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
),
46 op
(1150, fx
, chr_declaration
),
49 chr_show_store
/1, % +Module
50 find_chr_constraint
/1, % +Pattern
56 :- expects_dialect
(swi
).
58 :- set_prolog_flag
(generate_debug_info
, false
).
60 :- multifile user
:file_search_path
/2.
61 :- dynamic user
:file_search_path
/2.
62 :- dynamic chr_translated_program
/1.
64 user
:file_search_path
(chr, library
(chr)).
66 :- load_files
([ chr(chr_translate
),
69 chr(chr_hashtable_store
),
70 chr(chr_compiler_errors
)
76 :- use_module
(library
(lists
),[member
/2]).
88 %% :- op
(1180, xfx
, ==>),
89 %% op
(1180, xfx
, <=>),
90 %% op
(1150, fx
, constraints
),
91 %% op
(1150, fx
, handler
),
92 %% op
(1150, fx
, rules
),
95 %% op
(1190, xfx
, pragma
),
97 %% op
(1150, fx
, chr_type
),
98 %% op
(1130, xfx
, --->),
101 %% :- multifile user
:file_search_path
/2.
102 %% :- dynamic chr_translated_program
/1.
104 %% user
:file_search_path
(chr, library
(chr)).
107 %% :- use_module
('chr/chr_translate').
108 %% :- use_module
('chr/chr_runtime').
109 %% :- use_module
('chr/chr_hashtable_store').
110 %% :- use_module
('chr/hprolog').
113 :- multifile
chr:'$chr_module'/1.
115 :- dynamic chr_term
/3. % File
, Term
117 :- dynamic chr_pp
/2. % File
, Term
119 % chr_expandable
(+Term
)
121 % Succeeds
if Term is a rule that must be handled by the CHR
122 % compiler
. Ideally CHR definitions should be between
126 % :- end_constraints
.
128 % As they are
not we have to
use some heuristics
. We assume any
129 % file is a CHR after we
've seen :- constraints ...
131 chr_expandable((:- constraints _)).
132 chr_expandable((constraints _)).
133 chr_expandable((:- chr_constraint _)).
134 chr_expandable((:- chr_type _)).
135 chr_expandable((chr_type _)).
136 chr_expandable((:- chr_declaration _)).
137 chr_expandable(option(_, _)).
138 chr_expandable((:- chr_option(_, _))).
139 chr_expandable((handler _)).
140 chr_expandable((rules _)).
141 chr_expandable((_ <=> _)).
142 chr_expandable((_ @ _)).
143 chr_expandable((_ ==> _)).
144 chr_expandable((_ pragma _)).
146 % chr_expand(+Term, -Expansion)
148 % Extract CHR declarations and rules from the file and run the
149 % CHR compiler when reaching end-of-file.
152 extra_declarations([(:- use_module(chr(chr_runtime)))
153 ,(:- style_check(-discontiguous)) % no need to restore; file ends
154 ,(:- set_prolog_flag(generate_debug_info, false))
159 %% extra_declarations([(:-use_module(chr(chr_runtime)))
160 %% , (:- use_module(chr(hprolog),[term_variables/2,term_variables/3]))
161 %% , (:-use_module(chr(hpattvars)))
165 chr_expand(Term, []) :-
166 chr_expandable(Term), !,
167 prolog_load_context(file,File),
168 prolog_load_context(term_position,'$stream_position'(_, LineNumber, _, _, _)),
169 add_pragma_to_chr_rule(Term,line_number(LineNumber),NTerm),
170 assert(chr_term(File, LineNumber, NTerm)).
171 chr_expand(Term, []) :-
172 Term = (:- chr_preprocessor Preprocessor), !,
173 prolog_load_context(file,File),
174 assert(chr_pp(File, Preprocessor)).
175 chr_expand(end_of_file, FinalProgram) :-
176 extra_declarations(FinalProgram,Program),
177 prolog_load_context(file,File),
178 findall(T, retract(chr_term(File,_Line,T)), CHR0),
180 prolog_load_context(module, Module),
181 add_debug_decl(CHR0, CHR1),
182 add_optimise_decl(CHR1, CHR2),
183 CHR3 = [ (:- module(Module, [])) | CHR2 ],
184 findall(P, retract(chr_pp(File, P)), Preprocessors),
185 ( Preprocessors = [] ->
187 ; Preprocessors = [Preprocessor] ->
188 chr_compiler_errors:chr_info(preprocessor,'\tPreprocessing with
~w
.\n',[Preprocessor]),
189 call_chr_preprocessor(Preprocessor,CHR3,CHR)
191 chr_compiler_errors:print_chr_error(error(syntax(Preprocessors),'Too many preprocessors
! Only one is allowed
!\n',[])),
194 catch(call_chr_translate(File,
195 [ (:- module(Module, []))
200 ( chr_compiler_errors:print_chr_error(Error),
204 delete_header(Program0, Program).
207 delete_header([(:- module(_,_))|T0], T) :- !,
208 delete_header(T0, T).
211 add_debug_decl(CHR, CHR) :-
212 member(option(Name, _), CHR), Name == debug, !.
213 add_debug_decl(CHR, CHR) :-
214 member((:- chr_option(Name, _)), CHR), Name == debug, !.
215 add_debug_decl(CHR, [(:- chr_option(debug, Debug))|CHR]) :-
216 ( chr_current_prolog_flag(generate_debug_info, true)
222 chr_current_prolog_flag(Flag,Val) :- current_prolog_flag(Flag,Val).
225 add_optimise_decl(CHR, CHR) :-
226 \+(\+(memberchk((:- chr_option(optimize, _)), CHR))), !.
227 add_optimise_decl(CHR, [(:- chr_option(optimize, full))|CHR]) :-
228 chr_current_prolog_flag(optimize, full), !.
229 add_optimise_decl(CHR, CHR).
232 % call_chr_translate(+File, +In, -Out)
234 % The entire chr_translate/2 translation may fail, in which case we'd
235 % better issue a warning rather than simply ignoring the CHR
238 call_chr_translate
(File
, In
, _Out
) :-
239 ( chr_translate_line_info
(In
, File
, Out0
) ->
240 nb_setval
(chr_translated_program
,Out0
),
243 call_chr_translate
(_
, _In
, Out
) :-
244 nb_current
(chr_translated_program
,Out
), !,
245 nb_delete
(chr_translated_program
).
247 call_chr_translate
(File
, _
, []) :-
248 print_message
(error
, chr(compilation_failed
(File
))).
250 call_chr_preprocessor
(Preprocessor
,CHR
,_NCHR
) :-
251 ( call
(Preprocessor
,CHR
,CHR0
) ->
252 nb_setval
(chr_preprocessed_program
,CHR0
),
255 call_chr_preprocessor
(_
,_
,NCHR
) :-
256 nb_current
(chr_preprocessed_program
,NCHR
), !,
257 nb_delete
(chr_preprocessed_program
).
258 call_chr_preprocessor
(Preprocessor
,_
,_
) :-
259 chr_compiler_errors
:print_chr_error
(error
(preprocessor
,'Preprocessor `~w\' failed!\n',[Preprocessor
])).
263 /*******************************
264 * SYNCHRONISE TRACER
*
265 *******************************/
270 chr:debug_interact
/3.
274 user
:message_hook
(trace_mode
(OnOff
), _
, _
) :-
279 fail
. % backtrack to other handlers
281 % chr:debug_event
(+State
, +Event
)
283 % Hook into the CHR debugger
. At this moment we will discard CHR
284 % events
if we are
in a Prolog
`skip' and we ignore the
286 chr:debug_event(_State, _Event) :-
287 tracing, % are we tracing?
288 prolog_skip_level(Skip, Skip),
290 prolog_current_frame(Me),
291 prolog_frame_attribute(Me, level, Level),
294 % chr:debug_interact(+Event, +Depth, -Command)
296 % Hook into the CHR debugger to display Event and ask for the next
297 % command to execute. This definition causes the normal Prolog
298 % debugger to be used for the standard ports.
300 chr:debug_interact(Event, _Depth, creep) :-
304 prolog_event(call(_)).
305 prolog_event(exit(_)).
306 prolog_event(fail(_)).
311 /*******************************
313 *******************************/
318 prolog:message(chr(CHR)) -->
321 /*******************************
322 * TOPLEVEL PRINTING *
323 *******************************/
325 :- set_prolog_flag(chr_toplevel_show_store,true).
327 prolog:message(query(YesNo)) --> !,
328 ['~@'-[chr:print_all_stores]],
329 '$messages':prolog_message(query(YesNo)).
331 prolog:message(query(YesNo,Bindings)) --> !,
332 ['~@'-[chr:print_all_stores]],
333 '$messages':prolog_message(query(YesNo,Bindings)).
336 ( chr_current_prolog_flag(chr_toplevel_show_store,true),
337 catch(nb_getval(chr_global, _), _, fail),
338 chr:'$chr_module'(Mod),
345 /*******************************
347 *******************************/
349 :- multifile user:term_expansion/2.
350 :- dynamic user:term_expansion/2.
352 user:term_expansion(In, Out) :-
359 % current_toplevel_show_store/1,
360 % current_generate_debug_info/1,
361 % current_optimize/1.
363 % current_toplevel_show_store(on).
365 % current_generate_debug_info(false).
367 % current_optimize(off).
369 % chr_current_prolog_flag(generate_debug_info, X) :-
370 % chr_flag(generate_debug_info, X, X).
371 % chr_current_prolog_flag(optimize, X) :-
372 % chr_flag(optimize, X, X).
374 % chr_flag(Flag, Old, New) :-
375 % Goal = chr_flag(Flag,Old,New),
376 % g must_be(Flag, oneof([toplevel_show_store,generate_debug_info,optimize]), Goal, 1),
377 % chr_flag(Flag, Old, New, Goal).
379 % chr_flag(toplevel_show_store, Old, New, Goal) :-
380 % clause(current_toplevel_show_store(Old), true, Ref),
382 % ; must_be(New, oneof([on,off]), Goal, 3),
384 % assertz(current_toplevel_show_store(New))
386 % chr_flag(generate_debug_info, Old, New, Goal) :-
387 % clause(current_generate_debug_info(Old), true, Ref),
389 % ; must_be(New, oneof([false,true]), Goal, 3),
391 % assertz(current_generate_debug_info(New))
393 % chr_flag(optimize, Old, New, Goal) :-
394 % clause(current_optimize(Old), true, Ref),
396 % ; must_be(New, oneof([full,off]), Goal, 3),
398 % assertz(current_optimize(New))
402 % all_stores_goal(Goal, CVAs) :-
403 % chr_flag(toplevel_show_store, on, on), !,
404 % findall(C-CVAs, find_chr_constraint(C), Pairs),
405 % andify(Pairs, Goal, CVAs).
406 % all_stores_goal(true, _).
408 % andify([], true, _).
409 % andify([X-Vs|L], Conj, Vs) :- andify(L, X, Conj, Vs).
411 % andify([], X, X, _).
412 % andify([Y-Vs|L], X, (X,Conj), Vs) :- andify(L, Y, Conj, Vs).
414 % :- multifile user:term_expansion/6.
416 % user:term_expansion(In, _, Ids, Out, [], [chr|Ids]) :-
418 % nonmember(chr, Ids),
419 % chr_expand(In, Out), !.
425 add_pragma_to_chr_rule((Name @ Rule), Pragma, Result) :- !,
426 add_pragma_to_chr_rule(Rule,Pragma,NRule),
427 Result = (Name @ NRule).
428 add_pragma_to_chr_rule((Rule pragma Pragmas), Pragma, Result) :- !,
429 Result = (Rule pragma (Pragma,Pragmas)).
430 add_pragma_to_chr_rule((Head ==> Body), Pragma, Result) :- !,
431 Result = (Head ==> Body pragma Pragma).
432 add_pragma_to_chr_rule((Head <=> Body), Pragma, Result) :- !,
433 Result = (Head <=> Body pragma Pragma).
434 add_pragma_to_chr_rule(Term,_,Term).