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))
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).
211 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
213 %------------------------------------------------------------------------------%
214 :- chr_constraint chr_source_file/1.
215 :- chr_option(mode,chr_source_file(+)).
216 :- chr_option(type_declaration,chr_source_file(module_name)).
217 %------------------------------------------------------------------------------%
218 chr_source_file(_) \ chr_source_file(_) <=> true.
220 %------------------------------------------------------------------------------%
221 :- chr_constraint get_chr_source_file/1.
222 :- chr_option(mode,get_chr_source_file(-)).
223 :- chr_option(type_declaration,get_chr_source_file(module_name)).
224 %------------------------------------------------------------------------------%
225 chr_source_file(Mod) \ get_chr_source_file(Query)
227 get_chr_source_file(Query)
231 %------------------------------------------------------------------------------%
232 :- chr_constraint target_module/1.
233 :- chr_option(mode,target_module(+)).
234 :- chr_option(type_declaration,target_module(module_name)).
235 %------------------------------------------------------------------------------%
236 target_module(_) \ target_module(_) <=> true.
238 %------------------------------------------------------------------------------%
239 :- chr_constraint get_target_module/1.
240 :- chr_option(mode,get_target_module(-)).
241 :- chr_option(type_declaration,get_target_module(module_name)).
242 %------------------------------------------------------------------------------%
243 target_module(Mod) \ get_target_module(Query)
245 get_target_module(Query)
248 %------------------------------------------------------------------------------%
249 :- chr_constraint line_number/2.
250 :- chr_option(mode,line_number(+,+)).
251 %------------------------------------------------------------------------------%
252 line_number(RuleNb,LineNb) \ line_number(RuleNb,LineNumber) <=> true.
254 %------------------------------------------------------------------------------%
255 :- chr_constraint get_line_number/2.
256 :- chr_option(mode,get_line_number(+,-)).
257 %------------------------------------------------------------------------------%
258 line_number(RuleNb,LineNb) \ get_line_number(RuleNb,Q) <=> Q = LineNb.
259 get_line_number(RuleNb,Q) <=> Q = 0. % no line number available
261 :- chr_constraint indexed_argument/2. % argument instantiation may enable applicability of rule
262 :- chr_option(mode,indexed_argument(+,+)).
263 :- chr_option(type_declaration,indexed_argument(constraint,int)).
265 :- chr_constraint is_indexed_argument/2.
266 :- chr_option(mode,is_indexed_argument(+,+)).
267 :- chr_option(type_declaration,is_indexed_argument(constraint,int)).
269 :- chr_constraint constraint_mode/2.
270 :- chr_option(mode,constraint_mode(+,+)).
271 :- chr_option(type_declaration,constraint_mode(constraint,list)).
273 :- chr_constraint get_constraint_mode/2.
274 :- chr_option(mode,get_constraint_mode(+,-)).
275 :- chr_option(type_declaration,get_constraint_mode(constraint,list)).
277 :- chr_constraint may_trigger/1.
278 :- chr_option(mode,may_trigger(+)).
279 :- chr_option(type_declaration,may_trigger(constraint)).
281 :- chr_constraint only_ground_indexed_arguments/1.
282 :- chr_option(mode,only_ground_indexed_arguments(+)).
283 :- chr_option(type_declaration,only_ground_indexed_arguments(constraint)).
285 :- chr_constraint none_suspended_on_variables/0.
287 :- chr_constraint are_none_suspended_on_variables/0.
289 :- chr_constraint store_type/2.
290 :- chr_option(mode,store_type(+,+)).
291 :- chr_option(type_declaration,store_type(constraint,store_type)).
293 :- chr_constraint get_store_type/2.
294 :- chr_option(mode,get_store_type(+,?)).
295 :- chr_option(type_declaration,get_store_type(constraint,store_type)).
297 :- chr_constraint update_store_type/2.
298 :- chr_option(mode,update_store_type(+,+)).
299 :- chr_option(type_declaration,update_store_type(constraint,store_type)).
301 :- chr_constraint actual_store_types/2.
302 :- chr_option(mode,actual_store_types(+,+)).
303 :- chr_option(type_declaration,actual_store_types(constraint,list(store_type))).
305 :- chr_constraint assumed_store_type/2.
306 :- chr_option(mode,assumed_store_type(+,+)).
307 :- chr_option(type_declaration,assumed_store_type(constraint,store_type)).
309 :- chr_constraint validate_store_type_assumption/1.
310 :- chr_option(mode,validate_store_type_assumption(+)).
311 :- chr_option(type_declaration,validate_store_type_assumption(constraint)).
313 :- chr_constraint rule_count/1.
314 :- chr_option(mode,rule_count(+)).
315 :- chr_option(type_declaration,rule_count(natural)).
317 :- chr_constraint inc_rule_count/1.
318 :- chr_option(mode,inc_rule_count(-)).
319 :- chr_option(type_declaration,inc_rule_count(natural)).
321 rule_count(_) \ rule_count(_)
323 rule_count(C), inc_rule_count(NC)
324 <=> NC is C + 1, rule_count(NC).
326 <=> NC = 1, rule_count(NC).
328 :- chr_constraint passive/2.
329 :- chr_option(mode,passive(+,+)).
331 :- chr_constraint is_passive/2.
332 :- chr_option(mode,is_passive(+,+)).
334 :- chr_constraint any_passive_head/1.
335 :- chr_option(mode,any_passive_head(+)).
337 :- chr_constraint new_occurrence/4.
338 :- chr_option(mode,new_occurrence(+,+,+,+)).
340 :- chr_constraint occurrence/5.
341 :- chr_option(mode,occurrence(+,+,+,+,+)).
342 :- chr_type occurrence_type ---> simplification ; propagation.
343 :- chr_option(type_declaration,occurrence(any,any,any,any,occurrence_type)).
345 :- chr_constraint get_occurrence/4.
346 :- chr_option(mode,get_occurrence(+,+,-,-)).
348 :- chr_constraint get_occurrence_from_id/4.
349 :- chr_option(mode,get_occurrence_from_id(+,-,+,+)).
351 :- chr_constraint max_occurrence/2.
352 :- chr_option(mode,max_occurrence(+,+)).
354 :- chr_constraint get_max_occurrence/2.
355 :- chr_option(mode,get_max_occurrence(+,-)).
357 :- chr_constraint allocation_occurrence/2.
358 :- chr_option(mode,allocation_occurrence(+,+)).
360 :- chr_constraint get_allocation_occurrence/2.
361 :- chr_option(mode,get_allocation_occurrence(+,-)).
363 :- chr_constraint rule/2.
364 :- chr_option(mode,rule(+,+)).
365 :- chr_option(type_declaration,rule(rule_nb,pragma_rule)).
367 :- chr_constraint get_rule/2.
368 :- chr_option(mode,get_rule(+,-)).
369 :- chr_option(type_declaration,get_rule(int,pragma_rule)).
371 :- chr_constraint least_occurrence/2.
372 :- chr_option(mode,least_occurrence(+,+)).
373 :- chr_option(type_declaration,least_occurrence(any,list)).
375 :- chr_constraint is_least_occurrence/1.
376 :- chr_option(mode,is_least_occurrence(+)).
379 indexed_argument(FA,I) \ indexed_argument(FA,I) <=> true.
380 indexed_argument(FA,I) \ is_indexed_argument(FA,I) <=> true.
381 is_indexed_argument(_,_) <=> fail.
383 %%% C O N S T R A I N T M O D E %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
385 constraint_mode(FA,_) \ constraint_mode(FA,_) <=> true.
386 constraint_mode(FA,Mode) \ get_constraint_mode(FA,Q) <=>
388 get_constraint_mode(FA,Q) <=>
392 %%% M A Y T R I G G E R %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
394 may_trigger(FA) <=> \+ has_active_occurrence(FA) | fail.
395 constraint_mode(FA,Mode), indexed_argument(FA,I) \ may_trigger(FA) <=>
399 may_trigger(FA) <=> chr_pp_flag(debugable,on). % in debug mode, we assume everything can be triggered
401 constraint_mode(FA,Mode), indexed_argument(FA,I) \ only_ground_indexed_arguments(FA)
407 only_ground_indexed_arguments(_) <=>
410 none_suspended_on_variables \ none_suspended_on_variables <=> true.
411 none_suspended_on_variables \ are_none_suspended_on_variables <=> true.
412 are_none_suspended_on_variables <=> fail.
413 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
415 store_type(FA,Store) \ get_store_type(FA,Query)
418 assumed_store_type(FA,Store) \ get_store_type(FA,Query)
420 get_store_type(_,Query)
423 actual_store_types(C,STs) \ update_store_type(C,ST)
424 <=> member(ST,STs) | true.
425 update_store_type(C,ST), actual_store_types(C,STs)
427 actual_store_types(C,[ST|STs]).
428 update_store_type(C,ST)
430 actual_store_types(C,[ST]).
432 % refine store type assumption
433 validate_store_type_assumption(C) \ actual_store_types(C,STs), actual_atomic_multi_hash_keys(C,Index,Keys)
435 delete(STs,multi_hash([Index]),STs0),
436 /* writeln(actual_store_types(C,[atomic_constants(Index,Keys)|STs0])), */
437 actual_store_types(C,[atomic_constants(Index,Keys)|STs0]).
438 validate_store_type_assumption(C) \ actual_store_types(C,STs), actual_ground_multi_hash_keys(C,Index,Keys)
440 delete(STs,multi_hash([Index]),STs0),
441 /* writeln(actual_store_types(C,[ground_constants(Index,Keys)|STs0])), */
442 actual_store_types(C,[ground_constants(Index,Keys)|STs0]).
443 validate_store_type_assumption(C) \ actual_store_types(C,STs)
445 memberchk(multi_hash([[Index]]),STs),
446 get_constraint_type(C,Types),
447 nth1(Index,Types,Type),
448 enumerated_atomic_type(Type,Atoms)
450 delete(STs,multi_hash([[Index]]),STs0),
451 writeln(actual_store_types(C,[atomic_constants([Index],Atoms)|STs0])),
452 actual_store_types(C,[atomic_constants([Index],Atoms)|STs0]).
453 validate_store_type_assumption(C), actual_store_types(C,STs), assumed_store_type(C,_) % automatic assumption
455 ( STs = [ground_constants(_,_)] ->
456 store_type(C,multi_store([global_ground|STs]))
458 store_type(C,multi_store(STs))
460 validate_store_type_assumption(C), actual_store_types(C,STs), store_type(C,_) % user assumption
462 store_type(C,multi_store(STs)).
463 validate_store_type_assumption(C), assumed_store_type(C,_) % no lookups on constraint in debug mode
465 chr_pp_flag(debugable,on)
467 store_type(C,default).
468 validate_store_type_assumption(C), assumed_store_type(C,_) % no lookups on constraint
469 <=> store_type(C,global_ground).
470 validate_store_type_assumption(C)
473 %%% P A S S I V E %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
474 passive(R,ID) \ passive(R,ID) <=> true.
476 passive(RuleNb,ID) \ is_passive(RuleNb,ID) <=> true.
477 is_passive(_,_) <=> fail.
479 passive(RuleNb,_) \ any_passive_head(RuleNb)
483 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
485 max_occurrence(C,N) \ max_occurrence(C,M)
488 max_occurrence(C,MO), new_occurrence(C,RuleNb,ID,Type) <=>
490 occurrence(C,NO,RuleNb,ID,Type),
491 max_occurrence(C,NO).
492 new_occurrence(C,RuleNb,ID,_) <=>
493 chr_error(internal,'new_occurrence: missing max_occurrence for ~w in rule ~w\n',[C,RuleNb]).
495 max_occurrence(C,MON) \ get_max_occurrence(C,Q)
497 get_max_occurrence(C,Q)
498 <=> chr_error(internal,'get_max_occurrence: missing max occurrence for ~w\n',[C]).
500 occurrence(C,ON,Rule,ID,_) \ get_occurrence(C,ON,QRule,QID)
501 <=> Rule = QRule, ID = QID.
502 get_occurrence(C,O,_,_)
503 <=> chr_error(internal,'get_occurrence: missing occurrence ~w:~w\n',[C,O]).
505 occurrence(C,ON,Rule,ID,_) \ get_occurrence_from_id(QC,QON,Rule,ID)
506 <=> QC = C, QON = ON.
507 get_occurrence_from_id(C,O,_,_)
508 <=> chr_error(internal,'get_occurrence_from_id: missing occurrence ~w:~w\n',[]).
510 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
513 late_allocation_analysis(Cs) :-
514 ( chr_pp_flag(late_allocation,on) ->
515 maplist(late_allocation, Cs)
520 late_allocation(C) :- late_allocation(C,0).
521 late_allocation(C,O) :- allocation_occurrence(C,O), !.
522 late_allocation(C,O) :- NO is O + 1, late_allocation(C,NO).
524 % A L L O C C A T I O N O C C U R R E N C E %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
526 allocation_occurrence(C,0) ==> stored_in_guard_before_next_kept_occurrence(C,0).
528 rule(RuleNb,Rule), occurrence(C,O,RuleNb,Id,Type), allocation_occurrence(C,O) ==>
529 \+ is_passive(RuleNb,Id),
531 ( stored_in_guard_before_next_kept_occurrence(C,O) ->
533 ; Rule = pragma(rule([_|_],_,_,_),_,_,_,_) -> % simpagation rule
535 ; is_least_occurrence(RuleNb) -> % propagation rule
541 stored_in_guard_before_next_kept_occurrence(C,O) :-
542 chr_pp_flag(store_in_guards, on),
544 stored_in_guard_lookahead(C,NO).
546 :- chr_constraint stored_in_guard_lookahead/2.
547 :- chr_option(mode, stored_in_guard_lookahead(+,+)).
549 occurrence(C,O,RuleNb,Id,_), passive(RuleNb,Id) \ stored_in_guard_lookahead(C,O) <=>
550 NO is O + 1, stored_in_guard_lookahead(C,NO).
551 occurrence(C,O,RuleNb,Id,Type) \ stored_in_guard_lookahead(C,O) <=>
552 Type == simplification,
553 ( is_stored_in_guard(C,RuleNb) ->
556 NO is O + 1, stored_in_guard_lookahead(C,NO)
558 stored_in_guard_lookahead(_,_) <=> fail.
561 rule(RuleNb,Rule), occurrence(C,O,RuleNb,ID,_), allocation_occurrence(C,AO)
562 \ least_occurrence(RuleNb,[ID|IDs])
563 <=> AO >= O, \+ may_trigger(C) |
564 least_occurrence(RuleNb,IDs).
565 rule(RuleNb,Rule), passive(RuleNb,ID)
566 \ least_occurrence(RuleNb,[ID|IDs])
567 <=> least_occurrence(RuleNb,IDs).
570 ==> Rule = pragma(rule([],_,_,_),ids([],IDs),_,_,_) |
571 least_occurrence(RuleNb,IDs).
573 least_occurrence(RuleNb,[]) \ is_least_occurrence(RuleNb)
575 is_least_occurrence(_)
578 allocation_occurrence(C,O) \ get_allocation_occurrence(C,Q)
580 get_allocation_occurrence(_,Q)
581 <=> chr_pp_flag(late_allocation,off), Q=0.
582 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
584 rule(RuleNb,Rule) \ get_rule(RuleNb,Q)
589 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
591 %%% C O N S T R A I N T I N D E X %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
593 % Default store constraint index assignment.
595 :- chr_constraint constraint_index/2. % constraint_index(F/A,DefaultStoreAndAttachedIndex)
596 :- chr_option(mode,constraint_index(+,+)).
597 :- chr_option(type_declaration,constraint_index(constraint,int)).
599 :- chr_constraint get_constraint_index/2.
600 :- chr_option(mode,get_constraint_index(+,-)).
601 :- chr_option(type_declaration,get_constraint_index(constraint,int)).
603 :- chr_constraint get_indexed_constraint/2.
604 :- chr_option(mode,get_indexed_constraint(+,-)).
605 :- chr_option(type_declaration,get_indexed_constraint(int,constraint)).
607 :- chr_constraint max_constraint_index/1. % max_constraint_index(MaxDefaultStoreAndAttachedIndex)
608 :- chr_option(mode,max_constraint_index(+)).
609 :- chr_option(type_declaration,max_constraint_index(int)).
611 :- chr_constraint get_max_constraint_index/1.
612 :- chr_option(mode,get_max_constraint_index(-)).
613 :- chr_option(type_declaration,get_max_constraint_index(int)).
615 constraint_index(C,Index) \ get_constraint_index(C,Query)
617 get_constraint_index(C,Query)
620 constraint_index(C,Index) \ get_indexed_constraint(Index,Q)
622 get_indexed_constraint(Index,Q)
625 max_constraint_index(Index) \ get_max_constraint_index(Query)
627 get_max_constraint_index(Query)
630 set_constraint_indices(Constraints) :-
631 set_constraint_indices(Constraints,1).
632 set_constraint_indices([],M) :-
634 max_constraint_index(N).
635 set_constraint_indices([C|Cs],N) :-
636 ( ( chr_pp_flag(debugable, on) ; \+ only_ground_indexed_arguments(C), is_stored(C) ; is_stored(C), get_store_type(C,default)
637 ; get_store_type(C,var_assoc_store(_,_))) ->
638 constraint_index(C,N),
640 set_constraint_indices(Cs,M)
642 set_constraint_indices(Cs,N)
645 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
648 :- chr_constraint identifier_size/1.
649 :- chr_option(mode,identifier_size(+)).
650 :- chr_option(type_declaration,identifier_size(natural)).
652 identifier_size(_) \ identifier_size(_)
656 :- chr_constraint get_identifier_size/1.
657 :- chr_option(mode,get_identifier_size(-)).
658 :- chr_option(type_declaration,get_identifier_size(natural)).
660 identifier_size(Size) \ get_identifier_size(Q)
664 get_identifier_size(Q)
668 :- chr_constraint identifier_index/3.
669 :- chr_option(mode,identifier_index(+,+,+)).
670 :- chr_option(type_declaration,identifier_index(constraint,natural,natural)).
672 identifier_index(C,I,_) \ identifier_index(C,I,_)
676 :- chr_constraint get_identifier_index/3.
677 :- chr_option(mode,get_identifier_index(+,+,-)).
678 :- chr_option(type_declaration,get_identifier_index(constraint,natural,natural)).
680 identifier_index(C,I,II) \ get_identifier_index(C,I,Q)
683 identifier_size(Size), get_identifier_index(C,I,Q)
686 identifier_index(C,I,NSize),
687 identifier_size(NSize),
689 get_identifier_index(C,I,Q)
691 identifier_index(C,I,2),
695 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
696 % Type Indexed Identifier Indexes
698 :- chr_constraint type_indexed_identifier_size/2.
699 :- chr_option(mode,type_indexed_identifier_size(+,+)).
700 :- chr_option(type_declaration,type_indexed_identifier_size(any,natural)).
702 type_indexed_identifier_size(IndexType,_) \ type_indexed_identifier_size(IndexType,_)
706 :- chr_constraint get_type_indexed_identifier_size/2.
707 :- chr_option(mode,get_type_indexed_identifier_size(+,-)).
708 :- chr_option(type_declaration,get_type_indexed_identifier_size(any,natural)).
710 type_indexed_identifier_size(IndexType,Size) \ get_type_indexed_identifier_size(IndexType,Q)
714 get_type_indexed_identifier_size(IndexType,Q)
718 :- chr_constraint type_indexed_identifier_index/4.
719 :- chr_option(mode,type_indexed_identifier_index(+,+,+,+)).
720 :- chr_option(type_declaration,type_indexed_identifier_index(any,constraint,natural,natural)).
722 type_indexed_identifier_index(_,C,I,_) \ type_indexed_identifier_index(_,C,I,_)
726 :- chr_constraint get_type_indexed_identifier_index/4.
727 :- chr_option(mode,get_type_indexed_identifier_index(+,+,+,-)).
728 :- chr_option(type_declaration,get_type_indexed_identifier_index(any,constraint,natural,natural)).
730 type_indexed_identifier_index(IndexType,C,I,II) \ get_type_indexed_identifier_index(IndexType,C,I,Q)
733 type_indexed_identifier_size(IndexType,Size), get_type_indexed_identifier_index(IndexType,C,I,Q)
736 type_indexed_identifier_index(IndexType,C,I,NSize),
737 type_indexed_identifier_size(IndexType,NSize),
739 get_type_indexed_identifier_index(IndexType,C,I,Q)
741 type_indexed_identifier_index(IndexType,C,I,2),
742 type_indexed_identifier_size(IndexType,2),
745 type_indexed_identifier_structure(IndexType,Structure) :-
746 type_indexed_identifier_name(IndexType,type_indexed_identifier_struct,Functor),
747 get_type_indexed_identifier_size(IndexType,Arity),
748 functor(Structure,Functor,Arity).
749 type_indexed_identifier_name(IndexType,Prefix,Name) :-
751 IndexTypeName = IndexType
753 term_to_atom(IndexType,IndexTypeName)
755 atom_concat_list([Prefix,'_',IndexTypeName],Name).
757 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
762 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
766 chr_translate(Declarations,NewDeclarations) :-
767 chr_translate_line_info(Declarations,'bootstrap',NewDeclarations).
769 chr_translate_line_info(Declarations,File,NewDeclarations) :-
770 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',[]),
772 chr_source_file(File),
773 partition_clauses(Declarations,Constraints0,Rules0,OtherClauses),
774 chr_compiler_options:sanity_check,
775 check_declared_constraints(Constraints0),
776 generate_show_constraint(Constraints0,Constraints,Rules0,Rules1),
777 add_constraints(Constraints),
779 generate_never_stored_rules(Constraints,NewRules),
781 append(Rules1,NewRules,Rules),
783 check_rules(Rules,Constraints),
784 time('type checking',chr_translate:static_type_check),
785 add_occurrences(Rules),
786 time('functional dependency',chr_translate:functional_dependency_analysis(Rules)),
787 time('set semantics',chr_translate:set_semantics_rules(Rules)),
788 time('symmetry analysis',chr_translate:symmetry_analysis(Rules)),
789 time('guard simplification',chr_translate:guard_simplification),
790 time('late storage',chr_translate:storage_analysis(Constraints)),
791 time('observation',chr_translate:observation_analysis(Constraints)),
792 time('ai observation',chr_translate:ai_observation_analysis(Constraints)),
793 time('late allocation',chr_translate:late_allocation_analysis(Constraints)),
794 partial_wake_analysis,
795 time('assume constraint stores',chr_translate:assume_constraint_stores(Constraints)),
796 time('default constraint indices',chr_translate:set_constraint_indices(Constraints)),
797 time('check storedness assertions',chr_translate:check_storedness_assertions(Constraints)),
799 time('constraint code generation',chr_translate:constraints_code(Constraints,ConstraintClauses)),
800 time('validate store assumptions',chr_translate:validate_store_type_assumptions(Constraints)),
801 phase_end(validate_store_type_assumptions),
803 time('store code generation',chr_translate:store_management_preds(Constraints,StoreClauses)), % depends on actual code used
804 insert_declarations(OtherClauses, Clauses0),
805 chr_module_declaration(CHRModuleDeclaration),
806 append([StoreClauses,ConstraintClauses,CHRModuleDeclaration,[end_of_file]],StuffyGeneratedClauses),
807 clean_clauses(StuffyGeneratedClauses,GeneratedClauses),
808 append([Clauses0,GeneratedClauses], NewDeclarations).
810 store_management_preds(Constraints,Clauses) :-
811 generate_attach_detach_a_constraint_all(Constraints,AttachAConstraintClauses),
812 generate_attr_unify_hook(AttrUnifyHookClauses),
813 generate_attach_increment(AttachIncrementClauses),
814 generate_extra_clauses(Constraints,ExtraClauses),
815 generate_insert_delete_constraints(Constraints,DeleteClauses),
816 generate_attach_code(Constraints,StoreClauses),
817 generate_counter_code(CounterClauses),
818 generate_dynamic_type_check_clauses(TypeCheckClauses),
819 append([AttachAConstraintClauses
820 ,AttachIncrementClauses
821 ,AttrUnifyHookClauses
831 insert_declarations(Clauses0, Clauses) :-
832 findall(:- use_module(chr(Module)),(auxiliary_module(Module), is_used_auxiliary_module(Module)),Decls),
833 append(Clauses0, [:- use_module(chr(chr_runtime))|Decls], Clauses).
835 auxiliary_module(chr_hashtable_store).
836 auxiliary_module(chr_integertable_store).
837 auxiliary_module(chr_assoc_store).
839 generate_counter_code(Clauses) :-
840 ( chr_pp_flag(store_counter,on) ->
842 ('$counter_init'(N1) :- nb_setval(N1,0)) ,
843 ('$counter'(N2,X1) :- nb_getval(N2,X1)),
844 ('$counter_inc'(N) :- nb_getval(N,X), Y is X + 1, nb_setval(N,Y)),
845 (:- '$counter_init'('$insert_counter')),
846 (:- '$counter_init'('$delete_counter')),
847 ('$insert_counter_inc' :- '$counter_inc'('$insert_counter')),
848 ('$delete_counter_inc' :- '$counter_inc'('$delete_counter')),
849 ( counter_stats(I,D) :- '$counter'('$insert_counter',I),'$counter'('$delete_counter',D))
855 % for systems with multifile declaration
856 chr_module_declaration(CHRModuleDeclaration) :-
857 get_target_module(Mod),
858 ( Mod \== chr_translate, chr_pp_flag(toplevel_show_store,on) ->
859 CHRModuleDeclaration = [
860 (:- multifile chr:'$chr_module'/1),
861 chr:'$chr_module'(Mod)
864 CHRModuleDeclaration = []
868 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
870 %% Partitioning of clauses into constraint declarations, chr rules and other
873 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
874 %% partition_clauses(+Clauses,-ConstraintDeclarations,-Rules,-OtherClauses) is det.
875 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
876 partition_clauses([],[],[],[]).
877 partition_clauses([Clause|Clauses],ConstraintDeclarations,Rules,OtherClauses) :-
878 ( parse_rule(Clause,Rule) ->
879 ConstraintDeclarations = RestConstraintDeclarations,
880 Rules = [Rule|RestRules],
881 OtherClauses = RestOtherClauses
882 ; is_declaration(Clause,ConstraintDeclaration) ->
883 append(ConstraintDeclaration,RestConstraintDeclarations,ConstraintDeclarations),
885 OtherClauses = RestOtherClauses
886 ; is_module_declaration(Clause,Mod) ->
888 ConstraintDeclarations = RestConstraintDeclarations,
890 OtherClauses = [Clause|RestOtherClauses]
891 ; is_type_definition(Clause) ->
892 ConstraintDeclarations = RestConstraintDeclarations,
894 OtherClauses = RestOtherClauses
895 ; Clause = (handler _) ->
896 chr_warning(deprecated(Clause),'Backward compatibility: ignoring handler/1 declaration.\n',[]),
897 ConstraintDeclarations = RestConstraintDeclarations,
899 OtherClauses = RestOtherClauses
900 ; Clause = (rules _) ->
901 chr_warning(deprecated(Clause),'Backward compatibility: ignoring rules/1 declaration.\n',[]),
902 ConstraintDeclarations = RestConstraintDeclarations,
904 OtherClauses = RestOtherClauses
905 ; Clause = option(OptionName,OptionValue) ->
906 chr_warning(deprecated(Clause),'Instead use `:-chr_option(~w,~w).\'\n',[OptionName,OptionValue]),
907 handle_option(OptionName,OptionValue),
908 ConstraintDeclarations = RestConstraintDeclarations,
910 OtherClauses = RestOtherClauses
911 ; Clause = (:-chr_option(OptionName,OptionValue)) ->
912 handle_option(OptionName,OptionValue),
913 ConstraintDeclarations = RestConstraintDeclarations,
915 OtherClauses = RestOtherClauses
916 ; Clause = ('$chr_compiled_with_version'(_)) ->
917 ConstraintDeclarations = RestConstraintDeclarations,
919 OtherClauses = ['$chr_compiled_with_version'(3)|RestOtherClauses]
920 ; ConstraintDeclarations = RestConstraintDeclarations,
922 OtherClauses = [Clause|RestOtherClauses]
924 partition_clauses(Clauses,RestConstraintDeclarations,RestRules,RestOtherClauses).
926 '$chr_compiled_with_version'(2).
928 is_declaration(D, Constraints) :- %% constraint declaration
929 ( D = (:- Decl), Decl =.. [F,Cs], F == (chr_constraint) ->
930 conj2list(Cs,Constraints0)
933 Decl =.. [constraints,Cs]
935 D =.. [constraints,Cs]
937 conj2list(Cs,Constraints0),
938 chr_warning(deprecated(D),'Instead use :- chr_constraint ~w.\n',[Cs])
940 extract_type_mode(Constraints0,Constraints).
942 extract_type_mode([],[]).
943 extract_type_mode([F/A|R],[F/A|R2]) :- !,extract_type_mode(R,R2).
944 extract_type_mode([C0|R],[ConstraintSymbol|R2]) :-
945 ( C0 = C # Annotation ->
947 extract_annotation(Annotation,F/A)
952 ConstraintSymbol = F/A,
954 extract_types_and_modes(Args,ArgTypes,ArgModes),
955 constraint_type(ConstraintSymbol,ArgTypes),
956 constraint_mode(ConstraintSymbol,ArgModes),
957 extract_type_mode(R,R2).
959 extract_annotation(stored,Symbol) :-
960 stored_assertion(Symbol).
961 extract_annotation(default(Goal),Symbol) :-
962 never_stored_default(Symbol,Goal).
964 extract_types_and_modes([],[],[]).
965 extract_types_and_modes([X|R],[T|R2],[M|R3]) :-
966 extract_type_and_mode(X,T,M),
967 extract_types_and_modes(R,R2,R3).
969 extract_type_and_mode(+(T),T,(+)) :- !.
970 extract_type_and_mode(?(T),T,(?)) :- !.
971 extract_type_and_mode(-(T),T,(-)) :- !.
972 extract_type_and_mode((+),any,(+)) :- !.
973 extract_type_and_mode((?),any,(?)) :- !.
974 extract_type_and_mode((-),any,(-)) :- !.
975 extract_type_and_mode(Illegal,_,_) :-
976 chr_error(syntax(Illegal),'Illegal mode/type declaration.\n\tCorrect syntax is +type, -type or ?type\n\tor +, - or ?.\n',[]).
978 is_type_definition(Declaration) :-
979 ( Declaration = (:- TDef) ->
984 TDef =.. [chr_type,TypeDef],
985 ( TypeDef = (Name ---> Def) ->
986 tdisj2list(Def,DefList),
987 type_definition(Name,DefList)
988 ; TypeDef = (Alias == Name) ->
989 type_alias(Alias,Name)
991 type_definition(TypeDef,[]),
992 chr_warning(syntax,'Empty type definition `~w\'.\nAre you sure you want to declare a phantom type?\n',[Declaration])
995 %% tdisj2list(+Goal,-ListOfGoals) is det.
997 % no removal of fails, e.g. :- type bool ---> true ; fail.
998 tdisj2list(Conj,L) :-
999 tdisj2list(Conj,L,[]).
1001 tdisj2list(Conj,L,T) :-
1003 tdisj2list(G1,L,T1),
1004 tdisj2list(G2,T1,T).
1005 tdisj2list(G,[G | T],T).
1008 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
1009 %% parse_rule(+term,-pragma_rule) is semidet.
1010 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
1011 parse_rule(RI,R) :- %% name @ rule
1012 RI = (Name @ RI2), !,
1013 rule(RI2,yes(Name),R).
1017 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
1018 %% parse_rule(+term,-pragma_rule) is semidet.
1019 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
1021 RI = (RI2 pragma P), !, %% pragmas
1023 Ps = [_] % intercept variable
1027 inc_rule_count(RuleCount),
1028 R = pragma(R1,IDs,Ps,Name,RuleCount),
1029 is_rule(RI2,R1,IDs,R).
1031 inc_rule_count(RuleCount),
1032 R = pragma(R1,IDs,[],Name,RuleCount),
1033 is_rule(RI,R1,IDs,R).
1035 is_rule(RI,R,IDs,RC) :- %% propagation rule
1037 conj2list(H,Head2i),
1038 get_ids(Head2i,IDs2,Head2,RC),
1041 R = rule([],Head2,G,RB)
1043 R = rule([],Head2,true,B)
1045 is_rule(RI,R,IDs,RC) :- %% simplification/simpagation rule
1054 conj2list(H1,Head2i),
1055 conj2list(H2,Head1i),
1056 get_ids(Head2i,IDs2,Head2,0,N,RC),
1057 get_ids(Head1i,IDs1,Head1,N,_,RC),
1058 IDs = ids(IDs1,IDs2)
1059 ; conj2list(H,Head1i),
1061 get_ids(Head1i,IDs1,Head1,RC),
1064 R = rule(Head1,Head2,Guard,Body).
1066 get_ids(Cs,IDs,NCs,RC) :-
1067 get_ids(Cs,IDs,NCs,0,_,RC).
1069 get_ids([],[],[],N,N,_).
1070 get_ids([C|Cs],[N|IDs],[NC|NCs],N,NN,RC) :-
1075 check_direct_pragma(N1,N,RC)
1081 get_ids(Cs,IDs,NCs, M,NN,RC).
1083 check_direct_pragma(passive,Id,PragmaRule) :- !,
1084 PragmaRule = pragma(_,_,_,_,RuleNb),
1086 check_direct_pragma(Abbrev,Id,PragmaRule) :-
1087 ( direct_pragma(FullPragma),
1088 atom_concat(Abbrev,Remainder,FullPragma) ->
1089 chr_warning(problem_pragma(Abbrev,PragmaRule),'completed `~w\' to `~w\'\n',[Abbrev,FullPragma])
1091 chr_warning(unsupported_pragma(Abbrev,PragmaRule),'',[])
1094 direct_pragma(passive).
1096 is_module_declaration((:- module(Mod)),Mod).
1097 is_module_declaration((:- module(Mod,_)),Mod).
1099 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1101 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1103 add_constraints([]).
1104 add_constraints([C|Cs]) :-
1105 max_occurrence(C,0),
1109 constraint_mode(C,Mode),
1110 add_constraints(Cs).
1114 add_rules([Rule|Rules]) :-
1115 Rule = pragma(_,_,_,_,RuleNb),
1119 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1121 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1122 %% Some input verification:
1124 check_declared_constraints(Constraints) :-
1125 check_declared_constraints(Constraints,[]).
1127 check_declared_constraints([],_).
1128 check_declared_constraints([C|Cs],Acc) :-
1129 ( memberchk_eq(C,Acc) ->
1130 chr_error(syntax(C),'Constraint multiply defined: ~w.\n\tRemove redundant declaration!\n',[C])
1134 check_declared_constraints(Cs,[C|Acc]).
1136 %% - all constraints in heads are declared constraints
1137 %% - all passive pragmas refer to actual head constraints
1140 check_rules([PragmaRule|Rest],Decls) :-
1141 check_rule(PragmaRule,Decls),
1142 check_rules(Rest,Decls).
1144 check_rule(PragmaRule,Decls) :-
1145 check_rule_indexing(PragmaRule),
1146 check_trivial_propagation_rule(PragmaRule),
1147 PragmaRule = pragma(Rule,_IDs,Pragmas,_Name,_N),
1148 Rule = rule(H1,H2,_,_),
1149 append(H1,H2,HeadConstraints),
1150 check_head_constraints(HeadConstraints,Decls,PragmaRule),
1151 check_pragmas(Pragmas,PragmaRule).
1153 % Make all heads passive in trivial propagation rule
1154 % ... ==> ... | true.
1155 check_trivial_propagation_rule(PragmaRule) :-
1156 PragmaRule = pragma(Rule,IDs,Pragmas,Name,RuleNb),
1157 ( Rule = rule([],_,_,true) ->
1158 chr_warning(weird_program,'Ignoring propagation rule with empty body: ~@.\n\t\n',[format_rule(PragmaRule)]),
1159 set_all_passive(RuleNb)
1164 check_head_constraints([],_,_).
1165 check_head_constraints([Constr|Rest],Decls,PragmaRule) :-
1166 functor(Constr,F,A),
1167 ( member(F/A,Decls) ->
1168 check_head_constraints(Rest,Decls,PragmaRule)
1170 chr_error(syntax(Constr),'Undeclared constraint ~w in head of ~@.\n\tConstraint should be one of ~w.\n', [F/A,format_rule(PragmaRule),Decls])
1173 check_pragmas([],_).
1174 check_pragmas([Pragma|Pragmas],PragmaRule) :-
1175 check_pragma(Pragma,PragmaRule),
1176 check_pragmas(Pragmas,PragmaRule).
1178 check_pragma(Pragma,PragmaRule) :-
1180 chr_error(syntax(Pragma),'Invalid pragma ~w in ~@.\n\tPragma should not be a variable!\n',[Pragma,format_rule(PragmaRule)]).
1181 check_pragma(passive(ID), PragmaRule) :-
1183 PragmaRule = pragma(_,ids(IDs1,IDs2),_,_,RuleNb),
1184 ( memberchk_eq(ID,IDs1) ->
1186 ; memberchk_eq(ID,IDs2) ->
1189 chr_error(syntax(ID),'Invalid identifier ~w in pragma passive in ~@.\n', [ID,format_rule(PragmaRule)])
1193 check_pragma(mpassive(IDs), PragmaRule) :-
1195 PragmaRule = pragma(_,_,_,_,RuleNb),
1196 chr_warning(experimental,'Experimental pragma ~w. Use with care!\n',[mpassive(IDs)]),
1197 maplist(passive(RuleNb),IDs).
1199 check_pragma(Pragma, PragmaRule) :-
1200 Pragma = already_in_heads,
1202 chr_warning(unsupported_pragma(Pragma,PragmaRule),'Termination and correctness may be affected.\n',[]).
1204 check_pragma(Pragma, PragmaRule) :-
1205 Pragma = already_in_head(_),
1207 chr_warning(unsupported_pragma(Pragma,PragmaRule),'Termination and correctness may be affected.\n',[]).
1209 check_pragma(Pragma, PragmaRule) :-
1210 Pragma = no_history,
1212 chr_warning(experimental,'Experimental pragma no_history. Use with care!\n',[]),
1213 PragmaRule = pragma(_,_,_,_,N),
1216 check_pragma(Pragma, PragmaRule) :-
1217 Pragma = history(HistoryName,IDs),
1219 PragmaRule = pragma(_,ids(IDs1,IDs2),_,_,RuleNb),
1220 chr_warning(experimental,'Experimental pragma ~w. Use with care!\n',[Pragma]),
1222 chr_error(syntax(Pragma),'Pragma history only implemented for propagation rules.\n',[])
1223 ; \+ atom(HistoryName) ->
1224 chr_error(syntax(Pragma),'Illegal argument for pragma history: ~w is not an atom (rule number ~w).\n',[HistoryName,RuleNb])
1226 chr_error(syntax(Pragma),'Illegal argument for pragma history: ~w is not a set (rule number ~w).\n',[IDs,RuleNb])
1227 ; check_history_pragma_ids(IDs,IDs1,IDs2) ->
1228 history(RuleNb,HistoryName,IDs)
1230 chr_error(syntax(Pragma),'Invalid identifier(s) in pragma ~w of rule number ~w.\n',[Pragma,RuleNb])
1232 check_pragma(Pragma,PragmaRule) :-
1233 Pragma = line_number(LineNumber),
1235 PragmaRule = pragma(_,_,_,_,RuleNb),
1236 line_number(RuleNb,LineNumber).
1238 check_history_pragma_ids([], _, _).
1239 check_history_pragma_ids([ID|IDs],IDs1,IDs2) :-
1240 ( memberchk_eq(ID,IDs2) ; memberchk_eq(ID,IDs1) ),
1241 check_history_pragma_ids(IDs,IDs1,IDs2).
1243 check_pragma(Pragma,PragmaRule) :-
1244 chr_error(syntax(Pragma),'Unknown pragma ~w in ~@.\n', [Pragma,format_rule(PragmaRule)]).
1246 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1247 %% no_history(+RuleNb) is det.
1248 :- chr_constraint no_history/1.
1249 :- chr_option(mode,no_history(+)).
1250 :- chr_option(type_declaration,no_history(int)).
1252 %% has_no_history(+RuleNb) is semidet.
1253 :- chr_constraint has_no_history/1.
1254 :- chr_option(mode,has_no_history(+)).
1255 :- chr_option(type_declaration,has_no_history(int)).
1257 no_history(RuleNb) \ has_no_history(RuleNb) <=> true.
1258 has_no_history(_) <=> fail.
1260 :- chr_constraint history/3.
1261 :- chr_option(mode,history(+,+,+)).
1262 :- chr_option(type_declaration,history(any,any,list)).
1264 :- chr_constraint named_history/3.
1266 history(RuleNb,_,_), history(RuleNb,_,_) ==>
1267 chr_error(syntax,'Only one pragma history allowed per rule (rule number ~w)\n',[RuleNb]). %'
1269 history(RuleNb1,Name,IDs1), history(RuleNb2,Name,IDs2) ==>
1270 length(IDs1,L1), length(IDs2,L2),
1272 chr_error(syntax,'The history named ~w does not always range over an equal amount of occurrences.\n',[Name])
1274 test_named_history_id_pairs(RuleNb1,IDs1,RuleNb2,IDs2)
1277 test_named_history_id_pairs(_, [], _, []).
1278 test_named_history_id_pairs(RuleNb1, [ID1|IDs1], RuleNb2, [ID2|IDs2]) :-
1279 test_named_history_id_pair(RuleNb1,ID1,RuleNb2,ID2),
1280 test_named_history_id_pairs(RuleNb1,IDs1,RuleNb2,IDs2).
1282 :- chr_constraint test_named_history_id_pair/4.
1283 :- chr_option(mode,test_named_history_id_pair(+,+,+,+)).
1285 occurrence(C,_,RuleNb1,ID1,_), occurrence(C,_,RuleNb2,ID2,_)
1286 \ test_named_history_id_pair(RuleNb1,ID1,RuleNb2,ID2) <=> true.
1287 test_named_history_id_pair(RuleNb1,ID1,RuleNb2,ID2) <=>
1288 chr_error(syntax,'Occurrences of shared history in rules number ~w and ~w do not correspond\n', [RuleNb2,RuleNb1]).
1290 history(RuleNb,Name,IDs) \ named_history(RuleNb,QName,QIDs) <=> QName = Name, QIDs = IDs.
1291 named_history(_,_,_) <=> fail.
1293 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1296 format_rule(PragmaRule) :-
1297 PragmaRule = pragma(_,_,_,MaybeName,RuleNumber),
1298 ( MaybeName = yes(Name) ->
1299 write('rule '), write(Name)
1301 write('rule number '), write(RuleNumber)
1303 get_line_number(RuleNumber,LineNumber),
1308 check_rule_indexing(PragmaRule) :-
1309 PragmaRule = pragma(Rule,_,_,_,_),
1310 Rule = rule(H1,H2,G,_),
1311 term_variables(H1-H2,HeadVars),
1312 remove_anti_monotonic_guards(G,HeadVars,NG),
1313 check_indexing(H1,NG-H2),
1314 check_indexing(H2,NG-H1),
1316 ( chr_pp_flag(term_indexing,on) ->
1317 term_variables(NG,GuardVariables),
1318 append(H1,H2,Heads),
1319 check_specs_indexing(Heads,GuardVariables,Specs)
1324 :- chr_constraint indexing_spec/2.
1325 :- chr_option(mode,indexing_spec(+,+)).
1327 :- chr_constraint get_indexing_spec/2.
1328 :- chr_option(mode,get_indexing_spec(+,-)).
1331 indexing_spec(FA,Spec) \ get_indexing_spec(FA,R) <=> R = Spec.
1332 get_indexing_spec(_,Spec) <=> Spec = [].
1334 indexing_spec(FA,Specs1), indexing_spec(FA,Specs2)
1336 append(Specs1,Specs2,Specs),
1337 indexing_spec(FA,Specs).
1339 remove_anti_monotonic_guards(G,Vars,NG) :-
1341 remove_anti_monotonic_guard_list(GL,Vars,NGL),
1344 remove_anti_monotonic_guard_list([],_,[]).
1345 remove_anti_monotonic_guard_list([G|Gs],Vars,NGs) :-
1346 ( G = var(X), memberchk_eq(X,Vars) ->
1348 % TODO: this is not correct
1349 % ; G = functor(Term,Functor,Arity), % isotonic
1350 % \+ memberchk_eq(Functor,Vars), \+ memberchk_eq(Arity,Vars) ->
1355 remove_anti_monotonic_guard_list(Gs,Vars,RGs).
1357 check_indexing([],_).
1358 check_indexing([Head|Heads],Other) :-
1361 term_variables(Heads-Other,OtherVars),
1362 check_indexing(Args,1,F/A,OtherVars),
1363 check_indexing(Heads,[Head|Other]).
1365 check_indexing([],_,_,_).
1366 check_indexing([Arg|Args],I,FA,OtherVars) :-
1367 ( is_indexed_argument(FA,I) ->
1370 indexed_argument(FA,I)
1372 term_variables(Args,ArgsVars),
1373 append(ArgsVars,OtherVars,RestVars),
1374 ( memberchk_eq(Arg,RestVars) ->
1375 indexed_argument(FA,I)
1381 term_variables(Arg,NVars),
1382 append(NVars,OtherVars,NOtherVars),
1383 check_indexing(Args,J,FA,NOtherVars).
1385 check_specs_indexing([],_,[]).
1386 check_specs_indexing([Head|Heads],Variables,Specs) :-
1387 Specs = [Spec|RSpecs],
1388 term_variables(Heads,OtherVariables,Variables),
1389 check_spec_indexing(Head,OtherVariables,Spec),
1390 term_variables(Head,NVariables,Variables),
1391 check_specs_indexing(Heads,NVariables,RSpecs).
1393 check_spec_indexing(Head,OtherVariables,Spec) :-
1395 Spec = spec(F,A,ArgSpecs),
1397 check_args_spec_indexing(Args,1,OtherVariables,ArgSpecs),
1398 indexing_spec(F/A,[ArgSpecs]).
1400 check_args_spec_indexing([],_,_,[]).
1401 check_args_spec_indexing([Arg|Args],I,OtherVariables,ArgSpecs) :-
1402 term_variables(Args,Variables,OtherVariables),
1403 ( check_arg_spec_indexing(Arg,I,Variables,ArgSpec) ->
1404 ArgSpecs = [ArgSpec|RArgSpecs]
1406 ArgSpecs = RArgSpecs
1409 term_variables(Arg,NOtherVariables,OtherVariables),
1410 check_args_spec_indexing(Args,J,NOtherVariables,RArgSpecs).
1412 check_arg_spec_indexing(Arg,I,Variables,ArgSpec) :-
1414 memberchk_eq(Arg,Variables),
1415 ArgSpec = specinfo(I,any,[])
1418 ArgSpec = specinfo(I,F/A,[ArgSpecs]),
1420 check_args_spec_indexing(Args,1,Variables,ArgSpecs)
1423 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1425 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1428 add_occurrences([]).
1429 add_occurrences([Rule|Rules]) :-
1430 Rule = pragma(rule(H1,H2,_,_),ids(IDs1,IDs2),_,_,Nb),
1431 add_occurrences(H1,IDs1,simplification,Nb),
1432 add_occurrences(H2,IDs2,propagation,Nb),
1433 add_occurrences(Rules).
1435 add_occurrences([],[],_,_).
1436 add_occurrences([H|Hs],[ID|IDs],Type,RuleNb) :-
1439 new_occurrence(FA,RuleNb,ID,Type),
1440 add_occurrences(Hs,IDs,Type,RuleNb).
1442 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1444 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1445 % Observation Analysis
1455 :- chr_constraint observation_analysis/1.
1456 :- chr_option(mode, observation_analysis(+)).
1458 observation_analysis(Cs), rule(RuleNb,PragmaRule) # Id ==>
1459 PragmaRule = pragma(rule(_,_,Guard,Body),_,_,_,_),
1460 ( chr_pp_flag(store_in_guards, on) ->
1461 observation_analysis(RuleNb, Guard, guard, Cs)
1465 observation_analysis(RuleNb, Body, body, Cs)
1468 observation_analysis(_) <=> true.
1470 observation_analysis(RuleNb, Term, GB, Cs) :-
1471 ( all_spawned(RuleNb,GB) ->
1474 spawns_all(RuleNb,GB)
1482 observation_analysis(RuleNb,T1,GB,Cs),
1483 observation_analysis(RuleNb,T2,GB,Cs)
1485 observation_analysis(RuleNb,T1,GB,Cs),
1486 observation_analysis(RuleNb,T2,GB,Cs)
1487 ; Term = (T1->T2) ->
1488 observation_analysis(RuleNb,T1,GB,Cs),
1489 observation_analysis(RuleNb,T2,GB,Cs)
1491 observation_analysis(RuleNb,T,GB,Cs)
1492 ; functor(Term,F,A), member(F/A,Cs) ->
1493 spawns(RuleNb,GB,F/A)
1495 spawns_all_triggers(RuleNb,GB)
1496 ; Term = (_ is _) ->
1497 spawns_all_triggers(RuleNb,GB)
1498 ; builtin_binds_b(Term,Vars) ->
1502 spawns_all_triggers(RuleNb,GB)
1505 spawns_all(RuleNb,GB)
1508 :- chr_constraint spawns/3.
1509 :- chr_option(mode, spawns(+,+,+)).
1510 :- chr_type spawns_type ---> guard ; body.
1511 :- chr_option(type_declaration,spawns(any,spawns_type,any)).
1513 :- chr_constraint spawns_all/2, spawns_all_triggers/2.
1514 :- chr_option(mode, spawns_all(+,+)).
1515 :- chr_option(type_declaration,spawns_all(any,spawns_type)).
1516 :- chr_option(mode, spawns_all_triggers(+,+)).
1517 :- chr_option(type_declaration,spawns_all_triggers(any,spawns_type)).
1519 spawns_all(RuleNb,GB) \ spawns_all(RuleNb,GB) <=> true.
1520 spawns_all(RuleNb,guard) \ spawns_all(RuleNb,body) <=> true.
1521 spawns_all_triggers(RuleNb,GB) \ spawns_all_triggers(RuleNb,GB) <=> true.
1522 spawns_all_triggers(RuleNb,guard) \ spawns_all_triggers(RuleNb,body) <=> true.
1523 spawns(RuleNb,GB,C) \ spawns(RuleNb,GB,C) <=> true.
1524 spawns(RuleNb,guard,C) \ spawns(RuleNb,body,C) <=> true.
1526 spawns_all(RuleNb,GB) \ spawns(RuleNb,GB,_) <=> true.
1527 spawns_all(RuleNb,guard) \ spawns(RuleNb,body,_) <=> true.
1528 spawns_all(RuleNb,GB) \ spawns_all_triggers(RuleNb,GB) <=> true.
1529 spawns_all(RuleNb,guard) \ spawns_all_triggers(RuleNb,body) <=> true.
1531 spawns_all_triggers(RuleNb,GB) \ spawns(RuleNb,GB,C) <=> may_trigger(C) | true.
1532 spawns_all_triggers(RuleNb,guard) \ spawns(RuleNb,body,C) <=> may_trigger(C) | true.
1534 spawns_all(RuleNb2,_), occurrence(C1,_,RuleNb2,O,_)#Id
1536 spawns(RuleNb1,GB,C1)
1538 \+ is_passive(RuleNb2,O)
1540 spawns_all(RuleNb1,GB)
1544 occurrence(C1,_,RuleNb2,O,_)#Id, spawns_all(RuleNb2,_)
1546 \+(\+ spawns_all_triggers_implies_spawns_all), % in the hope it schedules this guard early...
1547 \+ is_passive(RuleNb2,O), may_trigger(C1)
1549 spawns_all_triggers_implies_spawns_all
1553 :- chr_constraint spawns_all_triggers_implies_spawns_all/0.
1554 spawns_all_triggers_implies_spawns_all, spawns_all_triggers_implies_spawns_all <=> fail.
1555 spawns_all_triggers_implies_spawns_all \
1556 spawns_all_triggers(RuleNb,GB) <=> spawns_all(RuleNb,GB).
1558 spawns_all_triggers(RuleNb2,_), occurrence(C1,_,RuleNb2,O,_)#Id
1560 spawns(RuleNb1,GB,C1)
1563 \+ is_passive(RuleNb2,O)
1565 spawns_all_triggers(RuleNb1,GB)
1569 spawns_all_triggers(RuleNb2,_), occurrence(C1,_,RuleNb2,O,_)#Id,
1570 spawns(RuleNb1,GB,C1)
1573 \+ is_passive(RuleNb2,O)
1575 spawns_all_triggers(RuleNb1,GB)
1579 % a bit dangerous this rule: could start propagating too much too soon?
1580 spawns(RuleNb2,_,C2), occurrence(C1,_,RuleNb2,O,_)#Id,
1581 spawns(RuleNb1,GB,C1)
1583 RuleNb1 \== RuleNb2, C1 \== C2,
1584 \+ is_passive(RuleNb2,O)
1586 spawns(RuleNb1,GB,C2)
1590 spawns(RuleNb2,_,C2), occurrence(C1,_,RuleNb2,O,_)#Id,
1591 spawns_all_triggers(RuleNb1,GB)
1593 \+ is_passive(RuleNb2,O), may_trigger(C1), \+ may_trigger(C2)
1595 spawns(RuleNb1,GB,C2)
1600 :- chr_constraint all_spawned/2.
1601 :- chr_option(mode, all_spawned(+,+)).
1602 spawns_all(RuleNb,guard) \ all_spawned(RuleNb,_) <=> true.
1603 spawns_all(RuleNb,GB) \ all_spawned(RuleNb,GB) <=> true.
1604 all_spawned(RuleNb,GB) <=> fail.
1607 % Overview of the supported queries:
1608 % is_observed(+functor/artiy, +occurrence_number, +(guard;body))
1609 % only succeeds if the occurrence is observed by the
1610 % guard resp. body (depending on the last argument) of its rule
1611 % is_observed(+functor/artiy, +occurrence_number, -)
1612 % succeeds if the occurrence is observed by either the guard or
1613 % the body of its rule
1614 % NOTE: the last argument is NOT bound by this query
1616 % do_is_observed(+functor/artiy,+rule_number,+(guard;body))
1617 % succeeds if the given constraint is observed by the given
1619 % do_is_observed(+functor/artiy,+rule_number)
1620 % succeeds if the given constraint is observed by the given
1621 % rule (either its guard or its body)
1626 ai_is_observed(C,O).
1628 is_stored_in_guard(C,RuleNb) :-
1629 chr_pp_flag(store_in_guards, on),
1630 do_is_observed(C,RuleNb,guard).
1632 :- chr_constraint is_observed/3.
1633 :- chr_option(mode, is_observed(+,+,+)).
1634 occurrence(C,O,RuleNb,_,_) \ is_observed(C,O,GB) <=> do_is_observed(C,RuleNb,GB).
1635 is_observed(_,_,_) <=> fail. % this will not happen in practice
1638 :- chr_constraint do_is_observed/3.
1639 :- chr_option(mode, do_is_observed(+,+,+)).
1640 :- chr_constraint do_is_observed/2.
1641 :- chr_option(mode, do_is_observed(+,+)).
1643 do_is_observed(C,RuleNb,GB) <=> var(GB) | do_is_observed(C,RuleNb).
1646 % a constraint C is observed if the GB of the rule it occurs in spawns all,
1647 % and some non-passive occurrence of some (possibly other) constraint
1648 % exists in a rule (could be same rule) with at least one occurrence of C
1650 spawns_all(RuleNb,GB),
1651 occurrence(_,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1653 do_is_observed(C,RuleNb,GB)
1655 \+ is_passive(RuleNb2,O)
1659 spawns_all(RuleNb,_),
1660 occurrence(_,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1662 do_is_observed(C,RuleNb)
1664 \+ is_passive(RuleNb2,O)
1669 % a constraint C is observed if the GB of the rule it occurs in spawns a
1670 % constraint C2 that occurs non-passively in a rule (possibly the same rule)
1671 % as an occurrence of C
1673 spawns(RuleNb,GB,C2),
1674 occurrence(C2,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1676 do_is_observed(C,RuleNb,GB)
1678 \+ is_passive(RuleNb2,O)
1682 spawns(RuleNb,_,C2),
1683 occurrence(C2,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1685 do_is_observed(C,RuleNb)
1687 \+ is_passive(RuleNb2,O)
1691 % (3) spawns_all_triggers
1692 % a constraint C is observed if the GB of the rule it occurs in spawns all triggers
1693 % and some non-passive occurrence of some (possibly other) constraint that may trigger
1694 % exists in a rule (could be same rule) with at least one occurrence of C
1696 spawns_all_triggers(RuleNb,GB),
1697 occurrence(C2,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1699 do_is_observed(C,RuleNb,GB)
1701 \+ is_passive(RuleNb2,O), may_trigger(C2)
1705 spawns_all_triggers(RuleNb,_),
1706 occurrence(C2,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1708 do_is_observed(C,RuleNb)
1710 \+ is_passive(RuleNb2,O), may_trigger(C2)
1714 % (4) conservativeness
1715 do_is_observed(_,_,_) <=> chr_pp_flag(observation_analysis,off).
1716 do_is_observed(_,_) <=> chr_pp_flag(observation_analysis,off).
1719 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1721 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1724 %% Generated predicates
1725 %% attach_$CONSTRAINT
1727 %% detach_$CONSTRAINT
1730 %% attach_$CONSTRAINT
1731 generate_attach_detach_a_constraint_all([],[]).
1732 generate_attach_detach_a_constraint_all([Constraint|Constraints],Clauses) :-
1733 ( ( chr_pp_flag(debugable,on) ; is_stored(Constraint), \+ only_ground_indexed_arguments(Constraint), \+ get_store_type(Constraint,var_assoc_store(_,_)) ) ->
1734 generate_attach_a_constraint(Constraint,Clauses1),
1735 generate_detach_a_constraint(Constraint,Clauses2)
1740 generate_attach_detach_a_constraint_all(Constraints,Clauses3),
1741 append([Clauses1,Clauses2,Clauses3],Clauses).
1743 generate_attach_a_constraint(Constraint,[Clause1,Clause2]) :-
1744 generate_attach_a_constraint_nil(Constraint,Clause1),
1745 generate_attach_a_constraint_cons(Constraint,Clause2).
1747 attach_constraint_atom(FA,Vars,Susp,Atom) :-
1748 make_name('attach_',FA,Name),
1749 Atom =.. [Name,Vars,Susp].
1751 generate_attach_a_constraint_nil(FA,Clause) :-
1752 Clause = (Head :- true),
1753 attach_constraint_atom(FA,[],_,Head).
1755 generate_attach_a_constraint_cons(FA,Clause) :-
1756 Clause = (Head :- Body),
1757 attach_constraint_atom(FA,[Var|Vars],Susp,Head),
1758 attach_constraint_atom(FA,Vars,Susp,RecursiveCall),
1759 Body = ( AttachBody, Subscribe, RecursiveCall ),
1760 get_max_constraint_index(N),
1762 generate_attach_body_1(FA,Var,Susp,AttachBody)
1764 generate_attach_body_n(FA,Var,Susp,AttachBody)
1766 % SWI-Prolog specific code
1767 chr_pp_flag(solver_events,NMod),
1769 Args = [[Var|_],Susp],
1770 get_target_module(Mod),
1771 use_auxiliary_predicate(run_suspensions),
1772 Subscribe = clp_events:subscribe(Var,NMod,Mod,Mod:'$run_suspensions'([Susp]))
1777 generate_attach_body_1(FA,Var,Susp,Body) :-
1778 get_target_module(Mod),
1780 ( get_attr(Var, Mod, Susps) ->
1781 put_attr(Var, Mod, [Susp|Susps])
1783 put_attr(Var, Mod, [Susp])
1786 generate_attach_body_n(F/A,Var,Susp,Body) :-
1787 get_constraint_index(F/A,Position),
1788 get_max_constraint_index(Total),
1789 get_target_module(Mod),
1790 add_attr(Total,Susp,Position,TAttr,AddGoal,NTAttr),
1791 singleton_attr(Total,Susp,Position,NewAttr3),
1793 ( get_attr(Var,Mod,TAttr) ->
1795 put_attr(Var,Mod,NTAttr)
1797 put_attr(Var,Mod,NewAttr3)
1800 %% detach_$CONSTRAINT
1801 generate_detach_a_constraint(Constraint,[Clause1,Clause2]) :-
1802 generate_detach_a_constraint_nil(Constraint,Clause1),
1803 generate_detach_a_constraint_cons(Constraint,Clause2).
1805 detach_constraint_atom(FA,Vars,Susp,Atom) :-
1806 make_name('detach_',FA,Name),
1807 Atom =.. [Name,Vars,Susp].
1809 generate_detach_a_constraint_nil(FA,Clause) :-
1810 Clause = ( Head :- true),
1811 detach_constraint_atom(FA,[],_,Head).
1813 generate_detach_a_constraint_cons(FA,Clause) :-
1814 Clause = (Head :- Body),
1815 detach_constraint_atom(FA,[Var|Vars],Susp,Head),
1816 detach_constraint_atom(FA,Vars,Susp,RecursiveCall),
1817 Body = ( DetachBody, RecursiveCall ),
1818 get_max_constraint_index(N),
1820 generate_detach_body_1(FA,Var,Susp,DetachBody)
1822 generate_detach_body_n(FA,Var,Susp,DetachBody)
1825 generate_detach_body_1(FA,Var,Susp,Body) :-
1826 get_target_module(Mod),
1828 ( get_attr(Var,Mod,Susps) ->
1829 'chr sbag_del_element'(Susps,Susp,NewSusps),
1833 put_attr(Var,Mod,NewSusps)
1839 generate_detach_body_n(F/A,Var,Susp,Body) :-
1840 get_constraint_index(F/A,Position),
1841 get_max_constraint_index(Total),
1842 rem_attr(Total,Var,Susp,Position,TAttr,RemGoal),
1843 get_target_module(Mod),
1845 ( get_attr(Var,Mod,TAttr) ->
1851 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1852 %-------------------------------------------------------------------------------
1853 %% generate_indexed_variables_body(+ConstraintSymbol,+ArgList,-Body,-VarList) is det.
1854 :- chr_constraint generate_indexed_variables_body/4.
1855 :- chr_option(mode,generate_indexed_variables_body(+,?,+,?)).
1856 :- chr_option(type_declaration,generate_indexed_variables_body(constraint,any,any,any)).
1857 %-------------------------------------------------------------------------------
1858 constraint_mode(F/A,ArgModes) \ generate_indexed_variables_body(F/A,Args,Body,Vars) <=>
1859 get_indexing_spec(F/A,Specs),
1860 ( chr_pp_flag(term_indexing,on) ->
1861 spectermvars(Specs,Args,F,A,Body,Vars)
1863 get_constraint_type_det(F/A,ArgTypes),
1864 create_indexed_variables_body(Args,ArgModes,ArgTypes,Vars,1,F/A,MaybeBody,N),
1865 ( MaybeBody == empty ->
1872 Term =.. [term|Args]
1874 Body = term_variables(Term,Vars)
1879 generate_indexed_variables_body(FA,_,_,_) <=>
1880 chr_error(internal,'generate_indexed_variables_body: missing mode info for ~w.\n',[FA]).
1881 %===============================================================================
1883 create_indexed_variables_body([],[],[],_,_,_,empty,0).
1884 create_indexed_variables_body([V|Vs],[Mode|Modes],[Type|Types],Vars,I,FA,Body,N) :-
1886 create_indexed_variables_body(Vs,Modes,Types,Tail,J,FA,RBody,M),
1888 is_indexed_argument(FA,I) ->
1889 ( atomic_type(Type) ->
1900 Continuation = true, Tail = []
1902 Continuation = RBody
1906 Body = term_variables(V,Vars)
1908 Body = (term_variables(V,Vars,Tail),RBody)
1912 ; Mode == (-), is_indexed_argument(FA,I) ->
1916 Body = (Vars = [V|Tail],RBody)
1924 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1926 spectermvars(Specs,Args,F,A,Goal,Vars) :-
1927 spectermvars(Args,1,Specs,F,A,Vars,[],Goal).
1929 spectermvars([],B,_,_,A,L,L,true) :- B > A, !.
1930 spectermvars([Arg|Args],I,Specs,F,A,L,T,Goal) :-
1931 Goal = (ArgGoal,RGoal),
1932 argspecs(Specs,I,TempArgSpecs,RSpecs),
1933 merge_argspecs(TempArgSpecs,ArgSpecs),
1934 arggoal(ArgSpecs,Arg,ArgGoal,L,L1),
1936 spectermvars(Args,J,RSpecs,F,A,L1,T,RGoal).
1938 argspecs([],_,[],[]).
1939 argspecs([[]|Rest],I,ArgSpecs,RestSpecs) :-
1940 argspecs(Rest,I,ArgSpecs,RestSpecs).
1941 argspecs([[specinfo(J,Spec,Args)|Specs]|Rest],I,ArgSpecs,RestSpecs) :-
1943 ArgSpecs = [specinfo(J,Spec,Args)|RArgSpecs],
1945 RRestSpecs = RestSpecs
1947 RestSpecs = [Specs|RRestSpecs]
1950 ArgSpecs = RArgSpecs,
1951 RestSpecs = [[specinfo(J,Spec,Args)|Specs]|RRestSpecs]
1953 argspecs(Rest,I,RArgSpecs,RRestSpecs).
1955 merge_argspecs(In,Out) :-
1957 merge_argspecs_(Sorted,Out).
1959 merge_argspecs_([],[]).
1960 merge_argspecs_([X],R) :- !, R = [X].
1961 merge_argspecs_([specinfo(I,F1,A1),specinfo(I,F2,A2)|Rest],R) :-
1962 ( (F1 == any ; F2 == any) ->
1963 merge_argspecs_([specinfo(I,any,[])|Rest],R)
1966 merge_argspecs_([specinfo(I,F1,A)|Rest],R)
1968 R = [specinfo(I,F1,A1)|RR],
1969 merge_argspecs_([specinfo(I,F2,A2)|Rest],RR)
1972 arggoal(List,Arg,Goal,L,T) :-
1976 ; List = [specinfo(_,any,_)] ->
1977 Goal = term_variables(Arg,L,T)
1985 arggoal_cases(List,Arg,L,T,Cases)
1988 arggoal_cases([],_,L,T,L=T).
1989 arggoal_cases([specinfo(_,FA,ArgSpecs)|Rest],Arg,L,T,Cases) :-
1992 ; ArgSpecs == [[]] ->
1995 Cases = (Case ; RCases),
1998 Case = (Arg = Term -> ArgsGoal),
1999 spectermvars(Args,1,ArgSpecs,F,A,L,T,ArgsGoal)
2001 arggoal_cases(Rest,Arg,L,T,RCases).
2002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2004 generate_extra_clauses(Constraints,List) :-
2005 generate_activate_clauses(Constraints,List,Tail0),
2006 generate_remove_clauses(Constraints,Tail0,Tail1),
2007 generate_allocate_clauses(Constraints,Tail1,Tail2),
2008 generate_insert_constraint_internal_clauses(Constraints,Tail2,Tail3),
2009 generate_novel_production(Tail3,Tail4),
2010 generate_extend_history(Tail4,Tail5),
2011 generate_run_suspensions_clauses(Constraints,Tail5,Tail6),
2012 generate_empty_named_history_initialisations(Tail6,Tail7),
2015 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2016 % remove_constraint_internal/[1/3]
2018 generate_remove_clauses([],List,List).
2019 generate_remove_clauses([C|Cs],List,Tail) :-
2020 generate_remove_clause(C,List,List1),
2021 generate_remove_clauses(Cs,List1,Tail).
2023 remove_constraint_goal(Constraint,Susp,Agenda,DeleteNo,DeleteYes,Role,Goal) :-
2024 uses_state(Constraint,removed),
2025 ( chr_pp_flag(inline_insertremove,off) ->
2026 use_auxiliary_predicate(remove_constraint_internal,Constraint),
2027 Goal = ( DeleteGoal, ( Delete == yes -> DeleteYes ; DeleteNo) ),
2028 remove_constraint_atom(Constraint,Susp,Agenda,Delete,DeleteGoal)
2030 delay_phase_end(validate_store_type_assumptions,
2031 generate_remove_body(Constraint,Susp,Agenda,DeleteNo,DeleteYes,Role,Goal)
2035 remove_constraint_atom(Constraint,Susp,Agenda,Delete,Goal) :-
2036 make_name('$remove_constraint_internal_',Constraint,Name),
2037 ( chr_pp_flag(debugable,off), ( only_ground_indexed_arguments(Constraint) ; get_store_type(Constraint,var_assoc_store(_,_)) ) ->
2038 Goal =.. [Name, Susp,Delete]
2040 Goal =.. [Name,Susp,Agenda,Delete]
2043 generate_remove_clause(Constraint,List,Tail) :-
2044 ( is_used_auxiliary_predicate(remove_constraint_internal,Constraint) ->
2045 List = [RemoveClause|Tail],
2046 RemoveClause = (Head :- RemoveBody),
2047 remove_constraint_atom(Constraint,Susp,Agenda,Delete,Head),
2048 generate_remove_body(Constraint,Susp,Agenda,Delete = no,Delete = yes,active,RemoveBody)
2053 generate_remove_body(Constraint,Susp,Agenda,DeleteNo,DeleteYes,Role,RemoveBody) :-
2054 ( chr_pp_flag(debugable,off), ( only_ground_indexed_arguments(Constraint) ; get_store_type(Constraint,var_assoc_store(_,_))) ->
2056 get_update_suspension_field(Constraint,Susp,state,State,removed,GetState,GetStateValue0,UpdateState),
2057 if_used_state(Constraint,not_stored_yet,GetStateValue0,true,GetStateValue),
2058 if_used_state(Constraint,not_stored_yet,(State == not_stored_yet -> DeleteNo ; DeleteYes),DeleteYes,MaybeDelete)
2059 ; Role == partner ->
2060 get_update_suspension_field(Constraint,Susp,state,State,removed,GetState,_,UpdateState),
2061 GetStateValue = true,
2062 MaybeDelete = DeleteYes
2072 static_suspension_term(Constraint,Susp2),
2073 get_static_suspension_term_field(arguments,Constraint,Susp2,Args),
2074 generate_indexed_variables_body(Constraint,Args,IndexedVariablesBody,Agenda),
2075 ( chr_pp_flag(debugable,on) ->
2076 Constraint = Functor / _,
2077 get_static_suspension_term_field(functor,Constraint,Susp2,Functor)
2082 get_update_static_suspension_field(Constraint,Susp,Susp2,state,State,removed,GetStateValue0,UpdateState),
2083 if_used_state(Constraint,not_stored_yet,GetStateValue0,true,GetStateValue),
2084 if_used_state(Constraint,not_stored_yet,(State == not_stored_yet -> Agenda = [], DeleteNo ; IndexedVariablesBody, DeleteYes),(IndexedVariablesBody,DeleteYes),MaybeDelete)
2085 ; Role == partner ->
2086 get_update_static_suspension_field(Constraint,Susp,Susp2,state,State,removed,_,UpdateState),
2087 GetStateValue = true,
2088 MaybeDelete = (IndexedVariablesBody, DeleteYes)
2099 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2100 % activate_constraint/4
2102 generate_activate_clauses([],List,List).
2103 generate_activate_clauses([C|Cs],List,Tail) :-
2104 generate_activate_clause(C,List,List1),
2105 generate_activate_clauses(Cs,List1,Tail).
2107 activate_constraint_goal(Constraint,StoreAction,Vars,Susp,Generation,Goal) :-
2108 ( chr_pp_flag(inline_insertremove,off) ->
2109 use_auxiliary_predicate(activate_constraint,Constraint),
2110 Goal = ( ActivateGoal , (Store == yes -> StoreAction ; true) ),
2111 activate_constraint_atom(Constraint,Store,Vars,Susp,Generation,ActivateGoal)
2113 delay_phase_end(validate_store_type_assumptions,
2114 activate_constraint_body(Constraint,StoreAction,true,Vars,Susp,Generation,Goal)
2118 activate_constraint_atom(Constraint,Store,Vars,Susp,Generation,Goal) :-
2119 make_name('$activate_constraint_',Constraint,Name),
2120 ( chr_pp_flag(debugable,off), only_ground_indexed_arguments(Constraint) ->
2121 Goal =.. [Name,Store, Susp]
2122 ; chr_pp_flag(debugable,off), may_trigger(Constraint), get_store_type(Constraint,var_assoc_store(_,_)) ->
2123 Goal =.. [Name,Store, Susp, Generation]
2124 ; chr_pp_flag(debugable,off), may_trigger(Constraint), get_store_type(Constraint,var_assoc_store(_,_)) ->
2125 Goal =.. [Name,Store, Vars, Susp, Generation]
2127 Goal =.. [Name,Store, Vars, Susp]
2130 generate_activate_clause(Constraint,List,Tail) :-
2131 ( is_used_auxiliary_predicate(activate_constraint,Constraint) ->
2132 List = [Clause|Tail],
2133 Clause = (Head :- Body),
2134 activate_constraint_atom(Constraint,Store,Vars,Susp,Generation,Head),
2135 activate_constraint_body(Constraint,Store = yes, Store = no,Vars,Susp,Generation,Body)
2140 activate_constraint_body(Constraint,StoreYes,StoreNo,Vars,Susp,Generation,Body) :-
2141 ( chr_pp_flag(debugable,off), may_trigger(Constraint), uses_field(Constraint,generation) ->
2142 get_update_suspension_field(Constraint,Susp,generation,Gen,Generation,GetGeneration,GetGenerationValue,UpdateGeneration),
2143 GenerationHandling = (GetGeneration, GetGenerationValue, Generation is Gen+1, UpdateGeneration)
2145 GenerationHandling = true
2147 get_update_suspension_field(Constraint,Susp,state,State,active,GetState,GetStateValue0,UpdateState),
2148 if_used_state(Constraint,not_stored_yet,GetStateValue0,true,GetStateValue),
2149 ( chr_pp_flag(debugable,off), ( only_ground_indexed_arguments(Constraint) ; get_store_type(Constraint,var_assoc_store(_,_))) ->
2150 if_used_state(Constraint,not_stored_yet,( State == not_stored_yet -> StoreYes ; StoreNo ),StoreNo,StoreVarsGoal)
2152 get_dynamic_suspension_term_field(arguments,Constraint,Susp,Arguments,ArgumentsGoal),
2153 generate_indexed_variables_body(Constraint,Arguments,IndexedVariablesBody,Vars),
2154 ( chr_pp_flag(guard_locks,off) ->
2157 NoneLocked = 'chr none_locked'( Vars)
2159 if_used_state(Constraint,not_stored_yet,
2160 ( State == not_stored_yet ->
2162 IndexedVariablesBody,
2169 % (Vars = [],StoreNo),StoreVarsGoal)
2170 StoreNo,StoreVarsGoal)
2180 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2181 % allocate_constraint/4
2183 generate_allocate_clauses([],List,List).
2184 generate_allocate_clauses([C|Cs],List,Tail) :-
2185 generate_allocate_clause(C,List,List1),
2186 generate_allocate_clauses(Cs,List1,Tail).
2188 allocate_constraint_goal(Constraint,Susp,Args,Goal) :-
2189 uses_state(Constraint,not_stored_yet),
2190 ( chr_pp_flag(inline_insertremove,off) ->
2191 use_auxiliary_predicate(allocate_constraint,Constraint),
2192 allocate_constraint_atom(Constraint,Susp,Args,Goal)
2194 Goal = (Susp = Suspension, Goal0),
2195 delay_phase_end(validate_store_type_assumptions,
2196 allocate_constraint_body(Constraint,Suspension,Args,Goal0)
2200 allocate_constraint_atom(Constraint, Susp, Args,Goal) :-
2201 make_name('$allocate_constraint_',Constraint,Name),
2202 Goal =.. [Name,Susp|Args].
2204 generate_allocate_clause(Constraint,List,Tail) :-
2205 ( is_used_auxiliary_predicate(allocate_constraint,Constraint) ->
2206 List = [Clause|Tail],
2207 Clause = (Head :- Body),
2210 allocate_constraint_atom(Constraint,Susp,Args,Head),
2211 allocate_constraint_body(Constraint,Susp,Args,Body)
2216 allocate_constraint_body(Constraint,Susp,Args,Body) :-
2217 static_suspension_term(Constraint,Suspension),
2218 get_static_suspension_term_field(arguments,Constraint,Suspension,Args),
2219 ( chr_pp_flag(debugable,on) ->
2220 Constraint = Functor / _,
2221 get_static_suspension_term_field(functor,Constraint,Suspension,Functor)
2225 ( chr_pp_flag(debugable,on) ->
2226 ( may_trigger(Constraint) ->
2227 append(Args,[Susp],VarsSusp),
2228 build_head(F,A,[0],VarsSusp, ContinuationGoal),
2229 get_target_module(Mod),
2230 Continuation = Mod : ContinuationGoal
2234 Init = (Susp = Suspension),
2235 create_static_suspension_field(Constraint,Suspension,continuation,Continuation,CreateContinuation),
2236 create_static_suspension_field(Constraint,Suspension,generation,0,CreateGeneration)
2237 ; may_trigger(Constraint), uses_field(Constraint,generation) ->
2238 create_static_suspension_field(Constraint,Suspension,generation,0,CreateGeneration),
2239 Susp = Suspension, Init = true, CreateContinuation = true
2241 CreateGeneration = true, Susp = Suspension, Init = true, CreateContinuation = true
2243 ( uses_history(Constraint) ->
2244 create_static_suspension_field(Constraint,Suspension,history,t,CreateHistory)
2246 CreateHistory = true
2248 create_static_suspension_field(Constraint,Suspension,state,not_stored_yet,CreateState),
2249 ( has_suspension_field(Constraint,id) ->
2250 get_static_suspension_term_field(id,Constraint,Suspension,Id),
2251 GenID = 'chr gen_id'(Id)
2265 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2266 % insert_constraint_internal
2268 generate_insert_constraint_internal_clauses([],List,List).
2269 generate_insert_constraint_internal_clauses([C|Cs],List,Tail) :-
2270 generate_insert_constraint_internal_clause(C,List,List1),
2271 generate_insert_constraint_internal_clauses(Cs,List1,Tail).
2273 insert_constraint_internal_constraint_goal(Constraint, Vars, Suspension, Continuation, Args,Goal) :-
2274 ( chr_pp_flag(inline_insertremove,off) ->
2275 use_auxiliary_predicate(remove_constraint_internal,Constraint),
2276 insert_constraint_internal_constraint_atom(Constraint,Vars,Suspension,Continuation,Args,Goal)
2278 delay_phase_end(validate_store_type_assumptions,
2279 generate_insert_constraint_internal_body(Constraint,Suspension,Continuation,Args,Vars,Goal)
2284 insert_constraint_internal_constraint_atom(Constraint,Vars,Self,Closure,Args,Goal) :-
2285 insert_constraint_internal_constraint_name(Constraint,Name),
2286 ( chr_pp_flag(debugable,on) ->
2287 Goal =.. [Name, Vars, Self, Closure | Args]
2288 ; ( only_ground_indexed_arguments(Constraint) ; get_store_type(Constraint,var_assoc_store(_,_)))->
2289 Goal =.. [Name,Self | Args]
2291 Goal =.. [Name,Vars, Self | Args]
2294 insert_constraint_internal_constraint_name(Constraint,Name) :-
2295 make_name('$insert_constraint_internal_',Constraint,Name).
2297 generate_insert_constraint_internal_clause(Constraint,List,Tail) :-
2298 ( is_used_auxiliary_predicate(insert_constraint_internal,Constraint) ->
2299 List = [Clause|Tail],
2300 Clause = (Head :- Body),
2303 insert_constraint_internal_constraint_atom(Constraint, Vars, Suspension, Continuation,Args,Head),
2304 generate_insert_constraint_internal_body(Constraint,Suspension,Continuation,Args,Vars,Body)
2310 generate_insert_constraint_internal_body(Constraint,Susp,Continuation,Args,Vars,Body) :-
2311 static_suspension_term(Constraint,Suspension),
2312 create_static_suspension_field(Constraint,Suspension,state,active,CreateState),
2313 ( chr_pp_flag(debugable,on) ->
2314 get_static_suspension_term_field(continuation,Constraint,Suspension,Continuation),
2315 create_static_suspension_field(Constraint,Suspension,generation,0,CreateGeneration)
2316 ; may_trigger(Constraint), uses_field(Constraint,generation) ->
2317 create_static_suspension_field(Constraint,Suspension,generation,0,CreateGeneration)
2319 CreateGeneration = true
2321 ( chr_pp_flag(debugable,on) ->
2322 Constraint = Functor / _,
2323 get_static_suspension_term_field(functor,Constraint,Suspension,Functor)
2327 ( uses_history(Constraint) ->
2328 create_static_suspension_field(Constraint,Suspension,history,t,CreateHistory)
2330 CreateHistory = true
2332 get_static_suspension_term_field(arguments,Constraint,Suspension,Args),
2333 List = [Clause|Tail],
2334 ( chr_pp_flag(debugable,off), ( only_ground_indexed_arguments(Constraint) ; get_store_type(Constraint,var_assoc_store(_,_)))->
2335 suspension_term_base_fields(Constraint,BaseFields),
2336 ( has_suspension_field(Constraint,id) ->
2337 get_static_suspension_term_field(id,Constraint,Suspension,Id),
2338 GenID = 'chr gen_id'(Id)
2351 ( has_suspension_field(Constraint,id) ->
2352 get_static_suspension_term_field(id,Constraint,Suspension,Id),
2353 GenID = 'chr gen_id'(Id)
2357 generate_indexed_variables_body(Constraint,Args,IndexedVariablesBody,Vars),
2358 ( chr_pp_flag(guard_locks,off) ->
2361 NoneLocked = 'chr none_locked'( Vars)
2366 IndexedVariablesBody,
2375 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2376 % novel_production/2
2378 generate_novel_production(List,Tail) :-
2379 ( is_used_auxiliary_predicate(novel_production) ->
2380 List = [Clause|Tail],
2383 '$novel_production'( Self, Tuple) :-
2384 % arg( 3, Self, Ref), % ARGXXX
2385 % 'chr get_mutable'( History, Ref),
2386 arg( 3, Self, History), % ARGXXX
2387 ( hprolog:get_ds( Tuple, History, _) ->
2397 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2400 generate_extend_history(List,Tail) :-
2401 ( is_used_auxiliary_predicate(extend_history) ->
2402 List = [Clause|Tail],
2405 '$extend_history'( Self, Tuple) :-
2406 % arg( 3, Self, Ref), % ARGXXX
2407 % 'chr get_mutable'( History, Ref),
2408 arg( 3, Self, History), % ARGXXX
2409 hprolog:put_ds( Tuple, History, x, NewHistory),
2410 setarg( 3, Self, NewHistory) % ARGXXX
2416 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2419 empty_named_history_initialisations/2,
2420 generate_empty_named_history_initialisation/1,
2421 find_empty_named_histories/0.
2423 generate_empty_named_history_initialisations(List, Tail) :-
2424 empty_named_history_initialisations(List, Tail),
2425 find_empty_named_histories.
2427 find_empty_named_histories, history(_, Name, []) ==>
2428 generate_empty_named_history_initialisation(Name).
2430 generate_empty_named_history_initialisation(Name) \
2431 generate_empty_named_history_initialisation(Name) <=> true.
2432 generate_empty_named_history_initialisation(Name) \
2433 empty_named_history_initialisations(List, Tail) # Passive
2435 empty_named_history_global_variable(Name, GlobalVariable),
2436 List = [(:- nb_setval(GlobalVariable, 0))|Rest],
2437 empty_named_history_initialisations(Rest, Tail)
2438 pragma passive(Passive).
2440 find_empty_named_histories \
2441 generate_empty_named_history_initialisation(_) # Passive <=> true
2442 pragma passive(Passive).
2444 find_empty_named_histories,
2445 empty_named_history_initialisations(List, Tail) # Passive <=> List = Tail
2446 pragma passive(Passive).
2448 find_empty_named_histories <=>
2449 chr_error(internal, 'find_empty_named_histories was not removed', []).
2452 empty_named_history_global_variable(Name, GlobalVariable) :-
2453 atom_concat('chr empty named history ', Name, GlobalVariable).
2455 empty_named_history_novel_production(Name, nb_getval(GlobalVariable, 0)) :-
2456 empty_named_history_global_variable(Name, GlobalVariable).
2458 empty_named_history_extend_history(Name, b_setval(GlobalVariable, 1)) :-
2459 empty_named_history_global_variable(Name, GlobalVariable).
2462 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2465 generate_run_suspensions_clauses([],List,List).
2466 generate_run_suspensions_clauses([C|Cs],List,Tail) :-
2467 generate_run_suspensions_clause(C,List,List1),
2468 generate_run_suspensions_clauses(Cs,List1,Tail).
2470 run_suspensions_goal(Constraint,Suspensions,Goal) :-
2471 make_name('$run_suspensions_',Constraint,Name),
2472 Goal =.. [Name,Suspensions].
2474 generate_run_suspensions_clause(Constraint,List,Tail) :-
2475 ( is_used_auxiliary_predicate(run_suspensions,Constraint) ->
2476 List = [Clause1,Clause2|Tail],
2477 run_suspensions_goal(Constraint,[],Clause1),
2478 ( chr_pp_flag(debugable,on) ->
2479 run_suspensions_goal(Constraint,[Suspension|Suspensions],Clause2Head),
2480 get_update_suspension_field(Constraint,Suspension,state,State,triggered,GetState,GetStateValue,UpdateState),
2481 get_update_suspension_field(Constraint,Suspension,state,Post,active,GetPost,GetPostValue,UpdatePost),
2482 get_update_suspension_field(Constraint,Suspension,generation,Gen,Generation,GetGeneration,GetGenerationValue,UpdateGeneration),
2483 get_dynamic_suspension_term_field(continuation,Constraint,Suspension,Continuation,GetContinuation),
2484 run_suspensions_goal(Constraint,Suspensions,Clause2Recursion),
2494 Generation is Gen+1,
2498 'chr debug_event'(wake(Suspension)),
2501 'chr debug_event'(fail(Suspension)), !,
2505 'chr debug_event'(exit(Suspension))
2507 'chr debug_event'(redo(Suspension)),
2512 ( Post==triggered ->
2513 UpdatePost % catching constraints that did not do anything
2523 run_suspensions_goal(Constraint,[Suspension|Suspensions],Clause2Head),
2524 static_suspension_term(Constraint,SuspensionTerm),
2525 get_static_suspension_term_field(arguments,Constraint,SuspensionTerm,Arguments),
2526 append(Arguments,[Suspension],VarsSusp),
2527 make_suspension_continuation_goal(Constraint,VarsSusp,Continuation),
2528 run_suspensions_goal(Constraint,Suspensions,Clause2Recursion),
2529 ( uses_field(Constraint,generation) ->
2530 get_update_static_suspension_field(Constraint,Suspension,SuspensionTerm,generation,Gen,Generation,GetGeneration,UpdateGeneration),
2531 GenerationHandling = ( GetGeneration, Generation is Gen+1, UpdateGeneration)
2533 GenerationHandling = true
2535 get_update_static_suspension_field(Constraint,Suspension,SuspensionTerm,state,State,triggered,GetState,UpdateState),
2536 get_update_static_suspension_field(Constraint,Suspension,SuspensionTerm,state,Post,active,GetPostState,UpdatePostState),
2537 if_used_state(Constraint,removed,
2540 -> ReactivateConstraint
2542 ),ReactivateConstraint,CondReactivate),
2543 ReactivateConstraint =
2549 ( Post==triggered ->
2550 UpdatePostState % catching constraints that did not do anything
2558 Suspension = SuspensionTerm,
2567 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2569 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2570 generate_attach_increment(Clauses) :-
2571 get_max_constraint_index(N),
2572 ( is_used_auxiliary_predicate(attach_increment), N > 0 ->
2573 Clauses = [Clause1,Clause2],
2574 generate_attach_increment_empty(Clause1),
2576 generate_attach_increment_one(Clause2)
2578 generate_attach_increment_many(N,Clause2)
2584 generate_attach_increment_empty((attach_increment([],_) :- true)).
2586 generate_attach_increment_one(Clause) :-
2587 Head = attach_increment([Var|Vars],Susps),
2588 get_target_module(Mod),
2589 ( chr_pp_flag(guard_locks,off) ->
2592 NotLocked = 'chr not_locked'( Var)
2597 ( get_attr(Var,Mod,VarSusps) ->
2598 sort(VarSusps,SortedVarSusps),
2599 'chr merge_attributes'(Susps,SortedVarSusps,MergedSusps),
2600 put_attr(Var,Mod,MergedSusps)
2602 put_attr(Var,Mod,Susps)
2604 attach_increment(Vars,Susps)
2606 Clause = (Head :- Body).
2608 generate_attach_increment_many(N,Clause) :-
2609 Head = attach_increment([Var|Vars],TAttr1),
2610 % writeln(merge_attributes_1_before),
2611 merge_attributes(N,TAttr1,TAttr2,MergeGoal,Attr),
2612 % writeln(merge_attributes_1_after),
2613 get_target_module(Mod),
2614 ( chr_pp_flag(guard_locks,off) ->
2617 NotLocked = 'chr not_locked'( Var)
2622 ( get_attr(Var,Mod,TAttr2) ->
2624 put_attr(Var,Mod,Attr)
2626 put_attr(Var,Mod,TAttr1)
2628 attach_increment(Vars,TAttr1)
2630 Clause = (Head :- Body).
2633 generate_attr_unify_hook(Clauses) :-
2634 get_max_constraint_index(N),
2639 generate_attr_unify_hook_one(Clauses)
2641 generate_attr_unify_hook_many(N,Clauses)
2645 generate_attr_unify_hook_one([Clause]) :-
2646 Head = attr_unify_hook(Susps,Other),
2647 get_target_module(Mod),
2648 get_indexed_constraint(1,C),
2649 ( get_store_type(C,ST),
2650 ( ST = default ; ST = multi_store(STs), member(default,STs) ) ->
2651 make_run_suspensions(NewSusps,SortedSusps,WakeNewSusps),
2652 make_run_suspensions(SortedSusps,SortedSusps,WakeSusps),
2653 ( atomic_types_suspended_constraint(C) ->
2655 SortedSusps = Susps,
2657 SortedOtherSusps = OtherSusps,
2658 MergeGoal = (append(Susps,OtherSusps,List), sort(List,NewSusps)),
2661 SortGoal1 = sort(Susps, SortedSusps),
2662 SortGoal2 = sort(OtherSusps,SortedOtherSusps),
2663 MergeGoal = 'chr merge_attributes'(SortedSusps,SortedOtherSusps,NewSusps),
2664 use_auxiliary_predicate(attach_increment),
2666 ( compound(Other) ->
2667 term_variables(Other,OtherVars),
2668 attach_increment(OtherVars, SortedSusps)
2677 ( get_attr(Other,Mod,OtherSusps) ->
2680 put_attr(Other,Mod,NewSusps),
2683 put_attr(Other,Mod,SortedSusps),
2691 Clause = (Head :- Body)
2692 ; get_store_type(C,var_assoc_store(VarIndex,KeyIndex)) ->
2693 make_run_suspensions(List,List,WakeNewSusps),
2694 MergeGoal = (merge_into_assoc_store(Susps,OtherSusps,List)),
2696 ( get_attr(Other,Mod,OtherSusps) ->
2700 put_attr(Other,Mod,Susps)
2702 Clause = (Head :- Body)
2706 generate_attr_unify_hook_many(N,[Clause]) :-
2707 chr_pp_flag(dynattr,off), !,
2708 Head = attr_unify_hook(Attr,Other),
2709 get_target_module(Mod),
2710 make_attr(N,Mask,SuspsList,Attr),
2711 bagof(Sort,A ^ B ^ ( member(A,SuspsList) , Sort = sort(A,B) ) , SortGoalList),
2712 list2conj(SortGoalList,SortGoals),
2713 bagof(B, A ^ member(sort(A,B),SortGoalList), SortedSuspsList),
2714 merge_attributes2(N,Mask,SortedSuspsList,TOtherAttr,MergeGoal,MergedAttr),
2715 get_all_suspensions2(N,MergedAttr,MergedSuspsList),
2716 make_attr(N,Mask,SortedSuspsList,SortedAttr),
2717 make_run_suspensions_loop(MergedSuspsList,SortedSuspsList,WakeMergedSusps),
2718 make_run_suspensions_loop(SortedSuspsList,SortedSuspsList,WakeSortedSusps),
2719 ( forall((between(1,N,Index), get_indexed_constraint(Index,Constraint)),atomic_types_suspended_constraint(Constraint)) ->
2722 use_auxiliary_predicate(attach_increment),
2724 ( compound(Other) ->
2725 term_variables(Other,OtherVars),
2726 attach_increment(OtherVars,SortedAttr)
2735 ( get_attr(Other,Mod,TOtherAttr) ->
2737 put_attr(Other,Mod,MergedAttr),
2740 put_attr(Other,Mod,SortedAttr),
2748 Clause = (Head :- Body).
2751 generate_attr_unify_hook_many(N,Clauses) :-
2752 Head = attr_unify_hook(Attr,Other),
2753 get_target_module(Mod),
2754 normalize_attr(Attr,NormalGoal,NormalAttr),
2755 normalize_attr(OtherAttr,NormalOtherGoal,NormalOtherAttr),
2756 merge_attributes(N,NormalAttr,NormalOtherAttr,MergeGoal,MergedAttr),
2757 make_run_suspensions(N),
2758 ( forall((between(1,N,Index), get_indexed_constraint(Index,Constraint)),atomic_types_suspended_constraint(Constraint)) ->
2761 use_auxiliary_predicate(attach_increment),
2763 ( compound(Other) ->
2764 term_variables(Other,OtherVars),
2765 attach_increment(OtherVars,NormalAttr)
2774 ( get_attr(Other,Mod,OtherAttr) ->
2777 put_attr(Other,Mod,MergedAttr),
2778 '$dispatch_run_suspensions'(MergedAttr)
2780 put_attr(Other,Mod,NormalAttr),
2781 '$dispatch_run_suspensions'(NormalAttr)
2785 '$dispatch_run_suspensions'(NormalAttr)
2788 Clause = (Head :- Body),
2789 Clauses = [Clause,DispatchList1,DispatchList2|Dispatchers],
2790 DispatchList1 = ('$dispatch_run_suspensions'([])),
2791 DispatchList2 = ('$dispatch_run_suspensions'([Pos-List|Rest]) :- '$dispatch_run_suspensions'(Pos,List),'$dispatch_run_suspensions'(Rest)),
2792 run_suspensions_dispatchers(N,[],Dispatchers).
2795 run_suspensions_dispatchers(N,Acc,Dispatchers) :-
2797 get_indexed_constraint(N,C),
2798 NAcc = [('$dispatch_run_suspensions'(N,List) :- Body)|Acc],
2800 run_suspensions_goal(C,List,Body)
2805 run_suspensions_dispatchers(M,NAcc,Dispatchers)
2811 make_run_suspensions(N) :-
2813 ( get_indexed_constraint(N,C),
2815 use_auxiliary_predicate(run_suspensions,C)
2820 make_run_suspensions(M)
2825 make_run_suspensions(AllSusps,OneSusps,Goal) :-
2826 make_run_suspensions(1,AllSusps,OneSusps,Goal).
2828 make_run_suspensions(Index,AllSusps,OneSusps,Goal) :-
2829 ( get_indexed_constraint(Index,C), may_trigger(C) ->
2830 use_auxiliary_predicate(run_suspensions,C),
2831 ( wakes_partially(C) ->
2832 run_suspensions_goal(C,OneSusps,Goal)
2834 run_suspensions_goal(C,AllSusps,Goal)
2840 make_run_suspensions_loop(AllSuspsList,OneSuspsList,Goal) :-
2841 make_run_suspensions_loop(AllSuspsList,OneSuspsList,1,Goal).
2843 make_run_suspensions_loop([],[],_,true).
2844 make_run_suspensions_loop([AllSusps|AllSuspsList],[OneSusps|OneSuspsList],I,(Goal,Goals)) :-
2845 make_run_suspensions(I,AllSusps,OneSusps,Goal),
2847 make_run_suspensions_loop(AllSuspsList,OneSuspsList,J,Goals).
2849 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2850 % $insert_in_store_F/A
2851 % $delete_from_store_F/A
2853 generate_insert_delete_constraints([],[]).
2854 generate_insert_delete_constraints([FA|Rest],Clauses) :-
2856 generate_insert_delete_constraint(FA,Clauses,RestClauses)
2858 Clauses = RestClauses
2860 generate_insert_delete_constraints(Rest,RestClauses).
2862 generate_insert_delete_constraint(FA,Clauses,RestClauses) :-
2863 insert_constraint_clause(FA,Clauses,RestClauses1),
2864 delete_constraint_clause(FA,RestClauses1,RestClauses).
2866 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
2869 insert_constraint_goal(FA,Susp,Vars,Goal) :-
2870 ( chr_pp_flag(inline_insertremove,off) ->
2871 use_auxiliary_predicate(insert_in_store,FA),
2872 insert_constraint_atom(FA,Susp,Goal)
2874 delay_phase_end(validate_store_type_assumptions,
2875 ( insert_constraint_body(FA,Susp,UsedVars,Goal),
2876 insert_constraint_direct_used_vars(UsedVars,Vars)
2881 insert_constraint_direct_used_vars([],_).
2882 insert_constraint_direct_used_vars([Index-Var|Rest],Vars) :-
2883 nth1(Index,Vars,Var),
2884 insert_constraint_direct_used_vars(Rest,Vars).
2886 insert_constraint_atom(FA,Susp,Call) :-
2887 make_name('$insert_in_store_',FA,Functor),
2888 Call =.. [Functor,Susp].
2890 insert_constraint_clause(C,Clauses,RestClauses) :-
2891 ( is_used_auxiliary_predicate(insert_in_store,C) ->
2892 Clauses = [Clause|RestClauses],
2893 Clause = (Head :- InsertCounterInc,VarsBody,Body),
2894 insert_constraint_atom(C,Susp,Head),
2895 insert_constraint_body(C,Susp,UsedVars,Body),
2896 insert_constraint_used_vars(UsedVars,C,Susp,VarsBody),
2897 ( chr_pp_flag(store_counter,on) ->
2898 InsertCounterInc = '$insert_counter_inc'
2900 InsertCounterInc = true
2903 Clauses = RestClauses
2906 insert_constraint_used_vars([],_,_,true).
2907 insert_constraint_used_vars([Index-Var|Rest],C,Susp,(Goal,Goals)) :-
2908 get_dynamic_suspension_term_field(argument(Index),C,Susp,Var,Goal),
2909 insert_constraint_used_vars(Rest,C,Susp,Goals).
2911 insert_constraint_body(C,Susp,UsedVars,Body) :-
2912 get_store_type(C,StoreType),
2913 insert_constraint_body(StoreType,C,Susp,UsedVars,Body).
2915 insert_constraint_body(default,C,Susp,[],Body) :-
2916 global_list_store_name(C,StoreName),
2917 make_get_store_goal(StoreName,Store,GetStoreGoal),
2918 make_update_store_goal(StoreName,Cell,UpdateStoreGoal),
2919 ( chr_pp_flag(debugable,on) ->
2920 Cell = [Susp|Store],
2927 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,Cell,SetGoal),
2931 Cell = [Susp|Store],
2933 ( Store = [NextSusp|_] ->
2940 % get_target_module(Mod),
2941 % get_max_constraint_index(Total),
2943 % generate_attach_body_1(C,Store,Susp,AttachBody)
2945 % generate_attach_body_n(C,Store,Susp,AttachBody)
2949 % 'chr default_store'(Store),
2952 insert_constraint_body(multi_inthash(Indexes),C,Susp,[],Body) :-
2953 generate_multi_inthash_insert_constraint_bodies(Indexes,C,Susp,Body).
2954 insert_constraint_body(multi_hash(Indexes),C,Susp,MixedUsedVars,Body) :-
2955 generate_multi_hash_insert_constraint_bodies(Indexes,C,Susp,Body,MixedUsedVars),
2956 sort_out_used_vars(MixedUsedVars,UsedVars).
2957 insert_constraint_body(atomic_constants([Index],_),C,Susp,UsedVars,Body) :-
2958 atomic_constant_store_index_name(C,[Index],IndexName),
2959 UsedVars = [Index - Key],
2960 IndexLookup =.. [IndexName,Key,StoreName],
2963 nb_getval(StoreName,Store),
2964 b_setval(StoreName,[Susp|Store])
2968 insert_constraint_body(ground_constants([Index],_),C,Susp,UsedVars,Body) :-
2969 ground_constant_store_index_name(C,[Index],IndexName),
2970 UsedVars = [Index - Key],
2971 IndexLookup =.. [IndexName,Key,StoreName],
2974 nb_getval(StoreName,Store),
2975 b_setval(StoreName,[Susp|Store])
2979 insert_constraint_body(global_ground,C,Susp,[],Body) :-
2980 global_ground_store_name(C,StoreName),
2981 make_get_store_goal(StoreName,Store,GetStoreGoal),
2982 make_update_store_goal(StoreName,Cell,UpdateStoreGoal),
2983 ( chr_pp_flag(debugable,on) ->
2984 Cell = [Susp|Store],
2991 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,Cell,SetGoal),
2995 Cell = [Susp|Store],
2997 ( Store = [NextSusp|_] ->
3004 % global_ground_store_name(C,StoreName),
3005 % make_get_store_goal(StoreName,Store,GetStoreGoal),
3006 % make_update_store_goal(StoreName,[Susp|Store],UpdateStoreGoal),
3009 % GetStoreGoal, % nb_getval(StoreName,Store),
3010 % UpdateStoreGoal % b_setval(StoreName,[Susp|Store])
3012 insert_constraint_body(var_assoc_store(VarIndex,AssocIndex),C,Susp,[VarIndex-Variable,AssocIndex-Key],Body) :-
3013 % TODO: generalize to more than one !!!
3014 get_target_module(Module),
3015 Body = ( get_attr(Variable,Module,AssocStore) ->
3016 insert_assoc_store(AssocStore,Key,Susp)
3018 new_assoc_store(AssocStore),
3019 put_attr(Variable,Module,AssocStore),
3020 insert_assoc_store(AssocStore,Key,Susp)
3023 insert_constraint_body(global_singleton,C,Susp,[],Body) :-
3024 global_singleton_store_name(C,StoreName),
3025 make_update_store_goal(StoreName,Susp,UpdateStoreGoal),
3030 insert_constraint_body(multi_store(StoreTypes),C,Susp,UsedVars,Body) :-
3031 find_with_var_identity(
3035 member(ST,StoreTypes),
3036 chr_translate:insert_constraint_body(ST,C,Susp,UV,B)
3040 once(pairup(Bodies,NestedUsedVars,BodiesUsedVars)),
3041 list2conj(Bodies,Body),
3042 sort_out_used_vars(NestedUsedVars,UsedVars).
3043 insert_constraint_body(identifier_store(Index),C,Susp,UsedVars,Body) :-
3044 UsedVars = [Index-Var],
3045 get_identifier_size(ISize),
3046 functor(Struct,struct,ISize),
3047 get_identifier_index(C,Index,IIndex),
3048 arg(IIndex,Struct,Susps),
3049 Body = (Var = Struct, setarg(IIndex,Var,[Susp|Susps])).
3050 insert_constraint_body(type_indexed_identifier_store(Index,IndexType),C,Susp,UsedVars,Body) :-
3051 UsedVars = [Index-Var],
3052 type_indexed_identifier_structure(IndexType,Struct),
3053 get_type_indexed_identifier_index(IndexType,C,Index,IIndex),
3054 arg(IIndex,Struct,Susps),
3055 Body = (Var = Struct, setarg(IIndex,Var,[Susp|Susps])).
3057 sort_out_used_vars(NestedUsedVars,UsedVars) :-
3058 flatten(NestedUsedVars,FlatUsedVars),
3059 sort(FlatUsedVars,SortedFlatUsedVars),
3060 sort_out_used_vars1(SortedFlatUsedVars,UsedVars).
3062 sort_out_used_vars1([],[]).
3063 sort_out_used_vars1([I-V],L) :- !, L = [I-V].
3064 sort_out_used_vars1([I-X,J-Y|R],L) :-
3067 sort_out_used_vars1([I-X|R],L)
3070 sort_out_used_vars1([J-Y|R],T)
3073 generate_multi_inthash_insert_constraint_bodies([],_,_,true).
3074 generate_multi_inthash_insert_constraint_bodies([Index|Indexes],FA,Susp,(Body,Bodies)) :-
3075 multi_hash_store_name(FA,Index,StoreName),
3076 multi_hash_key(FA,Index,Susp,KeyBody,Key),
3080 nb_getval(StoreName,Store),
3081 insert_iht(Store,Key,Susp)
3083 generate_multi_inthash_insert_constraint_bodies(Indexes,FA,Susp,Bodies).
3085 generate_multi_hash_insert_constraint_bodies([],_,_,true,[]).
3086 generate_multi_hash_insert_constraint_bodies([Index|Indexes],FA,Susp,(Body,Bodies),[UsedVars|MoreUsedVars]) :-
3087 multi_hash_store_name(FA,Index,StoreName),
3088 multi_hash_key_direct(FA,Index,Susp,Key,UsedVars),
3089 make_get_store_goal(StoreName,Store,GetStoreGoal),
3090 ( chr_pp_flag(ht_removal,on)
3091 -> ht_prev_field(Index,PrevField),
3092 set_dynamic_suspension_term_field(PrevField,FA,NextSusp,Result,
3097 insert_ht(Store,Key,Susp,Result),
3098 ( Result = [_,NextSusp|_]
3106 insert_ht(Store,Key,Susp)
3109 generate_multi_hash_insert_constraint_bodies(Indexes,FA,Susp,Bodies,MoreUsedVars).
3111 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3114 delete_constraint_clause(C,Clauses,RestClauses) :-
3115 ( is_used_auxiliary_predicate(delete_from_store,C) ->
3116 Clauses = [Clause|RestClauses],
3117 Clause = (Head :- Body),
3118 delete_constraint_atom(C,Susp,Head),
3121 delete_constraint_body(C,Head,Susp,[],Body)
3123 Clauses = RestClauses
3126 delete_constraint_goal(Head,Susp,VarDict,Goal) :-
3129 ( chr_pp_flag(inline_insertremove,off) ->
3130 use_auxiliary_predicate(delete_from_store,C),
3131 delete_constraint_atom(C,Susp,Goal)
3133 delay_phase_end(validate_store_type_assumptions, delete_constraint_body(C,Head,Susp,VarDict,Goal))
3136 delete_constraint_atom(C,Susp,Atom) :-
3137 make_name('$delete_from_store_',C,Functor),
3138 Atom =.. [Functor,Susp].
3141 delete_constraint_body(C,Head,Susp,VarDict,Body) :-
3142 Body = (CounterBody,DeleteBody),
3143 ( chr_pp_flag(store_counter,on) ->
3144 CounterBody = '$delete_counter_inc'
3148 get_store_type(C,StoreType),
3149 delete_constraint_body(StoreType,C,Head,Susp,VarDict,DeleteBody).
3151 delete_constraint_body(default,C,_,Susp,_,Body) :-
3152 ( chr_pp_flag(debugable,on) ->
3153 global_list_store_name(C,StoreName),
3154 make_get_store_goal(StoreName,Store,GetStoreGoal),
3155 make_update_store_goal(StoreName,NStore,UpdateStoreGoal),
3158 GetStoreGoal, % nb_getval(StoreName,Store),
3159 'chr sbag_del_element'(Store,Susp,NStore),
3160 UpdateStoreGoal % b_setval(StoreName,NStore)
3163 get_dynamic_suspension_term_field(global_list_prev,C,Susp,PredCell,GetGoal),
3164 global_list_store_name(C,StoreName),
3165 make_get_store_goal(StoreName,Store,GetStoreGoal),
3166 make_update_store_goal(StoreName,Tail,UpdateStoreGoal),
3167 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,_,SetGoal1),
3168 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,PredCell,SetGoal2),
3173 GetStoreGoal, % nb_getval(StoreName,Store),
3176 ( Tail = [NextSusp|_] ->
3182 PredCell = [_,_|Tail],
3183 setarg(2,PredCell,Tail),
3184 ( Tail = [NextSusp|_] ->
3192 % get_target_module(Mod),
3193 % get_max_constraint_index(Total),
3195 % generate_detach_body_1(C,Store,Susp,DetachBody),
3198 % 'chr default_store'(Store),
3202 % generate_detach_body_n(C,Store,Susp,DetachBody),
3205 % 'chr default_store'(Store),
3209 delete_constraint_body(multi_inthash(Indexes),C,_,Susp,_,Body) :-
3210 generate_multi_inthash_delete_constraint_bodies(Indexes,C,Susp,Body).
3211 delete_constraint_body(multi_hash(Indexes),C,Head,Susp,VarDict,Body) :-
3212 generate_multi_hash_delete_constraint_bodies(Indexes,C,Head,Susp,VarDict,Body).
3213 delete_constraint_body(atomic_constants([Index],_),C,Head,Susp,VarDict,Body) :-
3214 atomic_constant_store_index_name(C,[Index],IndexName),
3215 get_suspension_argument_possibly_in_scope(Head,Index,VarDict,Susp,Key,Goal),
3216 IndexLookup =.. [IndexName,Key,StoreName],
3220 nb_getval(StoreName,Store),
3221 'chr sbag_del_element'(Store,Susp,NStore),
3222 b_setval(StoreName,NStore)
3226 delete_constraint_body(atomic_constants([Index],_),C,Head,Susp,VarDict,Body) :-
3227 ground_constant_store_index_name(C,[Index],IndexName),
3228 get_suspension_argument_possibly_in_scope(Head,Index,VarDict,Susp,Key,Goal),
3229 IndexLookup =.. [IndexName,Key,StoreName],
3233 nb_getval(StoreName,Store),
3234 'chr sbag_del_element'(Store,Susp,NStore),
3235 b_setval(StoreName,NStore)
3239 delete_constraint_body(global_ground,C,_,Susp,_,Body) :-
3240 ( chr_pp_flag(debugable,on) ->
3241 global_ground_store_name(C,StoreName),
3242 make_get_store_goal(StoreName,Store,GetStoreGoal),
3243 make_update_store_goal(StoreName,NStore,UpdateStoreGoal),
3246 GetStoreGoal, % nb_getval(StoreName,Store),
3247 'chr sbag_del_element'(Store,Susp,NStore),
3248 UpdateStoreGoal % b_setval(StoreName,NStore)
3251 get_dynamic_suspension_term_field(global_list_prev,C,Susp,PredCell,GetGoal),
3252 global_ground_store_name(C,StoreName),
3253 make_get_store_goal(StoreName,Store,GetStoreGoal),
3254 make_update_store_goal(StoreName,Tail,UpdateStoreGoal),
3255 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,_,SetGoal1),
3256 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,PredCell,SetGoal2),
3261 GetStoreGoal, % nb_getval(StoreName,Store),
3264 ( Tail = [NextSusp|_] ->
3270 PredCell = [_,_|Tail],
3271 setarg(2,PredCell,Tail),
3272 ( Tail = [NextSusp|_] ->
3280 % global_ground_store_name(C,StoreName),
3281 % make_get_store_goal(StoreName,Store,GetStoreGoal),
3282 % make_update_store_goal(StoreName,NStore,UpdateStoreGoal),
3285 % GetStoreGoal, % nb_getval(StoreName,Store),
3286 % 'chr sbag_del_element'(Store,Susp,NStore),
3287 % UpdateStoreGoal % b_setval(StoreName,NStore)
3289 delete_constraint_body(var_assoc_store(VarIndex,AssocIndex),C,_,Susp,_,Body) :-
3290 get_target_module(Module),
3291 get_dynamic_suspension_term_field(argument(VarIndex),C,Susp,Variable,VariableGoal),
3292 get_dynamic_suspension_term_field(argument(AssocIndex),C,Susp,Key,KeyGoal),
3295 get_attr(Variable,Module,AssocStore),
3297 delete_assoc_store(AssocStore,Key,Susp)
3299 delete_constraint_body(global_singleton,C,_,_Susp,_,Body) :-
3300 global_singleton_store_name(C,StoreName),
3301 make_update_store_goal(StoreName,[],UpdateStoreGoal),
3304 UpdateStoreGoal % b_setval(StoreName,[])
3306 delete_constraint_body(multi_store(StoreTypes),C,Head,Susp,VarDict,Body) :-
3307 find_with_var_identity(
3309 [Susp/VarDict/Head],
3311 member(ST,StoreTypes),
3312 chr_translate:delete_constraint_body(ST,C,Head,Susp,VarDict,B)
3316 list2conj(Bodies,Body).
3317 delete_constraint_body(identifier_store(Index),C,Head,Susp,VarDict,Body) :-
3318 get_suspension_argument_possibly_in_scope(Head,Index,VarDict,Susp,Variable,VariableGoal),
3319 get_identifier_size(ISize),
3320 functor(Struct,struct,ISize),
3321 get_identifier_index(C,Index,IIndex),
3322 arg(IIndex,Struct,Susps),
3326 'chr sbag_del_element'(Susps,Susp,NSusps),
3327 setarg(IIndex,Variable,NSusps)
3329 delete_constraint_body(type_indexed_identifier_store(Index,IndexType),C,Head,Susp,VarDict,Body) :-
3330 get_suspension_argument_possibly_in_scope(Head,Index,VarDict,Susp,Variable,VariableGoal),
3331 type_indexed_identifier_structure(IndexType,Struct),
3332 get_type_indexed_identifier_index(IndexType,C,Index,IIndex),
3333 arg(IIndex,Struct,Susps),
3337 'chr sbag_del_element'(Susps,Susp,NSusps),
3338 setarg(IIndex,Variable,NSusps)
3341 generate_multi_inthash_delete_constraint_bodies([],_,_,true).
3342 generate_multi_inthash_delete_constraint_bodies([Index|Indexes],FA,Susp,(Body,Bodies)) :-
3343 multi_hash_store_name(FA,Index,StoreName),
3344 multi_hash_key(FA,Index,Susp,KeyBody,Key),
3348 nb_getval(StoreName,Store),
3349 delete_iht(Store,Key,Susp)
3351 generate_multi_inthash_delete_constraint_bodies(Indexes,FA,Susp,Bodies).
3352 generate_multi_hash_delete_constraint_bodies([],_,_,_,_,true).
3353 generate_multi_hash_delete_constraint_bodies([Index|Indexes],C,Head,Susp,VarDict,(Body,Bodies)) :-
3354 multi_hash_store_name(C,Index,StoreName),
3355 multi_hash_key(C,Head,Index,Susp,VarDict,KeyBody,Key),
3356 make_get_store_goal(StoreName,Store,GetStoreGoal),
3357 ( chr_pp_flag(ht_removal,on)
3358 -> ht_prev_field(Index,PrevField),
3359 get_dynamic_suspension_term_field(PrevField,C,Susp,Prev,GetGoal),
3360 set_dynamic_suspension_term_field(PrevField,C,NextSusp,_,
3362 set_dynamic_suspension_term_field(PrevField,C,NextSusp,Prev,
3370 delete_first_ht(Store,Key,Values),
3371 ( Values = [NextSusp|_]
3375 ; Prev = [_,_|Values],
3376 setarg(2,Prev,Values),
3377 ( Values = [NextSusp|_]
3386 GetStoreGoal, % nb_getval(StoreName,Store),
3387 delete_ht(Store,Key,Susp)
3390 generate_multi_hash_delete_constraint_bodies(Indexes,FA,Head,Susp,VarDict,Bodies).
3392 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3395 module_initializer/1,
3396 module_initializers/1.
3398 module_initializers(G), module_initializer(Initializer) <=>
3399 G = (Initializer,Initializers),
3400 module_initializers(Initializers).
3402 module_initializers(G) <=>
3405 generate_attach_code(Constraints,[Enumerate|L]) :-
3406 enumerate_stores_code(Constraints,Enumerate),
3407 generate_attach_code(Constraints,L,T),
3408 module_initializers(Initializers),
3409 prolog_global_variables_code(PrologGlobalVariables),
3410 T = [('$chr_initialization' :- Initializers),(:- initialization '$chr_initialization')|PrologGlobalVariables].
3412 generate_attach_code([],L,L).
3413 generate_attach_code([C|Cs],L,T) :-
3414 get_store_type(C,StoreType),
3415 generate_attach_code(StoreType,C,L,L1),
3416 generate_attach_code(Cs,L1,T).
3418 generate_attach_code(default,C,L,T) :-
3419 global_list_store_initialisation(C,L,T).
3420 generate_attach_code(multi_inthash(Indexes),C,L,T) :-
3421 multi_inthash_store_initialisations(Indexes,C,L,L1),
3422 multi_inthash_via_lookups(Indexes,C,L1,T).
3423 generate_attach_code(multi_hash(Indexes),C,L,T) :-
3424 multi_hash_store_initialisations(Indexes,C,L,L1),
3425 multi_hash_lookups(Indexes,C,L1,T).
3426 generate_attach_code(atomic_constants(Index,Constants),C,L,T) :-
3427 maplist(atomic_constant_store_name(C,Index),Constants,StoreNames),
3428 findall(Initializer,
3429 ( member(StoreName,StoreNames),
3430 Initializer = nb_setval(StoreName,[])
3433 maplist(module_initializer,Initializers),
3434 atomic_constants_code(C,Index,Constants,L,T).
3435 generate_attach_code(ground_constants(Index,Constants),C,L,T) :-
3436 maplist(ground_constant_store_name(C,Index),Constants,StoreNames),
3437 findall(Initializer,
3438 ( member(StoreName,StoreNames),
3439 Initializer = nb_setval(StoreName,[])
3442 maplist(module_initializer,Initializers),
3443 ground_constants_code(C,Index,Constants,L,T).
3444 generate_attach_code(global_ground,C,L,T) :-
3445 global_ground_store_initialisation(C,L,T).
3446 generate_attach_code(var_assoc_store(_,_),_,L,L) :-
3447 use_auxiliary_module(chr_assoc_store).
3448 generate_attach_code(global_singleton,C,L,T) :-
3449 global_singleton_store_initialisation(C,L,T).
3450 generate_attach_code(multi_store(StoreTypes),C,L,T) :-
3451 multi_store_generate_attach_code(StoreTypes,C,L,T).
3452 generate_attach_code(identifier_store(Index),C,L,T) :-
3453 get_identifier_index(C,Index,IIndex),
3455 get_identifier_size(ISize),
3456 functor(Struct,struct,ISize),
3457 Struct =.. [_,Label|Stores],
3458 set_elems(Stores,[]),
3459 Clause1 = new_identifier(Label,Struct),
3460 functor(Struct2,struct,ISize),
3461 arg(1,Struct2,Label2),
3463 ( user:portray(Struct2) :-
3468 functor(Struct3,struct,ISize),
3469 arg(1,Struct3,Label3),
3470 Clause3 = identifier_label(Struct3,Label3),
3471 L = [Clause1,Clause2,Clause3|T]
3475 generate_attach_code(type_indexed_identifier_store(Index,IndexType),C,L,T) :-
3476 get_type_indexed_identifier_index(IndexType,C,Index,IIndex),
3478 identifier_store_initialization(IndexType,L,L1),
3479 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3480 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3481 get_type_indexed_identifier_size(IndexType,ISize),
3482 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3483 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3484 type_indexed_identifier_structure(IndexType,Struct),
3485 Struct =.. [_,Label|Stores],
3486 set_elems(Stores,[]),
3487 type_indexed_identifier_name(IndexType,new_identifier,Name1),
3488 Clause1 =.. [Name1,Label,Struct],
3489 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3490 Goal1 =.. [Name1,Label1b,S1b],
3491 type_indexed_identifier_structure(IndexType,Struct1b),
3492 Struct1b =.. [_,Label1b|Stores1b],
3493 set_elems(Stores1b,[]),
3494 Expansion1 = (S1b = Struct1b),
3495 Clause1b = user:goal_expansion(Goal1,Expansion1),
3496 % writeln(Clause1-Clause1b),
3497 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3498 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3499 type_indexed_identifier_structure(IndexType,Struct2),
3500 arg(1,Struct2,Label2),
3502 ( user:portray(Struct2) :-
3507 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3508 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3509 type_indexed_identifier_structure(IndexType,Struct3),
3510 arg(1,Struct3,Label3),
3511 type_indexed_identifier_name(IndexType,identifier_label,Name3),
3512 Clause3 =.. [Name3,Struct3,Label3],
3513 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3514 Goal3b =.. [Name3,S3b,L3b],
3515 type_indexed_identifier_structure(IndexType,Struct3b),
3516 arg(1,Struct3b,L3b),
3517 Expansion3b = (S3 = Struct3b),
3518 Clause3b = ( user:goal_expansion(Goal3b,Expansion3b) :- writeln(expanding)),
3519 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3520 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3521 identifier_store_name(IndexType,GlobalVariable),
3522 lookup_identifier_atom(IndexType,X,IX,LookupAtom),
3523 type_indexed_identifier_name(IndexType,new_identifier,NewIdentifierFunctor),
3524 NewIdentifierGoal =.. [NewIdentifierFunctor,X,IX],
3527 nb_getval(GlobalVariable,HT),
3528 ( lookup_ht(HT,X,[IX]) ->
3535 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3536 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3537 L1 = [(:- multifile goal_expansion/2),(:- dynamic goal_expansion/2),Clause1,Clause1b,Clause2,Clause3,Clause3b,Clause4|T]
3542 lookup_identifier_atom(Key,X,IX,Atom) :-
3543 atom_concat('lookup_identifier_',Key,LookupFunctor),
3544 Atom =.. [LookupFunctor,X,IX].
3546 identifier_label_atom(IndexType,IX,X,Atom) :-
3547 type_indexed_identifier_name(IndexType,identifier_label,Name),
3548 Atom =.. [Name,IX,X].
3550 multi_store_generate_attach_code([],_,L,L).
3551 multi_store_generate_attach_code([ST|STs],C,L,T) :-
3552 generate_attach_code(ST,C,L,L1),
3553 multi_store_generate_attach_code(STs,C,L1,T).
3555 multi_inthash_store_initialisations([],_,L,L).
3556 multi_inthash_store_initialisations([Index|Indexes],FA,L,T) :-
3557 use_auxiliary_module(chr_integertable_store),
3558 multi_hash_store_name(FA,Index,StoreName),
3559 module_initializer((new_iht(HT),nb_setval(StoreName,HT))),
3560 % L = [(:- (chr_integertable_store:new_ht(HT),nb_setval(StoreName,HT)) )|L1],
3562 multi_inthash_store_initialisations(Indexes,FA,L1,T).
3563 multi_hash_store_initialisations([],_,L,L).
3564 multi_hash_store_initialisations([Index|Indexes],FA,L,T) :-
3565 use_auxiliary_module(chr_hashtable_store),
3566 multi_hash_store_name(FA,Index,StoreName),
3567 prolog_global_variable(StoreName),
3568 make_init_store_goal(StoreName,HT,InitStoreGoal),
3569 module_initializer((new_ht(HT),InitStoreGoal)),
3571 multi_hash_store_initialisations(Indexes,FA,L1,T).
3573 global_list_store_initialisation(C,L,T) :-
3575 global_list_store_name(C,StoreName),
3576 prolog_global_variable(StoreName),
3577 make_init_store_goal(StoreName,[],InitStoreGoal),
3578 module_initializer(InitStoreGoal)
3583 global_ground_store_initialisation(C,L,T) :-
3584 global_ground_store_name(C,StoreName),
3585 prolog_global_variable(StoreName),
3586 make_init_store_goal(StoreName,[],InitStoreGoal),
3587 module_initializer(InitStoreGoal),
3589 global_singleton_store_initialisation(C,L,T) :-
3590 global_singleton_store_name(C,StoreName),
3591 prolog_global_variable(StoreName),
3592 make_init_store_goal(StoreName,[],InitStoreGoal),
3593 module_initializer(InitStoreGoal),
3595 identifier_store_initialization(IndexType,L,T) :-
3596 use_auxiliary_module(chr_hashtable_store),
3597 identifier_store_name(IndexType,StoreName),
3598 prolog_global_variable(StoreName),
3599 make_init_store_goal(StoreName,HT,InitStoreGoal),
3600 module_initializer((new_ht(HT),InitStoreGoal)),
3604 multi_inthash_via_lookups([],_,L,L).
3605 multi_inthash_via_lookups([Index|Indexes],C,L,T) :-
3606 multi_hash_lookup_head(C,Index,Key,SuspsList,Head),
3607 multi_hash_lookup_body(C,inthash,Index,Key,SuspsList,Body),
3608 L = [(Head :- Body)|L1],
3609 multi_inthash_via_lookups(Indexes,C,L1,T).
3610 multi_hash_lookups([],_,L,L).
3611 multi_hash_lookups([Index|Indexes],C,L,T) :-
3612 multi_hash_lookup_head(C,Index,Key,SuspsList,Head),
3613 multi_hash_lookup_body(C,hash,Index,Key,SuspsList,Body),
3614 L = [(Head :- Body)|L1],
3615 multi_hash_lookups(Indexes,C,L1,T).
3617 multi_hash_lookup_head(ConstraintSymbol,Index,Key,SuspsList,Head) :-
3618 multi_hash_lookup_name(ConstraintSymbol,Index,Name),
3619 Head =.. [Name,Key,SuspsList].
3621 %% multi_hash_lookup_body(+ConstraintSymbol,+HashType,+Index,+Key,+SuspsList,-Goal) is det.
3623 % Returns goal that performs hash table lookup.
3624 multi_hash_lookup_body(ConstraintSymbol,HashType,Index,Key,SuspsList,Goal) :-
3626 ( get_store_type(ConstraintSymbol,multi_store(Stores)),
3627 memberchk(atomic_constants(Index,Constants),Stores) ->
3629 atomic_constant_store_name(ConstraintSymbol,Index,Key,StoreName),
3630 Goal = nb_getval(StoreName,SuspsList)
3632 atomic_constant_store_index_name(ConstraintSymbol,Index,IndexName),
3633 Lookup =.. [IndexName,Key,StoreName],
3634 Goal = (Lookup, nb_getval(StoreName,SuspsList))
3636 ; get_store_type(ConstraintSymbol,multi_store(Stores)),
3637 memberchk(ground_constants(Index,Constants),Stores) ->
3639 ground_constant_store_name(ConstraintSymbol,Index,Key,StoreName),
3640 Goal = nb_getval(StoreName,SuspsList)
3642 ground_constant_store_index_name(ConstraintSymbol,Index,IndexName),
3643 Lookup =.. [IndexName,Key,StoreName],
3644 Goal = (Lookup, nb_getval(StoreName,SuspsList))
3647 multi_hash_store_name(ConstraintSymbol,Index,StoreName),
3648 make_get_store_goal(StoreName,HT,GetStoreGoal),
3649 ( HashType == hash, specialized_hash_term_call(Key,Hash,HashCall) ->
3652 GetStoreGoal, % nb_getval(StoreName,HT),
3653 HashCall, % hash_term(Key,Hash),
3654 lookup_ht1(HT,Hash,Key,SuspsList)
3657 lookup_hash_call(HashType,HT,Key,SuspsList,Lookup),
3660 GetStoreGoal, % nb_getval(StoreName,HT),
3661 hash_term(Key,Hash),
3668 lookup_hash_call(hash,HT,Key,SuspsList,lookup_ht(HT,Key,SuspsList)).
3669 lookup_hash_call(inthash,HT,Key,SuspsList,lookup_iht(HT,Key,SuspsList)).
3671 specialized_hash_term_call(Key,Hash,Call) :-
3673 % This is based on a property of SWI-Prolog's
3674 % hash_term/2 predicate:
3675 % the hash value is stable over repeated invocations
3677 hash_term(Key,Hash),
3681 specialize_hash_term(Key,NewKey),
3683 Call = hash_term(NewKey,Hash)
3686 specialize_hash_term(Term,NewTerm) :-
3688 hash_term(Term,NewTerm)
3693 maplist(specialize_hash_term,Args,NewArgs),
3694 NewTerm =.. [F|NewArgs]
3697 multi_hash_lookup_goal(ConstraintSymbol,HashType,Index,Key,SuspsList,Goal) :-
3698 ( /* chr_pp_flag(experiment,off) ->
3701 actual_atomic_multi_hash_keys(ConstraintSymbol,Index,[Key])
3703 actual_ground_multi_hash_keys(ConstraintSymbol,Index,[Key])
3705 actual_non_atomic_multi_hash_key(ConstraintSymbol,Index)
3707 delay_phase_end(validate_store_type_assumptions,
3708 multi_hash_lookup_body(ConstraintSymbol,HashType,Index,Key,SuspsList,Goal)).
3710 :- chr_constraint actual_atomic_multi_hash_keys/3.
3711 :- chr_option(mode,actual_atomic_multi_hash_keys(+,+,?)).
3713 :- chr_constraint actual_ground_multi_hash_keys/3.
3714 :- chr_option(mode,actual_ground_multi_hash_keys(+,+,?)).
3716 :- chr_constraint actual_non_atomic_multi_hash_key/2.
3717 :- chr_option(mode,actual_non_atomic_multi_hash_key(+,+)).
3720 actual_atomic_multi_hash_keys(C,Index,Keys)
3721 ==> format('Keys: ~w - ~w : ~w\n', [C,Index,Keys]).
3723 actual_ground_multi_hash_keys(C,Index,Keys)
3724 ==> format('Keys: ~w - ~w : ~w\n', [C,Index,Keys]).
3726 actual_non_atomic_multi_hash_key(C,Index)
3727 ==> format('Keys: ~w - ~w : N/A\n', [C,Index]).
3729 actual_atomic_multi_hash_keys(C,Index,Keys1), actual_atomic_multi_hash_keys(C,Index,Keys2)
3730 <=> append(Keys1,Keys2,Keys0),
3732 actual_atomic_multi_hash_keys(C,Index,Keys).
3734 actual_ground_multi_hash_keys(C,Index,Keys1), actual_atomic_multi_hash_keys(C,Index,Keys2)
3735 <=> append(Keys1,Keys2,Keys0),
3737 actual_ground_multi_hash_keys(C,Index,Keys).
3739 actual_ground_multi_hash_keys(C,Index,Keys1), actual_ground_multi_hash_keys(C,Index,Keys2)
3740 <=> append(Keys1,Keys2,Keys0),
3742 actual_ground_multi_hash_keys(C,Index,Keys).
3744 actual_non_atomic_multi_hash_key(C,Index) \ actual_non_atomic_multi_hash_key(C,Index)
3747 actual_non_atomic_multi_hash_key(C,Index) \ actual_atomic_multi_hash_keys(C,Index,_)
3750 actual_non_atomic_multi_hash_key(C,Index) \ actual_ground_multi_hash_keys(C,Index,_)
3753 %% multi_hash_lookup_name(+ConstraintSymbol,+Index,-Name)
3755 % Returns predicate name of hash table lookup predicate.
3756 multi_hash_lookup_name(F/A,Index,Name) :-
3760 atom_concat_list(Index,IndexName)
3762 atom_concat_list(['$via1_multi_hash_',F,'___',A,'-',IndexName],Name).
3764 multi_hash_store_name(F/A,Index,Name) :-
3765 get_target_module(Mod),
3769 atom_concat_list(Index,IndexName)
3771 atom_concat_list(['$chr_store_multi_hash_',Mod,'____',F,'___',A,'-',IndexName],Name).
3773 multi_hash_key(FA,Index,Susp,KeyBody,Key) :-
3774 ( ( integer(Index) ->
3779 get_dynamic_suspension_term_field(argument(I),FA,Susp,Key,KeyBody)
3781 sort(Index,Indexes),
3782 find_with_var_identity(Goal-KeyI,[Susp],(member(I,Indexes),get_dynamic_suspension_term_field(argument(I),FA,Susp,KeyI,Goal)),ArgKeyPairs),
3783 once(pairup(Bodies,Keys,ArgKeyPairs)),
3785 list2conj(Bodies,KeyBody)
3788 multi_hash_key(C,Head,Index,Susp,VarDict,KeyBody,Key) :-
3789 ( ( integer(Index) ->
3794 get_suspension_argument_possibly_in_scope(Head,I,VarDict,Susp,Key,KeyBody)
3796 sort(Index,Indexes),
3797 find_with_var_identity(
3799 [Susp/Head/VarDict],
3802 get_suspension_argument_possibly_in_scope(Head,I,VarDict,Susp,KeyI,Goal)
3806 once(pairup(Bodies,Keys,ArgKeyPairs)),
3808 list2conj(Bodies,KeyBody)
3811 get_suspension_argument_possibly_in_scope(Head,Index,VarDict,Susp,Arg,Goal) :-
3812 arg(Index,Head,OriginalArg),
3813 ( lookup_eq(VarDict,OriginalArg,Arg) ->
3818 get_dynamic_suspension_term_field(argument(Index),C,Susp,Arg,Goal)
3821 multi_hash_key_direct(FA,Index,Susp,Key,UsedVars) :-
3822 ( ( integer(Index) ->
3829 sort(Index,Indexes),
3830 pairup(Indexes,Keys,UsedVars),
3834 multi_hash_key_args(Index,Head,KeyArgs) :-
3836 arg(Index,Head,Arg),
3839 sort(Index,Indexes),
3840 term_variables(Head,Vars),
3841 find_with_var_identity(Arg,Vars,(member(I,Indexes), arg(I,Head,Arg)),KeyArgs)
3845 %-------------------------------------------------------------------------------
3846 atomic_constants_code(C,Index,Constants,L,T) :-
3847 atomic_constant_store_index_name(C,Index,IndexName),
3849 ( member(Constant,Constants),
3850 atomic_constant_store_name(C,Index,Constant,StoreName),
3851 Clause =.. [IndexName,Constant,StoreName]
3854 append(Clauses,T,L).
3856 atomic_constant_store_name(F/A,[Index],Constant,Name) :-
3857 get_target_module(Mod),
3858 atom_concat_list(['$chr_store_atomic_constant_',Mod,'____',F,'___',A,'___',Index,'___',Constant],Name).
3860 atomic_constant_store_index_name(F/A,[Index],Name) :-
3861 get_target_module(Mod),
3862 atom_concat_list(['$chr_store_atomic_constant_',Mod,'____',F,'___',A,'___',Index],Name).
3863 %-------------------------------------------------------------------------------
3864 ground_constants_code(C,Index,Terms,L,T) :-
3865 ground_constant_store_index_name(C,Index,IndexName),
3867 ( member(Constant,Terms),
3868 ground_constant_store_name(C,Index,Constant,StoreName)
3872 replicate(N,[],More),
3873 % writeln(StoreNames),
3874 trie_index([Terms|More],StoreNames,IndexName,L,T).
3876 % ( member(Term,Terms),
3877 % ground_constant_store_name(C,Index,Term,StoreName),
3878 % Clause =.. [IndexName,Term,StoreName] % TODO: replace with trie
3881 % append(Clauses,T,L).
3883 ground_constant_store_name(F/A,Index,Term,Name) :-
3884 get_target_module(Mod),
3885 term_to_atom(Term,Constant),
3886 term_to_atom(Index,IndexAtom),
3887 atom_concat_list(['$chr_store_ground_constant_',Mod,'____',F,'___',A,'___',IndexAtom,'___',Constant],Name).
3889 ground_constant_store_index_name(F/A,Index,Name) :-
3890 get_target_module(Mod),
3891 term_to_atom(Index,IndexAtom),
3892 atom_concat_list(['$chr_store_ground_constant_',Mod,'____',F,'___',A,'___',IndexAtom],Name).
3894 trie_index([Patterns|MorePatterns],Results,Prefix,Clauses,Tail) :-
3895 % writeln(trie_index([Patterns|MorePatterns],Results,Prefix,Clauses,Tail)),
3896 trie_step(Patterns,Prefix,Prefix,MorePatterns,Results,Clauses,Tail).
3898 trie_step([],_,_,[],[],L,L) :- !.
3899 % length MorePatterns == length Patterns == length Results
3900 trie_step(Patterns,Symbol,Prefix,MorePatterns,Results,Clauses,T) :-
3901 % writeln(trie_step(Patterns,Symbol,Prefix,MorePatterns,Results,Clauses,T)),
3902 MorePatterns = [List|_],
3905 ( member(Pattern,Patterns),
3906 functor(Pattern,F,A)
3911 trie_step_cases(FAs,N1,Patterns,MorePatterns,Results,Symbol,Prefix,Clauses,T).
3913 trie_step_cases([],_,_,_,_,_,_,Clauses,Clauses).
3914 trie_step_cases([FA|FAs],N,Pattern,MorePatterns,Results,Symbol,Prefix,Clauses,Tail) :-
3915 trie_step_case(FA,N,Pattern,MorePatterns,Results,Symbol,Prefix,Clauses,Clauses1),
3916 trie_step_cases(FAs,N,Pattern,MorePatterns,Results,Symbol,Prefix,Clauses1,Tail).
3918 trie_step_case(F/A,N,Patterns,MorePatterns,Results,Symbol,Prefix,[Clause|List],Tail) :-
3919 % format('% ~w\n',[F/A]),
3920 Clause = (Head :- Body),
3922 functor(Head,Symbol,N1),
3923 arg(N1,Head,Result),
3924 functor(IndexPattern,F,A),
3925 arg(1,Head,IndexPattern),
3926 Head =.. [_,_|RestArgs],
3927 IndexPattern =.. [_|Args],
3928 append(Args,RestArgs,RecArgs),
3929 ( RecArgs == [Result] ->
3933 rec_cases(Patterns,_,Results,F/A,_,_,MoreResults),
3934 % writeln(MoreResults),
3935 MoreResults = [Result]
3937 gensym(Prefix,RSymbol),
3938 Body =.. [RSymbol|RecArgs],
3939 rec_cases(Patterns,MorePatterns,Results,F/A,Cases,MoreCases,MoreResults),
3940 trie_step(Cases,RSymbol,Prefix,MoreCases,MoreResults,List,Tail)
3943 rec_cases([],[],[],_,[],[],[]).
3944 rec_cases([Pattern|Patterns],[MorePattern|MorePatterns],[Result|Results],F/A,Cases,MoreCases,MoreResults) :-
3945 ( functor(Pattern,F,A), Pattern =.. [_|ArgPatterns], append(ArgPatterns,MorePattern,[Case|MoreCase]) ->
3946 Cases = [Case|NCases],
3947 MoreCases = [MoreCase|NMoreCases],
3948 MoreResults = [Result|NMoreResults],
3949 rec_cases(Patterns,MorePatterns,Results,F/A,NCases,NMoreCases,NMoreResults)
3951 rec_cases(Patterns,MorePatterns,Results,F/A,Cases,MoreCases,MoreResults)
3954 %-------------------------------------------------------------------------------
3955 global_list_store_name(F/A,Name) :-
3956 get_target_module(Mod),
3957 atom_concat_list(['$chr_store_global_list_',Mod,'____',F,'___',A],Name).
3958 global_ground_store_name(F/A,Name) :-
3959 get_target_module(Mod),
3960 atom_concat_list(['$chr_store_global_ground_',Mod,'____',F,'___',A],Name).
3961 global_singleton_store_name(F/A,Name) :-
3962 get_target_module(Mod),
3963 atom_concat_list(['$chr_store_global_singleton_',Mod,'____',F,'___',A],Name).
3965 identifier_store_name(TypeName,Name) :-
3966 get_target_module(Mod),
3967 atom_concat_list(['$chr_identifier_lookup_',Mod,'____',TypeName],Name).
3969 :- chr_constraint prolog_global_variable/1.
3970 :- chr_option(mode,prolog_global_variable(+)).
3972 :- chr_constraint prolog_global_variables/1.
3973 :- chr_option(mode,prolog_global_variables(-)).
3975 prolog_global_variable(Name) \ prolog_global_variable(Name) <=> true.
3977 prolog_global_variables(List), prolog_global_variable(Name) <=>
3979 prolog_global_variables(Tail).
3980 prolog_global_variables(List) <=> List = [].
3983 prolog_global_variables_code(Code) :-
3984 prolog_global_variables(Names),
3988 findall('$chr_prolog_global_variable'(Name),member(Name,Names),NameDeclarations),
3989 Code = [(:- dynamic user:exception/3),
3990 (:- multifile user:exception/3),
3991 (user:exception(undefined_global_variable,Name,retry) :-
3993 '$chr_prolog_global_variable'(Name),
3994 '$chr_initialization'
4003 % prolog_global_variables_code([]).
4005 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4006 %sbag_member_call(S,L,sysh:mem(S,L)).
4007 sbag_member_call(S,L,'chr sbag_member'(S,L)).
4008 %sbag_member_call(S,L,member(S,L)).
4009 update_mutable_call(A,B,'chr update_mutable'( A, B)).
4010 %update_mutable_call(A,B,setarg(1, B, A)).
4011 create_mutable_call(Value,Mutable,true) :- Mutable = mutable(Value).
4012 % create_mutable_call(Value,Mutable,'chr create_mutable'(Value,Mutable)).
4014 % get_suspension_field(Constraint,Susp,FieldName,Value,(Get0,Get1)) :-
4015 % get_dynamic_suspension_term_field(FieldName,Constraint,Susp,Field,Get0),
4016 % create_get_mutable(Value,Field,Get1).
4018 % update_suspension_field(Constraint,Susp,FieldName,NewValue,(Get,Set)) :-
4019 % get_dynamic_suspension_term_field(FieldName,Constraint,Susp,Field,Get),
4020 % update_mutable_call(NewValue,Field,Set).
4022 % get_update_suspension_field(Constraint,Susp,FieldName,Value,NewValue,Get0,Get1,Set) :-
4023 % get_dynamic_suspension_term_field(FieldName,Constraint,Susp,Field,Get0),
4024 % create_get_mutable_ref(Value,Field,Get1),
4025 % update_mutable_call(NewValue,Field,Set).
4027 % create_static_suspension_field(Constraint,Susp,FieldName,Value,Create) :-
4028 % get_static_suspension_term_field(FieldName,Constraint,Susp,Field),
4029 % create_mutable_call(Value,Field,Create).
4031 % get_static_suspension_field(Constraint,Susp,FieldName,Value,Get) :-
4032 % get_static_suspension_term_field(FieldName,Constraint,Susp,Field),
4033 % create_get_mutable(Value,Field,Get).
4035 % get_update_static_suspension_field(Constraint,Susp,SuspTerm,FieldName,Value,NewValue,Get,Set) :-
4036 % get_static_suspension_term_field(FieldName,Constraint,SuspTerm,Field),
4037 % create_get_mutable_ref(Value,Field,Get),
4038 % update_mutable_call(NewValue,Field,Set).
4040 get_suspension_field(Constraint,Susp,FieldName,Value,Get) :-
4041 get_dynamic_suspension_term_field(FieldName,Constraint,Susp,Value,Get).
4043 update_suspension_field(Constraint,Susp,FieldName,NewValue,Set) :-
4044 set_dynamic_suspension_term_field(FieldName,Constraint,Susp,NewValue,Set).
4046 get_update_suspension_field(Constraint,Susp,FieldName,Value,NewValue,true,Get,Set) :-
4047 get_dynamic_suspension_term_field(FieldName,Constraint,Susp,Value,Get),
4048 set_dynamic_suspension_term_field(FieldName,Constraint,Susp,NewValue,Set).
4050 create_static_suspension_field(Constraint,Susp,FieldName,Value,true) :-
4051 get_static_suspension_term_field(FieldName,Constraint,Susp,Value).
4053 get_static_suspension_field(Constraint,Susp,FieldName,Value,true) :-
4054 get_static_suspension_term_field(FieldName,Constraint,Susp,Value).
4056 get_update_static_suspension_field(Constraint,Susp,SuspTerm,FieldName,Value,NewValue,true,Set) :-
4057 get_static_suspension_term_field(FieldName,Constraint,SuspTerm,Value),
4058 set_dynamic_suspension_term_field(FieldName,Constraint,Susp,NewValue,Set).
4060 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4062 enumerate_stores_code(Constraints,Clause) :-
4063 Head = '$enumerate_constraints'(Constraint),
4064 enumerate_store_bodies(Constraints,Constraint,Bodies),
4065 list2disj(Bodies,Body),
4066 Clause = (Head :- Body).
4068 enumerate_store_bodies([],_,[]).
4069 enumerate_store_bodies([C|Cs],Constraint,L) :-
4071 get_store_type(C,StoreType),
4072 enumerate_store_body(StoreType,C,Suspension,SuspensionBody),
4073 get_dynamic_suspension_term_field(arguments,C,Suspension,Arguments,DynamicGoal),
4075 Constraint0 =.. [F|Arguments],
4076 Body = (SuspensionBody, DynamicGoal, Constraint = Constraint0),
4081 enumerate_store_bodies(Cs,Constraint,T).
4083 enumerate_store_body(default,C,Susp,Body) :-
4084 global_list_store_name(C,StoreName),
4085 sbag_member_call(Susp,List,Sbag),
4086 make_get_store_goal(StoreName,List,GetStoreGoal),
4089 GetStoreGoal, % nb_getval(StoreName,List),
4092 % get_constraint_index(C,Index),
4093 % get_target_module(Mod),
4094 % get_max_constraint_index(MaxIndex),
4097 % 'chr default_store'(GlobalStore),
4098 % get_attr(GlobalStore,Mod,Attr)
4101 % NIndex is Index + 1,
4102 % sbag_member_call(Susp,List,Sbag),
4105 % arg(NIndex,Attr,List),
4109 % sbag_member_call(Susp,Attr,Sbag),
4112 % Body = (Body1,Body2).
4113 enumerate_store_body(multi_inthash([Index|_]),C,Susp,Body) :-
4114 multi_inthash_enumerate_store_body(Index,C,Susp,Body).
4115 enumerate_store_body(multi_hash([Index|_]),C,Susp,Body) :-
4116 multi_hash_enumerate_store_body(Index,C,Susp,Body).
4117 enumerate_store_body(atomic_constants(_,_),_,_,_) :- fail.
4118 enumerate_store_body(ground_constants(_,_),_,_,_) :- fail.
4119 enumerate_store_body(global_ground,C,Susp,Body) :-
4120 global_ground_store_name(C,StoreName),
4121 sbag_member_call(Susp,List,Sbag),
4122 make_get_store_goal(StoreName,List,GetStoreGoal),
4125 GetStoreGoal, % nb_getval(StoreName,List),
4128 enumerate_store_body(var_assoc_store(_,_),C,_,Body) :-
4130 enumerate_store_body(global_singleton,C,Susp,Body) :-
4131 global_singleton_store_name(C,StoreName),
4132 make_get_store_goal(StoreName,Susp,GetStoreGoal),
4135 GetStoreGoal, % nb_getval(StoreName,Susp),
4138 enumerate_store_body(multi_store(STs),C,Susp,Body) :-
4141 enumerate_store_body(ST,C,Susp,Body)
4143 enumerate_store_body(identifier_store(Index),C,Susp,Body) :-
4145 enumerate_store_body(type_indexed_identifier_store(Index,IndexType),C,Susp,Body) :-
4148 multi_inthash_enumerate_store_body(I,C,Susp,B) :-
4149 multi_hash_store_name(C,I,StoreName),
4152 nb_getval(StoreName,HT),
4155 multi_hash_enumerate_store_body(I,C,Susp,B) :-
4156 multi_hash_store_name(C,I,StoreName),
4157 make_get_store_goal(StoreName,HT,GetStoreGoal),
4160 GetStoreGoal, % nb_getval(StoreName,HT),
4164 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4173 :- chr_option(mode,prev_guard_list(+,+,+,+,+,+,+,+)).
4174 :- chr_option(mode,prev_guard_list(+,+,+,+,+,+)).
4175 :- chr_option(type_declaration,prev_guard_list(any,any,any,any,any,list)).
4176 :- chr_option(mode,simplify_guards(+)).
4177 :- chr_option(mode,set_all_passive(+)).
4179 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4180 % GUARD SIMPLIFICATION
4181 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4182 % If the negation of the guards of earlier rules entails (part of)
4183 % the current guard, the current guard can be simplified. We can only
4184 % use earlier rules with a head that matches if the head of the current
4185 % rule does, and which make it impossible for the current rule to match
4186 % if they fire (i.e. they shouldn't be propagation rules and their
4187 % head constraints must be subsets of those of the current rule).
4188 % At this point, we know for sure that the negation of the guard
4189 % of such a rule has to be true (otherwise the earlier rule would have
4190 % fired, because of the refined operational semantics), so we can use
4191 % that information to simplify the guard by replacing all entailed
4192 % conditions by true/0. As a consequence, the never-stored analysis
4193 % (in a further phase) will detect more cases of never-stored constraints.
4195 % e.g. c(X),d(Y) <=> X > 0 | ...
4196 % e(X) <=> X < 0 | ...
4197 % c(X) \ d(Y),e(Z) <=> X =< 0, Z >= 0, ... | ...
4201 guard_simplification :-
4202 ( chr_pp_flag(guard_simplification,on) ->
4203 precompute_head_matchings,
4209 % for every rule, we create a prev_guard_list where the last argument
4210 % eventually is a list of the negations of earlier guards
4211 rule(RuleNb,Rule) \ simplify_guards(RuleNb)
4213 Rule = pragma(rule(Head1,Head2,Guard,_B),ids(IDs1,IDs2),_Pragmas,_Name,RuleNb),
4214 append(Head1,Head2,Heads),
4215 make_head_matchings_explicit_not_negated(Heads,MatchingFreeHeads,Matchings),
4216 multiple_occ_constraints_checked([]),
4217 apply_guard_wrt_term(Heads,Guard,SubstitutedHeads),
4219 append(IDs1,IDs2,IDs),
4220 findall(tuple(C,O,RuleNb)-(-RuleNb),(member(ID,IDs),get_occurrence_from_id(C,O,RuleNb,ID)),HeapData),
4222 insert_list_q(HeapData,EmptyHeap,Heap),
4223 next_prev_rule(Heap,_,Heap1),
4224 next_prev_rule(Heap1,PrevRuleNb,NHeap),
4225 prev_guard_list(RuleNb,PrevRuleNb,NHeap,MatchingFreeHeads,Guard,[],Matchings,[SubstitutedHeads]),
4226 NextRule is RuleNb+1,
4227 simplify_guards(NextRule).
4229 next_prev_rule(Heap,RuleNb,NHeap) :-
4230 ( find_min_q(Heap,_-Priority) ->
4231 Priority = (-RuleNb),
4232 normalize_heap(Heap,Priority,NHeap)
4238 normalize_heap(Heap,Priority,NHeap) :-
4239 ( find_min_q(Heap,_-Priority) ->
4240 delete_min_q(Heap,Heap1,tuple(C,O,_)-_),
4243 get_occurrence(C,NO,RuleNb,_),
4244 insert_q(Heap1,tuple(C,NO,RuleNb)-(-RuleNb),Heap2)
4248 normalize_heap(Heap2,Priority,NHeap)
4258 % The negation of the guard of a non-propagation rule is added
4259 % if its kept head constraints are a subset of the kept constraints of
4260 % the rule we're working on, and its removed head constraints (at least one)
4261 % are a subset of the removed constraints.
4263 rule(PrevRuleNb,PrevRule) \ prev_guard_list(RuleNb,PrevRuleNb,Heap,CurrentHeads,G,GuardList,Matchings,GH)
4265 PrevRule = pragma(rule(H1,H2,PrevGuard,_B),_Ids,_Pragmas,_Name,_PrevRuleNb), % PrevRuleNb == _PrevRuleNb
4267 make_head_matchings_explicit(PrevRuleNb,MatchingFreeHeads,PrevMatchings),
4268 setof(Renaming,chr_translate:head_subset(MatchingFreeHeads,CurrentHeads,Renaming),Renamings)
4270 append(H1,H2,Heads),
4271 compute_derived_info(Renamings,PrevMatchings,MatchingFreeHeads,Heads,PrevGuard,Matchings,CurrentHeads,GH,DerivedInfo,GH_New1),
4272 append(GuardList,DerivedInfo,GL1),
4273 normalize_conj_list(GL1,GL),
4274 append(GH_New1,GH,GH1),
4275 normalize_conj_list(GH1,GH_New),
4276 next_prev_rule(Heap,PrevPrevRuleNb,NHeap),
4277 % PrevPrevRuleNb is PrevRuleNb-1,
4278 prev_guard_list(RuleNb,PrevPrevRuleNb,NHeap,CurrentHeads,G,GL,Matchings,GH_New).
4280 % if this isn't the case, we skip this one and try the next rule
4281 prev_guard_list(RuleNb,N,Heap,H,G,GuardList,M,GH)
4284 next_prev_rule(Heap,N1,NHeap),
4286 prev_guard_list(RuleNb,N1,NHeap,H,G,GuardList,M,GH)
4288 prev_guard_list(RuleNb,H,G,GuardList,M,GH)
4291 prev_guard_list(RuleNb,H,G,GuardList,M,GH)
4295 head_types_modes_condition(GH,H,TypeInfo),
4296 conj2list(TypeInfo,TI),
4297 term_variables(H,HeadVars),
4298 append([chr_pp_headvariables(HeadVars)|TI],GuardList,Info),
4299 normalize_conj_list(Info,InfoL),
4300 prev_guard_list(RuleNb,H,G,InfoL,M,[]).
4302 head_types_modes_condition([],H,true).
4303 head_types_modes_condition([GH|GHs],H,(TI1, TI2)) :-
4304 types_modes_condition(H,GH,TI1),
4305 head_types_modes_condition(GHs,H,TI2).
4309 % when all earlier guards are added or skipped, we simplify the guard.
4310 % if it's different from the original one, we change the rule
4312 prev_guard_list(RuleNb,H,G,GuardList,M,[]), rule(RuleNb,Rule)
4314 Rule = pragma(rule(Head1,Head2,G,B),Ids,Pragmas,Name,RuleNb),
4315 G \== true, % let's not try to simplify this ;)
4316 append(M,GuardList,Info),
4317 simplify_guard(G,B,Info,SimpleGuard,NB),
4320 rule(RuleNb,pragma(rule(Head1,Head2,SimpleGuard,NB),Ids,Pragmas,Name,RuleNb)),
4321 prev_guard_list(RuleNb,H,SimpleGuard,GuardList,M,[]).
4323 %% normalize_conj_list(+List,-NormalList) is det.
4325 % Removes =true= elements and flattens out conjunctions.
4327 normalize_conj_list(List,NormalList) :-
4328 list2conj(List,Conj),
4329 conj2list(Conj,NormalList).
4331 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4332 % AUXILIARY PREDICATES (GUARD SIMPLIFICATION)
4333 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4335 compute_derived_info([],_PrevMatchings,_MatchingFreeHeads,_Heads,_PrevGuard,_Matchings,_H,_GH,[],[]).
4336 compute_derived_info([Renaming1|RestRenamings],PrevMatchings,PrevMatchingFreeHeads,PrevHeads,PrevGuard,Matchings,H,GH,[DerivedInfo1|DerivedInfo2],[GH3|GH_New2]) :-
4337 copy_term(PrevMatchings-PrevGuard,FreshMatchings),
4338 variable_replacement(PrevMatchings-PrevGuard,FreshMatchings,ExtraRenaming),
4339 append(Renaming1,ExtraRenaming,Renaming2),
4340 list2conj(PrevMatchings,Match),
4341 negate_b(Match,HeadsDontMatch),
4342 make_head_matchings_explicit_not_negated2(PrevHeads,PrevMatchingFreeHeads,HeadsMatch),
4343 list2conj(HeadsMatch,HeadsMatchBut),
4344 term_variables(Renaming2,RenVars),
4345 term_variables(PrevMatchings-PrevGuard-HeadsMatch,MGVars),
4346 new_vars(MGVars,RenVars,ExtraRenaming2),
4347 append(Renaming2,ExtraRenaming2,Renaming),
4348 ( PrevGuard == true -> % true can't fail
4349 Info_ = HeadsDontMatch
4351 negate_b(PrevGuard,TheGuardFailed),
4352 Info_ = (HeadsDontMatch ; (HeadsMatchBut, TheGuardFailed))
4354 copy_with_variable_replacement(Info_,DerivedInfo1,Renaming),
4355 copy_with_variable_replacement(PrevGuard,RenamedG2,Renaming),
4356 copy_with_variable_replacement(PrevMatchings,RenamedMatchings_,Renaming),
4357 list2conj(RenamedMatchings_,RenamedMatchings),
4358 apply_guard_wrt_term(H,RenamedG2,GH2),
4359 apply_guard_wrt_term(GH2,RenamedMatchings,GH3),
4360 compute_derived_info(RestRenamings,PrevMatchings,PrevMatchingFreeHeads,PrevHeads,PrevGuard,Matchings,H,GH,DerivedInfo2,GH_New2).
4362 simplify_guard(G,B,Info,SG,NB) :-
4364 % writeq(guard_entailment:simplify_guards(Info,B,LG,SGL,NB)),nl,
4365 guard_entailment:simplify_guards(Info,B,LG,SGL,NB),
4370 new_vars([A|As],RV,ER) :-
4371 ( memberchk_eq(A,RV) ->
4374 ER = [A-NewA,NewA-A|ER2],
4378 %% head_subset(+Subset,+MultiSet,-Renaming) is nondet.
4380 % check if a list of constraints is a subset of another list of constraints
4381 % (multiset-subset), meanwhile computing a variable renaming to convert
4382 % one into the other.
4383 head_subset(H,Head,Renaming) :-
4384 head_subset(H,Head,Renaming,[],_).
4386 head_subset([],Remainder,Renaming,Renaming,Remainder).
4387 head_subset([X|Xs],MultiSet,Renaming,Acc,Remainder) :-
4388 head_member(MultiSet,X,NAcc,Acc,Remainder1),
4389 head_subset(Xs,Remainder1,Renaming,NAcc,Remainder).
4391 % check if A is in the list, remove it from Headleft
4392 head_member([X|Xs],A,Renaming,Acc,Remainder) :-
4393 ( variable_replacement(A,X,Acc,Renaming),
4396 Remainder = [X|RRemainder],
4397 head_member(Xs,A,Renaming,Acc,RRemainder)
4399 %-------------------------------------------------------------------------------%
4400 % memoing code to speed up repeated computation
4402 :- chr_constraint precompute_head_matchings/0.
4404 rule(RuleNb,PragmaRule), precompute_head_matchings ==>
4405 PragmaRule = pragma(rule(H1,H2,_G,_B),_Ids,_Pragmas,_Name,_PrevRuleNb),
4406 append(H1,H2,Heads),
4407 make_head_matchings_explicit_(Heads,MatchingFreeHeads,Matchings),
4408 copy_term_nat(MatchingFreeHeads-Matchings,A-B),
4409 make_head_matchings_explicit_memo_table(RuleNb,A,B).
4411 precompute_head_matchings <=> true.
4413 :- chr_constraint make_head_matchings_explicit_memo_table/3.
4414 :- chr_constraint make_head_matchings_explicit_memo_lookup/3.
4416 :- chr_option(mode,make_head_matchings_explicit_memo_table(+,?,?)).
4417 :- chr_option(mode,make_head_matchings_explicit_memo_lookup(+,?,?)).
4419 make_head_matchings_explicit_memo_table(RuleNb,NHeads,Matchings) \
4420 make_head_matchings_explicit_memo_lookup(RuleNb,Q1,Q2)
4424 make_head_matchings_explicit_memo_lookup(_,_,_) <=> fail.
4426 make_head_matchings_explicit(RuleNb,MatchingFreeHeads,Matchings) :-
4427 make_head_matchings_explicit_memo_lookup(RuleNb,A,B),
4428 copy_term_nat(A-B,MatchingFreeHeads-Matchings).
4429 %-------------------------------------------------------------------------------%
4431 make_head_matchings_explicit_(Heads,MatchingFreeHeads,Matchings) :-
4432 extract_arguments(Heads,Arguments),
4433 make_matchings_explicit(Arguments,FreeVariables,[],[],_,Matchings),
4434 substitute_arguments(Heads,FreeVariables,MatchingFreeHeads).
4436 make_head_matchings_explicit_not_negated(Heads,MatchingFreeHeads,Matchings) :-
4437 extract_arguments(Heads,Arguments),
4438 make_matchings_explicit_not_negated(Arguments,FreshVariables,Matchings),
4439 substitute_arguments(Heads,FreshVariables,MatchingFreeHeads).
4441 make_head_matchings_explicit_not_negated2(Heads,MatchingFreeHeads,Matchings) :-
4442 extract_arguments(Heads,Arguments1),
4443 extract_arguments(MatchingFreeHeads,Arguments2),
4444 make_matchings_explicit_not_negated(Arguments1,Arguments2,Matchings).
4446 %% extract_arguments(+ListOfConstraints,-ListOfVariables) is det.
4448 % Returns list of arguments of given list of constraints.
4449 extract_arguments([],[]).
4450 extract_arguments([Constraint|Constraints],AllArguments) :-
4451 Constraint =.. [_|Arguments],
4452 append(Arguments,RestArguments,AllArguments),
4453 extract_arguments(Constraints,RestArguments).
4455 %% substitute_arguments(+InListOfConstraints,ListOfVariables,-OutListOfConstraints) is det.
4457 % Substitutes arguments of constraints with those in the given list.
4459 substitute_arguments([],[],[]).
4460 substitute_arguments([Constraint|Constraints],Variables,[NConstraint|NConstraints]) :-
4461 functor(Constraint,F,N),
4462 split_at(N,Variables,Arguments,RestVariables),
4463 NConstraint =.. [F|Arguments],
4464 substitute_arguments(Constraints,RestVariables,NConstraints).
4466 make_matchings_explicit([],[],_,MC,MC,[]).
4467 make_matchings_explicit([Arg|Args],[NewVar|NewVars],VarAcc,MatchingCondition,MatchingConditionO,Matchings) :-
4469 ( memberchk_eq(Arg,VarAcc) ->
4470 list2disj(MatchingCondition,MatchingCondition_disj),
4471 Matchings = [(MatchingCondition_disj ; NewVar == Arg)|RestMatchings], % or only = ??
4474 Matchings = RestMatchings,
4476 NVarAcc = [Arg|VarAcc]
4478 MatchingCondition2 = MatchingCondition
4481 Arg =.. [F|RecArgs],
4482 make_matchings_explicit(RecArgs,RecVars,VarAcc,MatchingCondition,MatchingCondition_,RecMatchings),
4483 FlatArg =.. [F|RecVars],
4484 ( RecMatchings == [] ->
4485 Matchings = [functor(NewVar,F,A)|RestMatchings]
4487 list2conj(RecMatchings,ArgM_conj),
4488 list2disj(MatchingCondition,MatchingCondition_disj),
4489 ArgM_ = (NewVar \= FlatArg ; MatchingCondition_disj ; ArgM_conj),
4490 Matchings = [ functor(NewVar,F,A) , ArgM_|RestMatchings]
4492 MatchingCondition2 = [ NewVar \= FlatArg |MatchingCondition_],
4493 term_variables(Args,ArgVars),
4494 append(ArgVars,VarAcc,NVarAcc)
4496 make_matchings_explicit(Args,NewVars,NVarAcc,MatchingCondition2,MatchingConditionO,RestMatchings).
4499 %% make_matchings_explicit_not_negated(+ListOfTerms,-ListOfVariables,-ListOfMatchings) is det.
4501 % Returns list of new variables and list of pairwise unifications between given list and variables.
4503 make_matchings_explicit_not_negated([],[],[]).
4504 make_matchings_explicit_not_negated([X|Xs],[Var|Vars],Matchings) :-
4505 Matchings = [Var = X|RMatchings],
4506 make_matchings_explicit_not_negated(Xs,Vars,RMatchings).
4508 %% apply_guard_wrt_term(+ListOfConstraints,+Goal,-NewListOfConstraints) is det.
4510 % (Partially) applies substitutions of =Goal= to given list.
4512 apply_guard_wrt_term([],_Guard,[]).
4513 apply_guard_wrt_term([Term|RH],Guard,[NTerm|RGH]) :-
4515 apply_guard_wrt_variable(Guard,Term,NTerm)
4518 apply_guard_wrt_term(HArgs,Guard,NewHArgs),
4519 NTerm =.. [F|NewHArgs]
4521 apply_guard_wrt_term(RH,Guard,RGH).
4523 %% apply_guard_wrt_variable(+Goal,+Variable,-NVariable) is det.
4525 % (Partially) applies goal =Guard= wrt variable.
4527 apply_guard_wrt_variable((Guard1,Guard2),Variable,NVariable) :- !,
4528 apply_guard_wrt_variable(Guard1,Variable,NVariable1),
4529 apply_guard_wrt_variable(Guard2,NVariable1,NVariable).
4530 apply_guard_wrt_variable(Guard,Variable,NVariable) :-
4531 ( Guard = (X = Y), Variable == X ->
4533 ; Guard = functor(AVariable,Functor,Arity), Variable == AVariable, ground(Functor), ground(Arity) ->
4534 functor(NVariable,Functor,Arity)
4536 NVariable = Variable
4539 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4540 % ALWAYS FAILING HEADS
4541 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4543 rule(RuleNb,Rule) \ prev_guard_list(RuleNb,H,G,GuardList,M,[])
4545 chr_pp_flag(check_impossible_rules,on),
4546 Rule = pragma(rule(Head1,Head2,G,B),Ids,Pragmas,Name,RuleNb),
4547 append(M,GuardList,Info),
4548 guard_entailment:entails_guard(Info,fail)
4550 chr_warning(weird_program,'Heads will never match in ~@.\n\tThis rule will never fire!\n',[format_rule(Rule)]),
4551 set_all_passive(RuleNb).
4553 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4554 % HEAD SIMPLIFICATION
4555 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4557 % now we check the head matchings (guard may have been simplified meanwhile)
4558 prev_guard_list(RuleNb,H,G,GuardList,M,[]) \ rule(RuleNb,Rule)
4560 Rule = pragma(rule(Head1,Head2,G,B),Ids,Pragmas,Name,RuleNb),
4561 simplify_heads(M,GuardList,G,B,NewM,NewB),
4563 extract_arguments(Head1,VH1),
4564 extract_arguments(Head2,VH2),
4565 extract_arguments(H,VH),
4566 replace_some_heads(VH1,VH2,VH,NewM,H1,H2,G,B,NewB_),
4567 substitute_arguments(Head1,H1,NewH1),
4568 substitute_arguments(Head2,H2,NewH2),
4569 append(NewB,NewB_,NewBody),
4570 list2conj(NewBody,BodyMatchings),
4571 NewRule = pragma(rule(NewH1,NewH2,G,(BodyMatchings,B)),Ids,Pragmas,Name,RuleNb),
4572 (Head1 \== NewH1 ; Head2 \== NewH2 )
4574 rule(RuleNb,NewRule).
4576 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4577 % AUXILIARY PREDICATES (HEAD SIMPLIFICATION)
4578 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4580 replace_some_heads(H1,H2,NH,[],H1,H2,G,Body,[]) :- !.
4581 replace_some_heads([],[H2|RH2],[NH|RNH],[M|RM],[],[H2_|RH2_],G,Body,NewB) :- !,
4584 replace_some_heads([],RH2,RNH,RM,[],RH2_,G,Body,NewB)
4586 (M = functor(X,F,A), NH == X ->
4592 H2 =.. [F|OrigArgs],
4593 use_same_args(OrigArgs,A_args,A_args_,G,Body,NewB1),
4596 replace_some_heads([],RH2,RNH,RM,[],RH2_,G,Body,NewB2),
4597 append(NewB1,NewB2,NewB)
4600 replace_some_heads([],RH2,RNH,[M|RM],[],RH2_,G,Body,NewB)
4604 replace_some_heads([H1|RH1],H2,[NH|RNH],[M|RM],[H1_|RH1_],H2_,G,Body,NewB) :- !,
4607 replace_some_heads(RH1,H2,RNH,RM,RH1_,H2_,G,Body,NewB)
4609 (M = functor(X,F,A), NH == X ->
4615 H1 =.. [F|OrigArgs],
4616 use_same_args(OrigArgs,A_args,A_args_,G,Body,NewB1),
4619 replace_some_heads(RH1,H2,RNH,RM,RH1_,H2_,G,Body,NewB2),
4620 append(NewB1,NewB2,NewB)
4623 replace_some_heads(RH1,H2,RNH,[M|RM],RH1_,H2_,G,Body,NewB)
4627 use_same_args([],[],[],_,_,[]).
4628 use_same_args([OA|ROA],[NA|RNA],[Out|ROut],G,Body,NewB) :-
4631 use_same_args(ROA,RNA,ROut,G,Body,NewB).
4632 use_same_args([OA|ROA],[NA|RNA],[Out|ROut],G,Body,NewB) :-
4634 ( common_variables(OA,Body) ->
4635 NewB = [NA = OA|NextB]
4640 use_same_args(ROA,RNA,ROut,G,Body,NextB).
4643 simplify_heads([],_GuardList,_G,_Body,[],[]).
4644 simplify_heads([M|RM],GuardList,G,Body,NewM,NewB) :-
4646 ( (nonvar(B) ; common_variables(B,RM-GuardList)),
4647 guard_entailment:entails_guard(GuardList,(A=B)) ->
4648 ( common_variables(B,G-RM-GuardList) ->
4652 ( common_variables(B,Body) ->
4653 NewB = [A = B|NextB]
4660 ( nonvar(B), functor(B,BFu,BAr),
4661 guard_entailment:entails_guard([functor(A,BFu,BAr)|GuardList],(A=B)) ->
4663 ( common_variables(B,G-RM-GuardList) ->
4666 NewM = [functor(A,BFu,BAr)|NextM]
4673 simplify_heads(RM,[M|GuardList],G,Body,NextM,NextB).
4675 common_variables(B,G) :-
4676 term_variables(B,BVars),
4677 term_variables(G,GVars),
4678 intersect_eq(BVars,GVars,L),
4682 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4683 % ALWAYS FAILING GUARDS
4684 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4686 set_all_passive(RuleNb), occurrence(_,_,RuleNb,ID,_) ==> passive(RuleNb,ID).
4687 set_all_passive(_) <=> true.
4689 prev_guard_list(RuleNb,H,G,GuardList,M,[]),rule(RuleNb,Rule)
4691 chr_pp_flag(check_impossible_rules,on),
4692 Rule = pragma(rule(_,_,G,_),_Ids,_Pragmas,_Name,RuleNb),
4694 % writeq(guard_entailment:entails_guard(GL,fail)),nl,
4695 guard_entailment:entails_guard(GL,fail)
4697 chr_warning(weird_program,'Guard will always fail in ~@.\n\tThis rule will never fire!\n',[format_rule(Rule)]),
4698 set_all_passive(RuleNb).
4702 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4703 % OCCURRENCE SUBSUMPTION
4704 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4707 first_occ_in_rule/4,
4710 :- chr_option(mode,first_occ_in_rule(+,+,+,+)).
4711 :- chr_option(mode,next_occ_in_rule(+,+,+,+,+,+)).
4713 :- chr_constraint multiple_occ_constraints_checked/1.
4714 :- chr_option(mode,multiple_occ_constraints_checked(+)).
4716 prev_guard_list(RuleNb,H,G,GuardList,M,[]),
4717 occurrence(C,O,RuleNb,ID,_),
4718 occurrence(C,O2,RuleNb,ID2,_),
4721 multiple_occ_constraints_checked(Done)
4724 chr_pp_flag(occurrence_subsumption,on),
4725 Rule = pragma(rule(H1,H2,_G,_B),_Ids,_Pragmas,_Name,_RuleNb), % RuleNb == _RuleNb
4727 \+ memberchk_eq(C,Done)
4729 first_occ_in_rule(RuleNb,C,O,ID),
4730 multiple_occ_constraints_checked([C|Done]).
4732 % Find first occurrence of constraint =C= in rule =RuleNb=
4733 occurrence(C,O,RuleNb,ID,_) \ first_occ_in_rule(RuleNb,C,O2,_)
4737 first_occ_in_rule(RuleNb,C,O,ID).
4739 first_occ_in_rule(RuleNb,C,O,ID_o1)
4742 functor(FreshHead,F,A),
4743 next_occ_in_rule(RuleNb,C,O,ID_o1,[],FreshHead).
4745 % Skip passive occurrences.
4746 passive(RuleNb,ID_o2), occurrence(C,O2,RuleNb,ID_o2,_) \ next_occ_in_rule(RuleNb,C,O,ID_o1,Cond,FH)
4750 next_occ_in_rule(RuleNb,C,O2,ID_o1,NewCond,FH).
4752 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)
4755 Rule = pragma(rule(H1,H2,G,B),ids(ID1,ID2),_Pragmas,_Name,RuleNb)
4757 append(H1,H2,Heads),
4758 add_failing_occ(Rule,Heads,H,ID_o1,ExtraCond,FH,M,C,Repl),
4759 ( ExtraCond == [chr_pp_void_info] ->
4760 next_occ_in_rule(RuleNb,C,O2,ID_o2,Cond,FH)
4762 append(ExtraCond,Cond,NewCond),
4763 add_failing_occ(Rule,Heads,H,ID_o2,CheckCond,FH,M,C,Repl2),
4764 copy_term(GuardList,FGuardList),
4765 variable_replacement(GuardList,FGuardList,GLRepl),
4766 copy_with_variable_replacement(GuardList,GuardList2,Repl),
4767 copy_with_variable_replacement(GuardList,GuardList3_,Repl2),
4768 copy_with_variable_replacement(GuardList3_,GuardList3,GLRepl),
4769 append(NewCond,GuardList2,BigCond),
4770 append(BigCond,GuardList3,BigCond2),
4771 copy_with_variable_replacement(M,M2,Repl),
4772 copy_with_variable_replacement(M,M3,Repl2),
4773 append(M3,BigCond2,BigCond3),
4774 append([chr_pp_active_constraint(FH)|M2],BigCond3,Info),
4775 list2conj(CheckCond,OccSubsum),
4776 copy_term((NewCond,BigCond2,Info,OccSubsum,FH),(NewCond2,BigCond2_,Info2,OccSubsum2,FH2)),
4777 ( OccSubsum \= chr_pp_void_info ->
4778 ( guard_entailment:entails_guard(Info2,OccSubsum2) ->
4779 passive(RuleNb,ID_o2)
4786 next_occ_in_rule(RuleNb,C,O2,ID_o2,NewCond,FH)
4790 next_occ_in_rule(RuleNb,C,O,ID,Cond,Args)
4794 prev_guard_list(RuleNb,H,G,GuardList,M,[]), multiple_occ_constraints_checked(Done)
4798 add_failing_occ(Rule,Heads,NH,ID_o1,FailCond,FH,M,C,Repl) :-
4799 Rule = pragma(rule(H1,H2,G,B),ids(ID1,ID2),_Pragmas,_Name,RuleNb),
4800 append(ID2,ID1,IDs),
4801 missing_partner_cond(Heads,NH,IDs,ID_o1,MPCond,H,C),
4802 copy_term((H,Heads,NH),(FH2,FHeads,NH2)),
4803 variable_replacement((H,Heads,NH),(FH2,FHeads,NH2),Repl),
4804 copy_with_variable_replacement(G,FG,Repl),
4805 extract_explicit_matchings(FG,FG2),
4806 negate_b(FG2,NotFG),
4807 copy_with_variable_replacement(MPCond,FMPCond,Repl),
4808 ( safely_unifiable(FH,FH2), FH=FH2 ->
4809 FailCond = [(NotFG;FMPCond)]
4811 % in this case, not much can be done
4812 % e.g. c(f(...)), c(g(...)) <=> ...
4813 FailCond = [chr_pp_void_info]
4816 missing_partner_cond([],[],[],ID_o1,fail,H2,C).
4817 missing_partner_cond([H|Hs],[H2|H2s],[ID_o1|IDs],ID_o1,Cond,H,C) :- !,
4818 missing_partner_cond(Hs,H2s,IDs,ID_o1,Cond,H,C).
4819 missing_partner_cond([H|Hs],[NH|NHs],[ID|IDs],ID_o1,Cond,H2,F/A) :-
4820 Cond = (chr_pp_not_in_store(H);Cond1),
4821 missing_partner_cond(Hs,NHs,IDs,ID_o1,Cond1,H2,F/A).
4823 extract_explicit_matchings((A,B),D) :- !,
4824 ( extract_explicit_matchings(A) ->
4825 extract_explicit_matchings(B,D)
4828 extract_explicit_matchings(B,E)
4830 extract_explicit_matchings(A,D) :- !,
4831 ( extract_explicit_matchings(A) ->
4837 extract_explicit_matchings(A=B) :-
4838 var(A), var(B), !, A=B.
4839 extract_explicit_matchings(A==B) :-
4840 var(A), var(B), !, A=B.
4842 safely_unifiable(H,I) :- var(H), !.
4843 safely_unifiable([],[]) :- !.
4844 safely_unifiable([H|Hs],[I|Is]) :- !,
4845 safely_unifiable(H,I),
4846 safely_unifiable(Hs,Is).
4847 safely_unifiable(H,I) :-
4852 safely_unifiable(HA,IA).
4856 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4858 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4864 get_type_definition/2,
4865 get_constraint_type/2.
4868 :- chr_option(mode,type_definition(?,?)).
4869 :- chr_option(mode,get_type_definition(?,?)).
4870 :- chr_option(mode,type_alias(?,?)).
4871 :- chr_option(mode,constraint_type(+,+)).
4872 :- chr_option(mode,get_constraint_type(+,-)).
4874 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4875 % Consistency checks of type aliases
4877 type_alias(T,T2) <=>
4878 nonvar(T),nonvar(T2),functor(T,F,A),functor(T2,F,A),
4879 copy_term((T,T2),(X,Y)),oneway_unification(Y,X) |
4880 chr_error(type_error,'Cyclic alias definition: "~w".\n',[(T == T2)]).
4882 type_alias(T1,A1), type_alias(T2,A2) <=>
4883 nonvar(T1),nonvar(T2),functor(T1,F,A),functor(T2,F,A),
4885 copy_term_nat(T1,T1_),
4886 copy_term_nat(T2,T2_),
4888 chr_error(type_error,
4889 '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_]).
4891 type_alias(T,B) \ type_alias(X,T2) <=>
4892 nonvar(T),nonvar(T2),functor(T,F,A),functor(T2,F,A),
4893 copy_term_nat((X,T2,T,B),(X2,T3,T1,D1)),oneway_unification(T3,T1) |
4894 chr_info(type_information,'Inferring `~w\' from `~w\' and `~w\'.\n',[X2==D1,X==T2,T==B]),
4897 oneway_unification(X,Y) :-
4898 term_variables(X,XVars),
4899 chr_runtime:lockv(XVars),
4901 chr_runtime:unlockv(XVars).
4903 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4904 % Consistency checks of type definitions
4906 type_definition(T1,_), type_definition(T2,_)
4908 functor(T1,F,A), functor(T2,F,A)
4910 chr_error(type_error,'Multiple definitions for type: ~w/~w.\n',[F,A]).
4912 type_definition(T1,_), type_alias(T2,_)
4914 functor(T1,F,A), functor(T2,F,A)
4916 chr_error(type_error,'Multiple definitions for type, once in a type definition and once as a type alias: ~w/~w.\n',[F,A]).
4918 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4919 %% get_type_definition(+Type,-Definition) is semidet.
4920 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4922 get_type_definition(T,Def)
4926 chr_error(type_error,'Non-ground type in constraint definition: "~w".\n',[T]).
4928 type_alias(T,D) \ get_type_definition(T2,Def)
4930 nonvar(T),nonvar(T2),functor(T,F,A),functor(T2,F,A),
4931 copy_term_nat((T,D),(T1,D1)),T1=T2
4933 ( get_type_definition(D1,Def) ->
4936 chr_error(type_error,'Could not find type definition for "~w" (accessed via alias "~w").\n',[D1,T1]), fail
4939 type_definition(T,D) \ get_type_definition(T2,Def)
4941 nonvar(T),nonvar(T2),functor(T,F,A),functor(T2,F,A),
4942 copy_term_nat((T,D),(T1,D1)),T1=T2
4946 get_type_definition(Type,Def)
4948 atomic_builtin_type(Type,_,_)
4952 get_type_definition(Type,Def)
4954 compound_builtin_type(Type,_,_)
4958 get_type_definition(X,Y) <=> fail.
4960 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4961 %% get_type_definition_det(+Type,-Definition) is det.
4962 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4963 get_type_definition_det(Type,Definition) :-
4964 ( get_type_definition(Type,Definition) ->
4967 chr_error(type,'Could not find type definition for type `~w\'.\n',[Type])
4970 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
4971 %% get_constraint_type(+ConstraintSymbol,-Types) is semidet.
4973 % Return argument types of =ConstraintSymbol=, but fails if none where
4975 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
4976 constraint_type(C,T) \ get_constraint_type(C,Type) <=> Type = T.
4977 get_constraint_type(_,_) <=> fail.
4979 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
4980 %% get_constraint_type_det(+ConstraintSymbol,-Types) is det.
4982 % Like =get_constraint_type/2=, but returns list of =any= types when
4983 % no types are declared.
4984 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
4985 get_constraint_type_det(ConstraintSymbol,Types) :-
4986 ( get_constraint_type(ConstraintSymbol,Types) ->
4989 ConstraintSymbol = _ / N,
4990 replicate(N,any,Types)
4992 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
4993 %% unalias_type(+Alias,-Type) is det.
4995 % Follows alias chain until base type is reached.
4996 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
4997 :- chr_constraint unalias_type/2.
5000 unalias_type(Alias,BaseType)
5007 type_alias(AliasProtoType,ProtoType) \ unalias_type(Alias,BaseType)
5009 nonvar(AliasProtoType),
5011 functor(AliasProtoType,F,A),
5013 copy_term_nat((AliasProtoType,ProtoType),(AliasInstance,Type)),
5014 Alias = AliasInstance
5016 unalias_type(Type,BaseType).
5018 unalias_type_definition @
5019 type_definition(ProtoType,Definition) \ unalias_type(Alias,BaseType)
5023 functor(ProtoType,F,A),
5028 unalias_atomic_builtin @
5029 unalias_type(Alias,BaseType)
5031 atomic_builtin_type(Alias,_,_)
5035 unalias_compound_builtin @
5036 unalias_type(Alias,BaseType)
5038 compound_builtin_type(Alias,_,_)
5042 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5043 %% types_modes_condition(+Heads,+UnrollHeads,-Condition) is det.
5044 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5045 :- chr_constraint types_modes_condition/3.
5046 :- chr_option(mode,types_modes_condition(+,+,?)).
5047 :- chr_option(type_declaration,types_modes_condition(list,list,goal)).
5049 types_modes_condition([],[],T) <=> T=true.
5051 constraint_mode(F/A,Modes) \ types_modes_condition([Head|Heads],[UnrollHead|UnrollHeads],Condition)
5056 Condition = (ModesCondition, TypesCondition, RestCondition),
5057 modes_condition(Modes,Args,ModesCondition),
5058 get_constraint_type_det(F/A,Types),
5059 UnrollHead =.. [_|RealArgs],
5060 types_condition(Types,Args,RealArgs,Modes,TypesCondition),
5061 types_modes_condition(Heads,UnrollHeads,RestCondition).
5063 types_modes_condition([Head|_],_,_)
5066 chr_error(internal,'Mode information missing for ~w.\n',[F/A]).
5069 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5070 %% modes_condition(+Modes,+Args,-Condition) is det.
5072 % Return =Condition= on =Args= that checks =Modes=.
5073 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5074 modes_condition([],[],true).
5075 modes_condition([Mode|Modes],[Arg|Args],Condition) :-
5077 Condition = ( ground(Arg) , RCondition )
5079 Condition = ( var(Arg) , RCondition )
5081 Condition = RCondition
5083 modes_condition(Modes,Args,RCondition).
5085 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5086 %% types_condition(+Types,+Args,+UnrollArgs,+Modes,-Condition) is det.
5088 % Return =Condition= on =Args= that checks =Types= given =Modes=.
5089 % =UnrollArgs= controls the depth of type definition unrolling.
5090 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5091 types_condition([],[],[],[],true).
5092 types_condition([Type|Types],[Arg|Args],[UnrollArg|UnrollArgs],[Mode|Modes],(DisjTypeConditionList,RCondition)) :-
5094 TypeConditionList = [true] % TypeConditionList = [var(Arg)] already encoded in modes_condition
5096 get_type_definition_det(Type,Def),
5097 type_condition(Def,Arg,UnrollArg,Mode,TypeConditionList1),
5099 TypeConditionList = TypeConditionList1
5101 TypeConditionList = [(\+ ground(Arg))|TypeConditionList1]
5104 list2disj(TypeConditionList,DisjTypeConditionList),
5105 types_condition(Types,Args,UnrollArgs,Modes,RCondition).
5107 type_condition([],_,_,_,[]).
5108 type_condition([DefCase|DefCases],Arg,UnrollArg,Mode,[Condition|Conditions]) :-
5110 chr_error(type,'Unexpected variable type in type definition!\n',[]) % Condition = true
5111 ; atomic_builtin_type(DefCase,Arg,Condition) ->
5113 ; compound_builtin_type(DefCase,Arg,Condition) ->
5116 type_def_case_condition(DefCase,Arg,UnrollArg,Mode,Condition)
5118 type_condition(DefCases,Arg,UnrollArg,Mode,Conditions).
5120 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5121 :- chr_type atomic_builtin_type ---> any
5128 ; chr_identifier(any).
5129 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5131 atomic_builtin_type(any,_Arg,true).
5132 atomic_builtin_type(dense_int,Arg,(integer(Arg),Arg>=0)).
5133 atomic_builtin_type(int,Arg,integer(Arg)).
5134 atomic_builtin_type(number,Arg,number(Arg)).
5135 atomic_builtin_type(float,Arg,float(Arg)).
5136 atomic_builtin_type(natural,Arg,(integer(Arg),Arg>=0)).
5137 atomic_builtin_type(chr_identifier,_Arg,true).
5139 compound_builtin_type(chr_identifier(_),_Arg,true).
5141 type_def_case_condition(DefCase,Arg,UnrollArg,Mode,Condition) :-
5142 ( nonvar(DefCase) ->
5143 functor(DefCase,F,A),
5145 Condition = (Arg = DefCase)
5147 Condition = functor(Arg,F,A)
5148 ; functor(UnrollArg,F,A) ->
5149 Condition = (functor(Arg,F,A),Arg=Template,ArgsCondition),
5150 DefCase =.. [_|ArgTypes],
5151 UnrollArg =.. [_|UnrollArgs],
5152 functor(Template,F,A),
5153 Template =.. [_|TemplateArgs],
5154 replicate(A,Mode,ArgModes),
5155 types_condition(ArgTypes,TemplateArgs,UnrollArgs,ArgModes,ArgsCondition)
5157 Condition = functor(Arg,F,A)
5160 chr_error(internal,'Illegal type definition (must be nonvar).\n',[])
5164 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5165 % Static type checking
5166 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5167 % Checks head constraints and CHR constraint calls in bodies.
5170 % - type clashes involving built-in types
5171 % - Prolog built-ins in guard and body
5172 % - indicate position in terms in error messages
5173 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5175 static_type_check/0.
5177 :- chr_type type_error_src ---> head(any) ; body(any).
5179 rule(_,Rule), static_type_check
5181 copy_term_nat(Rule,RuleCopy),
5182 RuleCopy = pragma(rule(Head1,Head2,G,Body),ids(IDs1,IDs2),Pragmas,Name,RuleNb),
5185 ( static_type_check_heads(Head1),
5186 static_type_check_heads(Head2),
5187 conj2list(Body,GoalList),
5188 static_type_check_body(GoalList)
5191 ( Error = invalid_functor(Src,Term,Type) ->
5192 chr_error(type_error,'Invalid functor in ~@ of ~@:\n\t\tfound `~w\',\n\t\texpected type `~w\'!\n',
5193 [chr_translate:format_src(Src),format_rule(Rule),Term,Type])
5194 ; Error = type_clash(Var,Src1,Src2,Type1,Type2) ->
5195 chr_error(type_error,'Type clash for variable ~w in ~@:\n\t\texpected type ~w in ~@\n\t\texpected type ~w in ~@\n',
5196 [Var,format_rule(Rule),Type1,chr_translate:format_src(Src1),Type2,chr_translate:format_src(Src2)])
5199 fail % cleanup constraints
5205 static_type_check <=> true.
5207 static_type_check_heads([]).
5208 static_type_check_heads([Head|Heads]) :-
5209 static_type_check_head(Head),
5210 static_type_check_heads(Heads).
5212 static_type_check_head(Head) :-
5214 get_constraint_type_det(F/A,Types),
5216 maplist(static_type_check_term(head(Head)),Args,Types).
5218 static_type_check_body([]).
5219 static_type_check_body([Goal|Goals]) :-
5221 get_constraint_type_det(F/A,Types),
5223 maplist(static_type_check_term(body(Goal)),Args,Types),
5224 static_type_check_body(Goals).
5226 :- chr_constraint static_type_check_term/3.
5227 :- chr_option(mode,static_type_check_term(?,?,?)).
5228 :- chr_option(type_declaration,static_type_check_term(type_error_src,any,any)).
5230 static_type_check_term(Src,Term,Type)
5234 static_type_check_var(Src,Term,Type).
5235 static_type_check_term(Src,Term,Type)
5237 atomic_builtin_type(Type,Term,Goal)
5242 throw(type_error(invalid_functor(Src,Term,Type)))
5244 static_type_check_term(Src,Term,Type)
5246 compound_builtin_type(Type,Term,Goal)
5251 throw(type_error(invalid_functor(Src,Term,Type)))
5253 type_alias(AType,ADef) \ static_type_check_term(Src,Term,Type)
5258 copy_term_nat(AType-ADef,Type-Def),
5259 static_type_check_term(Src,Term,Def).
5261 type_definition(AType,ADef) \ static_type_check_term(Src,Term,Type)
5266 copy_term_nat(AType-ADef,Type-Variants),
5267 functor(Term,TF,TA),
5268 ( member(Variant,Variants), functor(Variant,TF,TA) ->
5270 Variant =.. [_|Types],
5271 maplist(static_type_check_term(Src),Args,Types)
5273 throw(type_error(invalid_functor(Src,Term,Type)))
5276 static_type_check_term(Src,Term,Type)
5278 chr_error(internal,'Undefined type ~w while type checking term ~w in ~@.\n',[Type,Term,chr_translate:format_src(Src)]).
5280 :- chr_constraint static_type_check_var/3.
5281 :- chr_option(mode,static_type_check_var(?,-,?)).
5282 :- chr_option(type_declaration,static_type_check_term(type_error_src,any,any)).
5284 type_alias(AType,ADef) \ static_type_check_var(Src,Var,Type)
5289 copy_term_nat(AType-ADef,Type-Def),
5290 static_type_check_var(Src,Var,Def).
5292 static_type_check_var(Src,Var,Type)
5294 atomic_builtin_type(Type,_,_)
5296 static_atomic_builtin_type_check_var(Src,Var,Type).
5298 static_type_check_var(Src,Var,Type)
5300 compound_builtin_type(Type,_,_)
5305 static_type_check_var(Src1,Var,Type1), static_type_check_var(Src2,Var,Type2)
5309 throw(type_error(type_clash(Var,Src1,Src2,Type1,Type2))).
5311 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5312 %% static_atomic_builtin_type_check_var(+type_error_src,-Var,+atomic_builtin_type)
5313 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5314 :- chr_constraint static_atomic_builtin_type_check_var/3.
5315 :- chr_option(mode,static_type_check_var(?,-,+)).
5316 :- chr_option(type_declaration,static_type_check_term(type_error_src,any,atomic_builtin_type)).
5318 static_atomic_builtin_type_check_var(_,_,any) <=> true.
5319 static_atomic_builtin_type_check_var(_,Var,BuiltinType) \ static_atomic_builtin_type_check_var(_,Var,BuiltinType)
5322 static_atomic_builtin_type_check_var(_,Var,float) \ static_atomic_builtin_type_check_var(_,Var,number)
5325 static_atomic_builtin_type_check_var(_,Var,int) \ static_atomic_builtin_type_check_var(_,Var,number)
5328 static_atomic_builtin_type_check_var(_,Var,natural) \ static_atomic_builtin_type_check_var(_,Var,number)
5331 static_atomic_builtin_type_check_var(_,Var,dense_int) \ static_atomic_builtin_type_check_var(_,Var,number)
5334 static_atomic_builtin_type_check_var(_,Var,natural) \ static_atomic_builtin_type_check_var(_,Var,int)
5337 static_atomic_builtin_type_check_var(_,Var,dense_int) \ static_atomic_builtin_type_check_var(_,Var,int)
5340 static_atomic_builtin_type_check_var(_,Var,dense_int) \ static_atomic_builtin_type_check_var(_,Var,natural)
5343 static_atomic_builtin_type_check_var(Src1,Var,Type1), static_atomic_builtin_type_check_var(Src2,Var,Type2)
5345 throw(type_error(type_clash(Var,Src1,Src2,Type1,Type2))).
5347 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5348 %% format_src(+type_error_src) is det.
5349 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5350 format_src(head(Head)) :- format('head ~w',[Head]).
5351 format_src(body(Goal)) :- format('body goal ~w',[Goal]).
5353 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5354 % Dynamic type checking
5355 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5358 dynamic_type_check/0,
5359 dynamic_type_check_clauses/1,
5360 get_dynamic_type_check_clauses/1.
5362 generate_dynamic_type_check_clauses(Clauses) :-
5363 ( chr_pp_flag(debugable,on) ->
5365 get_dynamic_type_check_clauses(Clauses0),
5367 [('$dynamic_type_check'(Type,Term) :-
5368 throw(error(type_error(Type,Term),context(_,'CHR Runtime Type Error')))
5375 type_definition(T,D), dynamic_type_check
5377 copy_term_nat(T-D,Type-Definition),
5378 maplist(dynamic_type_check_clause(Type),Definition,DynamicChecks),
5379 dynamic_type_check_clauses(DynamicChecks).
5380 type_alias(A,B), dynamic_type_check
5382 copy_term_nat(A-B,Alias-Body),
5383 dynamic_type_check_alias_clause(Alias,Body,Clause),
5384 dynamic_type_check_clauses([Clause]).
5386 dynamic_type_check <=>
5388 ('$dynamic_type_check'(Type,Term) :- Goal),
5389 ( atomic_builtin_type(Type,Term,Goal) ; compound_builtin_type(Type,Term,Goal) ),
5392 dynamic_type_check_clauses(BuiltinChecks).
5394 dynamic_type_check_clause(T,DC,Clause) :-
5395 copy_term(T-DC,Type-DefinitionClause),
5396 functor(DefinitionClause,F,A),
5398 DefinitionClause =.. [_|DCArgs],
5399 Term =.. [_|TermArgs],
5400 maplist(dynamic_type_check_call,DCArgs,TermArgs,RecursiveCallList),
5401 list2conj(RecursiveCallList,RecursiveCalls),
5403 '$dynamic_type_check'(Type,Term) :-
5407 dynamic_type_check_alias_clause(Alias,Body,Clause) :-
5409 '$dynamic_type_check'(Alias,Term) :-
5410 '$dynamic_type_check'(Body,Term)
5413 dynamic_type_check_call(Type,Term,Call) :-
5414 % ( nonvar(Type), atomic_builtin_type(Type,Term,Goal) ->
5415 % Call = when(nonvar(Term),Goal)
5416 % ; nonvar(Type), compound_builtin_type(Type,Term,Goal) ->
5417 % Call = when(nonvar(Term),Goal)
5422 Call = when(nonvar(Term),once('$dynamic_type_check'(Type,Term)))
5427 dynamic_type_check_clauses(C1), dynamic_type_check_clauses(C2)
5430 dynamic_type_check_clauses(C).
5432 get_dynamic_type_check_clauses(Q), dynamic_type_check_clauses(C)
5435 get_dynamic_type_check_clauses(Q)
5439 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5441 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5442 % Some optimizations can be applied for atomic types...
5443 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5445 atomic_types_suspended_constraint(C) :-
5447 get_constraint_type(C,ArgTypes),
5448 get_constraint_mode(C,ArgModes),
5449 findall(I,between(1,N,I),Indexes),
5450 maplist(atomic_types_suspended_constraint(C),ArgTypes,ArgModes,Indexes).
5452 atomic_types_suspended_constraint(C,Type,Mode,Index) :-
5453 ( is_indexed_argument(C,Index) ->
5463 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5464 %% atomic_type(+Type) is semidet.
5466 % Succeeds when all values of =Type= are atomic.
5467 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5468 :- chr_constraint atomic_type/1.
5470 atomic_type(Type) <=> atomic_builtin_type(Type,_,_) | Type \== any.
5472 type_definition(TypePat,Def) \ atomic_type(Type)
5474 functor(Type,F,A), functor(TypePat,F,A)
5476 forall(member(Term,Def),atomic(Term)).
5478 type_alias(TypePat,Alias) \ atomic_type(Type)
5480 functor(Type,F,A), functor(TypePat,F,A)
5483 copy_term_nat(TypePat-Alias,Type-NType),
5486 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5487 %% enumerated_atomic_type(+Type,-Atoms) is semidet.
5489 % Succeeds when all values of =Type= are atomic
5490 % and the atom values are finitely enumerable.
5491 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5492 :- chr_constraint enumerated_atomic_type/2.
5494 enumerated_atomic_type(Type,_) <=> atomic_builtin_type(Type,_,_) | fail.
5496 type_definition(TypePat,Def) \ enumerated_atomic_type(Type,Atoms)
5498 functor(Type,F,A), functor(TypePat,F,A)
5500 forall(member(Term,Def),atomic(Term)),
5503 type_alias(TypePat,Alias) \ enumerated_atomic_type(Type,Atoms)
5505 functor(Type,F,A), functor(TypePat,F,A)
5508 copy_term_nat(TypePat-Alias,Type-NType),
5509 enumerated_atomic_type(NType,Atoms).
5510 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5513 stored/3, % constraint,occurrence,(yes/no/maybe)
5514 stored_completing/3,
5517 is_finally_stored/1,
5518 check_all_passive/2.
5520 :- chr_option(mode,stored(+,+,+)).
5521 :- chr_option(type_declaration,stored(any,int,storedinfo)).
5522 :- chr_type storedinfo ---> yes ; no ; maybe.
5523 :- chr_option(mode,stored_complete(+,+,+)).
5524 :- chr_option(mode,maybe_complementary_guards(+,+,?,?)).
5525 :- chr_option(mode,guard_list(+,+,+,+)).
5526 :- chr_option(mode,check_all_passive(+,+)).
5527 :- chr_option(type_declaration,check_all_passive(any,list)).
5529 % change yes in maybe when yes becomes passive
5530 passive(RuleNb,ID), occurrence(C,O,RuleNb,ID,_) \
5531 stored(C,O,yes), stored_complete(C,RO,Yesses)
5532 <=> O < RO | NYesses is Yesses - 1,
5533 stored(C,O,maybe), stored_complete(C,RO,NYesses).
5534 % change yes in maybe when not observed
5535 ai_not_observed(C,O) \ stored(C,O,yes), stored_complete(C,RO,Yesses)
5537 NYesses is Yesses - 1,
5538 stored(C,O,maybe), stored_complete(C,RO,NYesses).
5540 occurrence(_,_,RuleNb,ID,_), occurrence(C2,_,RuleNb,_,_), stored_complete(C2,RO,0), max_occurrence(C2,MO2)
5541 ==> RO =< MO2 | % C2 is never stored
5547 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5549 rule(RuleNb,Rule),passive(RuleNb,Id) ==>
5550 Rule = pragma(rule(Head1,Head2,G,B),ids([Id|IDs1],IDs2),Pragmas,Name,RuleNb) |
5551 append(IDs1,IDs2,I), check_all_passive(RuleNb,I).
5553 rule(RuleNb,Rule),passive(RuleNb,Id) ==>
5554 Rule = pragma(rule(Head1,Head2,G,B),ids([],[Id|IDs2]),Pragmas,Name,RuleNb) |
5555 check_all_passive(RuleNb,IDs2).
5557 passive(RuleNb,Id) \ check_all_passive(RuleNb,[Id|IDs]) <=>
5558 check_all_passive(RuleNb,IDs).
5560 rule(RuleNb,Rule) \ check_all_passive(RuleNb,[]) <=>
5561 chr_warning(weird_program,'All heads passive in ~@.\n\tThis rule never fires. Please check your program.\n',[format_rule(Rule)]).
5563 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5565 % collect the storage information
5566 stored(C,O,yes) \ stored_completing(C,O,Yesses)
5567 <=> NO is O + 1, NYesses is Yesses + 1,
5568 stored_completing(C,NO,NYesses).
5569 stored(C,O,maybe) \ stored_completing(C,O,Yesses)
5571 stored_completing(C,NO,Yesses).
5573 stored(C,O,no) \ stored_completing(C,O,Yesses)
5574 <=> stored_complete(C,O,Yesses).
5575 stored_completing(C,O,Yesses)
5576 <=> stored_complete(C,O,Yesses).
5578 stored_complete(C,O,Yesses), occurrence(C,O2,RuleNb,Id,_) ==>
5579 O2 > O | passive(RuleNb,Id).
5581 % decide whether a constraint is stored
5582 max_occurrence(C,MO), stored_complete(C,RO,0) \ is_stored(C)
5583 <=> RO =< MO | fail.
5584 is_stored(C) <=> true.
5586 % decide whether a constraint is suspends after occurrences
5587 max_occurrence(C,MO), stored_complete(C,RO,_) \ is_finally_stored(C)
5588 <=> RO =< MO | fail.
5589 is_finally_stored(C) <=> true.
5591 storage_analysis(Constraints) :-
5592 ( chr_pp_flag(storage_analysis,on) ->
5593 check_constraint_storages(Constraints)
5598 check_constraint_storages([]).
5599 check_constraint_storages([C|Cs]) :-
5600 check_constraint_storage(C),
5601 check_constraint_storages(Cs).
5603 check_constraint_storage(C) :-
5604 get_max_occurrence(C,MO),
5605 check_occurrences_storage(C,1,MO).
5607 check_occurrences_storage(C,O,MO) :-
5609 stored_completing(C,1,0)
5611 check_occurrence_storage(C,O),
5613 check_occurrences_storage(C,NO,MO)
5616 check_occurrence_storage(C,O) :-
5617 get_occurrence(C,O,RuleNb,ID),
5618 ( is_passive(RuleNb,ID) ->
5621 get_rule(RuleNb,PragmaRule),
5622 PragmaRule = pragma(rule(Heads1,Heads2,Guard,Body),ids(IDs1,IDs2),_,_,_),
5623 ( select2(ID,Head1,IDs1,Heads1,RIDs1,RHeads1) ->
5624 check_storage_head1(Head1,O,Heads1,Heads2,Guard)
5625 ; select2(ID,Head2,IDs2,Heads2,RIDs2,RHeads2) ->
5626 check_storage_head2(Head2,O,Heads1,Body)
5630 check_storage_head1(Head,O,H1,H2,G) :-
5635 % writeq(guard_entailment:entails_guard([chr_pp_headvariables(Head)],G)),nl,
5636 guard_entailment:entails_guard([chr_pp_headvariables(Head)],G),
5638 no_matching(L,[]) ->
5645 no_matching([X|Xs],Prev) :-
5647 \+ memberchk_eq(X,Prev),
5648 no_matching(Xs,[X|Prev]).
5650 check_storage_head2(Head,O,H1,B) :-
5654 ( H1 \== [], B == true )
5656 % \+ is_observed(F/A,O) % always fails because observation analysis has not been performed yet
5664 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5666 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5667 %% ____ _ ____ _ _ _ _
5668 %% | _ \ _ _| | ___ / ___|___ _ __ ___ _ __ (_) | __ _| |_(_) ___ _ __
5669 %% | |_) | | | | |/ _ \ | | / _ \| '_ ` _ \| '_ \| | |/ _` | __| |/ _ \| '_ \
5670 %% | _ <| |_| | | __/ | |__| (_) | | | | | | |_) | | | (_| | |_| | (_) | | | |
5671 %% |_| \_\\__,_|_|\___| \____\___/|_| |_| |_| .__/|_|_|\__,_|\__|_|\___/|_| |_|
5674 constraints_code(Constraints,Clauses) :-
5675 (chr_pp_flag(reduced_indexing,on),
5676 \+ forsome(C,Constraints,\+ chr_translate:only_ground_indexed_arguments(C)) ->
5677 none_suspended_on_variables
5681 constraints_code1(Constraints,Clauses,[]).
5683 %===============================================================================
5684 :- chr_constraint constraints_code1/3.
5685 :- chr_option(mode,constraints_code1(+,+,+)).
5686 :- chr_option(type_declaration,constraints_code1(list,any,any)).
5687 %-------------------------------------------------------------------------------
5688 constraints_code1([],L,T) <=> L = T.
5689 constraints_code1([C|RCs],L,T)
5691 constraint_code(C,L,T1),
5692 constraints_code1(RCs,T1,T).
5693 %===============================================================================
5694 :- chr_constraint constraint_code/3.
5695 :- chr_option(mode,constraint_code(+,+,+)).
5696 %-------------------------------------------------------------------------------
5697 %% Generate code for a single CHR constraint
5698 constraint_code(Constraint, L, T)
5700 | ( (chr_pp_flag(debugable,on) ;
5701 is_stored(Constraint), ( has_active_occurrence(Constraint); chr_pp_flag(late_allocation,off)),
5702 ( may_trigger(Constraint) ;
5703 get_allocation_occurrence(Constraint,AO),
5704 get_max_occurrence(Constraint,MO), MO >= AO ) )
5706 constraint_prelude(Constraint,Clause),
5707 add_dummy_location(Clause,LocatedClause),
5708 L = [LocatedClause | L1]
5713 occurrences_code(Constraint,1,Id,NId,L1,L2),
5714 gen_cond_attach_clause(Constraint,NId,L2,T).
5716 %===============================================================================
5717 %% Generate prelude predicate for a constraint.
5718 %% f(...) :- f/a_0(...,Susp).
5719 constraint_prelude(F/A, Clause) :-
5720 vars_susp(A,Vars,Susp,VarsSusp),
5721 Head =.. [ F | Vars],
5722 make_suspension_continuation_goal(F/A,VarsSusp,Continuation),
5723 build_head(F,A,[0],VarsSusp,Delegate),
5724 ( chr_pp_flag(debugable,on) ->
5725 insert_constraint_goal(F/A,Susp,Vars,InsertCall),
5726 attach_constraint_atom(F/A,Vars2,Susp,AttachCall),
5727 delay_phase_end(validate_store_type_assumptions,chr_translate:update_suspension_field(F/A,Susp,state,inactive,Inactive)),
5728 insert_constraint_internal_constraint_goal(F/A, Vars2, Susp, Continuation, Vars,InsertGoal),
5730 ( get_constraint_type(F/A,ArgTypeList) ->
5731 maplist(dynamic_type_check_call,ArgTypeList,Vars,DynamicTypeCheckList),
5732 list2conj(DynamicTypeCheckList,DynamicTypeChecks)
5734 DynamicTypeChecks = true
5744 'chr debug_event'(insert(Head#Susp)),
5746 'chr debug_event'(call(Susp)),
5749 'chr debug_event'(fail(Susp)), !,
5753 'chr debug_event'(exit(Susp))
5755 'chr debug_event'(redo(Susp)),
5759 ; get_allocation_occurrence(F/A,0) ->
5760 gen_insert_constraint_internal_goal(F/A,Goal,VarsSusp,Vars,Susp),
5761 delay_phase_end(validate_store_type_assumptions,chr_translate:update_suspension_field(F/A,Susp,state,inactive,Inactive)),
5762 Clause = ( Head :- Goal, Inactive, Delegate )
5764 Clause = ( Head :- Delegate )
5767 make_suspension_continuation_goal(F/A,VarsSusp,Goal) :-
5768 ( may_trigger(F/A) ->
5769 build_head(F,A,[0],VarsSusp,Delegate),
5770 ( chr_pp_flag(debugable,off) ->
5773 get_target_module(Mod),
5780 %===============================================================================
5781 :- chr_constraint has_active_occurrence/1, has_active_occurrence/2.
5782 :- chr_option(mode,has_active_occurrence(+)).
5783 :- chr_option(mode,has_active_occurrence(+,+)).
5784 %-------------------------------------------------------------------------------
5785 has_active_occurrence(C) <=> has_active_occurrence(C,1).
5787 max_occurrence(C,MO) \ has_active_occurrence(C,O) <=>
5789 passive(RuleNb,ID),occurrence(C,O,RuleNb,ID,_) \
5790 has_active_occurrence(C,O) <=>
5792 has_active_occurrence(C,NO).
5793 has_active_occurrence(C,O) <=> true.
5794 %===============================================================================
5796 gen_cond_attach_clause(F/A,Id,L,T) :-
5797 ( is_finally_stored(F/A) ->
5798 get_allocation_occurrence(F/A,AllocationOccurrence),
5799 get_max_occurrence(F/A,MaxOccurrence),
5800 ( chr_pp_flag(debugable,off), MaxOccurrence < AllocationOccurrence ->
5801 ( only_ground_indexed_arguments(F/A) ->
5802 gen_insert_constraint_internal_goal(F/A,Body,AllArgs,Args,Susp)
5804 gen_cond_attach_goal(F/A,Body,AllArgs,Args,Susp)
5806 ; vars_susp(A,Args,Susp,AllArgs),
5807 gen_uncond_attach_goal(F/A,Susp,Args,Body,_)
5809 build_head(F,A,Id,AllArgs,Head),
5810 Clause = ( Head :- Body ),
5811 add_dummy_location(Clause,LocatedClause),
5812 L = [LocatedClause | T]
5817 :- chr_constraint use_auxiliary_predicate/1.
5818 :- chr_option(mode,use_auxiliary_predicate(+)).
5820 :- chr_constraint use_auxiliary_predicate/2.
5821 :- chr_option(mode,use_auxiliary_predicate(+,+)).
5823 :- chr_constraint is_used_auxiliary_predicate/1.
5824 :- chr_option(mode,is_used_auxiliary_predicate(+)).
5826 :- chr_constraint is_used_auxiliary_predicate/2.
5827 :- chr_option(mode,is_used_auxiliary_predicate(+,+)).
5830 use_auxiliary_predicate(P) \ use_auxiliary_predicate(P) <=> true.
5832 use_auxiliary_predicate(P,C) \ use_auxiliary_predicate(P,C) <=> true.
5834 use_auxiliary_predicate(P) \ is_used_auxiliary_predicate(P) <=> true.
5836 use_auxiliary_predicate(P,_) \ is_used_auxiliary_predicate(P) <=> true.
5838 is_used_auxiliary_predicate(P) <=> fail.
5840 use_auxiliary_predicate(P) \ is_used_auxiliary_predicate(P,_) <=> true.
5841 use_auxiliary_predicate(P,C) \ is_used_auxiliary_predicate(P,C) <=> true.
5843 is_used_auxiliary_predicate(P,C) <=> fail.
5845 %------------------------------------------------------------------------------%
5846 % Only generate import statements for actually used modules.
5847 %------------------------------------------------------------------------------%
5849 :- chr_constraint use_auxiliary_module/1.
5850 :- chr_option(mode,use_auxiliary_module(+)).
5852 :- chr_constraint is_used_auxiliary_module/1.
5853 :- chr_option(mode,is_used_auxiliary_module(+)).
5856 use_auxiliary_module(P) \ use_auxiliary_module(P) <=> true.
5858 use_auxiliary_module(P) \ is_used_auxiliary_module(P) <=> true.
5860 is_used_auxiliary_module(P) <=> fail.
5862 % only called for constraints with
5864 % non-ground indexed argument
5865 gen_cond_attach_goal(F/A,Goal,AllArgs,Args,Susp) :-
5866 vars_susp(A,Args,Susp,AllArgs),
5867 make_suspension_continuation_goal(F/A,AllArgs,Closure),
5868 ( get_store_type(F/A,var_assoc_store(_,_)) ->
5871 attach_constraint_atom(F/A,Vars,Susp,Attach)
5874 insert_constraint_goal(F/A,Susp,Args,InsertCall),
5875 insert_constraint_internal_constraint_goal(F/A, Vars, Susp, Closure, Args,InsertGoal),
5876 ( may_trigger(F/A) ->
5877 activate_constraint_goal(F/A,(InsertCall,Attach),Vars,Susp,_,ActivateGoal),
5881 InsertGoal, % insert_constraint_internal(Stored,Vars,Susp,Closure,F,Args)
5885 ActivateGoal % activate_constraint(Stored,Vars,Susp,_)
5891 InsertGoal, % insert_constraint_internal(Stored,Vars,Susp,Closure,F,Args),
5897 gen_insert_constraint_internal_goal(F/A,Goal,AllArgs,Args,Susp) :-
5898 vars_susp(A,Args,Susp,AllArgs),
5899 make_suspension_continuation_goal(F/A,AllArgs,Cont),
5900 ( \+ only_ground_indexed_arguments(F/A), \+ get_store_type(F/A,var_assoc_store(_,_)) ->
5901 attach_constraint_atom(F/A,Vars,Susp,Attach)
5906 insert_constraint_goal(F/A,Susp,Args,InsertCall),
5907 insert_constraint_internal_constraint_goal(F/A, Vars, Susp, Cont, Args,InsertInternalGoal),
5908 ( only_ground_indexed_arguments(F/A), chr_pp_flag(debugable,off) ->
5911 InsertInternalGoal, % insert_constraint_internal(Susp,F,Args),
5917 InsertInternalGoal, % insert_constraint_internal(_,Vars,Susp,Cont,F,Args),
5923 gen_uncond_attach_goal(FA,Susp,Args,AttachGoal,Generation) :-
5924 ( \+ only_ground_indexed_arguments(FA), \+ get_store_type(FA,var_assoc_store(_,_)) ->
5925 attach_constraint_atom(FA,Vars,Susp,Attach)
5929 insert_constraint_goal(FA,Susp,Args,InsertCall),
5930 ( chr_pp_flag(late_allocation,on) ->
5931 activate_constraint_goal(FA,(InsertCall,Attach),Vars,Susp,Generation,AttachGoal)
5933 activate_constraint_goal(FA,true,Vars,Susp,Generation,AttachGoal)
5936 %-------------------------------------------------------------------------------
5937 :- chr_constraint occurrences_code/6.
5938 :- chr_option(mode,occurrences_code(+,+,+,+,+,+)).
5939 %-------------------------------------------------------------------------------
5940 max_occurrence(C,MO) \ occurrences_code(C,O,Id,NId,L,T)
5943 occurrences_code(C,O,Id,NId,L,T)
5945 occurrence_code(C,O,Id,Id1,L,L1),
5947 occurrences_code(C,NO,Id1,NId,L1,T).
5948 %-------------------------------------------------------------------------------
5949 :- chr_constraint occurrence_code/6.
5950 :- chr_option(mode,occurrence_code(+,+,+,+,+,+)).
5951 %-------------------------------------------------------------------------------
5952 occurrence(C,O,RuleNb,ID,_), passive(RuleNb,ID) \ occurrence_code(C,O,Id,NId,L,T)
5954 ( named_history(RuleNb,_,_) ->
5955 does_use_history(C,O)
5961 occurrence(C,O,RuleNb,ID,_), rule(RuleNb,PragmaRule) \ occurrence_code(C,O,Id,NId,L,T)
5963 PragmaRule = pragma(rule(Heads1,Heads2,_,_),ids(IDs1,IDs2),_,_,_),
5964 ( select2(ID,Head1,IDs1,Heads1,RIDs1,RHeads1) ->
5966 head1_code(Head1,ID,RHeads1,RIDs1,PragmaRule,C,O,Id,L,T)
5967 ; select2(ID,Head2,IDs2,Heads2,RIDs2,RHeads2) ->
5968 head2_code(Head2,ID,RHeads2,RIDs2,PragmaRule,C,O,Id,L,L1),
5970 ( unconditional_occurrence(C,O) ->
5973 gen_alloc_inc_clause(C,O,Id,L1,T)
5977 occurrence_code(C,O,_,_,_,_)
5979 chr_error(internal,'occurrence_code/6: missing information to compile ~w:~w\n',[C,O]).
5980 %-------------------------------------------------------------------------------
5982 %% Generate code based on one removed head of a CHR rule
5983 head1_code(Head,ID,OtherHeads,OtherIDs,PragmaRule,FA,O,Id,L,T) :-
5984 PragmaRule = pragma(Rule,_,_,_Name,RuleNb),
5985 Rule = rule(_,Head2,_,_),
5987 reorder_heads(RuleNb,Head,OtherHeads,OtherIDs,NOtherHeads,NOtherIDs),
5988 simplification_code(Head,ID,NOtherHeads,NOtherIDs,PragmaRule,FA,O,Id,L,T)
5990 simpagation_head1_code(Head,ID,OtherHeads,OtherIDs,PragmaRule,FA,O,Id,L,T)
5993 %% Generate code based on one persistent head of a CHR rule
5994 head2_code(Head,ID,OtherHeads,OtherIDs,PragmaRule,FA,O,Id,L,T) :-
5995 PragmaRule = pragma(Rule,_,_,_Name,RuleNb),
5996 Rule = rule(Head1,_,_,_),
5998 reorder_heads(RuleNb,Head,OtherHeads,OtherIDs,NOtherHeads,NOtherIDs),
5999 propagation_code(Head,ID,NOtherHeads,NOtherIDs,Rule,RuleNb,FA,O,Id,L,T)
6001 simpagation_head2_code(Head,ID,OtherHeads,OtherIDs,PragmaRule,FA,O,Id,L,T)
6004 gen_alloc_inc_clause(F/A,O,Id,L,T) :-
6005 vars_susp(A,Vars,Susp,VarsSusp),
6006 build_head(F,A,Id,VarsSusp,Head),
6008 build_head(F,A,IncId,VarsSusp,CallHead),
6009 gen_occ_allocation(F/A,O,Vars,Susp,ConditionalAlloc),
6016 add_dummy_location(Clause,LocatedClause),
6017 L = [LocatedClause|T].
6019 gen_occ_allocation(FA,O,Vars,Susp,Goal) :-
6020 get_allocation_occurrence(FA,AO),
6021 ( chr_pp_flag(debugable,off), O == AO ->
6022 allocate_constraint_goal(FA,Susp,Vars,Goal0),
6023 ( may_trigger(FA) ->
6024 Goal = (var(Susp) -> Goal0 ; true)
6032 gen_occ_allocation_in_guard(FA,O,Vars,Susp,Goal) :-
6033 get_allocation_occurrence(FA,AO),
6034 ( chr_pp_flag(debugable,off), O < AO ->
6035 allocate_constraint_goal(FA,Susp,Vars,Goal0),
6036 ( may_trigger(FA) ->
6037 Goal = (var(Susp) -> Goal0 ; true)
6045 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6047 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6049 % Reorders guard goals with respect to partner constraint retrieval goals and
6050 % active constraint. Returns combined partner retrieval + guard goal.
6052 guard_via_reschedule_new(Retrievals,GuardList,Prelude,GuardListSkeleton,LookupSkeleton,GoalSkeleton) :-
6053 ( chr_pp_flag(guard_via_reschedule,on) ->
6054 guard_via_reschedule_main_new(Retrievals,GuardList,Prelude,GuardListSkeleton,LookupSkeleton,ScheduleSkeleton),
6055 list2conj(ScheduleSkeleton,GoalSkeleton)
6057 length(Retrievals,RL), length(LookupSkeleton,RL),
6058 length(GuardList,GL), length(GuardListSkeleton,GL),
6059 append(LookupSkeleton,GuardListSkeleton,GoalListSkeleton),
6060 list2conj(GoalListSkeleton,GoalSkeleton)
6062 guard_via_reschedule_main_new(PartnerLookups,GuardList,ActiveHead,
6063 GuardListSkeleton,LookupSkeleton,ScheduleSkeleton) :-
6064 initialize_unit_dictionary(ActiveHead,Dict),
6065 maplist(wrap_in_functor(lookup),PartnerLookups,WrappedPartnerLookups),
6066 maplist(wrap_in_functor(guard),GuardList,WrappedGuardList),
6067 build_units(WrappedPartnerLookups,WrappedGuardList,Dict,Units),
6068 dependency_reorder(Units,NUnits),
6069 wrappedunits2lists(NUnits,IndexedGuardListSkeleton,LookupSkeleton,ScheduleSkeleton),
6070 sort(IndexedGuardListSkeleton,SortedIndexedGuardListSkeleton),
6071 snd_of_pairs(SortedIndexedGuardListSkeleton,GuardListSkeleton).
6073 wrap_in_functor(Functor,X,Term) :-
6074 Term =.. [Functor,X].
6076 wrappedunits2lists([],[],[],[]).
6077 wrappedunits2lists([unit(N,WrappedGoal,_,_)|Units],Gs,Ls,Ss) :-
6078 Ss = [GoalCopy|TSs],
6079 ( WrappedGoal = lookup(Goal) ->
6080 Ls = [GoalCopy|TLs],
6082 ; WrappedGoal = guard(Goal) ->
6083 Gs = [N-GoalCopy|TGs],
6086 wrappedunits2lists(Units,TGs,TLs,TSs).
6088 guard_splitting(Rule,SplitGuardList) :-
6089 Rule = rule(H1,H2,Guard,_),
6090 append(H1,H2,Heads),
6091 conj2list(Guard,GuardList),
6092 term_variables(Heads,HeadVars),
6093 split_off_simple_guard_new(GuardList,HeadVars,GuardPrefix,RestGuardList),
6094 append(GuardPrefix,[RestGuard],SplitGuardList),
6095 term_variables(RestGuardList,GuardVars1),
6096 % variables that are declared to be ground don't need to be locked
6097 ground_vars(Heads,GroundVars),
6098 list_difference_eq(HeadVars,GroundVars,LockableHeadVars),
6099 intersect_eq(LockableHeadVars,GuardVars1,GuardVars),
6100 ( chr_pp_flag(guard_locks,on),
6101 bagof(('chr lock'(X)) - ('chr unlock'(X)), (lists:member(X,GuardVars)), LocksUnlocks) ->
6102 once(pairup(Locks,Unlocks,LocksUnlocks))
6107 list2conj(Locks,LockPhase),
6108 list2conj(Unlocks,UnlockPhase),
6109 list2conj(RestGuardList,RestGuard1),
6110 RestGuard = (LockPhase,(RestGuard1,UnlockPhase)).
6112 guard_body_copies3(Rule,GuardList,VarDict,GuardCopyList,BodyCopy) :-
6113 Rule = rule(_,_,_,Body),
6114 my_term_copy(GuardList,VarDict,VarDict2,GuardCopyList),
6115 my_term_copy(Body,VarDict2,BodyCopy).
6118 split_off_simple_guard_new([],_,[],[]).
6119 split_off_simple_guard_new([G|Gs],VarDict,S,C) :-
6120 ( simple_guard_new(G,VarDict) ->
6122 split_off_simple_guard_new(Gs,VarDict,Ss,C)
6128 % simple guard: cheap and benign (does not bind variables)
6129 simple_guard_new(G,Vars) :-
6130 builtin_binds_b(G,BoundVars),
6131 \+ (( member(V,BoundVars),
6132 memberchk_eq(V,Vars)
6135 dependency_reorder(Units,NUnits) :-
6136 dependency_reorder(Units,[],NUnits).
6138 dependency_reorder([],Acc,Result) :-
6139 reverse(Acc,Result).
6141 dependency_reorder([Unit|Units],Acc,Result) :-
6142 Unit = unit(_GID,_Goal,Type,GIDs),
6146 dependency_insert(Acc,Unit,GIDs,NAcc)
6148 dependency_reorder(Units,NAcc,Result).
6150 dependency_insert([],Unit,_,[Unit]).
6151 dependency_insert([X|Xs],Unit,GIDs,L) :-
6152 X = unit(GID,_,_,_),
6153 ( memberchk(GID,GIDs) ->
6157 dependency_insert(Xs,Unit,GIDs,T)
6160 build_units(Retrievals,Guard,InitialDict,Units) :-
6161 build_retrieval_units(Retrievals,1,N,InitialDict,Dict,Units,Tail),
6162 build_guard_units(Guard,N,Dict,Tail).
6164 build_retrieval_units([],N,N,Dict,Dict,L,L).
6165 build_retrieval_units([U|Us],N,M,Dict,NDict,L,T) :-
6166 term_variables(U,Vs),
6167 update_unit_dictionary(Vs,N,Dict,Dict1,[],GIDs),
6168 L = [unit(N,U,fixed,GIDs)|L1],
6170 build_retrieval_units(Us,N1,M,Dict1,NDict,L1,T).
6172 initialize_unit_dictionary(Term,Dict) :-
6173 term_variables(Term,Vars),
6174 pair_all_with(Vars,0,Dict).
6176 update_unit_dictionary([],_,Dict,Dict,GIDs,GIDs).
6177 update_unit_dictionary([V|Vs],This,Dict,NDict,GIDs,NGIDs) :-
6178 ( lookup_eq(Dict,V,GID) ->
6179 ( (GID == This ; memberchk(GID,GIDs) ) ->
6186 Dict1 = [V - This|Dict],
6189 update_unit_dictionary(Vs,This,Dict1,NDict,GIDs1,NGIDs).
6191 build_guard_units(Guard,N,Dict,Units) :-
6193 Units = [unit(N,Goal,fixed,[])]
6194 ; Guard = [Goal|Goals] ->
6195 term_variables(Goal,Vs),
6196 update_unit_dictionary2(Vs,N,Dict,NDict,[],GIDs),
6197 Units = [unit(N,Goal,movable,GIDs)|RUnits],
6199 build_guard_units(Goals,N1,NDict,RUnits)
6202 update_unit_dictionary2([],_,Dict,Dict,GIDs,GIDs).
6203 update_unit_dictionary2([V|Vs],This,Dict,NDict,GIDs,NGIDs) :-
6204 ( lookup_eq(Dict,V,GID) ->
6205 ( (GID == This ; memberchk(GID,GIDs) ) ->
6210 Dict1 = [V - This|Dict]
6212 Dict1 = [V - This|Dict],
6215 update_unit_dictionary2(Vs,This,Dict1,NDict,GIDs1,NGIDs).
6217 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6219 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6221 %% / ___| ___| |_ / ___| ___ _ __ ___ __ _ _ __ | |_(_) ___ ___ _
6222 %% \___ \ / _ \ __| \___ \ / _ \ '_ ` _ \ / _` | '_ \| __| |/ __/ __(_)
6223 %% ___) | __/ |_ ___) | __/ | | | | | (_| | | | | |_| | (__\__ \_
6224 %% |____/ \___|\__| |____/ \___|_| |_| |_|\__,_|_| |_|\__|_|\___|___(_)
6227 %% | | | |_ __ (_) __ _ _ _ ___ |_ _|_ __ / _| ___ _ __ ___ _ __ ___ ___
6228 %% | | | | '_ \| |/ _` | | | |/ _ \ | || '_ \| |_ / _ \ '__/ _ \ '_ \ / __/ _ \
6229 %% | |_| | | | | | (_| | |_| | __/ | || | | | _| __/ | | __/ | | | (_| __/
6230 %% \___/|_| |_|_|\__, |\__,_|\___| |___|_| |_|_| \___|_| \___|_| |_|\___\___|
6233 functional_dependency/4,
6234 get_functional_dependency/4.
6236 :- chr_option(mode,functional_dependency(+,+,?,?)).
6237 :- chr_option(mode,get_functional_dependency(+,+,?,?)).
6239 allocation_occurrence(C,AO), occurrence(C,O,RuleNb,_,_) \ functional_dependency(C,RuleNb,Pattern,Key)
6243 functional_dependency(C,1,Pattern,Key).
6245 functional_dependency(C,RuleNb1,Pattern,Key) \ get_functional_dependency(C,RuleNb2,QPattern,QKey)
6249 QPattern = Pattern, QKey = Key.
6250 get_functional_dependency(_,_,_,_)
6254 functional_dependency_analysis(Rules) :-
6255 ( fail, chr_pp_flag(functional_dependency_analysis,on) ->
6256 functional_dependency_analysis_main(Rules)
6261 functional_dependency_analysis_main([]).
6262 functional_dependency_analysis_main([PRule|PRules]) :-
6263 ( discover_unique_pattern(PRule,C,RuleNb,Pattern,Key) ->
6264 functional_dependency(C,RuleNb,Pattern,Key)
6268 functional_dependency_analysis_main(PRules).
6270 discover_unique_pattern(PragmaRule,F/A,RuleNb,Pattern,Key) :-
6271 PragmaRule = pragma(Rule,_,_,Name,RuleNb),
6272 Rule = rule(H1,H2,Guard,_),
6280 check_unique_constraints(C1,C2,Guard,RuleNb,List),
6281 term_variables(C1,Vs),
6284 lookup_eq(List,V1,V2),
6287 select_pragma_unique_variables(Vs,List,Key1),
6288 copy_term_nat(C1-Key1,Pattern-Key),
6291 select_pragma_unique_variables([],_,[]).
6292 select_pragma_unique_variables([V|Vs],List,L) :-
6293 ( lookup_eq(List,V,_) ->
6298 select_pragma_unique_variables(Vs,List,T).
6300 % depends on functional dependency analysis
6301 % and shape of rule: C1 \ C2 <=> true.
6302 set_semantics_rules(Rules) :-
6303 ( fail, chr_pp_flag(set_semantics_rule,on) ->
6304 set_semantics_rules_main(Rules)
6309 set_semantics_rules_main([]).
6310 set_semantics_rules_main([R|Rs]) :-
6311 set_semantics_rule_main(R),
6312 set_semantics_rules_main(Rs).
6314 set_semantics_rule_main(PragmaRule) :-
6315 PragmaRule = pragma(Rule,IDs,Pragmas,_,RuleNb),
6316 ( Rule = rule([C1],[C2],true,_),
6317 IDs = ids([ID1],[ID2]),
6318 \+ is_passive(RuleNb,ID1),
6320 get_functional_dependency(F/A,RuleNb,Pattern,Key),
6321 copy_term_nat(Pattern-Key,C1-Key1),
6322 copy_term_nat(Pattern-Key,C2-Key2),
6329 check_unique_constraints(C1,C2,G,RuleNb,List) :-
6330 \+ any_passive_head(RuleNb),
6331 variable_replacement(C1-C2,C2-C1,List),
6332 copy_with_variable_replacement(G,OtherG,List),
6334 once(entails_b(NotG,OtherG)).
6336 % checks for rules of the shape ...,C1,C2... (<|=)=> ...
6337 % where C1 and C2 are symmteric constraints
6338 symmetry_analysis(Rules) :-
6339 ( chr_pp_flag(check_unnecessary_active,off) ->
6342 symmetry_analysis_main(Rules)
6345 symmetry_analysis_main([]).
6346 symmetry_analysis_main([R|Rs]) :-
6347 R = pragma(Rule,ids(IDs1,IDs2),_,_,RuleNb),
6348 Rule = rule(H1,H2,_,_),
6349 ( ( \+ chr_pp_flag(check_unnecessary_active,simplification) ; H2 == [] ), H1 \== [] ->
6350 symmetry_analysis_heads_simplification(H1,IDs1,[],[],Rule,RuleNb),
6351 symmetry_analysis_heads_propagation(H2,IDs2,[],[],Rule,RuleNb)
6355 symmetry_analysis_main(Rs).
6357 symmetry_analysis_heads_simplification([],[],_,_,_,_).
6358 symmetry_analysis_heads_simplification([H|Hs],[ID|IDs],PreHs,PreIDs,Rule,RuleNb) :-
6359 ( \+ is_passive(RuleNb,ID),
6360 member2(PreHs,PreIDs,PreH-PreID),
6361 \+ is_passive(RuleNb,PreID),
6362 variable_replacement(PreH,H,List),
6363 copy_with_variable_replacement(Rule,Rule2,List),
6364 identical_guarded_rules(Rule,Rule2) ->
6369 symmetry_analysis_heads_simplification(Hs,IDs,[H|PreHs],[ID|PreIDs],Rule,RuleNb).
6371 symmetry_analysis_heads_propagation([],[],_,_,_,_).
6372 symmetry_analysis_heads_propagation([H|Hs],[ID|IDs],PreHs,PreIDs,Rule,RuleNb) :-
6373 ( \+ is_passive(RuleNb,ID),
6374 member2(PreHs,PreIDs,PreH-PreID),
6375 \+ is_passive(RuleNb,PreID),
6376 variable_replacement(PreH,H,List),
6377 copy_with_variable_replacement(Rule,Rule2,List),
6378 identical_rules(Rule,Rule2) ->
6383 symmetry_analysis_heads_propagation(Hs,IDs,[H|PreHs],[ID|PreIDs],Rule,RuleNb).
6385 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6387 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6388 %% ____ _ _ _ __ _ _ _
6389 %% / ___|(_)_ __ ___ _ __ | (_)/ _(_) ___ __ _| |_(_) ___ _ __
6390 %% \___ \| | '_ ` _ \| '_ \| | | |_| |/ __/ _` | __| |/ _ \| '_ \
6391 %% ___) | | | | | | | |_) | | | _| | (_| (_| | |_| | (_) | | | |
6392 %% |____/|_|_| |_| |_| .__/|_|_|_| |_|\___\__,_|\__|_|\___/|_| |_|
6395 simplification_code(Head,ID,RestHeads,RestIDs,PragmaRule,F/A,O,Id,L,T) :-
6396 PragmaRule = pragma(Rule,_,Pragmas,_,RuleNb),
6397 head_info(Head,A,_Vars,Susp,HeadVars,HeadPairs),
6398 build_head(F,A,Id,HeadVars,ClauseHead),
6399 get_constraint_mode(F/A,Mode),
6400 head_arg_matches(HeadPairs,Mode,[],FirstMatching,VarDict1,[],GroundVars),
6403 guard_splitting(Rule,GuardList0),
6404 ( is_stored_in_guard(F/A, RuleNb) ->
6405 GuardList = [Hole1|GuardList0]
6407 GuardList = GuardList0
6409 guard_via_reschedule_new(RestHeads,GuardList,Head,GuardCopyList,GetRestHeads,RescheduledTest),
6411 rest_heads_retrieval_and_matching(RestHeads,RestIDs,Head,GetRestHeads,Susps,VarDict1,VarDict,[],[],[],GroundVars,_),
6413 guard_body_copies3(Rule,GuardList,VarDict,GuardCopyList,BodyCopy),
6415 ( is_stored_in_guard(F/A, RuleNb) ->
6416 gen_occ_allocation_in_guard(F/A,O,Vars,Susp,Allocation),
6417 gen_uncond_attach_goal(F/A,Susp,Vars,Attachment,_),
6418 GuardCopyList = [Hole1Copy|_],
6419 Hole1Copy = (Allocation, Attachment)
6425 partner_constraint_detachments(Susps,RestHeads,VarDict,SuspsDetachments),
6426 active_constraint_detachment(Id,Susp,Head,VarDict,SuspDetachment),
6428 ( chr_pp_flag(debugable,on) ->
6429 Rule = rule(_,_,Guard,Body),
6430 my_term_copy(Guard - Body, VarDict, DebugGuard - DebugBody),
6431 sort_by_key([Susp|Susps],[ID|RestIDs],SortedSusps),
6432 DebugTry = 'chr debug_event'( try(SortedSusps,[],DebugGuard,DebugBody)),
6433 DebugApply = 'chr debug_event'(apply(SortedSusps,[],DebugGuard,DebugBody)),
6434 instrument_goal(ActualCut,DebugTry,DebugApply,Cut)
6438 ( unconditional_occurrence(F/A,O), chr_pp_flag(late_allocation,on) -> ActualCut = true ; ActualCut = (!) ),
6439 Clause = ( ClauseHead :-
6447 add_location(Clause,RuleNb,LocatedClause),
6448 L = [LocatedClause | T].
6450 add_location(Clause,RuleNb,NClause) :-
6451 ( chr_pp_flag(line_numbers,on) ->
6452 get_chr_source_file(File),
6453 get_line_number(RuleNb,LineNb),
6454 NClause = '$source_location'(File,LineNb):Clause
6459 add_dummy_location(Clause,NClause) :-
6460 ( chr_pp_flag(line_numbers,on) ->
6461 get_chr_source_file(File),
6462 NClause = '$source_location'(File,1):Clause
6466 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6467 %% head_arg_matches(+Pairs,+Modes,+VarDict,-Goal,-NVarDict) is det.
6469 % Return goal matching newly introduced variables with variables in
6470 % previously looked-up heads.
6471 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6472 head_arg_matches(Pairs,Modes,VarDict,Goal,NVarDict) :-
6473 head_arg_matches(Pairs,Modes,VarDict,Goal,NVarDict,[],_).
6475 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6476 %% head_arg_matches(+Pairs,+Modes,+VarDict,-Goal,-NVarDict,+GroundVars,-NGroundVars) is det.
6477 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6478 head_arg_matches(Pairs,Modes,VarDict,Goal,NVarDict,GroundVars,NGroundVars) :-
6479 head_arg_matches_(Pairs,Modes,VarDict,GroundVars,GoalList,NVarDict,NGroundVars),
6480 list2conj(GoalList,Goal).
6482 head_arg_matches_([],[],VarDict,GroundVars,[],VarDict,GroundVars).
6483 head_arg_matches_([Arg-Var| Rest],[Mode|Modes],VarDict,GroundVars,GoalList,NVarDict,NGroundVars) :-
6485 ( lookup_eq(VarDict,Arg,OtherVar) ->
6487 ( memberchk_eq(Arg,GroundVars) ->
6488 GoalList = [Var = OtherVar | RestGoalList],
6489 GroundVars1 = GroundVars
6491 GoalList = [Var == OtherVar | RestGoalList],
6492 GroundVars1 = [Arg|GroundVars]
6495 GoalList = [Var == OtherVar | RestGoalList],
6496 GroundVars1 = GroundVars
6500 VarDict1 = [Arg-Var | VarDict],
6501 GoalList = RestGoalList,
6503 GroundVars1 = [Arg|GroundVars]
6505 GroundVars1 = GroundVars
6510 ; ground(Arg), Arg = '$chr_identifier_match'(ActualArg,IndexType) ->
6511 identifier_label_atom(IndexType,Var,ActualArg,Goal),
6512 GoalList = [Goal|RestGoalList],
6514 GroundVars1 = GroundVars,
6519 GoalList = [ Var = Arg | RestGoalList]
6521 GoalList = [ Var == Arg | RestGoalList]
6524 GroundVars1 = GroundVars,
6527 ; Mode == (+), is_ground(GroundVars,Arg) ->
6528 copy_with_variable_replacement(Arg,ArgCopy,VarDict),
6529 GoalList = [ Var = ArgCopy | RestGoalList],
6531 GroundVars1 = GroundVars,
6536 functor(Term,Fct,N),
6539 GoalList = [ Var = Term | RestGoalList ]
6541 GoalList = [ nonvar(Var), Var = Term | RestGoalList ]
6543 pairup(Args,Vars,NewPairs),
6544 append(NewPairs,Rest,Pairs),
6545 replicate(N,Mode,NewModes),
6546 append(NewModes,Modes,RestModes),
6548 GroundVars1 = GroundVars
6550 head_arg_matches_(Pairs,RestModes,VarDict1,GroundVars1,RestGoalList,NVarDict,NGroundVars).
6552 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6553 % add_heads_types(+ListOfHeads,+VarTypes,-NVarTypes) is det.
6554 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6555 add_heads_types([],VarTypes,VarTypes).
6556 add_heads_types([Head|Heads],VarTypes,NVarTypes) :-
6557 add_head_types(Head,VarTypes,VarTypes1),
6558 add_heads_types(Heads,VarTypes1,NVarTypes).
6560 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6561 % add_head_types(+Head,+VarTypes,-NVarTypes) is det.
6562 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6563 add_head_types(Head,VarTypes,NVarTypes) :-
6565 get_constraint_type_det(F/A,ArgTypes),
6567 add_args_types(Args,ArgTypes,VarTypes,NVarTypes).
6569 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6570 % add_args_types(+Terms,+Types,+VarTypes,-NVarTypes) is det.
6571 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6572 add_args_types([],[],VarTypes,VarTypes).
6573 add_args_types([Arg|Args],[Type|Types],VarTypes,NVarTypes) :-
6574 add_arg_types(Arg,Type,VarTypes,VarTypes1),
6575 add_args_types(Args,Types,VarTypes1,NVarTypes).
6577 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6578 % add_arg_types(+Term,+Type,+VarTypes,-NVarTypes) is det.
6579 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6580 add_arg_types(Term,Type,VarTypes,NVarTypes) :-
6582 ( lookup_eq(VarTypes,Term,_) ->
6583 NVarTypes = VarTypes
6585 NVarTypes = [Term-Type|VarTypes]
6588 NVarTypes = VarTypes
6589 ; % TODO improve approximation!
6590 term_variables(Term,Vars),
6592 replicate(VarNb,any,Types),
6593 add_args_types(Vars,Types,VarTypes,NVarTypes)
6598 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6599 %% add_heads_ground_variables(+ListOfHeads,+GroundVars,-NGroundVars) is det.
6601 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6602 add_heads_ground_variables([],GroundVars,GroundVars).
6603 add_heads_ground_variables([Head|Heads],GroundVars,NGroundVars) :-
6604 add_head_ground_variables(Head,GroundVars,GroundVars1),
6605 add_heads_ground_variables(Heads,GroundVars1,NGroundVars).
6607 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6608 %% add_head_ground_variables(+Head,+GroundVars,-GroundVars) is det.
6610 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6611 add_head_ground_variables(Head,GroundVars,NGroundVars) :-
6613 get_constraint_mode(F/A,ArgModes),
6615 add_arg_ground_variables(Args,ArgModes,GroundVars,NGroundVars).
6618 add_arg_ground_variables([],[],GroundVars,GroundVars).
6619 add_arg_ground_variables([Arg|Args],[Mode|Modes],GroundVars,NGroundVars) :-
6621 term_variables(Arg,Vars),
6622 add_var_ground_variables(Vars,GroundVars,GroundVars1)
6624 GroundVars = GroundVars1
6626 add_arg_ground_variables(Args,Modes,GroundVars1,NGroundVars).
6628 add_var_ground_variables([],GroundVars,GroundVars).
6629 add_var_ground_variables([Var|Vars],GroundVars,NGroundVars) :-
6630 ( memberchk_eq(Var,GroundVars) ->
6631 GroundVars1 = GroundVars
6633 GroundVars1 = [Var|GroundVars]
6635 add_var_ground_variables(Vars,GroundVars1,NGroundVars).
6636 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6637 %% is_ground(+GroundVars,+Term) is semidet.
6639 % Determine whether =Term= is always ground.
6640 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6641 is_ground(GroundVars,Term) :-
6646 maplist(is_ground(GroundVars),Args)
6648 memberchk_eq(Term,GroundVars)
6651 %% check_ground(+GroundVars,+Term,-Goal) is det.
6653 % Return runtime check to see whether =Term= is ground.
6654 check_ground(GroundVars,Term,Goal) :-
6655 term_variables(Term,Variables),
6656 check_ground_variables(Variables,GroundVars,Goal).
6658 check_ground_variables([],_,true).
6659 check_ground_variables([Var|Vars],GroundVars,Goal) :-
6660 ( memberchk_eq(Var,GroundVars) ->
6661 check_ground_variables(Vars,GroundVars,Goal)
6663 Goal = (ground(Var), RGoal),
6664 check_ground_variables(Vars,GroundVars,RGoal)
6667 rest_heads_retrieval_and_matching(Heads,IDs,ActiveHead,GoalList,Susps,VarDict,NVarDict,PrevHs,PrevSusps,AttrDict) :-
6668 rest_heads_retrieval_and_matching(Heads,IDs,ActiveHead,GoalList,Susps,VarDict,NVarDict,PrevHs,PrevSusps,AttrDict,[],_).
6670 rest_heads_retrieval_and_matching(Heads,IDs,ActiveHead,GoalList,Susps,VarDict,NVarDict,PrevHs,PrevSusps,AttrDict,GroundVars,NGroundVars) :-
6672 rest_heads_retrieval_and_matching_n(Heads,IDs,PrevHs,PrevSusps,ActiveHead,GoalList,Susps,VarDict,NVarDict,AttrDict,GroundVars,NGroundVars)
6677 GroundVars = NGroundVars
6680 rest_heads_retrieval_and_matching_n([],_,_,_,_,[],[],VarDict,VarDict,_AttrDict,GroundVars,GroundVars).
6681 rest_heads_retrieval_and_matching_n([H|Hs],[ID|IDs],PrevHs,PrevSusps,ActiveHead,
6682 [Goal|Goals],[Susp|Susps],VarDict,NVarDict,_AttrDict,GroundVars,NGroundVars) :-
6684 head_info(H,A,Vars,_,_,Pairs),
6685 get_store_type(F/A,StoreType),
6686 ( StoreType == default ->
6687 passive_head_via(H,[ActiveHead|PrevHs],VarDict,ViaGoal,VarSusps),
6688 delay_phase_end(validate_store_type_assumptions,
6689 ( static_suspension_term(F/A,Suspension),
6690 get_static_suspension_term_field(arguments,F/A,Suspension,Vars),
6691 get_static_suspension_field(F/A,Suspension,state,active,GetState)
6694 % create_get_mutable_ref(active,State,GetMutable),
6695 get_constraint_mode(F/A,Mode),
6696 head_arg_matches(Pairs,Mode,VarDict,MatchingGoal,VarDict1,GroundVars,GroundVars1),
6698 sbag_member_call(Susp,VarSusps,Sbag),
6699 ExistentialLookup = (
6702 Susp = Suspension, % not inlined
6706 delay_phase_end(validate_store_type_assumptions,
6707 ( static_suspension_term(F/A,Suspension),
6708 get_static_suspension_term_field(arguments,F/A,Suspension,Vars)
6711 existential_lookup(StoreType,H,[ActiveHead|PrevHs],VarDict,GroundVars,Suspension,ExistentialLookup,Susp,Pairs,NPairs),
6712 get_constraint_mode(F/A,Mode),
6713 filter_mode(NPairs,Pairs,Mode,NMode),
6714 head_arg_matches(NPairs,NMode,VarDict,MatchingGoal,VarDict1,GroundVars,GroundVars1)
6716 different_from_other_susps(H,Susp,PrevHs,PrevSusps,DiffSuspGoals),
6717 append(NPairs,VarDict1,DA_), % order important here
6718 translate(GroundVars1,DA_,GroundVarsA),
6719 translate(GroundVars1,VarDict1,GroundVarsB),
6720 inline_matching_goal(MatchingGoal,MatchingGoal2,GroundVarsA,GroundVarsB),
6727 rest_heads_retrieval_and_matching_n(Hs,IDs,[H|PrevHs],[Susp|PrevSusps],ActiveHead,Goals,Susps,VarDict1,NVarDict,_NewAttrDict,GroundVars1,NGroundVars).
6729 inline_matching_goal(A==B,true,GVA,GVB) :-
6730 memberchk_eq(A,GVA),
6731 memberchk_eq(B,GVB),
6734 % inline_matching_goal(A=B,true,_,_) :- A=B, !.
6735 inline_matching_goal((A,B),(A2,B2),GVA,GVB) :- !,
6736 inline_matching_goal(A,A2,GVA,GVB),
6737 inline_matching_goal(B,B2,GVA,GVB).
6738 inline_matching_goal(X,X,_,_).
6741 filter_mode([],_,_,[]).
6742 filter_mode([Arg-Var|Rest],[_-V|R],[M|Ms],Modes) :-
6745 filter_mode(Rest,R,Ms,MT)
6747 filter_mode([Arg-Var|Rest],R,Ms,Modes)
6750 check_unique_keys([],_).
6751 check_unique_keys([V|Vs],Dict) :-
6752 lookup_eq(Dict,V,_),
6753 check_unique_keys(Vs,Dict).
6755 % Generates tests to ensure the found constraint differs from previously found constraints
6756 % TODO: detect more cases where constraints need be different
6757 different_from_other_susps(Head,Susp,Heads,Susps,DiffSuspGoals) :-
6758 different_from_other_susps_(Heads,Susps,Head,Susp,DiffSuspGoalList),
6759 list2conj(DiffSuspGoalList,DiffSuspGoals).
6761 different_from_other_susps_(_,[],_,_,[]) :- !.
6762 different_from_other_susps_([PreHead|Heads],[PreSusp|Susps],Head,Susp,List) :-
6763 ( functor(Head,F,A), functor(PreHead,F,A),
6764 copy_term_nat(PreHead-Head,PreHeadCopy-HeadCopy),
6765 \+ \+ PreHeadCopy = HeadCopy ->
6767 List = [Susp \== PreSusp | Tail]
6771 different_from_other_susps_(Heads,Susps,Head,Susp,Tail).
6773 % passive_head_via(in,in,in,in,out,out,out) :-
6774 passive_head_via(Head,PrevHeads,VarDict,Goal,AllSusps) :-
6776 get_constraint_index(F/A,Pos),
6777 common_variables(Head,PrevHeads,CommonVars),
6778 global_list_store_name(F/A,Name),
6779 GlobalGoal = nb_getval(Name,AllSusps),
6780 get_constraint_mode(F/A,ArgModes),
6783 ; member(CommonVar,CommonVars), nth(I,ArgModes,(-)), arg(I,Head,Arg), Arg == CommonVar ->
6784 translate([CommonVar],VarDict,[Var]),
6785 gen_get_mod_constraints(F/A,Var,AttrGoal,AllSusps),
6788 translate(CommonVars,VarDict,Vars),
6789 add_heads_types(PrevHeads,[],TypeDict),
6790 my_term_copy(TypeDict,VarDict,TypeDictCopy),
6791 gen_get_mod_constraints(F/A,Vars,TypeDictCopy,ViaGoal,AttrGoal,AllSusps),
6800 common_variables(T,Ts,Vs) :-
6801 term_variables(T,V1),
6802 term_variables(Ts,V2),
6803 intersect_eq(V1,V2,Vs).
6805 gen_get_mod_constraints(FA,Vars,TypeDict,ViaGoal,AttrGoal,AllSusps) :-
6806 get_target_module(Mod),
6808 lookup_eq(TypeDict,A,Type),
6809 ( atomic_type(Type) ->
6813 ViaGoal = 'chr newvia_1'(A,V)
6816 ViaGoal = 'chr newvia_2'(A,B,V)
6818 ViaGoal = 'chr newvia'(Vars,V)
6821 ( get_attr(V,Mod,TSusps),
6822 TSuspsEqSusps % TSusps = Susps
6824 get_max_constraint_index(N),
6826 TSuspsEqSusps = true, % TSusps = Susps
6829 get_constraint_index(FA,Pos),
6830 get_suspensions(N,Pos,TSusps,TSuspsEqSusps,AllSusps)
6832 gen_get_mod_constraints(FA,Var,AttrGoal,AllSusps) :-
6833 get_target_module(Mod),
6835 ( get_attr(Var,Mod,TSusps),
6836 TSuspsEqSusps % TSusps = Susps
6838 get_max_constraint_index(N),
6840 TSuspsEqSusps = true, % TSusps = Susps
6843 get_constraint_index(FA,Pos),
6844 get_suspensions(N,Pos,TSusps,TSuspsEqSusps,AllSusps)
6847 guard_body_copies(Rule,VarDict,GuardCopy,BodyCopy) :-
6848 guard_body_copies2(Rule,VarDict,GuardCopyList,BodyCopy),
6849 list2conj(GuardCopyList,GuardCopy).
6851 guard_body_copies2(Rule,VarDict,GuardCopyList,BodyCopy) :-
6852 Rule = rule(H,_,Guard,Body),
6853 conj2list(Guard,GuardList),
6854 split_off_simple_guard(GuardList,VarDict,GuardPrefix,RestGuardList),
6855 my_term_copy(GuardPrefix-RestGuardList,VarDict,VarDict2,GuardPrefixCopy-RestGuardListCopyCore),
6857 append(GuardPrefixCopy,[RestGuardCopy],GuardCopyList),
6858 term_variables(RestGuardList,GuardVars),
6859 term_variables(RestGuardListCopyCore,GuardCopyVars),
6860 % variables that are declared to be ground don't need to be locked
6861 ground_vars(H,GroundVars),
6862 list_difference_eq(GuardVars,GroundVars,GuardVars_),
6863 ( chr_pp_flag(guard_locks,on),
6864 bagof(('chr lock'(Y)) - ('chr unlock'(Y)),
6865 X ^ (lists:member(X,GuardVars), % X is a variable appearing in the original guard
6866 pairlist:lookup_eq(VarDict,X,Y), % translate X into new variable
6867 memberchk_eq(Y,GuardCopyVars) % redundant check? or multiple entries for X possible?
6870 once(pairup(Locks,Unlocks,LocksUnlocks))
6875 list2conj(Locks,LockPhase),
6876 list2conj(Unlocks,UnlockPhase),
6877 list2conj(RestGuardListCopyCore,RestGuardCopyCore),
6878 RestGuardCopy = (LockPhase,(RestGuardCopyCore,UnlockPhase)),
6879 my_term_copy(Body,VarDict2,BodyCopy).
6882 split_off_simple_guard([],_,[],[]).
6883 split_off_simple_guard([G|Gs],VarDict,S,C) :-
6884 ( simple_guard(G,VarDict) ->
6886 split_off_simple_guard(Gs,VarDict,Ss,C)
6892 % simple guard: cheap and benign (does not bind variables)
6893 simple_guard(G,VarDict) :-
6895 \+ (( member(V,Vars),
6896 lookup_eq(VarDict,V,_)
6899 active_constraint_detachment(Id,Susp,Head,VarDict,SuspDetachment) :-
6905 Id == [0], chr_pp_flag(store_in_guards, off)
6907 ( get_allocation_occurrence(C,AO),
6908 get_max_occurrence(C,MO),
6911 only_ground_indexed_arguments(C), chr_pp_flag(late_allocation,on) ->
6912 SuspDetachment = true
6914 gen_uncond_susp_detachment(Head,Susp,active,VarDict,UnCondSuspDetachment),
6915 ( chr_pp_flag(late_allocation,on) ->
6920 UnCondSuspDetachment
6923 SuspDetachment = UnCondSuspDetachment
6927 SuspDetachment = true
6930 partner_constraint_detachments([],[],_,true).
6931 partner_constraint_detachments([Susp|Susps],[Head|Heads],VarDict,(SuspDetachment,SuspsDetachments)) :-
6932 gen_uncond_susp_detachment(Head,Susp,partner,VarDict,SuspDetachment),
6933 partner_constraint_detachments(Susps,Heads,VarDict,SuspsDetachments).
6935 gen_uncond_susp_detachment(Head,Susp,Role,VarDict,SuspDetachment) :-
6939 SuspDetachment = ( DebugEvent, RemoveInternalGoal),
6940 ( chr_pp_flag(debugable,on) ->
6941 DebugEvent = 'chr debug_event'(remove(Susp))
6945 remove_constraint_goal(C,Susp,Vars,true,(DeleteCall,Detach),Role,RemoveInternalGoal),
6946 delete_constraint_goal(Head,Susp,VarDict,DeleteCall),
6947 ( \+ only_ground_indexed_arguments(C), \+ get_store_type(C,var_assoc_store(_,_)) ->
6948 detach_constraint_atom(C,Vars,Susp,Detach)
6953 SuspDetachment = true
6956 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6958 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6960 %% / ___|(_)_ __ ___ _ __ __ _ __ _ __ _| |_(_) ___ _ __ / |
6961 %% \___ \| | '_ ` _ \| '_ \ / _` |/ _` |/ _` | __| |/ _ \| '_ \ | |
6962 %% ___) | | | | | | | |_) | (_| | (_| | (_| | |_| | (_) | | | | | |
6963 %% |____/|_|_| |_| |_| .__/ \__,_|\__, |\__,_|\__|_|\___/|_| |_| |_|
6966 simpagation_head1_code(Head,ID,RestHeads,OtherIDs,PragmaRule,F/A,O,Id,L,T) :-
6967 PragmaRule = pragma(Rule,ids(_,Heads2IDs),Pragmas,_Name,RuleNb),
6968 Rule = rule(_Heads,Heads2,Guard,Body),
6970 head_info(Head,A,Vars,Susp,HeadVars,HeadPairs),
6971 get_constraint_mode(F/A,Mode),
6972 head_arg_matches(HeadPairs,Mode,[],FirstMatching,VarDict1,[],GroundVars),
6974 build_head(F,A,Id,HeadVars,ClauseHead),
6976 append(RestHeads,Heads2,Heads),
6977 append(OtherIDs,Heads2IDs,IDs),
6978 reorder_heads(RuleNb,Head,Heads,IDs,NHeads,NIDs),
6980 guard_splitting(Rule,GuardList0),
6981 ( is_stored_in_guard(F/A, RuleNb) ->
6982 GuardList = [Hole1|GuardList0]
6984 GuardList = GuardList0
6986 guard_via_reschedule_new(NHeads,GuardList,Head,GuardCopyList,GetRestHeads,RescheduledTest),
6988 rest_heads_retrieval_and_matching(NHeads,NIDs,Head,GetRestHeads,Susps,VarDict1,VarDict,[],[],[],GroundVars,_),
6989 split_by_ids(NIDs,Susps,OtherIDs,Susps1,Susps1IDs,Susps2,Susps2IDs),
6991 guard_body_copies3(Rule,GuardList,VarDict,GuardCopyList,BodyCopy),
6993 ( is_stored_in_guard(F/A, RuleNb) ->
6994 gen_uncond_attach_goal(F/A,Susp,Vars,Attachment,_),
6995 GuardCopyList = [Hole1Copy|_],
6996 Hole1Copy = Attachment
7001 sort_by_key(Susps1,Susps1IDs,SortedSusps1),
7002 partner_constraint_detachments(SortedSusps1,RestHeads,VarDict,SuspsDetachments),
7003 active_constraint_detachment(Id,Susp,Head,VarDict,SuspDetachment),
7005 ( chr_pp_flag(debugable,on) ->
7006 my_term_copy(Guard - Body, VarDict, DebugGuard - DebugBody),
7007 sort_by_key([Susp|Susps1],[ID|Susps1IDs],RemovedSusps),
7008 sort_by_key(Susps2,Susps2IDs,KeptSusps),
7009 DebugTry = 'chr debug_event'( try(RemovedSusps,KeptSusps,DebugGuard,DebugBody)),
7010 DebugApply = 'chr debug_event'(apply(RemovedSusps,KeptSusps,DebugGuard,DebugBody)),
7011 instrument_goal((!),DebugTry,DebugApply,Cut)
7016 Clause = ( ClauseHead :-
7024 add_location(Clause,RuleNb,LocatedClause),
7025 L = [LocatedClause | T].
7027 split_by_ids([],[],_,[],[]).
7028 split_by_ids([I|Is],[S|Ss],I1s,S1s,S2s) :-
7029 ( memberchk_eq(I,I1s) ->
7036 split_by_ids(Is,Ss,I1s,R1s,R2s).
7038 split_by_ids([],[],_,[],[],[],[]).
7039 split_by_ids([I|Is],[S|Ss],I1s,S1s,SI1s,S2s,SI2s) :-
7040 ( memberchk_eq(I,I1s) ->
7051 split_by_ids(Is,Ss,I1s,R1s,RSI1s,R2s,RSI2s).
7052 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7055 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7057 %% / ___|(_)_ __ ___ _ __ __ _ __ _ __ _| |_(_) ___ _ __ |___ \
7058 %% \___ \| | '_ ` _ \| '_ \ / _` |/ _` |/ _` | __| |/ _ \| '_ \ __) |
7059 %% ___) | | | | | | | |_) | (_| | (_| | (_| | |_| | (_) | | | | / __/
7060 %% |____/|_|_| |_| |_| .__/ \__,_|\__, |\__,_|\__|_|\___/|_| |_| |_____|
7063 %% Genereate prelude + worker predicate
7064 %% prelude calls worker
7065 %% worker iterates over one type of removed constraints
7066 simpagation_head2_code(Head2,ID,RestHeads2,RestIDs,PragmaRule,FA,O,Id,L,T) :-
7067 PragmaRule = pragma(Rule,ids(IDs1,IDs2),Pragmas,_Name,RuleNb),
7068 Rule = rule(Heads1,_,Guard,Body),
7069 append(Heads1,RestHeads2,Heads),
7070 append(IDs1,RestIDs,IDs),
7071 reorder_heads(RuleNb,Head2,Heads,IDs,[NHead|NHeads],[NID|NIDs]),
7072 simpagation_head2_prelude(Head2,NHead,[NHeads,Guard,Body],FA,O,Id,L,L1),
7074 ( memberchk_eq(NID,IDs2) ->
7075 simpagation_universal_searches(NHeads,NIDs,IDs2,[NHead,Head2],Rule,FA,NextHeads,PreHeads,NextIDs,Id1,Id2,L1,L2)
7077 L1 = L2, Id1 = Id2,NextHeads = NHeads, PreHeads = [NHead,Head2], NextIDs = NIDs
7079 universal_search_iterator_end(PreHeads,NextHeads,Rule,FA,Id2,L2,L3),
7080 simpagation_head2_worker(PreHeads,NextHeads,NextIDs,ID,PragmaRule,FA,O,Id2,L3,T).
7082 simpagation_universal_searches([],[],_,PreHeads,_,_,[],PreHeads,[],Id,Id,L,L).
7083 simpagation_universal_searches(Heads,[ID|IDs],IDs2,PreHeads,Rule,C,OutHeads,OutPreHeads,OutIDs,Id,NId,L,T) :-
7084 Heads = [Head|RHeads],
7086 universal_search_iterator_end(PreHeads,Heads,Rule,C,Id,L,L0),
7087 universal_search_iterator(Heads,PreHeads,Rule,C,Id,L0,L1),
7088 ( memberchk_eq(ID,IDs2) ->
7089 simpagation_universal_searches(RHeads,IDs,IDs2,[Head|PreHeads],Rule,C,OutHeads,OutPreHeads,OutIDs,Id1,NId,L1,T)
7091 NId = Id1, L1 = T, OutHeads = RHeads, OutPreHeads = [Head|PreHeads], IDs = OutIDs
7094 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7095 simpagation_head2_prelude(Head,Head1,Rest,F/A,O,Id1,L,T) :-
7096 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs),
7097 build_head(F,A,Id1,VarsSusp,ClauseHead),
7098 get_constraint_mode(F/A,Mode),
7099 head_arg_matches(HeadPairs,Mode,[],FirstMatching,VarDict,[],GroundVars),
7101 lookup_passive_head(Head1,[Head],VarDict,GroundVars,ModConstraintsGoal,AllSusps),
7103 gen_occ_allocation(F/A,O,Vars,Susp,ConstraintAllocationGoal),
7105 extend_id(Id1,DelegateId),
7106 extra_active_delegate_variables(Head,[Head1|Rest],VarDict,ExtraVars),
7107 append([AllSusps|VarsSusp],ExtraVars,DelegateCallVars),
7108 build_head(F,A,DelegateId,DelegateCallVars,Delegate),
7115 ConstraintAllocationGoal,
7118 add_dummy_location(PreludeClause,LocatedPreludeClause),
7119 L = [LocatedPreludeClause|T].
7121 extra_active_delegate_variables(Term,Terms,VarDict,Vars) :-
7123 delegate_variables(Term,Terms,VarDict,Args,Vars).
7125 passive_delegate_variables(Term,PrevTerms,NextTerms,VarDict,Vars) :-
7126 term_variables(PrevTerms,PrevVars),
7127 delegate_variables(Term,NextTerms,VarDict,PrevVars,Vars).
7129 delegate_variables(Term,Terms,VarDict,PrevVars,Vars) :-
7130 term_variables(Term,V1),
7131 term_variables(Terms,V2),
7132 intersect_eq(V1,V2,V3),
7133 list_difference_eq(V3,PrevVars,V4),
7134 translate(V4,VarDict,Vars).
7137 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7138 simpagation_head2_worker([CurrentHead|PreHeads],NextHeads,NextIDs,ID,PragmaRule,F/A,O,Id,L,T) :-
7139 PragmaRule = pragma(Rule,ids(IDs1,_),Pragmas,_,RuleNb),
7140 Rule = rule(_,_,Guard,Body),
7141 get_prop_inner_loop_vars(PreHeads,[CurrentHead,NextHeads,Guard,Body],PreVarsAndSusps,VarDict,Susp,Vars,PreSusps),
7144 gen_var(OtherSusps),
7146 functor(CurrentHead,OtherF,OtherA),
7147 gen_vars(OtherA,OtherVars),
7148 head_info(CurrentHead,OtherA,OtherVars,OtherSusp,_VarsSusp,HeadPairs),
7149 get_constraint_mode(OtherF/OtherA,Mode),
7150 head_arg_matches(HeadPairs,Mode,VarDict,FirstMatching,VarDict1,[],GroundVars),
7152 delay_phase_end(validate_store_type_assumptions,
7153 ( static_suspension_term(OtherF/OtherA,OtherSuspension),
7154 get_static_suspension_field(OtherF/OtherA,OtherSuspension,state,active,GetState),
7155 get_static_suspension_term_field(arguments,OtherF/OtherA,OtherSuspension,OtherVars)
7158 % create_get_mutable_ref(active,State,GetMutable),
7159 different_from_other_susps(CurrentHead,OtherSusp,PreHeads,PreSusps,DiffSuspGoals),
7161 OtherSusp = OtherSuspension,
7167 ClauseVars = [[OtherSusp|OtherSusps]|PreVarsAndSusps],
7168 build_head(F,A,Id,ClauseVars,ClauseHead),
7170 guard_splitting(Rule,GuardList0),
7171 ( is_stored_in_guard(F/A, RuleNb) ->
7172 GuardList = [Hole1|GuardList0]
7174 GuardList = GuardList0
7176 guard_via_reschedule_new(NextHeads,GuardList,[CurrentHead|PreHeads],GuardCopyList,RestSuspsRetrieval,RescheduledTest),
7178 rest_heads_retrieval_and_matching(NextHeads,NextIDs,[CurrentHead|PreHeads],RestSuspsRetrieval,Susps,VarDict1,VarDict2,[CurrentHead|PreHeads],[OtherSusp|PreSusps],[]),
7179 split_by_ids(NextIDs,Susps,IDs1,Susps1,Susps2),
7180 split_by_ids(NextIDs,NextHeads,IDs1,RestHeads1,_),
7182 partner_constraint_detachments([OtherSusp | Susps1],[CurrentHead|RestHeads1],VarDict2,Susps1Detachments),
7184 RecursiveVars = [OtherSusps|PreVarsAndSusps],
7185 build_head(F,A,Id,RecursiveVars,RecursiveCall),
7186 RecursiveVars2 = [[]|PreVarsAndSusps],
7187 build_head(F,A,Id,RecursiveVars2,RecursiveCall2),
7189 guard_body_copies3(Rule,GuardList,VarDict2,GuardCopyList,BodyCopy),
7190 ( is_stored_in_guard(F/A, RuleNb) ->
7191 GuardCopyList = [GuardAttachment|_] % once( ) ??
7196 ( is_observed(F/A,O) ->
7197 gen_uncond_attach_goal(F/A,Susp,Vars,Attachment,Generation),
7198 gen_state_cond_call(Susp,F/A,RecursiveCall,Generation,ConditionalRecursiveCall),
7199 gen_state_cond_call(Susp,F/A,RecursiveCall2,Generation,ConditionalRecursiveCall2)
7202 ConditionalRecursiveCall = RecursiveCall,
7203 ConditionalRecursiveCall2 = RecursiveCall2
7206 ( chr_pp_flag(debugable,on) ->
7207 my_term_copy(Guard - Body, VarDict, DebugGuard - DebugBody),
7208 DebugTry = 'chr debug_event'( try([OtherSusp|Susps1],[Susp|Susps2],DebugGuard,DebugBody)),
7209 DebugApply = 'chr debug_event'(apply([OtherSusp|Susps1],[Susp|Susps2],DebugGuard,DebugBody))
7215 ( is_stored_in_guard(F/A, RuleNb) ->
7216 GuardAttachment = Attachment,
7217 BodyAttachment = true
7219 GuardAttachment = true,
7220 BodyAttachment = Attachment % will be true if not observed at all
7223 ( member(unique(ID1,UniqueKeys), Pragmas),
7224 check_unique_keys(UniqueKeys,VarDict) ->
7227 ( CurrentSuspTest ->
7234 ConditionalRecursiveCall2
7252 ConditionalRecursiveCall
7258 add_location(Clause,RuleNb,LocatedClause),
7259 L = [LocatedClause | T].
7261 gen_state_cond_call(Susp,FA,Call,Generation,ConditionalCall) :-
7262 ( may_trigger(FA) ->
7263 does_use_field(FA,generation),
7264 delay_phase_end(validate_store_type_assumptions,
7265 ( static_suspension_term(FA,Suspension),
7266 get_update_static_suspension_field(FA,Susp,Suspension,state,active,inactive,GetState,UpdateState),
7267 get_static_suspension_field(FA,Suspension,generation,Generation,GetGeneration),
7268 get_static_suspension_term_field(arguments,FA,Suspension,Args)
7272 delay_phase_end(validate_store_type_assumptions,
7273 ( static_suspension_term(FA,Suspension),
7274 get_update_static_suspension_field(FA,Susp,Suspension,state,active,inactive,GetState,UpdateState),
7275 get_static_suspension_term_field(arguments,FA,Suspension,Args)
7278 GetGeneration = true
7281 ( Susp = Suspension,
7290 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7293 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7295 %% | _ \ _ __ ___ _ __ __ _ __ _ __ _| |_(_) ___ _ __
7296 %% | |_) | '__/ _ \| '_ \ / _` |/ _` |/ _` | __| |/ _ \| '_ \
7297 %% | __/| | | (_) | |_) | (_| | (_| | (_| | |_| | (_) | | | |
7298 %% |_| |_| \___/| .__/ \__,_|\__, |\__,_|\__|_|\___/|_| |_|
7301 propagation_code(Head,ID,RestHeads,RestIDs,Rule,RuleNb,FA,O,Id,L,T) :-
7302 ( RestHeads == [] ->
7303 propagation_single_headed(Head,ID,Rule,RuleNb,FA,O,Id,L,T)
7305 propagation_multi_headed(Head,RestHeads,RestIDs,Rule,RuleNb,FA,O,Id,L,T)
7307 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7308 %% Single headed propagation
7309 %% everything in a single clause
7310 propagation_single_headed(Head,ID,Rule,RuleNb,F/A,O,Id,ProgramList,ProgramTail) :-
7311 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs),
7312 build_head(F,A,Id,VarsSusp,ClauseHead),
7315 build_head(F,A,NextId,VarsSusp,NextHead),
7317 get_constraint_mode(F/A,Mode),
7318 head_arg_matches(HeadPairs,Mode,[],HeadMatching,VarDict,[],GroundVars),
7319 guard_body_copies(Rule,VarDict,GuardCopy,BodyCopy),
7321 % - recursive call -
7322 RecursiveCall = NextHead,
7324 ( unconditional_occurrence(F/A,O), chr_pp_flag(late_allocation,on) ->
7330 Rule = rule(_,_,Guard,Body),
7331 ( chr_pp_flag(debugable,on) ->
7332 my_term_copy(Guard - Body, VarDict, DebugGuard - DebugBody),
7333 DebugTry = 'chr debug_event'( try([],[Susp],DebugGuard,DebugBody)),
7334 DebugApply = 'chr debug_event'(apply([],[Susp],DebugGuard,DebugBody)),
7335 instrument_goal(ActualCut,DebugTry,DebugApply,Cut)
7339 ( may_trigger(F/A), \+ has_no_history(RuleNb)->
7340 use_auxiliary_predicate(novel_production),
7341 use_auxiliary_predicate(extend_history),
7342 does_use_history(F/A,O),
7343 gen_occ_allocation(F/A,O,Vars,Susp,Allocation),
7345 ( named_history(RuleNb,HistoryName,HistoryIDs) ->
7346 ( HistoryIDs == [] ->
7347 empty_named_history_novel_production(HistoryName,NovelProduction),
7348 empty_named_history_extend_history(HistoryName,ExtendHistory)
7356 ( var(NovelProduction) ->
7357 NovelProduction = '$novel_production'(Susp,Tuple),
7358 ExtendHistory = '$extend_history'(Susp,Tuple)
7363 ( is_observed(F/A,O) ->
7364 gen_uncond_attach_goal(F/A,Susp,Vars,Attachment,Generation),
7365 gen_state_cond_call(Susp,F/A,RecursiveCall,Generation,ConditionalRecursiveCall)
7368 ConditionalRecursiveCall = RecursiveCall
7372 NovelProduction = true,
7373 ExtendHistory = true,
7375 ( is_observed(F/A,O) ->
7376 get_allocation_occurrence(F/A,AllocO),
7378 gen_insert_constraint_internal_goal(F/A,Attachment,VarsSusp,Vars,Susp),
7380 ; % more room for improvement?
7381 Attachment = (Attachment1, Attachment2),
7382 gen_occ_allocation(F/A,O,Vars,Susp,Attachment1),
7383 gen_uncond_attach_goal(F/A,Susp,Vars,Attachment2,Generation)
7385 gen_state_cond_call(Susp,F/A,RecursiveCall,Generation,ConditionalRecursiveCall)
7387 gen_occ_allocation(F/A,O,Vars,Susp,Attachment),
7388 ConditionalRecursiveCall = RecursiveCall
7392 ( is_stored_in_guard(F/A, RuleNb) ->
7393 GuardAttachment = Attachment,
7394 BodyAttachment = true
7396 GuardAttachment = true,
7397 BodyAttachment = Attachment % will be true if not observed at all
7411 ConditionalRecursiveCall
7413 add_location(Clause,RuleNb,LocatedClause),
7414 ProgramList = [LocatedClause | ProgramTail].
7416 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7417 %% multi headed propagation
7418 %% prelude + predicates to accumulate the necessary combinations of suspended
7419 %% constraints + predicate to execute the body
7420 propagation_multi_headed(Head,RestHeads,RestIDs,Rule,RuleNb,FA,O,Id,L,T) :-
7421 RestHeads = [First|Rest],
7422 propagation_prelude(Head,RestHeads,Rule,FA,O,Id,L,L1),
7423 extend_id(Id,ExtendedId),
7424 propagation_nested_code(Rest,[First,Head],RestIDs,Rule,RuleNb,FA,O,ExtendedId,L1,T).
7426 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7427 propagation_prelude(Head,[First|Rest],Rule,F/A,O,Id,L,T) :-
7428 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs),
7429 build_head(F,A,Id,VarsSusp,PreludeHead),
7430 get_constraint_mode(F/A,Mode),
7431 head_arg_matches(HeadPairs,Mode,[],FirstMatching,VarDict,[],GroundVars),
7432 Rule = rule(_,_,Guard,Body),
7433 extra_active_delegate_variables(Head,[First,Rest,Guard,Body],VarDict,ExtraVars),
7435 lookup_passive_head(First,[Head],VarDict,GroundVars,FirstSuspGoal,Susps),
7437 gen_occ_allocation(F/A,O,Vars,Susp,CondAllocation),
7439 extend_id(Id,NestedId),
7440 append([Susps|VarsSusp],ExtraVars,NestedVars),
7441 build_head(F,A,NestedId,NestedVars,NestedHead),
7442 NestedCall = NestedHead,
7452 add_dummy_location(Prelude,LocatedPrelude),
7453 L = [LocatedPrelude|T].
7455 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7456 propagation_nested_code([],[CurrentHead|PreHeads],RestIDs,Rule,RuleNb,FA,O,Id,L,T) :-
7457 universal_search_iterator_end([CurrentHead|PreHeads],[],Rule,FA,Id,L,L1),
7458 propagation_body(CurrentHead,PreHeads,RestIDs,Rule,RuleNb,FA,O,Id,L1,T).
7460 propagation_nested_code([Head|RestHeads],PreHeads,RestIDs,Rule,RuleNb,FA,O,Id,L,T) :-
7461 universal_search_iterator_end(PreHeads,[Head|RestHeads],Rule,FA,Id,L,L1),
7462 universal_search_iterator([Head|RestHeads],PreHeads,Rule,FA,Id,L1,L2),
7464 propagation_nested_code(RestHeads,[Head|PreHeads],RestIDs,Rule,RuleNb,FA,O,IncId,L2,T).
7466 %check_fd_lookup_condition(_,_,_,_) :- fail.
7467 check_fd_lookup_condition(F,A,_,_) :-
7468 get_store_type(F/A,global_singleton), !.
7469 check_fd_lookup_condition(F,A,CurrentHead,PreHeads) :-
7470 \+ may_trigger(F/A),
7471 get_functional_dependency(F/A,1,P,K),
7472 copy_term(P-K,CurrentHead-Key),
7473 term_variables(PreHeads,PreVars),
7474 intersect_eq(Key,PreVars,Key),!.
7476 propagation_body(CurrentHead,PreHeads,RestIDs,Rule,RuleNb,F/A,O,Id,L,T) :-
7477 Rule = rule(_,H2,Guard,Body),
7478 gen_var_susp_list_for_b(PreHeads,[CurrentHead,Guard,Body],VarDict1,PreVarsAndSuspsList,FirstVarsSusp,AllSusps,PrevIterators),
7479 flatten(PreVarsAndSuspsList,PreVarsAndSusps),
7480 init(AllSusps,RestSusps),
7481 last(AllSusps,Susp),
7483 gen_var(OtherSusps),
7484 functor(CurrentHead,OtherF,OtherA),
7485 gen_vars(OtherA,OtherVars),
7486 delay_phase_end(validate_store_type_assumptions,
7487 ( static_suspension_term(OtherF/OtherA,Suspension),
7488 get_static_suspension_field(OtherF/OtherA,Suspension,state,active,GetState),
7489 get_static_suspension_term_field(arguments,OtherF/OtherA,Suspension,OtherVars)
7492 % create_get_mutable_ref(active,State,GetMutable),
7494 OtherSusp = Suspension,
7497 ClauseVars = [[OtherSusp|OtherSusps]|PreVarsAndSusps],
7498 build_head(F,A,Id,ClauseVars,ClauseHead),
7499 ( check_fd_lookup_condition(OtherF,OtherA,CurrentHead,PreHeads) -> % iterator (OtherSusps) is empty at runtime
7500 universal_search_iterator_failure_vars(PreHeads,Id,PreVarsAndSuspsList,FirstVarsSusp,PrevIterators,PreVarsAndSusps1,PrevId),
7501 RecursiveVars = PreVarsAndSusps1
7503 RecursiveVars = [OtherSusps|PreVarsAndSusps],
7506 build_head(F,A,PrevId,RecursiveVars,RecursiveHead),
7507 RecursiveCall = RecursiveHead,
7508 CurrentHead =.. [_|OtherArgs],
7509 pairup(OtherArgs,OtherVars,OtherPairs),
7510 get_constraint_mode(OtherF/OtherA,Mode),
7511 head_arg_matches(OtherPairs,Mode,VarDict1,Matching,VarDict),
7513 different_from_other_susps(CurrentHead,OtherSusp,PreHeads,RestSusps,DiffSuspGoals),
7514 guard_body_copies(Rule,VarDict,GuardCopy,BodyCopy),
7515 get_occurrence(F/A,O,_,ID),
7517 ( is_observed(F/A,O) ->
7518 init(FirstVarsSusp,FirstVars),
7519 gen_uncond_attach_goal(F/A,Susp,FirstVars,Attachment,Generation),
7520 gen_state_cond_call(Susp,F/A,RecursiveCall,Generation,ConditionalRecursiveCall)
7523 ConditionalRecursiveCall = RecursiveCall
7525 ( (is_least_occurrence(RuleNb) ; has_no_history(RuleNb)) ->
7526 NovelProduction = true,
7527 ExtendHistory = true
7528 ; \+ may_trigger(F/A), forall(member(SomeID,RestIDs),(chr_translate:is_passive(RuleNb,SomeID))) ->
7529 NovelProduction = true,
7530 ExtendHistory = true
7532 get_occurrence(F/A,O,_,ID),
7533 use_auxiliary_predicate(novel_production),
7534 use_auxiliary_predicate(extend_history),
7535 does_use_history(F/A,O),
7536 ( named_history(RuleNb,HistoryName,HistoryIDs) ->
7537 ( HistoryIDs == [] ->
7538 empty_named_history_novel_production(HistoryName,NovelProduction),
7539 empty_named_history_extend_history(HistoryName,ExtendHistory)
7541 reverse([OtherSusp|RestSusps],NamedSusps),
7542 named_history_susps(HistoryIDs,[ID|RestIDs],[Susp|NamedSusps],HistorySusps),
7543 HistorySusps = [HistorySusp|_],
7545 ( length(HistoryIDs, 1) ->
7546 ExtendHistory = '$extend_history'(HistorySusp,HistoryName),
7547 NovelProduction = '$novel_production'(HistorySusp,HistoryName)
7549 findall(ConstraintSymbol,(member(SomeID,HistoryIDs),get_occurrence_from_id(ConstraintSymbol,_,RuleNb,SomeID)),ConstraintSymbols),
7550 Tuple =.. [t,HistoryName|HistorySusps]
7555 findall(Functor/Arity,(member(H,H2),functor(H,Functor,Arity)),ConstraintSymbols),
7556 sort([ID|RestIDs],HistoryIDs),
7557 history_susps(RestIDs,[OtherSusp|RestSusps],Susp,ID,HistorySusps),
7558 Tuple =.. [t,RuleNb|HistorySusps]
7561 ( var(NovelProduction) ->
7562 novel_production_calls(ConstraintSymbols,HistoryIDs,HistorySusps,RuleNb,TupleVar,NovelProductions),
7563 ExtendHistory = '$extend_history'(HistorySusp,TupleVar),
7564 NovelProduction = ( TupleVar = Tuple, NovelProductions )
7571 ( chr_pp_flag(debugable,on) ->
7572 Rule = rule(_,_,Guard,Body),
7573 my_term_copy(Guard - Body, VarDict, DebugGuard - DebugBody),
7574 get_occurrence(F/A,O,_,ID),
7575 sort_by_key([Susp,OtherSusp|RestSusps],[ID|RestIDs],KeptSusps),
7576 DebugTry = 'chr debug_event'( try([],KeptSusps,DebugGuard,DebugBody)),
7577 DebugApply = 'chr debug_event'(apply([],KeptSusps,DebugGuard,DebugBody))
7583 ( is_stored_in_guard(F/A, RuleNb) ->
7584 GuardAttachment = Attachment,
7585 BodyAttachment = true
7587 GuardAttachment = true,
7588 BodyAttachment = Attachment % will be true if not observed at all
7604 ConditionalRecursiveCall
7608 add_location(Clause,RuleNb,LocatedClause),
7609 L = [LocatedClause|T].
7611 novel_production_calls([],[],[],_,_,true).
7612 novel_production_calls([ConstraintSymbol|ConstraintSymbols],[ID|IDs],[Suspension|Suspensions],RuleNb,Tuple,(Goal,Goals)) :-
7613 get_occurrence_from_id(ConstraintSymbol,Occurrence,RuleNb,ID),
7614 delay_phase_end(validate_store_type_assumptions,novel_production_call(ConstraintSymbol,Occurrence,'$novel_production'(Suspension,Tuple),Goal)),
7615 novel_production_calls(ConstraintSymbols,IDs,Suspensions,RuleNb,Tuple,Goals).
7617 history_susps(RestIDs,ReversedRestSusps,Susp,ID,HistorySusps) :-
7618 reverse(ReversedRestSusps,RestSusps),
7619 sort_by_key([Susp|RestSusps],[ID|RestIDs],HistorySusps).
7621 named_history_susps([],_,_,[]).
7622 named_history_susps([HistoryID|HistoryIDs],IDs,Susps,[HistorySusp|HistorySusps]) :-
7623 select2(HistoryID,HistorySusp,IDs,Susps,RestIDs,RestSusps), !,
7624 named_history_susps(HistoryIDs,RestIDs,RestSusps,HistorySusps).
7628 gen_var_susp_list_for([Head],Terms,VarDict,HeadVars,VarsSusp,Susp) :-
7631 head_info(Head,A,_Vars,Susp,VarsSusp,HeadPairs),
7632 get_constraint_mode(F/A,Mode),
7633 head_arg_matches(HeadPairs,Mode,[],_,VarDict),
7634 extra_active_delegate_variables(Head,Terms,VarDict,ExtraVars),
7635 append(VarsSusp,ExtraVars,HeadVars).
7636 gen_var_susp_list_for([Head|Heads],Terms,NVarDict,VarsSusps,Rest,Susps) :-
7637 gen_var_susp_list_for(Heads,[Head|Terms],VarDict,Rest,_,_),
7640 head_info(Head,A,_Vars,Susp,_VarsSusp,HeadPairs),
7641 get_constraint_mode(F/A,Mode),
7642 head_arg_matches(HeadPairs,Mode,VarDict,_,NVarDict),
7643 passive_delegate_variables(Head,Heads,Terms,NVarDict,HeadVars),
7644 append(HeadVars,[Susp,Susps|Rest],VarsSusps).
7647 % VarDict for the copies of variables in the original heads
7648 % VarsSuspsList list of lists of arguments for the successive heads
7649 % FirstVarsSusp top level arguments
7650 % SuspList list of all suspensions
7651 % Iterators list of all iterators
7652 gen_var_susp_list_for_b([Head],NextHeads,VarDict,[HeadVars],VarsSusp,[Susp],[]) :-
7655 head_info(Head,A,_Vars,Susp,VarsSusp,Pairs), % make variables for argument positions
7656 get_constraint_mode(F/A,Mode),
7657 head_arg_matches(Pairs,Mode,[],_,VarDict), % copy variables inside arguments, build dictionary
7658 extra_active_delegate_variables(Head,NextHeads,VarDict,ExtraVars), % decide what additional variables are needed
7659 append(VarsSusp,ExtraVars,HeadVars). % add additional variables to head variables
7660 gen_var_susp_list_for_b([Head|Heads],NextHeads,NVarDict,[Vars|RestVars],FirstVarsSusp,[Susp|SuspList],[Susps|Iterators]) :-
7661 gen_var_susp_list_for_b(Heads,[Head|NextHeads],VarDict,RestVars,FirstVarsSusp,SuspList,Iterators),
7664 head_info(Head,A,_Vars,Susp,_VarsSusp,HeadPairs),
7665 get_constraint_mode(F/A,Mode),
7666 head_arg_matches(HeadPairs,Mode,VarDict,_,NVarDict),
7667 passive_delegate_variables(Head,Heads,NextHeads,NVarDict,HeadVars),
7668 append(HeadVars,[Susp,Susps],Vars).
7670 get_prop_inner_loop_vars([Head],NextHeads,HeadVars,VarDict,Susp,Vars,[]) :-
7673 head_info(Head,A,Vars,Susp,VarsSusp,Pairs),
7674 get_constraint_mode(F/A,Mode),
7675 head_arg_matches(Pairs,Mode,[],_,VarDict),
7676 extra_active_delegate_variables(Head,NextHeads,VarDict,ExtraVars),
7677 append(VarsSusp,ExtraVars,HeadVars).
7678 get_prop_inner_loop_vars([Head|Heads],Terms,VarsSusps,NVarDict,MainSusp,MainVars,[Susp|RestSusps]) :-
7679 get_prop_inner_loop_vars(Heads,[Head|Terms],RestVarsSusp,VarDict,MainSusp,MainVars,RestSusps),
7682 head_info(Head,A,_Vars,Susp,_VarsSusp,Pairs),
7683 get_constraint_mode(F/A,Mode),
7684 head_arg_matches(Pairs,Mode,VarDict,_,NVarDict),
7685 passive_delegate_variables(Head,Heads,Terms,NVarDict,HeadVars),
7686 append(HeadVars,[Susp,Susps|RestVarsSusp],VarsSusps).
7688 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7690 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7692 %% | _ \ __ _ ___ ___(_)_ _____ | | | | ___ __ _ __| |
7693 %% | |_) / _` / __/ __| \ \ / / _ \ | |_| |/ _ \/ _` |/ _` |
7694 %% | __/ (_| \__ \__ \ |\ V / __/ | _ | __/ (_| | (_| |
7695 %% |_| \__,_|___/___/_| \_/ \___| |_| |_|\___|\__,_|\__,_|
7698 %% | _ \ ___| |_ _ __(_) _____ ____ _| |
7699 %% | |_) / _ \ __| '__| |/ _ \ \ / / _` | |
7700 %% | _ < __/ |_| | | | __/\ V / (_| | |
7701 %% |_| \_\___|\__|_| |_|\___| \_/ \__,_|_|
7704 %% | _ \ ___ ___ _ __ __| | ___ _ __(_)_ __ __ _
7705 %% | |_) / _ \/ _ \| '__/ _` |/ _ \ '__| | '_ \ / _` |
7706 %% | _ < __/ (_) | | | (_| | __/ | | | | | | (_| |
7707 %% |_| \_\___|\___/|_| \__,_|\___|_| |_|_| |_|\__, |
7710 reorder_heads(RuleNb,Head,RestHeads,RestIDs,NRestHeads,NRestIDs) :-
7711 ( chr_pp_flag(reorder_heads,on), length(RestHeads,Length), Length =< 6 ->
7712 reorder_heads_main(RuleNb,Head,RestHeads,RestIDs,NRestHeads,NRestIDs)
7714 NRestHeads = RestHeads,
7718 reorder_heads_main(RuleNb,Head,RestHeads,RestIDs,NRestHeads,NRestIDs) :-
7719 term_variables(Head,Vars),
7720 InitialData = entry([],[],Vars,RestHeads,RestIDs,RuleNb),
7721 copy_term_nat(InitialData,InitialDataCopy),
7722 a_star(InitialDataCopy,FD^(chr_translate:final_data(FD)),N^EN^C^(chr_translate:expand_data(N,EN,C)),FinalData),
7723 InitialDataCopy = InitialData,
7724 FinalData = entry(RNRestHeads,RNRestIDs,_,_,_,_),
7725 reverse(RNRestHeads,NRestHeads),
7726 reverse(RNRestIDs,NRestIDs).
7728 final_data(Entry) :-
7729 Entry = entry(_,_,_,_,[],_).
7731 expand_data(Entry,NEntry,Cost) :-
7732 Entry = entry(Heads,IDs,Vars,NHeads,NIDs,RuleNb),
7733 select2(Head1,ID1,NHeads,NIDs,NHeads1,NIDs1),
7734 term_variables([Head1|Vars],Vars1),
7735 NEntry = entry([Head1|Heads],[ID1|IDs],Vars1,NHeads1,NIDs1,RuleNb),
7736 order_score(Head1,ID1,Vars,NHeads1,RuleNb,Cost).
7738 % Assigns score to head based on known variables and heads to lookup
7739 order_score(Head,ID,KnownVars,RestHeads,RuleNb,Score) :-
7741 get_store_type(F/A,StoreType),
7742 order_score(StoreType,Head,ID,KnownVars,RestHeads,RuleNb,Score).
7744 order_score(default,Head,_ID,KnownVars,RestHeads,RuleNb,Score) :-
7745 term_variables(Head,HeadVars),
7746 term_variables(RestHeads,RestVars),
7747 order_score_vars(HeadVars,KnownVars,RestVars,Score).
7748 order_score(multi_inthash(Indexes),Head,_ID,KnownVars,RestHeads,RuleNb,Score) :-
7749 order_score_indexes(Indexes,Head,KnownVars,0,Score).
7750 order_score(multi_hash(Indexes),Head,_ID,KnownVars,RestHeads,RuleNb,Score) :-
7751 order_score_indexes(Indexes,Head,KnownVars,0,Score).
7752 order_score(global_ground,Head,ID,KnownVars,RestHeads,RuleNb,Score) :-
7753 term_variables(Head,HeadVars),
7754 term_variables(RestHeads,RestVars),
7755 order_score_vars(HeadVars,KnownVars,RestVars,Score_),
7756 Score is Score_ * 2.
7757 order_score(var_assoc_store(_,_),_,_,_,_,_,1).
7758 order_score(global_singleton,_Head,ID,_KnownVars,_RestHeads,_RuleNb,Score) :-
7759 Score = 1. % guaranteed O(1)
7761 order_score(multi_store(StoreTypes),Head,ID,KnownVars,RestHeads,RuleNb,Score) :-
7762 find_with_var_identity(
7764 t(Head,KnownVars,RestHeads),
7765 ( lists:member(ST,StoreTypes), chr_translate:order_score(ST,Head,ID,KnownVars,RestHeads,RuleNb,S) ),
7768 min_list(Scores,Score).
7769 order_score(identifier_store(Index),Head,ID,KnownVars,RestHeads,RuleNb,Score) :-
7771 order_score(type_indexed_identifier_store(_,_),Head,ID,KnownVars,RestHeads,RuleNb,Score) :-
7774 order_score_indexes([],_,_,Score,NScore) :-
7775 Score > 0, NScore = 100.
7776 order_score_indexes([I|Is],Head,KnownVars,Score,NScore) :-
7777 multi_hash_key_args(I,Head,Args),
7778 ( forall(Arg,Args,memberchk_eq(Arg,KnownVars)) ->
7783 order_score_indexes(Is,Head,KnownVars,Score1,NScore).
7785 order_score_vars(Vars,KnownVars,RestVars,Score) :-
7786 order_score_count_vars(Vars,KnownVars,RestVars,K-R-O),
7790 Score is max(10 - K,0)
7792 Score is max(10 - R,1) * 10
7794 Score is max(10-O,1) * 100
7796 order_score_count_vars([],_,_,0-0-0).
7797 order_score_count_vars([V|Vs],KnownVars,RestVars,NK-NR-NO) :-
7798 order_score_count_vars(Vs,KnownVars,RestVars,K-R-O),
7799 ( memberchk_eq(V,KnownVars) ->
7802 ; memberchk_eq(V,RestVars) ->
7810 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7812 %% |_ _|_ __ | (_)_ __ (_)_ __ __ _
7813 %% | || '_ \| | | '_ \| | '_ \ / _` |
7814 %% | || | | | | | | | | | | | | (_| |
7815 %% |___|_| |_|_|_|_| |_|_|_| |_|\__, |
7819 create_get_mutable_ref(V,M,GM) :- GM = (M = mutable(V)).
7820 create_get_mutable(V,M,GM) :- M = mutable(V), GM = true.
7824 %% create_get_mutable(V,M,GM) :- GM = get_mutable(V,M).
7825 %% create_get_mutable_ref(V,M,GM) :- GM = get_mutable(V,M).
7828 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7830 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7832 %% | | | | |_(_) (_) |_ _ _
7833 %% | | | | __| | | | __| | | |
7834 %% | |_| | |_| | | | |_| |_| |
7835 %% \___/ \__|_|_|_|\__|\__, |
7838 % Create a fresh variable.
7841 % Create =N= fresh variables.
7845 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs) :-
7846 vars_susp(A,Vars,Susp,VarsSusp),
7848 pairup(Args,Vars,HeadPairs).
7850 inc_id([N|Ns],[O|Ns]) :-
7852 dec_id([N|Ns],[M|Ns]) :-
7855 extend_id(Id,[0|Id]).
7857 next_id([_,N|Ns],[O|Ns]) :-
7860 % return clause Head
7861 % for F/A constraint symbol, predicate identifier Id and arguments Head
7862 build_head(F,A,Id,Args,Head) :-
7863 buildName(F,A,Id,Name),
7864 ( (chr_pp_flag(debugable,on) ; is_stored(F/A), ( has_active_occurrence(F/A) ; chr_pp_flag(late_allocation,off)),
7865 ( may_trigger(F/A) ;
7866 get_allocation_occurrence(F/A,AO),
7867 get_max_occurrence(F/A,MO),
7869 Head =.. [Name|Args]
7871 init(Args,ArgsWOSusp), % XXX not entirely correct!
7872 Head =.. [Name|ArgsWOSusp]
7875 % return predicate name Result
7876 % for Fct/Aty constraint symbol and predicate identifier List
7877 buildName(Fct,Aty,List,Result) :-
7878 ( (chr_pp_flag(debugable,on) ; (once((is_stored(Fct/Aty), ( has_active_occurrence(Fct/Aty) ; chr_pp_flag(late_allocation,off)),
7879 ( may_trigger(Fct/Aty) ; get_allocation_occurrence(Fct/Aty,AO), get_max_occurrence(Fct/Aty,MO),
7880 MO >= AO ) ; List \= [0])) ) ) ->
7881 atom_concat(Fct, '___' ,FctSlash),
7882 atomic_concat(FctSlash,Aty,FctSlashAty),
7883 buildName_(List,FctSlashAty,Result)
7888 buildName_([],Name,Name).
7889 buildName_([N|Ns],Name,Result) :-
7890 buildName_(Ns,Name,Name1),
7891 atom_concat(Name1,'__',NameDash), % '_' is a char :-(
7892 atomic_concat(NameDash,N,Result).
7894 vars_susp(A,Vars,Susp,VarsSusp) :-
7896 append(Vars,[Susp],VarsSusp).
7898 or_pattern(Pos,Pat) :-
7900 Pat is 1 << Pow. % was 2 ** X
7902 and_pattern(Pos,Pat) :-
7904 Y is 1 << X, % was 2 ** X
7905 Pat is (-1)*(Y + 1).
7907 make_name(Prefix,F/A,Name) :-
7908 atom_concat_list([Prefix,F,'___',A],Name).
7910 %===============================================================================
7911 % Attribute for attributed variables
7913 make_attr(N,Mask,SuspsList,Attr) :-
7914 length(SuspsList,N),
7915 Attr =.. [v,Mask|SuspsList].
7917 get_all_suspensions2(N,Attr,SuspensionsList) :-
7918 chr_pp_flag(dynattr,off), !,
7919 make_attr(N,_,SuspensionsList,Attr).
7922 get_all_suspensions2(N,Attr,Goal,SuspensionsList) :-
7923 % writeln(get_all_suspensions2),
7924 length(SuspensionsList,N),
7925 Goal = 'chr all_suspensions'(SuspensionsList,1,Attr).
7929 normalize_attr(Attr,NormalGoal,NormalAttr) :-
7930 % writeln(normalize_attr),
7931 NormalGoal = 'chr normalize_attr'(Attr,NormalAttr).
7933 get_suspensions(N,Position,TAttr,(TAttr = Attr),Suspensions) :-
7934 chr_pp_flag(dynattr,off), !,
7935 make_attr(N,_,SuspsList,Attr),
7936 nth1(Position,SuspsList,Suspensions).
7939 get_suspensions(N,Position,TAttr,Goal,Suspensions) :-
7940 % writeln(get_suspensions),
7942 ( memberchk(Position-Suspensions,TAttr) ->
7948 %-------------------------------------------------------------------------------
7949 % +N: number of constraint symbols
7950 % +Suspension: source-level variable, for suspension
7951 % +Position: constraint symbol number
7952 % -Attr: source-level term, for new attribute
7953 singleton_attr(N,Suspension,Position,Attr) :-
7954 chr_pp_flag(dynattr,off), !,
7955 or_pattern(Position,Pattern),
7956 make_attr(N,Pattern,SuspsList,Attr),
7957 nth1(Position,SuspsList,[Suspension]),
7958 chr_delete(SuspsList,[Suspension],RestSuspsList),
7959 set_elems(RestSuspsList,[]).
7962 singleton_attr(N,Suspension,Position,Attr) :-
7963 % writeln(singleton_attr),
7964 Attr = [Position-[Suspension]].
7966 %-------------------------------------------------------------------------------
7967 % +N: number of constraint symbols
7968 % +Suspension: source-level variable, for suspension
7969 % +Position: constraint symbol number
7970 % +TAttr: source-level variable, for old attribute
7971 % -Goal: goal for creating new attribute
7972 % -NTAttr: source-level variable, for new attribute
7973 add_attr(N,Suspension,Position,TAttr,Goal,NTAttr) :-
7974 chr_pp_flag(dynattr,off), !,
7975 make_attr(N,Mask,SuspsList,Attr),
7976 or_pattern(Position,Pattern),
7977 nth1(Position,SuspsList,Susps),
7978 substitute_eq(Susps,SuspsList,[Suspension|Susps],SuspsList1),
7979 make_attr(N,Mask,SuspsList1,NewAttr1),
7980 substitute_eq(Susps,SuspsList,[Suspension],SuspsList2),
7981 make_attr(N,NewMask,SuspsList2,NewAttr2),
7984 ( Mask /\ Pattern =:= Pattern ->
7987 NewMask is Mask \/ Pattern,
7993 add_attr(N,Suspension,Position,TAttr,Goal,NTAttr) :-
7994 % writeln(add_attr),
7996 ( 'chr select'(TAttr,Position-Suspensions,RAttr) ->
7997 NTAttr = [Position-[Suspension|Suspensions]|RAttr]
7999 NTAttr = [Position-[Suspension]|TAttr]
8002 rem_attr(N,Var,Suspension,Position,TAttr,Goal) :-
8003 chr_pp_flag(dynattr,off), !,
8004 or_pattern(Position,Pattern),
8005 and_pattern(Position,DelPattern),
8006 make_attr(N,Mask,SuspsList,Attr),
8007 nth1(Position,SuspsList,Susps),
8008 substitute_eq(Susps,SuspsList,[],SuspsList1),
8009 make_attr(N,NewMask,SuspsList1,Attr1),
8010 substitute_eq(Susps,SuspsList,NewSusps,SuspsList2),
8011 make_attr(N,Mask,SuspsList2,Attr2),
8012 get_target_module(Mod),
8015 ( Mask /\ Pattern =:= Pattern ->
8016 'chr sbag_del_element'(Susps,Suspension,NewSusps),
8018 NewMask is Mask /\ DelPattern,
8022 put_attr(Var,Mod,Attr1)
8025 put_attr(Var,Mod,Attr2)
8033 rem_attr(N,Var,Suspension,Position,TAttr,Goal) :-
8034 % writeln(rem_attr),
8035 get_target_module(Mod),
8037 ( 'chr select'(TAttr,Position-Suspensions,RAttr) ->
8038 'chr sbag_del_element'(Suspensions,Suspension,NSuspensions),
8039 ( NSuspensions == [] ->
8043 put_attr(Var,Mod,RAttr)
8046 put_attr(Var,Mod,[Position-NSuspensions|RAttr])
8052 %-------------------------------------------------------------------------------
8053 % +N: number of constraint symbols
8054 % +TAttr1: source-level variable, for attribute
8055 % +TAttr2: source-level variable, for other attribute
8056 % -Goal: goal for merging the two attributes
8057 % -Attr: source-level term, for merged attribute
8058 merge_attributes(N,TAttr1,TAttr2,Goal,Attr) :-
8059 chr_pp_flag(dynattr,off), !,
8060 make_attr(N,Mask1,SuspsList1,Attr1),
8061 merge_attributes2(N,Mask1,SuspsList1,TAttr2,Goal2,Attr),
8068 merge_attributes(N,TAttr1,TAttr2,Goal,Attr) :-
8069 % writeln(merge_attributes),
8071 sort(TAttr1,Sorted1),
8072 sort(TAttr2,Sorted2),
8073 'chr new_merge_attributes'(Sorted1,Sorted2,Attr)
8077 %-------------------------------------------------------------------------------
8078 % +N: number of constraint symbols
8080 % +SuspsList1: static term, for suspensions list
8081 % +TAttr2: source-level variable, for other attribute
8082 % -Goal: goal for merging the two attributes
8083 % -Attr: source-level term, for merged attribute
8084 merge_attributes2(N,Mask1,SuspsList1,TAttr2,Goal,Attr) :-
8085 make_attr(N,Mask2,SuspsList2,Attr2),
8086 bagof(G,X ^ Y ^ SY ^ M ^ (member2(SuspsList1,SuspsList2,X-Y),G = (sort(Y,SY),'chr merge_attributes'(X,SY,M))),Gs),
8087 list2conj(Gs,SortGoals),
8088 bagof(MS,A ^ B ^ C ^ member((A,'chr merge_attributes'(B,C,MS)),Gs), SuspsList),
8089 make_attr(N,Mask,SuspsList,Attr),
8093 Mask is Mask1 \/ Mask2
8097 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8098 % Storetype dependent lookup
8100 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8101 %% lookup_passive_head(+Head,+PreviousVars,+RenamingVarDict,
8102 %% -Goal,-SuspensionList) is det.
8104 % Create a universal lookup goal for given head.
8105 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8106 lookup_passive_head(Head,PreJoin,VarDict,Goal,AllSusps) :-
8108 get_store_type(F/A,StoreType),
8109 lookup_passive_head(StoreType,Head,PreJoin,VarDict,[],Goal,AllSusps).
8111 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8112 %% lookup_passive_head(+Head,+PreviousVars,+RenamingVarDict,+GroundVars,
8113 %% -Goal,-SuspensionList) is det.
8115 % Create a universal lookup goal for given head.
8116 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8117 lookup_passive_head(Head,PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
8119 get_store_type(F/A,StoreType),
8120 lookup_passive_head(StoreType,Head,PreJoin,VarDict,GroundVars,Goal,AllSusps).
8122 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8123 %% lookup_passive_head(+StoreType,+Head,+PreviousVars,+RenamingVarDict,
8124 %% +GroundVars,-Goal,-SuspensionList) is det.
8126 % Create a universal lookup goal for given head.
8127 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8128 lookup_passive_head(default,Head,PreJoin,VarDict,_,Goal,AllSusps) :-
8130 passive_head_via(Head,PreJoin,VarDict,Goal,AllSusps),
8131 update_store_type(F/A,default).
8132 lookup_passive_head(multi_inthash(Indexes),Head,_PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
8133 hash_lookup_passive_head(inthash,Indexes,Head,VarDict,GroundVars,Goal,AllSusps,_).
8134 lookup_passive_head(multi_hash(Indexes),Head,_PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
8135 hash_lookup_passive_head(hash,Indexes,Head,VarDict,GroundVars,Goal,AllSusps,_).
8136 lookup_passive_head(global_ground,Head,_PreJoin,_VarDict,_,Goal,AllSusps) :-
8138 global_ground_store_name(F/A,StoreName),
8139 make_get_store_goal(StoreName,AllSusps,Goal), % Goal = nb_getval(StoreName,AllSusps),
8140 update_store_type(F/A,global_ground).
8141 lookup_passive_head(var_assoc_store(VarIndex,KeyIndex),Head,_PreJoin,VarDict,_,Goal,AllSusps) :-
8142 arg(VarIndex,Head,OVar),
8143 arg(KeyIndex,Head,OKey),
8144 translate([OVar,OKey],VarDict,[Var,Key]),
8145 get_target_module(Module),
8147 get_attr(Var,Module,AssocStore),
8148 lookup_assoc_store(AssocStore,Key,AllSusps)
8150 lookup_passive_head(global_singleton,Head,_PreJoin,_VarDict,_,Goal,AllSusps) :-
8152 global_singleton_store_name(F/A,StoreName),
8153 make_get_store_goal(StoreName,Susp,GetStoreGoal),
8154 Goal = (GetStoreGoal,Susp \== [],AllSusps = [Susp]),
8155 update_store_type(F/A,global_singleton).
8156 lookup_passive_head(multi_store(StoreTypes),Head,PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
8158 member(ST,StoreTypes),
8159 lookup_passive_head(ST,Head,PreJoin,VarDict,GroundVars,Goal,AllSusps)
8161 lookup_passive_head(identifier_store(Index),Head,PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
8163 arg(Index,Head,Var),
8164 translate([Var],VarDict,[KeyVar]),
8165 delay_phase_end(validate_store_type_assumptions,
8166 identifier_lookup(F/A,Index,AllSusps,KeyVar,Goal)
8168 update_store_type(F/A,identifier_store(Index)),
8169 get_identifier_index(F/A,Index,_).
8170 lookup_passive_head(type_indexed_identifier_store(Index,IndexType),Head,PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
8172 arg(Index,Head,Var),
8174 translate([Var],VarDict,[KeyVar]),
8176 ; ground(Var), Var = '$chr_identifier_match'(ActualVar,_) ->
8177 lookup_identifier_atom(IndexType,ActualVar,KeyVar,LookupGoal),
8178 Goal = (LookupGoal,StructGoal)
8180 delay_phase_end(validate_store_type_assumptions,
8181 type_indexed_identifier_lookup(F/A,Index,IndexType,AllSusps,KeyVar,StructGoal)
8183 update_store_type(F/A,type_indexed_identifier_store(Index,IndexType)),
8184 get_type_indexed_identifier_index(IndexType,F/A,Index,_).
8186 identifier_lookup(C,Index,AllSusps,KeyVar,Goal) :-
8187 get_identifier_size(ISize),
8188 functor(Struct,struct,ISize),
8189 get_identifier_index(C,Index,IIndex),
8190 arg(IIndex,Struct,AllSusps),
8191 Goal = (KeyVar = Struct).
8193 type_indexed_identifier_lookup(C,Index,IndexType,AllSusps,KeyVar,Goal) :-
8194 type_indexed_identifier_structure(IndexType,Struct),
8195 get_type_indexed_identifier_index(IndexType,C,Index,IIndex),
8196 arg(IIndex,Struct,AllSusps),
8197 Goal = (KeyVar = Struct).
8199 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8200 %% hash_lookup_passive_head(+StoreType,+Indexes,+Head,+RenamingVarDict,
8201 %% +GroundVars,-Goal,-SuspensionList,-Index) is det.
8203 % Create a universal hash lookup goal for given head.
8204 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8205 hash_lookup_passive_head(HashType,Indexes,Head,VarDict,GroundVars,Goal,AllSusps,Index) :-
8207 member(Index,Indexes),
8208 multi_hash_key_args(Index,Head,KeyArgs),
8210 translate(KeyArgs,VarDict,KeyArgCopies)
8212 ground(KeyArgs), KeyArgCopies = KeyArgs
8215 ( KeyArgCopies = [KeyCopy] ->
8218 KeyCopy =.. [k|KeyArgCopies]
8221 multi_hash_lookup_goal(F/A,HashType,Index,KeyCopy,AllSusps,LookupGoal),
8223 check_ground(GroundVars,KeyArgs,OriginalGroundCheck),
8224 my_term_copy(OriginalGroundCheck,VarDict,GroundCheck),
8226 Goal = (GroundCheck,LookupGoal),
8228 ( HashType == inthash ->
8229 update_store_type(F/A,multi_inthash([Index]))
8231 update_store_type(F/A,multi_hash([Index]))
8234 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8235 %% existential_lookup(+StoreType,+Head,+PrevVariablesHead,+RenamingVarDict,
8236 %% +GroundVariables,-SuspensionTerm,-Goal,-SuspVar,
8237 %% +VarArgDict,-NewVarArgDict) is det.
8239 % Create existential lookup goal for given head.
8240 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8241 existential_lookup(var_assoc_store(VarIndex,KeyIndex),Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,Pairs) :- !,
8242 lookup_passive_head(var_assoc_store(VarIndex,KeyIndex),Head,PreJoin,VarDict,GroundVars,UniversalGoal,AllSusps),
8243 sbag_member_call(Susp,AllSusps,Sbag),
8245 delay_phase_end(validate_store_type_assumptions,
8246 ( static_suspension_term(F/A,SuspTerm),
8247 get_static_suspension_field(F/A,SuspTerm,state,active,GetState)
8256 existential_lookup(global_singleton,Head,_PreJoin,_VarDict,_,SuspTerm,Goal,Susp,Pairs,Pairs) :- !,
8258 global_singleton_store_name(F/A,StoreName),
8259 make_get_store_goal(StoreName,Susp,GetStoreGoal),
8261 GetStoreGoal, % nb_getval(StoreName,Susp),
8265 update_store_type(F/A,global_singleton).
8266 existential_lookup(multi_store(StoreTypes),Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :- !,
8268 member(ST,StoreTypes),
8269 existential_lookup(ST,Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs)
8271 existential_lookup(multi_inthash(Indexes),Head,_,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :- !,
8272 existential_hash_lookup(inthash,Indexes,Head,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs).
8273 existential_lookup(multi_hash(Indexes),Head,_,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :- !,
8274 existential_hash_lookup(hash,Indexes,Head,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs).
8275 existential_lookup(identifier_store(Index),Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :- !,
8276 lookup_passive_head(identifier_store(Index),Head,PreJoin,VarDict,GroundVars,LookupGoal,AllSusps),
8277 hash_index_filter(Pairs,Index,NPairs),
8280 ( check_fd_lookup_condition(F,A,Head,KeyArgs) ->
8281 Sbag = (AllSusps = [Susp])
8283 sbag_member_call(Susp,AllSusps,Sbag)
8285 delay_phase_end(validate_store_type_assumptions,
8286 ( static_suspension_term(F/A,SuspTerm),
8287 get_static_suspension_field(F/A,SuspTerm,state,active,GetState)
8293 Susp = SuspTerm, % not inlined
8296 existential_lookup(type_indexed_identifier_store(Index,IndexType),Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :- !,
8297 lookup_passive_head(type_indexed_identifier_store(Index,IndexType),Head,PreJoin,VarDict,GroundVars,LookupGoal,AllSusps),
8298 hash_index_filter(Pairs,Index,NPairs),
8301 ( check_fd_lookup_condition(F,A,Head,KeyArgs) ->
8302 Sbag = (AllSusps = [Susp])
8304 sbag_member_call(Susp,AllSusps,Sbag)
8306 delay_phase_end(validate_store_type_assumptions,
8307 ( static_suspension_term(F/A,SuspTerm),
8308 get_static_suspension_field(F/A,SuspTerm,state,active,GetState)
8314 Susp = SuspTerm, % not inlined
8317 existential_lookup(StoreType,Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,Pairs) :-
8318 lookup_passive_head(StoreType,Head,PreJoin,VarDict,GroundVars,UGoal,Susps),
8319 sbag_member_call(Susp,Susps,Sbag),
8321 delay_phase_end(validate_store_type_assumptions,
8322 ( static_suspension_term(F/A,SuspTerm),
8323 get_static_suspension_field(F/A,SuspTerm,state,active,GetState)
8329 Susp = SuspTerm, % not inlined
8333 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8334 %% existential_hash_lookup(+StoreType,+Indexes,+Head,+RenamingVarDict,
8335 %% +GroundVariables,-SuspensionTerm,-Goal,-SuspVar,
8336 %% +VarArgDict,-NewVarArgDict) is det.
8338 % Create existential hash lookup goal for given head.
8339 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8340 existential_hash_lookup(HashType,Indexes,Head,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :-
8341 hash_lookup_passive_head(HashType,Indexes,Head,VarDict,GroundVars,LookupGoal,AllSusps,Index),
8343 hash_index_filter(Pairs,Index,NPairs),
8346 ( check_fd_lookup_condition(F,A,Head,KeyArgs) ->
8347 Sbag = (AllSusps = [Susp])
8349 sbag_member_call(Susp,AllSusps,Sbag)
8351 delay_phase_end(validate_store_type_assumptions,
8352 ( static_suspension_term(F/A,SuspTerm),
8353 get_static_suspension_field(F/A,SuspTerm,state,active,GetState)
8359 Susp = SuspTerm, % not inlined
8363 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8364 %% hash_index_filter(+Pairs,+Index,-NPairs) is det.
8366 % Filter out pairs already covered by given hash index.
8367 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8368 hash_index_filter(Pairs,Index,NPairs) :-
8374 hash_index_filter(Pairs,NIndex,1,NPairs).
8376 hash_index_filter([],_,_,[]).
8377 hash_index_filter([P|Ps],Index,N,NPairs) :-
8382 hash_index_filter(Ps,[I|Is],NN,NPs)
8384 hash_index_filter(Ps,Is,NN,NPairs)
8390 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8391 %------------------------------------------------------------------------------%
8392 %% assume_constraint_stores(+ConstraintSymbols) is det.
8394 % Compute all constraint store types that are possible for the given
8395 % =ConstraintSymbols=.
8396 %------------------------------------------------------------------------------%
8397 assume_constraint_stores([]).
8398 assume_constraint_stores([C|Cs]) :-
8399 ( chr_pp_flag(debugable,off),
8400 ( only_ground_indexed_arguments(C) ; chr_pp_flag(mixed_stores,on) ),
8402 get_store_type(C,default) ->
8403 get_indexed_arguments(C,AllIndexedArgs),
8404 get_constraint_mode(C,Modes),
8405 findall(Index,(member(Index,AllIndexedArgs),
8406 nth(Index,Modes,+)),IndexedArgs),
8407 length(IndexedArgs,NbIndexedArgs),
8408 % Construct Index Combinations
8409 ( NbIndexedArgs > 10 ->
8410 findall([Index],member(Index,IndexedArgs),Indexes)
8412 findall(Index,(sublist(Index,IndexedArgs), Index \== []),UnsortedIndexes),
8413 predsort(longer_list,UnsortedIndexes,Indexes)
8416 ( get_functional_dependency(C,1,Pattern,Key),
8417 all_distinct_var_args(Pattern), Key == [] ->
8418 assumed_store_type(C,global_singleton)
8419 ; ( only_ground_indexed_arguments(C) ; NbIndexedArgs > 0 ) ->
8420 get_constraint_type_det(C,ArgTypes),
8421 partition_indexes(Indexes,ArgTypes,HashIndexes,IntHashIndexes,IdentifierIndexes,CompoundIdentifierIndexes),
8423 ( IntHashIndexes = [] ->
8426 Stores = [multi_inthash(IntHashIndexes)|Stores1]
8428 ( HashIndexes = [] ->
8431 Stores1 = [multi_hash(HashIndexes)|Stores2]
8433 ( IdentifierIndexes = [] ->
8436 maplist(wrap_in_functor(identifier_store),IdentifierIndexes,WrappedIdentifierIndexes),
8437 append(WrappedIdentifierIndexes,Stores3,Stores2)
8439 append(CompoundIdentifierIndexes,Stores4,Stores3),
8440 ( only_ground_indexed_arguments(C)
8441 -> Stores4 = [global_ground]
8442 ; Stores4 = [default]
8444 assumed_store_type(C,multi_store(Stores))
8450 assume_constraint_stores(Cs).
8452 %------------------------------------------------------------------------------%
8453 %% partition_indexes(+Indexes,+Types,
8454 %% -HashIndexes,-IntHashIndexes,-IdentifierIndexes) is det.
8455 %------------------------------------------------------------------------------%
8456 partition_indexes([],_,[],[],[],[]).
8457 partition_indexes([Index|Indexes],Types,HashIndexes,IntHashIndexes,IdentifierIndexes,CompoundIdentifierIndexes) :-
8460 unalias_type(Type,UnAliasedType),
8461 UnAliasedType == chr_identifier ->
8462 IdentifierIndexes = [I|RIdentifierIndexes],
8463 IntHashIndexes = RIntHashIndexes,
8464 HashIndexes = RHashIndexes,
8465 CompoundIdentifierIndexes = RCompoundIdentifierIndexes
8468 unalias_type(Type,UnAliasedType),
8469 nonvar(UnAliasedType),
8470 UnAliasedType = chr_identifier(IndexType) ->
8471 CompoundIdentifierIndexes = [type_indexed_identifier_store(I,IndexType)|RCompoundIdentifierIndexes],
8472 IdentifierIndexes = RIdentifierIndexes,
8473 IntHashIndexes = RIntHashIndexes,
8474 HashIndexes = RHashIndexes
8477 unalias_type(Type,UnAliasedType),
8478 UnAliasedType == dense_int ->
8479 IntHashIndexes = [Index|RIntHashIndexes],
8480 HashIndexes = RHashIndexes,
8481 IdentifierIndexes = RIdentifierIndexes,
8482 CompoundIdentifierIndexes = RCompoundIdentifierIndexes
8485 unalias_type(Type,UnAliasedType),
8486 nonvar(UnAliasedType),
8487 UnAliasedType = chr_identifier(_) ->
8488 % don't use chr_identifiers in hash indexes
8489 IntHashIndexes = RIntHashIndexes,
8490 HashIndexes = RHashIndexes,
8491 IdentifierIndexes = RIdentifierIndexes,
8492 CompoundIdentifierIndexes = RCompoundIdentifierIndexes
8494 IntHashIndexes = RIntHashIndexes,
8495 HashIndexes = [Index|RHashIndexes],
8496 IdentifierIndexes = RIdentifierIndexes,
8497 CompoundIdentifierIndexes = RCompoundIdentifierIndexes
8499 partition_indexes(Indexes,Types,RHashIndexes,RIntHashIndexes,RIdentifierIndexes,RCompoundIdentifierIndexes).
8501 longer_list(R,L1,L2) :-
8511 all_distinct_var_args(Term) :-
8513 copy_term_nat(Args,NArgs),
8514 all_distinct_var_args_(NArgs).
8516 all_distinct_var_args_([]).
8517 all_distinct_var_args_([X|Xs]) :-
8520 all_distinct_var_args_(Xs).
8522 get_indexed_arguments(C,IndexedArgs) :-
8524 get_indexed_arguments(1,A,C,IndexedArgs).
8526 get_indexed_arguments(I,N,C,L) :-
8529 ; ( is_indexed_argument(C,I) ->
8535 get_indexed_arguments(J,N,C,T)
8538 validate_store_type_assumptions([]).
8539 validate_store_type_assumptions([C|Cs]) :-
8540 validate_store_type_assumption(C),
8541 validate_store_type_assumptions(Cs).
8543 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8544 % new code generation
8545 universal_search_iterator_end([CurrentHead|PrevHeads],NextHeads,Rule,F/A,Id,L,T) :-
8546 Rule = rule(H1,_,Guard,Body),
8547 gen_var_susp_list_for_b(PrevHeads,[CurrentHead,NextHeads,Guard,Body],_,VarsAndSuspsList,FirstVarsSusp,_,PrevIterators),
8548 universal_search_iterator_failure_vars(PrevHeads,Id,VarsAndSuspsList,FirstVarsSusp,PrevIterators,PrevVarsAndSusps,PrevId),
8549 flatten(VarsAndSuspsList,VarsAndSusps),
8550 Vars = [ [] | VarsAndSusps],
8551 build_head(F,A,Id,Vars,Head),
8552 build_head(F,A,PrevId,PrevVarsAndSusps,PredecessorCall),
8553 Clause = ( Head :- PredecessorCall),
8554 add_dummy_location(Clause,LocatedClause),
8555 L = [LocatedClause | T].
8557 % functor(CurrentHead,CF,CA),
8558 % check_fd_lookup_condition(CF,CA,CurrentHead,PrevHeads) ->
8561 % gen_var_susp_list_for_b(PrevHeads,[CurrentHead,NextHeads,Guard,Body],_,VarsAndSuspsList,FirstVarsSusp,_,PrevIterators),
8562 % universal_search_iterator_failure_vars(PrevHeads,Id,VarsAndSuspsList,FirstVarsSusp,PrevIterators,PrevVarsAndSusps,PrevId),
8563 % flatten(VarsAndSuspsList,VarsAndSusps),
8564 % Vars = [ [] | VarsAndSusps],
8565 % build_head(F,A,Id,Vars,Head),
8566 % build_head(F,A,PrevId,PrevVarsAndSusps,PredecessorCall),
8567 % Clause = ( Head :- PredecessorCall),
8571 % skips back intelligently over global_singleton lookups
8572 universal_search_iterator_failure_vars(PrevHeads,Id,VarsAndSuspsList,BaseCallArgs,PrevIterators,PrevVarsAndSusps,PrevId) :-
8575 PrevVarsAndSusps = BaseCallArgs
8577 VarsAndSuspsList = [_|AllButFirstList],
8579 ( PrevHeads = [PrevHead|PrevHeads1],
8580 functor(PrevHead,F,A),
8581 check_fd_lookup_condition(F,A,PrevHead,PrevHeads1) ->
8582 PrevIterators = [_|PrevIterators1],
8583 universal_search_iterator_failure_vars(PrevHeads1,PrevId1,AllButFirstList,BaseCallArgs,PrevIterators1,PrevVarsAndSusps,PrevId)
8586 flatten(AllButFirstList,AllButFirst),
8587 PrevIterators = [PrevIterator|_],
8588 PrevVarsAndSusps = [PrevIterator|AllButFirst]
8592 universal_search_iterator([NextHead|RestHeads],[CurrentHead|PreHeads],Rule,F/A,Id,L,T) :-
8593 Rule = rule(_,_,Guard,Body),
8594 gen_var_susp_list_for_b(PreHeads,[CurrentHead,NextHead,RestHeads,Guard,Body],VarDict,PreVarsAndSuspsList,FirstVarsSusp,AllSusps,PrevIterators),
8595 init(AllSusps,PreSusps),
8596 flatten(PreVarsAndSuspsList,PreVarsAndSusps),
8597 gen_var(OtherSusps),
8598 functor(CurrentHead,OtherF,OtherA),
8599 gen_vars(OtherA,OtherVars),
8600 head_info(CurrentHead,OtherA,OtherVars,OtherSusp,_VarsSusp,HeadPairs),
8601 get_constraint_mode(OtherF/OtherA,Mode),
8602 head_arg_matches(HeadPairs,Mode,VarDict,FirstMatching,VarDict1),
8604 delay_phase_end(validate_store_type_assumptions,
8605 ( static_suspension_term(OtherF/OtherA,OtherSuspension),
8606 get_static_suspension_field(OtherF/OtherA,OtherSuspension,state,active,GetState),
8607 get_static_suspension_term_field(arguments,OtherF/OtherA,OtherSuspension,OtherVars)
8611 different_from_other_susps(CurrentHead,OtherSusp,PreHeads,PreSusps,DiffSuspGoals),
8612 % create_get_mutable_ref(active,State,GetMutable),
8614 OtherSusp = OtherSuspension,
8619 add_heads_ground_variables([CurrentHead|PreHeads],[],GroundVars),
8620 lookup_passive_head(NextHead,[CurrentHead|PreHeads],VarDict1,GroundVars,NextSuspGoal,NextSusps),
8621 inc_id(Id,NestedId),
8622 ClauseVars = [[OtherSusp|OtherSusps]|PreVarsAndSusps],
8623 build_head(F,A,Id,ClauseVars,ClauseHead),
8624 passive_delegate_variables(CurrentHead,PreHeads,[NextHead,RestHeads,Guard,Body],VarDict1,CurrentHeadVars),
8625 append([NextSusps|CurrentHeadVars],[OtherSusp,OtherSusps|PreVarsAndSusps],NestedVars),
8626 build_head(F,A,NestedId,NestedVars,NestedHead),
8628 ( check_fd_lookup_condition(OtherF,OtherA,CurrentHead,PreHeads) -> % iterator (OtherSusps) is empty at runtime
8629 universal_search_iterator_failure_vars(PreHeads,Id,PreVarsAndSuspsList,FirstVarsSusp,PrevIterators,PreVarsAndSusps1,PrevId),
8630 RecursiveVars = PreVarsAndSusps1
8632 RecursiveVars = [OtherSusps|PreVarsAndSusps],
8635 build_head(F,A,PrevId,RecursiveVars,RecursiveHead),
8646 add_dummy_location(Clause,LocatedClause),
8647 L = [LocatedClause|T].
8649 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8651 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8652 % Observation Analysis
8657 % Analysis based on Abstract Interpretation paper.
8660 % stronger analysis domain [research]
8663 initial_call_pattern/1,
8665 call_pattern_worker/1,
8666 final_answer_pattern/2,
8667 abstract_constraints/1,
8671 ai_observed_internal/2,
8673 ai_not_observed_internal/2,
8677 ai_observation_gather_results/0.
8679 :- chr_type abstract_domain ---> odom(program_point,list(constraint)).
8680 :- chr_type program_point == any.
8682 :- chr_option(mode,initial_call_pattern(+)).
8683 :- chr_option(type_declaration,call_pattern(abstract_domain)).
8685 :- chr_option(mode,call_pattern(+)).
8686 :- chr_option(type_declaration,call_pattern(abstract_domain)).
8688 :- chr_option(mode,call_pattern_worker(+)).
8689 :- chr_option(type_declaration,call_pattern_worker(abstract_domain)).
8691 :- chr_option(mode,final_answer_pattern(+,+)).
8692 :- chr_option(type_declaration,final_answer_pattern(abstract_domain,abstract_domain)).
8694 :- chr_option(mode,abstract_constraints(+)).
8695 :- chr_option(type_declaration,abstract_constraints(list)).
8697 :- chr_option(mode,depends_on(+,+)).
8698 :- chr_option(type_declaration,depends_on(abstract_domain,abstract_domain)).
8700 :- chr_option(mode,depends_on_as(+,+,+)).
8701 :- chr_option(mode,depends_on_ap(+,+,+,+)).
8702 :- chr_option(mode,depends_on_goal(+,+)).
8703 :- chr_option(mode,ai_is_observed(+,+)).
8704 :- chr_option(mode,ai_not_observed(+,+)).
8705 % :- chr_option(mode,ai_observed(+,+)).
8706 :- chr_option(mode,ai_not_observed_internal(+,+)).
8707 :- chr_option(mode,ai_observed_internal(+,+)).
8710 abstract_constraints_fd @
8711 abstract_constraints(_) \ abstract_constraints(_) <=> true.
8713 ai_observed_internal(C,O) \ ai_not_observed_internal(C,O) <=> true.
8714 ai_not_observed_internal(C,O) \ ai_not_observed_internal(C,O) <=> true.
8715 ai_observed_internal(C,O) \ ai_observed_internal(C,O) <=> true.
8717 ai_not_observed(C,O) \ ai_is_observed(C,O) <=> fail.
8718 ai_is_observed(_,_) <=> true.
8720 ai_observation_gather_results \ ai_observed_internal(C,O) <=> true. % ai_observed(C,O).
8721 ai_observation_gather_results \ ai_not_observed_internal(C,O) <=> ai_not_observed(C,O).
8722 ai_observation_gather_results <=> true.
8724 %------------------------------------------------------------------------------%
8725 % Main Analysis Entry
8726 %------------------------------------------------------------------------------%
8727 ai_observation_analysis(ACs) :-
8728 ( chr_pp_flag(ai_observation_analysis,on),
8729 get_target_module(Module), '$chr_compiled_with_version'(3) -> % , Module \== guard_entailment ->
8730 list_to_ord_set(ACs,ACSet),
8731 abstract_constraints(ACSet),
8732 ai_observation_schedule_initial_calls(ACSet,ACSet),
8733 ai_observation_gather_results
8738 ai_observation_schedule_initial_calls([],_).
8739 ai_observation_schedule_initial_calls([AC|RACs],ACs) :-
8740 ai_observation_schedule_initial_call(AC,ACs),
8741 ai_observation_schedule_initial_calls(RACs,ACs).
8743 ai_observation_schedule_initial_call(AC,ACs) :-
8744 ai_observation_top(AC,CallPattern),
8745 % ai_observation_bot(AC,ACs,CallPattern),
8746 initial_call_pattern(CallPattern).
8748 ai_observation_schedule_new_calls([],AP).
8749 ai_observation_schedule_new_calls([AC|ACs],AP) :-
8751 initial_call_pattern(odom(AC,Set)),
8752 ai_observation_schedule_new_calls(ACs,AP).
8754 final_answer_pattern(CP,AP1) \ final_answer_pattern(CP,AP2)
8756 ai_observation_leq(AP2,AP1)
8760 initial_call_pattern(CP) \ initial_call_pattern(CP) <=> true.
8762 initial_call_pattern(CP) ==> call_pattern(CP).
8764 initial_call_pattern(CP), final_answer_pattern(CP,AP), abstract_constraints(ACs) # ID3
8766 ai_observation_schedule_new_calls(ACs,AP)
8770 call_pattern(CP) \ call_pattern(CP) <=> true.
8772 depends_on(CP1,CP2), final_answer_pattern(CP2,AP) ==>
8773 final_answer_pattern(CP1,AP).
8775 %call_pattern(CP) ==> writeln(call_pattern(CP)).
8777 call_pattern(CP) ==> call_pattern_worker(CP).
8779 %------------------------------------------------------------------------------%
8781 %------------------------------------------------------------------------------%
8784 %call_pattern(odom([],Set)) ==>
8785 % final_answer_pattern(odom([],Set),odom([],Set)).
8787 call_pattern_worker(odom([],Set)) <=>
8788 % writeln(' - AbstractGoal'(odom([],Set))),
8789 final_answer_pattern(odom([],Set),odom([],Set)).
8792 call_pattern_worker(odom([G|Gs],Set)) <=>
8793 % writeln(' - AbstractGoal'(odom([G|Gs],Set))),
8795 depends_on_goal(odom([G|Gs],Set),CP1),
8798 depends_on_goal(CP1,CP2), final_answer_pattern(CP2,AP2) \ depends_on(CP1,_) # ID
8799 <=> true pragma passive(ID).
8800 depends_on_goal(CP1,CP2), final_answer_pattern(CP2,AP2)
8802 CP1 = odom([_|Gs],_),
8806 depends_on(CP1,CCP).
8808 %------------------------------------------------------------------------------%
8809 % Abstract Disjunction
8810 %------------------------------------------------------------------------------%
8812 call_pattern_worker(odom((AG1;AG2),Set)) <=>
8813 CP = odom((AG1;AG2),Set),
8814 InitialAnswerApproximation = odom([],Set),
8815 final_answer_pattern(CP,InitialAnswerApproximation),
8816 CP1 = odom(AG1,Set),
8817 CP2 = odom(AG2,Set),
8820 depends_on_as(CP,CP1,CP2).
8822 %------------------------------------------------------------------------------%
8824 %------------------------------------------------------------------------------%
8825 call_pattern_worker(odom(builtin,Set)) <=>
8826 % writeln(' - AbstractSolve'(odom(builtin,Set))),
8827 ord_empty(EmptySet),
8828 final_answer_pattern(odom(builtin,Set),odom([],EmptySet)).
8830 %------------------------------------------------------------------------------%
8832 %------------------------------------------------------------------------------%
8833 max_occurrence(C,MO) # ID2 \ call_pattern_worker(odom(occ(C,O),Set))
8837 % writeln(' - AbstractDrop'(odom(occ(C,O),Set))),
8838 final_answer_pattern(odom(occ(C,O),Set),odom([],Set))
8842 %------------------------------------------------------------------------------%
8844 %------------------------------------------------------------------------------%
8845 call_pattern_worker(odom(AC,Set))
8849 % writeln(' - AbstractActivate'(odom(AC,Set))),
8850 CP = odom(occ(AC,1),Set),
8852 depends_on(odom(AC,Set),CP).
8854 %------------------------------------------------------------------------------%
8856 %------------------------------------------------------------------------------%
8857 occurrence(C,O,RuleNb,ID,_) # ID2 \ call_pattern_worker(odom(occ(C,O),Set))
8859 is_passive(RuleNb,ID)
8861 % writeln(' - AbstractPassive'(odom(occ(C,O),Set))),
8864 DCP = odom(occ(C,NO),Set),
8866 final_answer_pattern(odom(occ(C,O),Set),odom([],Set)),
8867 depends_on(odom(occ(C,O),Set),DCP)
8870 %------------------------------------------------------------------------------%
8872 %------------------------------------------------------------------------------%
8875 occurrence(C,O,RuleNb,ID,simplification) # ID2 \ call_pattern_worker(odom(occ(C,O),Set))
8877 \+ is_passive(RuleNb,ID)
8879 % writeln(' - AbstractPassive'(odom(occ(C,O),Set))),
8880 ai_observation_memo_simplification_rest_heads(C,O,AbstractRestHeads),
8881 ai_observation_observe_set(Set,AbstractRestHeads,Set2),
8882 ai_observation_memo_abstract_goal(RuleNb,AG),
8883 call_pattern(odom(AG,Set2)),
8886 DCP = odom(occ(C,NO),Set),
8888 depends_on_as(odom(occ(C,O),Set),odom(AG,Set2),DCP),
8889 % DEADLOCK AVOIDANCE
8890 final_answer_pattern(odom(occ(C,O),Set),odom([],Set))
8894 depends_on_as(CP,CPS,CPD),
8895 final_answer_pattern(CPS,APS),
8896 final_answer_pattern(CPD,APD) ==>
8897 ai_observation_lub(APS,APD,AP),
8898 final_answer_pattern(CP,AP).
8902 ai_observation_memo_simplification_rest_heads/3,
8903 ai_observation_memoed_simplification_rest_heads/3.
8905 :- chr_option(mode,ai_observation_memo_simplification_rest_heads(+,+,?)).
8906 :- chr_option(mode,ai_observation_memoed_simplification_rest_heads(+,+,+)).
8908 ai_observation_memoed_simplification_rest_heads(C,O,RH) \ ai_observation_memo_simplification_rest_heads(C,O,QRH)
8911 abstract_constraints(ACs) # ID1, occurrence(C,O,RuleNb,ID,_) # ID2, rule(RuleNb,Rule) # ID3 \ ai_observation_memo_simplification_rest_heads(C,O,QRH)
8913 Rule = pragma(rule(H1,H2,_,_),ids(IDs1,_),_,_,_),
8914 once(select2(ID,_,IDs1,H1,_,RestH1)),
8915 ai_observation_abstract_constraints(RestH1,ACs,ARestHeads),
8916 ai_observation_abstract_constraints(H2,ACs,AH2),
8917 append(ARestHeads,AH2,AbstractHeads),
8918 sort(AbstractHeads,QRH),
8919 ai_observation_memoed_simplification_rest_heads(C,O,QRH)
8925 ai_observation_memo_simplification_rest_heads(_,_,_) <=> fail.
8927 %------------------------------------------------------------------------------%
8928 % Abstract Propagate
8929 %------------------------------------------------------------------------------%
8933 occurrence(C,O,RuleNb,ID,propagation) # ID2 \ call_pattern_worker(odom(occ(C,O),Set))
8935 \+ is_passive(RuleNb,ID)
8937 % writeln(' - AbstractPropagate'(odom(occ(C,O),Set))),
8939 ai_observation_memo_propagation_rest_heads(C,O,AHs),
8940 ai_observation_observe_set(Set,AHs,Set2),
8941 ord_add_element(Set2,C,Set3),
8942 ai_observation_memo_abstract_goal(RuleNb,AG),
8943 call_pattern(odom(AG,Set3)),
8944 ( ord_memberchk(C,Set2) ->
8951 DCP = odom(occ(C,NO),Set),
8953 depends_on_ap(odom(occ(C,O),Set),odom(AG,Set3),DCP,Delete)
8958 ai_observation_memo_propagation_rest_heads/3,
8959 ai_observation_memoed_propagation_rest_heads/3.
8961 :- chr_option(mode,ai_observation_memo_propagation_rest_heads(+,+,?)).
8962 :- chr_option(mode,ai_observation_memoed_propagation_rest_heads(+,+,+)).
8964 ai_observation_memoed_propagation_rest_heads(C,O,RH) \ ai_observation_memo_propagation_rest_heads(C,O,QRH)
8967 abstract_constraints(ACs) # ID1, occurrence(C,O,RuleNb,ID,_) # ID2, rule(RuleNb,Rule) # ID3 \ ai_observation_memo_propagation_rest_heads(C,O,QRH)
8969 Rule = pragma(rule(H1,H2,_,_),ids(_,IDs2),_,_,_),
8970 once(select2(ID,_,IDs2,H2,_,RestH2)),
8971 ai_observation_abstract_constraints(RestH2,ACs,ARestHeads),
8972 ai_observation_abstract_constraints(H1,ACs,AH1),
8973 append(ARestHeads,AH1,AbstractHeads),
8974 sort(AbstractHeads,QRH),
8975 ai_observation_memoed_propagation_rest_heads(C,O,QRH)
8981 ai_observation_memo_propagation_rest_heads(_,_,_) <=> fail.
8983 depends_on_ap(CP,CPP,CPD,Delete), final_answer_pattern(CPD,APD) ==>
8984 final_answer_pattern(CP,APD).
8985 depends_on_ap(CP,CPP,CPD,Delete), final_answer_pattern(CPP,APP),
8986 final_answer_pattern(CPD,APD) ==>
8988 CP = odom(occ(C,O),_),
8989 ( ai_observation_is_observed(APP,C) ->
8990 ai_observed_internal(C,O)
8992 ai_not_observed_internal(C,O)
8995 APP = odom([],Set0),
8996 ord_del_element(Set0,C,Set),
9001 ai_observation_lub(NAPP,APD,AP),
9002 final_answer_pattern(CP,AP).
9004 %------------------------------------------------------------------------------%
9006 %------------------------------------------------------------------------------%
9008 call_pattern_worker(CP) <=> chr_error(internal,'AI observation analysis: unexpected abstract state ~w\n',[CP]).
9010 %------------------------------------------------------------------------------%
9011 % Auxiliary Predicates
9012 %------------------------------------------------------------------------------%
9014 ai_observation_lub(odom(AG,S1),odom(AG,S2),odom(AG,S3)) :-
9015 ord_intersection(S1,S2,S3).
9017 ai_observation_bot(AG,AS,odom(AG,AS)).
9019 ai_observation_top(AG,odom(AG,EmptyS)) :-
9022 ai_observation_leq(odom(AG,S1),odom(AG,S2)) :-
9025 ai_observation_observe_set(S,ACSet,NS) :-
9026 ord_subtract(S,ACSet,NS).
9028 ai_observation_abstract_constraint(C,ACs,AC) :-
9033 ai_observation_abstract_constraints(Cs,ACs,NACs) :-
9034 findall(NAC,(member(C,Cs),ai_observation_abstract_constraint(C,ACs,NAC)),NACs).
9036 %------------------------------------------------------------------------------%
9037 % Abstraction of Rule Bodies
9038 %------------------------------------------------------------------------------%
9041 ai_observation_memoed_abstract_goal/2,
9042 ai_observation_memo_abstract_goal/2.
9044 :- chr_option(mode,ai_observation_memoed_abstract_goal(+,+)).
9045 :- chr_option(mode,ai_observation_memo_abstract_goal(+,?)).
9047 ai_observation_memoed_abstract_goal(RuleNb,AG) # ID1 \ ai_observation_memo_abstract_goal(RuleNb,QAG)
9053 rule(RuleNb,Rule) # ID1, abstract_constraints(ACs) # ID2 \ ai_observation_memo_abstract_goal(RuleNb,QAG)
9055 Rule = pragma(rule(H1,H2,Guard,Body),_,_,_,_),
9056 ai_observation_abstract_goal_(H1,H2,Guard,Body,ACs,AG),
9058 ai_observation_memoed_abstract_goal(RuleNb,AG)
9063 ai_observation_abstract_goal_(H1,H2,Guard,G,ACs,AG) :-
9064 % also guard: e.g. b, c(X) ==> Y=X | p(Y).
9065 term_variables((H1,H2,Guard),HVars),
9066 append(H1,H2,Heads),
9067 % variables that are declared to be ground are safe,
9068 ground_vars(Heads,GroundVars),
9069 % so we remove them from the list of 'dangerous' head variables
9070 list_difference_eq(HVars,GroundVars,HV),
9071 ai_observation_abstract_goal(G,ACs,AG,[],HV),!.
9072 % writeln(ai_observation_abstract_goal(G,ACs,AG,[],HV)).
9073 % HV are 'dangerous' variables, all others are fresh and safe
9076 ground_vars([H|Hs],GroundVars) :-
9078 get_constraint_mode(F/A,Mode),
9079 head_info(H,A,_Vars,_Susp,_HeadVars,HeadPairs),
9080 head_arg_matches(HeadPairs,Mode,[],_FirstMatching,_VarDict1,[],GroundVars1),
9081 ground_vars(Hs,GroundVars2),
9082 append(GroundVars1,GroundVars2,GroundVars).
9084 ai_observation_abstract_goal((G1,G2),ACs,List,Tail,HV) :- !, % conjunction
9085 ai_observation_abstract_goal(G1,ACs,List,IntermediateList,HV),
9086 ai_observation_abstract_goal(G2,ACs,IntermediateList,Tail,HV).
9087 ai_observation_abstract_goal((G1;G2),ACs,[(ABranch1;ABranch2)|Tail],Tail,HV) :- !, % disjunction
9088 ai_observation_abstract_goal(G1,ACs,ABranch1,[],HV),
9089 ai_observation_abstract_goal(G2,ACs,ABranch2,[],HV).
9090 ai_observation_abstract_goal((G1->G2),ACs,List,Tail,HV) :- !, % if-then
9091 ai_observation_abstract_goal(G1,ACs,List,IntermediateList,HV),
9092 ai_observation_abstract_goal(G2,ACs,IntermediateList,Tail,HV).
9093 ai_observation_abstract_goal(C,ACs,[AC|Tail],Tail,HV) :-
9094 ai_observation_abstract_constraint(C,ACs,AC), !. % CHR constraint
9095 ai_observation_abstract_goal(true,_,Tail,Tail,_) :- !.
9096 ai_observation_abstract_goal(writeln(_),_,Tail,Tail,_) :- !.
9097 % non-CHR constraint is safe if it only binds fresh variables
9098 ai_observation_abstract_goal(G,_,Tail,Tail,HV) :-
9099 builtin_binds_b(G,Vars),
9100 intersect_eq(Vars,HV,[]),
9102 ai_observation_abstract_goal(G,_,[AG|Tail],Tail,_) :-
9103 AG = builtin. % default case if goal is not recognized/safe
9105 ai_observation_is_observed(odom(_,ACSet),AC) :-
9106 \+ ord_memberchk(AC,ACSet).
9108 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9109 unconditional_occurrence(C,O) :-
9110 get_occurrence(C,O,RuleNb,ID),
9111 get_rule(RuleNb,PRule),
9112 PRule = pragma(ORule,_,_,_,_),
9113 copy_term_nat(ORule,Rule),
9114 Rule = rule(H1,H2,Guard,_),
9115 % writeq(guard_entailment:entails_guard([chr_pp_headvariables(H1,H2)],Guard)),nl,
9116 guard_entailment:entails_guard([chr_pp_headvariables(H1,H2)],Guard),
9118 H1 = [Head], H2 == []
9120 H2 = [Head], H1 == [], \+ may_trigger(C)
9124 unconditional_occurrence_args(Args).
9126 unconditional_occurrence_args([]).
9127 unconditional_occurrence_args([X|Xs]) :-
9130 unconditional_occurrence_args(Xs).
9132 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9134 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9135 % Partial wake analysis
9137 % In a Var = Var unification do not wake up constraints of both variables,
9138 % but rather only those of one variable.
9139 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9141 :- chr_constraint partial_wake_analysis/0.
9142 :- chr_constraint no_partial_wake/1.
9143 :- chr_option(mode,no_partial_wake(+)).
9144 :- chr_constraint wakes_partially/1.
9145 :- chr_option(mode,wakes_partially(+)).
9147 partial_wake_analysis, occurrence(FA,O,RuleNb,ID,Type), rule(RuleNb,Rule), constraint_mode(FA,ArgModes)
9149 Rule = pragma(rule(H1,H2,Guard,Body),_,_,_,_),
9150 ( is_passive(RuleNb,ID) ->
9152 ; Type == simplification ->
9153 select(H,H1,RestH1),
9155 term_variables(Guard,Vars),
9156 partial_wake_args(Args,ArgModes,Vars,FA)
9157 ; % Type == propagation ->
9158 select(H,H2,RestH2),
9160 term_variables(Guard,Vars),
9161 partial_wake_args(Args,ArgModes,Vars,FA)
9164 partial_wake_args([],_,_,_).
9165 partial_wake_args([Arg|Args],[Mode|Modes],Vars,C) :-
9169 ; memberchk_eq(Arg,Vars) ->
9177 partial_wake_args(Args,Modes,Vars,C).
9179 no_partial_wake(C) \ no_partial_wake(C) <=> true.
9181 no_partial_wake(C) \ wakes_partially(C) <=> fail.
9183 wakes_partially(C) <=> true.
9186 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9187 % Generate rules that implement chr_show_store/1 functionality.
9193 % Generates additional rules:
9195 % $show, C1 # ID ==> writeln(C1) pragma passive(ID).
9197 % $show, Cn # ID ==> writeln(Cn) pragma passive(ID).
9200 generate_show_constraint(Constraints0,Constraints,Rules0,Rules) :-
9201 ( chr_pp_flag(show,on) ->
9202 Constraints = ['$show'/0|Constraints0],
9203 generate_show_rules(Constraints0,Rules,[Rule|Rules0]),
9204 inc_rule_count(RuleNb),
9206 rule(['$show'],[],true,true),
9213 Constraints = Constraints0,
9217 generate_show_rules([],Rules,Rules).
9218 generate_show_rules([F/A|Rest],[Rule|Tail],Rules) :-
9220 inc_rule_count(RuleNb),
9222 rule([],['$show',C],true,writeln(C)),
9228 generate_show_rules(Rest,Tail,Rules).
9230 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9231 % Custom supension term layout
9233 static_suspension_term(F/A,Suspension) :-
9234 suspension_term_base(F/A,Base),
9236 functor(Suspension,suspension,Arity).
9238 has_suspension_field(FA,Field) :-
9239 suspension_term_base_fields(FA,Fields),
9240 memberchk(Field,Fields).
9242 suspension_term_base(FA,Base) :-
9243 suspension_term_base_fields(FA,Fields),
9244 length(Fields,Base).
9246 suspension_term_base_fields(FA,Fields) :-
9247 ( chr_pp_flag(debugable,on) ->
9250 % 3. Propagation History
9251 % 4. Generation Number
9252 % 5. Continuation Goal
9254 Fields = [id,state,history,generation,continuation,functor]
9256 ( uses_history(FA) ->
9257 Fields = [id,state,history|Fields2]
9258 ; only_ground_indexed_arguments(FA), get_functional_dependency(FA,1,_,_) ->
9259 Fields = [state|Fields2]
9261 Fields = [id,state|Fields2]
9263 ( only_ground_indexed_arguments(FA) ->
9264 get_store_type(FA,StoreType),
9265 basic_store_types(StoreType,BasicStoreTypes),
9266 ( memberchk(global_ground,BasicStoreTypes) ->
9269 % 3. Propagation History
9270 % 4. Global List Prev
9271 Fields2 = [global_list_prev|Fields3]
9275 % 3. Propagation History
9278 ( chr_pp_flag(ht_removal,on)
9279 -> ht_prev_fields(BasicStoreTypes,Fields3)
9282 ; may_trigger(FA) ->
9285 % 3. Propagation History
9286 ( uses_field(FA,generation) ->
9287 % 4. Generation Number
9288 % 5. Global List Prev
9289 Fields2 = [generation,global_list_prev|Fields3]
9291 Fields2 = [global_list_prev|Fields3]
9293 ( chr_pp_flag(mixed_stores,on),
9294 chr_pp_flag(ht_removal,on)
9295 -> get_store_type(FA,StoreType),
9296 basic_store_types(StoreType,BasicStoreTypes),
9297 ht_prev_fields(BasicStoreTypes,Fields3)
9303 % 3. Propagation History
9304 % 4. Global List Prev
9305 Fields2 = [global_list_prev|Fields3],
9306 ( chr_pp_flag(mixed_stores,on),
9307 chr_pp_flag(ht_removal,on)
9308 -> get_store_type(FA,StoreType),
9309 basic_store_types(StoreType,BasicStoreTypes),
9310 ht_prev_fields(BasicStoreTypes,Fields3)
9316 ht_prev_fields(Stores,Prevs) :-
9317 ht_prev_fields_int(Stores,PrevsList),
9318 append(PrevsList,Prevs).
9319 ht_prev_fields_int([],[]).
9320 ht_prev_fields_int([H|T],Fields) :-
9321 ( H = multi_hash(Indexes)
9322 -> maplist(ht_prev_field,Indexes,FH),
9326 ht_prev_fields_int(T,FT).
9328 ht_prev_field(Index,Field) :-
9330 -> atom_concat('multi_hash_prev-',Index,Field)
9332 -> concat_atom(['multi_hash_prev-'|Index],Field)
9335 get_static_suspension_term_field(FieldName,FA,StaticSuspension,Field) :-
9336 suspension_term_base_fields(FA,Fields),
9337 nth(Index,Fields,FieldName), !,
9338 arg(Index,StaticSuspension,Field).
9339 get_static_suspension_term_field(arguments,FA,StaticSuspension,Field) :- !,
9340 suspension_term_base(FA,Base),
9341 StaticSuspension =.. [_|Args],
9342 drop(Base,Args,Field).
9343 get_static_suspension_term_field(FieldName,FA,_StaticSuspension,_Field) :-
9344 chr_error(internal,'Trying to obtain field ~w of ~w, wich does not have it!',[FieldName,FA]).
9347 get_dynamic_suspension_term_field(FieldName,FA,DynamicSuspension,Field,Goal) :-
9348 suspension_term_base_fields(FA,Fields),
9349 nth(Index,Fields,FieldName), !,
9350 Goal = arg(Index,DynamicSuspension,Field).
9351 get_dynamic_suspension_term_field(arguments,FA,DynamicSuspension,Field,Goal) :- !,
9352 static_suspension_term(FA,StaticSuspension),
9353 get_static_suspension_term_field(arguments,FA,StaticSuspension,Field),
9354 Goal = (DynamicSuspension = StaticSuspension).
9355 get_dynamic_suspension_term_field(argument(I),FA,DynamicSuspension,Field,Goal) :- !,
9356 suspension_term_base(FA,Base),
9358 Goal = arg(Index,DynamicSuspension,Field).
9359 get_dynamic_suspension_term_field(FieldName,FA,_DynamicSuspension,_Field,_Goal) :-
9360 chr_error(internal,'Dynamic goal to get ~w of ~w, which does not have this field!',[FieldName,FA]).
9363 set_dynamic_suspension_term_field(FieldName,FA,DynamicSuspension,Field,Goal) :-
9364 suspension_term_base_fields(FA,Fields),
9365 nth(Index,Fields,FieldName), !,
9366 Goal = setarg(Index,DynamicSuspension,Field).
9367 set_dynamic_suspension_term_field(FieldName,FA,_DynamicSuspension,_Field,_Goal) :-
9368 chr_error(internal,'Dynamic goal to set ~w of ~w, which does not have this field!',[FieldName,FA]).
9370 basic_store_types(multi_store(Types),Types) :- !.
9371 basic_store_types(Type,[Type]).
9373 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9380 :- chr_option(mode,phase_end(+)).
9381 :- chr_option(mode,delay_phase_end(+,?)).
9383 phase_end(Phase) \ delay_phase_end(Phase,Goal) <=> call(Goal).
9384 % phase_end(Phase) <=> true.
9387 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9391 novel_production_call/4.
9393 :- chr_option(mode,uses_history(+)).
9394 :- chr_option(mode,does_use_history(+,+)).
9395 :- chr_option(mode,novel_production_call(+,+,?,?)).
9397 does_use_history(FA,Occ) \ does_use_history(FA,Occ) <=> true.
9398 does_use_history(FA,_) \ uses_history(FA) <=> true.
9399 uses_history(_FA) <=> fail.
9401 does_use_history(FA,Occ) \ novel_production_call(FA,Occ,PossibleGoal,Goal) <=> Goal = PossibleGoal.
9402 novel_production_call(FA,_,_PossibleGoal,Goal) <=> Goal = true.
9408 :- chr_option(mode,uses_field(+,+)).
9409 :- chr_option(mode,does_use_field(+,+)).
9411 does_use_field(FA,Field) \ does_use_field(FA,Field) <=> true.
9412 does_use_field(FA,Field) \ uses_field(FA,Field) <=> true.
9413 uses_field(_FA,_Field) <=> fail.
9418 used_states_known/0.
9420 :- chr_option(mode,uses_state(+,+)).
9421 :- chr_option(mode,if_used_state(+,+,?,?,?)).
9424 % states ::= not_stored_yet | passive | active | triggered | removed
9426 % allocate CREATES not_stored_yet
9427 % remove CHECKS not_stored_yet
9428 % activate CHECKS not_stored_yet
9430 % ==> no allocate THEN no not_stored_yet
9432 % recurs CREATES inactive
9433 % lookup CHECKS inactive
9435 % insert CREATES active
9436 % activate CREATES active
9437 % lookup CHECKS active
9438 % recurs CHECKS active
9440 % runsusp CREATES triggered
9441 % lookup CHECKS triggered
9443 % ==> no runsusp THEN no triggered
9445 % remove CREATES removed
9446 % runsusp CHECKS removed
9447 % lookup CHECKS removed
9448 % recurs CHECKS removed
9450 % ==> no remove THEN no removed
9452 % ==> no allocate, no remove, no active/inactive distinction THEN no state at all...
9454 uses_state(Constraint,State) \ uses_state(Constraint,State) <=> true.
9456 used_states_known, uses_state(Constraint,State) \ if_used_state(Constraint,State,Used,NotUsed,ResultGoal)
9457 <=> ResultGoal = Used.
9458 used_states_known \ if_used_state(Constraint,State,Used,NotUsed,ResultGoal)
9459 <=> ResultGoal = NotUsed.
9461 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9462 % Check storedness annotations.
9466 :- chr_constraint stored_assertion/1.
9467 :- chr_option(mode,stored_assertion(+)).
9468 :- chr_option(type_declaration,stored_assertion(constraint)).
9470 :- chr_constraint never_stored_default/2.
9471 :- chr_option(mode,never_stored_default(+,?)).
9472 :- chr_option(type_declaration,never_stored_default(constraint,any)).
9474 generate_never_stored_rules(Constraints,Rules) :-
9475 ( chr_pp_flag(declare_stored_constraints,on) ->
9476 never_stored_rules(Constraints,Rules)
9481 :- chr_constraint never_stored_rules/2.
9482 :- chr_option(mode,never_stored_rules(+,?)).
9483 :- chr_option(type_declaration,never_stored_rules(list(constraint),any)).
9485 never_stored_rules([],Rules) <=> Rules = [].
9486 never_stored_default(Constraint,Goal) \ never_stored_rules([Constraint|Constraints],Rules) <=>
9489 inc_rule_count(RuleNb),
9491 rule([Head],[],true,Goal),
9497 Rules = [Rule|Tail],
9498 never_stored_rules(Constraints,Tail).
9499 never_stored_rules([_|Constraints],Rules) <=>
9500 never_stored_rules(Constraints,Rules).
9502 check_storedness_assertions(Constraints) :-
9503 ( chr_pp_flag(declare_stored_constraints,on) ->
9504 forall(Constraint,Constraints,check_storedness_assertion(Constraint))
9510 :- chr_constraint check_storedness_assertion/1.
9511 :- chr_option(mode,check_storedness_assertion(+)).
9512 :- chr_option(type_declaration,check_storedness_assertion(constraint)).
9514 check_storedness_assertion(Constraint), stored_assertion(Constraint)
9515 <=> ( is_stored(Constraint) ->
9518 chr_warning(assertion_failed,'Constraint ~w is not stored. However, it was asserted to be stored.\n',[Constraint])
9520 never_stored_default(Constraint,_) \ check_storedness_assertion(Constraint)
9521 <=> ( is_finally_stored(Constraint) ->
9522 chr_warning(assertion_failed,'Constraint ~w is stored. However, it was asserted not to be stored.\n',[Constraint])
9523 ; is_stored(Constraint) ->
9524 chr_warning(assertion_failed,'Constraint ~w is temporarily stored. However, it was asserted not to be stored.\n',[Constraint])
9528 % never-stored, no default goal
9529 check_storedness_assertion(Constraint)
9530 <=> ( is_finally_stored(Constraint) ->
9531 chr_warning(assertion_failed,'Constraint ~w is stored. However, it was asserted not to be stored.\n',[Constraint])
9532 ; is_stored(Constraint) ->
9533 chr_warning(assertion_failed,'Constraint ~w is temporarily stored. However, it was asserted not to be stored.\n',[Constraint])