/************************************************************************* * * * YAP Prolog * * * * Yap Prolog was developed at NCCUP - Universidade do Porto * * * * Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 * * * ************************************************************************** * * * File: eval.yap * * Last rev: * * mods: * * comments: optimise disjunction handling * * * *************************************************************************/ :- system_module( '$_eval', [], ['$full_clause_optimisation'/4]). :- use_system_module( terms, [new_variables_in_term/3, variables_within_term/3]). %, portray_clause((H:-BF)) '$full_clause_optimisation'(H, M, B0, BF) :- '$localise_vars_opt'(H, M, B0, BF), !. % the idea here is to make global variables in disjunctions % local. '$localise_vars_opt'(H, M, (B1;B2), (NB1;NB2)) :- '$variables_in_term'(H, [], LV), '$localise_vars'(B1, M, NB1, LV, LV, []), '$localise_disj_vars'(B2, M, NB2, LV, LV, []). '$localise_disj_vars'((B;B2), M, (NB ; NB2), LV, LV0, LEqs) :- !, '$localise_vars'(B, M, NB, LV, LV0, LEqs), '$localise_disj_vars'(B2, M, NB2, LV, LV0, LEqs). '$localise_disj_vars'(B2, M, NB, LV, LV0, LEqs) :- '$localise_vars'(B2, M, NB, LV, LV0, LEqs). '$localise_vars'((A->B), M, (A->NB), LV, LV0, LEqs) :- '$safe_guard'(A, M), !, '$variables_in_term'(A, LV, LV1), '$localise_vars'(B, M, NB, LV1, LV0, LEqs). '$localise_vars'((A;B), M, (NA;NB), LV1, LV0, LEqs) :- !, '$localise_vars'(A, M, NA, LV1, LV0, LEqs), '$localise_disj_vars'(B, M, NB, LV1, LV0, LEqs). '$localise_vars'(((A,B),C), M, NG, LV, LV0, LEqs) :- !, '$flatten_bd'((A,B),C,NB), '$localise_vars'(NB, M, NG, LV, LV0, LEqs). '$localise_vars'((!,B), M, (!,NB), LV, LV0, LEqs) :- !, '$localise_vars'(B, M, NB, LV, LV0, LEqs). '$localise_vars'((X=Y,B), M, (X=Y,NB1), LV, LV0, LEqs) :- var(X), var(Y), !, '$localise_vars'(B, M, NB1, LV, LV0, [X,Y|LEqs]). '$localise_vars'((G,B), M, (G,NB1), LV, LV0, LEqs) :- '$safe_builtin'(G, M), !, '$variables_in_term'(G, LV, LV1), '$add_extra_safe'(G, NLV0, LV0), '$localise_vars'(B, M, NB1, LV1, NLV0, LEqs). '$localise_vars'((G1,B1), _, O, LV, LV0, LEqs) :- !, terms:variables_within_term(LV, B1, Commons), terms:new_variables_in_term(LV, B1, New), copy_term(Commons+New+LEqs+B1, NCommons+NNew+NLEqs+NB1), NNew = New, NLEqs = LEqs, '$gen_equals'(Commons, NCommons, LV0, (G1,NB1), O). '$localise_vars'(G, _, G, _, _, _). '$gen_equals'([], [], _, O, O). '$gen_equals'([V|Commons],[NV|NCommons], LV0, O, NO) :- V == NV, !, '$gen_equals'(Commons,NCommons, LV0, O, NO). '$gen_equals'([V|Commons],[NV|NCommons], LV0, O, OO) :- '$vmember'(V,LV0), OO = (V=NV,'$safe'(NV),NO), '$gen_equals'(Commons,NCommons, LV0, O, NO). '$gen_equals'([V|Commons],[NV|NCommons], LV0, O, OO) :- OO = (V=NV,NO), '$gen_equals'(Commons,NCommons, LV0, O, NO). '$safe_guard'((A,B), M) :- !, '$safe_guard'(A, M), '$safe_guard'(B, M). '$safe_guard'((A;B), M) :- !, '$safe_guard'(A, M), '$safe_guard'(B, M). '$safe_guard'(A, M) :- !, '$safe_builtin'(A, M). '$safe_builtin'(G, Mod) :- '$flags'(G, Mod, Fl, Fl), Fl /\ 0x00008880 =\= 0. '$vmember'(V,[V1|_]) :- V == V1, !. '$vmember'(V,[_|LV0]) :- '$vmember'(V,LV0). '$flatten_bd'((A,B),R,NB) :- !, '$flatten_bd'(B,R,R1), '$flatten_bd'(A,R1,NB). '$flatten_bd'(A,R,(A,R)). '$add_extra_safe'('$plus'(_,_,V)) --> !, [V]. '$add_extra_safe'('$minus'(_,_,V)) --> !, [V]. '$add_extra_safe'('$times'(_,_,V)) --> !, [V]. '$add_extra_safe'('$div'(_,_,V)) --> !, [V]. '$add_extra_safe'('$and'(_,_,V)) --> !, [V]. '$add_extra_safe'('$or'(_,_,V)) --> !, [V]. '$add_extra_safe'('$sll'(_,_,V)) --> !, [V]. '$add_extra_safe'('$slr'(_,_,V)) --> !, [V]. '$add_extra_safe'(C=D,A,B) :- !, ( compound(C) -> '$variables_in_term'(C,E,A) ; E=A ), ( compound(D) -> '$variables_in_term'(D,B,E) ; B=E ). '$add_extra_safe'(_) --> [].