/* File: flrdependency.P -- the dependency checker ** ** Author(s): Chang Zhao ** ** Contact: flora-users@lists.sourceforge.net ** ** Copyright (C) The Research Foundation of SUNY, 2002 ** ** FLORA-2 is free software; you can redistribute it and/or modify it under the ** terms of the GNU Library General Public License as published by the Free ** Software Foundation; either version 2 of the License, or (at your option) ** any later version. ** ** FLORA-2 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 Library General Public License for ** more details. ** ** You should have received a copy of the GNU Library General Public License ** along with FLORA-2; if not, write to the Free Software Foundation, ** Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** $Id: flrdependency.P,v 1.12 2003/06/18 07:01:37 kifer Exp $ ** */ %%%% Check dependency of tabled predicates on updates or procedural methods. %%%% Such dependency is considered a likely error and warning is issued. %%%% %%%% Usage: check_for_dependencies(+CodeList,-ErrWarnList) %%%% generate_rules(+CodeList) %%%% depend(+Sk1,+Sk2,+Option). :- compiler_options([xpp_on]). #include "flora_terms.flh" #include "flora_errors.flh" #define MAXDEPTH 3 #define STARTPOINT 1 #define DEFAULT_WORKSPACE '' #mode save #mode nostring "\!#'" #define PREFIXING(X) FLORA_USER_MODULE_PREFIX'''#1' #mode restore #define PREFIXED_WRAP_ISA PREFIXING(WRAP_ISA) #define PREFIXED_WRAP_SUB PREFIXING(WRAP_SUB) #define PREFIXED_WRAP_FD PREFIXING(WRAP_FD) #define PREFIXED_WRAP_IFD PREFIXING(WRAP_IFD) #define PREFIXED_WRAP_METH PREFIXING(WRAP_METH) #define PREFIXED_WRAP_IMETH PREFIXING(WRAP_IMETH) #define PREFIXED_WRAP_FDSIG PREFIXING(WRAP_FDSIG) #define PREFIXED_WRAP_MVDSIG PREFIXING(WRAP_MVDSIG) #define PREFIXED_WRAP_IFDSIG PREFIXING(WRAP_IFDSIG) #define PREFIXED_WRAP_IMVDSIG PREFIXING(WRAP_IMVDSIG) #define PREFIXED_WRAP_MVD PREFIXING(WRAP_MVD) #define PREFIXED_WRAP_IMVD PREFIXING(WRAP_IMVD) #define PREFIXED_WRAP_EXISTS PREFIXING(WRAP_EXISTS) #define PREFIXED_WRAP_FDDEF PREFIXING(WRAP_FDDEF) #define PREFIXED_WRAP_IFDDEF PREFIXING(WRAP_IFDDEF) #define PREFIXED_WRAP_MVDDEF PREFIXING(WRAP_MVDDEF) #define PREFIXED_WRAP_IMVDDEF PREFIXING(WRAP_IMVDDEF) #define PREFIXED_WRAP_OBJEQL PREFIXING(WRAP_OBJEQL) #define PREFIXED_WRAP_TRAN PREFIXING(WRAP_TRAN) #define PREFIXED_WRAP_HILOG PREFIXING(WRAP_HILOG) /**************************************************************************** utilities ****************************************************************************/ default_tabled(PREFIXED_WRAP_ISA,2). default_tabled(PREFIXED_WRAP_SUB,2). default_tabled(PREFIXED_WRAP_FD,3). default_tabled(PREFIXED_WRAP_IFD,3). default_tabled(PREFIXED_WRAP_METH,2). default_tabled(PREFIXED_WRAP_IMETH,2). default_tabled(PREFIXED_WRAP_FDSIG,3). default_tabled(PREFIXED_WRAP_MVDSIG,3). default_tabled(PREFIXED_WRAP_IFDSIG,3). default_tabled(PREFIXED_WRAP_IMVDSIG,3). default_tabled(PREFIXED_WRAP_MVD,3). default_tabled(PREFIXED_WRAP_IMVD,3). default_tabled(PREFIXED_WRAP_EXISTS,1). default_tabled(PREFIXED_WRAP_FDDEF,2). default_tabled(PREFIXED_WRAP_IFDDEF,2). default_tabled(PREFIXED_WRAP_MVDDEF,2). default_tabled(PREFIXED_WRAP_IMVDDEF,2). default_tabled(PREFIXED_WRAP_OBJEQL,2). procedural(PREFIXED_WRAP_TRAN,2). dboperation(FLLIBINSERT,1). dboperation(FLLIBINSERTALL,1). dboperation(FLLIBBTINSERT,1). dboperation(FLLIBBTINSERTALL,1). dboperation(FLLIBDELETE,1). dboperation(FLLIBDELETEALL,1). dboperation(FLLIBBTDELETE,1). dboperation(FLLIBBTDELETEALL,1). dboperation(FLLIBERASE,1). dboperation(FLLIBERASEALL,1). dboperation(FLLIBBTERASE,1). dboperation(FLLIBBTERASEALL,1). dboperation(FLLIBINSERT,2). dboperation(FLLIBINSERTALL,2). dboperation(FLLIBBTINSERT,2). dboperation(FLLIBBTINSERTALL,2). dboperation(FLLIBDELETE,2). dboperation(FLLIBDELETEALL,2). dboperation(FLLIBBTDELETE,2). dboperation(FLLIBBTDELETEALL,2). dboperation(FLLIBERASE,2). dboperation(FLLIBERASEALL,2). dboperation(FLLIBBTERASE,2). dboperation(FLLIBBTERASEALL,2). is_upd(FLLIBINSERT(List,Condition),insert,List,Condition) :- !. is_upd(FLLIBBTINSERT(List,Condition),btinsert,List,Condition) :- !. is_upd(FLLIBDELETE(List,Condition),delete,List,Condition) :- !. is_upd(FLLIBBTDELETE(List,Condition),btdelete,List,Condition) :- !. is_upd(FLLIBERASE(List,Condition),erase,List,Condition) :- !. is_upd(FLLIBBTERASE(List,Condition),bterase,List,Condition) :- !. is_updall(FLLIBINSERTALL(List,Condition),insertall,List,Condition) :- !. is_updall(FLLIBBTINSERTALL(List,Condition),btinsertall,List,Condition) :- !. is_updall(FLLIBDELETEALL(List,Condition),deleteall,List,Condition) :- !. is_updall(FLLIBBTDELETEALL(List,Condition),btdeleteall,List,Condition) :- !. is_updall(FLLIBERASEALL(List,Condition),eraseall,List,Condition) :- !. is_updall(FLLIBBTERASEALL(List,Condition),bteraseall,List,Condition) :- !. is_upd(FLLIBINSERT(List),insert,List,_) :- !. is_upd(FLLIBBTINSERT(List),btinsert,List,_) :- !. is_upd(FLLIBDELETE(List),delete,List,_) :- !. is_upd(FLLIBBTDELETE(List),btdelete,List,_) :- !. is_upd(FLLIBERASE(List),erase,List,_) :- !. is_upd(FLLIBBTERASE(List),bterase,List,_) :- !. is_updall(FLLIBINSERTALL(List),insertall,List,_) :- !. is_updall(FLLIBBTINSERTALL(List),btinsertall,List,_) :- !. is_updall(FLLIBDELETEALL(List),deleteall,List,_) :- !. is_updall(FLLIBBTDELETEALL(List),btdeleteall,List,_) :- !. is_updall(FLLIBERASEALL(List),eraseall,List,_) :- !. is_updall(FLLIBBTERASEALL(List),bteraseall,List,_) :- !. is_agg(FLLIBMIN(Var,Group,Cond,Result),min,Var,Group,Cond,Result) :- !. is_agg(FLLIBMAX(Var,Group,Cond,Result),max,Var,Group,Cond,Result) :- !. is_agg(FLLIBSUM(Var,Group,Cond,Result),sum,Var,Group,Cond,Result) :- !. is_agg(FLLIBAVG(Var,Group,Cond,Result),avg,Var,Group,Cond,Result) :- !. is_agg(FLLIBCOUNT(Var,Group,Cond,Result),count,Var,Group,Cond,Result) :- !. is_agg(FLLIBCOLLECTSET(Var,Group,Cond,Result),collectset,Var,Group,Cond,Result) :- !. is_agg(FLLIBCOLLECTBAG(Var,Group,Cond,Result),collectbag,Var,Group,Cond,Result) :- !. is_control(FLLIBIFTHEN(If,Then),FLLIBIFTHEN,[If,Then]) :- !. is_control(FLLIBIFTHENELSE(If,Then,Else),FLLIBIFTHENELSE,[If,Then,Else]) :- !. is_constraint(PRCONSTRAINT(Constr),Constr). /**************************************************************************** cut_off(+Term_before_cutoff,-Term_after_cutoff) cut off a term whose depth is greater than MAXDEPTH ****************************************************************************/ cut_off(T1,T2) :- cut_off(T1,T2,1). cut_off(T1,T2,N) :- ( N>MAXDEPTH -> writeln('Too deep'), fail ; ( (atomic(T1); var(T1)) -> T2=T1, ! ; ( N=MAXDEPTH -> functor(T1,Func,Nargs), functor(T2,Func,Nargs) ; NewN is N+1, T1 =.. [Func|Args], cut_off_list(Args,NewArgs,NewN), T2 =.. [Func|NewArgs] ) ) ). cut_off_list([],[],_) :- !. cut_off_list([H|T],[NewH|NewT],N) :- cut_off(H,NewH,N), cut_off_list(T,NewT,N). /**************************************************************************** depth(+Term,-Depth_of_the_term) compute the depth of a term ****************************************************************************/ depth(X,0) :- atomic(X), !. depth(X,0) :- var(X), !. depth(X,N1) :- !, X =.. [_F|Y], param_depth(Y,N), N1 is N+1. /**************************************************************************** param_depth(+ParamList,-MaxDepth) given a list of parameters, returns the max depth of all params ****************************************************************************/ param_depth([X],N) :- depth(X,N),!. param_depth([H|T],N) :- depth(H,N1), param_depth(T,N2), ( (N1>N2) -> N = N1 ; N = N2 ). /**************************************************************************** depend(+Sk1,+Sk2,-T1,-T2,+Option) possible options: u -- depends on update a -- depends on aggregation n -- depends negatively p -- depends positively arb -- arbitrary check whether Sk1 depends on Sk2 with given option, T1 and T2 are instantiations of Sk1 and Sk2, respectively ****************************************************************************/ depend(Sk1,Sk2,T1,T2,Opt) :- retractall(dependency(_,_,_,_)), depend(Sk1,Sk2), dependency((T1,_IT1),(T2,_IT2),anu(A,N,U),_), ( (Opt=u, atom(U)) ; (Opt=a, atom(A)) ; (Opt=n, atom(N)) ; (Opt=p, var(N)) ; (Opt=arb) ). /**************************************************************************** depend(+Sk1,+Sk2,+Option) decides whether Sk1 dependes on Sk2 without caring about the instantiations ****************************************************************************/ depend(Sk1,Sk2,Opt) :- depend(Sk1,Sk2,_IT1,_IT2,Opt). /**************************************************************************** depend(+Sk1,+Sk2) decide whether term skeleton Sk1 depends on Sk2 and whether the dependency is through aggregation, negation, update dependency/4 will be asserted for each path pattern from Sk1 to Sk2 ****************************************************************************/ depend(Sk1,Sk2) :- retractall(target(_)), ( is_list(Sk2) -> list_to_targets(Sk2) ; assert(target(Sk2)) ), findall((RuleHead),match_rule(Sk1,RuleHead,_,_),HeadList), remove_dup(HeadList,NewHeadList), depend_list(NewHeadList). list_to_targets([]) :- !. list_to_targets([H|T]) :- assert(target(H)), list_to_targets(T). remove_dup([],[]) :- !. remove_dup([H|T],NewList) :- ( member(H,T) -> remove_dup(T,NewList) ; remove_dup(T,InterList), NewList = [H|InterList] ). depend_list([]) :- !. depend_list([(H)|T]) :- retractall(dependency(_,_,_)), depend_detail(H), findall((Body,anu(A,N,U),Templete), dependency(Body,anu(A,N,U),Templete), DependencyList), assert_dependency_list(H,DependencyList), depend_list(T). assert_dependency_list(_,[]) :- !. assert_dependency_list(Term,[(Body,anu(A,N,U),Templete)|T]) :- assert(dependency(Term,Body,anu(A,N,U),Templete)), assert_dependency_list(Term,T). depend_detail((_Sk1,IndSk1)) :- retractall(checked(_)), findall((RuleBody,anu(A,N,U)), same_rule(IndSk1,_RuleHead,RuleBody,anu(A,N,U)), BodyList), my_append([],BodyList,L,STARTPOINT,_Template), traversal(L). /**************************************************************************** traversal(+List) BFS for all possible dependencies from Sk1 to Sk2. Originally List only contains terms that Sk1 directly depends on. Sk2 is asserted by target(Sk2). Each time the first element of the list is taken out. We find the rules whose heads can unify with this element and consider the bodies of those rules. If 1) the rule body unifies with Sk2, then we have found a dependency 2) we have checked the body (asserted by checked/1) with the same (A,N,U) and Template value, then it will be discarded 3) otherwise, the body and its cut-off form will be put to the end of List ****************************************************************************/ traversal([]) :- !. traversal([Head|Tail]) :- Head = (Term,(T,IndTerm),anu(A,N,U),Times,Template), compare_with_target(Term,(T,IndTerm),anu(A,N,U),Template), ( (checked((CT,anu(A1,N1,U1),Template1)), subsumes(CT,Term), variant((A1,N1,U1,Template1),(A,N,U,Template))) -> NewList=Tail ; assert(checked((Term,anu(A,N,U),Template))), findall((RuleBody,anu(A,N,U)), match_rule(Term,_RuleHead,RuleBody,anu(A,N,U)), BodyList), NewTimes is Times+1, my_append(Tail,BodyList,NewList,NewTimes,Template) ), traversal(NewList). my_append(List,[],List,_,_) :- !. my_append(List,[Head|Tail],NewList,Times,Template) :- Head = ((RuleBody,IndRuleBody),anu(A,N,U)), ( (depth((RuleBody),Depth),Depth>MAXDEPTH) -> cut_off(RuleBody,NewBody), TT=tt ; NewBody=RuleBody, TT=Template ), NewTerm = (NewBody,(RuleBody,IndRuleBody),anu(A,N,U),Times,TT), TempList=[NewTerm|List], my_append(TempList,Tail,NewList,Times,Template). compare_with_target(Term,(T,IndTerm),anu(A,N,U),Template) :- target(Sk2), Term=Sk2, assert(dependency((T,IndTerm),anu(A,N,U),Template)), fail. compare_with_target(_Term,(_T,_IndTerm),anu(_A,_N,_U),_Template). /**************************************************************************** match_rule(+Term,-Head,-Body,?anu(A,N,U)) find rules whose heads unify with Term ****************************************************************************/ match_rule(T,(H,IH),B,anu(A,N,U)) :- rule((H,IH),B,anu(A,N,U)), T=H. /**************************************************************************** same_rule(+IndTerm,-Head,-Body,?anu(A,N,U)) find rules whose heads unify with Term ****************************************************************************/ same_rule(IT,(H,IH),B,anu(A,N,U)) :- rule((H,IH),B,anu(A,N,U)), IT=IH. /**************************************************************************** generate_rules(+CodeList) generate rules from intermediate code ****************************************************************************/ generate_rules([]) :- !. generate_rules(CodeList) :- retractall(rule(_,_,_)), parse_codelist(CodeList). /**************************************************************************** parse_codelist(+CodeList) generate rules from a list of intermediate code ****************************************************************************/ parse_codelist([T]) :- !, parse_code(T). parse_codelist([T|L]) :- parse_code(T), parse_codelist(L). parse_code(Term) :- ( is_prrule(Term,Head,Body) -> parse_rule(Head,Body) ; true ). parse_rule(Head,Body) :- flora_build_struct(Head,DEFAULT_WORKSPACE,FLBODYPREFIX,VarList,HeadCode,HCI), flora_build_struct(Body,DEFAULT_WORKSPACE,FLBODYPREFIX,VarList,BodyCode,BCI), assert_rule((HeadCode,HCI),BodyCode,BCI,anu(_,_,_)). assert_rule(_H,BodyCode,_BI,_) :- var(BodyCode), !. assert_rule(HeadCode,BodyCode,(BCI,_I),anu(A,N,U)) :- (BodyCode=','(Body1,Body2); BodyCode=';'(Body1,Body2)), (BCI=','(BCI1,BCI2); BCI=';'(BCI1,BCI2)), !, assert_rule(HeadCode,Body1,BCI1,anu(A,N,U)), assert_rule(HeadCode,Body2,BCI2,anu(A,N,U)). assert_rule(HeadCode,BodyCode,(BCI,_I),anu(A,_,U)) :- (BodyCode=not(NewBody); BodyCode=tnot(NewBody)), (BCI=not(NewBCI); BCI=tnot(NewBCI)), !, assert_rule(HeadCode,NewBody,NewBCI,anu(A,n,U)). assert_rule(_HeadCode,BodyCode,(_BCI,_I),anu(_A,_N,_U)) :- is_constraint(BodyCode,_), !. assert_rule(HeadCode,BodyCode,(BCI,Index),anu(A,N,U)) :- is_upd(BodyCode,_,List,Cond), !, is_upd(BCI,_,(ListI,_I),CondI), assert(rule(HeadCode,(BodyCode,(BCI,Index)),anu(A,N,u))), assert_rule(HeadCode,Cond,CondI,anu(A,N,U)), assert_rules(HeadCode,List,ListI,anu(A,N,u)). assert_rule(HeadCode,BodyCode,(BCI,Index),anu(A,N,U)) :- is_updall(BodyCode,_,List,Cond), !, is_updall(BCI,_,(ListI,_I),CondI), assert(rule(HeadCode,(BodyCode,(BCI,Index)),anu(a,N,u))), assert_rule(HeadCode,Cond,CondI,anu(A,N,U)), assert_rules(HeadCode,List,ListI,anu(A,N,u)). assert_rule(HeadCode,BodyCode,(BCI,Index),anu(_,N,U)) :- is_agg(BodyCode,_,_,_,Condition,_), !, is_agg(BCI,_,_,_,ConditionI,_), assert(rule(HeadCode,(BodyCode,(BCI,Index)),anu(a,N,U))), assert_rule(HeadCode,Condition,ConditionI,anu(a,N,U)). assert_rule(HeadCode,BodyCode,(BCI,_I),anu(A,N,U)) :- is_control(BodyCode,_,Args), !, is_control(BCI,_,ArgsI), assert_rules(HeadCode,Args,ArgsI,anu(A,N,U)). assert_rule(HeadCode,BodyCode,(BCI,_I),anu(A,N,U)) :- BodyCode = flsysdbupdate(NewBody,_,_), !, BCI = flsysdbupdate(NewBCI,_,_), assert_rule(HeadCode,NewBody,NewBCI,anu(A,N,U)). assert_rule(HeadCode,BodyCode,BCwithIndex,anu(A,N,U)) :- assert(rule(HeadCode,(BodyCode,BCwithIndex),anu(A,N,U))). assert_rules(_,[],_,_) :- !. assert_rules(HeadCode,[H|T],[HI|TI],anu(A,N,U)) :- assert_rule(HeadCode,H,HI,anu(A,N,U)), assert_rules(HeadCode,T,TI,anu(A,N,U)). /**************************************************************************** check_for_dependencies(+CodeList,-WarnList) check whether tabled predicates depend on procedural/database operations. ****************************************************************************/ check_for_dependencies(CodeList,WarnList) :- retractall(program_tabled(_,_)), retrieve_program_tabled(CodeList), generate_rules(CodeList), findall((Func1,Arity1), default_tabled(Func1,Arity1), TabledList1), findall((Func1,Arity1,PREFIXED_WRAP_HILOG), program_tabled(Func1,Arity1), TabledList2), append(TabledList1,TabledList2,TabledList), findall((Func2,Arity2), (procedural(Func2,Arity2);dboperation(Func2,Arity2)), ProcList), retractall(warning_seen(_,_,_,_,_)), checking_list(TabledList,ProcList), generate_warnings(WarnList), !. check_for_dependencies(_CodeList,[error(UNKNOWN_ERROR)]). /**************************************************************************** checking_list(+TabledPredicateList,+TargetList) ****************************************************************************/ checking_list([],_) :- !. checking_list([H|T],OpList) :- checking(H,OpList), checking_list(T,OpList). /**************************************************************************** checking(+(Func,Arity),+TargetList) ****************************************************************************/ checking(_,[]) :- !. checking((Func1,Arity1,Wrapper),Ops) :- !, construct_sk(Func1,Arity1,Wrapper,TabledPred), setup_targets(Ops,Targets), ( depend(TabledPred,Targets,arb) -> aggregate_warnings ; true ). checking((Func1,Arity1),Ops) :- functor(TabledPred,Func1,Arity1), setup_targets(Ops,Targets), ( depend(TabledPred,Targets,arb) -> aggregate_warnings ; true ). construct_sk(F,A,Wrapper,Pred) :- number(A), !, length(L,A), Pred =.. [Wrapper,F|L]. construct_sk(F,A,Wrapper,Pred) :- A=FL_SLASH(A1,A2), construct_sk(F,A1,Wrapper,TP), length(L,A2), Pred =.. [Wrapper,TP|L]. /**************************************************************************** setup_targets(+ListOfFuncArity,-TargetList) ****************************************************************************/ setup_targets([],[]) :- !. setup_targets([(Func,Arity)|T],[OpPred|NewT]) :- functor(OpPred,Func,Arity), setup_targets(T,NewT). /**************************************************************************** aggregate_warnings find all asserted dependency/4, generate warnings and aggregate them ****************************************************************************/ aggregate_warnings :- findall(((T1,IT1),(T2,IT2),anu(A,N,U),Temp), dependency((T1,IT1),(T2,IT2),anu(A,N,U),Temp), DependencyList ), aggregate_warnings(DependencyList). aggregate_warnings([]) :- !. aggregate_warnings([((T1,IT1),(T2,IT2),_,_)|T]) :- flora_set_counter(min_ind,0), flora_set_counter(next_min_ind,0), to_string(T1,IT1,Str1,RuleID), flora_get_counter(min_ind,HMinInd), flora_get_counter(next_min_ind,HNMinInd), flora_set_counter(min_ind,0), flora_set_counter(next_min_ind,0), to_string(T2,IT2,Str2,_RID), flora_get_counter(min_ind,BMinInd), ( T2=PREFIXED_WRAP_TRAN(_,_) -> Type = 'procedural method' ; Type = ' db operation' ), fmt_write_string(WarnMsg,"Tabled literal in the head of rule that starts with %s depends on %s %s", args(Str1,Type,Str2)), ( warning_seen(RuleID,HInd1,HInd2,BMinInd,_) -> ( (HInd1 true ; retract(warning_seen(RuleID,HInd1,HInd2,BMinInd,_)), assert(warning_seen(RuleID,HMinInd,HNMinInd,BMinInd,WarnMsg)) ) ; assert(warning_seen(RuleID,HMinInd,HNMinInd,BMinInd,WarnMsg)) ), aggregate_warnings(T). /**************************************************************************** retrieve_program_table(+IntermediateCodeList) ****************************************************************************/ retrieve_program_tabled([]) :- !. retrieve_program_tabled([H|T]) :- ( is_prdirective(H,Direct) -> (is_prtable(Direct,Functor,Arity) -> assert(program_tabled(Functor,Arity)) ; true ) ; true ), retrieve_program_tabled(T). /**************************************************************************** to_string(+Term,+IndexedTerm,-Str,-RuleID) ****************************************************************************/ to_string(Term,(IT,Index),Str,RuleID) :- rebuild_text(Term,(IT,Index),Text), ( (Index==NO_INDEX) -> fmt_write_string(Str,"`%s'",args(Text)), RuleID==NO_INDEX ; flora_token_rulenum(Index,RuleID), flora_nth_token(Index,Token), flora_token_text(Token,_T,BL,BC,_EL,_EC), fmt_write_string(Str,"`%s' near line(%d)/char(%d)", args(Text,BL,BC)) ). /**************************************************************************** rebuild_text(+Term,+IndexdTerm,-Text) return a string for the given term to construct warning message ****************************************************************************/ rebuild_text(_Term,(T,Index),Text) :- (atomic(T);var(T)), !, flora_get_counter(min_ind,MinInd), flora_get_counter(next_min_ind,NextMinInd), ( (Index flora_set_counter(next_min_ind,MinInd), flora_set_counter(min_ind,Index) ; ( (Index flora_set_counter(next_min_ind,Index) ; true ) ), flora_nth_token(Index,Token), flora_token_text(Token,Text,_BL,_BC,_EL,_EC). rebuild_text(Term,(IndTerm,_Ind),Text) :- Term=..['.'|_ListItems], !, rebuild_text_list(Term,IndTerm,ListText), fmt_write_string(Text,"[%s]",args(ListText)). rebuild_text(Term,(_IndT,Index),Text) :- ( is_upd(Term,_Op,_List,_Cond) ; is_updall(Term,_Op,_List,_Cond) ; is_agg(Term,_Op,_Var,_Group,_Condition,_Result) ), !, flora_get_counter(min_ind,MinInd), flora_get_counter(next_min_ind,NextMinInd), ( (Index flora_set_counter(next_min_ind,MinInd), flora_set_counter(min_ind,Index) ; ( (Index flora_set_counter(next_min_ind,Index) ; true ) ), flora_nth_token(Index,Token), flora_token_text(Token,Text,_BL,_BC,_EL,_EC). rebuild_text(Term,(IndT,_Index),Text) :- Term=PREFIXED_WRAP_TRAN(Var,Tran), !, IndT=PREFIXED_WRAP_TRAN(IndVar,IndTran), rebuild_text(Var,IndVar,VarText), rebuild_text(Tran,IndTran,TranText), fmt_write_string(Text,"%s[#%s]",args(VarText,TranText)). rebuild_text(Term,(IndT,_Index),Text) :- Term=PREFIXED_WRAP_ISA(Var,Class), !, IndT=PREFIXED_WRAP_ISA(IndVar,IndClass), rebuild_text(Var,IndVar,VarText), rebuild_text(Class,IndClass,ClassText), fmt_write_string(Text,"%s:%s",args(VarText,ClassText)). rebuild_text(Term,(IndT,_Index),Text) :- Term=PREFIXED_WRAP_SUB(Var,Class), !, IndT=PREFIXED_WRAP_SUB(IndVar,IndClass), rebuild_text(Var,IndVar,VarText), rebuild_text(Class,IndClass,ClassText), fmt_write_string(Text,"%s::%s",args(VarText,ClassText)). rebuild_text(Term,(IndT,_Index),Text) :- Term=PREFIXED_WRAP_METH(Var,Meth), !, IndT=PREFIXED_WRAP_METH(IndVar,IndMeth), rebuild_text(Var,IndVar,VarText), rebuild_text(Meth,IndMeth,MethText), fmt_write_string(Text,"%s[%s]",args(VarText,MethText)). rebuild_text(Term,(IndT,_Index),Text) :- Term=PREFIXED_WRAP_IMETH(Var,IMeth), !, IndT=PREFIXED_WRAP_IMETH(IndVar,IndIMeth), rebuild_text(Var,IndVar,VarText), rebuild_text(IMeth,IndIMeth,IMethText), fmt_write_string(Text,"%s[*%s]",args(VarText,IMethText)). rebuild_text(Term,(IndT,_Index),Text) :- Term=fdskolem(Var,Meth), !, IndT=fdskolem(IndVar,IndMeth), rebuild_text(Var,IndVar,VarText), rebuild_text(Meth,IndMeth,MethText), fmt_write_string(Text,"%s.%s",args(VarText,MethText)). rebuild_text(Term,(IndT,_Index),Text) :- Term=ifdskolem(Var,IMeth), !, IndT=ifdskolem(IndVar,IndIMeth), rebuild_text(Var,IndVar,VarText), rebuild_text(IMeth,IndIMeth,IMethText), fmt_write_string(Text,"%s!%s",args(VarText,IMethText)). rebuild_text(Term,(IndT,_Index),Text) :- Term=PREFIXED_WRAP_FD(Var,Attr,Val), !, IndT=PREFIXED_WRAP_FD(IndVar,IndAttr,IndVal), rebuild_text(Var,IndVar,VarText), rebuild_text(Attr,IndAttr,AttrText), ( (not(var(Val)),(Val=fdskolem(Var,Attr))) -> fmt_write_string(Text,"%s.%s[]",args(VarText,AttrText)) ; rebuild_text(Val,IndVal,ValText), fmt_write_string(Text,"%s[%s->%s]",args(VarText,AttrText,ValText)) ). rebuild_text(Term,(IndT,_Index),Text) :- Term=PREFIXED_WRAP_IFD(Var,Attr,Val), !, IndT=PREFIXED_WRAP_IFD(IndVar,IndAttr,IndVal), rebuild_text(Var,IndVar,VarText), rebuild_text(Attr,IndAttr,AttrText), ( (not(var(Val)),(Val=ifdskolem(Var,Attr))) -> fmt_write_string(Text,"%s!%s[]",args(VarText,AttrText)) ; rebuild_text(Val,IndVal,ValText), fmt_write_string(Text,"%s[%s*->%s]",args(VarText,AttrText,ValText)) ). rebuild_text(Term,(IndT,_Index),Text) :- Term=PREFIXED_WRAP_FDSIG(Var,Attr,Type), !, IndT=PREFIXED_WRAP_FDSIG(IndVar,IndAttr,IndType), rebuild_text(Var,IndVar,VarText), rebuild_text(Attr,IndAttr,AttrText), rebuild_text(Type,IndType,TypeText), fmt_write_string(Text,"%s[%s=>%s]",args(VarText,AttrText,TypeText)). rebuild_text(Term,(IndT,_Index),Text) :- Term=PREFIXED_WRAP_IFDSIG(Var,Attr,Type), !, IndT=PREFIXED_WRAP_IFDSIG(IndVar,IndAttr,IndType), rebuild_text(Var,IndVar,VarText), rebuild_text(Attr,IndAttr,AttrText), rebuild_text(Type,IndType,TypeText), fmt_write_string(Text,"%s[%s*=>%s]",args(VarText,AttrText,TypeText)). rebuild_text(Term,(IndT,_Index),Text) :- Term=PREFIXED_WRAP_MVD(Var,Attr,Val), !, IndT=PREFIXED_WRAP_MVD(IndVar,IndAttr,IndVal), rebuild_text(Var,IndVar,VarText), rebuild_text(Attr,IndAttr,AttrText), rebuild_text(Val,IndVal,ValText), fmt_write_string(Text,"%s[%s->>{%s}]",args(VarText,AttrText,ValText)). rebuild_text(Term,(IndT,_Index),Text) :- Term=PREFIXED_WRAP_IMVD(Var,Attr,Val), !, IndT=PREFIXED_WRAP_IMVD(IndVar,IndAttr,IndVal), rebuild_text(Var,IndVar,VarText), rebuild_text(Attr,IndAttr,AttrText), rebuild_text(Val,IndVal,ValText), fmt_write_string(Text,"%s[%s*->>{%s}]",args(VarText,AttrText,ValText)). rebuild_text(Term,(IndT,_Index),Text) :- Term=PREFIXED_WRAP_MVDSIG(Var,Attr,Type), !, IndT=PREFIXED_WRAP_MVDSIG(IndVar,IndAttr,IndType), rebuild_text(Var,IndVar,VarText), rebuild_text(Attr,IndAttr,AttrText), rebuild_text(Type,IndType,TypeText), fmt_write_string(Text,"%s[%s=>>%s]",args(VarText,AttrText,TypeText)). rebuild_text(Term,(IndT,_Index),Text) :- Term=PREFIXED_WRAP_IMVDSIG(Var,Attr,Type), !, IndT=PREFIXED_WRAP_IMVDSIG(IndVar,IndAttr,IndType), rebuild_text(Var,IndVar,VarText), rebuild_text(Attr,IndAttr,AttrText), rebuild_text(Type,IndType,TypeText), fmt_write_string(Text,"%s[%s*=>>%s]",args(VarText,AttrText,TypeText)). rebuild_text(Term,(IndT,_Index),Text) :- Term=PREFIXED_WRAP_EXISTS(Var), !, IndT=PREFIXED_WRAP_EXISTS(IndVar), rebuild_text(Var,IndVar,VarText), fmt_write_string(Text,"%s[]",args(VarText)). rebuild_text(Term,(IndT,_Index),Text) :- Term=PREFIXED_WRAP_MVDDEF(Var,Attr), !, IndT=PREFIXED_WRAP_MVDDEF(IndVar,IndAttr), rebuild_text(Var,IndVar,VarText), rebuild_text(Attr,IndAttr,AttrText), fmt_write_string(Text,"%s[%s->>{}]",args(VarText,AttrText)). rebuild_text(Term,(IndT,_Index),Text) :- Term=PREFIXED_WRAP_IMVDDEF(Var,Attr), !, IndT=PREFIXED_WRAP_IMVDDEF(IndVar,IndAttr), rebuild_text(Var,IndVar,VarText), rebuild_text(Attr,IndAttr,AttrText), fmt_write_string(Text,"%s[%s*->>{}]",args(VarText,AttrText)). rebuild_text(Term,(IndT,_Index),Text) :- Term=PREFIXED_WRAP_OBJEQL(O1,O2), !, IndT=PREFIXED_WRAP_OBJEQL(IndO1,IndO2), rebuild_text(O1,IndO1,O1Text), rebuild_text(O2,IndO2,O2Text), fmt_write_string(Text,"%s:=:%s",args(O1Text,O2Text)). rebuild_text(Term,(IndT,Index),Text) :- Term=..[F|A], IndT=..[_IndF|IndA], ( (F==PREFIXED_WRAP_HILOG;F==WRAP_HILOG) -> A=[Func|Args], IndA=[IndFunc|IndArgs], rebuild_text(Func,IndFunc,FuncText) ; flora_get_counter(min_ind,MinInd), flora_get_counter(next_min_ind,NextMinInd), ( (Index flora_set_counter(next_min_ind,MinInd), flora_set_counter(min_ind,Index) ; ( (Index flora_set_counter(next_min_ind,Index) ; true ) ), flora_nth_token(Index,Token), flora_token_text(Token,FuncText,_BL,_BC,_EL,_EC), Args=A, IndArgs=IndA ), ( (Args==[]) -> fmt_write_string(Text,"%s",args(FuncText)) ; rebuild_text_list(Args,IndArgs,ArgsText), fmt_write_string(Text,"%s(%s)",args(FuncText,ArgsText)) ). /**************************************************************************** rebuild_text_list(+List,+IndexdList,-Text) ****************************************************************************/ rebuild_text_list(L,(_Var,Index),Text) :- var(L), !, flora_get_counter(min_ind,MinInd), flora_get_counter(next_min_ind,NextMinInd), ( (Index flora_set_counter(next_min_ind,MinInd), flora_set_counter(min_ind,Index) ; ( (Index flora_set_counter(next_min_ind,Index) ; true ) ), flora_nth_token(Index,Token), flora_token_text(Token,Text,_BL,_BC,_EL,_EC). rebuild_text_list([],_,'') :- !. rebuild_text_list([H|L],[IndH|IndL],Text) :- ( var(L) -> rebuild_text(H,IndH,HText), ( (IndL=..['.'|_ListItems]) -> rebuild_text_list(L,IndL,LText), fmt_write_string(Text,"%s,%s",args(HText,LText)) ; rebuild_text(L,IndL,LText), fmt_write_string(Text,"%s|%s",args(HText,LText)) ) ; ( L==[] -> rebuild_text(H,IndH,Text) ; rebuild_text(H,IndH,HText), ( (IndL=..['.'|_ListItems]) -> rebuild_text_list(L,IndL,LText), fmt_write_string(Text,"%s,%s",args(HText,LText)) ; rebuild_text(L,IndL,LText), fmt_write_string(Text,"%s|%s",args(HText,LText)) ) ) ). /**************************************************************************** generate_warnings(-WarnList) ****************************************************************************/ generate_warnings(WarnList) :- findall((HInd1,BInd,WarnMsg),warning_seen(_,HInd1,_,BInd,WarnMsg),WL), sort(WL, SortedWL), append_warnings(SortedWL,WarnList). append_warnings([],[]) :- !. append_warnings([(_HInd,_BInd,WarnMsg)|T],[warning(WarnMsg)|InterWarnList]) :- append_warnings(T,InterWarnList).