282 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			282 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
|   | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||
|  | %% | ||
|  | %% Thom Fruehwirth ECRC 1991-1993 | ||
|  | %% 910528 started boolean,and,or constraints | ||
|  | %% 910904 added xor,neg constraints | ||
|  | %% 911120 added imp constraint | ||
|  | %% 931110 ported to new release | ||
|  | %% 931111 added card constraint  | ||
|  | %% 961107 Christian Holzbaur, SICStus mods | ||
|  | %% | ||
|  | %% ported to hProlog by Tom Schrijvers June 2003 | ||
|  | 
 | ||
|  | 
 | ||
|  | :- module(bool,[]). | ||
|  | :- use_module(library(chr)). | ||
|  | 
 | ||
|  | :- constraints boolean/1, and/3, or/3, xor/3, neg/2, imp/2, labeling/0, card/4. | ||
|  | 
 | ||
|  | 
 | ||
|  | boolean(0) <=> true. | ||
|  | boolean(1) <=> true. | ||
|  | 
 | ||
|  | labeling, boolean(A)#Pc <=>  | ||
|  | ( A=0 ; A=1),  | ||
|  | labeling | ||
|  | pragma passive(Pc). | ||
|  | 
 | ||
|  | 
 | ||
|  | %% and/3 specification | ||
|  | %%and(0,0,0). | ||
|  | %%and(0,1,0). | ||
|  | %%and(1,0,0). | ||
|  | %%and(1,1,1). | ||
|  | 
 | ||
|  | and(0,X,Y) <=> Y=0. | ||
|  | and(X,0,Y) <=> Y=0. | ||
|  | and(1,X,Y) <=> Y=X. | ||
|  | and(X,1,Y) <=> Y=X. | ||
|  | and(X,Y,1) <=> X=1,Y=1. | ||
|  | and(X,X,Z) <=> X=Z. | ||
|  | %%and(X,Y,X) <=> imp(X,Y). | ||
|  | %%and(X,Y,Y) <=> imp(Y,X). | ||
|  | and(X,Y,A) \ and(X,Y,B) <=> A=B. | ||
|  | and(X,Y,A) \ and(Y,X,B) <=> A=B. | ||
|  | 
 | ||
|  | labeling, and(A,B,C)#Pc <=>  | ||
|  | label_and(A,B,C),  | ||
|  | labeling | ||
|  | pragma passive(Pc). | ||
|  | 
 | ||
|  | label_and(0,X,0). | ||
|  | label_and(1,X,X). | ||
|  | 
 | ||
|  | 
 | ||
|  | %% or/3 specification | ||
|  | %%or(0,0,0). | ||
|  | %%or(0,1,1). | ||
|  | %%or(1,0,1). | ||
|  | %%or(1,1,1). | ||
|  | 
 | ||
|  | or(0,X,Y) <=> Y=X. | ||
|  | or(X,0,Y) <=> Y=X. | ||
|  | or(X,Y,0) <=> X=0,Y=0. | ||
|  | or(1,X,Y) <=> Y=1. | ||
|  | or(X,1,Y) <=> Y=1. | ||
|  | or(X,X,Z) <=> X=Z. | ||
|  | %%or(X,Y,X) <=> imp(Y,X). | ||
|  | %%or(X,Y,Y) <=> imp(X,Y). | ||
|  | or(X,Y,A) \ or(X,Y,B) <=> A=B. | ||
|  | or(X,Y,A) \ or(Y,X,B) <=> A=B. | ||
|  | 
 | ||
|  | labeling, or(A,B,C)#Pc <=>  | ||
|  | label_or(A,B,C),  | ||
|  | labeling | ||
|  | pragma passive(Pc). | ||
|  | 
 | ||
|  | label_or(0,X,X). | ||
|  | label_or(1,X,1). | ||
|  | 
 | ||
|  | 
 | ||
|  | %% xor/3 specification | ||
|  | %%xor(0,0,0). | ||
|  | %%xor(0,1,1). | ||
|  | %%xor(1,0,1). | ||
|  | %%xor(1,1,0). | ||
|  | 
 | ||
|  | xor(0,X,Y) <=> X=Y. | ||
|  | xor(X,0,Y) <=> X=Y. | ||
|  | xor(X,Y,0) <=> X=Y. | ||
|  | xor(1,X,Y) <=> neg(X,Y). | ||
|  | xor(X,1,Y) <=> neg(X,Y). | ||
|  | xor(X,Y,1) <=> neg(X,Y). | ||
|  | xor(X,X,Y) <=> Y=0. | ||
|  | xor(X,Y,X) <=> Y=0. | ||
|  | xor(Y,X,X) <=> Y=0. | ||
|  | xor(X,Y,A) \ xor(X,Y,B) <=> A=B. | ||
|  | xor(X,Y,A) \ xor(Y,X,B) <=> A=B. | ||
|  | 
 | ||
|  | labeling, xor(A,B,C)#Pc <=>  | ||
|  | label_xor(A,B,C),  | ||
|  | labeling | ||
|  | pragma passive(Pc). | ||
|  | 
 | ||
