Prolog删除功能 - 几乎正常工作

时间:2010-04-01 18:44:21

标签: prolog

以下谓词为remove(L,X,R),其中L为列表,X是要从列表中删除的元素。代码返回正确的列表,但之后它总是返回false。

我无法在运行时找到可以应用两个规则的地方。

remove([],X,[]) :- !. 
remove([X|T],X,L1) :- remove(T,X,L1). 
remove([H|T],X,[H|L1]) :- \+(X==H), remove(T,X,L1). 

具有预期结果的示例查询:

?- remove([1,2,3,4],3,R).
R = [1, 2, 4] ; 
false.

2 个答案:

答案 0 :(得分:2)

如果您的Prolog系统支持,您可以按照以下步骤保留。 使用 tfilter/3和具体化的不等式谓词dif/3,我们可以写:

remove(Xs0,E,Xs) :- tfilter(dif(E),Xs0,Xs).

快速检查是否有效:

?- tfilter(dif(3),[1,2,3,4],Xs).
Xs = [1,2,4].                     % succeeds deterministically

tfilter/3dif/3 单调,所以 即使对于一般查询,我们也会得到合理的答案:

?- remove([A,B,C],3,Xs).
Xs = [     ],     A=3 ,     B=3 ,     C=3  ;
Xs = [    C],     A=3 ,     B=3 , dif(C,3) ;
Xs = [  B  ],     A=3 , dif(B,3),     C=3  ;
Xs = [  B,C],     A=3 , dif(B,3), dif(C,3) ;
Xs = [A    ], dif(A,3),     B=3 ,     C=3  ;
Xs = [A,  C], dif(A,3),     B=3 , dif(C,3) ;
Xs = [A,B  ], dif(A,3), dif(B,3),     C=3  ;
Xs = [A,B,C], dif(A,3), dif(B,3), dif(C,3) ;
false.

答案 1 :(得分:1)

http://www.cs.bris.ac.uk/Teaching/Resources/COMS30106/labs/tracer.html - SWI-prolog具有跟踪/调试模式。在我看来,cmd-line调试器优于可视化调试器。

编辑:

remove([],X,[]) :- !. 
remove([X|T],X,L1) :- !, remove(T,X,L1).          <-- cut was added
remove([H|T],X,[H|L1]) :- remove(T,X,L1).         <-- condition was deleted

上面的代码应该没问题。不过没有保修。