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
125 :- use_module(library(lists)).
126 :- use_module(hprolog).
127 :- use_module(library(assoc)).
128 :- use_module(pairlist).
129 :- use_module(library(ordsets)).
133 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
138 get_constraint_index/2,
139 max_constraint_index/1,
140 get_max_constraint_index/1,
147 constraint(FA,Number) \ constraint(FA,Query)
149 constraint(FA,Index) # ID \ constraint(Query,Index)
150 <=> Query = FA pragma passive(ID).
152 constraint_count(Index) # ID \ constraint_count(Query)
153 <=> Query = Index pragma passive(ID).
155 target_module(Mod) # ID \ get_target_module(Query)
158 get_target_module(Query)
161 constraint_index(C,Index) # ID \ get_constraint_index(C,Query)
164 get_constraint_index(C,Query)
167 max_constraint_index(Index) # ID \ get_max_constraint_index(Query)
170 get_max_constraint_index(Query)
173 attached(Constr,yes) \ attached(Constr,_) <=> true.
174 attached(Constr,no) \ attached(Constr,_) <=> true.
175 attached(Constr,maybe) \ attached(Constr,maybe) <=> true.
177 attached(Constr,Type) # ID \ is_attached(Constr)
185 is_attached(C) <=> true.
187 chr_clear \ constraint(_,_) # ID
188 <=> true pragma passive(ID).
189 chr_clear \ constraint_count(_) # ID
190 <=> true pragma passive(ID).
191 chr_clear \ constraint_index(_,_) # ID
192 <=> true pragma passive(ID).
193 chr_clear \ max_constraint_index(_) # ID
194 <=> true pragma passive(ID).
195 chr_clear \ target_module(_) # ID
196 <=> true pragma passive(ID).
197 chr_clear \ attached(_,_) # ID
198 <=> true pragma passive(ID).
201 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
203 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
207 chr_translate(Declarations,NewDeclarations) :-
209 partition_clauses(Declarations,Decls,Rules,OtherClauses),
211 NewDeclarations = OtherClauses
213 check_rules(Rules,Decls),
214 unique_analyse_optimise(Rules,NRules),
215 check_attachments(NRules),
216 set_constraint_indices(Decls,1),
217 store_management_preds(Decls,StoreClauses),
218 constraints_code(Decls,NRules,ConstraintClauses),
219 append_lists([OtherClauses,
227 store_management_preds(Constraints,Clauses) :-
228 generate_attach_detach_a_constraint_all(Constraints,AttachAConstraintClauses),
229 generate_attach_increment(AttachIncrementClauses),
230 generate_attr_unify_hook(AttrUnifyHookClauses),
231 append_lists([AttachAConstraintClauses
232 ,AttachIncrementClauses
233 ,AttrUnifyHookClauses]
237 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
239 %% Partitioning of clauses into constraint declarations, chr rules and other
242 partition_clauses([],[],[],[]).
243 partition_clauses([C|Cs],Ds,Rs,OCs) :-
248 ; is_declaration(C,D) ->
252 ; is_module_declaration(C,Mod) ->
258 format('CHR compiler WARNING: ~w.\n',[C]),
259 format(' `--> SICStus compatibility: ignoring handler/1 declaration.\n',[]),
264 format('CHR compiler WARNING: ~w.\n',[C]),
265 format(' `--> SICStus compatibility: ignoring rules/1 declaration.\n',[]),
269 ; C = (:- chr_option(OptionName,OptionValue)) ->
270 handle_option(OptionName,OptionValue),
278 partition_clauses(Cs,RDs,RRs,ROCs).
280 is_declaration(D, Constraints) :- %% constraint declaration
282 ( Decl =.. [chr_constraint,Cs] ; Decl =.. [chr_constraint,Cs]),
283 conj2list(Cs,Constraints).
301 %% list(constraint), :: constraints to be removed
302 %% list(constraint), :: surviving constraints
307 rule(RI,R) :- %% name @ rule
308 RI = (Name @ RI2), !,
309 rule(RI2,yes(Name),R).
314 RI = (RI2 pragma P), !, %% pragmas
317 R = pragma(R1,IDs,Ps,Name).
320 R = pragma(R1,IDs,[],Name).
322 is_rule(RI,R,IDs) :- %% propagation rule
325 get_ids(Head2i,IDs2,Head2),
328 R = rule([],Head2,G,RB)
330 R = rule([],Head2,true,B)
332 is_rule(RI,R,IDs) :- %% simplification/simpagation rule
341 conj2list(H1,Head2i),
342 conj2list(H2,Head1i),
343 get_ids(Head2i,IDs2,Head2,0,N),
344 get_ids(Head1i,IDs1,Head1,N,_),
346 ; conj2list(H,Head1i),
348 get_ids(Head1i,IDs1,Head1),
351 R = rule(Head1,Head2,Guard,Body).
353 get_ids(Cs,IDs,NCs) :-
354 get_ids(Cs,IDs,NCs,0,_).
356 get_ids([],[],[],N,N).
357 get_ids([C|Cs],[N|IDs],[NC|NCs],N,NN) :-
364 get_ids(Cs,IDs,NCs, M,NN).
366 is_module_declaration((:- module(Mod)),Mod).
367 is_module_declaration((:- module(Mod,_)),Mod).
369 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
371 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
372 %% Some input verification:
373 %% - all constraints in heads are declared constraints
375 check_rules(Rules,Decls) :-
376 check_rules(Rules,Decls,1).
379 check_rules([PragmaRule|Rest],Decls,N) :-
380 check_rule(PragmaRule,Decls,N),
382 check_rules(Rest,Decls,N1).
384 check_rule(PragmaRule,Decls,N) :-
385 PragmaRule = pragma(Rule,_IDs,Pragmas,_Name),
386 Rule = rule(H1,H2,_,_),
387 append(H1,H2,HeadConstraints),
388 check_head_constraints(HeadConstraints,Decls,PragmaRule,N),
389 check_pragmas(Pragmas,PragmaRule,N).
391 check_head_constraints([],_,_,_).
392 check_head_constraints([Constr|Rest],Decls,PragmaRule,N) :-
394 ( member(F/A,Decls) ->
395 check_head_constraints(Rest,Decls,PragmaRule,N)
397 format('CHR compiler ERROR: Undeclared constraint ~w in head of ~@.\n',
398 [F/A,format_rule(PragmaRule,N)]),
399 format(' `--> Constraint should be on of ~w.\n',[Decls]),
403 check_pragmas([],_,_).
404 check_pragmas([Pragma|Pragmas],PragmaRule,N) :-
405 check_pragma(Pragma,PragmaRule,N),
406 check_pragmas(Pragmas,PragmaRule,N).
408 check_pragma(Pragma,PragmaRule,N) :-
410 format('CHR compiler ERROR: invalid pragma ~w in ~@.\n',
411 [Pragma,format_rule(PragmaRule,N)]),
412 format(' `--> Pragma should not be a variable!\n',[]),
415 check_pragma(passive(ID), PragmaRule, N) :-
417 PragmaRule = pragma(_,ids(IDs1,IDs2),_,_),
418 ( memberchk_eq(ID,IDs1) ->
420 ; memberchk_eq(ID,IDs2) ->
423 format('CHR compiler ERROR: invalid identifier ~w in pragma passive in ~@.\n',
424 [ID,format_rule(PragmaRule,N)]),
428 check_pragma(Pragma, PragmaRule, N) :-
429 Pragma = unique(_,_),
431 format('CHR compiler WARNING: undocument pragma ~w in ~@.\n',[Pragma,format_rule(PragmaRule,N)]),
432 format(' `--> Only use this pragma if you know what you are doing.\n',[]).
434 check_pragma(Pragma, PragmaRule, N) :-
435 Pragma = already_in_heads,
437 format('CHR compiler WARNING: currently unsupported pragma ~w in ~@.\n',[Pragma,format_rule(PragmaRule,N)]),
438 format(' `--> Pragma is ignored. Termination and correctness may be affected \n',[]).
440 check_pragma(Pragma, PragmaRule, N) :-
441 Pragma = already_in_head(_),
443 format('CHR compiler WARNING: currently unsupported pragma ~w in ~@.\n',[Pragma,format_rule(PragmaRule,N)]),
444 format(' `--> Pragma is ignored. Termination and correctness may be affected \n',[]).
446 check_pragma(Pragma,PragmaRule,N) :-
447 format('CHR compiler ERROR: invalid pragma ~w in ~@.\n',[Pragma,format_rule(PragmaRule,N)]),
448 format(' `--> Pragma should be one of passive/1!\n',[]),
451 format_rule(PragmaRule,N) :-
452 PragmaRule = pragma(_,_,_,MaybeName),
453 ( MaybeName = yes(Name) ->
454 write('rule '), write(Name)
456 write('rule number '), write(N)
459 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
461 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
465 handle_option(Var,Value) :-
467 format('CHR compiler ERROR: ~w.\n',[option(Var,Value)]),
468 format(' `--> First argument should be an atom, not a variable.\n',[]),
471 handle_option(Name,Value) :-
473 format('CHR compiler ERROR: ~w.\n',[option(Name,Value)]),
474 format(' `--> Second argument should be a nonvariable.\n',[]),
477 handle_option(Name,Value) :-
478 option_definition(Name,Value,Flags),
480 set_chr_pp_flags(Flags).
482 handle_option(Name,Value) :-
483 \+ option_definition(Name,_,_), !.
485 handle_option(Name,Value) :-
486 findall(V,option_definition(Name,V,_),Vs),
487 format('CHR compiler ERROR: ~w.\n',[option(Name,Value)]),
488 format(' `--> Invalid value ~w: should be one of ~w.\n',[Value,Vs]),
491 option_definition(optimize,experimental,Flags) :-
492 Flags = [ unique_analyse_optimise - on,
493 check_unnecessary_active - full,
495 set_semantics_rule - on,
496 check_attachments - on,
497 guard_via_reschedule - on
499 option_definition(optimize,full,Flags) :-
500 Flags = [ unique_analyse_optimise - on,
501 check_unnecessary_active - full,
503 set_semantics_rule - on,
504 check_attachments - on,
505 guard_via_reschedule - on
508 option_definition(optimize,sicstus,Flags) :-
509 Flags = [ unique_analyse_optimise - off,
510 check_unnecessary_active - simplification,
512 set_semantics_rule - off,
513 check_attachments - off,
514 guard_via_reschedule - off
517 option_definition(optimize,off,Flags) :-
518 Flags = [ unique_analyse_optimise - off,
519 check_unnecessary_active - off,
521 set_semantics_rule - off,
522 check_attachments - off,
523 guard_via_reschedule - off
526 option_definition(debug,off,Flags) :-
527 Flags = [ debugable - off ].
528 option_definition(debug,on,Flags) :-
529 Flags = [ debugable - on ].
531 option_definition(check_guard_bindings,on,Flags) :-
532 Flags = [ guard_locks - on ].
534 option_definition(check_guard_bindings,off,Flags) :-
535 Flags = [ guard_locks - off ].
538 chr_pp_flag_definition(Name,[DefaultValue|_]),
539 set_chr_pp_flag(Name,DefaultValue),
543 set_chr_pp_flags([]).
544 set_chr_pp_flags([Name-Value|Flags]) :-
545 set_chr_pp_flag(Name,Value),
546 set_chr_pp_flags(Flags).
548 set_chr_pp_flag(Name,Value) :-
549 atomic_concat('$chr_pp_',Name,GlobalVar),
550 nb_setval(GlobalVar,Value).
552 chr_pp_flag_definition(unique_analyse_optimise,[on,off]).
553 chr_pp_flag_definition(check_unnecessary_active,[full,simplification,off]).
554 chr_pp_flag_definition(reorder_heads,[on,off]).
555 chr_pp_flag_definition(set_semantics_rule,[on,off]).
556 chr_pp_flag_definition(guard_via_reschedule,[on,off]).
557 chr_pp_flag_definition(guard_locks,[on,off]).
558 chr_pp_flag_definition(check_attachments,[on,off]).
559 chr_pp_flag_definition(debugable,[off,on]).
561 chr_pp_flag(Name,Value) :-
562 atomic_concat('$chr_pp_',Name,GlobalVar),
563 nb_getval(GlobalVar,V),
565 chr_pp_flag_definition(Name,[Value|_])
569 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
571 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
573 %% Generated predicates
574 %% attach_$CONSTRAINT
576 %% detach_$CONSTRAINT
579 %% attach_$CONSTRAINT
580 generate_attach_detach_a_constraint_all([],[]).
581 generate_attach_detach_a_constraint_all([Constraint|Constraints],Clauses) :-
582 ( is_attached(Constraint) ->
583 generate_attach_a_constraint(Constraint,Clauses1),
584 generate_detach_a_constraint(Constraint,Clauses2)
589 generate_attach_detach_a_constraint_all(Constraints,Clauses3),
590 append_lists([Clauses1,Clauses2,Clauses3],Clauses).
592 generate_attach_a_constraint(Constraint,[Clause1,Clause2]) :-
593 generate_attach_a_constraint_empty_list(Constraint,Clause1),
594 get_max_constraint_index(N),
596 generate_attach_a_constraint_1_1(Constraint,Clause2)
598 generate_attach_a_constraint_t_p(Constraint,Clause2)
601 generate_attach_a_constraint_empty_list(CFct / CAty,Clause) :-
602 atom_concat_list(['attach_',CFct, (/) ,CAty],Fct),
604 Head =.. [Fct | Args],
605 Clause = ( Head :- true).
607 generate_attach_a_constraint_1_1(CFct / CAty,Clause) :-
608 atom_concat_list(['attach_',CFct, (/) ,CAty],Fct),
609 Args = [[Var|Vars],Susp],
610 Head =.. [Fct | Args],
611 RecursiveCall =.. [Fct,Vars,Susp],
612 get_target_module(Mod),
615 ( get_attr(Var, Mod, Susps) ->
616 NewSusps=[Susp|Susps],
617 put_attr(Var, Mod, NewSusps)
619 put_attr(Var, Mod, [Susp])
623 Clause = (Head :- Body).
625 generate_attach_a_constraint_t_p(CFct / CAty,Clause) :-
626 atom_concat_list(['attach_',CFct, (/) ,CAty],Fct),
627 Args = [[Var|Vars],Susp],
628 Head =.. [Fct | Args],
629 RecursiveCall =.. [Fct,Vars,Susp],
630 get_constraint_index(CFct/CAty,Position),
631 or_pattern(Position,Pattern),
632 get_max_constraint_index(Total),
633 make_attr(Total,Mask,SuspsList,Attr),
634 nth(Position,SuspsList,Susps),
635 substitute(Susps,SuspsList,[Susp|Susps],SuspsList1),
636 make_attr(Total,Mask,SuspsList1,NewAttr1),
637 substitute(Susps,SuspsList,[Susp],SuspsList2),
638 make_attr(Total,NewMask,SuspsList2,NewAttr2),
639 copy_term(SuspsList,SuspsList3),
640 nth(Position,SuspsList3,[Susp]),
641 chr_delete(SuspsList3,[Susp],RestSuspsList),
642 set_elems(RestSuspsList,[]),
643 make_attr(Total,Pattern,SuspsList3,NewAttr3),
644 get_target_module(Mod),
647 ( get_attr(Var,Mod,TAttr) ->
649 ( Mask /\ Pattern =:= Pattern ->
650 put_attr(Var, Mod, NewAttr1)
652 NewMask is Mask \/ Pattern,
653 put_attr(Var, Mod, NewAttr2)
656 put_attr(Var,Mod,NewAttr3)
660 Clause = (Head :- Body).
662 %% detach_$CONSTRAINT
663 generate_detach_a_constraint(Constraint,[Clause1,Clause2]) :-
664 generate_detach_a_constraint_empty_list(Constraint,Clause1),
665 get_max_constraint_index(N),
667 generate_detach_a_constraint_1_1(Constraint,Clause2)
669 generate_detach_a_constraint_t_p(Constraint,Clause2)
672 generate_detach_a_constraint_empty_list(CFct / CAty,Clause) :-
673 atom_concat_list(['detach_',CFct, (/) ,CAty],Fct),
675 Head =.. [Fct | Args],
676 Clause = ( Head :- true).
678 generate_detach_a_constraint_1_1(CFct / CAty,Clause) :-
679 atom_concat_list(['detach_',CFct, (/) ,CAty],Fct),
680 Args = [[Var|Vars],Susp],
681 Head =.. [Fct | Args],
682 RecursiveCall =.. [Fct,Vars,Susp],
683 get_target_module(Mod),
686 ( get_attr(Var,Mod,Susps) ->
687 'chr sbag_del_element'(Susps,Susp,NewSusps),
691 put_attr(Var,Mod,NewSusps)
698 Clause = (Head :- Body).
700 generate_detach_a_constraint_t_p(CFct / CAty,Clause) :-
701 atom_concat_list(['detach_',CFct, (/) ,CAty],Fct),
702 Args = [[Var|Vars],Susp],
703 Head =.. [Fct | Args],
704 RecursiveCall =.. [Fct,Vars,Susp],
705 get_constraint_index(CFct/CAty,Position),
706 or_pattern(Position,Pattern),
707 and_pattern(Position,DelPattern),
708 get_max_constraint_index(Total),
709 make_attr(Total,Mask,SuspsList,Attr),
710 nth(Position,SuspsList,Susps),
711 substitute(Susps,SuspsList,[],SuspsList1),
712 make_attr(Total,NewMask,SuspsList1,Attr1),
713 substitute(Susps,SuspsList,NewSusps,SuspsList2),
714 make_attr(Total,Mask,SuspsList2,Attr2),
715 get_target_module(Mod),
718 ( get_attr(Var,Mod,TAttr) ->
720 ( Mask /\ Pattern =:= Pattern ->
721 'chr sbag_del_element'(Susps,Susp,NewSusps),
723 NewMask is Mask /\ DelPattern,
727 put_attr(Var,Mod,Attr1)
730 put_attr(Var,Mod,Attr2)
740 Clause = (Head :- Body).
742 %% detach_$CONSTRAINT
743 generate_attach_increment([Clause1,Clause2]) :-
744 generate_attach_increment_empty(Clause1),
745 get_max_constraint_index(N),
747 generate_attach_increment_one(Clause2)
749 generate_attach_increment_many(N,Clause2)
752 generate_attach_increment_empty((attach_increment([],_) :- true)).
754 generate_attach_increment_one(Clause) :-
755 Head = attach_increment([Var|Vars],Susps),
756 get_target_module(Mod),
759 'chr not_locked'(Var),
760 ( get_attr(Var,Mod,VarSusps) ->
761 sort(VarSusps,SortedVarSusps),
762 merge(Susps,SortedVarSusps,MergedSusps),
763 put_attr(Var,Mod,MergedSusps)
765 put_attr(Var,Mod,Susps)
767 attach_increment(Vars,Susps)
769 Clause = (Head :- Body).
771 generate_attach_increment_many(N,Clause) :-
772 make_attr(N,Mask,SuspsList,Attr),
773 make_attr(N,OtherMask,OtherSuspsList,OtherAttr),
774 Head = attach_increment([Var|Vars],Attr),
775 bagof(G,X ^ Y ^ SY ^ M ^ (member2(SuspsList,OtherSuspsList,X-Y),G = (sort(Y,SY),'chr merge_attributes'(X,SY,M))),Gs),
776 list2conj(Gs,SortGoals),
777 bagof(MS,A ^ B ^ C ^ member((A,'chr merge_attributes'(B,C,MS)),Gs), MergedSuspsList),
778 make_attr(N,MergedMask,MergedSuspsList,NewAttr),
779 get_target_module(Mod),
782 'chr not_locked'(Var),
783 ( get_attr(Var,Mod,TOtherAttr) ->
784 TOtherAttr = OtherAttr,
786 MergedMask is Mask \/ OtherMask,
787 put_attr(Var,Mod,NewAttr)
789 put_attr(Var,Mod,Attr)
791 attach_increment(Vars,Attr)
793 Clause = (Head :- Body).
796 generate_attr_unify_hook([Clause]) :-
797 get_max_constraint_index(N),
799 generate_attr_unify_hook_one(Clause)
801 generate_attr_unify_hook_many(N,Clause)
804 generate_attr_unify_hook_one(Clause) :-
805 Head = Mod:attr_unify_hook(Susps,Other),
806 get_target_module(Mod),
807 make_run_suspensions(NewSusps,WakeNewSusps),
808 make_run_suspensions(Susps,WakeSusps),
811 sort(Susps, SortedSusps),
813 ( get_attr(Other,Mod,OtherSusps) ->
818 sort(OtherSusps,SortedOtherSusps),
819 'chr merge_attributes'(SortedSusps,SortedOtherSusps,NewSusps),
820 put_attr(Other,Mod,NewSusps),
824 term_variables(Other,OtherVars),
825 attach_increment(OtherVars, SortedSusps)
832 Clause = (Head :- Body).
834 generate_attr_unify_hook_many(N,Clause) :-
835 make_attr(N,Mask,SuspsList,Attr),
836 make_attr(N,OtherMask,OtherSuspsList,OtherAttr),
837 bagof(Sort,A ^ B ^ ( member(A,SuspsList) , Sort = sort(A,B) ) , SortGoalList),
838 list2conj(SortGoalList,SortGoals),
839 bagof(B, A ^ member(sort(A,B),SortGoalList), SortedSuspsList),
840 bagof(C, D ^ E ^ F ^ G ^ (member2(SortedSuspsList,OtherSuspsList,D-E),
842 'chr merge_attributes'(D,F,G)) ),
844 bagof(G, D ^ F ^ H ^ member((H,'chr merge_attributes'(D,F,G)),SortMergeGoalList) , MergedSuspsList),
845 list2conj(SortMergeGoalList,SortMergeGoals),
846 make_attr(N,MergedMask,MergedSuspsList,MergedAttr),
847 make_attr(N,Mask,SortedSuspsList,SortedAttr),
848 Head = Mod:attr_unify_hook(Attr,Other),
849 get_target_module(Mod),
850 make_run_suspensions_loop(MergedSuspsList,WakeMergedSusps),
851 make_run_suspensions_loop(SortedSuspsList,WakeSortedSusps),
856 ( get_attr(Other,Mod,TOtherAttr) ->
857 TOtherAttr = OtherAttr,
859 MergedMask is Mask \/ OtherMask,
860 put_attr(Other,Mod,MergedAttr),
863 put_attr(Other,Mod,SortedAttr),
868 term_variables(Other,OtherVars),
869 attach_increment(OtherVars,SortedAttr)
876 Clause = (Head :- Body).
878 make_run_suspensions(Susps,Goal) :-
879 ( chr_pp_flag(debugable,on) ->
880 Goal = 'chr run_suspensions_d'(Susps)
882 Goal = 'chr run_suspensions'(Susps)
885 make_run_suspensions_loop(SuspsList,Goal) :-
886 ( chr_pp_flag(debugable,on) ->
887 Goal = 'chr run_suspensions_loop_d'(SuspsList)
889 Goal = 'chr run_suspensions_loop'(SuspsList)
892 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
894 check_attachments(Rules) :-
895 ( chr_pp_flag(check_attachments,on) ->
896 check_attachments_(Rules)
901 check_attachments_([]).
902 check_attachments_([R|Rs]) :-
904 check_attachments_(Rs).
906 check_attachment(R) :-
907 R = pragma(Rule,_,_,_),
908 Rule = rule(H1,H2,G,B),
909 check_attachment_heads1(H1,H1,H2,G),
910 check_attachment_heads2(H2,H1,B).
912 check_attachment_heads1([],_,_,_).
913 check_attachment_heads1([C|Cs],H1,H2,G) :-
924 check_attachment_heads1(Cs,H1,H2,G).
927 no_matching([X|Xs],Prev) :-
929 \+ memberchk_eq(X,Prev),
930 no_matching(Xs,[X|Prev]).
932 check_attachment_heads2([],_,_).
933 check_attachment_heads2([C|Cs],H1,B) :-
941 check_attachment_heads2(Cs,H1,B).
944 all_attached([C|Cs]) :-
949 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
951 set_constraint_indices([],M) :-
953 max_constraint_index(N).
954 set_constraint_indices([C|Cs],N) :-
956 constraint_index(C,N),
958 set_constraint_indices(Cs,M)
960 set_constraint_indices(Cs,N)
963 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
964 %% ____ _ ____ _ _ _ _
965 %% | _ \ _ _| | ___ / ___|___ _ __ ___ _ __ (_) | __ _| |_(_) ___ _ __
966 %% | |_) | | | | |/ _ \ | | / _ \| '_ ` _ \| '_ \| | |/ _` | __| |/ _ \| '_ \
967 %% | _ <| |_| | | __/ | |__| (_) | | | | | | |_) | | | (_| | |_| | (_) | | | |
968 %% |_| \_\\__,_|_|\___| \____\___/|_| |_| |_| .__/|_|_|\__,_|\__|_|\___/|_| |_|
971 constraints_code(Constraints,Rules,Clauses) :-
972 post_constraints(Constraints,1),
973 constraints_code1(1,Rules,L,[]),
974 clean_clauses(L,Clauses).
977 post_constraints([],MaxIndex1) :-
978 MaxIndex is MaxIndex1 - 1,
979 constraint_count(MaxIndex).
980 post_constraints([F/A|Cs],N) :-
983 post_constraints(Cs,M).
984 constraints_code1(I,Rules,L,T) :-
989 constraint_code(I,Rules,L,T1),
991 constraints_code1(J,Rules,T1,T)
994 %% Generate code for a single CHR constraint
995 constraint_code(I, Rules, L, T) :-
996 constraint(Constraint,I),
997 constraint_prelude(Constraint,Clause),
1000 rules_code(Rules,1,I,Id1,Id2,L1,L2),
1001 gen_cond_attach_clause(Constraint,Id2,L2,T).
1003 %% Generate prelude predicate for a constraint.
1004 %% f(...) :- f/a_0(...,Susp).
1005 constraint_prelude(F/A, Clause) :-
1006 vars_susp(A,Vars,Susp,VarsSusp),
1007 Head =.. [ F | Vars],
1008 build_head(F,A,[0],VarsSusp,Delegate),
1009 get_target_module(Mod),
1010 ( chr_pp_flag(debugable,on) ->
1013 'chr allocate_constraint'(Mod : Delegate, Susp, F, Vars),
1015 'chr debug_event'(call(Susp)),
1018 'chr debug_event'(fail(Susp)), !,
1022 'chr debug_event'(exit(Susp))
1024 'chr debug_event'(redo(Susp)),
1029 Clause = ( Head :- Delegate )
1032 gen_cond_attach_clause(F/A,Id,L,T) :-
1033 ( is_attached(F/A) ->
1035 gen_cond_attach_goal(F/A,Body,AllArgs,Args,Susp)
1036 ; vars_susp(A,Args,Susp,AllArgs),
1037 gen_uncond_attach_goal(F/A,Susp,Body,_)
1039 ( chr_pp_flag(debugable,on) ->
1040 Constraint =.. [F|Args],
1041 DebugEvent = 'chr debug_event'(insert(Constraint#Susp))
1045 build_head(F,A,Id,AllArgs,Head),
1046 Clause = ( Head :- DebugEvent,Body ),
1052 gen_cond_attach_goal(F/A,Goal,AllArgs,Args,Susp) :-
1053 vars_susp(A,Args,Susp,AllArgs),
1054 build_head(F,A,[0],AllArgs,Closure),
1055 atom_concat_list(['attach_',F, (/) ,A],AttachF),
1056 Attach =.. [AttachF,Vars,Susp],
1057 get_target_module(Mod),
1061 'chr insert_constraint_internal'(Vars,Susp,Mod:Closure,F,Args)
1063 'chr activate_constraint'(Vars,Susp,_)
1068 gen_uncond_attach_goal(F/A,Susp,AttachGoal,Generation) :-
1069 atom_concat_list(['attach_',F, (/) ,A],AttachF),
1070 Attach =.. [AttachF,Vars,Susp],
1073 'chr activate_constraint'(Vars, Susp, Generation),
1077 %% Generate all the code for a constraint based on all CHR rules
1078 rules_code([],_,_,Id,Id,L,L).
1079 rules_code([R |Rs],RuleNb,I,Id1,Id3,L,T) :-
1080 rule_code(R,RuleNb,I,Id1,Id2,L,T1),
1081 NextRuleNb is RuleNb + 1,
1082 rules_code(Rs,NextRuleNb,I,Id2,Id3,T1,T).
1084 %% Generate code for a constraint based on a single CHR rule
1085 rule_code(PragmaRule,RuleNb,I,Id1,Id2,L,T) :-
1086 PragmaRule = pragma(Rule,HeadIDs,_Pragmas,_Name),
1087 HeadIDs = ids(Head1IDs,Head2IDs),
1088 Rule = rule(Head1,Head2,_,_),
1089 heads1_code(Head1,[],Head1IDs,[],PragmaRule,I,Id1,L,L1),
1090 heads2_code(Head2,[],Head2IDs,[],PragmaRule,RuleNb,I,Id1,Id2,L1,T).
1092 %% Generate code based on all the removed heads of a CHR rule
1093 heads1_code([],_,_,_,_,_,_,L,L).
1094 heads1_code([Head|Heads],RestHeads,[HeadID|HeadIDs],RestIDs,PragmaRule,I,Id,L,T) :-
1095 PragmaRule = pragma(Rule,_,Pragmas,_Name),
1097 ( functor(Head,F,A),
1098 \+ check_unnecessary_active(Head,RestHeads,Rule),
1099 \+ memberchk_eq(passive(HeadID),Pragmas),
1100 all_attached(Heads),
1101 all_attached(RestHeads),
1102 Rule = rule(_,Heads2,_,_),
1103 all_attached(Heads2) ->
1104 append(Heads,RestHeads,OtherHeads),
1105 append(HeadIDs,RestIDs,OtherIDs),
1106 head1_code(Head,OtherHeads,OtherIDs,PragmaRule,F/A,I,Id,L,L1)
1110 heads1_code(Heads,[Head|RestHeads],HeadIDs,[HeadID|RestIDs],PragmaRule,I,Id,L1,T).
1112 %% Generate code based on one removed head of a CHR rule
1113 head1_code(Head,OtherHeads,OtherIDs,PragmaRule,FA,I,Id,L,T) :-
1114 PragmaRule = pragma(Rule,_,_,_Name),
1115 Rule = rule(_,Head2,_,_),
1117 reorder_heads(Head,OtherHeads,OtherIDs,NOtherHeads,NOtherIDs),
1118 simplification_code(Head,NOtherHeads,NOtherIDs,PragmaRule,FA,Id,L,T)
1120 simpagation_head1_code(Head,OtherHeads,OtherIDs,PragmaRule,FA,Id,L,T)
1123 %% Generate code based on all the persistent heads of a CHR rule
1124 heads2_code([],_,_,_,_,_,_,Id,Id,L,L).
1125 heads2_code([Head|Heads],RestHeads,[HeadID|HeadIDs],RestIDs,PragmaRule,RuleNb,I,Id1,Id3,L,T) :-
1126 PragmaRule = pragma(Rule,_,Pragmas,_Name),
1128 ( functor(Head,F,A),
1129 \+ check_unnecessary_active(Head,RestHeads,Rule),
1130 \+ memberchk_eq(passive(HeadID),Pragmas),
1131 \+ set_semantics_rule(PragmaRule),
1132 all_attached(Heads),
1133 all_attached(RestHeads),
1134 Rule = rule(Heads1,_,_,_),
1135 all_attached(Heads1) ->
1136 append(Heads,RestHeads,OtherHeads),
1137 append(HeadIDs,RestIDs,OtherIDs),
1138 length(Heads,RestHeadNb),
1139 head2_code(Head,OtherHeads,OtherIDs,PragmaRule,RuleNb,RestHeadNb,F/A,Id1,L,L0),
1141 gen_alloc_inc_clause(F/A,Id1,L0,L1)
1146 heads2_code(Heads,[Head|RestHeads],HeadIDs,[HeadID|RestIDs],PragmaRule,RuleNb,I,Id2,Id3,L1,T).
1148 %% Generate code based on one persistent head of a CHR rule
1149 head2_code(Head,OtherHeads,OtherIDs,PragmaRule,RuleNb,RestHeadNb,FA,Id,L,T) :-
1150 PragmaRule = pragma(Rule,_,_,_Name),
1151 Rule = rule(Head1,_,_,_),
1153 reorder_heads(Head,OtherHeads,NOtherHeads),
1154 propagation_code(Head,NOtherHeads,Rule,RuleNb,RestHeadNb,FA,Id,L,T)
1156 simpagation_head2_code(Head,OtherHeads,OtherIDs,PragmaRule,FA,Id,L,T)
1159 gen_alloc_inc_clause(F/A,Id,L,T) :-
1160 vars_susp(A,Vars,Susp,VarsSusp),
1161 build_head(F,A,Id,VarsSusp,Head),
1163 build_head(F,A,IncId,VarsSusp,CallHead),
1165 gen_cond_allocation(Vars,Susp,F/A,VarsSusp,ConditionalAlloc)
1167 ConditionalAlloc = true
1177 gen_cond_allocation(Vars,Susp,F/A,VarsSusp,ConstraintAllocationGoal) :-
1178 build_head(F,A,[0],VarsSusp,Term),
1179 get_target_module(Mod),
1180 ConstraintAllocationGoal =
1182 'chr allocate_constraint'(Mod : Term, Susp, F, Vars)
1187 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1190 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1192 guard_via_reschedule(Retrievals,GuardList,Prelude,Goal) :-
1193 ( chr_pp_flag(guard_via_reschedule,on) ->
1194 guard_via_reschedule_main(Retrievals,GuardList,Prelude,Goal)
1196 append(Retrievals,GuardList,GoalList),
1197 list2conj(GoalList,Goal)
1200 guard_via_reschedule_main(Retrievals,GuardList,Prelude,Goal) :-
1201 initialize_unit_dictionary(Prelude,Dict),
1202 build_units(Retrievals,GuardList,Dict,Units),
1203 dependency_reorder(Units,NUnits),
1204 units2goal(NUnits,Goal).
1206 units2goal([],true).
1207 units2goal([unit(_,Goal,_,_)|Units],(Goal,Goals)) :-
1208 units2goal(Units,Goals).
1210 dependency_reorder(Units,NUnits) :-
1211 dependency_reorder(Units,[],NUnits).
1213 dependency_reorder([],Acc,Result) :-
1214 reverse(Acc,Result).
1216 dependency_reorder([Unit|Units],Acc,Result) :-
1217 Unit = unit(_GID,_Goal,Type,GIDs),
1221 dependency_insert(Acc,Unit,GIDs,NAcc)
1223 dependency_reorder(Units,NAcc,Result).
1225 dependency_insert([],Unit,_,[Unit]).
1226 dependency_insert([X|Xs],Unit,GIDs,L) :-
1227 X = unit(GID,_,_,_),
1228 ( memberchk(GID,GIDs) ->
1232 dependency_insert(Xs,Unit,GIDs,T)
1235 build_units(Retrievals,Guard,InitialDict,Units) :-
1236 build_retrieval_units(Retrievals,1,N,InitialDict,Dict,Units,Tail),
1237 build_guard_units(Guard,N,Dict,Tail).
1239 build_retrieval_units([],N,N,Dict,Dict,L,L).
1240 build_retrieval_units([U|Us],N,M,Dict,NDict,L,T) :-
1241 term_variables(U,Vs),
1242 update_unit_dictionary(Vs,N,Dict,Dict1,[],GIDs),
1243 L = [unit(N,U,movable,GIDs)|L1],
1245 build_retrieval_units2(Us,N1,M,Dict1,NDict,L1,T).
1247 build_retrieval_units2([],N,N,Dict,Dict,L,L).
1248 build_retrieval_units2([U|Us],N,M,Dict,NDict,L,T) :-
1249 term_variables(U,Vs),
1250 update_unit_dictionary(Vs,N,Dict,Dict1,[],GIDs),
1251 L = [unit(N,U,fixed,GIDs)|L1],
1253 build_retrieval_units(Us,N1,M,Dict1,NDict,L1,T).
1255 initialize_unit_dictionary(Term,Dict) :-
1256 term_variables(Term,Vars),
1257 pair_all_with(Vars,0,Dict).
1259 update_unit_dictionary([],_,Dict,Dict,GIDs,GIDs).
1260 update_unit_dictionary([V|Vs],This,Dict,NDict,GIDs,NGIDs) :-
1261 ( lookup_eq(Dict,V,GID) ->
1262 ( (GID == This ; memberchk(GID,GIDs) ) ->
1269 Dict1 = [V - This|Dict],
1272 update_unit_dictionary(Vs,This,Dict1,NDict,GIDs1,NGIDs).
1274 build_guard_units(Guard,N,Dict,Units) :-
1276 Units = [unit(N,Goal,fixed,[])]
1277 ; Guard = [Goal|Goals] ->
1278 term_variables(Goal,Vs),
1279 update_unit_dictionary2(Vs,N,Dict,NDict,[],GIDs),
1280 Units = [unit(N,Goal,movable,GIDs)|RUnits],
1282 build_guard_units(Goals,N1,NDict,RUnits)
1285 update_unit_dictionary2([],_,Dict,Dict,GIDs,GIDs).
1286 update_unit_dictionary2([V|Vs],This,Dict,NDict,GIDs,NGIDs) :-
1287 ( lookup_eq(Dict,V,GID) ->
1288 ( (GID == This ; memberchk(GID,GIDs) ) ->
1293 Dict1 = [V - This|Dict]
1295 Dict1 = [V - This|Dict],
1298 update_unit_dictionary2(Vs,This,Dict1,NDict,GIDs1,NGIDs).
1300 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1302 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1304 %% / ___| ___| |_ / ___| ___ _ __ ___ __ _ _ __ | |_(_) ___ ___ _
1305 %% \___ \ / _ \ __| \___ \ / _ \ '_ ` _ \ / _` | '_ \| __| |/ __/ __(_)
1306 %% ___) | __/ |_ ___) | __/ | | | | | (_| | | | | |_| | (__\__ \_
1307 %% |____/ \___|\__| |____/ \___|_| |_| |_|\__,_|_| |_|\__|_|\___|___(_)
1310 %% | | | |_ __ (_) __ _ _ _ ___ |_ _|_ __ / _| ___ _ __ ___ _ __ ___ ___
1311 %% | | | | '_ \| |/ _` | | | |/ _ \ | || '_ \| |_ / _ \ '__/ _ \ '_ \ / __/ _ \
1312 %% | |_| | | | | | (_| | |_| | __/ | || | | | _| __/ | | __/ | | | (_| __/
1313 %% \___/|_| |_|_|\__, |\__,_|\___| |___|_| |_|_| \___|_| \___|_| |_|\___\___|
1315 unique_analyse_optimise(Rules,NRules) :-
1316 ( chr_pp_flag(unique_analyse_optimise,on) ->
1317 unique_analyse_optimise_main(Rules,1,[],NRules)
1322 unique_analyse_optimise_main([],_,_,[]).
1323 unique_analyse_optimise_main([PRule|PRules],N,PatternList,[NPRule|NPRules]) :-
1324 ( discover_unique_pattern(PRule,N,Pattern) ->
1325 NPatternList = [Pattern|PatternList]
1327 NPatternList = PatternList
1329 PRule = pragma(Rule,Ids,Pragmas,Name),
1330 Rule = rule(H1,H2,_,_),
1331 Ids = ids(Ids1,Ids2),
1332 apply_unique_patterns_to_constraints(H1,Ids1,NPatternList,MorePragmas1),
1333 apply_unique_patterns_to_constraints(H2,Ids2,NPatternList,MorePragmas2),
1334 append_lists([MorePragmas1,MorePragmas2,Pragmas],NPragmas),
1335 NPRule = pragma(Rule,Ids,NPragmas,Name),
1337 unique_analyse_optimise_main(PRules,N1,NPatternList,NPRules).
1339 apply_unique_patterns_to_constraints([],_,_,[]).
1340 apply_unique_patterns_to_constraints([C|Cs],[Id|Ids],Patterns,Pragmas) :-
1341 ( member(Pattern,Patterns),
1342 apply_unique_pattern(C,Id,Pattern,Pragma) ->
1343 Pragmas = [Pragma | RPragmas]
1347 apply_unique_patterns_to_constraints(Cs,Ids,Patterns,RPragmas).
1349 apply_unique_pattern(Constraint,Id,Pattern,Pragma) :-
1350 Pattern = unique(PatternConstraint,PatternKey),
1351 subsumes(Constraint,PatternConstraint,Unifier),
1354 member(T,PatternKey),
1355 lookup_eq(Unifier,T,Term),
1356 term_variables(Term,Vs),
1364 Pragma = unique(Id,Vars).
1366 % subsumes(+Term1, +Term2, -Unifier)
1368 % If Term1 is a more general term than Term2 (e.g. has a larger
1369 % part instantiated), unify Unifier with a list Var-Value of
1370 % variables from Term2 and their corresponding values in Term1.
1372 subsumes(Term1,Term2,Unifier) :-
1374 subsumes_aux(Term1,Term2,S0,S),
1376 build_unifier(L,Unifier).
1378 subsumes_aux(Term1, Term2, S0, S) :-
1380 functor(Term2, F, N)
1381 -> compound(Term1), functor(Term1, F, N),
1382 subsumes_aux(N, Term1, Term2, S0, S)
1386 get_assoc(Term1,S0,V)
1387 -> V == Term2, S = S0
1389 put_assoc(Term1, S0, Term2, S)
1392 subsumes_aux(0, _, _, S, S) :- ! .
1393 subsumes_aux(N, T1, T2, S0, S) :-
1396 subsumes_aux(T1x, T2x, S0, S1),
1398 subsumes_aux(M, T1, T2, S1, S).
1400 build_unifier([],[]).
1401 build_unifier([X-V|R],[V - X | T]) :-
1404 discover_unique_pattern(PragmaRule,RuleNb,Pattern) :-
1405 PragmaRule = pragma(Rule,_,Pragmas,Name),
1406 ( Rule = rule([C1],[C2],Guard,Body) ->
1409 Rule = rule([C1,C2],[],Guard,Body)
1411 check_unique_constraints(C1,C2,Guard,Body,Pragmas,List),
1412 term_variables(C1,Vs),
1413 select_pragma_unique_variables(List,Vs,Key),
1414 Pattern0 = unique(C1,Key),
1415 copy_term(Pattern0,Pattern),
1417 format('Found unique pattern ~w in rule ~d~@\n',
1418 [Pattern,RuleNb,(Name=yes(N) -> write(": "),write(N) ; true)])
1423 select_pragma_unique_variables([],_,[]).
1424 select_pragma_unique_variables([X-Y|R],Vs,L) :-
1429 \+ memberchk_eq(X,Vs)
1431 \+ memberchk_eq(Y,Vs)
1435 select_pragma_unique_variables(R,Vs,T).
1437 check_unique_constraints(C1,C2,G,_Body,Pragmas,List) :-
1438 \+ member(passive(_),Pragmas),
1439 variable_replacement(C1-C2,C2-C1,List),
1440 copy_with_variable_replacement(G,OtherG,List),
1442 once(entails(NotG,OtherG)).
1446 negate(X =< Y, Y < X).
1447 negate(X > Y, Y >= X).
1448 negate(X >= Y, Y > X).
1449 negate(X < Y, Y =< X).
1450 negate(var(X),nonvar(X)).
1451 negate(nonvar(X),var(X)).
1453 entails(X,X1) :- X1 == X.
1455 entails(X > Y, X1 >= Y1) :- X1 == X, Y1 == Y.
1456 entails(X < Y, X1 =< Y1) :- X1 == X, Y1 == Y.
1457 entails(ground(X),nonvar(X1)) :- X1 == X.
1458 entails(compound(X),nonvar(X1)) :- X1 == X.
1459 entails(atomic(X),nonvar(X1)) :- X1 == X.
1460 entails(number(X),nonvar(X1)) :- X1 == X.
1461 entails(atom(X),nonvar(X1)) :- X1 == X.
1463 check_unnecessary_active(Constraint,Previous,Rule) :-
1464 ( chr_pp_flag(check_unnecessary_active,full) ->
1465 check_unnecessary_active_main(Constraint,Previous,Rule)
1466 ; chr_pp_flag(check_unnecessary_active,simplification),
1467 Rule = rule(_,[],_,_) ->
1468 check_unnecessary_active_main(Constraint,Previous,Rule)
1473 check_unnecessary_active_main(Constraint,Previous,Rule) :-
1474 member(Other,Previous),
1475 variable_replacement(Other,Constraint,List),
1476 copy_with_variable_replacement(Rule,Rule2,List),
1477 identical_rules(Rule,Rule2), ! .
1479 set_semantics_rule(PragmaRule) :-
1480 ( chr_pp_flag(set_semantics_rule,on) ->
1481 set_semantics_rule_main(PragmaRule)
1486 set_semantics_rule_main(PragmaRule) :-
1487 PragmaRule = pragma(Rule,IDs,Pragmas,_),
1488 Rule = rule([C1],[C2],true,_),
1489 IDs = ids([ID1],[ID2]),
1490 once(member(unique(ID1,L1),Pragmas)),
1491 once(member(unique(ID2,L2),Pragmas)),
1493 \+ memberchk_eq(passive(ID1),Pragmas).
1494 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1496 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1498 %% | _ \ _ _| | ___ | ____|__ _ _ _(_)_ ____ _| | ___ _ __ ___ ___
1499 %% | |_) | | | | |/ _ \ | _| / _` | | | | \ \ / / _` | |/ _ \ '_ \ / __/ _ \
1500 %% | _ <| |_| | | __/ | |__| (_| | |_| | |\ V / (_| | | __/ | | | (_| __/
1501 %% |_| \_\\__,_|_|\___| |_____\__, |\__,_|_| \_/ \__,_|_|\___|_| |_|\___\___|
1503 % have to check for no duplicates in value list
1505 % check wether two rules are identical
1507 identical_rules(rule(H11,H21,G1,B1),rule(H12,H22,G2,B2)) :-
1509 identical_bodies(B1,B2),
1510 permutation(H11,P1),
1512 permutation(H21,P2),
1515 identical_bodies(B1,B2) :-
1527 % replace variables in list
1529 copy_with_variable_replacement(X,Y,L) :-
1531 ( lookup_eq(L,X,Y) ->
1539 copy_with_variable_replacement_l(XArgs,YArgs,L)
1542 copy_with_variable_replacement_l([],[],_).
1543 copy_with_variable_replacement_l([X|Xs],[Y|Ys],L) :-
1544 copy_with_variable_replacement(X,Y,L),
1545 copy_with_variable_replacement_l(Xs,Ys,L).
1547 %% build variable replacement list
1549 variable_replacement(X,Y,L) :-
1550 variable_replacement(X,Y,[],L).
1552 variable_replacement(X,Y,L1,L2) :-
1555 ( lookup_eq(L1,X,Z) ->
1563 variable_replacement_l(XArgs,YArgs,L1,L2)
1566 variable_replacement_l([],[],L,L).
1567 variable_replacement_l([X|Xs],[Y|Ys],L1,L3) :-
1568 variable_replacement(X,Y,L1,L2),
1569 variable_replacement_l(Xs,Ys,L2,L3).
1570 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1572 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1573 %% ____ _ _ _ __ _ _ _
1574 %% / ___|(_)_ __ ___ _ __ | (_)/ _(_) ___ __ _| |_(_) ___ _ __
1575 %% \___ \| | '_ ` _ \| '_ \| | | |_| |/ __/ _` | __| |/ _ \| '_ \
1576 %% ___) | | | | | | | |_) | | | _| | (_| (_| | |_| | (_) | | | |
1577 %% |____/|_|_| |_| |_| .__/|_|_|_| |_|\___\__,_|\__|_|\___/|_| |_|
1580 simplification_code(Head,RestHeads,RestIDs,PragmaRule,F/A,Id,L,T) :-
1581 PragmaRule = pragma(Rule,_,Pragmas,_),
1582 head_info(Head,A,_Vars,Susp,HeadVars,HeadPairs),
1583 build_head(F,A,Id,HeadVars,ClauseHead),
1584 head_arg_matches(HeadPairs,[],FirstMatching,VarDict1),
1586 ( RestHeads == [] ->
1591 rest_heads_retrieval_and_matching(RestHeads,RestIDs,Pragmas,Head,GetRestHeads,Susps,VarDict1,VarDict)
1594 guard_body_copies2(Rule,VarDict,GuardCopyList,BodyCopy),
1595 guard_via_reschedule(GetRestHeads,GuardCopyList,ClauseHead-FirstMatching,RescheduledTest),
1597 gen_uncond_susps_detachments(Susps,RestHeads,SuspsDetachments),
1598 gen_cond_susp_detachment(Susp,F/A,SuspDetachment),
1600 ( chr_pp_flag(debugable,on) ->
1601 Rule = rule(_,_,Guard,Body),
1602 my_term_copy(Guard - Body, VarDict, _, DebugGuard - DebugBody),
1603 DebugTry = 'chr debug_event'( try([Susp|RestSusps],[],DebugGuard,DebugBody)),
1604 DebugApply = 'chr debug_event'(apply([Susp|RestSusps],[],DebugGuard,DebugBody))
1610 Clause = ( ClauseHead :-
1622 head_arg_matches(Pairs,VarDict,Goal,NVarDict) :-
1623 head_arg_matches_(Pairs,VarDict,GoalList,NVarDict),
1624 list2conj(GoalList,Goal).
1626 head_arg_matches_([],VarDict,[],VarDict).
1627 head_arg_matches_([Arg-Var| Rest],VarDict,GoalList,NVarDict) :-
1629 ( lookup_eq(VarDict,Arg,OtherVar) ->
1630 GoalList = [Var == OtherVar | RestGoalList],
1632 ; VarDict1 = [Arg-Var | VarDict],
1633 GoalList = RestGoalList
1637 GoalList = [ Var == Arg | RestGoalList],
1642 functor(Term,Fct,N),
1644 GoalList =[ nonvar(Var), Var = Term | RestGoalList ],
1645 pairup(Args,Vars,NewPairs),
1646 append(NewPairs,Rest,Pairs),
1649 head_arg_matches_(Pairs,VarDict1,RestGoalList,NVarDict).
1651 rest_heads_retrieval_and_matching(Heads,IDs,Pragmas,ActiveHead,GoalList,Susps,VarDict,NVarDict):-
1652 rest_heads_retrieval_and_matching(Heads,IDs,Pragmas,ActiveHead,GoalList,Susps,VarDict,NVarDict,[],[],[]).
1654 rest_heads_retrieval_and_matching(Heads,IDs,Pragmas,ActiveHead,GoalList,Susps,VarDict,NVarDict,PrevHs,PrevSusps,AttrDict) :-
1656 rest_heads_retrieval_and_matching_n(Heads,IDs,Pragmas,PrevHs,PrevSusps,ActiveHead,GoalList,Susps,VarDict,NVarDict,AttrDict)
1663 rest_heads_retrieval_and_matching_n([],_,_,_,_,_,[],[],VarDict,VarDict,AttrDict) :-
1664 instantiate_pattern_goals(AttrDict).
1665 rest_heads_retrieval_and_matching_n([H|Hs],[ID|IDs],Pragmas,PrevHs,PrevSusps,ActiveHead,[ViaGoal,Goal|Goals],[Susp|Susps],VarDict,NVarDict,AttrDict) :-
1666 passive_head_via(H,[ActiveHead|PrevHs],AttrDict,VarDict,ViaGoal,Attr,NewAttrDict),
1668 head_info(H,Aty,Vars,_,_,Pairs),
1669 head_arg_matches(Pairs,VarDict,MatchingGoal,VarDict1),
1670 Suspension =.. [suspension,_,State,_,_,_,_|Vars],
1671 get_max_constraint_index(N),
1675 get_constraint_index(Fct/Aty,Pos),
1676 make_attr(N,_Mask,SuspsList,Attr),
1677 nth(Pos,SuspsList,VarSusps)
1679 different_from_other_susps(H,Susp,PrevHs,PrevSusps,DiffSuspGoals),
1680 create_get_mutable_ref(active,State,GetMutable),
1683 'chr sbag_member'(Susp,VarSusps),
1689 ( member(unique(ID,UniqueKeus),Pragmas),
1690 check_unique_keys(UniqueKeus,VarDict) ->
1691 Goal = (Goal1 -> true)
1695 rest_heads_retrieval_and_matching_n(Hs,IDs,Pragmas,[H|PrevHs],[Susp|PrevSusps],ActiveHead,Goals,Susps,VarDict1,NVarDict,NewAttrDict).
1697 instantiate_pattern_goals([]).
1698 instantiate_pattern_goals([_-attr(Attr,Bits,Goal)|Rest]) :-
1699 get_max_constraint_index(N),
1703 make_attr(N,Mask,_,Attr),
1704 or_list(Bits,Pattern), !,
1705 Goal = (Mask /\ Pattern =:= Pattern)
1707 instantiate_pattern_goals(Rest).
1710 check_unique_keys([],_).
1711 check_unique_keys([V|Vs],Dict) :-
1712 lookup_eq(Dict,V,_),
1713 check_unique_keys(Vs,Dict).
1715 % Generates tests to ensure the found constraint differs from previously found constraints
1716 different_from_other_susps(Head,Susp,Heads,Susps,DiffSuspGoals) :-
1717 ( bagof(DiffSuspGoal, Pos ^ ( nth(Pos,Heads,PreHead), \+ Head \= PreHead, nth(Pos,Susps,PreSusp), DiffSuspGoal = (Susp \== PreSusp) ),DiffSuspGoalList) ->
1718 list2conj(DiffSuspGoalList,DiffSuspGoals)
1720 DiffSuspGoals = true
1723 passive_head_via(Head,PrevHeads,AttrDict,VarDict,Goal,Attr,NewAttrDict) :-
1725 get_constraint_index(F/A,Pos),
1726 common_variables(Head,PrevHeads,CommonVars),
1727 translate(CommonVars,VarDict,Vars),
1728 or_pattern(Pos,Bit),
1729 ( permutation(Vars,PermutedVars),
1730 lookup_eq(AttrDict,PermutedVars,attr(Attr,Positions,_)) ->
1731 member(Bit,Positions), !,
1732 NewAttrDict = AttrDict,
1735 Goal = (Goal1, PatternGoal),
1736 gen_get_mod_constraints(Vars,Goal1,Attr),
1737 NewAttrDict = [Vars - attr(Attr,[Bit|_],PatternGoal) | AttrDict]
1740 common_variables(T,Ts,Vs) :-
1741 term_variables(T,V1),
1742 term_variables(Ts,V2),
1743 intersect_eq(V1,V2,Vs).
1745 gen_get_mod_constraints(L,Goal,Susps) :-
1746 get_target_module(Mod),
1749 ( 'chr default_store'(Global),
1750 get_attr(Global,Mod,TSusps),
1755 VIA = 'chr via_1'(A,V)
1757 VIA = 'chr via_2'(A,B,V)
1758 ; VIA = 'chr via'(L,V)
1763 get_attr(V,Mod,TSusps),
1768 guard_body_copies(Rule,VarDict,GuardCopy,BodyCopy) :-
1769 guard_body_copies2(Rule,VarDict,GuardCopyList,BodyCopy),
1770 list2conj(GuardCopyList,GuardCopy).
1772 guard_body_copies2(Rule,VarDict,GuardCopyList,BodyCopy) :-
1773 Rule = rule(_,_,Guard,Body),
1774 conj2list(Guard,GuardList),
1775 split_off_simple_guard(GuardList,VarDict,GuardPrefix,RestGuardList),
1776 my_term_copy(GuardPrefix-RestGuardList,VarDict,VarDict2,GuardPrefixCopy-RestGuardListCopyCore),
1778 append(GuardPrefixCopy,[RestGuardCopy],GuardCopyList),
1779 term_variables(RestGuardList,GuardVars),
1780 term_variables(RestGuardListCopyCore,GuardCopyVars),
1781 ( chr_pp_flag(guard_locks,on),
1782 bagof(('chr lock'(Y)) - ('chr unlock'(Y)),
1783 X ^ (member(X,GuardVars), % X is a variable appearing in the original guard
1784 lookup_eq(VarDict,X,Y), % translate X into new variable
1785 memberchk_eq(Y,GuardCopyVars) % redundant check? or multiple entries for X possible?
1788 once(pairup(Locks,Unlocks,LocksUnlocks))
1793 list2conj(Locks,LockPhase),
1794 list2conj(Unlocks,UnlockPhase),
1795 list2conj(RestGuardListCopyCore,RestGuardCopyCore),
1796 RestGuardCopy = (LockPhase,(RestGuardCopyCore,UnlockPhase)),
1797 my_term_copy(Body,VarDict2,BodyCopy).
1800 split_off_simple_guard([],_,[],[]).
1801 split_off_simple_guard([G|Gs],VarDict,S,C) :-
1802 ( simple_guard(G,VarDict) ->
1804 split_off_simple_guard(Gs,VarDict,Ss,C)
1810 % simple guard: cheap and benign (does not bind variables)
1812 simple_guard(var(_), _).
1813 simple_guard(nonvar(_), _).
1814 simple_guard(ground(_), _).
1815 simple_guard(number(_), _).
1816 simple_guard(atom(_), _).
1817 simple_guard(integer(_), _).
1818 simple_guard(float(_), _).
1820 simple_guard(_ > _ , _).
1821 simple_guard(_ < _ , _).
1822 simple_guard(_ =< _, _).
1823 simple_guard(_ >= _, _).
1824 simple_guard(_ =:= _, _).
1825 simple_guard(_ == _, _).
1827 simple_guard(X is _, VarDict) :-
1828 \+ lookup_eq(VarDict,X,_).
1830 simple_guard((G1,G2),VarDict) :-
1831 simple_guard(G1,VarDict),
1832 simple_guard(G2,VarDict).
1834 simple_guard(\+ G, VarDict) :-
1835 simple_guard(G, VarDict).
1837 my_term_copy(X,Dict,Y) :-
1838 my_term_copy(X,Dict,_,Y).
1840 my_term_copy(X,Dict1,Dict2,Y) :-
1842 ( lookup_eq(Dict1,X,Y) ->
1844 ; Dict2 = [X-Y|Dict1]
1850 my_term_copy_list(XArgs,Dict1,Dict2,YArgs)
1853 my_term_copy_list([],Dict,Dict,[]).
1854 my_term_copy_list([X|Xs],Dict1,Dict3,[Y|Ys]) :-
1855 my_term_copy(X,Dict1,Dict2,Y),
1856 my_term_copy_list(Xs,Dict2,Dict3,Ys).
1858 gen_cond_susp_detachment(Susp,FA,SuspDetachment) :-
1859 ( is_attached(FA) ->
1860 gen_uncond_susp_detachment(Susp,FA,UnCondSuspDetachment),
1864 ; UnCondSuspDetachment
1867 SuspDetachment = true
1870 gen_uncond_susp_detachment(Susp,CFct/CAty,SuspDetachment) :-
1871 ( is_attached(CFct/CAty) ->
1872 atom_concat_list(['detach_',CFct, (/) ,CAty],Fct),
1873 Detach =.. [Fct,Vars,Susp],
1874 ( chr_pp_flag(debugable,on) ->
1875 DebugEvent = 'chr debug_event'(remove(Susp))
1882 'chr remove_constraint_internal'(Susp, Vars),
1886 SuspDetachment = true
1889 gen_uncond_susps_detachments([],[],true).
1890 gen_uncond_susps_detachments([Susp|Susps],[Term|Terms],(SuspDetachment,SuspsDetachments)) :-
1892 gen_uncond_susp_detachment(Susp,F/A,SuspDetachment),
1893 gen_uncond_susps_detachments(Susps,Terms,SuspsDetachments).
1895 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1897 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1899 %% / ___|(_)_ __ ___ _ __ __ _ __ _ __ _| |_(_) ___ _ __ / |
1900 %% \___ \| | '_ ` _ \| '_ \ / _` |/ _` |/ _` | __| |/ _ \| '_ \ | |
1901 %% ___) | | | | | | | |_) | (_| | (_| | (_| | |_| | (_) | | | | | |
1902 %% |____/|_|_| |_| |_| .__/ \__,_|\__, |\__,_|\__|_|\___/|_| |_| |_|
1905 simpagation_head1_code(Head,RestHeads,OtherIDs,PragmaRule,F/A,Id,L,T) :-
1906 PragmaRule = pragma(Rule,ids(_,Heads2IDs),Pragmas,_Name),
1907 Rule = rule(_Heads,Heads2,Guard,Body),
1909 head_info(Head,A,_Vars,Susp,HeadVars,HeadPairs),
1910 head_arg_matches(HeadPairs,[],FirstMatching,VarDict1),
1912 build_head(F,A,Id,HeadVars,ClauseHead),
1914 append(RestHeads,Heads2,Heads),
1915 append(OtherIDs,Heads2IDs,IDs),
1916 reorder_heads(Head,Heads,IDs,NHeads,NIDs),
1917 rest_heads_retrieval_and_matching(NHeads,NIDs,Pragmas,Head,GetRestHeads,Susps,VarDict1,VarDict),
1918 split_by_ids(NIDs,Susps,OtherIDs,Susps1,Susps2),
1920 guard_body_copies2(Rule,VarDict,GuardCopyList,BodyCopy),
1921 guard_via_reschedule(GetRestHeads,GuardCopyList,ClauseHead-FirstMatching,RescheduledTest),
1923 gen_uncond_susps_detachments(Susps1,RestHeads,SuspsDetachments),
1924 gen_cond_susp_detachment(Susp,F/A,SuspDetachment),
1926 ( chr_pp_flag(debugable,on) ->
1927 my_term_copy(Guard - Body, VarDict, _, DebugGuard - DebugBody),
1928 DebugTry = 'chr debug_event'( try([Susp|Susps1],Susps2,DebugGuard,DebugBody)),
1929 DebugApply = 'chr debug_event'(apply([Susp|Susps1],Susps2,DebugGuard,DebugBody))
1935 Clause = ( ClauseHead :-
1947 split_by_ids([],[],_,[],[]).
1948 split_by_ids([I|Is],[S|Ss],I1s,S1s,S2s) :-
1949 ( memberchk_eq(I,I1s) ->
1956 split_by_ids(Is,Ss,I1s,R1s,R2s).
1958 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1961 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1963 %% / ___|(_)_ __ ___ _ __ __ _ __ _ __ _| |_(_) ___ _ __ |___ \
1964 %% \___ \| | '_ ` _ \| '_ \ / _` |/ _` |/ _` | __| |/ _ \| '_ \ __) |
1965 %% ___) | | | | | | | |_) | (_| | (_| | (_| | |_| | (_) | | | | / __/
1966 %% |____/|_|_| |_| |_| .__/ \__,_|\__, |\__,_|\__|_|\___/|_| |_| |_____|
1969 %% Genereate prelude + worker predicate
1970 %% prelude calls worker
1971 %% worker iterates over one type of removed constraints
1972 simpagation_head2_code(Head2,RestHeads2,RestIDs,PragmaRule,FA,Id,L,T) :-
1973 PragmaRule = pragma(Rule,ids(IDs1,_),Pragmas,_Name),
1974 Rule = rule(Heads1,_,Guard,Body),
1975 reorder_heads(Head2,Heads1,IDs1,[Head1|RestHeads1],[ID1|RestIDs1]), % Heads1 = [Head1|RestHeads1],
1976 % IDs1 = [ID1|RestIDs1],
1977 simpagation_head2_prelude(Head2,Head1,[RestHeads2,Heads1,Guard,Body],FA,Id,L,L1),
1979 simpagation_head2_worker(Head2,Head1,ID1,RestHeads1,RestIDs1,RestHeads2,RestIDs,Rule,Pragmas,FA,Id2,L1,T).
1981 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1982 simpagation_head2_prelude(Head,Head1,Rest,F/A,Id1,L,T) :-
1983 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs),
1984 build_head(F,A,Id1,VarsSusp,ClauseHead),
1985 head_arg_matches(HeadPairs,[],FirstMatching,VarDict),
1987 passive_head_via(Head1,[Head],[],VarDict,ModConstraintsGoal,Attr,AttrDict),
1988 instantiate_pattern_goals(AttrDict),
1989 get_max_constraint_index(N),
1993 functor(Head1,F1,A1),
1994 get_constraint_index(F1/A1,Pos),
1995 make_attr(N,_,SuspsList,Attr),
1996 nth(Pos,SuspsList,AllSusps)
1999 ( Id1 == [0] -> % create suspension
2000 gen_cond_allocation(Vars,Susp,F/A,VarsSusp,ConstraintAllocationGoal)
2001 ; ConstraintAllocationGoal = true
2004 extend_id(Id1,DelegateId),
2005 extra_active_delegate_variables(Head,Rest,VarDict,ExtraVars),
2006 append([AllSusps|VarsSusp],ExtraVars,DelegateCallVars),
2007 build_head(F,A,DelegateId,DelegateCallVars,Delegate),
2014 ConstraintAllocationGoal,
2017 L = [PreludeClause|T].
2019 extra_active_delegate_variables(Term,Terms,VarDict,Vars) :-
2021 delegate_variables(Term,Terms,VarDict,Args,Vars).
2023 passive_delegate_variables(Term,PrevTerms,NextTerms,VarDict,Vars) :-
2024 term_variables(PrevTerms,PrevVars),
2025 delegate_variables(Term,NextTerms,VarDict,PrevVars,Vars).
2027 delegate_variables(Term,Terms,VarDict,PrevVars,Vars) :-
2028 term_variables(Term,V1),
2029 term_variables(Terms,V2),
2030 intersect_eq(V1,V2,V3),
2031 list_difference_eq(V3,PrevVars,V4),
2032 translate(V4,VarDict,Vars).
2035 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2036 simpagation_head2_worker(Head2,Head1,ID1,RestHeads1,IDs1,RestHeads2,IDs2,Rule,Pragmas,FA,Id,L,T) :-
2037 Rule = rule(_,_,Guard,Body),
2038 simpagation_head2_worker_end(Head2,[Head1,RestHeads1,RestHeads2,Guard,Body],FA,Id,L,L1),
2039 simpagation_head2_worker_body(Head2,Head1,ID1,RestHeads1,IDs1,RestHeads2,IDs2,Rule,Pragmas,FA,Id,L1,T).
2041 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2042 simpagation_head2_worker_body(Head2,Head1,ID1,RestHeads1,IDs1,RestHeads2,IDs2,Rule,Pragmas,F/A,Id,L,T) :-
2044 gen_var(OtherSusps),
2046 head_info(Head2,A,_Vars,Susp,VarsSusp,Head2Pairs),
2047 head_arg_matches(Head2Pairs,[],_,VarDict1),
2049 Rule = rule(_,_,Guard,Body),
2050 extra_active_delegate_variables(Head2,[Head1,RestHeads1,RestHeads2,Guard,Body],VarDict1,ExtraVars),
2051 append([[OtherSusp|OtherSusps]|VarsSusp],ExtraVars,HeadVars),
2052 build_head(F,A,Id,HeadVars,ClauseHead),
2054 functor(Head1,_OtherF,OtherA),
2055 head_info(Head1,OtherA,OtherVars,_,_,Head1Pairs),
2056 head_arg_matches(Head1Pairs,VarDict1,FirstMatching,VarDict2),
2058 OtherSuspension =.. [suspension,_,OtherState,_,_,_,_|OtherVars],
2059 create_get_mutable_ref(active,OtherState,GetMutable),
2061 ( OtherSusp = OtherSuspension,
2065 ( (RestHeads1 \== [] ; RestHeads2 \== []) ->
2066 append(RestHeads1,RestHeads2,RestHeads),
2067 append(IDs1,IDs2,IDs),
2068 reorder_heads(Head1-Head2,RestHeads,IDs,NRestHeads,NIDs),
2069 rest_heads_retrieval_and_matching(NRestHeads,NIDs,Pragmas,[Head1,Head2],RestSuspsRetrieval,Susps,VarDict2,VarDict,[Head1],[OtherSusp],[]),
2070 split_by_ids(NIDs,Susps,IDs1,Susps1,Susps2)
2071 ; RestSuspsRetrieval = [],
2077 gen_uncond_susps_detachments([OtherSusp | Susps1],[Head1|RestHeads1],Susps1Detachments),
2079 append([OtherSusps|VarsSusp],ExtraVars,RecursiveVars),
2080 build_head(F,A,Id,RecursiveVars,RecursiveCall),
2081 append([[]|VarsSusp],ExtraVars,RecursiveVars2),
2082 build_head(F,A,Id,RecursiveVars2,RecursiveCall2),
2084 guard_body_copies2(Rule,VarDict,GuardCopyList,BodyCopy),
2085 guard_via_reschedule(RestSuspsRetrieval,GuardCopyList,v(ClauseHead,IteratorSuspTest,FirstMatching),RescheduledTest),
2086 ( BodyCopy \== true ->
2087 gen_uncond_attach_goal(F/A,Susp,Attachment,Generation),
2088 gen_state_cond_call(Susp,A,RecursiveCall,Generation,ConditionalRecursiveCall),
2089 gen_state_cond_call(Susp,A,RecursiveCall2,Generation,ConditionalRecursiveCall2)
2090 ; Attachment = true,
2091 ConditionalRecursiveCall = RecursiveCall,
2092 ConditionalRecursiveCall2 = RecursiveCall2
2095 ( chr_pp_flag(debugable,on) ->
2096 my_term_copy(Guard - Body, VarDict, _, DebugGuard - DebugBody),
2097 DebugTry = 'chr debug_event'( try([OtherSusp|Susps1],[Susp|Susps2],DebugGuard,DebugBody)),
2098 DebugApply = 'chr debug_event'(apply([OtherSusp|Susps1],[Susp|Susps2],DebugGuard,DebugBody))
2104 ( member(unique(ID1,UniqueKeys), Pragmas),
2105 check_unique_keys(UniqueKeys,VarDict1) ->
2116 ConditionalRecursiveCall2
2135 ConditionalRecursiveCall
2143 gen_state_cond_call(Susp,N,Call,Generation,ConditionalCall) :-
2145 Suspension =.. [suspension,_,State,_,NewGeneration,_,_|Args],
2146 create_get_mutable_ref(active,State,GetState),
2147 create_get_mutable_ref(Generation,NewGeneration,GetGeneration),
2149 ( Susp = Suspension,
2152 'chr update_mutable'(inactive,State),
2157 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2158 simpagation_head2_worker_end(Head,Rest,F/A,Id,L,T) :-
2159 head_info(Head,A,_Vars,_Susp,VarsSusp,Pairs),
2160 head_arg_matches(Pairs,[],_,VarDict),
2161 extra_active_delegate_variables(Head,Rest,VarDict,ExtraVars),
2162 append([[]|VarsSusp],ExtraVars,HeadVars),
2163 build_head(F,A,Id,HeadVars,ClauseHead),
2164 next_id(Id,ContinuationId),
2165 build_head(F,A,ContinuationId,VarsSusp,ContinuationHead),
2166 Clause = ( ClauseHead :- ContinuationHead ),
2169 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2172 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2174 %% | _ \ _ __ ___ _ __ __ _ __ _ __ _| |_(_) ___ _ __
2175 %% | |_) | '__/ _ \| '_ \ / _` |/ _` |/ _` | __| |/ _ \| '_ \
2176 %% | __/| | | (_) | |_) | (_| | (_| | (_| | |_| | (_) | | | |
2177 %% |_| |_| \___/| .__/ \__,_|\__, |\__,_|\__|_|\___/|_| |_|
2180 propagation_code(Head,RestHeads,Rule,RuleNb,RestHeadNb,FA,Id,L,T) :-
2181 ( RestHeads == [] ->
2182 propagation_single_headed(Head,Rule,RuleNb,FA,Id,L,T)
2184 propagation_multi_headed(Head,RestHeads,Rule,RuleNb,RestHeadNb,FA,Id,L,T)
2186 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2187 %% Single headed propagation
2188 %% everything in a single clause
2189 propagation_single_headed(Head,Rule,RuleNb,F/A,Id,L,T) :-
2190 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs),
2191 build_head(F,A,Id,VarsSusp,ClauseHead),
2194 build_head(F,A,NextId,VarsSusp,NextHead),
2196 NextCall = NextHead,
2198 head_arg_matches(HeadPairs,[],HeadMatching,VarDict),
2199 guard_body_copies(Rule,VarDict,GuardCopy,BodyCopy),
2201 gen_cond_allocation(Vars,Susp,F/A,VarsSusp,Allocation),
2202 Allocation1 = Allocation
2206 gen_uncond_attach_goal(F/A,Susp,Attachment,Generation),
2208 gen_state_cond_call(Susp,A,NextCall,Generation,ConditionalNextCall),
2210 ( chr_pp_flag(debugable,on) ->
2211 Rule = rule(_,_,Guard,Body),
2212 my_term_copy(Guard - Body, VarDict, _, DebugGuard - DebugBody),
2213 DebugTry = 'chr debug_event'( try([],[Susp],DebugGuard,DebugBody)),
2214 DebugApply = 'chr debug_event'(apply([],[Susp],DebugGuard,DebugBody))
2224 'chr novel_production'(Susp,RuleNb), % optimisation of t(RuleNb,Susp)
2229 'chr extend_history'(Susp,RuleNb),
2236 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2237 %% multi headed propagation
2238 %% prelude + predicates to accumulate the necessary combinations of suspended
2239 %% constraints + predicate to execute the body
2240 propagation_multi_headed(Head,RestHeads,Rule,RuleNb,RestHeadNb,FA,Id,L,T) :-
2241 RestHeads = [First|Rest],
2242 propagation_prelude(Head,RestHeads,Rule,FA,Id,L,L1),
2243 extend_id(Id,ExtendedId),
2244 propagation_nested_code(Rest,[First,Head],Rule,RuleNb,RestHeadNb,FA,ExtendedId,L1,T).
2246 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2247 propagation_prelude(Head,[First|Rest],Rule,F/A,Id,L,T) :-
2248 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs),
2249 build_head(F,A,Id,VarsSusp,PreludeHead),
2250 head_arg_matches(HeadPairs,[],FirstMatching,VarDict),
2251 Rule = rule(_,_,Guard,Body),
2252 extra_active_delegate_variables(Head,[First,Rest,Guard,Body],VarDict,ExtraVars),
2254 passive_head_via(First,[Head],[],VarDict,FirstSuspGoal,Attr,AttrDict),
2255 instantiate_pattern_goals(AttrDict),
2256 get_max_constraint_index(N),
2260 functor(First,FirstFct,FirstAty),
2261 make_attr(N,_Mask,SuspsList,Attr),
2262 get_constraint_index(FirstFct/FirstAty,Pos),
2263 nth(Pos,SuspsList,Susps)
2267 gen_cond_allocation(Vars,Susp,F/A,VarsSusp,CondAllocation)
2268 ; CondAllocation = true
2271 extend_id(Id,NestedId),
2272 append([Susps|VarsSusp],ExtraVars,NestedVars),
2273 build_head(F,A,NestedId,NestedVars,NestedHead),
2274 NestedCall = NestedHead,
2286 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2287 propagation_nested_code([],[CurrentHead|PreHeads],Rule,RuleNb,RestHeadNb,FA,Id,L,T) :-
2288 propagation_end([CurrentHead|PreHeads],[],Rule,FA,Id,L,L1),
2289 propagation_body(CurrentHead,PreHeads,Rule,RuleNb,RestHeadNb,FA,Id,L1,T).
2291 propagation_nested_code([Head|RestHeads],PreHeads,Rule,RuleNb,RestHeadNb,FA,Id,L,T) :-
2292 propagation_end(PreHeads,[Head|RestHeads],Rule,FA,Id,L,L1),
2293 propagation_accumulator([Head|RestHeads],PreHeads,Rule,FA,Id,L1,L2),
2295 propagation_nested_code(RestHeads,[Head|PreHeads],Rule,RuleNb,RestHeadNb,FA,IncId,L2,T).
2297 propagation_body(CurrentHead,PreHeads,Rule,RuleNb,RestHeadNb,F/A,Id,L,T) :-
2298 Rule = rule(_,_,Guard,Body),
2299 get_prop_inner_loop_vars(PreHeads,[CurrentHead,Guard,Body],PreVarsAndSusps,VarDict1,Susp,RestSusps),
2301 gen_var(OtherSusps),
2302 functor(CurrentHead,_OtherF,OtherA),
2303 gen_vars(OtherA,OtherVars),
2304 Suspension =.. [suspension,_,State,_,_,_,_|OtherVars],
2305 create_get_mutable_ref(active,State,GetMutable),
2307 OtherSusp = Suspension,
2310 ClauseVars = [[OtherSusp|OtherSusps]|PreVarsAndSusps],
2311 build_head(F,A,Id,ClauseVars,ClauseHead),
2312 RecursiveVars = [OtherSusps|PreVarsAndSusps],
2313 build_head(F,A,Id,RecursiveVars,RecursiveHead),
2314 RecursiveCall = RecursiveHead,
2315 CurrentHead =.. [_|OtherArgs],
2316 pairup(OtherArgs,OtherVars,OtherPairs),
2317 head_arg_matches(OtherPairs,VarDict1,Matching,VarDict),
2319 different_from_other_susps(CurrentHead,OtherSusp,PreHeads,RestSusps,DiffSuspGoals),
2321 guard_body_copies(Rule,VarDict,GuardCopy,BodyCopy),
2322 gen_uncond_attach_goal(F/A,Susp,Attach,Generation),
2323 gen_state_cond_call(Susp,A,RecursiveCall,Generation,ConditionalRecursiveCall),
2325 history_susps(RestHeadNb,[OtherSusp|RestSusps],Susp,[],HistorySusps),
2326 bagof('chr novel_production'(X,Y),( member(X,HistorySusps), Y = TupleVar) ,NovelProductionsList),
2327 list2conj(NovelProductionsList,NovelProductions),
2328 Tuple =.. [t,RuleNb|HistorySusps],
2330 ( chr_pp_flag(debugable,on) ->
2331 Rule = rule(_,_,Guard,Body),
2332 my_term_copy(Guard - Body, VarDict, _, DebugGuard - DebugBody),
2333 DebugTry = 'chr debug_event'( try([],[Susp,OtherSusp|RestSusps],DebugGuard,DebugBody)),
2334 DebugApply = 'chr debug_event'(apply([],[Susp,OtherSusp|RestSusps],DebugGuard,DebugBody))
2350 'chr extend_history'(Susp,TupleVar),
2353 ConditionalRecursiveCall
2360 history_susps(Count,OtherSusps,Susp,Acc,HistorySusps) :-
2362 reverse(OtherSusps,ReversedSusps),
2363 append(ReversedSusps,[Susp|Acc],HistorySusps)
2365 OtherSusps = [OtherSusp|RestOtherSusps],
2366 NCount is Count - 1,
2367 history_susps(NCount,RestOtherSusps,Susp,[OtherSusp|Acc],HistorySusps)
2371 get_prop_inner_loop_vars([Head],Terms,HeadVars,VarDict,Susp,[]) :-
2374 head_info(Head,A,_Vars,Susp,VarsSusp,Pairs),
2375 head_arg_matches(Pairs,[],_,VarDict),
2376 extra_active_delegate_variables(Head,Terms,VarDict,ExtraVars),
2377 append(VarsSusp,ExtraVars,HeadVars).
2378 get_prop_inner_loop_vars([Head|Heads],Terms,VarsSusps,NVarDict,MainSusp,[Susp|RestSusps]) :-
2379 get_prop_inner_loop_vars(Heads,[Head|Terms],RestVarsSusp,VarDict,MainSusp,RestSusps),
2382 head_info(Head,A,_Vars,Susp,_VarsSusp,Pairs),
2383 head_arg_matches(Pairs,VarDict,_,NVarDict),
2384 passive_delegate_variables(Head,Heads,Terms,NVarDict,HeadVars),
2385 append(HeadVars,[Susp,Susps|RestVarsSusp],VarsSusps).
2387 propagation_end([CurrentHead|PrevHeads],NextHeads,Rule,F/A,Id,L,T) :-
2388 Rule = rule(_,_,Guard,Body),
2389 gen_var_susp_list_for(PrevHeads,[CurrentHead,NextHeads,Guard,Body],_,VarsAndSusps,AllButFirst,FirstSusp),
2391 Vars = [ [] | VarsAndSusps],
2393 build_head(F,A,Id,Vars,Head),
2397 PrevVarsAndSusps = AllButFirst
2400 PrevVarsAndSusps = [FirstSusp|AllButFirst]
2403 build_head(F,A,PrevId,PrevVarsAndSusps,PrevHead),
2404 PredecessorCall = PrevHead,
2412 gen_var_susp_list_for([Head],Terms,VarDict,HeadVars,VarsSusp,Susp) :-
2415 head_info(Head,A,_Vars,Susp,VarsSusp,HeadPairs),
2416 head_arg_matches(HeadPairs,[],_,VarDict),
2417 extra_active_delegate_variables(Head,Terms,VarDict,ExtraVars),
2418 append(VarsSusp,ExtraVars,HeadVars).
2419 gen_var_susp_list_for([Head|Heads],Terms,NVarDict,VarsSusps,Rest,Susps) :-
2420 gen_var_susp_list_for(Heads,[Head|Terms],VarDict,Rest,_,_),
2423 head_info(Head,A,_Vars,Susp,_VarsSusp,HeadPairs),
2424 head_arg_matches(HeadPairs,VarDict,_,NVarDict),
2425 passive_delegate_variables(Head,Heads,Terms,NVarDict,HeadVars),
2426 append(HeadVars,[Susp,Susps|Rest],VarsSusps).
2428 propagation_accumulator([NextHead|RestHeads],[CurrentHead|PreHeads],Rule,F/A,Id,L,T) :-
2429 Rule = rule(_,_,Guard,Body),
2430 pre_vars_and_susps(PreHeads,[CurrentHead,NextHead,RestHeads,Guard,Body],PreVarsAndSusps,VarDict,PreSusps),
2431 gen_var(OtherSusps),
2432 functor(CurrentHead,_OtherF,OtherA),
2433 gen_vars(OtherA,OtherVars),
2434 head_info(CurrentHead,OtherA,OtherVars,OtherSusp,_VarsSusp,HeadPairs),
2435 head_arg_matches(HeadPairs,VarDict,FirstMatching,VarDict1),
2437 OtherSuspension =.. [suspension,_,State,_,_,_,_|OtherVars],
2439 different_from_other_susps(CurrentHead,OtherSusp,PreHeads,PreSusps,DiffSuspGoals),
2440 create_get_mutable_ref(active,State,GetMutable),
2442 OtherSusp = OtherSuspension,
2447 functor(NextHead,NextF,NextA),
2448 passive_head_via(NextHead,[CurrentHead|PreHeads],[],VarDict1,NextSuspGoal,Attr,AttrDict),
2449 instantiate_pattern_goals(AttrDict),
2450 get_max_constraint_index(N),
2454 get_constraint_index(NextF/NextA,Position),
2455 make_attr(N,_Mask,SuspsList,Attr),
2456 nth(Position,SuspsList,NextSusps)
2458 inc_id(Id,NestedId),
2459 ClauseVars = [[OtherSusp|OtherSusps]|PreVarsAndSusps],
2460 build_head(F,A,Id,ClauseVars,ClauseHead),
2461 passive_delegate_variables(CurrentHead,PreHeads,[NextHead,RestHeads,Guard,Body],VarDict1,CurrentHeadVars),
2462 append([NextSusps|CurrentHeadVars],[OtherSusp,OtherSusps|PreVarsAndSusps],NestedVars),
2463 build_head(F,A,NestedId,NestedVars,NestedHead),
2465 RecursiveVars = [OtherSusps|PreVarsAndSusps],
2466 build_head(F,A,Id,RecursiveVars,RecursiveHead),
2478 pre_vars_and_susps([Head],Terms,HeadVars,VarDict,[]) :-
2481 head_info(Head,A,_Vars,_Susp,VarsSusp,HeadPairs),
2482 head_arg_matches(HeadPairs,[],_,VarDict),
2483 extra_active_delegate_variables(Head,Terms,VarDict,ExtraVars),
2484 append(VarsSusp,ExtraVars,HeadVars).
2485 pre_vars_and_susps([Head|Heads],Terms,NVSs,NVarDict,[Susp|Susps]) :-
2486 pre_vars_and_susps(Heads,[Head|Terms],VSs,VarDict,Susps),
2489 head_info(Head,A,_Vars,Susp,_VarsSusp,HeadPairs),
2490 head_arg_matches(HeadPairs,VarDict,_,NVarDict),
2491 passive_delegate_variables(Head,Heads,Terms,NVarDict,HeadVars),
2492 append(HeadVars,[Susp,NextSusps|VSs],NVSs).
2494 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2496 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2498 %% | _ \ __ _ ___ ___(_)_ _____ | | | | ___ __ _ __| |
2499 %% | |_) / _` / __/ __| \ \ / / _ \ | |_| |/ _ \/ _` |/ _` |
2500 %% | __/ (_| \__ \__ \ |\ V / __/ | _ | __/ (_| | (_| |
2501 %% |_| \__,_|___/___/_| \_/ \___| |_| |_|\___|\__,_|\__,_|
2504 %% | _ \ ___| |_ _ __(_) _____ ____ _| |
2505 %% | |_) / _ \ __| '__| |/ _ \ \ / / _` | |
2506 %% | _ < __/ |_| | | | __/\ V / (_| | |
2507 %% |_| \_\___|\__|_| |_|\___| \_/ \__,_|_|
2510 %% | _ \ ___ ___ _ __ __| | ___ _ __(_)_ __ __ _
2511 %% | |_) / _ \/ _ \| '__/ _` |/ _ \ '__| | '_ \ / _` |
2512 %% | _ < __/ (_) | | | (_| | __/ | | | | | | (_| |
2513 %% |_| \_\___|\___/|_| \__,_|\___|_| |_|_| |_|\__, |
2516 reorder_heads(Head,RestHeads,RestIDs,NRestHeads,NRestIDs) :-
2517 ( chr_pp_flag(reorder_heads,on) ->
2518 reorder_heads_main(Head,RestHeads,RestIDs,NRestHeads,NRestIDs)
2520 NRestHeads = RestHeads,
2524 reorder_heads_main(Head,RestHeads,RestIDs,NRestHeads,NRestIDs) :-
2525 term_variables(Head,KnownVars),
2526 reorder_heads1(RestHeads,RestIDs,KnownVars,NRestHeads,NRestIDs).
2528 reorder_heads1(Heads,IDs,KnownVars,NHeads,NIDs) :-
2533 NHeads = [BestHead|BestTail],
2534 NIDs = [BestID | BestIDs],
2535 select_best_head(Heads,IDs,KnownVars,BestHead,BestID,RestHeads,RestIDs,NKnownVars),
2536 reorder_heads1(RestHeads,RestIDs,NKnownVars,BestTail,BestIDs)
2539 select_best_head(Heads,IDs,KnownVars,BestHead,BestID,RestHeads,RestIDs,NKnownVars) :-
2540 ( bagof(tuple(Score,Head,ID,Rest,RIDs), (
2541 select2(Head,ID, Heads,IDs,Rest,RIDs) ,
2542 order_score(Head,KnownVars,Rest,Score)
2544 Scores) -> true ; Scores = []),
2545 max_go_list(Scores,tuple(_,BestHead,BestID,RestHeads,RestIDs)),
2546 term_variables(BestHead,BestHeadVars),
2548 member(V,BestHeadVars),
2549 \+ memberchk_eq(V,KnownVars)
2551 NewVars) -> true ; NewVars = []),
2552 append(NewVars,KnownVars,NKnownVars).
2554 reorder_heads(Head,RestHeads,NRestHeads) :-
2555 term_variables(Head,KnownVars),
2556 reorder_heads1(RestHeads,KnownVars,NRestHeads).
2558 reorder_heads1(Heads,KnownVars,NHeads) :-
2562 NHeads = [BestHead|BestTail],
2563 select_best_head(Heads,KnownVars,BestHead,RestHeads,NKnownVars),
2564 reorder_heads1(RestHeads,NKnownVars,BestTail)
2567 select_best_head(Heads,KnownVars,BestHead,RestHeads,NKnownVars) :-
2568 ( bagof(tuple(Score,Head,Rest), (
2569 select(Head,Heads,Rest) ,
2570 order_score(Head,KnownVars,Rest,Score)
2572 Scores) -> true ; Scores = []),
2573 max_go_list(Scores,tuple(_,BestHead,RestHeads)),
2574 term_variables(BestHead,BestHeadVars),
2576 member(V,BestHeadVars),
2577 \+ memberchk_eq(V,KnownVars)
2579 NewVars) -> true ; NewVars = []),
2580 append(NewVars,KnownVars,NKnownVars).
2582 order_score(Head,KnownVars,Rest,Score) :-
2583 term_variables(Head,HeadVars),
2584 term_variables(Rest,RestVars),
2585 order_score_vars(HeadVars,KnownVars,RestVars,0,Score).
2587 order_score_vars([],_,_,Score,NScore) :-
2593 order_score_vars([V|Vs],KnownVars,RestVars,Score,NScore) :-
2594 ( memberchk_eq(V,KnownVars) ->
2596 ; memberchk_eq(V,RestVars) ->
2601 order_score_vars(Vs,KnownVars,RestVars,TScore,NScore).
2603 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2605 %% |_ _|_ __ | (_)_ __ (_)_ __ __ _
2606 %% | || '_ \| | | '_ \| | '_ \ / _` |
2607 %% | || | | | | | | | | | | | | (_| |
2608 %% |___|_| |_|_|_|_| |_|_|_| |_|\__, |
2612 create_get_mutable_ref(V,M,GM) :- GM = (M = mutable(V)).
2616 %% create_get_mutable_ref(V,M,GM) :- GM = get_mutable(V,M).
2619 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2621 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2623 %% / ___|___ __| | ___ / ___| | ___ __ _ _ __ (_)_ __ __ _
2624 %% | | / _ \ / _` |/ _ \ | | | |/ _ \/ _` | '_ \| | '_ \ / _` |
2625 %% | |__| (_) | (_| | __/ | |___| | __/ (_| | | | | | | | | (_| |
2626 %% \____\___/ \__,_|\___| \____|_|\___|\__,_|_| |_|_|_| |_|\__, |
2629 %% removes redundant 'true's and other trivial but potentially non-free constructs
2631 clean_clauses([],[]).
2632 clean_clauses([C|Cs],[NC|NCs]) :-
2634 clean_clauses(Cs,NCs).
2636 clean_clause(Clause,NClause) :-
2637 ( Clause = (Head :- Body) ->
2638 clean_goal(Body,NBody),
2642 NClause = (Head :- NBody)
2648 clean_goal(Goal,NGoal) :-
2651 clean_goal((G1,G2),NGoal) :-
2662 clean_goal((If -> Then ; Else),NGoal) :-
2666 clean_goal(Then,NThen),
2669 clean_goal(Else,NElse),
2672 clean_goal(Then,NThen),
2673 clean_goal(Else,NElse),
2674 NGoal = (NIf -> NThen; NElse)
2676 clean_goal((G1 ; G2),NGoal) :-
2687 clean_goal(once(G),NGoal) :-
2697 clean_goal((G1 -> G2),NGoal) :-
2701 clean_goal(G2,NGoal)
2706 NGoal = (NG1 -> NG2)
2708 clean_goal(Goal,Goal).
2709 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2711 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2713 %% | | | | |_(_) (_) |_ _ _
2714 %% | | | | __| | | | __| | | |
2715 %% | |_| | |_| | | | |_| |_| |
2716 %% \___/ \__|_|_|_|\__|\__, |
2723 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs) :-
2724 vars_susp(A,Vars,Susp,VarsSusp),
2726 pairup(Args,Vars,HeadPairs).
2728 inc_id([N|Ns],[O|Ns]) :-
2730 dec_id([N|Ns],[M|Ns]) :-
2733 extend_id(Id,[0|Id]).
2735 next_id([_,N|Ns],[O|Ns]) :-
2738 build_head(F,A,Id,Args,Head) :-
2739 buildName(F,A,Id,Name),
2740 Head =.. [Name|Args].
2742 buildName(Fct,Aty,List,Result) :-
2743 atom_concat(Fct, (/) ,FctSlash),
2744 atomic_concat(FctSlash,Aty,FctSlashAty),
2745 buildName_(List,FctSlashAty,Result).
2747 buildName_([],Name,Name).
2748 buildName_([N|Ns],Name,Result) :-
2749 buildName_(Ns,Name,Name1),
2750 atom_concat(Name1,'__',NameDash), % '_' is a char :-(
2751 atomic_concat(NameDash,N,Result).
2753 vars_susp(A,Vars,Susp,VarsSusp) :-
2755 append(Vars,[Susp],VarsSusp).
2757 make_attr(N,Mask,SuspsList,Attr) :-
2758 length(SuspsList,N),
2759 Attr =.. [v,Mask|SuspsList].
2761 or_pattern(Pos,Pat) :-
2763 Pat is 1 << Pow. % was 2 ** X
2765 and_pattern(Pos,Pat) :-
2767 Y is 1 << X, % was 2 ** X
2768 Pat is (-1)*(Y + 1). % because fx (-) is redefined
2770 conj2list(Conj,L) :- %% transform conjunctions to list
2771 conj2list(Conj,L,[]).
2773 conj2list(Conj,L,T) :-
2777 conj2list(G,[G | T],T).
2780 list2conj([G],X) :- !, X = G.
2781 list2conj([G|Gs],C) :-
2782 ( G == true -> %% remove some redundant trues
2789 atom_concat_list([X],X) :- ! .
2790 atom_concat_list([X|Xs],A) :-
2791 atom_concat_list(Xs,B),
2792 atomic_concat(X,B,A).
2794 atomic_concat(A,B,C) :-
2797 atom_concat(AA,BB,C).
2810 set_elems([X|Xs],X) :-
2813 member2([X|_],[Y|_],X-Y).
2814 member2([_|Xs],[_|Ys],P) :-
2817 select2(X, Y, [X|Xs], [Y|Ys], Xs, Ys).
2818 select2(X, Y, [X1|Xs], [Y1|Ys], [X1|NXs], [Y1|NYs]) :-
2819 select2(X, Y, Xs, Ys, NXs, NYs).
2821 pair_all_with([],_,[]).
2822 pair_all_with([X|Xs],Y,[X-Y|Rest]) :-
2823 pair_all_with(Xs,Y,Rest).
2825 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2828 verbosity_on :- prolog_flag(verbose,V), V == yes.
2832 %% verbosity_on. % at the moment