2015-06-03 94 views
0

我想从列表中删除重复的,但我得到false复制,这是我的代码:删除列表

remov([],[]):-!. 
remov([T|Q],[T|R]):-not(member(T,R)),remov(Q,[T|R]). 
remov([T|Q],R):-member(T,R),!,remov(Q,R). 

member(E,[]):-!,fail. 
member(T,[T|Q]):-!. 
member(E,[T|Q]):-member(E,Q). 
+3

[这里](http://stackoverflow.com/a/27989470/772868)是一个纯和快速版本 – false

回答

1

坦率地说,谓词的执行remov/2member/2 留下很多有待改进。

为什么? 6个子句中的5个“使用”元逻辑构造(!)/0not/1。这几乎破坏了所有的声明性方面,这迫使我专注于关于程序执行方面的大量细节。详情请参阅

作为替代方案,我建议以下实现的remov/2

remov(Xs,Ys) :- 
    (ground(Xs) -> sort(Xs,Ys) 
    ; throw(error(instantiation_error,remov/2)) 
    ). 

让我们的代码分开!诀窍是使用内置的谓词sort/2:根据standard order

  • 的内置谓词sort/2各种Prolog的术语列表。

  • sort/2消除重复的项目。

  • 根据具体实例,sort/2可能不保留

  • sort/2如果我们只将它与地面数据一起使用,那么它在逻辑上是合理的(术语顺序是安全的)。

示例查询:

?- remov([1,2,3,1,2],Xs). 
Xs = [1, 2, 3]. 

?- remov(Xs,Ys). 
ERROR: Arguments are not sufficiently instantiated