【发布时间】:2015-03-05 23:20:30
【问题描述】:
这是我第一次在这里提出问题,但是我有一个问题,我真的无法解决这个问题,即 Prolog 递归,尤其是在处理列表时。所以我应该解决的任务是编写一个像这样工作的 drop 谓词。例如,drop([1,2,3,4,5,6,7,8,9], 2, L) 其中L = [1,3,5,7,9] 和N=n 其中位置n、2n、3n....的元素将被删除。列表从 1 开始是另一件需要注意的事情。
这是我目前的尝试和思考过程:
drop([], _, []).
indexOf([X|_], X, 1). %Using 1 because the question says the first element starts from 1.
indexOf([_|Ys], Y , I):-
indexOf(Ys, Y, N),
I is N + 1.
drop([X|Xs], Y, [X|_]) :-
indexOf([X|Xs] , X , A),
Z is A mod Y,
Z \== 0.
drop([X|Xs], Y, Zs) :-
%indexOf([X|Xs], X, A),
drop(Xs, Y, Zs).
我创建了一个 indexOf 谓词来查找从 1 开始的元素的索引。接下来,我的想法是使用我的第一个 drop 递归案例(在上面的代码中是第 5 个案例)来检查元素的位置在除以 Y(第二个输入)时是否返回零余数.如果它不返回零的余数,则 X 将保留在列表中并且不会被删除。然后,prolog 移动到第二个 drop 递归案例,该案例只能在 Z=0 时到达,它将从列表中删除 X 以返回 Zs。本质上,如果由indexOf 返回的索引为 n、2n、3n... 的元素在除以 Y(第二个输入)时未返回零余数,则将被删除。
目前我还没有学习 Cut。如果有人能指出我正确的方向,我将不胜感激。我已经为此工作了将近一天。
我仍在尝试调整这种编程范式中的逻辑和声明式思维。如果您能与我分享,我将不胜感激,您个人是如何掌握逻辑编程的?
【问题讨论】:
-
您的第二个 drop 谓词在结果的尾部有
_,这不好。这意味着您的结果将具有该匿名变量。所以你显然不是那个意思。将这些视为规则并尝试将其视为规则。drop([X|Xs], Y, [X|_]) :-...是 删除了Y-th 元素的列表[X|Xs]是[X|_]if...。是什么让它成为现实?当然你需要Y > 1,但是[X|_]需要一个真正的尾巴,尾巴的值将由你的规则决定。 -
indexOf([X|Xs], X, A)的第一个结果A不是总是A = 1吗?indexOf策略的一个谬误是,在你到达那里之前,你并不真正知道Y-th 元素将是什么,所以你没有它来获取它的索引。你真的只想要一个简单的计数器。 -
感谢您的回复!今天早上我再次尝试重新尝试时看到了这一点。我正在查看 gtrace,但无法理解为什么我的结果会像 [a | _G264]。感谢您的第一条评论,我现在终于明白了。我不应该在我的结果中使用匿名变量,因为我需要它来实例化/存储我的结果。
-
是的!今天早上我注意到了使用 indexOf 策略的谬误,我尝试使用累加器作为简单的计数器,但无法使其正常工作。不太确定如何在 Prolog 中创建计数器,因为在 Java 中我所要做的就是创建一个局部变量 i。我现在要在下面阅读您的长篇回复。