34
36:- module(chr,
37 [ op(1180, xfx, ==>),
38 op(1180, xfx, <=>),
39 op(1150, fx, constraints),
40 op(1150, fx, chr_constraint),
41 op(1150, fx, chr_preprocessor),
42 op(1150, fx, handler),
43 op(1150, fx, rules),
44 op(1100, xfx, \),
45 op(1200, xfx, @),
46 op(1190, xfx, pragma),
47 op( 500, yfx, #),
48 op(1150, fx, chr_type),
49 op(1150, fx, chr_declaration),
50 op(1130, xfx, --->),
51 op(1150, fx, (?)),
52 chr_show_store/1, 53 find_chr_constraint/1, 54 chr_trace/0,
55 chr_notrace/0,
56 chr_leash/1 57 ]). 58
59:- expects_dialect(swi). 60
61:- set_prolog_flag(generate_debug_info, false). 62
63:- multifile
64 debug_ask_continue/1,
65 preprocess/2. 66
67:- multifile user:file_search_path/2. 68:- dynamic user:file_search_path/2. 69:- dynamic chr_translated_program/1. 70
71user:file_search_path(chr, library(chr)).
72
73:- load_files([ chr(chr_translate),
74 chr(chr_runtime),
75 chr(chr_messages),
76 chr(chr_hashtable_store),
77 chr(chr_compiler_errors)
78 ],
79 [ if(not_loaded),
80 silent(true)
81 ]). 82
83:- use_module(library(lists), [member/2]). 85
119
120:- multifile chr:'$chr_module'/1. 121
122:- dynamic chr_term/3. 123
124:- dynamic chr_pp/2. 125
137
138chr_expandable((:- constraints _)).
139chr_expandable((constraints _)).
140chr_expandable((:- chr_constraint _)).
141chr_expandable((:- chr_type _)).
142chr_expandable((chr_type _)).
143chr_expandable((:- chr_declaration _)).
144chr_expandable(option(_, _)).
145chr_expandable((:- chr_option(_, _))).
146chr_expandable((handler _)).
147chr_expandable((rules _)).
148chr_expandable((_ <=> _)).
149chr_expandable((_ @ _)).
150chr_expandable((_ ==> _)).
151chr_expandable((_ pragma _)).
152
157
([ (:- use_module(chr(chr_runtime))),
160 (:- style_check(-discontiguous)),
161 (:- style_check(-singleton)),
162 (:- style_check(-no_effect)),
163 (:- set_prolog_flag(generate_debug_info, false))
164 | Tail
165 ], Tail).
167
174
175chr_expand(Term, []) :-
176 chr_expandable(Term), !,
177 prolog_load_context(source,File),
178 prolog_load_context(term_position,Pos),
179 stream_position_data(line_count,Pos,LineNumber),
180 add_pragma_to_chr_rule(Term,line_number(LineNumber),NTerm),
181 assert(chr_term(File, LineNumber, NTerm)).
182chr_expand(Term, []) :-
183 Term = (:- chr_preprocessor Preprocessor), !,
184 prolog_load_context(source,File),
185 assert(chr_pp(File, Preprocessor)).
186chr_expand(end_of_file, FinalProgram) :-
187 extra_declarations(FinalProgram,Program),
188 prolog_load_context(source,File),
189 findall(T, retract(chr_term(File,_Line,T)), CHR0),
190 CHR0 \== [],
191 prolog_load_context(module, Module),
192 add_debug_decl(CHR0, CHR1),
193 add_optimise_decl(CHR1, CHR2),
194 call_preprocess(CHR2, CHR3),
195 CHR4 = [ (:- module(Module, [])) | CHR3 ],
196 findall(P, retract(chr_pp(File, P)), Preprocessors),
197 ( Preprocessors = [] ->
198 CHR4 = CHR
199 ; Preprocessors = [Preprocessor] ->
200 chr_compiler_errors:chr_info(preprocessor,'\tPreprocessing with ~w.\n',[Preprocessor]),
201 call_chr_preprocessor(Preprocessor,CHR4,CHR)
202 ;
203 chr_compiler_errors:print_chr_error(error(syntax(Preprocessors),'Too many preprocessors! Only one is allowed!\n',[])),
204 fail
205 ),
206 catch(call_chr_translate(File,
207 [ (:- module(Module, []))
208 | CHR
209 ],
210 Program0),
211 chr_error(Error),
212 ( chr_compiler_errors:print_chr_error(Error),
213 fail
214 )
215 ),
216 delete_header(Program0, Program).
217
218
([(:- module(_,_))|T0], T) :- !,
220 delete_header(T0, T).
221delete_header(L, L).
222
223add_debug_decl(CHR, CHR) :-
224 member(option(Name, _), CHR), Name == debug, !.
225add_debug_decl(CHR, CHR) :-
226 member((:- chr_option(Name, _)), CHR), Name == debug, !.
227add_debug_decl(CHR, [(:- chr_option(debug, Debug))|CHR]) :-
228 ( chr_current_prolog_flag(generate_debug_info, true)
229 -> Debug = on
230 ; Debug = off
231 ).
232
234chr_current_prolog_flag(Flag,Val) :- current_prolog_flag(Flag,Val).
236
237add_optimise_decl(CHR, CHR) :-
238 \+(\+(memberchk((:- chr_option(optimize, _)), CHR))), !.
239add_optimise_decl(CHR, [(:- chr_option(optimize, full))|CHR]) :-
240 chr_current_prolog_flag(optimize, full), !.
241add_optimise_decl(CHR, CHR).
242
246
247call_preprocess(CHR0, CHR) :-
248 preprocess(CHR0, CHR), !.
249call_preprocess(CHR, CHR).
250
256
257call_chr_translate(File, In, _Out) :-
258 ( chr_translate_line_info(In, File, Out0) ->
259 nb_setval(chr_translated_program,Out0),
260 fail
261 ).
262call_chr_translate(_, _In, Out) :-
263 nb_current(chr_translated_program,Out), !,
264 nb_delete(chr_translated_program).
265
266call_chr_translate(File, _, []) :-
267 print_message(error, chr(compilation_failed(File))).
268
269call_chr_preprocessor(Preprocessor,CHR,_NCHR) :-
270 ( call(Preprocessor,CHR,CHR0) ->
271 nb_setval(chr_preprocessed_program,CHR0),
272 fail
273 ).
274call_chr_preprocessor(_,_,NCHR) :-
275 nb_current(chr_preprocessed_program,NCHR), !,
276 nb_delete(chr_preprocessed_program).
277call_chr_preprocessor(Preprocessor,_,_) :-
278 chr_compiler_errors:print_chr_error(error(preprocessor,'Preprocessor `~w\' failed!\n',[Preprocessor])).
279
281
282 285
286:- multifile
287 user:message_hook/3,
288 chr:debug_event/2,
289 chr:debug_interact/3. 290:- dynamic
291 user:message_hook/3. 292
293user:message_hook(trace_mode(OnOff), _, _) :-
294 ( OnOff == on
295 -> chr_trace
296 ; chr_notrace
297 ),
298 fail. 299
300:- public
301 debug_event/2,
302 debug_interact/3. 303
308
309debug_event(_State, _Event) :-
310 tracing, 311 prolog_skip_level(Skip, Skip),
312 Skip \== very_deep,
313 prolog_current_frame(Me),
314 prolog_frame_attribute(Me, level, Level),
315 Level > Skip, !.
316
322
323debug_interact(Event, _Depth, creep) :-
324 prolog_event(Event),
325 tracing, !.
326
327prolog_event(call(_)).
328prolog_event(exit(_)).
329prolog_event(fail(_)).
330
336
337
338 341
342:- multifile
343 prolog:message/3. 344
345prolog:message(chr(CHR)) -->
346 chr_message(CHR).
347
348:- multifile
349 check:trivial_fail_goal/1. 350
351check:trivial_fail_goal(_:Goal) :-
352 functor(Goal, Name, _),
353 sub_atom(Name, 0, _, _, '$chr_store_constants_').
354
355 358
359:- create_prolog_flag(chr_toplevel_show_store, true, []). 360
361:- residual_goals(chr_residuals). 362
378
379chr_residuals(Residuals, Tail) :-
380 chr_current_prolog_flag(chr_toplevel_show_store,true),
381 nb_current(chr_global, _), !,
382 Goal = _:_,
383 findallv(Goal, current_chr_constraint(Goal), Residuals, Tail).
384chr_residuals(Residuals, Residuals).
385
386:- meta_predicate
387 findallv(?, 0, ?, ?). 388
389findallv(Templ, Goal, List, Tail) :-
390 List2 = [x|_],
391 State = state(List2),
392 ( call(Goal),
393 arg(1, State, L),
394 duplicate_term(Templ, New),
395 New = Templ,
396 Cons = [New|_],
397 nb_linkarg(2, L, Cons),
398 nb_linkarg(1, State, Cons),
399 fail
400 ; List2 = [x|List],
401 arg(1, State, Last),
402 arg(2, Last, Tail)
403 ).
404
405
406 409
410:- multifile system:term_expansion/2. 411:- dynamic system:term_expansion/2. 412
413system:term_expansion(In, Out) :-
414 \+ current_prolog_flag(xref, true),
415 chr_expand(In, Out).
417
484
486
487add_pragma_to_chr_rule((Name @ Rule), Pragma, Result) :- !,
488 add_pragma_to_chr_rule(Rule,Pragma,NRule),
489 Result = (Name @ NRule).
490add_pragma_to_chr_rule((Rule pragma Pragmas), Pragma, Result) :- !,
491 Result = (Rule pragma (Pragma,Pragmas)).
492add_pragma_to_chr_rule((Head ==> Body), Pragma, Result) :- !,
493 Result = (Head ==> Body pragma Pragma).
494add_pragma_to_chr_rule((Head <=> Body), Pragma, Result) :- !,
495 Result = (Head <=> Body pragma Pragma).
496add_pragma_to_chr_rule(Term,_,Term).
497
498
499 502
503:- multifile
504 sandbox:safe_primitive/1. 505
509
510sandbox:safe_primitive(system:b_setval(V, _)) :-
511 chr_var(V).
512sandbox:safe_primitive(system:nb_linkval(V, _)) :-
513 chr_var(V).
514sandbox:safe_primitive(chr:debug_event(_,_)).
515sandbox:safe_primitive(chr:debug_interact(_,_,_)).
516
517chr_var(Name) :- sub_atom(Name, 0, _, _, '$chr').
518chr_var(Name) :- sub_atom(Name, 0, _, _, 'chr').
519
520
521 524
525:- multifile
526 prolog_colour:term_colours/2,
527 prolog_colour:goal_colours/2. 528
532
533term_colours((_Name @ Rule), delimiter - [ identifier, RuleColours ]) :- !,
534 term_colours(Rule, RuleColours).
535term_colours((Rule pragma _Pragma), delimiter - [RuleColours,pragma]) :- !,
536 term_colours(Rule, RuleColours).
537term_colours((Head <=> Body), delimiter - [ HeadColours, BodyColours ]) :- !,
538 chr_head(Head, HeadColours),
539 chr_body(Body, BodyColours).
540term_colours((Head ==> Body), delimiter - [ HeadColours, BodyColours ]) :- !,
541 chr_head(Head, HeadColours),
542 chr_body(Body, BodyColours).
543
544chr_head(_C#_Id, delimiter - [ head, identifier ]) :- !.
545chr_head((A \ B), delimiter - [ AC, BC ]) :- !,
546 chr_head(A, AC),
547 chr_head(B, BC).
548chr_head((A, B), functor - [ AC, BC ]) :- !,
549 chr_head(A, AC),
550 chr_head(B, BC).
551chr_head(_, head).
552
553chr_body((Guard|Goal), delimiter - [ GuardColour, GoalColour ]) :- !,
554 chr_body(Guard, GuardColour),
555 chr_body(Goal, GoalColour).
556chr_body(_, body).
557
558
562
563goal_colours(constraints(Decls), deprecated-[DeclColours]) :-
564 chr_constraint_colours(Decls, DeclColours).
565goal_colours(chr_constraint(Decls), built_in-[DeclColours]) :-
566 chr_constraint_colours(Decls, DeclColours).
567goal_colours(chr_type(TypeDecl), built_in-[DeclColours]) :-
568 chr_type_decl_colours(TypeDecl, DeclColours).
569goal_colours(chr_option(Option,Value), built_in-[OpC,ValC]) :-
570 chr_option_colours(Option, Value, OpC, ValC).
571
572chr_constraint_colours(Var, instantiation_error(Var)) :-
573 var(Var), !.
574chr_constraint_colours((H,T), classify-[HeadColours,BodyColours]) :- !,
575 chr_constraint_colours(H, HeadColours),
576 chr_constraint_colours(T, BodyColours).
577chr_constraint_colours(PI, Colours) :-
578 pi_to_term(PI, Goal), !,
579 Colours = predicate_indicator-[ goal(constraint(0), Goal),
580 arity
581 ].
582chr_constraint_colours(Goal, Colours) :-
583 atom(Goal), !,
584 Colours = goal(constraint(0), Goal).
585chr_constraint_colours(Goal, Colours) :-
586 compound(Goal), !,
587 compound_name_arguments(Goal, _Name, Args),
588 maplist(chr_argspec, Args, ArgColours),
589 Colours = goal(constraint(0), Goal)-ArgColours.
590
591chr_argspec(Term, mode(Mode)-[chr_type(Type)]) :-
592 compound(Term),
593 compound_name_arguments(Term, Mode, [Type]),
594 chr_mode(Mode).
595
596chr_mode(+).
597chr_mode(?).
598chr_mode(-).
599
600pi_to_term(Name/Arity, Term) :-
601 atom(Name), integer(Arity), Arity >= 0, !,
602 functor(Term, Name, Arity).
603
604chr_type_decl_colours((Type ---> Def), built_in-[chr_type(Type), DefColours]) :-
605 chr_type_colours(Def, DefColours).
606chr_type_decl_colours((Type == Alias), built_in-[chr_type(Type), chr_type(Alias)]).
607
608chr_type_colours(Var, classify) :-
609 var(Var), !.
610chr_type_colours((A;B), control-[CA,CB]) :- !,
611 chr_type_colours(A, CA),
612 chr_type_colours(B, CB).
613chr_type_colours(T, chr_type(T)).
614
615chr_option_colours(Option, Value, identifier, ValCol) :-
616 chr_option_range(Option, Values), !,
617 ( nonvar(Value),
618 memberchk(Value, Values)
619 -> ValCol = classify
620 ; ValCol = error
621 ).
622chr_option_colours(_, _, error, classify).
623
624chr_option_range(check_guard_bindings, [on,off]).
625chr_option_range(optimize, [off, full]).
626chr_option_range(debug, [on, off]).
627
628prolog_colour:term_colours(Term, Colours) :-
629 term_colours(Term, Colours).
630prolog_colour:goal_colours(Term, Colours) :-
631 goal_colours(Term, Colours)