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 %% * analyze history usage to determine whether/when
64 %% cheaper suspension is possible:
65 %% don't use history when all partners are passive and self never triggers
66 %% * store constraint unconditionally for unconditional propagation rule,
67 %% if first, i.e. without checking history and set trigger cont to next occ
68 %% * get rid of suspension passing for never triggered constraints,
69 %% up to allocation occurrence
70 %% * get rid of call indirection for never triggered constraints
71 %% up to first allocation occurrence.
72 %% * get rid of unnecessary indirection if last active occurrence
73 %% before unconditional removal is head2, e.g.
76 %% * Eliminate last clause of never stored constraint, if its body
80 %% * Specialize lookup operations and indexes for functional dependencies.
84 %% * map A \ B <=> true | true rules
85 %% onto efficient code that empties the constraint stores of B
86 %% in O(1) time for ground constraints where A and B do not share
88 %% * ground matching seems to be not optimized for compound terms
89 %% in case of simpagation_head2 and propagation occurrences
90 %% * analysis for storage delaying (see primes for case)
91 %% * internal constraints declaration + analyses?
92 %% * Do not store in global variable store if not necessary
93 %% NOTE: affects show_store/1
94 %% * var_assoc multi-level store: variable - ground
95 %% * Do not maintain/check unnecessary propagation history
96 %% for reasons of anti-monotony
97 %% * Strengthen storage analysis for propagation rules
98 %% reason about bodies of rules only containing constraints
99 %% -> fixpoint with observation analysis
100 %% * instantiation declarations
101 %% COMPOUND (bound to nonvar)
102 %% avoid nonvar tests
104 %% * make difference between cheap guards for reordering
105 %% and non-binding guards for lock removal
106 %% * fd -> once/[] transformation for propagation
107 %% * cheap guards interleaved with head retrieval + faster
108 %% via-retrieval + non-empty checking for propagation rules
109 %% redo for simpagation_head2 prelude
110 %% * intelligent backtracking for simplification/simpagation rule
111 %% generator_1(X),'_$savecp'(CP_1),
118 %% ('_$cutto'(CP_1), fail)
122 %% or recently developped cascading-supported approach
123 %% * intelligent backtracking for propagation rule
124 %% use additional boolean argument for each possible smart backtracking
125 %% when boolean at end of list true -> no smart backtracking
126 %% false -> smart backtracking
127 %% only works for rules with at least 3 constraints in the head
128 %% * (set semantics + functional dependency) declaration + resolution
130 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
131 :- module(chr_translate,
132 [ chr_translate/2 % +Decls, -TranslatedDecls
133 , chr_translate_line_info/3 % +DeclsWithLines, -TranslatedDecls
136 :- use_module(library(lists),[member/2, append/3,reverse/2,permutation/2,last/2]).
137 :- use_module(library(ordsets)).
138 :- use_module(library(aggregate)).
139 :- use_module(library(apply_macros)).
140 :- use_module(library(occurs)).
141 :- use_module(library(assoc)).
144 % imports and operators {{{
145 :- use_module(hprolog).
146 :- use_module(pairlist).
147 :- use_module(a_star).
148 :- use_module(listmap).
149 :- use_module(clean_code).
150 :- use_module(builtins).
152 :- use_module(binomialheap).
153 :- use_module(guard_entailment).
154 :- use_module(chr_compiler_options).
155 :- use_module(chr_compiler_utility).
156 :- use_module(chr_compiler_errors).
158 :- op(1150, fx, chr_type).
159 :- op(1130, xfx, --->).
163 :- op(1150, fx, constraints).
164 :- op(1150, fx, chr_constraint).
167 :- chr_option(debug,off).
168 :- chr_option(optimize,full).
169 :- chr_option(check_guard_bindings,off).
171 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
172 % Type Declarations {{{
173 :- chr_type list(T) ---> [] ; [T|list(T)].
175 :- chr_type list == list(any).
177 :- chr_type mode ---> (+) ; (-) ; (?).
179 :- chr_type maybe(T) ---> yes(T) ; no.
181 :- chr_type constraint ---> any / any.
183 :- chr_type module_name == any.
185 :- chr_type pragma_rule ---> pragma(rule,idspair,list(pragma_type),maybe(rule_name),rule_nb).
186 :- chr_type rule ---> rule(list(any),list(any),goal,goal).
187 :- chr_type idspair ---> ids(list(id),list(id)).
189 :- chr_type pragma_type ---> passive(id)
192 ; already_in_heads(id)
194 ; history(history_name,list(id)).
195 :- chr_type history_name== any.
197 :- chr_type rule_name == any.
198 :- chr_type rule_nb == natural.
199 :- chr_type id == natural.
200 :- chr_type occurrence == int.
202 :- chr_type goal == any.
204 :- chr_type store_type ---> default
205 ; multi_store(list(store_type))
206 ; multi_hash(list(list(int)))
207 ; multi_inthash(list(list(int)))
210 % EXPERIMENTAL STORES
211 ; atomic_constants(list(int),list(any),coverage)
212 ; ground_constants(list(int),list(any),coverage)
213 ; var_assoc_store(int,list(int))
214 ; identifier_store(int)
215 ; type_indexed_identifier_store(int,any).
216 :- chr_type coverage ---> complete ; incomplete.
218 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
220 %------------------------------------------------------------------------------%
221 :- chr_constraint chr_source_file/1.
222 :- chr_option(mode,chr_source_file(+)).
223 :- chr_option(type_declaration,chr_source_file(module_name)).
224 %------------------------------------------------------------------------------%
225 chr_source_file(_) \ chr_source_file(_) <=> true.
227 %------------------------------------------------------------------------------%
228 :- chr_constraint get_chr_source_file/1.
229 :- chr_option(mode,get_chr_source_file(-)).
230 :- chr_option(type_declaration,get_chr_source_file(module_name)).
231 %------------------------------------------------------------------------------%
232 chr_source_file(Mod) \ get_chr_source_file(Query)
234 get_chr_source_file(Query)
238 %------------------------------------------------------------------------------%
239 :- chr_constraint target_module/1.
240 :- chr_option(mode,target_module(+)).
241 :- chr_option(type_declaration,target_module(module_name)).
242 %------------------------------------------------------------------------------%
243 target_module(_) \ target_module(_) <=> true.
245 %------------------------------------------------------------------------------%
246 :- chr_constraint get_target_module/1.
247 :- chr_option(mode,get_target_module(-)).
248 :- chr_option(type_declaration,get_target_module(module_name)).
249 %------------------------------------------------------------------------------%
250 target_module(Mod) \ get_target_module(Query)
252 get_target_module(Query)
255 %------------------------------------------------------------------------------%
256 :- chr_constraint line_number/2.
257 :- chr_option(mode,line_number(+,+)).
258 :- chr_option(type_declaration,line_number(rule_nb,int)).
259 %------------------------------------------------------------------------------%
260 line_number(RuleNb,LineNb) \ line_number(RuleNb,LineNumber) <=> true.
262 %------------------------------------------------------------------------------%
263 :- chr_constraint get_line_number/2.
264 :- chr_option(mode,get_line_number(+,-)).
265 :- chr_option(type_declaration,get_line_number(rule_nb,int)).
266 %------------------------------------------------------------------------------%
267 line_number(RuleNb,LineNb) \ get_line_number(RuleNb,Q) <=> Q = LineNb.
268 get_line_number(RuleNb,Q) <=> Q = 0. % no line number available
270 :- chr_constraint indexed_argument/2. % argument instantiation may enable applicability of rule
271 :- chr_option(mode,indexed_argument(+,+)).
272 :- chr_option(type_declaration,indexed_argument(constraint,int)).
274 :- chr_constraint is_indexed_argument/2.
275 :- chr_option(mode,is_indexed_argument(+,+)).
276 :- chr_option(type_declaration,is_indexed_argument(constraint,int)).
278 :- chr_constraint constraint_mode/2.
279 :- chr_option(mode,constraint_mode(+,+)).
280 :- chr_option(type_declaration,constraint_mode(constraint,list(mode))).
282 :- chr_constraint get_constraint_mode/2.
283 :- chr_option(mode,get_constraint_mode(+,-)).
284 :- chr_option(type_declaration,get_constraint_mode(constraint,list(mode))).
286 :- chr_constraint may_trigger/1.
287 :- chr_option(mode,may_trigger(+)).
288 :- chr_option(type_declaration,may_trigger(constraint)).
290 :- chr_constraint only_ground_indexed_arguments/1.
291 :- chr_option(mode,only_ground_indexed_arguments(+)).
292 :- chr_option(type_declaration,only_ground_indexed_arguments(constraint)).
294 :- chr_constraint none_suspended_on_variables/0.
296 :- chr_constraint are_none_suspended_on_variables/0.
298 :- chr_constraint store_type/2.
299 :- chr_option(mode,store_type(+,+)).
300 :- chr_option(type_declaration,store_type(constraint,store_type)).
302 :- chr_constraint get_store_type/2.
303 :- chr_option(mode,get_store_type(+,?)).
304 :- chr_option(type_declaration,get_store_type(constraint,store_type)).
306 :- chr_constraint update_store_type/2.
307 :- chr_option(mode,update_store_type(+,+)).
308 :- chr_option(type_declaration,update_store_type(constraint,store_type)).
310 :- chr_constraint actual_store_types/2.
311 :- chr_option(mode,actual_store_types(+,+)).
312 :- chr_option(type_declaration,actual_store_types(constraint,list(store_type))).
314 :- chr_constraint assumed_store_type/2.
315 :- chr_option(mode,assumed_store_type(+,+)).
316 :- chr_option(type_declaration,assumed_store_type(constraint,store_type)).
318 :- chr_constraint validate_store_type_assumption/1.
319 :- chr_option(mode,validate_store_type_assumption(+)).
320 :- chr_option(type_declaration,validate_store_type_assumption(constraint)).
322 :- chr_constraint rule_count/1.
323 :- chr_option(mode,rule_count(+)).
324 :- chr_option(type_declaration,rule_count(natural)).
326 :- chr_constraint inc_rule_count/1.
327 :- chr_option(mode,inc_rule_count(-)).
328 :- chr_option(type_declaration,inc_rule_count(natural)).
330 rule_count(_) \ rule_count(_)
332 rule_count(C), inc_rule_count(NC)
333 <=> NC is C + 1, rule_count(NC).
335 <=> NC = 1, rule_count(NC).
337 :- chr_constraint passive/2.
338 :- chr_option(mode,passive(+,+)).
340 :- chr_constraint is_passive/2.
341 :- chr_option(mode,is_passive(+,+)).
343 :- chr_constraint any_passive_head/1.
344 :- chr_option(mode,any_passive_head(+)).
346 :- chr_constraint new_occurrence/4.
347 :- chr_option(mode,new_occurrence(+,+,+,+)).
349 :- chr_constraint occurrence/5.
350 :- chr_option(mode,occurrence(+,+,+,+,+)).
351 :- chr_type occurrence_type ---> simplification ; propagation.
352 :- chr_option(type_declaration,occurrence(constraint,occurrence,rule_nb,id,occurrence_type)).
354 :- chr_constraint get_occurrence/4.
355 :- chr_option(mode,get_occurrence(+,+,-,-)).
357 :- chr_constraint get_occurrence_from_id/4.
358 :- chr_option(mode,get_occurrence_from_id(+,-,+,+)).
360 :- chr_constraint max_occurrence/2.
361 :- chr_option(mode,max_occurrence(+,+)).
363 :- chr_constraint get_max_occurrence/2.
364 :- chr_option(mode,get_max_occurrence(+,-)).
366 :- chr_constraint allocation_occurrence/2.
367 :- chr_option(mode,allocation_occurrence(+,+)).
369 :- chr_constraint get_allocation_occurrence/2.
370 :- chr_option(mode,get_allocation_occurrence(+,-)).
372 :- chr_constraint rule/2.
373 :- chr_option(mode,rule(+,+)).
374 :- chr_option(type_declaration,rule(rule_nb,pragma_rule)).
376 :- chr_constraint get_rule/2.
377 :- chr_option(mode,get_rule(+,-)).
378 :- chr_option(type_declaration,get_rule(int,pragma_rule)).
380 :- chr_constraint least_occurrence/2.
381 :- chr_option(mode,least_occurrence(+,+)).
382 :- chr_option(type_declaration,least_occurrence(any,list)).
384 :- chr_constraint is_least_occurrence/1.
385 :- chr_option(mode,is_least_occurrence(+)).
388 indexed_argument(FA,I) \ indexed_argument(FA,I) <=> true.
389 indexed_argument(FA,I) \ is_indexed_argument(FA,I) <=> true.
390 is_indexed_argument(_,_) <=> fail.
392 %%% C O N S T R A I N T M O D E %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
394 constraint_mode(FA,_) \ constraint_mode(FA,_) <=> true.
395 constraint_mode(FA,Mode) \ get_constraint_mode(FA,Q) <=>
397 get_constraint_mode(FA,Q) <=>
401 %%% M A Y T R I G G E R %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
403 may_trigger(FA) <=> \+ has_active_occurrence(FA) | fail.
404 constraint_mode(FA,Mode), indexed_argument(FA,I) \ may_trigger(FA) <=>
408 may_trigger(FA) <=> chr_pp_flag(debugable,on). % in debug mode, we assume everything can be triggered
410 constraint_mode(FA,Mode), indexed_argument(FA,I) \ only_ground_indexed_arguments(FA)
416 only_ground_indexed_arguments(_) <=>
419 none_suspended_on_variables \ none_suspended_on_variables <=> true.
420 none_suspended_on_variables \ are_none_suspended_on_variables <=> true.
421 are_none_suspended_on_variables <=> fail.
422 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
425 % The functionality for inspecting and deciding on the different types of constraint
426 % store / indexes for constraints.
428 store_type(FA,StoreType)
429 ==> chr_pp_flag(verbose,on)
431 format('The indexes for ~w are:\n',[FA]),
432 format_storetype(StoreType).
433 % chr_info(verbose,'Storetype of ~w is ~w.\n',[FA,StoreType]).
435 format_storetype(multi_store(StoreTypes)) :- !,
436 maplist(format_storetype,StoreTypes).
437 format_storetype(atomic_constants(Index,Constants,_)) :-
438 format('\t* a trie index on the argument(s) ~w for the ground terms ~w\n',[Index,Constants]).
439 format_storetype(ground_constants(Index,Constants,_)) :-
440 format('\t* a trie index on the argument(s) ~w for the ground terms ~w\n',[Index,Constants]).
441 format_storetype(StoreType) :-
442 format('\t* ~w\n',[StoreType]).
450 get_store_type_normal @
451 store_type(FA,Store) \ get_store_type(FA,Query)
454 get_store_type_assumed @
455 assumed_store_type(FA,Store) \ get_store_type(FA,Query)
458 get_store_type_default @
459 get_store_type(_,Query)
462 % 2. Store type registration
463 % ~~~~~~~~~~~~~~~~~~~~~~~~~~
465 actual_store_types(C,STs) \ update_store_type(C,ST)
466 <=> memberchk(ST,STs) | true.
467 update_store_type(C,ST), actual_store_types(C,STs)
469 actual_store_types(C,[ST|STs]).
470 update_store_type(C,ST)
472 actual_store_types(C,[ST]).
474 % 3. Final decision on store types
475 % ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
477 validate_store_type_assumption(C) \ actual_store_types(C,STs), actual_atomic_multi_hash_keys(C,Index,Keys)
479 true % chr_pp_flag(experiment,on)
481 delete(STs,multi_hash([Index]),STs0),
483 ( get_constraint_arg_type(C,IndexPos,Type),
484 enumerated_atomic_type(Type,Atoms) ->
485 /* use the type constants rather than the collected keys */
487 Completeness = complete
490 Completeness = incomplete
492 actual_store_types(C,[atomic_constants(Index,Constants,Completeness)|STs0]).
493 validate_store_type_assumption(C) \ actual_store_types(C,STs), actual_ground_multi_hash_keys(C,Index,Constants0)
495 true % chr_pp_flag(experiment,on)
497 ( Index = [IndexPos],
498 get_constraint_arg_type(C,IndexPos,Type),
499 ( Type = chr_constants(Key) -> get_chr_constants(Key,Constants)
500 ; Type = chr_enum(Constants) -> true
503 Completeness = complete
505 Constants = Constants0,
506 Completeness = incomplete
508 delete(STs,multi_hash([Index]),STs0),
509 actual_store_types(C,[ground_constants(Index,Constants,Completeness)|STs0]).
511 get_constraint_arg_type(C,Pos,Type) :-
512 get_constraint_type(C,Types),
513 nth1(Pos,Types,Type0),
514 unalias_type(Type0,Type).
516 validate_store_type_assumption(C) \ actual_store_types(C,STs)
518 % chr_pp_flag(experiment,on),
519 memberchk(multi_hash([[Index]]),STs),
520 get_constraint_type(C,Types),
521 nth1(Index,Types,Type),
522 enumerated_atomic_type(Type,Atoms)
524 delete(STs,multi_hash([[Index]]),STs0),
525 actual_store_types(C,[atomic_constants([Index],Atoms,complete)|STs0]).
526 validate_store_type_assumption(C) \ actual_store_types(C,STs)
528 memberchk(multi_hash([[Index]]),STs),
529 get_constraint_arg_type(C,Index,Type),
530 ( Type = chr_enum(Constants) -> true
531 ; Type = chr_constants(Key) -> get_chr_constants(Key,Constants)
534 delete(STs,multi_hash([[Index]]),STs0),
535 actual_store_types(C,[ground_constants([Index],Constants,complete)|STs0]).
536 validate_store_type_assumption(C), actual_store_types(C,STs), assumed_store_type(C,_) % automatic assumption
538 ( /* chr_pp_flag(experiment,on), */ maplist(partial_store,STs) ->
539 Stores = [global_ground|STs]
543 store_type(C,multi_store(Stores)).
544 validate_store_type_assumption(C), actual_store_types(C,STs), store_type(C,_) % user assumption
546 store_type(C,multi_store(STs)).
547 validate_store_type_assumption(C), assumed_store_type(C,_) % no lookups on constraint in debug mode
549 chr_pp_flag(debugable,on)
551 store_type(C,default).
552 validate_store_type_assumption(C), assumed_store_type(C,_) % no lookups on constraint
553 <=> store_type(C,global_ground).
554 validate_store_type_assumption(C)
557 partial_store(ground_constants(_,_,incomplete)).
558 partial_store(atomic_constants(_,_,incomplete)).
560 %%% P A S S I V E %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
561 passive(R,ID) \ passive(R,ID) <=> true.
563 passive(RuleNb,ID) \ is_passive(RuleNb,ID) <=> true.
564 is_passive(_,_) <=> fail.
566 passive(RuleNb,_) \ any_passive_head(RuleNb)
570 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
572 max_occurrence(C,N) \ max_occurrence(C,M)
575 max_occurrence(C,MO), new_occurrence(C,RuleNb,ID,Type) <=>
577 occurrence(C,NO,RuleNb,ID,Type),
578 max_occurrence(C,NO).
579 new_occurrence(C,RuleNb,ID,_) <=>
580 chr_error(internal,'new_occurrence: missing max_occurrence for ~w in rule ~w\n',[C,RuleNb]).
582 max_occurrence(C,MON) \ get_max_occurrence(C,Q)
584 get_max_occurrence(C,Q)
585 <=> chr_error(internal,'get_max_occurrence: missing max occurrence for ~w\n',[C]).
587 occurrence(C,ON,Rule,ID,_) \ get_occurrence(C,ON,QRule,QID)
588 <=> Rule = QRule, ID = QID.
589 get_occurrence(C,O,_,_)
590 <=> chr_error(internal,'get_occurrence: missing occurrence ~w:~w\n',[C,O]).
592 occurrence(C,ON,Rule,ID,_) \ get_occurrence_from_id(QC,QON,Rule,ID)
593 <=> QC = C, QON = ON.
594 get_occurrence_from_id(C,O,_,_)
595 <=> chr_error(internal,'get_occurrence_from_id: missing occurrence ~w:~w\n',[]).
597 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
600 late_allocation_analysis(Cs) :-
601 ( chr_pp_flag(late_allocation,on) ->
602 maplist(late_allocation, Cs)
607 late_allocation(C) :- late_allocation(C,0).
608 late_allocation(C,O) :- allocation_occurrence(C,O), !.
609 late_allocation(C,O) :- NO is O + 1, late_allocation(C,NO).
611 % A L L O C C A T I O N O C C U R R E N C E %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
613 allocation_occurrence(C,0) ==> stored_in_guard_before_next_kept_occurrence(C,0).
615 rule(RuleNb,Rule), occurrence(C,O,RuleNb,Id,Type), allocation_occurrence(C,O) ==>
616 \+ is_passive(RuleNb,Id),
618 ( stored_in_guard_before_next_kept_occurrence(C,O) ->
620 ; Rule = pragma(rule([_|_],_,_,_),_,_,_,_) -> % simpagation rule
622 ; is_least_occurrence(RuleNb) -> % propagation rule
628 stored_in_guard_before_next_kept_occurrence(C,O) :-
629 chr_pp_flag(store_in_guards, on),
631 stored_in_guard_lookahead(C,NO).
633 :- chr_constraint stored_in_guard_lookahead/2.
634 :- chr_option(mode, stored_in_guard_lookahead(+,+)).
636 occurrence(C,O,RuleNb,Id,_), passive(RuleNb,Id) \ stored_in_guard_lookahead(C,O) <=>
637 NO is O + 1, stored_in_guard_lookahead(C,NO).
638 occurrence(C,O,RuleNb,Id,Type) \ stored_in_guard_lookahead(C,O) <=>
639 Type == simplification,
640 ( is_stored_in_guard(C,RuleNb) ->
643 NO is O + 1, stored_in_guard_lookahead(C,NO)
645 stored_in_guard_lookahead(_,_) <=> fail.
648 rule(RuleNb,Rule), occurrence(C,O,RuleNb,ID,_), allocation_occurrence(C,AO)
649 \ least_occurrence(RuleNb,[ID|IDs])
650 <=> AO >= O, \+ may_trigger(C) |
651 least_occurrence(RuleNb,IDs).
652 rule(RuleNb,Rule), passive(RuleNb,ID)
653 \ least_occurrence(RuleNb,[ID|IDs])
654 <=> least_occurrence(RuleNb,IDs).
657 ==> Rule = pragma(rule([],_,_,_),ids([],IDs),_,_,_) |
658 least_occurrence(RuleNb,IDs).
660 least_occurrence(RuleNb,[]) \ is_least_occurrence(RuleNb)
662 is_least_occurrence(_)
665 allocation_occurrence(C,O) \ get_allocation_occurrence(C,Q)
667 get_allocation_occurrence(_,Q)
668 <=> chr_pp_flag(late_allocation,off), Q=0.
669 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
671 rule(RuleNb,Rule) \ get_rule(RuleNb,Q)
676 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
678 %%% C O N S T R A I N T I N D E X %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
680 % Default store constraint index assignment.
682 :- chr_constraint constraint_index/2. % constraint_index(F/A,DefaultStoreAndAttachedIndex)
683 :- chr_option(mode,constraint_index(+,+)).
684 :- chr_option(type_declaration,constraint_index(constraint,int)).
686 :- chr_constraint get_constraint_index/2.
687 :- chr_option(mode,get_constraint_index(+,-)).
688 :- chr_option(type_declaration,get_constraint_index(constraint,int)).
690 :- chr_constraint get_indexed_constraint/2.
691 :- chr_option(mode,get_indexed_constraint(+,-)).
692 :- chr_option(type_declaration,get_indexed_constraint(int,constraint)).
694 :- chr_constraint max_constraint_index/1. % max_constraint_index(MaxDefaultStoreAndAttachedIndex)
695 :- chr_option(mode,max_constraint_index(+)).
696 :- chr_option(type_declaration,max_constraint_index(int)).
698 :- chr_constraint get_max_constraint_index/1.
699 :- chr_option(mode,get_max_constraint_index(-)).
700 :- chr_option(type_declaration,get_max_constraint_index(int)).
702 constraint_index(C,Index) \ get_constraint_index(C,Query)
704 get_constraint_index(C,Query)
707 constraint_index(C,Index) \ get_indexed_constraint(Index,Q)
709 get_indexed_constraint(Index,Q)
712 max_constraint_index(Index) \ get_max_constraint_index(Query)
714 get_max_constraint_index(Query)
717 set_constraint_indices(Constraints) :-
718 set_constraint_indices(Constraints,1).
719 set_constraint_indices([],M) :-
721 max_constraint_index(N).
722 set_constraint_indices([C|Cs],N) :-
723 ( ( chr_pp_flag(debugable, on) ; \+ only_ground_indexed_arguments(C), is_stored(C) ; is_stored(C), get_store_type(C,default)
724 ; get_store_type(C,var_assoc_store(_,_))) ->
725 constraint_index(C,N),
727 set_constraint_indices(Cs,M)
729 set_constraint_indices(Cs,N)
732 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
735 :- chr_constraint identifier_size/1.
736 :- chr_option(mode,identifier_size(+)).
737 :- chr_option(type_declaration,identifier_size(natural)).
739 identifier_size(_) \ identifier_size(_)
743 :- chr_constraint get_identifier_size/1.
744 :- chr_option(mode,get_identifier_size(-)).
745 :- chr_option(type_declaration,get_identifier_size(natural)).
747 identifier_size(Size) \ get_identifier_size(Q)
751 get_identifier_size(Q)
755 :- chr_constraint identifier_index/3.
756 :- chr_option(mode,identifier_index(+,+,+)).
757 :- chr_option(type_declaration,identifier_index(constraint,natural,natural)).
759 identifier_index(C,I,_) \ identifier_index(C,I,_)
763 :- chr_constraint get_identifier_index/3.
764 :- chr_option(mode,get_identifier_index(+,+,-)).
765 :- chr_option(type_declaration,get_identifier_index(constraint,natural,natural)).
767 identifier_index(C,I,II) \ get_identifier_index(C,I,Q)
770 identifier_size(Size), get_identifier_index(C,I,Q)
773 identifier_index(C,I,NSize),
774 identifier_size(NSize),
776 get_identifier_index(C,I,Q)
778 identifier_index(C,I,2),
782 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
783 % Type Indexed Identifier Indexes
785 :- chr_constraint type_indexed_identifier_size/2.
786 :- chr_option(mode,type_indexed_identifier_size(+,+)).
787 :- chr_option(type_declaration,type_indexed_identifier_size(any,natural)).
789 type_indexed_identifier_size(IndexType,_) \ type_indexed_identifier_size(IndexType,_)
793 :- chr_constraint get_type_indexed_identifier_size/2.
794 :- chr_option(mode,get_type_indexed_identifier_size(+,-)).
795 :- chr_option(type_declaration,get_type_indexed_identifier_size(any,natural)).
797 type_indexed_identifier_size(IndexType,Size) \ get_type_indexed_identifier_size(IndexType,Q)
801 get_type_indexed_identifier_size(IndexType,Q)
805 :- chr_constraint type_indexed_identifier_index/4.
806 :- chr_option(mode,type_indexed_identifier_index(+,+,+,+)).
807 :- chr_option(type_declaration,type_indexed_identifier_index(any,constraint,natural,natural)).
809 type_indexed_identifier_index(_,C,I,_) \ type_indexed_identifier_index(_,C,I,_)
813 :- chr_constraint get_type_indexed_identifier_index/4.
814 :- chr_option(mode,get_type_indexed_identifier_index(+,+,+,-)).
815 :- chr_option(type_declaration,get_type_indexed_identifier_index(any,constraint,natural,natural)).
817 type_indexed_identifier_index(IndexType,C,I,II) \ get_type_indexed_identifier_index(IndexType,C,I,Q)
820 type_indexed_identifier_size(IndexType,Size), get_type_indexed_identifier_index(IndexType,C,I,Q)
823 type_indexed_identifier_index(IndexType,C,I,NSize),
824 type_indexed_identifier_size(IndexType,NSize),
826 get_type_indexed_identifier_index(IndexType,C,I,Q)
828 type_indexed_identifier_index(IndexType,C,I,2),
829 type_indexed_identifier_size(IndexType,2),
832 type_indexed_identifier_structure(IndexType,Structure) :-
833 type_indexed_identifier_name(IndexType,type_indexed_identifier_struct,Functor),
834 get_type_indexed_identifier_size(IndexType,Arity),
835 functor(Structure,Functor,Arity).
836 type_indexed_identifier_name(IndexType,Prefix,Name) :-
838 IndexTypeName = IndexType
840 term_to_atom(IndexType,IndexTypeName)
842 atom_concat_list([Prefix,'_',IndexTypeName],Name).
844 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
849 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
853 chr_translate(Declarations,NewDeclarations) :-
854 chr_translate_line_info(Declarations,'bootstrap',NewDeclarations).
856 chr_translate_line_info(Declarations0,File,NewDeclarations) :-
858 restart_after_flattening(Declarations0,Declarations),
860 chr_source_file(File),
861 /* sort out the interesting stuff from the input */
862 partition_clauses(Declarations,Constraints0,Rules0,OtherClauses),
863 chr_compiler_options:sanity_check,
865 dump_code(Declarations),
867 check_declared_constraints(Constraints0),
868 generate_show_constraint(Constraints0,Constraints,Rules0,Rules1),
869 add_constraints(Constraints),
871 generate_never_stored_rules(Constraints,NewRules),
873 append(Rules1,NewRules,Rules),
874 chr_analysis(Rules,Constraints,Declarations),
875 time('constraint code generation',chr_translate:constraints_code(Constraints,ConstraintClauses)),
876 time('validate store assumptions',chr_translate:validate_store_type_assumptions(Constraints)),
877 phase_end(validate_store_type_assumptions),
879 time('store code generation',chr_translate:store_management_preds(Constraints,StoreClauses)), % depends on actual code used
880 insert_declarations(OtherClauses, Clauses0),
881 chr_module_declaration(CHRModuleDeclaration),
882 append([StoreClauses,ConstraintClauses,CHRModuleDeclaration,[end_of_file]],StuffyGeneratedClauses),
883 clean_clauses(StuffyGeneratedClauses,GeneratedClauses),
884 append([Clauses0,GeneratedClauses], NewDeclarations),
885 dump_code(NewDeclarations),
886 !. /* cut choicepoint of restart_after_flattening */
888 chr_analysis(Rules,Constraints,Declarations) :-
889 check_rules(Rules,Constraints),
890 time('type checking',chr_translate:static_type_check),
892 collect_constants(Rules,Constraints,Declarations),
893 add_occurrences(Rules),
894 time('functional dependency',chr_translate:functional_dependency_analysis(Rules)),
895 time('set semantics',chr_translate:set_semantics_rules(Rules)),
896 time('symmetry analysis',chr_translate:symmetry_analysis(Rules)),
897 time('guard simplification',chr_translate:guard_simplification),
898 time('late storage',chr_translate:storage_analysis(Constraints)),
899 time('observation',chr_translate:observation_analysis(Constraints)),
900 time('ai observation',chr_translate:ai_observation_analysis(Constraints)),
901 time('late allocation',chr_translate:late_allocation_analysis(Constraints)),
902 partial_wake_analysis,
903 time('assume constraint stores',chr_translate:assume_constraint_stores(Constraints)),
904 time('default constraint indices',chr_translate:set_constraint_indices(Constraints)),
905 time('check storedness assertions',chr_translate:check_storedness_assertions(Constraints)),
906 time('continuation analysis',chr_translate:continuation_analysis(Constraints)).
908 store_management_preds(Constraints,Clauses) :-
909 generate_attach_detach_a_constraint_all(Constraints,AttachAConstraintClauses),
910 generate_attr_unify_hook(AttrUnifyHookClauses),
911 generate_attach_increment(AttachIncrementClauses),
912 generate_extra_clauses(Constraints,ExtraClauses),
913 generate_insert_delete_constraints(Constraints,DeleteClauses),
914 generate_attach_code(Constraints,StoreClauses),
915 generate_counter_code(CounterClauses),
916 generate_dynamic_type_check_clauses(TypeCheckClauses),
917 append([AttachAConstraintClauses
918 ,AttachIncrementClauses
919 ,AttrUnifyHookClauses
929 insert_declarations(Clauses0, Clauses) :-
930 findall(:- use_module(chr(Module)),(auxiliary_module(Module), is_used_auxiliary_module(Module)),Decls),
931 append(Clauses0, [:- use_module(chr(chr_runtime))|Decls], Clauses).
933 auxiliary_module(chr_hashtable_store).
934 auxiliary_module(chr_integertable_store).
935 auxiliary_module(chr_assoc_store).
937 generate_counter_code(Clauses) :-
938 ( chr_pp_flag(store_counter,on) ->
940 ('$counter_init'(N1) :- nb_setval(N1,0)) ,
941 ('$counter'(N2,X1) :- nb_getval(N2,X1)),
942 ('$counter_inc'(N) :- nb_getval(N,X), Y is X + 1, nb_setval(N,Y)),
943 (:- '$counter_init'('$insert_counter')),
944 (:- '$counter_init'('$delete_counter')),
945 ('$insert_counter_inc' :- '$counter_inc'('$insert_counter')),
946 ('$delete_counter_inc' :- '$counter_inc'('$delete_counter')),
947 ( counter_stats(I,D) :- '$counter'('$insert_counter',I),'$counter'('$delete_counter',D))
953 % for systems with multifile declaration
954 chr_module_declaration(CHRModuleDeclaration) :-
955 get_target_module(Mod),
956 ( Mod \== chr_translate, chr_pp_flag(toplevel_show_store,on) ->
957 CHRModuleDeclaration = [
958 (:- multifile chr:'$chr_module'/1),
959 chr:'$chr_module'(Mod)
962 CHRModuleDeclaration = []
966 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
968 %% Partitioning of clauses into constraint declarations, chr rules and other
971 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
972 %% partition_clauses(+Clauses,-ConstraintDeclarations,-Rules,-OtherClauses) is det.
973 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
974 partition_clauses([],[],[],[]).
975 partition_clauses([Clause|Clauses],ConstraintDeclarations,Rules,OtherClauses) :-
976 ( parse_rule(Clause,Rule) ->
977 ConstraintDeclarations = RestConstraintDeclarations,
978 Rules = [Rule|RestRules],
979 OtherClauses = RestOtherClauses
980 ; is_declaration(Clause,ConstraintDeclaration) ->
981 append(ConstraintDeclaration,RestConstraintDeclarations,ConstraintDeclarations),
983 OtherClauses = RestOtherClauses
984 ; is_module_declaration(Clause,Mod) ->
986 ConstraintDeclarations = RestConstraintDeclarations,
988 OtherClauses = [Clause|RestOtherClauses]
989 ; is_type_definition(Clause) ->
990 ConstraintDeclarations = RestConstraintDeclarations,
992 OtherClauses = RestOtherClauses
993 ; Clause = (handler _) ->
994 chr_warning(deprecated(Clause),'Backward compatibility: ignoring handler/1 declaration.\n',[]),
995 ConstraintDeclarations = RestConstraintDeclarations,
997 OtherClauses = RestOtherClauses
998 ; Clause = (rules _) ->
999 chr_warning(deprecated(Clause),'Backward compatibility: ignoring rules/1 declaration.\n',[]),
1000 ConstraintDeclarations = RestConstraintDeclarations,
1002 OtherClauses = RestOtherClauses
1003 ; Clause = option(OptionName,OptionValue) ->
1004 chr_warning(deprecated(Clause),'Instead use `:-chr_option(~w,~w).\'\n',[OptionName,OptionValue]),
1005 handle_option(OptionName,OptionValue),
1006 ConstraintDeclarations = RestConstraintDeclarations,
1008 OtherClauses = RestOtherClauses
1009 ; Clause = (:-chr_option(OptionName,OptionValue)) ->
1010 handle_option(OptionName,OptionValue),
1011 ConstraintDeclarations = RestConstraintDeclarations,
1013 OtherClauses = RestOtherClauses
1014 ; Clause = ('$chr_compiled_with_version'(_)) ->
1015 ConstraintDeclarations = RestConstraintDeclarations,
1017 OtherClauses = ['$chr_compiled_with_version'(3)|RestOtherClauses]
1018 ; ConstraintDeclarations = RestConstraintDeclarations,
1020 OtherClauses = [Clause|RestOtherClauses]
1022 partition_clauses(Clauses,RestConstraintDeclarations,RestRules,RestOtherClauses).
1024 '$chr_compiled_with_version'(2).
1026 is_declaration(D, Constraints) :- %% constraint declaration
1027 ( D = (:- Decl), Decl =.. [F,Cs], F == (chr_constraint) ->
1028 conj2list(Cs,Constraints0)
1031 Decl =.. [constraints,Cs]
1033 D =.. [constraints,Cs]
1035 conj2list(Cs,Constraints0),
1036 chr_warning(deprecated(D),'Instead use :- chr_constraint ~w.\n',[Cs])
1038 extract_type_mode(Constraints0,Constraints).
1040 extract_type_mode([],[]).
1041 extract_type_mode([F/A|R],[F/A|R2]) :- !,extract_type_mode(R,R2).
1042 extract_type_mode([C0|R],[ConstraintSymbol|R2]) :-
1043 ( C0 = C # Annotation ->
1045 extract_annotation(Annotation,F/A)
1050 ConstraintSymbol = F/A,
1052 extract_types_and_modes(Args,ArgTypes,ArgModes),
1053 assert_constraint_type(ConstraintSymbol,ArgTypes),
1054 constraint_mode(ConstraintSymbol,ArgModes),
1055 extract_type_mode(R,R2).
1057 extract_annotation(stored,Symbol) :-
1058 stored_assertion(Symbol).
1059 extract_annotation(default(Goal),Symbol) :-
1060 never_stored_default(Symbol,Goal).
1062 extract_types_and_modes([],[],[]).
1063 extract_types_and_modes([X|R],[T|R2],[M|R3]) :-
1064 extract_type_and_mode(X,T,M),
1065 extract_types_and_modes(R,R2,R3).
1067 extract_type_and_mode(+(T),T,(+)) :- !.
1068 extract_type_and_mode(?(T),T,(?)) :- !.
1069 extract_type_and_mode(-(T),T,(-)) :- !.
1070 extract_type_and_mode((+),any,(+)) :- !.
1071 extract_type_and_mode((?),any,(?)) :- !.
1072 extract_type_and_mode((-),any,(-)) :- !.
1073 extract_type_and_mode(Illegal,_,_) :-
1074 chr_error(syntax(Illegal),'Illegal mode/type declaration.\n\tCorrect syntax is +type, -type or ?type\n\tor +, - or ?.\n',[]).
1076 is_type_definition(Declaration) :-
1077 is_type_definition(Declaration,Result),
1078 assert_type_definition(Result).
1080 assert_type_definition(typedef(Name,DefList)) :- type_definition(Name,DefList).
1081 assert_type_definition(alias(Alias,Name)) :- type_alias(Alias,Name).
1083 is_type_definition(Declaration,Result) :-
1084 ( Declaration = (:- TDef) ->
1089 TDef =.. [chr_type,TypeDef],
1090 ( TypeDef = (Name ---> Def) ->
1091 tdisj2list(Def,DefList),
1092 Result = typedef(Name,DefList)
1093 ; TypeDef = (Alias == Name) ->
1094 Result = alias(Alias,Name)
1096 Result = typedef(TypeDef,[]),
1097 chr_warning(syntax,'Empty type definition `~w\'.\nAre you sure you want to declare a phantom type?\n',[Declaration])
1100 %% tdisj2list(+Goal,-ListOfGoals) is det.
1102 % no removal of fails, e.g. :- type bool ---> true ; fail.
1103 tdisj2list(Conj,L) :-
1104 tdisj2list(Conj,L,[]).
1106 tdisj2list(Conj,L,T) :-
1108 tdisj2list(G1,L,T1),
1109 tdisj2list(G2,T1,T).
1110 tdisj2list(G,[G | T],T).
1113 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
1114 %% parse_rule(+term,-pragma_rule) is semidet.
1115 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
1116 parse_rule(RI,R) :- %% name @ rule
1117 RI = (Name @ RI2), !,
1118 rule(RI2,yes(Name),R).
1122 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
1123 %% parse_rule(+term,-pragma_rule) is semidet.
1124 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
1126 RI = (RI2 pragma P), !, %% pragmas
1128 Ps = [_] % intercept variable
1132 inc_rule_count(RuleCount),
1133 R = pragma(R1,IDs,Ps,Name,RuleCount),
1134 is_rule(RI2,R1,IDs,R).
1136 inc_rule_count(RuleCount),
1137 R = pragma(R1,IDs,[],Name,RuleCount),
1138 is_rule(RI,R1,IDs,R).
1140 is_rule(RI,R,IDs,RC) :- %% propagation rule
1142 conj2list(H,Head2i),
1143 get_ids(Head2i,IDs2,Head2,RC),
1146 R = rule([],Head2,G,RB)
1148 R = rule([],Head2,true,B)
1150 is_rule(RI,R,IDs,RC) :- %% simplification/simpagation rule
1159 conj2list(H1,Head2i),
1160 conj2list(H2,Head1i),
1161 get_ids(Head2i,IDs2,Head2,0,N,RC),
1162 get_ids(Head1i,IDs1,Head1,N,_,RC),
1163 IDs = ids(IDs1,IDs2)
1164 ; conj2list(H,Head1i),
1166 get_ids(Head1i,IDs1,Head1,RC),
1169 R = rule(Head1,Head2,Guard,Body).
1171 get_ids(Cs,IDs,NCs,RC) :-
1172 get_ids(Cs,IDs,NCs,0,_,RC).
1174 get_ids([],[],[],N,N,_).
1175 get_ids([C|Cs],[N|IDs],[NC|NCs],N,NN,RC) :-
1180 check_direct_pragma(N1,N,RC)
1186 get_ids(Cs,IDs,NCs, M,NN,RC).
1188 check_direct_pragma(passive,Id,PragmaRule) :- !,
1189 PragmaRule = pragma(_,_,_,_,RuleNb),
1191 check_direct_pragma(Abbrev,Id,PragmaRule) :-
1192 ( direct_pragma(FullPragma),
1193 atom_concat(Abbrev,Remainder,FullPragma) ->
1194 chr_warning(problem_pragma(Abbrev,PragmaRule),'completed `~w\' to `~w\'\n',[Abbrev,FullPragma])
1196 chr_warning(unsupported_pragma(Abbrev,PragmaRule),'',[])
1199 direct_pragma(passive).
1201 is_module_declaration((:- module(Mod)),Mod).
1202 is_module_declaration((:- module(Mod,_)),Mod).
1204 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1206 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1208 add_constraints([]).
1209 add_constraints([C|Cs]) :-
1210 max_occurrence(C,0),
1214 constraint_mode(C,Mode),
1215 add_constraints(Cs).
1219 add_rules([Rule|Rules]) :-
1220 Rule = pragma(_,_,_,_,RuleNb),
1224 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1226 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1227 %% Some input verification:
1229 check_declared_constraints(Constraints) :-
1230 tree_set_empty(Acc),
1231 check_declared_constraints(Constraints,Acc).
1233 check_declared_constraints([],_).
1234 check_declared_constraints([C|Cs],Acc) :-
1235 ( tree_set_memberchk(C,Acc) ->
1236 chr_error(syntax(C),'Constraint multiply defined: ~w.\n\tRemove redundant declaration!\n',[C])
1240 tree_set_add(Acc,C,NAcc),
1241 check_declared_constraints(Cs,NAcc).
1243 %% - all constraints in heads are declared constraints
1244 %% - all passive pragmas refer to actual head constraints
1247 check_rules([PragmaRule|Rest],Decls) :-
1248 check_rule(PragmaRule,Decls),
1249 check_rules(Rest,Decls).
1251 check_rule(PragmaRule,Decls) :-
1252 check_rule_indexing(PragmaRule),
1253 check_trivial_propagation_rule(PragmaRule),
1254 PragmaRule = pragma(Rule,_IDs,Pragmas,_Name,_N),
1255 Rule = rule(H1,H2,_,_),
1256 append(H1,H2,HeadConstraints),
1257 check_head_constraints(HeadConstraints,Decls,PragmaRule),
1258 check_pragmas(Pragmas,PragmaRule).
1260 % Make all heads passive in trivial propagation rule
1261 % ... ==> ... | true.
1262 check_trivial_propagation_rule(PragmaRule) :-
1263 PragmaRule = pragma(Rule,IDs,Pragmas,Name,RuleNb),
1264 ( Rule = rule([],_,_,true) ->
1265 chr_warning(weird_program,'Ignoring propagation rule with empty body: ~@.\n\t\n',[format_rule(PragmaRule)]),
1266 set_all_passive(RuleNb)
1271 check_head_constraints([],_,_).
1272 check_head_constraints([Constr|Rest],Decls,PragmaRule) :-
1273 functor(Constr,F,A),
1274 ( memberchk(F/A,Decls) ->
1275 check_head_constraints(Rest,Decls,PragmaRule)
1277 chr_error(syntax(Constr),'Undeclared constraint ~w in head of ~@.\n\tConstraint should be one of ~w.\n', [F/A,format_rule(PragmaRule),Decls])
1280 check_pragmas([],_).
1281 check_pragmas([Pragma|Pragmas],PragmaRule) :-
1282 check_pragma(Pragma,PragmaRule),
1283 check_pragmas(Pragmas,PragmaRule).
1285 check_pragma(Pragma,PragmaRule) :-
1287 chr_error(syntax(Pragma),'Invalid pragma ~w in ~@.\n\tPragma should not be a variable!\n',[Pragma,format_rule(PragmaRule)]).
1288 check_pragma(passive(ID), PragmaRule) :-
1290 PragmaRule = pragma(_,ids(IDs1,IDs2),_,_,RuleNb),
1291 ( memberchk_eq(ID,IDs1) ->
1293 ; memberchk_eq(ID,IDs2) ->
1296 chr_error(syntax(ID),'Invalid identifier ~w in pragma passive in ~@.\n', [ID,format_rule(PragmaRule)])
1300 check_pragma(mpassive(IDs), PragmaRule) :-
1302 PragmaRule = pragma(_,_,_,_,RuleNb),
1303 chr_warning(experimental,'Experimental pragma ~w. Use with care!\n',[mpassive(IDs)]),
1304 maplist(passive(RuleNb),IDs).
1306 check_pragma(Pragma, PragmaRule) :-
1307 Pragma = already_in_heads,
1309 chr_warning(unsupported_pragma(Pragma,PragmaRule),'Termination and correctness may be affected.\n',[]).
1311 check_pragma(Pragma, PragmaRule) :-
1312 Pragma = already_in_head(_),
1314 chr_warning(unsupported_pragma(Pragma,PragmaRule),'Termination and correctness may be affected.\n',[]).
1316 check_pragma(Pragma, PragmaRule) :-
1317 Pragma = no_history,
1319 chr_warning(experimental,'Experimental pragma no_history. Use with care!\n',[]),
1320 PragmaRule = pragma(_,_,_,_,N),
1323 check_pragma(Pragma, PragmaRule) :-
1324 Pragma = history(HistoryName,IDs),
1326 PragmaRule = pragma(_,ids(IDs1,IDs2),_,_,RuleNb),
1327 chr_warning(experimental,'Experimental pragma ~w. Use with care!\n',[Pragma]),
1329 chr_error(syntax(Pragma),'Pragma history only implemented for propagation rules.\n',[])
1330 ; \+ atom(HistoryName) ->
1331 chr_error(syntax(Pragma),'Illegal argument for pragma history: ~w is not an atom (rule number ~w).\n',[HistoryName,RuleNb])
1333 chr_error(syntax(Pragma),'Illegal argument for pragma history: ~w is not a set (rule number ~w).\n',[IDs,RuleNb])
1334 ; check_history_pragma_ids(IDs,IDs1,IDs2) ->
1335 history(RuleNb,HistoryName,IDs)
1337 chr_error(syntax(Pragma),'Invalid identifier(s) in pragma ~w of rule number ~w.\n',[Pragma,RuleNb])
1339 check_pragma(Pragma,PragmaRule) :-
1340 Pragma = line_number(LineNumber),
1342 PragmaRule = pragma(_,_,_,_,RuleNb),
1343 line_number(RuleNb,LineNumber).
1345 check_history_pragma_ids([], _, _).
1346 check_history_pragma_ids([ID|IDs],IDs1,IDs2) :-
1347 ( memberchk_eq(ID,IDs2) ; memberchk_eq(ID,IDs1) ),
1348 check_history_pragma_ids(IDs,IDs1,IDs2).
1350 check_pragma(Pragma,PragmaRule) :-
1351 chr_error(syntax(Pragma),'Unknown pragma ~w in ~@.\n', [Pragma,format_rule(PragmaRule)]).
1353 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1354 %% no_history(+RuleNb) is det.
1355 :- chr_constraint no_history/1.
1356 :- chr_option(mode,no_history(+)).
1357 :- chr_option(type_declaration,no_history(int)).
1359 %% has_no_history(+RuleNb) is semidet.
1360 :- chr_constraint has_no_history/1.
1361 :- chr_option(mode,has_no_history(+)).
1362 :- chr_option(type_declaration,has_no_history(int)).
1364 no_history(RuleNb) \ has_no_history(RuleNb) <=> true.
1365 has_no_history(_) <=> fail.
1367 :- chr_constraint history/3.
1368 :- chr_option(mode,history(+,+,+)).
1369 :- chr_option(type_declaration,history(any,any,list)).
1371 :- chr_constraint named_history/3.
1373 history(RuleNb,_,_), history(RuleNb,_,_) ==>
1374 chr_error(syntax,'Only one pragma history allowed per rule (rule number ~w)\n',[RuleNb]). %'
1376 history(RuleNb1,Name,IDs1), history(RuleNb2,Name,IDs2) ==>
1377 length(IDs1,L1), length(IDs2,L2),
1379 chr_error(syntax,'The history named ~w does not always range over an equal amount of occurrences.\n',[Name])
1381 test_named_history_id_pairs(RuleNb1,IDs1,RuleNb2,IDs2)
1384 test_named_history_id_pairs(_, [], _, []).
1385 test_named_history_id_pairs(RuleNb1, [ID1|IDs1], RuleNb2, [ID2|IDs2]) :-
1386 test_named_history_id_pair(RuleNb1,ID1,RuleNb2,ID2),
1387 test_named_history_id_pairs(RuleNb1,IDs1,RuleNb2,IDs2).
1389 :- chr_constraint test_named_history_id_pair/4.
1390 :- chr_option(mode,test_named_history_id_pair(+,+,+,+)).
1392 occurrence(C,_,RuleNb1,ID1,_), occurrence(C,_,RuleNb2,ID2,_)
1393 \ test_named_history_id_pair(RuleNb1,ID1,RuleNb2,ID2) <=> true.
1394 test_named_history_id_pair(RuleNb1,ID1,RuleNb2,ID2) <=>
1395 chr_error(syntax,'Occurrences of shared history in rules number ~w and ~w do not correspond\n', [RuleNb2,RuleNb1]).
1397 history(RuleNb,Name,IDs) \ named_history(RuleNb,QName,QIDs) <=> QName = Name, QIDs = IDs.
1398 named_history(_,_,_) <=> fail.
1400 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1403 format_rule(PragmaRule) :-
1404 PragmaRule = pragma(_,_,_,MaybeName,RuleNumber),
1405 ( MaybeName = yes(Name) ->
1406 write('rule '), write(Name)
1408 write('rule number '), write(RuleNumber)
1410 get_line_number(RuleNumber,LineNumber),
1415 check_rule_indexing(PragmaRule) :-
1416 PragmaRule = pragma(Rule,_,_,_,_),
1417 Rule = rule(H1,H2,G,_),
1418 term_variables(H1-H2,HeadVars),
1419 remove_anti_monotonic_guards(G,HeadVars,NG),
1420 check_indexing(H1,NG-H2),
1421 check_indexing(H2,NG-H1),
1423 ( chr_pp_flag(term_indexing,on) ->
1424 term_variables(NG,GuardVariables),
1425 append(H1,H2,Heads),
1426 check_specs_indexing(Heads,GuardVariables,Specs)
1431 :- chr_constraint indexing_spec/2.
1432 :- chr_option(mode,indexing_spec(+,+)).
1434 :- chr_constraint get_indexing_spec/2.
1435 :- chr_option(mode,get_indexing_spec(+,-)).
1438 indexing_spec(FA,Spec) \ get_indexing_spec(FA,R) <=> R = Spec.
1439 get_indexing_spec(_,Spec) <=> Spec = [].
1441 indexing_spec(FA,Specs1), indexing_spec(FA,Specs2)
1443 append(Specs1,Specs2,Specs),
1444 indexing_spec(FA,Specs).
1446 remove_anti_monotonic_guards(G,Vars,NG) :-
1448 remove_anti_monotonic_guard_list(GL,Vars,NGL),
1451 remove_anti_monotonic_guard_list([],_,[]).
1452 remove_anti_monotonic_guard_list([G|Gs],Vars,NGs) :-
1453 ( G = var(X), memberchk_eq(X,Vars) ->
1455 % TODO: this is not correct
1456 % ; G = functor(Term,Functor,Arity), % isotonic
1457 % \+ memberchk_eq(Functor,Vars), \+ memberchk_eq(Arity,Vars) ->
1462 remove_anti_monotonic_guard_list(Gs,Vars,RGs).
1464 check_indexing([],_).
1465 check_indexing([Head|Heads],Other) :-
1468 term_variables(Heads-Other,OtherVars),
1469 check_indexing(Args,1,F/A,OtherVars),
1470 check_indexing(Heads,[Head|Other]).
1472 check_indexing([],_,_,_).
1473 check_indexing([Arg|Args],I,FA,OtherVars) :-
1474 ( is_indexed_argument(FA,I) ->
1477 indexed_argument(FA,I)
1479 term_variables(Args,ArgsVars),
1480 append(ArgsVars,OtherVars,RestVars),
1481 ( memberchk_eq(Arg,RestVars) ->
1482 indexed_argument(FA,I)
1488 term_variables(Arg,NVars),
1489 append(NVars,OtherVars,NOtherVars),
1490 check_indexing(Args,J,FA,NOtherVars).
1492 check_specs_indexing([],_,[]).
1493 check_specs_indexing([Head|Heads],Variables,Specs) :-
1494 Specs = [Spec|RSpecs],
1495 term_variables(Heads,OtherVariables,Variables),
1496 check_spec_indexing(Head,OtherVariables,Spec),
1497 term_variables(Head,NVariables,Variables),
1498 check_specs_indexing(Heads,NVariables,RSpecs).
1500 check_spec_indexing(Head,OtherVariables,Spec) :-
1502 Spec = spec(F,A,ArgSpecs),
1504 check_args_spec_indexing(Args,1,OtherVariables,ArgSpecs),
1505 indexing_spec(F/A,[ArgSpecs]).
1507 check_args_spec_indexing([],_,_,[]).
1508 check_args_spec_indexing([Arg|Args],I,OtherVariables,ArgSpecs) :-
1509 term_variables(Args,Variables,OtherVariables),
1510 ( check_arg_spec_indexing(Arg,I,Variables,ArgSpec) ->
1511 ArgSpecs = [ArgSpec|RArgSpecs]
1513 ArgSpecs = RArgSpecs
1516 term_variables(Arg,NOtherVariables,OtherVariables),
1517 check_args_spec_indexing(Args,J,NOtherVariables,RArgSpecs).
1519 check_arg_spec_indexing(Arg,I,Variables,ArgSpec) :-
1521 memberchk_eq(Arg,Variables),
1522 ArgSpec = specinfo(I,any,[])
1525 ArgSpec = specinfo(I,F/A,[ArgSpecs]),
1527 check_args_spec_indexing(Args,1,Variables,ArgSpecs)
1530 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1532 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1535 add_occurrences([]).
1536 add_occurrences([Rule|Rules]) :-
1537 Rule = pragma(rule(H1,H2,_,_),ids(IDs1,IDs2),_,_,Nb),
1538 add_occurrences(H1,IDs1,simplification,Nb),
1539 add_occurrences(H2,IDs2,propagation,Nb),
1540 add_occurrences(Rules).
1542 add_occurrences([],[],_,_).
1543 add_occurrences([H|Hs],[ID|IDs],Type,RuleNb) :-
1546 new_occurrence(FA,RuleNb,ID,Type),
1547 add_occurrences(Hs,IDs,Type,RuleNb).
1549 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1551 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1552 % Observation Analysis
1562 :- chr_constraint observation_analysis/1.
1563 :- chr_option(mode, observation_analysis(+)).
1565 observation_analysis(Cs), rule(RuleNb,PragmaRule) # Id ==>
1566 PragmaRule = pragma(rule(_,_,Guard,Body),_,_,_,_),
1567 ( chr_pp_flag(store_in_guards, on) ->
1568 observation_analysis(RuleNb, Guard, guard, Cs)
1572 observation_analysis(RuleNb, Body, body, Cs)
1575 observation_analysis(_) <=> true.
1577 observation_analysis(RuleNb, Term, GB, Cs) :-
1578 ( all_spawned(RuleNb,GB) ->
1581 spawns_all(RuleNb,GB)
1589 observation_analysis(RuleNb,T1,GB,Cs),
1590 observation_analysis(RuleNb,T2,GB,Cs)
1592 observation_analysis(RuleNb,T1,GB,Cs),
1593 observation_analysis(RuleNb,T2,GB,Cs)
1594 ; Term = (T1->T2) ->
1595 observation_analysis(RuleNb,T1,GB,Cs),
1596 observation_analysis(RuleNb,T2,GB,Cs)
1598 observation_analysis(RuleNb,T,GB,Cs)
1599 ; functor(Term,F,A), memberchk(F/A,Cs) ->
1600 spawns(RuleNb,GB,F/A)
1602 spawns_all_triggers(RuleNb,GB)
1603 ; Term = (_ is _) ->
1604 spawns_all_triggers(RuleNb,GB)
1605 ; builtin_binds_b(Term,Vars) ->
1609 spawns_all_triggers(RuleNb,GB)
1612 spawns_all(RuleNb,GB)
1615 :- chr_constraint spawns/3.
1616 :- chr_option(mode, spawns(+,+,+)).
1617 :- chr_type spawns_type ---> guard ; body.
1618 :- chr_option(type_declaration,spawns(any,spawns_type,any)).
1620 :- chr_constraint spawns_all/2, spawns_all_triggers/2.
1621 :- chr_option(mode, spawns_all(+,+)).
1622 :- chr_option(type_declaration,spawns_all(any,spawns_type)).
1623 :- chr_option(mode, spawns_all_triggers(+,+)).
1624 :- chr_option(type_declaration,spawns_all_triggers(any,spawns_type)).
1626 spawns_all(RuleNb,GB) \ spawns_all(RuleNb,GB) <=> true.
1627 spawns_all(RuleNb,guard) \ spawns_all(RuleNb,body) <=> true.
1628 spawns_all_triggers(RuleNb,GB) \ spawns_all_triggers(RuleNb,GB) <=> true.
1629 spawns_all_triggers(RuleNb,guard) \ spawns_all_triggers(RuleNb,body) <=> true.
1630 spawns(RuleNb,GB,C) \ spawns(RuleNb,GB,C) <=> true.
1631 spawns(RuleNb,guard,C) \ spawns(RuleNb,body,C) <=> true.
1633 spawns_all(RuleNb,GB) \ spawns(RuleNb,GB,_) <=> true.
1634 spawns_all(RuleNb,guard) \ spawns(RuleNb,body,_) <=> true.
1635 spawns_all(RuleNb,GB) \ spawns_all_triggers(RuleNb,GB) <=> true.
1636 spawns_all(RuleNb,guard) \ spawns_all_triggers(RuleNb,body) <=> true.
1638 spawns_all_triggers(RuleNb,GB) \ spawns(RuleNb,GB,C) <=> may_trigger(C) | true.
1639 spawns_all_triggers(RuleNb,guard) \ spawns(RuleNb,body,C) <=> may_trigger(C) | true.
1641 spawns_all(RuleNb2,_), occurrence(C1,_,RuleNb2,O,_)#Id
1643 spawns(RuleNb1,GB,C1)
1645 \+ is_passive(RuleNb2,O)
1647 spawns_all(RuleNb1,GB)
1651 occurrence(C1,_,RuleNb2,O,_)#Id, spawns_all(RuleNb2,_)
1653 \+(\+ spawns_all_triggers_implies_spawns_all), % in the hope it schedules this guard early...
1654 \+ is_passive(RuleNb2,O), may_trigger(C1)
1656 spawns_all_triggers_implies_spawns_all
1660 :- chr_constraint spawns_all_triggers_implies_spawns_all/0.
1661 spawns_all_triggers_implies_spawns_all, spawns_all_triggers_implies_spawns_all <=> fail.
1662 spawns_all_triggers_implies_spawns_all \
1663 spawns_all_triggers(RuleNb,GB) <=> spawns_all(RuleNb,GB).
1665 spawns_all_triggers(RuleNb2,_), occurrence(C1,_,RuleNb2,O,_)#Id
1667 spawns(RuleNb1,GB,C1)
1670 \+ is_passive(RuleNb2,O)
1672 spawns_all_triggers(RuleNb1,GB)
1676 spawns_all_triggers(RuleNb2,_), occurrence(C1,_,RuleNb2,O,_)#Id,
1677 spawns(RuleNb1,GB,C1)
1680 \+ is_passive(RuleNb2,O)
1682 spawns_all_triggers(RuleNb1,GB)
1686 % a bit dangerous this rule: could start propagating too much too soon?
1687 spawns(RuleNb2,_,C2), occurrence(C1,_,RuleNb2,O,_)#Id,
1688 spawns(RuleNb1,GB,C1)
1690 RuleNb1 \== RuleNb2, C1 \== C2,
1691 \+ is_passive(RuleNb2,O)
1693 spawns(RuleNb1,GB,C2)
1697 spawns(RuleNb2,_,C2), occurrence(C1,_,RuleNb2,O,_)#Id,
1698 spawns_all_triggers(RuleNb1,GB)
1700 \+ is_passive(RuleNb2,O), may_trigger(C1), \+ may_trigger(C2)
1702 spawns(RuleNb1,GB,C2)
1707 :- chr_constraint all_spawned/2.
1708 :- chr_option(mode, all_spawned(+,+)).
1709 spawns_all(RuleNb,guard) \ all_spawned(RuleNb,_) <=> true.
1710 spawns_all(RuleNb,GB) \ all_spawned(RuleNb,GB) <=> true.
1711 all_spawned(RuleNb,GB) <=> fail.
1714 % Overview of the supported queries:
1715 % is_observed(+functor/artiy, +occurrence_number, +(guard;body))
1716 % only succeeds if the occurrence is observed by the
1717 % guard resp. body (depending on the last argument) of its rule
1718 % is_observed(+functor/artiy, +occurrence_number, -)
1719 % succeeds if the occurrence is observed by either the guard or
1720 % the body of its rule
1721 % NOTE: the last argument is NOT bound by this query
1723 % do_is_observed(+functor/artiy,+rule_number,+(guard;body))
1724 % succeeds if the given constraint is observed by the given
1726 % do_is_observed(+functor/artiy,+rule_number)
1727 % succeeds if the given constraint is observed by the given
1728 % rule (either its guard or its body)
1733 ai_is_observed(C,O).
1735 is_stored_in_guard(C,RuleNb) :-
1736 chr_pp_flag(store_in_guards, on),
1737 do_is_observed(C,RuleNb,guard).
1739 :- chr_constraint is_observed/3.
1740 :- chr_option(mode, is_observed(+,+,+)).
1741 occurrence(C,O,RuleNb,_,_) \ is_observed(C,O,GB) <=> do_is_observed(C,RuleNb,GB).
1742 is_observed(_,_,_) <=> fail. % this will not happen in practice
1745 :- chr_constraint do_is_observed/3.
1746 :- chr_option(mode, do_is_observed(+,+,+)).
1747 :- chr_constraint do_is_observed/2.
1748 :- chr_option(mode, do_is_observed(+,+)).
1750 do_is_observed(C,RuleNb,GB) <=> var(GB) | do_is_observed(C,RuleNb).
1753 % a constraint C is observed if the GB of the rule it occurs in spawns all,
1754 % and some non-passive occurrence of some (possibly other) constraint
1755 % exists in a rule (could be same rule) with at least one occurrence of C
1757 spawns_all(RuleNb,GB),
1758 occurrence(_,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1760 do_is_observed(C,RuleNb,GB)
1762 \+ is_passive(RuleNb2,O)
1766 spawns_all(RuleNb,_),
1767 occurrence(_,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1769 do_is_observed(C,RuleNb)
1771 \+ is_passive(RuleNb2,O)
1776 % a constraint C is observed if the GB of the rule it occurs in spawns a
1777 % constraint C2 that occurs non-passively in a rule (possibly the same rule)
1778 % as an occurrence of C
1780 spawns(RuleNb,GB,C2),
1781 occurrence(C2,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1783 do_is_observed(C,RuleNb,GB)
1785 \+ is_passive(RuleNb2,O)
1789 spawns(RuleNb,_,C2),
1790 occurrence(C2,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1792 do_is_observed(C,RuleNb)
1794 \+ is_passive(RuleNb2,O)
1798 % (3) spawns_all_triggers
1799 % a constraint C is observed if the GB of the rule it occurs in spawns all triggers
1800 % and some non-passive occurrence of some (possibly other) constraint that may trigger
1801 % exists in a rule (could be same rule) with at least one occurrence of C
1803 spawns_all_triggers(RuleNb,GB),
1804 occurrence(C2,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1806 do_is_observed(C,RuleNb,GB)
1808 \+ is_passive(RuleNb2,O), may_trigger(C2)
1812 spawns_all_triggers(RuleNb,_),
1813 occurrence(C2,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1815 do_is_observed(C,RuleNb)
1817 \+ is_passive(RuleNb2,O), may_trigger(C2)
1821 % (4) conservativeness
1822 do_is_observed(_,_,_) <=> chr_pp_flag(observation_analysis,off).
1823 do_is_observed(_,_) <=> chr_pp_flag(observation_analysis,off).
1826 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1828 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1831 %% Generated predicates
1832 %% attach_$CONSTRAINT
1834 %% detach_$CONSTRAINT
1837 %% attach_$CONSTRAINT
1838 generate_attach_detach_a_constraint_all([],[]).
1839 generate_attach_detach_a_constraint_all([Constraint|Constraints],Clauses) :-
1840 ( ( chr_pp_flag(debugable,on) ; is_stored(Constraint), \+ only_ground_indexed_arguments(Constraint), \+ get_store_type(Constraint,var_assoc_store(_,_)) ) ->
1841 generate_attach_a_constraint(Constraint,Clauses1),
1842 generate_detach_a_constraint(Constraint,Clauses2)
1847 generate_attach_detach_a_constraint_all(Constraints,Clauses3),
1848 append([Clauses1,Clauses2,Clauses3],Clauses).
1850 generate_attach_a_constraint(Constraint,[Clause1,Clause2]) :-
1851 generate_attach_a_constraint_nil(Constraint,Clause1),
1852 generate_attach_a_constraint_cons(Constraint,Clause2).
1854 attach_constraint_atom(FA,Vars,Susp,Atom) :-
1855 make_name('attach_',FA,Name),
1856 Atom =.. [Name,Vars,Susp].
1858 generate_attach_a_constraint_nil(FA,Clause) :-
1859 Clause = (Head :- true),
1860 attach_constraint_atom(FA,[],_,Head).
1862 generate_attach_a_constraint_cons(FA,Clause) :-
1863 Clause = (Head :- Body),
1864 attach_constraint_atom(FA,[Var|Vars],Susp,Head),
1865 attach_constraint_atom(FA,Vars,Susp,RecursiveCall),
1866 Body = ( AttachBody, Subscribe, RecursiveCall ),
1867 get_max_constraint_index(N),
1869 generate_attach_body_1(FA,Var,Susp,AttachBody)
1871 generate_attach_body_n(FA,Var,Susp,AttachBody)
1873 % SWI-Prolog specific code
1874 chr_pp_flag(solver_events,NMod),
1876 Args = [[Var|_],Susp],
1877 get_target_module(Mod),
1878 use_auxiliary_predicate(run_suspensions),
1879 Subscribe = clp_events:subscribe(Var,NMod,Mod,Mod:'$run_suspensions'([Susp]))
1884 generate_attach_body_1(FA,Var,Susp,Body) :-
1885 get_target_module(Mod),
1887 ( get_attr(Var, Mod, Susps) ->
1888 put_attr(Var, Mod, [Susp|Susps])
1890 put_attr(Var, Mod, [Susp])
1893 generate_attach_body_n(F/A,Var,Susp,Body) :-
1894 get_constraint_index(F/A,Position),
1895 get_max_constraint_index(Total),
1896 get_target_module(Mod),
1897 add_attr(Total,Susp,Position,TAttr,AddGoal,NTAttr),
1898 singleton_attr(Total,Susp,Position,NewAttr3),
1900 ( get_attr(Var,Mod,TAttr) ->
1902 put_attr(Var,Mod,NTAttr)
1904 put_attr(Var,Mod,NewAttr3)
1907 %% detach_$CONSTRAINT
1908 generate_detach_a_constraint(Constraint,[Clause1,Clause2]) :-
1909 generate_detach_a_constraint_nil(Constraint,Clause1),
1910 generate_detach_a_constraint_cons(Constraint,Clause2).
1912 detach_constraint_atom(FA,Vars,Susp,Atom) :-
1913 make_name('detach_',FA,Name),
1914 Atom =.. [Name,Vars,Susp].
1916 generate_detach_a_constraint_nil(FA,Clause) :-
1917 Clause = ( Head :- true),
1918 detach_constraint_atom(FA,[],_,Head).
1920 generate_detach_a_constraint_cons(FA,Clause) :-
1921 Clause = (Head :- Body),
1922 detach_constraint_atom(FA,[Var|Vars],Susp,Head),
1923 detach_constraint_atom(FA,Vars,Susp,RecursiveCall),
1924 Body = ( DetachBody, RecursiveCall ),
1925 get_max_constraint_index(N),
1927 generate_detach_body_1(FA,Var,Susp,DetachBody)
1929 generate_detach_body_n(FA,Var,Susp,DetachBody)
1932 generate_detach_body_1(FA,Var,Susp,Body) :-
1933 get_target_module(Mod),
1935 ( get_attr(Var,Mod,Susps) ->
1936 'chr sbag_del_element'(Susps,Susp,NewSusps),
1940 put_attr(Var,Mod,NewSusps)
1946 generate_detach_body_n(F/A,Var,Susp,Body) :-
1947 get_constraint_index(F/A,Position),
1948 get_max_constraint_index(Total),
1949 rem_attr(Total,Var,Susp,Position,TAttr,RemGoal),
1950 get_target_module(Mod),
1952 ( get_attr(Var,Mod,TAttr) ->
1958 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1959 %-------------------------------------------------------------------------------
1960 %% generate_indexed_variables_body(+ConstraintSymbol,+ArgList,-Body,-VarList) is det.
1961 :- chr_constraint generate_indexed_variables_body/4.
1962 :- chr_option(mode,generate_indexed_variables_body(+,?,+,?)).
1963 :- chr_option(type_declaration,generate_indexed_variables_body(constraint,any,any,any)).
1964 %-------------------------------------------------------------------------------
1965 constraint_mode(F/A,ArgModes) \ generate_indexed_variables_body(F/A,Args,Body,Vars) <=>
1966 get_indexing_spec(F/A,Specs),
1967 ( chr_pp_flag(term_indexing,on) ->
1968 spectermvars(Specs,Args,F,A,Body,Vars)
1970 get_constraint_type_det(F/A,ArgTypes),
1971 create_indexed_variables_body(Args,ArgModes,ArgTypes,Vars,1,F/A,MaybeBody,N),
1972 ( MaybeBody == empty ->
1979 Term =.. [term|Args]
1981 Body = term_variables(Term,Vars)
1986 generate_indexed_variables_body(FA,_,_,_) <=>
1987 chr_error(internal,'generate_indexed_variables_body: missing mode info for ~w.\n',[FA]).
1988 %===============================================================================
1990 create_indexed_variables_body([],[],[],_,_,_,empty,0).
1991 create_indexed_variables_body([V|Vs],[Mode|Modes],[Type|Types],Vars,I,FA,Body,N) :-
1993 create_indexed_variables_body(Vs,Modes,Types,Tail,J,FA,RBody,M),
1995 is_indexed_argument(FA,I) ->
1996 ( atomic_type(Type) ->
2007 Continuation = true, Tail = []
2009 Continuation = RBody
2013 Body = term_variables(V,Vars)
2015 Body = (term_variables(V,Vars,Tail),RBody)
2019 ; Mode == (-), is_indexed_argument(FA,I) ->
2023 Body = (Vars = [V|Tail],RBody)
2031 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2033 spectermvars(Specs,Args,F,A,Goal,Vars) :-
2034 spectermvars(Args,1,Specs,F,A,Vars,[],Goal).
2036 spectermvars([],B,_,_,A,L,L,true) :- B > A, !.
2037 spectermvars([Arg|Args],I,Specs,F,A,L,T,Goal) :-
2038 Goal = (ArgGoal,RGoal),
2039 argspecs(Specs,I,TempArgSpecs,RSpecs),
2040 merge_argspecs(TempArgSpecs,ArgSpecs),
2041 arggoal(ArgSpecs,Arg,ArgGoal,L,L1),
2043 spectermvars(Args,J,RSpecs,F,A,L1,T,RGoal).
2045 argspecs([],_,[],[]).
2046 argspecs([[]|Rest],I,ArgSpecs,RestSpecs) :-
2047 argspecs(Rest,I,ArgSpecs,RestSpecs).
2048 argspecs([[specinfo(J,Spec,Args)|Specs]|Rest],I,ArgSpecs,RestSpecs) :-
2050 ArgSpecs = [specinfo(J,Spec,Args)|RArgSpecs],
2052 RRestSpecs = RestSpecs
2054 RestSpecs = [Specs|RRestSpecs]
2057 ArgSpecs = RArgSpecs,
2058 RestSpecs = [[specinfo(J,Spec,Args)|Specs]|RRestSpecs]
2060 argspecs(Rest,I,RArgSpecs,RRestSpecs).
2062 merge_argspecs(In,Out) :-
2064 merge_argspecs_(Sorted,Out).
2066 merge_argspecs_([],[]).
2067 merge_argspecs_([X],R) :- !, R = [X].
2068 merge_argspecs_([specinfo(I,F1,A1),specinfo(I,F2,A2)|Rest],R) :-
2069 ( (F1 == any ; F2 == any) ->
2070 merge_argspecs_([specinfo(I,any,[])|Rest],R)
2073 merge_argspecs_([specinfo(I,F1,A)|Rest],R)
2075 R = [specinfo(I,F1,A1)|RR],
2076 merge_argspecs_([specinfo(I,F2,A2)|Rest],RR)
2079 arggoal(List,Arg,Goal,L,T) :-
2083 ; List = [specinfo(_,any,_)] ->
2084 Goal = term_variables(Arg,L,T)
2092 arggoal_cases(List,Arg,L,T,Cases)
2095 arggoal_cases([],_,L,T,L=T).
2096 arggoal_cases([specinfo(_,FA,ArgSpecs)|Rest],Arg,L,T,Cases) :-
2099 ; ArgSpecs == [[]] ->
2102 Cases = (Case ; RCases),
2105 Case = (Arg = Term -> ArgsGoal),
2106 spectermvars(Args,1,ArgSpecs,F,A,L,T,ArgsGoal)
2108 arggoal_cases(Rest,Arg,L,T,RCases).
2109 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2111 generate_extra_clauses(Constraints,List) :-
2112 generate_activate_clauses(Constraints,List,Tail0),
2113 generate_remove_clauses(Constraints,Tail0,Tail1),
2114 generate_allocate_clauses(Constraints,Tail1,Tail2),
2115 generate_insert_constraint_internal_clauses(Constraints,Tail2,Tail3),
2116 generate_novel_production(Tail3,Tail4),
2117 generate_extend_history(Tail4,Tail5),
2118 generate_run_suspensions_clauses(Constraints,Tail5,Tail6),
2119 generate_empty_named_history_initialisations(Tail6,Tail7),
2122 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2123 % remove_constraint_internal/[1/3]
2125 generate_remove_clauses([],List,List).
2126 generate_remove_clauses([C|Cs],List,Tail) :-
2127 generate_remove_clause(C,List,List1),
2128 generate_remove_clauses(Cs,List1,Tail).
2130 remove_constraint_goal(Constraint,Susp,Agenda,DeleteNo,DeleteYes,Role,Goal) :-
2131 uses_state(Constraint,removed),
2132 ( chr_pp_flag(inline_insertremove,off) ->
2133 use_auxiliary_predicate(remove_constraint_internal,Constraint),
2134 Goal = ( DeleteGoal, ( Delete == yes -> DeleteYes ; DeleteNo) ),
2135 remove_constraint_atom(Constraint,Susp,Agenda,Delete,DeleteGoal)
2137 delay_phase_end(validate_store_type_assumptions,
2138 generate_remove_body(Constraint,Susp,Agenda,DeleteNo,DeleteYes,Role,Goal)
2142 remove_constraint_atom(Constraint,Susp,Agenda,Delete,Goal) :-
2143 make_name('$remove_constraint_internal_',Constraint,Name),
2144 ( chr_pp_flag(debugable,off), ( only_ground_indexed_arguments(Constraint) ; get_store_type(Constraint,var_assoc_store(_,_)) ) ->
2145 Goal =.. [Name, Susp,Delete]
2147 Goal =.. [Name,Susp,Agenda,Delete]
2150 generate_remove_clause(Constraint,List,Tail) :-
2151 ( is_used_auxiliary_predicate(remove_constraint_internal,Constraint) ->
2152 List = [RemoveClause|Tail],
2153 RemoveClause = (Head :- RemoveBody),
2154 remove_constraint_atom(Constraint,Susp,Agenda,Delete,Head),
2155 generate_remove_body(Constraint,Susp,Agenda,Delete = no,Delete = yes,active,RemoveBody)
2160 generate_remove_body(Constraint,Susp,Agenda,DeleteNo,DeleteYes,Role,RemoveBody) :-
2161 ( chr_pp_flag(debugable,off), ( only_ground_indexed_arguments(Constraint) ; get_store_type(Constraint,var_assoc_store(_,_))) ->
2163 get_update_suspension_field(Constraint,Susp,state,State,removed,GetState,GetStateValue0,UpdateState),
2164 if_used_state(Constraint,not_stored_yet,GetStateValue0,true,GetStateValue),
2165 if_used_state(Constraint,not_stored_yet,(State == not_stored_yet -> DeleteNo ; DeleteYes),DeleteYes,MaybeDelete)
2166 ; Role == partner ->
2167 get_update_suspension_field(Constraint,Susp,state,State,removed,GetState,_,UpdateState),
2168 GetStateValue = true,
2169 MaybeDelete = DeleteYes
2179 static_suspension_term(Constraint,Susp2),
2180 get_static_suspension_term_field(arguments,Constraint,Susp2,Args),
2181 generate_indexed_variables_body(Constraint,Args,IndexedVariablesBody,Agenda),
2182 ( chr_pp_flag(debugable,on) ->
2183 Constraint = Functor / _,
2184 get_static_suspension_term_field(functor,Constraint,Susp2,Functor)
2189 get_update_static_suspension_field(Constraint,Susp,Susp2,state,State,removed,GetStateValue0,UpdateState),
2190 if_used_state(Constraint,not_stored_yet,GetStateValue0,true,GetStateValue),
2191 if_used_state(Constraint,not_stored_yet,(State == not_stored_yet -> Agenda = [], DeleteNo ; IndexedVariablesBody, DeleteYes),(IndexedVariablesBody,DeleteYes),MaybeDelete)
2192 ; Role == partner ->
2193 get_update_static_suspension_field(Constraint,Susp,Susp2,state,State,removed,_,UpdateState),
2194 GetStateValue = true,
2195 MaybeDelete = (IndexedVariablesBody, DeleteYes)
2206 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2207 % activate_constraint/4
2209 generate_activate_clauses([],List,List).
2210 generate_activate_clauses([C|Cs],List,Tail) :-
2211 generate_activate_clause(C,List,List1),
2212 generate_activate_clauses(Cs,List1,Tail).
2214 activate_constraint_goal(Constraint,StoreAction,Vars,Susp,Generation,Goal) :-
2215 ( chr_pp_flag(inline_insertremove,off) ->
2216 use_auxiliary_predicate(activate_constraint,Constraint),
2217 Goal = ( ActivateGoal , (Store == yes -> StoreAction ; true) ),
2218 activate_constraint_atom(Constraint,Store,Vars,Susp,Generation,ActivateGoal)
2220 delay_phase_end(validate_store_type_assumptions,
2221 activate_constraint_body(Constraint,StoreAction,true,Vars,Susp,Generation,Goal)
2225 activate_constraint_atom(Constraint,Store,Vars,Susp,Generation,Goal) :-
2226 make_name('$activate_constraint_',Constraint,Name),
2227 ( chr_pp_flag(debugable,off), only_ground_indexed_arguments(Constraint) ->
2228 Goal =.. [Name,Store, Susp]
2229 ; chr_pp_flag(debugable,off), may_trigger(Constraint), get_store_type(Constraint,var_assoc_store(_,_)) ->
2230 Goal =.. [Name,Store, Susp, Generation]
2231 ; chr_pp_flag(debugable,off), may_trigger(Constraint), get_store_type(Constraint,var_assoc_store(_,_)) ->
2232 Goal =.. [Name,Store, Vars, Susp, Generation]
2234 Goal =.. [Name,Store, Vars, Susp]
2237 generate_activate_clause(Constraint,List,Tail) :-
2238 ( is_used_auxiliary_predicate(activate_constraint,Constraint) ->
2239 List = [Clause|Tail],
2240 Clause = (Head :- Body),
2241 activate_constraint_atom(Constraint,Store,Vars,Susp,Generation,Head),
2242 activate_constraint_body(Constraint,Store = yes, Store = no,Vars,Susp,Generation,Body)
2247 activate_constraint_body(Constraint,StoreYes,StoreNo,Vars,Susp,Generation,Body) :-
2248 ( chr_pp_flag(debugable,off), may_trigger(Constraint), uses_field(Constraint,generation) ->
2249 get_update_suspension_field(Constraint,Susp,generation,Gen,Generation,GetGeneration,GetGenerationValue,UpdateGeneration),
2250 GenerationHandling = (GetGeneration, GetGenerationValue, Generation is Gen+1, UpdateGeneration)
2252 GenerationHandling = true
2254 get_update_suspension_field(Constraint,Susp,state,State,active,GetState,GetStateValue0,UpdateState),
2255 if_used_state(Constraint,not_stored_yet,GetStateValue0,true,GetStateValue),
2256 ( chr_pp_flag(debugable,off), ( only_ground_indexed_arguments(Constraint) ; get_store_type(Constraint,var_assoc_store(_,_))) ->
2257 if_used_state(Constraint,not_stored_yet,( State == not_stored_yet -> StoreYes ; StoreNo ),StoreNo,StoreVarsGoal)
2259 get_dynamic_suspension_term_field(arguments,Constraint,Susp,Arguments,ArgumentsGoal),
2260 generate_indexed_variables_body(Constraint,Arguments,IndexedVariablesBody,Vars),
2261 ( chr_pp_flag(guard_locks,off) ->
2264 NoneLocked = 'chr none_locked'( Vars)
2266 if_used_state(Constraint,not_stored_yet,
2267 ( State == not_stored_yet ->
2269 IndexedVariablesBody,
2276 % (Vars = [],StoreNo),StoreVarsGoal)
2277 StoreNo,StoreVarsGoal)
2287 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2288 % allocate_constraint/4
2290 generate_allocate_clauses([],List,List).
2291 generate_allocate_clauses([C|Cs],List,Tail) :-
2292 generate_allocate_clause(C,List,List1),
2293 generate_allocate_clauses(Cs,List1,Tail).
2295 allocate_constraint_goal(Constraint,Susp,Args,Goal) :-
2296 uses_state(Constraint,not_stored_yet),
2297 ( chr_pp_flag(inline_insertremove,off) ->
2298 use_auxiliary_predicate(allocate_constraint,Constraint),
2299 allocate_constraint_atom(Constraint,Susp,Args,Goal)
2301 Goal = (Susp = Suspension, Goal0),
2302 delay_phase_end(validate_store_type_assumptions,
2303 allocate_constraint_body(Constraint,Suspension,Args,Goal0)
2307 allocate_constraint_atom(Constraint, Susp, Args,Goal) :-
2308 make_name('$allocate_constraint_',Constraint,Name),
2309 Goal =.. [Name,Susp|Args].
2311 generate_allocate_clause(Constraint,List,Tail) :-
2312 ( is_used_auxiliary_predicate(allocate_constraint,Constraint) ->
2313 List = [Clause|Tail],
2314 Clause = (Head :- Body),
2317 allocate_constraint_atom(Constraint,Susp,Args,Head),
2318 allocate_constraint_body(Constraint,Susp,Args,Body)
2323 allocate_constraint_body(Constraint,Susp,Args,Body) :-
2324 static_suspension_term(Constraint,Suspension),
2325 get_static_suspension_term_field(arguments,Constraint,Suspension,Args),
2326 ( chr_pp_flag(debugable,on) ->
2327 Constraint = Functor / _,
2328 get_static_suspension_term_field(functor,Constraint,Suspension,Functor)
2332 ( chr_pp_flag(debugable,on) ->
2333 ( may_trigger(Constraint) ->
2334 append(Args,[Susp],VarsSusp),
2335 build_head(F,A,[0],VarsSusp, ContinuationGoal),
2336 get_target_module(Mod),
2337 Continuation = Mod : ContinuationGoal
2341 Init = (Susp = Suspension),
2342 create_static_suspension_field(Constraint,Suspension,continuation,Continuation,CreateContinuation),
2343 create_static_suspension_field(Constraint,Suspension,generation,0,CreateGeneration)
2344 ; may_trigger(Constraint), uses_field(Constraint,generation) ->
2345 create_static_suspension_field(Constraint,Suspension,generation,0,CreateGeneration),
2346 Susp = Suspension, Init = true, CreateContinuation = true
2348 CreateGeneration = true, Susp = Suspension, Init = true, CreateContinuation = true
2350 ( uses_history(Constraint) ->
2351 create_static_suspension_field(Constraint,Suspension,history,t,CreateHistory)
2353 CreateHistory = true
2355 create_static_suspension_field(Constraint,Suspension,state,not_stored_yet,CreateState),
2356 ( has_suspension_field(Constraint,id) ->
2357 get_static_suspension_term_field(id,Constraint,Suspension,Id),
2372 gen_id(Id,'chr gen_id'(Id)).
2373 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2374 % insert_constraint_internal
2376 generate_insert_constraint_internal_clauses([],List,List).
2377 generate_insert_constraint_internal_clauses([C|Cs],List,Tail) :-
2378 generate_insert_constraint_internal_clause(C,List,List1),
2379 generate_insert_constraint_internal_clauses(Cs,List1,Tail).
2381 insert_constraint_internal_constraint_goal(Constraint, Vars, Suspension, Continuation, Args,Goal) :-
2382 ( chr_pp_flag(inline_insertremove,off) ->
2383 use_auxiliary_predicate(remove_constraint_internal,Constraint),
2384 insert_constraint_internal_constraint_atom(Constraint,Vars,Suspension,Continuation,Args,Goal)
2386 delay_phase_end(validate_store_type_assumptions,
2387 generate_insert_constraint_internal_body(Constraint,Suspension,Continuation,Args,Vars,Goal)
2392 insert_constraint_internal_constraint_atom(Constraint,Vars,Self,Closure,Args,Goal) :-
2393 insert_constraint_internal_constraint_name(Constraint,Name),
2394 ( chr_pp_flag(debugable,on) ->
2395 Goal =.. [Name, Vars, Self, Closure | Args]
2396 ; ( only_ground_indexed_arguments(Constraint) ; get_store_type(Constraint,var_assoc_store(_,_)))->
2397 Goal =.. [Name,Self | Args]
2399 Goal =.. [Name,Vars, Self | Args]
2402 insert_constraint_internal_constraint_name(Constraint,Name) :-
2403 make_name('$insert_constraint_internal_',Constraint,Name).
2405 generate_insert_constraint_internal_clause(Constraint,List,Tail) :-
2406 ( is_used_auxiliary_predicate(insert_constraint_internal,Constraint) ->
2407 List = [Clause|Tail],
2408 Clause = (Head :- Body),
2411 insert_constraint_internal_constraint_atom(Constraint, Vars, Suspension, Continuation,Args,Head),
2412 generate_insert_constraint_internal_body(Constraint,Suspension,Continuation,Args,Vars,Body)
2418 generate_insert_constraint_internal_body(Constraint,Susp,Continuation,Args,Vars,Body) :-
2419 static_suspension_term(Constraint,Suspension),
2420 create_static_suspension_field(Constraint,Suspension,state,active,CreateState),
2421 ( chr_pp_flag(debugable,on) ->
2422 get_static_suspension_term_field(continuation,Constraint,Suspension,Continuation),
2423 create_static_suspension_field(Constraint,Suspension,generation,0,CreateGeneration)
2424 ; may_trigger(Constraint), uses_field(Constraint,generation) ->
2425 create_static_suspension_field(Constraint,Suspension,generation,0,CreateGeneration)
2427 CreateGeneration = true
2429 ( chr_pp_flag(debugable,on) ->
2430 Constraint = Functor / _,
2431 get_static_suspension_term_field(functor,Constraint,Suspension,Functor)
2435 ( uses_history(Constraint) ->
2436 create_static_suspension_field(Constraint,Suspension,history,t,CreateHistory)
2438 CreateHistory = true
2440 get_static_suspension_term_field(arguments,Constraint,Suspension,Args),
2441 List = [Clause|Tail],
2442 ( chr_pp_flag(debugable,off), ( only_ground_indexed_arguments(Constraint) ; get_store_type(Constraint,var_assoc_store(_,_)))->
2443 suspension_term_base_fields(Constraint,BaseFields),
2444 ( has_suspension_field(Constraint,id) ->
2445 get_static_suspension_term_field(id,Constraint,Suspension,Id),
2459 ( has_suspension_field(Constraint,id) ->
2460 get_static_suspension_term_field(id,Constraint,Suspension,Id),
2465 generate_indexed_variables_body(Constraint,Args,IndexedVariablesBody,Vars),
2466 ( chr_pp_flag(guard_locks,off) ->
2469 NoneLocked = 'chr none_locked'( Vars)
2474 IndexedVariablesBody,
2483 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2484 % novel_production/2
2486 generate_novel_production(List,Tail) :-
2487 ( is_used_auxiliary_predicate(novel_production) ->
2488 List = [Clause|Tail],
2491 '$novel_production'( Self, Tuple) :-
2492 % arg( 3, Self, Ref), % ARGXXX
2493 % 'chr get_mutable'( History, Ref),
2494 arg( 3, Self, History), % ARGXXX
2495 ( hprolog:get_ds( Tuple, History, _) ->
2505 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2508 generate_extend_history(List,Tail) :-
2509 ( is_used_auxiliary_predicate(extend_history) ->
2510 List = [Clause|Tail],
2513 '$extend_history'( Self, Tuple) :-
2514 % arg( 3, Self, Ref), % ARGXXX
2515 % 'chr get_mutable'( History, Ref),
2516 arg( 3, Self, History), % ARGXXX
2517 hprolog:put_ds( Tuple, History, x, NewHistory),
2518 setarg( 3, Self, NewHistory) % ARGXXX
2524 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2527 empty_named_history_initialisations/2,
2528 generate_empty_named_history_initialisation/1,
2529 find_empty_named_histories/0.
2531 generate_empty_named_history_initialisations(List, Tail) :-
2532 empty_named_history_initialisations(List, Tail),
2533 find_empty_named_histories.
2535 find_empty_named_histories, history(_, Name, []) ==>
2536 generate_empty_named_history_initialisation(Name).
2538 generate_empty_named_history_initialisation(Name) \
2539 generate_empty_named_history_initialisation(Name) <=> true.
2540 generate_empty_named_history_initialisation(Name) \
2541 empty_named_history_initialisations(List, Tail) # Passive
2543 empty_named_history_global_variable(Name, GlobalVariable),
2544 List = [(:- nb_setval(GlobalVariable, 0))|Rest],
2545 empty_named_history_initialisations(Rest, Tail)
2546 pragma passive(Passive).
2548 find_empty_named_histories \
2549 generate_empty_named_history_initialisation(_) # Passive <=> true
2550 pragma passive(Passive).
2552 find_empty_named_histories,
2553 empty_named_history_initialisations(List, Tail) # Passive <=> List = Tail
2554 pragma passive(Passive).
2556 find_empty_named_histories <=>
2557 chr_error(internal, 'find_empty_named_histories was not removed', []).
2560 empty_named_history_global_variable(Name, GlobalVariable) :-
2561 atom_concat('chr empty named history ', Name, GlobalVariable).
2563 empty_named_history_novel_production(Name, nb_getval(GlobalVariable, 0)) :-
2564 empty_named_history_global_variable(Name, GlobalVariable).
2566 empty_named_history_extend_history(Name, b_setval(GlobalVariable, 1)) :-
2567 empty_named_history_global_variable(Name, GlobalVariable).
2570 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2573 generate_run_suspensions_clauses([],List,List).
2574 generate_run_suspensions_clauses([C|Cs],List,Tail) :-
2575 generate_run_suspensions_clause(C,List,List1),
2576 generate_run_suspensions_clauses(Cs,List1,Tail).
2578 run_suspensions_goal(Constraint,Suspensions,Goal) :-
2579 make_name('$run_suspensions_',Constraint,Name),
2580 Goal =.. [Name,Suspensions].
2582 generate_run_suspensions_clause(Constraint,List,Tail) :-
2583 ( is_used_auxiliary_predicate(run_suspensions,Constraint) ->
2584 List = [Clause1,Clause2|Tail],
2585 run_suspensions_goal(Constraint,[],Clause1),
2586 ( chr_pp_flag(debugable,on) ->
2587 run_suspensions_goal(Constraint,[Suspension|Suspensions],Clause2Head),
2588 get_update_suspension_field(Constraint,Suspension,state,State,triggered,GetState,GetStateValue,UpdateState),
2589 get_update_suspension_field(Constraint,Suspension,state,Post,active,GetPost,GetPostValue,UpdatePost),
2590 get_update_suspension_field(Constraint,Suspension,generation,Gen,Generation,GetGeneration,GetGenerationValue,UpdateGeneration),
2591 get_dynamic_suspension_term_field(continuation,Constraint,Suspension,Continuation,GetContinuation),
2592 run_suspensions_goal(Constraint,Suspensions,Clause2Recursion),
2602 Generation is Gen+1,
2606 'chr debug_event'(wake(Suspension)),
2609 'chr debug_event'(fail(Suspension)), !,
2613 'chr debug_event'(exit(Suspension))
2615 'chr debug_event'(redo(Suspension)),
2620 ( Post==triggered ->
2621 UpdatePost % catching constraints that did not do anything
2631 run_suspensions_goal(Constraint,[Suspension|Suspensions],Clause2Head),
2632 static_suspension_term(Constraint,SuspensionTerm),
2633 get_static_suspension_term_field(arguments,Constraint,SuspensionTerm,Arguments),
2634 append(Arguments,[Suspension],VarsSusp),
2635 make_suspension_continuation_goal(Constraint,VarsSusp,Continuation),
2636 run_suspensions_goal(Constraint,Suspensions,Clause2Recursion),
2637 ( uses_field(Constraint,generation) ->
2638 get_update_static_suspension_field(Constraint,Suspension,SuspensionTerm,generation,Gen,Generation,GetGeneration,UpdateGeneration),
2639 GenerationHandling = ( GetGeneration, Generation is Gen+1, UpdateGeneration)
2641 GenerationHandling = true
2643 get_update_static_suspension_field(Constraint,Suspension,SuspensionTerm,state,State,triggered,GetState,UpdateState),
2644 get_update_static_suspension_field(Constraint,Suspension,SuspensionTerm,state,Post,active,GetPostState,UpdatePostState),
2645 if_used_state(Constraint,removed,
2648 -> ReactivateConstraint
2650 ),ReactivateConstraint,CondReactivate),
2651 ReactivateConstraint =
2657 ( Post==triggered ->
2658 UpdatePostState % catching constraints that did not do anything
2666 Suspension = SuspensionTerm,
2675 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2677 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2678 generate_attach_increment(Clauses) :-
2679 get_max_constraint_index(N),
2680 ( is_used_auxiliary_predicate(attach_increment), N > 0 ->
2681 Clauses = [Clause1,Clause2],
2682 generate_attach_increment_empty(Clause1),
2684 generate_attach_increment_one(Clause2)
2686 generate_attach_increment_many(N,Clause2)
2692 generate_attach_increment_empty((attach_increment([],_) :- true)).
2694 generate_attach_increment_one(Clause) :-
2695 Head = attach_increment([Var|Vars],Susps),
2696 get_target_module(Mod),
2697 ( chr_pp_flag(guard_locks,off) ->
2700 NotLocked = 'chr not_locked'( Var)
2705 ( get_attr(Var,Mod,VarSusps) ->
2706 sort(VarSusps,SortedVarSusps),
2707 'chr merge_attributes'(Susps,SortedVarSusps,MergedSusps),
2708 put_attr(Var,Mod,MergedSusps)
2710 put_attr(Var,Mod,Susps)
2712 attach_increment(Vars,Susps)
2714 Clause = (Head :- Body).
2716 generate_attach_increment_many(N,Clause) :-
2717 Head = attach_increment([Var|Vars],TAttr1),
2718 % writeln(merge_attributes_1_before),
2719 merge_attributes(N,TAttr1,TAttr2,MergeGoal,Attr),
2720 % writeln(merge_attributes_1_after),
2721 get_target_module(Mod),
2722 ( chr_pp_flag(guard_locks,off) ->
2725 NotLocked = 'chr not_locked'( Var)
2730 ( get_attr(Var,Mod,TAttr2) ->
2732 put_attr(Var,Mod,Attr)
2734 put_attr(Var,Mod,TAttr1)
2736 attach_increment(Vars,TAttr1)
2738 Clause = (Head :- Body).
2741 generate_attr_unify_hook(Clauses) :-
2742 get_max_constraint_index(N),
2747 generate_attr_unify_hook_one(Clauses)
2749 generate_attr_unify_hook_many(N,Clauses)
2753 generate_attr_unify_hook_one([Clause]) :-
2754 Head = attr_unify_hook(Susps,Other),
2755 get_target_module(Mod),
2756 get_indexed_constraint(1,C),
2757 ( get_store_type(C,ST),
2758 ( ST = default ; ST = multi_store(STs), memberchk(default,STs) ) ->
2759 make_run_suspensions(NewSusps,SortedSusps,WakeNewSusps),
2760 make_run_suspensions(SortedSusps,SortedSusps,WakeSusps),
2761 ( atomic_types_suspended_constraint(C) ->
2763 SortedSusps = Susps,
2765 SortedOtherSusps = OtherSusps,
2766 MergeGoal = (append(Susps,OtherSusps,List), sort(List,NewSusps)),
2769 SortGoal1 = sort(Susps, SortedSusps),
2770 SortGoal2 = sort(OtherSusps,SortedOtherSusps),
2771 MergeGoal = 'chr merge_attributes'(SortedSusps,SortedOtherSusps,NewSusps),
2772 use_auxiliary_predicate(attach_increment),
2774 ( compound(Other) ->
2775 term_variables(Other,OtherVars),
2776 attach_increment(OtherVars, SortedSusps)
2785 ( get_attr(Other,Mod,OtherSusps) ->
2788 put_attr(Other,Mod,NewSusps),
2791 put_attr(Other,Mod,SortedSusps),
2799 Clause = (Head :- Body)
2800 ; get_store_type(C,var_assoc_store(VarIndex,KeyIndex)) ->
2801 make_run_suspensions(List,List,WakeNewSusps),
2802 MergeGoal = (merge_into_assoc_store(Susps,OtherSusps,List)),
2804 ( get_attr(Other,Mod,OtherSusps) ->
2808 put_attr(Other,Mod,Susps)
2810 Clause = (Head :- Body)
2814 generate_attr_unify_hook_many(N,[Clause]) :-
2815 chr_pp_flag(dynattr,off), !,
2816 Head = attr_unify_hook(Attr,Other),
2817 get_target_module(Mod),
2818 make_attr(N,Mask,SuspsList,Attr),
2819 bagof(Sort,A ^ B ^ ( member(A,SuspsList) , Sort = sort(A,B) ) , SortGoalList),
2820 list2conj(SortGoalList,SortGoals),
2821 bagof(B, A ^ member(sort(A,B),SortGoalList), SortedSuspsList),
2822 merge_attributes2(N,Mask,SortedSuspsList,TOtherAttr,MergeGoal,MergedAttr),
2823 get_all_suspensions2(N,MergedAttr,MergedSuspsList),
2824 make_attr(N,Mask,SortedSuspsList,SortedAttr),
2825 make_run_suspensions_loop(MergedSuspsList,SortedSuspsList,WakeMergedSusps),
2826 make_run_suspensions_loop(SortedSuspsList,SortedSuspsList,WakeSortedSusps),
2827 ( forall((between(1,N,Index), get_indexed_constraint(Index,Constraint)),atomic_types_suspended_constraint(Constraint)) ->
2830 use_auxiliary_predicate(attach_increment),
2832 ( compound(Other) ->
2833 term_variables(Other,OtherVars),
2834 attach_increment(OtherVars,SortedAttr)
2843 ( get_attr(Other,Mod,TOtherAttr) ->
2845 put_attr(Other,Mod,MergedAttr),
2848 put_attr(Other,Mod,SortedAttr),
2856 Clause = (Head :- Body).
2859 generate_attr_unify_hook_many(N,Clauses) :-
2860 Head = attr_unify_hook(Attr,Other),
2861 get_target_module(Mod),
2862 normalize_attr(Attr,NormalGoal,NormalAttr),
2863 normalize_attr(OtherAttr,NormalOtherGoal,NormalOtherAttr),
2864 merge_attributes(N,NormalAttr,NormalOtherAttr,MergeGoal,MergedAttr),
2865 make_run_suspensions(N),
2866 ( forall((between(1,N,Index), get_indexed_constraint(Index,Constraint)),atomic_types_suspended_constraint(Constraint)) ->
2869 use_auxiliary_predicate(attach_increment),
2871 ( compound(Other) ->
2872 term_variables(Other,OtherVars),
2873 attach_increment(OtherVars,NormalAttr)
2882 ( get_attr(Other,Mod,OtherAttr) ->
2885 put_attr(Other,Mod,MergedAttr),
2886 '$dispatch_run_suspensions'(MergedAttr)
2888 put_attr(Other,Mod,NormalAttr),
2889 '$dispatch_run_suspensions'(NormalAttr)
2893 '$dispatch_run_suspensions'(NormalAttr)
2896 Clause = (Head :- Body),
2897 Clauses = [Clause,DispatchList1,DispatchList2|Dispatchers],
2898 DispatchList1 = ('$dispatch_run_suspensions'([])),
2899 DispatchList2 = ('$dispatch_run_suspensions'([Pos-List|Rest]) :- '$dispatch_run_suspensions'(Pos,List),'$dispatch_run_suspensions'(Rest)),
2900 run_suspensions_dispatchers(N,[],Dispatchers).
2903 run_suspensions_dispatchers(N,Acc,Dispatchers) :-
2905 get_indexed_constraint(N,C),
2906 NAcc = [('$dispatch_run_suspensions'(N,List) :- Body)|Acc],
2908 run_suspensions_goal(C,List,Body)
2913 run_suspensions_dispatchers(M,NAcc,Dispatchers)
2919 make_run_suspensions(N) :-
2921 ( get_indexed_constraint(N,C),
2923 use_auxiliary_predicate(run_suspensions,C)
2928 make_run_suspensions(M)
2933 make_run_suspensions(AllSusps,OneSusps,Goal) :-
2934 make_run_suspensions(1,AllSusps,OneSusps,Goal).
2936 make_run_suspensions(Index,AllSusps,OneSusps,Goal) :-
2937 ( get_indexed_constraint(Index,C), may_trigger(C) ->
2938 use_auxiliary_predicate(run_suspensions,C),
2939 ( wakes_partially(C) ->
2940 run_suspensions_goal(C,OneSusps,Goal)
2942 run_suspensions_goal(C,AllSusps,Goal)
2948 make_run_suspensions_loop(AllSuspsList,OneSuspsList,Goal) :-
2949 make_run_suspensions_loop(AllSuspsList,OneSuspsList,1,Goal).
2951 make_run_suspensions_loop([],[],_,true).
2952 make_run_suspensions_loop([AllSusps|AllSuspsList],[OneSusps|OneSuspsList],I,(Goal,Goals)) :-
2953 make_run_suspensions(I,AllSusps,OneSusps,Goal),
2955 make_run_suspensions_loop(AllSuspsList,OneSuspsList,J,Goals).
2957 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2958 % $insert_in_store_F/A
2959 % $delete_from_store_F/A
2961 generate_insert_delete_constraints([],[]).
2962 generate_insert_delete_constraints([FA|Rest],Clauses) :-
2964 generate_insert_delete_constraint(FA,Clauses,RestClauses)
2966 Clauses = RestClauses
2968 generate_insert_delete_constraints(Rest,RestClauses).
2970 generate_insert_delete_constraint(FA,Clauses,RestClauses) :-
2971 insert_constraint_clause(FA,Clauses,RestClauses1),
2972 delete_constraint_clause(FA,RestClauses1,RestClauses).
2974 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
2977 insert_constraint_goal(FA,Susp,Vars,Goal) :-
2978 ( chr_pp_flag(inline_insertremove,off) ->
2979 use_auxiliary_predicate(insert_in_store,FA),
2980 insert_constraint_atom(FA,Susp,Goal)
2982 delay_phase_end(validate_store_type_assumptions,
2983 ( insert_constraint_body(FA,Susp,UsedVars,Goal),
2984 insert_constraint_direct_used_vars(UsedVars,Vars)
2989 insert_constraint_direct_used_vars([],_).
2990 insert_constraint_direct_used_vars([Index-Var|Rest],Vars) :-
2991 nth1(Index,Vars,Var),
2992 insert_constraint_direct_used_vars(Rest,Vars).
2994 insert_constraint_atom(FA,Susp,Call) :-
2995 make_name('$insert_in_store_',FA,Functor),
2996 Call =.. [Functor,Susp].
2998 insert_constraint_clause(C,Clauses,RestClauses) :-
2999 ( is_used_auxiliary_predicate(insert_in_store,C) ->
3000 Clauses = [Clause|RestClauses],
3001 Clause = (Head :- InsertCounterInc,VarsBody,Body),
3002 insert_constraint_atom(C,Susp,Head),
3003 insert_constraint_body(C,Susp,UsedVars,Body),
3004 insert_constraint_used_vars(UsedVars,C,Susp,VarsBody),
3005 ( chr_pp_flag(store_counter,on) ->
3006 InsertCounterInc = '$insert_counter_inc'
3008 InsertCounterInc = true
3011 Clauses = RestClauses
3014 insert_constraint_used_vars([],_,_,true).
3015 insert_constraint_used_vars([Index-Var|Rest],C,Susp,(Goal,Goals)) :-
3016 get_dynamic_suspension_term_field(argument(Index),C,Susp,Var,Goal),
3017 insert_constraint_used_vars(Rest,C,Susp,Goals).
3019 insert_constraint_body(C,Susp,UsedVars,Body) :-
3020 get_store_type(C,StoreType),
3021 insert_constraint_body(StoreType,C,Susp,UsedVars,Body).
3023 insert_constraint_body(default,C,Susp,[],Body) :-
3024 global_list_store_name(C,StoreName),
3025 make_get_store_goal(StoreName,Store,GetStoreGoal),
3026 make_update_store_goal(StoreName,Cell,UpdateStoreGoal),
3027 ( chr_pp_flag(debugable,on) ->
3028 Cell = [Susp|Store],
3035 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,Cell,SetGoal),
3039 Cell = [Susp|Store],
3041 ( Store = [NextSusp|_] ->
3048 % get_target_module(Mod),
3049 % get_max_constraint_index(Total),
3051 % generate_attach_body_1(C,Store,Susp,AttachBody)
3053 % generate_attach_body_n(C,Store,Susp,AttachBody)
3057 % 'chr default_store'(Store),
3060 insert_constraint_body(multi_inthash(Indexes),C,Susp,[],Body) :-
3061 generate_multi_inthash_insert_constraint_bodies(Indexes,C,Susp,Body).
3062 insert_constraint_body(multi_hash(Indexes),C,Susp,MixedUsedVars,Body) :-
3063 generate_multi_hash_insert_constraint_bodies(Indexes,C,Susp,Body,MixedUsedVars),
3064 sort_out_used_vars(MixedUsedVars,UsedVars).
3065 insert_constraint_body(atomic_constants(Index,_,_),C,Susp,UsedVars,Body) :-
3066 multi_hash_key_direct(C,Index,Susp,Key,UsedVars),
3067 constants_store_index_name(C,Index,IndexName),
3068 IndexLookup =.. [IndexName,Key,StoreName],
3071 nb_getval(StoreName,Store),
3072 b_setval(StoreName,[Susp|Store])
3076 insert_constraint_body(ground_constants(Index,_,_),C,Susp,UsedVars,Body) :-
3077 multi_hash_key_direct(C,Index,Susp,Key,UsedVars),
3078 constants_store_index_name(C,Index,IndexName),
3079 IndexLookup =.. [IndexName,Key,StoreName],
3082 nb_getval(StoreName,Store),
3083 b_setval(StoreName,[Susp|Store])
3087 insert_constraint_body(global_ground,C,Susp,[],Body) :-
3088 global_ground_store_name(C,StoreName),
3089 make_get_store_goal(StoreName,Store,GetStoreGoal),
3090 make_update_store_goal(StoreName,Cell,UpdateStoreGoal),
3091 ( chr_pp_flag(debugable,on) ->
3092 Cell = [Susp|Store],
3099 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,Cell,SetGoal),
3103 Cell = [Susp|Store],
3105 ( Store = [NextSusp|_] ->
3112 % global_ground_store_name(C,StoreName),
3113 % make_get_store_goal(StoreName,Store,GetStoreGoal),
3114 % make_update_store_goal(StoreName,[Susp|Store],UpdateStoreGoal),
3117 % GetStoreGoal, % nb_getval(StoreName,Store),
3118 % UpdateStoreGoal % b_setval(StoreName,[Susp|Store])
3120 insert_constraint_body(var_assoc_store(VarIndex,AssocIndex),C,Susp,[VarIndex-Variable,AssocIndex-Key],Body) :-
3121 % TODO: generalize to more than one !!!
3122 get_target_module(Module),
3123 Body = ( get_attr(Variable,Module,AssocStore) ->
3124 insert_assoc_store(AssocStore,Key,Susp)
3126 new_assoc_store(AssocStore),
3127 put_attr(Variable,Module,AssocStore),
3128 insert_assoc_store(AssocStore,Key,Susp)
3131 insert_constraint_body(global_singleton,C,Susp,[],Body) :-
3132 global_singleton_store_name(C,StoreName),
3133 make_update_store_goal(StoreName,Susp,UpdateStoreGoal),
3138 insert_constraint_body(multi_store(StoreTypes),C,Susp,UsedVars,Body) :-
3139 maplist(insert_constraint_body1(C,Susp),StoreTypes,NestedUsedVars,Bodies),
3140 list2conj(Bodies,Body),
3141 sort_out_used_vars(NestedUsedVars,UsedVars).
3142 insert_constraint_body1(C,Susp,StoreType,UsedVars,Body) :-
3143 insert_constraint_body(StoreType,C,Susp,UsedVars,Body).
3144 insert_constraint_body(identifier_store(Index),C,Susp,UsedVars,Body) :-
3145 UsedVars = [Index-Var],
3146 get_identifier_size(ISize),
3147 functor(Struct,struct,ISize),
3148 get_identifier_index(C,Index,IIndex),
3149 arg(IIndex,Struct,Susps),
3150 Body = (Var = Struct, setarg(IIndex,Var,[Susp|Susps])).
3151 insert_constraint_body(type_indexed_identifier_store(Index,IndexType),C,Susp,UsedVars,Body) :-
3152 UsedVars = [Index-Var],
3153 type_indexed_identifier_structure(IndexType,Struct),
3154 get_type_indexed_identifier_index(IndexType,C,Index,IIndex),
3155 arg(IIndex,Struct,Susps),
3156 Body = (Var = Struct, setarg(IIndex,Var,[Susp|Susps])).
3158 sort_out_used_vars(NestedUsedVars,UsedVars) :-
3159 flatten(NestedUsedVars,FlatUsedVars),
3160 sort(FlatUsedVars,SortedFlatUsedVars),
3161 sort_out_used_vars1(SortedFlatUsedVars,UsedVars).
3163 sort_out_used_vars1([],[]).
3164 sort_out_used_vars1([I-V],L) :- !, L = [I-V].
3165 sort_out_used_vars1([I-X,J-Y|R],L) :-
3168 sort_out_used_vars1([I-X|R],L)
3171 sort_out_used_vars1([J-Y|R],T)
3174 generate_multi_inthash_insert_constraint_bodies([],_,_,true).
3175 generate_multi_inthash_insert_constraint_bodies([Index|Indexes],FA,Susp,(Body,Bodies)) :-
3176 multi_hash_store_name(FA,Index,StoreName),
3177 multi_hash_key(FA,Index,Susp,KeyBody,Key),
3181 nb_getval(StoreName,Store),
3182 insert_iht(Store,Key,Susp)
3184 generate_multi_inthash_insert_constraint_bodies(Indexes,FA,Susp,Bodies).
3186 generate_multi_hash_insert_constraint_bodies([],_,_,true,[]).
3187 generate_multi_hash_insert_constraint_bodies([Index|Indexes],FA,Susp,(Body,Bodies),[UsedVars|MoreUsedVars]) :-
3188 multi_hash_store_name(FA,Index,StoreName),
3189 multi_hash_key_direct(FA,Index,Susp,Key,UsedVars),
3190 make_get_store_goal(StoreName,Store,GetStoreGoal),
3191 ( chr_pp_flag(ht_removal,on)
3192 -> ht_prev_field(Index,PrevField),
3193 set_dynamic_suspension_term_field(PrevField,FA,NextSusp,Result,
3198 insert_ht(Store,Key,Susp,Result),
3199 ( Result = [_,NextSusp|_]
3207 insert_ht(Store,Key,Susp)
3210 generate_multi_hash_insert_constraint_bodies(Indexes,FA,Susp,Bodies,MoreUsedVars).
3212 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3215 delete_constraint_clause(C,Clauses,RestClauses) :-
3216 ( is_used_auxiliary_predicate(delete_from_store,C) ->
3217 Clauses = [Clause|RestClauses],
3218 Clause = (Head :- Body),
3219 delete_constraint_atom(C,Susp,Head),
3222 delete_constraint_body(C,Head,Susp,[],Body)
3224 Clauses = RestClauses
3227 delete_constraint_goal(Head,Susp,VarDict,Goal) :-
3230 ( chr_pp_flag(inline_insertremove,off) ->
3231 use_auxiliary_predicate(delete_from_store,C),
3232 delete_constraint_atom(C,Susp,Goal)
3234 delay_phase_end(validate_store_type_assumptions, delete_constraint_body(C,Head,Susp,VarDict,Goal))
3237 delete_constraint_atom(C,Susp,Atom) :-
3238 make_name('$delete_from_store_',C,Functor),
3239 Atom =.. [Functor,Susp].
3242 delete_constraint_body(C,Head,Susp,VarDict,Body) :-
3243 Body = (CounterBody,DeleteBody),
3244 ( chr_pp_flag(store_counter,on) ->
3245 CounterBody = '$delete_counter_inc'
3249 get_store_type(C,StoreType),
3250 delete_constraint_body(StoreType,C,Head,Susp,VarDict,DeleteBody).
3252 delete_constraint_body(default,C,_,Susp,_,Body) :-
3253 ( chr_pp_flag(debugable,on) ->
3254 global_list_store_name(C,StoreName),
3255 make_get_store_goal(StoreName,Store,GetStoreGoal),
3256 make_update_store_goal(StoreName,NStore,UpdateStoreGoal),
3259 GetStoreGoal, % nb_getval(StoreName,Store),
3260 'chr sbag_del_element'(Store,Susp,NStore),
3261 UpdateStoreGoal % b_setval(StoreName,NStore)
3264 get_dynamic_suspension_term_field(global_list_prev,C,Susp,PredCell,GetGoal),
3265 global_list_store_name(C,StoreName),
3266 make_get_store_goal(StoreName,Store,GetStoreGoal),
3267 make_update_store_goal(StoreName,Tail,UpdateStoreGoal),
3268 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,_,SetGoal1),
3269 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,PredCell,SetGoal2),
3274 GetStoreGoal, % nb_getval(StoreName,Store),
3277 ( Tail = [NextSusp|_] ->
3283 PredCell = [_,_|Tail],
3284 setarg(2,PredCell,Tail),
3285 ( Tail = [NextSusp|_] ->
3293 % get_target_module(Mod),
3294 % get_max_constraint_index(Total),
3296 % generate_detach_body_1(C,Store,Susp,DetachBody),
3299 % 'chr default_store'(Store),
3303 % generate_detach_body_n(C,Store,Susp,DetachBody),
3306 % 'chr default_store'(Store),
3310 delete_constraint_body(multi_inthash(Indexes),C,_,Susp,_,Body) :-
3311 generate_multi_inthash_delete_constraint_bodies(Indexes,C,Susp,Body).
3312 delete_constraint_body(multi_hash(Indexes),C,Head,Susp,VarDict,Body) :-
3313 generate_multi_hash_delete_constraint_bodies(Indexes,C,Head,Susp,VarDict,Body).
3314 delete_constraint_body(atomic_constants(Index,_,_),C,Head,Susp,VarDict,Body) :-
3315 multi_hash_key(C,Head,Index,Susp,VarDict,KeyBody,Key),
3316 constants_store_index_name(C,Index,IndexName),
3317 IndexLookup =.. [IndexName,Key,StoreName],
3321 nb_getval(StoreName,Store),
3322 'chr sbag_del_element'(Store,Susp,NStore),
3323 b_setval(StoreName,NStore)
3327 delete_constraint_body(ground_constants(Index,_,_),C,Head,Susp,VarDict,Body) :-
3328 multi_hash_key(C,Head,Index,Susp,VarDict,KeyBody,Key),
3329 constants_store_index_name(C,Index,IndexName),
3330 IndexLookup =.. [IndexName,Key,StoreName],
3334 nb_getval(StoreName,Store),
3335 'chr sbag_del_element'(Store,Susp,NStore),
3336 b_setval(StoreName,NStore)
3340 delete_constraint_body(global_ground,C,_,Susp,_,Body) :-
3341 ( chr_pp_flag(debugable,on) ->
3342 global_ground_store_name(C,StoreName),
3343 make_get_store_goal(StoreName,Store,GetStoreGoal),
3344 make_update_store_goal(StoreName,NStore,UpdateStoreGoal),
3347 GetStoreGoal, % nb_getval(StoreName,Store),
3348 'chr sbag_del_element'(Store,Susp,NStore),
3349 UpdateStoreGoal % b_setval(StoreName,NStore)
3352 get_dynamic_suspension_term_field(global_list_prev,C,Susp,PredCell,GetGoal),
3353 global_ground_store_name(C,StoreName),
3354 make_get_store_goal(StoreName,Store,GetStoreGoal),
3355 make_update_store_goal(StoreName,Tail,UpdateStoreGoal),
3356 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,_,SetGoal1),
3357 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,PredCell,SetGoal2),
3362 GetStoreGoal, % nb_getval(StoreName,Store),
3365 ( Tail = [NextSusp|_] ->
3371 PredCell = [_,_|Tail],
3372 setarg(2,PredCell,Tail),
3373 ( Tail = [NextSusp|_] ->
3381 % global_ground_store_name(C,StoreName),
3382 % make_get_store_goal(StoreName,Store,GetStoreGoal),
3383 % make_update_store_goal(StoreName,NStore,UpdateStoreGoal),
3386 % GetStoreGoal, % nb_getval(StoreName,Store),
3387 % 'chr sbag_del_element'(Store,Susp,NStore),
3388 % UpdateStoreGoal % b_setval(StoreName,NStore)
3390 delete_constraint_body(var_assoc_store(VarIndex,AssocIndex),C,_,Susp,_,Body) :-
3391 get_target_module(Module),
3392 get_dynamic_suspension_term_field(argument(VarIndex),C,Susp,Variable,VariableGoal),
3393 get_dynamic_suspension_term_field(argument(AssocIndex),C,Susp,Key,KeyGoal),
3396 get_attr(Variable,Module,AssocStore),
3398 delete_assoc_store(AssocStore,Key,Susp)
3400 delete_constraint_body(global_singleton,C,_,_Susp,_,Body) :-
3401 global_singleton_store_name(C,StoreName),
3402 make_update_store_goal(StoreName,[],UpdateStoreGoal),
3405 UpdateStoreGoal % b_setval(StoreName,[])
3407 delete_constraint_body(multi_store(StoreTypes),C,Head,Susp,VarDict,Body) :-
3408 maplist(delete_constraint_body1(C,Head,Susp,VarDict),StoreTypes,Bodies),
3409 list2conj(Bodies,Body).
3410 delete_constraint_body1(C,Head,Susp,VarDict,StoreType,Body) :-
3411 delete_constraint_body(StoreType,C,Head,Susp,VarDict,Body).
3412 delete_constraint_body(identifier_store(Index),C,Head,Susp,VarDict,Body) :-
3413 get_suspension_argument_possibly_in_scope(Head,VarDict,Susp,Index,Variable,VariableGoal),
3414 get_identifier_size(ISize),
3415 functor(Struct,struct,ISize),
3416 get_identifier_index(C,Index,IIndex),
3417 arg(IIndex,Struct,Susps),
3421 'chr sbag_del_element'(Susps,Susp,NSusps),
3422 setarg(IIndex,Variable,NSusps)
3424 delete_constraint_body(type_indexed_identifier_store(Index,IndexType),C,Head,Susp,VarDict,Body) :-
3425 get_suspension_argument_possibly_in_scope(Head,VarDict,Susp,Index,Variable,VariableGoal),
3426 type_indexed_identifier_structure(IndexType,Struct),
3427 get_type_indexed_identifier_index(IndexType,C,Index,IIndex),
3428 arg(IIndex,Struct,Susps),
3432 'chr sbag_del_element'(Susps,Susp,NSusps),
3433 setarg(IIndex,Variable,NSusps)
3436 generate_multi_inthash_delete_constraint_bodies([],_,_,true).
3437 generate_multi_inthash_delete_constraint_bodies([Index|Indexes],FA,Susp,(Body,Bodies)) :-
3438 multi_hash_store_name(FA,Index,StoreName),
3439 multi_hash_key(FA,Index,Susp,KeyBody,Key),
3443 nb_getval(StoreName,Store),
3444 delete_iht(Store,Key,Susp)
3446 generate_multi_inthash_delete_constraint_bodies(Indexes,FA,Susp,Bodies).
3447 generate_multi_hash_delete_constraint_bodies([],_,_,_,_,true).
3448 generate_multi_hash_delete_constraint_bodies([Index|Indexes],C,Head,Susp,VarDict,(Body,Bodies)) :-
3449 multi_hash_store_name(C,Index,StoreName),
3450 multi_hash_key(C,Head,Index,Susp,VarDict,KeyBody,Key),
3451 make_get_store_goal(StoreName,Store,GetStoreGoal),
3452 ( chr_pp_flag(ht_removal,on)
3453 -> ht_prev_field(Index,PrevField),
3454 get_dynamic_suspension_term_field(PrevField,C,Susp,Prev,GetGoal),
3455 set_dynamic_suspension_term_field(PrevField,C,NextSusp,_,
3457 set_dynamic_suspension_term_field(PrevField,C,NextSusp,Prev,
3465 delete_first_ht(Store,Key,Values),
3466 ( Values = [NextSusp|_]
3470 ; Prev = [_,_|Values],
3471 setarg(2,Prev,Values),
3472 ( Values = [NextSusp|_]
3481 GetStoreGoal, % nb_getval(StoreName,Store),
3482 delete_ht(Store,Key,Susp)
3485 generate_multi_hash_delete_constraint_bodies(Indexes,FA,Head,Susp,VarDict,Bodies).
3487 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3490 module_initializer/1,
3491 module_initializers/1.
3493 module_initializers(G), module_initializer(Initializer) <=>
3494 G = (Initializer,Initializers),
3495 module_initializers(Initializers).
3497 module_initializers(G) <=>
3500 generate_attach_code(Constraints,[Enumerate|L]) :-
3501 enumerate_stores_code(Constraints,Enumerate),
3502 generate_attach_code(Constraints,L,T),
3503 module_initializers(Initializers),
3504 prolog_global_variables_code(PrologGlobalVariables),
3505 % Do not rename or the 'chr_initialization' predicate
3506 % without warning SSS
3507 T = [('$chr_initialization' :- Initializers),(:- initialization '$chr_initialization')|PrologGlobalVariables].
3509 generate_attach_code([],L,L).
3510 generate_attach_code([C|Cs],L,T) :-
3511 get_store_type(C,StoreType),
3512 generate_attach_code(StoreType,C,L,L1),
3513 generate_attach_code(Cs,L1,T).
3515 generate_attach_code(default,C,L,T) :-
3516 global_list_store_initialisation(C,L,T).
3517 generate_attach_code(multi_inthash(Indexes),C,L,T) :-
3518 multi_inthash_store_initialisations(Indexes,C,L,L1),
3519 multi_inthash_via_lookups(Indexes,C,L1,T).
3520 generate_attach_code(multi_hash(Indexes),C,L,T) :-
3521 multi_hash_store_initialisations(Indexes,C,L,L1),
3522 multi_hash_lookups(Indexes,C,L1,T).
3523 generate_attach_code(atomic_constants(Index,Constants,_),C,L,T) :-
3524 constants_initializers(C,Index,Constants),
3525 atomic_constants_code(C,Index,Constants,L,T).
3526 generate_attach_code(ground_constants(Index,Constants,_),C,L,T) :-
3527 constants_initializers(C,Index,Constants),
3528 ground_constants_code(C,Index,Constants,L,T).
3529 generate_attach_code(global_ground,C,L,T) :-
3530 global_ground_store_initialisation(C,L,T).
3531 generate_attach_code(var_assoc_store(_,_),_,L,L) :-
3532 use_auxiliary_module(chr_assoc_store).
3533 generate_attach_code(global_singleton,C,L,T) :-
3534 global_singleton_store_initialisation(C,L,T).
3535 generate_attach_code(multi_store(StoreTypes),C,L,T) :-
3536 multi_store_generate_attach_code(StoreTypes,C,L,T).
3537 generate_attach_code(identifier_store(Index),C,L,T) :-
3538 get_identifier_index(C,Index,IIndex),
3540 get_identifier_size(ISize),
3541 functor(Struct,struct,ISize),
3542 Struct =.. [_,Label|Stores],
3543 set_elems(Stores,[]),
3544 Clause1 = new_identifier(Label,Struct),
3545 functor(Struct2,struct,ISize),
3546 arg(1,Struct2,Label2),
3548 ( user:portray(Struct2) :-
3553 functor(Struct3,struct,ISize),
3554 arg(1,Struct3,Label3),
3555 Clause3 = identifier_label(Struct3,Label3),
3556 L = [Clause1,Clause2,Clause3|T]
3560 generate_attach_code(type_indexed_identifier_store(Index,IndexType),C,L,T) :-
3561 get_type_indexed_identifier_index(IndexType,C,Index,IIndex),
3563 identifier_store_initialization(IndexType,L,L1),
3564 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3565 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3566 get_type_indexed_identifier_size(IndexType,ISize),
3567 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3568 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3569 type_indexed_identifier_structure(IndexType,Struct),
3570 Struct =.. [_,Label|Stores],
3571 set_elems(Stores,[]),
3572 type_indexed_identifier_name(IndexType,new_identifier,Name1),
3573 Clause1 =.. [Name1,Label,Struct],
3574 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3575 Goal1 =.. [Name1,Label1b,S1b],
3576 type_indexed_identifier_structure(IndexType,Struct1b),
3577 Struct1b =.. [_,Label1b|Stores1b],
3578 set_elems(Stores1b,[]),
3579 Expansion1 = (S1b = Struct1b),
3580 Clause1b = user:goal_expansion(Goal1,Expansion1),
3581 % writeln(Clause1-Clause1b),
3582 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3583 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3584 type_indexed_identifier_structure(IndexType,Struct2),
3585 arg(1,Struct2,Label2),
3587 ( user:portray(Struct2) :-
3592 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3593 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3594 type_indexed_identifier_structure(IndexType,Struct3),
3595 arg(1,Struct3,Label3),
3596 type_indexed_identifier_name(IndexType,identifier_label,Name3),
3597 Clause3 =.. [Name3,Struct3,Label3],
3598 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3599 Goal3b =.. [Name3,S3b,L3b],
3600 type_indexed_identifier_structure(IndexType,Struct3b),
3601 arg(1,Struct3b,L3b),
3602 Expansion3b = (S3 = Struct3b),
3603 Clause3b = ( user:goal_expansion(Goal3b,Expansion3b) :- writeln(expanding)),
3604 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3605 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3606 identifier_store_name(IndexType,GlobalVariable),
3607 lookup_identifier_atom(IndexType,X,IX,LookupAtom),
3608 type_indexed_identifier_name(IndexType,new_identifier,NewIdentifierFunctor),
3609 NewIdentifierGoal =.. [NewIdentifierFunctor,X,IX],
3612 nb_getval(GlobalVariable,HT),
3613 ( lookup_ht(HT,X,[IX]) ->
3620 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3621 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3622 L1 = [(:- multifile goal_expansion/2),(:- dynamic goal_expansion/2),Clause1,Clause1b,Clause2,Clause3,Clause3b,Clause4|T]
3627 constants_initializers(C,Index,Constants) :-
3628 maplist(constant_initializer(C,Index),Constants).
3630 constant_initializer(C,Index,Constant) :-
3631 constants_store_name(C,Index,Constant,StoreName),
3632 module_initializer(nb_setval(StoreName,[])).
3634 lookup_identifier_atom(Key,X,IX,Atom) :-
3635 atom_concat('lookup_identifier_',Key,LookupFunctor),
3636 Atom =.. [LookupFunctor,X,IX].
3638 identifier_label_atom(IndexType,IX,X,Atom) :-
3639 type_indexed_identifier_name(IndexType,identifier_label,Name),
3640 Atom =.. [Name,IX,X].
3642 multi_store_generate_attach_code([],_,L,L).
3643 multi_store_generate_attach_code([ST|STs],C,L,T) :-
3644 generate_attach_code(ST,C,L,L1),
3645 multi_store_generate_attach_code(STs,C,L1,T).
3647 multi_inthash_store_initialisations([],_,L,L).
3648 multi_inthash_store_initialisations([Index|Indexes],FA,L,T) :-
3649 use_auxiliary_module(chr_integertable_store),
3650 multi_hash_store_name(FA,Index,StoreName),
3651 module_initializer((new_iht(HT),nb_setval(StoreName,HT))),
3652 % L = [(:- (chr_integertable_store:new_ht(HT),nb_setval(StoreName,HT)) )|L1],
3654 multi_inthash_store_initialisations(Indexes,FA,L1,T).
3655 multi_hash_store_initialisations([],_,L,L).
3656 multi_hash_store_initialisations([Index|Indexes],FA,L,T) :-
3657 use_auxiliary_module(chr_hashtable_store),
3658 multi_hash_store_name(FA,Index,StoreName),
3659 prolog_global_variable(StoreName),
3660 make_init_store_goal(StoreName,HT,InitStoreGoal),
3661 module_initializer((new_ht(HT),InitStoreGoal)),
3663 multi_hash_store_initialisations(Indexes,FA,L1,T).
3665 global_list_store_initialisation(C,L,T) :-
3667 global_list_store_name(C,StoreName),
3668 prolog_global_variable(StoreName),
3669 make_init_store_goal(StoreName,[],InitStoreGoal),
3670 module_initializer(InitStoreGoal)
3675 global_ground_store_initialisation(C,L,T) :-
3676 global_ground_store_name(C,StoreName),
3677 prolog_global_variable(StoreName),
3678 make_init_store_goal(StoreName,[],InitStoreGoal),
3679 module_initializer(InitStoreGoal),
3681 global_singleton_store_initialisation(C,L,T) :-
3682 global_singleton_store_name(C,StoreName),
3683 prolog_global_variable(StoreName),
3684 make_init_store_goal(StoreName,[],InitStoreGoal),
3685 module_initializer(InitStoreGoal),
3687 identifier_store_initialization(IndexType,L,T) :-
3688 use_auxiliary_module(chr_hashtable_store),
3689 identifier_store_name(IndexType,StoreName),
3690 prolog_global_variable(StoreName),
3691 make_init_store_goal(StoreName,HT,InitStoreGoal),
3692 module_initializer((new_ht(HT),InitStoreGoal)),
3696 multi_inthash_via_lookups([],_,L,L).
3697 multi_inthash_via_lookups([Index|Indexes],C,L,T) :-
3698 multi_hash_lookup_head(C,Index,Key,SuspsList,Head),
3699 multi_hash_lookup_body(C,inthash,Index,Key,SuspsList,Body),
3700 L = [(Head :- Body)|L1],
3701 multi_inthash_via_lookups(Indexes,C,L1,T).
3702 multi_hash_lookups([],_,L,L).
3703 multi_hash_lookups([Index|Indexes],C,L,T) :-
3704 multi_hash_lookup_head(C,Index,Key,SuspsList,Head),
3705 multi_hash_lookup_body(C,hash,Index,Key,SuspsList,Body),
3706 L = [(Head :- Body)|L1],
3707 multi_hash_lookups(Indexes,C,L1,T).
3709 multi_hash_lookup_head(ConstraintSymbol,Index,Key,SuspsList,Head) :-
3710 multi_hash_lookup_name(ConstraintSymbol,Index,Name),
3711 Head =.. [Name,Key,SuspsList].
3713 %% multi_hash_lookup_body(+ConstraintSymbol,+HashType,+Index,+Key,+SuspsList,-Goal) is det.
3715 % Returns goal that performs hash table lookup.
3716 multi_hash_lookup_body(ConstraintSymbol,HashType,Index,Key,SuspsList,Goal) :-
3718 get_store_type(ConstraintSymbol,multi_store(Stores)),
3719 ( memberchk(atomic_constants(Index,Constants,_),Stores) ->
3721 constants_store_name(ConstraintSymbol,Index,Key,StoreName),
3722 Goal = nb_getval(StoreName,SuspsList)
3724 constants_store_index_name(ConstraintSymbol,Index,IndexName),
3725 Lookup =.. [IndexName,Key,StoreName],
3726 Goal = (Lookup, nb_getval(StoreName,SuspsList))
3728 ; memberchk(ground_constants(Index,Constants,_),Stores) ->
3730 constants_store_name(ConstraintSymbol,Index,Key,StoreName),
3731 Goal = nb_getval(StoreName,SuspsList)
3733 constants_store_index_name(ConstraintSymbol,Index,IndexName),
3734 Lookup =.. [IndexName,Key,StoreName],
3735 Goal = (Lookup, nb_getval(StoreName,SuspsList))
3737 ; memberchk(multi_hash([Index]),Stores) ->
3738 multi_hash_store_name(ConstraintSymbol,Index,StoreName),
3739 make_get_store_goal(StoreName,HT,GetStoreGoal),
3740 ( HashType == hash, specialized_hash_term_call(ConstraintSymbol,Index,Key,Hash,HashCall) ->
3743 GetStoreGoal, % nb_getval(StoreName,HT),
3744 HashCall, % hash_term(Key,Hash),
3745 lookup_ht1(HT,Hash,Key,SuspsList)
3748 lookup_hash_call(HashType,HT,Key,SuspsList,Lookup),
3751 GetStoreGoal, % nb_getval(StoreName,HT),
3755 ; HashType == inthash ->
3756 multi_hash_store_name(ConstraintSymbol,Index,StoreName),
3757 make_get_store_goal(StoreName,HT,GetStoreGoal),
3758 lookup_hash_call(HashType,HT,Key,SuspsList,Lookup),
3761 GetStoreGoal, % nb_getval(StoreName,HT),
3764 % ; % chr_error(internal,'Index ~w for constraint ~w does not exist!\n',[Index,ConstraintSymbol])
3765 % find alternative index
3766 % -> SubIndex + RestIndex
3767 % -> SubKey + RestKeys
3768 % multi_hash_lookup_goal(ConstraintSymbol,HashType,SubIndex,SubKey,SuspsList,SubGoal),
3769 % instantiate rest goal?
3770 % Goal = (SubGoal,RestGoal)
3774 lookup_hash_call(hash,HT,Key,SuspsList,lookup_ht(HT,Key,SuspsList)).
3775 lookup_hash_call(inthash,HT,Key,SuspsList,lookup_iht(HT,Key,SuspsList)).
3777 specialized_hash_term_call(Constraint,Index,Key,Hash,Call) :-
3779 % This is based on a property of SWI-Prolog's
3780 % hash_term/2 predicate:
3781 % the hash value is stable over repeated invocations
3783 hash_term(Key,Hash),
3785 ; Index = [IndexPos],
3786 get_constraint_type(Constraint,ArgTypes),
3787 nth1(IndexPos,ArgTypes,Type),
3788 unalias_type(Type,NormalType),
3789 memberchk_eq(NormalType,[int,natural]) ->
3790 ( NormalType == int ->
3799 specialize_hash_term(Key,NewKey),
3801 Call = hash_term(NewKey,Hash)
3804 specialize_hash_term(Term,NewTerm) :-
3806 hash_term(Term,NewTerm)
3811 maplist(specialize_hash_term,Args,NewArgs),
3812 NewTerm =.. [F|NewArgs]
3815 multi_hash_lookup_goal(ConstraintSymbol,HashType,Index,Key,SuspsList,Goal) :-
3816 % format(' * lookup of ~w on ~w with ~w.\n',[ConstraintSymbol,Index,Key]),
3817 ( /* chr_pp_flag(experiment,off) ->
3820 actual_atomic_multi_hash_keys(ConstraintSymbol,Index,[Key])
3822 actual_ground_multi_hash_keys(ConstraintSymbol,Index,[Key])
3825 get_constraint_arg_type(ConstraintSymbol,Pos,chr_constants(_))
3829 actual_non_ground_multi_hash_key(ConstraintSymbol,Index)
3832 delay_phase_end(validate_store_type_assumptions,
3833 multi_hash_lookup_body(ConstraintSymbol,HashType,Index,Key,SuspsList,Goal)).
3835 :- chr_constraint actual_atomic_multi_hash_keys/3.
3836 :- chr_option(mode,actual_atomic_multi_hash_keys(+,+,?)).
3838 :- chr_constraint actual_ground_multi_hash_keys/3.
3839 :- chr_option(mode,actual_ground_multi_hash_keys(+,+,?)).
3841 :- chr_constraint actual_non_ground_multi_hash_key/2.
3842 :- chr_option(mode,actual_non_ground_multi_hash_key(+,+)).
3845 actual_atomic_multi_hash_keys(C,Index,Keys)
3846 ==> format('Keys: ~w - ~w : ~w\n', [C,Index,Keys]).
3848 actual_ground_multi_hash_keys(C,Index,Keys)
3849 ==> format('Keys: ~w - ~w : ~w\n', [C,Index,Keys]).
3851 actual_non_ground_multi_hash_key(C,Index)
3852 ==> format('Keys: ~w - ~w : N/A\n', [C,Index]).
3854 actual_atomic_multi_hash_keys(C,Index,Keys1), actual_atomic_multi_hash_keys(C,Index,Keys2)
3855 <=> append(Keys1,Keys2,Keys0),
3857 actual_atomic_multi_hash_keys(C,Index,Keys).
3859 actual_ground_multi_hash_keys(C,Index,Keys1), actual_atomic_multi_hash_keys(C,Index,Keys2)
3860 <=> append(Keys1,Keys2,Keys0),
3862 actual_ground_multi_hash_keys(C,Index,Keys).
3864 actual_ground_multi_hash_keys(C,Index,Keys1), actual_ground_multi_hash_keys(C,Index,Keys2)
3865 <=> append(Keys1,Keys2,Keys0),
3867 actual_ground_multi_hash_keys(C,Index,Keys).
3869 actual_non_ground_multi_hash_key(C,Index) \ actual_non_ground_multi_hash_key(C,Index)
3872 actual_non_ground_multi_hash_key(C,Index) \ actual_atomic_multi_hash_keys(C,Index,_)
3875 actual_non_ground_multi_hash_key(C,Index) \ actual_ground_multi_hash_keys(C,Index,_)
3878 %% multi_hash_lookup_name(+ConstraintSymbol,+Index,-Name)
3880 % Returns predicate name of hash table lookup predicate.
3881 multi_hash_lookup_name(F/A,Index,Name) :-
3885 atom_concat_list(Index,IndexName)
3887 atom_concat_list(['$via1_multi_hash_',F,'___',A,'-',IndexName],Name).
3889 multi_hash_store_name(F/A,Index,Name) :-
3890 get_target_module(Mod),
3894 atom_concat_list(Index,IndexName)
3896 atom_concat_list(['$chr_store_multi_hash_',Mod,'____',F,'___',A,'-',IndexName],Name).
3898 multi_hash_key(FA,Index,Susp,KeyBody,Key) :-
3899 ( ( integer(Index) ->
3904 get_dynamic_suspension_term_field(argument(I),FA,Susp,Key,KeyBody)
3906 sort(Index,Indexes),
3907 maplist(get_dynamic_suspension_term_field1(FA,Susp),Indexes,Keys,Bodies),
3909 list2conj(Bodies,KeyBody)
3912 get_dynamic_suspension_term_field1(FA,Susp,I,KeyI,Goal) :-
3913 get_dynamic_suspension_term_field(argument(I),FA,Susp,KeyI,Goal).
3915 multi_hash_key(C,Head,Index,Susp,VarDict,KeyBody,Key) :-
3916 ( ( integer(Index) ->
3921 get_suspension_argument_possibly_in_scope(Head,VarDict,Susp,I,Key,KeyBody)
3923 sort(Index,Indexes),
3924 maplist(get_suspension_argument_possibly_in_scope(Head,VarDict,Susp),Indexes,Keys,Bodies),
3926 list2conj(Bodies,KeyBody)
3929 get_suspension_argument_possibly_in_scope(Head,VarDict,Susp,Index,Arg,Goal) :-
3930 arg(Index,Head,OriginalArg),
3931 ( lookup_eq(VarDict,OriginalArg,Arg) ->
3936 get_dynamic_suspension_term_field(argument(Index),C,Susp,Arg,Goal)
3939 multi_hash_key_direct(FA,Index,Susp,Key,UsedVars) :-
3940 ( ( integer(Index) ->
3947 sort(Index,Indexes),
3948 pairup(Indexes,Keys,UsedVars),
3952 multi_hash_key_args(Index,Head,KeyArgs) :-
3954 arg(Index,Head,Arg),
3957 sort(Index,Indexes),
3958 term_variables(Head,Vars),
3959 maplist(arg1(Head),Indexes,KeyArgs)
3962 %-------------------------------------------------------------------------------
3963 atomic_constants_code(C,Index,Constants,L,T) :-
3964 constants_store_index_name(C,Index,IndexName),
3965 maplist(atomic_constant_code(C,Index,IndexName),Constants,Clauses),
3966 append(Clauses,T,L).
3968 atomic_constant_code(C,Index,IndexName,Constant,Clause) :-
3969 constants_store_name(C,Index,Constant,StoreName),
3970 Clause =.. [IndexName,Constant,StoreName].
3972 %-------------------------------------------------------------------------------
3973 ground_constants_code(C,Index,Terms,L,T) :-
3974 constants_store_index_name(C,Index,IndexName),
3975 maplist(constants_store_name(C,Index),Terms,StoreNames),
3977 replicate(N,[],More),
3978 trie_index([Terms|More],StoreNames,IndexName,L,T).
3980 constants_store_name(F/A,Index,Term,Name) :-
3981 get_target_module(Mod),
3982 term_to_atom(Term,Constant),
3983 term_to_atom(Index,IndexAtom),
3984 atom_concat_list(['$chr_store_constants_',Mod,'____',F,'___',A,'___',IndexAtom,'___',Constant],Name).
3986 constants_store_index_name(F/A,Index,Name) :-
3987 get_target_module(Mod),
3988 term_to_atom(Index,IndexAtom),
3989 atom_concat_list(['$chr_store_constants_',Mod,'____',F,'___',A,'___',IndexAtom],Name).
3991 % trie index code {{{
3992 trie_index([Patterns|MorePatterns],Results,Prefix,Clauses,Tail) :-
3993 trie_step(Patterns,Prefix,Prefix,MorePatterns,Results,Clauses,Tail).
3995 trie_step([],_,_,[],[],L,L) :- !.
3996 % length MorePatterns == length Patterns == length Results
3997 trie_step(Patterns,Symbol,Prefix,MorePatterns,Results,Clauses,T) :-
3998 MorePatterns = [List|_],
4000 aggregate_all(set(F/A),
4001 ( member(Pattern,Patterns),
4002 functor(Pattern,F,A)
4006 trie_step_cases(FAs,N1,Patterns,MorePatterns,Results,Symbol,Prefix,Clauses,T).
4008 trie_step_cases([],_,_,_,_,_,_,Clauses,Clauses).
4009 trie_step_cases([FA|FAs],N,Pattern,MorePatterns,Results,Symbol,Prefix,Clauses,Tail) :-
4010 trie_step_case(FA,N,Pattern,MorePatterns,Results,Symbol,Prefix,Clauses,Clauses1),
4011 trie_step_cases(FAs,N,Pattern,MorePatterns,Results,Symbol,Prefix,Clauses1,Tail).
4013 trie_step_case(F/A,N,Patterns,MorePatterns,Results,Symbol,Prefix,[Clause|List],Tail) :-
4014 Clause = (Head :- Body),
4015 /* Head = Symbol(IndexPattern,V2,...,Vn,Result) */
4017 functor(Head,Symbol,N1),
4018 arg(1,Head,IndexPattern),
4019 Head =.. [_,_|RestArgs],
4020 once(append(Vs,[Result],RestArgs)),
4021 /* IndexPattern = F() */
4022 functor(IndexPattern,F,A),
4023 IndexPattern =.. [_|Args],
4024 append(Args,RestArgs,RecArgs),
4025 ( RecArgs == [Result] ->
4026 /* nothing more to match on */
4029 rec_cases(Patterns,_,Results,F/A,_,_,MoreResults),
4030 MoreResults = [Result]
4031 ; /* more things to match on */
4032 rec_cases(Patterns,MorePatterns,Results,F/A,Cases,MoreCases,MoreResults),
4033 ( MoreCases = [OneMoreCase] ->
4034 /* only one more thing to match on */
4037 append([Cases,OneMoreCase,MoreResults],RecArgs)
4039 /* more than one thing to match on */
4043 pairup(Cases,MoreCases,CasePairs),
4044 common_pattern(CasePairs,CommonPatternPair,DiffVars,Differences),
4045 append(Args,Vs,[First|Rest]),
4046 First-Rest = CommonPatternPair,
4047 % Body = RSymbol(DiffVars,Result)
4048 gensym(Prefix,RSymbol),
4049 append(DiffVars,[Result],RecCallVars),
4050 Body =.. [RSymbol|RecCallVars],
4051 findall(CH-CT,member([CH|CT],Differences),CPairs),
4052 once(pairup(CHs,CTs,CPairs)),
4053 trie_step(CHs,RSymbol,Prefix,CTs,MoreResults,List,Tail)
4057 rec_cases([],[],[],_,[],[],[]).
4058 rec_cases([Pattern|Patterns],[MorePattern|MorePatterns],[Result|Results],F/A,Cases,MoreCases,MoreResults) :-
4059 ( functor(Pattern,F,A), Pattern =.. [_|ArgPatterns], append(ArgPatterns,MorePattern,[Case|MoreCase]) ->
4060 Cases = [Case|NCases],
4061 MoreCases = [MoreCase|NMoreCases],
4062 MoreResults = [Result|NMoreResults],
4063 rec_cases(Patterns,MorePatterns,Results,F/A,NCases,NMoreCases,NMoreResults)
4065 rec_cases(Patterns,MorePatterns,Results,F/A,Cases,MoreCases,MoreResults)
4069 %% common_pattern(+terms,-term,-vars,-differences) is det.
4070 common_pattern(Ts,T,Vars,Differences) :-
4072 term_variables(T,Vars),
4073 findall(Vars,member(T,Ts),Differences).
4078 gct_(T1,T2,T,Dict0,Dict) :-
4089 maplist_dcg(gct_,Args1,Args2,Args,Dict0,Dict)
4091 /* T is a variable */
4092 ( lookup_eq(Dict0,T1+T2,T) ->
4093 /* we already have a variable for this difference */
4096 /* T is a fresh variable */
4097 Dict = [(T1+T2)-T|Dict0]
4102 fold1(P,[Head|Tail],Result) :-
4103 fold(Tail,P,Head,Result).
4106 fold([X|Xs],P,Acc,Res) :-
4108 fold(Xs,P,NAcc,Res).
4110 maplist_dcg(P,L1,L2,L) -->
4111 maplist_dcg_(L1,L2,L,P).
4113 maplist_dcg_([],[],[],_) --> [].
4114 maplist_dcg_([X|Xs],[Y|Ys],[Z|Zs],P) -->
4116 maplist_dcg_(Xs,Ys,Zs,P).
4117 %-------------------------------------------------------------------------------
4118 global_list_store_name(F/A,Name) :-
4119 get_target_module(Mod),
4120 atom_concat_list(['$chr_store_global_list_',Mod,'____',F,'___',A],Name).
4121 global_ground_store_name(F/A,Name) :-
4122 get_target_module(Mod),
4123 atom_concat_list(['$chr_store_global_ground_',Mod,'____',F,'___',A],Name).
4124 global_singleton_store_name(F/A,Name) :-
4125 get_target_module(Mod),
4126 atom_concat_list(['$chr_store_global_singleton_',Mod,'____',F,'___',A],Name).
4128 identifier_store_name(TypeName,Name) :-
4129 get_target_module(Mod),
4130 atom_concat_list(['$chr_identifier_lookup_',Mod,'____',TypeName],Name).
4132 :- chr_constraint prolog_global_variable/1.
4133 :- chr_option(mode,prolog_global_variable(+)).
4135 :- chr_constraint prolog_global_variables/1.
4136 :- chr_option(mode,prolog_global_variables(-)).
4138 prolog_global_variable(Name) \ prolog_global_variable(Name) <=> true.
4140 prolog_global_variables(List), prolog_global_variable(Name) <=>
4142 prolog_global_variables(Tail).
4143 prolog_global_variables(List) <=> List = [].
4146 prolog_global_variables_code(Code) :-
4147 prolog_global_variables(Names),
4151 maplist(wrap_in_functor('$chr_prolog_global_variable'),Names,NameDeclarations),
4152 Code = [(:- dynamic user:exception/3),
4153 (:- multifile user:exception/3),
4154 (user:exception(undefined_global_variable,Name,retry) :-
4156 '$chr_prolog_global_variable'(Name),
4157 '$chr_initialization'
4166 % prolog_global_variables_code([]).
4168 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4169 %sbag_member_call(S,L,sysh:mem(S,L)).
4170 sbag_member_call(S,L,'chr sbag_member'(S,L)).
4171 %sbag_member_call(S,L,member(S,L)).
4172 update_mutable_call(A,B,'chr update_mutable'( A, B)).
4173 %update_mutable_call(A,B,setarg(1, B, A)).
4174 create_mutable_call(Value,Mutable,true) :- Mutable = mutable(Value).
4175 % create_mutable_call(Value,Mutable,'chr create_mutable'(Value,Mutable)).
4177 % get_suspension_field(Constraint,Susp,FieldName,Value,(Get0,Get1)) :-
4178 % get_dynamic_suspension_term_field(FieldName,Constraint,Susp,Field,Get0),
4179 % create_get_mutable(Value,Field,Get1).
4181 % update_suspension_field(Constraint,Susp,FieldName,NewValue,(Get,Set)) :-
4182 % get_dynamic_suspension_term_field(FieldName,Constraint,Susp,Field,Get),
4183 % update_mutable_call(NewValue,Field,Set).
4185 % get_update_suspension_field(Constraint,Susp,FieldName,Value,NewValue,Get0,Get1,Set) :-
4186 % get_dynamic_suspension_term_field(FieldName,Constraint,Susp,Field,Get0),
4187 % create_get_mutable_ref(Value,Field,Get1),
4188 % update_mutable_call(NewValue,Field,Set).
4190 % create_static_suspension_field(Constraint,Susp,FieldName,Value,Create) :-
4191 % get_static_suspension_term_field(FieldName,Constraint,Susp,Field),
4192 % create_mutable_call(Value,Field,Create).
4194 % get_static_suspension_field(Constraint,Susp,FieldName,Value,Get) :-
4195 % get_static_suspension_term_field(FieldName,Constraint,Susp,Field),
4196 % create_get_mutable(Value,Field,Get).
4198 % get_update_static_suspension_field(Constraint,Susp,SuspTerm,FieldName,Value,NewValue,Get,Set) :-
4199 % get_static_suspension_term_field(FieldName,Constraint,SuspTerm,Field),
4200 % create_get_mutable_ref(Value,Field,Get),
4201 % update_mutable_call(NewValue,Field,Set).
4203 get_suspension_field(Constraint,Susp,FieldName,Value,Get) :-
4204 get_dynamic_suspension_term_field(FieldName,Constraint,Susp,Value,Get).
4206 update_suspension_field(Constraint,Susp,FieldName,NewValue,Set) :-
4207 set_dynamic_suspension_term_field(FieldName,Constraint,Susp,NewValue,Set).
4209 get_update_suspension_field(Constraint,Susp,FieldName,Value,NewValue,true,Get,Set) :-
4210 get_dynamic_suspension_term_field(FieldName,Constraint,Susp,Value,Get),
4211 set_dynamic_suspension_term_field(FieldName,Constraint,Susp,NewValue,Set).
4213 create_static_suspension_field(Constraint,Susp,FieldName,Value,true) :-
4214 get_static_suspension_term_field(FieldName,Constraint,Susp,Value).
4216 get_static_suspension_field(Constraint,Susp,FieldName,Value,true) :-
4217 get_static_suspension_term_field(FieldName,Constraint,Susp,Value).
4219 get_update_static_suspension_field(Constraint,Susp,SuspTerm,FieldName,Value,NewValue,true,Set) :-
4220 get_static_suspension_term_field(FieldName,Constraint,SuspTerm,Value),
4221 set_dynamic_suspension_term_field(FieldName,Constraint,Susp,NewValue,Set).
4223 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4225 enumerate_stores_code(Constraints,Clause) :-
4226 Head = '$enumerate_constraints'(Constraint),
4227 enumerate_store_bodies(Constraints,Constraint,Bodies),
4228 list2disj(Bodies,Body),
4229 Clause = (Head :- Body).
4231 enumerate_store_bodies([],_,[]).
4232 enumerate_store_bodies([C|Cs],Constraint,L) :-
4234 get_store_type(C,StoreType),
4235 ( enumerate_store_body(StoreType,C,Suspension,SuspensionBody) ->
4238 chr_error(internal,'Could not generate enumeration code for constraint ~w.\n',[C])
4240 get_dynamic_suspension_term_field(arguments,C,Suspension,Arguments,DynamicGoal),
4242 Constraint0 =.. [F|Arguments],
4243 Body = (SuspensionBody, DynamicGoal, Constraint = Constraint0),
4248 enumerate_store_bodies(Cs,Constraint,T).
4250 enumerate_store_body(default,C,Susp,Body) :-
4251 global_list_store_name(C,StoreName),
4252 sbag_member_call(Susp,List,Sbag),
4253 make_get_store_goal(StoreName,List,GetStoreGoal),
4256 GetStoreGoal, % nb_getval(StoreName,List),
4259 % get_constraint_index(C,Index),
4260 % get_target_module(Mod),
4261 % get_max_constraint_index(MaxIndex),
4264 % 'chr default_store'(GlobalStore),
4265 % get_attr(GlobalStore,Mod,Attr)
4268 % NIndex is Index + 1,
4269 % sbag_member_call(Susp,List,Sbag),
4272 % arg(NIndex,Attr,List),
4276 % sbag_member_call(Susp,Attr,Sbag),
4279 % Body = (Body1,Body2).
4280 enumerate_store_body(multi_inthash([Index|_]),C,Susp,Body) :-
4281 multi_inthash_enumerate_store_body(Index,C,Susp,Body).
4282 enumerate_store_body(multi_hash([Index|_]),C,Susp,Body) :-
4283 multi_hash_enumerate_store_body(Index,C,Susp,Body).
4284 enumerate_store_body(atomic_constants(Index,Constants,Completeness),C,Susp,Body) :-
4285 Completeness == complete, % fail if incomplete
4286 maplist(enumerate_constant_store_body(C,Index,Susps),Constants,Disjuncts),
4287 list2disj(Disjuncts, Disjunction),
4288 Body = ( Disjunction, member(Susp,Susps) ).
4289 enumerate_constant_store_body(C,Index,Susps,Constant,nb_getval(StoreName,Susps)) :-
4290 constants_store_name(C,Index,Constant,StoreName).
4292 enumerate_store_body(ground_constants(Index,Constants,Completeness),C,Susp,Body) :-
4293 enumerate_store_body(atomic_constants(Index,Constants,Completeness),C,Susp,Body).
4294 enumerate_store_body(global_ground,C,Susp,Body) :-
4295 global_ground_store_name(C,StoreName),
4296 sbag_member_call(Susp,List,Sbag),
4297 make_get_store_goal(StoreName,List,GetStoreGoal),
4300 GetStoreGoal, % nb_getval(StoreName,List),
4303 enumerate_store_body(var_assoc_store(_,_),C,_,Body) :-
4305 enumerate_store_body(global_singleton,C,Susp,Body) :-
4306 global_singleton_store_name(C,StoreName),
4307 make_get_store_goal(StoreName,Susp,GetStoreGoal),
4310 GetStoreGoal, % nb_getval(StoreName,Susp),
4313 enumerate_store_body(multi_store(STs),C,Susp,Body) :-
4316 enumerate_store_body(ST,C,Susp,Body)
4318 enumerate_store_body(identifier_store(Index),C,Susp,Body) :-
4320 enumerate_store_body(type_indexed_identifier_store(Index,IndexType),C,Susp,Body) :-
4323 multi_inthash_enumerate_store_body(I,C,Susp,B) :-
4324 multi_hash_store_name(C,I,StoreName),
4327 nb_getval(StoreName,HT),
4330 multi_hash_enumerate_store_body(I,C,Susp,B) :-
4331 multi_hash_store_name(C,I,StoreName),
4332 make_get_store_goal(StoreName,HT,GetStoreGoal),
4335 GetStoreGoal, % nb_getval(StoreName,HT),
4339 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4348 :- chr_option(mode,prev_guard_list(+,+,+,+,+,+,+,+)).
4349 :- chr_option(mode,prev_guard_list(+,+,+,+,+,+)).
4350 :- chr_option(type_declaration,prev_guard_list(any,any,any,any,any,list)).
4351 :- chr_option(mode,simplify_guards(+)).
4352 :- chr_option(mode,set_all_passive(+)).
4354 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4355 % GUARD SIMPLIFICATION
4356 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4357 % If the negation of the guards of earlier rules entails (part of)
4358 % the current guard, the current guard can be simplified. We can only
4359 % use earlier rules with a head that matches if the head of the current
4360 % rule does, and which make it impossible for the current rule to match
4361 % if they fire (i.e. they shouldn't be propagation rules and their
4362 % head constraints must be subsets of those of the current rule).
4363 % At this point, we know for sure that the negation of the guard
4364 % of such a rule has to be true (otherwise the earlier rule would have
4365 % fired, because of the refined operational semantics), so we can use
4366 % that information to simplify the guard by replacing all entailed
4367 % conditions by true/0. As a consequence, the never-stored analysis
4368 % (in a further phase) will detect more cases of never-stored constraints.
4370 % e.g. c(X),d(Y) <=> X > 0 | ...
4371 % e(X) <=> X < 0 | ...
4372 % c(X) \ d(Y),e(Z) <=> X =< 0, Z >= 0, ... | ...
4376 guard_simplification :-
4377 ( chr_pp_flag(guard_simplification,on) ->
4378 precompute_head_matchings,
4384 % for every rule, we create a prev_guard_list where the last argument
4385 % eventually is a list of the negations of earlier guards
4386 rule(RuleNb,Rule) \ simplify_guards(RuleNb)
4388 Rule = pragma(rule(Head1,Head2,Guard,_B),ids(IDs1,IDs2),_Pragmas,_Name,RuleNb),
4389 append(Head1,Head2,Heads),
4390 make_head_matchings_explicit_not_negated(Heads,MatchingFreeHeads,Matchings),
4391 tree_set_empty(Done),
4392 multiple_occ_constraints_checked(Done),
4393 apply_guard_wrt_term(Heads,Guard,SubstitutedHeads),
4395 append(IDs1,IDs2,IDs),
4396 findall(tuple(C,O,RuleNb)-(-RuleNb),(member(ID,IDs),get_occurrence_from_id(C,O,RuleNb,ID)),HeapData),
4398 insert_list_q(HeapData,EmptyHeap,Heap),
4399 next_prev_rule(Heap,_,Heap1),
4400 next_prev_rule(Heap1,PrevRuleNb,NHeap),
4401 prev_guard_list(RuleNb,PrevRuleNb,NHeap,MatchingFreeHeads,Guard,[],Matchings,[SubstitutedHeads]),
4402 NextRule is RuleNb+1,
4403 simplify_guards(NextRule).
4405 next_prev_rule(Heap,RuleNb,NHeap) :-
4406 ( find_min_q(Heap,_-Priority) ->
4407 Priority = (-RuleNb),
4408 normalize_heap(Heap,Priority,NHeap)
4414 normalize_heap(Heap,Priority,NHeap) :-
4415 ( find_min_q(Heap,_-Priority) ->
4416 delete_min_q(Heap,Heap1,tuple(C,O,_)-_),
4419 get_occurrence(C,NO,RuleNb,_),
4420 insert_q(Heap1,tuple(C,NO,RuleNb)-(-RuleNb),Heap2)
4424 normalize_heap(Heap2,Priority,NHeap)
4434 % The negation of the guard of a non-propagation rule is added
4435 % if its kept head constraints are a subset of the kept constraints of
4436 % the rule we're working on, and its removed head constraints (at least one)
4437 % are a subset of the removed constraints.
4439 rule(PrevRuleNb,PrevRule) \ prev_guard_list(RuleNb,PrevRuleNb,Heap,CurrentHeads,G,GuardList,Matchings,GH)
4441 PrevRule = pragma(rule(H1,H2,PrevGuard,_B),_Ids,_Pragmas,_Name,_PrevRuleNb), % PrevRuleNb == _PrevRuleNb
4443 make_head_matchings_explicit(PrevRuleNb,MatchingFreeHeads,PrevMatchings),
4444 setof(Renaming,chr_translate:head_subset(MatchingFreeHeads,CurrentHeads,Renaming),Renamings)
4446 append(H1,H2,Heads),
4447 compute_derived_info(Renamings,PrevMatchings,MatchingFreeHeads,Heads,PrevGuard,Matchings,CurrentHeads,GH,DerivedInfo,GH_New1),
4448 append(GuardList,DerivedInfo,GL1),
4449 normalize_conj_list(GL1,GL),
4450 append(GH_New1,GH,GH1),
4451 normalize_conj_list(GH1,GH_New),
4452 next_prev_rule(Heap,PrevPrevRuleNb,NHeap),
4453 % PrevPrevRuleNb is PrevRuleNb-1,
4454 prev_guard_list(RuleNb,PrevPrevRuleNb,NHeap,CurrentHeads,G,GL,Matchings,GH_New).
4456 % if this isn't the case, we skip this one and try the next rule
4457 prev_guard_list(RuleNb,N,Heap,H,G,GuardList,M,GH)
4460 next_prev_rule(Heap,N1,NHeap),
4462 prev_guard_list(RuleNb,N1,NHeap,H,G,GuardList,M,GH)
4464 prev_guard_list(RuleNb,H,G,GuardList,M,GH)
4467 prev_guard_list(RuleNb,H,G,GuardList,M,GH)
4471 head_types_modes_condition(GH,H,TypeInfo),
4472 conj2list(TypeInfo,TI),
4473 term_variables(H,HeadVars),
4474 append([chr_pp_headvariables(HeadVars)|TI],GuardList,Info),
4475 normalize_conj_list(Info,InfoL),
4476 prev_guard_list(RuleNb,H,G,InfoL,M,[]).
4478 head_types_modes_condition([],H,true).
4479 head_types_modes_condition([GH|GHs],H,(TI1, TI2)) :-
4480 types_modes_condition(H,GH,TI1),
4481 head_types_modes_condition(GHs,H,TI2).
4485 % when all earlier guards are added or skipped, we simplify the guard.
4486 % if it's different from the original one, we change the rule
4488 prev_guard_list(RuleNb,H,G,GuardList,M,[]), rule(RuleNb,Rule)
4490 Rule = pragma(rule(Head1,Head2,G,B),Ids,Pragmas,Name,RuleNb),
4491 G \== true, % let's not try to simplify this ;)
4492 append(M,GuardList,Info),
4493 simplify_guard(G,B,Info,SimpleGuard,NB),
4496 rule(RuleNb,pragma(rule(Head1,Head2,SimpleGuard,NB),Ids,Pragmas,Name,RuleNb)),
4497 prev_guard_list(RuleNb,H,SimpleGuard,GuardList,M,[]).
4499 %% normalize_conj_list(+List,-NormalList) is det.
4501 % Removes =true= elements and flattens out conjunctions.
4503 normalize_conj_list(List,NormalList) :-
4504 list2conj(List,Conj),
4505 conj2list(Conj,NormalList).
4507 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4508 % AUXILIARY PREDICATES (GUARD SIMPLIFICATION)
4509 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4511 compute_derived_info([],_PrevMatchings,_MatchingFreeHeads,_Heads,_PrevGuard,_Matchings,_H,_GH,[],[]).
4512 compute_derived_info([Renaming1|RestRenamings],PrevMatchings,PrevMatchingFreeHeads,PrevHeads,PrevGuard,Matchings,H,GH,[DerivedInfo1|DerivedInfo2],[GH3|GH_New2]) :-
4513 copy_term(PrevMatchings-PrevGuard,FreshMatchings),
4514 variable_replacement(PrevMatchings-PrevGuard,FreshMatchings,ExtraRenaming),
4515 append(Renaming1,ExtraRenaming,Renaming2),
4516 list2conj(PrevMatchings,Match),
4517 negate_b(Match,HeadsDontMatch),
4518 make_head_matchings_explicit_not_negated2(PrevHeads,PrevMatchingFreeHeads,HeadsMatch),
4519 list2conj(HeadsMatch,HeadsMatchBut),
4520 term_variables(Renaming2,RenVars),
4521 term_variables(PrevMatchings-PrevGuard-HeadsMatch,MGVars),
4522 new_vars(MGVars,RenVars,ExtraRenaming2),
4523 append(Renaming2,ExtraRenaming2,Renaming),
4524 ( PrevGuard == true -> % true can't fail
4525 Info_ = HeadsDontMatch
4527 negate_b(PrevGuard,TheGuardFailed),
4528 Info_ = (HeadsDontMatch ; (HeadsMatchBut, TheGuardFailed))
4530 copy_with_variable_replacement(Info_,DerivedInfo1,Renaming),
4531 copy_with_variable_replacement(PrevGuard,RenamedG2,Renaming),
4532 copy_with_variable_replacement(PrevMatchings,RenamedMatchings_,Renaming),
4533 list2conj(RenamedMatchings_,RenamedMatchings),
4534 apply_guard_wrt_term(H,RenamedG2,GH2),
4535 apply_guard_wrt_term(GH2,RenamedMatchings,GH3),
4536 compute_derived_info(RestRenamings,PrevMatchings,PrevMatchingFreeHeads,PrevHeads,PrevGuard,Matchings,H,GH,DerivedInfo2,GH_New2).
4538 simplify_guard(G,B,Info,SG,NB) :-
4540 % writeq(guard_entailment:simplify_guards(Info,B,LG,SGL,NB)),nl,
4541 guard_entailment:simplify_guards(Info,B,LG,SGL,NB),
4546 new_vars([A|As],RV,ER) :-
4547 ( memberchk_eq(A,RV) ->
4550 ER = [A-NewA,NewA-A|ER2],
4554 %% head_subset(+Subset,+MultiSet,-Renaming) is nondet.
4556 % check if a list of constraints is a subset of another list of constraints
4557 % (multiset-subset), meanwhile computing a variable renaming to convert
4558 % one into the other.
4559 head_subset(H,Head,Renaming) :-
4560 head_subset(H,Head,Renaming,[],_).
4562 head_subset([],Remainder,Renaming,Renaming,Remainder).
4563 head_subset([X|Xs],MultiSet,Renaming,Acc,Remainder) :-
4564 head_member(MultiSet,X,NAcc,Acc,Remainder1),
4565 head_subset(Xs,Remainder1,Renaming,NAcc,Remainder).
4567 % check if A is in the list, remove it from Headleft
4568 head_member([X|Xs],A,Renaming,Acc,Remainder) :-
4569 ( variable_replacement(A,X,Acc,Renaming),
4572 Remainder = [X|RRemainder],
4573 head_member(Xs,A,Renaming,Acc,RRemainder)
4575 %-------------------------------------------------------------------------------%
4576 % memoing code to speed up repeated computation
4578 :- chr_constraint precompute_head_matchings/0.
4580 rule(RuleNb,PragmaRule), precompute_head_matchings ==>
4581 PragmaRule = pragma(rule(H1,H2,_G,_B),_Ids,_Pragmas,_Name,_PrevRuleNb),
4582 append(H1,H2,Heads),
4583 make_head_matchings_explicit_(Heads,MatchingFreeHeads,Matchings),
4584 copy_term_nat(MatchingFreeHeads-Matchings,A-B),
4585 make_head_matchings_explicit_memo_table(RuleNb,A,B).
4587 precompute_head_matchings <=> true.
4589 :- chr_constraint make_head_matchings_explicit_memo_table/3.
4590 :- chr_constraint make_head_matchings_explicit_memo_lookup/3.
4592 :- chr_option(mode,make_head_matchings_explicit_memo_table(+,?,?)).
4593 :- chr_option(mode,make_head_matchings_explicit_memo_lookup(+,?,?)).
4595 make_head_matchings_explicit_memo_table(RuleNb,NHeads,Matchings) \
4596 make_head_matchings_explicit_memo_lookup(RuleNb,Q1,Q2)
4600 make_head_matchings_explicit_memo_lookup(_,_,_) <=> fail.
4602 make_head_matchings_explicit(RuleNb,MatchingFreeHeads,Matchings) :-
4603 make_head_matchings_explicit_memo_lookup(RuleNb,A,B),
4604 copy_term_nat(A-B,MatchingFreeHeads-Matchings).
4605 %-------------------------------------------------------------------------------%
4607 make_head_matchings_explicit_(Heads,MatchingFreeHeads,Matchings) :-
4608 extract_arguments(Heads,Arguments),
4609 make_matchings_explicit(Arguments,FreeVariables,[],[],_,Matchings),
4610 substitute_arguments(Heads,FreeVariables,MatchingFreeHeads).
4612 make_head_matchings_explicit_not_negated(Heads,MatchingFreeHeads,Matchings) :-
4613 extract_arguments(Heads,Arguments),
4614 make_matchings_explicit_not_negated(Arguments,FreshVariables,Matchings),
4615 substitute_arguments(Heads,FreshVariables,MatchingFreeHeads).
4617 make_head_matchings_explicit_not_negated2(Heads,MatchingFreeHeads,Matchings) :-
4618 extract_arguments(Heads,Arguments1),
4619 extract_arguments(MatchingFreeHeads,Arguments2),
4620 make_matchings_explicit_not_negated(Arguments1,Arguments2,Matchings).
4622 %% extract_arguments(+ListOfConstraints,-ListOfVariables) is det.
4624 % Returns list of arguments of given list of constraints.
4625 extract_arguments([],[]).
4626 extract_arguments([Constraint|Constraints],AllArguments) :-
4627 Constraint =.. [_|Arguments],
4628 append(Arguments,RestArguments,AllArguments),
4629 extract_arguments(Constraints,RestArguments).
4631 %% substitute_arguments(+InListOfConstraints,ListOfVariables,-OutListOfConstraints) is det.
4633 % Substitutes arguments of constraints with those in the given list.
4635 substitute_arguments([],[],[]).
4636 substitute_arguments([Constraint|Constraints],Variables,[NConstraint|NConstraints]) :-
4637 functor(Constraint,F,N),
4638 split_at(N,Variables,Arguments,RestVariables),
4639 NConstraint =.. [F|Arguments],
4640 substitute_arguments(Constraints,RestVariables,NConstraints).
4642 make_matchings_explicit([],[],_,MC,MC,[]).
4643 make_matchings_explicit([Arg|Args],[NewVar|NewVars],VarAcc,MatchingCondition,MatchingConditionO,Matchings) :-
4645 ( memberchk_eq(Arg,VarAcc) ->
4646 list2disj(MatchingCondition,MatchingCondition_disj),
4647 Matchings = [(MatchingCondition_disj ; NewVar == Arg)|RestMatchings], % or only = ??
4650 Matchings = RestMatchings,
4652 NVarAcc = [Arg|VarAcc]
4654 MatchingCondition2 = MatchingCondition
4657 Arg =.. [F|RecArgs],
4658 make_matchings_explicit(RecArgs,RecVars,VarAcc,MatchingCondition,MatchingCondition_,RecMatchings),
4659 FlatArg =.. [F|RecVars],
4660 ( RecMatchings == [] ->
4661 Matchings = [functor(NewVar,F,A)|RestMatchings]
4663 list2conj(RecMatchings,ArgM_conj),
4664 list2disj(MatchingCondition,MatchingCondition_disj),
4665 ArgM_ = (NewVar \= FlatArg ; MatchingCondition_disj ; ArgM_conj),
4666 Matchings = [ functor(NewVar,F,A) , ArgM_|RestMatchings]
4668 MatchingCondition2 = [ NewVar \= FlatArg |MatchingCondition_],
4669 term_variables(Args,ArgVars),
4670 append(ArgVars,VarAcc,NVarAcc)
4672 make_matchings_explicit(Args,NewVars,NVarAcc,MatchingCondition2,MatchingConditionO,RestMatchings).
4675 %% make_matchings_explicit_not_negated(+ListOfTerms,-ListOfVariables,-ListOfMatchings) is det.
4677 % Returns list of new variables and list of pairwise unifications between given list and variables.
4679 make_matchings_explicit_not_negated([],[],[]).
4680 make_matchings_explicit_not_negated([X|Xs],[Var|Vars],Matchings) :-
4681 Matchings = [Var = X|RMatchings],
4682 make_matchings_explicit_not_negated(Xs,Vars,RMatchings).
4684 %% apply_guard_wrt_term(+ListOfConstraints,+Goal,-NewListOfConstraints) is det.
4686 % (Partially) applies substitutions of =Goal= to given list.
4688 apply_guard_wrt_term([],_Guard,[]).
4689 apply_guard_wrt_term([Term|RH],Guard,[NTerm|RGH]) :-
4691 apply_guard_wrt_variable(Guard,Term,NTerm)
4694 apply_guard_wrt_term(HArgs,Guard,NewHArgs),
4695 NTerm =.. [F|NewHArgs]
4697 apply_guard_wrt_term(RH,Guard,RGH).
4699 %% apply_guard_wrt_variable(+Goal,+Variable,-NVariable) is det.
4701 % (Partially) applies goal =Guard= wrt variable.
4703 apply_guard_wrt_variable((Guard1,Guard2),Variable,NVariable) :- !,
4704 apply_guard_wrt_variable(Guard1,Variable,NVariable1),
4705 apply_guard_wrt_variable(Guard2,NVariable1,NVariable).
4706 apply_guard_wrt_variable(Guard,Variable,NVariable) :-
4707 ( Guard = (X = Y), Variable == X ->
4709 ; Guard = functor(AVariable,Functor,Arity), Variable == AVariable, ground(Functor), ground(Arity) ->
4710 functor(NVariable,Functor,Arity)
4712 NVariable = Variable
4715 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4716 % ALWAYS FAILING HEADS
4717 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4719 rule(RuleNb,Rule) \ prev_guard_list(RuleNb,H,G,GuardList,M,[])
4721 chr_pp_flag(check_impossible_rules,on),
4722 Rule = pragma(rule(Head1,Head2,G,B),Ids,Pragmas,Name,RuleNb),
4723 append(M,GuardList,Info),
4724 guard_entailment:entails_guard(Info,fail)
4726 chr_warning(weird_program,'Heads will never match in ~@.\n\tThis rule will never fire!\n',[format_rule(Rule)]),
4727 set_all_passive(RuleNb).
4729 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4730 % HEAD SIMPLIFICATION
4731 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4733 % now we check the head matchings (guard may have been simplified meanwhile)
4734 prev_guard_list(RuleNb,H,G,GuardList,M,[]) \ rule(RuleNb,Rule)
4736 Rule = pragma(rule(Head1,Head2,G,B),Ids,Pragmas,Name,RuleNb),
4737 simplify_heads(M,GuardList,G,B,NewM,NewB),
4739 extract_arguments(Head1,VH1),
4740 extract_arguments(Head2,VH2),
4741 extract_arguments(H,VH),
4742 replace_some_heads(VH1,VH2,VH,NewM,H1,H2,G,B,NewB_),
4743 substitute_arguments(Head1,H1,NewH1),
4744 substitute_arguments(Head2,H2,NewH2),
4745 append(NewB,NewB_,NewBody),
4746 list2conj(NewBody,BodyMatchings),
4747 NewRule = pragma(rule(NewH1,NewH2,G,(BodyMatchings,B)),Ids,Pragmas,Name,RuleNb),
4748 (Head1 \== NewH1 ; Head2 \== NewH2 )
4750 rule(RuleNb,NewRule).
4752 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4753 % AUXILIARY PREDICATES (HEAD SIMPLIFICATION)
4754 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4756 replace_some_heads(H1,H2,NH,[],H1,H2,G,Body,[]) :- !.
4757 replace_some_heads([],[H2|RH2],[NH|RNH],[M|RM],[],[H2_|RH2_],G,Body,NewB) :- !,
4760 replace_some_heads([],RH2,RNH,RM,[],RH2_,G,Body,NewB)
4762 (M = functor(X,F,A), NH == X ->
4768 H2 =.. [F|OrigArgs],
4769 use_same_args(OrigArgs,A_args,A_args_,G,Body,NewB1),
4772 replace_some_heads([],RH2,RNH,RM,[],RH2_,G,Body,NewB2),
4773 append(NewB1,NewB2,NewB)
4776 replace_some_heads([],RH2,RNH,[M|RM],[],RH2_,G,Body,NewB)
4780 replace_some_heads([H1|RH1],H2,[NH|RNH],[M|RM],[H1_|RH1_],H2_,G,Body,NewB) :- !,
4783 replace_some_heads(RH1,H2,RNH,RM,RH1_,H2_,G,Body,NewB)
4785 (M = functor(X,F,A), NH == X ->
4791 H1 =.. [F|OrigArgs],
4792 use_same_args(OrigArgs,A_args,A_args_,G,Body,NewB1),
4795 replace_some_heads(RH1,H2,RNH,RM,RH1_,H2_,G,Body,NewB2),
4796 append(NewB1,NewB2,NewB)
4799 replace_some_heads(RH1,H2,RNH,[M|RM],RH1_,H2_,G,Body,NewB)
4803 use_same_args([],[],[],_,_,[]).
4804 use_same_args([OA|ROA],[NA|RNA],[Out|ROut],G,Body,NewB) :-
4807 use_same_args(ROA,RNA,ROut,G,Body,NewB).
4808 use_same_args([OA|ROA],[NA|RNA],[Out|ROut],G,Body,NewB) :-
4810 ( common_variables(OA,Body) ->
4811 NewB = [NA = OA|NextB]
4816 use_same_args(ROA,RNA,ROut,G,Body,NextB).
4819 simplify_heads([],_GuardList,_G,_Body,[],[]).
4820 simplify_heads([M|RM],GuardList,G,Body,NewM,NewB) :-
4822 ( (nonvar(B) ; common_variables(B,RM-GuardList)),
4823 guard_entailment:entails_guard(GuardList,(A=B)) ->
4824 ( common_variables(B,G-RM-GuardList) ->
4828 ( common_variables(B,Body) ->
4829 NewB = [A = B|NextB]
4836 ( nonvar(B), functor(B,BFu,BAr),
4837 guard_entailment:entails_guard([functor(A,BFu,BAr)|GuardList],(A=B)) ->
4839 ( common_variables(B,G-RM-GuardList) ->
4842 NewM = [functor(A,BFu,BAr)|NextM]
4849 simplify_heads(RM,[M|GuardList],G,Body,NextM,NextB).
4851 common_variables(B,G) :-
4852 term_variables(B,BVars),
4853 term_variables(G,GVars),
4854 intersect_eq(BVars,GVars,L),
4858 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4859 % ALWAYS FAILING GUARDS
4860 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4862 set_all_passive(RuleNb), occurrence(_,_,RuleNb,ID,_) ==> passive(RuleNb,ID).
4863 set_all_passive(_) <=> true.
4865 prev_guard_list(RuleNb,H,G,GuardList,M,[]),rule(RuleNb,Rule)
4867 chr_pp_flag(check_impossible_rules,on),
4868 Rule = pragma(rule(_,_,G,_),_Ids,_Pragmas,_Name,RuleNb),
4870 % writeq(guard_entailment:entails_guard(GL,fail)),nl,
4871 guard_entailment:entails_guard(GL,fail)
4873 chr_warning(weird_program,'Guard will always fail in ~@.\n\tThis rule will never fire!\n',[format_rule(Rule)]),
4874 set_all_passive(RuleNb).
4878 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4879 % OCCURRENCE SUBSUMPTION
4880 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4883 first_occ_in_rule/4,
4886 :- chr_option(mode,first_occ_in_rule(+,+,+,+)).
4887 :- chr_option(mode,next_occ_in_rule(+,+,+,+,+,+)).
4889 :- chr_constraint multiple_occ_constraints_checked/1.
4890 :- chr_option(mode,multiple_occ_constraints_checked(+)).
4892 prev_guard_list(RuleNb,H,G,GuardList,M,[]),
4893 occurrence(C,O,RuleNb,ID,_),
4894 occurrence(C,O2,RuleNb,ID2,_),
4897 multiple_occ_constraints_checked(Done)
4900 chr_pp_flag(occurrence_subsumption,on),
4901 Rule = pragma(rule(H1,H2,_G,_B),_Ids,_Pragmas,_Name,_RuleNb), % RuleNb == _RuleNb
4903 \+ tree_set_memberchk(C,Done)
4905 first_occ_in_rule(RuleNb,C,O,ID),
4906 tree_set_add(Done,C,NDone),
4907 multiple_occ_constraints_checked(NDone).
4909 % Find first occurrence of constraint =C= in rule =RuleNb=
4910 occurrence(C,O,RuleNb,ID,_) \ first_occ_in_rule(RuleNb,C,O2,_)
4914 first_occ_in_rule(RuleNb,C,O,ID).
4916 first_occ_in_rule(RuleNb,C,O,ID_o1)
4919 functor(FreshHead,F,A),
4920 next_occ_in_rule(RuleNb,C,O,ID_o1,[],FreshHead).
4922 % Skip passive occurrences.
4923 passive(RuleNb,ID_o2), occurrence(C,O2,RuleNb,ID_o2,_) \ next_occ_in_rule(RuleNb,C,O,ID_o1,Cond,FH)
4927 next_occ_in_rule(RuleNb,C,O2,ID_o1,NewCond,FH).
4929 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)
4932 Rule = pragma(rule(H1,H2,G,B),ids(ID1,ID2),_Pragmas,_Name,RuleNb)
4934 append(H1,H2,Heads),
4935 add_failing_occ(Rule,Heads,H,ID_o1,ExtraCond,FH,M,C,Repl),
4936 ( ExtraCond == [chr_pp_void_info] ->
4937 next_occ_in_rule(RuleNb,C,O2,ID_o2,Cond,FH)
4939 append(ExtraCond,Cond,NewCond),
4940 add_failing_occ(Rule,Heads,H,ID_o2,CheckCond,FH,M,C,Repl2),
4941 copy_term(GuardList,FGuardList),
4942 variable_replacement(GuardList,FGuardList,GLRepl),
4943 copy_with_variable_replacement(GuardList,GuardList2,Repl),
4944 copy_with_variable_replacement(GuardList,GuardList3_,Repl2),
4945 copy_with_variable_replacement(GuardList3_,GuardList3,GLRepl),
4946 append(NewCond,GuardList2,BigCond),
4947 append(BigCond,GuardList3,BigCond2),
4948 copy_with_variable_replacement(M,M2,Repl),
4949 copy_with_variable_replacement(M,M3,Repl2),
4950 append(M3,BigCond2,BigCond3),
4951 append([chr_pp_active_constraint(FH)|M2],BigCond3,Info),
4952 list2conj(CheckCond,OccSubsum),
4953 copy_term((NewCond,BigCond2,Info,OccSubsum,FH),(NewCond2,BigCond2_,Info2,OccSubsum2,FH2)),
4954 ( OccSubsum \= chr_pp_void_info ->
4955 ( guard_entailment:entails_guard(Info2,OccSubsum2) ->
4956 passive(RuleNb,ID_o2)
4963 next_occ_in_rule(RuleNb,C,O2,ID_o2,NewCond,FH)
4967 next_occ_in_rule(RuleNb,C,O,ID,Cond,Args)
4971 prev_guard_list(RuleNb,H,G,GuardList,M,[]), multiple_occ_constraints_checked(Done)
4975 add_failing_occ(Rule,Heads,NH,ID_o1,FailCond,FH,M,C,Repl) :-
4976 Rule = pragma(rule(H1,H2,G,B),ids(ID1,ID2),_Pragmas,_Name,RuleNb),
4977 append(ID2,ID1,IDs),
4978 missing_partner_cond(Heads,NH,IDs,ID_o1,MPCond,H,C),
4979 copy_term((H,Heads,NH),(FH2,FHeads,NH2)),
4980 variable_replacement((H,Heads,NH),(FH2,FHeads,NH2),Repl),
4981 copy_with_variable_replacement(G,FG,Repl),
4982 extract_explicit_matchings(FG,FG2),
4983 negate_b(FG2,NotFG),
4984 copy_with_variable_replacement(MPCond,FMPCond,Repl),
4985 ( subsumes(FH,FH2) ->
4986 FailCond = [(NotFG;FMPCond)]
4988 % in this case, not much can be done
4989 % e.g. c(f(...)), c(g(...)) <=> ...
4990 FailCond = [chr_pp_void_info]
4993 missing_partner_cond([],[],[],ID_o1,fail,H2,C).
4994 missing_partner_cond([H|Hs],[H2|H2s],[ID_o1|IDs],ID_o1,Cond,H,C) :- !,
4995 missing_partner_cond(Hs,H2s,IDs,ID_o1,Cond,H,C).
4996 missing_partner_cond([H|Hs],[NH|NHs],[ID|IDs],ID_o1,Cond,H2,F/A) :-
4997 Cond = (chr_pp_not_in_store(H);Cond1),
4998 missing_partner_cond(Hs,NHs,IDs,ID_o1,Cond1,H2,F/A).
5000 extract_explicit_matchings((A,B),D) :- !,
5001 ( extract_explicit_matchings(A) ->
5002 extract_explicit_matchings(B,D)
5005 extract_explicit_matchings(B,E)
5007 extract_explicit_matchings(A,D) :- !,
5008 ( extract_explicit_matchings(A) ->
5014 extract_explicit_matchings(A=B) :-
5015 var(A), var(B), !, A=B.
5016 extract_explicit_matchings(A==B) :-
5017 var(A), var(B), !, A=B.
5019 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5021 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5027 get_type_definition/2,
5028 get_constraint_type/2.
5031 :- chr_option(mode,type_definition(?,?)).
5032 :- chr_option(mode,get_type_definition(?,?)).
5033 :- chr_option(mode,type_alias(?,?)).
5034 :- chr_option(mode,constraint_type(+,+)).
5035 :- chr_option(mode,get_constraint_type(+,-)).
5037 assert_constraint_type(Constraint,ArgTypes) :-
5038 ( ground(ArgTypes) ->
5039 constraint_type(Constraint,ArgTypes)
5041 chr_error(type_error,'Declared argument types "~w" for constraint "~w" must be ground!\n',[ArgTypes,Constraint])
5044 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5045 % Consistency checks of type aliases
5047 type_alias(T,T2) <=>
5048 nonvar(T),nonvar(T2),functor(T,F,A),functor(T2,F,A),
5049 copy_term((T,T2),(X,Y)),oneway_unification(Y,X) |
5050 chr_error(type_error,'Cyclic alias definition: "~w".\n',[(T == T2)]).
5052 type_alias(T1,A1), type_alias(T2,A2) <=>
5053 nonvar(T1),nonvar(T2),functor(T1,F,A),functor(T2,F,A),
5055 copy_term_nat(T1,T1_),
5056 copy_term_nat(T2,T2_),
5058 chr_error(type_error,
5059 '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_]).
5061 type_alias(T,B) \ type_alias(X,T2) <=>
5062 nonvar(T),nonvar(T2),functor(T,F,A),functor(T2,F,A),
5063 copy_term_nat((X,T2,T,B),(X2,T3,T1,D1)),oneway_unification(T3,T1) |
5064 % chr_info(type_information,'Inferring `~w\' from `~w\' and `~w\'.\n',[X2==D1,X==T2,T==B]),
5067 oneway_unification(X,Y) :-
5068 term_variables(X,XVars),
5069 chr_runtime:lockv(XVars),
5071 chr_runtime:unlockv(XVars).
5073 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5074 % Consistency checks of type definitions
5076 type_definition(T1,_), type_definition(T2,_)
5078 functor(T1,F,A), functor(T2,F,A)
5080 chr_error(type_error,'Multiple definitions for type: ~w/~w.\n',[F,A]).
5082 type_definition(T1,_), type_alias(T2,_)
5084 functor(T1,F,A), functor(T2,F,A)
5086 chr_error(type_error,'Multiple definitions for type, once in a type definition and once as a type alias: ~w/~w.\n',[F,A]).
5088 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5089 %% get_type_definition(+Type,-Definition) is semidet.
5090 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5092 get_type_definition(T,Def)
5096 chr_error(type_error,'Non-ground type in constraint definition: "~w".\n',[T]).
5098 type_alias(T,D) \ get_type_definition(T2,Def)
5100 nonvar(T),nonvar(T2),functor(T,F,A),functor(T2,F,A),
5101 copy_term_nat((T,D),(T1,D1)),T1=T2
5103 ( get_type_definition(D1,Def) ->
5106 chr_error(type_error,'Could not find type definition for "~w" (accessed via alias "~w").\n',[D1,T1]), fail
5109 type_definition(T,D) \ get_type_definition(T2,Def)
5111 nonvar(T),nonvar(T2),functor(T,F,A),functor(T2,F,A),
5112 copy_term_nat((T,D),(T1,D1)),T1=T2
5116 get_type_definition(Type,Def)
5118 atomic_builtin_type(Type,_,_)
5122 get_type_definition(Type,Def)
5124 compound_builtin_type(Type,_,_,_)
5128 get_type_definition(X,Y) <=> fail.
5130 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5131 %% get_type_definition_det(+Type,-Definition) is det.
5132 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5133 get_type_definition_det(Type,Definition) :-
5134 ( get_type_definition(Type,Definition) ->
5137 chr_error(type,'Could not find type definition for type `~w\'.\n',[Type])
5140 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5141 %% get_constraint_type(+ConstraintSymbol,-Types) is semidet.
5143 % Return argument types of =ConstraintSymbol=, but fails if none where
5145 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5146 constraint_type(C,T) \ get_constraint_type(C,Type) <=> Type = T.
5147 get_constraint_type(_,_) <=> fail.
5149 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5150 %% get_constraint_type_det(+ConstraintSymbol,-Types) is det.
5152 % Like =get_constraint_type/2=, but returns list of =any= types when
5153 % no types are declared.
5154 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5155 get_constraint_type_det(ConstraintSymbol,Types) :-
5156 ( get_constraint_type(ConstraintSymbol,Types) ->
5159 ConstraintSymbol = _ / N,
5160 replicate(N,any,Types)
5162 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5163 %% unalias_type(+Alias,-Type) is det.
5165 % Follows alias chain until base type is reached.
5166 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5167 :- chr_constraint unalias_type/2.
5170 unalias_type(Alias,BaseType)
5177 type_alias(AliasProtoType,ProtoType) \ unalias_type(Alias,BaseType)
5179 nonvar(AliasProtoType),
5181 functor(AliasProtoType,F,A),
5183 copy_term_nat((AliasProtoType,ProtoType),(AliasInstance,Type)),
5184 Alias = AliasInstance
5186 unalias_type(Type,BaseType).
5188 unalias_type_definition @
5189 type_definition(ProtoType,Definition) \ unalias_type(Alias,BaseType)
5193 functor(ProtoType,F,A),
5198 unalias_atomic_builtin @
5199 unalias_type(Alias,BaseType)
5201 atomic_builtin_type(Alias,_,_)
5205 unalias_compound_builtin @
5206 unalias_type(Alias,BaseType)
5208 compound_builtin_type(Alias,_,_,_)
5212 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5213 %% types_modes_condition(+Heads,+UnrollHeads,-Condition) is det.
5214 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5215 :- chr_constraint types_modes_condition/3.
5216 :- chr_option(mode,types_modes_condition(+,+,?)).
5217 :- chr_option(type_declaration,types_modes_condition(list,list,goal)).
5219 types_modes_condition([],[],T) <=> T=true.
5221 constraint_mode(F/A,Modes) \ types_modes_condition([Head|Heads],[UnrollHead|UnrollHeads],Condition)
5226 Condition = (ModesCondition, TypesCondition, RestCondition),
5227 modes_condition(Modes,Args,ModesCondition),
5228 get_constraint_type_det(F/A,Types),
5229 UnrollHead =.. [_|RealArgs],
5230 types_condition(Types,Args,RealArgs,Modes,TypesCondition),
5231 types_modes_condition(Heads,UnrollHeads,RestCondition).
5233 types_modes_condition([Head|_],_,_)
5236 chr_error(internal,'Mode information missing for ~w.\n',[F/A]).
5239 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5240 %% modes_condition(+Modes,+Args,-Condition) is det.
5242 % Return =Condition= on =Args= that checks =Modes=.
5243 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5244 modes_condition([],[],true).
5245 modes_condition([Mode|Modes],[Arg|Args],Condition) :-
5247 Condition = ( ground(Arg) , RCondition )
5249 Condition = ( var(Arg) , RCondition )
5251 Condition = RCondition
5253 modes_condition(Modes,Args,RCondition).
5255 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5256 %% types_condition(+Types,+Args,+UnrollArgs,+Modes,-Condition) is det.
5258 % Return =Condition= on =Args= that checks =Types= given =Modes=.
5259 % =UnrollArgs= controls the depth of type definition unrolling.
5260 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5261 types_condition([],[],[],[],true).
5262 types_condition([Type|Types],[Arg|Args],[UnrollArg|UnrollArgs],[Mode|Modes],(DisjTypeConditionList,RCondition)) :-
5264 TypeConditionList = [true] % TypeConditionList = [var(Arg)] already encoded in modes_condition
5266 get_type_definition_det(Type,Def),
5267 type_condition(Def,Arg,UnrollArg,Mode,TypeConditionList1),
5269 TypeConditionList = TypeConditionList1
5271 TypeConditionList = [(\+ ground(Arg))|TypeConditionList1]
5274 list2disj(TypeConditionList,DisjTypeConditionList),
5275 types_condition(Types,Args,UnrollArgs,Modes,RCondition).
5277 type_condition([],_,_,_,[]).
5278 type_condition([DefCase|DefCases],Arg,UnrollArg,Mode,[Condition|Conditions]) :-
5280 chr_error(type,'Unexpected variable type in type definition!\n',[]) % Condition = true
5281 ; atomic_builtin_type(DefCase,Arg,Condition) ->
5283 ; compound_builtin_type(DefCase,Arg,Condition,_) ->
5286 type_def_case_condition(DefCase,Arg,UnrollArg,Mode,Condition)
5288 type_condition(DefCases,Arg,UnrollArg,Mode,Conditions).
5290 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5291 :- chr_type atomic_builtin_type ---> any
5298 ; chr_identifier(any)
5299 ; /* all possible values are given */
5301 ; /* all possible values appear in rule heads;
5302 to distinguish between multiple chr_constants
5305 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5307 atomic_builtin_type(any,_Arg,true).
5308 atomic_builtin_type(dense_int,Arg,(integer(Arg),Arg>=0)).
5309 atomic_builtin_type(int,Arg,integer(Arg)).
5310 atomic_builtin_type(number,Arg,number(Arg)).
5311 atomic_builtin_type(float,Arg,float(Arg)).
5312 atomic_builtin_type(natural,Arg,(integer(Arg),Arg>=0)).
5313 atomic_builtin_type(chr_identifier,_Arg,true).
5315 compound_builtin_type(chr_constants(_),_Arg,true,true).
5316 compound_builtin_type(chr_identifier(_),_Arg,true,true).
5317 compound_builtin_type(chr_enum(Constants),Arg,(ground(Arg), memberchk(Arg,Constants)),
5318 once(( member(Constant,Constants),
5319 unifiable(Arg,Constant,_)
5324 type_def_case_condition(DefCase,Arg,UnrollArg,Mode,Condition) :-
5325 ( nonvar(DefCase) ->
5326 functor(DefCase,F,A),
5328 Condition = (Arg = DefCase)
5330 Condition = functor(Arg,F,A)
5331 ; functor(UnrollArg,F,A) ->
5332 Condition = (functor(Arg,F,A),Arg=Template,ArgsCondition),
5333 DefCase =.. [_|ArgTypes],
5334 UnrollArg =.. [_|UnrollArgs],
5335 functor(Template,F,A),
5336 Template =.. [_|TemplateArgs],
5337 replicate(A,Mode,ArgModes),
5338 types_condition(ArgTypes,TemplateArgs,UnrollArgs,ArgModes,ArgsCondition)
5340 Condition = functor(Arg,F,A)
5343 chr_error(internal,'Illegal type definition (must be nonvar).\n',[])
5347 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5348 % STATIC TYPE CHECKING
5349 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5350 % Checks head constraints and CHR constraint calls in bodies.
5353 % - type clashes involving built-in types
5354 % - Prolog built-ins in guard and body
5355 % - indicate position in terms in error messages
5356 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5358 static_type_check/0.
5361 % 1. Check the declared types
5363 constraint_type(Constraint,ArgTypes), static_type_check
5366 ( member(ArgType,ArgTypes), sub_term(ArgType,Type) ),
5367 ( get_type_definition(Type,_) ->
5370 chr_error(type_error,'Undefined type "~w" used in type declaration of "~w".\n',[Type,Constraint])
5374 % 2. Check the rules
5376 :- chr_type type_error_src ---> head(any) ; body(any).
5378 rule(_,Rule), static_type_check
5380 copy_term_nat(Rule,RuleCopy),
5381 RuleCopy = pragma(rule(Head1,Head2,G,Body),ids(IDs1,IDs2),Pragmas,Name,RuleNb),
5384 ( static_type_check_heads(Head1),
5385 static_type_check_heads(Head2),
5386 conj2list(Body,GoalList),
5387 static_type_check_body(GoalList)
5390 ( Error = invalid_functor(Src,Term,Type) ->
5391 chr_error(type_error,'Invalid functor in ~@ of ~@:\n\t\tfound `~w\',\n\t\texpected type `~w\'!\n',
5392 [chr_translate:format_src(Src),format_rule(Rule),Term,Type])
5393 ; Error = type_clash(Var,Src1,Src2,Type1,Type2) ->
5394 chr_error(type_error,'Type clash for variable ~w in ~@:\n\t\texpected type ~w in ~@\n\t\texpected type ~w in ~@\n',
5395 [Var,format_rule(Rule),Type1,chr_translate:format_src(Src1),Type2,chr_translate:format_src(Src2)])
5398 fail % cleanup constraints
5404 static_type_check <=> true.
5406 static_type_check_heads([]).
5407 static_type_check_heads([Head|Heads]) :-
5408 static_type_check_head(Head),
5409 static_type_check_heads(Heads).
5411 static_type_check_head(Head) :-
5413 get_constraint_type_det(F/A,Types),
5415 maplist(static_type_check_term(head(Head)),Args,Types).
5417 static_type_check_body([]).
5418 static_type_check_body([Goal|Goals]) :-
5420 get_constraint_type_det(F/A,Types),
5422 maplist(static_type_check_term(body(Goal)),Args,Types),
5423 static_type_check_body(Goals).
5425 :- chr_constraint static_type_check_term/3.
5426 :- chr_option(mode,static_type_check_term(?,?,?)).
5427 :- chr_option(type_declaration,static_type_check_term(type_error_src,any,any)).
5429 static_type_check_term(Src,Term,Type)
5433 static_type_check_var(Src,Term,Type).
5434 static_type_check_term(Src,Term,Type)
5436 atomic_builtin_type(Type,Term,Goal)
5441 throw(type_error(invalid_functor(Src,Term,Type)))
5443 static_type_check_term(Src,Term,Type)
5445 compound_builtin_type(Type,Term,_,Goal)
5450 throw(type_error(invalid_functor(Src,Term,Type)))
5452 type_alias(AType,ADef) \ static_type_check_term(Src,Term,Type)
5457 copy_term_nat(AType-ADef,Type-Def),
5458 static_type_check_term(Src,Term,Def).
5460 type_definition(AType,ADef) \ static_type_check_term(Src,Term,Type)
5465 copy_term_nat(AType-ADef,Type-Variants),
5466 functor(Term,TF,TA),
5467 ( member(Variant,Variants), functor(Variant,TF,TA) ->
5469 Variant =.. [_|Types],
5470 maplist(static_type_check_term(Src),Args,Types)
5472 throw(type_error(invalid_functor(Src,Term,Type)))
5475 static_type_check_term(Src,Term,Type)
5477 chr_error(internal,'Undefined type ~w while type checking term ~w in ~@.\n',[Type,Term,chr_translate:format_src(Src)]).
5479 :- chr_constraint static_type_check_var/3.
5480 :- chr_option(mode,static_type_check_var(?,-,?)).
5481 :- chr_option(type_declaration,static_type_check_term(type_error_src,any,any)).
5483 type_alias(AType,ADef) \ static_type_check_var(Src,Var,Type)
5488 copy_term_nat(AType-ADef,Type-Def),
5489 static_type_check_var(Src,Var,Def).
5491 static_type_check_var(Src,Var,Type)
5493 atomic_builtin_type(Type,_,_)
5495 static_atomic_builtin_type_check_var(Src,Var,Type).
5497 static_type_check_var(Src,Var,Type)
5499 compound_builtin_type(Type,_,_,_)
5504 static_type_check_var(Src1,Var,Type1), static_type_check_var(Src2,Var,Type2)
5508 throw(type_error(type_clash(Var,Src1,Src2,Type1,Type2))).
5510 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5511 %% static_atomic_builtin_type_check_var(+type_error_src,-Var,+atomic_builtin_type)
5512 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5513 :- chr_constraint static_atomic_builtin_type_check_var/3.
5514 :- chr_option(mode,static_type_check_var(?,-,+)).
5515 :- chr_option(type_declaration,static_type_check_term(type_error_src,any,atomic_builtin_type)).
5517 static_atomic_builtin_type_check_var(_,_,any) <=> true.
5518 static_atomic_builtin_type_check_var(_,Var,BuiltinType) \ static_atomic_builtin_type_check_var(_,Var,BuiltinType)
5521 static_atomic_builtin_type_check_var(_,Var,float) \ static_atomic_builtin_type_check_var(_,Var,number)
5524 static_atomic_builtin_type_check_var(_,Var,int) \ static_atomic_builtin_type_check_var(_,Var,number)
5527 static_atomic_builtin_type_check_var(_,Var,natural) \ static_atomic_builtin_type_check_var(_,Var,number)
5530 static_atomic_builtin_type_check_var(_,Var,dense_int) \ static_atomic_builtin_type_check_var(_,Var,number)
5533 static_atomic_builtin_type_check_var(_,Var,natural) \ static_atomic_builtin_type_check_var(_,Var,int)
5536 static_atomic_builtin_type_check_var(_,Var,dense_int) \ static_atomic_builtin_type_check_var(_,Var,int)
5539 static_atomic_builtin_type_check_var(_,Var,dense_int) \ static_atomic_builtin_type_check_var(_,Var,natural)
5542 static_atomic_builtin_type_check_var(Src1,Var,Type1), static_atomic_builtin_type_check_var(Src2,Var,Type2)
5544 throw(type_error(type_clash(Var,Src1,Src2,Type1,Type2))).
5546 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5547 %% format_src(+type_error_src) is det.
5548 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5549 format_src(head(Head)) :- format('head ~w',[Head]).
5550 format_src(body(Goal)) :- format('body goal ~w',[Goal]).
5552 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5553 % Dynamic type checking
5554 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5557 dynamic_type_check/0,
5558 dynamic_type_check_clauses/1,
5559 get_dynamic_type_check_clauses/1.
5561 generate_dynamic_type_check_clauses(Clauses) :-
5562 ( chr_pp_flag(debugable,on) ->
5564 get_dynamic_type_check_clauses(Clauses0),
5566 [('$dynamic_type_check'(Type,Term) :-
5567 throw(error(type_error(Type,Term),context(_,'CHR Runtime Type Error')))
5574 type_definition(T,D), dynamic_type_check
5576 copy_term_nat(T-D,Type-Definition),
5577 maplist(dynamic_type_check_clause(Type),Definition,DynamicChecks),
5578 dynamic_type_check_clauses(DynamicChecks).
5579 type_alias(A,B), dynamic_type_check
5581 copy_term_nat(A-B,Alias-Body),
5582 dynamic_type_check_alias_clause(Alias,Body,Clause),
5583 dynamic_type_check_clauses([Clause]).
5585 dynamic_type_check <=>
5587 ('$dynamic_type_check'(Type,Term) :- Goal),
5588 ( atomic_builtin_type(Type,Term,Goal) ; compound_builtin_type(Type,Term,Goal,_) ),
5591 dynamic_type_check_clauses(BuiltinChecks).
5593 dynamic_type_check_clause(T,DC,Clause) :-
5594 copy_term(T-DC,Type-DefinitionClause),
5595 functor(DefinitionClause,F,A),
5597 DefinitionClause =.. [_|DCArgs],
5598 Term =.. [_|TermArgs],
5599 maplist(dynamic_type_check_call,DCArgs,TermArgs,RecursiveCallList),
5600 list2conj(RecursiveCallList,RecursiveCalls),
5602 '$dynamic_type_check'(Type,Term) :-
5606 dynamic_type_check_alias_clause(Alias,Body,Clause) :-
5608 '$dynamic_type_check'(Alias,Term) :-
5609 '$dynamic_type_check'(Body,Term)
5612 dynamic_type_check_call(Type,Term,Call) :-
5613 % ( nonvar(Type), atomic_builtin_type(Type,Term,Goal) ->
5614 % Call = when(nonvar(Term),Goal)
5615 % ; nonvar(Type), compound_builtin_type(Type,Term,Goal) ->
5616 % Call = when(nonvar(Term),Goal)
5621 Call = when(nonvar(Term),once('$dynamic_type_check'(Type,Term)))
5626 dynamic_type_check_clauses(C1), dynamic_type_check_clauses(C2)
5629 dynamic_type_check_clauses(C).
5631 get_dynamic_type_check_clauses(Q), dynamic_type_check_clauses(C)
5634 get_dynamic_type_check_clauses(Q)
5638 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5640 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5641 % Some optimizations can be applied for atomic types...
5642 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5644 atomic_types_suspended_constraint(C) :-
5646 get_constraint_type(C,ArgTypes),
5647 get_constraint_mode(C,ArgModes),
5648 findall(I,between(1,N,I),Indexes),
5649 maplist(atomic_types_suspended_constraint(C),ArgTypes,ArgModes,Indexes).
5651 atomic_types_suspended_constraint(C,Type,Mode,Index) :-
5652 ( is_indexed_argument(C,Index) ->
5662 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5663 %% atomic_type(+Type) is semidet.
5665 % Succeeds when all values of =Type= are atomic.
5666 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5667 :- chr_constraint atomic_type/1.
5669 atomic_type(Type) <=> atomic_builtin_type(Type,_,_) | Type \== any.
5671 type_definition(TypePat,Def) \ atomic_type(Type)
5673 functor(Type,F,A), functor(TypePat,F,A)
5675 maplist(atomic,Def).
5677 type_alias(TypePat,Alias) \ atomic_type(Type)
5679 functor(Type,F,A), functor(TypePat,F,A)
5682 copy_term_nat(TypePat-Alias,Type-NType),
5685 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5686 %% enumerated_atomic_type(+Type,-Atoms) is semidet.
5688 % Succeeds when all values of =Type= are atomic
5689 % and the atom values are finitely enumerable.
5690 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5691 :- chr_constraint enumerated_atomic_type/2.
5693 enumerated_atomic_type(Type,_) <=> atomic_builtin_type(Type,_,_) | fail.
5695 type_definition(TypePat,Def) \ enumerated_atomic_type(Type,Atoms)
5697 functor(Type,F,A), functor(TypePat,F,A)
5699 maplist(atomic,Def),
5702 type_alias(TypePat,Alias) \ enumerated_atomic_type(Type,Atoms)
5704 functor(Type,F,A), functor(TypePat,F,A)
5707 copy_term_nat(TypePat-Alias,Type-NType),
5708 enumerated_atomic_type(NType,Atoms).
5709 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5712 stored/3, % constraint,occurrence,(yes/no/maybe)
5713 stored_completing/3,
5716 is_finally_stored/1,
5717 check_all_passive/2.
5719 :- chr_option(mode,stored(+,+,+)).
5720 :- chr_option(type_declaration,stored(any,int,storedinfo)).
5721 :- chr_type storedinfo ---> yes ; no ; maybe.
5722 :- chr_option(mode,stored_complete(+,+,+)).
5723 :- chr_option(mode,maybe_complementary_guards(+,+,?,?)).
5724 :- chr_option(mode,guard_list(+,+,+,+)).
5725 :- chr_option(mode,check_all_passive(+,+)).
5726 :- chr_option(type_declaration,check_all_passive(any,list)).
5728 % change yes in maybe when yes becomes passive
5729 passive(RuleNb,ID), occurrence(C,O,RuleNb,ID,_) \
5730 stored(C,O,yes), stored_complete(C,RO,Yesses)
5731 <=> O < RO | NYesses is Yesses - 1,
5732 stored(C,O,maybe), stored_complete(C,RO,NYesses).
5733 % change yes in maybe when not observed
5734 ai_not_observed(C,O) \ stored(C,O,yes), stored_complete(C,RO,Yesses)
5736 NYesses is Yesses - 1,
5737 stored(C,O,maybe), stored_complete(C,RO,NYesses).
5739 occurrence(_,_,RuleNb,ID,_), occurrence(C2,_,RuleNb,_,_), stored_complete(C2,RO,0), max_occurrence(C2,MO2)
5740 ==> RO =< MO2 | % C2 is never stored
5746 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5748 rule(RuleNb,Rule),passive(RuleNb,Id) ==>
5749 Rule = pragma(rule(Head1,Head2,G,B),ids([Id|IDs1],IDs2),Pragmas,Name,RuleNb) |
5750 append(IDs1,IDs2,I), check_all_passive(RuleNb,I).
5752 rule(RuleNb,Rule),passive(RuleNb,Id) ==>
5753 Rule = pragma(rule(Head1,Head2,G,B),ids([],[Id|IDs2]),Pragmas,Name,RuleNb) |
5754 check_all_passive(RuleNb,IDs2).
5756 passive(RuleNb,Id) \ check_all_passive(RuleNb,[Id|IDs]) <=>
5757 check_all_passive(RuleNb,IDs).
5759 rule(RuleNb,Rule) \ check_all_passive(RuleNb,[]) <=>
5760 chr_warning(weird_program,'All heads passive in ~@.\n\tThis rule never fires. Please check your program.\n',[format_rule(Rule)]).
5762 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5764 % collect the storage information
5765 stored(C,O,yes) \ stored_completing(C,O,Yesses)
5766 <=> NO is O + 1, NYesses is Yesses + 1,
5767 stored_completing(C,NO,NYesses).
5768 stored(C,O,maybe) \ stored_completing(C,O,Yesses)
5770 stored_completing(C,NO,Yesses).
5772 stored(C,O,no) \ stored_completing(C,O,Yesses)
5773 <=> stored_complete(C,O,Yesses).
5774 stored_completing(C,O,Yesses)
5775 <=> stored_complete(C,O,Yesses).
5777 stored_complete(C,O,Yesses), occurrence(C,O2,RuleNb,Id,_) ==>
5778 O2 > O | passive(RuleNb,Id).
5780 % decide whether a constraint is stored
5781 max_occurrence(C,MO), stored_complete(C,RO,0) \ is_stored(C)
5782 <=> RO =< MO | fail.
5783 is_stored(C) <=> true.
5785 % decide whether a constraint is suspends after occurrences
5786 max_occurrence(C,MO), stored_complete(C,RO,_) \ is_finally_stored(C)
5787 <=> RO =< MO | fail.
5788 is_finally_stored(C) <=> true.
5790 storage_analysis(Constraints) :-
5791 ( chr_pp_flag(storage_analysis,on) ->
5792 check_constraint_storages(Constraints)
5797 check_constraint_storages([]).
5798 check_constraint_storages([C|Cs]) :-
5799 check_constraint_storage(C),
5800 check_constraint_storages(Cs).
5802 check_constraint_storage(C) :-
5803 get_max_occurrence(C,MO),
5804 check_occurrences_storage(C,1,MO).
5806 check_occurrences_storage(C,O,MO) :-
5808 stored_completing(C,1,0)
5810 check_occurrence_storage(C,O),
5812 check_occurrences_storage(C,NO,MO)
5815 check_occurrence_storage(C,O) :-
5816 get_occurrence(C,O,RuleNb,ID),
5817 ( is_passive(RuleNb,ID) ->
5820 get_rule(RuleNb,PragmaRule),
5821 PragmaRule = pragma(rule(Heads1,Heads2,Guard,Body),ids(IDs1,IDs2),_,_,_),
5822 ( select2(ID,Head1,IDs1,Heads1,RIDs1,RHeads1) ->
5823 check_storage_head1(Head1,O,Heads1,Heads2,Guard)
5824 ; select2(ID,Head2,IDs2,Heads2,RIDs2,RHeads2) ->
5825 check_storage_head2(Head2,O,Heads1,Body)
5829 check_storage_head1(Head,O,H1,H2,G) :-
5834 % writeq(guard_entailment:entails_guard([chr_pp_headvariables(Head)],G)),nl,
5835 guard_entailment:entails_guard([chr_pp_headvariables(Head)],G),
5837 no_matching(L,[]) ->
5844 no_matching([X|Xs],Prev) :-
5846 \+ memberchk_eq(X,Prev),
5847 no_matching(Xs,[X|Prev]).
5849 check_storage_head2(Head,O,H1,B) :-
5853 ( H1 \== [], B == true )
5855 % \+ is_observed(F/A,O) % always fails because observation analysis has not been performed yet
5863 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5865 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5866 %% ____ _ ____ _ _ _ _
5867 %% | _ \ _ _| | ___ / ___|___ _ __ ___ _ __ (_) | __ _| |_(_) ___ _ __
5868 %% | |_) | | | | |/ _ \ | | / _ \| '_ ` _ \| '_ \| | |/ _` | __| |/ _ \| '_ \
5869 %% | _ <| |_| | | __/ | |__| (_) | | | | | | |_) | | | (_| | |_| | (_) | | | |
5870 %% |_| \_\\__,_|_|\___| \____\___/|_| |_| |_| .__/|_|_|\__,_|\__|_|\___/|_| |_|
5873 constraints_code(Constraints,Clauses) :-
5874 (chr_pp_flag(reduced_indexing,on),
5875 forall(C,Constraints,chr_translate:only_ground_indexed_arguments(C)) ->
5876 none_suspended_on_variables
5880 constraints_code1(Constraints,Clauses,[]).
5882 %===============================================================================
5883 :- chr_constraint constraints_code1/3.
5884 :- chr_option(mode,constraints_code1(+,+,+)).
5885 :- chr_option(type_declaration,constraints_code1(list,any,any)).
5886 %-------------------------------------------------------------------------------
5887 constraints_code1([],L,T) <=> L = T.
5888 constraints_code1([C|RCs],L,T)
5890 constraint_code(C,L,T1),
5891 constraints_code1(RCs,T1,T).
5892 %===============================================================================
5893 :- chr_constraint constraint_code/3.
5894 :- chr_option(mode,constraint_code(+,+,+)).
5895 %-------------------------------------------------------------------------------
5896 %% Generate code for a single CHR constraint
5897 constraint_code(Constraint, L, T)
5899 | ( (chr_pp_flag(debugable,on) ;
5900 is_stored(Constraint), ( has_active_occurrence(Constraint); chr_pp_flag(late_allocation,off)),
5901 ( may_trigger(Constraint) ;
5902 get_allocation_occurrence(Constraint,AO),
5903 get_max_occurrence(Constraint,MO), MO >= AO ) )
5905 constraint_prelude(Constraint,Clause),
5906 add_dummy_location(Clause,LocatedClause),
5907 L = [LocatedClause | L1]
5912 occurrences_code(Constraint,1,Id,NId,L1,L2),
5913 gen_cond_attach_clause(Constraint,NId,L2,T).
5915 %===============================================================================
5916 %% Generate prelude predicate for a constraint.
5917 %% f(...) :- f/a_0(...,Susp).
5918 constraint_prelude(F/A, Clause) :-
5919 vars_susp(A,Vars,Susp,VarsSusp),
5920 Head =.. [ F | Vars],
5921 make_suspension_continuation_goal(F/A,VarsSusp,Continuation),
5922 build_head(F,A,[0],VarsSusp,Delegate),
5923 ( chr_pp_flag(debugable,on) ->
5924 insert_constraint_goal(F/A,Susp,Vars,InsertCall),
5925 attach_constraint_atom(F/A,Vars2,Susp,AttachCall),
5926 delay_phase_end(validate_store_type_assumptions,chr_translate:update_suspension_field(F/A,Susp,state,inactive,Inactive)),
5927 insert_constraint_internal_constraint_goal(F/A, Vars2, Susp, Continuation, Vars,InsertGoal),
5929 ( get_constraint_type(F/A,ArgTypeList) ->
5930 maplist(dynamic_type_check_call,ArgTypeList,Vars,DynamicTypeCheckList),
5931 list2conj(DynamicTypeCheckList,DynamicTypeChecks)
5933 DynamicTypeChecks = true
5943 'chr debug_event'(insert(Head#Susp)),
5945 'chr debug_event'(call(Susp)),
5948 'chr debug_event'(fail(Susp)), !,
5952 'chr debug_event'(exit(Susp))
5954 'chr debug_event'(redo(Susp)),
5958 ; get_allocation_occurrence(F/A,0) ->
5959 gen_insert_constraint_internal_goal(F/A,Goal,VarsSusp,Vars,Susp),
5960 delay_phase_end(validate_store_type_assumptions,chr_translate:update_suspension_field(F/A,Susp,state,inactive,Inactive)),
5961 Clause = ( Head :- Goal, Inactive, Delegate )
5963 Clause = ( Head :- Delegate )
5966 make_suspension_continuation_goal(F/A,VarsSusp,Goal) :-
5967 ( may_trigger(F/A) ->
5968 build_head(F,A,[0],VarsSusp,Delegate),
5969 ( chr_pp_flag(debugable,off) ->
5972 get_target_module(Mod),
5979 %===============================================================================
5980 :- chr_constraint has_active_occurrence/1, has_active_occurrence/2.
5981 :- chr_option(mode,has_active_occurrence(+)).
5982 :- chr_option(mode,has_active_occurrence(+,+)).
5983 %-------------------------------------------------------------------------------
5984 has_active_occurrence(C) <=> has_active_occurrence(C,1).
5986 max_occurrence(C,MO) \ has_active_occurrence(C,O) <=>
5988 passive(RuleNb,ID),occurrence(C,O,RuleNb,ID,_) \
5989 has_active_occurrence(C,O) <=>
5991 has_active_occurrence(C,NO).
5992 has_active_occurrence(C,O) <=> true.
5993 %===============================================================================
5995 gen_cond_attach_clause(F/A,Id,L,T) :-
5996 ( is_finally_stored(F/A) ->
5997 get_allocation_occurrence(F/A,AllocationOccurrence),
5998 get_max_occurrence(F/A,MaxOccurrence),
5999 ( chr_pp_flag(debugable,off), MaxOccurrence < AllocationOccurrence ->
6000 ( only_ground_indexed_arguments(F/A) ->
6001 gen_insert_constraint_internal_goal(F/A,Body,AllArgs,Args,Susp)
6003 gen_cond_attach_goal(F/A,Body,AllArgs,Args,Susp)
6005 ; vars_susp(A,Args,Susp,AllArgs),
6006 gen_uncond_attach_goal(F/A,Susp,Args,Body,_)
6008 build_head(F,A,Id,AllArgs,Head),
6009 Clause = ( Head :- Body ),
6010 add_dummy_location(Clause,LocatedClause),
6011 L = [LocatedClause | T]
6016 :- chr_constraint use_auxiliary_predicate/1.
6017 :- chr_option(mode,use_auxiliary_predicate(+)).
6019 :- chr_constraint use_auxiliary_predicate/2.
6020 :- chr_option(mode,use_auxiliary_predicate(+,+)).
6022 :- chr_constraint is_used_auxiliary_predicate/1.
6023 :- chr_option(mode,is_used_auxiliary_predicate(+)).
6025 :- chr_constraint is_used_auxiliary_predicate/2.
6026 :- chr_option(mode,is_used_auxiliary_predicate(+,+)).
6029 use_auxiliary_predicate(P) \ use_auxiliary_predicate(P) <=> true.
6031 use_auxiliary_predicate(P,C) \ use_auxiliary_predicate(P,C) <=> true.
6033 use_auxiliary_predicate(P) \ is_used_auxiliary_predicate(P) <=> true.
6035 use_auxiliary_predicate(P,_) \ is_used_auxiliary_predicate(P) <=> true.
6037 is_used_auxiliary_predicate(P) <=> fail.
6039 use_auxiliary_predicate(P) \ is_used_auxiliary_predicate(P,_) <=> true.
6040 use_auxiliary_predicate(P,C) \ is_used_auxiliary_predicate(P,C) <=> true.
6042 is_used_auxiliary_predicate(P,C) <=> fail.
6044 %------------------------------------------------------------------------------%
6045 % Only generate import statements for actually used modules.
6046 %------------------------------------------------------------------------------%
6048 :- chr_constraint use_auxiliary_module/1.
6049 :- chr_option(mode,use_auxiliary_module(+)).
6051 :- chr_constraint is_used_auxiliary_module/1.
6052 :- chr_option(mode,is_used_auxiliary_module(+)).
6055 use_auxiliary_module(P) \ use_auxiliary_module(P) <=> true.
6057 use_auxiliary_module(P) \ is_used_auxiliary_module(P) <=> true.
6059 is_used_auxiliary_module(P) <=> fail.
6061 % only called for constraints with
6063 % non-ground indexed argument
6064 gen_cond_attach_goal(F/A,Goal,AllArgs,Args,Susp) :-
6065 vars_susp(A,Args,Susp,AllArgs),
6066 make_suspension_continuation_goal(F/A,AllArgs,Closure),
6067 ( get_store_type(F/A,var_assoc_store(_,_)) ->
6070 attach_constraint_atom(F/A,Vars,Susp,Attach)
6073 insert_constraint_goal(F/A,Susp,Args,InsertCall),
6074 insert_constraint_internal_constraint_goal(F/A, Vars, Susp, Closure, Args,InsertGoal),
6075 ( may_trigger(F/A) ->
6076 activate_constraint_goal(F/A,(InsertCall,Attach),Vars,Susp,_,ActivateGoal),
6080 InsertGoal, % insert_constraint_internal(Stored,Vars,Susp,Closure,F,Args)
6084 ActivateGoal % activate_constraint(Stored,Vars,Susp,_)
6090 InsertGoal, % insert_constraint_internal(Stored,Vars,Susp,Closure,F,Args),
6096 gen_insert_constraint_internal_goal(F/A,Goal,AllArgs,Args,Susp) :-
6097 vars_susp(A,Args,Susp,AllArgs),
6098 make_suspension_continuation_goal(F/A,AllArgs,Cont),
6099 ( \+ only_ground_indexed_arguments(F/A), \+ get_store_type(F/A,var_assoc_store(_,_)) ->
6100 attach_constraint_atom(F/A,Vars,Susp,Attach)
6105 insert_constraint_goal(F/A,Susp,Args,InsertCall),
6106 insert_constraint_internal_constraint_goal(F/A, Vars, Susp, Cont, Args,InsertInternalGoal),
6107 ( only_ground_indexed_arguments(F/A), chr_pp_flag(debugable,off) ->
6110 InsertInternalGoal, % insert_constraint_internal(Susp,F,Args),
6116 InsertInternalGoal, % insert_constraint_internal(_,Vars,Susp,Cont,F,Args),
6122 gen_uncond_attach_goal(FA,Susp,Args,AttachGoal,Generation) :-
6123 ( \+ only_ground_indexed_arguments(FA), \+ get_store_type(FA,var_assoc_store(_,_)) ->
6124 attach_constraint_atom(FA,Vars,Susp,Attach)
6128 insert_constraint_goal(FA,Susp,Args,InsertCall),
6129 ( chr_pp_flag(late_allocation,on) ->
6130 activate_constraint_goal(FA,(InsertCall,Attach),Vars,Susp,Generation,AttachGoal)
6132 activate_constraint_goal(FA,true,Vars,Susp,Generation,AttachGoal)
6135 %-------------------------------------------------------------------------------
6136 :- chr_constraint occurrences_code/6.
6137 :- chr_option(mode,occurrences_code(+,+,+,+,+,+)).
6138 %-------------------------------------------------------------------------------
6139 max_occurrence(C,MO) \ occurrences_code(C,O,Id,NId,L,T)
6142 occurrences_code(C,O,Id,NId,L,T)
6144 occurrence_code(C,O,Id,Id1,L,L1),
6146 occurrences_code(C,NO,Id1,NId,L1,T).
6147 %-------------------------------------------------------------------------------
6148 :- chr_constraint occurrence_code/6.
6149 :- chr_option(mode,occurrence_code(+,+,+,+,+,+)).
6150 %-------------------------------------------------------------------------------
6151 occurrence(C,O,RuleNb,ID,_), passive(RuleNb,ID) \ occurrence_code(C,O,Id,NId,L,T)
6153 ( named_history(RuleNb,_,_) ->
6154 does_use_history(C,O)
6160 occurrence(C,O,RuleNb,ID,_), rule(RuleNb,PragmaRule) \ occurrence_code(C,O,Id,NId,L,T)
6162 PragmaRule = pragma(rule(Heads1,Heads2,_,_),ids(IDs1,IDs2),_,_,_),
6163 ( select2(ID,Head1,IDs1,Heads1,RIDs1,RHeads1) ->
6165 head1_code(Head1,ID,RHeads1,RIDs1,PragmaRule,C,O,Id,L,T)
6166 ; select2(ID,Head2,IDs2,Heads2,RIDs2,RHeads2) ->
6168 head2_code(Head2,ID,RHeads2,RIDs2,PragmaRule,C,O,Id,L,L1),
6169 ( should_skip_to_next_id(C,O) ->
6171 ( unconditional_occurrence(C,O) ->
6174 gen_alloc_inc_clause(C,O,Id,L1,T)
6182 occurrence_code(C,O,_,_,_,_)
6184 chr_error(internal,'occurrence_code/6: missing information to compile ~w:~w\n',[C,O]).
6185 %-------------------------------------------------------------------------------
6187 %% Generate code based on one removed head of a CHR rule
6188 head1_code(Head,ID,OtherHeads,OtherIDs,PragmaRule,FA,O,Id,L,T) :-
6189 PragmaRule = pragma(Rule,_,_,_Name,RuleNb),
6190 Rule = rule(_,Head2,_,_),
6192 reorder_heads(RuleNb,Head,OtherHeads,OtherIDs,NOtherHeads,NOtherIDs),
6193 simplification_code(Head,ID,NOtherHeads,NOtherIDs,PragmaRule,FA,O,Id,L,T)
6195 simpagation_head1_code(Head,ID,OtherHeads,OtherIDs,PragmaRule,FA,O,Id,L,T)
6198 %% Generate code based on one persistent head of a CHR rule
6199 head2_code(Head,ID,OtherHeads,OtherIDs,PragmaRule,FA,O,Id,L,T) :-
6200 PragmaRule = pragma(Rule,_,_,_Name,RuleNb),
6201 Rule = rule(Head1,_,_,_),
6203 reorder_heads(RuleNb,Head,OtherHeads,OtherIDs,NOtherHeads,NOtherIDs),
6204 propagation_code(Head,ID,NOtherHeads,NOtherIDs,Rule,RuleNb,FA,O,Id,L,T)
6206 simpagation_head2_code(Head,ID,OtherHeads,OtherIDs,PragmaRule,FA,O,Id,L,T)
6209 gen_alloc_inc_clause(F/A,O,Id,L,T) :-
6210 vars_susp(A,Vars,Susp,VarsSusp),
6211 build_head(F,A,Id,VarsSusp,Head),
6213 build_head(F,A,IncId,VarsSusp,CallHead),
6214 gen_occ_allocation(F/A,O,Vars,Susp,ConditionalAlloc),
6221 add_dummy_location(Clause,LocatedClause),
6222 L = [LocatedClause|T].
6224 gen_occ_allocation(FA,O,Vars,Susp,Goal) :-
6225 get_allocation_occurrence(FA,AO),
6226 get_occurrence_code_id(FA,AO,AId),
6227 get_occurrence_code_id(FA,O,Id),
6228 ( chr_pp_flag(debugable,off), Id == AId ->
6229 allocate_constraint_goal(FA,Susp,Vars,Goal0),
6230 ( may_trigger(FA) ->
6231 Goal = (var(Susp) -> Goal0 ; true)
6239 gen_occ_allocation_in_guard(FA,O,Vars,Susp,Goal) :-
6240 get_allocation_occurrence(FA,AO),
6241 ( chr_pp_flag(debugable,off), O < AO ->
6242 allocate_constraint_goal(FA,Susp,Vars,Goal0),
6243 ( may_trigger(FA) ->
6244 Goal = (var(Susp) -> Goal0 ; true)
6252 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6254 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6256 % Reorders guard goals with respect to partner constraint retrieval goals and
6257 % active constraint. Returns combined partner retrieval + guard goal.
6259 guard_via_reschedule_new(Retrievals,GuardList,Prelude,GuardListSkeleton,LookupSkeleton,GoalSkeleton) :-
6260 ( chr_pp_flag(guard_via_reschedule,on) ->
6261 guard_via_reschedule_main_new(Retrievals,GuardList,Prelude,GuardListSkeleton,LookupSkeleton,ScheduleSkeleton),
6262 list2conj(ScheduleSkeleton,GoalSkeleton)
6264 length(Retrievals,RL), length(LookupSkeleton,RL),
6265 length(GuardList,GL), length(GuardListSkeleton,GL),
6266 append(LookupSkeleton,GuardListSkeleton,GoalListSkeleton),
6267 list2conj(GoalListSkeleton,GoalSkeleton)
6269 guard_via_reschedule_main_new(PartnerLookups,GuardList,ActiveHead,
6270 GuardListSkeleton,LookupSkeleton,ScheduleSkeleton) :-
6271 initialize_unit_dictionary(ActiveHead,Dict),
6272 maplist(wrap_in_functor(lookup),PartnerLookups,WrappedPartnerLookups),
6273 maplist(wrap_in_functor(guard),GuardList,WrappedGuardList),
6274 build_units(WrappedPartnerLookups,WrappedGuardList,Dict,Units),
6275 dependency_reorder(Units,NUnits),
6276 wrappedunits2lists(NUnits,IndexedGuardListSkeleton,LookupSkeleton,ScheduleSkeleton),
6277 sort(IndexedGuardListSkeleton,SortedIndexedGuardListSkeleton),
6278 snd_of_pairs(SortedIndexedGuardListSkeleton,GuardListSkeleton).
6280 wrappedunits2lists([],[],[],[]).
6281 wrappedunits2lists([unit(N,WrappedGoal,_,_)|Units],Gs,Ls,Ss) :-
6282 Ss = [GoalCopy|TSs],
6283 ( WrappedGoal = lookup(Goal) ->
6284 Ls = [GoalCopy|TLs],
6286 ; WrappedGoal = guard(Goal) ->
6287 Gs = [N-GoalCopy|TGs],
6290 wrappedunits2lists(Units,TGs,TLs,TSs).
6292 guard_splitting(Rule,SplitGuardList) :-
6293 Rule = rule(H1,H2,Guard,_),
6294 append(H1,H2,Heads),
6295 conj2list(Guard,GuardList),
6296 term_variables(Heads,HeadVars),
6297 split_off_simple_guard_new(GuardList,HeadVars,GuardPrefix,RestGuardList),
6298 append(GuardPrefix,[RestGuard],SplitGuardList),
6299 term_variables(RestGuardList,GuardVars1),
6300 % variables that are declared to be ground don't need to be locked
6301 ground_vars(Heads,GroundVars),
6302 list_difference_eq(HeadVars,GroundVars,LockableHeadVars),
6303 intersect_eq(LockableHeadVars,GuardVars1,GuardVars),
6304 ( chr_pp_flag(guard_locks,on),
6305 bagof(('chr lock'(X)) - ('chr unlock'(X)), (lists:member(X,GuardVars)), LocksUnlocks) ->
6306 once(pairup(Locks,Unlocks,LocksUnlocks))
6311 list2conj(Locks,LockPhase),
6312 list2conj(Unlocks,UnlockPhase),
6313 list2conj(RestGuardList,RestGuard1),
6314 RestGuard = (LockPhase,(RestGuard1,UnlockPhase)).
6316 guard_body_copies3(Rule,GuardList,VarDict,GuardCopyList,BodyCopy) :-
6317 Rule = rule(_,_,_,Body),
6318 my_term_copy(GuardList,VarDict,VarDict2,GuardCopyList),
6319 my_term_copy(Body,VarDict2,BodyCopy).
6322 split_off_simple_guard_new([],_,[],[]).
6323 split_off_simple_guard_new([G|Gs],VarDict,S,C) :-
6324 ( simple_guard_new(G,VarDict) ->
6326 split_off_simple_guard_new(Gs,VarDict,Ss,C)
6332 % simple guard: cheap and benign (does not bind variables)
6333 simple_guard_new(G,Vars) :-
6334 builtin_binds_b(G,BoundVars),
6335 \+ (( member(V,BoundVars),
6336 memberchk_eq(V,Vars)
6339 dependency_reorder(Units,NUnits) :-
6340 dependency_reorder(Units,[],NUnits).
6342 dependency_reorder([],Acc,Result) :-
6343 reverse(Acc,Result).
6345 dependency_reorder([Unit|Units],Acc,Result) :-
6346 Unit = unit(_GID,_Goal,Type,GIDs),
6350 dependency_insert(Acc,Unit,GIDs,NAcc)
6352 dependency_reorder(Units,NAcc,Result).
6354 dependency_insert([],Unit,_,[Unit]).
6355 dependency_insert([X|Xs],Unit,GIDs,L) :-
6356 X = unit(GID,_,_,_),
6357 ( memberchk(GID,GIDs) ->
6361 dependency_insert(Xs,Unit,GIDs,T)
6364 build_units(Retrievals,Guard,InitialDict,Units) :-
6365 build_retrieval_units(Retrievals,1,N,InitialDict,Dict,Units,Tail),
6366 build_guard_units(Guard,N,Dict,Tail).
6368 build_retrieval_units([],N,N,Dict,Dict,L,L).
6369 build_retrieval_units([U|Us],N,M,Dict,NDict,L,T) :-
6370 term_variables(U,Vs),
6371 update_unit_dictionary(Vs,N,Dict,Dict1,[],GIDs),
6372 L = [unit(N,U,fixed,GIDs)|L1],
6374 build_retrieval_units(Us,N1,M,Dict1,NDict,L1,T).
6376 initialize_unit_dictionary(Term,Dict) :-
6377 term_variables(Term,Vars),
6378 pair_all_with(Vars,0,Dict).
6380 update_unit_dictionary([],_,Dict,Dict,GIDs,GIDs).
6381 update_unit_dictionary([V|Vs],This,Dict,NDict,GIDs,NGIDs) :-
6382 ( lookup_eq(Dict,V,GID) ->
6383 ( (GID == This ; memberchk(GID,GIDs) ) ->
6390 Dict1 = [V - This|Dict],
6393 update_unit_dictionary(Vs,This,Dict1,NDict,GIDs1,NGIDs).
6395 build_guard_units(Guard,N,Dict,Units) :-
6397 Units = [unit(N,Goal,fixed,[])]
6398 ; Guard = [Goal|Goals] ->
6399 term_variables(Goal,Vs),
6400 update_unit_dictionary2(Vs,N,Dict,NDict,[],GIDs),
6401 Units = [unit(N,Goal,movable,GIDs)|RUnits],
6403 build_guard_units(Goals,N1,NDict,RUnits)
6406 update_unit_dictionary2([],_,Dict,Dict,GIDs,GIDs).
6407 update_unit_dictionary2([V|Vs],This,Dict,NDict,GIDs,NGIDs) :-
6408 ( lookup_eq(Dict,V,GID) ->
6409 ( (GID == This ; memberchk(GID,GIDs) ) ->
6414 Dict1 = [V - This|Dict]
6416 Dict1 = [V - This|Dict],
6419 update_unit_dictionary2(Vs,This,Dict1,NDict,GIDs1,NGIDs).
6421 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6423 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6425 %% / ___| ___| |_ / ___| ___ _ __ ___ __ _ _ __ | |_(_) ___ ___ _
6426 %% \___ \ / _ \ __| \___ \ / _ \ '_ ` _ \ / _` | '_ \| __| |/ __/ __(_)
6427 %% ___) | __/ |_ ___) | __/ | | | | | (_| | | | | |_| | (__\__ \_
6428 %% |____/ \___|\__| |____/ \___|_| |_| |_|\__,_|_| |_|\__|_|\___|___(_)
6431 %% | | | |_ __ (_) __ _ _ _ ___ |_ _|_ __ / _| ___ _ __ ___ _ __ ___ ___
6432 %% | | | | '_ \| |/ _` | | | |/ _ \ | || '_ \| |_ / _ \ '__/ _ \ '_ \ / __/ _ \
6433 %% | |_| | | | | | (_| | |_| | __/ | || | | | _| __/ | | __/ | | | (_| __/
6434 %% \___/|_| |_|_|\__, |\__,_|\___| |___|_| |_|_| \___|_| \___|_| |_|\___\___|
6437 functional_dependency/4,
6438 get_functional_dependency/4.
6440 :- chr_option(mode,functional_dependency(+,+,?,?)).
6441 :- chr_option(mode,get_functional_dependency(+,+,?,?)).
6443 allocation_occurrence(C,AO), occurrence(C,O,RuleNb,_,_) \ functional_dependency(C,RuleNb,Pattern,Key)
6447 functional_dependency(C,1,Pattern,Key).
6449 functional_dependency(C,RuleNb1,Pattern,Key) \ get_functional_dependency(C,RuleNb2,QPattern,QKey)
6453 QPattern = Pattern, QKey = Key.
6454 get_functional_dependency(_,_,_,_)
6458 functional_dependency_analysis(Rules) :-
6459 ( fail, chr_pp_flag(functional_dependency_analysis,on) ->
6460 functional_dependency_analysis_main(Rules)
6465 functional_dependency_analysis_main([]).
6466 functional_dependency_analysis_main([PRule|PRules]) :-
6467 ( discover_unique_pattern(PRule,C,RuleNb,Pattern,Key) ->
6468 functional_dependency(C,RuleNb,Pattern,Key)
6472 functional_dependency_analysis_main(PRules).
6474 discover_unique_pattern(PragmaRule,F/A,RuleNb,Pattern,Key) :-
6475 PragmaRule = pragma(Rule,_,_,Name,RuleNb),
6476 Rule = rule(H1,H2,Guard,_),
6484 check_unique_constraints(C1,C2,Guard,RuleNb,List),
6485 term_variables(C1,Vs),
6488 lookup_eq(List,V1,V2),
6491 select_pragma_unique_variables(Vs,List,Key1),
6492 copy_term_nat(C1-Key1,Pattern-Key),
6495 select_pragma_unique_variables([],_,[]).
6496 select_pragma_unique_variables([V|Vs],List,L) :-
6497 ( lookup_eq(List,V,_) ->
6502 select_pragma_unique_variables(Vs,List,T).
6504 % depends on functional dependency analysis
6505 % and shape of rule: C1 \ C2 <=> true.
6506 set_semantics_rules(Rules) :-
6507 ( fail, chr_pp_flag(set_semantics_rule,on) ->
6508 set_semantics_rules_main(Rules)
6513 set_semantics_rules_main([]).
6514 set_semantics_rules_main([R|Rs]) :-
6515 set_semantics_rule_main(R),
6516 set_semantics_rules_main(Rs).
6518 set_semantics_rule_main(PragmaRule) :-
6519 PragmaRule = pragma(Rule,IDs,Pragmas,_,RuleNb),
6520 ( Rule = rule([C1],[C2],true,_),
6521 IDs = ids([ID1],[ID2]),
6522 \+ is_passive(RuleNb,ID1),
6524 get_functional_dependency(F/A,RuleNb,Pattern,Key),
6525 copy_term_nat(Pattern-Key,C1-Key1),
6526 copy_term_nat(Pattern-Key,C2-Key2),
6533 check_unique_constraints(C1,C2,G,RuleNb,List) :-
6534 \+ any_passive_head(RuleNb),
6535 variable_replacement(C1-C2,C2-C1,List),
6536 copy_with_variable_replacement(G,OtherG,List),
6538 once(entails_b(NotG,OtherG)).
6540 % checks for rules of the shape ...,C1,C2... (<|=)=> ...
6541 % where C1 and C2 are symmteric constraints
6542 symmetry_analysis(Rules) :-
6543 ( chr_pp_flag(check_unnecessary_active,off) ->
6546 symmetry_analysis_main(Rules)
6549 symmetry_analysis_main([]).
6550 symmetry_analysis_main([R|Rs]) :-
6551 R = pragma(Rule,ids(IDs1,IDs2),_,_,RuleNb),
6552 Rule = rule(H1,H2,_,_),
6553 ( ( \+ chr_pp_flag(check_unnecessary_active,simplification) ; H2 == [] ), H1 \== [] ->
6554 symmetry_analysis_heads_simplification(H1,IDs1,[],[],Rule,RuleNb),
6555 symmetry_analysis_heads_propagation(H2,IDs2,[],[],Rule,RuleNb)
6559 symmetry_analysis_main(Rs).
6561 symmetry_analysis_heads_simplification([],[],_,_,_,_).
6562 symmetry_analysis_heads_simplification([H|Hs],[ID|IDs],PreHs,PreIDs,Rule,RuleNb) :-
6563 ( \+ is_passive(RuleNb,ID),
6564 member2(PreHs,PreIDs,PreH-PreID),
6565 \+ is_passive(RuleNb,PreID),
6566 variable_replacement(PreH,H,List),
6567 copy_with_variable_replacement(Rule,Rule2,List),
6568 identical_guarded_rules(Rule,Rule2) ->
6573 symmetry_analysis_heads_simplification(Hs,IDs,[H|PreHs],[ID|PreIDs],Rule,RuleNb).
6575 symmetry_analysis_heads_propagation([],[],_,_,_,_).
6576 symmetry_analysis_heads_propagation([H|Hs],[ID|IDs],PreHs,PreIDs,Rule,RuleNb) :-
6577 ( \+ is_passive(RuleNb,ID),
6578 member2(PreHs,PreIDs,PreH-PreID),
6579 \+ is_passive(RuleNb,PreID),
6580 variable_replacement(PreH,H,List),
6581 copy_with_variable_replacement(Rule,Rule2,List),
6582 identical_rules(Rule,Rule2) ->
6587 symmetry_analysis_heads_propagation(Hs,IDs,[H|PreHs],[ID|PreIDs],Rule,RuleNb).
6589 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6591 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6592 %% ____ _ _ _ __ _ _ _
6593 %% / ___|(_)_ __ ___ _ __ | (_)/ _(_) ___ __ _| |_(_) ___ _ __
6594 %% \___ \| | '_ ` _ \| '_ \| | | |_| |/ __/ _` | __| |/ _ \| '_ \
6595 %% ___) | | | | | | | |_) | | | _| | (_| (_| | |_| | (_) | | | |
6596 %% |____/|_|_| |_| |_| .__/|_|_|_| |_|\___\__,_|\__|_|\___/|_| |_|
6600 simplification_code(Head,ID,RestHeads,RestIDs,PragmaRule,F/A,O,Id,L,T) :-
6601 PragmaRule = pragma(Rule,_,Pragmas,_,RuleNb),
6602 head_info(Head,A,_Vars,Susp,HeadVars,HeadPairs),
6603 build_head(F,A,Id,HeadVars,ClauseHead),
6604 get_constraint_mode(F/A,Mode),
6605 head_arg_matches(HeadPairs,Mode,[],FirstMatching,VarDict1,[],GroundVars),
6608 guard_splitting(Rule,GuardList0),
6609 ( is_stored_in_guard(F/A, RuleNb) ->
6610 GuardList = [Hole1|GuardList0]
6612 GuardList = GuardList0
6614 guard_via_reschedule_new(RestHeads,GuardList,Head,GuardCopyList,GetRestHeads,RescheduledTest),
6616 rest_heads_retrieval_and_matching(RestHeads,RestIDs,Head,GetRestHeads,Susps,VarDict1,VarDict,[],[],[],GroundVars,_),
6618 guard_body_copies3(Rule,GuardList,VarDict,GuardCopyList,BodyCopy),
6620 ( is_stored_in_guard(F/A, RuleNb) ->
6621 gen_occ_allocation_in_guard(F/A,O,Vars,Susp,Allocation),
6622 gen_uncond_attach_goal(F/A,Susp,Vars,Attachment,_),
6623 GuardCopyList = [Hole1Copy|_],
6624 Hole1Copy = (Allocation, Attachment)
6630 partner_constraint_detachments(Susps,RestHeads,VarDict,SuspsDetachments),
6631 active_constraint_detachment(Id,Susp,Head,VarDict,SuspDetachment),
6633 ( chr_pp_flag(debugable,on) ->
6634 Rule = rule(_,_,Guard,Body),
6635 my_term_copy(Guard - Body, VarDict, DebugGuard - DebugBody),
6636 sort_by_key([Susp|Susps],[ID|RestIDs],SortedSusps),
6637 DebugTry = 'chr debug_event'( try(SortedSusps,[],DebugGuard,DebugBody)),
6638 DebugApply = 'chr debug_event'(apply(SortedSusps,[],DebugGuard,DebugBody)),
6639 instrument_goal(ActualCut,DebugTry,DebugApply,Cut)
6643 ( unconditional_occurrence(F/A,O), chr_pp_flag(late_allocation,on) -> ActualCut = true ; ActualCut = (!) ),
6644 Clause = ( ClauseHead :-
6652 add_location(Clause,RuleNb,LocatedClause),
6653 L = [LocatedClause | T].
6657 add_location(Clause,RuleNb,NClause) :-
6658 ( chr_pp_flag(line_numbers,on) ->
6659 get_chr_source_file(File),
6660 get_line_number(RuleNb,LineNb),
6661 NClause = '$source_location'(File,LineNb):Clause
6666 add_dummy_location(Clause,NClause) :-
6667 ( chr_pp_flag(line_numbers,on) ->
6668 get_chr_source_file(File),
6669 NClause = '$source_location'(File,1):Clause
6673 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6674 %% head_arg_matches(+Pairs,+Modes,+VarDict,-Goal,-NVarDict) is det.
6676 % Return goal matching newly introduced variables with variables in
6677 % previously looked-up heads.
6678 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6679 head_arg_matches(Pairs,Modes,VarDict,Goal,NVarDict) :-
6680 head_arg_matches(Pairs,Modes,VarDict,Goal,NVarDict,[],_).
6682 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6683 %% head_arg_matches(+Pairs,+Modes,+VarDict,-Goal,-NVarDict,+GroundVars,-NGroundVars) is det.
6684 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6685 head_arg_matches(Pairs,Modes,VarDict,Goal,NVarDict,GroundVars,NGroundVars) :-
6686 head_arg_matches_(Pairs,Modes,VarDict,GroundVars,GoalList,NVarDict,NGroundVars),
6687 list2conj(GoalList,Goal).
6689 head_arg_matches_([],[],VarDict,GroundVars,[],VarDict,GroundVars).
6690 head_arg_matches_([Arg-Var| Rest],[Mode|Modes],VarDict,GroundVars,GoalList,NVarDict,NGroundVars) :-
6692 ( lookup_eq(VarDict,Arg,OtherVar) ->
6694 ( memberchk_eq(Arg,GroundVars) ->
6695 GoalList = [Var = OtherVar | RestGoalList],
6696 GroundVars1 = GroundVars
6698 GoalList = [Var == OtherVar | RestGoalList],
6699 GroundVars1 = [Arg|GroundVars]
6702 GoalList = [Var == OtherVar | RestGoalList],
6703 GroundVars1 = GroundVars
6707 VarDict1 = [Arg-Var | VarDict],
6708 GoalList = RestGoalList,
6710 GroundVars1 = [Arg|GroundVars]
6712 GroundVars1 = GroundVars
6717 ; ground(Arg), Arg = '$chr_identifier_match'(ActualArg,IndexType) ->
6718 identifier_label_atom(IndexType,Var,ActualArg,Goal),
6719 GoalList = [Goal|RestGoalList],
6721 GroundVars1 = GroundVars,
6726 GoalList = [ Var = Arg | RestGoalList]
6728 GoalList = [ Var == Arg | RestGoalList]
6731 GroundVars1 = GroundVars,
6734 ; Mode == (+), is_ground(GroundVars,Arg) ->
6735 copy_with_variable_replacement(Arg,ArgCopy,VarDict),
6736 GoalList = [ Var = ArgCopy | RestGoalList],
6738 GroundVars1 = GroundVars,
6741 ; Mode == (?), is_ground(GroundVars,Arg) ->
6742 copy_with_variable_replacement(Arg,ArgCopy,VarDict),
6743 GoalList = [ Var == ArgCopy | RestGoalList],
6745 GroundVars1 = GroundVars,
6750 functor(Term,Fct,N),
6753 GoalList = [ Var = Term | RestGoalList ]
6755 GoalList = [ nonvar(Var), Var = Term | RestGoalList ]
6757 pairup(Args,Vars,NewPairs),
6758 append(NewPairs,Rest,Pairs),
6759 replicate(N,Mode,NewModes),
6760 append(NewModes,Modes,RestModes),
6762 GroundVars1 = GroundVars
6764 head_arg_matches_(Pairs,RestModes,VarDict1,GroundVars1,RestGoalList,NVarDict,NGroundVars).
6766 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6767 % add_heads_types(+ListOfHeads,+VarTypes,-NVarTypes) is det.
6768 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6769 add_heads_types([],VarTypes,VarTypes).
6770 add_heads_types([Head|Heads],VarTypes,NVarTypes) :-
6771 add_head_types(Head,VarTypes,VarTypes1),
6772 add_heads_types(Heads,VarTypes1,NVarTypes).
6774 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6775 % add_head_types(+Head,+VarTypes,-NVarTypes) is det.
6776 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6777 add_head_types(Head,VarTypes,NVarTypes) :-
6779 get_constraint_type_det(F/A,ArgTypes),
6781 add_args_types(Args,ArgTypes,VarTypes,NVarTypes).
6783 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6784 % add_args_types(+Terms,+Types,+VarTypes,-NVarTypes) is det.
6785 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6786 add_args_types([],[],VarTypes,VarTypes).
6787 add_args_types([Arg|Args],[Type|Types],VarTypes,NVarTypes) :-
6788 add_arg_types(Arg,Type,VarTypes,VarTypes1),
6789 add_args_types(Args,Types,VarTypes1,NVarTypes).
6791 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6792 % add_arg_types(+Term,+Type,+VarTypes,-NVarTypes) is det.
6793 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6794 add_arg_types(Term,Type,VarTypes,NVarTypes) :-
6796 ( lookup_eq(VarTypes,Term,_) ->
6797 NVarTypes = VarTypes
6799 NVarTypes = [Term-Type|VarTypes]
6802 NVarTypes = VarTypes
6803 ; % TODO improve approximation!
6804 term_variables(Term,Vars),
6806 replicate(VarNb,any,Types),
6807 add_args_types(Vars,Types,VarTypes,NVarTypes)
6812 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6813 %% add_heads_ground_variables(+ListOfHeads,+GroundVars,-NGroundVars) is det.
6815 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6816 add_heads_ground_variables([],GroundVars,GroundVars).
6817 add_heads_ground_variables([Head|Heads],GroundVars,NGroundVars) :-
6818 add_head_ground_variables(Head,GroundVars,GroundVars1),
6819 add_heads_ground_variables(Heads,GroundVars1,NGroundVars).
6821 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6822 %% add_head_ground_variables(+Head,+GroundVars,-GroundVars) is det.
6824 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6825 add_head_ground_variables(Head,GroundVars,NGroundVars) :-
6827 get_constraint_mode(F/A,ArgModes),
6829 add_arg_ground_variables(Args,ArgModes,GroundVars,NGroundVars).
6832 add_arg_ground_variables([],[],GroundVars,GroundVars).
6833 add_arg_ground_variables([Arg|Args],[Mode|Modes],GroundVars,NGroundVars) :-
6835 term_variables(Arg,Vars),
6836 add_var_ground_variables(Vars,GroundVars,GroundVars1)
6838 GroundVars = GroundVars1
6840 add_arg_ground_variables(Args,Modes,GroundVars1,NGroundVars).
6842 add_var_ground_variables([],GroundVars,GroundVars).
6843 add_var_ground_variables([Var|Vars],GroundVars,NGroundVars) :-
6844 ( memberchk_eq(Var,GroundVars) ->
6845 GroundVars1 = GroundVars
6847 GroundVars1 = [Var|GroundVars]
6849 add_var_ground_variables(Vars,GroundVars1,NGroundVars).
6850 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6851 %% is_ground(+GroundVars,+Term) is semidet.
6853 % Determine whether =Term= is always ground.
6854 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6855 is_ground(GroundVars,Term) :-
6860 maplist(is_ground(GroundVars),Args)
6862 memberchk_eq(Term,GroundVars)
6865 %% check_ground(+GroundVars,+Term,-Goal) is det.
6867 % Return runtime check to see whether =Term= is ground.
6868 check_ground(GroundVars,Term,Goal) :-
6869 term_variables(Term,Variables),
6870 check_ground_variables(Variables,GroundVars,Goal).
6872 check_ground_variables([],_,true).
6873 check_ground_variables([Var|Vars],GroundVars,Goal) :-
6874 ( memberchk_eq(Var,GroundVars) ->
6875 check_ground_variables(Vars,GroundVars,Goal)
6877 Goal = (ground(Var), RGoal),
6878 check_ground_variables(Vars,GroundVars,RGoal)
6881 rest_heads_retrieval_and_matching(Heads,IDs,ActiveHead,GoalList,Susps,VarDict,NVarDict,PrevHs,PrevSusps,AttrDict) :-
6882 rest_heads_retrieval_and_matching(Heads,IDs,ActiveHead,GoalList,Susps,VarDict,NVarDict,PrevHs,PrevSusps,AttrDict,[],_).
6884 rest_heads_retrieval_and_matching(Heads,IDs,ActiveHead,GoalList,Susps,VarDict,NVarDict,PrevHs,PrevSusps,AttrDict,GroundVars,NGroundVars) :-
6886 rest_heads_retrieval_and_matching_n(Heads,IDs,PrevHs,PrevSusps,ActiveHead,GoalList,Susps,VarDict,NVarDict,AttrDict,GroundVars,NGroundVars)
6891 GroundVars = NGroundVars
6894 rest_heads_retrieval_and_matching_n([],_,_,_,_,[],[],VarDict,VarDict,_AttrDict,GroundVars,GroundVars).
6895 rest_heads_retrieval_and_matching_n([H|Hs],[ID|IDs],PrevHs,PrevSusps,ActiveHead,
6896 [Goal|Goals],[Susp|Susps],VarDict,NVarDict,_AttrDict,GroundVars,NGroundVars) :-
6898 head_info(H,A,Vars,_,_,Pairs),
6899 get_store_type(F/A,StoreType),
6900 ( StoreType == default ->
6901 passive_head_via(H,[ActiveHead|PrevHs],VarDict,ViaGoal,VarSusps),
6902 delay_phase_end(validate_store_type_assumptions,
6903 ( static_suspension_term(F/A,Suspension),
6904 get_static_suspension_term_field(arguments,F/A,Suspension,Vars),
6905 get_static_suspension_field(F/A,Suspension,state,active,GetState)
6908 % create_get_mutable_ref(active,State,GetMutable),
6909 get_constraint_mode(F/A,Mode),
6910 head_arg_matches(Pairs,Mode,VarDict,MatchingGoal,VarDict1,GroundVars,GroundVars1),
6912 sbag_member_call(Susp,VarSusps,Sbag),
6913 ExistentialLookup = (
6916 Susp = Suspension, % not inlined
6920 delay_phase_end(validate_store_type_assumptions,
6921 ( static_suspension_term(F/A,Suspension),
6922 get_static_suspension_term_field(arguments,F/A,Suspension,Vars)
6925 existential_lookup(StoreType,H,[ActiveHead|PrevHs],VarDict,GroundVars,Suspension,ExistentialLookup,Susp,Pairs,NPairs),
6926 get_constraint_mode(F/A,Mode),
6927 filter_mode(NPairs,Pairs,Mode,NMode),
6928 head_arg_matches(NPairs,NMode,VarDict,MatchingGoal,VarDict1,GroundVars,GroundVars1)
6930 different_from_other_susps(H,Susp,PrevHs,PrevSusps,DiffSuspGoals),
6931 append(NPairs,VarDict1,DA_), % order important here
6932 translate(GroundVars1,DA_,GroundVarsA),
6933 translate(GroundVars1,VarDict1,GroundVarsB),
6934 inline_matching_goal(MatchingGoal,MatchingGoal2,GroundVarsA,GroundVarsB),
6941 rest_heads_retrieval_and_matching_n(Hs,IDs,[H|PrevHs],[Susp|PrevSusps],ActiveHead,Goals,Susps,VarDict1,NVarDict,_NewAttrDict,GroundVars1,NGroundVars).
6943 inline_matching_goal(A==B,true,GVA,GVB) :-
6944 memberchk_eq(A,GVA),
6945 memberchk_eq(B,GVB),
6948 % inline_matching_goal(A=B,true,_,_) :- A=B, !.
6949 inline_matching_goal((A,B),(A2,B2),GVA,GVB) :- !,
6950 inline_matching_goal(A,A2,GVA,GVB),
6951 inline_matching_goal(B,B2,GVA,GVB).
6952 inline_matching_goal(X,X,_,_).
6955 filter_mode([],_,_,[]).
6956 filter_mode([Arg-Var|Rest],[_-V|R],[M|Ms],Modes) :-
6959 filter_mode(Rest,R,Ms,MT)
6961 filter_mode([Arg-Var|Rest],R,Ms,Modes)
6964 check_unique_keys([],_).
6965 check_unique_keys([V|Vs],Dict) :-
6966 lookup_eq(Dict,V,_),
6967 check_unique_keys(Vs,Dict).
6969 % Generates tests to ensure the found constraint differs from previously found constraints
6970 % TODO: detect more cases where constraints need be different
6971 different_from_other_susps(Head,Susp,Heads,Susps,DiffSuspGoals) :-
6972 different_from_other_susps_(Heads,Susps,Head,Susp,DiffSuspGoalList),
6973 list2conj(DiffSuspGoalList,DiffSuspGoals).
6975 different_from_other_susps_(_,[],_,_,[]) :- !.
6976 different_from_other_susps_([PreHead|Heads],[PreSusp|Susps],Head,Susp,List) :-
6977 ( functor(Head,F,A), functor(PreHead,F,A),
6978 copy_term_nat(PreHead-Head,PreHeadCopy-HeadCopy),
6979 \+ \+ PreHeadCopy = HeadCopy ->
6981 List = [Susp \== PreSusp | Tail]
6985 different_from_other_susps_(Heads,Susps,Head,Susp,Tail).
6987 % passive_head_via(in,in,in,in,out,out,out) :-
6988 passive_head_via(Head,PrevHeads,VarDict,Goal,AllSusps) :-
6990 get_constraint_index(F/A,Pos),
6991 common_variables(Head,PrevHeads,CommonVars),
6992 global_list_store_name(F/A,Name),
6993 GlobalGoal = nb_getval(Name,AllSusps),
6994 get_constraint_mode(F/A,ArgModes),
6997 ; member(CommonVar,CommonVars), nth1(I,ArgModes,(-)), arg(I,Head,Arg), Arg == CommonVar ->
6998 translate([CommonVar],VarDict,[Var]),
6999 gen_get_mod_constraints(F/A,Var,AttrGoal,AllSusps),
7002 translate(CommonVars,VarDict,Vars),
7003 add_heads_types(PrevHeads,[],TypeDict),
7004 my_term_copy(TypeDict,VarDict,TypeDictCopy),
7005 gen_get_mod_constraints(F/A,Vars,TypeDictCopy,ViaGoal,AttrGoal,AllSusps),
7014 common_variables(T,Ts,Vs) :-
7015 term_variables(T,V1),
7016 term_variables(Ts,V2),
7017 intersect_eq(V1,V2,Vs).
7019 gen_get_mod_constraints(FA,Vars,TypeDict,ViaGoal,AttrGoal,AllSusps) :-
7020 get_target_module(Mod),
7022 lookup_eq(TypeDict,A,Type),
7023 ( atomic_type(Type) ->
7027 ViaGoal = 'chr newvia_1'(A,V)
7030 ViaGoal = 'chr newvia_2'(A,B,V)
7032 ViaGoal = 'chr newvia'(Vars,V)
7035 ( get_attr(V,Mod,TSusps),
7036 TSuspsEqSusps % TSusps = Susps
7038 get_max_constraint_index(N),
7040 TSuspsEqSusps = true, % TSusps = Susps
7043 get_constraint_index(FA,Pos),
7044 get_suspensions(N,Pos,TSusps,TSuspsEqSusps,AllSusps)
7046 gen_get_mod_constraints(FA,Var,AttrGoal,AllSusps) :-
7047 get_target_module(Mod),
7049 ( get_attr(Var,Mod,TSusps),
7050 TSuspsEqSusps % TSusps = Susps
7052 get_max_constraint_index(N),
7054 TSuspsEqSusps = true, % TSusps = Susps
7057 get_constraint_index(FA,Pos),
7058 get_suspensions(N,Pos,TSusps,TSuspsEqSusps,AllSusps)
7061 guard_body_copies(Rule,VarDict,GuardCopy,BodyCopy) :-
7062 guard_body_copies2(Rule,VarDict,GuardCopyList,BodyCopy),
7063 list2conj(GuardCopyList,GuardCopy).
7065 guard_body_copies2(Rule,VarDict,GuardCopyList,BodyCopy) :-
7066 Rule = rule(_,H,Guard,Body),
7067 conj2list(Guard,GuardList),
7068 split_off_simple_guard(GuardList,VarDict,GuardPrefix,RestGuardList),
7069 my_term_copy(GuardPrefix-RestGuardList,VarDict,VarDict2,GuardPrefixCopy-RestGuardListCopyCore),
7071 append(GuardPrefixCopy,[RestGuardCopy],GuardCopyList),
7072 term_variables(RestGuardList,GuardVars),
7073 term_variables(RestGuardListCopyCore,GuardCopyVars),
7074 % variables that are declared to be ground don't need to be locked
7075 ground_vars(H,GroundVars),
7076 list_difference_eq(GuardVars,GroundVars,LockedGuardVars),
7077 ( chr_pp_flag(guard_locks,on),
7078 bagof(('chr lock'(Y)) - ('chr unlock'(Y)),
7079 X ^ (lists:member(X,LockedGuardVars), % X is a variable appearing in the original guard
7080 pairlist:lookup_eq(VarDict,X,Y), % translate X into new variable
7081 memberchk_eq(Y,GuardCopyVars) % redundant check? or multiple entries for X possible?
7084 once(pairup(Locks,Unlocks,LocksUnlocks))
7089 list2conj(Locks,LockPhase),
7090 list2conj(Unlocks,UnlockPhase),
7091 list2conj(RestGuardListCopyCore,RestGuardCopyCore),
7092 RestGuardCopy = (LockPhase,(RestGuardCopyCore,UnlockPhase)),
7093 my_term_copy(Body,VarDict2,BodyCopy).
7096 split_off_simple_guard([],_,[],[]).
7097 split_off_simple_guard([G|Gs],VarDict,S,C) :-
7098 ( simple_guard(G,VarDict) ->
7100 split_off_simple_guard(Gs,VarDict,Ss,C)
7106 % simple guard: cheap and benign (does not bind variables)
7107 simple_guard(G,VarDict) :-
7109 \+ (( member(V,Vars),
7110 lookup_eq(VarDict,V,_)
7113 active_constraint_detachment(Id,Susp,Head,VarDict,SuspDetachment) :-
7119 Id == [0], chr_pp_flag(store_in_guards, off)
7121 ( get_allocation_occurrence(C,AO),
7122 get_max_occurrence(C,MO),
7125 only_ground_indexed_arguments(C), chr_pp_flag(late_allocation,on) ->
7126 SuspDetachment = true
7128 gen_uncond_susp_detachment(Head,Susp,active,VarDict,UnCondSuspDetachment),
7129 ( chr_pp_flag(late_allocation,on) ->
7134 UnCondSuspDetachment
7137 SuspDetachment = UnCondSuspDetachment
7141 SuspDetachment = true
7144 partner_constraint_detachments([],[],_,true).
7145 partner_constraint_detachments([Susp|Susps],[Head|Heads],VarDict,(SuspDetachment,SuspsDetachments)) :-
7146 gen_uncond_susp_detachment(Head,Susp,partner,VarDict,SuspDetachment),
7147 partner_constraint_detachments(Susps,Heads,VarDict,SuspsDetachments).
7149 gen_uncond_susp_detachment(Head,Susp,Role,VarDict,SuspDetachment) :-
7153 SuspDetachment = ( DebugEvent, RemoveInternalGoal),
7154 ( chr_pp_flag(debugable,on) ->
7155 DebugEvent = 'chr debug_event'(remove(Susp))
7159 remove_constraint_goal(C,Susp,Vars,true,(DeleteCall,Detach),Role,RemoveInternalGoal),
7160 delete_constraint_goal(Head,Susp,VarDict,DeleteCall),
7161 ( \+ only_ground_indexed_arguments(C), \+ get_store_type(C,var_assoc_store(_,_)) ->
7162 detach_constraint_atom(C,Vars,Susp,Detach)
7167 SuspDetachment = true
7170 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7172 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7174 %% / ___|(_)_ __ ___ _ __ __ _ __ _ __ _| |_(_) ___ _ __ / |
7175 %% \___ \| | '_ ` _ \| '_ \ / _` |/ _` |/ _` | __| |/ _ \| '_ \ | |
7176 %% ___) | | | | | | | |_) | (_| | (_| | (_| | |_| | (_) | | | | | |
7177 %% |____/|_|_| |_| |_| .__/ \__,_|\__, |\__,_|\__|_|\___/|_| |_| |_|
7181 simpagation_head1_code(Head,ID,RestHeads,OtherIDs,PragmaRule,F/A,O,Id,L,T) :-
7182 PragmaRule = pragma(Rule,ids(_,Heads2IDs),Pragmas,_Name,RuleNb),
7183 Rule = rule(_Heads,Heads2,Guard,Body),
7185 head_info(Head,A,Vars,Susp,HeadVars,HeadPairs),
7186 get_constraint_mode(F/A,Mode),
7187 head_arg_matches(HeadPairs,Mode,[],FirstMatching,VarDict1,[],GroundVars),
7189 build_head(F,A,Id,HeadVars,ClauseHead),
7191 append(RestHeads,Heads2,Heads),
7192 append(OtherIDs,Heads2IDs,IDs),
7193 reorder_heads(RuleNb,Head,Heads,IDs,NHeads,NIDs),
7195 guard_splitting(Rule,GuardList0),
7196 ( is_stored_in_guard(F/A, RuleNb) ->
7197 GuardList = [Hole1|GuardList0]
7199 GuardList = GuardList0
7201 guard_via_reschedule_new(NHeads,GuardList,Head,GuardCopyList,GetRestHeads,RescheduledTest),
7203 rest_heads_retrieval_and_matching(NHeads,NIDs,Head,GetRestHeads,Susps,VarDict1,VarDict,[],[],[],GroundVars,_),
7204 split_by_ids(NIDs,Susps,OtherIDs,Susps1,Susps1IDs,Susps2,Susps2IDs),
7206 guard_body_copies3(Rule,GuardList,VarDict,GuardCopyList,BodyCopy),
7208 ( is_stored_in_guard(F/A, RuleNb) ->
7209 gen_uncond_attach_goal(F/A,Susp,Vars,Attachment,_),
7210 GuardCopyList = [Hole1Copy|_],
7211 Hole1Copy = Attachment
7216 sort_by_key(Susps1,Susps1IDs,SortedSusps1),
7217 partner_constraint_detachments(SortedSusps1,RestHeads,VarDict,SuspsDetachments),
7218 active_constraint_detachment(Id,Susp,Head,VarDict,SuspDetachment),
7220 ( chr_pp_flag(debugable,on) ->
7221 my_term_copy(Guard - Body, VarDict, DebugGuard - DebugBody),
7222 sort_by_key([Susp|Susps1],[ID|Susps1IDs],RemovedSusps),
7223 sort_by_key(Susps2,Susps2IDs,KeptSusps),
7224 DebugTry = 'chr debug_event'( try(RemovedSusps,KeptSusps,DebugGuard,DebugBody)),
7225 DebugApply = 'chr debug_event'(apply(RemovedSusps,KeptSusps,DebugGuard,DebugBody)),
7226 instrument_goal((!),DebugTry,DebugApply,Cut)
7231 Clause = ( ClauseHead :-
7239 add_location(Clause,RuleNb,LocatedClause),
7240 L = [LocatedClause | T].
7244 split_by_ids([],[],_,[],[]).
7245 split_by_ids([I|Is],[S|Ss],I1s,S1s,S2s) :-
7246 ( memberchk_eq(I,I1s) ->
7253 split_by_ids(Is,Ss,I1s,R1s,R2s).
7255 split_by_ids([],[],_,[],[],[],[]).
7256 split_by_ids([I|Is],[S|Ss],I1s,S1s,SI1s,S2s,SI2s) :-
7257 ( memberchk_eq(I,I1s) ->
7268 split_by_ids(Is,Ss,I1s,R1s,RSI1s,R2s,RSI2s).
7269 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7272 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7274 %% / ___|(_)_ __ ___ _ __ __ _ __ _ __ _| |_(_) ___ _ __ |___ \
7275 %% \___ \| | '_ ` _ \| '_ \ / _` |/ _` |/ _` | __| |/ _ \| '_ \ __) |
7276 %% ___) | | | | | | | |_) | (_| | (_| | (_| | |_| | (_) | | | | / __/
7277 %% |____/|_|_| |_| |_| .__/ \__,_|\__, |\__,_|\__|_|\___/|_| |_| |_____|
7280 %% Genereate prelude + worker predicate
7281 %% prelude calls worker
7282 %% worker iterates over one type of removed constraints
7283 simpagation_head2_code(Head2,ID,RestHeads2,RestIDs,PragmaRule,FA,O,Id,L,T) :-
7284 PragmaRule = pragma(Rule,ids(IDs1,IDs2),Pragmas,_Name,RuleNb),
7285 Rule = rule(Heads1,_,Guard,Body),
7286 append(Heads1,RestHeads2,Heads),
7287 append(IDs1,RestIDs,IDs),
7288 reorder_heads(RuleNb,Head2,Heads,IDs,[NHead|NHeads],[NID|NIDs]),
7289 simpagation_head2_prelude(Head2,NHead,[NHeads,Guard,Body],FA,O,Id,L,L1),
7291 ( memberchk_eq(NID,IDs2) ->
7292 simpagation_universal_searches(NHeads,NIDs,IDs2,[NHead,Head2],Rule,FA,O,NextHeads,PreHeads,NextIDs,Id1,Id2,L1,L2)
7294 L1 = L2, Id1 = Id2,NextHeads = NHeads, PreHeads = [NHead,Head2], NextIDs = NIDs
7296 universal_search_iterator_end(PreHeads,NextHeads,Rule,FA,O,Id2,L2,L3),
7297 simpagation_head2_worker(PreHeads,NextHeads,NextIDs,ID,PragmaRule,FA,O,Id2,L3,T).
7299 simpagation_universal_searches([],[],_,PreHeads,_,_,_,[],PreHeads,[],Id,Id,L,L).
7300 simpagation_universal_searches(Heads,[ID|IDs],IDs2,PreHeads,Rule,C,O,OutHeads,OutPreHeads,OutIDs,Id,NId,L,T) :-
7301 Heads = [Head|RHeads],
7303 universal_search_iterator_end(PreHeads,Heads,Rule,C,O,Id,L,L0),
7304 universal_search_iterator(Heads,PreHeads,Rule,C,O,Id,L0,L1),
7305 ( memberchk_eq(ID,IDs2) ->
7306 simpagation_universal_searches(RHeads,IDs,IDs2,[Head|PreHeads],Rule,C,O,OutHeads,OutPreHeads,OutIDs,Id1,NId,L1,T)
7308 NId = Id1, L1 = T, OutHeads = RHeads, OutPreHeads = [Head|PreHeads], IDs = OutIDs
7311 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7312 simpagation_head2_prelude(Head,Head1,Rest,F/A,O,Id1,L,T) :-
7313 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs),
7314 build_head(F,A,Id1,VarsSusp,ClauseHead),
7315 get_constraint_mode(F/A,Mode),
7316 head_arg_matches(HeadPairs,Mode,[],FirstMatching,VarDict,[],GroundVars),
7318 lookup_passive_head(Head1,[Head],VarDict,GroundVars,ModConstraintsGoal,AllSusps),
7320 gen_occ_allocation(F/A,O,Vars,Susp,ConstraintAllocationGoal),
7322 extend_id(Id1,DelegateId),
7323 extra_active_delegate_variables(Head,[Head1|Rest],VarDict,ExtraVars),
7324 append([AllSusps|VarsSusp],ExtraVars,DelegateCallVars),
7325 build_head(F,A,[O|DelegateId],DelegateCallVars,Delegate),
7332 ConstraintAllocationGoal,
7335 add_dummy_location(PreludeClause,LocatedPreludeClause),
7336 L = [LocatedPreludeClause|T].
7338 extra_active_delegate_variables(Term,Terms,VarDict,Vars) :-
7340 delegate_variables(Term,Terms,VarDict,Args,Vars).
7342 passive_delegate_variables(Term,PrevTerms,NextTerms,VarDict,Vars) :-
7343 term_variables(PrevTerms,PrevVars),
7344 delegate_variables(Term,NextTerms,VarDict,PrevVars,Vars).
7346 delegate_variables(Term,Terms,VarDict,PrevVars,Vars) :-
7347 term_variables(Term,V1),
7348 term_variables(Terms,V2),
7349 intersect_eq(V1,V2,V3),
7350 list_difference_eq(V3,PrevVars,V4),
7351 translate(V4,VarDict,Vars).
7354 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7355 simpagation_head2_worker([CurrentHead|PreHeads],NextHeads,NextIDs,ID,PragmaRule,F/A,O,Id,L,T) :-
7356 PragmaRule = pragma(Rule,ids(IDs1,_),Pragmas,_,RuleNb),
7357 Rule = rule(_,_,Guard,Body),
7358 get_prop_inner_loop_vars(PreHeads,[CurrentHead,NextHeads,Guard,Body],PreVarsAndSusps,VarDict,Susp,Vars,PreSusps),
7361 gen_var(OtherSusps),
7363 functor(CurrentHead,OtherF,OtherA),
7364 gen_vars(OtherA,OtherVars),
7365 head_info(CurrentHead,OtherA,OtherVars,OtherSusp,_VarsSusp,HeadPairs),
7366 get_constraint_mode(OtherF/OtherA,Mode),
7367 head_arg_matches(HeadPairs,Mode,VarDict,FirstMatching,VarDict1,[],GroundVars),
7369 delay_phase_end(validate_store_type_assumptions,
7370 ( static_suspension_term(OtherF/OtherA,OtherSuspension),
7371 get_static_suspension_field(OtherF/OtherA,OtherSuspension,state,active,GetState),
7372 get_static_suspension_term_field(arguments,OtherF/OtherA,OtherSuspension,OtherVars)
7375 % create_get_mutable_ref(active,State,GetMutable),
7376 different_from_other_susps(CurrentHead,OtherSusp,PreHeads,PreSusps,DiffSuspGoals),
7378 OtherSusp = OtherSuspension,
7384 ClauseVars = [[OtherSusp|OtherSusps]|PreVarsAndSusps],
7385 build_head(F,A,[O|Id],ClauseVars,ClauseHead),
7387 guard_splitting(Rule,GuardList0),
7388 ( is_stored_in_guard(F/A, RuleNb) ->
7389 GuardList = [Hole1|GuardList0]
7391 GuardList = GuardList0
7393 guard_via_reschedule_new(NextHeads,GuardList,[CurrentHead|PreHeads],GuardCopyList,RestSuspsRetrieval,RescheduledTest),
7395 rest_heads_retrieval_and_matching(NextHeads,NextIDs,[CurrentHead|PreHeads],RestSuspsRetrieval,Susps,VarDict1,VarDict2,[CurrentHead|PreHeads],[OtherSusp|PreSusps],[]),
7396 split_by_ids(NextIDs,Susps,IDs1,Susps1,Susps2),
7397 split_by_ids(NextIDs,NextHeads,IDs1,RestHeads1,_),
7399 partner_constraint_detachments([OtherSusp | Susps1],[CurrentHead|RestHeads1],VarDict2,Susps1Detachments),
7401 RecursiveVars = [OtherSusps|PreVarsAndSusps],
7402 build_head(F,A,[O|Id],RecursiveVars,RecursiveCall),
7403 RecursiveVars2 = [[]|PreVarsAndSusps],
7404 build_head(F,A,[O|Id],RecursiveVars2,RecursiveCall2),
7406 guard_body_copies3(Rule,GuardList,VarDict2,GuardCopyList,BodyCopy),
7407 ( is_stored_in_guard(F/A, RuleNb) ->
7408 GuardCopyList = [GuardAttachment|_] % once( ) ??
7413 ( is_observed(F/A,O) ->
7414 gen_uncond_attach_goal(F/A,Susp,Vars,Attachment,Generation),
7415 gen_state_cond_call(Susp,F/A,RecursiveCall,Generation,ConditionalRecursiveCall),
7416 gen_state_cond_call(Susp,F/A,RecursiveCall2,Generation,ConditionalRecursiveCall2)
7419 ConditionalRecursiveCall = RecursiveCall,
7420 ConditionalRecursiveCall2 = RecursiveCall2
7423 ( chr_pp_flag(debugable,on) ->
7424 my_term_copy(Guard - Body, VarDict, DebugGuard - DebugBody),
7425 DebugTry = 'chr debug_event'( try([OtherSusp|Susps1],[Susp|Susps2],DebugGuard,DebugBody)),
7426 DebugApply = 'chr debug_event'(apply([OtherSusp|Susps1],[Susp|Susps2],DebugGuard,DebugBody))
7432 ( is_stored_in_guard(F/A, RuleNb) ->
7433 GuardAttachment = Attachment,
7434 BodyAttachment = true
7436 GuardAttachment = true,
7437 BodyAttachment = Attachment % will be true if not observed at all
7440 ( member(unique(ID1,UniqueKeys), Pragmas),
7441 check_unique_keys(UniqueKeys,VarDict) ->
7444 ( CurrentSuspTest ->
7451 ConditionalRecursiveCall2
7469 ConditionalRecursiveCall
7475 add_location(Clause,RuleNb,LocatedClause),
7476 L = [LocatedClause | T].
7478 gen_state_cond_call(Susp,FA,Call,Generation,ConditionalCall) :-
7479 ( may_trigger(FA) ->
7480 does_use_field(FA,generation),
7481 delay_phase_end(validate_store_type_assumptions,
7482 ( static_suspension_term(FA,Suspension),
7483 get_update_static_suspension_field(FA,Susp,Suspension,state,active,inactive,GetState,UpdateState),
7484 get_static_suspension_field(FA,Suspension,generation,Generation,GetGeneration),
7485 get_static_suspension_term_field(arguments,FA,Suspension,Args)
7489 delay_phase_end(validate_store_type_assumptions,
7490 ( static_suspension_term(FA,Suspension),
7491 get_update_static_suspension_field(FA,Susp,Suspension,state,active,inactive,GetState,UpdateState),
7492 get_static_suspension_term_field(arguments,FA,Suspension,Args)
7495 GetGeneration = true
7498 ( Susp = Suspension,
7507 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7510 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7512 %% | _ \ _ __ ___ _ __ __ _ __ _ __ _| |_(_) ___ _ __
7513 %% | |_) | '__/ _ \| '_ \ / _` |/ _` |/ _` | __| |/ _ \| '_ \
7514 %% | __/| | | (_) | |_) | (_| | (_| | (_| | |_| | (_) | | | |
7515 %% |_| |_| \___/| .__/ \__,_|\__, |\__,_|\__|_|\___/|_| |_|
7518 propagation_code(Head,ID,RestHeads,RestIDs,Rule,RuleNb,FA,O,Id,L,T) :-
7519 ( RestHeads == [] ->
7520 propagation_single_headed(Head,ID,Rule,RuleNb,FA,O,Id,L,T)
7522 propagation_multi_headed(Head,RestHeads,RestIDs,Rule,RuleNb,FA,O,Id,L,T)
7524 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7525 %% Single headed propagation
7526 %% everything in a single clause
7527 propagation_single_headed(Head,ID,Rule,RuleNb,F/A,O,Id,ProgramList,ProgramTail) :-
7528 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs),
7529 build_head(F,A,Id,VarsSusp,ClauseHead),
7532 build_head(F,A,NextId,VarsSusp,NextHead),
7534 get_constraint_mode(F/A,Mode),
7535 head_arg_matches(HeadPairs,Mode,[],HeadMatching,VarDict,[],GroundVars),
7536 guard_body_copies(Rule,VarDict,GuardCopy,BodyCopy),
7538 % - recursive call -
7539 RecursiveCall = NextHead,
7541 ( unconditional_occurrence(F/A,O), chr_pp_flag(late_allocation,on) ->
7547 Rule = rule(_,_,Guard,Body),
7548 ( chr_pp_flag(debugable,on) ->
7549 my_term_copy(Guard - Body, VarDict, DebugGuard - DebugBody),
7550 DebugTry = 'chr debug_event'( try([],[Susp],DebugGuard,DebugBody)),
7551 DebugApply = 'chr debug_event'(apply([],[Susp],DebugGuard,DebugBody)),
7552 instrument_goal(ActualCut,DebugTry,DebugApply,Cut)
7556 ( may_trigger(F/A), \+ has_no_history(RuleNb)->
7557 use_auxiliary_predicate(novel_production),
7558 use_auxiliary_predicate(extend_history),
7559 does_use_history(F/A,O),
7560 gen_occ_allocation(F/A,O,Vars,Susp,Allocation),
7562 ( named_history(RuleNb,HistoryName,HistoryIDs) ->
7563 ( HistoryIDs == [] ->
7564 empty_named_history_novel_production(HistoryName,NovelProduction),
7565 empty_named_history_extend_history(HistoryName,ExtendHistory)
7573 ( var(NovelProduction) ->
7574 NovelProduction = '$novel_production'(Susp,Tuple),
7575 ExtendHistory = '$extend_history'(Susp,Tuple)
7580 ( is_observed(F/A,O) ->
7581 gen_uncond_attach_goal(F/A,Susp,Vars,Attachment,Generation),
7582 gen_state_cond_call(Susp,F/A,RecursiveCall,Generation,ConditionalRecursiveCall)
7585 ConditionalRecursiveCall = RecursiveCall
7589 NovelProduction = true,
7590 ExtendHistory = true,
7592 ( is_observed(F/A,O) ->
7593 get_allocation_occurrence(F/A,AllocO),
7595 gen_insert_constraint_internal_goal(F/A,Attachment,VarsSusp,Vars,Susp),
7597 ; % more room for improvement?
7598 Attachment = (Attachment1, Attachment2),
7599 gen_occ_allocation(F/A,O,Vars,Susp,Attachment1),
7600 gen_uncond_attach_goal(F/A,Susp,Vars,Attachment2,Generation)
7602 gen_state_cond_call(Susp,F/A,RecursiveCall,Generation,ConditionalRecursiveCall)
7604 gen_occ_allocation(F/A,O,Vars,Susp,Attachment),
7605 ConditionalRecursiveCall = RecursiveCall
7609 ( is_stored_in_guard(F/A, RuleNb) ->
7610 GuardAttachment = Attachment,
7611 BodyAttachment = true
7613 GuardAttachment = true,
7614 BodyAttachment = Attachment % will be true if not observed at all
7628 ConditionalRecursiveCall
7630 add_location(Clause,RuleNb,LocatedClause),
7631 ProgramList = [LocatedClause | ProgramTail].
7633 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7634 %% multi headed propagation
7635 %% prelude + predicates to accumulate the necessary combinations of suspended
7636 %% constraints + predicate to execute the body
7637 propagation_multi_headed(Head,RestHeads,RestIDs,Rule,RuleNb,FA,O,Id,L,T) :-
7638 RestHeads = [First|Rest],
7639 propagation_prelude(Head,RestHeads,Rule,FA,O,Id,L,L1),
7640 extend_id(Id,ExtendedId),
7641 propagation_nested_code(Rest,[First,Head],RestIDs,Rule,RuleNb,FA,O,ExtendedId,L1,T).
7643 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7644 propagation_prelude(Head,[First|Rest],Rule,F/A,O,Id,L,T) :-
7645 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs),
7646 build_head(F,A,Id,VarsSusp,PreludeHead),
7647 get_constraint_mode(F/A,Mode),
7648 head_arg_matches(HeadPairs,Mode,[],FirstMatching,VarDict,[],GroundVars),
7649 Rule = rule(_,_,Guard,Body),
7650 extra_active_delegate_variables(Head,[First,Rest,Guard,Body],VarDict,ExtraVars),
7652 lookup_passive_head(First,[Head],VarDict,GroundVars,FirstSuspGoal,Susps),
7654 gen_occ_allocation(F/A,O,Vars,Susp,CondAllocation),
7656 extend_id(Id,NestedId),
7657 append([Susps|VarsSusp],ExtraVars,NestedVars),
7658 build_head(F,A,[O|NestedId],NestedVars,NestedHead),
7659 NestedCall = NestedHead,
7669 add_dummy_location(Prelude,LocatedPrelude),
7670 L = [LocatedPrelude|T].
7672 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7673 propagation_nested_code([],[CurrentHead|PreHeads],RestIDs,Rule,RuleNb,FA,O,Id,L,T) :-
7674 universal_search_iterator_end([CurrentHead|PreHeads],[],Rule,FA,O,Id,L,L1),
7675 propagation_body(CurrentHead,PreHeads,RestIDs,Rule,RuleNb,FA,O,Id,L1,T).
7677 propagation_nested_code([Head|RestHeads],PreHeads,RestIDs,Rule,RuleNb,FA,O,Id,L,T) :-
7678 universal_search_iterator_end(PreHeads,[Head|RestHeads],Rule,FA,O,Id,L,L1),
7679 universal_search_iterator([Head|RestHeads],PreHeads,Rule,FA,O,Id,L1,L2),
7681 propagation_nested_code(RestHeads,[Head|PreHeads],RestIDs,Rule,RuleNb,FA,O,IncId,L2,T).
7683 %check_fd_lookup_condition(_,_,_,_) :- fail.
7684 check_fd_lookup_condition(F,A,_,_) :-
7685 get_store_type(F/A,global_singleton), !.
7686 check_fd_lookup_condition(F,A,CurrentHead,PreHeads) :-
7687 \+ may_trigger(F/A),
7688 get_functional_dependency(F/A,1,P,K),
7689 copy_term(P-K,CurrentHead-Key),
7690 term_variables(PreHeads,PreVars),
7691 intersect_eq(Key,PreVars,Key),!.
7693 propagation_body(CurrentHead,PreHeads,RestIDs,Rule,RuleNb,F/A,O,Id,L,T) :-
7694 Rule = rule(_,H2,Guard,Body),
7695 gen_var_susp_list_for_b(PreHeads,[CurrentHead,Guard,Body],VarDict1,PreVarsAndSuspsList,FirstVarsSusp,AllSusps,PrevIterators),
7696 flatten(PreVarsAndSuspsList,PreVarsAndSusps),
7697 init(AllSusps,RestSusps),
7698 last(AllSusps,Susp),
7700 gen_var(OtherSusps),
7701 functor(CurrentHead,OtherF,OtherA),
7702 gen_vars(OtherA,OtherVars),
7703 delay_phase_end(validate_store_type_assumptions,
7704 ( static_suspension_term(OtherF/OtherA,Suspension),
7705 get_static_suspension_field(OtherF/OtherA,Suspension,state,active,GetState),
7706 get_static_suspension_term_field(arguments,OtherF/OtherA,Suspension,OtherVars)
7709 % create_get_mutable_ref(active,State,GetMutable),
7711 OtherSusp = Suspension,
7714 ClauseVars = [[OtherSusp|OtherSusps]|PreVarsAndSusps],
7715 build_head(F,A,[O|Id],ClauseVars,ClauseHead),
7716 ( check_fd_lookup_condition(OtherF,OtherA,CurrentHead,PreHeads) -> % iterator (OtherSusps) is empty at runtime
7717 universal_search_iterator_failure_vars(PreHeads,Id,PreVarsAndSuspsList,FirstVarsSusp,PrevIterators,PreVarsAndSusps1,PrevId0),
7718 RecursiveVars = PreVarsAndSusps1
7720 RecursiveVars = [OtherSusps|PreVarsAndSusps],
7726 PrevId = [O|PrevId0]
7728 build_head(F,A,PrevId,RecursiveVars,RecursiveHead),
7729 RecursiveCall = RecursiveHead,
7730 CurrentHead =.. [_|OtherArgs],
7731 pairup(OtherArgs,OtherVars,OtherPairs),
7732 get_constraint_mode(OtherF/OtherA,Mode),
7733 head_arg_matches(OtherPairs,Mode,VarDict1,Matching,VarDict),
7735 different_from_other_susps(CurrentHead,OtherSusp,PreHeads,RestSusps,DiffSuspGoals),
7736 guard_body_copies(Rule,VarDict,GuardCopy,BodyCopy),
7737 get_occurrence(F/A,O,_,ID),
7739 ( is_observed(F/A,O) ->
7740 init(FirstVarsSusp,FirstVars),
7741 gen_uncond_attach_goal(F/A,Susp,FirstVars,Attachment,Generation),
7742 gen_state_cond_call(Susp,F/A,RecursiveCall,Generation,ConditionalRecursiveCall)
7745 ConditionalRecursiveCall = RecursiveCall
7747 ( (is_least_occurrence(RuleNb) ; has_no_history(RuleNb)) ->
7748 NovelProduction = true,
7749 ExtendHistory = true
7750 ; \+ may_trigger(F/A), maplist(is_passive(RuleNb),RestIDs) ->
7751 NovelProduction = true,
7752 ExtendHistory = true
7754 get_occurrence(F/A,O,_,ID),
7755 use_auxiliary_predicate(novel_production),
7756 use_auxiliary_predicate(extend_history),
7757 does_use_history(F/A,O),
7758 ( named_history(RuleNb,HistoryName,HistoryIDs) ->
7759 ( HistoryIDs == [] ->
7760 empty_named_history_novel_production(HistoryName,NovelProduction),
7761 empty_named_history_extend_history(HistoryName,ExtendHistory)
7763 reverse([OtherSusp|RestSusps],NamedSusps),
7764 named_history_susps(HistoryIDs,[ID|RestIDs],[Susp|NamedSusps],HistorySusps),
7765 HistorySusps = [HistorySusp|_],
7767 ( length(HistoryIDs, 1) ->
7768 ExtendHistory = '$extend_history'(HistorySusp,HistoryName),
7769 NovelProduction = '$novel_production'(HistorySusp,HistoryName)
7771 findall(ConstraintSymbol,(member(SomeID,HistoryIDs),get_occurrence_from_id(ConstraintSymbol,_,RuleNb,SomeID)),ConstraintSymbols),
7772 Tuple =.. [t,HistoryName|HistorySusps]
7777 findall(Functor/Arity,(member(H,H2),functor(H,Functor,Arity)),ConstraintSymbols),
7778 sort([ID|RestIDs],HistoryIDs),
7779 history_susps(RestIDs,[OtherSusp|RestSusps],Susp,ID,HistorySusps),
7780 Tuple =.. [t,RuleNb|HistorySusps]
7783 ( var(NovelProduction) ->
7784 novel_production_calls(ConstraintSymbols,HistoryIDs,HistorySusps,RuleNb,TupleVar,NovelProductions),
7785 ExtendHistory = '$extend_history'(HistorySusp,TupleVar),
7786 NovelProduction = ( TupleVar = Tuple, NovelProductions )
7793 ( chr_pp_flag(debugable,on) ->
7794 Rule = rule(_,_,Guard,Body),
7795 my_term_copy(Guard - Body, VarDict, DebugGuard - DebugBody),
7796 get_occurrence(F/A,O,_,ID),
7797 sort_by_key([Susp,OtherSusp|RestSusps],[ID|RestIDs],KeptSusps),
7798 DebugTry = 'chr debug_event'( try([],KeptSusps,DebugGuard,DebugBody)),
7799 DebugApply = 'chr debug_event'(apply([],KeptSusps,DebugGuard,DebugBody))
7805 ( is_stored_in_guard(F/A, RuleNb) ->
7806 GuardAttachment = Attachment,
7807 BodyAttachment = true
7809 GuardAttachment = true,
7810 BodyAttachment = Attachment % will be true if not observed at all
7826 ConditionalRecursiveCall
7830 add_location(Clause,RuleNb,LocatedClause),
7831 L = [LocatedClause|T].
7833 novel_production_calls([],[],[],_,_,true).
7834 novel_production_calls([ConstraintSymbol|ConstraintSymbols],[ID|IDs],[Suspension|Suspensions],RuleNb,Tuple,(Goal,Goals)) :-
7835 get_occurrence_from_id(ConstraintSymbol,Occurrence,RuleNb,ID),
7836 delay_phase_end(validate_store_type_assumptions,novel_production_call(ConstraintSymbol,Occurrence,'$novel_production'(Suspension,Tuple),Goal)),
7837 novel_production_calls(ConstraintSymbols,IDs,Suspensions,RuleNb,Tuple,Goals).
7839 history_susps(RestIDs,ReversedRestSusps,Susp,ID,HistorySusps) :-
7840 reverse(ReversedRestSusps,RestSusps),
7841 sort_by_key([Susp|RestSusps],[ID|RestIDs],HistorySusps).
7843 named_history_susps([],_,_,[]).
7844 named_history_susps([HistoryID|HistoryIDs],IDs,Susps,[HistorySusp|HistorySusps]) :-
7845 select2(HistoryID,HistorySusp,IDs,Susps,RestIDs,RestSusps), !,
7846 named_history_susps(HistoryIDs,RestIDs,RestSusps,HistorySusps).
7850 gen_var_susp_list_for([Head],Terms,VarDict,HeadVars,VarsSusp,Susp) :-
7853 head_info(Head,A,_Vars,Susp,VarsSusp,HeadPairs),
7854 get_constraint_mode(F/A,Mode),
7855 head_arg_matches(HeadPairs,Mode,[],_,VarDict),
7856 extra_active_delegate_variables(Head,Terms,VarDict,ExtraVars),
7857 append(VarsSusp,ExtraVars,HeadVars).
7858 gen_var_susp_list_for([Head|Heads],Terms,NVarDict,VarsSusps,Rest,Susps) :-
7859 gen_var_susp_list_for(Heads,[Head|Terms],VarDict,Rest,_,_),
7862 head_info(Head,A,_Vars,Susp,_VarsSusp,HeadPairs),
7863 get_constraint_mode(F/A,Mode),
7864 head_arg_matches(HeadPairs,Mode,VarDict,_,NVarDict),
7865 passive_delegate_variables(Head,Heads,Terms,NVarDict,HeadVars),
7866 append(HeadVars,[Susp,Susps|Rest],VarsSusps).
7869 % VarDict for the copies of variables in the original heads
7870 % VarsSuspsList list of lists of arguments for the successive heads
7871 % FirstVarsSusp top level arguments
7872 % SuspList list of all suspensions
7873 % Iterators list of all iterators
7874 gen_var_susp_list_for_b([Head],NextHeads,VarDict,[HeadVars],VarsSusp,[Susp],[]) :-
7877 head_info(Head,A,_Vars,Susp,VarsSusp,Pairs), % make variables for argument positions
7878 get_constraint_mode(F/A,Mode),
7879 head_arg_matches(Pairs,Mode,[],_,VarDict), % copy variables inside arguments, build dictionary
7880 extra_active_delegate_variables(Head,NextHeads,VarDict,ExtraVars), % decide what additional variables are needed
7881 append(VarsSusp,ExtraVars,HeadVars). % add additional variables to head variables
7882 gen_var_susp_list_for_b([Head|Heads],NextHeads,NVarDict,[Vars|RestVars],FirstVarsSusp,[Susp|SuspList],[Susps|Iterators]) :-
7883 gen_var_susp_list_for_b(Heads,[Head|NextHeads],VarDict,RestVars,FirstVarsSusp,SuspList,Iterators),
7886 head_info(Head,A,_Vars,Susp,_VarsSusp,HeadPairs),
7887 get_constraint_mode(F/A,Mode),
7888 head_arg_matches(HeadPairs,Mode,VarDict,_,NVarDict),
7889 passive_delegate_variables(Head,Heads,NextHeads,NVarDict,HeadVars),
7890 append(HeadVars,[Susp,Susps],Vars).
7892 get_prop_inner_loop_vars([Head],NextHeads,HeadVars,VarDict,Susp,Vars,[]) :-
7895 head_info(Head,A,Vars,Susp,VarsSusp,Pairs),
7896 get_constraint_mode(F/A,Mode),
7897 head_arg_matches(Pairs,Mode,[],_,VarDict),
7898 extra_active_delegate_variables(Head,NextHeads,VarDict,ExtraVars),
7899 append(VarsSusp,ExtraVars,HeadVars).
7900 get_prop_inner_loop_vars([Head|Heads],Terms,VarsSusps,NVarDict,MainSusp,MainVars,[Susp|RestSusps]) :-
7901 get_prop_inner_loop_vars(Heads,[Head|Terms],RestVarsSusp,VarDict,MainSusp,MainVars,RestSusps),
7904 head_info(Head,A,_Vars,Susp,_VarsSusp,Pairs),
7905 get_constraint_mode(F/A,Mode),
7906 head_arg_matches(Pairs,Mode,VarDict,_,NVarDict),
7907 passive_delegate_variables(Head,Heads,Terms,NVarDict,HeadVars),
7908 append(HeadVars,[Susp,Susps|RestVarsSusp],VarsSusps).
7910 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7912 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7914 %% | _ \ __ _ ___ ___(_)_ _____ | | | | ___ __ _ __| |
7915 %% | |_) / _` / __/ __| \ \ / / _ \ | |_| |/ _ \/ _` |/ _` |
7916 %% | __/ (_| \__ \__ \ |\ V / __/ | _ | __/ (_| | (_| |
7917 %% |_| \__,_|___/___/_| \_/ \___| |_| |_|\___|\__,_|\__,_|
7920 %% | _ \ ___| |_ _ __(_) _____ ____ _| |
7921 %% | |_) / _ \ __| '__| |/ _ \ \ / / _` | |
7922 %% | _ < __/ |_| | | | __/\ V / (_| | |
7923 %% |_| \_\___|\__|_| |_|\___| \_/ \__,_|_|
7926 %% | _ \ ___ ___ _ __ __| | ___ _ __(_)_ __ __ _
7927 %% | |_) / _ \/ _ \| '__/ _` |/ _ \ '__| | '_ \ / _` |
7928 %% | _ < __/ (_) | | | (_| | __/ | | | | | | (_| |
7929 %% |_| \_\___|\___/|_| \__,_|\___|_| |_|_| |_|\__, |
7932 reorder_heads(RuleNb,Head,RestHeads,RestIDs,NRestHeads,NRestIDs) :-
7933 ( chr_pp_flag(reorder_heads,on), length(RestHeads,Length), Length =< 6 ->
7934 reorder_heads_main(RuleNb,Head,RestHeads,RestIDs,NRestHeads,NRestIDs)
7936 NRestHeads = RestHeads,
7940 reorder_heads_main(RuleNb,Head,RestHeads,RestIDs,NRestHeads,NRestIDs) :-
7941 term_variables(Head,Vars),
7942 InitialData = entry([],[],Vars,RestHeads,RestIDs,RuleNb),
7943 copy_term_nat(InitialData,InitialDataCopy),
7944 a_star(InitialDataCopy,FD^(chr_translate:final_data(FD)),N^EN^C^(chr_translate:expand_data(N,EN,C)),FinalData),
7945 InitialDataCopy = InitialData,
7946 FinalData = entry(RNRestHeads,RNRestIDs,_,_,_,_),
7947 reverse(RNRestHeads,NRestHeads),
7948 reverse(RNRestIDs,NRestIDs).
7950 final_data(Entry) :-
7951 Entry = entry(_,_,_,_,[],_).
7953 expand_data(Entry,NEntry,Cost) :-
7954 Entry = entry(Heads,IDs,Vars,NHeads,NIDs,RuleNb),
7955 select2(Head1,ID1,NHeads,NIDs,NHeads1,NIDs1),
7956 term_variables([Head1|Vars],Vars1),
7957 NEntry = entry([Head1|Heads],[ID1|IDs],Vars1,NHeads1,NIDs1,RuleNb),
7958 order_score(Head1,ID1,Vars,NHeads1,RuleNb,Cost).
7960 % Assigns score to head based on known variables and heads to lookup
7961 order_score(Head,ID,KnownVars,RestHeads,RuleNb,Score) :-
7963 get_store_type(F/A,StoreType),
7964 order_score(StoreType,Head,ID,KnownVars,RestHeads,RuleNb,Score).
7966 order_score(default,Head,_ID,KnownVars,RestHeads,RuleNb,Score) :-
7967 term_variables(Head,HeadVars),
7968 term_variables(RestHeads,RestVars),
7969 order_score_vars(HeadVars,KnownVars,RestVars,Score).
7970 order_score(multi_inthash(Indexes),Head,_ID,KnownVars,RestHeads,RuleNb,Score) :-
7971 order_score_indexes(Indexes,Head,KnownVars,0,Score).
7972 order_score(multi_hash(Indexes),Head,_ID,KnownVars,RestHeads,RuleNb,Score) :-
7973 order_score_indexes(Indexes,Head,KnownVars,0,Score).
7974 order_score(global_ground,Head,ID,KnownVars,RestHeads,RuleNb,Score) :-
7975 term_variables(Head,HeadVars),
7976 term_variables(RestHeads,RestVars),
7977 order_score_vars(HeadVars,KnownVars,RestVars,Score_),
7978 Score is Score_ * 2.
7979 order_score(var_assoc_store(_,_),_,_,_,_,_,1).
7980 order_score(global_singleton,_Head,ID,_KnownVars,_RestHeads,_RuleNb,Score) :-
7981 Score = 1. % guaranteed O(1)
7983 order_score(multi_store(StoreTypes),Head,ID,KnownVars,RestHeads,RuleNb,Score) :-
7984 maplist(order_score1(Head,ID,KnownVars,RestHeads,RuleNb),StoreTypes,Scores),
7985 min_list(Scores,Score).
7986 order_score1(Head,ID,KnownVars,RestHeads,RuleNb,StoreType,Score) :-
7987 ( order_score(StoreType,Head,ID,KnownVars,RestHeads,RuleNb,Score) ->
7992 order_score(identifier_store(Index),Head,ID,KnownVars,RestHeads,RuleNb,Score) :-
7994 order_score(type_indexed_identifier_store(_,_),Head,ID,KnownVars,RestHeads,RuleNb,Score) :-
7997 order_score_indexes([],_,_,Score,NScore) :-
7998 Score > 0, NScore = 100.
7999 order_score_indexes([I|Is],Head,KnownVars,Score,NScore) :-
8000 multi_hash_key_args(I,Head,Args),
8001 ( forall(Arg,Args,memberchk_eq(Arg,KnownVars)) ->
8006 order_score_indexes(Is,Head,KnownVars,Score1,NScore).
8008 order_score_vars(Vars,KnownVars,RestVars,Score) :-
8009 order_score_count_vars(Vars,KnownVars,RestVars,K-R-O),
8013 Score is max(10 - K,0)
8015 Score is max(10 - R,1) * 10
8017 Score is max(10-O,1) * 100
8019 order_score_count_vars([],_,_,0-0-0).
8020 order_score_count_vars([V|Vs],KnownVars,RestVars,NK-NR-NO) :-
8021 order_score_count_vars(Vs,KnownVars,RestVars,K-R-O),
8022 ( memberchk_eq(V,KnownVars) ->
8025 ; memberchk_eq(V,RestVars) ->
8033 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8035 %% |_ _|_ __ | (_)_ __ (_)_ __ __ _
8036 %% | || '_ \| | | '_ \| | '_ \ / _` |
8037 %% | || | | | | | | | | | | | | (_| |
8038 %% |___|_| |_|_|_|_| |_|_|_| |_|\__, |
8042 create_get_mutable_ref(V,M,GM) :- GM = (M = mutable(V)).
8043 create_get_mutable(V,M,GM) :- M = mutable(V), GM = true.
8047 %% create_get_mutable(V,M,GM) :- GM = get_mutable(V,M).
8048 %% create_get_mutable_ref(V,M,GM) :- GM = get_mutable(V,M).
8051 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8053 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8055 %% | | | | |_(_) (_) |_ _ _
8056 %% | | | | __| | | | __| | | |
8057 %% | |_| | |_| | | | |_| |_| |
8058 %% \___/ \__|_|_|_|\__|\__, |
8061 % Create a fresh variable.
8064 % Create =N= fresh variables.
8068 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs) :-
8069 vars_susp(A,Vars,Susp,VarsSusp),
8071 pairup(Args,Vars,HeadPairs).
8073 inc_id([N|Ns],[O|Ns]) :-
8075 dec_id([N|Ns],[M|Ns]) :-
8078 extend_id(Id,[0|Id]).
8080 next_id([_,N|Ns],[O|Ns]) :-
8083 % return clause Head
8084 % for F/A constraint symbol, predicate identifier Id and arguments Head
8085 build_head(F,A,Id,Args,Head) :-
8086 buildName(F,A,Id,Name),
8087 ( (chr_pp_flag(debugable,on) ; is_stored(F/A), ( has_active_occurrence(F/A) ; chr_pp_flag(late_allocation,off)),
8088 ( may_trigger(F/A) ;
8089 get_allocation_occurrence(F/A,AO),
8090 get_max_occurrence(F/A,MO),
8092 Head =.. [Name|Args]
8094 init(Args,ArgsWOSusp), % XXX not entirely correct!
8095 Head =.. [Name|ArgsWOSusp]
8098 % return predicate name Result
8099 % for Fct/Aty constraint symbol and predicate identifier List
8100 buildName(Fct,Aty,List,Result) :-
8101 ( (chr_pp_flag(debugable,on) ; (once((is_stored(Fct/Aty), ( has_active_occurrence(Fct/Aty) ; chr_pp_flag(late_allocation,off)),
8102 ( may_trigger(Fct/Aty) ; get_allocation_occurrence(Fct/Aty,AO), get_max_occurrence(Fct/Aty,MO),
8103 MO >= AO ) ; List \= [0])) ) ) ->
8104 atom_concat(Fct, '___' ,FctSlash),
8105 atomic_concat(FctSlash,Aty,FctSlashAty),
8106 buildName_(List,FctSlashAty,Result)
8111 buildName_([],Name,Name).
8112 buildName_([N|Ns],Name,Result) :-
8113 buildName_(Ns,Name,Name1),
8114 atom_concat(Name1,'__',NameDash), % '_' is a char :-(
8115 atomic_concat(NameDash,N,Result).
8117 vars_susp(A,Vars,Susp,VarsSusp) :-
8119 append(Vars,[Susp],VarsSusp).
8121 or_pattern(Pos,Pat) :-
8123 Pat is 1 << Pow. % was 2 ** X
8125 and_pattern(Pos,Pat) :-
8127 Y is 1 << X, % was 2 ** X
8128 Pat is (-1)*(Y + 1).
8130 make_name(Prefix,F/A,Name) :-
8131 atom_concat_list([Prefix,F,'___',A],Name).
8133 %===============================================================================
8134 % Attribute for attributed variables
8136 make_attr(N,Mask,SuspsList,Attr) :-
8137 length(SuspsList,N),
8138 Attr =.. [v,Mask|SuspsList].
8140 get_all_suspensions2(N,Attr,SuspensionsList) :-
8141 chr_pp_flag(dynattr,off), !,
8142 make_attr(N,_,SuspensionsList,Attr).
8145 get_all_suspensions2(N,Attr,Goal,SuspensionsList) :-
8146 % writeln(get_all_suspensions2),
8147 length(SuspensionsList,N),
8148 Goal = 'chr all_suspensions'(SuspensionsList,1,Attr).
8152 normalize_attr(Attr,NormalGoal,NormalAttr) :-
8153 % writeln(normalize_attr),
8154 NormalGoal = 'chr normalize_attr'(Attr,NormalAttr).
8156 get_suspensions(N,Position,TAttr,(TAttr = Attr),Suspensions) :-
8157 chr_pp_flag(dynattr,off), !,
8158 make_attr(N,_,SuspsList,Attr),
8159 nth1(Position,SuspsList,Suspensions).
8162 get_suspensions(N,Position,TAttr,Goal,Suspensions) :-
8163 % writeln(get_suspensions),
8165 ( memberchk(Position-Suspensions,TAttr) ->
8171 %-------------------------------------------------------------------------------
8172 % +N: number of constraint symbols
8173 % +Suspension: source-level variable, for suspension
8174 % +Position: constraint symbol number
8175 % -Attr: source-level term, for new attribute
8176 singleton_attr(N,Suspension,Position,Attr) :-
8177 chr_pp_flag(dynattr,off), !,
8178 or_pattern(Position,Pattern),
8179 make_attr(N,Pattern,SuspsList,Attr),
8180 nth1(Position,SuspsList,[Suspension]),
8181 chr_delete(SuspsList,[Suspension],RestSuspsList),
8182 set_elems(RestSuspsList,[]).
8185 singleton_attr(N,Suspension,Position,Attr) :-
8186 % writeln(singleton_attr),
8187 Attr = [Position-[Suspension]].
8189 %-------------------------------------------------------------------------------
8190 % +N: number of constraint symbols
8191 % +Suspension: source-level variable, for suspension
8192 % +Position: constraint symbol number
8193 % +TAttr: source-level variable, for old attribute
8194 % -Goal: goal for creating new attribute
8195 % -NTAttr: source-level variable, for new attribute
8196 add_attr(N,Suspension,Position,TAttr,Goal,NTAttr) :-
8197 chr_pp_flag(dynattr,off), !,
8198 make_attr(N,Mask,SuspsList,Attr),
8199 or_pattern(Position,Pattern),
8200 nth1(Position,SuspsList,Susps),
8201 substitute_eq(Susps,SuspsList,[Suspension|Susps],SuspsList1),
8202 make_attr(N,Mask,SuspsList1,NewAttr1),
8203 substitute_eq(Susps,SuspsList,[Suspension],SuspsList2),
8204 make_attr(N,NewMask,SuspsList2,NewAttr2),
8207 ( Mask /\ Pattern =:= Pattern ->
8210 NewMask is Mask \/ Pattern,
8216 add_attr(N,Suspension,Position,TAttr,Goal,NTAttr) :-
8217 % writeln(add_attr),
8219 ( 'chr select'(TAttr,Position-Suspensions,RAttr) ->
8220 NTAttr = [Position-[Suspension|Suspensions]|RAttr]
8222 NTAttr = [Position-[Suspension]|TAttr]
8225 rem_attr(N,Var,Suspension,Position,TAttr,Goal) :-
8226 chr_pp_flag(dynattr,off), !,
8227 or_pattern(Position,Pattern),
8228 and_pattern(Position,DelPattern),
8229 make_attr(N,Mask,SuspsList,Attr),
8230 nth1(Position,SuspsList,Susps),
8231 substitute_eq(Susps,SuspsList,[],SuspsList1),
8232 make_attr(N,NewMask,SuspsList1,Attr1),
8233 substitute_eq(Susps,SuspsList,NewSusps,SuspsList2),
8234 make_attr(N,Mask,SuspsList2,Attr2),
8235 get_target_module(Mod),
8238 ( Mask /\ Pattern =:= Pattern ->
8239 'chr sbag_del_element'(Susps,Suspension,NewSusps),
8241 NewMask is Mask /\ DelPattern,
8245 put_attr(Var,Mod,Attr1)
8248 put_attr(Var,Mod,Attr2)
8256 rem_attr(N,Var,Suspension,Position,TAttr,Goal) :-
8257 % writeln(rem_attr),
8258 get_target_module(Mod),
8260 ( 'chr select'(TAttr,Position-Suspensions,RAttr) ->
8261 'chr sbag_del_element'(Suspensions,Suspension,NSuspensions),
8262 ( NSuspensions == [] ->
8266 put_attr(Var,Mod,RAttr)
8269 put_attr(Var,Mod,[Position-NSuspensions|RAttr])
8275 %-------------------------------------------------------------------------------
8276 % +N: number of constraint symbols
8277 % +TAttr1: source-level variable, for attribute
8278 % +TAttr2: source-level variable, for other attribute
8279 % -Goal: goal for merging the two attributes
8280 % -Attr: source-level term, for merged attribute
8281 merge_attributes(N,TAttr1,TAttr2,Goal,Attr) :-
8282 chr_pp_flag(dynattr,off), !,
8283 make_attr(N,Mask1,SuspsList1,Attr1),
8284 merge_attributes2(N,Mask1,SuspsList1,TAttr2,Goal2,Attr),
8291 merge_attributes(N,TAttr1,TAttr2,Goal,Attr) :-
8292 % writeln(merge_attributes),
8294 sort(TAttr1,Sorted1),
8295 sort(TAttr2,Sorted2),
8296 'chr new_merge_attributes'(Sorted1,Sorted2,Attr)
8300 %-------------------------------------------------------------------------------
8301 % +N: number of constraint symbols
8303 % +SuspsList1: static term, for suspensions list
8304 % +TAttr2: source-level variable, for other attribute
8305 % -Goal: goal for merging the two attributes
8306 % -Attr: source-level term, for merged attribute
8307 merge_attributes2(N,Mask1,SuspsList1,TAttr2,Goal,Attr) :-
8308 make_attr(N,Mask2,SuspsList2,Attr2),
8309 bagof(G,X ^ Y ^ SY ^ M ^ (member2(SuspsList1,SuspsList2,X-Y),G = (sort(Y,SY),'chr merge_attributes'(X,SY,M))),Gs),
8310 list2conj(Gs,SortGoals),
8311 bagof(MS,A ^ B ^ C ^ member((A,'chr merge_attributes'(B,C,MS)),Gs), SuspsList),
8312 make_attr(N,Mask,SuspsList,Attr),
8316 Mask is Mask1 \/ Mask2
8320 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8321 % Storetype dependent lookup
8323 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8324 %% lookup_passive_head(+Head,+PreviousVars,+RenamingVarDict,
8325 %% -Goal,-SuspensionList) is det.
8327 % Create a universal lookup goal for given head.
8328 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8329 lookup_passive_head(Head,PreJoin,VarDict,Goal,AllSusps) :-
8331 get_store_type(F/A,StoreType),
8332 lookup_passive_head(StoreType,Head,PreJoin,VarDict,[],Goal,AllSusps).
8334 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8335 %% lookup_passive_head(+Head,+PreviousVars,+RenamingVarDict,+GroundVars,
8336 %% -Goal,-SuspensionList) is det.
8338 % Create a universal lookup goal for given head.
8339 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8340 lookup_passive_head(Head,PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
8342 get_store_type(F/A,StoreType),
8343 lookup_passive_head(StoreType,Head,PreJoin,VarDict,GroundVars,Goal,AllSusps).
8345 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8346 %% lookup_passive_head(+StoreType,+Head,+PreviousVars,+RenamingVarDict,
8347 %% +GroundVars,-Goal,-SuspensionList) is det.
8349 % Create a universal lookup goal for given head.
8350 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8351 lookup_passive_head(default,Head,PreJoin,VarDict,_,Goal,AllSusps) :-
8353 passive_head_via(Head,PreJoin,VarDict,Goal,AllSusps),
8354 update_store_type(F/A,default).
8355 lookup_passive_head(multi_inthash(Indexes),Head,_PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
8356 hash_lookup_passive_head(inthash,Indexes,Head,VarDict,GroundVars,Goal,AllSusps,_).
8357 lookup_passive_head(multi_hash(Indexes),Head,_PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
8358 hash_lookup_passive_head(hash,Indexes,Head,VarDict,GroundVars,Goal,AllSusps,_).
8359 lookup_passive_head(global_ground,Head,_PreJoin,_VarDict,_,(Goal,AllSusps \== []),AllSusps) :-
8361 global_ground_store_name(F/A,StoreName),
8362 make_get_store_goal(StoreName,AllSusps,Goal), % Goal = nb_getval(StoreName,AllSusps),
8363 update_store_type(F/A,global_ground).
8364 lookup_passive_head(var_assoc_store(VarIndex,KeyIndex),Head,_PreJoin,VarDict,_,Goal,AllSusps) :-
8365 arg(VarIndex,Head,OVar),
8366 arg(KeyIndex,Head,OKey),
8367 translate([OVar,OKey],VarDict,[Var,Key]),
8368 get_target_module(Module),
8370 get_attr(Var,Module,AssocStore),
8371 lookup_assoc_store(AssocStore,Key,AllSusps)
8373 lookup_passive_head(global_singleton,Head,_PreJoin,_VarDict,_,Goal,AllSusps) :-
8375 global_singleton_store_name(F/A,StoreName),
8376 make_get_store_goal(StoreName,Susp,GetStoreGoal),
8377 Goal = (GetStoreGoal,Susp \== [],AllSusps = [Susp]),
8378 update_store_type(F/A,global_singleton).
8379 lookup_passive_head(multi_store(StoreTypes),Head,PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
8381 member(ST,StoreTypes),
8382 lookup_passive_head(ST,Head,PreJoin,VarDict,GroundVars,Goal,AllSusps)
8384 lookup_passive_head(identifier_store(Index),Head,PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
8386 arg(Index,Head,Var),
8387 translate([Var],VarDict,[KeyVar]),
8388 delay_phase_end(validate_store_type_assumptions,
8389 identifier_lookup(F/A,Index,AllSusps,KeyVar,Goal)
8391 update_store_type(F/A,identifier_store(Index)),
8392 get_identifier_index(F/A,Index,_).
8393 lookup_passive_head(type_indexed_identifier_store(Index,IndexType),Head,PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
8395 arg(Index,Head,Var),
8397 translate([Var],VarDict,[KeyVar]),
8399 ; ground(Var), Var = '$chr_identifier_match'(ActualVar,_) ->
8400 lookup_identifier_atom(IndexType,ActualVar,KeyVar,LookupGoal),
8401 Goal = (LookupGoal,StructGoal)
8403 delay_phase_end(validate_store_type_assumptions,
8404 type_indexed_identifier_lookup(F/A,Index,IndexType,AllSusps,KeyVar,StructGoal)
8406 update_store_type(F/A,type_indexed_identifier_store(Index,IndexType)),
8407 get_type_indexed_identifier_index(IndexType,F/A,Index,_).
8409 identifier_lookup(C,Index,AllSusps,KeyVar,Goal) :-
8410 get_identifier_size(ISize),
8411 functor(Struct,struct,ISize),
8412 get_identifier_index(C,Index,IIndex),
8413 arg(IIndex,Struct,AllSusps),
8414 Goal = (KeyVar = Struct).
8416 type_indexed_identifier_lookup(C,Index,IndexType,AllSusps,KeyVar,Goal) :-
8417 type_indexed_identifier_structure(IndexType,Struct),
8418 get_type_indexed_identifier_index(IndexType,C,Index,IIndex),
8419 arg(IIndex,Struct,AllSusps),
8420 Goal = (KeyVar = Struct).
8422 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8423 %% hash_lookup_passive_head(+StoreType,+Indexes,+Head,+RenamingVarDict,
8424 %% +GroundVars,-Goal,-SuspensionList,-Index) is det.
8426 % Create a universal hash lookup goal for given head.
8427 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8428 hash_lookup_passive_head(HashType,Indexes,Head,VarDict,GroundVars,Goal,AllSusps,Index) :-
8430 member(Index,Indexes),
8431 multi_hash_key_args(Index,Head,KeyArgs),
8433 translate(KeyArgs,VarDict,KeyArgCopies)
8435 ground(KeyArgs), KeyArgCopies = KeyArgs
8438 ( KeyArgCopies = [KeyCopy] ->
8441 KeyCopy =.. [k|KeyArgCopies]
8444 multi_hash_lookup_goal(F/A,HashType,Index,KeyCopy,AllSusps,LookupGoal),
8446 check_ground(GroundVars,KeyArgs,OriginalGroundCheck),
8447 my_term_copy(OriginalGroundCheck,VarDict,GroundCheck),
8449 Goal = (GroundCheck,LookupGoal),
8451 ( HashType == inthash ->
8452 update_store_type(F/A,multi_inthash([Index]))
8454 update_store_type(F/A,multi_hash([Index]))
8457 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8458 %% existential_lookup(+StoreType,+Head,+PrevVariablesHead,+RenamingVarDict,
8459 %% +GroundVariables,-SuspensionTerm,-Goal,-SuspVar,
8460 %% +VarArgDict,-NewVarArgDict) is det.
8462 % Create existential lookup goal for given head.
8463 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8464 existential_lookup(var_assoc_store(VarIndex,KeyIndex),Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,Pairs) :- !,
8465 lookup_passive_head(var_assoc_store(VarIndex,KeyIndex),Head,PreJoin,VarDict,GroundVars,UniversalGoal,AllSusps),
8466 sbag_member_call(Susp,AllSusps,Sbag),
8468 delay_phase_end(validate_store_type_assumptions,
8469 ( static_suspension_term(F/A,SuspTerm),
8470 get_static_suspension_field(F/A,SuspTerm,state,active,GetState)
8479 existential_lookup(global_singleton,Head,_PreJoin,_VarDict,_,SuspTerm,Goal,Susp,Pairs,Pairs) :- !,
8481 global_singleton_store_name(F/A,StoreName),
8482 make_get_store_goal(StoreName,Susp,GetStoreGoal),
8484 GetStoreGoal, % nb_getval(StoreName,Susp),
8488 update_store_type(F/A,global_singleton).
8489 existential_lookup(multi_store(StoreTypes),Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :- !,
8491 member(ST,StoreTypes),
8492 existential_lookup(ST,Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs)
8494 existential_lookup(multi_inthash(Indexes),Head,_,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :- !,
8495 existential_hash_lookup(inthash,Indexes,Head,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs).
8496 existential_lookup(multi_hash(Indexes),Head,_,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :- !,
8497 existential_hash_lookup(hash,Indexes,Head,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs).
8498 existential_lookup(identifier_store(Index),Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :- !,
8499 lookup_passive_head(identifier_store(Index),Head,PreJoin,VarDict,GroundVars,LookupGoal,AllSusps),
8500 hash_index_filter(Pairs,Index,NPairs),
8503 ( check_fd_lookup_condition(F,A,Head,KeyArgs) ->
8504 Sbag = (AllSusps = [Susp])
8506 sbag_member_call(Susp,AllSusps,Sbag)
8508 delay_phase_end(validate_store_type_assumptions,
8509 ( static_suspension_term(F/A,SuspTerm),
8510 get_static_suspension_field(F/A,SuspTerm,state,active,GetState)
8516 Susp = SuspTerm, % not inlined
8519 existential_lookup(type_indexed_identifier_store(Index,IndexType),Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :- !,
8520 lookup_passive_head(type_indexed_identifier_store(Index,IndexType),Head,PreJoin,VarDict,GroundVars,LookupGoal,AllSusps),
8521 hash_index_filter(Pairs,Index,NPairs),
8524 ( check_fd_lookup_condition(F,A,Head,KeyArgs) ->
8525 Sbag = (AllSusps = [Susp])
8527 sbag_member_call(Susp,AllSusps,Sbag)
8529 delay_phase_end(validate_store_type_assumptions,
8530 ( static_suspension_term(F/A,SuspTerm),
8531 get_static_suspension_field(F/A,SuspTerm,state,active,GetState)
8537 Susp = SuspTerm, % not inlined
8540 existential_lookup(StoreType,Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,Pairs) :-
8541 lookup_passive_head(StoreType,Head,PreJoin,VarDict,GroundVars,UGoal,Susps),
8542 sbag_member_call(Susp,Susps,Sbag),
8544 delay_phase_end(validate_store_type_assumptions,
8545 ( static_suspension_term(F/A,SuspTerm),
8546 get_static_suspension_field(F/A,SuspTerm,state,active,GetState)
8552 Susp = SuspTerm, % not inlined
8556 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8557 %% existential_hash_lookup(+StoreType,+Indexes,+Head,+RenamingVarDict,
8558 %% +GroundVariables,-SuspensionTerm,-Goal,-SuspVar,
8559 %% +VarArgDict,-NewVarArgDict) is det.
8561 % Create existential hash lookup goal for given head.
8562 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8563 existential_hash_lookup(HashType,Indexes,Head,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :-
8564 hash_lookup_passive_head(HashType,Indexes,Head,VarDict,GroundVars,LookupGoal,AllSusps,Index),
8566 hash_index_filter(Pairs,Index,NPairs),
8569 ( check_fd_lookup_condition(F,A,Head,KeyArgs) ->
8570 Sbag = (AllSusps = [Susp])
8572 sbag_member_call(Susp,AllSusps,Sbag)
8574 delay_phase_end(validate_store_type_assumptions,
8575 ( static_suspension_term(F/A,SuspTerm),
8576 get_static_suspension_field(F/A,SuspTerm,state,active,GetState)
8582 Susp = SuspTerm, % not inlined
8586 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8587 %% hash_index_filter(+Pairs,+Index,-NPairs) is det.
8589 % Filter out pairs already covered by given hash index.
8590 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8591 hash_index_filter(Pairs,Index,NPairs) :-
8597 hash_index_filter(Pairs,NIndex,1,NPairs).
8599 hash_index_filter([],_,_,[]).
8600 hash_index_filter([P|Ps],Index,N,NPairs) :-
8605 hash_index_filter(Ps,[I|Is],NN,NPs)
8607 hash_index_filter(Ps,Is,NN,NPairs)
8613 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8614 %------------------------------------------------------------------------------%
8615 %% assume_constraint_stores(+ConstraintSymbols) is det.
8617 % Compute all constraint store types that are possible for the given
8618 % =ConstraintSymbols=.
8619 %------------------------------------------------------------------------------%
8620 assume_constraint_stores([]).
8621 assume_constraint_stores([C|Cs]) :-
8622 ( chr_pp_flag(debugable,off),
8623 ( only_ground_indexed_arguments(C) ; chr_pp_flag(mixed_stores,on) ),
8625 get_store_type(C,default) ->
8626 get_indexed_arguments(C,AllIndexedArgs),
8627 get_constraint_mode(C,Modes),
8628 aggregate_all(bag(Index)-count,
8629 (member(Index,AllIndexedArgs),nth1(Index,Modes,+)),
8630 IndexedArgs-NbIndexedArgs),
8631 % Construct Index Combinations
8632 ( NbIndexedArgs > 10 ->
8633 findall([Index],member(Index,IndexedArgs),Indexes)
8635 findall(Index,(sublist(Index,IndexedArgs), Index \== []),UnsortedIndexes),
8636 predsort(longer_list,UnsortedIndexes,Indexes)
8638 % EXPERIMENTAL HEURISTIC
8640 % member(Arg1,IndexedArgs),
8641 % member(Arg2,IndexedArgs),
8643 % sort([Arg1,Arg2], Index)
8644 % ), UnsortedIndexes),
8645 % predsort(longer_list,UnsortedIndexes,Indexes),
8647 ( get_functional_dependency(C,1,Pattern,Key),
8648 all_distinct_var_args(Pattern), Key == [] ->
8649 assumed_store_type(C,global_singleton)
8650 ; ( only_ground_indexed_arguments(C) ; NbIndexedArgs > 0 ) ->
8651 get_constraint_type_det(C,ArgTypes),
8652 partition_indexes(Indexes,ArgTypes,HashIndexes,IntHashIndexes,IdentifierIndexes,CompoundIdentifierIndexes),
8654 ( IntHashIndexes = [] ->
8657 Stores = [multi_inthash(IntHashIndexes)|Stores1]
8659 ( HashIndexes = [] ->
8662 Stores1 = [multi_hash(HashIndexes)|Stores2]
8664 ( IdentifierIndexes = [] ->
8667 maplist(wrap_in_functor(identifier_store),IdentifierIndexes,WrappedIdentifierIndexes),
8668 append(WrappedIdentifierIndexes,Stores3,Stores2)
8670 append(CompoundIdentifierIndexes,Stores4,Stores3),
8671 ( only_ground_indexed_arguments(C)
8672 -> Stores4 = [global_ground]
8673 ; Stores4 = [default]
8675 assumed_store_type(C,multi_store(Stores))
8681 assume_constraint_stores(Cs).
8683 %------------------------------------------------------------------------------%
8684 %% partition_indexes(+Indexes,+Types,
8685 %% -HashIndexes,-IntHashIndexes,-IdentifierIndexes) is det.
8686 %------------------------------------------------------------------------------%
8687 partition_indexes([],_,[],[],[],[]).
8688 partition_indexes([Index|Indexes],Types,HashIndexes,IntHashIndexes,IdentifierIndexes,CompoundIdentifierIndexes) :-
8691 unalias_type(Type,UnAliasedType),
8692 UnAliasedType == chr_identifier ->
8693 IdentifierIndexes = [I|RIdentifierIndexes],
8694 IntHashIndexes = RIntHashIndexes,
8695 HashIndexes = RHashIndexes,
8696 CompoundIdentifierIndexes = RCompoundIdentifierIndexes
8699 unalias_type(Type,UnAliasedType),
8700 nonvar(UnAliasedType),
8701 UnAliasedType = chr_identifier(IndexType) ->
8702 CompoundIdentifierIndexes = [type_indexed_identifier_store(I,IndexType)|RCompoundIdentifierIndexes],
8703 IdentifierIndexes = RIdentifierIndexes,
8704 IntHashIndexes = RIntHashIndexes,
8705 HashIndexes = RHashIndexes
8708 unalias_type(Type,UnAliasedType),
8709 UnAliasedType == dense_int ->
8710 IntHashIndexes = [Index|RIntHashIndexes],
8711 HashIndexes = RHashIndexes,
8712 IdentifierIndexes = RIdentifierIndexes,
8713 CompoundIdentifierIndexes = RCompoundIdentifierIndexes
8716 unalias_type(Type,UnAliasedType),
8717 nonvar(UnAliasedType),
8718 UnAliasedType = chr_identifier(_) ->
8719 % don't use chr_identifiers in hash indexes
8720 IntHashIndexes = RIntHashIndexes,
8721 HashIndexes = RHashIndexes,
8722 IdentifierIndexes = RIdentifierIndexes,
8723 CompoundIdentifierIndexes = RCompoundIdentifierIndexes
8725 IntHashIndexes = RIntHashIndexes,
8726 HashIndexes = [Index|RHashIndexes],
8727 IdentifierIndexes = RIdentifierIndexes,
8728 CompoundIdentifierIndexes = RCompoundIdentifierIndexes
8730 partition_indexes(Indexes,Types,RHashIndexes,RIntHashIndexes,RIdentifierIndexes,RCompoundIdentifierIndexes).
8732 longer_list(R,L1,L2) :-
8742 all_distinct_var_args(Term) :-
8743 copy_term_nat(Term,TermCopy),
8745 functor(Pattern,F,A),
8748 get_indexed_arguments(C,IndexedArgs) :-
8750 get_indexed_arguments(1,A,C,IndexedArgs).
8752 get_indexed_arguments(I,N,C,L) :-
8755 ; ( is_indexed_argument(C,I) ->
8761 get_indexed_arguments(J,N,C,T)
8764 validate_store_type_assumptions([]).
8765 validate_store_type_assumptions([C|Cs]) :-
8766 validate_store_type_assumption(C),
8767 validate_store_type_assumptions(Cs).
8769 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8770 % new code generation
8771 universal_search_iterator_end([CurrentHead|PrevHeads],NextHeads,Rule,F/A,O,Id,L,T) :-
8772 Rule = rule(H1,_,Guard,Body),
8773 gen_var_susp_list_for_b(PrevHeads,[CurrentHead,NextHeads,Guard,Body],_,VarsAndSuspsList,FirstVarsSusp,_,PrevIterators),
8774 universal_search_iterator_failure_vars(PrevHeads,Id,VarsAndSuspsList,FirstVarsSusp,PrevIterators,PrevVarsAndSusps,PrevId0),
8775 flatten(VarsAndSuspsList,VarsAndSusps),
8776 Vars = [ [] | VarsAndSusps],
8777 build_head(F,A,[O|Id],Vars,Head),
8779 get_success_continuation_code_id(F/A,O,PredictedPrevId),
8780 % format('~w == ~w ?\n',[PrevId0,PredictedPrevId]),
8781 PrevId = [PredictedPrevId] % PrevId = PrevId0
8783 PrevId = [O|PrevId0]
8785 build_head(F,A,PrevId,PrevVarsAndSusps,PredecessorCall),
8786 Clause = ( Head :- PredecessorCall),
8787 add_dummy_location(Clause,LocatedClause),
8788 L = [LocatedClause | T].
8790 % functor(CurrentHead,CF,CA),
8791 % check_fd_lookup_condition(CF,CA,CurrentHead,PrevHeads) ->
8794 % gen_var_susp_list_for_b(PrevHeads,[CurrentHead,NextHeads,Guard,Body],_,VarsAndSuspsList,FirstVarsSusp,_,PrevIterators),
8795 % universal_search_iterator_failure_vars(PrevHeads,Id,VarsAndSuspsList,FirstVarsSusp,PrevIterators,PrevVarsAndSusps,PrevId),
8796 % flatten(VarsAndSuspsList,VarsAndSusps),
8797 % Vars = [ [] | VarsAndSusps],
8798 % build_head(F,A,Id,Vars,Head),
8799 % build_head(F,A,PrevId,PrevVarsAndSusps,PredecessorCall),
8800 % Clause = ( Head :- PredecessorCall),
8804 % skips back intelligently over global_singleton lookups
8805 universal_search_iterator_failure_vars(PrevHeads,Id,VarsAndSuspsList,BaseCallArgs,PrevIterators,PrevVarsAndSusps,PrevId) :-
8807 % TOM: add partial success continuation optimization here!
8809 PrevVarsAndSusps = BaseCallArgs
8811 VarsAndSuspsList = [_|AllButFirstList],
8813 ( PrevHeads = [PrevHead|PrevHeads1],
8814 functor(PrevHead,F,A),
8815 check_fd_lookup_condition(F,A,PrevHead,PrevHeads1) ->
8816 PrevIterators = [_|PrevIterators1],
8817 universal_search_iterator_failure_vars(PrevHeads1,PrevId1,AllButFirstList,BaseCallArgs,PrevIterators1,PrevVarsAndSusps,PrevId)
8820 flatten(AllButFirstList,AllButFirst),
8821 PrevIterators = [PrevIterator|_],
8822 PrevVarsAndSusps = [PrevIterator|AllButFirst]
8826 universal_search_iterator([NextHead|RestHeads],[CurrentHead|PreHeads],Rule,F/A,O,Id,L,T) :-
8827 Rule = rule(_,_,Guard,Body),
8828 gen_var_susp_list_for_b(PreHeads,[CurrentHead,NextHead,RestHeads,Guard,Body],VarDict,PreVarsAndSuspsList,FirstVarsSusp,AllSusps,PrevIterators),
8829 init(AllSusps,PreSusps),
8830 flatten(PreVarsAndSuspsList,PreVarsAndSusps),
8831 gen_var(OtherSusps),
8832 functor(CurrentHead,OtherF,OtherA),
8833 gen_vars(OtherA,OtherVars),
8834 head_info(CurrentHead,OtherA,OtherVars,OtherSusp,_VarsSusp,HeadPairs),
8835 get_constraint_mode(OtherF/OtherA,Mode),
8836 head_arg_matches(HeadPairs,Mode,VarDict,FirstMatching,VarDict1),
8838 delay_phase_end(validate_store_type_assumptions,
8839 ( static_suspension_term(OtherF/OtherA,OtherSuspension),
8840 get_static_suspension_field(OtherF/OtherA,OtherSuspension,state,active,GetState),
8841 get_static_suspension_term_field(arguments,OtherF/OtherA,OtherSuspension,OtherVars)
8845 different_from_other_susps(CurrentHead,OtherSusp,PreHeads,PreSusps,DiffSuspGoals),
8846 % create_get_mutable_ref(active,State,GetMutable),
8848 OtherSusp = OtherSuspension,
8853 add_heads_ground_variables([CurrentHead|PreHeads],[],GroundVars),
8854 lookup_passive_head(NextHead,[CurrentHead|PreHeads],VarDict1,GroundVars,NextSuspGoal,NextSusps),
8855 inc_id(Id,NestedId),
8856 ClauseVars = [[OtherSusp|OtherSusps]|PreVarsAndSusps],
8857 build_head(F,A,[O|Id],ClauseVars,ClauseHead),
8858 passive_delegate_variables(CurrentHead,PreHeads,[NextHead,RestHeads,Guard,Body],VarDict1,CurrentHeadVars),
8859 append([NextSusps|CurrentHeadVars],[OtherSusp,OtherSusps|PreVarsAndSusps],NestedVars),
8860 build_head(F,A,[O|NestedId],NestedVars,NestedHead),
8862 ( check_fd_lookup_condition(OtherF,OtherA,CurrentHead,PreHeads) -> % iterator (OtherSusps) is empty at runtime
8863 universal_search_iterator_failure_vars(PreHeads,Id,PreVarsAndSuspsList,FirstVarsSusp,PrevIterators,PreVarsAndSusps1,PrevId0),
8864 RecursiveVars = PreVarsAndSusps1
8866 RecursiveVars = [OtherSusps|PreVarsAndSusps],
8872 PrevId = [O|PrevId0]
8874 build_head(F,A,PrevId,RecursiveVars,RecursiveHead),
8885 add_dummy_location(Clause,LocatedClause),
8886 L = [LocatedClause|T].
8888 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8890 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8891 % Observation Analysis
8896 % Analysis based on Abstract Interpretation paper.
8899 % stronger analysis domain [research]
8902 initial_call_pattern/1,
8904 call_pattern_worker/1,
8905 final_answer_pattern/2,
8906 abstract_constraints/1,
8910 ai_observed_internal/2,
8912 ai_not_observed_internal/2,
8916 ai_observation_gather_results/0.
8918 :- chr_type abstract_domain ---> odom(program_point,list(constraint)).
8919 :- chr_type program_point == any.
8921 :- chr_option(mode,initial_call_pattern(+)).
8922 :- chr_option(type_declaration,call_pattern(abstract_domain)).
8924 :- chr_option(mode,call_pattern(+)).
8925 :- chr_option(type_declaration,call_pattern(abstract_domain)).
8927 :- chr_option(mode,call_pattern_worker(+)).
8928 :- chr_option(type_declaration,call_pattern_worker(abstract_domain)).
8930 :- chr_option(mode,final_answer_pattern(+,+)).
8931 :- chr_option(type_declaration,final_answer_pattern(abstract_domain,abstract_domain)).
8933 :- chr_option(mode,abstract_constraints(+)).
8934 :- chr_option(type_declaration,abstract_constraints(list)).
8936 :- chr_option(mode,depends_on(+,+)).
8937 :- chr_option(type_declaration,depends_on(abstract_domain,abstract_domain)).
8939 :- chr_option(mode,depends_on_as(+,+,+)).
8940 :- chr_option(mode,depends_on_ap(+,+,+,+)).
8941 :- chr_option(mode,depends_on_goal(+,+)).
8942 :- chr_option(mode,ai_is_observed(+,+)).
8943 :- chr_option(mode,ai_not_observed(+,+)).
8944 % :- chr_option(mode,ai_observed(+,+)).
8945 :- chr_option(mode,ai_not_observed_internal(+,+)).
8946 :- chr_option(mode,ai_observed_internal(+,+)).
8949 abstract_constraints_fd @
8950 abstract_constraints(_) \ abstract_constraints(_) <=> true.
8952 ai_observed_internal(C,O) \ ai_not_observed_internal(C,O) <=> true.
8953 ai_not_observed_internal(C,O) \ ai_not_observed_internal(C,O) <=> true.
8954 ai_observed_internal(C,O) \ ai_observed_internal(C,O) <=> true.
8956 ai_not_observed(C,O) \ ai_is_observed(C,O) <=> fail.
8957 ai_is_observed(_,_) <=> true.
8959 ai_observation_gather_results \ ai_observed_internal(C,O) <=> true. % ai_observed(C,O).
8960 ai_observation_gather_results \ ai_not_observed_internal(C,O) <=> ai_not_observed(C,O).
8961 ai_observation_gather_results <=> true.
8963 %------------------------------------------------------------------------------%
8964 % Main Analysis Entry
8965 %------------------------------------------------------------------------------%
8966 ai_observation_analysis(ACs) :-
8967 ( chr_pp_flag(ai_observation_analysis,on),
8968 get_target_module(Module), '$chr_compiled_with_version'(3) -> % , Module \== guard_entailment ->
8969 list_to_ord_set(ACs,ACSet),
8970 abstract_constraints(ACSet),
8971 ai_observation_schedule_initial_calls(ACSet,ACSet),
8972 ai_observation_gather_results
8977 ai_observation_schedule_initial_calls([],_).
8978 ai_observation_schedule_initial_calls([AC|RACs],ACs) :-
8979 ai_observation_schedule_initial_call(AC,ACs),
8980 ai_observation_schedule_initial_calls(RACs,ACs).
8982 ai_observation_schedule_initial_call(AC,ACs) :-
8983 ai_observation_top(AC,CallPattern),
8984 % ai_observation_bot(AC,ACs,CallPattern),
8985 initial_call_pattern(CallPattern).
8987 ai_observation_schedule_new_calls([],AP).
8988 ai_observation_schedule_new_calls([AC|ACs],AP) :-
8990 initial_call_pattern(odom(AC,Set)),
8991 ai_observation_schedule_new_calls(ACs,AP).
8993 final_answer_pattern(CP,AP1) \ final_answer_pattern(CP,AP2)
8995 ai_observation_leq(AP2,AP1)
8999 initial_call_pattern(CP) \ initial_call_pattern(CP) <=> true.
9001 initial_call_pattern(CP) ==> call_pattern(CP).
9003 initial_call_pattern(CP), final_answer_pattern(CP,AP), abstract_constraints(ACs) # ID3
9005 ai_observation_schedule_new_calls(ACs,AP)
9009 call_pattern(CP) \ call_pattern(CP) <=> true.
9011 depends_on(CP1,CP2), final_answer_pattern(CP2,AP) ==>
9012 final_answer_pattern(CP1,AP).
9014 %call_pattern(CP) ==> writeln(call_pattern(CP)).
9016 call_pattern(CP) ==> call_pattern_worker(CP).
9018 %------------------------------------------------------------------------------%
9020 %------------------------------------------------------------------------------%
9023 %call_pattern(odom([],Set)) ==>
9024 % final_answer_pattern(odom([],Set),odom([],Set)).
9026 call_pattern_worker(odom([],Set)) <=>
9027 % writeln(' - AbstractGoal'(odom([],Set))),
9028 final_answer_pattern(odom([],Set),odom([],Set)).
9031 call_pattern_worker(odom([G|Gs],Set)) <=>
9032 % writeln(' - AbstractGoal'(odom([G|Gs],Set))),
9034 depends_on_goal(odom([G|Gs],Set),CP1),
9037 depends_on_goal(CP1,CP2), final_answer_pattern(CP2,AP2) \ depends_on(CP1,_) # ID
9038 <=> true pragma passive(ID).
9039 depends_on_goal(CP1,CP2), final_answer_pattern(CP2,AP2)
9041 CP1 = odom([_|Gs],_),
9045 depends_on(CP1,CCP).
9047 %------------------------------------------------------------------------------%
9048 % Abstract Disjunction
9049 %------------------------------------------------------------------------------%
9051 call_pattern_worker(odom((AG1;AG2),Set)) <=>
9052 CP = odom((AG1;AG2),Set),
9053 InitialAnswerApproximation = odom([],Set),
9054 final_answer_pattern(CP,InitialAnswerApproximation),
9055 CP1 = odom(AG1,Set),
9056 CP2 = odom(AG2,Set),
9059 depends_on_as(CP,CP1,CP2).
9061 %------------------------------------------------------------------------------%
9063 %------------------------------------------------------------------------------%
9064 call_pattern_worker(odom(builtin,Set)) <=>
9065 % writeln(' - AbstractSolve'(odom(builtin,Set))),
9066 ord_empty(EmptySet),
9067 final_answer_pattern(odom(builtin,Set),odom([],EmptySet)).
9069 %------------------------------------------------------------------------------%
9071 %------------------------------------------------------------------------------%
9072 max_occurrence(C,MO) # ID2 \ call_pattern_worker(odom(occ(C,O),Set))
9076 % writeln(' - AbstractDrop'(odom(occ(C,O),Set))),
9077 final_answer_pattern(odom(occ(C,O),Set),odom([],Set))
9081 %------------------------------------------------------------------------------%
9083 %------------------------------------------------------------------------------%
9084 call_pattern_worker(odom(AC,Set))
9088 % writeln(' - AbstractActivate'(odom(AC,Set))),
9089 CP = odom(occ(AC,1),Set),
9091 depends_on(odom(AC,Set),CP).
9093 %------------------------------------------------------------------------------%
9095 %------------------------------------------------------------------------------%
9096 occurrence(C,O,RuleNb,ID,_) # ID2 \ call_pattern_worker(odom(occ(C,O),Set))
9098 is_passive(RuleNb,ID)
9100 % writeln(' - AbstractPassive'(odom(occ(C,O),Set))),
9103 DCP = odom(occ(C,NO),Set),
9105 final_answer_pattern(odom(occ(C,O),Set),odom([],Set)),
9106 depends_on(odom(occ(C,O),Set),DCP)
9109 %------------------------------------------------------------------------------%
9111 %------------------------------------------------------------------------------%
9114 occurrence(C,O,RuleNb,ID,simplification) # ID2 \ call_pattern_worker(odom(occ(C,O),Set))
9116 \+ is_passive(RuleNb,ID)
9118 % writeln(' - AbstractPassive'(odom(occ(C,O),Set))),
9119 ai_observation_memo_simplification_rest_heads(C,O,AbstractRestHeads),
9120 ai_observation_observe_set(Set,AbstractRestHeads,Set2),
9121 ai_observation_memo_abstract_goal(RuleNb,AG),
9122 call_pattern(odom(AG,Set2)),
9125 DCP = odom(occ(C,NO),Set),
9127 depends_on_as(odom(occ(C,O),Set),odom(AG,Set2),DCP),
9128 % DEADLOCK AVOIDANCE
9129 final_answer_pattern(odom(occ(C,O),Set),odom([],Set))
9133 depends_on_as(CP,CPS,CPD),
9134 final_answer_pattern(CPS,APS),
9135 final_answer_pattern(CPD,APD) ==>
9136 ai_observation_lub(APS,APD,AP),
9137 final_answer_pattern(CP,AP).
9141 ai_observation_memo_simplification_rest_heads/3,
9142 ai_observation_memoed_simplification_rest_heads/3.
9144 :- chr_option(mode,ai_observation_memo_simplification_rest_heads(+,+,?)).
9145 :- chr_option(mode,ai_observation_memoed_simplification_rest_heads(+,+,+)).
9147 ai_observation_memoed_simplification_rest_heads(C,O,RH) \ ai_observation_memo_simplification_rest_heads(C,O,QRH)
9150 abstract_constraints(ACs) # ID1, occurrence(C,O,RuleNb,ID,_) # ID2, rule(RuleNb,Rule) # ID3 \ ai_observation_memo_simplification_rest_heads(C,O,QRH)
9152 Rule = pragma(rule(H1,H2,_,_),ids(IDs1,_),_,_,_),
9153 once(select2(ID,_,IDs1,H1,_,RestH1)),
9154 ai_observation_abstract_constraints(RestH1,ACs,ARestHeads),
9155 ai_observation_abstract_constraints(H2,ACs,AH2),
9156 append(ARestHeads,AH2,AbstractHeads),
9157 sort(AbstractHeads,QRH),
9158 ai_observation_memoed_simplification_rest_heads(C,O,QRH)
9164 ai_observation_memo_simplification_rest_heads(_,_,_) <=> fail.
9166 %------------------------------------------------------------------------------%
9167 % Abstract Propagate
9168 %------------------------------------------------------------------------------%
9172 occurrence(C,O,RuleNb,ID,propagation) # ID2 \ call_pattern_worker(odom(occ(C,O),Set))
9174 \+ is_passive(RuleNb,ID)
9176 % writeln(' - AbstractPropagate'(odom(occ(C,O),Set))),
9178 ai_observation_memo_propagation_rest_heads(C,O,AHs),
9179 ai_observation_observe_set(Set,AHs,Set2),
9180 ord_add_element(Set2,C,Set3),
9181 ai_observation_memo_abstract_goal(RuleNb,AG),
9182 call_pattern(odom(AG,Set3)),
9183 ( ord_memberchk(C,Set2) ->
9190 DCP = odom(occ(C,NO),Set),
9192 depends_on_ap(odom(occ(C,O),Set),odom(AG,Set3),DCP,Delete)
9197 ai_observation_memo_propagation_rest_heads/3,
9198 ai_observation_memoed_propagation_rest_heads/3.
9200 :- chr_option(mode,ai_observation_memo_propagation_rest_heads(+,+,?)).
9201 :- chr_option(mode,ai_observation_memoed_propagation_rest_heads(+,+,+)).
9203 ai_observation_memoed_propagation_rest_heads(C,O,RH) \ ai_observation_memo_propagation_rest_heads(C,O,QRH)
9206 abstract_constraints(ACs) # ID1, occurrence(C,O,RuleNb,ID,_) # ID2, rule(RuleNb,Rule) # ID3 \ ai_observation_memo_propagation_rest_heads(C,O,QRH)
9208 Rule = pragma(rule(H1,H2,_,_),ids(_,IDs2),_,_,_),
9209 once(select2(ID,_,IDs2,H2,_,RestH2)),
9210 ai_observation_abstract_constraints(RestH2,ACs,ARestHeads),
9211 ai_observation_abstract_constraints(H1,ACs,AH1),
9212 append(ARestHeads,AH1,AbstractHeads),
9213 sort(AbstractHeads,QRH),
9214 ai_observation_memoed_propagation_rest_heads(C,O,QRH)
9220 ai_observation_memo_propagation_rest_heads(_,_,_) <=> fail.
9222 depends_on_ap(CP,CPP,CPD,Delete), final_answer_pattern(CPD,APD) ==>
9223 final_answer_pattern(CP,APD).
9224 depends_on_ap(CP,CPP,CPD,Delete), final_answer_pattern(CPP,APP),
9225 final_answer_pattern(CPD,APD) ==>
9227 CP = odom(occ(C,O),_),
9228 ( ai_observation_is_observed(APP,C) ->
9229 ai_observed_internal(C,O)
9231 ai_not_observed_internal(C,O)
9234 APP = odom([],Set0),
9235 ord_del_element(Set0,C,Set),
9240 ai_observation_lub(NAPP,APD,AP),
9241 final_answer_pattern(CP,AP).
9243 %------------------------------------------------------------------------------%
9245 %------------------------------------------------------------------------------%
9247 call_pattern_worker(CP) <=> chr_error(internal,'AI observation analysis: unexpected abstract state ~w\n',[CP]).
9249 %------------------------------------------------------------------------------%
9250 % Auxiliary Predicates
9251 %------------------------------------------------------------------------------%
9253 ai_observation_lub(odom(AG,S1),odom(AG,S2),odom(AG,S3)) :-
9254 ord_intersection(S1,S2,S3).
9256 ai_observation_bot(AG,AS,odom(AG,AS)).
9258 ai_observation_top(AG,odom(AG,EmptyS)) :-
9261 ai_observation_leq(odom(AG,S1),odom(AG,S2)) :-
9264 ai_observation_observe_set(S,ACSet,NS) :-
9265 ord_subtract(S,ACSet,NS).
9267 ai_observation_abstract_constraint(C,ACs,AC) :-
9272 ai_observation_abstract_constraints(Cs,ACs,NACs) :-
9273 findall(NAC,(member(C,Cs),ai_observation_abstract_constraint(C,ACs,NAC)),NACs).
9275 %------------------------------------------------------------------------------%
9276 % Abstraction of Rule Bodies
9277 %------------------------------------------------------------------------------%
9280 ai_observation_memoed_abstract_goal/2,
9281 ai_observation_memo_abstract_goal/2.
9283 :- chr_option(mode,ai_observation_memoed_abstract_goal(+,+)).
9284 :- chr_option(mode,ai_observation_memo_abstract_goal(+,?)).
9286 ai_observation_memoed_abstract_goal(RuleNb,AG) # ID1 \ ai_observation_memo_abstract_goal(RuleNb,QAG)
9292 rule(RuleNb,Rule) # ID1, abstract_constraints(ACs) # ID2 \ ai_observation_memo_abstract_goal(RuleNb,QAG)
9294 Rule = pragma(rule(H1,H2,Guard,Body),_,_,_,_),
9295 ai_observation_abstract_goal_(H1,H2,Guard,Body,ACs,AG),
9297 ai_observation_memoed_abstract_goal(RuleNb,AG)
9302 ai_observation_abstract_goal_(H1,H2,Guard,G,ACs,AG) :-
9303 % also guard: e.g. b, c(X) ==> Y=X | p(Y).
9304 term_variables((H1,H2,Guard),HVars),
9305 append(H1,H2,Heads),
9306 % variables that are declared to be ground are safe,
9307 ground_vars(Heads,GroundVars),
9308 % so we remove them from the list of 'dangerous' head variables
9309 list_difference_eq(HVars,GroundVars,HV),
9310 ai_observation_abstract_goal(G,ACs,AG,[],HV),!.
9311 % writeln(ai_observation_abstract_goal(G,ACs,AG,[],HV)).
9312 % HV are 'dangerous' variables, all others are fresh and safe
9315 ground_vars([H|Hs],GroundVars) :-
9317 get_constraint_mode(F/A,Mode),
9318 % TOM: fix this code!
9319 head_info(H,A,_Vars,_Susp,_HeadVars,HeadPairs),
9320 head_arg_matches(HeadPairs,Mode,[],_FirstMatching,_VarDict1,[],GroundVars1),
9321 ground_vars(Hs,GroundVars2),
9322 append(GroundVars1,GroundVars2,GroundVars).
9324 ai_observation_abstract_goal((G1,G2),ACs,List,Tail,HV) :- !, % conjunction
9325 ai_observation_abstract_goal(G1,ACs,List,IntermediateList,HV),
9326 ai_observation_abstract_goal(G2,ACs,IntermediateList,Tail,HV).
9327 ai_observation_abstract_goal((G1;G2),ACs,[(ABranch1;ABranch2)|Tail],Tail,HV) :- !, % disjunction
9328 ai_observation_abstract_goal(G1,ACs,ABranch1,[],HV),
9329 ai_observation_abstract_goal(G2,ACs,ABranch2,[],HV).
9330 ai_observation_abstract_goal((G1->G2),ACs,List,Tail,HV) :- !, % if-then
9331 ai_observation_abstract_goal(G1,ACs,List,IntermediateList,HV),
9332 ai_observation_abstract_goal(G2,ACs,IntermediateList,Tail,HV).
9333 ai_observation_abstract_goal(C,ACs,[AC|Tail],Tail,HV) :-
9334 ai_observation_abstract_constraint(C,ACs,AC), !. % CHR constraint
9335 ai_observation_abstract_goal(true,_,Tail,Tail,_) :- !.
9336 ai_observation_abstract_goal(writeln(_),_,Tail,Tail,_) :- !.
9337 % non-CHR constraint is safe if it only binds fresh variables
9338 ai_observation_abstract_goal(G,_,Tail,Tail,HV) :-
9339 builtin_binds_b(G,Vars),
9340 intersect_eq(Vars,HV,[]),
9342 ai_observation_abstract_goal(G,_,[AG|Tail],Tail,_) :-
9343 AG = builtin. % default case if goal is not recognized/safe
9345 ai_observation_is_observed(odom(_,ACSet),AC) :-
9346 \+ ord_memberchk(AC,ACSet).
9348 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9349 unconditional_occurrence(C,O) :-
9350 get_occurrence(C,O,RuleNb,ID),
9351 get_rule(RuleNb,PRule),
9352 PRule = pragma(ORule,_,_,_,_),
9353 copy_term_nat(ORule,Rule),
9354 Rule = rule(H1,H2,Guard,_),
9355 % writeq(guard_entailment:entails_guard([chr_pp_headvariables(H1,H2)],Guard)),nl,
9356 guard_entailment:entails_guard([chr_pp_headvariables(H1,H2)],Guard),
9358 H1 = [Head], H2 == []
9360 H2 = [Head], H1 == [], \+ may_trigger(C)
9364 unconditional_occurrence_args(Args).
9366 unconditional_occurrence_args([]).
9367 unconditional_occurrence_args([X|Xs]) :-
9370 unconditional_occurrence_args(Xs).
9372 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9374 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9375 % Partial wake analysis
9377 % In a Var = Var unification do not wake up constraints of both variables,
9378 % but rather only those of one variable.
9379 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9381 :- chr_constraint partial_wake_analysis/0.
9382 :- chr_constraint no_partial_wake/1.
9383 :- chr_option(mode,no_partial_wake(+)).
9384 :- chr_constraint wakes_partially/1.
9385 :- chr_option(mode,wakes_partially(+)).
9387 partial_wake_analysis, occurrence(FA,O,RuleNb,ID,Type), rule(RuleNb,Rule), constraint_mode(FA,ArgModes)
9389 Rule = pragma(rule(H1,H2,Guard,Body),_,_,_,_),
9390 ( is_passive(RuleNb,ID) ->
9392 ; Type == simplification ->
9393 select(H,H1,RestH1),
9395 term_variables(Guard,Vars),
9396 partial_wake_args(Args,ArgModes,Vars,FA)
9397 ; % Type == propagation ->
9398 select(H,H2,RestH2),
9400 term_variables(Guard,Vars),
9401 partial_wake_args(Args,ArgModes,Vars,FA)
9404 partial_wake_args([],_,_,_).
9405 partial_wake_args([Arg|Args],[Mode|Modes],Vars,C) :-
9409 ; memberchk_eq(Arg,Vars) ->
9417 partial_wake_args(Args,Modes,Vars,C).
9419 no_partial_wake(C) \ no_partial_wake(C) <=> true.
9421 no_partial_wake(C) \ wakes_partially(C) <=> fail.
9423 wakes_partially(C) <=> true.
9426 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9427 % Generate rules that implement chr_show_store/1 functionality.
9433 % Generates additional rules:
9435 % $show, C1 # ID ==> writeln(C1) pragma passive(ID).
9437 % $show, Cn # ID ==> writeln(Cn) pragma passive(ID).
9440 generate_show_constraint(Constraints0,Constraints,Rules0,Rules) :-
9441 ( chr_pp_flag(show,on) ->
9442 Constraints = ['$show'/0|Constraints0],
9443 generate_show_rules(Constraints0,Rules,[Rule|Rules0]),
9444 inc_rule_count(RuleNb),
9446 rule(['$show'],[],true,true),
9453 Constraints = Constraints0,
9457 generate_show_rules([],Rules,Rules).
9458 generate_show_rules([F/A|Rest],[Rule|Tail],Rules) :-
9460 inc_rule_count(RuleNb),
9462 rule([],['$show',C],true,writeln(C)),
9468 generate_show_rules(Rest,Tail,Rules).
9470 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9471 % Custom supension term layout
9473 static_suspension_term(F/A,Suspension) :-
9474 suspension_term_base(F/A,Base),
9476 functor(Suspension,suspension,Arity).
9478 has_suspension_field(FA,Field) :-
9479 suspension_term_base_fields(FA,Fields),
9480 memberchk(Field,Fields).
9482 suspension_term_base(FA,Base) :-
9483 suspension_term_base_fields(FA,Fields),
9484 length(Fields,Base).
9486 suspension_term_base_fields(FA,Fields) :-
9487 ( chr_pp_flag(debugable,on) ->
9490 % 3. Propagation History
9491 % 4. Generation Number
9492 % 5. Continuation Goal
9494 Fields = [id,state,history,generation,continuation,functor]
9496 ( uses_history(FA) ->
9497 Fields = [id,state,history|Fields2]
9498 ; only_ground_indexed_arguments(FA), get_functional_dependency(FA,1,_,_) ->
9499 Fields = [state|Fields2]
9501 Fields = [id,state|Fields2]
9503 ( only_ground_indexed_arguments(FA) ->
9504 get_store_type(FA,StoreType),
9505 basic_store_types(StoreType,BasicStoreTypes),
9506 ( memberchk(global_ground,BasicStoreTypes) ->
9509 % 3. Propagation History
9510 % 4. Global List Prev
9511 Fields2 = [global_list_prev|Fields3]
9515 % 3. Propagation History
9518 ( chr_pp_flag(ht_removal,on)
9519 -> ht_prev_fields(BasicStoreTypes,Fields3)
9522 ; may_trigger(FA) ->
9525 % 3. Propagation History
9526 ( uses_field(FA,generation) ->
9527 % 4. Generation Number
9528 % 5. Global List Prev
9529 Fields2 = [generation,global_list_prev|Fields3]
9531 Fields2 = [global_list_prev|Fields3]
9533 ( chr_pp_flag(mixed_stores,on),
9534 chr_pp_flag(ht_removal,on)
9535 -> get_store_type(FA,StoreType),
9536 basic_store_types(StoreType,BasicStoreTypes),
9537 ht_prev_fields(BasicStoreTypes,Fields3)
9543 % 3. Propagation History
9544 % 4. Global List Prev
9545 Fields2 = [global_list_prev|Fields3],
9546 ( chr_pp_flag(mixed_stores,on),
9547 chr_pp_flag(ht_removal,on)
9548 -> get_store_type(FA,StoreType),
9549 basic_store_types(StoreType,BasicStoreTypes),
9550 ht_prev_fields(BasicStoreTypes,Fields3)
9556 ht_prev_fields(Stores,Prevs) :-
9557 ht_prev_fields_int(Stores,PrevsList),
9558 append(PrevsList,Prevs).
9559 ht_prev_fields_int([],[]).
9560 ht_prev_fields_int([H|T],Fields) :-
9561 ( H = multi_hash(Indexes)
9562 -> maplist(ht_prev_field,Indexes,FH),
9566 ht_prev_fields_int(T,FT).
9568 ht_prev_field(Index,Field) :-
9570 -> atom_concat('multi_hash_prev-',Index,Field)
9572 -> concat_atom(['multi_hash_prev-'|Index],Field)
9575 get_static_suspension_term_field(FieldName,FA,StaticSuspension,Field) :-
9576 suspension_term_base_fields(FA,Fields),
9577 nth1(Index,Fields,FieldName), !,
9578 arg(Index,StaticSuspension,Field).
9579 get_static_suspension_term_field(arguments,FA,StaticSuspension,Field) :- !,
9580 suspension_term_base(FA,Base),
9581 StaticSuspension =.. [_|Args],
9582 drop(Base,Args,Field).
9583 get_static_suspension_term_field(FieldName,FA,_StaticSuspension,_Field) :-
9584 chr_error(internal,'Trying to obtain field ~w of ~w, wich does not have it!',[FieldName,FA]).
9587 get_dynamic_suspension_term_field(FieldName,FA,DynamicSuspension,Field,Goal) :-
9588 suspension_term_base_fields(FA,Fields),
9589 nth1(Index,Fields,FieldName), !,
9590 Goal = arg(Index,DynamicSuspension,Field).
9591 get_dynamic_suspension_term_field(arguments,FA,DynamicSuspension,Field,Goal) :- !,
9592 static_suspension_term(FA,StaticSuspension),
9593 get_static_suspension_term_field(arguments,FA,StaticSuspension,Field),
9594 Goal = (DynamicSuspension = StaticSuspension).
9595 get_dynamic_suspension_term_field(argument(I),FA,DynamicSuspension,Field,Goal) :- !,
9596 suspension_term_base(FA,Base),
9598 Goal = arg(Index,DynamicSuspension,Field).
9599 get_dynamic_suspension_term_field(FieldName,FA,_DynamicSuspension,_Field,_Goal) :-
9600 chr_error(internal,'Dynamic goal to get ~w of ~w, which does not have this field!',[FieldName,FA]).
9603 set_dynamic_suspension_term_field(FieldName,FA,DynamicSuspension,Field,Goal) :-
9604 suspension_term_base_fields(FA,Fields),
9605 nth1(Index,Fields,FieldName), !,
9606 Goal = setarg(Index,DynamicSuspension,Field).
9607 set_dynamic_suspension_term_field(FieldName,FA,_DynamicSuspension,_Field,_Goal) :-
9608 chr_error(internal,'Dynamic goal to set ~w of ~w, which does not have this field!',[FieldName,FA]).
9610 basic_store_types(multi_store(Types),Types) :- !.
9611 basic_store_types(Type,[Type]).
9613 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9620 :- chr_option(mode,phase_end(+)).
9621 :- chr_option(mode,delay_phase_end(+,?)).
9623 phase_end(Phase) \ delay_phase_end(Phase,Goal) <=> call(Goal).
9624 % phase_end(Phase) <=> true.
9627 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9631 novel_production_call/4.
9633 :- chr_option(mode,uses_history(+)).
9634 :- chr_option(mode,does_use_history(+,+)).
9635 :- chr_option(mode,novel_production_call(+,+,?,?)).
9637 does_use_history(FA,Occ) \ does_use_history(FA,Occ) <=> true.
9638 does_use_history(FA,_) \ uses_history(FA) <=> true.
9639 uses_history(_FA) <=> fail.
9641 does_use_history(FA,Occ) \ novel_production_call(FA,Occ,PossibleGoal,Goal) <=> Goal = PossibleGoal.
9642 novel_production_call(FA,_,_PossibleGoal,Goal) <=> Goal = true.
9648 :- chr_option(mode,uses_field(+,+)).
9649 :- chr_option(mode,does_use_field(+,+)).
9651 does_use_field(FA,Field) \ does_use_field(FA,Field) <=> true.
9652 does_use_field(FA,Field) \ uses_field(FA,Field) <=> true.
9653 uses_field(_FA,_Field) <=> fail.
9658 used_states_known/0.
9660 :- chr_option(mode,uses_state(+,+)).
9661 :- chr_option(mode,if_used_state(+,+,?,?,?)).
9664 % states ::= not_stored_yet | passive | active | triggered | removed
9666 % allocate CREATES not_stored_yet
9667 % remove CHECKS not_stored_yet
9668 % activate CHECKS not_stored_yet
9670 % ==> no allocate THEN no not_stored_yet
9672 % recurs CREATES inactive
9673 % lookup CHECKS inactive
9675 % insert CREATES active
9676 % activate CREATES active
9677 % lookup CHECKS active
9678 % recurs CHECKS active
9680 % runsusp CREATES triggered
9681 % lookup CHECKS triggered
9683 % ==> no runsusp THEN no triggered
9685 % remove CREATES removed
9686 % runsusp CHECKS removed
9687 % lookup CHECKS removed
9688 % recurs CHECKS removed
9690 % ==> no remove THEN no removed
9692 % ==> no allocate, no remove, no active/inactive distinction THEN no state at all...
9694 uses_state(Constraint,State) \ uses_state(Constraint,State) <=> true.
9696 used_states_known, uses_state(Constraint,State) \ if_used_state(Constraint,State,Used,NotUsed,ResultGoal)
9697 <=> ResultGoal = Used.
9698 used_states_known \ if_used_state(Constraint,State,Used,NotUsed,ResultGoal)
9699 <=> ResultGoal = NotUsed.
9701 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9702 % CHECK STOREDNESS ANNOTATIONS AND GENERATE DEFAULT SIMPLIFICATION RULES
9708 % When the programmer enables the `declare_stored_constraints' option, i.e. writes
9710 % :- chr_option(declare_stored_constraints,on).
9712 % the compiler will check for the storedness of constraints.
9714 % By default, the compiler assumes that the programmer wants his constraints to
9715 % be never-stored. Hence, a warning will be issues when a constraint is actually
9718 % Such warnings are suppressed, if the programmer adds the `# stored' modifier
9719 % to a constraint declaration, i.e. writes
9721 % :- chr_constraint c(...) # stored.
9723 % In that case a warning is issued when the constraint is never-stored.
9725 % NOTE: Checking is only performed if `storage_analysis' is on. Otherwise, all
9726 % constraints are stored anyway.
9729 % 2. Rule Generation
9730 % ~~~~~~~~~~~~~~~~~~
9732 % When the programmer enables the `declare_stored_constraints' option, i.e. writes
9734 % :- chr_option(declare_stored_constraints,on).
9736 % the compiler will generate default simplification rules for constraints.
9738 % By default, no default rule is generated for a constraint. However, if the
9739 % programmer writes a default/1 annotation in the constraint declaration, i.e. writes
9741 % :- chr_constraint c(...) # default(Goal).
9743 % where `Goal' is a ground and callable goal (e.g. `true', `fail' or `throw(error)'),
9744 % the compiler generates a rule:
9746 % c(_,...,_) <=> Goal.
9748 % at the end of the program. If multiple default rules are generated, for several constraints,
9749 % then the order of the default rules is not specified.
9752 :- chr_constraint stored_assertion/1.
9753 :- chr_option(mode,stored_assertion(+)).
9754 :- chr_option(type_declaration,stored_assertion(constraint)).
9756 :- chr_constraint never_stored_default/2.
9757 :- chr_option(mode,never_stored_default(+,?)).
9758 :- chr_option(type_declaration,never_stored_default(constraint,any)).
9763 generate_never_stored_rules(Constraints,Rules) :-
9764 ( chr_pp_flag(declare_stored_constraints,on) ->
9765 never_stored_rules(Constraints,Rules)
9770 :- chr_constraint never_stored_rules/2.
9771 :- chr_option(mode,never_stored_rules(+,?)).
9772 :- chr_option(type_declaration,never_stored_rules(list(constraint),any)).
9774 never_stored_rules([],Rules) <=> Rules = [].
9775 never_stored_default(Constraint,Goal) \ never_stored_rules([Constraint|Constraints],Rules) <=>
9778 inc_rule_count(RuleNb),
9780 rule([Head],[],true,Goal),
9786 Rules = [Rule|Tail],
9787 never_stored_rules(Constraints,Tail).
9788 never_stored_rules([_|Constraints],Rules) <=>
9789 never_stored_rules(Constraints,Rules).
9794 check_storedness_assertions(Constraints) :-
9795 ( chr_pp_flag(storage_analysis,on), chr_pp_flag(declare_stored_constraints,on) ->
9796 forall(Constraint,Constraints,check_storedness_assertion(Constraint))
9802 :- chr_constraint check_storedness_assertion/1.
9803 :- chr_option(mode,check_storedness_assertion(+)).
9804 :- chr_option(type_declaration,check_storedness_assertion(constraint)).
9806 check_storedness_assertion(Constraint), stored_assertion(Constraint)
9807 <=> ( is_stored(Constraint) ->
9810 chr_warning(assertion_failed,'Constraint ~w is not stored. However, it was asserted to be stored.\n',[Constraint])
9812 never_stored_default(Constraint,_) \ check_storedness_assertion(Constraint)
9813 <=> ( is_finally_stored(Constraint) ->
9814 chr_warning(assertion_failed,'Constraint ~w is stored. However, it was asserted not to be stored.\n',[Constraint])
9815 ; is_stored(Constraint) ->
9816 chr_warning(assertion_failed,'Constraint ~w is temporarily stored. However, it was asserted not to be stored.\n',[Constraint])
9820 % never-stored, no default goal
9821 check_storedness_assertion(Constraint)
9822 <=> ( is_finally_stored(Constraint) ->
9823 chr_warning(assertion_failed,'Constraint ~w is stored. However, it was asserted not to be stored.\n',[Constraint])
9824 ; is_stored(Constraint) ->
9825 chr_warning(assertion_failed,'Constraint ~w is temporarily stored. However, it was asserted not to be stored.\n',[Constraint])
9830 %^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
9831 % success continuation analysis
9834 % also use for forward jumping improvement!
9835 % use Prolog indexing for generated code
9839 % should_skip_to_next_id(C,O)
9841 % get_occurrence_code_id(C,O,Id)
9843 %vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
9845 continuation_analysis(ConstraintSymbols) :-
9846 maplist(analyse_continuations,ConstraintSymbols).
9848 analyse_continuations(C) :-
9849 % 1. compute success continuations of the
9850 % occurrences of constraint C
9851 continuation_analysis(C,1),
9852 % 2. determine for which occurrences
9853 % to skip to next code id
9854 get_max_occurrence(C,MO),
9856 bulk_propagation(C,1,LO),
9857 % 3. determine code id for each occurrence
9858 set_occurrence_code_id(C,1,0).
9860 % 1. Compute the success continuations of constrait C
9861 %-------------------------------------------------------------------------------
9863 continuation_analysis(C,O) :-
9864 get_max_occurrence(C,MO),
9869 continuation_occurrence(C,O,NextO)
9871 constraint_continuation(C,O,MO,NextO),
9872 continuation_occurrence(C,O,NextO),
9874 continuation_analysis(C,NO)
9877 constraint_continuation(C,O,MO,NextO) :-
9878 ( get_occurrence_head(C,O,Head) ->
9880 ( between(NO,MO,NextO),
9881 get_occurrence_head(C,NextO,NextHead),
9882 unifiable(Head,NextHead,_) ->
9887 ; % current occurrence is passive
9891 get_occurrence_head(C,O,Head) :-
9892 get_occurrence(C,O,RuleNb,Id),
9893 \+ is_passive(RuleNb,Id),
9894 get_rule(RuleNb,Rule),
9895 Rule = pragma(rule(H1,H2,_,_),ids(Ids1,Ids2),_,_,_),
9896 ( select2(Id,Head,Ids1,H1,_,_) -> true
9897 ; select2(Id,Head,Ids2,H2,_,_)
9900 :- chr_constraint continuation_occurrence/3.
9901 :- chr_option(mode,continuation_occurrence(+,+,+)).
9903 :- chr_constraint get_success_continuation_occurrence/3.
9904 :- chr_option(mode,get_success_continuation_occurrence(+,+,-)).
9906 continuation_occurrence(C,O,NO) \ get_success_continuation_occurrence(C,O,X)
9910 get_success_continuation_occurrence(C,O,X)
9912 chr_error(internal,'Success continuation not found for ~w.\n',[C:O]).
9914 % 2. figure out when to skip to next code id
9915 %-------------------------------------------------------------------------------
9916 % don't go beyond the last occurrence
9917 % we have to go to next id for storage here
9919 :- chr_constraint skip_to_next_id/2.
9920 :- chr_option(mode,skip_to_next_id(+,+)).
9922 :- chr_constraint should_skip_to_next_id/2.
9923 :- chr_option(mode,should_skip_to_next_id(+,+)).
9925 skip_to_next_id(C,O) \ should_skip_to_next_id(C,O)
9929 should_skip_to_next_id(_,_)
9933 :- chr_constraint bulk_propagation/3.
9934 :- chr_option(mode,bulk_propagation(+,+,+)).
9936 max_occurrence(C,MO) \ bulk_propagation(C,O,_)
9940 skip_to_next_id(C,O).
9941 % we have to go to the next id here because
9942 % a predecessor needs it
9943 bulk_propagation(C,O,LO)
9947 skip_to_next_id(C,O),
9948 get_max_occurrence(C,MO),
9950 bulk_propagation(C,LO,NLO).
9951 % we have to go to the next id here because
9952 % we're running into a simplification rule
9953 % IMPROVE: propagate back to propagation predecessor (IF ANY)
9954 occurrence(C,NO,_,_,simplification) \ bulk_propagation(C,O,LO)
9958 skip_to_next_id(C,O),
9959 get_max_occurrence(C,MO),
9961 bulk_propagation(C,NO,NLO).
9962 % we skip the next id here
9963 % and go to the next occurrence
9964 continuation_occurrence(C,O,NextO) \ bulk_propagation(C,O,LO)
9968 NLO is min(LO,NextO),
9970 bulk_propagation(C,NO,NLO).
9972 % err on the safe side
9973 bulk_propagation(C,O,LO)
9975 skip_to_next_id(C,O),
9976 get_max_occurrence(C,MO),
9979 bulk_propagation(C,NO,NLO).
9981 skip_to_next_id(C,O) \ skip_to_next_id(C,O) <=> true.
9983 % if this occurrence is passive, but has to skip,
9984 % then the previous one must skip instead...
9985 % IMPROVE reasoning is conservative
9986 occurrence(C,O,RuleNb,Id,_), passive(RuleNb,Id), skip_to_next_id(C,O)
9991 skip_to_next_id(C,PO).
9993 % 3. determine code id of each occurrence
9994 %-------------------------------------------------------------------------------
9996 :- chr_constraint set_occurrence_code_id/3.
9997 :- chr_option(mode,set_occurrence_code_id(+,+,+)).
9999 :- chr_constraint occurrence_code_id/3.
10000 :- chr_option(mode,occurrence_code_id(+,+,+)).
10003 set_occurrence_code_id(C,O,IdNb)
10005 get_max_occurrence(C,MO),
10008 occurrence_code_id(C,O,IdNb).
10010 % passive occurrences don't change the code id
10011 occurrence(C,O,RuleNb,Id,_), passive(RuleNb,Id) \ set_occurrence_code_id(C,O,IdNb)
10013 occurrence_code_id(C,O,IdNb),
10015 set_occurrence_code_id(C,NO,IdNb).
10017 occurrence(C,O,RuleNb,Id,simplification) \ set_occurrence_code_id(C,O,IdNb)
10019 occurrence_code_id(C,O,IdNb),
10021 set_occurrence_code_id(C,NO,IdNb).
10023 occurrence(C,O,RuleNb,Id,propagation), skip_to_next_id(C,O) \ set_occurrence_code_id(C,O,IdNb)
10025 occurrence_code_id(C,O,IdNb),
10028 set_occurrence_code_id(C,NO,NIdNb).
10030 occurrence(C,O,RuleNb,Id,propagation) \ set_occurrence_code_id(C,O,IdNb)
10032 occurrence_code_id(C,O,IdNb),
10034 set_occurrence_code_id(C,NO,IdNb).
10036 % occurrence_code_id(C,O,IdNb) ==> writeln(occurrence_code_id(C,O,IdNb)).
10038 :- chr_constraint get_occurrence_code_id/3.
10039 :- chr_option(mode,get_occurrence_code_id(+,+,-)).
10041 occurrence_code_id(C,O,IdNb) \ get_occurrence_code_id(C,O,X)
10045 get_occurrence_code_id(C,O,X)
10050 format('no occurrence code for ~w!\n',[C:O])
10053 get_success_continuation_code_id(C,O,NextId) :-
10054 get_success_continuation_occurrence(C,O,NextO),
10055 get_occurrence_code_id(C,NextO,NextId).
10057 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10058 % COLLECT CONSTANTS FOR INLINING
10062 % collect_constants(+rules,+constraint_symbols,+clauses) {{{
10063 collect_constants(Rules,Constraints,Clauses0) :-
10065 maplist(collect_rule_constants(Constraints),Rules),
10066 ( chr_pp_flag(verbose,on) ->
10067 print_chr_constants
10071 ( chr_pp_flag(experiment,on) ->
10072 flattening_dictionary(Constraints,Dictionary),
10073 copy_term_nat([dict(Dictionary)|Clauses0],Clauses),
10074 flatten_clauses(Clauses,FlatClauses),
10075 install_new_declarations_and_restart(FlatClauses)
10083 :- chr_constraint chr_constants/2.
10084 :- chr_option(mode,chr_constants(+,+)).
10086 :- chr_constraint get_chr_constants/2.
10088 chr_constants(Key,Constants) \ get_chr_constants(Key,Q) <=> Q = Constants.
10090 get_chr_constants(Key,Q) <=> chr_warning(internal,'No constants found for key ~w.\n',[Key]), Q = [].
10092 % collect_rule_constants(+constraint_symbols,+rule) {{{
10093 collect_rule_constants(Constraints,Rule) :-
10094 Rule = pragma(rule(H1,H2,_,B),_,_,_,_),
10095 maplist(collect_head_constants,H1),
10096 maplist(collect_head_constants,H2),
10097 collect_body_constants(B,Constraints).
10099 collect_body_constants(Body,Constraints) :-
10100 conj2list(Body,Goals),
10101 maplist(collect_goal_constants(Constraints),Goals).
10103 collect_goal_constants(Constraints,Goal) :-
10106 memberchk(C/N,Constraints) ->
10107 collect_head_constants(Goal)
10109 Goal = Mod : TheGoal,
10110 get_target_module(Module),
10113 functor(TheGoal,C,N),
10114 memberchk(C/N,Constraints) ->
10115 collect_head_constants(TheGoal)
10120 collect_head_constants(Head) :-
10122 get_constraint_type_det(C/N,Types),
10124 maplist(collect_arg_constants,Args,Types).
10126 collect_arg_constants(Arg,Type) :-
10128 unalias_type(Type,chr_constants(Key)) ->
10129 add_chr_constant(Key,Arg)
10133 :- chr_constraint add_chr_constant/2.
10134 :- chr_option(mode,add_chr_constant(+,+)).
10136 add_chr_constant(Key,Constant) , chr_constants(Key,Constants) <=>
10137 sort([Constant|Constants],NConstants),
10138 chr_constants(Key,NConstants).
10140 add_chr_constant(Key,Constant) <=>
10141 chr_constants(Key,[Constant]).
10145 :- chr_constraint print_chr_constants/0. % {{{
10147 print_chr_constants, chr_constants(Key,Constants) # Id ==>
10148 format('\t* chr_constants ~w : ~w.\n',[Key,Constants])
10149 pragma passive(Id).
10151 print_chr_constants <=>
10156 % flattening_dictionary(+constraint_symbols,-dictionary) {{{
10157 flattening_dictionary([],[]).
10158 flattening_dictionary([CS|CSs],Dictionary) :-
10159 ( flattening_dictionary_entry(CS,Entry) ->
10160 Dictionary = [Entry|Rest]
10164 flattening_dictionary(CSs,Rest).
10166 flattening_dictionary_entry(CS,Entry) :-
10167 get_constraint_arg_type(CS,Pos,Type),
10168 Type = chr_constants(Key), !,
10169 get_chr_constants(Key,Constants),
10170 Entry = CS-Pos-Specs,
10171 maplist(flat_spec(CS,Pos),Constants,Specs).
10173 flat_spec(C/N,Pos,Term,Spec) :-
10174 Spec = Term - Functor,
10175 term_to_atom(Term,TermAtom),
10176 atom_concat_list(['$flat_',C,'/',N,'___',Pos,'___',TermAtom],Functor).
10180 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10181 % RESTART AFTER FLATTENING {{{
10183 restart_after_flattening(Declarations,Declarations) :-
10184 nb_setval('$chr_restart_after_flattening',started).
10185 restart_after_flattening(_,Declarations) :-
10186 nb_getval('$chr_restart_after_flattening',restart(Declarations)),
10187 nb_setval('$chr_restart_after_flattening',restarted).
10190 nb_getval('$chr_restart_after_flattening',started).
10192 install_new_declarations_and_restart(Declarations) :-
10193 nb_setval('$chr_restart_after_flattening',restart(Declarations)),
10194 fail. /* fails to choicepoint of restart_after_flattening */
10196 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10200 % -) generate dictionary from collected chr_constants
10201 % enable with :- chr_option(experiment,on).
10202 % -) issue constraint declarations for constraints not present in
10206 % -) integrate with CHR compiler
10207 % RELEASE-----------------------------------------------------------------
10208 % -) pass Mike's test code (full syntactic support for current CHR code)
10209 % -) rewrite the body using the inliner
10210 % -) refined semantics correctness issue
10211 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10213 flatten_clauses(Clauses0,NClauses) :-
10214 select(dict(Dict),Clauses0,Clauses),
10215 flatten_readcontent(Clauses,Rules,Symbols,ModeDecls,_TypeDefs,TypeDecls,RestClauses),
10216 flatten_clauses_(Dict,Rules,RestClauses,Symbols,ModeDecls,TypeDecls,NClauses).
10218 flatten_clauses_(Dict,Clauses,RestClauses,Symbols,ModeDecls,TypeDecls,NClauses) :-
10219 auxiliary_constraints_declarations(Dict,ModeDecls,TypeDecls,NClauses0),
10220 dispatching_rules(Dict,NClauses1),
10221 declarations(Symbols,Dict,ModeDecls,TypeDecls,NClauses2),
10222 flatten_rules(Clauses,Dict,NClauses3),
10223 append([RestClauses,NClauses0,NClauses1,NClauses2,NClauses3],NClauses).
10225 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10226 % Declarations for non-flattened constraints
10228 % declarations(+constraint_symbols,+dict,+mode_decls,+type_decls,-clauses) {{{
10229 declarations(ConstraintSymbols,Dict,ModeDecls,TypeDecls,Declarations) :-
10230 findall(Symbol,(member(Symbol,ConstraintSymbols), \+ memberchk(Symbol-_-_,Dict)),Symbols),
10231 maplist(declaration(ModeDecls,TypeDecls),Symbols,DeclarationsList),
10232 flatten(DeclarationsList,Declarations).
10234 declaration(ModeDecls,TypeDecls,ConstraintSymbol,
10235 [(:- chr_constraint ConstraintSymbol),
10236 (:- chr_option(mode,ModeDeclPattern)),
10237 (:- chr_option(type_declaration,TypeDeclPattern))
10239 ConstraintSymbol = Functor / Arity,
10240 % print optional mode declaration
10241 functor(ModeDeclPattern,Functor,Arity),
10242 ( memberchk(ModeDeclPattern,ModeDecls) ->
10245 replicate(Arity,(?),Modes),
10246 ModeDeclPattern =.. [_|Modes]
10248 % print optional type declaration
10249 functor(TypeDeclPattern,Functor,Arity),
10250 ( memberchk(TypeDeclPattern,TypeDecls) ->
10253 replicate(Arity,any,Types),
10254 TypeDeclPattern =.. [_|Types]
10257 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10258 % read clauses from file
10260 % declared constaints are returned
10261 % type definitions are returned and printed
10262 % mode declarations are returned
10263 % other clauses are returned
10265 % flatten_readcontent(+clauses,-rules,-symbols,-mode_decls,-type_defs,-type_decls,-rest_clauses) {{{
10266 flatten_readcontent([],[],[],[],[],[],[]).
10267 flatten_readcontent([Clause|RClauses],Rules,ConstraintSymbols,ModeDecls,TypeDefs,TypeDecls,RestClauses) :-
10269 ( Clause == end_of_file ->
10271 ConstraintSymbols = [],
10276 ; crude_is_rule(Clause) ->
10277 Rules = [Clause|RestRules],
10278 flatten_readcontent(RClauses,RestRules,ConstraintSymbols,ModeDecls,TypeDefs,TypeDecls,RestClauses)
10279 ; pure_is_declaration(Clause,SomeConstraintSymbols,SomeModeDecls,SomeTypeDecls) ->
10280 append(SomeConstraintSymbols,RestConstraintSymbols,ConstraintSymbols),
10281 append(SomeModeDecls,RestModeDecls,ModeDecls),
10282 append(SomeTypeDecls,RestTypeDecls,TypeDecls),
10283 flatten_readcontent(RClauses,Rules,RestConstraintSymbols,RestModeDecls,TypeDefs,RestTypeDecls,RestClauses)
10284 ; is_mode_declaration(Clause,ModeDecl) ->
10285 ModeDecls = [ModeDecl|RestModeDecls],
10286 flatten_readcontent(RClauses,Rules,ConstraintSymbols,RestModeDecls,TypeDefs,TypeDecls,RestClauses)
10287 ; is_type_declaration(Clause,TypeDecl) ->
10288 TypeDecls = [TypeDecl|RestTypeDecls],
10289 flatten_readcontent(RClauses,Rules,ConstraintSymbols,ModeDecls,TypeDefs,RestTypeDecls,RestClauses)
10290 ; is_type_definition(Clause,TypeDef) ->
10291 RestClauses = [Clause|NRestClauses],
10292 TypeDefs = [TypeDef|RestTypeDefs],
10293 flatten_readcontent(RClauses,Rules,ConstraintSymbols,ModeDecls,RestTypeDefs,TypeDecls,NRestClauses)
10294 ; ( Clause = (:- op(A,B,C)) ->
10295 % assert operators in order to read and print them out properly
10300 RestClauses = [Clause|NRestClauses],
10301 flatten_readcontent(RClauses,Rules,ConstraintSymbols,ModeDecls,TypeDefs,TypeDecls,NRestClauses)
10304 crude_is_rule(_ @ _).
10305 crude_is_rule(_ pragma _).
10306 crude_is_rule(_ ==> _).
10307 crude_is_rule(_ <=> _).
10309 pure_is_declaration(D, Constraints,Modes,Types) :- %% constraint declaration
10310 D = (:- Decl), Decl =.. [F,Cs], F == (chr_constraint),
10311 conj2list(Cs,Constraints0),
10312 pure_extract_type_mode(Constraints0,Constraints,Modes,Types).
10314 pure_extract_type_mode([],[],[],[]).
10315 pure_extract_type_mode([F/A|R],[F/A|R2],Modes,Types) :- !,
10316 pure_extract_type_mode(R,R2,Modes,Types).
10317 pure_extract_type_mode([C|R],[ConstraintSymbol|R2],[Mode|Modes],Types) :-
10319 ConstraintSymbol = F/A,
10321 extract_types_and_modes(Args,ArgTypes,ArgModes),
10322 Mode =.. [F|ArgModes],
10323 ( forall(member(ArgType,ArgTypes),ArgType == any) ->
10326 Types = [Type|RTypes],
10327 Type =.. [F|ArgTypes]
10329 pure_extract_type_mode(R,R2,Modes,RTypes).
10331 is_mode_declaration((:- chr_option(mode,ModeDecl)),ModeDecl).
10333 is_type_declaration((:- chr_option(type_declaration,TypeDecl)),TypeDecl).
10335 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10336 % DECLARATIONS FOR FLATTENED CONSTRAINTS
10337 % including mode and type declarations
10339 % auxiliary_constraints_declarations(+dict,+mode_decls,+type_decls,-constraint_specs) {{{
10340 auxiliary_constraints_declarations(Dict,ModeDecls,TypeDecls,ConstraintSpecs) :-
10341 findall(ConstraintSpec,auxiliary_constraints_declaration(Dict,ModeDecls,TypeDecls,ConstraintSpec),ConstraintSpecs0),
10342 flatten(ConstraintSpecs0,ConstraintSpecs).
10344 auxiliary_constraints_declaration(Dict,ModeDecls,TypeDecls,
10345 [(:- chr_constraint ConstraintSpec),
10346 (:- chr_option(mode,NewModeDecl)),
10347 (:- chr_option(type_declaration,NewTypeDecl))]) :-
10348 member(C/N-I-SFs,Dict),
10349 arg_modes(C,N,ModeDecls,Modes),
10350 specialize_modes(Modes,I,SpecializedModes),
10351 arg_types(C,N,TypeDecls,Types),
10352 specialize_types(Types,I,SpecializedTypes),
10354 member(_Term-F,SFs),
10355 ConstraintSpec = F/AN,
10356 NewModeDecl =.. [F|SpecializedModes],
10357 NewTypeDecl =.. [F|SpecializedTypes].
10359 arg_modes(C,N,ModeDecls,ArgModes) :-
10360 functor(ConstraintPattern,C,N),
10361 ( memberchk(ConstraintPattern,ModeDecls) ->
10362 ConstraintPattern =.. [_|ArgModes]
10364 replicate(N,?,ArgModes)
10367 specialize_modes(Modes,I,SpecializedModes) :-
10368 split(Modes,I,Before,_At,After),
10369 append(Before,After,SpecializedModes).
10371 arg_types(C,N,TypeDecls,ArgTypes) :-
10372 functor(ConstraintPattern,C,N),
10373 ( memberchk(ConstraintPattern,TypeDecls) ->
10374 ConstraintPattern =.. [_|ArgTypes]
10376 replicate(N,any,ArgTypes)
10379 specialize_types(Types,I,SpecializedTypes) :-
10380 split(Types,I,Before,_At,After),
10381 append(Before,After,SpecializedTypes).
10384 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10385 % DISPATCHING RULES
10387 % dispatching_rules(+dict,-newrules)
10390 dispatching_rules([],[]).
10391 dispatching_rules([CN-I-SFs|Dict], DispatchingRules) :-
10392 constraint_dispatching_rule(SFs,CN,I,DispatchingRules,RestDispatchingRules),
10393 dispatching_rules(Dict,RestDispatchingRules).
10395 constraint_dispatching_rule(SFs,CN,I,Rules,RestRules) :-
10397 /* index on first argument */
10402 /* reorder arguments for 1st argument indexing */
10405 split(Args,I,BeforeArgs,IndexArg,AfterArgs),
10406 append([IndexArg|BeforeArgs],AfterArgs,ShuffledArgs),
10407 atom_concat(C,'_$shuffled',NC),
10408 Body =.. [NC|ShuffledArgs],
10409 [(Head :- Body)|Rules0] = Rules,
10412 dispatching_rule_term_cases(SFs,NCN,Rules0,RestRules).
10413 % dispatching_rule_cases(SFs,NCN,Rules0,RestRules).
10415 dispatching_rule_term_cases(SFs,NC/N,Rules,RestRules) :-
10416 once(pairup(Terms,Functors,SFs)),
10418 replicate(K,[],MorePatterns),
10420 maplist(dispatching_action,Functors,Actions),
10421 dispatch_trie_index([Terms|MorePatterns],Payload,Actions,NC,Rules,RestRules).
10423 dispatching_action(Functor,PayloadArgs,Goal) :-
10424 Goal =.. [Functor|PayloadArgs].
10426 % dispatching_rule_cases([],C/N,Rules,RestRules) :-
10427 % functor(Head,C,N),
10428 % arg(1,Head,IndexArg),
10429 % Body = throw(wrong_argument(C/N,IndexArg)),
10430 % Rules = [(Head :- Body)|RestRules].
10431 % dispatching_rule_cases([Term-Name|SFs],C/N,[Rule|Rules],RestRules) :-
10432 % functor(Head,C,N),
10433 % Head =.. [_,IndexArg|RestArgs],
10435 % Body =.. [Name|RestArgs],
10436 % Rule = (Head :- !, Body),
10437 % dispatching_rule_special(SFs,C/N,Rules,RestRules).
10439 dispatch_trie_index([Patterns|MorePatterns],Payload,Actions,Prefix,Clauses,Tail) :-
10440 dispatch_trie_step(Patterns,Prefix,Prefix,MorePatterns,Payload,Actions,Clauses,Tail).
10442 dispatch_trie_step([],_,_,_,[],[],L,L) :- !.
10443 % length MorePatterns == length Patterns == length Results
10444 dispatch_trie_step(Patterns,Symbol,Prefix,MorePatterns,Payload,Actions,Clauses,T) :-
10445 writeln(dispatch_trie_step(Patterns,Symbol,Prefix,MorePatterns,Payload,Actions,Clauses,T)),
10446 MorePatterns = [List|_],
10448 aggregate_all(set(F/A),
10449 ( member(Pattern,Patterns),
10450 functor(Pattern,F,A)
10454 dispatch_trie_step_cases(FAs,N1,Patterns,MorePatterns,Payload,Actions,Symbol,Prefix,Clauses,T).
10456 dispatch_trie_step_cases([],_,_,_,_,_,_,_,Clauses,Clauses).
10457 dispatch_trie_step_cases([FA|FAs],N,Pattern,MorePatterns,Payload,Actions,Symbol,Prefix,Clauses,Tail) :-
10458 dispatch_trie_step_case(FA,N,Pattern,MorePatterns,Payload,Actions,Symbol,Prefix,Clauses,Clauses1),
10459 dispatch_trie_step_cases(FAs,N,Pattern,MorePatterns,Payload,Actions,Symbol,Prefix,Clauses1,Tail).
10461 dispatch_trie_step_case(F/A,N,Patterns,MorePatterns,Payload,Actions,Symbol,Prefix,[Clause|List],Tail) :-
10462 Clause = (Head :- Body),
10463 /* Head = Symbol(IndexPattern,V2,...,Vn,Payload) */
10465 functor(Head,Symbol,N1),
10466 arg(1,Head,IndexPattern),
10467 Head =.. [_,_|RestArgs],
10468 length(PayloadArgs,Payload),
10469 once(append(Vs,PayloadArgs,RestArgs)),
10470 /* IndexPattern = F(...) */
10471 functor(IndexPattern,F,A),
10472 IndexPattern =.. [_|Args],
10473 append(Args,RestArgs,RecArgs),
10474 ( RecArgs == PayloadArgs ->
10475 /* nothing more to match on */
10477 rec_cases(Patterns,_,Actions,F/A,_,_,MoreActions),
10478 MoreActions = [Action],
10479 call(Action,PayloadArgs,Body)
10480 ; /* more things to match on */
10481 rec_cases(Patterns,MorePatterns,Actions,F/A,Cases,MoreCases,MoreActions),
10482 ( MoreActions = [OneMoreAction] ->
10483 /* only one more thing to match on */
10485 call(OneMoreAction,PayloadArgs,Body)
10487 /* more than one thing to match on */
10491 pairup(Cases,MoreCases,CasePairs),
10492 common_pattern(CasePairs,CommonPatternPair,DiffVars,Differences),
10493 append(Args,Vs,[First|Rest]),
10494 First-Rest = CommonPatternPair,
10495 gensym(Prefix,RSymbol),
10496 append(DiffVars,PayloadArgs,RecCallVars),
10497 Body =.. [RSymbol|RecCallVars],
10498 findall(CH-CT,member([CH|CT],Differences),CPairs),
10499 once(pairup(CHs,CTs,CPairs)),
10500 dispatch_trie_step(CHs,RSymbol,Prefix,CTs,Payload,MoreActions,List,Tail)
10505 % split(list,int,before,at,after).
10507 split([X|Xs],I,Before,At,After) :-
10514 Before = [X|RBefore],
10515 split(Xs,J,RBefore,At,After)
10519 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10520 % SUBSTITUTE CONSTRAINT SYMBOL FUNCTORS
10522 % flatten_rules(+rule_clauses,+dict,-rule_clauses).
10524 % dict :== list(functor/arity-int-list(term-functor))
10527 flatten_rules(Rules,Dict,FlatRules) :-
10528 flatten_rules1(Rules,Dict,FlatRulesList),
10529 flatten(FlatRulesList,FlatRules).
10531 flatten_rules1([],_,[]).
10532 flatten_rules1([Rule|Rules],Dict,[FlatRules|FlatRulesList]) :-
10533 findall(FlatRule,flatten_rule(Rule,Dict,FlatRule),FlatRules),
10534 flatten_rules1(Rules,Dict,FlatRulesList).
10536 flatten_rule((Name @ Rule),Dict,(Name @ NRule)) :- !,
10537 flatten_rule(Rule,Dict,NRule).
10538 flatten_rule((Rule pragma Pragmas),Dict,(NRule pragma Pragmas)) :- !,
10539 flatten_rule(Rule,Dict,NRule).
10540 flatten_rule((H ==> B),Dict,(NH ==> NB)) :- !,
10541 flatten_heads(H,Dict,NH),
10542 flatten_body(B,Dict,NB).
10543 flatten_rule((H1 \ H2 <=> B),Dict,(NH1 \ NH2 <=> NB)) :- !,
10544 flatten_heads((H1,H2),Dict,(NH1,NH2)),
10545 flatten_body(B,Dict,NB).
10546 flatten_rule((H <=> B),Dict,(NH <=> NB)) :-
10547 flatten_heads(H,Dict,NH),
10548 flatten_body(B,Dict,NB).
10550 flatten_heads((H1,H2),Dict,(NH1,NH2)) :- !,
10551 flatten_heads(H1,Dict,NH1),
10552 flatten_heads(H2,Dict,NH2).
10553 flatten_heads((H # Annotation),Dict,(NH # Annotation)) :- !,
10554 flatten_heads(H,Dict,NH).
10555 flatten_heads(H,Dict,NH) :-
10557 memberchk(C/N-I-SFs,Dict) ->
10559 split(AllArgs,I,PreArgs,Arg,PostArgs),
10560 member(Term-Name,SFs),
10562 append(PreArgs,PostArgs,FlatArgs),
10563 NH =.. [Name|FlatArgs]
10568 flatten_body(Body,Dict,NBody) :-
10569 conj2list(Body,Goals),
10570 maplist(flatten_goal(Dict),Goals,NGoals),
10571 list2conj(NGoals,NBody).
10573 flatten_goal(Dict,Goal,NGoal) :-
10574 ( is_specializable_goal(Goal,Dict,ArgPos)
10576 specialize_goal(Goal,ArgPos,NGoal)
10578 Goal = Mod : TheGoal,
10579 get_target_module(Module),
10581 is_specializable_goal(TheGoal,Dict,ArgPos)
10583 specialize_goal(TheGoal,ArgPos,NTheGoal),
10584 NGoal = Mod : NTheGoal
10589 is_specializable_goal(Goal,Dict,ArgPos) :-
10592 memberchk(C/N-ArgPos-_,Dict),
10593 arg(ArgPos,Goal,Arg),
10597 specialize_goal(Goal,ArgPos,NGoal) :-
10600 split(Args,ArgPos,Before,Arg,After),
10601 append(Before,After,NArgs),
10602 flat_spec(C/N,ArgPos,Arg,_-Functor),
10603 NGoal =.. [Functor|NArgs].
10607 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10608 dump_code(Clauses) :-
10609 ( chr_pp_flag(dump,on) ->
10610 maplist(portray_clause,Clauses)
10611 % member(Clause,Clauses),
10612 % copy_term_nat(Clause,NClause),
10613 % portray_clause(NClause),
10620 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',[]).