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)].
172 :- chr_type list == list(any).
174 :- chr_type maybe(T) ---> yes(T) ; no.
176 :- chr_type constraint ---> any / any.
178 :- chr_type module_name == any.
180 :- chr_type pragma_rule ---> pragma(rule,idspair,list(pragma_type),maybe(rule_name),rule_nb).
181 :- chr_type rule ---> rule(list(any),list(any),goal,goal).
182 :- chr_type idspair ---> ids(list(id),list(id)).
184 :- chr_type pragma_type ---> passive(id)
187 ; already_in_heads(id)
189 ; history(history_name,list(id)).
190 :- chr_type history_name== any.
192 :- chr_type rule_name == any.
193 :- chr_type rule_nb == natural.
194 :- chr_type id == natural.
196 :- chr_type goal == any.
198 :- chr_type store_type ---> default
199 ; multi_store(list(store_type))
200 ; multi_hash(list(list(int)))
201 ; multi_inthash(list(list(int)))
204 % EXPERIMENTAL STORES
205 ; atomic_constants(list(int),list(any),atomic_coverage)
206 ; ground_constants(list(int),list(any))
207 ; var_assoc_store(int,list(int))
208 ; identifier_store(int)
209 ; type_indexed_identifier_store(int,any).
210 :- chr_type atomic_coverage ---> complete ; incomplete.
212 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
214 %------------------------------------------------------------------------------%
215 :- chr_constraint chr_source_file/1.
216 :- chr_option(mode,chr_source_file(+)).
217 :- chr_option(type_declaration,chr_source_file(module_name)).
218 %------------------------------------------------------------------------------%
219 chr_source_file(_) \ chr_source_file(_) <=> true.
221 %------------------------------------------------------------------------------%
222 :- chr_constraint get_chr_source_file/1.
223 :- chr_option(mode,get_chr_source_file(-)).
224 :- chr_option(type_declaration,get_chr_source_file(module_name)).
225 %------------------------------------------------------------------------------%
226 chr_source_file(Mod) \ get_chr_source_file(Query)
228 get_chr_source_file(Query)
232 %------------------------------------------------------------------------------%
233 :- chr_constraint target_module/1.
234 :- chr_option(mode,target_module(+)).
235 :- chr_option(type_declaration,target_module(module_name)).
236 %------------------------------------------------------------------------------%
237 target_module(_) \ target_module(_) <=> true.
239 %------------------------------------------------------------------------------%
240 :- chr_constraint get_target_module/1.
241 :- chr_option(mode,get_target_module(-)).
242 :- chr_option(type_declaration,get_target_module(module_name)).
243 %------------------------------------------------------------------------------%
244 target_module(Mod) \ get_target_module(Query)
246 get_target_module(Query)
249 %------------------------------------------------------------------------------%
250 :- chr_constraint line_number/2.
251 :- chr_option(mode,line_number(+,+)).
252 %------------------------------------------------------------------------------%
253 line_number(RuleNb,LineNb) \ line_number(RuleNb,LineNumber) <=> true.
255 %------------------------------------------------------------------------------%
256 :- chr_constraint get_line_number/2.
257 :- chr_option(mode,get_line_number(+,-)).
258 %------------------------------------------------------------------------------%
259 line_number(RuleNb,LineNb) \ get_line_number(RuleNb,Q) <=> Q = LineNb.
260 get_line_number(RuleNb,Q) <=> Q = 0. % no line number available
262 :- chr_constraint indexed_argument/2. % argument instantiation may enable applicability of rule
263 :- chr_option(mode,indexed_argument(+,+)).
264 :- chr_option(type_declaration,indexed_argument(constraint,int)).
266 :- chr_constraint is_indexed_argument/2.
267 :- chr_option(mode,is_indexed_argument(+,+)).
268 :- chr_option(type_declaration,is_indexed_argument(constraint,int)).
270 :- chr_constraint constraint_mode/2.
271 :- chr_option(mode,constraint_mode(+,+)).
272 :- chr_option(type_declaration,constraint_mode(constraint,list)).
274 :- chr_constraint get_constraint_mode/2.
275 :- chr_option(mode,get_constraint_mode(+,-)).
276 :- chr_option(type_declaration,get_constraint_mode(constraint,list)).
278 :- chr_constraint may_trigger/1.
279 :- chr_option(mode,may_trigger(+)).
280 :- chr_option(type_declaration,may_trigger(constraint)).
282 :- chr_constraint only_ground_indexed_arguments/1.
283 :- chr_option(mode,only_ground_indexed_arguments(+)).
284 :- chr_option(type_declaration,only_ground_indexed_arguments(constraint)).
286 :- chr_constraint none_suspended_on_variables/0.
288 :- chr_constraint are_none_suspended_on_variables/0.
290 :- chr_constraint store_type/2.
291 :- chr_option(mode,store_type(+,+)).
292 :- chr_option(type_declaration,store_type(constraint,store_type)).
294 :- chr_constraint get_store_type/2.
295 :- chr_option(mode,get_store_type(+,?)).
296 :- chr_option(type_declaration,get_store_type(constraint,store_type)).
298 :- chr_constraint update_store_type/2.
299 :- chr_option(mode,update_store_type(+,+)).
300 :- chr_option(type_declaration,update_store_type(constraint,store_type)).
302 :- chr_constraint actual_store_types/2.
303 :- chr_option(mode,actual_store_types(+,+)).
304 :- chr_option(type_declaration,actual_store_types(constraint,list(store_type))).
306 :- chr_constraint assumed_store_type/2.
307 :- chr_option(mode,assumed_store_type(+,+)).
308 :- chr_option(type_declaration,assumed_store_type(constraint,store_type)).
310 :- chr_constraint validate_store_type_assumption/1.
311 :- chr_option(mode,validate_store_type_assumption(+)).
312 :- chr_option(type_declaration,validate_store_type_assumption(constraint)).
314 :- chr_constraint rule_count/1.
315 :- chr_option(mode,rule_count(+)).
316 :- chr_option(type_declaration,rule_count(natural)).
318 :- chr_constraint inc_rule_count/1.
319 :- chr_option(mode,inc_rule_count(-)).
320 :- chr_option(type_declaration,inc_rule_count(natural)).
322 rule_count(_) \ rule_count(_)
324 rule_count(C), inc_rule_count(NC)
325 <=> NC is C + 1, rule_count(NC).
327 <=> NC = 1, rule_count(NC).
329 :- chr_constraint passive/2.
330 :- chr_option(mode,passive(+,+)).
332 :- chr_constraint is_passive/2.
333 :- chr_option(mode,is_passive(+,+)).
335 :- chr_constraint any_passive_head/1.
336 :- chr_option(mode,any_passive_head(+)).
338 :- chr_constraint new_occurrence/4.
339 :- chr_option(mode,new_occurrence(+,+,+,+)).
341 :- chr_constraint occurrence/5.
342 :- chr_option(mode,occurrence(+,+,+,+,+)).
343 :- chr_type occurrence_type ---> simplification ; propagation.
344 :- chr_option(type_declaration,occurrence(any,any,any,any,occurrence_type)).
346 :- chr_constraint get_occurrence/4.
347 :- chr_option(mode,get_occurrence(+,+,-,-)).
349 :- chr_constraint get_occurrence_from_id/4.
350 :- chr_option(mode,get_occurrence_from_id(+,-,+,+)).
352 :- chr_constraint max_occurrence/2.
353 :- chr_option(mode,max_occurrence(+,+)).
355 :- chr_constraint get_max_occurrence/2.
356 :- chr_option(mode,get_max_occurrence(+,-)).
358 :- chr_constraint allocation_occurrence/2.
359 :- chr_option(mode,allocation_occurrence(+,+)).
361 :- chr_constraint get_allocation_occurrence/2.
362 :- chr_option(mode,get_allocation_occurrence(+,-)).
364 :- chr_constraint rule/2.
365 :- chr_option(mode,rule(+,+)).
366 :- chr_option(type_declaration,rule(rule_nb,pragma_rule)).
368 :- chr_constraint get_rule/2.
369 :- chr_option(mode,get_rule(+,-)).
370 :- chr_option(type_declaration,get_rule(int,pragma_rule)).
372 :- chr_constraint least_occurrence/2.
373 :- chr_option(mode,least_occurrence(+,+)).
374 :- chr_option(type_declaration,least_occurrence(any,list)).
376 :- chr_constraint is_least_occurrence/1.
377 :- chr_option(mode,is_least_occurrence(+)).
380 indexed_argument(FA,I) \ indexed_argument(FA,I) <=> true.
381 indexed_argument(FA,I) \ is_indexed_argument(FA,I) <=> true.
382 is_indexed_argument(_,_) <=> fail.
384 %%% C O N S T R A I N T M O D E %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
386 constraint_mode(FA,_) \ constraint_mode(FA,_) <=> true.
387 constraint_mode(FA,Mode) \ get_constraint_mode(FA,Q) <=>
389 get_constraint_mode(FA,Q) <=>
393 %%% M A Y T R I G G E R %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
395 may_trigger(FA) <=> \+ has_active_occurrence(FA) | fail.
396 constraint_mode(FA,Mode), indexed_argument(FA,I) \ may_trigger(FA) <=>
400 may_trigger(FA) <=> chr_pp_flag(debugable,on). % in debug mode, we assume everything can be triggered
402 constraint_mode(FA,Mode), indexed_argument(FA,I) \ only_ground_indexed_arguments(FA)
408 only_ground_indexed_arguments(_) <=>
411 none_suspended_on_variables \ none_suspended_on_variables <=> true.
412 none_suspended_on_variables \ are_none_suspended_on_variables <=> true.
413 are_none_suspended_on_variables <=> fail.
414 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
416 store_type(FA,StoreType)
417 ==> chr_pp_flag(verbose,on)
418 | chr_info(verbose,'Storetype of ~w is ~w.\n',[FA,StoreType]).
420 store_type(FA,Store) \ get_store_type(FA,Query)
423 assumed_store_type(FA,Store) \ get_store_type(FA,Query)
425 get_store_type(_,Query)
428 actual_store_types(C,STs) \ update_store_type(C,ST)
429 <=> member(ST,STs) | true.
430 update_store_type(C,ST), actual_store_types(C,STs)
432 actual_store_types(C,[ST|STs]).
433 update_store_type(C,ST)
435 actual_store_types(C,[ST]).
437 % refine store type assumption
438 validate_store_type_assumption(C) \ actual_store_types(C,STs), actual_atomic_multi_hash_keys(C,Index,Keys)
440 delete(STs,multi_hash([Index]),STs0),
442 ( get_constraint_type(C,Types),
443 nth1(IndexPos,Types,Type),
444 enumerated_atomic_type(Type,Atoms),
446 Completeness = complete
448 Completeness = incomplete
450 actual_store_types(C,[atomic_constants(Index,Keys,Completeness)|STs0]).
451 validate_store_type_assumption(C) \ actual_store_types(C,STs), actual_ground_multi_hash_keys(C,Index,Keys)
453 delete(STs,multi_hash([Index]),STs0),
454 actual_store_types(C,[ground_constants(Index,Keys)|STs0]).
455 validate_store_type_assumption(C) \ actual_store_types(C,STs)
457 memberchk(multi_hash([[Index]]),STs),
458 get_constraint_type(C,Types),
459 nth1(Index,Types,Type),
460 enumerated_atomic_type(Type,Atoms)
462 delete(STs,multi_hash([[Index]]),STs0),
463 actual_store_types(C,[atomic_constants([Index],Atoms,complete)|STs0]).
464 validate_store_type_assumption(C), actual_store_types(C,STs), assumed_store_type(C,_) % automatic assumption
466 ( ( STs = [ground_constants(_,_)] ; STs = [atomic_constants(_,_,incomplete)]) ->
467 store_type(C,multi_store([global_ground|STs]))
469 store_type(C,multi_store(STs))
471 validate_store_type_assumption(C), actual_store_types(C,STs), store_type(C,_) % user assumption
473 store_type(C,multi_store(STs)).
474 validate_store_type_assumption(C), assumed_store_type(C,_) % no lookups on constraint in debug mode
476 chr_pp_flag(debugable,on)
478 store_type(C,default).
479 validate_store_type_assumption(C), assumed_store_type(C,_) % no lookups on constraint
480 <=> store_type(C,global_ground).
481 validate_store_type_assumption(C)
484 %%% P A S S I V E %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
485 passive(R,ID) \ passive(R,ID) <=> true.
487 passive(RuleNb,ID) \ is_passive(RuleNb,ID) <=> true.
488 is_passive(_,_) <=> fail.
490 passive(RuleNb,_) \ any_passive_head(RuleNb)
494 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
496 max_occurrence(C,N) \ max_occurrence(C,M)
499 max_occurrence(C,MO), new_occurrence(C,RuleNb,ID,Type) <=>
501 occurrence(C,NO,RuleNb,ID,Type),
502 max_occurrence(C,NO).
503 new_occurrence(C,RuleNb,ID,_) <=>
504 chr_error(internal,'new_occurrence: missing max_occurrence for ~w in rule ~w\n',[C,RuleNb]).
506 max_occurrence(C,MON) \ get_max_occurrence(C,Q)
508 get_max_occurrence(C,Q)
509 <=> chr_error(internal,'get_max_occurrence: missing max occurrence for ~w\n',[C]).
511 occurrence(C,ON,Rule,ID,_) \ get_occurrence(C,ON,QRule,QID)
512 <=> Rule = QRule, ID = QID.
513 get_occurrence(C,O,_,_)
514 <=> chr_error(internal,'get_occurrence: missing occurrence ~w:~w\n',[C,O]).
516 occurrence(C,ON,Rule,ID,_) \ get_occurrence_from_id(QC,QON,Rule,ID)
517 <=> QC = C, QON = ON.
518 get_occurrence_from_id(C,O,_,_)
519 <=> chr_error(internal,'get_occurrence_from_id: missing occurrence ~w:~w\n',[]).
521 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
524 late_allocation_analysis(Cs) :-
525 ( chr_pp_flag(late_allocation,on) ->
526 maplist(late_allocation, Cs)
531 late_allocation(C) :- late_allocation(C,0).
532 late_allocation(C,O) :- allocation_occurrence(C,O), !.
533 late_allocation(C,O) :- NO is O + 1, late_allocation(C,NO).
535 % A L L O C C A T I O N O C C U R R E N C E %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
537 allocation_occurrence(C,0) ==> stored_in_guard_before_next_kept_occurrence(C,0).
539 rule(RuleNb,Rule), occurrence(C,O,RuleNb,Id,Type), allocation_occurrence(C,O) ==>
540 \+ is_passive(RuleNb,Id),
542 ( stored_in_guard_before_next_kept_occurrence(C,O) ->
544 ; Rule = pragma(rule([_|_],_,_,_),_,_,_,_) -> % simpagation rule
546 ; is_least_occurrence(RuleNb) -> % propagation rule
552 stored_in_guard_before_next_kept_occurrence(C,O) :-
553 chr_pp_flag(store_in_guards, on),
555 stored_in_guard_lookahead(C,NO).
557 :- chr_constraint stored_in_guard_lookahead/2.
558 :- chr_option(mode, stored_in_guard_lookahead(+,+)).
560 occurrence(C,O,RuleNb,Id,_), passive(RuleNb,Id) \ stored_in_guard_lookahead(C,O) <=>
561 NO is O + 1, stored_in_guard_lookahead(C,NO).
562 occurrence(C,O,RuleNb,Id,Type) \ stored_in_guard_lookahead(C,O) <=>
563 Type == simplification,
564 ( is_stored_in_guard(C,RuleNb) ->
567 NO is O + 1, stored_in_guard_lookahead(C,NO)
569 stored_in_guard_lookahead(_,_) <=> fail.
572 rule(RuleNb,Rule), occurrence(C,O,RuleNb,ID,_), allocation_occurrence(C,AO)
573 \ least_occurrence(RuleNb,[ID|IDs])
574 <=> AO >= O, \+ may_trigger(C) |
575 least_occurrence(RuleNb,IDs).
576 rule(RuleNb,Rule), passive(RuleNb,ID)
577 \ least_occurrence(RuleNb,[ID|IDs])
578 <=> least_occurrence(RuleNb,IDs).
581 ==> Rule = pragma(rule([],_,_,_),ids([],IDs),_,_,_) |
582 least_occurrence(RuleNb,IDs).
584 least_occurrence(RuleNb,[]) \ is_least_occurrence(RuleNb)
586 is_least_occurrence(_)
589 allocation_occurrence(C,O) \ get_allocation_occurrence(C,Q)
591 get_allocation_occurrence(_,Q)
592 <=> chr_pp_flag(late_allocation,off), Q=0.
593 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
595 rule(RuleNb,Rule) \ get_rule(RuleNb,Q)
600 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
602 %%% C O N S T R A I N T I N D E X %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
604 % Default store constraint index assignment.
606 :- chr_constraint constraint_index/2. % constraint_index(F/A,DefaultStoreAndAttachedIndex)
607 :- chr_option(mode,constraint_index(+,+)).
608 :- chr_option(type_declaration,constraint_index(constraint,int)).
610 :- chr_constraint get_constraint_index/2.
611 :- chr_option(mode,get_constraint_index(+,-)).
612 :- chr_option(type_declaration,get_constraint_index(constraint,int)).
614 :- chr_constraint get_indexed_constraint/2.
615 :- chr_option(mode,get_indexed_constraint(+,-)).
616 :- chr_option(type_declaration,get_indexed_constraint(int,constraint)).
618 :- chr_constraint max_constraint_index/1. % max_constraint_index(MaxDefaultStoreAndAttachedIndex)
619 :- chr_option(mode,max_constraint_index(+)).
620 :- chr_option(type_declaration,max_constraint_index(int)).
622 :- chr_constraint get_max_constraint_index/1.
623 :- chr_option(mode,get_max_constraint_index(-)).
624 :- chr_option(type_declaration,get_max_constraint_index(int)).
626 constraint_index(C,Index) \ get_constraint_index(C,Query)
628 get_constraint_index(C,Query)
631 constraint_index(C,Index) \ get_indexed_constraint(Index,Q)
633 get_indexed_constraint(Index,Q)
636 max_constraint_index(Index) \ get_max_constraint_index(Query)
638 get_max_constraint_index(Query)
641 set_constraint_indices(Constraints) :-
642 set_constraint_indices(Constraints,1).
643 set_constraint_indices([],M) :-
645 max_constraint_index(N).
646 set_constraint_indices([C|Cs],N) :-
647 ( ( chr_pp_flag(debugable, on) ; \+ only_ground_indexed_arguments(C), is_stored(C) ; is_stored(C), get_store_type(C,default)
648 ; get_store_type(C,var_assoc_store(_,_))) ->
649 constraint_index(C,N),
651 set_constraint_indices(Cs,M)
653 set_constraint_indices(Cs,N)
656 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
659 :- chr_constraint identifier_size/1.
660 :- chr_option(mode,identifier_size(+)).
661 :- chr_option(type_declaration,identifier_size(natural)).
663 identifier_size(_) \ identifier_size(_)
667 :- chr_constraint get_identifier_size/1.
668 :- chr_option(mode,get_identifier_size(-)).
669 :- chr_option(type_declaration,get_identifier_size(natural)).
671 identifier_size(Size) \ get_identifier_size(Q)
675 get_identifier_size(Q)
679 :- chr_constraint identifier_index/3.
680 :- chr_option(mode,identifier_index(+,+,+)).
681 :- chr_option(type_declaration,identifier_index(constraint,natural,natural)).
683 identifier_index(C,I,_) \ identifier_index(C,I,_)
687 :- chr_constraint get_identifier_index/3.
688 :- chr_option(mode,get_identifier_index(+,+,-)).
689 :- chr_option(type_declaration,get_identifier_index(constraint,natural,natural)).
691 identifier_index(C,I,II) \ get_identifier_index(C,I,Q)
694 identifier_size(Size), get_identifier_index(C,I,Q)
697 identifier_index(C,I,NSize),
698 identifier_size(NSize),
700 get_identifier_index(C,I,Q)
702 identifier_index(C,I,2),
706 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
707 % Type Indexed Identifier Indexes
709 :- chr_constraint type_indexed_identifier_size/2.
710 :- chr_option(mode,type_indexed_identifier_size(+,+)).
711 :- chr_option(type_declaration,type_indexed_identifier_size(any,natural)).
713 type_indexed_identifier_size(IndexType,_) \ type_indexed_identifier_size(IndexType,_)
717 :- chr_constraint get_type_indexed_identifier_size/2.
718 :- chr_option(mode,get_type_indexed_identifier_size(+,-)).
719 :- chr_option(type_declaration,get_type_indexed_identifier_size(any,natural)).
721 type_indexed_identifier_size(IndexType,Size) \ get_type_indexed_identifier_size(IndexType,Q)
725 get_type_indexed_identifier_size(IndexType,Q)
729 :- chr_constraint type_indexed_identifier_index/4.
730 :- chr_option(mode,type_indexed_identifier_index(+,+,+,+)).
731 :- chr_option(type_declaration,type_indexed_identifier_index(any,constraint,natural,natural)).
733 type_indexed_identifier_index(_,C,I,_) \ type_indexed_identifier_index(_,C,I,_)
737 :- chr_constraint get_type_indexed_identifier_index/4.
738 :- chr_option(mode,get_type_indexed_identifier_index(+,+,+,-)).
739 :- chr_option(type_declaration,get_type_indexed_identifier_index(any,constraint,natural,natural)).
741 type_indexed_identifier_index(IndexType,C,I,II) \ get_type_indexed_identifier_index(IndexType,C,I,Q)
744 type_indexed_identifier_size(IndexType,Size), get_type_indexed_identifier_index(IndexType,C,I,Q)
747 type_indexed_identifier_index(IndexType,C,I,NSize),
748 type_indexed_identifier_size(IndexType,NSize),
750 get_type_indexed_identifier_index(IndexType,C,I,Q)
752 type_indexed_identifier_index(IndexType,C,I,2),
753 type_indexed_identifier_size(IndexType,2),
756 type_indexed_identifier_structure(IndexType,Structure) :-
757 type_indexed_identifier_name(IndexType,type_indexed_identifier_struct,Functor),
758 get_type_indexed_identifier_size(IndexType,Arity),
759 functor(Structure,Functor,Arity).
760 type_indexed_identifier_name(IndexType,Prefix,Name) :-
762 IndexTypeName = IndexType
764 term_to_atom(IndexType,IndexTypeName)
766 atom_concat_list([Prefix,'_',IndexTypeName],Name).
768 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
773 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
777 chr_translate(Declarations,NewDeclarations) :-
778 chr_translate_line_info(Declarations,'bootstrap',NewDeclarations).
780 chr_translate_line_info(Declarations,File,NewDeclarations) :-
781 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',[]),
783 chr_source_file(File),
784 partition_clauses(Declarations,Constraints0,Rules0,OtherClauses),
785 chr_compiler_options:sanity_check,
786 check_declared_constraints(Constraints0),
787 generate_show_constraint(Constraints0,Constraints,Rules0,Rules1),
788 add_constraints(Constraints),
790 generate_never_stored_rules(Constraints,NewRules),
792 append(Rules1,NewRules,Rules),
794 check_rules(Rules,Constraints),
795 time('type checking',chr_translate:static_type_check),
796 add_occurrences(Rules),
797 time('functional dependency',chr_translate:functional_dependency_analysis(Rules)),
798 time('set semantics',chr_translate:set_semantics_rules(Rules)),
799 time('symmetry analysis',chr_translate:symmetry_analysis(Rules)),
800 time('guard simplification',chr_translate:guard_simplification),
801 time('late storage',chr_translate:storage_analysis(Constraints)),
802 time('observation',chr_translate:observation_analysis(Constraints)),
803 time('ai observation',chr_translate:ai_observation_analysis(Constraints)),
804 time('late allocation',chr_translate:late_allocation_analysis(Constraints)),
805 partial_wake_analysis,
806 time('assume constraint stores',chr_translate:assume_constraint_stores(Constraints)),
807 time('default constraint indices',chr_translate:set_constraint_indices(Constraints)),
808 time('check storedness assertions',chr_translate:check_storedness_assertions(Constraints)),
810 time('constraint code generation',chr_translate:constraints_code(Constraints,ConstraintClauses)),
811 time('validate store assumptions',chr_translate:validate_store_type_assumptions(Constraints)),
812 phase_end(validate_store_type_assumptions),
814 time('store code generation',chr_translate:store_management_preds(Constraints,StoreClauses)), % depends on actual code used
815 insert_declarations(OtherClauses, Clauses0),
816 chr_module_declaration(CHRModuleDeclaration),
817 append([StoreClauses,ConstraintClauses,CHRModuleDeclaration,[end_of_file]],StuffyGeneratedClauses),
818 clean_clauses(StuffyGeneratedClauses,GeneratedClauses),
819 append([Clauses0,GeneratedClauses], NewDeclarations).
821 store_management_preds(Constraints,Clauses) :-
822 generate_attach_detach_a_constraint_all(Constraints,AttachAConstraintClauses),
823 generate_attr_unify_hook(AttrUnifyHookClauses),
824 generate_attach_increment(AttachIncrementClauses),
825 generate_extra_clauses(Constraints,ExtraClauses),
826 generate_insert_delete_constraints(Constraints,DeleteClauses),
827 generate_attach_code(Constraints,StoreClauses),
828 generate_counter_code(CounterClauses),
829 generate_dynamic_type_check_clauses(TypeCheckClauses),
830 append([AttachAConstraintClauses
831 ,AttachIncrementClauses
832 ,AttrUnifyHookClauses
842 insert_declarations(Clauses0, Clauses) :-
843 findall(:- use_module(chr(Module)),(auxiliary_module(Module), is_used_auxiliary_module(Module)),Decls),
844 append(Clauses0, [:- use_module(chr(chr_runtime))|Decls], Clauses).
846 auxiliary_module(chr_hashtable_store).
847 auxiliary_module(chr_integertable_store).
848 auxiliary_module(chr_assoc_store).
850 generate_counter_code(Clauses) :-
851 ( chr_pp_flag(store_counter,on) ->
853 ('$counter_init'(N1) :- nb_setval(N1,0)) ,
854 ('$counter'(N2,X1) :- nb_getval(N2,X1)),
855 ('$counter_inc'(N) :- nb_getval(N,X), Y is X + 1, nb_setval(N,Y)),
856 (:- '$counter_init'('$insert_counter')),
857 (:- '$counter_init'('$delete_counter')),
858 ('$insert_counter_inc' :- '$counter_inc'('$insert_counter')),
859 ('$delete_counter_inc' :- '$counter_inc'('$delete_counter')),
860 ( counter_stats(I,D) :- '$counter'('$insert_counter',I),'$counter'('$delete_counter',D))
866 % for systems with multifile declaration
867 chr_module_declaration(CHRModuleDeclaration) :-
868 get_target_module(Mod),
869 ( Mod \== chr_translate, chr_pp_flag(toplevel_show_store,on) ->
870 CHRModuleDeclaration = [
871 (:- multifile chr:'$chr_module'/1),
872 chr:'$chr_module'(Mod)
875 CHRModuleDeclaration = []
879 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
881 %% Partitioning of clauses into constraint declarations, chr rules and other
884 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
885 %% partition_clauses(+Clauses,-ConstraintDeclarations,-Rules,-OtherClauses) is det.
886 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
887 partition_clauses([],[],[],[]).
888 partition_clauses([Clause|Clauses],ConstraintDeclarations,Rules,OtherClauses) :-
889 ( parse_rule(Clause,Rule) ->
890 ConstraintDeclarations = RestConstraintDeclarations,
891 Rules = [Rule|RestRules],
892 OtherClauses = RestOtherClauses
893 ; is_declaration(Clause,ConstraintDeclaration) ->
894 append(ConstraintDeclaration,RestConstraintDeclarations,ConstraintDeclarations),
896 OtherClauses = RestOtherClauses
897 ; is_module_declaration(Clause,Mod) ->
899 ConstraintDeclarations = RestConstraintDeclarations,
901 OtherClauses = [Clause|RestOtherClauses]
902 ; is_type_definition(Clause) ->
903 ConstraintDeclarations = RestConstraintDeclarations,
905 OtherClauses = RestOtherClauses
906 ; Clause = (handler _) ->
907 chr_warning(deprecated(Clause),'Backward compatibility: ignoring handler/1 declaration.\n',[]),
908 ConstraintDeclarations = RestConstraintDeclarations,
910 OtherClauses = RestOtherClauses
911 ; Clause = (rules _) ->
912 chr_warning(deprecated(Clause),'Backward compatibility: ignoring rules/1 declaration.\n',[]),
913 ConstraintDeclarations = RestConstraintDeclarations,
915 OtherClauses = RestOtherClauses
916 ; Clause = option(OptionName,OptionValue) ->
917 chr_warning(deprecated(Clause),'Instead use `:-chr_option(~w,~w).\'\n',[OptionName,OptionValue]),
918 handle_option(OptionName,OptionValue),
919 ConstraintDeclarations = RestConstraintDeclarations,
921 OtherClauses = RestOtherClauses
922 ; Clause = (:-chr_option(OptionName,OptionValue)) ->
923 handle_option(OptionName,OptionValue),
924 ConstraintDeclarations = RestConstraintDeclarations,
926 OtherClauses = RestOtherClauses
927 ; Clause = ('$chr_compiled_with_version'(_)) ->
928 ConstraintDeclarations = RestConstraintDeclarations,
930 OtherClauses = ['$chr_compiled_with_version'(3)|RestOtherClauses]
931 ; ConstraintDeclarations = RestConstraintDeclarations,
933 OtherClauses = [Clause|RestOtherClauses]
935 partition_clauses(Clauses,RestConstraintDeclarations,RestRules,RestOtherClauses).
937 '$chr_compiled_with_version'(2).
939 is_declaration(D, Constraints) :- %% constraint declaration
940 ( D = (:- Decl), Decl =.. [F,Cs], F == (chr_constraint) ->
941 conj2list(Cs,Constraints0)
944 Decl =.. [constraints,Cs]
946 D =.. [constraints,Cs]
948 conj2list(Cs,Constraints0),
949 chr_warning(deprecated(D),'Instead use :- chr_constraint ~w.\n',[Cs])
951 extract_type_mode(Constraints0,Constraints).
953 extract_type_mode([],[]).
954 extract_type_mode([F/A|R],[F/A|R2]) :- !,extract_type_mode(R,R2).
955 extract_type_mode([C0|R],[ConstraintSymbol|R2]) :-
956 ( C0 = C # Annotation ->
958 extract_annotation(Annotation,F/A)
963 ConstraintSymbol = F/A,
965 extract_types_and_modes(Args,ArgTypes,ArgModes),
966 constraint_type(ConstraintSymbol,ArgTypes),
967 constraint_mode(ConstraintSymbol,ArgModes),
968 extract_type_mode(R,R2).
970 extract_annotation(stored,Symbol) :-
971 stored_assertion(Symbol).
972 extract_annotation(default(Goal),Symbol) :-
973 never_stored_default(Symbol,Goal).
975 extract_types_and_modes([],[],[]).
976 extract_types_and_modes([X|R],[T|R2],[M|R3]) :-
977 extract_type_and_mode(X,T,M),
978 extract_types_and_modes(R,R2,R3).
980 extract_type_and_mode(+(T),T,(+)) :- !.
981 extract_type_and_mode(?(T),T,(?)) :- !.
982 extract_type_and_mode(-(T),T,(-)) :- !.
983 extract_type_and_mode((+),any,(+)) :- !.
984 extract_type_and_mode((?),any,(?)) :- !.
985 extract_type_and_mode((-),any,(-)) :- !.
986 extract_type_and_mode(Illegal,_,_) :-
987 chr_error(syntax(Illegal),'Illegal mode/type declaration.\n\tCorrect syntax is +type, -type or ?type\n\tor +, - or ?.\n',[]).
989 is_type_definition(Declaration) :-
990 ( Declaration = (:- TDef) ->
995 TDef =.. [chr_type,TypeDef],
996 ( TypeDef = (Name ---> Def) ->
997 tdisj2list(Def,DefList),
998 type_definition(Name,DefList)
999 ; TypeDef = (Alias == Name) ->
1000 type_alias(Alias,Name)
1002 type_definition(TypeDef,[]),
1003 chr_warning(syntax,'Empty type definition `~w\'.\nAre you sure you want to declare a phantom type?\n',[Declaration])
1006 %% tdisj2list(+Goal,-ListOfGoals) is det.
1008 % no removal of fails, e.g. :- type bool ---> true ; fail.
1009 tdisj2list(Conj,L) :-
1010 tdisj2list(Conj,L,[]).
1012 tdisj2list(Conj,L,T) :-
1014 tdisj2list(G1,L,T1),
1015 tdisj2list(G2,T1,T).
1016 tdisj2list(G,[G | T],T).
1019 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
1020 %% parse_rule(+term,-pragma_rule) is semidet.
1021 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
1022 parse_rule(RI,R) :- %% name @ rule
1023 RI = (Name @ RI2), !,
1024 rule(RI2,yes(Name),R).
1028 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
1029 %% parse_rule(+term,-pragma_rule) is semidet.
1030 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
1032 RI = (RI2 pragma P), !, %% pragmas
1034 Ps = [_] % intercept variable
1038 inc_rule_count(RuleCount),
1039 R = pragma(R1,IDs,Ps,Name,RuleCount),
1040 is_rule(RI2,R1,IDs,R).
1042 inc_rule_count(RuleCount),
1043 R = pragma(R1,IDs,[],Name,RuleCount),
1044 is_rule(RI,R1,IDs,R).
1046 is_rule(RI,R,IDs,RC) :- %% propagation rule
1048 conj2list(H,Head2i),
1049 get_ids(Head2i,IDs2,Head2,RC),
1052 R = rule([],Head2,G,RB)
1054 R = rule([],Head2,true,B)
1056 is_rule(RI,R,IDs,RC) :- %% simplification/simpagation rule
1065 conj2list(H1,Head2i),
1066 conj2list(H2,Head1i),
1067 get_ids(Head2i,IDs2,Head2,0,N,RC),
1068 get_ids(Head1i,IDs1,Head1,N,_,RC),
1069 IDs = ids(IDs1,IDs2)
1070 ; conj2list(H,Head1i),
1072 get_ids(Head1i,IDs1,Head1,RC),
1075 R = rule(Head1,Head2,Guard,Body).
1077 get_ids(Cs,IDs,NCs,RC) :-
1078 get_ids(Cs,IDs,NCs,0,_,RC).
1080 get_ids([],[],[],N,N,_).
1081 get_ids([C|Cs],[N|IDs],[NC|NCs],N,NN,RC) :-
1086 check_direct_pragma(N1,N,RC)
1092 get_ids(Cs,IDs,NCs, M,NN,RC).
1094 check_direct_pragma(passive,Id,PragmaRule) :- !,
1095 PragmaRule = pragma(_,_,_,_,RuleNb),
1097 check_direct_pragma(Abbrev,Id,PragmaRule) :-
1098 ( direct_pragma(FullPragma),
1099 atom_concat(Abbrev,Remainder,FullPragma) ->
1100 chr_warning(problem_pragma(Abbrev,PragmaRule),'completed `~w\' to `~w\'\n',[Abbrev,FullPragma])
1102 chr_warning(unsupported_pragma(Abbrev,PragmaRule),'',[])
1105 direct_pragma(passive).
1107 is_module_declaration((:- module(Mod)),Mod).
1108 is_module_declaration((:- module(Mod,_)),Mod).
1110 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1112 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1114 add_constraints([]).
1115 add_constraints([C|Cs]) :-
1116 max_occurrence(C,0),
1120 constraint_mode(C,Mode),
1121 add_constraints(Cs).
1125 add_rules([Rule|Rules]) :-
1126 Rule = pragma(_,_,_,_,RuleNb),
1130 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1132 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1133 %% Some input verification:
1135 check_declared_constraints(Constraints) :-
1136 check_declared_constraints(Constraints,[]).
1138 check_declared_constraints([],_).
1139 check_declared_constraints([C|Cs],Acc) :-
1140 ( memberchk_eq(C,Acc) ->
1141 chr_error(syntax(C),'Constraint multiply defined: ~w.\n\tRemove redundant declaration!\n',[C])
1145 check_declared_constraints(Cs,[C|Acc]).
1147 %% - all constraints in heads are declared constraints
1148 %% - all passive pragmas refer to actual head constraints
1151 check_rules([PragmaRule|Rest],Decls) :-
1152 check_rule(PragmaRule,Decls),
1153 check_rules(Rest,Decls).
1155 check_rule(PragmaRule,Decls) :-
1156 check_rule_indexing(PragmaRule),
1157 check_trivial_propagation_rule(PragmaRule),
1158 PragmaRule = pragma(Rule,_IDs,Pragmas,_Name,_N),
1159 Rule = rule(H1,H2,_,_),
1160 append(H1,H2,HeadConstraints),
1161 check_head_constraints(HeadConstraints,Decls,PragmaRule),
1162 check_pragmas(Pragmas,PragmaRule).
1164 % Make all heads passive in trivial propagation rule
1165 % ... ==> ... | true.
1166 check_trivial_propagation_rule(PragmaRule) :-
1167 PragmaRule = pragma(Rule,IDs,Pragmas,Name,RuleNb),
1168 ( Rule = rule([],_,_,true) ->
1169 chr_warning(weird_program,'Ignoring propagation rule with empty body: ~@.\n\t\n',[format_rule(PragmaRule)]),
1170 set_all_passive(RuleNb)
1175 check_head_constraints([],_,_).
1176 check_head_constraints([Constr|Rest],Decls,PragmaRule) :-
1177 functor(Constr,F,A),
1178 ( member(F/A,Decls) ->
1179 check_head_constraints(Rest,Decls,PragmaRule)
1181 chr_error(syntax(Constr),'Undeclared constraint ~w in head of ~@.\n\tConstraint should be one of ~w.\n', [F/A,format_rule(PragmaRule),Decls])
1184 check_pragmas([],_).
1185 check_pragmas([Pragma|Pragmas],PragmaRule) :-
1186 check_pragma(Pragma,PragmaRule),
1187 check_pragmas(Pragmas,PragmaRule).
1189 check_pragma(Pragma,PragmaRule) :-
1191 chr_error(syntax(Pragma),'Invalid pragma ~w in ~@.\n\tPragma should not be a variable!\n',[Pragma,format_rule(PragmaRule)]).
1192 check_pragma(passive(ID), PragmaRule) :-
1194 PragmaRule = pragma(_,ids(IDs1,IDs2),_,_,RuleNb),
1195 ( memberchk_eq(ID,IDs1) ->
1197 ; memberchk_eq(ID,IDs2) ->
1200 chr_error(syntax(ID),'Invalid identifier ~w in pragma passive in ~@.\n', [ID,format_rule(PragmaRule)])
1204 check_pragma(mpassive(IDs), PragmaRule) :-
1206 PragmaRule = pragma(_,_,_,_,RuleNb),
1207 chr_warning(experimental,'Experimental pragma ~w. Use with care!\n',[mpassive(IDs)]),
1208 maplist(passive(RuleNb),IDs).
1210 check_pragma(Pragma, PragmaRule) :-
1211 Pragma = already_in_heads,
1213 chr_warning(unsupported_pragma(Pragma,PragmaRule),'Termination and correctness may be affected.\n',[]).
1215 check_pragma(Pragma, PragmaRule) :-
1216 Pragma = already_in_head(_),
1218 chr_warning(unsupported_pragma(Pragma,PragmaRule),'Termination and correctness may be affected.\n',[]).
1220 check_pragma(Pragma, PragmaRule) :-
1221 Pragma = no_history,
1223 chr_warning(experimental,'Experimental pragma no_history. Use with care!\n',[]),
1224 PragmaRule = pragma(_,_,_,_,N),
1227 check_pragma(Pragma, PragmaRule) :-
1228 Pragma = history(HistoryName,IDs),
1230 PragmaRule = pragma(_,ids(IDs1,IDs2),_,_,RuleNb),
1231 chr_warning(experimental,'Experimental pragma ~w. Use with care!\n',[Pragma]),
1233 chr_error(syntax(Pragma),'Pragma history only implemented for propagation rules.\n',[])
1234 ; \+ atom(HistoryName) ->
1235 chr_error(syntax(Pragma),'Illegal argument for pragma history: ~w is not an atom (rule number ~w).\n',[HistoryName,RuleNb])
1237 chr_error(syntax(Pragma),'Illegal argument for pragma history: ~w is not a set (rule number ~w).\n',[IDs,RuleNb])
1238 ; check_history_pragma_ids(IDs,IDs1,IDs2) ->
1239 history(RuleNb,HistoryName,IDs)
1241 chr_error(syntax(Pragma),'Invalid identifier(s) in pragma ~w of rule number ~w.\n',[Pragma,RuleNb])
1243 check_pragma(Pragma,PragmaRule) :-
1244 Pragma = line_number(LineNumber),
1246 PragmaRule = pragma(_,_,_,_,RuleNb),
1247 line_number(RuleNb,LineNumber).
1249 check_history_pragma_ids([], _, _).
1250 check_history_pragma_ids([ID|IDs],IDs1,IDs2) :-
1251 ( memberchk_eq(ID,IDs2) ; memberchk_eq(ID,IDs1) ),
1252 check_history_pragma_ids(IDs,IDs1,IDs2).
1254 check_pragma(Pragma,PragmaRule) :-
1255 chr_error(syntax(Pragma),'Unknown pragma ~w in ~@.\n', [Pragma,format_rule(PragmaRule)]).
1257 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1258 %% no_history(+RuleNb) is det.
1259 :- chr_constraint no_history/1.
1260 :- chr_option(mode,no_history(+)).
1261 :- chr_option(type_declaration,no_history(int)).
1263 %% has_no_history(+RuleNb) is semidet.
1264 :- chr_constraint has_no_history/1.
1265 :- chr_option(mode,has_no_history(+)).
1266 :- chr_option(type_declaration,has_no_history(int)).
1268 no_history(RuleNb) \ has_no_history(RuleNb) <=> true.
1269 has_no_history(_) <=> fail.
1271 :- chr_constraint history/3.
1272 :- chr_option(mode,history(+,+,+)).
1273 :- chr_option(type_declaration,history(any,any,list)).
1275 :- chr_constraint named_history/3.
1277 history(RuleNb,_,_), history(RuleNb,_,_) ==>
1278 chr_error(syntax,'Only one pragma history allowed per rule (rule number ~w)\n',[RuleNb]). %'
1280 history(RuleNb1,Name,IDs1), history(RuleNb2,Name,IDs2) ==>
1281 length(IDs1,L1), length(IDs2,L2),
1283 chr_error(syntax,'The history named ~w does not always range over an equal amount of occurrences.\n',[Name])
1285 test_named_history_id_pairs(RuleNb1,IDs1,RuleNb2,IDs2)
1288 test_named_history_id_pairs(_, [], _, []).
1289 test_named_history_id_pairs(RuleNb1, [ID1|IDs1], RuleNb2, [ID2|IDs2]) :-
1290 test_named_history_id_pair(RuleNb1,ID1,RuleNb2,ID2),
1291 test_named_history_id_pairs(RuleNb1,IDs1,RuleNb2,IDs2).
1293 :- chr_constraint test_named_history_id_pair/4.
1294 :- chr_option(mode,test_named_history_id_pair(+,+,+,+)).
1296 occurrence(C,_,RuleNb1,ID1,_), occurrence(C,_,RuleNb2,ID2,_)
1297 \ test_named_history_id_pair(RuleNb1,ID1,RuleNb2,ID2) <=> true.
1298 test_named_history_id_pair(RuleNb1,ID1,RuleNb2,ID2) <=>
1299 chr_error(syntax,'Occurrences of shared history in rules number ~w and ~w do not correspond\n', [RuleNb2,RuleNb1]).
1301 history(RuleNb,Name,IDs) \ named_history(RuleNb,QName,QIDs) <=> QName = Name, QIDs = IDs.
1302 named_history(_,_,_) <=> fail.
1304 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1307 format_rule(PragmaRule) :-
1308 PragmaRule = pragma(_,_,_,MaybeName,RuleNumber),
1309 ( MaybeName = yes(Name) ->
1310 write('rule '), write(Name)
1312 write('rule number '), write(RuleNumber)
1314 get_line_number(RuleNumber,LineNumber),
1319 check_rule_indexing(PragmaRule) :-
1320 PragmaRule = pragma(Rule,_,_,_,_),
1321 Rule = rule(H1,H2,G,_),
1322 term_variables(H1-H2,HeadVars),
1323 remove_anti_monotonic_guards(G,HeadVars,NG),
1324 check_indexing(H1,NG-H2),
1325 check_indexing(H2,NG-H1),
1327 ( chr_pp_flag(term_indexing,on) ->
1328 term_variables(NG,GuardVariables),
1329 append(H1,H2,Heads),
1330 check_specs_indexing(Heads,GuardVariables,Specs)
1335 :- chr_constraint indexing_spec/2.
1336 :- chr_option(mode,indexing_spec(+,+)).
1338 :- chr_constraint get_indexing_spec/2.
1339 :- chr_option(mode,get_indexing_spec(+,-)).
1342 indexing_spec(FA,Spec) \ get_indexing_spec(FA,R) <=> R = Spec.
1343 get_indexing_spec(_,Spec) <=> Spec = [].
1345 indexing_spec(FA,Specs1), indexing_spec(FA,Specs2)
1347 append(Specs1,Specs2,Specs),
1348 indexing_spec(FA,Specs).
1350 remove_anti_monotonic_guards(G,Vars,NG) :-
1352 remove_anti_monotonic_guard_list(GL,Vars,NGL),
1355 remove_anti_monotonic_guard_list([],_,[]).
1356 remove_anti_monotonic_guard_list([G|Gs],Vars,NGs) :-
1357 ( G = var(X), memberchk_eq(X,Vars) ->
1359 % TODO: this is not correct
1360 % ; G = functor(Term,Functor,Arity), % isotonic
1361 % \+ memberchk_eq(Functor,Vars), \+ memberchk_eq(Arity,Vars) ->
1366 remove_anti_monotonic_guard_list(Gs,Vars,RGs).
1368 check_indexing([],_).
1369 check_indexing([Head|Heads],Other) :-
1372 term_variables(Heads-Other,OtherVars),
1373 check_indexing(Args,1,F/A,OtherVars),
1374 check_indexing(Heads,[Head|Other]).
1376 check_indexing([],_,_,_).
1377 check_indexing([Arg|Args],I,FA,OtherVars) :-
1378 ( is_indexed_argument(FA,I) ->
1381 indexed_argument(FA,I)
1383 term_variables(Args,ArgsVars),
1384 append(ArgsVars,OtherVars,RestVars),
1385 ( memberchk_eq(Arg,RestVars) ->
1386 indexed_argument(FA,I)
1392 term_variables(Arg,NVars),
1393 append(NVars,OtherVars,NOtherVars),
1394 check_indexing(Args,J,FA,NOtherVars).
1396 check_specs_indexing([],_,[]).
1397 check_specs_indexing([Head|Heads],Variables,Specs) :-
1398 Specs = [Spec|RSpecs],
1399 term_variables(Heads,OtherVariables,Variables),
1400 check_spec_indexing(Head,OtherVariables,Spec),
1401 term_variables(Head,NVariables,Variables),
1402 check_specs_indexing(Heads,NVariables,RSpecs).
1404 check_spec_indexing(Head,OtherVariables,Spec) :-
1406 Spec = spec(F,A,ArgSpecs),
1408 check_args_spec_indexing(Args,1,OtherVariables,ArgSpecs),
1409 indexing_spec(F/A,[ArgSpecs]).
1411 check_args_spec_indexing([],_,_,[]).
1412 check_args_spec_indexing([Arg|Args],I,OtherVariables,ArgSpecs) :-
1413 term_variables(Args,Variables,OtherVariables),
1414 ( check_arg_spec_indexing(Arg,I,Variables,ArgSpec) ->
1415 ArgSpecs = [ArgSpec|RArgSpecs]
1417 ArgSpecs = RArgSpecs
1420 term_variables(Arg,NOtherVariables,OtherVariables),
1421 check_args_spec_indexing(Args,J,NOtherVariables,RArgSpecs).
1423 check_arg_spec_indexing(Arg,I,Variables,ArgSpec) :-
1425 memberchk_eq(Arg,Variables),
1426 ArgSpec = specinfo(I,any,[])
1429 ArgSpec = specinfo(I,F/A,[ArgSpecs]),
1431 check_args_spec_indexing(Args,1,Variables,ArgSpecs)
1434 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1436 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1439 add_occurrences([]).
1440 add_occurrences([Rule|Rules]) :-
1441 Rule = pragma(rule(H1,H2,_,_),ids(IDs1,IDs2),_,_,Nb),
1442 add_occurrences(H1,IDs1,simplification,Nb),
1443 add_occurrences(H2,IDs2,propagation,Nb),
1444 add_occurrences(Rules).
1446 add_occurrences([],[],_,_).
1447 add_occurrences([H|Hs],[ID|IDs],Type,RuleNb) :-
1450 new_occurrence(FA,RuleNb,ID,Type),
1451 add_occurrences(Hs,IDs,Type,RuleNb).
1453 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1455 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1456 % Observation Analysis
1466 :- chr_constraint observation_analysis/1.
1467 :- chr_option(mode, observation_analysis(+)).
1469 observation_analysis(Cs), rule(RuleNb,PragmaRule) # Id ==>
1470 PragmaRule = pragma(rule(_,_,Guard,Body),_,_,_,_),
1471 ( chr_pp_flag(store_in_guards, on) ->
1472 observation_analysis(RuleNb, Guard, guard, Cs)
1476 observation_analysis(RuleNb, Body, body, Cs)
1479 observation_analysis(_) <=> true.
1481 observation_analysis(RuleNb, Term, GB, Cs) :-
1482 ( all_spawned(RuleNb,GB) ->
1485 spawns_all(RuleNb,GB)
1493 observation_analysis(RuleNb,T1,GB,Cs),
1494 observation_analysis(RuleNb,T2,GB,Cs)
1496 observation_analysis(RuleNb,T1,GB,Cs),
1497 observation_analysis(RuleNb,T2,GB,Cs)
1498 ; Term = (T1->T2) ->
1499 observation_analysis(RuleNb,T1,GB,Cs),
1500 observation_analysis(RuleNb,T2,GB,Cs)
1502 observation_analysis(RuleNb,T,GB,Cs)
1503 ; functor(Term,F,A), member(F/A,Cs) ->
1504 spawns(RuleNb,GB,F/A)
1506 spawns_all_triggers(RuleNb,GB)
1507 ; Term = (_ is _) ->
1508 spawns_all_triggers(RuleNb,GB)
1509 ; builtin_binds_b(Term,Vars) ->
1513 spawns_all_triggers(RuleNb,GB)
1516 spawns_all(RuleNb,GB)
1519 :- chr_constraint spawns/3.
1520 :- chr_option(mode, spawns(+,+,+)).
1521 :- chr_type spawns_type ---> guard ; body.
1522 :- chr_option(type_declaration,spawns(any,spawns_type,any)).
1524 :- chr_constraint spawns_all/2, spawns_all_triggers/2.
1525 :- chr_option(mode, spawns_all(+,+)).
1526 :- chr_option(type_declaration,spawns_all(any,spawns_type)).
1527 :- chr_option(mode, spawns_all_triggers(+,+)).
1528 :- chr_option(type_declaration,spawns_all_triggers(any,spawns_type)).
1530 spawns_all(RuleNb,GB) \ spawns_all(RuleNb,GB) <=> true.
1531 spawns_all(RuleNb,guard) \ spawns_all(RuleNb,body) <=> true.
1532 spawns_all_triggers(RuleNb,GB) \ spawns_all_triggers(RuleNb,GB) <=> true.
1533 spawns_all_triggers(RuleNb,guard) \ spawns_all_triggers(RuleNb,body) <=> true.
1534 spawns(RuleNb,GB,C) \ spawns(RuleNb,GB,C) <=> true.
1535 spawns(RuleNb,guard,C) \ spawns(RuleNb,body,C) <=> true.
1537 spawns_all(RuleNb,GB) \ spawns(RuleNb,GB,_) <=> true.
1538 spawns_all(RuleNb,guard) \ spawns(RuleNb,body,_) <=> true.
1539 spawns_all(RuleNb,GB) \ spawns_all_triggers(RuleNb,GB) <=> true.
1540 spawns_all(RuleNb,guard) \ spawns_all_triggers(RuleNb,body) <=> true.
1542 spawns_all_triggers(RuleNb,GB) \ spawns(RuleNb,GB,C) <=> may_trigger(C) | true.
1543 spawns_all_triggers(RuleNb,guard) \ spawns(RuleNb,body,C) <=> may_trigger(C) | true.
1545 spawns_all(RuleNb2,_), occurrence(C1,_,RuleNb2,O,_)#Id
1547 spawns(RuleNb1,GB,C1)
1549 \+ is_passive(RuleNb2,O)
1551 spawns_all(RuleNb1,GB)
1555 occurrence(C1,_,RuleNb2,O,_)#Id, spawns_all(RuleNb2,_)
1557 \+(\+ spawns_all_triggers_implies_spawns_all), % in the hope it schedules this guard early...
1558 \+ is_passive(RuleNb2,O), may_trigger(C1)
1560 spawns_all_triggers_implies_spawns_all
1564 :- chr_constraint spawns_all_triggers_implies_spawns_all/0.
1565 spawns_all_triggers_implies_spawns_all, spawns_all_triggers_implies_spawns_all <=> fail.
1566 spawns_all_triggers_implies_spawns_all \
1567 spawns_all_triggers(RuleNb,GB) <=> spawns_all(RuleNb,GB).
1569 spawns_all_triggers(RuleNb2,_), occurrence(C1,_,RuleNb2,O,_)#Id
1571 spawns(RuleNb1,GB,C1)
1574 \+ is_passive(RuleNb2,O)
1576 spawns_all_triggers(RuleNb1,GB)
1580 spawns_all_triggers(RuleNb2,_), occurrence(C1,_,RuleNb2,O,_)#Id,
1581 spawns(RuleNb1,GB,C1)
1584 \+ is_passive(RuleNb2,O)
1586 spawns_all_triggers(RuleNb1,GB)
1590 % a bit dangerous this rule: could start propagating too much too soon?
1591 spawns(RuleNb2,_,C2), occurrence(C1,_,RuleNb2,O,_)#Id,
1592 spawns(RuleNb1,GB,C1)
1594 RuleNb1 \== RuleNb2, C1 \== C2,
1595 \+ is_passive(RuleNb2,O)
1597 spawns(RuleNb1,GB,C2)
1601 spawns(RuleNb2,_,C2), occurrence(C1,_,RuleNb2,O,_)#Id,
1602 spawns_all_triggers(RuleNb1,GB)
1604 \+ is_passive(RuleNb2,O), may_trigger(C1), \+ may_trigger(C2)
1606 spawns(RuleNb1,GB,C2)
1611 :- chr_constraint all_spawned/2.
1612 :- chr_option(mode, all_spawned(+,+)).
1613 spawns_all(RuleNb,guard) \ all_spawned(RuleNb,_) <=> true.
1614 spawns_all(RuleNb,GB) \ all_spawned(RuleNb,GB) <=> true.
1615 all_spawned(RuleNb,GB) <=> fail.
1618 % Overview of the supported queries:
1619 % is_observed(+functor/artiy, +occurrence_number, +(guard;body))
1620 % only succeeds if the occurrence is observed by the
1621 % guard resp. body (depending on the last argument) of its rule
1622 % is_observed(+functor/artiy, +occurrence_number, -)
1623 % succeeds if the occurrence is observed by either the guard or
1624 % the body of its rule
1625 % NOTE: the last argument is NOT bound by this query
1627 % do_is_observed(+functor/artiy,+rule_number,+(guard;body))
1628 % succeeds if the given constraint is observed by the given
1630 % do_is_observed(+functor/artiy,+rule_number)
1631 % succeeds if the given constraint is observed by the given
1632 % rule (either its guard or its body)
1637 ai_is_observed(C,O).
1639 is_stored_in_guard(C,RuleNb) :-
1640 chr_pp_flag(store_in_guards, on),
1641 do_is_observed(C,RuleNb,guard).
1643 :- chr_constraint is_observed/3.
1644 :- chr_option(mode, is_observed(+,+,+)).
1645 occurrence(C,O,RuleNb,_,_) \ is_observed(C,O,GB) <=> do_is_observed(C,RuleNb,GB).
1646 is_observed(_,_,_) <=> fail. % this will not happen in practice
1649 :- chr_constraint do_is_observed/3.
1650 :- chr_option(mode, do_is_observed(+,+,+)).
1651 :- chr_constraint do_is_observed/2.
1652 :- chr_option(mode, do_is_observed(+,+)).
1654 do_is_observed(C,RuleNb,GB) <=> var(GB) | do_is_observed(C,RuleNb).
1657 % a constraint C is observed if the GB of the rule it occurs in spawns all,
1658 % and some non-passive occurrence of some (possibly other) constraint
1659 % exists in a rule (could be same rule) with at least one occurrence of C
1661 spawns_all(RuleNb,GB),
1662 occurrence(_,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1664 do_is_observed(C,RuleNb,GB)
1666 \+ is_passive(RuleNb2,O)
1670 spawns_all(RuleNb,_),
1671 occurrence(_,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1673 do_is_observed(C,RuleNb)
1675 \+ is_passive(RuleNb2,O)
1680 % a constraint C is observed if the GB of the rule it occurs in spawns a
1681 % constraint C2 that occurs non-passively in a rule (possibly the same rule)
1682 % as an occurrence of C
1684 spawns(RuleNb,GB,C2),
1685 occurrence(C2,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1687 do_is_observed(C,RuleNb,GB)
1689 \+ is_passive(RuleNb2,O)
1693 spawns(RuleNb,_,C2),
1694 occurrence(C2,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1696 do_is_observed(C,RuleNb)
1698 \+ is_passive(RuleNb2,O)
1702 % (3) spawns_all_triggers
1703 % a constraint C is observed if the GB of the rule it occurs in spawns all triggers
1704 % and some non-passive occurrence of some (possibly other) constraint that may trigger
1705 % exists in a rule (could be same rule) with at least one occurrence of C
1707 spawns_all_triggers(RuleNb,GB),
1708 occurrence(C2,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1710 do_is_observed(C,RuleNb,GB)
1712 \+ is_passive(RuleNb2,O), may_trigger(C2)
1716 spawns_all_triggers(RuleNb,_),
1717 occurrence(C2,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1719 do_is_observed(C,RuleNb)
1721 \+ is_passive(RuleNb2,O), may_trigger(C2)
1725 % (4) conservativeness
1726 do_is_observed(_,_,_) <=> chr_pp_flag(observation_analysis,off).
1727 do_is_observed(_,_) <=> chr_pp_flag(observation_analysis,off).
1730 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1732 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1735 %% Generated predicates
1736 %% attach_$CONSTRAINT
1738 %% detach_$CONSTRAINT
1741 %% attach_$CONSTRAINT
1742 generate_attach_detach_a_constraint_all([],[]).
1743 generate_attach_detach_a_constraint_all([Constraint|Constraints],Clauses) :-
1744 ( ( chr_pp_flag(debugable,on) ; is_stored(Constraint), \+ only_ground_indexed_arguments(Constraint), \+ get_store_type(Constraint,var_assoc_store(_,_)) ) ->
1745 generate_attach_a_constraint(Constraint,Clauses1),
1746 generate_detach_a_constraint(Constraint,Clauses2)
1751 generate_attach_detach_a_constraint_all(Constraints,Clauses3),
1752 append([Clauses1,Clauses2,Clauses3],Clauses).
1754 generate_attach_a_constraint(Constraint,[Clause1,Clause2]) :-
1755 generate_attach_a_constraint_nil(Constraint,Clause1),
1756 generate_attach_a_constraint_cons(Constraint,Clause2).
1758 attach_constraint_atom(FA,Vars,Susp,Atom) :-
1759 make_name('attach_',FA,Name),
1760 Atom =.. [Name,Vars,Susp].
1762 generate_attach_a_constraint_nil(FA,Clause) :-
1763 Clause = (Head :- true),
1764 attach_constraint_atom(FA,[],_,Head).
1766 generate_attach_a_constraint_cons(FA,Clause) :-
1767 Clause = (Head :- Body),
1768 attach_constraint_atom(FA,[Var|Vars],Susp,Head),
1769 attach_constraint_atom(FA,Vars,Susp,RecursiveCall),
1770 Body = ( AttachBody, Subscribe, RecursiveCall ),
1771 get_max_constraint_index(N),
1773 generate_attach_body_1(FA,Var,Susp,AttachBody)
1775 generate_attach_body_n(FA,Var,Susp,AttachBody)
1777 % SWI-Prolog specific code
1778 chr_pp_flag(solver_events,NMod),
1780 Args = [[Var|_],Susp],
1781 get_target_module(Mod),
1782 use_auxiliary_predicate(run_suspensions),
1783 Subscribe = clp_events:subscribe(Var,NMod,Mod,Mod:'$run_suspensions'([Susp]))
1788 generate_attach_body_1(FA,Var,Susp,Body) :-
1789 get_target_module(Mod),
1791 ( get_attr(Var, Mod, Susps) ->
1792 put_attr(Var, Mod, [Susp|Susps])
1794 put_attr(Var, Mod, [Susp])
1797 generate_attach_body_n(F/A,Var,Susp,Body) :-
1798 get_constraint_index(F/A,Position),
1799 get_max_constraint_index(Total),
1800 get_target_module(Mod),
1801 add_attr(Total,Susp,Position,TAttr,AddGoal,NTAttr),
1802 singleton_attr(Total,Susp,Position,NewAttr3),
1804 ( get_attr(Var,Mod,TAttr) ->
1806 put_attr(Var,Mod,NTAttr)
1808 put_attr(Var,Mod,NewAttr3)
1811 %% detach_$CONSTRAINT
1812 generate_detach_a_constraint(Constraint,[Clause1,Clause2]) :-
1813 generate_detach_a_constraint_nil(Constraint,Clause1),
1814 generate_detach_a_constraint_cons(Constraint,Clause2).
1816 detach_constraint_atom(FA,Vars,Susp,Atom) :-
1817 make_name('detach_',FA,Name),
1818 Atom =.. [Name,Vars,Susp].
1820 generate_detach_a_constraint_nil(FA,Clause) :-
1821 Clause = ( Head :- true),
1822 detach_constraint_atom(FA,[],_,Head).
1824 generate_detach_a_constraint_cons(FA,Clause) :-
1825 Clause = (Head :- Body),
1826 detach_constraint_atom(FA,[Var|Vars],Susp,Head),
1827 detach_constraint_atom(FA,Vars,Susp,RecursiveCall),
1828 Body = ( DetachBody, RecursiveCall ),
1829 get_max_constraint_index(N),
1831 generate_detach_body_1(FA,Var,Susp,DetachBody)
1833 generate_detach_body_n(FA,Var,Susp,DetachBody)
1836 generate_detach_body_1(FA,Var,Susp,Body) :-
1837 get_target_module(Mod),
1839 ( get_attr(Var,Mod,Susps) ->
1840 'chr sbag_del_element'(Susps,Susp,NewSusps),
1844 put_attr(Var,Mod,NewSusps)
1850 generate_detach_body_n(F/A,Var,Susp,Body) :-
1851 get_constraint_index(F/A,Position),
1852 get_max_constraint_index(Total),
1853 rem_attr(Total,Var,Susp,Position,TAttr,RemGoal),
1854 get_target_module(Mod),
1856 ( get_attr(Var,Mod,TAttr) ->
1862 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1863 %-------------------------------------------------------------------------------
1864 %% generate_indexed_variables_body(+ConstraintSymbol,+ArgList,-Body,-VarList) is det.
1865 :- chr_constraint generate_indexed_variables_body/4.
1866 :- chr_option(mode,generate_indexed_variables_body(+,?,+,?)).
1867 :- chr_option(type_declaration,generate_indexed_variables_body(constraint,any,any,any)).
1868 %-------------------------------------------------------------------------------
1869 constraint_mode(F/A,ArgModes) \ generate_indexed_variables_body(F/A,Args,Body,Vars) <=>
1870 get_indexing_spec(F/A,Specs),
1871 ( chr_pp_flag(term_indexing,on) ->
1872 spectermvars(Specs,Args,F,A,Body,Vars)
1874 get_constraint_type_det(F/A,ArgTypes),
1875 create_indexed_variables_body(Args,ArgModes,ArgTypes,Vars,1,F/A,MaybeBody,N),
1876 ( MaybeBody == empty ->
1883 Term =.. [term|Args]
1885 Body = term_variables(Term,Vars)
1890 generate_indexed_variables_body(FA,_,_,_) <=>
1891 chr_error(internal,'generate_indexed_variables_body: missing mode info for ~w.\n',[FA]).
1892 %===============================================================================
1894 create_indexed_variables_body([],[],[],_,_,_,empty,0).
1895 create_indexed_variables_body([V|Vs],[Mode|Modes],[Type|Types],Vars,I,FA,Body,N) :-
1897 create_indexed_variables_body(Vs,Modes,Types,Tail,J,FA,RBody,M),
1899 is_indexed_argument(FA,I) ->
1900 ( atomic_type(Type) ->
1911 Continuation = true, Tail = []
1913 Continuation = RBody
1917 Body = term_variables(V,Vars)
1919 Body = (term_variables(V,Vars,Tail),RBody)
1923 ; Mode == (-), is_indexed_argument(FA,I) ->
1927 Body = (Vars = [V|Tail],RBody)
1935 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1937 spectermvars(Specs,Args,F,A,Goal,Vars) :-
1938 spectermvars(Args,1,Specs,F,A,Vars,[],Goal).
1940 spectermvars([],B,_,_,A,L,L,true) :- B > A, !.
1941 spectermvars([Arg|Args],I,Specs,F,A,L,T,Goal) :-
1942 Goal = (ArgGoal,RGoal),
1943 argspecs(Specs,I,TempArgSpecs,RSpecs),
1944 merge_argspecs(TempArgSpecs,ArgSpecs),
1945 arggoal(ArgSpecs,Arg,ArgGoal,L,L1),
1947 spectermvars(Args,J,RSpecs,F,A,L1,T,RGoal).
1949 argspecs([],_,[],[]).
1950 argspecs([[]|Rest],I,ArgSpecs,RestSpecs) :-
1951 argspecs(Rest,I,ArgSpecs,RestSpecs).
1952 argspecs([[specinfo(J,Spec,Args)|Specs]|Rest],I,ArgSpecs,RestSpecs) :-
1954 ArgSpecs = [specinfo(J,Spec,Args)|RArgSpecs],
1956 RRestSpecs = RestSpecs
1958 RestSpecs = [Specs|RRestSpecs]
1961 ArgSpecs = RArgSpecs,
1962 RestSpecs = [[specinfo(J,Spec,Args)|Specs]|RRestSpecs]
1964 argspecs(Rest,I,RArgSpecs,RRestSpecs).
1966 merge_argspecs(In,Out) :-
1968 merge_argspecs_(Sorted,Out).
1970 merge_argspecs_([],[]).
1971 merge_argspecs_([X],R) :- !, R = [X].
1972 merge_argspecs_([specinfo(I,F1,A1),specinfo(I,F2,A2)|Rest],R) :-
1973 ( (F1 == any ; F2 == any) ->
1974 merge_argspecs_([specinfo(I,any,[])|Rest],R)
1977 merge_argspecs_([specinfo(I,F1,A)|Rest],R)
1979 R = [specinfo(I,F1,A1)|RR],
1980 merge_argspecs_([specinfo(I,F2,A2)|Rest],RR)
1983 arggoal(List,Arg,Goal,L,T) :-
1987 ; List = [specinfo(_,any,_)] ->
1988 Goal = term_variables(Arg,L,T)
1996 arggoal_cases(List,Arg,L,T,Cases)
1999 arggoal_cases([],_,L,T,L=T).
2000 arggoal_cases([specinfo(_,FA,ArgSpecs)|Rest],Arg,L,T,Cases) :-
2003 ; ArgSpecs == [[]] ->
2006 Cases = (Case ; RCases),
2009 Case = (Arg = Term -> ArgsGoal),
2010 spectermvars(Args,1,ArgSpecs,F,A,L,T,ArgsGoal)
2012 arggoal_cases(Rest,Arg,L,T,RCases).
2013 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2015 generate_extra_clauses(Constraints,List) :-
2016 generate_activate_clauses(Constraints,List,Tail0),
2017 generate_remove_clauses(Constraints,Tail0,Tail1),
2018 generate_allocate_clauses(Constraints,Tail1,Tail2),
2019 generate_insert_constraint_internal_clauses(Constraints,Tail2,Tail3),
2020 generate_novel_production(Tail3,Tail4),
2021 generate_extend_history(Tail4,Tail5),
2022 generate_run_suspensions_clauses(Constraints,Tail5,Tail6),
2023 generate_empty_named_history_initialisations(Tail6,Tail7),
2026 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2027 % remove_constraint_internal/[1/3]
2029 generate_remove_clauses([],List,List).
2030 generate_remove_clauses([C|Cs],List,Tail) :-
2031 generate_remove_clause(C,List,List1),
2032 generate_remove_clauses(Cs,List1,Tail).
2034 remove_constraint_goal(Constraint,Susp,Agenda,DeleteNo,DeleteYes,Role,Goal) :-
2035 uses_state(Constraint,removed),
2036 ( chr_pp_flag(inline_insertremove,off) ->
2037 use_auxiliary_predicate(remove_constraint_internal,Constraint),
2038 Goal = ( DeleteGoal, ( Delete == yes -> DeleteYes ; DeleteNo) ),
2039 remove_constraint_atom(Constraint,Susp,Agenda,Delete,DeleteGoal)
2041 delay_phase_end(validate_store_type_assumptions,
2042 generate_remove_body(Constraint,Susp,Agenda,DeleteNo,DeleteYes,Role,Goal)
2046 remove_constraint_atom(Constraint,Susp,Agenda,Delete,Goal) :-
2047 make_name('$remove_constraint_internal_',Constraint,Name),
2048 ( chr_pp_flag(debugable,off), ( only_ground_indexed_arguments(Constraint) ; get_store_type(Constraint,var_assoc_store(_,_)) ) ->
2049 Goal =.. [Name, Susp,Delete]
2051 Goal =.. [Name,Susp,Agenda,Delete]
2054 generate_remove_clause(Constraint,List,Tail) :-
2055 ( is_used_auxiliary_predicate(remove_constraint_internal,Constraint) ->
2056 List = [RemoveClause|Tail],
2057 RemoveClause = (Head :- RemoveBody),
2058 remove_constraint_atom(Constraint,Susp,Agenda,Delete,Head),
2059 generate_remove_body(Constraint,Susp,Agenda,Delete = no,Delete = yes,active,RemoveBody)
2064 generate_remove_body(Constraint,Susp,Agenda,DeleteNo,DeleteYes,Role,RemoveBody) :-
2065 ( chr_pp_flag(debugable,off), ( only_ground_indexed_arguments(Constraint) ; get_store_type(Constraint,var_assoc_store(_,_))) ->
2067 get_update_suspension_field(Constraint,Susp,state,State,removed,GetState,GetStateValue0,UpdateState),
2068 if_used_state(Constraint,not_stored_yet,GetStateValue0,true,GetStateValue),
2069 if_used_state(Constraint,not_stored_yet,(State == not_stored_yet -> DeleteNo ; DeleteYes),DeleteYes,MaybeDelete)
2070 ; Role == partner ->
2071 get_update_suspension_field(Constraint,Susp,state,State,removed,GetState,_,UpdateState),
2072 GetStateValue = true,
2073 MaybeDelete = DeleteYes
2083 static_suspension_term(Constraint,Susp2),
2084 get_static_suspension_term_field(arguments,Constraint,Susp2,Args),
2085 generate_indexed_variables_body(Constraint,Args,IndexedVariablesBody,Agenda),
2086 ( chr_pp_flag(debugable,on) ->
2087 Constraint = Functor / _,
2088 get_static_suspension_term_field(functor,Constraint,Susp2,Functor)
2093 get_update_static_suspension_field(Constraint,Susp,Susp2,state,State,removed,GetStateValue0,UpdateState),
2094 if_used_state(Constraint,not_stored_yet,GetStateValue0,true,GetStateValue),
2095 if_used_state(Constraint,not_stored_yet,(State == not_stored_yet -> Agenda = [], DeleteNo ; IndexedVariablesBody, DeleteYes),(IndexedVariablesBody,DeleteYes),MaybeDelete)
2096 ; Role == partner ->
2097 get_update_static_suspension_field(Constraint,Susp,Susp2,state,State,removed,_,UpdateState),
2098 GetStateValue = true,
2099 MaybeDelete = (IndexedVariablesBody, DeleteYes)
2110 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2111 % activate_constraint/4
2113 generate_activate_clauses([],List,List).
2114 generate_activate_clauses([C|Cs],List,Tail) :-
2115 generate_activate_clause(C,List,List1),
2116 generate_activate_clauses(Cs,List1,Tail).
2118 activate_constraint_goal(Constraint,StoreAction,Vars,Susp,Generation,Goal) :-
2119 ( chr_pp_flag(inline_insertremove,off) ->
2120 use_auxiliary_predicate(activate_constraint,Constraint),
2121 Goal = ( ActivateGoal , (Store == yes -> StoreAction ; true) ),
2122 activate_constraint_atom(Constraint,Store,Vars,Susp,Generation,ActivateGoal)
2124 delay_phase_end(validate_store_type_assumptions,
2125 activate_constraint_body(Constraint,StoreAction,true,Vars,Susp,Generation,Goal)
2129 activate_constraint_atom(Constraint,Store,Vars,Susp,Generation,Goal) :-
2130 make_name('$activate_constraint_',Constraint,Name),
2131 ( chr_pp_flag(debugable,off), only_ground_indexed_arguments(Constraint) ->
2132 Goal =.. [Name,Store, Susp]
2133 ; chr_pp_flag(debugable,off), may_trigger(Constraint), get_store_type(Constraint,var_assoc_store(_,_)) ->
2134 Goal =.. [Name,Store, Susp, Generation]
2135 ; chr_pp_flag(debugable,off), may_trigger(Constraint), get_store_type(Constraint,var_assoc_store(_,_)) ->
2136 Goal =.. [Name,Store, Vars, Susp, Generation]
2138 Goal =.. [Name,Store, Vars, Susp]
2141 generate_activate_clause(Constraint,List,Tail) :-
2142 ( is_used_auxiliary_predicate(activate_constraint,Constraint) ->
2143 List = [Clause|Tail],
2144 Clause = (Head :- Body),
2145 activate_constraint_atom(Constraint,Store,Vars,Susp,Generation,Head),
2146 activate_constraint_body(Constraint,Store = yes, Store = no,Vars,Susp,Generation,Body)
2151 activate_constraint_body(Constraint,StoreYes,StoreNo,Vars,Susp,Generation,Body) :-
2152 ( chr_pp_flag(debugable,off), may_trigger(Constraint), uses_field(Constraint,generation) ->
2153 get_update_suspension_field(Constraint,Susp,generation,Gen,Generation,GetGeneration,GetGenerationValue,UpdateGeneration),
2154 GenerationHandling = (GetGeneration, GetGenerationValue, Generation is Gen+1, UpdateGeneration)
2156 GenerationHandling = true
2158 get_update_suspension_field(Constraint,Susp,state,State,active,GetState,GetStateValue0,UpdateState),
2159 if_used_state(Constraint,not_stored_yet,GetStateValue0,true,GetStateValue),
2160 ( chr_pp_flag(debugable,off), ( only_ground_indexed_arguments(Constraint) ; get_store_type(Constraint,var_assoc_store(_,_))) ->
2161 if_used_state(Constraint,not_stored_yet,( State == not_stored_yet -> StoreYes ; StoreNo ),StoreNo,StoreVarsGoal)
2163 get_dynamic_suspension_term_field(arguments,Constraint,Susp,Arguments,ArgumentsGoal),
2164 generate_indexed_variables_body(Constraint,Arguments,IndexedVariablesBody,Vars),
2165 ( chr_pp_flag(guard_locks,off) ->
2168 NoneLocked = 'chr none_locked'( Vars)
2170 if_used_state(Constraint,not_stored_yet,
2171 ( State == not_stored_yet ->
2173 IndexedVariablesBody,
2180 % (Vars = [],StoreNo),StoreVarsGoal)
2181 StoreNo,StoreVarsGoal)
2191 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2192 % allocate_constraint/4
2194 generate_allocate_clauses([],List,List).
2195 generate_allocate_clauses([C|Cs],List,Tail) :-
2196 generate_allocate_clause(C,List,List1),
2197 generate_allocate_clauses(Cs,List1,Tail).
2199 allocate_constraint_goal(Constraint,Susp,Args,Goal) :-
2200 uses_state(Constraint,not_stored_yet),
2201 ( chr_pp_flag(inline_insertremove,off) ->
2202 use_auxiliary_predicate(allocate_constraint,Constraint),
2203 allocate_constraint_atom(Constraint,Susp,Args,Goal)
2205 Goal = (Susp = Suspension, Goal0),
2206 delay_phase_end(validate_store_type_assumptions,
2207 allocate_constraint_body(Constraint,Suspension,Args,Goal0)
2211 allocate_constraint_atom(Constraint, Susp, Args,Goal) :-
2212 make_name('$allocate_constraint_',Constraint,Name),
2213 Goal =.. [Name,Susp|Args].
2215 generate_allocate_clause(Constraint,List,Tail) :-
2216 ( is_used_auxiliary_predicate(allocate_constraint,Constraint) ->
2217 List = [Clause|Tail],
2218 Clause = (Head :- Body),
2221 allocate_constraint_atom(Constraint,Susp,Args,Head),
2222 allocate_constraint_body(Constraint,Susp,Args,Body)
2227 allocate_constraint_body(Constraint,Susp,Args,Body) :-
2228 static_suspension_term(Constraint,Suspension),
2229 get_static_suspension_term_field(arguments,Constraint,Suspension,Args),
2230 ( chr_pp_flag(debugable,on) ->
2231 Constraint = Functor / _,
2232 get_static_suspension_term_field(functor,Constraint,Suspension,Functor)
2236 ( chr_pp_flag(debugable,on) ->
2237 ( may_trigger(Constraint) ->
2238 append(Args,[Susp],VarsSusp),
2239 build_head(F,A,[0],VarsSusp, ContinuationGoal),
2240 get_target_module(Mod),
2241 Continuation = Mod : ContinuationGoal
2245 Init = (Susp = Suspension),
2246 create_static_suspension_field(Constraint,Suspension,continuation,Continuation,CreateContinuation),
2247 create_static_suspension_field(Constraint,Suspension,generation,0,CreateGeneration)
2248 ; may_trigger(Constraint), uses_field(Constraint,generation) ->
2249 create_static_suspension_field(Constraint,Suspension,generation,0,CreateGeneration),
2250 Susp = Suspension, Init = true, CreateContinuation = true
2252 CreateGeneration = true, Susp = Suspension, Init = true, CreateContinuation = true
2254 ( uses_history(Constraint) ->
2255 create_static_suspension_field(Constraint,Suspension,history,t,CreateHistory)
2257 CreateHistory = true
2259 create_static_suspension_field(Constraint,Suspension,state,not_stored_yet,CreateState),
2260 ( has_suspension_field(Constraint,id) ->
2261 get_static_suspension_term_field(id,Constraint,Suspension,Id),
2262 GenID = 'chr gen_id'(Id)
2276 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2277 % insert_constraint_internal
2279 generate_insert_constraint_internal_clauses([],List,List).
2280 generate_insert_constraint_internal_clauses([C|Cs],List,Tail) :-
2281 generate_insert_constraint_internal_clause(C,List,List1),
2282 generate_insert_constraint_internal_clauses(Cs,List1,Tail).
2284 insert_constraint_internal_constraint_goal(Constraint, Vars, Suspension, Continuation, Args,Goal) :-
2285 ( chr_pp_flag(inline_insertremove,off) ->
2286 use_auxiliary_predicate(remove_constraint_internal,Constraint),
2287 insert_constraint_internal_constraint_atom(Constraint,Vars,Suspension,Continuation,Args,Goal)
2289 delay_phase_end(validate_store_type_assumptions,
2290 generate_insert_constraint_internal_body(Constraint,Suspension,Continuation,Args,Vars,Goal)
2295 insert_constraint_internal_constraint_atom(Constraint,Vars,Self,Closure,Args,Goal) :-
2296 insert_constraint_internal_constraint_name(Constraint,Name),
2297 ( chr_pp_flag(debugable,on) ->
2298 Goal =.. [Name, Vars, Self, Closure | Args]
2299 ; ( only_ground_indexed_arguments(Constraint) ; get_store_type(Constraint,var_assoc_store(_,_)))->
2300 Goal =.. [Name,Self | Args]
2302 Goal =.. [Name,Vars, Self | Args]
2305 insert_constraint_internal_constraint_name(Constraint,Name) :-
2306 make_name('$insert_constraint_internal_',Constraint,Name).
2308 generate_insert_constraint_internal_clause(Constraint,List,Tail) :-
2309 ( is_used_auxiliary_predicate(insert_constraint_internal,Constraint) ->
2310 List = [Clause|Tail],
2311 Clause = (Head :- Body),
2314 insert_constraint_internal_constraint_atom(Constraint, Vars, Suspension, Continuation,Args,Head),
2315 generate_insert_constraint_internal_body(Constraint,Suspension,Continuation,Args,Vars,Body)
2321 generate_insert_constraint_internal_body(Constraint,Susp,Continuation,Args,Vars,Body) :-
2322 static_suspension_term(Constraint,Suspension),
2323 create_static_suspension_field(Constraint,Suspension,state,active,CreateState),
2324 ( chr_pp_flag(debugable,on) ->
2325 get_static_suspension_term_field(continuation,Constraint,Suspension,Continuation),
2326 create_static_suspension_field(Constraint,Suspension,generation,0,CreateGeneration)
2327 ; may_trigger(Constraint), uses_field(Constraint,generation) ->
2328 create_static_suspension_field(Constraint,Suspension,generation,0,CreateGeneration)
2330 CreateGeneration = true
2332 ( chr_pp_flag(debugable,on) ->
2333 Constraint = Functor / _,
2334 get_static_suspension_term_field(functor,Constraint,Suspension,Functor)
2338 ( uses_history(Constraint) ->
2339 create_static_suspension_field(Constraint,Suspension,history,t,CreateHistory)
2341 CreateHistory = true
2343 get_static_suspension_term_field(arguments,Constraint,Suspension,Args),
2344 List = [Clause|Tail],
2345 ( chr_pp_flag(debugable,off), ( only_ground_indexed_arguments(Constraint) ; get_store_type(Constraint,var_assoc_store(_,_)))->
2346 suspension_term_base_fields(Constraint,BaseFields),
2347 ( has_suspension_field(Constraint,id) ->
2348 get_static_suspension_term_field(id,Constraint,Suspension,Id),
2349 GenID = 'chr gen_id'(Id)
2362 ( has_suspension_field(Constraint,id) ->
2363 get_static_suspension_term_field(id,Constraint,Suspension,Id),
2364 GenID = 'chr gen_id'(Id)
2368 generate_indexed_variables_body(Constraint,Args,IndexedVariablesBody,Vars),
2369 ( chr_pp_flag(guard_locks,off) ->
2372 NoneLocked = 'chr none_locked'( Vars)
2377 IndexedVariablesBody,
2386 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2387 % novel_production/2
2389 generate_novel_production(List,Tail) :-
2390 ( is_used_auxiliary_predicate(novel_production) ->
2391 List = [Clause|Tail],
2394 '$novel_production'( Self, Tuple) :-
2395 % arg( 3, Self, Ref), % ARGXXX
2396 % 'chr get_mutable'( History, Ref),
2397 arg( 3, Self, History), % ARGXXX
2398 ( hprolog:get_ds( Tuple, History, _) ->
2408 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2411 generate_extend_history(List,Tail) :-
2412 ( is_used_auxiliary_predicate(extend_history) ->
2413 List = [Clause|Tail],
2416 '$extend_history'( Self, Tuple) :-
2417 % arg( 3, Self, Ref), % ARGXXX
2418 % 'chr get_mutable'( History, Ref),
2419 arg( 3, Self, History), % ARGXXX
2420 hprolog:put_ds( Tuple, History, x, NewHistory),
2421 setarg( 3, Self, NewHistory) % ARGXXX
2427 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2430 empty_named_history_initialisations/2,
2431 generate_empty_named_history_initialisation/1,
2432 find_empty_named_histories/0.
2434 generate_empty_named_history_initialisations(List, Tail) :-
2435 empty_named_history_initialisations(List, Tail),
2436 find_empty_named_histories.
2438 find_empty_named_histories, history(_, Name, []) ==>
2439 generate_empty_named_history_initialisation(Name).
2441 generate_empty_named_history_initialisation(Name) \
2442 generate_empty_named_history_initialisation(Name) <=> true.
2443 generate_empty_named_history_initialisation(Name) \
2444 empty_named_history_initialisations(List, Tail) # Passive
2446 empty_named_history_global_variable(Name, GlobalVariable),
2447 List = [(:- nb_setval(GlobalVariable, 0))|Rest],
2448 empty_named_history_initialisations(Rest, Tail)
2449 pragma passive(Passive).
2451 find_empty_named_histories \
2452 generate_empty_named_history_initialisation(_) # Passive <=> true
2453 pragma passive(Passive).
2455 find_empty_named_histories,
2456 empty_named_history_initialisations(List, Tail) # Passive <=> List = Tail
2457 pragma passive(Passive).
2459 find_empty_named_histories <=>
2460 chr_error(internal, 'find_empty_named_histories was not removed', []).
2463 empty_named_history_global_variable(Name, GlobalVariable) :-
2464 atom_concat('chr empty named history ', Name, GlobalVariable).
2466 empty_named_history_novel_production(Name, nb_getval(GlobalVariable, 0)) :-
2467 empty_named_history_global_variable(Name, GlobalVariable).
2469 empty_named_history_extend_history(Name, b_setval(GlobalVariable, 1)) :-
2470 empty_named_history_global_variable(Name, GlobalVariable).
2473 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2476 generate_run_suspensions_clauses([],List,List).
2477 generate_run_suspensions_clauses([C|Cs],List,Tail) :-
2478 generate_run_suspensions_clause(C,List,List1),
2479 generate_run_suspensions_clauses(Cs,List1,Tail).
2481 run_suspensions_goal(Constraint,Suspensions,Goal) :-
2482 make_name('$run_suspensions_',Constraint,Name),
2483 Goal =.. [Name,Suspensions].
2485 generate_run_suspensions_clause(Constraint,List,Tail) :-
2486 ( is_used_auxiliary_predicate(run_suspensions,Constraint) ->
2487 List = [Clause1,Clause2|Tail],
2488 run_suspensions_goal(Constraint,[],Clause1),
2489 ( chr_pp_flag(debugable,on) ->
2490 run_suspensions_goal(Constraint,[Suspension|Suspensions],Clause2Head),
2491 get_update_suspension_field(Constraint,Suspension,state,State,triggered,GetState,GetStateValue,UpdateState),
2492 get_update_suspension_field(Constraint,Suspension,state,Post,active,GetPost,GetPostValue,UpdatePost),
2493 get_update_suspension_field(Constraint,Suspension,generation,Gen,Generation,GetGeneration,GetGenerationValue,UpdateGeneration),
2494 get_dynamic_suspension_term_field(continuation,Constraint,Suspension,Continuation,GetContinuation),
2495 run_suspensions_goal(Constraint,Suspensions,Clause2Recursion),
2505 Generation is Gen+1,
2509 'chr debug_event'(wake(Suspension)),
2512 'chr debug_event'(fail(Suspension)), !,
2516 'chr debug_event'(exit(Suspension))
2518 'chr debug_event'(redo(Suspension)),
2523 ( Post==triggered ->
2524 UpdatePost % catching constraints that did not do anything
2534 run_suspensions_goal(Constraint,[Suspension|Suspensions],Clause2Head),
2535 static_suspension_term(Constraint,SuspensionTerm),
2536 get_static_suspension_term_field(arguments,Constraint,SuspensionTerm,Arguments),
2537 append(Arguments,[Suspension],VarsSusp),
2538 make_suspension_continuation_goal(Constraint,VarsSusp,Continuation),
2539 run_suspensions_goal(Constraint,Suspensions,Clause2Recursion),
2540 ( uses_field(Constraint,generation) ->
2541 get_update_static_suspension_field(Constraint,Suspension,SuspensionTerm,generation,Gen,Generation,GetGeneration,UpdateGeneration),
2542 GenerationHandling = ( GetGeneration, Generation is Gen+1, UpdateGeneration)
2544 GenerationHandling = true
2546 get_update_static_suspension_field(Constraint,Suspension,SuspensionTerm,state,State,triggered,GetState,UpdateState),
2547 get_update_static_suspension_field(Constraint,Suspension,SuspensionTerm,state,Post,active,GetPostState,UpdatePostState),
2548 if_used_state(Constraint,removed,
2551 -> ReactivateConstraint
2553 ),ReactivateConstraint,CondReactivate),
2554 ReactivateConstraint =
2560 ( Post==triggered ->
2561 UpdatePostState % catching constraints that did not do anything
2569 Suspension = SuspensionTerm,
2578 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2580 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2581 generate_attach_increment(Clauses) :-
2582 get_max_constraint_index(N),
2583 ( is_used_auxiliary_predicate(attach_increment), N > 0 ->
2584 Clauses = [Clause1,Clause2],
2585 generate_attach_increment_empty(Clause1),
2587 generate_attach_increment_one(Clause2)
2589 generate_attach_increment_many(N,Clause2)
2595 generate_attach_increment_empty((attach_increment([],_) :- true)).
2597 generate_attach_increment_one(Clause) :-
2598 Head = attach_increment([Var|Vars],Susps),
2599 get_target_module(Mod),
2600 ( chr_pp_flag(guard_locks,off) ->
2603 NotLocked = 'chr not_locked'( Var)
2608 ( get_attr(Var,Mod,VarSusps) ->
2609 sort(VarSusps,SortedVarSusps),
2610 'chr merge_attributes'(Susps,SortedVarSusps,MergedSusps),
2611 put_attr(Var,Mod,MergedSusps)
2613 put_attr(Var,Mod,Susps)
2615 attach_increment(Vars,Susps)
2617 Clause = (Head :- Body).
2619 generate_attach_increment_many(N,Clause) :-
2620 Head = attach_increment([Var|Vars],TAttr1),
2621 % writeln(merge_attributes_1_before),
2622 merge_attributes(N,TAttr1,TAttr2,MergeGoal,Attr),
2623 % writeln(merge_attributes_1_after),
2624 get_target_module(Mod),
2625 ( chr_pp_flag(guard_locks,off) ->
2628 NotLocked = 'chr not_locked'( Var)
2633 ( get_attr(Var,Mod,TAttr2) ->
2635 put_attr(Var,Mod,Attr)
2637 put_attr(Var,Mod,TAttr1)
2639 attach_increment(Vars,TAttr1)
2641 Clause = (Head :- Body).
2644 generate_attr_unify_hook(Clauses) :-
2645 get_max_constraint_index(N),
2650 generate_attr_unify_hook_one(Clauses)
2652 generate_attr_unify_hook_many(N,Clauses)
2656 generate_attr_unify_hook_one([Clause]) :-
2657 Head = attr_unify_hook(Susps,Other),
2658 get_target_module(Mod),
2659 get_indexed_constraint(1,C),
2660 ( get_store_type(C,ST),
2661 ( ST = default ; ST = multi_store(STs), member(default,STs) ) ->
2662 make_run_suspensions(NewSusps,SortedSusps,WakeNewSusps),
2663 make_run_suspensions(SortedSusps,SortedSusps,WakeSusps),
2664 ( atomic_types_suspended_constraint(C) ->
2666 SortedSusps = Susps,
2668 SortedOtherSusps = OtherSusps,
2669 MergeGoal = (append(Susps,OtherSusps,List), sort(List,NewSusps)),
2672 SortGoal1 = sort(Susps, SortedSusps),
2673 SortGoal2 = sort(OtherSusps,SortedOtherSusps),
2674 MergeGoal = 'chr merge_attributes'(SortedSusps,SortedOtherSusps,NewSusps),
2675 use_auxiliary_predicate(attach_increment),
2677 ( compound(Other) ->
2678 term_variables(Other,OtherVars),
2679 attach_increment(OtherVars, SortedSusps)
2688 ( get_attr(Other,Mod,OtherSusps) ->
2691 put_attr(Other,Mod,NewSusps),
2694 put_attr(Other,Mod,SortedSusps),
2702 Clause = (Head :- Body)
2703 ; get_store_type(C,var_assoc_store(VarIndex,KeyIndex)) ->
2704 make_run_suspensions(List,List,WakeNewSusps),
2705 MergeGoal = (merge_into_assoc_store(Susps,OtherSusps,List)),
2707 ( get_attr(Other,Mod,OtherSusps) ->
2711 put_attr(Other,Mod,Susps)
2713 Clause = (Head :- Body)
2717 generate_attr_unify_hook_many(N,[Clause]) :-
2718 chr_pp_flag(dynattr,off), !,
2719 Head = attr_unify_hook(Attr,Other),
2720 get_target_module(Mod),
2721 make_attr(N,Mask,SuspsList,Attr),
2722 bagof(Sort,A ^ B ^ ( member(A,SuspsList) , Sort = sort(A,B) ) , SortGoalList),
2723 list2conj(SortGoalList,SortGoals),
2724 bagof(B, A ^ member(sort(A,B),SortGoalList), SortedSuspsList),
2725 merge_attributes2(N,Mask,SortedSuspsList,TOtherAttr,MergeGoal,MergedAttr),
2726 get_all_suspensions2(N,MergedAttr,MergedSuspsList),
2727 make_attr(N,Mask,SortedSuspsList,SortedAttr),
2728 make_run_suspensions_loop(MergedSuspsList,SortedSuspsList,WakeMergedSusps),
2729 make_run_suspensions_loop(SortedSuspsList,SortedSuspsList,WakeSortedSusps),
2730 ( forall((between(1,N,Index), get_indexed_constraint(Index,Constraint)),atomic_types_suspended_constraint(Constraint)) ->
2733 use_auxiliary_predicate(attach_increment),
2735 ( compound(Other) ->
2736 term_variables(Other,OtherVars),
2737 attach_increment(OtherVars,SortedAttr)
2746 ( get_attr(Other,Mod,TOtherAttr) ->
2748 put_attr(Other,Mod,MergedAttr),
2751 put_attr(Other,Mod,SortedAttr),
2759 Clause = (Head :- Body).
2762 generate_attr_unify_hook_many(N,Clauses) :-
2763 Head = attr_unify_hook(Attr,Other),
2764 get_target_module(Mod),
2765 normalize_attr(Attr,NormalGoal,NormalAttr),
2766 normalize_attr(OtherAttr,NormalOtherGoal,NormalOtherAttr),
2767 merge_attributes(N,NormalAttr,NormalOtherAttr,MergeGoal,MergedAttr),
2768 make_run_suspensions(N),
2769 ( forall((between(1,N,Index), get_indexed_constraint(Index,Constraint)),atomic_types_suspended_constraint(Constraint)) ->
2772 use_auxiliary_predicate(attach_increment),
2774 ( compound(Other) ->
2775 term_variables(Other,OtherVars),
2776 attach_increment(OtherVars,NormalAttr)
2785 ( get_attr(Other,Mod,OtherAttr) ->
2788 put_attr(Other,Mod,MergedAttr),
2789 '$dispatch_run_suspensions'(MergedAttr)
2791 put_attr(Other,Mod,NormalAttr),
2792 '$dispatch_run_suspensions'(NormalAttr)
2796 '$dispatch_run_suspensions'(NormalAttr)
2799 Clause = (Head :- Body),
2800 Clauses = [Clause,DispatchList1,DispatchList2|Dispatchers],
2801 DispatchList1 = ('$dispatch_run_suspensions'([])),
2802 DispatchList2 = ('$dispatch_run_suspensions'([Pos-List|Rest]) :- '$dispatch_run_suspensions'(Pos,List),'$dispatch_run_suspensions'(Rest)),
2803 run_suspensions_dispatchers(N,[],Dispatchers).
2806 run_suspensions_dispatchers(N,Acc,Dispatchers) :-
2808 get_indexed_constraint(N,C),
2809 NAcc = [('$dispatch_run_suspensions'(N,List) :- Body)|Acc],
2811 run_suspensions_goal(C,List,Body)
2816 run_suspensions_dispatchers(M,NAcc,Dispatchers)
2822 make_run_suspensions(N) :-
2824 ( get_indexed_constraint(N,C),
2826 use_auxiliary_predicate(run_suspensions,C)
2831 make_run_suspensions(M)
2836 make_run_suspensions(AllSusps,OneSusps,Goal) :-
2837 make_run_suspensions(1,AllSusps,OneSusps,Goal).
2839 make_run_suspensions(Index,AllSusps,OneSusps,Goal) :-
2840 ( get_indexed_constraint(Index,C), may_trigger(C) ->
2841 use_auxiliary_predicate(run_suspensions,C),
2842 ( wakes_partially(C) ->
2843 run_suspensions_goal(C,OneSusps,Goal)
2845 run_suspensions_goal(C,AllSusps,Goal)
2851 make_run_suspensions_loop(AllSuspsList,OneSuspsList,Goal) :-
2852 make_run_suspensions_loop(AllSuspsList,OneSuspsList,1,Goal).
2854 make_run_suspensions_loop([],[],_,true).
2855 make_run_suspensions_loop([AllSusps|AllSuspsList],[OneSusps|OneSuspsList],I,(Goal,Goals)) :-
2856 make_run_suspensions(I,AllSusps,OneSusps,Goal),
2858 make_run_suspensions_loop(AllSuspsList,OneSuspsList,J,Goals).
2860 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2861 % $insert_in_store_F/A
2862 % $delete_from_store_F/A
2864 generate_insert_delete_constraints([],[]).
2865 generate_insert_delete_constraints([FA|Rest],Clauses) :-
2867 generate_insert_delete_constraint(FA,Clauses,RestClauses)
2869 Clauses = RestClauses
2871 generate_insert_delete_constraints(Rest,RestClauses).
2873 generate_insert_delete_constraint(FA,Clauses,RestClauses) :-
2874 insert_constraint_clause(FA,Clauses,RestClauses1),
2875 delete_constraint_clause(FA,RestClauses1,RestClauses).
2877 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
2880 insert_constraint_goal(FA,Susp,Vars,Goal) :-
2881 ( chr_pp_flag(inline_insertremove,off) ->
2882 use_auxiliary_predicate(insert_in_store,FA),
2883 insert_constraint_atom(FA,Susp,Goal)
2885 delay_phase_end(validate_store_type_assumptions,
2886 ( insert_constraint_body(FA,Susp,UsedVars,Goal),
2887 insert_constraint_direct_used_vars(UsedVars,Vars)
2892 insert_constraint_direct_used_vars([],_).
2893 insert_constraint_direct_used_vars([Index-Var|Rest],Vars) :-
2894 nth1(Index,Vars,Var),
2895 insert_constraint_direct_used_vars(Rest,Vars).
2897 insert_constraint_atom(FA,Susp,Call) :-
2898 make_name('$insert_in_store_',FA,Functor),
2899 Call =.. [Functor,Susp].
2901 insert_constraint_clause(C,Clauses,RestClauses) :-
2902 ( is_used_auxiliary_predicate(insert_in_store,C) ->
2903 Clauses = [Clause|RestClauses],
2904 Clause = (Head :- InsertCounterInc,VarsBody,Body),
2905 insert_constraint_atom(C,Susp,Head),
2906 insert_constraint_body(C,Susp,UsedVars,Body),
2907 insert_constraint_used_vars(UsedVars,C,Susp,VarsBody),
2908 ( chr_pp_flag(store_counter,on) ->
2909 InsertCounterInc = '$insert_counter_inc'
2911 InsertCounterInc = true
2914 Clauses = RestClauses
2917 insert_constraint_used_vars([],_,_,true).
2918 insert_constraint_used_vars([Index-Var|Rest],C,Susp,(Goal,Goals)) :-
2919 get_dynamic_suspension_term_field(argument(Index),C,Susp,Var,Goal),
2920 insert_constraint_used_vars(Rest,C,Susp,Goals).
2922 insert_constraint_body(C,Susp,UsedVars,Body) :-
2923 get_store_type(C,StoreType),
2924 insert_constraint_body(StoreType,C,Susp,UsedVars,Body).
2926 insert_constraint_body(default,C,Susp,[],Body) :-
2927 global_list_store_name(C,StoreName),
2928 make_get_store_goal(StoreName,Store,GetStoreGoal),
2929 make_update_store_goal(StoreName,Cell,UpdateStoreGoal),
2930 ( chr_pp_flag(debugable,on) ->
2931 Cell = [Susp|Store],
2938 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,Cell,SetGoal),
2942 Cell = [Susp|Store],
2944 ( Store = [NextSusp|_] ->
2951 % get_target_module(Mod),
2952 % get_max_constraint_index(Total),
2954 % generate_attach_body_1(C,Store,Susp,AttachBody)
2956 % generate_attach_body_n(C,Store,Susp,AttachBody)
2960 % 'chr default_store'(Store),
2963 insert_constraint_body(multi_inthash(Indexes),C,Susp,[],Body) :-
2964 generate_multi_inthash_insert_constraint_bodies(Indexes,C,Susp,Body).
2965 insert_constraint_body(multi_hash(Indexes),C,Susp,MixedUsedVars,Body) :-
2966 generate_multi_hash_insert_constraint_bodies(Indexes,C,Susp,Body,MixedUsedVars),
2967 sort_out_used_vars(MixedUsedVars,UsedVars).
2968 insert_constraint_body(atomic_constants(Index,_,_),C,Susp,UsedVars,Body) :-
2969 multi_hash_key_direct(C,Index,Susp,Key,UsedVars),
2970 constants_store_index_name(C,Index,IndexName),
2971 IndexLookup =.. [IndexName,Key,StoreName],
2974 nb_getval(StoreName,Store),
2975 b_setval(StoreName,[Susp|Store])
2979 insert_constraint_body(ground_constants(Index,_),C,Susp,UsedVars,Body) :-
2980 multi_hash_key_direct(C,Index,Susp,Key,UsedVars),
2981 constants_store_index_name(C,Index,IndexName),
2982 IndexLookup =.. [IndexName,Key,StoreName],
2985 nb_getval(StoreName,Store),
2986 b_setval(StoreName,[Susp|Store])
2990 insert_constraint_body(global_ground,C,Susp,[],Body) :-
2991 global_ground_store_name(C,StoreName),
2992 make_get_store_goal(StoreName,Store,GetStoreGoal),
2993 make_update_store_goal(StoreName,Cell,UpdateStoreGoal),
2994 ( chr_pp_flag(debugable,on) ->
2995 Cell = [Susp|Store],
3002 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,Cell,SetGoal),
3006 Cell = [Susp|Store],
3008 ( Store = [NextSusp|_] ->
3015 % global_ground_store_name(C,StoreName),
3016 % make_get_store_goal(StoreName,Store,GetStoreGoal),
3017 % make_update_store_goal(StoreName,[Susp|Store],UpdateStoreGoal),
3020 % GetStoreGoal, % nb_getval(StoreName,Store),
3021 % UpdateStoreGoal % b_setval(StoreName,[Susp|Store])
3023 insert_constraint_body(var_assoc_store(VarIndex,AssocIndex),C,Susp,[VarIndex-Variable,AssocIndex-Key],Body) :-
3024 % TODO: generalize to more than one !!!
3025 get_target_module(Module),
3026 Body = ( get_attr(Variable,Module,AssocStore) ->
3027 insert_assoc_store(AssocStore,Key,Susp)
3029 new_assoc_store(AssocStore),
3030 put_attr(Variable,Module,AssocStore),
3031 insert_assoc_store(AssocStore,Key,Susp)
3034 insert_constraint_body(global_singleton,C,Susp,[],Body) :-
3035 global_singleton_store_name(C,StoreName),
3036 make_update_store_goal(StoreName,Susp,UpdateStoreGoal),
3041 insert_constraint_body(multi_store(StoreTypes),C,Susp,UsedVars,Body) :-
3042 find_with_var_identity(
3046 member(ST,StoreTypes),
3047 chr_translate:insert_constraint_body(ST,C,Susp,UV,B)
3051 once(pairup(Bodies,NestedUsedVars,BodiesUsedVars)),
3052 list2conj(Bodies,Body),
3053 sort_out_used_vars(NestedUsedVars,UsedVars).
3054 insert_constraint_body(identifier_store(Index),C,Susp,UsedVars,Body) :-
3055 UsedVars = [Index-Var],
3056 get_identifier_size(ISize),
3057 functor(Struct,struct,ISize),
3058 get_identifier_index(C,Index,IIndex),
3059 arg(IIndex,Struct,Susps),
3060 Body = (Var = Struct, setarg(IIndex,Var,[Susp|Susps])).
3061 insert_constraint_body(type_indexed_identifier_store(Index,IndexType),C,Susp,UsedVars,Body) :-
3062 UsedVars = [Index-Var],
3063 type_indexed_identifier_structure(IndexType,Struct),
3064 get_type_indexed_identifier_index(IndexType,C,Index,IIndex),
3065 arg(IIndex,Struct,Susps),
3066 Body = (Var = Struct, setarg(IIndex,Var,[Susp|Susps])).
3068 sort_out_used_vars(NestedUsedVars,UsedVars) :-
3069 flatten(NestedUsedVars,FlatUsedVars),
3070 sort(FlatUsedVars,SortedFlatUsedVars),
3071 sort_out_used_vars1(SortedFlatUsedVars,UsedVars).
3073 sort_out_used_vars1([],[]).
3074 sort_out_used_vars1([I-V],L) :- !, L = [I-V].
3075 sort_out_used_vars1([I-X,J-Y|R],L) :-
3078 sort_out_used_vars1([I-X|R],L)
3081 sort_out_used_vars1([J-Y|R],T)
3084 generate_multi_inthash_insert_constraint_bodies([],_,_,true).
3085 generate_multi_inthash_insert_constraint_bodies([Index|Indexes],FA,Susp,(Body,Bodies)) :-
3086 multi_hash_store_name(FA,Index,StoreName),
3087 multi_hash_key(FA,Index,Susp,KeyBody,Key),
3091 nb_getval(StoreName,Store),
3092 insert_iht(Store,Key,Susp)
3094 generate_multi_inthash_insert_constraint_bodies(Indexes,FA,Susp,Bodies).
3096 generate_multi_hash_insert_constraint_bodies([],_,_,true,[]).
3097 generate_multi_hash_insert_constraint_bodies([Index|Indexes],FA,Susp,(Body,Bodies),[UsedVars|MoreUsedVars]) :-
3098 multi_hash_store_name(FA,Index,StoreName),
3099 multi_hash_key_direct(FA,Index,Susp,Key,UsedVars),
3100 make_get_store_goal(StoreName,Store,GetStoreGoal),
3101 ( chr_pp_flag(ht_removal,on)
3102 -> ht_prev_field(Index,PrevField),
3103 set_dynamic_suspension_term_field(PrevField,FA,NextSusp,Result,
3108 insert_ht(Store,Key,Susp,Result),
3109 ( Result = [_,NextSusp|_]
3117 insert_ht(Store,Key,Susp)
3120 generate_multi_hash_insert_constraint_bodies(Indexes,FA,Susp,Bodies,MoreUsedVars).
3122 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3125 delete_constraint_clause(C,Clauses,RestClauses) :-
3126 ( is_used_auxiliary_predicate(delete_from_store,C) ->
3127 Clauses = [Clause|RestClauses],
3128 Clause = (Head :- Body),
3129 delete_constraint_atom(C,Susp,Head),
3132 delete_constraint_body(C,Head,Susp,[],Body)
3134 Clauses = RestClauses
3137 delete_constraint_goal(Head,Susp,VarDict,Goal) :-
3140 ( chr_pp_flag(inline_insertremove,off) ->
3141 use_auxiliary_predicate(delete_from_store,C),
3142 delete_constraint_atom(C,Susp,Goal)
3144 delay_phase_end(validate_store_type_assumptions, delete_constraint_body(C,Head,Susp,VarDict,Goal))
3147 delete_constraint_atom(C,Susp,Atom) :-
3148 make_name('$delete_from_store_',C,Functor),
3149 Atom =.. [Functor,Susp].
3152 delete_constraint_body(C,Head,Susp,VarDict,Body) :-
3153 Body = (CounterBody,DeleteBody),
3154 ( chr_pp_flag(store_counter,on) ->
3155 CounterBody = '$delete_counter_inc'
3159 get_store_type(C,StoreType),
3160 delete_constraint_body(StoreType,C,Head,Susp,VarDict,DeleteBody).
3162 delete_constraint_body(default,C,_,Susp,_,Body) :-
3163 ( chr_pp_flag(debugable,on) ->
3164 global_list_store_name(C,StoreName),
3165 make_get_store_goal(StoreName,Store,GetStoreGoal),
3166 make_update_store_goal(StoreName,NStore,UpdateStoreGoal),
3169 GetStoreGoal, % nb_getval(StoreName,Store),
3170 'chr sbag_del_element'(Store,Susp,NStore),
3171 UpdateStoreGoal % b_setval(StoreName,NStore)
3174 get_dynamic_suspension_term_field(global_list_prev,C,Susp,PredCell,GetGoal),
3175 global_list_store_name(C,StoreName),
3176 make_get_store_goal(StoreName,Store,GetStoreGoal),
3177 make_update_store_goal(StoreName,Tail,UpdateStoreGoal),
3178 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,_,SetGoal1),
3179 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,PredCell,SetGoal2),
3184 GetStoreGoal, % nb_getval(StoreName,Store),
3187 ( Tail = [NextSusp|_] ->
3193 PredCell = [_,_|Tail],
3194 setarg(2,PredCell,Tail),
3195 ( Tail = [NextSusp|_] ->
3203 % get_target_module(Mod),
3204 % get_max_constraint_index(Total),
3206 % generate_detach_body_1(C,Store,Susp,DetachBody),
3209 % 'chr default_store'(Store),
3213 % generate_detach_body_n(C,Store,Susp,DetachBody),
3216 % 'chr default_store'(Store),
3220 delete_constraint_body(multi_inthash(Indexes),C,_,Susp,_,Body) :-
3221 generate_multi_inthash_delete_constraint_bodies(Indexes,C,Susp,Body).
3222 delete_constraint_body(multi_hash(Indexes),C,Head,Susp,VarDict,Body) :-
3223 generate_multi_hash_delete_constraint_bodies(Indexes,C,Head,Susp,VarDict,Body).
3224 delete_constraint_body(atomic_constants(Index,_,_),C,Head,Susp,VarDict,Body) :-
3225 multi_hash_key(C,Head,Index,Susp,VarDict,KeyBody,Key),
3226 constants_store_index_name(C,Index,IndexName),
3227 IndexLookup =.. [IndexName,Key,StoreName],
3231 nb_getval(StoreName,Store),
3232 'chr sbag_del_element'(Store,Susp,NStore),
3233 b_setval(StoreName,NStore)
3237 delete_constraint_body(ground_constants(Index,_),C,Head,Susp,VarDict,Body) :-
3238 multi_hash_key(C,Head,Index,Susp,VarDict,KeyBody,Key),
3239 constants_store_index_name(C,Index,IndexName),
3240 IndexLookup =.. [IndexName,Key,StoreName],
3244 nb_getval(StoreName,Store),
3245 'chr sbag_del_element'(Store,Susp,NStore),
3246 b_setval(StoreName,NStore)
3250 delete_constraint_body(global_ground,C,_,Susp,_,Body) :-
3251 ( chr_pp_flag(debugable,on) ->
3252 global_ground_store_name(C,StoreName),
3253 make_get_store_goal(StoreName,Store,GetStoreGoal),
3254 make_update_store_goal(StoreName,NStore,UpdateStoreGoal),
3257 GetStoreGoal, % nb_getval(StoreName,Store),
3258 'chr sbag_del_element'(Store,Susp,NStore),
3259 UpdateStoreGoal % b_setval(StoreName,NStore)
3262 get_dynamic_suspension_term_field(global_list_prev,C,Susp,PredCell,GetGoal),
3263 global_ground_store_name(C,StoreName),
3264 make_get_store_goal(StoreName,Store,GetStoreGoal),
3265 make_update_store_goal(StoreName,Tail,UpdateStoreGoal),
3266 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,_,SetGoal1),
3267 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,PredCell,SetGoal2),
3272 GetStoreGoal, % nb_getval(StoreName,Store),
3275 ( Tail = [NextSusp|_] ->
3281 PredCell = [_,_|Tail],
3282 setarg(2,PredCell,Tail),
3283 ( Tail = [NextSusp|_] ->
3291 % global_ground_store_name(C,StoreName),
3292 % make_get_store_goal(StoreName,Store,GetStoreGoal),
3293 % make_update_store_goal(StoreName,NStore,UpdateStoreGoal),
3296 % GetStoreGoal, % nb_getval(StoreName,Store),
3297 % 'chr sbag_del_element'(Store,Susp,NStore),
3298 % UpdateStoreGoal % b_setval(StoreName,NStore)
3300 delete_constraint_body(var_assoc_store(VarIndex,AssocIndex),C,_,Susp,_,Body) :-
3301 get_target_module(Module),
3302 get_dynamic_suspension_term_field(argument(VarIndex),C,Susp,Variable,VariableGoal),
3303 get_dynamic_suspension_term_field(argument(AssocIndex),C,Susp,Key,KeyGoal),
3306 get_attr(Variable,Module,AssocStore),
3308 delete_assoc_store(AssocStore,Key,Susp)
3310 delete_constraint_body(global_singleton,C,_,_Susp,_,Body) :-
3311 global_singleton_store_name(C,StoreName),
3312 make_update_store_goal(StoreName,[],UpdateStoreGoal),
3315 UpdateStoreGoal % b_setval(StoreName,[])
3317 delete_constraint_body(multi_store(StoreTypes),C,Head,Susp,VarDict,Body) :-
3318 find_with_var_identity(
3320 [Susp/VarDict/Head],
3322 member(ST,StoreTypes),
3323 chr_translate:delete_constraint_body(ST,C,Head,Susp,VarDict,B)
3327 list2conj(Bodies,Body).
3328 delete_constraint_body(identifier_store(Index),C,Head,Susp,VarDict,Body) :-
3329 get_suspension_argument_possibly_in_scope(Head,Index,VarDict,Susp,Variable,VariableGoal),
3330 get_identifier_size(ISize),
3331 functor(Struct,struct,ISize),
3332 get_identifier_index(C,Index,IIndex),
3333 arg(IIndex,Struct,Susps),
3337 'chr sbag_del_element'(Susps,Susp,NSusps),
3338 setarg(IIndex,Variable,NSusps)
3340 delete_constraint_body(type_indexed_identifier_store(Index,IndexType),C,Head,Susp,VarDict,Body) :-
3341 get_suspension_argument_possibly_in_scope(Head,Index,VarDict,Susp,Variable,VariableGoal),
3342 type_indexed_identifier_structure(IndexType,Struct),
3343 get_type_indexed_identifier_index(IndexType,C,Index,IIndex),
3344 arg(IIndex,Struct,Susps),
3348 'chr sbag_del_element'(Susps,Susp,NSusps),
3349 setarg(IIndex,Variable,NSusps)
3352 generate_multi_inthash_delete_constraint_bodies([],_,_,true).
3353 generate_multi_inthash_delete_constraint_bodies([Index|Indexes],FA,Susp,(Body,Bodies)) :-
3354 multi_hash_store_name(FA,Index,StoreName),
3355 multi_hash_key(FA,Index,Susp,KeyBody,Key),
3359 nb_getval(StoreName,Store),
3360 delete_iht(Store,Key,Susp)
3362 generate_multi_inthash_delete_constraint_bodies(Indexes,FA,Susp,Bodies).
3363 generate_multi_hash_delete_constraint_bodies([],_,_,_,_,true).
3364 generate_multi_hash_delete_constraint_bodies([Index|Indexes],C,Head,Susp,VarDict,(Body,Bodies)) :-
3365 multi_hash_store_name(C,Index,StoreName),
3366 multi_hash_key(C,Head,Index,Susp,VarDict,KeyBody,Key),
3367 make_get_store_goal(StoreName,Store,GetStoreGoal),
3368 ( chr_pp_flag(ht_removal,on)
3369 -> ht_prev_field(Index,PrevField),
3370 get_dynamic_suspension_term_field(PrevField,C,Susp,Prev,GetGoal),
3371 set_dynamic_suspension_term_field(PrevField,C,NextSusp,_,
3373 set_dynamic_suspension_term_field(PrevField,C,NextSusp,Prev,
3381 delete_first_ht(Store,Key,Values),
3382 ( Values = [NextSusp|_]
3386 ; Prev = [_,_|Values],
3387 setarg(2,Prev,Values),
3388 ( Values = [NextSusp|_]
3397 GetStoreGoal, % nb_getval(StoreName,Store),
3398 delete_ht(Store,Key,Susp)
3401 generate_multi_hash_delete_constraint_bodies(Indexes,FA,Head,Susp,VarDict,Bodies).
3403 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3406 module_initializer/1,
3407 module_initializers/1.
3409 module_initializers(G), module_initializer(Initializer) <=>
3410 G = (Initializer,Initializers),
3411 module_initializers(Initializers).
3413 module_initializers(G) <=>
3416 generate_attach_code(Constraints,[Enumerate|L]) :-
3417 enumerate_stores_code(Constraints,Enumerate),
3418 generate_attach_code(Constraints,L,T),
3419 module_initializers(Initializers),
3420 prolog_global_variables_code(PrologGlobalVariables),
3421 T = [('$chr_initialization' :- Initializers),(:- initialization '$chr_initialization')|PrologGlobalVariables].
3423 generate_attach_code([],L,L).
3424 generate_attach_code([C|Cs],L,T) :-
3425 get_store_type(C,StoreType),
3426 generate_attach_code(StoreType,C,L,L1),
3427 generate_attach_code(Cs,L1,T).
3429 generate_attach_code(default,C,L,T) :-
3430 global_list_store_initialisation(C,L,T).
3431 generate_attach_code(multi_inthash(Indexes),C,L,T) :-
3432 multi_inthash_store_initialisations(Indexes,C,L,L1),
3433 multi_inthash_via_lookups(Indexes,C,L1,T).
3434 generate_attach_code(multi_hash(Indexes),C,L,T) :-
3435 multi_hash_store_initialisations(Indexes,C,L,L1),
3436 multi_hash_lookups(Indexes,C,L1,T).
3437 generate_attach_code(atomic_constants(Index,Constants,_),C,L,T) :-
3438 constants_initializers(C,Index,Constants),
3439 atomic_constants_code(C,Index,Constants,L,T).
3440 generate_attach_code(ground_constants(Index,Constants),C,L,T) :-
3441 constants_initializers(C,Index,Constants),
3442 ground_constants_code(C,Index,Constants,L,T).
3443 generate_attach_code(global_ground,C,L,T) :-
3444 global_ground_store_initialisation(C,L,T).
3445 generate_attach_code(var_assoc_store(_,_),_,L,L) :-
3446 use_auxiliary_module(chr_assoc_store).
3447 generate_attach_code(global_singleton,C,L,T) :-
3448 global_singleton_store_initialisation(C,L,T).
3449 generate_attach_code(multi_store(StoreTypes),C,L,T) :-
3450 multi_store_generate_attach_code(StoreTypes,C,L,T).
3451 generate_attach_code(identifier_store(Index),C,L,T) :-
3452 get_identifier_index(C,Index,IIndex),
3454 get_identifier_size(ISize),
3455 functor(Struct,struct,ISize),
3456 Struct =.. [_,Label|Stores],
3457 set_elems(Stores,[]),
3458 Clause1 = new_identifier(Label,Struct),
3459 functor(Struct2,struct,ISize),
3460 arg(1,Struct2,Label2),
3462 ( user:portray(Struct2) :-
3467 functor(Struct3,struct,ISize),
3468 arg(1,Struct3,Label3),
3469 Clause3 = identifier_label(Struct3,Label3),
3470 L = [Clause1,Clause2,Clause3|T]
3474 generate_attach_code(type_indexed_identifier_store(Index,IndexType),C,L,T) :-
3475 get_type_indexed_identifier_index(IndexType,C,Index,IIndex),
3477 identifier_store_initialization(IndexType,L,L1),
3478 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3479 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3480 get_type_indexed_identifier_size(IndexType,ISize),
3481 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3482 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3483 type_indexed_identifier_structure(IndexType,Struct),
3484 Struct =.. [_,Label|Stores],
3485 set_elems(Stores,[]),
3486 type_indexed_identifier_name(IndexType,new_identifier,Name1),
3487 Clause1 =.. [Name1,Label,Struct],
3488 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3489 Goal1 =.. [Name1,Label1b,S1b],
3490 type_indexed_identifier_structure(IndexType,Struct1b),
3491 Struct1b =.. [_,Label1b|Stores1b],
3492 set_elems(Stores1b,[]),
3493 Expansion1 = (S1b = Struct1b),
3494 Clause1b = user:goal_expansion(Goal1,Expansion1),
3495 % writeln(Clause1-Clause1b),
3496 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3497 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3498 type_indexed_identifier_structure(IndexType,Struct2),
3499 arg(1,Struct2,Label2),
3501 ( user:portray(Struct2) :-
3506 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3507 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3508 type_indexed_identifier_structure(IndexType,Struct3),
3509 arg(1,Struct3,Label3),
3510 type_indexed_identifier_name(IndexType,identifier_label,Name3),
3511 Clause3 =.. [Name3,Struct3,Label3],
3512 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3513 Goal3b =.. [Name3,S3b,L3b],
3514 type_indexed_identifier_structure(IndexType,Struct3b),
3515 arg(1,Struct3b,L3b),
3516 Expansion3b = (S3 = Struct3b),
3517 Clause3b = ( user:goal_expansion(Goal3b,Expansion3b) :- writeln(expanding)),
3518 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3519 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3520 identifier_store_name(IndexType,GlobalVariable),
3521 lookup_identifier_atom(IndexType,X,IX,LookupAtom),
3522 type_indexed_identifier_name(IndexType,new_identifier,NewIdentifierFunctor),
3523 NewIdentifierGoal =.. [NewIdentifierFunctor,X,IX],
3526 nb_getval(GlobalVariable,HT),
3527 ( lookup_ht(HT,X,[IX]) ->
3534 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3535 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3536 L1 = [(:- multifile goal_expansion/2),(:- dynamic goal_expansion/2),Clause1,Clause1b,Clause2,Clause3,Clause3b,Clause4|T]
3541 constants_initializers(C,Index,Constants) :-
3542 maplist(constants_store_name(C,Index),Constants,StoreNames),
3543 findall(Initializer,
3544 ( member(StoreName,StoreNames),
3545 Initializer = nb_setval(StoreName,[])
3548 maplist(module_initializer,Initializers).
3550 lookup_identifier_atom(Key,X,IX,Atom) :-
3551 atom_concat('lookup_identifier_',Key,LookupFunctor),
3552 Atom =.. [LookupFunctor,X,IX].
3554 identifier_label_atom(IndexType,IX,X,Atom) :-
3555 type_indexed_identifier_name(IndexType,identifier_label,Name),
3556 Atom =.. [Name,IX,X].
3558 multi_store_generate_attach_code([],_,L,L).
3559 multi_store_generate_attach_code([ST|STs],C,L,T) :-
3560 generate_attach_code(ST,C,L,L1),
3561 multi_store_generate_attach_code(STs,C,L1,T).
3563 multi_inthash_store_initialisations([],_,L,L).
3564 multi_inthash_store_initialisations([Index|Indexes],FA,L,T) :-
3565 use_auxiliary_module(chr_integertable_store),
3566 multi_hash_store_name(FA,Index,StoreName),
3567 module_initializer((new_iht(HT),nb_setval(StoreName,HT))),
3568 % L = [(:- (chr_integertable_store:new_ht(HT),nb_setval(StoreName,HT)) )|L1],
3570 multi_inthash_store_initialisations(Indexes,FA,L1,T).
3571 multi_hash_store_initialisations([],_,L,L).
3572 multi_hash_store_initialisations([Index|Indexes],FA,L,T) :-
3573 use_auxiliary_module(chr_hashtable_store),
3574 multi_hash_store_name(FA,Index,StoreName),
3575 prolog_global_variable(StoreName),
3576 make_init_store_goal(StoreName,HT,InitStoreGoal),
3577 module_initializer((new_ht(HT),InitStoreGoal)),
3579 multi_hash_store_initialisations(Indexes,FA,L1,T).
3581 global_list_store_initialisation(C,L,T) :-
3583 global_list_store_name(C,StoreName),
3584 prolog_global_variable(StoreName),
3585 make_init_store_goal(StoreName,[],InitStoreGoal),
3586 module_initializer(InitStoreGoal)
3591 global_ground_store_initialisation(C,L,T) :-
3592 global_ground_store_name(C,StoreName),
3593 prolog_global_variable(StoreName),
3594 make_init_store_goal(StoreName,[],InitStoreGoal),
3595 module_initializer(InitStoreGoal),
3597 global_singleton_store_initialisation(C,L,T) :-
3598 global_singleton_store_name(C,StoreName),
3599 prolog_global_variable(StoreName),
3600 make_init_store_goal(StoreName,[],InitStoreGoal),
3601 module_initializer(InitStoreGoal),
3603 identifier_store_initialization(IndexType,L,T) :-
3604 use_auxiliary_module(chr_hashtable_store),
3605 identifier_store_name(IndexType,StoreName),
3606 prolog_global_variable(StoreName),
3607 make_init_store_goal(StoreName,HT,InitStoreGoal),
3608 module_initializer((new_ht(HT),InitStoreGoal)),
3612 multi_inthash_via_lookups([],_,L,L).
3613 multi_inthash_via_lookups([Index|Indexes],C,L,T) :-
3614 multi_hash_lookup_head(C,Index,Key,SuspsList,Head),
3615 multi_hash_lookup_body(C,inthash,Index,Key,SuspsList,Body),
3616 L = [(Head :- Body)|L1],
3617 multi_inthash_via_lookups(Indexes,C,L1,T).
3618 multi_hash_lookups([],_,L,L).
3619 multi_hash_lookups([Index|Indexes],C,L,T) :-
3620 multi_hash_lookup_head(C,Index,Key,SuspsList,Head),
3621 multi_hash_lookup_body(C,hash,Index,Key,SuspsList,Body),
3622 L = [(Head :- Body)|L1],
3623 multi_hash_lookups(Indexes,C,L1,T).
3625 multi_hash_lookup_head(ConstraintSymbol,Index,Key,SuspsList,Head) :-
3626 multi_hash_lookup_name(ConstraintSymbol,Index,Name),
3627 Head =.. [Name,Key,SuspsList].
3629 %% multi_hash_lookup_body(+ConstraintSymbol,+HashType,+Index,+Key,+SuspsList,-Goal) is det.
3631 % Returns goal that performs hash table lookup.
3632 multi_hash_lookup_body(ConstraintSymbol,HashType,Index,Key,SuspsList,Goal) :-
3634 ( get_store_type(ConstraintSymbol,multi_store(Stores)),
3635 memberchk(atomic_constants(Index,Constants,_),Stores) ->
3637 constants_store_name(ConstraintSymbol,Index,Key,StoreName),
3638 Goal = nb_getval(StoreName,SuspsList)
3640 constants_store_index_name(ConstraintSymbol,Index,IndexName),
3641 Lookup =.. [IndexName,Key,StoreName],
3642 Goal = (Lookup, nb_getval(StoreName,SuspsList))
3644 ; get_store_type(ConstraintSymbol,multi_store(Stores)),
3645 memberchk(ground_constants(Index,Constants),Stores) ->
3647 constants_store_name(ConstraintSymbol,Index,Key,StoreName),
3648 Goal = nb_getval(StoreName,SuspsList)
3650 constants_store_index_name(ConstraintSymbol,Index,IndexName),
3651 Lookup =.. [IndexName,Key,StoreName],
3652 Goal = (Lookup, nb_getval(StoreName,SuspsList))
3655 multi_hash_store_name(ConstraintSymbol,Index,StoreName),
3656 make_get_store_goal(StoreName,HT,GetStoreGoal),
3657 ( HashType == hash, specialized_hash_term_call(Key,Hash,HashCall) ->
3660 GetStoreGoal, % nb_getval(StoreName,HT),
3661 HashCall, % hash_term(Key,Hash),
3662 lookup_ht1(HT,Hash,Key,SuspsList)
3665 lookup_hash_call(HashType,HT,Key,SuspsList,Lookup),
3668 GetStoreGoal, % nb_getval(StoreName,HT),
3669 hash_term(Key,Hash),
3676 lookup_hash_call(hash,HT,Key,SuspsList,lookup_ht(HT,Key,SuspsList)).
3677 lookup_hash_call(inthash,HT,Key,SuspsList,lookup_iht(HT,Key,SuspsList)).
3679 specialized_hash_term_call(Key,Hash,Call) :-
3681 % This is based on a property of SWI-Prolog's
3682 % hash_term/2 predicate:
3683 % the hash value is stable over repeated invocations
3685 hash_term(Key,Hash),
3689 specialize_hash_term(Key,NewKey),
3691 Call = hash_term(NewKey,Hash)
3694 specialize_hash_term(Term,NewTerm) :-
3696 hash_term(Term,NewTerm)
3701 maplist(specialize_hash_term,Args,NewArgs),
3702 NewTerm =.. [F|NewArgs]
3705 multi_hash_lookup_goal(ConstraintSymbol,HashType,Index,Key,SuspsList,Goal) :-
3706 ( /* chr_pp_flag(experiment,off) ->
3709 actual_atomic_multi_hash_keys(ConstraintSymbol,Index,[Key])
3711 actual_ground_multi_hash_keys(ConstraintSymbol,Index,[Key])
3713 actual_non_atomic_multi_hash_key(ConstraintSymbol,Index)
3715 delay_phase_end(validate_store_type_assumptions,
3716 multi_hash_lookup_body(ConstraintSymbol,HashType,Index,Key,SuspsList,Goal)).
3718 :- chr_constraint actual_atomic_multi_hash_keys/3.
3719 :- chr_option(mode,actual_atomic_multi_hash_keys(+,+,?)).
3721 :- chr_constraint actual_ground_multi_hash_keys/3.
3722 :- chr_option(mode,actual_ground_multi_hash_keys(+,+,?)).
3724 :- chr_constraint actual_non_atomic_multi_hash_key/2.
3725 :- chr_option(mode,actual_non_atomic_multi_hash_key(+,+)).
3728 actual_atomic_multi_hash_keys(C,Index,Keys)
3729 ==> format('Keys: ~w - ~w : ~w\n', [C,Index,Keys]).
3731 actual_ground_multi_hash_keys(C,Index,Keys)
3732 ==> format('Keys: ~w - ~w : ~w\n', [C,Index,Keys]).
3734 actual_non_atomic_multi_hash_key(C,Index)
3735 ==> format('Keys: ~w - ~w : N/A\n', [C,Index]).
3737 actual_atomic_multi_hash_keys(C,Index,Keys1), actual_atomic_multi_hash_keys(C,Index,Keys2)
3738 <=> append(Keys1,Keys2,Keys0),
3740 actual_atomic_multi_hash_keys(C,Index,Keys).
3742 actual_ground_multi_hash_keys(C,Index,Keys1), actual_atomic_multi_hash_keys(C,Index,Keys2)
3743 <=> append(Keys1,Keys2,Keys0),
3745 actual_ground_multi_hash_keys(C,Index,Keys).
3747 actual_ground_multi_hash_keys(C,Index,Keys1), actual_ground_multi_hash_keys(C,Index,Keys2)
3748 <=> append(Keys1,Keys2,Keys0),
3750 actual_ground_multi_hash_keys(C,Index,Keys).
3752 actual_non_atomic_multi_hash_key(C,Index) \ actual_non_atomic_multi_hash_key(C,Index)
3755 actual_non_atomic_multi_hash_key(C,Index) \ actual_atomic_multi_hash_keys(C,Index,_)
3758 actual_non_atomic_multi_hash_key(C,Index) \ actual_ground_multi_hash_keys(C,Index,_)
3761 %% multi_hash_lookup_name(+ConstraintSymbol,+Index,-Name)
3763 % Returns predicate name of hash table lookup predicate.
3764 multi_hash_lookup_name(F/A,Index,Name) :-
3768 atom_concat_list(Index,IndexName)
3770 atom_concat_list(['$via1_multi_hash_',F,'___',A,'-',IndexName],Name).
3772 multi_hash_store_name(F/A,Index,Name) :-
3773 get_target_module(Mod),
3777 atom_concat_list(Index,IndexName)
3779 atom_concat_list(['$chr_store_multi_hash_',Mod,'____',F,'___',A,'-',IndexName],Name).
3781 multi_hash_key(FA,Index,Susp,KeyBody,Key) :-
3782 ( ( integer(Index) ->
3787 get_dynamic_suspension_term_field(argument(I),FA,Susp,Key,KeyBody)
3789 sort(Index,Indexes),
3790 find_with_var_identity(Goal-KeyI,[Susp],(member(I,Indexes),get_dynamic_suspension_term_field(argument(I),FA,Susp,KeyI,Goal)),ArgKeyPairs),
3791 once(pairup(Bodies,Keys,ArgKeyPairs)),
3793 list2conj(Bodies,KeyBody)
3796 multi_hash_key(C,Head,Index,Susp,VarDict,KeyBody,Key) :-
3797 ( ( integer(Index) ->
3802 get_suspension_argument_possibly_in_scope(Head,I,VarDict,Susp,Key,KeyBody)
3804 sort(Index,Indexes),
3805 find_with_var_identity(
3807 [Susp/Head/VarDict],
3810 get_suspension_argument_possibly_in_scope(Head,I,VarDict,Susp,KeyI,Goal)
3814 once(pairup(Bodies,Keys,ArgKeyPairs)),
3816 list2conj(Bodies,KeyBody)
3819 get_suspension_argument_possibly_in_scope(Head,Index,VarDict,Susp,Arg,Goal) :-
3820 arg(Index,Head,OriginalArg),
3821 ( lookup_eq(VarDict,OriginalArg,Arg) ->
3826 get_dynamic_suspension_term_field(argument(Index),C,Susp,Arg,Goal)
3829 multi_hash_key_direct(FA,Index,Susp,Key,UsedVars) :-
3830 ( ( integer(Index) ->
3837 sort(Index,Indexes),
3838 pairup(Indexes,Keys,UsedVars),
3842 multi_hash_key_args(Index,Head,KeyArgs) :-
3844 arg(Index,Head,Arg),
3847 sort(Index,Indexes),
3848 term_variables(Head,Vars),
3849 find_with_var_identity(Arg,Vars,(member(I,Indexes), arg(I,Head,Arg)),KeyArgs)
3853 %-------------------------------------------------------------------------------
3854 atomic_constants_code(C,Index,Constants,L,T) :-
3855 constants_store_index_name(C,Index,IndexName),
3857 ( member(Constant,Constants),
3858 constants_store_name(C,Index,Constant,StoreName),
3859 Clause =.. [IndexName,Constant,StoreName]
3862 append(Clauses,T,L).
3864 %-------------------------------------------------------------------------------
3865 ground_constants_code(C,Index,Terms,L,T) :-
3866 constants_store_index_name(C,Index,IndexName),
3868 ( member(Constant,Terms),
3869 constants_store_name(C,Index,Constant,StoreName)
3873 replicate(N,[],More),
3874 trie_index([Terms|More],StoreNames,IndexName,L,T).
3876 constants_store_name(F/A,Index,Term,Name) :-
3877 get_target_module(Mod),
3878 term_to_atom(Term,Constant),
3879 term_to_atom(Index,IndexAtom),
3880 atom_concat_list(['$chr_store_constants_',Mod,'____',F,'___',A,'___',IndexAtom,'___',Constant],Name).
3882 constants_store_index_name(F/A,Index,Name) :-
3883 get_target_module(Mod),
3884 term_to_atom(Index,IndexAtom),
3885 atom_concat_list(['$chr_store_constants_',Mod,'____',F,'___',A,'___',IndexAtom],Name).
3887 trie_index([Patterns|MorePatterns],Results,Prefix,Clauses,Tail) :-
3888 trie_step(Patterns,Prefix,Prefix,MorePatterns,Results,Clauses,Tail).
3890 trie_step([],_,_,[],[],L,L) :- !.
3891 % length MorePatterns == length Patterns == length Results
3892 trie_step(Patterns,Symbol,Prefix,MorePatterns,Results,Clauses,T) :-
3893 MorePatterns = [List|_],
3896 ( member(Pattern,Patterns),
3897 functor(Pattern,F,A)
3902 trie_step_cases(FAs,N1,Patterns,MorePatterns,Results,Symbol,Prefix,Clauses,T).
3904 trie_step_cases([],_,_,_,_,_,_,Clauses,Clauses).
3905 trie_step_cases([FA|FAs],N,Pattern,MorePatterns,Results,Symbol,Prefix,Clauses,Tail) :-
3906 trie_step_case(FA,N,Pattern,MorePatterns,Results,Symbol,Prefix,Clauses,Clauses1),
3907 trie_step_cases(FAs,N,Pattern,MorePatterns,Results,Symbol,Prefix,Clauses1,Tail).
3909 trie_step_case(F/A,N,Patterns,MorePatterns,Results,Symbol,Prefix,[Clause|List],Tail) :-
3910 Clause = (Head :- Body),
3912 functor(Head,Symbol,N1),
3913 arg(N1,Head,Result),
3914 functor(IndexPattern,F,A),
3915 arg(1,Head,IndexPattern),
3916 Head =.. [_,_|RestArgs],
3917 IndexPattern =.. [_|Args],
3918 append(Args,RestArgs,RecArgs),
3919 ( RecArgs == [Result] ->
3922 rec_cases(Patterns,_,Results,F/A,_,_,MoreResults),
3923 MoreResults = [Result]
3925 gensym(Prefix,RSymbol),
3926 Body =.. [RSymbol|RecArgs],
3927 rec_cases(Patterns,MorePatterns,Results,F/A,Cases,MoreCases,MoreResults),
3928 trie_step(Cases,RSymbol,Prefix,MoreCases,MoreResults,List,Tail)
3931 rec_cases([],[],[],_,[],[],[]).
3932 rec_cases([Pattern|Patterns],[MorePattern|MorePatterns],[Result|Results],F/A,Cases,MoreCases,MoreResults) :-
3933 ( functor(Pattern,F,A), Pattern =.. [_|ArgPatterns], append(ArgPatterns,MorePattern,[Case|MoreCase]) ->
3934 Cases = [Case|NCases],
3935 MoreCases = [MoreCase|NMoreCases],
3936 MoreResults = [Result|NMoreResults],
3937 rec_cases(Patterns,MorePatterns,Results,F/A,NCases,NMoreCases,NMoreResults)
3939 rec_cases(Patterns,MorePatterns,Results,F/A,Cases,MoreCases,MoreResults)
3942 %-------------------------------------------------------------------------------
3943 global_list_store_name(F/A,Name) :-
3944 get_target_module(Mod),
3945 atom_concat_list(['$chr_store_global_list_',Mod,'____',F,'___',A],Name).
3946 global_ground_store_name(F/A,Name) :-
3947 get_target_module(Mod),
3948 atom_concat_list(['$chr_store_global_ground_',Mod,'____',F,'___',A],Name).
3949 global_singleton_store_name(F/A,Name) :-
3950 get_target_module(Mod),
3951 atom_concat_list(['$chr_store_global_singleton_',Mod,'____',F,'___',A],Name).
3953 identifier_store_name(TypeName,Name) :-
3954 get_target_module(Mod),
3955 atom_concat_list(['$chr_identifier_lookup_',Mod,'____',TypeName],Name).
3957 :- chr_constraint prolog_global_variable/1.
3958 :- chr_option(mode,prolog_global_variable(+)).
3960 :- chr_constraint prolog_global_variables/1.
3961 :- chr_option(mode,prolog_global_variables(-)).
3963 prolog_global_variable(Name) \ prolog_global_variable(Name) <=> true.
3965 prolog_global_variables(List), prolog_global_variable(Name) <=>
3967 prolog_global_variables(Tail).
3968 prolog_global_variables(List) <=> List = [].
3971 prolog_global_variables_code(Code) :-
3972 prolog_global_variables(Names),
3976 findall('$chr_prolog_global_variable'(Name),member(Name,Names),NameDeclarations),
3977 Code = [(:- dynamic user:exception/3),
3978 (:- multifile user:exception/3),
3979 (user:exception(undefined_global_variable,Name,retry) :-
3981 '$chr_prolog_global_variable'(Name),
3982 '$chr_initialization'
3991 % prolog_global_variables_code([]).
3993 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3994 %sbag_member_call(S,L,sysh:mem(S,L)).
3995 sbag_member_call(S,L,'chr sbag_member'(S,L)).
3996 %sbag_member_call(S,L,member(S,L)).
3997 update_mutable_call(A,B,'chr update_mutable'( A, B)).
3998 %update_mutable_call(A,B,setarg(1, B, A)).
3999 create_mutable_call(Value,Mutable,true) :- Mutable = mutable(Value).
4000 % create_mutable_call(Value,Mutable,'chr create_mutable'(Value,Mutable)).
4002 % get_suspension_field(Constraint,Susp,FieldName,Value,(Get0,Get1)) :-
4003 % get_dynamic_suspension_term_field(FieldName,Constraint,Susp,Field,Get0),
4004 % create_get_mutable(Value,Field,Get1).
4006 % update_suspension_field(Constraint,Susp,FieldName,NewValue,(Get,Set)) :-
4007 % get_dynamic_suspension_term_field(FieldName,Constraint,Susp,Field,Get),
4008 % update_mutable_call(NewValue,Field,Set).
4010 % get_update_suspension_field(Constraint,Susp,FieldName,Value,NewValue,Get0,Get1,Set) :-
4011 % get_dynamic_suspension_term_field(FieldName,Constraint,Susp,Field,Get0),
4012 % create_get_mutable_ref(Value,Field,Get1),
4013 % update_mutable_call(NewValue,Field,Set).
4015 % create_static_suspension_field(Constraint,Susp,FieldName,Value,Create) :-
4016 % get_static_suspension_term_field(FieldName,Constraint,Susp,Field),
4017 % create_mutable_call(Value,Field,Create).
4019 % get_static_suspension_field(Constraint,Susp,FieldName,Value,Get) :-
4020 % get_static_suspension_term_field(FieldName,Constraint,Susp,Field),
4021 % create_get_mutable(Value,Field,Get).
4023 % get_update_static_suspension_field(Constraint,Susp,SuspTerm,FieldName,Value,NewValue,Get,Set) :-
4024 % get_static_suspension_term_field(FieldName,Constraint,SuspTerm,Field),
4025 % create_get_mutable_ref(Value,Field,Get),
4026 % update_mutable_call(NewValue,Field,Set).
4028 get_suspension_field(Constraint,Susp,FieldName,Value,Get) :-
4029 get_dynamic_suspension_term_field(FieldName,Constraint,Susp,Value,Get).
4031 update_suspension_field(Constraint,Susp,FieldName,NewValue,Set) :-
4032 set_dynamic_suspension_term_field(FieldName,Constraint,Susp,NewValue,Set).
4034 get_update_suspension_field(Constraint,Susp,FieldName,Value,NewValue,true,Get,Set) :-
4035 get_dynamic_suspension_term_field(FieldName,Constraint,Susp,Value,Get),
4036 set_dynamic_suspension_term_field(FieldName,Constraint,Susp,NewValue,Set).
4038 create_static_suspension_field(Constraint,Susp,FieldName,Value,true) :-
4039 get_static_suspension_term_field(FieldName,Constraint,Susp,Value).
4041 get_static_suspension_field(Constraint,Susp,FieldName,Value,true) :-
4042 get_static_suspension_term_field(FieldName,Constraint,Susp,Value).
4044 get_update_static_suspension_field(Constraint,Susp,SuspTerm,FieldName,Value,NewValue,true,Set) :-
4045 get_static_suspension_term_field(FieldName,Constraint,SuspTerm,Value),
4046 set_dynamic_suspension_term_field(FieldName,Constraint,Susp,NewValue,Set).
4048 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4050 enumerate_stores_code(Constraints,Clause) :-
4051 Head = '$enumerate_constraints'(Constraint),
4052 enumerate_store_bodies(Constraints,Constraint,Bodies),
4053 list2disj(Bodies,Body),
4054 Clause = (Head :- Body).
4056 enumerate_store_bodies([],_,[]).
4057 enumerate_store_bodies([C|Cs],Constraint,L) :-
4059 get_store_type(C,StoreType),
4060 enumerate_store_body(StoreType,C,Suspension,SuspensionBody),
4061 get_dynamic_suspension_term_field(arguments,C,Suspension,Arguments,DynamicGoal),
4063 Constraint0 =.. [F|Arguments],
4064 Body = (SuspensionBody, DynamicGoal, Constraint = Constraint0),
4069 enumerate_store_bodies(Cs,Constraint,T).
4071 enumerate_store_body(default,C,Susp,Body) :-
4072 global_list_store_name(C,StoreName),
4073 sbag_member_call(Susp,List,Sbag),
4074 make_get_store_goal(StoreName,List,GetStoreGoal),
4077 GetStoreGoal, % nb_getval(StoreName,List),
4080 % get_constraint_index(C,Index),
4081 % get_target_module(Mod),
4082 % get_max_constraint_index(MaxIndex),
4085 % 'chr default_store'(GlobalStore),
4086 % get_attr(GlobalStore,Mod,Attr)
4089 % NIndex is Index + 1,
4090 % sbag_member_call(Susp,List,Sbag),
4093 % arg(NIndex,Attr,List),
4097 % sbag_member_call(Susp,Attr,Sbag),
4100 % Body = (Body1,Body2).
4101 enumerate_store_body(multi_inthash([Index|_]),C,Susp,Body) :-
4102 multi_inthash_enumerate_store_body(Index,C,Susp,Body).
4103 enumerate_store_body(multi_hash([Index|_]),C,Susp,Body) :-
4104 multi_hash_enumerate_store_body(Index,C,Susp,Body).
4105 enumerate_store_body(atomic_constants(Index,Constants,Completeness),C,Susp,Body) :-
4106 Completeness == complete, % fail if incomplete
4107 find_with_var_identity(nb_getval(StoreName,Susps),[Susps],
4108 ( member(Constant,Constants),
4109 constants_store_name(C,Index,Constant,StoreName) )
4111 list2disj(Disjuncts, Disjunction),
4112 Body = ( Disjunction, member(Susp,Susps) ).
4113 enumerate_store_body(ground_constants(_,_),_,_,_) :- fail.
4114 enumerate_store_body(global_ground,C,Susp,Body) :-
4115 global_ground_store_name(C,StoreName),
4116 sbag_member_call(Susp,List,Sbag),
4117 make_get_store_goal(StoreName,List,GetStoreGoal),
4120 GetStoreGoal, % nb_getval(StoreName,List),
4123 enumerate_store_body(var_assoc_store(_,_),C,_,Body) :-
4125 enumerate_store_body(global_singleton,C,Susp,Body) :-
4126 global_singleton_store_name(C,StoreName),
4127 make_get_store_goal(StoreName,Susp,GetStoreGoal),
4130 GetStoreGoal, % nb_getval(StoreName,Susp),
4133 enumerate_store_body(multi_store(STs),C,Susp,Body) :-
4136 enumerate_store_body(ST,C,Susp,Body)
4138 enumerate_store_body(identifier_store(Index),C,Susp,Body) :-
4140 enumerate_store_body(type_indexed_identifier_store(Index,IndexType),C,Susp,Body) :-
4143 multi_inthash_enumerate_store_body(I,C,Susp,B) :-
4144 multi_hash_store_name(C,I,StoreName),
4147 nb_getval(StoreName,HT),
4150 multi_hash_enumerate_store_body(I,C,Susp,B) :-
4151 multi_hash_store_name(C,I,StoreName),
4152 make_get_store_goal(StoreName,HT,GetStoreGoal),
4155 GetStoreGoal, % nb_getval(StoreName,HT),
4159 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4168 :- chr_option(mode,prev_guard_list(+,+,+,+,+,+,+,+)).
4169 :- chr_option(mode,prev_guard_list(+,+,+,+,+,+)).
4170 :- chr_option(type_declaration,prev_guard_list(any,any,any,any,any,list)).
4171 :- chr_option(mode,simplify_guards(+)).
4172 :- chr_option(mode,set_all_passive(+)).
4174 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4175 % GUARD SIMPLIFICATION
4176 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4177 % If the negation of the guards of earlier rules entails (part of)
4178 % the current guard, the current guard can be simplified. We can only
4179 % use earlier rules with a head that matches if the head of the current
4180 % rule does, and which make it impossible for the current rule to match
4181 % if they fire (i.e. they shouldn't be propagation rules and their
4182 % head constraints must be subsets of those of the current rule).
4183 % At this point, we know for sure that the negation of the guard
4184 % of such a rule has to be true (otherwise the earlier rule would have
4185 % fired, because of the refined operational semantics), so we can use
4186 % that information to simplify the guard by replacing all entailed
4187 % conditions by true/0. As a consequence, the never-stored analysis
4188 % (in a further phase) will detect more cases of never-stored constraints.
4190 % e.g. c(X),d(Y) <=> X > 0 | ...
4191 % e(X) <=> X < 0 | ...
4192 % c(X) \ d(Y),e(Z) <=> X =< 0, Z >= 0, ... | ...
4196 guard_simplification :-
4197 ( chr_pp_flag(guard_simplification,on) ->
4198 precompute_head_matchings,
4204 % for every rule, we create a prev_guard_list where the last argument
4205 % eventually is a list of the negations of earlier guards
4206 rule(RuleNb,Rule) \ simplify_guards(RuleNb)
4208 Rule = pragma(rule(Head1,Head2,Guard,_B),ids(IDs1,IDs2),_Pragmas,_Name,RuleNb),
4209 append(Head1,Head2,Heads),
4210 make_head_matchings_explicit_not_negated(Heads,MatchingFreeHeads,Matchings),
4211 multiple_occ_constraints_checked([]),
4212 apply_guard_wrt_term(Heads,Guard,SubstitutedHeads),
4214 append(IDs1,IDs2,IDs),
4215 findall(tuple(C,O,RuleNb)-(-RuleNb),(member(ID,IDs),get_occurrence_from_id(C,O,RuleNb,ID)),HeapData),
4217 insert_list_q(HeapData,EmptyHeap,Heap),
4218 next_prev_rule(Heap,_,Heap1),
4219 next_prev_rule(Heap1,PrevRuleNb,NHeap),
4220 prev_guard_list(RuleNb,PrevRuleNb,NHeap,MatchingFreeHeads,Guard,[],Matchings,[SubstitutedHeads]),
4221 NextRule is RuleNb+1,
4222 simplify_guards(NextRule).
4224 next_prev_rule(Heap,RuleNb,NHeap) :-
4225 ( find_min_q(Heap,_-Priority) ->
4226 Priority = (-RuleNb),
4227 normalize_heap(Heap,Priority,NHeap)
4233 normalize_heap(Heap,Priority,NHeap) :-
4234 ( find_min_q(Heap,_-Priority) ->
4235 delete_min_q(Heap,Heap1,tuple(C,O,_)-_),
4238 get_occurrence(C,NO,RuleNb,_),
4239 insert_q(Heap1,tuple(C,NO,RuleNb)-(-RuleNb),Heap2)
4243 normalize_heap(Heap2,Priority,NHeap)
4253 % The negation of the guard of a non-propagation rule is added
4254 % if its kept head constraints are a subset of the kept constraints of
4255 % the rule we're working on, and its removed head constraints (at least one)
4256 % are a subset of the removed constraints.
4258 rule(PrevRuleNb,PrevRule) \ prev_guard_list(RuleNb,PrevRuleNb,Heap,CurrentHeads,G,GuardList,Matchings,GH)
4260 PrevRule = pragma(rule(H1,H2,PrevGuard,_B),_Ids,_Pragmas,_Name,_PrevRuleNb), % PrevRuleNb == _PrevRuleNb
4262 make_head_matchings_explicit(PrevRuleNb,MatchingFreeHeads,PrevMatchings),
4263 setof(Renaming,chr_translate:head_subset(MatchingFreeHeads,CurrentHeads,Renaming),Renamings)
4265 append(H1,H2,Heads),
4266 compute_derived_info(Renamings,PrevMatchings,MatchingFreeHeads,Heads,PrevGuard,Matchings,CurrentHeads,GH,DerivedInfo,GH_New1),
4267 append(GuardList,DerivedInfo,GL1),
4268 normalize_conj_list(GL1,GL),
4269 append(GH_New1,GH,GH1),
4270 normalize_conj_list(GH1,GH_New),
4271 next_prev_rule(Heap,PrevPrevRuleNb,NHeap),
4272 % PrevPrevRuleNb is PrevRuleNb-1,
4273 prev_guard_list(RuleNb,PrevPrevRuleNb,NHeap,CurrentHeads,G,GL,Matchings,GH_New).
4275 % if this isn't the case, we skip this one and try the next rule
4276 prev_guard_list(RuleNb,N,Heap,H,G,GuardList,M,GH)
4279 next_prev_rule(Heap,N1,NHeap),
4281 prev_guard_list(RuleNb,N1,NHeap,H,G,GuardList,M,GH)
4283 prev_guard_list(RuleNb,H,G,GuardList,M,GH)
4286 prev_guard_list(RuleNb,H,G,GuardList,M,GH)
4290 head_types_modes_condition(GH,H,TypeInfo),
4291 conj2list(TypeInfo,TI),
4292 term_variables(H,HeadVars),
4293 append([chr_pp_headvariables(HeadVars)|TI],GuardList,Info),
4294 normalize_conj_list(Info,InfoL),
4295 prev_guard_list(RuleNb,H,G,InfoL,M,[]).
4297 head_types_modes_condition([],H,true).
4298 head_types_modes_condition([GH|GHs],H,(TI1, TI2)) :-
4299 types_modes_condition(H,GH,TI1),
4300 head_types_modes_condition(GHs,H,TI2).
4304 % when all earlier guards are added or skipped, we simplify the guard.
4305 % if it's different from the original one, we change the rule
4307 prev_guard_list(RuleNb,H,G,GuardList,M,[]), rule(RuleNb,Rule)
4309 Rule = pragma(rule(Head1,Head2,G,B),Ids,Pragmas,Name,RuleNb),
4310 G \== true, % let's not try to simplify this ;)
4311 append(M,GuardList,Info),
4312 simplify_guard(G,B,Info,SimpleGuard,NB),
4315 rule(RuleNb,pragma(rule(Head1,Head2,SimpleGuard,NB),Ids,Pragmas,Name,RuleNb)),
4316 prev_guard_list(RuleNb,H,SimpleGuard,GuardList,M,[]).
4318 %% normalize_conj_list(+List,-NormalList) is det.
4320 % Removes =true= elements and flattens out conjunctions.
4322 normalize_conj_list(List,NormalList) :-
4323 list2conj(List,Conj),
4324 conj2list(Conj,NormalList).
4326 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4327 % AUXILIARY PREDICATES (GUARD SIMPLIFICATION)
4328 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4330 compute_derived_info([],_PrevMatchings,_MatchingFreeHeads,_Heads,_PrevGuard,_Matchings,_H,_GH,[],[]).
4331 compute_derived_info([Renaming1|RestRenamings],PrevMatchings,PrevMatchingFreeHeads,PrevHeads,PrevGuard,Matchings,H,GH,[DerivedInfo1|DerivedInfo2],[GH3|GH_New2]) :-
4332 copy_term(PrevMatchings-PrevGuard,FreshMatchings),
4333 variable_replacement(PrevMatchings-PrevGuard,FreshMatchings,ExtraRenaming),
4334 append(Renaming1,ExtraRenaming,Renaming2),
4335 list2conj(PrevMatchings,Match),
4336 negate_b(Match,HeadsDontMatch),
4337 make_head_matchings_explicit_not_negated2(PrevHeads,PrevMatchingFreeHeads,HeadsMatch),
4338 list2conj(HeadsMatch,HeadsMatchBut),
4339 term_variables(Renaming2,RenVars),
4340 term_variables(PrevMatchings-PrevGuard-HeadsMatch,MGVars),
4341 new_vars(MGVars,RenVars,ExtraRenaming2),
4342 append(Renaming2,ExtraRenaming2,Renaming),
4343 ( PrevGuard == true -> % true can't fail
4344 Info_ = HeadsDontMatch
4346 negate_b(PrevGuard,TheGuardFailed),
4347 Info_ = (HeadsDontMatch ; (HeadsMatchBut, TheGuardFailed))
4349 copy_with_variable_replacement(Info_,DerivedInfo1,Renaming),
4350 copy_with_variable_replacement(PrevGuard,RenamedG2,Renaming),
4351 copy_with_variable_replacement(PrevMatchings,RenamedMatchings_,Renaming),
4352 list2conj(RenamedMatchings_,RenamedMatchings),
4353 apply_guard_wrt_term(H,RenamedG2,GH2),
4354 apply_guard_wrt_term(GH2,RenamedMatchings,GH3),
4355 compute_derived_info(RestRenamings,PrevMatchings,PrevMatchingFreeHeads,PrevHeads,PrevGuard,Matchings,H,GH,DerivedInfo2,GH_New2).
4357 simplify_guard(G,B,Info,SG,NB) :-
4359 % writeq(guard_entailment:simplify_guards(Info,B,LG,SGL,NB)),nl,
4360 guard_entailment:simplify_guards(Info,B,LG,SGL,NB),
4365 new_vars([A|As],RV,ER) :-
4366 ( memberchk_eq(A,RV) ->
4369 ER = [A-NewA,NewA-A|ER2],
4373 %% head_subset(+Subset,+MultiSet,-Renaming) is nondet.
4375 % check if a list of constraints is a subset of another list of constraints
4376 % (multiset-subset), meanwhile computing a variable renaming to convert
4377 % one into the other.
4378 head_subset(H,Head,Renaming) :-
4379 head_subset(H,Head,Renaming,[],_).
4381 head_subset([],Remainder,Renaming,Renaming,Remainder).
4382 head_subset([X|Xs],MultiSet,Renaming,Acc,Remainder) :-
4383 head_member(MultiSet,X,NAcc,Acc,Remainder1),
4384 head_subset(Xs,Remainder1,Renaming,NAcc,Remainder).
4386 % check if A is in the list, remove it from Headleft
4387 head_member([X|Xs],A,Renaming,Acc,Remainder) :-
4388 ( variable_replacement(A,X,Acc,Renaming),
4391 Remainder = [X|RRemainder],
4392 head_member(Xs,A,Renaming,Acc,RRemainder)
4394 %-------------------------------------------------------------------------------%
4395 % memoing code to speed up repeated computation
4397 :- chr_constraint precompute_head_matchings/0.
4399 rule(RuleNb,PragmaRule), precompute_head_matchings ==>
4400 PragmaRule = pragma(rule(H1,H2,_G,_B),_Ids,_Pragmas,_Name,_PrevRuleNb),
4401 append(H1,H2,Heads),
4402 make_head_matchings_explicit_(Heads,MatchingFreeHeads,Matchings),
4403 copy_term_nat(MatchingFreeHeads-Matchings,A-B),
4404 make_head_matchings_explicit_memo_table(RuleNb,A,B).
4406 precompute_head_matchings <=> true.
4408 :- chr_constraint make_head_matchings_explicit_memo_table/3.
4409 :- chr_constraint make_head_matchings_explicit_memo_lookup/3.
4411 :- chr_option(mode,make_head_matchings_explicit_memo_table(+,?,?)).
4412 :- chr_option(mode,make_head_matchings_explicit_memo_lookup(+,?,?)).
4414 make_head_matchings_explicit_memo_table(RuleNb,NHeads,Matchings) \
4415 make_head_matchings_explicit_memo_lookup(RuleNb,Q1,Q2)
4419 make_head_matchings_explicit_memo_lookup(_,_,_) <=> fail.
4421 make_head_matchings_explicit(RuleNb,MatchingFreeHeads,Matchings) :-
4422 make_head_matchings_explicit_memo_lookup(RuleNb,A,B),
4423 copy_term_nat(A-B,MatchingFreeHeads-Matchings).
4424 %-------------------------------------------------------------------------------%
4426 make_head_matchings_explicit_(Heads,MatchingFreeHeads,Matchings) :-
4427 extract_arguments(Heads,Arguments),
4428 make_matchings_explicit(Arguments,FreeVariables,[],[],_,Matchings),
4429 substitute_arguments(Heads,FreeVariables,MatchingFreeHeads).
4431 make_head_matchings_explicit_not_negated(Heads,MatchingFreeHeads,Matchings) :-
4432 extract_arguments(Heads,Arguments),
4433 make_matchings_explicit_not_negated(Arguments,FreshVariables,Matchings),
4434 substitute_arguments(Heads,FreshVariables,MatchingFreeHeads).
4436 make_head_matchings_explicit_not_negated2(Heads,MatchingFreeHeads,Matchings) :-
4437 extract_arguments(Heads,Arguments1),
4438 extract_arguments(MatchingFreeHeads,Arguments2),
4439 make_matchings_explicit_not_negated(Arguments1,Arguments2,Matchings).
4441 %% extract_arguments(+ListOfConstraints,-ListOfVariables) is det.
4443 % Returns list of arguments of given list of constraints.
4444 extract_arguments([],[]).
4445 extract_arguments([Constraint|Constraints],AllArguments) :-
4446 Constraint =.. [_|Arguments],
4447 append(Arguments,RestArguments,AllArguments),
4448 extract_arguments(Constraints,RestArguments).
4450 %% substitute_arguments(+InListOfConstraints,ListOfVariables,-OutListOfConstraints) is det.
4452 % Substitutes arguments of constraints with those in the given list.
4454 substitute_arguments([],[],[]).
4455 substitute_arguments([Constraint|Constraints],Variables,[NConstraint|NConstraints]) :-
4456 functor(Constraint,F,N),
4457 split_at(N,Variables,Arguments,RestVariables),
4458 NConstraint =.. [F|Arguments],
4459 substitute_arguments(Constraints,RestVariables,NConstraints).
4461 make_matchings_explicit([],[],_,MC,MC,[]).
4462 make_matchings_explicit([Arg|Args],[NewVar|NewVars],VarAcc,MatchingCondition,MatchingConditionO,Matchings) :-
4464 ( memberchk_eq(Arg,VarAcc) ->
4465 list2disj(MatchingCondition,MatchingCondition_disj),
4466 Matchings = [(MatchingCondition_disj ; NewVar == Arg)|RestMatchings], % or only = ??
4469 Matchings = RestMatchings,
4471 NVarAcc = [Arg|VarAcc]
4473 MatchingCondition2 = MatchingCondition
4476 Arg =.. [F|RecArgs],
4477 make_matchings_explicit(RecArgs,RecVars,VarAcc,MatchingCondition,MatchingCondition_,RecMatchings),
4478 FlatArg =.. [F|RecVars],
4479 ( RecMatchings == [] ->
4480 Matchings = [functor(NewVar,F,A)|RestMatchings]
4482 list2conj(RecMatchings,ArgM_conj),
4483 list2disj(MatchingCondition,MatchingCondition_disj),
4484 ArgM_ = (NewVar \= FlatArg ; MatchingCondition_disj ; ArgM_conj),
4485 Matchings = [ functor(NewVar,F,A) , ArgM_|RestMatchings]
4487 MatchingCondition2 = [ NewVar \= FlatArg |MatchingCondition_],
4488 term_variables(Args,ArgVars),
4489 append(ArgVars,VarAcc,NVarAcc)
4491 make_matchings_explicit(Args,NewVars,NVarAcc,MatchingCondition2,MatchingConditionO,RestMatchings).
4494 %% make_matchings_explicit_not_negated(+ListOfTerms,-ListOfVariables,-ListOfMatchings) is det.
4496 % Returns list of new variables and list of pairwise unifications between given list and variables.
4498 make_matchings_explicit_not_negated([],[],[]).
4499 make_matchings_explicit_not_negated([X|Xs],[Var|Vars],Matchings) :-
4500 Matchings = [Var = X|RMatchings],
4501 make_matchings_explicit_not_negated(Xs,Vars,RMatchings).
4503 %% apply_guard_wrt_term(+ListOfConstraints,+Goal,-NewListOfConstraints) is det.
4505 % (Partially) applies substitutions of =Goal= to given list.
4507 apply_guard_wrt_term([],_Guard,[]).
4508 apply_guard_wrt_term([Term|RH],Guard,[NTerm|RGH]) :-
4510 apply_guard_wrt_variable(Guard,Term,NTerm)
4513 apply_guard_wrt_term(HArgs,Guard,NewHArgs),
4514 NTerm =.. [F|NewHArgs]
4516 apply_guard_wrt_term(RH,Guard,RGH).
4518 %% apply_guard_wrt_variable(+Goal,+Variable,-NVariable) is det.
4520 % (Partially) applies goal =Guard= wrt variable.
4522 apply_guard_wrt_variable((Guard1,Guard2),Variable,NVariable) :- !,
4523 apply_guard_wrt_variable(Guard1,Variable,NVariable1),
4524 apply_guard_wrt_variable(Guard2,NVariable1,NVariable).
4525 apply_guard_wrt_variable(Guard,Variable,NVariable) :-
4526 ( Guard = (X = Y), Variable == X ->
4528 ; Guard = functor(AVariable,Functor,Arity), Variable == AVariable, ground(Functor), ground(Arity) ->
4529 functor(NVariable,Functor,Arity)
4531 NVariable = Variable
4534 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4535 % ALWAYS FAILING HEADS
4536 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4538 rule(RuleNb,Rule) \ prev_guard_list(RuleNb,H,G,GuardList,M,[])
4540 chr_pp_flag(check_impossible_rules,on),
4541 Rule = pragma(rule(Head1,Head2,G,B),Ids,Pragmas,Name,RuleNb),
4542 append(M,GuardList,Info),
4543 guard_entailment:entails_guard(Info,fail)
4545 chr_warning(weird_program,'Heads will never match in ~@.\n\tThis rule will never fire!\n',[format_rule(Rule)]),
4546 set_all_passive(RuleNb).
4548 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4549 % HEAD SIMPLIFICATION
4550 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4552 % now we check the head matchings (guard may have been simplified meanwhile)
4553 prev_guard_list(RuleNb,H,G,GuardList,M,[]) \ rule(RuleNb,Rule)
4555 Rule = pragma(rule(Head1,Head2,G,B),Ids,Pragmas,Name,RuleNb),
4556 simplify_heads(M,GuardList,G,B,NewM,NewB),
4558 extract_arguments(Head1,VH1),
4559 extract_arguments(Head2,VH2),
4560 extract_arguments(H,VH),
4561 replace_some_heads(VH1,VH2,VH,NewM,H1,H2,G,B,NewB_),
4562 substitute_arguments(Head1,H1,NewH1),
4563 substitute_arguments(Head2,H2,NewH2),
4564 append(NewB,NewB_,NewBody),
4565 list2conj(NewBody,BodyMatchings),
4566 NewRule = pragma(rule(NewH1,NewH2,G,(BodyMatchings,B)),Ids,Pragmas,Name,RuleNb),
4567 (Head1 \== NewH1 ; Head2 \== NewH2 )
4569 rule(RuleNb,NewRule).
4571 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4572 % AUXILIARY PREDICATES (HEAD SIMPLIFICATION)
4573 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4575 replace_some_heads(H1,H2,NH,[],H1,H2,G,Body,[]) :- !.
4576 replace_some_heads([],[H2|RH2],[NH|RNH],[M|RM],[],[H2_|RH2_],G,Body,NewB) :- !,
4579 replace_some_heads([],RH2,RNH,RM,[],RH2_,G,Body,NewB)
4581 (M = functor(X,F,A), NH == X ->
4587 H2 =.. [F|OrigArgs],
4588 use_same_args(OrigArgs,A_args,A_args_,G,Body,NewB1),
4591 replace_some_heads([],RH2,RNH,RM,[],RH2_,G,Body,NewB2),
4592 append(NewB1,NewB2,NewB)
4595 replace_some_heads([],RH2,RNH,[M|RM],[],RH2_,G,Body,NewB)
4599 replace_some_heads([H1|RH1],H2,[NH|RNH],[M|RM],[H1_|RH1_],H2_,G,Body,NewB) :- !,
4602 replace_some_heads(RH1,H2,RNH,RM,RH1_,H2_,G,Body,NewB)
4604 (M = functor(X,F,A), NH == X ->
4610 H1 =.. [F|OrigArgs],
4611 use_same_args(OrigArgs,A_args,A_args_,G,Body,NewB1),
4614 replace_some_heads(RH1,H2,RNH,RM,RH1_,H2_,G,Body,NewB2),
4615 append(NewB1,NewB2,NewB)
4618 replace_some_heads(RH1,H2,RNH,[M|RM],RH1_,H2_,G,Body,NewB)
4622 use_same_args([],[],[],_,_,[]).
4623 use_same_args([OA|ROA],[NA|RNA],[Out|ROut],G,Body,NewB) :-
4626 use_same_args(ROA,RNA,ROut,G,Body,NewB).
4627 use_same_args([OA|ROA],[NA|RNA],[Out|ROut],G,Body,NewB) :-
4629 ( common_variables(OA,Body) ->
4630 NewB = [NA = OA|NextB]
4635 use_same_args(ROA,RNA,ROut,G,Body,NextB).
4638 simplify_heads([],_GuardList,_G,_Body,[],[]).
4639 simplify_heads([M|RM],GuardList,G,Body,NewM,NewB) :-
4641 ( (nonvar(B) ; common_variables(B,RM-GuardList)),
4642 guard_entailment:entails_guard(GuardList,(A=B)) ->
4643 ( common_variables(B,G-RM-GuardList) ->
4647 ( common_variables(B,Body) ->
4648 NewB = [A = B|NextB]
4655 ( nonvar(B), functor(B,BFu,BAr),
4656 guard_entailment:entails_guard([functor(A,BFu,BAr)|GuardList],(A=B)) ->
4658 ( common_variables(B,G-RM-GuardList) ->
4661 NewM = [functor(A,BFu,BAr)|NextM]
4668 simplify_heads(RM,[M|GuardList],G,Body,NextM,NextB).
4670 common_variables(B,G) :-
4671 term_variables(B,BVars),
4672 term_variables(G,GVars),
4673 intersect_eq(BVars,GVars,L),
4677 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4678 % ALWAYS FAILING GUARDS
4679 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4681 set_all_passive(RuleNb), occurrence(_,_,RuleNb,ID,_) ==> passive(RuleNb,ID).
4682 set_all_passive(_) <=> true.
4684 prev_guard_list(RuleNb,H,G,GuardList,M,[]),rule(RuleNb,Rule)
4686 chr_pp_flag(check_impossible_rules,on),
4687 Rule = pragma(rule(_,_,G,_),_Ids,_Pragmas,_Name,RuleNb),
4689 % writeq(guard_entailment:entails_guard(GL,fail)),nl,
4690 guard_entailment:entails_guard(GL,fail)
4692 chr_warning(weird_program,'Guard will always fail in ~@.\n\tThis rule will never fire!\n',[format_rule(Rule)]),
4693 set_all_passive(RuleNb).
4697 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4698 % OCCURRENCE SUBSUMPTION
4699 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4702 first_occ_in_rule/4,
4705 :- chr_option(mode,first_occ_in_rule(+,+,+,+)).
4706 :- chr_option(mode,next_occ_in_rule(+,+,+,+,+,+)).
4708 :- chr_constraint multiple_occ_constraints_checked/1.
4709 :- chr_option(mode,multiple_occ_constraints_checked(+)).
4711 prev_guard_list(RuleNb,H,G,GuardList,M,[]),
4712 occurrence(C,O,RuleNb,ID,_),
4713 occurrence(C,O2,RuleNb,ID2,_),
4716 multiple_occ_constraints_checked(Done)
4719 chr_pp_flag(occurrence_subsumption,on),
4720 Rule = pragma(rule(H1,H2,_G,_B),_Ids,_Pragmas,_Name,_RuleNb), % RuleNb == _RuleNb
4722 \+ memberchk_eq(C,Done)
4724 first_occ_in_rule(RuleNb,C,O,ID),
4725 multiple_occ_constraints_checked([C|Done]).
4727 % Find first occurrence of constraint =C= in rule =RuleNb=
4728 occurrence(C,O,RuleNb,ID,_) \ first_occ_in_rule(RuleNb,C,O2,_)
4732 first_occ_in_rule(RuleNb,C,O,ID).
4734 first_occ_in_rule(RuleNb,C,O,ID_o1)
4737 functor(FreshHead,F,A),
4738 next_occ_in_rule(RuleNb,C,O,ID_o1,[],FreshHead).
4740 % Skip passive occurrences.
4741 passive(RuleNb,ID_o2), occurrence(C,O2,RuleNb,ID_o2,_) \ next_occ_in_rule(RuleNb,C,O,ID_o1,Cond,FH)
4745 next_occ_in_rule(RuleNb,C,O2,ID_o1,NewCond,FH).
4747 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)
4750 Rule = pragma(rule(H1,H2,G,B),ids(ID1,ID2),_Pragmas,_Name,RuleNb)
4752 append(H1,H2,Heads),
4753 add_failing_occ(Rule,Heads,H,ID_o1,ExtraCond,FH,M,C,Repl),
4754 ( ExtraCond == [chr_pp_void_info] ->
4755 next_occ_in_rule(RuleNb,C,O2,ID_o2,Cond,FH)
4757 append(ExtraCond,Cond,NewCond),
4758 add_failing_occ(Rule,Heads,H,ID_o2,CheckCond,FH,M,C,Repl2),
4759 copy_term(GuardList,FGuardList),
4760 variable_replacement(GuardList,FGuardList,GLRepl),
4761 copy_with_variable_replacement(GuardList,GuardList2,Repl),
4762 copy_with_variable_replacement(GuardList,GuardList3_,Repl2),
4763 copy_with_variable_replacement(GuardList3_,GuardList3,GLRepl),
4764 append(NewCond,GuardList2,BigCond),
4765 append(BigCond,GuardList3,BigCond2),
4766 copy_with_variable_replacement(M,M2,Repl),
4767 copy_with_variable_replacement(M,M3,Repl2),
4768 append(M3,BigCond2,BigCond3),
4769 append([chr_pp_active_constraint(FH)|M2],BigCond3,Info),
4770 list2conj(CheckCond,OccSubsum),
4771 copy_term((NewCond,BigCond2,Info,OccSubsum,FH),(NewCond2,BigCond2_,Info2,OccSubsum2,FH2)),
4772 ( OccSubsum \= chr_pp_void_info ->
4773 ( guard_entailment:entails_guard(Info2,OccSubsum2) ->
4774 passive(RuleNb,ID_o2)
4781 next_occ_in_rule(RuleNb,C,O2,ID_o2,NewCond,FH)
4785 next_occ_in_rule(RuleNb,C,O,ID,Cond,Args)
4789 prev_guard_list(RuleNb,H,G,GuardList,M,[]), multiple_occ_constraints_checked(Done)
4793 add_failing_occ(Rule,Heads,NH,ID_o1,FailCond,FH,M,C,Repl) :-
4794 Rule = pragma(rule(H1,H2,G,B),ids(ID1,ID2),_Pragmas,_Name,RuleNb),
4795 append(ID2,ID1,IDs),
4796 missing_partner_cond(Heads,NH,IDs,ID_o1,MPCond,H,C),
4797 copy_term((H,Heads,NH),(FH2,FHeads,NH2)),
4798 variable_replacement((H,Heads,NH),(FH2,FHeads,NH2),Repl),
4799 copy_with_variable_replacement(G,FG,Repl),
4800 extract_explicit_matchings(FG,FG2),
4801 negate_b(FG2,NotFG),
4802 copy_with_variable_replacement(MPCond,FMPCond,Repl),
4803 ( safely_unifiable(FH,FH2), FH=FH2 ->
4804 FailCond = [(NotFG;FMPCond)]
4806 % in this case, not much can be done
4807 % e.g. c(f(...)), c(g(...)) <=> ...
4808 FailCond = [chr_pp_void_info]
4811 missing_partner_cond([],[],[],ID_o1,fail,H2,C).
4812 missing_partner_cond([H|Hs],[H2|H2s],[ID_o1|IDs],ID_o1,Cond,H,C) :- !,
4813 missing_partner_cond(Hs,H2s,IDs,ID_o1,Cond,H,C).
4814 missing_partner_cond([H|Hs],[NH|NHs],[ID|IDs],ID_o1,Cond,H2,F/A) :-
4815 Cond = (chr_pp_not_in_store(H);Cond1),
4816 missing_partner_cond(Hs,NHs,IDs,ID_o1,Cond1,H2,F/A).
4818 extract_explicit_matchings((A,B),D) :- !,
4819 ( extract_explicit_matchings(A) ->
4820 extract_explicit_matchings(B,D)
4823 extract_explicit_matchings(B,E)
4825 extract_explicit_matchings(A,D) :- !,
4826 ( extract_explicit_matchings(A) ->
4832 extract_explicit_matchings(A=B) :-
4833 var(A), var(B), !, A=B.
4834 extract_explicit_matchings(A==B) :-
4835 var(A), var(B), !, A=B.
4837 safely_unifiable(H,I) :- var(H), !.
4838 safely_unifiable([],[]) :- !.
4839 safely_unifiable([H|Hs],[I|Is]) :- !,
4840 safely_unifiable(H,I),
4841 safely_unifiable(Hs,Is).
4842 safely_unifiable(H,I) :-
4847 safely_unifiable(HA,IA).
4851 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4853 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4859 get_type_definition/2,
4860 get_constraint_type/2.
4863 :- chr_option(mode,type_definition(?,?)).
4864 :- chr_option(mode,get_type_definition(?,?)).
4865 :- chr_option(mode,type_alias(?,?)).
4866 :- chr_option(mode,constraint_type(+,+)).
4867 :- chr_option(mode,get_constraint_type(+,-)).
4869 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4870 % Consistency checks of type aliases
4872 type_alias(T,T2) <=>
4873 nonvar(T),nonvar(T2),functor(T,F,A),functor(T2,F,A),
4874 copy_term((T,T2),(X,Y)),oneway_unification(Y,X) |
4875 chr_error(type_error,'Cyclic alias definition: "~w".\n',[(T == T2)]).
4877 type_alias(T1,A1), type_alias(T2,A2) <=>
4878 nonvar(T1),nonvar(T2),functor(T1,F,A),functor(T2,F,A),
4880 copy_term_nat(T1,T1_),
4881 copy_term_nat(T2,T2_),
4883 chr_error(type_error,
4884 '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_]).
4886 type_alias(T,B) \ type_alias(X,T2) <=>
4887 nonvar(T),nonvar(T2),functor(T,F,A),functor(T2,F,A),
4888 copy_term_nat((X,T2,T,B),(X2,T3,T1,D1)),oneway_unification(T3,T1) |
4889 % chr_info(type_information,'Inferring `~w\' from `~w\' and `~w\'.\n',[X2==D1,X==T2,T==B]),
4892 oneway_unification(X,Y) :-
4893 term_variables(X,XVars),
4894 chr_runtime:lockv(XVars),
4896 chr_runtime:unlockv(XVars).
4898 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4899 % Consistency checks of type definitions
4901 type_definition(T1,_), type_definition(T2,_)
4903 functor(T1,F,A), functor(T2,F,A)
4905 chr_error(type_error,'Multiple definitions for type: ~w/~w.\n',[F,A]).
4907 type_definition(T1,_), type_alias(T2,_)
4909 functor(T1,F,A), functor(T2,F,A)
4911 chr_error(type_error,'Multiple definitions for type, once in a type definition and once as a type alias: ~w/~w.\n',[F,A]).
4913 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4914 %% get_type_definition(+Type,-Definition) is semidet.
4915 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4917 get_type_definition(T,Def)
4921 chr_error(type_error,'Non-ground type in constraint definition: "~w".\n',[T]).
4923 type_alias(T,D) \ get_type_definition(T2,Def)
4925 nonvar(T),nonvar(T2),functor(T,F,A),functor(T2,F,A),
4926 copy_term_nat((T,D),(T1,D1)),T1=T2
4928 ( get_type_definition(D1,Def) ->
4931 chr_error(type_error,'Could not find type definition for "~w" (accessed via alias "~w").\n',[D1,T1]), fail
4934 type_definition(T,D) \ get_type_definition(T2,Def)
4936 nonvar(T),nonvar(T2),functor(T,F,A),functor(T2,F,A),
4937 copy_term_nat((T,D),(T1,D1)),T1=T2
4941 get_type_definition(Type,Def)
4943 atomic_builtin_type(Type,_,_)
4947 get_type_definition(Type,Def)
4949 compound_builtin_type(Type,_,_)
4953 get_type_definition(X,Y) <=> fail.
4955 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4956 %% get_type_definition_det(+Type,-Definition) is det.
4957 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4958 get_type_definition_det(Type,Definition) :-
4959 ( get_type_definition(Type,Definition) ->
4962 chr_error(type,'Could not find type definition for type `~w\'.\n',[Type])
4965 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
4966 %% get_constraint_type(+ConstraintSymbol,-Types) is semidet.
4968 % Return argument types of =ConstraintSymbol=, but fails if none where
4970 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
4971 constraint_type(C,T) \ get_constraint_type(C,Type) <=> Type = T.
4972 get_constraint_type(_,_) <=> fail.
4974 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
4975 %% get_constraint_type_det(+ConstraintSymbol,-Types) is det.
4977 % Like =get_constraint_type/2=, but returns list of =any= types when
4978 % no types are declared.
4979 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
4980 get_constraint_type_det(ConstraintSymbol,Types) :-
4981 ( get_constraint_type(ConstraintSymbol,Types) ->
4984 ConstraintSymbol = _ / N,
4985 replicate(N,any,Types)
4987 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
4988 %% unalias_type(+Alias,-Type) is det.
4990 % Follows alias chain until base type is reached.
4991 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
4992 :- chr_constraint unalias_type/2.
4995 unalias_type(Alias,BaseType)
5002 type_alias(AliasProtoType,ProtoType) \ unalias_type(Alias,BaseType)
5004 nonvar(AliasProtoType),
5006 functor(AliasProtoType,F,A),
5008 copy_term_nat((AliasProtoType,ProtoType),(AliasInstance,Type)),
5009 Alias = AliasInstance
5011 unalias_type(Type,BaseType).
5013 unalias_type_definition @
5014 type_definition(ProtoType,Definition) \ unalias_type(Alias,BaseType)
5018 functor(ProtoType,F,A),
5023 unalias_atomic_builtin @
5024 unalias_type(Alias,BaseType)
5026 atomic_builtin_type(Alias,_,_)
5030 unalias_compound_builtin @
5031 unalias_type(Alias,BaseType)
5033 compound_builtin_type(Alias,_,_)
5037 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5038 %% types_modes_condition(+Heads,+UnrollHeads,-Condition) is det.
5039 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5040 :- chr_constraint types_modes_condition/3.
5041 :- chr_option(mode,types_modes_condition(+,+,?)).
5042 :- chr_option(type_declaration,types_modes_condition(list,list,goal)).
5044 types_modes_condition([],[],T) <=> T=true.
5046 constraint_mode(F/A,Modes) \ types_modes_condition([Head|Heads],[UnrollHead|UnrollHeads],Condition)
5051 Condition = (ModesCondition, TypesCondition, RestCondition),
5052 modes_condition(Modes,Args,ModesCondition),
5053 get_constraint_type_det(F/A,Types),
5054 UnrollHead =.. [_|RealArgs],
5055 types_condition(Types,Args,RealArgs,Modes,TypesCondition),
5056 types_modes_condition(Heads,UnrollHeads,RestCondition).
5058 types_modes_condition([Head|_],_,_)
5061 chr_error(internal,'Mode information missing for ~w.\n',[F/A]).
5064 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5065 %% modes_condition(+Modes,+Args,-Condition) is det.
5067 % Return =Condition= on =Args= that checks =Modes=.
5068 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5069 modes_condition([],[],true).
5070 modes_condition([Mode|Modes],[Arg|Args],Condition) :-
5072 Condition = ( ground(Arg) , RCondition )
5074 Condition = ( var(Arg) , RCondition )
5076 Condition = RCondition
5078 modes_condition(Modes,Args,RCondition).
5080 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5081 %% types_condition(+Types,+Args,+UnrollArgs,+Modes,-Condition) is det.
5083 % Return =Condition= on =Args= that checks =Types= given =Modes=.
5084 % =UnrollArgs= controls the depth of type definition unrolling.
5085 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5086 types_condition([],[],[],[],true).
5087 types_condition([Type|Types],[Arg|Args],[UnrollArg|UnrollArgs],[Mode|Modes],(DisjTypeConditionList,RCondition)) :-
5089 TypeConditionList = [true] % TypeConditionList = [var(Arg)] already encoded in modes_condition
5091 get_type_definition_det(Type,Def),
5092 type_condition(Def,Arg,UnrollArg,Mode,TypeConditionList1),
5094 TypeConditionList = TypeConditionList1
5096 TypeConditionList = [(\+ ground(Arg))|TypeConditionList1]
5099 list2disj(TypeConditionList,DisjTypeConditionList),
5100 types_condition(Types,Args,UnrollArgs,Modes,RCondition).
5102 type_condition([],_,_,_,[]).
5103 type_condition([DefCase|DefCases],Arg,UnrollArg,Mode,[Condition|Conditions]) :-
5105 chr_error(type,'Unexpected variable type in type definition!\n',[]) % Condition = true
5106 ; atomic_builtin_type(DefCase,Arg,Condition) ->
5108 ; compound_builtin_type(DefCase,Arg,Condition) ->
5111 type_def_case_condition(DefCase,Arg,UnrollArg,Mode,Condition)
5113 type_condition(DefCases,Arg,UnrollArg,Mode,Conditions).
5115 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5116 :- chr_type atomic_builtin_type ---> any
5123 ; chr_identifier(any).
5124 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5126 atomic_builtin_type(any,_Arg,true).
5127 atomic_builtin_type(dense_int,Arg,(integer(Arg),Arg>=0)).
5128 atomic_builtin_type(int,Arg,integer(Arg)).
5129 atomic_builtin_type(number,Arg,number(Arg)).
5130 atomic_builtin_type(float,Arg,float(Arg)).
5131 atomic_builtin_type(natural,Arg,(integer(Arg),Arg>=0)).
5132 atomic_builtin_type(chr_identifier,_Arg,true).
5134 compound_builtin_type(chr_identifier(_),_Arg,true).
5136 type_def_case_condition(DefCase,Arg,UnrollArg,Mode,Condition) :-
5137 ( nonvar(DefCase) ->
5138 functor(DefCase,F,A),
5140 Condition = (Arg = DefCase)
5142 Condition = functor(Arg,F,A)
5143 ; functor(UnrollArg,F,A) ->
5144 Condition = (functor(Arg,F,A),Arg=Template,ArgsCondition),
5145 DefCase =.. [_|ArgTypes],
5146 UnrollArg =.. [_|UnrollArgs],
5147 functor(Template,F,A),
5148 Template =.. [_|TemplateArgs],
5149 replicate(A,Mode,ArgModes),
5150 types_condition(ArgTypes,TemplateArgs,UnrollArgs,ArgModes,ArgsCondition)
5152 Condition = functor(Arg,F,A)
5155 chr_error(internal,'Illegal type definition (must be nonvar).\n',[])
5159 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5160 % Static type checking
5161 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5162 % Checks head constraints and CHR constraint calls in bodies.
5165 % - type clashes involving built-in types
5166 % - Prolog built-ins in guard and body
5167 % - indicate position in terms in error messages
5168 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5170 static_type_check/0.
5172 :- chr_type type_error_src ---> head(any) ; body(any).
5174 rule(_,Rule), static_type_check
5176 copy_term_nat(Rule,RuleCopy),
5177 RuleCopy = pragma(rule(Head1,Head2,G,Body),ids(IDs1,IDs2),Pragmas,Name,RuleNb),
5180 ( static_type_check_heads(Head1),
5181 static_type_check_heads(Head2),
5182 conj2list(Body,GoalList),
5183 static_type_check_body(GoalList)
5186 ( Error = invalid_functor(Src,Term,Type) ->
5187 chr_error(type_error,'Invalid functor in ~@ of ~@:\n\t\tfound `~w\',\n\t\texpected type `~w\'!\n',
5188 [chr_translate:format_src(Src),format_rule(Rule),Term,Type])
5189 ; Error = type_clash(Var,Src1,Src2,Type1,Type2) ->
5190 chr_error(type_error,'Type clash for variable ~w in ~@:\n\t\texpected type ~w in ~@\n\t\texpected type ~w in ~@\n',
5191 [Var,format_rule(Rule),Type1,chr_translate:format_src(Src1),Type2,chr_translate:format_src(Src2)])
5194 fail % cleanup constraints
5200 static_type_check <=> true.
5202 static_type_check_heads([]).
5203 static_type_check_heads([Head|Heads]) :-
5204 static_type_check_head(Head),
5205 static_type_check_heads(Heads).
5207 static_type_check_head(Head) :-
5209 get_constraint_type_det(F/A,Types),
5211 maplist(static_type_check_term(head(Head)),Args,Types).
5213 static_type_check_body([]).
5214 static_type_check_body([Goal|Goals]) :-
5216 get_constraint_type_det(F/A,Types),
5218 maplist(static_type_check_term(body(Goal)),Args,Types),
5219 static_type_check_body(Goals).
5221 :- chr_constraint static_type_check_term/3.
5222 :- chr_option(mode,static_type_check_term(?,?,?)).
5223 :- chr_option(type_declaration,static_type_check_term(type_error_src,any,any)).
5225 static_type_check_term(Src,Term,Type)
5229 static_type_check_var(Src,Term,Type).
5230 static_type_check_term(Src,Term,Type)
5232 atomic_builtin_type(Type,Term,Goal)
5237 throw(type_error(invalid_functor(Src,Term,Type)))
5239 static_type_check_term(Src,Term,Type)
5241 compound_builtin_type(Type,Term,Goal)
5246 throw(type_error(invalid_functor(Src,Term,Type)))
5248 type_alias(AType,ADef) \ static_type_check_term(Src,Term,Type)
5253 copy_term_nat(AType-ADef,Type-Def),
5254 static_type_check_term(Src,Term,Def).
5256 type_definition(AType,ADef) \ static_type_check_term(Src,Term,Type)
5261 copy_term_nat(AType-ADef,Type-Variants),
5262 functor(Term,TF,TA),
5263 ( member(Variant,Variants), functor(Variant,TF,TA) ->
5265 Variant =.. [_|Types],
5266 maplist(static_type_check_term(Src),Args,Types)
5268 throw(type_error(invalid_functor(Src,Term,Type)))
5271 static_type_check_term(Src,Term,Type)
5273 chr_error(internal,'Undefined type ~w while type checking term ~w in ~@.\n',[Type,Term,chr_translate:format_src(Src)]).
5275 :- chr_constraint static_type_check_var/3.
5276 :- chr_option(mode,static_type_check_var(?,-,?)).
5277 :- chr_option(type_declaration,static_type_check_term(type_error_src,any,any)).
5279 type_alias(AType,ADef) \ static_type_check_var(Src,Var,Type)
5284 copy_term_nat(AType-ADef,Type-Def),
5285 static_type_check_var(Src,Var,Def).
5287 static_type_check_var(Src,Var,Type)
5289 atomic_builtin_type(Type,_,_)
5291 static_atomic_builtin_type_check_var(Src,Var,Type).
5293 static_type_check_var(Src,Var,Type)
5295 compound_builtin_type(Type,_,_)
5300 static_type_check_var(Src1,Var,Type1), static_type_check_var(Src2,Var,Type2)
5304 throw(type_error(type_clash(Var,Src1,Src2,Type1,Type2))).
5306 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5307 %% static_atomic_builtin_type_check_var(+type_error_src,-Var,+atomic_builtin_type)
5308 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5309 :- chr_constraint static_atomic_builtin_type_check_var/3.
5310 :- chr_option(mode,static_type_check_var(?,-,+)).
5311 :- chr_option(type_declaration,static_type_check_term(type_error_src,any,atomic_builtin_type)).
5313 static_atomic_builtin_type_check_var(_,_,any) <=> true.
5314 static_atomic_builtin_type_check_var(_,Var,BuiltinType) \ static_atomic_builtin_type_check_var(_,Var,BuiltinType)
5317 static_atomic_builtin_type_check_var(_,Var,float) \ static_atomic_builtin_type_check_var(_,Var,number)
5320 static_atomic_builtin_type_check_var(_,Var,int) \ static_atomic_builtin_type_check_var(_,Var,number)
5323 static_atomic_builtin_type_check_var(_,Var,natural) \ static_atomic_builtin_type_check_var(_,Var,number)
5326 static_atomic_builtin_type_check_var(_,Var,dense_int) \ static_atomic_builtin_type_check_var(_,Var,number)
5329 static_atomic_builtin_type_check_var(_,Var,natural) \ static_atomic_builtin_type_check_var(_,Var,int)
5332 static_atomic_builtin_type_check_var(_,Var,dense_int) \ static_atomic_builtin_type_check_var(_,Var,int)
5335 static_atomic_builtin_type_check_var(_,Var,dense_int) \ static_atomic_builtin_type_check_var(_,Var,natural)
5338 static_atomic_builtin_type_check_var(Src1,Var,Type1), static_atomic_builtin_type_check_var(Src2,Var,Type2)
5340 throw(type_error(type_clash(Var,Src1,Src2,Type1,Type2))).
5342 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5343 %% format_src(+type_error_src) is det.
5344 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5345 format_src(head(Head)) :- format('head ~w',[Head]).
5346 format_src(body(Goal)) :- format('body goal ~w',[Goal]).
5348 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5349 % Dynamic type checking
5350 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5353 dynamic_type_check/0,
5354 dynamic_type_check_clauses/1,
5355 get_dynamic_type_check_clauses/1.
5357 generate_dynamic_type_check_clauses(Clauses) :-
5358 ( chr_pp_flag(debugable,on) ->
5360 get_dynamic_type_check_clauses(Clauses0),
5362 [('$dynamic_type_check'(Type,Term) :-
5363 throw(error(type_error(Type,Term),context(_,'CHR Runtime Type Error')))
5370 type_definition(T,D), dynamic_type_check
5372 copy_term_nat(T-D,Type-Definition),
5373 maplist(dynamic_type_check_clause(Type),Definition,DynamicChecks),
5374 dynamic_type_check_clauses(DynamicChecks).
5375 type_alias(A,B), dynamic_type_check
5377 copy_term_nat(A-B,Alias-Body),
5378 dynamic_type_check_alias_clause(Alias,Body,Clause),
5379 dynamic_type_check_clauses([Clause]).
5381 dynamic_type_check <=>
5383 ('$dynamic_type_check'(Type,Term) :- Goal),
5384 ( atomic_builtin_type(Type,Term,Goal) ; compound_builtin_type(Type,Term,Goal) ),
5387 dynamic_type_check_clauses(BuiltinChecks).
5389 dynamic_type_check_clause(T,DC,Clause) :-
5390 copy_term(T-DC,Type-DefinitionClause),
5391 functor(DefinitionClause,F,A),
5393 DefinitionClause =.. [_|DCArgs],
5394 Term =.. [_|TermArgs],
5395 maplist(dynamic_type_check_call,DCArgs,TermArgs,RecursiveCallList),
5396 list2conj(RecursiveCallList,RecursiveCalls),
5398 '$dynamic_type_check'(Type,Term) :-
5402 dynamic_type_check_alias_clause(Alias,Body,Clause) :-
5404 '$dynamic_type_check'(Alias,Term) :-
5405 '$dynamic_type_check'(Body,Term)
5408 dynamic_type_check_call(Type,Term,Call) :-
5409 % ( nonvar(Type), atomic_builtin_type(Type,Term,Goal) ->
5410 % Call = when(nonvar(Term),Goal)
5411 % ; nonvar(Type), compound_builtin_type(Type,Term,Goal) ->
5412 % Call = when(nonvar(Term),Goal)
5417 Call = when(nonvar(Term),once('$dynamic_type_check'(Type,Term)))
5422 dynamic_type_check_clauses(C1), dynamic_type_check_clauses(C2)
5425 dynamic_type_check_clauses(C).
5427 get_dynamic_type_check_clauses(Q), dynamic_type_check_clauses(C)
5430 get_dynamic_type_check_clauses(Q)
5434 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5436 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5437 % Some optimizations can be applied for atomic types...
5438 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5440 atomic_types_suspended_constraint(C) :-
5442 get_constraint_type(C,ArgTypes),
5443 get_constraint_mode(C,ArgModes),
5444 findall(I,between(1,N,I),Indexes),
5445 maplist(atomic_types_suspended_constraint(C),ArgTypes,ArgModes,Indexes).
5447 atomic_types_suspended_constraint(C,Type,Mode,Index) :-
5448 ( is_indexed_argument(C,Index) ->
5458 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5459 %% atomic_type(+Type) is semidet.
5461 % Succeeds when all values of =Type= are atomic.
5462 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5463 :- chr_constraint atomic_type/1.
5465 atomic_type(Type) <=> atomic_builtin_type(Type,_,_) | Type \== any.
5467 type_definition(TypePat,Def) \ atomic_type(Type)
5469 functor(Type,F,A), functor(TypePat,F,A)
5471 forall(member(Term,Def),atomic(Term)).
5473 type_alias(TypePat,Alias) \ atomic_type(Type)
5475 functor(Type,F,A), functor(TypePat,F,A)
5478 copy_term_nat(TypePat-Alias,Type-NType),
5481 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5482 %% enumerated_atomic_type(+Type,-Atoms) is semidet.
5484 % Succeeds when all values of =Type= are atomic
5485 % and the atom values are finitely enumerable.
5486 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5487 :- chr_constraint enumerated_atomic_type/2.
5489 enumerated_atomic_type(Type,_) <=> atomic_builtin_type(Type,_,_) | fail.
5491 type_definition(TypePat,Def) \ enumerated_atomic_type(Type,Atoms)
5493 functor(Type,F,A), functor(TypePat,F,A)
5495 forall(member(Term,Def),atomic(Term)),
5498 type_alias(TypePat,Alias) \ enumerated_atomic_type(Type,Atoms)
5500 functor(Type,F,A), functor(TypePat,F,A)
5503 copy_term_nat(TypePat-Alias,Type-NType),
5504 enumerated_atomic_type(NType,Atoms).
5505 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5508 stored/3, % constraint,occurrence,(yes/no/maybe)
5509 stored_completing/3,
5512 is_finally_stored/1,
5513 check_all_passive/2.
5515 :- chr_option(mode,stored(+,+,+)).
5516 :- chr_option(type_declaration,stored(any,int,storedinfo)).
5517 :- chr_type storedinfo ---> yes ; no ; maybe.
5518 :- chr_option(mode,stored_complete(+,+,+)).
5519 :- chr_option(mode,maybe_complementary_guards(+,+,?,?)).
5520 :- chr_option(mode,guard_list(+,+,+,+)).
5521 :- chr_option(mode,check_all_passive(+,+)).
5522 :- chr_option(type_declaration,check_all_passive(any,list)).
5524 % change yes in maybe when yes becomes passive
5525 passive(RuleNb,ID), occurrence(C,O,RuleNb,ID,_) \
5526 stored(C,O,yes), stored_complete(C,RO,Yesses)
5527 <=> O < RO | NYesses is Yesses - 1,
5528 stored(C,O,maybe), stored_complete(C,RO,NYesses).
5529 % change yes in maybe when not observed
5530 ai_not_observed(C,O) \ stored(C,O,yes), stored_complete(C,RO,Yesses)
5532 NYesses is Yesses - 1,
5533 stored(C,O,maybe), stored_complete(C,RO,NYesses).
5535 occurrence(_,_,RuleNb,ID,_), occurrence(C2,_,RuleNb,_,_), stored_complete(C2,RO,0), max_occurrence(C2,MO2)
5536 ==> RO =< MO2 | % C2 is never stored
5542 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5544 rule(RuleNb,Rule),passive(RuleNb,Id) ==>
5545 Rule = pragma(rule(Head1,Head2,G,B),ids([Id|IDs1],IDs2),Pragmas,Name,RuleNb) |
5546 append(IDs1,IDs2,I), check_all_passive(RuleNb,I).
5548 rule(RuleNb,Rule),passive(RuleNb,Id) ==>
5549 Rule = pragma(rule(Head1,Head2,G,B),ids([],[Id|IDs2]),Pragmas,Name,RuleNb) |
5550 check_all_passive(RuleNb,IDs2).
5552 passive(RuleNb,Id) \ check_all_passive(RuleNb,[Id|IDs]) <=>
5553 check_all_passive(RuleNb,IDs).
5555 rule(RuleNb,Rule) \ check_all_passive(RuleNb,[]) <=>
5556 chr_warning(weird_program,'All heads passive in ~@.\n\tThis rule never fires. Please check your program.\n',[format_rule(Rule)]).
5558 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5560 % collect the storage information
5561 stored(C,O,yes) \ stored_completing(C,O,Yesses)
5562 <=> NO is O + 1, NYesses is Yesses + 1,
5563 stored_completing(C,NO,NYesses).
5564 stored(C,O,maybe) \ stored_completing(C,O,Yesses)
5566 stored_completing(C,NO,Yesses).
5568 stored(C,O,no) \ stored_completing(C,O,Yesses)
5569 <=> stored_complete(C,O,Yesses).
5570 stored_completing(C,O,Yesses)
5571 <=> stored_complete(C,O,Yesses).
5573 stored_complete(C,O,Yesses), occurrence(C,O2,RuleNb,Id,_) ==>
5574 O2 > O | passive(RuleNb,Id).
5576 % decide whether a constraint is stored
5577 max_occurrence(C,MO), stored_complete(C,RO,0) \ is_stored(C)
5578 <=> RO =< MO | fail.
5579 is_stored(C) <=> true.
5581 % decide whether a constraint is suspends after occurrences
5582 max_occurrence(C,MO), stored_complete(C,RO,_) \ is_finally_stored(C)
5583 <=> RO =< MO | fail.
5584 is_finally_stored(C) <=> true.
5586 storage_analysis(Constraints) :-
5587 ( chr_pp_flag(storage_analysis,on) ->
5588 check_constraint_storages(Constraints)
5593 check_constraint_storages([]).
5594 check_constraint_storages([C|Cs]) :-
5595 check_constraint_storage(C),
5596 check_constraint_storages(Cs).
5598 check_constraint_storage(C) :-
5599 get_max_occurrence(C,MO),
5600 check_occurrences_storage(C,1,MO).
5602 check_occurrences_storage(C,O,MO) :-
5604 stored_completing(C,1,0)
5606 check_occurrence_storage(C,O),
5608 check_occurrences_storage(C,NO,MO)
5611 check_occurrence_storage(C,O) :-
5612 get_occurrence(C,O,RuleNb,ID),
5613 ( is_passive(RuleNb,ID) ->
5616 get_rule(RuleNb,PragmaRule),
5617 PragmaRule = pragma(rule(Heads1,Heads2,Guard,Body),ids(IDs1,IDs2),_,_,_),
5618 ( select2(ID,Head1,IDs1,Heads1,RIDs1,RHeads1) ->
5619 check_storage_head1(Head1,O,Heads1,Heads2,Guard)
5620 ; select2(ID,Head2,IDs2,Heads2,RIDs2,RHeads2) ->
5621 check_storage_head2(Head2,O,Heads1,Body)
5625 check_storage_head1(Head,O,H1,H2,G) :-
5630 % writeq(guard_entailment:entails_guard([chr_pp_headvariables(Head)],G)),nl,
5631 guard_entailment:entails_guard([chr_pp_headvariables(Head)],G),
5633 no_matching(L,[]) ->
5640 no_matching([X|Xs],Prev) :-
5642 \+ memberchk_eq(X,Prev),
5643 no_matching(Xs,[X|Prev]).
5645 check_storage_head2(Head,O,H1,B) :-
5649 ( H1 \== [], B == true )
5651 % \+ is_observed(F/A,O) % always fails because observation analysis has not been performed yet
5659 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5661 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5662 %% ____ _ ____ _ _ _ _
5663 %% | _ \ _ _| | ___ / ___|___ _ __ ___ _ __ (_) | __ _| |_(_) ___ _ __
5664 %% | |_) | | | | |/ _ \ | | / _ \| '_ ` _ \| '_ \| | |/ _` | __| |/ _ \| '_ \
5665 %% | _ <| |_| | | __/ | |__| (_) | | | | | | |_) | | | (_| | |_| | (_) | | | |
5666 %% |_| \_\\__,_|_|\___| \____\___/|_| |_| |_| .__/|_|_|\__,_|\__|_|\___/|_| |_|
5669 constraints_code(Constraints,Clauses) :-
5670 (chr_pp_flag(reduced_indexing,on),
5671 \+ forsome(C,Constraints,\+ chr_translate:only_ground_indexed_arguments(C)) ->
5672 none_suspended_on_variables
5676 constraints_code1(Constraints,Clauses,[]).
5678 %===============================================================================
5679 :- chr_constraint constraints_code1/3.
5680 :- chr_option(mode,constraints_code1(+,+,+)).
5681 :- chr_option(type_declaration,constraints_code1(list,any,any)).
5682 %-------------------------------------------------------------------------------
5683 constraints_code1([],L,T) <=> L = T.
5684 constraints_code1([C|RCs],L,T)
5686 constraint_code(C,L,T1),
5687 constraints_code1(RCs,T1,T).
5688 %===============================================================================
5689 :- chr_constraint constraint_code/3.
5690 :- chr_option(mode,constraint_code(+,+,+)).
5691 %-------------------------------------------------------------------------------
5692 %% Generate code for a single CHR constraint
5693 constraint_code(Constraint, L, T)
5695 | ( (chr_pp_flag(debugable,on) ;
5696 is_stored(Constraint), ( has_active_occurrence(Constraint); chr_pp_flag(late_allocation,off)),
5697 ( may_trigger(Constraint) ;
5698 get_allocation_occurrence(Constraint,AO),
5699 get_max_occurrence(Constraint,MO), MO >= AO ) )
5701 constraint_prelude(Constraint,Clause),
5702 add_dummy_location(Clause,LocatedClause),
5703 L = [LocatedClause | L1]
5708 occurrences_code(Constraint,1,Id,NId,L1,L2),
5709 gen_cond_attach_clause(Constraint,NId,L2,T).
5711 %===============================================================================
5712 %% Generate prelude predicate for a constraint.
5713 %% f(...) :- f/a_0(...,Susp).
5714 constraint_prelude(F/A, Clause) :-
5715 vars_susp(A,Vars,Susp,VarsSusp),
5716 Head =.. [ F | Vars],
5717 make_suspension_continuation_goal(F/A,VarsSusp,Continuation),
5718 build_head(F,A,[0],VarsSusp,Delegate),
5719 ( chr_pp_flag(debugable,on) ->
5720 insert_constraint_goal(F/A,Susp,Vars,InsertCall),
5721 attach_constraint_atom(F/A,Vars2,Susp,AttachCall),
5722 delay_phase_end(validate_store_type_assumptions,chr_translate:update_suspension_field(F/A,Susp,state,inactive,Inactive)),
5723 insert_constraint_internal_constraint_goal(F/A, Vars2, Susp, Continuation, Vars,InsertGoal),
5725 ( get_constraint_type(F/A,ArgTypeList) ->
5726 maplist(dynamic_type_check_call,ArgTypeList,Vars,DynamicTypeCheckList),
5727 list2conj(DynamicTypeCheckList,DynamicTypeChecks)
5729 DynamicTypeChecks = true
5739 'chr debug_event'(insert(Head#Susp)),
5741 'chr debug_event'(call(Susp)),
5744 'chr debug_event'(fail(Susp)), !,
5748 'chr debug_event'(exit(Susp))
5750 'chr debug_event'(redo(Susp)),
5754 ; get_allocation_occurrence(F/A,0) ->
5755 gen_insert_constraint_internal_goal(F/A,Goal,VarsSusp,Vars,Susp),
5756 delay_phase_end(validate_store_type_assumptions,chr_translate:update_suspension_field(F/A,Susp,state,inactive,Inactive)),
5757 Clause = ( Head :- Goal, Inactive, Delegate )
5759 Clause = ( Head :- Delegate )
5762 make_suspension_continuation_goal(F/A,VarsSusp,Goal) :-
5763 ( may_trigger(F/A) ->
5764 build_head(F,A,[0],VarsSusp,Delegate),
5765 ( chr_pp_flag(debugable,off) ->
5768 get_target_module(Mod),
5775 %===============================================================================
5776 :- chr_constraint has_active_occurrence/1, has_active_occurrence/2.
5777 :- chr_option(mode,has_active_occurrence(+)).
5778 :- chr_option(mode,has_active_occurrence(+,+)).
5779 %-------------------------------------------------------------------------------
5780 has_active_occurrence(C) <=> has_active_occurrence(C,1).
5782 max_occurrence(C,MO) \ has_active_occurrence(C,O) <=>
5784 passive(RuleNb,ID),occurrence(C,O,RuleNb,ID,_) \
5785 has_active_occurrence(C,O) <=>
5787 has_active_occurrence(C,NO).
5788 has_active_occurrence(C,O) <=> true.
5789 %===============================================================================
5791 gen_cond_attach_clause(F/A,Id,L,T) :-
5792 ( is_finally_stored(F/A) ->
5793 get_allocation_occurrence(F/A,AllocationOccurrence),
5794 get_max_occurrence(F/A,MaxOccurrence),
5795 ( chr_pp_flag(debugable,off), MaxOccurrence < AllocationOccurrence ->
5796 ( only_ground_indexed_arguments(F/A) ->
5797 gen_insert_constraint_internal_goal(F/A,Body,AllArgs,Args,Susp)
5799 gen_cond_attach_goal(F/A,Body,AllArgs,Args,Susp)
5801 ; vars_susp(A,Args,Susp,AllArgs),
5802 gen_uncond_attach_goal(F/A,Susp,Args,Body,_)
5804 build_head(F,A,Id,AllArgs,Head),
5805 Clause = ( Head :- Body ),
5806 add_dummy_location(Clause,LocatedClause),
5807 L = [LocatedClause | T]
5812 :- chr_constraint use_auxiliary_predicate/1.
5813 :- chr_option(mode,use_auxiliary_predicate(+)).
5815 :- chr_constraint use_auxiliary_predicate/2.
5816 :- chr_option(mode,use_auxiliary_predicate(+,+)).
5818 :- chr_constraint is_used_auxiliary_predicate/1.
5819 :- chr_option(mode,is_used_auxiliary_predicate(+)).
5821 :- chr_constraint is_used_auxiliary_predicate/2.
5822 :- chr_option(mode,is_used_auxiliary_predicate(+,+)).
5825 use_auxiliary_predicate(P) \ use_auxiliary_predicate(P) <=> true.
5827 use_auxiliary_predicate(P,C) \ use_auxiliary_predicate(P,C) <=> true.
5829 use_auxiliary_predicate(P) \ is_used_auxiliary_predicate(P) <=> true.
5831 use_auxiliary_predicate(P,_) \ is_used_auxiliary_predicate(P) <=> true.
5833 is_used_auxiliary_predicate(P) <=> fail.
5835 use_auxiliary_predicate(P) \ is_used_auxiliary_predicate(P,_) <=> true.
5836 use_auxiliary_predicate(P,C) \ is_used_auxiliary_predicate(P,C) <=> true.
5838 is_used_auxiliary_predicate(P,C) <=> fail.
5840 %------------------------------------------------------------------------------%
5841 % Only generate import statements for actually used modules.
5842 %------------------------------------------------------------------------------%
5844 :- chr_constraint use_auxiliary_module/1.
5845 :- chr_option(mode,use_auxiliary_module(+)).
5847 :- chr_constraint is_used_auxiliary_module/1.
5848 :- chr_option(mode,is_used_auxiliary_module(+)).
5851 use_auxiliary_module(P) \ use_auxiliary_module(P) <=> true.
5853 use_auxiliary_module(P) \ is_used_auxiliary_module(P) <=> true.
5855 is_used_auxiliary_module(P) <=> fail.
5857 % only called for constraints with
5859 % non-ground indexed argument
5860 gen_cond_attach_goal(F/A,Goal,AllArgs,Args,Susp) :-
5861 vars_susp(A,Args,Susp,AllArgs),
5862 make_suspension_continuation_goal(F/A,AllArgs,Closure),
5863 ( get_store_type(F/A,var_assoc_store(_,_)) ->
5866 attach_constraint_atom(F/A,Vars,Susp,Attach)
5869 insert_constraint_goal(F/A,Susp,Args,InsertCall),
5870 insert_constraint_internal_constraint_goal(F/A, Vars, Susp, Closure, Args,InsertGoal),
5871 ( may_trigger(F/A) ->
5872 activate_constraint_goal(F/A,(InsertCall,Attach),Vars,Susp,_,ActivateGoal),
5876 InsertGoal, % insert_constraint_internal(Stored,Vars,Susp,Closure,F,Args)
5880 ActivateGoal % activate_constraint(Stored,Vars,Susp,_)
5886 InsertGoal, % insert_constraint_internal(Stored,Vars,Susp,Closure,F,Args),
5892 gen_insert_constraint_internal_goal(F/A,Goal,AllArgs,Args,Susp) :-
5893 vars_susp(A,Args,Susp,AllArgs),
5894 make_suspension_continuation_goal(F/A,AllArgs,Cont),
5895 ( \+ only_ground_indexed_arguments(F/A), \+ get_store_type(F/A,var_assoc_store(_,_)) ->
5896 attach_constraint_atom(F/A,Vars,Susp,Attach)
5901 insert_constraint_goal(F/A,Susp,Args,InsertCall),
5902 insert_constraint_internal_constraint_goal(F/A, Vars, Susp, Cont, Args,InsertInternalGoal),
5903 ( only_ground_indexed_arguments(F/A), chr_pp_flag(debugable,off) ->
5906 InsertInternalGoal, % insert_constraint_internal(Susp,F,Args),
5912 InsertInternalGoal, % insert_constraint_internal(_,Vars,Susp,Cont,F,Args),
5918 gen_uncond_attach_goal(FA,Susp,Args,AttachGoal,Generation) :-
5919 ( \+ only_ground_indexed_arguments(FA), \+ get_store_type(FA,var_assoc_store(_,_)) ->
5920 attach_constraint_atom(FA,Vars,Susp,Attach)
5924 insert_constraint_goal(FA,Susp,Args,InsertCall),
5925 ( chr_pp_flag(late_allocation,on) ->
5926 activate_constraint_goal(FA,(InsertCall,Attach),Vars,Susp,Generation,AttachGoal)
5928 activate_constraint_goal(FA,true,Vars,Susp,Generation,AttachGoal)
5931 %-------------------------------------------------------------------------------
5932 :- chr_constraint occurrences_code/6.
5933 :- chr_option(mode,occurrences_code(+,+,+,+,+,+)).
5934 %-------------------------------------------------------------------------------
5935 max_occurrence(C,MO) \ occurrences_code(C,O,Id,NId,L,T)
5938 occurrences_code(C,O,Id,NId,L,T)
5940 occurrence_code(C,O,Id,Id1,L,L1),
5942 occurrences_code(C,NO,Id1,NId,L1,T).
5943 %-------------------------------------------------------------------------------
5944 :- chr_constraint occurrence_code/6.
5945 :- chr_option(mode,occurrence_code(+,+,+,+,+,+)).
5946 %-------------------------------------------------------------------------------
5947 occurrence(C,O,RuleNb,ID,_), passive(RuleNb,ID) \ occurrence_code(C,O,Id,NId,L,T)
5949 ( named_history(RuleNb,_,_) ->
5950 does_use_history(C,O)
5956 occurrence(C,O,RuleNb,ID,_), rule(RuleNb,PragmaRule) \ occurrence_code(C,O,Id,NId,L,T)
5958 PragmaRule = pragma(rule(Heads1,Heads2,_,_),ids(IDs1,IDs2),_,_,_),
5959 ( select2(ID,Head1,IDs1,Heads1,RIDs1,RHeads1) ->
5961 head1_code(Head1,ID,RHeads1,RIDs1,PragmaRule,C,O,Id,L,T)
5962 ; select2(ID,Head2,IDs2,Heads2,RIDs2,RHeads2) ->
5963 head2_code(Head2,ID,RHeads2,RIDs2,PragmaRule,C,O,Id,L,L1),
5965 ( unconditional_occurrence(C,O) ->
5968 gen_alloc_inc_clause(C,O,Id,L1,T)
5972 occurrence_code(C,O,_,_,_,_)
5974 chr_error(internal,'occurrence_code/6: missing information to compile ~w:~w\n',[C,O]).
5975 %-------------------------------------------------------------------------------
5977 %% Generate code based on one removed head of a CHR rule
5978 head1_code(Head,ID,OtherHeads,OtherIDs,PragmaRule,FA,O,Id,L,T) :-
5979 PragmaRule = pragma(Rule,_,_,_Name,RuleNb),
5980 Rule = rule(_,Head2,_,_),
5982 reorder_heads(RuleNb,Head,OtherHeads,OtherIDs,NOtherHeads,NOtherIDs),
5983 simplification_code(Head,ID,NOtherHeads,NOtherIDs,PragmaRule,FA,O,Id,L,T)
5985 simpagation_head1_code(Head,ID,OtherHeads,OtherIDs,PragmaRule,FA,O,Id,L,T)
5988 %% Generate code based on one persistent head of a CHR rule
5989 head2_code(Head,ID,OtherHeads,OtherIDs,PragmaRule,FA,O,Id,L,T) :-
5990 PragmaRule = pragma(Rule,_,_,_Name,RuleNb),
5991 Rule = rule(Head1,_,_,_),
5993 reorder_heads(RuleNb,Head,OtherHeads,OtherIDs,NOtherHeads,NOtherIDs),
5994 propagation_code(Head,ID,NOtherHeads,NOtherIDs,Rule,RuleNb,FA,O,Id,L,T)
5996 simpagation_head2_code(Head,ID,OtherHeads,OtherIDs,PragmaRule,FA,O,Id,L,T)
5999 gen_alloc_inc_clause(F/A,O,Id,L,T) :-
6000 vars_susp(A,Vars,Susp,VarsSusp),
6001 build_head(F,A,Id,VarsSusp,Head),
6003 build_head(F,A,IncId,VarsSusp,CallHead),
6004 gen_occ_allocation(F/A,O,Vars,Susp,ConditionalAlloc),
6011 add_dummy_location(Clause,LocatedClause),
6012 L = [LocatedClause|T].
6014 gen_occ_allocation(FA,O,Vars,Susp,Goal) :-
6015 get_allocation_occurrence(FA,AO),
6016 ( chr_pp_flag(debugable,off), O == AO ->
6017 allocate_constraint_goal(FA,Susp,Vars,Goal0),
6018 ( may_trigger(FA) ->
6019 Goal = (var(Susp) -> Goal0 ; true)
6027 gen_occ_allocation_in_guard(FA,O,Vars,Susp,Goal) :-
6028 get_allocation_occurrence(FA,AO),
6029 ( chr_pp_flag(debugable,off), O < AO ->
6030 allocate_constraint_goal(FA,Susp,Vars,Goal0),
6031 ( may_trigger(FA) ->
6032 Goal = (var(Susp) -> Goal0 ; true)
6040 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6042 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6044 % Reorders guard goals with respect to partner constraint retrieval goals and
6045 % active constraint. Returns combined partner retrieval + guard goal.
6047 guard_via_reschedule_new(Retrievals,GuardList,Prelude,GuardListSkeleton,LookupSkeleton,GoalSkeleton) :-
6048 ( chr_pp_flag(guard_via_reschedule,on) ->
6049 guard_via_reschedule_main_new(Retrievals,GuardList,Prelude,GuardListSkeleton,LookupSkeleton,ScheduleSkeleton),
6050 list2conj(ScheduleSkeleton,GoalSkeleton)
6052 length(Retrievals,RL), length(LookupSkeleton,RL),
6053 length(GuardList,GL), length(GuardListSkeleton,GL),
6054 append(LookupSkeleton,GuardListSkeleton,GoalListSkeleton),
6055 list2conj(GoalListSkeleton,GoalSkeleton)
6057 guard_via_reschedule_main_new(PartnerLookups,GuardList,ActiveHead,
6058 GuardListSkeleton,LookupSkeleton,ScheduleSkeleton) :-
6059 initialize_unit_dictionary(ActiveHead,Dict),
6060 maplist(wrap_in_functor(lookup),PartnerLookups,WrappedPartnerLookups),
6061 maplist(wrap_in_functor(guard),GuardList,WrappedGuardList),
6062 build_units(WrappedPartnerLookups,WrappedGuardList,Dict,Units),
6063 dependency_reorder(Units,NUnits),
6064 wrappedunits2lists(NUnits,IndexedGuardListSkeleton,LookupSkeleton,ScheduleSkeleton),
6065 sort(IndexedGuardListSkeleton,SortedIndexedGuardListSkeleton),
6066 snd_of_pairs(SortedIndexedGuardListSkeleton,GuardListSkeleton).
6068 wrap_in_functor(Functor,X,Term) :-
6069 Term =.. [Functor,X].
6071 wrappedunits2lists([],[],[],[]).
6072 wrappedunits2lists([unit(N,WrappedGoal,_,_)|Units],Gs,Ls,Ss) :-
6073 Ss = [GoalCopy|TSs],
6074 ( WrappedGoal = lookup(Goal) ->
6075 Ls = [GoalCopy|TLs],
6077 ; WrappedGoal = guard(Goal) ->
6078 Gs = [N-GoalCopy|TGs],
6081 wrappedunits2lists(Units,TGs,TLs,TSs).
6083 guard_splitting(Rule,SplitGuardList) :-
6084 Rule = rule(H1,H2,Guard,_),
6085 append(H1,H2,Heads),
6086 conj2list(Guard,GuardList),
6087 term_variables(Heads,HeadVars),
6088 split_off_simple_guard_new(GuardList,HeadVars,GuardPrefix,RestGuardList),
6089 append(GuardPrefix,[RestGuard],SplitGuardList),
6090 term_variables(RestGuardList,GuardVars1),
6091 % variables that are declared to be ground don't need to be locked
6092 ground_vars(Heads,GroundVars),
6093 list_difference_eq(HeadVars,GroundVars,LockableHeadVars),
6094 intersect_eq(LockableHeadVars,GuardVars1,GuardVars),
6095 ( chr_pp_flag(guard_locks,on),
6096 bagof(('chr lock'(X)) - ('chr unlock'(X)), (lists:member(X,GuardVars)), LocksUnlocks) ->
6097 once(pairup(Locks,Unlocks,LocksUnlocks))
6102 list2conj(Locks,LockPhase),
6103 list2conj(Unlocks,UnlockPhase),
6104 list2conj(RestGuardList,RestGuard1),
6105 RestGuard = (LockPhase,(RestGuard1,UnlockPhase)).
6107 guard_body_copies3(Rule,GuardList,VarDict,GuardCopyList,BodyCopy) :-
6108 Rule = rule(_,_,_,Body),
6109 my_term_copy(GuardList,VarDict,VarDict2,GuardCopyList),
6110 my_term_copy(Body,VarDict2,BodyCopy).
6113 split_off_simple_guard_new([],_,[],[]).
6114 split_off_simple_guard_new([G|Gs],VarDict,S,C) :-
6115 ( simple_guard_new(G,VarDict) ->
6117 split_off_simple_guard_new(Gs,VarDict,Ss,C)
6123 % simple guard: cheap and benign (does not bind variables)
6124 simple_guard_new(G,Vars) :-
6125 builtin_binds_b(G,BoundVars),
6126 \+ (( member(V,BoundVars),
6127 memberchk_eq(V,Vars)
6130 dependency_reorder(Units,NUnits) :-
6131 dependency_reorder(Units,[],NUnits).
6133 dependency_reorder([],Acc,Result) :-
6134 reverse(Acc,Result).
6136 dependency_reorder([Unit|Units],Acc,Result) :-
6137 Unit = unit(_GID,_Goal,Type,GIDs),
6141 dependency_insert(Acc,Unit,GIDs,NAcc)
6143 dependency_reorder(Units,NAcc,Result).
6145 dependency_insert([],Unit,_,[Unit]).
6146 dependency_insert([X|Xs],Unit,GIDs,L) :-
6147 X = unit(GID,_,_,_),
6148 ( memberchk(GID,GIDs) ->
6152 dependency_insert(Xs,Unit,GIDs,T)
6155 build_units(Retrievals,Guard,InitialDict,Units) :-
6156 build_retrieval_units(Retrievals,1,N,InitialDict,Dict,Units,Tail),
6157 build_guard_units(Guard,N,Dict,Tail).
6159 build_retrieval_units([],N,N,Dict,Dict,L,L).
6160 build_retrieval_units([U|Us],N,M,Dict,NDict,L,T) :-
6161 term_variables(U,Vs),
6162 update_unit_dictionary(Vs,N,Dict,Dict1,[],GIDs),
6163 L = [unit(N,U,fixed,GIDs)|L1],
6165 build_retrieval_units(Us,N1,M,Dict1,NDict,L1,T).
6167 initialize_unit_dictionary(Term,Dict) :-
6168 term_variables(Term,Vars),
6169 pair_all_with(Vars,0,Dict).
6171 update_unit_dictionary([],_,Dict,Dict,GIDs,GIDs).
6172 update_unit_dictionary([V|Vs],This,Dict,NDict,GIDs,NGIDs) :-
6173 ( lookup_eq(Dict,V,GID) ->
6174 ( (GID == This ; memberchk(GID,GIDs) ) ->
6181 Dict1 = [V - This|Dict],
6184 update_unit_dictionary(Vs,This,Dict1,NDict,GIDs1,NGIDs).
6186 build_guard_units(Guard,N,Dict,Units) :-
6188 Units = [unit(N,Goal,fixed,[])]
6189 ; Guard = [Goal|Goals] ->
6190 term_variables(Goal,Vs),
6191 update_unit_dictionary2(Vs,N,Dict,NDict,[],GIDs),
6192 Units = [unit(N,Goal,movable,GIDs)|RUnits],
6194 build_guard_units(Goals,N1,NDict,RUnits)
6197 update_unit_dictionary2([],_,Dict,Dict,GIDs,GIDs).
6198 update_unit_dictionary2([V|Vs],This,Dict,NDict,GIDs,NGIDs) :-
6199 ( lookup_eq(Dict,V,GID) ->
6200 ( (GID == This ; memberchk(GID,GIDs) ) ->
6205 Dict1 = [V - This|Dict]
6207 Dict1 = [V - This|Dict],
6210 update_unit_dictionary2(Vs,This,Dict1,NDict,GIDs1,NGIDs).
6212 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6214 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6216 %% / ___| ___| |_ / ___| ___ _ __ ___ __ _ _ __ | |_(_) ___ ___ _
6217 %% \___ \ / _ \ __| \___ \ / _ \ '_ ` _ \ / _` | '_ \| __| |/ __/ __(_)
6218 %% ___) | __/ |_ ___) | __/ | | | | | (_| | | | | |_| | (__\__ \_
6219 %% |____/ \___|\__| |____/ \___|_| |_| |_|\__,_|_| |_|\__|_|\___|___(_)
6222 %% | | | |_ __ (_) __ _ _ _ ___ |_ _|_ __ / _| ___ _ __ ___ _ __ ___ ___
6223 %% | | | | '_ \| |/ _` | | | |/ _ \ | || '_ \| |_ / _ \ '__/ _ \ '_ \ / __/ _ \
6224 %% | |_| | | | | | (_| | |_| | __/ | || | | | _| __/ | | __/ | | | (_| __/
6225 %% \___/|_| |_|_|\__, |\__,_|\___| |___|_| |_|_| \___|_| \___|_| |_|\___\___|
6228 functional_dependency/4,
6229 get_functional_dependency/4.
6231 :- chr_option(mode,functional_dependency(+,+,?,?)).
6232 :- chr_option(mode,get_functional_dependency(+,+,?,?)).
6234 allocation_occurrence(C,AO), occurrence(C,O,RuleNb,_,_) \ functional_dependency(C,RuleNb,Pattern,Key)
6238 functional_dependency(C,1,Pattern,Key).
6240 functional_dependency(C,RuleNb1,Pattern,Key) \ get_functional_dependency(C,RuleNb2,QPattern,QKey)
6244 QPattern = Pattern, QKey = Key.
6245 get_functional_dependency(_,_,_,_)
6249 functional_dependency_analysis(Rules) :-
6250 ( fail, chr_pp_flag(functional_dependency_analysis,on) ->
6251 functional_dependency_analysis_main(Rules)
6256 functional_dependency_analysis_main([]).
6257 functional_dependency_analysis_main([PRule|PRules]) :-
6258 ( discover_unique_pattern(PRule,C,RuleNb,Pattern,Key) ->
6259 functional_dependency(C,RuleNb,Pattern,Key)
6263 functional_dependency_analysis_main(PRules).
6265 discover_unique_pattern(PragmaRule,F/A,RuleNb,Pattern,Key) :-
6266 PragmaRule = pragma(Rule,_,_,Name,RuleNb),
6267 Rule = rule(H1,H2,Guard,_),
6275 check_unique_constraints(C1,C2,Guard,RuleNb,List),
6276 term_variables(C1,Vs),
6279 lookup_eq(List,V1,V2),
6282 select_pragma_unique_variables(Vs,List,Key1),
6283 copy_term_nat(C1-Key1,Pattern-Key),
6286 select_pragma_unique_variables([],_,[]).
6287 select_pragma_unique_variables([V|Vs],List,L) :-
6288 ( lookup_eq(List,V,_) ->
6293 select_pragma_unique_variables(Vs,List,T).
6295 % depends on functional dependency analysis
6296 % and shape of rule: C1 \ C2 <=> true.
6297 set_semantics_rules(Rules) :-
6298 ( fail, chr_pp_flag(set_semantics_rule,on) ->
6299 set_semantics_rules_main(Rules)
6304 set_semantics_rules_main([]).
6305 set_semantics_rules_main([R|Rs]) :-
6306 set_semantics_rule_main(R),
6307 set_semantics_rules_main(Rs).
6309 set_semantics_rule_main(PragmaRule) :-
6310 PragmaRule = pragma(Rule,IDs,Pragmas,_,RuleNb),
6311 ( Rule = rule([C1],[C2],true,_),
6312 IDs = ids([ID1],[ID2]),
6313 \+ is_passive(RuleNb,ID1),
6315 get_functional_dependency(F/A,RuleNb,Pattern,Key),
6316 copy_term_nat(Pattern-Key,C1-Key1),
6317 copy_term_nat(Pattern-Key,C2-Key2),
6324 check_unique_constraints(C1,C2,G,RuleNb,List) :-
6325 \+ any_passive_head(RuleNb),
6326 variable_replacement(C1-C2,C2-C1,List),
6327 copy_with_variable_replacement(G,OtherG,List),
6329 once(entails_b(NotG,OtherG)).
6331 % checks for rules of the shape ...,C1,C2... (<|=)=> ...
6332 % where C1 and C2 are symmteric constraints
6333 symmetry_analysis(Rules) :-
6334 ( chr_pp_flag(check_unnecessary_active,off) ->
6337 symmetry_analysis_main(Rules)
6340 symmetry_analysis_main([]).
6341 symmetry_analysis_main([R|Rs]) :-
6342 R = pragma(Rule,ids(IDs1,IDs2),_,_,RuleNb),
6343 Rule = rule(H1,H2,_,_),
6344 ( ( \+ chr_pp_flag(check_unnecessary_active,simplification) ; H2 == [] ), H1 \== [] ->
6345 symmetry_analysis_heads_simplification(H1,IDs1,[],[],Rule,RuleNb),
6346 symmetry_analysis_heads_propagation(H2,IDs2,[],[],Rule,RuleNb)
6350 symmetry_analysis_main(Rs).
6352 symmetry_analysis_heads_simplification([],[],_,_,_,_).
6353 symmetry_analysis_heads_simplification([H|Hs],[ID|IDs],PreHs,PreIDs,Rule,RuleNb) :-
6354 ( \+ is_passive(RuleNb,ID),
6355 member2(PreHs,PreIDs,PreH-PreID),
6356 \+ is_passive(RuleNb,PreID),
6357 variable_replacement(PreH,H,List),
6358 copy_with_variable_replacement(Rule,Rule2,List),
6359 identical_guarded_rules(Rule,Rule2) ->
6364 symmetry_analysis_heads_simplification(Hs,IDs,[H|PreHs],[ID|PreIDs],Rule,RuleNb).
6366 symmetry_analysis_heads_propagation([],[],_,_,_,_).
6367 symmetry_analysis_heads_propagation([H|Hs],[ID|IDs],PreHs,PreIDs,Rule,RuleNb) :-
6368 ( \+ is_passive(RuleNb,ID),
6369 member2(PreHs,PreIDs,PreH-PreID),
6370 \+ is_passive(RuleNb,PreID),
6371 variable_replacement(PreH,H,List),
6372 copy_with_variable_replacement(Rule,Rule2,List),
6373 identical_rules(Rule,Rule2) ->
6378 symmetry_analysis_heads_propagation(Hs,IDs,[H|PreHs],[ID|PreIDs],Rule,RuleNb).
6380 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6382 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6383 %% ____ _ _ _ __ _ _ _
6384 %% / ___|(_)_ __ ___ _ __ | (_)/ _(_) ___ __ _| |_(_) ___ _ __
6385 %% \___ \| | '_ ` _ \| '_ \| | | |_| |/ __/ _` | __| |/ _ \| '_ \
6386 %% ___) | | | | | | | |_) | | | _| | (_| (_| | |_| | (_) | | | |
6387 %% |____/|_|_| |_| |_| .__/|_|_|_| |_|\___\__,_|\__|_|\___/|_| |_|
6390 simplification_code(Head,ID,RestHeads,RestIDs,PragmaRule,F/A,O,Id,L,T) :-
6391 PragmaRule = pragma(Rule,_,Pragmas,_,RuleNb),
6392 head_info(Head,A,_Vars,Susp,HeadVars,HeadPairs),
6393 build_head(F,A,Id,HeadVars,ClauseHead),
6394 get_constraint_mode(F/A,Mode),
6395 head_arg_matches(HeadPairs,Mode,[],FirstMatching,VarDict1,[],GroundVars),
6398 guard_splitting(Rule,GuardList0),
6399 ( is_stored_in_guard(F/A, RuleNb) ->
6400 GuardList = [Hole1|GuardList0]
6402 GuardList = GuardList0
6404 guard_via_reschedule_new(RestHeads,GuardList,Head,GuardCopyList,GetRestHeads,RescheduledTest),
6406 rest_heads_retrieval_and_matching(RestHeads,RestIDs,Head,GetRestHeads,Susps,VarDict1,VarDict,[],[],[],GroundVars,_),
6408 guard_body_copies3(Rule,GuardList,VarDict,GuardCopyList,BodyCopy),
6410 ( is_stored_in_guard(F/A, RuleNb) ->
6411 gen_occ_allocation_in_guard(F/A,O,Vars,Susp,Allocation),
6412 gen_uncond_attach_goal(F/A,Susp,Vars,Attachment,_),
6413 GuardCopyList = [Hole1Copy|_],
6414 Hole1Copy = (Allocation, Attachment)
6420 partner_constraint_detachments(Susps,RestHeads,VarDict,SuspsDetachments),
6421 active_constraint_detachment(Id,Susp,Head,VarDict,SuspDetachment),
6423 ( chr_pp_flag(debugable,on) ->
6424 Rule = rule(_,_,Guard,Body),
6425 my_term_copy(Guard - Body, VarDict, DebugGuard - DebugBody),
6426 sort_by_key([Susp|Susps],[ID|RestIDs],SortedSusps),
6427 DebugTry = 'chr debug_event'( try(SortedSusps,[],DebugGuard,DebugBody)),
6428 DebugApply = 'chr debug_event'(apply(SortedSusps,[],DebugGuard,DebugBody)),
6429 instrument_goal(ActualCut,DebugTry,DebugApply,Cut)
6433 ( unconditional_occurrence(F/A,O), chr_pp_flag(late_allocation,on) -> ActualCut = true ; ActualCut = (!) ),
6434 Clause = ( ClauseHead :-
6442 add_location(Clause,RuleNb,LocatedClause),
6443 L = [LocatedClause | T].
6445 add_location(Clause,RuleNb,NClause) :-
6446 ( chr_pp_flag(line_numbers,on) ->
6447 get_chr_source_file(File),
6448 get_line_number(RuleNb,LineNb),
6449 NClause = '$source_location'(File,LineNb):Clause
6454 add_dummy_location(Clause,NClause) :-
6455 ( chr_pp_flag(line_numbers,on) ->
6456 get_chr_source_file(File),
6457 NClause = '$source_location'(File,1):Clause
6461 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6462 %% head_arg_matches(+Pairs,+Modes,+VarDict,-Goal,-NVarDict) is det.
6464 % Return goal matching newly introduced variables with variables in
6465 % previously looked-up heads.
6466 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6467 head_arg_matches(Pairs,Modes,VarDict,Goal,NVarDict) :-
6468 head_arg_matches(Pairs,Modes,VarDict,Goal,NVarDict,[],_).
6470 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6471 %% head_arg_matches(+Pairs,+Modes,+VarDict,-Goal,-NVarDict,+GroundVars,-NGroundVars) is det.
6472 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6473 head_arg_matches(Pairs,Modes,VarDict,Goal,NVarDict,GroundVars,NGroundVars) :-
6474 head_arg_matches_(Pairs,Modes,VarDict,GroundVars,GoalList,NVarDict,NGroundVars),
6475 list2conj(GoalList,Goal).
6477 head_arg_matches_([],[],VarDict,GroundVars,[],VarDict,GroundVars).
6478 head_arg_matches_([Arg-Var| Rest],[Mode|Modes],VarDict,GroundVars,GoalList,NVarDict,NGroundVars) :-
6480 ( lookup_eq(VarDict,Arg,OtherVar) ->
6482 ( memberchk_eq(Arg,GroundVars) ->
6483 GoalList = [Var = OtherVar | RestGoalList],
6484 GroundVars1 = GroundVars
6486 GoalList = [Var == OtherVar | RestGoalList],
6487 GroundVars1 = [Arg|GroundVars]
6490 GoalList = [Var == OtherVar | RestGoalList],
6491 GroundVars1 = GroundVars
6495 VarDict1 = [Arg-Var | VarDict],
6496 GoalList = RestGoalList,
6498 GroundVars1 = [Arg|GroundVars]
6500 GroundVars1 = GroundVars
6505 ; ground(Arg), Arg = '$chr_identifier_match'(ActualArg,IndexType) ->
6506 identifier_label_atom(IndexType,Var,ActualArg,Goal),
6507 GoalList = [Goal|RestGoalList],
6509 GroundVars1 = GroundVars,
6514 GoalList = [ Var = Arg | RestGoalList]
6516 GoalList = [ Var == Arg | RestGoalList]
6519 GroundVars1 = GroundVars,
6522 ; Mode == (+), is_ground(GroundVars,Arg) ->
6523 copy_with_variable_replacement(Arg,ArgCopy,VarDict),
6524 GoalList = [ Var = ArgCopy | RestGoalList],
6526 GroundVars1 = GroundVars,
6531 functor(Term,Fct,N),
6534 GoalList = [ Var = Term | RestGoalList ]
6536 GoalList = [ nonvar(Var), Var = Term | RestGoalList ]
6538 pairup(Args,Vars,NewPairs),
6539 append(NewPairs,Rest,Pairs),
6540 replicate(N,Mode,NewModes),
6541 append(NewModes,Modes,RestModes),
6543 GroundVars1 = GroundVars
6545 head_arg_matches_(Pairs,RestModes,VarDict1,GroundVars1,RestGoalList,NVarDict,NGroundVars).
6547 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6548 % add_heads_types(+ListOfHeads,+VarTypes,-NVarTypes) is det.
6549 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6550 add_heads_types([],VarTypes,VarTypes).
6551 add_heads_types([Head|Heads],VarTypes,NVarTypes) :-
6552 add_head_types(Head,VarTypes,VarTypes1),
6553 add_heads_types(Heads,VarTypes1,NVarTypes).
6555 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6556 % add_head_types(+Head,+VarTypes,-NVarTypes) is det.
6557 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6558 add_head_types(Head,VarTypes,NVarTypes) :-
6560 get_constraint_type_det(F/A,ArgTypes),
6562 add_args_types(Args,ArgTypes,VarTypes,NVarTypes).
6564 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6565 % add_args_types(+Terms,+Types,+VarTypes,-NVarTypes) is det.
6566 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6567 add_args_types([],[],VarTypes,VarTypes).
6568 add_args_types([Arg|Args],[Type|Types],VarTypes,NVarTypes) :-
6569 add_arg_types(Arg,Type,VarTypes,VarTypes1),
6570 add_args_types(Args,Types,VarTypes1,NVarTypes).
6572 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6573 % add_arg_types(+Term,+Type,+VarTypes,-NVarTypes) is det.
6574 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6575 add_arg_types(Term,Type,VarTypes,NVarTypes) :-
6577 ( lookup_eq(VarTypes,Term,_) ->
6578 NVarTypes = VarTypes
6580 NVarTypes = [Term-Type|VarTypes]
6583 NVarTypes = VarTypes
6584 ; % TODO improve approximation!
6585 term_variables(Term,Vars),
6587 replicate(VarNb,any,Types),
6588 add_args_types(Vars,Types,VarTypes,NVarTypes)
6593 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6594 %% add_heads_ground_variables(+ListOfHeads,+GroundVars,-NGroundVars) is det.
6596 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6597 add_heads_ground_variables([],GroundVars,GroundVars).
6598 add_heads_ground_variables([Head|Heads],GroundVars,NGroundVars) :-
6599 add_head_ground_variables(Head,GroundVars,GroundVars1),
6600 add_heads_ground_variables(Heads,GroundVars1,NGroundVars).
6602 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6603 %% add_head_ground_variables(+Head,+GroundVars,-GroundVars) is det.
6605 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6606 add_head_ground_variables(Head,GroundVars,NGroundVars) :-
6608 get_constraint_mode(F/A,ArgModes),
6610 add_arg_ground_variables(Args,ArgModes,GroundVars,NGroundVars).
6613 add_arg_ground_variables([],[],GroundVars,GroundVars).
6614 add_arg_ground_variables([Arg|Args],[Mode|Modes],GroundVars,NGroundVars) :-
6616 term_variables(Arg,Vars),
6617 add_var_ground_variables(Vars,GroundVars,GroundVars1)
6619 GroundVars = GroundVars1
6621 add_arg_ground_variables(Args,Modes,GroundVars1,NGroundVars).
6623 add_var_ground_variables([],GroundVars,GroundVars).
6624 add_var_ground_variables([Var|Vars],GroundVars,NGroundVars) :-
6625 ( memberchk_eq(Var,GroundVars) ->
6626 GroundVars1 = GroundVars
6628 GroundVars1 = [Var|GroundVars]
6630 add_var_ground_variables(Vars,GroundVars1,NGroundVars).
6631 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6632 %% is_ground(+GroundVars,+Term) is semidet.
6634 % Determine whether =Term= is always ground.
6635 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6636 is_ground(GroundVars,Term) :-
6641 maplist(is_ground(GroundVars),Args)
6643 memberchk_eq(Term,GroundVars)
6646 %% check_ground(+GroundVars,+Term,-Goal) is det.
6648 % Return runtime check to see whether =Term= is ground.
6649 check_ground(GroundVars,Term,Goal) :-
6650 term_variables(Term,Variables),
6651 check_ground_variables(Variables,GroundVars,Goal).
6653 check_ground_variables([],_,true).
6654 check_ground_variables([Var|Vars],GroundVars,Goal) :-
6655 ( memberchk_eq(Var,GroundVars) ->
6656 check_ground_variables(Vars,GroundVars,Goal)
6658 Goal = (ground(Var), RGoal),
6659 check_ground_variables(Vars,GroundVars,RGoal)
6662 rest_heads_retrieval_and_matching(Heads,IDs,ActiveHead,GoalList,Susps,VarDict,NVarDict,PrevHs,PrevSusps,AttrDict) :-
6663 rest_heads_retrieval_and_matching(Heads,IDs,ActiveHead,GoalList,Susps,VarDict,NVarDict,PrevHs,PrevSusps,AttrDict,[],_).
6665 rest_heads_retrieval_and_matching(Heads,IDs,ActiveHead,GoalList,Susps,VarDict,NVarDict,PrevHs,PrevSusps,AttrDict,GroundVars,NGroundVars) :-
6667 rest_heads_retrieval_and_matching_n(Heads,IDs,PrevHs,PrevSusps,ActiveHead,GoalList,Susps,VarDict,NVarDict,AttrDict,GroundVars,NGroundVars)
6672 GroundVars = NGroundVars
6675 rest_heads_retrieval_and_matching_n([],_,_,_,_,[],[],VarDict,VarDict,_AttrDict,GroundVars,GroundVars).
6676 rest_heads_retrieval_and_matching_n([H|Hs],[ID|IDs],PrevHs,PrevSusps,ActiveHead,
6677 [Goal|Goals],[Susp|Susps],VarDict,NVarDict,_AttrDict,GroundVars,NGroundVars) :-
6679 head_info(H,A,Vars,_,_,Pairs),
6680 get_store_type(F/A,StoreType),
6681 ( StoreType == default ->
6682 passive_head_via(H,[ActiveHead|PrevHs],VarDict,ViaGoal,VarSusps),
6683 delay_phase_end(validate_store_type_assumptions,
6684 ( static_suspension_term(F/A,Suspension),
6685 get_static_suspension_term_field(arguments,F/A,Suspension,Vars),
6686 get_static_suspension_field(F/A,Suspension,state,active,GetState)
6689 % create_get_mutable_ref(active,State,GetMutable),
6690 get_constraint_mode(F/A,Mode),
6691 head_arg_matches(Pairs,Mode,VarDict,MatchingGoal,VarDict1,GroundVars,GroundVars1),
6693 sbag_member_call(Susp,VarSusps,Sbag),
6694 ExistentialLookup = (
6697 Susp = Suspension, % not inlined
6701 delay_phase_end(validate_store_type_assumptions,
6702 ( static_suspension_term(F/A,Suspension),
6703 get_static_suspension_term_field(arguments,F/A,Suspension,Vars)
6706 existential_lookup(StoreType,H,[ActiveHead|PrevHs],VarDict,GroundVars,Suspension,ExistentialLookup,Susp,Pairs,NPairs),
6707 get_constraint_mode(F/A,Mode),
6708 filter_mode(NPairs,Pairs,Mode,NMode),
6709 head_arg_matches(NPairs,NMode,VarDict,MatchingGoal,VarDict1,GroundVars,GroundVars1)
6711 different_from_other_susps(H,Susp,PrevHs,PrevSusps,DiffSuspGoals),
6712 append(NPairs,VarDict1,DA_), % order important here
6713 translate(GroundVars1,DA_,GroundVarsA),
6714 translate(GroundVars1,VarDict1,GroundVarsB),
6715 inline_matching_goal(MatchingGoal,MatchingGoal2,GroundVarsA,GroundVarsB),
6722 rest_heads_retrieval_and_matching_n(Hs,IDs,[H|PrevHs],[Susp|PrevSusps],ActiveHead,Goals,Susps,VarDict1,NVarDict,_NewAttrDict,GroundVars1,NGroundVars).
6724 inline_matching_goal(A==B,true,GVA,GVB) :-
6725 memberchk_eq(A,GVA),
6726 memberchk_eq(B,GVB),
6729 % inline_matching_goal(A=B,true,_,_) :- A=B, !.
6730 inline_matching_goal((A,B),(A2,B2),GVA,GVB) :- !,
6731 inline_matching_goal(A,A2,GVA,GVB),
6732 inline_matching_goal(B,B2,GVA,GVB).
6733 inline_matching_goal(X,X,_,_).
6736 filter_mode([],_,_,[]).
6737 filter_mode([Arg-Var|Rest],[_-V|R],[M|Ms],Modes) :-
6740 filter_mode(Rest,R,Ms,MT)
6742 filter_mode([Arg-Var|Rest],R,Ms,Modes)
6745 check_unique_keys([],_).
6746 check_unique_keys([V|Vs],Dict) :-
6747 lookup_eq(Dict,V,_),
6748 check_unique_keys(Vs,Dict).
6750 % Generates tests to ensure the found constraint differs from previously found constraints
6751 % TODO: detect more cases where constraints need be different
6752 different_from_other_susps(Head,Susp,Heads,Susps,DiffSuspGoals) :-
6753 different_from_other_susps_(Heads,Susps,Head,Susp,DiffSuspGoalList),
6754 list2conj(DiffSuspGoalList,DiffSuspGoals).
6756 different_from_other_susps_(_,[],_,_,[]) :- !.
6757 different_from_other_susps_([PreHead|Heads],[PreSusp|Susps],Head,Susp,List) :-
6758 ( functor(Head,F,A), functor(PreHead,F,A),
6759 copy_term_nat(PreHead-Head,PreHeadCopy-HeadCopy),
6760 \+ \+ PreHeadCopy = HeadCopy ->
6762 List = [Susp \== PreSusp | Tail]
6766 different_from_other_susps_(Heads,Susps,Head,Susp,Tail).
6768 % passive_head_via(in,in,in,in,out,out,out) :-
6769 passive_head_via(Head,PrevHeads,VarDict,Goal,AllSusps) :-
6771 get_constraint_index(F/A,Pos),
6772 common_variables(Head,PrevHeads,CommonVars),
6773 global_list_store_name(F/A,Name),
6774 GlobalGoal = nb_getval(Name,AllSusps),
6775 get_constraint_mode(F/A,ArgModes),
6778 ; member(CommonVar,CommonVars), nth(I,ArgModes,(-)), arg(I,Head,Arg), Arg == CommonVar ->
6779 translate([CommonVar],VarDict,[Var]),
6780 gen_get_mod_constraints(F/A,Var,AttrGoal,AllSusps),
6783 translate(CommonVars,VarDict,Vars),
6784 add_heads_types(PrevHeads,[],TypeDict),
6785 my_term_copy(TypeDict,VarDict,TypeDictCopy),
6786 gen_get_mod_constraints(F/A,Vars,TypeDictCopy,ViaGoal,AttrGoal,AllSusps),
6795 common_variables(T,Ts,Vs) :-
6796 term_variables(T,V1),
6797 term_variables(Ts,V2),
6798 intersect_eq(V1,V2,Vs).
6800 gen_get_mod_constraints(FA,Vars,TypeDict,ViaGoal,AttrGoal,AllSusps) :-
6801 get_target_module(Mod),
6803 lookup_eq(TypeDict,A,Type),
6804 ( atomic_type(Type) ->
6808 ViaGoal = 'chr newvia_1'(A,V)
6811 ViaGoal = 'chr newvia_2'(A,B,V)
6813 ViaGoal = 'chr newvia'(Vars,V)
6816 ( get_attr(V,Mod,TSusps),
6817 TSuspsEqSusps % TSusps = Susps
6819 get_max_constraint_index(N),
6821 TSuspsEqSusps = true, % TSusps = Susps
6824 get_constraint_index(FA,Pos),
6825 get_suspensions(N,Pos,TSusps,TSuspsEqSusps,AllSusps)
6827 gen_get_mod_constraints(FA,Var,AttrGoal,AllSusps) :-
6828 get_target_module(Mod),
6830 ( get_attr(Var,Mod,TSusps),
6831 TSuspsEqSusps % TSusps = Susps
6833 get_max_constraint_index(N),
6835 TSuspsEqSusps = true, % TSusps = Susps
6838 get_constraint_index(FA,Pos),
6839 get_suspensions(N,Pos,TSusps,TSuspsEqSusps,AllSusps)
6842 guard_body_copies(Rule,VarDict,GuardCopy,BodyCopy) :-
6843 guard_body_copies2(Rule,VarDict,GuardCopyList,BodyCopy),
6844 list2conj(GuardCopyList,GuardCopy).
6846 guard_body_copies2(Rule,VarDict,GuardCopyList,BodyCopy) :-
6847 Rule = rule(H,_,Guard,Body),
6848 conj2list(Guard,GuardList),
6849 split_off_simple_guard(GuardList,VarDict,GuardPrefix,RestGuardList),
6850 my_term_copy(GuardPrefix-RestGuardList,VarDict,VarDict2,GuardPrefixCopy-RestGuardListCopyCore),
6852 append(GuardPrefixCopy,[RestGuardCopy],GuardCopyList),
6853 term_variables(RestGuardList,GuardVars),
6854 term_variables(RestGuardListCopyCore,GuardCopyVars),
6855 % variables that are declared to be ground don't need to be locked
6856 ground_vars(H,GroundVars),
6857 list_difference_eq(GuardVars,GroundVars,GuardVars_),
6858 ( chr_pp_flag(guard_locks,on),
6859 bagof(('chr lock'(Y)) - ('chr unlock'(Y)),
6860 X ^ (lists:member(X,GuardVars), % X is a variable appearing in the original guard
6861 pairlist:lookup_eq(VarDict,X,Y), % translate X into new variable
6862 memberchk_eq(Y,GuardCopyVars) % redundant check? or multiple entries for X possible?
6865 once(pairup(Locks,Unlocks,LocksUnlocks))
6870 list2conj(Locks,LockPhase),
6871 list2conj(Unlocks,UnlockPhase),
6872 list2conj(RestGuardListCopyCore,RestGuardCopyCore),
6873 RestGuardCopy = (LockPhase,(RestGuardCopyCore,UnlockPhase)),
6874 my_term_copy(Body,VarDict2,BodyCopy).
6877 split_off_simple_guard([],_,[],[]).
6878 split_off_simple_guard([G|Gs],VarDict,S,C) :-
6879 ( simple_guard(G,VarDict) ->
6881 split_off_simple_guard(Gs,VarDict,Ss,C)
6887 % simple guard: cheap and benign (does not bind variables)
6888 simple_guard(G,VarDict) :-
6890 \+ (( member(V,Vars),
6891 lookup_eq(VarDict,V,_)
6894 active_constraint_detachment(Id,Susp,Head,VarDict,SuspDetachment) :-
6900 Id == [0], chr_pp_flag(store_in_guards, off)
6902 ( get_allocation_occurrence(C,AO),
6903 get_max_occurrence(C,MO),
6906 only_ground_indexed_arguments(C), chr_pp_flag(late_allocation,on) ->
6907 SuspDetachment = true
6909 gen_uncond_susp_detachment(Head,Susp,active,VarDict,UnCondSuspDetachment),
6910 ( chr_pp_flag(late_allocation,on) ->
6915 UnCondSuspDetachment
6918 SuspDetachment = UnCondSuspDetachment
6922 SuspDetachment = true
6925 partner_constraint_detachments([],[],_,true).
6926 partner_constraint_detachments([Susp|Susps],[Head|Heads],VarDict,(SuspDetachment,SuspsDetachments)) :-
6927 gen_uncond_susp_detachment(Head,Susp,partner,VarDict,SuspDetachment),
6928 partner_constraint_detachments(Susps,Heads,VarDict,SuspsDetachments).
6930 gen_uncond_susp_detachment(Head,Susp,Role,VarDict,SuspDetachment) :-
6934 SuspDetachment = ( DebugEvent, RemoveInternalGoal),
6935 ( chr_pp_flag(debugable,on) ->
6936 DebugEvent = 'chr debug_event'(remove(Susp))
6940 remove_constraint_goal(C,Susp,Vars,true,(DeleteCall,Detach),Role,RemoveInternalGoal),
6941 delete_constraint_goal(Head,Susp,VarDict,DeleteCall),
6942 ( \+ only_ground_indexed_arguments(C), \+ get_store_type(C,var_assoc_store(_,_)) ->
6943 detach_constraint_atom(C,Vars,Susp,Detach)
6948 SuspDetachment = true
6951 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6953 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6955 %% / ___|(_)_ __ ___ _ __ __ _ __ _ __ _| |_(_) ___ _ __ / |
6956 %% \___ \| | '_ ` _ \| '_ \ / _` |/ _` |/ _` | __| |/ _ \| '_ \ | |
6957 %% ___) | | | | | | | |_) | (_| | (_| | (_| | |_| | (_) | | | | | |
6958 %% |____/|_|_| |_| |_| .__/ \__,_|\__, |\__,_|\__|_|\___/|_| |_| |_|
6961 simpagation_head1_code(Head,ID,RestHeads,OtherIDs,PragmaRule,F/A,O,Id,L,T) :-
6962 PragmaRule = pragma(Rule,ids(_,Heads2IDs),Pragmas,_Name,RuleNb),
6963 Rule = rule(_Heads,Heads2,Guard,Body),
6965 head_info(Head,A,Vars,Susp,HeadVars,HeadPairs),
6966 get_constraint_mode(F/A,Mode),
6967 head_arg_matches(HeadPairs,Mode,[],FirstMatching,VarDict1,[],GroundVars),
6969 build_head(F,A,Id,HeadVars,ClauseHead),
6971 append(RestHeads,Heads2,Heads),
6972 append(OtherIDs,Heads2IDs,IDs),
6973 reorder_heads(RuleNb,Head,Heads,IDs,NHeads,NIDs),
6975 guard_splitting(Rule,GuardList0),
6976 ( is_stored_in_guard(F/A, RuleNb) ->
6977 GuardList = [Hole1|GuardList0]
6979 GuardList = GuardList0
6981 guard_via_reschedule_new(NHeads,GuardList,Head,GuardCopyList,GetRestHeads,RescheduledTest),
6983 rest_heads_retrieval_and_matching(NHeads,NIDs,Head,GetRestHeads,Susps,VarDict1,VarDict,[],[],[],GroundVars,_),
6984 split_by_ids(NIDs,Susps,OtherIDs,Susps1,Susps1IDs,Susps2,Susps2IDs),
6986 guard_body_copies3(Rule,GuardList,VarDict,GuardCopyList,BodyCopy),
6988 ( is_stored_in_guard(F/A, RuleNb) ->
6989 gen_uncond_attach_goal(F/A,Susp,Vars,Attachment,_),
6990 GuardCopyList = [Hole1Copy|_],
6991 Hole1Copy = Attachment
6996 sort_by_key(Susps1,Susps1IDs,SortedSusps1),
6997 partner_constraint_detachments(SortedSusps1,RestHeads,VarDict,SuspsDetachments),
6998 active_constraint_detachment(Id,Susp,Head,VarDict,SuspDetachment),
7000 ( chr_pp_flag(debugable,on) ->
7001 my_term_copy(Guard - Body, VarDict, DebugGuard - DebugBody),
7002 sort_by_key([Susp|Susps1],[ID|Susps1IDs],RemovedSusps),
7003 sort_by_key(Susps2,Susps2IDs,KeptSusps),
7004 DebugTry = 'chr debug_event'( try(RemovedSusps,KeptSusps,DebugGuard,DebugBody)),
7005 DebugApply = 'chr debug_event'(apply(RemovedSusps,KeptSusps,DebugGuard,DebugBody)),
7006 instrument_goal((!),DebugTry,DebugApply,Cut)
7011 Clause = ( ClauseHead :-
7019 add_location(Clause,RuleNb,LocatedClause),
7020 L = [LocatedClause | T].
7022 split_by_ids([],[],_,[],[]).
7023 split_by_ids([I|Is],[S|Ss],I1s,S1s,S2s) :-
7024 ( memberchk_eq(I,I1s) ->
7031 split_by_ids(Is,Ss,I1s,R1s,R2s).
7033 split_by_ids([],[],_,[],[],[],[]).
7034 split_by_ids([I|Is],[S|Ss],I1s,S1s,SI1s,S2s,SI2s) :-
7035 ( memberchk_eq(I,I1s) ->
7046 split_by_ids(Is,Ss,I1s,R1s,RSI1s,R2s,RSI2s).
7047 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7050 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7052 %% / ___|(_)_ __ ___ _ __ __ _ __ _ __ _| |_(_) ___ _ __ |___ \
7053 %% \___ \| | '_ ` _ \| '_ \ / _` |/ _` |/ _` | __| |/ _ \| '_ \ __) |
7054 %% ___) | | | | | | | |_) | (_| | (_| | (_| | |_| | (_) | | | | / __/
7055 %% |____/|_|_| |_| |_| .__/ \__,_|\__, |\__,_|\__|_|\___/|_| |_| |_____|
7058 %% Genereate prelude + worker predicate
7059 %% prelude calls worker
7060 %% worker iterates over one type of removed constraints
7061 simpagation_head2_code(Head2,ID,RestHeads2,RestIDs,PragmaRule,FA,O,Id,L,T) :-
7062 PragmaRule = pragma(Rule,ids(IDs1,IDs2),Pragmas,_Name,RuleNb),
7063 Rule = rule(Heads1,_,Guard,Body),
7064 append(Heads1,RestHeads2,Heads),
7065 append(IDs1,RestIDs,IDs),
7066 reorder_heads(RuleNb,Head2,Heads,IDs,[NHead|NHeads],[NID|NIDs]),
7067 simpagation_head2_prelude(Head2,NHead,[NHeads,Guard,Body],FA,O,Id,L,L1),
7069 ( memberchk_eq(NID,IDs2) ->
7070 simpagation_universal_searches(NHeads,NIDs,IDs2,[NHead,Head2],Rule,FA,NextHeads,PreHeads,NextIDs,Id1,Id2,L1,L2)
7072 L1 = L2, Id1 = Id2,NextHeads = NHeads, PreHeads = [NHead,Head2], NextIDs = NIDs
7074 universal_search_iterator_end(PreHeads,NextHeads,Rule,FA,Id2,L2,L3),
7075 simpagation_head2_worker(PreHeads,NextHeads,NextIDs,ID,PragmaRule,FA,O,Id2,L3,T).
7077 simpagation_universal_searches([],[],_,PreHeads,_,_,[],PreHeads,[],Id,Id,L,L).
7078 simpagation_universal_searches(Heads,[ID|IDs],IDs2,PreHeads,Rule,C,OutHeads,OutPreHeads,OutIDs,Id,NId,L,T) :-
7079 Heads = [Head|RHeads],
7081 universal_search_iterator_end(PreHeads,Heads,Rule,C,Id,L,L0),
7082 universal_search_iterator(Heads,PreHeads,Rule,C,Id,L0,L1),
7083 ( memberchk_eq(ID,IDs2) ->
7084 simpagation_universal_searches(RHeads,IDs,IDs2,[Head|PreHeads],Rule,C,OutHeads,OutPreHeads,OutIDs,Id1,NId,L1,T)
7086 NId = Id1, L1 = T, OutHeads = RHeads, OutPreHeads = [Head|PreHeads], IDs = OutIDs
7089 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7090 simpagation_head2_prelude(Head,Head1,Rest,F/A,O,Id1,L,T) :-
7091 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs),
7092 build_head(F,A,Id1,VarsSusp,ClauseHead),
7093 get_constraint_mode(F/A,Mode),
7094 head_arg_matches(HeadPairs,Mode,[],FirstMatching,VarDict,[],GroundVars),
7096 lookup_passive_head(Head1,[Head],VarDict,GroundVars,ModConstraintsGoal,AllSusps),
7098 gen_occ_allocation(F/A,O,Vars,Susp,ConstraintAllocationGoal),
7100 extend_id(Id1,DelegateId),
7101 extra_active_delegate_variables(Head,[Head1|Rest],VarDict,ExtraVars),
7102 append([AllSusps|VarsSusp],ExtraVars,DelegateCallVars),
7103 build_head(F,A,DelegateId,DelegateCallVars,Delegate),
7110 ConstraintAllocationGoal,
7113 add_dummy_location(PreludeClause,LocatedPreludeClause),
7114 L = [LocatedPreludeClause|T].
7116 extra_active_delegate_variables(Term,Terms,VarDict,Vars) :-
7118 delegate_variables(Term,Terms,VarDict,Args,Vars).
7120 passive_delegate_variables(Term,PrevTerms,NextTerms,VarDict,Vars) :-
7121 term_variables(PrevTerms,PrevVars),
7122 delegate_variables(Term,NextTerms,VarDict,PrevVars,Vars).
7124 delegate_variables(Term,Terms,VarDict,PrevVars,Vars) :-
7125 term_variables(Term,V1),
7126 term_variables(Terms,V2),
7127 intersect_eq(V1,V2,V3),
7128 list_difference_eq(V3,PrevVars,V4),
7129 translate(V4,VarDict,Vars).
7132 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7133 simpagation_head2_worker([CurrentHead|PreHeads],NextHeads,NextIDs,ID,PragmaRule,F/A,O,Id,L,T) :-
7134 PragmaRule = pragma(Rule,ids(IDs1,_),Pragmas,_,RuleNb),
7135 Rule = rule(_,_,Guard,Body),
7136 get_prop_inner_loop_vars(PreHeads,[CurrentHead,NextHeads,Guard,Body],PreVarsAndSusps,VarDict,Susp,Vars,PreSusps),
7139 gen_var(OtherSusps),
7141 functor(CurrentHead,OtherF,OtherA),
7142 gen_vars(OtherA,OtherVars),
7143 head_info(CurrentHead,OtherA,OtherVars,OtherSusp,_VarsSusp,HeadPairs),
7144 get_constraint_mode(OtherF/OtherA,Mode),
7145 head_arg_matches(HeadPairs,Mode,VarDict,FirstMatching,VarDict1,[],GroundVars),
7147 delay_phase_end(validate_store_type_assumptions,
7148 ( static_suspension_term(OtherF/OtherA,OtherSuspension),
7149 get_static_suspension_field(OtherF/OtherA,OtherSuspension,state,active,GetState),
7150 get_static_suspension_term_field(arguments,OtherF/OtherA,OtherSuspension,OtherVars)
7153 % create_get_mutable_ref(active,State,GetMutable),
7154 different_from_other_susps(CurrentHead,OtherSusp,PreHeads,PreSusps,DiffSuspGoals),
7156 OtherSusp = OtherSuspension,
7162 ClauseVars = [[OtherSusp|OtherSusps]|PreVarsAndSusps],
7163 build_head(F,A,Id,ClauseVars,ClauseHead),
7165 guard_splitting(Rule,GuardList0),
7166 ( is_stored_in_guard(F/A, RuleNb) ->
7167 GuardList = [Hole1|GuardList0]
7169 GuardList = GuardList0
7171 guard_via_reschedule_new(NextHeads,GuardList,[CurrentHead|PreHeads],GuardCopyList,RestSuspsRetrieval,RescheduledTest),
7173 rest_heads_retrieval_and_matching(NextHeads,NextIDs,[CurrentHead|PreHeads],RestSuspsRetrieval,Susps,VarDict1,VarDict2,[CurrentHead|PreHeads],[OtherSusp|PreSusps],[]),
7174 split_by_ids(NextIDs,Susps,IDs1,Susps1,Susps2),
7175 split_by_ids(NextIDs,NextHeads,IDs1,RestHeads1,_),
7177 partner_constraint_detachments([OtherSusp | Susps1],[CurrentHead|RestHeads1],VarDict2,Susps1Detachments),
7179 RecursiveVars = [OtherSusps|PreVarsAndSusps],
7180 build_head(F,A,Id,RecursiveVars,RecursiveCall),
7181 RecursiveVars2 = [[]|PreVarsAndSusps],
7182 build_head(F,A,Id,RecursiveVars2,RecursiveCall2),
7184 guard_body_copies3(Rule,GuardList,VarDict2,GuardCopyList,BodyCopy),
7185 ( is_stored_in_guard(F/A, RuleNb) ->
7186 GuardCopyList = [GuardAttachment|_] % once( ) ??
7191 ( is_observed(F/A,O) ->
7192 gen_uncond_attach_goal(F/A,Susp,Vars,Attachment,Generation),
7193 gen_state_cond_call(Susp,F/A,RecursiveCall,Generation,ConditionalRecursiveCall),
7194 gen_state_cond_call(Susp,F/A,RecursiveCall2,Generation,ConditionalRecursiveCall2)
7197 ConditionalRecursiveCall = RecursiveCall,
7198 ConditionalRecursiveCall2 = RecursiveCall2
7201 ( chr_pp_flag(debugable,on) ->
7202 my_term_copy(Guard - Body, VarDict, DebugGuard - DebugBody),
7203 DebugTry = 'chr debug_event'( try([OtherSusp|Susps1],[Susp|Susps2],DebugGuard,DebugBody)),
7204 DebugApply = 'chr debug_event'(apply([OtherSusp|Susps1],[Susp|Susps2],DebugGuard,DebugBody))
7210 ( is_stored_in_guard(F/A, RuleNb) ->
7211 GuardAttachment = Attachment,
7212 BodyAttachment = true
7214 GuardAttachment = true,
7215 BodyAttachment = Attachment % will be true if not observed at all
7218 ( member(unique(ID1,UniqueKeys), Pragmas),
7219 check_unique_keys(UniqueKeys,VarDict) ->
7222 ( CurrentSuspTest ->
7229 ConditionalRecursiveCall2
7247 ConditionalRecursiveCall
7253 add_location(Clause,RuleNb,LocatedClause),
7254 L = [LocatedClause | T].
7256 gen_state_cond_call(Susp,FA,Call,Generation,ConditionalCall) :-
7257 ( may_trigger(FA) ->
7258 does_use_field(FA,generation),
7259 delay_phase_end(validate_store_type_assumptions,
7260 ( static_suspension_term(FA,Suspension),
7261 get_update_static_suspension_field(FA,Susp,Suspension,state,active,inactive,GetState,UpdateState),
7262 get_static_suspension_field(FA,Suspension,generation,Generation,GetGeneration),
7263 get_static_suspension_term_field(arguments,FA,Suspension,Args)
7267 delay_phase_end(validate_store_type_assumptions,
7268 ( static_suspension_term(FA,Suspension),
7269 get_update_static_suspension_field(FA,Susp,Suspension,state,active,inactive,GetState,UpdateState),
7270 get_static_suspension_term_field(arguments,FA,Suspension,Args)
7273 GetGeneration = true
7276 ( Susp = Suspension,
7285 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7288 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7290 %% | _ \ _ __ ___ _ __ __ _ __ _ __ _| |_(_) ___ _ __
7291 %% | |_) | '__/ _ \| '_ \ / _` |/ _` |/ _` | __| |/ _ \| '_ \
7292 %% | __/| | | (_) | |_) | (_| | (_| | (_| | |_| | (_) | | | |
7293 %% |_| |_| \___/| .__/ \__,_|\__, |\__,_|\__|_|\___/|_| |_|
7296 propagation_code(Head,ID,RestHeads,RestIDs,Rule,RuleNb,FA,O,Id,L,T) :-
7297 ( RestHeads == [] ->
7298 propagation_single_headed(Head,ID,Rule,RuleNb,FA,O,Id,L,T)
7300 propagation_multi_headed(Head,RestHeads,RestIDs,Rule,RuleNb,FA,O,Id,L,T)
7302 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7303 %% Single headed propagation
7304 %% everything in a single clause
7305 propagation_single_headed(Head,ID,Rule,RuleNb,F/A,O,Id,ProgramList,ProgramTail) :-
7306 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs),
7307 build_head(F,A,Id,VarsSusp,ClauseHead),
7310 build_head(F,A,NextId,VarsSusp,NextHead),
7312 get_constraint_mode(F/A,Mode),
7313 head_arg_matches(HeadPairs,Mode,[],HeadMatching,VarDict,[],GroundVars),
7314 guard_body_copies(Rule,VarDict,GuardCopy,BodyCopy),
7316 % - recursive call -
7317 RecursiveCall = NextHead,
7319 ( unconditional_occurrence(F/A,O), chr_pp_flag(late_allocation,on) ->
7325 Rule = rule(_,_,Guard,Body),
7326 ( chr_pp_flag(debugable,on) ->
7327 my_term_copy(Guard - Body, VarDict, DebugGuard - DebugBody),
7328 DebugTry = 'chr debug_event'( try([],[Susp],DebugGuard,DebugBody)),
7329 DebugApply = 'chr debug_event'(apply([],[Susp],DebugGuard,DebugBody)),
7330 instrument_goal(ActualCut,DebugTry,DebugApply,Cut)
7334 ( may_trigger(F/A), \+ has_no_history(RuleNb)->
7335 use_auxiliary_predicate(novel_production),
7336 use_auxiliary_predicate(extend_history),
7337 does_use_history(F/A,O),
7338 gen_occ_allocation(F/A,O,Vars,Susp,Allocation),
7340 ( named_history(RuleNb,HistoryName,HistoryIDs) ->
7341 ( HistoryIDs == [] ->
7342 empty_named_history_novel_production(HistoryName,NovelProduction),
7343 empty_named_history_extend_history(HistoryName,ExtendHistory)
7351 ( var(NovelProduction) ->
7352 NovelProduction = '$novel_production'(Susp,Tuple),
7353 ExtendHistory = '$extend_history'(Susp,Tuple)
7358 ( is_observed(F/A,O) ->
7359 gen_uncond_attach_goal(F/A,Susp,Vars,Attachment,Generation),
7360 gen_state_cond_call(Susp,F/A,RecursiveCall,Generation,ConditionalRecursiveCall)
7363 ConditionalRecursiveCall = RecursiveCall
7367 NovelProduction = true,
7368 ExtendHistory = true,
7370 ( is_observed(F/A,O) ->
7371 get_allocation_occurrence(F/A,AllocO),
7373 gen_insert_constraint_internal_goal(F/A,Attachment,VarsSusp,Vars,Susp),
7375 ; % more room for improvement?
7376 Attachment = (Attachment1, Attachment2),
7377 gen_occ_allocation(F/A,O,Vars,Susp,Attachment1),
7378 gen_uncond_attach_goal(F/A,Susp,Vars,Attachment2,Generation)
7380 gen_state_cond_call(Susp,F/A,RecursiveCall,Generation,ConditionalRecursiveCall)
7382 gen_occ_allocation(F/A,O,Vars,Susp,Attachment),
7383 ConditionalRecursiveCall = RecursiveCall
7387 ( is_stored_in_guard(F/A, RuleNb) ->
7388 GuardAttachment = Attachment,
7389 BodyAttachment = true
7391 GuardAttachment = true,
7392 BodyAttachment = Attachment % will be true if not observed at all
7406 ConditionalRecursiveCall
7408 add_location(Clause,RuleNb,LocatedClause),
7409 ProgramList = [LocatedClause | ProgramTail].
7411 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7412 %% multi headed propagation
7413 %% prelude + predicates to accumulate the necessary combinations of suspended
7414 %% constraints + predicate to execute the body
7415 propagation_multi_headed(Head,RestHeads,RestIDs,Rule,RuleNb,FA,O,Id,L,T) :-
7416 RestHeads = [First|Rest],
7417 propagation_prelude(Head,RestHeads,Rule,FA,O,Id,L,L1),
7418 extend_id(Id,ExtendedId),
7419 propagation_nested_code(Rest,[First,Head],RestIDs,Rule,RuleNb,FA,O,ExtendedId,L1,T).
7421 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7422 propagation_prelude(Head,[First|Rest],Rule,F/A,O,Id,L,T) :-
7423 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs),
7424 build_head(F,A,Id,VarsSusp,PreludeHead),
7425 get_constraint_mode(F/A,Mode),
7426 head_arg_matches(HeadPairs,Mode,[],FirstMatching,VarDict,[],GroundVars),
7427 Rule = rule(_,_,Guard,Body),
7428 extra_active_delegate_variables(Head,[First,Rest,Guard,Body],VarDict,ExtraVars),
7430 lookup_passive_head(First,[Head],VarDict,GroundVars,FirstSuspGoal,Susps),
7432 gen_occ_allocation(F/A,O,Vars,Susp,CondAllocation),
7434 extend_id(Id,NestedId),
7435 append([Susps|VarsSusp],ExtraVars,NestedVars),
7436 build_head(F,A,NestedId,NestedVars,NestedHead),
7437 NestedCall = NestedHead,
7447 add_dummy_location(Prelude,LocatedPrelude),
7448 L = [LocatedPrelude|T].
7450 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7451 propagation_nested_code([],[CurrentHead|PreHeads],RestIDs,Rule,RuleNb,FA,O,Id,L,T) :-
7452 universal_search_iterator_end([CurrentHead|PreHeads],[],Rule,FA,Id,L,L1),
7453 propagation_body(CurrentHead,PreHeads,RestIDs,Rule,RuleNb,FA,O,Id,L1,T).
7455 propagation_nested_code([Head|RestHeads],PreHeads,RestIDs,Rule,RuleNb,FA,O,Id,L,T) :-
7456 universal_search_iterator_end(PreHeads,[Head|RestHeads],Rule,FA,Id,L,L1),
7457 universal_search_iterator([Head|RestHeads],PreHeads,Rule,FA,Id,L1,L2),
7459 propagation_nested_code(RestHeads,[Head|PreHeads],RestIDs,Rule,RuleNb,FA,O,IncId,L2,T).
7461 %check_fd_lookup_condition(_,_,_,_) :- fail.
7462 check_fd_lookup_condition(F,A,_,_) :-
7463 get_store_type(F/A,global_singleton), !.
7464 check_fd_lookup_condition(F,A,CurrentHead,PreHeads) :-
7465 \+ may_trigger(F/A),
7466 get_functional_dependency(F/A,1,P,K),
7467 copy_term(P-K,CurrentHead-Key),
7468 term_variables(PreHeads,PreVars),
7469 intersect_eq(Key,PreVars,Key),!.
7471 propagation_body(CurrentHead,PreHeads,RestIDs,Rule,RuleNb,F/A,O,Id,L,T) :-
7472 Rule = rule(_,H2,Guard,Body),
7473 gen_var_susp_list_for_b(PreHeads,[CurrentHead,Guard,Body],VarDict1,PreVarsAndSuspsList,FirstVarsSusp,AllSusps,PrevIterators),
7474 flatten(PreVarsAndSuspsList,PreVarsAndSusps),
7475 init(AllSusps,RestSusps),
7476 last(AllSusps,Susp),
7478 gen_var(OtherSusps),
7479 functor(CurrentHead,OtherF,OtherA),
7480 gen_vars(OtherA,OtherVars),
7481 delay_phase_end(validate_store_type_assumptions,
7482 ( static_suspension_term(OtherF/OtherA,Suspension),
7483 get_static_suspension_field(OtherF/OtherA,Suspension,state,active,GetState),
7484 get_static_suspension_term_field(arguments,OtherF/OtherA,Suspension,OtherVars)
7487 % create_get_mutable_ref(active,State,GetMutable),
7489 OtherSusp = Suspension,
7492 ClauseVars = [[OtherSusp|OtherSusps]|PreVarsAndSusps],
7493 build_head(F,A,Id,ClauseVars,ClauseHead),
7494 ( check_fd_lookup_condition(OtherF,OtherA,CurrentHead,PreHeads) -> % iterator (OtherSusps) is empty at runtime
7495 universal_search_iterator_failure_vars(PreHeads,Id,PreVarsAndSuspsList,FirstVarsSusp,PrevIterators,PreVarsAndSusps1,PrevId),
7496 RecursiveVars = PreVarsAndSusps1
7498 RecursiveVars = [OtherSusps|PreVarsAndSusps],
7501 build_head(F,A,PrevId,RecursiveVars,RecursiveHead),
7502 RecursiveCall = RecursiveHead,
7503 CurrentHead =.. [_|OtherArgs],
7504 pairup(OtherArgs,OtherVars,OtherPairs),
7505 get_constraint_mode(OtherF/OtherA,Mode),
7506 head_arg_matches(OtherPairs,Mode,VarDict1,Matching,VarDict),
7508 different_from_other_susps(CurrentHead,OtherSusp,PreHeads,RestSusps,DiffSuspGoals),
7509 guard_body_copies(Rule,VarDict,GuardCopy,BodyCopy),
7510 get_occurrence(F/A,O,_,ID),
7512 ( is_observed(F/A,O) ->
7513 init(FirstVarsSusp,FirstVars),
7514 gen_uncond_attach_goal(F/A,Susp,FirstVars,Attachment,Generation),
7515 gen_state_cond_call(Susp,F/A,RecursiveCall,Generation,ConditionalRecursiveCall)
7518 ConditionalRecursiveCall = RecursiveCall
7520 ( (is_least_occurrence(RuleNb) ; has_no_history(RuleNb)) ->
7521 NovelProduction = true,
7522 ExtendHistory = true
7523 ; \+ may_trigger(F/A), forall(member(SomeID,RestIDs),(chr_translate:is_passive(RuleNb,SomeID))) ->
7524 NovelProduction = true,
7525 ExtendHistory = true
7527 get_occurrence(F/A,O,_,ID),
7528 use_auxiliary_predicate(novel_production),
7529 use_auxiliary_predicate(extend_history),
7530 does_use_history(F/A,O),
7531 ( named_history(RuleNb,HistoryName,HistoryIDs) ->
7532 ( HistoryIDs == [] ->
7533 empty_named_history_novel_production(HistoryName,NovelProduction),
7534 empty_named_history_extend_history(HistoryName,ExtendHistory)
7536 reverse([OtherSusp|RestSusps],NamedSusps),
7537 named_history_susps(HistoryIDs,[ID|RestIDs],[Susp|NamedSusps],HistorySusps),
7538 HistorySusps = [HistorySusp|_],
7540 ( length(HistoryIDs, 1) ->
7541 ExtendHistory = '$extend_history'(HistorySusp,HistoryName),
7542 NovelProduction = '$novel_production'(HistorySusp,HistoryName)
7544 findall(ConstraintSymbol,(member(SomeID,HistoryIDs),get_occurrence_from_id(ConstraintSymbol,_,RuleNb,SomeID)),ConstraintSymbols),
7545 Tuple =.. [t,HistoryName|HistorySusps]
7550 findall(Functor/Arity,(member(H,H2),functor(H,Functor,Arity)),ConstraintSymbols),
7551 sort([ID|RestIDs],HistoryIDs),
7552 history_susps(RestIDs,[OtherSusp|RestSusps],Susp,ID,HistorySusps),
7553 Tuple =.. [t,RuleNb|HistorySusps]
7556 ( var(NovelProduction) ->
7557 novel_production_calls(ConstraintSymbols,HistoryIDs,HistorySusps,RuleNb,TupleVar,NovelProductions),
7558 ExtendHistory = '$extend_history'(HistorySusp,TupleVar),
7559 NovelProduction = ( TupleVar = Tuple, NovelProductions )
7566 ( chr_pp_flag(debugable,on) ->
7567 Rule = rule(_,_,Guard,Body),
7568 my_term_copy(Guard - Body, VarDict, DebugGuard - DebugBody),
7569 get_occurrence(F/A,O,_,ID),
7570 sort_by_key([Susp,OtherSusp|RestSusps],[ID|RestIDs],KeptSusps),
7571 DebugTry = 'chr debug_event'( try([],KeptSusps,DebugGuard,DebugBody)),
7572 DebugApply = 'chr debug_event'(apply([],KeptSusps,DebugGuard,DebugBody))
7578 ( is_stored_in_guard(F/A, RuleNb) ->
7579 GuardAttachment = Attachment,
7580 BodyAttachment = true
7582 GuardAttachment = true,
7583 BodyAttachment = Attachment % will be true if not observed at all
7599 ConditionalRecursiveCall
7603 add_location(Clause,RuleNb,LocatedClause),
7604 L = [LocatedClause|T].
7606 novel_production_calls([],[],[],_,_,true).
7607 novel_production_calls([ConstraintSymbol|ConstraintSymbols],[ID|IDs],[Suspension|Suspensions],RuleNb,Tuple,(Goal,Goals)) :-
7608 get_occurrence_from_id(ConstraintSymbol,Occurrence,RuleNb,ID),
7609 delay_phase_end(validate_store_type_assumptions,novel_production_call(ConstraintSymbol,Occurrence,'$novel_production'(Suspension,Tuple),Goal)),
7610 novel_production_calls(ConstraintSymbols,IDs,Suspensions,RuleNb,Tuple,Goals).
7612 history_susps(RestIDs,ReversedRestSusps,Susp,ID,HistorySusps) :-
7613 reverse(ReversedRestSusps,RestSusps),
7614 sort_by_key([Susp|RestSusps],[ID|RestIDs],HistorySusps).
7616 named_history_susps([],_,_,[]).
7617 named_history_susps([HistoryID|HistoryIDs],IDs,Susps,[HistorySusp|HistorySusps]) :-
7618 select2(HistoryID,HistorySusp,IDs,Susps,RestIDs,RestSusps), !,
7619 named_history_susps(HistoryIDs,RestIDs,RestSusps,HistorySusps).
7623 gen_var_susp_list_for([Head],Terms,VarDict,HeadVars,VarsSusp,Susp) :-
7626 head_info(Head,A,_Vars,Susp,VarsSusp,HeadPairs),
7627 get_constraint_mode(F/A,Mode),
7628 head_arg_matches(HeadPairs,Mode,[],_,VarDict),
7629 extra_active_delegate_variables(Head,Terms,VarDict,ExtraVars),
7630 append(VarsSusp,ExtraVars,HeadVars).
7631 gen_var_susp_list_for([Head|Heads],Terms,NVarDict,VarsSusps,Rest,Susps) :-
7632 gen_var_susp_list_for(Heads,[Head|Terms],VarDict,Rest,_,_),
7635 head_info(Head,A,_Vars,Susp,_VarsSusp,HeadPairs),
7636 get_constraint_mode(F/A,Mode),
7637 head_arg_matches(HeadPairs,Mode,VarDict,_,NVarDict),
7638 passive_delegate_variables(Head,Heads,Terms,NVarDict,HeadVars),
7639 append(HeadVars,[Susp,Susps|Rest],VarsSusps).
7642 % VarDict for the copies of variables in the original heads
7643 % VarsSuspsList list of lists of arguments for the successive heads
7644 % FirstVarsSusp top level arguments
7645 % SuspList list of all suspensions
7646 % Iterators list of all iterators
7647 gen_var_susp_list_for_b([Head],NextHeads,VarDict,[HeadVars],VarsSusp,[Susp],[]) :-
7650 head_info(Head,A,_Vars,Susp,VarsSusp,Pairs), % make variables for argument positions
7651 get_constraint_mode(F/A,Mode),
7652 head_arg_matches(Pairs,Mode,[],_,VarDict), % copy variables inside arguments, build dictionary
7653 extra_active_delegate_variables(Head,NextHeads,VarDict,ExtraVars), % decide what additional variables are needed
7654 append(VarsSusp,ExtraVars,HeadVars). % add additional variables to head variables
7655 gen_var_susp_list_for_b([Head|Heads],NextHeads,NVarDict,[Vars|RestVars],FirstVarsSusp,[Susp|SuspList],[Susps|Iterators]) :-
7656 gen_var_susp_list_for_b(Heads,[Head|NextHeads],VarDict,RestVars,FirstVarsSusp,SuspList,Iterators),
7659 head_info(Head,A,_Vars,Susp,_VarsSusp,HeadPairs),
7660 get_constraint_mode(F/A,Mode),
7661 head_arg_matches(HeadPairs,Mode,VarDict,_,NVarDict),
7662 passive_delegate_variables(Head,Heads,NextHeads,NVarDict,HeadVars),
7663 append(HeadVars,[Susp,Susps],Vars).
7665 get_prop_inner_loop_vars([Head],NextHeads,HeadVars,VarDict,Susp,Vars,[]) :-
7668 head_info(Head,A,Vars,Susp,VarsSusp,Pairs),
7669 get_constraint_mode(F/A,Mode),
7670 head_arg_matches(Pairs,Mode,[],_,VarDict),
7671 extra_active_delegate_variables(Head,NextHeads,VarDict,ExtraVars),
7672 append(VarsSusp,ExtraVars,HeadVars).
7673 get_prop_inner_loop_vars([Head|Heads],Terms,VarsSusps,NVarDict,MainSusp,MainVars,[Susp|RestSusps]) :-
7674 get_prop_inner_loop_vars(Heads,[Head|Terms],RestVarsSusp,VarDict,MainSusp,MainVars,RestSusps),
7677 head_info(Head,A,_Vars,Susp,_VarsSusp,Pairs),
7678 get_constraint_mode(F/A,Mode),
7679 head_arg_matches(Pairs,Mode,VarDict,_,NVarDict),
7680 passive_delegate_variables(Head,Heads,Terms,NVarDict,HeadVars),
7681 append(HeadVars,[Susp,Susps|RestVarsSusp],VarsSusps).
7683 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7685 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7687 %% | _ \ __ _ ___ ___(_)_ _____ | | | | ___ __ _ __| |
7688 %% | |_) / _` / __/ __| \ \ / / _ \ | |_| |/ _ \/ _` |/ _` |
7689 %% | __/ (_| \__ \__ \ |\ V / __/ | _ | __/ (_| | (_| |
7690 %% |_| \__,_|___/___/_| \_/ \___| |_| |_|\___|\__,_|\__,_|
7693 %% | _ \ ___| |_ _ __(_) _____ ____ _| |
7694 %% | |_) / _ \ __| '__| |/ _ \ \ / / _` | |
7695 %% | _ < __/ |_| | | | __/\ V / (_| | |
7696 %% |_| \_\___|\__|_| |_|\___| \_/ \__,_|_|
7699 %% | _ \ ___ ___ _ __ __| | ___ _ __(_)_ __ __ _
7700 %% | |_) / _ \/ _ \| '__/ _` |/ _ \ '__| | '_ \ / _` |
7701 %% | _ < __/ (_) | | | (_| | __/ | | | | | | (_| |
7702 %% |_| \_\___|\___/|_| \__,_|\___|_| |_|_| |_|\__, |
7705 reorder_heads(RuleNb,Head,RestHeads,RestIDs,NRestHeads,NRestIDs) :-
7706 ( chr_pp_flag(reorder_heads,on), length(RestHeads,Length), Length =< 6 ->
7707 reorder_heads_main(RuleNb,Head,RestHeads,RestIDs,NRestHeads,NRestIDs)
7709 NRestHeads = RestHeads,
7713 reorder_heads_main(RuleNb,Head,RestHeads,RestIDs,NRestHeads,NRestIDs) :-
7714 term_variables(Head,Vars),
7715 InitialData = entry([],[],Vars,RestHeads,RestIDs,RuleNb),
7716 copy_term_nat(InitialData,InitialDataCopy),
7717 a_star(InitialDataCopy,FD^(chr_translate:final_data(FD)),N^EN^C^(chr_translate:expand_data(N,EN,C)),FinalData),
7718 InitialDataCopy = InitialData,
7719 FinalData = entry(RNRestHeads,RNRestIDs,_,_,_,_),
7720 reverse(RNRestHeads,NRestHeads),
7721 reverse(RNRestIDs,NRestIDs).
7723 final_data(Entry) :-
7724 Entry = entry(_,_,_,_,[],_).
7726 expand_data(Entry,NEntry,Cost) :-
7727 Entry = entry(Heads,IDs,Vars,NHeads,NIDs,RuleNb),
7728 select2(Head1,ID1,NHeads,NIDs,NHeads1,NIDs1),
7729 term_variables([Head1|Vars],Vars1),
7730 NEntry = entry([Head1|Heads],[ID1|IDs],Vars1,NHeads1,NIDs1,RuleNb),
7731 order_score(Head1,ID1,Vars,NHeads1,RuleNb,Cost).
7733 % Assigns score to head based on known variables and heads to lookup
7734 order_score(Head,ID,KnownVars,RestHeads,RuleNb,Score) :-
7736 get_store_type(F/A,StoreType),
7737 order_score(StoreType,Head,ID,KnownVars,RestHeads,RuleNb,Score).
7739 order_score(default,Head,_ID,KnownVars,RestHeads,RuleNb,Score) :-
7740 term_variables(Head,HeadVars),
7741 term_variables(RestHeads,RestVars),
7742 order_score_vars(HeadVars,KnownVars,RestVars,Score).
7743 order_score(multi_inthash(Indexes),Head,_ID,KnownVars,RestHeads,RuleNb,Score) :-
7744 order_score_indexes(Indexes,Head,KnownVars,0,Score).
7745 order_score(multi_hash(Indexes),Head,_ID,KnownVars,RestHeads,RuleNb,Score) :-
7746 order_score_indexes(Indexes,Head,KnownVars,0,Score).
7747 order_score(global_ground,Head,ID,KnownVars,RestHeads,RuleNb,Score) :-
7748 term_variables(Head,HeadVars),
7749 term_variables(RestHeads,RestVars),
7750 order_score_vars(HeadVars,KnownVars,RestVars,Score_),
7751 Score is Score_ * 2.
7752 order_score(var_assoc_store(_,_),_,_,_,_,_,1).
7753 order_score(global_singleton,_Head,ID,_KnownVars,_RestHeads,_RuleNb,Score) :-
7754 Score = 1. % guaranteed O(1)
7756 order_score(multi_store(StoreTypes),Head,ID,KnownVars,RestHeads,RuleNb,Score) :-
7757 find_with_var_identity(
7759 t(Head,KnownVars,RestHeads),
7760 ( lists:member(ST,StoreTypes), chr_translate:order_score(ST,Head,ID,KnownVars,RestHeads,RuleNb,S) ),
7763 min_list(Scores,Score).
7764 order_score(identifier_store(Index),Head,ID,KnownVars,RestHeads,RuleNb,Score) :-
7766 order_score(type_indexed_identifier_store(_,_),Head,ID,KnownVars,RestHeads,RuleNb,Score) :-
7769 order_score_indexes([],_,_,Score,NScore) :-
7770 Score > 0, NScore = 100.
7771 order_score_indexes([I|Is],Head,KnownVars,Score,NScore) :-
7772 multi_hash_key_args(I,Head,Args),
7773 ( forall(Arg,Args,memberchk_eq(Arg,KnownVars)) ->
7778 order_score_indexes(Is,Head,KnownVars,Score1,NScore).
7780 order_score_vars(Vars,KnownVars,RestVars,Score) :-
7781 order_score_count_vars(Vars,KnownVars,RestVars,K-R-O),
7785 Score is max(10 - K,0)
7787 Score is max(10 - R,1) * 10
7789 Score is max(10-O,1) * 100
7791 order_score_count_vars([],_,_,0-0-0).
7792 order_score_count_vars([V|Vs],KnownVars,RestVars,NK-NR-NO) :-
7793 order_score_count_vars(Vs,KnownVars,RestVars,K-R-O),
7794 ( memberchk_eq(V,KnownVars) ->
7797 ; memberchk_eq(V,RestVars) ->
7805 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7807 %% |_ _|_ __ | (_)_ __ (_)_ __ __ _
7808 %% | || '_ \| | | '_ \| | '_ \ / _` |
7809 %% | || | | | | | | | | | | | | (_| |
7810 %% |___|_| |_|_|_|_| |_|_|_| |_|\__, |
7814 create_get_mutable_ref(V,M,GM) :- GM = (M = mutable(V)).
7815 create_get_mutable(V,M,GM) :- M = mutable(V), GM = true.
7819 %% create_get_mutable(V,M,GM) :- GM = get_mutable(V,M).
7820 %% create_get_mutable_ref(V,M,GM) :- GM = get_mutable(V,M).
7823 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7825 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7827 %% | | | | |_(_) (_) |_ _ _
7828 %% | | | | __| | | | __| | | |
7829 %% | |_| | |_| | | | |_| |_| |
7830 %% \___/ \__|_|_|_|\__|\__, |
7833 % Create a fresh variable.
7836 % Create =N= fresh variables.
7840 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs) :-
7841 vars_susp(A,Vars,Susp,VarsSusp),
7843 pairup(Args,Vars,HeadPairs).
7845 inc_id([N|Ns],[O|Ns]) :-
7847 dec_id([N|Ns],[M|Ns]) :-
7850 extend_id(Id,[0|Id]).
7852 next_id([_,N|Ns],[O|Ns]) :-
7855 % return clause Head
7856 % for F/A constraint symbol, predicate identifier Id and arguments Head
7857 build_head(F,A,Id,Args,Head) :-
7858 buildName(F,A,Id,Name),
7859 ( (chr_pp_flag(debugable,on) ; is_stored(F/A), ( has_active_occurrence(F/A) ; chr_pp_flag(late_allocation,off)),
7860 ( may_trigger(F/A) ;
7861 get_allocation_occurrence(F/A,AO),
7862 get_max_occurrence(F/A,MO),
7864 Head =.. [Name|Args]
7866 init(Args,ArgsWOSusp), % XXX not entirely correct!
7867 Head =.. [Name|ArgsWOSusp]
7870 % return predicate name Result
7871 % for Fct/Aty constraint symbol and predicate identifier List
7872 buildName(Fct,Aty,List,Result) :-
7873 ( (chr_pp_flag(debugable,on) ; (once((is_stored(Fct/Aty), ( has_active_occurrence(Fct/Aty) ; chr_pp_flag(late_allocation,off)),
7874 ( may_trigger(Fct/Aty) ; get_allocation_occurrence(Fct/Aty,AO), get_max_occurrence(Fct/Aty,MO),
7875 MO >= AO ) ; List \= [0])) ) ) ->
7876 atom_concat(Fct, '___' ,FctSlash),
7877 atomic_concat(FctSlash,Aty,FctSlashAty),
7878 buildName_(List,FctSlashAty,Result)
7883 buildName_([],Name,Name).
7884 buildName_([N|Ns],Name,Result) :-
7885 buildName_(Ns,Name,Name1),
7886 atom_concat(Name1,'__',NameDash), % '_' is a char :-(
7887 atomic_concat(NameDash,N,Result).
7889 vars_susp(A,Vars,Susp,VarsSusp) :-
7891 append(Vars,[Susp],VarsSusp).
7893 or_pattern(Pos,Pat) :-
7895 Pat is 1 << Pow. % was 2 ** X
7897 and_pattern(Pos,Pat) :-
7899 Y is 1 << X, % was 2 ** X
7900 Pat is (-1)*(Y + 1).
7902 make_name(Prefix,F/A,Name) :-
7903 atom_concat_list([Prefix,F,'___',A],Name).
7905 %===============================================================================
7906 % Attribute for attributed variables
7908 make_attr(N,Mask,SuspsList,Attr) :-
7909 length(SuspsList,N),
7910 Attr =.. [v,Mask|SuspsList].
7912 get_all_suspensions2(N,Attr,SuspensionsList) :-
7913 chr_pp_flag(dynattr,off), !,
7914 make_attr(N,_,SuspensionsList,Attr).
7917 get_all_suspensions2(N,Attr,Goal,SuspensionsList) :-
7918 % writeln(get_all_suspensions2),
7919 length(SuspensionsList,N),
7920 Goal = 'chr all_suspensions'(SuspensionsList,1,Attr).
7924 normalize_attr(Attr,NormalGoal,NormalAttr) :-
7925 % writeln(normalize_attr),
7926 NormalGoal = 'chr normalize_attr'(Attr,NormalAttr).
7928 get_suspensions(N,Position,TAttr,(TAttr = Attr),Suspensions) :-
7929 chr_pp_flag(dynattr,off), !,
7930 make_attr(N,_,SuspsList,Attr),
7931 nth1(Position,SuspsList,Suspensions).
7934 get_suspensions(N,Position,TAttr,Goal,Suspensions) :-
7935 % writeln(get_suspensions),
7937 ( memberchk(Position-Suspensions,TAttr) ->
7943 %-------------------------------------------------------------------------------
7944 % +N: number of constraint symbols
7945 % +Suspension: source-level variable, for suspension
7946 % +Position: constraint symbol number
7947 % -Attr: source-level term, for new attribute
7948 singleton_attr(N,Suspension,Position,Attr) :-
7949 chr_pp_flag(dynattr,off), !,
7950 or_pattern(Position,Pattern),
7951 make_attr(N,Pattern,SuspsList,Attr),
7952 nth1(Position,SuspsList,[Suspension]),
7953 chr_delete(SuspsList,[Suspension],RestSuspsList),
7954 set_elems(RestSuspsList,[]).
7957 singleton_attr(N,Suspension,Position,Attr) :-
7958 % writeln(singleton_attr),
7959 Attr = [Position-[Suspension]].
7961 %-------------------------------------------------------------------------------
7962 % +N: number of constraint symbols
7963 % +Suspension: source-level variable, for suspension
7964 % +Position: constraint symbol number
7965 % +TAttr: source-level variable, for old attribute
7966 % -Goal: goal for creating new attribute
7967 % -NTAttr: source-level variable, for new attribute
7968 add_attr(N,Suspension,Position,TAttr,Goal,NTAttr) :-
7969 chr_pp_flag(dynattr,off), !,
7970 make_attr(N,Mask,SuspsList,Attr),
7971 or_pattern(Position,Pattern),
7972 nth1(Position,SuspsList,Susps),
7973 substitute_eq(Susps,SuspsList,[Suspension|Susps],SuspsList1),
7974 make_attr(N,Mask,SuspsList1,NewAttr1),
7975 substitute_eq(Susps,SuspsList,[Suspension],SuspsList2),
7976 make_attr(N,NewMask,SuspsList2,NewAttr2),
7979 ( Mask /\ Pattern =:= Pattern ->
7982 NewMask is Mask \/ Pattern,
7988 add_attr(N,Suspension,Position,TAttr,Goal,NTAttr) :-
7989 % writeln(add_attr),
7991 ( 'chr select'(TAttr,Position-Suspensions,RAttr) ->
7992 NTAttr = [Position-[Suspension|Suspensions]|RAttr]
7994 NTAttr = [Position-[Suspension]|TAttr]
7997 rem_attr(N,Var,Suspension,Position,TAttr,Goal) :-
7998 chr_pp_flag(dynattr,off), !,
7999 or_pattern(Position,Pattern),
8000 and_pattern(Position,DelPattern),
8001 make_attr(N,Mask,SuspsList,Attr),
8002 nth1(Position,SuspsList,Susps),
8003 substitute_eq(Susps,SuspsList,[],SuspsList1),
8004 make_attr(N,NewMask,SuspsList1,Attr1),
8005 substitute_eq(Susps,SuspsList,NewSusps,SuspsList2),
8006 make_attr(N,Mask,SuspsList2,Attr2),
8007 get_target_module(Mod),
8010 ( Mask /\ Pattern =:= Pattern ->
8011 'chr sbag_del_element'(Susps,Suspension,NewSusps),
8013 NewMask is Mask /\ DelPattern,
8017 put_attr(Var,Mod,Attr1)
8020 put_attr(Var,Mod,Attr2)
8028 rem_attr(N,Var,Suspension,Position,TAttr,Goal) :-
8029 % writeln(rem_attr),
8030 get_target_module(Mod),
8032 ( 'chr select'(TAttr,Position-Suspensions,RAttr) ->
8033 'chr sbag_del_element'(Suspensions,Suspension,NSuspensions),
8034 ( NSuspensions == [] ->
8038 put_attr(Var,Mod,RAttr)
8041 put_attr(Var,Mod,[Position-NSuspensions|RAttr])
8047 %-------------------------------------------------------------------------------
8048 % +N: number of constraint symbols
8049 % +TAttr1: source-level variable, for attribute
8050 % +TAttr2: source-level variable, for other attribute
8051 % -Goal: goal for merging the two attributes
8052 % -Attr: source-level term, for merged attribute
8053 merge_attributes(N,TAttr1,TAttr2,Goal,Attr) :-
8054 chr_pp_flag(dynattr,off), !,
8055 make_attr(N,Mask1,SuspsList1,Attr1),
8056 merge_attributes2(N,Mask1,SuspsList1,TAttr2,Goal2,Attr),
8063 merge_attributes(N,TAttr1,TAttr2,Goal,Attr) :-
8064 % writeln(merge_attributes),
8066 sort(TAttr1,Sorted1),
8067 sort(TAttr2,Sorted2),
8068 'chr new_merge_attributes'(Sorted1,Sorted2,Attr)
8072 %-------------------------------------------------------------------------------
8073 % +N: number of constraint symbols
8075 % +SuspsList1: static term, for suspensions list
8076 % +TAttr2: source-level variable, for other attribute
8077 % -Goal: goal for merging the two attributes
8078 % -Attr: source-level term, for merged attribute
8079 merge_attributes2(N,Mask1,SuspsList1,TAttr2,Goal,Attr) :-
8080 make_attr(N,Mask2,SuspsList2,Attr2),
8081 bagof(G,X ^ Y ^ SY ^ M ^ (member2(SuspsList1,SuspsList2,X-Y),G = (sort(Y,SY),'chr merge_attributes'(X,SY,M))),Gs),
8082 list2conj(Gs,SortGoals),
8083 bagof(MS,A ^ B ^ C ^ member((A,'chr merge_attributes'(B,C,MS)),Gs), SuspsList),
8084 make_attr(N,Mask,SuspsList,Attr),
8088 Mask is Mask1 \/ Mask2
8092 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8093 % Storetype dependent lookup
8095 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8096 %% lookup_passive_head(+Head,+PreviousVars,+RenamingVarDict,
8097 %% -Goal,-SuspensionList) is det.
8099 % Create a universal lookup goal for given head.
8100 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8101 lookup_passive_head(Head,PreJoin,VarDict,Goal,AllSusps) :-
8103 get_store_type(F/A,StoreType),
8104 lookup_passive_head(StoreType,Head,PreJoin,VarDict,[],Goal,AllSusps).
8106 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8107 %% lookup_passive_head(+Head,+PreviousVars,+RenamingVarDict,+GroundVars,
8108 %% -Goal,-SuspensionList) is det.
8110 % Create a universal lookup goal for given head.
8111 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8112 lookup_passive_head(Head,PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
8114 get_store_type(F/A,StoreType),
8115 lookup_passive_head(StoreType,Head,PreJoin,VarDict,GroundVars,Goal,AllSusps).
8117 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8118 %% lookup_passive_head(+StoreType,+Head,+PreviousVars,+RenamingVarDict,
8119 %% +GroundVars,-Goal,-SuspensionList) is det.
8121 % Create a universal lookup goal for given head.
8122 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8123 lookup_passive_head(default,Head,PreJoin,VarDict,_,Goal,AllSusps) :-
8125 passive_head_via(Head,PreJoin,VarDict,Goal,AllSusps),
8126 update_store_type(F/A,default).
8127 lookup_passive_head(multi_inthash(Indexes),Head,_PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
8128 hash_lookup_passive_head(inthash,Indexes,Head,VarDict,GroundVars,Goal,AllSusps,_).
8129 lookup_passive_head(multi_hash(Indexes),Head,_PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
8130 hash_lookup_passive_head(hash,Indexes,Head,VarDict,GroundVars,Goal,AllSusps,_).
8131 lookup_passive_head(global_ground,Head,_PreJoin,_VarDict,_,Goal,AllSusps) :-
8133 global_ground_store_name(F/A,StoreName),
8134 make_get_store_goal(StoreName,AllSusps,Goal), % Goal = nb_getval(StoreName,AllSusps),
8135 update_store_type(F/A,global_ground).
8136 lookup_passive_head(var_assoc_store(VarIndex,KeyIndex),Head,_PreJoin,VarDict,_,Goal,AllSusps) :-
8137 arg(VarIndex,Head,OVar),
8138 arg(KeyIndex,Head,OKey),
8139 translate([OVar,OKey],VarDict,[Var,Key]),
8140 get_target_module(Module),
8142 get_attr(Var,Module,AssocStore),
8143 lookup_assoc_store(AssocStore,Key,AllSusps)
8145 lookup_passive_head(global_singleton,Head,_PreJoin,_VarDict,_,Goal,AllSusps) :-
8147 global_singleton_store_name(F/A,StoreName),
8148 make_get_store_goal(StoreName,Susp,GetStoreGoal),
8149 Goal = (GetStoreGoal,Susp \== [],AllSusps = [Susp]),
8150 update_store_type(F/A,global_singleton).
8151 lookup_passive_head(multi_store(StoreTypes),Head,PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
8153 member(ST,StoreTypes),
8154 lookup_passive_head(ST,Head,PreJoin,VarDict,GroundVars,Goal,AllSusps)
8156 lookup_passive_head(identifier_store(Index),Head,PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
8158 arg(Index,Head,Var),
8159 translate([Var],VarDict,[KeyVar]),
8160 delay_phase_end(validate_store_type_assumptions,
8161 identifier_lookup(F/A,Index,AllSusps,KeyVar,Goal)
8163 update_store_type(F/A,identifier_store(Index)),
8164 get_identifier_index(F/A,Index,_).
8165 lookup_passive_head(type_indexed_identifier_store(Index,IndexType),Head,PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
8167 arg(Index,Head,Var),
8169 translate([Var],VarDict,[KeyVar]),
8171 ; ground(Var), Var = '$chr_identifier_match'(ActualVar,_) ->
8172 lookup_identifier_atom(IndexType,ActualVar,KeyVar,LookupGoal),
8173 Goal = (LookupGoal,StructGoal)
8175 delay_phase_end(validate_store_type_assumptions,
8176 type_indexed_identifier_lookup(F/A,Index,IndexType,AllSusps,KeyVar,StructGoal)
8178 update_store_type(F/A,type_indexed_identifier_store(Index,IndexType)),
8179 get_type_indexed_identifier_index(IndexType,F/A,Index,_).
8181 identifier_lookup(C,Index,AllSusps,KeyVar,Goal) :-
8182 get_identifier_size(ISize),
8183 functor(Struct,struct,ISize),
8184 get_identifier_index(C,Index,IIndex),
8185 arg(IIndex,Struct,AllSusps),
8186 Goal = (KeyVar = Struct).
8188 type_indexed_identifier_lookup(C,Index,IndexType,AllSusps,KeyVar,Goal) :-
8189 type_indexed_identifier_structure(IndexType,Struct),
8190 get_type_indexed_identifier_index(IndexType,C,Index,IIndex),
8191 arg(IIndex,Struct,AllSusps),
8192 Goal = (KeyVar = Struct).
8194 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8195 %% hash_lookup_passive_head(+StoreType,+Indexes,+Head,+RenamingVarDict,
8196 %% +GroundVars,-Goal,-SuspensionList,-Index) is det.
8198 % Create a universal hash lookup goal for given head.
8199 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8200 hash_lookup_passive_head(HashType,Indexes,Head,VarDict,GroundVars,Goal,AllSusps,Index) :-
8202 member(Index,Indexes),
8203 multi_hash_key_args(Index,Head,KeyArgs),
8205 translate(KeyArgs,VarDict,KeyArgCopies)
8207 ground(KeyArgs), KeyArgCopies = KeyArgs
8210 ( KeyArgCopies = [KeyCopy] ->
8213 KeyCopy =.. [k|KeyArgCopies]
8216 multi_hash_lookup_goal(F/A,HashType,Index,KeyCopy,AllSusps,LookupGoal),
8218 check_ground(GroundVars,KeyArgs,OriginalGroundCheck),
8219 my_term_copy(OriginalGroundCheck,VarDict,GroundCheck),
8221 Goal = (GroundCheck,LookupGoal),
8223 ( HashType == inthash ->
8224 update_store_type(F/A,multi_inthash([Index]))
8226 update_store_type(F/A,multi_hash([Index]))
8229 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8230 %% existential_lookup(+StoreType,+Head,+PrevVariablesHead,+RenamingVarDict,
8231 %% +GroundVariables,-SuspensionTerm,-Goal,-SuspVar,
8232 %% +VarArgDict,-NewVarArgDict) is det.
8234 % Create existential lookup goal for given head.
8235 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8236 existential_lookup(var_assoc_store(VarIndex,KeyIndex),Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,Pairs) :- !,
8237 lookup_passive_head(var_assoc_store(VarIndex,KeyIndex),Head,PreJoin,VarDict,GroundVars,UniversalGoal,AllSusps),
8238 sbag_member_call(Susp,AllSusps,Sbag),
8240 delay_phase_end(validate_store_type_assumptions,
8241 ( static_suspension_term(F/A,SuspTerm),
8242 get_static_suspension_field(F/A,SuspTerm,state,active,GetState)
8251 existential_lookup(global_singleton,Head,_PreJoin,_VarDict,_,SuspTerm,Goal,Susp,Pairs,Pairs) :- !,
8253 global_singleton_store_name(F/A,StoreName),
8254 make_get_store_goal(StoreName,Susp,GetStoreGoal),
8256 GetStoreGoal, % nb_getval(StoreName,Susp),
8260 update_store_type(F/A,global_singleton).
8261 existential_lookup(multi_store(StoreTypes),Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :- !,
8263 member(ST,StoreTypes),
8264 existential_lookup(ST,Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs)
8266 existential_lookup(multi_inthash(Indexes),Head,_,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :- !,
8267 existential_hash_lookup(inthash,Indexes,Head,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs).
8268 existential_lookup(multi_hash(Indexes),Head,_,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :- !,
8269 existential_hash_lookup(hash,Indexes,Head,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs).
8270 existential_lookup(identifier_store(Index),Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :- !,
8271 lookup_passive_head(identifier_store(Index),Head,PreJoin,VarDict,GroundVars,LookupGoal,AllSusps),
8272 hash_index_filter(Pairs,Index,NPairs),
8275 ( check_fd_lookup_condition(F,A,Head,KeyArgs) ->
8276 Sbag = (AllSusps = [Susp])
8278 sbag_member_call(Susp,AllSusps,Sbag)
8280 delay_phase_end(validate_store_type_assumptions,
8281 ( static_suspension_term(F/A,SuspTerm),
8282 get_static_suspension_field(F/A,SuspTerm,state,active,GetState)
8288 Susp = SuspTerm, % not inlined
8291 existential_lookup(type_indexed_identifier_store(Index,IndexType),Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :- !,
8292 lookup_passive_head(type_indexed_identifier_store(Index,IndexType),Head,PreJoin,VarDict,GroundVars,LookupGoal,AllSusps),
8293 hash_index_filter(Pairs,Index,NPairs),
8296 ( check_fd_lookup_condition(F,A,Head,KeyArgs) ->
8297 Sbag = (AllSusps = [Susp])
8299 sbag_member_call(Susp,AllSusps,Sbag)
8301 delay_phase_end(validate_store_type_assumptions,
8302 ( static_suspension_term(F/A,SuspTerm),
8303 get_static_suspension_field(F/A,SuspTerm,state,active,GetState)
8309 Susp = SuspTerm, % not inlined
8312 existential_lookup(StoreType,Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,Pairs) :-
8313 lookup_passive_head(StoreType,Head,PreJoin,VarDict,GroundVars,UGoal,Susps),
8314 sbag_member_call(Susp,Susps,Sbag),
8316 delay_phase_end(validate_store_type_assumptions,
8317 ( static_suspension_term(F/A,SuspTerm),
8318 get_static_suspension_field(F/A,SuspTerm,state,active,GetState)
8324 Susp = SuspTerm, % not inlined
8328 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8329 %% existential_hash_lookup(+StoreType,+Indexes,+Head,+RenamingVarDict,
8330 %% +GroundVariables,-SuspensionTerm,-Goal,-SuspVar,
8331 %% +VarArgDict,-NewVarArgDict) is det.
8333 % Create existential hash lookup goal for given head.
8334 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8335 existential_hash_lookup(HashType,Indexes,Head,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :-
8336 hash_lookup_passive_head(HashType,Indexes,Head,VarDict,GroundVars,LookupGoal,AllSusps,Index),
8338 hash_index_filter(Pairs,Index,NPairs),
8341 ( check_fd_lookup_condition(F,A,Head,KeyArgs) ->
8342 Sbag = (AllSusps = [Susp])
8344 sbag_member_call(Susp,AllSusps,Sbag)
8346 delay_phase_end(validate_store_type_assumptions,
8347 ( static_suspension_term(F/A,SuspTerm),
8348 get_static_suspension_field(F/A,SuspTerm,state,active,GetState)
8354 Susp = SuspTerm, % not inlined
8358 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8359 %% hash_index_filter(+Pairs,+Index,-NPairs) is det.
8361 % Filter out pairs already covered by given hash index.
8362 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8363 hash_index_filter(Pairs,Index,NPairs) :-
8369 hash_index_filter(Pairs,NIndex,1,NPairs).
8371 hash_index_filter([],_,_,[]).
8372 hash_index_filter([P|Ps],Index,N,NPairs) :-
8377 hash_index_filter(Ps,[I|Is],NN,NPs)
8379 hash_index_filter(Ps,Is,NN,NPairs)
8385 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8386 %------------------------------------------------------------------------------%
8387 %% assume_constraint_stores(+ConstraintSymbols) is det.
8389 % Compute all constraint store types that are possible for the given
8390 % =ConstraintSymbols=.
8391 %------------------------------------------------------------------------------%
8392 assume_constraint_stores([]).
8393 assume_constraint_stores([C|Cs]) :-
8394 ( chr_pp_flag(debugable,off),
8395 ( only_ground_indexed_arguments(C) ; chr_pp_flag(mixed_stores,on) ),
8397 get_store_type(C,default) ->
8398 get_indexed_arguments(C,AllIndexedArgs),
8399 get_constraint_mode(C,Modes),
8400 findall(Index,(member(Index,AllIndexedArgs),
8401 nth(Index,Modes,+)),IndexedArgs),
8402 length(IndexedArgs,NbIndexedArgs),
8403 % Construct Index Combinations
8404 ( NbIndexedArgs > 10 ->
8405 findall([Index],member(Index,IndexedArgs),Indexes)
8407 findall(Index,(sublist(Index,IndexedArgs), Index \== []),UnsortedIndexes),
8408 predsort(longer_list,UnsortedIndexes,Indexes)
8411 ( get_functional_dependency(C,1,Pattern,Key),
8412 all_distinct_var_args(Pattern), Key == [] ->
8413 assumed_store_type(C,global_singleton)
8414 ; ( only_ground_indexed_arguments(C) ; NbIndexedArgs > 0 ) ->
8415 get_constraint_type_det(C,ArgTypes),
8416 partition_indexes(Indexes,ArgTypes,HashIndexes,IntHashIndexes,IdentifierIndexes,CompoundIdentifierIndexes),
8418 ( IntHashIndexes = [] ->
8421 Stores = [multi_inthash(IntHashIndexes)|Stores1]
8423 ( HashIndexes = [] ->
8426 Stores1 = [multi_hash(HashIndexes)|Stores2]
8428 ( IdentifierIndexes = [] ->
8431 maplist(wrap_in_functor(identifier_store),IdentifierIndexes,WrappedIdentifierIndexes),
8432 append(WrappedIdentifierIndexes,Stores3,Stores2)
8434 append(CompoundIdentifierIndexes,Stores4,Stores3),
8435 ( only_ground_indexed_arguments(C)
8436 -> Stores4 = [global_ground]
8437 ; Stores4 = [default]
8439 assumed_store_type(C,multi_store(Stores))
8445 assume_constraint_stores(Cs).
8447 %------------------------------------------------------------------------------%
8448 %% partition_indexes(+Indexes,+Types,
8449 %% -HashIndexes,-IntHashIndexes,-IdentifierIndexes) is det.
8450 %------------------------------------------------------------------------------%
8451 partition_indexes([],_,[],[],[],[]).
8452 partition_indexes([Index|Indexes],Types,HashIndexes,IntHashIndexes,IdentifierIndexes,CompoundIdentifierIndexes) :-
8455 unalias_type(Type,UnAliasedType),
8456 UnAliasedType == chr_identifier ->
8457 IdentifierIndexes = [I|RIdentifierIndexes],
8458 IntHashIndexes = RIntHashIndexes,
8459 HashIndexes = RHashIndexes,
8460 CompoundIdentifierIndexes = RCompoundIdentifierIndexes
8463 unalias_type(Type,UnAliasedType),
8464 nonvar(UnAliasedType),
8465 UnAliasedType = chr_identifier(IndexType) ->
8466 CompoundIdentifierIndexes = [type_indexed_identifier_store(I,IndexType)|RCompoundIdentifierIndexes],
8467 IdentifierIndexes = RIdentifierIndexes,
8468 IntHashIndexes = RIntHashIndexes,
8469 HashIndexes = RHashIndexes
8472 unalias_type(Type,UnAliasedType),
8473 UnAliasedType == dense_int ->
8474 IntHashIndexes = [Index|RIntHashIndexes],
8475 HashIndexes = RHashIndexes,
8476 IdentifierIndexes = RIdentifierIndexes,
8477 CompoundIdentifierIndexes = RCompoundIdentifierIndexes
8480 unalias_type(Type,UnAliasedType),
8481 nonvar(UnAliasedType),
8482 UnAliasedType = chr_identifier(_) ->
8483 % don't use chr_identifiers in hash indexes
8484 IntHashIndexes = RIntHashIndexes,
8485 HashIndexes = RHashIndexes,
8486 IdentifierIndexes = RIdentifierIndexes,
8487 CompoundIdentifierIndexes = RCompoundIdentifierIndexes
8489 IntHashIndexes = RIntHashIndexes,
8490 HashIndexes = [Index|RHashIndexes],
8491 IdentifierIndexes = RIdentifierIndexes,
8492 CompoundIdentifierIndexes = RCompoundIdentifierIndexes
8494 partition_indexes(Indexes,Types,RHashIndexes,RIntHashIndexes,RIdentifierIndexes,RCompoundIdentifierIndexes).
8496 longer_list(R,L1,L2) :-
8506 all_distinct_var_args(Term) :-
8508 copy_term_nat(Args,NArgs),
8509 all_distinct_var_args_(NArgs).
8511 all_distinct_var_args_([]).
8512 all_distinct_var_args_([X|Xs]) :-
8515 all_distinct_var_args_(Xs).
8517 get_indexed_arguments(C,IndexedArgs) :-
8519 get_indexed_arguments(1,A,C,IndexedArgs).
8521 get_indexed_arguments(I,N,C,L) :-
8524 ; ( is_indexed_argument(C,I) ->
8530 get_indexed_arguments(J,N,C,T)
8533 validate_store_type_assumptions([]).
8534 validate_store_type_assumptions([C|Cs]) :-
8535 validate_store_type_assumption(C),
8536 validate_store_type_assumptions(Cs).
8538 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8539 % new code generation
8540 universal_search_iterator_end([CurrentHead|PrevHeads],NextHeads,Rule,F/A,Id,L,T) :-
8541 Rule = rule(H1,_,Guard,Body),
8542 gen_var_susp_list_for_b(PrevHeads,[CurrentHead,NextHeads,Guard,Body],_,VarsAndSuspsList,FirstVarsSusp,_,PrevIterators),
8543 universal_search_iterator_failure_vars(PrevHeads,Id,VarsAndSuspsList,FirstVarsSusp,PrevIterators,PrevVarsAndSusps,PrevId),
8544 flatten(VarsAndSuspsList,VarsAndSusps),
8545 Vars = [ [] | VarsAndSusps],
8546 build_head(F,A,Id,Vars,Head),
8547 build_head(F,A,PrevId,PrevVarsAndSusps,PredecessorCall),
8548 Clause = ( Head :- PredecessorCall),
8549 add_dummy_location(Clause,LocatedClause),
8550 L = [LocatedClause | T].
8552 % functor(CurrentHead,CF,CA),
8553 % check_fd_lookup_condition(CF,CA,CurrentHead,PrevHeads) ->
8556 % gen_var_susp_list_for_b(PrevHeads,[CurrentHead,NextHeads,Guard,Body],_,VarsAndSuspsList,FirstVarsSusp,_,PrevIterators),
8557 % universal_search_iterator_failure_vars(PrevHeads,Id,VarsAndSuspsList,FirstVarsSusp,PrevIterators,PrevVarsAndSusps,PrevId),
8558 % flatten(VarsAndSuspsList,VarsAndSusps),
8559 % Vars = [ [] | VarsAndSusps],
8560 % build_head(F,A,Id,Vars,Head),
8561 % build_head(F,A,PrevId,PrevVarsAndSusps,PredecessorCall),
8562 % Clause = ( Head :- PredecessorCall),
8566 % skips back intelligently over global_singleton lookups
8567 universal_search_iterator_failure_vars(PrevHeads,Id,VarsAndSuspsList,BaseCallArgs,PrevIterators,PrevVarsAndSusps,PrevId) :-
8570 PrevVarsAndSusps = BaseCallArgs
8572 VarsAndSuspsList = [_|AllButFirstList],
8574 ( PrevHeads = [PrevHead|PrevHeads1],
8575 functor(PrevHead,F,A),
8576 check_fd_lookup_condition(F,A,PrevHead,PrevHeads1) ->
8577 PrevIterators = [_|PrevIterators1],
8578 universal_search_iterator_failure_vars(PrevHeads1,PrevId1,AllButFirstList,BaseCallArgs,PrevIterators1,PrevVarsAndSusps,PrevId)
8581 flatten(AllButFirstList,AllButFirst),
8582 PrevIterators = [PrevIterator|_],
8583 PrevVarsAndSusps = [PrevIterator|AllButFirst]
8587 universal_search_iterator([NextHead|RestHeads],[CurrentHead|PreHeads],Rule,F/A,Id,L,T) :-
8588 Rule = rule(_,_,Guard,Body),
8589 gen_var_susp_list_for_b(PreHeads,[CurrentHead,NextHead,RestHeads,Guard,Body],VarDict,PreVarsAndSuspsList,FirstVarsSusp,AllSusps,PrevIterators),
8590 init(AllSusps,PreSusps),
8591 flatten(PreVarsAndSuspsList,PreVarsAndSusps),
8592 gen_var(OtherSusps),
8593 functor(CurrentHead,OtherF,OtherA),
8594 gen_vars(OtherA,OtherVars),
8595 head_info(CurrentHead,OtherA,OtherVars,OtherSusp,_VarsSusp,HeadPairs),
8596 get_constraint_mode(OtherF/OtherA,Mode),
8597 head_arg_matches(HeadPairs,Mode,VarDict,FirstMatching,VarDict1),
8599 delay_phase_end(validate_store_type_assumptions,
8600 ( static_suspension_term(OtherF/OtherA,OtherSuspension),
8601 get_static_suspension_field(OtherF/OtherA,OtherSuspension,state,active,GetState),
8602 get_static_suspension_term_field(arguments,OtherF/OtherA,OtherSuspension,OtherVars)
8606 different_from_other_susps(CurrentHead,OtherSusp,PreHeads,PreSusps,DiffSuspGoals),
8607 % create_get_mutable_ref(active,State,GetMutable),
8609 OtherSusp = OtherSuspension,
8614 add_heads_ground_variables([CurrentHead|PreHeads],[],GroundVars),
8615 lookup_passive_head(NextHead,[CurrentHead|PreHeads],VarDict1,GroundVars,NextSuspGoal,NextSusps),
8616 inc_id(Id,NestedId),
8617 ClauseVars = [[OtherSusp|OtherSusps]|PreVarsAndSusps],
8618 build_head(F,A,Id,ClauseVars,ClauseHead),
8619 passive_delegate_variables(CurrentHead,PreHeads,[NextHead,RestHeads,Guard,Body],VarDict1,CurrentHeadVars),
8620 append([NextSusps|CurrentHeadVars],[OtherSusp,OtherSusps|PreVarsAndSusps],NestedVars),
8621 build_head(F,A,NestedId,NestedVars,NestedHead),
8623 ( check_fd_lookup_condition(OtherF,OtherA,CurrentHead,PreHeads) -> % iterator (OtherSusps) is empty at runtime
8624 universal_search_iterator_failure_vars(PreHeads,Id,PreVarsAndSuspsList,FirstVarsSusp,PrevIterators,PreVarsAndSusps1,PrevId),
8625 RecursiveVars = PreVarsAndSusps1
8627 RecursiveVars = [OtherSusps|PreVarsAndSusps],
8630 build_head(F,A,PrevId,RecursiveVars,RecursiveHead),
8641 add_dummy_location(Clause,LocatedClause),
8642 L = [LocatedClause|T].
8644 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8646 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8647 % Observation Analysis
8652 % Analysis based on Abstract Interpretation paper.
8655 % stronger analysis domain [research]
8658 initial_call_pattern/1,
8660 call_pattern_worker/1,
8661 final_answer_pattern/2,
8662 abstract_constraints/1,
8666 ai_observed_internal/2,
8668 ai_not_observed_internal/2,
8672 ai_observation_gather_results/0.
8674 :- chr_type abstract_domain ---> odom(program_point,list(constraint)).
8675 :- chr_type program_point == any.
8677 :- chr_option(mode,initial_call_pattern(+)).
8678 :- chr_option(type_declaration,call_pattern(abstract_domain)).
8680 :- chr_option(mode,call_pattern(+)).
8681 :- chr_option(type_declaration,call_pattern(abstract_domain)).
8683 :- chr_option(mode,call_pattern_worker(+)).
8684 :- chr_option(type_declaration,call_pattern_worker(abstract_domain)).
8686 :- chr_option(mode,final_answer_pattern(+,+)).
8687 :- chr_option(type_declaration,final_answer_pattern(abstract_domain,abstract_domain)).
8689 :- chr_option(mode,abstract_constraints(+)).
8690 :- chr_option(type_declaration,abstract_constraints(list)).
8692 :- chr_option(mode,depends_on(+,+)).
8693 :- chr_option(type_declaration,depends_on(abstract_domain,abstract_domain)).
8695 :- chr_option(mode,depends_on_as(+,+,+)).
8696 :- chr_option(mode,depends_on_ap(+,+,+,+)).
8697 :- chr_option(mode,depends_on_goal(+,+)).
8698 :- chr_option(mode,ai_is_observed(+,+)).
8699 :- chr_option(mode,ai_not_observed(+,+)).
8700 % :- chr_option(mode,ai_observed(+,+)).
8701 :- chr_option(mode,ai_not_observed_internal(+,+)).
8702 :- chr_option(mode,ai_observed_internal(+,+)).
8705 abstract_constraints_fd @
8706 abstract_constraints(_) \ abstract_constraints(_) <=> true.
8708 ai_observed_internal(C,O) \ ai_not_observed_internal(C,O) <=> true.
8709 ai_not_observed_internal(C,O) \ ai_not_observed_internal(C,O) <=> true.
8710 ai_observed_internal(C,O) \ ai_observed_internal(C,O) <=> true.
8712 ai_not_observed(C,O) \ ai_is_observed(C,O) <=> fail.
8713 ai_is_observed(_,_) <=> true.
8715 ai_observation_gather_results \ ai_observed_internal(C,O) <=> true. % ai_observed(C,O).
8716 ai_observation_gather_results \ ai_not_observed_internal(C,O) <=> ai_not_observed(C,O).
8717 ai_observation_gather_results <=> true.
8719 %------------------------------------------------------------------------------%
8720 % Main Analysis Entry
8721 %------------------------------------------------------------------------------%
8722 ai_observation_analysis(ACs) :-
8723 ( chr_pp_flag(ai_observation_analysis,on),
8724 get_target_module(Module), '$chr_compiled_with_version'(3) -> % , Module \== guard_entailment ->
8725 list_to_ord_set(ACs,ACSet),
8726 abstract_constraints(ACSet),
8727 ai_observation_schedule_initial_calls(ACSet,ACSet),
8728 ai_observation_gather_results
8733 ai_observation_schedule_initial_calls([],_).
8734 ai_observation_schedule_initial_calls([AC|RACs],ACs) :-
8735 ai_observation_schedule_initial_call(AC,ACs),
8736 ai_observation_schedule_initial_calls(RACs,ACs).
8738 ai_observation_schedule_initial_call(AC,ACs) :-
8739 ai_observation_top(AC,CallPattern),
8740 % ai_observation_bot(AC,ACs,CallPattern),
8741 initial_call_pattern(CallPattern).
8743 ai_observation_schedule_new_calls([],AP).
8744 ai_observation_schedule_new_calls([AC|ACs],AP) :-
8746 initial_call_pattern(odom(AC,Set)),
8747 ai_observation_schedule_new_calls(ACs,AP).
8749 final_answer_pattern(CP,AP1) \ final_answer_pattern(CP,AP2)
8751 ai_observation_leq(AP2,AP1)
8755 initial_call_pattern(CP) \ initial_call_pattern(CP) <=> true.
8757 initial_call_pattern(CP) ==> call_pattern(CP).
8759 initial_call_pattern(CP), final_answer_pattern(CP,AP), abstract_constraints(ACs) # ID3
8761 ai_observation_schedule_new_calls(ACs,AP)
8765 call_pattern(CP) \ call_pattern(CP) <=> true.
8767 depends_on(CP1,CP2), final_answer_pattern(CP2,AP) ==>
8768 final_answer_pattern(CP1,AP).
8770 %call_pattern(CP) ==> writeln(call_pattern(CP)).
8772 call_pattern(CP) ==> call_pattern_worker(CP).
8774 %------------------------------------------------------------------------------%
8776 %------------------------------------------------------------------------------%
8779 %call_pattern(odom([],Set)) ==>
8780 % final_answer_pattern(odom([],Set),odom([],Set)).
8782 call_pattern_worker(odom([],Set)) <=>
8783 % writeln(' - AbstractGoal'(odom([],Set))),
8784 final_answer_pattern(odom([],Set),odom([],Set)).
8787 call_pattern_worker(odom([G|Gs],Set)) <=>
8788 % writeln(' - AbstractGoal'(odom([G|Gs],Set))),
8790 depends_on_goal(odom([G|Gs],Set),CP1),
8793 depends_on_goal(CP1,CP2), final_answer_pattern(CP2,AP2) \ depends_on(CP1,_) # ID
8794 <=> true pragma passive(ID).
8795 depends_on_goal(CP1,CP2), final_answer_pattern(CP2,AP2)
8797 CP1 = odom([_|Gs],_),
8801 depends_on(CP1,CCP).
8803 %------------------------------------------------------------------------------%
8804 % Abstract Disjunction
8805 %------------------------------------------------------------------------------%
8807 call_pattern_worker(odom((AG1;AG2),Set)) <=>
8808 CP = odom((AG1;AG2),Set),
8809 InitialAnswerApproximation = odom([],Set),
8810 final_answer_pattern(CP,InitialAnswerApproximation),
8811 CP1 = odom(AG1,Set),
8812 CP2 = odom(AG2,Set),
8815 depends_on_as(CP,CP1,CP2).
8817 %------------------------------------------------------------------------------%
8819 %------------------------------------------------------------------------------%
8820 call_pattern_worker(odom(builtin,Set)) <=>
8821 % writeln(' - AbstractSolve'(odom(builtin,Set))),
8822 ord_empty(EmptySet),
8823 final_answer_pattern(odom(builtin,Set),odom([],EmptySet)).
8825 %------------------------------------------------------------------------------%
8827 %------------------------------------------------------------------------------%
8828 max_occurrence(C,MO) # ID2 \ call_pattern_worker(odom(occ(C,O),Set))
8832 % writeln(' - AbstractDrop'(odom(occ(C,O),Set))),
8833 final_answer_pattern(odom(occ(C,O),Set),odom([],Set))
8837 %------------------------------------------------------------------------------%
8839 %------------------------------------------------------------------------------%
8840 call_pattern_worker(odom(AC,Set))
8844 % writeln(' - AbstractActivate'(odom(AC,Set))),
8845 CP = odom(occ(AC,1),Set),
8847 depends_on(odom(AC,Set),CP).
8849 %------------------------------------------------------------------------------%
8851 %------------------------------------------------------------------------------%
8852 occurrence(C,O,RuleNb,ID,_) # ID2 \ call_pattern_worker(odom(occ(C,O),Set))
8854 is_passive(RuleNb,ID)
8856 % writeln(' - AbstractPassive'(odom(occ(C,O),Set))),
8859 DCP = odom(occ(C,NO),Set),
8861 final_answer_pattern(odom(occ(C,O),Set),odom([],Set)),
8862 depends_on(odom(occ(C,O),Set),DCP)
8865 %------------------------------------------------------------------------------%
8867 %------------------------------------------------------------------------------%
8870 occurrence(C,O,RuleNb,ID,simplification) # ID2 \ call_pattern_worker(odom(occ(C,O),Set))
8872 \+ is_passive(RuleNb,ID)
8874 % writeln(' - AbstractPassive'(odom(occ(C,O),Set))),
8875 ai_observation_memo_simplification_rest_heads(C,O,AbstractRestHeads),
8876 ai_observation_observe_set(Set,AbstractRestHeads,Set2),
8877 ai_observation_memo_abstract_goal(RuleNb,AG),
8878 call_pattern(odom(AG,Set2)),
8881 DCP = odom(occ(C,NO),Set),
8883 depends_on_as(odom(occ(C,O),Set),odom(AG,Set2),DCP),
8884 % DEADLOCK AVOIDANCE
8885 final_answer_pattern(odom(occ(C,O),Set),odom([],Set))
8889 depends_on_as(CP,CPS,CPD),
8890 final_answer_pattern(CPS,APS),
8891 final_answer_pattern(CPD,APD) ==>
8892 ai_observation_lub(APS,APD,AP),
8893 final_answer_pattern(CP,AP).
8897 ai_observation_memo_simplification_rest_heads/3,
8898 ai_observation_memoed_simplification_rest_heads/3.
8900 :- chr_option(mode,ai_observation_memo_simplification_rest_heads(+,+,?)).
8901 :- chr_option(mode,ai_observation_memoed_simplification_rest_heads(+,+,+)).
8903 ai_observation_memoed_simplification_rest_heads(C,O,RH) \ ai_observation_memo_simplification_rest_heads(C,O,QRH)
8906 abstract_constraints(ACs) # ID1, occurrence(C,O,RuleNb,ID,_) # ID2, rule(RuleNb,Rule) # ID3 \ ai_observation_memo_simplification_rest_heads(C,O,QRH)
8908 Rule = pragma(rule(H1,H2,_,_),ids(IDs1,_),_,_,_),
8909 once(select2(ID,_,IDs1,H1,_,RestH1)),
8910 ai_observation_abstract_constraints(RestH1,ACs,ARestHeads),
8911 ai_observation_abstract_constraints(H2,ACs,AH2),
8912 append(ARestHeads,AH2,AbstractHeads),
8913 sort(AbstractHeads,QRH),
8914 ai_observation_memoed_simplification_rest_heads(C,O,QRH)
8920 ai_observation_memo_simplification_rest_heads(_,_,_) <=> fail.
8922 %------------------------------------------------------------------------------%
8923 % Abstract Propagate
8924 %------------------------------------------------------------------------------%
8928 occurrence(C,O,RuleNb,ID,propagation) # ID2 \ call_pattern_worker(odom(occ(C,O),Set))
8930 \+ is_passive(RuleNb,ID)
8932 % writeln(' - AbstractPropagate'(odom(occ(C,O),Set))),
8934 ai_observation_memo_propagation_rest_heads(C,O,AHs),
8935 ai_observation_observe_set(Set,AHs,Set2),
8936 ord_add_element(Set2,C,Set3),
8937 ai_observation_memo_abstract_goal(RuleNb,AG),
8938 call_pattern(odom(AG,Set3)),
8939 ( ord_memberchk(C,Set2) ->
8946 DCP = odom(occ(C,NO),Set),
8948 depends_on_ap(odom(occ(C,O),Set),odom(AG,Set3),DCP,Delete)
8953 ai_observation_memo_propagation_rest_heads/3,
8954 ai_observation_memoed_propagation_rest_heads/3.
8956 :- chr_option(mode,ai_observation_memo_propagation_rest_heads(+,+,?)).
8957 :- chr_option(mode,ai_observation_memoed_propagation_rest_heads(+,+,+)).
8959 ai_observation_memoed_propagation_rest_heads(C,O,RH) \ ai_observation_memo_propagation_rest_heads(C,O,QRH)
8962 abstract_constraints(ACs) # ID1, occurrence(C,O,RuleNb,ID,_) # ID2, rule(RuleNb,Rule) # ID3 \ ai_observation_memo_propagation_rest_heads(C,O,QRH)
8964 Rule = pragma(rule(H1,H2,_,_),ids(_,IDs2),_,_,_),
8965 once(select2(ID,_,IDs2,H2,_,RestH2)),
8966 ai_observation_abstract_constraints(RestH2,ACs,ARestHeads),
8967 ai_observation_abstract_constraints(H1,ACs,AH1),
8968 append(ARestHeads,AH1,AbstractHeads),
8969 sort(AbstractHeads,QRH),
8970 ai_observation_memoed_propagation_rest_heads(C,O,QRH)
8976 ai_observation_memo_propagation_rest_heads(_,_,_) <=> fail.
8978 depends_on_ap(CP,CPP,CPD,Delete), final_answer_pattern(CPD,APD) ==>
8979 final_answer_pattern(CP,APD).
8980 depends_on_ap(CP,CPP,CPD,Delete), final_answer_pattern(CPP,APP),
8981 final_answer_pattern(CPD,APD) ==>
8983 CP = odom(occ(C,O),_),
8984 ( ai_observation_is_observed(APP,C) ->
8985 ai_observed_internal(C,O)
8987 ai_not_observed_internal(C,O)
8990 APP = odom([],Set0),
8991 ord_del_element(Set0,C,Set),
8996 ai_observation_lub(NAPP,APD,AP),
8997 final_answer_pattern(CP,AP).
8999 %------------------------------------------------------------------------------%
9001 %------------------------------------------------------------------------------%
9003 call_pattern_worker(CP) <=> chr_error(internal,'AI observation analysis: unexpected abstract state ~w\n',[CP]).
9005 %------------------------------------------------------------------------------%
9006 % Auxiliary Predicates
9007 %------------------------------------------------------------------------------%
9009 ai_observation_lub(odom(AG,S1),odom(AG,S2),odom(AG,S3)) :-
9010 ord_intersection(S1,S2,S3).
9012 ai_observation_bot(AG,AS,odom(AG,AS)).
9014 ai_observation_top(AG,odom(AG,EmptyS)) :-
9017 ai_observation_leq(odom(AG,S1),odom(AG,S2)) :-
9020 ai_observation_observe_set(S,ACSet,NS) :-
9021 ord_subtract(S,ACSet,NS).
9023 ai_observation_abstract_constraint(C,ACs,AC) :-
9028 ai_observation_abstract_constraints(Cs,ACs,NACs) :-
9029 findall(NAC,(member(C,Cs),ai_observation_abstract_constraint(C,ACs,NAC)),NACs).
9031 %------------------------------------------------------------------------------%
9032 % Abstraction of Rule Bodies
9033 %------------------------------------------------------------------------------%
9036 ai_observation_memoed_abstract_goal/2,
9037 ai_observation_memo_abstract_goal/2.
9039 :- chr_option(mode,ai_observation_memoed_abstract_goal(+,+)).
9040 :- chr_option(mode,ai_observation_memo_abstract_goal(+,?)).
9042 ai_observation_memoed_abstract_goal(RuleNb,AG) # ID1 \ ai_observation_memo_abstract_goal(RuleNb,QAG)
9048 rule(RuleNb,Rule) # ID1, abstract_constraints(ACs) # ID2 \ ai_observation_memo_abstract_goal(RuleNb,QAG)
9050 Rule = pragma(rule(H1,H2,Guard,Body),_,_,_,_),
9051 ai_observation_abstract_goal_(H1,H2,Guard,Body,ACs,AG),
9053 ai_observation_memoed_abstract_goal(RuleNb,AG)
9058 ai_observation_abstract_goal_(H1,H2,Guard,G,ACs,AG) :-
9059 % also guard: e.g. b, c(X) ==> Y=X | p(Y).
9060 term_variables((H1,H2,Guard),HVars),
9061 append(H1,H2,Heads),
9062 % variables that are declared to be ground are safe,
9063 ground_vars(Heads,GroundVars),
9064 % so we remove them from the list of 'dangerous' head variables
9065 list_difference_eq(HVars,GroundVars,HV),
9066 ai_observation_abstract_goal(G,ACs,AG,[],HV),!.
9067 % writeln(ai_observation_abstract_goal(G,ACs,AG,[],HV)).
9068 % HV are 'dangerous' variables, all others are fresh and safe
9071 ground_vars([H|Hs],GroundVars) :-
9073 get_constraint_mode(F/A,Mode),
9074 head_info(H,A,_Vars,_Susp,_HeadVars,HeadPairs),
9075 head_arg_matches(HeadPairs,Mode,[],_FirstMatching,_VarDict1,[],GroundVars1),
9076 ground_vars(Hs,GroundVars2),
9077 append(GroundVars1,GroundVars2,GroundVars).
9079 ai_observation_abstract_goal((G1,G2),ACs,List,Tail,HV) :- !, % conjunction
9080 ai_observation_abstract_goal(G1,ACs,List,IntermediateList,HV),
9081 ai_observation_abstract_goal(G2,ACs,IntermediateList,Tail,HV).
9082 ai_observation_abstract_goal((G1;G2),ACs,[(ABranch1;ABranch2)|Tail],Tail,HV) :- !, % disjunction
9083 ai_observation_abstract_goal(G1,ACs,ABranch1,[],HV),
9084 ai_observation_abstract_goal(G2,ACs,ABranch2,[],HV).
9085 ai_observation_abstract_goal((G1->G2),ACs,List,Tail,HV) :- !, % if-then
9086 ai_observation_abstract_goal(G1,ACs,List,IntermediateList,HV),
9087 ai_observation_abstract_goal(G2,ACs,IntermediateList,Tail,HV).
9088 ai_observation_abstract_goal(C,ACs,[AC|Tail],Tail,HV) :-
9089 ai_observation_abstract_constraint(C,ACs,AC), !. % CHR constraint
9090 ai_observation_abstract_goal(true,_,Tail,Tail,_) :- !.
9091 ai_observation_abstract_goal(writeln(_),_,Tail,Tail,_) :- !.
9092 % non-CHR constraint is safe if it only binds fresh variables
9093 ai_observation_abstract_goal(G,_,Tail,Tail,HV) :-
9094 builtin_binds_b(G,Vars),
9095 intersect_eq(Vars,HV,[]),
9097 ai_observation_abstract_goal(G,_,[AG|Tail],Tail,_) :-
9098 AG = builtin. % default case if goal is not recognized/safe
9100 ai_observation_is_observed(odom(_,ACSet),AC) :-
9101 \+ ord_memberchk(AC,ACSet).
9103 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9104 unconditional_occurrence(C,O) :-
9105 get_occurrence(C,O,RuleNb,ID),
9106 get_rule(RuleNb,PRule),
9107 PRule = pragma(ORule,_,_,_,_),
9108 copy_term_nat(ORule,Rule),
9109 Rule = rule(H1,H2,Guard,_),
9110 % writeq(guard_entailment:entails_guard([chr_pp_headvariables(H1,H2)],Guard)),nl,
9111 guard_entailment:entails_guard([chr_pp_headvariables(H1,H2)],Guard),
9113 H1 = [Head], H2 == []
9115 H2 = [Head], H1 == [], \+ may_trigger(C)
9119 unconditional_occurrence_args(Args).
9121 unconditional_occurrence_args([]).
9122 unconditional_occurrence_args([X|Xs]) :-
9125 unconditional_occurrence_args(Xs).
9127 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9129 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9130 % Partial wake analysis
9132 % In a Var = Var unification do not wake up constraints of both variables,
9133 % but rather only those of one variable.
9134 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9136 :- chr_constraint partial_wake_analysis/0.
9137 :- chr_constraint no_partial_wake/1.
9138 :- chr_option(mode,no_partial_wake(+)).
9139 :- chr_constraint wakes_partially/1.
9140 :- chr_option(mode,wakes_partially(+)).
9142 partial_wake_analysis, occurrence(FA,O,RuleNb,ID,Type), rule(RuleNb,Rule), constraint_mode(FA,ArgModes)
9144 Rule = pragma(rule(H1,H2,Guard,Body),_,_,_,_),
9145 ( is_passive(RuleNb,ID) ->
9147 ; Type == simplification ->
9148 select(H,H1,RestH1),
9150 term_variables(Guard,Vars),
9151 partial_wake_args(Args,ArgModes,Vars,FA)
9152 ; % Type == propagation ->
9153 select(H,H2,RestH2),
9155 term_variables(Guard,Vars),
9156 partial_wake_args(Args,ArgModes,Vars,FA)
9159 partial_wake_args([],_,_,_).
9160 partial_wake_args([Arg|Args],[Mode|Modes],Vars,C) :-
9164 ; memberchk_eq(Arg,Vars) ->
9172 partial_wake_args(Args,Modes,Vars,C).
9174 no_partial_wake(C) \ no_partial_wake(C) <=> true.
9176 no_partial_wake(C) \ wakes_partially(C) <=> fail.
9178 wakes_partially(C) <=> true.
9181 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9182 % Generate rules that implement chr_show_store/1 functionality.
9188 % Generates additional rules:
9190 % $show, C1 # ID ==> writeln(C1) pragma passive(ID).
9192 % $show, Cn # ID ==> writeln(Cn) pragma passive(ID).
9195 generate_show_constraint(Constraints0,Constraints,Rules0,Rules) :-
9196 ( chr_pp_flag(show,on) ->
9197 Constraints = ['$show'/0|Constraints0],
9198 generate_show_rules(Constraints0,Rules,[Rule|Rules0]),
9199 inc_rule_count(RuleNb),
9201 rule(['$show'],[],true,true),
9208 Constraints = Constraints0,
9212 generate_show_rules([],Rules,Rules).
9213 generate_show_rules([F/A|Rest],[Rule|Tail],Rules) :-
9215 inc_rule_count(RuleNb),
9217 rule([],['$show',C],true,writeln(C)),
9223 generate_show_rules(Rest,Tail,Rules).
9225 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9226 % Custom supension term layout
9228 static_suspension_term(F/A,Suspension) :-
9229 suspension_term_base(F/A,Base),
9231 functor(Suspension,suspension,Arity).
9233 has_suspension_field(FA,Field) :-
9234 suspension_term_base_fields(FA,Fields),
9235 memberchk(Field,Fields).
9237 suspension_term_base(FA,Base) :-
9238 suspension_term_base_fields(FA,Fields),
9239 length(Fields,Base).
9241 suspension_term_base_fields(FA,Fields) :-
9242 ( chr_pp_flag(debugable,on) ->
9245 % 3. Propagation History
9246 % 4. Generation Number
9247 % 5. Continuation Goal
9249 Fields = [id,state,history,generation,continuation,functor]
9251 ( uses_history(FA) ->
9252 Fields = [id,state,history|Fields2]
9253 ; only_ground_indexed_arguments(FA), get_functional_dependency(FA,1,_,_) ->
9254 Fields = [state|Fields2]
9256 Fields = [id,state|Fields2]
9258 ( only_ground_indexed_arguments(FA) ->
9259 get_store_type(FA,StoreType),
9260 basic_store_types(StoreType,BasicStoreTypes),
9261 ( memberchk(global_ground,BasicStoreTypes) ->
9264 % 3. Propagation History
9265 % 4. Global List Prev
9266 Fields2 = [global_list_prev|Fields3]
9270 % 3. Propagation History
9273 ( chr_pp_flag(ht_removal,on)
9274 -> ht_prev_fields(BasicStoreTypes,Fields3)
9277 ; may_trigger(FA) ->
9280 % 3. Propagation History
9281 ( uses_field(FA,generation) ->
9282 % 4. Generation Number
9283 % 5. Global List Prev
9284 Fields2 = [generation,global_list_prev|Fields3]
9286 Fields2 = [global_list_prev|Fields3]
9288 ( chr_pp_flag(mixed_stores,on),
9289 chr_pp_flag(ht_removal,on)
9290 -> get_store_type(FA,StoreType),
9291 basic_store_types(StoreType,BasicStoreTypes),
9292 ht_prev_fields(BasicStoreTypes,Fields3)
9298 % 3. Propagation History
9299 % 4. Global List Prev
9300 Fields2 = [global_list_prev|Fields3],
9301 ( chr_pp_flag(mixed_stores,on),
9302 chr_pp_flag(ht_removal,on)
9303 -> get_store_type(FA,StoreType),
9304 basic_store_types(StoreType,BasicStoreTypes),
9305 ht_prev_fields(BasicStoreTypes,Fields3)
9311 ht_prev_fields(Stores,Prevs) :-
9312 ht_prev_fields_int(Stores,PrevsList),
9313 append(PrevsList,Prevs).
9314 ht_prev_fields_int([],[]).
9315 ht_prev_fields_int([H|T],Fields) :-
9316 ( H = multi_hash(Indexes)
9317 -> maplist(ht_prev_field,Indexes,FH),
9321 ht_prev_fields_int(T,FT).
9323 ht_prev_field(Index,Field) :-
9325 -> atom_concat('multi_hash_prev-',Index,Field)
9327 -> concat_atom(['multi_hash_prev-'|Index],Field)
9330 get_static_suspension_term_field(FieldName,FA,StaticSuspension,Field) :-
9331 suspension_term_base_fields(FA,Fields),
9332 nth(Index,Fields,FieldName), !,
9333 arg(Index,StaticSuspension,Field).
9334 get_static_suspension_term_field(arguments,FA,StaticSuspension,Field) :- !,
9335 suspension_term_base(FA,Base),
9336 StaticSuspension =.. [_|Args],
9337 drop(Base,Args,Field).
9338 get_static_suspension_term_field(FieldName,FA,_StaticSuspension,_Field) :-
9339 chr_error(internal,'Trying to obtain field ~w of ~w, wich does not have it!',[FieldName,FA]).
9342 get_dynamic_suspension_term_field(FieldName,FA,DynamicSuspension,Field,Goal) :-
9343 suspension_term_base_fields(FA,Fields),
9344 nth(Index,Fields,FieldName), !,
9345 Goal = arg(Index,DynamicSuspension,Field).
9346 get_dynamic_suspension_term_field(arguments,FA,DynamicSuspension,Field,Goal) :- !,
9347 static_suspension_term(FA,StaticSuspension),
9348 get_static_suspension_term_field(arguments,FA,StaticSuspension,Field),
9349 Goal = (DynamicSuspension = StaticSuspension).
9350 get_dynamic_suspension_term_field(argument(I),FA,DynamicSuspension,Field,Goal) :- !,
9351 suspension_term_base(FA,Base),
9353 Goal = arg(Index,DynamicSuspension,Field).
9354 get_dynamic_suspension_term_field(FieldName,FA,_DynamicSuspension,_Field,_Goal) :-
9355 chr_error(internal,'Dynamic goal to get ~w of ~w, which does not have this field!',[FieldName,FA]).
9358 set_dynamic_suspension_term_field(FieldName,FA,DynamicSuspension,Field,Goal) :-
9359 suspension_term_base_fields(FA,Fields),
9360 nth(Index,Fields,FieldName), !,
9361 Goal = setarg(Index,DynamicSuspension,Field).
9362 set_dynamic_suspension_term_field(FieldName,FA,_DynamicSuspension,_Field,_Goal) :-
9363 chr_error(internal,'Dynamic goal to set ~w of ~w, which does not have this field!',[FieldName,FA]).
9365 basic_store_types(multi_store(Types),Types) :- !.
9366 basic_store_types(Type,[Type]).
9368 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9375 :- chr_option(mode,phase_end(+)).
9376 :- chr_option(mode,delay_phase_end(+,?)).
9378 phase_end(Phase) \ delay_phase_end(Phase,Goal) <=> call(Goal).
9379 % phase_end(Phase) <=> true.
9382 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9386 novel_production_call/4.
9388 :- chr_option(mode,uses_history(+)).
9389 :- chr_option(mode,does_use_history(+,+)).
9390 :- chr_option(mode,novel_production_call(+,+,?,?)).
9392 does_use_history(FA,Occ) \ does_use_history(FA,Occ) <=> true.
9393 does_use_history(FA,_) \ uses_history(FA) <=> true.
9394 uses_history(_FA) <=> fail.
9396 does_use_history(FA,Occ) \ novel_production_call(FA,Occ,PossibleGoal,Goal) <=> Goal = PossibleGoal.
9397 novel_production_call(FA,_,_PossibleGoal,Goal) <=> Goal = true.
9403 :- chr_option(mode,uses_field(+,+)).
9404 :- chr_option(mode,does_use_field(+,+)).
9406 does_use_field(FA,Field) \ does_use_field(FA,Field) <=> true.
9407 does_use_field(FA,Field) \ uses_field(FA,Field) <=> true.
9408 uses_field(_FA,_Field) <=> fail.
9413 used_states_known/0.
9415 :- chr_option(mode,uses_state(+,+)).
9416 :- chr_option(mode,if_used_state(+,+,?,?,?)).
9419 % states ::= not_stored_yet | passive | active | triggered | removed
9421 % allocate CREATES not_stored_yet
9422 % remove CHECKS not_stored_yet
9423 % activate CHECKS not_stored_yet
9425 % ==> no allocate THEN no not_stored_yet
9427 % recurs CREATES inactive
9428 % lookup CHECKS inactive
9430 % insert CREATES active
9431 % activate CREATES active
9432 % lookup CHECKS active
9433 % recurs CHECKS active
9435 % runsusp CREATES triggered
9436 % lookup CHECKS triggered
9438 % ==> no runsusp THEN no triggered
9440 % remove CREATES removed
9441 % runsusp CHECKS removed
9442 % lookup CHECKS removed
9443 % recurs CHECKS removed
9445 % ==> no remove THEN no removed
9447 % ==> no allocate, no remove, no active/inactive distinction THEN no state at all...
9449 uses_state(Constraint,State) \ uses_state(Constraint,State) <=> true.
9451 used_states_known, uses_state(Constraint,State) \ if_used_state(Constraint,State,Used,NotUsed,ResultGoal)
9452 <=> ResultGoal = Used.
9453 used_states_known \ if_used_state(Constraint,State,Used,NotUsed,ResultGoal)
9454 <=> ResultGoal = NotUsed.
9456 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9457 % CHECK STOREDNESS ANNOTATIONS AND GENERATE DEFAULT SIMPLIFICATION RULES
9463 % When the programmer enables the `declare_stored_constraints' option, i.e. writes
9465 % :- chr_option(declare_stored_constraints,on).
9467 % the compiler will check for the storedness of constraints.
9469 % By default, the compiler assumes that the programmer wants his constraints to
9470 % be never-stored. Hence, a warning will be issues when a constraint is actually
9473 % Such warnings are suppressed, if the programmer adds the `# stored' modifier
9474 % to a constraint declaration, i.e. writes
9476 % :- chr_constraint c(...) # stored.
9478 % In that case a warning is issued when the constraint is never-stored.
9480 % NOTE: Checking is only performed if `storage_analysis' is on. Otherwise, all
9481 % constraints are stored anyway.
9484 % 2. Rule Generation
9485 % ~~~~~~~~~~~~~~~~~~
9487 % When the programmer enables the `declare_stored_constraints' option, i.e. writes
9489 % :- chr_option(declare_stored_constraints,on).
9491 % the compiler will generate default simplification rules for constraints.
9493 % By default, no default rule is generated for a constraint. However, if the
9494 % programmer writes a default/1 annotation in the constraint declaration, i.e. writes
9496 % :- chr_constraint c(...) # default(Goal).
9498 % where `Goal' is a ground and callable goal (e.g. `true', `fail' or `throw(error)'),
9499 % the compiler generates a rule:
9501 % c(_,...,_) <=> Goal.
9503 % at the end of the program. If multiple default rules are generated, for several constraints,
9504 % then the order of the default rules is not specified.
9507 :- chr_constraint stored_assertion/1.
9508 :- chr_option(mode,stored_assertion(+)).
9509 :- chr_option(type_declaration,stored_assertion(constraint)).
9511 :- chr_constraint never_stored_default/2.
9512 :- chr_option(mode,never_stored_default(+,?)).
9513 :- chr_option(type_declaration,never_stored_default(constraint,any)).
9518 generate_never_stored_rules(Constraints,Rules) :-
9519 ( chr_pp_flag(declare_stored_constraints,on) ->
9520 never_stored_rules(Constraints,Rules)
9525 :- chr_constraint never_stored_rules/2.
9526 :- chr_option(mode,never_stored_rules(+,?)).
9527 :- chr_option(type_declaration,never_stored_rules(list(constraint),any)).
9529 never_stored_rules([],Rules) <=> Rules = [].
9530 never_stored_default(Constraint,Goal) \ never_stored_rules([Constraint|Constraints],Rules) <=>
9533 inc_rule_count(RuleNb),
9535 rule([Head],[],true,Goal),
9541 Rules = [Rule|Tail],
9542 never_stored_rules(Constraints,Tail).
9543 never_stored_rules([_|Constraints],Rules) <=>
9544 never_stored_rules(Constraints,Rules).
9549 check_storedness_assertions(Constraints) :-
9550 ( chr_pp_flag(storage_analysis,on), chr_pp_flag(declare_stored_constraints,on) ->
9551 forall(Constraint,Constraints,check_storedness_assertion(Constraint))
9557 :- chr_constraint check_storedness_assertion/1.
9558 :- chr_option(mode,check_storedness_assertion(+)).
9559 :- chr_option(type_declaration,check_storedness_assertion(constraint)).
9561 check_storedness_assertion(Constraint), stored_assertion(Constraint)
9562 <=> ( is_stored(Constraint) ->
9565 chr_warning(assertion_failed,'Constraint ~w is not stored. However, it was asserted to be stored.\n',[Constraint])
9567 never_stored_default(Constraint,_) \ check_storedness_assertion(Constraint)
9568 <=> ( is_finally_stored(Constraint) ->
9569 chr_warning(assertion_failed,'Constraint ~w is stored. However, it was asserted not to be stored.\n',[Constraint])
9570 ; is_stored(Constraint) ->
9571 chr_warning(assertion_failed,'Constraint ~w is temporarily stored. However, it was asserted not to be stored.\n',[Constraint])
9575 % never-stored, no default goal
9576 check_storedness_assertion(Constraint)
9577 <=> ( is_finally_stored(Constraint) ->
9578 chr_warning(assertion_failed,'Constraint ~w is stored. However, it was asserted not to be stored.\n',[Constraint])
9579 ; is_stored(Constraint) ->
9580 chr_warning(assertion_failed,'Constraint ~w is temporarily stored. However, it was asserted not to be stored.\n',[Constraint])