|  | label_xor(0,X,X). | ||
|  | label_xor(1,X,Y):- neg(X,Y). | ||
|  | 
 | ||
|  | 
 | ||
|  | %% neg/2 specification | ||
|  | %%neg(0,1). | ||
|  | %%neg(1,0). | ||
|  | 
 | ||
|  | neg(0,X) <=> X=1. | ||
|  | neg(X,0) <=> X=1. | ||
|  | neg(1,X) <=> X=0. | ||
|  | neg(X,1) <=> X=0. | ||
|  | neg(X,X) <=> fail. | ||
|  | neg(X,Y) \ neg(Y,Z) <=> X=Z.	 | ||
|  | neg(X,Y) \ neg(Z,Y) <=> X=Z.	 | ||
|  | neg(Y,X) \ neg(Y,Z) <=> X=Z.	 | ||
|  | %% Interaction with other boolean constraints | ||
|  | neg(X,Y) \ and(X,Y,Z) <=> Z=0. | ||
|  | neg(Y,X) \ and(X,Y,Z) <=> Z=0. | ||
|  | neg(X,Z) , and(X,Y,Z) <=> X=1,Y=0,Z=0. | ||
|  | neg(Z,X) , and(X,Y,Z) <=> X=1,Y=0,Z=0. | ||
|  | neg(Y,Z) , and(X,Y,Z) <=> X=0,Y=1,Z=0. | ||
|  | neg(Z,Y) , and(X,Y,Z) <=> X=0,Y=1,Z=0. | ||
|  | neg(X,Y) \ or(X,Y,Z) <=> Z=1. | ||
|  | neg(Y,X) \ or(X,Y,Z) <=> Z=1. | ||
|  | neg(X,Z) , or(X,Y,Z) <=> X=0,Y=1,Z=1. | ||
|  | neg(Z,X) , or(X,Y,Z) <=> X=0,Y=1,Z=1. | ||
|  | neg(Y,Z) , or(X,Y,Z) <=> X=1,Y=0,Z=1. | ||
|  | neg(Z,Y) , or(X,Y,Z) <=> X=1,Y=0,Z=1. | ||
|  | neg(X,Y) \ xor(X,Y,Z) <=> Z=1. | ||
|  | neg(Y,X) \ xor(X,Y,Z) <=> Z=1. | ||
|  | neg(X,Z) \ xor(X,Y,Z) <=> Y=1. | ||
|  | neg(Z,X) \ xor(X,Y,Z) <=> Y=1. | ||
|  | neg(Y,Z) \ xor(X,Y,Z) <=> X=1. | ||
|  | neg(Z,Y) \ xor(X,Y,Z) <=> X=1. | ||
|  | neg(X,Y) , imp(X,Y) <=> X=0,Y=1. | ||
|  | neg(Y,X) , imp(X,Y) <=> X=0,Y=1. | ||
|  | 
 | ||
|  | labeling, neg(A,B)#Pc <=>  | ||
|  | label_neg(A,B),  | ||
|  | labeling | ||
|  | pragma passive(Pc). | ||
|  | 
 | ||
|  | label_neg(0,1). | ||
|  | label_neg(1,0). | ||
|  | 
 | ||
|  | 
 | ||
|  | %% imp/2 specification (implication) | ||
|  | %%imp(0,0). | ||
|  | %%imp(0,1). | ||
|  | %%imp(1,1). | ||
|  | 
 | ||
|  | imp(0,X) <=> true. | ||
|  | imp(X,0) <=> X=0. | ||
|  | imp(1,X) <=> X=1. | ||
|  | imp(X,1) <=> true. | ||
|  | imp(X,X) <=> true. | ||
|  | imp(X,Y),imp(Y,X) <=> X=Y.	 | ||
|  | 
 | ||
|  | labeling, imp(A,B)#Pc <=>  | ||
|  | label_imp(A,B),  | ||
|  | labeling | ||
|  | pragma passive(Pc). | ||
|  | 
 | ||
|  | label_imp(0,X). | ||
|  | label_imp(1,1). | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | %% Boolean cardinality operator | ||
|  | %% card(A,B,L,N) constrains list L of length N to have between A and B 1s | ||
|  | 
 | ||
|  | 
 | ||
|  | card(A,B,L):-  | ||
|  | 	length(L,N),  | ||
|  | 	A=<B,0=<B,A=<N,				%0=<N 	 | ||
|  | 	card(A,B,L,N). | ||
|  | 
 | ||
|  | %% card/4 specification | ||
|  | %%card(A,B,[],0):- A=<0,0=<B. | ||
|  | %%card(A,B,[0|L],N):- | ||
|  | %%		N1 is N-1, | ||
|  | %%		card(A,B,L,N1). | ||
|  | %%card(A,B,[1|L],N):-   | ||
|  | %%		A1 is A-1, B1 is B-1, N1 is N-1, | ||
|  | %%		card(A1,B1,L,N1). | ||
|  | 
 | ||
