
More Advanced Features 159
corresponding to: find all elements X that are members of A or are members of B
but not members of A.
With this new definition, the or operator gives the expected result.
?- X=[a,b,c,d],Y=[e,b,f,c,g],A sis X or Y.
X = [a,b,c,d] ,
Y = [e,b,f,c,g] ,
A = [a,b,c,d,e,f,g]
If we want to combine several operators in a single expression, e.g. X and Y
and Z, we need to change the definitions of and, or and - when used with sis, to
allow for the possibility of an argument being an expression not a list.
We can do this by first applying sis to each argument, replacing it by a list if it
is an expression, or by itself if it is a list. This requires an additional final clause to
be added, specifying that applying sis to 'anything else' (i.e. a list) gives the same
value.
This gives a revised definition of sis/2 as follows:
Y sis A and B :-
A1 sis A,B1 sis B,
findall(X,(member(X,A1),member(X,B1)),Y),!.
Y sis A or B:-
A1 sis A,B1 sis B,
findall(X,(member(X,A1);(member(X,B1),not(member(X,A1)))),Y),!.
Y sis A-B :-
A1 sis A,B1 sis B,
findall(X,(member(X,A1),not(member(X,B1))),Y),!.
A sis A:-!.
?- X=[a,b,c,d],Y=[e,b,f,c,g],Z=[a,e,c,g,h],A sis X and Y and Z.
X = [a,b,c,d] ,
Y = [e,b,f,c,g] ,
Z = [a,e,c,g,h] ,
A = [c]
?- X=[a,b,c,d],Y=[e,b,f,c,g],Z=[a,e,c,g,h],A sis X or Y or Z.
X = [a,b,c,d] ,
Y = [e,b,f,c,g] ,
Z = [a,e,c,g,h] ,
A = [a,b,c,d,e,f,g,h]