% Copyright (C) 2003 Fred Mesnard <fred@univ-reunion.fr>
%
% This file is part of cTI.
%
% cTI is free software; you can redistribute it and/or modify it
% under the terms of the GNU General Public License as published by the
% Free Software Foundation; either version 2 of the License, or (at your
% option) any later version.
%
% cTI is distributed in the hope that it will be useful, but WITHOUT
% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
% FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
% for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program; if not, write to the Free Software
% Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
% USA.
%
% For the most up-to-date information see the cTI's web site:
% http://www.cs.unipr.it/cTI/

%% Fred
%% mars 1997, octobre 1999
%% fevrier 2000

:- module(bool_op,[
		   true/1,
		   false/1,
		   conjunction/3,
		   satisfiable/1,
		   entail/4,
		   equivalent/4,
		   union/6,
		   widening/6,
		   project/4
		  ]).

:-use_module(library(clpb)).

%%%%
true(1).

%%%%
false(0).

%%%%
conjunction(C1,C2,C1*C2).

%%%%
check(G):- \+ \+ call(G).
	
%%%%%
satisfiable( T ):- check(sat(T)).

%%%%%
entail(Xs, S ,Ys, T ):- check( (Xs=Ys,taut(S =< T,1)) ).

%%%%%
equivalent(Xs, S ,Ys, T ):- check( (Xs=Ys, taut(S =:= T, 1)) ).
	
%%%%%
union(Xs, S ,Ys, T ,Zs, U ):-
	copy_term(e(Ys,T),e(Xs,Tcxs)),
	project(Xs,S+Tcxs,Zs,U).

%%%%% a ameliorer
widening(Xs,S,Ys,T,Zs,U):-union(Xs,S,Ys,T,Zs,U).

%%%%%
project(Xs, S ,_,_):-
	sat(S),bb_put(copy,Xs),
	call_residue(bb_delete(copy,Ys),C),gather(C,Cs),
	normalize(Ys,X1s,[],Cs,C2s),
	bb_put(copy,env(X1s,C2s)),
	fail.
project(_,_,Ys, T ):-
	bb_delete(copy,env(Ys,T1)), 
	free_vars(T1,Ys,FreeVars),
	eliminate(FreeVars,T1,T2),
	virer_dernier1(T2,T).

virer_dernier1(C,E):-var(C),!,E=C.
virer_dernier1(C*D,E):-var(D),!,E=C*D.
virer_dernier1(C*1,E):-!,E=C.
virer_dernier1(C,C).

gather([],1).
gather([_-sat(C)|Cs],T):-gather(Cs,C,T).
	
gather([],C,C).
gather([_-sat(C1)|Cs],C2,T):-gather(Cs,C2*C1,T).
	
normalize([],[],_,Cs,Cs).
normalize([X|Xs],[Y|Ys],Vars,C1s,C2s):-
	var(X),member_var(Vars,X),!,normalize(Xs,Ys,Vars,(Y=:=X)*C1s,C2s).
normalize([X|Xs],[X|Ys],Vars,C1s,C2s):-
	var(X),!,normalize(Xs,Ys,[X|Vars],C1s,C2s).
normalize([X|Xs],[Y|Ys],Vars,C1s,C2s):-
	(X=0 -> Z= ~Y ;  Z=Y),
	normalize(Xs,Ys,Vars,Z*C1s,C2s).	
	

member_var([Y|_],X):-X==Y,!.
member_var([_|Ys],X):-member_var(Ys,X).
	
free_vars(Term,Vars,FreeVars):-fv(Term,Vars,[],FreeVars).

fv(X,Vars,FV,FV):-var(X), (member_var(Vars,X) ; member_var(FV,X)),!.
fv(X,_,FV,[X|FV]):-var(X), !.
fv(X,_,FV,FV):-ground(X),!.
fv(~T,Vars,FV1,FV2):-!,fv(T,Vars,FV1,FV2).
fv(T,Vars,FV1,FV2):-T=..[_,T1,T2],fv(T1,Vars,FV1,FV3),fv(T2,Vars,FV3,FV2).
		
eliminate([],T,T).
eliminate([X|Xs],T,U):-eliminate(Xs,(X^T),U).
	

/* 

exemples
	bool_project([X,Y],(X=:=0)*(X=:=Y),A,B).
	bool_project([X,Y],X=:=Y+Z,A,B).
	bool_project([X,Y],(X=:=Y+Z)*(X=:=Y),A,B).
	bool_project([X,Y],X=:=Y+a,A,B).
	bool_project([X,Y,Z],X*Z+(Y=:=1),A,B).
	


fa(Vars,Tb,S) :-
	findall(Vars,(sat(Tb),labeling(Vars)),S).

*/












