% 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/

:- module(main,[current_cti_flag/2,
		set_cti_flag/2,
		program_termination_conditions/2,
		file_termconds/2,
		file_expand_termconds/2]).

:- dynamic(current_cti_flag/2).

%----------- Sicstus libraries --------------------------------------------------------
% all SP libraries we need are referenced below:
%--------------------------------------------------------------------------------------
:- use_module(library(ugraphs)).
:- use_module(library(lists)).
:- use_module(library(assoc)).
:- use_module(library(terms)).
:- use_module(library(clpb)).
:- use_module(library(clpq)).
:- use_module(library(timeout)).
:- use_module(library(system)).
%----------- cTI files ----------------------------------------------------------------
% all files we need are referenced below:
%--------------------------------------------------------------------------------------
:- use_module(predef).		            % ISO-Prolog predefs
:- use_module(utils).       		    % utilities
:- use_module(db).                          % db management
:- use_module(term_size).                   % term_size code
:- use_module(time).                        % timings utilities
:- use_module(clpq_clpn).                   % clp(Q) constraints to clp(N) constraints
%--------------------------------------------------------------------------------------
:- use_module(prolog_flatprolog).           % ISO-Prolog to FlatPrologh
:- use_module(prolog_clph).                 % FlatProlog to clp(H)
:- use_module(prolog_trad_cd).              % cTI directives 
%---------------------------------------------------------------------------------------
:- use_module(num_itp).                     % fix-point poly_ppl/poly_clpq
:- use_module(num_clph_clpn).	            % clp(H) to clp(N)
:- use_module(num_prolog_clpn).	            % ISO-Prolog to clp(N)
:- use_module(num_op,[]).                   % meta ops for clp(Q)
:- use_module(num_add_model_al).            % adding prop to prog
:- use_module(num_dual).                    % dual
:- use_module(num_cmc).                     % compute matrix/column
:- use_module(num_constr_lm).               % compute all level mappings
:- use_module(num_concrete_lm).             % generate max level mappings
%---------------------------------------------------------------------------------------
:- use_module(bool_itp).                    % fix-point clp(B)
:- use_module(bool_op,[]).    		    % meta-operations sur clp(bool)
:- use_module(bool_nat_bool).               % clp(N) to clp(B)
:- use_module(bool_lm_nat_bool).            % lm max clp(N) to  lm bool
:- use_module(bool_dc).                     % transfo Bool -> FPos
:- use_module(bool_term_cond).	    	    % calcul de conditions de terminaison
:- use_module(contrib_mu).                  % mu-calculator written by Serge Colin
%---------------------------------------------------------------------------------------
:- use_module(quantify).                    % calcul quantif modes couverts par cTI
%---------------------------------------------------------------------------------------
:- include(flag).                           % current_cti_flag/2 and set_cti_flag/2
:- include(file_termconds).                 % reading files and processing directives
%---------------------------------------------------------------------------------------
:- use_module(poly_ppl).
:- use_module(poly_clpq).
%---------------------------------------------------------------------------------------
% 
:-	F='/usr/local/lib/ppl/ppl_sicstus.pl',
        (file_exists(F) ->
	    compile(F),
	    user:ppl_initialize,
	    Lib=ppl,
	    assert(current_cti_flag(poly_lib,poly_ppl))
	;
	    write('Please install the PPL.'),
	    halt(1),
	    Lib=clpq,
	    assert(current_cti_flag(poly_lib,poly_clpq))),
	write('*  Polyhedra library is '),write(Lib),nl.
%---------------------------------------------------------------------------------------

program_termination_conditions(ListClausesProlog,ListTermConds) :-
	stat_init(Stat0),
        prologs_clpns(ListClausesProlog,ListClausesClpN),
	add_stat(Stat0,isopl_clpn,Stat1),
	%current_cti_flag(compare_ppl_clpq,CompPplClpq),
	current_cti_flag(nb_ite_clpn,NbIteCLPN),
	current_cti_flag(poly_lib,PolyLib), current_cti_flag(time_out,TimeOut),
	Options=[%comp=CompPplClpq,
		 nb=NbIteCLPN,poly=PolyLib,to=TimeOut],
	clpn_tc_(ListClausesClpN,Options,ListTermConds0,UP,_RN,_LM,_RB,Stat1,Stat2),
	stat_final(Stat2),
	possibly_nonterm_predicates(ListTermConds0,NonTermPreds),
	sort(ListTermConds0,ListTermConds),
	quantify(ListTermConds),
	(UP==[] -> true;(write('% Undefined predicates assumed to fail:'),write(UP),nl)),
	(NonTermPreds=[] -> true;(write('% Possibly non-terminating predicates: '),write(NonTermPreds),nl)).

