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
137 , chr_translate_line_info/3 % +DeclsWithLines, -TranslatedDecls
140 :- use_module(library(lists),[member/2, append/3,reverse/2,permutation/2,last/2]).
141 :- use_module(library(ordsets)).
144 :- use_module(hprolog).
145 :- use_module(pairlist).
146 :- use_module(a_star).
147 :- use_module(listmap).
148 :- use_module(clean_code).
149 :- use_module(builtins).
151 :- use_module(binomialheap).
152 :- use_module(guard_entailment).
153 :- use_module(chr_compiler_options).
154 :- use_module(chr_compiler_utility).
155 :- use_module(chr_compiler_errors).
157 :- op(1150, fx, chr_type).
158 :- op(1130, xfx, --->).
162 :- op(1150, fx, constraints).
163 :- op(1150, fx, chr_constraint).
165 :- chr_option(debug,off).
166 :- chr_option(optimize,full).
167 :- chr_option(check_guard_bindings,off).
169 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
171 :- chr_type list(T) ---> [] ; [T|list(T)].
173 :- chr_type list == list(any).
175 :- chr_type mode ---> (+) ; (-) ; (?).
177 :- chr_type maybe(T) ---> yes(T) ; no.
179 :- chr_type constraint ---> any / any.
181 :- chr_type module_name == any.
183 :- chr_type pragma_rule ---> pragma(rule,idspair,list(pragma_type),maybe(rule_name),rule_nb).
184 :- chr_type rule ---> rule(list(any),list(any),goal,goal).
185 :- chr_type idspair ---> ids(list(id),list(id)).
187 :- chr_type pragma_type ---> passive(id)
190 ; already_in_heads(id)
192 ; history(history_name,list(id)).
193 :- chr_type history_name== any.
195 :- chr_type rule_name == any.
196 :- chr_type rule_nb == natural.
197 :- chr_type id == natural.
198 :- chr_type occurrence == int.
200 :- chr_type goal == any.
202 :- chr_type store_type ---> default
203 ; multi_store(list(store_type))
204 ; multi_hash(list(list(int)))
205 ; multi_inthash(list(list(int)))
208 % EXPERIMENTAL STORES
209 ; atomic_constants(list(int),list(any),atomic_coverage)
210 ; ground_constants(list(int),list(any))
211 ; var_assoc_store(int,list(int))
212 ; identifier_store(int)
213 ; type_indexed_identifier_store(int,any).
214 :- chr_type atomic_coverage ---> complete ; incomplete.
216 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
218 %------------------------------------------------------------------------------%
219 :- chr_constraint chr_source_file/1.
220 :- chr_option(mode,chr_source_file(+)).
221 :- chr_option(type_declaration,chr_source_file(module_name)).
222 %------------------------------------------------------------------------------%
223 chr_source_file(_) \ chr_source_file(_) <=> true.
225 %------------------------------------------------------------------------------%
226 :- chr_constraint get_chr_source_file/1.
227 :- chr_option(mode,get_chr_source_file(-)).
228 :- chr_option(type_declaration,get_chr_source_file(module_name)).
229 %------------------------------------------------------------------------------%
230 chr_source_file(Mod) \ get_chr_source_file(Query)
232 get_chr_source_file(Query)
236 %------------------------------------------------------------------------------%
237 :- chr_constraint target_module/1.
238 :- chr_option(mode,target_module(+)).
239 :- chr_option(type_declaration,target_module(module_name)).
240 %------------------------------------------------------------------------------%
241 target_module(_) \ target_module(_) <=> true.
243 %------------------------------------------------------------------------------%
244 :- chr_constraint get_target_module/1.
245 :- chr_option(mode,get_target_module(-)).
246 :- chr_option(type_declaration,get_target_module(module_name)).
247 %------------------------------------------------------------------------------%
248 target_module(Mod) \ get_target_module(Query)
250 get_target_module(Query)
253 %------------------------------------------------------------------------------%
254 :- chr_constraint line_number/2.
255 :- chr_option(mode,line_number(+,+)).
256 :- chr_option(type_declaration,line_number(rule_nb,int)).
257 %------------------------------------------------------------------------------%
258 line_number(RuleNb,LineNb) \ line_number(RuleNb,LineNumber) <=> true.
260 %------------------------------------------------------------------------------%
261 :- chr_constraint get_line_number/2.
262 :- chr_option(mode,get_line_number(+,-)).
263 :- chr_option(type_declaration,get_line_number(rule_nb,int)).
264 %------------------------------------------------------------------------------%
265 line_number(RuleNb,LineNb) \ get_line_number(RuleNb,Q) <=> Q = LineNb.
266 get_line_number(RuleNb,Q) <=> Q = 0. % no line number available
268 :- chr_constraint indexed_argument/2. % argument instantiation may enable applicability of rule
269 :- chr_option(mode,indexed_argument(+,+)).
270 :- chr_option(type_declaration,indexed_argument(constraint,int)).
272 :- chr_constraint is_indexed_argument/2.
273 :- chr_option(mode,is_indexed_argument(+,+)).
274 :- chr_option(type_declaration,is_indexed_argument(constraint,int)).
276 :- chr_constraint constraint_mode/2.
277 :- chr_option(mode,constraint_mode(+,+)).
278 :- chr_option(type_declaration,constraint_mode(constraint,list(mode))).
280 :- chr_constraint get_constraint_mode/2.
281 :- chr_option(mode,get_constraint_mode(+,-)).
282 :- chr_option(type_declaration,get_constraint_mode(constraint,list(mode))).
284 :- chr_constraint may_trigger/1.
285 :- chr_option(mode,may_trigger(+)).
286 :- chr_option(type_declaration,may_trigger(constraint)).
288 :- chr_constraint only_ground_indexed_arguments/1.
289 :- chr_option(mode,only_ground_indexed_arguments(+)).
290 :- chr_option(type_declaration,only_ground_indexed_arguments(constraint)).
292 :- chr_constraint none_suspended_on_variables/0.
294 :- chr_constraint are_none_suspended_on_variables/0.
296 :- chr_constraint store_type/2.
297 :- chr_option(mode,store_type(+,+)).
298 :- chr_option(type_declaration,store_type(constraint,store_type)).
300 :- chr_constraint get_store_type/2.
301 :- chr_option(mode,get_store_type(+,?)).
302 :- chr_option(type_declaration,get_store_type(constraint,store_type)).
304 :- chr_constraint update_store_type/2.
305 :- chr_option(mode,update_store_type(+,+)).
306 :- chr_option(type_declaration,update_store_type(constraint,store_type)).
308 :- chr_constraint actual_store_types/2.
309 :- chr_option(mode,actual_store_types(+,+)).
310 :- chr_option(type_declaration,actual_store_types(constraint,list(store_type))).
312 :- chr_constraint assumed_store_type/2.
313 :- chr_option(mode,assumed_store_type(+,+)).
314 :- chr_option(type_declaration,assumed_store_type(constraint,store_type)).
316 :- chr_constraint validate_store_type_assumption/1.
317 :- chr_option(mode,validate_store_type_assumption(+)).
318 :- chr_option(type_declaration,validate_store_type_assumption(constraint)).
320 :- chr_constraint rule_count/1.
321 :- chr_option(mode,rule_count(+)).
322 :- chr_option(type_declaration,rule_count(natural)).
324 :- chr_constraint inc_rule_count/1.
325 :- chr_option(mode,inc_rule_count(-)).
326 :- chr_option(type_declaration,inc_rule_count(natural)).
328 rule_count(_) \ rule_count(_)
330 rule_count(C), inc_rule_count(NC)
331 <=> NC is C + 1, rule_count(NC).
333 <=> NC = 1, rule_count(NC).
335 :- chr_constraint passive/2.
336 :- chr_option(mode,passive(+,+)).
338 :- chr_constraint is_passive/2.
339 :- chr_option(mode,is_passive(+,+)).
341 :- chr_constraint any_passive_head/1.
342 :- chr_option(mode,any_passive_head(+)).
344 :- chr_constraint new_occurrence/4.
345 :- chr_option(mode,new_occurrence(+,+,+,+)).
347 :- chr_constraint occurrence/5.
348 :- chr_option(mode,occurrence(+,+,+,+,+)).
349 :- chr_type occurrence_type ---> simplification ; propagation.
350 :- chr_option(type_declaration,occurrence(constraint,occurrence,rule_nb,id,occurrence_type)).
352 :- chr_constraint get_occurrence/4.
353 :- chr_option(mode,get_occurrence(+,+,-,-)).
355 :- chr_constraint get_occurrence_from_id/4.
356 :- chr_option(mode,get_occurrence_from_id(+,-,+,+)).
358 :- chr_constraint max_occurrence/2.
359 :- chr_option(mode,max_occurrence(+,+)).
361 :- chr_constraint get_max_occurrence/2.
362 :- chr_option(mode,get_max_occurrence(+,-)).
364 :- chr_constraint allocation_occurrence/2.
365 :- chr_option(mode,allocation_occurrence(+,+)).
367 :- chr_constraint get_allocation_occurrence/2.
368 :- chr_option(mode,get_allocation_occurrence(+,-)).
370 :- chr_constraint rule/2.
371 :- chr_option(mode,rule(+,+)).
372 :- chr_option(type_declaration,rule(rule_nb,pragma_rule)).
374 :- chr_constraint get_rule/2.
375 :- chr_option(mode,get_rule(+,-)).
376 :- chr_option(type_declaration,get_rule(int,pragma_rule)).
378 :- chr_constraint least_occurrence/2.
379 :- chr_option(mode,least_occurrence(+,+)).
380 :- chr_option(type_declaration,least_occurrence(any,list)).
382 :- chr_constraint is_least_occurrence/1.
383 :- chr_option(mode,is_least_occurrence(+)).
386 indexed_argument(FA,I) \ indexed_argument(FA,I) <=> true.
387 indexed_argument(FA,I) \ is_indexed_argument(FA,I) <=> true.
388 is_indexed_argument(_,_) <=> fail.
390 %%% C O N S T R A I N T M O D E %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
392 constraint_mode(FA,_) \ constraint_mode(FA,_) <=> true.
393 constraint_mode(FA,Mode) \ get_constraint_mode(FA,Q) <=>
395 get_constraint_mode(FA,Q) <=>
399 %%% M A Y T R I G G E R %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
401 may_trigger(FA) <=> \+ has_active_occurrence(FA) | fail.
402 constraint_mode(FA,Mode), indexed_argument(FA,I) \ may_trigger(FA) <=>
406 may_trigger(FA) <=> chr_pp_flag(debugable,on). % in debug mode, we assume everything can be triggered
408 constraint_mode(FA,Mode), indexed_argument(FA,I) \ only_ground_indexed_arguments(FA)
414 only_ground_indexed_arguments(_) <=>
417 none_suspended_on_variables \ none_suspended_on_variables <=> true.
418 none_suspended_on_variables \ are_none_suspended_on_variables <=> true.
419 are_none_suspended_on_variables <=> fail.
420 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
423 % The functionality for inspecting and deciding on the different types of constraint
424 % store / indexes for constraints.
426 store_type(FA,StoreType)
427 ==> chr_pp_flag(verbose,on)
429 format('The indexes for ~w are:\n',[FA]),
430 format_storetype(StoreType).
431 % chr_info(verbose,'Storetype of ~w is ~w.\n',[FA,StoreType]).
433 format_storetype(multi_store(StoreTypes)) :- !,
434 forall(member(StoreType,StoreTypes), format_storetype(StoreType)).
435 format_storetype(atomic_constants(Index,Constants,_)) :-
436 format('\t* a trie index on the argument(s) ~w for the ground terms ~w\n',[Index,Constants]).
437 format_storetype(ground_constants(Index,Constants)) :-
438 format('\t* a trie index on the argument(s) ~w for the ground terms ~w\n',[Index,Constants]).
439 format_storetype(StoreType) :-
440 format('\t* ~w\n',[StoreType]).
448 get_store_type_normal @
449 store_type(FA,Store) \ get_store_type(FA,Query)
452 get_store_type_assumed @
453 assumed_store_type(FA,Store) \ get_store_type(FA,Query)
456 get_store_type_default @
457 get_store_type(_,Query)
460 % 2. Store type registration
461 % ~~~~~~~~~~~~~~~~~~~~~~~~~~
463 actual_store_types(C,STs) \ update_store_type(C,ST)
464 <=> member(ST,STs) | true.
465 update_store_type(C,ST), actual_store_types(C,STs)
467 actual_store_types(C,[ST|STs]).
468 update_store_type(C,ST)
470 actual_store_types(C,[ST]).
472 % 3. Final decision on store types
473 % ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
475 validate_store_type_assumption(C) \ actual_store_types(C,STs), actual_atomic_multi_hash_keys(C,Index,Keys)
477 true % chr_pp_flag(experiment,on)
479 delete(STs,multi_hash([Index]),STs0),
481 ( get_constraint_type(C,Types),
482 nth1(IndexPos,Types,Type),
483 enumerated_atomic_type(Type,Atoms),
485 Completeness = complete
487 Completeness = incomplete
489 actual_store_types(C,[atomic_constants(Index,Keys,Completeness)|STs0]).
490 validate_store_type_assumption(C) \ actual_store_types(C,STs), actual_ground_multi_hash_keys(C,Index,Keys)
492 true % chr_pp_flag(experiment,on)
494 delete(STs,multi_hash([Index]),STs0),
495 actual_store_types(C,[ground_constants(Index,Keys)|STs0]).
496 validate_store_type_assumption(C) \ actual_store_types(C,STs)
498 % chr_pp_flag(experiment,on),
499 memberchk(multi_hash([[Index]]),STs),
500 get_constraint_type(C,Types),
501 nth1(Index,Types,Type),
502 enumerated_atomic_type(Type,Atoms)
504 delete(STs,multi_hash([[Index]]),STs0),
505 actual_store_types(C,[atomic_constants([Index],Atoms,complete)|STs0]).
506 validate_store_type_assumption(C), actual_store_types(C,STs), assumed_store_type(C,_) % automatic assumption
508 ( /* chr_pp_flag(experiment,on), */ forall(member(ST,STs), partial_store(ST)) ->
509 Stores0 = [global_ground|STs]
513 prune_stores(Stores0,Stores),
514 store_type(C,multi_store(Stores)).
515 validate_store_type_assumption(C), actual_store_types(C,STs), store_type(C,_) % user assumption
517 store_type(C,multi_store(STs)).
518 validate_store_type_assumption(C), assumed_store_type(C,_) % no lookups on constraint in debug mode
520 chr_pp_flag(debugable,on)
522 store_type(C,default).
523 validate_store_type_assumption(C), assumed_store_type(C,_) % no lookups on constraint
524 <=> store_type(C,global_ground).
525 validate_store_type_assumption(C)
528 partial_store(ground_constants(_,_)).
529 partial_store(atomic_constants(_,_,incomplete)).
531 % heuristic to reduce the number of indexes
532 % prune_stores(Stores0,Stores) :-
533 % select(multi_hash([Indexes1]),Stores0,Stores1),
534 % Indexes1 = [_,_,_|_],
535 % member(multi_hash([Indexes2]),Stores1),
536 % Indexes2 = [_,_|_],
537 % subset(Indexes2,Indexes1),
541 prune_stores(Stores,Stores).
543 %%% P A S S I V E %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
544 passive(R,ID) \ passive(R,ID) <=> true.
546 passive(RuleNb,ID) \ is_passive(RuleNb,ID) <=> true.
547 is_passive(_,_) <=> fail.
549 passive(RuleNb,_) \ any_passive_head(RuleNb)
553 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
555 max_occurrence(C,N) \ max_occurrence(C,M)
558 max_occurrence(C,MO), new_occurrence(C,RuleNb,ID,Type) <=>
560 occurrence(C,NO,RuleNb,ID,Type),
561 max_occurrence(C,NO).
562 new_occurrence(C,RuleNb,ID,_) <=>
563 chr_error(internal,'new_occurrence: missing max_occurrence for ~w in rule ~w\n',[C,RuleNb]).
565 max_occurrence(C,MON) \ get_max_occurrence(C,Q)
567 get_max_occurrence(C,Q)
568 <=> chr_error(internal,'get_max_occurrence: missing max occurrence for ~w\n',[C]).
570 occurrence(C,ON,Rule,ID,_) \ get_occurrence(C,ON,QRule,QID)
571 <=> Rule = QRule, ID = QID.
572 get_occurrence(C,O,_,_)
573 <=> chr_error(internal,'get_occurrence: missing occurrence ~w:~w\n',[C,O]).
575 occurrence(C,ON,Rule,ID,_) \ get_occurrence_from_id(QC,QON,Rule,ID)
576 <=> QC = C, QON = ON.
577 get_occurrence_from_id(C,O,_,_)
578 <=> chr_error(internal,'get_occurrence_from_id: missing occurrence ~w:~w\n',[]).
580 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
583 late_allocation_analysis(Cs) :-
584 ( chr_pp_flag(late_allocation,on) ->
585 maplist(late_allocation, Cs)
590 late_allocation(C) :- late_allocation(C,0).
591 late_allocation(C,O) :- allocation_occurrence(C,O), !.
592 late_allocation(C,O) :- NO is O + 1, late_allocation(C,NO).
594 % A L L O C C A T I O N O C C U R R E N C E %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
596 allocation_occurrence(C,0) ==> stored_in_guard_before_next_kept_occurrence(C,0).
598 rule(RuleNb,Rule), occurrence(C,O,RuleNb,Id,Type), allocation_occurrence(C,O) ==>
599 \+ is_passive(RuleNb,Id),
601 ( stored_in_guard_before_next_kept_occurrence(C,O) ->
603 ; Rule = pragma(rule([_|_],_,_,_),_,_,_,_) -> % simpagation rule
605 ; is_least_occurrence(RuleNb) -> % propagation rule
611 stored_in_guard_before_next_kept_occurrence(C,O) :-
612 chr_pp_flag(store_in_guards, on),
614 stored_in_guard_lookahead(C,NO).
616 :- chr_constraint stored_in_guard_lookahead/2.
617 :- chr_option(mode, stored_in_guard_lookahead(+,+)).
619 occurrence(C,O,RuleNb,Id,_), passive(RuleNb,Id) \ stored_in_guard_lookahead(C,O) <=>
620 NO is O + 1, stored_in_guard_lookahead(C,NO).
621 occurrence(C,O,RuleNb,Id,Type) \ stored_in_guard_lookahead(C,O) <=>
622 Type == simplification,
623 ( is_stored_in_guard(C,RuleNb) ->
626 NO is O + 1, stored_in_guard_lookahead(C,NO)
628 stored_in_guard_lookahead(_,_) <=> fail.
631 rule(RuleNb,Rule), occurrence(C,O,RuleNb,ID,_), allocation_occurrence(C,AO)
632 \ least_occurrence(RuleNb,[ID|IDs])
633 <=> AO >= O, \+ may_trigger(C) |
634 least_occurrence(RuleNb,IDs).
635 rule(RuleNb,Rule), passive(RuleNb,ID)
636 \ least_occurrence(RuleNb,[ID|IDs])
637 <=> least_occurrence(RuleNb,IDs).
640 ==> Rule = pragma(rule([],_,_,_),ids([],IDs),_,_,_) |
641 least_occurrence(RuleNb,IDs).
643 least_occurrence(RuleNb,[]) \ is_least_occurrence(RuleNb)
645 is_least_occurrence(_)
648 allocation_occurrence(C,O) \ get_allocation_occurrence(C,Q)
650 get_allocation_occurrence(_,Q)
651 <=> chr_pp_flag(late_allocation,off), Q=0.
652 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
654 rule(RuleNb,Rule) \ get_rule(RuleNb,Q)
659 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
661 %%% C O N S T R A I N T I N D E X %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
663 % Default store constraint index assignment.
665 :- chr_constraint constraint_index/2. % constraint_index(F/A,DefaultStoreAndAttachedIndex)
666 :- chr_option(mode,constraint_index(+,+)).
667 :- chr_option(type_declaration,constraint_index(constraint,int)).
669 :- chr_constraint get_constraint_index/2.
670 :- chr_option(mode,get_constraint_index(+,-)).
671 :- chr_option(type_declaration,get_constraint_index(constraint,int)).
673 :- chr_constraint get_indexed_constraint/2.
674 :- chr_option(mode,get_indexed_constraint(+,-)).
675 :- chr_option(type_declaration,get_indexed_constraint(int,constraint)).
677 :- chr_constraint max_constraint_index/1. % max_constraint_index(MaxDefaultStoreAndAttachedIndex)
678 :- chr_option(mode,max_constraint_index(+)).
679 :- chr_option(type_declaration,max_constraint_index(int)).
681 :- chr_constraint get_max_constraint_index/1.
682 :- chr_option(mode,get_max_constraint_index(-)).
683 :- chr_option(type_declaration,get_max_constraint_index(int)).
685 constraint_index(C,Index) \ get_constraint_index(C,Query)
687 get_constraint_index(C,Query)
690 constraint_index(C,Index) \ get_indexed_constraint(Index,Q)
692 get_indexed_constraint(Index,Q)
695 max_constraint_index(Index) \ get_max_constraint_index(Query)
697 get_max_constraint_index(Query)
700 set_constraint_indices(Constraints) :-
701 set_constraint_indices(Constraints,1).
702 set_constraint_indices([],M) :-
704 max_constraint_index(N).
705 set_constraint_indices([C|Cs],N) :-
706 ( ( chr_pp_flag(debugable, on) ; \+ only_ground_indexed_arguments(C), is_stored(C) ; is_stored(C), get_store_type(C,default)
707 ; get_store_type(C,var_assoc_store(_,_))) ->
708 constraint_index(C,N),
710 set_constraint_indices(Cs,M)
712 set_constraint_indices(Cs,N)
715 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
718 :- chr_constraint identifier_size/1.
719 :- chr_option(mode,identifier_size(+)).
720 :- chr_option(type_declaration,identifier_size(natural)).
722 identifier_size(_) \ identifier_size(_)
726 :- chr_constraint get_identifier_size/1.
727 :- chr_option(mode,get_identifier_size(-)).
728 :- chr_option(type_declaration,get_identifier_size(natural)).
730 identifier_size(Size) \ get_identifier_size(Q)
734 get_identifier_size(Q)
738 :- chr_constraint identifier_index/3.
739 :- chr_option(mode,identifier_index(+,+,+)).
740 :- chr_option(type_declaration,identifier_index(constraint,natural,natural)).
742 identifier_index(C,I,_) \ identifier_index(C,I,_)
746 :- chr_constraint get_identifier_index/3.
747 :- chr_option(mode,get_identifier_index(+,+,-)).
748 :- chr_option(type_declaration,get_identifier_index(constraint,natural,natural)).
750 identifier_index(C,I,II) \ get_identifier_index(C,I,Q)
753 identifier_size(Size), get_identifier_index(C,I,Q)
756 identifier_index(C,I,NSize),
757 identifier_size(NSize),
759 get_identifier_index(C,I,Q)
761 identifier_index(C,I,2),
765 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
766 % Type Indexed Identifier Indexes
768 :- chr_constraint type_indexed_identifier_size/2.
769 :- chr_option(mode,type_indexed_identifier_size(+,+)).
770 :- chr_option(type_declaration,type_indexed_identifier_size(any,natural)).
772 type_indexed_identifier_size(IndexType,_) \ type_indexed_identifier_size(IndexType,_)
776 :- chr_constraint get_type_indexed_identifier_size/2.
777 :- chr_option(mode,get_type_indexed_identifier_size(+,-)).
778 :- chr_option(type_declaration,get_type_indexed_identifier_size(any,natural)).
780 type_indexed_identifier_size(IndexType,Size) \ get_type_indexed_identifier_size(IndexType,Q)
784 get_type_indexed_identifier_size(IndexType,Q)
788 :- chr_constraint type_indexed_identifier_index/4.
789 :- chr_option(mode,type_indexed_identifier_index(+,+,+,+)).
790 :- chr_option(type_declaration,type_indexed_identifier_index(any,constraint,natural,natural)).
792 type_indexed_identifier_index(_,C,I,_) \ type_indexed_identifier_index(_,C,I,_)
796 :- chr_constraint get_type_indexed_identifier_index/4.
797 :- chr_option(mode,get_type_indexed_identifier_index(+,+,+,-)).
798 :- chr_option(type_declaration,get_type_indexed_identifier_index(any,constraint,natural,natural)).
800 type_indexed_identifier_index(IndexType,C,I,II) \ get_type_indexed_identifier_index(IndexType,C,I,Q)
803 type_indexed_identifier_size(IndexType,Size), get_type_indexed_identifier_index(IndexType,C,I,Q)
806 type_indexed_identifier_index(IndexType,C,I,NSize),
807 type_indexed_identifier_size(IndexType,NSize),
809 get_type_indexed_identifier_index(IndexType,C,I,Q)
811 type_indexed_identifier_index(IndexType,C,I,2),
812 type_indexed_identifier_size(IndexType,2),
815 type_indexed_identifier_structure(IndexType,Structure) :-
816 type_indexed_identifier_name(IndexType,type_indexed_identifier_struct,Functor),
817 get_type_indexed_identifier_size(IndexType,Arity),
818 functor(Structure,Functor,Arity).
819 type_indexed_identifier_name(IndexType,Prefix,Name) :-
821 IndexTypeName = IndexType
823 term_to_atom(IndexType,IndexTypeName)
825 atom_concat_list([Prefix,'_',IndexTypeName],Name).
827 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
832 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
836 chr_translate(Declarations,NewDeclarations) :-
837 chr_translate_line_info(Declarations,'bootstrap',NewDeclarations).
839 chr_translate_line_info(Declarations,File,NewDeclarations) :-
840 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',[]),
842 chr_source_file(File),
843 partition_clauses(Declarations,Constraints0,Rules0,OtherClauses),
844 chr_compiler_options:sanity_check,
845 check_declared_constraints(Constraints0),
846 generate_show_constraint(Constraints0,Constraints,Rules0,Rules1),
847 add_constraints(Constraints),
849 generate_never_stored_rules(Constraints,NewRules),
851 append(Rules1,NewRules,Rules),
853 check_rules(Rules,Constraints),
854 time('type checking',chr_translate:static_type_check),
855 add_occurrences(Rules),
856 time('functional dependency',chr_translate:functional_dependency_analysis(Rules)),
857 time('set semantics',chr_translate:set_semantics_rules(Rules)),
858 time('symmetry analysis',chr_translate:symmetry_analysis(Rules)),
859 time('guard simplification',chr_translate:guard_simplification),
860 time('late storage',chr_translate:storage_analysis(Constraints)),
861 time('observation',chr_translate:observation_analysis(Constraints)),
862 time('ai observation',chr_translate:ai_observation_analysis(Constraints)),
863 time('late allocation',chr_translate:late_allocation_analysis(Constraints)),
864 partial_wake_analysis,
865 time('assume constraint stores',chr_translate:assume_constraint_stores(Constraints)),
866 time('default constraint indices',chr_translate:set_constraint_indices(Constraints)),
867 time('check storedness assertions',chr_translate:check_storedness_assertions(Constraints)),
868 success_continuation_analysis(Constraints),
870 time('constraint code generation',chr_translate:constraints_code(Constraints,ConstraintClauses)),
871 time('validate store assumptions',chr_translate:validate_store_type_assumptions(Constraints)),
872 phase_end(validate_store_type_assumptions),
874 time('store code generation',chr_translate:store_management_preds(Constraints,StoreClauses)), % depends on actual code used
875 insert_declarations(OtherClauses, Clauses0),
876 chr_module_declaration(CHRModuleDeclaration),
877 append([StoreClauses,ConstraintClauses,CHRModuleDeclaration,[end_of_file]],StuffyGeneratedClauses),
878 clean_clauses(StuffyGeneratedClauses,GeneratedClauses),
879 append([Clauses0,GeneratedClauses], NewDeclarations).
881 store_management_preds(Constraints,Clauses) :-
882 generate_attach_detach_a_constraint_all(Constraints,AttachAConstraintClauses),
883 generate_attr_unify_hook(AttrUnifyHookClauses),
884 generate_attach_increment(AttachIncrementClauses),
885 generate_extra_clauses(Constraints,ExtraClauses),
886 generate_insert_delete_constraints(Constraints,DeleteClauses),
887 generate_attach_code(Constraints,StoreClauses),
888 generate_counter_code(CounterClauses),
889 generate_dynamic_type_check_clauses(TypeCheckClauses),
890 append([AttachAConstraintClauses
891 ,AttachIncrementClauses
892 ,AttrUnifyHookClauses
902 insert_declarations(Clauses0, Clauses) :-
903 findall(:- use_module(chr(Module)),(auxiliary_module(Module), is_used_auxiliary_module(Module)),Decls),
904 append(Clauses0, [:- use_module(chr(chr_runtime))|Decls], Clauses).
906 auxiliary_module(chr_hashtable_store).
907 auxiliary_module(chr_integertable_store).
908 auxiliary_module(chr_assoc_store).
910 generate_counter_code(Clauses) :-
911 ( chr_pp_flag(store_counter,on) ->
913 ('$counter_init'(N1) :- nb_setval(N1,0)) ,
914 ('$counter'(N2,X1) :- nb_getval(N2,X1)),
915 ('$counter_inc'(N) :- nb_getval(N,X), Y is X + 1, nb_setval(N,Y)),
916 (:- '$counter_init'('$insert_counter')),
917 (:- '$counter_init'('$delete_counter')),
918 ('$insert_counter_inc' :- '$counter_inc'('$insert_counter')),
919 ('$delete_counter_inc' :- '$counter_inc'('$delete_counter')),
920 ( counter_stats(I,D) :- '$counter'('$insert_counter',I),'$counter'('$delete_counter',D))
926 % for systems with multifile declaration
927 chr_module_declaration(CHRModuleDeclaration) :-
928 get_target_module(Mod),
929 ( Mod \== chr_translate, chr_pp_flag(toplevel_show_store,on) ->
930 CHRModuleDeclaration = [
931 (:- multifile chr:'$chr_module'/1),
932 chr:'$chr_module'(Mod)
935 CHRModuleDeclaration = []
939 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
941 %% Partitioning of clauses into constraint declarations, chr rules and other
944 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
945 %% partition_clauses(+Clauses,-ConstraintDeclarations,-Rules,-OtherClauses) is det.
946 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
947 partition_clauses([],[],[],[]).
948 partition_clauses([Clause|Clauses],ConstraintDeclarations,Rules,OtherClauses) :-
949 ( parse_rule(Clause,Rule) ->
950 ConstraintDeclarations = RestConstraintDeclarations,
951 Rules = [Rule|RestRules],
952 OtherClauses = RestOtherClauses
953 ; is_declaration(Clause,ConstraintDeclaration) ->
954 append(ConstraintDeclaration,RestConstraintDeclarations,ConstraintDeclarations),
956 OtherClauses = RestOtherClauses
957 ; is_module_declaration(Clause,Mod) ->
959 ConstraintDeclarations = RestConstraintDeclarations,
961 OtherClauses = [Clause|RestOtherClauses]
962 ; is_type_definition(Clause) ->
963 ConstraintDeclarations = RestConstraintDeclarations,
965 OtherClauses = RestOtherClauses
966 ; Clause = (handler _) ->
967 chr_warning(deprecated(Clause),'Backward compatibility: ignoring handler/1 declaration.\n',[]),
968 ConstraintDeclarations = RestConstraintDeclarations,
970 OtherClauses = RestOtherClauses
971 ; Clause = (rules _) ->
972 chr_warning(deprecated(Clause),'Backward compatibility: ignoring rules/1 declaration.\n',[]),
973 ConstraintDeclarations = RestConstraintDeclarations,
975 OtherClauses = RestOtherClauses
976 ; Clause = option(OptionName,OptionValue) ->
977 chr_warning(deprecated(Clause),'Instead use `:-chr_option(~w,~w).\'\n',[OptionName,OptionValue]),
978 handle_option(OptionName,OptionValue),
979 ConstraintDeclarations = RestConstraintDeclarations,
981 OtherClauses = RestOtherClauses
982 ; Clause = (:-chr_option(OptionName,OptionValue)) ->
983 handle_option(OptionName,OptionValue),
984 ConstraintDeclarations = RestConstraintDeclarations,
986 OtherClauses = RestOtherClauses
987 ; Clause = ('$chr_compiled_with_version'(_)) ->
988 ConstraintDeclarations = RestConstraintDeclarations,
990 OtherClauses = ['$chr_compiled_with_version'(3)|RestOtherClauses]
991 ; ConstraintDeclarations = RestConstraintDeclarations,
993 OtherClauses = [Clause|RestOtherClauses]
995 partition_clauses(Clauses,RestConstraintDeclarations,RestRules,RestOtherClauses).
997 '$chr_compiled_with_version'(2).
999 is_declaration(D, Constraints) :- %% constraint declaration
1000 ( D = (:- Decl), Decl =.. [F,Cs], F == (chr_constraint) ->
1001 conj2list(Cs,Constraints0)
1004 Decl =.. [constraints,Cs]
1006 D =.. [constraints,Cs]
1008 conj2list(Cs,Constraints0),
1009 chr_warning(deprecated(D),'Instead use :- chr_constraint ~w.\n',[Cs])
1011 extract_type_mode(Constraints0,Constraints).
1013 extract_type_mode([],[]).
1014 extract_type_mode([F/A|R],[F/A|R2]) :- !,extract_type_mode(R,R2).
1015 extract_type_mode([C0|R],[ConstraintSymbol|R2]) :-
1016 ( C0 = C # Annotation ->
1018 extract_annotation(Annotation,F/A)
1023 ConstraintSymbol = F/A,
1025 extract_types_and_modes(Args,ArgTypes,ArgModes),
1026 assert_constraint_type(ConstraintSymbol,ArgTypes),
1027 constraint_mode(ConstraintSymbol,ArgModes),
1028 extract_type_mode(R,R2).
1030 extract_annotation(stored,Symbol) :-
1031 stored_assertion(Symbol).
1032 extract_annotation(default(Goal),Symbol) :-
1033 never_stored_default(Symbol,Goal).
1035 extract_types_and_modes([],[],[]).
1036 extract_types_and_modes([X|R],[T|R2],[M|R3]) :-
1037 extract_type_and_mode(X,T,M),
1038 extract_types_and_modes(R,R2,R3).
1040 extract_type_and_mode(+(T),T,(+)) :- !.
1041 extract_type_and_mode(?(T),T,(?)) :- !.
1042 extract_type_and_mode(-(T),T,(-)) :- !.
1043 extract_type_and_mode((+),any,(+)) :- !.
1044 extract_type_and_mode((?),any,(?)) :- !.
1045 extract_type_and_mode((-),any,(-)) :- !.
1046 extract_type_and_mode(Illegal,_,_) :-
1047 chr_error(syntax(Illegal),'Illegal mode/type declaration.\n\tCorrect syntax is +type, -type or ?type\n\tor +, - or ?.\n',[]).
1049 is_type_definition(Declaration) :-
1050 ( Declaration = (:- TDef) ->
1055 TDef =.. [chr_type,TypeDef],
1056 ( TypeDef = (Name ---> Def) ->
1057 tdisj2list(Def,DefList),
1058 type_definition(Name,DefList)
1059 ; TypeDef = (Alias == Name) ->
1060 type_alias(Alias,Name)
1062 type_definition(TypeDef,[]),
1063 chr_warning(syntax,'Empty type definition `~w\'.\nAre you sure you want to declare a phantom type?\n',[Declaration])
1066 %% tdisj2list(+Goal,-ListOfGoals) is det.
1068 % no removal of fails, e.g. :- type bool ---> true ; fail.
1069 tdisj2list(Conj,L) :-
1070 tdisj2list(Conj,L,[]).
1072 tdisj2list(Conj,L,T) :-
1074 tdisj2list(G1,L,T1),
1075 tdisj2list(G2,T1,T).
1076 tdisj2list(G,[G | T],T).
1079 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
1080 %% parse_rule(+term,-pragma_rule) is semidet.
1081 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
1082 parse_rule(RI,R) :- %% name @ rule
1083 RI = (Name @ RI2), !,
1084 rule(RI2,yes(Name),R).
1088 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
1089 %% parse_rule(+term,-pragma_rule) is semidet.
1090 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
1092 RI = (RI2 pragma P), !, %% pragmas
1094 Ps = [_] % intercept variable
1098 inc_rule_count(RuleCount),
1099 R = pragma(R1,IDs,Ps,Name,RuleCount),
1100 is_rule(RI2,R1,IDs,R).
1102 inc_rule_count(RuleCount),
1103 R = pragma(R1,IDs,[],Name,RuleCount),
1104 is_rule(RI,R1,IDs,R).
1106 is_rule(RI,R,IDs,RC) :- %% propagation rule
1108 conj2list(H,Head2i),
1109 get_ids(Head2i,IDs2,Head2,RC),
1112 R = rule([],Head2,G,RB)
1114 R = rule([],Head2,true,B)
1116 is_rule(RI,R,IDs,RC) :- %% simplification/simpagation rule
1125 conj2list(H1,Head2i),
1126 conj2list(H2,Head1i),
1127 get_ids(Head2i,IDs2,Head2,0,N,RC),
1128 get_ids(Head1i,IDs1,Head1,N,_,RC),
1129 IDs = ids(IDs1,IDs2)
1130 ; conj2list(H,Head1i),
1132 get_ids(Head1i,IDs1,Head1,RC),
1135 R = rule(Head1,Head2,Guard,Body).
1137 get_ids(Cs,IDs,NCs,RC) :-
1138 get_ids(Cs,IDs,NCs,0,_,RC).
1140 get_ids([],[],[],N,N,_).
1141 get_ids([C|Cs],[N|IDs],[NC|NCs],N,NN,RC) :-
1146 check_direct_pragma(N1,N,RC)
1152 get_ids(Cs,IDs,NCs, M,NN,RC).
1154 check_direct_pragma(passive,Id,PragmaRule) :- !,
1155 PragmaRule = pragma(_,_,_,_,RuleNb),
1157 check_direct_pragma(Abbrev,Id,PragmaRule) :-
1158 ( direct_pragma(FullPragma),
1159 atom_concat(Abbrev,Remainder,FullPragma) ->
1160 chr_warning(problem_pragma(Abbrev,PragmaRule),'completed `~w\' to `~w\'\n',[Abbrev,FullPragma])
1162 chr_warning(unsupported_pragma(Abbrev,PragmaRule),'',[])
1165 direct_pragma(passive).
1167 is_module_declaration((:- module(Mod)),Mod).
1168 is_module_declaration((:- module(Mod,_)),Mod).
1170 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1172 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1174 add_constraints([]).
1175 add_constraints([C|Cs]) :-
1176 max_occurrence(C,0),
1180 constraint_mode(C,Mode),
1181 add_constraints(Cs).
1185 add_rules([Rule|Rules]) :-
1186 Rule = pragma(_,_,_,_,RuleNb),
1190 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1192 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1193 %% Some input verification:
1195 check_declared_constraints(Constraints) :-
1196 check_declared_constraints(Constraints,[]).
1198 check_declared_constraints([],_).
1199 check_declared_constraints([C|Cs],Acc) :-
1200 ( memberchk_eq(C,Acc) ->
1201 chr_error(syntax(C),'Constraint multiply defined: ~w.\n\tRemove redundant declaration!\n',[C])
1205 check_declared_constraints(Cs,[C|Acc]).
1207 %% - all constraints in heads are declared constraints
1208 %% - all passive pragmas refer to actual head constraints
1211 check_rules([PragmaRule|Rest],Decls) :-
1212 check_rule(PragmaRule,Decls),
1213 check_rules(Rest,Decls).
1215 check_rule(PragmaRule,Decls) :-
1216 check_rule_indexing(PragmaRule),
1217 check_trivial_propagation_rule(PragmaRule),
1218 PragmaRule = pragma(Rule,_IDs,Pragmas,_Name,_N),
1219 Rule = rule(H1,H2,_,_),
1220 append(H1,H2,HeadConstraints),
1221 check_head_constraints(HeadConstraints,Decls,PragmaRule),
1222 check_pragmas(Pragmas,PragmaRule).
1224 % Make all heads passive in trivial propagation rule
1225 % ... ==> ... | true.
1226 check_trivial_propagation_rule(PragmaRule) :-
1227 PragmaRule = pragma(Rule,IDs,Pragmas,Name,RuleNb),
1228 ( Rule = rule([],_,_,true) ->
1229 chr_warning(weird_program,'Ignoring propagation rule with empty body: ~@.\n\t\n',[format_rule(PragmaRule)]),
1230 set_all_passive(RuleNb)
1235 check_head_constraints([],_,_).
1236 check_head_constraints([Constr|Rest],Decls,PragmaRule) :-
1237 functor(Constr,F,A),
1238 ( member(F/A,Decls) ->
1239 check_head_constraints(Rest,Decls,PragmaRule)
1241 chr_error(syntax(Constr),'Undeclared constraint ~w in head of ~@.\n\tConstraint should be one of ~w.\n', [F/A,format_rule(PragmaRule),Decls])
1244 check_pragmas([],_).
1245 check_pragmas([Pragma|Pragmas],PragmaRule) :-
1246 check_pragma(Pragma,PragmaRule),
1247 check_pragmas(Pragmas,PragmaRule).
1249 check_pragma(Pragma,PragmaRule) :-
1251 chr_error(syntax(Pragma),'Invalid pragma ~w in ~@.\n\tPragma should not be a variable!\n',[Pragma,format_rule(PragmaRule)]).
1252 check_pragma(passive(ID), PragmaRule) :-
1254 PragmaRule = pragma(_,ids(IDs1,IDs2),_,_,RuleNb),
1255 ( memberchk_eq(ID,IDs1) ->
1257 ; memberchk_eq(ID,IDs2) ->
1260 chr_error(syntax(ID),'Invalid identifier ~w in pragma passive in ~@.\n', [ID,format_rule(PragmaRule)])
1264 check_pragma(mpassive(IDs), PragmaRule) :-
1266 PragmaRule = pragma(_,_,_,_,RuleNb),
1267 chr_warning(experimental,'Experimental pragma ~w. Use with care!\n',[mpassive(IDs)]),
1268 maplist(passive(RuleNb),IDs).
1270 check_pragma(Pragma, PragmaRule) :-
1271 Pragma = already_in_heads,
1273 chr_warning(unsupported_pragma(Pragma,PragmaRule),'Termination and correctness may be affected.\n',[]).
1275 check_pragma(Pragma, PragmaRule) :-
1276 Pragma = already_in_head(_),
1278 chr_warning(unsupported_pragma(Pragma,PragmaRule),'Termination and correctness may be affected.\n',[]).
1280 check_pragma(Pragma, PragmaRule) :-
1281 Pragma = no_history,
1283 chr_warning(experimental,'Experimental pragma no_history. Use with care!\n',[]),
1284 PragmaRule = pragma(_,_,_,_,N),
1287 check_pragma(Pragma, PragmaRule) :-
1288 Pragma = history(HistoryName,IDs),
1290 PragmaRule = pragma(_,ids(IDs1,IDs2),_,_,RuleNb),
1291 chr_warning(experimental,'Experimental pragma ~w. Use with care!\n',[Pragma]),
1293 chr_error(syntax(Pragma),'Pragma history only implemented for propagation rules.\n',[])
1294 ; \+ atom(HistoryName) ->
1295 chr_error(syntax(Pragma),'Illegal argument for pragma history: ~w is not an atom (rule number ~w).\n',[HistoryName,RuleNb])
1297 chr_error(syntax(Pragma),'Illegal argument for pragma history: ~w is not a set (rule number ~w).\n',[IDs,RuleNb])
1298 ; check_history_pragma_ids(IDs,IDs1,IDs2) ->
1299 history(RuleNb,HistoryName,IDs)
1301 chr_error(syntax(Pragma),'Invalid identifier(s) in pragma ~w of rule number ~w.\n',[Pragma,RuleNb])
1303 check_pragma(Pragma,PragmaRule) :-
1304 Pragma = line_number(LineNumber),
1306 PragmaRule = pragma(_,_,_,_,RuleNb),
1307 line_number(RuleNb,LineNumber).
1309 check_history_pragma_ids([], _, _).
1310 check_history_pragma_ids([ID|IDs],IDs1,IDs2) :-
1311 ( memberchk_eq(ID,IDs2) ; memberchk_eq(ID,IDs1) ),
1312 check_history_pragma_ids(IDs,IDs1,IDs2).
1314 check_pragma(Pragma,PragmaRule) :-
1315 chr_error(syntax(Pragma),'Unknown pragma ~w in ~@.\n', [Pragma,format_rule(PragmaRule)]).
1317 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1318 %% no_history(+RuleNb) is det.
1319 :- chr_constraint no_history/1.
1320 :- chr_option(mode,no_history(+)).
1321 :- chr_option(type_declaration,no_history(int)).
1323 %% has_no_history(+RuleNb) is semidet.
1324 :- chr_constraint has_no_history/1.
1325 :- chr_option(mode,has_no_history(+)).
1326 :- chr_option(type_declaration,has_no_history(int)).
1328 no_history(RuleNb) \ has_no_history(RuleNb) <=> true.
1329 has_no_history(_) <=> fail.
1331 :- chr_constraint history/3.
1332 :- chr_option(mode,history(+,+,+)).
1333 :- chr_option(type_declaration,history(any,any,list)).
1335 :- chr_constraint named_history/3.
1337 history(RuleNb,_,_), history(RuleNb,_,_) ==>
1338 chr_error(syntax,'Only one pragma history allowed per rule (rule number ~w)\n',[RuleNb]). %'
1340 history(RuleNb1,Name,IDs1), history(RuleNb2,Name,IDs2) ==>
1341 length(IDs1,L1), length(IDs2,L2),
1343 chr_error(syntax,'The history named ~w does not always range over an equal amount of occurrences.\n',[Name])
1345 test_named_history_id_pairs(RuleNb1,IDs1,RuleNb2,IDs2)
1348 test_named_history_id_pairs(_, [], _, []).
1349 test_named_history_id_pairs(RuleNb1, [ID1|IDs1], RuleNb2, [ID2|IDs2]) :-
1350 test_named_history_id_pair(RuleNb1,ID1,RuleNb2,ID2),
1351 test_named_history_id_pairs(RuleNb1,IDs1,RuleNb2,IDs2).
1353 :- chr_constraint test_named_history_id_pair/4.
1354 :- chr_option(mode,test_named_history_id_pair(+,+,+,+)).
1356 occurrence(C,_,RuleNb1,ID1,_), occurrence(C,_,RuleNb2,ID2,_)
1357 \ test_named_history_id_pair(RuleNb1,ID1,RuleNb2,ID2) <=> true.
1358 test_named_history_id_pair(RuleNb1,ID1,RuleNb2,ID2) <=>
1359 chr_error(syntax,'Occurrences of shared history in rules number ~w and ~w do not correspond\n', [RuleNb2,RuleNb1]).
1361 history(RuleNb,Name,IDs) \ named_history(RuleNb,QName,QIDs) <=> QName = Name, QIDs = IDs.
1362 named_history(_,_,_) <=> fail.
1364 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1367 format_rule(PragmaRule) :-
1368 PragmaRule = pragma(_,_,_,MaybeName,RuleNumber),
1369 ( MaybeName = yes(Name) ->
1370 write('rule '), write(Name)
1372 write('rule number '), write(RuleNumber)
1374 get_line_number(RuleNumber,LineNumber),
1379 check_rule_indexing(PragmaRule) :-
1380 PragmaRule = pragma(Rule,_,_,_,_),
1381 Rule = rule(H1,H2,G,_),
1382 term_variables(H1-H2,HeadVars),
1383 remove_anti_monotonic_guards(G,HeadVars,NG),
1384 check_indexing(H1,NG-H2),
1385 check_indexing(H2,NG-H1),
1387 ( chr_pp_flag(term_indexing,on) ->
1388 term_variables(NG,GuardVariables),
1389 append(H1,H2,Heads),
1390 check_specs_indexing(Heads,GuardVariables,Specs)
1395 :- chr_constraint indexing_spec/2.
1396 :- chr_option(mode,indexing_spec(+,+)).
1398 :- chr_constraint get_indexing_spec/2.
1399 :- chr_option(mode,get_indexing_spec(+,-)).
1402 indexing_spec(FA,Spec) \ get_indexing_spec(FA,R) <=> R = Spec.
1403 get_indexing_spec(_,Spec) <=> Spec = [].
1405 indexing_spec(FA,Specs1), indexing_spec(FA,Specs2)
1407 append(Specs1,Specs2,Specs),
1408 indexing_spec(FA,Specs).
1410 remove_anti_monotonic_guards(G,Vars,NG) :-
1412 remove_anti_monotonic_guard_list(GL,Vars,NGL),
1415 remove_anti_monotonic_guard_list([],_,[]).
1416 remove_anti_monotonic_guard_list([G|Gs],Vars,NGs) :-
1417 ( G = var(X), memberchk_eq(X,Vars) ->
1419 % TODO: this is not correct
1420 % ; G = functor(Term,Functor,Arity), % isotonic
1421 % \+ memberchk_eq(Functor,Vars), \+ memberchk_eq(Arity,Vars) ->
1426 remove_anti_monotonic_guard_list(Gs,Vars,RGs).
1428 check_indexing([],_).
1429 check_indexing([Head|Heads],Other) :-
1432 term_variables(Heads-Other,OtherVars),
1433 check_indexing(Args,1,F/A,OtherVars),
1434 check_indexing(Heads,[Head|Other]).
1436 check_indexing([],_,_,_).
1437 check_indexing([Arg|Args],I,FA,OtherVars) :-
1438 ( is_indexed_argument(FA,I) ->
1441 indexed_argument(FA,I)
1443 term_variables(Args,ArgsVars),
1444 append(ArgsVars,OtherVars,RestVars),
1445 ( memberchk_eq(Arg,RestVars) ->
1446 indexed_argument(FA,I)
1452 term_variables(Arg,NVars),
1453 append(NVars,OtherVars,NOtherVars),
1454 check_indexing(Args,J,FA,NOtherVars).
1456 check_specs_indexing([],_,[]).
1457 check_specs_indexing([Head|Heads],Variables,Specs) :-
1458 Specs = [Spec|RSpecs],
1459 term_variables(Heads,OtherVariables,Variables),
1460 check_spec_indexing(Head,OtherVariables,Spec),
1461 term_variables(Head,NVariables,Variables),
1462 check_specs_indexing(Heads,NVariables,RSpecs).
1464 check_spec_indexing(Head,OtherVariables,Spec) :-
1466 Spec = spec(F,A,ArgSpecs),
1468 check_args_spec_indexing(Args,1,OtherVariables,ArgSpecs),
1469 indexing_spec(F/A,[ArgSpecs]).
1471 check_args_spec_indexing([],_,_,[]).
1472 check_args_spec_indexing([Arg|Args],I,OtherVariables,ArgSpecs) :-
1473 term_variables(Args,Variables,OtherVariables),
1474 ( check_arg_spec_indexing(Arg,I,Variables,ArgSpec) ->
1475 ArgSpecs = [ArgSpec|RArgSpecs]
1477 ArgSpecs = RArgSpecs
1480 term_variables(Arg,NOtherVariables,OtherVariables),
1481 check_args_spec_indexing(Args,J,NOtherVariables,RArgSpecs).
1483 check_arg_spec_indexing(Arg,I,Variables,ArgSpec) :-
1485 memberchk_eq(Arg,Variables),
1486 ArgSpec = specinfo(I,any,[])
1489 ArgSpec = specinfo(I,F/A,[ArgSpecs]),
1491 check_args_spec_indexing(Args,1,Variables,ArgSpecs)
1494 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1496 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1499 add_occurrences([]).
1500 add_occurrences([Rule|Rules]) :-
1501 Rule = pragma(rule(H1,H2,_,_),ids(IDs1,IDs2),_,_,Nb),
1502 add_occurrences(H1,IDs1,simplification,Nb),
1503 add_occurrences(H2,IDs2,propagation,Nb),
1504 add_occurrences(Rules).
1506 add_occurrences([],[],_,_).
1507 add_occurrences([H|Hs],[ID|IDs],Type,RuleNb) :-
1510 new_occurrence(FA,RuleNb,ID,Type),
1511 add_occurrences(Hs,IDs,Type,RuleNb).
1513 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1515 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1516 % Observation Analysis
1526 :- chr_constraint observation_analysis/1.
1527 :- chr_option(mode, observation_analysis(+)).
1529 observation_analysis(Cs), rule(RuleNb,PragmaRule) # Id ==>
1530 PragmaRule = pragma(rule(_,_,Guard,Body),_,_,_,_),
1531 ( chr_pp_flag(store_in_guards, on) ->
1532 observation_analysis(RuleNb, Guard, guard, Cs)
1536 observation_analysis(RuleNb, Body, body, Cs)
1539 observation_analysis(_) <=> true.
1541 observation_analysis(RuleNb, Term, GB, Cs) :-
1542 ( all_spawned(RuleNb,GB) ->
1545 spawns_all(RuleNb,GB)
1553 observation_analysis(RuleNb,T1,GB,Cs),
1554 observation_analysis(RuleNb,T2,GB,Cs)
1556 observation_analysis(RuleNb,T1,GB,Cs),
1557 observation_analysis(RuleNb,T2,GB,Cs)
1558 ; Term = (T1->T2) ->
1559 observation_analysis(RuleNb,T1,GB,Cs),
1560 observation_analysis(RuleNb,T2,GB,Cs)
1562 observation_analysis(RuleNb,T,GB,Cs)
1563 ; functor(Term,F,A), member(F/A,Cs) ->
1564 spawns(RuleNb,GB,F/A)
1566 spawns_all_triggers(RuleNb,GB)
1567 ; Term = (_ is _) ->
1568 spawns_all_triggers(RuleNb,GB)
1569 ; builtin_binds_b(Term,Vars) ->
1573 spawns_all_triggers(RuleNb,GB)
1576 spawns_all(RuleNb,GB)
1579 :- chr_constraint spawns/3.
1580 :- chr_option(mode, spawns(+,+,+)).
1581 :- chr_type spawns_type ---> guard ; body.
1582 :- chr_option(type_declaration,spawns(any,spawns_type,any)).
1584 :- chr_constraint spawns_all/2, spawns_all_triggers/2.
1585 :- chr_option(mode, spawns_all(+,+)).
1586 :- chr_option(type_declaration,spawns_all(any,spawns_type)).
1587 :- chr_option(mode, spawns_all_triggers(+,+)).
1588 :- chr_option(type_declaration,spawns_all_triggers(any,spawns_type)).
1590 spawns_all(RuleNb,GB) \ spawns_all(RuleNb,GB) <=> true.
1591 spawns_all(RuleNb,guard) \ spawns_all(RuleNb,body) <=> true.
1592 spawns_all_triggers(RuleNb,GB) \ spawns_all_triggers(RuleNb,GB) <=> true.
1593 spawns_all_triggers(RuleNb,guard) \ spawns_all_triggers(RuleNb,body) <=> true.
1594 spawns(RuleNb,GB,C) \ spawns(RuleNb,GB,C) <=> true.
1595 spawns(RuleNb,guard,C) \ spawns(RuleNb,body,C) <=> true.
1597 spawns_all(RuleNb,GB) \ spawns(RuleNb,GB,_) <=> true.
1598 spawns_all(RuleNb,guard) \ spawns(RuleNb,body,_) <=> true.
1599 spawns_all(RuleNb,GB) \ spawns_all_triggers(RuleNb,GB) <=> true.
1600 spawns_all(RuleNb,guard) \ spawns_all_triggers(RuleNb,body) <=> true.
1602 spawns_all_triggers(RuleNb,GB) \ spawns(RuleNb,GB,C) <=> may_trigger(C) | true.
1603 spawns_all_triggers(RuleNb,guard) \ spawns(RuleNb,body,C) <=> may_trigger(C) | true.
1605 spawns_all(RuleNb2,_), occurrence(C1,_,RuleNb2,O,_)#Id
1607 spawns(RuleNb1,GB,C1)
1609 \+ is_passive(RuleNb2,O)
1611 spawns_all(RuleNb1,GB)
1615 occurrence(C1,_,RuleNb2,O,_)#Id, spawns_all(RuleNb2,_)
1617 \+(\+ spawns_all_triggers_implies_spawns_all), % in the hope it schedules this guard early...
1618 \+ is_passive(RuleNb2,O), may_trigger(C1)
1620 spawns_all_triggers_implies_spawns_all
1624 :- chr_constraint spawns_all_triggers_implies_spawns_all/0.
1625 spawns_all_triggers_implies_spawns_all, spawns_all_triggers_implies_spawns_all <=> fail.
1626 spawns_all_triggers_implies_spawns_all \
1627 spawns_all_triggers(RuleNb,GB) <=> spawns_all(RuleNb,GB).
1629 spawns_all_triggers(RuleNb2,_), occurrence(C1,_,RuleNb2,O,_)#Id
1631 spawns(RuleNb1,GB,C1)
1634 \+ is_passive(RuleNb2,O)
1636 spawns_all_triggers(RuleNb1,GB)
1640 spawns_all_triggers(RuleNb2,_), occurrence(C1,_,RuleNb2,O,_)#Id,
1641 spawns(RuleNb1,GB,C1)
1644 \+ is_passive(RuleNb2,O)
1646 spawns_all_triggers(RuleNb1,GB)
1650 % a bit dangerous this rule: could start propagating too much too soon?
1651 spawns(RuleNb2,_,C2), occurrence(C1,_,RuleNb2,O,_)#Id,
1652 spawns(RuleNb1,GB,C1)
1654 RuleNb1 \== RuleNb2, C1 \== C2,
1655 \+ is_passive(RuleNb2,O)
1657 spawns(RuleNb1,GB,C2)
1661 spawns(RuleNb2,_,C2), occurrence(C1,_,RuleNb2,O,_)#Id,
1662 spawns_all_triggers(RuleNb1,GB)
1664 \+ is_passive(RuleNb2,O), may_trigger(C1), \+ may_trigger(C2)
1666 spawns(RuleNb1,GB,C2)
1671 :- chr_constraint all_spawned/2.
1672 :- chr_option(mode, all_spawned(+,+)).
1673 spawns_all(RuleNb,guard) \ all_spawned(RuleNb,_) <=> true.
1674 spawns_all(RuleNb,GB) \ all_spawned(RuleNb,GB) <=> true.
1675 all_spawned(RuleNb,GB) <=> fail.
1678 % Overview of the supported queries:
1679 % is_observed(+functor/artiy, +occurrence_number, +(guard;body))
1680 % only succeeds if the occurrence is observed by the
1681 % guard resp. body (depending on the last argument) of its rule
1682 % is_observed(+functor/artiy, +occurrence_number, -)
1683 % succeeds if the occurrence is observed by either the guard or
1684 % the body of its rule
1685 % NOTE: the last argument is NOT bound by this query
1687 % do_is_observed(+functor/artiy,+rule_number,+(guard;body))
1688 % succeeds if the given constraint is observed by the given
1690 % do_is_observed(+functor/artiy,+rule_number)
1691 % succeeds if the given constraint is observed by the given
1692 % rule (either its guard or its body)
1697 ai_is_observed(C,O).
1699 is_stored_in_guard(C,RuleNb) :-
1700 chr_pp_flag(store_in_guards, on),
1701 do_is_observed(C,RuleNb,guard).
1703 :- chr_constraint is_observed/3.
1704 :- chr_option(mode, is_observed(+,+,+)).
1705 occurrence(C,O,RuleNb,_,_) \ is_observed(C,O,GB) <=> do_is_observed(C,RuleNb,GB).
1706 is_observed(_,_,_) <=> fail. % this will not happen in practice
1709 :- chr_constraint do_is_observed/3.
1710 :- chr_option(mode, do_is_observed(+,+,+)).
1711 :- chr_constraint do_is_observed/2.
1712 :- chr_option(mode, do_is_observed(+,+)).
1714 do_is_observed(C,RuleNb,GB) <=> var(GB) | do_is_observed(C,RuleNb).
1717 % a constraint C is observed if the GB of the rule it occurs in spawns all,
1718 % and some non-passive occurrence of some (possibly other) constraint
1719 % exists in a rule (could be same rule) with at least one occurrence of C
1721 spawns_all(RuleNb,GB),
1722 occurrence(_,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1724 do_is_observed(C,RuleNb,GB)
1726 \+ is_passive(RuleNb2,O)
1730 spawns_all(RuleNb,_),
1731 occurrence(_,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1733 do_is_observed(C,RuleNb)
1735 \+ is_passive(RuleNb2,O)
1740 % a constraint C is observed if the GB of the rule it occurs in spawns a
1741 % constraint C2 that occurs non-passively in a rule (possibly the same rule)
1742 % as an occurrence of C
1744 spawns(RuleNb,GB,C2),
1745 occurrence(C2,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1747 do_is_observed(C,RuleNb,GB)
1749 \+ is_passive(RuleNb2,O)
1753 spawns(RuleNb,_,C2),
1754 occurrence(C2,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1756 do_is_observed(C,RuleNb)
1758 \+ is_passive(RuleNb2,O)
1762 % (3) spawns_all_triggers
1763 % a constraint C is observed if the GB of the rule it occurs in spawns all triggers
1764 % and some non-passive occurrence of some (possibly other) constraint that may trigger
1765 % exists in a rule (could be same rule) with at least one occurrence of C
1767 spawns_all_triggers(RuleNb,GB),
1768 occurrence(C2,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1770 do_is_observed(C,RuleNb,GB)
1772 \+ is_passive(RuleNb2,O), may_trigger(C2)
1776 spawns_all_triggers(RuleNb,_),
1777 occurrence(C2,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1779 do_is_observed(C,RuleNb)
1781 \+ is_passive(RuleNb2,O), may_trigger(C2)
1785 % (4) conservativeness
1786 do_is_observed(_,_,_) <=> chr_pp_flag(observation_analysis,off).
1787 do_is_observed(_,_) <=> chr_pp_flag(observation_analysis,off).
1790 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1792 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1795 %% Generated predicates
1796 %% attach_$CONSTRAINT
1798 %% detach_$CONSTRAINT
1801 %% attach_$CONSTRAINT
1802 generate_attach_detach_a_constraint_all([],[]).
1803 generate_attach_detach_a_constraint_all([Constraint|Constraints],Clauses) :-
1804 ( ( chr_pp_flag(debugable,on) ; is_stored(Constraint), \+ only_ground_indexed_arguments(Constraint), \+ get_store_type(Constraint,var_assoc_store(_,_)) ) ->
1805 generate_attach_a_constraint(Constraint,Clauses1),
1806 generate_detach_a_constraint(Constraint,Clauses2)
1811 generate_attach_detach_a_constraint_all(Constraints,Clauses3),
1812 append([Clauses1,Clauses2,Clauses3],Clauses).
1814 generate_attach_a_constraint(Constraint,[Clause1,Clause2]) :-
1815 generate_attach_a_constraint_nil(Constraint,Clause1),
1816 generate_attach_a_constraint_cons(Constraint,Clause2).
1818 attach_constraint_atom(FA,Vars,Susp,Atom) :-
1819 make_name('attach_',FA,Name),
1820 Atom =.. [Name,Vars,Susp].
1822 generate_attach_a_constraint_nil(FA,Clause) :-
1823 Clause = (Head :- true),
1824 attach_constraint_atom(FA,[],_,Head).
1826 generate_attach_a_constraint_cons(FA,Clause) :-
1827 Clause = (Head :- Body),
1828 attach_constraint_atom(FA,[Var|Vars],Susp,Head),
1829 attach_constraint_atom(FA,Vars,Susp,RecursiveCall),
1830 Body = ( AttachBody, Subscribe, RecursiveCall ),
1831 get_max_constraint_index(N),
1833 generate_attach_body_1(FA,Var,Susp,AttachBody)
1835 generate_attach_body_n(FA,Var,Susp,AttachBody)
1837 % SWI-Prolog specific code
1838 chr_pp_flag(solver_events,NMod),
1840 Args = [[Var|_],Susp],
1841 get_target_module(Mod),
1842 use_auxiliary_predicate(run_suspensions),
1843 Subscribe = clp_events:subscribe(Var,NMod,Mod,Mod:'$run_suspensions'([Susp]))
1848 generate_attach_body_1(FA,Var,Susp,Body) :-
1849 get_target_module(Mod),
1851 ( get_attr(Var, Mod, Susps) ->
1852 put_attr(Var, Mod, [Susp|Susps])
1854 put_attr(Var, Mod, [Susp])
1857 generate_attach_body_n(F/A,Var,Susp,Body) :-
1858 get_constraint_index(F/A,Position),
1859 get_max_constraint_index(Total),
1860 get_target_module(Mod),
1861 add_attr(Total,Susp,Position,TAttr,AddGoal,NTAttr),
1862 singleton_attr(Total,Susp,Position,NewAttr3),
1864 ( get_attr(Var,Mod,TAttr) ->
1866 put_attr(Var,Mod,NTAttr)
1868 put_attr(Var,Mod,NewAttr3)
1871 %% detach_$CONSTRAINT
1872 generate_detach_a_constraint(Constraint,[Clause1,Clause2]) :-
1873 generate_detach_a_constraint_nil(Constraint,Clause1),
1874 generate_detach_a_constraint_cons(Constraint,Clause2).
1876 detach_constraint_atom(FA,Vars,Susp,Atom) :-
1877 make_name('detach_',FA,Name),
1878 Atom =.. [Name,Vars,Susp].
1880 generate_detach_a_constraint_nil(FA,Clause) :-
1881 Clause = ( Head :- true),
1882 detach_constraint_atom(FA,[],_,Head).
1884 generate_detach_a_constraint_cons(FA,Clause) :-
1885 Clause = (Head :- Body),
1886 detach_constraint_atom(FA,[Var|Vars],Susp,Head),
1887 detach_constraint_atom(FA,Vars,Susp,RecursiveCall),
1888 Body = ( DetachBody, RecursiveCall ),
1889 get_max_constraint_index(N),
1891 generate_detach_body_1(FA,Var,Susp,DetachBody)
1893 generate_detach_body_n(FA,Var,Susp,DetachBody)
1896 generate_detach_body_1(FA,Var,Susp,Body) :-
1897 get_target_module(Mod),
1899 ( get_attr(Var,Mod,Susps) ->
1900 'chr sbag_del_element'(Susps,Susp,NewSusps),
1904 put_attr(Var,Mod,NewSusps)
1910 generate_detach_body_n(F/A,Var,Susp,Body) :-
1911 get_constraint_index(F/A,Position),
1912 get_max_constraint_index(Total),
1913 rem_attr(Total,Var,Susp,Position,TAttr,RemGoal),
1914 get_target_module(Mod),
1916 ( get_attr(Var,Mod,TAttr) ->
1922 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1923 %-------------------------------------------------------------------------------
1924 %% generate_indexed_variables_body(+ConstraintSymbol,+ArgList,-Body,-VarList) is det.
1925 :- chr_constraint generate_indexed_variables_body/4.
1926 :- chr_option(mode,generate_indexed_variables_body(+,?,+,?)).
1927 :- chr_option(type_declaration,generate_indexed_variables_body(constraint,any,any,any)).
1928 %-------------------------------------------------------------------------------
1929 constraint_mode(F/A,ArgModes) \ generate_indexed_variables_body(F/A,Args,Body,Vars) <=>
1930 get_indexing_spec(F/A,Specs),
1931 ( chr_pp_flag(term_indexing,on) ->
1932 spectermvars(Specs,Args,F,A,Body,Vars)
1934 get_constraint_type_det(F/A,ArgTypes),
1935 create_indexed_variables_body(Args,ArgModes,ArgTypes,Vars,1,F/A,MaybeBody,N),
1936 ( MaybeBody == empty ->
1943 Term =.. [term|Args]
1945 Body = term_variables(Term,Vars)
1950 generate_indexed_variables_body(FA,_,_,_) <=>
1951 chr_error(internal,'generate_indexed_variables_body: missing mode info for ~w.\n',[FA]).
1952 %===============================================================================
1954 create_indexed_variables_body([],[],[],_,_,_,empty,0).
1955 create_indexed_variables_body([V|Vs],[Mode|Modes],[Type|Types],Vars,I,FA,Body,N) :-
1957 create_indexed_variables_body(Vs,Modes,Types,Tail,J,FA,RBody,M),
1959 is_indexed_argument(FA,I) ->
1960 ( atomic_type(Type) ->
1971 Continuation = true, Tail = []
1973 Continuation = RBody
1977 Body = term_variables(V,Vars)
1979 Body = (term_variables(V,Vars,Tail),RBody)
1983 ; Mode == (-), is_indexed_argument(FA,I) ->
1987 Body = (Vars = [V|Tail],RBody)
1995 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1997 spectermvars(Specs,Args,F,A,Goal,Vars) :-
1998 spectermvars(Args,1,Specs,F,A,Vars,[],Goal).
2000 spectermvars([],B,_,_,A,L,L,true) :- B > A, !.
2001 spectermvars([Arg|Args],I,Specs,F,A,L,T,Goal) :-
2002 Goal = (ArgGoal,RGoal),
2003 argspecs(Specs,I,TempArgSpecs,RSpecs),
2004 merge_argspecs(TempArgSpecs,ArgSpecs),
2005 arggoal(ArgSpecs,Arg,ArgGoal,L,L1),
2007 spectermvars(Args,J,RSpecs,F,A,L1,T,RGoal).
2009 argspecs([],_,[],[]).
2010 argspecs([[]|Rest],I,ArgSpecs,RestSpecs) :-
2011 argspecs(Rest,I,ArgSpecs,RestSpecs).
2012 argspecs([[specinfo(J,Spec,Args)|Specs]|Rest],I,ArgSpecs,RestSpecs) :-
2014 ArgSpecs = [specinfo(J,Spec,Args)|RArgSpecs],
2016 RRestSpecs = RestSpecs
2018 RestSpecs = [Specs|RRestSpecs]
2021 ArgSpecs = RArgSpecs,
2022 RestSpecs = [[specinfo(J,Spec,Args)|Specs]|RRestSpecs]
2024 argspecs(Rest,I,RArgSpecs,RRestSpecs).
2026 merge_argspecs(In,Out) :-
2028 merge_argspecs_(Sorted,Out).
2030 merge_argspecs_([],[]).
2031 merge_argspecs_([X],R) :- !, R = [X].
2032 merge_argspecs_([specinfo(I,F1,A1),specinfo(I,F2,A2)|Rest],R) :-
2033 ( (F1 == any ; F2 == any) ->
2034 merge_argspecs_([specinfo(I,any,[])|Rest],R)
2037 merge_argspecs_([specinfo(I,F1,A)|Rest],R)
2039 R = [specinfo(I,F1,A1)|RR],
2040 merge_argspecs_([specinfo(I,F2,A2)|Rest],RR)
2043 arggoal(List,Arg,Goal,L,T) :-
2047 ; List = [specinfo(_,any,_)] ->
2048 Goal = term_variables(Arg,L,T)
2056 arggoal_cases(List,Arg,L,T,Cases)
2059 arggoal_cases([],_,L,T,L=T).
2060 arggoal_cases([specinfo(_,FA,ArgSpecs)|Rest],Arg,L,T,Cases) :-
2063 ; ArgSpecs == [[]] ->
2066 Cases = (Case ; RCases),
2069 Case = (Arg = Term -> ArgsGoal),
2070 spectermvars(Args,1,ArgSpecs,F,A,L,T,ArgsGoal)
2072 arggoal_cases(Rest,Arg,L,T,RCases).
2073 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2075 generate_extra_clauses(Constraints,List) :-
2076 generate_activate_clauses(Constraints,List,Tail0),
2077 generate_remove_clauses(Constraints,Tail0,Tail1),
2078 generate_allocate_clauses(Constraints,Tail1,Tail2),
2079 generate_insert_constraint_internal_clauses(Constraints,Tail2,Tail3),
2080 generate_novel_production(Tail3,Tail4),
2081 generate_extend_history(Tail4,Tail5),
2082 generate_run_suspensions_clauses(Constraints,Tail5,Tail6),
2083 generate_empty_named_history_initialisations(Tail6,Tail7),
2086 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2087 % remove_constraint_internal/[1/3]
2089 generate_remove_clauses([],List,List).
2090 generate_remove_clauses([C|Cs],List,Tail) :-
2091 generate_remove_clause(C,List,List1),
2092 generate_remove_clauses(Cs,List1,Tail).
2094 remove_constraint_goal(Constraint,Susp,Agenda,DeleteNo,DeleteYes,Role,Goal) :-
2095 uses_state(Constraint,removed),
2096 ( chr_pp_flag(inline_insertremove,off) ->
2097 use_auxiliary_predicate(remove_constraint_internal,Constraint),
2098 Goal = ( DeleteGoal, ( Delete == yes -> DeleteYes ; DeleteNo) ),
2099 remove_constraint_atom(Constraint,Susp,Agenda,Delete,DeleteGoal)
2101 delay_phase_end(validate_store_type_assumptions,
2102 generate_remove_body(Constraint,Susp,Agenda,DeleteNo,DeleteYes,Role,Goal)
2106 remove_constraint_atom(Constraint,Susp,Agenda,Delete,Goal) :-
2107 make_name('$remove_constraint_internal_',Constraint,Name),
2108 ( chr_pp_flag(debugable,off), ( only_ground_indexed_arguments(Constraint) ; get_store_type(Constraint,var_assoc_store(_,_)) ) ->
2109 Goal =.. [Name, Susp,Delete]
2111 Goal =.. [Name,Susp,Agenda,Delete]
2114 generate_remove_clause(Constraint,List,Tail) :-
2115 ( is_used_auxiliary_predicate(remove_constraint_internal,Constraint) ->
2116 List = [RemoveClause|Tail],
2117 RemoveClause = (Head :- RemoveBody),
2118 remove_constraint_atom(Constraint,Susp,Agenda,Delete,Head),
2119 generate_remove_body(Constraint,Susp,Agenda,Delete = no,Delete = yes,active,RemoveBody)
2124 generate_remove_body(Constraint,Susp,Agenda,DeleteNo,DeleteYes,Role,RemoveBody) :-
2125 ( chr_pp_flag(debugable,off), ( only_ground_indexed_arguments(Constraint) ; get_store_type(Constraint,var_assoc_store(_,_))) ->
2127 get_update_suspension_field(Constraint,Susp,state,State,removed,GetState,GetStateValue0,UpdateState),
2128 if_used_state(Constraint,not_stored_yet,GetStateValue0,true,GetStateValue),
2129 if_used_state(Constraint,not_stored_yet,(State == not_stored_yet -> DeleteNo ; DeleteYes),DeleteYes,MaybeDelete)
2130 ; Role == partner ->
2131 get_update_suspension_field(Constraint,Susp,state,State,removed,GetState,_,UpdateState),
2132 GetStateValue = true,
2133 MaybeDelete = DeleteYes
2143 static_suspension_term(Constraint,Susp2),
2144 get_static_suspension_term_field(arguments,Constraint,Susp2,Args),
2145 generate_indexed_variables_body(Constraint,Args,IndexedVariablesBody,Agenda),
2146 ( chr_pp_flag(debugable,on) ->
2147 Constraint = Functor / _,
2148 get_static_suspension_term_field(functor,Constraint,Susp2,Functor)
2153 get_update_static_suspension_field(Constraint,Susp,Susp2,state,State,removed,GetStateValue0,UpdateState),
2154 if_used_state(Constraint,not_stored_yet,GetStateValue0,true,GetStateValue),
2155 if_used_state(Constraint,not_stored_yet,(State == not_stored_yet -> Agenda = [], DeleteNo ; IndexedVariablesBody, DeleteYes),(IndexedVariablesBody,DeleteYes),MaybeDelete)
2156 ; Role == partner ->
2157 get_update_static_suspension_field(Constraint,Susp,Susp2,state,State,removed,_,UpdateState),
2158 GetStateValue = true,
2159 MaybeDelete = (IndexedVariablesBody, DeleteYes)
2170 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2171 % activate_constraint/4
2173 generate_activate_clauses([],List,List).
2174 generate_activate_clauses([C|Cs],List,Tail) :-
2175 generate_activate_clause(C,List,List1),
2176 generate_activate_clauses(Cs,List1,Tail).
2178 activate_constraint_goal(Constraint,StoreAction,Vars,Susp,Generation,Goal) :-
2179 ( chr_pp_flag(inline_insertremove,off) ->
2180 use_auxiliary_predicate(activate_constraint,Constraint),
2181 Goal = ( ActivateGoal , (Store == yes -> StoreAction ; true) ),
2182 activate_constraint_atom(Constraint,Store,Vars,Susp,Generation,ActivateGoal)
2184 delay_phase_end(validate_store_type_assumptions,
2185 activate_constraint_body(Constraint,StoreAction,true,Vars,Susp,Generation,Goal)
2189 activate_constraint_atom(Constraint,Store,Vars,Susp,Generation,Goal) :-
2190 make_name('$activate_constraint_',Constraint,Name),
2191 ( chr_pp_flag(debugable,off), only_ground_indexed_arguments(Constraint) ->
2192 Goal =.. [Name,Store, Susp]
2193 ; chr_pp_flag(debugable,off), may_trigger(Constraint), get_store_type(Constraint,var_assoc_store(_,_)) ->
2194 Goal =.. [Name,Store, Susp, Generation]
2195 ; chr_pp_flag(debugable,off), may_trigger(Constraint), get_store_type(Constraint,var_assoc_store(_,_)) ->
2196 Goal =.. [Name,Store, Vars, Susp, Generation]
2198 Goal =.. [Name,Store, Vars, Susp]
2201 generate_activate_clause(Constraint,List,Tail) :-
2202 ( is_used_auxiliary_predicate(activate_constraint,Constraint) ->
2203 List = [Clause|Tail],
2204 Clause = (Head :- Body),
2205 activate_constraint_atom(Constraint,Store,Vars,Susp,Generation,Head),
2206 activate_constraint_body(Constraint,Store = yes, Store = no,Vars,Susp,Generation,Body)
2211 activate_constraint_body(Constraint,StoreYes,StoreNo,Vars,Susp,Generation,Body) :-
2212 ( chr_pp_flag(debugable,off), may_trigger(Constraint), uses_field(Constraint,generation) ->
2213 get_update_suspension_field(Constraint,Susp,generation,Gen,Generation,GetGeneration,GetGenerationValue,UpdateGeneration),
2214 GenerationHandling = (GetGeneration, GetGenerationValue, Generation is Gen+1, UpdateGeneration)
2216 GenerationHandling = true
2218 get_update_suspension_field(Constraint,Susp,state,State,active,GetState,GetStateValue0,UpdateState),
2219 if_used_state(Constraint,not_stored_yet,GetStateValue0,true,GetStateValue),
2220 ( chr_pp_flag(debugable,off), ( only_ground_indexed_arguments(Constraint) ; get_store_type(Constraint,var_assoc_store(_,_))) ->
2221 if_used_state(Constraint,not_stored_yet,( State == not_stored_yet -> StoreYes ; StoreNo ),StoreNo,StoreVarsGoal)
2223 get_dynamic_suspension_term_field(arguments,Constraint,Susp,Arguments,ArgumentsGoal),
2224 generate_indexed_variables_body(Constraint,Arguments,IndexedVariablesBody,Vars),
2225 ( chr_pp_flag(guard_locks,off) ->
2228 NoneLocked = 'chr none_locked'( Vars)
2230 if_used_state(Constraint,not_stored_yet,
2231 ( State == not_stored_yet ->
2233 IndexedVariablesBody,
2240 % (Vars = [],StoreNo),StoreVarsGoal)
2241 StoreNo,StoreVarsGoal)
2251 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2252 % allocate_constraint/4
2254 generate_allocate_clauses([],List,List).
2255 generate_allocate_clauses([C|Cs],List,Tail) :-
2256 generate_allocate_clause(C,List,List1),
2257 generate_allocate_clauses(Cs,List1,Tail).
2259 allocate_constraint_goal(Constraint,Susp,Args,Goal) :-
2260 uses_state(Constraint,not_stored_yet),
2261 ( chr_pp_flag(inline_insertremove,off) ->
2262 use_auxiliary_predicate(allocate_constraint,Constraint),
2263 allocate_constraint_atom(Constraint,Susp,Args,Goal)
2265 Goal = (Susp = Suspension, Goal0),
2266 delay_phase_end(validate_store_type_assumptions,
2267 allocate_constraint_body(Constraint,Suspension,Args,Goal0)
2271 allocate_constraint_atom(Constraint, Susp, Args,Goal) :-
2272 make_name('$allocate_constraint_',Constraint,Name),
2273 Goal =.. [Name,Susp|Args].
2275 generate_allocate_clause(Constraint,List,Tail) :-
2276 ( is_used_auxiliary_predicate(allocate_constraint,Constraint) ->
2277 List = [Clause|Tail],
2278 Clause = (Head :- Body),
2281 allocate_constraint_atom(Constraint,Susp,Args,Head),
2282 allocate_constraint_body(Constraint,Susp,Args,Body)
2287 allocate_constraint_body(Constraint,Susp,Args,Body) :-
2288 static_suspension_term(Constraint,Suspension),
2289 get_static_suspension_term_field(arguments,Constraint,Suspension,Args),
2290 ( chr_pp_flag(debugable,on) ->
2291 Constraint = Functor / _,
2292 get_static_suspension_term_field(functor,Constraint,Suspension,Functor)
2296 ( chr_pp_flag(debugable,on) ->
2297 ( may_trigger(Constraint) ->
2298 append(Args,[Susp],VarsSusp),
2299 build_head(F,A,[0],VarsSusp, ContinuationGoal),
2300 get_target_module(Mod),
2301 Continuation = Mod : ContinuationGoal
2305 Init = (Susp = Suspension),
2306 create_static_suspension_field(Constraint,Suspension,continuation,Continuation,CreateContinuation),
2307 create_static_suspension_field(Constraint,Suspension,generation,0,CreateGeneration)
2308 ; may_trigger(Constraint), uses_field(Constraint,generation) ->
2309 create_static_suspension_field(Constraint,Suspension,generation,0,CreateGeneration),
2310 Susp = Suspension, Init = true, CreateContinuation = true
2312 CreateGeneration = true, Susp = Suspension, Init = true, CreateContinuation = true
2314 ( uses_history(Constraint) ->
2315 create_static_suspension_field(Constraint,Suspension,history,t,CreateHistory)
2317 CreateHistory = true
2319 create_static_suspension_field(Constraint,Suspension,state,not_stored_yet,CreateState),
2320 ( has_suspension_field(Constraint,id) ->
2321 get_static_suspension_term_field(id,Constraint,Suspension,Id),
2336 gen_id(Id,'chr gen_id'(Id)).
2337 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2338 % insert_constraint_internal
2340 generate_insert_constraint_internal_clauses([],List,List).
2341 generate_insert_constraint_internal_clauses([C|Cs],List,Tail) :-
2342 generate_insert_constraint_internal_clause(C,List,List1),
2343 generate_insert_constraint_internal_clauses(Cs,List1,Tail).
2345 insert_constraint_internal_constraint_goal(Constraint, Vars, Suspension, Continuation, Args,Goal) :-
2346 ( chr_pp_flag(inline_insertremove,off) ->
2347 use_auxiliary_predicate(remove_constraint_internal,Constraint),
2348 insert_constraint_internal_constraint_atom(Constraint,Vars,Suspension,Continuation,Args,Goal)
2350 delay_phase_end(validate_store_type_assumptions,
2351 generate_insert_constraint_internal_body(Constraint,Suspension,Continuation,Args,Vars,Goal)
2356 insert_constraint_internal_constraint_atom(Constraint,Vars,Self,Closure,Args,Goal) :-
2357 insert_constraint_internal_constraint_name(Constraint,Name),
2358 ( chr_pp_flag(debugable,on) ->
2359 Goal =.. [Name, Vars, Self, Closure | Args]
2360 ; ( only_ground_indexed_arguments(Constraint) ; get_store_type(Constraint,var_assoc_store(_,_)))->
2361 Goal =.. [Name,Self | Args]
2363 Goal =.. [Name,Vars, Self | Args]
2366 insert_constraint_internal_constraint_name(Constraint,Name) :-
2367 make_name('$insert_constraint_internal_',Constraint,Name).
2369 generate_insert_constraint_internal_clause(Constraint,List,Tail) :-
2370 ( is_used_auxiliary_predicate(insert_constraint_internal,Constraint) ->
2371 List = [Clause|Tail],
2372 Clause = (Head :- Body),
2375 insert_constraint_internal_constraint_atom(Constraint, Vars, Suspension, Continuation,Args,Head),
2376 generate_insert_constraint_internal_body(Constraint,Suspension,Continuation,Args,Vars,Body)
2382 generate_insert_constraint_internal_body(Constraint,Susp,Continuation,Args,Vars,Body) :-
2383 static_suspension_term(Constraint,Suspension),
2384 create_static_suspension_field(Constraint,Suspension,state,active,CreateState),
2385 ( chr_pp_flag(debugable,on) ->
2386 get_static_suspension_term_field(continuation,Constraint,Suspension,Continuation),
2387 create_static_suspension_field(Constraint,Suspension,generation,0,CreateGeneration)
2388 ; may_trigger(Constraint), uses_field(Constraint,generation) ->
2389 create_static_suspension_field(Constraint,Suspension,generation,0,CreateGeneration)
2391 CreateGeneration = true
2393 ( chr_pp_flag(debugable,on) ->
2394 Constraint = Functor / _,
2395 get_static_suspension_term_field(functor,Constraint,Suspension,Functor)
2399 ( uses_history(Constraint) ->
2400 create_static_suspension_field(Constraint,Suspension,history,t,CreateHistory)
2402 CreateHistory = true
2404 get_static_suspension_term_field(arguments,Constraint,Suspension,Args),
2405 List = [Clause|Tail],
2406 ( chr_pp_flag(debugable,off), ( only_ground_indexed_arguments(Constraint) ; get_store_type(Constraint,var_assoc_store(_,_)))->
2407 suspension_term_base_fields(Constraint,BaseFields),
2408 ( has_suspension_field(Constraint,id) ->
2409 get_static_suspension_term_field(id,Constraint,Suspension,Id),
2423 ( has_suspension_field(Constraint,id) ->
2424 get_static_suspension_term_field(id,Constraint,Suspension,Id),
2429 generate_indexed_variables_body(Constraint,Args,IndexedVariablesBody,Vars),
2430 ( chr_pp_flag(guard_locks,off) ->
2433 NoneLocked = 'chr none_locked'( Vars)
2438 IndexedVariablesBody,
2447 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2448 % novel_production/2
2450 generate_novel_production(List,Tail) :-
2451 ( is_used_auxiliary_predicate(novel_production) ->
2452 List = [Clause|Tail],
2455 '$novel_production'( Self, Tuple) :-
2456 % arg( 3, Self, Ref), % ARGXXX
2457 % 'chr get_mutable'( History, Ref),
2458 arg( 3, Self, History), % ARGXXX
2459 ( hprolog:get_ds( Tuple, History, _) ->
2469 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2472 generate_extend_history(List,Tail) :-
2473 ( is_used_auxiliary_predicate(extend_history) ->
2474 List = [Clause|Tail],
2477 '$extend_history'( Self, Tuple) :-
2478 % arg( 3, Self, Ref), % ARGXXX
2479 % 'chr get_mutable'( History, Ref),
2480 arg( 3, Self, History), % ARGXXX
2481 hprolog:put_ds( Tuple, History, x, NewHistory),
2482 setarg( 3, Self, NewHistory) % ARGXXX
2488 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2491 empty_named_history_initialisations/2,
2492 generate_empty_named_history_initialisation/1,
2493 find_empty_named_histories/0.
2495 generate_empty_named_history_initialisations(List, Tail) :-
2496 empty_named_history_initialisations(List, Tail),
2497 find_empty_named_histories.
2499 find_empty_named_histories, history(_, Name, []) ==>
2500 generate_empty_named_history_initialisation(Name).
2502 generate_empty_named_history_initialisation(Name) \
2503 generate_empty_named_history_initialisation(Name) <=> true.
2504 generate_empty_named_history_initialisation(Name) \
2505 empty_named_history_initialisations(List, Tail) # Passive
2507 empty_named_history_global_variable(Name, GlobalVariable),
2508 List = [(:- nb_setval(GlobalVariable, 0))|Rest],
2509 empty_named_history_initialisations(Rest, Tail)
2510 pragma passive(Passive).
2512 find_empty_named_histories \
2513 generate_empty_named_history_initialisation(_) # Passive <=> true
2514 pragma passive(Passive).
2516 find_empty_named_histories,
2517 empty_named_history_initialisations(List, Tail) # Passive <=> List = Tail
2518 pragma passive(Passive).
2520 find_empty_named_histories <=>
2521 chr_error(internal, 'find_empty_named_histories was not removed', []).
2524 empty_named_history_global_variable(Name, GlobalVariable) :-
2525 atom_concat('chr empty named history ', Name, GlobalVariable).
2527 empty_named_history_novel_production(Name, nb_getval(GlobalVariable, 0)) :-
2528 empty_named_history_global_variable(Name, GlobalVariable).
2530 empty_named_history_extend_history(Name, b_setval(GlobalVariable, 1)) :-
2531 empty_named_history_global_variable(Name, GlobalVariable).
2534 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2537 generate_run_suspensions_clauses([],List,List).
2538 generate_run_suspensions_clauses([C|Cs],List,Tail) :-
2539 generate_run_suspensions_clause(C,List,List1),
2540 generate_run_suspensions_clauses(Cs,List1,Tail).
2542 run_suspensions_goal(Constraint,Suspensions,Goal) :-
2543 make_name('$run_suspensions_',Constraint,Name),
2544 Goal =.. [Name,Suspensions].
2546 generate_run_suspensions_clause(Constraint,List,Tail) :-
2547 ( is_used_auxiliary_predicate(run_suspensions,Constraint) ->
2548 List = [Clause1,Clause2|Tail],
2549 run_suspensions_goal(Constraint,[],Clause1),
2550 ( chr_pp_flag(debugable,on) ->
2551 run_suspensions_goal(Constraint,[Suspension|Suspensions],Clause2Head),
2552 get_update_suspension_field(Constraint,Suspension,state,State,triggered,GetState,GetStateValue,UpdateState),
2553 get_update_suspension_field(Constraint,Suspension,state,Post,active,GetPost,GetPostValue,UpdatePost),
2554 get_update_suspension_field(Constraint,Suspension,generation,Gen,Generation,GetGeneration,GetGenerationValue,UpdateGeneration),
2555 get_dynamic_suspension_term_field(continuation,Constraint,Suspension,Continuation,GetContinuation),
2556 run_suspensions_goal(Constraint,Suspensions,Clause2Recursion),
2566 Generation is Gen+1,
2570 'chr debug_event'(wake(Suspension)),
2573 'chr debug_event'(fail(Suspension)), !,
2577 'chr debug_event'(exit(Suspension))
2579 'chr debug_event'(redo(Suspension)),
2584 ( Post==triggered ->
2585 UpdatePost % catching constraints that did not do anything
2595 run_suspensions_goal(Constraint,[Suspension|Suspensions],Clause2Head),
2596 static_suspension_term(Constraint,SuspensionTerm),
2597 get_static_suspension_term_field(arguments,Constraint,SuspensionTerm,Arguments),
2598 append(Arguments,[Suspension],VarsSusp),
2599 make_suspension_continuation_goal(Constraint,VarsSusp,Continuation),
2600 run_suspensions_goal(Constraint,Suspensions,Clause2Recursion),
2601 ( uses_field(Constraint,generation) ->
2602 get_update_static_suspension_field(Constraint,Suspension,SuspensionTerm,generation,Gen,Generation,GetGeneration,UpdateGeneration),
2603 GenerationHandling = ( GetGeneration, Generation is Gen+1, UpdateGeneration)
2605 GenerationHandling = true
2607 get_update_static_suspension_field(Constraint,Suspension,SuspensionTerm,state,State,triggered,GetState,UpdateState),
2608 get_update_static_suspension_field(Constraint,Suspension,SuspensionTerm,state,Post,active,GetPostState,UpdatePostState),
2609 if_used_state(Constraint,removed,
2612 -> ReactivateConstraint
2614 ),ReactivateConstraint,CondReactivate),
2615 ReactivateConstraint =
2621 ( Post==triggered ->
2622 UpdatePostState % catching constraints that did not do anything
2630 Suspension = SuspensionTerm,
2639 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2641 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2642 generate_attach_increment(Clauses) :-
2643 get_max_constraint_index(N),
2644 ( is_used_auxiliary_predicate(attach_increment), N > 0 ->
2645 Clauses = [Clause1,Clause2],
2646 generate_attach_increment_empty(Clause1),
2648 generate_attach_increment_one(Clause2)
2650 generate_attach_increment_many(N,Clause2)
2656 generate_attach_increment_empty((attach_increment([],_) :- true)).
2658 generate_attach_increment_one(Clause) :-
2659 Head = attach_increment([Var|Vars],Susps),
2660 get_target_module(Mod),
2661 ( chr_pp_flag(guard_locks,off) ->
2664 NotLocked = 'chr not_locked'( Var)
2669 ( get_attr(Var,Mod,VarSusps) ->
2670 sort(VarSusps,SortedVarSusps),
2671 'chr merge_attributes'(Susps,SortedVarSusps,MergedSusps),
2672 put_attr(Var,Mod,MergedSusps)
2674 put_attr(Var,Mod,Susps)
2676 attach_increment(Vars,Susps)
2678 Clause = (Head :- Body).
2680 generate_attach_increment_many(N,Clause) :-
2681 Head = attach_increment([Var|Vars],TAttr1),
2682 % writeln(merge_attributes_1_before),
2683 merge_attributes(N,TAttr1,TAttr2,MergeGoal,Attr),
2684 % writeln(merge_attributes_1_after),
2685 get_target_module(Mod),
2686 ( chr_pp_flag(guard_locks,off) ->
2689 NotLocked = 'chr not_locked'( Var)
2694 ( get_attr(Var,Mod,TAttr2) ->
2696 put_attr(Var,Mod,Attr)
2698 put_attr(Var,Mod,TAttr1)
2700 attach_increment(Vars,TAttr1)
2702 Clause = (Head :- Body).
2705 generate_attr_unify_hook(Clauses) :-
2706 get_max_constraint_index(N),
2711 generate_attr_unify_hook_one(Clauses)
2713 generate_attr_unify_hook_many(N,Clauses)
2717 generate_attr_unify_hook_one([Clause]) :-
2718 Head = attr_unify_hook(Susps,Other),
2719 get_target_module(Mod),
2720 get_indexed_constraint(1,C),
2721 ( get_store_type(C,ST),
2722 ( ST = default ; ST = multi_store(STs), member(default,STs) ) ->
2723 make_run_suspensions(NewSusps,SortedSusps,WakeNewSusps),
2724 make_run_suspensions(SortedSusps,SortedSusps,WakeSusps),
2725 ( atomic_types_suspended_constraint(C) ->
2727 SortedSusps = Susps,
2729 SortedOtherSusps = OtherSusps,
2730 MergeGoal = (append(Susps,OtherSusps,List), sort(List,NewSusps)),
2733 SortGoal1 = sort(Susps, SortedSusps),
2734 SortGoal2 = sort(OtherSusps,SortedOtherSusps),
2735 MergeGoal = 'chr merge_attributes'(SortedSusps,SortedOtherSusps,NewSusps),
2736 use_auxiliary_predicate(attach_increment),
2738 ( compound(Other) ->
2739 term_variables(Other,OtherVars),
2740 attach_increment(OtherVars, SortedSusps)
2749 ( get_attr(Other,Mod,OtherSusps) ->
2752 put_attr(Other,Mod,NewSusps),
2755 put_attr(Other,Mod,SortedSusps),
2763 Clause = (Head :- Body)
2764 ; get_store_type(C,var_assoc_store(VarIndex,KeyIndex)) ->
2765 make_run_suspensions(List,List,WakeNewSusps),
2766 MergeGoal = (merge_into_assoc_store(Susps,OtherSusps,List)),
2768 ( get_attr(Other,Mod,OtherSusps) ->
2772 put_attr(Other,Mod,Susps)
2774 Clause = (Head :- Body)
2778 generate_attr_unify_hook_many(N,[Clause]) :-
2779 chr_pp_flag(dynattr,off), !,
2780 Head = attr_unify_hook(Attr,Other),
2781 get_target_module(Mod),
2782 make_attr(N,Mask,SuspsList,Attr),
2783 bagof(Sort,A ^ B ^ ( member(A,SuspsList) , Sort = sort(A,B) ) , SortGoalList),
2784 list2conj(SortGoalList,SortGoals),
2785 bagof(B, A ^ member(sort(A,B),SortGoalList), SortedSuspsList),
2786 merge_attributes2(N,Mask,SortedSuspsList,TOtherAttr,MergeGoal,MergedAttr),
2787 get_all_suspensions2(N,MergedAttr,MergedSuspsList),
2788 make_attr(N,Mask,SortedSuspsList,SortedAttr),
2789 make_run_suspensions_loop(MergedSuspsList,SortedSuspsList,WakeMergedSusps),
2790 make_run_suspensions_loop(SortedSuspsList,SortedSuspsList,WakeSortedSusps),
2791 ( forall((between(1,N,Index), get_indexed_constraint(Index,Constraint)),atomic_types_suspended_constraint(Constraint)) ->
2794 use_auxiliary_predicate(attach_increment),
2796 ( compound(Other) ->
2797 term_variables(Other,OtherVars),
2798 attach_increment(OtherVars,SortedAttr)
2807 ( get_attr(Other,Mod,TOtherAttr) ->
2809 put_attr(Other,Mod,MergedAttr),
2812 put_attr(Other,Mod,SortedAttr),
2820 Clause = (Head :- Body).
2823 generate_attr_unify_hook_many(N,Clauses) :-
2824 Head = attr_unify_hook(Attr,Other),
2825 get_target_module(Mod),
2826 normalize_attr(Attr,NormalGoal,NormalAttr),
2827 normalize_attr(OtherAttr,NormalOtherGoal,NormalOtherAttr),
2828 merge_attributes(N,NormalAttr,NormalOtherAttr,MergeGoal,MergedAttr),
2829 make_run_suspensions(N),
2830 ( forall((between(1,N,Index), get_indexed_constraint(Index,Constraint)),atomic_types_suspended_constraint(Constraint)) ->
2833 use_auxiliary_predicate(attach_increment),
2835 ( compound(Other) ->
2836 term_variables(Other,OtherVars),
2837 attach_increment(OtherVars,NormalAttr)
2846 ( get_attr(Other,Mod,OtherAttr) ->
2849 put_attr(Other,Mod,MergedAttr),
2850 '$dispatch_run_suspensions'(MergedAttr)
2852 put_attr(Other,Mod,NormalAttr),
2853 '$dispatch_run_suspensions'(NormalAttr)
2857 '$dispatch_run_suspensions'(NormalAttr)
2860 Clause = (Head :- Body),
2861 Clauses = [Clause,DispatchList1,DispatchList2|Dispatchers],
2862 DispatchList1 = ('$dispatch_run_suspensions'([])),
2863 DispatchList2 = ('$dispatch_run_suspensions'([Pos-List|Rest]) :- '$dispatch_run_suspensions'(Pos,List),'$dispatch_run_suspensions'(Rest)),
2864 run_suspensions_dispatchers(N,[],Dispatchers).
2867 run_suspensions_dispatchers(N,Acc,Dispatchers) :-
2869 get_indexed_constraint(N,C),
2870 NAcc = [('$dispatch_run_suspensions'(N,List) :- Body)|Acc],
2872 run_suspensions_goal(C,List,Body)
2877 run_suspensions_dispatchers(M,NAcc,Dispatchers)
2883 make_run_suspensions(N) :-
2885 ( get_indexed_constraint(N,C),
2887 use_auxiliary_predicate(run_suspensions,C)
2892 make_run_suspensions(M)
2897 make_run_suspensions(AllSusps,OneSusps,Goal) :-
2898 make_run_suspensions(1,AllSusps,OneSusps,Goal).
2900 make_run_suspensions(Index,AllSusps,OneSusps,Goal) :-
2901 ( get_indexed_constraint(Index,C), may_trigger(C) ->
2902 use_auxiliary_predicate(run_suspensions,C),
2903 ( wakes_partially(C) ->
2904 run_suspensions_goal(C,OneSusps,Goal)
2906 run_suspensions_goal(C,AllSusps,Goal)
2912 make_run_suspensions_loop(AllSuspsList,OneSuspsList,Goal) :-
2913 make_run_suspensions_loop(AllSuspsList,OneSuspsList,1,Goal).
2915 make_run_suspensions_loop([],[],_,true).
2916 make_run_suspensions_loop([AllSusps|AllSuspsList],[OneSusps|OneSuspsList],I,(Goal,Goals)) :-
2917 make_run_suspensions(I,AllSusps,OneSusps,Goal),
2919 make_run_suspensions_loop(AllSuspsList,OneSuspsList,J,Goals).
2921 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2922 % $insert_in_store_F/A
2923 % $delete_from_store_F/A
2925 generate_insert_delete_constraints([],[]).
2926 generate_insert_delete_constraints([FA|Rest],Clauses) :-
2928 generate_insert_delete_constraint(FA,Clauses,RestClauses)
2930 Clauses = RestClauses
2932 generate_insert_delete_constraints(Rest,RestClauses).
2934 generate_insert_delete_constraint(FA,Clauses,RestClauses) :-
2935 insert_constraint_clause(FA,Clauses,RestClauses1),
2936 delete_constraint_clause(FA,RestClauses1,RestClauses).
2938 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
2941 insert_constraint_goal(FA,Susp,Vars,Goal) :-
2942 ( chr_pp_flag(inline_insertremove,off) ->
2943 use_auxiliary_predicate(insert_in_store,FA),
2944 insert_constraint_atom(FA,Susp,Goal)
2946 delay_phase_end(validate_store_type_assumptions,
2947 ( insert_constraint_body(FA,Susp,UsedVars,Goal),
2948 insert_constraint_direct_used_vars(UsedVars,Vars)
2953 insert_constraint_direct_used_vars([],_).
2954 insert_constraint_direct_used_vars([Index-Var|Rest],Vars) :-
2955 nth1(Index,Vars,Var),
2956 insert_constraint_direct_used_vars(Rest,Vars).
2958 insert_constraint_atom(FA,Susp,Call) :-
2959 make_name('$insert_in_store_',FA,Functor),
2960 Call =.. [Functor,Susp].
2962 insert_constraint_clause(C,Clauses,RestClauses) :-
2963 ( is_used_auxiliary_predicate(insert_in_store,C) ->
2964 Clauses = [Clause|RestClauses],
2965 Clause = (Head :- InsertCounterInc,VarsBody,Body),
2966 insert_constraint_atom(C,Susp,Head),
2967 insert_constraint_body(C,Susp,UsedVars,Body),
2968 insert_constraint_used_vars(UsedVars,C,Susp,VarsBody),
2969 ( chr_pp_flag(store_counter,on) ->
2970 InsertCounterInc = '$insert_counter_inc'
2972 InsertCounterInc = true
2975 Clauses = RestClauses
2978 insert_constraint_used_vars([],_,_,true).
2979 insert_constraint_used_vars([Index-Var|Rest],C,Susp,(Goal,Goals)) :-
2980 get_dynamic_suspension_term_field(argument(Index),C,Susp,Var,Goal),
2981 insert_constraint_used_vars(Rest,C,Susp,Goals).
2983 insert_constraint_body(C,Susp,UsedVars,Body) :-
2984 get_store_type(C,StoreType),
2985 insert_constraint_body(StoreType,C,Susp,UsedVars,Body).
2987 insert_constraint_body(default,C,Susp,[],Body) :-
2988 global_list_store_name(C,StoreName),
2989 make_get_store_goal(StoreName,Store,GetStoreGoal),
2990 make_update_store_goal(StoreName,Cell,UpdateStoreGoal),
2991 ( chr_pp_flag(debugable,on) ->
2992 Cell = [Susp|Store],
2999 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,Cell,SetGoal),
3003 Cell = [Susp|Store],
3005 ( Store = [NextSusp|_] ->
3012 % get_target_module(Mod),
3013 % get_max_constraint_index(Total),
3015 % generate_attach_body_1(C,Store,Susp,AttachBody)
3017 % generate_attach_body_n(C,Store,Susp,AttachBody)
3021 % 'chr default_store'(Store),
3024 insert_constraint_body(multi_inthash(Indexes),C,Susp,[],Body) :-
3025 generate_multi_inthash_insert_constraint_bodies(Indexes,C,Susp,Body).
3026 insert_constraint_body(multi_hash(Indexes),C,Susp,MixedUsedVars,Body) :-
3027 generate_multi_hash_insert_constraint_bodies(Indexes,C,Susp,Body,MixedUsedVars),
3028 sort_out_used_vars(MixedUsedVars,UsedVars).
3029 insert_constraint_body(atomic_constants(Index,_,_),C,Susp,UsedVars,Body) :-
3030 multi_hash_key_direct(C,Index,Susp,Key,UsedVars),
3031 constants_store_index_name(C,Index,IndexName),
3032 IndexLookup =.. [IndexName,Key,StoreName],
3035 nb_getval(StoreName,Store),
3036 b_setval(StoreName,[Susp|Store])
3040 insert_constraint_body(ground_constants(Index,_),C,Susp,UsedVars,Body) :-
3041 multi_hash_key_direct(C,Index,Susp,Key,UsedVars),
3042 constants_store_index_name(C,Index,IndexName),
3043 IndexLookup =.. [IndexName,Key,StoreName],
3046 nb_getval(StoreName,Store),
3047 b_setval(StoreName,[Susp|Store])
3051 insert_constraint_body(global_ground,C,Susp,[],Body) :-
3052 global_ground_store_name(C,StoreName),
3053 make_get_store_goal(StoreName,Store,GetStoreGoal),
3054 make_update_store_goal(StoreName,Cell,UpdateStoreGoal),
3055 ( chr_pp_flag(debugable,on) ->
3056 Cell = [Susp|Store],
3063 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,Cell,SetGoal),
3067 Cell = [Susp|Store],
3069 ( Store = [NextSusp|_] ->
3076 % global_ground_store_name(C,StoreName),
3077 % make_get_store_goal(StoreName,Store,GetStoreGoal),
3078 % make_update_store_goal(StoreName,[Susp|Store],UpdateStoreGoal),
3081 % GetStoreGoal, % nb_getval(StoreName,Store),
3082 % UpdateStoreGoal % b_setval(StoreName,[Susp|Store])
3084 insert_constraint_body(var_assoc_store(VarIndex,AssocIndex),C,Susp,[VarIndex-Variable,AssocIndex-Key],Body) :-
3085 % TODO: generalize to more than one !!!
3086 get_target_module(Module),
3087 Body = ( get_attr(Variable,Module,AssocStore) ->
3088 insert_assoc_store(AssocStore,Key,Susp)
3090 new_assoc_store(AssocStore),
3091 put_attr(Variable,Module,AssocStore),
3092 insert_assoc_store(AssocStore,Key,Susp)
3095 insert_constraint_body(global_singleton,C,Susp,[],Body) :-
3096 global_singleton_store_name(C,StoreName),
3097 make_update_store_goal(StoreName,Susp,UpdateStoreGoal),
3102 insert_constraint_body(multi_store(StoreTypes),C,Susp,UsedVars,Body) :-
3103 find_with_var_identity(
3107 member(ST,StoreTypes),
3108 chr_translate:insert_constraint_body(ST,C,Susp,UV,B)
3112 once(pairup(Bodies,NestedUsedVars,BodiesUsedVars)),
3113 list2conj(Bodies,Body),
3114 sort_out_used_vars(NestedUsedVars,UsedVars).
3115 insert_constraint_body(identifier_store(Index),C,Susp,UsedVars,Body) :-
3116 UsedVars = [Index-Var],
3117 get_identifier_size(ISize),
3118 functor(Struct,struct,ISize),
3119 get_identifier_index(C,Index,IIndex),
3120 arg(IIndex,Struct,Susps),
3121 Body = (Var = Struct, setarg(IIndex,Var,[Susp|Susps])).
3122 insert_constraint_body(type_indexed_identifier_store(Index,IndexType),C,Susp,UsedVars,Body) :-
3123 UsedVars = [Index-Var],
3124 type_indexed_identifier_structure(IndexType,Struct),
3125 get_type_indexed_identifier_index(IndexType,C,Index,IIndex),
3126 arg(IIndex,Struct,Susps),
3127 Body = (Var = Struct, setarg(IIndex,Var,[Susp|Susps])).
3129 sort_out_used_vars(NestedUsedVars,UsedVars) :-
3130 flatten(NestedUsedVars,FlatUsedVars),
3131 sort(FlatUsedVars,SortedFlatUsedVars),
3132 sort_out_used_vars1(SortedFlatUsedVars,UsedVars).
3134 sort_out_used_vars1([],[]).
3135 sort_out_used_vars1([I-V],L) :- !, L = [I-V].
3136 sort_out_used_vars1([I-X,J-Y|R],L) :-
3139 sort_out_used_vars1([I-X|R],L)
3142 sort_out_used_vars1([J-Y|R],T)
3145 generate_multi_inthash_insert_constraint_bodies([],_,_,true).
3146 generate_multi_inthash_insert_constraint_bodies([Index|Indexes],FA,Susp,(Body,Bodies)) :-
3147 multi_hash_store_name(FA,Index,StoreName),
3148 multi_hash_key(FA,Index,Susp,KeyBody,Key),
3152 nb_getval(StoreName,Store),
3153 insert_iht(Store,Key,Susp)
3155 generate_multi_inthash_insert_constraint_bodies(Indexes,FA,Susp,Bodies).
3157 generate_multi_hash_insert_constraint_bodies([],_,_,true,[]).
3158 generate_multi_hash_insert_constraint_bodies([Index|Indexes],FA,Susp,(Body,Bodies),[UsedVars|MoreUsedVars]) :-
3159 multi_hash_store_name(FA,Index,StoreName),
3160 multi_hash_key_direct(FA,Index,Susp,Key,UsedVars),
3161 make_get_store_goal(StoreName,Store,GetStoreGoal),
3162 ( chr_pp_flag(ht_removal,on)
3163 -> ht_prev_field(Index,PrevField),
3164 set_dynamic_suspension_term_field(PrevField,FA,NextSusp,Result,
3169 insert_ht(Store,Key,Susp,Result),
3170 ( Result = [_,NextSusp|_]
3178 insert_ht(Store,Key,Susp)
3181 generate_multi_hash_insert_constraint_bodies(Indexes,FA,Susp,Bodies,MoreUsedVars).
3183 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3186 delete_constraint_clause(C,Clauses,RestClauses) :-
3187 ( is_used_auxiliary_predicate(delete_from_store,C) ->
3188 Clauses = [Clause|RestClauses],
3189 Clause = (Head :- Body),
3190 delete_constraint_atom(C,Susp,Head),
3193 delete_constraint_body(C,Head,Susp,[],Body)
3195 Clauses = RestClauses
3198 delete_constraint_goal(Head,Susp,VarDict,Goal) :-
3201 ( chr_pp_flag(inline_insertremove,off) ->
3202 use_auxiliary_predicate(delete_from_store,C),
3203 delete_constraint_atom(C,Susp,Goal)
3205 delay_phase_end(validate_store_type_assumptions, delete_constraint_body(C,Head,Susp,VarDict,Goal))
3208 delete_constraint_atom(C,Susp,Atom) :-
3209 make_name('$delete_from_store_',C,Functor),
3210 Atom =.. [Functor,Susp].
3213 delete_constraint_body(C,Head,Susp,VarDict,Body) :-
3214 Body = (CounterBody,DeleteBody),
3215 ( chr_pp_flag(store_counter,on) ->
3216 CounterBody = '$delete_counter_inc'
3220 get_store_type(C,StoreType),
3221 delete_constraint_body(StoreType,C,Head,Susp,VarDict,DeleteBody).
3223 delete_constraint_body(default,C,_,Susp,_,Body) :-
3224 ( chr_pp_flag(debugable,on) ->
3225 global_list_store_name(C,StoreName),
3226 make_get_store_goal(StoreName,Store,GetStoreGoal),
3227 make_update_store_goal(StoreName,NStore,UpdateStoreGoal),
3230 GetStoreGoal, % nb_getval(StoreName,Store),
3231 'chr sbag_del_element'(Store,Susp,NStore),
3232 UpdateStoreGoal % b_setval(StoreName,NStore)
3235 get_dynamic_suspension_term_field(global_list_prev,C,Susp,PredCell,GetGoal),
3236 global_list_store_name(C,StoreName),
3237 make_get_store_goal(StoreName,Store,GetStoreGoal),
3238 make_update_store_goal(StoreName,Tail,UpdateStoreGoal),
3239 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,_,SetGoal1),
3240 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,PredCell,SetGoal2),
3245 GetStoreGoal, % nb_getval(StoreName,Store),
3248 ( Tail = [NextSusp|_] ->
3254 PredCell = [_,_|Tail],
3255 setarg(2,PredCell,Tail),
3256 ( Tail = [NextSusp|_] ->
3264 % get_target_module(Mod),
3265 % get_max_constraint_index(Total),
3267 % generate_detach_body_1(C,Store,Susp,DetachBody),
3270 % 'chr default_store'(Store),
3274 % generate_detach_body_n(C,Store,Susp,DetachBody),
3277 % 'chr default_store'(Store),
3281 delete_constraint_body(multi_inthash(Indexes),C,_,Susp,_,Body) :-
3282 generate_multi_inthash_delete_constraint_bodies(Indexes,C,Susp,Body).
3283 delete_constraint_body(multi_hash(Indexes),C,Head,Susp,VarDict,Body) :-
3284 generate_multi_hash_delete_constraint_bodies(Indexes,C,Head,Susp,VarDict,Body).
3285 delete_constraint_body(atomic_constants(Index,_,_),C,Head,Susp,VarDict,Body) :-
3286 multi_hash_key(C,Head,Index,Susp,VarDict,KeyBody,Key),
3287 constants_store_index_name(C,Index,IndexName),
3288 IndexLookup =.. [IndexName,Key,StoreName],
3292 nb_getval(StoreName,Store),
3293 'chr sbag_del_element'(Store,Susp,NStore),
3294 b_setval(StoreName,NStore)
3298 delete_constraint_body(ground_constants(Index,_),C,Head,Susp,VarDict,Body) :-
3299 multi_hash_key(C,Head,Index,Susp,VarDict,KeyBody,Key),
3300 constants_store_index_name(C,Index,IndexName),
3301 IndexLookup =.. [IndexName,Key,StoreName],
3305 nb_getval(StoreName,Store),
3306 'chr sbag_del_element'(Store,Susp,NStore),
3307 b_setval(StoreName,NStore)
3311 delete_constraint_body(global_ground,C,_,Susp,_,Body) :-
3312 ( chr_pp_flag(debugable,on) ->
3313 global_ground_store_name(C,StoreName),
3314 make_get_store_goal(StoreName,Store,GetStoreGoal),
3315 make_update_store_goal(StoreName,NStore,UpdateStoreGoal),
3318 GetStoreGoal, % nb_getval(StoreName,Store),
3319 'chr sbag_del_element'(Store,Susp,NStore),
3320 UpdateStoreGoal % b_setval(StoreName,NStore)
3323 get_dynamic_suspension_term_field(global_list_prev,C,Susp,PredCell,GetGoal),
3324 global_ground_store_name(C,StoreName),
3325 make_get_store_goal(StoreName,Store,GetStoreGoal),
3326 make_update_store_goal(StoreName,Tail,UpdateStoreGoal),
3327 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,_,SetGoal1),
3328 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,PredCell,SetGoal2),
3333 GetStoreGoal, % nb_getval(StoreName,Store),
3336 ( Tail = [NextSusp|_] ->
3342 PredCell = [_,_|Tail],
3343 setarg(2,PredCell,Tail),
3344 ( Tail = [NextSusp|_] ->
3352 % global_ground_store_name(C,StoreName),
3353 % make_get_store_goal(StoreName,Store,GetStoreGoal),
3354 % make_update_store_goal(StoreName,NStore,UpdateStoreGoal),
3357 % GetStoreGoal, % nb_getval(StoreName,Store),
3358 % 'chr sbag_del_element'(Store,Susp,NStore),
3359 % UpdateStoreGoal % b_setval(StoreName,NStore)
3361 delete_constraint_body(var_assoc_store(VarIndex,AssocIndex),C,_,Susp,_,Body) :-
3362 get_target_module(Module),
3363 get_dynamic_suspension_term_field(argument(VarIndex),C,Susp,Variable,VariableGoal),
3364 get_dynamic_suspension_term_field(argument(AssocIndex),C,Susp,Key,KeyGoal),
3367 get_attr(Variable,Module,AssocStore),
3369 delete_assoc_store(AssocStore,Key,Susp)
3371 delete_constraint_body(global_singleton,C,_,_Susp,_,Body) :-
3372 global_singleton_store_name(C,StoreName),
3373 make_update_store_goal(StoreName,[],UpdateStoreGoal),
3376 UpdateStoreGoal % b_setval(StoreName,[])
3378 delete_constraint_body(multi_store(StoreTypes),C,Head,Susp,VarDict,Body) :-
3379 find_with_var_identity(
3381 [Susp/VarDict/Head],
3383 member(ST,StoreTypes),
3384 chr_translate:delete_constraint_body(ST,C,Head,Susp,VarDict,B)
3388 list2conj(Bodies,Body).
3389 delete_constraint_body(identifier_store(Index),C,Head,Susp,VarDict,Body) :-
3390 get_suspension_argument_possibly_in_scope(Head,Index,VarDict,Susp,Variable,VariableGoal),
3391 get_identifier_size(ISize),
3392 functor(Struct,struct,ISize),
3393 get_identifier_index(C,Index,IIndex),
3394 arg(IIndex,Struct,Susps),
3398 'chr sbag_del_element'(Susps,Susp,NSusps),
3399 setarg(IIndex,Variable,NSusps)
3401 delete_constraint_body(type_indexed_identifier_store(Index,IndexType),C,Head,Susp,VarDict,Body) :-
3402 get_suspension_argument_possibly_in_scope(Head,Index,VarDict,Susp,Variable,VariableGoal),
3403 type_indexed_identifier_structure(IndexType,Struct),
3404 get_type_indexed_identifier_index(IndexType,C,Index,IIndex),
3405 arg(IIndex,Struct,Susps),
3409 'chr sbag_del_element'(Susps,Susp,NSusps),
3410 setarg(IIndex,Variable,NSusps)
3413 generate_multi_inthash_delete_constraint_bodies([],_,_,true).
3414 generate_multi_inthash_delete_constraint_bodies([Index|Indexes],FA,Susp,(Body,Bodies)) :-
3415 multi_hash_store_name(FA,Index,StoreName),
3416 multi_hash_key(FA,Index,Susp,KeyBody,Key),
3420 nb_getval(StoreName,Store),
3421 delete_iht(Store,Key,Susp)
3423 generate_multi_inthash_delete_constraint_bodies(Indexes,FA,Susp,Bodies).
3424 generate_multi_hash_delete_constraint_bodies([],_,_,_,_,true).
3425 generate_multi_hash_delete_constraint_bodies([Index|Indexes],C,Head,Susp,VarDict,(Body,Bodies)) :-
3426 multi_hash_store_name(C,Index,StoreName),
3427 multi_hash_key(C,Head,Index,Susp,VarDict,KeyBody,Key),
3428 make_get_store_goal(StoreName,Store,GetStoreGoal),
3429 ( chr_pp_flag(ht_removal,on)
3430 -> ht_prev_field(Index,PrevField),
3431 get_dynamic_suspension_term_field(PrevField,C,Susp,Prev,GetGoal),
3432 set_dynamic_suspension_term_field(PrevField,C,NextSusp,_,
3434 set_dynamic_suspension_term_field(PrevField,C,NextSusp,Prev,
3442 delete_first_ht(Store,Key,Values),
3443 ( Values = [NextSusp|_]
3447 ; Prev = [_,_|Values],
3448 setarg(2,Prev,Values),
3449 ( Values = [NextSusp|_]
3458 GetStoreGoal, % nb_getval(StoreName,Store),
3459 delete_ht(Store,Key,Susp)
3462 generate_multi_hash_delete_constraint_bodies(Indexes,FA,Head,Susp,VarDict,Bodies).
3464 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3467 module_initializer/1,
3468 module_initializers/1.
3470 module_initializers(G), module_initializer(Initializer) <=>
3471 G = (Initializer,Initializers),
3472 module_initializers(Initializers).
3474 module_initializers(G) <=>
3477 generate_attach_code(Constraints,[Enumerate|L]) :-
3478 enumerate_stores_code(Constraints,Enumerate),
3479 generate_attach_code(Constraints,L,T),
3480 module_initializers(Initializers),
3481 prolog_global_variables_code(PrologGlobalVariables),
3482 % Do not rename or the 'chr_initialization' predicate
3483 % without warning SSS
3484 T = [('$chr_initialization' :- Initializers),(:- initialization '$chr_initialization')|PrologGlobalVariables].
3486 generate_attach_code([],L,L).
3487 generate_attach_code([C|Cs],L,T) :-
3488 get_store_type(C,StoreType),
3489 generate_attach_code(StoreType,C,L,L1),
3490 generate_attach_code(Cs,L1,T).
3492 generate_attach_code(default,C,L,T) :-
3493 global_list_store_initialisation(C,L,T).
3494 generate_attach_code(multi_inthash(Indexes),C,L,T) :-
3495 multi_inthash_store_initialisations(Indexes,C,L,L1),
3496 multi_inthash_via_lookups(Indexes,C,L1,T).
3497 generate_attach_code(multi_hash(Indexes),C,L,T) :-
3498 multi_hash_store_initialisations(Indexes,C,L,L1),
3499 multi_hash_lookups(Indexes,C,L1,T).
3500 generate_attach_code(atomic_constants(Index,Constants,_),C,L,T) :-
3501 constants_initializers(C,Index,Constants),
3502 atomic_constants_code(C,Index,Constants,L,T).
3503 generate_attach_code(ground_constants(Index,Constants),C,L,T) :-
3504 constants_initializers(C,Index,Constants),
3505 ground_constants_code(C,Index,Constants,L,T).
3506 generate_attach_code(global_ground,C,L,T) :-
3507 global_ground_store_initialisation(C,L,T).
3508 generate_attach_code(var_assoc_store(_,_),_,L,L) :-
3509 use_auxiliary_module(chr_assoc_store).
3510 generate_attach_code(global_singleton,C,L,T) :-
3511 global_singleton_store_initialisation(C,L,T).
3512 generate_attach_code(multi_store(StoreTypes),C,L,T) :-
3513 multi_store_generate_attach_code(StoreTypes,C,L,T).
3514 generate_attach_code(identifier_store(Index),C,L,T) :-
3515 get_identifier_index(C,Index,IIndex),
3517 get_identifier_size(ISize),
3518 functor(Struct,struct,ISize),
3519 Struct =.. [_,Label|Stores],
3520 set_elems(Stores,[]),
3521 Clause1 = new_identifier(Label,Struct),
3522 functor(Struct2,struct,ISize),
3523 arg(1,Struct2,Label2),
3525 ( user:portray(Struct2) :-
3530 functor(Struct3,struct,ISize),
3531 arg(1,Struct3,Label3),
3532 Clause3 = identifier_label(Struct3,Label3),
3533 L = [Clause1,Clause2,Clause3|T]
3537 generate_attach_code(type_indexed_identifier_store(Index,IndexType),C,L,T) :-
3538 get_type_indexed_identifier_index(IndexType,C,Index,IIndex),
3540 identifier_store_initialization(IndexType,L,L1),
3541 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3542 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3543 get_type_indexed_identifier_size(IndexType,ISize),
3544 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3545 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3546 type_indexed_identifier_structure(IndexType,Struct),
3547 Struct =.. [_,Label|Stores],
3548 set_elems(Stores,[]),
3549 type_indexed_identifier_name(IndexType,new_identifier,Name1),
3550 Clause1 =.. [Name1,Label,Struct],
3551 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3552 Goal1 =.. [Name1,Label1b,S1b],
3553 type_indexed_identifier_structure(IndexType,Struct1b),
3554 Struct1b =.. [_,Label1b|Stores1b],
3555 set_elems(Stores1b,[]),
3556 Expansion1 = (S1b = Struct1b),
3557 Clause1b = user:goal_expansion(Goal1,Expansion1),
3558 % writeln(Clause1-Clause1b),
3559 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3560 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3561 type_indexed_identifier_structure(IndexType,Struct2),
3562 arg(1,Struct2,Label2),
3564 ( user:portray(Struct2) :-
3569 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3570 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3571 type_indexed_identifier_structure(IndexType,Struct3),
3572 arg(1,Struct3,Label3),
3573 type_indexed_identifier_name(IndexType,identifier_label,Name3),
3574 Clause3 =.. [Name3,Struct3,Label3],
3575 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3576 Goal3b =.. [Name3,S3b,L3b],
3577 type_indexed_identifier_structure(IndexType,Struct3b),
3578 arg(1,Struct3b,L3b),
3579 Expansion3b = (S3 = Struct3b),
3580 Clause3b = ( user:goal_expansion(Goal3b,Expansion3b) :- writeln(expanding)),
3581 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3582 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3583 identifier_store_name(IndexType,GlobalVariable),
3584 lookup_identifier_atom(IndexType,X,IX,LookupAtom),
3585 type_indexed_identifier_name(IndexType,new_identifier,NewIdentifierFunctor),
3586 NewIdentifierGoal =.. [NewIdentifierFunctor,X,IX],
3589 nb_getval(GlobalVariable,HT),
3590 ( lookup_ht(HT,X,[IX]) ->
3597 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3598 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3599 L1 = [(:- multifile goal_expansion/2),(:- dynamic goal_expansion/2),Clause1,Clause1b,Clause2,Clause3,Clause3b,Clause4|T]
3604 constants_initializers(C,Index,Constants) :-
3605 maplist(constants_store_name(C,Index),Constants,StoreNames),
3606 findall(Initializer,
3607 ( member(StoreName,StoreNames),
3608 Initializer = nb_setval(StoreName,[])
3611 maplist(module_initializer,Initializers).
3613 lookup_identifier_atom(Key,X,IX,Atom) :-
3614 atom_concat('lookup_identifier_',Key,LookupFunctor),
3615 Atom =.. [LookupFunctor,X,IX].
3617 identifier_label_atom(IndexType,IX,X,Atom) :-
3618 type_indexed_identifier_name(IndexType,identifier_label,Name),
3619 Atom =.. [Name,IX,X].
3621 multi_store_generate_attach_code([],_,L,L).
3622 multi_store_generate_attach_code([ST|STs],C,L,T) :-
3623 generate_attach_code(ST,C,L,L1),
3624 multi_store_generate_attach_code(STs,C,L1,T).
3626 multi_inthash_store_initialisations([],_,L,L).
3627 multi_inthash_store_initialisations([Index|Indexes],FA,L,T) :-
3628 use_auxiliary_module(chr_integertable_store),
3629 multi_hash_store_name(FA,Index,StoreName),
3630 module_initializer((new_iht(HT),nb_setval(StoreName,HT))),
3631 % L = [(:- (chr_integertable_store:new_ht(HT),nb_setval(StoreName,HT)) )|L1],
3633 multi_inthash_store_initialisations(Indexes,FA,L1,T).
3634 multi_hash_store_initialisations([],_,L,L).
3635 multi_hash_store_initialisations([Index|Indexes],FA,L,T) :-
3636 use_auxiliary_module(chr_hashtable_store),
3637 multi_hash_store_name(FA,Index,StoreName),
3638 prolog_global_variable(StoreName),
3639 make_init_store_goal(StoreName,HT,InitStoreGoal),
3640 module_initializer((new_ht(HT),InitStoreGoal)),
3642 multi_hash_store_initialisations(Indexes,FA,L1,T).
3644 global_list_store_initialisation(C,L,T) :-
3646 global_list_store_name(C,StoreName),
3647 prolog_global_variable(StoreName),
3648 make_init_store_goal(StoreName,[],InitStoreGoal),
3649 module_initializer(InitStoreGoal)
3654 global_ground_store_initialisation(C,L,T) :-
3655 global_ground_store_name(C,StoreName),
3656 prolog_global_variable(StoreName),
3657 make_init_store_goal(StoreName,[],InitStoreGoal),
3658 module_initializer(InitStoreGoal),
3660 global_singleton_store_initialisation(C,L,T) :-
3661 global_singleton_store_name(C,StoreName),
3662 prolog_global_variable(StoreName),
3663 make_init_store_goal(StoreName,[],InitStoreGoal),
3664 module_initializer(InitStoreGoal),
3666 identifier_store_initialization(IndexType,L,T) :-
3667 use_auxiliary_module(chr_hashtable_store),
3668 identifier_store_name(IndexType,StoreName),
3669 prolog_global_variable(StoreName),
3670 make_init_store_goal(StoreName,HT,InitStoreGoal),
3671 module_initializer((new_ht(HT),InitStoreGoal)),
3675 multi_inthash_via_lookups([],_,L,L).
3676 multi_inthash_via_lookups([Index|Indexes],C,L,T) :-
3677 multi_hash_lookup_head(C,Index,Key,SuspsList,Head),
3678 multi_hash_lookup_body(C,inthash,Index,Key,SuspsList,Body),
3679 L = [(Head :- Body)|L1],
3680 multi_inthash_via_lookups(Indexes,C,L1,T).
3681 multi_hash_lookups([],_,L,L).
3682 multi_hash_lookups([Index|Indexes],C,L,T) :-
3683 multi_hash_lookup_head(C,Index,Key,SuspsList,Head),
3684 multi_hash_lookup_body(C,hash,Index,Key,SuspsList,Body),
3685 L = [(Head :- Body)|L1],
3686 multi_hash_lookups(Indexes,C,L1,T).
3688 multi_hash_lookup_head(ConstraintSymbol,Index,Key,SuspsList,Head) :-
3689 multi_hash_lookup_name(ConstraintSymbol,Index,Name),
3690 Head =.. [Name,Key,SuspsList].
3692 %% multi_hash_lookup_body(+ConstraintSymbol,+HashType,+Index,+Key,+SuspsList,-Goal) is det.
3694 % Returns goal that performs hash table lookup.
3695 multi_hash_lookup_body(ConstraintSymbol,HashType,Index,Key,SuspsList,Goal) :-
3697 get_store_type(ConstraintSymbol,multi_store(Stores)),
3698 ( memberchk(atomic_constants(Index,Constants,_),Stores) ->
3700 constants_store_name(ConstraintSymbol,Index,Key,StoreName),
3701 Goal = nb_getval(StoreName,SuspsList)
3703 constants_store_index_name(ConstraintSymbol,Index,IndexName),
3704 Lookup =.. [IndexName,Key,StoreName],
3705 Goal = (Lookup, nb_getval(StoreName,SuspsList))
3707 ; memberchk(ground_constants(Index,Constants),Stores) ->
3709 constants_store_name(ConstraintSymbol,Index,Key,StoreName),
3710 Goal = nb_getval(StoreName,SuspsList)
3712 constants_store_index_name(ConstraintSymbol,Index,IndexName),
3713 Lookup =.. [IndexName,Key,StoreName],
3714 Goal = (Lookup, nb_getval(StoreName,SuspsList))
3716 ; memberchk(multi_hash([Index]),Stores) ->
3717 multi_hash_store_name(ConstraintSymbol,Index,StoreName),
3718 make_get_store_goal(StoreName,HT,GetStoreGoal),
3719 ( HashType == hash, specialized_hash_term_call(ConstraintSymbol,Index,Key,Hash,HashCall) ->
3722 GetStoreGoal, % nb_getval(StoreName,HT),
3723 HashCall, % hash_term(Key,Hash),
3724 lookup_ht1(HT,Hash,Key,SuspsList)
3727 lookup_hash_call(HashType,HT,Key,SuspsList,Lookup),
3730 GetStoreGoal, % nb_getval(StoreName,HT),
3734 ; HashType == inthash ->
3735 multi_hash_store_name(ConstraintSymbol,Index,StoreName),
3736 make_get_store_goal(StoreName,HT,GetStoreGoal),
3737 lookup_hash_call(HashType,HT,Key,SuspsList,Lookup),
3740 GetStoreGoal, % nb_getval(StoreName,HT),
3743 % ; % chr_error(internal,'Index ~w for constraint ~w does not exist!\n',[Index,ConstraintSymbol])
3744 % find alternative index
3745 % -> SubIndex + RestIndex
3746 % -> SubKey + RestKeys
3747 % multi_hash_lookup_goal(ConstraintSymbol,HashType,SubIndex,SubKey,SuspsList,SubGoal),
3748 % instantiate rest goal?
3749 % Goal = (SubGoal,RestGoal)
3753 lookup_hash_call(hash,HT,Key,SuspsList,lookup_ht(HT,Key,SuspsList)).
3754 lookup_hash_call(inthash,HT,Key,SuspsList,lookup_iht(HT,Key,SuspsList)).
3756 specialized_hash_term_call(Constraint,Index,Key,Hash,Call) :-
3758 % This is based on a property of SWI-Prolog's
3759 % hash_term/2 predicate:
3760 % the hash value is stable over repeated invocations
3762 hash_term(Key,Hash),
3764 ; Index = [IndexPos],
3765 get_constraint_type(Constraint,ArgTypes),
3766 nth1(IndexPos,ArgTypes,Type),
3767 unalias_type(Type,NormalType),
3768 memberchk_eq(NormalType,[int,natural]) ->
3769 ( NormalType == int ->
3778 specialize_hash_term(Key,NewKey),
3780 Call = hash_term(NewKey,Hash)
3783 specialize_hash_term(Term,NewTerm) :-
3785 hash_term(Term,NewTerm)
3790 maplist(specialize_hash_term,Args,NewArgs),
3791 NewTerm =.. [F|NewArgs]
3794 multi_hash_lookup_goal(ConstraintSymbol,HashType,Index,Key,SuspsList,Goal) :-
3795 ( /* chr_pp_flag(experiment,off) ->
3798 actual_atomic_multi_hash_keys(ConstraintSymbol,Index,[Key])
3800 actual_ground_multi_hash_keys(ConstraintSymbol,Index,[Key])
3802 actual_non_atomic_multi_hash_key(ConstraintSymbol,Index)
3804 delay_phase_end(validate_store_type_assumptions,
3805 multi_hash_lookup_body(ConstraintSymbol,HashType,Index,Key,SuspsList,Goal)).
3807 :- chr_constraint actual_atomic_multi_hash_keys/3.
3808 :- chr_option(mode,actual_atomic_multi_hash_keys(+,+,?)).
3810 :- chr_constraint actual_ground_multi_hash_keys/3.
3811 :- chr_option(mode,actual_ground_multi_hash_keys(+,+,?)).
3813 :- chr_constraint actual_non_atomic_multi_hash_key/2.
3814 :- chr_option(mode,actual_non_atomic_multi_hash_key(+,+)).
3817 actual_atomic_multi_hash_keys(C,Index,Keys)
3818 ==> format('Keys: ~w - ~w : ~w\n', [C,Index,Keys]).
3820 actual_ground_multi_hash_keys(C,Index,Keys)
3821 ==> format('Keys: ~w - ~w : ~w\n', [C,Index,Keys]).
3823 actual_non_atomic_multi_hash_key(C,Index)
3824 ==> format('Keys: ~w - ~w : N/A\n', [C,Index]).
3826 actual_atomic_multi_hash_keys(C,Index,Keys1), actual_atomic_multi_hash_keys(C,Index,Keys2)
3827 <=> append(Keys1,Keys2,Keys0),
3829 actual_atomic_multi_hash_keys(C,Index,Keys).
3831 actual_ground_multi_hash_keys(C,Index,Keys1), actual_atomic_multi_hash_keys(C,Index,Keys2)
3832 <=> append(Keys1,Keys2,Keys0),
3834 actual_ground_multi_hash_keys(C,Index,Keys).
3836 actual_ground_multi_hash_keys(C,Index,Keys1), actual_ground_multi_hash_keys(C,Index,Keys2)
3837 <=> append(Keys1,Keys2,Keys0),
3839 actual_ground_multi_hash_keys(C,Index,Keys).
3841 actual_non_atomic_multi_hash_key(C,Index) \ actual_non_atomic_multi_hash_key(C,Index)
3844 actual_non_atomic_multi_hash_key(C,Index) \ actual_atomic_multi_hash_keys(C,Index,_)
3847 actual_non_atomic_multi_hash_key(C,Index) \ actual_ground_multi_hash_keys(C,Index,_)
3850 %% multi_hash_lookup_name(+ConstraintSymbol,+Index,-Name)
3852 % Returns predicate name of hash table lookup predicate.
3853 multi_hash_lookup_name(F/A,Index,Name) :-
3857 atom_concat_list(Index,IndexName)
3859 atom_concat_list(['$via1_multi_hash_',F,'___',A,'-',IndexName],Name).
3861 multi_hash_store_name(F/A,Index,Name) :-
3862 get_target_module(Mod),
3866 atom_concat_list(Index,IndexName)
3868 atom_concat_list(['$chr_store_multi_hash_',Mod,'____',F,'___',A,'-',IndexName],Name).
3870 multi_hash_key(FA,Index,Susp,KeyBody,Key) :-
3871 ( ( integer(Index) ->
3876 get_dynamic_suspension_term_field(argument(I),FA,Susp,Key,KeyBody)
3878 sort(Index,Indexes),
3879 find_with_var_identity(Goal-KeyI,[Susp],(member(I,Indexes),get_dynamic_suspension_term_field(argument(I),FA,Susp,KeyI,Goal)),ArgKeyPairs),
3880 once(pairup(Bodies,Keys,ArgKeyPairs)),
3882 list2conj(Bodies,KeyBody)
3885 multi_hash_key(C,Head,Index,Susp,VarDict,KeyBody,Key) :-
3886 ( ( integer(Index) ->
3891 get_suspension_argument_possibly_in_scope(Head,I,VarDict,Susp,Key,KeyBody)
3893 sort(Index,Indexes),
3894 find_with_var_identity(
3896 [Susp/Head/VarDict],
3899 get_suspension_argument_possibly_in_scope(Head,I,VarDict,Susp,KeyI,Goal)
3903 once(pairup(Bodies,Keys,ArgKeyPairs)),
3905 list2conj(Bodies,KeyBody)
3908 get_suspension_argument_possibly_in_scope(Head,Index,VarDict,Susp,Arg,Goal) :-
3909 arg(Index,Head,OriginalArg),
3910 ( lookup_eq(VarDict,OriginalArg,Arg) ->
3915 get_dynamic_suspension_term_field(argument(Index),C,Susp,Arg,Goal)
3918 multi_hash_key_direct(FA,Index,Susp,Key,UsedVars) :-
3919 ( ( integer(Index) ->
3926 sort(Index,Indexes),
3927 pairup(Indexes,Keys,UsedVars),
3931 multi_hash_key_args(Index,Head,KeyArgs) :-
3933 arg(Index,Head,Arg),
3936 sort(Index,Indexes),
3937 term_variables(Head,Vars),
3938 find_with_var_identity(Arg,Vars,(member(I,Indexes), arg(I,Head,Arg)),KeyArgs)
3942 %-------------------------------------------------------------------------------
3943 atomic_constants_code(C,Index,Constants,L,T) :-
3944 constants_store_index_name(C,Index,IndexName),
3946 ( member(Constant,Constants),
3947 constants_store_name(C,Index,Constant,StoreName),
3948 Clause =.. [IndexName,Constant,StoreName]
3951 append(Clauses,T,L).
3953 %-------------------------------------------------------------------------------
3954 ground_constants_code(C,Index,Terms,L,T) :-
3955 constants_store_index_name(C,Index,IndexName),
3957 ( member(Constant,Terms),
3958 constants_store_name(C,Index,Constant,StoreName)
3962 replicate(N,[],More),
3963 trie_index([Terms|More],StoreNames,IndexName,L,T).
3965 constants_store_name(F/A,Index,Term,Name) :-
3966 get_target_module(Mod),
3967 term_to_atom(Term,Constant),
3968 term_to_atom(Index,IndexAtom),
3969 atom_concat_list(['$chr_store_constants_',Mod,'____',F,'___',A,'___',IndexAtom,'___',Constant],Name).
3971 constants_store_index_name(F/A,Index,Name) :-
3972 get_target_module(Mod),
3973 term_to_atom(Index,IndexAtom),
3974 atom_concat_list(['$chr_store_constants_',Mod,'____',F,'___',A,'___',IndexAtom],Name).
3976 trie_index([Patterns|MorePatterns],Results,Prefix,Clauses,Tail) :-
3977 trie_step(Patterns,Prefix,Prefix,MorePatterns,Results,Clauses,Tail).
3979 trie_step([],_,_,[],[],L,L) :- !.
3980 % length MorePatterns == length Patterns == length Results
3981 trie_step(Patterns,Symbol,Prefix,MorePatterns,Results,Clauses,T) :-
3982 MorePatterns = [List|_],
3985 ( member(Pattern,Patterns),
3986 functor(Pattern,F,A)
3991 trie_step_cases(FAs,N1,Patterns,MorePatterns,Results,Symbol,Prefix,Clauses,T).
3993 trie_step_cases([],_,_,_,_,_,_,Clauses,Clauses).
3994 trie_step_cases([FA|FAs],N,Pattern,MorePatterns,Results,Symbol,Prefix,Clauses,Tail) :-
3995 trie_step_case(FA,N,Pattern,MorePatterns,Results,Symbol,Prefix,Clauses,Clauses1),
3996 trie_step_cases(FAs,N,Pattern,MorePatterns,Results,Symbol,Prefix,Clauses1,Tail).
3998 trie_step_case(F/A,N,Patterns,MorePatterns,Results,Symbol,Prefix,[Clause|List],Tail) :-
3999 Clause = (Head :- Body),
4001 functor(Head,Symbol,N1),
4002 arg(N1,Head,Result),
4003 functor(IndexPattern,F,A),
4004 arg(1,Head,IndexPattern),
4005 Head =.. [_,_|RestArgs],
4006 IndexPattern =.. [_|Args],
4007 append(Args,RestArgs,RecArgs),
4008 ( RecArgs == [Result] ->
4011 rec_cases(Patterns,_,Results,F/A,_,_,MoreResults),
4012 MoreResults = [Result]
4014 gensym(Prefix,RSymbol),
4015 Body =.. [RSymbol|RecArgs],
4016 rec_cases(Patterns,MorePatterns,Results,F/A,Cases,MoreCases,MoreResults),
4017 trie_step(Cases,RSymbol,Prefix,MoreCases,MoreResults,List,Tail)
4020 rec_cases([],[],[],_,[],[],[]).
4021 rec_cases([Pattern|Patterns],[MorePattern|MorePatterns],[Result|Results],F/A,Cases,MoreCases,MoreResults) :-
4022 ( functor(Pattern,F,A), Pattern =.. [_|ArgPatterns], append(ArgPatterns,MorePattern,[Case|MoreCase]) ->
4023 Cases = [Case|NCases],
4024 MoreCases = [MoreCase|NMoreCases],
4025 MoreResults = [Result|NMoreResults],
4026 rec_cases(Patterns,MorePatterns,Results,F/A,NCases,NMoreCases,NMoreResults)
4028 rec_cases(Patterns,MorePatterns,Results,F/A,Cases,MoreCases,MoreResults)
4031 %-------------------------------------------------------------------------------
4032 global_list_store_name(F/A,Name) :-
4033 get_target_module(Mod),
4034 atom_concat_list(['$chr_store_global_list_',Mod,'____',F,'___',A],Name).
4035 global_ground_store_name(F/A,Name) :-
4036 get_target_module(Mod),
4037 atom_concat_list(['$chr_store_global_ground_',Mod,'____',F,'___',A],Name).
4038 global_singleton_store_name(F/A,Name) :-
4039 get_target_module(Mod),
4040 atom_concat_list(['$chr_store_global_singleton_',Mod,'____',F,'___',A],Name).
4042 identifier_store_name(TypeName,Name) :-
4043 get_target_module(Mod),
4044 atom_concat_list(['$chr_identifier_lookup_',Mod,'____',TypeName],Name).
4046 :- chr_constraint prolog_global_variable/1.
4047 :- chr_option(mode,prolog_global_variable(+)).
4049 :- chr_constraint prolog_global_variables/1.
4050 :- chr_option(mode,prolog_global_variables(-)).
4052 prolog_global_variable(Name) \ prolog_global_variable(Name) <=> true.
4054 prolog_global_variables(List), prolog_global_variable(Name) <=>
4056 prolog_global_variables(Tail).
4057 prolog_global_variables(List) <=> List = [].
4060 prolog_global_variables_code(Code) :-
4061 prolog_global_variables(Names),
4065 findall('$chr_prolog_global_variable'(Name),member(Name,Names),NameDeclarations),
4066 Code = [(:- dynamic user:exception/3),
4067 (:- multifile user:exception/3),
4068 (user:exception(undefined_global_variable,Name,retry) :-
4070 '$chr_prolog_global_variable'(Name),
4071 '$chr_initialization'
4080 % prolog_global_variables_code([]).
4082 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4083 %sbag_member_call(S,L,sysh:mem(S,L)).
4084 sbag_member_call(S,L,'chr sbag_member'(S,L)).
4085 %sbag_member_call(S,L,member(S,L)).
4086 update_mutable_call(A,B,'chr update_mutable'( A, B)).
4087 %update_mutable_call(A,B,setarg(1, B, A)).
4088 create_mutable_call(Value,Mutable,true) :- Mutable = mutable(Value).
4089 % create_mutable_call(Value,Mutable,'chr create_mutable'(Value,Mutable)).
4091 % get_suspension_field(Constraint,Susp,FieldName,Value,(Get0,Get1)) :-
4092 % get_dynamic_suspension_term_field(FieldName,Constraint,Susp,Field,Get0),
4093 % create_get_mutable(Value,Field,Get1).
4095 % update_suspension_field(Constraint,Susp,FieldName,NewValue,(Get,Set)) :-
4096 % get_dynamic_suspension_term_field(FieldName,Constraint,Susp,Field,Get),
4097 % update_mutable_call(NewValue,Field,Set).
4099 % get_update_suspension_field(Constraint,Susp,FieldName,Value,NewValue,Get0,Get1,Set) :-
4100 % get_dynamic_suspension_term_field(FieldName,Constraint,Susp,Field,Get0),
4101 % create_get_mutable_ref(Value,Field,Get1),
4102 % update_mutable_call(NewValue,Field,Set).
4104 % create_static_suspension_field(Constraint,Susp,FieldName,Value,Create) :-
4105 % get_static_suspension_term_field(FieldName,Constraint,Susp,Field),
4106 % create_mutable_call(Value,Field,Create).
4108 % get_static_suspension_field(Constraint,Susp,FieldName,Value,Get) :-
4109 % get_static_suspension_term_field(FieldName,Constraint,Susp,Field),
4110 % create_get_mutable(Value,Field,Get).
4112 % get_update_static_suspension_field(Constraint,Susp,SuspTerm,FieldName,Value,NewValue,Get,Set) :-
4113 % get_static_suspension_term_field(FieldName,Constraint,SuspTerm,Field),
4114 % create_get_mutable_ref(Value,Field,Get),
4115 % update_mutable_call(NewValue,Field,Set).
4117 get_suspension_field(Constraint,Susp,FieldName,Value,Get) :-
4118 get_dynamic_suspension_term_field(FieldName,Constraint,Susp,Value,Get).
4120 update_suspension_field(Constraint,Susp,FieldName,NewValue,Set) :-
4121 set_dynamic_suspension_term_field(FieldName,Constraint,Susp,NewValue,Set).
4123 get_update_suspension_field(Constraint,Susp,FieldName,Value,NewValue,true,Get,Set) :-
4124 get_dynamic_suspension_term_field(FieldName,Constraint,Susp,Value,Get),
4125 set_dynamic_suspension_term_field(FieldName,Constraint,Susp,NewValue,Set).
4127 create_static_suspension_field(Constraint,Susp,FieldName,Value,true) :-
4128 get_static_suspension_term_field(FieldName,Constraint,Susp,Value).
4130 get_static_suspension_field(Constraint,Susp,FieldName,Value,true) :-
4131 get_static_suspension_term_field(FieldName,Constraint,Susp,Value).
4133 get_update_static_suspension_field(Constraint,Susp,SuspTerm,FieldName,Value,NewValue,true,Set) :-
4134 get_static_suspension_term_field(FieldName,Constraint,SuspTerm,Value),
4135 set_dynamic_suspension_term_field(FieldName,Constraint,Susp,NewValue,Set).
4137 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4139 enumerate_stores_code(Constraints,Clause) :-
4140 Head = '$enumerate_constraints'(Constraint),
4141 enumerate_store_bodies(Constraints,Constraint,Bodies),
4142 list2disj(Bodies,Body),
4143 Clause = (Head :- Body).
4145 enumerate_store_bodies([],_,[]).
4146 enumerate_store_bodies([C|Cs],Constraint,L) :-
4148 get_store_type(C,StoreType),
4149 ( enumerate_store_body(StoreType,C,Suspension,SuspensionBody) ->
4152 chr_error(internal,'Could not generate enumeration code for constraint ~w.\n',[C])
4154 get_dynamic_suspension_term_field(arguments,C,Suspension,Arguments,DynamicGoal),
4156 Constraint0 =.. [F|Arguments],
4157 Body = (SuspensionBody, DynamicGoal, Constraint = Constraint0),
4162 enumerate_store_bodies(Cs,Constraint,T).
4164 enumerate_store_body(default,C,Susp,Body) :-
4165 global_list_store_name(C,StoreName),
4166 sbag_member_call(Susp,List,Sbag),
4167 make_get_store_goal(StoreName,List,GetStoreGoal),
4170 GetStoreGoal, % nb_getval(StoreName,List),
4173 % get_constraint_index(C,Index),
4174 % get_target_module(Mod),
4175 % get_max_constraint_index(MaxIndex),
4178 % 'chr default_store'(GlobalStore),
4179 % get_attr(GlobalStore,Mod,Attr)
4182 % NIndex is Index + 1,
4183 % sbag_member_call(Susp,List,Sbag),
4186 % arg(NIndex,Attr,List),
4190 % sbag_member_call(Susp,Attr,Sbag),
4193 % Body = (Body1,Body2).
4194 enumerate_store_body(multi_inthash([Index|_]),C,Susp,Body) :-
4195 multi_inthash_enumerate_store_body(Index,C,Susp,Body).
4196 enumerate_store_body(multi_hash([Index|_]),C,Susp,Body) :-
4197 multi_hash_enumerate_store_body(Index,C,Susp,Body).
4198 enumerate_store_body(atomic_constants(Index,Constants,Completeness),C,Susp,Body) :-
4199 Completeness == complete, % fail if incomplete
4200 find_with_var_identity(nb_getval(StoreName,Susps),[Susps],
4201 ( member(Constant,Constants),
4202 constants_store_name(C,Index,Constant,StoreName) )
4204 list2disj(Disjuncts, Disjunction),
4205 Body = ( Disjunction, member(Susp,Susps) ).
4206 enumerate_store_body(ground_constants(_,_),_,_,_) :- fail.
4207 enumerate_store_body(global_ground,C,Susp,Body) :-
4208 global_ground_store_name(C,StoreName),
4209 sbag_member_call(Susp,List,Sbag),
4210 make_get_store_goal(StoreName,List,GetStoreGoal),
4213 GetStoreGoal, % nb_getval(StoreName,List),
4216 enumerate_store_body(var_assoc_store(_,_),C,_,Body) :-
4218 enumerate_store_body(global_singleton,C,Susp,Body) :-
4219 global_singleton_store_name(C,StoreName),
4220 make_get_store_goal(StoreName,Susp,GetStoreGoal),
4223 GetStoreGoal, % nb_getval(StoreName,Susp),
4226 enumerate_store_body(multi_store(STs),C,Susp,Body) :-
4229 enumerate_store_body(ST,C,Susp,Body)
4231 enumerate_store_body(identifier_store(Index),C,Susp,Body) :-
4233 enumerate_store_body(type_indexed_identifier_store(Index,IndexType),C,Susp,Body) :-
4236 multi_inthash_enumerate_store_body(I,C,Susp,B) :-
4237 multi_hash_store_name(C,I,StoreName),
4240 nb_getval(StoreName,HT),
4243 multi_hash_enumerate_store_body(I,C,Susp,B) :-
4244 multi_hash_store_name(C,I,StoreName),
4245 make_get_store_goal(StoreName,HT,GetStoreGoal),
4248 GetStoreGoal, % nb_getval(StoreName,HT),
4252 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4261 :- chr_option(mode,prev_guard_list(+,+,+,+,+,+,+,+)).
4262 :- chr_option(mode,prev_guard_list(+,+,+,+,+,+)).
4263 :- chr_option(type_declaration,prev_guard_list(any,any,any,any,any,list)).
4264 :- chr_option(mode,simplify_guards(+)).
4265 :- chr_option(mode,set_all_passive(+)).
4267 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4268 % GUARD SIMPLIFICATION
4269 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4270 % If the negation of the guards of earlier rules entails (part of)
4271 % the current guard, the current guard can be simplified. We can only
4272 % use earlier rules with a head that matches if the head of the current
4273 % rule does, and which make it impossible for the current rule to match
4274 % if they fire (i.e. they shouldn't be propagation rules and their
4275 % head constraints must be subsets of those of the current rule).
4276 % At this point, we know for sure that the negation of the guard
4277 % of such a rule has to be true (otherwise the earlier rule would have
4278 % fired, because of the refined operational semantics), so we can use
4279 % that information to simplify the guard by replacing all entailed
4280 % conditions by true/0. As a consequence, the never-stored analysis
4281 % (in a further phase) will detect more cases of never-stored constraints.
4283 % e.g. c(X),d(Y) <=> X > 0 | ...
4284 % e(X) <=> X < 0 | ...
4285 % c(X) \ d(Y),e(Z) <=> X =< 0, Z >= 0, ... | ...
4289 guard_simplification :-
4290 ( chr_pp_flag(guard_simplification,on) ->
4291 precompute_head_matchings,
4297 % for every rule, we create a prev_guard_list where the last argument
4298 % eventually is a list of the negations of earlier guards
4299 rule(RuleNb,Rule) \ simplify_guards(RuleNb)
4301 Rule = pragma(rule(Head1,Head2,Guard,_B),ids(IDs1,IDs2),_Pragmas,_Name,RuleNb),
4302 append(Head1,Head2,Heads),
4303 make_head_matchings_explicit_not_negated(Heads,MatchingFreeHeads,Matchings),
4304 multiple_occ_constraints_checked([]),
4305 apply_guard_wrt_term(Heads,Guard,SubstitutedHeads),
4307 append(IDs1,IDs2,IDs),
4308 findall(tuple(C,O,RuleNb)-(-RuleNb),(member(ID,IDs),get_occurrence_from_id(C,O,RuleNb,ID)),HeapData),
4310 insert_list_q(HeapData,EmptyHeap,Heap),
4311 next_prev_rule(Heap,_,Heap1),
4312 next_prev_rule(Heap1,PrevRuleNb,NHeap),
4313 prev_guard_list(RuleNb,PrevRuleNb,NHeap,MatchingFreeHeads,Guard,[],Matchings,[SubstitutedHeads]),
4314 NextRule is RuleNb+1,
4315 simplify_guards(NextRule).
4317 next_prev_rule(Heap,RuleNb,NHeap) :-
4318 ( find_min_q(Heap,_-Priority) ->
4319 Priority = (-RuleNb),
4320 normalize_heap(Heap,Priority,NHeap)
4326 normalize_heap(Heap,Priority,NHeap) :-
4327 ( find_min_q(Heap,_-Priority) ->
4328 delete_min_q(Heap,Heap1,tuple(C,O,_)-_),
4331 get_occurrence(C,NO,RuleNb,_),
4332 insert_q(Heap1,tuple(C,NO,RuleNb)-(-RuleNb),Heap2)
4336 normalize_heap(Heap2,Priority,NHeap)
4346 % The negation of the guard of a non-propagation rule is added
4347 % if its kept head constraints are a subset of the kept constraints of
4348 % the rule we're working on, and its removed head constraints (at least one)
4349 % are a subset of the removed constraints.
4351 rule(PrevRuleNb,PrevRule) \ prev_guard_list(RuleNb,PrevRuleNb,Heap,CurrentHeads,G,GuardList,Matchings,GH)
4353 PrevRule = pragma(rule(H1,H2,PrevGuard,_B),_Ids,_Pragmas,_Name,_PrevRuleNb), % PrevRuleNb == _PrevRuleNb
4355 make_head_matchings_explicit(PrevRuleNb,MatchingFreeHeads,PrevMatchings),
4356 setof(Renaming,chr_translate:head_subset(MatchingFreeHeads,CurrentHeads,Renaming),Renamings)
4358 append(H1,H2,Heads),
4359 compute_derived_info(Renamings,PrevMatchings,MatchingFreeHeads,Heads,PrevGuard,Matchings,CurrentHeads,GH,DerivedInfo,GH_New1),
4360 append(GuardList,DerivedInfo,GL1),
4361 normalize_conj_list(GL1,GL),
4362 append(GH_New1,GH,GH1),
4363 normalize_conj_list(GH1,GH_New),
4364 next_prev_rule(Heap,PrevPrevRuleNb,NHeap),
4365 % PrevPrevRuleNb is PrevRuleNb-1,
4366 prev_guard_list(RuleNb,PrevPrevRuleNb,NHeap,CurrentHeads,G,GL,Matchings,GH_New).
4368 % if this isn't the case, we skip this one and try the next rule
4369 prev_guard_list(RuleNb,N,Heap,H,G,GuardList,M,GH)
4372 next_prev_rule(Heap,N1,NHeap),
4374 prev_guard_list(RuleNb,N1,NHeap,H,G,GuardList,M,GH)
4376 prev_guard_list(RuleNb,H,G,GuardList,M,GH)
4379 prev_guard_list(RuleNb,H,G,GuardList,M,GH)
4383 head_types_modes_condition(GH,H,TypeInfo),
4384 conj2list(TypeInfo,TI),
4385 term_variables(H,HeadVars),
4386 append([chr_pp_headvariables(HeadVars)|TI],GuardList,Info),
4387 normalize_conj_list(Info,InfoL),
4388 prev_guard_list(RuleNb,H,G,InfoL,M,[]).
4390 head_types_modes_condition([],H,true).
4391 head_types_modes_condition([GH|GHs],H,(TI1, TI2)) :-
4392 types_modes_condition(H,GH,TI1),
4393 head_types_modes_condition(GHs,H,TI2).
4397 % when all earlier guards are added or skipped, we simplify the guard.
4398 % if it's different from the original one, we change the rule
4400 prev_guard_list(RuleNb,H,G,GuardList,M,[]), rule(RuleNb,Rule)
4402 Rule = pragma(rule(Head1,Head2,G,B),Ids,Pragmas,Name,RuleNb),
4403 G \== true, % let's not try to simplify this ;)
4404 append(M,GuardList,Info),
4405 simplify_guard(G,B,Info,SimpleGuard,NB),
4408 rule(RuleNb,pragma(rule(Head1,Head2,SimpleGuard,NB),Ids,Pragmas,Name,RuleNb)),
4409 prev_guard_list(RuleNb,H,SimpleGuard,GuardList,M,[]).
4411 %% normalize_conj_list(+List,-NormalList) is det.
4413 % Removes =true= elements and flattens out conjunctions.
4415 normalize_conj_list(List,NormalList) :-
4416 list2conj(List,Conj),
4417 conj2list(Conj,NormalList).
4419 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4420 % AUXILIARY PREDICATES (GUARD SIMPLIFICATION)
4421 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4423 compute_derived_info([],_PrevMatchings,_MatchingFreeHeads,_Heads,_PrevGuard,_Matchings,_H,_GH,[],[]).
4424 compute_derived_info([Renaming1|RestRenamings],PrevMatchings,PrevMatchingFreeHeads,PrevHeads,PrevGuard,Matchings,H,GH,[DerivedInfo1|DerivedInfo2],[GH3|GH_New2]) :-
4425 copy_term(PrevMatchings-PrevGuard,FreshMatchings),
4426 variable_replacement(PrevMatchings-PrevGuard,FreshMatchings,ExtraRenaming),
4427 append(Renaming1,ExtraRenaming,Renaming2),
4428 list2conj(PrevMatchings,Match),
4429 negate_b(Match,HeadsDontMatch),
4430 make_head_matchings_explicit_not_negated2(PrevHeads,PrevMatchingFreeHeads,HeadsMatch),
4431 list2conj(HeadsMatch,HeadsMatchBut),
4432 term_variables(Renaming2,RenVars),
4433 term_variables(PrevMatchings-PrevGuard-HeadsMatch,MGVars),
4434 new_vars(MGVars,RenVars,ExtraRenaming2),
4435 append(Renaming2,ExtraRenaming2,Renaming),
4436 ( PrevGuard == true -> % true can't fail
4437 Info_ = HeadsDontMatch
4439 negate_b(PrevGuard,TheGuardFailed),
4440 Info_ = (HeadsDontMatch ; (HeadsMatchBut, TheGuardFailed))
4442 copy_with_variable_replacement(Info_,DerivedInfo1,Renaming),
4443 copy_with_variable_replacement(PrevGuard,RenamedG2,Renaming),
4444 copy_with_variable_replacement(PrevMatchings,RenamedMatchings_,Renaming),
4445 list2conj(RenamedMatchings_,RenamedMatchings),
4446 apply_guard_wrt_term(H,RenamedG2,GH2),
4447 apply_guard_wrt_term(GH2,RenamedMatchings,GH3),
4448 compute_derived_info(RestRenamings,PrevMatchings,PrevMatchingFreeHeads,PrevHeads,PrevGuard,Matchings,H,GH,DerivedInfo2,GH_New2).
4450 simplify_guard(G,B,Info,SG,NB) :-
4452 % writeq(guard_entailment:simplify_guards(Info,B,LG,SGL,NB)),nl,
4453 guard_entailment:simplify_guards(Info,B,LG,SGL,NB),
4458 new_vars([A|As],RV,ER) :-
4459 ( memberchk_eq(A,RV) ->
4462 ER = [A-NewA,NewA-A|ER2],
4466 %% head_subset(+Subset,+MultiSet,-Renaming) is nondet.
4468 % check if a list of constraints is a subset of another list of constraints
4469 % (multiset-subset), meanwhile computing a variable renaming to convert
4470 % one into the other.
4471 head_subset(H,Head,Renaming) :-
4472 head_subset(H,Head,Renaming,[],_).
4474 head_subset([],Remainder,Renaming,Renaming,Remainder).
4475 head_subset([X|Xs],MultiSet,Renaming,Acc,Remainder) :-
4476 head_member(MultiSet,X,NAcc,Acc,Remainder1),
4477 head_subset(Xs,Remainder1,Renaming,NAcc,Remainder).
4479 % check if A is in the list, remove it from Headleft
4480 head_member([X|Xs],A,Renaming,Acc,Remainder) :-
4481 ( variable_replacement(A,X,Acc,Renaming),
4484 Remainder = [X|RRemainder],
4485 head_member(Xs,A,Renaming,Acc,RRemainder)
4487 %-------------------------------------------------------------------------------%
4488 % memoing code to speed up repeated computation
4490 :- chr_constraint precompute_head_matchings/0.
4492 rule(RuleNb,PragmaRule), precompute_head_matchings ==>
4493 PragmaRule = pragma(rule(H1,H2,_G,_B),_Ids,_Pragmas,_Name,_PrevRuleNb),
4494 append(H1,H2,Heads),
4495 make_head_matchings_explicit_(Heads,MatchingFreeHeads,Matchings),
4496 copy_term_nat(MatchingFreeHeads-Matchings,A-B),
4497 make_head_matchings_explicit_memo_table(RuleNb,A,B).
4499 precompute_head_matchings <=> true.
4501 :- chr_constraint make_head_matchings_explicit_memo_table/3.
4502 :- chr_constraint make_head_matchings_explicit_memo_lookup/3.
4504 :- chr_option(mode,make_head_matchings_explicit_memo_table(+,?,?)).
4505 :- chr_option(mode,make_head_matchings_explicit_memo_lookup(+,?,?)).
4507 make_head_matchings_explicit_memo_table(RuleNb,NHeads,Matchings) \
4508 make_head_matchings_explicit_memo_lookup(RuleNb,Q1,Q2)
4512 make_head_matchings_explicit_memo_lookup(_,_,_) <=> fail.
4514 make_head_matchings_explicit(RuleNb,MatchingFreeHeads,Matchings) :-
4515 make_head_matchings_explicit_memo_lookup(RuleNb,A,B),
4516 copy_term_nat(A-B,MatchingFreeHeads-Matchings).
4517 %-------------------------------------------------------------------------------%
4519 make_head_matchings_explicit_(Heads,MatchingFreeHeads,Matchings) :-
4520 extract_arguments(Heads,Arguments),
4521 make_matchings_explicit(Arguments,FreeVariables,[],[],_,Matchings),
4522 substitute_arguments(Heads,FreeVariables,MatchingFreeHeads).
4524 make_head_matchings_explicit_not_negated(Heads,MatchingFreeHeads,Matchings) :-
4525 extract_arguments(Heads,Arguments),
4526 make_matchings_explicit_not_negated(Arguments,FreshVariables,Matchings),
4527 substitute_arguments(Heads,FreshVariables,MatchingFreeHeads).
4529 make_head_matchings_explicit_not_negated2(Heads,MatchingFreeHeads,Matchings) :-
4530 extract_arguments(Heads,Arguments1),
4531 extract_arguments(MatchingFreeHeads,Arguments2),
4532 make_matchings_explicit_not_negated(Arguments1,Arguments2,Matchings).
4534 %% extract_arguments(+ListOfConstraints,-ListOfVariables) is det.
4536 % Returns list of arguments of given list of constraints.
4537 extract_arguments([],[]).
4538 extract_arguments([Constraint|Constraints],AllArguments) :-
4539 Constraint =.. [_|Arguments],
4540 append(Arguments,RestArguments,AllArguments),
4541 extract_arguments(Constraints,RestArguments).
4543 %% substitute_arguments(+InListOfConstraints,ListOfVariables,-OutListOfConstraints) is det.
4545 % Substitutes arguments of constraints with those in the given list.
4547 substitute_arguments([],[],[]).
4548 substitute_arguments([Constraint|Constraints],Variables,[NConstraint|NConstraints]) :-
4549 functor(Constraint,F,N),
4550 split_at(N,Variables,Arguments,RestVariables),
4551 NConstraint =.. [F|Arguments],
4552 substitute_arguments(Constraints,RestVariables,NConstraints).
4554 make_matchings_explicit([],[],_,MC,MC,[]).
4555 make_matchings_explicit([Arg|Args],[NewVar|NewVars],VarAcc,MatchingCondition,MatchingConditionO,Matchings) :-
4557 ( memberchk_eq(Arg,VarAcc) ->
4558 list2disj(MatchingCondition,MatchingCondition_disj),
4559 Matchings = [(MatchingCondition_disj ; NewVar == Arg)|RestMatchings], % or only = ??
4562 Matchings = RestMatchings,
4564 NVarAcc = [Arg|VarAcc]
4566 MatchingCondition2 = MatchingCondition
4569 Arg =.. [F|RecArgs],
4570 make_matchings_explicit(RecArgs,RecVars,VarAcc,MatchingCondition,MatchingCondition_,RecMatchings),
4571 FlatArg =.. [F|RecVars],
4572 ( RecMatchings == [] ->
4573 Matchings = [functor(NewVar,F,A)|RestMatchings]
4575 list2conj(RecMatchings,ArgM_conj),
4576 list2disj(MatchingCondition,MatchingCondition_disj),
4577 ArgM_ = (NewVar \= FlatArg ; MatchingCondition_disj ; ArgM_conj),
4578 Matchings = [ functor(NewVar,F,A) , ArgM_|RestMatchings]
4580 MatchingCondition2 = [ NewVar \= FlatArg |MatchingCondition_],
4581 term_variables(Args,ArgVars),
4582 append(ArgVars,VarAcc,NVarAcc)
4584 make_matchings_explicit(Args,NewVars,NVarAcc,MatchingCondition2,MatchingConditionO,RestMatchings).
4587 %% make_matchings_explicit_not_negated(+ListOfTerms,-ListOfVariables,-ListOfMatchings) is det.
4589 % Returns list of new variables and list of pairwise unifications between given list and variables.
4591 make_matchings_explicit_not_negated([],[],[]).
4592 make_matchings_explicit_not_negated([X|Xs],[Var|Vars],Matchings) :-
4593 Matchings = [Var = X|RMatchings],
4594 make_matchings_explicit_not_negated(Xs,Vars,RMatchings).
4596 %% apply_guard_wrt_term(+ListOfConstraints,+Goal,-NewListOfConstraints) is det.
4598 % (Partially) applies substitutions of =Goal= to given list.
4600 apply_guard_wrt_term([],_Guard,[]).
4601 apply_guard_wrt_term([Term|RH],Guard,[NTerm|RGH]) :-
4603 apply_guard_wrt_variable(Guard,Term,NTerm)
4606 apply_guard_wrt_term(HArgs,Guard,NewHArgs),
4607 NTerm =.. [F|NewHArgs]
4609 apply_guard_wrt_term(RH,Guard,RGH).
4611 %% apply_guard_wrt_variable(+Goal,+Variable,-NVariable) is det.
4613 % (Partially) applies goal =Guard= wrt variable.
4615 apply_guard_wrt_variable((Guard1,Guard2),Variable,NVariable) :- !,
4616 apply_guard_wrt_variable(Guard1,Variable,NVariable1),
4617 apply_guard_wrt_variable(Guard2,NVariable1,NVariable).
4618 apply_guard_wrt_variable(Guard,Variable,NVariable) :-
4619 ( Guard = (X = Y), Variable == X ->
4621 ; Guard = functor(AVariable,Functor,Arity), Variable == AVariable, ground(Functor), ground(Arity) ->
4622 functor(NVariable,Functor,Arity)
4624 NVariable = Variable
4627 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4628 % ALWAYS FAILING HEADS
4629 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4631 rule(RuleNb,Rule) \ prev_guard_list(RuleNb,H,G,GuardList,M,[])
4633 chr_pp_flag(check_impossible_rules,on),
4634 Rule = pragma(rule(Head1,Head2,G,B),Ids,Pragmas,Name,RuleNb),
4635 append(M,GuardList,Info),
4636 guard_entailment:entails_guard(Info,fail)
4638 chr_warning(weird_program,'Heads will never match in ~@.\n\tThis rule will never fire!\n',[format_rule(Rule)]),
4639 set_all_passive(RuleNb).
4641 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4642 % HEAD SIMPLIFICATION
4643 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4645 % now we check the head matchings (guard may have been simplified meanwhile)
4646 prev_guard_list(RuleNb,H,G,GuardList,M,[]) \ rule(RuleNb,Rule)
4648 Rule = pragma(rule(Head1,Head2,G,B),Ids,Pragmas,Name,RuleNb),
4649 simplify_heads(M,GuardList,G,B,NewM,NewB),
4651 extract_arguments(Head1,VH1),
4652 extract_arguments(Head2,VH2),
4653 extract_arguments(H,VH),
4654 replace_some_heads(VH1,VH2,VH,NewM,H1,H2,G,B,NewB_),
4655 substitute_arguments(Head1,H1,NewH1),
4656 substitute_arguments(Head2,H2,NewH2),
4657 append(NewB,NewB_,NewBody),
4658 list2conj(NewBody,BodyMatchings),
4659 NewRule = pragma(rule(NewH1,NewH2,G,(BodyMatchings,B)),Ids,Pragmas,Name,RuleNb),
4660 (Head1 \== NewH1 ; Head2 \== NewH2 )
4662 rule(RuleNb,NewRule).
4664 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4665 % AUXILIARY PREDICATES (HEAD SIMPLIFICATION)
4666 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4668 replace_some_heads(H1,H2,NH,[],H1,H2,G,Body,[]) :- !.
4669 replace_some_heads([],[H2|RH2],[NH|RNH],[M|RM],[],[H2_|RH2_],G,Body,NewB) :- !,
4672 replace_some_heads([],RH2,RNH,RM,[],RH2_,G,Body,NewB)
4674 (M = functor(X,F,A), NH == X ->
4680 H2 =.. [F|OrigArgs],
4681 use_same_args(OrigArgs,A_args,A_args_,G,Body,NewB1),
4684 replace_some_heads([],RH2,RNH,RM,[],RH2_,G,Body,NewB2),
4685 append(NewB1,NewB2,NewB)
4688 replace_some_heads([],RH2,RNH,[M|RM],[],RH2_,G,Body,NewB)
4692 replace_some_heads([H1|RH1],H2,[NH|RNH],[M|RM],[H1_|RH1_],H2_,G,Body,NewB) :- !,
4695 replace_some_heads(RH1,H2,RNH,RM,RH1_,H2_,G,Body,NewB)
4697 (M = functor(X,F,A), NH == X ->
4703 H1 =.. [F|OrigArgs],
4704 use_same_args(OrigArgs,A_args,A_args_,G,Body,NewB1),
4707 replace_some_heads(RH1,H2,RNH,RM,RH1_,H2_,G,Body,NewB2),
4708 append(NewB1,NewB2,NewB)
4711 replace_some_heads(RH1,H2,RNH,[M|RM],RH1_,H2_,G,Body,NewB)
4715 use_same_args([],[],[],_,_,[]).
4716 use_same_args([OA|ROA],[NA|RNA],[Out|ROut],G,Body,NewB) :-
4719 use_same_args(ROA,RNA,ROut,G,Body,NewB).
4720 use_same_args([OA|ROA],[NA|RNA],[Out|ROut],G,Body,NewB) :-
4722 ( common_variables(OA,Body) ->
4723 NewB = [NA = OA|NextB]
4728 use_same_args(ROA,RNA,ROut,G,Body,NextB).
4731 simplify_heads([],_GuardList,_G,_Body,[],[]).
4732 simplify_heads([M|RM],GuardList,G,Body,NewM,NewB) :-
4734 ( (nonvar(B) ; common_variables(B,RM-GuardList)),
4735 guard_entailment:entails_guard(GuardList,(A=B)) ->
4736 ( common_variables(B,G-RM-GuardList) ->
4740 ( common_variables(B,Body) ->
4741 NewB = [A = B|NextB]
4748 ( nonvar(B), functor(B,BFu,BAr),
4749 guard_entailment:entails_guard([functor(A,BFu,BAr)|GuardList],(A=B)) ->
4751 ( common_variables(B,G-RM-GuardList) ->
4754 NewM = [functor(A,BFu,BAr)|NextM]
4761 simplify_heads(RM,[M|GuardList],G,Body,NextM,NextB).
4763 common_variables(B,G) :-
4764 term_variables(B,BVars),
4765 term_variables(G,GVars),
4766 intersect_eq(BVars,GVars,L),
4770 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4771 % ALWAYS FAILING GUARDS
4772 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4774 set_all_passive(RuleNb), occurrence(_,_,RuleNb,ID,_) ==> passive(RuleNb,ID).
4775 set_all_passive(_) <=> true.
4777 prev_guard_list(RuleNb,H,G,GuardList,M,[]),rule(RuleNb,Rule)
4779 chr_pp_flag(check_impossible_rules,on),
4780 Rule = pragma(rule(_,_,G,_),_Ids,_Pragmas,_Name,RuleNb),
4782 % writeq(guard_entailment:entails_guard(GL,fail)),nl,
4783 guard_entailment:entails_guard(GL,fail)
4785 chr_warning(weird_program,'Guard will always fail in ~@.\n\tThis rule will never fire!\n',[format_rule(Rule)]),
4786 set_all_passive(RuleNb).
4790 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4791 % OCCURRENCE SUBSUMPTION
4792 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4795 first_occ_in_rule/4,
4798 :- chr_option(mode,first_occ_in_rule(+,+,+,+)).
4799 :- chr_option(mode,next_occ_in_rule(+,+,+,+,+,+)).
4801 :- chr_constraint multiple_occ_constraints_checked/1.
4802 :- chr_option(mode,multiple_occ_constraints_checked(+)).
4804 prev_guard_list(RuleNb,H,G,GuardList,M,[]),
4805 occurrence(C,O,RuleNb,ID,_),
4806 occurrence(C,O2,RuleNb,ID2,_),
4809 multiple_occ_constraints_checked(Done)
4812 chr_pp_flag(occurrence_subsumption,on),
4813 Rule = pragma(rule(H1,H2,_G,_B),_Ids,_Pragmas,_Name,_RuleNb), % RuleNb == _RuleNb
4815 \+ memberchk_eq(C,Done)
4817 first_occ_in_rule(RuleNb,C,O,ID),
4818 multiple_occ_constraints_checked([C|Done]).
4820 % Find first occurrence of constraint =C= in rule =RuleNb=
4821 occurrence(C,O,RuleNb,ID,_) \ first_occ_in_rule(RuleNb,C,O2,_)
4825 first_occ_in_rule(RuleNb,C,O,ID).
4827 first_occ_in_rule(RuleNb,C,O,ID_o1)
4830 functor(FreshHead,F,A),
4831 next_occ_in_rule(RuleNb,C,O,ID_o1,[],FreshHead).
4833 % Skip passive occurrences.
4834 passive(RuleNb,ID_o2), occurrence(C,O2,RuleNb,ID_o2,_) \ next_occ_in_rule(RuleNb,C,O,ID_o1,Cond,FH)
4838 next_occ_in_rule(RuleNb,C,O2,ID_o1,NewCond,FH).
4840 prev_guard_list(RuleNb,H,G,GuardList,M,[]), occurrence(C,O2,RuleNb,ID_o2,_), rule(RuleNb,Rule) \ next_occ_in_rule(RuleNb,C,O,ID_o1,Cond,FH)
4843 Rule = pragma(rule(H1,H2,G,B),ids(ID1,ID2),_Pragmas,_Name,RuleNb)
4845 append(H1,H2,Heads),
4846 add_failing_occ(Rule,Heads,H,ID_o1,ExtraCond,FH,M,C,Repl),
4847 ( ExtraCond == [chr_pp_void_info] ->
4848 next_occ_in_rule(RuleNb,C,O2,ID_o2,Cond,FH)
4850 append(ExtraCond,Cond,NewCond),
4851 add_failing_occ(Rule,Heads,H,ID_o2,CheckCond,FH,M,C,Repl2),
4852 copy_term(GuardList,FGuardList),
4853 variable_replacement(GuardList,FGuardList,GLRepl),
4854 copy_with_variable_replacement(GuardList,GuardList2,Repl),
4855 copy_with_variable_replacement(GuardList,GuardList3_,Repl2),
4856 copy_with_variable_replacement(GuardList3_,GuardList3,GLRepl),
4857 append(NewCond,GuardList2,BigCond),
4858 append(BigCond,GuardList3,BigCond2),
4859 copy_with_variable_replacement(M,M2,Repl),
4860 copy_with_variable_replacement(M,M3,Repl2),
4861 append(M3,BigCond2,BigCond3),
4862 append([chr_pp_active_constraint(FH)|M2],BigCond3,Info),
4863 list2conj(CheckCond,OccSubsum),
4864 copy_term((NewCond,BigCond2,Info,OccSubsum,FH),(NewCond2,BigCond2_,Info2,OccSubsum2,FH2)),
4865 ( OccSubsum \= chr_pp_void_info ->
4866 ( guard_entailment:entails_guard(Info2,OccSubsum2) ->
4867 passive(RuleNb,ID_o2)
4874 next_occ_in_rule(RuleNb,C,O2,ID_o2,NewCond,FH)
4878 next_occ_in_rule(RuleNb,C,O,ID,Cond,Args)
4882 prev_guard_list(RuleNb,H,G,GuardList,M,[]), multiple_occ_constraints_checked(Done)
4886 add_failing_occ(Rule,Heads,NH,ID_o1,FailCond,FH,M,C,Repl) :-
4887 Rule = pragma(rule(H1,H2,G,B),ids(ID1,ID2),_Pragmas,_Name,RuleNb),
4888 append(ID2,ID1,IDs),
4889 missing_partner_cond(Heads,NH,IDs,ID_o1,MPCond,H,C),
4890 copy_term((H,Heads,NH),(FH2,FHeads,NH2)),
4891 variable_replacement((H,Heads,NH),(FH2,FHeads,NH2),Repl),
4892 copy_with_variable_replacement(G,FG,Repl),
4893 extract_explicit_matchings(FG,FG2),
4894 negate_b(FG2,NotFG),
4895 copy_with_variable_replacement(MPCond,FMPCond,Repl),
4896 ( safely_unifiable(FH,FH2), FH=FH2 ->
4897 FailCond = [(NotFG;FMPCond)]
4899 % in this case, not much can be done
4900 % e.g. c(f(...)), c(g(...)) <=> ...
4901 FailCond = [chr_pp_void_info]
4904 missing_partner_cond([],[],[],ID_o1,fail,H2,C).
4905 missing_partner_cond([H|Hs],[H2|H2s],[ID_o1|IDs],ID_o1,Cond,H,C) :- !,
4906 missing_partner_cond(Hs,H2s,IDs,ID_o1,Cond,H,C).
4907 missing_partner_cond([H|Hs],[NH|NHs],[ID|IDs],ID_o1,Cond,H2,F/A) :-
4908 Cond = (chr_pp_not_in_store(H);Cond1),
4909 missing_partner_cond(Hs,NHs,IDs,ID_o1,Cond1,H2,F/A).
4911 extract_explicit_matchings((A,B),D) :- !,
4912 ( extract_explicit_matchings(A) ->
4913 extract_explicit_matchings(B,D)
4916 extract_explicit_matchings(B,E)
4918 extract_explicit_matchings(A,D) :- !,
4919 ( extract_explicit_matchings(A) ->
4925 extract_explicit_matchings(A=B) :-
4926 var(A), var(B), !, A=B.
4927 extract_explicit_matchings(A==B) :-
4928 var(A), var(B), !, A=B.
4930 safely_unifiable(H,I) :- var(H), !.
4931 safely_unifiable([],[]) :- !.
4932 safely_unifiable([H|Hs],[I|Is]) :- !,
4933 safely_unifiable(H,I),
4934 safely_unifiable(Hs,Is).
4935 safely_unifiable(H,I) :-
4940 safely_unifiable(HA,IA).
4944 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4946 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4952 get_type_definition/2,
4953 get_constraint_type/2.
4956 :- chr_option(mode,type_definition(?,?)).
4957 :- chr_option(mode,get_type_definition(?,?)).
4958 :- chr_option(mode,type_alias(?,?)).
4959 :- chr_option(mode,constraint_type(+,+)).
4960 :- chr_option(mode,get_constraint_type(+,-)).
4962 assert_constraint_type(Constraint,ArgTypes) :-
4963 ( ground(ArgTypes) ->
4964 constraint_type(Constraint,ArgTypes)
4966 chr_error(type_error,'Declared argument types "~w" for constraint "~w" must be ground!\n',[ArgTypes,Constraint])
4969 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4970 % Consistency checks of type aliases
4972 type_alias(T,T2) <=>
4973 nonvar(T),nonvar(T2),functor(T,F,A),functor(T2,F,A),
4974 copy_term((T,T2),(X,Y)),oneway_unification(Y,X) |
4975 chr_error(type_error,'Cyclic alias definition: "~w".\n',[(T == T2)]).
4977 type_alias(T1,A1), type_alias(T2,A2) <=>
4978 nonvar(T1),nonvar(T2),functor(T1,F,A),functor(T2,F,A),
4980 copy_term_nat(T1,T1_),
4981 copy_term_nat(T2,T2_),
4983 chr_error(type_error,
4984 '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_]).
4986 type_alias(T,B) \ type_alias(X,T2) <=>
4987 nonvar(T),nonvar(T2),functor(T,F,A),functor(T2,F,A),
4988 copy_term_nat((X,T2,T,B),(X2,T3,T1,D1)),oneway_unification(T3,T1) |
4989 % chr_info(type_information,'Inferring `~w\' from `~w\' and `~w\'.\n',[X2==D1,X==T2,T==B]),
4992 oneway_unification(X,Y) :-
4993 term_variables(X,XVars),
4994 chr_runtime:lockv(XVars),
4996 chr_runtime:unlockv(XVars).
4998 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4999 % Consistency checks of type definitions
5001 type_definition(T1,_), type_definition(T2,_)
5003 functor(T1,F,A), functor(T2,F,A)
5005 chr_error(type_error,'Multiple definitions for type: ~w/~w.\n',[F,A]).
5007 type_definition(T1,_), type_alias(T2,_)
5009 functor(T1,F,A), functor(T2,F,A)
5011 chr_error(type_error,'Multiple definitions for type, once in a type definition and once as a type alias: ~w/~w.\n',[F,A]).
5013 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5014 %% get_type_definition(+Type,-Definition) is semidet.
5015 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5017 get_type_definition(T,Def)
5021 chr_error(type_error,'Non-ground type in constraint definition: "~w".\n',[T]).
5023 type_alias(T,D) \ get_type_definition(T2,Def)
5025 nonvar(T),nonvar(T2),functor(T,F,A),functor(T2,F,A),
5026 copy_term_nat((T,D),(T1,D1)),T1=T2
5028 ( get_type_definition(D1,Def) ->
5031 chr_error(type_error,'Could not find type definition for "~w" (accessed via alias "~w").\n',[D1,T1]), fail
5034 type_definition(T,D) \ get_type_definition(T2,Def)
5036 nonvar(T),nonvar(T2),functor(T,F,A),functor(T2,F,A),
5037 copy_term_nat((T,D),(T1,D1)),T1=T2
5041 get_type_definition(Type,Def)
5043 atomic_builtin_type(Type,_,_)
5047 get_type_definition(Type,Def)
5049 compound_builtin_type(Type,_,_)
5053 get_type_definition(X,Y) <=> fail.
5055 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5056 %% get_type_definition_det(+Type,-Definition) is det.
5057 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5058 get_type_definition_det(Type,Definition) :-
5059 ( get_type_definition(Type,Definition) ->
5062 chr_error(type,'Could not find type definition for type `~w\'.\n',[Type])
5065 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5066 %% get_constraint_type(+ConstraintSymbol,-Types) is semidet.
5068 % Return argument types of =ConstraintSymbol=, but fails if none where
5070 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5071 constraint_type(C,T) \ get_constraint_type(C,Type) <=> Type = T.
5072 get_constraint_type(_,_) <=> fail.
5074 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5075 %% get_constraint_type_det(+ConstraintSymbol,-Types) is det.
5077 % Like =get_constraint_type/2=, but returns list of =any= types when
5078 % no types are declared.
5079 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5080 get_constraint_type_det(ConstraintSymbol,Types) :-
5081 ( get_constraint_type(ConstraintSymbol,Types) ->
5084 ConstraintSymbol = _ / N,
5085 replicate(N,any,Types)
5087 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5088 %% unalias_type(+Alias,-Type) is det.
5090 % Follows alias chain until base type is reached.
5091 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5092 :- chr_constraint unalias_type/2.
5095 unalias_type(Alias,BaseType)
5102 type_alias(AliasProtoType,ProtoType) \ unalias_type(Alias,BaseType)
5104 nonvar(AliasProtoType),
5106 functor(AliasProtoType,F,A),
5108 copy_term_nat((AliasProtoType,ProtoType),(AliasInstance,Type)),
5109 Alias = AliasInstance
5111 unalias_type(Type,BaseType).
5113 unalias_type_definition @
5114 type_definition(ProtoType,Definition) \ unalias_type(Alias,BaseType)
5118 functor(ProtoType,F,A),
5123 unalias_atomic_builtin @
5124 unalias_type(Alias,BaseType)
5126 atomic_builtin_type(Alias,_,_)
5130 unalias_compound_builtin @
5131 unalias_type(Alias,BaseType)
5133 compound_builtin_type(Alias,_,_)
5137 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5138 %% types_modes_condition(+Heads,+UnrollHeads,-Condition) is det.
5139 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5140 :- chr_constraint types_modes_condition/3.
5141 :- chr_option(mode,types_modes_condition(+,+,?)).
5142 :- chr_option(type_declaration,types_modes_condition(list,list,goal)).
5144 types_modes_condition([],[],T) <=> T=true.
5146 constraint_mode(F/A,Modes) \ types_modes_condition([Head|Heads],[UnrollHead|UnrollHeads],Condition)
5151 Condition = (ModesCondition, TypesCondition, RestCondition),
5152 modes_condition(Modes,Args,ModesCondition),
5153 get_constraint_type_det(F/A,Types),
5154 UnrollHead =.. [_|RealArgs],
5155 types_condition(Types,Args,RealArgs,Modes,TypesCondition),
5156 types_modes_condition(Heads,UnrollHeads,RestCondition).
5158 types_modes_condition([Head|_],_,_)
5161 chr_error(internal,'Mode information missing for ~w.\n',[F/A]).
5164 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5165 %% modes_condition(+Modes,+Args,-Condition) is det.
5167 % Return =Condition= on =Args= that checks =Modes=.
5168 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5169 modes_condition([],[],true).
5170 modes_condition([Mode|Modes],[Arg|Args],Condition) :-
5172 Condition = ( ground(Arg) , RCondition )
5174 Condition = ( var(Arg) , RCondition )
5176 Condition = RCondition
5178 modes_condition(Modes,Args,RCondition).
5180 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5181 %% types_condition(+Types,+Args,+UnrollArgs,+Modes,-Condition) is det.
5183 % Return =Condition= on =Args= that checks =Types= given =Modes=.
5184 % =UnrollArgs= controls the depth of type definition unrolling.
5185 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5186 types_condition([],[],[],[],true).
5187 types_condition([Type|Types],[Arg|Args],[UnrollArg|UnrollArgs],[Mode|Modes],(DisjTypeConditionList,RCondition)) :-
5189 TypeConditionList = [true] % TypeConditionList = [var(Arg)] already encoded in modes_condition
5191 get_type_definition_det(Type,Def),
5192 type_condition(Def,Arg,UnrollArg,Mode,TypeConditionList1),
5194 TypeConditionList = TypeConditionList1
5196 TypeConditionList = [(\+ ground(Arg))|TypeConditionList1]
5199 list2disj(TypeConditionList,DisjTypeConditionList),
5200 types_condition(Types,Args,UnrollArgs,Modes,RCondition).
5202 type_condition([],_,_,_,[]).
5203 type_condition([DefCase|DefCases],Arg,UnrollArg,Mode,[Condition|Conditions]) :-
5205 chr_error(type,'Unexpected variable type in type definition!\n',[]) % Condition = true
5206 ; atomic_builtin_type(DefCase,Arg,Condition) ->
5208 ; compound_builtin_type(DefCase,Arg,Condition) ->
5211 type_def_case_condition(DefCase,Arg,UnrollArg,Mode,Condition)
5213 type_condition(DefCases,Arg,UnrollArg,Mode,Conditions).
5215 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5216 :- chr_type atomic_builtin_type ---> any
5223 ; chr_identifier(any).
5224 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5226 atomic_builtin_type(any,_Arg,true).
5227 atomic_builtin_type(dense_int,Arg,(integer(Arg),Arg>=0)).
5228 atomic_builtin_type(int,Arg,integer(Arg)).
5229 atomic_builtin_type(number,Arg,number(Arg)).
5230 atomic_builtin_type(float,Arg,float(Arg)).
5231 atomic_builtin_type(natural,Arg,(integer(Arg),Arg>=0)).
5232 atomic_builtin_type(chr_identifier,_Arg,true).
5234 compound_builtin_type(chr_identifier(_),_Arg,true).
5236 type_def_case_condition(DefCase,Arg,UnrollArg,Mode,Condition) :-
5237 ( nonvar(DefCase) ->
5238 functor(DefCase,F,A),
5240 Condition = (Arg = DefCase)
5242 Condition = functor(Arg,F,A)
5243 ; functor(UnrollArg,F,A) ->
5244 Condition = (functor(Arg,F,A),Arg=Template,ArgsCondition),
5245 DefCase =.. [_|ArgTypes],
5246 UnrollArg =.. [_|UnrollArgs],
5247 functor(Template,F,A),
5248 Template =.. [_|TemplateArgs],
5249 replicate(A,Mode,ArgModes),
5250 types_condition(ArgTypes,TemplateArgs,UnrollArgs,ArgModes,ArgsCondition)
5252 Condition = functor(Arg,F,A)
5255 chr_error(internal,'Illegal type definition (must be nonvar).\n',[])
5259 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5260 % STATIC TYPE CHECKING
5261 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5262 % Checks head constraints and CHR constraint calls in bodies.
5265 % - type clashes involving built-in types
5266 % - Prolog built-ins in guard and body
5267 % - indicate position in terms in error messages
5268 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5270 static_type_check/0.
5273 % 1. Check the declared types
5275 constraint_type(Constraint,ArgTypes), static_type_check
5278 ( member(ArgType,ArgTypes), forsubterm(ArgType,Type) ),
5279 ( get_type_definition(Type,_) ->
5282 chr_error(type_error,'Undefined type "~w" used in type declaration of "~w".\n',[Type,Constraint])
5287 forsubterm(Term,SubTerm) :-
5293 forsubterm(Arg,SubTerm)
5297 % 2. Check the rules
5299 :- chr_type type_error_src ---> head(any) ; body(any).
5301 rule(_,Rule), static_type_check
5303 copy_term_nat(Rule,RuleCopy),
5304 RuleCopy = pragma(rule(Head1,Head2,G,Body),ids(IDs1,IDs2),Pragmas,Name,RuleNb),
5307 ( static_type_check_heads(Head1),
5308 static_type_check_heads(Head2),
5309 conj2list(Body,GoalList),
5310 static_type_check_body(GoalList)
5313 ( Error = invalid_functor(Src,Term,Type) ->
5314 chr_error(type_error,'Invalid functor in ~@ of ~@:\n\t\tfound `~w\',\n\t\texpected type `~w\'!\n',
5315 [chr_translate:format_src(Src),format_rule(Rule),Term,Type])
5316 ; Error = type_clash(Var,Src1,Src2,Type1,Type2) ->
5317 chr_error(type_error,'Type clash for variable ~w in ~@:\n\t\texpected type ~w in ~@\n\t\texpected type ~w in ~@\n',
5318 [Var,format_rule(Rule),Type1,chr_translate:format_src(Src1),Type2,chr_translate:format_src(Src2)])
5321 fail % cleanup constraints
5327 static_type_check <=> true.
5329 static_type_check_heads([]).
5330 static_type_check_heads([Head|Heads]) :-
5331 static_type_check_head(Head),
5332 static_type_check_heads(Heads).
5334 static_type_check_head(Head) :-
5336 get_constraint_type_det(F/A,Types),
5338 maplist(static_type_check_term(head(Head)),Args,Types).
5340 static_type_check_body([]).
5341 static_type_check_body([Goal|Goals]) :-
5343 get_constraint_type_det(F/A,Types),
5345 maplist(static_type_check_term(body(Goal)),Args,Types),
5346 static_type_check_body(Goals).
5348 :- chr_constraint static_type_check_term/3.
5349 :- chr_option(mode,static_type_check_term(?,?,?)).
5350 :- chr_option(type_declaration,static_type_check_term(type_error_src,any,any)).
5352 static_type_check_term(Src,Term,Type)
5356 static_type_check_var(Src,Term,Type).
5357 static_type_check_term(Src,Term,Type)
5359 atomic_builtin_type(Type,Term,Goal)
5364 throw(type_error(invalid_functor(Src,Term,Type)))
5366 static_type_check_term(Src,Term,Type)
5368 compound_builtin_type(Type,Term,Goal)
5373 throw(type_error(invalid_functor(Src,Term,Type)))
5375 type_alias(AType,ADef) \ static_type_check_term(Src,Term,Type)
5380 copy_term_nat(AType-ADef,Type-Def),
5381 static_type_check_term(Src,Term,Def).
5383 type_definition(AType,ADef) \ static_type_check_term(Src,Term,Type)
5388 copy_term_nat(AType-ADef,Type-Variants),
5389 functor(Term,TF,TA),
5390 ( member(Variant,Variants), functor(Variant,TF,TA) ->
5392 Variant =.. [_|Types],
5393 maplist(static_type_check_term(Src),Args,Types)
5395 throw(type_error(invalid_functor(Src,Term,Type)))
5398 static_type_check_term(Src,Term,Type)
5400 chr_error(internal,'Undefined type ~w while type checking term ~w in ~@.\n',[Type,Term,chr_translate:format_src(Src)]).
5402 :- chr_constraint static_type_check_var/3.
5403 :- chr_option(mode,static_type_check_var(?,-,?)).
5404 :- chr_option(type_declaration,static_type_check_term(type_error_src,any,any)).
5406 type_alias(AType,ADef) \ static_type_check_var(Src,Var,Type)
5411 copy_term_nat(AType-ADef,Type-Def),
5412 static_type_check_var(Src,Var,Def).
5414 static_type_check_var(Src,Var,Type)
5416 atomic_builtin_type(Type,_,_)
5418 static_atomic_builtin_type_check_var(Src,Var,Type).
5420 static_type_check_var(Src,Var,Type)
5422 compound_builtin_type(Type,_,_)
5427 static_type_check_var(Src1,Var,Type1), static_type_check_var(Src2,Var,Type2)
5431 throw(type_error(type_clash(Var,Src1,Src2,Type1,Type2))).
5433 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5434 %% static_atomic_builtin_type_check_var(+type_error_src,-Var,+atomic_builtin_type)
5435 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5436 :- chr_constraint static_atomic_builtin_type_check_var/3.
5437 :- chr_option(mode,static_type_check_var(?,-,+)).
5438 :- chr_option(type_declaration,static_type_check_term(type_error_src,any,atomic_builtin_type)).
5440 static_atomic_builtin_type_check_var(_,_,any) <=> true.
5441 static_atomic_builtin_type_check_var(_,Var,BuiltinType) \ static_atomic_builtin_type_check_var(_,Var,BuiltinType)
5444 static_atomic_builtin_type_check_var(_,Var,float) \ static_atomic_builtin_type_check_var(_,Var,number)
5447 static_atomic_builtin_type_check_var(_,Var,int) \ static_atomic_builtin_type_check_var(_,Var,number)
5450 static_atomic_builtin_type_check_var(_,Var,natural) \ static_atomic_builtin_type_check_var(_,Var,number)
5453 static_atomic_builtin_type_check_var(_,Var,dense_int) \ static_atomic_builtin_type_check_var(_,Var,number)
5456 static_atomic_builtin_type_check_var(_,Var,natural) \ static_atomic_builtin_type_check_var(_,Var,int)
5459 static_atomic_builtin_type_check_var(_,Var,dense_int) \ static_atomic_builtin_type_check_var(_,Var,int)
5462 static_atomic_builtin_type_check_var(_,Var,dense_int) \ static_atomic_builtin_type_check_var(_,Var,natural)
5465 static_atomic_builtin_type_check_var(Src1,Var,Type1), static_atomic_builtin_type_check_var(Src2,Var,Type2)
5467 throw(type_error(type_clash(Var,Src1,Src2,Type1,Type2))).
5469 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5470 %% format_src(+type_error_src) is det.
5471 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5472 format_src(head(Head)) :- format('head ~w',[Head]).
5473 format_src(body(Goal)) :- format('body goal ~w',[Goal]).
5475 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5476 % Dynamic type checking
5477 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5480 dynamic_type_check/0,
5481 dynamic_type_check_clauses/1,
5482 get_dynamic_type_check_clauses/1.
5484 generate_dynamic_type_check_clauses(Clauses) :-
5485 ( chr_pp_flag(debugable,on) ->
5487 get_dynamic_type_check_clauses(Clauses0),
5489 [('$dynamic_type_check'(Type,Term) :-
5490 throw(error(type_error(Type,Term),context(_,'CHR Runtime Type Error')))
5497 type_definition(T,D), dynamic_type_check
5499 copy_term_nat(T-D,Type-Definition),
5500 maplist(dynamic_type_check_clause(Type),Definition,DynamicChecks),
5501 dynamic_type_check_clauses(DynamicChecks).
5502 type_alias(A,B), dynamic_type_check
5504 copy_term_nat(A-B,Alias-Body),
5505 dynamic_type_check_alias_clause(Alias,Body,Clause),
5506 dynamic_type_check_clauses([Clause]).
5508 dynamic_type_check <=>
5510 ('$dynamic_type_check'(Type,Term) :- Goal),
5511 ( atomic_builtin_type(Type,Term,Goal) ; compound_builtin_type(Type,Term,Goal) ),
5514 dynamic_type_check_clauses(BuiltinChecks).
5516 dynamic_type_check_clause(T,DC,Clause) :-
5517 copy_term(T-DC,Type-DefinitionClause),
5518 functor(DefinitionClause,F,A),
5520 DefinitionClause =.. [_|DCArgs],
5521 Term =.. [_|TermArgs],
5522 maplist(dynamic_type_check_call,DCArgs,TermArgs,RecursiveCallList),
5523 list2conj(RecursiveCallList,RecursiveCalls),
5525 '$dynamic_type_check'(Type,Term) :-
5529 dynamic_type_check_alias_clause(Alias,Body,Clause) :-
5531 '$dynamic_type_check'(Alias,Term) :-
5532 '$dynamic_type_check'(Body,Term)
5535 dynamic_type_check_call(Type,Term,Call) :-
5536 % ( nonvar(Type), atomic_builtin_type(Type,Term,Goal) ->
5537 % Call = when(nonvar(Term),Goal)
5538 % ; nonvar(Type), compound_builtin_type(Type,Term,Goal) ->
5539 % Call = when(nonvar(Term),Goal)
5544 Call = when(nonvar(Term),once('$dynamic_type_check'(Type,Term)))
5549 dynamic_type_check_clauses(C1), dynamic_type_check_clauses(C2)
5552 dynamic_type_check_clauses(C).
5554 get_dynamic_type_check_clauses(Q), dynamic_type_check_clauses(C)
5557 get_dynamic_type_check_clauses(Q)
5561 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5563 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5564 % Some optimizations can be applied for atomic types...
5565 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5567 atomic_types_suspended_constraint(C) :-
5569 get_constraint_type(C,ArgTypes),
5570 get_constraint_mode(C,ArgModes),
5571 findall(I,between(1,N,I),Indexes),
5572 maplist(atomic_types_suspended_constraint(C),ArgTypes,ArgModes,Indexes).
5574 atomic_types_suspended_constraint(C,Type,Mode,Index) :-
5575 ( is_indexed_argument(C,Index) ->
5585 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5586 %% atomic_type(+Type) is semidet.
5588 % Succeeds when all values of =Type= are atomic.
5589 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5590 :- chr_constraint atomic_type/1.
5592 atomic_type(Type) <=> atomic_builtin_type(Type,_,_) | Type \== any.
5594 type_definition(TypePat,Def) \ atomic_type(Type)
5596 functor(Type,F,A), functor(TypePat,F,A)
5598 forall(member(Term,Def),atomic(Term)).
5600 type_alias(TypePat,Alias) \ atomic_type(Type)
5602 functor(Type,F,A), functor(TypePat,F,A)
5605 copy_term_nat(TypePat-Alias,Type-NType),
5608 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5609 %% enumerated_atomic_type(+Type,-Atoms) is semidet.
5611 % Succeeds when all values of =Type= are atomic
5612 % and the atom values are finitely enumerable.
5613 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5614 :- chr_constraint enumerated_atomic_type/2.
5616 enumerated_atomic_type(Type,_) <=> atomic_builtin_type(Type,_,_) | fail.
5618 type_definition(TypePat,Def) \ enumerated_atomic_type(Type,Atoms)
5620 functor(Type,F,A), functor(TypePat,F,A)
5622 forall(member(Term,Def),atomic(Term)),
5625 type_alias(TypePat,Alias) \ enumerated_atomic_type(Type,Atoms)
5627 functor(Type,F,A), functor(TypePat,F,A)
5630 copy_term_nat(TypePat-Alias,Type-NType),
5631 enumerated_atomic_type(NType,Atoms).
5632 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5635 stored/3, % constraint,occurrence,(yes/no/maybe)
5636 stored_completing/3,
5639 is_finally_stored/1,
5640 check_all_passive/2.
5642 :- chr_option(mode,stored(+,+,+)).
5643 :- chr_option(type_declaration,stored(any,int,storedinfo)).
5644 :- chr_type storedinfo ---> yes ; no ; maybe.
5645 :- chr_option(mode,stored_complete(+,+,+)).
5646 :- chr_option(mode,maybe_complementary_guards(+,+,?,?)).
5647 :- chr_option(mode,guard_list(+,+,+,+)).
5648 :- chr_option(mode,check_all_passive(+,+)).
5649 :- chr_option(type_declaration,check_all_passive(any,list)).
5651 % change yes in maybe when yes becomes passive
5652 passive(RuleNb,ID), occurrence(C,O,RuleNb,ID,_) \
5653 stored(C,O,yes), stored_complete(C,RO,Yesses)
5654 <=> O < RO | NYesses is Yesses - 1,
5655 stored(C,O,maybe), stored_complete(C,RO,NYesses).
5656 % change yes in maybe when not observed
5657 ai_not_observed(C,O) \ stored(C,O,yes), stored_complete(C,RO,Yesses)
5659 NYesses is Yesses - 1,
5660 stored(C,O,maybe), stored_complete(C,RO,NYesses).
5662 occurrence(_,_,RuleNb,ID,_), occurrence(C2,_,RuleNb,_,_), stored_complete(C2,RO,0), max_occurrence(C2,MO2)
5663 ==> RO =< MO2 | % C2 is never stored
5669 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5671 rule(RuleNb,Rule),passive(RuleNb,Id) ==>
5672 Rule = pragma(rule(Head1,Head2,G,B),ids([Id|IDs1],IDs2),Pragmas,Name,RuleNb) |
5673 append(IDs1,IDs2,I), check_all_passive(RuleNb,I).
5675 rule(RuleNb,Rule),passive(RuleNb,Id) ==>
5676 Rule = pragma(rule(Head1,Head2,G,B),ids([],[Id|IDs2]),Pragmas,Name,RuleNb) |
5677 check_all_passive(RuleNb,IDs2).
5679 passive(RuleNb,Id) \ check_all_passive(RuleNb,[Id|IDs]) <=>
5680 check_all_passive(RuleNb,IDs).
5682 rule(RuleNb,Rule) \ check_all_passive(RuleNb,[]) <=>
5683 chr_warning(weird_program,'All heads passive in ~@.\n\tThis rule never fires. Please check your program.\n',[format_rule(Rule)]).
5685 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5687 % collect the storage information
5688 stored(C,O,yes) \ stored_completing(C,O,Yesses)
5689 <=> NO is O + 1, NYesses is Yesses + 1,
5690 stored_completing(C,NO,NYesses).
5691 stored(C,O,maybe) \ stored_completing(C,O,Yesses)
5693 stored_completing(C,NO,Yesses).
5695 stored(C,O,no) \ stored_completing(C,O,Yesses)
5696 <=> stored_complete(C,O,Yesses).
5697 stored_completing(C,O,Yesses)
5698 <=> stored_complete(C,O,Yesses).
5700 stored_complete(C,O,Yesses), occurrence(C,O2,RuleNb,Id,_) ==>
5701 O2 > O | passive(RuleNb,Id).
5703 % decide whether a constraint is stored
5704 max_occurrence(C,MO), stored_complete(C,RO,0) \ is_stored(C)
5705 <=> RO =< MO | fail.
5706 is_stored(C) <=> true.
5708 % decide whether a constraint is suspends after occurrences
5709 max_occurrence(C,MO), stored_complete(C,RO,_) \ is_finally_stored(C)
5710 <=> RO =< MO | fail.
5711 is_finally_stored(C) <=> true.
5713 storage_analysis(Constraints) :-
5714 ( chr_pp_flag(storage_analysis,on) ->
5715 check_constraint_storages(Constraints)
5720 check_constraint_storages([]).
5721 check_constraint_storages([C|Cs]) :-
5722 check_constraint_storage(C),
5723 check_constraint_storages(Cs).
5725 check_constraint_storage(C) :-
5726 get_max_occurrence(C,MO),
5727 check_occurrences_storage(C,1,MO).
5729 check_occurrences_storage(C,O,MO) :-
5731 stored_completing(C,1,0)
5733 check_occurrence_storage(C,O),
5735 check_occurrences_storage(C,NO,MO)
5738 check_occurrence_storage(C,O) :-
5739 get_occurrence(C,O,RuleNb,ID),
5740 ( is_passive(RuleNb,ID) ->
5743 get_rule(RuleNb,PragmaRule),
5744 PragmaRule = pragma(rule(Heads1,Heads2,Guard,Body),ids(IDs1,IDs2),_,_,_),
5745 ( select2(ID,Head1,IDs1,Heads1,RIDs1,RHeads1) ->
5746 check_storage_head1(Head1,O,Heads1,Heads2,Guard)
5747 ; select2(ID,Head2,IDs2,Heads2,RIDs2,RHeads2) ->
5748 check_storage_head2(Head2,O,Heads1,Body)
5752 check_storage_head1(Head,O,H1,H2,G) :-
5757 % writeq(guard_entailment:entails_guard([chr_pp_headvariables(Head)],G)),nl,
5758 guard_entailment:entails_guard([chr_pp_headvariables(Head)],G),
5760 no_matching(L,[]) ->
5767 no_matching([X|Xs],Prev) :-
5769 \+ memberchk_eq(X,Prev),
5770 no_matching(Xs,[X|Prev]).
5772 check_storage_head2(Head,O,H1,B) :-
5776 ( H1 \== [], B == true )
5778 % \+ is_observed(F/A,O) % always fails because observation analysis has not been performed yet
5786 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5788 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5789 %% ____ _ ____ _ _ _ _
5790 %% | _ \ _ _| | ___ / ___|___ _ __ ___ _ __ (_) | __ _| |_(_) ___ _ __
5791 %% | |_) | | | | |/ _ \ | | / _ \| '_ ` _ \| '_ \| | |/ _` | __| |/ _ \| '_ \
5792 %% | _ <| |_| | | __/ | |__| (_) | | | | | | |_) | | | (_| | |_| | (_) | | | |
5793 %% |_| \_\\__,_|_|\___| \____\___/|_| |_| |_| .__/|_|_|\__,_|\__|_|\___/|_| |_|
5796 constraints_code(Constraints,Clauses) :-
5797 (chr_pp_flag(reduced_indexing,on),
5798 \+ forsome(C,Constraints,\+ chr_translate:only_ground_indexed_arguments(C)) ->
5799 none_suspended_on_variables
5803 constraints_code1(Constraints,Clauses,[]).
5805 %===============================================================================
5806 :- chr_constraint constraints_code1/3.
5807 :- chr_option(mode,constraints_code1(+,+,+)).
5808 :- chr_option(type_declaration,constraints_code1(list,any,any)).
5809 %-------------------------------------------------------------------------------
5810 constraints_code1([],L,T) <=> L = T.
5811 constraints_code1([C|RCs],L,T)
5813 constraint_code(C,L,T1),
5814 constraints_code1(RCs,T1,T).
5815 %===============================================================================
5816 :- chr_constraint constraint_code/3.
5817 :- chr_option(mode,constraint_code(+,+,+)).
5818 %-------------------------------------------------------------------------------
5819 %% Generate code for a single CHR constraint
5820 constraint_code(Constraint, L, T)
5822 | ( (chr_pp_flag(debugable,on) ;
5823 is_stored(Constraint), ( has_active_occurrence(Constraint); chr_pp_flag(late_allocation,off)),
5824 ( may_trigger(Constraint) ;
5825 get_allocation_occurrence(Constraint,AO),
5826 get_max_occurrence(Constraint,MO), MO >= AO ) )
5828 constraint_prelude(Constraint,Clause),
5829 add_dummy_location(Clause,LocatedClause),
5830 L = [LocatedClause | L1]
5835 occurrences_code(Constraint,1,Id,NId,L1,L2),
5836 gen_cond_attach_clause(Constraint,NId,L2,T).
5838 %===============================================================================
5839 %% Generate prelude predicate for a constraint.
5840 %% f(...) :- f/a_0(...,Susp).
5841 constraint_prelude(F/A, Clause) :-
5842 vars_susp(A,Vars,Susp,VarsSusp),
5843 Head =.. [ F | Vars],
5844 make_suspension_continuation_goal(F/A,VarsSusp,Continuation),
5845 build_head(F,A,[0],VarsSusp,Delegate),
5846 ( chr_pp_flag(debugable,on) ->
5847 insert_constraint_goal(F/A,Susp,Vars,InsertCall),
5848 attach_constraint_atom(F/A,Vars2,Susp,AttachCall),
5849 delay_phase_end(validate_store_type_assumptions,chr_translate:update_suspension_field(F/A,Susp,state,inactive,Inactive)),
5850 insert_constraint_internal_constraint_goal(F/A, Vars2, Susp, Continuation, Vars,InsertGoal),
5852 ( get_constraint_type(F/A,ArgTypeList) ->
5853 maplist(dynamic_type_check_call,ArgTypeList,Vars,DynamicTypeCheckList),
5854 list2conj(DynamicTypeCheckList,DynamicTypeChecks)
5856 DynamicTypeChecks = true
5866 'chr debug_event'(insert(Head#Susp)),
5868 'chr debug_event'(call(Susp)),
5871 'chr debug_event'(fail(Susp)), !,
5875 'chr debug_event'(exit(Susp))
5877 'chr debug_event'(redo(Susp)),
5881 ; get_allocation_occurrence(F/A,0) ->
5882 gen_insert_constraint_internal_goal(F/A,Goal,VarsSusp,Vars,Susp),
5883 delay_phase_end(validate_store_type_assumptions,chr_translate:update_suspension_field(F/A,Susp,state,inactive,Inactive)),
5884 Clause = ( Head :- Goal, Inactive, Delegate )
5886 Clause = ( Head :- Delegate )
5889 make_suspension_continuation_goal(F/A,VarsSusp,Goal) :-
5890 ( may_trigger(F/A) ->
5891 build_head(F,A,[0],VarsSusp,Delegate),
5892 ( chr_pp_flag(debugable,off) ->
5895 get_target_module(Mod),
5902 %===============================================================================
5903 :- chr_constraint has_active_occurrence/1, has_active_occurrence/2.
5904 :- chr_option(mode,has_active_occurrence(+)).
5905 :- chr_option(mode,has_active_occurrence(+,+)).
5906 %-------------------------------------------------------------------------------
5907 has_active_occurrence(C) <=> has_active_occurrence(C,1).
5909 max_occurrence(C,MO) \ has_active_occurrence(C,O) <=>
5911 passive(RuleNb,ID),occurrence(C,O,RuleNb,ID,_) \
5912 has_active_occurrence(C,O) <=>
5914 has_active_occurrence(C,NO).
5915 has_active_occurrence(C,O) <=> true.
5916 %===============================================================================
5918 gen_cond_attach_clause(F/A,Id,L,T) :-
5919 ( is_finally_stored(F/A) ->
5920 get_allocation_occurrence(F/A,AllocationOccurrence),
5921 get_max_occurrence(F/A,MaxOccurrence),
5922 ( chr_pp_flag(debugable,off), MaxOccurrence < AllocationOccurrence ->
5923 ( only_ground_indexed_arguments(F/A) ->
5924 gen_insert_constraint_internal_goal(F/A,Body,AllArgs,Args,Susp)
5926 gen_cond_attach_goal(F/A,Body,AllArgs,Args,Susp)
5928 ; vars_susp(A,Args,Susp,AllArgs),
5929 gen_uncond_attach_goal(F/A,Susp,Args,Body,_)
5931 build_head(F,A,Id,AllArgs,Head),
5932 Clause = ( Head :- Body ),
5933 add_dummy_location(Clause,LocatedClause),
5934 L = [LocatedClause | T]
5939 :- chr_constraint use_auxiliary_predicate/1.
5940 :- chr_option(mode,use_auxiliary_predicate(+)).
5942 :- chr_constraint use_auxiliary_predicate/2.
5943 :- chr_option(mode,use_auxiliary_predicate(+,+)).
5945 :- chr_constraint is_used_auxiliary_predicate/1.
5946 :- chr_option(mode,is_used_auxiliary_predicate(+)).
5948 :- chr_constraint is_used_auxiliary_predicate/2.
5949 :- chr_option(mode,is_used_auxiliary_predicate(+,+)).
5952 use_auxiliary_predicate(P) \ use_auxiliary_predicate(P) <=> true.
5954 use_auxiliary_predicate(P,C) \ use_auxiliary_predicate(P,C) <=> true.
5956 use_auxiliary_predicate(P) \ is_used_auxiliary_predicate(P) <=> true.
5958 use_auxiliary_predicate(P,_) \ is_used_auxiliary_predicate(P) <=> true.
5960 is_used_auxiliary_predicate(P) <=> fail.
5962 use_auxiliary_predicate(P) \ is_used_auxiliary_predicate(P,_) <=> true.
5963 use_auxiliary_predicate(P,C) \ is_used_auxiliary_predicate(P,C) <=> true.
5965 is_used_auxiliary_predicate(P,C) <=> fail.
5967 %------------------------------------------------------------------------------%
5968 % Only generate import statements for actually used modules.
5969 %------------------------------------------------------------------------------%
5971 :- chr_constraint use_auxiliary_module/1.
5972 :- chr_option(mode,use_auxiliary_module(+)).
5974 :- chr_constraint is_used_auxiliary_module/1.
5975 :- chr_option(mode,is_used_auxiliary_module(+)).
5978 use_auxiliary_module(P) \ use_auxiliary_module(P) <=> true.
5980 use_auxiliary_module(P) \ is_used_auxiliary_module(P) <=> true.
5982 is_used_auxiliary_module(P) <=> fail.
5984 % only called for constraints with
5986 % non-ground indexed argument
5987 gen_cond_attach_goal(F/A,Goal,AllArgs,Args,Susp) :-
5988 vars_susp(A,Args,Susp,AllArgs),
5989 make_suspension_continuation_goal(F/A,AllArgs,Closure),
5990 ( get_store_type(F/A,var_assoc_store(_,_)) ->
5993 attach_constraint_atom(F/A,Vars,Susp,Attach)
5996 insert_constraint_goal(F/A,Susp,Args,InsertCall),
5997 insert_constraint_internal_constraint_goal(F/A, Vars, Susp, Closure, Args,InsertGoal),
5998 ( may_trigger(F/A) ->
5999 activate_constraint_goal(F/A,(InsertCall,Attach),Vars,Susp,_,ActivateGoal),
6003 InsertGoal, % insert_constraint_internal(Stored,Vars,Susp,Closure,F,Args)
6007 ActivateGoal % activate_constraint(Stored,Vars,Susp,_)
6013 InsertGoal, % insert_constraint_internal(Stored,Vars,Susp,Closure,F,Args),
6019 gen_insert_constraint_internal_goal(F/A,Goal,AllArgs,Args,Susp) :-
6020 vars_susp(A,Args,Susp,AllArgs),
6021 make_suspension_continuation_goal(F/A,AllArgs,Cont),
6022 ( \+ only_ground_indexed_arguments(F/A), \+ get_store_type(F/A,var_assoc_store(_,_)) ->
6023 attach_constraint_atom(F/A,Vars,Susp,Attach)
6028 insert_constraint_goal(F/A,Susp,Args,InsertCall),
6029 insert_constraint_internal_constraint_goal(F/A, Vars, Susp, Cont, Args,InsertInternalGoal),
6030 ( only_ground_indexed_arguments(F/A), chr_pp_flag(debugable,off) ->
6033 InsertInternalGoal, % insert_constraint_internal(Susp,F,Args),
6039 InsertInternalGoal, % insert_constraint_internal(_,Vars,Susp,Cont,F,Args),
6045 gen_uncond_attach_goal(FA,Susp,Args,AttachGoal,Generation) :-
6046 ( \+ only_ground_indexed_arguments(FA), \+ get_store_type(FA,var_assoc_store(_,_)) ->
6047 attach_constraint_atom(FA,Vars,Susp,Attach)
6051 insert_constraint_goal(FA,Susp,Args,InsertCall),
6052 ( chr_pp_flag(late_allocation,on) ->
6053 activate_constraint_goal(FA,(InsertCall,Attach),Vars,Susp,Generation,AttachGoal)
6055 activate_constraint_goal(FA,true,Vars,Susp,Generation,AttachGoal)
6058 %-------------------------------------------------------------------------------
6059 :- chr_constraint occurrences_code/6.
6060 :- chr_option(mode,occurrences_code(+,+,+,+,+,+)).
6061 %-------------------------------------------------------------------------------
6062 max_occurrence(C,MO) \ occurrences_code(C,O,Id,NId,L,T)
6065 occurrences_code(C,O,Id,NId,L,T)
6067 occurrence_code(C,O,Id,Id1,L,L1),
6069 occurrences_code(C,NO,Id1,NId,L1,T).
6070 %-------------------------------------------------------------------------------
6071 :- chr_constraint occurrence_code/6.
6072 :- chr_option(mode,occurrence_code(+,+,+,+,+,+)).
6073 %-------------------------------------------------------------------------------
6074 occurrence(C,O,RuleNb,ID,_), passive(RuleNb,ID) \ occurrence_code(C,O,Id,NId,L,T)
6076 ( named_history(RuleNb,_,_) ->
6077 does_use_history(C,O)
6083 occurrence(C,O,RuleNb,ID,_), rule(RuleNb,PragmaRule) \ occurrence_code(C,O,Id,NId,L,T)
6085 PragmaRule = pragma(rule(Heads1,Heads2,_,_),ids(IDs1,IDs2),_,_,_),
6086 ( select2(ID,Head1,IDs1,Heads1,RIDs1,RHeads1) ->
6088 head1_code(Head1,ID,RHeads1,RIDs1,PragmaRule,C,O,Id,L,T)
6089 ; select2(ID,Head2,IDs2,Heads2,RIDs2,RHeads2) ->
6090 head2_code(Head2,ID,RHeads2,RIDs2,PragmaRule,C,O,Id,L,L1),
6091 ( should_skip_to_next_id(C,O) ->
6093 ( unconditional_occurrence(C,O) ->
6096 gen_alloc_inc_clause(C,O,Id,L1,T)
6104 occurrence_code(C,O,_,_,_,_)
6106 chr_error(internal,'occurrence_code/6: missing information to compile ~w:~w\n',[C,O]).
6107 %-------------------------------------------------------------------------------
6109 %% Generate code based on one removed head of a CHR rule
6110 head1_code(Head,ID,OtherHeads,OtherIDs,PragmaRule,FA,O,Id,L,T) :-
6111 PragmaRule = pragma(Rule,_,_,_Name,RuleNb),
6112 Rule = rule(_,Head2,_,_),
6114 reorder_heads(RuleNb,Head,OtherHeads,OtherIDs,NOtherHeads,NOtherIDs),
6115 simplification_code(Head,ID,NOtherHeads,NOtherIDs,PragmaRule,FA,O,Id,L,T)
6117 simpagation_head1_code(Head,ID,OtherHeads,OtherIDs,PragmaRule,FA,O,Id,L,T)
6120 %% Generate code based on one persistent head of a CHR rule
6121 head2_code(Head,ID,OtherHeads,OtherIDs,PragmaRule,FA,O,Id,L,T) :-
6122 PragmaRule = pragma(Rule,_,_,_Name,RuleNb),
6123 Rule = rule(Head1,_,_,_),
6125 reorder_heads(RuleNb,Head,OtherHeads,OtherIDs,NOtherHeads,NOtherIDs),
6126 propagation_code(Head,ID,NOtherHeads,NOtherIDs,Rule,RuleNb,FA,O,Id,L,T)
6128 simpagation_head2_code(Head,ID,OtherHeads,OtherIDs,PragmaRule,FA,O,Id,L,T)
6131 gen_alloc_inc_clause(F/A,O,Id,L,T) :-
6132 vars_susp(A,Vars,Susp,VarsSusp),
6133 build_head(F,A,Id,VarsSusp,Head),
6135 build_head(F,A,IncId,VarsSusp,CallHead),
6136 gen_occ_allocation(F/A,O,Vars,Susp,ConditionalAlloc),
6143 add_dummy_location(Clause,LocatedClause),
6144 L = [LocatedClause|T].
6146 gen_occ_allocation(FA,O,Vars,Susp,Goal) :-
6147 get_allocation_occurrence(FA,AO),
6148 ( chr_pp_flag(debugable,off), O == AO ->
6149 allocate_constraint_goal(FA,Susp,Vars,Goal0),
6150 ( may_trigger(FA) ->
6151 Goal = (var(Susp) -> Goal0 ; true)
6159 gen_occ_allocation_in_guard(FA,O,Vars,Susp,Goal) :-
6160 get_allocation_occurrence(FA,AO),
6161 ( chr_pp_flag(debugable,off), O < AO ->
6162 allocate_constraint_goal(FA,Susp,Vars,Goal0),
6163 ( may_trigger(FA) ->
6164 Goal = (var(Susp) -> Goal0 ; true)
6172 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6174 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6176 % Reorders guard goals with respect to partner constraint retrieval goals and
6177 % active constraint. Returns combined partner retrieval + guard goal.
6179 guard_via_reschedule_new(Retrievals,GuardList,Prelude,GuardListSkeleton,LookupSkeleton,GoalSkeleton) :-
6180 ( chr_pp_flag(guard_via_reschedule,on) ->
6181 guard_via_reschedule_main_new(Retrievals,GuardList,Prelude,GuardListSkeleton,LookupSkeleton,ScheduleSkeleton),
6182 list2conj(ScheduleSkeleton,GoalSkeleton)
6184 length(Retrievals,RL), length(LookupSkeleton,RL),
6185 length(GuardList,GL), length(GuardListSkeleton,GL),
6186 append(LookupSkeleton,GuardListSkeleton,GoalListSkeleton),
6187 list2conj(GoalListSkeleton,GoalSkeleton)
6189 guard_via_reschedule_main_new(PartnerLookups,GuardList,ActiveHead,
6190 GuardListSkeleton,LookupSkeleton,ScheduleSkeleton) :-
6191 initialize_unit_dictionary(ActiveHead,Dict),
6192 maplist(wrap_in_functor(lookup),PartnerLookups,WrappedPartnerLookups),
6193 maplist(wrap_in_functor(guard),GuardList,WrappedGuardList),
6194 build_units(WrappedPartnerLookups,WrappedGuardList,Dict,Units),
6195 dependency_reorder(Units,NUnits),
6196 wrappedunits2lists(NUnits,IndexedGuardListSkeleton,LookupSkeleton,ScheduleSkeleton),
6197 sort(IndexedGuardListSkeleton,SortedIndexedGuardListSkeleton),
6198 snd_of_pairs(SortedIndexedGuardListSkeleton,GuardListSkeleton).
6200 wrap_in_functor(Functor,X,Term) :-
6201 Term =.. [Functor,X].
6203 wrappedunits2lists([],[],[],[]).
6204 wrappedunits2lists([unit(N,WrappedGoal,_,_)|Units],Gs,Ls,Ss) :-
6205 Ss = [GoalCopy|TSs],
6206 ( WrappedGoal = lookup(Goal) ->
6207 Ls = [GoalCopy|TLs],
6209 ; WrappedGoal = guard(Goal) ->
6210 Gs = [N-GoalCopy|TGs],
6213 wrappedunits2lists(Units,TGs,TLs,TSs).
6215 guard_splitting(Rule,SplitGuardList) :-
6216 Rule = rule(H1,H2,Guard,_),
6217 append(H1,H2,Heads),
6218 conj2list(Guard,GuardList),
6219 term_variables(Heads,HeadVars),
6220 split_off_simple_guard_new(GuardList,HeadVars,GuardPrefix,RestGuardList),
6221 append(GuardPrefix,[RestGuard],SplitGuardList),
6222 term_variables(RestGuardList,GuardVars1),
6223 % variables that are declared to be ground don't need to be locked
6224 ground_vars(Heads,GroundVars),
6225 list_difference_eq(HeadVars,GroundVars,LockableHeadVars),
6226 intersect_eq(LockableHeadVars,GuardVars1,GuardVars),
6227 ( chr_pp_flag(guard_locks,on),
6228 bagof(('chr lock'(X)) - ('chr unlock'(X)), (lists:member(X,GuardVars)), LocksUnlocks) ->
6229 once(pairup(Locks,Unlocks,LocksUnlocks))
6234 list2conj(Locks,LockPhase),
6235 list2conj(Unlocks,UnlockPhase),
6236 list2conj(RestGuardList,RestGuard1),
6237 RestGuard = (LockPhase,(RestGuard1,UnlockPhase)).
6239 guard_body_copies3(Rule,GuardList,VarDict,GuardCopyList,BodyCopy) :-
6240 Rule = rule(_,_,_,Body),
6241 my_term_copy(GuardList,VarDict,VarDict2,GuardCopyList),
6242 my_term_copy(Body,VarDict2,BodyCopy).
6245 split_off_simple_guard_new([],_,[],[]).
6246 split_off_simple_guard_new([G|Gs],VarDict,S,C) :-
6247 ( simple_guard_new(G,VarDict) ->
6249 split_off_simple_guard_new(Gs,VarDict,Ss,C)
6255 % simple guard: cheap and benign (does not bind variables)
6256 simple_guard_new(G,Vars) :-
6257 builtin_binds_b(G,BoundVars),
6258 \+ (( member(V,BoundVars),
6259 memberchk_eq(V,Vars)
6262 dependency_reorder(Units,NUnits) :-
6263 dependency_reorder(Units,[],NUnits).
6265 dependency_reorder([],Acc,Result) :-
6266 reverse(Acc,Result).
6268 dependency_reorder([Unit|Units],Acc,Result) :-
6269 Unit = unit(_GID,_Goal,Type,GIDs),
6273 dependency_insert(Acc,Unit,GIDs,NAcc)
6275 dependency_reorder(Units,NAcc,Result).
6277 dependency_insert([],Unit,_,[Unit]).
6278 dependency_insert([X|Xs],Unit,GIDs,L) :-
6279 X = unit(GID,_,_,_),
6280 ( memberchk(GID,GIDs) ->
6284 dependency_insert(Xs,Unit,GIDs,T)
6287 build_units(Retrievals,Guard,InitialDict,Units) :-
6288 build_retrieval_units(Retrievals,1,N,InitialDict,Dict,Units,Tail),
6289 build_guard_units(Guard,N,Dict,Tail).
6291 build_retrieval_units([],N,N,Dict,Dict,L,L).
6292 build_retrieval_units([U|Us],N,M,Dict,NDict,L,T) :-
6293 term_variables(U,Vs),
6294 update_unit_dictionary(Vs,N,Dict,Dict1,[],GIDs),
6295 L = [unit(N,U,fixed,GIDs)|L1],
6297 build_retrieval_units(Us,N1,M,Dict1,NDict,L1,T).
6299 initialize_unit_dictionary(Term,Dict) :-
6300 term_variables(Term,Vars),
6301 pair_all_with(Vars,0,Dict).
6303 update_unit_dictionary([],_,Dict,Dict,GIDs,GIDs).
6304 update_unit_dictionary([V|Vs],This,Dict,NDict,GIDs,NGIDs) :-
6305 ( lookup_eq(Dict,V,GID) ->
6306 ( (GID == This ; memberchk(GID,GIDs) ) ->
6313 Dict1 = [V - This|Dict],
6316 update_unit_dictionary(Vs,This,Dict1,NDict,GIDs1,NGIDs).
6318 build_guard_units(Guard,N,Dict,Units) :-
6320 Units = [unit(N,Goal,fixed,[])]
6321 ; Guard = [Goal|Goals] ->
6322 term_variables(Goal,Vs),
6323 update_unit_dictionary2(Vs,N,Dict,NDict,[],GIDs),
6324 Units = [unit(N,Goal,movable,GIDs)|RUnits],
6326 build_guard_units(Goals,N1,NDict,RUnits)
6329 update_unit_dictionary2([],_,Dict,Dict,GIDs,GIDs).
6330 update_unit_dictionary2([V|Vs],This,Dict,NDict,GIDs,NGIDs) :-
6331 ( lookup_eq(Dict,V,GID) ->
6332 ( (GID == This ; memberchk(GID,GIDs) ) ->
6337 Dict1 = [V - This|Dict]
6339 Dict1 = [V - This|Dict],
6342 update_unit_dictionary2(Vs,This,Dict1,NDict,GIDs1,NGIDs).
6344 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6346 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6348 %% / ___| ___| |_ / ___| ___ _ __ ___ __ _ _ __ | |_(_) ___ ___ _
6349 %% \___ \ / _ \ __| \___ \ / _ \ '_ ` _ \ / _` | '_ \| __| |/ __/ __(_)
6350 %% ___) | __/ |_ ___) | __/ | | | | | (_| | | | | |_| | (__\__ \_
6351 %% |____/ \___|\__| |____/ \___|_| |_| |_|\__,_|_| |_|\__|_|\___|___(_)
6354 %% | | | |_ __ (_) __ _ _ _ ___ |_ _|_ __ / _| ___ _ __ ___ _ __ ___ ___
6355 %% | | | | '_ \| |/ _` | | | |/ _ \ | || '_ \| |_ / _ \ '__/ _ \ '_ \ / __/ _ \
6356 %% | |_| | | | | | (_| | |_| | __/ | || | | | _| __/ | | __/ | | | (_| __/
6357 %% \___/|_| |_|_|\__, |\__,_|\___| |___|_| |_|_| \___|_| \___|_| |_|\___\___|
6360 functional_dependency/4,
6361 get_functional_dependency/4.
6363 :- chr_option(mode,functional_dependency(+,+,?,?)).
6364 :- chr_option(mode,get_functional_dependency(+,+,?,?)).
6366 allocation_occurrence(C,AO), occurrence(C,O,RuleNb,_,_) \ functional_dependency(C,RuleNb,Pattern,Key)
6370 functional_dependency(C,1,Pattern,Key).
6372 functional_dependency(C,RuleNb1,Pattern,Key) \ get_functional_dependency(C,RuleNb2,QPattern,QKey)
6376 QPattern = Pattern, QKey = Key.
6377 get_functional_dependency(_,_,_,_)
6381 functional_dependency_analysis(Rules) :-
6382 ( fail, chr_pp_flag(functional_dependency_analysis,on) ->
6383 functional_dependency_analysis_main(Rules)
6388 functional_dependency_analysis_main([]).
6389 functional_dependency_analysis_main([PRule|PRules]) :-
6390 ( discover_unique_pattern(PRule,C,RuleNb,Pattern,Key) ->
6391 functional_dependency(C,RuleNb,Pattern,Key)
6395 functional_dependency_analysis_main(PRules).
6397 discover_unique_pattern(PragmaRule,F/A,RuleNb,Pattern,Key) :-
6398 PragmaRule = pragma(Rule,_,_,Name,RuleNb),
6399 Rule = rule(H1,H2,Guard,_),
6407 check_unique_constraints(C1,C2,Guard,RuleNb,List),
6408 term_variables(C1,Vs),
6411 lookup_eq(List,V1,V2),
6414 select_pragma_unique_variables(Vs,List,Key1),
6415 copy_term_nat(C1-Key1,Pattern-Key),
6418 select_pragma_unique_variables([],_,[]).
6419 select_pragma_unique_variables([V|Vs],List,L) :-
6420 ( lookup_eq(List,V,_) ->
6425 select_pragma_unique_variables(Vs,List,T).
6427 % depends on functional dependency analysis
6428 % and shape of rule: C1 \ C2 <=> true.
6429 set_semantics_rules(Rules) :-
6430 ( fail, chr_pp_flag(set_semantics_rule,on) ->
6431 set_semantics_rules_main(Rules)
6436 set_semantics_rules_main([]).
6437 set_semantics_rules_main([R|Rs]) :-
6438 set_semantics_rule_main(R),
6439 set_semantics_rules_main(Rs).
6441 set_semantics_rule_main(PragmaRule) :-
6442 PragmaRule = pragma(Rule,IDs,Pragmas,_,RuleNb),
6443 ( Rule = rule([C1],[C2],true,_),
6444 IDs = ids([ID1],[ID2]),
6445 \+ is_passive(RuleNb,ID1),
6447 get_functional_dependency(F/A,RuleNb,Pattern,Key),
6448 copy_term_nat(Pattern-Key,C1-Key1),
6449 copy_term_nat(Pattern-Key,C2-Key2),
6456 check_unique_constraints(C1,C2,G,RuleNb,List) :-
6457 \+ any_passive_head(RuleNb),
6458 variable_replacement(C1-C2,C2-C1,List),
6459 copy_with_variable_replacement(G,OtherG,List),
6461 once(entails_b(NotG,OtherG)).
6463 % checks for rules of the shape ...,C1,C2... (<|=)=> ...
6464 % where C1 and C2 are symmteric constraints
6465 symmetry_analysis(Rules) :-
6466 ( chr_pp_flag(check_unnecessary_active,off) ->
6469 symmetry_analysis_main(Rules)
6472 symmetry_analysis_main([]).
6473 symmetry_analysis_main([R|Rs]) :-
6474 R = pragma(Rule,ids(IDs1,IDs2),_,_,RuleNb),
6475 Rule = rule(H1,H2,_,_),
6476 ( ( \+ chr_pp_flag(check_unnecessary_active,simplification) ; H2 == [] ), H1 \== [] ->
6477 symmetry_analysis_heads_simplification(H1,IDs1,[],[],Rule,RuleNb),
6478 symmetry_analysis_heads_propagation(H2,IDs2,[],[],Rule,RuleNb)
6482 symmetry_analysis_main(Rs).
6484 symmetry_analysis_heads_simplification([],[],_,_,_,_).
6485 symmetry_analysis_heads_simplification([H|Hs],[ID|IDs],PreHs,PreIDs,Rule,RuleNb) :-
6486 ( \+ is_passive(RuleNb,ID),
6487 member2(PreHs,PreIDs,PreH-PreID),
6488 \+ is_passive(RuleNb,PreID),
6489 variable_replacement(PreH,H,List),
6490 copy_with_variable_replacement(Rule,Rule2,List),
6491 identical_guarded_rules(Rule,Rule2) ->
6496 symmetry_analysis_heads_simplification(Hs,IDs,[H|PreHs],[ID|PreIDs],Rule,RuleNb).
6498 symmetry_analysis_heads_propagation([],[],_,_,_,_).
6499 symmetry_analysis_heads_propagation([H|Hs],[ID|IDs],PreHs,PreIDs,Rule,RuleNb) :-
6500 ( \+ is_passive(RuleNb,ID),
6501 member2(PreHs,PreIDs,PreH-PreID),
6502 \+ is_passive(RuleNb,PreID),
6503 variable_replacement(PreH,H,List),
6504 copy_with_variable_replacement(Rule,Rule2,List),
6505 identical_rules(Rule,Rule2) ->
6510 symmetry_analysis_heads_propagation(Hs,IDs,[H|PreHs],[ID|PreIDs],Rule,RuleNb).
6512 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6514 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6515 %% ____ _ _ _ __ _ _ _
6516 %% / ___|(_)_ __ ___ _ __ | (_)/ _(_) ___ __ _| |_(_) ___ _ __
6517 %% \___ \| | '_ ` _ \| '_ \| | | |_| |/ __/ _` | __| |/ _ \| '_ \
6518 %% ___) | | | | | | | |_) | | | _| | (_| (_| | |_| | (_) | | | |
6519 %% |____/|_|_| |_| |_| .__/|_|_|_| |_|\___\__,_|\__|_|\___/|_| |_|
6522 simplification_code(Head,ID,RestHeads,RestIDs,PragmaRule,F/A,O,Id,L,T) :-
6523 PragmaRule = pragma(Rule,_,Pragmas,_,RuleNb),
6524 head_info(Head,A,_Vars,Susp,HeadVars,HeadPairs),
6525 build_head(F,A,Id,HeadVars,ClauseHead),
6526 get_constraint_mode(F/A,Mode),
6527 head_arg_matches(HeadPairs,Mode,[],FirstMatching,VarDict1,[],GroundVars),
6530 guard_splitting(Rule,GuardList0),
6531 ( is_stored_in_guard(F/A, RuleNb) ->
6532 GuardList = [Hole1|GuardList0]
6534 GuardList = GuardList0
6536 guard_via_reschedule_new(RestHeads,GuardList,Head,GuardCopyList,GetRestHeads,RescheduledTest),
6538 rest_heads_retrieval_and_matching(RestHeads,RestIDs,Head,GetRestHeads,Susps,VarDict1,VarDict,[],[],[],GroundVars,_),
6540 guard_body_copies3(Rule,GuardList,VarDict,GuardCopyList,BodyCopy),
6542 ( is_stored_in_guard(F/A, RuleNb) ->
6543 gen_occ_allocation_in_guard(F/A,O,Vars,Susp,Allocation),
6544 gen_uncond_attach_goal(F/A,Susp,Vars,Attachment,_),
6545 GuardCopyList = [Hole1Copy|_],
6546 Hole1Copy = (Allocation, Attachment)
6552 partner_constraint_detachments(Susps,RestHeads,VarDict,SuspsDetachments),
6553 active_constraint_detachment(Id,Susp,Head,VarDict,SuspDetachment),
6555 ( chr_pp_flag(debugable,on) ->
6556 Rule = rule(_,_,Guard,Body),
6557 my_term_copy(Guard - Body, VarDict, DebugGuard - DebugBody),
6558 sort_by_key([Susp|Susps],[ID|RestIDs],SortedSusps),
6559 DebugTry = 'chr debug_event'( try(SortedSusps,[],DebugGuard,DebugBody)),
6560 DebugApply = 'chr debug_event'(apply(SortedSusps,[],DebugGuard,DebugBody)),
6561 instrument_goal(ActualCut,DebugTry,DebugApply,Cut)
6565 ( unconditional_occurrence(F/A,O), chr_pp_flag(late_allocation,on) -> ActualCut = true ; ActualCut = (!) ),
6566 Clause = ( ClauseHead :-
6574 add_location(Clause,RuleNb,LocatedClause),
6575 L = [LocatedClause | T].
6577 add_location(Clause,RuleNb,NClause) :-
6578 ( chr_pp_flag(line_numbers,on) ->
6579 get_chr_source_file(File),
6580 get_line_number(RuleNb,LineNb),
6581 NClause = '$source_location'(File,LineNb):Clause
6586 add_dummy_location(Clause,NClause) :-
6587 ( chr_pp_flag(line_numbers,on) ->
6588 get_chr_source_file(File),
6589 NClause = '$source_location'(File,1):Clause
6593 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6594 %% head_arg_matches(+Pairs,+Modes,+VarDict,-Goal,-NVarDict) is det.
6596 % Return goal matching newly introduced variables with variables in
6597 % previously looked-up heads.
6598 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6599 head_arg_matches(Pairs,Modes,VarDict,Goal,NVarDict) :-
6600 head_arg_matches(Pairs,Modes,VarDict,Goal,NVarDict,[],_).
6602 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6603 %% head_arg_matches(+Pairs,+Modes,+VarDict,-Goal,-NVarDict,+GroundVars,-NGroundVars) is det.
6604 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6605 head_arg_matches(Pairs,Modes,VarDict,Goal,NVarDict,GroundVars,NGroundVars) :-
6606 head_arg_matches_(Pairs,Modes,VarDict,GroundVars,GoalList,NVarDict,NGroundVars),
6607 list2conj(GoalList,Goal).
6609 head_arg_matches_([],[],VarDict,GroundVars,[],VarDict,GroundVars).
6610 head_arg_matches_([Arg-Var| Rest],[Mode|Modes],VarDict,GroundVars,GoalList,NVarDict,NGroundVars) :-
6612 ( lookup_eq(VarDict,Arg,OtherVar) ->
6614 ( memberchk_eq(Arg,GroundVars) ->
6615 GoalList = [Var = OtherVar | RestGoalList],
6616 GroundVars1 = GroundVars
6618 GoalList = [Var == OtherVar | RestGoalList],
6619 GroundVars1 = [Arg|GroundVars]
6622 GoalList = [Var == OtherVar | RestGoalList],
6623 GroundVars1 = GroundVars
6627 VarDict1 = [Arg-Var | VarDict],
6628 GoalList = RestGoalList,
6630 GroundVars1 = [Arg|GroundVars]
6632 GroundVars1 = GroundVars
6637 ; ground(Arg), Arg = '$chr_identifier_match'(ActualArg,IndexType) ->
6638 identifier_label_atom(IndexType,Var,ActualArg,Goal),
6639 GoalList = [Goal|RestGoalList],
6641 GroundVars1 = GroundVars,
6646 GoalList = [ Var = Arg | RestGoalList]
6648 GoalList = [ Var == Arg | RestGoalList]
6651 GroundVars1 = GroundVars,
6654 ; Mode == (+), is_ground(GroundVars,Arg) ->
6655 copy_with_variable_replacement(Arg,ArgCopy,VarDict),
6656 GoalList = [ Var = ArgCopy | RestGoalList],
6658 GroundVars1 = GroundVars,
6663 functor(Term,Fct,N),
6666 GoalList = [ Var = Term | RestGoalList ]
6668 GoalList = [ nonvar(Var), Var = Term | RestGoalList ]
6670 pairup(Args,Vars,NewPairs),
6671 append(NewPairs,Rest,Pairs),
6672 replicate(N,Mode,NewModes),
6673 append(NewModes,Modes,RestModes),
6675 GroundVars1 = GroundVars
6677 head_arg_matches_(Pairs,RestModes,VarDict1,GroundVars1,RestGoalList,NVarDict,NGroundVars).
6679 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6680 % add_heads_types(+ListOfHeads,+VarTypes,-NVarTypes) is det.
6681 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6682 add_heads_types([],VarTypes,VarTypes).
6683 add_heads_types([Head|Heads],VarTypes,NVarTypes) :-
6684 add_head_types(Head,VarTypes,VarTypes1),
6685 add_heads_types(Heads,VarTypes1,NVarTypes).
6687 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6688 % add_head_types(+Head,+VarTypes,-NVarTypes) is det.
6689 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6690 add_head_types(Head,VarTypes,NVarTypes) :-
6692 get_constraint_type_det(F/A,ArgTypes),
6694 add_args_types(Args,ArgTypes,VarTypes,NVarTypes).
6696 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6697 % add_args_types(+Terms,+Types,+VarTypes,-NVarTypes) is det.
6698 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6699 add_args_types([],[],VarTypes,VarTypes).
6700 add_args_types([Arg|Args],[Type|Types],VarTypes,NVarTypes) :-
6701 add_arg_types(Arg,Type,VarTypes,VarTypes1),
6702 add_args_types(Args,Types,VarTypes1,NVarTypes).
6704 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6705 % add_arg_types(+Term,+Type,+VarTypes,-NVarTypes) is det.
6706 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6707 add_arg_types(Term,Type,VarTypes,NVarTypes) :-
6709 ( lookup_eq(VarTypes,Term,_) ->
6710 NVarTypes = VarTypes
6712 NVarTypes = [Term-Type|VarTypes]
6715 NVarTypes = VarTypes
6716 ; % TODO improve approximation!
6717 term_variables(Term,Vars),
6719 replicate(VarNb,any,Types),
6720 add_args_types(Vars,Types,VarTypes,NVarTypes)
6725 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6726 %% add_heads_ground_variables(+ListOfHeads,+GroundVars,-NGroundVars) is det.
6728 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6729 add_heads_ground_variables([],GroundVars,GroundVars).
6730 add_heads_ground_variables([Head|Heads],GroundVars,NGroundVars) :-
6731 add_head_ground_variables(Head,GroundVars,GroundVars1),
6732 add_heads_ground_variables(Heads,GroundVars1,NGroundVars).
6734 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6735 %% add_head_ground_variables(+Head,+GroundVars,-GroundVars) is det.
6737 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6738 add_head_ground_variables(Head,GroundVars,NGroundVars) :-
6740 get_constraint_mode(F/A,ArgModes),
6742 add_arg_ground_variables(Args,ArgModes,GroundVars,NGroundVars).
6745 add_arg_ground_variables([],[],GroundVars,GroundVars).
6746 add_arg_ground_variables([Arg|Args],[Mode|Modes],GroundVars,NGroundVars) :-
6748 term_variables(Arg,Vars),
6749 add_var_ground_variables(Vars,GroundVars,GroundVars1)
6751 GroundVars = GroundVars1
6753 add_arg_ground_variables(Args,Modes,GroundVars1,NGroundVars).
6755 add_var_ground_variables([],GroundVars,GroundVars).
6756 add_var_ground_variables([Var|Vars],GroundVars,NGroundVars) :-
6757 ( memberchk_eq(Var,GroundVars) ->
6758 GroundVars1 = GroundVars
6760 GroundVars1 = [Var|GroundVars]
6762 add_var_ground_variables(Vars,GroundVars1,NGroundVars).
6763 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6764 %% is_ground(+GroundVars,+Term) is semidet.
6766 % Determine whether =Term= is always ground.
6767 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6768 is_ground(GroundVars,Term) :-
6773 maplist(is_ground(GroundVars),Args)
6775 memberchk_eq(Term,GroundVars)
6778 %% check_ground(+GroundVars,+Term,-Goal) is det.
6780 % Return runtime check to see whether =Term= is ground.
6781 check_ground(GroundVars,Term,Goal) :-
6782 term_variables(Term,Variables),
6783 check_ground_variables(Variables,GroundVars,Goal).
6785 check_ground_variables([],_,true).
6786 check_ground_variables([Var|Vars],GroundVars,Goal) :-
6787 ( memberchk_eq(Var,GroundVars) ->
6788 check_ground_variables(Vars,GroundVars,Goal)
6790 Goal = (ground(Var), RGoal),
6791 check_ground_variables(Vars,GroundVars,RGoal)
6794 rest_heads_retrieval_and_matching(Heads,IDs,ActiveHead,GoalList,Susps,VarDict,NVarDict,PrevHs,PrevSusps,AttrDict) :-
6795 rest_heads_retrieval_and_matching(Heads,IDs,ActiveHead,GoalList,Susps,VarDict,NVarDict,PrevHs,PrevSusps,AttrDict,[],_).
6797 rest_heads_retrieval_and_matching(Heads,IDs,ActiveHead,GoalList,Susps,VarDict,NVarDict,PrevHs,PrevSusps,AttrDict,GroundVars,NGroundVars) :-
6799 rest_heads_retrieval_and_matching_n(Heads,IDs,PrevHs,PrevSusps,ActiveHead,GoalList,Susps,VarDict,NVarDict,AttrDict,GroundVars,NGroundVars)
6804 GroundVars = NGroundVars
6807 rest_heads_retrieval_and_matching_n([],_,_,_,_,[],[],VarDict,VarDict,_AttrDict,GroundVars,GroundVars).
6808 rest_heads_retrieval_and_matching_n([H|Hs],[ID|IDs],PrevHs,PrevSusps,ActiveHead,
6809 [Goal|Goals],[Susp|Susps],VarDict,NVarDict,_AttrDict,GroundVars,NGroundVars) :-
6811 head_info(H,A,Vars,_,_,Pairs),
6812 get_store_type(F/A,StoreType),
6813 ( StoreType == default ->
6814 passive_head_via(H,[ActiveHead|PrevHs],VarDict,ViaGoal,VarSusps),
6815 delay_phase_end(validate_store_type_assumptions,
6816 ( static_suspension_term(F/A,Suspension),
6817 get_static_suspension_term_field(arguments,F/A,Suspension,Vars),
6818 get_static_suspension_field(F/A,Suspension,state,active,GetState)
6821 % create_get_mutable_ref(active,State,GetMutable),
6822 get_constraint_mode(F/A,Mode),
6823 head_arg_matches(Pairs,Mode,VarDict,MatchingGoal,VarDict1,GroundVars,GroundVars1),
6825 sbag_member_call(Susp,VarSusps,Sbag),
6826 ExistentialLookup = (
6829 Susp = Suspension, % not inlined
6833 delay_phase_end(validate_store_type_assumptions,
6834 ( static_suspension_term(F/A,Suspension),
6835 get_static_suspension_term_field(arguments,F/A,Suspension,Vars)
6838 existential_lookup(StoreType,H,[ActiveHead|PrevHs],VarDict,GroundVars,Suspension,ExistentialLookup,Susp,Pairs,NPairs),
6839 get_constraint_mode(F/A,Mode),
6840 filter_mode(NPairs,Pairs,Mode,NMode),
6841 head_arg_matches(NPairs,NMode,VarDict,MatchingGoal,VarDict1,GroundVars,GroundVars1)
6843 different_from_other_susps(H,Susp,PrevHs,PrevSusps,DiffSuspGoals),
6844 append(NPairs,VarDict1,DA_), % order important here
6845 translate(GroundVars1,DA_,GroundVarsA),
6846 translate(GroundVars1,VarDict1,GroundVarsB),
6847 inline_matching_goal(MatchingGoal,MatchingGoal2,GroundVarsA,GroundVarsB),
6854 rest_heads_retrieval_and_matching_n(Hs,IDs,[H|PrevHs],[Susp|PrevSusps],ActiveHead,Goals,Susps,VarDict1,NVarDict,_NewAttrDict,GroundVars1,NGroundVars).
6856 inline_matching_goal(A==B,true,GVA,GVB) :-
6857 memberchk_eq(A,GVA),
6858 memberchk_eq(B,GVB),
6861 % inline_matching_goal(A=B,true,_,_) :- A=B, !.
6862 inline_matching_goal((A,B),(A2,B2),GVA,GVB) :- !,
6863 inline_matching_goal(A,A2,GVA,GVB),
6864 inline_matching_goal(B,B2,GVA,GVB).
6865 inline_matching_goal(X,X,_,_).
6868 filter_mode([],_,_,[]).
6869 filter_mode([Arg-Var|Rest],[_-V|R],[M|Ms],Modes) :-
6872 filter_mode(Rest,R,Ms,MT)
6874 filter_mode([Arg-Var|Rest],R,Ms,Modes)
6877 check_unique_keys([],_).
6878 check_unique_keys([V|Vs],Dict) :-
6879 lookup_eq(Dict,V,_),
6880 check_unique_keys(Vs,Dict).
6882 % Generates tests to ensure the found constraint differs from previously found constraints
6883 % TODO: detect more cases where constraints need be different
6884 different_from_other_susps(Head,Susp,Heads,Susps,DiffSuspGoals) :-
6885 different_from_other_susps_(Heads,Susps,Head,Susp,DiffSuspGoalList),
6886 list2conj(DiffSuspGoalList,DiffSuspGoals).
6888 different_from_other_susps_(_,[],_,_,[]) :- !.
6889 different_from_other_susps_([PreHead|Heads],[PreSusp|Susps],Head,Susp,List) :-
6890 ( functor(Head,F,A), functor(PreHead,F,A),
6891 copy_term_nat(PreHead-Head,PreHeadCopy-HeadCopy),
6892 \+ \+ PreHeadCopy = HeadCopy ->
6894 List = [Susp \== PreSusp | Tail]
6898 different_from_other_susps_(Heads,Susps,Head,Susp,Tail).
6900 % passive_head_via(in,in,in,in,out,out,out) :-
6901 passive_head_via(Head,PrevHeads,VarDict,Goal,AllSusps) :-
6903 get_constraint_index(F/A,Pos),
6904 common_variables(Head,PrevHeads,CommonVars),
6905 global_list_store_name(F/A,Name),
6906 GlobalGoal = nb_getval(Name,AllSusps),
6907 get_constraint_mode(F/A,ArgModes),
6910 ; member(CommonVar,CommonVars), nth(I,ArgModes,(-)), arg(I,Head,Arg), Arg == CommonVar ->
6911 translate([CommonVar],VarDict,[Var]),
6912 gen_get_mod_constraints(F/A,Var,AttrGoal,AllSusps),
6915 translate(CommonVars,VarDict,Vars),
6916 add_heads_types(PrevHeads,[],TypeDict),
6917 my_term_copy(TypeDict,VarDict,TypeDictCopy),
6918 gen_get_mod_constraints(F/A,Vars,TypeDictCopy,ViaGoal,AttrGoal,AllSusps),
6927 common_variables(T,Ts,Vs) :-
6928 term_variables(T,V1),
6929 term_variables(Ts,V2),
6930 intersect_eq(V1,V2,Vs).
6932 gen_get_mod_constraints(FA,Vars,TypeDict,ViaGoal,AttrGoal,AllSusps) :-
6933 get_target_module(Mod),
6935 lookup_eq(TypeDict,A,Type),
6936 ( atomic_type(Type) ->
6940 ViaGoal = 'chr newvia_1'(A,V)
6943 ViaGoal = 'chr newvia_2'(A,B,V)
6945 ViaGoal = 'chr newvia'(Vars,V)
6948 ( get_attr(V,Mod,TSusps),
6949 TSuspsEqSusps % TSusps = Susps
6951 get_max_constraint_index(N),
6953 TSuspsEqSusps = true, % TSusps = Susps
6956 get_constraint_index(FA,Pos),
6957 get_suspensions(N,Pos,TSusps,TSuspsEqSusps,AllSusps)
6959 gen_get_mod_constraints(FA,Var,AttrGoal,AllSusps) :-
6960 get_target_module(Mod),
6962 ( get_attr(Var,Mod,TSusps),
6963 TSuspsEqSusps % TSusps = Susps
6965 get_max_constraint_index(N),
6967 TSuspsEqSusps = true, % TSusps = Susps
6970 get_constraint_index(FA,Pos),
6971 get_suspensions(N,Pos,TSusps,TSuspsEqSusps,AllSusps)
6974 guard_body_copies(Rule,VarDict,GuardCopy,BodyCopy) :-
6975 guard_body_copies2(Rule,VarDict,GuardCopyList,BodyCopy),
6976 list2conj(GuardCopyList,GuardCopy).
6978 guard_body_copies2(Rule,VarDict,GuardCopyList,BodyCopy) :-
6979 Rule = rule(_,H,Guard,Body),
6980 conj2list(Guard,GuardList),
6981 split_off_simple_guard(GuardList,VarDict,GuardPrefix,RestGuardList),
6982 my_term_copy(GuardPrefix-RestGuardList,VarDict,VarDict2,GuardPrefixCopy-RestGuardListCopyCore),
6984 append(GuardPrefixCopy,[RestGuardCopy],GuardCopyList),
6985 term_variables(RestGuardList,GuardVars),
6986 term_variables(RestGuardListCopyCore,GuardCopyVars),
6987 % variables that are declared to be ground don't need to be locked
6988 ground_vars(H,GroundVars),
6989 list_difference_eq(GuardVars,GroundVars,LockedGuardVars),
6990 ( chr_pp_flag(guard_locks,on),
6991 bagof(('chr lock'(Y)) - ('chr unlock'(Y)),
6992 X ^ (lists:member(X,LockedGuardVars), % X is a variable appearing in the original guard
6993 pairlist:lookup_eq(VarDict,X,Y), % translate X into new variable
6994 memberchk_eq(Y,GuardCopyVars) % redundant check? or multiple entries for X possible?
6997 once(pairup(Locks,Unlocks,LocksUnlocks))
7002 list2conj(Locks,LockPhase),
7003 list2conj(Unlocks,UnlockPhase),
7004 list2conj(RestGuardListCopyCore,RestGuardCopyCore),
7005 RestGuardCopy = (LockPhase,(RestGuardCopyCore,UnlockPhase)),
7006 my_term_copy(Body,VarDict2,BodyCopy).
7009 split_off_simple_guard([],_,[],[]).
7010 split_off_simple_guard([G|Gs],VarDict,S,C) :-
7011 ( simple_guard(G,VarDict) ->
7013 split_off_simple_guard(Gs,VarDict,Ss,C)
7019 % simple guard: cheap and benign (does not bind variables)
7020 simple_guard(G,VarDict) :-
7022 \+ (( member(V,Vars),
7023 lookup_eq(VarDict,V,_)
7026 active_constraint_detachment(Id,Susp,Head,VarDict,SuspDetachment) :-
7032 Id == [0], chr_pp_flag(store_in_guards, off)
7034 ( get_allocation_occurrence(C,AO),
7035 get_max_occurrence(C,MO),
7038 only_ground_indexed_arguments(C), chr_pp_flag(late_allocation,on) ->
7039 SuspDetachment = true
7041 gen_uncond_susp_detachment(Head,Susp,active,VarDict,UnCondSuspDetachment),
7042 ( chr_pp_flag(late_allocation,on) ->
7047 UnCondSuspDetachment
7050 SuspDetachment = UnCondSuspDetachment
7054 SuspDetachment = true
7057 partner_constraint_detachments([],[],_,true).
7058 partner_constraint_detachments([Susp|Susps],[Head|Heads],VarDict,(SuspDetachment,SuspsDetachments)) :-
7059 gen_uncond_susp_detachment(Head,Susp,partner,VarDict,SuspDetachment),
7060 partner_constraint_detachments(Susps,Heads,VarDict,SuspsDetachments).
7062 gen_uncond_susp_detachment(Head,Susp,Role,VarDict,SuspDetachment) :-
7066 SuspDetachment = ( DebugEvent, RemoveInternalGoal),
7067 ( chr_pp_flag(debugable,on) ->
7068 DebugEvent = 'chr debug_event'(remove(Susp))
7072 remove_constraint_goal(C,Susp,Vars,true,(DeleteCall,Detach),Role,RemoveInternalGoal),
7073 delete_constraint_goal(Head,Susp,VarDict,DeleteCall),
7074 ( \+ only_ground_indexed_arguments(C), \+ get_store_type(C,var_assoc_store(_,_)) ->
7075 detach_constraint_atom(C,Vars,Susp,Detach)
7080 SuspDetachment = true
7083 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7085 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7087 %% / ___|(_)_ __ ___ _ __ __ _ __ _ __ _| |_(_) ___ _ __ / |
7088 %% \___ \| | '_ ` _ \| '_ \ / _` |/ _` |/ _` | __| |/ _ \| '_ \ | |
7089 %% ___) | | | | | | | |_) | (_| | (_| | (_| | |_| | (_) | | | | | |
7090 %% |____/|_|_| |_| |_| .__/ \__,_|\__, |\__,_|\__|_|\___/|_| |_| |_|
7093 simpagation_head1_code(Head,ID,RestHeads,OtherIDs,PragmaRule,F/A,O,Id,L,T) :-
7094 PragmaRule = pragma(Rule,ids(_,Heads2IDs),Pragmas,_Name,RuleNb),
7095 Rule = rule(_Heads,Heads2,Guard,Body),
7097 head_info(Head,A,Vars,Susp,HeadVars,HeadPairs),
7098 get_constraint_mode(F/A,Mode),
7099 head_arg_matches(HeadPairs,Mode,[],FirstMatching,VarDict1,[],GroundVars),
7101 build_head(F,A,Id,HeadVars,ClauseHead),
7103 append(RestHeads,Heads2,Heads),
7104 append(OtherIDs,Heads2IDs,IDs),
7105 reorder_heads(RuleNb,Head,Heads,IDs,NHeads,NIDs),
7107 guard_splitting(Rule,GuardList0),
7108 ( is_stored_in_guard(F/A, RuleNb) ->
7109 GuardList = [Hole1|GuardList0]
7111 GuardList = GuardList0
7113 guard_via_reschedule_new(NHeads,GuardList,Head,GuardCopyList,GetRestHeads,RescheduledTest),
7115 rest_heads_retrieval_and_matching(NHeads,NIDs,Head,GetRestHeads,Susps,VarDict1,VarDict,[],[],[],GroundVars,_),
7116 split_by_ids(NIDs,Susps,OtherIDs,Susps1,Susps1IDs,Susps2,Susps2IDs),
7118 guard_body_copies3(Rule,GuardList,VarDict,GuardCopyList,BodyCopy),
7120 ( is_stored_in_guard(F/A, RuleNb) ->
7121 gen_uncond_attach_goal(F/A,Susp,Vars,Attachment,_),
7122 GuardCopyList = [Hole1Copy|_],
7123 Hole1Copy = Attachment
7128 sort_by_key(Susps1,Susps1IDs,SortedSusps1),
7129 partner_constraint_detachments(SortedSusps1,RestHeads,VarDict,SuspsDetachments),
7130 active_constraint_detachment(Id,Susp,Head,VarDict,SuspDetachment),
7132 ( chr_pp_flag(debugable,on) ->
7133 my_term_copy(Guard - Body, VarDict, DebugGuard - DebugBody),
7134 sort_by_key([Susp|Susps1],[ID|Susps1IDs],RemovedSusps),
7135 sort_by_key(Susps2,Susps2IDs,KeptSusps),
7136 DebugTry = 'chr debug_event'( try(RemovedSusps,KeptSusps,DebugGuard,DebugBody)),
7137 DebugApply = 'chr debug_event'(apply(RemovedSusps,KeptSusps,DebugGuard,DebugBody)),
7138 instrument_goal((!),DebugTry,DebugApply,Cut)
7143 Clause = ( ClauseHead :-
7151 add_location(Clause,RuleNb,LocatedClause),
7152 L = [LocatedClause | T].
7154 split_by_ids([],[],_,[],[]).
7155 split_by_ids([I|Is],[S|Ss],I1s,S1s,S2s) :-
7156 ( memberchk_eq(I,I1s) ->
7163 split_by_ids(Is,Ss,I1s,R1s,R2s).
7165 split_by_ids([],[],_,[],[],[],[]).
7166 split_by_ids([I|Is],[S|Ss],I1s,S1s,SI1s,S2s,SI2s) :-
7167 ( memberchk_eq(I,I1s) ->
7178 split_by_ids(Is,Ss,I1s,R1s,RSI1s,R2s,RSI2s).
7179 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7182 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7184 %% / ___|(_)_ __ ___ _ __ __ _ __ _ __ _| |_(_) ___ _ __ |___ \
7185 %% \___ \| | '_ ` _ \| '_ \ / _` |/ _` |/ _` | __| |/ _ \| '_ \ __) |
7186 %% ___) | | | | | | | |_) | (_| | (_| | (_| | |_| | (_) | | | | / __/
7187 %% |____/|_|_| |_| |_| .__/ \__,_|\__, |\__,_|\__|_|\___/|_| |_| |_____|
7190 %% Genereate prelude + worker predicate
7191 %% prelude calls worker
7192 %% worker iterates over one type of removed constraints
7193 simpagation_head2_code(Head2,ID,RestHeads2,RestIDs,PragmaRule,FA,O,Id,L,T) :-
7194 PragmaRule = pragma(Rule,ids(IDs1,IDs2),Pragmas,_Name,RuleNb),
7195 Rule = rule(Heads1,_,Guard,Body),
7196 append(Heads1,RestHeads2,Heads),
7197 append(IDs1,RestIDs,IDs),
7198 reorder_heads(RuleNb,Head2,Heads,IDs,[NHead|NHeads],[NID|NIDs]),
7199 simpagation_head2_prelude(Head2,NHead,[NHeads,Guard,Body],FA,O,Id,L,L1),
7201 ( memberchk_eq(NID,IDs2) ->
7202 simpagation_universal_searches(NHeads,NIDs,IDs2,[NHead,Head2],Rule,FA,O,NextHeads,PreHeads,NextIDs,Id1,Id2,L1,L2)
7204 L1 = L2, Id1 = Id2,NextHeads = NHeads, PreHeads = [NHead,Head2], NextIDs = NIDs
7206 universal_search_iterator_end(PreHeads,NextHeads,Rule,FA,O,Id2,L2,L3),
7207 simpagation_head2_worker(PreHeads,NextHeads,NextIDs,ID,PragmaRule,FA,O,Id2,L3,T).
7209 simpagation_universal_searches([],[],_,PreHeads,_,_,_,[],PreHeads,[],Id,Id,L,L).
7210 simpagation_universal_searches(Heads,[ID|IDs],IDs2,PreHeads,Rule,C,O,OutHeads,OutPreHeads,OutIDs,Id,NId,L,T) :-
7211 Heads = [Head|RHeads],
7213 universal_search_iterator_end(PreHeads,Heads,Rule,C,O,Id,L,L0),
7214 universal_search_iterator(Heads,PreHeads,Rule,C,O,Id,L0,L1),
7215 ( memberchk_eq(ID,IDs2) ->
7216 simpagation_universal_searches(RHeads,IDs,IDs2,[Head|PreHeads],Rule,C,O,OutHeads,OutPreHeads,OutIDs,Id1,NId,L1,T)
7218 NId = Id1, L1 = T, OutHeads = RHeads, OutPreHeads = [Head|PreHeads], IDs = OutIDs
7221 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7222 simpagation_head2_prelude(Head,Head1,Rest,F/A,O,Id1,L,T) :-
7223 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs),
7224 build_head(F,A,Id1,VarsSusp,ClauseHead),
7225 get_constraint_mode(F/A,Mode),
7226 head_arg_matches(HeadPairs,Mode,[],FirstMatching,VarDict,[],GroundVars),
7228 lookup_passive_head(Head1,[Head],VarDict,GroundVars,ModConstraintsGoal,AllSusps),
7230 gen_occ_allocation(F/A,O,Vars,Susp,ConstraintAllocationGoal),
7232 extend_id(Id1,DelegateId),
7233 extra_active_delegate_variables(Head,[Head1|Rest],VarDict,ExtraVars),
7234 append([AllSusps|VarsSusp],ExtraVars,DelegateCallVars),
7235 build_head(F,A,[O|DelegateId],DelegateCallVars,Delegate),
7242 ConstraintAllocationGoal,
7245 add_dummy_location(PreludeClause,LocatedPreludeClause),
7246 L = [LocatedPreludeClause|T].
7248 extra_active_delegate_variables(Term,Terms,VarDict,Vars) :-
7250 delegate_variables(Term,Terms,VarDict,Args,Vars).
7252 passive_delegate_variables(Term,PrevTerms,NextTerms,VarDict,Vars) :-
7253 term_variables(PrevTerms,PrevVars),
7254 delegate_variables(Term,NextTerms,VarDict,PrevVars,Vars).
7256 delegate_variables(Term,Terms,VarDict,PrevVars,Vars) :-
7257 term_variables(Term,V1),
7258 term_variables(Terms,V2),
7259 intersect_eq(V1,V2,V3),
7260 list_difference_eq(V3,PrevVars,V4),
7261 translate(V4,VarDict,Vars).
7264 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7265 simpagation_head2_worker([CurrentHead|PreHeads],NextHeads,NextIDs,ID,PragmaRule,F/A,O,Id,L,T) :-
7266 PragmaRule = pragma(Rule,ids(IDs1,_),Pragmas,_,RuleNb),
7267 Rule = rule(_,_,Guard,Body),
7268 get_prop_inner_loop_vars(PreHeads,[CurrentHead,NextHeads,Guard,Body],PreVarsAndSusps,VarDict,Susp,Vars,PreSusps),
7271 gen_var(OtherSusps),
7273 functor(CurrentHead,OtherF,OtherA),
7274 gen_vars(OtherA,OtherVars),
7275 head_info(CurrentHead,OtherA,OtherVars,OtherSusp,_VarsSusp,HeadPairs),
7276 get_constraint_mode(OtherF/OtherA,Mode),
7277 head_arg_matches(HeadPairs,Mode,VarDict,FirstMatching,VarDict1,[],GroundVars),
7279 delay_phase_end(validate_store_type_assumptions,
7280 ( static_suspension_term(OtherF/OtherA,OtherSuspension),
7281 get_static_suspension_field(OtherF/OtherA,OtherSuspension,state,active,GetState),
7282 get_static_suspension_term_field(arguments,OtherF/OtherA,OtherSuspension,OtherVars)
7285 % create_get_mutable_ref(active,State,GetMutable),
7286 different_from_other_susps(CurrentHead,OtherSusp,PreHeads,PreSusps,DiffSuspGoals),
7288 OtherSusp = OtherSuspension,
7294 ClauseVars = [[OtherSusp|OtherSusps]|PreVarsAndSusps],
7295 build_head(F,A,[O|Id],ClauseVars,ClauseHead),
7297 guard_splitting(Rule,GuardList0),
7298 ( is_stored_in_guard(F/A, RuleNb) ->
7299 GuardList = [Hole1|GuardList0]
7301 GuardList = GuardList0
7303 guard_via_reschedule_new(NextHeads,GuardList,[CurrentHead|PreHeads],GuardCopyList,RestSuspsRetrieval,RescheduledTest),
7305 rest_heads_retrieval_and_matching(NextHeads,NextIDs,[CurrentHead|PreHeads],RestSuspsRetrieval,Susps,VarDict1,VarDict2,[CurrentHead|PreHeads],[OtherSusp|PreSusps],[]),
7306 split_by_ids(NextIDs,Susps,IDs1,Susps1,Susps2),
7307 split_by_ids(NextIDs,NextHeads,IDs1,RestHeads1,_),
7309 partner_constraint_detachments([OtherSusp | Susps1],[CurrentHead|RestHeads1],VarDict2,Susps1Detachments),
7311 RecursiveVars = [OtherSusps|PreVarsAndSusps],
7312 build_head(F,A,[O|Id],RecursiveVars,RecursiveCall),
7313 RecursiveVars2 = [[]|PreVarsAndSusps],
7314 build_head(F,A,[O|Id],RecursiveVars2,RecursiveCall2),
7316 guard_body_copies3(Rule,GuardList,VarDict2,GuardCopyList,BodyCopy),
7317 ( is_stored_in_guard(F/A, RuleNb) ->
7318 GuardCopyList = [GuardAttachment|_] % once( ) ??
7323 ( is_observed(F/A,O) ->
7324 gen_uncond_attach_goal(F/A,Susp,Vars,Attachment,Generation),
7325 gen_state_cond_call(Susp,F/A,RecursiveCall,Generation,ConditionalRecursiveCall),
7326 gen_state_cond_call(Susp,F/A,RecursiveCall2,Generation,ConditionalRecursiveCall2)
7329 ConditionalRecursiveCall = RecursiveCall,
7330 ConditionalRecursiveCall2 = RecursiveCall2
7333 ( chr_pp_flag(debugable,on) ->
7334 my_term_copy(Guard - Body, VarDict, DebugGuard - DebugBody),
7335 DebugTry = 'chr debug_event'( try([OtherSusp|Susps1],[Susp|Susps2],DebugGuard,DebugBody)),
7336 DebugApply = 'chr debug_event'(apply([OtherSusp|Susps1],[Susp|Susps2],DebugGuard,DebugBody))
7342 ( is_stored_in_guard(F/A, RuleNb) ->
7343 GuardAttachment = Attachment,
7344 BodyAttachment = true
7346 GuardAttachment = true,
7347 BodyAttachment = Attachment % will be true if not observed at all
7350 ( member(unique(ID1,UniqueKeys), Pragmas),
7351 check_unique_keys(UniqueKeys,VarDict) ->
7354 ( CurrentSuspTest ->
7361 ConditionalRecursiveCall2
7379 ConditionalRecursiveCall
7385 add_location(Clause,RuleNb,LocatedClause),
7386 L = [LocatedClause | T].
7388 gen_state_cond_call(Susp,FA,Call,Generation,ConditionalCall) :-
7389 ( may_trigger(FA) ->
7390 does_use_field(FA,generation),
7391 delay_phase_end(validate_store_type_assumptions,
7392 ( static_suspension_term(FA,Suspension),
7393 get_update_static_suspension_field(FA,Susp,Suspension,state,active,inactive,GetState,UpdateState),
7394 get_static_suspension_field(FA,Suspension,generation,Generation,GetGeneration),
7395 get_static_suspension_term_field(arguments,FA,Suspension,Args)
7399 delay_phase_end(validate_store_type_assumptions,
7400 ( static_suspension_term(FA,Suspension),
7401 get_update_static_suspension_field(FA,Susp,Suspension,state,active,inactive,GetState,UpdateState),
7402 get_static_suspension_term_field(arguments,FA,Suspension,Args)
7405 GetGeneration = true
7408 ( Susp = Suspension,
7417 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7420 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7422 %% | _ \ _ __ ___ _ __ __ _ __ _ __ _| |_(_) ___ _ __
7423 %% | |_) | '__/ _ \| '_ \ / _` |/ _` |/ _` | __| |/ _ \| '_ \
7424 %% | __/| | | (_) | |_) | (_| | (_| | (_| | |_| | (_) | | | |
7425 %% |_| |_| \___/| .__/ \__,_|\__, |\__,_|\__|_|\___/|_| |_|
7428 propagation_code(Head,ID,RestHeads,RestIDs,Rule,RuleNb,FA,O,Id,L,T) :-
7429 ( RestHeads == [] ->
7430 propagation_single_headed(Head,ID,Rule,RuleNb,FA,O,Id,L,T)
7432 propagation_multi_headed(Head,RestHeads,RestIDs,Rule,RuleNb,FA,O,Id,L,T)
7434 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7435 %% Single headed propagation
7436 %% everything in a single clause
7437 propagation_single_headed(Head,ID,Rule,RuleNb,F/A,O,Id,ProgramList,ProgramTail) :-
7438 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs),
7439 build_head(F,A,Id,VarsSusp,ClauseHead),
7442 build_head(F,A,NextId,VarsSusp,NextHead),
7444 get_constraint_mode(F/A,Mode),
7445 head_arg_matches(HeadPairs,Mode,[],HeadMatching,VarDict,[],GroundVars),
7446 guard_body_copies(Rule,VarDict,GuardCopy,BodyCopy),
7448 % - recursive call -
7449 RecursiveCall = NextHead,
7451 ( unconditional_occurrence(F/A,O), chr_pp_flag(late_allocation,on) ->
7457 Rule = rule(_,_,Guard,Body),
7458 ( chr_pp_flag(debugable,on) ->
7459 my_term_copy(Guard - Body, VarDict, DebugGuard - DebugBody),
7460 DebugTry = 'chr debug_event'( try([],[Susp],DebugGuard,DebugBody)),
7461 DebugApply = 'chr debug_event'(apply([],[Susp],DebugGuard,DebugBody)),
7462 instrument_goal(ActualCut,DebugTry,DebugApply,Cut)
7466 ( may_trigger(F/A), \+ has_no_history(RuleNb)->
7467 use_auxiliary_predicate(novel_production),
7468 use_auxiliary_predicate(extend_history),
7469 does_use_history(F/A,O),
7470 gen_occ_allocation(F/A,O,Vars,Susp,Allocation),
7472 ( named_history(RuleNb,HistoryName,HistoryIDs) ->
7473 ( HistoryIDs == [] ->
7474 empty_named_history_novel_production(HistoryName,NovelProduction),
7475 empty_named_history_extend_history(HistoryName,ExtendHistory)
7483 ( var(NovelProduction) ->
7484 NovelProduction = '$novel_production'(Susp,Tuple),
7485 ExtendHistory = '$extend_history'(Susp,Tuple)
7490 ( is_observed(F/A,O) ->
7491 gen_uncond_attach_goal(F/A,Susp,Vars,Attachment,Generation),
7492 gen_state_cond_call(Susp,F/A,RecursiveCall,Generation,ConditionalRecursiveCall)
7495 ConditionalRecursiveCall = RecursiveCall
7499 NovelProduction = true,
7500 ExtendHistory = true,
7502 ( is_observed(F/A,O) ->
7503 get_allocation_occurrence(F/A,AllocO),
7505 gen_insert_constraint_internal_goal(F/A,Attachment,VarsSusp,Vars,Susp),
7507 ; % more room for improvement?
7508 Attachment = (Attachment1, Attachment2),
7509 gen_occ_allocation(F/A,O,Vars,Susp,Attachment1),
7510 gen_uncond_attach_goal(F/A,Susp,Vars,Attachment2,Generation)
7512 gen_state_cond_call(Susp,F/A,RecursiveCall,Generation,ConditionalRecursiveCall)
7514 gen_occ_allocation(F/A,O,Vars,Susp,Attachment),
7515 ConditionalRecursiveCall = RecursiveCall
7519 ( is_stored_in_guard(F/A, RuleNb) ->
7520 GuardAttachment = Attachment,
7521 BodyAttachment = true
7523 GuardAttachment = true,
7524 BodyAttachment = Attachment % will be true if not observed at all
7538 ConditionalRecursiveCall
7540 add_location(Clause,RuleNb,LocatedClause),
7541 ProgramList = [LocatedClause | ProgramTail].
7543 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7544 %% multi headed propagation
7545 %% prelude + predicates to accumulate the necessary combinations of suspended
7546 %% constraints + predicate to execute the body
7547 propagation_multi_headed(Head,RestHeads,RestIDs,Rule,RuleNb,FA,O,Id,L,T) :-
7548 RestHeads = [First|Rest],
7549 propagation_prelude(Head,RestHeads,Rule,FA,O,Id,L,L1),
7550 extend_id(Id,ExtendedId),
7551 propagation_nested_code(Rest,[First,Head],RestIDs,Rule,RuleNb,FA,O,ExtendedId,L1,T).
7553 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7554 propagation_prelude(Head,[First|Rest],Rule,F/A,O,Id,L,T) :-
7555 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs),
7556 build_head(F,A,Id,VarsSusp,PreludeHead),
7557 get_constraint_mode(F/A,Mode),
7558 head_arg_matches(HeadPairs,Mode,[],FirstMatching,VarDict,[],GroundVars),
7559 Rule = rule(_,_,Guard,Body),
7560 extra_active_delegate_variables(Head,[First,Rest,Guard,Body],VarDict,ExtraVars),
7562 lookup_passive_head(First,[Head],VarDict,GroundVars,FirstSuspGoal,Susps),
7564 gen_occ_allocation(F/A,O,Vars,Susp,CondAllocation),
7566 extend_id(Id,NestedId),
7567 append([Susps|VarsSusp],ExtraVars,NestedVars),
7568 build_head(F,A,[O|NestedId],NestedVars,NestedHead),
7569 NestedCall = NestedHead,
7579 add_dummy_location(Prelude,LocatedPrelude),
7580 L = [LocatedPrelude|T].
7582 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7583 propagation_nested_code([],[CurrentHead|PreHeads],RestIDs,Rule,RuleNb,FA,O,Id,L,T) :-
7584 universal_search_iterator_end([CurrentHead|PreHeads],[],Rule,FA,O,Id,L,L1),
7585 propagation_body(CurrentHead,PreHeads,RestIDs,Rule,RuleNb,FA,O,Id,L1,T).
7587 propagation_nested_code([Head|RestHeads],PreHeads,RestIDs,Rule,RuleNb,FA,O,Id,L,T) :-
7588 universal_search_iterator_end(PreHeads,[Head|RestHeads],Rule,FA,O,Id,L,L1),
7589 universal_search_iterator([Head|RestHeads],PreHeads,Rule,FA,O,Id,L1,L2),
7591 propagation_nested_code(RestHeads,[Head|PreHeads],RestIDs,Rule,RuleNb,FA,O,IncId,L2,T).
7593 %check_fd_lookup_condition(_,_,_,_) :- fail.
7594 check_fd_lookup_condition(F,A,_,_) :-
7595 get_store_type(F/A,global_singleton), !.
7596 check_fd_lookup_condition(F,A,CurrentHead,PreHeads) :-
7597 \+ may_trigger(F/A),
7598 get_functional_dependency(F/A,1,P,K),
7599 copy_term(P-K,CurrentHead-Key),
7600 term_variables(PreHeads,PreVars),
7601 intersect_eq(Key,PreVars,Key),!.
7603 propagation_body(CurrentHead,PreHeads,RestIDs,Rule,RuleNb,F/A,O,Id,L,T) :-
7604 Rule = rule(_,H2,Guard,Body),
7605 gen_var_susp_list_for_b(PreHeads,[CurrentHead,Guard,Body],VarDict1,PreVarsAndSuspsList,FirstVarsSusp,AllSusps,PrevIterators),
7606 flatten(PreVarsAndSuspsList,PreVarsAndSusps),
7607 init(AllSusps,RestSusps),
7608 last(AllSusps,Susp),
7610 gen_var(OtherSusps),
7611 functor(CurrentHead,OtherF,OtherA),
7612 gen_vars(OtherA,OtherVars),
7613 delay_phase_end(validate_store_type_assumptions,
7614 ( static_suspension_term(OtherF/OtherA,Suspension),
7615 get_static_suspension_field(OtherF/OtherA,Suspension,state,active,GetState),
7616 get_static_suspension_term_field(arguments,OtherF/OtherA,Suspension,OtherVars)
7619 % create_get_mutable_ref(active,State,GetMutable),
7621 OtherSusp = Suspension,
7624 ClauseVars = [[OtherSusp|OtherSusps]|PreVarsAndSusps],
7625 build_head(F,A,[O|Id],ClauseVars,ClauseHead),
7626 ( check_fd_lookup_condition(OtherF,OtherA,CurrentHead,PreHeads) -> % iterator (OtherSusps) is empty at runtime
7627 universal_search_iterator_failure_vars(PreHeads,Id,PreVarsAndSuspsList,FirstVarsSusp,PrevIterators,PreVarsAndSusps1,PrevId0),
7628 RecursiveVars = PreVarsAndSusps1
7630 RecursiveVars = [OtherSusps|PreVarsAndSusps],
7636 PrevId = [O|PrevId0]
7638 build_head(F,A,PrevId,RecursiveVars,RecursiveHead),
7639 RecursiveCall = RecursiveHead,
7640 CurrentHead =.. [_|OtherArgs],
7641 pairup(OtherArgs,OtherVars,OtherPairs),
7642 get_constraint_mode(OtherF/OtherA,Mode),
7643 head_arg_matches(OtherPairs,Mode,VarDict1,Matching,VarDict),
7645 different_from_other_susps(CurrentHead,OtherSusp,PreHeads,RestSusps,DiffSuspGoals),
7646 guard_body_copies(Rule,VarDict,GuardCopy,BodyCopy),
7647 get_occurrence(F/A,O,_,ID),
7649 ( is_observed(F/A,O) ->
7650 init(FirstVarsSusp,FirstVars),
7651 gen_uncond_attach_goal(F/A,Susp,FirstVars,Attachment,Generation),
7652 gen_state_cond_call(Susp,F/A,RecursiveCall,Generation,ConditionalRecursiveCall)
7655 ConditionalRecursiveCall = RecursiveCall
7657 ( (is_least_occurrence(RuleNb) ; has_no_history(RuleNb)) ->
7658 NovelProduction = true,
7659 ExtendHistory = true
7660 ; \+ may_trigger(F/A), forall(member(SomeID,RestIDs),(chr_translate:is_passive(RuleNb,SomeID))) ->
7661 NovelProduction = true,
7662 ExtendHistory = true
7664 get_occurrence(F/A,O,_,ID),
7665 use_auxiliary_predicate(novel_production),
7666 use_auxiliary_predicate(extend_history),
7667 does_use_history(F/A,O),
7668 ( named_history(RuleNb,HistoryName,HistoryIDs) ->
7669 ( HistoryIDs == [] ->
7670 empty_named_history_novel_production(HistoryName,NovelProduction),
7671 empty_named_history_extend_history(HistoryName,ExtendHistory)
7673 reverse([OtherSusp|RestSusps],NamedSusps),
7674 named_history_susps(HistoryIDs,[ID|RestIDs],[Susp|NamedSusps],HistorySusps),
7675 HistorySusps = [HistorySusp|_],
7677 ( length(HistoryIDs, 1) ->
7678 ExtendHistory = '$extend_history'(HistorySusp,HistoryName),
7679 NovelProduction = '$novel_production'(HistorySusp,HistoryName)
7681 findall(ConstraintSymbol,(member(SomeID,HistoryIDs),get_occurrence_from_id(ConstraintSymbol,_,RuleNb,SomeID)),ConstraintSymbols),
7682 Tuple =.. [t,HistoryName|HistorySusps]
7687 findall(Functor/Arity,(member(H,H2),functor(H,Functor,Arity)),ConstraintSymbols),
7688 sort([ID|RestIDs],HistoryIDs),
7689 history_susps(RestIDs,[OtherSusp|RestSusps],Susp,ID,HistorySusps),
7690 Tuple =.. [t,RuleNb|HistorySusps]
7693 ( var(NovelProduction) ->
7694 novel_production_calls(ConstraintSymbols,HistoryIDs,HistorySusps,RuleNb,TupleVar,NovelProductions),
7695 ExtendHistory = '$extend_history'(HistorySusp,TupleVar),
7696 NovelProduction = ( TupleVar = Tuple, NovelProductions )
7703 ( chr_pp_flag(debugable,on) ->
7704 Rule = rule(_,_,Guard,Body),
7705 my_term_copy(Guard - Body, VarDict, DebugGuard - DebugBody),
7706 get_occurrence(F/A,O,_,ID),
7707 sort_by_key([Susp,OtherSusp|RestSusps],[ID|RestIDs],KeptSusps),
7708 DebugTry = 'chr debug_event'( try([],KeptSusps,DebugGuard,DebugBody)),
7709 DebugApply = 'chr debug_event'(apply([],KeptSusps,DebugGuard,DebugBody))
7715 ( is_stored_in_guard(F/A, RuleNb) ->
7716 GuardAttachment = Attachment,
7717 BodyAttachment = true
7719 GuardAttachment = true,
7720 BodyAttachment = Attachment % will be true if not observed at all
7736 ConditionalRecursiveCall
7740 add_location(Clause,RuleNb,LocatedClause),
7741 L = [LocatedClause|T].
7743 novel_production_calls([],[],[],_,_,true).
7744 novel_production_calls([ConstraintSymbol|ConstraintSymbols],[ID|IDs],[Suspension|Suspensions],RuleNb,Tuple,(Goal,Goals)) :-
7745 get_occurrence_from_id(ConstraintSymbol,Occurrence,RuleNb,ID),
7746 delay_phase_end(validate_store_type_assumptions,novel_production_call(ConstraintSymbol,Occurrence,'$novel_production'(Suspension,Tuple),Goal)),
7747 novel_production_calls(ConstraintSymbols,IDs,Suspensions,RuleNb,Tuple,Goals).
7749 history_susps(RestIDs,ReversedRestSusps,Susp,ID,HistorySusps) :-
7750 reverse(ReversedRestSusps,RestSusps),
7751 sort_by_key([Susp|RestSusps],[ID|RestIDs],HistorySusps).
7753 named_history_susps([],_,_,[]).
7754 named_history_susps([HistoryID|HistoryIDs],IDs,Susps,[HistorySusp|HistorySusps]) :-
7755 select2(HistoryID,HistorySusp,IDs,Susps,RestIDs,RestSusps), !,
7756 named_history_susps(HistoryIDs,RestIDs,RestSusps,HistorySusps).
7760 gen_var_susp_list_for([Head],Terms,VarDict,HeadVars,VarsSusp,Susp) :-
7763 head_info(Head,A,_Vars,Susp,VarsSusp,HeadPairs),
7764 get_constraint_mode(F/A,Mode),
7765 head_arg_matches(HeadPairs,Mode,[],_,VarDict),
7766 extra_active_delegate_variables(Head,Terms,VarDict,ExtraVars),
7767 append(VarsSusp,ExtraVars,HeadVars).
7768 gen_var_susp_list_for([Head|Heads],Terms,NVarDict,VarsSusps,Rest,Susps) :-
7769 gen_var_susp_list_for(Heads,[Head|Terms],VarDict,Rest,_,_),
7772 head_info(Head,A,_Vars,Susp,_VarsSusp,HeadPairs),
7773 get_constraint_mode(F/A,Mode),
7774 head_arg_matches(HeadPairs,Mode,VarDict,_,NVarDict),
7775 passive_delegate_variables(Head,Heads,Terms,NVarDict,HeadVars),
7776 append(HeadVars,[Susp,Susps|Rest],VarsSusps).
7779 % VarDict for the copies of variables in the original heads
7780 % VarsSuspsList list of lists of arguments for the successive heads
7781 % FirstVarsSusp top level arguments
7782 % SuspList list of all suspensions
7783 % Iterators list of all iterators
7784 gen_var_susp_list_for_b([Head],NextHeads,VarDict,[HeadVars],VarsSusp,[Susp],[]) :-
7787 head_info(Head,A,_Vars,Susp,VarsSusp,Pairs), % make variables for argument positions
7788 get_constraint_mode(F/A,Mode),
7789 head_arg_matches(Pairs,Mode,[],_,VarDict), % copy variables inside arguments, build dictionary
7790 extra_active_delegate_variables(Head,NextHeads,VarDict,ExtraVars), % decide what additional variables are needed
7791 append(VarsSusp,ExtraVars,HeadVars). % add additional variables to head variables
7792 gen_var_susp_list_for_b([Head|Heads],NextHeads,NVarDict,[Vars|RestVars],FirstVarsSusp,[Susp|SuspList],[Susps|Iterators]) :-
7793 gen_var_susp_list_for_b(Heads,[Head|NextHeads],VarDict,RestVars,FirstVarsSusp,SuspList,Iterators),
7796 head_info(Head,A,_Vars,Susp,_VarsSusp,HeadPairs),
7797 get_constraint_mode(F/A,Mode),
7798 head_arg_matches(HeadPairs,Mode,VarDict,_,NVarDict),
7799 passive_delegate_variables(Head,Heads,NextHeads,NVarDict,HeadVars),
7800 append(HeadVars,[Susp,Susps],Vars).
7802 get_prop_inner_loop_vars([Head],NextHeads,HeadVars,VarDict,Susp,Vars,[]) :-
7805 head_info(Head,A,Vars,Susp,VarsSusp,Pairs),
7806 get_constraint_mode(F/A,Mode),
7807 head_arg_matches(Pairs,Mode,[],_,VarDict),
7808 extra_active_delegate_variables(Head,NextHeads,VarDict,ExtraVars),
7809 append(VarsSusp,ExtraVars,HeadVars).
7810 get_prop_inner_loop_vars([Head|Heads],Terms,VarsSusps,NVarDict,MainSusp,MainVars,[Susp|RestSusps]) :-
7811 get_prop_inner_loop_vars(Heads,[Head|Terms],RestVarsSusp,VarDict,MainSusp,MainVars,RestSusps),
7814 head_info(Head,A,_Vars,Susp,_VarsSusp,Pairs),
7815 get_constraint_mode(F/A,Mode),
7816 head_arg_matches(Pairs,Mode,VarDict,_,NVarDict),
7817 passive_delegate_variables(Head,Heads,Terms,NVarDict,HeadVars),
7818 append(HeadVars,[Susp,Susps|RestVarsSusp],VarsSusps).
7820 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7822 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7824 %% | _ \ __ _ ___ ___(_)_ _____ | | | | ___ __ _ __| |
7825 %% | |_) / _` / __/ __| \ \ / / _ \ | |_| |/ _ \/ _` |/ _` |
7826 %% | __/ (_| \__ \__ \ |\ V / __/ | _ | __/ (_| | (_| |
7827 %% |_| \__,_|___/___/_| \_/ \___| |_| |_|\___|\__,_|\__,_|
7830 %% | _ \ ___| |_ _ __(_) _____ ____ _| |
7831 %% | |_) / _ \ __| '__| |/ _ \ \ / / _` | |
7832 %% | _ < __/ |_| | | | __/\ V / (_| | |
7833 %% |_| \_\___|\__|_| |_|\___| \_/ \__,_|_|
7836 %% | _ \ ___ ___ _ __ __| | ___ _ __(_)_ __ __ _
7837 %% | |_) / _ \/ _ \| '__/ _` |/ _ \ '__| | '_ \ / _` |
7838 %% | _ < __/ (_) | | | (_| | __/ | | | | | | (_| |
7839 %% |_| \_\___|\___/|_| \__,_|\___|_| |_|_| |_|\__, |
7842 reorder_heads(RuleNb,Head,RestHeads,RestIDs,NRestHeads,NRestIDs) :-
7843 ( chr_pp_flag(reorder_heads,on), length(RestHeads,Length), Length =< 6 ->
7844 reorder_heads_main(RuleNb,Head,RestHeads,RestIDs,NRestHeads,NRestIDs)
7846 NRestHeads = RestHeads,
7850 reorder_heads_main(RuleNb,Head,RestHeads,RestIDs,NRestHeads,NRestIDs) :-
7851 term_variables(Head,Vars),
7852 InitialData = entry([],[],Vars,RestHeads,RestIDs,RuleNb),
7853 copy_term_nat(InitialData,InitialDataCopy),
7854 a_star(InitialDataCopy,FD^(chr_translate:final_data(FD)),N^EN^C^(chr_translate:expand_data(N,EN,C)),FinalData),
7855 InitialDataCopy = InitialData,
7856 FinalData = entry(RNRestHeads,RNRestIDs,_,_,_,_),
7857 reverse(RNRestHeads,NRestHeads),
7858 reverse(RNRestIDs,NRestIDs).
7860 final_data(Entry) :-
7861 Entry = entry(_,_,_,_,[],_).
7863 expand_data(Entry,NEntry,Cost) :-
7864 Entry = entry(Heads,IDs,Vars,NHeads,NIDs,RuleNb),
7865 select2(Head1,ID1,NHeads,NIDs,NHeads1,NIDs1),
7866 term_variables([Head1|Vars],Vars1),
7867 NEntry = entry([Head1|Heads],[ID1|IDs],Vars1,NHeads1,NIDs1,RuleNb),
7868 order_score(Head1,ID1,Vars,NHeads1,RuleNb,Cost).
7870 % Assigns score to head based on known variables and heads to lookup
7871 order_score(Head,ID,KnownVars,RestHeads,RuleNb,Score) :-
7873 get_store_type(F/A,StoreType),
7874 order_score(StoreType,Head,ID,KnownVars,RestHeads,RuleNb,Score).
7876 order_score(default,Head,_ID,KnownVars,RestHeads,RuleNb,Score) :-
7877 term_variables(Head,HeadVars),
7878 term_variables(RestHeads,RestVars),
7879 order_score_vars(HeadVars,KnownVars,RestVars,Score).
7880 order_score(multi_inthash(Indexes),Head,_ID,KnownVars,RestHeads,RuleNb,Score) :-
7881 order_score_indexes(Indexes,Head,KnownVars,0,Score).
7882 order_score(multi_hash(Indexes),Head,_ID,KnownVars,RestHeads,RuleNb,Score) :-
7883 order_score_indexes(Indexes,Head,KnownVars,0,Score).
7884 order_score(global_ground,Head,ID,KnownVars,RestHeads,RuleNb,Score) :-
7885 term_variables(Head,HeadVars),
7886 term_variables(RestHeads,RestVars),
7887 order_score_vars(HeadVars,KnownVars,RestVars,Score_),
7888 Score is Score_ * 2.
7889 order_score(var_assoc_store(_,_),_,_,_,_,_,1).
7890 order_score(global_singleton,_Head,ID,_KnownVars,_RestHeads,_RuleNb,Score) :-
7891 Score = 1. % guaranteed O(1)
7893 order_score(multi_store(StoreTypes),Head,ID,KnownVars,RestHeads,RuleNb,Score) :-
7894 find_with_var_identity(
7896 t(Head,KnownVars,RestHeads),
7897 ( lists:member(ST,StoreTypes), chr_translate:order_score(ST,Head,ID,KnownVars,RestHeads,RuleNb,S) ),
7900 min_list(Scores,Score).
7901 order_score(identifier_store(Index),Head,ID,KnownVars,RestHeads,RuleNb,Score) :-
7903 order_score(type_indexed_identifier_store(_,_),Head,ID,KnownVars,RestHeads,RuleNb,Score) :-
7906 order_score_indexes([],_,_,Score,NScore) :-
7907 Score > 0, NScore = 100.
7908 order_score_indexes([I|Is],Head,KnownVars,Score,NScore) :-
7909 multi_hash_key_args(I,Head,Args),
7910 ( forall(Arg,Args,memberchk_eq(Arg,KnownVars)) ->
7915 order_score_indexes(Is,Head,KnownVars,Score1,NScore).
7917 order_score_vars(Vars,KnownVars,RestVars,Score) :-
7918 order_score_count_vars(Vars,KnownVars,RestVars,K-R-O),
7922 Score is max(10 - K,0)
7924 Score is max(10 - R,1) * 10
7926 Score is max(10-O,1) * 100
7928 order_score_count_vars([],_,_,0-0-0).
7929 order_score_count_vars([V|Vs],KnownVars,RestVars,NK-NR-NO) :-
7930 order_score_count_vars(Vs,KnownVars,RestVars,K-R-O),
7931 ( memberchk_eq(V,KnownVars) ->
7934 ; memberchk_eq(V,RestVars) ->
7942 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7944 %% |_ _|_ __ | (_)_ __ (_)_ __ __ _
7945 %% | || '_ \| | | '_ \| | '_ \ / _` |
7946 %% | || | | | | | | | | | | | | (_| |
7947 %% |___|_| |_|_|_|_| |_|_|_| |_|\__, |
7951 create_get_mutable_ref(V,M,GM) :- GM = (M = mutable(V)).
7952 create_get_mutable(V,M,GM) :- M = mutable(V), GM = true.
7956 %% create_get_mutable(V,M,GM) :- GM = get_mutable(V,M).
7957 %% create_get_mutable_ref(V,M,GM) :- GM = get_mutable(V,M).
7960 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7962 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7964 %% | | | | |_(_) (_) |_ _ _
7965 %% | | | | __| | | | __| | | |
7966 %% | |_| | |_| | | | |_| |_| |
7967 %% \___/ \__|_|_|_|\__|\__, |
7970 % Create a fresh variable.
7973 % Create =N= fresh variables.
7977 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs) :-
7978 vars_susp(A,Vars,Susp,VarsSusp),
7980 pairup(Args,Vars,HeadPairs).
7982 inc_id([N|Ns],[O|Ns]) :-
7984 dec_id([N|Ns],[M|Ns]) :-
7987 extend_id(Id,[0|Id]).
7989 next_id([_,N|Ns],[O|Ns]) :-
7992 % return clause Head
7993 % for F/A constraint symbol, predicate identifier Id and arguments Head
7994 build_head(F,A,Id,Args,Head) :-
7995 buildName(F,A,Id,Name),
7996 ( (chr_pp_flag(debugable,on) ; is_stored(F/A), ( has_active_occurrence(F/A) ; chr_pp_flag(late_allocation,off)),
7997 ( may_trigger(F/A) ;
7998 get_allocation_occurrence(F/A,AO),
7999 get_max_occurrence(F/A,MO),
8001 Head =.. [Name|Args]
8003 init(Args,ArgsWOSusp), % XXX not entirely correct!
8004 Head =.. [Name|ArgsWOSusp]
8007 % return predicate name Result
8008 % for Fct/Aty constraint symbol and predicate identifier List
8009 buildName(Fct,Aty,List,Result) :-
8010 ( (chr_pp_flag(debugable,on) ; (once((is_stored(Fct/Aty), ( has_active_occurrence(Fct/Aty) ; chr_pp_flag(late_allocation,off)),
8011 ( may_trigger(Fct/Aty) ; get_allocation_occurrence(Fct/Aty,AO), get_max_occurrence(Fct/Aty,MO),
8012 MO >= AO ) ; List \= [0])) ) ) ->
8013 atom_concat(Fct, '___' ,FctSlash),
8014 atomic_concat(FctSlash,Aty,FctSlashAty),
8015 buildName_(List,FctSlashAty,Result)
8020 buildName_([],Name,Name).
8021 buildName_([N|Ns],Name,Result) :-
8022 buildName_(Ns,Name,Name1),
8023 atom_concat(Name1,'__',NameDash), % '_' is a char :-(
8024 atomic_concat(NameDash,N,Result).
8026 vars_susp(A,Vars,Susp,VarsSusp) :-
8028 append(Vars,[Susp],VarsSusp).
8030 or_pattern(Pos,Pat) :-
8032 Pat is 1 << Pow. % was 2 ** X
8034 and_pattern(Pos,Pat) :-
8036 Y is 1 << X, % was 2 ** X
8037 Pat is (-1)*(Y + 1).
8039 make_name(Prefix,F/A,Name) :-
8040 atom_concat_list([Prefix,F,'___',A],Name).
8042 %===============================================================================
8043 % Attribute for attributed variables
8045 make_attr(N,Mask,SuspsList,Attr) :-
8046 length(SuspsList,N),
8047 Attr =.. [v,Mask|SuspsList].
8049 get_all_suspensions2(N,Attr,SuspensionsList) :-
8050 chr_pp_flag(dynattr,off), !,
8051 make_attr(N,_,SuspensionsList,Attr).
8054 get_all_suspensions2(N,Attr,Goal,SuspensionsList) :-
8055 % writeln(get_all_suspensions2),
8056 length(SuspensionsList,N),
8057 Goal = 'chr all_suspensions'(SuspensionsList,1,Attr).
8061 normalize_attr(Attr,NormalGoal,NormalAttr) :-
8062 % writeln(normalize_attr),
8063 NormalGoal = 'chr normalize_attr'(Attr,NormalAttr).
8065 get_suspensions(N,Position,TAttr,(TAttr = Attr),Suspensions) :-
8066 chr_pp_flag(dynattr,off), !,
8067 make_attr(N,_,SuspsList,Attr),
8068 nth1(Position,SuspsList,Suspensions).
8071 get_suspensions(N,Position,TAttr,Goal,Suspensions) :-
8072 % writeln(get_suspensions),
8074 ( memberchk(Position-Suspensions,TAttr) ->
8080 %-------------------------------------------------------------------------------
8081 % +N: number of constraint symbols
8082 % +Suspension: source-level variable, for suspension
8083 % +Position: constraint symbol number
8084 % -Attr: source-level term, for new attribute
8085 singleton_attr(N,Suspension,Position,Attr) :-
8086 chr_pp_flag(dynattr,off), !,
8087 or_pattern(Position,Pattern),
8088 make_attr(N,Pattern,SuspsList,Attr),
8089 nth1(Position,SuspsList,[Suspension]),
8090 chr_delete(SuspsList,[Suspension],RestSuspsList),
8091 set_elems(RestSuspsList,[]).
8094 singleton_attr(N,Suspension,Position,Attr) :-
8095 % writeln(singleton_attr),
8096 Attr = [Position-[Suspension]].
8098 %-------------------------------------------------------------------------------
8099 % +N: number of constraint symbols
8100 % +Suspension: source-level variable, for suspension
8101 % +Position: constraint symbol number
8102 % +TAttr: source-level variable, for old attribute
8103 % -Goal: goal for creating new attribute
8104 % -NTAttr: source-level variable, for new attribute
8105 add_attr(N,Suspension,Position,TAttr,Goal,NTAttr) :-
8106 chr_pp_flag(dynattr,off), !,
8107 make_attr(N,Mask,SuspsList,Attr),
8108 or_pattern(Position,Pattern),
8109 nth1(Position,SuspsList,Susps),
8110 substitute_eq(Susps,SuspsList,[Suspension|Susps],SuspsList1),
8111 make_attr(N,Mask,SuspsList1,NewAttr1),
8112 substitute_eq(Susps,SuspsList,[Suspension],SuspsList2),
8113 make_attr(N,NewMask,SuspsList2,NewAttr2),
8116 ( Mask /\ Pattern =:= Pattern ->
8119 NewMask is Mask \/ Pattern,
8125 add_attr(N,Suspension,Position,TAttr,Goal,NTAttr) :-
8126 % writeln(add_attr),
8128 ( 'chr select'(TAttr,Position-Suspensions,RAttr) ->
8129 NTAttr = [Position-[Suspension|Suspensions]|RAttr]
8131 NTAttr = [Position-[Suspension]|TAttr]
8134 rem_attr(N,Var,Suspension,Position,TAttr,Goal) :-
8135 chr_pp_flag(dynattr,off), !,
8136 or_pattern(Position,Pattern),
8137 and_pattern(Position,DelPattern),
8138 make_attr(N,Mask,SuspsList,Attr),
8139 nth1(Position,SuspsList,Susps),
8140 substitute_eq(Susps,SuspsList,[],SuspsList1),
8141 make_attr(N,NewMask,SuspsList1,Attr1),
8142 substitute_eq(Susps,SuspsList,NewSusps,SuspsList2),
8143 make_attr(N,Mask,SuspsList2,Attr2),
8144 get_target_module(Mod),
8147 ( Mask /\ Pattern =:= Pattern ->
8148 'chr sbag_del_element'(Susps,Suspension,NewSusps),
8150 NewMask is Mask /\ DelPattern,
8154 put_attr(Var,Mod,Attr1)
8157 put_attr(Var,Mod,Attr2)
8165 rem_attr(N,Var,Suspension,Position,TAttr,Goal) :-
8166 % writeln(rem_attr),
8167 get_target_module(Mod),
8169 ( 'chr select'(TAttr,Position-Suspensions,RAttr) ->
8170 'chr sbag_del_element'(Suspensions,Suspension,NSuspensions),
8171 ( NSuspensions == [] ->
8175 put_attr(Var,Mod,RAttr)
8178 put_attr(Var,Mod,[Position-NSuspensions|RAttr])
8184 %-------------------------------------------------------------------------------
8185 % +N: number of constraint symbols
8186 % +TAttr1: source-level variable, for attribute
8187 % +TAttr2: source-level variable, for other attribute
8188 % -Goal: goal for merging the two attributes
8189 % -Attr: source-level term, for merged attribute
8190 merge_attributes(N,TAttr1,TAttr2,Goal,Attr) :-
8191 chr_pp_flag(dynattr,off), !,
8192 make_attr(N,Mask1,SuspsList1,Attr1),
8193 merge_attributes2(N,Mask1,SuspsList1,TAttr2,Goal2,Attr),
8200 merge_attributes(N,TAttr1,TAttr2,Goal,Attr) :-
8201 % writeln(merge_attributes),
8203 sort(TAttr1,Sorted1),
8204 sort(TAttr2,Sorted2),
8205 'chr new_merge_attributes'(Sorted1,Sorted2,Attr)
8209 %-------------------------------------------------------------------------------
8210 % +N: number of constraint symbols
8212 % +SuspsList1: static term, for suspensions list
8213 % +TAttr2: source-level variable, for other attribute
8214 % -Goal: goal for merging the two attributes
8215 % -Attr: source-level term, for merged attribute
8216 merge_attributes2(N,Mask1,SuspsList1,TAttr2,Goal,Attr) :-
8217 make_attr(N,Mask2,SuspsList2,Attr2),
8218 bagof(G,X ^ Y ^ SY ^ M ^ (member2(SuspsList1,SuspsList2,X-Y),G = (sort(Y,SY),'chr merge_attributes'(X,SY,M))),Gs),
8219 list2conj(Gs,SortGoals),
8220 bagof(MS,A ^ B ^ C ^ member((A,'chr merge_attributes'(B,C,MS)),Gs), SuspsList),
8221 make_attr(N,Mask,SuspsList,Attr),
8225 Mask is Mask1 \/ Mask2
8229 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8230 % Storetype dependent lookup
8232 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8233 %% lookup_passive_head(+Head,+PreviousVars,+RenamingVarDict,
8234 %% -Goal,-SuspensionList) is det.
8236 % Create a universal lookup goal for given head.
8237 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8238 lookup_passive_head(Head,PreJoin,VarDict,Goal,AllSusps) :-
8240 get_store_type(F/A,StoreType),
8241 lookup_passive_head(StoreType,Head,PreJoin,VarDict,[],Goal,AllSusps).
8243 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8244 %% lookup_passive_head(+Head,+PreviousVars,+RenamingVarDict,+GroundVars,
8245 %% -Goal,-SuspensionList) is det.
8247 % Create a universal lookup goal for given head.
8248 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8249 lookup_passive_head(Head,PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
8251 get_store_type(F/A,StoreType),
8252 lookup_passive_head(StoreType,Head,PreJoin,VarDict,GroundVars,Goal,AllSusps).
8254 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8255 %% lookup_passive_head(+StoreType,+Head,+PreviousVars,+RenamingVarDict,
8256 %% +GroundVars,-Goal,-SuspensionList) is det.
8258 % Create a universal lookup goal for given head.
8259 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8260 lookup_passive_head(default,Head,PreJoin,VarDict,_,Goal,AllSusps) :-
8262 passive_head_via(Head,PreJoin,VarDict,Goal,AllSusps),
8263 update_store_type(F/A,default).
8264 lookup_passive_head(multi_inthash(Indexes),Head,_PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
8265 hash_lookup_passive_head(inthash,Indexes,Head,VarDict,GroundVars,Goal,AllSusps,_).
8266 lookup_passive_head(multi_hash(Indexes),Head,_PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
8267 hash_lookup_passive_head(hash,Indexes,Head,VarDict,GroundVars,Goal,AllSusps,_).
8268 lookup_passive_head(global_ground,Head,_PreJoin,_VarDict,_,Goal,AllSusps) :-
8270 global_ground_store_name(F/A,StoreName),
8271 make_get_store_goal(StoreName,AllSusps,Goal), % Goal = nb_getval(StoreName,AllSusps),
8272 update_store_type(F/A,global_ground).
8273 lookup_passive_head(var_assoc_store(VarIndex,KeyIndex),Head,_PreJoin,VarDict,_,Goal,AllSusps) :-
8274 arg(VarIndex,Head,OVar),
8275 arg(KeyIndex,Head,OKey),
8276 translate([OVar,OKey],VarDict,[Var,Key]),
8277 get_target_module(Module),
8279 get_attr(Var,Module,AssocStore),
8280 lookup_assoc_store(AssocStore,Key,AllSusps)
8282 lookup_passive_head(global_singleton,Head,_PreJoin,_VarDict,_,Goal,AllSusps) :-
8284 global_singleton_store_name(F/A,StoreName),
8285 make_get_store_goal(StoreName,Susp,GetStoreGoal),
8286 Goal = (GetStoreGoal,Susp \== [],AllSusps = [Susp]),
8287 update_store_type(F/A,global_singleton).
8288 lookup_passive_head(multi_store(StoreTypes),Head,PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
8290 member(ST,StoreTypes),
8291 lookup_passive_head(ST,Head,PreJoin,VarDict,GroundVars,Goal,AllSusps)
8293 lookup_passive_head(identifier_store(Index),Head,PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
8295 arg(Index,Head,Var),
8296 translate([Var],VarDict,[KeyVar]),
8297 delay_phase_end(validate_store_type_assumptions,
8298 identifier_lookup(F/A,Index,AllSusps,KeyVar,Goal)
8300 update_store_type(F/A,identifier_store(Index)),
8301 get_identifier_index(F/A,Index,_).
8302 lookup_passive_head(type_indexed_identifier_store(Index,IndexType),Head,PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
8304 arg(Index,Head,Var),
8306 translate([Var],VarDict,[KeyVar]),
8308 ; ground(Var), Var = '$chr_identifier_match'(ActualVar,_) ->
8309 lookup_identifier_atom(IndexType,ActualVar,KeyVar,LookupGoal),
8310 Goal = (LookupGoal,StructGoal)
8312 delay_phase_end(validate_store_type_assumptions,
8313 type_indexed_identifier_lookup(F/A,Index,IndexType,AllSusps,KeyVar,StructGoal)
8315 update_store_type(F/A,type_indexed_identifier_store(Index,IndexType)),
8316 get_type_indexed_identifier_index(IndexType,F/A,Index,_).
8318 identifier_lookup(C,Index,AllSusps,KeyVar,Goal) :-
8319 get_identifier_size(ISize),
8320 functor(Struct,struct,ISize),
8321 get_identifier_index(C,Index,IIndex),
8322 arg(IIndex,Struct,AllSusps),
8323 Goal = (KeyVar = Struct).
8325 type_indexed_identifier_lookup(C,Index,IndexType,AllSusps,KeyVar,Goal) :-
8326 type_indexed_identifier_structure(IndexType,Struct),
8327 get_type_indexed_identifier_index(IndexType,C,Index,IIndex),
8328 arg(IIndex,Struct,AllSusps),
8329 Goal = (KeyVar = Struct).
8331 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8332 %% hash_lookup_passive_head(+StoreType,+Indexes,+Head,+RenamingVarDict,
8333 %% +GroundVars,-Goal,-SuspensionList,-Index) is det.
8335 % Create a universal hash lookup goal for given head.
8336 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8337 hash_lookup_passive_head(HashType,Indexes,Head,VarDict,GroundVars,Goal,AllSusps,Index) :-
8339 member(Index,Indexes),
8340 multi_hash_key_args(Index,Head,KeyArgs),
8342 translate(KeyArgs,VarDict,KeyArgCopies)
8344 ground(KeyArgs), KeyArgCopies = KeyArgs
8347 ( KeyArgCopies = [KeyCopy] ->
8350 KeyCopy =.. [k|KeyArgCopies]
8353 multi_hash_lookup_goal(F/A,HashType,Index,KeyCopy,AllSusps,LookupGoal),
8355 check_ground(GroundVars,KeyArgs,OriginalGroundCheck),
8356 my_term_copy(OriginalGroundCheck,VarDict,GroundCheck),
8358 Goal = (GroundCheck,LookupGoal),
8360 ( HashType == inthash ->
8361 update_store_type(F/A,multi_inthash([Index]))
8363 update_store_type(F/A,multi_hash([Index]))
8366 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8367 %% existential_lookup(+StoreType,+Head,+PrevVariablesHead,+RenamingVarDict,
8368 %% +GroundVariables,-SuspensionTerm,-Goal,-SuspVar,
8369 %% +VarArgDict,-NewVarArgDict) is det.
8371 % Create existential lookup goal for given head.
8372 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8373 existential_lookup(var_assoc_store(VarIndex,KeyIndex),Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,Pairs) :- !,
8374 lookup_passive_head(var_assoc_store(VarIndex,KeyIndex),Head,PreJoin,VarDict,GroundVars,UniversalGoal,AllSusps),
8375 sbag_member_call(Susp,AllSusps,Sbag),
8377 delay_phase_end(validate_store_type_assumptions,
8378 ( static_suspension_term(F/A,SuspTerm),
8379 get_static_suspension_field(F/A,SuspTerm,state,active,GetState)
8388 existential_lookup(global_singleton,Head,_PreJoin,_VarDict,_,SuspTerm,Goal,Susp,Pairs,Pairs) :- !,
8390 global_singleton_store_name(F/A,StoreName),
8391 make_get_store_goal(StoreName,Susp,GetStoreGoal),
8393 GetStoreGoal, % nb_getval(StoreName,Susp),
8397 update_store_type(F/A,global_singleton).
8398 existential_lookup(multi_store(StoreTypes),Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :- !,
8400 member(ST,StoreTypes),
8401 existential_lookup(ST,Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs)
8403 existential_lookup(multi_inthash(Indexes),Head,_,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :- !,
8404 existential_hash_lookup(inthash,Indexes,Head,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs).
8405 existential_lookup(multi_hash(Indexes),Head,_,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :- !,
8406 existential_hash_lookup(hash,Indexes,Head,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs).
8407 existential_lookup(identifier_store(Index),Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :- !,
8408 lookup_passive_head(identifier_store(Index),Head,PreJoin,VarDict,GroundVars,LookupGoal,AllSusps),
8409 hash_index_filter(Pairs,Index,NPairs),
8412 ( check_fd_lookup_condition(F,A,Head,KeyArgs) ->
8413 Sbag = (AllSusps = [Susp])
8415 sbag_member_call(Susp,AllSusps,Sbag)
8417 delay_phase_end(validate_store_type_assumptions,
8418 ( static_suspension_term(F/A,SuspTerm),
8419 get_static_suspension_field(F/A,SuspTerm,state,active,GetState)
8425 Susp = SuspTerm, % not inlined
8428 existential_lookup(type_indexed_identifier_store(Index,IndexType),Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :- !,
8429 lookup_passive_head(type_indexed_identifier_store(Index,IndexType),Head,PreJoin,VarDict,GroundVars,LookupGoal,AllSusps),
8430 hash_index_filter(Pairs,Index,NPairs),
8433 ( check_fd_lookup_condition(F,A,Head,KeyArgs) ->
8434 Sbag = (AllSusps = [Susp])
8436 sbag_member_call(Susp,AllSusps,Sbag)
8438 delay_phase_end(validate_store_type_assumptions,
8439 ( static_suspension_term(F/A,SuspTerm),
8440 get_static_suspension_field(F/A,SuspTerm,state,active,GetState)
8446 Susp = SuspTerm, % not inlined
8449 existential_lookup(StoreType,Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,Pairs) :-
8450 lookup_passive_head(StoreType,Head,PreJoin,VarDict,GroundVars,UGoal,Susps),
8451 sbag_member_call(Susp,Susps,Sbag),
8453 delay_phase_end(validate_store_type_assumptions,
8454 ( static_suspension_term(F/A,SuspTerm),
8455 get_static_suspension_field(F/A,SuspTerm,state,active,GetState)
8461 Susp = SuspTerm, % not inlined
8465 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8466 %% existential_hash_lookup(+StoreType,+Indexes,+Head,+RenamingVarDict,
8467 %% +GroundVariables,-SuspensionTerm,-Goal,-SuspVar,
8468 %% +VarArgDict,-NewVarArgDict) is det.
8470 % Create existential hash lookup goal for given head.
8471 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8472 existential_hash_lookup(HashType,Indexes,Head,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :-
8473 hash_lookup_passive_head(HashType,Indexes,Head,VarDict,GroundVars,LookupGoal,AllSusps,Index),
8475 hash_index_filter(Pairs,Index,NPairs),
8478 ( check_fd_lookup_condition(F,A,Head,KeyArgs) ->
8479 Sbag = (AllSusps = [Susp])
8481 sbag_member_call(Susp,AllSusps,Sbag)
8483 delay_phase_end(validate_store_type_assumptions,
8484 ( static_suspension_term(F/A,SuspTerm),
8485 get_static_suspension_field(F/A,SuspTerm,state,active,GetState)
8491 Susp = SuspTerm, % not inlined
8495 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8496 %% hash_index_filter(+Pairs,+Index,-NPairs) is det.
8498 % Filter out pairs already covered by given hash index.
8499 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8500 hash_index_filter(Pairs,Index,NPairs) :-
8506 hash_index_filter(Pairs,NIndex,1,NPairs).
8508 hash_index_filter([],_,_,[]).
8509 hash_index_filter([P|Ps],Index,N,NPairs) :-
8514 hash_index_filter(Ps,[I|Is],NN,NPs)
8516 hash_index_filter(Ps,Is,NN,NPairs)
8522 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8523 %------------------------------------------------------------------------------%
8524 %% assume_constraint_stores(+ConstraintSymbols) is det.
8526 % Compute all constraint store types that are possible for the given
8527 % =ConstraintSymbols=.
8528 %------------------------------------------------------------------------------%
8529 assume_constraint_stores([]).
8530 assume_constraint_stores([C|Cs]) :-
8531 ( chr_pp_flag(debugable,off),
8532 ( only_ground_indexed_arguments(C) ; chr_pp_flag(mixed_stores,on) ),
8534 get_store_type(C,default) ->
8535 get_indexed_arguments(C,AllIndexedArgs),
8536 get_constraint_mode(C,Modes),
8537 findall(Index,(member(Index,AllIndexedArgs),
8538 nth(Index,Modes,+)),IndexedArgs),
8539 length(IndexedArgs,NbIndexedArgs),
8540 % Construct Index Combinations
8541 ( NbIndexedArgs > 10 ->
8542 findall([Index],member(Index,IndexedArgs),Indexes)
8544 findall(Index,(sublist(Index,IndexedArgs), Index \== []),UnsortedIndexes),
8545 predsort(longer_list,UnsortedIndexes,Indexes)
8547 % EXPERIMENTAL HEURISTIC
8549 % member(Arg1,IndexedArgs),
8550 % member(Arg2,IndexedArgs),
8552 % sort([Arg1,Arg2], Index)
8553 % ), UnsortedIndexes),
8554 % predsort(longer_list,UnsortedIndexes,Indexes),
8556 ( get_functional_dependency(C,1,Pattern,Key),
8557 all_distinct_var_args(Pattern), Key == [] ->
8558 assumed_store_type(C,global_singleton)
8559 ; ( only_ground_indexed_arguments(C) ; NbIndexedArgs > 0 ) ->
8560 get_constraint_type_det(C,ArgTypes),
8561 partition_indexes(Indexes,ArgTypes,HashIndexes,IntHashIndexes,IdentifierIndexes,CompoundIdentifierIndexes),
8563 ( IntHashIndexes = [] ->
8566 Stores = [multi_inthash(IntHashIndexes)|Stores1]
8568 ( HashIndexes = [] ->
8571 Stores1 = [multi_hash(HashIndexes)|Stores2]
8573 ( IdentifierIndexes = [] ->
8576 maplist(wrap_in_functor(identifier_store),IdentifierIndexes,WrappedIdentifierIndexes),
8577 append(WrappedIdentifierIndexes,Stores3,Stores2)
8579 append(CompoundIdentifierIndexes,Stores4,Stores3),
8580 ( only_ground_indexed_arguments(C)
8581 -> Stores4 = [global_ground]
8582 ; Stores4 = [default]
8584 assumed_store_type(C,multi_store(Stores))
8590 assume_constraint_stores(Cs).
8592 %------------------------------------------------------------------------------%
8593 %% partition_indexes(+Indexes,+Types,
8594 %% -HashIndexes,-IntHashIndexes,-IdentifierIndexes) is det.
8595 %------------------------------------------------------------------------------%
8596 partition_indexes([],_,[],[],[],[]).
8597 partition_indexes([Index|Indexes],Types,HashIndexes,IntHashIndexes,IdentifierIndexes,CompoundIdentifierIndexes) :-
8600 unalias_type(Type,UnAliasedType),
8601 UnAliasedType == chr_identifier ->
8602 IdentifierIndexes = [I|RIdentifierIndexes],
8603 IntHashIndexes = RIntHashIndexes,
8604 HashIndexes = RHashIndexes,
8605 CompoundIdentifierIndexes = RCompoundIdentifierIndexes
8608 unalias_type(Type,UnAliasedType),
8609 nonvar(UnAliasedType),
8610 UnAliasedType = chr_identifier(IndexType) ->
8611 CompoundIdentifierIndexes = [type_indexed_identifier_store(I,IndexType)|RCompoundIdentifierIndexes],
8612 IdentifierIndexes = RIdentifierIndexes,
8613 IntHashIndexes = RIntHashIndexes,
8614 HashIndexes = RHashIndexes
8617 unalias_type(Type,UnAliasedType),
8618 UnAliasedType == dense_int ->
8619 IntHashIndexes = [Index|RIntHashIndexes],
8620 HashIndexes = RHashIndexes,
8621 IdentifierIndexes = RIdentifierIndexes,
8622 CompoundIdentifierIndexes = RCompoundIdentifierIndexes
8625 unalias_type(Type,UnAliasedType),
8626 nonvar(UnAliasedType),
8627 UnAliasedType = chr_identifier(_) ->
8628 % don't use chr_identifiers in hash indexes
8629 IntHashIndexes = RIntHashIndexes,
8630 HashIndexes = RHashIndexes,
8631 IdentifierIndexes = RIdentifierIndexes,
8632 CompoundIdentifierIndexes = RCompoundIdentifierIndexes
8634 IntHashIndexes = RIntHashIndexes,
8635 HashIndexes = [Index|RHashIndexes],
8636 IdentifierIndexes = RIdentifierIndexes,
8637 CompoundIdentifierIndexes = RCompoundIdentifierIndexes
8639 partition_indexes(Indexes,Types,RHashIndexes,RIntHashIndexes,RIdentifierIndexes,RCompoundIdentifierIndexes).
8641 longer_list(R,L1,L2) :-
8651 all_distinct_var_args(Term) :-
8653 copy_term_nat(Args,NArgs),
8654 all_distinct_var_args_(NArgs).
8656 all_distinct_var_args_([]).
8657 all_distinct_var_args_([X|Xs]) :-
8660 all_distinct_var_args_(Xs).
8662 get_indexed_arguments(C,IndexedArgs) :-
8664 get_indexed_arguments(1,A,C,IndexedArgs).
8666 get_indexed_arguments(I,N,C,L) :-
8669 ; ( is_indexed_argument(C,I) ->
8675 get_indexed_arguments(J,N,C,T)
8678 validate_store_type_assumptions([]).
8679 validate_store_type_assumptions([C|Cs]) :-
8680 validate_store_type_assumption(C),
8681 validate_store_type_assumptions(Cs).
8683 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8684 % new code generation
8685 universal_search_iterator_end([CurrentHead|PrevHeads],NextHeads,Rule,F/A,O,Id,L,T) :-
8686 Rule = rule(H1,_,Guard,Body),
8687 gen_var_susp_list_for_b(PrevHeads,[CurrentHead,NextHeads,Guard,Body],_,VarsAndSuspsList,FirstVarsSusp,_,PrevIterators),
8688 universal_search_iterator_failure_vars(PrevHeads,Id,VarsAndSuspsList,FirstVarsSusp,PrevIterators,PrevVarsAndSusps,PrevId0),
8689 flatten(VarsAndSuspsList,VarsAndSusps),
8690 Vars = [ [] | VarsAndSusps],
8691 build_head(F,A,[O|Id],Vars,Head),
8695 PrevId = [O|PrevId0]
8697 build_head(F,A,PrevId,PrevVarsAndSusps,PredecessorCall),
8698 Clause = ( Head :- PredecessorCall),
8699 add_dummy_location(Clause,LocatedClause),
8700 L = [LocatedClause | T].
8702 % functor(CurrentHead,CF,CA),
8703 % check_fd_lookup_condition(CF,CA,CurrentHead,PrevHeads) ->
8706 % gen_var_susp_list_for_b(PrevHeads,[CurrentHead,NextHeads,Guard,Body],_,VarsAndSuspsList,FirstVarsSusp,_,PrevIterators),
8707 % universal_search_iterator_failure_vars(PrevHeads,Id,VarsAndSuspsList,FirstVarsSusp,PrevIterators,PrevVarsAndSusps,PrevId),
8708 % flatten(VarsAndSuspsList,VarsAndSusps),
8709 % Vars = [ [] | VarsAndSusps],
8710 % build_head(F,A,Id,Vars,Head),
8711 % build_head(F,A,PrevId,PrevVarsAndSusps,PredecessorCall),
8712 % Clause = ( Head :- PredecessorCall),
8716 % skips back intelligently over global_singleton lookups
8717 universal_search_iterator_failure_vars(PrevHeads,Id,VarsAndSuspsList,BaseCallArgs,PrevIterators,PrevVarsAndSusps,PrevId) :-
8719 % TOM: add partial success continuation optimization here!
8721 PrevVarsAndSusps = BaseCallArgs
8723 VarsAndSuspsList = [_|AllButFirstList],
8725 ( PrevHeads = [PrevHead|PrevHeads1],
8726 functor(PrevHead,F,A),
8727 check_fd_lookup_condition(F,A,PrevHead,PrevHeads1) ->
8728 PrevIterators = [_|PrevIterators1],
8729 universal_search_iterator_failure_vars(PrevHeads1,PrevId1,AllButFirstList,BaseCallArgs,PrevIterators1,PrevVarsAndSusps,PrevId)
8732 flatten(AllButFirstList,AllButFirst),
8733 PrevIterators = [PrevIterator|_],
8734 PrevVarsAndSusps = [PrevIterator|AllButFirst]
8738 universal_search_iterator([NextHead|RestHeads],[CurrentHead|PreHeads],Rule,F/A,O,Id,L,T) :-
8739 Rule = rule(_,_,Guard,Body),
8740 gen_var_susp_list_for_b(PreHeads,[CurrentHead,NextHead,RestHeads,Guard,Body],VarDict,PreVarsAndSuspsList,FirstVarsSusp,AllSusps,PrevIterators),
8741 init(AllSusps,PreSusps),
8742 flatten(PreVarsAndSuspsList,PreVarsAndSusps),
8743 gen_var(OtherSusps),
8744 functor(CurrentHead,OtherF,OtherA),
8745 gen_vars(OtherA,OtherVars),
8746 head_info(CurrentHead,OtherA,OtherVars,OtherSusp,_VarsSusp,HeadPairs),
8747 get_constraint_mode(OtherF/OtherA,Mode),
8748 head_arg_matches(HeadPairs,Mode,VarDict,FirstMatching,VarDict1),
8750 delay_phase_end(validate_store_type_assumptions,
8751 ( static_suspension_term(OtherF/OtherA,OtherSuspension),
8752 get_static_suspension_field(OtherF/OtherA,OtherSuspension,state,active,GetState),
8753 get_static_suspension_term_field(arguments,OtherF/OtherA,OtherSuspension,OtherVars)
8757 different_from_other_susps(CurrentHead,OtherSusp,PreHeads,PreSusps,DiffSuspGoals),
8758 % create_get_mutable_ref(active,State,GetMutable),
8760 OtherSusp = OtherSuspension,
8765 add_heads_ground_variables([CurrentHead|PreHeads],[],GroundVars),
8766 lookup_passive_head(NextHead,[CurrentHead|PreHeads],VarDict1,GroundVars,NextSuspGoal,NextSusps),
8767 inc_id(Id,NestedId),
8768 ClauseVars = [[OtherSusp|OtherSusps]|PreVarsAndSusps],
8769 build_head(F,A,[O|Id],ClauseVars,ClauseHead),
8770 passive_delegate_variables(CurrentHead,PreHeads,[NextHead,RestHeads,Guard,Body],VarDict1,CurrentHeadVars),
8771 append([NextSusps|CurrentHeadVars],[OtherSusp,OtherSusps|PreVarsAndSusps],NestedVars),
8772 build_head(F,A,[O|NestedId],NestedVars,NestedHead),
8774 ( check_fd_lookup_condition(OtherF,OtherA,CurrentHead,PreHeads) -> % iterator (OtherSusps) is empty at runtime
8775 universal_search_iterator_failure_vars(PreHeads,Id,PreVarsAndSuspsList,FirstVarsSusp,PrevIterators,PreVarsAndSusps1,PrevId0),
8776 RecursiveVars = PreVarsAndSusps1
8778 RecursiveVars = [OtherSusps|PreVarsAndSusps],
8784 PrevId = [O|PrevId0]
8786 build_head(F,A,PrevId,RecursiveVars,RecursiveHead),
8797 add_dummy_location(Clause,LocatedClause),
8798 L = [LocatedClause|T].
8800 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8802 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8803 % Observation Analysis
8808 % Analysis based on Abstract Interpretation paper.
8811 % stronger analysis domain [research]
8814 initial_call_pattern/1,
8816 call_pattern_worker/1,
8817 final_answer_pattern/2,
8818 abstract_constraints/1,
8822 ai_observed_internal/2,
8824 ai_not_observed_internal/2,
8828 ai_observation_gather_results/0.
8830 :- chr_type abstract_domain ---> odom(program_point,list(constraint)).
8831 :- chr_type program_point == any.
8833 :- chr_option(mode,initial_call_pattern(+)).
8834 :- chr_option(type_declaration,call_pattern(abstract_domain)).
8836 :- chr_option(mode,call_pattern(+)).
8837 :- chr_option(type_declaration,call_pattern(abstract_domain)).
8839 :- chr_option(mode,call_pattern_worker(+)).
8840 :- chr_option(type_declaration,call_pattern_worker(abstract_domain)).
8842 :- chr_option(mode,final_answer_pattern(+,+)).
8843 :- chr_option(type_declaration,final_answer_pattern(abstract_domain,abstract_domain)).
8845 :- chr_option(mode,abstract_constraints(+)).
8846 :- chr_option(type_declaration,abstract_constraints(list)).
8848 :- chr_option(mode,depends_on(+,+)).
8849 :- chr_option(type_declaration,depends_on(abstract_domain,abstract_domain)).
8851 :- chr_option(mode,depends_on_as(+,+,+)).
8852 :- chr_option(mode,depends_on_ap(+,+,+,+)).
8853 :- chr_option(mode,depends_on_goal(+,+)).
8854 :- chr_option(mode,ai_is_observed(+,+)).
8855 :- chr_option(mode,ai_not_observed(+,+)).
8856 % :- chr_option(mode,ai_observed(+,+)).
8857 :- chr_option(mode,ai_not_observed_internal(+,+)).
8858 :- chr_option(mode,ai_observed_internal(+,+)).
8861 abstract_constraints_fd @
8862 abstract_constraints(_) \ abstract_constraints(_) <=> true.
8864 ai_observed_internal(C,O) \ ai_not_observed_internal(C,O) <=> true.
8865 ai_not_observed_internal(C,O) \ ai_not_observed_internal(C,O) <=> true.
8866 ai_observed_internal(C,O) \ ai_observed_internal(C,O) <=> true.
8868 ai_not_observed(C,O) \ ai_is_observed(C,O) <=> fail.
8869 ai_is_observed(_,_) <=> true.
8871 ai_observation_gather_results \ ai_observed_internal(C,O) <=> true. % ai_observed(C,O).
8872 ai_observation_gather_results \ ai_not_observed_internal(C,O) <=> ai_not_observed(C,O).
8873 ai_observation_gather_results <=> true.
8875 %------------------------------------------------------------------------------%
8876 % Main Analysis Entry
8877 %------------------------------------------------------------------------------%
8878 ai_observation_analysis(ACs) :-
8879 ( chr_pp_flag(ai_observation_analysis,on),
8880 get_target_module(Module), '$chr_compiled_with_version'(3) -> % , Module \== guard_entailment ->
8881 list_to_ord_set(ACs,ACSet),
8882 abstract_constraints(ACSet),
8883 ai_observation_schedule_initial_calls(ACSet,ACSet),
8884 ai_observation_gather_results
8889 ai_observation_schedule_initial_calls([],_).
8890 ai_observation_schedule_initial_calls([AC|RACs],ACs) :-
8891 ai_observation_schedule_initial_call(AC,ACs),
8892 ai_observation_schedule_initial_calls(RACs,ACs).
8894 ai_observation_schedule_initial_call(AC,ACs) :-
8895 ai_observation_top(AC,CallPattern),
8896 % ai_observation_bot(AC,ACs,CallPattern),
8897 initial_call_pattern(CallPattern).
8899 ai_observation_schedule_new_calls([],AP).
8900 ai_observation_schedule_new_calls([AC|ACs],AP) :-
8902 initial_call_pattern(odom(AC,Set)),
8903 ai_observation_schedule_new_calls(ACs,AP).
8905 final_answer_pattern(CP,AP1) \ final_answer_pattern(CP,AP2)
8907 ai_observation_leq(AP2,AP1)
8911 initial_call_pattern(CP) \ initial_call_pattern(CP) <=> true.
8913 initial_call_pattern(CP) ==> call_pattern(CP).
8915 initial_call_pattern(CP), final_answer_pattern(CP,AP), abstract_constraints(ACs) # ID3
8917 ai_observation_schedule_new_calls(ACs,AP)
8921 call_pattern(CP) \ call_pattern(CP) <=> true.
8923 depends_on(CP1,CP2), final_answer_pattern(CP2,AP) ==>
8924 final_answer_pattern(CP1,AP).
8926 %call_pattern(CP) ==> writeln(call_pattern(CP)).
8928 call_pattern(CP) ==> call_pattern_worker(CP).
8930 %------------------------------------------------------------------------------%
8932 %------------------------------------------------------------------------------%
8935 %call_pattern(odom([],Set)) ==>
8936 % final_answer_pattern(odom([],Set),odom([],Set)).
8938 call_pattern_worker(odom([],Set)) <=>
8939 % writeln(' - AbstractGoal'(odom([],Set))),
8940 final_answer_pattern(odom([],Set),odom([],Set)).
8943 call_pattern_worker(odom([G|Gs],Set)) <=>
8944 % writeln(' - AbstractGoal'(odom([G|Gs],Set))),
8946 depends_on_goal(odom([G|Gs],Set),CP1),
8949 depends_on_goal(CP1,CP2), final_answer_pattern(CP2,AP2) \ depends_on(CP1,_) # ID
8950 <=> true pragma passive(ID).
8951 depends_on_goal(CP1,CP2), final_answer_pattern(CP2,AP2)
8953 CP1 = odom([_|Gs],_),
8957 depends_on(CP1,CCP).
8959 %------------------------------------------------------------------------------%
8960 % Abstract Disjunction
8961 %------------------------------------------------------------------------------%
8963 call_pattern_worker(odom((AG1;AG2),Set)) <=>
8964 CP = odom((AG1;AG2),Set),
8965 InitialAnswerApproximation = odom([],Set),
8966 final_answer_pattern(CP,InitialAnswerApproximation),
8967 CP1 = odom(AG1,Set),
8968 CP2 = odom(AG2,Set),
8971 depends_on_as(CP,CP1,CP2).
8973 %------------------------------------------------------------------------------%
8975 %------------------------------------------------------------------------------%
8976 call_pattern_worker(odom(builtin,Set)) <=>
8977 % writeln(' - AbstractSolve'(odom(builtin,Set))),
8978 ord_empty(EmptySet),
8979 final_answer_pattern(odom(builtin,Set),odom([],EmptySet)).
8981 %------------------------------------------------------------------------------%
8983 %------------------------------------------------------------------------------%
8984 max_occurrence(C,MO) # ID2 \ call_pattern_worker(odom(occ(C,O),Set))
8988 % writeln(' - AbstractDrop'(odom(occ(C,O),Set))),
8989 final_answer_pattern(odom(occ(C,O),Set),odom([],Set))
8993 %------------------------------------------------------------------------------%
8995 %------------------------------------------------------------------------------%
8996 call_pattern_worker(odom(AC,Set))
9000 % writeln(' - AbstractActivate'(odom(AC,Set))),
9001 CP = odom(occ(AC,1),Set),
9003 depends_on(odom(AC,Set),CP).
9005 %------------------------------------------------------------------------------%
9007 %------------------------------------------------------------------------------%
9008 occurrence(C,O,RuleNb,ID,_) # ID2 \ call_pattern_worker(odom(occ(C,O),Set))
9010 is_passive(RuleNb,ID)
9012 % writeln(' - AbstractPassive'(odom(occ(C,O),Set))),
9015 DCP = odom(occ(C,NO),Set),
9017 final_answer_pattern(odom(occ(C,O),Set),odom([],Set)),
9018 depends_on(odom(occ(C,O),Set),DCP)
9021 %------------------------------------------------------------------------------%
9023 %------------------------------------------------------------------------------%
9026 occurrence(C,O,RuleNb,ID,simplification) # ID2 \ call_pattern_worker(odom(occ(C,O),Set))
9028 \+ is_passive(RuleNb,ID)
9030 % writeln(' - AbstractPassive'(odom(occ(C,O),Set))),
9031 ai_observation_memo_simplification_rest_heads(C,O,AbstractRestHeads),
9032 ai_observation_observe_set(Set,AbstractRestHeads,Set2),
9033 ai_observation_memo_abstract_goal(RuleNb,AG),
9034 call_pattern(odom(AG,Set2)),
9037 DCP = odom(occ(C,NO),Set),
9039 depends_on_as(odom(occ(C,O),Set),odom(AG,Set2),DCP),
9040 % DEADLOCK AVOIDANCE
9041 final_answer_pattern(odom(occ(C,O),Set),odom([],Set))
9045 depends_on_as(CP,CPS,CPD),
9046 final_answer_pattern(CPS,APS),
9047 final_answer_pattern(CPD,APD) ==>
9048 ai_observation_lub(APS,APD,AP),
9049 final_answer_pattern(CP,AP).
9053 ai_observation_memo_simplification_rest_heads/3,
9054 ai_observation_memoed_simplification_rest_heads/3.
9056 :- chr_option(mode,ai_observation_memo_simplification_rest_heads(+,+,?)).
9057 :- chr_option(mode,ai_observation_memoed_simplification_rest_heads(+,+,+)).
9059 ai_observation_memoed_simplification_rest_heads(C,O,RH) \ ai_observation_memo_simplification_rest_heads(C,O,QRH)
9062 abstract_constraints(ACs) # ID1, occurrence(C,O,RuleNb,ID,_) # ID2, rule(RuleNb,Rule) # ID3 \ ai_observation_memo_simplification_rest_heads(C,O,QRH)
9064 Rule = pragma(rule(H1,H2,_,_),ids(IDs1,_),_,_,_),
9065 once(select2(ID,_,IDs1,H1,_,RestH1)),
9066 ai_observation_abstract_constraints(RestH1,ACs,ARestHeads),
9067 ai_observation_abstract_constraints(H2,ACs,AH2),
9068 append(ARestHeads,AH2,AbstractHeads),
9069 sort(AbstractHeads,QRH),
9070 ai_observation_memoed_simplification_rest_heads(C,O,QRH)
9076 ai_observation_memo_simplification_rest_heads(_,_,_) <=> fail.
9078 %------------------------------------------------------------------------------%
9079 % Abstract Propagate
9080 %------------------------------------------------------------------------------%
9084 occurrence(C,O,RuleNb,ID,propagation) # ID2 \ call_pattern_worker(odom(occ(C,O),Set))
9086 \+ is_passive(RuleNb,ID)
9088 % writeln(' - AbstractPropagate'(odom(occ(C,O),Set))),
9090 ai_observation_memo_propagation_rest_heads(C,O,AHs),
9091 ai_observation_observe_set(Set,AHs,Set2),
9092 ord_add_element(Set2,C,Set3),
9093 ai_observation_memo_abstract_goal(RuleNb,AG),
9094 call_pattern(odom(AG,Set3)),
9095 ( ord_memberchk(C,Set2) ->
9102 DCP = odom(occ(C,NO),Set),
9104 depends_on_ap(odom(occ(C,O),Set),odom(AG,Set3),DCP,Delete)
9109 ai_observation_memo_propagation_rest_heads/3,
9110 ai_observation_memoed_propagation_rest_heads/3.
9112 :- chr_option(mode,ai_observation_memo_propagation_rest_heads(+,+,?)).
9113 :- chr_option(mode,ai_observation_memoed_propagation_rest_heads(+,+,+)).
9115 ai_observation_memoed_propagation_rest_heads(C,O,RH) \ ai_observation_memo_propagation_rest_heads(C,O,QRH)
9118 abstract_constraints(ACs) # ID1, occurrence(C,O,RuleNb,ID,_) # ID2, rule(RuleNb,Rule) # ID3 \ ai_observation_memo_propagation_rest_heads(C,O,QRH)
9120 Rule = pragma(rule(H1,H2,_,_),ids(_,IDs2),_,_,_),
9121 once(select2(ID,_,IDs2,H2,_,RestH2)),
9122 ai_observation_abstract_constraints(RestH2,ACs,ARestHeads),
9123 ai_observation_abstract_constraints(H1,ACs,AH1),
9124 append(ARestHeads,AH1,AbstractHeads),
9125 sort(AbstractHeads,QRH),
9126 ai_observation_memoed_propagation_rest_heads(C,O,QRH)
9132 ai_observation_memo_propagation_rest_heads(_,_,_) <=> fail.
9134 depends_on_ap(CP,CPP,CPD,Delete), final_answer_pattern(CPD,APD) ==>
9135 final_answer_pattern(CP,APD).
9136 depends_on_ap(CP,CPP,CPD,Delete), final_answer_pattern(CPP,APP),
9137 final_answer_pattern(CPD,APD) ==>
9139 CP = odom(occ(C,O),_),
9140 ( ai_observation_is_observed(APP,C) ->
9141 ai_observed_internal(C,O)
9143 ai_not_observed_internal(C,O)
9146 APP = odom([],Set0),
9147 ord_del_element(Set0,C,Set),
9152 ai_observation_lub(NAPP,APD,AP),
9153 final_answer_pattern(CP,AP).
9155 %------------------------------------------------------------------------------%
9157 %------------------------------------------------------------------------------%
9159 call_pattern_worker(CP) <=> chr_error(internal,'AI observation analysis: unexpected abstract state ~w\n',[CP]).
9161 %------------------------------------------------------------------------------%
9162 % Auxiliary Predicates
9163 %------------------------------------------------------------------------------%
9165 ai_observation_lub(odom(AG,S1),odom(AG,S2),odom(AG,S3)) :-
9166 ord_intersection(S1,S2,S3).
9168 ai_observation_bot(AG,AS,odom(AG,AS)).
9170 ai_observation_top(AG,odom(AG,EmptyS)) :-
9173 ai_observation_leq(odom(AG,S1),odom(AG,S2)) :-
9176 ai_observation_observe_set(S,ACSet,NS) :-
9177 ord_subtract(S,ACSet,NS).
9179 ai_observation_abstract_constraint(C,ACs,AC) :-
9184 ai_observation_abstract_constraints(Cs,ACs,NACs) :-
9185 findall(NAC,(member(C,Cs),ai_observation_abstract_constraint(C,ACs,NAC)),NACs).
9187 %------------------------------------------------------------------------------%
9188 % Abstraction of Rule Bodies
9189 %------------------------------------------------------------------------------%
9192 ai_observation_memoed_abstract_goal/2,
9193 ai_observation_memo_abstract_goal/2.
9195 :- chr_option(mode,ai_observation_memoed_abstract_goal(+,+)).
9196 :- chr_option(mode,ai_observation_memo_abstract_goal(+,?)).
9198 ai_observation_memoed_abstract_goal(RuleNb,AG) # ID1 \ ai_observation_memo_abstract_goal(RuleNb,QAG)
9204 rule(RuleNb,Rule) # ID1, abstract_constraints(ACs) # ID2 \ ai_observation_memo_abstract_goal(RuleNb,QAG)
9206 Rule = pragma(rule(H1,H2,Guard,Body),_,_,_,_),
9207 ai_observation_abstract_goal_(H1,H2,Guard,Body,ACs,AG),
9209 ai_observation_memoed_abstract_goal(RuleNb,AG)
9214 ai_observation_abstract_goal_(H1,H2,Guard,G,ACs,AG) :-
9215 % also guard: e.g. b, c(X) ==> Y=X | p(Y).
9216 term_variables((H1,H2,Guard),HVars),
9217 append(H1,H2,Heads),
9218 % variables that are declared to be ground are safe,
9219 ground_vars(Heads,GroundVars),
9220 % so we remove them from the list of 'dangerous' head variables
9221 list_difference_eq(HVars,GroundVars,HV),
9222 ai_observation_abstract_goal(G,ACs,AG,[],HV),!.
9223 % writeln(ai_observation_abstract_goal(G,ACs,AG,[],HV)).
9224 % HV are 'dangerous' variables, all others are fresh and safe
9227 ground_vars([H|Hs],GroundVars) :-
9229 get_constraint_mode(F/A,Mode),
9230 % TOM: fix this code!
9231 head_info(H,A,_Vars,_Susp,_HeadVars,HeadPairs),
9232 head_arg_matches(HeadPairs,Mode,[],_FirstMatching,_VarDict1,[],GroundVars1),
9233 ground_vars(Hs,GroundVars2),
9234 append(GroundVars1,GroundVars2,GroundVars).
9236 ai_observation_abstract_goal((G1,G2),ACs,List,Tail,HV) :- !, % conjunction
9237 ai_observation_abstract_goal(G1,ACs,List,IntermediateList,HV),
9238 ai_observation_abstract_goal(G2,ACs,IntermediateList,Tail,HV).
9239 ai_observation_abstract_goal((G1;G2),ACs,[(ABranch1;ABranch2)|Tail],Tail,HV) :- !, % disjunction
9240 ai_observation_abstract_goal(G1,ACs,ABranch1,[],HV),
9241 ai_observation_abstract_goal(G2,ACs,ABranch2,[],HV).
9242 ai_observation_abstract_goal((G1->G2),ACs,List,Tail,HV) :- !, % if-then
9243 ai_observation_abstract_goal(G1,ACs,List,IntermediateList,HV),
9244 ai_observation_abstract_goal(G2,ACs,IntermediateList,Tail,HV).
9245 ai_observation_abstract_goal(C,ACs,[AC|Tail],Tail,HV) :-
9246 ai_observation_abstract_constraint(C,ACs,AC), !. % CHR constraint
9247 ai_observation_abstract_goal(true,_,Tail,Tail,_) :- !.
9248 ai_observation_abstract_goal(writeln(_),_,Tail,Tail,_) :- !.
9249 % non-CHR constraint is safe if it only binds fresh variables
9250 ai_observation_abstract_goal(G,_,Tail,Tail,HV) :-
9251 builtin_binds_b(G,Vars),
9252 intersect_eq(Vars,HV,[]),
9254 ai_observation_abstract_goal(G,_,[AG|Tail],Tail,_) :-
9255 AG = builtin. % default case if goal is not recognized/safe
9257 ai_observation_is_observed(odom(_,ACSet),AC) :-
9258 \+ ord_memberchk(AC,ACSet).
9260 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9261 unconditional_occurrence(C,O) :-
9262 get_occurrence(C,O,RuleNb,ID),
9263 get_rule(RuleNb,PRule),
9264 PRule = pragma(ORule,_,_,_,_),
9265 copy_term_nat(ORule,Rule),
9266 Rule = rule(H1,H2,Guard,_),
9267 % writeq(guard_entailment:entails_guard([chr_pp_headvariables(H1,H2)],Guard)),nl,
9268 guard_entailment:entails_guard([chr_pp_headvariables(H1,H2)],Guard),
9270 H1 = [Head], H2 == []
9272 H2 = [Head], H1 == [], \+ may_trigger(C)
9276 unconditional_occurrence_args(Args).
9278 unconditional_occurrence_args([]).
9279 unconditional_occurrence_args([X|Xs]) :-
9282 unconditional_occurrence_args(Xs).
9284 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9286 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9287 % Partial wake analysis
9289 % In a Var = Var unification do not wake up constraints of both variables,
9290 % but rather only those of one variable.
9291 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9293 :- chr_constraint partial_wake_analysis/0.
9294 :- chr_constraint no_partial_wake/1.
9295 :- chr_option(mode,no_partial_wake(+)).
9296 :- chr_constraint wakes_partially/1.
9297 :- chr_option(mode,wakes_partially(+)).
9299 partial_wake_analysis, occurrence(FA,O,RuleNb,ID,Type), rule(RuleNb,Rule), constraint_mode(FA,ArgModes)
9301 Rule = pragma(rule(H1,H2,Guard,Body),_,_,_,_),
9302 ( is_passive(RuleNb,ID) ->
9304 ; Type == simplification ->
9305 select(H,H1,RestH1),
9307 term_variables(Guard,Vars),
9308 partial_wake_args(Args,ArgModes,Vars,FA)
9309 ; % Type == propagation ->
9310 select(H,H2,RestH2),
9312 term_variables(Guard,Vars),
9313 partial_wake_args(Args,ArgModes,Vars,FA)
9316 partial_wake_args([],_,_,_).
9317 partial_wake_args([Arg|Args],[Mode|Modes],Vars,C) :-
9321 ; memberchk_eq(Arg,Vars) ->
9329 partial_wake_args(Args,Modes,Vars,C).
9331 no_partial_wake(C) \ no_partial_wake(C) <=> true.
9333 no_partial_wake(C) \ wakes_partially(C) <=> fail.
9335 wakes_partially(C) <=> true.
9338 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9339 % Generate rules that implement chr_show_store/1 functionality.
9345 % Generates additional rules:
9347 % $show, C1 # ID ==> writeln(C1) pragma passive(ID).
9349 % $show, Cn # ID ==> writeln(Cn) pragma passive(ID).
9352 generate_show_constraint(Constraints0,Constraints,Rules0,Rules) :-
9353 ( chr_pp_flag(show,on) ->
9354 Constraints = ['$show'/0|Constraints0],
9355 generate_show_rules(Constraints0,Rules,[Rule|Rules0]),
9356 inc_rule_count(RuleNb),
9358 rule(['$show'],[],true,true),
9365 Constraints = Constraints0,
9369 generate_show_rules([],Rules,Rules).
9370 generate_show_rules([F/A|Rest],[Rule|Tail],Rules) :-
9372 inc_rule_count(RuleNb),
9374 rule([],['$show',C],true,writeln(C)),
9380 generate_show_rules(Rest,Tail,Rules).
9382 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9383 % Custom supension term layout
9385 static_suspension_term(F/A,Suspension) :-
9386 suspension_term_base(F/A,Base),
9388 functor(Suspension,suspension,Arity).
9390 has_suspension_field(FA,Field) :-
9391 suspension_term_base_fields(FA,Fields),
9392 memberchk(Field,Fields).
9394 suspension_term_base(FA,Base) :-
9395 suspension_term_base_fields(FA,Fields),
9396 length(Fields,Base).
9398 suspension_term_base_fields(FA,Fields) :-
9399 ( chr_pp_flag(debugable,on) ->
9402 % 3. Propagation History
9403 % 4. Generation Number
9404 % 5. Continuation Goal
9406 Fields = [id,state,history,generation,continuation,functor]
9408 ( uses_history(FA) ->
9409 Fields = [id,state,history|Fields2]
9410 ; only_ground_indexed_arguments(FA), get_functional_dependency(FA,1,_,_) ->
9411 Fields = [state|Fields2]
9413 Fields = [id,state|Fields2]
9415 ( only_ground_indexed_arguments(FA) ->
9416 get_store_type(FA,StoreType),
9417 basic_store_types(StoreType,BasicStoreTypes),
9418 ( memberchk(global_ground,BasicStoreTypes) ->
9421 % 3. Propagation History
9422 % 4. Global List Prev
9423 Fields2 = [global_list_prev|Fields3]
9427 % 3. Propagation History
9430 ( chr_pp_flag(ht_removal,on)
9431 -> ht_prev_fields(BasicStoreTypes,Fields3)
9434 ; may_trigger(FA) ->
9437 % 3. Propagation History
9438 ( uses_field(FA,generation) ->
9439 % 4. Generation Number
9440 % 5. Global List Prev
9441 Fields2 = [generation,global_list_prev|Fields3]
9443 Fields2 = [global_list_prev|Fields3]
9445 ( chr_pp_flag(mixed_stores,on),
9446 chr_pp_flag(ht_removal,on)
9447 -> get_store_type(FA,StoreType),
9448 basic_store_types(StoreType,BasicStoreTypes),
9449 ht_prev_fields(BasicStoreTypes,Fields3)
9455 % 3. Propagation History
9456 % 4. Global List Prev
9457 Fields2 = [global_list_prev|Fields3],
9458 ( chr_pp_flag(mixed_stores,on),
9459 chr_pp_flag(ht_removal,on)
9460 -> get_store_type(FA,StoreType),
9461 basic_store_types(StoreType,BasicStoreTypes),
9462 ht_prev_fields(BasicStoreTypes,Fields3)
9468 ht_prev_fields(Stores,Prevs) :-
9469 ht_prev_fields_int(Stores,PrevsList),
9470 append(PrevsList,Prevs).
9471 ht_prev_fields_int([],[]).
9472 ht_prev_fields_int([H|T],Fields) :-
9473 ( H = multi_hash(Indexes)
9474 -> maplist(ht_prev_field,Indexes,FH),
9478 ht_prev_fields_int(T,FT).
9480 ht_prev_field(Index,Field) :-
9482 -> atom_concat('multi_hash_prev-',Index,Field)
9484 -> concat_atom(['multi_hash_prev-'|Index],Field)
9487 get_static_suspension_term_field(FieldName,FA,StaticSuspension,Field) :-
9488 suspension_term_base_fields(FA,Fields),
9489 nth(Index,Fields,FieldName), !,
9490 arg(Index,StaticSuspension,Field).
9491 get_static_suspension_term_field(arguments,FA,StaticSuspension,Field) :- !,
9492 suspension_term_base(FA,Base),
9493 StaticSuspension =.. [_|Args],
9494 drop(Base,Args,Field).
9495 get_static_suspension_term_field(FieldName,FA,_StaticSuspension,_Field) :-
9496 chr_error(internal,'Trying to obtain field ~w of ~w, wich does not have it!',[FieldName,FA]).
9499 get_dynamic_suspension_term_field(FieldName,FA,DynamicSuspension,Field,Goal) :-
9500 suspension_term_base_fields(FA,Fields),
9501 nth(Index,Fields,FieldName), !,
9502 Goal = arg(Index,DynamicSuspension,Field).
9503 get_dynamic_suspension_term_field(arguments,FA,DynamicSuspension,Field,Goal) :- !,
9504 static_suspension_term(FA,StaticSuspension),
9505 get_static_suspension_term_field(arguments,FA,StaticSuspension,Field),
9506 Goal = (DynamicSuspension = StaticSuspension).
9507 get_dynamic_suspension_term_field(argument(I),FA,DynamicSuspension,Field,Goal) :- !,
9508 suspension_term_base(FA,Base),
9510 Goal = arg(Index,DynamicSuspension,Field).
9511 get_dynamic_suspension_term_field(FieldName,FA,_DynamicSuspension,_Field,_Goal) :-
9512 chr_error(internal,'Dynamic goal to get ~w of ~w, which does not have this field!',[FieldName,FA]).
9515 set_dynamic_suspension_term_field(FieldName,FA,DynamicSuspension,Field,Goal) :-
9516 suspension_term_base_fields(FA,Fields),
9517 nth(Index,Fields,FieldName), !,
9518 Goal = setarg(Index,DynamicSuspension,Field).
9519 set_dynamic_suspension_term_field(FieldName,FA,_DynamicSuspension,_Field,_Goal) :-
9520 chr_error(internal,'Dynamic goal to set ~w of ~w, which does not have this field!',[FieldName,FA]).
9522 basic_store_types(multi_store(Types),Types) :- !.
9523 basic_store_types(Type,[Type]).
9525 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9532 :- chr_option(mode,phase_end(+)).
9533 :- chr_option(mode,delay_phase_end(+,?)).
9535 phase_end(Phase) \ delay_phase_end(Phase,Goal) <=> call(Goal).
9536 % phase_end(Phase) <=> true.
9539 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9543 novel_production_call/4.
9545 :- chr_option(mode,uses_history(+)).
9546 :- chr_option(mode,does_use_history(+,+)).
9547 :- chr_option(mode,novel_production_call(+,+,?,?)).
9549 does_use_history(FA,Occ) \ does_use_history(FA,Occ) <=> true.
9550 does_use_history(FA,_) \ uses_history(FA) <=> true.
9551 uses_history(_FA) <=> fail.
9553 does_use_history(FA,Occ) \ novel_production_call(FA,Occ,PossibleGoal,Goal) <=> Goal = PossibleGoal.
9554 novel_production_call(FA,_,_PossibleGoal,Goal) <=> Goal = true.
9560 :- chr_option(mode,uses_field(+,+)).
9561 :- chr_option(mode,does_use_field(+,+)).
9563 does_use_field(FA,Field) \ does_use_field(FA,Field) <=> true.
9564 does_use_field(FA,Field) \ uses_field(FA,Field) <=> true.
9565 uses_field(_FA,_Field) <=> fail.
9570 used_states_known/0.
9572 :- chr_option(mode,uses_state(+,+)).
9573 :- chr_option(mode,if_used_state(+,+,?,?,?)).
9576 % states ::= not_stored_yet | passive | active | triggered | removed
9578 % allocate CREATES not_stored_yet
9579 % remove CHECKS not_stored_yet
9580 % activate CHECKS not_stored_yet
9582 % ==> no allocate THEN no not_stored_yet
9584 % recurs CREATES inactive
9585 % lookup CHECKS inactive
9587 % insert CREATES active
9588 % activate CREATES active
9589 % lookup CHECKS active
9590 % recurs CHECKS active
9592 % runsusp CREATES triggered
9593 % lookup CHECKS triggered
9595 % ==> no runsusp THEN no triggered
9597 % remove CREATES removed
9598 % runsusp CHECKS removed
9599 % lookup CHECKS removed
9600 % recurs CHECKS removed
9602 % ==> no remove THEN no removed
9604 % ==> no allocate, no remove, no active/inactive distinction THEN no state at all...
9606 uses_state(Constraint,State) \ uses_state(Constraint,State) <=> true.
9608 used_states_known, uses_state(Constraint,State) \ if_used_state(Constraint,State,Used,NotUsed,ResultGoal)
9609 <=> ResultGoal = Used.
9610 used_states_known \ if_used_state(Constraint,State,Used,NotUsed,ResultGoal)
9611 <=> ResultGoal = NotUsed.
9613 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9614 % CHECK STOREDNESS ANNOTATIONS AND GENERATE DEFAULT SIMPLIFICATION RULES
9620 % When the programmer enables the `declare_stored_constraints' option, i.e. writes
9622 % :- chr_option(declare_stored_constraints,on).
9624 % the compiler will check for the storedness of constraints.
9626 % By default, the compiler assumes that the programmer wants his constraints to
9627 % be never-stored. Hence, a warning will be issues when a constraint is actually
9630 % Such warnings are suppressed, if the programmer adds the `# stored' modifier
9631 % to a constraint declaration, i.e. writes
9633 % :- chr_constraint c(...) # stored.
9635 % In that case a warning is issued when the constraint is never-stored.
9637 % NOTE: Checking is only performed if `storage_analysis' is on. Otherwise, all
9638 % constraints are stored anyway.
9641 % 2. Rule Generation
9642 % ~~~~~~~~~~~~~~~~~~
9644 % When the programmer enables the `declare_stored_constraints' option, i.e. writes
9646 % :- chr_option(declare_stored_constraints,on).
9648 % the compiler will generate default simplification rules for constraints.
9650 % By default, no default rule is generated for a constraint. However, if the
9651 % programmer writes a default/1 annotation in the constraint declaration, i.e. writes
9653 % :- chr_constraint c(...) # default(Goal).
9655 % where `Goal' is a ground and callable goal (e.g. `true', `fail' or `throw(error)'),
9656 % the compiler generates a rule:
9658 % c(_,...,_) <=> Goal.
9660 % at the end of the program. If multiple default rules are generated, for several constraints,
9661 % then the order of the default rules is not specified.
9664 :- chr_constraint stored_assertion/1.
9665 :- chr_option(mode,stored_assertion(+)).
9666 :- chr_option(type_declaration,stored_assertion(constraint)).
9668 :- chr_constraint never_stored_default/2.
9669 :- chr_option(mode,never_stored_default(+,?)).
9670 :- chr_option(type_declaration,never_stored_default(constraint,any)).
9675 generate_never_stored_rules(Constraints,Rules) :-
9676 ( chr_pp_flag(declare_stored_constraints,on) ->
9677 never_stored_rules(Constraints,Rules)
9682 :- chr_constraint never_stored_rules/2.
9683 :- chr_option(mode,never_stored_rules(+,?)).
9684 :- chr_option(type_declaration,never_stored_rules(list(constraint),any)).
9686 never_stored_rules([],Rules) <=> Rules = [].
9687 never_stored_default(Constraint,Goal) \ never_stored_rules([Constraint|Constraints],Rules) <=>
9690 inc_rule_count(RuleNb),
9692 rule([Head],[],true,Goal),
9698 Rules = [Rule|Tail],
9699 never_stored_rules(Constraints,Tail).
9700 never_stored_rules([_|Constraints],Rules) <=>
9701 never_stored_rules(Constraints,Rules).
9706 check_storedness_assertions(Constraints) :-
9707 ( chr_pp_flag(storage_analysis,on), chr_pp_flag(declare_stored_constraints,on) ->
9708 forall(Constraint,Constraints,check_storedness_assertion(Constraint))
9714 :- chr_constraint check_storedness_assertion/1.
9715 :- chr_option(mode,check_storedness_assertion(+)).
9716 :- chr_option(type_declaration,check_storedness_assertion(constraint)).
9718 check_storedness_assertion(Constraint), stored_assertion(Constraint)
9719 <=> ( is_stored(Constraint) ->
9722 chr_warning(assertion_failed,'Constraint ~w is not stored. However, it was asserted to be stored.\n',[Constraint])
9724 never_stored_default(Constraint,_) \ check_storedness_assertion(Constraint)
9725 <=> ( is_finally_stored(Constraint) ->
9726 chr_warning(assertion_failed,'Constraint ~w is stored. However, it was asserted not to be stored.\n',[Constraint])
9727 ; is_stored(Constraint) ->
9728 chr_warning(assertion_failed,'Constraint ~w is temporarily stored. However, it was asserted not to be stored.\n',[Constraint])
9732 % never-stored, no default goal
9733 check_storedness_assertion(Constraint)
9734 <=> ( is_finally_stored(Constraint) ->
9735 chr_warning(assertion_failed,'Constraint ~w is stored. However, it was asserted not to be stored.\n',[Constraint])
9736 ; is_stored(Constraint) ->
9737 chr_warning(assertion_failed,'Constraint ~w is temporarily stored. However, it was asserted not to be stored.\n',[Constraint])
9742 %^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
9743 % success continuation analysis
9746 % take passive occurrences into account for correctness!
9747 % also use for forward jumping improvement!
9749 success_continuation_analysis([]).
9750 success_continuation_analysis([C|Cs]) :-
9751 success_continuation_analysis(C,1),
9752 get_max_occurrence(C,MO),
9754 bulk_propagation(C,1,LO),
9755 success_continuation_analysis(Cs).
9757 success_continuation_analysis(C,O) :-
9758 get_max_occurrence(C,MO),
9762 constraint_success_continuation(C,O,MO,NextO),
9763 success_continuation_occurrence(C,O,NextO),
9765 success_continuation_analysis(C,NO)
9768 constraint_success_continuation(C,O,MO,NextO) :-
9769 get_occurrence_head(C,O,Head),
9771 ( between(NO,MO,NextO),
9772 get_occurrence_head(C,NextO,NextHead),
9773 unifiable(Head,NextHead,_) ->
9779 get_occurrence_head(C,O,Head) :-
9780 get_occurrence(C,O,RuleNb,Id),
9781 get_rule(RuleNb,Rule),
9782 Rule = pragma(rule(H1,H2,_,_),ids(Ids1,Ids2),_,_,_),
9783 ( select2(Id,Head,Ids1,H1,_,_) -> true
9784 ; select2(Id,Head,Ids2,H2,_,_)
9787 :- chr_constraint success_continuation_occurrence/3.
9788 :- chr_option(mode,success_continuation_occurrence(+,+,+)).
9790 :- chr_constraint bulk_propagation/3.
9791 :- chr_option(mode,bulk_propagation(+,+,+)).
9793 :- chr_constraint skip_to_next_id/2.
9794 :- chr_option(mode,skip_to_next_id(+,+)).
9796 :- chr_constraint should_skip_to_next_id/2.
9797 :- chr_option(mode,should_skip_to_next_id(+,+)).
9799 skip_to_next_id(C,O) \ should_skip_to_next_id(C,O)
9803 should_skip_to_next_id(_,_)
9807 % don't go beyond the last occurrence
9808 % we have to go to next id for storage here
9809 max_occurrence(C,MO) \ bulk_propagation(C,O,_)
9813 skip_to_next_id(C,O).
9814 % we have to go to the next id here because
9815 % a predecessor needs it
9816 bulk_propagation(C,O,LO)
9820 skip_to_next_id(C,O),
9821 get_max_occurrence(C,MO),
9823 bulk_propagation(C,LO,NLO).
9824 % we have to go to the next id here because
9825 % we're running into a simplification rule
9826 % IMPROVE: propagate back to propagation predecessor (IF ANY)
9827 occurrence(C,NO,_,_,simplification) \ bulk_propagation(C,O,LO)
9831 skip_to_next_id(C,O),
9832 get_max_occurrence(C,MO),
9834 bulk_propagation(C,NO,NLO).
9835 % we skip the next id here
9836 % and go to the next occurrence
9837 success_continuation_occurrence(C,O,NextO) \ bulk_propagation(C,O,LO)
9841 NLO is min(LO,NextO),
9843 bulk_propagation(C,NO,NLO).
9845 % err on the safe side
9846 bulk_propagation(C,O,LO)
9848 skip_to_next_id(C,O),
9849 get_max_occurrence(C,MO),
9852 bulk_propagation(C,NO,NLO).
9854 skip_to_next_id(C,O) \ skip_to_next_id(C,O) <=> true.
9856 % if this occurrence is passive, but has to skip,
9857 % then the previous one must skip instead...
9858 % IMPROVE reasoning is conservative
9859 occurrence(C,O,RuleNb,Id,_), passive(RuleNb,Id), skip_to_next_id(C,O)
9864 skip_to_next_id(C,PO).