Using clpfd, I define a custom contraint xor32/3 yielding R #= X xor Y when any 2 out of 3 variables are instantiated.
When using this, mod32/3 is leaving unexpected choice points. May be I understood something wrongly here. Any help would be appreciated:
:- use_module(library(clpfd)).
:- multifile clpfd:run_propagator/2.
% xor32(X, Y, R) computes R #= X xor Y if any 2 out of 3 variables are instantiated
clpfd:run_propagator(xor32(X, Y, R), MState):-
(integer(X), integer(Y))
-> clpfd:kill(MState), R #= X xor Y
; (integer(X), integer(R))
-> clpfd:kill(MState), Y #= R xor X
; (integer(Y), integer(R))
-> clpfd:kill(MState), X #= R xor Y
; true
.
xor32(X, Y, R):-
clpfd:make_propagator(xor32(X, Y, R), Prop)
, clpfd:init_propagator(X, Prop)
, clpfd:init_propagator(Y, Prop)
, clpfd:init_propagator(R, Prop)
, clpfd:trigger_once(Prop)
.
Sample execution:
125 ?- xor32(X, Y, R), X=345.
X = 345,
xor32(345, Y, R),
xor32(345, Y, R) ;
X = 345,
xor32(345, Y, R),
xor32(345, Y, R) ;
X = 345,
xor32(345, Y, R),
xor32(345, Y, R) ;
X = 345,
xor32(345, Y, R),
xor32(345, Y, R).
N.B. Unfortunately, the build-in xor cannot resolve R #= X xor Y when R and (X or Y) is known
126 ?- R #= X xor Y, Y = 453, R = 3467.
R = 3467,
Y = 453,
3467#=X xor 453.
132 ?- R #= X xor Y, Y = 453, R = 3467, X in 0..0xffffffff, label([X]).
R = 3467,
X = 3150,
Y = 453 ;
--> does not terminate in a reasonaable time
127 ?- xor32(X, Y, R), Y = 453, R = 3467.
X = 3150,
Y = 453,
R = 3467 .