clpn_tc_(ListClausesClpN,Options,ListTermConds,UndefPreds,RelsInterArgsN,LevelMappings,
	 RelsInterArgsBool,Stat1,Stat) :-
	Options=[%comp=CompPplClpq,
		 nb=NbIteCLPN,poly=PolyLib,to=TimeOut],
	call_graph(ListClausesClpN,CallGraph),
	graph_sccs(CallGraph,Sccs), %write(CallGraph),nl,write(Sccs),nl,
	length(Sccs,LengthSccs),write('% |Sccs|='),write(LengthSccs),nl,
	
	empty_db(Db0),
	add_cls_domain_dbs(ListClausesClpN,clpn,Db0,Db1),
	cg_db_domain_undefpred(CallGraph,Db1,clpn,UndefPreds),%write_list(UndefPreds),nl,
	sccs_db_domain_sccscls(Sccs,Db1,clpn,SccsClsN), %write(SccsClsN),
	
	%(CompPplClpq==on -> comp_lib(SccsClsN,NbIteCLPN,TimeOut);true),
	write('% n-model ...'),nl,
	ntp(SccsClsN,PolyLib,NbIteCLPN,BaseN,[star-widening],TimeOut),
	add_stat(Stat1,model_clpn,Stat2),
	assoc_to_list(BaseN,RelsInterArgsN), %write_list(RelsInterArgsN),
	add_prop_domain_dbs(RelsInterArgsN,modeln,Db1,Db2), %print_db(Db1),

	add_model_after_litt(SccsClsN,Db2,modeln,SccsClsNSpec), %nl,write_list(SccsClsNSpec),
	write('% constr-lm ...'),nl,
        constr_lm(SccsClsNSpec,ConsLevelMappings,TimeOut),%write_list(ConsLevelMappings),
	add_stat(Stat2,constr__lm,Stat3),
	write('% concr-lm ...'),nl,
	concrete_lm(ConsLevelMappings,LevelMappings,TimeOut),%write_list(LevelMappings),
	add_stat(Stat3,concret_lm,Stat4),
	lm_nat_bool(LevelMappings,BoolLevelMappings),%write_list(BoolLevelMappings),
	add_prop_domain_dbs(BoolLevelMappings,blm,Db2,Db3),

	%nat_bool(SccsClsNSpec,SccsClsB), %nl,write_list(SccsClsB), % pour pdt crois'e
	nat_bool(SccsClsN,SccsClsB), %nl,write_list(SccsClsB),
	add_stat(Stat4,pgnat_bool,Stat5),
	write('% b-model ...'),nl,
	tp(SccsClsB,bool_op,no_widening,BaseBool,[star-union],TimeOut),
	add_stat(Stat5,model_bool,Stat6),
	assoc_to_list(BaseBool,RelsInterArgsBool),%write_list(RelsInterArgsBool),
	add_prop_domain_dbs(RelsInterArgsBool,modelb,Db3,Db4),%print_db(Db4),
	write('% term-cond ...'),nl,
	term_cond(SccsClsB,Db4,Db5,TimeOut),%print_db(Db5),
	add_stat(Stat6,term_conds,Stat),
	get_sccs_domain_db_props(Sccs,termcond,Db5,ListTermConds).

/*
% to compare PPL and clpq:
comp_lib(SccsClsN,NbIteCLPN,TimeOut) :-
	current_cti_flag(poly_lib,PolyLib),

	set_cti_flag(poly_lib,poly_clpq),
            nl,write('tp-CLPQ pre PPL: '),
	    statistics(runtime,_),NbIteCLPN_pour_tp is max(1,NbIteCLPN -1),
	    tp(SccsClsN,num_op,NbIteCLPN_pour_tp,BaseN0,[star-widening],TimeOut),
	    statistics(runtime,[_,Tclpq0]),
	    write(Tclpq0),write(' ms'),nl,
	    
%%% 	set_cti_flag(poly_lib,poly_clpq),
%%% 	    nl,write('ntp-CLPQ post PPL: '),
%%% 	    statistics(runtime,_),
%%% 	    ntp(SccsClsN1,poly_clpq,NbIteCLPN,BaseN1,[star-widening],TimeOut),
%%% 	    statistics(runtime,[_,Tclpq1]),
%%% 	    write(Tclpq1),write(' ms'),nl,

	set_cti_flag(poly_lib,poly_ppl),
	    write('ntp-PPL: '),
	    statistics(runtime,_),
	    ntp(SccsClsN,poly_ppl,NbIteCLPN,BaseN2,[star-widening],TimeOut),
	    statistics(runtime,[_,Tppl]),
	    write(Tppl),write(' ms'),nl,

	set_cti_flag(poly_lib,PolyLib),
	RV is Tclpq0/Tppl,
	write('clpq/ppl:'),write(RV),nl,%format("~2d%",[RV]),nl,
	assoc_to_list(BaseN0,RelsInterArgsN0),	
%%%	assoc_to_list(BaseN1,RelsInterArgsN1),	
	assoc_to_list(BaseN2,RelsInterArgsN2),
	%write('Model CLPQ : '),nl,write_list(RelsInterArgsN1),
	%write('Model PPL : '),nl,write_list(RelsInterArgsN2),nl,
	write('Difference between models: '),nl,
%%%	write('tp-clpq/ntp-clpq:'),nl,
%%%	compare_ris(RelsInterArgsN0,RelsInterArgsN1),
%%%	write('ntp-clpq/ntp-ppl:'),nl,
%%%	compare_ris(RelsInterArgsN1,RelsInterArgsN2),
%%%	write('tp-clpq/ntp-ppl:'),nl,
	compare_ris(RelsInterArgsN0,RelsInterArgsN2),

	write('Done.'),nl,
	abort.

*/
