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 ].
857 option_definition(type_definition, _, []). % JW: ignored by bootstrap compiler
858 option_definition(type_declaration, _, []). % JW: ignored by bootstrap compiler
861 chr_pp_flag_definition(Name,[DefaultValue|_]),
862 set_chr_pp_flag(Name,DefaultValue),
866 set_chr_pp_flags([]).
867 set_chr_pp_flags([Name-Value|Flags]) :-
868 set_chr_pp_flag(Name,Value),
869 set_chr_pp_flags(Flags).
871 set_chr_pp_flag(Name,Value) :-
872 atom_concat('$chr_pp_',Name,GlobalVar),
873 nb_setval(GlobalVar,Value).
875 chr_pp_flag_definition(unique_analyse_optimise,[on,off]).
876 chr_pp_flag_definition(check_unnecessary_active,[full,simplification,off]).
877 chr_pp_flag_definition(reorder_heads,[on,off]).
878 chr_pp_flag_definition(set_semantics_rule,[on,off]).
879 chr_pp_flag_definition(guard_via_reschedule,[on,off]).
880 chr_pp_flag_definition(guard_locks,[on,off]).
881 chr_pp_flag_definition(check_attachments,[on,off]).
882 chr_pp_flag_definition(debugable,[off,on]).
883 chr_pp_flag_definition(reduced_indexing,[on,off]).
885 chr_pp_flag(Name,Value) :-
886 atom_concat('$chr_pp_',Name,GlobalVar),
887 nb_getval(GlobalVar,V),
889 chr_pp_flag_definition(Name,[Value|_])
893 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
895 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
897 %% Generated predicates
898 %% attach_$CONSTRAINT
900 %% detach_$CONSTRAINT
903 %% attach_$CONSTRAINT
904 generate_attach_detach_a_constraint_all([],[]).
905 generate_attach_detach_a_constraint_all([Constraint|Constraints],Clauses) :-
906 ( may_trigger(Constraint) ->
907 generate_attach_a_constraint(Constraint,Clauses1),
908 generate_detach_a_constraint(Constraint,Clauses2)
913 generate_attach_detach_a_constraint_all(Constraints,Clauses3),
914 append_lists([Clauses1,Clauses2,Clauses3],Clauses).
916 generate_attach_a_constraint(Constraint,[Clause1,Clause2]) :-
917 generate_attach_a_constraint_empty_list(Constraint,Clause1),
918 get_max_constraint_index(N),
920 generate_attach_a_constraint_1_1(Constraint,Clause2)
922 generate_attach_a_constraint_t_p(Constraint,Clause2)
925 generate_attach_a_constraint_skeleton(FA,Args,Body,Clause) :-
926 make_name('attach_',FA,Fct),
927 Head =.. [Fct | Args],
928 Clause = ( Head :- Body).
930 generate_attach_a_constraint_empty_list(FA,Clause) :-
931 generate_attach_a_constraint_skeleton(FA,[[],_],true,Clause).
933 generate_attach_a_constraint_1_1(FA,Clause) :-
934 Args = [[Var|Vars],Susp],
935 generate_attach_a_constraint_skeleton(FA,Args,Body,Clause),
936 generate_attach_body_1(FA,Var,Susp,AttachBody),
937 make_name('attach_',FA,Fct),
938 RecursiveCall =.. [Fct,Vars,Susp],
945 generate_attach_body_1(FA,Var,Susp,Body) :-
946 get_target_module(Mod),
948 ( get_attr(Var, Mod, Susps) ->
949 NewSusps=[Susp|Susps],
950 put_attr(Var, Mod, NewSusps)
952 put_attr(Var, Mod, [Susp])
955 generate_attach_a_constraint_t_p(FA,Clause) :-
956 Args = [[Var|Vars],Susp],
957 generate_attach_a_constraint_skeleton(FA,Args,Body,Clause),
958 make_name('attach_',FA,Fct),
959 RecursiveCall =.. [Fct,Vars,Susp],
960 generate_attach_body_n(FA,Var,Susp,AttachBody),
967 generate_attach_body_n(F/A,Var,Susp,Body) :-
968 get_constraint_index(F/A,Position),
969 or_pattern(Position,Pattern),
970 get_max_constraint_index(Total),
971 make_attr(Total,Mask,SuspsList,Attr),
972 nth(Position,SuspsList,Susps),
973 substitute(Susps,SuspsList,[Susp|Susps],SuspsList1),
974 make_attr(Total,Mask,SuspsList1,NewAttr1),
975 substitute(Susps,SuspsList,[Susp],SuspsList2),
976 make_attr(Total,NewMask,SuspsList2,NewAttr2),
977 copy_term(SuspsList,SuspsList3),
978 nth(Position,SuspsList3,[Susp]),
979 delete(SuspsList3,[Susp],RestSuspsList),
980 set_elems(RestSuspsList,[]),
981 make_attr(Total,Pattern,SuspsList3,NewAttr3),
982 get_target_module(Mod),
984 ( get_attr(Var,Mod,TAttr) ->
986 ( Mask /\ Pattern =:= Pattern ->
987 put_attr(Var, Mod, NewAttr1)
989 NewMask is Mask \/ Pattern,
990 put_attr(Var, Mod, NewAttr2)
993 put_attr(Var,Mod,NewAttr3)
996 %% detach_$CONSTRAINT
997 generate_detach_a_constraint(Constraint,[Clause1,Clause2]) :-
998 generate_detach_a_constraint_empty_list(Constraint,Clause1),
999 get_max_constraint_index(N),
1001 generate_detach_a_constraint_1_1(Constraint,Clause2)
1003 generate_detach_a_constraint_t_p(Constraint,Clause2)
1006 generate_detach_a_constraint_empty_list(FA,Clause) :-
1007 make_name('detach_',FA,Fct),
1009 Head =.. [Fct | Args],
1010 Clause = ( Head :- true).
1012 generate_detach_a_constraint_1_1(FA,Clause) :-
1013 make_name('detach_',FA,Fct),
1014 Args = [[Var|Vars],Susp],
1015 Head =.. [Fct | Args],
1016 RecursiveCall =.. [Fct,Vars,Susp],
1017 generate_detach_body_1(FA,Var,Susp,DetachBody),
1023 Clause = (Head :- Body).
1025 generate_detach_body_1(FA,Var,Susp,Body) :-
1026 get_target_module(Mod),
1028 ( get_attr(Var,Mod,Susps) ->
1029 'chr sbag_del_element'(Susps,Susp,NewSusps),
1033 put_attr(Var,Mod,NewSusps)
1039 generate_detach_a_constraint_t_p(FA,Clause) :-
1040 make_name('detach_',FA,Fct),
1041 Args = [[Var|Vars],Susp],
1042 Head =.. [Fct | Args],
1043 RecursiveCall =.. [Fct,Vars,Susp],
1044 generate_detach_body_n(FA,Var,Susp,DetachBody),
1050 Clause = (Head :- Body).
1052 generate_detach_body_n(F/A,Var,Susp,Body) :-
1053 get_constraint_index(F/A,Position),
1054 or_pattern(Position,Pattern),
1055 and_pattern(Position,DelPattern),
1056 get_max_constraint_index(Total),
1057 make_attr(Total,Mask,SuspsList,Attr),
1058 nth(Position,SuspsList,Susps),
1059 substitute(Susps,SuspsList,[],SuspsList1),
1060 make_attr(Total,NewMask,SuspsList1,Attr1),
1061 substitute(Susps,SuspsList,NewSusps,SuspsList2),
1062 make_attr(Total,Mask,SuspsList2,Attr2),
1063 get_target_module(Mod),
1065 ( get_attr(Var,Mod,TAttr) ->
1067 ( Mask /\ Pattern =:= Pattern ->
1068 'chr sbag_del_element'(Susps,Susp,NewSusps),
1070 NewMask is Mask /\ DelPattern,
1074 put_attr(Var,Mod,Attr1)
1077 put_attr(Var,Mod,Attr2)
1086 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1087 generate_indexed_variables_clauses(Constraints,Clauses) :-
1088 ( forsome(C,Constraints,chr_translate:may_trigger(C)) ->
1089 generate_indexed_variables_clauses_(Constraints,Clauses)
1094 generate_indexed_variables_clauses_([],[]).
1095 generate_indexed_variables_clauses_([C|Cs],Clauses) :-
1096 ( ( is_attached(C) ; chr_pp_flag(debugable,on)) ->
1097 Clauses = [Clause|RestClauses],
1098 generate_indexed_variables_clause(C,Clause)
1100 Clauses = RestClauses
1102 generate_indexed_variables_clauses_(Cs,RestClauses).
1104 generate_indexed_variables_clause(F/A,Clause) :-
1106 get_constraint_mode(F/A,ArgModes),
1108 create_indexed_variables_body(Args,ArgModes,Vars,1,F/A,MaybeBody,N),
1109 ( MaybeBody == empty ->
1113 Body = term_variables(Susp,Vars)
1118 ( '$indexed_variables'(Susp,Vars) :-
1123 create_indexed_variables_body([],[],_,_,_,empty,0).
1124 create_indexed_variables_body([V|Vs],[Mode|Modes],Vars,I,FA,Body,N) :-
1126 create_indexed_variables_body(Vs,Modes,Tail,J,FA,RBody,M),
1128 is_indexed_argument(FA,I) ->
1130 Body = term_variables(V,Vars)
1132 Body = (term_variables(V,Vars,Tail),RBody)
1141 generate_extra_clauses(Constraints,[A,B,C,D,E]) :-
1142 ( chr_pp_flag(reduced_indexing,on) ->
1143 global_indexed_variables_clause(Constraints,D)
1146 ( chr_indexed_variables(Susp,Vars) :-
1147 'chr chr_indexed_variables'(Susp,Vars)
1150 generate_remove_clause(A),
1151 generate_activate_clause(B),
1152 generate_allocate_clause(C),
1153 generate_insert_constraint_internal(E).
1155 generate_remove_clause(RemoveClause) :-
1158 remove_constraint_internal(Susp, Agenda, Delete) :-
1159 arg( 2, Susp, Mref),
1160 Mref = mutable(State), % get_mutable( State, Mref), % XXX Inlined
1161 'chr update_mutable'( removed, Mref), % mark in any case
1162 ( compound(State) -> % passive/1
1168 %; State==triggered ->
1172 chr_indexed_variables(Susp,Agenda)
1176 generate_activate_clause(ActivateClause) :-
1179 activate_constraint(Store, Vars, Susp, Generation) :-
1180 arg( 2, Susp, Mref),
1181 Mref = mutable(State), % get_mutable( State, Mref), % XXX Inlined
1182 'chr update_mutable'( active, Mref),
1183 ( nonvar(Generation) -> % aih
1186 arg( 4, Susp, Gref),
1187 Gref = mutable(Gen), % get_mutable( Gen, Gref), % XXX Inlined
1188 Generation is Gen+1,
1189 'chr update_mutable'( Generation, Gref)
1191 ( compound(State) -> % passive/1
1192 term_variables( State, Vars),
1193 'chr none_locked'( Vars),
1195 ; State == removed -> % the price for eager removal ...
1196 chr_indexed_variables(Susp,Vars),
1204 generate_allocate_clause(AllocateClause) :-
1207 allocate_constraint( Closure, Self, F, Args) :-
1208 Self =.. [suspension,Id,Mref,Closure,Gref,Href,F|Args],
1210 'chr empty_history'(History),
1211 Href = mutable(History),
1212 chr_indexed_variables(Self,Vars),
1213 Mref = mutable(passive(Vars)),
1217 generate_insert_constraint_internal(Clause) :-
1220 insert_constraint_internal(yes, Vars, Self, Closure, F, Args) :-
1221 Self =.. [suspension,Id,Mref,Closure,Gref,Href,F|Args],
1222 chr_indexed_variables(Self,Vars),
1223 'chr none_locked'(Vars),
1224 Mref = mutable(active),
1226 Href = mutable(History),
1227 'chr empty_history'(History),
1231 global_indexed_variables_clause(Constraints,Clause) :-
1232 ( forsome(C,Constraints,chr_translate:may_trigger(C)) ->
1233 Body = (Susp =.. [_,_,_,_,_,_,Term|_], '$indexed_variables'(Term,Vars))
1238 Clause = ( chr_indexed_variables(Susp,Vars) :- Body ).
1240 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1241 generate_attach_increment(Clauses) :-
1242 get_max_constraint_index(N),
1244 Clauses = [Clause1,Clause2],
1245 generate_attach_increment_empty(Clause1),
1247 generate_attach_increment_one(Clause2)
1249 generate_attach_increment_many(N,Clause2)
1255 generate_attach_increment_empty((attach_increment([],_) :- true)).
1257 generate_attach_increment_one(Clause) :-
1258 Head = attach_increment([Var|Vars],Susps),
1259 get_target_module(Mod),
1262 'chr not_locked'(Var),
1263 ( get_attr(Var,Mod,VarSusps) ->
1264 sort(VarSusps,SortedVarSusps),
1265 merge(Susps,SortedVarSusps,MergedSusps),
1266 put_attr(Var,Mod,MergedSusps)
1268 put_attr(Var,Mod,Susps)
1270 attach_increment(Vars,Susps)
1272 Clause = (Head :- Body).
1274 generate_attach_increment_many(N,Clause) :-
1275 make_attr(N,Mask,SuspsList,Attr),
1276 make_attr(N,OtherMask,OtherSuspsList,OtherAttr),
1277 Head = attach_increment([Var|Vars],Attr),
1278 bagof(G,X ^ Y ^ SY ^ M ^ (member2(SuspsList,OtherSuspsList,X-Y),G = (sort(Y,SY),'chr merge_attributes'(X,SY,M))),Gs),
1279 list2conj(Gs,SortGoals),
1280 bagof(MS,A ^ B ^ C ^ member((A,'chr merge_attributes'(B,C,MS)),Gs), MergedSuspsList),
1281 make_attr(N,MergedMask,MergedSuspsList,NewAttr),
1282 get_target_module(Mod),
1285 'chr not_locked'(Var),
1286 ( get_attr(Var,Mod,TOtherAttr) ->
1287 TOtherAttr = OtherAttr,
1289 MergedMask is Mask \/ OtherMask,
1290 put_attr(Var,Mod,NewAttr)
1292 put_attr(Var,Mod,Attr)
1294 attach_increment(Vars,Attr)
1296 Clause = (Head :- Body).
1299 generate_attr_unify_hook([Clause]) :-
1300 get_max_constraint_index(N),
1302 get_target_module(Mod),
1304 ( attr_unify_hook(Attr,Var) :-
1305 write('ERROR: Unexpected triggering of attr_unify_hook/2 in module '),
1309 generate_attr_unify_hook_one(Clause)
1311 generate_attr_unify_hook_many(N,Clause)
1314 generate_attr_unify_hook_one(Clause) :-
1315 Head = attr_unify_hook(Susps,Other),
1316 get_target_module(Mod),
1317 make_run_suspensions(NewSusps,WakeNewSusps),
1318 make_run_suspensions(Susps,WakeSusps),
1321 sort(Susps, SortedSusps),
1323 ( get_attr(Other,Mod,OtherSusps) ->
1328 sort(OtherSusps,SortedOtherSusps),
1329 'chr merge_attributes'(SortedSusps,SortedOtherSusps,NewSusps),
1330 put_attr(Other,Mod,NewSusps),
1333 ( compound(Other) ->
1334 term_variables(Other,OtherVars),
1335 attach_increment(OtherVars, SortedSusps)
1342 Clause = (Head :- Body).
1344 generate_attr_unify_hook_many(N,Clause) :-
1345 make_attr(N,Mask,SuspsList,Attr),
1346 make_attr(N,OtherMask,OtherSuspsList,OtherAttr),
1347 bagof(Sort,A ^ B ^ ( member(A,SuspsList) , Sort = sort(A,B) ) , SortGoalList),
1348 list2conj(SortGoalList,SortGoals),
1349 bagof(B, A ^ member(sort(A,B),SortGoalList), SortedSuspsList),
1350 bagof(C, D ^ E ^ F ^ G ^ (member2(SortedSuspsList,OtherSuspsList,D-E),
1352 'chr merge_attributes'(D,F,G)) ),
1354 bagof(G, D ^ F ^ H ^ member((H,'chr merge_attributes'(D,F,G)),SortMergeGoalList) , MergedSuspsList),
1355 list2conj(SortMergeGoalList,SortMergeGoals),
1356 make_attr(N,MergedMask,MergedSuspsList,MergedAttr),
1357 make_attr(N,Mask,SortedSuspsList,SortedAttr),
1358 Head = attr_unify_hook(Attr,Other),
1359 get_target_module(Mod),
1360 make_run_suspensions_loop(MergedSuspsList,WakeMergedSusps),
1361 make_run_suspensions_loop(SortedSuspsList,WakeSortedSusps),
1366 ( get_attr(Other,Mod,TOtherAttr) ->
1367 TOtherAttr = OtherAttr,
1369 MergedMask is Mask \/ OtherMask,
1370 put_attr(Other,Mod,MergedAttr),
1373 put_attr(Other,Mod,SortedAttr),
1377 ( compound(Other) ->
1378 term_variables(Other,OtherVars),
1379 attach_increment(OtherVars,SortedAttr)
1386 Clause = (Head :- Body).
1388 make_run_suspensions(Susps,Goal) :-
1389 ( chr_pp_flag(debugable,on) ->
1390 Goal = 'chr run_suspensions_d'(Susps)
1392 Goal = 'chr run_suspensions'(Susps)
1395 make_run_suspensions_loop(SuspsList,Goal) :-
1396 ( chr_pp_flag(debugable,on) ->
1397 Goal = 'chr run_suspensions_loop_d'(SuspsList)
1399 Goal = 'chr run_suspensions_loop'(SuspsList)
1402 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1403 % $insert_in_store_F/A
1404 % $delete_from_store_F/A
1406 generate_insert_delete_constraints([],[]).
1407 generate_insert_delete_constraints([FA|Rest],Clauses) :-
1408 ( is_attached(FA) ->
1409 Clauses = [IClause,DClause|RestClauses],
1410 generate_insert_delete_constraint(FA,IClause,DClause)
1412 Clauses = RestClauses
1414 generate_insert_delete_constraints(Rest,RestClauses).
1416 generate_insert_delete_constraint(FA,IClause,DClause) :-
1417 get_store_type(FA,StoreType),
1418 generate_insert_constraint(StoreType,FA,IClause),
1419 generate_delete_constraint(StoreType,FA,DClause).
1421 generate_insert_constraint(StoreType,C,Clause) :-
1422 make_name('$insert_in_store_',C,ClauseName),
1423 Head =.. [ClauseName,Susp],
1424 generate_insert_constraint_body(StoreType,C,Susp,Body),
1425 Clause = (Head :- Body).
1427 generate_insert_constraint_body(default,C,Susp,Body) :-
1428 get_target_module(Mod),
1429 get_max_constraint_index(Total),
1431 generate_attach_body_1(C,Store,Susp,AttachBody)
1433 generate_attach_body_n(C,Store,Susp,AttachBody)
1437 'chr global_term_ref_1'(Store),
1440 generate_insert_constraint_body(multi_hash(Indexes),C,Susp,Body) :-
1441 generate_multi_hash_insert_constraint_bodies(Indexes,C,Susp,Body).
1442 generate_insert_constraint_body(global_ground,C,Susp,Body) :-
1443 global_ground_store_name(C,StoreName),
1446 nb_getval(StoreName,Store),
1447 b_setval(StoreName,[Susp|Store])
1449 generate_insert_constraint_body(multi_store(StoreTypes),C,Susp,Body) :-
1450 find_with_var_identity(
1454 member(ST,StoreTypes),
1455 chr_translate:generate_insert_constraint_body(ST,C,Susp,B)
1459 list2conj(Bodies,Body).
1461 generate_multi_hash_insert_constraint_bodies([],_,_,true).
1462 generate_multi_hash_insert_constraint_bodies([Index|Indexes],FA,Susp,(Body,Bodies)) :-
1463 multi_hash_store_name(FA,Index,StoreName),
1464 multi_hash_key(FA,Index,Susp,KeyBody,Key),
1468 nb_getval(StoreName,Store),
1469 insert_ht(Store,Key,Susp)
1471 generate_multi_hash_insert_constraint_bodies(Indexes,FA,Susp,Bodies).
1473 generate_delete_constraint(StoreType,FA,Clause) :-
1474 make_name('$delete_from_store_',FA,ClauseName),
1475 Head =.. [ClauseName,Susp],
1476 generate_delete_constraint_body(StoreType,FA,Susp,Body),
1477 Clause = (Head :- Body).
1479 generate_delete_constraint_body(default,C,Susp,Body) :-
1480 get_target_module(Mod),
1481 get_max_constraint_index(Total),
1483 generate_detach_body_1(C,Store,Susp,DetachBody),
1486 'chr global_term_ref_1'(Store),
1490 generate_detach_body_n(C,Store,Susp,DetachBody),
1493 'chr global_term_ref_1'(Store),
1497 generate_delete_constraint_body(multi_hash(Indexes),C,Susp,Body) :-
1498 generate_multi_hash_delete_constraint_bodies(Indexes,C,Susp,Body).
1499 generate_delete_constraint_body(global_ground,C,Susp,Body) :-
1500 global_ground_store_name(C,StoreName),
1503 nb_getval(StoreName,Store),
1504 'chr sbag_del_element'(Store,Susp,NStore),
1505 b_setval(StoreName,NStore)
1507 generate_delete_constraint_body(multi_store(StoreTypes),C,Susp,Body) :-
1508 find_with_var_identity(
1512 member(ST,StoreTypes),
1513 chr_translate:generate_delete_constraint_body(ST,C,Susp,B)
1517 list2conj(Bodies,Body).
1519 generate_multi_hash_delete_constraint_bodies([],_,_,true).
1520 generate_multi_hash_delete_constraint_bodies([Index|Indexes],FA,Susp,(Body,Bodies)) :-
1521 multi_hash_store_name(FA,Index,StoreName),
1522 multi_hash_key(FA,Index,Susp,KeyBody,Key),
1526 nb_getval(StoreName,Store),
1527 delete_ht(Store,Key,Susp)
1529 generate_multi_hash_delete_constraint_bodies(Indexes,FA,Susp,Bodies).
1531 generate_delete_constraint_call(FA,Susp,Call) :-
1532 make_name('$delete_from_store_',FA,Functor),
1533 Call =.. [Functor,Susp].
1535 generate_insert_constraint_call(FA,Susp,Call) :-
1536 make_name('$insert_in_store_',FA,Functor),
1537 Call =.. [Functor,Susp].
1539 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1541 generate_store_code(Constraints,[Enumerate|L]) :-
1542 enumerate_stores_code(Constraints,Enumerate),
1543 generate_store_code(Constraints,L,[]).
1545 generate_store_code([],L,L).
1546 generate_store_code([C|Cs],L,T) :-
1547 get_store_type(C,StoreType),
1548 generate_store_code(StoreType,C,L,L1),
1549 generate_store_code(Cs,L1,T).
1551 generate_store_code(default,_,L,L).
1552 generate_store_code(multi_hash(Indexes),C,L,T) :-
1553 multi_hash_store_initialisations(Indexes,C,L,L1),
1554 multi_hash_via_lookups(Indexes,C,L1,T).
1555 generate_store_code(global_ground,C,L,T) :-
1556 global_ground_store_initialisation(C,L,T).
1557 generate_store_code(multi_store(StoreTypes),C,L,T) :-
1558 multi_store_generate_store_code(StoreTypes,C,L,T).
1560 multi_store_generate_store_code([],_,L,L).
1561 multi_store_generate_store_code([ST|STs],C,L,T) :-
1562 generate_store_code(ST,C,L,L1),
1563 multi_store_generate_store_code(STs,C,L1,T).
1565 multi_hash_store_initialisations([],_,L,L).
1566 multi_hash_store_initialisations([Index|Indexes],FA,L,T) :-
1567 multi_hash_store_name(FA,Index,StoreName),
1568 L = [(:- (new_ht(HT),nb_setval(StoreName,HT)) )|L1],
1569 multi_hash_store_initialisations(Indexes,FA,L1,T).
1571 global_ground_store_initialisation(C,L,T) :-
1572 global_ground_store_name(C,StoreName),
1573 L = [(:- nb_setval(StoreName,[]))|T].
1575 multi_hash_via_lookups([],_,L,L).
1576 multi_hash_via_lookups([Index|Indexes],C,L,T) :-
1577 multi_hash_via_lookup_name(C,Index,PredName),
1578 Head =.. [PredName,Key,SuspsList],
1579 multi_hash_store_name(C,Index,StoreName),
1582 nb_getval(StoreName,HT),
1583 lookup_ht(HT,Key,SuspsList)
1585 L = [(Head :- Body)|L1],
1586 multi_hash_via_lookups(Indexes,C,L1,T).
1588 multi_hash_via_lookup_name(F/A,Index,Name) :-
1592 atom_concat_list(Index,IndexName)
1594 atom_concat_list(['$via1_multi_hash_',F,(/),A,'-',IndexName],Name).
1596 multi_hash_store_name(F/A,Index,Name) :-
1597 get_target_module(Mod),
1601 atom_concat_list(Index,IndexName)
1603 atom_concat_list(['$chr_store_multi_hash_',Mod,(:),F,(/),A,'-',IndexName],Name).
1605 multi_hash_key(F/A,Index,Susp,KeyBody,Key) :-
1606 ( ( integer(Index) ->
1612 KeyBody = arg(SuspIndex,Susp,Key)
1614 sort(Index,Indexes),
1615 find_with_var_identity(arg(J,Susp,KeyI)-KeyI,[Susp],(member(I,Indexes),J is I + 6),ArgKeyPairs),
1616 pairup(Bodies,Keys,ArgKeyPairs),
1618 list2conj(Bodies,KeyBody)
1621 multi_hash_key_args(Index,Head,KeyArgs) :-
1623 arg(Index,Head,Arg),
1626 sort(Index,Indexes),
1627 term_variables(Head,Vars),
1628 find_with_var_identity(Arg,Vars,(member(I,Indexes), arg(I,Head,Arg)),KeyArgs)
1631 global_ground_store_name(F/A,Name) :-
1632 get_target_module(Mod),
1633 atom_concat_list(['$chr_store_global_ground_',Mod,(:),F,(/),A],Name).
1634 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1635 enumerate_stores_code(Constraints,Clause) :-
1636 Head = '$enumerate_suspensions'(Susp),
1637 enumerate_store_bodies(Constraints,Susp,Bodies),
1638 list2disj(Bodies,Body),
1639 Clause = (Head :- Body).
1641 enumerate_store_bodies([],_,[]).
1642 enumerate_store_bodies([C|Cs],Susp,L) :-
1644 get_store_type(C,StoreType),
1645 enumerate_store_body(StoreType,C,Susp,B),
1650 enumerate_store_bodies(Cs,Susp,T).
1652 enumerate_store_body(default,C,Susp,Body) :-
1653 get_constraint_index(C,Index),
1654 get_target_module(Mod),
1655 get_max_constraint_index(MaxIndex),
1658 'chr global_term_ref_1'(GlobalStore),
1659 get_attr(GlobalStore,Mod,Attr)
1662 NIndex is Index + 1,
1665 arg(NIndex,Attr,List),
1666 'chr sbag_member'(Susp,List)
1669 Body2 = 'chr sbag_member'(Susp,Attr)
1671 Body = (Body1,Body2).
1672 enumerate_store_body(multi_hash([Index|_]),C,Susp,Body) :-
1673 multi_hash_enumerate_store_body(Index,C,Susp,Body).
1674 enumerate_store_body(global_ground,C,Susp,Body) :-
1675 global_ground_store_name(C,StoreName),
1678 nb_getval(StoreName,List),
1679 'chr sbag_member'(Susp,List)
1681 enumerate_store_body(multi_store(STs),C,Susp,Body) :-
1684 enumerate_store_body(ST,C,Susp,Body)
1687 multi_hash_enumerate_store_body(I,C,Susp,B) :-
1688 multi_hash_store_name(C,I,StoreName),
1691 nb_getval(StoreName,HT),
1694 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1695 check_attachments(Constraints) :-
1696 ( chr_pp_flag(check_attachments,on) ->
1697 check_constraint_attachments(Constraints)
1702 check_constraint_attachments([]).
1703 check_constraint_attachments([C|Cs]) :-
1704 check_constraint_attachment(C),
1705 check_constraint_attachments(Cs).
1707 check_constraint_attachment(C) :-
1708 get_max_occurrence(C,MO),
1709 check_occurrences_attachment(C,1,MO).
1711 check_occurrences_attachment(C,O,MO) :-
1715 check_occurrence_attachment(C,O),
1717 check_occurrences_attachment(C,NO,MO)
1720 check_occurrence_attachment(C,O) :-
1721 get_occurrence(C,O,RuleNb,ID),
1722 get_rule(RuleNb,PragmaRule),
1723 PragmaRule = pragma(rule(Heads1,Heads2,Guard,Body),ids(IDs1,IDs2),_,_,_),
1724 ( select2(ID,Head1,IDs1,Heads1,RIDs1,RHeads1) ->
1725 check_attachment_head1(Head1,ID,RuleNb,Heads1,Heads2,Guard)
1726 ; select2(ID,Head2,IDs2,Heads2,RIDs2,RHeads2) ->
1727 check_attachment_head2(Head2,ID,RuleNb,Heads1,Body)
1730 check_attachment_head1(C,ID,RuleNb,H1,H2,G) :-
1737 \+ is_passive(RuleNb,ID) ->
1744 no_matching([X|Xs],Prev) :-
1746 \+ memberchk_eq(X,Prev),
1747 no_matching(Xs,[X|Prev]).
1749 check_attachment_head2(C,ID,RuleNb,H1,B) :-
1751 ( is_passive(RuleNb,ID) ->
1761 all_attached([C|Cs]) :-
1766 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1768 set_constraint_indices([],M) :-
1770 max_constraint_index(N).
1771 set_constraint_indices([C|Cs],N) :-
1772 ( ( may_trigger(C) ; is_attached(C), get_store_type(C,default)) ->
1773 constraint_index(C,N),
1775 set_constraint_indices(Cs,M)
1777 set_constraint_indices(Cs,N)
1780 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1781 %% ____ _ ____ _ _ _ _
1782 %% | _ \ _ _| | ___ / ___|___ _ __ ___ _ __ (_) | __ _| |_(_) ___ _ __
1783 %% | |_) | | | | |/ _ \ | | / _ \| '_ ` _ \| '_ \| | |/ _` | __| |/ _ \| '_ \
1784 %% | _ <| |_| | | __/ | |__| (_) | | | | | | |_) | | | (_| | |_| | (_) | | | |
1785 %% |_| \_\\__,_|_|\___| \____\___/|_| |_| |_| .__/|_|_|\__,_|\__|_|\___/|_| |_|
1788 constraints_code(Constraints,Rules,Clauses) :-
1789 post_constraints(Constraints,1),
1790 constraints_code1(1,Rules,L,[]),
1791 clean_clauses(L,Clauses).
1794 post_constraints([],MaxIndex1) :-
1795 MaxIndex is MaxIndex1 - 1,
1796 constraint_count(MaxIndex).
1797 post_constraints([F/A|Cs],N) :-
1800 post_constraints(Cs,M).
1801 constraints_code1(I,Rules,L,T) :-
1802 get_constraint_count(N),
1806 constraint_code(I,Rules,L,T1),
1808 constraints_code1(J,Rules,T1,T)
1811 %% Generate code for a single CHR constraint
1812 constraint_code(I, Rules, L, T) :-
1813 get_constraint(Constraint,I),
1814 constraint_prelude(Constraint,Clause),
1817 rules_code(Rules,I,Id1,Id2,L1,L2),
1818 gen_cond_attach_clause(Constraint,Id2,L2,T).
1820 %% Generate prelude predicate for a constraint.
1821 %% f(...) :- f/a_0(...,Susp).
1822 constraint_prelude(F/A, Clause) :-
1823 vars_susp(A,Vars,Susp,VarsSusp),
1824 Head =.. [ F | Vars],
1825 build_head(F,A,[0],VarsSusp,Delegate),
1826 get_target_module(Mod),
1828 ( chr_pp_flag(debugable,on) ->
1831 allocate_constraint(Mod : Delegate, Susp, FTerm, Vars),
1833 'chr debug_event'(call(Susp)),
1836 'chr debug_event'(fail(Susp)), !,
1840 'chr debug_event'(exit(Susp))
1842 'chr debug_event'(redo(Susp)),
1847 Clause = ( Head :- Delegate )
1850 gen_cond_attach_clause(F/A,Id,L,T) :-
1851 ( is_attached(F/A) ->
1853 ( may_trigger(F/A) ->
1854 gen_cond_attach_goal(F/A,Body,AllArgs,Args,Susp)
1856 gen_insert_constraint_internal_goal(F/A,Body,AllArgs,Args,Susp)
1858 ; vars_susp(A,Args,Susp,AllArgs),
1859 gen_uncond_attach_goal(F/A,Susp,Body,_)
1861 ( chr_pp_flag(debugable,on) ->
1862 Constraint =.. [F|Args],
1863 DebugEvent = 'chr debug_event'(insert(Constraint#Susp))
1867 build_head(F,A,Id,AllArgs,Head),
1868 Clause = ( Head :- DebugEvent,Body ),
1874 gen_cond_attach_goal(F/A,Goal,AllArgs,Args,Susp) :-
1875 vars_susp(A,Args,Susp,AllArgs),
1876 build_head(F,A,[0],AllArgs,Closure),
1877 ( may_trigger(F/A) ->
1878 make_name('attach_',F/A,AttachF),
1879 Attach =.. [AttachF,Vars,Susp]
1883 get_target_module(Mod),
1885 generate_insert_constraint_call(F/A,Susp,InsertCall),
1889 insert_constraint_internal(Stored,Vars,Susp,Mod:Closure,FTerm,Args)
1891 activate_constraint(Stored,Vars,Susp,_)
1901 gen_insert_constraint_internal_goal(F/A,Goal,AllArgs,Args,Susp) :-
1902 vars_susp(A,Args,Susp,AllArgs),
1903 build_head(F,A,[0],AllArgs,Closure),
1904 ( may_trigger(F/A) ->
1905 make_name('attach_',F/A,AttachF),
1906 Attach =.. [AttachF,Vars,Susp]
1910 get_target_module(Mod),
1912 generate_insert_constraint_call(F/A,Susp,InsertCall),
1915 insert_constraint_internal(_,Vars,Susp,Mod:Closure,FTerm,Args),
1920 gen_uncond_attach_goal(FA,Susp,AttachGoal,Generation) :-
1921 ( may_trigger(FA) ->
1922 make_name('attach_',FA,AttachF),
1923 Attach =.. [AttachF,Vars,Susp]
1927 generate_insert_constraint_call(FA,Susp,InsertCall),
1930 activate_constraint(Stored,Vars, Susp, Generation),
1939 occurrences_code(O,MO,C,Id,NId,L,T) :-
1944 occurrence_code(O,C,Id,Id1,L,L1),
1946 occurrences_code(NO,MO,C,Id1,NId,L1,T)
1949 occurrences_code(O,C,Id,NId,L,T) :-
1950 get_occurrence(C,O,RuleNb,ID),
1951 ( is_passive(RuleNb,ID) ->
1955 get_rule(RuleNb,PragmaRule),
1956 PragmaRule = pragma(rule(Heads1,Heads2,_,_),ids(IDs1,IDs2),_,_,_),
1957 ( select2(IDs1,Heads1,ID,Head1,RIDs1,RHeads1) ->
1959 head1_code(Head1,RHeads1,RIDs1,PragmaRule,C,Id,L,T)
1960 ; select2(IDs2,Heads2,ID,Head2,RIDs2,RHeads2) ->
1961 length(RHeads2,RestHeadNb),
1962 head2_code(Head2,RHeads2,RIDs2,PragmaRule,RestHeadNb,C,Id,L,L1),
1964 gen_alloc_inc_clause(C,Id,L1,T)
1969 %% Generate all the code for a constraint based on all CHR rules
1970 rules_code([],_,Id,Id,L,L).
1971 rules_code([R |Rs],I,Id1,Id3,L,T) :-
1972 rule_code(R,I,Id1,Id2,L,T1),
1973 rules_code(Rs,I,Id2,Id3,T1,T).
1975 %% Generate code for a constraint based on a single CHR rule
1976 rule_code(PragmaRule,I,Id1,Id2,L,T) :-
1977 PragmaRule = pragma(Rule,HeadIDs,_Pragmas,_Name,_RuleNb),
1978 HeadIDs = ids(Head1IDs,Head2IDs),
1979 Rule = rule(Head1,Head2,_,_),
1980 heads1_code(Head1,[],Head1IDs,[],PragmaRule,I,Id1,L,L1),
1981 heads2_code(Head2,[],Head2IDs,[],PragmaRule,I,Id1,Id2,L1,T).
1983 %% Generate code based on all the removed heads of a CHR rule
1984 heads1_code([],_,_,_,_,_,_,L,L).
1985 heads1_code([Head|Heads],RestHeads,[HeadID|HeadIDs],RestIDs,PragmaRule,I,Id,L,T) :-
1986 PragmaRule = pragma(Rule,_,_Pragmas,_Name,RuleNb),
1987 get_constraint(F/A,I),
1988 ( functor(Head,F,A),
1989 \+ is_passive(RuleNb,HeadID),
1990 \+ check_unnecessary_active(Head,RestHeads,Rule),
1991 all_attached(Heads),
1992 all_attached(RestHeads),
1993 Rule = rule(_,Heads2,_,_),
1994 all_attached(Heads2) ->
1995 append(Heads,RestHeads,OtherHeads),
1996 append(HeadIDs,RestIDs,OtherIDs),
1997 head1_code(Head,OtherHeads,OtherIDs,PragmaRule,F/A,I,Id,L,L1)
2001 heads1_code(Heads,[Head|RestHeads],HeadIDs,[HeadID|RestIDs],PragmaRule,I,Id,L1,T).
2003 %% Generate code based on one removed head of a CHR rule
2004 head1_code(Head,OtherHeads,OtherIDs,PragmaRule,FA,I,Id,L,T) :-
2005 PragmaRule = pragma(Rule,_,_,_Name,RuleNb),
2006 Rule = rule(_,Head2,_,_),
2008 reorder_heads(RuleNb,Head,OtherHeads,OtherIDs,NOtherHeads,NOtherIDs),
2009 simplification_code(Head,NOtherHeads,NOtherIDs,PragmaRule,FA,Id,L,T)
2011 simpagation_head1_code(Head,OtherHeads,OtherIDs,PragmaRule,FA,Id,L,T)
2014 %% Generate code based on all the persistent heads of a CHR rule
2015 heads2_code([],_,_,_,_,_,Id,Id,L,L).
2016 heads2_code([Head|Heads],RestHeads,[HeadID|HeadIDs],RestIDs,PragmaRule,I,Id1,Id3,L,T) :-
2017 PragmaRule = pragma(Rule,_,_Pragmas,_Name,RuleNb),
2018 get_constraint(F/A,I),
2019 ( functor(Head,F,A),
2020 \+ is_passive(RuleNb,HeadID),
2021 \+ check_unnecessary_active(Head,RestHeads,Rule),
2022 \+ set_semantics_rule(PragmaRule),
2023 all_attached(Heads),
2024 all_attached(RestHeads),
2025 Rule = rule(Heads1,_,_,_),
2026 all_attached(Heads1) ->
2027 append(Heads,RestHeads,OtherHeads),
2028 append(HeadIDs,RestIDs,OtherIDs),
2029 length(Heads,RestHeadNb),
2030 head2_code(Head,OtherHeads,OtherIDs,PragmaRule,RestHeadNb,F/A,Id1,L,L0),
2032 gen_alloc_inc_clause(F/A,Id1,L0,L1)
2037 heads2_code(Heads,[Head|RestHeads],HeadIDs,[HeadID|RestIDs],PragmaRule,I,Id2,Id3,L1,T).
2039 %% Generate code based on one persistent head of a CHR rule
2040 head2_code(Head,OtherHeads,OtherIDs,PragmaRule,RestHeadNb,FA,Id,L,T) :-
2041 PragmaRule = pragma(Rule,_,_,_Name,RuleNb),
2042 Rule = rule(Head1,_,_,_),
2044 reorder_heads(RuleNb,Head,OtherHeads,OtherIDs,NOtherHeads,_),
2045 propagation_code(Head,NOtherHeads,Rule,RuleNb,RestHeadNb,FA,Id,L,T)
2047 simpagation_head2_code(Head,OtherHeads,OtherIDs,PragmaRule,FA,Id,L,T)
2050 gen_alloc_inc_clause(F/A,Id,L,T) :-
2051 vars_susp(A,Vars,Susp,VarsSusp),
2052 build_head(F,A,Id,VarsSusp,Head),
2054 build_head(F,A,IncId,VarsSusp,CallHead),
2055 gen_allocation(Id,Vars,Susp,F/A,VarsSusp,ConditionalAlloc),
2064 gen_cond_allocation(Vars,Susp,FA,VarsSusp,ConstraintAllocationGoal) :-
2065 gen_allocation(Vars,Susp,FA,VarsSusp,UncondConstraintAllocationGoal),
2066 ConstraintAllocationGoal =
2068 UncondConstraintAllocationGoal
2072 gen_allocation(Vars,Susp,F/A,VarsSusp,ConstraintAllocationGoal) :-
2073 build_head(F,A,[0],VarsSusp,Term),
2074 get_target_module(Mod),
2076 ConstraintAllocationGoal = allocate_constraint(Mod : Term, Susp, FTerm, Vars).
2078 gen_allocation(Id,Vars,Susp,FA,VarsSusp,ConstraintAllocationGoal) :-
2080 ( is_attached(FA) ->
2081 ( may_trigger(FA) ->
2082 gen_cond_allocation(Vars,Susp,FA,VarsSusp,ConstraintAllocationGoal)
2084 gen_allocation(Vars,Susp,FA,VarsSusp,ConstraintAllocationGoal)
2087 ConstraintAllocationGoal = true
2090 ConstraintAllocationGoal = true
2092 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2095 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2097 guard_via_reschedule(Retrievals,GuardList,Prelude,Goal) :-
2098 ( chr_pp_flag(guard_via_reschedule,on) ->
2099 guard_via_reschedule_main(Retrievals,GuardList,Prelude,Goal)
2101 append(Retrievals,GuardList,GoalList),
2102 list2conj(GoalList,Goal)
2105 guard_via_reschedule_main(Retrievals,GuardList,Prelude,Goal) :-
2106 initialize_unit_dictionary(Prelude,Dict),
2107 build_units(Retrievals,GuardList,Dict,Units),
2108 dependency_reorder(Units,NUnits),
2109 units2goal(NUnits,Goal).
2111 units2goal([],true).
2112 units2goal([unit(_,Goal,_,_)|Units],(Goal,Goals)) :-
2113 units2goal(Units,Goals).
2115 dependency_reorder(Units,NUnits) :-
2116 dependency_reorder(Units,[],NUnits).
2118 dependency_reorder([],Acc,Result) :-
2119 reverse(Acc,Result).
2121 dependency_reorder([Unit|Units],Acc,Result) :-
2122 Unit = unit(_GID,_Goal,Type,GIDs),
2126 dependency_insert(Acc,Unit,GIDs,NAcc)
2128 dependency_reorder(Units,NAcc,Result).
2130 dependency_insert([],Unit,_,[Unit]).
2131 dependency_insert([X|Xs],Unit,GIDs,L) :-
2132 X = unit(GID,_,_,_),
2133 ( memberchk(GID,GIDs) ->
2137 dependency_insert(Xs,Unit,GIDs,T)
2140 build_units(Retrievals,Guard,InitialDict,Units) :-
2141 build_retrieval_units(Retrievals,1,N,InitialDict,Dict,Units,Tail),
2142 build_guard_units(Guard,N,Dict,Tail).
2144 build_retrieval_units([],N,N,Dict,Dict,L,L).
2145 build_retrieval_units([U|Us],N,M,Dict,NDict,L,T) :-
2146 term_variables(U,Vs),
2147 update_unit_dictionary(Vs,N,Dict,Dict1,[],GIDs),
2148 L = [unit(N,U,movable,GIDs)|L1],
2150 build_retrieval_units2(Us,N1,M,Dict1,NDict,L1,T).
2152 build_retrieval_units2([],N,N,Dict,Dict,L,L).
2153 build_retrieval_units2([U|Us],N,M,Dict,NDict,L,T) :-
2154 term_variables(U,Vs),
2155 update_unit_dictionary(Vs,N,Dict,Dict1,[],GIDs),
2156 L = [unit(N,U,fixed,GIDs)|L1],
2158 build_retrieval_units(Us,N1,M,Dict1,NDict,L1,T).
2160 initialize_unit_dictionary(Term,Dict) :-
2161 term_variables(Term,Vars),
2162 pair_all_with(Vars,0,Dict).
2164 update_unit_dictionary([],_,Dict,Dict,GIDs,GIDs).
2165 update_unit_dictionary([V|Vs],This,Dict,NDict,GIDs,NGIDs) :-
2166 ( lookup_eq(Dict,V,GID) ->
2167 ( (GID == This ; memberchk(GID,GIDs) ) ->
2174 Dict1 = [V - This|Dict],
2177 update_unit_dictionary(Vs,This,Dict1,NDict,GIDs1,NGIDs).
2179 build_guard_units(Guard,N,Dict,Units) :-
2181 Units = [unit(N,Goal,fixed,[])]
2182 ; Guard = [Goal|Goals] ->
2183 term_variables(Goal,Vs),
2184 update_unit_dictionary2(Vs,N,Dict,NDict,[],GIDs),
2185 Units = [unit(N,Goal,movable,GIDs)|RUnits],
2187 build_guard_units(Goals,N1,NDict,RUnits)
2190 update_unit_dictionary2([],_,Dict,Dict,GIDs,GIDs).
2191 update_unit_dictionary2([V|Vs],This,Dict,NDict,GIDs,NGIDs) :-
2192 ( lookup_eq(Dict,V,GID) ->
2193 ( (GID == This ; memberchk(GID,GIDs) ) ->
2198 Dict1 = [V - This|Dict]
2200 Dict1 = [V - This|Dict],
2203 update_unit_dictionary2(Vs,This,Dict1,NDict,GIDs1,NGIDs).
2205 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2207 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2209 %% / ___| ___| |_ / ___| ___ _ __ ___ __ _ _ __ | |_(_) ___ ___ _
2210 %% \___ \ / _ \ __| \___ \ / _ \ '_ ` _ \ / _` | '_ \| __| |/ __/ __(_)
2211 %% ___) | __/ |_ ___) | __/ | | | | | (_| | | | | |_| | (__\__ \_
2212 %% |____/ \___|\__| |____/ \___|_| |_| |_|\__,_|_| |_|\__|_|\___|___(_)
2215 %% | | | |_ __ (_) __ _ _ _ ___ |_ _|_ __ / _| ___ _ __ ___ _ __ ___ ___
2216 %% | | | | '_ \| |/ _` | | | |/ _ \ | || '_ \| |_ / _ \ '__/ _ \ '_ \ / __/ _ \
2217 %% | |_| | | | | | (_| | |_| | __/ | || | | | _| __/ | | __/ | | | (_| __/
2218 %% \___/|_| |_|_|\__, |\__,_|\___| |___|_| |_|_| \___|_| \___|_| |_|\___\___|
2220 unique_analyse_optimise(Rules,NRules) :-
2221 ( chr_pp_flag(unique_analyse_optimise,on) ->
2222 unique_analyse_optimise_main(Rules,1,[],NRules)
2227 unique_analyse_optimise_main([],_,_,[]).
2228 unique_analyse_optimise_main([PRule|PRules],N,PatternList,[NPRule|NPRules]) :-
2229 ( discover_unique_pattern(PRule,N,Pattern) ->
2230 NPatternList = [Pattern|PatternList]
2232 NPatternList = PatternList
2234 PRule = pragma(Rule,Ids,Pragmas,Name,RuleNb),
2235 Rule = rule(H1,H2,_,_),
2236 Ids = ids(Ids1,Ids2),
2237 apply_unique_patterns_to_constraints(H1,Ids1,NPatternList,MorePragmas1),
2238 apply_unique_patterns_to_constraints(H2,Ids2,NPatternList,MorePragmas2),
2239 globalize_unique_pragmas(MorePragmas1,RuleNb),
2240 globalize_unique_pragmas(MorePragmas2,RuleNb),
2241 append_lists([MorePragmas1,MorePragmas2,Pragmas],NPragmas),
2242 NPRule = pragma(Rule,Ids,NPragmas,Name,RuleNb),
2244 unique_analyse_optimise_main(PRules,N1,NPatternList,NPRules).
2246 globalize_unique_pragmas([],_).
2247 globalize_unique_pragmas([unique(ID,Vars)|R],RuleNb) :-
2248 pragma_unique(RuleNb,ID,Vars),
2249 globalize_unique_pragmas(R,RuleNb).
2251 apply_unique_patterns_to_constraints([],_,_,[]).
2252 apply_unique_patterns_to_constraints([C|Cs],[Id|Ids],Patterns,Pragmas) :-
2253 ( member(Pattern,Patterns),
2254 apply_unique_pattern(C,Id,Pattern,Pragma) ->
2255 Pragmas = [Pragma | RPragmas]
2259 apply_unique_patterns_to_constraints(Cs,Ids,Patterns,RPragmas).
2261 apply_unique_pattern(Constraint,Id,Pattern,Pragma) :-
2262 Pattern = unique(PatternConstraint,PatternKey),
2263 subsumes(Constraint,PatternConstraint,Unifier),
2266 member(T,PatternKey),
2267 lookup_eq(Unifier,T,Term),
2268 term_variables(Term,Vs),
2276 Pragma = unique(Id,Vars).
2278 % subsumes(+Term1, +Term2, -Unifier)
2280 % If Term1 is a more general term than Term2 (e.g. has a larger
2281 % part instantiated), unify Unifier with a list Var-Value of
2282 % variables from Term2 and their corresponding values in Term1.
2284 subsumes(Term1,Term2,Unifier) :-
2286 subsumes_aux(Term1,Term2,S0,S),
2288 build_unifier(L,Unifier).
2290 subsumes_aux(Term1, Term2, S0, S) :-
2292 functor(Term2, F, N)
2293 -> compound(Term1), functor(Term1, F, N),
2294 subsumes_aux(N, Term1, Term2, S0, S)
2298 get_assoc(Term1,S0,V)
2299 -> V == Term2, S = S0
2301 put_assoc(Term1, S0, Term2, S)
2304 subsumes_aux(0, _, _, S, S) :- ! .
2305 subsumes_aux(N, T1, T2, S0, S) :-
2308 subsumes_aux(T1x, T2x, S0, S1),
2310 subsumes_aux(M, T1, T2, S1, S).
2312 build_unifier([],[]).
2313 build_unifier([X-V|R],[V - X | T]) :-
2316 discover_unique_pattern(PragmaRule,RuleNb,Pattern) :-
2317 PragmaRule = pragma(Rule,_,_Pragmas,Name,RuleNb),
2318 Rule = rule(H1,H2,Guard,_),
2326 check_unique_constraints(C1,C2,Guard,RuleNb,List),
2327 term_variables(C1,Vs),
2328 select_pragma_unique_variables(List,Vs,Key),
2329 Pattern0 = unique(C1,Key),
2330 copy_term(Pattern0,Pattern),
2331 ( prolog_flag(verbose,V), V == yes ->
2332 format('Found unique pattern ~w in rule ~d~@\n',
2333 [Pattern,RuleNb,(Name=yes(N) -> write(": "),write(N) ; true)])
2338 select_pragma_unique_variables([],_,[]).
2339 select_pragma_unique_variables([X-Y|R],Vs,L) :-
2344 \+ memberchk_eq(X,Vs)
2346 \+ memberchk_eq(Y,Vs)
2350 select_pragma_unique_variables(R,Vs,T).
2352 check_unique_constraints(C1,C2,G,RuleNb,List) :-
2353 \+ any_passive_head(RuleNb),
2354 variable_replacement(C1-C2,C2-C1,List),
2355 copy_with_variable_replacement(G,OtherG,List),
2357 once(entails_b(NotG,OtherG)).
2359 check_unnecessary_active(Constraint,Previous,Rule) :-
2360 ( chr_pp_flag(check_unnecessary_active,full) ->
2361 check_unnecessary_active_main(Constraint,Previous,Rule)
2362 ; chr_pp_flag(check_unnecessary_active,simplification),
2363 Rule = rule(_,[],_,_) ->
2364 check_unnecessary_active_main(Constraint,Previous,Rule)
2369 check_unnecessary_active_main(Constraint,Previous,Rule) :-
2370 member(Other,Previous),
2371 variable_replacement(Other,Constraint,List),
2372 copy_with_variable_replacement(Rule,Rule2,List),
2373 identical_rules(Rule,Rule2), ! .
2375 set_semantics_rule(PragmaRule) :-
2376 ( chr_pp_flag(set_semantics_rule,on) ->
2377 set_semantics_rule_main(PragmaRule)
2382 set_semantics_rule_main(PragmaRule) :-
2383 PragmaRule = pragma(Rule,IDs,Pragmas,_,RuleNb),
2384 Rule = rule([C1],[C2],true,_),
2385 IDs = ids([ID1],[ID2]),
2386 once(member(unique(ID1,L1),Pragmas)),
2387 once(member(unique(ID2,L2),Pragmas)),
2389 \+ is_passive(RuleNb,ID1).
2390 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2392 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2394 %% | _ \ _ _| | ___ | ____|__ _ _ _(_)_ ____ _| | ___ _ __ ___ ___
2395 %% | |_) | | | | |/ _ \ | _| / _` | | | | \ \ / / _` | |/ _ \ '_ \ / __/ _ \
2396 %% | _ <| |_| | | __/ | |__| (_| | |_| | |\ V / (_| | | __/ | | | (_| __/
2397 %% |_| \_\\__,_|_|\___| |_____\__, |\__,_|_| \_/ \__,_|_|\___|_| |_|\___\___|
2399 % have to check for no duplicates in value list
2401 % check wether two rules are identical
2403 identical_rules(rule(H11,H21,G1,B1),rule(H12,H22,G2,B2)) :-
2405 identical_bodies(B1,B2),
2406 permutation(H11,P1),
2408 permutation(H21,P2),
2411 identical_bodies(B1,B2) :-
2423 % replace variables in list
2425 copy_with_variable_replacement(X,Y,L) :-
2427 ( lookup_eq(L,X,Y) ->
2435 copy_with_variable_replacement_l(XArgs,YArgs,L)
2438 copy_with_variable_replacement_l([],[],_).
2439 copy_with_variable_replacement_l([X|Xs],[Y|Ys],L) :-
2440 copy_with_variable_replacement(X,Y,L),
2441 copy_with_variable_replacement_l(Xs,Ys,L).
2443 %% build variable replacement list
2445 variable_replacement(X,Y,L) :-
2446 variable_replacement(X,Y,[],L).
2448 variable_replacement(X,Y,L1,L2) :-
2451 ( lookup_eq(L1,X,Z) ->
2459 variable_replacement_l(XArgs,YArgs,L1,L2)
2462 variable_replacement_l([],[],L,L).
2463 variable_replacement_l([X|Xs],[Y|Ys],L1,L3) :-
2464 variable_replacement(X,Y,L1,L2),
2465 variable_replacement_l(Xs,Ys,L2,L3).
2466 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2468 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2469 %% ____ _ _ _ __ _ _ _
2470 %% / ___|(_)_ __ ___ _ __ | (_)/ _(_) ___ __ _| |_(_) ___ _ __
2471 %% \___ \| | '_ ` _ \| '_ \| | | |_| |/ __/ _` | __| |/ _ \| '_ \
2472 %% ___) | | | | | | | |_) | | | _| | (_| (_| | |_| | (_) | | | |
2473 %% |____/|_|_| |_| |_| .__/|_|_|_| |_|\___\__,_|\__|_|\___/|_| |_|
2476 simplification_code(Head,RestHeads,RestIDs,PragmaRule,F/A,Id,L,T) :-
2477 PragmaRule = pragma(Rule,_,Pragmas,_,_RuleNb),
2478 head_info(Head,A,_Vars,Susp,HeadVars,HeadPairs),
2479 build_head(F,A,Id,HeadVars,ClauseHead),
2480 head_arg_matches(HeadPairs,[],FirstMatching,VarDict1),
2482 ( RestHeads == [] ->
2487 rest_heads_retrieval_and_matching(RestHeads,RestIDs,Pragmas,Head,GetRestHeads,Susps,VarDict1,VarDict)
2490 guard_body_copies2(Rule,VarDict,GuardCopyList,BodyCopy),
2491 guard_via_reschedule(GetRestHeads,GuardCopyList,ClauseHead-FirstMatching,RescheduledTest),
2493 gen_uncond_susps_detachments(Susps,RestHeads,SuspsDetachments),
2494 gen_cond_susp_detachment(Id,Susp,F/A,SuspDetachment),
2496 ( chr_pp_flag(debugable,on) ->
2497 Rule = rule(_,_,Guard,Body),
2498 my_term_copy(Guard - Body, VarDict, _, DebugGuard - DebugBody),
2499 DebugTry = 'chr debug_event'( try([Susp|RestSusps],[],DebugGuard,DebugBody)),
2500 DebugApply = 'chr debug_event'(apply([Susp|RestSusps],[],DebugGuard,DebugBody))
2506 Clause = ( ClauseHead :-
2518 head_arg_matches(Pairs,VarDict,Goal,NVarDict) :-
2519 head_arg_matches_(Pairs,VarDict,GoalList,NVarDict),
2520 list2conj(GoalList,Goal).
2522 head_arg_matches_([],VarDict,[],VarDict).
2523 head_arg_matches_([Arg-Var| Rest],VarDict,GoalList,NVarDict) :-
2525 ( lookup_eq(VarDict,Arg,OtherVar) ->
2526 GoalList = [Var == OtherVar | RestGoalList],
2528 ; VarDict1 = [Arg-Var | VarDict],
2529 GoalList = RestGoalList
2533 GoalList = [ Var == Arg | RestGoalList],
2538 functor(Term,Fct,N),
2540 GoalList =[ nonvar(Var), Var = Term | RestGoalList ],
2541 pairup(Args,Vars,NewPairs),
2542 append(NewPairs,Rest,Pairs),
2545 head_arg_matches_(Pairs,VarDict1,RestGoalList,NVarDict).
2547 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,[],[],[]).
2550 rest_heads_retrieval_and_matching(Heads,IDs,Pragmas,ActiveHead,GoalList,Susps,VarDict,NVarDict,PrevHs,PrevSusps,AttrDict) :-
2552 rest_heads_retrieval_and_matching_n(Heads,IDs,Pragmas,PrevHs,PrevSusps,ActiveHead,GoalList,Susps,VarDict,NVarDict,AttrDict)
2559 rest_heads_retrieval_and_matching_n([],_,_,_,_,_,[],[],VarDict,VarDict,AttrDict) :-
2560 instantiate_pattern_goals(AttrDict).
2561 rest_heads_retrieval_and_matching_n([H|Hs],[ID|IDs],Pragmas,PrevHs,PrevSusps,ActiveHead,[ViaGoal,Goal|Goals],[Susp|Susps],VarDict,NVarDict,AttrDict) :-
2563 get_store_type(F/A,StoreType),
2564 ( StoreType == default ->
2565 passive_head_via(H,[ActiveHead|PrevHs],AttrDict,VarDict,ViaGoal,Attr,NewAttrDict),
2566 get_max_constraint_index(N),
2570 get_constraint_index(F/A,Pos),
2571 make_attr(N,_Mask,SuspsList,Attr),
2572 nth(Pos,SuspsList,VarSusps)
2575 lookup_passive_head(StoreType,H,[ActiveHead|PrevHs],VarDict,ViaGoal,VarSusps),
2576 NewAttrDict = AttrDict
2578 head_info(H,A,Vars,_,_,Pairs),
2579 head_arg_matches(Pairs,VarDict,MatchingGoal,VarDict1),
2580 Suspension =.. [suspension,_,State,_,_,_,_|Vars],
2581 different_from_other_susps(H,Susp,PrevHs,PrevSusps,DiffSuspGoals),
2582 create_get_mutable(active,State,GetMutable),
2585 'chr sbag_member'(Susp,VarSusps),
2591 ( member(unique(ID,UniqueKeus),Pragmas),
2592 check_unique_keys(UniqueKeus,VarDict) ->
2593 Goal = (Goal1 -> true)
2597 rest_heads_retrieval_and_matching_n(Hs,IDs,Pragmas,[H|PrevHs],[Susp|PrevSusps],ActiveHead,Goals,Susps,VarDict1,NVarDict,NewAttrDict).
2599 instantiate_pattern_goals([]).
2600 instantiate_pattern_goals([_-attr(Attr,Bits,Goal)|Rest]) :-
2601 get_max_constraint_index(N),
2605 make_attr(N,Mask,_,Attr),
2606 or_list(Bits,Pattern), !,
2607 Goal = (Mask /\ Pattern =:= Pattern)
2609 instantiate_pattern_goals(Rest).
2612 check_unique_keys([],_).
2613 check_unique_keys([V|Vs],Dict) :-
2614 lookup_eq(Dict,V,_),
2615 check_unique_keys(Vs,Dict).
2617 % Generates tests to ensure the found constraint differs from previously found constraints
2618 % TODO: detect more cases where constraints need be different
2619 different_from_other_susps(Head,Susp,Heads,Susps,DiffSuspGoals) :-
2620 ( bagof(DiffSuspGoal, Pos ^ ( nth(Pos,Heads,PreHead), \+ Head \= PreHead, nth(Pos,Susps,PreSusp), DiffSuspGoal = (Susp \== PreSusp) ),DiffSuspGoalList) ->
2621 list2conj(DiffSuspGoalList,DiffSuspGoals)
2623 DiffSuspGoals = true
2626 passive_head_via(Head,PrevHeads,AttrDict,VarDict,Goal,Attr,NewAttrDict) :-
2628 get_constraint_index(F/A,Pos),
2629 common_variables(Head,PrevHeads,CommonVars),
2630 translate(CommonVars,VarDict,Vars),
2631 or_pattern(Pos,Bit),
2632 ( permutation(Vars,PermutedVars),
2633 lookup_eq(AttrDict,PermutedVars,attr(Attr,Positions,_)) ->
2634 member(Bit,Positions), !,
2635 NewAttrDict = AttrDict,
2638 Goal = (Goal1, PatternGoal),
2639 gen_get_mod_constraints(Vars,Goal1,Attr),
2640 NewAttrDict = [Vars - attr(Attr,[Bit|_],PatternGoal) | AttrDict]
2643 common_variables(T,Ts,Vs) :-
2644 term_variables(T,V1),
2645 term_variables(Ts,V2),
2646 intersect_eq(V1,V2,Vs).
2648 gen_get_mod_constraints(L,Goal,Susps) :-
2649 get_target_module(Mod),
2652 ( 'chr global_term_ref_1'(Global),
2653 get_attr(Global,Mod,TSusps),
2658 VIA = 'chr via_1'(A,V)
2660 VIA = 'chr via_2'(A,B,V)
2661 ; VIA = 'chr via'(L,V)
2666 get_attr(V,Mod,TSusps),
2671 guard_body_copies(Rule,VarDict,GuardCopy,BodyCopy) :-
2672 guard_body_copies2(Rule,VarDict,GuardCopyList,BodyCopy),
2673 list2conj(GuardCopyList,GuardCopy).
2675 guard_body_copies2(Rule,VarDict,GuardCopyList,BodyCopy) :-
2676 Rule = rule(_,_,Guard,Body),
2677 conj2list(Guard,GuardList),
2678 split_off_simple_guard(GuardList,VarDict,GuardPrefix,RestGuardList),
2679 my_term_copy(GuardPrefix-RestGuardList,VarDict,VarDict2,GuardPrefixCopy-RestGuardListCopyCore),
2681 append(GuardPrefixCopy,[RestGuardCopy],GuardCopyList),
2682 term_variables(RestGuardList,GuardVars),
2683 term_variables(RestGuardListCopyCore,GuardCopyVars),
2684 ( chr_pp_flag(guard_locks,on),
2685 bagof(('chr lock'(Y)) - ('chr unlock'(Y)),
2686 X ^ (member(X,GuardVars), % X is a variable appearing in the original guard
2687 lookup_eq(VarDict,X,Y), % translate X into new variable
2688 memberchk_eq(Y,GuardCopyVars) % redundant check? or multiple entries for X possible?
2691 once(pairup(Locks,Unlocks,LocksUnlocks))
2696 list2conj(Locks,LockPhase),
2697 list2conj(Unlocks,UnlockPhase),
2698 list2conj(RestGuardListCopyCore,RestGuardCopyCore),
2699 RestGuardCopy = (LockPhase,(RestGuardCopyCore,UnlockPhase)),
2700 my_term_copy(Body,VarDict2,BodyCopy).
2703 split_off_simple_guard([],_,[],[]).
2704 split_off_simple_guard([G|Gs],VarDict,S,C) :-
2705 ( simple_guard(G,VarDict) ->
2707 split_off_simple_guard(Gs,VarDict,Ss,C)
2713 % simple guard: cheap and benign (does not bind variables)
2714 simple_guard(G,VarDict) :-
2716 \+ (( member(V,Vars),
2717 lookup_eq(VarDict,V,_)
2720 my_term_copy(X,Dict,Y) :-
2721 my_term_copy(X,Dict,_,Y).
2723 my_term_copy(X,Dict1,Dict2,Y) :-
2725 ( lookup_eq(Dict1,X,Y) ->
2727 ; Dict2 = [X-Y|Dict1]
2733 my_term_copy_list(XArgs,Dict1,Dict2,YArgs)
2736 my_term_copy_list([],Dict,Dict,[]).
2737 my_term_copy_list([X|Xs],Dict1,Dict3,[Y|Ys]) :-
2738 my_term_copy(X,Dict1,Dict2,Y),
2739 my_term_copy_list(Xs,Dict2,Dict3,Ys).
2741 gen_cond_susp_detachment(Id,Susp,FA,SuspDetachment) :-
2742 ( is_attached(FA) ->
2743 ( Id == [0], \+ may_trigger(FA) ->
2744 SuspDetachment = true
2746 gen_uncond_susp_detachment(Susp,FA,UnCondSuspDetachment),
2750 ; UnCondSuspDetachment
2754 SuspDetachment = true
2757 gen_uncond_susp_detachment(Susp,FA,SuspDetachment) :-
2758 ( is_attached(FA) ->
2759 ( may_trigger(FA) ->
2760 make_name('detach_',FA,Fct),
2761 Detach =.. [Fct,Vars,Susp]
2765 ( chr_pp_flag(debugable,on) ->
2766 DebugEvent = 'chr debug_event'(remove(Susp))
2770 generate_delete_constraint_call(FA,Susp,DeleteCall),
2774 remove_constraint_internal(Susp, Vars, Delete),
2783 SuspDetachment = true
2786 gen_uncond_susps_detachments([],[],true).
2787 gen_uncond_susps_detachments([Susp|Susps],[Term|Terms],(SuspDetachment,SuspsDetachments)) :-
2789 gen_uncond_susp_detachment(Susp,F/A,SuspDetachment),
2790 gen_uncond_susps_detachments(Susps,Terms,SuspsDetachments).
2792 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2794 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2796 %% / ___|(_)_ __ ___ _ __ __ _ __ _ __ _| |_(_) ___ _ __ / |
2797 %% \___ \| | '_ ` _ \| '_ \ / _` |/ _` |/ _` | __| |/ _ \| '_ \ | |
2798 %% ___) | | | | | | | |_) | (_| | (_| | (_| | |_| | (_) | | | | | |
2799 %% |____/|_|_| |_| |_| .__/ \__,_|\__, |\__,_|\__|_|\___/|_| |_| |_|
2802 simpagation_head1_code(Head,RestHeads,OtherIDs,PragmaRule,F/A,Id,L,T) :-
2803 PragmaRule = pragma(Rule,ids(_,Heads2IDs),Pragmas,_Name,RuleNb),
2804 Rule = rule(_Heads,Heads2,Guard,Body),
2806 head_info(Head,A,_Vars,Susp,HeadVars,HeadPairs),
2807 head_arg_matches(HeadPairs,[],FirstMatching,VarDict1),
2809 build_head(F,A,Id,HeadVars,ClauseHead),
2811 append(RestHeads,Heads2,Heads),
2812 append(OtherIDs,Heads2IDs,IDs),
2813 reorder_heads(RuleNb,Head,Heads,IDs,NHeads,NIDs),
2814 rest_heads_retrieval_and_matching(NHeads,NIDs,Pragmas,Head,GetRestHeads,Susps,VarDict1,VarDict),
2815 split_by_ids(NIDs,Susps,OtherIDs,Susps1,Susps2),
2817 guard_body_copies2(Rule,VarDict,GuardCopyList,BodyCopy),
2818 guard_via_reschedule(GetRestHeads,GuardCopyList,ClauseHead-FirstMatching,RescheduledTest),
2820 gen_uncond_susps_detachments(Susps1,RestHeads,SuspsDetachments),
2821 gen_cond_susp_detachment(Id,Susp,F/A,SuspDetachment),
2823 ( chr_pp_flag(debugable,on) ->
2824 my_term_copy(Guard - Body, VarDict, _, DebugGuard - DebugBody),
2825 DebugTry = 'chr debug_event'( try([Susp|Susps1],Susps2,DebugGuard,DebugBody)),
2826 DebugApply = 'chr debug_event'(apply([Susp|Susps1],Susps2,DebugGuard,DebugBody))
2832 Clause = ( ClauseHead :-
2844 split_by_ids([],[],_,[],[]).
2845 split_by_ids([I|Is],[S|Ss],I1s,S1s,S2s) :-
2846 ( memberchk_eq(I,I1s) ->
2853 split_by_ids(Is,Ss,I1s,R1s,R2s).
2855 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2858 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2860 %% / ___|(_)_ __ ___ _ __ __ _ __ _ __ _| |_(_) ___ _ __ |___ \
2861 %% \___ \| | '_ ` _ \| '_ \ / _` |/ _` |/ _` | __| |/ _ \| '_ \ __) |
2862 %% ___) | | | | | | | |_) | (_| | (_| | (_| | |_| | (_) | | | | / __/
2863 %% |____/|_|_| |_| |_| .__/ \__,_|\__, |\__,_|\__|_|\___/|_| |_| |_____|
2866 %% Genereate prelude + worker predicate
2867 %% prelude calls worker
2868 %% worker iterates over one type of removed constraints
2869 simpagation_head2_code(Head2,RestHeads2,RestIDs,PragmaRule,FA,Id,L,T) :-
2870 PragmaRule = pragma(Rule,ids(IDs1,_),Pragmas,_Name,RuleNb),
2871 Rule = rule(Heads1,_,Guard,Body),
2872 reorder_heads(RuleNb,Head2,Heads1,IDs1,[Head1|RestHeads1],[ID1|RestIDs1]), % Heads1 = [Head1|RestHeads1],
2873 % IDs1 = [ID1|RestIDs1],
2874 simpagation_head2_prelude(Head2,Head1,[RestHeads2,Heads1,Guard,Body],FA,Id,L,L1),
2876 simpagation_head2_worker(Head2,Head1,ID1,RestHeads1,RestIDs1,RestHeads2,RestIDs,PragmaRule,FA,Id2,L1,T).
2878 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2879 simpagation_head2_prelude(Head,Head1,Rest,F/A,Id1,L,T) :-
2880 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs),
2881 build_head(F,A,Id1,VarsSusp,ClauseHead),
2882 head_arg_matches(HeadPairs,[],FirstMatching,VarDict),
2884 lookup_passive_head(Head1,[Head],VarDict,ModConstraintsGoal,AllSusps),
2886 gen_allocation(Id1,Vars,Susp,F/A,VarsSusp,ConstraintAllocationGoal),
2888 extend_id(Id1,DelegateId),
2889 extra_active_delegate_variables(Head,Rest,VarDict,ExtraVars),
2890 append([AllSusps|VarsSusp],ExtraVars,DelegateCallVars),
2891 build_head(F,A,DelegateId,DelegateCallVars,Delegate),
2898 ConstraintAllocationGoal,
2901 L = [PreludeClause|T].
2903 extra_active_delegate_variables(Term,Terms,VarDict,Vars) :-
2905 delegate_variables(Term,Terms,VarDict,Args,Vars).
2907 passive_delegate_variables(Term,PrevTerms,NextTerms,VarDict,Vars) :-
2908 term_variables(PrevTerms,PrevVars),
2909 delegate_variables(Term,NextTerms,VarDict,PrevVars,Vars).
2911 delegate_variables(Term,Terms,VarDict,PrevVars,Vars) :-
2912 term_variables(Term,V1),
2913 term_variables(Terms,V2),
2914 intersect_eq(V1,V2,V3),
2915 list_difference_eq(V3,PrevVars,V4),
2916 translate(V4,VarDict,Vars).
2919 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2920 simpagation_head2_worker(Head2,Head1,ID1,RestHeads1,IDs1,RestHeads2,IDs2,PragmaRule,FA,Id,L,T) :-
2921 PragmaRule = pragma(Rule,_,_,_,_),
2922 Rule = rule(_,_,Guard,Body),
2923 simpagation_head2_worker_end(Head2,[Head1,RestHeads1,RestHeads2,Guard,Body],FA,Id,L,L1),
2924 simpagation_head2_worker_body(Head2,Head1,ID1,RestHeads1,IDs1,RestHeads2,IDs2,PragmaRule,FA,Id,L1,T).
2926 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2927 simpagation_head2_worker_body(Head2,Head1,ID1,RestHeads1,IDs1,RestHeads2,IDs2,PragmaRule,F/A,Id,L,T) :-
2929 gen_var(OtherSusps),
2931 head_info(Head2,A,_Vars,Susp,VarsSusp,Head2Pairs),
2932 head_arg_matches(Head2Pairs,[],_,VarDict1),
2934 PragmaRule = pragma(Rule,_,Pragmas,_,RuleNb),
2935 Rule = rule(_,_,Guard,Body),
2936 extra_active_delegate_variables(Head2,[Head1,RestHeads1,RestHeads2,Guard,Body],VarDict1,ExtraVars),
2937 append([[OtherSusp|OtherSusps]|VarsSusp],ExtraVars,HeadVars),
2938 build_head(F,A,Id,HeadVars,ClauseHead),
2940 functor(Head1,_OtherF,OtherA),
2941 head_info(Head1,OtherA,OtherVars,_,_,Head1Pairs),
2942 head_arg_matches(Head1Pairs,VarDict1,FirstMatching,VarDict2),
2944 OtherSuspension =.. [suspension,_,OtherState,_,_,_,_|OtherVars],
2945 create_get_mutable(active,OtherState,GetMutable),
2947 ( OtherSusp = OtherSuspension,
2951 ( (RestHeads1 \== [] ; RestHeads2 \== []) ->
2952 append(RestHeads1,RestHeads2,RestHeads),
2953 append(IDs1,IDs2,IDs),
2954 reorder_heads(RuleNb,Head1-Head2,RestHeads,IDs,NRestHeads,NIDs),
2955 rest_heads_retrieval_and_matching(NRestHeads,NIDs,Pragmas,[Head1,Head2],RestSuspsRetrieval,Susps,VarDict2,VarDict,[Head1],[OtherSusp],[]),
2956 split_by_ids(NIDs,Susps,IDs1,Susps1,Susps2)
2957 ; RestSuspsRetrieval = [],
2963 gen_uncond_susps_detachments([OtherSusp | Susps1],[Head1|RestHeads1],Susps1Detachments),
2965 append([OtherSusps|VarsSusp],ExtraVars,RecursiveVars),
2966 build_head(F,A,Id,RecursiveVars,RecursiveCall),
2967 append([[]|VarsSusp],ExtraVars,RecursiveVars2),
2968 build_head(F,A,Id,RecursiveVars2,RecursiveCall2),
2970 guard_body_copies2(Rule,VarDict,GuardCopyList,BodyCopy),
2971 guard_via_reschedule(RestSuspsRetrieval,GuardCopyList,v(ClauseHead,IteratorSuspTest,FirstMatching),RescheduledTest),
2972 ( BodyCopy \== true ->
2973 gen_uncond_attach_goal(F/A,Susp,Attachment,Generation),
2974 gen_state_cond_call(Susp,A,RecursiveCall,Generation,ConditionalRecursiveCall),
2975 gen_state_cond_call(Susp,A,RecursiveCall2,Generation,ConditionalRecursiveCall2)
2976 ; Attachment = true,
2977 ConditionalRecursiveCall = RecursiveCall,
2978 ConditionalRecursiveCall2 = RecursiveCall2
2981 ( chr_pp_flag(debugable,on) ->
2982 my_term_copy(Guard - Body, VarDict, _, DebugGuard - DebugBody),
2983 DebugTry = 'chr debug_event'( try([OtherSusp|Susps1],[Susp|Susps2],DebugGuard,DebugBody)),
2984 DebugApply = 'chr debug_event'(apply([OtherSusp|Susps1],[Susp|Susps2],DebugGuard,DebugBody))
2990 ( member(unique(ID1,UniqueKeys), Pragmas),
2991 check_unique_keys(UniqueKeys,VarDict1) ->
3002 ConditionalRecursiveCall2
3021 ConditionalRecursiveCall
3029 gen_state_cond_call(Susp,N,Call,Generation,ConditionalCall) :-
3031 Suspension =.. [suspension,_,State,_,NewGeneration,_,_|Args],
3032 create_get_mutable(active,State,GetState),
3033 create_get_mutable(Generation,NewGeneration,GetGeneration),
3035 ( Susp = Suspension,
3038 'chr update_mutable'(inactive,State),
3043 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3044 simpagation_head2_worker_end(Head,Rest,F/A,Id,L,T) :-
3045 head_info(Head,A,_Vars,_Susp,VarsSusp,Pairs),
3046 head_arg_matches(Pairs,[],_,VarDict),
3047 extra_active_delegate_variables(Head,Rest,VarDict,ExtraVars),
3048 append([[]|VarsSusp],ExtraVars,HeadVars),
3049 build_head(F,A,Id,HeadVars,ClauseHead),
3050 next_id(Id,ContinuationId),
3051 build_head(F,A,ContinuationId,VarsSusp,ContinuationHead),
3052 Clause = ( ClauseHead :- ContinuationHead ),
3055 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3058 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3060 %% | _ \ _ __ ___ _ __ __ _ __ _ __ _| |_(_) ___ _ __
3061 %% | |_) | '__/ _ \| '_ \ / _` |/ _` |/ _` | __| |/ _ \| '_ \
3062 %% | __/| | | (_) | |_) | (_| | (_| | (_| | |_| | (_) | | | |
3063 %% |_| |_| \___/| .__/ \__,_|\__, |\__,_|\__|_|\___/|_| |_|
3066 propagation_code(Head,RestHeads,Rule,RuleNb,RestHeadNb,FA,Id,L,T) :-
3067 ( RestHeads == [] ->
3068 propagation_single_headed(Head,Rule,RuleNb,FA,Id,L,T)
3070 propagation_multi_headed(Head,RestHeads,Rule,RuleNb,RestHeadNb,FA,Id,L,T)
3072 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3073 %% Single headed propagation
3074 %% everything in a single clause
3075 propagation_single_headed(Head,Rule,RuleNb,F/A,Id,L,T) :-
3076 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs),
3077 build_head(F,A,Id,VarsSusp,ClauseHead),
3080 build_head(F,A,NextId,VarsSusp,NextHead),
3082 NextCall = NextHead,
3084 head_arg_matches(HeadPairs,[],HeadMatching,VarDict),
3085 guard_body_copies(Rule,VarDict,GuardCopy,BodyCopy),
3086 gen_allocation(Id,Vars,Susp,F/A,VarsSusp,Allocation),
3087 gen_uncond_attach_goal(F/A,Susp,Attachment,Generation),
3089 gen_state_cond_call(Susp,A,NextCall,Generation,ConditionalNextCall),
3091 ( chr_pp_flag(debugable,on) ->
3092 Rule = rule(_,_,Guard,Body),
3093 my_term_copy(Guard - Body, VarDict, _, DebugGuard - DebugBody),
3094 DebugTry = 'chr debug_event'( try([],[Susp],DebugGuard,DebugBody)),
3095 DebugApply = 'chr debug_event'(apply([],[Susp],DebugGuard,DebugBody))
3105 'chr novel_production'(Susp,RuleNb), % optimisation of t(RuleNb,Susp)
3110 'chr extend_history'(Susp,RuleNb),
3117 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3118 %% multi headed propagation
3119 %% prelude + predicates to accumulate the necessary combinations of suspended
3120 %% constraints + predicate to execute the body
3121 propagation_multi_headed(Head,RestHeads,Rule,RuleNb,RestHeadNb,FA,Id,L,T) :-
3122 RestHeads = [First|Rest],
3123 propagation_prelude(Head,RestHeads,Rule,FA,Id,L,L1),
3124 extend_id(Id,ExtendedId),
3125 propagation_nested_code(Rest,[First,Head],Rule,RuleNb,RestHeadNb,FA,ExtendedId,L1,T).
3127 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3128 propagation_prelude(Head,[First|Rest],Rule,F/A,Id,L,T) :-
3129 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs),
3130 build_head(F,A,Id,VarsSusp,PreludeHead),
3131 head_arg_matches(HeadPairs,[],FirstMatching,VarDict),
3132 Rule = rule(_,_,Guard,Body),
3133 extra_active_delegate_variables(Head,[First,Rest,Guard,Body],VarDict,ExtraVars),
3135 lookup_passive_head(First,[Head],VarDict,FirstSuspGoal,Susps),
3137 gen_allocation(Id,Vars,Susp,F/A,VarsSusp,CondAllocation),
3139 extend_id(Id,NestedId),
3140 append([Susps|VarsSusp],ExtraVars,NestedVars),
3141 build_head(F,A,NestedId,NestedVars,NestedHead),
3142 NestedCall = NestedHead,
3154 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3155 propagation_nested_code([],[CurrentHead|PreHeads],Rule,RuleNb,RestHeadNb,FA,Id,L,T) :-
3156 propagation_end([CurrentHead|PreHeads],[],Rule,FA,Id,L,L1),
3157 propagation_body(CurrentHead,PreHeads,Rule,RuleNb,RestHeadNb,FA,Id,L1,T).
3159 propagation_nested_code([Head|RestHeads],PreHeads,Rule,RuleNb,RestHeadNb,FA,Id,L,T) :-
3160 propagation_end(PreHeads,[Head|RestHeads],Rule,FA,Id,L,L1),
3161 propagation_accumulator([Head|RestHeads],PreHeads,Rule,FA,Id,L1,L2),
3163 propagation_nested_code(RestHeads,[Head|PreHeads],Rule,RuleNb,RestHeadNb,FA,IncId,L2,T).
3165 propagation_body(CurrentHead,PreHeads,Rule,RuleNb,RestHeadNb,F/A,Id,L,T) :-
3166 Rule = rule(_,_,Guard,Body),
3167 get_prop_inner_loop_vars(PreHeads,[CurrentHead,Guard,Body],PreVarsAndSusps,VarDict1,Susp,RestSusps),
3169 gen_var(OtherSusps),
3170 functor(CurrentHead,_OtherF,OtherA),
3171 gen_vars(OtherA,OtherVars),
3172 Suspension =.. [suspension,_,State,_,_,_,_|OtherVars],
3173 create_get_mutable(active,State,GetMutable),
3175 OtherSusp = Suspension,
3178 ClauseVars = [[OtherSusp|OtherSusps]|PreVarsAndSusps],
3179 build_head(F,A,Id,ClauseVars,ClauseHead),
3180 RecursiveVars = [OtherSusps|PreVarsAndSusps],
3181 build_head(F,A,Id,RecursiveVars,RecursiveHead),
3182 RecursiveCall = RecursiveHead,
3183 CurrentHead =.. [_|OtherArgs],
3184 pairup(OtherArgs,OtherVars,OtherPairs),
3185 head_arg_matches(OtherPairs,VarDict1,Matching,VarDict),
3187 different_from_other_susps(CurrentHead,OtherSusp,PreHeads,RestSusps,DiffSuspGoals),
3189 guard_body_copies(Rule,VarDict,GuardCopy,BodyCopy),
3190 gen_uncond_attach_goal(F/A,Susp,Attach,Generation),
3191 gen_state_cond_call(Susp,A,RecursiveCall,Generation,ConditionalRecursiveCall),
3193 history_susps(RestHeadNb,[OtherSusp|RestSusps],Susp,[],HistorySusps),
3194 bagof('chr novel_production'(X,Y),( member(X,HistorySusps), Y = TupleVar) ,NovelProductionsList),
3195 list2conj(NovelProductionsList,NovelProductions),
3196 Tuple =.. [t,RuleNb|HistorySusps],
3198 ( chr_pp_flag(debugable,on) ->
3199 Rule = rule(_,_,Guard,Body),
3200 my_term_copy(Guard - Body, VarDict, _, DebugGuard - DebugBody),
3201 DebugTry = 'chr debug_event'( try([],[Susp,OtherSusp|RestSusps],DebugGuard,DebugBody)),
3202 DebugApply = 'chr debug_event'(apply([],[Susp,OtherSusp|RestSusps],DebugGuard,DebugBody))
3218 'chr extend_history'(Susp,TupleVar),
3221 ConditionalRecursiveCall
3227 history_susps(Count,OtherSusps,Susp,Acc,HistorySusps) :-
3229 reverse(OtherSusps,ReversedSusps),
3230 append(ReversedSusps,[Susp|Acc],HistorySusps)
3232 OtherSusps = [OtherSusp|RestOtherSusps],
3233 NCount is Count - 1,
3234 history_susps(NCount,RestOtherSusps,Susp,[OtherSusp|Acc],HistorySusps)
3237 get_prop_inner_loop_vars([Head],Terms,HeadVars,VarDict,Susp,[]) :-
3240 head_info(Head,A,_Vars,Susp,VarsSusp,Pairs),
3241 head_arg_matches(Pairs,[],_,VarDict),
3242 extra_active_delegate_variables(Head,Terms,VarDict,ExtraVars),
3243 append(VarsSusp,ExtraVars,HeadVars).
3244 get_prop_inner_loop_vars([Head|Heads],Terms,VarsSusps,NVarDict,MainSusp,[Susp|RestSusps]) :-
3245 get_prop_inner_loop_vars(Heads,[Head|Terms],RestVarsSusp,VarDict,MainSusp,RestSusps),
3248 head_info(Head,A,_Vars,Susp,_VarsSusp,Pairs),
3249 head_arg_matches(Pairs,VarDict,_,NVarDict),
3250 passive_delegate_variables(Head,Heads,Terms,NVarDict,HeadVars),
3251 append(HeadVars,[Susp,Susps|RestVarsSusp],VarsSusps).
3253 propagation_end([CurrentHead|PrevHeads],NextHeads,Rule,F/A,Id,L,T) :-
3254 Rule = rule(_,_,Guard,Body),
3255 gen_var_susp_list_for(PrevHeads,[CurrentHead,NextHeads,Guard,Body],_,VarsAndSusps,AllButFirst,FirstSusp),
3257 Vars = [ [] | VarsAndSusps],
3259 build_head(F,A,Id,Vars,Head),
3263 PrevVarsAndSusps = AllButFirst
3266 PrevVarsAndSusps = [FirstSusp|AllButFirst]
3269 build_head(F,A,PrevId,PrevVarsAndSusps,PrevHead),
3270 PredecessorCall = PrevHead,
3278 gen_var_susp_list_for([Head],Terms,VarDict,HeadVars,VarsSusp,Susp) :-
3281 head_info(Head,A,_Vars,Susp,VarsSusp,HeadPairs),
3282 head_arg_matches(HeadPairs,[],_,VarDict),
3283 extra_active_delegate_variables(Head,Terms,VarDict,ExtraVars),
3284 append(VarsSusp,ExtraVars,HeadVars).
3285 gen_var_susp_list_for([Head|Heads],Terms,NVarDict,VarsSusps,Rest,Susps) :-
3286 gen_var_susp_list_for(Heads,[Head|Terms],VarDict,Rest,_,_),
3289 head_info(Head,A,_Vars,Susp,_VarsSusp,HeadPairs),
3290 head_arg_matches(HeadPairs,VarDict,_,NVarDict),
3291 passive_delegate_variables(Head,Heads,Terms,NVarDict,HeadVars),
3292 append(HeadVars,[Susp,Susps|Rest],VarsSusps).
3294 propagation_accumulator([NextHead|RestHeads],[CurrentHead|PreHeads],Rule,F/A,Id,L,T) :-
3295 Rule = rule(_,_,Guard,Body),
3296 pre_vars_and_susps(PreHeads,[CurrentHead,NextHead,RestHeads,Guard,Body],PreVarsAndSusps,VarDict,PreSusps),
3297 gen_var(OtherSusps),
3298 functor(CurrentHead,_OtherF,OtherA),
3299 gen_vars(OtherA,OtherVars),
3300 head_info(CurrentHead,OtherA,OtherVars,OtherSusp,_VarsSusp,HeadPairs),
3301 head_arg_matches(HeadPairs,VarDict,FirstMatching,VarDict1),
3303 OtherSuspension =.. [suspension,_,State,_,_,_,_|OtherVars],
3305 different_from_other_susps(CurrentHead,OtherSusp,PreHeads,PreSusps,DiffSuspGoals),
3306 create_get_mutable(active,State,GetMutable),
3308 OtherSusp = OtherSuspension,
3313 lookup_passive_head(NextHead,[CurrentHead|PreHeads],VarDict1,NextSuspGoal,NextSusps),
3314 inc_id(Id,NestedId),
3315 ClauseVars = [[OtherSusp|OtherSusps]|PreVarsAndSusps],
3316 build_head(F,A,Id,ClauseVars,ClauseHead),
3317 passive_delegate_variables(CurrentHead,PreHeads,[NextHead,RestHeads,Guard,Body],VarDict1,CurrentHeadVars),
3318 append([NextSusps|CurrentHeadVars],[OtherSusp,OtherSusps|PreVarsAndSusps],NestedVars),
3319 build_head(F,A,NestedId,NestedVars,NestedHead),
3321 RecursiveVars = [OtherSusps|PreVarsAndSusps],
3322 build_head(F,A,Id,RecursiveVars,RecursiveHead),
3334 pre_vars_and_susps([Head],Terms,HeadVars,VarDict,[]) :-
3337 head_info(Head,A,_Vars,_Susp,VarsSusp,HeadPairs),
3338 head_arg_matches(HeadPairs,[],_,VarDict),
3339 extra_active_delegate_variables(Head,Terms,VarDict,ExtraVars),
3340 append(VarsSusp,ExtraVars,HeadVars).
3341 pre_vars_and_susps([Head|Heads],Terms,NVSs,NVarDict,[Susp|Susps]) :-
3342 pre_vars_and_susps(Heads,[Head|Terms],VSs,VarDict,Susps),
3345 head_info(Head,A,_Vars,Susp,_VarsSusp,HeadPairs),
3346 head_arg_matches(HeadPairs,VarDict,_,NVarDict),
3347 passive_delegate_variables(Head,Heads,Terms,NVarDict,HeadVars),
3348 append(HeadVars,[Susp,NextSusps|VSs],NVSs).
3350 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3352 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3354 %% | _ \ __ _ ___ ___(_)_ _____ | | | | ___ __ _ __| |
3355 %% | |_) / _` / __/ __| \ \ / / _ \ | |_| |/ _ \/ _` |/ _` |
3356 %% | __/ (_| \__ \__ \ |\ V / __/ | _ | __/ (_| | (_| |
3357 %% |_| \__,_|___/___/_| \_/ \___| |_| |_|\___|\__,_|\__,_|
3360 %% | _ \ ___| |_ _ __(_) _____ ____ _| |
3361 %% | |_) / _ \ __| '__| |/ _ \ \ / / _` | |
3362 %% | _ < __/ |_| | | | __/\ V / (_| | |
3363 %% |_| \_\___|\__|_| |_|\___| \_/ \__,_|_|
3366 %% | _ \ ___ ___ _ __ __| | ___ _ __(_)_ __ __ _
3367 %% | |_) / _ \/ _ \| '__/ _` |/ _ \ '__| | '_ \ / _` |
3368 %% | _ < __/ (_) | | | (_| | __/ | | | | | | (_| |
3369 %% |_| \_\___|\___/|_| \__,_|\___|_| |_|_| |_|\__, |
3372 reorder_heads(RuleNb,Head,RestHeads,RestIDs,NRestHeads,NRestIDs) :-
3373 ( chr_pp_flag(reorder_heads,on) ->
3374 reorder_heads_main(RuleNb,Head,RestHeads,RestIDs,NRestHeads,NRestIDs)
3376 NRestHeads = RestHeads,
3380 reorder_heads_main(RuleNb,Head,RestHeads,RestIDs,NRestHeads,NRestIDs) :-
3381 term_variables(Head,Vars),
3382 InitialData = entry([],[],Vars,RestHeads,RestIDs,RuleNb),
3383 a_star(InitialData,FD^(chr_translate:final_data(FD)),N^EN^C^(chr_translate:expand_data(N,EN,C)),FinalData),
3384 FinalData = entry(RNRestHeads,RNRestIDs,_,_,_,_),
3385 reverse(RNRestHeads,NRestHeads),
3386 reverse(RNRestIDs,NRestIDs).
3388 final_data(Entry) :-
3389 Entry = entry(_,_,_,_,[],_).
3391 expand_data(Entry,NEntry,Cost) :-
3392 Entry = entry(Heads,IDs,Vars,NHeads,NIDs,RuleNb),
3393 term_variables(Entry,EVars),
3394 NEntry = entry([Head1|Heads],[ID1|IDs],Vars1,NHeads1,NIDs1,RuleNb),
3395 select2(Head1,ID1,NHeads,NIDs,NHeads1,NIDs1),
3396 order_score(Head1,ID1,Vars,NHeads1,RuleNb,Cost),
3397 term_variables([Head1|Vars],Vars1).
3399 order_score(Head,ID,KnownVars,RestHeads,RuleNb,Score) :-
3401 get_store_type(F/A,StoreType),
3402 order_score(StoreType,Head,ID,KnownVars,RestHeads,RuleNb,Score).
3404 order_score(default,Head,_ID,KnownVars,RestHeads,RuleNb,Score) :-
3405 term_variables(Head,HeadVars),
3406 term_variables(RestHeads,RestVars),
3407 order_score_vars(HeadVars,KnownVars,RestHeads,0,Score).
3408 order_score(multi_hash(Indexes),Head,_ID,KnownVars,RestHeads,RuleNb,Score) :-
3409 order_score_indexes(Indexes,Head,KnownVars,0,Score).
3410 order_score(global_ground,Head,ID,_KnownVars,_RestHeads,RuleNb,Score) :-
3412 ( get_pragma_unique(RuleNb,ID,Vars),
3414 Score = 1 % guaranteed O(1)
3415 ; A == 0 -> % flag constraint
3416 Score = 10 % O(1)? [CHECK: no deleted/triggered/... constraints in store?]
3421 order_score(multi_store(StoreTypes),Head,ID,KnownVars,RestHeads,RuleNb,Score) :-
3422 find_with_var_identity(
3424 t(Head,KnownVars,RestHeads),
3425 ( member(ST,StoreTypes), chr_translate:order_score(ST,Head,ID,KnownVars,RestHeads,RuleNb,S) ),
3428 min_list(Scores,Score).
3431 order_score_indexes([],_,_,Score,Score) :-
3433 order_score_indexes([I|Is],Head,KnownVars,Score,NScore) :-
3434 multi_hash_key_args(I,Head,Args),
3435 ( forall(Arg,Args,hprolog:memberchk_eq(Arg,KnownVars)) ->
3436 Score1 is Score + 10
3440 order_score_indexes(Is,Head,KnownVars,Score1,NScore).
3442 order_score_vars([],_,_,Score,NScore) :-
3448 order_score_vars([V|Vs],KnownVars,RestVars,Score,NScore) :-
3449 ( memberchk_eq(V,KnownVars) ->
3450 TScore is Score + 10
3451 ; memberchk_eq(V,RestVars) ->
3452 TScore is Score + 100
3456 order_score_vars(Vs,KnownVars,RestVars,TScore,NScore).
3458 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3460 %% |_ _|_ __ | (_)_ __ (_)_ __ __ _
3461 %% | || '_ \| | | '_ \| | '_ \ / _` |
3462 %% | || | | | | | | | | | | | | (_| |
3463 %% |___|_| |_|_|_|_| |_|_|_| |_|\__, |
3466 create_get_mutable(V,M,GM) :-
3467 GM = (M = mutable(V)).
3469 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3471 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3473 %% | | | | |_(_) (_) |_ _ _
3474 %% | | | | __| | | | __| | | |
3475 %% | |_| | |_| | | | |_| |_| |
3476 %% \___/ \__|_|_|_|\__|\__, |
3483 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs) :-
3484 vars_susp(A,Vars,Susp,VarsSusp),
3486 pairup(Args,Vars,HeadPairs).
3488 inc_id([N|Ns],[O|Ns]) :-
3490 dec_id([N|Ns],[M|Ns]) :-
3493 extend_id(Id,[0|Id]).
3495 next_id([_,N|Ns],[O|Ns]) :-
3498 build_head(F,A,Id,Args,Head) :-
3499 buildName(F,A,Id,Name),
3500 Head =.. [Name|Args].
3502 buildName(Fct,Aty,List,Result) :-
3503 atom_concat(Fct, (/) ,FctSlash),
3504 atom_concat(FctSlash,Aty,FctSlashAty),
3505 buildName_(List,FctSlashAty,Result).
3507 buildName_([],Name,Name).
3508 buildName_([N|Ns],Name,Result) :-
3509 buildName_(Ns,Name,Name1),
3510 atom_concat(Name1,'__',NameDash), % '_' is a char :-(
3511 atom_concat(NameDash,N,Result).
3513 vars_susp(A,Vars,Susp,VarsSusp) :-
3515 append(Vars,[Susp],VarsSusp).
3517 make_attr(N,Mask,SuspsList,Attr) :-
3518 length(SuspsList,N),
3519 Attr =.. [v,Mask|SuspsList].
3521 or_pattern(Pos,Pat) :-
3523 Pat is 1 << Pow. % was 2 ** X
3525 and_pattern(Pos,Pat) :-
3527 Y is 1 << X, % was 2 ** X
3528 Pat is (-1)*(Y + 1). % because fx (-) is redefined
3530 conj2list(Conj,L) :- %% transform conjunctions to list
3531 conj2list(Conj,L,[]).
3533 conj2list(Conj,L,T) :-
3537 conj2list(G,[G | T],T).
3540 list2conj([G],X) :- !, X = G.
3541 list2conj([G|Gs],C) :-
3542 ( G == true -> %% remove some redundant trues
3550 list2disj([G],X) :- !, X = G.
3551 list2disj([G|Gs],C) :-
3552 ( G == fail -> %% remove some redundant fails
3559 atom_concat_list([X],X) :- ! .
3560 atom_concat_list([X|Xs],A) :-
3561 atom_concat_list(Xs,B),
3564 make_name(Prefix,F/A,Name) :-
3565 atom_concat_list([Prefix,F,(/),A],Name).
3568 set_elems([X|Xs],X) :-
3571 member2([X|_],[Y|_],X-Y).
3572 member2([_|Xs],[_|Ys],P) :-
3575 select2(X, Y, [X|Xs], [Y|Ys], Xs, Ys).
3576 select2(X, Y, [X1|Xs], [Y1|Ys], [X1|NXs], [Y1|NYs]) :-
3577 select2(X, Y, Xs, Ys, NXs, NYs).
3579 pair_all_with([],_,[]).
3580 pair_all_with([X|Xs],Y,[X-Y|Rest]) :-
3581 pair_all_with(Xs,Y,Rest).
3582 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3584 lookup_passive_head(Head,PreJoin,VarDict,Goal,AllSusps) :-
3586 get_store_type(F/A,StoreType),
3587 lookup_passive_head(StoreType,Head,PreJoin,VarDict,Goal,AllSusps).
3589 lookup_passive_head(default,Head,PreJoin,VarDict,Goal,AllSusps) :-
3590 passive_head_via(Head,PreJoin,[],VarDict,Goal,Attr,AttrDict),
3591 instantiate_pattern_goals(AttrDict),
3592 get_max_constraint_index(N),
3597 get_constraint_index(F/A,Pos),
3598 make_attr(N,_,SuspsList,Attr),
3599 nth(Pos,SuspsList,AllSusps)
3601 lookup_passive_head(multi_hash(Indexes),Head,_PreJoin,VarDict,Goal,AllSusps) :-
3603 member(Index,Indexes),
3604 multi_hash_key_args(Index,Head,KeyArgs),
3605 translate(KeyArgs,VarDict,KeyArgCopies)
3607 ( KeyArgCopies = [KeyCopy] ->
3610 KeyCopy =.. [k|KeyArgCopies]
3613 multi_hash_via_lookup_name(F/A,Index,ViaName),
3614 Goal =.. [ViaName,KeyCopy,AllSusps],
3615 update_store_type(F/A,multi_hash([Index])).
3616 lookup_passive_head(global_ground,Head,PreJoin,_VarDict,Goal,AllSusps) :-
3618 global_ground_store_name(F/A,StoreName),
3619 Goal = nb_getval(StoreName,AllSusps),
3620 update_store_type(F/A,global_ground).
3621 lookup_passive_head(multi_store(StoreTypes),Head,PreJoin,VarDict,Goal,AllSusps) :-
3623 member(ST,StoreTypes),
3624 lookup_passive_head(ST,Head,PreJoin,VarDict,Goal,AllSusps)
3626 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3627 assume_constraint_stores([]).
3628 assume_constraint_stores([C|Cs]) :-
3629 ( \+ may_trigger(C),
3631 get_store_type(C,default) ->
3632 get_indexed_arguments(C,IndexedArgs),
3633 findall(Index,(sublist(Index,IndexedArgs), Index \== []),Indexes),
3634 assumed_store_type(C,multi_store([multi_hash(Indexes),global_ground]))
3638 assume_constraint_stores(Cs).
3640 get_indexed_arguments(C,IndexedArgs) :-
3642 get_indexed_arguments(1,A,C,IndexedArgs).
3644 get_indexed_arguments(I,N,C,L) :-
3647 ; ( is_indexed_argument(C,I) ->
3653 get_indexed_arguments(J,N,C,T)
3656 validate_store_type_assumptions([]).
3657 validate_store_type_assumptions([C|Cs]) :-
3658 validate_store_type_assumption(C),
3659 validate_store_type_assumptions(Cs).