Prolog XOR on elements of list

1.5k views Asked by At

I am new in Prolog and I would like to apply XOR operation on elements of given list of length n. The predicate should return True if list contains some false elements in the first n-1 element or if last element is True.

I have written the following code so far, but it does not work properly such as for the query ?- function([true,false,false]) the predicate should return True but it returns false.

function([X|_]) :-  \ + X,!.
function([X]):-X,!.
function([_|XS]):- function(XS),!,helper(XS).

helper([X]):- X,!.
helper([_|YS]):- helper(YS),!.

I would appreciate if you could help me. Thanks!

3

There are 3 answers

2
repeat On BEST ANSWER

Here's your spec again:

The predicate should return True if list contains some false elements in the first n-1 element or if last element is True.

Let's define predicate xor_check/1 like this:

xor_check(List) :-
   booleans(List),
   append(ButLast,[Last],List),
   xor_check__aux(Last,ButLast).

Above code is based on xor_check__aux/2, which in turn builds on memberd/2:

xor_check__aux(true,_).
xor_check__aux(false,ButLast) :-
   memberd(false,ButLast).

The auxiliary predicates boolean/1 and booleans/1 can be defined as:

boolean(true).
boolean(false).

booleans([]).
booleans([B|Bs]) :-
   boolean(B),
   booleans(Bs).

Sample queries (with SICStus Prolog 4.3.2):

?- xor_check([true,false]).
no
?- xor_check([true,true,true]).
yes
?- xor_check([true,false,false]).
yes
1
Ventsyslav Raikov On

I don't have a prolog compiler at hand but this should do the trick.

function([false|_]).

function([X]):- X.

function([_ | XS]) :- function(XS).
0
Nicholas Carey On

A XOR B if true if either A or B is true, but not both. Here's its truth table:

  A   |   B   | A XOR B
------+------ |---------
false | false | false
false | true  | true
true  | false | true
true  | true  | false

Write that truth table as a Prolog predicate:

%      A       B   | A XOR B
%    -----   ----- | -------
xor( false , false , false   ) .
xor( false , true  , true    ) .
xor( true  , false , true    ) .
xor( true  , true  , false   ) .

Then it's a simply mater of recursively it over the list. When the list collapsed to a single element, it succeeds on [true] and fails otherwise:

xor_list( [ A,B | T ] ) :- xor(A,B,C) , xor_list( [C|T] ) .
xor_list( [ true    ] ) .

This can all be collapsed into a slightly smaller/simpler predicate:

xor_list( [ false , false | T ] ) :- xor_list( [ false | T ] ) .
xor_list( [ false , true  | T ] ) :- xor_list( [ true  | T ] ) .
xor_list( [ true  , false | T ] ) :- xor_list( [ true  | T ] ) .
xor_list( [ true  , true  | T ] ) :- xor_list( [ false | T ] ) .
xor_list( [ true              ] ) .