2009-12-23 100 views
0

member(K,[a,b,c,d]) if for ...其中之一...序言語句語法

兩個...的聲明是什麼?

+4

你將不得不澄清這個問題有點。 – 2009-12-23 02:41:06

+0

看到我的意見在這個答案:http://stackoverflow.com/questions/1939054/how-to-solve-this-problem-by-prolog/1941239#1941239 – user198729 2009-12-23 03:35:17

回答

2

剛剛沖洗和重複:

?- List = [a,b,c,d],member(X,List),member(Y,List). 

如果你想那麼兩種截然不同的元素,

?- List = [a,b,c,d],member(X,List),member(Y,List),X \== Y. 

然後在謂詞包起來,如果這就是你追求的:

two_members(X,Y,List) :- 
    member(X,List), 
    member(Y,List), 
    X \== Y. 
+1

通過使用「dif/2」表達術語不平等你即使使用非基礎術語,也可以保留[標籤:邏輯純度]。 – repeat 2015-06-23 09:03:07

1

我已經有些不同地解釋了謂詞two_members/3的預期語義:

  • 我們要吸取項目從給定的列表LsXY
  • Ls必須至少有兩個two_members/3的列表項才能成功。
  • XY可能相等,如果Ls包含X至少兩次。

基於內置的謂詞select/3member/2我們定義:

two_members(X,Y,Ls) :- 
    select(X,Ls,Ls0), 
    member(Y,Ls0). 

讓我們運行一些查詢!

?- two_members(X,Y,[a,b,c,d]). 
X = a, Y = b ; 
X = a, Y = c ; 
X = a, Y = d ; 
X = b, Y = a ; 
X = b, Y = c ; 
X = b, Y = d ; 
X = c, Y = a ; 
X = c, Y = b ; 
X = c, Y = d ; 
X = d, Y = a ; 
X = d, Y = b ; 
X = d, Y = c ; 
false. 

如果發生哪些項目在Ls不止一次:首先,查詢OP中的問題提出?

?- two_members(X,Y,[a,a,b]). 
X = a, Y = a ; 
X = a, Y = b ; 
X = a, Y = a ;    % redundant answer 
X = a, Y = b ;    % redundant answer 
X = b, Y = a ; 
X = b, Y = a ;    % redundant answer 
false. 

以上多餘的答案呢?他們從哪裏來,我們可以避免它們?

冗餘答案來自select/3member/3

?- select(X,[a,a,b],Xs). 
X = a, Xs = [a,b] ; 
X = a, Xs = [a,b] ;   % redundant answer 
X = b, Xs = [a,a] ; 
false. 

?- member(X,[a,a,b]). 
X = a ; 
X = a ;      % redundant answer 
X = b. 

爲了擺脫這些冗餘的,我們可以用 memberd/2代替member/2selectd/3而不是select/3。讓我們再次運行以上查詢:

 
?- selectd(X,[a,a,b],Xs). 
X = a, Xs = [a,b] ; 
X = b, Xs = [a,a] ; 
false. 

?- memberd(X,[a,a,b]). 
X = a ; 
X = b ; 
false. 

多餘的答案不見了!因此,讓我們據此重新定義two_members/3

 
two_members(X,Y,Ls) :- 
    selectd(X,Ls,Ls0), 
    memberd(Y,Ls0). 

這裏是上面的two_members/3查詢用來給這些多餘的答案:

?- two_members(X,Y,[a,a,b]). 
X = a, Y = a ; 
X = a, Y = b ; 
X = b, Y = a ; 
false.      % all of above redundant answers have gone!