I want to create a clause that will hold if its two boolean parameters are equal and the third parameter is 1 or its two boolean parameters are not equal and the third parameter is 0. My first attempt:
equal_bools(X, Y, N) :-
X = Y,
N=1.
equal_bools(X, Y, N) :-
\+ X = Y,
N=0.
This seems to work:
?- equal_bools(true, true, 0).
false.
?- equal_bools(true, true, 1).
true.
?- equal_bools(true, false, 0).
true.
?- equal_bools(true, false, 1).
false.
The problem is, I really need Y to be bound to the correct value. For example, equal_bools(false, Y, 0).
should give back Y = true .
. Instead:
?- equal_bools(false, Y, 0).
false.
It seems \+ X = Y
checks for equality, but doesn't bind X
or Y
to any values. How do I fix this? This is for learning purposes, so I'd like to understand exactly how to do this rather than get a built-in clause that does all this or another library.
Nicely deterministic (i.e. no unwanted choicepoints), using (as usual) first-argument indexing, and unification:
bool_opp(true, false).
bool_opp(false, true).
% Unifies X with Y
bools_int(1, X, X) :-
bool_opp(X, _).
bools_int(0, X, Y) :-
bool_opp(X, Y).
Results in swi-prolog:
?- bools_int(I, X, Y).
I = 1,
X = Y, Y = true ;
I = 1,
X = Y, Y = false ;
I = 0,
X = true,
Y = false ;
I = 0,
X = false,
Y = true.
?- bools_int(1, X, Y).
X = Y, Y = true ;
X = Y, Y = false.
?- bools_int(0, X, Y).
X = true,
Y = false ;
X = false,
Y = true.
?- bools_int(0, X, true).
X = false.
?- bools_int(1, X, true).
X = true.
?- bools_int(1, X, false).
X = false.
?- bools_int(0, X, false).
X = true.
?- bools_int(I, X, false).
I = 1,
X = false ;
I = 0,
X = true.