3 Part of CHR
(Constraint Handling Rules
)
6 E
-mail
: Tom
.Schrijvers
@cs.kuleuven
.be
7 WWW
: http
://www
.swi
-prolog
.org
8 Copyright
(C
): 2005-2006, K
.U
. Leuven
10 This program is free software
; you can redistribute it
and/or
11 modify it under the terms of the GNU General Public License
12 as published by the Free Software Foundation
; either version
2
13 of the License
, or (at your option
) any later version
.
15 This program is distributed
in the hope that it will be useful
,
16 but WITHOUT ANY WARRANTY
; without even the implied warranty of
17 MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE
. See the
18 GNU General Public License
for more details
.
20 You should have received a copy of the GNU Lesser General Public
21 License along with this library
; if not, write to the Free Software
22 Foundation
, Inc
., 59 Temple Place
, Suite
330, Boston
, MA
02111-1307 USA
24 As a special exception
, if you
link this library with other files
,
25 compiled with a Free Software compiler
, to produce an executable
, this
26 library does
not by itself cause the resulting executable to be covered
27 by the GNU General Public License
. This exception does
not however
28 invalidate any other reasons why the executable file might be covered by
29 the GNU General Public License
.
31 :- module
(chr_compiler_utility
,
39 , variable_replacement
/3
40 , variable_replacement
/4
42 , identical_guarded_rules
/2
43 , copy_with_variable_replacement
/3
57 , tree_set_memberchk
/2
66 :- use_module
(pairlist
).
67 :- use_module
(library
(lists
), [permutation
/2]).
68 :- use_module
(library
(assoc
)).
71 %% use_module
(library
(terms
),[term_variables
/2]).
75 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
77 % statistics
(runtime
,[T1
|_
]),
79 % statistics
(runtime
,[T2
|_
]),
81 % format
(' ~w ~46t ~D~80| ms\n',[Phase
,T
]),
86 % format
('\t\tNOT DETERMINISTIC!\n',[])
88 time(_
,Goal
) :- call
(Goal
).
90 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
100 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
101 pair_all_with
([],_
,[]).
102 pair_all_with
([X
|Xs
],Y
,[X
-Y
|Rest
]) :-
103 pair_all_with
(Xs
,Y
,Rest
).
105 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
106 conj2list
(Conj
,L
) :- %% transform conjunctions to list
107 conj2list
(Conj
,L
,[]).
109 conj2list
(Var
,L
,T
) :-
112 conj2list
(true
,L
,L
) :- !.
113 conj2list
(Conj
,L
,T
) :-
117 conj2list
(G
,[G
| T
],T
).
119 disj2list
(Conj
,L
) :- %% transform disjunctions to list
120 disj2list
(Conj
,L
,[]).
121 disj2list
(Conj
,L
,T
) :-
124 disj2list
(Conj
,L
,T
) :-
128 disj2list
(G
,[G
| T
],T
).
131 list2conj
([G
],X
) :- !, X
= G
.
132 list2conj
([G
|Gs
],C
) :-
133 ( G
== true
-> %% remove some redundant trues
141 list2disj
([G
],X
) :- !, X
= G
.
142 list2disj
([G
|Gs
],C
) :-
143 ( G
== fail
-> %% remove some redundant fails
150 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
151 % check wether two rules are identical
153 identical_guarded_rules
(rule
(H11
,H21
,G1
,_
),rule
(H12
,H22
,G2
,_
)) :-
160 identical_rules
(rule
(H11
,H21
,G1
,B1
),rule
(H12
,H22
,G2
,B2
)) :-
162 identical_bodies
(B1
,B2
),
168 identical_bodies
(B1
,B2
) :-
180 % replace variables
in list
182 copy_with_variable_replacement
(X
,Y
,L
) :-
184 ( lookup_eq
(L
,X
,Y
) ->
192 copy_with_variable_replacement_l
(XArgs
,YArgs
,L
)
195 copy_with_variable_replacement_l
([],[],_
).
196 copy_with_variable_replacement_l
([X
|Xs
],[Y
|Ys
],L
) :-
197 copy_with_variable_replacement
(X
,Y
,L
),
198 copy_with_variable_replacement_l
(Xs
,Ys
,L
).
200 % build variable replacement list
202 variable_replacement
(X
,Y
,L
) :-
203 variable_replacement
(X
,Y
,[],L
).
205 variable_replacement
(X
,Y
,L1
,L2
) :-
208 ( lookup_eq
(L1
,X
,Z
) ->
211 ; ( X
== Y
-> L2
=L1
; L2
= [X
-Y
,Y
-X
|L1
])
216 variable_replacement_l
(XArgs
,YArgs
,L1
,L2
)
219 variable_replacement_l
([],[],L
,L
).
220 variable_replacement_l
([X
|Xs
],[Y
|Ys
],L1
,L3
) :-
221 variable_replacement
(X
,Y
,L1
,L2
),
222 variable_replacement_l
(Xs
,Ys
,L2
,L3
).
224 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
225 my_term_copy
(X
,Dict
,Y
) :-
226 my_term_copy
(X
,Dict
,_
,Y
).
228 my_term_copy
(X
,Dict1
,Dict2
,Y
) :-
230 ( lookup_eq
(Dict1
,X
,Y
) ->
232 ; Dict2
= [X
-Y
|Dict1
]
238 my_term_copy_list
(XArgs
,Dict1
,Dict2
,YArgs
)
241 my_term_copy_list
([],Dict
,Dict
,[]).
242 my_term_copy_list
([X
|Xs
],Dict1
,Dict3
,[Y
|Ys
]) :-
243 my_term_copy
(X
,Dict1
,Dict2
,Y
),
244 my_term_copy_list
(Xs
,Dict2
,Dict3
,Ys
).
246 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
247 atom_concat_list
([X
],X
) :- ! .
248 atom_concat_list
([X
|Xs
],A
) :-
249 atom_concat_list
(Xs
,B
),
250 atomic_concat
(X
,B
,A
).
252 atomic_concat
(A
,B
,C
) :-
255 atom_concat
(AA
,BB
,C
).
270 set_elems
([X
|Xs
],X
) :-
275 init
([X
|Xs
],[X
|R
]) :-
278 member2
([X
|_
],[Y
|_
],X
-Y
).
279 member2
([_
|Xs
],[_
|Ys
],P
) :-
282 select2
(X
, Y
, [X
|Xs
], [Y
|Ys
], Xs
, Ys
).
283 select2
(X
, Y
, [X1
|Xs
], [Y1
|Ys
], [X1
|NXs
], [Y1
|NYs
]) :-
284 select2
(X
, Y
, Xs
, Ys
, NXs
, NYs
).
286 instrument_goal
(Goal
,Pre
,Post
,(Pre
,Goal
,Post
)).
288 sort_by_key
(List
,Keys
,SortedList
) :-
289 pairup
(Keys
,List
,Pairs
),
290 sort(Pairs
,SortedPairs
),
291 once
(pairup
(_
,SortedList
,SortedPairs
)).
293 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
294 arg1
(Term
,Index
,Arg
) :- arg
(Index
,Term
,Arg
).
296 wrap_in_functor
(Functor
,X
,Term
) :-
297 Term
=.. [Functor
,X
].
299 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
301 tree_set_empty
(TreeSet
) :- empty_assoc
(TreeSet
).
302 tree_set_memberchk
(Element
,TreeSet
) :- get_assoc
(Element
,TreeSet
,_
).
303 tree_set_add
(TreeSet
,Element
,NTreeSet
) :- put_assoc
(Element
,TreeSet
,x
,NTreeSet
).
304 tree_set_merge
(TreeSet1
,TreeSet2
,TreeSet3
) :-
305 assoc_to_list
(TreeSet1
,List
),
306 fold
(List
,tree_set_add_pair
,TreeSet2
,TreeSet3
).
307 tree_set_add_pair
(Key
-Value
,TreeSet
,NTreeSet
) :-
308 put_assoc
(Key
,TreeSet
,Value
,NTreeSet
).
310 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
311 fold1
(P
,[Head
|Tail
],Result
) :-
312 fold
(Tail
,P
,Head
,Result
).
315 fold
([X
|Xs
],P
,Acc
,Res
) :-
319 maplist_dcg
(P
,L1
,L2
,L
) -->
320 maplist_dcg_
(L1
,L2
,L
,P
).
322 maplist_dcg_
([],[],[],_
) --> [].
323 maplist_dcg_
([X
|Xs
],[Y
|Ys
],[Z
|Zs
],P
) -->
325 maplist_dcg_
(Xs
,Ys
,Zs
,P
).
327 maplist_dcg
(P
,L1
,L2
) -->
328 maplist_dcg_
(L1
,L2
,P
).
330 maplist_dcg_
([],[],_
) --> [].
331 maplist_dcg_
([X
|Xs
],[Y
|Ys
],P
) -->
333 maplist_dcg_
(Xs
,Ys
,P
).
334 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
336 user
:goal_expansion
/2.
338 user
:goal_expansion
/2.
340 user
:goal_expansion
(arg1
(Term
,Index
,Arg
), arg
(Index
,Term
,Arg
)).
341 user
:goal_expansion
(wrap_in_functor
(Functor
,In
,Out
), Goal
) :-
342 ( atom
(Functor
), var
(Out
) ->
343 Out
=.. [Functor
,In
],
346 Goal
= (Out
=.. [Functor
,In
])