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
/3. % 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 prolog_load_context(term_position,'$stream_position'(_, LineNumber, _, _, _)),
165 add_pragma_to_chr_rule(Term,line_number(LineNumber),NTerm),
166 assert(chr_term(File, LineNumber, NTerm)).
167 chr_expand(Term, []) :-
168 Term = (:- chr_preprocessor Preprocessor), !,
169 prolog_load_context(file,File),
170 assert(chr_pp(File, Preprocessor)).
171 chr_expand(end_of_file, FinalProgram) :-
172 extra_declarations(FinalProgram,Program),
173 prolog_load_context(file,File),
174 findall(T, retract(chr_term(File,_Line,T)), CHR0),
176 prolog_load_context(module, Module),
177 add_debug_decl(CHR0, CHR1),
178 add_optimise_decl(CHR1, CHR2),
179 CHR3 = [ (:- module(Module, [])) | CHR2 ],
180 findall(P, retract(chr_pp(File, P)), Preprocessors),
181 ( Preprocessors = [] ->
183 ; Preprocessors = [Preprocessor] ->
184 chr_compiler_errors:chr_info(preprocessor,'\tPreprocessing with
~w
.\n',[Preprocessor]),
185 call_chr_preprocessor(Preprocessor,CHR3,CHR)
187 chr_compiler_errors:print_chr_error(error(syntax(Preprocessors),'Too many preprocessors
! Only one is allowed
!\n',[])),
190 catch(call_chr_translate(File,
191 [ (:- module(Module, []))
196 ( chr_compiler_errors:print_chr_error(Error),
200 delete_header(Program0, Program).
203 delete_header([(:- module(_,_))|T0], T) :- !,
204 delete_header(T0, T).
207 add_debug_decl(CHR, CHR) :-
208 member(option(Name, _), CHR), Name == debug, !.
209 add_debug_decl(CHR, CHR) :-
210 member((:- chr_option(Name, _)), CHR), Name == debug, !.
211 add_debug_decl(CHR, [(:- chr_option(debug, Debug))|CHR]) :-
212 ( chr_current_prolog_flag(generate_debug_info, true)
218 chr_current_prolog_flag(Flag,Val) :- current_prolog_flag(Flag,Val).
221 add_optimise_decl(CHR, CHR) :-
222 \+(\+(memberchk((:- chr_option(optimize, _)), CHR))), !.
223 add_optimise_decl(CHR, [(:- chr_option(optimize, full))|CHR]) :-
224 chr_current_prolog_flag(optimize, full), !.
225 add_optimise_decl(CHR, CHR).
228 % call_chr_translate(+File, +In, -Out)
230 % The entire chr_translate/2 translation may fail, in which case we'd
231 % better issue a warning rather than simply ignoring the CHR
234 call_chr_translate
(File
, In
, _Out
) :-
235 ( chr_translate_line_info
(In
, File
, Out0
) ->
236 nb_setval
(chr_translated_program
,Out0
),
239 call_chr_translate
(_
, _In
, Out
) :-
240 nb_current
(chr_translated_program
,Out
), !,
241 nb_delete
(chr_translated_program
).
243 call_chr_translate
(File
, _
, []) :-
244 print_message
(error
, chr(compilation_failed
(File
))).
246 call_chr_preprocessor
(Preprocessor
,CHR
,_NCHR
) :-
247 ( call
(Preprocessor
,CHR
,CHR0
) ->
248 nb_setval
(chr_preprocessed_program
,CHR0
),
251 call_chr_preprocessor
(_
,_
,NCHR
) :-
252 nb_current
(chr_preprocessed_program
,NCHR
), !,
253 nb_delete
(chr_preprocessed_program
).
254 call_chr_preprocessor
(Preprocessor
,_
,_
) :-
255 chr_compiler_errors
:print_chr_error
(error
(preprocessor
,'Preprocessor `~w\' failed!\n',[Preprocessor
])).
259 /*******************************
260 * SYNCHRONISE TRACER
*
261 *******************************/
266 chr:debug_interact
/3.
270 user
:message_hook
(trace_mode
(OnOff
), _
, _
) :-
275 fail
. % backtrack to other handlers
277 % chr:debug_event
(+State
, +Event
)
279 % Hook into the CHR debugger
. At this moment we will discard CHR
280 % events
if we are
in a Prolog
`skip' and we ignore the
282 chr:debug_event(_State, _Event) :-
283 tracing, % are we tracing?
284 prolog_skip_level(Skip, Skip),
286 prolog_current_frame(Me),
287 prolog_frame_attribute(Me, level, Level),
290 % chr:debug_interact(+Event, +Depth, -Command)
292 % Hook into the CHR debugger to display Event and ask for the next
293 % command to execute. This definition causes the normal Prolog
294 % debugger to be used for the standard ports.
296 chr:debug_interact(Event, _Depth, creep) :-
300 prolog_event(call(_)).
301 prolog_event(exit(_)).
302 prolog_event(fail(_)).
307 /*******************************
309 *******************************/
314 prolog:message(chr(CHR)) -->
317 /*******************************
318 * TOPLEVEL PRINTING *
319 *******************************/
321 :- set_prolog_flag(chr_toplevel_show_store,true).
323 prolog:message(query(YesNo)) --> !,
324 ['~@'-[chr:print_all_stores]],
325 '$messages':prolog_message(query(YesNo)).
327 prolog:message(query(YesNo,Bindings)) --> !,
328 ['~@'-[chr:print_all_stores]],
329 '$messages':prolog_message(query(YesNo,Bindings)).
332 ( chr_current_prolog_flag(chr_toplevel_show_store,true),
333 catch(nb_getval(chr_global, _), _, fail),
334 chr:'$chr_module'(Mod),
341 /*******************************
343 *******************************/
345 :- multifile user:term_expansion/2.
346 :- dynamic user:term_expansion/2.
348 user:term_expansion(In, Out) :-
355 % current_toplevel_show_store/1,
356 % current_generate_debug_info/1,
357 % current_optimize/1.
359 % current_toplevel_show_store(on).
361 % current_generate_debug_info(false).
363 % current_optimize(off).
365 % chr_current_prolog_flag(generate_debug_info, X) :-
366 % chr_flag(generate_debug_info, X, X).
367 % chr_current_prolog_flag(optimize, X) :-
368 % chr_flag(optimize, X, X).
370 % chr_flag(Flag, Old, New) :-
371 % Goal = chr_flag(Flag,Old,New),
372 % g must_be(Flag, oneof([toplevel_show_store,generate_debug_info,optimize]), Goal, 1),
373 % chr_flag(Flag, Old, New, Goal).
375 % chr_flag(toplevel_show_store, Old, New, Goal) :-
376 % clause(current_toplevel_show_store(Old), true, Ref),
378 % ; must_be(New, oneof([on,off]), Goal, 3),
380 % assertz(current_toplevel_show_store(New))
382 % chr_flag(generate_debug_info, Old, New, Goal) :-
383 % clause(current_generate_debug_info(Old), true, Ref),
385 % ; must_be(New, oneof([false,true]), Goal, 3),
387 % assertz(current_generate_debug_info(New))
389 % chr_flag(optimize, Old, New, Goal) :-
390 % clause(current_optimize(Old), true, Ref),
392 % ; must_be(New, oneof([full,off]), Goal, 3),
394 % assertz(current_optimize(New))
398 % all_stores_goal(Goal, CVAs) :-
399 % chr_flag(toplevel_show_store, on, on), !,
400 % findall(C-CVAs, find_chr_constraint(C), Pairs),
401 % andify(Pairs, Goal, CVAs).
402 % all_stores_goal(true, _).
404 % andify([], true, _).
405 % andify([X-Vs|L], Conj, Vs) :- andify(L, X, Conj, Vs).
407 % andify([], X, X, _).
408 % andify([Y-Vs|L], X, (X,Conj), Vs) :- andify(L, Y, Conj, Vs).
410 % :- multifile user:term_expansion/6.
412 % user:term_expansion(In, _, Ids, Out, [], [chr|Ids]) :-
414 % nonmember(chr, Ids),
415 % chr_expand(In, Out), !.
421 add_pragma_to_chr_rule(Name @ Rule, Pragma, Result) :- !,
422 add_pragma_to_chr_rule(Rule,Pragma,NRule),
423 Result = (Name @ NRule).
424 add_pragma_to_chr_rule(Rule pragma Pragmas, Pragma, Result) :- !,
425 Result = (Rule pragma (Pragma,Pragmas)).
426 add_pragma_to_chr_rule(Head ==> Body, Pragma, Result) :- !,
427 Result = (Head ==> Body pragma Pragma).
428 add_pragma_to_chr_rule(Head <=> Body, Pragma, Result) :- !,
429 Result = (Head <=> Body pragma Pragma).
430 add_pragma_to_chr_rule(Term,_,Term).