2015-06-03 122 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