开发者

Prolog statement syntax

开发者 https://www.devze.com 2022-12-14 13:12 出处:网络
member(K,[a,b,c,d]) if for one of ... What\'s the stat开发者_如何学运维ement for two of ...?Just rinse and repeat:

member(K,[a,b,c,d]) if for one of ...

What's the stat开发者_如何学运维ement for two of ...?


Just rinse and repeat:

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

If you want two distinct elements then,

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

Then wrap it up in a predicate if that's what you're after:

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


I have interpreted the intended semantics of predicate two_members/3 somewhat differently:

  • We want to draw items X and Y from the given list Ls.
  • Ls must have at least two list items for two_members/3 to succeed.
  • X and Y may be equal if Ls contains X at least twice.

Based on the builtin predicates select/3 and member/2 we define:

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

Let's run some queries! First, the query the OP suggested in the question:

?- 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.

What if some item occurs more than once in Ls?

?- 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.

What about above redundant answers? Where do they come from and can we avoid them?

The redundant answers come from select/3 and member/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.

To get rid of these redundancies, we can use memberd/2 instead of member/2 and selectd/3 instead of select/3. Let's run above queries again:

?- 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.

The redundant answers are gone! So let's re-define two_members/3 accordingly:

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

Here's above query of two_members/3 that used to give these redundant answers:

?- 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!
0

精彩评论

暂无评论...
验证码 换一张
取 消