在Prolog中,我有兩個略有不同的predicate,unique_element/2的實現。當給定元素X和列表L時謂詞成功,元素X在列表中只出現一次。下面是實現和結果:(SWI)序言:子目標的順序
實現1:
%%% unique_element/2
unique_element(Elem, [Elem|T]) :-
not(member(Elem, T)).
unique_element(Elem, [H|T]) :-
member(Elem, T),
H\==Elem,
unique_element(Elem, T),
!.
結果:
?- unique_element(X, [a, a, b, c, c, b]).
false.
?- unique_element(X, [a, b, c, c, b, d]).
X = a ;
X = d.
實現2:
%%% unique_element/2
unique_element(Elem, [Elem|T]) :-
not(member(Elem, T)).
unique_element(Elem, [H|T]) :-
H\==Elem,
member(Elem, T),
unique_element(Elem, T),
!.
如果你一開始沒有注意到視線:「H \ == Elem」和「成員(Elem,T)」在第二條impl規則2上翻轉。
個結果:
?- unique_element(X, [a, a, b, c, c, b]).
X = a.
?- unique_element(X, [a, b, c, c, b, d]).
X = a ;
X = d.
問:怎樣的順序,在這種情況下,影響結果?我意識到規則/事實/等的順序很重要。這兩個翻轉過來的特定規則似乎並不是以某種方式「相互聯繫」或相互影響(例如,在錯誤的地點/順序中的「裁減」謂詞)。
注意:我們在這裏正在討論SWI-Prolog。
注2:我知道,可能不同和更好的實現。這裏我的問題是關於改變次級目標的順序。
這兩個版本都錯誤地失敗了'unique_element(X,[a,b,c]),X = c.' – false