1 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2 % Author
: Tom Schrijvers
3 % Email
: Tom
.Schrijvers
@cs.kuleuven
.be
4 % Copyright
: K
.U
.Leuven
2004
5 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7 %% / ___|___ __| | ___ / ___
| | ___ __ _ _ __
(_
)_ __ __ _
8 %% | | / _ \ / _
` |/ _ \ | | | |/ _ \/ _` | '_ \| | '_ \
/ _
` |
9 %% | |__| (_) | (_| | __/ | |___| | __/ (_| | | | | | | | | (_| |
10 %% \____\___/ \__,_|\___| \____|_|\___|\__,_|_| |_|_|_| |_|\__, |
22 :- use_module(hprolog).
24 clean_clauses(Clauses,NClauses) :-
25 clean_clauses1(Clauses,Clauses1),
26 merge_clauses(Clauses1,NClauses).
29 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
32 % - move neck unification into the head of the clause
34 % - specialize control flow goal wrt true and fail
36 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
38 clean_clauses1([],[]).
39 clean_clauses1([C|Cs],[NC|NCs]) :-
41 clean_clauses1(Cs,NCs).
43 clean_clause(Clause,NClause) :-
44 ( Clause = (Head :- Body) ->
45 clean_goal(Body,Body1),
46 move_unification_into_head(Head,Body1,NHead,NBody),
50 NClause = (NHead :- NBody)
52 ; Clause = '$source_location'(File,Line) : ActualClause ->
53 NClause = '$source_location'(File,Line) : NActualClause,
54 clean_clause(ActualClause,NActualClause)
59 clean_goal(Goal,NGoal) :-
62 clean_goal((G1,G2),NGoal) :-
73 clean_goal((If -> Then ; Else),NGoal) :-
77 clean_goal(Then,NThen),
80 clean_goal(Else,NElse),
83 clean_goal(Then,NThen),
84 clean_goal(Else,NElse),
85 NGoal = (NIf -> NThen; NElse)
87 clean_goal((G1 ; G2),NGoal) :-
98 clean_goal(once(G),NGoal) :-
108 clean_goal((G1 -> G2),NGoal) :-
119 clean_goal(Goal,Goal).
120 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
121 move_unification_into_head(Head,Body,NHead,NBody) :-
122 conj2list(Body,BodyList),
123 move_unification_into_head_(BodyList,Head,NHead,NBody).
125 move_unification_into_head_([],Head,Head,true).
126 move_unification_into_head_([G|Gs],Head,NHead,NBody) :-
127 ( nonvar(G), G = (X = Y) ->
128 term_variables(Gs,GsVars),
129 ( var(X), ( \+ memberchk_eq(X,GsVars) ; atomic(Y)) ->
131 move_unification_into_head_(Gs,Head,NHead,NBody)
132 ; var(Y), (\+ memberchk_eq(Y,GsVars) ; atomic(X)) ->
134 move_unification_into_head_(Gs,Head,NHead,NBody)
137 list2conj([G|Gs],NBody)
141 list2conj([G|Gs],NBody)
145 conj2list(Conj,L) :- %% transform conjunctions to list
146 conj2list(Conj,L,[]).
151 conj2list(true,L,L) :- !.
152 conj2list(Conj,L,T) :-
156 conj2list(G,[G | T],T).
159 list2conj([G],X) :- !, X = G.
160 list2conj([G|Gs],C) :-
161 ( G == true -> %% remove some redundant trues
168 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
171 % Find common prefixes of successive clauses and share them.
173 % Note: we assume that the prefix does not generate a side effect.
175 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
177 merge_clauses([],[]).
178 merge_clauses([C],[C]).
179 merge_clauses([X,Y|Clauses],NClauses) :-
180 ( merge_two_clauses(X,Y,Clause) ->
181 merge_clauses([Clause|Clauses],NClauses)
183 NClauses = [X|RClauses],
184 merge_clauses([Y|Clauses],RClauses)
187 merge_two_clauses('$source_location'(F1,L1) : C1,
188 '$source_location'(_F2,_L2) : C2,
190 merge_two_clauses(C1,C2,C),
191 Result = '$source_location'(F1,L1) : C.
192 merge_two_clauses(H1 :- B1, H2 :- B2, H :- B) :-
197 merge_lists(List1,List2,H1,H2,Unifier,List,NList1,NList2),
201 list2conj(List,Prefix),
202 list2conj(NList1,NB1),
206 list2conj(NList2,NB2),
207 B = (Prefix,(NB1 ; NB2))
210 merge_lists([],[],_,_,true,[],[],[]).
211 merge_lists([],L2,_,_,true,[],[],L2).
212 merge_lists([!|Xs],_,_,_,true,[!|Xs],[],!) :- !.
213 merge_lists([X|Xs],[],_,_,true,[],[X|Xs],[]).
214 merge_lists([X|Xs],[Y|Ys],H1,H2,Unifier,Common,N1,N2) :-
216 Unifier = (X = Y, RUnifier),
217 Common = [X|NCommon],
218 merge_lists(Xs,Ys,H1/X,H2/Y,RUnifier,NCommon,N1,N2)