0

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

What's the statement for two of ...?

user198729
  • 61,774
  • 108
  • 250
  • 348

2 Answers2

2

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.
repeat
  • 18,496
  • 4
  • 54
  • 166
nedned
  • 3,552
  • 8
  • 38
  • 41
  • 1
    By using `dif/2` for expressing term inequality you could preserve [tag:logical-purity] even when working with non-ground terms. – repeat Jun 23 '15 at 09:03
1

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!
Community
  • 1
  • 1
repeat
  • 18,496
  • 4
  • 54
  • 166