3 Part of CHR (Constraint Handling Rules)
6 E-mail: Tom.Schrijvers@cs.kuleuven.ac.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.ac.be
45 %% * based on the SICStus CHR compilation by Christian Holzbaur
47 %% First working version: 6 June 2003
49 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
53 %% * fine-tune automatic selection of constraint stores
57 %% * further specialize runtime predicates for special cases where
58 %% - none of the constraints contain any indexing variables, ...
59 %% - just one constraint requires some runtime predicate
60 %% * analysis for attachment delaying (see primes for case)
61 %% * internal constraints declaration + analyses?
62 %% * Do not store in global variable store if not necessary
63 %% NOTE: affects show_store/1
64 %% * multi-level store: variable - ground
65 %% * Do not maintain/check unnecessary propagation history
66 %% for rules that cannot be applied more than once
67 %% e.g. due to groundness
68 %% * Strengthen attachment analysis:
69 %% reason about bodies of rules only containing constraints
71 %% * SICStus compatibility
72 %% - rules/1 declaration
76 %% * instantiation declarations
79 %% - cheaper matching code?
80 %% VARIABLE (never bound)
82 %% * make difference between cheap guards for reordering
83 %% and non-binding guards for lock removal
84 %% * unqiue -> once/[] transformation for propagation
85 %% * cheap guards interleaved with head retrieval + faster
86 %% via-retrieval + non-empty checking for propagation rules
87 %% redo for simpagation_head2 prelude
88 %% * intelligent backtracking for simplification/simpagation rule
89 %% generator_1(X),'_$savecp'(CP_1),
96 %% ('_$cutto'(CP_1), fail)
100 %% or recently developped cascading-supported approach
102 %% * intelligent backtracking for propagation rule
103 %% use additional boolean argument for each possible smart backtracking
104 %% when boolean at end of list true -> no smart backtracking
105 %% false -> smart backtracking
106 %% only works for rules with at least 3 constraints in the head
108 %% * mutually exclusive rules
109 %% * (set semantics + functional dependency) declaration + resolution
111 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
112 :- module(chr_translate,
113 [ chr_translate/2 % +Decls, -TranslatedDecls
115 :- use_module(library(lists)).
116 :- use_module(hprolog).
117 :- use_module(library(assoc)).
118 :- use_module(pairlist).
119 :- use_module(library(ordsets)).
120 :- use_module(a_star).
121 :- use_module(clean_code).
122 :- use_module(builtins).
127 option(optimize,full).
129 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
132 constraint/2, % constraint(F/A,ConstraintIndex)
135 constraint_count/1, % constraint_count(MaxConstraintIndex)
136 get_constraint_count/1,
138 constraint_index/2, % constraint_index(F/A,DefaultStoreAndAttachedIndex)
139 get_constraint_index/2,
141 max_constraint_index/1, % max_constraint_index(MaxDefaultStoreAndAttachedIndex)
142 get_max_constraint_index/1,
144 target_module/1, % target_module(Module)
147 attached/2, % attached(F/A,yes/no/maybe)
150 indexed_argument/2, % argument instantiation may enable applicability of rule
151 is_indexed_argument/2,
154 get_constraint_mode/2,
158 has_nonground_indexed_argument/3,
163 actual_store_types/2,
164 assumed_store_type/2,
165 validate_store_type_assumption/1,
182 get_max_occurrence/2,
184 allocation_occurrence/2,
185 get_allocation_occurrence/2,
190 option(mode,constraint(+,+)).
191 option(mode,constraint_count(+)).
192 option(mode,constraint_index(+,+)).
193 option(mode,max_constraint_index(+)).
194 option(mode,target_module(+)).
195 option(mode,attached(+,+)).
196 option(mode,indexed_argument(+,+)).
197 option(mode,constraint_mode(+,+)).
198 option(mode,may_trigger(+)).
199 option(mode,store_type(+,+)).
200 option(mode,actual_store_types(+,+)).
201 option(mode,assumed_store_type(+,+)).
202 option(mode,rule_count(+)).
203 option(mode,passive(+,+)).
204 option(mode,pragma_unique(+,+,?)).
205 option(mode,occurrence(+,+,+,+)).
206 option(mode,max_occurrence(+,+)).
207 option(mode,allocation_occurrence(+,+)).
208 option(mode,rule(+,+)).
210 constraint(FA,Index) \ get_constraint(Query,Index)
215 constraint_count(Index) \ get_constraint_count(Query)
217 get_constraint_count(Query)
220 target_module(Mod) \ get_target_module(Query)
222 get_target_module(Query)
225 constraint_index(C,Index) \ get_constraint_index(C,Query)
227 get_constraint_index(_,_)
230 max_constraint_index(Index) \ get_max_constraint_index(Query)
232 get_max_constraint_index(Query)
235 attached(Constr,yes) \ attached(Constr,_) <=> true.
236 attached(Constr,no) \ attached(Constr,_) <=> true.
237 attached(Constr,maybe) \ attached(Constr,maybe) <=> true.
239 attached(Constr,Type) \ is_attached(Constr)
241 is_attached(_) <=> true.
243 indexed_argument(FA,I) \ indexed_argument(FA,I) <=> true.
244 indexed_argument(FA,I) \ is_indexed_argument(FA,I) <=> true.
245 is_indexed_argument(_,_) <=> fail.
247 constraint_mode(FA,Mode) \ get_constraint_mode(FA,Query)
249 get_constraint_mode(FA,Query)
250 <=> FA = _/A, length(Query,A), set_elems(Query,?).
254 get_constraint_mode(FA,Mode),
255 has_nonground_indexed_argument(FA,1,Mode).
257 has_nonground_indexed_argument(FA,I,[Mode|Modes])
261 ( is_indexed_argument(FA,I),
266 has_nonground_indexed_argument(FA,J,Modes)
268 has_nonground_indexed_argument(_,_,_)
271 store_type(FA,atom_hash(Index)) <=> store_type(FA,multi_hash([Index])).
272 store_type(FA,Store) \ get_store_type(FA,Query)
274 assumed_store_type(FA,Store) \ get_store_type(FA,Query)
276 get_store_type(_,Query)
279 actual_store_types(C,STs) \ update_store_type(C,ST)
280 <=> member(ST,STs) | true.
281 update_store_type(C,ST), actual_store_types(C,STs)
283 actual_store_types(C,[ST|STs]).
284 update_store_type(C,ST)
286 actual_store_types(C,[ST]).
288 % refine store type assumption
289 validate_store_type_assumption(C), actual_store_types(C,STs), assumed_store_type(C,_) % automatic assumption
291 store_type(C,multi_store(STs)).
292 validate_store_type_assumption(C), actual_store_types(C,STs), store_type(C,_) % user assumption
294 store_type(C,multi_store(STs)).
295 validate_store_type_assumption(_)
298 rule_count(C), inc_rule_count(NC)
299 <=> NC is C + 1, rule_count(NC).
301 <=> NC = 1, rule_count(NC).
303 rule_count(C) \ get_rule_count(Q)
308 passive(RuleNb,ID) \ is_passive(RuleNb,ID)
312 passive(RuleNb,_) \ any_passive_head(RuleNb)
317 pragma_unique(RuleNb,ID,Vars) \ get_pragma_unique(RuleNb,ID,Query)
319 get_pragma_unique(_,_,_)
322 occurrence(C,ON,Rule,ID) \ get_occurrence(C,ON,QRule,QID)
323 <=> Rule = QRule, ID = QID.
324 get_occurrence(_,_,_,_)
327 occurrence(C,ON,_,_) ==> max_occurrence(C,ON).
328 max_occurrence(C,N) \ max_occurrence(C,M)
330 max_occurrence(C,MON) \ get_max_occurrence(C,Q)
332 get_max_occurrence(_,Q)
335 % need not store constraint that is removed
336 rule(RuleNb,Rule), occurrence(C,O,RuleNb,ID) \ allocation_occurrence(C,O)
337 <=> Rule = pragma(_,ids(IDs1,_),_,_,_), member(ID,IDs)
338 | NO is O + 1, allocation_occurrence(C,NO).
339 % need not store constraint when body is true
340 rule(RuleNb,Rule), occurrence(C,O,RuleNb,_) \ allocation_occurrence(C,O)
341 <=> Rule = pragma(rule(_,_,_,true),_,_,_,_)
342 | NO is O + 1, allocation_occurrence(C,NO).
343 % cannot store constraint at passive occurrence
344 occurrence(C,O,RuleNb,ID), passive(RuleNb,ID) \ allocation_occurrence(C,O)
345 <=> NO is O + 1, allocation_occurrence(C,NO).
346 allocation_occurrence(C,O) \ get_allocation_occurrence(C,Q)
348 get_allocation_occurrence(_,_)
351 rule(RuleNb,Rule) \ get_rule(RuleNb,Q)
357 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
360 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
364 chr_translate(Declarations,NewDeclarations) :-
366 partition_clauses(Declarations,Constraints,Rules,OtherClauses),
367 ( Constraints == [] ->
368 insert_declarations(OtherClauses, NewDeclarations)
372 check_rules(Rules,Constraints),
373 add_occurrences(Rules),
374 late_allocation(Constraints),
375 unique_analyse_optimise(Rules,NRules),
376 check_attachments(Constraints),
377 assume_constraint_stores(Constraints),
378 set_constraint_indices(Constraints,1),
380 constraints_code(Constraints,NRules,ConstraintClauses),
381 validate_store_type_assumptions(Constraints),
382 store_management_preds(Constraints,StoreClauses), % depends on actual code used
383 insert_declarations(OtherClauses, Clauses0),
384 chr_module_declaration(CHRModuleDeclaration),
385 append_lists([Clauses0,
393 store_management_preds(Constraints,Clauses) :-
394 generate_attach_detach_a_constraint_all(Constraints,AttachAConstraintClauses),
395 generate_indexed_variables_clauses(Constraints,IndexedClauses),
396 generate_attach_increment(AttachIncrementClauses),
397 generate_attr_unify_hook(AttrUnifyHookClauses),
398 generate_extra_clauses(Constraints,ExtraClauses),
399 generate_insert_delete_constraints(Constraints,DeleteClauses),
400 generate_store_code(Constraints,StoreClauses),
401 append_lists([AttachAConstraintClauses
403 ,AttachIncrementClauses
404 ,AttrUnifyHookClauses
410 insert_declarations(Clauses0, Clauses) :-
411 ( Clauses0 = [:- module(M,E)|FileBody]
412 -> Clauses = [ :- module(M,E),
413 :- use_module('chr_runtime'),
414 :- use_module('chr_hashtable_store'),
415 :- style_check(-singleton),
416 :- style_check(-discontiguous)
419 ; Clauses = [ :- use_module('chr_runtime'),
420 :- use_module('chr_hashtable_store'),
421 :- style_check(-singleton),
422 :- style_check(-discontiguous)
428 chr_module_declaration(CHRModuleDeclaration) :-
429 get_target_module(Mod),
430 ( Mod \== chr_translate ->
431 CHRModuleDeclaration = [
432 (:- multifile chr:'$chr_module'/1),
433 chr:'$chr_module'(Mod)
436 CHRModuleDeclaration = []
440 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
442 %% Partitioning of clauses into constraint declarations, chr rules and other
445 partition_clauses([],[],[],[]).
446 partition_clauses([C|Cs],Ds,Rs,OCs) :-
451 ; is_declaration(C,D) ->
455 ; is_module_declaration(C,Mod) ->
461 format('CHR compiler WARNING: ~w.\n',[C]),
462 format(' `--> SICStus compatibility: ignoring handler/1 declaration.\n',[]),
467 format('CHR compiler WARNING: ~w.\n',[C]),
468 format(' `--> SICStus compatibility: ignoring rules/1 declaration.\n',[]),
472 ; C = option(OptionName,OptionValue) ->
473 handle_option(OptionName,OptionValue),
481 partition_clauses(Cs,RDs,RRs,ROCs).
483 is_declaration(D, Constraints) :- %% constraint declaration
489 Decl =.. [constraints,Cs],
490 conj2list(Cs,Constraints).
499 %% yesno(string), :: maybe rule nane
500 %% int :: rule number
509 %% list(constraint), :: constraints to be removed
510 %% list(constraint), :: surviving constraints
515 parse_rule(RI,R) :- %% name @ rule
516 RI = (Name @ RI2), !,
517 rule(RI2,yes(Name),R).
522 RI = (RI2 pragma P), !, %% pragmas
525 inc_rule_count(RuleCount),
526 R = pragma(R1,IDs,Ps,Name,RuleCount).
529 inc_rule_count(RuleCount),
530 R = pragma(R1,IDs,[],Name,RuleCount).
532 is_rule(RI,R,IDs) :- %% propagation rule
535 get_ids(Head2i,IDs2,Head2),
538 R = rule([],Head2,G,RB)
540 R = rule([],Head2,true,B)
542 is_rule(RI,R,IDs) :- %% simplification/simpagation rule
551 conj2list(H1,Head2i),
552 conj2list(H2,Head1i),
553 get_ids(Head2i,IDs2,Head2,0,N),
554 get_ids(Head1i,IDs1,Head1,N,_),
556 ; conj2list(H,Head1i),
558 get_ids(Head1i,IDs1,Head1),
561 R = rule(Head1,Head2,Guard,Body).
563 get_ids(Cs,IDs,NCs) :-
564 get_ids(Cs,IDs,NCs,0,_).
566 get_ids([],[],[],N,N).
567 get_ids([C|Cs],[N|IDs],[NC|NCs],N,NN) :-
574 get_ids(Cs,IDs,NCs, M,NN).
576 is_module_declaration((:- module(Mod)),Mod).
577 is_module_declaration((:- module(Mod,_)),Mod).
579 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
581 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
584 add_rules([Rule|Rules]) :-
585 Rule = pragma(_,_,_,_,RuleNb),
589 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
591 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
592 %% Some input verification:
593 %% - all constraints in heads are declared constraints
594 %% - all passive pragmas refer to actual head constraints
597 check_rules([PragmaRule|Rest],Decls) :-
598 check_rule(PragmaRule,Decls),
599 check_rules(Rest,Decls).
601 check_rule(PragmaRule,Decls) :-
602 check_rule_indexing(PragmaRule),
603 PragmaRule = pragma(Rule,_IDs,Pragmas,_Name,_N),
604 Rule = rule(H1,H2,_,_),
605 append(H1,H2,HeadConstraints),
606 check_head_constraints(HeadConstraints,Decls,PragmaRule),
607 check_pragmas(Pragmas,PragmaRule).
609 check_head_constraints([],_,_).
610 check_head_constraints([Constr|Rest],Decls,PragmaRule) :-
612 ( member(F/A,Decls) ->
613 check_head_constraints(Rest,Decls,PragmaRule)
615 format('CHR compiler ERROR: Undeclared constraint ~w in head of ~@.\n',
616 [F/A,format_rule(PragmaRule)]),
617 format(' `--> Constraint should be one of ~w.\n',[Decls]),
622 check_pragmas([Pragma|Pragmas],PragmaRule) :-
623 check_pragma(Pragma,PragmaRule),
624 check_pragmas(Pragmas,PragmaRule).
626 check_pragma(Pragma,PragmaRule) :-
628 format('CHR compiler ERROR: invalid pragma ~w in ~@.\n',
629 [Pragma,format_rule(PragmaRule)]),
630 format(' `--> Pragma should not be a variable!\n',[]),
632 check_pragma(passive(ID), PragmaRule) :-
634 PragmaRule = pragma(_,ids(IDs1,IDs2),_,_,RuleNb),
635 ( memberchk_eq(ID,IDs1) ->
637 ; memberchk_eq(ID,IDs2) ->
640 format('CHR compiler ERROR: invalid identifier ~w in pragma passive in ~@.\n',
641 [ID,format_rule(PragmaRule)]),
646 check_pragma(Pragma, PragmaRule) :-
647 Pragma = unique(ID,Vars),
649 PragmaRule = pragma(_,_,_,_,RuleNb),
650 pragma_unique(RuleNb,ID,Vars),
651 format('CHR compiler WARNING: undocument pragma ~w in ~@.\n',[Pragma,format_rule(PragmaRule)]),
652 format(' `--> Only use this pragma if you know what you are doing.\n',[]).
654 check_pragma(Pragma, PragmaRule) :-
655 Pragma = already_in_heads,
657 format('CHR compiler WARNING: currently unsupported pragma ~w in ~@.\n',[Pragma,format_rule(PragmaRule)]),
658 format(' `--> Pragma is ignored. Termination and correctness may be affected \n',[]).
660 check_pragma(Pragma, PragmaRule) :-
661 Pragma = already_in_head(_),
663 format('CHR compiler WARNING: currently unsupported pragma ~w in ~@.\n',[Pragma,format_rule(PragmaRule)]),
664 format(' `--> Pragma is ignored. Termination and correctness may be affected \n',[]).
666 check_pragma(Pragma,PragmaRule) :-
667 format('CHR compiler ERROR: invalid pragma ~w in ~@.\n',[Pragma,format_rule(PragmaRule)]),
668 format(' `--> Pragma should be one of passive/1!\n',[]),
671 format_rule(PragmaRule) :-
672 PragmaRule = pragma(_,_,_,MaybeName,N),
673 ( MaybeName = yes(Name) ->
674 write('rule '), write(Name)
676 write('rule number '), write(N)
679 check_rule_indexing(PragmaRule) :-
680 PragmaRule = pragma(Rule,_,_,_,_),
681 Rule = rule(H1,H2,G,_),
682 term_variables(H1-H2,HeadVars),
683 remove_anti_monotonic_guards(G,HeadVars,NG),
684 check_indexing(H1,NG-H2),
685 check_indexing(H2,NG-H1).
687 remove_anti_monotonic_guards(G,Vars,NG) :-
689 remove_anti_monotonic_guard_list(GL,Vars,NGL),
692 remove_anti_monotonic_guard_list([],_,[]).
693 remove_anti_monotonic_guard_list([G|Gs],Vars,NGs) :-
695 memberchk_eq(X,Vars) ->
700 remove_anti_monotonic_guard_list(Gs,Vars,RGs).
702 check_indexing([],_).
703 check_indexing([Head|Heads],Other) :-
706 term_variables(Heads-Other,OtherVars),
707 check_indexing(Args,1,F/A,OtherVars),
708 check_indexing(Heads,[Head|Other]).
710 check_indexing([],_,_,_).
711 check_indexing([Arg|Args],I,FA,OtherVars) :-
712 ( is_indexed_argument(FA,I) ->
715 indexed_argument(FA,I)
717 term_variables(Args,ArgsVars),
718 append(ArgsVars,OtherVars,RestVars),
719 ( memberchk_eq(Arg,RestVars) ->
720 indexed_argument(FA,I)
726 term_variables(Arg,NVars),
727 append(NVars,OtherVars,NOtherVars),
728 check_indexing(Args,J,FA,NOtherVars).
730 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
732 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
736 add_occurrences([Rule|Rules]) :-
737 Rule = pragma(rule(H1,H2,_,_),ids(IDs1,IDs2),_,_,Nb),
738 add_occurrences(H1,IDs1,Nb),
739 add_occurrences(H2,IDs2,Nb),
740 add_occurrences(Rules).
742 add_occurrences([],[],_).
743 add_occurrences([H|Hs],[ID|IDs],RuleNb) :-
746 get_max_occurrence(FA,MO),
748 occurrence(FA,O,RuleNb,ID),
749 add_occurrences(Hs,IDs,RuleNb).
751 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
753 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
757 late_allocation([C|Cs]) :-
758 allocation_occurrence(C,1),
760 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
762 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
766 handle_option(Var,Value) :-
768 format('CHR compiler ERROR: ~w.\n',[option(Var,Value)]),
769 format(' `--> First argument should be an atom, not a variable.\n',[]),
772 handle_option(Name,Value) :-
774 format('CHR compiler ERROR: ~w.\n',[option(Name,Value)]),
775 format(' `--> Second argument should be a nonvariable.\n',[]),
778 handle_option(Name,Value) :-
779 option_definition(Name,Value,Flags),
781 set_chr_pp_flags(Flags).
783 handle_option(Name,Value) :-
784 \+ option_definition(Name,_,_), !,
785 % setof(N,_V ^ _F ^ (option_definition(N,_V,_F)),Ns),
786 format('CHR compiler WARNING: ~w.\n',[option(Name,Value)]),
787 format(' `--> Invalid option name \n',[]). %~w: should be one of ~w.\n',[Name,Ns]).
789 handle_option(Name,Value) :-
790 findall(V,option_definition(Name,V,_),Vs),
791 format('CHR compiler ERROR: ~w.\n',[option(Name,Value)]),
792 format(' `--> Invalid value ~w: should be one of ~w.\n',[Value,Vs]),
795 option_definition(optimize,experimental,Flags) :-
796 Flags = [ unique_analyse_optimise - on,
797 check_unnecessary_active - full,
799 set_semantics_rule - on,
800 check_attachments - on,
801 guard_via_reschedule - on
803 option_definition(optimize,full,Flags) :-
804 Flags = [ unique_analyse_optimise - on,
805 check_unnecessary_active - full,
807 set_semantics_rule - on,
808 check_attachments - on,
809 guard_via_reschedule - on
812 option_definition(optimize,sicstus,Flags) :-
813 Flags = [ unique_analyse_optimise - off,
814 check_unnecessary_active - simplification,
816 set_semantics_rule - off,
817 check_attachments - off,
818 guard_via_reschedule - off
821 option_definition(optimize,off,Flags) :-
822 Flags = [ unique_analyse_optimise - off,
823 check_unnecessary_active - off,
825 set_semantics_rule - off,
826 check_attachments - off,
827 guard_via_reschedule - off
830 option_definition(check_guard_bindings,on,Flags) :-
831 Flags = [ guard_locks - on ].
833 option_definition(check_guard_bindings,off,Flags) :-
834 Flags = [ guard_locks - off ].
836 option_definition(reduced_indexing,on,Flags) :-
837 Flags = [ reduced_indexing - on ].
839 option_definition(reduced_indexing,off,Flags) :-
840 Flags = [ reduced_indexing - off ].
842 option_definition(mode,ModeDecl,[]) :-
844 functor(ModeDecl,F,A),
845 ModeDecl =.. [_|ArgModes],
846 constraint_mode(F/A,ArgModes)
850 option_definition(store,FA-Store,[]) :-
851 store_type(FA,Store).
853 option_definition(debug,on,Flags) :-
854 Flags = [ debugable - on ].
855 option_definition(debug,off,Flags) :-
856 Flags = [ debugable - off ].
859 chr_pp_flag_definition(Name,[DefaultValue|_]),
860 set_chr_pp_flag(Name,DefaultValue),
864 set_chr_pp_flags([]).
865 set_chr_pp_flags([Name-Value|Flags]) :-
866 set_chr_pp_flag(Name,Value),
867 set_chr_pp_flags(Flags).
869 set_chr_pp_flag(Name,Value) :-
870 atom_concat('$chr_pp_',Name,GlobalVar),
871 nb_setval(GlobalVar,Value).
873 chr_pp_flag_definition(unique_analyse_optimise,[on,off]).
874 chr_pp_flag_definition(check_unnecessary_active,[full,simplification,off]).
875 chr_pp_flag_definition(reorder_heads,[on,off]).
876 chr_pp_flag_definition(set_semantics_rule,[on,off]).
877 chr_pp_flag_definition(guard_via_reschedule,[on,off]).
878 chr_pp_flag_definition(guard_locks,[on,off]).
879 chr_pp_flag_definition(check_attachments,[on,off]).
880 chr_pp_flag_definition(debugable,[off,on]).
881 chr_pp_flag_definition(reduced_indexing,[on,off]).
883 chr_pp_flag(Name,Value) :-
884 atom_concat('$chr_pp_',Name,GlobalVar),
885 nb_getval(GlobalVar,V),
887 chr_pp_flag_definition(Name,[Value|_])
891 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
893 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
895 %% Generated predicates
896 %% attach_$CONSTRAINT
898 %% detach_$CONSTRAINT
901 %% attach_$CONSTRAINT
902 generate_attach_detach_a_constraint_all([],[]).
903 generate_attach_detach_a_constraint_all([Constraint|Constraints],Clauses) :-
904 ( may_trigger(Constraint) ->
905 generate_attach_a_constraint(Constraint,Clauses1),
906 generate_detach_a_constraint(Constraint,Clauses2)
911 generate_attach_detach_a_constraint_all(Constraints,Clauses3),
912 append_lists([Clauses1,Clauses2,Clauses3],Clauses).
914 generate_attach_a_constraint(Constraint,[Clause1,Clause2]) :-
915 generate_attach_a_constraint_empty_list(Constraint,Clause1),
916 get_max_constraint_index(N),
918 generate_attach_a_constraint_1_1(Constraint,Clause2)
920 generate_attach_a_constraint_t_p(Constraint,Clause2)
923 generate_attach_a_constraint_skeleton(FA,Args,Body,Clause) :-
924 make_name('attach_',FA,Fct),
925 Head =.. [Fct | Args],
926 Clause = ( Head :- Body).
928 generate_attach_a_constraint_empty_list(FA,Clause) :-
929 generate_attach_a_constraint_skeleton(FA,[[],_],true,Clause).
931 generate_attach_a_constraint_1_1(FA,Clause) :-
932 Args = [[Var|Vars],Susp],
933 generate_attach_a_constraint_skeleton(FA,Args,Body,Clause),
934 generate_attach_body_1(FA,Var,Susp,AttachBody),
935 make_name('attach_',FA,Fct),
936 RecursiveCall =.. [Fct,Vars,Susp],
943 generate_attach_body_1(FA,Var,Susp,Body) :-
944 get_target_module(Mod),
946 ( get_attr(Var, Mod, Susps) ->
947 NewSusps=[Susp|Susps],
948 put_attr(Var, Mod, NewSusps)
950 put_attr(Var, Mod, [Susp])
953 generate_attach_a_constraint_t_p(FA,Clause) :-
954 Args = [[Var|Vars],Susp],
955 generate_attach_a_constraint_skeleton(FA,Args,Body,Clause),
956 make_name('attach_',FA,Fct),
957 RecursiveCall =.. [Fct,Vars,Susp],
958 generate_attach_body_n(FA,Var,Susp,AttachBody),
965 generate_attach_body_n(F/A,Var,Susp,Body) :-
966 get_constraint_index(F/A,Position),
967 or_pattern(Position,Pattern),
968 get_max_constraint_index(Total),
969 make_attr(Total,Mask,SuspsList,Attr),
970 nth(Position,SuspsList,Susps),
971 substitute(Susps,SuspsList,[Susp|Susps],SuspsList1),
972 make_attr(Total,Mask,SuspsList1,NewAttr1),
973 substitute(Susps,SuspsList,[Susp],SuspsList2),
974 make_attr(Total,NewMask,SuspsList2,NewAttr2),
975 copy_term(SuspsList,SuspsList3),
976 nth(Position,SuspsList3,[Susp]),
977 delete(SuspsList3,[Susp],RestSuspsList),
978 set_elems(RestSuspsList,[]),
979 make_attr(Total,Pattern,SuspsList3,NewAttr3),
980 get_target_module(Mod),
982 ( get_attr(Var,Mod,TAttr) ->
984 ( Mask /\ Pattern =:= Pattern ->
985 put_attr(Var, Mod, NewAttr1)
987 NewMask is Mask \/ Pattern,
988 put_attr(Var, Mod, NewAttr2)
991 put_attr(Var,Mod,NewAttr3)
994 %% detach_$CONSTRAINT
995 generate_detach_a_constraint(Constraint,[Clause1,Clause2]) :-
996 generate_detach_a_constraint_empty_list(Constraint,Clause1),
997 get_max_constraint_index(N),
999 generate_detach_a_constraint_1_1(Constraint,Clause2)
1001 generate_detach_a_constraint_t_p(Constraint,Clause2)
1004 generate_detach_a_constraint_empty_list(FA,Clause) :-
1005 make_name('detach_',FA,Fct),
1007 Head =.. [Fct | Args],
1008 Clause = ( Head :- true).
1010 generate_detach_a_constraint_1_1(FA,Clause) :-
1011 make_name('detach_',FA,Fct),
1012 Args = [[Var|Vars],Susp],
1013 Head =.. [Fct | Args],
1014 RecursiveCall =.. [Fct,Vars,Susp],
1015 generate_detach_body_1(FA,Var,Susp,DetachBody),
1021 Clause = (Head :- Body).
1023 generate_detach_body_1(FA,Var,Susp,Body) :-
1024 get_target_module(Mod),
1026 ( get_attr(Var,Mod,Susps) ->
1027 'chr sbag_del_element'(Susps,Susp,NewSusps),
1031 put_attr(Var,Mod,NewSusps)
1037 generate_detach_a_constraint_t_p(FA,Clause) :-
1038 make_name('detach_',FA,Fct),
1039 Args = [[Var|Vars],Susp],
1040 Head =.. [Fct | Args],
1041 RecursiveCall =.. [Fct,Vars,Susp],
1042 generate_detach_body_n(FA,Var,Susp,DetachBody),
1048 Clause = (Head :- Body).
1050 generate_detach_body_n(F/A,Var,Susp,Body) :-
1051 get_constraint_index(F/A,Position),
1052 or_pattern(Position,Pattern),
1053 and_pattern(Position,DelPattern),
1054 get_max_constraint_index(Total),
1055 make_attr(Total,Mask,SuspsList,Attr),
1056 nth(Position,SuspsList,Susps),
1057 substitute(Susps,SuspsList,[],SuspsList1),
1058 make_attr(Total,NewMask,SuspsList1,Attr1),
1059 substitute(Susps,SuspsList,NewSusps,SuspsList2),
1060 make_attr(Total,Mask,SuspsList2,Attr2),
1061 get_target_module(Mod),
1063 ( get_attr(Var,Mod,TAttr) ->
1065 ( Mask /\ Pattern =:= Pattern ->
1066 'chr sbag_del_element'(Susps,Susp,NewSusps),
1068 NewMask is Mask /\ DelPattern,
1072 put_attr(Var,Mod,Attr1)
1075 put_attr(Var,Mod,Attr2)
1084 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1085 generate_indexed_variables_clauses(Constraints,Clauses) :-
1086 ( forsome(C,Constraints,chr_translate:may_trigger(C)) ->
1087 generate_indexed_variables_clauses_(Constraints,Clauses)
1092 generate_indexed_variables_clauses_([],[]).
1093 generate_indexed_variables_clauses_([C|Cs],Clauses) :-
1094 ( ( is_attached(C) ; chr_pp_flag(debugable,on)) ->
1095 Clauses = [Clause|RestClauses],
1096 generate_indexed_variables_clause(C,Clause)
1098 Clauses = RestClauses
1100 generate_indexed_variables_clauses_(Cs,RestClauses).
1102 generate_indexed_variables_clause(F/A,Clause) :-
1104 get_constraint_mode(F/A,ArgModes),
1106 create_indexed_variables_body(Args,ArgModes,Vars,1,F/A,MaybeBody,N),
1107 ( MaybeBody == empty ->
1111 Body = term_variables(Susp,Vars)
1116 ( '$indexed_variables'(Susp,Vars) :-
1121 create_indexed_variables_body([],[],_,_,_,empty,0).
1122 create_indexed_variables_body([V|Vs],[Mode|Modes],Vars,I,FA,Body,N) :-
1124 create_indexed_variables_body(Vs,Modes,Tail,J,FA,RBody,M),
1126 is_indexed_argument(FA,I) ->
1128 Body = term_variables(V,Vars)
1130 Body = (term_variables(V,Vars,Tail),RBody)
1139 generate_extra_clauses(Constraints,[A,B,C,D,E]) :-
1140 ( chr_pp_flag(reduced_indexing,on) ->
1141 global_indexed_variables_clause(Constraints,D)
1144 ( chr_indexed_variables(Susp,Vars) :-
1145 'chr chr_indexed_variables'(Susp,Vars)
1148 generate_remove_clause(A),
1149 generate_activate_clause(B),
1150 generate_allocate_clause(C),
1151 generate_insert_constraint_internal(E).
1153 generate_remove_clause(RemoveClause) :-
1156 remove_constraint_internal(Susp, Agenda, Delete) :-
1157 arg( 2, Susp, Mref),
1158 Mref = mutable(State), % get_mutable( State, Mref), % XXX Inlined
1159 'chr update_mutable'( removed, Mref), % mark in any case
1160 ( compound(State) -> % passive/1
1166 %; State==triggered ->
1170 chr_indexed_variables(Susp,Agenda)
1174 generate_activate_clause(ActivateClause) :-
1177 activate_constraint(Store, Vars, Susp, Generation) :-
1178 arg( 2, Susp, Mref),
1179 Mref = mutable(State), % get_mutable( State, Mref), % XXX Inlined
1180 'chr update_mutable'( active, Mref),
1181 ( nonvar(Generation) -> % aih
1184 arg( 4, Susp, Gref),
1185 Gref = mutable(Gen), % get_mutable( Gen, Gref), % XXX Inlined
1186 Generation is Gen+1,
1187 'chr update_mutable'( Generation, Gref)
1189 ( compound(State) -> % passive/1
1190 term_variables( State, Vars),
1191 'chr none_locked'( Vars),
1193 ; State == removed -> % the price for eager removal ...
1194 chr_indexed_variables(Susp,Vars),
1202 generate_allocate_clause(AllocateClause) :-
1205 allocate_constraint( Closure, Self, F, Args) :-
1206 Self =.. [suspension,Id,Mref,Closure,Gref,Href,F|Args],
1208 'chr empty_history'(History),
1209 Href = mutable(History),
1210 chr_indexed_variables(Self,Vars),
1211 Mref = mutable(passive(Vars)),
1215 generate_insert_constraint_internal(Clause) :-
1218 insert_constraint_internal(yes, Vars, Self, Closure, F, Args) :-
1219 Self =.. [suspension,Id,Mref,Closure,Gref,Href,F|Args],
1220 chr_indexed_variables(Self,Vars),
1221 'chr none_locked'(Vars),
1222 Mref = mutable(active),
1224 Href = mutable(History),
1225 'chr empty_history'(History),
1229 global_indexed_variables_clause(Constraints,Clause) :-
1230 ( forsome(C,Constraints,chr_translate:may_trigger(C)) ->
1231 Body = (Susp =.. [_,_,_,_,_,_,Term|_], '$indexed_variables'(Term,Vars))
1236 Clause = ( chr_indexed_variables(Susp,Vars) :- Body ).
1238 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1239 generate_attach_increment(Clauses) :-
1240 get_max_constraint_index(N),
1242 Clauses = [Clause1,Clause2],
1243 generate_attach_increment_empty(Clause1),
1245 generate_attach_increment_one(Clause2)
1247 generate_attach_increment_many(N,Clause2)
1253 generate_attach_increment_empty((attach_increment([],_) :- true)).
1255 generate_attach_increment_one(Clause) :-
1256 Head = attach_increment([Var|Vars],Susps),
1257 get_target_module(Mod),
1260 'chr not_locked'(Var),
1261 ( get_attr(Var,Mod,VarSusps) ->
1262 sort(VarSusps,SortedVarSusps),
1263 merge(Susps,SortedVarSusps,MergedSusps),
1264 put_attr(Var,Mod,MergedSusps)
1266 put_attr(Var,Mod,Susps)
1268 attach_increment(Vars,Susps)
1270 Clause = (Head :- Body).
1272 generate_attach_increment_many(N,Clause) :-
1273 make_attr(N,Mask,SuspsList,Attr),
1274 make_attr(N,OtherMask,OtherSuspsList,OtherAttr),
1275 Head = attach_increment([Var|Vars],Attr),
1276 bagof(G,X ^ Y ^ SY ^ M ^ (member2(SuspsList,OtherSuspsList,X-Y),G = (sort(Y,SY),'chr merge_attributes'(X,SY,M))),Gs),
1277 list2conj(Gs,SortGoals),
1278 bagof(MS,A ^ B ^ C ^ member((A,'chr merge_attributes'(B,C,MS)),Gs), MergedSuspsList),
1279 make_attr(N,MergedMask,MergedSuspsList,NewAttr),
1280 get_target_module(Mod),
1283 'chr not_locked'(Var),
1284 ( get_attr(Var,Mod,TOtherAttr) ->
1285 TOtherAttr = OtherAttr,
1287 MergedMask is Mask \/ OtherMask,
1288 put_attr(Var,Mod,NewAttr)
1290 put_attr(Var,Mod,Attr)
1292 attach_increment(Vars,Attr)
1294 Clause = (Head :- Body).
1297 generate_attr_unify_hook([Clause]) :-
1298 get_max_constraint_index(N),
1300 get_target_module(Mod),
1302 ( attr_unify_hook(Attr,Var) :-
1303 write('ERROR: Unexpected triggering of attr_unify_hook/2 in module '),
1307 generate_attr_unify_hook_one(Clause)
1309 generate_attr_unify_hook_many(N,Clause)
1312 generate_attr_unify_hook_one(Clause) :-
1313 Head = attr_unify_hook(Susps,Other),
1314 get_target_module(Mod),
1315 make_run_suspensions(NewSusps,WakeNewSusps),
1316 make_run_suspensions(Susps,WakeSusps),
1319 sort(Susps, SortedSusps),
1321 ( get_attr(Other,Mod,OtherSusps) ->
1326 sort(OtherSusps,SortedOtherSusps),
1327 'chr merge_attributes'(SortedSusps,SortedOtherSusps,NewSusps),
1328 put_attr(Other,Mod,NewSusps),
1331 ( compound(Other) ->
1332 term_variables(Other,OtherVars),
1333 attach_increment(OtherVars, SortedSusps)
1340 Clause = (Head :- Body).
1342 generate_attr_unify_hook_many(N,Clause) :-
1343 make_attr(N,Mask,SuspsList,Attr),
1344 make_attr(N,OtherMask,OtherSuspsList,OtherAttr),
1345 bagof(Sort,A ^ B ^ ( member(A,SuspsList) , Sort = sort(A,B) ) , SortGoalList),
1346 list2conj(SortGoalList,SortGoals),
1347 bagof(B, A ^ member(sort(A,B),SortGoalList), SortedSuspsList),
1348 bagof(C, D ^ E ^ F ^ G ^ (member2(SortedSuspsList,OtherSuspsList,D-E),
1350 'chr merge_attributes'(D,F,G)) ),
1352 bagof(G, D ^ F ^ H ^ member((H,'chr merge_attributes'(D,F,G)),SortMergeGoalList) , MergedSuspsList),
1353 list2conj(SortMergeGoalList,SortMergeGoals),
1354 make_attr(N,MergedMask,MergedSuspsList,MergedAttr),
1355 make_attr(N,Mask,SortedSuspsList,SortedAttr),
1356 Head = attr_unify_hook(Attr,Other),
1357 get_target_module(Mod),
1358 make_run_suspensions_loop(MergedSuspsList,WakeMergedSusps),
1359 make_run_suspensions_loop(SortedSuspsList,WakeSortedSusps),
1364 ( get_attr(Other,Mod,TOtherAttr) ->
1365 TOtherAttr = OtherAttr,
1367 MergedMask is Mask \/ OtherMask,
1368 put_attr(Other,Mod,MergedAttr),
1371 put_attr(Other,Mod,SortedAttr),
1375 ( compound(Other) ->
1376 term_variables(Other,OtherVars),
1377 attach_increment(OtherVars,SortedAttr)
1384 Clause = (Head :- Body).
1386 make_run_suspensions(Susps,Goal) :-
1387 ( chr_pp_flag(debugable,on) ->
1388 Goal = 'chr run_suspensions_d'(Susps)
1390 Goal = 'chr run_suspensions'(Susps)
1393 make_run_suspensions_loop(SuspsList,Goal) :-
1394 ( chr_pp_flag(debugable,on) ->
1395 Goal = 'chr run_suspensions_loop_d'(SuspsList)
1397 Goal = 'chr run_suspensions_loop'(SuspsList)
1400 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1401 % $insert_in_store_F/A
1402 % $delete_from_store_F/A
1404 generate_insert_delete_constraints([],[]).
1405 generate_insert_delete_constraints([FA|Rest],Clauses) :-
1406 ( is_attached(FA) ->
1407 Clauses = [IClause,DClause|RestClauses],
1408 generate_insert_delete_constraint(FA,IClause,DClause)
1410 Clauses = RestClauses
1412 generate_insert_delete_constraints(Rest,RestClauses).
1414 generate_insert_delete_constraint(FA,IClause,DClause) :-
1415 get_store_type(FA,StoreType),
1416 generate_insert_constraint(StoreType,FA,IClause),
1417 generate_delete_constraint(StoreType,FA,DClause).
1419 generate_insert_constraint(StoreType,C,Clause) :-
1420 make_name('$insert_in_store_',C,ClauseName),
1421 Head =.. [ClauseName,Susp],
1422 generate_insert_constraint_body(StoreType,C,Susp,Body),
1423 Clause = (Head :- Body).
1425 generate_insert_constraint_body(default,C,Susp,Body) :-
1426 get_target_module(Mod),
1427 get_max_constraint_index(Total),
1429 generate_attach_body_1(C,Store,Susp,AttachBody)
1431 generate_attach_body_n(C,Store,Susp,AttachBody)
1435 'chr global_term_ref_1'(Store),
1438 generate_insert_constraint_body(multi_hash(Indexes),C,Susp,Body) :-
1439 generate_multi_hash_insert_constraint_bodies(Indexes,C,Susp,Body).
1440 generate_insert_constraint_body(global_ground,C,Susp,Body) :-
1441 global_ground_store_name(C,StoreName),
1444 nb_getval(StoreName,Store),
1445 b_setval(StoreName,[Susp|Store])
1447 generate_insert_constraint_body(multi_store(StoreTypes),C,Susp,Body) :-
1448 find_with_var_identity(
1452 member(ST,StoreTypes),
1453 chr_translate:generate_insert_constraint_body(ST,C,Susp,B)
1457 list2conj(Bodies,Body).
1459 generate_multi_hash_insert_constraint_bodies([],_,_,true).
1460 generate_multi_hash_insert_constraint_bodies([Index|Indexes],FA,Susp,(Body,Bodies)) :-
1461 multi_hash_store_name(FA,Index,StoreName),
1462 multi_hash_key(FA,Index,Susp,KeyBody,Key),
1466 nb_getval(StoreName,Store),
1467 insert_ht(Store,Key,Susp)
1469 generate_multi_hash_insert_constraint_bodies(Indexes,FA,Susp,Bodies).
1471 generate_delete_constraint(StoreType,FA,Clause) :-
1472 make_name('$delete_from_store_',FA,ClauseName),
1473 Head =.. [ClauseName,Susp],
1474 generate_delete_constraint_body(StoreType,FA,Susp,Body),
1475 Clause = (Head :- Body).
1477 generate_delete_constraint_body(default,C,Susp,Body) :-
1478 get_target_module(Mod),
1479 get_max_constraint_index(Total),
1481 generate_detach_body_1(C,Store,Susp,DetachBody),
1484 'chr global_term_ref_1'(Store),
1488 generate_detach_body_n(C,Store,Susp,DetachBody),
1491 'chr global_term_ref_1'(Store),
1495 generate_delete_constraint_body(multi_hash(Indexes),C,Susp,Body) :-
1496 generate_multi_hash_delete_constraint_bodies(Indexes,C,Susp,Body).
1497 generate_delete_constraint_body(global_ground,C,Susp,Body) :-
1498 global_ground_store_name(C,StoreName),
1501 nb_getval(StoreName,Store),
1502 'chr sbag_del_element'(Store,Susp,NStore),
1503 b_setval(StoreName,NStore)
1505 generate_delete_constraint_body(multi_store(StoreTypes),C,Susp,Body) :-
1506 find_with_var_identity(
1510 member(ST,StoreTypes),
1511 chr_translate:generate_delete_constraint_body(ST,C,Susp,B)
1515 list2conj(Bodies,Body).
1517 generate_multi_hash_delete_constraint_bodies([],_,_,true).
1518 generate_multi_hash_delete_constraint_bodies([Index|Indexes],FA,Susp,(Body,Bodies)) :-
1519 multi_hash_store_name(FA,Index,StoreName),
1520 multi_hash_key(FA,Index,Susp,KeyBody,Key),
1524 nb_getval(StoreName,Store),
1525 delete_ht(Store,Key,Susp)
1527 generate_multi_hash_delete_constraint_bodies(Indexes,FA,Susp,Bodies).
1529 generate_delete_constraint_call(FA,Susp,Call) :-
1530 make_name('$delete_from_store_',FA,Functor),
1531 Call =.. [Functor,Susp].
1533 generate_insert_constraint_call(FA,Susp,Call) :-
1534 make_name('$insert_in_store_',FA,Functor),
1535 Call =.. [Functor,Susp].
1537 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1539 generate_store_code(Constraints,[Enumerate|L]) :-
1540 enumerate_stores_code(Constraints,Enumerate),
1541 generate_store_code(Constraints,L,[]).
1543 generate_store_code([],L,L).
1544 generate_store_code([C|Cs],L,T) :-
1545 get_store_type(C,StoreType),
1546 generate_store_code(StoreType,C,L,L1),
1547 generate_store_code(Cs,L1,T).
1549 generate_store_code(default,_,L,L).
1550 generate_store_code(multi_hash(Indexes),C,L,T) :-
1551 multi_hash_store_initialisations(Indexes,C,L,L1),
1552 multi_hash_via_lookups(Indexes,C,L1,T).
1553 generate_store_code(global_ground,C,L,T) :-
1554 global_ground_store_initialisation(C,L,T).
1555 generate_store_code(multi_store(StoreTypes),C,L,T) :-
1556 multi_store_generate_store_code(StoreTypes,C,L,T).
1558 multi_store_generate_store_code([],_,L,L).
1559 multi_store_generate_store_code([ST|STs],C,L,T) :-
1560 generate_store_code(ST,C,L,L1),
1561 multi_store_generate_store_code(STs,C,L1,T).
1563 multi_hash_store_initialisations([],_,L,L).
1564 multi_hash_store_initialisations([Index|Indexes],FA,L,T) :-
1565 multi_hash_store_name(FA,Index,StoreName),
1566 L = [(:- (new_ht(HT),nb_setval(StoreName,HT)) )|L1],
1567 multi_hash_store_initialisations(Indexes,FA,L1,T).
1569 global_ground_store_initialisation(C,L,T) :-
1570 global_ground_store_name(C,StoreName),
1571 L = [(:- nb_setval(StoreName,[]))|T].
1573 multi_hash_via_lookups([],_,L,L).
1574 multi_hash_via_lookups([Index|Indexes],C,L,T) :-
1575 multi_hash_via_lookup_name(C,Index,PredName),
1576 Head =.. [PredName,Key,SuspsList],
1577 multi_hash_store_name(C,Index,StoreName),
1580 nb_getval(StoreName,HT),
1581 lookup_ht(HT,Key,SuspsList)
1583 L = [(Head :- Body)|L1],
1584 multi_hash_via_lookups(Indexes,C,L1,T).
1586 multi_hash_via_lookup_name(F/A,Index,Name) :-
1590 atom_concat_list(Index,IndexName)
1592 atom_concat_list(['$via1_multi_hash_',F,(/),A,'-',IndexName],Name).
1594 multi_hash_store_name(F/A,Index,Name) :-
1595 get_target_module(Mod),
1599 atom_concat_list(Index,IndexName)
1601 atom_concat_list(['$chr_store_multi_hash_',Mod,(:),F,(/),A,'-',IndexName],Name).
1603 multi_hash_key(F/A,Index,Susp,KeyBody,Key) :-
1604 ( ( integer(Index) ->
1610 KeyBody = arg(SuspIndex,Susp,Key)
1612 sort(Index,Indexes),
1613 find_with_var_identity(arg(J,Susp,KeyI)-KeyI,[Susp],(member(I,Indexes),J is I + 6),ArgKeyPairs),
1614 pairup(Bodies,Keys,ArgKeyPairs),
1616 list2conj(Bodies,KeyBody)
1619 multi_hash_key_args(Index,Head,KeyArgs) :-
1621 arg(Index,Head,Arg),
1624 sort(Index,Indexes),
1625 term_variables(Head,Vars),
1626 find_with_var_identity(Arg,Vars,(member(I,Indexes), arg(I,Head,Arg)),KeyArgs)
1629 global_ground_store_name(F/A,Name) :-
1630 get_target_module(Mod),
1631 atom_concat_list(['$chr_store_global_ground_',Mod,(:),F,(/),A],Name).
1632 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1633 enumerate_stores_code(Constraints,Clause) :-
1634 Head = '$enumerate_suspensions'(Susp),
1635 enumerate_store_bodies(Constraints,Susp,Bodies),
1636 list2disj(Bodies,Body),
1637 Clause = (Head :- Body).
1639 enumerate_store_bodies([],_,[]).
1640 enumerate_store_bodies([C|Cs],Susp,L) :-
1642 get_store_type(C,StoreType),
1643 enumerate_store_body(StoreType,C,Susp,B),
1648 enumerate_store_bodies(Cs,Susp,T).
1650 enumerate_store_body(default,C,Susp,Body) :-
1651 get_constraint_index(C,Index),
1652 get_target_module(Mod),
1653 get_max_constraint_index(MaxIndex),
1656 'chr global_term_ref_1'(GlobalStore),
1657 get_attr(GlobalStore,Mod,Attr)
1660 NIndex is Index + 1,
1663 arg(NIndex,Attr,List),
1664 'chr sbag_member'(Susp,List)
1667 Body2 = 'chr sbag_member'(Susp,Attr)
1669 Body = (Body1,Body2).
1670 enumerate_store_body(multi_hash([Index|_]),C,Susp,Body) :-
1671 multi_hash_enumerate_store_body(Index,C,Susp,Body).
1672 enumerate_store_body(global_ground,C,Susp,Body) :-
1673 global_ground_store_name(C,StoreName),
1676 nb_getval(StoreName,List),
1677 'chr sbag_member'(Susp,List)
1679 enumerate_store_body(multi_store(STs),C,Susp,Body) :-
1682 enumerate_store_body(ST,C,Susp,Body)
1685 multi_hash_enumerate_store_body(I,C,Susp,B) :-
1686 multi_hash_store_name(C,I,StoreName),
1689 nb_getval(StoreName,HT),
1692 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1693 check_attachments(Constraints) :-
1694 ( chr_pp_flag(check_attachments,on) ->
1695 check_constraint_attachments(Constraints)
1700 check_constraint_attachments([]).
1701 check_constraint_attachments([C|Cs]) :-
1702 check_constraint_attachment(C),
1703 check_constraint_attachments(Cs).
1705 check_constraint_attachment(C) :-
1706 get_max_occurrence(C,MO),
1707 check_occurrences_attachment(C,1,MO).
1709 check_occurrences_attachment(C,O,MO) :-
1713 check_occurrence_attachment(C,O),
1715 check_occurrences_attachment(C,NO,MO)
1718 check_occurrence_attachment(C,O) :-
1719 get_occurrence(C,O,RuleNb,ID),
1720 get_rule(RuleNb,PragmaRule),
1721 PragmaRule = pragma(rule(Heads1,Heads2,Guard,Body),ids(IDs1,IDs2),_,_,_),
1722 ( select2(ID,Head1,IDs1,Heads1,RIDs1,RHeads1) ->
1723 check_attachment_head1(Head1,ID,RuleNb,Heads1,Heads2,Guard)
1724 ; select2(ID,Head2,IDs2,Heads2,RIDs2,RHeads2) ->
1725 check_attachment_head2(Head2,ID,RuleNb,Heads1,Body)
1728 check_attachment_head1(C,ID,RuleNb,H1,H2,G) :-
1735 \+ is_passive(RuleNb,ID) ->
1742 no_matching([X|Xs],Prev) :-
1744 \+ memberchk_eq(X,Prev),
1745 no_matching(Xs,[X|Prev]).
1747 check_attachment_head2(C,ID,RuleNb,H1,B) :-
1749 ( is_passive(RuleNb,ID) ->
1759 all_attached([C|Cs]) :-
1764 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1766 set_constraint_indices([],M) :-
1768 max_constraint_index(N).
1769 set_constraint_indices([C|Cs],N) :-
1770 ( ( may_trigger(C) ; is_attached(C), get_store_type(C,default)) ->
1771 constraint_index(C,N),
1773 set_constraint_indices(Cs,M)
1775 set_constraint_indices(Cs,N)
1778 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1779 %% ____ _ ____ _ _ _ _
1780 %% | _ \ _ _| | ___ / ___|___ _ __ ___ _ __ (_) | __ _| |_(_) ___ _ __
1781 %% | |_) | | | | |/ _ \ | | / _ \| '_ ` _ \| '_ \| | |/ _` | __| |/ _ \| '_ \
1782 %% | _ <| |_| | | __/ | |__| (_) | | | | | | |_) | | | (_| | |_| | (_) | | | |
1783 %% |_| \_\\__,_|_|\___| \____\___/|_| |_| |_| .__/|_|_|\__,_|\__|_|\___/|_| |_|
1786 constraints_code(Constraints,Rules,Clauses) :-
1787 post_constraints(Constraints,1),
1788 constraints_code1(1,Rules,L,[]),
1789 clean_clauses(L,Clauses).
1792 post_constraints([],MaxIndex1) :-
1793 MaxIndex is MaxIndex1 - 1,
1794 constraint_count(MaxIndex).
1795 post_constraints([F/A|Cs],N) :-
1798 post_constraints(Cs,M).
1799 constraints_code1(I,Rules,L,T) :-
1800 get_constraint_count(N),
1804 constraint_code(I,Rules,L,T1),
1806 constraints_code1(J,Rules,T1,T)
1809 %% Generate code for a single CHR constraint
1810 constraint_code(I, Rules, L, T) :-
1811 get_constraint(Constraint,I),
1812 constraint_prelude(Constraint,Clause),
1815 rules_code(Rules,I,Id1,Id2,L1,L2),
1816 gen_cond_attach_clause(Constraint,Id2,L2,T).
1818 %% Generate prelude predicate for a constraint.
1819 %% f(...) :- f/a_0(...,Susp).
1820 constraint_prelude(F/A, Clause) :-
1821 vars_susp(A,Vars,Susp,VarsSusp),
1822 Head =.. [ F | Vars],
1823 build_head(F,A,[0],VarsSusp,Delegate),
1824 get_target_module(Mod),
1826 ( chr_pp_flag(debugable,on) ->
1829 allocate_constraint(Mod : Delegate, Susp, FTerm, Vars),
1831 'chr debug_event'(call(Susp)),
1834 'chr debug_event'(fail(Susp)), !,
1838 'chr debug_event'(exit(Susp))
1840 'chr debug_event'(redo(Susp)),
1845 Clause = ( Head :- Delegate )
1848 gen_cond_attach_clause(F/A,Id,L,T) :-
1849 ( is_attached(F/A) ->
1851 ( may_trigger(F/A) ->
1852 gen_cond_attach_goal(F/A,Body,AllArgs,Args,Susp)
1854 gen_insert_constraint_internal_goal(F/A,Body,AllArgs,Args,Susp)
1856 ; vars_susp(A,Args,Susp,AllArgs),
1857 gen_uncond_attach_goal(F/A,Susp,Body,_)
1859 ( chr_pp_flag(debugable,on) ->
1860 Constraint =.. [F|Args],
1861 DebugEvent = 'chr debug_event'(insert(Constraint#Susp))
1865 build_head(F,A,Id,AllArgs,Head),
1866 Clause = ( Head :- DebugEvent,Body ),
1872 gen_cond_attach_goal(F/A,Goal,AllArgs,Args,Susp) :-
1873 vars_susp(A,Args,Susp,AllArgs),
1874 build_head(F,A,[0],AllArgs,Closure),
1875 ( may_trigger(F/A) ->
1876 make_name('attach_',F/A,AttachF),
1877 Attach =.. [AttachF,Vars,Susp]
1881 get_target_module(Mod),
1883 generate_insert_constraint_call(F/A,Susp,InsertCall),
1887 insert_constraint_internal(Stored,Vars,Susp,Mod:Closure,FTerm,Args)
1889 activate_constraint(Stored,Vars,Susp,_)
1899 gen_insert_constraint_internal_goal(F/A,Goal,AllArgs,Args,Susp) :-
1900 vars_susp(A,Args,Susp,AllArgs),
1901 build_head(F,A,[0],AllArgs,Closure),
1902 ( may_trigger(F/A) ->
1903 make_name('attach_',F/A,AttachF),
1904 Attach =.. [AttachF,Vars,Susp]
1908 get_target_module(Mod),
1910 generate_insert_constraint_call(F/A,Susp,InsertCall),
1913 insert_constraint_internal(_,Vars,Susp,Mod:Closure,FTerm,Args),
1918 gen_uncond_attach_goal(FA,Susp,AttachGoal,Generation) :-
1919 ( may_trigger(FA) ->
1920 make_name('attach_',FA,AttachF),
1921 Attach =.. [AttachF,Vars,Susp]
1925 generate_insert_constraint_call(FA,Susp,InsertCall),
1928 activate_constraint(Stored,Vars, Susp, Generation),
1937 occurrences_code(O,MO,C,Id,NId,L,T) :-
1942 occurrence_code(O,C,Id,Id1,L,L1),
1944 occurrences_code(NO,MO,C,Id1,NId,L1,T)
1947 occurrences_code(O,C,Id,NId,L,T) :-
1948 get_occurrence(C,O,RuleNb,ID),
1949 ( is_passive(RuleNb,ID) ->
1953 get_rule(RuleNb,PragmaRule),
1954 PragmaRule = pragma(rule(Heads1,Heads2,_,_),ids(IDs1,IDs2),_,_,_),
1955 ( select2(IDs1,Heads1,ID,Head1,RIDs1,RHeads1) ->
1957 head1_code(Head1,RHeads1,RIDs1,PragmaRule,C,Id,L,T)
1958 ; select2(IDs2,Heads2,ID,Head2,RIDs2,RHeads2) ->
1959 length(RHeads2,RestHeadNb),
1960 head2_code(Head2,RHeads2,RIDs2,PragmaRule,RestHeadNb,C,Id,L,L1),
1962 gen_alloc_inc_clause(C,Id,L1,T)
1967 %% Generate all the code for a constraint based on all CHR rules
1968 rules_code([],_,Id,Id,L,L).
1969 rules_code([R |Rs],I,Id1,Id3,L,T) :-
1970 rule_code(R,I,Id1,Id2,L,T1),
1971 rules_code(Rs,I,Id2,Id3,T1,T).
1973 %% Generate code for a constraint based on a single CHR rule
1974 rule_code(PragmaRule,I,Id1,Id2,L,T) :-
1975 PragmaRule = pragma(Rule,HeadIDs,_Pragmas,_Name,_RuleNb),
1976 HeadIDs = ids(Head1IDs,Head2IDs),
1977 Rule = rule(Head1,Head2,_,_),
1978 heads1_code(Head1,[],Head1IDs,[],PragmaRule,I,Id1,L,L1),
1979 heads2_code(Head2,[],Head2IDs,[],PragmaRule,I,Id1,Id2,L1,T).
1981 %% Generate code based on all the removed heads of a CHR rule
1982 heads1_code([],_,_,_,_,_,_,L,L).
1983 heads1_code([Head|Heads],RestHeads,[HeadID|HeadIDs],RestIDs,PragmaRule,I,Id,L,T) :-
1984 PragmaRule = pragma(Rule,_,_Pragmas,_Name,RuleNb),
1985 get_constraint(F/A,I),
1986 ( functor(Head,F,A),
1987 \+ is_passive(RuleNb,HeadID),
1988 \+ check_unnecessary_active(Head,RestHeads,Rule),
1989 all_attached(Heads),
1990 all_attached(RestHeads),
1991 Rule = rule(_,Heads2,_,_),
1992 all_attached(Heads2) ->
1993 append(Heads,RestHeads,OtherHeads),
1994 append(HeadIDs,RestIDs,OtherIDs),
1995 head1_code(Head,OtherHeads,OtherIDs,PragmaRule,F/A,I,Id,L,L1)
1999 heads1_code(Heads,[Head|RestHeads],HeadIDs,[HeadID|RestIDs],PragmaRule,I,Id,L1,T).
2001 %% Generate code based on one removed head of a CHR rule
2002 head1_code(Head,OtherHeads,OtherIDs,PragmaRule,FA,I,Id,L,T) :-
2003 PragmaRule = pragma(Rule,_,_,_Name,RuleNb),
2004 Rule = rule(_,Head2,_,_),
2006 reorder_heads(RuleNb,Head,OtherHeads,OtherIDs,NOtherHeads,NOtherIDs),
2007 simplification_code(Head,NOtherHeads,NOtherIDs,PragmaRule,FA,Id,L,T)
2009 simpagation_head1_code(Head,OtherHeads,OtherIDs,PragmaRule,FA,Id,L,T)
2012 %% Generate code based on all the persistent heads of a CHR rule
2013 heads2_code([],_,_,_,_,_,Id,Id,L,L).
2014 heads2_code([Head|Heads],RestHeads,[HeadID|HeadIDs],RestIDs,PragmaRule,I,Id1,Id3,L,T) :-
2015 PragmaRule = pragma(Rule,_,_Pragmas,_Name,RuleNb),
2016 get_constraint(F/A,I),
2017 ( functor(Head,F,A),
2018 \+ is_passive(RuleNb,HeadID),
2019 \+ check_unnecessary_active(Head,RestHeads,Rule),
2020 \+ set_semantics_rule(PragmaRule),
2021 all_attached(Heads),
2022 all_attached(RestHeads),
2023 Rule = rule(Heads1,_,_,_),
2024 all_attached(Heads1) ->
2025 append(Heads,RestHeads,OtherHeads),
2026 append(HeadIDs,RestIDs,OtherIDs),
2027 length(Heads,RestHeadNb),
2028 head2_code(Head,OtherHeads,OtherIDs,PragmaRule,RestHeadNb,F/A,Id1,L,L0),
2030 gen_alloc_inc_clause(F/A,Id1,L0,L1)
2035 heads2_code(Heads,[Head|RestHeads],HeadIDs,[HeadID|RestIDs],PragmaRule,I,Id2,Id3,L1,T).
2037 %% Generate code based on one persistent head of a CHR rule
2038 head2_code(Head,OtherHeads,OtherIDs,PragmaRule,RestHeadNb,FA,Id,L,T) :-
2039 PragmaRule = pragma(Rule,_,_,_Name,RuleNb),
2040 Rule = rule(Head1,_,_,_),
2042 reorder_heads(RuleNb,Head,OtherHeads,OtherIDs,NOtherHeads,_),
2043 propagation_code(Head,NOtherHeads,Rule,RuleNb,RestHeadNb,FA,Id,L,T)
2045 simpagation_head2_code(Head,OtherHeads,OtherIDs,PragmaRule,FA,Id,L,T)
2048 gen_alloc_inc_clause(F/A,Id,L,T) :-
2049 vars_susp(A,Vars,Susp,VarsSusp),
2050 build_head(F,A,Id,VarsSusp,Head),
2052 build_head(F,A,IncId,VarsSusp,CallHead),
2053 gen_allocation(Id,Vars,Susp,F/A,VarsSusp,ConditionalAlloc),
2062 gen_cond_allocation(Vars,Susp,FA,VarsSusp,ConstraintAllocationGoal) :-
2063 gen_allocation(Vars,Susp,FA,VarsSusp,UncondConstraintAllocationGoal),
2064 ConstraintAllocationGoal =
2066 UncondConstraintAllocationGoal
2070 gen_allocation(Vars,Susp,F/A,VarsSusp,ConstraintAllocationGoal) :-
2071 build_head(F,A,[0],VarsSusp,Term),
2072 get_target_module(Mod),
2074 ConstraintAllocationGoal = allocate_constraint(Mod : Term, Susp, FTerm, Vars).
2076 gen_allocation(Id,Vars,Susp,FA,VarsSusp,ConstraintAllocationGoal) :-
2078 ( is_attached(FA) ->
2079 ( may_trigger(FA) ->
2080 gen_cond_allocation(Vars,Susp,FA,VarsSusp,ConstraintAllocationGoal)
2082 gen_allocation(Vars,Susp,FA,VarsSusp,ConstraintAllocationGoal)
2085 ConstraintAllocationGoal = true
2088 ConstraintAllocationGoal = true
2090 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2093 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2095 guard_via_reschedule(Retrievals,GuardList,Prelude,Goal) :-
2096 ( chr_pp_flag(guard_via_reschedule,on) ->
2097 guard_via_reschedule_main(Retrievals,GuardList,Prelude,Goal)
2099 append(Retrievals,GuardList,GoalList),
2100 list2conj(GoalList,Goal)
2103 guard_via_reschedule_main(Retrievals,GuardList,Prelude,Goal) :-
2104 initialize_unit_dictionary(Prelude,Dict),
2105 build_units(Retrievals,GuardList,Dict,Units),
2106 dependency_reorder(Units,NUnits),
2107 units2goal(NUnits,Goal).
2109 units2goal([],true).
2110 units2goal([unit(_,Goal,_,_)|Units],(Goal,Goals)) :-
2111 units2goal(Units,Goals).
2113 dependency_reorder(Units,NUnits) :-
2114 dependency_reorder(Units,[],NUnits).
2116 dependency_reorder([],Acc,Result) :-
2117 reverse(Acc,Result).
2119 dependency_reorder([Unit|Units],Acc,Result) :-
2120 Unit = unit(_GID,_Goal,Type,GIDs),
2124 dependency_insert(Acc,Unit,GIDs,NAcc)
2126 dependency_reorder(Units,NAcc,Result).
2128 dependency_insert([],Unit,_,[Unit]).
2129 dependency_insert([X|Xs],Unit,GIDs,L) :-
2130 X = unit(GID,_,_,_),
2131 ( memberchk(GID,GIDs) ->
2135 dependency_insert(Xs,Unit,GIDs,T)
2138 build_units(Retrievals,Guard,InitialDict,Units) :-
2139 build_retrieval_units(Retrievals,1,N,InitialDict,Dict,Units,Tail),
2140 build_guard_units(Guard,N,Dict,Tail).
2142 build_retrieval_units([],N,N,Dict,Dict,L,L).
2143 build_retrieval_units([U|Us],N,M,Dict,NDict,L,T) :-
2144 term_variables(U,Vs),
2145 update_unit_dictionary(Vs,N,Dict,Dict1,[],GIDs),
2146 L = [unit(N,U,movable,GIDs)|L1],
2148 build_retrieval_units2(Us,N1,M,Dict1,NDict,L1,T).
2150 build_retrieval_units2([],N,N,Dict,Dict,L,L).
2151 build_retrieval_units2([U|Us],N,M,Dict,NDict,L,T) :-
2152 term_variables(U,Vs),
2153 update_unit_dictionary(Vs,N,Dict,Dict1,[],GIDs),
2154 L = [unit(N,U,fixed,GIDs)|L1],
2156 build_retrieval_units(Us,N1,M,Dict1,NDict,L1,T).
2158 initialize_unit_dictionary(Term,Dict) :-
2159 term_variables(Term,Vars),
2160 pair_all_with(Vars,0,Dict).
2162 update_unit_dictionary([],_,Dict,Dict,GIDs,GIDs).
2163 update_unit_dictionary([V|Vs],This,Dict,NDict,GIDs,NGIDs) :-
2164 ( lookup_eq(Dict,V,GID) ->
2165 ( (GID == This ; memberchk(GID,GIDs) ) ->
2172 Dict1 = [V - This|Dict],
2175 update_unit_dictionary(Vs,This,Dict1,NDict,GIDs1,NGIDs).
2177 build_guard_units(Guard,N,Dict,Units) :-
2179 Units = [unit(N,Goal,fixed,[])]
2180 ; Guard = [Goal|Goals] ->
2181 term_variables(Goal,Vs),
2182 update_unit_dictionary2(Vs,N,Dict,NDict,[],GIDs),
2183 Units = [unit(N,Goal,movable,GIDs)|RUnits],
2185 build_guard_units(Goals,N1,NDict,RUnits)
2188 update_unit_dictionary2([],_,Dict,Dict,GIDs,GIDs).
2189 update_unit_dictionary2([V|Vs],This,Dict,NDict,GIDs,NGIDs) :-
2190 ( lookup_eq(Dict,V,GID) ->
2191 ( (GID == This ; memberchk(GID,GIDs) ) ->
2196 Dict1 = [V - This|Dict]
2198 Dict1 = [V - This|Dict],
2201 update_unit_dictionary2(Vs,This,Dict1,NDict,GIDs1,NGIDs).
2203 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2205 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2207 %% / ___| ___| |_ / ___| ___ _ __ ___ __ _ _ __ | |_(_) ___ ___ _
2208 %% \___ \ / _ \ __| \___ \ / _ \ '_ ` _ \ / _` | '_ \| __| |/ __/ __(_)
2209 %% ___) | __/ |_ ___) | __/ | | | | | (_| | | | | |_| | (__\__ \_
2210 %% |____/ \___|\__| |____/ \___|_| |_| |_|\__,_|_| |_|\__|_|\___|___(_)
2213 %% | | | |_ __ (_) __ _ _ _ ___ |_ _|_ __ / _| ___ _ __ ___ _ __ ___ ___
2214 %% | | | | '_ \| |/ _` | | | |/ _ \ | || '_ \| |_ / _ \ '__/ _ \ '_ \ / __/ _ \
2215 %% | |_| | | | | | (_| | |_| | __/ | || | | | _| __/ | | __/ | | | (_| __/
2216 %% \___/|_| |_|_|\__, |\__,_|\___| |___|_| |_|_| \___|_| \___|_| |_|\___\___|
2218 unique_analyse_optimise(Rules,NRules) :-
2219 ( chr_pp_flag(unique_analyse_optimise,on) ->
2220 unique_analyse_optimise_main(Rules,1,[],NRules)
2225 unique_analyse_optimise_main([],_,_,[]).
2226 unique_analyse_optimise_main([PRule|PRules],N,PatternList,[NPRule|NPRules]) :-
2227 ( discover_unique_pattern(PRule,N,Pattern) ->
2228 NPatternList = [Pattern|PatternList]
2230 NPatternList = PatternList
2232 PRule = pragma(Rule,Ids,Pragmas,Name,RuleNb),
2233 Rule = rule(H1,H2,_,_),
2234 Ids = ids(Ids1,Ids2),
2235 apply_unique_patterns_to_constraints(H1,Ids1,NPatternList,MorePragmas1),
2236 apply_unique_patterns_to_constraints(H2,Ids2,NPatternList,MorePragmas2),
2237 globalize_unique_pragmas(MorePragmas1,RuleNb),
2238 globalize_unique_pragmas(MorePragmas2,RuleNb),
2239 append_lists([MorePragmas1,MorePragmas2,Pragmas],NPragmas),
2240 NPRule = pragma(Rule,Ids,NPragmas,Name,RuleNb),
2242 unique_analyse_optimise_main(PRules,N1,NPatternList,NPRules).
2244 globalize_unique_pragmas([],_).
2245 globalize_unique_pragmas([unique(ID,Vars)|R],RuleNb) :-
2246 pragma_unique(RuleNb,ID,Vars),
2247 globalize_unique_pragmas(R,RuleNb).
2249 apply_unique_patterns_to_constraints([],_,_,[]).
2250 apply_unique_patterns_to_constraints([C|Cs],[Id|Ids],Patterns,Pragmas) :-
2251 ( member(Pattern,Patterns),
2252 apply_unique_pattern(C,Id,Pattern,Pragma) ->
2253 Pragmas = [Pragma | RPragmas]
2257 apply_unique_patterns_to_constraints(Cs,Ids,Patterns,RPragmas).
2259 apply_unique_pattern(Constraint,Id,Pattern,Pragma) :-
2260 Pattern = unique(PatternConstraint,PatternKey),
2261 subsumes(Constraint,PatternConstraint,Unifier),
2264 member(T,PatternKey),
2265 lookup_eq(Unifier,T,Term),
2266 term_variables(Term,Vs),
2274 Pragma = unique(Id,Vars).
2276 % subsumes(+Term1, +Term2, -Unifier)
2278 % If Term1 is a more general term than Term2 (e.g. has a larger
2279 % part instantiated), unify Unifier with a list Var-Value of
2280 % variables from Term2 and their corresponding values in Term1.
2282 subsumes(Term1,Term2,Unifier) :-
2284 subsumes_aux(Term1,Term2,S0,S),
2286 build_unifier(L,Unifier).
2288 subsumes_aux(Term1, Term2, S0, S) :-
2290 functor(Term2, F, N)
2291 -> compound(Term1), functor(Term1, F, N),
2292 subsumes_aux(N, Term1, Term2, S0, S)
2296 get_assoc(Term1,S0,V)
2297 -> V == Term2, S = S0
2299 put_assoc(Term1, S0, Term2, S)
2302 subsumes_aux(0, _, _, S, S) :- ! .
2303 subsumes_aux(N, T1, T2, S0, S) :-
2306 subsumes_aux(T1x, T2x, S0, S1),
2308 subsumes_aux(M, T1, T2, S1, S).
2310 build_unifier([],[]).
2311 build_unifier([X-V|R],[V - X | T]) :-
2314 discover_unique_pattern(PragmaRule,RuleNb,Pattern) :-
2315 PragmaRule = pragma(Rule,_,_Pragmas,Name,RuleNb),
2316 Rule = rule(H1,H2,Guard,_),
2324 check_unique_constraints(C1,C2,Guard,RuleNb,List),
2325 term_variables(C1,Vs),
2326 select_pragma_unique_variables(List,Vs,Key),
2327 Pattern0 = unique(C1,Key),
2328 copy_term(Pattern0,Pattern),
2329 ( prolog_flag(verbose,V), V == yes ->
2330 format('Found unique pattern ~w in rule ~d~@\n',
2331 [Pattern,RuleNb,(Name=yes(N) -> write(": "),write(N) ; true)])
2336 select_pragma_unique_variables([],_,[]).
2337 select_pragma_unique_variables([X-Y|R],Vs,L) :-
2342 \+ memberchk_eq(X,Vs)
2344 \+ memberchk_eq(Y,Vs)
2348 select_pragma_unique_variables(R,Vs,T).
2350 check_unique_constraints(C1,C2,G,RuleNb,List) :-
2351 \+ any_passive_head(RuleNb),
2352 variable_replacement(C1-C2,C2-C1,List),
2353 copy_with_variable_replacement(G,OtherG,List),
2355 once(entails_b(NotG,OtherG)).
2357 check_unnecessary_active(Constraint,Previous,Rule) :-
2358 ( chr_pp_flag(check_unnecessary_active,full) ->
2359 check_unnecessary_active_main(Constraint,Previous,Rule)
2360 ; chr_pp_flag(check_unnecessary_active,simplification),
2361 Rule = rule(_,[],_,_) ->
2362 check_unnecessary_active_main(Constraint,Previous,Rule)
2367 check_unnecessary_active_main(Constraint,Previous,Rule) :-
2368 member(Other,Previous),
2369 variable_replacement(Other,Constraint,List),
2370 copy_with_variable_replacement(Rule,Rule2,List),
2371 identical_rules(Rule,Rule2), ! .
2373 set_semantics_rule(PragmaRule) :-
2374 ( chr_pp_flag(set_semantics_rule,on) ->
2375 set_semantics_rule_main(PragmaRule)
2380 set_semantics_rule_main(PragmaRule) :-
2381 PragmaRule = pragma(Rule,IDs,Pragmas,_,RuleNb),
2382 Rule = rule([C1],[C2],true,_),
2383 IDs = ids([ID1],[ID2]),
2384 once(member(unique(ID1,L1),Pragmas)),
2385 once(member(unique(ID2,L2),Pragmas)),
2387 \+ is_passive(RuleNb,ID1).
2388 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2390 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2392 %% | _ \ _ _| | ___ | ____|__ _ _ _(_)_ ____ _| | ___ _ __ ___ ___
2393 %% | |_) | | | | |/ _ \ | _| / _` | | | | \ \ / / _` | |/ _ \ '_ \ / __/ _ \
2394 %% | _ <| |_| | | __/ | |__| (_| | |_| | |\ V / (_| | | __/ | | | (_| __/
2395 %% |_| \_\\__,_|_|\___| |_____\__, |\__,_|_| \_/ \__,_|_|\___|_| |_|\___\___|
2397 % have to check for no duplicates in value list
2399 % check wether two rules are identical
2401 identical_rules(rule(H11,H21,G1,B1),rule(H12,H22,G2,B2)) :-
2403 identical_bodies(B1,B2),
2404 permutation(H11,P1),
2406 permutation(H21,P2),
2409 identical_bodies(B1,B2) :-
2421 % replace variables in list
2423 copy_with_variable_replacement(X,Y,L) :-
2425 ( lookup_eq(L,X,Y) ->
2433 copy_with_variable_replacement_l(XArgs,YArgs,L)
2436 copy_with_variable_replacement_l([],[],_).
2437 copy_with_variable_replacement_l([X|Xs],[Y|Ys],L) :-
2438 copy_with_variable_replacement(X,Y,L),
2439 copy_with_variable_replacement_l(Xs,Ys,L).
2441 %% build variable replacement list
2443 variable_replacement(X,Y,L) :-
2444 variable_replacement(X,Y,[],L).
2446 variable_replacement(X,Y,L1,L2) :-
2449 ( lookup_eq(L1,X,Z) ->
2457 variable_replacement_l(XArgs,YArgs,L1,L2)
2460 variable_replacement_l([],[],L,L).
2461 variable_replacement_l([X|Xs],[Y|Ys],L1,L3) :-
2462 variable_replacement(X,Y,L1,L2),
2463 variable_replacement_l(Xs,Ys,L2,L3).
2464 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2466 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2467 %% ____ _ _ _ __ _ _ _
2468 %% / ___|(_)_ __ ___ _ __ | (_)/ _(_) ___ __ _| |_(_) ___ _ __
2469 %% \___ \| | '_ ` _ \| '_ \| | | |_| |/ __/ _` | __| |/ _ \| '_ \
2470 %% ___) | | | | | | | |_) | | | _| | (_| (_| | |_| | (_) | | | |
2471 %% |____/|_|_| |_| |_| .__/|_|_|_| |_|\___\__,_|\__|_|\___/|_| |_|
2474 simplification_code(Head,RestHeads,RestIDs,PragmaRule,F/A,Id,L,T) :-
2475 PragmaRule = pragma(Rule,_,Pragmas,_,_RuleNb),
2476 head_info(Head,A,_Vars,Susp,HeadVars,HeadPairs),
2477 build_head(F,A,Id,HeadVars,ClauseHead),
2478 head_arg_matches(HeadPairs,[],FirstMatching,VarDict1),
2480 ( RestHeads == [] ->
2485 rest_heads_retrieval_and_matching(RestHeads,RestIDs,Pragmas,Head,GetRestHeads,Susps,VarDict1,VarDict)
2488 guard_body_copies2(Rule,VarDict,GuardCopyList,BodyCopy),
2489 guard_via_reschedule(GetRestHeads,GuardCopyList,ClauseHead-FirstMatching,RescheduledTest),
2491 gen_uncond_susps_detachments(Susps,RestHeads,SuspsDetachments),
2492 gen_cond_susp_detachment(Id,Susp,F/A,SuspDetachment),
2494 ( chr_pp_flag(debugable,on) ->
2495 Rule = rule(_,_,Guard,Body),
2496 my_term_copy(Guard - Body, VarDict, _, DebugGuard - DebugBody),
2497 DebugTry = 'chr debug_event'( try([Susp|RestSusps],[],DebugGuard,DebugBody)),
2498 DebugApply = 'chr debug_event'(apply([Susp|RestSusps],[],DebugGuard,DebugBody))
2504 Clause = ( ClauseHead :-
2516 head_arg_matches(Pairs,VarDict,Goal,NVarDict) :-
2517 head_arg_matches_(Pairs,VarDict,GoalList,NVarDict),
2518 list2conj(GoalList,Goal).
2520 head_arg_matches_([],VarDict,[],VarDict).
2521 head_arg_matches_([Arg-Var| Rest],VarDict,GoalList,NVarDict) :-
2523 ( lookup_eq(VarDict,Arg,OtherVar) ->
2524 GoalList = [Var == OtherVar | RestGoalList],
2526 ; VarDict1 = [Arg-Var | VarDict],
2527 GoalList = RestGoalList
2531 GoalList = [ Var == Arg | RestGoalList],
2536 functor(Term,Fct,N),
2538 GoalList =[ nonvar(Var), Var = Term | RestGoalList ],
2539 pairup(Args,Vars,NewPairs),
2540 append(NewPairs,Rest,Pairs),
2543 head_arg_matches_(Pairs,VarDict1,RestGoalList,NVarDict).
2545 rest_heads_retrieval_and_matching(Heads,IDs,Pragmas,ActiveHead,GoalList,Susps,VarDict,NVarDict):-
2546 rest_heads_retrieval_and_matching(Heads,IDs,Pragmas,ActiveHead,GoalList,Susps,VarDict,NVarDict,[],[],[]).
2548 rest_heads_retrieval_and_matching(Heads,IDs,Pragmas,ActiveHead,GoalList,Susps,VarDict,NVarDict,PrevHs,PrevSusps,AttrDict) :-
2550 rest_heads_retrieval_and_matching_n(Heads,IDs,Pragmas,PrevHs,PrevSusps,ActiveHead,GoalList,Susps,VarDict,NVarDict,AttrDict)
2557 rest_heads_retrieval_and_matching_n([],_,_,_,_,_,[],[],VarDict,VarDict,AttrDict) :-
2558 instantiate_pattern_goals(AttrDict).
2559 rest_heads_retrieval_and_matching_n([H|Hs],[ID|IDs],Pragmas,PrevHs,PrevSusps,ActiveHead,[ViaGoal,Goal|Goals],[Susp|Susps],VarDict,NVarDict,AttrDict) :-
2561 get_store_type(F/A,StoreType),
2562 ( StoreType == default ->
2563 passive_head_via(H,[ActiveHead|PrevHs],AttrDict,VarDict,ViaGoal,Attr,NewAttrDict),
2564 get_max_constraint_index(N),
2568 get_constraint_index(F/A,Pos),
2569 make_attr(N,_Mask,SuspsList,Attr),
2570 nth(Pos,SuspsList,VarSusps)
2573 lookup_passive_head(StoreType,H,[ActiveHead|PrevHs],VarDict,ViaGoal,VarSusps),
2574 NewAttrDict = AttrDict
2576 head_info(H,A,Vars,_,_,Pairs),
2577 head_arg_matches(Pairs,VarDict,MatchingGoal,VarDict1),
2578 Suspension =.. [suspension,_,State,_,_,_,_|Vars],
2579 different_from_other_susps(H,Susp,PrevHs,PrevSusps,DiffSuspGoals),
2580 create_get_mutable(active,State,GetMutable),
2583 'chr sbag_member'(Susp,VarSusps),
2589 ( member(unique(ID,UniqueKeus),Pragmas),
2590 check_unique_keys(UniqueKeus,VarDict) ->
2591 Goal = (Goal1 -> true)
2595 rest_heads_retrieval_and_matching_n(Hs,IDs,Pragmas,[H|PrevHs],[Susp|PrevSusps],ActiveHead,Goals,Susps,VarDict1,NVarDict,NewAttrDict).
2597 instantiate_pattern_goals([]).
2598 instantiate_pattern_goals([_-attr(Attr,Bits,Goal)|Rest]) :-
2599 get_max_constraint_index(N),
2603 make_attr(N,Mask,_,Attr),
2604 or_list(Bits,Pattern), !,
2605 Goal = (Mask /\ Pattern =:= Pattern)
2607 instantiate_pattern_goals(Rest).
2610 check_unique_keys([],_).
2611 check_unique_keys([V|Vs],Dict) :-
2612 lookup_eq(Dict,V,_),
2613 check_unique_keys(Vs,Dict).
2615 % Generates tests to ensure the found constraint differs from previously found constraints
2616 % TODO: detect more cases where constraints need be different
2617 different_from_other_susps(Head,Susp,Heads,Susps,DiffSuspGoals) :-
2618 ( bagof(DiffSuspGoal, Pos ^ ( nth(Pos,Heads,PreHead), \+ Head \= PreHead, nth(Pos,Susps,PreSusp), DiffSuspGoal = (Susp \== PreSusp) ),DiffSuspGoalList) ->
2619 list2conj(DiffSuspGoalList,DiffSuspGoals)
2621 DiffSuspGoals = true
2624 passive_head_via(Head,PrevHeads,AttrDict,VarDict,Goal,Attr,NewAttrDict) :-
2626 get_constraint_index(F/A,Pos),
2627 common_variables(Head,PrevHeads,CommonVars),
2628 translate(CommonVars,VarDict,Vars),
2629 or_pattern(Pos,Bit),
2630 ( permutation(Vars,PermutedVars),
2631 lookup_eq(AttrDict,PermutedVars,attr(Attr,Positions,_)) ->
2632 member(Bit,Positions), !,
2633 NewAttrDict = AttrDict,
2636 Goal = (Goal1, PatternGoal),
2637 gen_get_mod_constraints(Vars,Goal1,Attr),
2638 NewAttrDict = [Vars - attr(Attr,[Bit|_],PatternGoal) | AttrDict]
2641 common_variables(T,Ts,Vs) :-
2642 term_variables(T,V1),
2643 term_variables(Ts,V2),
2644 intersect_eq(V1,V2,Vs).
2646 gen_get_mod_constraints(L,Goal,Susps) :-
2647 get_target_module(Mod),
2650 ( 'chr global_term_ref_1'(Global),
2651 get_attr(Global,Mod,TSusps),
2656 VIA = 'chr via_1'(A,V)
2658 VIA = 'chr via_2'(A,B,V)
2659 ; VIA = 'chr via'(L,V)
2664 get_attr(V,Mod,TSusps),
2669 guard_body_copies(Rule,VarDict,GuardCopy,BodyCopy) :-
2670 guard_body_copies2(Rule,VarDict,GuardCopyList,BodyCopy),
2671 list2conj(GuardCopyList,GuardCopy).
2673 guard_body_copies2(Rule,VarDict,GuardCopyList,BodyCopy) :-
2674 Rule = rule(_,_,Guard,Body),
2675 conj2list(Guard,GuardList),
2676 split_off_simple_guard(GuardList,VarDict,GuardPrefix,RestGuardList),
2677 my_term_copy(GuardPrefix-RestGuardList,VarDict,VarDict2,GuardPrefixCopy-RestGuardListCopyCore),
2679 append(GuardPrefixCopy,[RestGuardCopy],GuardCopyList),
2680 term_variables(RestGuardList,GuardVars),
2681 term_variables(RestGuardListCopyCore,GuardCopyVars),
2682 ( chr_pp_flag(guard_locks,on),
2683 bagof(('chr lock'(Y)) - ('chr unlock'(Y)),
2684 X ^ (member(X,GuardVars), % X is a variable appearing in the original guard
2685 lookup_eq(VarDict,X,Y), % translate X into new variable
2686 memberchk_eq(Y,GuardCopyVars) % redundant check? or multiple entries for X possible?
2689 once(pairup(Locks,Unlocks,LocksUnlocks))
2694 list2conj(Locks,LockPhase),
2695 list2conj(Unlocks,UnlockPhase),
2696 list2conj(RestGuardListCopyCore,RestGuardCopyCore),
2697 RestGuardCopy = (LockPhase,(RestGuardCopyCore,UnlockPhase)),
2698 my_term_copy(Body,VarDict2,BodyCopy).
2701 split_off_simple_guard([],_,[],[]).
2702 split_off_simple_guard([G|Gs],VarDict,S,C) :-
2703 ( simple_guard(G,VarDict) ->
2705 split_off_simple_guard(Gs,VarDict,Ss,C)
2711 % simple guard: cheap and benign (does not bind variables)
2712 simple_guard(G,VarDict) :-
2714 \+ (( member(V,Vars),
2715 lookup_eq(VarDict,V,_)
2718 my_term_copy(X,Dict,Y) :-
2719 my_term_copy(X,Dict,_,Y).
2721 my_term_copy(X,Dict1,Dict2,Y) :-
2723 ( lookup_eq(Dict1,X,Y) ->
2725 ; Dict2 = [X-Y|Dict1]
2731 my_term_copy_list(XArgs,Dict1,Dict2,YArgs)
2734 my_term_copy_list([],Dict,Dict,[]).
2735 my_term_copy_list([X|Xs],Dict1,Dict3,[Y|Ys]) :-
2736 my_term_copy(X,Dict1,Dict2,Y),
2737 my_term_copy_list(Xs,Dict2,Dict3,Ys).
2739 gen_cond_susp_detachment(Id,Susp,FA,SuspDetachment) :-
2740 ( is_attached(FA) ->
2741 ( Id == [0], \+ may_trigger(FA) ->
2742 SuspDetachment = true
2744 gen_uncond_susp_detachment(Susp,FA,UnCondSuspDetachment),
2748 ; UnCondSuspDetachment
2752 SuspDetachment = true
2755 gen_uncond_susp_detachment(Susp,FA,SuspDetachment) :-
2756 ( is_attached(FA) ->
2757 ( may_trigger(FA) ->
2758 make_name('detach_',FA,Fct),
2759 Detach =.. [Fct,Vars,Susp]
2763 ( chr_pp_flag(debugable,on) ->
2764 DebugEvent = 'chr debug_event'(remove(Susp))
2768 generate_delete_constraint_call(FA,Susp,DeleteCall),
2772 remove_constraint_internal(Susp, Vars, Delete),
2781 SuspDetachment = true
2784 gen_uncond_susps_detachments([],[],true).
2785 gen_uncond_susps_detachments([Susp|Susps],[Term|Terms],(SuspDetachment,SuspsDetachments)) :-
2787 gen_uncond_susp_detachment(Susp,F/A,SuspDetachment),
2788 gen_uncond_susps_detachments(Susps,Terms,SuspsDetachments).
2790 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2792 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2794 %% / ___|(_)_ __ ___ _ __ __ _ __ _ __ _| |_(_) ___ _ __ / |
2795 %% \___ \| | '_ ` _ \| '_ \ / _` |/ _` |/ _` | __| |/ _ \| '_ \ | |
2796 %% ___) | | | | | | | |_) | (_| | (_| | (_| | |_| | (_) | | | | | |
2797 %% |____/|_|_| |_| |_| .__/ \__,_|\__, |\__,_|\__|_|\___/|_| |_| |_|
2800 simpagation_head1_code(Head,RestHeads,OtherIDs,PragmaRule,F/A,Id,L,T) :-
2801 PragmaRule = pragma(Rule,ids(_,Heads2IDs),Pragmas,_Name,RuleNb),
2802 Rule = rule(_Heads,Heads2,Guard,Body),
2804 head_info(Head,A,_Vars,Susp,HeadVars,HeadPairs),
2805 head_arg_matches(HeadPairs,[],FirstMatching,VarDict1),
2807 build_head(F,A,Id,HeadVars,ClauseHead),
2809 append(RestHeads,Heads2,Heads),
2810 append(OtherIDs,Heads2IDs,IDs),
2811 reorder_heads(RuleNb,Head,Heads,IDs,NHeads,NIDs),
2812 rest_heads_retrieval_and_matching(NHeads,NIDs,Pragmas,Head,GetRestHeads,Susps,VarDict1,VarDict),
2813 split_by_ids(NIDs,Susps,OtherIDs,Susps1,Susps2),
2815 guard_body_copies2(Rule,VarDict,GuardCopyList,BodyCopy),
2816 guard_via_reschedule(GetRestHeads,GuardCopyList,ClauseHead-FirstMatching,RescheduledTest),
2818 gen_uncond_susps_detachments(Susps1,RestHeads,SuspsDetachments),
2819 gen_cond_susp_detachment(Id,Susp,F/A,SuspDetachment),
2821 ( chr_pp_flag(debugable,on) ->
2822 my_term_copy(Guard - Body, VarDict, _, DebugGuard - DebugBody),
2823 DebugTry = 'chr debug_event'( try([Susp|Susps1],Susps2,DebugGuard,DebugBody)),
2824 DebugApply = 'chr debug_event'(apply([Susp|Susps1],Susps2,DebugGuard,DebugBody))
2830 Clause = ( ClauseHead :-
2842 split_by_ids([],[],_,[],[]).
2843 split_by_ids([I|Is],[S|Ss],I1s,S1s,S2s) :-
2844 ( memberchk_eq(I,I1s) ->
2851 split_by_ids(Is,Ss,I1s,R1s,R2s).
2853 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2856 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2858 %% / ___|(_)_ __ ___ _ __ __ _ __ _ __ _| |_(_) ___ _ __ |___ \
2859 %% \___ \| | '_ ` _ \| '_ \ / _` |/ _` |/ _` | __| |/ _ \| '_ \ __) |
2860 %% ___) | | | | | | | |_) | (_| | (_| | (_| | |_| | (_) | | | | / __/
2861 %% |____/|_|_| |_| |_| .__/ \__,_|\__, |\__,_|\__|_|\___/|_| |_| |_____|
2864 %% Genereate prelude + worker predicate
2865 %% prelude calls worker
2866 %% worker iterates over one type of removed constraints
2867 simpagation_head2_code(Head2,RestHeads2,RestIDs,PragmaRule,FA,Id,L,T) :-
2868 PragmaRule = pragma(Rule,ids(IDs1,_),Pragmas,_Name,RuleNb),
2869 Rule = rule(Heads1,_,Guard,Body),
2870 reorder_heads(RuleNb,Head2,Heads1,IDs1,[Head1|RestHeads1],[ID1|RestIDs1]), % Heads1 = [Head1|RestHeads1],
2871 % IDs1 = [ID1|RestIDs1],
2872 simpagation_head2_prelude(Head2,Head1,[RestHeads2,Heads1,Guard,Body],FA,Id,L,L1),
2874 simpagation_head2_worker(Head2,Head1,ID1,RestHeads1,RestIDs1,RestHeads2,RestIDs,PragmaRule,FA,Id2,L1,T).
2876 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2877 simpagation_head2_prelude(Head,Head1,Rest,F/A,Id1,L,T) :-
2878 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs),
2879 build_head(F,A,Id1,VarsSusp,ClauseHead),
2880 head_arg_matches(HeadPairs,[],FirstMatching,VarDict),
2882 lookup_passive_head(Head1,[Head],VarDict,ModConstraintsGoal,AllSusps),
2884 gen_allocation(Id1,Vars,Susp,F/A,VarsSusp,ConstraintAllocationGoal),
2886 extend_id(Id1,DelegateId),
2887 extra_active_delegate_variables(Head,Rest,VarDict,ExtraVars),
2888 append([AllSusps|VarsSusp],ExtraVars,DelegateCallVars),
2889 build_head(F,A,DelegateId,DelegateCallVars,Delegate),
2896 ConstraintAllocationGoal,
2899 L = [PreludeClause|T].
2901 extra_active_delegate_variables(Term,Terms,VarDict,Vars) :-
2903 delegate_variables(Term,Terms,VarDict,Args,Vars).
2905 passive_delegate_variables(Term,PrevTerms,NextTerms,VarDict,Vars) :-
2906 term_variables(PrevTerms,PrevVars),
2907 delegate_variables(Term,NextTerms,VarDict,PrevVars,Vars).
2909 delegate_variables(Term,Terms,VarDict,PrevVars,Vars) :-
2910 term_variables(Term,V1),
2911 term_variables(Terms,V2),
2912 intersect_eq(V1,V2,V3),
2913 list_difference_eq(V3,PrevVars,V4),
2914 translate(V4,VarDict,Vars).
2917 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2918 simpagation_head2_worker(Head2,Head1,ID1,RestHeads1,IDs1,RestHeads2,IDs2,PragmaRule,FA,Id,L,T) :-
2919 PragmaRule = pragma(Rule,_,_,_,_),
2920 Rule = rule(_,_,Guard,Body),
2921 simpagation_head2_worker_end(Head2,[Head1,RestHeads1,RestHeads2,Guard,Body],FA,Id,L,L1),
2922 simpagation_head2_worker_body(Head2,Head1,ID1,RestHeads1,IDs1,RestHeads2,IDs2,PragmaRule,FA,Id,L1,T).
2924 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2925 simpagation_head2_worker_body(Head2,Head1,ID1,RestHeads1,IDs1,RestHeads2,IDs2,PragmaRule,F/A,Id,L,T) :-
2927 gen_var(OtherSusps),
2929 head_info(Head2,A,_Vars,Susp,VarsSusp,Head2Pairs),
2930 head_arg_matches(Head2Pairs,[],_,VarDict1),
2932 PragmaRule = pragma(Rule,_,Pragmas,_,RuleNb),
2933 Rule = rule(_,_,Guard,Body),
2934 extra_active_delegate_variables(Head2,[Head1,RestHeads1,RestHeads2,Guard,Body],VarDict1,ExtraVars),
2935 append([[OtherSusp|OtherSusps]|VarsSusp],ExtraVars,HeadVars),
2936 build_head(F,A,Id,HeadVars,ClauseHead),
2938 functor(Head1,_OtherF,OtherA),
2939 head_info(Head1,OtherA,OtherVars,_,_,Head1Pairs),
2940 head_arg_matches(Head1Pairs,VarDict1,FirstMatching,VarDict2),
2942 OtherSuspension =.. [suspension,_,OtherState,_,_,_,_|OtherVars],
2943 create_get_mutable(active,OtherState,GetMutable),
2945 ( OtherSusp = OtherSuspension,
2949 ( (RestHeads1 \== [] ; RestHeads2 \== []) ->
2950 append(RestHeads1,RestHeads2,RestHeads),
2951 append(IDs1,IDs2,IDs),
2952 reorder_heads(RuleNb,Head1-Head2,RestHeads,IDs,NRestHeads,NIDs),
2953 rest_heads_retrieval_and_matching(NRestHeads,NIDs,Pragmas,[Head1,Head2],RestSuspsRetrieval,Susps,VarDict2,VarDict,[Head1],[OtherSusp],[]),
2954 split_by_ids(NIDs,Susps,IDs1,Susps1,Susps2)
2955 ; RestSuspsRetrieval = [],
2961 gen_uncond_susps_detachments([OtherSusp | Susps1],[Head1|RestHeads1],Susps1Detachments),
2963 append([OtherSusps|VarsSusp],ExtraVars,RecursiveVars),
2964 build_head(F,A,Id,RecursiveVars,RecursiveCall),
2965 append([[]|VarsSusp],ExtraVars,RecursiveVars2),
2966 build_head(F,A,Id,RecursiveVars2,RecursiveCall2),
2968 guard_body_copies2(Rule,VarDict,GuardCopyList,BodyCopy),
2969 guard_via_reschedule(RestSuspsRetrieval,GuardCopyList,v(ClauseHead,IteratorSuspTest,FirstMatching),RescheduledTest),
2970 ( BodyCopy \== true ->
2971 gen_uncond_attach_goal(F/A,Susp,Attachment,Generation),
2972 gen_state_cond_call(Susp,A,RecursiveCall,Generation,ConditionalRecursiveCall),
2973 gen_state_cond_call(Susp,A,RecursiveCall2,Generation,ConditionalRecursiveCall2)
2974 ; Attachment = true,
2975 ConditionalRecursiveCall = RecursiveCall,
2976 ConditionalRecursiveCall2 = RecursiveCall2
2979 ( chr_pp_flag(debugable,on) ->
2980 my_term_copy(Guard - Body, VarDict, _, DebugGuard - DebugBody),
2981 DebugTry = 'chr debug_event'( try([OtherSusp|Susps1],[Susp|Susps2],DebugGuard,DebugBody)),
2982 DebugApply = 'chr debug_event'(apply([OtherSusp|Susps1],[Susp|Susps2],DebugGuard,DebugBody))
2988 ( member(unique(ID1,UniqueKeys), Pragmas),
2989 check_unique_keys(UniqueKeys,VarDict1) ->
3000 ConditionalRecursiveCall2
3019 ConditionalRecursiveCall
3027 gen_state_cond_call(Susp,N,Call,Generation,ConditionalCall) :-
3029 Suspension =.. [suspension,_,State,_,NewGeneration,_,_|Args],
3030 create_get_mutable(active,State,GetState),
3031 create_get_mutable(Generation,NewGeneration,GetGeneration),
3033 ( Susp = Suspension,
3036 'chr update_mutable'(inactive,State),
3041 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3042 simpagation_head2_worker_end(Head,Rest,F/A,Id,L,T) :-
3043 head_info(Head,A,_Vars,_Susp,VarsSusp,Pairs),
3044 head_arg_matches(Pairs,[],_,VarDict),
3045 extra_active_delegate_variables(Head,Rest,VarDict,ExtraVars),
3046 append([[]|VarsSusp],ExtraVars,HeadVars),
3047 build_head(F,A,Id,HeadVars,ClauseHead),
3048 next_id(Id,ContinuationId),
3049 build_head(F,A,ContinuationId,VarsSusp,ContinuationHead),
3050 Clause = ( ClauseHead :- ContinuationHead ),
3053 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3056 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3058 %% | _ \ _ __ ___ _ __ __ _ __ _ __ _| |_(_) ___ _ __
3059 %% | |_) | '__/ _ \| '_ \ / _` |/ _` |/ _` | __| |/ _ \| '_ \
3060 %% | __/| | | (_) | |_) | (_| | (_| | (_| | |_| | (_) | | | |
3061 %% |_| |_| \___/| .__/ \__,_|\__, |\__,_|\__|_|\___/|_| |_|
3064 propagation_code(Head,RestHeads,Rule,RuleNb,RestHeadNb,FA,Id,L,T) :-
3065 ( RestHeads == [] ->
3066 propagation_single_headed(Head,Rule,RuleNb,FA,Id,L,T)
3068 propagation_multi_headed(Head,RestHeads,Rule,RuleNb,RestHeadNb,FA,Id,L,T)
3070 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3071 %% Single headed propagation
3072 %% everything in a single clause
3073 propagation_single_headed(Head,Rule,RuleNb,F/A,Id,L,T) :-
3074 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs),
3075 build_head(F,A,Id,VarsSusp,ClauseHead),
3078 build_head(F,A,NextId,VarsSusp,NextHead),
3080 NextCall = NextHead,
3082 head_arg_matches(HeadPairs,[],HeadMatching,VarDict),
3083 guard_body_copies(Rule,VarDict,GuardCopy,BodyCopy),
3084 gen_allocation(Id,Vars,Susp,F/A,VarsSusp,Allocation),
3085 gen_uncond_attach_goal(F/A,Susp,Attachment,Generation),
3087 gen_state_cond_call(Susp,A,NextCall,Generation,ConditionalNextCall),
3089 ( chr_pp_flag(debugable,on) ->
3090 Rule = rule(_,_,Guard,Body),
3091 my_term_copy(Guard - Body, VarDict, _, DebugGuard - DebugBody),
3092 DebugTry = 'chr debug_event'( try([],[Susp],DebugGuard,DebugBody)),
3093 DebugApply = 'chr debug_event'(apply([],[Susp],DebugGuard,DebugBody))
3103 'chr novel_production'(Susp,RuleNb), % optimisation of t(RuleNb,Susp)
3108 'chr extend_history'(Susp,RuleNb),
3115 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3116 %% multi headed propagation
3117 %% prelude + predicates to accumulate the necessary combinations of suspended
3118 %% constraints + predicate to execute the body
3119 propagation_multi_headed(Head,RestHeads,Rule,RuleNb,RestHeadNb,FA,Id,L,T) :-
3120 RestHeads = [First|Rest],
3121 propagation_prelude(Head,RestHeads,Rule,FA,Id,L,L1),
3122 extend_id(Id,ExtendedId),
3123 propagation_nested_code(Rest,[First,Head],Rule,RuleNb,RestHeadNb,FA,ExtendedId,L1,T).
3125 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3126 propagation_prelude(Head,[First|Rest],Rule,F/A,Id,L,T) :-
3127 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs),
3128 build_head(F,A,Id,VarsSusp,PreludeHead),
3129 head_arg_matches(HeadPairs,[],FirstMatching,VarDict),
3130 Rule = rule(_,_,Guard,Body),
3131 extra_active_delegate_variables(Head,[First,Rest,Guard,Body],VarDict,ExtraVars),
3133 lookup_passive_head(First,[Head],VarDict,FirstSuspGoal,Susps),
3135 gen_allocation(Id,Vars,Susp,F/A,VarsSusp,CondAllocation),
3137 extend_id(Id,NestedId),
3138 append([Susps|VarsSusp],ExtraVars,NestedVars),
3139 build_head(F,A,NestedId,NestedVars,NestedHead),
3140 NestedCall = NestedHead,
3152 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3153 propagation_nested_code([],[CurrentHead|PreHeads],Rule,RuleNb,RestHeadNb,FA,Id,L,T) :-
3154 propagation_end([CurrentHead|PreHeads],[],Rule,FA,Id,L,L1),
3155 propagation_body(CurrentHead,PreHeads,Rule,RuleNb,RestHeadNb,FA,Id,L1,T).
3157 propagation_nested_code([Head|RestHeads],PreHeads,Rule,RuleNb,RestHeadNb,FA,Id,L,T) :-
3158 propagation_end(PreHeads,[Head|RestHeads],Rule,FA,Id,L,L1),
3159 propagation_accumulator([Head|RestHeads],PreHeads,Rule,FA,Id,L1,L2),
3161 propagation_nested_code(RestHeads,[Head|PreHeads],Rule,RuleNb,RestHeadNb,FA,IncId,L2,T).
3163 propagation_body(CurrentHead,PreHeads,Rule,RuleNb,RestHeadNb,F/A,Id,L,T) :-
3164 Rule = rule(_,_,Guard,Body),
3165 get_prop_inner_loop_vars(PreHeads,[CurrentHead,Guard,Body],PreVarsAndSusps,VarDict1,Susp,RestSusps),
3167 gen_var(OtherSusps),
3168 functor(CurrentHead,_OtherF,OtherA),
3169 gen_vars(OtherA,OtherVars),
3170 Suspension =.. [suspension,_,State,_,_,_,_|OtherVars],
3171 create_get_mutable(active,State,GetMutable),
3173 OtherSusp = Suspension,
3176 ClauseVars = [[OtherSusp|OtherSusps]|PreVarsAndSusps],
3177 build_head(F,A,Id,ClauseVars,ClauseHead),
3178 RecursiveVars = [OtherSusps|PreVarsAndSusps],
3179 build_head(F,A,Id,RecursiveVars,RecursiveHead),
3180 RecursiveCall = RecursiveHead,
3181 CurrentHead =.. [_|OtherArgs],
3182 pairup(OtherArgs,OtherVars,OtherPairs),
3183 head_arg_matches(OtherPairs,VarDict1,Matching,VarDict),
3185 different_from_other_susps(CurrentHead,OtherSusp,PreHeads,RestSusps,DiffSuspGoals),
3187 guard_body_copies(Rule,VarDict,GuardCopy,BodyCopy),
3188 gen_uncond_attach_goal(F/A,Susp,Attach,Generation),
3189 gen_state_cond_call(Susp,A,RecursiveCall,Generation,ConditionalRecursiveCall),
3191 history_susps(RestHeadNb,[OtherSusp|RestSusps],Susp,[],HistorySusps),
3192 bagof('chr novel_production'(X,Y),( member(X,HistorySusps), Y = TupleVar) ,NovelProductionsList),
3193 list2conj(NovelProductionsList,NovelProductions),
3194 Tuple =.. [t,RuleNb|HistorySusps],
3196 ( chr_pp_flag(debugable,on) ->
3197 Rule = rule(_,_,Guard,Body),
3198 my_term_copy(Guard - Body, VarDict, _, DebugGuard - DebugBody),
3199 DebugTry = 'chr debug_event'( try([],[Susp,OtherSusp|RestSusps],DebugGuard,DebugBody)),
3200 DebugApply = 'chr debug_event'(apply([],[Susp,OtherSusp|RestSusps],DebugGuard,DebugBody))
3216 'chr extend_history'(Susp,TupleVar),
3219 ConditionalRecursiveCall
3225 history_susps(Count,OtherSusps,Susp,Acc,HistorySusps) :-
3227 reverse(OtherSusps,ReversedSusps),
3228 append(ReversedSusps,[Susp|Acc],HistorySusps)
3230 OtherSusps = [OtherSusp|RestOtherSusps],
3231 NCount is Count - 1,
3232 history_susps(NCount,RestOtherSusps,Susp,[OtherSusp|Acc],HistorySusps)
3235 get_prop_inner_loop_vars([Head],Terms,HeadVars,VarDict,Susp,[]) :-
3238 head_info(Head,A,_Vars,Susp,VarsSusp,Pairs),
3239 head_arg_matches(Pairs,[],_,VarDict),
3240 extra_active_delegate_variables(Head,Terms,VarDict,ExtraVars),
3241 append(VarsSusp,ExtraVars,HeadVars).
3242 get_prop_inner_loop_vars([Head|Heads],Terms,VarsSusps,NVarDict,MainSusp,[Susp|RestSusps]) :-
3243 get_prop_inner_loop_vars(Heads,[Head|Terms],RestVarsSusp,VarDict,MainSusp,RestSusps),
3246 head_info(Head,A,_Vars,Susp,_VarsSusp,Pairs),
3247 head_arg_matches(Pairs,VarDict,_,NVarDict),
3248 passive_delegate_variables(Head,Heads,Terms,NVarDict,HeadVars),
3249 append(HeadVars,[Susp,Susps|RestVarsSusp],VarsSusps).
3251 propagation_end([CurrentHead|PrevHeads],NextHeads,Rule,F/A,Id,L,T) :-
3252 Rule = rule(_,_,Guard,Body),
3253 gen_var_susp_list_for(PrevHeads,[CurrentHead,NextHeads,Guard,Body],_,VarsAndSusps,AllButFirst,FirstSusp),
3255 Vars = [ [] | VarsAndSusps],
3257 build_head(F,A,Id,Vars,Head),
3261 PrevVarsAndSusps = AllButFirst
3264 PrevVarsAndSusps = [FirstSusp|AllButFirst]
3267 build_head(F,A,PrevId,PrevVarsAndSusps,PrevHead),
3268 PredecessorCall = PrevHead,
3276 gen_var_susp_list_for([Head],Terms,VarDict,HeadVars,VarsSusp,Susp) :-
3279 head_info(Head,A,_Vars,Susp,VarsSusp,HeadPairs),
3280 head_arg_matches(HeadPairs,[],_,VarDict),
3281 extra_active_delegate_variables(Head,Terms,VarDict,ExtraVars),
3282 append(VarsSusp,ExtraVars,HeadVars).
3283 gen_var_susp_list_for([Head|Heads],Terms,NVarDict,VarsSusps,Rest,Susps) :-
3284 gen_var_susp_list_for(Heads,[Head|Terms],VarDict,Rest,_,_),
3287 head_info(Head,A,_Vars,Susp,_VarsSusp,HeadPairs),
3288 head_arg_matches(HeadPairs,VarDict,_,NVarDict),
3289 passive_delegate_variables(Head,Heads,Terms,NVarDict,HeadVars),
3290 append(HeadVars,[Susp,Susps|Rest],VarsSusps).
3292 propagation_accumulator([NextHead|RestHeads],[CurrentHead|PreHeads],Rule,F/A,Id,L,T) :-
3293 Rule = rule(_,_,Guard,Body),
3294 pre_vars_and_susps(PreHeads,[CurrentHead,NextHead,RestHeads,Guard,Body],PreVarsAndSusps,VarDict,PreSusps),
3295 gen_var(OtherSusps),
3296 functor(CurrentHead,_OtherF,OtherA),
3297 gen_vars(OtherA,OtherVars),
3298 head_info(CurrentHead,OtherA,OtherVars,OtherSusp,_VarsSusp,HeadPairs),
3299 head_arg_matches(HeadPairs,VarDict,FirstMatching,VarDict1),
3301 OtherSuspension =.. [suspension,_,State,_,_,_,_|OtherVars],
3303 different_from_other_susps(CurrentHead,OtherSusp,PreHeads,PreSusps,DiffSuspGoals),
3304 create_get_mutable(active,State,GetMutable),
3306 OtherSusp = OtherSuspension,
3311 lookup_passive_head(NextHead,[CurrentHead|PreHeads],VarDict1,NextSuspGoal,NextSusps),
3312 inc_id(Id,NestedId),
3313 ClauseVars = [[OtherSusp|OtherSusps]|PreVarsAndSusps],
3314 build_head(F,A,Id,ClauseVars,ClauseHead),
3315 passive_delegate_variables(CurrentHead,PreHeads,[NextHead,RestHeads,Guard,Body],VarDict1,CurrentHeadVars),
3316 append([NextSusps|CurrentHeadVars],[OtherSusp,OtherSusps|PreVarsAndSusps],NestedVars),
3317 build_head(F,A,NestedId,NestedVars,NestedHead),
3319 RecursiveVars = [OtherSusps|PreVarsAndSusps],
3320 build_head(F,A,Id,RecursiveVars,RecursiveHead),
3332 pre_vars_and_susps([Head],Terms,HeadVars,VarDict,[]) :-
3335 head_info(Head,A,_Vars,_Susp,VarsSusp,HeadPairs),
3336 head_arg_matches(HeadPairs,[],_,VarDict),
3337 extra_active_delegate_variables(Head,Terms,VarDict,ExtraVars),
3338 append(VarsSusp,ExtraVars,HeadVars).
3339 pre_vars_and_susps([Head|Heads],Terms,NVSs,NVarDict,[Susp|Susps]) :-
3340 pre_vars_and_susps(Heads,[Head|Terms],VSs,VarDict,Susps),
3343 head_info(Head,A,_Vars,Susp,_VarsSusp,HeadPairs),
3344 head_arg_matches(HeadPairs,VarDict,_,NVarDict),
3345 passive_delegate_variables(Head,Heads,Terms,NVarDict,HeadVars),
3346 append(HeadVars,[Susp,NextSusps|VSs],NVSs).
3348 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3350 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3352 %% | _ \ __ _ ___ ___(_)_ _____ | | | | ___ __ _ __| |
3353 %% | |_) / _` / __/ __| \ \ / / _ \ | |_| |/ _ \/ _` |/ _` |
3354 %% | __/ (_| \__ \__ \ |\ V / __/ | _ | __/ (_| | (_| |
3355 %% |_| \__,_|___/___/_| \_/ \___| |_| |_|\___|\__,_|\__,_|
3358 %% | _ \ ___| |_ _ __(_) _____ ____ _| |
3359 %% | |_) / _ \ __| '__| |/ _ \ \ / / _` | |
3360 %% | _ < __/ |_| | | | __/\ V / (_| | |
3361 %% |_| \_\___|\__|_| |_|\___| \_/ \__,_|_|
3364 %% | _ \ ___ ___ _ __ __| | ___ _ __(_)_ __ __ _
3365 %% | |_) / _ \/ _ \| '__/ _` |/ _ \ '__| | '_ \ / _` |
3366 %% | _ < __/ (_) | | | (_| | __/ | | | | | | (_| |
3367 %% |_| \_\___|\___/|_| \__,_|\___|_| |_|_| |_|\__, |
3370 reorder_heads(RuleNb,Head,RestHeads,RestIDs,NRestHeads,NRestIDs) :-
3371 ( chr_pp_flag(reorder_heads,on) ->
3372 reorder_heads_main(RuleNb,Head,RestHeads,RestIDs,NRestHeads,NRestIDs)
3374 NRestHeads = RestHeads,
3378 reorder_heads_main(RuleNb,Head,RestHeads,RestIDs,NRestHeads,NRestIDs) :-
3379 term_variables(Head,Vars),
3380 InitialData = entry([],[],Vars,RestHeads,RestIDs,RuleNb),
3381 a_star(InitialData,FD^(chr_translate:final_data(FD)),N^EN^C^(chr_translate:expand_data(N,EN,C)),FinalData),
3382 FinalData = entry(RNRestHeads,RNRestIDs,_,_,_,_),
3383 reverse(RNRestHeads,NRestHeads),
3384 reverse(RNRestIDs,NRestIDs).
3386 final_data(Entry) :-
3387 Entry = entry(_,_,_,_,[],_).
3389 expand_data(Entry,NEntry,Cost) :-
3390 Entry = entry(Heads,IDs,Vars,NHeads,NIDs,RuleNb),
3391 term_variables(Entry,EVars),
3392 NEntry = entry([Head1|Heads],[ID1|IDs],Vars1,NHeads1,NIDs1,RuleNb),
3393 select2(Head1,ID1,NHeads,NIDs,NHeads1,NIDs1),
3394 order_score(Head1,ID1,Vars,NHeads1,RuleNb,Cost),
3395 term_variables([Head1|Vars],Vars1).
3397 order_score(Head,ID,KnownVars,RestHeads,RuleNb,Score) :-
3399 get_store_type(F/A,StoreType),
3400 order_score(StoreType,Head,ID,KnownVars,RestHeads,RuleNb,Score).
3402 order_score(default,Head,_ID,KnownVars,RestHeads,RuleNb,Score) :-
3403 term_variables(Head,HeadVars),
3404 term_variables(RestHeads,RestVars),
3405 order_score_vars(HeadVars,KnownVars,RestHeads,0,Score).
3406 order_score(multi_hash(Indexes),Head,_ID,KnownVars,RestHeads,RuleNb,Score) :-
3407 order_score_indexes(Indexes,Head,KnownVars,0,Score).
3408 order_score(global_ground,Head,ID,_KnownVars,_RestHeads,RuleNb,Score) :-
3410 ( get_pragma_unique(RuleNb,ID,Vars),
3412 Score = 1 % guaranteed O(1)
3413 ; A == 0 -> % flag constraint
3414 Score = 10 % O(1)? [CHECK: no deleted/triggered/... constraints in store?]
3419 order_score(multi_store(StoreTypes),Head,ID,KnownVars,RestHeads,RuleNb,Score) :-
3420 find_with_var_identity(
3422 t(Head,KnownVars,RestHeads),
3423 ( member(ST,StoreTypes), chr_translate:order_score(ST,Head,ID,KnownVars,RestHeads,RuleNb,S) ),
3426 min_list(Scores,Score).
3429 order_score_indexes([],_,_,Score,Score) :-
3431 order_score_indexes([I|Is],Head,KnownVars,Score,NScore) :-
3432 multi_hash_key_args(I,Head,Args),
3433 ( forall(Arg,Args,hprolog:memberchk_eq(Arg,KnownVars)) ->
3434 Score1 is Score + 10
3438 order_score_indexes(Is,Head,KnownVars,Score1,NScore).
3440 order_score_vars([],_,_,Score,NScore) :-
3446 order_score_vars([V|Vs],KnownVars,RestVars,Score,NScore) :-
3447 ( memberchk_eq(V,KnownVars) ->
3448 TScore is Score + 10
3449 ; memberchk_eq(V,RestVars) ->
3450 TScore is Score + 100
3454 order_score_vars(Vs,KnownVars,RestVars,TScore,NScore).
3456 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3458 %% |_ _|_ __ | (_)_ __ (_)_ __ __ _
3459 %% | || '_ \| | | '_ \| | '_ \ / _` |
3460 %% | || | | | | | | | | | | | | (_| |
3461 %% |___|_| |_|_|_|_| |_|_|_| |_|\__, |
3464 create_get_mutable(V,M,GM) :-
3465 GM = (M = mutable(V)).
3467 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3469 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3471 %% | | | | |_(_) (_) |_ _ _
3472 %% | | | | __| | | | __| | | |
3473 %% | |_| | |_| | | | |_| |_| |
3474 %% \___/ \__|_|_|_|\__|\__, |
3481 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs) :-
3482 vars_susp(A,Vars,Susp,VarsSusp),
3484 pairup(Args,Vars,HeadPairs).
3486 inc_id([N|Ns],[O|Ns]) :-
3488 dec_id([N|Ns],[M|Ns]) :-
3491 extend_id(Id,[0|Id]).
3493 next_id([_,N|Ns],[O|Ns]) :-
3496 build_head(F,A,Id,Args,Head) :-
3497 buildName(F,A,Id,Name),
3498 Head =.. [Name|Args].
3500 buildName(Fct,Aty,List,Result) :-
3501 atom_concat(Fct, (/) ,FctSlash),
3502 atom_concat(FctSlash,Aty,FctSlashAty),
3503 buildName_(List,FctSlashAty,Result).
3505 buildName_([],Name,Name).
3506 buildName_([N|Ns],Name,Result) :-
3507 buildName_(Ns,Name,Name1),
3508 atom_concat(Name1,'__',NameDash), % '_' is a char :-(
3509 atom_concat(NameDash,N,Result).
3511 vars_susp(A,Vars,Susp,VarsSusp) :-
3513 append(Vars,[Susp],VarsSusp).
3515 make_attr(N,Mask,SuspsList,Attr) :-
3516 length(SuspsList,N),
3517 Attr =.. [v,Mask|SuspsList].
3519 or_pattern(Pos,Pat) :-
3521 Pat is 1 << Pow. % was 2 ** X
3523 and_pattern(Pos,Pat) :-
3525 Y is 1 << X, % was 2 ** X
3526 Pat is (-1)*(Y + 1). % because fx (-) is redefined
3528 conj2list(Conj,L) :- %% transform conjunctions to list
3529 conj2list(Conj,L,[]).
3531 conj2list(Conj,L,T) :-
3535 conj2list(G,[G | T],T).
3538 list2conj([G],X) :- !, X = G.
3539 list2conj([G|Gs],C) :-
3540 ( G == true -> %% remove some redundant trues
3548 list2disj([G],X) :- !, X = G.
3549 list2disj([G|Gs],C) :-
3550 ( G == fail -> %% remove some redundant fails
3557 atom_concat_list([X],X) :- ! .
3558 atom_concat_list([X|Xs],A) :-
3559 atom_concat_list(Xs,B),
3562 make_name(Prefix,F/A,Name) :-
3563 atom_concat_list([Prefix,F,(/),A],Name).
3566 set_elems([X|Xs],X) :-
3569 member2([X|_],[Y|_],X-Y).
3570 member2([_|Xs],[_|Ys],P) :-
3573 select2(X, Y, [X|Xs], [Y|Ys], Xs, Ys).
3574 select2(X, Y, [X1|Xs], [Y1|Ys], [X1|NXs], [Y1|NYs]) :-
3575 select2(X, Y, Xs, Ys, NXs, NYs).
3577 pair_all_with([],_,[]).
3578 pair_all_with([X|Xs],Y,[X-Y|Rest]) :-
3579 pair_all_with(Xs,Y,Rest).
3580 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3582 lookup_passive_head(Head,PreJoin,VarDict,Goal,AllSusps) :-
3584 get_store_type(F/A,StoreType),
3585 lookup_passive_head(StoreType,Head,PreJoin,VarDict,Goal,AllSusps).
3587 lookup_passive_head(default,Head,PreJoin,VarDict,Goal,AllSusps) :-
3588 passive_head_via(Head,PreJoin,[],VarDict,Goal,Attr,AttrDict),
3589 instantiate_pattern_goals(AttrDict),
3590 get_max_constraint_index(N),
3595 get_constraint_index(F/A,Pos),
3596 make_attr(N,_,SuspsList,Attr),
3597 nth(Pos,SuspsList,AllSusps)
3599 lookup_passive_head(multi_hash(Indexes),Head,_PreJoin,VarDict,Goal,AllSusps) :-
3601 member(Index,Indexes),
3602 multi_hash_key_args(Index,Head,KeyArgs),
3603 translate(KeyArgs,VarDict,KeyArgCopies)
3605 ( KeyArgCopies = [KeyCopy] ->
3608 KeyCopy =.. [k|KeyArgCopies]
3611 multi_hash_via_lookup_name(F/A,Index,ViaName),
3612 Goal =.. [ViaName,KeyCopy,AllSusps],
3613 update_store_type(F/A,multi_hash([Index])).
3614 lookup_passive_head(global_ground,Head,PreJoin,_VarDict,Goal,AllSusps) :-
3616 global_ground_store_name(F/A,StoreName),
3617 Goal = nb_getval(StoreName,AllSusps),
3618 update_store_type(F/A,global_ground).
3619 lookup_passive_head(multi_store(StoreTypes),Head,PreJoin,VarDict,Goal,AllSusps) :-
3621 member(ST,StoreTypes),
3622 lookup_passive_head(ST,Head,PreJoin,VarDict,Goal,AllSusps)
3624 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3625 assume_constraint_stores([]).
3626 assume_constraint_stores([C|Cs]) :-
3627 ( \+ may_trigger(C),
3629 get_store_type(C,default) ->
3630 get_indexed_arguments(C,IndexedArgs),
3631 findall(Index,(sublist(Index,IndexedArgs), Index \== []),Indexes),
3632 assumed_store_type(C,multi_store([multi_hash(Indexes),global_ground]))
3636 assume_constraint_stores(Cs).
3638 get_indexed_arguments(C,IndexedArgs) :-
3640 get_indexed_arguments(1,A,C,IndexedArgs).
3642 get_indexed_arguments(I,N,C,L) :-
3645 ; ( is_indexed_argument(C,I) ->
3651 get_indexed_arguments(J,N,C,T)
3654 validate_store_type_assumptions([]).
3655 validate_store_type_assumptions([C|Cs]) :-
3656 validate_store_type_assumption(C),
3657 validate_store_type_assumptions(Cs).