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 current_chr_constraint/1, 55 chr_trace/0,
56 chr_notrace/0,
57 chr_leash/1 58 ]). 59:- use_module(library(dialect), [expects_dialect/1]). 60:- use_module(library(apply), [maplist/3]). 61:- use_module(library(lists), [member/2]). 62
63:- expects_dialect(swi). 64
65:- set_prolog_flag(generate_debug_info, false). 66
67:- multifile
68 debug_ask_continue/1,
69 preprocess/2. 70
71:- multifile user:file_search_path/2. 72:- dynamic user:file_search_path/2. 73:- dynamic chr_translated_program/1. 74
75user:file_search_path(chr, library(chr)).
76
77:- load_files([ chr(chr_translate),
78 chr(chr_runtime),
79 chr(chr_messages),
80 chr(chr_hashtable_store),
81 chr(chr_compiler_errors)
82 ],
83 [ if(not_loaded),
84 silent(true)
85 ]). 86
87:- use_module(library(lists), [member/2]). 89
123
124:- multifile chr:'$chr_module'/1. 125
126:- dynamic chr_term/3. 127
128:- dynamic chr_pp/2. 129
141
142chr_expandable((:- constraints _)).
143chr_expandable((constraints _)).
144chr_expandable((:- chr_constraint _)).
145chr_expandable((:- chr_type _)).
146chr_expandable((chr_type _)).
147chr_expandable((:- chr_declaration _)).
148chr_expandable(option(_, _)).
149chr_expandable((:- chr_option(_, _))).
150chr_expandable((handler _)).
151chr_expandable((rules _)).
152chr_expandable((_ <=> _)).
153chr_expandable((_ @ _)).
154chr_expandable((_ ==> _)).
155chr_expandable((_ pragma _)).
156
161
([ (:- use_module(chr(chr_runtime))),
164 (:- style_check(-discontiguous)),
165 (:- style_check(-singleton)),
166 (:- style_check(-no_effect)),
167 (:- set_prolog_flag(generate_debug_info, false))
168 | Tail
169 ], Tail).
171
178
179chr_expand(Term, []) :-
180 chr_expandable(Term), !,
181 prolog_load_context(source,Source),
182 prolog_load_context(source,File),
183 prolog_load_context(term_position,Pos),
184 stream_position_data(line_count,Pos,SourceLocation),
185 add_pragma_to_chr_rule(Term,source_location(File:SourceLocation),NTerm),
186 assert(chr_term(Source, SourceLocation, NTerm)).
187chr_expand(Term, []) :-
188 Term = (:- chr_preprocessor Preprocessor), !,
189 prolog_load_context(source,File),
190 assert(chr_pp(File, Preprocessor)).
191chr_expand(end_of_file, FinalProgram) :-
192 extra_declarations(FinalProgram,Program),
193 prolog_load_context(source,File),
194 findall(T, retract(chr_term(File,_Line,T)), CHR0),
195 CHR0 \== [],
196 prolog_load_context(module, Module),
197 add_debug_decl(CHR0, CHR1),
198 add_optimise_decl(CHR1, CHR2),
199 call_preprocess(CHR2, CHR3),
200 CHR4 = [ (:- module(Module, [])) | CHR3 ],
201 findall(P, retract(chr_pp(File, P)), Preprocessors),
202 ( Preprocessors = [] ->
203 CHR4 = CHR
204 ; Preprocessors = [Preprocessor] ->
205 chr_compiler_errors:chr_info(preprocessor,'\tPreprocessing with ~w.\n',[Preprocessor]),
206 call_chr_preprocessor(Preprocessor,CHR4,CHR)
207 ;
208 chr_compiler_errors:print_chr_error(error(syntax(Preprocessors),'Too many preprocessors! Only one is allowed!\n',[])),
209 fail
210 ),
211 catch(call_chr_translate(File,
212 [ (:- module(Module, []))
213 | CHR
214 ],
215 Program0),
216 chr_error(Error),
217 ( chr_compiler_errors:print_chr_error(Error),
218 fail
219 )
220 ),
221 delete_header(Program0, Program).
222
223
([(:- module(_,_))|T0], T) :- !,
225 delete_header(T0, T).
226delete_header(L, L).
227
228add_debug_decl(CHR, CHR) :-
229 member(option(Name, _), CHR), Name == debug, !.
230add_debug_decl(CHR, CHR) :-
231 member((:- chr_option(Name, _)), CHR), Name == debug, !.
232add_debug_decl(CHR, [(:- chr_option(debug, Debug))|CHR]) :-
233 ( chr_current_prolog_flag(generate_debug_info, true)
234 -> Debug = on
235 ; Debug = off
236 ).
237
239chr_current_prolog_flag(Flag,Val) :- current_prolog_flag(Flag,Val).
241
242add_optimise_decl(CHR, CHR) :-
243 \+(\+(memberchk((:- chr_option(optimize, _)), CHR))), !.
244add_optimise_decl(CHR, [(:- chr_option(optimize, full))|CHR]) :-
245 chr_current_prolog_flag(optimize, full), !.
246add_optimise_decl(CHR, CHR).
247
251
252call_preprocess(CHR0, CHR) :-
253 preprocess(CHR0, CHR), !.
254call_preprocess(CHR, CHR).
255
261
262call_chr_translate(File, In, _Out) :-
263 ( chr_translate_line_info(In, File, Out0) ->
264 nb_setval(chr_translated_program,Out0),
265 fail
266 ).
267call_chr_translate(_, _In, Out) :-
268 nb_current(chr_translated_program,Out), !,
269 nb_delete(chr_translated_program).
270
271call_chr_translate(File, _, []) :-
272 print_message(error, chr(compilation_failed(File))).
273
274call_chr_preprocessor(Preprocessor,CHR,_NCHR) :-
275 ( call(Preprocessor,CHR,CHR0) ->
276 nb_setval(chr_preprocessed_program,CHR0),
277 fail
278 ).
279call_chr_preprocessor(_,_,NCHR) :-
280 nb_current(chr_preprocessed_program,NCHR), !,
281 nb_delete(chr_preprocessed_program).
282call_chr_preprocessor(Preprocessor,_,_) :-
283 chr_compiler_errors:print_chr_error(error(preprocessor,'Preprocessor `~w\' failed!\n',[Preprocessor])).
284
286
287 290
291:- multifile
292 user:message_hook/3,
293 chr:debug_event/2,
294 chr:debug_interact/3. 295:- dynamic
296 user:message_hook/3. 297
298user:message_hook(trace_mode(OnOff), _, _) :-
299 ( OnOff == on
300 -> chr_trace
301 ; chr_notrace
302 ),
303 fail. 304
305:- public
306 debug_event/2,
307 debug_interact/3. 308
313
314debug_event(_State, _Event) :-
315 tracing, 316 prolog_skip_level(Skip, Skip),
317 Skip \== very_deep,
318 prolog_current_frame(Me),
319 prolog_frame_attribute(Me, level, Level),
320 Level > Skip, !.
321
327
328debug_interact(Event, _Depth, creep) :-
329 prolog_event(Event),
330 tracing, !.
331
332prolog_event(call(_)).
333prolog_event(exit(_)).
334prolog_event(fail(_)).
335
341
342
343 346
347:- multifile
348 prolog:message/3. 349
350prolog:message(chr(CHR)) -->
351 chr_message(CHR).
352
353:- multifile
354 check:trivial_fail_goal/1. 355
356check:trivial_fail_goal(_:Goal) :-
357 functor(Goal, Name, _),
358 sub_atom(Name, 0, _, _, '$chr_store_constants_').
359
360 363
364:- create_prolog_flag(chr_toplevel_show_store, true, []). 365
366:- residual_goals(chr_residuals). 367
383
384chr_residuals(Residuals, Tail) :-
385 chr_current_prolog_flag(chr_toplevel_show_store,true),
386 nb_current(chr_global, _), !,
387 Goal = _:_,
388 findallv(Goal, current_chr_constraint(Goal), Residuals, Tail).
389chr_residuals(Residuals, Residuals).
390
391:- meta_predicate
392 findallv(?, 0, ?, ?). 393
394findallv(Templ, Goal, List, Tail) :-
395 List2 = [x|_],
396 State = state(List2),
397 ( call(Goal),
398 arg(1, State, L),
399 duplicate_term(Templ, New),
400 New = Templ,
401 Cons = [New|_],
402 nb_linkarg(2, L, Cons),
403 nb_linkarg(1, State, Cons),
404 fail
405 ; List2 = [x|List],
406 arg(1, State, Last),
407 arg(2, Last, Tail)
408 ).
409
410
411 414
415:- multifile system:term_expansion/2. 416:- dynamic system:term_expansion/2. 417
418system:term_expansion(In, Out) :-
419 \+ current_prolog_flag(xref, true),
420 chr_expand(In, Out).
422
489
491
492add_pragma_to_chr_rule((Name @ Rule), Pragma, Result) :- !,
493 add_pragma_to_chr_rule(Rule,Pragma,NRule),
494 Result = (Name @ NRule).
495add_pragma_to_chr_rule((Rule pragma Pragmas), Pragma, Result) :- !,
496 Result = (Rule pragma (Pragma,Pragmas)).
497add_pragma_to_chr_rule((Head ==> Body), Pragma, Result) :- !,
498 Result = (Head ==> Body pragma Pragma).
499add_pragma_to_chr_rule((Head <=> Body), Pragma, Result) :- !,
500 Result = (Head <=> Body pragma Pragma).
501add_pragma_to_chr_rule(Term,_,Term).
502
503
504 507
508:- multifile
509 sandbox:safe_primitive/1. 510
514
515sandbox:safe_primitive(system:b_setval(V, _)) :-
516 chr_var(V).
517sandbox:safe_primitive(system:nb_linkval(V, _)) :-
518 chr_var(V).
519sandbox:safe_primitive(chr:debug_event(_,_)).
520sandbox:safe_primitive(chr:debug_interact(_,_,_)).
521
522chr_var(Name) :- sub_atom(Name, 0, _, _, '$chr').
523chr_var(Name) :- sub_atom(Name, 0, _, _, 'chr').
524
525
526 529
530:- multifile
531 prolog_colour:term_colours/2,
532 prolog_colour:goal_colours/2. 533
537
538term_colours((_Name @ Rule), delimiter - [ identifier, RuleColours ]) :- !,
539 term_colours(Rule, RuleColours).
540term_colours((Rule pragma _Pragma), delimiter - [RuleColours,pragma]) :- !,
541 term_colours(Rule, RuleColours).
542term_colours((Head <=> Body), delimiter - [ HeadColours, BodyColours ]) :- !,
543 chr_head(Head, HeadColours),
544 chr_body(Body, BodyColours).
545term_colours((Head ==> Body), delimiter - [ HeadColours, BodyColours ]) :- !,
546 chr_head(Head, HeadColours),
547 chr_body(Body, BodyColours).
548
549chr_head(_C#_Id, delimiter - [ head, identifier ]) :- !.
550chr_head((A \ B), delimiter - [ AC, BC ]) :- !,
551 chr_head(A, AC),
552 chr_head(B, BC).
553chr_head((A, B), functor - [ AC, BC ]) :- !,
554 chr_head(A, AC),
555 chr_head(B, BC).
556chr_head(_, head).
557
558chr_body((Guard|Goal), delimiter - [ GuardColour, GoalColour ]) :- !,
559 chr_body(Guard, GuardColour),
560 chr_body(Goal, GoalColour).
561chr_body(_, body).
562
563
567
568goal_colours(constraints(Decls), deprecated-[DeclColours]) :-
569 chr_constraint_colours(Decls, DeclColours).
570goal_colours(chr_constraint(Decls), built_in-[DeclColours]) :-
571 chr_constraint_colours(Decls, DeclColours).
572goal_colours(chr_type(TypeDecl), built_in-[DeclColours]) :-
573 chr_type_decl_colours(TypeDecl, DeclColours).
574goal_colours(chr_option(Option,Value), built_in-[OpC,ValC]) :-
575 chr_option_colours(Option, Value, OpC, ValC).
576
577chr_constraint_colours(Var, instantiation_error(Var)) :-
578 var(Var), !.
579chr_constraint_colours((H,T), classify-[HeadColours,BodyColours]) :- !,
580 chr_constraint_colours(H, HeadColours),
581 chr_constraint_colours(T, BodyColours).
582chr_constraint_colours(PI, Colours) :-
583 pi_to_term(PI, Goal), !,
584 Colours = predicate_indicator-[ goal(constraint(0), Goal),
585 arity
586 ].
587chr_constraint_colours(Goal, Colours) :-
588 atom(Goal), !,
589 Colours = goal(constraint(0), Goal).
590chr_constraint_colours(Goal, Colours) :-
591 compound(Goal), !,
592 compound_name_arguments(Goal, _Name, Args),
593 maplist(chr_argspec, Args, ArgColours),
594 Colours = goal(constraint(0), Goal)-ArgColours.
595
596chr_argspec(Term, mode(Mode)-[chr_type(Type)]) :-
597 compound(Term),
598 compound_name_arguments(Term, Mode, [Type]),
599 chr_mode(Mode).
600
601chr_mode(+).
602chr_mode(?).
603chr_mode(-).
604
605pi_to_term(Name/Arity, Term) :-
606 atom(Name), integer(Arity), Arity >= 0, !,
607 functor(Term, Name, Arity).
608
609chr_type_decl_colours((Type ---> Def), built_in-[chr_type(Type), DefColours]) :-
610 chr_type_colours(Def, DefColours).
611chr_type_decl_colours((Type == Alias), built_in-[chr_type(Type), chr_type(Alias)]).
612
613chr_type_colours(Var, classify) :-
614 var(Var), !.
615chr_type_colours((A;B), control-[CA,CB]) :- !,
616 chr_type_colours(A, CA),
617 chr_type_colours(B, CB).
618chr_type_colours(T, chr_type(T)).
619
620chr_option_colours(Option, Value, identifier, ValCol) :-
621 chr_option_range(Option, Values), !,
622 ( nonvar(Value),
623 memberchk(Value, Values)
624 -> ValCol = classify
625 ; ValCol = error
626 ).
627chr_option_colours(_, _, error, classify).
628
629chr_option_range(check_guard_bindings, [on,off]).
630chr_option_range(optimize, [off, full]).
631chr_option_range(debug, [on, off]).
632
633prolog_colour:term_colours(Term, Colours) :-
634 term_colours(Term, Colours).
635prolog_colour:goal_colours(Term, Colours) :-
636 goal_colours(Term, Colours)