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 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 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 store_type(C,multi_store([global_ground|STs]))
511 store_type(C,multi_store(STs))
513 validate_store_type_assumption(C), actual_store_types(C,STs), store_type(C,_) % user assumption
515 store_type(C,multi_store(STs)).
516 validate_store_type_assumption(C), assumed_store_type(C,_) % no lookups on constraint in debug mode
518 chr_pp_flag(debugable,on)
520 store_type(C,default).
521 validate_store_type_assumption(C), assumed_store_type(C,_) % no lookups on constraint
522 <=> store_type(C,global_ground).
523 validate_store_type_assumption(C)
526 partial_store(ground_constants(_,_)).
527 partial_store(atomic_constants(_,_,incomplete)).
529 %%% P A S S I V E %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
530 passive(R,ID) \ passive(R,ID) <=> true.
532 passive(RuleNb,ID) \ is_passive(RuleNb,ID) <=> true.
533 is_passive(_,_) <=> fail.
535 passive(RuleNb,_) \ any_passive_head(RuleNb)
539 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
541 max_occurrence(C,N) \ max_occurrence(C,M)
544 max_occurrence(C,MO), new_occurrence(C,RuleNb,ID,Type) <=>
546 occurrence(C,NO,RuleNb,ID,Type),
547 max_occurrence(C,NO).
548 new_occurrence(C,RuleNb,ID,_) <=>
549 chr_error(internal,'new_occurrence: missing max_occurrence for ~w in rule ~w\n',[C,RuleNb]).
551 max_occurrence(C,MON) \ get_max_occurrence(C,Q)
553 get_max_occurrence(C,Q)
554 <=> chr_error(internal,'get_max_occurrence: missing max occurrence for ~w\n',[C]).
556 occurrence(C,ON,Rule,ID,_) \ get_occurrence(C,ON,QRule,QID)
557 <=> Rule = QRule, ID = QID.
558 get_occurrence(C,O,_,_)
559 <=> chr_error(internal,'get_occurrence: missing occurrence ~w:~w\n',[C,O]).
561 occurrence(C,ON,Rule,ID,_) \ get_occurrence_from_id(QC,QON,Rule,ID)
562 <=> QC = C, QON = ON.
563 get_occurrence_from_id(C,O,_,_)
564 <=> chr_error(internal,'get_occurrence_from_id: missing occurrence ~w:~w\n',[]).
566 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
569 late_allocation_analysis(Cs) :-
570 ( chr_pp_flag(late_allocation,on) ->
571 maplist(late_allocation, Cs)
576 late_allocation(C) :- late_allocation(C,0).
577 late_allocation(C,O) :- allocation_occurrence(C,O), !.
578 late_allocation(C,O) :- NO is O + 1, late_allocation(C,NO).
580 % A L L O C C A T I O N O C C U R R E N C E %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
582 allocation_occurrence(C,0) ==> stored_in_guard_before_next_kept_occurrence(C,0).
584 rule(RuleNb,Rule), occurrence(C,O,RuleNb,Id,Type), allocation_occurrence(C,O) ==>
585 \+ is_passive(RuleNb,Id),
587 ( stored_in_guard_before_next_kept_occurrence(C,O) ->
589 ; Rule = pragma(rule([_|_],_,_,_),_,_,_,_) -> % simpagation rule
591 ; is_least_occurrence(RuleNb) -> % propagation rule
597 stored_in_guard_before_next_kept_occurrence(C,O) :-
598 chr_pp_flag(store_in_guards, on),
600 stored_in_guard_lookahead(C,NO).
602 :- chr_constraint stored_in_guard_lookahead/2.
603 :- chr_option(mode, stored_in_guard_lookahead(+,+)).
605 occurrence(C,O,RuleNb,Id,_), passive(RuleNb,Id) \ stored_in_guard_lookahead(C,O) <=>
606 NO is O + 1, stored_in_guard_lookahead(C,NO).
607 occurrence(C,O,RuleNb,Id,Type) \ stored_in_guard_lookahead(C,O) <=>
608 Type == simplification,
609 ( is_stored_in_guard(C,RuleNb) ->
612 NO is O + 1, stored_in_guard_lookahead(C,NO)
614 stored_in_guard_lookahead(_,_) <=> fail.
617 rule(RuleNb,Rule), occurrence(C,O,RuleNb,ID,_), allocation_occurrence(C,AO)
618 \ least_occurrence(RuleNb,[ID|IDs])
619 <=> AO >= O, \+ may_trigger(C) |
620 least_occurrence(RuleNb,IDs).
621 rule(RuleNb,Rule), passive(RuleNb,ID)
622 \ least_occurrence(RuleNb,[ID|IDs])
623 <=> least_occurrence(RuleNb,IDs).
626 ==> Rule = pragma(rule([],_,_,_),ids([],IDs),_,_,_) |
627 least_occurrence(RuleNb,IDs).
629 least_occurrence(RuleNb,[]) \ is_least_occurrence(RuleNb)
631 is_least_occurrence(_)
634 allocation_occurrence(C,O) \ get_allocation_occurrence(C,Q)
636 get_allocation_occurrence(_,Q)
637 <=> chr_pp_flag(late_allocation,off), Q=0.
638 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
640 rule(RuleNb,Rule) \ get_rule(RuleNb,Q)
645 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
647 %%% C O N S T R A I N T I N D E X %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
649 % Default store constraint index assignment.
651 :- chr_constraint constraint_index/2. % constraint_index(F/A,DefaultStoreAndAttachedIndex)
652 :- chr_option(mode,constraint_index(+,+)).
653 :- chr_option(type_declaration,constraint_index(constraint,int)).
655 :- chr_constraint get_constraint_index/2.
656 :- chr_option(mode,get_constraint_index(+,-)).
657 :- chr_option(type_declaration,get_constraint_index(constraint,int)).
659 :- chr_constraint get_indexed_constraint/2.
660 :- chr_option(mode,get_indexed_constraint(+,-)).
661 :- chr_option(type_declaration,get_indexed_constraint(int,constraint)).
663 :- chr_constraint max_constraint_index/1. % max_constraint_index(MaxDefaultStoreAndAttachedIndex)
664 :- chr_option(mode,max_constraint_index(+)).
665 :- chr_option(type_declaration,max_constraint_index(int)).
667 :- chr_constraint get_max_constraint_index/1.
668 :- chr_option(mode,get_max_constraint_index(-)).
669 :- chr_option(type_declaration,get_max_constraint_index(int)).
671 constraint_index(C,Index) \ get_constraint_index(C,Query)
673 get_constraint_index(C,Query)
676 constraint_index(C,Index) \ get_indexed_constraint(Index,Q)
678 get_indexed_constraint(Index,Q)
681 max_constraint_index(Index) \ get_max_constraint_index(Query)
683 get_max_constraint_index(Query)
686 set_constraint_indices(Constraints) :-
687 set_constraint_indices(Constraints,1).
688 set_constraint_indices([],M) :-
690 max_constraint_index(N).
691 set_constraint_indices([C|Cs],N) :-
692 ( ( chr_pp_flag(debugable, on) ; \+ only_ground_indexed_arguments(C), is_stored(C) ; is_stored(C), get_store_type(C,default)
693 ; get_store_type(C,var_assoc_store(_,_))) ->
694 constraint_index(C,N),
696 set_constraint_indices(Cs,M)
698 set_constraint_indices(Cs,N)
701 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
704 :- chr_constraint identifier_size/1.
705 :- chr_option(mode,identifier_size(+)).
706 :- chr_option(type_declaration,identifier_size(natural)).
708 identifier_size(_) \ identifier_size(_)
712 :- chr_constraint get_identifier_size/1.
713 :- chr_option(mode,get_identifier_size(-)).
714 :- chr_option(type_declaration,get_identifier_size(natural)).
716 identifier_size(Size) \ get_identifier_size(Q)
720 get_identifier_size(Q)
724 :- chr_constraint identifier_index/3.
725 :- chr_option(mode,identifier_index(+,+,+)).
726 :- chr_option(type_declaration,identifier_index(constraint,natural,natural)).
728 identifier_index(C,I,_) \ identifier_index(C,I,_)
732 :- chr_constraint get_identifier_index/3.
733 :- chr_option(mode,get_identifier_index(+,+,-)).
734 :- chr_option(type_declaration,get_identifier_index(constraint,natural,natural)).
736 identifier_index(C,I,II) \ get_identifier_index(C,I,Q)
739 identifier_size(Size), get_identifier_index(C,I,Q)
742 identifier_index(C,I,NSize),
743 identifier_size(NSize),
745 get_identifier_index(C,I,Q)
747 identifier_index(C,I,2),
751 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
752 % Type Indexed Identifier Indexes
754 :- chr_constraint type_indexed_identifier_size/2.
755 :- chr_option(mode,type_indexed_identifier_size(+,+)).
756 :- chr_option(type_declaration,type_indexed_identifier_size(any,natural)).
758 type_indexed_identifier_size(IndexType,_) \ type_indexed_identifier_size(IndexType,_)
762 :- chr_constraint get_type_indexed_identifier_size/2.
763 :- chr_option(mode,get_type_indexed_identifier_size(+,-)).
764 :- chr_option(type_declaration,get_type_indexed_identifier_size(any,natural)).
766 type_indexed_identifier_size(IndexType,Size) \ get_type_indexed_identifier_size(IndexType,Q)
770 get_type_indexed_identifier_size(IndexType,Q)
774 :- chr_constraint type_indexed_identifier_index/4.
775 :- chr_option(mode,type_indexed_identifier_index(+,+,+,+)).
776 :- chr_option(type_declaration,type_indexed_identifier_index(any,constraint,natural,natural)).
778 type_indexed_identifier_index(_,C,I,_) \ type_indexed_identifier_index(_,C,I,_)
782 :- chr_constraint get_type_indexed_identifier_index/4.
783 :- chr_option(mode,get_type_indexed_identifier_index(+,+,+,-)).
784 :- chr_option(type_declaration,get_type_indexed_identifier_index(any,constraint,natural,natural)).
786 type_indexed_identifier_index(IndexType,C,I,II) \ get_type_indexed_identifier_index(IndexType,C,I,Q)
789 type_indexed_identifier_size(IndexType,Size), get_type_indexed_identifier_index(IndexType,C,I,Q)
792 type_indexed_identifier_index(IndexType,C,I,NSize),
793 type_indexed_identifier_size(IndexType,NSize),
795 get_type_indexed_identifier_index(IndexType,C,I,Q)
797 type_indexed_identifier_index(IndexType,C,I,2),
798 type_indexed_identifier_size(IndexType,2),
801 type_indexed_identifier_structure(IndexType,Structure) :-
802 type_indexed_identifier_name(IndexType,type_indexed_identifier_struct,Functor),
803 get_type_indexed_identifier_size(IndexType,Arity),
804 functor(Structure,Functor,Arity).
805 type_indexed_identifier_name(IndexType,Prefix,Name) :-
807 IndexTypeName = IndexType
809 term_to_atom(IndexType,IndexTypeName)
811 atom_concat_list([Prefix,'_',IndexTypeName],Name).
813 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
818 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
822 chr_translate(Declarations,NewDeclarations) :-
823 chr_translate_line_info(Declarations,'bootstrap',NewDeclarations).
825 chr_translate_line_info(Declarations,File,NewDeclarations) :-
826 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',[]),
828 chr_source_file(File),
829 partition_clauses(Declarations,Constraints0,Rules0,OtherClauses),
830 chr_compiler_options:sanity_check,
831 check_declared_constraints(Constraints0),
832 generate_show_constraint(Constraints0,Constraints,Rules0,Rules1),
833 add_constraints(Constraints),
835 generate_never_stored_rules(Constraints,NewRules),
837 append(Rules1,NewRules,Rules),
839 check_rules(Rules,Constraints),
840 time('type checking',chr_translate:static_type_check),
841 add_occurrences(Rules),
842 time('functional dependency',chr_translate:functional_dependency_analysis(Rules)),
843 time('set semantics',chr_translate:set_semantics_rules(Rules)),
844 time('symmetry analysis',chr_translate:symmetry_analysis(Rules)),
845 time('guard simplification',chr_translate:guard_simplification),
846 time('late storage',chr_translate:storage_analysis(Constraints)),
847 time('observation',chr_translate:observation_analysis(Constraints)),
848 time('ai observation',chr_translate:ai_observation_analysis(Constraints)),
849 time('late allocation',chr_translate:late_allocation_analysis(Constraints)),
850 partial_wake_analysis,
851 time('assume constraint stores',chr_translate:assume_constraint_stores(Constraints)),
852 time('default constraint indices',chr_translate:set_constraint_indices(Constraints)),
853 time('check storedness assertions',chr_translate:check_storedness_assertions(Constraints)),
855 time('constraint code generation',chr_translate:constraints_code(Constraints,ConstraintClauses)),
856 time('validate store assumptions',chr_translate:validate_store_type_assumptions(Constraints)),
857 phase_end(validate_store_type_assumptions),
859 time('store code generation',chr_translate:store_management_preds(Constraints,StoreClauses)), % depends on actual code used
860 insert_declarations(OtherClauses, Clauses0),
861 chr_module_declaration(CHRModuleDeclaration),
862 append([StoreClauses,ConstraintClauses,CHRModuleDeclaration,[end_of_file]],StuffyGeneratedClauses),
863 clean_clauses(StuffyGeneratedClauses,GeneratedClauses),
864 append([Clauses0,GeneratedClauses], NewDeclarations).
866 store_management_preds(Constraints,Clauses) :-
867 generate_attach_detach_a_constraint_all(Constraints,AttachAConstraintClauses),
868 generate_attr_unify_hook(AttrUnifyHookClauses),
869 generate_attach_increment(AttachIncrementClauses),
870 generate_extra_clauses(Constraints,ExtraClauses),
871 generate_insert_delete_constraints(Constraints,DeleteClauses),
872 generate_attach_code(Constraints,StoreClauses),
873 generate_counter_code(CounterClauses),
874 generate_dynamic_type_check_clauses(TypeCheckClauses),
875 append([AttachAConstraintClauses
876 ,AttachIncrementClauses
877 ,AttrUnifyHookClauses
887 insert_declarations(Clauses0, Clauses) :-
888 findall(:- use_module(chr(Module)),(auxiliary_module(Module), is_used_auxiliary_module(Module)),Decls),
889 append(Clauses0, [:- use_module(chr(chr_runtime))|Decls], Clauses).
891 auxiliary_module(chr_hashtable_store).
892 auxiliary_module(chr_integertable_store).
893 auxiliary_module(chr_assoc_store).
895 generate_counter_code(Clauses) :-
896 ( chr_pp_flag(store_counter,on) ->
898 ('$counter_init'(N1) :- nb_setval(N1,0)) ,
899 ('$counter'(N2,X1) :- nb_getval(N2,X1)),
900 ('$counter_inc'(N) :- nb_getval(N,X), Y is X + 1, nb_setval(N,Y)),
901 (:- '$counter_init'('$insert_counter')),
902 (:- '$counter_init'('$delete_counter')),
903 ('$insert_counter_inc' :- '$counter_inc'('$insert_counter')),
904 ('$delete_counter_inc' :- '$counter_inc'('$delete_counter')),
905 ( counter_stats(I,D) :- '$counter'('$insert_counter',I),'$counter'('$delete_counter',D))
911 % for systems with multifile declaration
912 chr_module_declaration(CHRModuleDeclaration) :-
913 get_target_module(Mod),
914 ( Mod \== chr_translate, chr_pp_flag(toplevel_show_store,on) ->
915 CHRModuleDeclaration = [
916 (:- multifile chr:'$chr_module'/1),
917 chr:'$chr_module'(Mod)
920 CHRModuleDeclaration = []
924 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
926 %% Partitioning of clauses into constraint declarations, chr rules and other
929 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
930 %% partition_clauses(+Clauses,-ConstraintDeclarations,-Rules,-OtherClauses) is det.
931 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
932 partition_clauses([],[],[],[]).
933 partition_clauses([Clause|Clauses],ConstraintDeclarations,Rules,OtherClauses) :-
934 ( parse_rule(Clause,Rule) ->
935 ConstraintDeclarations = RestConstraintDeclarations,
936 Rules = [Rule|RestRules],
937 OtherClauses = RestOtherClauses
938 ; is_declaration(Clause,ConstraintDeclaration) ->
939 append(ConstraintDeclaration,RestConstraintDeclarations,ConstraintDeclarations),
941 OtherClauses = RestOtherClauses
942 ; is_module_declaration(Clause,Mod) ->
944 ConstraintDeclarations = RestConstraintDeclarations,
946 OtherClauses = [Clause|RestOtherClauses]
947 ; is_type_definition(Clause) ->
948 ConstraintDeclarations = RestConstraintDeclarations,
950 OtherClauses = RestOtherClauses
951 ; Clause = (handler _) ->
952 chr_warning(deprecated(Clause),'Backward compatibility: ignoring handler/1 declaration.\n',[]),
953 ConstraintDeclarations = RestConstraintDeclarations,
955 OtherClauses = RestOtherClauses
956 ; Clause = (rules _) ->
957 chr_warning(deprecated(Clause),'Backward compatibility: ignoring rules/1 declaration.\n',[]),
958 ConstraintDeclarations = RestConstraintDeclarations,
960 OtherClauses = RestOtherClauses
961 ; Clause = option(OptionName,OptionValue) ->
962 chr_warning(deprecated(Clause),'Instead use `:-chr_option(~w,~w).\'\n',[OptionName,OptionValue]),
963 handle_option(OptionName,OptionValue),
964 ConstraintDeclarations = RestConstraintDeclarations,
966 OtherClauses = RestOtherClauses
967 ; Clause = (:-chr_option(OptionName,OptionValue)) ->
968 handle_option(OptionName,OptionValue),
969 ConstraintDeclarations = RestConstraintDeclarations,
971 OtherClauses = RestOtherClauses
972 ; Clause = ('$chr_compiled_with_version'(_)) ->
973 ConstraintDeclarations = RestConstraintDeclarations,
975 OtherClauses = ['$chr_compiled_with_version'(3)|RestOtherClauses]
976 ; ConstraintDeclarations = RestConstraintDeclarations,
978 OtherClauses = [Clause|RestOtherClauses]
980 partition_clauses(Clauses,RestConstraintDeclarations,RestRules,RestOtherClauses).
982 '$chr_compiled_with_version'(2).
984 is_declaration(D, Constraints) :- %% constraint declaration
985 ( D = (:- Decl), Decl =.. [F,Cs], F == (chr_constraint) ->
986 conj2list(Cs,Constraints0)
989 Decl =.. [constraints,Cs]
991 D =.. [constraints,Cs]
993 conj2list(Cs,Constraints0),
994 chr_warning(deprecated(D),'Instead use :- chr_constraint ~w.\n',[Cs])
996 extract_type_mode(Constraints0,Constraints).
998 extract_type_mode([],[]).
999 extract_type_mode([F/A|R],[F/A|R2]) :- !,extract_type_mode(R,R2).
1000 extract_type_mode([C0|R],[ConstraintSymbol|R2]) :-
1001 ( C0 = C # Annotation ->
1003 extract_annotation(Annotation,F/A)
1008 ConstraintSymbol = F/A,
1010 extract_types_and_modes(Args,ArgTypes,ArgModes),
1011 assert_constraint_type(ConstraintSymbol,ArgTypes),
1012 constraint_mode(ConstraintSymbol,ArgModes),
1013 extract_type_mode(R,R2).
1015 extract_annotation(stored,Symbol) :-
1016 stored_assertion(Symbol).
1017 extract_annotation(default(Goal),Symbol) :-
1018 never_stored_default(Symbol,Goal).
1020 extract_types_and_modes([],[],[]).
1021 extract_types_and_modes([X|R],[T|R2],[M|R3]) :-
1022 extract_type_and_mode(X,T,M),
1023 extract_types_and_modes(R,R2,R3).
1025 extract_type_and_mode(+(T),T,(+)) :- !.
1026 extract_type_and_mode(?(T),T,(?)) :- !.
1027 extract_type_and_mode(-(T),T,(-)) :- !.
1028 extract_type_and_mode((+),any,(+)) :- !.
1029 extract_type_and_mode((?),any,(?)) :- !.
1030 extract_type_and_mode((-),any,(-)) :- !.
1031 extract_type_and_mode(Illegal,_,_) :-
1032 chr_error(syntax(Illegal),'Illegal mode/type declaration.\n\tCorrect syntax is +type, -type or ?type\n\tor +, - or ?.\n',[]).
1034 is_type_definition(Declaration) :-
1035 ( Declaration = (:- TDef) ->
1040 TDef =.. [chr_type,TypeDef],
1041 ( TypeDef = (Name ---> Def) ->
1042 tdisj2list(Def,DefList),
1043 type_definition(Name,DefList)
1044 ; TypeDef = (Alias == Name) ->
1045 type_alias(Alias,Name)
1047 type_definition(TypeDef,[]),
1048 chr_warning(syntax,'Empty type definition `~w\'.\nAre you sure you want to declare a phantom type?\n',[Declaration])
1051 %% tdisj2list(+Goal,-ListOfGoals) is det.
1053 % no removal of fails, e.g. :- type bool ---> true ; fail.
1054 tdisj2list(Conj,L) :-
1055 tdisj2list(Conj,L,[]).
1057 tdisj2list(Conj,L,T) :-
1059 tdisj2list(G1,L,T1),
1060 tdisj2list(G2,T1,T).
1061 tdisj2list(G,[G | T],T).
1064 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
1065 %% parse_rule(+term,-pragma_rule) is semidet.
1066 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
1067 parse_rule(RI,R) :- %% name @ rule
1068 RI = (Name @ RI2), !,
1069 rule(RI2,yes(Name),R).
1073 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
1074 %% parse_rule(+term,-pragma_rule) is semidet.
1075 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
1077 RI = (RI2 pragma P), !, %% pragmas
1079 Ps = [_] % intercept variable
1083 inc_rule_count(RuleCount),
1084 R = pragma(R1,IDs,Ps,Name,RuleCount),
1085 is_rule(RI2,R1,IDs,R).
1087 inc_rule_count(RuleCount),
1088 R = pragma(R1,IDs,[],Name,RuleCount),
1089 is_rule(RI,R1,IDs,R).
1091 is_rule(RI,R,IDs,RC) :- %% propagation rule
1093 conj2list(H,Head2i),
1094 get_ids(Head2i,IDs2,Head2,RC),
1097 R = rule([],Head2,G,RB)
1099 R = rule([],Head2,true,B)
1101 is_rule(RI,R,IDs,RC) :- %% simplification/simpagation rule
1110 conj2list(H1,Head2i),
1111 conj2list(H2,Head1i),
1112 get_ids(Head2i,IDs2,Head2,0,N,RC),
1113 get_ids(Head1i,IDs1,Head1,N,_,RC),
1114 IDs = ids(IDs1,IDs2)
1115 ; conj2list(H,Head1i),
1117 get_ids(Head1i,IDs1,Head1,RC),
1120 R = rule(Head1,Head2,Guard,Body).
1122 get_ids(Cs,IDs,NCs,RC) :-
1123 get_ids(Cs,IDs,NCs,0,_,RC).
1125 get_ids([],[],[],N,N,_).
1126 get_ids([C|Cs],[N|IDs],[NC|NCs],N,NN,RC) :-
1131 check_direct_pragma(N1,N,RC)
1137 get_ids(Cs,IDs,NCs, M,NN,RC).
1139 check_direct_pragma(passive,Id,PragmaRule) :- !,
1140 PragmaRule = pragma(_,_,_,_,RuleNb),
1142 check_direct_pragma(Abbrev,Id,PragmaRule) :-
1143 ( direct_pragma(FullPragma),
1144 atom_concat(Abbrev,Remainder,FullPragma) ->
1145 chr_warning(problem_pragma(Abbrev,PragmaRule),'completed `~w\' to `~w\'\n',[Abbrev,FullPragma])
1147 chr_warning(unsupported_pragma(Abbrev,PragmaRule),'',[])
1150 direct_pragma(passive).
1152 is_module_declaration((:- module(Mod)),Mod).
1153 is_module_declaration((:- module(Mod,_)),Mod).
1155 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1157 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1159 add_constraints([]).
1160 add_constraints([C|Cs]) :-
1161 max_occurrence(C,0),
1165 constraint_mode(C,Mode),
1166 add_constraints(Cs).
1170 add_rules([Rule|Rules]) :-
1171 Rule = pragma(_,_,_,_,RuleNb),
1175 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1177 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1178 %% Some input verification:
1180 check_declared_constraints(Constraints) :-
1181 check_declared_constraints(Constraints,[]).
1183 check_declared_constraints([],_).
1184 check_declared_constraints([C|Cs],Acc) :-
1185 ( memberchk_eq(C,Acc) ->
1186 chr_error(syntax(C),'Constraint multiply defined: ~w.\n\tRemove redundant declaration!\n',[C])
1190 check_declared_constraints(Cs,[C|Acc]).
1192 %% - all constraints in heads are declared constraints
1193 %% - all passive pragmas refer to actual head constraints
1196 check_rules([PragmaRule|Rest],Decls) :-
1197 check_rule(PragmaRule,Decls),
1198 check_rules(Rest,Decls).
1200 check_rule(PragmaRule,Decls) :-
1201 check_rule_indexing(PragmaRule),
1202 check_trivial_propagation_rule(PragmaRule),
1203 PragmaRule = pragma(Rule,_IDs,Pragmas,_Name,_N),
1204 Rule = rule(H1,H2,_,_),
1205 append(H1,H2,HeadConstraints),
1206 check_head_constraints(HeadConstraints,Decls,PragmaRule),
1207 check_pragmas(Pragmas,PragmaRule).
1209 % Make all heads passive in trivial propagation rule
1210 % ... ==> ... | true.
1211 check_trivial_propagation_rule(PragmaRule) :-
1212 PragmaRule = pragma(Rule,IDs,Pragmas,Name,RuleNb),
1213 ( Rule = rule([],_,_,true) ->
1214 chr_warning(weird_program,'Ignoring propagation rule with empty body: ~@.\n\t\n',[format_rule(PragmaRule)]),
1215 set_all_passive(RuleNb)
1220 check_head_constraints([],_,_).
1221 check_head_constraints([Constr|Rest],Decls,PragmaRule) :-
1222 functor(Constr,F,A),
1223 ( member(F/A,Decls) ->
1224 check_head_constraints(Rest,Decls,PragmaRule)
1226 chr_error(syntax(Constr),'Undeclared constraint ~w in head of ~@.\n\tConstraint should be one of ~w.\n', [F/A,format_rule(PragmaRule),Decls])
1229 check_pragmas([],_).
1230 check_pragmas([Pragma|Pragmas],PragmaRule) :-
1231 check_pragma(Pragma,PragmaRule),
1232 check_pragmas(Pragmas,PragmaRule).
1234 check_pragma(Pragma,PragmaRule) :-
1236 chr_error(syntax(Pragma),'Invalid pragma ~w in ~@.\n\tPragma should not be a variable!\n',[Pragma,format_rule(PragmaRule)]).
1237 check_pragma(passive(ID), PragmaRule) :-
1239 PragmaRule = pragma(_,ids(IDs1,IDs2),_,_,RuleNb),
1240 ( memberchk_eq(ID,IDs1) ->
1242 ; memberchk_eq(ID,IDs2) ->
1245 chr_error(syntax(ID),'Invalid identifier ~w in pragma passive in ~@.\n', [ID,format_rule(PragmaRule)])
1249 check_pragma(mpassive(IDs), PragmaRule) :-
1251 PragmaRule = pragma(_,_,_,_,RuleNb),
1252 chr_warning(experimental,'Experimental pragma ~w. Use with care!\n',[mpassive(IDs)]),
1253 maplist(passive(RuleNb),IDs).
1255 check_pragma(Pragma, PragmaRule) :-
1256 Pragma = already_in_heads,
1258 chr_warning(unsupported_pragma(Pragma,PragmaRule),'Termination and correctness may be affected.\n',[]).
1260 check_pragma(Pragma, PragmaRule) :-
1261 Pragma = already_in_head(_),
1263 chr_warning(unsupported_pragma(Pragma,PragmaRule),'Termination and correctness may be affected.\n',[]).
1265 check_pragma(Pragma, PragmaRule) :-
1266 Pragma = no_history,
1268 chr_warning(experimental,'Experimental pragma no_history. Use with care!\n',[]),
1269 PragmaRule = pragma(_,_,_,_,N),
1272 check_pragma(Pragma, PragmaRule) :-
1273 Pragma = history(HistoryName,IDs),
1275 PragmaRule = pragma(_,ids(IDs1,IDs2),_,_,RuleNb),
1276 chr_warning(experimental,'Experimental pragma ~w. Use with care!\n',[Pragma]),
1278 chr_error(syntax(Pragma),'Pragma history only implemented for propagation rules.\n',[])
1279 ; \+ atom(HistoryName) ->
1280 chr_error(syntax(Pragma),'Illegal argument for pragma history: ~w is not an atom (rule number ~w).\n',[HistoryName,RuleNb])
1282 chr_error(syntax(Pragma),'Illegal argument for pragma history: ~w is not a set (rule number ~w).\n',[IDs,RuleNb])
1283 ; check_history_pragma_ids(IDs,IDs1,IDs2) ->
1284 history(RuleNb,HistoryName,IDs)
1286 chr_error(syntax(Pragma),'Invalid identifier(s) in pragma ~w of rule number ~w.\n',[Pragma,RuleNb])
1288 check_pragma(Pragma,PragmaRule) :-
1289 Pragma = line_number(LineNumber),
1291 PragmaRule = pragma(_,_,_,_,RuleNb),
1292 line_number(RuleNb,LineNumber).
1294 check_history_pragma_ids([], _, _).
1295 check_history_pragma_ids([ID|IDs],IDs1,IDs2) :-
1296 ( memberchk_eq(ID,IDs2) ; memberchk_eq(ID,IDs1) ),
1297 check_history_pragma_ids(IDs,IDs1,IDs2).
1299 check_pragma(Pragma,PragmaRule) :-
1300 chr_error(syntax(Pragma),'Unknown pragma ~w in ~@.\n', [Pragma,format_rule(PragmaRule)]).
1302 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1303 %% no_history(+RuleNb) is det.
1304 :- chr_constraint no_history/1.
1305 :- chr_option(mode,no_history(+)).
1306 :- chr_option(type_declaration,no_history(int)).
1308 %% has_no_history(+RuleNb) is semidet.
1309 :- chr_constraint has_no_history/1.
1310 :- chr_option(mode,has_no_history(+)).
1311 :- chr_option(type_declaration,has_no_history(int)).
1313 no_history(RuleNb) \ has_no_history(RuleNb) <=> true.
1314 has_no_history(_) <=> fail.
1316 :- chr_constraint history/3.
1317 :- chr_option(mode,history(+,+,+)).
1318 :- chr_option(type_declaration,history(any,any,list)).
1320 :- chr_constraint named_history/3.
1322 history(RuleNb,_,_), history(RuleNb,_,_) ==>
1323 chr_error(syntax,'Only one pragma history allowed per rule (rule number ~w)\n',[RuleNb]). %'
1325 history(RuleNb1,Name,IDs1), history(RuleNb2,Name,IDs2) ==>
1326 length(IDs1,L1), length(IDs2,L2),
1328 chr_error(syntax,'The history named ~w does not always range over an equal amount of occurrences.\n',[Name])
1330 test_named_history_id_pairs(RuleNb1,IDs1,RuleNb2,IDs2)
1333 test_named_history_id_pairs(_, [], _, []).
1334 test_named_history_id_pairs(RuleNb1, [ID1|IDs1], RuleNb2, [ID2|IDs2]) :-
1335 test_named_history_id_pair(RuleNb1,ID1,RuleNb2,ID2),
1336 test_named_history_id_pairs(RuleNb1,IDs1,RuleNb2,IDs2).
1338 :- chr_constraint test_named_history_id_pair/4.
1339 :- chr_option(mode,test_named_history_id_pair(+,+,+,+)).
1341 occurrence(C,_,RuleNb1,ID1,_), occurrence(C,_,RuleNb2,ID2,_)
1342 \ test_named_history_id_pair(RuleNb1,ID1,RuleNb2,ID2) <=> true.
1343 test_named_history_id_pair(RuleNb1,ID1,RuleNb2,ID2) <=>
1344 chr_error(syntax,'Occurrences of shared history in rules number ~w and ~w do not correspond\n', [RuleNb2,RuleNb1]).
1346 history(RuleNb,Name,IDs) \ named_history(RuleNb,QName,QIDs) <=> QName = Name, QIDs = IDs.
1347 named_history(_,_,_) <=> fail.
1349 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1352 format_rule(PragmaRule) :-
1353 PragmaRule = pragma(_,_,_,MaybeName,RuleNumber),
1354 ( MaybeName = yes(Name) ->
1355 write('rule '), write(Name)
1357 write('rule number '), write(RuleNumber)
1359 get_line_number(RuleNumber,LineNumber),
1364 check_rule_indexing(PragmaRule) :-
1365 PragmaRule = pragma(Rule,_,_,_,_),
1366 Rule = rule(H1,H2,G,_),
1367 term_variables(H1-H2,HeadVars),
1368 remove_anti_monotonic_guards(G,HeadVars,NG),
1369 check_indexing(H1,NG-H2),
1370 check_indexing(H2,NG-H1),
1372 ( chr_pp_flag(term_indexing,on) ->
1373 term_variables(NG,GuardVariables),
1374 append(H1,H2,Heads),
1375 check_specs_indexing(Heads,GuardVariables,Specs)
1380 :- chr_constraint indexing_spec/2.
1381 :- chr_option(mode,indexing_spec(+,+)).
1383 :- chr_constraint get_indexing_spec/2.
1384 :- chr_option(mode,get_indexing_spec(+,-)).
1387 indexing_spec(FA,Spec) \ get_indexing_spec(FA,R) <=> R = Spec.
1388 get_indexing_spec(_,Spec) <=> Spec = [].
1390 indexing_spec(FA,Specs1), indexing_spec(FA,Specs2)
1392 append(Specs1,Specs2,Specs),
1393 indexing_spec(FA,Specs).
1395 remove_anti_monotonic_guards(G,Vars,NG) :-
1397 remove_anti_monotonic_guard_list(GL,Vars,NGL),
1400 remove_anti_monotonic_guard_list([],_,[]).
1401 remove_anti_monotonic_guard_list([G|Gs],Vars,NGs) :-
1402 ( G = var(X), memberchk_eq(X,Vars) ->
1404 % TODO: this is not correct
1405 % ; G = functor(Term,Functor,Arity), % isotonic
1406 % \+ memberchk_eq(Functor,Vars), \+ memberchk_eq(Arity,Vars) ->
1411 remove_anti_monotonic_guard_list(Gs,Vars,RGs).
1413 check_indexing([],_).
1414 check_indexing([Head|Heads],Other) :-
1417 term_variables(Heads-Other,OtherVars),
1418 check_indexing(Args,1,F/A,OtherVars),
1419 check_indexing(Heads,[Head|Other]).
1421 check_indexing([],_,_,_).
1422 check_indexing([Arg|Args],I,FA,OtherVars) :-
1423 ( is_indexed_argument(FA,I) ->
1426 indexed_argument(FA,I)
1428 term_variables(Args,ArgsVars),
1429 append(ArgsVars,OtherVars,RestVars),
1430 ( memberchk_eq(Arg,RestVars) ->
1431 indexed_argument(FA,I)
1437 term_variables(Arg,NVars),
1438 append(NVars,OtherVars,NOtherVars),
1439 check_indexing(Args,J,FA,NOtherVars).
1441 check_specs_indexing([],_,[]).
1442 check_specs_indexing([Head|Heads],Variables,Specs) :-
1443 Specs = [Spec|RSpecs],
1444 term_variables(Heads,OtherVariables,Variables),
1445 check_spec_indexing(Head,OtherVariables,Spec),
1446 term_variables(Head,NVariables,Variables),
1447 check_specs_indexing(Heads,NVariables,RSpecs).
1449 check_spec_indexing(Head,OtherVariables,Spec) :-
1451 Spec = spec(F,A,ArgSpecs),
1453 check_args_spec_indexing(Args,1,OtherVariables,ArgSpecs),
1454 indexing_spec(F/A,[ArgSpecs]).
1456 check_args_spec_indexing([],_,_,[]).
1457 check_args_spec_indexing([Arg|Args],I,OtherVariables,ArgSpecs) :-
1458 term_variables(Args,Variables,OtherVariables),
1459 ( check_arg_spec_indexing(Arg,I,Variables,ArgSpec) ->
1460 ArgSpecs = [ArgSpec|RArgSpecs]
1462 ArgSpecs = RArgSpecs
1465 term_variables(Arg,NOtherVariables,OtherVariables),
1466 check_args_spec_indexing(Args,J,NOtherVariables,RArgSpecs).
1468 check_arg_spec_indexing(Arg,I,Variables,ArgSpec) :-
1470 memberchk_eq(Arg,Variables),
1471 ArgSpec = specinfo(I,any,[])
1474 ArgSpec = specinfo(I,F/A,[ArgSpecs]),
1476 check_args_spec_indexing(Args,1,Variables,ArgSpecs)
1479 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1481 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1484 add_occurrences([]).
1485 add_occurrences([Rule|Rules]) :-
1486 Rule = pragma(rule(H1,H2,_,_),ids(IDs1,IDs2),_,_,Nb),
1487 add_occurrences(H1,IDs1,simplification,Nb),
1488 add_occurrences(H2,IDs2,propagation,Nb),
1489 add_occurrences(Rules).
1491 add_occurrences([],[],_,_).
1492 add_occurrences([H|Hs],[ID|IDs],Type,RuleNb) :-
1495 new_occurrence(FA,RuleNb,ID,Type),
1496 add_occurrences(Hs,IDs,Type,RuleNb).
1498 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1500 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1501 % Observation Analysis
1511 :- chr_constraint observation_analysis/1.
1512 :- chr_option(mode, observation_analysis(+)).
1514 observation_analysis(Cs), rule(RuleNb,PragmaRule) # Id ==>
1515 PragmaRule = pragma(rule(_,_,Guard,Body),_,_,_,_),
1516 ( chr_pp_flag(store_in_guards, on) ->
1517 observation_analysis(RuleNb, Guard, guard, Cs)
1521 observation_analysis(RuleNb, Body, body, Cs)
1524 observation_analysis(_) <=> true.
1526 observation_analysis(RuleNb, Term, GB, Cs) :-
1527 ( all_spawned(RuleNb,GB) ->
1530 spawns_all(RuleNb,GB)
1538 observation_analysis(RuleNb,T1,GB,Cs),
1539 observation_analysis(RuleNb,T2,GB,Cs)
1541 observation_analysis(RuleNb,T1,GB,Cs),
1542 observation_analysis(RuleNb,T2,GB,Cs)
1543 ; Term = (T1->T2) ->
1544 observation_analysis(RuleNb,T1,GB,Cs),
1545 observation_analysis(RuleNb,T2,GB,Cs)
1547 observation_analysis(RuleNb,T,GB,Cs)
1548 ; functor(Term,F,A), member(F/A,Cs) ->
1549 spawns(RuleNb,GB,F/A)
1551 spawns_all_triggers(RuleNb,GB)
1552 ; Term = (_ is _) ->
1553 spawns_all_triggers(RuleNb,GB)
1554 ; builtin_binds_b(Term,Vars) ->
1558 spawns_all_triggers(RuleNb,GB)
1561 spawns_all(RuleNb,GB)
1564 :- chr_constraint spawns/3.
1565 :- chr_option(mode, spawns(+,+,+)).
1566 :- chr_type spawns_type ---> guard ; body.
1567 :- chr_option(type_declaration,spawns(any,spawns_type,any)).
1569 :- chr_constraint spawns_all/2, spawns_all_triggers/2.
1570 :- chr_option(mode, spawns_all(+,+)).
1571 :- chr_option(type_declaration,spawns_all(any,spawns_type)).
1572 :- chr_option(mode, spawns_all_triggers(+,+)).
1573 :- chr_option(type_declaration,spawns_all_triggers(any,spawns_type)).
1575 spawns_all(RuleNb,GB) \ spawns_all(RuleNb,GB) <=> true.
1576 spawns_all(RuleNb,guard) \ spawns_all(RuleNb,body) <=> true.
1577 spawns_all_triggers(RuleNb,GB) \ spawns_all_triggers(RuleNb,GB) <=> true.
1578 spawns_all_triggers(RuleNb,guard) \ spawns_all_triggers(RuleNb,body) <=> true.
1579 spawns(RuleNb,GB,C) \ spawns(RuleNb,GB,C) <=> true.
1580 spawns(RuleNb,guard,C) \ spawns(RuleNb,body,C) <=> true.
1582 spawns_all(RuleNb,GB) \ spawns(RuleNb,GB,_) <=> true.
1583 spawns_all(RuleNb,guard) \ spawns(RuleNb,body,_) <=> true.
1584 spawns_all(RuleNb,GB) \ spawns_all_triggers(RuleNb,GB) <=> true.
1585 spawns_all(RuleNb,guard) \ spawns_all_triggers(RuleNb,body) <=> true.
1587 spawns_all_triggers(RuleNb,GB) \ spawns(RuleNb,GB,C) <=> may_trigger(C) | true.
1588 spawns_all_triggers(RuleNb,guard) \ spawns(RuleNb,body,C) <=> may_trigger(C) | true.
1590 spawns_all(RuleNb2,_), occurrence(C1,_,RuleNb2,O,_)#Id
1592 spawns(RuleNb1,GB,C1)
1594 \+ is_passive(RuleNb2,O)
1596 spawns_all(RuleNb1,GB)
1600 occurrence(C1,_,RuleNb2,O,_)#Id, spawns_all(RuleNb2,_)
1602 \+(\+ spawns_all_triggers_implies_spawns_all), % in the hope it schedules this guard early...
1603 \+ is_passive(RuleNb2,O), may_trigger(C1)
1605 spawns_all_triggers_implies_spawns_all
1609 :- chr_constraint spawns_all_triggers_implies_spawns_all/0.
1610 spawns_all_triggers_implies_spawns_all, spawns_all_triggers_implies_spawns_all <=> fail.
1611 spawns_all_triggers_implies_spawns_all \
1612 spawns_all_triggers(RuleNb,GB) <=> spawns_all(RuleNb,GB).
1614 spawns_all_triggers(RuleNb2,_), occurrence(C1,_,RuleNb2,O,_)#Id
1616 spawns(RuleNb1,GB,C1)
1619 \+ is_passive(RuleNb2,O)
1621 spawns_all_triggers(RuleNb1,GB)
1625 spawns_all_triggers(RuleNb2,_), occurrence(C1,_,RuleNb2,O,_)#Id,
1626 spawns(RuleNb1,GB,C1)
1629 \+ is_passive(RuleNb2,O)
1631 spawns_all_triggers(RuleNb1,GB)
1635 % a bit dangerous this rule: could start propagating too much too soon?
1636 spawns(RuleNb2,_,C2), occurrence(C1,_,RuleNb2,O,_)#Id,
1637 spawns(RuleNb1,GB,C1)
1639 RuleNb1 \== RuleNb2, C1 \== C2,
1640 \+ is_passive(RuleNb2,O)
1642 spawns(RuleNb1,GB,C2)
1646 spawns(RuleNb2,_,C2), occurrence(C1,_,RuleNb2,O,_)#Id,
1647 spawns_all_triggers(RuleNb1,GB)
1649 \+ is_passive(RuleNb2,O), may_trigger(C1), \+ may_trigger(C2)
1651 spawns(RuleNb1,GB,C2)
1656 :- chr_constraint all_spawned/2.
1657 :- chr_option(mode, all_spawned(+,+)).
1658 spawns_all(RuleNb,guard) \ all_spawned(RuleNb,_) <=> true.
1659 spawns_all(RuleNb,GB) \ all_spawned(RuleNb,GB) <=> true.
1660 all_spawned(RuleNb,GB) <=> fail.
1663 % Overview of the supported queries:
1664 % is_observed(+functor/artiy, +occurrence_number, +(guard;body))
1665 % only succeeds if the occurrence is observed by the
1666 % guard resp. body (depending on the last argument) of its rule
1667 % is_observed(+functor/artiy, +occurrence_number, -)
1668 % succeeds if the occurrence is observed by either the guard or
1669 % the body of its rule
1670 % NOTE: the last argument is NOT bound by this query
1672 % do_is_observed(+functor/artiy,+rule_number,+(guard;body))
1673 % succeeds if the given constraint is observed by the given
1675 % do_is_observed(+functor/artiy,+rule_number)
1676 % succeeds if the given constraint is observed by the given
1677 % rule (either its guard or its body)
1682 ai_is_observed(C,O).
1684 is_stored_in_guard(C,RuleNb) :-
1685 chr_pp_flag(store_in_guards, on),
1686 do_is_observed(C,RuleNb,guard).
1688 :- chr_constraint is_observed/3.
1689 :- chr_option(mode, is_observed(+,+,+)).
1690 occurrence(C,O,RuleNb,_,_) \ is_observed(C,O,GB) <=> do_is_observed(C,RuleNb,GB).
1691 is_observed(_,_,_) <=> fail. % this will not happen in practice
1694 :- chr_constraint do_is_observed/3.
1695 :- chr_option(mode, do_is_observed(+,+,+)).
1696 :- chr_constraint do_is_observed/2.
1697 :- chr_option(mode, do_is_observed(+,+)).
1699 do_is_observed(C,RuleNb,GB) <=> var(GB) | do_is_observed(C,RuleNb).
1702 % a constraint C is observed if the GB of the rule it occurs in spawns all,
1703 % and some non-passive occurrence of some (possibly other) constraint
1704 % exists in a rule (could be same rule) with at least one occurrence of C
1706 spawns_all(RuleNb,GB),
1707 occurrence(_,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1709 do_is_observed(C,RuleNb,GB)
1711 \+ is_passive(RuleNb2,O)
1715 spawns_all(RuleNb,_),
1716 occurrence(_,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1718 do_is_observed(C,RuleNb)
1720 \+ is_passive(RuleNb2,O)
1725 % a constraint C is observed if the GB of the rule it occurs in spawns a
1726 % constraint C2 that occurs non-passively in a rule (possibly the same rule)
1727 % as an occurrence of C
1729 spawns(RuleNb,GB,C2),
1730 occurrence(C2,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1732 do_is_observed(C,RuleNb,GB)
1734 \+ is_passive(RuleNb2,O)
1738 spawns(RuleNb,_,C2),
1739 occurrence(C2,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1741 do_is_observed(C,RuleNb)
1743 \+ is_passive(RuleNb2,O)
1747 % (3) spawns_all_triggers
1748 % a constraint C is observed if the GB of the rule it occurs in spawns all triggers
1749 % and some non-passive occurrence of some (possibly other) constraint that may trigger
1750 % exists in a rule (could be same rule) with at least one occurrence of C
1752 spawns_all_triggers(RuleNb,GB),
1753 occurrence(C2,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1755 do_is_observed(C,RuleNb,GB)
1757 \+ is_passive(RuleNb2,O), may_trigger(C2)
1761 spawns_all_triggers(RuleNb,_),
1762 occurrence(C2,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1764 do_is_observed(C,RuleNb)
1766 \+ is_passive(RuleNb2,O), may_trigger(C2)
1770 % (4) conservativeness
1771 do_is_observed(_,_,_) <=> chr_pp_flag(observation_analysis,off).
1772 do_is_observed(_,_) <=> chr_pp_flag(observation_analysis,off).
1775 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1777 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1780 %% Generated predicates
1781 %% attach_$CONSTRAINT
1783 %% detach_$CONSTRAINT
1786 %% attach_$CONSTRAINT
1787 generate_attach_detach_a_constraint_all([],[]).
1788 generate_attach_detach_a_constraint_all([Constraint|Constraints],Clauses) :-
1789 ( ( chr_pp_flag(debugable,on) ; is_stored(Constraint), \+ only_ground_indexed_arguments(Constraint), \+ get_store_type(Constraint,var_assoc_store(_,_)) ) ->
1790 generate_attach_a_constraint(Constraint,Clauses1),
1791 generate_detach_a_constraint(Constraint,Clauses2)
1796 generate_attach_detach_a_constraint_all(Constraints,Clauses3),
1797 append([Clauses1,Clauses2,Clauses3],Clauses).
1799 generate_attach_a_constraint(Constraint,[Clause1,Clause2]) :-
1800 generate_attach_a_constraint_nil(Constraint,Clause1),
1801 generate_attach_a_constraint_cons(Constraint,Clause2).
1803 attach_constraint_atom(FA,Vars,Susp,Atom) :-
1804 make_name('attach_',FA,Name),
1805 Atom =.. [Name,Vars,Susp].
1807 generate_attach_a_constraint_nil(FA,Clause) :-
1808 Clause = (Head :- true),
1809 attach_constraint_atom(FA,[],_,Head).
1811 generate_attach_a_constraint_cons(FA,Clause) :-
1812 Clause = (Head :- Body),
1813 attach_constraint_atom(FA,[Var|Vars],Susp,Head),
1814 attach_constraint_atom(FA,Vars,Susp,RecursiveCall),
1815 Body = ( AttachBody, Subscribe, RecursiveCall ),
1816 get_max_constraint_index(N),
1818 generate_attach_body_1(FA,Var,Susp,AttachBody)
1820 generate_attach_body_n(FA,Var,Susp,AttachBody)
1822 % SWI-Prolog specific code
1823 chr_pp_flag(solver_events,NMod),
1825 Args = [[Var|_],Susp],
1826 get_target_module(Mod),
1827 use_auxiliary_predicate(run_suspensions),
1828 Subscribe = clp_events:subscribe(Var,NMod,Mod,Mod:'$run_suspensions'([Susp]))
1833 generate_attach_body_1(FA,Var,Susp,Body) :-
1834 get_target_module(Mod),
1836 ( get_attr(Var, Mod, Susps) ->
1837 put_attr(Var, Mod, [Susp|Susps])
1839 put_attr(Var, Mod, [Susp])
1842 generate_attach_body_n(F/A,Var,Susp,Body) :-
1843 get_constraint_index(F/A,Position),
1844 get_max_constraint_index(Total),
1845 get_target_module(Mod),
1846 add_attr(Total,Susp,Position,TAttr,AddGoal,NTAttr),
1847 singleton_attr(Total,Susp,Position,NewAttr3),
1849 ( get_attr(Var,Mod,TAttr) ->
1851 put_attr(Var,Mod,NTAttr)
1853 put_attr(Var,Mod,NewAttr3)
1856 %% detach_$CONSTRAINT
1857 generate_detach_a_constraint(Constraint,[Clause1,Clause2]) :-
1858 generate_detach_a_constraint_nil(Constraint,Clause1),
1859 generate_detach_a_constraint_cons(Constraint,Clause2).
1861 detach_constraint_atom(FA,Vars,Susp,Atom) :-
1862 make_name('detach_',FA,Name),
1863 Atom =.. [Name,Vars,Susp].
1865 generate_detach_a_constraint_nil(FA,Clause) :-
1866 Clause = ( Head :- true),
1867 detach_constraint_atom(FA,[],_,Head).
1869 generate_detach_a_constraint_cons(FA,Clause) :-
1870 Clause = (Head :- Body),
1871 detach_constraint_atom(FA,[Var|Vars],Susp,Head),
1872 detach_constraint_atom(FA,Vars,Susp,RecursiveCall),
1873 Body = ( DetachBody, RecursiveCall ),
1874 get_max_constraint_index(N),
1876 generate_detach_body_1(FA,Var,Susp,DetachBody)
1878 generate_detach_body_n(FA,Var,Susp,DetachBody)
1881 generate_detach_body_1(FA,Var,Susp,Body) :-
1882 get_target_module(Mod),
1884 ( get_attr(Var,Mod,Susps) ->
1885 'chr sbag_del_element'(Susps,Susp,NewSusps),
1889 put_attr(Var,Mod,NewSusps)
1895 generate_detach_body_n(F/A,Var,Susp,Body) :-
1896 get_constraint_index(F/A,Position),
1897 get_max_constraint_index(Total),
1898 rem_attr(Total,Var,Susp,Position,TAttr,RemGoal),
1899 get_target_module(Mod),
1901 ( get_attr(Var,Mod,TAttr) ->
1907 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1908 %-------------------------------------------------------------------------------
1909 %% generate_indexed_variables_body(+ConstraintSymbol,+ArgList,-Body,-VarList) is det.
1910 :- chr_constraint generate_indexed_variables_body/4.
1911 :- chr_option(mode,generate_indexed_variables_body(+,?,+,?)).
1912 :- chr_option(type_declaration,generate_indexed_variables_body(constraint,any,any,any)).
1913 %-------------------------------------------------------------------------------
1914 constraint_mode(F/A,ArgModes) \ generate_indexed_variables_body(F/A,Args,Body,Vars) <=>
1915 get_indexing_spec(F/A,Specs),
1916 ( chr_pp_flag(term_indexing,on) ->
1917 spectermvars(Specs,Args,F,A,Body,Vars)
1919 get_constraint_type_det(F/A,ArgTypes),
1920 create_indexed_variables_body(Args,ArgModes,ArgTypes,Vars,1,F/A,MaybeBody,N),
1921 ( MaybeBody == empty ->
1928 Term =.. [term|Args]
1930 Body = term_variables(Term,Vars)
1935 generate_indexed_variables_body(FA,_,_,_) <=>
1936 chr_error(internal,'generate_indexed_variables_body: missing mode info for ~w.\n',[FA]).
1937 %===============================================================================
1939 create_indexed_variables_body([],[],[],_,_,_,empty,0).
1940 create_indexed_variables_body([V|Vs],[Mode|Modes],[Type|Types],Vars,I,FA,Body,N) :-
1942 create_indexed_variables_body(Vs,Modes,Types,Tail,J,FA,RBody,M),
1944 is_indexed_argument(FA,I) ->
1945 ( atomic_type(Type) ->
1956 Continuation = true, Tail = []
1958 Continuation = RBody
1962 Body = term_variables(V,Vars)
1964 Body = (term_variables(V,Vars,Tail),RBody)
1968 ; Mode == (-), is_indexed_argument(FA,I) ->
1972 Body = (Vars = [V|Tail],RBody)
1980 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1982 spectermvars(Specs,Args,F,A,Goal,Vars) :-
1983 spectermvars(Args,1,Specs,F,A,Vars,[],Goal).
1985 spectermvars([],B,_,_,A,L,L,true) :- B > A, !.
1986 spectermvars([Arg|Args],I,Specs,F,A,L,T,Goal) :-
1987 Goal = (ArgGoal,RGoal),
1988 argspecs(Specs,I,TempArgSpecs,RSpecs),
1989 merge_argspecs(TempArgSpecs,ArgSpecs),
1990 arggoal(ArgSpecs,Arg,ArgGoal,L,L1),
1992 spectermvars(Args,J,RSpecs,F,A,L1,T,RGoal).
1994 argspecs([],_,[],[]).
1995 argspecs([[]|Rest],I,ArgSpecs,RestSpecs) :-
1996 argspecs(Rest,I,ArgSpecs,RestSpecs).
1997 argspecs([[specinfo(J,Spec,Args)|Specs]|Rest],I,ArgSpecs,RestSpecs) :-
1999 ArgSpecs = [specinfo(J,Spec,Args)|RArgSpecs],
2001 RRestSpecs = RestSpecs
2003 RestSpecs = [Specs|RRestSpecs]
2006 ArgSpecs = RArgSpecs,
2007 RestSpecs = [[specinfo(J,Spec,Args)|Specs]|RRestSpecs]
2009 argspecs(Rest,I,RArgSpecs,RRestSpecs).
2011 merge_argspecs(In,Out) :-
2013 merge_argspecs_(Sorted,Out).
2015 merge_argspecs_([],[]).
2016 merge_argspecs_([X],R) :- !, R = [X].
2017 merge_argspecs_([specinfo(I,F1,A1),specinfo(I,F2,A2)|Rest],R) :-
2018 ( (F1 == any ; F2 == any) ->
2019 merge_argspecs_([specinfo(I,any,[])|Rest],R)
2022 merge_argspecs_([specinfo(I,F1,A)|Rest],R)
2024 R = [specinfo(I,F1,A1)|RR],
2025 merge_argspecs_([specinfo(I,F2,A2)|Rest],RR)
2028 arggoal(List,Arg,Goal,L,T) :-
2032 ; List = [specinfo(_,any,_)] ->
2033 Goal = term_variables(Arg,L,T)
2041 arggoal_cases(List,Arg,L,T,Cases)
2044 arggoal_cases([],_,L,T,L=T).
2045 arggoal_cases([specinfo(_,FA,ArgSpecs)|Rest],Arg,L,T,Cases) :-
2048 ; ArgSpecs == [[]] ->
2051 Cases = (Case ; RCases),
2054 Case = (Arg = Term -> ArgsGoal),
2055 spectermvars(Args,1,ArgSpecs,F,A,L,T,ArgsGoal)
2057 arggoal_cases(Rest,Arg,L,T,RCases).
2058 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2060 generate_extra_clauses(Constraints,List) :-
2061 generate_activate_clauses(Constraints,List,Tail0),
2062 generate_remove_clauses(Constraints,Tail0,Tail1),
2063 generate_allocate_clauses(Constraints,Tail1,Tail2),
2064 generate_insert_constraint_internal_clauses(Constraints,Tail2,Tail3),
2065 generate_novel_production(Tail3,Tail4),
2066 generate_extend_history(Tail4,Tail5),
2067 generate_run_suspensions_clauses(Constraints,Tail5,Tail6),
2068 generate_empty_named_history_initialisations(Tail6,Tail7),
2071 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2072 % remove_constraint_internal/[1/3]
2074 generate_remove_clauses([],List,List).
2075 generate_remove_clauses([C|Cs],List,Tail) :-
2076 generate_remove_clause(C,List,List1),
2077 generate_remove_clauses(Cs,List1,Tail).
2079 remove_constraint_goal(Constraint,Susp,Agenda,DeleteNo,DeleteYes,Role,Goal) :-
2080 uses_state(Constraint,removed),
2081 ( chr_pp_flag(inline_insertremove,off) ->
2082 use_auxiliary_predicate(remove_constraint_internal,Constraint),
2083 Goal = ( DeleteGoal, ( Delete == yes -> DeleteYes ; DeleteNo) ),
2084 remove_constraint_atom(Constraint,Susp,Agenda,Delete,DeleteGoal)
2086 delay_phase_end(validate_store_type_assumptions,
2087 generate_remove_body(Constraint,Susp,Agenda,DeleteNo,DeleteYes,Role,Goal)
2091 remove_constraint_atom(Constraint,Susp,Agenda,Delete,Goal) :-
2092 make_name('$remove_constraint_internal_',Constraint,Name),
2093 ( chr_pp_flag(debugable,off), ( only_ground_indexed_arguments(Constraint) ; get_store_type(Constraint,var_assoc_store(_,_)) ) ->
2094 Goal =.. [Name, Susp,Delete]
2096 Goal =.. [Name,Susp,Agenda,Delete]
2099 generate_remove_clause(Constraint,List,Tail) :-
2100 ( is_used_auxiliary_predicate(remove_constraint_internal,Constraint) ->
2101 List = [RemoveClause|Tail],
2102 RemoveClause = (Head :- RemoveBody),
2103 remove_constraint_atom(Constraint,Susp,Agenda,Delete,Head),
2104 generate_remove_body(Constraint,Susp,Agenda,Delete = no,Delete = yes,active,RemoveBody)
2109 generate_remove_body(Constraint,Susp,Agenda,DeleteNo,DeleteYes,Role,RemoveBody) :-
2110 ( chr_pp_flag(debugable,off), ( only_ground_indexed_arguments(Constraint) ; get_store_type(Constraint,var_assoc_store(_,_))) ->
2112 get_update_suspension_field(Constraint,Susp,state,State,removed,GetState,GetStateValue0,UpdateState),
2113 if_used_state(Constraint,not_stored_yet,GetStateValue0,true,GetStateValue),
2114 if_used_state(Constraint,not_stored_yet,(State == not_stored_yet -> DeleteNo ; DeleteYes),DeleteYes,MaybeDelete)
2115 ; Role == partner ->
2116 get_update_suspension_field(Constraint,Susp,state,State,removed,GetState,_,UpdateState),
2117 GetStateValue = true,
2118 MaybeDelete = DeleteYes
2128 static_suspension_term(Constraint,Susp2),
2129 get_static_suspension_term_field(arguments,Constraint,Susp2,Args),
2130 generate_indexed_variables_body(Constraint,Args,IndexedVariablesBody,Agenda),
2131 ( chr_pp_flag(debugable,on) ->
2132 Constraint = Functor / _,
2133 get_static_suspension_term_field(functor,Constraint,Susp2,Functor)
2138 get_update_static_suspension_field(Constraint,Susp,Susp2,state,State,removed,GetStateValue0,UpdateState),
2139 if_used_state(Constraint,not_stored_yet,GetStateValue0,true,GetStateValue),
2140 if_used_state(Constraint,not_stored_yet,(State == not_stored_yet -> Agenda = [], DeleteNo ; IndexedVariablesBody, DeleteYes),(IndexedVariablesBody,DeleteYes),MaybeDelete)
2141 ; Role == partner ->
2142 get_update_static_suspension_field(Constraint,Susp,Susp2,state,State,removed,_,UpdateState),
2143 GetStateValue = true,
2144 MaybeDelete = (IndexedVariablesBody, DeleteYes)
2155 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2156 % activate_constraint/4
2158 generate_activate_clauses([],List,List).
2159 generate_activate_clauses([C|Cs],List,Tail) :-
2160 generate_activate_clause(C,List,List1),
2161 generate_activate_clauses(Cs,List1,Tail).
2163 activate_constraint_goal(Constraint,StoreAction,Vars,Susp,Generation,Goal) :-
2164 ( chr_pp_flag(inline_insertremove,off) ->
2165 use_auxiliary_predicate(activate_constraint,Constraint),
2166 Goal = ( ActivateGoal , (Store == yes -> StoreAction ; true) ),
2167 activate_constraint_atom(Constraint,Store,Vars,Susp,Generation,ActivateGoal)
2169 delay_phase_end(validate_store_type_assumptions,
2170 activate_constraint_body(Constraint,StoreAction,true,Vars,Susp,Generation,Goal)
2174 activate_constraint_atom(Constraint,Store,Vars,Susp,Generation,Goal) :-
2175 make_name('$activate_constraint_',Constraint,Name),
2176 ( chr_pp_flag(debugable,off), only_ground_indexed_arguments(Constraint) ->
2177 Goal =.. [Name,Store, Susp]
2178 ; chr_pp_flag(debugable,off), may_trigger(Constraint), get_store_type(Constraint,var_assoc_store(_,_)) ->
2179 Goal =.. [Name,Store, Susp, Generation]
2180 ; chr_pp_flag(debugable,off), may_trigger(Constraint), get_store_type(Constraint,var_assoc_store(_,_)) ->
2181 Goal =.. [Name,Store, Vars, Susp, Generation]
2183 Goal =.. [Name,Store, Vars, Susp]
2186 generate_activate_clause(Constraint,List,Tail) :-
2187 ( is_used_auxiliary_predicate(activate_constraint,Constraint) ->
2188 List = [Clause|Tail],
2189 Clause = (Head :- Body),
2190 activate_constraint_atom(Constraint,Store,Vars,Susp,Generation,Head),
2191 activate_constraint_body(Constraint,Store = yes, Store = no,Vars,Susp,Generation,Body)
2196 activate_constraint_body(Constraint,StoreYes,StoreNo,Vars,Susp,Generation,Body) :-
2197 ( chr_pp_flag(debugable,off), may_trigger(Constraint), uses_field(Constraint,generation) ->
2198 get_update_suspension_field(Constraint,Susp,generation,Gen,Generation,GetGeneration,GetGenerationValue,UpdateGeneration),
2199 GenerationHandling = (GetGeneration, GetGenerationValue, Generation is Gen+1, UpdateGeneration)
2201 GenerationHandling = true
2203 get_update_suspension_field(Constraint,Susp,state,State,active,GetState,GetStateValue0,UpdateState),
2204 if_used_state(Constraint,not_stored_yet,GetStateValue0,true,GetStateValue),
2205 ( chr_pp_flag(debugable,off), ( only_ground_indexed_arguments(Constraint) ; get_store_type(Constraint,var_assoc_store(_,_))) ->
2206 if_used_state(Constraint,not_stored_yet,( State == not_stored_yet -> StoreYes ; StoreNo ),StoreNo,StoreVarsGoal)
2208 get_dynamic_suspension_term_field(arguments,Constraint,Susp,Arguments,ArgumentsGoal),
2209 generate_indexed_variables_body(Constraint,Arguments,IndexedVariablesBody,Vars),
2210 ( chr_pp_flag(guard_locks,off) ->
2213 NoneLocked = 'chr none_locked'( Vars)
2215 if_used_state(Constraint,not_stored_yet,
2216 ( State == not_stored_yet ->
2218 IndexedVariablesBody,
2225 % (Vars = [],StoreNo),StoreVarsGoal)
2226 StoreNo,StoreVarsGoal)
2236 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2237 % allocate_constraint/4
2239 generate_allocate_clauses([],List,List).
2240 generate_allocate_clauses([C|Cs],List,Tail) :-
2241 generate_allocate_clause(C,List,List1),
2242 generate_allocate_clauses(Cs,List1,Tail).
2244 allocate_constraint_goal(Constraint,Susp,Args,Goal) :-
2245 uses_state(Constraint,not_stored_yet),
2246 ( chr_pp_flag(inline_insertremove,off) ->
2247 use_auxiliary_predicate(allocate_constraint,Constraint),
2248 allocate_constraint_atom(Constraint,Susp,Args,Goal)
2250 Goal = (Susp = Suspension, Goal0),
2251 delay_phase_end(validate_store_type_assumptions,
2252 allocate_constraint_body(Constraint,Suspension,Args,Goal0)
2256 allocate_constraint_atom(Constraint, Susp, Args,Goal) :-
2257 make_name('$allocate_constraint_',Constraint,Name),
2258 Goal =.. [Name,Susp|Args].
2260 generate_allocate_clause(Constraint,List,Tail) :-
2261 ( is_used_auxiliary_predicate(allocate_constraint,Constraint) ->
2262 List = [Clause|Tail],
2263 Clause = (Head :- Body),
2266 allocate_constraint_atom(Constraint,Susp,Args,Head),
2267 allocate_constraint_body(Constraint,Susp,Args,Body)
2272 allocate_constraint_body(Constraint,Susp,Args,Body) :-
2273 static_suspension_term(Constraint,Suspension),
2274 get_static_suspension_term_field(arguments,Constraint,Suspension,Args),
2275 ( chr_pp_flag(debugable,on) ->
2276 Constraint = Functor / _,
2277 get_static_suspension_term_field(functor,Constraint,Suspension,Functor)
2281 ( chr_pp_flag(debugable,on) ->
2282 ( may_trigger(Constraint) ->
2283 append(Args,[Susp],VarsSusp),
2284 build_head(F,A,[0],VarsSusp, ContinuationGoal),
2285 get_target_module(Mod),
2286 Continuation = Mod : ContinuationGoal
2290 Init = (Susp = Suspension),
2291 create_static_suspension_field(Constraint,Suspension,continuation,Continuation,CreateContinuation),
2292 create_static_suspension_field(Constraint,Suspension,generation,0,CreateGeneration)
2293 ; may_trigger(Constraint), uses_field(Constraint,generation) ->
2294 create_static_suspension_field(Constraint,Suspension,generation,0,CreateGeneration),
2295 Susp = Suspension, Init = true, CreateContinuation = true
2297 CreateGeneration = true, Susp = Suspension, Init = true, CreateContinuation = true
2299 ( uses_history(Constraint) ->
2300 create_static_suspension_field(Constraint,Suspension,history,t,CreateHistory)
2302 CreateHistory = true
2304 create_static_suspension_field(Constraint,Suspension,state,not_stored_yet,CreateState),
2305 ( has_suspension_field(Constraint,id) ->
2306 get_static_suspension_term_field(id,Constraint,Suspension,Id),
2307 GenID = 'chr gen_id'(Id)
2321 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2322 % insert_constraint_internal
2324 generate_insert_constraint_internal_clauses([],List,List).
2325 generate_insert_constraint_internal_clauses([C|Cs],List,Tail) :-
2326 generate_insert_constraint_internal_clause(C,List,List1),
2327 generate_insert_constraint_internal_clauses(Cs,List1,Tail).
2329 insert_constraint_internal_constraint_goal(Constraint, Vars, Suspension, Continuation, Args,Goal) :-
2330 ( chr_pp_flag(inline_insertremove,off) ->
2331 use_auxiliary_predicate(remove_constraint_internal,Constraint),
2332 insert_constraint_internal_constraint_atom(Constraint,Vars,Suspension,Continuation,Args,Goal)
2334 delay_phase_end(validate_store_type_assumptions,
2335 generate_insert_constraint_internal_body(Constraint,Suspension,Continuation,Args,Vars,Goal)
2340 insert_constraint_internal_constraint_atom(Constraint,Vars,Self,Closure,Args,Goal) :-
2341 insert_constraint_internal_constraint_name(Constraint,Name),
2342 ( chr_pp_flag(debugable,on) ->
2343 Goal =.. [Name, Vars, Self, Closure | Args]
2344 ; ( only_ground_indexed_arguments(Constraint) ; get_store_type(Constraint,var_assoc_store(_,_)))->
2345 Goal =.. [Name,Self | Args]
2347 Goal =.. [Name,Vars, Self | Args]
2350 insert_constraint_internal_constraint_name(Constraint,Name) :-
2351 make_name('$insert_constraint_internal_',Constraint,Name).
2353 generate_insert_constraint_internal_clause(Constraint,List,Tail) :-
2354 ( is_used_auxiliary_predicate(insert_constraint_internal,Constraint) ->
2355 List = [Clause|Tail],
2356 Clause = (Head :- Body),
2359 insert_constraint_internal_constraint_atom(Constraint, Vars, Suspension, Continuation,Args,Head),
2360 generate_insert_constraint_internal_body(Constraint,Suspension,Continuation,Args,Vars,Body)
2366 generate_insert_constraint_internal_body(Constraint,Susp,Continuation,Args,Vars,Body) :-
2367 static_suspension_term(Constraint,Suspension),
2368 create_static_suspension_field(Constraint,Suspension,state,active,CreateState),
2369 ( chr_pp_flag(debugable,on) ->
2370 get_static_suspension_term_field(continuation,Constraint,Suspension,Continuation),
2371 create_static_suspension_field(Constraint,Suspension,generation,0,CreateGeneration)
2372 ; may_trigger(Constraint), uses_field(Constraint,generation) ->
2373 create_static_suspension_field(Constraint,Suspension,generation,0,CreateGeneration)
2375 CreateGeneration = true
2377 ( chr_pp_flag(debugable,on) ->
2378 Constraint = Functor / _,
2379 get_static_suspension_term_field(functor,Constraint,Suspension,Functor)
2383 ( uses_history(Constraint) ->
2384 create_static_suspension_field(Constraint,Suspension,history,t,CreateHistory)
2386 CreateHistory = true
2388 get_static_suspension_term_field(arguments,Constraint,Suspension,Args),
2389 List = [Clause|Tail],
2390 ( chr_pp_flag(debugable,off), ( only_ground_indexed_arguments(Constraint) ; get_store_type(Constraint,var_assoc_store(_,_)))->
2391 suspension_term_base_fields(Constraint,BaseFields),
2392 ( has_suspension_field(Constraint,id) ->
2393 get_static_suspension_term_field(id,Constraint,Suspension,Id),
2394 GenID = 'chr gen_id'(Id)
2407 ( has_suspension_field(Constraint,id) ->
2408 get_static_suspension_term_field(id,Constraint,Suspension,Id),
2409 GenID = 'chr gen_id'(Id)
2413 generate_indexed_variables_body(Constraint,Args,IndexedVariablesBody,Vars),
2414 ( chr_pp_flag(guard_locks,off) ->
2417 NoneLocked = 'chr none_locked'( Vars)
2422 IndexedVariablesBody,
2431 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2432 % novel_production/2
2434 generate_novel_production(List,Tail) :-
2435 ( is_used_auxiliary_predicate(novel_production) ->
2436 List = [Clause|Tail],
2439 '$novel_production'( Self, Tuple) :-
2440 % arg( 3, Self, Ref), % ARGXXX
2441 % 'chr get_mutable'( History, Ref),
2442 arg( 3, Self, History), % ARGXXX
2443 ( hprolog:get_ds( Tuple, History, _) ->
2453 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2456 generate_extend_history(List,Tail) :-
2457 ( is_used_auxiliary_predicate(extend_history) ->
2458 List = [Clause|Tail],
2461 '$extend_history'( Self, Tuple) :-
2462 % arg( 3, Self, Ref), % ARGXXX
2463 % 'chr get_mutable'( History, Ref),
2464 arg( 3, Self, History), % ARGXXX
2465 hprolog:put_ds( Tuple, History, x, NewHistory),
2466 setarg( 3, Self, NewHistory) % ARGXXX
2472 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2475 empty_named_history_initialisations/2,
2476 generate_empty_named_history_initialisation/1,
2477 find_empty_named_histories/0.
2479 generate_empty_named_history_initialisations(List, Tail) :-
2480 empty_named_history_initialisations(List, Tail),
2481 find_empty_named_histories.
2483 find_empty_named_histories, history(_, Name, []) ==>
2484 generate_empty_named_history_initialisation(Name).
2486 generate_empty_named_history_initialisation(Name) \
2487 generate_empty_named_history_initialisation(Name) <=> true.
2488 generate_empty_named_history_initialisation(Name) \
2489 empty_named_history_initialisations(List, Tail) # Passive
2491 empty_named_history_global_variable(Name, GlobalVariable),
2492 List = [(:- nb_setval(GlobalVariable, 0))|Rest],
2493 empty_named_history_initialisations(Rest, Tail)
2494 pragma passive(Passive).
2496 find_empty_named_histories \
2497 generate_empty_named_history_initialisation(_) # Passive <=> true
2498 pragma passive(Passive).
2500 find_empty_named_histories,
2501 empty_named_history_initialisations(List, Tail) # Passive <=> List = Tail
2502 pragma passive(Passive).
2504 find_empty_named_histories <=>
2505 chr_error(internal, 'find_empty_named_histories was not removed', []).
2508 empty_named_history_global_variable(Name, GlobalVariable) :-
2509 atom_concat('chr empty named history ', Name, GlobalVariable).
2511 empty_named_history_novel_production(Name, nb_getval(GlobalVariable, 0)) :-
2512 empty_named_history_global_variable(Name, GlobalVariable).
2514 empty_named_history_extend_history(Name, b_setval(GlobalVariable, 1)) :-
2515 empty_named_history_global_variable(Name, GlobalVariable).
2518 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2521 generate_run_suspensions_clauses([],List,List).
2522 generate_run_suspensions_clauses([C|Cs],List,Tail) :-
2523 generate_run_suspensions_clause(C,List,List1),
2524 generate_run_suspensions_clauses(Cs,List1,Tail).
2526 run_suspensions_goal(Constraint,Suspensions,Goal) :-
2527 make_name('$run_suspensions_',Constraint,Name),
2528 Goal =.. [Name,Suspensions].
2530 generate_run_suspensions_clause(Constraint,List,Tail) :-
2531 ( is_used_auxiliary_predicate(run_suspensions,Constraint) ->
2532 List = [Clause1,Clause2|Tail],
2533 run_suspensions_goal(Constraint,[],Clause1),
2534 ( chr_pp_flag(debugable,on) ->
2535 run_suspensions_goal(Constraint,[Suspension|Suspensions],Clause2Head),
2536 get_update_suspension_field(Constraint,Suspension,state,State,triggered,GetState,GetStateValue,UpdateState),
2537 get_update_suspension_field(Constraint,Suspension,state,Post,active,GetPost,GetPostValue,UpdatePost),
2538 get_update_suspension_field(Constraint,Suspension,generation,Gen,Generation,GetGeneration,GetGenerationValue,UpdateGeneration),
2539 get_dynamic_suspension_term_field(continuation,Constraint,Suspension,Continuation,GetContinuation),
2540 run_suspensions_goal(Constraint,Suspensions,Clause2Recursion),
2550 Generation is Gen+1,
2554 'chr debug_event'(wake(Suspension)),
2557 'chr debug_event'(fail(Suspension)), !,
2561 'chr debug_event'(exit(Suspension))
2563 'chr debug_event'(redo(Suspension)),
2568 ( Post==triggered ->
2569 UpdatePost % catching constraints that did not do anything
2579 run_suspensions_goal(Constraint,[Suspension|Suspensions],Clause2Head),
2580 static_suspension_term(Constraint,SuspensionTerm),
2581 get_static_suspension_term_field(arguments,Constraint,SuspensionTerm,Arguments),
2582 append(Arguments,[Suspension],VarsSusp),
2583 make_suspension_continuation_goal(Constraint,VarsSusp,Continuation),
2584 run_suspensions_goal(Constraint,Suspensions,Clause2Recursion),
2585 ( uses_field(Constraint,generation) ->
2586 get_update_static_suspension_field(Constraint,Suspension,SuspensionTerm,generation,Gen,Generation,GetGeneration,UpdateGeneration),
2587 GenerationHandling = ( GetGeneration, Generation is Gen+1, UpdateGeneration)
2589 GenerationHandling = true
2591 get_update_static_suspension_field(Constraint,Suspension,SuspensionTerm,state,State,triggered,GetState,UpdateState),
2592 get_update_static_suspension_field(Constraint,Suspension,SuspensionTerm,state,Post,active,GetPostState,UpdatePostState),
2593 if_used_state(Constraint,removed,
2596 -> ReactivateConstraint
2598 ),ReactivateConstraint,CondReactivate),
2599 ReactivateConstraint =
2605 ( Post==triggered ->
2606 UpdatePostState % catching constraints that did not do anything
2614 Suspension = SuspensionTerm,
2623 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2625 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2626 generate_attach_increment(Clauses) :-
2627 get_max_constraint_index(N),
2628 ( is_used_auxiliary_predicate(attach_increment), N > 0 ->
2629 Clauses = [Clause1,Clause2],
2630 generate_attach_increment_empty(Clause1),
2632 generate_attach_increment_one(Clause2)
2634 generate_attach_increment_many(N,Clause2)
2640 generate_attach_increment_empty((attach_increment([],_) :- true)).
2642 generate_attach_increment_one(Clause) :-
2643 Head = attach_increment([Var|Vars],Susps),
2644 get_target_module(Mod),
2645 ( chr_pp_flag(guard_locks,off) ->
2648 NotLocked = 'chr not_locked'( Var)
2653 ( get_attr(Var,Mod,VarSusps) ->
2654 sort(VarSusps,SortedVarSusps),
2655 'chr merge_attributes'(Susps,SortedVarSusps,MergedSusps),
2656 put_attr(Var,Mod,MergedSusps)
2658 put_attr(Var,Mod,Susps)
2660 attach_increment(Vars,Susps)
2662 Clause = (Head :- Body).
2664 generate_attach_increment_many(N,Clause) :-
2665 Head = attach_increment([Var|Vars],TAttr1),
2666 % writeln(merge_attributes_1_before),
2667 merge_attributes(N,TAttr1,TAttr2,MergeGoal,Attr),
2668 % writeln(merge_attributes_1_after),
2669 get_target_module(Mod),
2670 ( chr_pp_flag(guard_locks,off) ->
2673 NotLocked = 'chr not_locked'( Var)
2678 ( get_attr(Var,Mod,TAttr2) ->
2680 put_attr(Var,Mod,Attr)
2682 put_attr(Var,Mod,TAttr1)
2684 attach_increment(Vars,TAttr1)
2686 Clause = (Head :- Body).
2689 generate_attr_unify_hook(Clauses) :-
2690 get_max_constraint_index(N),
2695 generate_attr_unify_hook_one(Clauses)
2697 generate_attr_unify_hook_many(N,Clauses)
2701 generate_attr_unify_hook_one([Clause]) :-
2702 Head = attr_unify_hook(Susps,Other),
2703 get_target_module(Mod),
2704 get_indexed_constraint(1,C),
2705 ( get_store_type(C,ST),
2706 ( ST = default ; ST = multi_store(STs), member(default,STs) ) ->
2707 make_run_suspensions(NewSusps,SortedSusps,WakeNewSusps),
2708 make_run_suspensions(SortedSusps,SortedSusps,WakeSusps),
2709 ( atomic_types_suspended_constraint(C) ->
2711 SortedSusps = Susps,
2713 SortedOtherSusps = OtherSusps,
2714 MergeGoal = (append(Susps,OtherSusps,List), sort(List,NewSusps)),
2717 SortGoal1 = sort(Susps, SortedSusps),
2718 SortGoal2 = sort(OtherSusps,SortedOtherSusps),
2719 MergeGoal = 'chr merge_attributes'(SortedSusps,SortedOtherSusps,NewSusps),
2720 use_auxiliary_predicate(attach_increment),
2722 ( compound(Other) ->
2723 term_variables(Other,OtherVars),
2724 attach_increment(OtherVars, SortedSusps)
2733 ( get_attr(Other,Mod,OtherSusps) ->
2736 put_attr(Other,Mod,NewSusps),
2739 put_attr(Other,Mod,SortedSusps),
2747 Clause = (Head :- Body)
2748 ; get_store_type(C,var_assoc_store(VarIndex,KeyIndex)) ->
2749 make_run_suspensions(List,List,WakeNewSusps),
2750 MergeGoal = (merge_into_assoc_store(Susps,OtherSusps,List)),
2752 ( get_attr(Other,Mod,OtherSusps) ->
2756 put_attr(Other,Mod,Susps)
2758 Clause = (Head :- Body)
2762 generate_attr_unify_hook_many(N,[Clause]) :-
2763 chr_pp_flag(dynattr,off), !,
2764 Head = attr_unify_hook(Attr,Other),
2765 get_target_module(Mod),
2766 make_attr(N,Mask,SuspsList,Attr),
2767 bagof(Sort,A ^ B ^ ( member(A,SuspsList) , Sort = sort(A,B) ) , SortGoalList),
2768 list2conj(SortGoalList,SortGoals),
2769 bagof(B, A ^ member(sort(A,B),SortGoalList), SortedSuspsList),
2770 merge_attributes2(N,Mask,SortedSuspsList,TOtherAttr,MergeGoal,MergedAttr),
2771 get_all_suspensions2(N,MergedAttr,MergedSuspsList),
2772 make_attr(N,Mask,SortedSuspsList,SortedAttr),
2773 make_run_suspensions_loop(MergedSuspsList,SortedSuspsList,WakeMergedSusps),
2774 make_run_suspensions_loop(SortedSuspsList,SortedSuspsList,WakeSortedSusps),
2775 ( forall((between(1,N,Index), get_indexed_constraint(Index,Constraint)),atomic_types_suspended_constraint(Constraint)) ->
2778 use_auxiliary_predicate(attach_increment),
2780 ( compound(Other) ->
2781 term_variables(Other,OtherVars),
2782 attach_increment(OtherVars,SortedAttr)
2791 ( get_attr(Other,Mod,TOtherAttr) ->
2793 put_attr(Other,Mod,MergedAttr),
2796 put_attr(Other,Mod,SortedAttr),
2804 Clause = (Head :- Body).
2807 generate_attr_unify_hook_many(N,Clauses) :-
2808 Head = attr_unify_hook(Attr,Other),
2809 get_target_module(Mod),
2810 normalize_attr(Attr,NormalGoal,NormalAttr),
2811 normalize_attr(OtherAttr,NormalOtherGoal,NormalOtherAttr),
2812 merge_attributes(N,NormalAttr,NormalOtherAttr,MergeGoal,MergedAttr),
2813 make_run_suspensions(N),
2814 ( forall((between(1,N,Index), get_indexed_constraint(Index,Constraint)),atomic_types_suspended_constraint(Constraint)) ->
2817 use_auxiliary_predicate(attach_increment),
2819 ( compound(Other) ->
2820 term_variables(Other,OtherVars),
2821 attach_increment(OtherVars,NormalAttr)
2830 ( get_attr(Other,Mod,OtherAttr) ->
2833 put_attr(Other,Mod,MergedAttr),
2834 '$dispatch_run_suspensions'(MergedAttr)
2836 put_attr(Other,Mod,NormalAttr),
2837 '$dispatch_run_suspensions'(NormalAttr)
2841 '$dispatch_run_suspensions'(NormalAttr)
2844 Clause = (Head :- Body),
2845 Clauses = [Clause,DispatchList1,DispatchList2|Dispatchers],
2846 DispatchList1 = ('$dispatch_run_suspensions'([])),
2847 DispatchList2 = ('$dispatch_run_suspensions'([Pos-List|Rest]) :- '$dispatch_run_suspensions'(Pos,List),'$dispatch_run_suspensions'(Rest)),
2848 run_suspensions_dispatchers(N,[],Dispatchers).
2851 run_suspensions_dispatchers(N,Acc,Dispatchers) :-
2853 get_indexed_constraint(N,C),
2854 NAcc = [('$dispatch_run_suspensions'(N,List) :- Body)|Acc],
2856 run_suspensions_goal(C,List,Body)
2861 run_suspensions_dispatchers(M,NAcc,Dispatchers)
2867 make_run_suspensions(N) :-
2869 ( get_indexed_constraint(N,C),
2871 use_auxiliary_predicate(run_suspensions,C)
2876 make_run_suspensions(M)
2881 make_run_suspensions(AllSusps,OneSusps,Goal) :-
2882 make_run_suspensions(1,AllSusps,OneSusps,Goal).
2884 make_run_suspensions(Index,AllSusps,OneSusps,Goal) :-
2885 ( get_indexed_constraint(Index,C), may_trigger(C) ->
2886 use_auxiliary_predicate(run_suspensions,C),
2887 ( wakes_partially(C) ->
2888 run_suspensions_goal(C,OneSusps,Goal)
2890 run_suspensions_goal(C,AllSusps,Goal)
2896 make_run_suspensions_loop(AllSuspsList,OneSuspsList,Goal) :-
2897 make_run_suspensions_loop(AllSuspsList,OneSuspsList,1,Goal).
2899 make_run_suspensions_loop([],[],_,true).
2900 make_run_suspensions_loop([AllSusps|AllSuspsList],[OneSusps|OneSuspsList],I,(Goal,Goals)) :-
2901 make_run_suspensions(I,AllSusps,OneSusps,Goal),
2903 make_run_suspensions_loop(AllSuspsList,OneSuspsList,J,Goals).
2905 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2906 % $insert_in_store_F/A
2907 % $delete_from_store_F/A
2909 generate_insert_delete_constraints([],[]).
2910 generate_insert_delete_constraints([FA|Rest],Clauses) :-
2912 generate_insert_delete_constraint(FA,Clauses,RestClauses)
2914 Clauses = RestClauses
2916 generate_insert_delete_constraints(Rest,RestClauses).
2918 generate_insert_delete_constraint(FA,Clauses,RestClauses) :-
2919 insert_constraint_clause(FA,Clauses,RestClauses1),
2920 delete_constraint_clause(FA,RestClauses1,RestClauses).
2922 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
2925 insert_constraint_goal(FA,Susp,Vars,Goal) :-
2926 ( chr_pp_flag(inline_insertremove,off) ->
2927 use_auxiliary_predicate(insert_in_store,FA),
2928 insert_constraint_atom(FA,Susp,Goal)
2930 delay_phase_end(validate_store_type_assumptions,
2931 ( insert_constraint_body(FA,Susp,UsedVars,Goal),
2932 insert_constraint_direct_used_vars(UsedVars,Vars)
2937 insert_constraint_direct_used_vars([],_).
2938 insert_constraint_direct_used_vars([Index-Var|Rest],Vars) :-
2939 nth1(Index,Vars,Var),
2940 insert_constraint_direct_used_vars(Rest,Vars).
2942 insert_constraint_atom(FA,Susp,Call) :-
2943 make_name('$insert_in_store_',FA,Functor),
2944 Call =.. [Functor,Susp].
2946 insert_constraint_clause(C,Clauses,RestClauses) :-
2947 ( is_used_auxiliary_predicate(insert_in_store,C) ->
2948 Clauses = [Clause|RestClauses],
2949 Clause = (Head :- InsertCounterInc,VarsBody,Body),
2950 insert_constraint_atom(C,Susp,Head),
2951 insert_constraint_body(C,Susp,UsedVars,Body),
2952 insert_constraint_used_vars(UsedVars,C,Susp,VarsBody),
2953 ( chr_pp_flag(store_counter,on) ->
2954 InsertCounterInc = '$insert_counter_inc'
2956 InsertCounterInc = true
2959 Clauses = RestClauses
2962 insert_constraint_used_vars([],_,_,true).
2963 insert_constraint_used_vars([Index-Var|Rest],C,Susp,(Goal,Goals)) :-
2964 get_dynamic_suspension_term_field(argument(Index),C,Susp,Var,Goal),
2965 insert_constraint_used_vars(Rest,C,Susp,Goals).
2967 insert_constraint_body(C,Susp,UsedVars,Body) :-
2968 get_store_type(C,StoreType),
2969 insert_constraint_body(StoreType,C,Susp,UsedVars,Body).
2971 insert_constraint_body(default,C,Susp,[],Body) :-
2972 global_list_store_name(C,StoreName),
2973 make_get_store_goal(StoreName,Store,GetStoreGoal),
2974 make_update_store_goal(StoreName,Cell,UpdateStoreGoal),
2975 ( chr_pp_flag(debugable,on) ->
2976 Cell = [Susp|Store],
2983 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,Cell,SetGoal),
2987 Cell = [Susp|Store],
2989 ( Store = [NextSusp|_] ->
2996 % get_target_module(Mod),
2997 % get_max_constraint_index(Total),
2999 % generate_attach_body_1(C,Store,Susp,AttachBody)
3001 % generate_attach_body_n(C,Store,Susp,AttachBody)
3005 % 'chr default_store'(Store),
3008 insert_constraint_body(multi_inthash(Indexes),C,Susp,[],Body) :-
3009 generate_multi_inthash_insert_constraint_bodies(Indexes,C,Susp,Body).
3010 insert_constraint_body(multi_hash(Indexes),C,Susp,MixedUsedVars,Body) :-
3011 generate_multi_hash_insert_constraint_bodies(Indexes,C,Susp,Body,MixedUsedVars),
3012 sort_out_used_vars(MixedUsedVars,UsedVars).
3013 insert_constraint_body(atomic_constants(Index,_,_),C,Susp,UsedVars,Body) :-
3014 multi_hash_key_direct(C,Index,Susp,Key,UsedVars),
3015 constants_store_index_name(C,Index,IndexName),
3016 IndexLookup =.. [IndexName,Key,StoreName],
3019 nb_getval(StoreName,Store),
3020 b_setval(StoreName,[Susp|Store])
3024 insert_constraint_body(ground_constants(Index,_),C,Susp,UsedVars,Body) :-
3025 multi_hash_key_direct(C,Index,Susp,Key,UsedVars),
3026 constants_store_index_name(C,Index,IndexName),
3027 IndexLookup =.. [IndexName,Key,StoreName],
3030 nb_getval(StoreName,Store),
3031 b_setval(StoreName,[Susp|Store])
3035 insert_constraint_body(global_ground,C,Susp,[],Body) :-
3036 global_ground_store_name(C,StoreName),
3037 make_get_store_goal(StoreName,Store,GetStoreGoal),
3038 make_update_store_goal(StoreName,Cell,UpdateStoreGoal),
3039 ( chr_pp_flag(debugable,on) ->
3040 Cell = [Susp|Store],
3047 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,Cell,SetGoal),
3051 Cell = [Susp|Store],
3053 ( Store = [NextSusp|_] ->
3060 % global_ground_store_name(C,StoreName),
3061 % make_get_store_goal(StoreName,Store,GetStoreGoal),
3062 % make_update_store_goal(StoreName,[Susp|Store],UpdateStoreGoal),
3065 % GetStoreGoal, % nb_getval(StoreName,Store),
3066 % UpdateStoreGoal % b_setval(StoreName,[Susp|Store])
3068 insert_constraint_body(var_assoc_store(VarIndex,AssocIndex),C,Susp,[VarIndex-Variable,AssocIndex-Key],Body) :-
3069 % TODO: generalize to more than one !!!
3070 get_target_module(Module),
3071 Body = ( get_attr(Variable,Module,AssocStore) ->
3072 insert_assoc_store(AssocStore,Key,Susp)
3074 new_assoc_store(AssocStore),
3075 put_attr(Variable,Module,AssocStore),
3076 insert_assoc_store(AssocStore,Key,Susp)
3079 insert_constraint_body(global_singleton,C,Susp,[],Body) :-
3080 global_singleton_store_name(C,StoreName),
3081 make_update_store_goal(StoreName,Susp,UpdateStoreGoal),
3086 insert_constraint_body(multi_store(StoreTypes),C,Susp,UsedVars,Body) :-
3087 find_with_var_identity(
3091 member(ST,StoreTypes),
3092 chr_translate:insert_constraint_body(ST,C,Susp,UV,B)
3096 once(pairup(Bodies,NestedUsedVars,BodiesUsedVars)),
3097 list2conj(Bodies,Body),
3098 sort_out_used_vars(NestedUsedVars,UsedVars).
3099 insert_constraint_body(identifier_store(Index),C,Susp,UsedVars,Body) :-
3100 UsedVars = [Index-Var],
3101 get_identifier_size(ISize),
3102 functor(Struct,struct,ISize),
3103 get_identifier_index(C,Index,IIndex),
3104 arg(IIndex,Struct,Susps),
3105 Body = (Var = Struct, setarg(IIndex,Var,[Susp|Susps])).
3106 insert_constraint_body(type_indexed_identifier_store(Index,IndexType),C,Susp,UsedVars,Body) :-
3107 UsedVars = [Index-Var],
3108 type_indexed_identifier_structure(IndexType,Struct),
3109 get_type_indexed_identifier_index(IndexType,C,Index,IIndex),
3110 arg(IIndex,Struct,Susps),
3111 Body = (Var = Struct, setarg(IIndex,Var,[Susp|Susps])).
3113 sort_out_used_vars(NestedUsedVars,UsedVars) :-
3114 flatten(NestedUsedVars,FlatUsedVars),
3115 sort(FlatUsedVars,SortedFlatUsedVars),
3116 sort_out_used_vars1(SortedFlatUsedVars,UsedVars).
3118 sort_out_used_vars1([],[]).
3119 sort_out_used_vars1([I-V],L) :- !, L = [I-V].
3120 sort_out_used_vars1([I-X,J-Y|R],L) :-
3123 sort_out_used_vars1([I-X|R],L)
3126 sort_out_used_vars1([J-Y|R],T)
3129 generate_multi_inthash_insert_constraint_bodies([],_,_,true).
3130 generate_multi_inthash_insert_constraint_bodies([Index|Indexes],FA,Susp,(Body,Bodies)) :-
3131 multi_hash_store_name(FA,Index,StoreName),
3132 multi_hash_key(FA,Index,Susp,KeyBody,Key),
3136 nb_getval(StoreName,Store),
3137 insert_iht(Store,Key,Susp)
3139 generate_multi_inthash_insert_constraint_bodies(Indexes,FA,Susp,Bodies).
3141 generate_multi_hash_insert_constraint_bodies([],_,_,true,[]).
3142 generate_multi_hash_insert_constraint_bodies([Index|Indexes],FA,Susp,(Body,Bodies),[UsedVars|MoreUsedVars]) :-
3143 multi_hash_store_name(FA,Index,StoreName),
3144 multi_hash_key_direct(FA,Index,Susp,Key,UsedVars),
3145 make_get_store_goal(StoreName,Store,GetStoreGoal),
3146 ( chr_pp_flag(ht_removal,on)
3147 -> ht_prev_field(Index,PrevField),
3148 set_dynamic_suspension_term_field(PrevField,FA,NextSusp,Result,
3153 insert_ht(Store,Key,Susp,Result),
3154 ( Result = [_,NextSusp|_]
3162 insert_ht(Store,Key,Susp)
3165 generate_multi_hash_insert_constraint_bodies(Indexes,FA,Susp,Bodies,MoreUsedVars).
3167 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3170 delete_constraint_clause(C,Clauses,RestClauses) :-
3171 ( is_used_auxiliary_predicate(delete_from_store,C) ->
3172 Clauses = [Clause|RestClauses],
3173 Clause = (Head :- Body),
3174 delete_constraint_atom(C,Susp,Head),
3177 delete_constraint_body(C,Head,Susp,[],Body)
3179 Clauses = RestClauses
3182 delete_constraint_goal(Head,Susp,VarDict,Goal) :-
3185 ( chr_pp_flag(inline_insertremove,off) ->
3186 use_auxiliary_predicate(delete_from_store,C),
3187 delete_constraint_atom(C,Susp,Goal)
3189 delay_phase_end(validate_store_type_assumptions, delete_constraint_body(C,Head,Susp,VarDict,Goal))
3192 delete_constraint_atom(C,Susp,Atom) :-
3193 make_name('$delete_from_store_',C,Functor),
3194 Atom =.. [Functor,Susp].
3197 delete_constraint_body(C,Head,Susp,VarDict,Body) :-
3198 Body = (CounterBody,DeleteBody),
3199 ( chr_pp_flag(store_counter,on) ->
3200 CounterBody = '$delete_counter_inc'
3204 get_store_type(C,StoreType),
3205 delete_constraint_body(StoreType,C,Head,Susp,VarDict,DeleteBody).
3207 delete_constraint_body(default,C,_,Susp,_,Body) :-
3208 ( chr_pp_flag(debugable,on) ->
3209 global_list_store_name(C,StoreName),
3210 make_get_store_goal(StoreName,Store,GetStoreGoal),
3211 make_update_store_goal(StoreName,NStore,UpdateStoreGoal),
3214 GetStoreGoal, % nb_getval(StoreName,Store),
3215 'chr sbag_del_element'(Store,Susp,NStore),
3216 UpdateStoreGoal % b_setval(StoreName,NStore)
3219 get_dynamic_suspension_term_field(global_list_prev,C,Susp,PredCell,GetGoal),
3220 global_list_store_name(C,StoreName),
3221 make_get_store_goal(StoreName,Store,GetStoreGoal),
3222 make_update_store_goal(StoreName,Tail,UpdateStoreGoal),
3223 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,_,SetGoal1),
3224 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,PredCell,SetGoal2),
3229 GetStoreGoal, % nb_getval(StoreName,Store),
3232 ( Tail = [NextSusp|_] ->
3238 PredCell = [_,_|Tail],
3239 setarg(2,PredCell,Tail),
3240 ( Tail = [NextSusp|_] ->
3248 % get_target_module(Mod),
3249 % get_max_constraint_index(Total),
3251 % generate_detach_body_1(C,Store,Susp,DetachBody),
3254 % 'chr default_store'(Store),
3258 % generate_detach_body_n(C,Store,Susp,DetachBody),
3261 % 'chr default_store'(Store),
3265 delete_constraint_body(multi_inthash(Indexes),C,_,Susp,_,Body) :-
3266 generate_multi_inthash_delete_constraint_bodies(Indexes,C,Susp,Body).
3267 delete_constraint_body(multi_hash(Indexes),C,Head,Susp,VarDict,Body) :-
3268 generate_multi_hash_delete_constraint_bodies(Indexes,C,Head,Susp,VarDict,Body).
3269 delete_constraint_body(atomic_constants(Index,_,_),C,Head,Susp,VarDict,Body) :-
3270 multi_hash_key(C,Head,Index,Susp,VarDict,KeyBody,Key),
3271 constants_store_index_name(C,Index,IndexName),
3272 IndexLookup =.. [IndexName,Key,StoreName],
3276 nb_getval(StoreName,Store),
3277 'chr sbag_del_element'(Store,Susp,NStore),
3278 b_setval(StoreName,NStore)
3282 delete_constraint_body(ground_constants(Index,_),C,Head,Susp,VarDict,Body) :-
3283 multi_hash_key(C,Head,Index,Susp,VarDict,KeyBody,Key),
3284 constants_store_index_name(C,Index,IndexName),
3285 IndexLookup =.. [IndexName,Key,StoreName],
3289 nb_getval(StoreName,Store),
3290 'chr sbag_del_element'(Store,Susp,NStore),
3291 b_setval(StoreName,NStore)
3295 delete_constraint_body(global_ground,C,_,Susp,_,Body) :-
3296 ( chr_pp_flag(debugable,on) ->
3297 global_ground_store_name(C,StoreName),
3298 make_get_store_goal(StoreName,Store,GetStoreGoal),
3299 make_update_store_goal(StoreName,NStore,UpdateStoreGoal),
3302 GetStoreGoal, % nb_getval(StoreName,Store),
3303 'chr sbag_del_element'(Store,Susp,NStore),
3304 UpdateStoreGoal % b_setval(StoreName,NStore)
3307 get_dynamic_suspension_term_field(global_list_prev,C,Susp,PredCell,GetGoal),
3308 global_ground_store_name(C,StoreName),
3309 make_get_store_goal(StoreName,Store,GetStoreGoal),
3310 make_update_store_goal(StoreName,Tail,UpdateStoreGoal),
3311 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,_,SetGoal1),
3312 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,PredCell,SetGoal2),
3317 GetStoreGoal, % nb_getval(StoreName,Store),
3320 ( Tail = [NextSusp|_] ->
3326 PredCell = [_,_|Tail],
3327 setarg(2,PredCell,Tail),
3328 ( Tail = [NextSusp|_] ->
3336 % global_ground_store_name(C,StoreName),
3337 % make_get_store_goal(StoreName,Store,GetStoreGoal),
3338 % make_update_store_goal(StoreName,NStore,UpdateStoreGoal),
3341 % GetStoreGoal, % nb_getval(StoreName,Store),
3342 % 'chr sbag_del_element'(Store,Susp,NStore),
3343 % UpdateStoreGoal % b_setval(StoreName,NStore)
3345 delete_constraint_body(var_assoc_store(VarIndex,AssocIndex),C,_,Susp,_,Body) :-
3346 get_target_module(Module),
3347 get_dynamic_suspension_term_field(argument(VarIndex),C,Susp,Variable,VariableGoal),
3348 get_dynamic_suspension_term_field(argument(AssocIndex),C,Susp,Key,KeyGoal),
3351 get_attr(Variable,Module,AssocStore),
3353 delete_assoc_store(AssocStore,Key,Susp)
3355 delete_constraint_body(global_singleton,C,_,_Susp,_,Body) :-
3356 global_singleton_store_name(C,StoreName),
3357 make_update_store_goal(StoreName,[],UpdateStoreGoal),
3360 UpdateStoreGoal % b_setval(StoreName,[])
3362 delete_constraint_body(multi_store(StoreTypes),C,Head,Susp,VarDict,Body) :-
3363 find_with_var_identity(
3365 [Susp/VarDict/Head],
3367 member(ST,StoreTypes),
3368 chr_translate:delete_constraint_body(ST,C,Head,Susp,VarDict,B)
3372 list2conj(Bodies,Body).
3373 delete_constraint_body(identifier_store(Index),C,Head,Susp,VarDict,Body) :-
3374 get_suspension_argument_possibly_in_scope(Head,Index,VarDict,Susp,Variable,VariableGoal),
3375 get_identifier_size(ISize),
3376 functor(Struct,struct,ISize),
3377 get_identifier_index(C,Index,IIndex),
3378 arg(IIndex,Struct,Susps),
3382 'chr sbag_del_element'(Susps,Susp,NSusps),
3383 setarg(IIndex,Variable,NSusps)
3385 delete_constraint_body(type_indexed_identifier_store(Index,IndexType),C,Head,Susp,VarDict,Body) :-
3386 get_suspension_argument_possibly_in_scope(Head,Index,VarDict,Susp,Variable,VariableGoal),
3387 type_indexed_identifier_structure(IndexType,Struct),
3388 get_type_indexed_identifier_index(IndexType,C,Index,IIndex),
3389 arg(IIndex,Struct,Susps),
3393 'chr sbag_del_element'(Susps,Susp,NSusps),
3394 setarg(IIndex,Variable,NSusps)
3397 generate_multi_inthash_delete_constraint_bodies([],_,_,true).
3398 generate_multi_inthash_delete_constraint_bodies([Index|Indexes],FA,Susp,(Body,Bodies)) :-
3399 multi_hash_store_name(FA,Index,StoreName),
3400 multi_hash_key(FA,Index,Susp,KeyBody,Key),
3404 nb_getval(StoreName,Store),
3405 delete_iht(Store,Key,Susp)
3407 generate_multi_inthash_delete_constraint_bodies(Indexes,FA,Susp,Bodies).
3408 generate_multi_hash_delete_constraint_bodies([],_,_,_,_,true).
3409 generate_multi_hash_delete_constraint_bodies([Index|Indexes],C,Head,Susp,VarDict,(Body,Bodies)) :-
3410 multi_hash_store_name(C,Index,StoreName),
3411 multi_hash_key(C,Head,Index,Susp,VarDict,KeyBody,Key),
3412 make_get_store_goal(StoreName,Store,GetStoreGoal),
3413 ( chr_pp_flag(ht_removal,on)
3414 -> ht_prev_field(Index,PrevField),
3415 get_dynamic_suspension_term_field(PrevField,C,Susp,Prev,GetGoal),
3416 set_dynamic_suspension_term_field(PrevField,C,NextSusp,_,
3418 set_dynamic_suspension_term_field(PrevField,C,NextSusp,Prev,
3426 delete_first_ht(Store,Key,Values),
3427 ( Values = [NextSusp|_]
3431 ; Prev = [_,_|Values],
3432 setarg(2,Prev,Values),
3433 ( Values = [NextSusp|_]
3442 GetStoreGoal, % nb_getval(StoreName,Store),
3443 delete_ht(Store,Key,Susp)
3446 generate_multi_hash_delete_constraint_bodies(Indexes,FA,Head,Susp,VarDict,Bodies).
3448 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3451 module_initializer/1,
3452 module_initializers/1.
3454 module_initializers(G), module_initializer(Initializer) <=>
3455 G = (Initializer,Initializers),
3456 module_initializers(Initializers).
3458 module_initializers(G) <=>
3461 generate_attach_code(Constraints,[Enumerate|L]) :-
3462 enumerate_stores_code(Constraints,Enumerate),
3463 generate_attach_code(Constraints,L,T),
3464 module_initializers(Initializers),
3465 prolog_global_variables_code(PrologGlobalVariables),
3466 % Do not rename or the 'chr_initialization' predicate
3467 % without warning SSS
3468 T = [('$chr_initialization' :- Initializers),(:- initialization '$chr_initialization')|PrologGlobalVariables].
3470 generate_attach_code([],L,L).
3471 generate_attach_code([C|Cs],L,T) :-
3472 get_store_type(C,StoreType),
3473 generate_attach_code(StoreType,C,L,L1),
3474 generate_attach_code(Cs,L1,T).
3476 generate_attach_code(default,C,L,T) :-
3477 global_list_store_initialisation(C,L,T).
3478 generate_attach_code(multi_inthash(Indexes),C,L,T) :-
3479 multi_inthash_store_initialisations(Indexes,C,L,L1),
3480 multi_inthash_via_lookups(Indexes,C,L1,T).
3481 generate_attach_code(multi_hash(Indexes),C,L,T) :-
3482 multi_hash_store_initialisations(Indexes,C,L,L1),
3483 multi_hash_lookups(Indexes,C,L1,T).
3484 generate_attach_code(atomic_constants(Index,Constants,_),C,L,T) :-
3485 constants_initializers(C,Index,Constants),
3486 atomic_constants_code(C,Index,Constants,L,T).
3487 generate_attach_code(ground_constants(Index,Constants),C,L,T) :-
3488 constants_initializers(C,Index,Constants),
3489 ground_constants_code(C,Index,Constants,L,T).
3490 generate_attach_code(global_ground,C,L,T) :-
3491 global_ground_store_initialisation(C,L,T).
3492 generate_attach_code(var_assoc_store(_,_),_,L,L) :-
3493 use_auxiliary_module(chr_assoc_store).
3494 generate_attach_code(global_singleton,C,L,T) :-
3495 global_singleton_store_initialisation(C,L,T).
3496 generate_attach_code(multi_store(StoreTypes),C,L,T) :-
3497 multi_store_generate_attach_code(StoreTypes,C,L,T).
3498 generate_attach_code(identifier_store(Index),C,L,T) :-
3499 get_identifier_index(C,Index,IIndex),
3501 get_identifier_size(ISize),
3502 functor(Struct,struct,ISize),
3503 Struct =.. [_,Label|Stores],
3504 set_elems(Stores,[]),
3505 Clause1 = new_identifier(Label,Struct),
3506 functor(Struct2,struct,ISize),
3507 arg(1,Struct2,Label2),
3509 ( user:portray(Struct2) :-
3514 functor(Struct3,struct,ISize),
3515 arg(1,Struct3,Label3),
3516 Clause3 = identifier_label(Struct3,Label3),
3517 L = [Clause1,Clause2,Clause3|T]
3521 generate_attach_code(type_indexed_identifier_store(Index,IndexType),C,L,T) :-
3522 get_type_indexed_identifier_index(IndexType,C,Index,IIndex),
3524 identifier_store_initialization(IndexType,L,L1),
3525 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3526 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3527 get_type_indexed_identifier_size(IndexType,ISize),
3528 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3529 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3530 type_indexed_identifier_structure(IndexType,Struct),
3531 Struct =.. [_,Label|Stores],
3532 set_elems(Stores,[]),
3533 type_indexed_identifier_name(IndexType,new_identifier,Name1),
3534 Clause1 =.. [Name1,Label,Struct],
3535 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3536 Goal1 =.. [Name1,Label1b,S1b],
3537 type_indexed_identifier_structure(IndexType,Struct1b),
3538 Struct1b =.. [_,Label1b|Stores1b],
3539 set_elems(Stores1b,[]),
3540 Expansion1 = (S1b = Struct1b),
3541 Clause1b = user:goal_expansion(Goal1,Expansion1),
3542 % writeln(Clause1-Clause1b),
3543 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3544 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3545 type_indexed_identifier_structure(IndexType,Struct2),
3546 arg(1,Struct2,Label2),
3548 ( user:portray(Struct2) :-
3553 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3554 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3555 type_indexed_identifier_structure(IndexType,Struct3),
3556 arg(1,Struct3,Label3),
3557 type_indexed_identifier_name(IndexType,identifier_label,Name3),
3558 Clause3 =.. [Name3,Struct3,Label3],
3559 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3560 Goal3b =.. [Name3,S3b,L3b],
3561 type_indexed_identifier_structure(IndexType,Struct3b),
3562 arg(1,Struct3b,L3b),
3563 Expansion3b = (S3 = Struct3b),
3564 Clause3b = ( user:goal_expansion(Goal3b,Expansion3b) :- writeln(expanding)),
3565 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3566 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3567 identifier_store_name(IndexType,GlobalVariable),
3568 lookup_identifier_atom(IndexType,X,IX,LookupAtom),
3569 type_indexed_identifier_name(IndexType,new_identifier,NewIdentifierFunctor),
3570 NewIdentifierGoal =.. [NewIdentifierFunctor,X,IX],
3573 nb_getval(GlobalVariable,HT),
3574 ( lookup_ht(HT,X,[IX]) ->
3581 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3582 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3583 L1 = [(:- multifile goal_expansion/2),(:- dynamic goal_expansion/2),Clause1,Clause1b,Clause2,Clause3,Clause3b,Clause4|T]
3588 constants_initializers(C,Index,Constants) :-
3589 maplist(constants_store_name(C,Index),Constants,StoreNames),
3590 findall(Initializer,
3591 ( member(StoreName,StoreNames),
3592 Initializer = nb_setval(StoreName,[])
3595 maplist(module_initializer,Initializers).
3597 lookup_identifier_atom(Key,X,IX,Atom) :-
3598 atom_concat('lookup_identifier_',Key,LookupFunctor),
3599 Atom =.. [LookupFunctor,X,IX].
3601 identifier_label_atom(IndexType,IX,X,Atom) :-
3602 type_indexed_identifier_name(IndexType,identifier_label,Name),
3603 Atom =.. [Name,IX,X].
3605 multi_store_generate_attach_code([],_,L,L).
3606 multi_store_generate_attach_code([ST|STs],C,L,T) :-
3607 generate_attach_code(ST,C,L,L1),
3608 multi_store_generate_attach_code(STs,C,L1,T).
3610 multi_inthash_store_initialisations([],_,L,L).
3611 multi_inthash_store_initialisations([Index|Indexes],FA,L,T) :-
3612 use_auxiliary_module(chr_integertable_store),
3613 multi_hash_store_name(FA,Index,StoreName),
3614 module_initializer((new_iht(HT),nb_setval(StoreName,HT))),
3615 % L = [(:- (chr_integertable_store:new_ht(HT),nb_setval(StoreName,HT)) )|L1],
3617 multi_inthash_store_initialisations(Indexes,FA,L1,T).
3618 multi_hash_store_initialisations([],_,L,L).
3619 multi_hash_store_initialisations([Index|Indexes],FA,L,T) :-
3620 use_auxiliary_module(chr_hashtable_store),
3621 multi_hash_store_name(FA,Index,StoreName),
3622 prolog_global_variable(StoreName),
3623 make_init_store_goal(StoreName,HT,InitStoreGoal),
3624 module_initializer((new_ht(HT),InitStoreGoal)),
3626 multi_hash_store_initialisations(Indexes,FA,L1,T).
3628 global_list_store_initialisation(C,L,T) :-
3630 global_list_store_name(C,StoreName),
3631 prolog_global_variable(StoreName),
3632 make_init_store_goal(StoreName,[],InitStoreGoal),
3633 module_initializer(InitStoreGoal)
3638 global_ground_store_initialisation(C,L,T) :-
3639 global_ground_store_name(C,StoreName),
3640 prolog_global_variable(StoreName),
3641 make_init_store_goal(StoreName,[],InitStoreGoal),
3642 module_initializer(InitStoreGoal),
3644 global_singleton_store_initialisation(C,L,T) :-
3645 global_singleton_store_name(C,StoreName),
3646 prolog_global_variable(StoreName),
3647 make_init_store_goal(StoreName,[],InitStoreGoal),
3648 module_initializer(InitStoreGoal),
3650 identifier_store_initialization(IndexType,L,T) :-
3651 use_auxiliary_module(chr_hashtable_store),
3652 identifier_store_name(IndexType,StoreName),
3653 prolog_global_variable(StoreName),
3654 make_init_store_goal(StoreName,HT,InitStoreGoal),
3655 module_initializer((new_ht(HT),InitStoreGoal)),
3659 multi_inthash_via_lookups([],_,L,L).
3660 multi_inthash_via_lookups([Index|Indexes],C,L,T) :-
3661 multi_hash_lookup_head(C,Index,Key,SuspsList,Head),
3662 multi_hash_lookup_body(C,inthash,Index,Key,SuspsList,Body),
3663 L = [(Head :- Body)|L1],
3664 multi_inthash_via_lookups(Indexes,C,L1,T).
3665 multi_hash_lookups([],_,L,L).
3666 multi_hash_lookups([Index|Indexes],C,L,T) :-
3667 multi_hash_lookup_head(C,Index,Key,SuspsList,Head),
3668 multi_hash_lookup_body(C,hash,Index,Key,SuspsList,Body),
3669 L = [(Head :- Body)|L1],
3670 multi_hash_lookups(Indexes,C,L1,T).
3672 multi_hash_lookup_head(ConstraintSymbol,Index,Key,SuspsList,Head) :-
3673 multi_hash_lookup_name(ConstraintSymbol,Index,Name),
3674 Head =.. [Name,Key,SuspsList].
3676 %% multi_hash_lookup_body(+ConstraintSymbol,+HashType,+Index,+Key,+SuspsList,-Goal) is det.
3678 % Returns goal that performs hash table lookup.
3679 multi_hash_lookup_body(ConstraintSymbol,HashType,Index,Key,SuspsList,Goal) :-
3681 ( get_store_type(ConstraintSymbol,multi_store(Stores)),
3682 memberchk(atomic_constants(Index,Constants,_),Stores) ->
3684 constants_store_name(ConstraintSymbol,Index,Key,StoreName),
3685 Goal = nb_getval(StoreName,SuspsList)
3687 constants_store_index_name(ConstraintSymbol,Index,IndexName),
3688 Lookup =.. [IndexName,Key,StoreName],
3689 Goal = (Lookup, nb_getval(StoreName,SuspsList))
3691 ; get_store_type(ConstraintSymbol,multi_store(Stores)),
3692 memberchk(ground_constants(Index,Constants),Stores) ->
3694 constants_store_name(ConstraintSymbol,Index,Key,StoreName),
3695 Goal = nb_getval(StoreName,SuspsList)
3697 constants_store_index_name(ConstraintSymbol,Index,IndexName),
3698 Lookup =.. [IndexName,Key,StoreName],
3699 Goal = (Lookup, nb_getval(StoreName,SuspsList))
3702 multi_hash_store_name(ConstraintSymbol,Index,StoreName),
3703 make_get_store_goal(StoreName,HT,GetStoreGoal),
3704 ( HashType == hash, specialized_hash_term_call(ConstraintSymbol,Index,Key,Hash,HashCall) ->
3707 GetStoreGoal, % nb_getval(StoreName,HT),
3708 HashCall, % hash_term(Key,Hash),
3709 lookup_ht1(HT,Hash,Key,SuspsList)
3712 lookup_hash_call(HashType,HT,Key,SuspsList,Lookup),
3715 GetStoreGoal, % nb_getval(StoreName,HT),
3716 hash_term(Key,Hash),
3723 lookup_hash_call(hash,HT,Key,SuspsList,lookup_ht(HT,Key,SuspsList)).
3724 lookup_hash_call(inthash,HT,Key,SuspsList,lookup_iht(HT,Key,SuspsList)).
3726 specialized_hash_term_call(Constraint,Index,Key,Hash,Call) :-
3728 % This is based on a property of SWI-Prolog's
3729 % hash_term/2 predicate:
3730 % the hash value is stable over repeated invocations
3732 hash_term(Key,Hash),
3734 ; Index = [IndexPos],
3735 get_constraint_type(Constraint,ArgTypes),
3736 nth1(IndexPos,ArgTypes,Type),
3737 unalias_type(Type,NormalType),
3738 memberchk_eq(NormalType,[int,natural]) ->
3739 ( NormalType == int ->
3748 specialize_hash_term(Key,NewKey),
3750 Call = hash_term(NewKey,Hash)
3753 specialize_hash_term(Term,NewTerm) :-
3755 hash_term(Term,NewTerm)
3760 maplist(specialize_hash_term,Args,NewArgs),
3761 NewTerm =.. [F|NewArgs]
3764 multi_hash_lookup_goal(ConstraintSymbol,HashType,Index,Key,SuspsList,Goal) :-
3765 ( /* chr_pp_flag(experiment,off) ->
3768 actual_atomic_multi_hash_keys(ConstraintSymbol,Index,[Key])
3770 actual_ground_multi_hash_keys(ConstraintSymbol,Index,[Key])
3772 actual_non_atomic_multi_hash_key(ConstraintSymbol,Index)
3774 delay_phase_end(validate_store_type_assumptions,
3775 multi_hash_lookup_body(ConstraintSymbol,HashType,Index,Key,SuspsList,Goal)).
3777 :- chr_constraint actual_atomic_multi_hash_keys/3.
3778 :- chr_option(mode,actual_atomic_multi_hash_keys(+,+,?)).
3780 :- chr_constraint actual_ground_multi_hash_keys/3.
3781 :- chr_option(mode,actual_ground_multi_hash_keys(+,+,?)).
3783 :- chr_constraint actual_non_atomic_multi_hash_key/2.
3784 :- chr_option(mode,actual_non_atomic_multi_hash_key(+,+)).
3787 actual_atomic_multi_hash_keys(C,Index,Keys)
3788 ==> format('Keys: ~w - ~w : ~w\n', [C,Index,Keys]).
3790 actual_ground_multi_hash_keys(C,Index,Keys)
3791 ==> format('Keys: ~w - ~w : ~w\n', [C,Index,Keys]).
3793 actual_non_atomic_multi_hash_key(C,Index)
3794 ==> format('Keys: ~w - ~w : N/A\n', [C,Index]).
3796 actual_atomic_multi_hash_keys(C,Index,Keys1), actual_atomic_multi_hash_keys(C,Index,Keys2)
3797 <=> append(Keys1,Keys2,Keys0),
3799 actual_atomic_multi_hash_keys(C,Index,Keys).
3801 actual_ground_multi_hash_keys(C,Index,Keys1), actual_atomic_multi_hash_keys(C,Index,Keys2)
3802 <=> append(Keys1,Keys2,Keys0),
3804 actual_ground_multi_hash_keys(C,Index,Keys).
3806 actual_ground_multi_hash_keys(C,Index,Keys1), actual_ground_multi_hash_keys(C,Index,Keys2)
3807 <=> append(Keys1,Keys2,Keys0),
3809 actual_ground_multi_hash_keys(C,Index,Keys).
3811 actual_non_atomic_multi_hash_key(C,Index) \ actual_non_atomic_multi_hash_key(C,Index)
3814 actual_non_atomic_multi_hash_key(C,Index) \ actual_atomic_multi_hash_keys(C,Index,_)
3817 actual_non_atomic_multi_hash_key(C,Index) \ actual_ground_multi_hash_keys(C,Index,_)
3820 %% multi_hash_lookup_name(+ConstraintSymbol,+Index,-Name)
3822 % Returns predicate name of hash table lookup predicate.
3823 multi_hash_lookup_name(F/A,Index,Name) :-
3827 atom_concat_list(Index,IndexName)
3829 atom_concat_list(['$via1_multi_hash_',F,'___',A,'-',IndexName],Name).
3831 multi_hash_store_name(F/A,Index,Name) :-
3832 get_target_module(Mod),
3836 atom_concat_list(Index,IndexName)
3838 atom_concat_list(['$chr_store_multi_hash_',Mod,'____',F,'___',A,'-',IndexName],Name).
3840 multi_hash_key(FA,Index,Susp,KeyBody,Key) :-
3841 ( ( integer(Index) ->
3846 get_dynamic_suspension_term_field(argument(I),FA,Susp,Key,KeyBody)
3848 sort(Index,Indexes),
3849 find_with_var_identity(Goal-KeyI,[Susp],(member(I,Indexes),get_dynamic_suspension_term_field(argument(I),FA,Susp,KeyI,Goal)),ArgKeyPairs),
3850 once(pairup(Bodies,Keys,ArgKeyPairs)),
3852 list2conj(Bodies,KeyBody)
3855 multi_hash_key(C,Head,Index,Susp,VarDict,KeyBody,Key) :-
3856 ( ( integer(Index) ->
3861 get_suspension_argument_possibly_in_scope(Head,I,VarDict,Susp,Key,KeyBody)
3863 sort(Index,Indexes),
3864 find_with_var_identity(
3866 [Susp/Head/VarDict],
3869 get_suspension_argument_possibly_in_scope(Head,I,VarDict,Susp,KeyI,Goal)
3873 once(pairup(Bodies,Keys,ArgKeyPairs)),
3875 list2conj(Bodies,KeyBody)
3878 get_suspension_argument_possibly_in_scope(Head,Index,VarDict,Susp,Arg,Goal) :-
3879 arg(Index,Head,OriginalArg),
3880 ( lookup_eq(VarDict,OriginalArg,Arg) ->
3885 get_dynamic_suspension_term_field(argument(Index),C,Susp,Arg,Goal)
3888 multi_hash_key_direct(FA,Index,Susp,Key,UsedVars) :-
3889 ( ( integer(Index) ->
3896 sort(Index,Indexes),
3897 pairup(Indexes,Keys,UsedVars),
3901 multi_hash_key_args(Index,Head,KeyArgs) :-
3903 arg(Index,Head,Arg),
3906 sort(Index,Indexes),
3907 term_variables(Head,Vars),
3908 find_with_var_identity(Arg,Vars,(member(I,Indexes), arg(I,Head,Arg)),KeyArgs)
3912 %-------------------------------------------------------------------------------
3913 atomic_constants_code(C,Index,Constants,L,T) :-
3914 constants_store_index_name(C,Index,IndexName),
3916 ( member(Constant,Constants),
3917 constants_store_name(C,Index,Constant,StoreName),
3918 Clause =.. [IndexName,Constant,StoreName]
3921 append(Clauses,T,L).
3923 %-------------------------------------------------------------------------------
3924 ground_constants_code(C,Index,Terms,L,T) :-
3925 constants_store_index_name(C,Index,IndexName),
3927 ( member(Constant,Terms),
3928 constants_store_name(C,Index,Constant,StoreName)
3932 replicate(N,[],More),
3933 trie_index([Terms|More],StoreNames,IndexName,L,T).
3935 constants_store_name(F/A,Index,Term,Name) :-
3936 get_target_module(Mod),
3937 term_to_atom(Term,Constant),
3938 term_to_atom(Index,IndexAtom),
3939 atom_concat_list(['$chr_store_constants_',Mod,'____',F,'___',A,'___',IndexAtom,'___',Constant],Name).
3941 constants_store_index_name(F/A,Index,Name) :-
3942 get_target_module(Mod),
3943 term_to_atom(Index,IndexAtom),
3944 atom_concat_list(['$chr_store_constants_',Mod,'____',F,'___',A,'___',IndexAtom],Name).
3946 trie_index([Patterns|MorePatterns],Results,Prefix,Clauses,Tail) :-
3947 trie_step(Patterns,Prefix,Prefix,MorePatterns,Results,Clauses,Tail).
3949 trie_step([],_,_,[],[],L,L) :- !.
3950 % length MorePatterns == length Patterns == length Results
3951 trie_step(Patterns,Symbol,Prefix,MorePatterns,Results,Clauses,T) :-
3952 MorePatterns = [List|_],
3955 ( member(Pattern,Patterns),
3956 functor(Pattern,F,A)
3961 trie_step_cases(FAs,N1,Patterns,MorePatterns,Results,Symbol,Prefix,Clauses,T).
3963 trie_step_cases([],_,_,_,_,_,_,Clauses,Clauses).
3964 trie_step_cases([FA|FAs],N,Pattern,MorePatterns,Results,Symbol,Prefix,Clauses,Tail) :-
3965 trie_step_case(FA,N,Pattern,MorePatterns,Results,Symbol,Prefix,Clauses,Clauses1),
3966 trie_step_cases(FAs,N,Pattern,MorePatterns,Results,Symbol,Prefix,Clauses1,Tail).
3968 trie_step_case(F/A,N,Patterns,MorePatterns,Results,Symbol,Prefix,[Clause|List],Tail) :-
3969 Clause = (Head :- Body),
3971 functor(Head,Symbol,N1),
3972 arg(N1,Head,Result),
3973 functor(IndexPattern,F,A),
3974 arg(1,Head,IndexPattern),
3975 Head =.. [_,_|RestArgs],
3976 IndexPattern =.. [_|Args],
3977 append(Args,RestArgs,RecArgs),
3978 ( RecArgs == [Result] ->
3981 rec_cases(Patterns,_,Results,F/A,_,_,MoreResults),
3982 MoreResults = [Result]
3984 gensym(Prefix,RSymbol),
3985 Body =.. [RSymbol|RecArgs],
3986 rec_cases(Patterns,MorePatterns,Results,F/A,Cases,MoreCases,MoreResults),
3987 trie_step(Cases,RSymbol,Prefix,MoreCases,MoreResults,List,Tail)
3990 rec_cases([],[],[],_,[],[],[]).
3991 rec_cases([Pattern|Patterns],[MorePattern|MorePatterns],[Result|Results],F/A,Cases,MoreCases,MoreResults) :-
3992 ( functor(Pattern,F,A), Pattern =.. [_|ArgPatterns], append(ArgPatterns,MorePattern,[Case|MoreCase]) ->
3993 Cases = [Case|NCases],
3994 MoreCases = [MoreCase|NMoreCases],
3995 MoreResults = [Result|NMoreResults],
3996 rec_cases(Patterns,MorePatterns,Results,F/A,NCases,NMoreCases,NMoreResults)
3998 rec_cases(Patterns,MorePatterns,Results,F/A,Cases,MoreCases,MoreResults)
4001 %-------------------------------------------------------------------------------
4002 global_list_store_name(F/A,Name) :-
4003 get_target_module(Mod),
4004 atom_concat_list(['$chr_store_global_list_',Mod,'____',F,'___',A],Name).
4005 global_ground_store_name(F/A,Name) :-
4006 get_target_module(Mod),
4007 atom_concat_list(['$chr_store_global_ground_',Mod,'____',F,'___',A],Name).
4008 global_singleton_store_name(F/A,Name) :-
4009 get_target_module(Mod),
4010 atom_concat_list(['$chr_store_global_singleton_',Mod,'____',F,'___',A],Name).
4012 identifier_store_name(TypeName,Name) :-
4013 get_target_module(Mod),
4014 atom_concat_list(['$chr_identifier_lookup_',Mod,'____',TypeName],Name).
4016 :- chr_constraint prolog_global_variable/1.
4017 :- chr_option(mode,prolog_global_variable(+)).
4019 :- chr_constraint prolog_global_variables/1.
4020 :- chr_option(mode,prolog_global_variables(-)).
4022 prolog_global_variable(Name) \ prolog_global_variable(Name) <=> true.
4024 prolog_global_variables(List), prolog_global_variable(Name) <=>
4026 prolog_global_variables(Tail).
4027 prolog_global_variables(List) <=> List = [].
4030 prolog_global_variables_code(Code) :-
4031 prolog_global_variables(Names),
4035 findall('$chr_prolog_global_variable'(Name),member(Name,Names),NameDeclarations),
4036 Code = [(:- dynamic user:exception/3),
4037 (:- multifile user:exception/3),
4038 (user:exception(undefined_global_variable,Name,retry) :-
4040 '$chr_prolog_global_variable'(Name),
4041 '$chr_initialization'
4050 % prolog_global_variables_code([]).
4052 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4053 %sbag_member_call(S,L,sysh:mem(S,L)).
4054 sbag_member_call(S,L,'chr sbag_member'(S,L)).
4055 %sbag_member_call(S,L,member(S,L)).
4056 update_mutable_call(A,B,'chr update_mutable'( A, B)).
4057 %update_mutable_call(A,B,setarg(1, B, A)).
4058 create_mutable_call(Value,Mutable,true) :- Mutable = mutable(Value).
4059 % create_mutable_call(Value,Mutable,'chr create_mutable'(Value,Mutable)).
4061 % get_suspension_field(Constraint,Susp,FieldName,Value,(Get0,Get1)) :-
4062 % get_dynamic_suspension_term_field(FieldName,Constraint,Susp,Field,Get0),
4063 % create_get_mutable(Value,Field,Get1).
4065 % update_suspension_field(Constraint,Susp,FieldName,NewValue,(Get,Set)) :-
4066 % get_dynamic_suspension_term_field(FieldName,Constraint,Susp,Field,Get),
4067 % update_mutable_call(NewValue,Field,Set).
4069 % get_update_suspension_field(Constraint,Susp,FieldName,Value,NewValue,Get0,Get1,Set) :-
4070 % get_dynamic_suspension_term_field(FieldName,Constraint,Susp,Field,Get0),
4071 % create_get_mutable_ref(Value,Field,Get1),
4072 % update_mutable_call(NewValue,Field,Set).
4074 % create_static_suspension_field(Constraint,Susp,FieldName,Value,Create) :-
4075 % get_static_suspension_term_field(FieldName,Constraint,Susp,Field),
4076 % create_mutable_call(Value,Field,Create).
4078 % get_static_suspension_field(Constraint,Susp,FieldName,Value,Get) :-
4079 % get_static_suspension_term_field(FieldName,Constraint,Susp,Field),
4080 % create_get_mutable(Value,Field,Get).
4082 % get_update_static_suspension_field(Constraint,Susp,SuspTerm,FieldName,Value,NewValue,Get,Set) :-
4083 % get_static_suspension_term_field(FieldName,Constraint,SuspTerm,Field),
4084 % create_get_mutable_ref(Value,Field,Get),
4085 % update_mutable_call(NewValue,Field,Set).
4087 get_suspension_field(Constraint,Susp,FieldName,Value,Get) :-
4088 get_dynamic_suspension_term_field(FieldName,Constraint,Susp,Value,Get).
4090 update_suspension_field(Constraint,Susp,FieldName,NewValue,Set) :-
4091 set_dynamic_suspension_term_field(FieldName,Constraint,Susp,NewValue,Set).
4093 get_update_suspension_field(Constraint,Susp,FieldName,Value,NewValue,true,Get,Set) :-
4094 get_dynamic_suspension_term_field(FieldName,Constraint,Susp,Value,Get),
4095 set_dynamic_suspension_term_field(FieldName,Constraint,Susp,NewValue,Set).
4097 create_static_suspension_field(Constraint,Susp,FieldName,Value,true) :-
4098 get_static_suspension_term_field(FieldName,Constraint,Susp,Value).
4100 get_static_suspension_field(Constraint,Susp,FieldName,Value,true) :-
4101 get_static_suspension_term_field(FieldName,Constraint,Susp,Value).
4103 get_update_static_suspension_field(Constraint,Susp,SuspTerm,FieldName,Value,NewValue,true,Set) :-
4104 get_static_suspension_term_field(FieldName,Constraint,SuspTerm,Value),
4105 set_dynamic_suspension_term_field(FieldName,Constraint,Susp,NewValue,Set).
4107 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4109 enumerate_stores_code(Constraints,Clause) :-
4110 Head = '$enumerate_constraints'(Constraint),
4111 enumerate_store_bodies(Constraints,Constraint,Bodies),
4112 list2disj(Bodies,Body),
4113 Clause = (Head :- Body).
4115 enumerate_store_bodies([],_,[]).
4116 enumerate_store_bodies([C|Cs],Constraint,L) :-
4118 get_store_type(C,StoreType),
4119 ( enumerate_store_body(StoreType,C,Suspension,SuspensionBody) ->
4122 chr_error(internal,'Could not generate enumeration code for constraint ~w.\n',[C])
4124 get_dynamic_suspension_term_field(arguments,C,Suspension,Arguments,DynamicGoal),
4126 Constraint0 =.. [F|Arguments],
4127 Body = (SuspensionBody, DynamicGoal, Constraint = Constraint0),
4132 enumerate_store_bodies(Cs,Constraint,T).
4134 enumerate_store_body(default,C,Susp,Body) :-
4135 global_list_store_name(C,StoreName),
4136 sbag_member_call(Susp,List,Sbag),
4137 make_get_store_goal(StoreName,List,GetStoreGoal),
4140 GetStoreGoal, % nb_getval(StoreName,List),
4143 % get_constraint_index(C,Index),
4144 % get_target_module(Mod),
4145 % get_max_constraint_index(MaxIndex),
4148 % 'chr default_store'(GlobalStore),
4149 % get_attr(GlobalStore,Mod,Attr)
4152 % NIndex is Index + 1,
4153 % sbag_member_call(Susp,List,Sbag),
4156 % arg(NIndex,Attr,List),
4160 % sbag_member_call(Susp,Attr,Sbag),
4163 % Body = (Body1,Body2).
4164 enumerate_store_body(multi_inthash([Index|_]),C,Susp,Body) :-
4165 multi_inthash_enumerate_store_body(Index,C,Susp,Body).
4166 enumerate_store_body(multi_hash([Index|_]),C,Susp,Body) :-
4167 multi_hash_enumerate_store_body(Index,C,Susp,Body).
4168 enumerate_store_body(atomic_constants(Index,Constants,Completeness),C,Susp,Body) :-
4169 Completeness == complete, % fail if incomplete
4170 find_with_var_identity(nb_getval(StoreName,Susps),[Susps],
4171 ( member(Constant,Constants),
4172 constants_store_name(C,Index,Constant,StoreName) )
4174 list2disj(Disjuncts, Disjunction),
4175 Body = ( Disjunction, member(Susp,Susps) ).
4176 enumerate_store_body(ground_constants(_,_),_,_,_) :- fail.
4177 enumerate_store_body(global_ground,C,Susp,Body) :-
4178 global_ground_store_name(C,StoreName),
4179 sbag_member_call(Susp,List,Sbag),
4180 make_get_store_goal(StoreName,List,GetStoreGoal),
4183 GetStoreGoal, % nb_getval(StoreName,List),
4186 enumerate_store_body(var_assoc_store(_,_),C,_,Body) :-
4188 enumerate_store_body(global_singleton,C,Susp,Body) :-
4189 global_singleton_store_name(C,StoreName),
4190 make_get_store_goal(StoreName,Susp,GetStoreGoal),
4193 GetStoreGoal, % nb_getval(StoreName,Susp),
4196 enumerate_store_body(multi_store(STs),C,Susp,Body) :-
4199 enumerate_store_body(ST,C,Susp,Body)
4201 enumerate_store_body(identifier_store(Index),C,Susp,Body) :-
4203 enumerate_store_body(type_indexed_identifier_store(Index,IndexType),C,Susp,Body) :-
4206 multi_inthash_enumerate_store_body(I,C,Susp,B) :-
4207 multi_hash_store_name(C,I,StoreName),
4210 nb_getval(StoreName,HT),
4213 multi_hash_enumerate_store_body(I,C,Susp,B) :-
4214 multi_hash_store_name(C,I,StoreName),
4215 make_get_store_goal(StoreName,HT,GetStoreGoal),
4218 GetStoreGoal, % nb_getval(StoreName,HT),
4222 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4231 :- chr_option(mode,prev_guard_list(+,+,+,+,+,+,+,+)).
4232 :- chr_option(mode,prev_guard_list(+,+,+,+,+,+)).
4233 :- chr_option(type_declaration,prev_guard_list(any,any,any,any,any,list)).
4234 :- chr_option(mode,simplify_guards(+)).
4235 :- chr_option(mode,set_all_passive(+)).
4237 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4238 % GUARD SIMPLIFICATION
4239 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4240 % If the negation of the guards of earlier rules entails (part of)
4241 % the current guard, the current guard can be simplified. We can only
4242 % use earlier rules with a head that matches if the head of the current
4243 % rule does, and which make it impossible for the current rule to match
4244 % if they fire (i.e. they shouldn't be propagation rules and their
4245 % head constraints must be subsets of those of the current rule).
4246 % At this point, we know for sure that the negation of the guard
4247 % of such a rule has to be true (otherwise the earlier rule would have
4248 % fired, because of the refined operational semantics), so we can use
4249 % that information to simplify the guard by replacing all entailed
4250 % conditions by true/0. As a consequence, the never-stored analysis
4251 % (in a further phase) will detect more cases of never-stored constraints.
4253 % e.g. c(X),d(Y) <=> X > 0 | ...
4254 % e(X) <=> X < 0 | ...
4255 % c(X) \ d(Y),e(Z) <=> X =< 0, Z >= 0, ... | ...
4259 guard_simplification :-
4260 ( chr_pp_flag(guard_simplification,on) ->
4261 precompute_head_matchings,
4267 % for every rule, we create a prev_guard_list where the last argument
4268 % eventually is a list of the negations of earlier guards
4269 rule(RuleNb,Rule) \ simplify_guards(RuleNb)
4271 Rule = pragma(rule(Head1,Head2,Guard,_B),ids(IDs1,IDs2),_Pragmas,_Name,RuleNb),
4272 append(Head1,Head2,Heads),
4273 make_head_matchings_explicit_not_negated(Heads,MatchingFreeHeads,Matchings),
4274 multiple_occ_constraints_checked([]),
4275 apply_guard_wrt_term(Heads,Guard,SubstitutedHeads),
4277 append(IDs1,IDs2,IDs),
4278 findall(tuple(C,O,RuleNb)-(-RuleNb),(member(ID,IDs),get_occurrence_from_id(C,O,RuleNb,ID)),HeapData),
4280 insert_list_q(HeapData,EmptyHeap,Heap),
4281 next_prev_rule(Heap,_,Heap1),
4282 next_prev_rule(Heap1,PrevRuleNb,NHeap),
4283 prev_guard_list(RuleNb,PrevRuleNb,NHeap,MatchingFreeHeads,Guard,[],Matchings,[SubstitutedHeads]),
4284 NextRule is RuleNb+1,
4285 simplify_guards(NextRule).
4287 next_prev_rule(Heap,RuleNb,NHeap) :-
4288 ( find_min_q(Heap,_-Priority) ->
4289 Priority = (-RuleNb),
4290 normalize_heap(Heap,Priority,NHeap)
4296 normalize_heap(Heap,Priority,NHeap) :-
4297 ( find_min_q(Heap,_-Priority) ->
4298 delete_min_q(Heap,Heap1,tuple(C,O,_)-_),
4301 get_occurrence(C,NO,RuleNb,_),
4302 insert_q(Heap1,tuple(C,NO,RuleNb)-(-RuleNb),Heap2)
4306 normalize_heap(Heap2,Priority,NHeap)
4316 % The negation of the guard of a non-propagation rule is added
4317 % if its kept head constraints are a subset of the kept constraints of
4318 % the rule we're working on, and its removed head constraints (at least one)
4319 % are a subset of the removed constraints.
4321 rule(PrevRuleNb,PrevRule) \ prev_guard_list(RuleNb,PrevRuleNb,Heap,CurrentHeads,G,GuardList,Matchings,GH)
4323 PrevRule = pragma(rule(H1,H2,PrevGuard,_B),_Ids,_Pragmas,_Name,_PrevRuleNb), % PrevRuleNb == _PrevRuleNb
4325 make_head_matchings_explicit(PrevRuleNb,MatchingFreeHeads,PrevMatchings),
4326 setof(Renaming,chr_translate:head_subset(MatchingFreeHeads,CurrentHeads,Renaming),Renamings)
4328 append(H1,H2,Heads),
4329 compute_derived_info(Renamings,PrevMatchings,MatchingFreeHeads,Heads,PrevGuard,Matchings,CurrentHeads,GH,DerivedInfo,GH_New1),
4330 append(GuardList,DerivedInfo,GL1),
4331 normalize_conj_list(GL1,GL),
4332 append(GH_New1,GH,GH1),
4333 normalize_conj_list(GH1,GH_New),
4334 next_prev_rule(Heap,PrevPrevRuleNb,NHeap),
4335 % PrevPrevRuleNb is PrevRuleNb-1,
4336 prev_guard_list(RuleNb,PrevPrevRuleNb,NHeap,CurrentHeads,G,GL,Matchings,GH_New).
4338 % if this isn't the case, we skip this one and try the next rule
4339 prev_guard_list(RuleNb,N,Heap,H,G,GuardList,M,GH)
4342 next_prev_rule(Heap,N1,NHeap),
4344 prev_guard_list(RuleNb,N1,NHeap,H,G,GuardList,M,GH)
4346 prev_guard_list(RuleNb,H,G,GuardList,M,GH)
4349 prev_guard_list(RuleNb,H,G,GuardList,M,GH)
4353 head_types_modes_condition(GH,H,TypeInfo),
4354 conj2list(TypeInfo,TI),
4355 term_variables(H,HeadVars),
4356 append([chr_pp_headvariables(HeadVars)|TI],GuardList,Info),
4357 normalize_conj_list(Info,InfoL),
4358 prev_guard_list(RuleNb,H,G,InfoL,M,[]).
4360 head_types_modes_condition([],H,true).
4361 head_types_modes_condition([GH|GHs],H,(TI1, TI2)) :-
4362 types_modes_condition(H,GH,TI1),
4363 head_types_modes_condition(GHs,H,TI2).
4367 % when all earlier guards are added or skipped, we simplify the guard.
4368 % if it's different from the original one, we change the rule
4370 prev_guard_list(RuleNb,H,G,GuardList,M,[]), rule(RuleNb,Rule)
4372 Rule = pragma(rule(Head1,Head2,G,B),Ids,Pragmas,Name,RuleNb),
4373 G \== true, % let's not try to simplify this ;)
4374 append(M,GuardList,Info),
4375 simplify_guard(G,B,Info,SimpleGuard,NB),
4378 rule(RuleNb,pragma(rule(Head1,Head2,SimpleGuard,NB),Ids,Pragmas,Name,RuleNb)),
4379 prev_guard_list(RuleNb,H,SimpleGuard,GuardList,M,[]).
4381 %% normalize_conj_list(+List,-NormalList) is det.
4383 % Removes =true= elements and flattens out conjunctions.
4385 normalize_conj_list(List,NormalList) :-
4386 list2conj(List,Conj),
4387 conj2list(Conj,NormalList).
4389 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4390 % AUXILIARY PREDICATES (GUARD SIMPLIFICATION)
4391 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4393 compute_derived_info([],_PrevMatchings,_MatchingFreeHeads,_Heads,_PrevGuard,_Matchings,_H,_GH,[],[]).
4394 compute_derived_info([Renaming1|RestRenamings],PrevMatchings,PrevMatchingFreeHeads,PrevHeads,PrevGuard,Matchings,H,GH,[DerivedInfo1|DerivedInfo2],[GH3|GH_New2]) :-
4395 copy_term(PrevMatchings-PrevGuard,FreshMatchings),
4396 variable_replacement(PrevMatchings-PrevGuard,FreshMatchings,ExtraRenaming),
4397 append(Renaming1,ExtraRenaming,Renaming2),
4398 list2conj(PrevMatchings,Match),
4399 negate_b(Match,HeadsDontMatch),
4400 make_head_matchings_explicit_not_negated2(PrevHeads,PrevMatchingFreeHeads,HeadsMatch),
4401 list2conj(HeadsMatch,HeadsMatchBut),
4402 term_variables(Renaming2,RenVars),
4403 term_variables(PrevMatchings-PrevGuard-HeadsMatch,MGVars),
4404 new_vars(MGVars,RenVars,ExtraRenaming2),
4405 append(Renaming2,ExtraRenaming2,Renaming),
4406 ( PrevGuard == true -> % true can't fail
4407 Info_ = HeadsDontMatch
4409 negate_b(PrevGuard,TheGuardFailed),
4410 Info_ = (HeadsDontMatch ; (HeadsMatchBut, TheGuardFailed))
4412 copy_with_variable_replacement(Info_,DerivedInfo1,Renaming),
4413 copy_with_variable_replacement(PrevGuard,RenamedG2,Renaming),
4414 copy_with_variable_replacement(PrevMatchings,RenamedMatchings_,Renaming),
4415 list2conj(RenamedMatchings_,RenamedMatchings),
4416 apply_guard_wrt_term(H,RenamedG2,GH2),
4417 apply_guard_wrt_term(GH2,RenamedMatchings,GH3),
4418 compute_derived_info(RestRenamings,PrevMatchings,PrevMatchingFreeHeads,PrevHeads,PrevGuard,Matchings,H,GH,DerivedInfo2,GH_New2).
4420 simplify_guard(G,B,Info,SG,NB) :-
4422 % writeq(guard_entailment:simplify_guards(Info,B,LG,SGL,NB)),nl,
4423 guard_entailment:simplify_guards(Info,B,LG,SGL,NB),
4428 new_vars([A|As],RV,ER) :-
4429 ( memberchk_eq(A,RV) ->
4432 ER = [A-NewA,NewA-A|ER2],
4436 %% head_subset(+Subset,+MultiSet,-Renaming) is nondet.
4438 % check if a list of constraints is a subset of another list of constraints
4439 % (multiset-subset), meanwhile computing a variable renaming to convert
4440 % one into the other.
4441 head_subset(H,Head,Renaming) :-
4442 head_subset(H,Head,Renaming,[],_).
4444 head_subset([],Remainder,Renaming,Renaming,Remainder).
4445 head_subset([X|Xs],MultiSet,Renaming,Acc,Remainder) :-
4446 head_member(MultiSet,X,NAcc,Acc,Remainder1),
4447 head_subset(Xs,Remainder1,Renaming,NAcc,Remainder).
4449 % check if A is in the list, remove it from Headleft
4450 head_member([X|Xs],A,Renaming,Acc,Remainder) :-
4451 ( variable_replacement(A,X,Acc,Renaming),
4454 Remainder = [X|RRemainder],
4455 head_member(Xs,A,Renaming,Acc,RRemainder)
4457 %-------------------------------------------------------------------------------%
4458 % memoing code to speed up repeated computation
4460 :- chr_constraint precompute_head_matchings/0.
4462 rule(RuleNb,PragmaRule), precompute_head_matchings ==>
4463 PragmaRule = pragma(rule(H1,H2,_G,_B),_Ids,_Pragmas,_Name,_PrevRuleNb),
4464 append(H1,H2,Heads),
4465 make_head_matchings_explicit_(Heads,MatchingFreeHeads,Matchings),
4466 copy_term_nat(MatchingFreeHeads-Matchings,A-B),
4467 make_head_matchings_explicit_memo_table(RuleNb,A,B).
4469 precompute_head_matchings <=> true.
4471 :- chr_constraint make_head_matchings_explicit_memo_table/3.
4472 :- chr_constraint make_head_matchings_explicit_memo_lookup/3.
4474 :- chr_option(mode,make_head_matchings_explicit_memo_table(+,?,?)).
4475 :- chr_option(mode,make_head_matchings_explicit_memo_lookup(+,?,?)).
4477 make_head_matchings_explicit_memo_table(RuleNb,NHeads,Matchings) \
4478 make_head_matchings_explicit_memo_lookup(RuleNb,Q1,Q2)
4482 make_head_matchings_explicit_memo_lookup(_,_,_) <=> fail.
4484 make_head_matchings_explicit(RuleNb,MatchingFreeHeads,Matchings) :-
4485 make_head_matchings_explicit_memo_lookup(RuleNb,A,B),
4486 copy_term_nat(A-B,MatchingFreeHeads-Matchings).
4487 %-------------------------------------------------------------------------------%
4489 make_head_matchings_explicit_(Heads,MatchingFreeHeads,Matchings) :-
4490 extract_arguments(Heads,Arguments),
4491 make_matchings_explicit(Arguments,FreeVariables,[],[],_,Matchings),
4492 substitute_arguments(Heads,FreeVariables,MatchingFreeHeads).
4494 make_head_matchings_explicit_not_negated(Heads,MatchingFreeHeads,Matchings) :-
4495 extract_arguments(Heads,Arguments),
4496 make_matchings_explicit_not_negated(Arguments,FreshVariables,Matchings),
4497 substitute_arguments(Heads,FreshVariables,MatchingFreeHeads).
4499 make_head_matchings_explicit_not_negated2(Heads,MatchingFreeHeads,Matchings) :-
4500 extract_arguments(Heads,Arguments1),
4501 extract_arguments(MatchingFreeHeads,Arguments2),
4502 make_matchings_explicit_not_negated(Arguments1,Arguments2,Matchings).
4504 %% extract_arguments(+ListOfConstraints,-ListOfVariables) is det.
4506 % Returns list of arguments of given list of constraints.
4507 extract_arguments([],[]).
4508 extract_arguments([Constraint|Constraints],AllArguments) :-
4509 Constraint =.. [_|Arguments],
4510 append(Arguments,RestArguments,AllArguments),
4511 extract_arguments(Constraints,RestArguments).
4513 %% substitute_arguments(+InListOfConstraints,ListOfVariables,-OutListOfConstraints) is det.
4515 % Substitutes arguments of constraints with those in the given list.
4517 substitute_arguments([],[],[]).
4518 substitute_arguments([Constraint|Constraints],Variables,[NConstraint|NConstraints]) :-
4519 functor(Constraint,F,N),
4520 split_at(N,Variables,Arguments,RestVariables),
4521 NConstraint =.. [F|Arguments],
4522 substitute_arguments(Constraints,RestVariables,NConstraints).
4524 make_matchings_explicit([],[],_,MC,MC,[]).
4525 make_matchings_explicit([Arg|Args],[NewVar|NewVars],VarAcc,MatchingCondition,MatchingConditionO,Matchings) :-
4527 ( memberchk_eq(Arg,VarAcc) ->
4528 list2disj(MatchingCondition,MatchingCondition_disj),
4529 Matchings = [(MatchingCondition_disj ; NewVar == Arg)|RestMatchings], % or only = ??
4532 Matchings = RestMatchings,
4534 NVarAcc = [Arg|VarAcc]
4536 MatchingCondition2 = MatchingCondition
4539 Arg =.. [F|RecArgs],
4540 make_matchings_explicit(RecArgs,RecVars,VarAcc,MatchingCondition,MatchingCondition_,RecMatchings),
4541 FlatArg =.. [F|RecVars],
4542 ( RecMatchings == [] ->
4543 Matchings = [functor(NewVar,F,A)|RestMatchings]
4545 list2conj(RecMatchings,ArgM_conj),
4546 list2disj(MatchingCondition,MatchingCondition_disj),
4547 ArgM_ = (NewVar \= FlatArg ; MatchingCondition_disj ; ArgM_conj),
4548 Matchings = [ functor(NewVar,F,A) , ArgM_|RestMatchings]
4550 MatchingCondition2 = [ NewVar \= FlatArg |MatchingCondition_],
4551 term_variables(Args,ArgVars),
4552 append(ArgVars,VarAcc,NVarAcc)
4554 make_matchings_explicit(Args,NewVars,NVarAcc,MatchingCondition2,MatchingConditionO,RestMatchings).
4557 %% make_matchings_explicit_not_negated(+ListOfTerms,-ListOfVariables,-ListOfMatchings) is det.
4559 % Returns list of new variables and list of pairwise unifications between given list and variables.
4561 make_matchings_explicit_not_negated([],[],[]).
4562 make_matchings_explicit_not_negated([X|Xs],[Var|Vars],Matchings) :-
4563 Matchings = [Var = X|RMatchings],
4564 make_matchings_explicit_not_negated(Xs,Vars,RMatchings).
4566 %% apply_guard_wrt_term(+ListOfConstraints,+Goal,-NewListOfConstraints) is det.
4568 % (Partially) applies substitutions of =Goal= to given list.
4570 apply_guard_wrt_term([],_Guard,[]).
4571 apply_guard_wrt_term([Term|RH],Guard,[NTerm|RGH]) :-
4573 apply_guard_wrt_variable(Guard,Term,NTerm)
4576 apply_guard_wrt_term(HArgs,Guard,NewHArgs),
4577 NTerm =.. [F|NewHArgs]
4579 apply_guard_wrt_term(RH,Guard,RGH).
4581 %% apply_guard_wrt_variable(+Goal,+Variable,-NVariable) is det.
4583 % (Partially) applies goal =Guard= wrt variable.
4585 apply_guard_wrt_variable((Guard1,Guard2),Variable,NVariable) :- !,
4586 apply_guard_wrt_variable(Guard1,Variable,NVariable1),
4587 apply_guard_wrt_variable(Guard2,NVariable1,NVariable).
4588 apply_guard_wrt_variable(Guard,Variable,NVariable) :-
4589 ( Guard = (X = Y), Variable == X ->
4591 ; Guard = functor(AVariable,Functor,Arity), Variable == AVariable, ground(Functor), ground(Arity) ->
4592 functor(NVariable,Functor,Arity)
4594 NVariable = Variable
4597 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4598 % ALWAYS FAILING HEADS
4599 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4601 rule(RuleNb,Rule) \ prev_guard_list(RuleNb,H,G,GuardList,M,[])
4603 chr_pp_flag(check_impossible_rules,on),
4604 Rule = pragma(rule(Head1,Head2,G,B),Ids,Pragmas,Name,RuleNb),
4605 append(M,GuardList,Info),
4606 guard_entailment:entails_guard(Info,fail)
4608 chr_warning(weird_program,'Heads will never match in ~@.\n\tThis rule will never fire!\n',[format_rule(Rule)]),
4609 set_all_passive(RuleNb).
4611 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4612 % HEAD SIMPLIFICATION
4613 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4615 % now we check the head matchings (guard may have been simplified meanwhile)
4616 prev_guard_list(RuleNb,H,G,GuardList,M,[]) \ rule(RuleNb,Rule)
4618 Rule = pragma(rule(Head1,Head2,G,B),Ids,Pragmas,Name,RuleNb),
4619 simplify_heads(M,GuardList,G,B,NewM,NewB),
4621 extract_arguments(Head1,VH1),
4622 extract_arguments(Head2,VH2),
4623 extract_arguments(H,VH),
4624 replace_some_heads(VH1,VH2,VH,NewM,H1,H2,G,B,NewB_),
4625 substitute_arguments(Head1,H1,NewH1),
4626 substitute_arguments(Head2,H2,NewH2),
4627 append(NewB,NewB_,NewBody),
4628 list2conj(NewBody,BodyMatchings),
4629 NewRule = pragma(rule(NewH1,NewH2,G,(BodyMatchings,B)),Ids,Pragmas,Name,RuleNb),
4630 (Head1 \== NewH1 ; Head2 \== NewH2 )
4632 rule(RuleNb,NewRule).
4634 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4635 % AUXILIARY PREDICATES (HEAD SIMPLIFICATION)
4636 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4638 replace_some_heads(H1,H2,NH,[],H1,H2,G,Body,[]) :- !.
4639 replace_some_heads([],[H2|RH2],[NH|RNH],[M|RM],[],[H2_|RH2_],G,Body,NewB) :- !,
4642 replace_some_heads([],RH2,RNH,RM,[],RH2_,G,Body,NewB)
4644 (M = functor(X,F,A), NH == X ->
4650 H2 =.. [F|OrigArgs],
4651 use_same_args(OrigArgs,A_args,A_args_,G,Body,NewB1),
4654 replace_some_heads([],RH2,RNH,RM,[],RH2_,G,Body,NewB2),
4655 append(NewB1,NewB2,NewB)
4658 replace_some_heads([],RH2,RNH,[M|RM],[],RH2_,G,Body,NewB)
4662 replace_some_heads([H1|RH1],H2,[NH|RNH],[M|RM],[H1_|RH1_],H2_,G,Body,NewB) :- !,
4665 replace_some_heads(RH1,H2,RNH,RM,RH1_,H2_,G,Body,NewB)
4667 (M = functor(X,F,A), NH == X ->
4673 H1 =.. [F|OrigArgs],
4674 use_same_args(OrigArgs,A_args,A_args_,G,Body,NewB1),
4677 replace_some_heads(RH1,H2,RNH,RM,RH1_,H2_,G,Body,NewB2),
4678 append(NewB1,NewB2,NewB)
4681 replace_some_heads(RH1,H2,RNH,[M|RM],RH1_,H2_,G,Body,NewB)
4685 use_same_args([],[],[],_,_,[]).
4686 use_same_args([OA|ROA],[NA|RNA],[Out|ROut],G,Body,NewB) :-
4689 use_same_args(ROA,RNA,ROut,G,Body,NewB).
4690 use_same_args([OA|ROA],[NA|RNA],[Out|ROut],G,Body,NewB) :-
4692 ( common_variables(OA,Body) ->
4693 NewB = [NA = OA|NextB]
4698 use_same_args(ROA,RNA,ROut,G,Body,NextB).
4701 simplify_heads([],_GuardList,_G,_Body,[],[]).
4702 simplify_heads([M|RM],GuardList,G,Body,NewM,NewB) :-
4704 ( (nonvar(B) ; common_variables(B,RM-GuardList)),
4705 guard_entailment:entails_guard(GuardList,(A=B)) ->
4706 ( common_variables(B,G-RM-GuardList) ->
4710 ( common_variables(B,Body) ->
4711 NewB = [A = B|NextB]
4718 ( nonvar(B), functor(B,BFu,BAr),
4719 guard_entailment:entails_guard([functor(A,BFu,BAr)|GuardList],(A=B)) ->
4721 ( common_variables(B,G-RM-GuardList) ->
4724 NewM = [functor(A,BFu,BAr)|NextM]
4731 simplify_heads(RM,[M|GuardList],G,Body,NextM,NextB).
4733 common_variables(B,G) :-
4734 term_variables(B,BVars),
4735 term_variables(G,GVars),
4736 intersect_eq(BVars,GVars,L),
4740 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4741 % ALWAYS FAILING GUARDS
4742 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4744 set_all_passive(RuleNb), occurrence(_,_,RuleNb,ID,_) ==> passive(RuleNb,ID).
4745 set_all_passive(_) <=> true.
4747 prev_guard_list(RuleNb,H,G,GuardList,M,[]),rule(RuleNb,Rule)
4749 chr_pp_flag(check_impossible_rules,on),
4750 Rule = pragma(rule(_,_,G,_),_Ids,_Pragmas,_Name,RuleNb),
4752 % writeq(guard_entailment:entails_guard(GL,fail)),nl,
4753 guard_entailment:entails_guard(GL,fail)
4755 chr_warning(weird_program,'Guard will always fail in ~@.\n\tThis rule will never fire!\n',[format_rule(Rule)]),
4756 set_all_passive(RuleNb).
4760 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4761 % OCCURRENCE SUBSUMPTION
4762 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4765 first_occ_in_rule/4,
4768 :- chr_option(mode,first_occ_in_rule(+,+,+,+)).
4769 :- chr_option(mode,next_occ_in_rule(+,+,+,+,+,+)).
4771 :- chr_constraint multiple_occ_constraints_checked/1.
4772 :- chr_option(mode,multiple_occ_constraints_checked(+)).
4774 prev_guard_list(RuleNb,H,G,GuardList,M,[]),
4775 occurrence(C,O,RuleNb,ID,_),
4776 occurrence(C,O2,RuleNb,ID2,_),
4779 multiple_occ_constraints_checked(Done)
4782 chr_pp_flag(occurrence_subsumption,on),
4783 Rule = pragma(rule(H1,H2,_G,_B),_Ids,_Pragmas,_Name,_RuleNb), % RuleNb == _RuleNb
4785 \+ memberchk_eq(C,Done)
4787 first_occ_in_rule(RuleNb,C,O,ID),
4788 multiple_occ_constraints_checked([C|Done]).
4790 % Find first occurrence of constraint =C= in rule =RuleNb=
4791 occurrence(C,O,RuleNb,ID,_) \ first_occ_in_rule(RuleNb,C,O2,_)
4795 first_occ_in_rule(RuleNb,C,O,ID).
4797 first_occ_in_rule(RuleNb,C,O,ID_o1)
4800 functor(FreshHead,F,A),
4801 next_occ_in_rule(RuleNb,C,O,ID_o1,[],FreshHead).
4803 % Skip passive occurrences.
4804 passive(RuleNb,ID_o2), occurrence(C,O2,RuleNb,ID_o2,_) \ next_occ_in_rule(RuleNb,C,O,ID_o1,Cond,FH)
4808 next_occ_in_rule(RuleNb,C,O2,ID_o1,NewCond,FH).
4810 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)
4813 Rule = pragma(rule(H1,H2,G,B),ids(ID1,ID2),_Pragmas,_Name,RuleNb)
4815 append(H1,H2,Heads),
4816 add_failing_occ(Rule,Heads,H,ID_o1,ExtraCond,FH,M,C,Repl),
4817 ( ExtraCond == [chr_pp_void_info] ->
4818 next_occ_in_rule(RuleNb,C,O2,ID_o2,Cond,FH)
4820 append(ExtraCond,Cond,NewCond),
4821 add_failing_occ(Rule,Heads,H,ID_o2,CheckCond,FH,M,C,Repl2),
4822 copy_term(GuardList,FGuardList),
4823 variable_replacement(GuardList,FGuardList,GLRepl),
4824 copy_with_variable_replacement(GuardList,GuardList2,Repl),
4825 copy_with_variable_replacement(GuardList,GuardList3_,Repl2),
4826 copy_with_variable_replacement(GuardList3_,GuardList3,GLRepl),
4827 append(NewCond,GuardList2,BigCond),
4828 append(BigCond,GuardList3,BigCond2),
4829 copy_with_variable_replacement(M,M2,Repl),
4830 copy_with_variable_replacement(M,M3,Repl2),
4831 append(M3,BigCond2,BigCond3),
4832 append([chr_pp_active_constraint(FH)|M2],BigCond3,Info),
4833 list2conj(CheckCond,OccSubsum),
4834 copy_term((NewCond,BigCond2,Info,OccSubsum,FH),(NewCond2,BigCond2_,Info2,OccSubsum2,FH2)),
4835 ( OccSubsum \= chr_pp_void_info ->
4836 ( guard_entailment:entails_guard(Info2,OccSubsum2) ->
4837 passive(RuleNb,ID_o2)
4844 next_occ_in_rule(RuleNb,C,O2,ID_o2,NewCond,FH)
4848 next_occ_in_rule(RuleNb,C,O,ID,Cond,Args)
4852 prev_guard_list(RuleNb,H,G,GuardList,M,[]), multiple_occ_constraints_checked(Done)
4856 add_failing_occ(Rule,Heads,NH,ID_o1,FailCond,FH,M,C,Repl) :-
4857 Rule = pragma(rule(H1,H2,G,B),ids(ID1,ID2),_Pragmas,_Name,RuleNb),
4858 append(ID2,ID1,IDs),
4859 missing_partner_cond(Heads,NH,IDs,ID_o1,MPCond,H,C),
4860 copy_term((H,Heads,NH),(FH2,FHeads,NH2)),
4861 variable_replacement((H,Heads,NH),(FH2,FHeads,NH2),Repl),
4862 copy_with_variable_replacement(G,FG,Repl),
4863 extract_explicit_matchings(FG,FG2),
4864 negate_b(FG2,NotFG),
4865 copy_with_variable_replacement(MPCond,FMPCond,Repl),
4866 ( safely_unifiable(FH,FH2), FH=FH2 ->
4867 FailCond = [(NotFG;FMPCond)]
4869 % in this case, not much can be done
4870 % e.g. c(f(...)), c(g(...)) <=> ...
4871 FailCond = [chr_pp_void_info]
4874 missing_partner_cond([],[],[],ID_o1,fail,H2,C).
4875 missing_partner_cond([H|Hs],[H2|H2s],[ID_o1|IDs],ID_o1,Cond,H,C) :- !,
4876 missing_partner_cond(Hs,H2s,IDs,ID_o1,Cond,H,C).
4877 missing_partner_cond([H|Hs],[NH|NHs],[ID|IDs],ID_o1,Cond,H2,F/A) :-
4878 Cond = (chr_pp_not_in_store(H);Cond1),
4879 missing_partner_cond(Hs,NHs,IDs,ID_o1,Cond1,H2,F/A).
4881 extract_explicit_matchings((A,B),D) :- !,
4882 ( extract_explicit_matchings(A) ->
4883 extract_explicit_matchings(B,D)
4886 extract_explicit_matchings(B,E)
4888 extract_explicit_matchings(A,D) :- !,
4889 ( extract_explicit_matchings(A) ->
4895 extract_explicit_matchings(A=B) :-
4896 var(A), var(B), !, A=B.
4897 extract_explicit_matchings(A==B) :-
4898 var(A), var(B), !, A=B.
4900 safely_unifiable(H,I) :- var(H), !.
4901 safely_unifiable([],[]) :- !.
4902 safely_unifiable([H|Hs],[I|Is]) :- !,
4903 safely_unifiable(H,I),
4904 safely_unifiable(Hs,Is).
4905 safely_unifiable(H,I) :-
4910 safely_unifiable(HA,IA).
4914 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4916 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4922 get_type_definition/2,
4923 get_constraint_type/2.
4926 :- chr_option(mode,type_definition(?,?)).
4927 :- chr_option(mode,get_type_definition(?,?)).
4928 :- chr_option(mode,type_alias(?,?)).
4929 :- chr_option(mode,constraint_type(+,+)).
4930 :- chr_option(mode,get_constraint_type(+,-)).
4932 assert_constraint_type(Constraint,ArgTypes) :-
4933 ( ground(ArgTypes) ->
4934 constraint_type(Constraint,ArgTypes)
4936 chr_error(type_error,'Declared argument types "~w" for constraint "~w" must be ground!\n',[ArgTypes,Constraint])
4939 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4940 % Consistency checks of type aliases
4942 type_alias(T,T2) <=>
4943 nonvar(T),nonvar(T2),functor(T,F,A),functor(T2,F,A),
4944 copy_term((T,T2),(X,Y)),oneway_unification(Y,X) |
4945 chr_error(type_error,'Cyclic alias definition: "~w".\n',[(T == T2)]).
4947 type_alias(T1,A1), type_alias(T2,A2) <=>
4948 nonvar(T1),nonvar(T2),functor(T1,F,A),functor(T2,F,A),
4950 copy_term_nat(T1,T1_),
4951 copy_term_nat(T2,T2_),
4953 chr_error(type_error,
4954 '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_]).
4956 type_alias(T,B) \ type_alias(X,T2) <=>
4957 nonvar(T),nonvar(T2),functor(T,F,A),functor(T2,F,A),
4958 copy_term_nat((X,T2,T,B),(X2,T3,T1,D1)),oneway_unification(T3,T1) |
4959 % chr_info(type_information,'Inferring `~w\' from `~w\' and `~w\'.\n',[X2==D1,X==T2,T==B]),
4962 oneway_unification(X,Y) :-
4963 term_variables(X,XVars),
4964 chr_runtime:lockv(XVars),
4966 chr_runtime:unlockv(XVars).
4968 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4969 % Consistency checks of type definitions
4971 type_definition(T1,_), type_definition(T2,_)
4973 functor(T1,F,A), functor(T2,F,A)
4975 chr_error(type_error,'Multiple definitions for type: ~w/~w.\n',[F,A]).
4977 type_definition(T1,_), type_alias(T2,_)
4979 functor(T1,F,A), functor(T2,F,A)
4981 chr_error(type_error,'Multiple definitions for type, once in a type definition and once as a type alias: ~w/~w.\n',[F,A]).
4983 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4984 %% get_type_definition(+Type,-Definition) is semidet.
4985 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4987 get_type_definition(T,Def)
4991 chr_error(type_error,'Non-ground type in constraint definition: "~w".\n',[T]).
4993 type_alias(T,D) \ get_type_definition(T2,Def)
4995 nonvar(T),nonvar(T2),functor(T,F,A),functor(T2,F,A),
4996 copy_term_nat((T,D),(T1,D1)),T1=T2
4998 ( get_type_definition(D1,Def) ->
5001 chr_error(type_error,'Could not find type definition for "~w" (accessed via alias "~w").\n',[D1,T1]), fail
5004 type_definition(T,D) \ get_type_definition(T2,Def)
5006 nonvar(T),nonvar(T2),functor(T,F,A),functor(T2,F,A),
5007 copy_term_nat((T,D),(T1,D1)),T1=T2
5011 get_type_definition(Type,Def)
5013 atomic_builtin_type(Type,_,_)
5017 get_type_definition(Type,Def)
5019 compound_builtin_type(Type,_,_)
5023 get_type_definition(X,Y) <=> fail.
5025 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5026 %% get_type_definition_det(+Type,-Definition) is det.
5027 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5028 get_type_definition_det(Type,Definition) :-
5029 ( get_type_definition(Type,Definition) ->
5032 chr_error(type,'Could not find type definition for type `~w\'.\n',[Type])
5035 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5036 %% get_constraint_type(+ConstraintSymbol,-Types) is semidet.
5038 % Return argument types of =ConstraintSymbol=, but fails if none where
5040 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5041 constraint_type(C,T) \ get_constraint_type(C,Type) <=> Type = T.
5042 get_constraint_type(_,_) <=> fail.
5044 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5045 %% get_constraint_type_det(+ConstraintSymbol,-Types) is det.
5047 % Like =get_constraint_type/2=, but returns list of =any= types when
5048 % no types are declared.
5049 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5050 get_constraint_type_det(ConstraintSymbol,Types) :-
5051 ( get_constraint_type(ConstraintSymbol,Types) ->
5054 ConstraintSymbol = _ / N,
5055 replicate(N,any,Types)
5057 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5058 %% unalias_type(+Alias,-Type) is det.
5060 % Follows alias chain until base type is reached.
5061 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5062 :- chr_constraint unalias_type/2.
5065 unalias_type(Alias,BaseType)
5072 type_alias(AliasProtoType,ProtoType) \ unalias_type(Alias,BaseType)
5074 nonvar(AliasProtoType),
5076 functor(AliasProtoType,F,A),
5078 copy_term_nat((AliasProtoType,ProtoType),(AliasInstance,Type)),
5079 Alias = AliasInstance
5081 unalias_type(Type,BaseType).
5083 unalias_type_definition @
5084 type_definition(ProtoType,Definition) \ unalias_type(Alias,BaseType)
5088 functor(ProtoType,F,A),
5093 unalias_atomic_builtin @
5094 unalias_type(Alias,BaseType)
5096 atomic_builtin_type(Alias,_,_)
5100 unalias_compound_builtin @
5101 unalias_type(Alias,BaseType)
5103 compound_builtin_type(Alias,_,_)
5107 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5108 %% types_modes_condition(+Heads,+UnrollHeads,-Condition) is det.
5109 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5110 :- chr_constraint types_modes_condition/3.
5111 :- chr_option(mode,types_modes_condition(+,+,?)).
5112 :- chr_option(type_declaration,types_modes_condition(list,list,goal)).
5114 types_modes_condition([],[],T) <=> T=true.
5116 constraint_mode(F/A,Modes) \ types_modes_condition([Head|Heads],[UnrollHead|UnrollHeads],Condition)
5121 Condition = (ModesCondition, TypesCondition, RestCondition),
5122 modes_condition(Modes,Args,ModesCondition),
5123 get_constraint_type_det(F/A,Types),
5124 UnrollHead =.. [_|RealArgs],
5125 types_condition(Types,Args,RealArgs,Modes,TypesCondition),
5126 types_modes_condition(Heads,UnrollHeads,RestCondition).
5128 types_modes_condition([Head|_],_,_)
5131 chr_error(internal,'Mode information missing for ~w.\n',[F/A]).
5134 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5135 %% modes_condition(+Modes,+Args,-Condition) is det.
5137 % Return =Condition= on =Args= that checks =Modes=.
5138 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5139 modes_condition([],[],true).
5140 modes_condition([Mode|Modes],[Arg|Args],Condition) :-
5142 Condition = ( ground(Arg) , RCondition )
5144 Condition = ( var(Arg) , RCondition )
5146 Condition = RCondition
5148 modes_condition(Modes,Args,RCondition).
5150 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5151 %% types_condition(+Types,+Args,+UnrollArgs,+Modes,-Condition) is det.
5153 % Return =Condition= on =Args= that checks =Types= given =Modes=.
5154 % =UnrollArgs= controls the depth of type definition unrolling.
5155 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5156 types_condition([],[],[],[],true).
5157 types_condition([Type|Types],[Arg|Args],[UnrollArg|UnrollArgs],[Mode|Modes],(DisjTypeConditionList,RCondition)) :-
5159 TypeConditionList = [true] % TypeConditionList = [var(Arg)] already encoded in modes_condition
5161 get_type_definition_det(Type,Def),
5162 type_condition(Def,Arg,UnrollArg,Mode,TypeConditionList1),
5164 TypeConditionList = TypeConditionList1
5166 TypeConditionList = [(\+ ground(Arg))|TypeConditionList1]
5169 list2disj(TypeConditionList,DisjTypeConditionList),
5170 types_condition(Types,Args,UnrollArgs,Modes,RCondition).
5172 type_condition([],_,_,_,[]).
5173 type_condition([DefCase|DefCases],Arg,UnrollArg,Mode,[Condition|Conditions]) :-
5175 chr_error(type,'Unexpected variable type in type definition!\n',[]) % Condition = true
5176 ; atomic_builtin_type(DefCase,Arg,Condition) ->
5178 ; compound_builtin_type(DefCase,Arg,Condition) ->
5181 type_def_case_condition(DefCase,Arg,UnrollArg,Mode,Condition)
5183 type_condition(DefCases,Arg,UnrollArg,Mode,Conditions).
5185 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5186 :- chr_type atomic_builtin_type ---> any
5193 ; chr_identifier(any).
5194 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5196 atomic_builtin_type(any,_Arg,true).
5197 atomic_builtin_type(dense_int,Arg,(integer(Arg),Arg>=0)).
5198 atomic_builtin_type(int,Arg,integer(Arg)).
5199 atomic_builtin_type(number,Arg,number(Arg)).
5200 atomic_builtin_type(float,Arg,float(Arg)).
5201 atomic_builtin_type(natural,Arg,(integer(Arg),Arg>=0)).
5202 atomic_builtin_type(chr_identifier,_Arg,true).
5204 compound_builtin_type(chr_identifier(_),_Arg,true).
5206 type_def_case_condition(DefCase,Arg,UnrollArg,Mode,Condition) :-
5207 ( nonvar(DefCase) ->
5208 functor(DefCase,F,A),
5210 Condition = (Arg = DefCase)
5212 Condition = functor(Arg,F,A)
5213 ; functor(UnrollArg,F,A) ->
5214 Condition = (functor(Arg,F,A),Arg=Template,ArgsCondition),
5215 DefCase =.. [_|ArgTypes],
5216 UnrollArg =.. [_|UnrollArgs],
5217 functor(Template,F,A),
5218 Template =.. [_|TemplateArgs],
5219 replicate(A,Mode,ArgModes),
5220 types_condition(ArgTypes,TemplateArgs,UnrollArgs,ArgModes,ArgsCondition)
5222 Condition = functor(Arg,F,A)
5225 chr_error(internal,'Illegal type definition (must be nonvar).\n',[])
5229 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5230 % STATIC TYPE CHECKING
5231 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5232 % Checks head constraints and CHR constraint calls in bodies.
5235 % - type clashes involving built-in types
5236 % - Prolog built-ins in guard and body
5237 % - indicate position in terms in error messages
5238 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5240 static_type_check/0.
5243 % 1. Check the declared types
5245 constraint_type(Constraint,ArgTypes), static_type_check
5248 ( member(ArgType,ArgTypes), forsubterm(ArgType,Type) ),
5249 ( get_type_definition(Type,_) ->
5252 chr_error(type_error,'Undefined type "~w" used in type declaration of "~w".\n',[Type,Constraint])
5257 forsubterm(Term,SubTerm) :-
5263 forsubterm(Arg,SubTerm)
5267 % 2. Check the rules
5269 :- chr_type type_error_src ---> head(any) ; body(any).
5271 rule(_,Rule), static_type_check
5273 copy_term_nat(Rule,RuleCopy),
5274 RuleCopy = pragma(rule(Head1,Head2,G,Body),ids(IDs1,IDs2),Pragmas,Name,RuleNb),
5277 ( static_type_check_heads(Head1),
5278 static_type_check_heads(Head2),
5279 conj2list(Body,GoalList),
5280 static_type_check_body(GoalList)
5283 ( Error = invalid_functor(Src,Term,Type) ->
5284 chr_error(type_error,'Invalid functor in ~@ of ~@:\n\t\tfound `~w\',\n\t\texpected type `~w\'!\n',
5285 [chr_translate:format_src(Src),format_rule(Rule),Term,Type])
5286 ; Error = type_clash(Var,Src1,Src2,Type1,Type2) ->
5287 chr_error(type_error,'Type clash for variable ~w in ~@:\n\t\texpected type ~w in ~@\n\t\texpected type ~w in ~@\n',
5288 [Var,format_rule(Rule),Type1,chr_translate:format_src(Src1),Type2,chr_translate:format_src(Src2)])
5291 fail % cleanup constraints
5297 static_type_check <=> true.
5299 static_type_check_heads([]).
5300 static_type_check_heads([Head|Heads]) :-
5301 static_type_check_head(Head),
5302 static_type_check_heads(Heads).
5304 static_type_check_head(Head) :-
5306 get_constraint_type_det(F/A,Types),
5308 maplist(static_type_check_term(head(Head)),Args,Types).
5310 static_type_check_body([]).
5311 static_type_check_body([Goal|Goals]) :-
5313 get_constraint_type_det(F/A,Types),
5315 maplist(static_type_check_term(body(Goal)),Args,Types),
5316 static_type_check_body(Goals).
5318 :- chr_constraint static_type_check_term/3.
5319 :- chr_option(mode,static_type_check_term(?,?,?)).
5320 :- chr_option(type_declaration,static_type_check_term(type_error_src,any,any)).
5322 static_type_check_term(Src,Term,Type)
5326 static_type_check_var(Src,Term,Type).
5327 static_type_check_term(Src,Term,Type)
5329 atomic_builtin_type(Type,Term,Goal)
5334 throw(type_error(invalid_functor(Src,Term,Type)))
5336 static_type_check_term(Src,Term,Type)
5338 compound_builtin_type(Type,Term,Goal)
5343 throw(type_error(invalid_functor(Src,Term,Type)))
5345 type_alias(AType,ADef) \ static_type_check_term(Src,Term,Type)
5350 copy_term_nat(AType-ADef,Type-Def),
5351 static_type_check_term(Src,Term,Def).
5353 type_definition(AType,ADef) \ static_type_check_term(Src,Term,Type)
5358 copy_term_nat(AType-ADef,Type-Variants),
5359 functor(Term,TF,TA),
5360 ( member(Variant,Variants), functor(Variant,TF,TA) ->
5362 Variant =.. [_|Types],
5363 maplist(static_type_check_term(Src),Args,Types)
5365 throw(type_error(invalid_functor(Src,Term,Type)))
5368 static_type_check_term(Src,Term,Type)
5370 chr_error(internal,'Undefined type ~w while type checking term ~w in ~@.\n',[Type,Term,chr_translate:format_src(Src)]).
5372 :- chr_constraint static_type_check_var/3.
5373 :- chr_option(mode,static_type_check_var(?,-,?)).
5374 :- chr_option(type_declaration,static_type_check_term(type_error_src,any,any)).
5376 type_alias(AType,ADef) \ static_type_check_var(Src,Var,Type)
5381 copy_term_nat(AType-ADef,Type-Def),
5382 static_type_check_var(Src,Var,Def).
5384 static_type_check_var(Src,Var,Type)
5386 atomic_builtin_type(Type,_,_)
5388 static_atomic_builtin_type_check_var(Src,Var,Type).
5390 static_type_check_var(Src,Var,Type)
5392 compound_builtin_type(Type,_,_)
5397 static_type_check_var(Src1,Var,Type1), static_type_check_var(Src2,Var,Type2)
5401 throw(type_error(type_clash(Var,Src1,Src2,Type1,Type2))).
5403 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5404 %% static_atomic_builtin_type_check_var(+type_error_src,-Var,+atomic_builtin_type)
5405 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5406 :- chr_constraint static_atomic_builtin_type_check_var/3.
5407 :- chr_option(mode,static_type_check_var(?,-,+)).
5408 :- chr_option(type_declaration,static_type_check_term(type_error_src,any,atomic_builtin_type)).
5410 static_atomic_builtin_type_check_var(_,_,any) <=> true.
5411 static_atomic_builtin_type_check_var(_,Var,BuiltinType) \ static_atomic_builtin_type_check_var(_,Var,BuiltinType)
5414 static_atomic_builtin_type_check_var(_,Var,float) \ static_atomic_builtin_type_check_var(_,Var,number)
5417 static_atomic_builtin_type_check_var(_,Var,int) \ static_atomic_builtin_type_check_var(_,Var,number)
5420 static_atomic_builtin_type_check_var(_,Var,natural) \ static_atomic_builtin_type_check_var(_,Var,number)
5423 static_atomic_builtin_type_check_var(_,Var,dense_int) \ static_atomic_builtin_type_check_var(_,Var,number)
5426 static_atomic_builtin_type_check_var(_,Var,natural) \ static_atomic_builtin_type_check_var(_,Var,int)
5429 static_atomic_builtin_type_check_var(_,Var,dense_int) \ static_atomic_builtin_type_check_var(_,Var,int)
5432 static_atomic_builtin_type_check_var(_,Var,dense_int) \ static_atomic_builtin_type_check_var(_,Var,natural)
5435 static_atomic_builtin_type_check_var(Src1,Var,Type1), static_atomic_builtin_type_check_var(Src2,Var,Type2)
5437 throw(type_error(type_clash(Var,Src1,Src2,Type1,Type2))).
5439 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5440 %% format_src(+type_error_src) is det.
5441 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5442 format_src(head(Head)) :- format('head ~w',[Head]).
5443 format_src(body(Goal)) :- format('body goal ~w',[Goal]).
5445 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5446 % Dynamic type checking
5447 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5450 dynamic_type_check/0,
5451 dynamic_type_check_clauses/1,
5452 get_dynamic_type_check_clauses/1.
5454 generate_dynamic_type_check_clauses(Clauses) :-
5455 ( chr_pp_flag(debugable,on) ->
5457 get_dynamic_type_check_clauses(Clauses0),
5459 [('$dynamic_type_check'(Type,Term) :-
5460 throw(error(type_error(Type,Term),context(_,'CHR Runtime Type Error')))
5467 type_definition(T,D), dynamic_type_check
5469 copy_term_nat(T-D,Type-Definition),
5470 maplist(dynamic_type_check_clause(Type),Definition,DynamicChecks),
5471 dynamic_type_check_clauses(DynamicChecks).
5472 type_alias(A,B), dynamic_type_check
5474 copy_term_nat(A-B,Alias-Body),
5475 dynamic_type_check_alias_clause(Alias,Body,Clause),
5476 dynamic_type_check_clauses([Clause]).
5478 dynamic_type_check <=>
5480 ('$dynamic_type_check'(Type,Term) :- Goal),
5481 ( atomic_builtin_type(Type,Term,Goal) ; compound_builtin_type(Type,Term,Goal) ),
5484 dynamic_type_check_clauses(BuiltinChecks).
5486 dynamic_type_check_clause(T,DC,Clause) :-
5487 copy_term(T-DC,Type-DefinitionClause),
5488 functor(DefinitionClause,F,A),
5490 DefinitionClause =.. [_|DCArgs],
5491 Term =.. [_|TermArgs],
5492 maplist(dynamic_type_check_call,DCArgs,TermArgs,RecursiveCallList),
5493 list2conj(RecursiveCallList,RecursiveCalls),
5495 '$dynamic_type_check'(Type,Term) :-
5499 dynamic_type_check_alias_clause(Alias,Body,Clause) :-
5501 '$dynamic_type_check'(Alias,Term) :-
5502 '$dynamic_type_check'(Body,Term)
5505 dynamic_type_check_call(Type,Term,Call) :-
5506 % ( nonvar(Type), atomic_builtin_type(Type,Term,Goal) ->
5507 % Call = when(nonvar(Term),Goal)
5508 % ; nonvar(Type), compound_builtin_type(Type,Term,Goal) ->
5509 % Call = when(nonvar(Term),Goal)
5514 Call = when(nonvar(Term),once('$dynamic_type_check'(Type,Term)))
5519 dynamic_type_check_clauses(C1), dynamic_type_check_clauses(C2)
5522 dynamic_type_check_clauses(C).
5524 get_dynamic_type_check_clauses(Q), dynamic_type_check_clauses(C)
5527 get_dynamic_type_check_clauses(Q)
5531 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5533 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5534 % Some optimizations can be applied for atomic types...
5535 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5537 atomic_types_suspended_constraint(C) :-
5539 get_constraint_type(C,ArgTypes),
5540 get_constraint_mode(C,ArgModes),
5541 findall(I,between(1,N,I),Indexes),
5542 maplist(atomic_types_suspended_constraint(C),ArgTypes,ArgModes,Indexes).
5544 atomic_types_suspended_constraint(C,Type,Mode,Index) :-
5545 ( is_indexed_argument(C,Index) ->
5555 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5556 %% atomic_type(+Type) is semidet.
5558 % Succeeds when all values of =Type= are atomic.
5559 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5560 :- chr_constraint atomic_type/1.
5562 atomic_type(Type) <=> atomic_builtin_type(Type,_,_) | Type \== any.
5564 type_definition(TypePat,Def) \ atomic_type(Type)
5566 functor(Type,F,A), functor(TypePat,F,A)
5568 forall(member(Term,Def),atomic(Term)).
5570 type_alias(TypePat,Alias) \ atomic_type(Type)
5572 functor(Type,F,A), functor(TypePat,F,A)
5575 copy_term_nat(TypePat-Alias,Type-NType),
5578 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5579 %% enumerated_atomic_type(+Type,-Atoms) is semidet.
5581 % Succeeds when all values of =Type= are atomic
5582 % and the atom values are finitely enumerable.
5583 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5584 :- chr_constraint enumerated_atomic_type/2.
5586 enumerated_atomic_type(Type,_) <=> atomic_builtin_type(Type,_,_) | fail.
5588 type_definition(TypePat,Def) \ enumerated_atomic_type(Type,Atoms)
5590 functor(Type,F,A), functor(TypePat,F,A)
5592 forall(member(Term,Def),atomic(Term)),
5595 type_alias(TypePat,Alias) \ enumerated_atomic_type(Type,Atoms)
5597 functor(Type,F,A), functor(TypePat,F,A)
5600 copy_term_nat(TypePat-Alias,Type-NType),
5601 enumerated_atomic_type(NType,Atoms).
5602 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5605 stored/3, % constraint,occurrence,(yes/no/maybe)
5606 stored_completing/3,
5609 is_finally_stored/1,
5610 check_all_passive/2.
5612 :- chr_option(mode,stored(+,+,+)).
5613 :- chr_option(type_declaration,stored(any,int,storedinfo)).
5614 :- chr_type storedinfo ---> yes ; no ; maybe.
5615 :- chr_option(mode,stored_complete(+,+,+)).
5616 :- chr_option(mode,maybe_complementary_guards(+,+,?,?)).
5617 :- chr_option(mode,guard_list(+,+,+,+)).
5618 :- chr_option(mode,check_all_passive(+,+)).
5619 :- chr_option(type_declaration,check_all_passive(any,list)).
5621 % change yes in maybe when yes becomes passive
5622 passive(RuleNb,ID), occurrence(C,O,RuleNb,ID,_) \
5623 stored(C,O,yes), stored_complete(C,RO,Yesses)
5624 <=> O < RO | NYesses is Yesses - 1,
5625 stored(C,O,maybe), stored_complete(C,RO,NYesses).
5626 % change yes in maybe when not observed
5627 ai_not_observed(C,O) \ stored(C,O,yes), stored_complete(C,RO,Yesses)
5629 NYesses is Yesses - 1,
5630 stored(C,O,maybe), stored_complete(C,RO,NYesses).
5632 occurrence(_,_,RuleNb,ID,_), occurrence(C2,_,RuleNb,_,_), stored_complete(C2,RO,0), max_occurrence(C2,MO2)
5633 ==> RO =< MO2 | % C2 is never stored
5639 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5641 rule(RuleNb,Rule),passive(RuleNb,Id) ==>
5642 Rule = pragma(rule(Head1,Head2,G,B),ids([Id|IDs1],IDs2),Pragmas,Name,RuleNb) |
5643 append(IDs1,IDs2,I), check_all_passive(RuleNb,I).
5645 rule(RuleNb,Rule),passive(RuleNb,Id) ==>
5646 Rule = pragma(rule(Head1,Head2,G,B),ids([],[Id|IDs2]),Pragmas,Name,RuleNb) |
5647 check_all_passive(RuleNb,IDs2).
5649 passive(RuleNb,Id) \ check_all_passive(RuleNb,[Id|IDs]) <=>
5650 check_all_passive(RuleNb,IDs).
5652 rule(RuleNb,Rule) \ check_all_passive(RuleNb,[]) <=>
5653 chr_warning(weird_program,'All heads passive in ~@.\n\tThis rule never fires. Please check your program.\n',[format_rule(Rule)]).
5655 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5657 % collect the storage information
5658 stored(C,O,yes) \ stored_completing(C,O,Yesses)
5659 <=> NO is O + 1, NYesses is Yesses + 1,
5660 stored_completing(C,NO,NYesses).
5661 stored(C,O,maybe) \ stored_completing(C,O,Yesses)
5663 stored_completing(C,NO,Yesses).
5665 stored(C,O,no) \ stored_completing(C,O,Yesses)
5666 <=> stored_complete(C,O,Yesses).
5667 stored_completing(C,O,Yesses)
5668 <=> stored_complete(C,O,Yesses).
5670 stored_complete(C,O,Yesses), occurrence(C,O2,RuleNb,Id,_) ==>
5671 O2 > O | passive(RuleNb,Id).
5673 % decide whether a constraint is stored
5674 max_occurrence(C,MO), stored_complete(C,RO,0) \ is_stored(C)
5675 <=> RO =< MO | fail.
5676 is_stored(C) <=> true.
5678 % decide whether a constraint is suspends after occurrences
5679 max_occurrence(C,MO), stored_complete(C,RO,_) \ is_finally_stored(C)
5680 <=> RO =< MO | fail.
5681 is_finally_stored(C) <=> true.
5683 storage_analysis(Constraints) :-
5684 ( chr_pp_flag(storage_analysis,on) ->
5685 check_constraint_storages(Constraints)
5690 check_constraint_storages([]).
5691 check_constraint_storages([C|Cs]) :-
5692 check_constraint_storage(C),
5693 check_constraint_storages(Cs).
5695 check_constraint_storage(C) :-
5696 get_max_occurrence(C,MO),
5697 check_occurrences_storage(C,1,MO).
5699 check_occurrences_storage(C,O,MO) :-
5701 stored_completing(C,1,0)
5703 check_occurrence_storage(C,O),
5705 check_occurrences_storage(C,NO,MO)
5708 check_occurrence_storage(C,O) :-
5709 get_occurrence(C,O,RuleNb,ID),
5710 ( is_passive(RuleNb,ID) ->
5713 get_rule(RuleNb,PragmaRule),
5714 PragmaRule = pragma(rule(Heads1,Heads2,Guard,Body),ids(IDs1,IDs2),_,_,_),
5715 ( select2(ID,Head1,IDs1,Heads1,RIDs1,RHeads1) ->
5716 check_storage_head1(Head1,O,Heads1,Heads2,Guard)
5717 ; select2(ID,Head2,IDs2,Heads2,RIDs2,RHeads2) ->
5718 check_storage_head2(Head2,O,Heads1,Body)
5722 check_storage_head1(Head,O,H1,H2,G) :-
5727 % writeq(guard_entailment:entails_guard([chr_pp_headvariables(Head)],G)),nl,
5728 guard_entailment:entails_guard([chr_pp_headvariables(Head)],G),
5730 no_matching(L,[]) ->
5737 no_matching([X|Xs],Prev) :-
5739 \+ memberchk_eq(X,Prev),
5740 no_matching(Xs,[X|Prev]).
5742 check_storage_head2(Head,O,H1,B) :-
5746 ( H1 \== [], B == true )
5748 % \+ is_observed(F/A,O) % always fails because observation analysis has not been performed yet
5756 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5758 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5759 %% ____ _ ____ _ _ _ _
5760 %% | _ \ _ _| | ___ / ___|___ _ __ ___ _ __ (_) | __ _| |_(_) ___ _ __
5761 %% | |_) | | | | |/ _ \ | | / _ \| '_ ` _ \| '_ \| | |/ _` | __| |/ _ \| '_ \
5762 %% | _ <| |_| | | __/ | |__| (_) | | | | | | |_) | | | (_| | |_| | (_) | | | |
5763 %% |_| \_\\__,_|_|\___| \____\___/|_| |_| |_| .__/|_|_|\__,_|\__|_|\___/|_| |_|
5766 constraints_code(Constraints,Clauses) :-
5767 (chr_pp_flag(reduced_indexing,on),
5768 \+ forsome(C,Constraints,\+ chr_translate:only_ground_indexed_arguments(C)) ->
5769 none_suspended_on_variables
5773 constraints_code1(Constraints,Clauses,[]).
5775 %===============================================================================
5776 :- chr_constraint constraints_code1/3.
5777 :- chr_option(mode,constraints_code1(+,+,+)).
5778 :- chr_option(type_declaration,constraints_code1(list,any,any)).
5779 %-------------------------------------------------------------------------------
5780 constraints_code1([],L,T) <=> L = T.
5781 constraints_code1([C|RCs],L,T)
5783 constraint_code(C,L,T1),
5784 constraints_code1(RCs,T1,T).
5785 %===============================================================================
5786 :- chr_constraint constraint_code/3.
5787 :- chr_option(mode,constraint_code(+,+,+)).
5788 %-------------------------------------------------------------------------------
5789 %% Generate code for a single CHR constraint
5790 constraint_code(Constraint, L, T)
5792 | ( (chr_pp_flag(debugable,on) ;
5793 is_stored(Constraint), ( has_active_occurrence(Constraint); chr_pp_flag(late_allocation,off)),
5794 ( may_trigger(Constraint) ;
5795 get_allocation_occurrence(Constraint,AO),
5796 get_max_occurrence(Constraint,MO), MO >= AO ) )
5798 constraint_prelude(Constraint,Clause),
5799 add_dummy_location(Clause,LocatedClause),
5800 L = [LocatedClause | L1]
5805 occurrences_code(Constraint,1,Id,NId,L1,L2),
5806 gen_cond_attach_clause(Constraint,NId,L2,T).
5808 %===============================================================================
5809 %% Generate prelude predicate for a constraint.
5810 %% f(...) :- f/a_0(...,Susp).
5811 constraint_prelude(F/A, Clause) :-
5812 vars_susp(A,Vars,Susp,VarsSusp),
5813 Head =.. [ F | Vars],
5814 make_suspension_continuation_goal(F/A,VarsSusp,Continuation),
5815 build_head(F,A,[0],VarsSusp,Delegate),
5816 ( chr_pp_flag(debugable,on) ->
5817 insert_constraint_goal(F/A,Susp,Vars,InsertCall),
5818 attach_constraint_atom(F/A,Vars2,Susp,AttachCall),
5819 delay_phase_end(validate_store_type_assumptions,chr_translate:update_suspension_field(F/A,Susp,state,inactive,Inactive)),
5820 insert_constraint_internal_constraint_goal(F/A, Vars2, Susp, Continuation, Vars,InsertGoal),
5822 ( get_constraint_type(F/A,ArgTypeList) ->
5823 maplist(dynamic_type_check_call,ArgTypeList,Vars,DynamicTypeCheckList),
5824 list2conj(DynamicTypeCheckList,DynamicTypeChecks)
5826 DynamicTypeChecks = true
5836 'chr debug_event'(insert(Head#Susp)),
5838 'chr debug_event'(call(Susp)),
5841 'chr debug_event'(fail(Susp)), !,
5845 'chr debug_event'(exit(Susp))
5847 'chr debug_event'(redo(Susp)),
5851 ; get_allocation_occurrence(F/A,0) ->
5852 gen_insert_constraint_internal_goal(F/A,Goal,VarsSusp,Vars,Susp),
5853 delay_phase_end(validate_store_type_assumptions,chr_translate:update_suspension_field(F/A,Susp,state,inactive,Inactive)),
5854 Clause = ( Head :- Goal, Inactive, Delegate )
5856 Clause = ( Head :- Delegate )
5859 make_suspension_continuation_goal(F/A,VarsSusp,Goal) :-
5860 ( may_trigger(F/A) ->
5861 build_head(F,A,[0],VarsSusp,Delegate),
5862 ( chr_pp_flag(debugable,off) ->
5865 get_target_module(Mod),
5872 %===============================================================================
5873 :- chr_constraint has_active_occurrence/1, has_active_occurrence/2.
5874 :- chr_option(mode,has_active_occurrence(+)).
5875 :- chr_option(mode,has_active_occurrence(+,+)).
5876 %-------------------------------------------------------------------------------
5877 has_active_occurrence(C) <=> has_active_occurrence(C,1).
5879 max_occurrence(C,MO) \ has_active_occurrence(C,O) <=>
5881 passive(RuleNb,ID),occurrence(C,O,RuleNb,ID,_) \
5882 has_active_occurrence(C,O) <=>
5884 has_active_occurrence(C,NO).
5885 has_active_occurrence(C,O) <=> true.
5886 %===============================================================================
5888 gen_cond_attach_clause(F/A,Id,L,T) :-
5889 ( is_finally_stored(F/A) ->
5890 get_allocation_occurrence(F/A,AllocationOccurrence),
5891 get_max_occurrence(F/A,MaxOccurrence),
5892 ( chr_pp_flag(debugable,off), MaxOccurrence < AllocationOccurrence ->
5893 ( only_ground_indexed_arguments(F/A) ->
5894 gen_insert_constraint_internal_goal(F/A,Body,AllArgs,Args,Susp)
5896 gen_cond_attach_goal(F/A,Body,AllArgs,Args,Susp)
5898 ; vars_susp(A,Args,Susp,AllArgs),
5899 gen_uncond_attach_goal(F/A,Susp,Args,Body,_)
5901 build_head(F,A,Id,AllArgs,Head),
5902 Clause = ( Head :- Body ),
5903 add_dummy_location(Clause,LocatedClause),
5904 L = [LocatedClause | T]
5909 :- chr_constraint use_auxiliary_predicate/1.
5910 :- chr_option(mode,use_auxiliary_predicate(+)).
5912 :- chr_constraint use_auxiliary_predicate/2.
5913 :- chr_option(mode,use_auxiliary_predicate(+,+)).
5915 :- chr_constraint is_used_auxiliary_predicate/1.
5916 :- chr_option(mode,is_used_auxiliary_predicate(+)).
5918 :- chr_constraint is_used_auxiliary_predicate/2.
5919 :- chr_option(mode,is_used_auxiliary_predicate(+,+)).
5922 use_auxiliary_predicate(P) \ use_auxiliary_predicate(P) <=> true.
5924 use_auxiliary_predicate(P,C) \ use_auxiliary_predicate(P,C) <=> true.
5926 use_auxiliary_predicate(P) \ is_used_auxiliary_predicate(P) <=> true.
5928 use_auxiliary_predicate(P,_) \ is_used_auxiliary_predicate(P) <=> true.
5930 is_used_auxiliary_predicate(P) <=> fail.
5932 use_auxiliary_predicate(P) \ is_used_auxiliary_predicate(P,_) <=> true.
5933 use_auxiliary_predicate(P,C) \ is_used_auxiliary_predicate(P,C) <=> true.
5935 is_used_auxiliary_predicate(P,C) <=> fail.
5937 %------------------------------------------------------------------------------%
5938 % Only generate import statements for actually used modules.
5939 %------------------------------------------------------------------------------%
5941 :- chr_constraint use_auxiliary_module/1.
5942 :- chr_option(mode,use_auxiliary_module(+)).
5944 :- chr_constraint is_used_auxiliary_module/1.
5945 :- chr_option(mode,is_used_auxiliary_module(+)).
5948 use_auxiliary_module(P) \ use_auxiliary_module(P) <=> true.
5950 use_auxiliary_module(P) \ is_used_auxiliary_module(P) <=> true.
5952 is_used_auxiliary_module(P) <=> fail.
5954 % only called for constraints with
5956 % non-ground indexed argument
5957 gen_cond_attach_goal(F/A,Goal,AllArgs,Args,Susp) :-
5958 vars_susp(A,Args,Susp,AllArgs),
5959 make_suspension_continuation_goal(F/A,AllArgs,Closure),
5960 ( get_store_type(F/A,var_assoc_store(_,_)) ->
5963 attach_constraint_atom(F/A,Vars,Susp,Attach)
5966 insert_constraint_goal(F/A,Susp,Args,InsertCall),
5967 insert_constraint_internal_constraint_goal(F/A, Vars, Susp, Closure, Args,InsertGoal),
5968 ( may_trigger(F/A) ->
5969 activate_constraint_goal(F/A,(InsertCall,Attach),Vars,Susp,_,ActivateGoal),
5973 InsertGoal, % insert_constraint_internal(Stored,Vars,Susp,Closure,F,Args)
5977 ActivateGoal % activate_constraint(Stored,Vars,Susp,_)
5983 InsertGoal, % insert_constraint_internal(Stored,Vars,Susp,Closure,F,Args),
5989 gen_insert_constraint_internal_goal(F/A,Goal,AllArgs,Args,Susp) :-
5990 vars_susp(A,Args,Susp,AllArgs),
5991 make_suspension_continuation_goal(F/A,AllArgs,Cont),
5992 ( \+ only_ground_indexed_arguments(F/A), \+ get_store_type(F/A,var_assoc_store(_,_)) ->
5993 attach_constraint_atom(F/A,Vars,Susp,Attach)
5998 insert_constraint_goal(F/A,Susp,Args,InsertCall),
5999 insert_constraint_internal_constraint_goal(F/A, Vars, Susp, Cont, Args,InsertInternalGoal),
6000 ( only_ground_indexed_arguments(F/A), chr_pp_flag(debugable,off) ->
6003 InsertInternalGoal, % insert_constraint_internal(Susp,F,Args),
6009 InsertInternalGoal, % insert_constraint_internal(_,Vars,Susp,Cont,F,Args),
6015 gen_uncond_attach_goal(FA,Susp,Args,AttachGoal,Generation) :-
6016 ( \+ only_ground_indexed_arguments(FA), \+ get_store_type(FA,var_assoc_store(_,_)) ->
6017 attach_constraint_atom(FA,Vars,Susp,Attach)
6021 insert_constraint_goal(FA,Susp,Args,InsertCall),
6022 ( chr_pp_flag(late_allocation,on) ->
6023 activate_constraint_goal(FA,(InsertCall,Attach),Vars,Susp,Generation,AttachGoal)
6025 activate_constraint_goal(FA,true,Vars,Susp,Generation,AttachGoal)
6028 %-------------------------------------------------------------------------------
6029 :- chr_constraint occurrences_code/6.
6030 :- chr_option(mode,occurrences_code(+,+,+,+,+,+)).
6031 %-------------------------------------------------------------------------------
6032 max_occurrence(C,MO) \ occurrences_code(C,O,Id,NId,L,T)
6035 occurrences_code(C,O,Id,NId,L,T)
6037 occurrence_code(C,O,Id,Id1,L,L1),
6039 occurrences_code(C,NO,Id1,NId,L1,T).
6040 %-------------------------------------------------------------------------------
6041 :- chr_constraint occurrence_code/6.
6042 :- chr_option(mode,occurrence_code(+,+,+,+,+,+)).
6043 %-------------------------------------------------------------------------------
6044 occurrence(C,O,RuleNb,ID,_), passive(RuleNb,ID) \ occurrence_code(C,O,Id,NId,L,T)
6046 ( named_history(RuleNb,_,_) ->
6047 does_use_history(C,O)
6053 occurrence(C,O,RuleNb,ID,_), rule(RuleNb,PragmaRule) \ occurrence_code(C,O,Id,NId,L,T)
6055 PragmaRule = pragma(rule(Heads1,Heads2,_,_),ids(IDs1,IDs2),_,_,_),
6056 ( select2(ID,Head1,IDs1,Heads1,RIDs1,RHeads1) ->
6058 head1_code(Head1,ID,RHeads1,RIDs1,PragmaRule,C,O,Id,L,T)
6059 ; select2(ID,Head2,IDs2,Heads2,RIDs2,RHeads2) ->
6060 head2_code(Head2,ID,RHeads2,RIDs2,PragmaRule,C,O,Id,L,L1),
6062 ( unconditional_occurrence(C,O) ->
6065 gen_alloc_inc_clause(C,O,Id,L1,T)
6069 occurrence_code(C,O,_,_,_,_)
6071 chr_error(internal,'occurrence_code/6: missing information to compile ~w:~w\n',[C,O]).
6072 %-------------------------------------------------------------------------------
6074 %% Generate code based on one removed head of a CHR rule
6075 head1_code(Head,ID,OtherHeads,OtherIDs,PragmaRule,FA,O,Id,L,T) :-
6076 PragmaRule = pragma(Rule,_,_,_Name,RuleNb),
6077 Rule = rule(_,Head2,_,_),
6079 reorder_heads(RuleNb,Head,OtherHeads,OtherIDs,NOtherHeads,NOtherIDs),
6080 simplification_code(Head,ID,NOtherHeads,NOtherIDs,PragmaRule,FA,O,Id,L,T)
6082 simpagation_head1_code(Head,ID,OtherHeads,OtherIDs,PragmaRule,FA,O,Id,L,T)
6085 %% Generate code based on one persistent head of a CHR rule
6086 head2_code(Head,ID,OtherHeads,OtherIDs,PragmaRule,FA,O,Id,L,T) :-
6087 PragmaRule = pragma(Rule,_,_,_Name,RuleNb),
6088 Rule = rule(Head1,_,_,_),
6090 reorder_heads(RuleNb,Head,OtherHeads,OtherIDs,NOtherHeads,NOtherIDs),
6091 propagation_code(Head,ID,NOtherHeads,NOtherIDs,Rule,RuleNb,FA,O,Id,L,T)
6093 simpagation_head2_code(Head,ID,OtherHeads,OtherIDs,PragmaRule,FA,O,Id,L,T)
6096 gen_alloc_inc_clause(F/A,O,Id,L,T) :-
6097 vars_susp(A,Vars,Susp,VarsSusp),
6098 build_head(F,A,Id,VarsSusp,Head),
6100 build_head(F,A,IncId,VarsSusp,CallHead),
6101 gen_occ_allocation(F/A,O,Vars,Susp,ConditionalAlloc),
6108 add_dummy_location(Clause,LocatedClause),
6109 L = [LocatedClause|T].
6111 gen_occ_allocation(FA,O,Vars,Susp,Goal) :-
6112 get_allocation_occurrence(FA,AO),
6113 ( chr_pp_flag(debugable,off), O == AO ->
6114 allocate_constraint_goal(FA,Susp,Vars,Goal0),
6115 ( may_trigger(FA) ->
6116 Goal = (var(Susp) -> Goal0 ; true)
6124 gen_occ_allocation_in_guard(FA,O,Vars,Susp,Goal) :-
6125 get_allocation_occurrence(FA,AO),
6126 ( chr_pp_flag(debugable,off), O < AO ->
6127 allocate_constraint_goal(FA,Susp,Vars,Goal0),
6128 ( may_trigger(FA) ->
6129 Goal = (var(Susp) -> Goal0 ; true)
6137 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6139 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6141 % Reorders guard goals with respect to partner constraint retrieval goals and
6142 % active constraint. Returns combined partner retrieval + guard goal.
6144 guard_via_reschedule_new(Retrievals,GuardList,Prelude,GuardListSkeleton,LookupSkeleton,GoalSkeleton) :-
6145 ( chr_pp_flag(guard_via_reschedule,on) ->
6146 guard_via_reschedule_main_new(Retrievals,GuardList,Prelude,GuardListSkeleton,LookupSkeleton,ScheduleSkeleton),
6147 list2conj(ScheduleSkeleton,GoalSkeleton)
6149 length(Retrievals,RL), length(LookupSkeleton,RL),
6150 length(GuardList,GL), length(GuardListSkeleton,GL),
6151 append(LookupSkeleton,GuardListSkeleton,GoalListSkeleton),
6152 list2conj(GoalListSkeleton,GoalSkeleton)
6154 guard_via_reschedule_main_new(PartnerLookups,GuardList,ActiveHead,
6155 GuardListSkeleton,LookupSkeleton,ScheduleSkeleton) :-
6156 initialize_unit_dictionary(ActiveHead,Dict),
6157 maplist(wrap_in_functor(lookup),PartnerLookups,WrappedPartnerLookups),
6158 maplist(wrap_in_functor(guard),GuardList,WrappedGuardList),
6159 build_units(WrappedPartnerLookups,WrappedGuardList,Dict,Units),
6160 dependency_reorder(Units,NUnits),
6161 wrappedunits2lists(NUnits,IndexedGuardListSkeleton,LookupSkeleton,ScheduleSkeleton),
6162 sort(IndexedGuardListSkeleton,SortedIndexedGuardListSkeleton),
6163 snd_of_pairs(SortedIndexedGuardListSkeleton,GuardListSkeleton).
6165 wrap_in_functor(Functor,X,Term) :-
6166 Term =.. [Functor,X].
6168 wrappedunits2lists([],[],[],[]).
6169 wrappedunits2lists([unit(N,WrappedGoal,_,_)|Units],Gs,Ls,Ss) :-
6170 Ss = [GoalCopy|TSs],
6171 ( WrappedGoal = lookup(Goal) ->
6172 Ls = [GoalCopy|TLs],
6174 ; WrappedGoal = guard(Goal) ->
6175 Gs = [N-GoalCopy|TGs],
6178 wrappedunits2lists(Units,TGs,TLs,TSs).
6180 guard_splitting(Rule,SplitGuardList) :-
6181 Rule = rule(H1,H2,Guard,_),
6182 append(H1,H2,Heads),
6183 conj2list(Guard,GuardList),
6184 term_variables(Heads,HeadVars),
6185 split_off_simple_guard_new(GuardList,HeadVars,GuardPrefix,RestGuardList),
6186 append(GuardPrefix,[RestGuard],SplitGuardList),
6187 term_variables(RestGuardList,GuardVars1),
6188 % variables that are declared to be ground don't need to be locked
6189 ground_vars(Heads,GroundVars),
6190 list_difference_eq(HeadVars,GroundVars,LockableHeadVars),
6191 intersect_eq(LockableHeadVars,GuardVars1,GuardVars),
6192 ( chr_pp_flag(guard_locks,on),
6193 bagof(('chr lock'(X)) - ('chr unlock'(X)), (lists:member(X,GuardVars)), LocksUnlocks) ->
6194 once(pairup(Locks,Unlocks,LocksUnlocks))
6199 list2conj(Locks,LockPhase),
6200 list2conj(Unlocks,UnlockPhase),
6201 list2conj(RestGuardList,RestGuard1),
6202 RestGuard = (LockPhase,(RestGuard1,UnlockPhase)).
6204 guard_body_copies3(Rule,GuardList,VarDict,GuardCopyList,BodyCopy) :-
6205 Rule = rule(_,_,_,Body),
6206 my_term_copy(GuardList,VarDict,VarDict2,GuardCopyList),
6207 my_term_copy(Body,VarDict2,BodyCopy).
6210 split_off_simple_guard_new([],_,[],[]).
6211 split_off_simple_guard_new([G|Gs],VarDict,S,C) :-
6212 ( simple_guard_new(G,VarDict) ->
6214 split_off_simple_guard_new(Gs,VarDict,Ss,C)
6220 % simple guard: cheap and benign (does not bind variables)
6221 simple_guard_new(G,Vars) :-
6222 builtin_binds_b(G,BoundVars),
6223 \+ (( member(V,BoundVars),
6224 memberchk_eq(V,Vars)
6227 dependency_reorder(Units,NUnits) :-
6228 dependency_reorder(Units,[],NUnits).
6230 dependency_reorder([],Acc,Result) :-
6231 reverse(Acc,Result).
6233 dependency_reorder([Unit|Units],Acc,Result) :-
6234 Unit = unit(_GID,_Goal,Type,GIDs),
6238 dependency_insert(Acc,Unit,GIDs,NAcc)
6240 dependency_reorder(Units,NAcc,Result).
6242 dependency_insert([],Unit,_,[Unit]).
6243 dependency_insert([X|Xs],Unit,GIDs,L) :-
6244 X = unit(GID,_,_,_),
6245 ( memberchk(GID,GIDs) ->
6249 dependency_insert(Xs,Unit,GIDs,T)
6252 build_units(Retrievals,Guard,InitialDict,Units) :-
6253 build_retrieval_units(Retrievals,1,N,InitialDict,Dict,Units,Tail),
6254 build_guard_units(Guard,N,Dict,Tail).
6256 build_retrieval_units([],N,N,Dict,Dict,L,L).
6257 build_retrieval_units([U|Us],N,M,Dict,NDict,L,T) :-
6258 term_variables(U,Vs),
6259 update_unit_dictionary(Vs,N,Dict,Dict1,[],GIDs),
6260 L = [unit(N,U,fixed,GIDs)|L1],
6262 build_retrieval_units(Us,N1,M,Dict1,NDict,L1,T).
6264 initialize_unit_dictionary(Term,Dict) :-
6265 term_variables(Term,Vars),
6266 pair_all_with(Vars,0,Dict).
6268 update_unit_dictionary([],_,Dict,Dict,GIDs,GIDs).
6269 update_unit_dictionary([V|Vs],This,Dict,NDict,GIDs,NGIDs) :-
6270 ( lookup_eq(Dict,V,GID) ->
6271 ( (GID == This ; memberchk(GID,GIDs) ) ->
6278 Dict1 = [V - This|Dict],
6281 update_unit_dictionary(Vs,This,Dict1,NDict,GIDs1,NGIDs).
6283 build_guard_units(Guard,N,Dict,Units) :-
6285 Units = [unit(N,Goal,fixed,[])]
6286 ; Guard = [Goal|Goals] ->
6287 term_variables(Goal,Vs),
6288 update_unit_dictionary2(Vs,N,Dict,NDict,[],GIDs),
6289 Units = [unit(N,Goal,movable,GIDs)|RUnits],
6291 build_guard_units(Goals,N1,NDict,RUnits)
6294 update_unit_dictionary2([],_,Dict,Dict,GIDs,GIDs).
6295 update_unit_dictionary2([V|Vs],This,Dict,NDict,GIDs,NGIDs) :-
6296 ( lookup_eq(Dict,V,GID) ->
6297 ( (GID == This ; memberchk(GID,GIDs) ) ->
6302 Dict1 = [V - This|Dict]
6304 Dict1 = [V - This|Dict],
6307 update_unit_dictionary2(Vs,This,Dict1,NDict,GIDs1,NGIDs).
6309 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6311 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6313 %% / ___| ___| |_ / ___| ___ _ __ ___ __ _ _ __ | |_(_) ___ ___ _
6314 %% \___ \ / _ \ __| \___ \ / _ \ '_ ` _ \ / _` | '_ \| __| |/ __/ __(_)
6315 %% ___) | __/ |_ ___) | __/ | | | | | (_| | | | | |_| | (__\__ \_
6316 %% |____/ \___|\__| |____/ \___|_| |_| |_|\__,_|_| |_|\__|_|\___|___(_)
6319 %% | | | |_ __ (_) __ _ _ _ ___ |_ _|_ __ / _| ___ _ __ ___ _ __ ___ ___
6320 %% | | | | '_ \| |/ _` | | | |/ _ \ | || '_ \| |_ / _ \ '__/ _ \ '_ \ / __/ _ \
6321 %% | |_| | | | | | (_| | |_| | __/ | || | | | _| __/ | | __/ | | | (_| __/
6322 %% \___/|_| |_|_|\__, |\__,_|\___| |___|_| |_|_| \___|_| \___|_| |_|\___\___|
6325 functional_dependency/4,
6326 get_functional_dependency/4.
6328 :- chr_option(mode,functional_dependency(+,+,?,?)).
6329 :- chr_option(mode,get_functional_dependency(+,+,?,?)).
6331 allocation_occurrence(C,AO), occurrence(C,O,RuleNb,_,_) \ functional_dependency(C,RuleNb,Pattern,Key)
6335 functional_dependency(C,1,Pattern,Key).
6337 functional_dependency(C,RuleNb1,Pattern,Key) \ get_functional_dependency(C,RuleNb2,QPattern,QKey)
6341 QPattern = Pattern, QKey = Key.
6342 get_functional_dependency(_,_,_,_)
6346 functional_dependency_analysis(Rules) :-
6347 ( fail, chr_pp_flag(functional_dependency_analysis,on) ->
6348 functional_dependency_analysis_main(Rules)
6353 functional_dependency_analysis_main([]).
6354 functional_dependency_analysis_main([PRule|PRules]) :-
6355 ( discover_unique_pattern(PRule,C,RuleNb,Pattern,Key) ->
6356 functional_dependency(C,RuleNb,Pattern,Key)
6360 functional_dependency_analysis_main(PRules).
6362 discover_unique_pattern(PragmaRule,F/A,RuleNb,Pattern,Key) :-
6363 PragmaRule = pragma(Rule,_,_,Name,RuleNb),
6364 Rule = rule(H1,H2,Guard,_),
6372 check_unique_constraints(C1,C2,Guard,RuleNb,List),
6373 term_variables(C1,Vs),
6376 lookup_eq(List,V1,V2),
6379 select_pragma_unique_variables(Vs,List,Key1),
6380 copy_term_nat(C1-Key1,Pattern-Key),
6383 select_pragma_unique_variables([],_,[]).
6384 select_pragma_unique_variables([V|Vs],List,L) :-
6385 ( lookup_eq(List,V,_) ->
6390 select_pragma_unique_variables(Vs,List,T).
6392 % depends on functional dependency analysis
6393 % and shape of rule: C1 \ C2 <=> true.
6394 set_semantics_rules(Rules) :-
6395 ( fail, chr_pp_flag(set_semantics_rule,on) ->
6396 set_semantics_rules_main(Rules)
6401 set_semantics_rules_main([]).
6402 set_semantics_rules_main([R|Rs]) :-
6403 set_semantics_rule_main(R),
6404 set_semantics_rules_main(Rs).
6406 set_semantics_rule_main(PragmaRule) :-
6407 PragmaRule = pragma(Rule,IDs,Pragmas,_,RuleNb),
6408 ( Rule = rule([C1],[C2],true,_),
6409 IDs = ids([ID1],[ID2]),
6410 \+ is_passive(RuleNb,ID1),
6412 get_functional_dependency(F/A,RuleNb,Pattern,Key),
6413 copy_term_nat(Pattern-Key,C1-Key1),
6414 copy_term_nat(Pattern-Key,C2-Key2),
6421 check_unique_constraints(C1,C2,G,RuleNb,List) :-
6422 \+ any_passive_head(RuleNb),
6423 variable_replacement(C1-C2,C2-C1,List),
6424 copy_with_variable_replacement(G,OtherG,List),
6426 once(entails_b(NotG,OtherG)).
6428 % checks for rules of the shape ...,C1,C2... (<|=)=> ...
6429 % where C1 and C2 are symmteric constraints
6430 symmetry_analysis(Rules) :-
6431 ( chr_pp_flag(check_unnecessary_active,off) ->
6434 symmetry_analysis_main(Rules)
6437 symmetry_analysis_main([]).
6438 symmetry_analysis_main([R|Rs]) :-
6439 R = pragma(Rule,ids(IDs1,IDs2),_,_,RuleNb),
6440 Rule = rule(H1,H2,_,_),
6441 ( ( \+ chr_pp_flag(check_unnecessary_active,simplification) ; H2 == [] ), H1 \== [] ->
6442 symmetry_analysis_heads_simplification(H1,IDs1,[],[],Rule,RuleNb),
6443 symmetry_analysis_heads_propagation(H2,IDs2,[],[],Rule,RuleNb)
6447 symmetry_analysis_main(Rs).
6449 symmetry_analysis_heads_simplification([],[],_,_,_,_).
6450 symmetry_analysis_heads_simplification([H|Hs],[ID|IDs],PreHs,PreIDs,Rule,RuleNb) :-
6451 ( \+ is_passive(RuleNb,ID),
6452 member2(PreHs,PreIDs,PreH-PreID),
6453 \+ is_passive(RuleNb,PreID),
6454 variable_replacement(PreH,H,List),
6455 copy_with_variable_replacement(Rule,Rule2,List),
6456 identical_guarded_rules(Rule,Rule2) ->
6461 symmetry_analysis_heads_simplification(Hs,IDs,[H|PreHs],[ID|PreIDs],Rule,RuleNb).
6463 symmetry_analysis_heads_propagation([],[],_,_,_,_).
6464 symmetry_analysis_heads_propagation([H|Hs],[ID|IDs],PreHs,PreIDs,Rule,RuleNb) :-
6465 ( \+ is_passive(RuleNb,ID),
6466 member2(PreHs,PreIDs,PreH-PreID),
6467 \+ is_passive(RuleNb,PreID),
6468 variable_replacement(PreH,H,List),
6469 copy_with_variable_replacement(Rule,Rule2,List),
6470 identical_rules(Rule,Rule2) ->
6475 symmetry_analysis_heads_propagation(Hs,IDs,[H|PreHs],[ID|PreIDs],Rule,RuleNb).
6477 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6479 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6480 %% ____ _ _ _ __ _ _ _
6481 %% / ___|(_)_ __ ___ _ __ | (_)/ _(_) ___ __ _| |_(_) ___ _ __
6482 %% \___ \| | '_ ` _ \| '_ \| | | |_| |/ __/ _` | __| |/ _ \| '_ \
6483 %% ___) | | | | | | | |_) | | | _| | (_| (_| | |_| | (_) | | | |
6484 %% |____/|_|_| |_| |_| .__/|_|_|_| |_|\___\__,_|\__|_|\___/|_| |_|
6487 simplification_code(Head,ID,RestHeads,RestIDs,PragmaRule,F/A,O,Id,L,T) :-
6488 PragmaRule = pragma(Rule,_,Pragmas,_,RuleNb),
6489 head_info(Head,A,_Vars,Susp,HeadVars,HeadPairs),
6490 build_head(F,A,Id,HeadVars,ClauseHead),
6491 get_constraint_mode(F/A,Mode),
6492 head_arg_matches(HeadPairs,Mode,[],FirstMatching,VarDict1,[],GroundVars),
6495 guard_splitting(Rule,GuardList0),
6496 ( is_stored_in_guard(F/A, RuleNb) ->
6497 GuardList = [Hole1|GuardList0]
6499 GuardList = GuardList0
6501 guard_via_reschedule_new(RestHeads,GuardList,Head,GuardCopyList,GetRestHeads,RescheduledTest),
6503 rest_heads_retrieval_and_matching(RestHeads,RestIDs,Head,GetRestHeads,Susps,VarDict1,VarDict,[],[],[],GroundVars,_),
6505 guard_body_copies3(Rule,GuardList,VarDict,GuardCopyList,BodyCopy),
6507 ( is_stored_in_guard(F/A, RuleNb) ->
6508 gen_occ_allocation_in_guard(F/A,O,Vars,Susp,Allocation),
6509 gen_uncond_attach_goal(F/A,Susp,Vars,Attachment,_),
6510 GuardCopyList = [Hole1Copy|_],
6511 Hole1Copy = (Allocation, Attachment)
6517 partner_constraint_detachments(Susps,RestHeads,VarDict,SuspsDetachments),
6518 active_constraint_detachment(Id,Susp,Head,VarDict,SuspDetachment),
6520 ( chr_pp_flag(debugable,on) ->
6521 Rule = rule(_,_,Guard,Body),
6522 my_term_copy(Guard - Body, VarDict, DebugGuard - DebugBody),
6523 sort_by_key([Susp|Susps],[ID|RestIDs],SortedSusps),
6524 DebugTry = 'chr debug_event'( try(SortedSusps,[],DebugGuard,DebugBody)),
6525 DebugApply = 'chr debug_event'(apply(SortedSusps,[],DebugGuard,DebugBody)),
6526 instrument_goal(ActualCut,DebugTry,DebugApply,Cut)
6530 ( unconditional_occurrence(F/A,O), chr_pp_flag(late_allocation,on) -> ActualCut = true ; ActualCut = (!) ),
6531 Clause = ( ClauseHead :-
6539 add_location(Clause,RuleNb,LocatedClause),
6540 L = [LocatedClause | T].
6542 add_location(Clause,RuleNb,NClause) :-
6543 ( chr_pp_flag(line_numbers,on) ->
6544 get_chr_source_file(File),
6545 get_line_number(RuleNb,LineNb),
6546 NClause = '$source_location'(File,LineNb):Clause
6551 add_dummy_location(Clause,NClause) :-
6552 ( chr_pp_flag(line_numbers,on) ->
6553 get_chr_source_file(File),
6554 NClause = '$source_location'(File,1):Clause
6558 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6559 %% head_arg_matches(+Pairs,+Modes,+VarDict,-Goal,-NVarDict) is det.
6561 % Return goal matching newly introduced variables with variables in
6562 % previously looked-up heads.
6563 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6564 head_arg_matches(Pairs,Modes,VarDict,Goal,NVarDict) :-
6565 head_arg_matches(Pairs,Modes,VarDict,Goal,NVarDict,[],_).
6567 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6568 %% head_arg_matches(+Pairs,+Modes,+VarDict,-Goal,-NVarDict,+GroundVars,-NGroundVars) is det.
6569 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6570 head_arg_matches(Pairs,Modes,VarDict,Goal,NVarDict,GroundVars,NGroundVars) :-
6571 head_arg_matches_(Pairs,Modes,VarDict,GroundVars,GoalList,NVarDict,NGroundVars),
6572 list2conj(GoalList,Goal).
6574 head_arg_matches_([],[],VarDict,GroundVars,[],VarDict,GroundVars).
6575 head_arg_matches_([Arg-Var| Rest],[Mode|Modes],VarDict,GroundVars,GoalList,NVarDict,NGroundVars) :-
6577 ( lookup_eq(VarDict,Arg,OtherVar) ->
6579 ( memberchk_eq(Arg,GroundVars) ->
6580 GoalList = [Var = OtherVar | RestGoalList],
6581 GroundVars1 = GroundVars
6583 GoalList = [Var == OtherVar | RestGoalList],
6584 GroundVars1 = [Arg|GroundVars]
6587 GoalList = [Var == OtherVar | RestGoalList],
6588 GroundVars1 = GroundVars
6592 VarDict1 = [Arg-Var | VarDict],
6593 GoalList = RestGoalList,
6595 GroundVars1 = [Arg|GroundVars]
6597 GroundVars1 = GroundVars
6602 ; ground(Arg), Arg = '$chr_identifier_match'(ActualArg,IndexType) ->
6603 identifier_label_atom(IndexType,Var,ActualArg,Goal),
6604 GoalList = [Goal|RestGoalList],
6606 GroundVars1 = GroundVars,
6611 GoalList = [ Var = Arg | RestGoalList]
6613 GoalList = [ Var == Arg | RestGoalList]
6616 GroundVars1 = GroundVars,
6619 ; Mode == (+), is_ground(GroundVars,Arg) ->
6620 copy_with_variable_replacement(Arg,ArgCopy,VarDict),
6621 GoalList = [ Var = ArgCopy | RestGoalList],
6623 GroundVars1 = GroundVars,
6628 functor(Term,Fct,N),
6631 GoalList = [ Var = Term | RestGoalList ]
6633 GoalList = [ nonvar(Var), Var = Term | RestGoalList ]
6635 pairup(Args,Vars,NewPairs),
6636 append(NewPairs,Rest,Pairs),
6637 replicate(N,Mode,NewModes),
6638 append(NewModes,Modes,RestModes),
6640 GroundVars1 = GroundVars
6642 head_arg_matches_(Pairs,RestModes,VarDict1,GroundVars1,RestGoalList,NVarDict,NGroundVars).
6644 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6645 % add_heads_types(+ListOfHeads,+VarTypes,-NVarTypes) is det.
6646 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6647 add_heads_types([],VarTypes,VarTypes).
6648 add_heads_types([Head|Heads],VarTypes,NVarTypes) :-
6649 add_head_types(Head,VarTypes,VarTypes1),
6650 add_heads_types(Heads,VarTypes1,NVarTypes).
6652 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6653 % add_head_types(+Head,+VarTypes,-NVarTypes) is det.
6654 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6655 add_head_types(Head,VarTypes,NVarTypes) :-
6657 get_constraint_type_det(F/A,ArgTypes),
6659 add_args_types(Args,ArgTypes,VarTypes,NVarTypes).
6661 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6662 % add_args_types(+Terms,+Types,+VarTypes,-NVarTypes) is det.
6663 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6664 add_args_types([],[],VarTypes,VarTypes).
6665 add_args_types([Arg|Args],[Type|Types],VarTypes,NVarTypes) :-
6666 add_arg_types(Arg,Type,VarTypes,VarTypes1),
6667 add_args_types(Args,Types,VarTypes1,NVarTypes).
6669 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6670 % add_arg_types(+Term,+Type,+VarTypes,-NVarTypes) is det.
6671 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6672 add_arg_types(Term,Type,VarTypes,NVarTypes) :-
6674 ( lookup_eq(VarTypes,Term,_) ->
6675 NVarTypes = VarTypes
6677 NVarTypes = [Term-Type|VarTypes]
6680 NVarTypes = VarTypes
6681 ; % TODO improve approximation!
6682 term_variables(Term,Vars),
6684 replicate(VarNb,any,Types),
6685 add_args_types(Vars,Types,VarTypes,NVarTypes)
6690 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6691 %% add_heads_ground_variables(+ListOfHeads,+GroundVars,-NGroundVars) is det.
6693 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6694 add_heads_ground_variables([],GroundVars,GroundVars).
6695 add_heads_ground_variables([Head|Heads],GroundVars,NGroundVars) :-
6696 add_head_ground_variables(Head,GroundVars,GroundVars1),
6697 add_heads_ground_variables(Heads,GroundVars1,NGroundVars).
6699 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6700 %% add_head_ground_variables(+Head,+GroundVars,-GroundVars) is det.
6702 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6703 add_head_ground_variables(Head,GroundVars,NGroundVars) :-
6705 get_constraint_mode(F/A,ArgModes),
6707 add_arg_ground_variables(Args,ArgModes,GroundVars,NGroundVars).
6710 add_arg_ground_variables([],[],GroundVars,GroundVars).
6711 add_arg_ground_variables([Arg|Args],[Mode|Modes],GroundVars,NGroundVars) :-
6713 term_variables(Arg,Vars),
6714 add_var_ground_variables(Vars,GroundVars,GroundVars1)
6716 GroundVars = GroundVars1
6718 add_arg_ground_variables(Args,Modes,GroundVars1,NGroundVars).
6720 add_var_ground_variables([],GroundVars,GroundVars).
6721 add_var_ground_variables([Var|Vars],GroundVars,NGroundVars) :-
6722 ( memberchk_eq(Var,GroundVars) ->
6723 GroundVars1 = GroundVars
6725 GroundVars1 = [Var|GroundVars]
6727 add_var_ground_variables(Vars,GroundVars1,NGroundVars).
6728 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6729 %% is_ground(+GroundVars,+Term) is semidet.
6731 % Determine whether =Term= is always ground.
6732 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6733 is_ground(GroundVars,Term) :-
6738 maplist(is_ground(GroundVars),Args)
6740 memberchk_eq(Term,GroundVars)
6743 %% check_ground(+GroundVars,+Term,-Goal) is det.
6745 % Return runtime check to see whether =Term= is ground.
6746 check_ground(GroundVars,Term,Goal) :-
6747 term_variables(Term,Variables),
6748 check_ground_variables(Variables,GroundVars,Goal).
6750 check_ground_variables([],_,true).
6751 check_ground_variables([Var|Vars],GroundVars,Goal) :-
6752 ( memberchk_eq(Var,GroundVars) ->
6753 check_ground_variables(Vars,GroundVars,Goal)
6755 Goal = (ground(Var), RGoal),
6756 check_ground_variables(Vars,GroundVars,RGoal)
6759 rest_heads_retrieval_and_matching(Heads,IDs,ActiveHead,GoalList,Susps,VarDict,NVarDict,PrevHs,PrevSusps,AttrDict) :-
6760 rest_heads_retrieval_and_matching(Heads,IDs,ActiveHead,GoalList,Susps,VarDict,NVarDict,PrevHs,PrevSusps,AttrDict,[],_).
6762 rest_heads_retrieval_and_matching(Heads,IDs,ActiveHead,GoalList,Susps,VarDict,NVarDict,PrevHs,PrevSusps,AttrDict,GroundVars,NGroundVars) :-
6764 rest_heads_retrieval_and_matching_n(Heads,IDs,PrevHs,PrevSusps,ActiveHead,GoalList,Susps,VarDict,NVarDict,AttrDict,GroundVars,NGroundVars)
6769 GroundVars = NGroundVars
6772 rest_heads_retrieval_and_matching_n([],_,_,_,_,[],[],VarDict,VarDict,_AttrDict,GroundVars,GroundVars).
6773 rest_heads_retrieval_and_matching_n([H|Hs],[ID|IDs],PrevHs,PrevSusps,ActiveHead,
6774 [Goal|Goals],[Susp|Susps],VarDict,NVarDict,_AttrDict,GroundVars,NGroundVars) :-
6776 head_info(H,A,Vars,_,_,Pairs),
6777 get_store_type(F/A,StoreType),
6778 ( StoreType == default ->
6779 passive_head_via(H,[ActiveHead|PrevHs],VarDict,ViaGoal,VarSusps),
6780 delay_phase_end(validate_store_type_assumptions,
6781 ( static_suspension_term(F/A,Suspension),
6782 get_static_suspension_term_field(arguments,F/A,Suspension,Vars),
6783 get_static_suspension_field(F/A,Suspension,state,active,GetState)
6786 % create_get_mutable_ref(active,State,GetMutable),
6787 get_constraint_mode(F/A,Mode),
6788 head_arg_matches(Pairs,Mode,VarDict,MatchingGoal,VarDict1,GroundVars,GroundVars1),
6790 sbag_member_call(Susp,VarSusps,Sbag),
6791 ExistentialLookup = (
6794 Susp = Suspension, % not inlined
6798 delay_phase_end(validate_store_type_assumptions,
6799 ( static_suspension_term(F/A,Suspension),
6800 get_static_suspension_term_field(arguments,F/A,Suspension,Vars)
6803 existential_lookup(StoreType,H,[ActiveHead|PrevHs],VarDict,GroundVars,Suspension,ExistentialLookup,Susp,Pairs,NPairs),
6804 get_constraint_mode(F/A,Mode),
6805 filter_mode(NPairs,Pairs,Mode,NMode),
6806 head_arg_matches(NPairs,NMode,VarDict,MatchingGoal,VarDict1,GroundVars,GroundVars1)
6808 different_from_other_susps(H,Susp,PrevHs,PrevSusps,DiffSuspGoals),
6809 append(NPairs,VarDict1,DA_), % order important here
6810 translate(GroundVars1,DA_,GroundVarsA),
6811 translate(GroundVars1,VarDict1,GroundVarsB),
6812 inline_matching_goal(MatchingGoal,MatchingGoal2,GroundVarsA,GroundVarsB),
6819 rest_heads_retrieval_and_matching_n(Hs,IDs,[H|PrevHs],[Susp|PrevSusps],ActiveHead,Goals,Susps,VarDict1,NVarDict,_NewAttrDict,GroundVars1,NGroundVars).
6821 inline_matching_goal(A==B,true,GVA,GVB) :-
6822 memberchk_eq(A,GVA),
6823 memberchk_eq(B,GVB),
6826 % inline_matching_goal(A=B,true,_,_) :- A=B, !.
6827 inline_matching_goal((A,B),(A2,B2),GVA,GVB) :- !,
6828 inline_matching_goal(A,A2,GVA,GVB),
6829 inline_matching_goal(B,B2,GVA,GVB).
6830 inline_matching_goal(X,X,_,_).
6833 filter_mode([],_,_,[]).
6834 filter_mode([Arg-Var|Rest],[_-V|R],[M|Ms],Modes) :-
6837 filter_mode(Rest,R,Ms,MT)
6839 filter_mode([Arg-Var|Rest],R,Ms,Modes)
6842 check_unique_keys([],_).
6843 check_unique_keys([V|Vs],Dict) :-
6844 lookup_eq(Dict,V,_),
6845 check_unique_keys(Vs,Dict).
6847 % Generates tests to ensure the found constraint differs from previously found constraints
6848 % TODO: detect more cases where constraints need be different
6849 different_from_other_susps(Head,Susp,Heads,Susps,DiffSuspGoals) :-
6850 different_from_other_susps_(Heads,Susps,Head,Susp,DiffSuspGoalList),
6851 list2conj(DiffSuspGoalList,DiffSuspGoals).
6853 different_from_other_susps_(_,[],_,_,[]) :- !.
6854 different_from_other_susps_([PreHead|Heads],[PreSusp|Susps],Head,Susp,List) :-
6855 ( functor(Head,F,A), functor(PreHead,F,A),
6856 copy_term_nat(PreHead-Head,PreHeadCopy-HeadCopy),
6857 \+ \+ PreHeadCopy = HeadCopy ->
6859 List = [Susp \== PreSusp | Tail]
6863 different_from_other_susps_(Heads,Susps,Head,Susp,Tail).
6865 % passive_head_via(in,in,in,in,out,out,out) :-
6866 passive_head_via(Head,PrevHeads,VarDict,Goal,AllSusps) :-
6868 get_constraint_index(F/A,Pos),
6869 common_variables(Head,PrevHeads,CommonVars),
6870 global_list_store_name(F/A,Name),
6871 GlobalGoal = nb_getval(Name,AllSusps),
6872 get_constraint_mode(F/A,ArgModes),
6875 ; member(CommonVar,CommonVars), nth(I,ArgModes,(-)), arg(I,Head,Arg), Arg == CommonVar ->
6876 translate([CommonVar],VarDict,[Var]),
6877 gen_get_mod_constraints(F/A,Var,AttrGoal,AllSusps),
6880 translate(CommonVars,VarDict,Vars),
6881 add_heads_types(PrevHeads,[],TypeDict),
6882 my_term_copy(TypeDict,VarDict,TypeDictCopy),
6883 gen_get_mod_constraints(F/A,Vars,TypeDictCopy,ViaGoal,AttrGoal,AllSusps),
6892 common_variables(T,Ts,Vs) :-
6893 term_variables(T,V1),
6894 term_variables(Ts,V2),
6895 intersect_eq(V1,V2,Vs).
6897 gen_get_mod_constraints(FA,Vars,TypeDict,ViaGoal,AttrGoal,AllSusps) :-
6898 get_target_module(Mod),
6900 lookup_eq(TypeDict,A,Type),
6901 ( atomic_type(Type) ->
6905 ViaGoal = 'chr newvia_1'(A,V)
6908 ViaGoal = 'chr newvia_2'(A,B,V)
6910 ViaGoal = 'chr newvia'(Vars,V)
6913 ( get_attr(V,Mod,TSusps),
6914 TSuspsEqSusps % TSusps = Susps
6916 get_max_constraint_index(N),
6918 TSuspsEqSusps = true, % TSusps = Susps
6921 get_constraint_index(FA,Pos),
6922 get_suspensions(N,Pos,TSusps,TSuspsEqSusps,AllSusps)
6924 gen_get_mod_constraints(FA,Var,AttrGoal,AllSusps) :-
6925 get_target_module(Mod),
6927 ( get_attr(Var,Mod,TSusps),
6928 TSuspsEqSusps % TSusps = Susps
6930 get_max_constraint_index(N),
6932 TSuspsEqSusps = true, % TSusps = Susps
6935 get_constraint_index(FA,Pos),
6936 get_suspensions(N,Pos,TSusps,TSuspsEqSusps,AllSusps)
6939 guard_body_copies(Rule,VarDict,GuardCopy,BodyCopy) :-
6940 guard_body_copies2(Rule,VarDict,GuardCopyList,BodyCopy),
6941 list2conj(GuardCopyList,GuardCopy).
6943 guard_body_copies2(Rule,VarDict,GuardCopyList,BodyCopy) :-
6944 Rule = rule(H,_,Guard,Body),
6945 conj2list(Guard,GuardList),
6946 split_off_simple_guard(GuardList,VarDict,GuardPrefix,RestGuardList),
6947 my_term_copy(GuardPrefix-RestGuardList,VarDict,VarDict2,GuardPrefixCopy-RestGuardListCopyCore),
6949 append(GuardPrefixCopy,[RestGuardCopy],GuardCopyList),
6950 term_variables(RestGuardList,GuardVars),
6951 term_variables(RestGuardListCopyCore,GuardCopyVars),
6952 % variables that are declared to be ground don't need to be locked
6953 ground_vars(H,GroundVars),
6954 list_difference_eq(GuardVars,GroundVars,GuardVars_),
6955 ( chr_pp_flag(guard_locks,on),
6956 bagof(('chr lock'(Y)) - ('chr unlock'(Y)),
6957 X ^ (lists:member(X,GuardVars), % X is a variable appearing in the original guard
6958 pairlist:lookup_eq(VarDict,X,Y), % translate X into new variable
6959 memberchk_eq(Y,GuardCopyVars) % redundant check? or multiple entries for X possible?
6962 once(pairup(Locks,Unlocks,LocksUnlocks))
6967 list2conj(Locks,LockPhase),
6968 list2conj(Unlocks,UnlockPhase),
6969 list2conj(RestGuardListCopyCore,RestGuardCopyCore),
6970 RestGuardCopy = (LockPhase,(RestGuardCopyCore,UnlockPhase)),
6971 my_term_copy(Body,VarDict2,BodyCopy).
6974 split_off_simple_guard([],_,[],[]).
6975 split_off_simple_guard([G|Gs],VarDict,S,C) :-
6976 ( simple_guard(G,VarDict) ->
6978 split_off_simple_guard(Gs,VarDict,Ss,C)
6984 % simple guard: cheap and benign (does not bind variables)
6985 simple_guard(G,VarDict) :-
6987 \+ (( member(V,Vars),
6988 lookup_eq(VarDict,V,_)
6991 active_constraint_detachment(Id,Susp,Head,VarDict,SuspDetachment) :-
6997 Id == [0], chr_pp_flag(store_in_guards, off)
6999 ( get_allocation_occurrence(C,AO),
7000 get_max_occurrence(C,MO),
7003 only_ground_indexed_arguments(C), chr_pp_flag(late_allocation,on) ->
7004 SuspDetachment = true
7006 gen_uncond_susp_detachment(Head,Susp,active,VarDict,UnCondSuspDetachment),
7007 ( chr_pp_flag(late_allocation,on) ->
7012 UnCondSuspDetachment
7015 SuspDetachment = UnCondSuspDetachment
7019 SuspDetachment = true
7022 partner_constraint_detachments([],[],_,true).
7023 partner_constraint_detachments([Susp|Susps],[Head|Heads],VarDict,(SuspDetachment,SuspsDetachments)) :-
7024 gen_uncond_susp_detachment(Head,Susp,partner,VarDict,SuspDetachment),
7025 partner_constraint_detachments(Susps,Heads,VarDict,SuspsDetachments).
7027 gen_uncond_susp_detachment(Head,Susp,Role,VarDict,SuspDetachment) :-
7031 SuspDetachment = ( DebugEvent, RemoveInternalGoal),
7032 ( chr_pp_flag(debugable,on) ->
7033 DebugEvent = 'chr debug_event'(remove(Susp))
7037 remove_constraint_goal(C,Susp,Vars,true,(DeleteCall,Detach),Role,RemoveInternalGoal),
7038 delete_constraint_goal(Head,Susp,VarDict,DeleteCall),
7039 ( \+ only_ground_indexed_arguments(C), \+ get_store_type(C,var_assoc_store(_,_)) ->
7040 detach_constraint_atom(C,Vars,Susp,Detach)
7045 SuspDetachment = true
7048 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7050 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7052 %% / ___|(_)_ __ ___ _ __ __ _ __ _ __ _| |_(_) ___ _ __ / |
7053 %% \___ \| | '_ ` _ \| '_ \ / _` |/ _` |/ _` | __| |/ _ \| '_ \ | |
7054 %% ___) | | | | | | | |_) | (_| | (_| | (_| | |_| | (_) | | | | | |
7055 %% |____/|_|_| |_| |_| .__/ \__,_|\__, |\__,_|\__|_|\___/|_| |_| |_|
7058 simpagation_head1_code(Head,ID,RestHeads,OtherIDs,PragmaRule,F/A,O,Id,L,T) :-
7059 PragmaRule = pragma(Rule,ids(_,Heads2IDs),Pragmas,_Name,RuleNb),
7060 Rule = rule(_Heads,Heads2,Guard,Body),
7062 head_info(Head,A,Vars,Susp,HeadVars,HeadPairs),
7063 get_constraint_mode(F/A,Mode),
7064 head_arg_matches(HeadPairs,Mode,[],FirstMatching,VarDict1,[],GroundVars),
7066 build_head(F,A,Id,HeadVars,ClauseHead),
7068 append(RestHeads,Heads2,Heads),
7069 append(OtherIDs,Heads2IDs,IDs),
7070 reorder_heads(RuleNb,Head,Heads,IDs,NHeads,NIDs),
7072 guard_splitting(Rule,GuardList0),
7073 ( is_stored_in_guard(F/A, RuleNb) ->
7074 GuardList = [Hole1|GuardList0]
7076 GuardList = GuardList0
7078 guard_via_reschedule_new(NHeads,GuardList,Head,GuardCopyList,GetRestHeads,RescheduledTest),
7080 rest_heads_retrieval_and_matching(NHeads,NIDs,Head,GetRestHeads,Susps,VarDict1,VarDict,[],[],[],GroundVars,_),
7081 split_by_ids(NIDs,Susps,OtherIDs,Susps1,Susps1IDs,Susps2,Susps2IDs),
7083 guard_body_copies3(Rule,GuardList,VarDict,GuardCopyList,BodyCopy),
7085 ( is_stored_in_guard(F/A, RuleNb) ->
7086 gen_uncond_attach_goal(F/A,Susp,Vars,Attachment,_),
7087 GuardCopyList = [Hole1Copy|_],
7088 Hole1Copy = Attachment
7093 sort_by_key(Susps1,Susps1IDs,SortedSusps1),
7094 partner_constraint_detachments(SortedSusps1,RestHeads,VarDict,SuspsDetachments),
7095 active_constraint_detachment(Id,Susp,Head,VarDict,SuspDetachment),
7097 ( chr_pp_flag(debugable,on) ->
7098 my_term_copy(Guard - Body, VarDict, DebugGuard - DebugBody),
7099 sort_by_key([Susp|Susps1],[ID|Susps1IDs],RemovedSusps),
7100 sort_by_key(Susps2,Susps2IDs,KeptSusps),
7101 DebugTry = 'chr debug_event'( try(RemovedSusps,KeptSusps,DebugGuard,DebugBody)),
7102 DebugApply = 'chr debug_event'(apply(RemovedSusps,KeptSusps,DebugGuard,DebugBody)),
7103 instrument_goal((!),DebugTry,DebugApply,Cut)
7108 Clause = ( ClauseHead :-
7116 add_location(Clause,RuleNb,LocatedClause),
7117 L = [LocatedClause | T].
7119 split_by_ids([],[],_,[],[]).
7120 split_by_ids([I|Is],[S|Ss],I1s,S1s,S2s) :-
7121 ( memberchk_eq(I,I1s) ->
7128 split_by_ids(Is,Ss,I1s,R1s,R2s).
7130 split_by_ids([],[],_,[],[],[],[]).
7131 split_by_ids([I|Is],[S|Ss],I1s,S1s,SI1s,S2s,SI2s) :-
7132 ( memberchk_eq(I,I1s) ->
7143 split_by_ids(Is,Ss,I1s,R1s,RSI1s,R2s,RSI2s).
7144 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7147 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7149 %% / ___|(_)_ __ ___ _ __ __ _ __ _ __ _| |_(_) ___ _ __ |___ \
7150 %% \___ \| | '_ ` _ \| '_ \ / _` |/ _` |/ _` | __| |/ _ \| '_ \ __) |
7151 %% ___) | | | | | | | |_) | (_| | (_| | (_| | |_| | (_) | | | | / __/
7152 %% |____/|_|_| |_| |_| .__/ \__,_|\__, |\__,_|\__|_|\___/|_| |_| |_____|
7155 %% Genereate prelude + worker predicate
7156 %% prelude calls worker
7157 %% worker iterates over one type of removed constraints
7158 simpagation_head2_code(Head2,ID,RestHeads2,RestIDs,PragmaRule,FA,O,Id,L,T) :-
7159 PragmaRule = pragma(Rule,ids(IDs1,IDs2),Pragmas,_Name,RuleNb),
7160 Rule = rule(Heads1,_,Guard,Body),
7161 append(Heads1,RestHeads2,Heads),
7162 append(IDs1,RestIDs,IDs),
7163 reorder_heads(RuleNb,Head2,Heads,IDs,[NHead|NHeads],[NID|NIDs]),
7164 simpagation_head2_prelude(Head2,NHead,[NHeads,Guard,Body],FA,O,Id,L,L1),
7166 ( memberchk_eq(NID,IDs2) ->
7167 simpagation_universal_searches(NHeads,NIDs,IDs2,[NHead,Head2],Rule,FA,NextHeads,PreHeads,NextIDs,Id1,Id2,L1,L2)
7169 L1 = L2, Id1 = Id2,NextHeads = NHeads, PreHeads = [NHead,Head2], NextIDs = NIDs
7171 universal_search_iterator_end(PreHeads,NextHeads,Rule,FA,Id2,L2,L3),
7172 simpagation_head2_worker(PreHeads,NextHeads,NextIDs,ID,PragmaRule,FA,O,Id2,L3,T).
7174 simpagation_universal_searches([],[],_,PreHeads,_,_,[],PreHeads,[],Id,Id,L,L).
7175 simpagation_universal_searches(Heads,[ID|IDs],IDs2,PreHeads,Rule,C,OutHeads,OutPreHeads,OutIDs,Id,NId,L,T) :-
7176 Heads = [Head|RHeads],
7178 universal_search_iterator_end(PreHeads,Heads,Rule,C,Id,L,L0),
7179 universal_search_iterator(Heads,PreHeads,Rule,C,Id,L0,L1),
7180 ( memberchk_eq(ID,IDs2) ->
7181 simpagation_universal_searches(RHeads,IDs,IDs2,[Head|PreHeads],Rule,C,OutHeads,OutPreHeads,OutIDs,Id1,NId,L1,T)
7183 NId = Id1, L1 = T, OutHeads = RHeads, OutPreHeads = [Head|PreHeads], IDs = OutIDs
7186 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7187 simpagation_head2_prelude(Head,Head1,Rest,F/A,O,Id1,L,T) :-
7188 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs),
7189 build_head(F,A,Id1,VarsSusp,ClauseHead),
7190 get_constraint_mode(F/A,Mode),
7191 head_arg_matches(HeadPairs,Mode,[],FirstMatching,VarDict,[],GroundVars),
7193 lookup_passive_head(Head1,[Head],VarDict,GroundVars,ModConstraintsGoal,AllSusps),
7195 gen_occ_allocation(F/A,O,Vars,Susp,ConstraintAllocationGoal),
7197 extend_id(Id1,DelegateId),
7198 extra_active_delegate_variables(Head,[Head1|Rest],VarDict,ExtraVars),
7199 append([AllSusps|VarsSusp],ExtraVars,DelegateCallVars),
7200 build_head(F,A,DelegateId,DelegateCallVars,Delegate),
7207 ConstraintAllocationGoal,
7210 add_dummy_location(PreludeClause,LocatedPreludeClause),
7211 L = [LocatedPreludeClause|T].
7213 extra_active_delegate_variables(Term,Terms,VarDict,Vars) :-
7215 delegate_variables(Term,Terms,VarDict,Args,Vars).
7217 passive_delegate_variables(Term,PrevTerms,NextTerms,VarDict,Vars) :-
7218 term_variables(PrevTerms,PrevVars),
7219 delegate_variables(Term,NextTerms,VarDict,PrevVars,Vars).
7221 delegate_variables(Term,Terms,VarDict,PrevVars,Vars) :-
7222 term_variables(Term,V1),
7223 term_variables(Terms,V2),
7224 intersect_eq(V1,V2,V3),
7225 list_difference_eq(V3,PrevVars,V4),
7226 translate(V4,VarDict,Vars).
7229 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7230 simpagation_head2_worker([CurrentHead|PreHeads],NextHeads,NextIDs,ID,PragmaRule,F/A,O,Id,L,T) :-
7231 PragmaRule = pragma(Rule,ids(IDs1,_),Pragmas,_,RuleNb),
7232 Rule = rule(_,_,Guard,Body),
7233 get_prop_inner_loop_vars(PreHeads,[CurrentHead,NextHeads,Guard,Body],PreVarsAndSusps,VarDict,Susp,Vars,PreSusps),
7236 gen_var(OtherSusps),
7238 functor(CurrentHead,OtherF,OtherA),
7239 gen_vars(OtherA,OtherVars),
7240 head_info(CurrentHead,OtherA,OtherVars,OtherSusp,_VarsSusp,HeadPairs),
7241 get_constraint_mode(OtherF/OtherA,Mode),
7242 head_arg_matches(HeadPairs,Mode,VarDict,FirstMatching,VarDict1,[],GroundVars),
7244 delay_phase_end(validate_store_type_assumptions,
7245 ( static_suspension_term(OtherF/OtherA,OtherSuspension),
7246 get_static_suspension_field(OtherF/OtherA,OtherSuspension,state,active,GetState),
7247 get_static_suspension_term_field(arguments,OtherF/OtherA,OtherSuspension,OtherVars)
7250 % create_get_mutable_ref(active,State,GetMutable),
7251 different_from_other_susps(CurrentHead,OtherSusp,PreHeads,PreSusps,DiffSuspGoals),
7253 OtherSusp = OtherSuspension,
7259 ClauseVars = [[OtherSusp|OtherSusps]|PreVarsAndSusps],
7260 build_head(F,A,Id,ClauseVars,ClauseHead),
7262 guard_splitting(Rule,GuardList0),
7263 ( is_stored_in_guard(F/A, RuleNb) ->
7264 GuardList = [Hole1|GuardList0]
7266 GuardList = GuardList0
7268 guard_via_reschedule_new(NextHeads,GuardList,[CurrentHead|PreHeads],GuardCopyList,RestSuspsRetrieval,RescheduledTest),
7270 rest_heads_retrieval_and_matching(NextHeads,NextIDs,[CurrentHead|PreHeads],RestSuspsRetrieval,Susps,VarDict1,VarDict2,[CurrentHead|PreHeads],[OtherSusp|PreSusps],[]),
7271 split_by_ids(NextIDs,Susps,IDs1,Susps1,Susps2),
7272 split_by_ids(NextIDs,NextHeads,IDs1,RestHeads1,_),
7274 partner_constraint_detachments([OtherSusp | Susps1],[CurrentHead|RestHeads1],VarDict2,Susps1Detachments),
7276 RecursiveVars = [OtherSusps|PreVarsAndSusps],
7277 build_head(F,A,Id,RecursiveVars,RecursiveCall),
7278 RecursiveVars2 = [[]|PreVarsAndSusps],
7279 build_head(F,A,Id,RecursiveVars2,RecursiveCall2),
7281 guard_body_copies3(Rule,GuardList,VarDict2,GuardCopyList,BodyCopy),
7282 ( is_stored_in_guard(F/A, RuleNb) ->
7283 GuardCopyList = [GuardAttachment|_] % once( ) ??
7288 ( is_observed(F/A,O) ->
7289 gen_uncond_attach_goal(F/A,Susp,Vars,Attachment,Generation),
7290 gen_state_cond_call(Susp,F/A,RecursiveCall,Generation,ConditionalRecursiveCall),
7291 gen_state_cond_call(Susp,F/A,RecursiveCall2,Generation,ConditionalRecursiveCall2)
7294 ConditionalRecursiveCall = RecursiveCall,
7295 ConditionalRecursiveCall2 = RecursiveCall2
7298 ( chr_pp_flag(debugable,on) ->
7299 my_term_copy(Guard - Body, VarDict, DebugGuard - DebugBody),
7300 DebugTry = 'chr debug_event'( try([OtherSusp|Susps1],[Susp|Susps2],DebugGuard,DebugBody)),
7301 DebugApply = 'chr debug_event'(apply([OtherSusp|Susps1],[Susp|Susps2],DebugGuard,DebugBody))
7307 ( is_stored_in_guard(F/A, RuleNb) ->
7308 GuardAttachment = Attachment,
7309 BodyAttachment = true
7311 GuardAttachment = true,
7312 BodyAttachment = Attachment % will be true if not observed at all
7315 ( member(unique(ID1,UniqueKeys), Pragmas),
7316 check_unique_keys(UniqueKeys,VarDict) ->
7319 ( CurrentSuspTest ->
7326 ConditionalRecursiveCall2
7344 ConditionalRecursiveCall
7350 add_location(Clause,RuleNb,LocatedClause),
7351 L = [LocatedClause | T].
7353 gen_state_cond_call(Susp,FA,Call,Generation,ConditionalCall) :-
7354 ( may_trigger(FA) ->
7355 does_use_field(FA,generation),
7356 delay_phase_end(validate_store_type_assumptions,
7357 ( static_suspension_term(FA,Suspension),
7358 get_update_static_suspension_field(FA,Susp,Suspension,state,active,inactive,GetState,UpdateState),
7359 get_static_suspension_field(FA,Suspension,generation,Generation,GetGeneration),
7360 get_static_suspension_term_field(arguments,FA,Suspension,Args)
7364 delay_phase_end(validate_store_type_assumptions,
7365 ( static_suspension_term(FA,Suspension),
7366 get_update_static_suspension_field(FA,Susp,Suspension,state,active,inactive,GetState,UpdateState),
7367 get_static_suspension_term_field(arguments,FA,Suspension,Args)
7370 GetGeneration = true
7373 ( Susp = Suspension,
7382 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7385 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7387 %% | _ \ _ __ ___ _ __ __ _ __ _ __ _| |_(_) ___ _ __
7388 %% | |_) | '__/ _ \| '_ \ / _` |/ _` |/ _` | __| |/ _ \| '_ \
7389 %% | __/| | | (_) | |_) | (_| | (_| | (_| | |_| | (_) | | | |
7390 %% |_| |_| \___/| .__/ \__,_|\__, |\__,_|\__|_|\___/|_| |_|
7393 propagation_code(Head,ID,RestHeads,RestIDs,Rule,RuleNb,FA,O,Id,L,T) :-
7394 ( RestHeads == [] ->
7395 propagation_single_headed(Head,ID,Rule,RuleNb,FA,O,Id,L,T)
7397 propagation_multi_headed(Head,RestHeads,RestIDs,Rule,RuleNb,FA,O,Id,L,T)
7399 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7400 %% Single headed propagation
7401 %% everything in a single clause
7402 propagation_single_headed(Head,ID,Rule,RuleNb,F/A,O,Id,ProgramList,ProgramTail) :-
7403 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs),
7404 build_head(F,A,Id,VarsSusp,ClauseHead),
7407 build_head(F,A,NextId,VarsSusp,NextHead),
7409 get_constraint_mode(F/A,Mode),
7410 head_arg_matches(HeadPairs,Mode,[],HeadMatching,VarDict,[],GroundVars),
7411 guard_body_copies(Rule,VarDict,GuardCopy,BodyCopy),
7413 % - recursive call -
7414 RecursiveCall = NextHead,
7416 ( unconditional_occurrence(F/A,O), chr_pp_flag(late_allocation,on) ->
7422 Rule = rule(_,_,Guard,Body),
7423 ( chr_pp_flag(debugable,on) ->
7424 my_term_copy(Guard - Body, VarDict, DebugGuard - DebugBody),
7425 DebugTry = 'chr debug_event'( try([],[Susp],DebugGuard,DebugBody)),
7426 DebugApply = 'chr debug_event'(apply([],[Susp],DebugGuard,DebugBody)),
7427 instrument_goal(ActualCut,DebugTry,DebugApply,Cut)
7431 ( may_trigger(F/A), \+ has_no_history(RuleNb)->
7432 use_auxiliary_predicate(novel_production),
7433 use_auxiliary_predicate(extend_history),
7434 does_use_history(F/A,O),
7435 gen_occ_allocation(F/A,O,Vars,Susp,Allocation),
7437 ( named_history(RuleNb,HistoryName,HistoryIDs) ->
7438 ( HistoryIDs == [] ->
7439 empty_named_history_novel_production(HistoryName,NovelProduction),
7440 empty_named_history_extend_history(HistoryName,ExtendHistory)
7448 ( var(NovelProduction) ->
7449 NovelProduction = '$novel_production'(Susp,Tuple),
7450 ExtendHistory = '$extend_history'(Susp,Tuple)
7455 ( is_observed(F/A,O) ->
7456 gen_uncond_attach_goal(F/A,Susp,Vars,Attachment,Generation),
7457 gen_state_cond_call(Susp,F/A,RecursiveCall,Generation,ConditionalRecursiveCall)
7460 ConditionalRecursiveCall = RecursiveCall
7464 NovelProduction = true,
7465 ExtendHistory = true,
7467 ( is_observed(F/A,O) ->
7468 get_allocation_occurrence(F/A,AllocO),
7470 gen_insert_constraint_internal_goal(F/A,Attachment,VarsSusp,Vars,Susp),
7472 ; % more room for improvement?
7473 Attachment = (Attachment1, Attachment2),
7474 gen_occ_allocation(F/A,O,Vars,Susp,Attachment1),
7475 gen_uncond_attach_goal(F/A,Susp,Vars,Attachment2,Generation)
7477 gen_state_cond_call(Susp,F/A,RecursiveCall,Generation,ConditionalRecursiveCall)
7479 gen_occ_allocation(F/A,O,Vars,Susp,Attachment),
7480 ConditionalRecursiveCall = RecursiveCall
7484 ( is_stored_in_guard(F/A, RuleNb) ->
7485 GuardAttachment = Attachment,
7486 BodyAttachment = true
7488 GuardAttachment = true,
7489 BodyAttachment = Attachment % will be true if not observed at all
7503 ConditionalRecursiveCall
7505 add_location(Clause,RuleNb,LocatedClause),
7506 ProgramList = [LocatedClause | ProgramTail].
7508 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7509 %% multi headed propagation
7510 %% prelude + predicates to accumulate the necessary combinations of suspended
7511 %% constraints + predicate to execute the body
7512 propagation_multi_headed(Head,RestHeads,RestIDs,Rule,RuleNb,FA,O,Id,L,T) :-
7513 RestHeads = [First|Rest],
7514 propagation_prelude(Head,RestHeads,Rule,FA,O,Id,L,L1),
7515 extend_id(Id,ExtendedId),
7516 propagation_nested_code(Rest,[First,Head],RestIDs,Rule,RuleNb,FA,O,ExtendedId,L1,T).
7518 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7519 propagation_prelude(Head,[First|Rest],Rule,F/A,O,Id,L,T) :-
7520 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs),
7521 build_head(F,A,Id,VarsSusp,PreludeHead),
7522 get_constraint_mode(F/A,Mode),
7523 head_arg_matches(HeadPairs,Mode,[],FirstMatching,VarDict,[],GroundVars),
7524 Rule = rule(_,_,Guard,Body),
7525 extra_active_delegate_variables(Head,[First,Rest,Guard,Body],VarDict,ExtraVars),
7527 lookup_passive_head(First,[Head],VarDict,GroundVars,FirstSuspGoal,Susps),
7529 gen_occ_allocation(F/A,O,Vars,Susp,CondAllocation),
7531 extend_id(Id,NestedId),
7532 append([Susps|VarsSusp],ExtraVars,NestedVars),
7533 build_head(F,A,NestedId,NestedVars,NestedHead),
7534 NestedCall = NestedHead,
7544 add_dummy_location(Prelude,LocatedPrelude),
7545 L = [LocatedPrelude|T].
7547 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7548 propagation_nested_code([],[CurrentHead|PreHeads],RestIDs,Rule,RuleNb,FA,O,Id,L,T) :-
7549 universal_search_iterator_end([CurrentHead|PreHeads],[],Rule,FA,Id,L,L1),
7550 propagation_body(CurrentHead,PreHeads,RestIDs,Rule,RuleNb,FA,O,Id,L1,T).
7552 propagation_nested_code([Head|RestHeads],PreHeads,RestIDs,Rule,RuleNb,FA,O,Id,L,T) :-
7553 universal_search_iterator_end(PreHeads,[Head|RestHeads],Rule,FA,Id,L,L1),
7554 universal_search_iterator([Head|RestHeads],PreHeads,Rule,FA,Id,L1,L2),
7556 propagation_nested_code(RestHeads,[Head|PreHeads],RestIDs,Rule,RuleNb,FA,O,IncId,L2,T).
7558 %check_fd_lookup_condition(_,_,_,_) :- fail.
7559 check_fd_lookup_condition(F,A,_,_) :-
7560 get_store_type(F/A,global_singleton), !.
7561 check_fd_lookup_condition(F,A,CurrentHead,PreHeads) :-
7562 \+ may_trigger(F/A),
7563 get_functional_dependency(F/A,1,P,K),
7564 copy_term(P-K,CurrentHead-Key),
7565 term_variables(PreHeads,PreVars),
7566 intersect_eq(Key,PreVars,Key),!.
7568 propagation_body(CurrentHead,PreHeads,RestIDs,Rule,RuleNb,F/A,O,Id,L,T) :-
7569 Rule = rule(_,H2,Guard,Body),
7570 gen_var_susp_list_for_b(PreHeads,[CurrentHead,Guard,Body],VarDict1,PreVarsAndSuspsList,FirstVarsSusp,AllSusps,PrevIterators),
7571 flatten(PreVarsAndSuspsList,PreVarsAndSusps),
7572 init(AllSusps,RestSusps),
7573 last(AllSusps,Susp),
7575 gen_var(OtherSusps),
7576 functor(CurrentHead,OtherF,OtherA),
7577 gen_vars(OtherA,OtherVars),
7578 delay_phase_end(validate_store_type_assumptions,
7579 ( static_suspension_term(OtherF/OtherA,Suspension),
7580 get_static_suspension_field(OtherF/OtherA,Suspension,state,active,GetState),
7581 get_static_suspension_term_field(arguments,OtherF/OtherA,Suspension,OtherVars)
7584 % create_get_mutable_ref(active,State,GetMutable),
7586 OtherSusp = Suspension,
7589 ClauseVars = [[OtherSusp|OtherSusps]|PreVarsAndSusps],
7590 build_head(F,A,Id,ClauseVars,ClauseHead),
7591 ( check_fd_lookup_condition(OtherF,OtherA,CurrentHead,PreHeads) -> % iterator (OtherSusps) is empty at runtime
7592 universal_search_iterator_failure_vars(PreHeads,Id,PreVarsAndSuspsList,FirstVarsSusp,PrevIterators,PreVarsAndSusps1,PrevId),
7593 RecursiveVars = PreVarsAndSusps1
7595 RecursiveVars = [OtherSusps|PreVarsAndSusps],
7598 build_head(F,A,PrevId,RecursiveVars,RecursiveHead),
7599 RecursiveCall = RecursiveHead,
7600 CurrentHead =.. [_|OtherArgs],
7601 pairup(OtherArgs,OtherVars,OtherPairs),
7602 get_constraint_mode(OtherF/OtherA,Mode),
7603 head_arg_matches(OtherPairs,Mode,VarDict1,Matching,VarDict),
7605 different_from_other_susps(CurrentHead,OtherSusp,PreHeads,RestSusps,DiffSuspGoals),
7606 guard_body_copies(Rule,VarDict,GuardCopy,BodyCopy),
7607 get_occurrence(F/A,O,_,ID),
7609 ( is_observed(F/A,O) ->
7610 init(FirstVarsSusp,FirstVars),
7611 gen_uncond_attach_goal(F/A,Susp,FirstVars,Attachment,Generation),
7612 gen_state_cond_call(Susp,F/A,RecursiveCall,Generation,ConditionalRecursiveCall)
7615 ConditionalRecursiveCall = RecursiveCall
7617 ( (is_least_occurrence(RuleNb) ; has_no_history(RuleNb)) ->
7618 NovelProduction = true,
7619 ExtendHistory = true
7620 ; \+ may_trigger(F/A), forall(member(SomeID,RestIDs),(chr_translate:is_passive(RuleNb,SomeID))) ->
7621 NovelProduction = true,
7622 ExtendHistory = true
7624 get_occurrence(F/A,O,_,ID),
7625 use_auxiliary_predicate(novel_production),
7626 use_auxiliary_predicate(extend_history),
7627 does_use_history(F/A,O),
7628 ( named_history(RuleNb,HistoryName,HistoryIDs) ->
7629 ( HistoryIDs == [] ->
7630 empty_named_history_novel_production(HistoryName,NovelProduction),
7631 empty_named_history_extend_history(HistoryName,ExtendHistory)
7633 reverse([OtherSusp|RestSusps],NamedSusps),
7634 named_history_susps(HistoryIDs,[ID|RestIDs],[Susp|NamedSusps],HistorySusps),
7635 HistorySusps = [HistorySusp|_],
7637 ( length(HistoryIDs, 1) ->
7638 ExtendHistory = '$extend_history'(HistorySusp,HistoryName),
7639 NovelProduction = '$novel_production'(HistorySusp,HistoryName)
7641 findall(ConstraintSymbol,(member(SomeID,HistoryIDs),get_occurrence_from_id(ConstraintSymbol,_,RuleNb,SomeID)),ConstraintSymbols),
7642 Tuple =.. [t,HistoryName|HistorySusps]
7647 findall(Functor/Arity,(member(H,H2),functor(H,Functor,Arity)),ConstraintSymbols),
7648 sort([ID|RestIDs],HistoryIDs),
7649 history_susps(RestIDs,[OtherSusp|RestSusps],Susp,ID,HistorySusps),
7650 Tuple =.. [t,RuleNb|HistorySusps]
7653 ( var(NovelProduction) ->
7654 novel_production_calls(ConstraintSymbols,HistoryIDs,HistorySusps,RuleNb,TupleVar,NovelProductions),
7655 ExtendHistory = '$extend_history'(HistorySusp,TupleVar),
7656 NovelProduction = ( TupleVar = Tuple, NovelProductions )
7663 ( chr_pp_flag(debugable,on) ->
7664 Rule = rule(_,_,Guard,Body),
7665 my_term_copy(Guard - Body, VarDict, DebugGuard - DebugBody),
7666 get_occurrence(F/A,O,_,ID),
7667 sort_by_key([Susp,OtherSusp|RestSusps],[ID|RestIDs],KeptSusps),
7668 DebugTry = 'chr debug_event'( try([],KeptSusps,DebugGuard,DebugBody)),
7669 DebugApply = 'chr debug_event'(apply([],KeptSusps,DebugGuard,DebugBody))
7675 ( is_stored_in_guard(F/A, RuleNb) ->
7676 GuardAttachment = Attachment,
7677 BodyAttachment = true
7679 GuardAttachment = true,
7680 BodyAttachment = Attachment % will be true if not observed at all
7696 ConditionalRecursiveCall
7700 add_location(Clause,RuleNb,LocatedClause),
7701 L = [LocatedClause|T].
7703 novel_production_calls([],[],[],_,_,true).
7704 novel_production_calls([ConstraintSymbol|ConstraintSymbols],[ID|IDs],[Suspension|Suspensions],RuleNb,Tuple,(Goal,Goals)) :-
7705 get_occurrence_from_id(ConstraintSymbol,Occurrence,RuleNb,ID),
7706 delay_phase_end(validate_store_type_assumptions,novel_production_call(ConstraintSymbol,Occurrence,'$novel_production'(Suspension,Tuple),Goal)),
7707 novel_production_calls(ConstraintSymbols,IDs,Suspensions,RuleNb,Tuple,Goals).
7709 history_susps(RestIDs,ReversedRestSusps,Susp,ID,HistorySusps) :-
7710 reverse(ReversedRestSusps,RestSusps),
7711 sort_by_key([Susp|RestSusps],[ID|RestIDs],HistorySusps).
7713 named_history_susps([],_,_,[]).
7714 named_history_susps([HistoryID|HistoryIDs],IDs,Susps,[HistorySusp|HistorySusps]) :-
7715 select2(HistoryID,HistorySusp,IDs,Susps,RestIDs,RestSusps), !,
7716 named_history_susps(HistoryIDs,RestIDs,RestSusps,HistorySusps).
7720 gen_var_susp_list_for([Head],Terms,VarDict,HeadVars,VarsSusp,Susp) :-
7723 head_info(Head,A,_Vars,Susp,VarsSusp,HeadPairs),
7724 get_constraint_mode(F/A,Mode),
7725 head_arg_matches(HeadPairs,Mode,[],_,VarDict),
7726 extra_active_delegate_variables(Head,Terms,VarDict,ExtraVars),
7727 append(VarsSusp,ExtraVars,HeadVars).
7728 gen_var_susp_list_for([Head|Heads],Terms,NVarDict,VarsSusps,Rest,Susps) :-
7729 gen_var_susp_list_for(Heads,[Head|Terms],VarDict,Rest,_,_),
7732 head_info(Head,A,_Vars,Susp,_VarsSusp,HeadPairs),
7733 get_constraint_mode(F/A,Mode),
7734 head_arg_matches(HeadPairs,Mode,VarDict,_,NVarDict),
7735 passive_delegate_variables(Head,Heads,Terms,NVarDict,HeadVars),
7736 append(HeadVars,[Susp,Susps|Rest],VarsSusps).
7739 % VarDict for the copies of variables in the original heads
7740 % VarsSuspsList list of lists of arguments for the successive heads
7741 % FirstVarsSusp top level arguments
7742 % SuspList list of all suspensions
7743 % Iterators list of all iterators
7744 gen_var_susp_list_for_b([Head],NextHeads,VarDict,[HeadVars],VarsSusp,[Susp],[]) :-
7747 head_info(Head,A,_Vars,Susp,VarsSusp,Pairs), % make variables for argument positions
7748 get_constraint_mode(F/A,Mode),
7749 head_arg_matches(Pairs,Mode,[],_,VarDict), % copy variables inside arguments, build dictionary
7750 extra_active_delegate_variables(Head,NextHeads,VarDict,ExtraVars), % decide what additional variables are needed
7751 append(VarsSusp,ExtraVars,HeadVars). % add additional variables to head variables
7752 gen_var_susp_list_for_b([Head|Heads],NextHeads,NVarDict,[Vars|RestVars],FirstVarsSusp,[Susp|SuspList],[Susps|Iterators]) :-
7753 gen_var_susp_list_for_b(Heads,[Head|NextHeads],VarDict,RestVars,FirstVarsSusp,SuspList,Iterators),
7756 head_info(Head,A,_Vars,Susp,_VarsSusp,HeadPairs),
7757 get_constraint_mode(F/A,Mode),
7758 head_arg_matches(HeadPairs,Mode,VarDict,_,NVarDict),
7759 passive_delegate_variables(Head,Heads,NextHeads,NVarDict,HeadVars),
7760 append(HeadVars,[Susp,Susps],Vars).
7762 get_prop_inner_loop_vars([Head],NextHeads,HeadVars,VarDict,Susp,Vars,[]) :-
7765 head_info(Head,A,Vars,Susp,VarsSusp,Pairs),
7766 get_constraint_mode(F/A,Mode),
7767 head_arg_matches(Pairs,Mode,[],_,VarDict),
7768 extra_active_delegate_variables(Head,NextHeads,VarDict,ExtraVars),
7769 append(VarsSusp,ExtraVars,HeadVars).
7770 get_prop_inner_loop_vars([Head|Heads],Terms,VarsSusps,NVarDict,MainSusp,MainVars,[Susp|RestSusps]) :-
7771 get_prop_inner_loop_vars(Heads,[Head|Terms],RestVarsSusp,VarDict,MainSusp,MainVars,RestSusps),
7774 head_info(Head,A,_Vars,Susp,_VarsSusp,Pairs),
7775 get_constraint_mode(F/A,Mode),
7776 head_arg_matches(Pairs,Mode,VarDict,_,NVarDict),
7777 passive_delegate_variables(Head,Heads,Terms,NVarDict,HeadVars),
7778 append(HeadVars,[Susp,Susps|RestVarsSusp],VarsSusps).
7780 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7782 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7784 %% | _ \ __ _ ___ ___(_)_ _____ | | | | ___ __ _ __| |
7785 %% | |_) / _` / __/ __| \ \ / / _ \ | |_| |/ _ \/ _` |/ _` |
7786 %% | __/ (_| \__ \__ \ |\ V / __/ | _ | __/ (_| | (_| |
7787 %% |_| \__,_|___/___/_| \_/ \___| |_| |_|\___|\__,_|\__,_|
7790 %% | _ \ ___| |_ _ __(_) _____ ____ _| |
7791 %% | |_) / _ \ __| '__| |/ _ \ \ / / _` | |
7792 %% | _ < __/ |_| | | | __/\ V / (_| | |
7793 %% |_| \_\___|\__|_| |_|\___| \_/ \__,_|_|
7796 %% | _ \ ___ ___ _ __ __| | ___ _ __(_)_ __ __ _
7797 %% | |_) / _ \/ _ \| '__/ _` |/ _ \ '__| | '_ \ / _` |
7798 %% | _ < __/ (_) | | | (_| | __/ | | | | | | (_| |
7799 %% |_| \_\___|\___/|_| \__,_|\___|_| |_|_| |_|\__, |
7802 reorder_heads(RuleNb,Head,RestHeads,RestIDs,NRestHeads,NRestIDs) :-
7803 ( chr_pp_flag(reorder_heads,on), length(RestHeads,Length), Length =< 6 ->
7804 reorder_heads_main(RuleNb,Head,RestHeads,RestIDs,NRestHeads,NRestIDs)
7806 NRestHeads = RestHeads,
7810 reorder_heads_main(RuleNb,Head,RestHeads,RestIDs,NRestHeads,NRestIDs) :-
7811 term_variables(Head,Vars),
7812 InitialData = entry([],[],Vars,RestHeads,RestIDs,RuleNb),
7813 copy_term_nat(InitialData,InitialDataCopy),
7814 a_star(InitialDataCopy,FD^(chr_translate:final_data(FD)),N^EN^C^(chr_translate:expand_data(N,EN,C)),FinalData),
7815 InitialDataCopy = InitialData,
7816 FinalData = entry(RNRestHeads,RNRestIDs,_,_,_,_),
7817 reverse(RNRestHeads,NRestHeads),
7818 reverse(RNRestIDs,NRestIDs).
7820 final_data(Entry) :-
7821 Entry = entry(_,_,_,_,[],_).
7823 expand_data(Entry,NEntry,Cost) :-
7824 Entry = entry(Heads,IDs,Vars,NHeads,NIDs,RuleNb),
7825 select2(Head1,ID1,NHeads,NIDs,NHeads1,NIDs1),
7826 term_variables([Head1|Vars],Vars1),
7827 NEntry = entry([Head1|Heads],[ID1|IDs],Vars1,NHeads1,NIDs1,RuleNb),
7828 order_score(Head1,ID1,Vars,NHeads1,RuleNb,Cost).
7830 % Assigns score to head based on known variables and heads to lookup
7831 order_score(Head,ID,KnownVars,RestHeads,RuleNb,Score) :-
7833 get_store_type(F/A,StoreType),
7834 order_score(StoreType,Head,ID,KnownVars,RestHeads,RuleNb,Score).
7836 order_score(default,Head,_ID,KnownVars,RestHeads,RuleNb,Score) :-
7837 term_variables(Head,HeadVars),
7838 term_variables(RestHeads,RestVars),
7839 order_score_vars(HeadVars,KnownVars,RestVars,Score).
7840 order_score(multi_inthash(Indexes),Head,_ID,KnownVars,RestHeads,RuleNb,Score) :-
7841 order_score_indexes(Indexes,Head,KnownVars,0,Score).
7842 order_score(multi_hash(Indexes),Head,_ID,KnownVars,RestHeads,RuleNb,Score) :-
7843 order_score_indexes(Indexes,Head,KnownVars,0,Score).
7844 order_score(global_ground,Head,ID,KnownVars,RestHeads,RuleNb,Score) :-
7845 term_variables(Head,HeadVars),
7846 term_variables(RestHeads,RestVars),
7847 order_score_vars(HeadVars,KnownVars,RestVars,Score_),
7848 Score is Score_ * 2.
7849 order_score(var_assoc_store(_,_),_,_,_,_,_,1).
7850 order_score(global_singleton,_Head,ID,_KnownVars,_RestHeads,_RuleNb,Score) :-
7851 Score = 1. % guaranteed O(1)
7853 order_score(multi_store(StoreTypes),Head,ID,KnownVars,RestHeads,RuleNb,Score) :-
7854 find_with_var_identity(
7856 t(Head,KnownVars,RestHeads),
7857 ( lists:member(ST,StoreTypes), chr_translate:order_score(ST,Head,ID,KnownVars,RestHeads,RuleNb,S) ),
7860 min_list(Scores,Score).
7861 order_score(identifier_store(Index),Head,ID,KnownVars,RestHeads,RuleNb,Score) :-
7863 order_score(type_indexed_identifier_store(_,_),Head,ID,KnownVars,RestHeads,RuleNb,Score) :-
7866 order_score_indexes([],_,_,Score,NScore) :-
7867 Score > 0, NScore = 100.
7868 order_score_indexes([I|Is],Head,KnownVars,Score,NScore) :-
7869 multi_hash_key_args(I,Head,Args),
7870 ( forall(Arg,Args,memberchk_eq(Arg,KnownVars)) ->
7875 order_score_indexes(Is,Head,KnownVars,Score1,NScore).
7877 order_score_vars(Vars,KnownVars,RestVars,Score) :-
7878 order_score_count_vars(Vars,KnownVars,RestVars,K-R-O),
7882 Score is max(10 - K,0)
7884 Score is max(10 - R,1) * 10
7886 Score is max(10-O,1) * 100
7888 order_score_count_vars([],_,_,0-0-0).
7889 order_score_count_vars([V|Vs],KnownVars,RestVars,NK-NR-NO) :-
7890 order_score_count_vars(Vs,KnownVars,RestVars,K-R-O),
7891 ( memberchk_eq(V,KnownVars) ->
7894 ; memberchk_eq(V,RestVars) ->
7902 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7904 %% |_ _|_ __ | (_)_ __ (_)_ __ __ _
7905 %% | || '_ \| | | '_ \| | '_ \ / _` |
7906 %% | || | | | | | | | | | | | | (_| |
7907 %% |___|_| |_|_|_|_| |_|_|_| |_|\__, |
7911 create_get_mutable_ref(V,M,GM) :- GM = (M = mutable(V)).
7912 create_get_mutable(V,M,GM) :- M = mutable(V), GM = true.
7916 %% create_get_mutable(V,M,GM) :- GM = get_mutable(V,M).
7917 %% create_get_mutable_ref(V,M,GM) :- GM = get_mutable(V,M).
7920 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7922 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7924 %% | | | | |_(_) (_) |_ _ _
7925 %% | | | | __| | | | __| | | |
7926 %% | |_| | |_| | | | |_| |_| |
7927 %% \___/ \__|_|_|_|\__|\__, |
7930 % Create a fresh variable.
7933 % Create =N= fresh variables.
7937 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs) :-
7938 vars_susp(A,Vars,Susp,VarsSusp),
7940 pairup(Args,Vars,HeadPairs).
7942 inc_id([N|Ns],[O|Ns]) :-
7944 dec_id([N|Ns],[M|Ns]) :-
7947 extend_id(Id,[0|Id]).
7949 next_id([_,N|Ns],[O|Ns]) :-
7952 % return clause Head
7953 % for F/A constraint symbol, predicate identifier Id and arguments Head
7954 build_head(F,A,Id,Args,Head) :-
7955 buildName(F,A,Id,Name),
7956 ( (chr_pp_flag(debugable,on) ; is_stored(F/A), ( has_active_occurrence(F/A) ; chr_pp_flag(late_allocation,off)),
7957 ( may_trigger(F/A) ;
7958 get_allocation_occurrence(F/A,AO),
7959 get_max_occurrence(F/A,MO),
7961 Head =.. [Name|Args]
7963 init(Args,ArgsWOSusp), % XXX not entirely correct!
7964 Head =.. [Name|ArgsWOSusp]
7967 % return predicate name Result
7968 % for Fct/Aty constraint symbol and predicate identifier List
7969 buildName(Fct,Aty,List,Result) :-
7970 ( (chr_pp_flag(debugable,on) ; (once((is_stored(Fct/Aty), ( has_active_occurrence(Fct/Aty) ; chr_pp_flag(late_allocation,off)),
7971 ( may_trigger(Fct/Aty) ; get_allocation_occurrence(Fct/Aty,AO), get_max_occurrence(Fct/Aty,MO),
7972 MO >= AO ) ; List \= [0])) ) ) ->
7973 atom_concat(Fct, '___' ,FctSlash),
7974 atomic_concat(FctSlash,Aty,FctSlashAty),
7975 buildName_(List,FctSlashAty,Result)
7980 buildName_([],Name,Name).
7981 buildName_([N|Ns],Name,Result) :-
7982 buildName_(Ns,Name,Name1),
7983 atom_concat(Name1,'__',NameDash), % '_' is a char :-(
7984 atomic_concat(NameDash,N,Result).
7986 vars_susp(A,Vars,Susp,VarsSusp) :-
7988 append(Vars,[Susp],VarsSusp).
7990 or_pattern(Pos,Pat) :-
7992 Pat is 1 << Pow. % was 2 ** X
7994 and_pattern(Pos,Pat) :-
7996 Y is 1 << X, % was 2 ** X
7997 Pat is (-1)*(Y + 1).
7999 make_name(Prefix,F/A,Name) :-
8000 atom_concat_list([Prefix,F,'___',A],Name).
8002 %===============================================================================
8003 % Attribute for attributed variables
8005 make_attr(N,Mask,SuspsList,Attr) :-
8006 length(SuspsList,N),
8007 Attr =.. [v,Mask|SuspsList].
8009 get_all_suspensions2(N,Attr,SuspensionsList) :-
8010 chr_pp_flag(dynattr,off), !,
8011 make_attr(N,_,SuspensionsList,Attr).
8014 get_all_suspensions2(N,Attr,Goal,SuspensionsList) :-
8015 % writeln(get_all_suspensions2),
8016 length(SuspensionsList,N),
8017 Goal = 'chr all_suspensions'(SuspensionsList,1,Attr).
8021 normalize_attr(Attr,NormalGoal,NormalAttr) :-
8022 % writeln(normalize_attr),
8023 NormalGoal = 'chr normalize_attr'(Attr,NormalAttr).
8025 get_suspensions(N,Position,TAttr,(TAttr = Attr),Suspensions) :-
8026 chr_pp_flag(dynattr,off), !,
8027 make_attr(N,_,SuspsList,Attr),
8028 nth1(Position,SuspsList,Suspensions).
8031 get_suspensions(N,Position,TAttr,Goal,Suspensions) :-
8032 % writeln(get_suspensions),
8034 ( memberchk(Position-Suspensions,TAttr) ->
8040 %-------------------------------------------------------------------------------
8041 % +N: number of constraint symbols
8042 % +Suspension: source-level variable, for suspension
8043 % +Position: constraint symbol number
8044 % -Attr: source-level term, for new attribute
8045 singleton_attr(N,Suspension,Position,Attr) :-
8046 chr_pp_flag(dynattr,off), !,
8047 or_pattern(Position,Pattern),
8048 make_attr(N,Pattern,SuspsList,Attr),
8049 nth1(Position,SuspsList,[Suspension]),
8050 chr_delete(SuspsList,[Suspension],RestSuspsList),
8051 set_elems(RestSuspsList,[]).
8054 singleton_attr(N,Suspension,Position,Attr) :-
8055 % writeln(singleton_attr),
8056 Attr = [Position-[Suspension]].
8058 %-------------------------------------------------------------------------------
8059 % +N: number of constraint symbols
8060 % +Suspension: source-level variable, for suspension
8061 % +Position: constraint symbol number
8062 % +TAttr: source-level variable, for old attribute
8063 % -Goal: goal for creating new attribute
8064 % -NTAttr: source-level variable, for new attribute
8065 add_attr(N,Suspension,Position,TAttr,Goal,NTAttr) :-
8066 chr_pp_flag(dynattr,off), !,
8067 make_attr(N,Mask,SuspsList,Attr),
8068 or_pattern(Position,Pattern),
8069 nth1(Position,SuspsList,Susps),
8070 substitute_eq(Susps,SuspsList,[Suspension|Susps],SuspsList1),
8071 make_attr(N,Mask,SuspsList1,NewAttr1),
8072 substitute_eq(Susps,SuspsList,[Suspension],SuspsList2),
8073 make_attr(N,NewMask,SuspsList2,NewAttr2),
8076 ( Mask /\ Pattern =:= Pattern ->
8079 NewMask is Mask \/ Pattern,
8085 add_attr(N,Suspension,Position,TAttr,Goal,NTAttr) :-
8086 % writeln(add_attr),
8088 ( 'chr select'(TAttr,Position-Suspensions,RAttr) ->
8089 NTAttr = [Position-[Suspension|Suspensions]|RAttr]
8091 NTAttr = [Position-[Suspension]|TAttr]
8094 rem_attr(N,Var,Suspension,Position,TAttr,Goal) :-
8095 chr_pp_flag(dynattr,off), !,
8096 or_pattern(Position,Pattern),
8097 and_pattern(Position,DelPattern),
8098 make_attr(N,Mask,SuspsList,Attr),
8099 nth1(Position,SuspsList,Susps),
8100 substitute_eq(Susps,SuspsList,[],SuspsList1),
8101 make_attr(N,NewMask,SuspsList1,Attr1),
8102 substitute_eq(Susps,SuspsList,NewSusps,SuspsList2),
8103 make_attr(N,Mask,SuspsList2,Attr2),
8104 get_target_module(Mod),
8107 ( Mask /\ Pattern =:= Pattern ->
8108 'chr sbag_del_element'(Susps,Suspension,NewSusps),
8110 NewMask is Mask /\ DelPattern,
8114 put_attr(Var,Mod,Attr1)
8117 put_attr(Var,Mod,Attr2)
8125 rem_attr(N,Var,Suspension,Position,TAttr,Goal) :-
8126 % writeln(rem_attr),
8127 get_target_module(Mod),
8129 ( 'chr select'(TAttr,Position-Suspensions,RAttr) ->
8130 'chr sbag_del_element'(Suspensions,Suspension,NSuspensions),
8131 ( NSuspensions == [] ->
8135 put_attr(Var,Mod,RAttr)
8138 put_attr(Var,Mod,[Position-NSuspensions|RAttr])
8144 %-------------------------------------------------------------------------------
8145 % +N: number of constraint symbols
8146 % +TAttr1: source-level variable, for attribute
8147 % +TAttr2: source-level variable, for other attribute
8148 % -Goal: goal for merging the two attributes
8149 % -Attr: source-level term, for merged attribute
8150 merge_attributes(N,TAttr1,TAttr2,Goal,Attr) :-
8151 chr_pp_flag(dynattr,off), !,
8152 make_attr(N,Mask1,SuspsList1,Attr1),
8153 merge_attributes2(N,Mask1,SuspsList1,TAttr2,Goal2,Attr),
8160 merge_attributes(N,TAttr1,TAttr2,Goal,Attr) :-
8161 % writeln(merge_attributes),
8163 sort(TAttr1,Sorted1),
8164 sort(TAttr2,Sorted2),
8165 'chr new_merge_attributes'(Sorted1,Sorted2,Attr)
8169 %-------------------------------------------------------------------------------
8170 % +N: number of constraint symbols
8172 % +SuspsList1: static term, for suspensions list
8173 % +TAttr2: source-level variable, for other attribute
8174 % -Goal: goal for merging the two attributes
8175 % -Attr: source-level term, for merged attribute
8176 merge_attributes2(N,Mask1,SuspsList1,TAttr2,Goal,Attr) :-
8177 make_attr(N,Mask2,SuspsList2,Attr2),
8178 bagof(G,X ^ Y ^ SY ^ M ^ (member2(SuspsList1,SuspsList2,X-Y),G = (sort(Y,SY),'chr merge_attributes'(X,SY,M))),Gs),
8179 list2conj(Gs,SortGoals),
8180 bagof(MS,A ^ B ^ C ^ member((A,'chr merge_attributes'(B,C,MS)),Gs), SuspsList),
8181 make_attr(N,Mask,SuspsList,Attr),
8185 Mask is Mask1 \/ Mask2
8189 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8190 % Storetype dependent lookup
8192 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8193 %% lookup_passive_head(+Head,+PreviousVars,+RenamingVarDict,
8194 %% -Goal,-SuspensionList) is det.
8196 % Create a universal lookup goal for given head.
8197 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8198 lookup_passive_head(Head,PreJoin,VarDict,Goal,AllSusps) :-
8200 get_store_type(F/A,StoreType),
8201 lookup_passive_head(StoreType,Head,PreJoin,VarDict,[],Goal,AllSusps).
8203 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8204 %% lookup_passive_head(+Head,+PreviousVars,+RenamingVarDict,+GroundVars,
8205 %% -Goal,-SuspensionList) is det.
8207 % Create a universal lookup goal for given head.
8208 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8209 lookup_passive_head(Head,PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
8211 get_store_type(F/A,StoreType),
8212 lookup_passive_head(StoreType,Head,PreJoin,VarDict,GroundVars,Goal,AllSusps).
8214 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8215 %% lookup_passive_head(+StoreType,+Head,+PreviousVars,+RenamingVarDict,
8216 %% +GroundVars,-Goal,-SuspensionList) is det.
8218 % Create a universal lookup goal for given head.
8219 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8220 lookup_passive_head(default,Head,PreJoin,VarDict,_,Goal,AllSusps) :-
8222 passive_head_via(Head,PreJoin,VarDict,Goal,AllSusps),
8223 update_store_type(F/A,default).
8224 lookup_passive_head(multi_inthash(Indexes),Head,_PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
8225 hash_lookup_passive_head(inthash,Indexes,Head,VarDict,GroundVars,Goal,AllSusps,_).
8226 lookup_passive_head(multi_hash(Indexes),Head,_PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
8227 hash_lookup_passive_head(hash,Indexes,Head,VarDict,GroundVars,Goal,AllSusps,_).
8228 lookup_passive_head(global_ground,Head,_PreJoin,_VarDict,_,Goal,AllSusps) :-
8230 global_ground_store_name(F/A,StoreName),
8231 make_get_store_goal(StoreName,AllSusps,Goal), % Goal = nb_getval(StoreName,AllSusps),
8232 update_store_type(F/A,global_ground).
8233 lookup_passive_head(var_assoc_store(VarIndex,KeyIndex),Head,_PreJoin,VarDict,_,Goal,AllSusps) :-
8234 arg(VarIndex,Head,OVar),
8235 arg(KeyIndex,Head,OKey),
8236 translate([OVar,OKey],VarDict,[Var,Key]),
8237 get_target_module(Module),
8239 get_attr(Var,Module,AssocStore),
8240 lookup_assoc_store(AssocStore,Key,AllSusps)
8242 lookup_passive_head(global_singleton,Head,_PreJoin,_VarDict,_,Goal,AllSusps) :-
8244 global_singleton_store_name(F/A,StoreName),
8245 make_get_store_goal(StoreName,Susp,GetStoreGoal),
8246 Goal = (GetStoreGoal,Susp \== [],AllSusps = [Susp]),
8247 update_store_type(F/A,global_singleton).
8248 lookup_passive_head(multi_store(StoreTypes),Head,PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
8250 member(ST,StoreTypes),
8251 lookup_passive_head(ST,Head,PreJoin,VarDict,GroundVars,Goal,AllSusps)
8253 lookup_passive_head(identifier_store(Index),Head,PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
8255 arg(Index,Head,Var),
8256 translate([Var],VarDict,[KeyVar]),
8257 delay_phase_end(validate_store_type_assumptions,
8258 identifier_lookup(F/A,Index,AllSusps,KeyVar,Goal)
8260 update_store_type(F/A,identifier_store(Index)),
8261 get_identifier_index(F/A,Index,_).
8262 lookup_passive_head(type_indexed_identifier_store(Index,IndexType),Head,PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
8264 arg(Index,Head,Var),
8266 translate([Var],VarDict,[KeyVar]),
8268 ; ground(Var), Var = '$chr_identifier_match'(ActualVar,_) ->
8269 lookup_identifier_atom(IndexType,ActualVar,KeyVar,LookupGoal),
8270 Goal = (LookupGoal,StructGoal)
8272 delay_phase_end(validate_store_type_assumptions,
8273 type_indexed_identifier_lookup(F/A,Index,IndexType,AllSusps,KeyVar,StructGoal)
8275 update_store_type(F/A,type_indexed_identifier_store(Index,IndexType)),
8276 get_type_indexed_identifier_index(IndexType,F/A,Index,_).
8278 identifier_lookup(C,Index,AllSusps,KeyVar,Goal) :-
8279 get_identifier_size(ISize),
8280 functor(Struct,struct,ISize),
8281 get_identifier_index(C,Index,IIndex),
8282 arg(IIndex,Struct,AllSusps),
8283 Goal = (KeyVar = Struct).
8285 type_indexed_identifier_lookup(C,Index,IndexType,AllSusps,KeyVar,Goal) :-
8286 type_indexed_identifier_structure(IndexType,Struct),
8287 get_type_indexed_identifier_index(IndexType,C,Index,IIndex),
8288 arg(IIndex,Struct,AllSusps),
8289 Goal = (KeyVar = Struct).
8291 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8292 %% hash_lookup_passive_head(+StoreType,+Indexes,+Head,+RenamingVarDict,
8293 %% +GroundVars,-Goal,-SuspensionList,-Index) is det.
8295 % Create a universal hash lookup goal for given head.
8296 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8297 hash_lookup_passive_head(HashType,Indexes,Head,VarDict,GroundVars,Goal,AllSusps,Index) :-
8299 member(Index,Indexes),
8300 multi_hash_key_args(Index,Head,KeyArgs),
8302 translate(KeyArgs,VarDict,KeyArgCopies)
8304 ground(KeyArgs), KeyArgCopies = KeyArgs
8307 ( KeyArgCopies = [KeyCopy] ->
8310 KeyCopy =.. [k|KeyArgCopies]
8313 multi_hash_lookup_goal(F/A,HashType,Index,KeyCopy,AllSusps,LookupGoal),
8315 check_ground(GroundVars,KeyArgs,OriginalGroundCheck),
8316 my_term_copy(OriginalGroundCheck,VarDict,GroundCheck),
8318 Goal = (GroundCheck,LookupGoal),
8320 ( HashType == inthash ->
8321 update_store_type(F/A,multi_inthash([Index]))
8323 update_store_type(F/A,multi_hash([Index]))
8326 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8327 %% existential_lookup(+StoreType,+Head,+PrevVariablesHead,+RenamingVarDict,
8328 %% +GroundVariables,-SuspensionTerm,-Goal,-SuspVar,
8329 %% +VarArgDict,-NewVarArgDict) is det.
8331 % Create existential lookup goal for given head.
8332 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8333 existential_lookup(var_assoc_store(VarIndex,KeyIndex),Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,Pairs) :- !,
8334 lookup_passive_head(var_assoc_store(VarIndex,KeyIndex),Head,PreJoin,VarDict,GroundVars,UniversalGoal,AllSusps),
8335 sbag_member_call(Susp,AllSusps,Sbag),
8337 delay_phase_end(validate_store_type_assumptions,
8338 ( static_suspension_term(F/A,SuspTerm),
8339 get_static_suspension_field(F/A,SuspTerm,state,active,GetState)
8348 existential_lookup(global_singleton,Head,_PreJoin,_VarDict,_,SuspTerm,Goal,Susp,Pairs,Pairs) :- !,
8350 global_singleton_store_name(F/A,StoreName),
8351 make_get_store_goal(StoreName,Susp,GetStoreGoal),
8353 GetStoreGoal, % nb_getval(StoreName,Susp),
8357 update_store_type(F/A,global_singleton).
8358 existential_lookup(multi_store(StoreTypes),Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :- !,
8360 member(ST,StoreTypes),
8361 existential_lookup(ST,Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs)
8363 existential_lookup(multi_inthash(Indexes),Head,_,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :- !,
8364 existential_hash_lookup(inthash,Indexes,Head,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs).
8365 existential_lookup(multi_hash(Indexes),Head,_,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :- !,
8366 existential_hash_lookup(hash,Indexes,Head,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs).
8367 existential_lookup(identifier_store(Index),Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :- !,
8368 lookup_passive_head(identifier_store(Index),Head,PreJoin,VarDict,GroundVars,LookupGoal,AllSusps),
8369 hash_index_filter(Pairs,Index,NPairs),
8372 ( check_fd_lookup_condition(F,A,Head,KeyArgs) ->
8373 Sbag = (AllSusps = [Susp])
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)
8385 Susp = SuspTerm, % not inlined
8388 existential_lookup(type_indexed_identifier_store(Index,IndexType),Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :- !,
8389 lookup_passive_head(type_indexed_identifier_store(Index,IndexType),Head,PreJoin,VarDict,GroundVars,LookupGoal,AllSusps),
8390 hash_index_filter(Pairs,Index,NPairs),
8393 ( check_fd_lookup_condition(F,A,Head,KeyArgs) ->
8394 Sbag = (AllSusps = [Susp])
8396 sbag_member_call(Susp,AllSusps,Sbag)
8398 delay_phase_end(validate_store_type_assumptions,
8399 ( static_suspension_term(F/A,SuspTerm),
8400 get_static_suspension_field(F/A,SuspTerm,state,active,GetState)
8406 Susp = SuspTerm, % not inlined
8409 existential_lookup(StoreType,Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,Pairs) :-
8410 lookup_passive_head(StoreType,Head,PreJoin,VarDict,GroundVars,UGoal,Susps),
8411 sbag_member_call(Susp,Susps,Sbag),
8413 delay_phase_end(validate_store_type_assumptions,
8414 ( static_suspension_term(F/A,SuspTerm),
8415 get_static_suspension_field(F/A,SuspTerm,state,active,GetState)
8421 Susp = SuspTerm, % not inlined
8425 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8426 %% existential_hash_lookup(+StoreType,+Indexes,+Head,+RenamingVarDict,
8427 %% +GroundVariables,-SuspensionTerm,-Goal,-SuspVar,
8428 %% +VarArgDict,-NewVarArgDict) is det.
8430 % Create existential hash lookup goal for given head.
8431 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8432 existential_hash_lookup(HashType,Indexes,Head,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :-
8433 hash_lookup_passive_head(HashType,Indexes,Head,VarDict,GroundVars,LookupGoal,AllSusps,Index),
8435 hash_index_filter(Pairs,Index,NPairs),
8438 ( check_fd_lookup_condition(F,A,Head,KeyArgs) ->
8439 Sbag = (AllSusps = [Susp])
8441 sbag_member_call(Susp,AllSusps,Sbag)
8443 delay_phase_end(validate_store_type_assumptions,
8444 ( static_suspension_term(F/A,SuspTerm),
8445 get_static_suspension_field(F/A,SuspTerm,state,active,GetState)
8451 Susp = SuspTerm, % not inlined
8455 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8456 %% hash_index_filter(+Pairs,+Index,-NPairs) is det.
8458 % Filter out pairs already covered by given hash index.
8459 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8460 hash_index_filter(Pairs,Index,NPairs) :-
8466 hash_index_filter(Pairs,NIndex,1,NPairs).
8468 hash_index_filter([],_,_,[]).
8469 hash_index_filter([P|Ps],Index,N,NPairs) :-
8474 hash_index_filter(Ps,[I|Is],NN,NPs)
8476 hash_index_filter(Ps,Is,NN,NPairs)
8482 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8483 %------------------------------------------------------------------------------%
8484 %% assume_constraint_stores(+ConstraintSymbols) is det.
8486 % Compute all constraint store types that are possible for the given
8487 % =ConstraintSymbols=.
8488 %------------------------------------------------------------------------------%
8489 assume_constraint_stores([]).
8490 assume_constraint_stores([C|Cs]) :-
8491 ( chr_pp_flag(debugable,off),
8492 ( only_ground_indexed_arguments(C) ; chr_pp_flag(mixed_stores,on) ),
8494 get_store_type(C,default) ->
8495 get_indexed_arguments(C,AllIndexedArgs),
8496 get_constraint_mode(C,Modes),
8497 findall(Index,(member(Index,AllIndexedArgs),
8498 nth(Index,Modes,+)),IndexedArgs),
8499 length(IndexedArgs,NbIndexedArgs),
8500 % Construct Index Combinations
8501 ( NbIndexedArgs > 10 ->
8502 findall([Index],member(Index,IndexedArgs),Indexes)
8504 findall(Index,(sublist(Index,IndexedArgs), Index \== []),UnsortedIndexes),
8505 predsort(longer_list,UnsortedIndexes,Indexes)
8508 ( get_functional_dependency(C,1,Pattern,Key),
8509 all_distinct_var_args(Pattern), Key == [] ->
8510 assumed_store_type(C,global_singleton)
8511 ; ( only_ground_indexed_arguments(C) ; NbIndexedArgs > 0 ) ->
8512 get_constraint_type_det(C,ArgTypes),
8513 partition_indexes(Indexes,ArgTypes,HashIndexes,IntHashIndexes,IdentifierIndexes,CompoundIdentifierIndexes),
8515 ( IntHashIndexes = [] ->
8518 Stores = [multi_inthash(IntHashIndexes)|Stores1]
8520 ( HashIndexes = [] ->
8523 Stores1 = [multi_hash(HashIndexes)|Stores2]
8525 ( IdentifierIndexes = [] ->
8528 maplist(wrap_in_functor(identifier_store),IdentifierIndexes,WrappedIdentifierIndexes),
8529 append(WrappedIdentifierIndexes,Stores3,Stores2)
8531 append(CompoundIdentifierIndexes,Stores4,Stores3),
8532 ( only_ground_indexed_arguments(C)
8533 -> Stores4 = [global_ground]
8534 ; Stores4 = [default]
8536 assumed_store_type(C,multi_store(Stores))
8542 assume_constraint_stores(Cs).
8544 %------------------------------------------------------------------------------%
8545 %% partition_indexes(+Indexes,+Types,
8546 %% -HashIndexes,-IntHashIndexes,-IdentifierIndexes) is det.
8547 %------------------------------------------------------------------------------%
8548 partition_indexes([],_,[],[],[],[]).
8549 partition_indexes([Index|Indexes],Types,HashIndexes,IntHashIndexes,IdentifierIndexes,CompoundIdentifierIndexes) :-
8552 unalias_type(Type,UnAliasedType),
8553 UnAliasedType == chr_identifier ->
8554 IdentifierIndexes = [I|RIdentifierIndexes],
8555 IntHashIndexes = RIntHashIndexes,
8556 HashIndexes = RHashIndexes,
8557 CompoundIdentifierIndexes = RCompoundIdentifierIndexes
8560 unalias_type(Type,UnAliasedType),
8561 nonvar(UnAliasedType),
8562 UnAliasedType = chr_identifier(IndexType) ->
8563 CompoundIdentifierIndexes = [type_indexed_identifier_store(I,IndexType)|RCompoundIdentifierIndexes],
8564 IdentifierIndexes = RIdentifierIndexes,
8565 IntHashIndexes = RIntHashIndexes,
8566 HashIndexes = RHashIndexes
8569 unalias_type(Type,UnAliasedType),
8570 UnAliasedType == dense_int ->
8571 IntHashIndexes = [Index|RIntHashIndexes],
8572 HashIndexes = RHashIndexes,
8573 IdentifierIndexes = RIdentifierIndexes,
8574 CompoundIdentifierIndexes = RCompoundIdentifierIndexes
8577 unalias_type(Type,UnAliasedType),
8578 nonvar(UnAliasedType),
8579 UnAliasedType = chr_identifier(_) ->
8580 % don't use chr_identifiers in hash indexes
8581 IntHashIndexes = RIntHashIndexes,
8582 HashIndexes = RHashIndexes,
8583 IdentifierIndexes = RIdentifierIndexes,
8584 CompoundIdentifierIndexes = RCompoundIdentifierIndexes
8586 IntHashIndexes = RIntHashIndexes,
8587 HashIndexes = [Index|RHashIndexes],
8588 IdentifierIndexes = RIdentifierIndexes,
8589 CompoundIdentifierIndexes = RCompoundIdentifierIndexes
8591 partition_indexes(Indexes,Types,RHashIndexes,RIntHashIndexes,RIdentifierIndexes,RCompoundIdentifierIndexes).
8593 longer_list(R,L1,L2) :-
8603 all_distinct_var_args(Term) :-
8605 copy_term_nat(Args,NArgs),
8606 all_distinct_var_args_(NArgs).
8608 all_distinct_var_args_([]).
8609 all_distinct_var_args_([X|Xs]) :-
8612 all_distinct_var_args_(Xs).
8614 get_indexed_arguments(C,IndexedArgs) :-
8616 get_indexed_arguments(1,A,C,IndexedArgs).
8618 get_indexed_arguments(I,N,C,L) :-
8621 ; ( is_indexed_argument(C,I) ->
8627 get_indexed_arguments(J,N,C,T)
8630 validate_store_type_assumptions([]).
8631 validate_store_type_assumptions([C|Cs]) :-
8632 validate_store_type_assumption(C),
8633 validate_store_type_assumptions(Cs).
8635 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8636 % new code generation
8637 universal_search_iterator_end([CurrentHead|PrevHeads],NextHeads,Rule,F/A,Id,L,T) :-
8638 Rule = rule(H1,_,Guard,Body),
8639 gen_var_susp_list_for_b(PrevHeads,[CurrentHead,NextHeads,Guard,Body],_,VarsAndSuspsList,FirstVarsSusp,_,PrevIterators),
8640 universal_search_iterator_failure_vars(PrevHeads,Id,VarsAndSuspsList,FirstVarsSusp,PrevIterators,PrevVarsAndSusps,PrevId),
8641 flatten(VarsAndSuspsList,VarsAndSusps),
8642 Vars = [ [] | VarsAndSusps],
8643 build_head(F,A,Id,Vars,Head),
8644 build_head(F,A,PrevId,PrevVarsAndSusps,PredecessorCall),
8645 Clause = ( Head :- PredecessorCall),
8646 add_dummy_location(Clause,LocatedClause),
8647 L = [LocatedClause | T].
8649 % functor(CurrentHead,CF,CA),
8650 % check_fd_lookup_condition(CF,CA,CurrentHead,PrevHeads) ->
8653 % gen_var_susp_list_for_b(PrevHeads,[CurrentHead,NextHeads,Guard,Body],_,VarsAndSuspsList,FirstVarsSusp,_,PrevIterators),
8654 % universal_search_iterator_failure_vars(PrevHeads,Id,VarsAndSuspsList,FirstVarsSusp,PrevIterators,PrevVarsAndSusps,PrevId),
8655 % flatten(VarsAndSuspsList,VarsAndSusps),
8656 % Vars = [ [] | VarsAndSusps],
8657 % build_head(F,A,Id,Vars,Head),
8658 % build_head(F,A,PrevId,PrevVarsAndSusps,PredecessorCall),
8659 % Clause = ( Head :- PredecessorCall),
8663 % skips back intelligently over global_singleton lookups
8664 universal_search_iterator_failure_vars(PrevHeads,Id,VarsAndSuspsList,BaseCallArgs,PrevIterators,PrevVarsAndSusps,PrevId) :-
8667 PrevVarsAndSusps = BaseCallArgs
8669 VarsAndSuspsList = [_|AllButFirstList],
8671 ( PrevHeads = [PrevHead|PrevHeads1],
8672 functor(PrevHead,F,A),
8673 check_fd_lookup_condition(F,A,PrevHead,PrevHeads1) ->
8674 PrevIterators = [_|PrevIterators1],
8675 universal_search_iterator_failure_vars(PrevHeads1,PrevId1,AllButFirstList,BaseCallArgs,PrevIterators1,PrevVarsAndSusps,PrevId)
8678 flatten(AllButFirstList,AllButFirst),
8679 PrevIterators = [PrevIterator|_],
8680 PrevVarsAndSusps = [PrevIterator|AllButFirst]
8684 universal_search_iterator([NextHead|RestHeads],[CurrentHead|PreHeads],Rule,F/A,Id,L,T) :-
8685 Rule = rule(_,_,Guard,Body),
8686 gen_var_susp_list_for_b(PreHeads,[CurrentHead,NextHead,RestHeads,Guard,Body],VarDict,PreVarsAndSuspsList,FirstVarsSusp,AllSusps,PrevIterators),
8687 init(AllSusps,PreSusps),
8688 flatten(PreVarsAndSuspsList,PreVarsAndSusps),
8689 gen_var(OtherSusps),
8690 functor(CurrentHead,OtherF,OtherA),
8691 gen_vars(OtherA,OtherVars),
8692 head_info(CurrentHead,OtherA,OtherVars,OtherSusp,_VarsSusp,HeadPairs),
8693 get_constraint_mode(OtherF/OtherA,Mode),
8694 head_arg_matches(HeadPairs,Mode,VarDict,FirstMatching,VarDict1),
8696 delay_phase_end(validate_store_type_assumptions,
8697 ( static_suspension_term(OtherF/OtherA,OtherSuspension),
8698 get_static_suspension_field(OtherF/OtherA,OtherSuspension,state,active,GetState),
8699 get_static_suspension_term_field(arguments,OtherF/OtherA,OtherSuspension,OtherVars)
8703 different_from_other_susps(CurrentHead,OtherSusp,PreHeads,PreSusps,DiffSuspGoals),
8704 % create_get_mutable_ref(active,State,GetMutable),
8706 OtherSusp = OtherSuspension,
8711 add_heads_ground_variables([CurrentHead|PreHeads],[],GroundVars),
8712 lookup_passive_head(NextHead,[CurrentHead|PreHeads],VarDict1,GroundVars,NextSuspGoal,NextSusps),
8713 inc_id(Id,NestedId),
8714 ClauseVars = [[OtherSusp|OtherSusps]|PreVarsAndSusps],
8715 build_head(F,A,Id,ClauseVars,ClauseHead),
8716 passive_delegate_variables(CurrentHead,PreHeads,[NextHead,RestHeads,Guard,Body],VarDict1,CurrentHeadVars),
8717 append([NextSusps|CurrentHeadVars],[OtherSusp,OtherSusps|PreVarsAndSusps],NestedVars),
8718 build_head(F,A,NestedId,NestedVars,NestedHead),
8720 ( check_fd_lookup_condition(OtherF,OtherA,CurrentHead,PreHeads) -> % iterator (OtherSusps) is empty at runtime
8721 universal_search_iterator_failure_vars(PreHeads,Id,PreVarsAndSuspsList,FirstVarsSusp,PrevIterators,PreVarsAndSusps1,PrevId),
8722 RecursiveVars = PreVarsAndSusps1
8724 RecursiveVars = [OtherSusps|PreVarsAndSusps],
8727 build_head(F,A,PrevId,RecursiveVars,RecursiveHead),
8738 add_dummy_location(Clause,LocatedClause),
8739 L = [LocatedClause|T].
8741 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8743 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8744 % Observation Analysis
8749 % Analysis based on Abstract Interpretation paper.
8752 % stronger analysis domain [research]
8755 initial_call_pattern/1,
8757 call_pattern_worker/1,
8758 final_answer_pattern/2,
8759 abstract_constraints/1,
8763 ai_observed_internal/2,
8765 ai_not_observed_internal/2,
8769 ai_observation_gather_results/0.
8771 :- chr_type abstract_domain ---> odom(program_point,list(constraint)).
8772 :- chr_type program_point == any.
8774 :- chr_option(mode,initial_call_pattern(+)).
8775 :- chr_option(type_declaration,call_pattern(abstract_domain)).
8777 :- chr_option(mode,call_pattern(+)).
8778 :- chr_option(type_declaration,call_pattern(abstract_domain)).
8780 :- chr_option(mode,call_pattern_worker(+)).
8781 :- chr_option(type_declaration,call_pattern_worker(abstract_domain)).
8783 :- chr_option(mode,final_answer_pattern(+,+)).
8784 :- chr_option(type_declaration,final_answer_pattern(abstract_domain,abstract_domain)).
8786 :- chr_option(mode,abstract_constraints(+)).
8787 :- chr_option(type_declaration,abstract_constraints(list)).
8789 :- chr_option(mode,depends_on(+,+)).
8790 :- chr_option(type_declaration,depends_on(abstract_domain,abstract_domain)).
8792 :- chr_option(mode,depends_on_as(+,+,+)).
8793 :- chr_option(mode,depends_on_ap(+,+,+,+)).
8794 :- chr_option(mode,depends_on_goal(+,+)).
8795 :- chr_option(mode,ai_is_observed(+,+)).
8796 :- chr_option(mode,ai_not_observed(+,+)).
8797 % :- chr_option(mode,ai_observed(+,+)).
8798 :- chr_option(mode,ai_not_observed_internal(+,+)).
8799 :- chr_option(mode,ai_observed_internal(+,+)).
8802 abstract_constraints_fd @
8803 abstract_constraints(_) \ abstract_constraints(_) <=> true.
8805 ai_observed_internal(C,O) \ ai_not_observed_internal(C,O) <=> true.
8806 ai_not_observed_internal(C,O) \ ai_not_observed_internal(C,O) <=> true.
8807 ai_observed_internal(C,O) \ ai_observed_internal(C,O) <=> true.
8809 ai_not_observed(C,O) \ ai_is_observed(C,O) <=> fail.
8810 ai_is_observed(_,_) <=> true.
8812 ai_observation_gather_results \ ai_observed_internal(C,O) <=> true. % ai_observed(C,O).
8813 ai_observation_gather_results \ ai_not_observed_internal(C,O) <=> ai_not_observed(C,O).
8814 ai_observation_gather_results <=> true.
8816 %------------------------------------------------------------------------------%
8817 % Main Analysis Entry
8818 %------------------------------------------------------------------------------%
8819 ai_observation_analysis(ACs) :-
8820 ( chr_pp_flag(ai_observation_analysis,on),
8821 get_target_module(Module), '$chr_compiled_with_version'(3) -> % , Module \== guard_entailment ->
8822 list_to_ord_set(ACs,ACSet),
8823 abstract_constraints(ACSet),
8824 ai_observation_schedule_initial_calls(ACSet,ACSet),
8825 ai_observation_gather_results
8830 ai_observation_schedule_initial_calls([],_).
8831 ai_observation_schedule_initial_calls([AC|RACs],ACs) :-
8832 ai_observation_schedule_initial_call(AC,ACs),
8833 ai_observation_schedule_initial_calls(RACs,ACs).
8835 ai_observation_schedule_initial_call(AC,ACs) :-
8836 ai_observation_top(AC,CallPattern),
8837 % ai_observation_bot(AC,ACs,CallPattern),
8838 initial_call_pattern(CallPattern).
8840 ai_observation_schedule_new_calls([],AP).
8841 ai_observation_schedule_new_calls([AC|ACs],AP) :-
8843 initial_call_pattern(odom(AC,Set)),
8844 ai_observation_schedule_new_calls(ACs,AP).
8846 final_answer_pattern(CP,AP1) \ final_answer_pattern(CP,AP2)
8848 ai_observation_leq(AP2,AP1)
8852 initial_call_pattern(CP) \ initial_call_pattern(CP) <=> true.
8854 initial_call_pattern(CP) ==> call_pattern(CP).
8856 initial_call_pattern(CP), final_answer_pattern(CP,AP), abstract_constraints(ACs) # ID3
8858 ai_observation_schedule_new_calls(ACs,AP)
8862 call_pattern(CP) \ call_pattern(CP) <=> true.
8864 depends_on(CP1,CP2), final_answer_pattern(CP2,AP) ==>
8865 final_answer_pattern(CP1,AP).
8867 %call_pattern(CP) ==> writeln(call_pattern(CP)).
8869 call_pattern(CP) ==> call_pattern_worker(CP).
8871 %------------------------------------------------------------------------------%
8873 %------------------------------------------------------------------------------%
8876 %call_pattern(odom([],Set)) ==>
8877 % final_answer_pattern(odom([],Set),odom([],Set)).
8879 call_pattern_worker(odom([],Set)) <=>
8880 % writeln(' - AbstractGoal'(odom([],Set))),
8881 final_answer_pattern(odom([],Set),odom([],Set)).
8884 call_pattern_worker(odom([G|Gs],Set)) <=>
8885 % writeln(' - AbstractGoal'(odom([G|Gs],Set))),
8887 depends_on_goal(odom([G|Gs],Set),CP1),
8890 depends_on_goal(CP1,CP2), final_answer_pattern(CP2,AP2) \ depends_on(CP1,_) # ID
8891 <=> true pragma passive(ID).
8892 depends_on_goal(CP1,CP2), final_answer_pattern(CP2,AP2)
8894 CP1 = odom([_|Gs],_),
8898 depends_on(CP1,CCP).
8900 %------------------------------------------------------------------------------%
8901 % Abstract Disjunction
8902 %------------------------------------------------------------------------------%
8904 call_pattern_worker(odom((AG1;AG2),Set)) <=>
8905 CP = odom((AG1;AG2),Set),
8906 InitialAnswerApproximation = odom([],Set),
8907 final_answer_pattern(CP,InitialAnswerApproximation),
8908 CP1 = odom(AG1,Set),
8909 CP2 = odom(AG2,Set),
8912 depends_on_as(CP,CP1,CP2).
8914 %------------------------------------------------------------------------------%
8916 %------------------------------------------------------------------------------%
8917 call_pattern_worker(odom(builtin,Set)) <=>
8918 % writeln(' - AbstractSolve'(odom(builtin,Set))),
8919 ord_empty(EmptySet),
8920 final_answer_pattern(odom(builtin,Set),odom([],EmptySet)).
8922 %------------------------------------------------------------------------------%
8924 %------------------------------------------------------------------------------%
8925 max_occurrence(C,MO) # ID2 \ call_pattern_worker(odom(occ(C,O),Set))
8929 % writeln(' - AbstractDrop'(odom(occ(C,O),Set))),
8930 final_answer_pattern(odom(occ(C,O),Set),odom([],Set))
8934 %------------------------------------------------------------------------------%
8936 %------------------------------------------------------------------------------%
8937 call_pattern_worker(odom(AC,Set))
8941 % writeln(' - AbstractActivate'(odom(AC,Set))),
8942 CP = odom(occ(AC,1),Set),
8944 depends_on(odom(AC,Set),CP).
8946 %------------------------------------------------------------------------------%
8948 %------------------------------------------------------------------------------%
8949 occurrence(C,O,RuleNb,ID,_) # ID2 \ call_pattern_worker(odom(occ(C,O),Set))
8951 is_passive(RuleNb,ID)
8953 % writeln(' - AbstractPassive'(odom(occ(C,O),Set))),
8956 DCP = odom(occ(C,NO),Set),
8958 final_answer_pattern(odom(occ(C,O),Set),odom([],Set)),
8959 depends_on(odom(occ(C,O),Set),DCP)
8962 %------------------------------------------------------------------------------%
8964 %------------------------------------------------------------------------------%
8967 occurrence(C,O,RuleNb,ID,simplification) # ID2 \ call_pattern_worker(odom(occ(C,O),Set))
8969 \+ is_passive(RuleNb,ID)
8971 % writeln(' - AbstractPassive'(odom(occ(C,O),Set))),
8972 ai_observation_memo_simplification_rest_heads(C,O,AbstractRestHeads),
8973 ai_observation_observe_set(Set,AbstractRestHeads,Set2),
8974 ai_observation_memo_abstract_goal(RuleNb,AG),
8975 call_pattern(odom(AG,Set2)),
8978 DCP = odom(occ(C,NO),Set),
8980 depends_on_as(odom(occ(C,O),Set),odom(AG,Set2),DCP),
8981 % DEADLOCK AVOIDANCE
8982 final_answer_pattern(odom(occ(C,O),Set),odom([],Set))
8986 depends_on_as(CP,CPS,CPD),
8987 final_answer_pattern(CPS,APS),
8988 final_answer_pattern(CPD,APD) ==>
8989 ai_observation_lub(APS,APD,AP),
8990 final_answer_pattern(CP,AP).
8994 ai_observation_memo_simplification_rest_heads/3,
8995 ai_observation_memoed_simplification_rest_heads/3.
8997 :- chr_option(mode,ai_observation_memo_simplification_rest_heads(+,+,?)).
8998 :- chr_option(mode,ai_observation_memoed_simplification_rest_heads(+,+,+)).
9000 ai_observation_memoed_simplification_rest_heads(C,O,RH) \ ai_observation_memo_simplification_rest_heads(C,O,QRH)
9003 abstract_constraints(ACs) # ID1, occurrence(C,O,RuleNb,ID,_) # ID2, rule(RuleNb,Rule) # ID3 \ ai_observation_memo_simplification_rest_heads(C,O,QRH)
9005 Rule = pragma(rule(H1,H2,_,_),ids(IDs1,_),_,_,_),
9006 once(select2(ID,_,IDs1,H1,_,RestH1)),
9007 ai_observation_abstract_constraints(RestH1,ACs,ARestHeads),
9008 ai_observation_abstract_constraints(H2,ACs,AH2),
9009 append(ARestHeads,AH2,AbstractHeads),
9010 sort(AbstractHeads,QRH),
9011 ai_observation_memoed_simplification_rest_heads(C,O,QRH)
9017 ai_observation_memo_simplification_rest_heads(_,_,_) <=> fail.
9019 %------------------------------------------------------------------------------%
9020 % Abstract Propagate
9021 %------------------------------------------------------------------------------%
9025 occurrence(C,O,RuleNb,ID,propagation) # ID2 \ call_pattern_worker(odom(occ(C,O),Set))
9027 \+ is_passive(RuleNb,ID)
9029 % writeln(' - AbstractPropagate'(odom(occ(C,O),Set))),
9031 ai_observation_memo_propagation_rest_heads(C,O,AHs),
9032 ai_observation_observe_set(Set,AHs,Set2),
9033 ord_add_element(Set2,C,Set3),
9034 ai_observation_memo_abstract_goal(RuleNb,AG),
9035 call_pattern(odom(AG,Set3)),
9036 ( ord_memberchk(C,Set2) ->
9043 DCP = odom(occ(C,NO),Set),
9045 depends_on_ap(odom(occ(C,O),Set),odom(AG,Set3),DCP,Delete)
9050 ai_observation_memo_propagation_rest_heads/3,
9051 ai_observation_memoed_propagation_rest_heads/3.
9053 :- chr_option(mode,ai_observation_memo_propagation_rest_heads(+,+,?)).
9054 :- chr_option(mode,ai_observation_memoed_propagation_rest_heads(+,+,+)).
9056 ai_observation_memoed_propagation_rest_heads(C,O,RH) \ ai_observation_memo_propagation_rest_heads(C,O,QRH)
9059 abstract_constraints(ACs) # ID1, occurrence(C,O,RuleNb,ID,_) # ID2, rule(RuleNb,Rule) # ID3 \ ai_observation_memo_propagation_rest_heads(C,O,QRH)
9061 Rule = pragma(rule(H1,H2,_,_),ids(_,IDs2),_,_,_),
9062 once(select2(ID,_,IDs2,H2,_,RestH2)),
9063 ai_observation_abstract_constraints(RestH2,ACs,ARestHeads),
9064 ai_observation_abstract_constraints(H1,ACs,AH1),
9065 append(ARestHeads,AH1,AbstractHeads),
9066 sort(AbstractHeads,QRH),
9067 ai_observation_memoed_propagation_rest_heads(C,O,QRH)
9073 ai_observation_memo_propagation_rest_heads(_,_,_) <=> fail.
9075 depends_on_ap(CP,CPP,CPD,Delete), final_answer_pattern(CPD,APD) ==>
9076 final_answer_pattern(CP,APD).
9077 depends_on_ap(CP,CPP,CPD,Delete), final_answer_pattern(CPP,APP),
9078 final_answer_pattern(CPD,APD) ==>
9080 CP = odom(occ(C,O),_),
9081 ( ai_observation_is_observed(APP,C) ->
9082 ai_observed_internal(C,O)
9084 ai_not_observed_internal(C,O)
9087 APP = odom([],Set0),
9088 ord_del_element(Set0,C,Set),
9093 ai_observation_lub(NAPP,APD,AP),
9094 final_answer_pattern(CP,AP).
9096 %------------------------------------------------------------------------------%
9098 %------------------------------------------------------------------------------%
9100 call_pattern_worker(CP) <=> chr_error(internal,'AI observation analysis: unexpected abstract state ~w\n',[CP]).
9102 %------------------------------------------------------------------------------%
9103 % Auxiliary Predicates
9104 %------------------------------------------------------------------------------%
9106 ai_observation_lub(odom(AG,S1),odom(AG,S2),odom(AG,S3)) :-
9107 ord_intersection(S1,S2,S3).
9109 ai_observation_bot(AG,AS,odom(AG,AS)).
9111 ai_observation_top(AG,odom(AG,EmptyS)) :-
9114 ai_observation_leq(odom(AG,S1),odom(AG,S2)) :-
9117 ai_observation_observe_set(S,ACSet,NS) :-
9118 ord_subtract(S,ACSet,NS).
9120 ai_observation_abstract_constraint(C,ACs,AC) :-
9125 ai_observation_abstract_constraints(Cs,ACs,NACs) :-
9126 findall(NAC,(member(C,Cs),ai_observation_abstract_constraint(C,ACs,NAC)),NACs).
9128 %------------------------------------------------------------------------------%
9129 % Abstraction of Rule Bodies
9130 %------------------------------------------------------------------------------%
9133 ai_observation_memoed_abstract_goal/2,
9134 ai_observation_memo_abstract_goal/2.
9136 :- chr_option(mode,ai_observation_memoed_abstract_goal(+,+)).
9137 :- chr_option(mode,ai_observation_memo_abstract_goal(+,?)).
9139 ai_observation_memoed_abstract_goal(RuleNb,AG) # ID1 \ ai_observation_memo_abstract_goal(RuleNb,QAG)
9145 rule(RuleNb,Rule) # ID1, abstract_constraints(ACs) # ID2 \ ai_observation_memo_abstract_goal(RuleNb,QAG)
9147 Rule = pragma(rule(H1,H2,Guard,Body),_,_,_,_),
9148 ai_observation_abstract_goal_(H1,H2,Guard,Body,ACs,AG),
9150 ai_observation_memoed_abstract_goal(RuleNb,AG)
9155 ai_observation_abstract_goal_(H1,H2,Guard,G,ACs,AG) :-
9156 % also guard: e.g. b, c(X) ==> Y=X | p(Y).
9157 term_variables((H1,H2,Guard),HVars),
9158 append(H1,H2,Heads),
9159 % variables that are declared to be ground are safe,
9160 ground_vars(Heads,GroundVars),
9161 % so we remove them from the list of 'dangerous' head variables
9162 list_difference_eq(HVars,GroundVars,HV),
9163 ai_observation_abstract_goal(G,ACs,AG,[],HV),!.
9164 % writeln(ai_observation_abstract_goal(G,ACs,AG,[],HV)).
9165 % HV are 'dangerous' variables, all others are fresh and safe
9168 ground_vars([H|Hs],GroundVars) :-
9170 get_constraint_mode(F/A,Mode),
9171 head_info(H,A,_Vars,_Susp,_HeadVars,HeadPairs),
9172 head_arg_matches(HeadPairs,Mode,[],_FirstMatching,_VarDict1,[],GroundVars1),
9173 ground_vars(Hs,GroundVars2),
9174 append(GroundVars1,GroundVars2,GroundVars).
9176 ai_observation_abstract_goal((G1,G2),ACs,List,Tail,HV) :- !, % conjunction
9177 ai_observation_abstract_goal(G1,ACs,List,IntermediateList,HV),
9178 ai_observation_abstract_goal(G2,ACs,IntermediateList,Tail,HV).
9179 ai_observation_abstract_goal((G1;G2),ACs,[(ABranch1;ABranch2)|Tail],Tail,HV) :- !, % disjunction
9180 ai_observation_abstract_goal(G1,ACs,ABranch1,[],HV),
9181 ai_observation_abstract_goal(G2,ACs,ABranch2,[],HV).
9182 ai_observation_abstract_goal((G1->G2),ACs,List,Tail,HV) :- !, % if-then
9183 ai_observation_abstract_goal(G1,ACs,List,IntermediateList,HV),
9184 ai_observation_abstract_goal(G2,ACs,IntermediateList,Tail,HV).
9185 ai_observation_abstract_goal(C,ACs,[AC|Tail],Tail,HV) :-
9186 ai_observation_abstract_constraint(C,ACs,AC), !. % CHR constraint
9187 ai_observation_abstract_goal(true,_,Tail,Tail,_) :- !.
9188 ai_observation_abstract_goal(writeln(_),_,Tail,Tail,_) :- !.
9189 % non-CHR constraint is safe if it only binds fresh variables
9190 ai_observation_abstract_goal(G,_,Tail,Tail,HV) :-
9191 builtin_binds_b(G,Vars),
9192 intersect_eq(Vars,HV,[]),
9194 ai_observation_abstract_goal(G,_,[AG|Tail],Tail,_) :-
9195 AG = builtin. % default case if goal is not recognized/safe
9197 ai_observation_is_observed(odom(_,ACSet),AC) :-
9198 \+ ord_memberchk(AC,ACSet).
9200 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9201 unconditional_occurrence(C,O) :-
9202 get_occurrence(C,O,RuleNb,ID),
9203 get_rule(RuleNb,PRule),
9204 PRule = pragma(ORule,_,_,_,_),
9205 copy_term_nat(ORule,Rule),
9206 Rule = rule(H1,H2,Guard,_),
9207 % writeq(guard_entailment:entails_guard([chr_pp_headvariables(H1,H2)],Guard)),nl,
9208 guard_entailment:entails_guard([chr_pp_headvariables(H1,H2)],Guard),
9210 H1 = [Head], H2 == []
9212 H2 = [Head], H1 == [], \+ may_trigger(C)
9216 unconditional_occurrence_args(Args).
9218 unconditional_occurrence_args([]).
9219 unconditional_occurrence_args([X|Xs]) :-
9222 unconditional_occurrence_args(Xs).
9224 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9226 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9227 % Partial wake analysis
9229 % In a Var = Var unification do not wake up constraints of both variables,
9230 % but rather only those of one variable.
9231 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9233 :- chr_constraint partial_wake_analysis/0.
9234 :- chr_constraint no_partial_wake/1.
9235 :- chr_option(mode,no_partial_wake(+)).
9236 :- chr_constraint wakes_partially/1.
9237 :- chr_option(mode,wakes_partially(+)).
9239 partial_wake_analysis, occurrence(FA,O,RuleNb,ID,Type), rule(RuleNb,Rule), constraint_mode(FA,ArgModes)
9241 Rule = pragma(rule(H1,H2,Guard,Body),_,_,_,_),
9242 ( is_passive(RuleNb,ID) ->
9244 ; Type == simplification ->
9245 select(H,H1,RestH1),
9247 term_variables(Guard,Vars),
9248 partial_wake_args(Args,ArgModes,Vars,FA)
9249 ; % Type == propagation ->
9250 select(H,H2,RestH2),
9252 term_variables(Guard,Vars),
9253 partial_wake_args(Args,ArgModes,Vars,FA)
9256 partial_wake_args([],_,_,_).
9257 partial_wake_args([Arg|Args],[Mode|Modes],Vars,C) :-
9261 ; memberchk_eq(Arg,Vars) ->
9269 partial_wake_args(Args,Modes,Vars,C).
9271 no_partial_wake(C) \ no_partial_wake(C) <=> true.
9273 no_partial_wake(C) \ wakes_partially(C) <=> fail.
9275 wakes_partially(C) <=> true.
9278 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9279 % Generate rules that implement chr_show_store/1 functionality.
9285 % Generates additional rules:
9287 % $show, C1 # ID ==> writeln(C1) pragma passive(ID).
9289 % $show, Cn # ID ==> writeln(Cn) pragma passive(ID).
9292 generate_show_constraint(Constraints0,Constraints,Rules0,Rules) :-
9293 ( chr_pp_flag(show,on) ->
9294 Constraints = ['$show'/0|Constraints0],
9295 generate_show_rules(Constraints0,Rules,[Rule|Rules0]),
9296 inc_rule_count(RuleNb),
9298 rule(['$show'],[],true,true),
9305 Constraints = Constraints0,
9309 generate_show_rules([],Rules,Rules).
9310 generate_show_rules([F/A|Rest],[Rule|Tail],Rules) :-
9312 inc_rule_count(RuleNb),
9314 rule([],['$show',C],true,writeln(C)),
9320 generate_show_rules(Rest,Tail,Rules).
9322 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9323 % Custom supension term layout
9325 static_suspension_term(F/A,Suspension) :-
9326 suspension_term_base(F/A,Base),
9328 functor(Suspension,suspension,Arity).
9330 has_suspension_field(FA,Field) :-
9331 suspension_term_base_fields(FA,Fields),
9332 memberchk(Field,Fields).
9334 suspension_term_base(FA,Base) :-
9335 suspension_term_base_fields(FA,Fields),
9336 length(Fields,Base).
9338 suspension_term_base_fields(FA,Fields) :-
9339 ( chr_pp_flag(debugable,on) ->
9342 % 3. Propagation History
9343 % 4. Generation Number
9344 % 5. Continuation Goal
9346 Fields = [id,state,history,generation,continuation,functor]
9348 ( uses_history(FA) ->
9349 Fields = [id,state,history|Fields2]
9350 ; only_ground_indexed_arguments(FA), get_functional_dependency(FA,1,_,_) ->
9351 Fields = [state|Fields2]
9353 Fields = [id,state|Fields2]
9355 ( only_ground_indexed_arguments(FA) ->
9356 get_store_type(FA,StoreType),
9357 basic_store_types(StoreType,BasicStoreTypes),
9358 ( memberchk(global_ground,BasicStoreTypes) ->
9361 % 3. Propagation History
9362 % 4. Global List Prev
9363 Fields2 = [global_list_prev|Fields3]
9367 % 3. Propagation History
9370 ( chr_pp_flag(ht_removal,on)
9371 -> ht_prev_fields(BasicStoreTypes,Fields3)
9374 ; may_trigger(FA) ->
9377 % 3. Propagation History
9378 ( uses_field(FA,generation) ->
9379 % 4. Generation Number
9380 % 5. Global List Prev
9381 Fields2 = [generation,global_list_prev|Fields3]
9383 Fields2 = [global_list_prev|Fields3]
9385 ( chr_pp_flag(mixed_stores,on),
9386 chr_pp_flag(ht_removal,on)
9387 -> get_store_type(FA,StoreType),
9388 basic_store_types(StoreType,BasicStoreTypes),
9389 ht_prev_fields(BasicStoreTypes,Fields3)
9395 % 3. Propagation History
9396 % 4. Global List Prev
9397 Fields2 = [global_list_prev|Fields3],
9398 ( chr_pp_flag(mixed_stores,on),
9399 chr_pp_flag(ht_removal,on)
9400 -> get_store_type(FA,StoreType),
9401 basic_store_types(StoreType,BasicStoreTypes),
9402 ht_prev_fields(BasicStoreTypes,Fields3)
9408 ht_prev_fields(Stores,Prevs) :-
9409 ht_prev_fields_int(Stores,PrevsList),
9410 append(PrevsList,Prevs).
9411 ht_prev_fields_int([],[]).
9412 ht_prev_fields_int([H|T],Fields) :-
9413 ( H = multi_hash(Indexes)
9414 -> maplist(ht_prev_field,Indexes,FH),
9418 ht_prev_fields_int(T,FT).
9420 ht_prev_field(Index,Field) :-
9422 -> atom_concat('multi_hash_prev-',Index,Field)
9424 -> concat_atom(['multi_hash_prev-'|Index],Field)
9427 get_static_suspension_term_field(FieldName,FA,StaticSuspension,Field) :-
9428 suspension_term_base_fields(FA,Fields),
9429 nth(Index,Fields,FieldName), !,
9430 arg(Index,StaticSuspension,Field).
9431 get_static_suspension_term_field(arguments,FA,StaticSuspension,Field) :- !,
9432 suspension_term_base(FA,Base),
9433 StaticSuspension =.. [_|Args],
9434 drop(Base,Args,Field).
9435 get_static_suspension_term_field(FieldName,FA,_StaticSuspension,_Field) :-
9436 chr_error(internal,'Trying to obtain field ~w of ~w, wich does not have it!',[FieldName,FA]).
9439 get_dynamic_suspension_term_field(FieldName,FA,DynamicSuspension,Field,Goal) :-
9440 suspension_term_base_fields(FA,Fields),
9441 nth(Index,Fields,FieldName), !,
9442 Goal = arg(Index,DynamicSuspension,Field).
9443 get_dynamic_suspension_term_field(arguments,FA,DynamicSuspension,Field,Goal) :- !,
9444 static_suspension_term(FA,StaticSuspension),
9445 get_static_suspension_term_field(arguments,FA,StaticSuspension,Field),
9446 Goal = (DynamicSuspension = StaticSuspension).
9447 get_dynamic_suspension_term_field(argument(I),FA,DynamicSuspension,Field,Goal) :- !,
9448 suspension_term_base(FA,Base),
9450 Goal = arg(Index,DynamicSuspension,Field).
9451 get_dynamic_suspension_term_field(FieldName,FA,_DynamicSuspension,_Field,_Goal) :-
9452 chr_error(internal,'Dynamic goal to get ~w of ~w, which does not have this field!',[FieldName,FA]).
9455 set_dynamic_suspension_term_field(FieldName,FA,DynamicSuspension,Field,Goal) :-
9456 suspension_term_base_fields(FA,Fields),
9457 nth(Index,Fields,FieldName), !,
9458 Goal = setarg(Index,DynamicSuspension,Field).
9459 set_dynamic_suspension_term_field(FieldName,FA,_DynamicSuspension,_Field,_Goal) :-
9460 chr_error(internal,'Dynamic goal to set ~w of ~w, which does not have this field!',[FieldName,FA]).
9462 basic_store_types(multi_store(Types),Types) :- !.
9463 basic_store_types(Type,[Type]).
9465 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9472 :- chr_option(mode,phase_end(+)).
9473 :- chr_option(mode,delay_phase_end(+,?)).
9475 phase_end(Phase) \ delay_phase_end(Phase,Goal) <=> call(Goal).
9476 % phase_end(Phase) <=> true.
9479 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9483 novel_production_call/4.
9485 :- chr_option(mode,uses_history(+)).
9486 :- chr_option(mode,does_use_history(+,+)).
9487 :- chr_option(mode,novel_production_call(+,+,?,?)).
9489 does_use_history(FA,Occ) \ does_use_history(FA,Occ) <=> true.
9490 does_use_history(FA,_) \ uses_history(FA) <=> true.
9491 uses_history(_FA) <=> fail.
9493 does_use_history(FA,Occ) \ novel_production_call(FA,Occ,PossibleGoal,Goal) <=> Goal = PossibleGoal.
9494 novel_production_call(FA,_,_PossibleGoal,Goal) <=> Goal = true.
9500 :- chr_option(mode,uses_field(+,+)).
9501 :- chr_option(mode,does_use_field(+,+)).
9503 does_use_field(FA,Field) \ does_use_field(FA,Field) <=> true.
9504 does_use_field(FA,Field) \ uses_field(FA,Field) <=> true.
9505 uses_field(_FA,_Field) <=> fail.
9510 used_states_known/0.
9512 :- chr_option(mode,uses_state(+,+)).
9513 :- chr_option(mode,if_used_state(+,+,?,?,?)).
9516 % states ::= not_stored_yet | passive | active | triggered | removed
9518 % allocate CREATES not_stored_yet
9519 % remove CHECKS not_stored_yet
9520 % activate CHECKS not_stored_yet
9522 % ==> no allocate THEN no not_stored_yet
9524 % recurs CREATES inactive
9525 % lookup CHECKS inactive
9527 % insert CREATES active
9528 % activate CREATES active
9529 % lookup CHECKS active
9530 % recurs CHECKS active
9532 % runsusp CREATES triggered
9533 % lookup CHECKS triggered
9535 % ==> no runsusp THEN no triggered
9537 % remove CREATES removed
9538 % runsusp CHECKS removed
9539 % lookup CHECKS removed
9540 % recurs CHECKS removed
9542 % ==> no remove THEN no removed
9544 % ==> no allocate, no remove, no active/inactive distinction THEN no state at all...
9546 uses_state(Constraint,State) \ uses_state(Constraint,State) <=> true.
9548 used_states_known, uses_state(Constraint,State) \ if_used_state(Constraint,State,Used,NotUsed,ResultGoal)
9549 <=> ResultGoal = Used.
9550 used_states_known \ if_used_state(Constraint,State,Used,NotUsed,ResultGoal)
9551 <=> ResultGoal = NotUsed.
9553 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9554 % CHECK STOREDNESS ANNOTATIONS AND GENERATE DEFAULT SIMPLIFICATION RULES
9560 % When the programmer enables the `declare_stored_constraints' option, i.e. writes
9562 % :- chr_option(declare_stored_constraints,on).
9564 % the compiler will check for the storedness of constraints.
9566 % By default, the compiler assumes that the programmer wants his constraints to
9567 % be never-stored. Hence, a warning will be issues when a constraint is actually
9570 % Such warnings are suppressed, if the programmer adds the `# stored' modifier
9571 % to a constraint declaration, i.e. writes
9573 % :- chr_constraint c(...) # stored.
9575 % In that case a warning is issued when the constraint is never-stored.
9577 % NOTE: Checking is only performed if `storage_analysis' is on. Otherwise, all
9578 % constraints are stored anyway.
9581 % 2. Rule Generation
9582 % ~~~~~~~~~~~~~~~~~~
9584 % When the programmer enables the `declare_stored_constraints' option, i.e. writes
9586 % :- chr_option(declare_stored_constraints,on).
9588 % the compiler will generate default simplification rules for constraints.
9590 % By default, no default rule is generated for a constraint. However, if the
9591 % programmer writes a default/1 annotation in the constraint declaration, i.e. writes
9593 % :- chr_constraint c(...) # default(Goal).
9595 % where `Goal' is a ground and callable goal (e.g. `true', `fail' or `throw(error)'),
9596 % the compiler generates a rule:
9598 % c(_,...,_) <=> Goal.
9600 % at the end of the program. If multiple default rules are generated, for several constraints,
9601 % then the order of the default rules is not specified.
9604 :- chr_constraint stored_assertion/1.
9605 :- chr_option(mode,stored_assertion(+)).
9606 :- chr_option(type_declaration,stored_assertion(constraint)).
9608 :- chr_constraint never_stored_default/2.
9609 :- chr_option(mode,never_stored_default(+,?)).
9610 :- chr_option(type_declaration,never_stored_default(constraint,any)).
9615 generate_never_stored_rules(Constraints,Rules) :-
9616 ( chr_pp_flag(declare_stored_constraints,on) ->
9617 never_stored_rules(Constraints,Rules)
9622 :- chr_constraint never_stored_rules/2.
9623 :- chr_option(mode,never_stored_rules(+,?)).
9624 :- chr_option(type_declaration,never_stored_rules(list(constraint),any)).
9626 never_stored_rules([],Rules) <=> Rules = [].
9627 never_stored_default(Constraint,Goal) \ never_stored_rules([Constraint|Constraints],Rules) <=>
9630 inc_rule_count(RuleNb),
9632 rule([Head],[],true,Goal),
9638 Rules = [Rule|Tail],
9639 never_stored_rules(Constraints,Tail).
9640 never_stored_rules([_|Constraints],Rules) <=>
9641 never_stored_rules(Constraints,Rules).
9646 check_storedness_assertions(Constraints) :-
9647 ( chr_pp_flag(storage_analysis,on), chr_pp_flag(declare_stored_constraints,on) ->
9648 forall(Constraint,Constraints,check_storedness_assertion(Constraint))
9654 :- chr_constraint check_storedness_assertion/1.
9655 :- chr_option(mode,check_storedness_assertion(+)).
9656 :- chr_option(type_declaration,check_storedness_assertion(constraint)).
9658 check_storedness_assertion(Constraint), stored_assertion(Constraint)
9659 <=> ( is_stored(Constraint) ->
9662 chr_warning(assertion_failed,'Constraint ~w is not stored. However, it was asserted to be stored.\n',[Constraint])
9664 never_stored_default(Constraint,_) \ check_storedness_assertion(Constraint)
9665 <=> ( is_finally_stored(Constraint) ->
9666 chr_warning(assertion_failed,'Constraint ~w is stored. However, it was asserted not to be stored.\n',[Constraint])
9667 ; is_stored(Constraint) ->
9668 chr_warning(assertion_failed,'Constraint ~w is temporarily stored. However, it was asserted not to be stored.\n',[Constraint])
9672 % never-stored, no default goal
9673 check_storedness_assertion(Constraint)
9674 <=> ( is_finally_stored(Constraint) ->
9675 chr_warning(assertion_failed,'Constraint ~w is stored. However, it was asserted not to be stored.\n',[Constraint])
9676 ; is_stored(Constraint) ->
9677 chr_warning(assertion_failed,'Constraint ~w is temporarily stored. However, it was asserted not to be stored.\n',[Constraint])