:- lib(ic).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Exercise 5.3 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%% 5.3. a)
myxor_a(X,Y,Z) :-
	[X,Y,Z]#::[0,1],
	(ground(X), ground(Y), X#=Y ->
		Z=0
	;
		suspend(myxor_a(X,Y,Z),2,[X,Y,Z] -> inst)
	).


%%% 5.3. b)
myxor_b(X,Y,Z) :-
	[X,Y,Z]#::[0,1],
	(ground(X) ->
		myxor_firstground(X,Y,Z)
	;ground(Y) ->
		myxor_firstground(Y,X,Z)
	;ground(Z) ->
		myxor_firstground(Z,X,Y)
	;
		suspend(myxor_b(X,Y,Z),2,[X,Y,Z] -> inst)
	).


myxor_firstground(0,Y,Z) :- Y #= Z.
myxor_firstground(1,Y,Z) :- Y #\= Z.


%%%% queries for the two CSPs in Exercise 4.2 %%%%

constraints(X1,X2,X3,X4,Y1,Y2,Y3,Y4) :-
	myxor_b(X1,X2,Y1),
	myxor_b(X2,X3,Y2),
	myxor_b(X3,X4,Y3),
	Y4 #= X4.

csp1 :-
	constraints(1,0,0,1,Y1,Y2,Y3,Y4),
	printf("Y1=%w  Y2=%w  Y3=%w  Y4=%w%n",[Y1,Y2,Y3,Y4]).


csp2 :-
	constraints(X1,1,X3,X4,1,Y2,1,1),
	printf("X1=%w  X3=%w  X4=%w  Y2=%w%n",[X1,X3,X4,Y2]).
