1
votes

I'm new to prolog and I wrote this code that suppose to return all the sub-lists of a list without some member of them.

contained(X, Y) :-
member(M, Y).
select(M, Y, X).

The query I type is:

contained(X, [1,2]) .

The expected result is:

[1],
[2]

The result I get is:

true,
true

What am I missing?

1
Do you understand what select/3 does? - Willem Van Onsem
it says: "Is true when List1, with Elem removed, results in List2. This implementation is determinsitic if the last element of List1 has been selected."...Doesn't it mean that X will be that list after removal? - user112112
Perhaps, also think of how you would write this without using library predicates. You can do it with three simple rules (one base case, two recursive cases). - lambda.xy.x

1 Answers

1
votes

The error you made is that you wrote a dot (.) at the end of member(M, Y). this means that Prolog thinks that you wrote:

contained(X, Y) :-
    member(M, Y).  %% notice the dot (.) here
select(M, Y, X).

So you here defined contained(X, Y) as member(M, Y) and furthermore you implemented a predicate named select(M, Y, X) that is always true for all values for M, Y and X.

You can replaced the . with a comma (,) here:

contained(X, Y) :-
    member(M, Y),
    select(M, Y, X).

That being said, you do not need member/2 here. In fact by using member, if the list contains duplicate values, it will result in yielding the same list multiple times.

You can just use select/3 [swi-doc] here with a wildcard (_) on the item to remove:

contained(X, Y) :-
    select(_, Y, X).

or we can use explicit recursion:

contained(T, [_|T]).
contained([H|T1], [H|T2]) :-
    contained(T1, T2).