3 Part of CHR (Constraint Handling Rules)
6 E-mail: Tom.Schrijvers@cs.kuleuven.be
7 WWW: http://www.swi-prolog.org
8 Copyright (C): 2003-2004, K.U. Leuven
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License
12 as published by the Free Software Foundation; either version 2
13 of the License, or (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU Lesser General Public
21 License along with this library; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 As a special exception, if you link this library with other files,
25 compiled with a Free Software compiler, to produce an executable, this
26 library does not by itself cause the resulting executable to be covered
27 by the GNU General Public License. This exception does not however
28 invalidate any other reasons why the executable file might be covered by
29 the GNU General Public License.
32 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
34 %% ____ _ _ ____ ____ _ _
35 %% / ___| | | | _ \ / ___|___ _ __ ___ _ __ (_) | ___ _ __
36 %% | | | |_| | |_) | | | / _ \| '_ ` _ \| '_ \| | |/ _ \ '__|
37 %% | |___| _ | _ < | |__| (_) | | | | | | |_) | | | __/ |
38 %% \____|_| |_|_| \_\ \____\___/|_| |_| |_| .__/|_|_|\___|_|
41 %% hProlog CHR compiler:
43 %% * by Tom Schrijvers, K.U. Leuven, Tom.Schrijvers@cs.kuleuven.be
45 %% * based on the SICStus CHR compilation by Christian Holzbaur
47 %% First working version: 6 June 2003
49 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
55 %% * add mode checking to debug mode
56 %% * add groundness info to a.i.-based observation analysis
57 %% * proper fd/index analysis
58 %% * re-add generation checking
59 %% * untangle CHR-level and target source-level generation & optimization
61 %% AGGRESSIVE OPTIMISATION IDEAS
63 %% * success continuation optimization
64 %% * analyze history usage to determine whether/when
65 %% cheaper suspension is possible:
66 %% don't use history when all partners are passive and self never triggers
67 %% * store constraint unconditionally for unconditional propagation rule,
68 %% if first, i.e. without checking history and set trigger cont to next occ
69 %% * get rid of suspension passing for never triggered constraints,
70 %% up to allocation occurrence
71 %% * get rid of call indirection for never triggered constraints
72 %% up to first allocation occurrence.
73 %% * get rid of unnecessary indirection if last active occurrence
74 %% before unconditional removal is head2, e.g.
77 %% * Eliminate last clause of never stored constraint, if its body
81 %% * Specialize lookup operations and indexes for functional dependencies.
85 %% * generate code to empty all constraint stores of a module (Bart Demoen)
86 %% * map A \ B <=> true | true rules
87 %% onto efficient code that empties the constraint stores of B
88 %% in O(1) time for ground constraints where A and B do not share
90 %% * ground matching seems to be not optimized for compound terms
91 %% in case of simpagation_head2 and propagation occurrences
92 %% * analysis for storage delaying (see primes for case)
93 %% * internal constraints declaration + analyses?
94 %% * Do not store in global variable store if not necessary
95 %% NOTE: affects show_store/1
96 %% * var_assoc multi-level store: variable - ground
97 %% * Do not maintain/check unnecessary propagation history
98 %% for reasons of anti-monotony
99 %% * Strengthen storage analysis for propagation rules
100 %% reason about bodies of rules only containing constraints
101 %% -> fixpoint with observation analysis
102 %% * instantiation declarations
103 %% COMPOUND (bound to nonvar)
104 %% avoid nonvar tests
106 %% * make difference between cheap guards for reordering
107 %% and non-binding guards for lock removal
108 %% * fd -> once/[] transformation for propagation
109 %% * cheap guards interleaved with head retrieval + faster
110 %% via-retrieval + non-empty checking for propagation rules
111 %% redo for simpagation_head2 prelude
112 %% * intelligent backtracking for simplification/simpagation rule
113 %% generator_1(X),'_$savecp'(CP_1),
120 %% ('_$cutto'(CP_1), fail)
124 %% or recently developped cascading-supported approach
125 %% * intelligent backtracking for propagation rule
126 %% use additional boolean argument for each possible smart backtracking
127 %% when boolean at end of list true -> no smart backtracking
128 %% false -> smart backtracking
129 %% only works for rules with at least 3 constraints in the head
130 %% * (set semantics + functional dependency) declaration + resolution
131 %% * identify cases where prefixes of partner lookups for subsequent occurrences can be
134 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
135 :- module(chr_translate,
136 [ chr_translate/2 % +Decls, -TranslatedDecls
139 :- use_module(library(lists),[member/2, append/3,reverse/2,permutation/2,last/2]).
140 :- use_module(library(ordsets)).
143 :- use_module(hprolog).
144 :- use_module(pairlist).
145 :- use_module(a_star).
146 :- use_module(listmap).
147 :- use_module(clean_code).
148 :- use_module(builtins).
150 :- use_module(guard_entailment).
151 :- use_module(chr_compiler_options).
152 :- use_module(chr_compiler_utility).
153 :- use_module(chr_compiler_errors).
155 :- op(1150, fx, chr_type).
156 :- op(1130, xfx, --->).
160 :- op(1150, fx, constraints).
161 :- op(1150, fx, chr_constraint).
163 :- chr_option(debug,off).
164 :- chr_option(optimize,full).
165 :- chr_option(check_guard_bindings,off).
167 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
169 :- chr_type list(T) ---> [] ; [T|list(T)].
170 :- chr_type list == list(any).
172 :- chr_type maybe(T) ---> yes(T) ; no.
174 :- chr_type constraint ---> any / any.
176 :- chr_type module_name == any.
178 :- chr_type pragma_rule ---> pragma(rule,idspair,list(pragma_type),maybe(rule_name),rule_nb).
179 :- chr_type rule ---> rule(list(any),list(any),goal,goal).
180 :- chr_type idspair ---> ids(list(id),list(id)).
182 :- chr_type pragma_type ---> passive(id)
185 ; already_in_heads(id)
187 ; history(history_name,list(id)).
188 :- chr_type history_name== any.
190 :- chr_type rule_name == any.
191 :- chr_type rule_nb == natural.
192 :- chr_type id == natural.
194 :- chr_type goal == any.
196 :- chr_type store_type ---> default
197 ; multi_store(list(store_type))
198 ; multi_hash(list(list(int)))
199 ; multi_inthash(list(list(int)))
202 % EXPERIMENTAL STORES
203 ; var_assoc_store(int,list(int))
204 ; identifier_store(int)
205 ; type_indexed_identifier_store(int,any).
207 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
209 %------------------------------------------------------------------------------%
210 :- chr_constraint target_module/1.
211 :- chr_option(mode,target_module(+)).
212 :- chr_option(type_declaration,target_module(module_name)).
213 %------------------------------------------------------------------------------%
214 target_module(_) \ target_module(_) <=> true.
216 %------------------------------------------------------------------------------%
217 :- chr_constraint get_target_module/1.
218 :- chr_option(mode,get_target_module(-)).
219 :- chr_option(type_declaration,get_target_module(module_name)).
220 %------------------------------------------------------------------------------%
221 target_module(Mod) \ get_target_module(Query)
223 get_target_module(Query)
226 :- chr_constraint indexed_argument/2. % argument instantiation may enable applicability of rule
227 :- chr_option(mode,indexed_argument(+,+)).
228 :- chr_option(type_declaration,indexed_argument(constraint,int)).
230 :- chr_constraint is_indexed_argument/2.
231 :- chr_option(mode,is_indexed_argument(+,+)).
232 :- chr_option(type_declaration,is_indexed_argument(constraint,int)).
234 :- chr_constraint constraint_mode/2.
235 :- chr_option(mode,constraint_mode(+,+)).
236 :- chr_option(type_declaration,constraint_mode(constraint,list)).
238 :- chr_constraint get_constraint_mode/2.
239 :- chr_option(mode,get_constraint_mode(+,-)).
240 :- chr_option(type_declaration,get_constraint_mode(constraint,list)).
242 :- chr_constraint may_trigger/1.
243 :- chr_option(mode,may_trigger(+)).
244 :- chr_option(type_declaration,may_trigger(constraint)).
246 :- chr_constraint only_ground_indexed_arguments/1.
247 :- chr_option(mode,only_ground_indexed_arguments(+)).
248 :- chr_option(type_declaration,only_ground_indexed_arguments(constraint)).
250 :- chr_constraint none_suspended_on_variables/0.
252 :- chr_constraint are_none_suspended_on_variables/0.
254 :- chr_constraint store_type/2.
255 :- chr_option(mode,store_type(+,+)).
256 :- chr_option(type_declaration,store_type(constraint,store_type)).
258 :- chr_constraint get_store_type/2.
259 :- chr_option(mode,get_store_type(+,?)).
260 :- chr_option(type_declaration,get_store_type(constraint,store_type)).
262 :- chr_constraint update_store_type/2.
263 :- chr_option(mode,update_store_type(+,+)).
264 :- chr_option(type_declaration,update_store_type(constraint,store_type)).
266 :- chr_constraint actual_store_types/2.
267 :- chr_option(mode,actual_store_types(+,+)).
268 :- chr_option(type_declaration,actual_store_types(constraint,list(store_type))).
270 :- chr_constraint assumed_store_type/2.
271 :- chr_option(mode,assumed_store_type(+,+)).
272 :- chr_option(type_declaration,assumed_store_type(constraint,store_type)).
274 :- chr_constraint validate_store_type_assumption/1.
275 :- chr_option(mode,validate_store_type_assumption(+)).
276 :- chr_option(type_declaration,validate_store_type_assumption(constraint)).
278 :- chr_constraint rule_count/1.
279 :- chr_option(mode,rule_count(+)).
280 :- chr_option(type_declaration,rule_count(natural)).
282 :- chr_constraint inc_rule_count/1.
283 :- chr_option(mode,inc_rule_count(-)).
284 :- chr_option(type_declaration,inc_rule_count(natural)).
286 rule_count(_) \ rule_count(_)
288 rule_count(C), inc_rule_count(NC)
289 <=> NC is C + 1, rule_count(NC).
291 <=> NC = 1, rule_count(NC).
293 :- chr_constraint passive/2.
294 :- chr_option(mode,passive(+,+)).
296 :- chr_constraint is_passive/2.
297 :- chr_option(mode,is_passive(+,+)).
299 :- chr_constraint any_passive_head/1.
300 :- chr_option(mode,any_passive_head(+)).
302 :- chr_constraint new_occurrence/4.
303 :- chr_option(mode,new_occurrence(+,+,+,+)).
305 :- chr_constraint occurrence/5.
306 :- chr_option(mode,occurrence(+,+,+,+,+)).
308 :- chr_constraint get_occurrence/4.
309 :- chr_option(mode,get_occurrence(+,+,-,-)).
311 :- chr_constraint get_occurrence_from_id/4.
312 :- chr_option(mode,get_occurrence_from_id(+,-,+,+)).
314 :- chr_constraint max_occurrence/2.
315 :- chr_option(mode,max_occurrence(+,+)).
317 :- chr_constraint get_max_occurrence/2.
318 :- chr_option(mode,get_max_occurrence(+,-)).
320 :- chr_constraint allocation_occurrence/2.
321 :- chr_option(mode,allocation_occurrence(+,+)).
323 :- chr_constraint get_allocation_occurrence/2.
324 :- chr_option(mode,get_allocation_occurrence(+,-)).
326 :- chr_constraint rule/2.
327 :- chr_option(mode,rule(+,+)).
328 :- chr_option(type_declaration,rule(rule_nb,pragma_rule)).
330 :- chr_constraint get_rule/2.
331 :- chr_option(mode,get_rule(+,-)).
332 :- chr_option(type_declaration,get_rule(int,pragma_rule)).
334 :- chr_constraint least_occurrence/2.
335 :- chr_option(mode,least_occurrence(+,+)).
337 :- chr_constraint is_least_occurrence/1.
338 :- chr_option(mode,is_least_occurrence(+)).
341 indexed_argument(FA,I) \ indexed_argument(FA,I) <=> true.
342 indexed_argument(FA,I) \ is_indexed_argument(FA,I) <=> true.
343 is_indexed_argument(_,_) <=> fail.
345 %%% C O N S T R A I N T M O D E %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
347 constraint_mode(FA,_) \ constraint_mode(FA,_) <=> true.
348 constraint_mode(FA,Mode) \ get_constraint_mode(FA,Q) <=>
350 get_constraint_mode(FA,Q) <=>
354 %%% M A Y T R I G G E R %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
356 may_trigger(FA) <=> \+ has_active_occurrence(FA) | fail.
357 constraint_mode(FA,Mode), indexed_argument(FA,I) \ may_trigger(FA) <=>
361 may_trigger(FA) <=> chr_pp_flag(debugable,on). % in debug mode, we assume everything can be triggered
363 constraint_mode(FA,Mode), indexed_argument(FA,I) \ only_ground_indexed_arguments(FA)
369 only_ground_indexed_arguments(_) <=>
372 none_suspended_on_variables \ none_suspended_on_variables <=> true.
373 none_suspended_on_variables \ are_none_suspended_on_variables <=> true.
374 are_none_suspended_on_variables <=> fail.
375 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
377 store_type(FA,Store) \ get_store_type(FA,Query)
380 assumed_store_type(FA,Store) \ get_store_type(FA,Query)
382 get_store_type(_,Query)
385 actual_store_types(C,STs) \ update_store_type(C,ST)
386 <=> member(ST,STs) | true.
387 update_store_type(C,ST), actual_store_types(C,STs)
389 actual_store_types(C,[ST|STs]).
390 update_store_type(C,ST)
392 actual_store_types(C,[ST]).
394 % refine store type assumption
395 validate_store_type_assumption(C), actual_store_types(C,STs), assumed_store_type(C,_) % automatic assumption
397 store_type(C,multi_store(STs)).
398 validate_store_type_assumption(C), actual_store_types(C,STs), store_type(C,_) % user assumption
400 store_type(C,multi_store(STs)).
401 validate_store_type_assumption(C), assumed_store_type(C,_) % no lookups on constraint in debug mode
403 chr_pp_flag(debugable,on)
405 store_type(C,default).
406 validate_store_type_assumption(C), assumed_store_type(C,_) % no lookups on constraint
407 <=> store_type(C,global_ground).
408 validate_store_type_assumption(C)
411 %%% P A S S I V E %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
412 passive(R,ID) \ passive(R,ID) <=> true.
414 passive(RuleNb,ID) \ is_passive(RuleNb,ID) <=> true.
415 is_passive(_,_) <=> fail.
417 passive(RuleNb,_) \ any_passive_head(RuleNb)
421 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
423 max_occurrence(C,N) \ max_occurrence(C,M)
426 max_occurrence(C,MO), new_occurrence(C,RuleNb,ID,Type) <=>
428 occurrence(C,NO,RuleNb,ID,Type),
429 max_occurrence(C,NO).
430 new_occurrence(C,RuleNb,ID,_) <=>
431 chr_error(internal,'new_occurrence: missing max_occurrence for ~w in rule ~w\n',[C,RuleNb]).
433 max_occurrence(C,MON) \ get_max_occurrence(C,Q)
435 get_max_occurrence(C,Q)
436 <=> chr_error(internal,'get_max_occurrence: missing max occurrence for ~w\n',[C]).
438 occurrence(C,ON,Rule,ID,_) \ get_occurrence(C,ON,QRule,QID)
439 <=> Rule = QRule, ID = QID.
440 get_occurrence(C,O,_,_)
441 <=> chr_error(internal,'get_occurrence: missing occurrence ~w:~w\n',[C,O]).
443 occurrence(C,ON,Rule,ID,_) \ get_occurrence_from_id(QC,QON,Rule,ID)
444 <=> QC = C, QON = ON.
445 get_occurrence_from_id(C,O,_,_)
446 <=> chr_error(internal,'get_occurrence_from_id: missing occurrence ~w:~w\n',[]).
448 % A L L O C C A T I O N O C C U R R E N C E %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
450 % cannot store constraint at passive occurrence
451 occurrence(C,O,RuleNb,ID,_), passive(RuleNb,ID) \ allocation_occurrence(C,O)
452 <=> NO is O + 1, allocation_occurrence(C,NO).
454 % need not store constraint that is removed,
455 % unless it has to be stored in the guard of the rule
456 rule(RuleNb,Rule), occurrence(C,O,RuleNb,ID,_) \ allocation_occurrence(C,O)
457 <=> \+ is_stored_in_guard(C,RuleNb), Rule = pragma(_,ids(IDs1,_),_,_,_), member(ID,IDs1)
458 | NO is O + 1, allocation_occurrence(C,NO).
460 % need not store constraint if does not observe itself
461 % (for propagation rules we could have to allocate (history))
462 rule(RuleNb,Rule), occurrence(C,O,RuleNb,_,_) \ allocation_occurrence(C,O)
463 <=> Rule = pragma(rule([_|_],_,_,_),_,_,_,_), \+ is_observed(C,O)
464 | NO is O + 1, allocation_occurrence(C,NO).
465 % need not store constraint if does not observe itself and cannot trigger
466 % (then no history is needed)
467 rule(RuleNb,Rule), occurrence(C,O,RuleNb,_,_), least_occurrence(RuleNb,[])
468 \ allocation_occurrence(C,O)
469 <=> Rule = pragma(rule([],_,_,_),_,_,_,_), \+ is_observed(C,O)
470 | NO is O + 1, allocation_occurrence(C,NO).
472 rule(RuleNb,Rule), occurrence(C,O,RuleNb,ID,_), allocation_occurrence(C,AO)
473 \ least_occurrence(RuleNb,[ID|IDs])
474 <=> AO >= O, \+ may_trigger(C) |
475 least_occurrence(RuleNb,IDs).
476 rule(RuleNb,Rule), passive(RuleNb,ID)
477 \ least_occurrence(RuleNb,[ID|IDs])
478 <=> least_occurrence(RuleNb,IDs).
481 ==> Rule = pragma(rule([],_,_,_),ids([],IDs),_,_,_) |
482 least_occurrence(RuleNb,IDs).
484 least_occurrence(RuleNb,[]) \ is_least_occurrence(RuleNb)
486 is_least_occurrence(_)
489 allocation_occurrence(C,O) \ get_allocation_occurrence(C,Q)
491 get_allocation_occurrence(_,Q)
492 <=> chr_pp_flag(late_allocation,off), Q=0.
493 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
495 rule(RuleNb,Rule) \ get_rule(RuleNb,Q)
500 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
502 %%% C O N S T R A I N T I N D E X %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
504 % Default store constraint index assignment.
506 :- chr_constraint constraint_index/2. % constraint_index(F/A,DefaultStoreAndAttachedIndex)
507 :- chr_option(mode,constraint_index(+,+)).
508 :- chr_option(type_declaration,constraint_index(constraint,int)).
510 :- chr_constraint get_constraint_index/2.
511 :- chr_option(mode,get_constraint_index(+,-)).
512 :- chr_option(type_declaration,get_constraint_index(constraint,int)).
514 :- chr_constraint get_indexed_constraint/2.
515 :- chr_option(mode,get_indexed_constraint(+,-)).
516 :- chr_option(type_declaration,get_indexed_constraint(int,constraint)).
518 :- chr_constraint max_constraint_index/1. % max_constraint_index(MaxDefaultStoreAndAttachedIndex)
519 :- chr_option(mode,max_constraint_index(+)).
520 :- chr_option(type_declaration,max_constraint_index(int)).
522 :- chr_constraint get_max_constraint_index/1.
523 :- chr_option(mode,get_max_constraint_index(-)).
524 :- chr_option(type_declaration,get_max_constraint_index(int)).
526 constraint_index(C,Index) \ get_constraint_index(C,Query)
528 get_constraint_index(C,Query)
531 constraint_index(C,Index) \ get_indexed_constraint(Index,Q)
533 get_indexed_constraint(Index,Q)
536 max_constraint_index(Index) \ get_max_constraint_index(Query)
538 get_max_constraint_index(Query)
541 set_constraint_indices(Constraints) :-
542 set_constraint_indices(Constraints,1).
543 set_constraint_indices([],M) :-
545 max_constraint_index(N).
546 set_constraint_indices([C|Cs],N) :-
547 ( ( chr_pp_flag(debugable, on) ; \+ only_ground_indexed_arguments(C), is_stored(C) ; is_stored(C), get_store_type(C,default)
548 ; get_store_type(C,var_assoc_store(_,_))) ->
549 constraint_index(C,N),
551 set_constraint_indices(Cs,M)
553 set_constraint_indices(Cs,N)
556 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
559 :- chr_constraint identifier_size/1.
560 :- chr_option(mode,identifier_size(+)).
561 :- chr_option(type_declaration,identifier_size(natural)).
563 identifier_size(_) \ identifier_size(_)
567 :- chr_constraint get_identifier_size/1.
568 :- chr_option(mode,get_identifier_size(-)).
569 :- chr_option(type_declaration,get_identifier_size(natural)).
571 identifier_size(Size) \ get_identifier_size(Q)
575 get_identifier_size(Q)
579 :- chr_constraint identifier_index/3.
580 :- chr_option(mode,identifier_index(+,+,+)).
581 :- chr_option(type_declaration,identifier_index(constraint,natural,natural)).
583 identifier_index(C,I,_) \ identifier_index(C,I,_)
587 :- chr_constraint get_identifier_index/3.
588 :- chr_option(mode,get_identifier_index(+,+,-)).
589 :- chr_option(type_declaration,get_identifier_index(constraint,natural,natural)).
591 identifier_index(C,I,II) \ get_identifier_index(C,I,Q)
594 identifier_size(Size), get_identifier_index(C,I,Q)
597 identifier_index(C,I,NSize),
598 identifier_size(NSize),
600 get_identifier_index(C,I,Q)
602 identifier_index(C,I,2),
606 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
607 % Type Indexed Identifier Indexes
609 :- chr_constraint type_indexed_identifier_size/2.
610 :- chr_option(mode,type_indexed_identifier_size(+,+)).
611 :- chr_option(type_declaration,type_indexed_identifier_size(any,natural)).
613 type_indexed_identifier_size(IndexType,_) \ type_indexed_identifier_size(IndexType,_)
617 :- chr_constraint get_type_indexed_identifier_size/2.
618 :- chr_option(mode,get_type_indexed_identifier_size(+,-)).
619 :- chr_option(type_declaration,get_type_indexed_identifier_size(any,natural)).
621 type_indexed_identifier_size(IndexType,Size) \ get_type_indexed_identifier_size(IndexType,Q)
625 get_type_indexed_identifier_size(IndexType,Q)
629 :- chr_constraint type_indexed_identifier_index/4.
630 :- chr_option(mode,type_indexed_identifier_index(+,+,+,+)).
631 :- chr_option(type_declaration,type_indexed_identifier_index(any,constraint,natural,natural)).
633 type_indexed_identifier_index(_,C,I,_) \ type_indexed_identifier_index(_,C,I,_)
637 :- chr_constraint get_type_indexed_identifier_index/4.
638 :- chr_option(mode,get_type_indexed_identifier_index(+,+,+,-)).
639 :- chr_option(type_declaration,get_type_indexed_identifier_index(any,constraint,natural,natural)).
641 type_indexed_identifier_index(IndexType,C,I,II) \ get_type_indexed_identifier_index(IndexType,C,I,Q)
644 type_indexed_identifier_size(IndexType,Size), get_type_indexed_identifier_index(IndexType,C,I,Q)
647 type_indexed_identifier_index(IndexType,C,I,NSize),
648 type_indexed_identifier_size(IndexType,NSize),
650 get_type_indexed_identifier_index(IndexType,C,I,Q)
652 type_indexed_identifier_index(IndexType,C,I,2),
653 type_indexed_identifier_size(IndexType,2),
656 type_indexed_identifier_structure(IndexType,Structure) :-
657 type_indexed_identifier_name(IndexType,type_indexed_identifier_struct,Functor),
658 get_type_indexed_identifier_size(IndexType,Arity),
659 functor(Structure,Functor,Arity).
660 type_indexed_identifier_name(IndexType,Prefix,Name) :-
662 IndexTypeName = IndexType
664 term_to_atom(IndexType,IndexTypeName)
666 atom_concat_list([Prefix,'_',IndexTypeName],Name).
668 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
673 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
677 chr_translate(Declarations,NewDeclarations) :-
678 chr_info(banner,'\tThe K.U.Leuven CHR System\t\n\t\tContributors:\tTom Schrijvers, Jon Sneyers, Bart Demoen,\n\t\t\t\tJan Wielemaker\n\t\tCopyright:\tK.U.Leuven, Belgium\n\t\tURL:\t\thttp://www.cs.kuleuven.be/~~toms/CHR/\n',[]),
680 partition_clauses(Declarations,Constraints0,Rules0,OtherClauses),
681 check_declared_constraints(Constraints0),
682 generate_show_constraint(Constraints0,Constraints,Rules0,Rules),
683 add_constraints(Constraints),
686 check_rules(Rules,Constraints),
687 time('type checking',chr_translate:static_type_check),
688 add_occurrences(Rules),
689 time('functional dependency',chr_translate:functional_dependency_analysis(Rules)),
690 time('set semantics',chr_translate:set_semantics_rules(Rules)),
691 time('symmetry analysis',chr_translate:symmetry_analysis(Rules)),
692 time('guard simplification',chr_translate:guard_simplification),
693 time('late storage',chr_translate:storage_analysis(Constraints)),
694 time('observation',chr_translate:observation_analysis(Constraints)),
695 time('ai observation',chr_translate:ai_observation_analysis(Constraints)),
696 time('late allocation',chr_translate:late_allocation_analysis(Constraints)),
697 partial_wake_analysis,
698 time('assume constraint stores',chr_translate:assume_constraint_stores(Constraints)),
699 time('default constraint indices',chr_translate:set_constraint_indices(Constraints)),
701 time('constraint code generation',chr_translate:constraints_code(Constraints,ConstraintClauses)),
702 time('validate store assumptions',chr_translate:validate_store_type_assumptions(Constraints)),
703 phase_end(validate_store_type_assumptions),
705 time('store code generation',chr_translate:store_management_preds(Constraints,StoreClauses)), % depends on actual code used
706 insert_declarations(OtherClauses, Clauses0),
707 chr_module_declaration(CHRModuleDeclaration),
708 append([StoreClauses,ConstraintClauses,CHRModuleDeclaration,[end_of_file]],StuffyGeneratedClauses),
709 clean_clauses(StuffyGeneratedClauses,GeneratedClauses),
710 append([Clauses0,GeneratedClauses], NewDeclarations).
712 store_management_preds(Constraints,Clauses) :-
713 generate_attach_detach_a_constraint_all(Constraints,AttachAConstraintClauses),
714 generate_attr_unify_hook(AttrUnifyHookClauses),
715 generate_attach_increment(AttachIncrementClauses),
716 generate_extra_clauses(Constraints,ExtraClauses),
717 generate_insert_delete_constraints(Constraints,DeleteClauses),
718 generate_attach_code(Constraints,StoreClauses),
719 generate_counter_code(CounterClauses),
720 generate_dynamic_type_check_clauses(TypeCheckClauses),
721 append([AttachAConstraintClauses
722 ,AttachIncrementClauses
723 ,AttrUnifyHookClauses
733 insert_declarations(Clauses0, Clauses) :-
734 findall(:- use_module(chr(Module)),(auxiliary_module(Module), is_used_auxiliary_module(Module)),Decls),
735 append(Clauses0, [:- use_module(chr(chr_runtime))|Decls], Clauses).
737 auxiliary_module(chr_hashtable_store).
738 auxiliary_module(chr_integertable_store).
739 auxiliary_module(chr_assoc_store).
741 generate_counter_code(Clauses) :-
742 ( chr_pp_flag(store_counter,on) ->
744 ('$counter_init'(N1) :- nb_setval(N1,0)) ,
745 ('$counter'(N2,X1) :- nb_getval(N2,X1)),
746 ('$counter_inc'(N) :- nb_getval(N,X), Y is X + 1, nb_setval(N,Y)),
747 (:- '$counter_init'('$insert_counter')),
748 (:- '$counter_init'('$delete_counter')),
749 ('$insert_counter_inc' :- '$counter_inc'('$insert_counter')),
750 ('$delete_counter_inc' :- '$counter_inc'('$delete_counter')),
751 ( counter_stats(I,D) :- '$counter'('$insert_counter',I),'$counter'('$delete_counter',D))
757 % for systems with multifile declaration
758 chr_module_declaration(CHRModuleDeclaration) :-
759 get_target_module(Mod),
760 ( Mod \== chr_translate, chr_pp_flag(toplevel_show_store,on) ->
761 CHRModuleDeclaration = [
762 (:- multifile chr:'$chr_module'/1),
763 chr:'$chr_module'(Mod)
766 CHRModuleDeclaration = []
770 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
772 %% Partitioning of clauses into constraint declarations, chr rules and other
775 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
776 %% partition_clauses(+Clauses,-ConstraintDeclarations,-Rules,-OtherClauses) is det.
777 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
778 partition_clauses([],[],[],[]).
779 partition_clauses([Clause|Clauses],ConstraintDeclarations,Rules,OtherClauses) :-
780 ( parse_rule(Clause,Rule) ->
781 ConstraintDeclarations = RestConstraintDeclarations,
782 Rules = [Rule|RestRules],
783 OtherClauses = RestOtherClauses
784 ; is_declaration(Clause,ConstraintDeclaration) ->
785 append(ConstraintDeclaration,RestConstraintDeclarations,ConstraintDeclarations),
787 OtherClauses = RestOtherClauses
788 ; is_module_declaration(Clause,Mod) ->
790 ConstraintDeclarations = RestConstraintDeclarations,
792 OtherClauses = [Clause|RestOtherClauses]
793 ; is_type_definition(Clause) ->
794 ConstraintDeclarations = RestConstraintDeclarations,
796 OtherClauses = RestOtherClauses
797 ; Clause = (handler _) ->
798 chr_warning(deprecated(Clause),'Backward compatibility: ignoring handler/1 declaration.\n',[]),
799 ConstraintDeclarations = RestConstraintDeclarations,
801 OtherClauses = RestOtherClauses
802 ; Clause = (rules _) ->
803 chr_warning(deprecated(Clause),'Backward compatibility: ignoring rules/1 declaration.\n',[]),
804 ConstraintDeclarations = RestConstraintDeclarations,
806 OtherClauses = RestOtherClauses
807 ; Clause = option(OptionName,OptionValue) ->
808 chr_warning(deprecated(Clause),'Instead use `:-chr_option(~w,~w).\'\n',[OptionName,OptionValue]),
809 handle_option(OptionName,OptionValue),
810 ConstraintDeclarations = RestConstraintDeclarations,
812 OtherClauses = RestOtherClauses
813 ; Clause = (:-chr_option(OptionName,OptionValue)) ->
814 handle_option(OptionName,OptionValue),
815 ConstraintDeclarations = RestConstraintDeclarations,
817 OtherClauses = RestOtherClauses
818 ; Clause = ('$chr_compiled_with_version'(_)) ->
819 ConstraintDeclarations = RestConstraintDeclarations,
821 OtherClauses = ['$chr_compiled_with_version'(3)|RestOtherClauses]
822 ; ConstraintDeclarations = RestConstraintDeclarations,
824 OtherClauses = [Clause|RestOtherClauses]
826 partition_clauses(Clauses,RestConstraintDeclarations,RestRules,RestOtherClauses).
828 '$chr_compiled_with_version'(2).
830 is_declaration(D, Constraints) :- %% constraint declaration
831 ( D = (:- Decl), Decl =.. [F,Cs], F == (chr_constraint) ->
832 conj2list(Cs,Constraints0)
835 Decl =.. [constraints,Cs]
837 D =.. [constraints,Cs]
839 conj2list(Cs,Constraints0),
840 chr_warning(deprecated(D),'Instead use :- chr_constraint ~w.\n',[Cs])
842 extract_type_mode(Constraints0,Constraints).
844 extract_type_mode([],[]).
845 extract_type_mode([F/A|R],[F/A|R2]) :- !,extract_type_mode(R,R2).
846 extract_type_mode([C|R],[ConstraintSymbol|R2]) :-
848 ConstraintSymbol = F/A,
850 extract_types_and_modes(Args,ArgTypes,ArgModes),
851 constraint_type(ConstraintSymbol,ArgTypes),
852 constraint_mode(ConstraintSymbol,ArgModes),
853 extract_type_mode(R,R2).
855 extract_types_and_modes([],[],[]).
856 extract_types_and_modes([X|R],[T|R2],[M|R3]) :-
857 extract_type_and_mode(X,T,M),
858 extract_types_and_modes(R,R2,R3).
860 extract_type_and_mode(+(T),T,(+)) :- !.
861 extract_type_and_mode(?(T),T,(?)) :- !.
862 extract_type_and_mode(-(T),T,(-)) :- !.
863 extract_type_and_mode((+),any,(+)) :- !.
864 extract_type_and_mode((?),any,(?)) :- !.
865 extract_type_and_mode((-),any,(-)) :- !.
866 extract_type_and_mode(Illegal,_,_) :-
867 chr_error(syntax(Illegal),'Illegal mode/type declaration.\n\tCorrect syntax is +type, -type or ?type\n\tor +, - or ?.\n',[]).
869 is_type_definition(Declaration) :-
870 ( Declaration = (:- TDef) ->
875 TDef =.. [chr_type,TypeDef],
876 ( TypeDef = (Name ---> Def) ->
877 tdisj2list(Def,DefList),
878 type_definition(Name,DefList)
879 ; TypeDef = (Alias == Name) ->
880 type_alias(Alias,Name)
882 type_definition(TypeDef,[]),
883 chr_warning(syntax,'Empty type definition `~w\'.\nAre you sure you want to declare a phantom type?\n',[Declaration])
886 %% tdisj2list(+Goal,-ListOfGoals) is det.
888 % no removal of fails, e.g. :- type bool ---> true ; fail.
889 tdisj2list(Conj,L) :-
890 tdisj2list(Conj,L,[]).
892 tdisj2list(Conj,L,T) :-
896 tdisj2list(G,[G | T],T).
899 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
900 %% parse_rule(+term,-pragma_rule) is semidet.
901 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
902 parse_rule(RI,R) :- %% name @ rule
903 RI = (Name @ RI2), !,
904 rule(RI2,yes(Name),R).
908 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
909 %% parse_rule(+term,-pragma_rule) is semidet.
910 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
912 RI = (RI2 pragma P), !, %% pragmas
914 Ps = [_] % intercept variable
918 inc_rule_count(RuleCount),
919 R = pragma(R1,IDs,Ps,Name,RuleCount),
920 is_rule(RI2,R1,IDs,R).
922 inc_rule_count(RuleCount),
923 R = pragma(R1,IDs,[],Name,RuleCount),
924 is_rule(RI,R1,IDs,R).
926 is_rule(RI,R,IDs,RC) :- %% propagation rule
929 get_ids(Head2i,IDs2,Head2,RC),
932 R = rule([],Head2,G,RB)
934 R = rule([],Head2,true,B)
936 is_rule(RI,R,IDs,RC) :- %% simplification/simpagation rule
945 conj2list(H1,Head2i),
946 conj2list(H2,Head1i),
947 get_ids(Head2i,IDs2,Head2,0,N,RC),
948 get_ids(Head1i,IDs1,Head1,N,_,RC),
950 ; conj2list(H,Head1i),
952 get_ids(Head1i,IDs1,Head1,RC),
955 R = rule(Head1,Head2,Guard,Body).
957 get_ids(Cs,IDs,NCs,RC) :-
958 get_ids(Cs,IDs,NCs,0,_,RC).
960 get_ids([],[],[],N,N,_).
961 get_ids([C|Cs],[N|IDs],[NC|NCs],N,NN,RC) :-
966 check_direct_pragma(N1,N,RC)
972 get_ids(Cs,IDs,NCs, M,NN,RC).
974 check_direct_pragma(passive,Id,PragmaRule) :- !,
975 PragmaRule = pragma(_,ids(IDs1,IDs2),_,_,RuleNb),
977 check_direct_pragma(Abbrev,Id,PragmaRule) :-
978 ( direct_pragma(FullPragma),
979 atom_concat(Abbrev,Remainder,FullPragma) ->
980 chr_warning(problem_pragma(Abbrev,PragmaRule),'completed `~w\' to `~w\'\n',[Abbrev,FullPragma])
982 chr_warning(unsupported_pragma(Abbrev,PragmaRule),'',[])
985 direct_pragma(passive).
987 is_module_declaration((:- module(Mod)),Mod).
988 is_module_declaration((:- module(Mod,_)),Mod).
990 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
992 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
995 add_constraints([C|Cs]) :-
1000 constraint_mode(C,Mode),
1001 add_constraints(Cs).
1005 add_rules([Rule|Rules]) :-
1006 Rule = pragma(_,_,_,_,RuleNb),
1010 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1012 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1013 %% Some input verification:
1015 check_declared_constraints(Constraints) :-
1016 check_declared_constraints(Constraints,[]).
1018 check_declared_constraints([],_).
1019 check_declared_constraints([C|Cs],Acc) :-
1020 ( memberchk_eq(C,Acc) ->
1021 chr_error(syntax(C),'Constraint multiply defined: ~w.\n\tRemove redundant declaration!\n',[C])
1025 check_declared_constraints(Cs,[C|Acc]).
1027 %% - all constraints in heads are declared constraints
1028 %% - all passive pragmas refer to actual head constraints
1031 check_rules([PragmaRule|Rest],Decls) :-
1032 check_rule(PragmaRule,Decls),
1033 check_rules(Rest,Decls).
1035 check_rule(PragmaRule,Decls) :-
1036 check_rule_indexing(PragmaRule),
1037 check_trivial_propagation_rule(PragmaRule),
1038 PragmaRule = pragma(Rule,_IDs,Pragmas,_Name,_N),
1039 Rule = rule(H1,H2,_,_),
1040 append(H1,H2,HeadConstraints),
1041 check_head_constraints(HeadConstraints,Decls,PragmaRule),
1042 check_pragmas(Pragmas,PragmaRule).
1044 % Make all heads passive in trivial propagation rule
1045 % ... ==> ... | true.
1046 check_trivial_propagation_rule(PragmaRule) :-
1047 PragmaRule = pragma(Rule,IDs,Pragmas,Name,RuleNb),
1048 ( Rule = rule([],_,_,true) ->
1049 chr_warning(weird_program,'Ignoring propagation rule with empty body: ~@.\n\t\n',[format_rule(PragmaRule)]),
1050 set_all_passive(RuleNb)
1055 check_head_constraints([],_,_).
1056 check_head_constraints([Constr|Rest],Decls,PragmaRule) :-
1057 functor(Constr,F,A),
1058 ( member(F/A,Decls) ->
1059 check_head_constraints(Rest,Decls,PragmaRule)
1061 chr_error(syntax(Constr),'Undeclared constraint ~w in head of ~@.\n\tConstraint should be one of ~w.\n', [F/A,format_rule(PragmaRule),Decls])
1064 check_pragmas([],_).
1065 check_pragmas([Pragma|Pragmas],PragmaRule) :-
1066 check_pragma(Pragma,PragmaRule),
1067 check_pragmas(Pragmas,PragmaRule).
1069 check_pragma(Pragma,PragmaRule) :-
1071 chr_error(syntax(Pragma),'Invalid pragma ~w in ~@.\n\tPragma should not be a variable!\n',[Pragma,format_rule(PragmaRule)]).
1072 check_pragma(passive(ID), PragmaRule) :-
1074 PragmaRule = pragma(_,ids(IDs1,IDs2),_,_,RuleNb),
1075 ( memberchk_eq(ID,IDs1) ->
1077 ; memberchk_eq(ID,IDs2) ->
1080 chr_error(syntax(ID),'Invalid identifier ~w in pragma passive in ~@.\n', [ID,format_rule(PragmaRule)])
1084 check_pragma(mpassive(IDs), PragmaRule) :-
1086 PragmaRule = pragma(_,_,_,_,RuleNb),
1087 chr_warning(experimental,'Experimental pragma ~w. Use with care!\n',[mpassive(IDs)]),
1088 maplist(passive(RuleNb),IDs).
1090 check_pragma(Pragma, PragmaRule) :-
1091 Pragma = already_in_heads,
1093 chr_warning(unsupported_pragma(Pragma,PragmaRule),'Termination and correctness may be affected.\n',[]).
1095 check_pragma(Pragma, PragmaRule) :-
1096 Pragma = already_in_head(_),
1098 chr_warning(unsupported_pragma(Pragma,PragmaRule),'Termination and correctness may be affected.\n',[]).
1100 check_pragma(Pragma, PragmaRule) :-
1101 Pragma = no_history,
1103 chr_warning(experimental,'Experimental pragma no_history. Use with care!\n',[]),
1104 PragmaRule = pragma(_,_,_,_,N),
1107 check_pragma(Pragma, PragmaRule) :-
1108 Pragma = history(HistoryName,IDs),
1110 chr_warning(experimental,'Experimental pragma ~w. Use with care!\n',[Pragma]),
1112 chr_error(syntax(Pragma),'Invalid empty history.\n',[])
1116 PragmaRule = pragma(_,_,_,_,RuleNb),
1117 history(RuleNb,HistoryName,IDs).
1119 check_pragma(Pragma,PragmaRule) :-
1120 chr_error(syntax(Pragma),'Unknown pragma ~w in ~@.\n', [Pragma,format_rule(PragmaRule)]).
1122 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1123 %% no_history(+RuleNb) is det.
1124 :- chr_constraint no_history/1.
1125 :- chr_option(mode,no_history(+)).
1126 :- chr_option(type_declaration,no_history(int)).
1128 %% has_no_history(+RuleNb) is semidet.
1129 :- chr_constraint has_no_history/1.
1130 :- chr_option(mode,has_no_history(+)).
1131 :- chr_option(type_declaration,has_no_history(int)).
1133 no_history(RuleNb) \ has_no_history(RuleNb) <=> true.
1134 has_no_history(_) <=> fail.
1136 :- chr_constraint history/3.
1137 :- chr_option(mode,history(+,+,+)).
1139 :- chr_constraint named_history/3.
1141 history(RuleNb,Name,IDs) \ named_history(RuleNb,QName,QIDs) <=> QName = Name, QIDs = IDs.
1143 named_history(_,_,_) <=> fail.
1145 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1148 format_rule(PragmaRule) :-
1149 PragmaRule = pragma(_,_,_,MaybeName,N),
1150 ( MaybeName = yes(Name) ->
1151 write('rule '), write(Name)
1153 write('rule number '), write(N)
1156 check_rule_indexing(PragmaRule) :-
1157 PragmaRule = pragma(Rule,_,_,_,_),
1158 Rule = rule(H1,H2,G,_),
1159 term_variables(H1-H2,HeadVars),
1160 remove_anti_monotonic_guards(G,HeadVars,NG),
1161 check_indexing(H1,NG-H2),
1162 check_indexing(H2,NG-H1),
1164 ( chr_pp_flag(term_indexing,on) ->
1165 term_variables(NG,GuardVariables),
1166 append(H1,H2,Heads),
1167 check_specs_indexing(Heads,GuardVariables,Specs)
1172 :- chr_constraint indexing_spec/2.
1173 :- chr_option(mode,indexing_spec(+,+)).
1175 :- chr_constraint get_indexing_spec/2.
1176 :- chr_option(mode,get_indexing_spec(+,-)).
1179 indexing_spec(FA,Spec) \ get_indexing_spec(FA,R) <=> R = Spec.
1180 get_indexing_spec(_,Spec) <=> Spec = [].
1182 indexing_spec(FA,Specs1), indexing_spec(FA,Specs2)
1184 append(Specs1,Specs2,Specs),
1185 indexing_spec(FA,Specs).
1187 remove_anti_monotonic_guards(G,Vars,NG) :-
1189 remove_anti_monotonic_guard_list(GL,Vars,NGL),
1192 remove_anti_monotonic_guard_list([],_,[]).
1193 remove_anti_monotonic_guard_list([G|Gs],Vars,NGs) :-
1194 ( G = var(X), memberchk_eq(X,Vars) ->
1196 % TODO: this is not correct
1197 % ; G = functor(Term,Functor,Arity), % isotonic
1198 % \+ memberchk_eq(Functor,Vars), \+ memberchk_eq(Arity,Vars) ->
1203 remove_anti_monotonic_guard_list(Gs,Vars,RGs).
1205 check_indexing([],_).
1206 check_indexing([Head|Heads],Other) :-
1209 term_variables(Heads-Other,OtherVars),
1210 check_indexing(Args,1,F/A,OtherVars),
1211 check_indexing(Heads,[Head|Other]).
1213 check_indexing([],_,_,_).
1214 check_indexing([Arg|Args],I,FA,OtherVars) :-
1215 ( is_indexed_argument(FA,I) ->
1218 indexed_argument(FA,I)
1220 term_variables(Args,ArgsVars),
1221 append(ArgsVars,OtherVars,RestVars),
1222 ( memberchk_eq(Arg,RestVars) ->
1223 indexed_argument(FA,I)
1229 term_variables(Arg,NVars),
1230 append(NVars,OtherVars,NOtherVars),
1231 check_indexing(Args,J,FA,NOtherVars).
1233 check_specs_indexing([],_,[]).
1234 check_specs_indexing([Head|Heads],Variables,Specs) :-
1235 Specs = [Spec|RSpecs],
1236 term_variables(Heads,OtherVariables,Variables),
1237 check_spec_indexing(Head,OtherVariables,Spec),
1238 term_variables(Head,NVariables,Variables),
1239 check_specs_indexing(Heads,NVariables,RSpecs).
1241 check_spec_indexing(Head,OtherVariables,Spec) :-
1243 Spec = spec(F,A,ArgSpecs),
1245 check_args_spec_indexing(Args,1,OtherVariables,ArgSpecs),
1246 indexing_spec(F/A,[ArgSpecs]).
1248 check_args_spec_indexing([],_,_,[]).
1249 check_args_spec_indexing([Arg|Args],I,OtherVariables,ArgSpecs) :-
1250 term_variables(Args,Variables,OtherVariables),
1251 ( check_arg_spec_indexing(Arg,I,Variables,ArgSpec) ->
1252 ArgSpecs = [ArgSpec|RArgSpecs]
1254 ArgSpecs = RArgSpecs
1257 term_variables(Arg,NOtherVariables,OtherVariables),
1258 check_args_spec_indexing(Args,J,NOtherVariables,RArgSpecs).
1260 check_arg_spec_indexing(Arg,I,Variables,ArgSpec) :-
1262 memberchk_eq(Arg,Variables),
1263 ArgSpec = specinfo(I,any,[])
1266 ArgSpec = specinfo(I,F/A,[ArgSpecs]),
1268 check_args_spec_indexing(Args,1,Variables,ArgSpecs)
1271 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1273 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1276 add_occurrences([]).
1277 add_occurrences([Rule|Rules]) :-
1278 Rule = pragma(rule(H1,H2,_,_),ids(IDs1,IDs2),_,_,Nb),
1279 add_occurrences(H1,IDs1,simplification,Nb),
1280 add_occurrences(H2,IDs2,propagation,Nb),
1281 add_occurrences(Rules).
1283 add_occurrences([],[],_,_).
1284 add_occurrences([H|Hs],[ID|IDs],Type,RuleNb) :-
1287 new_occurrence(FA,RuleNb,ID,Type),
1288 add_occurrences(Hs,IDs,Type,RuleNb).
1290 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1292 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1293 % Observation Analysis
1303 :- chr_constraint observation_analysis/1.
1304 :- chr_option(mode, observation_analysis(+)).
1306 observation_analysis(Cs), rule(RuleNb,PragmaRule) # Id ==>
1307 PragmaRule = pragma(rule(_,_,Guard,Body),_,_,_,_),
1308 ( chr_pp_flag(store_in_guards, on) ->
1309 observation_analysis(RuleNb, Guard, guard, Cs)
1313 observation_analysis(RuleNb, Body, body, Cs)
1316 observation_analysis(_) <=> true.
1318 observation_analysis(RuleNb, Term, GB, Cs) :-
1319 ( all_spawned(RuleNb,GB) ->
1322 spawns_all(RuleNb,GB)
1330 observation_analysis(RuleNb,T1,GB,Cs),
1331 observation_analysis(RuleNb,T2,GB,Cs)
1333 observation_analysis(RuleNb,T1,GB,Cs),
1334 observation_analysis(RuleNb,T2,GB,Cs)
1335 ; Term = (T1->T2) ->
1336 observation_analysis(RuleNb,T1,GB,Cs),
1337 observation_analysis(RuleNb,T2,GB,Cs)
1339 observation_analysis(RuleNb,T,GB,Cs)
1340 ; functor(Term,F,A), member(F/A,Cs) ->
1341 spawns(RuleNb,GB,F/A)
1343 spawns_all_triggers(RuleNb,GB)
1344 ; Term = (_ is _) ->
1345 spawns_all_triggers(RuleNb,GB)
1346 ; builtin_binds_b(Term,Vars) ->
1350 spawns_all_triggers(RuleNb,GB)
1353 spawns_all(RuleNb,GB)
1356 :- chr_constraint spawns/3.
1357 :- chr_option(mode, spawns(+,+,+)).
1359 :- chr_constraint spawns_all/2, spawns_all_triggers/2.
1360 :- chr_option(mode, spawns_all(+,+)).
1361 :- chr_option(mode, spawns_all_triggers(+,+)).
1363 spawns_all(RuleNb,GB) \ spawns_all(RuleNb,GB) <=> true.
1364 spawns_all(RuleNb,guard) \ spawns_all(RuleNb,body) <=> true.
1365 spawns_all_triggers(RuleNb,GB) \ spawns_all_triggers(RuleNb,GB) <=> true.
1366 spawns_all_triggers(RuleNb,guard) \ spawns_all_triggers(RuleNb,body) <=> true.
1367 spawns(RuleNb,GB,C) \ spawns(RuleNb,GB,C) <=> true.
1368 spawns(RuleNb,guard,C) \ spawns(RuleNb,body,C) <=> true.
1370 spawns_all(RuleNb,GB) \ spawns(RuleNb,GB,_) <=> true.
1371 spawns_all(RuleNb,guard) \ spawns(RuleNb,body,_) <=> true.
1372 spawns_all(RuleNb,GB) \ spawns_all_triggers(RuleNb,GB) <=> true.
1373 spawns_all(RuleNb,guard) \ spawns_all_triggers(RuleNb,body) <=> true.
1375 spawns_all_triggers(RuleNb,GB) \ spawns(RuleNb,GB,C) <=> may_trigger(C) | true.
1376 spawns_all_triggers(RuleNb,guard) \ spawns(RuleNb,body,C) <=> may_trigger(C) | true.
1378 spawns_all(RuleNb2,_), occurrence(C1,_,RuleNb2,O,_)#Id
1380 spawns(RuleNb1,GB,C1)
1382 \+ is_passive(RuleNb2,O)
1384 spawns_all(RuleNb1,GB)
1388 occurrence(C1,_,RuleNb2,O,_)#Id, spawns_all(RuleNb2,_)
1390 \+(\+ spawns_all_triggers_implies_spawns_all), % in the hope it schedules this guard early...
1391 \+ is_passive(RuleNb2,O), may_trigger(C1)
1393 spawns_all_triggers_implies_spawns_all
1397 :- chr_constraint spawns_all_triggers_implies_spawns_all/0.
1398 spawns_all_triggers_implies_spawns_all, spawns_all_triggers_implies_spawns_all <=> fail.
1399 spawns_all_triggers_implies_spawns_all \
1400 spawns_all_triggers(RuleNb,GB) <=> spawns_all(RuleNb,GB).
1402 spawns_all_triggers(RuleNb2,_), occurrence(C1,_,RuleNb2,O,_)#Id
1404 spawns(RuleNb1,GB,C1)
1406 \+ is_passive(RuleNb2,O)
1408 spawns_all_triggers(RuleNb1,GB)
1412 % a bit dangerous this rule: could start propagating too much too soon?
1413 spawns(RuleNb2,_,C2), occurrence(C1,_,RuleNb2,O,_)#Id,
1414 spawns(RuleNb1,GB,C1)
1416 RuleNb1 \== RuleNb2, C1 \== C2,
1417 \+ is_passive(RuleNb2,O)
1419 spawns(RuleNb1,GB,C2)
1423 spawns(RuleNb2,_,C2), occurrence(C1,_,RuleNb2,O,_)#Id,
1424 spawns_all_triggers(RuleNb1,GB)
1426 \+ is_passive(RuleNb2,O), may_trigger(C1), \+ may_trigger(C2)
1428 spawns(RuleNb1,GB,C2)
1433 :- chr_constraint all_spawned/2.
1434 :- chr_option(mode, all_spawned(+,+)).
1435 spawns_all(RuleNb,guard) \ all_spawned(RuleNb,_) <=> true.
1436 spawns_all(RuleNb,GB) \ all_spawned(RuleNb,GB) <=> true.
1437 all_spawned(RuleNb,GB) <=> fail.
1439 :- chr_constraint is_observed/3.
1440 :- chr_option(mode, is_observed(+,+,+)).
1441 occurrence(C,O,RuleNb,_,_) \ is_observed(C,O,GB) <=> do_is_observed(C,RuleNb,GB).
1442 is_observed(_,_,_) <=> throw('this cannot happen?').
1444 :- chr_constraint do_is_observed/3.
1445 :- chr_option(mode, do_is_observed(+,+,?)).
1447 spawns_all(RuleNb,GB),
1448 occurrence(_,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1450 do_is_observed(C,RuleNb,Q)
1452 \+ is_passive(RuleNb2,O)
1456 spawns(RuleNb,GB,C2),
1457 occurrence(C2,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1459 do_is_observed(C,RuleNb,Q)
1461 \+ is_passive(RuleNb2,O)
1465 spawns_all_triggers(RuleNb,GB),
1466 occurrence(C2,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1468 do_is_observed(C,RuleNb,Q)
1470 \+ is_passive(RuleNb2,O), may_trigger(C2)
1474 do_is_observed(_,_,_) <=> chr_pp_flag(observation_analysis,off).
1479 ai_is_observed(C,O).
1481 is_stored_in_guard(C,RuleNb) :-
1482 chr_pp_flag(store_in_guards, on),
1483 do_is_observed(C,RuleNb,guard).
1485 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1487 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1490 late_allocation_analysis(Cs) :-
1491 ( chr_pp_flag(late_allocation,on) ->
1497 late_allocation([]).
1498 late_allocation([C|Cs]) :-
1499 allocation_occurrence(C,1),
1500 late_allocation(Cs).
1501 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1504 %% Generated predicates
1505 %% attach_$CONSTRAINT
1507 %% detach_$CONSTRAINT
1510 %% attach_$CONSTRAINT
1511 generate_attach_detach_a_constraint_all([],[]).
1512 generate_attach_detach_a_constraint_all([Constraint|Constraints],Clauses) :-
1513 ( ( chr_pp_flag(debugable,on) ; is_stored(Constraint), \+ only_ground_indexed_arguments(Constraint), \+ get_store_type(Constraint,var_assoc_store(_,_)) ) ->
1514 generate_attach_a_constraint(Constraint,Clauses1),
1515 generate_detach_a_constraint(Constraint,Clauses2)
1520 generate_attach_detach_a_constraint_all(Constraints,Clauses3),
1521 append([Clauses1,Clauses2,Clauses3],Clauses).
1523 generate_attach_a_constraint(Constraint,[Clause1,Clause2]) :-
1524 generate_attach_a_constraint_nil(Constraint,Clause1),
1525 generate_attach_a_constraint_cons(Constraint,Clause2).
1527 attach_constraint_atom(FA,Vars,Susp,Atom) :-
1528 make_name('attach_',FA,Name),
1529 Atom =.. [Name,Vars,Susp].
1531 generate_attach_a_constraint_nil(FA,Clause) :-
1532 Clause = (Head :- true),
1533 attach_constraint_atom(FA,[],_,Head).
1535 generate_attach_a_constraint_cons(FA,Clause) :-
1536 Clause = (Head :- Body),
1537 attach_constraint_atom(FA,[Var|Vars],Susp,Head),
1538 attach_constraint_atom(FA,Vars,Susp,RecursiveCall),
1539 Body = ( AttachBody, Subscribe, RecursiveCall ),
1540 get_max_constraint_index(N),
1542 generate_attach_body_1(FA,Var,Susp,AttachBody)
1544 generate_attach_body_n(FA,Var,Susp,AttachBody)
1546 % SWI-Prolog specific code
1547 chr_pp_flag(solver_events,NMod),
1549 Args = [[Var|_],Susp],
1550 get_target_module(Mod),
1551 use_auxiliary_predicate(run_suspensions),
1552 Subscribe = clp_events:subscribe(Var,NMod,Mod,Mod:'$run_suspensions'([Susp]))
1557 generate_attach_body_1(FA,Var,Susp,Body) :-
1558 get_target_module(Mod),
1560 ( get_attr(Var, Mod, Susps) ->
1561 put_attr(Var, Mod, [Susp|Susps])
1563 put_attr(Var, Mod, [Susp])
1566 generate_attach_body_n(F/A,Var,Susp,Body) :-
1567 get_constraint_index(F/A,Position),
1568 or_pattern(Position,Pattern),
1569 get_max_constraint_index(Total),
1570 make_attr(Total,Mask,SuspsList,Attr),
1571 nth1(Position,SuspsList,Susps),
1572 substitute(Susps,SuspsList,[Susp|Susps],SuspsList1),
1573 make_attr(Total,Mask,SuspsList1,NewAttr1),
1574 substitute(Susps,SuspsList,[Susp],SuspsList2),
1575 make_attr(Total,NewMask,SuspsList2,NewAttr2),
1576 copy_term(SuspsList,SuspsList3),
1577 nth1(Position,SuspsList3,[Susp]),
1578 chr_delete(SuspsList3,[Susp],RestSuspsList),
1579 set_elems(RestSuspsList,[]),
1580 make_attr(Total,Pattern,SuspsList3,NewAttr3),
1581 get_target_module(Mod),
1583 ( get_attr(Var,Mod,TAttr) ->
1585 ( Mask /\ Pattern =:= Pattern ->
1586 put_attr(Var, Mod, NewAttr1)
1588 NewMask is Mask \/ Pattern,
1589 put_attr(Var, Mod, NewAttr2)
1592 put_attr(Var,Mod,NewAttr3)
1595 %% detach_$CONSTRAINT
1596 generate_detach_a_constraint(Constraint,[Clause1,Clause2]) :-
1597 generate_detach_a_constraint_nil(Constraint,Clause1),
1598 generate_detach_a_constraint_cons(Constraint,Clause2).
1600 detach_constraint_atom(FA,Vars,Susp,Atom) :-
1601 make_name('detach_',FA,Name),
1602 Atom =.. [Name,Vars,Susp].
1604 generate_detach_a_constraint_nil(FA,Clause) :-
1605 Clause = ( Head :- true),
1606 detach_constraint_atom(FA,[],_,Head).
1608 generate_detach_a_constraint_cons(FA,Clause) :-
1609 Clause = (Head :- Body),
1610 detach_constraint_atom(FA,[Var|Vars],Susp,Head),
1611 detach_constraint_atom(FA,Vars,Susp,RecursiveCall),
1612 Body = ( DetachBody, RecursiveCall ),
1613 get_max_constraint_index(N),
1615 generate_detach_body_1(FA,Var,Susp,DetachBody)
1617 generate_detach_body_n(FA,Var,Susp,DetachBody)
1620 generate_detach_body_1(FA,Var,Susp,Body) :-
1621 get_target_module(Mod),
1623 ( get_attr(Var,Mod,Susps) ->
1624 'chr sbag_del_element'(Susps,Susp,NewSusps),
1628 put_attr(Var,Mod,NewSusps)
1634 generate_detach_body_n(F/A,Var,Susp,Body) :-
1635 get_constraint_index(F/A,Position),
1636 or_pattern(Position,Pattern),
1637 and_pattern(Position,DelPattern),
1638 get_max_constraint_index(Total),
1639 make_attr(Total,Mask,SuspsList,Attr),
1640 nth1(Position,SuspsList,Susps),
1641 substitute(Susps,SuspsList,[],SuspsList1),
1642 make_attr(Total,NewMask,SuspsList1,Attr1),
1643 substitute(Susps,SuspsList,NewSusps,SuspsList2),
1644 make_attr(Total,Mask,SuspsList2,Attr2),
1645 get_target_module(Mod),
1647 ( get_attr(Var,Mod,TAttr) ->
1649 ( Mask /\ Pattern =:= Pattern ->
1650 'chr sbag_del_element'(Susps,Susp,NewSusps),
1652 NewMask is Mask /\ DelPattern,
1656 put_attr(Var,Mod,Attr1)
1659 put_attr(Var,Mod,Attr2)
1668 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1669 %-------------------------------------------------------------------------------
1670 %% generate_indexed_variables_body(+ConstraintSymbol,+ArgList,-Body,-VarList) is det.
1671 :- chr_constraint generate_indexed_variables_body/4.
1672 :- chr_option(mode,generate_indexed_variables_body(+,?,+,?)).
1673 %-------------------------------------------------------------------------------
1674 constraint_mode(F/A,ArgModes) \ generate_indexed_variables_body(F/A,Args,Body,Vars) <=>
1675 get_indexing_spec(F/A,Specs),
1676 ( chr_pp_flag(term_indexing,on) ->
1677 spectermvars(Specs,Args,F,A,Body,Vars)
1679 get_constraint_type_det(F/A,ArgTypes),
1680 create_indexed_variables_body(Args,ArgModes,ArgTypes,Vars,1,F/A,MaybeBody,N),
1681 ( MaybeBody == empty ->
1688 Term =.. [term|Args]
1690 Body = term_variables(Term,Vars)
1695 generate_indexed_variables_body(FA,_,_,_) <=>
1696 chr_error(internal,'generate_indexed_variables_body: missing mode info for ~w.\n',[FA]).
1697 %===============================================================================
1699 create_indexed_variables_body([],[],[],_,_,_,empty,0).
1700 create_indexed_variables_body([V|Vs],[Mode|Modes],[Type|Types],Vars,I,FA,Body,N) :-
1702 create_indexed_variables_body(Vs,Modes,Types,Tail,J,FA,RBody,M),
1704 is_indexed_argument(FA,I) ->
1705 ( atomic_type(Type) ->
1716 Continuation = true, Tail = []
1718 Continuation = RBody
1722 Body = term_variables(V,Vars)
1724 Body = (term_variables(V,Vars,Tail),RBody)
1728 ; Mode == (-), is_indexed_argument(FA,I) ->
1732 Body = (Vars = [V|Tail],RBody)
1740 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1742 spectermvars(Specs,Args,F,A,Goal,Vars) :-
1743 spectermvars(Args,1,Specs,F,A,Vars,[],Goal).
1745 spectermvars([],B,_,_,A,L,L,true) :- B > A, !.
1746 spectermvars([Arg|Args],I,Specs,F,A,L,T,Goal) :-
1747 Goal = (ArgGoal,RGoal),
1748 argspecs(Specs,I,TempArgSpecs,RSpecs),
1749 merge_argspecs(TempArgSpecs,ArgSpecs),
1750 arggoal(ArgSpecs,Arg,ArgGoal,L,L1),
1752 spectermvars(Args,J,RSpecs,F,A,L1,T,RGoal).
1754 argspecs([],_,[],[]).
1755 argspecs([[]|Rest],I,ArgSpecs,RestSpecs) :-
1756 argspecs(Rest,I,ArgSpecs,RestSpecs).
1757 argspecs([[specinfo(J,Spec,Args)|Specs]|Rest],I,ArgSpecs,RestSpecs) :-
1759 ArgSpecs = [specinfo(J,Spec,Args)|RArgSpecs],
1761 RRestSpecs = RestSpecs
1763 RestSpecs = [Specs|RRestSpecs]
1766 ArgSpecs = RArgSpecs,
1767 RestSpecs = [[specinfo(J,Spec,Args)|Specs]|RRestSpecs]
1769 argspecs(Rest,I,RArgSpecs,RRestSpecs).
1771 merge_argspecs(In,Out) :-
1773 merge_argspecs_(Sorted,Out).
1775 merge_argspecs_([],[]).
1776 merge_argspecs_([X],R) :- !, R = [X].
1777 merge_argspecs_([specinfo(I,F1,A1),specinfo(I,F2,A2)|Rest],R) :-
1778 ( (F1 == any ; F2 == any) ->
1779 merge_argspecs_([specinfo(I,any,[])|Rest],R)
1782 merge_argspecs_([specinfo(I,F1,A)|Rest],R)
1784 R = [specinfo(I,F1,A1)|RR],
1785 merge_argspecs_([specinfo(I,F2,A2)|Rest],RR)
1788 arggoal(List,Arg,Goal,L,T) :-
1792 ; List = [specinfo(_,any,_)] ->
1793 Goal = term_variables(Arg,L,T)
1801 arggoal_cases(List,Arg,L,T,Cases)
1804 arggoal_cases([],_,L,T,L=T).
1805 arggoal_cases([specinfo(_,FA,ArgSpecs)|Rest],Arg,L,T,Cases) :-
1808 ; ArgSpecs == [[]] ->
1811 Cases = (Case ; RCases),
1814 Case = (Arg = Term -> ArgsGoal),
1815 spectermvars(Args,1,ArgSpecs,F,A,L,T,ArgsGoal)
1817 arggoal_cases(Rest,Arg,L,T,RCases).
1818 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1820 generate_extra_clauses(Constraints,List) :-
1821 generate_activate_clauses(Constraints,List,Tail0),
1822 generate_remove_clauses(Constraints,Tail0,Tail1),
1823 generate_allocate_clauses(Constraints,Tail1,Tail2),
1824 generate_insert_constraint_internal_clauses(Constraints,Tail2,Tail3),
1825 generate_novel_production(Tail3,Tail4),
1826 generate_extend_history(Tail4,Tail5),
1827 generate_run_suspensions_clauses(Constraints,Tail5,Tail6),
1830 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
1831 % remove_constraint_internal/[1/3]
1833 generate_remove_clauses([],List,List).
1834 generate_remove_clauses([C|Cs],List,Tail) :-
1835 generate_remove_clause(C,List,List1),
1836 generate_remove_clauses(Cs,List1,Tail).
1838 remove_constraint_goal(Constraint,Susp,Agenda,DeleteNo,DeleteYes,Role,Goal) :-
1839 uses_state(Constraint,removed),
1840 ( chr_pp_flag(inline_insertremove,off) ->
1841 use_auxiliary_predicate(remove_constraint_internal,Constraint),
1842 Goal = ( DeleteGoal, ( Delete == yes -> DeleteYes ; DeleteNo) ),
1843 remove_constraint_atom(Constraint,Susp,Agenda,Delete,DeleteGoal)
1845 delay_phase_end(validate_store_type_assumptions,
1846 generate_remove_body(Constraint,Susp,Agenda,DeleteNo,DeleteYes,Role,Goal)
1850 remove_constraint_atom(Constraint,Susp,Agenda,Delete,Goal) :-
1851 make_name('$remove_constraint_internal_',Constraint,Name),
1852 ( chr_pp_flag(debugable,off), ( only_ground_indexed_arguments(Constraint) ; get_store_type(Constraint,var_assoc_store(_,_)) ) ->
1853 Goal =.. [Name, Susp,Delete]
1855 Goal =.. [Name,Susp,Agenda,Delete]
1858 generate_remove_clause(Constraint,List,Tail) :-
1859 ( is_used_auxiliary_predicate(remove_constraint_internal,Constraint) ->
1860 List = [RemoveClause|Tail],
1861 RemoveClause = (Head :- RemoveBody),
1862 remove_constraint_atom(Constraint,Susp,Agenda,Delete,Head),
1863 generate_remove_body(Constraint,Susp,Agenda,Delete = no,Delete = yes,active,RemoveBody)
1868 generate_remove_body(Constraint,Susp,Agenda,DeleteNo,DeleteYes,Role,RemoveBody) :-
1869 ( chr_pp_flag(debugable,off), ( only_ground_indexed_arguments(Constraint) ; get_store_type(Constraint,var_assoc_store(_,_))) ->
1871 get_update_suspension_field(Constraint,Susp,state,State,removed,GetState,GetStateValue0,UpdateState),
1872 if_used_state(Constraint,not_stored_yet,GetStateValue0,true,GetStateValue),
1873 if_used_state(Constraint,not_stored_yet,(State == not_stored_yet -> DeleteNo ; DeleteYes),DeleteYes,MaybeDelete)
1874 ; Role == partner ->
1875 get_update_suspension_field(Constraint,Susp,state,State,removed,GetState,_,UpdateState),
1876 GetStateValue = true,
1877 MaybeDelete = DeleteYes
1887 static_suspension_term(Constraint,Susp2),
1888 get_static_suspension_term_field(arguments,Constraint,Susp2,Args),
1889 generate_indexed_variables_body(Constraint,Args,IndexedVariablesBody,Agenda),
1890 ( chr_pp_flag(debugable,on) ->
1891 Constraint = Functor / _,
1892 get_static_suspension_term_field(functor,Constraint,Susp2,Functor)
1897 get_update_static_suspension_field(Constraint,Susp,Susp2,state,State,removed,GetStateValue0,UpdateState),
1898 if_used_state(Constraint,not_stored_yet,GetStateValue0,true,GetStateValue),
1899 if_used_state(Constraint,not_stored_yet,(State == not_stored_yet -> Agenda = [], DeleteNo ; IndexedVariablesBody, DeleteYes),(IndexedVariablesBody,DeleteYes),MaybeDelete)
1900 ; Role == partner ->
1901 get_update_static_suspension_field(Constraint,Susp,Susp2,state,State,removed,_,UpdateState),
1902 GetStateValue = true,
1903 MaybeDelete = (IndexedVariablesBody, DeleteYes)
1914 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
1915 % activate_constraint/4
1917 generate_activate_clauses([],List,List).
1918 generate_activate_clauses([C|Cs],List,Tail) :-
1919 generate_activate_clause(C,List,List1),
1920 generate_activate_clauses(Cs,List1,Tail).
1922 activate_constraint_goal(Constraint,StoreAction,Vars,Susp,Generation,Goal) :-
1923 ( chr_pp_flag(inline_insertremove,off) ->
1924 use_auxiliary_predicate(activate_constraint,Constraint),
1925 Goal = ( ActivateGoal , (Store == yes -> StoreAction ; true) ),
1926 activate_constraint_atom(Constraint,Store,Vars,Susp,Generation,ActivateGoal)
1928 delay_phase_end(validate_store_type_assumptions,
1929 activate_constraint_body(Constraint,StoreAction,true,Vars,Susp,Generation,Goal)
1933 activate_constraint_atom(Constraint,Store,Vars,Susp,Generation,Goal) :-
1934 make_name('$activate_constraint_',Constraint,Name),
1935 ( chr_pp_flag(debugable,off), only_ground_indexed_arguments(Constraint) ->
1936 Goal =.. [Name,Store, Susp]
1937 ; chr_pp_flag(debugable,off), may_trigger(Constraint), get_store_type(Constraint,var_assoc_store(_,_)) ->
1938 Goal =.. [Name,Store, Susp, Generation]
1939 ; chr_pp_flag(debugable,off), may_trigger(Constraint), get_store_type(Constraint,var_assoc_store(_,_)) ->
1940 Goal =.. [Name,Store, Vars, Susp, Generation]
1942 Goal =.. [Name,Store, Vars, Susp]
1945 generate_activate_clause(Constraint,List,Tail) :-
1946 ( is_used_auxiliary_predicate(activate_constraint,Constraint) ->
1947 List = [Clause|Tail],
1948 Clause = (Head :- Body),
1949 activate_constraint_atom(Constraint,Store,Vars,Susp,Generation,Head),
1950 activate_constraint_body(Constraint,Store = yes, Store = no,Vars,Susp,Generation,Body)
1955 activate_constraint_body(Constraint,StoreYes,StoreNo,Vars,Susp,Generation,Body) :-
1956 ( chr_pp_flag(debugable,off), may_trigger(Constraint), uses_field(Constraint,generation) ->
1957 get_update_suspension_field(Constraint,Susp,generation,Gen,Generation,GetGeneration,GetGenerationValue,UpdateGeneration),
1958 GenerationHandling = (GetGeneration, GetGenerationValue, Generation is Gen+1, UpdateGeneration)
1960 GenerationHandling = true
1962 get_update_suspension_field(Constraint,Susp,state,State,active,GetState,GetStateValue0,UpdateState),
1963 if_used_state(Constraint,not_stored_yet,GetStateValue0,true,GetStateValue),
1964 ( chr_pp_flag(debugable,off), ( only_ground_indexed_arguments(Constraint) ; get_store_type(Constraint,var_assoc_store(_,_))) ->
1965 if_used_state(Constraint,not_stored_yet,( State == not_stored_yet -> StoreYes ; StoreNo ),StoreNo,StoreVarsGoal)
1967 get_dynamic_suspension_term_field(arguments,Constraint,Susp,Arguments,ArgumentsGoal),
1968 generate_indexed_variables_body(Constraint,Arguments,IndexedVariablesBody,Vars),
1969 ( chr_pp_flag(guard_locks,off) ->
1972 NoneLocked = 'chr none_locked'( Vars)
1974 if_used_state(Constraint,not_stored_yet,
1975 ( State == not_stored_yet ->
1977 IndexedVariablesBody,
1984 % (Vars = [],StoreNo),StoreVarsGoal)
1985 StoreNo,StoreVarsGoal)
1995 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
1996 % allocate_constraint/4
1998 generate_allocate_clauses([],List,List).
1999 generate_allocate_clauses([C|Cs],List,Tail) :-
2000 generate_allocate_clause(C,List,List1),
2001 generate_allocate_clauses(Cs,List1,Tail).
2003 allocate_constraint_goal(Constraint,Susp,Args,Goal) :-
2004 uses_state(Constraint,not_stored_yet),
2005 ( chr_pp_flag(inline_insertremove,off) ->
2006 use_auxiliary_predicate(allocate_constraint,Constraint),
2007 allocate_constraint_atom(Constraint,Susp,Args,Goal)
2009 Goal = (Susp = Suspension, Goal0),
2010 delay_phase_end(validate_store_type_assumptions,
2011 allocate_constraint_body(Constraint,Suspension,Args,Goal0)
2015 allocate_constraint_atom(Constraint, Susp, Args,Goal) :-
2016 make_name('$allocate_constraint_',Constraint,Name),
2017 Goal =.. [Name,Susp|Args].
2019 generate_allocate_clause(Constraint,List,Tail) :-
2020 ( is_used_auxiliary_predicate(allocate_constraint,Constraint) ->
2021 List = [Clause|Tail],
2022 Clause = (Head :- Body),
2025 allocate_constraint_atom(Constraint,Susp,Args,Head),
2026 allocate_constraint_body(Constraint,Susp,Args,Body)
2031 allocate_constraint_body(Constraint,Susp,Args,Body) :-
2032 static_suspension_term(Constraint,Suspension),
2033 get_static_suspension_term_field(arguments,Constraint,Suspension,Args),
2034 ( chr_pp_flag(debugable,on) ->
2035 Constraint = Functor / _,
2036 get_static_suspension_term_field(functor,Constraint,Suspension,Functor)
2040 ( chr_pp_flag(debugable,on) ->
2041 ( may_trigger(Constraint) ->
2042 append(Args,[Susp],VarsSusp),
2043 build_head(F,A,[0],VarsSusp, ContinuationGoal),
2044 get_target_module(Mod),
2045 Continuation = Mod : ContinuationGoal
2049 Init = (Susp = Suspension),
2050 create_static_suspension_field(Constraint,Suspension,continuation,Continuation,CreateContinuation),
2051 create_static_suspension_field(Constraint,Suspension,generation,0,CreateGeneration)
2052 ; may_trigger(Constraint), uses_field(Constraint,generation) ->
2053 create_static_suspension_field(Constraint,Suspension,generation,0,CreateGeneration),
2054 Susp = Suspension, Init = true, CreateContinuation = true
2056 CreateGeneration = true, Susp = Suspension, Init = true, CreateContinuation = true
2058 ( uses_history(Constraint) ->
2059 create_static_suspension_field(Constraint,Suspension,history,t,CreateHistory)
2061 CreateHistory = true
2063 create_static_suspension_field(Constraint,Suspension,state,not_stored_yet,CreateState),
2064 ( has_suspension_field(Constraint,id) ->
2065 get_static_suspension_term_field(id,Constraint,Suspension,Id),
2066 GenID = 'chr gen_id'(Id)
2080 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2081 % insert_constraint_internal
2083 generate_insert_constraint_internal_clauses([],List,List).
2084 generate_insert_constraint_internal_clauses([C|Cs],List,Tail) :-
2085 generate_insert_constraint_internal_clause(C,List,List1),
2086 generate_insert_constraint_internal_clauses(Cs,List1,Tail).
2088 insert_constraint_internal_constraint_goal(Constraint, Vars, Suspension, Continuation, Args,Goal) :-
2089 ( chr_pp_flag(inline_insertremove,off) ->
2090 use_auxiliary_predicate(remove_constraint_internal,Constraint),
2091 insert_constraint_internal_constraint_atom(Constraint,Vars,Suspension,Continuation,Args,Goal)
2093 delay_phase_end(validate_store_type_assumptions,
2094 generate_insert_constraint_internal_body(Constraint,Suspension,Continuation,Args,Vars,Goal)
2099 insert_constraint_internal_constraint_atom(Constraint,Vars,Self,Closure,Args,Goal) :-
2100 insert_constraint_internal_constraint_name(Constraint,Name),
2101 ( chr_pp_flag(debugable,on) ->
2102 Goal =.. [Name, Vars, Self, Closure | Args]
2103 ; ( only_ground_indexed_arguments(Constraint) ; get_store_type(Constraint,var_assoc_store(_,_)))->
2104 Goal =.. [Name,Self | Args]
2106 Goal =.. [Name,Vars, Self | Args]
2109 insert_constraint_internal_constraint_name(Constraint,Name) :-
2110 make_name('$insert_constraint_internal_',Constraint,Name).
2112 generate_insert_constraint_internal_clause(Constraint,List,Tail) :-
2113 ( is_used_auxiliary_predicate(insert_constraint_internal,Constraint) ->
2114 List = [Clause|Tail],
2115 Clause = (Head :- Body),
2118 insert_constraint_internal_constraint_atom(Constraint, Vars, Suspension, Continuation,Args,Head),
2119 generate_insert_constraint_internal_body(Constraint,Suspension,Continuation,Args,Vars,Body)
2125 generate_insert_constraint_internal_body(Constraint,Susp,Continuation,Args,Vars,Body) :-
2126 static_suspension_term(Constraint,Suspension),
2127 create_static_suspension_field(Constraint,Suspension,state,active,CreateState),
2128 ( chr_pp_flag(debugable,on) ->
2129 get_static_suspension_term_field(continuation,Constraint,Suspension,Continuation),
2130 create_static_suspension_field(Constraint,Suspension,generation,0,CreateGeneration)
2131 ; may_trigger(Constraint), uses_field(Constraint,generation) ->
2132 create_static_suspension_field(Constraint,Suspension,generation,0,CreateGeneration)
2134 CreateGeneration = true
2136 ( chr_pp_flag(debugable,on) ->
2137 Constraint = Functor / _,
2138 get_static_suspension_term_field(functor,Constraint,Suspension,Functor)
2142 ( uses_history(Constraint) ->
2143 create_static_suspension_field(Constraint,Suspension,history,t,CreateHistory)
2145 CreateHistory = true
2147 get_static_suspension_term_field(arguments,Constraint,Suspension,Args),
2148 List = [Clause|Tail],
2149 ( chr_pp_flag(debugable,off), ( only_ground_indexed_arguments(Constraint) ; get_store_type(Constraint,var_assoc_store(_,_)))->
2150 suspension_term_base_fields(Constraint,BaseFields),
2151 ( has_suspension_field(Constraint,id) ->
2152 get_static_suspension_term_field(id,Constraint,Suspension,Id),
2153 GenID = 'chr gen_id'(Id)
2166 ( has_suspension_field(Constraint,id) ->
2167 get_static_suspension_term_field(id,Constraint,Suspension,Id),
2168 GenID = 'chr gen_id'(Id)
2172 generate_indexed_variables_body(Constraint,Args,IndexedVariablesBody,Vars),
2173 ( chr_pp_flag(guard_locks,off) ->
2176 NoneLocked = 'chr none_locked'( Vars)
2181 IndexedVariablesBody,
2190 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2191 % novel_production/2
2193 generate_novel_production(List,Tail) :-
2194 ( is_used_auxiliary_predicate(novel_production) ->
2195 List = [Clause|Tail],
2198 '$novel_production'( Self, Tuple) :-
2199 % arg( 3, Self, Ref), % ARGXXX
2200 % 'chr get_mutable'( History, Ref),
2201 arg( 3, Self, History), % ARGXXX
2202 ( hprolog:get_ds( Tuple, History, _) ->
2212 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2215 generate_extend_history(List,Tail) :-
2216 ( is_used_auxiliary_predicate(extend_history) ->
2217 List = [Clause|Tail],
2220 '$extend_history'( Self, Tuple) :-
2221 % arg( 3, Self, Ref), % ARGXXX
2222 % 'chr get_mutable'( History, Ref),
2223 arg( 3, Self, History), % ARGXXX
2224 hprolog:put_ds( Tuple, History, x, NewHistory),
2225 setarg( 3, Self, NewHistory) % ARGXXX
2231 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2234 generate_run_suspensions_clauses([],List,List).
2235 generate_run_suspensions_clauses([C|Cs],List,Tail) :-
2236 generate_run_suspensions_clause(C,List,List1),
2237 generate_run_suspensions_clauses(Cs,List1,Tail).
2239 run_suspensions_goal(Constraint,Suspensions,Goal) :-
2240 make_name('$run_suspensions_',Constraint,Name),
2241 Goal =.. [Name,Suspensions].
2243 generate_run_suspensions_clause(Constraint,List,Tail) :-
2244 ( is_used_auxiliary_predicate(run_suspensions,Constraint) ->
2245 List = [Clause1,Clause2|Tail],
2246 run_suspensions_goal(Constraint,[],Clause1),
2247 ( chr_pp_flag(debugable,on) ->
2248 run_suspensions_goal(Constraint,[Suspension|Suspensions],Clause2Head),
2249 get_update_suspension_field(Constraint,Suspension,state,State,triggered,GetState,GetStateValue,UpdateState),
2250 get_update_suspension_field(Constraint,Suspension,state,Post,active,GetPost,GetPostValue,UpdatePost),
2251 get_update_suspension_field(Constraint,Suspension,generation,Gen,Generation,GetGeneration,GetGenerationValue,UpdateGeneration),
2252 get_dynamic_suspension_term_field(continuation,Constraint,Suspension,Continuation,GetContinuation),
2253 run_suspensions_goal(Constraint,Suspensions,Clause2Recursion),
2263 Generation is Gen+1,
2267 'chr debug_event'(wake(Suspension)),
2270 'chr debug_event'(fail(Suspension)), !,
2274 'chr debug_event'(exit(Suspension))
2276 'chr debug_event'(redo(Suspension)),
2281 ( Post==triggered ->
2282 UpdatePost % catching constraints that did not do anything
2292 run_suspensions_goal(Constraint,[Suspension|Suspensions],Clause2Head),
2293 static_suspension_term(Constraint,SuspensionTerm),
2294 get_static_suspension_term_field(arguments,Constraint,SuspensionTerm,Arguments),
2295 append(Arguments,[Suspension],VarsSusp),
2296 make_suspension_continuation_goal(Constraint,VarsSusp,Continuation),
2297 run_suspensions_goal(Constraint,Suspensions,Clause2Recursion),
2298 ( uses_field(Constraint,generation) ->
2299 get_update_static_suspension_field(Constraint,Suspension,SuspensionTerm,generation,Gen,Generation,GetGeneration,UpdateGeneration),
2300 GenerationHandling = ( GetGeneration, Generation is Gen+1, UpdateGeneration)
2302 GenerationHandling = true
2304 get_update_static_suspension_field(Constraint,Suspension,SuspensionTerm,state,State,triggered,GetState,UpdateState),
2305 get_update_static_suspension_field(Constraint,Suspension,SuspensionTerm,state,Post,active,GetPostState,UpdatePostState),
2306 if_used_state(Constraint,removed,
2309 -> ReactivateConstraint
2311 ),ReactivateConstraint,CondReactivate),
2312 ReactivateConstraint =
2318 ( Post==triggered ->
2319 UpdatePostState % catching constraints that did not do anything
2327 Suspension = SuspensionTerm,
2336 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2338 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2339 generate_attach_increment(Clauses) :-
2340 get_max_constraint_index(N),
2341 ( is_used_auxiliary_predicate(attach_increment), N > 0 ->
2342 Clauses = [Clause1,Clause2],
2343 generate_attach_increment_empty(Clause1),
2345 generate_attach_increment_one(Clause2)
2347 generate_attach_increment_many(N,Clause2)
2353 generate_attach_increment_empty((attach_increment([],_) :- true)).
2355 generate_attach_increment_one(Clause) :-
2356 Head = attach_increment([Var|Vars],Susps),
2357 get_target_module(Mod),
2358 ( chr_pp_flag(guard_locks,off) ->
2361 NotLocked = 'chr not_locked'( Var)
2366 ( get_attr(Var,Mod,VarSusps) ->
2367 sort(VarSusps,SortedVarSusps),
2368 'chr merge_attributes'(Susps,SortedVarSusps,MergedSusps),
2369 put_attr(Var,Mod,MergedSusps)
2371 put_attr(Var,Mod,Susps)
2373 attach_increment(Vars,Susps)
2375 Clause = (Head :- Body).
2377 generate_attach_increment_many(N,Clause) :-
2378 make_attr(N,Mask,SuspsList,Attr),
2379 make_attr(N,OtherMask,OtherSuspsList,OtherAttr),
2380 Head = attach_increment([Var|Vars],Attr),
2381 bagof(G,X ^ Y ^ SY ^ M ^ (member2(SuspsList,OtherSuspsList,X-Y),G = (sort(Y,SY),'chr merge_attributes'(X,SY,M))),Gs),
2382 list2conj(Gs,SortGoals),
2383 bagof(MS,A ^ B ^ C ^ member((A,'chr merge_attributes'(B,C,MS)),Gs), MergedSuspsList),
2384 make_attr(N,MergedMask,MergedSuspsList,NewAttr),
2385 get_target_module(Mod),
2386 ( chr_pp_flag(guard_locks,off) ->
2389 NotLocked = 'chr not_locked'( Var)
2394 ( get_attr(Var,Mod,TOtherAttr) ->
2395 TOtherAttr = OtherAttr,
2397 MergedMask is Mask \/ OtherMask,
2398 put_attr(Var,Mod,NewAttr)
2400 put_attr(Var,Mod,Attr)
2402 attach_increment(Vars,Attr)
2404 Clause = (Head :- Body).
2407 generate_attr_unify_hook(Clauses) :-
2408 get_max_constraint_index(N),
2414 generate_attr_unify_hook_one(Clause)
2416 generate_attr_unify_hook_many(N,Clause)
2420 generate_attr_unify_hook_one(Clause) :-
2421 Head = attr_unify_hook(Susps,Other),
2422 get_target_module(Mod),
2423 get_indexed_constraint(1,C),
2424 ( get_store_type(C,default) ->
2425 make_run_suspensions(NewSusps,SortedSusps,WakeNewSusps),
2426 make_run_suspensions(SortedSusps,SortedSusps,WakeSusps),
2427 ( atomic_types_suspended_constraint(C) ->
2429 SortedSusps = Susps,
2431 SortedOtherSusps = OtherSusps,
2432 MergeGoal = (append(Susps,OtherSusps,List), sort(List,NewSusps)),
2435 SortGoal1 = sort(Susps, SortedSusps),
2436 SortGoal2 = sort(OtherSusps,SortedOtherSusps),
2437 MergeGoal = 'chr merge_attributes'(SortedSusps,SortedOtherSusps,NewSusps),
2438 use_auxiliary_predicate(attach_increment),
2440 ( compound(Other) ->
2441 term_variables(Other,OtherVars),
2442 attach_increment(OtherVars, SortedSusps)
2451 ( get_attr(Other,Mod,OtherSusps) ->
2454 put_attr(Other,Mod,NewSusps),
2457 put_attr(Other,Mod,SortedSusps),
2465 Clause = (Head :- Body)
2466 ; get_store_type(C,var_assoc_store(VarIndex,KeyIndex)) ->
2467 make_run_suspensions(List,List,WakeNewSusps),
2468 MergeGoal = (merge_into_assoc_store(Susps,OtherSusps,List)),
2470 ( get_attr(Other,Mod,OtherSusps) ->
2474 put_attr(Other,Mod,Susps)
2476 Clause = (Head :- Body)
2480 generate_attr_unify_hook_many(N,Clause) :-
2481 make_attr(N,Mask,SuspsList,Attr),
2482 make_attr(N,OtherMask,OtherSuspsList,OtherAttr),
2483 bagof(Sort,A ^ B ^ ( member(A,SuspsList) , Sort = sort(A,B) ) , SortGoalList),
2484 list2conj(SortGoalList,SortGoals),
2485 bagof(B, A ^ member(sort(A,B),SortGoalList), SortedSuspsList),
2486 bagof(C, D ^ E ^ F ^ G ^ (member2(SortedSuspsList,OtherSuspsList,D-E),
2488 'chr merge_attributes'(D,F,G)) ),
2490 bagof(G, D ^ F ^ H ^ member((H,'chr merge_attributes'(D,F,G)),SortMergeGoalList) , MergedSuspsList),
2491 list2conj(SortMergeGoalList,SortMergeGoals),
2492 make_attr(N,MergedMask,MergedSuspsList,MergedAttr),
2493 make_attr(N,Mask,SortedSuspsList,SortedAttr),
2494 Head = attr_unify_hook(Attr,Other),
2495 get_target_module(Mod),
2496 make_run_suspensions_loop(MergedSuspsList,SortedSuspsList,WakeMergedSusps),
2497 make_run_suspensions_loop(SortedSuspsList,SortedSuspsList,WakeSortedSusps),
2498 ( forall((between(1,N,Index), get_indexed_constraint(Index,Constraint)),atomic_types_suspended_constraint(Constraint)) ->
2501 use_auxiliary_predicate(attach_increment),
2503 ( compound(Other) ->
2504 term_variables(Other,OtherVars),
2505 attach_increment(OtherVars,SortedAttr)
2514 ( get_attr(Other,Mod,TOtherAttr) ->
2515 TOtherAttr = OtherAttr,
2517 MergedMask is Mask \/ OtherMask,
2518 put_attr(Other,Mod,MergedAttr),
2521 put_attr(Other,Mod,SortedAttr),
2529 Clause = (Head :- Body).
2531 make_run_suspensions(AllSusps,OneSusps,Goal) :-
2532 make_run_suspensions(1,AllSusps,OneSusps,Goal).
2534 make_run_suspensions(Index,AllSusps,OneSusps,Goal) :-
2535 ( get_indexed_constraint(Index,C), may_trigger(C) ->
2536 use_auxiliary_predicate(run_suspensions,C),
2537 ( wakes_partially(C) ->
2538 run_suspensions_goal(C,OneSusps,Goal)
2540 run_suspensions_goal(C,AllSusps,Goal)
2546 make_run_suspensions_loop(AllSuspsList,OneSuspsList,Goal) :-
2547 make_run_suspensions_loop(AllSuspsList,OneSuspsList,1,Goal).
2549 make_run_suspensions_loop([],[],_,true).
2550 make_run_suspensions_loop([AllSusps|AllSuspsList],[OneSusps|OneSuspsList],I,(Goal,Goals)) :-
2551 make_run_suspensions(I,AllSusps,OneSusps,Goal),
2553 make_run_suspensions_loop(AllSuspsList,OneSuspsList,J,Goals).
2555 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2556 % $insert_in_store_F/A
2557 % $delete_from_store_F/A
2559 generate_insert_delete_constraints([],[]).
2560 generate_insert_delete_constraints([FA|Rest],Clauses) :-
2562 generate_insert_delete_constraint(FA,Clauses,RestClauses)
2564 Clauses = RestClauses
2566 generate_insert_delete_constraints(Rest,RestClauses).
2568 generate_insert_delete_constraint(FA,Clauses,RestClauses) :-
2569 insert_constraint_clause(FA,Clauses,RestClauses1),
2570 delete_constraint_clause(FA,RestClauses1,RestClauses).
2572 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
2575 insert_constraint_goal(FA,Susp,Vars,Goal) :-
2576 ( chr_pp_flag(inline_insertremove,off) ->
2577 use_auxiliary_predicate(insert_in_store,FA),
2578 insert_constraint_atom(FA,Susp,Goal)
2580 delay_phase_end(validate_store_type_assumptions,
2581 ( insert_constraint_body(FA,Susp,UsedVars,Goal),
2582 insert_constraint_direct_used_vars(UsedVars,Vars)
2587 insert_constraint_direct_used_vars([],_).
2588 insert_constraint_direct_used_vars([Index-Var|Rest],Vars) :-
2589 nth1(Index,Vars,Var),
2590 insert_constraint_direct_used_vars(Rest,Vars).
2592 insert_constraint_atom(FA,Susp,Call) :-
2593 make_name('$insert_in_store_',FA,Functor),
2594 Call =.. [Functor,Susp].
2596 insert_constraint_clause(C,Clauses,RestClauses) :-
2597 ( is_used_auxiliary_predicate(insert_in_store,C) ->
2598 Clauses = [Clause|RestClauses],
2599 Clause = (Head :- InsertCounterInc,VarsBody,Body),
2600 insert_constraint_atom(C,Susp,Head),
2601 insert_constraint_body(C,Susp,UsedVars,Body),
2602 insert_constraint_used_vars(UsedVars,C,Susp,VarsBody),
2603 ( chr_pp_flag(store_counter,on) ->
2604 InsertCounterInc = '$insert_counter_inc'
2606 InsertCounterInc = true
2609 Clauses = RestClauses
2612 insert_constraint_used_vars([],_,_,true).
2613 insert_constraint_used_vars([Index-Var|Rest],C,Susp,(Goal,Goals)) :-
2614 get_dynamic_suspension_term_field(argument(Index),C,Susp,Var,Goal),
2615 insert_constraint_used_vars(Rest,C,Susp,Goals).
2617 insert_constraint_body(C,Susp,UsedVars,Body) :-
2618 get_store_type(C,StoreType),
2619 insert_constraint_body(StoreType,C,Susp,UsedVars,Body).
2621 insert_constraint_body(default,C,Susp,[],Body) :-
2622 global_list_store_name(C,StoreName),
2623 make_get_store_goal(StoreName,Store,GetStoreGoal),
2624 make_update_store_goal(StoreName,Cell,UpdateStoreGoal),
2625 ( chr_pp_flag(debugable,on) ->
2626 Cell = [Susp|Store],
2633 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,Cell,SetGoal),
2637 Cell = [Susp|Store],
2639 ( Store = [NextSusp|_] ->
2646 % get_target_module(Mod),
2647 % get_max_constraint_index(Total),
2649 % generate_attach_body_1(C,Store,Susp,AttachBody)
2651 % generate_attach_body_n(C,Store,Susp,AttachBody)
2655 % 'chr default_store'(Store),
2658 insert_constraint_body(multi_inthash(Indexes),C,Susp,[],Body) :-
2659 generate_multi_inthash_insert_constraint_bodies(Indexes,C,Susp,Body).
2660 insert_constraint_body(multi_hash(Indexes),C,Susp,MixedUsedVars,Body) :-
2661 generate_multi_hash_insert_constraint_bodies(Indexes,C,Susp,Body,MixedUsedVars),
2662 sort_out_used_vars(MixedUsedVars,UsedVars).
2663 insert_constraint_body(global_ground,C,Susp,[],Body) :-
2664 global_ground_store_name(C,StoreName),
2665 make_get_store_goal(StoreName,Store,GetStoreGoal),
2666 make_update_store_goal(StoreName,Cell,UpdateStoreGoal),
2667 ( chr_pp_flag(debugable,on) ->
2668 Cell = [Susp|Store],
2675 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,Cell,SetGoal),
2679 Cell = [Susp|Store],
2681 ( Store = [NextSusp|_] ->
2688 % global_ground_store_name(C,StoreName),
2689 % make_get_store_goal(StoreName,Store,GetStoreGoal),
2690 % make_update_store_goal(StoreName,[Susp|Store],UpdateStoreGoal),
2693 % GetStoreGoal, % nb_getval(StoreName,Store),
2694 % UpdateStoreGoal % b_setval(StoreName,[Susp|Store])
2696 insert_constraint_body(var_assoc_store(VarIndex,AssocIndex),C,Susp,[VarIndex-Variable,AssocIndex-Key],Body) :-
2697 % TODO: generalize to more than one !!!
2698 get_target_module(Module),
2699 Body = ( get_attr(Variable,Module,AssocStore) ->
2700 insert_assoc_store(AssocStore,Key,Susp)
2702 new_assoc_store(AssocStore),
2703 put_attr(Variable,Module,AssocStore),
2704 insert_assoc_store(AssocStore,Key,Susp)
2707 insert_constraint_body(global_singleton,C,Susp,[],Body) :-
2708 global_singleton_store_name(C,StoreName),
2709 make_update_store_goal(StoreName,Susp,UpdateStoreGoal),
2714 insert_constraint_body(multi_store(StoreTypes),C,Susp,UsedVars,Body) :-
2715 find_with_var_identity(
2719 member(ST,StoreTypes),
2720 chr_translate:insert_constraint_body(ST,C,Susp,UV,B)
2724 once(pairup(Bodies,NestedUsedVars,BodiesUsedVars)),
2725 list2conj(Bodies,Body),
2726 sort_out_used_vars(NestedUsedVars,UsedVars).
2727 insert_constraint_body(identifier_store(Index),C,Susp,UsedVars,Body) :-
2728 UsedVars = [Index-Var],
2729 get_identifier_size(ISize),
2730 functor(Struct,struct,ISize),
2731 get_identifier_index(C,Index,IIndex),
2732 arg(IIndex,Struct,Susps),
2733 Body = (Var = Struct, setarg(IIndex,Var,[Susp|Susps])).
2734 insert_constraint_body(type_indexed_identifier_store(Index,IndexType),C,Susp,UsedVars,Body) :-
2735 UsedVars = [Index-Var],
2736 type_indexed_identifier_structure(IndexType,Struct),
2737 get_type_indexed_identifier_index(IndexType,C,Index,IIndex),
2738 arg(IIndex,Struct,Susps),
2739 Body = (Var = Struct, setarg(IIndex,Var,[Susp|Susps])).
2741 sort_out_used_vars(NestedUsedVars,UsedVars) :-
2742 flatten(NestedUsedVars,FlatUsedVars),
2743 sort(FlatUsedVars,SortedFlatUsedVars),
2744 sort_out_used_vars1(SortedFlatUsedVars,UsedVars).
2746 sort_out_used_vars1([],[]).
2747 sort_out_used_vars1([I-V],L) :- !, L = [I-V].
2748 sort_out_used_vars1([I-X,J-Y|R],L) :-
2751 sort_out_used_vars1([I-X|R],L)
2754 sort_out_used_vars1([J-Y|R],T)
2757 generate_multi_inthash_insert_constraint_bodies([],_,_,true).
2758 generate_multi_inthash_insert_constraint_bodies([Index|Indexes],FA,Susp,(Body,Bodies)) :-
2759 multi_hash_store_name(FA,Index,StoreName),
2760 multi_hash_key(FA,Index,Susp,KeyBody,Key),
2764 nb_getval(StoreName,Store),
2765 insert_iht(Store,Key,Susp)
2767 generate_multi_inthash_insert_constraint_bodies(Indexes,FA,Susp,Bodies).
2769 generate_multi_hash_insert_constraint_bodies([],_,_,true,[]).
2770 generate_multi_hash_insert_constraint_bodies([Index|Indexes],FA,Susp,(Body,Bodies),[UsedVars|MoreUsedVars]) :-
2771 multi_hash_store_name(FA,Index,StoreName),
2772 multi_hash_key_direct(FA,Index,Susp,Key,UsedVars),
2773 make_get_store_goal(StoreName,Store,GetStoreGoal),
2777 insert_ht(Store,Key,Susp)
2779 generate_multi_hash_insert_constraint_bodies(Indexes,FA,Susp,Bodies,MoreUsedVars).
2781 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
2784 delete_constraint_clause(C,Clauses,RestClauses) :-
2785 ( is_used_auxiliary_predicate(delete_from_store,C) ->
2786 Clauses = [Clause|RestClauses],
2787 Clause = (Head :- Body),
2788 delete_constraint_atom(C,Susp,Head),
2791 delete_constraint_body(C,Head,Susp,[],Body)
2793 Clauses = RestClauses
2796 delete_constraint_goal(Head,Susp,VarDict,Goal) :-
2799 ( chr_pp_flag(inline_insertremove,off) ->
2800 use_auxiliary_predicate(delete_from_store,C),
2801 delete_constraint_atom(C,Susp,Goal)
2803 delay_phase_end(validate_store_type_assumptions, delete_constraint_body(C,Head,Susp,VarDict,Goal))
2806 delete_constraint_atom(C,Susp,Atom) :-
2807 make_name('$delete_from_store_',C,Functor),
2808 Atom =.. [Functor,Susp].
2811 delete_constraint_body(C,Head,Susp,VarDict,Body) :-
2812 Body = (CounterBody,DeleteBody),
2813 ( chr_pp_flag(store_counter,on) ->
2814 CounterBody = '$delete_counter_inc'
2818 get_store_type(C,StoreType),
2819 delete_constraint_body(StoreType,C,Head,Susp,VarDict,DeleteBody).
2821 delete_constraint_body(default,C,_,Susp,_,Body) :-
2822 ( chr_pp_flag(debugable,on) ->
2823 global_list_store_name(C,StoreName),
2824 make_get_store_goal(StoreName,Store,GetStoreGoal),
2825 make_update_store_goal(StoreName,NStore,UpdateStoreGoal),
2828 GetStoreGoal, % nb_getval(StoreName,Store),
2829 'chr sbag_del_element'(Store,Susp,NStore),
2830 UpdateStoreGoal % b_setval(StoreName,NStore)
2833 get_dynamic_suspension_term_field(global_list_prev,C,Susp,PredCell,GetGoal),
2834 global_list_store_name(C,StoreName),
2835 make_get_store_goal(StoreName,Store,GetStoreGoal),
2836 make_update_store_goal(StoreName,Tail,UpdateStoreGoal),
2837 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,_,SetGoal1),
2838 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,PredCell,SetGoal2),
2843 GetStoreGoal, % nb_getval(StoreName,Store),
2846 ( Tail = [NextSusp|_] ->
2852 PredCell = [_,_|Tail],
2853 setarg(2,PredCell,Tail),
2854 ( Tail = [NextSusp|_] ->
2862 % get_target_module(Mod),
2863 % get_max_constraint_index(Total),
2865 % generate_detach_body_1(C,Store,Susp,DetachBody),
2868 % 'chr default_store'(Store),
2872 % generate_detach_body_n(C,Store,Susp,DetachBody),
2875 % 'chr default_store'(Store),
2879 delete_constraint_body(multi_inthash(Indexes),C,_,Susp,_,Body) :-
2880 generate_multi_inthash_delete_constraint_bodies(Indexes,C,Susp,Body).
2881 delete_constraint_body(multi_hash(Indexes),C,Head,Susp,VarDict,Body) :-
2882 generate_multi_hash_delete_constraint_bodies(Indexes,C,Head,Susp,VarDict,Body).
2883 delete_constraint_body(global_ground,C,_,Susp,_,Body) :-
2884 ( chr_pp_flag(debugable,on) ->
2885 global_ground_store_name(C,StoreName),
2886 make_get_store_goal(StoreName,Store,GetStoreGoal),
2887 make_update_store_goal(StoreName,NStore,UpdateStoreGoal),
2890 GetStoreGoal, % nb_getval(StoreName,Store),
2891 'chr sbag_del_element'(Store,Susp,NStore),
2892 UpdateStoreGoal % b_setval(StoreName,NStore)
2895 get_dynamic_suspension_term_field(global_list_prev,C,Susp,PredCell,GetGoal),
2896 global_ground_store_name(C,StoreName),
2897 make_get_store_goal(StoreName,Store,GetStoreGoal),
2898 make_update_store_goal(StoreName,Tail,UpdateStoreGoal),
2899 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,_,SetGoal1),
2900 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,PredCell,SetGoal2),
2905 GetStoreGoal, % nb_getval(StoreName,Store),
2908 ( Tail = [NextSusp|_] ->
2914 PredCell = [_,_|Tail],
2915 setarg(2,PredCell,Tail),
2916 ( Tail = [NextSusp|_] ->
2924 % global_ground_store_name(C,StoreName),
2925 % make_get_store_goal(StoreName,Store,GetStoreGoal),
2926 % make_update_store_goal(StoreName,NStore,UpdateStoreGoal),
2929 % GetStoreGoal, % nb_getval(StoreName,Store),
2930 % 'chr sbag_del_element'(Store,Susp,NStore),
2931 % UpdateStoreGoal % b_setval(StoreName,NStore)
2933 delete_constraint_body(var_assoc_store(VarIndex,AssocIndex),C,_,Susp,_,Body) :-
2934 get_target_module(Module),
2935 get_dynamic_suspension_term_field(argument(VarIndex),C,Susp,Variable,VariableGoal),
2936 get_dynamic_suspension_term_field(argument(AssocIndex),C,Susp,Key,KeyGoal),
2939 get_attr(Variable,Module,AssocStore),
2941 delete_assoc_store(AssocStore,Key,Susp)
2943 delete_constraint_body(global_singleton,C,_,_Susp,_,Body) :-
2944 global_singleton_store_name(C,StoreName),
2945 make_update_store_goal(StoreName,[],UpdateStoreGoal),
2948 UpdateStoreGoal % b_setval(StoreName,[])
2950 delete_constraint_body(multi_store(StoreTypes),C,Head,Susp,VarDict,Body) :-
2951 find_with_var_identity(
2953 [Susp/VarDict/Head],
2955 member(ST,StoreTypes),
2956 chr_translate:delete_constraint_body(ST,C,Head,Susp,VarDict,B)
2960 list2conj(Bodies,Body).
2961 delete_constraint_body(identifier_store(Index),C,Head,Susp,VarDict,Body) :-
2962 get_suspension_argument_possibly_in_scope(Head,Index,VarDict,Susp,Variable,VariableGoal),
2963 get_identifier_size(ISize),
2964 functor(Struct,struct,ISize),
2965 get_identifier_index(C,Index,IIndex),
2966 arg(IIndex,Struct,Susps),
2970 'chr sbag_del_element'(Susps,Susp,NSusps),
2971 setarg(IIndex,Variable,NSusps)
2973 delete_constraint_body(type_indexed_identifier_store(Index,IndexType),C,Head,Susp,VarDict,Body) :-
2974 get_suspension_argument_possibly_in_scope(Head,Index,VarDict,Susp,Variable,VariableGoal),
2975 type_indexed_identifier_structure(IndexType,Struct),
2976 get_type_indexed_identifier_index(IndexType,C,Index,IIndex),
2977 arg(IIndex,Struct,Susps),
2981 'chr sbag_del_element'(Susps,Susp,NSusps),
2982 setarg(IIndex,Variable,NSusps)
2985 generate_multi_inthash_delete_constraint_bodies([],_,_,true).
2986 generate_multi_inthash_delete_constraint_bodies([Index|Indexes],FA,Susp,(Body,Bodies)) :-
2987 multi_hash_store_name(FA,Index,StoreName),
2988 multi_hash_key(FA,Index,Susp,KeyBody,Key),
2992 nb_getval(StoreName,Store),
2993 delete_iht(Store,Key,Susp)
2995 generate_multi_inthash_delete_constraint_bodies(Indexes,FA,Susp,Bodies).
2996 generate_multi_hash_delete_constraint_bodies([],_,_,_,_,true).
2997 generate_multi_hash_delete_constraint_bodies([Index|Indexes],C,Head,Susp,VarDict,(Body,Bodies)) :-
2998 multi_hash_store_name(C,Index,StoreName),
2999 multi_hash_key(C,Head,Index,Susp,VarDict,KeyBody,Key),
3000 make_get_store_goal(StoreName,Store,GetStoreGoal),
3004 GetStoreGoal, % nb_getval(StoreName,Store),
3005 delete_ht(Store,Key,Susp)
3007 generate_multi_hash_delete_constraint_bodies(Indexes,FA,Head,Susp,VarDict,Bodies).
3009 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3012 module_initializer/1,
3013 module_initializers/1.
3015 module_initializers(G), module_initializer(Initializer) <=>
3016 G = (Initializer,Initializers),
3017 module_initializers(Initializers).
3019 module_initializers(G) <=>
3022 generate_attach_code(Constraints,[Enumerate|L]) :-
3023 enumerate_stores_code(Constraints,Enumerate),
3024 generate_attach_code(Constraints,L,T),
3025 module_initializers(Initializers),
3026 prolog_global_variables_code(PrologGlobalVariables),
3027 T = [('$chr_initialization' :- Initializers),(:- '$chr_initialization')|PrologGlobalVariables].
3029 generate_attach_code([],L,L).
3030 generate_attach_code([C|Cs],L,T) :-
3031 get_store_type(C,StoreType),
3032 generate_attach_code(StoreType,C,L,L1),
3033 generate_attach_code(Cs,L1,T).
3035 generate_attach_code(default,C,L,T) :-
3036 global_list_store_initialisation(C,L,T).
3037 generate_attach_code(multi_inthash(Indexes),C,L,T) :-
3038 multi_inthash_store_initialisations(Indexes,C,L,L1),
3039 multi_inthash_via_lookups(Indexes,C,L1,T).
3040 generate_attach_code(multi_hash(Indexes),C,L,T) :-
3041 multi_hash_store_initialisations(Indexes,C,L,L1),
3042 multi_hash_via_lookups(Indexes,C,L1,T).
3043 generate_attach_code(global_ground,C,L,T) :-
3044 global_ground_store_initialisation(C,L,T).
3045 generate_attach_code(var_assoc_store(_,_),_,L,L) :-
3046 use_auxiliary_module(chr_assoc_store).
3047 generate_attach_code(global_singleton,C,L,T) :-
3048 global_singleton_store_initialisation(C,L,T).
3049 generate_attach_code(multi_store(StoreTypes),C,L,T) :-
3050 multi_store_generate_attach_code(StoreTypes,C,L,T).
3051 generate_attach_code(identifier_store(Index),C,L,T) :-
3052 get_identifier_index(C,Index,IIndex),
3054 get_identifier_size(ISize),
3055 functor(Struct,struct,ISize),
3056 Struct =.. [_,Label|Stores],
3057 set_elems(Stores,[]),
3058 Clause1 = new_identifier(Label,Struct),
3059 functor(Struct2,struct,ISize),
3060 arg(1,Struct2,Label2),
3062 ( user:portray(Struct2) :-
3067 functor(Struct3,struct,ISize),
3068 arg(1,Struct3,Label3),
3069 Clause3 = identifier_label(Struct3,Label3),
3070 L = [Clause1,Clause2,Clause3|T]
3074 generate_attach_code(type_indexed_identifier_store(Index,IndexType),C,L,T) :-
3075 get_type_indexed_identifier_index(IndexType,C,Index,IIndex),
3077 identifier_store_initialization(IndexType,L,L1),
3078 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3079 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3080 get_type_indexed_identifier_size(IndexType,ISize),
3081 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3082 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3083 type_indexed_identifier_structure(IndexType,Struct),
3084 Struct =.. [_,Label|Stores],
3085 set_elems(Stores,[]),
3086 type_indexed_identifier_name(IndexType,new_identifier,Name1),
3087 Clause1 =.. [Name1,Label,Struct],
3088 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3089 Goal1 =.. [Name1,Label1b,S1b],
3090 type_indexed_identifier_structure(IndexType,Struct1b),
3091 Struct1b =.. [_,Label1b|Stores1b],
3092 set_elems(Stores1b,[]),
3093 Expansion1 = (S1b = Struct1b),
3094 Clause1b = user:goal_expansion(Goal1,Expansion1),
3095 writeln(Clause1-Clause1b),
3096 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3097 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3098 type_indexed_identifier_structure(IndexType,Struct2),
3099 arg(1,Struct2,Label2),
3101 ( user:portray(Struct2) :-
3106 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3107 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3108 type_indexed_identifier_structure(IndexType,Struct3),
3109 arg(1,Struct3,Label3),
3110 type_indexed_identifier_name(IndexType,identifier_label,Name3),
3111 Clause3 =.. [Name3,Struct3,Label3],
3112 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3113 Goal3b =.. [Name3,S3b,L3b],
3114 type_indexed_identifier_structure(IndexType,Struct3b),
3115 arg(1,Struct3b,L3b),
3116 Expansion3b = (S3 = Struct3b),
3117 Clause3b = ( user:goal_expansion(Goal3b,Expansion3b) :- writeln(expanding)),
3118 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3119 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3120 identifier_store_name(IndexType,GlobalVariable),
3121 lookup_identifier_atom(IndexType,X,IX,LookupAtom),
3122 type_indexed_identifier_name(IndexType,new_identifier,NewIdentifierFunctor),
3123 NewIdentifierGoal =.. [NewIdentifierFunctor,X,IX],
3126 nb_getval(GlobalVariable,HT),
3127 ( lookup_ht(HT,X,[IX]) ->
3134 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3135 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3136 L1 = [(:- multifile goal_expansion/2),(:- dynamic goal_expansion/2),Clause1,Clause1b,Clause2,Clause3,Clause3b,Clause4|T]
3141 lookup_identifier_atom(Key,X,IX,Atom) :-
3142 atom_concat('lookup_identifier_',Key,LookupFunctor),
3143 Atom =.. [LookupFunctor,X,IX].
3145 identifier_label_atom(IndexType,IX,X,Atom) :-
3146 type_indexed_identifier_name(IndexType,identifier_label,Name),
3147 Atom =.. [Name,IX,X].
3149 multi_store_generate_attach_code([],_,L,L).
3150 multi_store_generate_attach_code([ST|STs],C,L,T) :-
3151 generate_attach_code(ST,C,L,L1),
3152 multi_store_generate_attach_code(STs,C,L1,T).
3154 multi_inthash_store_initialisations([],_,L,L).
3155 multi_inthash_store_initialisations([Index|Indexes],FA,L,T) :-
3156 use_auxiliary_module(chr_integertable_store),
3157 multi_hash_store_name(FA,Index,StoreName),
3158 module_initializer((new_iht(HT),nb_setval(StoreName,HT))),
3159 % L = [(:- (chr_integertable_store:new_ht(HT),nb_setval(StoreName,HT)) )|L1],
3161 multi_inthash_store_initialisations(Indexes,FA,L1,T).
3162 multi_hash_store_initialisations([],_,L,L).
3163 multi_hash_store_initialisations([Index|Indexes],FA,L,T) :-
3164 use_auxiliary_module(chr_hashtable_store),
3165 multi_hash_store_name(FA,Index,StoreName),
3166 prolog_global_variable(StoreName),
3167 make_init_store_goal(StoreName,HT,InitStoreGoal),
3168 module_initializer((new_ht(HT),InitStoreGoal)),
3170 multi_hash_store_initialisations(Indexes,FA,L1,T).
3172 global_list_store_initialisation(C,L,T) :-
3174 global_list_store_name(C,StoreName),
3175 prolog_global_variable(StoreName),
3176 make_init_store_goal(StoreName,[],InitStoreGoal),
3177 module_initializer(InitStoreGoal)
3182 global_ground_store_initialisation(C,L,T) :-
3183 global_ground_store_name(C,StoreName),
3184 prolog_global_variable(StoreName),
3185 make_init_store_goal(StoreName,[],InitStoreGoal),
3186 module_initializer(InitStoreGoal),
3188 global_singleton_store_initialisation(C,L,T) :-
3189 global_singleton_store_name(C,StoreName),
3190 prolog_global_variable(StoreName),
3191 make_init_store_goal(StoreName,[],InitStoreGoal),
3192 module_initializer(InitStoreGoal),
3194 identifier_store_initialization(IndexType,L,T) :-
3195 use_auxiliary_module(chr_hashtable_store),
3196 identifier_store_name(IndexType,StoreName),
3197 prolog_global_variable(StoreName),
3198 make_init_store_goal(StoreName,HT,InitStoreGoal),
3199 module_initializer((new_ht(HT),InitStoreGoal)),
3203 multi_inthash_via_lookups([],_,L,L).
3204 multi_inthash_via_lookups([Index|Indexes],C,L,T) :-
3205 multi_hash_via_lookup_goal(C,Index,Key,SuspsList,Head),
3206 multi_hash_store_name(C,Index,StoreName),
3209 nb_getval(StoreName,HT),
3210 lookup_iht(HT,Key,SuspsList)
3212 L = [(Head :- Body)|L1],
3213 multi_inthash_via_lookups(Indexes,C,L1,T).
3214 multi_hash_via_lookups([],_,L,L).
3215 multi_hash_via_lookups([Index|Indexes],C,L,T) :-
3216 multi_hash_via_lookup_goal(C,Index,Key,SuspsList,Head),
3217 multi_hash_store_name(C,Index,StoreName),
3218 make_get_store_goal(StoreName,HT,GetStoreGoal),
3221 GetStoreGoal, % nb_getval(StoreName,HT),
3222 lookup_ht(HT,Key,SuspsList)
3224 L = [(Head :- Body)|L1],
3225 multi_hash_via_lookups(Indexes,C,L1,T).
3227 %% multi_hash_via_lookup_goal(+ConstraintSymbol,+Index,+Key,+SuspsList,-Goal) is det.
3229 % Returns goal that performs hash table lookup.
3230 multi_hash_via_lookup_goal(ConstraintSymbol,Index,Key,SuspsList,Goal) :-
3231 multi_hash_via_lookup_name(ConstraintSymbol,Index,Name),
3232 Goal =.. [Name,Key,SuspsList].
3234 %% multi_hash_via_lookup_name(+ConstraintSymbol,+Index,-Name)
3236 % Returns predicate name of hash table lookup predicate.
3237 multi_hash_via_lookup_name(F/A,Index,Name) :-
3241 atom_concat_list(Index,IndexName)
3243 atom_concat_list(['$via1_multi_hash_',F,(/),A,'-',IndexName],Name).
3245 multi_hash_store_name(F/A,Index,Name) :-
3246 get_target_module(Mod),
3250 atom_concat_list(Index,IndexName)
3252 atom_concat_list(['$chr_store_multi_hash_',Mod,(:),F,(/),A,'-',IndexName],Name).
3254 multi_hash_key(FA,Index,Susp,KeyBody,Key) :-
3255 ( ( integer(Index) ->
3260 get_dynamic_suspension_term_field(argument(I),FA,Susp,Key,KeyBody)
3262 sort(Index,Indexes),
3263 find_with_var_identity(Goal-KeyI,[Susp],(member(I,Indexes),get_dynamic_suspension_term_field(argument(I),FA,Susp,KeyI,Goal)),ArgKeyPairs),
3264 once(pairup(Bodies,Keys,ArgKeyPairs)),
3266 list2conj(Bodies,KeyBody)
3269 multi_hash_key(C,Head,Index,Susp,VarDict,KeyBody,Key) :-
3270 ( ( integer(Index) ->
3275 get_suspension_argument_possibly_in_scope(Head,I,VarDict,Susp,Key,KeyBody)
3277 sort(Index,Indexes),
3278 find_with_var_identity(
3280 [Susp/Head/VarDict],
3283 get_suspension_argument_possibly_in_scope(Head,I,VarDict,Susp,KeyI,Goal)
3287 once(pairup(Bodies,Keys,ArgKeyPairs)),
3289 list2conj(Bodies,KeyBody)
3292 get_suspension_argument_possibly_in_scope(Head,Index,VarDict,Susp,Arg,Goal) :-
3293 arg(Index,Head,OriginalArg),
3294 ( lookup_eq(VarDict,OriginalArg,Arg) ->
3299 get_dynamic_suspension_term_field(argument(Index),C,Susp,Arg,Goal)
3302 multi_hash_key_direct(FA,Index,Susp,Key,UsedVars) :-
3303 ( ( integer(Index) ->
3310 sort(Index,Indexes),
3311 pairup(Indexes,Keys,UsedVars),
3315 multi_hash_key_args(Index,Head,KeyArgs) :-
3317 arg(Index,Head,Arg),
3320 sort(Index,Indexes),
3321 term_variables(Head,Vars),
3322 find_with_var_identity(Arg,Vars,(member(I,Indexes), arg(I,Head,Arg)),KeyArgs)
3325 global_list_store_name(F/A,Name) :-
3326 get_target_module(Mod),
3327 atom_concat_list(['$chr_store_global_list_',Mod,(:),F,(/),A],Name).
3328 global_ground_store_name(F/A,Name) :-
3329 get_target_module(Mod),
3330 atom_concat_list(['$chr_store_global_ground_',Mod,(:),F,(/),A],Name).
3331 global_singleton_store_name(F/A,Name) :-
3332 get_target_module(Mod),
3333 atom_concat_list(['$chr_store_global_singleton_',Mod,(:),F,(/),A],Name).
3335 identifier_store_name(TypeName,Name) :-
3336 get_target_module(Mod),
3337 atom_concat_list(['$chr_identifier_lookup_',Mod,(:),TypeName],Name).
3339 :- chr_constraint prolog_global_variable/1.
3340 :- chr_option(mode,prolog_global_variable(+)).
3342 :- chr_constraint prolog_global_variables/1.
3343 :- chr_option(mode,prolog_global_variables(-)).
3345 prolog_global_variable(Name) \ prolog_global_variable(Name) <=> true.
3347 prolog_global_variables(List), prolog_global_variable(Name) <=>
3349 prolog_global_variables(Tail).
3350 prolog_global_variables(List) <=> List = [].
3353 prolog_global_variables_code(Code) :-
3354 prolog_global_variables(Names),
3358 findall('$chr_prolog_global_variable'(Name),member(Name,Names),NameDeclarations),
3359 Code = [(:- dynamic user:exception/3),
3360 (:- multifile user:exception/3),
3361 (user:exception(undefined_global_variable,Name,retry) :-
3363 '$chr_prolog_global_variable'(Name),
3364 '$chr_initialization'
3373 % prolog_global_variables_code([]).
3375 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3376 %sbag_member_call(S,L,sysh:mem(S,L)).
3377 sbag_member_call(S,L,'chr sbag_member'(S,L)).
3378 %sbag_member_call(S,L,member(S,L)).
3379 update_mutable_call(A,B,'chr update_mutable'( A, B)).
3380 %update_mutable_call(A,B,setarg(1, B, A)).
3381 create_mutable_call(Value,Mutable,true) :- Mutable = mutable(Value).
3382 % create_mutable_call(Value,Mutable,'chr create_mutable'(Value,Mutable)).
3384 % get_suspension_field(Constraint,Susp,FieldName,Value,(Get0,Get1)) :-
3385 % get_dynamic_suspension_term_field(FieldName,Constraint,Susp,Field,Get0),
3386 % create_get_mutable(Value,Field,Get1).
3388 % update_suspension_field(Constraint,Susp,FieldName,NewValue,(Get,Set)) :-
3389 % get_dynamic_suspension_term_field(FieldName,Constraint,Susp,Field,Get),
3390 % update_mutable_call(NewValue,Field,Set).
3392 % get_update_suspension_field(Constraint,Susp,FieldName,Value,NewValue,Get0,Get1,Set) :-
3393 % get_dynamic_suspension_term_field(FieldName,Constraint,Susp,Field,Get0),
3394 % create_get_mutable_ref(Value,Field,Get1),
3395 % update_mutable_call(NewValue,Field,Set).
3397 % create_static_suspension_field(Constraint,Susp,FieldName,Value,Create) :-
3398 % get_static_suspension_term_field(FieldName,Constraint,Susp,Field),
3399 % create_mutable_call(Value,Field,Create).
3401 % get_static_suspension_field(Constraint,Susp,FieldName,Value,Get) :-
3402 % get_static_suspension_term_field(FieldName,Constraint,Susp,Field),
3403 % create_get_mutable(Value,Field,Get).
3405 % get_update_static_suspension_field(Constraint,Susp,SuspTerm,FieldName,Value,NewValue,Get,Set) :-
3406 % get_static_suspension_term_field(FieldName,Constraint,SuspTerm,Field),
3407 % create_get_mutable_ref(Value,Field,Get),
3408 % update_mutable_call(NewValue,Field,Set).
3410 get_suspension_field(Constraint,Susp,FieldName,Value,Get) :-
3411 get_dynamic_suspension_term_field(FieldName,Constraint,Susp,Value,Get).
3413 update_suspension_field(Constraint,Susp,FieldName,NewValue,Set) :-
3414 set_dynamic_suspension_term_field(FieldName,Constraint,Susp,NewValue,Set).
3416 get_update_suspension_field(Constraint,Susp,FieldName,Value,NewValue,true,Get,Set) :-
3417 get_dynamic_suspension_term_field(FieldName,Constraint,Susp,Value,Get),
3418 set_dynamic_suspension_term_field(FieldName,Constraint,Susp,NewValue,Set).
3420 create_static_suspension_field(Constraint,Susp,FieldName,Value,true) :-
3421 get_static_suspension_term_field(FieldName,Constraint,Susp,Value).
3423 get_static_suspension_field(Constraint,Susp,FieldName,Value,true) :-
3424 get_static_suspension_term_field(FieldName,Constraint,Susp,Value).
3426 get_update_static_suspension_field(Constraint,Susp,SuspTerm,FieldName,Value,NewValue,true,Set) :-
3427 get_static_suspension_term_field(FieldName,Constraint,SuspTerm,Value),
3428 set_dynamic_suspension_term_field(FieldName,Constraint,Susp,NewValue,Set).
3430 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3432 enumerate_stores_code(Constraints,Clause) :-
3433 Head = '$enumerate_constraints'(Constraint),
3434 enumerate_store_bodies(Constraints,Constraint,Bodies),
3435 list2disj(Bodies,Body),
3436 Clause = (Head :- Body).
3438 enumerate_store_bodies([],_,[]).
3439 enumerate_store_bodies([C|Cs],Constraint,L) :-
3441 get_store_type(C,StoreType),
3442 enumerate_store_body(StoreType,C,Suspension,SuspensionBody),
3443 get_dynamic_suspension_term_field(arguments,C,Suspension,Arguments,DynamicGoal),
3445 Constraint0 =.. [F|Arguments],
3446 Body = (SuspensionBody, DynamicGoal, Constraint = Constraint0),
3451 enumerate_store_bodies(Cs,Constraint,T).
3453 enumerate_store_body(default,C,Susp,Body) :-
3454 global_list_store_name(C,StoreName),
3455 sbag_member_call(Susp,List,Sbag),
3456 make_get_store_goal(StoreName,List,GetStoreGoal),
3459 GetStoreGoal, % nb_getval(StoreName,List),
3462 % get_constraint_index(C,Index),
3463 % get_target_module(Mod),
3464 % get_max_constraint_index(MaxIndex),
3467 % 'chr default_store'(GlobalStore),
3468 % get_attr(GlobalStore,Mod,Attr)
3471 % NIndex is Index + 1,
3472 % sbag_member_call(Susp,List,Sbag),
3475 % arg(NIndex,Attr,List),
3479 % sbag_member_call(Susp,Attr,Sbag),
3482 % Body = (Body1,Body2).
3483 enumerate_store_body(multi_inthash([Index|_]),C,Susp,Body) :-
3484 multi_inthash_enumerate_store_body(Index,C,Susp,Body).
3485 enumerate_store_body(multi_hash([Index|_]),C,Susp,Body) :-
3486 multi_hash_enumerate_store_body(Index,C,Susp,Body).
3487 enumerate_store_body(global_ground,C,Susp,Body) :-
3488 global_ground_store_name(C,StoreName),
3489 sbag_member_call(Susp,List,Sbag),
3490 make_get_store_goal(StoreName,List,GetStoreGoal),
3493 GetStoreGoal, % nb_getval(StoreName,List),
3496 enumerate_store_body(var_assoc_store(_,_),C,_,Body) :-
3498 enumerate_store_body(global_singleton,C,Susp,Body) :-
3499 global_singleton_store_name(C,StoreName),
3500 make_get_store_goal(StoreName,Susp,GetStoreGoal),
3503 GetStoreGoal, % nb_getval(StoreName,Susp),
3506 enumerate_store_body(multi_store(STs),C,Susp,Body) :-
3509 enumerate_store_body(ST,C,Susp,Body)
3511 enumerate_store_body(identifier_store(Index),C,Susp,Body) :-
3513 enumerate_store_body(type_indexed_identifier_store(Index,IndexType),C,Susp,Body) :-
3516 multi_inthash_enumerate_store_body(I,C,Susp,B) :-
3517 multi_hash_store_name(C,I,StoreName),
3520 nb_getval(StoreName,HT),
3523 multi_hash_enumerate_store_body(I,C,Susp,B) :-
3524 multi_hash_store_name(C,I,StoreName),
3525 make_get_store_goal(StoreName,HT,GetStoreGoal),
3528 GetStoreGoal, % nb_getval(StoreName,HT),
3532 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3540 :- chr_option(mode,prev_guard_list(+,+,+,+,+,+,+)).
3541 :- chr_option(mode,simplify_guards(+)).
3542 :- chr_option(mode,set_all_passive(+)).
3544 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3545 % GUARD SIMPLIFICATION
3546 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3547 % If the negation of the guards of earlier rules entails (part of)
3548 % the current guard, the current guard can be simplified. We can only
3549 % use earlier rules with a head that matches if the head of the current
3550 % rule does, and which make it impossible for the current rule to match
3551 % if they fire (i.e. they shouldn't be propagation rules and their
3552 % head constraints must be subsets of those of the current rule).
3553 % At this point, we know for sure that the negation of the guard
3554 % of such a rule has to be true (otherwise the earlier rule would have
3555 % fired, because of the refined operational semantics), so we can use
3556 % that information to simplify the guard by replacing all entailed
3557 % conditions by true/0. As a consequence, the never-stored analysis
3558 % (in a further phase) will detect more cases of never-stored constraints.
3560 % e.g. c(X),d(Y) <=> X > 0 | ...
3561 % e(X) <=> X < 0 | ...
3562 % c(X) \ d(Y),e(Z) <=> X =< 0, Z >= 0, ... | ...
3566 guard_simplification :-
3567 ( chr_pp_flag(guard_simplification,on) ->
3573 % for every rule, we create a prev_guard_list where the last argument
3574 % eventually is a list of the negations of earlier guards
3575 rule(RuleNb,Rule) \ simplify_guards(RuleNb)
3577 Rule = pragma(rule(Head1,Head2,Guard,_B),_Ids,_Pragmas,_Name,RuleNb),
3578 append(Head1,Head2,Heads),
3579 make_head_matchings_explicit_not_negated(Heads,MatchingFreeHeads,Matchings),
3580 multiple_occ_constraints_checked([]),
3581 apply_guard_wrt_term(Heads,Guard,SubstitutedHeads),
3582 PrevRuleNb is RuleNb-1,
3583 prev_guard_list(RuleNb,PrevRuleNb,MatchingFreeHeads,Guard,[],Matchings,[SubstitutedHeads]),
3584 NextRule is RuleNb+1,
3585 simplify_guards(NextRule).
3592 % The negation of the guard of a non-propagation rule is added
3593 % if its kept head constraints are a subset of the kept constraints of
3594 % the rule we're working on, and its removed head constraints (at least one)
3595 % are a subset of the removed constraints.
3597 rule(PrevRuleNb,PrevRule) \ prev_guard_list(RuleNb,PrevRuleNb,CurrentHeads,G,GuardList,Matchings,GH)
3599 PrevRule = pragma(rule(H1,H2,PrevGuard,_B),_Ids,_Pragmas,_Name,PrevRuleNb),
3601 append(H1,H2,Heads),
3602 make_head_matchings_explicit(Heads,MatchingFreeHeads,PrevMatchings),
3603 setof(Renaming,chr_translate:head_subset(MatchingFreeHeads,CurrentHeads,Renaming),Renamings)
3605 compute_derived_info(Renamings,PrevMatchings,MatchingFreeHeads,Heads,PrevGuard,Matchings,CurrentHeads,GH,DerivedInfo,GH_New1),
3606 append(GuardList,DerivedInfo,GL1),
3607 normalize_conj_list(GL1,GL),
3608 append(GH_New1,GH,GH1),
3609 normalize_conj_list(GH1,GH_New),
3610 PrevPrevRuleNb is PrevRuleNb-1,
3611 prev_guard_list(RuleNb,PrevPrevRuleNb,CurrentHeads,G,GL,Matchings,GH_New).
3613 % if this isn't the case, we skip this one and try the next rule
3614 prev_guard_list(RuleNb,N,H,G,GuardList,M,GH)
3619 prev_guard_list(RuleNb,N1,H,G,GuardList,M,GH).
3621 prev_guard_list(RuleNb,0,H,G,GuardList,M,GH)
3625 head_types_modes_condition(GH,H,TypeInfo),
3626 conj2list(TypeInfo,TI),
3627 term_variables(H,HeadVars),
3628 append([chr_pp_headvariables(HeadVars)|TI],GuardList,Info),
3629 normalize_conj_list(Info,InfoL),
3630 prev_guard_list(RuleNb,0,H,G,InfoL,M,[]).
3632 head_types_modes_condition([],H,true).
3633 head_types_modes_condition([GH|GHs],H,(TI1, TI2)) :-
3634 types_modes_condition(H,GH,TI1),
3635 head_types_modes_condition(GHs,H,TI2).
3639 % when all earlier guards are added or skipped, we simplify the guard.
3640 % if it's different from the original one, we change the rule
3642 prev_guard_list(RuleNb,0,H,G,GuardList,M,[]), rule(RuleNb,Rule)
3644 Rule = pragma(rule(Head1,Head2,G,B),Ids,Pragmas,Name,RuleNb),
3645 G \== true, % let's not try to simplify this ;)
3646 append(M,GuardList,Info),
3647 simplify_guard(G,B,Info,SimpleGuard,NB),
3650 rule(RuleNb,pragma(rule(Head1,Head2,SimpleGuard,NB),Ids,Pragmas,Name,RuleNb)),
3651 prev_guard_list(RuleNb,0,H,SimpleGuard,GuardList,M,[]).
3653 %% normalize_conj_list(+List,-NormalList) is det.
3655 % Removes =true= elements and flattens out conjunctions.
3657 normalize_conj_list(List,NormalList) :-
3658 list2conj(List,Conj),
3659 conj2list(Conj,NormalList).
3661 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3662 % AUXILIARY PREDICATES (GUARD SIMPLIFICATION)
3663 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3665 compute_derived_info([],_PrevMatchings,_MatchingFreeHeads,_Heads,_PrevGuard,_Matchings,_H,_GH,[],[]).
3666 compute_derived_info([Renaming1|RestRenamings],PrevMatchings,PrevMatchingFreeHeads,PrevHeads,PrevGuard,Matchings,H,GH,[DerivedInfo1|DerivedInfo2],[GH3|GH_New2]) :-
3667 copy_term(PrevMatchings-PrevGuard,FreshMatchings),
3668 variable_replacement(PrevMatchings-PrevGuard,FreshMatchings,ExtraRenaming),
3669 append(Renaming1,ExtraRenaming,Renaming2),
3670 list2conj(PrevMatchings,Match),
3671 negate_b(Match,HeadsDontMatch),
3672 make_head_matchings_explicit_not_negated2(PrevHeads,PrevMatchingFreeHeads,HeadsMatch),
3673 list2conj(HeadsMatch,HeadsMatchBut),
3674 term_variables(Renaming2,RenVars),
3675 term_variables(PrevMatchings-PrevGuard-HeadsMatch,MGVars),
3676 new_vars(MGVars,RenVars,ExtraRenaming2),
3677 append(Renaming2,ExtraRenaming2,Renaming),
3678 ( PrevGuard == true -> % true can't fail
3679 Info_ = HeadsDontMatch
3681 negate_b(PrevGuard,TheGuardFailed),
3682 Info_ = (HeadsDontMatch ; (HeadsMatchBut, TheGuardFailed))
3684 copy_with_variable_replacement(Info_,DerivedInfo1,Renaming),
3685 copy_with_variable_replacement(PrevGuard,RenamedG2,Renaming),
3686 copy_with_variable_replacement(PrevMatchings,RenamedMatchings_,Renaming),
3687 list2conj(RenamedMatchings_,RenamedMatchings),
3688 apply_guard_wrt_term(H,RenamedG2,GH2),
3689 apply_guard_wrt_term(GH2,RenamedMatchings,GH3),
3690 compute_derived_info(RestRenamings,PrevMatchings,PrevMatchingFreeHeads,PrevHeads,PrevGuard,Matchings,H,GH,DerivedInfo2,GH_New2).
3692 simplify_guard(G,B,Info,SG,NB) :-
3694 guard_entailment:simplify_guards(Info,B,LG,SGL,NB),
3699 new_vars([A|As],RV,ER) :-
3700 ( memberchk_eq(A,RV) ->
3703 ER = [A-NewA,NewA-A|ER2],
3707 %% head_subset(+Subset,+MultiSet,-Renaming) is nondet.
3709 % check if a list of constraints is a subset of another list of constraints
3710 % (multiset-subset), meanwhile computing a variable renaming to convert
3711 % one into the other.
3712 head_subset(H,Head,Renaming) :-
3713 head_subset(H,Head,Renaming,[],_).
3715 head_subset([],Remainder,Renaming,Renaming,Remainder).
3716 head_subset([X|Xs],MultiSet,Renaming,Acc,Remainder) :-
3717 head_member(X,MultiSet,NAcc,Acc,Remainder1),
3718 head_subset(Xs,Remainder1,Renaming,NAcc,Remainder).
3720 % check if A is in the list, remove it from Headleft
3721 head_member(A,[X|Xs],Renaming,Acc,Remainder) :-
3722 ( variable_replacement(A,X,Acc,Renaming),
3725 head_member(A,Xs,Renaming,Acc,RRemainder),
3726 Remainder = [X|RRemainder]
3729 make_head_matchings_explicit(Heads,MatchingFreeHeads,Matchings) :-
3730 extract_arguments(Heads,Arguments),
3731 make_matchings_explicit(Arguments,H1_,[],[],_,Matchings),
3732 substitute_arguments(Heads,H1_,MatchingFreeHeads).
3734 make_head_matchings_explicit_not_negated(Heads,MatchingFreeHeads,Matchings) :-
3735 extract_arguments(Heads,Arguments),
3736 make_matchings_explicit_not_negated(Arguments,FreshVariables,Matchings),
3737 substitute_arguments(Heads,FreshVariables,MatchingFreeHeads).
3739 make_head_matchings_explicit_not_negated2(Heads,MatchingFreeHeads,Matchings) :-
3740 extract_arguments(Heads,Arguments1),
3741 extract_arguments(MatchingFreeHeads,Arguments2),
3742 make_matchings_explicit_not_negated(Arguments1,Arguments2,Matchings).
3744 %% extract_arguments(+ListOfConstraints,-ListOfVariables) is det.
3746 % Returns list of arguments of given list of constraints.
3748 extract_arguments([],[]).
3749 extract_arguments([C|Cs],AllArguments) :-
3750 C =.. [_|Arguments],
3751 append(Arguments,RestArguments,AllArguments),
3752 extract_arguments(Cs,RestArguments).
3754 %% substitute_arguments(+InListOfConstraints,ListOfVariables,-OutListOfConstraints) is det.
3756 % Substitutes arguments of constraints with those in the given list.
3758 substitute_arguments([],[],[]).
3759 substitute_arguments([C|Cs],Variables,[NC|NCs]) :-
3761 split_at(N,Variables,Arguments,RestVariables),
3762 NC =.. [F|Arguments],
3763 substitute_arguments(Cs,RestVariables,NCs).
3765 make_matchings_explicit([],[],_,MC,MC,[]).
3766 make_matchings_explicit([X|R],[NewVar|R2],C,MC,MCO,M) :-
3768 ( memberchk_eq(X,C) ->
3769 list2disj(MC,MC_disj),
3770 M = [(MC_disj ; NewVar == X)|M2], % or only = ??
3781 make_matchings_explicit(Args,NewArgs,C,MC,MC_,ArgM),
3784 M = [functor(NewVar,F,A) |M2]
3786 list2conj(ArgM,ArgM_conj),
3787 list2disj(MC,MC_disj),
3788 ArgM_ = (NewVar \= X_ ; MC_disj ; ArgM_conj),
3789 M = [ functor(NewVar,F,A) , ArgM_|M2]
3791 MC2 = [ NewVar \= X_ |MC_],
3792 term_variables(Args,ArgVars),
3793 append(C,ArgVars,C2)
3795 make_matchings_explicit(R,R2,C2,MC2,MCO,M2).
3798 %% make_matchings_explicit_not_negated(+ListOfTerms,-ListOfVariables,-ListOfMatchings) is det.
3800 % Returns list of new variables and list of pairwise unifications between given list and variables.
3802 make_matchings_explicit_not_negated([],[],[]).
3803 make_matchings_explicit_not_negated([X|Xs],[Var|Vars],Matchings) :-
3804 Matchings = [Var = X|RMatchings],
3805 make_matchings_explicit_not_negated(Xs,Vars,RMatchings).
3807 %% apply_guard_wrt_term(+ListOfConstraints,+Goal,-NewListOfConstraints) is det.
3809 % (Partially) applies substitutions of =Goal= to given list.
3811 apply_guard_wrt_term([],_Guard,[]).
3812 apply_guard_wrt_term([Term|RH],Guard,[NTerm|RGH]) :-
3814 apply_guard_wrt_variable(Guard,Term,NTerm)
3817 apply_guard_wrt_term(HArgs,Guard,NewHArgs),
3818 NTerm =.. [F|NewHArgs]
3820 apply_guard_wrt_term(RH,Guard,RGH).
3822 %% apply_guard_wrt_variable(+Goal,+Variable,-NVariable) is det.
3824 % (Partially) applies goal =Guard= wrt variable.
3826 apply_guard_wrt_variable((Guard1,Guard2),Variable,NVariable) :- !,
3827 apply_guard_wrt_variable(Guard1,Variable,NVariable1),
3828 apply_guard_wrt_variable(Guard2,NVariable1,NVariable).
3829 apply_guard_wrt_variable(Guard,Variable,NVariable) :-
3830 ( Guard = (X = Y), Variable == X ->
3832 ; Guard = functor(AVariable,Functor,Arity), Variable == AVariable, ground(Functor), ground(Arity) ->
3833 functor(NVariable,Functor,Arity)
3835 NVariable = Variable
3838 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3839 % ALWAYS FAILING HEADS
3840 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3842 rule(RuleNb,Rule) \ prev_guard_list(RuleNb,0,H,G,GuardList,M,[])
3844 chr_pp_flag(check_impossible_rules,on),
3845 Rule = pragma(rule(Head1,Head2,G,B),Ids,Pragmas,Name,RuleNb),
3846 append(M,GuardList,Info),
3847 guard_entailment:entails_guard(Info,fail)
3849 chr_warning(weird_program,'Heads will never match in ~@.\n\tThis rule will never fire!\n',[format_rule(Rule)]),
3850 set_all_passive(RuleNb).
3852 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3853 % HEAD SIMPLIFICATION
3854 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3856 % now we check the head matchings (guard may have been simplified meanwhile)
3857 prev_guard_list(RuleNb,0,H,G,GuardList,M,[]) \ rule(RuleNb,Rule)
3859 Rule = pragma(rule(Head1,Head2,G,B),Ids,Pragmas,Name,RuleNb),
3860 simplify_heads(M,GuardList,G,B,NewM,NewB),
3862 extract_arguments(Head1,VH1),
3863 extract_arguments(Head2,VH2),
3864 extract_arguments(H,VH),
3865 replace_some_heads(VH1,VH2,VH,NewM,H1,H2,G,B,NewB_),
3866 substitute_arguments(Head1,H1,NewH1),
3867 substitute_arguments(Head2,H2,NewH2),
3868 append(NewB,NewB_,NewBody),
3869 list2conj(NewBody,BodyMatchings),
3870 NewRule = pragma(rule(NewH1,NewH2,G,(BodyMatchings,B)),Ids,Pragmas,Name,RuleNb),
3871 (Head1 \== NewH1 ; Head2 \== NewH2 )
3873 rule(RuleNb,NewRule).
3875 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3876 % AUXILIARY PREDICATES (HEAD SIMPLIFICATION)
3877 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3879 replace_some_heads(H1,H2,NH,[],H1,H2,G,Body,[]) :- !.
3880 replace_some_heads([],[H2|RH2],[NH|RNH],[M|RM],[],[H2_|RH2_],G,Body,NewB) :- !,
3883 replace_some_heads([],RH2,RNH,RM,[],RH2_,G,Body,NewB)
3885 (M = functor(X,F,A), NH == X ->
3891 H2 =.. [F|OrigArgs],
3892 use_same_args(OrigArgs,A_args,A_args_,G,Body,NewB1),
3895 replace_some_heads([],RH2,RNH,RM,[],RH2_,G,Body,NewB2),
3896 append(NewB1,NewB2,NewB)
3899 replace_some_heads([],RH2,RNH,[M|RM],[],RH2_,G,Body,NewB)
3903 replace_some_heads([H1|RH1],H2,[NH|RNH],[M|RM],[H1_|RH1_],H2_,G,Body,NewB) :- !,
3906 replace_some_heads(RH1,H2,RNH,RM,RH1_,H2_,G,Body,NewB)
3908 (M = functor(X,F,A), NH == X ->
3914 H1 =.. [F|OrigArgs],
3915 use_same_args(OrigArgs,A_args,A_args_,G,Body,NewB1),
3918 replace_some_heads(RH1,H2,RNH,RM,RH1_,H2_,G,Body,NewB2),
3919 append(NewB1,NewB2,NewB)
3922 replace_some_heads(RH1,H2,RNH,[M|RM],RH1_,H2_,G,Body,NewB)
3926 use_same_args([],[],[],_,_,[]).
3927 use_same_args([OA|ROA],[NA|RNA],[Out|ROut],G,Body,NewB) :-
3930 use_same_args(ROA,RNA,ROut,G,Body,NewB).
3931 use_same_args([OA|ROA],[NA|RNA],[Out|ROut],G,Body,NewB) :-
3933 ( vars_occur_in(OA,Body) ->
3934 NewB = [NA = OA|NextB]
3939 use_same_args(ROA,RNA,ROut,G,Body,NextB).
3942 simplify_heads([],_GuardList,_G,_Body,[],[]).
3943 simplify_heads([M|RM],GuardList,G,Body,NewM,NewB) :-
3945 ( (nonvar(B) ; vars_occur_in(B,RM-GuardList)),
3946 guard_entailment:entails_guard(GuardList,(A=B)) ->
3947 ( vars_occur_in(B,G-RM-GuardList) ->
3951 ( vars_occur_in(B,Body) ->
3952 NewB = [A = B|NextB]
3959 ( nonvar(B), functor(B,BFu,BAr),
3960 guard_entailment:entails_guard([functor(A,BFu,BAr)|GuardList],(A=B)) ->
3962 ( vars_occur_in(B,G-RM-GuardList) ->
3965 NewM = [functor(A,BFu,BAr)|NextM]
3972 simplify_heads(RM,[M|GuardList],G,Body,NextM,NextB).
3974 vars_occur_in(B,G) :-
3975 term_variables(B,BVars),
3976 term_variables(G,GVars),
3977 intersect_eq(BVars,GVars,L),
3981 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3982 % ALWAYS FAILING GUARDS
3983 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3985 set_all_passive(RuleNb), occurrence(_,_,RuleNb,ID,_) ==> passive(RuleNb,ID).
3986 set_all_passive(_) <=> true.
3988 prev_guard_list(RuleNb,0,H,G,GuardList,M,[]),rule(RuleNb,Rule)
3990 chr_pp_flag(check_impossible_rules,on),
3991 Rule = pragma(rule(_,_,G,_),_Ids,_Pragmas,_Name,RuleNb),
3993 guard_entailment:entails_guard(GL,fail)
3995 chr_warning(weird_program,'Guard will always fail in ~@.\n\tThis rule will never fire!\n',[format_rule(Rule)]),
3996 set_all_passive(RuleNb).
4000 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4001 % OCCURRENCE SUBSUMPTION
4002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4005 first_occ_in_rule/4,
4008 :- chr_option(mode,first_occ_in_rule(+,+,+,+)).
4009 :- chr_option(mode,next_occ_in_rule(+,+,+,+,+,+)).
4011 :- chr_constraint multiple_occ_constraints_checked/1.
4012 :- chr_option(mode,multiple_occ_constraints_checked(+)).
4014 prev_guard_list(RuleNb,0,H,G,GuardList,M,[]), occurrence(C,O,RuleNb,ID,_),
4015 occurrence(C,O2,RuleNb,ID2,_), rule(RuleNb,Rule) \ multiple_occ_constraints_checked(Done)
4018 chr_pp_flag(occurrence_subsumption,on),
4019 Rule = pragma(rule(H1,H2,_G,_B),_Ids,_Pragmas,_Name,RuleNb),
4021 \+ memberchk_eq(C,Done)
4023 first_occ_in_rule(RuleNb,C,O,ID),
4024 multiple_occ_constraints_checked([C|Done]).
4026 % Find first occurrence of constraint =C= in rule =RuleNb=
4027 occurrence(C,O,RuleNb,ID,_) \ first_occ_in_rule(RuleNb,C,O2,_)
4031 first_occ_in_rule(RuleNb,C,O,ID).
4033 first_occ_in_rule(RuleNb,C,O,ID_o1)
4036 functor(FreshHead,F,A),
4037 next_occ_in_rule(RuleNb,C,O,ID_o1,[],FreshHead).
4039 % Skip passive occurrences.
4040 passive(RuleNb,ID_o2), occurrence(C,O2,RuleNb,ID_o2,_) \ next_occ_in_rule(RuleNb,C,O,ID_o1,Cond,FH)
4044 next_occ_in_rule(RuleNb,C,O2,ID_o1,NewCond,FH).
4046 prev_guard_list(RuleNb,0,H,G,GuardList,M,[]), occurrence(C,O2,RuleNb,ID_o2,_), rule(RuleNb,Rule) \ next_occ_in_rule(RuleNb,C,O,ID_o1,Cond,FH)
4049 Rule = pragma(rule(H1,H2,G,B),ids(ID1,ID2),_Pragmas,_Name,RuleNb)
4051 append(H1,H2,Heads),
4052 add_failing_occ(Rule,Heads,H,ID_o1,ExtraCond,FH,M,C,Repl),
4053 ( ExtraCond == [chr_pp_void_info] ->
4054 next_occ_in_rule(RuleNb,C,O2,ID_o2,Cond,FH)
4056 append(ExtraCond,Cond,NewCond),
4057 add_failing_occ(Rule,Heads,H,ID_o2,CheckCond,FH,M,C,Repl2),
4058 copy_term(GuardList,FGuardList),
4059 variable_replacement(GuardList,FGuardList,GLRepl),
4060 copy_with_variable_replacement(GuardList,GuardList2,Repl),
4061 copy_with_variable_replacement(GuardList,GuardList3_,Repl2),
4062 copy_with_variable_replacement(GuardList3_,GuardList3,GLRepl),
4063 append(NewCond,GuardList2,BigCond),
4064 append(BigCond,GuardList3,BigCond2),
4065 copy_with_variable_replacement(M,M2,Repl),
4066 copy_with_variable_replacement(M,M3,Repl2),
4067 append(M3,BigCond2,BigCond3),
4068 append([chr_pp_active_constraint(FH)|M2],BigCond3,Info),
4069 list2conj(CheckCond,OccSubsum),
4070 copy_term((NewCond,BigCond2,Info,OccSubsum,FH),(NewCond2,BigCond2_,Info2,OccSubsum2,FH2)),
4071 % term_variables(NewCond2-FH2,InfoVars),
4072 % flatten_stuff(Info2,Info3),
4073 % flatten_stuff(OccSubsum2,OccSubsum3),
4074 ( OccSubsum \= chr_pp_void_info
4075 % unify_stuff(InfoVars,Info3,OccSubsum3)
4077 ( guard_entailment:entails_guard(Info2,OccSubsum2) ->
4078 passive(RuleNb,ID_o2)
4085 next_occ_in_rule(RuleNb,C,O2,ID_o2,NewCond,FH)
4089 next_occ_in_rule(RuleNb,C,O,ID,Cond,Args)
4093 prev_guard_list(RuleNb,0,H,G,GuardList,M,[]), multiple_occ_constraints_checked(Done)
4097 flatten_stuff([A|B],C) :- !,
4098 flatten_stuff(A,C1),
4099 flatten_stuff(B,C2),
4101 flatten_stuff((A;B),C) :- !,
4102 flatten_stuff(A,C1),
4103 flatten_stuff(B,C2),
4105 flatten_stuff((A,B),C) :- !,
4106 flatten_stuff(A,C1),
4107 flatten_stuff(B,C2),
4110 flatten_stuff(chr_pp_not_in_store(A),[A]) :- !.
4111 flatten_stuff(X,[]).
4113 unify_stuff(AllInfo,[],[]).
4115 unify_stuff(AllInfo,[H|RInfo],[I|ROS]) :-
4117 term_variables(H,HVars),
4118 term_variables(I,IVars),
4119 intersect_eq(HVars,IVars,SharedVars),
4120 check_safe_unif(H,I,SharedVars),
4121 variable_replacement(H,I,Repl),
4122 check_replacement(Repl),
4123 term_variables(Repl,ReplVars),
4124 list_difference_eq(ReplVars,HVars,LDiff),
4125 intersect_eq(AllInfo,LDiff,LDiff2),
4128 unify_stuff(AllInfo,RInfo,ROS),!.
4130 unify_stuff(AllInfo,X,[Y|ROS]) :-
4131 unify_stuff(AllInfo,X,ROS).
4133 unify_stuff(AllInfo,[Y|RInfo],X) :-
4134 unify_stuff(AllInfo,RInfo,X).
4136 check_safe_unif(H,I,SV) :- var(H), !, var(I),
4137 ( (memberchk_eq(H,SV);memberchk_eq(I,SV)) ->
4143 check_safe_unif([],[],SV) :- !.
4144 check_safe_unif([H|Hs],[I|Is],SV) :- !,
4145 check_safe_unif(H,I,SV),!,
4146 check_safe_unif(Hs,Is,SV).
4148 check_safe_unif(H,I,SV) :-
4149 nonvar(H),!,nonvar(I),
4152 check_safe_unif(HA,IA,SV).
4154 check_safe_unif2(H,I) :- var(H), !.
4156 check_safe_unif2([],[]) :- !.
4157 check_safe_unif2([H|Hs],[I|Is]) :- !,
4158 check_safe_unif2(H,I),!,
4159 check_safe_unif2(Hs,Is).
4161 check_safe_unif2(H,I) :-
4162 nonvar(H),!,nonvar(I),
4165 check_safe_unif2(HA,IA).
4168 check_replacement(Repl) :-
4169 check_replacement(Repl,FirstVars),
4170 sort(FirstVars,Sorted),
4172 length(FirstVars,L).
4174 check_replacement([],[]).
4175 check_replacement([A-B|R],[A|RC]) :-
4176 check_replacement(R,RC).
4178 add_failing_occ(Rule,Heads,NH,ID_o1,FailCond,FH,M,C,Repl) :-
4179 Rule = pragma(rule(H1,H2,G,B),ids(ID1,ID2),_Pragmas,_Name,RuleNb),
4180 append(ID2,ID1,IDs),
4181 missing_partner_cond(Heads,NH,IDs,ID_o1,MPCond,H,C),
4182 copy_term((H,Heads,NH),(FH2,FHeads,NH2)),
4183 variable_replacement((H,Heads,NH),(FH2,FHeads,NH2),Repl),
4184 copy_with_variable_replacement(G,FG,Repl),
4185 extract_explicit_matchings(FG,FG2),
4186 negate_b(FG2,NotFG),
4187 copy_with_variable_replacement(MPCond,FMPCond,Repl),
4188 ( check_safe_unif2(FH,FH2), FH=FH2 ->
4189 FailCond = [(NotFG;FMPCond)]
4191 % in this case, not much can be done
4192 % e.g. c(f(...)), c(g(...)) <=> ...
4193 FailCond = [chr_pp_void_info]
4198 missing_partner_cond([],[],[],ID_o1,fail,H2,C).
4199 missing_partner_cond([H|Hs],[H2|H2s],[ID_o1|IDs],ID_o1,Cond,H,C) :- !,
4200 missing_partner_cond(Hs,H2s,IDs,ID_o1,Cond,H,C).
4201 missing_partner_cond([H|Hs],[NH|NHs],[ID|IDs],ID_o1,Cond,H2,F/A) :-
4202 Cond = (chr_pp_not_in_store(H);Cond1),
4203 missing_partner_cond(Hs,NHs,IDs,ID_o1,Cond1,H2,F/A).
4205 extract_explicit_matchings(A=B) :-
4206 var(A), var(B), !, A=B.
4207 extract_explicit_matchings(A==B) :-
4208 var(A), var(B), !, A=B.
4210 extract_explicit_matchings((A,B),D) :- !,
4211 ( extract_explicit_matchings(A) ->
4212 extract_explicit_matchings(B,D)
4215 extract_explicit_matchings(B,E)
4217 extract_explicit_matchings(A,D) :- !,
4218 ( extract_explicit_matchings(A) ->
4227 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4229 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4235 get_type_definition/2,
4236 get_constraint_type/2.
4239 :- chr_option(mode,type_definition(?,?)).
4240 :- chr_option(mode,get_type_definition(?,?)).
4241 :- chr_option(mode,type_alias(?,?)).
4242 :- chr_option(mode,constraint_type(+,+)).
4243 :- chr_option(mode,get_constraint_type(+,-)).
4245 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4246 % Consistency checks of type aliases
4248 type_alias(T,T2) <=>
4249 nonvar(T),nonvar(T2),functor(T,F,A),functor(T2,F,A),
4250 copy_term((T,T2),(X,Y)),oneway_unification(Y,X) |
4251 chr_error(type_error,'Cyclic alias definition: "~w".\n',[(T == T2)]).
4253 type_alias(T1,A1), type_alias(T2,A2) <=>
4254 nonvar(T1),nonvar(T2),functor(T1,F,A),functor(T2,F,A),
4256 copy_term_nat(T1,T1_),
4257 copy_term_nat(T2,T2_),
4259 chr_error(type_error,
4260 'Ambiguous type aliases: you have defined \n\t`~w\'\n\t`~w\'\n\tresulting in two definitions for "~w".\n',[T1==A1,T2==A2,T1_]).
4262 type_alias(T,B) \ type_alias(X,T2) <=>
4263 nonvar(T),nonvar(T2),functor(T,F,A),functor(T2,F,A),
4264 copy_term_nat((X,T2,T,B),(X2,T3,T1,D1)),oneway_unification(T3,T1) |
4265 chr_info(type_information,'Inferring `~w\' from `~w\' and `~w\'.\n',[X2==D1,X==T2,T==B]),
4268 oneway_unification(X,Y) :-
4269 term_variables(X,XVars),
4270 chr_runtime:lockv(XVars),
4272 chr_runtime:unlockv(XVars).
4274 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4275 % Consistency checks of type definitions
4277 type_definition(T1,_), type_definition(T2,_)
4279 functor(T1,F,A), functor(T2,F,A)
4281 chr_error(type_error,'Multiple definitions for type: ~w/~w.\n',[F,A]).
4283 type_definition(T1,_), type_alias(T2,_)
4285 functor(T1,F,A), functor(T2,F,A)
4287 chr_error(type_error,'Multiple definitions for type, once in a type definition and once as a type alias: ~w/~w.\n',[F,A]).
4289 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4290 %% get_type_definition(+Type,-Definition) is semidet.
4291 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4293 get_type_definition(T,Def)
4297 chr_error(type_error,'Non-ground type in constraint definition: "~w".\n',[T]).
4299 type_alias(T,D) \ get_type_definition(T2,Def)
4301 nonvar(T),nonvar(T2),functor(T,F,A),functor(T2,F,A),
4302 copy_term_nat((T,D),(T1,D1)),T1=T2
4304 ( get_type_definition(D1,Def) ->
4307 chr_error(type_error,'Could not find type definition for "~w" (accessed via alias "~w").\n',[D1,T1]), fail
4310 type_definition(T,D) \ get_type_definition(T2,Def)
4312 nonvar(T),nonvar(T2),functor(T,F,A),functor(T2,F,A),
4313 copy_term_nat((T,D),(T1,D1)),T1=T2
4317 get_type_definition(Type,Def)
4319 atomic_builtin_type(Type,_,_)
4323 get_type_definition(Type,Def)
4325 compound_builtin_type(Type,_,_)
4329 get_type_definition(X,Y) <=> fail.
4331 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4332 %% get_type_definition_det(+Type,-Definition) is det.
4333 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4334 get_type_definition_det(Type,Definition) :-
4335 ( get_type_definition(Type,Definition) ->
4338 chr_error(type,'Could not find type definition for type `~w\'.\n',[Type])
4341 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
4342 %% get_constraint_type(+ConstraintSymbol,-Types) is semidet.
4344 % Return argument types of =ConstraintSymbol=, but fails if none where
4346 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
4347 constraint_type(C,T) \ get_constraint_type(C,Type) <=> Type = T.
4348 get_constraint_type(_,_) <=> fail.
4350 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
4351 %% get_constraint_type_det(+ConstraintSymbol,-Types) is det.
4353 % Like =get_constraint_type/2=, but returns list of =any= types when
4354 % no types are declared.
4355 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
4356 get_constraint_type_det(ConstraintSymbol,Types) :-
4357 ( get_constraint_type(ConstraintSymbol,Types) ->
4360 ConstraintSymbol = _ / N,
4361 replicate(N,any,Types)
4363 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
4364 %% unalias_type(+Alias,-Type) is det.
4366 % Follows alias chain until base type is reached.
4367 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
4368 :- chr_constraint unalias_type/2.
4371 unalias_type(Alias,BaseType)
4378 type_alias(AliasProtoType,ProtoType) \ unalias_type(Alias,BaseType)
4380 nonvar(AliasProtoType),
4382 functor(AliasProtoType,F,A),
4384 copy_term_nat((AliasProtoType,ProtoType),(AliasInstance,Type)),
4385 Alias = AliasInstance
4387 unalias_type(Type,BaseType).
4389 unalias_type_definition @
4390 type_definition(ProtoType,Definition) \ unalias_type(Alias,BaseType)
4394 functor(ProtoType,F,A),
4399 unalias_atomic_builtin @
4400 unalias_type(Alias,BaseType)
4402 atomic_builtin_type(Alias,_,_)
4406 unalias_compound_builtin @
4407 unalias_type(Alias,BaseType)
4409 compound_builtin_type(Alias,_,_)
4413 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
4414 %% types_modes_condition(+Heads,+UnrollHeads,-Condition) is det.
4415 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
4416 :- chr_constraint types_modes_condition/3.
4417 :- chr_option(mode,types_modes_condition(+,+,?)).
4418 :- chr_option(type_declaration,types_modes_condition(list,list,goal)).
4420 types_modes_condition([],[],T) <=> T=true.
4422 constraint_mode(F/A,Modes) \ types_modes_condition([Head|Heads],[UnrollHead|UnrollHeads],Condition)
4427 Condition = (ModesCondition, TypesCondition, RestCondition),
4428 modes_condition(Modes,Args,ModesCondition),
4429 get_constraint_type_det(F/A,Types),
4430 UnrollHead =.. [_|RealArgs],
4431 types_condition(Types,Args,RealArgs,Modes,TypesCondition),
4432 types_modes_condition(Heads,UnrollHeads,RestCondition).
4434 types_modes_condition([Head|_],_,_)
4437 chr_error(internal,'Mode information missing for ~w.\n',[F/A]).
4440 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
4441 %% modes_condition(+Modes,+Args,-Condition) is det.
4443 % Return =Condition= on =Args= that checks =Modes=.
4444 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
4445 modes_condition([],[],true).
4446 modes_condition([Mode|Modes],[Arg|Args],Condition) :-
4448 Condition = ( ground(Arg) , RCondition )
4450 Condition = ( var(Arg) , RCondition )
4452 Condition = RCondition
4454 modes_condition(Modes,Args,RCondition).
4456 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
4457 %% types_condition(+Types,+Args,+UnrollArgs,+Modes,-Condition) is det.
4459 % Return =Condition= on =Args= that checks =Types= given =Modes=.
4460 % =UnrollArgs= controls the depth of type definition unrolling.
4461 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
4462 types_condition([],[],[],[],true).
4463 types_condition([Type|Types],[Arg|Args],[UnrollArg|UnrollArgs],[Mode|Modes],(DisjTypeConditionList,RCondition)) :-
4465 TypeConditionList = [true] % TypeConditionList = [var(Arg)] already encoded in modes_condition
4467 get_type_definition_det(Type,Def),
4468 type_condition(Def,Arg,UnrollArg,Mode,TypeConditionList1),
4470 TypeConditionList = TypeConditionList1
4472 TypeConditionList = [(\+ ground(Arg))|TypeConditionList1]
4475 list2disj(TypeConditionList,DisjTypeConditionList),
4476 types_condition(Types,Args,UnrollArgs,Modes,RCondition).
4478 type_condition([],_,_,_,[]).
4479 type_condition([DefCase|DefCases],Arg,UnrollArg,Mode,[Condition|Conditions]) :-
4481 chr_error(type,'Unexpected variable type in type definition!\n',[]) % Condition = true
4482 ; atomic_builtin_type(DefCase,Arg,Condition) ->
4484 ; compound_builtin_type(DefCase,Arg,Condition) ->
4487 type_def_case_condition(DefCase,Arg,UnrollArg,Mode,Condition)
4489 type_condition(DefCases,Arg,UnrollArg,Mode,Conditions).
4491 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
4492 :- chr_type atomic_builtin_type ---> any
4499 ; chr_identifier(any).
4500 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
4502 atomic_builtin_type(any,_Arg,true).
4503 atomic_builtin_type(dense_int,Arg,(integer(Arg),Arg>=0)).
4504 atomic_builtin_type(int,Arg,integer(Arg)).
4505 atomic_builtin_type(number,Arg,number(Arg)).
4506 atomic_builtin_type(float,Arg,float(Arg)).
4507 atomic_builtin_type(natural,Arg,(integer(Arg),Arg>=0)).
4508 atomic_builtin_type(chr_identifier,_Arg,true).
4510 compound_builtin_type(chr_identifier(_),_Arg,true).
4512 type_def_case_condition(DefCase,Arg,UnrollArg,Mode,Condition) :-
4513 ( nonvar(DefCase) ->
4514 functor(DefCase,F,A),
4516 Condition = (Arg = DefCase)
4518 Condition = functor(Arg,F,A)
4519 ; functor(UnrollArg,F,A) ->
4520 Condition = (functor(Arg,F,A),Arg=Template,ArgsCondition),
4521 DefCase =.. [_|ArgTypes],
4522 UnrollArg =.. [_|UnrollArgs],
4523 functor(Template,F,A),
4524 Template =.. [_|TemplateArgs],
4525 replicate(A,Mode,ArgModes),
4526 types_condition(ArgTypes,TemplateArgs,UnrollArgs,ArgModes,ArgsCondition)
4528 Condition = functor(Arg,F,A)
4531 chr_error(internal,'Illegal type definition (must be nonvar).\n',[])
4535 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4536 % Static type checking
4537 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4538 % Checks head constraints and CHR constraint calls in bodies.
4541 % - type clashes involving built-in types
4542 % - Prolog built-ins in guard and body
4543 % - indicate position in terms in error messages
4544 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4546 static_type_check/0.
4548 :- chr_type type_error_src ---> head(any) ; body(any).
4550 rule(_,Rule), static_type_check
4552 copy_term_nat(Rule,RuleCopy),
4553 RuleCopy = pragma(rule(Head1,Head2,G,Body),ids(IDs1,IDs2),Pragmas,Name,RuleNb),
4556 ( static_type_check_heads(Head1),
4557 static_type_check_heads(Head2),
4558 conj2list(Body,GoalList),
4559 static_type_check_body(GoalList)
4562 ( Error = invalid_functor(Src,Term,Type) ->
4563 chr_error(type_error,'Invalid functor in ~@ of ~@:\n\t\tfound `~w\',\n\t\texpected type `~w\'!\n',
4564 [chr_translate:format_src(Src),format_rule(Rule),Term,Type])
4565 ; Error = type_clash(Var,Src1,Src2,Type1,Type2) ->
4566 chr_error(type_error,'Type clash for variable ~w in ~@:\n\t\texpected type ~w in ~@\n\t\texpected type ~w in ~@\n',
4567 [Var,format_rule(Rule),Type1,chr_translate:format_src(Src1),Type2,chr_translate:format_src(Src2)])
4570 fail % cleanup constraints
4576 static_type_check <=> true.
4578 static_type_check_heads([]).
4579 static_type_check_heads([Head|Heads]) :-
4580 static_type_check_head(Head),
4581 static_type_check_heads(Heads).
4583 static_type_check_head(Head) :-
4585 get_constraint_type_det(F/A,Types),
4587 maplist(static_type_check_term(head(Head)),Args,Types).
4589 static_type_check_body([]).
4590 static_type_check_body([Goal|Goals]) :-
4592 get_constraint_type_det(F/A,Types),
4594 maplist(static_type_check_term(body(Goal)),Args,Types),
4595 static_type_check_body(Goals).
4597 :- chr_constraint static_type_check_term/3.
4598 :- chr_option(mode,static_type_check_term(?,?,?)).
4599 :- chr_option(type_declaration,static_type_check_term(type_error_src,any,any)).
4601 static_type_check_term(Src,Term,Type)
4605 static_type_check_var(Src,Term,Type).
4606 static_type_check_term(Src,Term,Type)
4608 atomic_builtin_type(Type,Term,Goal)
4613 throw(type_error(invalid_functor(Src,Term,Type)))
4615 static_type_check_term(Src,Term,Type)
4617 compound_builtin_type(Type,Term,Goal)
4622 throw(type_error(invalid_functor(Src,Term,Type)))
4624 type_alias(AType,ADef) \ static_type_check_term(Src,Term,Type)
4629 copy_term_nat(AType-ADef,Type-Def),
4630 static_type_check_term(Src,Term,Def).
4632 type_definition(AType,ADef) \ static_type_check_term(Src,Term,Type)
4637 copy_term_nat(AType-ADef,Type-Variants),
4638 functor(Term,TF,TA),
4639 ( member(Variant,Variants), functor(Variant,TF,TA) ->
4641 Variant =.. [_|Types],
4642 maplist(static_type_check_term(Src),Args,Types)
4644 throw(type_error(invalid_functor(Src,Term,Type)))
4647 static_type_check_term(Src,Term,Type)
4649 chr_error(internal,'Undefined type ~w while type checking term ~w in ~@.\n',[Type,Term,chr_translate:format_src(Src)]).
4651 :- chr_constraint static_type_check_var/3.
4652 :- chr_option(mode,static_type_check_var(?,-,?)).
4653 :- chr_option(type_declaration,static_type_check_term(type_error_src,any,any)).
4655 type_alias(AType,ADef) \ static_type_check_var(Src,Var,Type)
4660 copy_term_nat(AType-ADef,Type-Def),
4661 static_type_check_var(Src,Var,Def).
4663 static_type_check_var(Src,Var,Type)
4665 atomic_builtin_type(Type,_,_)
4667 static_atomic_builtin_type_check_var(Src,Var,Type).
4669 static_type_check_var(Src,Var,Type)
4671 compound_builtin_type(Type,_,_)
4676 static_type_check_var(Src1,Var,Type1), static_type_check_var(Src2,Var,Type2)
4680 throw(type_error(type_clash(Var,Src1,Src2,Type1,Type2))).
4682 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
4683 %% static_atomic_builtin_type_check_var(+type_error_src,-Var,+atomic_builtin_type)
4684 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
4685 :- chr_constraint static_atomic_builtin_type_check_var/3.
4686 :- chr_option(mode,static_type_check_var(?,-,+)).
4687 :- chr_option(type_declaration,static_type_check_term(type_error_src,any,atomic_builtin_type)).
4689 static_atomic_builtin_type_check_var(_,_,any) <=> true.
4690 static_atomic_builtin_type_check_var(_,Var,BuiltinType) \ static_atomic_builtin_type_check_var(_,Var,BuiltinType)
4693 static_atomic_builtin_type_check_var(_,Var,float) \ static_atomic_builtin_type_check_var(_,Var,number)
4696 static_atomic_builtin_type_check_var(_,Var,int) \ static_atomic_builtin_type_check_var(_,Var,number)
4699 static_atomic_builtin_type_check_var(_,Var,natural) \ static_atomic_builtin_type_check_var(_,Var,number)
4702 static_atomic_builtin_type_check_var(_,Var,dense_int) \ static_atomic_builtin_type_check_var(_,Var,number)
4705 static_atomic_builtin_type_check_var(_,Var,natural) \ static_atomic_builtin_type_check_var(_,Var,int)
4708 static_atomic_builtin_type_check_var(_,Var,dense_int) \ static_atomic_builtin_type_check_var(_,Var,int)
4711 static_atomic_builtin_type_check_var(_,Var,dense_int) \ static_atomic_builtin_type_check_var(_,Var,natural)
4714 static_atomic_builtin_type_check_var(Src1,Var,Type1), static_atomic_builtin_type_check_var(Src2,Var,Type2)
4716 throw(type_error(type_clash(Var,Src1,Src2,Type1,Type2))).
4718 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
4719 %% format_src(+type_error_src) is det.
4720 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
4721 format_src(head(Head)) :- format('head ~w',[Head]).
4722 format_src(body(Goal)) :- format('body goal ~w',[Goal]).
4724 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4725 % Dynamic type checking
4726 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4729 dynamic_type_check/0,
4730 dynamic_type_check_clauses/1,
4731 get_dynamic_type_check_clauses/1.
4733 generate_dynamic_type_check_clauses(Clauses) :-
4734 ( chr_pp_flag(debugable,on) ->
4736 get_dynamic_type_check_clauses(Clauses0),
4738 [('$dynamic_type_check'(Type,Term) :-
4739 throw(error(type_error(Type,Term),context(_,'CHR Runtime Type Error')))
4746 type_definition(T,D), dynamic_type_check
4748 copy_term_nat(T-D,Type-Definition),
4749 maplist(dynamic_type_check_clause(Type),Definition,DynamicChecks),
4750 dynamic_type_check_clauses(DynamicChecks).
4751 type_alias(A,B), dynamic_type_check
4753 copy_term_nat(A-B,Alias-Body),
4754 dynamic_type_check_alias_clause(Alias,Body,Clause),
4755 dynamic_type_check_clauses([Clause]).
4757 dynamic_type_check <=>
4759 ('$dynamic_type_check'(Type,Term) :- Goal),
4760 ( atomic_builtin_type(Type,Term,Goal) ; compound_builtin_type(Type,Term,Goal) ),
4763 dynamic_type_check_clauses(BuiltinChecks).
4765 dynamic_type_check_clause(T,DC,Clause) :-
4766 copy_term(T-DC,Type-DefinitionClause),
4767 functor(DefinitionClause,F,A),
4769 DefinitionClause =.. [_|DCArgs],
4770 Term =.. [_|TermArgs],
4771 maplist(dynamic_type_check_call,DCArgs,TermArgs,RecursiveCallList),
4772 list2conj(RecursiveCallList,RecursiveCalls),
4774 '$dynamic_type_check'(Type,Term) :-
4778 dynamic_type_check_alias_clause(Alias,Body,Clause) :-
4780 '$dynamic_type_check'(Alias,Term) :-
4781 '$dynamic_type_check'(Body,Term)
4784 dynamic_type_check_call(Type,Term,Call) :-
4785 % ( nonvar(Type), atomic_builtin_type(Type,Term,Goal) ->
4786 % Call = when(nonvar(Term),Goal)
4787 % ; nonvar(Type), compound_builtin_type(Type,Term,Goal) ->
4788 % Call = when(nonvar(Term),Goal)
4793 Call = when(nonvar(Term),once('$dynamic_type_check'(Type,Term)))
4798 dynamic_type_check_clauses(C1), dynamic_type_check_clauses(C2)
4801 dynamic_type_check_clauses(C).
4803 get_dynamic_type_check_clauses(Q), dynamic_type_check_clauses(C)
4806 get_dynamic_type_check_clauses(Q)
4810 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4812 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4813 % Some optimizations can be applied for atomic types...
4814 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4816 atomic_types_suspended_constraint(C) :-
4818 get_constraint_type(C,ArgTypes),
4819 get_constraint_mode(C,ArgModes),
4820 findall(I,between(1,N,I),Indexes),
4821 maplist(atomic_types_suspended_constraint(C),ArgTypes,ArgModes,Indexes).
4823 atomic_types_suspended_constraint(C,Type,Mode,Index) :-
4824 ( is_indexed_argument(C,Index) ->
4834 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
4835 %% atomic_type(+Type) is semidet.
4837 % Succeeds when all values of =Type= are atomic.
4838 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
4839 :- chr_constraint atomic_type/1.
4841 atomic_type(Type) <=> atomic_builtin_type(Type,_,_) | Type \== any.
4843 type_definition(TypePat,Def) \ atomic_type(Type)
4845 functor(Type,F,A), functor(TypePat,F,A)
4847 forall(member(Term,Def),atomic(Term)).
4849 type_alias(TypePat,Alias) \ atomic_type(Type)
4851 functor(Type,F,A), functor(TypePat,F,A)
4854 copy_term_nat(TypePat-Alias,Type-NType),
4857 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4860 stored/3, % constraint,occurrence,(yes/no/maybe)
4861 stored_completing/3,
4864 is_finally_stored/1,
4865 check_all_passive/2.
4867 :- chr_option(mode,stored(+,+,+)).
4868 :- chr_option(type_declaration,stored(any,int,storedinfo)).
4869 :- chr_option(type_definition,type(storedinfo,[yes,no,maybe])).
4870 :- chr_option(mode,stored_complete(+,+,+)).
4871 :- chr_option(mode,maybe_complementary_guards(+,+,?,?)).
4872 :- chr_option(mode,guard_list(+,+,+,+)).
4873 :- chr_option(mode,check_all_passive(+,+)).
4875 % change yes in maybe when yes becomes passive
4876 passive(RuleNb,ID), occurrence(C,O,RuleNb,ID,_) \
4877 stored(C,O,yes), stored_complete(C,RO,Yesses)
4878 <=> O < RO | NYesses is Yesses - 1,
4879 stored(C,O,maybe), stored_complete(C,RO,NYesses).
4880 % change yes in maybe when not observed
4881 ai_not_observed(C,O) \ stored(C,O,yes), stored_complete(C,RO,Yesses)
4883 NYesses is Yesses - 1,
4884 stored(C,O,maybe), stored_complete(C,RO,NYesses).
4886 occurrence(_,_,RuleNb,ID,_), occurrence(C2,_,RuleNb,_,_), stored_complete(C2,RO,0), max_occurrence(C2,MO2)
4887 ==> RO =< MO2 | % C2 is never stored
4893 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4895 rule(RuleNb,Rule),passive(RuleNb,Id) ==>
4896 Rule = pragma(rule(Head1,Head2,G,B),ids([Id|IDs1],IDs2),Pragmas,Name,RuleNb) |
4897 append(IDs1,IDs2,I), check_all_passive(RuleNb,I).
4899 rule(RuleNb,Rule),passive(RuleNb,Id) ==>
4900 Rule = pragma(rule(Head1,Head2,G,B),ids([],[Id|IDs2]),Pragmas,Name,RuleNb) |
4901 check_all_passive(RuleNb,IDs2).
4903 passive(RuleNb,Id) \ check_all_passive(RuleNb,[Id|IDs]) <=>
4904 check_all_passive(RuleNb,IDs).
4906 rule(RuleNb,Rule) \ check_all_passive(RuleNb,[]) <=>
4907 chr_warning(weird_program,'All heads passive in ~@.\n\tThis rule never fires. Please check your program.\n',[format_rule(Rule)]).
4909 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4911 % collect the storage information
4912 stored(C,O,yes) \ stored_completing(C,O,Yesses)
4913 <=> NO is O + 1, NYesses is Yesses + 1,
4914 stored_completing(C,NO,NYesses).
4915 stored(C,O,maybe) \ stored_completing(C,O,Yesses)
4917 stored_completing(C,NO,Yesses).
4919 stored(C,O,no) \ stored_completing(C,O,Yesses)
4920 <=> stored_complete(C,O,Yesses).
4921 stored_completing(C,O,Yesses)
4922 <=> stored_complete(C,O,Yesses).
4924 stored_complete(C,O,Yesses), occurrence(C,O2,RuleNb,Id,_) ==>
4925 O2 > O | passive(RuleNb,Id).
4927 % decide whether a constraint is stored
4928 max_occurrence(C,MO), stored_complete(C,RO,0) \ is_stored(C)
4929 <=> RO =< MO | fail.
4930 is_stored(C) <=> true.
4932 % decide whether a constraint is suspends after occurrences
4933 max_occurrence(C,MO), stored_complete(C,RO,_) \ is_finally_stored(C)
4934 <=> RO =< MO | fail.
4935 is_finally_stored(C) <=> true.
4937 storage_analysis(Constraints) :-
4938 ( chr_pp_flag(storage_analysis,on) ->
4939 check_constraint_storages(Constraints)
4944 check_constraint_storages([]).
4945 check_constraint_storages([C|Cs]) :-
4946 check_constraint_storage(C),
4947 check_constraint_storages(Cs).
4949 check_constraint_storage(C) :-
4950 get_max_occurrence(C,MO),
4951 check_occurrences_storage(C,1,MO).
4953 check_occurrences_storage(C,O,MO) :-
4955 stored_completing(C,1,0)
4957 check_occurrence_storage(C,O),
4959 check_occurrences_storage(C,NO,MO)
4962 check_occurrence_storage(C,O) :-
4963 get_occurrence(C,O,RuleNb,ID),
4964 ( is_passive(RuleNb,ID) ->
4967 get_rule(RuleNb,PragmaRule),
4968 PragmaRule = pragma(rule(Heads1,Heads2,Guard,Body),ids(IDs1,IDs2),_,_,_),
4969 ( select2(ID,Head1,IDs1,Heads1,RIDs1,RHeads1) ->
4970 check_storage_head1(Head1,O,Heads1,Heads2,Guard)
4971 ; select2(ID,Head2,IDs2,Heads2,RIDs2,RHeads2) ->
4972 check_storage_head2(Head2,O,Heads1,Body)
4976 check_storage_head1(Head,O,H1,H2,G) :-
4981 guard_entailment:entails_guard([chr_pp_headvariables(Head)],G),
4983 no_matching(L,[]) ->
4990 no_matching([X|Xs],Prev) :-
4992 \+ memberchk_eq(X,Prev),
4993 no_matching(Xs,[X|Prev]).
4995 check_storage_head2(Head,O,H1,B) :-
4999 ( H1 \== [], B == true )
5001 % \+ is_observed(F/A,O) % always fails because observation analysis has not been performed yet
5009 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5011 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5012 %% ____ _ ____ _ _ _ _
5013 %% | _ \ _ _| | ___ / ___|___ _ __ ___ _ __ (_) | __ _| |_(_) ___ _ __
5014 %% | |_) | | | | |/ _ \ | | / _ \| '_ ` _ \| '_ \| | |/ _` | __| |/ _ \| '_ \
5015 %% | _ <| |_| | | __/ | |__| (_) | | | | | | |_) | | | (_| | |_| | (_) | | | |
5016 %% |_| \_\\__,_|_|\___| \____\___/|_| |_| |_| .__/|_|_|\__,_|\__|_|\___/|_| |_|
5019 constraints_code(Constraints,Clauses) :-
5020 (chr_pp_flag(reduced_indexing,on),
5021 \+ forsome(C,Constraints,\+ chr_translate:only_ground_indexed_arguments(C)) ->
5022 none_suspended_on_variables
5026 constraints_code1(Constraints,Clauses,[]).
5028 %===============================================================================
5029 :- chr_constraint constraints_code1/3.
5030 :- chr_option(mode,constraints_code1(+,+,+)).
5031 :- chr_option(type_declaration,constraints_code(list,any,any)).
5032 %-------------------------------------------------------------------------------
5033 constraints_code1([],L,T) <=> L = T.
5034 constraints_code1([C|RCs],L,T)
5036 constraint_code(C,L,T1),
5037 constraints_code1(RCs,T1,T).
5038 %===============================================================================
5039 :- chr_constraint constraint_code/3.
5040 :- chr_option(mode,constraint_code(+,+,+)).
5041 %-------------------------------------------------------------------------------
5042 %% Generate code for a single CHR constraint
5043 constraint_code(Constraint, L, T)
5045 | ( (chr_pp_flag(debugable,on) ;
5046 is_stored(Constraint), ( has_active_occurrence(Constraint); chr_pp_flag(late_allocation,off)),
5047 ( may_trigger(Constraint) ;
5048 get_allocation_occurrence(Constraint,AO),
5049 get_max_occurrence(Constraint,MO), MO >= AO ) )
5051 constraint_prelude(Constraint,Clause),
5057 occurrences_code(Constraint,1,Id,NId,L1,L2),
5058 gen_cond_attach_clause(Constraint,NId,L2,T).
5060 %===============================================================================
5061 %% Generate prelude predicate for a constraint.
5062 %% f(...) :- f/a_0(...,Susp).
5063 constraint_prelude(F/A, Clause) :-
5064 vars_susp(A,Vars,Susp,VarsSusp),
5065 Head =.. [ F | Vars],
5066 make_suspension_continuation_goal(F/A,VarsSusp,Continuation),
5067 build_head(F,A,[0],VarsSusp,Delegate),
5068 ( chr_pp_flag(debugable,on) ->
5069 insert_constraint_goal(F/A,Susp,Vars,InsertCall),
5070 attach_constraint_atom(F/A,Vars2,Susp,AttachCall),
5071 delay_phase_end(validate_store_type_assumptions,chr_translate:update_suspension_field(F/A,Susp,state,inactive,Inactive)),
5072 insert_constraint_internal_constraint_goal(F/A, Vars2, Susp, Continuation, Vars,InsertGoal),
5074 ( get_constraint_type(F/A,ArgTypeList) ->
5075 maplist(dynamic_type_check_call,ArgTypeList,Vars,DynamicTypeCheckList),
5076 list2conj(DynamicTypeCheckList,DynamicTypeChecks)
5078 DynamicTypeChecks = true
5088 'chr debug_event'(insert(Head#Susp)),
5090 'chr debug_event'(call(Susp)),
5093 'chr debug_event'(fail(Susp)), !,
5097 'chr debug_event'(exit(Susp))
5099 'chr debug_event'(redo(Susp)),
5103 ; get_allocation_occurrence(F/A,0) ->
5104 gen_insert_constraint_internal_goal(F/A,Goal,VarsSusp,Vars,Susp),
5105 delay_phase_end(validate_store_type_assumptions,chr_translate:update_suspension_field(F/A,Susp,state,inactive,Inactive)),
5106 Clause = ( Head :- Goal, Inactive, Delegate )
5108 Clause = ( Head :- Delegate )
5111 make_suspension_continuation_goal(F/A,VarsSusp,Goal) :-
5112 ( may_trigger(F/A) ->
5113 build_head(F,A,[0],VarsSusp,Delegate),
5114 ( chr_pp_flag(debugable,off) ->
5117 get_target_module(Mod),
5124 %===============================================================================
5125 :- chr_constraint has_active_occurrence/1, has_active_occurrence/2.
5126 :- chr_option(mode,has_active_occurrence(+)).
5127 :- chr_option(mode,has_active_occurrence(+,+)).
5128 %-------------------------------------------------------------------------------
5129 has_active_occurrence(C) <=> has_active_occurrence(C,1).
5131 max_occurrence(C,MO) \ has_active_occurrence(C,O) <=>
5133 passive(RuleNb,ID),occurrence(C,O,RuleNb,ID,_) \
5134 has_active_occurrence(C,O) <=>
5136 has_active_occurrence(C,NO).
5137 has_active_occurrence(C,O) <=> true.
5138 %===============================================================================
5140 gen_cond_attach_clause(F/A,Id,L,T) :-
5141 ( is_finally_stored(F/A) ->
5142 get_allocation_occurrence(F/A,AllocationOccurrence),
5143 get_max_occurrence(F/A,MaxOccurrence),
5144 ( chr_pp_flag(debugable,off), MaxOccurrence < AllocationOccurrence ->
5145 ( only_ground_indexed_arguments(F/A) ->
5146 gen_insert_constraint_internal_goal(F/A,Body,AllArgs,Args,Susp)
5148 gen_cond_attach_goal(F/A,Body,AllArgs,Args,Susp)
5150 ; vars_susp(A,Args,Susp,AllArgs),
5151 gen_uncond_attach_goal(F/A,Susp,Args,Body,_)
5153 build_head(F,A,Id,AllArgs,Head),
5154 Clause = ( Head :- Body ),
5160 :- chr_constraint use_auxiliary_predicate/1.
5161 :- chr_option(mode,use_auxiliary_predicate(+)).
5163 :- chr_constraint use_auxiliary_predicate/2.
5164 :- chr_option(mode,use_auxiliary_predicate(+,+)).
5166 :- chr_constraint is_used_auxiliary_predicate/1.
5167 :- chr_option(mode,is_used_auxiliary_predicate(+)).
5169 :- chr_constraint is_used_auxiliary_predicate/2.
5170 :- chr_option(mode,is_used_auxiliary_predicate(+,+)).
5173 use_auxiliary_predicate(P) \ use_auxiliary_predicate(P) <=> true.
5175 use_auxiliary_predicate(P,C) \ use_auxiliary_predicate(P,C) <=> true.
5177 use_auxiliary_predicate(P) \ is_used_auxiliary_predicate(P) <=> true.
5179 use_auxiliary_predicate(P,_) \ is_used_auxiliary_predicate(P) <=> true.
5181 is_used_auxiliary_predicate(P) <=> fail.
5183 use_auxiliary_predicate(P) \ is_used_auxiliary_predicate(P,_) <=> true.
5184 use_auxiliary_predicate(P,C) \ is_used_auxiliary_predicate(P,C) <=> true.
5186 is_used_auxiliary_predicate(P,C) <=> fail.
5188 %------------------------------------------------------------------------------%
5189 % Only generate import statements for actually used modules.
5190 %------------------------------------------------------------------------------%
5192 :- chr_constraint use_auxiliary_module/1.
5193 :- chr_option(mode,use_auxiliary_module(+)).
5195 :- chr_constraint is_used_auxiliary_module/1.
5196 :- chr_option(mode,is_used_auxiliary_module(+)).
5199 use_auxiliary_module(P) \ use_auxiliary_module(P) <=> true.
5201 use_auxiliary_module(P) \ is_used_auxiliary_module(P) <=> true.
5203 is_used_auxiliary_module(P) <=> fail.
5205 % only called for constraints with
5207 % non-ground indexed argument
5208 gen_cond_attach_goal(F/A,Goal,AllArgs,Args,Susp) :-
5209 vars_susp(A,Args,Susp,AllArgs),
5210 make_suspension_continuation_goal(F/A,AllArgs,Closure),
5211 ( get_store_type(F/A,var_assoc_store(_,_)) ->
5214 attach_constraint_atom(F/A,Vars,Susp,Attach)
5217 insert_constraint_goal(F/A,Susp,Args,InsertCall),
5218 insert_constraint_internal_constraint_goal(F/A, Vars, Susp, Closure, Args,InsertGoal),
5219 ( may_trigger(F/A) ->
5220 activate_constraint_goal(F/A,(InsertCall,Attach),Vars,Susp,_,ActivateGoal),
5224 InsertGoal, % insert_constraint_internal(Stored,Vars,Susp,Closure,F,Args)
5228 ActivateGoal % activate_constraint(Stored,Vars,Susp,_)
5234 InsertGoal, % insert_constraint_internal(Stored,Vars,Susp,Closure,F,Args),
5240 gen_insert_constraint_internal_goal(F/A,Goal,AllArgs,Args,Susp) :-
5241 vars_susp(A,Args,Susp,AllArgs),
5242 make_suspension_continuation_goal(F/A,AllArgs,Cont),
5243 ( \+ only_ground_indexed_arguments(F/A), \+ get_store_type(F/A,var_assoc_store(_,_)) ->
5244 attach_constraint_atom(F/A,Vars,Susp,Attach)
5249 insert_constraint_goal(F/A,Susp,Args,InsertCall),
5250 insert_constraint_internal_constraint_goal(F/A, Vars, Susp, Cont, Args,InsertInternalGoal),
5251 ( only_ground_indexed_arguments(F/A), chr_pp_flag(debugable,off) ->
5254 InsertInternalGoal, % insert_constraint_internal(Susp,F,Args),
5260 InsertInternalGoal, % insert_constraint_internal(_,Vars,Susp,Cont,F,Args),
5266 gen_uncond_attach_goal(FA,Susp,Args,AttachGoal,Generation) :-
5267 ( \+ only_ground_indexed_arguments(FA), \+ get_store_type(FA,var_assoc_store(_,_)) ->
5268 attach_constraint_atom(FA,Vars,Susp,Attach)
5272 insert_constraint_goal(FA,Susp,Args,InsertCall),
5273 ( chr_pp_flag(late_allocation,on) ->
5274 activate_constraint_goal(FA,(InsertCall,Attach),Vars,Susp,Generation,AttachGoal)
5276 activate_constraint_goal(FA,true,Vars,Susp,Generation,AttachGoal)
5279 %-------------------------------------------------------------------------------
5280 :- chr_constraint occurrences_code/6.
5281 :- chr_option(mode,occurrences_code(+,+,+,+,+,+)).
5282 %-------------------------------------------------------------------------------
5283 max_occurrence(C,MO) \ occurrences_code(C,O,Id,NId,L,T)
5286 occurrences_code(C,O,Id,NId,L,T)
5288 occurrence_code(C,O,Id,Id1,L,L1),
5290 occurrences_code(C,NO,Id1,NId,L1,T).
5291 %-------------------------------------------------------------------------------
5292 :- chr_constraint occurrence_code/6.
5293 :- chr_option(mode,occurrence_code(+,+,+,+,+,+)).
5294 %-------------------------------------------------------------------------------
5295 occurrence(C,O,RuleNb,ID,_), passive(RuleNb,ID) \ occurrence_code(C,O,Id,NId,L,T)
5297 ( named_history(RuleNb,_,_) ->
5298 does_use_history(C,O)
5304 occurrence(C,O,RuleNb,ID,_), rule(RuleNb,PragmaRule) \ occurrence_code(C,O,Id,NId,L,T)
5306 PragmaRule = pragma(rule(Heads1,Heads2,_,_),ids(IDs1,IDs2),_,_,_),
5307 ( select2(ID,Head1,IDs1,Heads1,RIDs1,RHeads1) ->
5309 head1_code(Head1,ID,RHeads1,RIDs1,PragmaRule,C,O,Id,L,T)
5310 ; select2(ID,Head2,IDs2,Heads2,RIDs2,RHeads2) ->
5311 head2_code(Head2,ID,RHeads2,RIDs2,PragmaRule,C,O,Id,L,L1),
5313 ( unconditional_occurrence(C,O) ->
5316 gen_alloc_inc_clause(C,O,Id,L1,T)
5320 occurrence_code(C,O,_,_,_,_)
5322 chr_error(internal,'occurrence_code/6: missing information to compile ~w:~w\n',[C,O]).
5323 %-------------------------------------------------------------------------------
5325 %% Generate code based on one removed head of a CHR rule
5326 head1_code(Head,ID,OtherHeads,OtherIDs,PragmaRule,FA,O,Id,L,T) :-
5327 PragmaRule = pragma(Rule,_,_,_Name,RuleNb),
5328 Rule = rule(_,Head2,_,_),
5330 reorder_heads(RuleNb,Head,OtherHeads,OtherIDs,NOtherHeads,NOtherIDs),
5331 simplification_code(Head,ID,NOtherHeads,NOtherIDs,PragmaRule,FA,O,Id,L,T)
5333 simpagation_head1_code(Head,ID,OtherHeads,OtherIDs,PragmaRule,FA,O,Id,L,T)
5336 %% Generate code based on one persistent head of a CHR rule
5337 head2_code(Head,ID,OtherHeads,OtherIDs,PragmaRule,FA,O,Id,L,T) :-
5338 PragmaRule = pragma(Rule,_,_,_Name,RuleNb),
5339 Rule = rule(Head1,_,_,_),
5341 reorder_heads(RuleNb,Head,OtherHeads,OtherIDs,NOtherHeads,NOtherIDs),
5342 propagation_code(Head,ID,NOtherHeads,NOtherIDs,Rule,RuleNb,FA,O,Id,L,T)
5344 simpagation_head2_code(Head,ID,OtherHeads,OtherIDs,PragmaRule,FA,O,Id,L,T)
5347 gen_alloc_inc_clause(F/A,O,Id,L,T) :-
5348 vars_susp(A,Vars,Susp,VarsSusp),
5349 build_head(F,A,Id,VarsSusp,Head),
5351 build_head(F,A,IncId,VarsSusp,CallHead),
5352 gen_occ_allocation(F/A,O,Vars,Susp,ConditionalAlloc),
5361 gen_occ_allocation(FA,O,Vars,Susp,Goal) :-
5362 get_allocation_occurrence(FA,AO),
5363 ( chr_pp_flag(debugable,off), O == AO ->
5364 allocate_constraint_goal(FA,Susp,Vars,Goal0),
5365 ( may_trigger(FA) ->
5366 Goal = (var(Susp) -> Goal0 ; true)
5374 gen_occ_allocation_in_guard(FA,O,Vars,Susp,Goal) :-
5375 get_allocation_occurrence(FA,AO),
5376 ( chr_pp_flag(debugable,off), O < AO ->
5377 allocate_constraint_goal(FA,Susp,Vars,Goal0),
5378 ( may_trigger(FA) ->
5379 Goal = (var(Susp) -> Goal0 ; true)
5387 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5389 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5391 % Reorders guard goals with respect to partner constraint retrieval goals and
5392 % active constraint. Returns combined partner retrieval + guard goal.
5394 guard_via_reschedule_new(Retrievals,GuardList,Prelude,GuardListSkeleton,LookupSkeleton,GoalSkeleton) :-
5395 ( chr_pp_flag(guard_via_reschedule,on) ->
5396 guard_via_reschedule_main_new(Retrievals,GuardList,Prelude,GuardListSkeleton,LookupSkeleton,ScheduleSkeleton),
5397 list2conj(ScheduleSkeleton,GoalSkeleton)
5399 length(Retrievals,RL), length(LookupSkeleton,RL),
5400 length(GuardList,GL), length(GuardListSkeleton,GL),
5401 append(LookupSkeleton,GuardListSkeleton,GoalListSkeleton),
5402 list2conj(GoalListSkeleton,GoalSkeleton)
5404 guard_via_reschedule_main_new(PartnerLookups,GuardList,ActiveHead,
5405 GuardListSkeleton,LookupSkeleton,ScheduleSkeleton) :-
5406 initialize_unit_dictionary(ActiveHead,Dict),
5407 maplist(wrap_in_functor(lookup),PartnerLookups,WrappedPartnerLookups),
5408 maplist(wrap_in_functor(guard),GuardList,WrappedGuardList),
5409 build_units(WrappedPartnerLookups,WrappedGuardList,Dict,Units),
5410 dependency_reorder(Units,NUnits),
5411 wrappedunits2lists(NUnits,IndexedGuardListSkeleton,LookupSkeleton,ScheduleSkeleton),
5412 sort(IndexedGuardListSkeleton,SortedIndexedGuardListSkeleton),
5413 snd_of_pairs(SortedIndexedGuardListSkeleton,GuardListSkeleton).
5415 wrap_in_functor(Functor,X,Term) :-
5416 Term =.. [Functor,X].
5418 wrappedunits2lists([],[],[],[]).
5419 wrappedunits2lists([unit(N,WrappedGoal,_,_)|Units],Gs,Ls,Ss) :-
5420 Ss = [GoalCopy|TSs],
5421 ( WrappedGoal = lookup(Goal) ->
5422 Ls = [GoalCopy|TLs],
5424 ; WrappedGoal = guard(Goal) ->
5425 Gs = [N-GoalCopy|TGs],
5428 wrappedunits2lists(Units,TGs,TLs,TSs).
5430 guard_splitting(Rule,SplitGuardList) :-
5431 Rule = rule(H1,H2,Guard,_),
5432 append(H1,H2,Heads),
5433 conj2list(Guard,GuardList),
5434 term_variables(Heads,HeadVars),
5435 split_off_simple_guard_new(GuardList,HeadVars,GuardPrefix,RestGuardList),
5436 append(GuardPrefix,[RestGuard],SplitGuardList),
5437 term_variables(RestGuardList,GuardVars1),
5438 % variables that are declared to be ground don't need to be locked
5439 ground_vars(Heads,GroundVars),
5440 list_difference_eq(HeadVars,GroundVars,LockableHeadVars),
5441 intersect_eq(LockableHeadVars,GuardVars1,GuardVars),
5442 ( chr_pp_flag(guard_locks,on),
5443 bagof(('chr lock'(X)) - ('chr unlock'(X)), (lists:member(X,GuardVars)), LocksUnlocks) ->
5444 once(pairup(Locks,Unlocks,LocksUnlocks))
5449 list2conj(Locks,LockPhase),
5450 list2conj(Unlocks,UnlockPhase),
5451 list2conj(RestGuardList,RestGuard1),
5452 RestGuard = (LockPhase,(RestGuard1,UnlockPhase)).
5454 guard_body_copies3(Rule,GuardList,VarDict,GuardCopyList,BodyCopy) :-
5455 Rule = rule(_,_,_,Body),
5456 my_term_copy(GuardList,VarDict,VarDict2,GuardCopyList),
5457 my_term_copy(Body,VarDict2,BodyCopy).
5460 split_off_simple_guard_new([],_,[],[]).
5461 split_off_simple_guard_new([G|Gs],VarDict,S,C) :-
5462 ( simple_guard_new(G,VarDict) ->
5464 split_off_simple_guard_new(Gs,VarDict,Ss,C)
5470 % simple guard: cheap and benign (does not bind variables)
5471 simple_guard_new(G,Vars) :-
5472 builtin_binds_b(G,BoundVars),
5473 \+ (( member(V,BoundVars),
5474 memberchk_eq(V,Vars)
5477 dependency_reorder(Units,NUnits) :-
5478 dependency_reorder(Units,[],NUnits).
5480 dependency_reorder([],Acc,Result) :-
5481 reverse(Acc,Result).
5483 dependency_reorder([Unit|Units],Acc,Result) :-
5484 Unit = unit(_GID,_Goal,Type,GIDs),
5488 dependency_insert(Acc,Unit,GIDs,NAcc)
5490 dependency_reorder(Units,NAcc,Result).
5492 dependency_insert([],Unit,_,[Unit]).
5493 dependency_insert([X|Xs],Unit,GIDs,L) :-
5494 X = unit(GID,_,_,_),
5495 ( memberchk(GID,GIDs) ->
5499 dependency_insert(Xs,Unit,GIDs,T)
5502 build_units(Retrievals,Guard,InitialDict,Units) :-
5503 build_retrieval_units(Retrievals,1,N,InitialDict,Dict,Units,Tail),
5504 build_guard_units(Guard,N,Dict,Tail).
5506 build_retrieval_units([],N,N,Dict,Dict,L,L).
5507 build_retrieval_units([U|Us],N,M,Dict,NDict,L,T) :-
5508 term_variables(U,Vs),
5509 update_unit_dictionary(Vs,N,Dict,Dict1,[],GIDs),
5510 L = [unit(N,U,fixed,GIDs)|L1],
5512 build_retrieval_units(Us,N1,M,Dict1,NDict,L1,T).
5514 initialize_unit_dictionary(Term,Dict) :-
5515 term_variables(Term,Vars),
5516 pair_all_with(Vars,0,Dict).
5518 update_unit_dictionary([],_,Dict,Dict,GIDs,GIDs).
5519 update_unit_dictionary([V|Vs],This,Dict,NDict,GIDs,NGIDs) :-
5520 ( lookup_eq(Dict,V,GID) ->
5521 ( (GID == This ; memberchk(GID,GIDs) ) ->
5528 Dict1 = [V - This|Dict],
5531 update_unit_dictionary(Vs,This,Dict1,NDict,GIDs1,NGIDs).
5533 build_guard_units(Guard,N,Dict,Units) :-
5535 Units = [unit(N,Goal,fixed,[])]
5536 ; Guard = [Goal|Goals] ->
5537 term_variables(Goal,Vs),
5538 update_unit_dictionary2(Vs,N,Dict,NDict,[],GIDs),
5539 Units = [unit(N,Goal,movable,GIDs)|RUnits],
5541 build_guard_units(Goals,N1,NDict,RUnits)
5544 update_unit_dictionary2([],_,Dict,Dict,GIDs,GIDs).
5545 update_unit_dictionary2([V|Vs],This,Dict,NDict,GIDs,NGIDs) :-
5546 ( lookup_eq(Dict,V,GID) ->
5547 ( (GID == This ; memberchk(GID,GIDs) ) ->
5552 Dict1 = [V - This|Dict]
5554 Dict1 = [V - This|Dict],
5557 update_unit_dictionary2(Vs,This,Dict1,NDict,GIDs1,NGIDs).
5559 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5561 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5563 %% / ___| ___| |_ / ___| ___ _ __ ___ __ _ _ __ | |_(_) ___ ___ _
5564 %% \___ \ / _ \ __| \___ \ / _ \ '_ ` _ \ / _` | '_ \| __| |/ __/ __(_)
5565 %% ___) | __/ |_ ___) | __/ | | | | | (_| | | | | |_| | (__\__ \_
5566 %% |____/ \___|\__| |____/ \___|_| |_| |_|\__,_|_| |_|\__|_|\___|___(_)
5569 %% | | | |_ __ (_) __ _ _ _ ___ |_ _|_ __ / _| ___ _ __ ___ _ __ ___ ___
5570 %% | | | | '_ \| |/ _` | | | |/ _ \ | || '_ \| |_ / _ \ '__/ _ \ '_ \ / __/ _ \
5571 %% | |_| | | | | | (_| | |_| | __/ | || | | | _| __/ | | __/ | | | (_| __/
5572 %% \___/|_| |_|_|\__, |\__,_|\___| |___|_| |_|_| \___|_| \___|_| |_|\___\___|
5575 functional_dependency/4,
5576 get_functional_dependency/4.
5578 :- chr_option(mode,functional_dependency(+,+,?,?)).
5579 :- chr_option(mode,get_functional_dependency(+,+,?,?)).
5581 allocation_occurrence(C,AO), occurrence(C,O,RuleNb,_,_) \ functional_dependency(C,RuleNb,Pattern,Key)
5585 functional_dependency(C,1,Pattern,Key).
5587 functional_dependency(C,RuleNb1,Pattern,Key) \ get_functional_dependency(C,RuleNb2,QPattern,QKey)
5591 QPattern = Pattern, QKey = Key.
5592 get_functional_dependency(_,_,_,_)
5596 functional_dependency_analysis(Rules) :-
5597 ( fail, chr_pp_flag(functional_dependency_analysis,on) ->
5598 functional_dependency_analysis_main(Rules)
5603 functional_dependency_analysis_main([]).
5604 functional_dependency_analysis_main([PRule|PRules]) :-
5605 ( discover_unique_pattern(PRule,C,RuleNb,Pattern,Key) ->
5606 functional_dependency(C,RuleNb,Pattern,Key)
5610 functional_dependency_analysis_main(PRules).
5612 discover_unique_pattern(PragmaRule,F/A,RuleNb,Pattern,Key) :-
5613 PragmaRule = pragma(Rule,_,_,Name,RuleNb),
5614 Rule = rule(H1,H2,Guard,_),
5622 check_unique_constraints(C1,C2,Guard,RuleNb,List),
5623 term_variables(C1,Vs),
5626 lookup_eq(List,V1,V2),
5629 select_pragma_unique_variables(Vs,List,Key1),
5630 copy_term_nat(C1-Key1,Pattern-Key),
5633 select_pragma_unique_variables([],_,[]).
5634 select_pragma_unique_variables([V|Vs],List,L) :-
5635 ( lookup_eq(List,V,_) ->
5640 select_pragma_unique_variables(Vs,List,T).
5642 % depends on functional dependency analysis
5643 % and shape of rule: C1 \ C2 <=> true.
5644 set_semantics_rules(Rules) :-
5645 ( fail, chr_pp_flag(set_semantics_rule,on) ->
5646 set_semantics_rules_main(Rules)
5651 set_semantics_rules_main([]).
5652 set_semantics_rules_main([R|Rs]) :-
5653 set_semantics_rule_main(R),
5654 set_semantics_rules_main(Rs).
5656 set_semantics_rule_main(PragmaRule) :-
5657 PragmaRule = pragma(Rule,IDs,Pragmas,_,RuleNb),
5658 ( Rule = rule([C1],[C2],true,_),
5659 IDs = ids([ID1],[ID2]),
5660 \+ is_passive(RuleNb,ID1),
5662 get_functional_dependency(F/A,RuleNb,Pattern,Key),
5663 copy_term_nat(Pattern-Key,C1-Key1),
5664 copy_term_nat(Pattern-Key,C2-Key2),
5671 check_unique_constraints(C1,C2,G,RuleNb,List) :-
5672 \+ any_passive_head(RuleNb),
5673 variable_replacement(C1-C2,C2-C1,List),
5674 copy_with_variable_replacement(G,OtherG,List),
5676 once(entails_b(NotG,OtherG)).
5678 % checks for rules of the shape ...,C1,C2... (<|=)=> ...
5679 % where C1 and C2 are symmteric constraints
5680 symmetry_analysis(Rules) :-
5681 ( chr_pp_flag(check_unnecessary_active,off) ->
5684 symmetry_analysis_main(Rules)
5687 symmetry_analysis_main([]).
5688 symmetry_analysis_main([R|Rs]) :-
5689 R = pragma(Rule,ids(IDs1,IDs2),_,_,RuleNb),
5690 Rule = rule(H1,H2,_,_),
5691 ( ( \+ chr_pp_flag(check_unnecessary_active,simplification) ; H2 == [] ), H1 \== [] ->
5692 symmetry_analysis_heads_simplification(H1,IDs1,[],[],Rule,RuleNb),
5693 symmetry_analysis_heads_propagation(H2,IDs2,[],[],Rule,RuleNb)
5697 symmetry_analysis_main(Rs).
5699 symmetry_analysis_heads_simplification([],[],_,_,_,_).
5700 symmetry_analysis_heads_simplification([H|Hs],[ID|IDs],PreHs,PreIDs,Rule,RuleNb) :-
5701 ( \+ is_passive(RuleNb,ID),
5702 member2(PreHs,PreIDs,PreH-PreID),
5703 \+ is_passive(RuleNb,PreID),
5704 variable_replacement(PreH,H,List),
5705 copy_with_variable_replacement(Rule,Rule2,List),
5706 identical_guarded_rules(Rule,Rule2) ->
5711 symmetry_analysis_heads_simplification(Hs,IDs,[H|PreHs],[ID|PreIDs],Rule,RuleNb).
5713 symmetry_analysis_heads_propagation([],[],_,_,_,_).
5714 symmetry_analysis_heads_propagation([H|Hs],[ID|IDs],PreHs,PreIDs,Rule,RuleNb) :-
5715 ( \+ is_passive(RuleNb,ID),
5716 member2(PreHs,PreIDs,PreH-PreID),
5717 \+ is_passive(RuleNb,PreID),
5718 variable_replacement(PreH,H,List),
5719 copy_with_variable_replacement(Rule,Rule2,List),
5720 identical_rules(Rule,Rule2) ->
5725 symmetry_analysis_heads_propagation(Hs,IDs,[H|PreHs],[ID|PreIDs],Rule,RuleNb).
5727 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5729 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5730 %% ____ _ _ _ __ _ _ _
5731 %% / ___|(_)_ __ ___ _ __ | (_)/ _(_) ___ __ _| |_(_) ___ _ __
5732 %% \___ \| | '_ ` _ \| '_ \| | | |_| |/ __/ _` | __| |/ _ \| '_ \
5733 %% ___) | | | | | | | |_) | | | _| | (_| (_| | |_| | (_) | | | |
5734 %% |____/|_|_| |_| |_| .__/|_|_|_| |_|\___\__,_|\__|_|\___/|_| |_|
5737 simplification_code(Head,ID,RestHeads,RestIDs,PragmaRule,F/A,O,Id,L,T) :-
5738 PragmaRule = pragma(Rule,_,Pragmas,_,RuleNb),
5739 head_info(Head,A,_Vars,Susp,HeadVars,HeadPairs),
5740 build_head(F,A,Id,HeadVars,ClauseHead),
5741 get_constraint_mode(F/A,Mode),
5742 head_arg_matches(HeadPairs,Mode,[],FirstMatching,VarDict1,[],GroundVars),
5745 guard_splitting(Rule,GuardList0),
5746 ( is_stored_in_guard(F/A, RuleNb) ->
5747 GuardList = [Hole1|GuardList0]
5749 GuardList = GuardList0
5751 guard_via_reschedule_new(RestHeads,GuardList,Head,GuardCopyList,GetRestHeads,RescheduledTest),
5753 rest_heads_retrieval_and_matching(RestHeads,RestIDs,Head,GetRestHeads,Susps,VarDict1,VarDict,[],[],[],GroundVars,_),
5755 guard_body_copies3(Rule,GuardList,VarDict,GuardCopyList,BodyCopy),
5757 ( is_stored_in_guard(F/A, RuleNb) ->
5758 gen_occ_allocation_in_guard(F/A,O,Vars,Susp,Allocation),
5759 gen_uncond_attach_goal(F/A,Susp,Vars,Attachment,_),
5760 GuardCopyList = [Hole1Copy|_],
5761 Hole1Copy = (Allocation, Attachment)
5767 partner_constraint_detachments(Susps,RestHeads,VarDict,SuspsDetachments),
5768 active_constraint_detachment(Id,Susp,Head,VarDict,SuspDetachment),
5770 ( chr_pp_flag(debugable,on) ->
5771 Rule = rule(_,_,Guard,Body),
5772 my_term_copy(Guard - Body, VarDict, DebugGuard - DebugBody),
5773 sort_by_key([Susp|Susps],[ID|RestIDs],SortedSusps),
5774 DebugTry = 'chr debug_event'( try(SortedSusps,[],DebugGuard,DebugBody)),
5775 DebugApply = 'chr debug_event'(apply(SortedSusps,[],DebugGuard,DebugBody)),
5776 instrument_goal(ActualCut,DebugTry,DebugApply,Cut)
5780 ( unconditional_occurrence(F/A,O), chr_pp_flag(late_allocation,on) -> ActualCut = true ; ActualCut = (!) ),
5781 Clause = ( ClauseHead :-
5791 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5792 %% head_arg_matches(+Pairs,+Modes,+VarDict,-Goal,-NVarDict) is det.
5794 % Return goal matching newly introduced variables with variables in
5795 % previously looked-up heads.
5796 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5797 head_arg_matches(Pairs,Modes,VarDict,Goal,NVarDict) :-
5798 head_arg_matches(Pairs,Modes,VarDict,Goal,NVarDict,[],_).
5800 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5801 %% head_arg_matches(+Pairs,+Modes,+VarDict,-Goal,-NVarDict,+GroundVars,-NGroundVars) is det.
5802 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5803 head_arg_matches(Pairs,Modes,VarDict,Goal,NVarDict,GroundVars,NGroundVars) :-
5804 head_arg_matches_(Pairs,Modes,VarDict,GroundVars,GoalList,NVarDict,NGroundVars),
5805 list2conj(GoalList,Goal).
5807 head_arg_matches_([],[],VarDict,GroundVars,[],VarDict,GroundVars).
5808 head_arg_matches_([Arg-Var| Rest],[Mode|Modes],VarDict,GroundVars,GoalList,NVarDict,NGroundVars) :-
5810 ( lookup_eq(VarDict,Arg,OtherVar) ->
5812 ( memberchk_eq(Arg,GroundVars) ->
5813 GoalList = [Var = OtherVar | RestGoalList],
5814 GroundVars1 = GroundVars
5816 GoalList = [Var == OtherVar | RestGoalList],
5817 GroundVars1 = [Arg|GroundVars]
5820 GoalList = [Var == OtherVar | RestGoalList],
5821 GroundVars1 = GroundVars
5825 VarDict1 = [Arg-Var | VarDict],
5826 GoalList = RestGoalList,
5828 GroundVars1 = [Arg|GroundVars]
5830 GroundVars1 = GroundVars
5835 ; ground(Arg), Arg = '$chr_identifier_match'(ActualArg,IndexType) ->
5836 identifier_label_atom(IndexType,Var,ActualArg,Goal),
5837 GoalList = [Goal|RestGoalList],
5839 GroundVars1 = GroundVars,
5844 GoalList = [ Var = Arg | RestGoalList]
5846 GoalList = [ Var == Arg | RestGoalList]
5849 GroundVars1 = GroundVars,
5852 ; Mode == (+), is_ground(GroundVars,Arg) ->
5853 copy_with_variable_replacement(Arg,ArgCopy,VarDict),
5854 GoalList = [ Var = ArgCopy | RestGoalList],
5856 GroundVars1 = GroundVars,
5861 functor(Term,Fct,N),
5864 GoalList = [ Var = Term | RestGoalList ]
5866 GoalList = [ nonvar(Var), Var = Term | RestGoalList ]
5868 pairup(Args,Vars,NewPairs),
5869 append(NewPairs,Rest,Pairs),
5870 replicate(N,Mode,NewModes),
5871 append(NewModes,Modes,RestModes),
5873 GroundVars1 = GroundVars
5875 head_arg_matches_(Pairs,RestModes,VarDict1,GroundVars1,RestGoalList,NVarDict,NGroundVars).
5877 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5878 % add_heads_types(+ListOfHeads,+VarTypes,-NVarTypes) is det.
5879 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5880 add_heads_types([],VarTypes,VarTypes).
5881 add_heads_types([Head|Heads],VarTypes,NVarTypes) :-
5882 add_head_types(Head,VarTypes,VarTypes1),
5883 add_heads_types(Heads,VarTypes1,NVarTypes).
5885 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5886 % add_head_types(+Head,+VarTypes,-NVarTypes) is det.
5887 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5888 add_head_types(Head,VarTypes,NVarTypes) :-
5890 get_constraint_type_det(F/A,ArgTypes),
5892 add_args_types(Args,ArgTypes,VarTypes,NVarTypes).
5894 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5895 % add_args_types(+Terms,+Types,+VarTypes,-NVarTypes) is det.
5896 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5897 add_args_types([],[],VarTypes,VarTypes).
5898 add_args_types([Arg|Args],[Type|Types],VarTypes,NVarTypes) :-
5899 add_arg_types(Arg,Type,VarTypes,VarTypes1),
5900 add_args_types(Args,Types,VarTypes1,NVarTypes).
5902 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5903 % add_arg_types(+Term,+Type,+VarTypes,-NVarTypes) is det.
5904 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5905 add_arg_types(Term,Type,VarTypes,NVarTypes) :-
5907 ( lookup_eq(VarTypes,Term,_) ->
5908 NVarTypes = VarTypes
5910 NVarTypes = [Term-Type|VarTypes]
5913 NVarTypes = VarTypes
5914 ; % TODO improve approximation!
5915 term_variables(Term,Vars),
5917 replicate(VarNb,any,Types),
5918 add_args_types(Vars,Types,VarTypes,NVarTypes)
5923 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5924 %% add_heads_ground_variables(+ListOfHeads,+GroundVars,-NGroundVars) is det.
5926 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5927 add_heads_ground_variables([],GroundVars,GroundVars).
5928 add_heads_ground_variables([Head|Heads],GroundVars,NGroundVars) :-
5929 add_head_ground_variables(Head,GroundVars,GroundVars1),
5930 add_heads_ground_variables(Heads,GroundVars1,NGroundVars).
5932 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5933 %% add_head_ground_variables(+Head,+GroundVars,-GroundVars) is det.
5935 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5936 add_head_ground_variables(Head,GroundVars,NGroundVars) :-
5938 get_constraint_mode(F/A,ArgModes),
5940 add_arg_ground_variables(Args,ArgModes,GroundVars,NGroundVars).
5943 add_arg_ground_variables([],[],GroundVars,GroundVars).
5944 add_arg_ground_variables([Arg|Args],[Mode|Modes],GroundVars,NGroundVars) :-
5946 term_variables(Arg,Vars),
5947 add_var_ground_variables(Vars,GroundVars,GroundVars1)
5949 GroundVars = GroundVars1
5951 add_arg_ground_variables(Args,Modes,GroundVars1,NGroundVars).
5953 add_var_ground_variables([],GroundVars,GroundVars).
5954 add_var_ground_variables([Var|Vars],GroundVars,NGroundVars) :-
5955 ( memberchk_eq(Var,GroundVars) ->
5956 GroundVars1 = GroundVars
5958 GroundVars1 = [Var|GroundVars]
5960 add_var_ground_variables(Vars,GroundVars1,NGroundVars).
5961 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5962 %% is_ground(+GroundVars,+Term) is semidet.
5964 % Determine whether =Term= is always ground.
5965 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5966 is_ground(GroundVars,Term) :-
5971 maplist(is_ground(GroundVars),Args)
5973 memberchk_eq(Term,GroundVars)
5976 %% check_ground(+GroundVars,+Term,-Goal) is det.
5978 % Return runtime check to see whether =Term= is ground.
5979 check_ground(GroundVars,Term,Goal) :-
5980 term_variables(Term,Variables),
5981 check_ground_variables(Variables,GroundVars,Goal).
5983 check_ground_variables([],_,true).
5984 check_ground_variables([Var|Vars],GroundVars,Goal) :-
5985 ( memberchk_eq(Var,GroundVars) ->
5986 check_ground_variables(Vars,GroundVars,Goal)
5988 Goal = (ground(Var), RGoal),
5989 check_ground_variables(Vars,GroundVars,RGoal)
5992 rest_heads_retrieval_and_matching(Heads,IDs,ActiveHead,GoalList,Susps,VarDict,NVarDict,PrevHs,PrevSusps,AttrDict) :-
5993 rest_heads_retrieval_and_matching(Heads,IDs,ActiveHead,GoalList,Susps,VarDict,NVarDict,PrevHs,PrevSusps,AttrDict,[],_).
5995 rest_heads_retrieval_and_matching(Heads,IDs,ActiveHead,GoalList,Susps,VarDict,NVarDict,PrevHs,PrevSusps,AttrDict,GroundVars,NGroundVars) :-
5997 rest_heads_retrieval_and_matching_n(Heads,IDs,PrevHs,PrevSusps,ActiveHead,GoalList,Susps,VarDict,NVarDict,AttrDict,GroundVars,NGroundVars)
6002 GroundVars = NGroundVars
6005 rest_heads_retrieval_and_matching_n([],_,_,_,_,[],[],VarDict,VarDict,_AttrDict,GroundVars,GroundVars).
6006 rest_heads_retrieval_and_matching_n([H|Hs],[ID|IDs],PrevHs,PrevSusps,ActiveHead,
6007 [Goal|Goals],[Susp|Susps],VarDict,NVarDict,_AttrDict,GroundVars,NGroundVars) :-
6009 head_info(H,A,Vars,_,_,Pairs),
6010 get_store_type(F/A,StoreType),
6011 ( StoreType == default ->
6012 passive_head_via(H,[ActiveHead|PrevHs],VarDict,ViaGoal,VarSusps),
6013 delay_phase_end(validate_store_type_assumptions,
6014 ( static_suspension_term(F/A,Suspension),
6015 get_static_suspension_term_field(arguments,F/A,Suspension,Vars),
6016 get_static_suspension_field(F/A,Suspension,state,active,GetState)
6019 % create_get_mutable_ref(active,State,GetMutable),
6020 get_constraint_mode(F/A,Mode),
6021 head_arg_matches(Pairs,Mode,VarDict,MatchingGoal,VarDict1,GroundVars,GroundVars1),
6023 sbag_member_call(Susp,VarSusps,Sbag),
6024 ExistentialLookup = (
6027 Susp = Suspension, % not inlined
6031 delay_phase_end(validate_store_type_assumptions,
6032 ( static_suspension_term(F/A,Suspension),
6033 get_static_suspension_term_field(arguments,F/A,Suspension,Vars)
6036 existential_lookup(StoreType,H,[ActiveHead|PrevHs],VarDict,GroundVars,Suspension,ExistentialLookup,Susp,Pairs,NPairs),
6037 get_constraint_mode(F/A,Mode),
6038 filter_mode(NPairs,Pairs,Mode,NMode),
6039 head_arg_matches(NPairs,NMode,VarDict,MatchingGoal,VarDict1,GroundVars,GroundVars1)
6041 different_from_other_susps(H,Susp,PrevHs,PrevSusps,DiffSuspGoals),
6042 append(NPairs,VarDict1,DA_), % order important here
6043 translate(GroundVars1,DA_,GroundVarsA),
6044 translate(GroundVars1,VarDict1,GroundVarsB),
6045 inline_matching_goal(MatchingGoal,MatchingGoal2,GroundVarsA,GroundVarsB),
6052 rest_heads_retrieval_and_matching_n(Hs,IDs,[H|PrevHs],[Susp|PrevSusps],ActiveHead,Goals,Susps,VarDict1,NVarDict,_NewAttrDict,GroundVars1,NGroundVars).
6054 inline_matching_goal(A==B,true,GVA,GVB) :-
6055 memberchk_eq(A,GVA),
6056 memberchk_eq(B,GVB),
6059 % inline_matching_goal(A=B,true,_,_) :- A=B, !.
6060 inline_matching_goal((A,B),(A2,B2),GVA,GVB) :- !,
6061 inline_matching_goal(A,A2,GVA,GVB),
6062 inline_matching_goal(B,B2,GVA,GVB).
6063 inline_matching_goal(X,X,_,_).
6066 filter_mode([],_,_,[]).
6067 filter_mode([Arg-Var|Rest],[_-V|R],[M|Ms],Modes) :-
6070 filter_mode(Rest,R,Ms,MT)
6072 filter_mode([Arg-Var|Rest],R,Ms,Modes)
6075 check_unique_keys([],_).
6076 check_unique_keys([V|Vs],Dict) :-
6077 lookup_eq(Dict,V,_),
6078 check_unique_keys(Vs,Dict).
6080 % Generates tests to ensure the found constraint differs from previously found constraints
6081 % TODO: detect more cases where constraints need be different
6082 different_from_other_susps(Head,Susp,Heads,Susps,DiffSuspGoals) :-
6083 different_from_other_susps_(Heads,Susps,Head,Susp,DiffSuspGoalList),
6084 list2conj(DiffSuspGoalList,DiffSuspGoals).
6086 different_from_other_susps_(_,[],_,_,[]) :- !.
6087 different_from_other_susps_([PreHead|Heads],[PreSusp|Susps],Head,Susp,List) :-
6088 ( functor(Head,F,A), functor(PreHead,F,A),
6089 copy_term_nat(PreHead-Head,PreHeadCopy-HeadCopy),
6090 \+ \+ PreHeadCopy = HeadCopy ->
6092 List = [Susp \== PreSusp | Tail]
6096 different_from_other_susps_(Heads,Susps,Head,Susp,Tail).
6098 % passive_head_via(in,in,in,in,out,out,out) :-
6099 passive_head_via(Head,PrevHeads,VarDict,Goal,AllSusps) :-
6101 get_constraint_index(F/A,Pos),
6102 common_variables(Head,PrevHeads,CommonVars),
6103 global_list_store_name(F/A,Name),
6104 GlobalGoal = nb_getval(Name,AllSusps),
6105 get_constraint_mode(F/A,ArgModes),
6108 ; member(CommonVar,CommonVars), nth(I,ArgModes,(-)), arg(I,Head,Arg), Arg == CommonVar ->
6109 translate([CommonVar],VarDict,[Var]),
6110 gen_get_mod_constraints(F/A,Var,AttrGoal,AllSusps),
6113 translate(CommonVars,VarDict,Vars),
6114 add_heads_types(PrevHeads,[],TypeDict),
6115 my_term_copy(TypeDict,VarDict,TypeDictCopy),
6116 gen_get_mod_constraints(F/A,Vars,TypeDictCopy,ViaGoal,AttrGoal,AllSusps),
6125 common_variables(T,Ts,Vs) :-
6126 term_variables(T,V1),
6127 term_variables(Ts,V2),
6128 intersect_eq(V1,V2,Vs).
6130 gen_get_mod_constraints(FA,Vars,TypeDict,ViaGoal,AttrGoal,AllSusps) :-
6131 get_target_module(Mod),
6133 lookup_eq(TypeDict,A,Type),
6134 ( atomic_type(Type) ->
6138 ViaGoal = 'chr newvia_1'(A,V)
6141 ViaGoal = 'chr newvia_2'(A,B,V)
6143 ViaGoal = 'chr newvia'(Vars,V)
6146 ( get_attr(V,Mod,TSusps),
6147 TSuspsEqSusps % TSusps = Susps
6149 get_max_constraint_index(N),
6151 TSuspsEqSusps = true, % TSusps = Susps
6154 TSuspsEqSusps = (TSusps = Susps),
6155 get_constraint_index(FA,Pos),
6156 make_attr(N,_,SuspsList,Susps),
6157 nth1(Pos,SuspsList,AllSusps)
6159 gen_get_mod_constraints(FA,Var,AttrGoal,AllSusps) :-
6160 get_target_module(Mod),
6162 ( get_attr(Var,Mod,TSusps),
6163 TSuspsEqSusps % TSusps = Susps
6165 get_max_constraint_index(N),
6167 TSuspsEqSusps = true, % TSusps = Susps
6170 TSuspsEqSusps = (TSusps = Susps),
6171 get_constraint_index(FA,Pos),
6172 make_attr(N,_,SuspsList,Susps),
6173 nth1(Pos,SuspsList,AllSusps)
6176 guard_body_copies(Rule,VarDict,GuardCopy,BodyCopy) :-
6177 guard_body_copies2(Rule,VarDict,GuardCopyList,BodyCopy),
6178 list2conj(GuardCopyList,GuardCopy).
6180 guard_body_copies2(Rule,VarDict,GuardCopyList,BodyCopy) :-
6181 Rule = rule(H,_,Guard,Body),
6182 conj2list(Guard,GuardList),
6183 split_off_simple_guard(GuardList,VarDict,GuardPrefix,RestGuardList),
6184 my_term_copy(GuardPrefix-RestGuardList,VarDict,VarDict2,GuardPrefixCopy-RestGuardListCopyCore),
6186 append(GuardPrefixCopy,[RestGuardCopy],GuardCopyList),
6187 term_variables(RestGuardList,GuardVars),
6188 term_variables(RestGuardListCopyCore,GuardCopyVars),
6189 % variables that are declared to be ground don't need to be locked
6190 ground_vars(H,GroundVars),
6191 list_difference_eq(GuardVars,GroundVars,GuardVars_),
6192 ( chr_pp_flag(guard_locks,on),
6193 bagof(('chr lock'(Y)) - ('chr unlock'(Y)),
6194 X ^ (lists:member(X,GuardVars), % X is a variable appearing in the original guard
6195 pairlist:lookup_eq(VarDict,X,Y), % translate X into new variable
6196 memberchk_eq(Y,GuardCopyVars) % redundant check? or multiple entries for X possible?
6199 once(pairup(Locks,Unlocks,LocksUnlocks))
6204 list2conj(Locks,LockPhase),
6205 list2conj(Unlocks,UnlockPhase),
6206 list2conj(RestGuardListCopyCore,RestGuardCopyCore),
6207 RestGuardCopy = (LockPhase,(RestGuardCopyCore,UnlockPhase)),
6208 my_term_copy(Body,VarDict2,BodyCopy).
6211 split_off_simple_guard([],_,[],[]).
6212 split_off_simple_guard([G|Gs],VarDict,S,C) :-
6213 ( simple_guard(G,VarDict) ->
6215 split_off_simple_guard(Gs,VarDict,Ss,C)
6221 % simple guard: cheap and benign (does not bind variables)
6222 simple_guard(G,VarDict) :-
6224 \+ (( member(V,Vars),
6225 lookup_eq(VarDict,V,_)
6228 active_constraint_detachment(Id,Susp,Head,VarDict,SuspDetachment) :-
6233 (get_allocation_occurrence(C,AO),
6234 get_max_occurrence(C,MO),
6236 only_ground_indexed_arguments(C), chr_pp_flag(late_allocation,on) ->
6237 SuspDetachment = true
6239 gen_uncond_susp_detachment(Head,Susp,active,VarDict,UnCondSuspDetachment),
6240 ( chr_pp_flag(late_allocation,on) ->
6245 UnCondSuspDetachment
6248 SuspDetachment = UnCondSuspDetachment
6252 SuspDetachment = true
6255 partner_constraint_detachments([],[],_,true).
6256 partner_constraint_detachments([Susp|Susps],[Head|Heads],VarDict,(SuspDetachment,SuspsDetachments)) :-
6257 gen_uncond_susp_detachment(Head,Susp,partner,VarDict,SuspDetachment),
6258 partner_constraint_detachments(Susps,Heads,VarDict,SuspsDetachments).
6260 gen_uncond_susp_detachment(Head,Susp,Role,VarDict,SuspDetachment) :-
6264 SuspDetachment = ( DebugEvent, RemoveInternalGoal),
6265 ( chr_pp_flag(debugable,on) ->
6266 DebugEvent = 'chr debug_event'(remove(Susp))
6270 remove_constraint_goal(C,Susp,Vars,true,(DeleteCall,Detach),Role,RemoveInternalGoal),
6271 delete_constraint_goal(Head,Susp,VarDict,DeleteCall),
6272 ( \+ only_ground_indexed_arguments(C), \+ get_store_type(C,var_assoc_store(_,_)) ->
6273 detach_constraint_atom(C,Vars,Susp,Detach)
6278 SuspDetachment = true
6281 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6283 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6285 %% / ___|(_)_ __ ___ _ __ __ _ __ _ __ _| |_(_) ___ _ __ / |
6286 %% \___ \| | '_ ` _ \| '_ \ / _` |/ _` |/ _` | __| |/ _ \| '_ \ | |
6287 %% ___) | | | | | | | |_) | (_| | (_| | (_| | |_| | (_) | | | | | |
6288 %% |____/|_|_| |_| |_| .__/ \__,_|\__, |\__,_|\__|_|\___/|_| |_| |_|
6291 simpagation_head1_code(Head,ID,RestHeads,OtherIDs,PragmaRule,F/A,O,Id,L,T) :-
6292 PragmaRule = pragma(Rule,ids(_,Heads2IDs),Pragmas,_Name,RuleNb),
6293 Rule = rule(_Heads,Heads2,Guard,Body),
6295 head_info(Head,A,_Vars,Susp,HeadVars,HeadPairs),
6296 get_constraint_mode(F/A,Mode),
6297 head_arg_matches(HeadPairs,Mode,[],FirstMatching,VarDict1,[],GroundVars),
6299 build_head(F,A,Id,HeadVars,ClauseHead),
6301 append(RestHeads,Heads2,Heads),
6302 append(OtherIDs,Heads2IDs,IDs),
6303 reorder_heads(RuleNb,Head,Heads,IDs,NHeads,NIDs),
6305 guard_splitting(Rule,GuardList0),
6306 ( is_stored_in_guard(F/A, RuleNb) ->
6307 GuardList = [Hole1|GuardList0]
6309 GuardList = GuardList0
6311 guard_via_reschedule_new(NHeads,GuardList,Head,GuardCopyList,GetRestHeads,RescheduledTest),
6313 rest_heads_retrieval_and_matching(NHeads,NIDs,Head,GetRestHeads,Susps,VarDict1,VarDict,[],[],[],GroundVars,_),
6314 split_by_ids(NIDs,Susps,OtherIDs,Susps1,Susps1IDs,Susps2,Susps2IDs),
6316 guard_body_copies3(Rule,GuardList,VarDict,GuardCopyList,BodyCopy),
6318 ( is_stored_in_guard(F/A, RuleNb) ->
6319 gen_occ_allocation_in_guard(F/A,O,Vars,Susp,Allocation),
6320 gen_uncond_attach_goal(F/A,Susp,Vars,Attachment,_),
6321 GuardCopyList = [Hole1Copy|_],
6322 Hole1Copy = (Allocation, Attachment)
6327 sort_by_key(Susps1,Susps1IDs,SortedSusps1),
6328 partner_constraint_detachments(SortedSusps1,RestHeads,VarDict,SuspsDetachments),
6329 active_constraint_detachment(Id,Susp,Head,VarDict,SuspDetachment),
6331 ( chr_pp_flag(debugable,on) ->
6332 my_term_copy(Guard - Body, VarDict, DebugGuard - DebugBody),
6333 sort_by_key([Susp|Susps1],[ID|Susps1IDs],RemovedSusps),
6334 sort_by_key(Susps2,Susps2IDs,KeptSusps),
6335 DebugTry = 'chr debug_event'( try(RemovedSusps,KeptSusps,DebugGuard,DebugBody)),
6336 DebugApply = 'chr debug_event'(apply(RemovedSusps,KeptSusps,DebugGuard,DebugBody)),
6337 instrument_goal((!),DebugTry,DebugApply,Cut)
6342 Clause = ( ClauseHead :-
6352 split_by_ids([],[],_,[],[]).
6353 split_by_ids([I|Is],[S|Ss],I1s,S1s,S2s) :-
6354 ( memberchk_eq(I,I1s) ->
6361 split_by_ids(Is,Ss,I1s,R1s,R2s).
6363 split_by_ids([],[],_,[],[],[],[]).
6364 split_by_ids([I|Is],[S|Ss],I1s,S1s,SI1s,S2s,SI2s) :-
6365 ( memberchk_eq(I,I1s) ->
6376 split_by_ids(Is,Ss,I1s,R1s,RSI1s,R2s,RSI2s).
6377 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6380 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6382 %% / ___|(_)_ __ ___ _ __ __ _ __ _ __ _| |_(_) ___ _ __ |___ \
6383 %% \___ \| | '_ ` _ \| '_ \ / _` |/ _` |/ _` | __| |/ _ \| '_ \ __) |
6384 %% ___) | | | | | | | |_) | (_| | (_| | (_| | |_| | (_) | | | | / __/
6385 %% |____/|_|_| |_| |_| .__/ \__,_|\__, |\__,_|\__|_|\___/|_| |_| |_____|
6388 %% Genereate prelude + worker predicate
6389 %% prelude calls worker
6390 %% worker iterates over one type of removed constraints
6391 simpagation_head2_code(Head2,ID,RestHeads2,RestIDs,PragmaRule,FA,O,Id,L,T) :-
6392 PragmaRule = pragma(Rule,ids(IDs1,IDs2),Pragmas,_Name,RuleNb),
6393 Rule = rule(Heads1,_,Guard,Body),
6394 append(Heads1,RestHeads2,Heads),
6395 append(IDs1,RestIDs,IDs),
6396 reorder_heads(RuleNb,Head2,Heads,IDs,[NHead|NHeads],[NID|NIDs]),
6397 simpagation_head2_prelude(Head2,NHead,[NHeads,Guard,Body],FA,O,Id,L,L1),
6399 ( memberchk_eq(NID,IDs2) ->
6400 simpagation_universal_searches(NHeads,NIDs,IDs2,[NHead,Head2],Rule,FA,NextHeads,PreHeads,NextIDs,Id1,Id2,L1,L2)
6402 L1 = L2, Id1 = Id2,NextHeads = NHeads, PreHeads = [NHead,Head2], NextIDs = NIDs
6404 universal_search_iterator_end(PreHeads,NextHeads,Rule,FA,Id2,L2,L3),
6405 simpagation_head2_worker(PreHeads,NextHeads,NextIDs,ID,PragmaRule,FA,O,Id2,L3,T).
6407 simpagation_universal_searches([],[],_,PreHeads,_,_,[],PreHeads,[],Id,Id,L,L).
6408 simpagation_universal_searches(Heads,[ID|IDs],IDs2,PreHeads,Rule,C,OutHeads,OutPreHeads,OutIDs,Id,NId,L,T) :-
6409 Heads = [Head|RHeads],
6411 universal_search_iterator_end(PreHeads,Heads,Rule,C,Id,L,L0),
6412 universal_search_iterator(Heads,PreHeads,Rule,C,Id,L0,L1),
6413 ( memberchk_eq(ID,IDs2) ->
6414 simpagation_universal_searches(RHeads,IDs,IDs2,[Head|PreHeads],Rule,C,OutHeads,OutPreHeads,OutIDs,Id1,NId,L1,T)
6416 NId = Id1, L1 = T, OutHeads = RHeads, OutPreHeads = [Head|PreHeads], IDs = OutIDs
6419 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6420 simpagation_head2_prelude(Head,Head1,Rest,F/A,O,Id1,L,T) :-
6421 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs),
6422 build_head(F,A,Id1,VarsSusp,ClauseHead),
6423 get_constraint_mode(F/A,Mode),
6424 head_arg_matches(HeadPairs,Mode,[],FirstMatching,VarDict,[],GroundVars),
6426 lookup_passive_head(Head1,[Head],VarDict,GroundVars,ModConstraintsGoal,AllSusps),
6428 gen_occ_allocation(F/A,O,Vars,Susp,ConstraintAllocationGoal),
6430 extend_id(Id1,DelegateId),
6431 extra_active_delegate_variables(Head,[Head1|Rest],VarDict,ExtraVars),
6432 append([AllSusps|VarsSusp],ExtraVars,DelegateCallVars),
6433 build_head(F,A,DelegateId,DelegateCallVars,Delegate),
6440 ConstraintAllocationGoal,
6443 L = [PreludeClause|T].
6445 extra_active_delegate_variables(Term,Terms,VarDict,Vars) :-
6447 delegate_variables(Term,Terms,VarDict,Args,Vars).
6449 passive_delegate_variables(Term,PrevTerms,NextTerms,VarDict,Vars) :-
6450 term_variables(PrevTerms,PrevVars),
6451 delegate_variables(Term,NextTerms,VarDict,PrevVars,Vars).
6453 delegate_variables(Term,Terms,VarDict,PrevVars,Vars) :-
6454 term_variables(Term,V1),
6455 term_variables(Terms,V2),
6456 intersect_eq(V1,V2,V3),
6457 list_difference_eq(V3,PrevVars,V4),
6458 translate(V4,VarDict,Vars).
6461 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6462 simpagation_head2_worker([CurrentHead|PreHeads],NextHeads,NextIDs,ID,PragmaRule,F/A,O,Id,L,T) :-
6463 PragmaRule = pragma(Rule,ids(IDs1,_),Pragmas,_,RuleNb),
6464 Rule = rule(_,_,Guard,Body),
6465 get_prop_inner_loop_vars(PreHeads,[CurrentHead,NextHeads,Guard,Body],PreVarsAndSusps,VarDict,Susp,Vars,PreSusps),
6468 gen_var(OtherSusps),
6470 functor(CurrentHead,OtherF,OtherA),
6471 gen_vars(OtherA,OtherVars),
6472 head_info(CurrentHead,OtherA,OtherVars,OtherSusp,_VarsSusp,HeadPairs),
6473 get_constraint_mode(OtherF/OtherA,Mode),
6474 head_arg_matches(HeadPairs,Mode,VarDict,FirstMatching,VarDict1,[],GroundVars),
6476 delay_phase_end(validate_store_type_assumptions,
6477 ( static_suspension_term(OtherF/OtherA,OtherSuspension),
6478 get_static_suspension_field(OtherF/OtherA,OtherSuspension,state,active,GetState),
6479 get_static_suspension_term_field(arguments,OtherF/OtherA,OtherSuspension,OtherVars)
6482 % create_get_mutable_ref(active,State,GetMutable),
6483 different_from_other_susps(CurrentHead,OtherSusp,PreHeads,PreSusps,DiffSuspGoals),
6485 OtherSusp = OtherSuspension,
6491 ClauseVars = [[OtherSusp|OtherSusps]|PreVarsAndSusps],
6492 build_head(F,A,Id,ClauseVars,ClauseHead),
6494 guard_splitting(Rule,GuardList0),
6495 ( is_stored_in_guard(F/A, RuleNb) ->
6496 GuardList = [Hole1|GuardList0]
6498 GuardList = GuardList0
6500 guard_via_reschedule_new(NextHeads,GuardList,[CurrentHead|PreHeads],GuardCopyList,RestSuspsRetrieval,RescheduledTest),
6502 rest_heads_retrieval_and_matching(NextHeads,NextIDs,[CurrentHead|PreHeads],RestSuspsRetrieval,Susps,VarDict1,VarDict2,[CurrentHead|PreHeads],[OtherSusp|PreSusps],[]),
6503 split_by_ids(NextIDs,Susps,IDs1,Susps1,Susps2),
6504 split_by_ids(NextIDs,NextHeads,IDs1,RestHeads1,_),
6506 partner_constraint_detachments([OtherSusp | Susps1],[CurrentHead|RestHeads1],VarDict2,Susps1Detachments),
6508 RecursiveVars = [OtherSusps|PreVarsAndSusps],
6509 build_head(F,A,Id,RecursiveVars,RecursiveCall),
6510 RecursiveVars2 = [[]|PreVarsAndSusps],
6511 build_head(F,A,Id,RecursiveVars2,RecursiveCall2),
6513 guard_body_copies3(Rule,GuardList,VarDict2,GuardCopyList,BodyCopy),
6514 ( is_stored_in_guard(F/A, RuleNb) ->
6515 GuardCopyList = [GuardAttachment|_] % once( ) ??
6520 ( is_observed(F/A,O) ->
6521 gen_uncond_attach_goal(F/A,Susp,Vars,Attachment,Generation),
6522 gen_state_cond_call(Susp,F/A,RecursiveCall,Generation,ConditionalRecursiveCall),
6523 gen_state_cond_call(Susp,F/A,RecursiveCall2,Generation,ConditionalRecursiveCall2)
6526 ConditionalRecursiveCall = RecursiveCall,
6527 ConditionalRecursiveCall2 = RecursiveCall2
6530 ( chr_pp_flag(debugable,on) ->
6531 my_term_copy(Guard - Body, VarDict, DebugGuard - DebugBody),
6532 DebugTry = 'chr debug_event'( try([OtherSusp|Susps1],[Susp|Susps2],DebugGuard,DebugBody)),
6533 DebugApply = 'chr debug_event'(apply([OtherSusp|Susps1],[Susp|Susps2],DebugGuard,DebugBody))
6539 ( is_stored_in_guard(F/A, RuleNb) ->
6540 GuardAttachment = Attachment,
6541 BodyAttachment = true
6543 GuardAttachment = true,
6544 BodyAttachment = Attachment % will be true if not observed at all
6547 ( member(unique(ID1,UniqueKeys), Pragmas),
6548 check_unique_keys(UniqueKeys,VarDict) ->
6551 ( CurrentSuspTest ->
6558 ConditionalRecursiveCall2
6576 ConditionalRecursiveCall
6584 gen_state_cond_call(Susp,FA,Call,Generation,ConditionalCall) :-
6585 ( may_trigger(FA) ->
6586 does_use_field(FA,generation),
6587 delay_phase_end(validate_store_type_assumptions,
6588 ( static_suspension_term(FA,Suspension),
6589 get_update_static_suspension_field(FA,Susp,Suspension,state,active,inactive,GetState,UpdateState),
6590 get_static_suspension_field(FA,Suspension,generation,Generation,GetGeneration),
6591 get_static_suspension_term_field(arguments,FA,Suspension,Args)
6595 delay_phase_end(validate_store_type_assumptions,
6596 ( static_suspension_term(FA,Suspension),
6597 get_update_static_suspension_field(FA,Susp,Suspension,state,active,inactive,GetState,UpdateState),
6598 get_static_suspension_term_field(arguments,FA,Suspension,Args)
6601 GetGeneration = true
6604 ( Susp = Suspension,
6613 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6616 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6618 %% | _ \ _ __ ___ _ __ __ _ __ _ __ _| |_(_) ___ _ __
6619 %% | |_) | '__/ _ \| '_ \ / _` |/ _` |/ _` | __| |/ _ \| '_ \
6620 %% | __/| | | (_) | |_) | (_| | (_| | (_| | |_| | (_) | | | |
6621 %% |_| |_| \___/| .__/ \__,_|\__, |\__,_|\__|_|\___/|_| |_|
6624 propagation_code(Head,ID,RestHeads,RestIDs,Rule,RuleNb,FA,O,Id,L,T) :-
6625 ( RestHeads == [] ->
6626 propagation_single_headed(Head,ID,Rule,RuleNb,FA,O,Id,L,T)
6628 propagation_multi_headed(Head,RestHeads,RestIDs,Rule,RuleNb,FA,O,Id,L,T)
6630 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6631 %% Single headed propagation
6632 %% everything in a single clause
6633 propagation_single_headed(Head,ID,Rule,RuleNb,F/A,O,Id,ProgramList,ProgramTail) :-
6634 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs),
6635 build_head(F,A,Id,VarsSusp,ClauseHead),
6638 build_head(F,A,NextId,VarsSusp,NextHead),
6640 get_constraint_mode(F/A,Mode),
6641 head_arg_matches(HeadPairs,Mode,[],HeadMatching,VarDict,[],GroundVars),
6642 guard_body_copies(Rule,VarDict,GuardCopy,BodyCopy),
6644 % - recursive call -
6645 RecursiveCall = NextHead,
6647 ( unconditional_occurrence(F/A,O), chr_pp_flag(late_allocation,on) ->
6653 Rule = rule(_,_,Guard,Body),
6654 ( chr_pp_flag(debugable,on) ->
6655 my_term_copy(Guard - Body, VarDict, DebugGuard - DebugBody),
6656 DebugTry = 'chr debug_event'( try([],[Susp],DebugGuard,DebugBody)),
6657 DebugApply = 'chr debug_event'(apply([],[Susp],DebugGuard,DebugBody)),
6658 instrument_goal(ActualCut,DebugTry,DebugApply,Cut)
6662 ( may_trigger(F/A), \+ has_no_history(RuleNb)->
6663 use_auxiliary_predicate(novel_production),
6664 use_auxiliary_predicate(extend_history),
6665 does_use_history(F/A,O),
6666 gen_occ_allocation(F/A,O,Vars,Susp,Allocation),
6668 ( named_history(RuleNb,HistoryName,HistoryIDs) ->
6669 % Tuple =.. [t,HistoryName,Susp]
6675 NovelProduction = '$novel_production'(Susp,Tuple),
6676 ExtendHistory = '$extend_history'(Susp,Tuple),
6678 ( is_observed(F/A,O) ->
6679 gen_uncond_attach_goal(F/A,Susp,Vars,Attachment,Generation),
6680 gen_state_cond_call(Susp,F/A,RecursiveCall,Generation,ConditionalRecursiveCall)
6683 ConditionalRecursiveCall = RecursiveCall
6687 NovelProduction = true,
6688 ExtendHistory = true,
6690 ( is_observed(F/A,O) ->
6691 get_allocation_occurrence(F/A,AllocO),
6693 gen_insert_constraint_internal_goal(F/A,Attachment,VarsSusp,Vars,Susp),
6695 ; % more room for improvement?
6696 Attachment = (Attachment1, Attachment2),
6697 gen_occ_allocation(F/A,O,Vars,Susp,Attachment1),
6698 gen_uncond_attach_goal(F/A,Susp,Vars,Attachment2,Generation)
6700 gen_state_cond_call(Susp,F/A,RecursiveCall,Generation,ConditionalRecursiveCall)
6702 gen_occ_allocation(F/A,O,Vars,Susp,Attachment),
6703 ConditionalRecursiveCall = RecursiveCall
6706 ( is_stored_in_guard(F/A, RuleNb) ->
6707 GuardAttachment = Attachment,
6708 BodyAttachment = true
6710 GuardAttachment = true,
6711 BodyAttachment = Attachment % will be true if not observed at all
6725 ConditionalRecursiveCall
6727 ProgramList = [Clause | ProgramTail].
6729 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6730 %% multi headed propagation
6731 %% prelude + predicates to accumulate the necessary combinations of suspended
6732 %% constraints + predicate to execute the body
6733 propagation_multi_headed(Head,RestHeads,RestIDs,Rule,RuleNb,FA,O,Id,L,T) :-
6734 RestHeads = [First|Rest],
6735 propagation_prelude(Head,RestHeads,Rule,FA,O,Id,L,L1),
6736 extend_id(Id,ExtendedId),
6737 propagation_nested_code(Rest,[First,Head],RestIDs,Rule,RuleNb,FA,O,ExtendedId,L1,T).
6739 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6740 propagation_prelude(Head,[First|Rest],Rule,F/A,O,Id,L,T) :-
6741 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs),
6742 build_head(F,A,Id,VarsSusp,PreludeHead),
6743 get_constraint_mode(F/A,Mode),
6744 head_arg_matches(HeadPairs,Mode,[],FirstMatching,VarDict,[],GroundVars),
6745 Rule = rule(_,_,Guard,Body),
6746 extra_active_delegate_variables(Head,[First,Rest,Guard,Body],VarDict,ExtraVars),
6748 lookup_passive_head(First,[Head],VarDict,GroundVars,FirstSuspGoal,Susps),
6750 gen_occ_allocation(F/A,O,Vars,Susp,CondAllocation),
6752 extend_id(Id,NestedId),
6753 append([Susps|VarsSusp],ExtraVars,NestedVars),
6754 build_head(F,A,NestedId,NestedVars,NestedHead),
6755 NestedCall = NestedHead,
6767 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6768 propagation_nested_code([],[CurrentHead|PreHeads],RestIDs,Rule,RuleNb,FA,O,Id,L,T) :-
6769 universal_search_iterator_end([CurrentHead|PreHeads],[],Rule,FA,Id,L,L1),
6770 propagation_body(CurrentHead,PreHeads,RestIDs,Rule,RuleNb,FA,O,Id,L1,T).
6772 propagation_nested_code([Head|RestHeads],PreHeads,RestIDs,Rule,RuleNb,FA,O,Id,L,T) :-
6773 universal_search_iterator_end(PreHeads,[Head|RestHeads],Rule,FA,Id,L,L1),
6774 universal_search_iterator([Head|RestHeads],PreHeads,Rule,FA,Id,L1,L2),
6776 propagation_nested_code(RestHeads,[Head|PreHeads],RestIDs,Rule,RuleNb,FA,O,IncId,L2,T).
6778 %check_fd_lookup_condition(_,_,_,_) :- fail.
6779 check_fd_lookup_condition(F,A,_,_) :-
6780 get_store_type(F/A,global_singleton), !.
6781 check_fd_lookup_condition(F,A,CurrentHead,PreHeads) :-
6782 \+ may_trigger(F/A),
6783 get_functional_dependency(F/A,1,P,K),
6784 copy_term(P-K,CurrentHead-Key),
6785 term_variables(PreHeads,PreVars),
6786 intersect_eq(Key,PreVars,Key),!.
6788 propagation_body(CurrentHead,PreHeads,RestIDs,Rule,RuleNb,F/A,O,Id,L,T) :-
6789 Rule = rule(_,H2,Guard,Body),
6790 gen_var_susp_list_for_b(PreHeads,[CurrentHead,Guard,Body],VarDict1,PreVarsAndSuspsList,FirstVarsSusp,AllSusps,PrevIterators),
6791 flatten(PreVarsAndSuspsList,PreVarsAndSusps),
6792 init(AllSusps,RestSusps),
6793 last(AllSusps,Susp),
6795 gen_var(OtherSusps),
6796 functor(CurrentHead,OtherF,OtherA),
6797 gen_vars(OtherA,OtherVars),
6798 delay_phase_end(validate_store_type_assumptions,
6799 ( static_suspension_term(OtherF/OtherA,Suspension),
6800 get_static_suspension_field(OtherF/OtherA,Suspension,state,active,GetState),
6801 get_static_suspension_term_field(arguments,OtherF/OtherA,Suspension,OtherVars)
6804 % create_get_mutable_ref(active,State,GetMutable),
6806 OtherSusp = Suspension,
6809 ClauseVars = [[OtherSusp|OtherSusps]|PreVarsAndSusps],
6810 build_head(F,A,Id,ClauseVars,ClauseHead),
6811 ( check_fd_lookup_condition(OtherF,OtherA,CurrentHead,PreHeads) -> % iterator (OtherSusps) is empty at runtime
6812 universal_search_iterator_failure_vars(PreHeads,Id,PreVarsAndSuspsList,FirstVarsSusp,PrevIterators,PreVarsAndSusps1,PrevId),
6813 RecursiveVars = PreVarsAndSusps1
6815 RecursiveVars = [OtherSusps|PreVarsAndSusps],
6818 build_head(F,A,PrevId,RecursiveVars,RecursiveHead),
6819 RecursiveCall = RecursiveHead,
6820 CurrentHead =.. [_|OtherArgs],
6821 pairup(OtherArgs,OtherVars,OtherPairs),
6822 get_constraint_mode(OtherF/OtherA,Mode),
6823 head_arg_matches(OtherPairs,Mode,VarDict1,Matching,VarDict),
6825 different_from_other_susps(CurrentHead,OtherSusp,PreHeads,RestSusps,DiffSuspGoals),
6826 guard_body_copies(Rule,VarDict,GuardCopy,BodyCopy),
6827 get_occurrence(F/A,O,_,ID),
6829 ( is_observed(F/A,O) ->
6830 init(FirstVarsSusp,FirstVars),
6831 gen_uncond_attach_goal(F/A,Susp,FirstVars,Attachment,Generation),
6832 gen_state_cond_call(Susp,F/A,RecursiveCall,Generation,ConditionalRecursiveCall)
6835 ConditionalRecursiveCall = RecursiveCall
6837 ( (is_least_occurrence(RuleNb) ; has_no_history(RuleNb)) ->
6838 NovelProduction = true,
6839 ExtendHistory = true
6840 ; \+ may_trigger(F/A), forall(member(SomeID,RestIDs),(chr_translate:is_passive(RuleNb,SomeID))) ->
6841 NovelProduction = true,
6842 ExtendHistory = true
6844 get_occurrence(F/A,O,_,ID),
6845 use_auxiliary_predicate(novel_production),
6846 use_auxiliary_predicate(extend_history),
6847 does_use_history(F/A,O),
6848 ( named_history(RuleNb,HistoryName,HistoryIDs) ->
6849 reverse([OtherSusp|RestSusps],NamedSusps),
6850 named_history_susps(HistoryIDs,[ID|RestIDs],[Susp|NamedSusps],HistorySusps),
6851 HistorySusps = [HistorySusp|_],
6853 ( length(HistoryIDs, 1) ->
6854 ExtendHistory = '$extend_history'(HistorySusp,HistoryName),
6855 NovelProduction = '$novel_production'(HistorySusp,HistoryName)
6857 findall(ConstraintSymbol,(member(SomeID,HistoryIDs),get_occurrence_from_id(ConstraintSymbol,_,RuleNb,SomeID)),ConstraintSymbols),
6858 Tuple =.. [t,HistoryName|HistorySusps]
6862 findall(Functor/Arity,(member(H,H2),functor(H,Functor,Arity)),ConstraintSymbols),
6863 sort([ID|RestIDs],HistoryIDs),
6864 history_susps(RestIDs,[OtherSusp|RestSusps],Susp,ID,HistorySusps),
6865 Tuple =.. [t,RuleNb|HistorySusps]
6868 ( var(NovelProduction) ->
6869 novel_production_calls(ConstraintSymbols,HistoryIDs,HistorySusps,RuleNb,TupleVar,NovelProductions),
6870 ExtendHistory = '$extend_history'(HistorySusp,TupleVar),
6871 NovelProduction = ( TupleVar = Tuple, NovelProductions)
6878 ( chr_pp_flag(debugable,on) ->
6879 Rule = rule(_,_,Guard,Body),
6880 my_term_copy(Guard - Body, VarDict, DebugGuard - DebugBody),
6881 get_occurrence(F/A,O,_,ID),
6882 sort_by_key([Susp,OtherSusp|RestSusps],[ID|RestIDs],KeptSusps),
6883 DebugTry = 'chr debug_event'( try([],KeptSusps,DebugGuard,DebugBody)),
6884 DebugApply = 'chr debug_event'(apply([],KeptSusps,DebugGuard,DebugBody))
6890 ( is_stored_in_guard(F/A, RuleNb) ->
6891 GuardAttachment = Attachment,
6892 BodyAttachment = true
6894 GuardAttachment = true,
6895 BodyAttachment = Attachment % will be true if not observed at all
6911 ConditionalRecursiveCall
6917 novel_production_calls([],[],[],_,_,true).
6918 novel_production_calls([ConstraintSymbol|ConstraintSymbols],[ID|IDs],[Suspension|Suspensions],RuleNb,Tuple,(Goal,Goals)) :-
6919 get_occurrence_from_id(ConstraintSymbol,Occurrence,RuleNb,ID),
6920 delay_phase_end(validate_store_type_assumptions,novel_production_call(ConstraintSymbol,Occurrence,'$novel_production'(Suspension,Tuple),Goal)),
6921 novel_production_calls(ConstraintSymbols,IDs,Suspensions,RuleNb,Tuple,Goals).
6923 history_susps(RestIDs,ReversedRestSusps,Susp,ID,HistorySusps) :-
6924 reverse(ReversedRestSusps,RestSusps),
6925 sort_by_key([Susp|RestSusps],[ID|RestIDs],HistorySusps).
6927 named_history_susps([],_,_,[]).
6928 named_history_susps([HistoryID|HistoryIDs],IDs,Susps,[HistorySusp|HistorySusps]) :-
6929 select2(HistoryID,HistorySusp,IDs,Susps,RestIDs,RestSusps), !,
6930 named_history_susps(HistoryIDs,RestIDs,RestSusps,HistorySusps).
6934 gen_var_susp_list_for([Head],Terms,VarDict,HeadVars,VarsSusp,Susp) :-
6937 head_info(Head,A,_Vars,Susp,VarsSusp,HeadPairs),
6938 get_constraint_mode(F/A,Mode),
6939 head_arg_matches(HeadPairs,Mode,[],_,VarDict),
6940 extra_active_delegate_variables(Head,Terms,VarDict,ExtraVars),
6941 append(VarsSusp,ExtraVars,HeadVars).
6942 gen_var_susp_list_for([Head|Heads],Terms,NVarDict,VarsSusps,Rest,Susps) :-
6943 gen_var_susp_list_for(Heads,[Head|Terms],VarDict,Rest,_,_),
6946 head_info(Head,A,_Vars,Susp,_VarsSusp,HeadPairs),
6947 get_constraint_mode(F/A,Mode),
6948 head_arg_matches(HeadPairs,Mode,VarDict,_,NVarDict),
6949 passive_delegate_variables(Head,Heads,Terms,NVarDict,HeadVars),
6950 append(HeadVars,[Susp,Susps|Rest],VarsSusps).
6953 % VarDict for the copies of variables in the original heads
6954 % VarsSuspsList list of lists of arguments for the successive heads
6955 % FirstVarsSusp top level arguments
6956 % SuspList list of all suspensions
6957 % Iterators list of all iterators
6958 gen_var_susp_list_for_b([Head],NextHeads,VarDict,[HeadVars],VarsSusp,[Susp],[]) :-
6961 head_info(Head,A,_Vars,Susp,VarsSusp,Pairs), % make variables for argument positions
6962 get_constraint_mode(F/A,Mode),
6963 head_arg_matches(Pairs,Mode,[],_,VarDict), % copy variables inside arguments, build dictionary
6964 extra_active_delegate_variables(Head,NextHeads,VarDict,ExtraVars), % decide what additional variables are needed
6965 append(VarsSusp,ExtraVars,HeadVars). % add additional variables to head variables
6966 gen_var_susp_list_for_b([Head|Heads],NextHeads,NVarDict,[Vars|RestVars],FirstVarsSusp,[Susp|SuspList],[Susps|Iterators]) :-
6967 gen_var_susp_list_for_b(Heads,[Head|NextHeads],VarDict,RestVars,FirstVarsSusp,SuspList,Iterators),
6970 head_info(Head,A,_Vars,Susp,_VarsSusp,HeadPairs),
6971 get_constraint_mode(F/A,Mode),
6972 head_arg_matches(HeadPairs,Mode,VarDict,_,NVarDict),
6973 passive_delegate_variables(Head,Heads,NextHeads,NVarDict,HeadVars),
6974 append(HeadVars,[Susp,Susps],Vars).
6976 get_prop_inner_loop_vars([Head],NextHeads,HeadVars,VarDict,Susp,Vars,[]) :-
6979 head_info(Head,A,Vars,Susp,VarsSusp,Pairs),
6980 get_constraint_mode(F/A,Mode),
6981 head_arg_matches(Pairs,Mode,[],_,VarDict),
6982 extra_active_delegate_variables(Head,NextHeads,VarDict,ExtraVars),
6983 append(VarsSusp,ExtraVars,HeadVars).
6984 get_prop_inner_loop_vars([Head|Heads],Terms,VarsSusps,NVarDict,MainSusp,MainVars,[Susp|RestSusps]) :-
6985 get_prop_inner_loop_vars(Heads,[Head|Terms],RestVarsSusp,VarDict,MainSusp,MainVars,RestSusps),
6988 head_info(Head,A,_Vars,Susp,_VarsSusp,Pairs),
6989 get_constraint_mode(F/A,Mode),
6990 head_arg_matches(Pairs,Mode,VarDict,_,NVarDict),
6991 passive_delegate_variables(Head,Heads,Terms,NVarDict,HeadVars),
6992 append(HeadVars,[Susp,Susps|RestVarsSusp],VarsSusps).
6994 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6996 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6998 %% | _ \ __ _ ___ ___(_)_ _____ | | | | ___ __ _ __| |
6999 %% | |_) / _` / __/ __| \ \ / / _ \ | |_| |/ _ \/ _` |/ _` |
7000 %% | __/ (_| \__ \__ \ |\ V / __/ | _ | __/ (_| | (_| |
7001 %% |_| \__,_|___/___/_| \_/ \___| |_| |_|\___|\__,_|\__,_|
7004 %% | _ \ ___| |_ _ __(_) _____ ____ _| |
7005 %% | |_) / _ \ __| '__| |/ _ \ \ / / _` | |
7006 %% | _ < __/ |_| | | | __/\ V / (_| | |
7007 %% |_| \_\___|\__|_| |_|\___| \_/ \__,_|_|
7010 %% | _ \ ___ ___ _ __ __| | ___ _ __(_)_ __ __ _
7011 %% | |_) / _ \/ _ \| '__/ _` |/ _ \ '__| | '_ \ / _` |
7012 %% | _ < __/ (_) | | | (_| | __/ | | | | | | (_| |
7013 %% |_| \_\___|\___/|_| \__,_|\___|_| |_|_| |_|\__, |
7016 reorder_heads(RuleNb,Head,RestHeads,RestIDs,NRestHeads,NRestIDs) :-
7017 ( chr_pp_flag(reorder_heads,on), length(RestHeads,Length), Length =< 6 ->
7018 reorder_heads_main(RuleNb,Head,RestHeads,RestIDs,NRestHeads,NRestIDs)
7020 NRestHeads = RestHeads,
7024 reorder_heads_main(RuleNb,Head,RestHeads,RestIDs,NRestHeads,NRestIDs) :-
7025 term_variables(Head,Vars),
7026 InitialData = entry([],[],Vars,RestHeads,RestIDs,RuleNb),
7027 copy_term_nat(InitialData,InitialDataCopy),
7028 a_star(InitialDataCopy,FD^(chr_translate:final_data(FD)),N^EN^C^(chr_translate:expand_data(N,EN,C)),FinalData),
7029 InitialDataCopy = InitialData,
7030 FinalData = entry(RNRestHeads,RNRestIDs,_,_,_,_),
7031 reverse(RNRestHeads,NRestHeads),
7032 reverse(RNRestIDs,NRestIDs).
7034 final_data(Entry) :-
7035 Entry = entry(_,_,_,_,[],_).
7037 expand_data(Entry,NEntry,Cost) :-
7038 Entry = entry(Heads,IDs,Vars,NHeads,NIDs,RuleNb),
7039 select2(Head1,ID1,NHeads,NIDs,NHeads1,NIDs1),
7040 term_variables([Head1|Vars],Vars1),
7041 NEntry = entry([Head1|Heads],[ID1|IDs],Vars1,NHeads1,NIDs1,RuleNb),
7042 order_score(Head1,ID1,Vars,NHeads1,RuleNb,Cost).
7044 % Assigns score to head based on known variables and heads to lookup
7045 order_score(Head,ID,KnownVars,RestHeads,RuleNb,Score) :-
7047 get_store_type(F/A,StoreType),
7048 order_score(StoreType,Head,ID,KnownVars,RestHeads,RuleNb,Score).
7050 order_score(default,Head,_ID,KnownVars,RestHeads,RuleNb,Score) :-
7051 term_variables(Head,HeadVars),
7052 term_variables(RestHeads,RestVars),
7053 order_score_vars(HeadVars,KnownVars,RestVars,Score).
7054 order_score(multi_inthash(Indexes),Head,_ID,KnownVars,RestHeads,RuleNb,Score) :-
7055 order_score_indexes(Indexes,Head,KnownVars,0,Score).
7056 order_score(multi_hash(Indexes),Head,_ID,KnownVars,RestHeads,RuleNb,Score) :-
7057 order_score_indexes(Indexes,Head,KnownVars,0,Score).
7058 order_score(global_ground,Head,ID,KnownVars,RestHeads,RuleNb,Score) :-
7059 term_variables(Head,HeadVars),
7060 term_variables(RestHeads,RestVars),
7061 order_score_vars(HeadVars,KnownVars,RestVars,Score_),
7062 Score is Score_ * 2.
7063 order_score(var_assoc_store(_,_),_,_,_,_,_,1).
7064 order_score(global_singleton,_Head,ID,_KnownVars,_RestHeads,_RuleNb,Score) :-
7065 Score = 1. % guaranteed O(1)
7067 order_score(multi_store(StoreTypes),Head,ID,KnownVars,RestHeads,RuleNb,Score) :-
7068 find_with_var_identity(
7070 t(Head,KnownVars,RestHeads),
7071 ( lists:member(ST,StoreTypes), chr_translate:order_score(ST,Head,ID,KnownVars,RestHeads,RuleNb,S) ),
7074 min_list(Scores,Score).
7075 order_score(identifier_store(Index),Head,ID,KnownVars,RestHeads,RuleNb,Score) :-
7077 order_score(type_indexed_identifier_store(_,_),Head,ID,KnownVars,RestHeads,RuleNb,Score) :-
7080 order_score_indexes([],_,_,Score,NScore) :-
7081 Score > 0, NScore = 100.
7082 order_score_indexes([I|Is],Head,KnownVars,Score,NScore) :-
7083 multi_hash_key_args(I,Head,Args),
7084 ( forall(Arg,Args,memberchk_eq(Arg,KnownVars)) ->
7089 order_score_indexes(Is,Head,KnownVars,Score1,NScore).
7091 order_score_vars(Vars,KnownVars,RestVars,Score) :-
7092 order_score_count_vars(Vars,KnownVars,RestVars,K-R-O),
7096 Score is max(10 - K,0)
7098 Score is max(10 - R,1) * 10
7100 Score is max(10-O,1) * 100
7102 order_score_count_vars([],_,_,0-0-0).
7103 order_score_count_vars([V|Vs],KnownVars,RestVars,NK-NR-NO) :-
7104 order_score_count_vars(Vs,KnownVars,RestVars,K-R-O),
7105 ( memberchk_eq(V,KnownVars) ->
7108 ; memberchk_eq(V,RestVars) ->
7116 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7118 %% |_ _|_ __ | (_)_ __ (_)_ __ __ _
7119 %% | || '_ \| | | '_ \| | '_ \ / _` |
7120 %% | || | | | | | | | | | | | | (_| |
7121 %% |___|_| |_|_|_|_| |_|_|_| |_|\__, |
7125 create_get_mutable_ref(V,M,GM) :- GM = (M = mutable(V)).
7126 create_get_mutable(V,M,GM) :- M = mutable(V), GM = true.
7130 %% create_get_mutable(V,M,GM) :- GM = get_mutable(V,M).
7131 %% create_get_mutable_ref(V,M,GM) :- GM = get_mutable(V,M).
7134 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7136 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7138 %% | | | | |_(_) (_) |_ _ _
7139 %% | | | | __| | | | __| | | |
7140 %% | |_| | |_| | | | |_| |_| |
7141 %% \___/ \__|_|_|_|\__|\__, |
7144 % Create a fresh variable.
7147 % Create =N= fresh variables.
7151 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs) :-
7152 vars_susp(A,Vars,Susp,VarsSusp),
7154 pairup(Args,Vars,HeadPairs).
7156 inc_id([N|Ns],[O|Ns]) :-
7158 dec_id([N|Ns],[M|Ns]) :-
7161 extend_id(Id,[0|Id]).
7163 next_id([_,N|Ns],[O|Ns]) :-
7166 build_head(F,A,Id,Args,Head) :-
7167 buildName(F,A,Id,Name),
7168 ( (chr_pp_flag(debugable,on) ; is_stored(F/A), has_active_occurrence(F/A),
7169 ( may_trigger(F/A) ;
7170 get_allocation_occurrence(F/A,AO),
7171 get_max_occurrence(F/A,MO),
7173 Head =.. [Name|Args]
7175 init(Args,ArgsWOSusp), % XXX not entirely correct!
7176 Head =.. [Name|ArgsWOSusp]
7179 buildName(Fct,Aty,List,Result) :-
7180 ( (chr_pp_flag(debugable,on) ; (once((is_stored(Fct/Aty), ( has_active_occurrence(Fct/Aty) ; chr_pp_flag(late_allocation,off)),
7181 ( may_trigger(Fct/Aty) ; get_allocation_occurrence(Fct/Aty,AO), get_max_occurrence(Fct/Aty,MO),
7182 MO >= AO ) ; List \= [0])) ) ) ->
7183 atom_concat(Fct, (/) ,FctSlash),
7184 atomic_concat(FctSlash,Aty,FctSlashAty),
7185 buildName_(List,FctSlashAty,Result)
7190 buildName_([],Name,Name).
7191 buildName_([N|Ns],Name,Result) :-
7192 buildName_(Ns,Name,Name1),
7193 atom_concat(Name1,'__',NameDash), % '_' is a char :-(
7194 atomic_concat(NameDash,N,Result).
7196 vars_susp(A,Vars,Susp,VarsSusp) :-
7198 append(Vars,[Susp],VarsSusp).
7200 make_attr(N,Mask,SuspsList,Attr) :-
7201 length(SuspsList,N),
7202 Attr =.. [v,Mask|SuspsList].
7204 or_pattern(Pos,Pat) :-
7206 Pat is 1 << Pow. % was 2 ** X
7208 and_pattern(Pos,Pat) :-
7210 Y is 1 << X, % was 2 ** X
7211 Pat is (-1)*(Y + 1).
7213 make_name(Prefix,F/A,Name) :-
7214 atom_concat_list([Prefix,F,(/),A],Name).
7216 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7217 % Storetype dependent lookup
7219 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
7220 %% lookup_passive_head(+Head,+PreviousVars,+RenamingVarDict,
7221 %% -Goal,-SuspensionList) is det.
7223 % Create a universal lookup goal for given head.
7224 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
7225 lookup_passive_head(Head,PreJoin,VarDict,Goal,AllSusps) :-
7227 get_store_type(F/A,StoreType),
7228 lookup_passive_head(StoreType,Head,PreJoin,VarDict,[],Goal,AllSusps).
7230 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
7231 %% lookup_passive_head(+Head,+PreviousVars,+RenamingVarDict,+GroundVars,
7232 %% -Goal,-SuspensionList) is det.
7234 % Create a universal lookup goal for given head.
7235 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
7236 lookup_passive_head(Head,PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
7238 get_store_type(F/A,StoreType),
7239 lookup_passive_head(StoreType,Head,PreJoin,VarDict,GroundVars,Goal,AllSusps).
7241 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
7242 %% lookup_passive_head(+StoreType,+Head,+PreviousVars,+RenamingVarDict,
7243 %% +GroundVars,-Goal,-SuspensionList) is det.
7245 % Create a universal lookup goal for given head.
7246 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
7247 lookup_passive_head(default,Head,PreJoin,VarDict,_,Goal,AllSusps) :-
7249 passive_head_via(Head,PreJoin,VarDict,Goal,AllSusps).
7250 lookup_passive_head(multi_inthash(Indexes),Head,_PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
7251 hash_lookup_passive_head(inthash,Indexes,Head,VarDict,GroundVars,Goal,AllSusps,_).
7252 lookup_passive_head(multi_hash(Indexes),Head,_PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
7253 hash_lookup_passive_head(hash,Indexes,Head,VarDict,GroundVars,Goal,AllSusps,_).
7254 lookup_passive_head(global_ground,Head,_PreJoin,_VarDict,_,Goal,AllSusps) :-
7256 global_ground_store_name(F/A,StoreName),
7257 make_get_store_goal(StoreName,AllSusps,Goal), % Goal = nb_getval(StoreName,AllSusps),
7258 update_store_type(F/A,global_ground).
7259 lookup_passive_head(var_assoc_store(VarIndex,KeyIndex),Head,_PreJoin,VarDict,_,Goal,AllSusps) :-
7260 arg(VarIndex,Head,OVar),
7261 arg(KeyIndex,Head,OKey),
7262 translate([OVar,OKey],VarDict,[Var,Key]),
7263 get_target_module(Module),
7265 get_attr(Var,Module,AssocStore),
7266 lookup_assoc_store(AssocStore,Key,AllSusps)
7268 lookup_passive_head(global_singleton,Head,_PreJoin,_VarDict,_,Goal,AllSusps) :-
7270 global_singleton_store_name(F/A,StoreName),
7271 make_get_store_goal(StoreName,Susp,GetStoreGoal),
7272 Goal = (GetStoreGoal,Susp \== [],AllSusps = [Susp]),
7273 update_store_type(F/A,global_singleton).
7274 lookup_passive_head(multi_store(StoreTypes),Head,PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
7276 member(ST,StoreTypes),
7277 lookup_passive_head(ST,Head,PreJoin,VarDict,GroundVars,Goal,AllSusps)
7279 lookup_passive_head(identifier_store(Index),Head,PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
7281 arg(Index,Head,Var),
7282 translate([Var],VarDict,[KeyVar]),
7283 delay_phase_end(validate_store_type_assumptions,
7284 identifier_lookup(F/A,Index,AllSusps,KeyVar,Goal)
7286 update_store_type(F/A,identifier_store(Index)),
7287 get_identifier_index(F/A,Index,_).
7288 lookup_passive_head(type_indexed_identifier_store(Index,IndexType),Head,PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
7290 arg(Index,Head,Var),
7292 translate([Var],VarDict,[KeyVar]),
7294 ; ground(Var), Var = '$chr_identifier_match'(ActualVar,_) ->
7295 lookup_identifier_atom(IndexType,ActualVar,KeyVar,LookupGoal),
7296 Goal = (LookupGoal,StructGoal)
7298 delay_phase_end(validate_store_type_assumptions,
7299 type_indexed_identifier_lookup(F/A,Index,IndexType,AllSusps,KeyVar,StructGoal)
7301 update_store_type(F/A,type_indexed_identifier_store(Index,IndexType)),
7302 get_type_indexed_identifier_index(IndexType,F/A,Index,_).
7304 identifier_lookup(C,Index,AllSusps,KeyVar,Goal) :-
7305 get_identifier_size(ISize),
7306 functor(Struct,struct,ISize),
7307 get_identifier_index(C,Index,IIndex),
7308 arg(IIndex,Struct,AllSusps),
7309 Goal = (KeyVar = Struct).
7311 type_indexed_identifier_lookup(C,Index,IndexType,AllSusps,KeyVar,Goal) :-
7312 type_indexed_identifier_structure(IndexType,Struct),
7313 get_type_indexed_identifier_index(IndexType,C,Index,IIndex),
7314 arg(IIndex,Struct,AllSusps),
7315 Goal = (KeyVar = Struct).
7317 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
7318 %% hash_lookup_passive_head(+StoreType,+Indexes,+Head,+RenamingVarDict,
7319 %% +GroundVars,-Goal,-SuspensionList,-Index) is det.
7321 % Create a universal hash lookup goal for given head.
7322 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
7323 hash_lookup_passive_head(HashType,Indexes,Head,VarDict,GroundVars,Goal,AllSusps,Index) :-
7325 member(Index,Indexes),
7326 multi_hash_key_args(Index,Head,KeyArgs),
7328 translate(KeyArgs,VarDict,KeyArgCopies)
7330 ground(KeyArgs), KeyArgCopies = KeyArgs
7333 ( KeyArgCopies = [KeyCopy] ->
7336 KeyCopy =.. [k|KeyArgCopies]
7339 multi_hash_via_lookup_goal(F/A,Index,KeyCopy,AllSusps,LookupGoal),
7341 check_ground(GroundVars,KeyArgs,OriginalGroundCheck),
7342 my_term_copy(OriginalGroundCheck,VarDict,GroundCheck),
7344 Goal = (GroundCheck,LookupGoal),
7346 ( HashType == inthash ->
7347 update_store_type(F/A,multi_inthash([Index]))
7349 update_store_type(F/A,multi_hash([Index]))
7352 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
7353 %% existential_lookup(+StoreType,+Head,+PrevVariablesHead,+RenamingVarDict,
7354 %% +GroundVariables,-SuspensionTerm,-Goal,-SuspVar,
7355 %% +VarArgDict,-NewVarArgDict) is det.
7357 % Create existential lookup goal for given head.
7358 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
7359 existential_lookup(var_assoc_store(VarIndex,KeyIndex),Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,Pairs) :- !,
7360 lookup_passive_head(var_assoc_store(VarIndex,KeyIndex),Head,PreJoin,VarDict,GroundVars,UniversalGoal,AllSusps),
7361 sbag_member_call(Susp,AllSusps,Sbag),
7363 delay_phase_end(validate_store_type_assumptions,
7364 ( static_suspension_term(F/A,SuspTerm),
7365 get_static_suspension_field(F/A,SuspTerm,state,active,GetState)
7374 existential_lookup(global_singleton,Head,_PreJoin,_VarDict,_,SuspTerm,Goal,Susp,Pairs,Pairs) :- !,
7376 global_singleton_store_name(F/A,StoreName),
7377 make_get_store_goal(StoreName,Susp,GetStoreGoal),
7379 GetStoreGoal, % nb_getval(StoreName,Susp),
7383 update_store_type(F/A,global_singleton).
7384 existential_lookup(multi_store(StoreTypes),Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :- !,
7386 member(ST,StoreTypes),
7387 existential_lookup(ST,Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs)
7389 existential_lookup(multi_inthash(Indexes),Head,_,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :- !,
7390 existential_hash_lookup(inthash,Indexes,Head,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs).
7391 existential_lookup(multi_hash(Indexes),Head,_,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :- !,
7392 existential_hash_lookup(hash,Indexes,Head,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs).
7393 existential_lookup(identifier_store(Index),Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :- !,
7394 lookup_passive_head(identifier_store(Index),Head,PreJoin,VarDict,GroundVars,LookupGoal,AllSusps),
7395 hash_index_filter(Pairs,Index,NPairs),
7398 ( check_fd_lookup_condition(F,A,Head,KeyArgs) ->
7399 Sbag = (AllSusps = [Susp])
7401 sbag_member_call(Susp,AllSusps,Sbag)
7403 delay_phase_end(validate_store_type_assumptions,
7404 ( static_suspension_term(F/A,SuspTerm),
7405 get_static_suspension_field(F/A,SuspTerm,state,active,GetState)
7411 Susp = SuspTerm, % not inlined
7414 existential_lookup(type_indexed_identifier_store(Index,IndexType),Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :- !,
7415 lookup_passive_head(type_indexed_identifier_store(Index,IndexType),Head,PreJoin,VarDict,GroundVars,LookupGoal,AllSusps),
7416 hash_index_filter(Pairs,Index,NPairs),
7419 ( check_fd_lookup_condition(F,A,Head,KeyArgs) ->
7420 Sbag = (AllSusps = [Susp])
7422 sbag_member_call(Susp,AllSusps,Sbag)
7424 delay_phase_end(validate_store_type_assumptions,
7425 ( static_suspension_term(F/A,SuspTerm),
7426 get_static_suspension_field(F/A,SuspTerm,state,active,GetState)
7432 Susp = SuspTerm, % not inlined
7435 existential_lookup(StoreType,Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,Pairs) :-
7436 lookup_passive_head(StoreType,Head,PreJoin,VarDict,GroundVars,UGoal,Susps),
7437 sbag_member_call(Susp,Susps,Sbag),
7439 delay_phase_end(validate_store_type_assumptions,
7440 ( static_suspension_term(F/A,SuspTerm),
7441 get_static_suspension_field(F/A,SuspTerm,state,active,GetState)
7447 Susp = SuspTerm, % not inlined
7451 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
7452 %% existential_hash_lookup(+StoreType,+Indexes,+Head,+RenamingVarDict,
7453 %% +GroundVariables,-SuspensionTerm,-Goal,-SuspVar,
7454 %% +VarArgDict,-NewVarArgDict) is det.
7456 % Create existential hash lookup goal for given head.
7457 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
7458 existential_hash_lookup(HashType,Indexes,Head,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :-
7459 hash_lookup_passive_head(HashType,Indexes,Head,VarDict,GroundVars,LookupGoal,AllSusps,Index),
7461 hash_index_filter(Pairs,Index,NPairs),
7464 ( check_fd_lookup_condition(F,A,Head,KeyArgs) ->
7465 Sbag = (AllSusps = [Susp])
7467 sbag_member_call(Susp,AllSusps,Sbag)
7469 delay_phase_end(validate_store_type_assumptions,
7470 ( static_suspension_term(F/A,SuspTerm),
7471 get_static_suspension_field(F/A,SuspTerm,state,active,GetState)
7477 Susp = SuspTerm, % not inlined
7481 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
7482 %% hash_index_filter(+Pairs,+Index,-NPairs) is det.
7484 % Filter out pairs already covered by given hash index.
7485 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
7486 hash_index_filter(Pairs,Index,NPairs) :-
7492 hash_index_filter(Pairs,NIndex,1,NPairs).
7494 hash_index_filter([],_,_,[]).
7495 hash_index_filter([P|Ps],Index,N,NPairs) :-
7500 hash_index_filter(Ps,[I|Is],NN,NPs)
7502 hash_index_filter(Ps,Is,NN,NPairs)
7508 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7509 %------------------------------------------------------------------------------%
7510 %% assume_constraint_stores(+ConstraintSymbols) is det.
7512 % Compute all constraint store types that are possible for the given
7513 % =ConstraintSymbols=.
7514 %------------------------------------------------------------------------------%
7515 assume_constraint_stores([]).
7516 assume_constraint_stores([C|Cs]) :-
7517 ( chr_pp_flag(debugable,off),
7518 only_ground_indexed_arguments(C),
7520 get_store_type(C,default) ->
7521 get_indexed_arguments(C,IndexedArgs),
7522 length(IndexedArgs,NbIndexedArgs),
7523 % Construct Index Combinations
7524 ( NbIndexedArgs > 10 ->
7525 findall([Index],member(Index,IndexedArgs),Indexes)
7527 findall(Index,(sublist(Index,IndexedArgs), Index \== []),UnsortedIndexes),
7528 predsort(longer_list,UnsortedIndexes,Indexes)
7531 ( get_functional_dependency(C,1,Pattern,Key),
7532 all_distinct_var_args(Pattern), Key == [] ->
7533 assumed_store_type(C,global_singleton)
7535 get_constraint_type_det(C,ArgTypes),
7536 partition_indexes(Indexes,ArgTypes,HashIndexes,IntHashIndexes,IdentifierIndexes,CompoundIdentifierIndexes),
7538 ( IntHashIndexes = [] ->
7541 Stores = [multi_inthash(IntHashIndexes)|Stores1]
7543 ( HashIndexes = [] ->
7546 Stores1 = [multi_hash(HashIndexes)|Stores2]
7548 ( IdentifierIndexes = [] ->
7551 maplist(wrap_in_functor(identifier_store),IdentifierIndexes,WrappedIdentifierIndexes),
7552 append(WrappedIdentifierIndexes,Stores3,Stores2)
7554 append(CompoundIdentifierIndexes,Stores4,Stores3),
7555 Stores4 = [global_ground],
7556 assumed_store_type(C,multi_store(Stores))
7561 assume_constraint_stores(Cs).
7563 %------------------------------------------------------------------------------%
7564 %% partition_indexes(+Indexes,+Types,
7565 %% -HashIndexes,-IntHashIndexes,-IdentifierIndexes) is det.
7566 %------------------------------------------------------------------------------%
7567 partition_indexes([],_,[],[],[],[]).
7568 partition_indexes([Index|Indexes],Types,HashIndexes,IntHashIndexes,IdentifierIndexes,CompoundIdentifierIndexes) :-
7571 unalias_type(Type,UnAliasedType),
7572 UnAliasedType == chr_identifier ->
7573 IdentifierIndexes = [I|RIdentifierIndexes],
7574 IntHashIndexes = RIntHashIndexes,
7575 HashIndexes = RHashIndexes,
7576 CompoundIdentifierIndexes = RCompoundIdentifierIndexes
7579 unalias_type(Type,UnAliasedType),
7580 nonvar(UnAliasedType),
7581 UnAliasedType = chr_identifier(IndexType) ->
7582 CompoundIdentifierIndexes = [type_indexed_identifier_store(I,IndexType)|RCompoundIdentifierIndexes],
7583 IdentifierIndexes = RIdentifierIndexes,
7584 IntHashIndexes = RIntHashIndexes,
7585 HashIndexes = RHashIndexes
7588 unalias_type(Type,UnAliasedType),
7589 UnAliasedType == dense_int ->
7590 IntHashIndexes = [Index|RIntHashIndexes],
7591 HashIndexes = RHashIndexes,
7592 IdentifierIndexes = RIdentifierIndexes,
7593 CompoundIdentifierIndexes = RCompoundIdentifierIndexes
7596 unalias_type(Type,UnAliasedType),
7597 nonvar(UnAliasedType),
7598 UnAliasedType = chr_identifier(_) ->
7599 % don't use chr_identifiers in hash indexes
7600 IntHashIndexes = RIntHashIndexes,
7601 HashIndexes = RHashIndexes,
7602 IdentifierIndexes = RIdentifierIndexes,
7603 CompoundIdentifierIndexes = RCompoundIdentifierIndexes
7605 IntHashIndexes = RIntHashIndexes,
7606 HashIndexes = [Index|RHashIndexes],
7607 IdentifierIndexes = RIdentifierIndexes,
7608 CompoundIdentifierIndexes = RCompoundIdentifierIndexes
7610 partition_indexes(Indexes,Types,RHashIndexes,RIntHashIndexes,RIdentifierIndexes,RCompoundIdentifierIndexes).
7612 longer_list(R,L1,L2) :-
7622 all_distinct_var_args(Term) :-
7624 copy_term_nat(Args,NArgs),
7625 all_distinct_var_args_(NArgs).
7627 all_distinct_var_args_([]).
7628 all_distinct_var_args_([X|Xs]) :-
7631 all_distinct_var_args_(Xs).
7633 get_indexed_arguments(C,IndexedArgs) :-
7635 get_indexed_arguments(1,A,C,IndexedArgs).
7637 get_indexed_arguments(I,N,C,L) :-
7640 ; ( is_indexed_argument(C,I) ->
7646 get_indexed_arguments(J,N,C,T)
7649 validate_store_type_assumptions([]).
7650 validate_store_type_assumptions([C|Cs]) :-
7651 validate_store_type_assumption(C),
7652 validate_store_type_assumptions(Cs).
7654 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7655 % new code generation
7656 universal_search_iterator_end([CurrentHead|PrevHeads],NextHeads,Rule,F/A,Id,L,T) :-
7657 Rule = rule(H1,_,Guard,Body),
7658 gen_var_susp_list_for_b(PrevHeads,[CurrentHead,NextHeads,Guard,Body],_,VarsAndSuspsList,FirstVarsSusp,_,PrevIterators),
7659 universal_search_iterator_failure_vars(PrevHeads,Id,VarsAndSuspsList,FirstVarsSusp,PrevIterators,PrevVarsAndSusps,PrevId),
7660 flatten(VarsAndSuspsList,VarsAndSusps),
7661 Vars = [ [] | VarsAndSusps],
7662 build_head(F,A,Id,Vars,Head),
7663 build_head(F,A,PrevId,PrevVarsAndSusps,PredecessorCall),
7664 Clause = ( Head :- PredecessorCall),
7667 % functor(CurrentHead,CF,CA),
7668 % check_fd_lookup_condition(CF,CA,CurrentHead,PrevHeads) ->
7671 % gen_var_susp_list_for_b(PrevHeads,[CurrentHead,NextHeads,Guard,Body],_,VarsAndSuspsList,FirstVarsSusp,_,PrevIterators),
7672 % universal_search_iterator_failure_vars(PrevHeads,Id,VarsAndSuspsList,FirstVarsSusp,PrevIterators,PrevVarsAndSusps,PrevId),
7673 % flatten(VarsAndSuspsList,VarsAndSusps),
7674 % Vars = [ [] | VarsAndSusps],
7675 % build_head(F,A,Id,Vars,Head),
7676 % build_head(F,A,PrevId,PrevVarsAndSusps,PredecessorCall),
7677 % Clause = ( Head :- PredecessorCall),
7681 % skips back intelligently over global_singleton lookups
7682 universal_search_iterator_failure_vars(PrevHeads,Id,VarsAndSuspsList,BaseCallArgs,PrevIterators,PrevVarsAndSusps,PrevId) :-
7685 PrevVarsAndSusps = BaseCallArgs
7687 VarsAndSuspsList = [_|AllButFirstList],
7689 ( PrevHeads = [PrevHead|PrevHeads1],
7690 functor(PrevHead,F,A),
7691 check_fd_lookup_condition(F,A,PrevHead,PrevHeads1) ->
7692 PrevIterators = [_|PrevIterators1],
7693 universal_search_iterator_failure_vars(PrevHeads1,PrevId1,AllButFirstList,BaseCallArgs,PrevIterators1,PrevVarsAndSusps,PrevId)
7696 flatten(AllButFirstList,AllButFirst),
7697 PrevIterators = [PrevIterator|_],
7698 PrevVarsAndSusps = [PrevIterator|AllButFirst]
7702 universal_search_iterator([NextHead|RestHeads],[CurrentHead|PreHeads],Rule,F/A,Id,L,T) :-
7703 Rule = rule(_,_,Guard,Body),
7704 gen_var_susp_list_for_b(PreHeads,[CurrentHead,NextHead,RestHeads,Guard,Body],VarDict,PreVarsAndSuspsList,FirstVarsSusp,AllSusps,PrevIterators),
7705 init(AllSusps,PreSusps),
7706 flatten(PreVarsAndSuspsList,PreVarsAndSusps),
7707 gen_var(OtherSusps),
7708 functor(CurrentHead,OtherF,OtherA),
7709 gen_vars(OtherA,OtherVars),
7710 head_info(CurrentHead,OtherA,OtherVars,OtherSusp,_VarsSusp,HeadPairs),
7711 get_constraint_mode(OtherF/OtherA,Mode),
7712 head_arg_matches(HeadPairs,Mode,VarDict,FirstMatching,VarDict1),
7714 delay_phase_end(validate_store_type_assumptions,
7715 ( static_suspension_term(OtherF/OtherA,OtherSuspension),
7716 get_static_suspension_field(OtherF/OtherA,OtherSuspension,state,active,GetState),
7717 get_static_suspension_term_field(arguments,OtherF/OtherA,OtherSuspension,OtherVars)
7721 different_from_other_susps(CurrentHead,OtherSusp,PreHeads,PreSusps,DiffSuspGoals),
7722 % create_get_mutable_ref(active,State,GetMutable),
7724 OtherSusp = OtherSuspension,
7729 add_heads_ground_variables([CurrentHead|PreHeads],[],GroundVars),
7730 lookup_passive_head(NextHead,[CurrentHead|PreHeads],VarDict1,GroundVars,NextSuspGoal,NextSusps),
7731 inc_id(Id,NestedId),
7732 ClauseVars = [[OtherSusp|OtherSusps]|PreVarsAndSusps],
7733 build_head(F,A,Id,ClauseVars,ClauseHead),
7734 passive_delegate_variables(CurrentHead,PreHeads,[NextHead,RestHeads,Guard,Body],VarDict1,CurrentHeadVars),
7735 append([NextSusps|CurrentHeadVars],[OtherSusp,OtherSusps|PreVarsAndSusps],NestedVars),
7736 build_head(F,A,NestedId,NestedVars,NestedHead),
7738 ( check_fd_lookup_condition(OtherF,OtherA,CurrentHead,PreHeads) -> % iterator (OtherSusps) is empty at runtime
7739 universal_search_iterator_failure_vars(PreHeads,Id,PreVarsAndSuspsList,FirstVarsSusp,PrevIterators,PreVarsAndSusps1,PrevId),
7740 RecursiveVars = PreVarsAndSusps1
7742 RecursiveVars = [OtherSusps|PreVarsAndSusps],
7745 build_head(F,A,PrevId,RecursiveVars,RecursiveHead),
7758 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7760 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7761 % Observation Analysis
7766 % Analysis based on Abstract Interpretation paper.
7769 % stronger analysis domain [research]
7772 initial_call_pattern/1,
7774 call_pattern_worker/1,
7775 final_answer_pattern/2,
7776 abstract_constraints/1,
7780 ai_observed_internal/2,
7782 ai_not_observed_internal/2,
7786 ai_observation_gather_results/0.
7788 :- chr_type abstract_domain ---> odom(program_point,list(constraint)).
7789 :- chr_type program_point == any.
7791 :- chr_option(mode,initial_call_pattern(+)).
7792 :- chr_option(type_declaration,call_pattern(abstract_domain)).
7794 :- chr_option(mode,call_pattern(+)).
7795 :- chr_option(type_declaration,call_pattern(abstract_domain)).
7797 :- chr_option(mode,call_pattern_worker(+)).
7798 :- chr_option(type_declaration,call_pattern_worker(abstract_domain)).
7800 :- chr_option(mode,final_answer_pattern(+,+)).
7801 :- chr_option(type_declaration,final_answer_pattern(abstract_domain,abstract_domain)).
7803 :- chr_option(mode,abstract_constraints(+)).
7804 :- chr_option(type_declaration,abstract_constraints(list)).
7806 :- chr_option(mode,depends_on(+,+)).
7807 :- chr_option(type_declaration,depends_on(abstract_domain,abstract_domain)).
7809 :- chr_option(mode,depends_on_as(+,+,+)).
7810 :- chr_option(mode,depends_on_ap(+,+,+,+)).
7811 :- chr_option(mode,depends_on_goal(+,+)).
7812 :- chr_option(mode,ai_is_observed(+,+)).
7813 :- chr_option(mode,ai_not_observed(+,+)).
7814 % :- chr_option(mode,ai_observed(+,+)).
7815 :- chr_option(mode,ai_not_observed_internal(+,+)).
7816 :- chr_option(mode,ai_observed_internal(+,+)).
7819 abstract_constraints_fd @
7820 abstract_constraints(_) \ abstract_constraints(_) <=> true.
7822 ai_observed_internal(C,O) \ ai_not_observed_internal(C,O) <=> true.
7823 ai_not_observed_internal(C,O) \ ai_not_observed_internal(C,O) <=> true.
7824 ai_observed_internal(C,O) \ ai_observed_internal(C,O) <=> true.
7826 ai_not_observed(C,O) \ ai_is_observed(C,O) <=> fail.
7827 ai_is_observed(_,_) <=> true.
7829 ai_observation_gather_results \ ai_observed_internal(C,O) <=> true. % ai_observed(C,O).
7830 ai_observation_gather_results \ ai_not_observed_internal(C,O) <=> ai_not_observed(C,O).
7831 ai_observation_gather_results <=> true.
7833 %------------------------------------------------------------------------------%
7834 % Main Analysis Entry
7835 %------------------------------------------------------------------------------%
7836 ai_observation_analysis(ACs) :-
7837 ( chr_pp_flag(ai_observation_analysis,on),
7838 get_target_module(Module), '$chr_compiled_with_version'(3) -> % , Module \== guard_entailment ->
7839 list_to_ord_set(ACs,ACSet),
7840 abstract_constraints(ACSet),
7841 ai_observation_schedule_initial_calls(ACSet,ACSet),
7842 ai_observation_gather_results
7847 ai_observation_schedule_initial_calls([],_).
7848 ai_observation_schedule_initial_calls([AC|RACs],ACs) :-
7849 ai_observation_schedule_initial_call(AC,ACs),
7850 ai_observation_schedule_initial_calls(RACs,ACs).
7852 ai_observation_schedule_initial_call(AC,ACs) :-
7853 ai_observation_top(AC,CallPattern),
7854 % ai_observation_bot(AC,ACs,CallPattern),
7855 initial_call_pattern(CallPattern).
7857 ai_observation_schedule_new_calls([],AP).
7858 ai_observation_schedule_new_calls([AC|ACs],AP) :-
7860 initial_call_pattern(odom(AC,Set)),
7861 ai_observation_schedule_new_calls(ACs,AP).
7863 final_answer_pattern(CP,AP1) \ final_answer_pattern(CP,AP2)
7865 ai_observation_leq(AP2,AP1)
7869 initial_call_pattern(CP) \ initial_call_pattern(CP) <=> true.
7871 initial_call_pattern(CP) ==> call_pattern(CP).
7873 initial_call_pattern(CP), final_answer_pattern(CP,AP), abstract_constraints(ACs) # ID3
7875 ai_observation_schedule_new_calls(ACs,AP)
7879 call_pattern(CP) \ call_pattern(CP) <=> true.
7881 depends_on(CP1,CP2), final_answer_pattern(CP2,AP) ==>
7882 final_answer_pattern(CP1,AP).
7884 %call_pattern(CP) ==> writeln(call_pattern(CP)).
7886 call_pattern(CP) ==> call_pattern_worker(CP).
7888 %------------------------------------------------------------------------------%
7890 %------------------------------------------------------------------------------%
7893 %call_pattern(odom([],Set)) ==>
7894 % final_answer_pattern(odom([],Set),odom([],Set)).
7896 call_pattern_worker(odom([],Set)) <=>
7897 % writeln(' - AbstractGoal'(odom([],Set))),
7898 final_answer_pattern(odom([],Set),odom([],Set)).
7901 call_pattern_worker(odom([G|Gs],Set)) <=>
7902 % writeln(' - AbstractGoal'(odom([G|Gs],Set))),
7904 depends_on_goal(odom([G|Gs],Set),CP1),
7907 depends_on_goal(CP1,CP2), final_answer_pattern(CP2,AP2) \ depends_on(CP1,_) # ID
7908 <=> true pragma passive(ID).
7909 depends_on_goal(CP1,CP2), final_answer_pattern(CP2,AP2)
7911 CP1 = odom([_|Gs],_),
7915 depends_on(CP1,CCP).
7917 %------------------------------------------------------------------------------%
7919 %------------------------------------------------------------------------------%
7920 call_pattern_worker(odom(builtin,Set)) <=>
7921 % writeln(' - AbstractSolve'(odom(builtin,Set))),
7922 ord_empty(EmptySet),
7923 final_answer_pattern(odom(builtin,Set),odom([],EmptySet)).
7925 %------------------------------------------------------------------------------%
7927 %------------------------------------------------------------------------------%
7928 max_occurrence(C,MO) # ID2 \ call_pattern_worker(odom(occ(C,O),Set))
7932 % writeln(' - AbstractDrop'(odom(occ(C,O),Set))),
7933 final_answer_pattern(odom(occ(C,O),Set),odom([],Set))
7937 %------------------------------------------------------------------------------%
7939 %------------------------------------------------------------------------------%
7940 call_pattern_worker(odom(AC,Set))
7944 % writeln(' - AbstractActivate'(odom(AC,Set))),
7945 CP = odom(occ(AC,1),Set),
7947 depends_on(odom(AC,Set),CP).
7949 %------------------------------------------------------------------------------%
7951 %------------------------------------------------------------------------------%
7952 occurrence(C,O,RuleNb,ID,_) # ID2 \ call_pattern_worker(odom(occ(C,O),Set))
7954 is_passive(RuleNb,ID)
7956 % writeln(' - AbstractPassive'(odom(occ(C,O),Set))),
7959 DCP = odom(occ(C,NO),Set),
7961 final_answer_pattern(odom(occ(C,O),Set),odom([],Set)),
7962 depends_on(odom(occ(C,O),Set),DCP)
7965 %------------------------------------------------------------------------------%
7967 %------------------------------------------------------------------------------%
7970 occurrence(C,O,RuleNb,ID,simplification) # ID2 \ call_pattern_worker(odom(occ(C,O),Set))
7972 \+ is_passive(RuleNb,ID)
7974 % writeln(' - AbstractPassive'(odom(occ(C,O),Set))),
7975 ai_observation_memo_simplification_rest_heads(C,O,AbstractRestHeads),
7976 ai_observation_observe_set(Set,AbstractRestHeads,Set2),
7977 ai_observation_memo_abstract_goal(RuleNb,AG),
7978 call_pattern(odom(AG,Set2)),
7981 DCP = odom(occ(C,NO),Set),
7983 depends_on_as(odom(occ(C,O),Set),odom(AG,Set2),DCP),
7984 % DEADLOCK AVOIDANCE
7985 final_answer_pattern(odom(occ(C,O),Set),odom([],Set))
7989 depends_on_as(CP,CPS,CPD),
7990 final_answer_pattern(CPS,APS),
7991 final_answer_pattern(CPD,APD) ==>
7992 ai_observation_lub(APS,APD,AP),
7993 final_answer_pattern(CP,AP).
7997 ai_observation_memo_simplification_rest_heads/3,
7998 ai_observation_memoed_simplification_rest_heads/3.
8000 :- chr_option(mode,ai_observation_memo_simplification_rest_heads(+,+,?)).
8001 :- chr_option(mode,ai_observation_memoed_simplification_rest_heads(+,+,+)).
8003 ai_observation_memoed_simplification_rest_heads(C,O,RH) \ ai_observation_memo_simplification_rest_heads(C,O,QRH)
8006 abstract_constraints(ACs) # ID1, occurrence(C,O,RuleNb,ID,_) # ID2, rule(RuleNb,Rule) # ID3 \ ai_observation_memo_simplification_rest_heads(C,O,QRH)
8008 Rule = pragma(rule(H1,H2,_,_),ids(IDs1,_),_,_,_),
8009 once(select2(ID,_,IDs1,H1,_,RestH1)),
8010 ai_observation_abstract_constraints(RestH1,ACs,ARestHeads),
8011 ai_observation_abstract_constraints(H2,ACs,AH2),
8012 append(ARestHeads,AH2,AbstractHeads),
8013 sort(AbstractHeads,QRH),
8014 ai_observation_memoed_simplification_rest_heads(C,O,QRH)
8020 ai_observation_memo_simplification_rest_heads(_,_,_) <=> fail.
8022 %------------------------------------------------------------------------------%
8023 % Abstract Propagate
8024 %------------------------------------------------------------------------------%
8028 occurrence(C,O,RuleNb,ID,propagation) # ID2 \ call_pattern_worker(odom(occ(C,O),Set))
8030 \+ is_passive(RuleNb,ID)
8032 % writeln(' - AbstractPropagate'(odom(occ(C,O),Set))),
8034 ai_observation_memo_propagation_rest_heads(C,O,AHs),
8035 ai_observation_observe_set(Set,AHs,Set2),
8036 ord_add_element(Set2,C,Set3),
8037 ai_observation_memo_abstract_goal(RuleNb,AG),
8038 call_pattern(odom(AG,Set3)),
8039 ( ord_memberchk(C,Set2) ->
8046 DCP = odom(occ(C,NO),Set),
8048 depends_on_ap(odom(occ(C,O),Set),odom(AG,Set3),DCP,Delete)
8053 ai_observation_memo_propagation_rest_heads/3,
8054 ai_observation_memoed_propagation_rest_heads/3.
8056 :- chr_option(mode,ai_observation_memo_propagation_rest_heads(+,+,?)).
8057 :- chr_option(mode,ai_observation_memoed_propagation_rest_heads(+,+,+)).
8059 ai_observation_memoed_propagation_rest_heads(C,O,RH) \ ai_observation_memo_propagation_rest_heads(C,O,QRH)
8062 abstract_constraints(ACs) # ID1, occurrence(C,O,RuleNb,ID,_) # ID2, rule(RuleNb,Rule) # ID3 \ ai_observation_memo_propagation_rest_heads(C,O,QRH)
8064 Rule = pragma(rule(H1,H2,_,_),ids(_,IDs2),_,_,_),
8065 once(select2(ID,_,IDs2,H2,_,RestH2)),
8066 ai_observation_abstract_constraints(RestH2,ACs,ARestHeads),
8067 ai_observation_abstract_constraints(H1,ACs,AH1),
8068 append(ARestHeads,AH1,AbstractHeads),
8069 sort(AbstractHeads,QRH),
8070 ai_observation_memoed_propagation_rest_heads(C,O,QRH)
8076 ai_observation_memo_propagation_rest_heads(_,_,_) <=> fail.
8078 depends_on_ap(CP,CPP,CPD,Delete), final_answer_pattern(CPD,APD) ==>
8079 final_answer_pattern(CP,APD).
8080 depends_on_ap(CP,CPP,CPD,Delete), final_answer_pattern(CPP,APP),
8081 final_answer_pattern(CPD,APD) ==>
8083 CP = odom(occ(C,O),_),
8084 ( ai_observation_is_observed(APP,C) ->
8085 ai_observed_internal(C,O)
8087 ai_not_observed_internal(C,O)
8090 APP = odom([],Set0),
8091 ord_del_element(Set0,C,Set),
8096 ai_observation_lub(NAPP,APD,AP),
8097 final_answer_pattern(CP,AP).
8099 %------------------------------------------------------------------------------%
8101 %------------------------------------------------------------------------------%
8103 call_pattern_worker(CP) <=> chr_error(internal,'AI observation analysis: unexpected abstract state ~w\n',[CP]).
8105 %------------------------------------------------------------------------------%
8106 % Auxiliary Predicates
8107 %------------------------------------------------------------------------------%
8109 ai_observation_lub(odom(AG,S1),odom(AG,S2),odom(AG,S3)) :-
8110 ord_intersection(S1,S2,S3).
8112 ai_observation_bot(AG,AS,odom(AG,AS)).
8114 ai_observation_top(AG,odom(AG,EmptyS)) :-
8117 ai_observation_leq(odom(AG,S1),odom(AG,S2)) :-
8120 ai_observation_observe_set(S,ACSet,NS) :-
8121 ord_subtract(S,ACSet,NS).
8123 ai_observation_abstract_constraint(C,ACs,AC) :-
8128 ai_observation_abstract_constraints(Cs,ACs,NACs) :-
8129 findall(NAC,(member(C,Cs),ai_observation_abstract_constraint(C,ACs,NAC)),NACs).
8131 %------------------------------------------------------------------------------%
8132 % Abstraction of Rule Bodies
8133 %------------------------------------------------------------------------------%
8136 ai_observation_memoed_abstract_goal/2,
8137 ai_observation_memo_abstract_goal/2.
8139 :- chr_option(mode,ai_observation_memoed_abstract_goal(+,+)).
8140 :- chr_option(mode,ai_observation_memo_abstract_goal(+,?)).
8142 ai_observation_memoed_abstract_goal(RuleNb,AG) # ID1 \ ai_observation_memo_abstract_goal(RuleNb,QAG)
8148 rule(RuleNb,Rule) # ID1, abstract_constraints(ACs) # ID2 \ ai_observation_memo_abstract_goal(RuleNb,QAG)
8150 Rule = pragma(rule(H1,H2,Guard,Body),_,_,_,_),
8151 ai_observation_abstract_goal_(H1,H2,Guard,Body,ACs,AG),
8153 ai_observation_memoed_abstract_goal(RuleNb,AG)
8158 ai_observation_abstract_goal_(H1,H2,Guard,G,ACs,AG) :-
8159 % also guard: e.g. b, c(X) ==> Y=X | p(Y).
8160 term_variables((H1,H2,Guard),HVars),
8161 append(H1,H2,Heads),
8162 % variables that are declared to be ground are safe,
8163 ground_vars(Heads,GroundVars),
8164 % so we remove them from the list of 'dangerous' head variables
8165 list_difference_eq(HVars,GroundVars,HV),
8166 ai_observation_abstract_goal(G,ACs,AG,[],HV),!.
8167 % writeln(ai_observation_abstract_goal(G,ACs,AG,[],HV)).
8168 % HV are 'dangerous' variables, all others are fresh and safe
8171 ground_vars([H|Hs],GroundVars) :-
8173 get_constraint_mode(F/A,Mode),
8174 head_info(H,A,_Vars,_Susp,_HeadVars,HeadPairs),
8175 head_arg_matches(HeadPairs,Mode,[],_FirstMatching,_VarDict1,[],GroundVars1),
8176 ground_vars(Hs,GroundVars2),
8177 append(GroundVars1,GroundVars2,GroundVars).
8179 ai_observation_abstract_goal((G1,G2),ACs,List,Tail,HV) :- !, % conjunction
8180 ai_observation_abstract_goal(G1,ACs,List,IntermediateList,HV),
8181 ai_observation_abstract_goal(G2,ACs,IntermediateList,Tail,HV).
8182 ai_observation_abstract_goal((G1;G2),ACs,List,Tail,HV) :- !, % disjunction
8183 ai_observation_abstract_goal(G1,ACs,List,IntermediateList,HV),
8184 ai_observation_abstract_goal(G2,ACs,IntermediateList,Tail,HV).
8185 ai_observation_abstract_goal((G1->G2),ACs,List,Tail,HV) :- !, % if-then
8186 ai_observation_abstract_goal(G1,ACs,List,IntermediateList,HV),
8187 ai_observation_abstract_goal(G2,ACs,IntermediateList,Tail,HV).
8188 ai_observation_abstract_goal(C,ACs,[AC|Tail],Tail,HV) :-
8189 ai_observation_abstract_constraint(C,ACs,AC), !. % CHR constraint
8190 ai_observation_abstract_goal(true,_,Tail,Tail,_) :- !.
8191 ai_observation_abstract_goal(writeln(_),_,Tail,Tail,_) :- !.
8192 % non-CHR constraint is safe if it only binds fresh variables
8193 ai_observation_abstract_goal(G,_,Tail,Tail,HV) :-
8194 builtin_binds_b(G,Vars),
8195 intersect_eq(Vars,HV,[]),
8197 ai_observation_abstract_goal(G,_,[AG|Tail],Tail,_) :-
8198 AG = builtin. % default case if goal is not recognized/safe
8200 ai_observation_is_observed(odom(_,ACSet),AC) :-
8201 \+ ord_memberchk(AC,ACSet).
8203 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8204 unconditional_occurrence(C,O) :-
8205 get_occurrence(C,O,RuleNb,ID),
8206 get_rule(RuleNb,PRule),
8207 PRule = pragma(ORule,_,_,_,_),
8208 copy_term_nat(ORule,Rule),
8209 Rule = rule(H1,H2,Guard,_),
8210 guard_entailment:entails_guard([chr_pp_headvariables(H1,H2)],Guard),
8212 H1 = [Head], H2 == []
8214 H2 = [Head], H1 == [], \+ may_trigger(C)
8218 unconditional_occurrence_args(Args).
8220 unconditional_occurrence_args([]).
8221 unconditional_occurrence_args([X|Xs]) :-
8224 unconditional_occurrence_args(Xs).
8226 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8228 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8229 % Partial wake analysis
8231 % In a Var = Var unification do not wake up constraints of both variables,
8232 % but rather only those of one variable.
8233 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8235 :- chr_constraint partial_wake_analysis/0.
8236 :- chr_constraint no_partial_wake/1.
8237 :- chr_option(mode,no_partial_wake(+)).
8238 :- chr_constraint wakes_partially/1.
8239 :- chr_option(mode,wakes_partially(+)).
8241 partial_wake_analysis, occurrence(FA,O,RuleNb,ID,Type), rule(RuleNb,Rule), constraint_mode(FA,ArgModes)
8243 Rule = pragma(rule(H1,H2,Guard,Body),_,_,_,_),
8244 ( is_passive(RuleNb,ID) ->
8246 ; Type == simplification ->
8247 select(H,H1,RestH1),
8249 term_variables(Guard,Vars),
8250 partial_wake_args(Args,ArgModes,Vars,FA)
8251 ; % Type == propagation ->
8252 select(H,H2,RestH2),
8254 term_variables(Guard,Vars),
8255 partial_wake_args(Args,ArgModes,Vars,FA)
8258 partial_wake_args([],_,_,_).
8259 partial_wake_args([Arg|Args],[Mode|Modes],Vars,C) :-
8263 ; memberchk_eq(Arg,Vars) ->
8271 partial_wake_args(Args,Modes,Vars,C).
8273 no_partial_wake(C) \ no_partial_wake(C) <=> true.
8275 no_partial_wake(C) \ wakes_partially(C) <=> fail.
8277 wakes_partially(C) <=> true.
8280 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8281 % Generate rules that implement chr_show_store/1 functionality.
8287 % Generates additional rules:
8289 % $show, C1 # ID ==> writeln(C1) pragma passive(ID).
8291 % $show, Cn # ID ==> writeln(Cn) pragma passive(ID).
8294 generate_show_constraint(Constraints0,Constraints,Rules0,Rules) :-
8295 ( chr_pp_flag(show,on) ->
8296 Constraints = ['$show'/0|Constraints0],
8297 generate_show_rules(Constraints0,Rules,[Rule|Rules0]),
8298 inc_rule_count(RuleNb),
8300 rule(['$show'],[],true,true),
8307 Constraints = Constraints0,
8311 generate_show_rules([],Rules,Rules).
8312 generate_show_rules([F/A|Rest],[Rule|Tail],Rules) :-
8314 inc_rule_count(RuleNb),
8316 rule([],['$show',C],true,writeln(C)),
8322 generate_show_rules(Rest,Tail,Rules).
8324 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8325 % Custom supension term layout
8327 static_suspension_term(F/A,Suspension) :-
8328 suspension_term_base(F/A,Base),
8330 functor(Suspension,suspension,Arity).
8332 has_suspension_field(FA,Field) :-
8333 suspension_term_base_fields(FA,Fields),
8334 memberchk(Field,Fields).
8336 suspension_term_base(FA,Base) :-
8337 suspension_term_base_fields(FA,Fields),
8338 length(Fields,Base).
8340 suspension_term_base_fields(FA,Fields) :-
8341 ( chr_pp_flag(debugable,on) ->
8344 % 3. Propagation History
8345 % 4. Generation Number
8346 % 5. Continuation Goal
8348 Fields = [id,state,history,generation,continuation,functor]
8350 ( uses_history(FA) ->
8351 Fields = [id,state,history|Fields2]
8352 ; only_ground_indexed_arguments(FA), get_functional_dependency(FA,1,_,_) ->
8353 Fields = [state|Fields2]
8355 Fields = [id,state|Fields2]
8357 ( only_ground_indexed_arguments(FA) ->
8358 get_store_type(FA,StoreType),
8359 basic_store_types(StoreType,BasicStoreTypes),
8360 ( memberchk(global_ground,BasicStoreTypes) ->
8363 % 3. Propagation History
8364 % 4. Global List Prev
8365 Fields2 = [global_list_prev]
8369 % 3. Propagation History
8372 ; may_trigger(FA) ->
8375 % 3. Propagation History
8376 ( uses_field(FA,generation) ->
8377 % 4. Generation Number
8378 % 5. Global List Prev
8379 Fields2 = [generation,global_list_prev]
8381 Fields2 = [global_list_prev]
8386 % 3. Propagation History
8387 % 4. Global List Prev
8388 Fields2 = [global_list_prev]
8392 get_static_suspension_term_field(FieldName,FA,StaticSuspension,Field) :-
8393 suspension_term_base_fields(FA,Fields),
8394 nth(Index,Fields,FieldName), !,
8395 arg(Index,StaticSuspension,Field).
8396 get_static_suspension_term_field(arguments,FA,StaticSuspension,Field) :- !,
8397 suspension_term_base(FA,Base),
8398 StaticSuspension =.. [_|Args],
8399 drop(Base,Args,Field).
8400 get_static_suspension_term_field(FieldName,FA,_StaticSuspension,_Field) :-
8401 chr_error(internal,'Trying to obtain field ~w of ~w, wich does not have it!',[FieldName,FA]).
8404 get_dynamic_suspension_term_field(FieldName,FA,DynamicSuspension,Field,Goal) :-
8405 suspension_term_base_fields(FA,Fields),
8406 nth(Index,Fields,FieldName), !,
8407 Goal = arg(Index,DynamicSuspension,Field).
8408 get_dynamic_suspension_term_field(arguments,FA,DynamicSuspension,Field,Goal) :- !,
8409 static_suspension_term(FA,StaticSuspension),
8410 get_static_suspension_term_field(arguments,FA,StaticSuspension,Field),
8411 Goal = (DynamicSuspension = StaticSuspension).
8412 get_dynamic_suspension_term_field(argument(I),FA,DynamicSuspension,Field,Goal) :- !,
8413 suspension_term_base(FA,Base),
8415 Goal = arg(Index,DynamicSuspension,Field).
8416 get_dynamic_suspension_term_field(FieldName,FA,_DynamicSuspension,_Field,_Goal) :-
8417 chr_error(internal,'Dynamic goal to get ~w of ~w, which does not have this field!',[FieldName,FA]).
8420 set_dynamic_suspension_term_field(FieldName,FA,DynamicSuspension,Field,Goal) :-
8421 suspension_term_base_fields(FA,Fields),
8422 nth(Index,Fields,FieldName), !,
8423 Goal = setarg(Index,DynamicSuspension,Field).
8424 set_dynamic_suspension_term_field(FieldName,FA,_DynamicSuspension,_Field,_Goal) :-
8425 chr_error(internal,'Dynamic goal to set ~w of ~w, which does not have this field!',[FieldName,FA]).
8427 basic_store_types(multi_store(Types),Types) :- !.
8428 basic_store_types(Type,[Type]).
8430 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8437 :- chr_option(mode,phase_end(+)).
8438 :- chr_option(mode,delay_phase_end(+,?)).
8440 phase_end(Phase) \ delay_phase_end(Phase,Goal) <=> call(Goal).
8441 % phase_end(Phase) <=> true.
8444 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8448 novel_production_call/4.
8450 :- chr_option(mode,uses_history(+)).
8451 :- chr_option(mode,does_use_history(+,+)).
8452 :- chr_option(mode,novel_production_call(+,+,?,?)).
8454 does_use_history(FA,Occ) \ does_use_history(FA,Occ) <=> true.
8455 does_use_history(FA,_) \ uses_history(FA) <=> true.
8456 uses_history(_FA) <=> fail.
8458 does_use_history(FA,Occ) \ novel_production_call(FA,Occ,PossibleGoal,Goal) <=> Goal = PossibleGoal.
8459 novel_production_call(FA,_,_PossibleGoal,Goal) <=> Goal = true.
8465 :- chr_option(mode,uses_field(+,+)).
8466 :- chr_option(mode,does_use_field(+,+)).
8468 does_use_field(FA,Field) \ does_use_field(FA,Field) <=> true.
8469 does_use_field(FA,Field) \ uses_field(FA,Field) <=> true.
8470 uses_field(_FA,_Field) <=> fail.
8475 used_states_known/0.
8477 :- chr_option(mode,uses_state(+,+)).
8478 :- chr_option(mode,if_used_state(+,+,?,?,?)).
8481 % states ::= not_stored_yet | passive | active | triggered | removed
8483 % allocate CREATES not_stored_yet
8484 % remove CHECKS not_stored_yet
8485 % activate CHECKS not_stored_yet
8487 % ==> no allocate THEN no not_stored_yet
8489 % recurs CREATES inactive
8490 % lookup CHECKS inactive
8492 % insert CREATES active
8493 % activate CREATES active
8494 % lookup CHECKS active
8495 % recurs CHECKS active
8497 % runsusp CREATES triggered
8498 % lookup CHECKS triggered
8500 % ==> no runsusp THEN no triggered
8502 % remove CREATES removed
8503 % runsusp CHECKS removed
8504 % lookup CHECKS removed
8505 % recurs CHECKS removed
8507 % ==> no remove THEN no removed
8509 % ==> no allocate, no remove, no active/inactive distinction THEN no state at all...
8511 uses_state(Constraint,State) \ uses_state(Constraint,State) <=> true.
8513 used_states_known, uses_state(Constraint,State) \ if_used_state(Constraint,State,Used,NotUsed,ResultGoal)
8514 <=> ResultGoal = Used.
8515 used_states_known \ if_used_state(Constraint,State,Used,NotUsed,ResultGoal)
8516 <=> ResultGoal = NotUsed.
8517 % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8518 % % In-place updates
8520 % inplace_updates(Constraints) :-
8521 % ( chr_pp_flag(inplace_updates,off) ->
8524 % inplace_updates0(Constraints)
8527 % inplace_updates0([]).
8528 % inplace_updates([C|Cs]) :-
8529 % inplace_update_allowed(C),
8530 % inplace_updates0(Cs).
8533 % inplace_update_allowed/1,
8534 % inplace_update_safe/1,
8535 % is_safe_inplace_update/1,
8536 % partial_remove_insert/7.
8538 % :- chr_option(mode,inplace_update_allowed(+)).
8539 % :- chr_option(mode,inplace_update_safe(+)).
8540 % :- chr_option(mode,is_safe_inplace_update(+)).
8541 % :- chr_option(mode,partial_remove_insert(+,?,?,?,?,?)).
8543 % % pointless to even check for in-place updates if C is never removed
8544 % occurrence(C,ON,RuleNb,ID,_), rule(RuleNb,Rule) \ inplace_update_allowed(C)
8550 % inplace_update_allowed(C) ==> reuse_susps_test(C).
8552 % inplace_update_allowed(C) <=> inplace_update_safe(C).
8555 % safe_body_check/5,
8556 % all_occs_passive_or_safe/2.
8558 % abstract_constraints(ACs) \ safe_body_check(H1,H2,Guard,G,C)
8560 % ai_observation_abstract_goal_(H1,H2,Guard,G,ACs,AG),
8561 % check_abstract_body_safety(AG,C).
8563 % safe_body_check(H1,H2,Guard,G,C) <=> fail.
8565 % check_abstract_body_safety([],_).
8566 % check_abstract_body_safety([builtin|_],_) :- !, fail.
8567 % check_abstract_body_safety([AC|Rest],C) :-
8568 % all_occs_passive_or_safe(AC,C),
8569 % check_abstract_body_safety(Rest,C).
8571 % % this breaks loops
8572 % this_one_should_not_be_all_passive @
8573 % all_occs_passive_or_safe(AC,C), all_occs_passive_or_safe(AC,C) <=> fail.
8575 % abstract_constraints(ACs), occurrence(AC,ON,RuleNb,ID,_), rule(RuleNb,Rule), all_occs_passive_or_safe(AC,C)
8577 % \+ is_passive(RuleNb,ID),
8578 % Rule = pragma(rule(Hr,Hk,Guard,Body),ids(IDr,IDk),_,_,_)
8580 % ai_observation_abstract_constraints(Hr,ACs,ARemovedHeads),
8581 % %not safe if it is removed
8582 % \+ memberchk_eq(C,ARemovedHeads),
8583 % safe_body_check(Hr,Hk,Guard,Body,C).
8585 % all_occs_passive_or_safe(AC,C) <=> true.
8587 % check_passive([],RuleNb).
8588 % check_passive([ID|IDs],RuleNb) :-
8589 % is_passive(RuleNb,ID),
8590 % check_passive(IDs,RuleNb).
8592 % inplace_update_safe(C) \ is_safe_inplace_update(C) <=> true.
8593 % is_safe_inplace_update(C) <=> fail.
8595 % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8598 % inplace_updates2/0,
8601 % inplace_updates2 \ maybe_inplace(C,_,Del,Ins,DelClause,InsClause,_,_,_,_,_,_,_,_,_,_)#Id
8603 % chr_pp_flag(inplace_updates,off)
8611 % maybe_inplace(C,Susp,Del,Ins,DelClause,InsClause,UpdateDelClause,UpdateInsClause,UpdatedArgs,_,OrigVars,TheNewVars,V1,V2,NewState,ResetHistory)#Id
8615 % ( fix_stores(C,Susp,UpdatedArgs,OrigVars,TheNewVars,UpdatedIndexes,RemoveFromModifiedStores,ReInsertIntoModifiedStores,UpdateInsClause,V1,V2,RSA) ->
8616 % ( reuse_susps_history_reset_needed(C) ->
8617 % update_suspension_field(C,Susp,history,t,ResetHistory)
8619 % ResetHistory = true
8621 % ( has_active_occurrence(C) ->
8623 % InsClause =.. [_|NewVars],
8624 % append(NewVars,[Susp],VarsSusp),
8625 % ( (chr_pp_flag(debugable,on) ; is_stored(C), ( has_active_occurrence(C); chr_pp_flag(late_allocation,off)), ( may_trigger(C) ; get_allocation_occurrence(C,AO), get_max_occurrence(C,MO), MO >= AO ) ) ->
8626 % build_head(F,A,[0],VarsSusp,Delegate),
8627 % ConstraintCall = (SetNewState,Delegate),
8628 % ( NewState = inactive ->
8629 % SetNewState = true
8631 % update_suspension_field(C,Susp,state,inactive,SetNewState)
8633 % reuse_susps_removed_needed(C),
8634 % Del = (RemoveFromModifiedStores,UpdateDelClause),
8635 % Ins = (ReInsertIntoModifiedStores,RSA,ConstraintCall)
8641 % Del = (RemoveFromModifiedStores,UpdateDelClause),
8642 % Ins = (ReInsertIntoModifiedStores,RSA),
8644 % (NewState = active -> true ; true)
8655 % fix_stores(C,Susp,UpdatedArgs,OrigVars,TheNewVars,UpdatedIndexes,RemoveFromModifiedStores,ReInsertIntoModifiedStores,SetArgs,V1,V2,RestSetArgs) :-
8656 % suspension_term_base(C,Base),
8657 % get_store_type(C,StoreType),
8658 % ( StoreType == default ->
8659 % RemoveFromModifiedStores = true,
8661 % none_indexed(UpdatedArgs,C),
8662 % UpdatedIndexes = [],
8663 % ReInsertIntoModifiedStores = true,
8664 % keep_nonindex_setargs(SetArgs,RestSetArgs,Base)
8666 % UpdatedIndexes = UpdatedArgs,
8667 % attach_constraint_atom(C,NewVars2,Susp,Attach),
8668 % detach_constraint_atom(C,OrigVars2,Susp,Detach),
8669 % ReInsertIntoModifiedStores = ('chr attach_diff'(OrigVars,TheNewVars,OrigVars2,NewVars2), Detach, Attach),
8670 % keep_nonindex_setargs(SetArgs,RestSetArgs,Base)
8673 % indexargs(StoreType,KeepArgs),
8674 % intersect_eq(KeepArgs,UpdatedArgs,UpdatedIndexes1),
8675 % multi_arg_updated_indexes(StoreType,UpdatedIndexes1,UpdatedIndexes,ModifiedStore),
8676 % generate_insert_constraint_body2(ModifiedStore,C,Susp,V1,V2,ReInsertIntoModifiedStores),
8677 % keep_nonindex_setargs(SetArgs,UpdatedIndexes1,RestSetArgs,Base),
8678 % RemoveFromModifiedStores = true
8681 % keep_nonindex_setargs(SetArgs,RestSetArgs,Base) :-
8682 % keep_nonindex_setargs(SetArgs,[],RestSetArgs,Base).
8684 % keep_nonindex_setargs(SetArgs,UpdatedIndexes1,RestSetArgs,Base) :-
8685 % conj2list(SetArgs,SA),
8686 % keep_nonindex_setargs_(SA,UpdatedIndexes1,RSA,Base),
8687 % list2conj(RSA,RestSetArgs).
8689 % keep_nonindex_setargs_([],_,[],_).
8690 % keep_nonindex_setargs_([X|Rest],UI,[X|Rest2],Base) :-
8692 % keep_nonindex_setargs_(Rest,UI,Rest2,Base).
8693 % keep_nonindex_setargs_([setarg(Pos,X,Y)|Rest],UI,Rest2,Base) :-
8694 % CPos is Pos - 6,!, % TOM: What is the magic number 6?
8695 % ( memberchk(CPos,UI) ->
8699 % CPos2 is CPos + Base,
8700 % Rest2 = [setarg(CPos2,X,Y)|R2]
8702 % Rest2 = [setarg(Pos,X,Y)|R2]
8705 % keep_nonindex_setargs_(Rest,UI,R2,Base).
8706 % keep_nonindex_setargs_([X|Rest],UI,[X|Rest2],Base) :-
8707 % keep_nonindex_setargs_(Rest,UI,Rest2,Base).
8710 % generate_insert_constraint_body2(multi_inthash(Indexes),C,Susp,O,N,Body) :-
8711 % generate_multi_inthash_insert_constraint_bodies2(Indexes,C,Susp,O,N,Body).
8712 % generate_insert_constraint_body2(multi_hash(Indexes),C,Susp,O,N,Body) :-
8713 % generate_multi_hash_insert_constraint_bodies2(Indexes,C,Susp,O,N,Body).
8714 % generate_insert_constraint_body2(multi_store(StoreTypes),C,Susp,O,N,Body) :-
8716 % find_with_var_identity(
8720 % lists:member(ST,StoreTypes),
8721 % generate_insert_constraint_body2(ST,C,Susp,O,N,B)
8725 % list2conj(Bodies,Body).
8727 % generate_multi_inthash_insert_constraint_bodies2([],_,_,_,_,true).
8728 % generate_multi_inthash_insert_constraint_bodies2([Index|Indexes],FA,Susp,O,N,(Body,Bodies)) :-
8729 % multi_hash_store_name(FA,Index,StoreName),
8733 % set_dynamic_suspension_term_field(argument(Pos),FA,Susp,New,UpdateArgument),
8739 % nb_getval(StoreName,Store),
8740 % chr_integertable_store:delete_ht(Store,Orig,Susp),
8742 % chr_integertable_store:insert_ht(Store,New,Susp)
8745 % generate_multi_inthash_insert_constraint_bodies2(Indexes,FA,Susp,O,N,Bodies).
8746 % generate_multi_hash_insert_constraint_bodies2([],_,_,_,_,true).
8747 % generate_multi_hash_insert_constraint_bodies2([Index|Indexes],FA,Susp,O,N,(Body,Bodies)) :-
8748 % multi_hash_store_name(FA,Index,StoreName),
8749 % multi_hash_key2(FA,Index,Susp,O,N,Key1,Key2,SetArgs),
8755 % nb_getval(StoreName,Store),
8756 % chr_hashtable_store:delete_ht(Store,Key1,Susp),
8758 % chr_hashtable_store:insert_ht(Store,Key2,Susp)
8761 % generate_multi_hash_insert_constraint_bodies2(Indexes,FA,Susp,O,N,Bodies).
8763 % multi_hash_key2(F/A,Index,Susp,O,N,Key1,Key2,SetArgs) :-
8764 % ( ( integer(Index) ->
8771 % set_dynamic_suspension_term_field(argument(I),F/A,Susp,Key2,SetArgs)
8773 % ; is_list(Index) ->
8774 % sort(Index,Indexes),
8776 % find_with_var_identity(
8777 % SetArg-(KeyO-KeyI),
8779 % (lists:member(I,Indexes),
8780 % lists:nth(I,N,KeyI),
8781 % lists:nth(I,O,KeyO),
8782 % set_dynamic_suspension_term_field(argument(I),F/A,Susp,KeyI,SetArg)),
8784 % pairup(Bodies,Keys,ArgKeyPairs),
8785 % pairup(OldKey,NewKey,Keys),
8786 % Key1 =.. [k|OldKey],
8787 % Key2 =.. [k|NewKey],
8788 % list2conj(Bodies,SetArgs)
8792 % avoid_redundant_arg_getval([],_,_,[]).
8793 % avoid_redundant_arg_getval([arg(Pos,Susp,Var)|Rest],SetArgs,GetVals,Rest2) :-
8794 % already_set(SetArgs,Pos,Susp,Var), !,
8795 % avoid_redundant_arg_getval(Rest,SetArgs,GetVals,Rest2).
8796 % avoid_redundant_arg_getval([nb_getval(Table,Var)|Rest],SetArgs,GetVals,Rest2) :-
8797 % already_got(GetVals,Table,Var), !,
8798 % avoid_redundant_arg_getval(Rest,SetArgs,GetVals,Rest2).
8799 % avoid_redundant_arg_getval([X|Rest],SetArgs,GetVals,[X|Rest2]) :-
8800 % avoid_redundant_arg_getval(Rest,SetArgs,GetVals,Rest2).
8802 % already_set([setarg(Pos,Susp2,Var2)|_],Pos,Susp,Var) :-
8803 % Susp == Susp2, !, Var = Var2.
8804 % already_set([_|Rest],Pos,Susp,Var) :-
8805 % already_set(Rest,Pos,Susp,Var).
8807 % already_got([nb_getval(Table,Var2)|_],Table,Var) :-
8809 % already_got([_|Rest],Table,Var) :- already_got(Rest,Table,Var).
8813 % % TOM: Is this predicate used?
8815 % get_store_type(C,StoreType),
8817 % StoreType = global_singleton
8819 % StoreType = multi_store([global_singleton])
8823 % inplace_updates2 \ reuse_susps_removed(_,_,X) <=> X = true.
8824 % inplace_updates2 \ reuse_susps_active(_,_,X) <=> X = true.
8826 % inplace_updates2 \
8827 % partial_remove_insert(F/A,X,TheNewVars,PartialRemove,PartialInsert,SetArgs,V2)
8829 % (get_store_type(F/A,StoreType),
8830 % (StoreType \== default ->
8831 % indexargs(StoreType,UpdatedArgs)
8833 % length(UpdatedArgs,A),
8834 % fill_inc_numbers(UpdatedArgs,1)
8837 % fix_stores(F/A,X,UpdatedArgs,V1,TheNewVars
8838 % , UpdatedIndexes, RemoveFromModifiedStores,
8839 % ReInsertIntoModifiedStores,SetArgs,V1,V2,RemainingSetArgs) ->
8840 % term_variables(ReInsertIntoModifiedStores,UsedVars),
8841 % suspension_term_base(F/A,Base),
8843 % getorigvars(V1,Base1,X,UsedVars,GetOrigVars2),
8847 % RemoveFromModifiedStores),
8848 % PartialInsert = (ReInsertIntoModifiedStores,RemainingSetArgs)
8850 % writeln('ERROR: could not fix stores')
8855 % getorigvars([],_,_,_,true).
8856 % getorigvars([V|Vs],Pos,Susp,UV,T) :-
8858 % (memberchk_eq(V,UV) ->
8859 % T = (arg(Pos,Susp,V),RT),
8860 % getorigvars(Vs,Pos1,Susp,UV,RT)
8862 % getorigvars(Vs,Pos1,Susp,UV,T)
8865 % fill_inc_numbers([],_).
8866 % fill_inc_numbers([A|As],A) :- B is A+1, fill_inc_numbers(As,B).
8868 % inplace_updates2 <=> true.
8870 % get_extra_constraint_clauses([],_C,[],[]).
8871 % get_extra_constraint_clauses([A|RC],C,EC,EC2) :-
8872 % once((A = (Head :- B) ; A = Head)),
8873 % ( Head = (C-H2) ->
8874 % EC = [(H2 :- B)|REC],
8880 % get_extra_constraint_clauses(RC,C,REC,REC2).
8882 % :- chr_constraint onlyone/1, isonlyone/1.
8883 % :- chr_option(mode,onlyone(+)).
8884 % :- chr_option(mode,isonlyone(+)).
8886 % onlyone(C) \ onlyone(C) <=> true.
8887 % onlyone(C) \ isonlyone(C) <=> true.
8888 % isonlyone(C) <=> fail.
8891 % none_indexed([],_).
8892 % none_indexed([A|As],C) :-
8893 % ( is_indexed_argument(C,A), get_constraint_mode(C,Mode), nth(A,Mode,M), M \== (+) ->
8896 % none_indexed(As,C)
8900 % multi_arg_updated_indexes(multi_inthash(Indices),UI,UpdInd,multi_inthash(UpdInd)) :- !,
8901 % find_updated(Indices,UI,UpdInd).
8902 % multi_arg_updated_indexes(multi_hash(Indices),UI,UpdInd,multi_hash(UpdInd)) :- !,
8903 % find_updated(Indices,UI,UpdInd).
8905 % find_updated([],_,[]).
8906 % find_updated([Ind|RInd],UI,RInd2) :-
8907 % intersect_eq(Ind,UI,[]), !,
8908 % find_updated(RInd,UI,RInd2).
8909 % find_updated([Ind|RInd],UI,[Ind|RInd2]) :- !,
8910 % find_updated(RInd,UI,RInd2).
8912 % multi_arg_updated_indexes(multi_store([]),_,[],multi_store([])) :- !.
8913 % multi_arg_updated_indexes(multi_store([S|Ss]),UI,UI2,multi_store([AS|ASs])) :- !,
8914 % multi_arg_updated_indexes(S,UI,X1,AS),
8915 % multi_arg_updated_indexes(multi_store(Ss),UI,X2,multi_store(ASs)),
8916 % append(X1,X2,Args_),
8918 % multi_arg_updated_indexes(_,_,[],multi_store([])).
8923 % indexargs(multi_inthash(Indexes),Args) :- !,indexes2args(Indexes,Args).
8924 % indexargs(multi_hash(Indexes),Args) :- !,indexes2args(Indexes,Args).
8925 % indexargs(multi_store([]),[]) :- !.
8926 % indexargs(multi_store([S|Ss]),Args) :- !,
8928 % indexargs(multi_store(Ss),A2),
8929 % append(A1,A2,Args_),
8931 % indexargs(global_ground,[]).
8932 % indexargs(global_singleton,[]).
8933 % % no default store (need to add support for correct detach-attach)
8935 % indexes2args([],[]).
8936 % indexes2args([[]|R],Ys) :- !, indexes2args(R,Ys).
8937 % indexes2args([[X|Xs]|R],[X|Ys]) :- !,indexes2args([Xs|R],Ys).
8938 % indexes2args([X|R],[X|Ys]) :- !,indexes2args(R,Ys).