1 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %% Thom Fruehwirth ECRC 1991-1993
4 %% 910528 started boolean,and,or constraints
5 %% 910904 added xor,neg constraints
6 %% 911120 added imp constraint
7 %% 931110 ported to new release
8 %% 931111 added card constraint
9 %% 961107 Christian Holzbaur, SICStus mods
11 %% ported to hProlog by Tom Schrijvers June 2003
15 :- use_module(library(chr)).
17 :- constraints boolean/1, and/3, or/3, xor/3, neg/2, imp/2, labeling/0, card/4.
23 labeling, boolean(A)#Pc <=>
29 %% and/3 specification
39 and(X,Y,1) <=> X=1,Y=1.
41 %%and(X,Y,X) <=> imp(X,Y).
42 %%and(X,Y,Y) <=> imp(Y,X).
43 and(X,Y,A) \ and(X,Y,B) <=> A=B.
44 and(X,Y,A) \ and(Y,X,B) <=> A=B.
46 labeling, and(A,B,C)#Pc <=>
63 or(X,Y,0) <=> X=0,Y=0.
67 %%or(X,Y,X) <=> imp(Y,X).
68 %%or(X,Y,Y) <=> imp(X,Y).
69 or(X,Y,A) \ or(X,Y,B) <=> A=B.
70 or(X,Y,A) \ or(Y,X,B) <=> A=B.
72 labeling, or(A,B,C)#Pc <=>
81 %% xor/3 specification
90 xor(1,X,Y) <=> neg(X,Y).
91 xor(X,1,Y) <=> neg(X,Y).
92 xor(X,Y,1) <=> neg(X,Y).
96 xor(X,Y,A) \ xor(X,Y,B) <=> A=B.
97 xor(X,Y,A) \ xor(Y,X,B) <=> A=B.
99 labeling, xor(A,B,C)#Pc <=>
105 label_xor(1,X,Y):- neg(X,Y).
108 %% neg/2 specification
117 neg(X,Y) \ neg(Y,Z) <=> X=Z.
118 neg(X,Y) \ neg(Z,Y) <=> X=Z.
119 neg(Y,X) \ neg(Y,Z) <=> X=Z.
120 %% Interaction with other boolean constraints
121 neg(X,Y) \ and(X,Y,Z) <=> Z=0.
122 neg(Y,X) \ and(X,Y,Z) <=> Z=0.
123 neg(X,Z) , and(X,Y,Z) <=> X=1,Y=0,Z=0.
124 neg(Z,X) , and(X,Y,Z) <=> X=1,Y=0,Z=0.
125 neg(Y,Z) , and(X,Y,Z) <=> X=0,Y=1,Z=0.
126 neg(Z,Y) , and(X,Y,Z) <=> X=0,Y=1,Z=0.
127 neg(X,Y) \ or(X,Y,Z) <=> Z=1.
128 neg(Y,X) \ or(X,Y,Z) <=> Z=1.
129 neg(X,Z) , or(X,Y,Z) <=> X=0,Y=1,Z=1.
130 neg(Z,X) , or(X,Y,Z) <=> X=0,Y=1,Z=1.
131 neg(Y,Z) , or(X,Y,Z) <=> X=1,Y=0,Z=1.
132 neg(Z,Y) , or(X,Y,Z) <=> X=1,Y=0,Z=1.
133 neg(X,Y) \ xor(X,Y,Z) <=> Z=1.
134 neg(Y,X) \ xor(X,Y,Z) <=> Z=1.
135 neg(X,Z) \ xor(X,Y,Z) <=> Y=1.
136 neg(Z,X) \ xor(X,Y,Z) <=> Y=1.
137 neg(Y,Z) \ xor(X,Y,Z) <=> X=1.
138 neg(Z,Y) \ xor(X,Y,Z) <=> X=1.
139 neg(X,Y) , imp(X,Y) <=> X=0,Y=1.
140 neg(Y,X) , imp(X,Y) <=> X=0,Y=1.
142 labeling, neg(A,B)#Pc <=>
151 %% imp/2 specification (implication)
161 imp(X,Y),imp(Y,X) <=> X=Y.
163 labeling, imp(A,B)#Pc <=>
173 %% Boolean cardinality operator
174 %% card(A,B,L,N) constrains list L of length N to have between A and B 1s
179 A=<B,0=<B,A=<N, %0=<N
182 %% card/4 specification
183 %%card(A,B,[],0):- A=<0,0=<B.
184 %%card(A,B,[0|L],N):-
187 %%card(A,B,[1|L],N):-
188 %% A1 is A-1, B1 is B-1, N1 is N-1,
191 triv_sat @ card(A,B,L,N) <=> A=<0,N=<B | true. % trivial satisfaction
192 pos_sat @ card(N,B,L,N) <=> set_to_ones(L). % positive satisfaction
193 neg_sat @ card(A,0,L,N) <=> set_to_zeros(L). % negative satisfaction
194 pos_red @ card(A,B,L,N) <=> b_delete(X,L,L1),X==1 | % positive reduction
195 A1 is A-1, B1 is B-1, N1 is N-1,
197 neg_red @ card(A,B,L,N) <=> b_delete(X,L,L1),X==0 | % negative reduction
200 %% special cases with two variables
201 card2nand @ card(0,1,[X,Y],2) <=> and(X,Y,0).
202 card2neg @ card(1,1,[X,Y],2) <=> neg(X,Y).
203 card2or @ card(1,2,[X,Y],2) <=> or(X,Y,1).
205 b_delete( X, [X|L], L).
206 b_delete( Y, [X|Xs], [X|Xt]) :-
207 b_delete( Y, Xs, Xt).
209 labeling, card(A,B,L,N)#Pc <=>
214 label_card(A,B,[],0):- A=<0,0=<B.
215 label_card(A,B,[0|L],N):-
218 label_card(A,B,[1|L],N):-
219 A1 is A-1, B1 is B-1, N1 is N-1,
227 set_to_zeros([0|L]):-
232 %% Auxiliary predicates
236 solve_bool(A,C) :- var(A), !, A=C.
237 solve_bool(A,C) :- atomic(A), !, A=C.
238 solve_bool(A * B, C) :- !,
242 solve_bool(A + B, C) :- !,
246 solve_bool(A # B, C) :- !,
250 solve_bool(not(A),C) :- !,
253 solve_bool((A -> B), C) :- !,
257 solve_bool(A = B, C) :- !,
268 /* % no write macros in SICStus and hProlog
270 bool_portray(and(A,B,C),Out):- !, Out = (A*B = C).
271 bool_portray(or(A,B,C),Out):- !, Out = (A+B = C).
272 bool_portray(xor(A,B,C),Out):- !, Out = (A#B = C).
273 bool_portray(neg(A,B),Out):- !, Out = (A= not(B)).
274 bool_portray(imp(A,B),Out):- !, Out = (A -> B).
275 bool_portray(card(A,B,L,N),Out):- !, Out = card(A,B,L).
277 :- define_macro(type(compound),bool_portray/2,[write]).
280 /* end of handler bool */