2009-12-23 106 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!