3 Part of CHR
(Constraint Handling Rules
)
5 Author
: Tom Schrijvers
and Jan Wielemaker
6 E
-mail
: Tom
.Schrijvers
@cs.kuleuven
.be
7 WWW
: http
://www
.swi
-prolog
.org
8 Copyright
(C
): 2003-2004, 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
.
36 op
(1150, fx
, constraints
),
37 op
(1150, fx
, chr_constraint
),
38 op
(1150, fx
, chr_preprocessor
),
39 op
(1150, fx
, handler
),
43 op
(1190, xfx
, pragma
),
45 op
(1150, fx
, chr_type
),
48 chr_show_store
/1, % +Module
49 find_chr_constraint
/1, % +Pattern
55 :- set_prolog_flag
(generate_debug_info
, false
).
57 :- multifile user
:file_search_path
/2.
58 :- dynamic user
:file_search_path
/2.
59 :- dynamic chr_translated_program
/1.
61 user
:file_search_path
(chr, library
(chr)).
63 :- load_files
([ chr(chr_translate
),
66 chr(chr_hashtable_store
),
67 chr(chr_compiler_errors
)
73 :- use_module
(library
(lists
),[member
/2]).
85 %% :- op
(1180, xfx
, ==>),
86 %% op
(1180, xfx
, <=>),
87 %% op
(1150, fx
, constraints
),
88 %% op
(1150, fx
, handler
),
89 %% op
(1150, fx
, rules
),
92 %% op
(1190, xfx
, pragma
),
94 %% op
(1150, fx
, chr_type
),
95 %% op
(1130, xfx
, --->),
98 %% :- multifile user
:file_search_path
/2.
99 %% :- dynamic chr_translated_program
/1.
101 %% user
:file_search_path
(chr, library
(chr)).
104 %% :- use_module
('chr/chr_translate').
105 %% :- use_module
('chr/chr_runtime').
106 %% :- use_module
('chr/chr_hashtable_store').
107 %% :- use_module
('chr/hprolog').
110 :- multifile
chr:'$chr_module'/1.
112 :- dynamic chr_term
/2. % File
, Term
114 :- dynamic chr_pp
/2. % File
, Term
116 % chr_expandable
(+Term
)
118 % Succeeds
if Term is a rule that must be handled by the CHR
119 % compiler
. Ideally CHR definitions should be between
123 % :- end_constraints
.
125 % As they are
not we have to
use some heuristics
. We assume any
126 % file is a CHR after we
've seen :- constraints ...
128 chr_expandable((:- constraints _)).
129 chr_expandable((constraints _)).
130 chr_expandable((:- chr_constraint _)).
131 chr_expandable((:- chr_type _)).
132 chr_expandable((chr_type _)).
133 chr_expandable(option(_, _)).
134 chr_expandable((:- chr_option(_, _))).
135 chr_expandable((handler _)).
136 chr_expandable((rules _)).
137 chr_expandable((_ <=> _)).
138 chr_expandable((_ @ _)).
139 chr_expandable((_ ==> _)).
140 chr_expandable((_ pragma _)).
142 % chr_expand(+Term, -Expansion)
144 % Extract CHR declarations and rules from the file and run the
145 % CHR compiler when reaching end-of-file.
148 extra_declarations([(:- use_module(chr(chr_runtime)))
149 ,(:- style_check(-discontiguous)) % no need to restore; file ends
150 ,(:- set_prolog_flag(generate_debug_info, false))
155 %% extra_declarations([(:-use_module(chr(chr_runtime)))
156 %% , (:- use_module(chr(hprolog),[term_variables/2,term_variables/3]))
157 %% , (:-use_module(chr(hpattvars)))
161 chr_expand(Term, []) :-
162 chr_expandable(Term), !,
163 prolog_load_context(file,File),
164 assert(chr_term(File, Term)).
165 chr_expand(Term, []) :-
166 Term = (:- chr_preprocessor Preprocessor), !,
167 prolog_load_context(file,File),
168 assert(chr_pp(File, Preprocessor)).
169 chr_expand(end_of_file, FinalProgram) :-
170 extra_declarations(FinalProgram,Program),
171 prolog_load_context(file,File),
172 findall(T, retract(chr_term(File, T)), CHR0),
174 prolog_load_context(module, Module),
175 add_debug_decl(CHR0, CHR1),
176 add_optimise_decl(CHR1, CHR2),
177 CHR3 = [ (:- module(Module, [])) | CHR2 ],
178 findall(P, retract(chr_pp(File, P)), Preprocessors),
179 ( Preprocessors = [] ->
181 ; Preprocessors = [Preprocessor] ->
182 chr_compiler_errors:chr_info(preprocessor,'\tPreprocessing with
~w
.\n',[Preprocessor]),
183 call_chr_preprocessor(Preprocessor,CHR3,CHR)
185 chr_compiler_errors:print_chr_error(error(syntax(Preprocessors),'Too many preprocessors
! Only one is allowed
!\n',[])),
188 catch(call_chr_translate(File,
189 [ (:- module(Module, []))
194 ( chr_compiler_errors:print_chr_error(Error),
198 delete_header(Program0, Program).
201 delete_header([(:- module(_,_))|T0], T) :- !,
202 delete_header(T0, T).
205 add_debug_decl(CHR, CHR) :-
206 member(option(Name, _), CHR), Name == debug, !.
207 add_debug_decl(CHR, CHR) :-
208 member((:- chr_option(Name, _)), CHR), Name == debug, !.
209 add_debug_decl(CHR, [(:- chr_option(debug, Debug))|CHR]) :-
210 ( chr_current_prolog_flag(generate_debug_info, true)
216 chr_current_prolog_flag(Flag,Val) :- current_prolog_flag(Flag,Val).
219 add_optimise_decl(CHR, CHR) :-
220 \+(\+(memberchk((:- chr_option(optimize, _)), CHR))), !.
221 add_optimise_decl(CHR, [(:- chr_option(optimize, full))|CHR]) :-
222 chr_current_prolog_flag(optimize, full), !.
223 add_optimise_decl(CHR, CHR).
226 % call_chr_translate(+File, +In, -Out)
228 % The entire chr_translate/2 translation may fail, in which case we'd
229 % better issue a warning rather than simply ignoring the CHR
232 call_chr_translate
(_
, In
, _Out
) :-
233 ( chr_translate
(In
, Out0
) ->
234 nb_setval
(chr_translated_program
,Out0
),
237 call_chr_translate
(_
, _In
, Out
) :-
238 nb_current
(chr_translated_program
,Out
), !,
239 nb_delete
(chr_translated_program
).
241 call_chr_translate
(File
, _
, []) :-
242 print_message
(error
, chr(compilation_failed
(File
))).
244 call_chr_preprocessor
(Preprocessor
,CHR
,_NCHR
) :-
245 ( call
(Preprocessor
,CHR
,CHR0
) ->
246 nb_setval
(chr_preprocessed_program
,CHR0
),
249 call_chr_preprocessor
(_
,_
,NCHR
) :-
250 nb_current
(chr_preprocessed_program
,NCHR
), !,
251 nb_delete
(chr_preprocessed_program
).
252 call_chr_preprocessor
(Preprocessor
,_
,_
) :-
253 chr_compiler_errors
:print_chr_error
(error
(preprocessor
,'Preprocessor `~w\' failed!\n',[Preprocessor
])).
257 /*******************************
258 * SYNCHRONISE TRACER
*
259 *******************************/
264 chr:debug_interact
/3.
268 user
:message_hook
(trace_mode
(OnOff
), _
, _
) :-
273 fail
. % backtrack to other handlers
275 % chr:debug_event
(+State
, +Event
)
277 % Hook into the CHR debugger
. At this moment we will discard CHR
278 % events
if we are
in a Prolog
`skip' and we ignore the
280 chr:debug_event(_State, _Event) :-
281 tracing, % are we tracing?
282 prolog_skip_level(Skip, Skip),
284 prolog_current_frame(Me),
285 prolog_frame_attribute(Me, level, Level),
288 % chr:debug_interact(+Event, +Depth, -Command)
290 % Hook into the CHR debugger to display Event and ask for the next
291 % command to execute. This definition causes the normal Prolog
292 % debugger to be used for the standard ports.
294 chr:debug_interact(Event, _Depth, creep) :-
298 prolog_event(call(_)).
299 prolog_event(exit(_)).
300 prolog_event(fail(_)).
305 /*******************************
307 *******************************/
312 prolog:message(chr(CHR)) -->
315 /*******************************
316 * TOPLEVEL PRINTING *
317 *******************************/
319 :- set_prolog_flag(chr_toplevel_show_store,true).
321 prolog:message(query(YesNo)) --> !,
322 ['~@'-[chr:print_all_stores]],
323 '$messages':prolog_message(query(YesNo)).
325 prolog:message(query(YesNo,Bindings)) --> !,
326 ['~@'-[chr:print_all_stores]],
327 '$messages':prolog_message(query(YesNo,Bindings)).
330 ( chr_current_prolog_flag(chr_toplevel_show_store,true),
331 catch(nb_getval(chr_global, _), _, fail),
332 chr:'$chr_module'(Mod),
339 /*******************************
341 *******************************/
343 :- multifile user:term_expansion/2.
344 :- dynamic user:term_expansion/2.
346 user:term_expansion(In, Out) :-
353 % current_toplevel_show_store/1,
354 % current_generate_debug_info/1,
355 % current_optimize/1.
357 % current_toplevel_show_store(on).
359 % current_generate_debug_info(false).
361 % current_optimize(off).
363 % chr_current_prolog_flag(generate_debug_info, X) :-
364 % chr_flag(generate_debug_info, X, X).
365 % chr_current_prolog_flag(optimize, X) :-
366 % chr_flag(optimize, X, X).
368 % chr_flag(Flag, Old, New) :-
369 % Goal = chr_flag(Flag,Old,New),
370 % g must_be(Flag, oneof([toplevel_show_store,generate_debug_info,optimize]), Goal, 1),
371 % chr_flag(Flag, Old, New, Goal).
373 % chr_flag(toplevel_show_store, Old, New, Goal) :-
374 % clause(current_toplevel_show_store(Old), true, Ref),
376 % ; must_be(New, oneof([on,off]), Goal, 3),
378 % assertz(current_toplevel_show_store(New))
380 % chr_flag(generate_debug_info, Old, New, Goal) :-
381 % clause(current_generate_debug_info(Old), true, Ref),
383 % ; must_be(New, oneof([false,true]), Goal, 3),
385 % assertz(current_generate_debug_info(New))
387 % chr_flag(optimize, Old, New, Goal) :-
388 % clause(current_optimize(Old), true, Ref),
390 % ; must_be(New, oneof([full,off]), Goal, 3),
392 % assertz(current_optimize(New))
396 % all_stores_goal(Goal, CVAs) :-
397 % chr_flag(toplevel_show_store, on, on), !,
398 % findall(C-CVAs, find_chr_constraint(C), Pairs),
399 % andify(Pairs, Goal, CVAs).
400 % all_stores_goal(true, _).
402 % andify([], true, _).
403 % andify([X-Vs|L], Conj, Vs) :- andify(L, X, Conj, Vs).
405 % andify([], X, X, _).
406 % andify([Y-Vs|L], X, (X,Conj), Vs) :- andify(L, Y, Conj, Vs).
408 % :- multifile user:term_expansion/6.
410 % user:term_expansion(In, _, Ids, Out, [], [chr|Ids]) :-
412 % nonmember(chr, Ids),
413 % chr_expand(In, Out), !.