ale
ale

Reputation: 11820

Prolog - Difference between two lists BUT

Using SWI-Prolog's listing predicate (or SICStus' predicate in its list library), we have:

lists:subtract([], _, []) :- !.
lists:subtract([A|C], B, D) :-
    memberchk(A, B), !,
    subtract(C, B, D).
lists:subtract([A|B], C, [A|D]) :-
    subtract(B, C, D).

which does this successfully:

?- subtract([2,3,4,5],[3,4],X).
X = [2, 5].

BUT, what if I want to do:

?- new_subtract([2,3,4,5],[3,X],Y).
X = [3, 2],
X = [3, 4],
X = [3, 5],

Y then has three solutions by taking the three X solutions from [2,3,4,5].

However, subtract/2 doesn't allow for this.

I've been trying to solve this for ages by taking the cuts (!)s out of the built in predicate's body to try and get it to backtrack and find all the solutions.

Upvotes: 1

Views: 6027

Answers (1)

Fred Foo
Fred Foo

Reputation: 363567

I assume you mean

?- new_subtract([2,3,4,5],[3,X],Y).
Y = [3, 2] ;
Y = [3, 4] ;
Y = [3, 5]

The following definition does that, but does not preserve all of subtract/3's behavior:

sub(List,[],List).
sub(List,[X|Sub],Rem) :- select(X,List,Rem0), sub(Rem0,Sub,Rem).

Usage:

?- sub([2,3,4,5],[3,X],Y).
X = 2,
Y = [4, 5] ;
X = 4,
Y = [2, 5] ;
X = 5,
Y = [2, 4] ;
false.

Upvotes: 4

Related Questions