跟踪一个简单的序言代码来完全理解CUT(!)

时间:2013-03-17 20:56:28

标签: prolog prolog-dif

member(X,[X|T]).
member(X,[H|T]):-member(X,T).

delfstocc(X,[X|T],T).
delfstocc(X,[Y|T],[Y|T1]):-delfstocc(X,T,T1),!.

delallocc(X,L,L1):-member(X,L),delfstocc(X,L,R),!,delallocc(X,R,L1);write(L).

首先,我在不使用剪切的情况下编写了此代码,  然后我试着在每个谓词之后放下切割算子,直到我得到完美的答案 但实际上我不明白使用切割后它是如何工作的。 我知道切割操作员阻止prolog进行匹配, 但是我不能正确使用它, 所以我想要帮助跟踪这段代码 顺便说一下,这段代码会简单地删除列表中所有出现的元素。

1 个答案:

答案 0 :(得分:1)

首先,就削减而言,实际上按如下方式处理:

“目标成功并将Prolog提交给所有做出的选择,因为父目标与该条款的负责人统一了”。

另请参阅:http://www.swi-prolog.org/pldoc/doc_for?object=!/0

关于从列表中删除:为了实现您的目标,您的方法不必要地复杂化。这是一个更简单的解决方案:

对于空列表,delete始终为true:

del([],_X,[]).

当列表的头部与您要删除的元素相同时,它不属于另一个列表:

del([X|Xs], X, Ys) :- del(Xs, X, Ys).

当列表的头部与您要删除的元素相同时,它属于另一个列表:

del([X|Xs], Z, [X|Ys]) :- dif(X,Z), del(Xs, X, Ys).

(注意:条款的顺序很重要!为什么?)

此解决方案不使用剪切和尝试回溯。您可以在适当的位置使用剪切以防止回溯。