14:- module(logicmoo_util_body_reorder,
15 [ call_body_reorder/3,
16 call_body_reorder_compare/4,
17 enable_body_reorder/0,
18 timeOfFirstAnswer/2,
19 timeOfFirstAnswer_0/2,
20 timeOfFirstAnswer_1/2,
21 reorderBody/2,
22 reorderBody/3,
23 reorderBody/4,
24 guess_reorder/3,
25 callClause/1,
26 make_reordering_key/4,
27 do_body_reorder/4,
28 fasterClause/4,
29 disable_body_reorder/0]). 30
31
32:- module_transparent((
33 call_body_reorder/3,
34 call_body_reorder_compare/4,
35 enable_body_reorder/0,
36 timeOfFirstAnswer/2,
37 timeOfFirstAnswer_0/2,
38 timeOfFirstAnswer_1/2,
39 reorderBody/2,
40 reorderBody/3,
41 reorderBody/4,
42 guess_reorder/3,
43 callClause/1,
44 reorder/0,
45 make_reordering_key/4,
46 do_body_reorder/4,
47 fasterClause/4,
48 disable_body_reorder/0)). 49
50:- thread_local(t_l:noreorder/0). 51
53:-meta_predicate(call_body_reorder(+,+,+)). 54
55:-volatile(lmcache:reordering/3). 56:-dynamic(lmcache:reordering/3). 57
58t_l:noreorder.
59reorder.
60
61reorder_if_var(Var,A,B):- nonvar(Var)-> (call(A),call(B));(call(B),call(A)).
62
63can_reorderBody(_ ,true):-!,fail.
64can_reorderBody(_ ,Body):-member(M,[did,t_l:noreorder,!,call_body_reorder,call_body_reorder_compare,var,nonvar]),contains_f(M,Body),!,fail.
65can_reorderBody(_ ,Body):-member(M,[reorder]),contains_f(M,Body),!.
67
68:-meta_predicate(do_body_reorder(+,?,+,-)). 69
70do_body_reorder(_,_,_,_):-!,fail.
71do_body_reorder(_,_,H,H):- \+ compound(H),!.
72do_body_reorder(Head,Vars,(A;B),(AA;BB)):- !,do_body_reorder(Head,Vars,A,AA),do_body_reorder(Head,Vars,B,BB).
73do_body_reorder(Head,_,Body,Body):- \+ can_reorderBody(Head,Body),!.
74do_body_reorder(Head,Vars,H,HO):-do_body_reorder_e(Head,Vars,H,HO)->H\=@=HO,!.
75do_body_reorder(Head,[],Body,call_body_reorder(Code,Head,BodyLOut)):- fail,
76 conj_to_list_reorder(Body,BodyLOut)->BodyLOut=[_,_|_],
77 gensym(reorderCode,Code),!.
78do_body_reorder(_,_,Body,Body).
79
80do_body_reorder_e(_,_,H,H):- \+ compound(H),!.
81do_body_reorder_e(Head,_,Body,call_body_reorder(Code,Head,BodyLOut)):-
82 Body=..[reorderBody|BodyLOut],!,
83 gensym(reorderCode,Code).
84do_body_reorder_e(Head,Vars,H,HO):-
85 H=..HL, must_maplist(do_body_reorder_e(Head,Vars),HL,HOL),HO=..HOL.
86
87conj_to_list_reorder((A),[A]):- \+ compound(A),!.
88conj_to_list_reorder((A,B),AB):-!,conj_to_list_reorder(A,AL),conj_to_list_reorder(B,BL),append(AL,BL,AB).
89conj_to_list_reorder((A),[A]).
90
91make_reordering_key(Head,C1,C2,Key):-
92 term_variables_of_ex(Head,HeadVars),
93 term_variables_of_ex(C1,C1V),
94 term_variables_of_ex(C2,C2V),
95 make_reordering_vkey(HeadVars,C1V,C2V,Key),!.
96
97
98term_variables_of_ex((C2^_),C2V):-!,term_variables(C2,C2V).
99term_variables_of_ex(C2,C2V):-term_variables(C2,C2V).
100
101shared_len(VA,VB,N3):-ord_subtract(VA,VB,Rest),length(Rest,N3).
102
103pairify_key(VA,VB,(UA^N3^UB)):- length(VA,N1),length(VB,N2),shared_len(VA,VB,N3),UA is N1-N3,UB is N2-N3.
105make_reordering_vkey([],[],[],nonvars).
106make_reordering_vkey([],[],_ ,h0_a0).
107make_reordering_vkey([],_ ,[],h0_b0).
108make_reordering_vkey(_ ,[],[],a0_b0).
109
110make_reordering_vkey([],VA,VB,h0(Key)):-pairify_key(VA,VB,Key).
111make_reordering_vkey(VH,[],VB,a0(Key)):-pairify_key(VH,VB,Key).
112make_reordering_vkey(VH,VA,[],b0(Key)):-pairify_key(VH,VA,Key).
113make_reordering_vkey(VH,VA,VB,open(Key1,Key2,Key3)):-pairify_key(VH,VA,Key3),pairify_key(VH,VB,Key1),pairify_key(VA,VB,Key2).
114
115reorderBody(C1,C2):- call_body_reorder(anon,2,[C1,C2]).
116reorderBody(C1,C2,C3):- call_body_reorder(anon,3,[C1,C2,C3]).
117reorderBody(C1,C2,C3,C4):- call_body_reorder(anon,4,[C1,C2,C3,C4]).
118
119lookup_reorder(Key,In,Out):- lmcache:reordering(Key,In,Out),!.
120save_reorder(Key,In,Out):- call(asserta,lmcache:reordering(Key,In,Out)),!.
121
122call_body_reorder_key(_Code,_Head,Key,C1,C2):- notrace(lookup_reorder(Key,(C1,C2),Found)),!,ereq(Found).
123call_body_reorder_key(_Code,_Head,Key,C1,C2):- notrace(guess_reorder(C1,C2,Reordered)),!,
124 save_reorder(Key,(C1,C2),Reordered),!,ereq(Reordered).
125
126
127call_body_reorder_compare(Code,Head,C1,C2):- notrace(make_reordering_key(Head,C1,C2,Key)),!,
128 call_body_reorder_key(Code,Head,Code-Key,C1,C2).
129
130
131make_body_reorderer(Code,Head,[C2,C1],call_body_reorder_compare(Code,Head,C1,C2)):-!.
132make_body_reorderer(Code,Head,[C3|C12],OUT):- make_body_reorderer(Code,Head,C12,OC12),make_body_reorderer(Code,Head,[OC12,C3],OUT).
133
134call_body_reorder(C,CC):-call_body_reorder(C,C,CC).
135
136:-meta_predicate(call_body_reorder(+,+,+)). 137call_body_reorder(_Code,_Head,[A]):- !,callClause(A).
138call_body_reorder(Code,Head,[A|B]):- !,callClause(A),call_body_reorder(Code,Head,B).
139call_body_reorder(Code,Head,[C1,C2]):- !, call_body_reorder_compare(Code,Head,C1,C2).
140call_body_reorder(Code,Head,[C1,C2,C3]):- call_body_reorder_compare(Code,Head,call_body_reorder_compare(Code,Head,C1,C2),C3).
141
142call_body_reorder(Code,Head,[C1,C2,C3,C4]):-
143 call_body_reorder_compare(Code,Head,call_body_reorder_compare(Code,Head,call_body_reorder_compare(Code,Head,C1,C2),C3),C4).
144
149call_body_reorder(Code,Head,List):- reverse(List,Rev),
150 make_body_reorderer(Code,Head,Rev,OUT),!,ereq(OUT).
151
152call_body_reorder(_Code,Head, List):- member(Var^Call,List), ground(Var), !,delete_eq(List,Var^Call,ListO),!,callClause(Call),call_body_reorder(Head,ListO).
153call_body_reorder(_Code,Head,[A|List]):- !,callClause(A),call_body_reorder(Head,List).
154call_body_reorder(_Code,Head,C):- dmsg(warn(callClause((Head:-C)))),dtrace,callClause(C).
155
157timeOfFirstAnswer(C1,Time):- catch((timeOfFirstAnswer_0(C1,Time)*->true;Time=888),Time=999,true).
158
159timeOfFirstAnswer_0(C1,TimeVar):-
160 TimeVar1=e(_),
161 timeOfFirstAnswer_1(C1,TimeVar1),
162 arg(1,TimeVar1,TimeVar).
163
164timeOfFirstAnswer_1(C1,TimeVar1):-
165 statistics(cputime,Start),
166 (ereq(C1)*->(ground(TimeVar1)->true;
167 (statistics(cputime,End),Time is End - Start,
168 nb_setarg(1,TimeVar1,Time)))).
169
170
171:-meta_predicate(guess_reorder(0,0,-)). 172guess_reorder(C1,C2,Reordered):-
173 ( Try1 = ( \+ ( \+ ((C1,C2))))),
174 ( Try2 = ( \+ ( \+ ((C2,C1))))),
175 fasterClause(Try1,Try2,T1,T2),!,
176 (T1<888 ; T2<888),
177 ( (T1 > T2 ) ->
178 Reordered = (C2,C1);
179 Reordered = (C1,C2)).
180
181:-meta_predicate(fasterClause(0,0,+,+)). 182fasterClause(C1,C2,T1,T2):-
183 timeOfFirstAnswer(C1,T1),
184 catch(catch(call_with_time_limit(T1,
185 timeOfFirstAnswer_0(C2,T2)),
186 time_limit_exceeded,T2 is T1+1),_,T2=999).
187
188
189:-meta_predicate(callClause(+)) . 190callClause(_^C):-!,callClause(C).
191callClause((C0->C1;C2)):-!,(callClause(C0)->callClause(C1);callClause(C2)).
192callClause((C0*->C1;C2)):-!,(callClause(C0)*->callClause(C1);callClause(C2)).
193callClause((C0->C1)):-!,(callClause(C0)->callClause(C1)).
194callClause((C0*->C1)):-!,(callClause(C0)*->callClause(C1)).
195callClause((C1;C2)):-!,callClause(C1);callClause(C2).
196callClause((C1,C2)):-!,callClause(C1),callClause(C2).
198callClause([L|Ist]):- !, dmsg(callClause([L|Ist])),!,call_body_reorder(_ ,[L|Ist]).
199callClause(C):- on_x_debug(ereq(C)).
200
201enable_body_reorder:- enable_in_file(do_body_reorder).
202disable_body_reorder:- disable_in_file(do_body_reorder).
203:- disable_body_reorder. 204
205:- fixup_exports. 206
207:- if(true). 209
210:- endif.