|  | triv_sat @ card(A,B,L,N) <=> A=<0,N=<B | true. % trivial satisfaction | ||
|  | pos_sat @ card(N,B,L,N) <=> set_to_ones(L).	% positive satisfaction | ||
|  | neg_sat @ card(A,0,L,N) <=> set_to_zeros(L). % negative satisfaction | ||
|  | pos_red @ card(A,B,L,N) <=> b_delete(X,L,L1),X==1 | % positive reduction | ||
|  | A1 is A-1, B1 is B-1, N1 is N-1, | ||
|  | card(A1,B1,L1,N1). | ||
|  | neg_red @ card(A,B,L,N) <=> b_delete(X,L,L1),X==0 | % negative reduction | ||
|  | N1 is N-1, | ||
|  | card(A,B,L1,N1). | ||
|  | %% special cases with two variables | ||
|  | card2nand @ card(0,1,[X,Y],2) <=> and(X,Y,0).		 | ||
|  | card2neg @ card(1,1,[X,Y],2) <=> neg(X,Y).		 | ||
|  | card2or @ card(1,2,[X,Y],2) <=> or(X,Y,1). | ||
|  | 
 | ||
|  | b_delete( X, [X|L],  L). | ||
|  | b_delete( Y, [X|Xs], [X|Xt]) :- | ||
|  | 	b_delete( Y, Xs, Xt). | ||
|  | 
 | ||
|  | labeling, card(A,B,L,N)#Pc <=>  | ||
|  | label_card(A,B,L,N),  | ||
|  | labeling | ||
|  | pragma passive(Pc). | ||
|  | 
 | ||
|  | label_card(A,B,[],0):- A=<0,0=<B. | ||
|  | label_card(A,B,[0|L],N):- | ||
|  | 	N1 is N-1, | ||
|  | 	card(A,B,L). | ||
|  | label_card(A,B,[1|L],N):-   | ||
|  | 	A1 is A-1, B1 is B-1, N1 is N-1, | ||
|  | 	card(A1,B1,L). | ||
|  | 
 | ||
|  | set_to_ones([]). | ||
|  | set_to_ones([1|L]):- | ||
|  | 	set_to_ones(L). | ||
|  | 
 | ||
|  | set_to_zeros([]). | ||
|  | set_to_zeros([0|L]):- | ||
|  | 	set_to_zeros(L). | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | %% Auxiliary predicates | ||
|  | 
 | ||
|  | :- op(100,xfy,#). | ||
|  | 
 | ||
|  | solve_bool(A,C) :- var(A), !, A=C. | ||
|  | solve_bool(A,C) :- atomic(A), !, A=C. | ||
|  | solve_bool(A * B, C) :- !, | ||
|  | 	solve_bool(A,A1), | ||
|  | 	solve_bool(B,B1), | ||
|  | 	and(A1,B1,C). | ||
|  | solve_bool(A + B, C) :- !, | ||
|  | 	solve_bool(A,A1), | ||
|  | 	solve_bool(B,B1), | ||
|  | 	or(A1,B1,C). | ||
|  | solve_bool(A # B, C) :- !, | ||
|  | 	solve_bool(A,A1), | ||
|  | 	solve_bool(B,B1), | ||
|  | 	xor(A1,B1,C). | ||
|  | solve_bool(not(A),C) :- !,  | ||
|  | 	solve_bool(A,A1), | ||
|  | 	neg(A1,C). | ||
|  | solve_bool((A -> B), C) :- !, | ||
|  | 	solve_bool(A,A1), | ||
|  | 	solve_bool(B,B1), | ||
|  | 	imp(A1,B1),C=1. | ||
|  | solve_bool(A = B, C) :- !, | ||
|  | 	solve_bool(A,A1), | ||
|  | 	solve_bool(B,B1), | ||
|  | 	A1=B1,C=1. | ||
|  | 
 | ||
|  | %% Labeling  | ||
|  | label_bool([]). | ||
|  | label_bool([X|L]) :- | ||
|  | 	( X=0;X=1), | ||
|  | 	label_bool(L). | ||
|  | 
 | ||
|  | /*								% no write macros in SICStus and hProlog | ||
|  | 
 | ||
|  | bool_portray(and(A,B,C),Out):- !, Out = (A*B = C). | ||
|  | bool_portray(or(A,B,C),Out):- !, Out = (A+B = C). | ||
|  | bool_portray(xor(A,B,C),Out):- !, Out = (A#B = C). | ||
|  | bool_portray(neg(A,B),Out):- !, Out = (A= not(B)). | ||
|  | bool_portray(imp(A,B),Out):- !, Out = (A -> B). | ||
|  | bool_portray(card(A,B,L,N),Out):- !, Out = card(A,B,L). | ||
|  | 
 | ||
|  | :- define_macro(type(compound),bool_portray/2,[write]). | ||
|  | */ | ||
|  | 
 | ||
|  | /* end of handler bool */ | ||
|  | 
 |