3 Part of CHR (Constraint Handling Rules)
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.
32 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
34 %% ____ _ _ ____ ____ _ _
35 %% / ___| | | | _ \ / ___|___ _ __ ___ _ __ (_) | ___ _ __
36 %% | | | |_| | |_) | | | / _ \| '_ ` _ \| '_ \| | |/ _ \ '__|
37 %% | |___| _ | _ < | |__| (_) | | | | | | |_) | | | __/ |
38 %% \____|_| |_|_| \_\ \____\___/|_| |_| |_| .__/|_|_|\___|_|
41 %% hProlog CHR compiler:
43 %% * by Tom Schrijvers, K.U. Leuven, Tom.Schrijvers@cs.kuleuven.be
45 %% * based on the SICStus CHR compilation by Christian Holzbaur
47 %% First working version: 6 June 2003
49 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
52 %% * SICStus compatibility
53 %% - rules/1 declaration
59 %% * do not suspend on variables that don't matter
60 %% * make difference between cheap guards for reordering
61 %% and non-binding guards for lock removal
63 %% * unqiue -> once/[] transformation for propagation
65 %% * cheap guards interleaved with head retrieval + faster
66 %% via-retrieval + non-empty checking for propagation rules
67 %% redo for simpagation_head2 prelude
69 %% * intelligent backtracking for simplification/simpagation rule
70 %% generator_1(X),'_$savecp'(CP_1),
77 %% ('_$cutto'(CP_1), fail)
81 %% or recently developped cascading-supported approach
83 %% * intelligent backtracking for propagation rule
84 %% use additional boolean argument for each possible smart backtracking
85 %% when boolean at end of list true -> no smart backtracking
86 %% false -> smart backtracking
87 %% only works for rules with at least 3 constraints in the head
89 %% * mutually exclusive rules
91 %% * (set semantics + functional dependency) declaration + resolution
93 %% * type and instantiation declarations + optimisations
96 %% * disable global store option
100 %% * debugging events
101 %% * constraints that can never be attached / always simplified away
102 %% -> need not be considered in diverse operations
103 %% * clean up generated code
104 %% * input verification: pragmas
105 %% * SICStus compatibility: handler/1, constraints/1
106 %% * optimise variable passing for propagation rule
107 %% * reordering of head constraints for passive head search
108 %% * unique inference for simpagation rules
109 %% * unique optimisation for simpagation and simplification rules
110 %% * cheap guards interleaved with head retrieval + faster
111 %% via-retrieval + non-empty checking for simplification / simpagation rules
113 %% C1 \ C2 <=> true | Body.
115 %% C1 # ID \ C2 <=> true | Body pragma passive(ID).
116 %% where C1 and C2 are indentical under functional dependency information
117 %% * valid to disregard body in uniqueness inference?
118 %% * unique inference for simplification rules
120 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
122 :- module(chr_translate_bootstrap1,
123 [ chr_translate/2 % +Decls, -TranslatedDecls
126 :- use_module(library(lists),[append/3,member/2,permutation/2,reverse/2]).
127 :- use_module(library(ordsets)).
129 :- use_module(hprolog).
130 :- use_module(pairlist).
134 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
139 get_constraint_index/2,
140 max_constraint_index/1,
141 get_max_constraint_index/1,
148 constraint(FA,Number) \ constraint(FA,Query)
150 constraint(FA,Index) # ID \ constraint(Query,Index)
151 <=> Query = FA pragma passive(ID).
153 constraint_count(Index) # ID \ constraint_count(Query)
154 <=> Query = Index pragma passive(ID).
156 target_module(Mod) # ID \ get_target_module(Query)
159 get_target_module(Query)
162 constraint_index(C,Index) # ID \ get_constraint_index(C,Query)
165 get_constraint_index(C,Query)
168 max_constraint_index(Index) # ID \ get_max_constraint_index(Query)
171 get_max_constraint_index(Query)
174 attached(Constr,yes) \ attached(Constr,_) <=> true.
175 attached(Constr,no) \ attached(Constr,_) <=> true.
176 attached(Constr,maybe) \ attached(Constr,maybe) <=> true.
178 attached(Constr,Type) # ID \ is_attached(Constr)
186 is_attached(C) <=> true.
188 chr_clear \ constraint(_,_) # ID
189 <=> true pragma passive(ID).
190 chr_clear \ constraint_count(_) # ID
191 <=> true pragma passive(ID).
192 chr_clear \ constraint_index(_,_) # ID
193 <=> true pragma passive(ID).
194 chr_clear \ max_constraint_index(_) # ID
195 <=> true pragma passive(ID).
196 chr_clear \ target_module(_) # ID
197 <=> true pragma passive(ID).
198 chr_clear \ attached(_,_) # ID
199 <=> true pragma passive(ID).
202 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
204 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
208 chr_translate(Declarations,NewDeclarations) :-
210 partition_clauses(Declarations,Decls,Rules,OtherClauses),
212 NewDeclarations = OtherClauses
214 check_rules(Rules,Decls),
215 unique_analyse_optimise(Rules,NRules),
216 check_attachments(NRules),
217 set_constraint_indices(Decls,1),
218 store_management_preds(Decls,StoreClauses),
219 constraints_code(Decls,NRules,ConstraintClauses),
220 append([OtherClauses,
228 store_management_preds(Constraints,Clauses) :-
229 generate_attach_detach_a_constraint_all(Constraints,AttachAConstraintClauses),
230 generate_attach_increment(AttachIncrementClauses),
231 generate_attr_unify_hook(AttrUnifyHookClauses),
232 append([AttachAConstraintClauses
233 ,AttachIncrementClauses
234 ,AttrUnifyHookClauses]
238 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
240 %% Partitioning of clauses into constraint declarations, chr rules and other
243 partition_clauses([],[],[],[]).
244 partition_clauses([C|Cs],Ds,Rs,OCs) :-
249 ; is_declaration(C,D) ->
253 ; is_module_declaration(C,Mod) ->
259 format('CHR compiler WARNING: ~w.\n',[C]),
260 format(' `--> SICStus compatibility: ignoring handler/1 declaration.\n',[]),
265 format('CHR compiler WARNING: ~w.\n',[C]),
266 format(' `--> SICStus compatibility: ignoring rules/1 declaration.\n',[]),
270 ; C = (:- chr_option(OptionName,OptionValue)) ->
271 handle_option(OptionName,OptionValue),
279 partition_clauses(Cs,RDs,RRs,ROCs).
281 is_declaration(D, Constraints) :- %% constraint declaration
283 ( Decl =.. [chr_constraint,Cs] ; Decl =.. [chr_constraint,Cs]),
284 conj2list(Cs,Constraints).
302 %% list(constraint), :: constraints to be removed
303 %% list(constraint), :: surviving constraints
308 rule(RI,R) :- %% name @ rule
309 RI = (Name @ RI2), !,
310 rule(RI2,yes(Name),R).
315 RI = (RI2 pragma P), !, %% pragmas
318 R = pragma(R1,IDs,Ps,Name).
321 R = pragma(R1,IDs,[],Name).
323 is_rule(RI,R,IDs) :- %% propagation rule
326 get_ids(Head2i,IDs2,Head2),
329 R = rule([],Head2,G,RB)
331 R = rule([],Head2,true,B)
333 is_rule(RI,R,IDs) :- %% simplification/simpagation rule
342 conj2list(H1,Head2i),
343 conj2list(H2,Head1i),
344 get_ids(Head2i,IDs2,Head2,0,N),
345 get_ids(Head1i,IDs1,Head1,N,_),
347 ; conj2list(H,Head1i),
349 get_ids(Head1i,IDs1,Head1),
352 R = rule(Head1,Head2,Guard,Body).
354 get_ids(Cs,IDs,NCs) :-
355 get_ids(Cs,IDs,NCs,0,_).
357 get_ids([],[],[],N,N).
358 get_ids([C|Cs],[N|IDs],[NC|NCs],N,NN) :-
365 get_ids(Cs,IDs,NCs, M,NN).
367 is_module_declaration((:- module(Mod)),Mod).
368 is_module_declaration((:- module(Mod,_)),Mod).
370 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
372 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
373 %% Some input verification:
374 %% - all constraints in heads are declared constraints
376 check_rules(Rules,Decls) :-
377 check_rules(Rules,Decls,1).
380 check_rules([PragmaRule|Rest],Decls,N) :-
381 check_rule(PragmaRule,Decls,N),
383 check_rules(Rest,Decls,N1).
385 check_rule(PragmaRule,Decls,N) :-
386 PragmaRule = pragma(Rule,_IDs,Pragmas,_Name),
387 Rule = rule(H1,H2,_,_),
388 append(H1,H2,HeadConstraints),
389 check_head_constraints(HeadConstraints,Decls,PragmaRule,N),
390 check_pragmas(Pragmas,PragmaRule,N).
392 check_head_constraints([],_,_,_).
393 check_head_constraints([Constr|Rest],Decls,PragmaRule,N) :-
395 ( member(F/A,Decls) ->
396 check_head_constraints(Rest,Decls,PragmaRule,N)
398 format('CHR compiler ERROR: Undeclared constraint ~w in head of ~@.\n',
399 [F/A,format_rule(PragmaRule,N)]),
400 format(' `--> Constraint should be on of ~w.\n',[Decls]),
404 check_pragmas([],_,_).
405 check_pragmas([Pragma|Pragmas],PragmaRule,N) :-
406 check_pragma(Pragma,PragmaRule,N),
407 check_pragmas(Pragmas,PragmaRule,N).
409 check_pragma(Pragma,PragmaRule,N) :-
411 format('CHR compiler ERROR: invalid pragma ~w in ~@.\n',
412 [Pragma,format_rule(PragmaRule,N)]),
413 format(' `--> Pragma should not be a variable!\n',[]),
416 check_pragma(passive(ID), PragmaRule, N) :-
418 PragmaRule = pragma(_,ids(IDs1,IDs2),_,_),
419 ( memberchk_eq(ID,IDs1) ->
421 ; memberchk_eq(ID,IDs2) ->
424 format('CHR compiler ERROR: invalid identifier ~w in pragma passive in ~@.\n',
425 [ID,format_rule(PragmaRule,N)]),
429 check_pragma(Pragma, PragmaRule, N) :-
430 Pragma = unique(_,_),
432 format('CHR compiler WARNING: undocumented pragma ~w in ~@.\n',[Pragma,format_rule(PragmaRule,N)]),
433 format(' `--> Only use this pragma if you know what you are doing.\n',[]).
435 check_pragma(Pragma, PragmaRule, N) :-
436 Pragma = already_in_heads,
438 format('CHR compiler WARNING: currently unsupported pragma ~w in ~@.\n',[Pragma,format_rule(PragmaRule,N)]),
439 format(' `--> Pragma is ignored. Termination and correctness may be affected \n',[]).
441 check_pragma(Pragma, PragmaRule, N) :-
442 Pragma = already_in_head(_),
444 format('CHR compiler WARNING: currently unsupported pragma ~w in ~@.\n',[Pragma,format_rule(PragmaRule,N)]),
445 format(' `--> Pragma is ignored. Termination and correctness may be affected \n',[]).
447 check_pragma(Pragma,PragmaRule,N) :-
448 format('CHR compiler ERROR: invalid pragma ~w in ~@.\n',[Pragma,format_rule(PragmaRule,N)]),
449 format(' `--> Pragma should be one of passive/1!\n',[]),
452 format_rule(PragmaRule,N) :-
453 PragmaRule = pragma(_,_,_,MaybeName),
454 ( MaybeName = yes(Name) ->
455 write('rule '), write(Name)
457 write('rule number '), write(N)
460 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
462 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
466 handle_option(Var,Value) :-
468 format('CHR compiler ERROR: ~w.\n',[option(Var,Value)]),
469 format(' `--> First argument should be an atom, not a variable.\n',[]),
472 handle_option(Name,Value) :-
474 format('CHR compiler ERROR: ~w.\n',[option(Name,Value)]),
475 format(' `--> Second argument should be a nonvariable.\n',[]),
478 handle_option(Name,Value) :-
479 option_definition(Name,Value,Flags),
481 set_chr_pp_flags(Flags).
483 handle_option(Name,Value) :-
484 \+ option_definition(Name,_,_), !.
486 handle_option(Name,Value) :-
487 findall(V,option_definition(Name,V,_),Vs),
488 format('CHR compiler ERROR: ~w.\n',[option(Name,Value)]),
489 format(' `--> Invalid value ~w: should be one of ~w.\n',[Value,Vs]),
492 option_definition(optimize,experimental,Flags) :-
493 Flags = [ unique_analyse_optimise - on,
494 check_unnecessary_active - full,
496 set_semantics_rule - on,
497 check_attachments - on,
498 guard_via_reschedule - on
500 option_definition(optimize,full,Flags) :-
501 Flags = [ unique_analyse_optimise - on,
502 check_unnecessary_active - full,
504 set_semantics_rule - on,
505 check_attachments - on,
506 guard_via_reschedule - on
509 option_definition(optimize,sicstus,Flags) :-
510 Flags = [ unique_analyse_optimise - off,
511 check_unnecessary_active - simplification,
513 set_semantics_rule - off,
514 check_attachments - off,
515 guard_via_reschedule - off
518 option_definition(optimize,off,Flags) :-
519 Flags = [ unique_analyse_optimise - off,
520 check_unnecessary_active - off,
522 set_semantics_rule - off,
523 check_attachments - off,
524 guard_via_reschedule - off
527 option_definition(debug,off,Flags) :-
528 Flags = [ debugable - off ].
529 option_definition(debug,on,Flags) :-
530 Flags = [ debugable - on ].
532 option_definition(check_guard_bindings,on,Flags) :-
533 Flags = [ guard_locks - on ].
535 option_definition(check_guard_bindings,off,Flags) :-
536 Flags = [ guard_locks - off ].
539 chr_pp_flag_definition(Name,[DefaultValue|_]),
540 set_chr_pp_flag(Name,DefaultValue),
544 set_chr_pp_flags([]).
545 set_chr_pp_flags([Name-Value|Flags]) :-
546 set_chr_pp_flag(Name,Value),
547 set_chr_pp_flags(Flags).
549 set_chr_pp_flag(Name,Value) :-
550 atomic_concat('$chr_pp_',Name,GlobalVar),
551 nb_setval(GlobalVar,Value).
553 chr_pp_flag_definition(unique_analyse_optimise,[on,off]).
554 chr_pp_flag_definition(check_unnecessary_active,[full,simplification,off]).
555 chr_pp_flag_definition(reorder_heads,[on,off]).
556 chr_pp_flag_definition(set_semantics_rule,[on,off]).
557 chr_pp_flag_definition(guard_via_reschedule,[on,off]).
558 chr_pp_flag_definition(guard_locks,[on,off]).
559 chr_pp_flag_definition(check_attachments,[on,off]).
560 chr_pp_flag_definition(debugable,[off,on]).
562 chr_pp_flag(Name,Value) :-
563 atomic_concat('$chr_pp_',Name,GlobalVar),
564 nb_getval(GlobalVar,V),
566 chr_pp_flag_definition(Name,[Value|_])
570 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
572 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
574 %% Generated predicates
575 %% attach_$CONSTRAINT
577 %% detach_$CONSTRAINT
580 %% attach_$CONSTRAINT
581 generate_attach_detach_a_constraint_all([],[]).
582 generate_attach_detach_a_constraint_all([Constraint|Constraints],Clauses) :-
583 ( is_attached(Constraint) ->
584 generate_attach_a_constraint(Constraint,Clauses1),
585 generate_detach_a_constraint(Constraint,Clauses2)
590 generate_attach_detach_a_constraint_all(Constraints,Clauses3),
591 append([Clauses1,Clauses2,Clauses3],Clauses).
593 generate_attach_a_constraint(Constraint,[Clause1,Clause2]) :-
594 generate_attach_a_constraint_empty_list(Constraint,Clause1),
595 get_max_constraint_index(N),
597 generate_attach_a_constraint_1_1(Constraint,Clause2)
599 generate_attach_a_constraint_t_p(Constraint,Clause2)
602 generate_attach_a_constraint_empty_list(CFct / CAty,Clause) :-
603 atom_concat_list(['attach_',CFct, (/) ,CAty],Fct),
605 Head =.. [Fct | Args],
606 Clause = ( Head :- true).
608 generate_attach_a_constraint_1_1(CFct / CAty,Clause) :-
609 atom_concat_list(['attach_',CFct, (/) ,CAty],Fct),
610 Args = [[Var|Vars],Susp],
611 Head =.. [Fct | Args],
612 RecursiveCall =.. [Fct,Vars,Susp],
613 get_target_module(Mod),
616 ( get_attr(Var, Mod, Susps) ->
617 NewSusps=[Susp|Susps],
618 put_attr(Var, Mod, NewSusps)
620 put_attr(Var, Mod, [Susp])
624 Clause = (Head :- Body).
626 generate_attach_a_constraint_t_p(CFct / CAty,Clause) :-
627 atom_concat_list(['attach_',CFct, (/) ,CAty],Fct),
628 Args = [[Var|Vars],Susp],
629 Head =.. [Fct | Args],
630 RecursiveCall =.. [Fct,Vars,Susp],
631 get_constraint_index(CFct/CAty,Position),
632 or_pattern(Position,Pattern),
633 get_max_constraint_index(Total),
634 make_attr(Total,Mask,SuspsList,Attr),
635 nth1(Position,SuspsList,Susps),
636 substitute(Susps,SuspsList,[Susp|Susps],SuspsList1),
637 make_attr(Total,Mask,SuspsList1,NewAttr1),
638 substitute(Susps,SuspsList,[Susp],SuspsList2),
639 make_attr(Total,NewMask,SuspsList2,NewAttr2),
640 copy_term_nat(SuspsList,SuspsList3),
641 nth1(Position,SuspsList3,[Susp]),
642 chr_delete(SuspsList3,[Susp],RestSuspsList),
643 set_elems(RestSuspsList,[]),
644 make_attr(Total,Pattern,SuspsList3,NewAttr3),
645 get_target_module(Mod),
648 ( get_attr(Var,Mod,TAttr) ->
650 ( Mask /\ Pattern =:= Pattern ->
651 put_attr(Var, Mod, NewAttr1)
653 NewMask is Mask \/ Pattern,
654 put_attr(Var, Mod, NewAttr2)
657 put_attr(Var,Mod,NewAttr3)
661 Clause = (Head :- Body).
663 %% detach_$CONSTRAINT
664 generate_detach_a_constraint(Constraint,[Clause1,Clause2]) :-
665 generate_detach_a_constraint_empty_list(Constraint,Clause1),
666 get_max_constraint_index(N),
668 generate_detach_a_constraint_1_1(Constraint,Clause2)
670 generate_detach_a_constraint_t_p(Constraint,Clause2)
673 generate_detach_a_constraint_empty_list(CFct / CAty,Clause) :-
674 atom_concat_list(['detach_',CFct, (/) ,CAty],Fct),
676 Head =.. [Fct | Args],
677 Clause = ( Head :- true).
679 generate_detach_a_constraint_1_1(CFct / CAty,Clause) :-
680 atom_concat_list(['detach_',CFct, (/) ,CAty],Fct),
681 Args = [[Var|Vars],Susp],
682 Head =.. [Fct | Args],
683 RecursiveCall =.. [Fct,Vars,Susp],
684 get_target_module(Mod),
687 ( get_attr(Var,Mod,Susps) ->
688 'chr sbag_del_element'(Susps,Susp,NewSusps),
692 put_attr(Var,Mod,NewSusps)
699 Clause = (Head :- Body).
701 generate_detach_a_constraint_t_p(CFct / CAty,Clause) :-
702 atom_concat_list(['detach_',CFct, (/) ,CAty],Fct),
703 Args = [[Var|Vars],Susp],
704 Head =.. [Fct | Args],
705 RecursiveCall =.. [Fct,Vars,Susp],
706 get_constraint_index(CFct/CAty,Position),
707 or_pattern(Position,Pattern),
708 and_pattern(Position,DelPattern),
709 get_max_constraint_index(Total),
710 make_attr(Total,Mask,SuspsList,Attr),
711 nth1(Position,SuspsList,Susps),
712 substitute(Susps,SuspsList,[],SuspsList1),
713 make_attr(Total,NewMask,SuspsList1,Attr1),
714 substitute(Susps,SuspsList,NewSusps,SuspsList2),
715 make_attr(Total,Mask,SuspsList2,Attr2),
716 get_target_module(Mod),
719 ( get_attr(Var,Mod,TAttr) ->
721 ( Mask /\ Pattern =:= Pattern ->
722 'chr sbag_del_element'(Susps,Susp,NewSusps),
724 NewMask is Mask /\ DelPattern,
728 put_attr(Var,Mod,Attr1)
731 put_attr(Var,Mod,Attr2)
741 Clause = (Head :- Body).
743 %% detach_$CONSTRAINT
744 generate_attach_increment([Clause1,Clause2]) :-
745 generate_attach_increment_empty(Clause1),
746 get_max_constraint_index(N),
748 generate_attach_increment_one(Clause2)
750 generate_attach_increment_many(N,Clause2)
753 generate_attach_increment_empty((attach_increment([],_) :- true)).
755 generate_attach_increment_one(Clause) :-
756 Head = attach_increment([Var|Vars],Susps),
757 get_target_module(Mod),
760 'chr not_locked'(Var),
761 ( get_attr(Var,Mod,VarSusps) ->
762 sort(VarSusps,SortedVarSusps),
763 merge(Susps,SortedVarSusps,MergedSusps),
764 put_attr(Var,Mod,MergedSusps)
766 put_attr(Var,Mod,Susps)
768 attach_increment(Vars,Susps)
770 Clause = (Head :- Body).
772 generate_attach_increment_many(N,Clause) :-
773 make_attr(N,Mask,SuspsList,Attr),
774 make_attr(N,OtherMask,OtherSuspsList,OtherAttr),
775 Head = attach_increment([Var|Vars],Attr),
776 bagof(G,X ^ Y ^ SY ^ M ^ (member2(SuspsList,OtherSuspsList,X-Y),G = (sort(Y,SY),'chr merge_attributes'(X,SY,M))),Gs),
777 list2conj(Gs,SortGoals),
778 bagof(MS,A ^ B ^ C ^ member((A,'chr merge_attributes'(B,C,MS)),Gs), MergedSuspsList),
779 make_attr(N,MergedMask,MergedSuspsList,NewAttr),
780 get_target_module(Mod),
783 'chr not_locked'(Var),
784 ( get_attr(Var,Mod,TOtherAttr) ->
785 TOtherAttr = OtherAttr,
787 MergedMask is Mask \/ OtherMask,
788 put_attr(Var,Mod,NewAttr)
790 put_attr(Var,Mod,Attr)
792 attach_increment(Vars,Attr)
794 Clause = (Head :- Body).
797 generate_attr_unify_hook([Clause]) :-
798 get_max_constraint_index(N),
800 generate_attr_unify_hook_one(Clause)
802 generate_attr_unify_hook_many(N,Clause)
805 generate_attr_unify_hook_one(Clause) :-
806 Head = Mod:attr_unify_hook(Susps,Other),
807 get_target_module(Mod),
808 make_run_suspensions(NewSusps,WakeNewSusps),
809 make_run_suspensions(Susps,WakeSusps),
812 sort(Susps, SortedSusps),
814 ( get_attr(Other,Mod,OtherSusps) ->
819 sort(OtherSusps,SortedOtherSusps),
820 'chr merge_attributes'(SortedSusps,SortedOtherSusps,NewSusps),
821 put_attr(Other,Mod,NewSusps),
825 term_variables(Other,OtherVars),
826 attach_increment(OtherVars, SortedSusps)
833 Clause = (Head :- Body).
835 generate_attr_unify_hook_many(N,Clause) :-
836 make_attr(N,Mask,SuspsList,Attr),
837 make_attr(N,OtherMask,OtherSuspsList,OtherAttr),
838 bagof(Sort,A ^ B ^ ( member(A,SuspsList) , Sort = sort(A,B) ) , SortGoalList),
839 list2conj(SortGoalList,SortGoals),
840 bagof(B, A ^ member(sort(A,B),SortGoalList), SortedSuspsList),
841 bagof(C, D ^ E ^ F ^ G ^ (member2(SortedSuspsList,OtherSuspsList,D-E),
843 'chr merge_attributes'(D,F,G)) ),
845 bagof(G, D ^ F ^ H ^ member((H,'chr merge_attributes'(D,F,G)),SortMergeGoalList) , MergedSuspsList),
846 list2conj(SortMergeGoalList,SortMergeGoals),
847 make_attr(N,MergedMask,MergedSuspsList,MergedAttr),
848 make_attr(N,Mask,SortedSuspsList,SortedAttr),
849 Head = Mod:attr_unify_hook(Attr,Other),
850 get_target_module(Mod),
851 make_run_suspensions_loop(MergedSuspsList,WakeMergedSusps),
852 make_run_suspensions_loop(SortedSuspsList,WakeSortedSusps),
857 ( get_attr(Other,Mod,TOtherAttr) ->
858 TOtherAttr = OtherAttr,
860 MergedMask is Mask \/ OtherMask,
861 put_attr(Other,Mod,MergedAttr),
864 put_attr(Other,Mod,SortedAttr),
869 term_variables(Other,OtherVars),
870 attach_increment(OtherVars,SortedAttr)
877 Clause = (Head :- Body).
879 make_run_suspensions(Susps,Goal) :-
880 ( chr_pp_flag(debugable,on) ->
881 Goal = 'chr run_suspensions_d'(Susps)
883 Goal = 'chr run_suspensions'(Susps)
886 make_run_suspensions_loop(SuspsList,Goal) :-
887 ( chr_pp_flag(debugable,on) ->
888 Goal = 'chr run_suspensions_loop_d'(SuspsList)
890 Goal = 'chr run_suspensions_loop'(SuspsList)
893 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
895 check_attachments(Rules) :-
896 ( chr_pp_flag(check_attachments,on) ->
897 check_attachments_(Rules)
902 check_attachments_([]).
903 check_attachments_([R|Rs]) :-
905 check_attachments_(Rs).
907 check_attachment(R) :-
908 R = pragma(Rule,_,_,_),
909 Rule = rule(H1,H2,G,B),
910 check_attachment_heads1(H1,H1,H2,G),
911 check_attachment_heads2(H2,H1,B).
913 check_attachment_heads1([],_,_,_).
914 check_attachment_heads1([C|Cs],H1,H2,G) :-
925 check_attachment_heads1(Cs,H1,H2,G).
928 no_matching([X|Xs],Prev) :-
930 \+ memberchk_eq(X,Prev),
931 no_matching(Xs,[X|Prev]).
933 check_attachment_heads2([],_,_).
934 check_attachment_heads2([C|Cs],H1,B) :-
942 check_attachment_heads2(Cs,H1,B).
945 all_attached([C|Cs]) :-
950 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
952 set_constraint_indices([],M) :-
954 max_constraint_index(N).
955 set_constraint_indices([C|Cs],N) :-
957 constraint_index(C,N),
959 set_constraint_indices(Cs,M)
961 set_constraint_indices(Cs,N)
964 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
965 %% ____ _ ____ _ _ _ _
966 %% | _ \ _ _| | ___ / ___|___ _ __ ___ _ __ (_) | __ _| |_(_) ___ _ __
967 %% | |_) | | | | |/ _ \ | | / _ \| '_ ` _ \| '_ \| | |/ _` | __| |/ _ \| '_ \
968 %% | _ <| |_| | | __/ | |__| (_) | | | | | | |_) | | | (_| | |_| | (_) | | | |
969 %% |_| \_\\__,_|_|\___| \____\___/|_| |_| |_| .__/|_|_|\__,_|\__|_|\___/|_| |_|
972 constraints_code(Constraints,Rules,Clauses) :-
973 post_constraints(Constraints,1),
974 constraints_code1(1,Rules,L,[]),
975 clean_clauses(L,Clauses).
978 post_constraints([],MaxIndex1) :-
979 MaxIndex is MaxIndex1 - 1,
980 constraint_count(MaxIndex).
981 post_constraints([F/A|Cs],N) :-
984 post_constraints(Cs,M).
985 constraints_code1(I,Rules,L,T) :-
990 constraint_code(I,Rules,L,T1),
992 constraints_code1(J,Rules,T1,T)
995 %% Generate code for a single CHR constraint
996 constraint_code(I, Rules, L, T) :-
997 constraint(Constraint,I),
998 constraint_prelude(Constraint,Clause),
1001 rules_code(Rules,1,I,Id1,Id2,L1,L2),
1002 gen_cond_attach_clause(Constraint,Id2,L2,T).
1004 %% Generate prelude predicate for a constraint.
1005 %% f(...) :- f/a_0(...,Susp).
1006 constraint_prelude(F/A, Clause) :-
1007 vars_susp(A,Vars,Susp,VarsSusp),
1008 Head =.. [ F | Vars],
1009 build_head(F,A,[0],VarsSusp,Delegate),
1010 get_target_module(Mod),
1011 ( chr_pp_flag(debugable,on) ->
1014 'chr allocate_constraint'(Mod : Delegate, Susp, F, Vars),
1016 'chr debug_event'(call(Susp)),
1019 'chr debug_event'(fail(Susp)), !,
1023 'chr debug_event'(exit(Susp))
1025 'chr debug_event'(redo(Susp)),
1030 Clause = ( Head :- Delegate )
1033 gen_cond_attach_clause(F/A,Id,L,T) :-
1034 ( is_attached(F/A) ->
1036 gen_cond_attach_goal(F/A,Body,AllArgs,Args,Susp)
1037 ; vars_susp(A,Args,Susp,AllArgs),
1038 gen_uncond_attach_goal(F/A,Susp,Body,_)
1040 ( chr_pp_flag(debugable,on) ->
1041 Constraint =.. [F|Args],
1042 DebugEvent = 'chr debug_event'(insert(Constraint#Susp))
1046 build_head(F,A,Id,AllArgs,Head),
1047 Clause = ( Head :- DebugEvent,Body ),
1053 gen_cond_attach_goal(F/A,Goal,AllArgs,Args,Susp) :-
1054 vars_susp(A,Args,Susp,AllArgs),
1055 build_head(F,A,[0],AllArgs,Closure),
1056 atom_concat_list(['attach_',F, (/) ,A],AttachF),
1057 Attach =.. [AttachF,Vars,Susp],
1058 get_target_module(Mod),
1062 'chr insert_constraint_internal'(Vars,Susp,Mod:Closure,F,Args)
1064 'chr activate_constraint'(Vars,Susp,_)
1069 gen_uncond_attach_goal(F/A,Susp,AttachGoal,Generation) :-
1070 atom_concat_list(['attach_',F, (/) ,A],AttachF),
1071 Attach =.. [AttachF,Vars,Susp],
1074 'chr activate_constraint'(Vars, Susp, Generation),
1078 %% Generate all the code for a constraint based on all CHR rules
1079 rules_code([],_,_,Id,Id,L,L).
1080 rules_code([R |Rs],RuleNb,I,Id1,Id3,L,T) :-
1081 rule_code(R,RuleNb,I,Id1,Id2,L,T1),
1082 NextRuleNb is RuleNb + 1,
1083 rules_code(Rs,NextRuleNb,I,Id2,Id3,T1,T).
1085 %% Generate code for a constraint based on a single CHR rule
1086 rule_code(PragmaRule,RuleNb,I,Id1,Id2,L,T) :-
1087 PragmaRule = pragma(Rule,HeadIDs,_Pragmas,_Name),
1088 HeadIDs = ids(Head1IDs,Head2IDs),
1089 Rule = rule(Head1,Head2,_,_),
1090 heads1_code(Head1,[],Head1IDs,[],PragmaRule,I,Id1,L,L1),
1091 heads2_code(Head2,[],Head2IDs,[],PragmaRule,RuleNb,I,Id1,Id2,L1,T).
1093 %% Generate code based on all the removed heads of a CHR rule
1094 heads1_code([],_,_,_,_,_,_,L,L).
1095 heads1_code([Head|Heads],RestHeads,[HeadID|HeadIDs],RestIDs,PragmaRule,I,Id,L,T) :-
1096 PragmaRule = pragma(Rule,_,Pragmas,_Name),
1098 ( functor(Head,F,A),
1099 \+ check_unnecessary_active(Head,RestHeads,Rule),
1100 \+ memberchk_eq(passive(HeadID),Pragmas),
1101 all_attached(Heads),
1102 all_attached(RestHeads),
1103 Rule = rule(_,Heads2,_,_),
1104 all_attached(Heads2) ->
1105 append(Heads,RestHeads,OtherHeads),
1106 append(HeadIDs,RestIDs,OtherIDs),
1107 head1_code(Head,OtherHeads,OtherIDs,PragmaRule,F/A,I,Id,L,L1)
1111 heads1_code(Heads,[Head|RestHeads],HeadIDs,[HeadID|RestIDs],PragmaRule,I,Id,L1,T).
1113 %% Generate code based on one removed head of a CHR rule
1114 head1_code(Head,OtherHeads,OtherIDs,PragmaRule,FA,I,Id,L,T) :-
1115 PragmaRule = pragma(Rule,_,_,_Name),
1116 Rule = rule(_,Head2,_,_),
1118 reorder_heads(Head,OtherHeads,OtherIDs,NOtherHeads,NOtherIDs),
1119 simplification_code(Head,NOtherHeads,NOtherIDs,PragmaRule,FA,Id,L,T)
1121 simpagation_head1_code(Head,OtherHeads,OtherIDs,PragmaRule,FA,Id,L,T)
1124 %% Generate code based on all the persistent heads of a CHR rule
1125 heads2_code([],_,_,_,_,_,_,Id,Id,L,L).
1126 heads2_code([Head|Heads],RestHeads,[HeadID|HeadIDs],RestIDs,PragmaRule,RuleNb,I,Id1,Id3,L,T) :-
1127 PragmaRule = pragma(Rule,_,Pragmas,_Name),
1129 ( functor(Head,F,A),
1130 \+ check_unnecessary_active(Head,RestHeads,Rule),
1131 \+ memberchk_eq(passive(HeadID),Pragmas),
1132 \+ set_semantics_rule(PragmaRule),
1133 all_attached(Heads),
1134 all_attached(RestHeads),
1135 Rule = rule(Heads1,_,_,_),
1136 all_attached(Heads1) ->
1137 append(Heads,RestHeads,OtherHeads),
1138 append(HeadIDs,RestIDs,OtherIDs),
1139 length(Heads,RestHeadNb),
1140 head2_code(Head,OtherHeads,OtherIDs,PragmaRule,RuleNb,RestHeadNb,F/A,Id1,L,L0),
1142 gen_alloc_inc_clause(F/A,Id1,L0,L1)
1147 heads2_code(Heads,[Head|RestHeads],HeadIDs,[HeadID|RestIDs],PragmaRule,RuleNb,I,Id2,Id3,L1,T).
1149 %% Generate code based on one persistent head of a CHR rule
1150 head2_code(Head,OtherHeads,OtherIDs,PragmaRule,RuleNb,RestHeadNb,FA,Id,L,T) :-
1151 PragmaRule = pragma(Rule,_,_,_Name),
1152 Rule = rule(Head1,_,_,_),
1154 reorder_heads(Head,OtherHeads,NOtherHeads),
1155 propagation_code(Head,NOtherHeads,Rule,RuleNb,RestHeadNb,FA,Id,L,T)
1157 simpagation_head2_code(Head,OtherHeads,OtherIDs,PragmaRule,FA,Id,L,T)
1160 gen_alloc_inc_clause(F/A,Id,L,T) :-
1161 vars_susp(A,Vars,Susp,VarsSusp),
1162 build_head(F,A,Id,VarsSusp,Head),
1164 build_head(F,A,IncId,VarsSusp,CallHead),
1166 gen_cond_allocation(Vars,Susp,F/A,VarsSusp,ConditionalAlloc)
1168 ConditionalAlloc = true
1178 gen_cond_allocation(Vars,Susp,F/A,VarsSusp,ConstraintAllocationGoal) :-
1179 build_head(F,A,[0],VarsSusp,Term),
1180 get_target_module(Mod),
1181 ConstraintAllocationGoal =
1183 'chr allocate_constraint'(Mod : Term, Susp, F, Vars)
1188 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1191 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1193 guard_via_reschedule(Retrievals,GuardList,Prelude,Goal) :-
1194 ( chr_pp_flag(guard_via_reschedule,on) ->
1195 guard_via_reschedule_main(Retrievals,GuardList,Prelude,Goal)
1197 append(Retrievals,GuardList,GoalList),
1198 list2conj(GoalList,Goal)
1201 guard_via_reschedule_main(Retrievals,GuardList,Prelude,Goal) :-
1202 initialize_unit_dictionary(Prelude,Dict),
1203 build_units(Retrievals,GuardList,Dict,Units),
1204 dependency_reorder(Units,NUnits),
1205 units2goal(NUnits,Goal).
1207 units2goal([],true).
1208 units2goal([unit(_,Goal,_,_)|Units],(Goal,Goals)) :-
1209 units2goal(Units,Goals).
1211 dependency_reorder(Units,NUnits) :-
1212 dependency_reorder(Units,[],NUnits).
1214 dependency_reorder([],Acc,Result) :-
1215 reverse(Acc,Result).
1217 dependency_reorder([Unit|Units],Acc,Result) :-
1218 Unit = unit(_GID,_Goal,Type,GIDs),
1222 dependency_insert(Acc,Unit,GIDs,NAcc)
1224 dependency_reorder(Units,NAcc,Result).
1226 dependency_insert([],Unit,_,[Unit]).
1227 dependency_insert([X|Xs],Unit,GIDs,L) :-
1228 X = unit(GID,_,_,_),
1229 ( memberchk(GID,GIDs) ->
1233 dependency_insert(Xs,Unit,GIDs,T)
1236 build_units(Retrievals,Guard,InitialDict,Units) :-
1237 build_retrieval_units(Retrievals,1,N,InitialDict,Dict,Units,Tail),
1238 build_guard_units(Guard,N,Dict,Tail).
1240 build_retrieval_units([],N,N,Dict,Dict,L,L).
1241 build_retrieval_units([U|Us],N,M,Dict,NDict,L,T) :-
1242 term_variables(U,Vs),
1243 update_unit_dictionary(Vs,N,Dict,Dict1,[],GIDs),
1244 L = [unit(N,U,movable,GIDs)|L1],
1246 build_retrieval_units2(Us,N1,M,Dict1,NDict,L1,T).
1248 build_retrieval_units2([],N,N,Dict,Dict,L,L).
1249 build_retrieval_units2([U|Us],N,M,Dict,NDict,L,T) :-
1250 term_variables(U,Vs),
1251 update_unit_dictionary(Vs,N,Dict,Dict1,[],GIDs),
1252 L = [unit(N,U,fixed,GIDs)|L1],
1254 build_retrieval_units(Us,N1,M,Dict1,NDict,L1,T).
1256 initialize_unit_dictionary(Term,Dict) :-
1257 term_variables(Term,Vars),
1258 pair_all_with(Vars,0,Dict).
1260 update_unit_dictionary([],_,Dict,Dict,GIDs,GIDs).
1261 update_unit_dictionary([V|Vs],This,Dict,NDict,GIDs,NGIDs) :-
1262 ( lookup_eq(Dict,V,GID) ->
1263 ( (GID == This ; memberchk(GID,GIDs) ) ->
1270 Dict1 = [V - This|Dict],
1273 update_unit_dictionary(Vs,This,Dict1,NDict,GIDs1,NGIDs).
1275 build_guard_units(Guard,N,Dict,Units) :-
1277 Units = [unit(N,Goal,fixed,[])]
1278 ; Guard = [Goal|Goals] ->
1279 term_variables(Goal,Vs),
1280 update_unit_dictionary2(Vs,N,Dict,NDict,[],GIDs),
1281 Units = [unit(N,Goal,movable,GIDs)|RUnits],
1283 build_guard_units(Goals,N1,NDict,RUnits)
1286 update_unit_dictionary2([],_,Dict,Dict,GIDs,GIDs).
1287 update_unit_dictionary2([V|Vs],This,Dict,NDict,GIDs,NGIDs) :-
1288 ( lookup_eq(Dict,V,GID) ->
1289 ( (GID == This ; memberchk(GID,GIDs) ) ->
1294 Dict1 = [V - This|Dict]
1296 Dict1 = [V - This|Dict],
1299 update_unit_dictionary2(Vs,This,Dict1,NDict,GIDs1,NGIDs).
1301 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1303 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1305 %% / ___| ___| |_ / ___| ___ _ __ ___ __ _ _ __ | |_(_) ___ ___ _
1306 %% \___ \ / _ \ __| \___ \ / _ \ '_ ` _ \ / _` | '_ \| __| |/ __/ __(_)
1307 %% ___) | __/ |_ ___) | __/ | | | | | (_| | | | | |_| | (__\__ \_
1308 %% |____/ \___|\__| |____/ \___|_| |_| |_|\__,_|_| |_|\__|_|\___|___(_)
1311 %% | | | |_ __ (_) __ _ _ _ ___ |_ _|_ __ / _| ___ _ __ ___ _ __ ___ ___
1312 %% | | | | '_ \| |/ _` | | | |/ _ \ | || '_ \| |_ / _ \ '__/ _ \ '_ \ / __/ _ \
1313 %% | |_| | | | | | (_| | |_| | __/ | || | | | _| __/ | | __/ | | | (_| __/
1314 %% \___/|_| |_|_|\__, |\__,_|\___| |___|_| |_|_| \___|_| \___|_| |_|\___\___|
1316 unique_analyse_optimise(Rules,NRules) :-
1317 ( chr_pp_flag(unique_analyse_optimise,on) ->
1318 unique_analyse_optimise_main(Rules,1,[],NRules)
1323 unique_analyse_optimise_main([],_,_,[]).
1324 unique_analyse_optimise_main([PRule|PRules],N,PatternList,[NPRule|NPRules]) :-
1325 ( discover_unique_pattern(PRule,N,Pattern) ->
1326 NPatternList = [Pattern|PatternList]
1328 NPatternList = PatternList
1330 PRule = pragma(Rule,Ids,Pragmas,Name),
1331 Rule = rule(H1,H2,_,_),
1332 Ids = ids(Ids1,Ids2),
1333 apply_unique_patterns_to_constraints(H1,Ids1,NPatternList,MorePragmas1),
1334 apply_unique_patterns_to_constraints(H2,Ids2,NPatternList,MorePragmas2),
1335 append([MorePragmas1,MorePragmas2,Pragmas],NPragmas),
1336 NPRule = pragma(Rule,Ids,NPragmas,Name),
1338 unique_analyse_optimise_main(PRules,N1,NPatternList,NPRules).
1340 apply_unique_patterns_to_constraints([],_,_,[]).
1341 apply_unique_patterns_to_constraints([C|Cs],[Id|Ids],Patterns,Pragmas) :-
1342 ( member(Pattern,Patterns),
1343 apply_unique_pattern(C,Id,Pattern,Pragma) ->
1344 Pragmas = [Pragma | RPragmas]
1348 apply_unique_patterns_to_constraints(Cs,Ids,Patterns,RPragmas).
1350 apply_unique_pattern(Constraint,Id,Pattern,Pragma) :-
1351 Pattern = unique(PatternConstraint,PatternKey),
1352 subsumes(Constraint,PatternConstraint,Unifier),
1355 member(T,PatternKey),
1356 lookup_eq(Unifier,T,Term),
1357 term_variables(Term,Vs),
1365 Pragma = unique(Id,Vars).
1367 % subsumes(+Term1, +Term2, -Unifier)
1369 % If Term1 is a more general term than Term2 (e.g. has a larger
1370 % part instantiated), unify Unifier with a list Var-Value of
1371 % variables from Term2 and their corresponding values in Term1.
1373 subsumes(Term1,Term2,Unifier) :-
1375 subsumes_aux(Term1,Term2,S0,S),
1377 build_unifier(L,Unifier).
1379 subsumes_aux(Term1, Term2, S0, S) :-
1381 functor(Term2, F, N)
1382 -> compound(Term1), functor(Term1, F, N),
1383 subsumes_aux(N, Term1, Term2, S0, S)
1388 -> V == Term2, S = S0
1390 put_ds(Term1, S0, Term2, S)
1393 subsumes_aux(0, _, _, S, S) :- ! .
1394 subsumes_aux(N, T1, T2, S0, S) :-
1397 subsumes_aux(T1x, T2x, S0, S1),
1399 subsumes_aux(M, T1, T2, S1, S).
1401 build_unifier([],[]).
1402 build_unifier([X-V|R],[V - X | T]) :-
1405 discover_unique_pattern(PragmaRule,RuleNb,Pattern) :-
1406 PragmaRule = pragma(Rule,_,Pragmas,Name),
1407 ( Rule = rule([C1],[C2],Guard,Body) ->
1410 Rule = rule([C1,C2],[],Guard,Body)
1412 check_unique_constraints(C1,C2,Guard,Body,Pragmas,List),
1413 term_variables(C1,Vs),
1414 select_pragma_unique_variables(List,Vs,Key),
1415 Pattern0 = unique(C1,Key),
1416 copy_term_nat(Pattern0,Pattern),
1418 format('Found unique pattern ~w in rule ~d~@\n',
1419 [Pattern,RuleNb,(Name=yes(N) -> write(": "),write(N) ; true)])
1424 select_pragma_unique_variables([],_,[]).
1425 select_pragma_unique_variables([X-Y|R],Vs,L) :-
1430 \+ memberchk_eq(X,Vs)
1432 \+ memberchk_eq(Y,Vs)
1436 select_pragma_unique_variables(R,Vs,T).
1438 check_unique_constraints(C1,C2,G,_Body,Pragmas,List) :-
1439 \+ member(passive(_),Pragmas),
1440 variable_replacement(C1-C2,C2-C1,List),
1441 copy_with_variable_replacement(G,OtherG,List),
1443 once(entails(NotG,OtherG)).
1447 negate(X =< Y, Y < X).
1448 negate(X > Y, Y >= X).
1449 negate(X >= Y, Y > X).
1450 negate(X < Y, Y =< X).
1451 negate(var(X),nonvar(X)).
1452 negate(nonvar(X),var(X)).
1454 entails(X,X1) :- X1 == X.
1456 entails(X > Y, X1 >= Y1) :- X1 == X, Y1 == Y.
1457 entails(X < Y, X1 =< Y1) :- X1 == X, Y1 == Y.
1458 entails(ground(X),nonvar(X1)) :- X1 == X.
1459 entails(compound(X),nonvar(X1)) :- X1 == X.
1460 entails(atomic(X),nonvar(X1)) :- X1 == X.
1461 entails(number(X),nonvar(X1)) :- X1 == X.
1462 entails(atom(X),nonvar(X1)) :- X1 == X.
1464 check_unnecessary_active(Constraint,Previous,Rule) :-
1465 ( chr_pp_flag(check_unnecessary_active,full) ->
1466 check_unnecessary_active_main(Constraint,Previous,Rule)
1467 ; chr_pp_flag(check_unnecessary_active,simplification),
1468 Rule = rule(_,[],_,_) ->
1469 check_unnecessary_active_main(Constraint,Previous,Rule)
1474 check_unnecessary_active_main(Constraint,Previous,Rule) :-
1475 member(Other,Previous),
1476 variable_replacement(Other,Constraint,List),
1477 copy_with_variable_replacement(Rule,Rule2,List),
1478 identical_rules(Rule,Rule2), ! .
1480 set_semantics_rule(PragmaRule) :-
1481 ( chr_pp_flag(set_semantics_rule,on) ->
1482 set_semantics_rule_main(PragmaRule)
1487 set_semantics_rule_main(PragmaRule) :-
1488 PragmaRule = pragma(Rule,IDs,Pragmas,_),
1489 Rule = rule([C1],[C2],true,_),
1490 IDs = ids([ID1],[ID2]),
1491 once(member(unique(ID1,L1),Pragmas)),
1492 once(member(unique(ID2,L2),Pragmas)),
1494 \+ memberchk_eq(passive(ID1),Pragmas).
1495 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1497 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1499 %% | _ \ _ _| | ___ | ____|__ _ _ _(_)_ ____ _| | ___ _ __ ___ ___
1500 %% | |_) | | | | |/ _ \ | _| / _` | | | | \ \ / / _` | |/ _ \ '_ \ / __/ _ \
1501 %% | _ <| |_| | | __/ | |__| (_| | |_| | |\ V / (_| | | __/ | | | (_| __/
1502 %% |_| \_\\__,_|_|\___| |_____\__, |\__,_|_| \_/ \__,_|_|\___|_| |_|\___\___|
1504 % have to check for no duplicates in value list
1506 % check wether two rules are identical
1508 identical_rules(rule(H11,H21,G1,B1),rule(H12,H22,G2,B2)) :-
1510 identical_bodies(B1,B2),
1511 permutation(H11,P1),
1513 permutation(H21,P2),
1516 identical_bodies(B1,B2) :-
1528 % replace variables in list
1530 copy_with_variable_replacement(X,Y,L) :-
1532 ( lookup_eq(L,X,Y) ->
1540 copy_with_variable_replacement_l(XArgs,YArgs,L)
1543 copy_with_variable_replacement_l([],[],_).
1544 copy_with_variable_replacement_l([X|Xs],[Y|Ys],L) :-
1545 copy_with_variable_replacement(X,Y,L),
1546 copy_with_variable_replacement_l(Xs,Ys,L).
1548 %% build variable replacement list
1550 variable_replacement(X,Y,L) :-
1551 variable_replacement(X,Y,[],L).
1553 variable_replacement(X,Y,L1,L2) :-
1556 ( lookup_eq(L1,X,Z) ->
1564 variable_replacement_l(XArgs,YArgs,L1,L2)
1567 variable_replacement_l([],[],L,L).
1568 variable_replacement_l([X|Xs],[Y|Ys],L1,L3) :-
1569 variable_replacement(X,Y,L1,L2),
1570 variable_replacement_l(Xs,Ys,L2,L3).
1571 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1573 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1574 %% ____ _ _ _ __ _ _ _
1575 %% / ___|(_)_ __ ___ _ __ | (_)/ _(_) ___ __ _| |_(_) ___ _ __
1576 %% \___ \| | '_ ` _ \| '_ \| | | |_| |/ __/ _` | __| |/ _ \| '_ \
1577 %% ___) | | | | | | | |_) | | | _| | (_| (_| | |_| | (_) | | | |
1578 %% |____/|_|_| |_| |_| .__/|_|_|_| |_|\___\__,_|\__|_|\___/|_| |_|
1581 simplification_code(Head,RestHeads,RestIDs,PragmaRule,F/A,Id,L,T) :-
1582 PragmaRule = pragma(Rule,_,Pragmas,_),
1583 head_info(Head,A,_Vars,Susp,HeadVars,HeadPairs),
1584 build_head(F,A,Id,HeadVars,ClauseHead),
1585 head_arg_matches(HeadPairs,[],FirstMatching,VarDict1),
1587 ( RestHeads == [] ->
1592 rest_heads_retrieval_and_matching(RestHeads,RestIDs,Pragmas,Head,GetRestHeads,Susps,VarDict1,VarDict)
1595 guard_body_copies2(Rule,VarDict,GuardCopyList,BodyCopy),
1596 guard_via_reschedule(GetRestHeads,GuardCopyList,ClauseHead-FirstMatching,RescheduledTest),
1598 gen_uncond_susps_detachments(Susps,RestHeads,SuspsDetachments),
1599 gen_cond_susp_detachment(Susp,F/A,SuspDetachment),
1601 ( chr_pp_flag(debugable,on) ->
1602 Rule = rule(_,_,Guard,Body),
1603 my_term_copy(Guard - Body, VarDict, _, DebugGuard - DebugBody),
1604 DebugTry = 'chr debug_event'( try([Susp|RestSusps],[],DebugGuard,DebugBody)),
1605 DebugApply = 'chr debug_event'(apply([Susp|RestSusps],[],DebugGuard,DebugBody))
1611 Clause = ( ClauseHead :-
1623 head_arg_matches(Pairs,VarDict,Goal,NVarDict) :-
1624 head_arg_matches_(Pairs,VarDict,GoalList,NVarDict),
1625 list2conj(GoalList,Goal).
1627 head_arg_matches_([],VarDict,[],VarDict).
1628 head_arg_matches_([Arg-Var| Rest],VarDict,GoalList,NVarDict) :-
1630 ( lookup_eq(VarDict,Arg,OtherVar) ->
1631 GoalList = [Var == OtherVar | RestGoalList],
1633 ; VarDict1 = [Arg-Var | VarDict],
1634 GoalList = RestGoalList
1638 GoalList = [ Var == Arg | RestGoalList],
1643 functor(Term,Fct,N),
1645 GoalList =[ nonvar(Var), Var = Term | RestGoalList ],
1646 pairup(Args,Vars,NewPairs),
1647 append(NewPairs,Rest,Pairs),
1650 head_arg_matches_(Pairs,VarDict1,RestGoalList,NVarDict).
1652 rest_heads_retrieval_and_matching(Heads,IDs,Pragmas,ActiveHead,GoalList,Susps,VarDict,NVarDict):-
1653 rest_heads_retrieval_and_matching(Heads,IDs,Pragmas,ActiveHead,GoalList,Susps,VarDict,NVarDict,[],[],[]).
1655 rest_heads_retrieval_and_matching(Heads,IDs,Pragmas,ActiveHead,GoalList,Susps,VarDict,NVarDict,PrevHs,PrevSusps,AttrDict) :-
1657 rest_heads_retrieval_and_matching_n(Heads,IDs,Pragmas,PrevHs,PrevSusps,ActiveHead,GoalList,Susps,VarDict,NVarDict,AttrDict)
1664 rest_heads_retrieval_and_matching_n([],_,_,_,_,_,[],[],VarDict,VarDict,AttrDict) :-
1665 instantiate_pattern_goals(AttrDict).
1666 rest_heads_retrieval_and_matching_n([H|Hs],[ID|IDs],Pragmas,PrevHs,PrevSusps,ActiveHead,[ViaGoal,Goal|Goals],[Susp|Susps],VarDict,NVarDict,AttrDict) :-
1667 passive_head_via(H,[ActiveHead|PrevHs],AttrDict,VarDict,ViaGoal,Attr,NewAttrDict),
1669 head_info(H,Aty,Vars,_,_,Pairs),
1670 head_arg_matches(Pairs,VarDict,MatchingGoal,VarDict1),
1671 Suspension =.. [suspension,_,State,_,_,_,_|Vars],
1672 get_max_constraint_index(N),
1676 get_constraint_index(Fct/Aty,Pos),
1677 make_attr(N,_Mask,SuspsList,Attr),
1678 nth1(Pos,SuspsList,VarSusps)
1680 different_from_other_susps(H,Susp,PrevHs,PrevSusps,DiffSuspGoals),
1681 create_get_mutable_ref(active,State,GetMutable),
1684 'chr sbag_member'(Susp,VarSusps),
1690 ( member(unique(ID,UniqueKeus),Pragmas),
1691 check_unique_keys(UniqueKeus,VarDict) ->
1692 Goal = (Goal1 -> true)
1696 rest_heads_retrieval_and_matching_n(Hs,IDs,Pragmas,[H|PrevHs],[Susp|PrevSusps],ActiveHead,Goals,Susps,VarDict1,NVarDict,NewAttrDict).
1698 instantiate_pattern_goals([]).
1699 instantiate_pattern_goals([_-attr(Attr,Bits,Goal)|Rest]) :-
1700 get_max_constraint_index(N),
1704 make_attr(N,Mask,_,Attr),
1705 or_list(Bits,Pattern), !,
1706 Goal = (Mask /\ Pattern =:= Pattern)
1708 instantiate_pattern_goals(Rest).
1711 check_unique_keys([],_).
1712 check_unique_keys([V|Vs],Dict) :-
1713 lookup_eq(Dict,V,_),
1714 check_unique_keys(Vs,Dict).
1716 % Generates tests to ensure the found constraint differs from previously found constraints
1717 different_from_other_susps(Head,Susp,Heads,Susps,DiffSuspGoals) :-
1718 ( bagof(DiffSuspGoal, Pos ^ ( nth1(Pos,Heads,PreHead), \+ Head \= PreHead, nth1(Pos,Susps,PreSusp), DiffSuspGoal = (Susp \== PreSusp) ),DiffSuspGoalList) ->
1719 list2conj(DiffSuspGoalList,DiffSuspGoals)
1721 DiffSuspGoals = true
1724 passive_head_via(Head,PrevHeads,AttrDict,VarDict,Goal,Attr,NewAttrDict) :-
1726 get_constraint_index(F/A,Pos),
1727 common_variables(Head,PrevHeads,CommonVars),
1728 translate(CommonVars,VarDict,Vars),
1729 or_pattern(Pos,Bit),
1730 ( permutation(Vars,PermutedVars),
1731 lookup_eq(AttrDict,PermutedVars,attr(Attr,Positions,_)) ->
1732 member(Bit,Positions), !,
1733 NewAttrDict = AttrDict,
1736 Goal = (Goal1, PatternGoal),
1737 gen_get_mod_constraints(Vars,Goal1,Attr),
1738 NewAttrDict = [Vars - attr(Attr,[Bit|_],PatternGoal) | AttrDict]
1741 common_variables(T,Ts,Vs) :-
1742 term_variables(T,V1),
1743 term_variables(Ts,V2),
1744 intersect_eq(V1,V2,Vs).
1746 gen_get_mod_constraints(L,Goal,Susps) :-
1747 get_target_module(Mod),
1750 ( 'chr default_store'(Global),
1751 get_attr(Global,Mod,TSusps),
1756 VIA = 'chr via_1'(A,V)
1758 VIA = 'chr via_2'(A,B,V)
1759 ; VIA = 'chr via'(L,V)
1764 get_attr(V,Mod,TSusps),
1769 guard_body_copies(Rule,VarDict,GuardCopy,BodyCopy) :-
1770 guard_body_copies2(Rule,VarDict,GuardCopyList,BodyCopy),
1771 list2conj(GuardCopyList,GuardCopy).
1773 guard_body_copies2(Rule,VarDict,GuardCopyList,BodyCopy) :-
1774 Rule = rule(_,_,Guard,Body),
1775 conj2list(Guard,GuardList),
1776 split_off_simple_guard(GuardList,VarDict,GuardPrefix,RestGuardList),
1777 my_term_copy(GuardPrefix-RestGuardList,VarDict,VarDict2,GuardPrefixCopy-RestGuardListCopyCore),
1779 append(GuardPrefixCopy,[RestGuardCopy],GuardCopyList),
1780 term_variables(RestGuardList,GuardVars),
1781 term_variables(RestGuardListCopyCore,GuardCopyVars),
1782 ( chr_pp_flag(guard_locks,on),
1783 bagof(('chr lock'(Y)) - ('chr unlock'(Y)),
1784 X ^ (member(X,GuardVars), % X is a variable appearing in the original guard
1785 lookup_eq(VarDict,X,Y), % translate X into new variable
1786 memberchk_eq(Y,GuardCopyVars) % redundant check? or multiple entries for X possible?
1789 once(pairup(Locks,Unlocks,LocksUnlocks))
1794 list2conj(Locks,LockPhase),
1795 list2conj(Unlocks,UnlockPhase),
1796 list2conj(RestGuardListCopyCore,RestGuardCopyCore),
1797 RestGuardCopy = (LockPhase,(RestGuardCopyCore,UnlockPhase)),
1798 my_term_copy(Body,VarDict2,BodyCopy).
1801 split_off_simple_guard([],_,[],[]).
1802 split_off_simple_guard([G|Gs],VarDict,S,C) :-
1803 ( simple_guard(G,VarDict) ->
1805 split_off_simple_guard(Gs,VarDict,Ss,C)
1811 % simple guard: cheap and benign (does not bind variables)
1813 simple_guard(var(_), _).
1814 simple_guard(nonvar(_), _).
1815 simple_guard(ground(_), _).
1816 simple_guard(number(_), _).
1817 simple_guard(atom(_), _).
1818 simple_guard(integer(_), _).
1819 simple_guard(float(_), _).
1821 simple_guard(_ > _ , _).
1822 simple_guard(_ < _ , _).
1823 simple_guard(_ =< _, _).
1824 simple_guard(_ >= _, _).
1825 simple_guard(_ =:= _, _).
1826 simple_guard(_ == _, _).
1828 simple_guard(X is _, VarDict) :-
1829 \+ lookup_eq(VarDict,X,_).
1831 simple_guard((G1,G2),VarDict) :-
1832 simple_guard(G1,VarDict),
1833 simple_guard(G2,VarDict).
1835 simple_guard(\+ G, VarDict) :-
1836 simple_guard(G, VarDict).
1838 my_term_copy(X,Dict,Y) :-
1839 my_term_copy(X,Dict,_,Y).
1841 my_term_copy(X,Dict1,Dict2,Y) :-
1843 ( lookup_eq(Dict1,X,Y) ->
1845 ; Dict2 = [X-Y|Dict1]
1851 my_term_copy_list(XArgs,Dict1,Dict2,YArgs)
1854 my_term_copy_list([],Dict,Dict,[]).
1855 my_term_copy_list([X|Xs],Dict1,Dict3,[Y|Ys]) :-
1856 my_term_copy(X,Dict1,Dict2,Y),
1857 my_term_copy_list(Xs,Dict2,Dict3,Ys).
1859 gen_cond_susp_detachment(Susp,FA,SuspDetachment) :-
1860 ( is_attached(FA) ->
1861 gen_uncond_susp_detachment(Susp,FA,UnCondSuspDetachment),
1865 ; UnCondSuspDetachment
1868 SuspDetachment = true
1871 gen_uncond_susp_detachment(Susp,CFct/CAty,SuspDetachment) :-
1872 ( is_attached(CFct/CAty) ->
1873 atom_concat_list(['detach_',CFct, (/) ,CAty],Fct),
1874 Detach =.. [Fct,Vars,Susp],
1875 ( chr_pp_flag(debugable,on) ->
1876 DebugEvent = 'chr debug_event'(remove(Susp))
1883 'chr remove_constraint_internal'(Susp, Vars),
1887 SuspDetachment = true
1890 gen_uncond_susps_detachments([],[],true).
1891 gen_uncond_susps_detachments([Susp|Susps],[Term|Terms],(SuspDetachment,SuspsDetachments)) :-
1893 gen_uncond_susp_detachment(Susp,F/A,SuspDetachment),
1894 gen_uncond_susps_detachments(Susps,Terms,SuspsDetachments).
1896 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1898 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1900 %% / ___|(_)_ __ ___ _ __ __ _ __ _ __ _| |_(_) ___ _ __ / |
1901 %% \___ \| | '_ ` _ \| '_ \ / _` |/ _` |/ _` | __| |/ _ \| '_ \ | |
1902 %% ___) | | | | | | | |_) | (_| | (_| | (_| | |_| | (_) | | | | | |
1903 %% |____/|_|_| |_| |_| .__/ \__,_|\__, |\__,_|\__|_|\___/|_| |_| |_|
1906 simpagation_head1_code(Head,RestHeads,OtherIDs,PragmaRule,F/A,Id,L,T) :-
1907 PragmaRule = pragma(Rule,ids(_,Heads2IDs),Pragmas,_Name),
1908 Rule = rule(_Heads,Heads2,Guard,Body),
1910 head_info(Head,A,_Vars,Susp,HeadVars,HeadPairs),
1911 head_arg_matches(HeadPairs,[],FirstMatching,VarDict1),
1913 build_head(F,A,Id,HeadVars,ClauseHead),
1915 append(RestHeads,Heads2,Heads),
1916 append(OtherIDs,Heads2IDs,IDs),
1917 reorder_heads(Head,Heads,IDs,NHeads,NIDs),
1918 rest_heads_retrieval_and_matching(NHeads,NIDs,Pragmas,Head,GetRestHeads,Susps,VarDict1,VarDict),
1919 split_by_ids(NIDs,Susps,OtherIDs,Susps1,Susps2),
1921 guard_body_copies2(Rule,VarDict,GuardCopyList,BodyCopy),
1922 guard_via_reschedule(GetRestHeads,GuardCopyList,ClauseHead-FirstMatching,RescheduledTest),
1924 gen_uncond_susps_detachments(Susps1,RestHeads,SuspsDetachments),
1925 gen_cond_susp_detachment(Susp,F/A,SuspDetachment),
1927 ( chr_pp_flag(debugable,on) ->
1928 my_term_copy(Guard - Body, VarDict, _, DebugGuard - DebugBody),
1929 DebugTry = 'chr debug_event'( try([Susp|Susps1],Susps2,DebugGuard,DebugBody)),
1930 DebugApply = 'chr debug_event'(apply([Susp|Susps1],Susps2,DebugGuard,DebugBody))
1936 Clause = ( ClauseHead :-
1948 split_by_ids([],[],_,[],[]).
1949 split_by_ids([I|Is],[S|Ss],I1s,S1s,S2s) :-
1950 ( memberchk_eq(I,I1s) ->
1957 split_by_ids(Is,Ss,I1s,R1s,R2s).
1959 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1962 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1964 %% / ___|(_)_ __ ___ _ __ __ _ __ _ __ _| |_(_) ___ _ __ |___ \
1965 %% \___ \| | '_ ` _ \| '_ \ / _` |/ _` |/ _` | __| |/ _ \| '_ \ __) |
1966 %% ___) | | | | | | | |_) | (_| | (_| | (_| | |_| | (_) | | | | / __/
1967 %% |____/|_|_| |_| |_| .__/ \__,_|\__, |\__,_|\__|_|\___/|_| |_| |_____|
1970 %% Genereate prelude + worker predicate
1971 %% prelude calls worker
1972 %% worker iterates over one type of removed constraints
1973 simpagation_head2_code(Head2,RestHeads2,RestIDs,PragmaRule,FA,Id,L,T) :-
1974 PragmaRule = pragma(Rule,ids(IDs1,_),Pragmas,_Name),
1975 Rule = rule(Heads1,_,Guard,Body),
1976 reorder_heads(Head2,Heads1,IDs1,[Head1|RestHeads1],[ID1|RestIDs1]), % Heads1 = [Head1|RestHeads1],
1977 % IDs1 = [ID1|RestIDs1],
1978 simpagation_head2_prelude(Head2,Head1,[RestHeads2,Heads1,Guard,Body],FA,Id,L,L1),
1980 simpagation_head2_worker(Head2,Head1,ID1,RestHeads1,RestIDs1,RestHeads2,RestIDs,Rule,Pragmas,FA,Id2,L1,T).
1982 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1983 simpagation_head2_prelude(Head,Head1,Rest,F/A,Id1,L,T) :-
1984 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs),
1985 build_head(F,A,Id1,VarsSusp,ClauseHead),
1986 head_arg_matches(HeadPairs,[],FirstMatching,VarDict),
1988 passive_head_via(Head1,[Head],[],VarDict,ModConstraintsGoal,Attr,AttrDict),
1989 instantiate_pattern_goals(AttrDict),
1990 get_max_constraint_index(N),
1994 functor(Head1,F1,A1),
1995 get_constraint_index(F1/A1,Pos),
1996 make_attr(N,_,SuspsList,Attr),
1997 nth1(Pos,SuspsList,AllSusps)
2000 ( Id1 == [0] -> % create suspension
2001 gen_cond_allocation(Vars,Susp,F/A,VarsSusp,ConstraintAllocationGoal)
2002 ; ConstraintAllocationGoal = true
2005 extend_id(Id1,DelegateId),
2006 extra_active_delegate_variables(Head,Rest,VarDict,ExtraVars),
2007 append([AllSusps|VarsSusp],ExtraVars,DelegateCallVars),
2008 build_head(F,A,DelegateId,DelegateCallVars,Delegate),
2015 ConstraintAllocationGoal,
2018 L = [PreludeClause|T].
2020 extra_active_delegate_variables(Term,Terms,VarDict,Vars) :-
2022 delegate_variables(Term,Terms,VarDict,Args,Vars).
2024 passive_delegate_variables(Term,PrevTerms,NextTerms,VarDict,Vars) :-
2025 term_variables(PrevTerms,PrevVars),
2026 delegate_variables(Term,NextTerms,VarDict,PrevVars,Vars).
2028 delegate_variables(Term,Terms,VarDict,PrevVars,Vars) :-
2029 term_variables(Term,V1),
2030 term_variables(Terms,V2),
2031 intersect_eq(V1,V2,V3),
2032 list_difference_eq(V3,PrevVars,V4),
2033 translate(V4,VarDict,Vars).
2036 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2037 simpagation_head2_worker(Head2,Head1,ID1,RestHeads1,IDs1,RestHeads2,IDs2,Rule,Pragmas,FA,Id,L,T) :-
2038 Rule = rule(_,_,Guard,Body),
2039 simpagation_head2_worker_end(Head2,[Head1,RestHeads1,RestHeads2,Guard,Body],FA,Id,L,L1),
2040 simpagation_head2_worker_body(Head2,Head1,ID1,RestHeads1,IDs1,RestHeads2,IDs2,Rule,Pragmas,FA,Id,L1,T).
2042 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2043 simpagation_head2_worker_body(Head2,Head1,ID1,RestHeads1,IDs1,RestHeads2,IDs2,Rule,Pragmas,F/A,Id,L,T) :-
2045 gen_var(OtherSusps),
2047 head_info(Head2,A,_Vars,Susp,VarsSusp,Head2Pairs),
2048 head_arg_matches(Head2Pairs,[],_,VarDict1),
2050 Rule = rule(_,_,Guard,Body),
2051 extra_active_delegate_variables(Head2,[Head1,RestHeads1,RestHeads2,Guard,Body],VarDict1,ExtraVars),
2052 append([[OtherSusp|OtherSusps]|VarsSusp],ExtraVars,HeadVars),
2053 build_head(F,A,Id,HeadVars,ClauseHead),
2055 functor(Head1,_OtherF,OtherA),
2056 head_info(Head1,OtherA,OtherVars,_,_,Head1Pairs),
2057 head_arg_matches(Head1Pairs,VarDict1,FirstMatching,VarDict2),
2059 OtherSuspension =.. [suspension,_,OtherState,_,_,_,_|OtherVars],
2060 create_get_mutable_ref(active,OtherState,GetMutable),
2062 ( OtherSusp = OtherSuspension,
2066 ( (RestHeads1 \== [] ; RestHeads2 \== []) ->
2067 append(RestHeads1,RestHeads2,RestHeads),
2068 append(IDs1,IDs2,IDs),
2069 reorder_heads(Head1-Head2,RestHeads,IDs,NRestHeads,NIDs),
2070 rest_heads_retrieval_and_matching(NRestHeads,NIDs,Pragmas,[Head1,Head2],RestSuspsRetrieval,Susps,VarDict2,VarDict,[Head1],[OtherSusp],[]),
2071 split_by_ids(NIDs,Susps,IDs1,Susps1,Susps2)
2072 ; RestSuspsRetrieval = [],
2078 gen_uncond_susps_detachments([OtherSusp | Susps1],[Head1|RestHeads1],Susps1Detachments),
2080 append([OtherSusps|VarsSusp],ExtraVars,RecursiveVars),
2081 build_head(F,A,Id,RecursiveVars,RecursiveCall),
2082 append([[]|VarsSusp],ExtraVars,RecursiveVars2),
2083 build_head(F,A,Id,RecursiveVars2,RecursiveCall2),
2085 guard_body_copies2(Rule,VarDict,GuardCopyList,BodyCopy),
2086 guard_via_reschedule(RestSuspsRetrieval,GuardCopyList,v(ClauseHead,IteratorSuspTest,FirstMatching),RescheduledTest),
2087 ( BodyCopy \== true ->
2088 gen_uncond_attach_goal(F/A,Susp,Attachment,Generation),
2089 gen_state_cond_call(Susp,A,RecursiveCall,Generation,ConditionalRecursiveCall),
2090 gen_state_cond_call(Susp,A,RecursiveCall2,Generation,ConditionalRecursiveCall2)
2091 ; Attachment = true,
2092 ConditionalRecursiveCall = RecursiveCall,
2093 ConditionalRecursiveCall2 = RecursiveCall2
2096 ( chr_pp_flag(debugable,on) ->
2097 my_term_copy(Guard - Body, VarDict, _, DebugGuard - DebugBody),
2098 DebugTry = 'chr debug_event'( try([OtherSusp|Susps1],[Susp|Susps2],DebugGuard,DebugBody)),
2099 DebugApply = 'chr debug_event'(apply([OtherSusp|Susps1],[Susp|Susps2],DebugGuard,DebugBody))
2105 ( member(unique(ID1,UniqueKeys), Pragmas),
2106 check_unique_keys(UniqueKeys,VarDict1) ->
2117 ConditionalRecursiveCall2
2136 ConditionalRecursiveCall
2144 gen_state_cond_call(Susp,N,Call,Generation,ConditionalCall) :-
2146 Suspension =.. [suspension,_,State,_,NewGeneration,_,_|Args],
2147 create_get_mutable_ref(active,State,GetState),
2148 create_get_mutable_ref(Generation,NewGeneration,GetGeneration),
2150 ( Susp = Suspension,
2153 'chr update_mutable'(inactive,State),
2158 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2159 simpagation_head2_worker_end(Head,Rest,F/A,Id,L,T) :-
2160 head_info(Head,A,_Vars,_Susp,VarsSusp,Pairs),
2161 head_arg_matches(Pairs,[],_,VarDict),
2162 extra_active_delegate_variables(Head,Rest,VarDict,ExtraVars),
2163 append([[]|VarsSusp],ExtraVars,HeadVars),
2164 build_head(F,A,Id,HeadVars,ClauseHead),
2165 next_id(Id,ContinuationId),
2166 build_head(F,A,ContinuationId,VarsSusp,ContinuationHead),
2167 Clause = ( ClauseHead :- ContinuationHead ),
2170 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2173 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2175 %% | _ \ _ __ ___ _ __ __ _ __ _ __ _| |_(_) ___ _ __
2176 %% | |_) | '__/ _ \| '_ \ / _` |/ _` |/ _` | __| |/ _ \| '_ \
2177 %% | __/| | | (_) | |_) | (_| | (_| | (_| | |_| | (_) | | | |
2178 %% |_| |_| \___/| .__/ \__,_|\__, |\__,_|\__|_|\___/|_| |_|
2181 propagation_code(Head,RestHeads,Rule,RuleNb,RestHeadNb,FA,Id,L,T) :-
2182 ( RestHeads == [] ->
2183 propagation_single_headed(Head,Rule,RuleNb,FA,Id,L,T)
2185 propagation_multi_headed(Head,RestHeads,Rule,RuleNb,RestHeadNb,FA,Id,L,T)
2187 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2188 %% Single headed propagation
2189 %% everything in a single clause
2190 propagation_single_headed(Head,Rule,RuleNb,F/A,Id,L,T) :-
2191 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs),
2192 build_head(F,A,Id,VarsSusp,ClauseHead),
2195 build_head(F,A,NextId,VarsSusp,NextHead),
2197 NextCall = NextHead,
2199 head_arg_matches(HeadPairs,[],HeadMatching,VarDict),
2200 guard_body_copies(Rule,VarDict,GuardCopy,BodyCopy),
2202 gen_cond_allocation(Vars,Susp,F/A,VarsSusp,Allocation),
2203 Allocation1 = Allocation
2207 gen_uncond_attach_goal(F/A,Susp,Attachment,Generation),
2209 gen_state_cond_call(Susp,A,NextCall,Generation,ConditionalNextCall),
2211 ( chr_pp_flag(debugable,on) ->
2212 Rule = rule(_,_,Guard,Body),
2213 my_term_copy(Guard - Body, VarDict, _, DebugGuard - DebugBody),
2214 DebugTry = 'chr debug_event'( try([],[Susp],DebugGuard,DebugBody)),
2215 DebugApply = 'chr debug_event'(apply([],[Susp],DebugGuard,DebugBody))
2225 'chr novel_production'(Susp,RuleNb), % optimisation of t(RuleNb,Susp)
2230 'chr extend_history'(Susp,RuleNb),
2237 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2238 %% multi headed propagation
2239 %% prelude + predicates to accumulate the necessary combinations of suspended
2240 %% constraints + predicate to execute the body
2241 propagation_multi_headed(Head,RestHeads,Rule,RuleNb,RestHeadNb,FA,Id,L,T) :-
2242 RestHeads = [First|Rest],
2243 propagation_prelude(Head,RestHeads,Rule,FA,Id,L,L1),
2244 extend_id(Id,ExtendedId),
2245 propagation_nested_code(Rest,[First,Head],Rule,RuleNb,RestHeadNb,FA,ExtendedId,L1,T).
2247 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2248 propagation_prelude(Head,[First|Rest],Rule,F/A,Id,L,T) :-
2249 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs),
2250 build_head(F,A,Id,VarsSusp,PreludeHead),
2251 head_arg_matches(HeadPairs,[],FirstMatching,VarDict),
2252 Rule = rule(_,_,Guard,Body),
2253 extra_active_delegate_variables(Head,[First,Rest,Guard,Body],VarDict,ExtraVars),
2255 passive_head_via(First,[Head],[],VarDict,FirstSuspGoal,Attr,AttrDict),
2256 instantiate_pattern_goals(AttrDict),
2257 get_max_constraint_index(N),
2261 functor(First,FirstFct,FirstAty),
2262 make_attr(N,_Mask,SuspsList,Attr),
2263 get_constraint_index(FirstFct/FirstAty,Pos),
2264 nth1(Pos,SuspsList,Susps)
2268 gen_cond_allocation(Vars,Susp,F/A,VarsSusp,CondAllocation)
2269 ; CondAllocation = true
2272 extend_id(Id,NestedId),
2273 append([Susps|VarsSusp],ExtraVars,NestedVars),
2274 build_head(F,A,NestedId,NestedVars,NestedHead),
2275 NestedCall = NestedHead,
2287 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2288 propagation_nested_code([],[CurrentHead|PreHeads],Rule,RuleNb,RestHeadNb,FA,Id,L,T) :-
2289 propagation_end([CurrentHead|PreHeads],[],Rule,FA,Id,L,L1),
2290 propagation_body(CurrentHead,PreHeads,Rule,RuleNb,RestHeadNb,FA,Id,L1,T).
2292 propagation_nested_code([Head|RestHeads],PreHeads,Rule,RuleNb,RestHeadNb,FA,Id,L,T) :-
2293 propagation_end(PreHeads,[Head|RestHeads],Rule,FA,Id,L,L1),
2294 propagation_accumulator([Head|RestHeads],PreHeads,Rule,FA,Id,L1,L2),
2296 propagation_nested_code(RestHeads,[Head|PreHeads],Rule,RuleNb,RestHeadNb,FA,IncId,L2,T).
2298 propagation_body(CurrentHead,PreHeads,Rule,RuleNb,RestHeadNb,F/A,Id,L,T) :-
2299 Rule = rule(_,_,Guard,Body),
2300 get_prop_inner_loop_vars(PreHeads,[CurrentHead,Guard,Body],PreVarsAndSusps,VarDict1,Susp,RestSusps),
2302 gen_var(OtherSusps),
2303 functor(CurrentHead,_OtherF,OtherA),
2304 gen_vars(OtherA,OtherVars),
2305 Suspension =.. [suspension,_,State,_,_,_,_|OtherVars],
2306 create_get_mutable_ref(active,State,GetMutable),
2308 OtherSusp = Suspension,
2311 ClauseVars = [[OtherSusp|OtherSusps]|PreVarsAndSusps],
2312 build_head(F,A,Id,ClauseVars,ClauseHead),
2313 RecursiveVars = [OtherSusps|PreVarsAndSusps],
2314 build_head(F,A,Id,RecursiveVars,RecursiveHead),
2315 RecursiveCall = RecursiveHead,
2316 CurrentHead =.. [_|OtherArgs],
2317 pairup(OtherArgs,OtherVars,OtherPairs),
2318 head_arg_matches(OtherPairs,VarDict1,Matching,VarDict),
2320 different_from_other_susps(CurrentHead,OtherSusp,PreHeads,RestSusps,DiffSuspGoals),
2322 guard_body_copies(Rule,VarDict,GuardCopy,BodyCopy),
2323 gen_uncond_attach_goal(F/A,Susp,Attach,Generation),
2324 gen_state_cond_call(Susp,A,RecursiveCall,Generation,ConditionalRecursiveCall),
2326 history_susps(RestHeadNb,[OtherSusp|RestSusps],Susp,[],HistorySusps),
2327 bagof('chr novel_production'(X,Y),( member(X,HistorySusps), Y = TupleVar) ,NovelProductionsList),
2328 list2conj(NovelProductionsList,NovelProductions),
2329 Tuple =.. [t,RuleNb|HistorySusps],
2331 ( chr_pp_flag(debugable,on) ->
2332 Rule = rule(_,_,Guard,Body),
2333 my_term_copy(Guard - Body, VarDict, _, DebugGuard - DebugBody),
2334 DebugTry = 'chr debug_event'( try([],[Susp,OtherSusp|RestSusps],DebugGuard,DebugBody)),
2335 DebugApply = 'chr debug_event'(apply([],[Susp,OtherSusp|RestSusps],DebugGuard,DebugBody))
2351 'chr extend_history'(Susp,TupleVar),
2354 ConditionalRecursiveCall
2361 history_susps(Count,OtherSusps,Susp,Acc,HistorySusps) :-
2363 reverse(OtherSusps,ReversedSusps),
2364 append(ReversedSusps,[Susp|Acc],HistorySusps)
2366 OtherSusps = [OtherSusp|RestOtherSusps],
2367 NCount is Count - 1,
2368 history_susps(NCount,RestOtherSusps,Susp,[OtherSusp|Acc],HistorySusps)
2372 get_prop_inner_loop_vars([Head],Terms,HeadVars,VarDict,Susp,[]) :-
2375 head_info(Head,A,_Vars,Susp,VarsSusp,Pairs),
2376 head_arg_matches(Pairs,[],_,VarDict),
2377 extra_active_delegate_variables(Head,Terms,VarDict,ExtraVars),
2378 append(VarsSusp,ExtraVars,HeadVars).
2379 get_prop_inner_loop_vars([Head|Heads],Terms,VarsSusps,NVarDict,MainSusp,[Susp|RestSusps]) :-
2380 get_prop_inner_loop_vars(Heads,[Head|Terms],RestVarsSusp,VarDict,MainSusp,RestSusps),
2383 head_info(Head,A,_Vars,Susp,_VarsSusp,Pairs),
2384 head_arg_matches(Pairs,VarDict,_,NVarDict),
2385 passive_delegate_variables(Head,Heads,Terms,NVarDict,HeadVars),
2386 append(HeadVars,[Susp,Susps|RestVarsSusp],VarsSusps).
2388 propagation_end([CurrentHead|PrevHeads],NextHeads,Rule,F/A,Id,L,T) :-
2389 Rule = rule(_,_,Guard,Body),
2390 gen_var_susp_list_for(PrevHeads,[CurrentHead,NextHeads,Guard,Body],_,VarsAndSusps,AllButFirst,FirstSusp),
2392 Vars = [ [] | VarsAndSusps],
2394 build_head(F,A,Id,Vars,Head),
2398 PrevVarsAndSusps = AllButFirst
2401 PrevVarsAndSusps = [FirstSusp|AllButFirst]
2404 build_head(F,A,PrevId,PrevVarsAndSusps,PrevHead),
2405 PredecessorCall = PrevHead,
2413 gen_var_susp_list_for([Head],Terms,VarDict,HeadVars,VarsSusp,Susp) :-
2416 head_info(Head,A,_Vars,Susp,VarsSusp,HeadPairs),
2417 head_arg_matches(HeadPairs,[],_,VarDict),
2418 extra_active_delegate_variables(Head,Terms,VarDict,ExtraVars),
2419 append(VarsSusp,ExtraVars,HeadVars).
2420 gen_var_susp_list_for([Head|Heads],Terms,NVarDict,VarsSusps,Rest,Susps) :-
2421 gen_var_susp_list_for(Heads,[Head|Terms],VarDict,Rest,_,_),
2424 head_info(Head,A,_Vars,Susp,_VarsSusp,HeadPairs),
2425 head_arg_matches(HeadPairs,VarDict,_,NVarDict),
2426 passive_delegate_variables(Head,Heads,Terms,NVarDict,HeadVars),
2427 append(HeadVars,[Susp,Susps|Rest],VarsSusps).
2429 propagation_accumulator([NextHead|RestHeads],[CurrentHead|PreHeads],Rule,F/A,Id,L,T) :-
2430 Rule = rule(_,_,Guard,Body),
2431 pre_vars_and_susps(PreHeads,[CurrentHead,NextHead,RestHeads,Guard,Body],PreVarsAndSusps,VarDict,PreSusps),
2432 gen_var(OtherSusps),
2433 functor(CurrentHead,_OtherF,OtherA),
2434 gen_vars(OtherA,OtherVars),
2435 head_info(CurrentHead,OtherA,OtherVars,OtherSusp,_VarsSusp,HeadPairs),
2436 head_arg_matches(HeadPairs,VarDict,FirstMatching,VarDict1),
2438 OtherSuspension =.. [suspension,_,State,_,_,_,_|OtherVars],
2440 different_from_other_susps(CurrentHead,OtherSusp,PreHeads,PreSusps,DiffSuspGoals),
2441 create_get_mutable_ref(active,State,GetMutable),
2443 OtherSusp = OtherSuspension,
2448 functor(NextHead,NextF,NextA),
2449 passive_head_via(NextHead,[CurrentHead|PreHeads],[],VarDict1,NextSuspGoal,Attr,AttrDict),
2450 instantiate_pattern_goals(AttrDict),
2451 get_max_constraint_index(N),
2455 get_constraint_index(NextF/NextA,Position),
2456 make_attr(N,_Mask,SuspsList,Attr),
2457 nth1(Position,SuspsList,NextSusps)
2459 inc_id(Id,NestedId),
2460 ClauseVars = [[OtherSusp|OtherSusps]|PreVarsAndSusps],
2461 build_head(F,A,Id,ClauseVars,ClauseHead),
2462 passive_delegate_variables(CurrentHead,PreHeads,[NextHead,RestHeads,Guard,Body],VarDict1,CurrentHeadVars),
2463 append([NextSusps|CurrentHeadVars],[OtherSusp,OtherSusps|PreVarsAndSusps],NestedVars),
2464 build_head(F,A,NestedId,NestedVars,NestedHead),
2466 RecursiveVars = [OtherSusps|PreVarsAndSusps],
2467 build_head(F,A,Id,RecursiveVars,RecursiveHead),
2479 pre_vars_and_susps([Head],Terms,HeadVars,VarDict,[]) :-
2482 head_info(Head,A,_Vars,_Susp,VarsSusp,HeadPairs),
2483 head_arg_matches(HeadPairs,[],_,VarDict),
2484 extra_active_delegate_variables(Head,Terms,VarDict,ExtraVars),
2485 append(VarsSusp,ExtraVars,HeadVars).
2486 pre_vars_and_susps([Head|Heads],Terms,NVSs,NVarDict,[Susp|Susps]) :-
2487 pre_vars_and_susps(Heads,[Head|Terms],VSs,VarDict,Susps),
2490 head_info(Head,A,_Vars,Susp,_VarsSusp,HeadPairs),
2491 head_arg_matches(HeadPairs,VarDict,_,NVarDict),
2492 passive_delegate_variables(Head,Heads,Terms,NVarDict,HeadVars),
2493 append(HeadVars,[Susp,NextSusps|VSs],NVSs).
2495 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2497 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2499 %% | _ \ __ _ ___ ___(_)_ _____ | | | | ___ __ _ __| |
2500 %% | |_) / _` / __/ __| \ \ / / _ \ | |_| |/ _ \/ _` |/ _` |
2501 %% | __/ (_| \__ \__ \ |\ V / __/ | _ | __/ (_| | (_| |
2502 %% |_| \__,_|___/___/_| \_/ \___| |_| |_|\___|\__,_|\__,_|
2505 %% | _ \ ___| |_ _ __(_) _____ ____ _| |
2506 %% | |_) / _ \ __| '__| |/ _ \ \ / / _` | |
2507 %% | _ < __/ |_| | | | __/\ V / (_| | |
2508 %% |_| \_\___|\__|_| |_|\___| \_/ \__,_|_|
2511 %% | _ \ ___ ___ _ __ __| | ___ _ __(_)_ __ __ _
2512 %% | |_) / _ \/ _ \| '__/ _` |/ _ \ '__| | '_ \ / _` |
2513 %% | _ < __/ (_) | | | (_| | __/ | | | | | | (_| |
2514 %% |_| \_\___|\___/|_| \__,_|\___|_| |_|_| |_|\__, |
2517 reorder_heads(Head,RestHeads,RestIDs,NRestHeads,NRestIDs) :-
2518 ( chr_pp_flag(reorder_heads,on) ->
2519 reorder_heads_main(Head,RestHeads,RestIDs,NRestHeads,NRestIDs)
2521 NRestHeads = RestHeads,
2525 reorder_heads_main(Head,RestHeads,RestIDs,NRestHeads,NRestIDs) :-
2526 term_variables(Head,KnownVars),
2527 reorder_heads1(RestHeads,RestIDs,KnownVars,NRestHeads,NRestIDs).
2529 reorder_heads1(Heads,IDs,KnownVars,NHeads,NIDs) :-
2534 NHeads = [BestHead|BestTail],
2535 NIDs = [BestID | BestIDs],
2536 select_best_head(Heads,IDs,KnownVars,BestHead,BestID,RestHeads,RestIDs,NKnownVars),
2537 reorder_heads1(RestHeads,RestIDs,NKnownVars,BestTail,BestIDs)
2540 select_best_head(Heads,IDs,KnownVars,BestHead,BestID,RestHeads,RestIDs,NKnownVars) :-
2541 ( bagof(tuple(Score,Head,ID,Rest,RIDs), (
2542 select2(Head,ID, Heads,IDs,Rest,RIDs) ,
2543 order_score(Head,KnownVars,Rest,Score)
2545 Scores) -> true ; Scores = []),
2546 max_go_list(Scores,tuple(_,BestHead,BestID,RestHeads,RestIDs)),
2547 term_variables(BestHead,BestHeadVars),
2549 member(V,BestHeadVars),
2550 \+ memberchk_eq(V,KnownVars)
2552 NewVars) -> true ; NewVars = []),
2553 append(NewVars,KnownVars,NKnownVars).
2555 reorder_heads(Head,RestHeads,NRestHeads) :-
2556 term_variables(Head,KnownVars),
2557 reorder_heads1(RestHeads,KnownVars,NRestHeads).
2559 reorder_heads1(Heads,KnownVars,NHeads) :-
2563 NHeads = [BestHead|BestTail],
2564 select_best_head(Heads,KnownVars,BestHead,RestHeads,NKnownVars),
2565 reorder_heads1(RestHeads,NKnownVars,BestTail)
2568 select_best_head(Heads,KnownVars,BestHead,RestHeads,NKnownVars) :-
2569 ( bagof(tuple(Score,Head,Rest), (
2570 select(Head,Heads,Rest) ,
2571 order_score(Head,KnownVars,Rest,Score)
2573 Scores) -> true ; Scores = []),
2574 max_go_list(Scores,tuple(_,BestHead,RestHeads)),
2575 term_variables(BestHead,BestHeadVars),
2577 member(V,BestHeadVars),
2578 \+ memberchk_eq(V,KnownVars)
2580 NewVars) -> true ; NewVars = []),
2581 append(NewVars,KnownVars,NKnownVars).
2583 order_score(Head,KnownVars,Rest,Score) :-
2584 term_variables(Head,HeadVars),
2585 term_variables(Rest,RestVars),
2586 order_score_vars(HeadVars,KnownVars,RestVars,0,Score).
2588 order_score_vars([],_,_,Score,NScore) :-
2594 order_score_vars([V|Vs],KnownVars,RestVars,Score,NScore) :-
2595 ( memberchk_eq(V,KnownVars) ->
2597 ; memberchk_eq(V,RestVars) ->
2602 order_score_vars(Vs,KnownVars,RestVars,TScore,NScore).
2604 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2606 %% |_ _|_ __ | (_)_ __ (_)_ __ __ _
2607 %% | || '_ \| | | '_ \| | '_ \ / _` |
2608 %% | || | | | | | | | | | | | | (_| |
2609 %% |___|_| |_|_|_|_| |_|_|_| |_|\__, |
2613 create_get_mutable_ref(V,M,GM) :- GM = (M = mutable(V)).
2617 %% create_get_mutable_ref(V,M,GM) :- GM = get_mutable(V,M).
2620 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2622 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2624 %% / ___|___ __| | ___ / ___| | ___ __ _ _ __ (_)_ __ __ _
2625 %% | | / _ \ / _` |/ _ \ | | | |/ _ \/ _` | '_ \| | '_ \ / _` |
2626 %% | |__| (_) | (_| | __/ | |___| | __/ (_| | | | | | | | | (_| |
2627 %% \____\___/ \__,_|\___| \____|_|\___|\__,_|_| |_|_|_| |_|\__, |
2630 %% removes redundant 'true's and other trivial but potentially non-free constructs
2632 clean_clauses([],[]).
2633 clean_clauses([C|Cs],[NC|NCs]) :-
2635 clean_clauses(Cs,NCs).
2637 clean_clause(Clause,NClause) :-
2638 ( Clause = (Head :- Body) ->
2639 clean_goal(Body,NBody),
2643 NClause = (Head :- NBody)
2649 clean_goal(Goal,NGoal) :-
2652 clean_goal((G1,G2),NGoal) :-
2663 clean_goal((If -> Then ; Else),NGoal) :-
2667 clean_goal(Then,NThen),
2670 clean_goal(Else,NElse),
2673 clean_goal(Then,NThen),
2674 clean_goal(Else,NElse),
2675 NGoal = (NIf -> NThen; NElse)
2677 clean_goal((G1 ; G2),NGoal) :-
2688 clean_goal(once(G),NGoal) :-
2698 clean_goal((G1 -> G2),NGoal) :-
2702 clean_goal(G2,NGoal)
2707 NGoal = (NG1 -> NG2)
2709 clean_goal(Goal,Goal).
2710 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2712 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2714 %% | | | | |_(_) (_) |_ _ _
2715 %% | | | | __| | | | __| | | |
2716 %% | |_| | |_| | | | |_| |_| |
2717 %% \___/ \__|_|_|_|\__|\__, |
2724 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs) :-
2725 vars_susp(A,Vars,Susp,VarsSusp),
2727 pairup(Args,Vars,HeadPairs).
2729 inc_id([N|Ns],[O|Ns]) :-
2731 dec_id([N|Ns],[M|Ns]) :-
2734 extend_id(Id,[0|Id]).
2736 next_id([_,N|Ns],[O|Ns]) :-
2739 build_head(F,A,Id,Args,Head) :-
2740 buildName(F,A,Id,Name),
2741 Head =.. [Name|Args].
2743 buildName(Fct,Aty,List,Result) :-
2744 atom_concat(Fct, (/) ,FctSlash),
2745 atomic_concat(FctSlash,Aty,FctSlashAty),
2746 buildName_(List,FctSlashAty,Result).
2748 buildName_([],Name,Name).
2749 buildName_([N|Ns],Name,Result) :-
2750 buildName_(Ns,Name,Name1),
2751 atom_concat(Name1,'__',NameDash), % '_' is a char :-(
2752 atomic_concat(NameDash,N,Result).
2754 vars_susp(A,Vars,Susp,VarsSusp) :-
2756 append(Vars,[Susp],VarsSusp).
2758 make_attr(N,Mask,SuspsList,Attr) :-
2759 length(SuspsList,N),
2760 Attr =.. [v,Mask|SuspsList].
2762 or_pattern(Pos,Pat) :-
2764 Pat is 1 << Pow. % was 2 ** X
2766 and_pattern(Pos,Pat) :-
2768 Y is 1 << X, % was 2 ** X
2769 Pat is (-1)*(Y + 1). % because fx (-) is redefined
2771 conj2list(Conj,L) :- %% transform conjunctions to list
2772 conj2list(Conj,L,[]).
2774 conj2list(Conj,L,T) :-
2778 conj2list(G,[G | T],T).
2781 list2conj([G],X) :- !, X = G.
2782 list2conj([G|Gs],C) :-
2783 ( G == true -> %% remove some redundant trues
2790 atom_concat_list([X],X) :- ! .
2791 atom_concat_list([X|Xs],A) :-
2792 atom_concat_list(Xs,B),
2793 atomic_concat(X,B,A).
2795 atomic_concat(A,B,C) :-
2798 atom_concat(AA,BB,C).
2811 set_elems([X|Xs],X) :-
2814 member2([X|_],[Y|_],X-Y).
2815 member2([_|Xs],[_|Ys],P) :-
2818 select2(X, Y, [X|Xs], [Y|Ys], Xs, Ys).
2819 select2(X, Y, [X1|Xs], [Y1|Ys], [X1|NXs], [Y1|NYs]) :-
2820 select2(X, Y, Xs, Ys, NXs, NYs).
2822 pair_all_with([],_,[]).
2823 pair_all_with([X|Xs],Y,[X-Y|Rest]) :-
2824 pair_all_with(Xs,Y,Rest).
2826 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2829 verbosity_on :- prolog_flag(verbose,V), V == yes.
2833 %% verbosity_on. % at the moment