List 删除prolog中的重复项
我对prolog相当陌生,目前正在阅读一本书,这本书为我提供了编写代码的实践示例。它让我负责删除重复项 注意:我已经阅读了其他stackoverflows,我知道如何删除重复项,但我不明白的是为什么我的代码不能工作。(对于其他堆栈溢出,我选择了不同的方法) 我已经创建了一个is_成员谓词,我相信它很好用List 删除prolog中的重复项,list,prolog,failure-slice,program-slicing,List,Prolog,Failure Slice,Program Slicing,我对prolog相当陌生,目前正在阅读一本书,这本书为我提供了编写代码的实践示例。它让我负责删除重复项 注意:我已经阅读了其他stackoverflows,我知道如何删除重复项,但我不明白的是为什么我的代码不能工作。(对于其他堆栈溢出,我选择了不同的方法) 我已经创建了一个is_成员谓词,我相信它很好用 is_member(X, [Head,Tail]):- X == Head; is_member(X, Tail). 然后我的remove_duplicates谓词 remov
is_member(X, [Head,Tail]):-
X == Head;
is_member(X, Tail).
然后我的remove_duplicates谓词
remove_duplicates([Head|Tail], Without):-
is_member(Head, Tail),
remove_duplicates(Tail, Without);
remove_duplicates(Tail, Head).
在我看来,这是有道理的,它检查头部是否是尾部的一部分,如果是,它不会将其添加到“无”列表中
否则它会
我显然遗漏了一些琐碎的东西
提前感谢让我们先考虑一下
is_member/2
来简化任务
你可以这样写:
is_member(X, [Head,Tail]):-
X == Head;
is_member(X, Tail).
太好了!这是我们所期望的
那么,a
是列表的成员吗
?- is_member(a, [a]).
false.
?是联合会成员(a,[a])。
错。
这绝对是错误的
我建议您从这里开始,然后转到更复杂的定义。以系统的方式处理它:
回答得很好,谢谢你,我会接受你的建议。我也相信,我修正了错误。With:
is_成员(X,[Head |)]:-X==Head代码>这修复了具体的测试用例是成员(a,[a])
,是。但是,尝试一下测试用例的轻微泛化:?-is_成员(a[X])。
这仍然失败。总的来说,我只能建议避免使用非单调谓词,如(==)/2
。它们只能在非常特殊的情况下安全地使用,在更一般的情况下会产生错误的答案。要表示两项相等,请使用(=)/2
。它在所有方向上都正常工作。不应该是_成员(a[X])。失败?仔细想想:假设是_成员(a[X])
失败。那么这就意味着,如果我们以声明的方式阅读它,那么这个查询就没有任何解决方案。然而,我们已经确定X=a
是一个解决方案,因为是成员(a[a])
必须成功!因此,由于更具体的案例是成员(a[a])
成功,因此更一般的案例是成员(a[X])
肯定不能失败。否则,这将意味着程序报告错误的答案。
?- is_member(a, [a]).
false.
:- op(950,fy, *).
*_.
is_member(X, [Head,Tail]):-
( * X == Head
; * is_member(X, Tail)
).
is_member(X, [Head,Tail]) :- true.
?- is_member(a, [a]).
false.