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(1150, fx, chr_declaration).
160 :- op(1130, xfx, --->).
164 :- op(1150, fx, constraints).
165 :- op(1150, fx, chr_constraint).
168 :- chr_option(debug,off).
169 :- chr_option(optimize,full).
170 :- chr_option(check_guard_bindings,off).
172 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
173 % Type Declarations {{{
174 :- chr_type list(T) ---> [] ; [T|list(T)].
176 :- chr_type list == list(any).
178 :- chr_type mode ---> (+) ; (-) ; (?).
180 :- chr_type maybe(T) ---> yes(T) ; no.
182 :- chr_type constraint ---> any / any.
184 :- chr_type module_name == any.
186 :- chr_type pragma_rule ---> pragma(rule,idspair,list(pragma_type),maybe(rule_name),rule_nb).
187 :- chr_type rule ---> rule(list(any),list(any),goal,goal).
188 :- chr_type idspair ---> ids(list(id),list(id)).
190 :- chr_type pragma_type ---> passive(id)
193 ; already_in_heads(id)
195 ; history(history_name,list(id)).
196 :- chr_type history_name== any.
198 :- chr_type rule_name == any.
199 :- chr_type rule_nb == natural.
200 :- chr_type id == natural.
201 :- chr_type occurrence == int.
203 :- chr_type goal == any.
205 :- chr_type store_type ---> default
206 ; multi_store(list(store_type))
207 ; multi_hash(list(list(int)))
208 ; multi_inthash(list(list(int)))
211 % EXPERIMENTAL STORES
212 ; atomic_constants(list(int),list(any),coverage)
213 ; ground_constants(list(int),list(any),coverage)
214 ; var_assoc_store(int,list(int))
215 ; identifier_store(int)
216 ; type_indexed_identifier_store(int,any).
217 :- chr_type coverage ---> complete ; incomplete.
219 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
221 %------------------------------------------------------------------------------%
222 :- chr_constraint chr_source_file/1.
223 :- chr_option(mode,chr_source_file(+)).
224 :- chr_option(type_declaration,chr_source_file(module_name)).
225 %------------------------------------------------------------------------------%
226 chr_source_file(_) \ chr_source_file(_) <=> true.
228 %------------------------------------------------------------------------------%
229 :- chr_constraint get_chr_source_file/1.
230 :- chr_option(mode,get_chr_source_file(-)).
231 :- chr_option(type_declaration,get_chr_source_file(module_name)).
232 %------------------------------------------------------------------------------%
233 chr_source_file(Mod) \ get_chr_source_file(Query)
235 get_chr_source_file(Query)
239 %------------------------------------------------------------------------------%
240 :- chr_constraint target_module/1.
241 :- chr_option(mode,target_module(+)).
242 :- chr_option(type_declaration,target_module(module_name)).
243 %------------------------------------------------------------------------------%
244 target_module(_) \ target_module(_) <=> true.
246 %------------------------------------------------------------------------------%
247 :- chr_constraint get_target_module/1.
248 :- chr_option(mode,get_target_module(-)).
249 :- chr_option(type_declaration,get_target_module(module_name)).
250 %------------------------------------------------------------------------------%
251 target_module(Mod) \ get_target_module(Query)
253 get_target_module(Query)
256 %------------------------------------------------------------------------------%
257 :- chr_constraint line_number/2.
258 :- chr_option(mode,line_number(+,+)).
259 :- chr_option(type_declaration,line_number(rule_nb,int)).
260 %------------------------------------------------------------------------------%
261 line_number(RuleNb,LineNb) \ line_number(RuleNb,LineNumber) <=> true.
263 %------------------------------------------------------------------------------%
264 :- chr_constraint get_line_number/2.
265 :- chr_option(mode,get_line_number(+,-)).
266 :- chr_option(type_declaration,get_line_number(rule_nb,int)).
267 %------------------------------------------------------------------------------%
268 line_number(RuleNb,LineNb) \ get_line_number(RuleNb,Q) <=> Q = LineNb.
269 get_line_number(RuleNb,Q) <=> Q = 0. % no line number available
271 :- chr_constraint indexed_argument/2. % argument instantiation may enable applicability of rule
272 :- chr_option(mode,indexed_argument(+,+)).
273 :- chr_option(type_declaration,indexed_argument(constraint,int)).
275 :- chr_constraint is_indexed_argument/2.
276 :- chr_option(mode,is_indexed_argument(+,+)).
277 :- chr_option(type_declaration,is_indexed_argument(constraint,int)).
279 :- chr_constraint constraint_mode/2.
280 :- chr_option(mode,constraint_mode(+,+)).
281 :- chr_option(type_declaration,constraint_mode(constraint,list(mode))).
283 :- chr_constraint get_constraint_mode/2.
284 :- chr_option(mode,get_constraint_mode(+,-)).
285 :- chr_option(type_declaration,get_constraint_mode(constraint,list(mode))).
287 :- chr_constraint may_trigger/1.
288 :- chr_option(mode,may_trigger(+)).
289 :- chr_option(type_declaration,may_trigger(constraint)).
291 :- chr_constraint only_ground_indexed_arguments/1.
292 :- chr_option(mode,only_ground_indexed_arguments(+)).
293 :- chr_option(type_declaration,only_ground_indexed_arguments(constraint)).
295 :- chr_constraint none_suspended_on_variables/0.
297 :- chr_constraint are_none_suspended_on_variables/0.
299 :- chr_constraint store_type/2.
300 :- chr_option(mode,store_type(+,+)).
301 :- chr_option(type_declaration,store_type(constraint,store_type)).
303 :- chr_constraint get_store_type/2.
304 :- chr_option(mode,get_store_type(+,?)).
305 :- chr_option(type_declaration,get_store_type(constraint,store_type)).
307 :- chr_constraint update_store_type/2.
308 :- chr_option(mode,update_store_type(+,+)).
309 :- chr_option(type_declaration,update_store_type(constraint,store_type)).
311 :- chr_constraint actual_store_types/2.
312 :- chr_option(mode,actual_store_types(+,+)).
313 :- chr_option(type_declaration,actual_store_types(constraint,list(store_type))).
315 :- chr_constraint assumed_store_type/2.
316 :- chr_option(mode,assumed_store_type(+,+)).
317 :- chr_option(type_declaration,assumed_store_type(constraint,store_type)).
319 :- chr_constraint validate_store_type_assumption/1.
320 :- chr_option(mode,validate_store_type_assumption(+)).
321 :- chr_option(type_declaration,validate_store_type_assumption(constraint)).
323 :- chr_constraint rule_count/1.
324 :- chr_option(mode,rule_count(+)).
325 :- chr_option(type_declaration,rule_count(natural)).
327 :- chr_constraint inc_rule_count/1.
328 :- chr_option(mode,inc_rule_count(-)).
329 :- chr_option(type_declaration,inc_rule_count(natural)).
331 rule_count(_) \ rule_count(_)
333 rule_count(C), inc_rule_count(NC)
334 <=> NC is C + 1, rule_count(NC).
336 <=> NC = 1, rule_count(NC).
338 :- chr_constraint passive/2.
339 :- chr_option(mode,passive(+,+)).
341 :- chr_constraint is_passive/2.
342 :- chr_option(mode,is_passive(+,+)).
344 :- chr_constraint any_passive_head/1.
345 :- chr_option(mode,any_passive_head(+)).
347 :- chr_constraint new_occurrence/4.
348 :- chr_option(mode,new_occurrence(+,+,+,+)).
350 :- chr_constraint occurrence/5.
351 :- chr_option(mode,occurrence(+,+,+,+,+)).
352 :- chr_type occurrence_type ---> simplification ; propagation.
353 :- chr_option(type_declaration,occurrence(constraint,occurrence,rule_nb,id,occurrence_type)).
355 :- chr_constraint get_occurrence/4.
356 :- chr_option(mode,get_occurrence(+,+,-,-)).
358 :- chr_constraint get_occurrence_from_id/4.
359 :- chr_option(mode,get_occurrence_from_id(+,-,+,+)).
361 :- chr_constraint max_occurrence/2.
362 :- chr_option(mode,max_occurrence(+,+)).
364 :- chr_constraint get_max_occurrence/2.
365 :- chr_option(mode,get_max_occurrence(+,-)).
367 :- chr_constraint allocation_occurrence/2.
368 :- chr_option(mode,allocation_occurrence(+,+)).
370 :- chr_constraint get_allocation_occurrence/2.
371 :- chr_option(mode,get_allocation_occurrence(+,-)).
373 :- chr_constraint rule/2.
374 :- chr_option(mode,rule(+,+)).
375 :- chr_option(type_declaration,rule(rule_nb,pragma_rule)).
377 :- chr_constraint get_rule/2.
378 :- chr_option(mode,get_rule(+,-)).
379 :- chr_option(type_declaration,get_rule(int,pragma_rule)).
381 :- chr_constraint least_occurrence/2.
382 :- chr_option(mode,least_occurrence(+,+)).
383 :- chr_option(type_declaration,least_occurrence(any,list)).
385 :- chr_constraint is_least_occurrence/1.
386 :- chr_option(mode,is_least_occurrence(+)).
389 indexed_argument(FA,I) \ indexed_argument(FA,I) <=> true.
390 indexed_argument(FA,I) \ is_indexed_argument(FA,I) <=> true.
391 is_indexed_argument(_,_) <=> fail.
393 %%% C O N S T R A I N T M O D E %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
395 constraint_mode(FA,_) \ constraint_mode(FA,_) <=> true.
396 constraint_mode(FA,Mode) \ get_constraint_mode(FA,Q) <=>
398 get_constraint_mode(FA,Q) <=>
402 %%% M A Y T R I G G E R %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
404 may_trigger(FA) <=> \+ has_active_occurrence(FA) | fail.
405 constraint_mode(FA,Mode), indexed_argument(FA,I) \ may_trigger(FA) <=>
409 may_trigger(FA) <=> chr_pp_flag(debugable,on). % in debug mode, we assume everything can be triggered
411 constraint_mode(FA,Mode), indexed_argument(FA,I) \ only_ground_indexed_arguments(FA)
417 only_ground_indexed_arguments(_) <=>
420 none_suspended_on_variables \ none_suspended_on_variables <=> true.
421 none_suspended_on_variables \ are_none_suspended_on_variables <=> true.
422 are_none_suspended_on_variables <=> fail.
423 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
426 % The functionality for inspecting and deciding on the different types of constraint
427 % store / indexes for constraints.
429 store_type(FA,StoreType)
430 ==> chr_pp_flag(verbose,on)
432 format('The indexes for ~w are:\n',[FA]),
433 format_storetype(StoreType).
434 % chr_info(verbose,'Storetype of ~w is ~w.\n',[FA,StoreType]).
436 format_storetype(multi_store(StoreTypes)) :- !,
437 maplist(format_storetype,StoreTypes).
438 format_storetype(atomic_constants(Index,Constants,_)) :-
439 format('\t* a trie index on the argument(s) ~w for the ground terms ~w\n',[Index,Constants]).
440 format_storetype(ground_constants(Index,Constants,_)) :-
441 format('\t* a trie index on the argument(s) ~w for the ground terms ~w\n',[Index,Constants]).
442 format_storetype(StoreType) :-
443 format('\t* ~w\n',[StoreType]).
451 get_store_type_normal @
452 store_type(FA,Store) \ get_store_type(FA,Query)
455 get_store_type_assumed @
456 assumed_store_type(FA,Store) \ get_store_type(FA,Query)
459 get_store_type_default @
460 get_store_type(_,Query)
463 % 2. Store type registration
464 % ~~~~~~~~~~~~~~~~~~~~~~~~~~
466 actual_store_types(C,STs) \ update_store_type(C,ST)
467 <=> memberchk(ST,STs) | true.
468 update_store_type(C,ST), actual_store_types(C,STs)
470 actual_store_types(C,[ST|STs]).
471 update_store_type(C,ST)
473 actual_store_types(C,[ST]).
475 % 3. Final decision on store types
476 % ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
478 validate_store_type_assumption(C) \ actual_store_types(C,STs), actual_atomic_multi_hash_keys(C,Index,Keys)
480 true % chr_pp_flag(experiment,on)
482 delete(STs,multi_hash([Index]),STs0),
484 ( get_constraint_arg_type(C,IndexPos,Type),
485 enumerated_atomic_type(Type,Atoms) ->
486 /* use the type constants rather than the collected keys */
488 Completeness = complete
491 Completeness = incomplete
493 actual_store_types(C,[atomic_constants(Index,Constants,Completeness)|STs0]).
494 validate_store_type_assumption(C) \ actual_store_types(C,STs), actual_ground_multi_hash_keys(C,Index,Constants0)
496 true % chr_pp_flag(experiment,on)
498 ( Index = [IndexPos],
499 get_constraint_arg_type(C,IndexPos,Type),
500 ( Type = chr_constants(Key) -> get_chr_constants(Key,Constants)
501 ; Type = chr_enum(Constants) -> true
504 Completeness = complete
506 Constants = Constants0,
507 Completeness = incomplete
509 delete(STs,multi_hash([Index]),STs0),
510 actual_store_types(C,[ground_constants(Index,Constants,Completeness)|STs0]).
512 get_constraint_arg_type(C,Pos,Type) :-
513 get_constraint_type(C,Types),
514 nth1(Pos,Types,Type0),
515 unalias_type(Type0,Type).
517 validate_store_type_assumption(C) \ actual_store_types(C,STs)
519 % chr_pp_flag(experiment,on),
520 memberchk(multi_hash([[Index]]),STs),
521 get_constraint_type(C,Types),
522 nth1(Index,Types,Type),
523 enumerated_atomic_type(Type,Atoms)
525 delete(STs,multi_hash([[Index]]),STs0),
526 actual_store_types(C,[atomic_constants([Index],Atoms,complete)|STs0]).
527 validate_store_type_assumption(C) \ actual_store_types(C,STs)
529 memberchk(multi_hash([[Index]]),STs),
530 get_constraint_arg_type(C,Index,Type),
531 ( Type = chr_enum(Constants) -> true
532 ; Type = chr_constants(Key) -> get_chr_constants(Key,Constants)
535 delete(STs,multi_hash([[Index]]),STs0),
536 actual_store_types(C,[ground_constants([Index],Constants,complete)|STs0]).
537 validate_store_type_assumption(C), actual_store_types(C,STs), assumed_store_type(C,_) % automatic assumption
539 ( /* chr_pp_flag(experiment,on), */ maplist(partial_store,STs) ->
540 Stores = [global_ground|STs]
544 store_type(C,multi_store(Stores)).
545 validate_store_type_assumption(C), actual_store_types(C,STs), store_type(C,_) % user assumption
547 store_type(C,multi_store(STs)).
548 validate_store_type_assumption(C), assumed_store_type(C,_) % no lookups on constraint in debug mode
550 chr_pp_flag(debugable,on)
552 store_type(C,default).
553 validate_store_type_assumption(C), assumed_store_type(C,_) % no lookups on constraint
554 <=> store_type(C,global_ground).
555 validate_store_type_assumption(C)
558 partial_store(ground_constants(_,_,incomplete)).
559 partial_store(atomic_constants(_,_,incomplete)).
561 %%% P A S S I V E %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
562 passive(R,ID) \ passive(R,ID) <=> true.
564 passive(RuleNb,ID) \ is_passive(RuleNb,ID) <=> true.
565 is_passive(_,_) <=> fail.
567 passive(RuleNb,_) \ any_passive_head(RuleNb)
571 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
573 max_occurrence(C,N) \ max_occurrence(C,M)
576 max_occurrence(C,MO), new_occurrence(C,RuleNb,ID,Type) <=>
578 occurrence(C,NO,RuleNb,ID,Type),
579 max_occurrence(C,NO).
580 new_occurrence(C,RuleNb,ID,_) <=>
581 chr_error(internal,'new_occurrence: missing max_occurrence for ~w in rule ~w\n',[C,RuleNb]).
583 max_occurrence(C,MON) \ get_max_occurrence(C,Q)
585 get_max_occurrence(C,Q)
586 <=> chr_error(internal,'get_max_occurrence: missing max occurrence for ~w\n',[C]).
588 occurrence(C,ON,Rule,ID,_) \ get_occurrence(C,ON,QRule,QID)
589 <=> Rule = QRule, ID = QID.
590 get_occurrence(C,O,_,_)
591 <=> chr_error(internal,'get_occurrence: missing occurrence ~w:~w\n',[C,O]).
593 occurrence(C,ON,Rule,ID,_) \ get_occurrence_from_id(QC,QON,Rule,ID)
594 <=> QC = C, QON = ON.
595 get_occurrence_from_id(C,O,_,_)
596 <=> chr_error(internal,'get_occurrence_from_id: missing occurrence ~w:~w\n',[]).
598 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
601 late_allocation_analysis(Cs) :-
602 ( chr_pp_flag(late_allocation,on) ->
603 maplist(late_allocation, Cs)
608 late_allocation(C) :- late_allocation(C,0).
609 late_allocation(C,O) :- allocation_occurrence(C,O), !.
610 late_allocation(C,O) :- NO is O + 1, late_allocation(C,NO).
612 % A L L O C C A T I O N O C C U R R E N C E %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
614 allocation_occurrence(C,0) ==> stored_in_guard_before_next_kept_occurrence(C,0).
616 rule(RuleNb,Rule), occurrence(C,O,RuleNb,Id,Type), allocation_occurrence(C,O) ==>
617 \+ is_passive(RuleNb,Id),
619 ( stored_in_guard_before_next_kept_occurrence(C,O) ->
621 ; Rule = pragma(rule([_|_],_,_,_),_,_,_,_) -> % simpagation rule
623 ; is_least_occurrence(RuleNb) -> % propagation rule
629 stored_in_guard_before_next_kept_occurrence(C,O) :-
630 chr_pp_flag(store_in_guards, on),
632 stored_in_guard_lookahead(C,NO).
634 :- chr_constraint stored_in_guard_lookahead/2.
635 :- chr_option(mode, stored_in_guard_lookahead(+,+)).
637 occurrence(C,O,RuleNb,Id,_), passive(RuleNb,Id) \ stored_in_guard_lookahead(C,O) <=>
638 NO is O + 1, stored_in_guard_lookahead(C,NO).
639 occurrence(C,O,RuleNb,Id,Type) \ stored_in_guard_lookahead(C,O) <=>
640 Type == simplification,
641 ( is_stored_in_guard(C,RuleNb) ->
644 NO is O + 1, stored_in_guard_lookahead(C,NO)
646 stored_in_guard_lookahead(_,_) <=> fail.
649 rule(RuleNb,Rule), occurrence(C,O,RuleNb,ID,_), allocation_occurrence(C,AO)
650 \ least_occurrence(RuleNb,[ID|IDs])
651 <=> AO >= O, \+ may_trigger(C) |
652 least_occurrence(RuleNb,IDs).
653 rule(RuleNb,Rule), passive(RuleNb,ID)
654 \ least_occurrence(RuleNb,[ID|IDs])
655 <=> least_occurrence(RuleNb,IDs).
658 ==> Rule = pragma(rule([],_,_,_),ids([],IDs),_,_,_) |
659 least_occurrence(RuleNb,IDs).
661 least_occurrence(RuleNb,[]) \ is_least_occurrence(RuleNb)
663 is_least_occurrence(_)
666 allocation_occurrence(C,O) \ get_allocation_occurrence(C,Q)
668 get_allocation_occurrence(_,Q)
669 <=> chr_pp_flag(late_allocation,off), Q=0.
670 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
672 rule(RuleNb,Rule) \ get_rule(RuleNb,Q)
677 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
679 %%% C O N S T R A I N T I N D E X %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
681 % Default store constraint index assignment.
683 :- chr_constraint constraint_index/2. % constraint_index(F/A,DefaultStoreAndAttachedIndex)
684 :- chr_option(mode,constraint_index(+,+)).
685 :- chr_option(type_declaration,constraint_index(constraint,int)).
687 :- chr_constraint get_constraint_index/2.
688 :- chr_option(mode,get_constraint_index(+,-)).
689 :- chr_option(type_declaration,get_constraint_index(constraint,int)).
691 :- chr_constraint get_indexed_constraint/2.
692 :- chr_option(mode,get_indexed_constraint(+,-)).
693 :- chr_option(type_declaration,get_indexed_constraint(int,constraint)).
695 :- chr_constraint max_constraint_index/1. % max_constraint_index(MaxDefaultStoreAndAttachedIndex)
696 :- chr_option(mode,max_constraint_index(+)).
697 :- chr_option(type_declaration,max_constraint_index(int)).
699 :- chr_constraint get_max_constraint_index/1.
700 :- chr_option(mode,get_max_constraint_index(-)).
701 :- chr_option(type_declaration,get_max_constraint_index(int)).
703 constraint_index(C,Index) \ get_constraint_index(C,Query)
705 get_constraint_index(C,Query)
708 constraint_index(C,Index) \ get_indexed_constraint(Index,Q)
710 get_indexed_constraint(Index,Q)
713 max_constraint_index(Index) \ get_max_constraint_index(Query)
715 get_max_constraint_index(Query)
718 set_constraint_indices(Constraints) :-
719 set_constraint_indices(Constraints,1).
720 set_constraint_indices([],M) :-
722 max_constraint_index(N).
723 set_constraint_indices([C|Cs],N) :-
724 ( ( chr_pp_flag(debugable, on) ; \+ only_ground_indexed_arguments(C), is_stored(C) ; is_stored(C), get_store_type(C,default)
725 ; get_store_type(C,var_assoc_store(_,_))) ->
726 constraint_index(C,N),
728 set_constraint_indices(Cs,M)
730 set_constraint_indices(Cs,N)
733 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
736 :- chr_constraint identifier_size/1.
737 :- chr_option(mode,identifier_size(+)).
738 :- chr_option(type_declaration,identifier_size(natural)).
740 identifier_size(_) \ identifier_size(_)
744 :- chr_constraint get_identifier_size/1.
745 :- chr_option(mode,get_identifier_size(-)).
746 :- chr_option(type_declaration,get_identifier_size(natural)).
748 identifier_size(Size) \ get_identifier_size(Q)
752 get_identifier_size(Q)
756 :- chr_constraint identifier_index/3.
757 :- chr_option(mode,identifier_index(+,+,+)).
758 :- chr_option(type_declaration,identifier_index(constraint,natural,natural)).
760 identifier_index(C,I,_) \ identifier_index(C,I,_)
764 :- chr_constraint get_identifier_index/3.
765 :- chr_option(mode,get_identifier_index(+,+,-)).
766 :- chr_option(type_declaration,get_identifier_index(constraint,natural,natural)).
768 identifier_index(C,I,II) \ get_identifier_index(C,I,Q)
771 identifier_size(Size), get_identifier_index(C,I,Q)
774 identifier_index(C,I,NSize),
775 identifier_size(NSize),
777 get_identifier_index(C,I,Q)
779 identifier_index(C,I,2),
783 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
784 % Type Indexed Identifier Indexes
786 :- chr_constraint type_indexed_identifier_size/2.
787 :- chr_option(mode,type_indexed_identifier_size(+,+)).
788 :- chr_option(type_declaration,type_indexed_identifier_size(any,natural)).
790 type_indexed_identifier_size(IndexType,_) \ type_indexed_identifier_size(IndexType,_)
794 :- chr_constraint get_type_indexed_identifier_size/2.
795 :- chr_option(mode,get_type_indexed_identifier_size(+,-)).
796 :- chr_option(type_declaration,get_type_indexed_identifier_size(any,natural)).
798 type_indexed_identifier_size(IndexType,Size) \ get_type_indexed_identifier_size(IndexType,Q)
802 get_type_indexed_identifier_size(IndexType,Q)
806 :- chr_constraint type_indexed_identifier_index/4.
807 :- chr_option(mode,type_indexed_identifier_index(+,+,+,+)).
808 :- chr_option(type_declaration,type_indexed_identifier_index(any,constraint,natural,natural)).
810 type_indexed_identifier_index(_,C,I,_) \ type_indexed_identifier_index(_,C,I,_)
814 :- chr_constraint get_type_indexed_identifier_index/4.
815 :- chr_option(mode,get_type_indexed_identifier_index(+,+,+,-)).
816 :- chr_option(type_declaration,get_type_indexed_identifier_index(any,constraint,natural,natural)).
818 type_indexed_identifier_index(IndexType,C,I,II) \ get_type_indexed_identifier_index(IndexType,C,I,Q)
821 type_indexed_identifier_size(IndexType,Size), get_type_indexed_identifier_index(IndexType,C,I,Q)
824 type_indexed_identifier_index(IndexType,C,I,NSize),
825 type_indexed_identifier_size(IndexType,NSize),
827 get_type_indexed_identifier_index(IndexType,C,I,Q)
829 type_indexed_identifier_index(IndexType,C,I,2),
830 type_indexed_identifier_size(IndexType,2),
833 type_indexed_identifier_structure(IndexType,Structure) :-
834 type_indexed_identifier_name(IndexType,type_indexed_identifier_struct,Functor),
835 get_type_indexed_identifier_size(IndexType,Arity),
836 functor(Structure,Functor,Arity).
837 type_indexed_identifier_name(IndexType,Prefix,Name) :-
839 IndexTypeName = IndexType
841 term_to_atom(IndexType,IndexTypeName)
843 atom_concat_list([Prefix,'_',IndexTypeName],Name).
845 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
850 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
854 chr_translate(Declarations,NewDeclarations) :-
855 chr_translate_line_info(Declarations,'bootstrap',NewDeclarations).
857 chr_translate_line_info(Declarations0,File,NewDeclarations) :-
859 restart_after_flattening(Declarations0,Declarations),
861 chr_source_file(File),
862 /* sort out the interesting stuff from the input */
863 partition_clauses(Declarations,Constraints0,Rules0,OtherClauses),
864 chr_compiler_options:sanity_check,
866 dump_code(Declarations),
868 check_declared_constraints(Constraints0),
869 generate_show_constraint(Constraints0,Constraints,Rules0,Rules1),
870 add_constraints(Constraints),
872 generate_never_stored_rules(Constraints,NewRules),
874 append(Rules1,NewRules,Rules),
875 chr_analysis(Rules,Constraints,Declarations),
876 time('constraint code generation',chr_translate:constraints_code(Constraints,ConstraintClauses)),
877 time('validate store assumptions',chr_translate:validate_store_type_assumptions(Constraints)),
878 phase_end(validate_store_type_assumptions),
880 time('store code generation',chr_translate:store_management_preds(Constraints,StoreClauses)), % depends on actual code used
881 insert_declarations(OtherClauses, Clauses0),
882 chr_module_declaration(CHRModuleDeclaration),
883 append([StoreClauses,ConstraintClauses,CHRModuleDeclaration,[end_of_file]],StuffyGeneratedClauses),
884 clean_clauses(StuffyGeneratedClauses,GeneratedClauses),
885 append([Clauses0,GeneratedClauses], NewDeclarations),
886 dump_code(NewDeclarations),
887 !. /* cut choicepoint of restart_after_flattening */
889 chr_analysis(Rules,Constraints,Declarations) :-
890 check_rules(Rules,Constraints),
891 time('type checking',chr_translate:static_type_check),
893 collect_constants(Rules,Constraints,Declarations),
894 add_occurrences(Rules),
895 time('functional dependency',chr_translate:functional_dependency_analysis(Rules)),
896 time('set semantics',chr_translate:set_semantics_rules(Rules)),
897 time('symmetry analysis',chr_translate:symmetry_analysis(Rules)),
898 time('guard simplification',chr_translate:guard_simplification),
899 time('late storage',chr_translate:storage_analysis(Constraints)),
900 time('observation',chr_translate:observation_analysis(Constraints)),
901 time('ai observation',chr_translate:ai_observation_analysis(Constraints)),
902 time('late allocation',chr_translate:late_allocation_analysis(Constraints)),
903 partial_wake_analysis,
904 time('assume constraint stores',chr_translate:assume_constraint_stores(Constraints)),
905 time('default constraint indices',chr_translate:set_constraint_indices(Constraints)),
906 time('check storedness assertions',chr_translate:check_storedness_assertions(Constraints)),
907 time('continuation analysis',chr_translate:continuation_analysis(Constraints)).
909 store_management_preds(Constraints,Clauses) :-
910 generate_attach_detach_a_constraint_all(Constraints,AttachAConstraintClauses),
911 generate_attr_unify_hook(AttrUnifyHookClauses),
912 generate_attach_increment(AttachIncrementClauses),
913 generate_extra_clauses(Constraints,ExtraClauses),
914 generate_insert_delete_constraints(Constraints,DeleteClauses),
915 generate_attach_code(Constraints,StoreClauses),
916 generate_counter_code(CounterClauses),
917 generate_dynamic_type_check_clauses(TypeCheckClauses),
918 append([AttachAConstraintClauses
919 ,AttachIncrementClauses
920 ,AttrUnifyHookClauses
930 insert_declarations(Clauses0, Clauses) :-
931 findall(:- use_module(chr(Module)),(auxiliary_module(Module), is_used_auxiliary_module(Module)),Decls),
932 append(Clauses0, [:- use_module(chr(chr_runtime))|Decls], Clauses).
934 auxiliary_module(chr_hashtable_store).
935 auxiliary_module(chr_integertable_store).
936 auxiliary_module(chr_assoc_store).
938 generate_counter_code(Clauses) :-
939 ( chr_pp_flag(store_counter,on) ->
941 ('$counter_init'(N1) :- nb_setval(N1,0)) ,
942 ('$counter'(N2,X1) :- nb_getval(N2,X1)),
943 ('$counter_inc'(N) :- nb_getval(N,X), Y is X + 1, nb_setval(N,Y)),
944 (:- '$counter_init'('$insert_counter')),
945 (:- '$counter_init'('$delete_counter')),
946 ('$insert_counter_inc' :- '$counter_inc'('$insert_counter')),
947 ('$delete_counter_inc' :- '$counter_inc'('$delete_counter')),
948 ( counter_stats(I,D) :- '$counter'('$insert_counter',I),'$counter'('$delete_counter',D))
954 % for systems with multifile declaration
955 chr_module_declaration(CHRModuleDeclaration) :-
956 get_target_module(Mod),
957 ( Mod \== chr_translate, chr_pp_flag(toplevel_show_store,on) ->
958 CHRModuleDeclaration = [
959 (:- multifile chr:'$chr_module'/1),
960 chr:'$chr_module'(Mod)
963 CHRModuleDeclaration = []
967 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
969 %% Partitioning of clauses into constraint declarations, chr rules and other
972 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
973 %% partition_clauses(+Clauses,-ConstraintDeclarations,-Rules,-OtherClauses) is det.
974 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
975 partition_clauses([],[],[],[]).
976 partition_clauses([Clause|Clauses],ConstraintDeclarations,Rules,OtherClauses) :-
977 ( parse_rule(Clause,Rule) ->
978 ConstraintDeclarations = RestConstraintDeclarations,
979 Rules = [Rule|RestRules],
980 OtherClauses = RestOtherClauses
981 ; is_declaration(Clause,ConstraintDeclaration) ->
982 append(ConstraintDeclaration,RestConstraintDeclarations,ConstraintDeclarations),
984 OtherClauses = RestOtherClauses
985 ; is_module_declaration(Clause,Mod) ->
987 ConstraintDeclarations = RestConstraintDeclarations,
989 OtherClauses = [Clause|RestOtherClauses]
990 ; is_type_definition(Clause) ->
991 ConstraintDeclarations = RestConstraintDeclarations,
993 OtherClauses = RestOtherClauses
994 ; is_chr_declaration(Clause) ->
995 ConstraintDeclarations = RestConstraintDeclarations,
997 OtherClauses = RestOtherClauses
998 ; Clause = (handler _) ->
999 chr_warning(deprecated(Clause),'Backward compatibility: ignoring handler/1 declaration.\n',[]),
1000 ConstraintDeclarations = RestConstraintDeclarations,
1002 OtherClauses = RestOtherClauses
1003 ; Clause = (rules _) ->
1004 chr_warning(deprecated(Clause),'Backward compatibility: ignoring rules/1 declaration.\n',[]),
1005 ConstraintDeclarations = RestConstraintDeclarations,
1007 OtherClauses = RestOtherClauses
1008 ; Clause = option(OptionName,OptionValue) ->
1009 chr_warning(deprecated(Clause),'Instead use `:-chr_option(~w,~w).\'\n',[OptionName,OptionValue]),
1010 handle_option(OptionName,OptionValue),
1011 ConstraintDeclarations = RestConstraintDeclarations,
1013 OtherClauses = RestOtherClauses
1014 ; Clause = (:-chr_option(OptionName,OptionValue)) ->
1015 handle_option(OptionName,OptionValue),
1016 ConstraintDeclarations = RestConstraintDeclarations,
1018 OtherClauses = RestOtherClauses
1019 ; Clause = ('$chr_compiled_with_version'(_)) ->
1020 ConstraintDeclarations = RestConstraintDeclarations,
1022 OtherClauses = ['$chr_compiled_with_version'(3)|RestOtherClauses]
1023 ; ConstraintDeclarations = RestConstraintDeclarations,
1025 OtherClauses = [Clause|RestOtherClauses]
1027 partition_clauses(Clauses,RestConstraintDeclarations,RestRules,RestOtherClauses).
1029 '$chr_compiled_with_version'(2).
1031 is_declaration(D, Constraints) :- %% constraint declaration
1032 ( D = (:- Decl), Decl =.. [F,Cs], F == (chr_constraint) ->
1033 conj2list(Cs,Constraints0)
1036 Decl =.. [constraints,Cs]
1038 D =.. [constraints,Cs]
1040 conj2list(Cs,Constraints0),
1041 chr_warning(deprecated(D),'Instead use :- chr_constraint ~w.\n',[Cs])
1043 extract_type_mode(Constraints0,Constraints).
1045 extract_type_mode([],[]).
1046 extract_type_mode([F/A|R],[F/A|R2]) :- !,extract_type_mode(R,R2).
1047 extract_type_mode([C0|R],[ConstraintSymbol|R2]) :-
1048 ( C0 = C # Annotation ->
1050 extract_annotation(Annotation,F/A)
1055 ConstraintSymbol = F/A,
1057 extract_types_and_modes(Args,ArgTypes,ArgModes),
1058 assert_constraint_type(ConstraintSymbol,ArgTypes),
1059 constraint_mode(ConstraintSymbol,ArgModes),
1060 extract_type_mode(R,R2).
1062 extract_annotation(stored,Symbol) :-
1063 stored_assertion(Symbol).
1064 extract_annotation(default(Goal),Symbol) :-
1065 never_stored_default(Symbol,Goal).
1067 extract_types_and_modes([],[],[]).
1068 extract_types_and_modes([X|R],[T|R2],[M|R3]) :-
1069 extract_type_and_mode(X,T,M),
1070 extract_types_and_modes(R,R2,R3).
1072 extract_type_and_mode(+(T),T,(+)) :- !.
1073 extract_type_and_mode(?(T),T,(?)) :- !.
1074 extract_type_and_mode(-(T),T,(-)) :- !.
1075 extract_type_and_mode((+),any,(+)) :- !.
1076 extract_type_and_mode((?),any,(?)) :- !.
1077 extract_type_and_mode((-),any,(-)) :- !.
1078 extract_type_and_mode(Illegal,_,_) :-
1079 chr_error(syntax(Illegal),'Illegal mode/type declaration.\n\tCorrect syntax is +type, -type or ?type\n\tor +, - or ?.\n',[]).
1081 is_chr_declaration(Declaration) :-
1082 Declaration = (:- chr_declaration Decl),
1083 ( Decl = (Pattern ---> Information) ->
1084 background_info(Pattern,Information)
1085 ; Decl = Information ->
1086 background_info([Information])
1088 is_type_definition(Declaration) :-
1089 is_type_definition(Declaration,Result),
1090 assert_type_definition(Result).
1092 assert_type_definition(typedef(Name,DefList)) :- type_definition(Name,DefList).
1093 assert_type_definition(alias(Alias,Name)) :- type_alias(Alias,Name).
1095 is_type_definition(Declaration,Result) :-
1096 ( Declaration = (:- TDef) ->
1101 TDef =.. [chr_type,TypeDef],
1102 ( TypeDef = (Name ---> Def) ->
1103 tdisj2list(Def,DefList),
1104 Result = typedef(Name,DefList)
1105 ; TypeDef = (Alias == Name) ->
1106 Result = alias(Alias,Name)
1108 Result = typedef(TypeDef,[]),
1109 chr_warning(syntax,'Empty type definition `~w\'.\nAre you sure you want to declare a phantom type?\n',[Declaration])
1112 %% tdisj2list(+Goal,-ListOfGoals) is det.
1114 % no removal of fails, e.g. :- type bool ---> true ; fail.
1115 tdisj2list(Conj,L) :-
1116 tdisj2list(Conj,L,[]).
1118 tdisj2list(Conj,L,T) :-
1120 tdisj2list(G1,L,T1),
1121 tdisj2list(G2,T1,T).
1122 tdisj2list(G,[G | T],T).
1125 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
1126 %% parse_rule(+term,-pragma_rule) is semidet.
1127 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
1128 parse_rule(RI,R) :- %% name @ rule
1129 RI = (Name @ RI2), !,
1130 rule(RI2,yes(Name),R).
1134 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
1135 %% parse_rule(+term,-pragma_rule) is semidet.
1136 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
1138 RI = (RI2 pragma P), !, %% pragmas
1140 Ps = [_] % intercept variable
1144 inc_rule_count(RuleCount),
1145 R = pragma(R1,IDs,Ps,Name,RuleCount),
1146 is_rule(RI2,R1,IDs,R).
1148 inc_rule_count(RuleCount),
1149 R = pragma(R1,IDs,[],Name,RuleCount),
1150 is_rule(RI,R1,IDs,R).
1152 is_rule(RI,R,IDs,RC) :- %% propagation rule
1154 conj2list(H,Head2i),
1155 get_ids(Head2i,IDs2,Head2,RC),
1158 R = rule([],Head2,G,RB)
1160 R = rule([],Head2,true,B)
1162 is_rule(RI,R,IDs,RC) :- %% simplification/simpagation rule
1171 conj2list(H1,Head2i),
1172 conj2list(H2,Head1i),
1173 get_ids(Head2i,IDs2,Head2,0,N,RC),
1174 get_ids(Head1i,IDs1,Head1,N,_,RC),
1175 IDs = ids(IDs1,IDs2)
1176 ; conj2list(H,Head1i),
1178 get_ids(Head1i,IDs1,Head1,RC),
1181 R = rule(Head1,Head2,Guard,Body).
1183 get_ids(Cs,IDs,NCs,RC) :-
1184 get_ids(Cs,IDs,NCs,0,_,RC).
1186 get_ids([],[],[],N,N,_).
1187 get_ids([C|Cs],[N|IDs],[NC|NCs],N,NN,RC) :-
1192 check_direct_pragma(N1,N,RC)
1198 get_ids(Cs,IDs,NCs, M,NN,RC).
1200 check_direct_pragma(passive,Id,PragmaRule) :- !,
1201 PragmaRule = pragma(_,_,_,_,RuleNb),
1203 check_direct_pragma(Abbrev,Id,PragmaRule) :-
1204 ( direct_pragma(FullPragma),
1205 atom_concat(Abbrev,Remainder,FullPragma) ->
1206 chr_warning(problem_pragma(Abbrev,PragmaRule),'completed `~w\' to `~w\'\n',[Abbrev,FullPragma])
1208 chr_warning(unsupported_pragma(Abbrev,PragmaRule),'',[])
1211 direct_pragma(passive).
1213 is_module_declaration((:- module(Mod)),Mod).
1214 is_module_declaration((:- module(Mod,_)),Mod).
1216 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1218 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1220 add_constraints([]).
1221 add_constraints([C|Cs]) :-
1222 max_occurrence(C,0),
1226 constraint_mode(C,Mode),
1227 add_constraints(Cs).
1231 add_rules([Rule|Rules]) :-
1232 Rule = pragma(_,_,_,_,RuleNb),
1236 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1238 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1239 %% Some input verification:
1241 check_declared_constraints(Constraints) :-
1242 tree_set_empty(Acc),
1243 check_declared_constraints(Constraints,Acc).
1245 check_declared_constraints([],_).
1246 check_declared_constraints([C|Cs],Acc) :-
1247 ( tree_set_memberchk(C,Acc) ->
1248 chr_error(syntax(C),'Constraint multiply defined: ~w.\n\tRemove redundant declaration!\n',[C])
1252 tree_set_add(Acc,C,NAcc),
1253 check_declared_constraints(Cs,NAcc).
1255 %% - all constraints in heads are declared constraints
1256 %% - all passive pragmas refer to actual head constraints
1259 check_rules([PragmaRule|Rest],Decls) :-
1260 check_rule(PragmaRule,Decls),
1261 check_rules(Rest,Decls).
1263 check_rule(PragmaRule,Decls) :-
1264 check_rule_indexing(PragmaRule),
1265 check_trivial_propagation_rule(PragmaRule),
1266 PragmaRule = pragma(Rule,_IDs,Pragmas,_Name,_N),
1267 Rule = rule(H1,H2,_,_),
1268 append(H1,H2,HeadConstraints),
1269 check_head_constraints(HeadConstraints,Decls,PragmaRule),
1270 check_pragmas(Pragmas,PragmaRule).
1272 % Make all heads passive in trivial propagation rule
1273 % ... ==> ... | true.
1274 check_trivial_propagation_rule(PragmaRule) :-
1275 PragmaRule = pragma(Rule,IDs,Pragmas,Name,RuleNb),
1276 ( Rule = rule([],_,_,true) ->
1277 chr_warning(weird_program,'Ignoring propagation rule with empty body: ~@.\n\t\n',[format_rule(PragmaRule)]),
1278 set_all_passive(RuleNb)
1283 check_head_constraints([],_,_).
1284 check_head_constraints([Constr|Rest],Decls,PragmaRule) :-
1285 functor(Constr,F,A),
1286 ( memberchk(F/A,Decls) ->
1287 check_head_constraints(Rest,Decls,PragmaRule)
1289 chr_error(syntax(Constr),'Undeclared constraint ~w in head of ~@.\n\tConstraint should be one of ~w.\n', [F/A,format_rule(PragmaRule),Decls])
1292 check_pragmas([],_).
1293 check_pragmas([Pragma|Pragmas],PragmaRule) :-
1294 check_pragma(Pragma,PragmaRule),
1295 check_pragmas(Pragmas,PragmaRule).
1297 check_pragma(Pragma,PragmaRule) :-
1299 chr_error(syntax(Pragma),'Invalid pragma ~w in ~@.\n\tPragma should not be a variable!\n',[Pragma,format_rule(PragmaRule)]).
1300 check_pragma(passive(ID), PragmaRule) :-
1302 PragmaRule = pragma(_,ids(IDs1,IDs2),_,_,RuleNb),
1303 ( memberchk_eq(ID,IDs1) ->
1305 ; memberchk_eq(ID,IDs2) ->
1308 chr_error(syntax(ID),'Invalid identifier ~w in pragma passive in ~@.\n', [ID,format_rule(PragmaRule)])
1312 check_pragma(mpassive(IDs), PragmaRule) :-
1314 PragmaRule = pragma(_,_,_,_,RuleNb),
1315 chr_warning(experimental,'Experimental pragma ~w. Use with care!\n',[mpassive(IDs)]),
1316 maplist(passive(RuleNb),IDs).
1318 check_pragma(Pragma, PragmaRule) :-
1319 Pragma = already_in_heads,
1321 chr_warning(unsupported_pragma(Pragma,PragmaRule),'Termination and correctness may be affected.\n',[]).
1323 check_pragma(Pragma, PragmaRule) :-
1324 Pragma = already_in_head(_),
1326 chr_warning(unsupported_pragma(Pragma,PragmaRule),'Termination and correctness may be affected.\n',[]).
1328 check_pragma(Pragma, PragmaRule) :-
1329 Pragma = no_history,
1331 chr_warning(experimental,'Experimental pragma no_history. Use with care!\n',[]),
1332 PragmaRule = pragma(_,_,_,_,N),
1335 check_pragma(Pragma, PragmaRule) :-
1336 Pragma = history(HistoryName,IDs),
1338 PragmaRule = pragma(_,ids(IDs1,IDs2),_,_,RuleNb),
1339 chr_warning(experimental,'Experimental pragma ~w. Use with care!\n',[Pragma]),
1341 chr_error(syntax(Pragma),'Pragma history only implemented for propagation rules.\n',[])
1342 ; \+ atom(HistoryName) ->
1343 chr_error(syntax(Pragma),'Illegal argument for pragma history: ~w is not an atom (rule number ~w).\n',[HistoryName,RuleNb])
1345 chr_error(syntax(Pragma),'Illegal argument for pragma history: ~w is not a set (rule number ~w).\n',[IDs,RuleNb])
1346 ; check_history_pragma_ids(IDs,IDs1,IDs2) ->
1347 history(RuleNb,HistoryName,IDs)
1349 chr_error(syntax(Pragma),'Invalid identifier(s) in pragma ~w of rule number ~w.\n',[Pragma,RuleNb])
1351 check_pragma(Pragma,PragmaRule) :-
1352 Pragma = line_number(LineNumber),
1354 PragmaRule = pragma(_,_,_,_,RuleNb),
1355 line_number(RuleNb,LineNumber).
1357 check_history_pragma_ids([], _, _).
1358 check_history_pragma_ids([ID|IDs],IDs1,IDs2) :-
1359 ( memberchk_eq(ID,IDs2) ; memberchk_eq(ID,IDs1) ),
1360 check_history_pragma_ids(IDs,IDs1,IDs2).
1362 check_pragma(Pragma,PragmaRule) :-
1363 chr_error(syntax(Pragma),'Unknown pragma ~w in ~@.\n', [Pragma,format_rule(PragmaRule)]).
1365 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1366 %% no_history(+RuleNb) is det.
1367 :- chr_constraint no_history/1.
1368 :- chr_option(mode,no_history(+)).
1369 :- chr_option(type_declaration,no_history(int)).
1371 %% has_no_history(+RuleNb) is semidet.
1372 :- chr_constraint has_no_history/1.
1373 :- chr_option(mode,has_no_history(+)).
1374 :- chr_option(type_declaration,has_no_history(int)).
1376 no_history(RuleNb) \ has_no_history(RuleNb) <=> true.
1377 has_no_history(_) <=> fail.
1379 :- chr_constraint history/3.
1380 :- chr_option(mode,history(+,+,+)).
1381 :- chr_option(type_declaration,history(any,any,list)).
1383 :- chr_constraint named_history/3.
1385 history(RuleNb,_,_), history(RuleNb,_,_) ==>
1386 chr_error(syntax,'Only one pragma history allowed per rule (rule number ~w)\n',[RuleNb]). %'
1388 history(RuleNb1,Name,IDs1), history(RuleNb2,Name,IDs2) ==>
1389 length(IDs1,L1), length(IDs2,L2),
1391 chr_error(syntax,'The history named ~w does not always range over an equal amount of occurrences.\n',[Name])
1393 test_named_history_id_pairs(RuleNb1,IDs1,RuleNb2,IDs2)
1396 test_named_history_id_pairs(_, [], _, []).
1397 test_named_history_id_pairs(RuleNb1, [ID1|IDs1], RuleNb2, [ID2|IDs2]) :-
1398 test_named_history_id_pair(RuleNb1,ID1,RuleNb2,ID2),
1399 test_named_history_id_pairs(RuleNb1,IDs1,RuleNb2,IDs2).
1401 :- chr_constraint test_named_history_id_pair/4.
1402 :- chr_option(mode,test_named_history_id_pair(+,+,+,+)).
1404 occurrence(C,_,RuleNb1,ID1,_), occurrence(C,_,RuleNb2,ID2,_)
1405 \ test_named_history_id_pair(RuleNb1,ID1,RuleNb2,ID2) <=> true.
1406 test_named_history_id_pair(RuleNb1,ID1,RuleNb2,ID2) <=>
1407 chr_error(syntax,'Occurrences of shared history in rules number ~w and ~w do not correspond\n', [RuleNb2,RuleNb1]).
1409 history(RuleNb,Name,IDs) \ named_history(RuleNb,QName,QIDs) <=> QName = Name, QIDs = IDs.
1410 named_history(_,_,_) <=> fail.
1412 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1415 format_rule(PragmaRule) :-
1416 PragmaRule = pragma(_,_,_,MaybeName,RuleNumber),
1417 ( MaybeName = yes(Name) ->
1418 write('rule '), write(Name)
1420 write('rule number '), write(RuleNumber)
1422 get_line_number(RuleNumber,LineNumber),
1427 check_rule_indexing(PragmaRule) :-
1428 PragmaRule = pragma(Rule,_,_,_,_),
1429 Rule = rule(H1,H2,G,_),
1430 term_variables(H1-H2,HeadVars),
1431 remove_anti_monotonic_guards(G,HeadVars,NG),
1432 check_indexing(H1,NG-H2),
1433 check_indexing(H2,NG-H1),
1435 ( chr_pp_flag(term_indexing,on) ->
1436 term_variables(NG,GuardVariables),
1437 append(H1,H2,Heads),
1438 check_specs_indexing(Heads,GuardVariables,Specs)
1443 :- chr_constraint indexing_spec/2.
1444 :- chr_option(mode,indexing_spec(+,+)).
1446 :- chr_constraint get_indexing_spec/2.
1447 :- chr_option(mode,get_indexing_spec(+,-)).
1450 indexing_spec(FA,Spec) \ get_indexing_spec(FA,R) <=> R = Spec.
1451 get_indexing_spec(_,Spec) <=> Spec = [].
1453 indexing_spec(FA,Specs1), indexing_spec(FA,Specs2)
1455 append(Specs1,Specs2,Specs),
1456 indexing_spec(FA,Specs).
1458 remove_anti_monotonic_guards(G,Vars,NG) :-
1460 remove_anti_monotonic_guard_list(GL,Vars,NGL),
1463 remove_anti_monotonic_guard_list([],_,[]).
1464 remove_anti_monotonic_guard_list([G|Gs],Vars,NGs) :-
1465 ( G = var(X), memberchk_eq(X,Vars) ->
1467 % TODO: this is not correct
1468 % ; G = functor(Term,Functor,Arity), % isotonic
1469 % \+ memberchk_eq(Functor,Vars), \+ memberchk_eq(Arity,Vars) ->
1474 remove_anti_monotonic_guard_list(Gs,Vars,RGs).
1476 check_indexing([],_).
1477 check_indexing([Head|Heads],Other) :-
1480 term_variables(Heads-Other,OtherVars),
1481 check_indexing(Args,1,F/A,OtherVars),
1482 check_indexing(Heads,[Head|Other]).
1484 check_indexing([],_,_,_).
1485 check_indexing([Arg|Args],I,FA,OtherVars) :-
1486 ( is_indexed_argument(FA,I) ->
1489 indexed_argument(FA,I)
1491 term_variables(Args,ArgsVars),
1492 append(ArgsVars,OtherVars,RestVars),
1493 ( memberchk_eq(Arg,RestVars) ->
1494 indexed_argument(FA,I)
1500 term_variables(Arg,NVars),
1501 append(NVars,OtherVars,NOtherVars),
1502 check_indexing(Args,J,FA,NOtherVars).
1504 check_specs_indexing([],_,[]).
1505 check_specs_indexing([Head|Heads],Variables,Specs) :-
1506 Specs = [Spec|RSpecs],
1507 term_variables(Heads,OtherVariables,Variables),
1508 check_spec_indexing(Head,OtherVariables,Spec),
1509 term_variables(Head,NVariables,Variables),
1510 check_specs_indexing(Heads,NVariables,RSpecs).
1512 check_spec_indexing(Head,OtherVariables,Spec) :-
1514 Spec = spec(F,A,ArgSpecs),
1516 check_args_spec_indexing(Args,1,OtherVariables,ArgSpecs),
1517 indexing_spec(F/A,[ArgSpecs]).
1519 check_args_spec_indexing([],_,_,[]).
1520 check_args_spec_indexing([Arg|Args],I,OtherVariables,ArgSpecs) :-
1521 term_variables(Args,Variables,OtherVariables),
1522 ( check_arg_spec_indexing(Arg,I,Variables,ArgSpec) ->
1523 ArgSpecs = [ArgSpec|RArgSpecs]
1525 ArgSpecs = RArgSpecs
1528 term_variables(Arg,NOtherVariables,OtherVariables),
1529 check_args_spec_indexing(Args,J,NOtherVariables,RArgSpecs).
1531 check_arg_spec_indexing(Arg,I,Variables,ArgSpec) :-
1533 memberchk_eq(Arg,Variables),
1534 ArgSpec = specinfo(I,any,[])
1537 ArgSpec = specinfo(I,F/A,[ArgSpecs]),
1539 check_args_spec_indexing(Args,1,Variables,ArgSpecs)
1542 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1544 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1547 add_occurrences([]).
1548 add_occurrences([Rule|Rules]) :-
1549 Rule = pragma(rule(H1,H2,_,_),ids(IDs1,IDs2),_,_,Nb),
1550 add_occurrences(H1,IDs1,simplification,Nb),
1551 add_occurrences(H2,IDs2,propagation,Nb),
1552 add_occurrences(Rules).
1554 add_occurrences([],[],_,_).
1555 add_occurrences([H|Hs],[ID|IDs],Type,RuleNb) :-
1558 new_occurrence(FA,RuleNb,ID,Type),
1559 add_occurrences(Hs,IDs,Type,RuleNb).
1561 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1563 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1564 % Observation Analysis
1574 :- chr_constraint observation_analysis/1.
1575 :- chr_option(mode, observation_analysis(+)).
1577 observation_analysis(Cs), rule(RuleNb,PragmaRule) # Id ==>
1578 PragmaRule = pragma(rule(_,_,Guard,Body),_,_,_,_),
1579 ( chr_pp_flag(store_in_guards, on) ->
1580 observation_analysis(RuleNb, Guard, guard, Cs)
1584 observation_analysis(RuleNb, Body, body, Cs)
1587 observation_analysis(_) <=> true.
1589 observation_analysis(RuleNb, Term, GB, Cs) :-
1590 ( all_spawned(RuleNb,GB) ->
1593 spawns_all(RuleNb,GB)
1601 observation_analysis(RuleNb,T1,GB,Cs),
1602 observation_analysis(RuleNb,T2,GB,Cs)
1604 observation_analysis(RuleNb,T1,GB,Cs),
1605 observation_analysis(RuleNb,T2,GB,Cs)
1606 ; Term = (T1->T2) ->
1607 observation_analysis(RuleNb,T1,GB,Cs),
1608 observation_analysis(RuleNb,T2,GB,Cs)
1610 observation_analysis(RuleNb,T,GB,Cs)
1611 ; functor(Term,F,A), memberchk(F/A,Cs) ->
1612 spawns(RuleNb,GB,F/A)
1614 spawns_all_triggers(RuleNb,GB)
1615 ; Term = (_ is _) ->
1616 spawns_all_triggers(RuleNb,GB)
1617 ; builtin_binds_b(Term,Vars) ->
1621 spawns_all_triggers(RuleNb,GB)
1624 spawns_all(RuleNb,GB)
1627 :- chr_constraint spawns/3.
1628 :- chr_option(mode, spawns(+,+,+)).
1629 :- chr_type spawns_type ---> guard ; body.
1630 :- chr_option(type_declaration,spawns(any,spawns_type,any)).
1632 :- chr_constraint spawns_all/2, spawns_all_triggers/2.
1633 :- chr_option(mode, spawns_all(+,+)).
1634 :- chr_option(type_declaration,spawns_all(any,spawns_type)).
1635 :- chr_option(mode, spawns_all_triggers(+,+)).
1636 :- chr_option(type_declaration,spawns_all_triggers(any,spawns_type)).
1638 spawns_all(RuleNb,GB) \ spawns_all(RuleNb,GB) <=> true.
1639 spawns_all(RuleNb,guard) \ spawns_all(RuleNb,body) <=> true.
1640 spawns_all_triggers(RuleNb,GB) \ spawns_all_triggers(RuleNb,GB) <=> true.
1641 spawns_all_triggers(RuleNb,guard) \ spawns_all_triggers(RuleNb,body) <=> true.
1642 spawns(RuleNb,GB,C) \ spawns(RuleNb,GB,C) <=> true.
1643 spawns(RuleNb,guard,C) \ spawns(RuleNb,body,C) <=> true.
1645 spawns_all(RuleNb,GB) \ spawns(RuleNb,GB,_) <=> true.
1646 spawns_all(RuleNb,guard) \ spawns(RuleNb,body,_) <=> true.
1647 spawns_all(RuleNb,GB) \ spawns_all_triggers(RuleNb,GB) <=> true.
1648 spawns_all(RuleNb,guard) \ spawns_all_triggers(RuleNb,body) <=> true.
1650 spawns_all_triggers(RuleNb,GB) \ spawns(RuleNb,GB,C) <=> may_trigger(C) | true.
1651 spawns_all_triggers(RuleNb,guard) \ spawns(RuleNb,body,C) <=> may_trigger(C) | true.
1653 spawns_all(RuleNb2,_), occurrence(C1,_,RuleNb2,O,_)#Id
1655 spawns(RuleNb1,GB,C1)
1657 \+ is_passive(RuleNb2,O)
1659 spawns_all(RuleNb1,GB)
1663 occurrence(C1,_,RuleNb2,O,_)#Id, spawns_all(RuleNb2,_)
1665 \+(\+ spawns_all_triggers_implies_spawns_all), % in the hope it schedules this guard early...
1666 \+ is_passive(RuleNb2,O), may_trigger(C1)
1668 spawns_all_triggers_implies_spawns_all
1672 :- chr_constraint spawns_all_triggers_implies_spawns_all/0.
1673 spawns_all_triggers_implies_spawns_all, spawns_all_triggers_implies_spawns_all <=> fail.
1674 spawns_all_triggers_implies_spawns_all \
1675 spawns_all_triggers(RuleNb,GB) <=> spawns_all(RuleNb,GB).
1677 spawns_all_triggers(RuleNb2,_), occurrence(C1,_,RuleNb2,O,_)#Id
1679 spawns(RuleNb1,GB,C1)
1682 \+ is_passive(RuleNb2,O)
1684 spawns_all_triggers(RuleNb1,GB)
1688 spawns_all_triggers(RuleNb2,_), occurrence(C1,_,RuleNb2,O,_)#Id,
1689 spawns(RuleNb1,GB,C1)
1692 \+ is_passive(RuleNb2,O)
1694 spawns_all_triggers(RuleNb1,GB)
1698 % a bit dangerous this rule: could start propagating too much too soon?
1699 spawns(RuleNb2,_,C2), occurrence(C1,_,RuleNb2,O,_)#Id,
1700 spawns(RuleNb1,GB,C1)
1702 RuleNb1 \== RuleNb2, C1 \== C2,
1703 \+ is_passive(RuleNb2,O)
1705 spawns(RuleNb1,GB,C2)
1709 spawns(RuleNb2,_,C2), occurrence(C1,_,RuleNb2,O,_)#Id,
1710 spawns_all_triggers(RuleNb1,GB)
1712 \+ is_passive(RuleNb2,O), may_trigger(C1), \+ may_trigger(C2)
1714 spawns(RuleNb1,GB,C2)
1719 :- chr_constraint all_spawned/2.
1720 :- chr_option(mode, all_spawned(+,+)).
1721 spawns_all(RuleNb,guard) \ all_spawned(RuleNb,_) <=> true.
1722 spawns_all(RuleNb,GB) \ all_spawned(RuleNb,GB) <=> true.
1723 all_spawned(RuleNb,GB) <=> fail.
1726 % Overview of the supported queries:
1727 % is_observed(+functor/artiy, +occurrence_number, +(guard;body))
1728 % only succeeds if the occurrence is observed by the
1729 % guard resp. body (depending on the last argument) of its rule
1730 % is_observed(+functor/artiy, +occurrence_number, -)
1731 % succeeds if the occurrence is observed by either the guard or
1732 % the body of its rule
1733 % NOTE: the last argument is NOT bound by this query
1735 % do_is_observed(+functor/artiy,+rule_number,+(guard;body))
1736 % succeeds if the given constraint is observed by the given
1738 % do_is_observed(+functor/artiy,+rule_number)
1739 % succeeds if the given constraint is observed by the given
1740 % rule (either its guard or its body)
1745 ai_is_observed(C,O).
1747 is_stored_in_guard(C,RuleNb) :-
1748 chr_pp_flag(store_in_guards, on),
1749 do_is_observed(C,RuleNb,guard).
1751 :- chr_constraint is_observed/3.
1752 :- chr_option(mode, is_observed(+,+,+)).
1753 occurrence(C,O,RuleNb,_,_) \ is_observed(C,O,GB) <=> do_is_observed(C,RuleNb,GB).
1754 is_observed(_,_,_) <=> fail. % this will not happen in practice
1757 :- chr_constraint do_is_observed/3.
1758 :- chr_option(mode, do_is_observed(+,+,?)).
1759 :- chr_constraint do_is_observed/2.
1760 :- chr_option(mode, do_is_observed(+,+)).
1762 do_is_observed(C,RuleNb,GB) <=> var(GB) | do_is_observed(C,RuleNb).
1765 % a constraint C is observed if the GB of the rule it occurs in spawns all,
1766 % and some non-passive occurrence of some (possibly other) constraint
1767 % exists in a rule (could be same rule) with at least one occurrence of C
1769 spawns_all(RuleNb,GB),
1770 occurrence(_,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1772 do_is_observed(C,RuleNb,GB)
1774 \+ is_passive(RuleNb2,O)
1778 spawns_all(RuleNb,_),
1779 occurrence(_,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1781 do_is_observed(C,RuleNb)
1783 \+ is_passive(RuleNb2,O)
1788 % a constraint C is observed if the GB of the rule it occurs in spawns a
1789 % constraint C2 that occurs non-passively in a rule (possibly the same rule)
1790 % as an occurrence of C
1792 spawns(RuleNb,GB,C2),
1793 occurrence(C2,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1795 do_is_observed(C,RuleNb,GB)
1797 \+ is_passive(RuleNb2,O)
1801 spawns(RuleNb,_,C2),
1802 occurrence(C2,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1804 do_is_observed(C,RuleNb)
1806 \+ is_passive(RuleNb2,O)
1810 % (3) spawns_all_triggers
1811 % a constraint C is observed if the GB of the rule it occurs in spawns all triggers
1812 % and some non-passive occurrence of some (possibly other) constraint that may trigger
1813 % exists in a rule (could be same rule) with at least one occurrence of C
1815 spawns_all_triggers(RuleNb,GB),
1816 occurrence(C2,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1818 do_is_observed(C,RuleNb,GB)
1820 \+ is_passive(RuleNb2,O), may_trigger(C2)
1824 spawns_all_triggers(RuleNb,_),
1825 occurrence(C2,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1827 do_is_observed(C,RuleNb)
1829 \+ is_passive(RuleNb2,O), may_trigger(C2)
1833 % (4) conservativeness
1834 do_is_observed(_,_,_) <=> chr_pp_flag(observation_analysis,off).
1835 do_is_observed(_,_) <=> chr_pp_flag(observation_analysis,off).
1838 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1840 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1843 %% Generated predicates
1844 %% attach_$CONSTRAINT
1846 %% detach_$CONSTRAINT
1849 %% attach_$CONSTRAINT
1850 generate_attach_detach_a_constraint_all([],[]).
1851 generate_attach_detach_a_constraint_all([Constraint|Constraints],Clauses) :-
1852 ( ( chr_pp_flag(debugable,on) ; is_stored(Constraint), \+ only_ground_indexed_arguments(Constraint), \+ get_store_type(Constraint,var_assoc_store(_,_)) ) ->
1853 generate_attach_a_constraint(Constraint,Clauses1),
1854 generate_detach_a_constraint(Constraint,Clauses2)
1859 generate_attach_detach_a_constraint_all(Constraints,Clauses3),
1860 append([Clauses1,Clauses2,Clauses3],Clauses).
1862 generate_attach_a_constraint(Constraint,[Clause1,Clause2]) :-
1863 generate_attach_a_constraint_nil(Constraint,Clause1),
1864 generate_attach_a_constraint_cons(Constraint,Clause2).
1866 attach_constraint_atom(FA,Vars,Susp,Atom) :-
1867 make_name('attach_',FA,Name),
1868 Atom =.. [Name,Vars,Susp].
1870 generate_attach_a_constraint_nil(FA,Clause) :-
1871 Clause = (Head :- true),
1872 attach_constraint_atom(FA,[],_,Head).
1874 generate_attach_a_constraint_cons(FA,Clause) :-
1875 Clause = (Head :- Body),
1876 attach_constraint_atom(FA,[Var|Vars],Susp,Head),
1877 attach_constraint_atom(FA,Vars,Susp,RecursiveCall),
1878 Body = ( AttachBody, Subscribe, RecursiveCall ),
1879 get_max_constraint_index(N),
1881 generate_attach_body_1(FA,Var,Susp,AttachBody)
1883 generate_attach_body_n(FA,Var,Susp,AttachBody)
1885 % SWI-Prolog specific code
1886 chr_pp_flag(solver_events,NMod),
1888 Args = [[Var|_],Susp],
1889 get_target_module(Mod),
1890 use_auxiliary_predicate(run_suspensions),
1891 Subscribe = clp_events:subscribe(Var,NMod,Mod,Mod:'$run_suspensions'([Susp]))
1896 generate_attach_body_1(FA,Var,Susp,Body) :-
1897 get_target_module(Mod),
1899 ( get_attr(Var, Mod, Susps) ->
1900 put_attr(Var, Mod, [Susp|Susps])
1902 put_attr(Var, Mod, [Susp])
1905 generate_attach_body_n(F/A,Var,Susp,Body) :-
1906 get_constraint_index(F/A,Position),
1907 get_max_constraint_index(Total),
1908 get_target_module(Mod),
1909 add_attr(Total,Susp,Position,TAttr,AddGoal,NTAttr),
1910 singleton_attr(Total,Susp,Position,NewAttr3),
1912 ( get_attr(Var,Mod,TAttr) ->
1914 put_attr(Var,Mod,NTAttr)
1916 put_attr(Var,Mod,NewAttr3)
1919 %% detach_$CONSTRAINT
1920 generate_detach_a_constraint(Constraint,[Clause1,Clause2]) :-
1921 generate_detach_a_constraint_nil(Constraint,Clause1),
1922 generate_detach_a_constraint_cons(Constraint,Clause2).
1924 detach_constraint_atom(FA,Vars,Susp,Atom) :-
1925 make_name('detach_',FA,Name),
1926 Atom =.. [Name,Vars,Susp].
1928 generate_detach_a_constraint_nil(FA,Clause) :-
1929 Clause = ( Head :- true),
1930 detach_constraint_atom(FA,[],_,Head).
1932 generate_detach_a_constraint_cons(FA,Clause) :-
1933 Clause = (Head :- Body),
1934 detach_constraint_atom(FA,[Var|Vars],Susp,Head),
1935 detach_constraint_atom(FA,Vars,Susp,RecursiveCall),
1936 Body = ( DetachBody, RecursiveCall ),
1937 get_max_constraint_index(N),
1939 generate_detach_body_1(FA,Var,Susp,DetachBody)
1941 generate_detach_body_n(FA,Var,Susp,DetachBody)
1944 generate_detach_body_1(FA,Var,Susp,Body) :-
1945 get_target_module(Mod),
1947 ( get_attr(Var,Mod,Susps) ->
1948 'chr sbag_del_element'(Susps,Susp,NewSusps),
1952 put_attr(Var,Mod,NewSusps)
1958 generate_detach_body_n(F/A,Var,Susp,Body) :-
1959 get_constraint_index(F/A,Position),
1960 get_max_constraint_index(Total),
1961 rem_attr(Total,Var,Susp,Position,TAttr,RemGoal),
1962 get_target_module(Mod),
1964 ( get_attr(Var,Mod,TAttr) ->
1970 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1971 %-------------------------------------------------------------------------------
1972 %% generate_indexed_variables_body(+ConstraintSymbol,+ArgList,-Body,-VarList) is det.
1973 :- chr_constraint generate_indexed_variables_body/4.
1974 :- chr_option(mode,generate_indexed_variables_body(+,?,+,?)).
1975 :- chr_option(type_declaration,generate_indexed_variables_body(constraint,any,any,any)).
1976 %-------------------------------------------------------------------------------
1977 constraint_mode(F/A,ArgModes) \ generate_indexed_variables_body(F/A,Args,Body,Vars) <=>
1978 get_indexing_spec(F/A,Specs),
1979 ( chr_pp_flag(term_indexing,on) ->
1980 spectermvars(Specs,Args,F,A,Body,Vars)
1982 get_constraint_type_det(F/A,ArgTypes),
1983 create_indexed_variables_body(Args,ArgModes,ArgTypes,Vars,1,F/A,MaybeBody,N),
1984 ( MaybeBody == empty ->
1991 Term =.. [term|Args]
1993 Body = term_variables(Term,Vars)
1998 generate_indexed_variables_body(FA,_,_,_) <=>
1999 chr_error(internal,'generate_indexed_variables_body: missing mode info for ~w.\n',[FA]).
2000 %===============================================================================
2002 create_indexed_variables_body([],[],[],_,_,_,empty,0).
2003 create_indexed_variables_body([V|Vs],[Mode|Modes],[Type|Types],Vars,I,FA,Body,N) :-
2005 create_indexed_variables_body(Vs,Modes,Types,Tail,J,FA,RBody,M),
2007 is_indexed_argument(FA,I) ->
2008 ( atomic_type(Type) ->
2019 Continuation = true, Tail = []
2021 Continuation = RBody
2025 Body = term_variables(V,Vars)
2027 Body = (term_variables(V,Vars,Tail),RBody)
2031 ; Mode == (-), is_indexed_argument(FA,I) ->
2035 Body = (Vars = [V|Tail],RBody)
2043 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2045 spectermvars(Specs,Args,F,A,Goal,Vars) :-
2046 spectermvars(Args,1,Specs,F,A,Vars,[],Goal).
2048 spectermvars([],B,_,_,A,L,L,true) :- B > A, !.
2049 spectermvars([Arg|Args],I,Specs,F,A,L,T,Goal) :-
2050 Goal = (ArgGoal,RGoal),
2051 argspecs(Specs,I,TempArgSpecs,RSpecs),
2052 merge_argspecs(TempArgSpecs,ArgSpecs),
2053 arggoal(ArgSpecs,Arg,ArgGoal,L,L1),
2055 spectermvars(Args,J,RSpecs,F,A,L1,T,RGoal).
2057 argspecs([],_,[],[]).
2058 argspecs([[]|Rest],I,ArgSpecs,RestSpecs) :-
2059 argspecs(Rest,I,ArgSpecs,RestSpecs).
2060 argspecs([[specinfo(J,Spec,Args)|Specs]|Rest],I,ArgSpecs,RestSpecs) :-
2062 ArgSpecs = [specinfo(J,Spec,Args)|RArgSpecs],
2064 RRestSpecs = RestSpecs
2066 RestSpecs = [Specs|RRestSpecs]
2069 ArgSpecs = RArgSpecs,
2070 RestSpecs = [[specinfo(J,Spec,Args)|Specs]|RRestSpecs]
2072 argspecs(Rest,I,RArgSpecs,RRestSpecs).
2074 merge_argspecs(In,Out) :-
2076 merge_argspecs_(Sorted,Out).
2078 merge_argspecs_([],[]).
2079 merge_argspecs_([X],R) :- !, R = [X].
2080 merge_argspecs_([specinfo(I,F1,A1),specinfo(I,F2,A2)|Rest],R) :-
2081 ( (F1 == any ; F2 == any) ->
2082 merge_argspecs_([specinfo(I,any,[])|Rest],R)
2085 merge_argspecs_([specinfo(I,F1,A)|Rest],R)
2087 R = [specinfo(I,F1,A1)|RR],
2088 merge_argspecs_([specinfo(I,F2,A2)|Rest],RR)
2091 arggoal(List,Arg,Goal,L,T) :-
2095 ; List = [specinfo(_,any,_)] ->
2096 Goal = term_variables(Arg,L,T)
2104 arggoal_cases(List,Arg,L,T,Cases)
2107 arggoal_cases([],_,L,T,L=T).
2108 arggoal_cases([specinfo(_,FA,ArgSpecs)|Rest],Arg,L,T,Cases) :-
2111 ; ArgSpecs == [[]] ->
2114 Cases = (Case ; RCases),
2117 Case = (Arg = Term -> ArgsGoal),
2118 spectermvars(Args,1,ArgSpecs,F,A,L,T,ArgsGoal)
2120 arggoal_cases(Rest,Arg,L,T,RCases).
2121 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2123 generate_extra_clauses(Constraints,List) :-
2124 generate_activate_clauses(Constraints,List,Tail0),
2125 generate_remove_clauses(Constraints,Tail0,Tail1),
2126 generate_allocate_clauses(Constraints,Tail1,Tail2),
2127 generate_insert_constraint_internal_clauses(Constraints,Tail2,Tail3),
2128 generate_novel_production(Tail3,Tail4),
2129 generate_extend_history(Tail4,Tail5),
2130 generate_run_suspensions_clauses(Constraints,Tail5,Tail6),
2131 generate_empty_named_history_initialisations(Tail6,Tail7),
2134 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2135 % remove_constraint_internal/[1/3]
2137 generate_remove_clauses([],List,List).
2138 generate_remove_clauses([C|Cs],List,Tail) :-
2139 generate_remove_clause(C,List,List1),
2140 generate_remove_clauses(Cs,List1,Tail).
2142 remove_constraint_goal(Constraint,Susp,Agenda,DeleteNo,DeleteYes,Role,Goal) :-
2143 uses_state(Constraint,removed),
2144 ( chr_pp_flag(inline_insertremove,off) ->
2145 use_auxiliary_predicate(remove_constraint_internal,Constraint),
2146 Goal = ( DeleteGoal, ( Delete == yes -> DeleteYes ; DeleteNo) ),
2147 remove_constraint_atom(Constraint,Susp,Agenda,Delete,DeleteGoal)
2149 delay_phase_end(validate_store_type_assumptions,
2150 generate_remove_body(Constraint,Susp,Agenda,DeleteNo,DeleteYes,Role,Goal)
2154 remove_constraint_atom(Constraint,Susp,Agenda,Delete,Goal) :-
2155 make_name('$remove_constraint_internal_',Constraint,Name),
2156 ( chr_pp_flag(debugable,off), ( only_ground_indexed_arguments(Constraint) ; get_store_type(Constraint,var_assoc_store(_,_)) ) ->
2157 Goal =.. [Name, Susp,Delete]
2159 Goal =.. [Name,Susp,Agenda,Delete]
2162 generate_remove_clause(Constraint,List,Tail) :-
2163 ( is_used_auxiliary_predicate(remove_constraint_internal,Constraint) ->
2164 List = [RemoveClause|Tail],
2165 RemoveClause = (Head :- RemoveBody),
2166 remove_constraint_atom(Constraint,Susp,Agenda,Delete,Head),
2167 generate_remove_body(Constraint,Susp,Agenda,Delete = no,Delete = yes,active,RemoveBody)
2172 generate_remove_body(Constraint,Susp,Agenda,DeleteNo,DeleteYes,Role,RemoveBody) :-
2173 ( chr_pp_flag(debugable,off), ( only_ground_indexed_arguments(Constraint) ; get_store_type(Constraint,var_assoc_store(_,_))) ->
2175 get_update_suspension_field(Constraint,Susp,state,State,removed,GetState,GetStateValue0,UpdateState),
2176 if_used_state(Constraint,not_stored_yet,GetStateValue0,true,GetStateValue),
2177 if_used_state(Constraint,not_stored_yet,(State == not_stored_yet -> DeleteNo ; DeleteYes),DeleteYes,MaybeDelete)
2178 ; Role == partner ->
2179 get_update_suspension_field(Constraint,Susp,state,State,removed,GetState,_,UpdateState),
2180 GetStateValue = true,
2181 MaybeDelete = DeleteYes
2191 static_suspension_term(Constraint,Susp2),
2192 get_static_suspension_term_field(arguments,Constraint,Susp2,Args),
2193 generate_indexed_variables_body(Constraint,Args,IndexedVariablesBody,Agenda),
2194 ( chr_pp_flag(debugable,on) ->
2195 Constraint = Functor / _,
2196 get_static_suspension_term_field(functor,Constraint,Susp2,Functor)
2201 get_update_static_suspension_field(Constraint,Susp,Susp2,state,State,removed,GetStateValue0,UpdateState),
2202 if_used_state(Constraint,not_stored_yet,GetStateValue0,true,GetStateValue),
2203 if_used_state(Constraint,not_stored_yet,(State == not_stored_yet -> Agenda = [], DeleteNo ; IndexedVariablesBody, DeleteYes),(IndexedVariablesBody,DeleteYes),MaybeDelete)
2204 ; Role == partner ->
2205 get_update_static_suspension_field(Constraint,Susp,Susp2,state,State,removed,_,UpdateState),
2206 GetStateValue = true,
2207 MaybeDelete = (IndexedVariablesBody, DeleteYes)
2218 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2219 % activate_constraint/4
2221 generate_activate_clauses([],List,List).
2222 generate_activate_clauses([C|Cs],List,Tail) :-
2223 generate_activate_clause(C,List,List1),
2224 generate_activate_clauses(Cs,List1,Tail).
2226 activate_constraint_goal(Constraint,StoreAction,Vars,Susp,Generation,Goal) :-
2227 ( chr_pp_flag(inline_insertremove,off) ->
2228 use_auxiliary_predicate(activate_constraint,Constraint),
2229 Goal = ( ActivateGoal , (Store == yes -> StoreAction ; true) ),
2230 activate_constraint_atom(Constraint,Store,Vars,Susp,Generation,ActivateGoal)
2232 delay_phase_end(validate_store_type_assumptions,
2233 activate_constraint_body(Constraint,StoreAction,true,Vars,Susp,Generation,Goal)
2237 activate_constraint_atom(Constraint,Store,Vars,Susp,Generation,Goal) :-
2238 make_name('$activate_constraint_',Constraint,Name),
2239 ( chr_pp_flag(debugable,off), only_ground_indexed_arguments(Constraint) ->
2240 Goal =.. [Name,Store, Susp]
2241 ; chr_pp_flag(debugable,off), may_trigger(Constraint), get_store_type(Constraint,var_assoc_store(_,_)) ->
2242 Goal =.. [Name,Store, Susp, Generation]
2243 ; chr_pp_flag(debugable,off), may_trigger(Constraint), get_store_type(Constraint,var_assoc_store(_,_)) ->
2244 Goal =.. [Name,Store, Vars, Susp, Generation]
2246 Goal =.. [Name,Store, Vars, Susp]
2249 generate_activate_clause(Constraint,List,Tail) :-
2250 ( is_used_auxiliary_predicate(activate_constraint,Constraint) ->
2251 List = [Clause|Tail],
2252 Clause = (Head :- Body),
2253 activate_constraint_atom(Constraint,Store,Vars,Susp,Generation,Head),
2254 activate_constraint_body(Constraint,Store = yes, Store = no,Vars,Susp,Generation,Body)
2259 activate_constraint_body(Constraint,StoreYes,StoreNo,Vars,Susp,Generation,Body) :-
2260 ( chr_pp_flag(debugable,off), may_trigger(Constraint), uses_field(Constraint,generation) ->
2261 get_update_suspension_field(Constraint,Susp,generation,Gen,Generation,GetGeneration,GetGenerationValue,UpdateGeneration),
2262 GenerationHandling = (GetGeneration, GetGenerationValue, Generation is Gen+1, UpdateGeneration)
2264 GenerationHandling = true
2266 get_update_suspension_field(Constraint,Susp,state,State,active,GetState,GetStateValue0,UpdateState),
2267 if_used_state(Constraint,not_stored_yet,GetStateValue0,true,GetStateValue),
2268 ( chr_pp_flag(debugable,off), ( only_ground_indexed_arguments(Constraint) ; get_store_type(Constraint,var_assoc_store(_,_))) ->
2269 if_used_state(Constraint,not_stored_yet,( State == not_stored_yet -> StoreYes ; StoreNo ),StoreNo,StoreVarsGoal)
2271 get_dynamic_suspension_term_field(arguments,Constraint,Susp,Arguments,ArgumentsGoal),
2272 generate_indexed_variables_body(Constraint,Arguments,IndexedVariablesBody,Vars),
2273 ( chr_pp_flag(guard_locks,off) ->
2276 NoneLocked = 'chr none_locked'( Vars)
2278 if_used_state(Constraint,not_stored_yet,
2279 ( State == not_stored_yet ->
2281 IndexedVariablesBody,
2288 % (Vars = [],StoreNo),StoreVarsGoal)
2289 StoreNo,StoreVarsGoal)
2299 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2300 % allocate_constraint/4
2302 generate_allocate_clauses([],List,List).
2303 generate_allocate_clauses([C|Cs],List,Tail) :-
2304 generate_allocate_clause(C,List,List1),
2305 generate_allocate_clauses(Cs,List1,Tail).
2307 allocate_constraint_goal(Constraint,Susp,Args,Goal) :-
2308 uses_state(Constraint,not_stored_yet),
2309 ( chr_pp_flag(inline_insertremove,off) ->
2310 use_auxiliary_predicate(allocate_constraint,Constraint),
2311 allocate_constraint_atom(Constraint,Susp,Args,Goal)
2313 Goal = (Susp = Suspension, Goal0),
2314 delay_phase_end(validate_store_type_assumptions,
2315 allocate_constraint_body(Constraint,Suspension,Args,Goal0)
2319 allocate_constraint_atom(Constraint, Susp, Args,Goal) :-
2320 make_name('$allocate_constraint_',Constraint,Name),
2321 Goal =.. [Name,Susp|Args].
2323 generate_allocate_clause(Constraint,List,Tail) :-
2324 ( is_used_auxiliary_predicate(allocate_constraint,Constraint) ->
2325 List = [Clause|Tail],
2326 Clause = (Head :- Body),
2329 allocate_constraint_atom(Constraint,Susp,Args,Head),
2330 allocate_constraint_body(Constraint,Susp,Args,Body)
2335 allocate_constraint_body(Constraint,Susp,Args,Body) :-
2336 static_suspension_term(Constraint,Suspension),
2337 get_static_suspension_term_field(arguments,Constraint,Suspension,Args),
2338 ( chr_pp_flag(debugable,on) ->
2339 Constraint = Functor / _,
2340 get_static_suspension_term_field(functor,Constraint,Suspension,Functor)
2344 ( chr_pp_flag(debugable,on) ->
2345 ( may_trigger(Constraint) ->
2346 append(Args,[Susp],VarsSusp),
2347 build_head(F,A,[0],VarsSusp, ContinuationGoal),
2348 get_target_module(Mod),
2349 Continuation = Mod : ContinuationGoal
2353 Init = (Susp = Suspension),
2354 create_static_suspension_field(Constraint,Suspension,continuation,Continuation,CreateContinuation),
2355 create_static_suspension_field(Constraint,Suspension,generation,0,CreateGeneration)
2356 ; may_trigger(Constraint), uses_field(Constraint,generation) ->
2357 create_static_suspension_field(Constraint,Suspension,generation,0,CreateGeneration),
2358 Susp = Suspension, Init = true, CreateContinuation = true
2360 CreateGeneration = true, Susp = Suspension, Init = true, CreateContinuation = true
2362 ( uses_history(Constraint) ->
2363 create_static_suspension_field(Constraint,Suspension,history,t,CreateHistory)
2365 CreateHistory = true
2367 create_static_suspension_field(Constraint,Suspension,state,not_stored_yet,CreateState),
2368 ( has_suspension_field(Constraint,id) ->
2369 get_static_suspension_term_field(id,Constraint,Suspension,Id),
2384 gen_id(Id,'chr gen_id'(Id)).
2385 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2386 % insert_constraint_internal
2388 generate_insert_constraint_internal_clauses([],List,List).
2389 generate_insert_constraint_internal_clauses([C|Cs],List,Tail) :-
2390 generate_insert_constraint_internal_clause(C,List,List1),
2391 generate_insert_constraint_internal_clauses(Cs,List1,Tail).
2393 insert_constraint_internal_constraint_goal(Constraint, Vars, Suspension, Continuation, Args,Goal) :-
2394 ( chr_pp_flag(inline_insertremove,off) ->
2395 use_auxiliary_predicate(remove_constraint_internal,Constraint),
2396 insert_constraint_internal_constraint_atom(Constraint,Vars,Suspension,Continuation,Args,Goal)
2398 delay_phase_end(validate_store_type_assumptions,
2399 generate_insert_constraint_internal_body(Constraint,Suspension,Continuation,Args,Vars,Goal)
2404 insert_constraint_internal_constraint_atom(Constraint,Vars,Self,Closure,Args,Goal) :-
2405 insert_constraint_internal_constraint_name(Constraint,Name),
2406 ( chr_pp_flag(debugable,on) ->
2407 Goal =.. [Name, Vars, Self, Closure | Args]
2408 ; ( only_ground_indexed_arguments(Constraint) ; get_store_type(Constraint,var_assoc_store(_,_)))->
2409 Goal =.. [Name,Self | Args]
2411 Goal =.. [Name,Vars, Self | Args]
2414 insert_constraint_internal_constraint_name(Constraint,Name) :-
2415 make_name('$insert_constraint_internal_',Constraint,Name).
2417 generate_insert_constraint_internal_clause(Constraint,List,Tail) :-
2418 ( is_used_auxiliary_predicate(insert_constraint_internal,Constraint) ->
2419 List = [Clause|Tail],
2420 Clause = (Head :- Body),
2423 insert_constraint_internal_constraint_atom(Constraint, Vars, Suspension, Continuation,Args,Head),
2424 generate_insert_constraint_internal_body(Constraint,Suspension,Continuation,Args,Vars,Body)
2430 generate_insert_constraint_internal_body(Constraint,Susp,Continuation,Args,Vars,Body) :-
2431 static_suspension_term(Constraint,Suspension),
2432 create_static_suspension_field(Constraint,Suspension,state,active,CreateState),
2433 ( chr_pp_flag(debugable,on) ->
2434 get_static_suspension_term_field(continuation,Constraint,Suspension,Continuation),
2435 create_static_suspension_field(Constraint,Suspension,generation,0,CreateGeneration)
2436 ; may_trigger(Constraint), uses_field(Constraint,generation) ->
2437 create_static_suspension_field(Constraint,Suspension,generation,0,CreateGeneration)
2439 CreateGeneration = true
2441 ( chr_pp_flag(debugable,on) ->
2442 Constraint = Functor / _,
2443 get_static_suspension_term_field(functor,Constraint,Suspension,Functor)
2447 ( uses_history(Constraint) ->
2448 create_static_suspension_field(Constraint,Suspension,history,t,CreateHistory)
2450 CreateHistory = true
2452 get_static_suspension_term_field(arguments,Constraint,Suspension,Args),
2453 List = [Clause|Tail],
2454 ( chr_pp_flag(debugable,off), ( only_ground_indexed_arguments(Constraint) ; get_store_type(Constraint,var_assoc_store(_,_)))->
2455 suspension_term_base_fields(Constraint,BaseFields),
2456 ( has_suspension_field(Constraint,id) ->
2457 get_static_suspension_term_field(id,Constraint,Suspension,Id),
2471 ( has_suspension_field(Constraint,id) ->
2472 get_static_suspension_term_field(id,Constraint,Suspension,Id),
2477 generate_indexed_variables_body(Constraint,Args,IndexedVariablesBody,Vars),
2478 ( chr_pp_flag(guard_locks,off) ->
2481 NoneLocked = 'chr none_locked'( Vars)
2486 IndexedVariablesBody,
2495 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2496 % novel_production/2
2498 generate_novel_production(List,Tail) :-
2499 ( is_used_auxiliary_predicate(novel_production) ->
2500 List = [Clause|Tail],
2503 '$novel_production'( Self, Tuple) :-
2504 % arg( 3, Self, Ref), % ARGXXX
2505 % 'chr get_mutable'( History, Ref),
2506 arg( 3, Self, History), % ARGXXX
2507 ( hprolog:get_ds( Tuple, History, _) ->
2517 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2520 generate_extend_history(List,Tail) :-
2521 ( is_used_auxiliary_predicate(extend_history) ->
2522 List = [Clause|Tail],
2525 '$extend_history'( Self, Tuple) :-
2526 % arg( 3, Self, Ref), % ARGXXX
2527 % 'chr get_mutable'( History, Ref),
2528 arg( 3, Self, History), % ARGXXX
2529 hprolog:put_ds( Tuple, History, x, NewHistory),
2530 setarg( 3, Self, NewHistory) % ARGXXX
2536 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2539 empty_named_history_initialisations/2,
2540 generate_empty_named_history_initialisation/1,
2541 find_empty_named_histories/0.
2543 generate_empty_named_history_initialisations(List, Tail) :-
2544 empty_named_history_initialisations(List, Tail),
2545 find_empty_named_histories.
2547 find_empty_named_histories, history(_, Name, []) ==>
2548 generate_empty_named_history_initialisation(Name).
2550 generate_empty_named_history_initialisation(Name) \
2551 generate_empty_named_history_initialisation(Name) <=> true.
2552 generate_empty_named_history_initialisation(Name) \
2553 empty_named_history_initialisations(List, Tail) # Passive
2555 empty_named_history_global_variable(Name, GlobalVariable),
2556 List = [(:- nb_setval(GlobalVariable, 0))|Rest],
2557 empty_named_history_initialisations(Rest, Tail)
2558 pragma passive(Passive).
2560 find_empty_named_histories \
2561 generate_empty_named_history_initialisation(_) # Passive <=> true
2562 pragma passive(Passive).
2564 find_empty_named_histories,
2565 empty_named_history_initialisations(List, Tail) # Passive <=> List = Tail
2566 pragma passive(Passive).
2568 find_empty_named_histories <=>
2569 chr_error(internal, 'find_empty_named_histories was not removed', []).
2572 empty_named_history_global_variable(Name, GlobalVariable) :-
2573 atom_concat('chr empty named history ', Name, GlobalVariable).
2575 empty_named_history_novel_production(Name, nb_getval(GlobalVariable, 0)) :-
2576 empty_named_history_global_variable(Name, GlobalVariable).
2578 empty_named_history_extend_history(Name, b_setval(GlobalVariable, 1)) :-
2579 empty_named_history_global_variable(Name, GlobalVariable).
2582 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2585 generate_run_suspensions_clauses([],List,List).
2586 generate_run_suspensions_clauses([C|Cs],List,Tail) :-
2587 generate_run_suspensions_clause(C,List,List1),
2588 generate_run_suspensions_clauses(Cs,List1,Tail).
2590 run_suspensions_goal(Constraint,Suspensions,Goal) :-
2591 make_name('$run_suspensions_',Constraint,Name),
2592 Goal =.. [Name,Suspensions].
2594 generate_run_suspensions_clause(Constraint,List,Tail) :-
2595 ( is_used_auxiliary_predicate(run_suspensions,Constraint) ->
2596 List = [Clause1,Clause2|Tail],
2597 run_suspensions_goal(Constraint,[],Clause1),
2598 ( chr_pp_flag(debugable,on) ->
2599 run_suspensions_goal(Constraint,[Suspension|Suspensions],Clause2Head),
2600 get_update_suspension_field(Constraint,Suspension,state,State,triggered,GetState,GetStateValue,UpdateState),
2601 get_update_suspension_field(Constraint,Suspension,state,Post,active,GetPost,GetPostValue,UpdatePost),
2602 get_update_suspension_field(Constraint,Suspension,generation,Gen,Generation,GetGeneration,GetGenerationValue,UpdateGeneration),
2603 get_dynamic_suspension_term_field(continuation,Constraint,Suspension,Continuation,GetContinuation),
2604 run_suspensions_goal(Constraint,Suspensions,Clause2Recursion),
2614 Generation is Gen+1,
2618 'chr debug_event'(wake(Suspension)),
2621 'chr debug_event'(fail(Suspension)), !,
2625 'chr debug_event'(exit(Suspension))
2627 'chr debug_event'(redo(Suspension)),
2632 ( Post==triggered ->
2633 UpdatePost % catching constraints that did not do anything
2643 run_suspensions_goal(Constraint,[Suspension|Suspensions],Clause2Head),
2644 static_suspension_term(Constraint,SuspensionTerm),
2645 get_static_suspension_term_field(arguments,Constraint,SuspensionTerm,Arguments),
2646 append(Arguments,[Suspension],VarsSusp),
2647 make_suspension_continuation_goal(Constraint,VarsSusp,Continuation),
2648 run_suspensions_goal(Constraint,Suspensions,Clause2Recursion),
2649 ( uses_field(Constraint,generation) ->
2650 get_update_static_suspension_field(Constraint,Suspension,SuspensionTerm,generation,Gen,Generation,GetGeneration,UpdateGeneration),
2651 GenerationHandling = ( GetGeneration, Generation is Gen+1, UpdateGeneration)
2653 GenerationHandling = true
2655 get_update_static_suspension_field(Constraint,Suspension,SuspensionTerm,state,State,triggered,GetState,UpdateState),
2656 get_update_static_suspension_field(Constraint,Suspension,SuspensionTerm,state,Post,active,GetPostState,UpdatePostState),
2657 if_used_state(Constraint,removed,
2660 -> ReactivateConstraint
2662 ),ReactivateConstraint,CondReactivate),
2663 ReactivateConstraint =
2669 ( Post==triggered ->
2670 UpdatePostState % catching constraints that did not do anything
2678 Suspension = SuspensionTerm,
2687 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2689 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2690 generate_attach_increment(Clauses) :-
2691 get_max_constraint_index(N),
2692 ( is_used_auxiliary_predicate(attach_increment), N > 0 ->
2693 Clauses = [Clause1,Clause2],
2694 generate_attach_increment_empty(Clause1),
2696 generate_attach_increment_one(Clause2)
2698 generate_attach_increment_many(N,Clause2)
2704 generate_attach_increment_empty((attach_increment([],_) :- true)).
2706 generate_attach_increment_one(Clause) :-
2707 Head = attach_increment([Var|Vars],Susps),
2708 get_target_module(Mod),
2709 ( chr_pp_flag(guard_locks,off) ->
2712 NotLocked = 'chr not_locked'( Var)
2717 ( get_attr(Var,Mod,VarSusps) ->
2718 sort(VarSusps,SortedVarSusps),
2719 'chr merge_attributes'(Susps,SortedVarSusps,MergedSusps),
2720 put_attr(Var,Mod,MergedSusps)
2722 put_attr(Var,Mod,Susps)
2724 attach_increment(Vars,Susps)
2726 Clause = (Head :- Body).
2728 generate_attach_increment_many(N,Clause) :-
2729 Head = attach_increment([Var|Vars],TAttr1),
2730 % writeln(merge_attributes_1_before),
2731 merge_attributes(N,TAttr1,TAttr2,MergeGoal,Attr),
2732 % writeln(merge_attributes_1_after),
2733 get_target_module(Mod),
2734 ( chr_pp_flag(guard_locks,off) ->
2737 NotLocked = 'chr not_locked'( Var)
2742 ( get_attr(Var,Mod,TAttr2) ->
2744 put_attr(Var,Mod,Attr)
2746 put_attr(Var,Mod,TAttr1)
2748 attach_increment(Vars,TAttr1)
2750 Clause = (Head :- Body).
2753 generate_attr_unify_hook(Clauses) :-
2754 get_max_constraint_index(N),
2759 generate_attr_unify_hook_one(Clauses)
2761 generate_attr_unify_hook_many(N,Clauses)
2765 generate_attr_unify_hook_one([Clause]) :-
2766 Head = attr_unify_hook(Susps,Other),
2767 get_target_module(Mod),
2768 get_indexed_constraint(1,C),
2769 ( get_store_type(C,ST),
2770 ( ST = default ; ST = multi_store(STs), memberchk(default,STs) ) ->
2771 make_run_suspensions(NewSusps,SortedSusps,WakeNewSusps),
2772 make_run_suspensions(SortedSusps,SortedSusps,WakeSusps),
2773 ( atomic_types_suspended_constraint(C) ->
2775 SortedSusps = Susps,
2777 SortedOtherSusps = OtherSusps,
2778 MergeGoal = (append(Susps,OtherSusps,List), sort(List,NewSusps)),
2781 SortGoal1 = sort(Susps, SortedSusps),
2782 SortGoal2 = sort(OtherSusps,SortedOtherSusps),
2783 MergeGoal = 'chr merge_attributes'(SortedSusps,SortedOtherSusps,NewSusps),
2784 use_auxiliary_predicate(attach_increment),
2786 ( compound(Other) ->
2787 term_variables(Other,OtherVars),
2788 attach_increment(OtherVars, SortedSusps)
2797 ( get_attr(Other,Mod,OtherSusps) ->
2800 put_attr(Other,Mod,NewSusps),
2803 put_attr(Other,Mod,SortedSusps),
2811 Clause = (Head :- Body)
2812 ; get_store_type(C,var_assoc_store(VarIndex,KeyIndex)) ->
2813 make_run_suspensions(List,List,WakeNewSusps),
2814 MergeGoal = (merge_into_assoc_store(Susps,OtherSusps,List)),
2816 ( get_attr(Other,Mod,OtherSusps) ->
2820 put_attr(Other,Mod,Susps)
2822 Clause = (Head :- Body)
2826 generate_attr_unify_hook_many(N,[Clause]) :-
2827 chr_pp_flag(dynattr,off), !,
2828 Head = attr_unify_hook(Attr,Other),
2829 get_target_module(Mod),
2830 make_attr(N,Mask,SuspsList,Attr),
2831 bagof(Sort,A ^ B ^ ( member(A,SuspsList) , Sort = sort(A,B) ) , SortGoalList),
2832 list2conj(SortGoalList,SortGoals),
2833 bagof(B, A ^ member(sort(A,B),SortGoalList), SortedSuspsList),
2834 merge_attributes2(N,Mask,SortedSuspsList,TOtherAttr,MergeGoal,MergedAttr),
2835 get_all_suspensions2(N,MergedAttr,MergedSuspsList),
2836 make_attr(N,Mask,SortedSuspsList,SortedAttr),
2837 make_run_suspensions_loop(MergedSuspsList,SortedSuspsList,WakeMergedSusps),
2838 make_run_suspensions_loop(SortedSuspsList,SortedSuspsList,WakeSortedSusps),
2839 ( forall((between(1,N,Index), get_indexed_constraint(Index,Constraint)),atomic_types_suspended_constraint(Constraint)) ->
2842 use_auxiliary_predicate(attach_increment),
2844 ( compound(Other) ->
2845 term_variables(Other,OtherVars),
2846 attach_increment(OtherVars,SortedAttr)
2855 ( get_attr(Other,Mod,TOtherAttr) ->
2857 put_attr(Other,Mod,MergedAttr),
2860 put_attr(Other,Mod,SortedAttr),
2868 Clause = (Head :- Body).
2871 generate_attr_unify_hook_many(N,Clauses) :-
2872 Head = attr_unify_hook(Attr,Other),
2873 get_target_module(Mod),
2874 normalize_attr(Attr,NormalGoal,NormalAttr),
2875 normalize_attr(OtherAttr,NormalOtherGoal,NormalOtherAttr),
2876 merge_attributes(N,NormalAttr,NormalOtherAttr,MergeGoal,MergedAttr),
2877 make_run_suspensions(N),
2878 ( forall((between(1,N,Index), get_indexed_constraint(Index,Constraint)),atomic_types_suspended_constraint(Constraint)) ->
2881 use_auxiliary_predicate(attach_increment),
2883 ( compound(Other) ->
2884 term_variables(Other,OtherVars),
2885 attach_increment(OtherVars,NormalAttr)
2894 ( get_attr(Other,Mod,OtherAttr) ->
2897 put_attr(Other,Mod,MergedAttr),
2898 '$dispatch_run_suspensions'(MergedAttr)
2900 put_attr(Other,Mod,NormalAttr),
2901 '$dispatch_run_suspensions'(NormalAttr)
2905 '$dispatch_run_suspensions'(NormalAttr)
2908 Clause = (Head :- Body),
2909 Clauses = [Clause,DispatchList1,DispatchList2|Dispatchers],
2910 DispatchList1 = ('$dispatch_run_suspensions'([])),
2911 DispatchList2 = ('$dispatch_run_suspensions'([Pos-List|Rest]) :- '$dispatch_run_suspensions'(Pos,List),'$dispatch_run_suspensions'(Rest)),
2912 run_suspensions_dispatchers(N,[],Dispatchers).
2915 run_suspensions_dispatchers(N,Acc,Dispatchers) :-
2917 get_indexed_constraint(N,C),
2918 NAcc = [('$dispatch_run_suspensions'(N,List) :- Body)|Acc],
2920 run_suspensions_goal(C,List,Body)
2925 run_suspensions_dispatchers(M,NAcc,Dispatchers)
2931 make_run_suspensions(N) :-
2933 ( get_indexed_constraint(N,C),
2935 use_auxiliary_predicate(run_suspensions,C)
2940 make_run_suspensions(M)
2945 make_run_suspensions(AllSusps,OneSusps,Goal) :-
2946 make_run_suspensions(1,AllSusps,OneSusps,Goal).
2948 make_run_suspensions(Index,AllSusps,OneSusps,Goal) :-
2949 ( get_indexed_constraint(Index,C), may_trigger(C) ->
2950 use_auxiliary_predicate(run_suspensions,C),
2951 ( wakes_partially(C) ->
2952 run_suspensions_goal(C,OneSusps,Goal)
2954 run_suspensions_goal(C,AllSusps,Goal)
2960 make_run_suspensions_loop(AllSuspsList,OneSuspsList,Goal) :-
2961 make_run_suspensions_loop(AllSuspsList,OneSuspsList,1,Goal).
2963 make_run_suspensions_loop([],[],_,true).
2964 make_run_suspensions_loop([AllSusps|AllSuspsList],[OneSusps|OneSuspsList],I,(Goal,Goals)) :-
2965 make_run_suspensions(I,AllSusps,OneSusps,Goal),
2967 make_run_suspensions_loop(AllSuspsList,OneSuspsList,J,Goals).
2969 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2970 % $insert_in_store_F/A
2971 % $delete_from_store_F/A
2973 generate_insert_delete_constraints([],[]).
2974 generate_insert_delete_constraints([FA|Rest],Clauses) :-
2976 generate_insert_delete_constraint(FA,Clauses,RestClauses)
2978 Clauses = RestClauses
2980 generate_insert_delete_constraints(Rest,RestClauses).
2982 generate_insert_delete_constraint(FA,Clauses,RestClauses) :-
2983 insert_constraint_clause(FA,Clauses,RestClauses1),
2984 delete_constraint_clause(FA,RestClauses1,RestClauses).
2986 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
2989 insert_constraint_goal(FA,Susp,Vars,Goal) :-
2990 ( chr_pp_flag(inline_insertremove,off) ->
2991 use_auxiliary_predicate(insert_in_store,FA),
2992 insert_constraint_atom(FA,Susp,Goal)
2994 delay_phase_end(validate_store_type_assumptions,
2995 ( insert_constraint_body(FA,Susp,UsedVars,Goal),
2996 insert_constraint_direct_used_vars(UsedVars,Vars)
3001 insert_constraint_direct_used_vars([],_).
3002 insert_constraint_direct_used_vars([Index-Var|Rest],Vars) :-
3003 nth1(Index,Vars,Var),
3004 insert_constraint_direct_used_vars(Rest,Vars).
3006 insert_constraint_atom(FA,Susp,Call) :-
3007 make_name('$insert_in_store_',FA,Functor),
3008 Call =.. [Functor,Susp].
3010 insert_constraint_clause(C,Clauses,RestClauses) :-
3011 ( is_used_auxiliary_predicate(insert_in_store,C) ->
3012 Clauses = [Clause|RestClauses],
3013 Clause = (Head :- InsertCounterInc,VarsBody,Body),
3014 insert_constraint_atom(C,Susp,Head),
3015 insert_constraint_body(C,Susp,UsedVars,Body),
3016 insert_constraint_used_vars(UsedVars,C,Susp,VarsBody),
3017 ( chr_pp_flag(store_counter,on) ->
3018 InsertCounterInc = '$insert_counter_inc'
3020 InsertCounterInc = true
3023 Clauses = RestClauses
3026 insert_constraint_used_vars([],_,_,true).
3027 insert_constraint_used_vars([Index-Var|Rest],C,Susp,(Goal,Goals)) :-
3028 get_dynamic_suspension_term_field(argument(Index),C,Susp,Var,Goal),
3029 insert_constraint_used_vars(Rest,C,Susp,Goals).
3031 insert_constraint_body(C,Susp,UsedVars,Body) :-
3032 get_store_type(C,StoreType),
3033 insert_constraint_body(StoreType,C,Susp,UsedVars,Body).
3035 insert_constraint_body(default,C,Susp,[],Body) :-
3036 global_list_store_name(C,StoreName),
3037 make_get_store_goal(StoreName,Store,GetStoreGoal),
3038 make_update_store_goal(StoreName,Cell,UpdateStoreGoal),
3039 ( chr_pp_flag(debugable,on) ->
3040 Cell = [Susp|Store],
3047 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,Cell,SetGoal),
3051 Cell = [Susp|Store],
3053 ( Store = [NextSusp|_] ->
3060 % get_target_module(Mod),
3061 % get_max_constraint_index(Total),
3063 % generate_attach_body_1(C,Store,Susp,AttachBody)
3065 % generate_attach_body_n(C,Store,Susp,AttachBody)
3069 % 'chr default_store'(Store),
3072 insert_constraint_body(multi_inthash(Indexes),C,Susp,[],Body) :-
3073 generate_multi_inthash_insert_constraint_bodies(Indexes,C,Susp,Body).
3074 insert_constraint_body(multi_hash(Indexes),C,Susp,MixedUsedVars,Body) :-
3075 generate_multi_hash_insert_constraint_bodies(Indexes,C,Susp,Body,MixedUsedVars),
3076 sort_out_used_vars(MixedUsedVars,UsedVars).
3077 insert_constraint_body(atomic_constants(Index,_,_),C,Susp,UsedVars,Body) :-
3078 multi_hash_key_direct(C,Index,Susp,Key,UsedVars),
3079 constants_store_index_name(C,Index,IndexName),
3080 IndexLookup =.. [IndexName,Key,StoreName],
3083 nb_getval(StoreName,Store),
3084 b_setval(StoreName,[Susp|Store])
3088 insert_constraint_body(ground_constants(Index,_,_),C,Susp,UsedVars,Body) :-
3089 multi_hash_key_direct(C,Index,Susp,Key,UsedVars),
3090 constants_store_index_name(C,Index,IndexName),
3091 IndexLookup =.. [IndexName,Key,StoreName],
3094 nb_getval(StoreName,Store),
3095 b_setval(StoreName,[Susp|Store])
3099 insert_constraint_body(global_ground,C,Susp,[],Body) :-
3100 global_ground_store_name(C,StoreName),
3101 make_get_store_goal(StoreName,Store,GetStoreGoal),
3102 make_update_store_goal(StoreName,Cell,UpdateStoreGoal),
3103 ( chr_pp_flag(debugable,on) ->
3104 Cell = [Susp|Store],
3111 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,Cell,SetGoal),
3115 Cell = [Susp|Store],
3117 ( Store = [NextSusp|_] ->
3124 % global_ground_store_name(C,StoreName),
3125 % make_get_store_goal(StoreName,Store,GetStoreGoal),
3126 % make_update_store_goal(StoreName,[Susp|Store],UpdateStoreGoal),
3129 % GetStoreGoal, % nb_getval(StoreName,Store),
3130 % UpdateStoreGoal % b_setval(StoreName,[Susp|Store])
3132 insert_constraint_body(var_assoc_store(VarIndex,AssocIndex),C,Susp,[VarIndex-Variable,AssocIndex-Key],Body) :-
3133 % TODO: generalize to more than one !!!
3134 get_target_module(Module),
3135 Body = ( get_attr(Variable,Module,AssocStore) ->
3136 insert_assoc_store(AssocStore,Key,Susp)
3138 new_assoc_store(AssocStore),
3139 put_attr(Variable,Module,AssocStore),
3140 insert_assoc_store(AssocStore,Key,Susp)
3143 insert_constraint_body(global_singleton,C,Susp,[],Body) :-
3144 global_singleton_store_name(C,StoreName),
3145 make_update_store_goal(StoreName,Susp,UpdateStoreGoal),
3150 insert_constraint_body(multi_store(StoreTypes),C,Susp,UsedVars,Body) :-
3151 maplist(insert_constraint_body1(C,Susp),StoreTypes,NestedUsedVars,Bodies),
3152 list2conj(Bodies,Body),
3153 sort_out_used_vars(NestedUsedVars,UsedVars).
3154 insert_constraint_body1(C,Susp,StoreType,UsedVars,Body) :-
3155 insert_constraint_body(StoreType,C,Susp,UsedVars,Body).
3156 insert_constraint_body(identifier_store(Index),C,Susp,UsedVars,Body) :-
3157 UsedVars = [Index-Var],
3158 get_identifier_size(ISize),
3159 functor(Struct,struct,ISize),
3160 get_identifier_index(C,Index,IIndex),
3161 arg(IIndex,Struct,Susps),
3162 Body = (Var = Struct, setarg(IIndex,Var,[Susp|Susps])).
3163 insert_constraint_body(type_indexed_identifier_store(Index,IndexType),C,Susp,UsedVars,Body) :-
3164 UsedVars = [Index-Var],
3165 type_indexed_identifier_structure(IndexType,Struct),
3166 get_type_indexed_identifier_index(IndexType,C,Index,IIndex),
3167 arg(IIndex,Struct,Susps),
3168 Body = (Var = Struct, setarg(IIndex,Var,[Susp|Susps])).
3170 sort_out_used_vars(NestedUsedVars,UsedVars) :-
3171 flatten(NestedUsedVars,FlatUsedVars),
3172 sort(FlatUsedVars,SortedFlatUsedVars),
3173 sort_out_used_vars1(SortedFlatUsedVars,UsedVars).
3175 sort_out_used_vars1([],[]).
3176 sort_out_used_vars1([I-V],L) :- !, L = [I-V].
3177 sort_out_used_vars1([I-X,J-Y|R],L) :-
3180 sort_out_used_vars1([I-X|R],L)
3183 sort_out_used_vars1([J-Y|R],T)
3186 generate_multi_inthash_insert_constraint_bodies([],_,_,true).
3187 generate_multi_inthash_insert_constraint_bodies([Index|Indexes],FA,Susp,(Body,Bodies)) :-
3188 multi_hash_store_name(FA,Index,StoreName),
3189 multi_hash_key(FA,Index,Susp,KeyBody,Key),
3193 nb_getval(StoreName,Store),
3194 insert_iht(Store,Key,Susp)
3196 generate_multi_inthash_insert_constraint_bodies(Indexes,FA,Susp,Bodies).
3198 generate_multi_hash_insert_constraint_bodies([],_,_,true,[]).
3199 generate_multi_hash_insert_constraint_bodies([Index|Indexes],FA,Susp,(Body,Bodies),[UsedVars|MoreUsedVars]) :-
3200 multi_hash_store_name(FA,Index,StoreName),
3201 multi_hash_key_direct(FA,Index,Susp,Key,UsedVars),
3202 make_get_store_goal(StoreName,Store,GetStoreGoal),
3203 ( chr_pp_flag(ht_removal,on)
3204 -> ht_prev_field(Index,PrevField),
3205 set_dynamic_suspension_term_field(PrevField,FA,NextSusp,Result,
3210 insert_ht(Store,Key,Susp,Result),
3211 ( Result = [_,NextSusp|_]
3219 insert_ht(Store,Key,Susp)
3222 generate_multi_hash_insert_constraint_bodies(Indexes,FA,Susp,Bodies,MoreUsedVars).
3224 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3227 delete_constraint_clause(C,Clauses,RestClauses) :-
3228 ( is_used_auxiliary_predicate(delete_from_store,C) ->
3229 Clauses = [Clause|RestClauses],
3230 Clause = (Head :- Body),
3231 delete_constraint_atom(C,Susp,Head),
3234 delete_constraint_body(C,Head,Susp,[],Body)
3236 Clauses = RestClauses
3239 delete_constraint_goal(Head,Susp,VarDict,Goal) :-
3242 ( chr_pp_flag(inline_insertremove,off) ->
3243 use_auxiliary_predicate(delete_from_store,C),
3244 delete_constraint_atom(C,Susp,Goal)
3246 delay_phase_end(validate_store_type_assumptions, delete_constraint_body(C,Head,Susp,VarDict,Goal))
3249 delete_constraint_atom(C,Susp,Atom) :-
3250 make_name('$delete_from_store_',C,Functor),
3251 Atom =.. [Functor,Susp].
3254 delete_constraint_body(C,Head,Susp,VarDict,Body) :-
3255 Body = (CounterBody,DeleteBody),
3256 ( chr_pp_flag(store_counter,on) ->
3257 CounterBody = '$delete_counter_inc'
3261 get_store_type(C,StoreType),
3262 delete_constraint_body(StoreType,C,Head,Susp,VarDict,DeleteBody).
3264 delete_constraint_body(default,C,_,Susp,_,Body) :-
3265 ( chr_pp_flag(debugable,on) ->
3266 global_list_store_name(C,StoreName),
3267 make_get_store_goal(StoreName,Store,GetStoreGoal),
3268 make_update_store_goal(StoreName,NStore,UpdateStoreGoal),
3271 GetStoreGoal, % nb_getval(StoreName,Store),
3272 'chr sbag_del_element'(Store,Susp,NStore),
3273 UpdateStoreGoal % b_setval(StoreName,NStore)
3276 get_dynamic_suspension_term_field(global_list_prev,C,Susp,PredCell,GetGoal),
3277 global_list_store_name(C,StoreName),
3278 make_get_store_goal(StoreName,Store,GetStoreGoal),
3279 make_update_store_goal(StoreName,Tail,UpdateStoreGoal),
3280 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,_,SetGoal1),
3281 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,PredCell,SetGoal2),
3286 GetStoreGoal, % nb_getval(StoreName,Store),
3289 ( Tail = [NextSusp|_] ->
3295 PredCell = [_,_|Tail],
3296 setarg(2,PredCell,Tail),
3297 ( Tail = [NextSusp|_] ->
3305 % get_target_module(Mod),
3306 % get_max_constraint_index(Total),
3308 % generate_detach_body_1(C,Store,Susp,DetachBody),
3311 % 'chr default_store'(Store),
3315 % generate_detach_body_n(C,Store,Susp,DetachBody),
3318 % 'chr default_store'(Store),
3322 delete_constraint_body(multi_inthash(Indexes),C,_,Susp,_,Body) :-
3323 generate_multi_inthash_delete_constraint_bodies(Indexes,C,Susp,Body).
3324 delete_constraint_body(multi_hash(Indexes),C,Head,Susp,VarDict,Body) :-
3325 generate_multi_hash_delete_constraint_bodies(Indexes,C,Head,Susp,VarDict,Body).
3326 delete_constraint_body(atomic_constants(Index,_,_),C,Head,Susp,VarDict,Body) :-
3327 multi_hash_key(C,Head,Index,Susp,VarDict,KeyBody,Key),
3328 constants_store_index_name(C,Index,IndexName),
3329 IndexLookup =.. [IndexName,Key,StoreName],
3333 nb_getval(StoreName,Store),
3334 'chr sbag_del_element'(Store,Susp,NStore),
3335 b_setval(StoreName,NStore)
3339 delete_constraint_body(ground_constants(Index,_,_),C,Head,Susp,VarDict,Body) :-
3340 multi_hash_key(C,Head,Index,Susp,VarDict,KeyBody,Key),
3341 constants_store_index_name(C,Index,IndexName),
3342 IndexLookup =.. [IndexName,Key,StoreName],
3346 nb_getval(StoreName,Store),
3347 'chr sbag_del_element'(Store,Susp,NStore),
3348 b_setval(StoreName,NStore)
3352 delete_constraint_body(global_ground,C,_,Susp,_,Body) :-
3353 ( chr_pp_flag(debugable,on) ->
3354 global_ground_store_name(C,StoreName),
3355 make_get_store_goal(StoreName,Store,GetStoreGoal),
3356 make_update_store_goal(StoreName,NStore,UpdateStoreGoal),
3359 GetStoreGoal, % nb_getval(StoreName,Store),
3360 'chr sbag_del_element'(Store,Susp,NStore),
3361 UpdateStoreGoal % b_setval(StoreName,NStore)
3364 get_dynamic_suspension_term_field(global_list_prev,C,Susp,PredCell,GetGoal),
3365 global_ground_store_name(C,StoreName),
3366 make_get_store_goal(StoreName,Store,GetStoreGoal),
3367 make_update_store_goal(StoreName,Tail,UpdateStoreGoal),
3368 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,_,SetGoal1),
3369 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,PredCell,SetGoal2),
3374 GetStoreGoal, % nb_getval(StoreName,Store),
3377 ( Tail = [NextSusp|_] ->
3383 PredCell = [_,_|Tail],
3384 setarg(2,PredCell,Tail),
3385 ( Tail = [NextSusp|_] ->
3393 % global_ground_store_name(C,StoreName),
3394 % make_get_store_goal(StoreName,Store,GetStoreGoal),
3395 % make_update_store_goal(StoreName,NStore,UpdateStoreGoal),
3398 % GetStoreGoal, % nb_getval(StoreName,Store),
3399 % 'chr sbag_del_element'(Store,Susp,NStore),
3400 % UpdateStoreGoal % b_setval(StoreName,NStore)
3402 delete_constraint_body(var_assoc_store(VarIndex,AssocIndex),C,_,Susp,_,Body) :-
3403 get_target_module(Module),
3404 get_dynamic_suspension_term_field(argument(VarIndex),C,Susp,Variable,VariableGoal),
3405 get_dynamic_suspension_term_field(argument(AssocIndex),C,Susp,Key,KeyGoal),
3408 get_attr(Variable,Module,AssocStore),
3410 delete_assoc_store(AssocStore,Key,Susp)
3412 delete_constraint_body(global_singleton,C,_,_Susp,_,Body) :-
3413 global_singleton_store_name(C,StoreName),
3414 make_update_store_goal(StoreName,[],UpdateStoreGoal),
3417 UpdateStoreGoal % b_setval(StoreName,[])
3419 delete_constraint_body(multi_store(StoreTypes),C,Head,Susp,VarDict,Body) :-
3420 maplist(delete_constraint_body1(C,Head,Susp,VarDict),StoreTypes,Bodies),
3421 list2conj(Bodies,Body).
3422 delete_constraint_body1(C,Head,Susp,VarDict,StoreType,Body) :-
3423 delete_constraint_body(StoreType,C,Head,Susp,VarDict,Body).
3424 delete_constraint_body(identifier_store(Index),C,Head,Susp,VarDict,Body) :-
3425 get_suspension_argument_possibly_in_scope(Head,VarDict,Susp,Index,Variable,VariableGoal),
3426 get_identifier_size(ISize),
3427 functor(Struct,struct,ISize),
3428 get_identifier_index(C,Index,IIndex),
3429 arg(IIndex,Struct,Susps),
3433 'chr sbag_del_element'(Susps,Susp,NSusps),
3434 setarg(IIndex,Variable,NSusps)
3436 delete_constraint_body(type_indexed_identifier_store(Index,IndexType),C,Head,Susp,VarDict,Body) :-
3437 get_suspension_argument_possibly_in_scope(Head,VarDict,Susp,Index,Variable,VariableGoal),
3438 type_indexed_identifier_structure(IndexType,Struct),
3439 get_type_indexed_identifier_index(IndexType,C,Index,IIndex),
3440 arg(IIndex,Struct,Susps),
3444 'chr sbag_del_element'(Susps,Susp,NSusps),
3445 setarg(IIndex,Variable,NSusps)
3448 generate_multi_inthash_delete_constraint_bodies([],_,_,true).
3449 generate_multi_inthash_delete_constraint_bodies([Index|Indexes],FA,Susp,(Body,Bodies)) :-
3450 multi_hash_store_name(FA,Index,StoreName),
3451 multi_hash_key(FA,Index,Susp,KeyBody,Key),
3455 nb_getval(StoreName,Store),
3456 delete_iht(Store,Key,Susp)
3458 generate_multi_inthash_delete_constraint_bodies(Indexes,FA,Susp,Bodies).
3459 generate_multi_hash_delete_constraint_bodies([],_,_,_,_,true).
3460 generate_multi_hash_delete_constraint_bodies([Index|Indexes],C,Head,Susp,VarDict,(Body,Bodies)) :-
3461 multi_hash_store_name(C,Index,StoreName),
3462 multi_hash_key(C,Head,Index,Susp,VarDict,KeyBody,Key),
3463 make_get_store_goal(StoreName,Store,GetStoreGoal),
3464 ( chr_pp_flag(ht_removal,on)
3465 -> ht_prev_field(Index,PrevField),
3466 get_dynamic_suspension_term_field(PrevField,C,Susp,Prev,GetGoal),
3467 set_dynamic_suspension_term_field(PrevField,C,NextSusp,_,
3469 set_dynamic_suspension_term_field(PrevField,C,NextSusp,Prev,
3477 delete_first_ht(Store,Key,Values),
3478 ( Values = [NextSusp|_]
3482 ; Prev = [_,_|Values],
3483 setarg(2,Prev,Values),
3484 ( Values = [NextSusp|_]
3493 GetStoreGoal, % nb_getval(StoreName,Store),
3494 delete_ht(Store,Key,Susp)
3497 generate_multi_hash_delete_constraint_bodies(Indexes,FA,Head,Susp,VarDict,Bodies).
3499 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3502 module_initializer/1,
3503 module_initializers/1.
3505 module_initializers(G), module_initializer(Initializer) <=>
3506 G = (Initializer,Initializers),
3507 module_initializers(Initializers).
3509 module_initializers(G) <=>
3512 generate_attach_code(Constraints,[Enumerate|L]) :-
3513 enumerate_stores_code(Constraints,Enumerate),
3514 generate_attach_code(Constraints,L,T),
3515 module_initializers(Initializers),
3516 prolog_global_variables_code(PrologGlobalVariables),
3517 % Do not rename or the 'chr_initialization' predicate
3518 % without warning SSS
3519 T = [('$chr_initialization' :- Initializers),(:- initialization '$chr_initialization')|PrologGlobalVariables].
3521 generate_attach_code([],L,L).
3522 generate_attach_code([C|Cs],L,T) :-
3523 get_store_type(C,StoreType),
3524 generate_attach_code(StoreType,C,L,L1),
3525 generate_attach_code(Cs,L1,T).
3527 generate_attach_code(default,C,L,T) :-
3528 global_list_store_initialisation(C,L,T).
3529 generate_attach_code(multi_inthash(Indexes),C,L,T) :-
3530 multi_inthash_store_initialisations(Indexes,C,L,L1),
3531 multi_inthash_via_lookups(Indexes,C,L1,T).
3532 generate_attach_code(multi_hash(Indexes),C,L,T) :-
3533 multi_hash_store_initialisations(Indexes,C,L,L1),
3534 multi_hash_lookups(Indexes,C,L1,T).
3535 generate_attach_code(atomic_constants(Index,Constants,_),C,L,T) :-
3536 constants_initializers(C,Index,Constants),
3537 atomic_constants_code(C,Index,Constants,L,T).
3538 generate_attach_code(ground_constants(Index,Constants,_),C,L,T) :-
3539 constants_initializers(C,Index,Constants),
3540 ground_constants_code(C,Index,Constants,L,T).
3541 generate_attach_code(global_ground,C,L,T) :-
3542 global_ground_store_initialisation(C,L,T).
3543 generate_attach_code(var_assoc_store(_,_),_,L,L) :-
3544 use_auxiliary_module(chr_assoc_store).
3545 generate_attach_code(global_singleton,C,L,T) :-
3546 global_singleton_store_initialisation(C,L,T).
3547 generate_attach_code(multi_store(StoreTypes),C,L,T) :-
3548 multi_store_generate_attach_code(StoreTypes,C,L,T).
3549 generate_attach_code(identifier_store(Index),C,L,T) :-
3550 get_identifier_index(C,Index,IIndex),
3552 get_identifier_size(ISize),
3553 functor(Struct,struct,ISize),
3554 Struct =.. [_,Label|Stores],
3555 set_elems(Stores,[]),
3556 Clause1 = new_identifier(Label,Struct),
3557 functor(Struct2,struct,ISize),
3558 arg(1,Struct2,Label2),
3560 ( user:portray(Struct2) :-
3565 functor(Struct3,struct,ISize),
3566 arg(1,Struct3,Label3),
3567 Clause3 = identifier_label(Struct3,Label3),
3568 L = [Clause1,Clause2,Clause3|T]
3572 generate_attach_code(type_indexed_identifier_store(Index,IndexType),C,L,T) :-
3573 get_type_indexed_identifier_index(IndexType,C,Index,IIndex),
3575 identifier_store_initialization(IndexType,L,L1),
3576 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3577 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3578 get_type_indexed_identifier_size(IndexType,ISize),
3579 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3580 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3581 type_indexed_identifier_structure(IndexType,Struct),
3582 Struct =.. [_,Label|Stores],
3583 set_elems(Stores,[]),
3584 type_indexed_identifier_name(IndexType,new_identifier,Name1),
3585 Clause1 =.. [Name1,Label,Struct],
3586 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3587 Goal1 =.. [Name1,Label1b,S1b],
3588 type_indexed_identifier_structure(IndexType,Struct1b),
3589 Struct1b =.. [_,Label1b|Stores1b],
3590 set_elems(Stores1b,[]),
3591 Expansion1 = (S1b = Struct1b),
3592 Clause1b = user:goal_expansion(Goal1,Expansion1),
3593 % writeln(Clause1-Clause1b),
3594 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3595 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3596 type_indexed_identifier_structure(IndexType,Struct2),
3597 arg(1,Struct2,Label2),
3599 ( user:portray(Struct2) :-
3604 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3605 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3606 type_indexed_identifier_structure(IndexType,Struct3),
3607 arg(1,Struct3,Label3),
3608 type_indexed_identifier_name(IndexType,identifier_label,Name3),
3609 Clause3 =.. [Name3,Struct3,Label3],
3610 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3611 Goal3b =.. [Name3,S3b,L3b],
3612 type_indexed_identifier_structure(IndexType,Struct3b),
3613 arg(1,Struct3b,L3b),
3614 Expansion3b = (S3 = Struct3b),
3615 Clause3b = ( user:goal_expansion(Goal3b,Expansion3b) :- writeln(expanding)),
3616 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3617 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3618 identifier_store_name(IndexType,GlobalVariable),
3619 lookup_identifier_atom(IndexType,X,IX,LookupAtom),
3620 type_indexed_identifier_name(IndexType,new_identifier,NewIdentifierFunctor),
3621 NewIdentifierGoal =.. [NewIdentifierFunctor,X,IX],
3624 nb_getval(GlobalVariable,HT),
3625 ( lookup_ht(HT,X,[IX]) ->
3632 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3633 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3634 L1 = [(:- multifile goal_expansion/2),(:- dynamic goal_expansion/2),Clause1,Clause1b,Clause2,Clause3,Clause3b,Clause4|T]
3639 constants_initializers(C,Index,Constants) :-
3640 maplist(constant_initializer(C,Index),Constants).
3642 constant_initializer(C,Index,Constant) :-
3643 constants_store_name(C,Index,Constant,StoreName),
3644 module_initializer(nb_setval(StoreName,[])).
3646 lookup_identifier_atom(Key,X,IX,Atom) :-
3647 atom_concat('lookup_identifier_',Key,LookupFunctor),
3648 Atom =.. [LookupFunctor,X,IX].
3650 identifier_label_atom(IndexType,IX,X,Atom) :-
3651 type_indexed_identifier_name(IndexType,identifier_label,Name),
3652 Atom =.. [Name,IX,X].
3654 multi_store_generate_attach_code([],_,L,L).
3655 multi_store_generate_attach_code([ST|STs],C,L,T) :-
3656 generate_attach_code(ST,C,L,L1),
3657 multi_store_generate_attach_code(STs,C,L1,T).
3659 multi_inthash_store_initialisations([],_,L,L).
3660 multi_inthash_store_initialisations([Index|Indexes],FA,L,T) :-
3661 use_auxiliary_module(chr_integertable_store),
3662 multi_hash_store_name(FA,Index,StoreName),
3663 module_initializer((new_iht(HT),nb_setval(StoreName,HT))),
3664 % L = [(:- (chr_integertable_store:new_ht(HT),nb_setval(StoreName,HT)) )|L1],
3666 multi_inthash_store_initialisations(Indexes,FA,L1,T).
3667 multi_hash_store_initialisations([],_,L,L).
3668 multi_hash_store_initialisations([Index|Indexes],FA,L,T) :-
3669 use_auxiliary_module(chr_hashtable_store),
3670 multi_hash_store_name(FA,Index,StoreName),
3671 prolog_global_variable(StoreName),
3672 make_init_store_goal(StoreName,HT,InitStoreGoal),
3673 module_initializer((new_ht(HT),InitStoreGoal)),
3675 multi_hash_store_initialisations(Indexes,FA,L1,T).
3677 global_list_store_initialisation(C,L,T) :-
3679 global_list_store_name(C,StoreName),
3680 prolog_global_variable(StoreName),
3681 make_init_store_goal(StoreName,[],InitStoreGoal),
3682 module_initializer(InitStoreGoal)
3687 global_ground_store_initialisation(C,L,T) :-
3688 global_ground_store_name(C,StoreName),
3689 prolog_global_variable(StoreName),
3690 make_init_store_goal(StoreName,[],InitStoreGoal),
3691 module_initializer(InitStoreGoal),
3693 global_singleton_store_initialisation(C,L,T) :-
3694 global_singleton_store_name(C,StoreName),
3695 prolog_global_variable(StoreName),
3696 make_init_store_goal(StoreName,[],InitStoreGoal),
3697 module_initializer(InitStoreGoal),
3699 identifier_store_initialization(IndexType,L,T) :-
3700 use_auxiliary_module(chr_hashtable_store),
3701 identifier_store_name(IndexType,StoreName),
3702 prolog_global_variable(StoreName),
3703 make_init_store_goal(StoreName,HT,InitStoreGoal),
3704 module_initializer((new_ht(HT),InitStoreGoal)),
3708 multi_inthash_via_lookups([],_,L,L).
3709 multi_inthash_via_lookups([Index|Indexes],C,L,T) :-
3710 multi_hash_lookup_head(C,Index,Key,SuspsList,Head),
3711 multi_hash_lookup_body(C,inthash,Index,Key,SuspsList,Body),
3712 L = [(Head :- Body)|L1],
3713 multi_inthash_via_lookups(Indexes,C,L1,T).
3714 multi_hash_lookups([],_,L,L).
3715 multi_hash_lookups([Index|Indexes],C,L,T) :-
3716 multi_hash_lookup_head(C,Index,Key,SuspsList,Head),
3717 multi_hash_lookup_body(C,hash,Index,Key,SuspsList,Body),
3718 L = [(Head :- Body)|L1],
3719 multi_hash_lookups(Indexes,C,L1,T).
3721 multi_hash_lookup_head(ConstraintSymbol,Index,Key,SuspsList,Head) :-
3722 multi_hash_lookup_name(ConstraintSymbol,Index,Name),
3723 Head =.. [Name,Key,SuspsList].
3725 %% multi_hash_lookup_body(+ConstraintSymbol,+HashType,+Index,+Key,+SuspsList,-Goal) is det.
3727 % Returns goal that performs hash table lookup.
3728 multi_hash_lookup_body(ConstraintSymbol,HashType,Index,Key,SuspsList,Goal) :-
3730 get_store_type(ConstraintSymbol,multi_store(Stores)),
3731 ( memberchk(atomic_constants(Index,Constants,_),Stores) ->
3733 constants_store_name(ConstraintSymbol,Index,Key,StoreName),
3734 Goal = nb_getval(StoreName,SuspsList)
3736 constants_store_index_name(ConstraintSymbol,Index,IndexName),
3737 Lookup =.. [IndexName,Key,StoreName],
3738 Goal = (Lookup, nb_getval(StoreName,SuspsList))
3740 ; memberchk(ground_constants(Index,Constants,_),Stores) ->
3742 constants_store_name(ConstraintSymbol,Index,Key,StoreName),
3743 Goal = nb_getval(StoreName,SuspsList)
3745 constants_store_index_name(ConstraintSymbol,Index,IndexName),
3746 Lookup =.. [IndexName,Key,StoreName],
3747 Goal = (Lookup, nb_getval(StoreName,SuspsList))
3749 ; memberchk(multi_hash([Index]),Stores) ->
3750 multi_hash_store_name(ConstraintSymbol,Index,StoreName),
3751 make_get_store_goal(StoreName,HT,GetStoreGoal),
3752 ( HashType == hash, specialized_hash_term_call(ConstraintSymbol,Index,Key,Hash,HashCall) ->
3755 GetStoreGoal, % nb_getval(StoreName,HT),
3756 HashCall, % hash_term(Key,Hash),
3757 lookup_ht1(HT,Hash,Key,SuspsList)
3760 lookup_hash_call(HashType,HT,Key,SuspsList,Lookup),
3763 GetStoreGoal, % nb_getval(StoreName,HT),
3767 ; HashType == inthash ->
3768 multi_hash_store_name(ConstraintSymbol,Index,StoreName),
3769 make_get_store_goal(StoreName,HT,GetStoreGoal),
3770 lookup_hash_call(HashType,HT,Key,SuspsList,Lookup),
3773 GetStoreGoal, % nb_getval(StoreName,HT),
3776 % ; % chr_error(internal,'Index ~w for constraint ~w does not exist!\n',[Index,ConstraintSymbol])
3777 % find alternative index
3778 % -> SubIndex + RestIndex
3779 % -> SubKey + RestKeys
3780 % multi_hash_lookup_goal(ConstraintSymbol,HashType,SubIndex,SubKey,SuspsList,SubGoal),
3781 % instantiate rest goal?
3782 % Goal = (SubGoal,RestGoal)
3786 lookup_hash_call(hash,HT,Key,SuspsList,lookup_ht(HT,Key,SuspsList)).
3787 lookup_hash_call(inthash,HT,Key,SuspsList,lookup_iht(HT,Key,SuspsList)).
3789 specialized_hash_term_call(Constraint,Index,Key,Hash,Call) :-
3791 % This is based on a property of SWI-Prolog's
3792 % hash_term/2 predicate:
3793 % the hash value is stable over repeated invocations
3795 hash_term(Key,Hash),
3797 ; Index = [IndexPos],
3798 get_constraint_type(Constraint,ArgTypes),
3799 nth1(IndexPos,ArgTypes,Type),
3800 unalias_type(Type,NormalType),
3801 memberchk_eq(NormalType,[int,natural]) ->
3802 ( NormalType == int ->
3803 Call = (Hash is abs(Key))
3810 specialize_hash_term(Key,NewKey),
3812 Call = hash_term(NewKey,Hash)
3815 specialize_hash_term(Term,NewTerm) :-
3817 hash_term(Term,NewTerm)
3822 maplist(specialize_hash_term,Args,NewArgs),
3823 NewTerm =.. [F|NewArgs]
3826 multi_hash_lookup_goal(ConstraintSymbol,HashType,Index,Key,SuspsList,Goal) :-
3827 % format(' * lookup of ~w on ~w with ~w.\n',[ConstraintSymbol,Index,Key]),
3828 ( /* chr_pp_flag(experiment,off) ->
3831 actual_atomic_multi_hash_keys(ConstraintSymbol,Index,[Key])
3833 actual_ground_multi_hash_keys(ConstraintSymbol,Index,[Key])
3836 get_constraint_arg_type(ConstraintSymbol,Pos,chr_constants(_))
3840 actual_non_ground_multi_hash_key(ConstraintSymbol,Index)
3843 delay_phase_end(validate_store_type_assumptions,
3844 multi_hash_lookup_body(ConstraintSymbol,HashType,Index,Key,SuspsList,Goal)).
3846 :- chr_constraint actual_atomic_multi_hash_keys/3.
3847 :- chr_option(mode,actual_atomic_multi_hash_keys(+,+,?)).
3849 :- chr_constraint actual_ground_multi_hash_keys/3.
3850 :- chr_option(mode,actual_ground_multi_hash_keys(+,+,?)).
3852 :- chr_constraint actual_non_ground_multi_hash_key/2.
3853 :- chr_option(mode,actual_non_ground_multi_hash_key(+,+)).
3856 actual_atomic_multi_hash_keys(C,Index,Keys)
3857 ==> format('Keys: ~w - ~w : ~w\n', [C,Index,Keys]).
3859 actual_ground_multi_hash_keys(C,Index,Keys)
3860 ==> format('Keys: ~w - ~w : ~w\n', [C,Index,Keys]).
3862 actual_non_ground_multi_hash_key(C,Index)
3863 ==> format('Keys: ~w - ~w : N/A\n', [C,Index]).
3865 actual_atomic_multi_hash_keys(C,Index,Keys1), actual_atomic_multi_hash_keys(C,Index,Keys2)
3866 <=> append(Keys1,Keys2,Keys0),
3868 actual_atomic_multi_hash_keys(C,Index,Keys).
3870 actual_ground_multi_hash_keys(C,Index,Keys1), actual_atomic_multi_hash_keys(C,Index,Keys2)
3871 <=> append(Keys1,Keys2,Keys0),
3873 actual_ground_multi_hash_keys(C,Index,Keys).
3875 actual_ground_multi_hash_keys(C,Index,Keys1), actual_ground_multi_hash_keys(C,Index,Keys2)
3876 <=> append(Keys1,Keys2,Keys0),
3878 actual_ground_multi_hash_keys(C,Index,Keys).
3880 actual_non_ground_multi_hash_key(C,Index) \ actual_non_ground_multi_hash_key(C,Index)
3883 actual_non_ground_multi_hash_key(C,Index) \ actual_atomic_multi_hash_keys(C,Index,_)
3886 actual_non_ground_multi_hash_key(C,Index) \ actual_ground_multi_hash_keys(C,Index,_)
3889 %% multi_hash_lookup_name(+ConstraintSymbol,+Index,-Name)
3891 % Returns predicate name of hash table lookup predicate.
3892 multi_hash_lookup_name(F/A,Index,Name) :-
3893 atom_concat_list(Index,IndexName),
3894 atom_concat_list(['$via1_multi_hash_',F,'___',A,'-',IndexName],Name).
3896 multi_hash_store_name(F/A,Index,Name) :-
3897 get_target_module(Mod),
3898 atom_concat_list(Index,IndexName),
3899 atom_concat_list(['$chr_store_multi_hash_',Mod,'____',F,'___',A,'-',IndexName],Name).
3901 multi_hash_key(FA,Index,Susp,KeyBody,Key) :-
3903 get_dynamic_suspension_term_field(argument(I),FA,Susp,Key,KeyBody)
3905 maplist(get_dynamic_suspension_term_field1(FA,Susp),Index,Keys,Bodies),
3907 list2conj(Bodies,KeyBody)
3910 get_dynamic_suspension_term_field1(FA,Susp,I,KeyI,Goal) :-
3911 get_dynamic_suspension_term_field(argument(I),FA,Susp,KeyI,Goal).
3913 multi_hash_key(C,Head,Index,Susp,VarDict,KeyBody,Key) :-
3915 get_suspension_argument_possibly_in_scope(Head,VarDict,Susp,I,Key,KeyBody)
3917 maplist(get_suspension_argument_possibly_in_scope(Head,VarDict,Susp),Index,Keys,Bodies),
3919 list2conj(Bodies,KeyBody)
3922 get_suspension_argument_possibly_in_scope(Head,VarDict,Susp,Index,Arg,Goal) :-
3923 arg(Index,Head,OriginalArg),
3924 ( lookup_eq(VarDict,OriginalArg,Arg) ->
3929 get_dynamic_suspension_term_field(argument(Index),C,Susp,Arg,Goal)
3932 multi_hash_key_direct(FA,Index,Susp,Key,UsedVars) :-
3936 pairup(Index,Keys,UsedVars),
3940 multi_hash_key_args(Index,Head,KeyArgs) :-
3941 maplist(arg1(Head),Index,KeyArgs).
3943 %-------------------------------------------------------------------------------
3944 atomic_constants_code(C,Index,Constants,L,T) :-
3945 constants_store_index_name(C,Index,IndexName),
3946 maplist(atomic_constant_code(C,Index,IndexName),Constants,Clauses),
3947 append(Clauses,T,L).
3949 atomic_constant_code(C,Index,IndexName,Constant,Clause) :-
3950 constants_store_name(C,Index,Constant,StoreName),
3951 Clause =.. [IndexName,Constant,StoreName].
3953 %-------------------------------------------------------------------------------
3954 ground_constants_code(C,Index,Terms,L,T) :-
3955 constants_store_index_name(C,Index,IndexName),
3956 maplist(constants_store_name(C,Index),Terms,StoreNames),
3958 replicate(N,[],More),
3959 trie_index([Terms|More],StoreNames,IndexName,L,T).
3961 constants_store_name(F/A,Index,Term,Name) :-
3962 get_target_module(Mod),
3963 term_to_atom(Term,Constant),
3964 term_to_atom(Index,IndexAtom),
3965 atom_concat_list(['$chr_store_constants_',Mod,'____',F,'___',A,'___',IndexAtom,'___',Constant],Name).
3967 constants_store_index_name(F/A,Index,Name) :-
3968 get_target_module(Mod),
3969 term_to_atom(Index,IndexAtom),
3970 atom_concat_list(['$chr_store_constants_',Mod,'____',F,'___',A,'___',IndexAtom],Name).
3972 % trie index code {{{
3973 trie_index([Patterns|MorePatterns],Results,Prefix,Clauses,Tail) :-
3974 trie_step(Patterns,Prefix,Prefix,MorePatterns,Results,Clauses,Tail).
3976 trie_step([],_,_,[],[],L,L) :- !.
3977 % length MorePatterns == length Patterns == length Results
3978 trie_step(Patterns,Symbol,Prefix,MorePatterns,Results,Clauses,T) :-
3979 MorePatterns = [List|_],
3981 aggregate_all(set(F/A),
3982 ( member(Pattern,Patterns),
3983 functor(Pattern,F,A)
3987 trie_step_cases(FAs,N1,Patterns,MorePatterns,Results,Symbol,Prefix,Clauses,T).
3989 trie_step_cases([],_,_,_,_,_,_,Clauses,Clauses).
3990 trie_step_cases([FA|FAs],N,Pattern,MorePatterns,Results,Symbol,Prefix,Clauses,Tail) :-
3991 trie_step_case(FA,N,Pattern,MorePatterns,Results,Symbol,Prefix,Clauses,Clauses1),
3992 trie_step_cases(FAs,N,Pattern,MorePatterns,Results,Symbol,Prefix,Clauses1,Tail).
3994 trie_step_case(F/A,N,Patterns,MorePatterns,Results,Symbol,Prefix,[Clause|List],Tail) :-
3995 Clause = (Head :- Body),
3996 /* Head = Symbol(IndexPattern,V2,...,Vn,Result) */
3998 functor(Head,Symbol,N1),
3999 arg(1,Head,IndexPattern),
4000 Head =.. [_,_|RestArgs],
4001 once(append(Vs,[Result],RestArgs)),
4002 /* IndexPattern = F() */
4003 functor(IndexPattern,F,A),
4004 IndexPattern =.. [_|Args],
4005 append(Args,RestArgs,RecArgs),
4006 ( RecArgs == [Result] ->
4007 /* nothing more to match on */
4010 rec_cases(Patterns,_,Results,F/A,_,_,MoreResults),
4011 MoreResults = [Result]
4012 ; /* more things to match on */
4013 rec_cases(Patterns,MorePatterns,Results,F/A,Cases,MoreCases,MoreResults),
4014 ( MoreCases = [OneMoreCase] ->
4015 /* only one more thing to match on */
4018 append([Cases,OneMoreCase,MoreResults],RecArgs)
4020 /* more than one thing to match on */
4024 pairup(Cases,MoreCases,CasePairs),
4025 common_pattern(CasePairs,CommonPatternPair,DiffVars,Differences),
4026 append(Args,Vs,[First|Rest]),
4027 First-Rest = CommonPatternPair,
4028 % Body = RSymbol(DiffVars,Result)
4029 gensym(Prefix,RSymbol),
4030 append(DiffVars,[Result],RecCallVars),
4031 Body =.. [RSymbol|RecCallVars],
4032 maplist(head_tail,Differences,CHs,CTs),
4033 trie_step(CHs,RSymbol,Prefix,CTs,MoreResults,List,Tail)
4037 head_tail([H|T],H,T).
4039 rec_cases([],[],[],_,[],[],[]).
4040 rec_cases([Pattern|Patterns],[MorePattern|MorePatterns],[Result|Results],F/A,Cases,MoreCases,MoreResults) :-
4041 ( functor(Pattern,F,A), Pattern =.. [_|ArgPatterns], append(ArgPatterns,MorePattern,[Case|MoreCase]) ->
4042 Cases = [Case|NCases],
4043 MoreCases = [MoreCase|NMoreCases],
4044 MoreResults = [Result|NMoreResults],
4045 rec_cases(Patterns,MorePatterns,Results,F/A,NCases,NMoreCases,NMoreResults)
4047 rec_cases(Patterns,MorePatterns,Results,F/A,Cases,MoreCases,MoreResults)
4051 %% common_pattern(+terms,-term,-vars,-differences) is det.
4052 common_pattern(Ts,T,Vars,Differences) :-
4054 term_variables(T,Vars),
4055 findall(Vars,member(T,Ts),Differences).
4060 gct_(T1,T2,T,Dict0,Dict) :-
4071 maplist_dcg(gct_,Args1,Args2,Args,Dict0,Dict)
4073 /* T is a variable */
4074 ( lookup_eq(Dict0,T1+T2,T) ->
4075 /* we already have a variable for this difference */
4078 /* T is a fresh variable */
4079 Dict = [(T1+T2)-T|Dict0]
4084 fold1(P,[Head|Tail],Result) :-
4085 fold(Tail,P,Head,Result).
4088 fold([X|Xs],P,Acc,Res) :-
4090 fold(Xs,P,NAcc,Res).
4092 maplist_dcg(P,L1,L2,L) -->
4093 maplist_dcg_(L1,L2,L,P).
4095 maplist_dcg_([],[],[],_) --> [].
4096 maplist_dcg_([X|Xs],[Y|Ys],[Z|Zs],P) -->
4098 maplist_dcg_(Xs,Ys,Zs,P).
4099 %-------------------------------------------------------------------------------
4100 global_list_store_name(F/A,Name) :-
4101 get_target_module(Mod),
4102 atom_concat_list(['$chr_store_global_list_',Mod,'____',F,'___',A],Name).
4103 global_ground_store_name(F/A,Name) :-
4104 get_target_module(Mod),
4105 atom_concat_list(['$chr_store_global_ground_',Mod,'____',F,'___',A],Name).
4106 global_singleton_store_name(F/A,Name) :-
4107 get_target_module(Mod),
4108 atom_concat_list(['$chr_store_global_singleton_',Mod,'____',F,'___',A],Name).
4110 identifier_store_name(TypeName,Name) :-
4111 get_target_module(Mod),
4112 atom_concat_list(['$chr_identifier_lookup_',Mod,'____',TypeName],Name).
4114 :- chr_constraint prolog_global_variable/1.
4115 :- chr_option(mode,prolog_global_variable(+)).
4117 :- chr_constraint prolog_global_variables/1.
4118 :- chr_option(mode,prolog_global_variables(-)).
4120 prolog_global_variable(Name) \ prolog_global_variable(Name) <=> true.
4122 prolog_global_variables(List), prolog_global_variable(Name) <=>
4124 prolog_global_variables(Tail).
4125 prolog_global_variables(List) <=> List = [].
4128 prolog_global_variables_code(Code) :-
4129 prolog_global_variables(Names),
4133 maplist(wrap_in_functor('$chr_prolog_global_variable'),Names,NameDeclarations),
4134 Code = [(:- dynamic user:exception/3),
4135 (:- multifile user:exception/3),
4136 (user:exception(undefined_global_variable,Name,retry) :-
4138 '$chr_prolog_global_variable'(Name),
4139 '$chr_initialization'
4148 % prolog_global_variables_code([]).
4150 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4151 %sbag_member_call(S,L,sysh:mem(S,L)).
4152 sbag_member_call(S,L,'chr sbag_member'(S,L)).
4153 %sbag_member_call(S,L,member(S,L)).
4154 update_mutable_call(A,B,'chr update_mutable'( A, B)).
4155 %update_mutable_call(A,B,setarg(1, B, A)).
4156 create_mutable_call(Value,Mutable,true) :- Mutable = mutable(Value).
4157 % create_mutable_call(Value,Mutable,'chr create_mutable'(Value,Mutable)).
4159 % get_suspension_field(Constraint,Susp,FieldName,Value,(Get0,Get1)) :-
4160 % get_dynamic_suspension_term_field(FieldName,Constraint,Susp,Field,Get0),
4161 % create_get_mutable(Value,Field,Get1).
4163 % update_suspension_field(Constraint,Susp,FieldName,NewValue,(Get,Set)) :-
4164 % get_dynamic_suspension_term_field(FieldName,Constraint,Susp,Field,Get),
4165 % update_mutable_call(NewValue,Field,Set).
4167 % get_update_suspension_field(Constraint,Susp,FieldName,Value,NewValue,Get0,Get1,Set) :-
4168 % get_dynamic_suspension_term_field(FieldName,Constraint,Susp,Field,Get0),
4169 % create_get_mutable_ref(Value,Field,Get1),
4170 % update_mutable_call(NewValue,Field,Set).
4172 % create_static_suspension_field(Constraint,Susp,FieldName,Value,Create) :-
4173 % get_static_suspension_term_field(FieldName,Constraint,Susp,Field),
4174 % create_mutable_call(Value,Field,Create).
4176 % get_static_suspension_field(Constraint,Susp,FieldName,Value,Get) :-
4177 % get_static_suspension_term_field(FieldName,Constraint,Susp,Field),
4178 % create_get_mutable(Value,Field,Get).
4180 % get_update_static_suspension_field(Constraint,Susp,SuspTerm,FieldName,Value,NewValue,Get,Set) :-
4181 % get_static_suspension_term_field(FieldName,Constraint,SuspTerm,Field),
4182 % create_get_mutable_ref(Value,Field,Get),
4183 % update_mutable_call(NewValue,Field,Set).
4185 get_suspension_field(Constraint,Susp,FieldName,Value,Get) :-
4186 get_dynamic_suspension_term_field(FieldName,Constraint,Susp,Value,Get).
4188 update_suspension_field(Constraint,Susp,FieldName,NewValue,Set) :-
4189 set_dynamic_suspension_term_field(FieldName,Constraint,Susp,NewValue,Set).
4191 get_update_suspension_field(Constraint,Susp,FieldName,Value,NewValue,true,Get,Set) :-
4192 get_dynamic_suspension_term_field(FieldName,Constraint,Susp,Value,Get),
4193 set_dynamic_suspension_term_field(FieldName,Constraint,Susp,NewValue,Set).
4195 create_static_suspension_field(Constraint,Susp,FieldName,Value,true) :-
4196 get_static_suspension_term_field(FieldName,Constraint,Susp,Value).
4198 get_static_suspension_field(Constraint,Susp,FieldName,Value,true) :-
4199 get_static_suspension_term_field(FieldName,Constraint,Susp,Value).
4201 get_update_static_suspension_field(Constraint,Susp,SuspTerm,FieldName,Value,NewValue,true,Set) :-
4202 get_static_suspension_term_field(FieldName,Constraint,SuspTerm,Value),
4203 set_dynamic_suspension_term_field(FieldName,Constraint,Susp,NewValue,Set).
4205 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4207 enumerate_stores_code(Constraints,Clause) :-
4208 Head = '$enumerate_constraints'(Constraint),
4209 enumerate_store_bodies(Constraints,Constraint,Bodies),
4210 list2disj(Bodies,Body),
4211 Clause = (Head :- Body).
4213 enumerate_store_bodies([],_,[]).
4214 enumerate_store_bodies([C|Cs],Constraint,L) :-
4216 get_store_type(C,StoreType),
4217 ( enumerate_store_body(StoreType,C,Suspension,SuspensionBody) ->
4220 chr_error(internal,'Could not generate enumeration code for constraint ~w.\n',[C])
4222 get_dynamic_suspension_term_field(arguments,C,Suspension,Arguments,DynamicGoal),
4224 Constraint0 =.. [F|Arguments],
4225 Body = (SuspensionBody, DynamicGoal, Constraint = Constraint0),
4230 enumerate_store_bodies(Cs,Constraint,T).
4232 enumerate_store_body(default,C,Susp,Body) :-
4233 global_list_store_name(C,StoreName),
4234 sbag_member_call(Susp,List,Sbag),
4235 make_get_store_goal(StoreName,List,GetStoreGoal),
4238 GetStoreGoal, % nb_getval(StoreName,List),
4241 % get_constraint_index(C,Index),
4242 % get_target_module(Mod),
4243 % get_max_constraint_index(MaxIndex),
4246 % 'chr default_store'(GlobalStore),
4247 % get_attr(GlobalStore,Mod,Attr)
4250 % NIndex is Index + 1,
4251 % sbag_member_call(Susp,List,Sbag),
4254 % arg(NIndex,Attr,List),
4258 % sbag_member_call(Susp,Attr,Sbag),
4261 % Body = (Body1,Body2).
4262 enumerate_store_body(multi_inthash([Index|_]),C,Susp,Body) :-
4263 multi_inthash_enumerate_store_body(Index,C,Susp,Body).
4264 enumerate_store_body(multi_hash([Index|_]),C,Susp,Body) :-
4265 multi_hash_enumerate_store_body(Index,C,Susp,Body).
4266 enumerate_store_body(atomic_constants(Index,Constants,Completeness),C,Susp,Body) :-
4267 Completeness == complete, % fail if incomplete
4268 maplist(enumerate_constant_store_body(C,Index,Susps),Constants,Disjuncts),
4269 list2disj(Disjuncts, Disjunction),
4270 Body = ( Disjunction, member(Susp,Susps) ).
4271 enumerate_constant_store_body(C,Index,Susps,Constant,nb_getval(StoreName,Susps)) :-
4272 constants_store_name(C,Index,Constant,StoreName).
4274 enumerate_store_body(ground_constants(Index,Constants,Completeness),C,Susp,Body) :-
4275 enumerate_store_body(atomic_constants(Index,Constants,Completeness),C,Susp,Body).
4276 enumerate_store_body(global_ground,C,Susp,Body) :-
4277 global_ground_store_name(C,StoreName),
4278 sbag_member_call(Susp,List,Sbag),
4279 make_get_store_goal(StoreName,List,GetStoreGoal),
4282 GetStoreGoal, % nb_getval(StoreName,List),
4285 enumerate_store_body(var_assoc_store(_,_),C,_,Body) :-
4287 enumerate_store_body(global_singleton,C,Susp,Body) :-
4288 global_singleton_store_name(C,StoreName),
4289 make_get_store_goal(StoreName,Susp,GetStoreGoal),
4292 GetStoreGoal, % nb_getval(StoreName,Susp),
4295 enumerate_store_body(multi_store(STs),C,Susp,Body) :-
4298 enumerate_store_body(ST,C,Susp,Body)
4300 enumerate_store_body(identifier_store(Index),C,Susp,Body) :-
4302 enumerate_store_body(type_indexed_identifier_store(Index,IndexType),C,Susp,Body) :-
4305 multi_inthash_enumerate_store_body(I,C,Susp,B) :-
4306 multi_hash_store_name(C,I,StoreName),
4309 nb_getval(StoreName,HT),
4312 multi_hash_enumerate_store_body(I,C,Susp,B) :-
4313 multi_hash_store_name(C,I,StoreName),
4314 make_get_store_goal(StoreName,HT,GetStoreGoal),
4317 GetStoreGoal, % nb_getval(StoreName,HT),
4321 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4322 % BACKGROUND INFORMATION (declared using :- chr_declaration)
4323 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4330 get_bg_info_answer/1.
4332 background_info(X), background_info(Y) <=>
4333 append(X,Y,XY), background_info(XY).
4334 background_info(X) \ get_bg_info(Q) <=> Q=X.
4335 get_bg_info(Q) <=> Q = [].
4337 background_info(T,I), get_bg_info(A,Q) ==>
4338 copy_term_nat(T,T1),
4341 copy_term_nat(T-I,A-X),
4342 get_bg_info_answer([X]).
4343 get_bg_info_answer(X), get_bg_info_answer(Y) <=>
4344 append(X,Y,XY), get_bg_info_answer(XY).
4346 get_bg_info_answer(X) # Id, get_bg_info(A,Q) <=> Q=X pragma passive(Id).
4347 get_bg_info(_,Q) <=> Q=[]. % no info found on this term
4349 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4358 :- chr_option(mode,prev_guard_list(+,+,+,+,+,+,+,+)).
4359 :- chr_option(mode,prev_guard_list(+,+,+,+,+,+)).
4360 :- chr_option(type_declaration,prev_guard_list(any,any,any,any,any,list)).
4361 :- chr_option(mode,simplify_guards(+)).
4362 :- chr_option(mode,set_all_passive(+)).
4364 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4365 % GUARD SIMPLIFICATION
4366 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4367 % If the negation of the guards of earlier rules entails (part of)
4368 % the current guard, the current guard can be simplified. We can only
4369 % use earlier rules with a head that matches if the head of the current
4370 % rule does, and which make it impossible for the current rule to match
4371 % if they fire (i.e. they shouldn't be propagation rules and their
4372 % head constraints must be subsets of those of the current rule).
4373 % At this point, we know for sure that the negation of the guard
4374 % of such a rule has to be true (otherwise the earlier rule would have
4375 % fired, because of the refined operational semantics), so we can use
4376 % that information to simplify the guard by replacing all entailed
4377 % conditions by true/0. As a consequence, the never-stored analysis
4378 % (in a further phase) will detect more cases of never-stored constraints.
4380 % e.g. c(X),d(Y) <=> X > 0 | ...
4381 % e(X) <=> X < 0 | ...
4382 % c(X) \ d(Y),e(Z) <=> X =< 0, Z >= 0, ... | ...
4386 guard_simplification :-
4387 ( chr_pp_flag(guard_simplification,on) ->
4388 precompute_head_matchings,
4394 % for every rule, we create a prev_guard_list where the last argument
4395 % eventually is a list of the negations of earlier guards
4396 rule(RuleNb,Rule) \ simplify_guards(RuleNb)
4398 Rule = pragma(rule(Head1,Head2,Guard,_B),ids(IDs1,IDs2),_Pragmas,_Name,RuleNb),
4399 append(Head1,Head2,Heads),
4400 make_head_matchings_explicit_not_negated(Heads,MatchingFreeHeads,Matchings),
4401 tree_set_empty(Done),
4402 multiple_occ_constraints_checked(Done),
4403 apply_guard_wrt_term(Heads,Guard,SubstitutedHeads),
4405 append(IDs1,IDs2,IDs),
4406 findall(tuple(C,O,RuleNb)-(-RuleNb),(member(ID,IDs),get_occurrence_from_id(C,O,RuleNb,ID)),HeapData),
4408 insert_list_q(HeapData,EmptyHeap,Heap),
4409 next_prev_rule(Heap,_,Heap1),
4410 next_prev_rule(Heap1,PrevRuleNb,NHeap),
4411 prev_guard_list(RuleNb,PrevRuleNb,NHeap,MatchingFreeHeads,Guard,[],Matchings,[SubstitutedHeads]),
4412 NextRule is RuleNb+1,
4413 simplify_guards(NextRule).
4415 next_prev_rule(Heap,RuleNb,NHeap) :-
4416 ( find_min_q(Heap,_-Priority) ->
4417 Priority = (-RuleNb),
4418 normalize_heap(Heap,Priority,NHeap)
4424 normalize_heap(Heap,Priority,NHeap) :-
4425 ( find_min_q(Heap,_-Priority) ->
4426 delete_min_q(Heap,Heap1,tuple(C,O,_)-_),
4429 get_occurrence(C,NO,RuleNb,_),
4430 insert_q(Heap1,tuple(C,NO,RuleNb)-(-RuleNb),Heap2)
4434 normalize_heap(Heap2,Priority,NHeap)
4444 % The negation of the guard of a non-propagation rule is added
4445 % if its kept head constraints are a subset of the kept constraints of
4446 % the rule we're working on, and its removed head constraints (at least one)
4447 % are a subset of the removed constraints.
4449 rule(PrevRuleNb,PrevRule) \ prev_guard_list(RuleNb,PrevRuleNb,Heap,CurrentHeads,G,GuardList,Matchings,GH)
4451 PrevRule = pragma(rule(H1,H2,PrevGuard,_B),_Ids,_Pragmas,_Name,_PrevRuleNb), % PrevRuleNb == _PrevRuleNb
4453 make_head_matchings_explicit(PrevRuleNb,MatchingFreeHeads,PrevMatchings),
4454 setof(Renaming,chr_translate:head_subset(MatchingFreeHeads,CurrentHeads,Renaming),Renamings)
4456 append(H1,H2,Heads),
4457 compute_derived_info(Renamings,PrevMatchings,MatchingFreeHeads,Heads,PrevGuard,Matchings,CurrentHeads,GH,DerivedInfo,GH_New1),
4458 append(GuardList,DerivedInfo,GL1),
4459 normalize_conj_list(GL1,GL),
4460 append(GH_New1,GH,GH1),
4461 normalize_conj_list(GH1,GH_New),
4462 next_prev_rule(Heap,PrevPrevRuleNb,NHeap),
4463 % PrevPrevRuleNb is PrevRuleNb-1,
4464 prev_guard_list(RuleNb,PrevPrevRuleNb,NHeap,CurrentHeads,G,GL,Matchings,GH_New).
4466 % if this isn't the case, we skip this one and try the next rule
4467 prev_guard_list(RuleNb,N,Heap,H,G,GuardList,M,GH)
4470 next_prev_rule(Heap,N1,NHeap),
4472 prev_guard_list(RuleNb,N1,NHeap,H,G,GuardList,M,GH)
4474 prev_guard_list(RuleNb,H,G,GuardList,M,GH)
4477 prev_guard_list(RuleNb,H,G,GuardList,M,GH)
4481 head_types_modes_condition(GH,H,TypeInfo),
4482 conj2list(TypeInfo,TI),
4483 term_variables(H,HeadVars),
4484 append([chr_pp_headvariables(HeadVars)|TI],GuardList,Info),
4485 normalize_conj_list(Info,InfoL),
4486 append(H,InfoL,RelevantTerms),
4487 add_background_info([G|RelevantTerms],BGInfo),
4488 append(InfoL,BGInfo,AllInfo_),
4489 normalize_conj_list(AllInfo_,AllInfo),
4490 prev_guard_list(RuleNb,H,G,AllInfo,M,[]).
4492 head_types_modes_condition([],H,true).
4493 head_types_modes_condition([GH|GHs],H,(TI1, TI2)) :-
4494 types_modes_condition(H,GH,TI1),
4495 head_types_modes_condition(GHs,H,TI2).
4497 add_background_info(Term,Info) :-
4498 get_bg_info(GeneralInfo),
4499 add_background_info2(Term,TermInfo),
4500 append(GeneralInfo,TermInfo,Info).
4502 add_background_info2(X,[]) :- var(X), !.
4503 add_background_info2([],[]) :- !.
4504 add_background_info2([X|Xs],Info) :- !,
4505 add_background_info2(X,Info1),
4506 add_background_info2(Xs,Infos),
4507 append(Info1,Infos,Info).
4509 add_background_info2(X,Info) :-
4510 (functor(X,_,A), A>0 ->
4512 add_background_info2(XArgs,XArgInfo)
4516 get_bg_info(X,XInfo),
4517 append(XInfo,XArgInfo,Info).
4520 % when all earlier guards are added or skipped, we simplify the guard.
4521 % if it's different from the original one, we change the rule
4523 prev_guard_list(RuleNb,H,G,GuardList,M,[]), rule(RuleNb,Rule)
4525 Rule = pragma(rule(Head1,Head2,G,B),Ids,Pragmas,Name,RuleNb),
4526 G \== true, % let's not try to simplify this ;)
4527 append(M,GuardList,Info),
4528 (% if guard + context is a contradiction, it should be simplified to "fail"
4529 conj2list(G,GL), append(Info,GL,GuardWithContext),
4530 guard_entailment:entails_guard(GuardWithContext,fail) ->
4533 % otherwise we try to remove redundant conjuncts
4534 simplify_guard(G,B,Info,SimpleGuard,NB)
4536 G \== SimpleGuard % only do this if we can change the guard
4538 rule(RuleNb,pragma(rule(Head1,Head2,SimpleGuard,NB),Ids,Pragmas,Name,RuleNb)),
4539 prev_guard_list(RuleNb,H,SimpleGuard,GuardList,M,[]).
4541 %% normalize_conj_list(+List,-NormalList) is det.
4543 % Removes =true= elements and flattens out conjunctions.
4545 normalize_conj_list(List,NormalList) :-
4546 list2conj(List,Conj),
4547 conj2list(Conj,NormalList).
4549 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4550 % AUXILIARY PREDICATES (GUARD SIMPLIFICATION)
4551 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4553 compute_derived_info([],_PrevMatchings,_MatchingFreeHeads,_Heads,_PrevGuard,_Matchings,_H,_GH,[],[]).
4554 compute_derived_info([Renaming1|RestRenamings],PrevMatchings,PrevMatchingFreeHeads,PrevHeads,PrevGuard,Matchings,H,GH,[DerivedInfo1|DerivedInfo2],[GH3|GH_New2]) :-
4555 copy_term(PrevMatchings-PrevGuard,FreshMatchings),
4556 variable_replacement(PrevMatchings-PrevGuard,FreshMatchings,ExtraRenaming),
4557 append(Renaming1,ExtraRenaming,Renaming2),
4558 list2conj(PrevMatchings,Match),
4559 negate_b(Match,HeadsDontMatch),
4560 make_head_matchings_explicit_not_negated2(PrevHeads,PrevMatchingFreeHeads,HeadsMatch),
4561 list2conj(HeadsMatch,HeadsMatchBut),
4562 term_variables(Renaming2,RenVars),
4563 term_variables(PrevMatchings-PrevGuard-HeadsMatch,MGVars),
4564 new_vars(MGVars,RenVars,ExtraRenaming2),
4565 append(Renaming2,ExtraRenaming2,Renaming),
4566 ( PrevGuard == true -> % true can't fail
4567 Info_ = HeadsDontMatch
4569 negate_b(PrevGuard,TheGuardFailed),
4570 Info_ = (HeadsDontMatch ; (HeadsMatchBut, TheGuardFailed))
4572 copy_with_variable_replacement(Info_,DerivedInfo1,Renaming),
4573 copy_with_variable_replacement(PrevGuard,RenamedG2,Renaming),
4574 copy_with_variable_replacement(PrevMatchings,RenamedMatchings_,Renaming),
4575 list2conj(RenamedMatchings_,RenamedMatchings),
4576 apply_guard_wrt_term(H,RenamedG2,GH2),
4577 apply_guard_wrt_term(GH2,RenamedMatchings,GH3),
4578 compute_derived_info(RestRenamings,PrevMatchings,PrevMatchingFreeHeads,PrevHeads,PrevGuard,Matchings,H,GH,DerivedInfo2,GH_New2).
4580 simplify_guard(G,B,Info,SG,NB) :-
4582 % writeq(guard_entailment:simplify_guards(Info,B,LG,SGL,NB)),nl,
4583 guard_entailment:simplify_guards(Info,B,LG,SGL,NB),
4588 new_vars([A|As],RV,ER) :-
4589 ( memberchk_eq(A,RV) ->
4592 ER = [A-NewA,NewA-A|ER2],
4596 %% head_subset(+Subset,+MultiSet,-Renaming) is nondet.
4598 % check if a list of constraints is a subset of another list of constraints
4599 % (multiset-subset), meanwhile computing a variable renaming to convert
4600 % one into the other.
4601 head_subset(H,Head,Renaming) :-
4602 head_subset(H,Head,Renaming,[],_).
4604 head_subset([],Remainder,Renaming,Renaming,Remainder).
4605 head_subset([X|Xs],MultiSet,Renaming,Acc,Remainder) :-
4606 head_member(MultiSet,X,NAcc,Acc,Remainder1),
4607 head_subset(Xs,Remainder1,Renaming,NAcc,Remainder).
4609 % check if A is in the list, remove it from Headleft
4610 head_member([X|Xs],A,Renaming,Acc,Remainder) :-
4611 ( variable_replacement(A,X,Acc,Renaming),
4614 Remainder = [X|RRemainder],
4615 head_member(Xs,A,Renaming,Acc,RRemainder)
4617 %-------------------------------------------------------------------------------%
4618 % memoing code to speed up repeated computation
4620 :- chr_constraint precompute_head_matchings/0.
4622 rule(RuleNb,PragmaRule), precompute_head_matchings ==>
4623 PragmaRule = pragma(rule(H1,H2,_G,_B),_Ids,_Pragmas,_Name,_PrevRuleNb),
4624 append(H1,H2,Heads),
4625 make_head_matchings_explicit_(Heads,MatchingFreeHeads,Matchings),
4626 copy_term_nat(MatchingFreeHeads-Matchings,A-B),
4627 make_head_matchings_explicit_memo_table(RuleNb,A,B).
4629 precompute_head_matchings <=> true.
4631 :- chr_constraint make_head_matchings_explicit_memo_table/3.
4632 :- chr_constraint make_head_matchings_explicit_memo_lookup/3.
4634 :- chr_option(mode,make_head_matchings_explicit_memo_table(+,?,?)).
4635 :- chr_option(mode,make_head_matchings_explicit_memo_lookup(+,?,?)).
4637 make_head_matchings_explicit_memo_table(RuleNb,NHeads,Matchings) \
4638 make_head_matchings_explicit_memo_lookup(RuleNb,Q1,Q2)
4642 make_head_matchings_explicit_memo_lookup(_,_,_) <=> fail.
4644 make_head_matchings_explicit(RuleNb,MatchingFreeHeads,Matchings) :-
4645 make_head_matchings_explicit_memo_lookup(RuleNb,A,B),
4646 copy_term_nat(A-B,MatchingFreeHeads-Matchings).
4647 %-------------------------------------------------------------------------------%
4649 make_head_matchings_explicit_(Heads,MatchingFreeHeads,Matchings) :-
4650 extract_arguments(Heads,Arguments),
4651 make_matchings_explicit(Arguments,FreeVariables,[],[],_,Matchings),
4652 substitute_arguments(Heads,FreeVariables,MatchingFreeHeads).
4654 make_head_matchings_explicit_not_negated(Heads,MatchingFreeHeads,Matchings) :-
4655 extract_arguments(Heads,Arguments),
4656 make_matchings_explicit_not_negated(Arguments,FreshVariables,Matchings),
4657 substitute_arguments(Heads,FreshVariables,MatchingFreeHeads).
4659 make_head_matchings_explicit_not_negated2(Heads,MatchingFreeHeads,Matchings) :-
4660 extract_arguments(Heads,Arguments1),
4661 extract_arguments(MatchingFreeHeads,Arguments2),
4662 make_matchings_explicit_not_negated(Arguments1,Arguments2,Matchings).
4664 %% extract_arguments(+ListOfConstraints,-ListOfVariables) is det.
4666 % Returns list of arguments of given list of constraints.
4667 extract_arguments([],[]).
4668 extract_arguments([Constraint|Constraints],AllArguments) :-
4669 Constraint =.. [_|Arguments],
4670 append(Arguments,RestArguments,AllArguments),
4671 extract_arguments(Constraints,RestArguments).
4673 %% substitute_arguments(+InListOfConstraints,ListOfVariables,-OutListOfConstraints) is det.
4675 % Substitutes arguments of constraints with those in the given list.
4677 substitute_arguments([],[],[]).
4678 substitute_arguments([Constraint|Constraints],Variables,[NConstraint|NConstraints]) :-
4679 functor(Constraint,F,N),
4680 split_at(N,Variables,Arguments,RestVariables),
4681 NConstraint =.. [F|Arguments],
4682 substitute_arguments(Constraints,RestVariables,NConstraints).
4684 make_matchings_explicit([],[],_,MC,MC,[]).
4685 make_matchings_explicit([Arg|Args],[NewVar|NewVars],VarAcc,MatchingCondition,MatchingConditionO,Matchings) :-
4687 ( memberchk_eq(Arg,VarAcc) ->
4688 list2disj(MatchingCondition,MatchingCondition_disj),
4689 Matchings = [(MatchingCondition_disj ; NewVar == Arg)|RestMatchings], % or only = ??
4692 Matchings = RestMatchings,
4694 NVarAcc = [Arg|VarAcc]
4696 MatchingCondition2 = MatchingCondition
4699 Arg =.. [F|RecArgs],
4700 make_matchings_explicit(RecArgs,RecVars,VarAcc,MatchingCondition,MatchingCondition_,RecMatchings),
4701 FlatArg =.. [F|RecVars],
4702 ( RecMatchings == [] ->
4703 Matchings = [functor(NewVar,F,A)|RestMatchings]
4705 list2conj(RecMatchings,ArgM_conj),
4706 list2disj(MatchingCondition,MatchingCondition_disj),
4707 ArgM_ = (NewVar \= FlatArg ; MatchingCondition_disj ; ArgM_conj),
4708 Matchings = [ functor(NewVar,F,A) , ArgM_|RestMatchings]
4710 MatchingCondition2 = [ NewVar \= FlatArg |MatchingCondition_],
4711 term_variables(Args,ArgVars),
4712 append(ArgVars,VarAcc,NVarAcc)
4714 make_matchings_explicit(Args,NewVars,NVarAcc,MatchingCondition2,MatchingConditionO,RestMatchings).
4717 %% make_matchings_explicit_not_negated(+ListOfTerms,-ListOfVariables,-ListOfMatchings) is det.
4719 % Returns list of new variables and list of pairwise unifications between given list and variables.
4721 make_matchings_explicit_not_negated([],[],[]).
4722 make_matchings_explicit_not_negated([X|Xs],[Var|Vars],Matchings) :-
4723 Matchings = [Var = X|RMatchings],
4724 make_matchings_explicit_not_negated(Xs,Vars,RMatchings).
4726 %% apply_guard_wrt_term(+ListOfConstraints,+Goal,-NewListOfConstraints) is det.
4728 % (Partially) applies substitutions of =Goal= to given list.
4730 apply_guard_wrt_term([],_Guard,[]).
4731 apply_guard_wrt_term([Term|RH],Guard,[NTerm|RGH]) :-
4733 apply_guard_wrt_variable(Guard,Term,NTerm)
4736 apply_guard_wrt_term(HArgs,Guard,NewHArgs),
4737 NTerm =.. [F|NewHArgs]
4739 apply_guard_wrt_term(RH,Guard,RGH).
4741 %% apply_guard_wrt_variable(+Goal,+Variable,-NVariable) is det.
4743 % (Partially) applies goal =Guard= wrt variable.
4745 apply_guard_wrt_variable((Guard1,Guard2),Variable,NVariable) :- !,
4746 apply_guard_wrt_variable(Guard1,Variable,NVariable1),
4747 apply_guard_wrt_variable(Guard2,NVariable1,NVariable).
4748 apply_guard_wrt_variable(Guard,Variable,NVariable) :-
4749 ( Guard = (X = Y), Variable == X ->
4751 ; Guard = functor(AVariable,Functor,Arity), Variable == AVariable, ground(Functor), ground(Arity) ->
4752 functor(NVariable,Functor,Arity)
4754 NVariable = Variable
4758 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4759 % ALWAYS FAILING GUARDS
4760 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4762 prev_guard_list(RuleNb,H,G,GuardList,M,[]),rule(RuleNb,Rule)
4764 chr_pp_flag(check_impossible_rules,on),
4765 Rule = pragma(rule(_,_,G,_),_Ids,_Pragmas,_Name,RuleNb),
4767 append(M,GuardList,Info),
4768 append(Info,GL,GuardWithContext),
4769 guard_entailment:entails_guard(GuardWithContext,fail)
4771 chr_warning(weird_program,'Heads will never match or guard will always fail in ~@.\n\tThis rule will never fire!\n',[format_rule(Rule)]),
4772 set_all_passive(RuleNb).
4774 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4775 % HEAD SIMPLIFICATION
4776 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4778 % now we check the head matchings (guard may have been simplified meanwhile)
4779 prev_guard_list(RuleNb,H,G,GuardList,M,[]) \ rule(RuleNb,Rule)
4781 Rule = pragma(rule(Head1,Head2,G,B),Ids,Pragmas,Name,RuleNb),
4782 simplify_heads(M,GuardList,G,B,NewM,NewB),
4784 extract_arguments(Head1,VH1),
4785 extract_arguments(Head2,VH2),
4786 extract_arguments(H,VH),
4787 replace_some_heads(VH1,VH2,VH,NewM,H1,H2,G,B,NewB_),
4788 substitute_arguments(Head1,H1,NewH1),
4789 substitute_arguments(Head2,H2,NewH2),
4790 append(NewB,NewB_,NewBody),
4791 list2conj(NewBody,BodyMatchings),
4792 NewRule = pragma(rule(NewH1,NewH2,G,(BodyMatchings,B)),Ids,Pragmas,Name,RuleNb),
4793 (Head1 \== NewH1 ; Head2 \== NewH2 )
4795 rule(RuleNb,NewRule).
4797 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4798 % AUXILIARY PREDICATES (HEAD SIMPLIFICATION)
4799 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4801 replace_some_heads(H1,H2,NH,[],H1,H2,G,Body,[]) :- !.
4802 replace_some_heads([],[H2|RH2],[NH|RNH],[M|RM],[],[H2_|RH2_],G,Body,NewB) :- !,
4805 replace_some_heads([],RH2,RNH,RM,[],RH2_,G,Body,NewB)
4807 (M = functor(X,F,A), NH == X ->
4813 H2 =.. [F|OrigArgs],
4814 use_same_args(OrigArgs,A_args,A_args_,G,Body,NewB1),
4817 replace_some_heads([],RH2,RNH,RM,[],RH2_,G,Body,NewB2),
4818 append(NewB1,NewB2,NewB)
4821 replace_some_heads([],RH2,RNH,[M|RM],[],RH2_,G,Body,NewB)
4825 replace_some_heads([H1|RH1],H2,[NH|RNH],[M|RM],[H1_|RH1_],H2_,G,Body,NewB) :- !,
4828 replace_some_heads(RH1,H2,RNH,RM,RH1_,H2_,G,Body,NewB)
4830 (M = functor(X,F,A), NH == X ->
4836 H1 =.. [F|OrigArgs],
4837 use_same_args(OrigArgs,A_args,A_args_,G,Body,NewB1),
4840 replace_some_heads(RH1,H2,RNH,RM,RH1_,H2_,G,Body,NewB2),
4841 append(NewB1,NewB2,NewB)
4844 replace_some_heads(RH1,H2,RNH,[M|RM],RH1_,H2_,G,Body,NewB)
4848 use_same_args([],[],[],_,_,[]).
4849 use_same_args([OA|ROA],[NA|RNA],[Out|ROut],G,Body,NewB) :-
4852 use_same_args(ROA,RNA,ROut,G,Body,NewB).
4853 use_same_args([OA|ROA],[NA|RNA],[Out|ROut],G,Body,NewB) :-
4855 ( common_variables(OA,Body) ->
4856 NewB = [NA = OA|NextB]
4861 use_same_args(ROA,RNA,ROut,G,Body,NextB).
4864 simplify_heads([],_GuardList,_G,_Body,[],[]).
4865 simplify_heads([M|RM],GuardList,G,Body,NewM,NewB) :-
4867 ( (nonvar(B) ; common_variables(B,RM-GuardList)),
4868 guard_entailment:entails_guard(GuardList,(A=B)) ->
4869 ( common_variables(B,G-RM-GuardList) ->
4873 ( common_variables(B,Body) ->
4874 NewB = [A = B|NextB]
4881 ( nonvar(B), functor(B,BFu,BAr),
4882 guard_entailment:entails_guard([functor(A,BFu,BAr)|GuardList],(A=B)) ->
4884 ( common_variables(B,G-RM-GuardList) ->
4887 NewM = [functor(A,BFu,BAr)|NextM]
4894 simplify_heads(RM,[M|GuardList],G,Body,NextM,NextB).
4896 common_variables(B,G) :-
4897 term_variables(B,BVars),
4898 term_variables(G,GVars),
4899 intersect_eq(BVars,GVars,L),
4903 set_all_passive(RuleNb), occurrence(_,_,RuleNb,ID,_) ==> passive(RuleNb,ID).
4904 set_all_passive(_) <=> true.
4908 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4909 % OCCURRENCE SUBSUMPTION
4910 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4913 first_occ_in_rule/4,
4916 :- chr_option(mode,first_occ_in_rule(+,+,+,+)).
4917 :- chr_option(mode,next_occ_in_rule(+,+,+,+,+,+)).
4919 :- chr_constraint multiple_occ_constraints_checked/1.
4920 :- chr_option(mode,multiple_occ_constraints_checked(+)).
4922 prev_guard_list(RuleNb,H,G,GuardList,M,[]),
4923 occurrence(C,O,RuleNb,ID,_),
4924 occurrence(C,O2,RuleNb,ID2,_),
4927 multiple_occ_constraints_checked(Done)
4930 chr_pp_flag(occurrence_subsumption,on),
4931 Rule = pragma(rule(H1,H2,_G,_B),_Ids,_Pragmas,_Name,_RuleNb), % RuleNb == _RuleNb
4933 \+ tree_set_memberchk(C,Done)
4935 first_occ_in_rule(RuleNb,C,O,ID),
4936 tree_set_add(Done,C,NDone),
4937 multiple_occ_constraints_checked(NDone).
4939 % Find first occurrence of constraint =C= in rule =RuleNb=
4940 occurrence(C,O,RuleNb,ID,_) \ first_occ_in_rule(RuleNb,C,O2,_)
4944 first_occ_in_rule(RuleNb,C,O,ID).
4946 first_occ_in_rule(RuleNb,C,O,ID_o1)
4949 functor(FreshHead,F,A),
4950 next_occ_in_rule(RuleNb,C,O,ID_o1,[],FreshHead).
4952 % Skip passive occurrences.
4953 passive(RuleNb,ID_o2), occurrence(C,O2,RuleNb,ID_o2,_) \ next_occ_in_rule(RuleNb,C,O,ID_o1,Cond,FH)
4957 next_occ_in_rule(RuleNb,C,O2,ID_o1,NewCond,FH).
4959 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)
4962 Rule = pragma(rule(H1,H2,G,B),ids(ID1,ID2),_Pragmas,_Name,RuleNb)
4964 append(H1,H2,Heads),
4965 add_failing_occ(Rule,Heads,H,ID_o1,ExtraCond,FH,M,C,Repl),
4966 ( ExtraCond == [chr_pp_void_info] ->
4967 next_occ_in_rule(RuleNb,C,O2,ID_o2,Cond,FH)
4969 append(ExtraCond,Cond,NewCond),
4970 add_failing_occ(Rule,Heads,H,ID_o2,CheckCond,FH,M,C,Repl2),
4971 copy_term(GuardList,FGuardList),
4972 variable_replacement(GuardList,FGuardList,GLRepl),
4973 copy_with_variable_replacement(GuardList,GuardList2,Repl),
4974 copy_with_variable_replacement(GuardList,GuardList3_,Repl2),
4975 copy_with_variable_replacement(GuardList3_,GuardList3,GLRepl),
4976 append(NewCond,GuardList2,BigCond),
4977 append(BigCond,GuardList3,BigCond2),
4978 copy_with_variable_replacement(M,M2,Repl),
4979 copy_with_variable_replacement(M,M3,Repl2),
4980 append(M3,BigCond2,BigCond3),
4981 append([chr_pp_active_constraint(FH)|M2],BigCond3,Info),
4982 list2conj(CheckCond,OccSubsum),
4983 copy_term((NewCond,BigCond2,Info,OccSubsum,FH),(NewCond2,BigCond2_,Info2,OccSubsum2,FH2)),
4984 ( OccSubsum \= chr_pp_void_info ->
4985 ( guard_entailment:entails_guard(Info2,OccSubsum2) ->
4986 passive(RuleNb,ID_o2)
4993 next_occ_in_rule(RuleNb,C,O2,ID_o2,NewCond,FH)
4997 next_occ_in_rule(RuleNb,C,O,ID,Cond,Args)
5001 prev_guard_list(RuleNb,H,G,GuardList,M,[]), multiple_occ_constraints_checked(Done)
5005 add_failing_occ(Rule,Heads,NH,ID_o1,FailCond,FH,M,C,Repl) :-
5006 Rule = pragma(rule(H1,H2,G,B),ids(ID1,ID2),_Pragmas,_Name,RuleNb),
5007 append(ID2,ID1,IDs),
5008 missing_partner_cond(Heads,NH,IDs,ID_o1,MPCond,H,C),
5009 copy_term((H,Heads,NH),(FH2,FHeads,NH2)),
5010 variable_replacement((H,Heads,NH),(FH2,FHeads,NH2),Repl),
5011 copy_with_variable_replacement(G,FG,Repl),
5012 extract_explicit_matchings(FG,FG2),
5013 negate_b(FG2,NotFG),
5014 copy_with_variable_replacement(MPCond,FMPCond,Repl),
5015 ( subsumes(FH,FH2) ->
5016 FailCond = [(NotFG;FMPCond)]
5018 % in this case, not much can be done
5019 % e.g. c(f(...)), c(g(...)) <=> ...
5020 FailCond = [chr_pp_void_info]
5023 missing_partner_cond([],[],[],ID_o1,fail,H2,C).
5024 missing_partner_cond([H|Hs],[H2|H2s],[ID_o1|IDs],ID_o1,Cond,H,C) :- !,
5025 missing_partner_cond(Hs,H2s,IDs,ID_o1,Cond,H,C).
5026 missing_partner_cond([H|Hs],[NH|NHs],[ID|IDs],ID_o1,Cond,H2,F/A) :-
5027 Cond = (chr_pp_not_in_store(H);Cond1),
5028 missing_partner_cond(Hs,NHs,IDs,ID_o1,Cond1,H2,F/A).
5030 extract_explicit_matchings((A,B),D) :- !,
5031 ( extract_explicit_matchings(A) ->
5032 extract_explicit_matchings(B,D)
5035 extract_explicit_matchings(B,E)
5037 extract_explicit_matchings(A,D) :- !,
5038 ( extract_explicit_matchings(A) ->
5044 extract_explicit_matchings(A=B) :-
5045 var(A), var(B), !, A=B.
5046 extract_explicit_matchings(A==B) :-
5047 var(A), var(B), !, A=B.
5049 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5051 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5057 get_type_definition/2,
5058 get_constraint_type/2.
5061 :- chr_option(mode,type_definition(?,?)).
5062 :- chr_option(mode,get_type_definition(?,?)).
5063 :- chr_option(mode,type_alias(?,?)).
5064 :- chr_option(mode,constraint_type(+,+)).
5065 :- chr_option(mode,get_constraint_type(+,-)).
5067 assert_constraint_type(Constraint,ArgTypes) :-
5068 ( ground(ArgTypes) ->
5069 constraint_type(Constraint,ArgTypes)
5071 chr_error(type_error,'Declared argument types "~w" for constraint "~w" must be ground!\n',[ArgTypes,Constraint])
5074 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5075 % Consistency checks of type aliases
5077 type_alias(T1,T2) <=>
5080 chr_error(type_error,'Variable alias definition: "~w".\n',[(:- chr_type T1 == T2)]).
5082 type_alias(T1,T2) <=>
5085 chr_error(type_error,'Variable alias definition: "~w".\n',[(:- chr_type T1 == T2)]).
5087 type_alias(T,T2) <=>
5090 copy_term((T,T2),(X,Y)), subsumes(X,Y)
5092 chr_error(type_error,'Cyclic alias definition: "~w".\n',[(T == T2)]).
5094 type_alias(T1,A1), type_alias(T2,A2) <=>
5099 copy_term_nat(T1,T1_),
5100 copy_term_nat(T2,T2_),
5102 chr_error(type_error,
5103 '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_]).
5105 type_alias(T,B) \ type_alias(X,T2) <=>
5108 copy_term_nat((X,T2,T,B),(X2,T3,T1,D1)),
5111 % chr_info(type_information,'Inferring `~w\' from `~w\' and `~w\'.\n',[X2==D1,X==T2,T==B]),
5114 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5115 % Consistency checks of type definitions
5117 type_definition(T1,_), type_definition(T2,_)
5119 functor(T1,F,A), functor(T2,F,A)
5121 chr_error(type_error,'Multiple definitions for type: ~w/~w.\n',[F,A]).
5123 type_definition(T1,_), type_alias(T2,_)
5125 functor(T1,F,A), functor(T2,F,A)
5127 chr_error(type_error,'Multiple definitions for type, once in a type definition and once as a type alias: ~w/~w.\n',[F,A]).
5129 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5130 %% get_type_definition(+Type,-Definition) is semidet.
5131 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5133 get_type_definition(T,Def)
5137 chr_error(type_error,'Non-ground type in constraint definition: "~w".\n',[T]).
5139 type_alias(T,D) \ get_type_definition(T2,Def)
5141 nonvar(T),nonvar(T2),functor(T,F,A),functor(T2,F,A),
5142 copy_term_nat((T,D),(T1,D1)),T1=T2
5144 ( get_type_definition(D1,Def) ->
5147 chr_error(type_error,'Could not find type definition for "~w" (accessed via alias "~w").\n',[D1,T1]), fail
5150 type_definition(T,D) \ get_type_definition(T2,Def)
5152 nonvar(T),nonvar(T2),functor(T,F,A),functor(T2,F,A),
5153 copy_term_nat((T,D),(T1,D1)),T1=T2
5157 get_type_definition(Type,Def)
5159 atomic_builtin_type(Type,_,_)
5163 get_type_definition(Type,Def)
5165 compound_builtin_type(Type,_,_,_)
5169 get_type_definition(X,Y) <=> fail.
5171 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5172 %% get_type_definition_det(+Type,-Definition) is det.
5173 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5174 get_type_definition_det(Type,Definition) :-
5175 ( get_type_definition(Type,Definition) ->
5178 chr_error(type,'Could not find type definition for type `~w\'.\n',[Type])
5181 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5182 %% get_constraint_type(+ConstraintSymbol,-Types) is semidet.
5184 % Return argument types of =ConstraintSymbol=, but fails if none where
5186 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5187 constraint_type(C,T) \ get_constraint_type(C,Type) <=> Type = T.
5188 get_constraint_type(_,_) <=> fail.
5190 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5191 %% get_constraint_type_det(+ConstraintSymbol,-Types) is det.
5193 % Like =get_constraint_type/2=, but returns list of =any= types when
5194 % no types are declared.
5195 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5196 get_constraint_type_det(ConstraintSymbol,Types) :-
5197 ( get_constraint_type(ConstraintSymbol,Types) ->
5200 ConstraintSymbol = _ / N,
5201 replicate(N,any,Types)
5203 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5204 %% unalias_type(+Alias,-Type) is det.
5206 % Follows alias chain until base type is reached.
5207 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5208 :- chr_constraint unalias_type/2.
5211 unalias_type(Alias,BaseType)
5218 type_alias(AliasProtoType,ProtoType) \ unalias_type(Alias,BaseType)
5220 nonvar(AliasProtoType),
5222 functor(AliasProtoType,F,A),
5224 copy_term_nat((AliasProtoType,ProtoType),(AliasInstance,Type)),
5225 Alias = AliasInstance
5227 unalias_type(Type,BaseType).
5229 unalias_type_definition @
5230 type_definition(ProtoType,Definition) \ unalias_type(Alias,BaseType)
5234 functor(ProtoType,F,A),
5239 unalias_atomic_builtin @
5240 unalias_type(Alias,BaseType)
5242 atomic_builtin_type(Alias,_,_)
5246 unalias_compound_builtin @
5247 unalias_type(Alias,BaseType)
5249 compound_builtin_type(Alias,_,_,_)
5253 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5254 %% types_modes_condition(+Heads,+UnrollHeads,-Condition) is det.
5255 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5256 :- chr_constraint types_modes_condition/3.
5257 :- chr_option(mode,types_modes_condition(+,+,?)).
5258 :- chr_option(type_declaration,types_modes_condition(list,list,goal)).
5260 types_modes_condition([],[],T) <=> T=true.
5262 constraint_mode(F/A,Modes) \ types_modes_condition([Head|Heads],[UnrollHead|UnrollHeads],Condition)
5267 Condition = (ModesCondition, TypesCondition, RestCondition),
5268 modes_condition(Modes,Args,ModesCondition),
5269 get_constraint_type_det(F/A,Types),
5270 UnrollHead =.. [_|RealArgs],
5271 types_condition(Types,Args,RealArgs,Modes,TypesCondition),
5272 types_modes_condition(Heads,UnrollHeads,RestCondition).
5274 types_modes_condition([Head|_],_,_)
5277 chr_error(internal,'Mode information missing for ~w.\n',[F/A]).
5280 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5281 %% modes_condition(+Modes,+Args,-Condition) is det.
5283 % Return =Condition= on =Args= that checks =Modes=.
5284 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5285 modes_condition([],[],true).
5286 modes_condition([Mode|Modes],[Arg|Args],Condition) :-
5288 Condition = ( ground(Arg) , RCondition )
5290 Condition = ( var(Arg) , RCondition )
5292 Condition = RCondition
5294 modes_condition(Modes,Args,RCondition).
5296 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5297 %% types_condition(+Types,+Args,+UnrollArgs,+Modes,-Condition) is det.
5299 % Return =Condition= on =Args= that checks =Types= given =Modes=.
5300 % =UnrollArgs= controls the depth of type definition unrolling.
5301 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5302 types_condition([],[],[],[],true).
5303 types_condition([Type|Types],[Arg|Args],[UnrollArg|UnrollArgs],[Mode|Modes],(DisjTypeConditionList,RCondition)) :-
5305 TypeConditionList = [true] % TypeConditionList = [var(Arg)] already encoded in modes_condition
5307 get_type_definition_det(Type,Def),
5308 type_condition(Def,Arg,UnrollArg,Mode,TypeConditionList1),
5310 TypeConditionList = TypeConditionList1
5312 TypeConditionList = [(\+ ground(Arg))|TypeConditionList1]
5315 list2disj(TypeConditionList,DisjTypeConditionList),
5316 types_condition(Types,Args,UnrollArgs,Modes,RCondition).
5318 type_condition([],_,_,_,[]).
5319 type_condition([DefCase|DefCases],Arg,UnrollArg,Mode,[Condition|Conditions]) :-
5321 chr_error(type,'Unexpected variable type in type definition!\n',[]) % Condition = true
5322 ; atomic_builtin_type(DefCase,Arg,Condition) ->
5324 ; compound_builtin_type(DefCase,Arg,Condition,_) ->
5327 type_def_case_condition(DefCase,Arg,UnrollArg,Mode,Condition)
5329 type_condition(DefCases,Arg,UnrollArg,Mode,Conditions).
5331 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5332 :- chr_type atomic_builtin_type ---> any
5339 ; chr_identifier(any)
5340 ; /* all possible values are given */
5342 ; /* all possible values appear in rule heads;
5343 to distinguish between multiple chr_constants
5346 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5348 atomic_builtin_type(any,_Arg,true).
5349 atomic_builtin_type(dense_int,Arg,(integer(Arg),Arg>=0)).
5350 atomic_builtin_type(int,Arg,integer(Arg)).
5351 atomic_builtin_type(number,Arg,number(Arg)).
5352 atomic_builtin_type(float,Arg,float(Arg)).
5353 atomic_builtin_type(natural,Arg,(integer(Arg),Arg>=0)).
5354 atomic_builtin_type(chr_identifier,_Arg,true).
5356 compound_builtin_type(chr_constants(_),_Arg,true,true).
5357 compound_builtin_type(chr_identifier(_),_Arg,true,true).
5358 compound_builtin_type(chr_enum(Constants),Arg,(ground(Arg), memberchk(Arg,Constants)),
5359 once(( member(Constant,Constants),
5360 unifiable(Arg,Constant,_)
5365 type_def_case_condition(DefCase,Arg,UnrollArg,Mode,Condition) :-
5366 ( nonvar(DefCase) ->
5367 functor(DefCase,F,A),
5369 Condition = (Arg = DefCase)
5371 Condition = functor(Arg,F,A)
5372 ; functor(UnrollArg,F,A) ->
5373 Condition = (functor(Arg,F,A),Arg=Template,ArgsCondition),
5374 DefCase =.. [_|ArgTypes],
5375 UnrollArg =.. [_|UnrollArgs],
5376 functor(Template,F,A),
5377 Template =.. [_|TemplateArgs],
5378 replicate(A,Mode,ArgModes),
5379 types_condition(ArgTypes,TemplateArgs,UnrollArgs,ArgModes,ArgsCondition)
5381 Condition = functor(Arg,F,A)
5384 chr_error(internal,'Illegal type definition (must be nonvar).\n',[])
5388 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5389 % STATIC TYPE CHECKING
5390 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5391 % Checks head constraints and CHR constraint calls in bodies.
5394 % - type clashes involving built-in types
5395 % - Prolog built-ins in guard and body
5396 % - indicate position in terms in error messages
5397 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5399 static_type_check/0.
5402 % 1. Check the declared types
5404 constraint_type(Constraint,ArgTypes), static_type_check
5407 ( member(ArgType,ArgTypes), sub_term(ArgType,Type) ),
5408 ( get_type_definition(Type,_) ->
5411 chr_error(type_error,'Undefined type "~w" used in type declaration of "~w".\n',[Type,Constraint])
5415 % 2. Check the rules
5417 :- chr_type type_error_src ---> head(any) ; body(any).
5419 rule(_,Rule), static_type_check
5421 copy_term_nat(Rule,RuleCopy),
5422 RuleCopy = pragma(rule(Head1,Head2,G,Body),ids(IDs1,IDs2),Pragmas,Name,RuleNb),
5425 ( static_type_check_heads(Head1),
5426 static_type_check_heads(Head2),
5427 conj2list(Body,GoalList),
5428 static_type_check_body(GoalList)
5431 ( Error = invalid_functor(Src,Term,Type) ->
5432 chr_error(type_error,'Invalid functor in ~@ of ~@:\n\t\tfound `~w\',\n\t\texpected type `~w\'!\n',
5433 [chr_translate:format_src(Src),format_rule(Rule),Term,Type])
5434 ; Error = type_clash(Var,Src1,Src2,Type1,Type2) ->
5435 chr_error(type_error,'Type clash for variable ~w in ~@:\n\t\texpected type ~w in ~@\n\t\texpected type ~w in ~@\n',
5436 [Var,format_rule(Rule),Type1,chr_translate:format_src(Src1),Type2,chr_translate:format_src(Src2)])
5439 fail % cleanup constraints
5445 static_type_check <=> true.
5447 static_type_check_heads([]).
5448 static_type_check_heads([Head|Heads]) :-
5449 static_type_check_head(Head),
5450 static_type_check_heads(Heads).
5452 static_type_check_head(Head) :-
5454 get_constraint_type_det(F/A,Types),
5456 maplist(static_type_check_term(head(Head)),Args,Types).
5458 static_type_check_body([]).
5459 static_type_check_body([Goal|Goals]) :-
5461 get_constraint_type_det(F/A,Types),
5463 maplist(static_type_check_term(body(Goal)),Args,Types),
5464 static_type_check_body(Goals).
5466 :- chr_constraint static_type_check_term/3.
5467 :- chr_option(mode,static_type_check_term(?,?,?)).
5468 :- chr_option(type_declaration,static_type_check_term(type_error_src,any,any)).
5470 static_type_check_term(Src,Term,Type)
5474 static_type_check_var(Src,Term,Type).
5475 static_type_check_term(Src,Term,Type)
5477 atomic_builtin_type(Type,Term,Goal)
5482 throw(type_error(invalid_functor(Src,Term,Type)))
5484 static_type_check_term(Src,Term,Type)
5486 compound_builtin_type(Type,Term,_,Goal)
5491 throw(type_error(invalid_functor(Src,Term,Type)))
5493 type_alias(AType,ADef) \ static_type_check_term(Src,Term,Type)
5498 copy_term_nat(AType-ADef,Type-Def),
5499 static_type_check_term(Src,Term,Def).
5501 type_definition(AType,ADef) \ static_type_check_term(Src,Term,Type)
5506 copy_term_nat(AType-ADef,Type-Variants),
5507 functor(Term,TF,TA),
5508 ( member(Variant,Variants), functor(Variant,TF,TA) ->
5510 Variant =.. [_|Types],
5511 maplist(static_type_check_term(Src),Args,Types)
5513 throw(type_error(invalid_functor(Src,Term,Type)))
5516 static_type_check_term(Src,Term,Type)
5518 chr_error(internal,'Undefined type ~w while type checking term ~w in ~@.\n',[Type,Term,chr_translate:format_src(Src)]).
5520 :- chr_constraint static_type_check_var/3.
5521 :- chr_option(mode,static_type_check_var(?,-,?)).
5522 :- chr_option(type_declaration,static_type_check_term(type_error_src,any,any)).
5524 type_alias(AType,ADef) \ static_type_check_var(Src,Var,Type)
5529 copy_term_nat(AType-ADef,Type-Def),
5530 static_type_check_var(Src,Var,Def).
5532 static_type_check_var(Src,Var,Type)
5534 atomic_builtin_type(Type,_,_)
5536 static_atomic_builtin_type_check_var(Src,Var,Type).
5538 static_type_check_var(Src,Var,Type)
5540 compound_builtin_type(Type,_,_,_)
5545 static_type_check_var(Src1,Var,Type1), static_type_check_var(Src2,Var,Type2)
5549 throw(type_error(type_clash(Var,Src1,Src2,Type1,Type2))).
5551 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5552 %% static_atomic_builtin_type_check_var(+type_error_src,-Var,+atomic_builtin_type)
5553 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5554 :- chr_constraint static_atomic_builtin_type_check_var/3.
5555 :- chr_option(mode,static_type_check_var(?,-,+)).
5556 :- chr_option(type_declaration,static_type_check_term(type_error_src,any,atomic_builtin_type)).
5558 static_atomic_builtin_type_check_var(_,_,any) <=> true.
5559 static_atomic_builtin_type_check_var(_,Var,BuiltinType) \ static_atomic_builtin_type_check_var(_,Var,BuiltinType)
5562 static_atomic_builtin_type_check_var(_,Var,float) \ static_atomic_builtin_type_check_var(_,Var,number)
5565 static_atomic_builtin_type_check_var(_,Var,int) \ static_atomic_builtin_type_check_var(_,Var,number)
5568 static_atomic_builtin_type_check_var(_,Var,natural) \ static_atomic_builtin_type_check_var(_,Var,number)
5571 static_atomic_builtin_type_check_var(_,Var,dense_int) \ static_atomic_builtin_type_check_var(_,Var,number)
5574 static_atomic_builtin_type_check_var(_,Var,natural) \ static_atomic_builtin_type_check_var(_,Var,int)
5577 static_atomic_builtin_type_check_var(_,Var,dense_int) \ static_atomic_builtin_type_check_var(_,Var,int)
5580 static_atomic_builtin_type_check_var(_,Var,dense_int) \ static_atomic_builtin_type_check_var(_,Var,natural)
5583 static_atomic_builtin_type_check_var(Src1,Var,Type1), static_atomic_builtin_type_check_var(Src2,Var,Type2)
5585 throw(type_error(type_clash(Var,Src1,Src2,Type1,Type2))).
5587 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5588 %% format_src(+type_error_src) is det.
5589 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5590 format_src(head(Head)) :- format('head ~w',[Head]).
5591 format_src(body(Goal)) :- format('body goal ~w',[Goal]).
5593 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5594 % Dynamic type checking
5595 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5598 dynamic_type_check/0,
5599 dynamic_type_check_clauses/1,
5600 get_dynamic_type_check_clauses/1.
5602 generate_dynamic_type_check_clauses(Clauses) :-
5603 ( chr_pp_flag(debugable,on) ->
5605 get_dynamic_type_check_clauses(Clauses0),
5607 [('$dynamic_type_check'(Type,Term) :-
5608 throw(error(type_error(Type,Term),context(_,'CHR Runtime Type Error')))
5615 type_definition(T,D), dynamic_type_check
5617 copy_term_nat(T-D,Type-Definition),
5618 maplist(dynamic_type_check_clause(Type),Definition,DynamicChecks),
5619 dynamic_type_check_clauses(DynamicChecks).
5620 type_alias(A,B), dynamic_type_check
5622 copy_term_nat(A-B,Alias-Body),
5623 dynamic_type_check_alias_clause(Alias,Body,Clause),
5624 dynamic_type_check_clauses([Clause]).
5626 dynamic_type_check <=>
5628 ('$dynamic_type_check'(Type,Term) :- Goal),
5629 ( atomic_builtin_type(Type,Term,Goal) ; compound_builtin_type(Type,Term,Goal,_) ),
5632 dynamic_type_check_clauses(BuiltinChecks).
5634 dynamic_type_check_clause(T,DC,Clause) :-
5635 copy_term(T-DC,Type-DefinitionClause),
5636 functor(DefinitionClause,F,A),
5638 DefinitionClause =.. [_|DCArgs],
5639 Term =.. [_|TermArgs],
5640 maplist(dynamic_type_check_call,DCArgs,TermArgs,RecursiveCallList),
5641 list2conj(RecursiveCallList,RecursiveCalls),
5643 '$dynamic_type_check'(Type,Term) :-
5647 dynamic_type_check_alias_clause(Alias,Body,Clause) :-
5649 '$dynamic_type_check'(Alias,Term) :-
5650 '$dynamic_type_check'(Body,Term)
5653 dynamic_type_check_call(Type,Term,Call) :-
5654 % ( nonvar(Type), atomic_builtin_type(Type,Term,Goal) ->
5655 % Call = when(nonvar(Term),Goal)
5656 % ; nonvar(Type), compound_builtin_type(Type,Term,Goal) ->
5657 % Call = when(nonvar(Term),Goal)
5662 Call = when(nonvar(Term),once('$dynamic_type_check'(Type,Term)))
5667 dynamic_type_check_clauses(C1), dynamic_type_check_clauses(C2)
5670 dynamic_type_check_clauses(C).
5672 get_dynamic_type_check_clauses(Q), dynamic_type_check_clauses(C)
5675 get_dynamic_type_check_clauses(Q)
5679 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5681 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5682 % Some optimizations can be applied for atomic types...
5683 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5685 atomic_types_suspended_constraint(C) :-
5687 get_constraint_type(C,ArgTypes),
5688 get_constraint_mode(C,ArgModes),
5689 findall(I,between(1,N,I),Indexes),
5690 maplist(atomic_types_suspended_constraint(C),ArgTypes,ArgModes,Indexes).
5692 atomic_types_suspended_constraint(C,Type,Mode,Index) :-
5693 ( is_indexed_argument(C,Index) ->
5703 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5704 %% atomic_type(+Type) is semidet.
5706 % Succeeds when all values of =Type= are atomic.
5707 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5708 :- chr_constraint atomic_type/1.
5710 atomic_type(Type) <=> atomic_builtin_type(Type,_,_) | Type \== any.
5712 type_definition(TypePat,Def) \ atomic_type(Type)
5714 functor(Type,F,A), functor(TypePat,F,A)
5716 maplist(atomic,Def).
5718 type_alias(TypePat,Alias) \ atomic_type(Type)
5720 functor(Type,F,A), functor(TypePat,F,A)
5723 copy_term_nat(TypePat-Alias,Type-NType),
5726 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5727 %% enumerated_atomic_type(+Type,-Atoms) is semidet.
5729 % Succeeds when all values of =Type= are atomic
5730 % and the atom values are finitely enumerable.
5731 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5732 :- chr_constraint enumerated_atomic_type/2.
5734 enumerated_atomic_type(Type,_) <=> atomic_builtin_type(Type,_,_) | fail.
5736 type_definition(TypePat,Def) \ enumerated_atomic_type(Type,Atoms)
5738 functor(Type,F,A), functor(TypePat,F,A)
5740 maplist(atomic,Def),
5743 type_alias(TypePat,Alias) \ enumerated_atomic_type(Type,Atoms)
5745 functor(Type,F,A), functor(TypePat,F,A)
5748 copy_term_nat(TypePat-Alias,Type-NType),
5749 enumerated_atomic_type(NType,Atoms).
5750 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5753 stored/3, % constraint,occurrence,(yes/no/maybe)
5754 stored_completing/3,
5757 is_finally_stored/1,
5758 check_all_passive/2.
5760 :- chr_option(mode,stored(+,+,+)).
5761 :- chr_option(type_declaration,stored(any,int,storedinfo)).
5762 :- chr_type storedinfo ---> yes ; no ; maybe.
5763 :- chr_option(mode,stored_complete(+,+,+)).
5764 :- chr_option(mode,maybe_complementary_guards(+,+,?,?)).
5765 :- chr_option(mode,guard_list(+,+,+,+)).
5766 :- chr_option(mode,check_all_passive(+,+)).
5767 :- chr_option(type_declaration,check_all_passive(any,list)).
5769 % change yes in maybe when yes becomes passive
5770 passive(RuleNb,ID), occurrence(C,O,RuleNb,ID,_) \
5771 stored(C,O,yes), stored_complete(C,RO,Yesses)
5772 <=> O < RO | NYesses is Yesses - 1,
5773 stored(C,O,maybe), stored_complete(C,RO,NYesses).
5774 % change yes in maybe when not observed
5775 ai_not_observed(C,O) \ stored(C,O,yes), stored_complete(C,RO,Yesses)
5777 NYesses is Yesses - 1,
5778 stored(C,O,maybe), stored_complete(C,RO,NYesses).
5780 occurrence(_,_,RuleNb,ID,_), occurrence(C2,_,RuleNb,_,_), stored_complete(C2,RO,0), max_occurrence(C2,MO2)
5781 ==> RO =< MO2 | % C2 is never stored
5787 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5789 rule(RuleNb,Rule),passive(RuleNb,Id) ==>
5790 Rule = pragma(rule(Head1,Head2,G,B),ids([Id|IDs1],IDs2),Pragmas,Name,RuleNb) |
5791 append(IDs1,IDs2,I), check_all_passive(RuleNb,I).
5793 rule(RuleNb,Rule),passive(RuleNb,Id) ==>
5794 Rule = pragma(rule(Head1,Head2,G,B),ids([],[Id|IDs2]),Pragmas,Name,RuleNb) |
5795 check_all_passive(RuleNb,IDs2).
5797 passive(RuleNb,Id) \ check_all_passive(RuleNb,[Id|IDs]) <=>
5798 check_all_passive(RuleNb,IDs).
5800 rule(RuleNb,Rule) \ check_all_passive(RuleNb,[]) <=>
5801 chr_warning(weird_program,'All heads passive in ~@.\n\tThis rule never fires. Please check your program.\n',[format_rule(Rule)]).
5803 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5805 % collect the storage information
5806 stored(C,O,yes) \ stored_completing(C,O,Yesses)
5807 <=> NO is O + 1, NYesses is Yesses + 1,
5808 stored_completing(C,NO,NYesses).
5809 stored(C,O,maybe) \ stored_completing(C,O,Yesses)
5811 stored_completing(C,NO,Yesses).
5813 stored(C,O,no) \ stored_completing(C,O,Yesses)
5814 <=> stored_complete(C,O,Yesses).
5815 stored_completing(C,O,Yesses)
5816 <=> stored_complete(C,O,Yesses).
5818 stored_complete(C,O,Yesses), occurrence(C,O2,RuleNb,Id,_) ==>
5819 O2 > O | passive(RuleNb,Id).
5821 % decide whether a constraint is stored
5822 max_occurrence(C,MO), stored_complete(C,RO,0) \ is_stored(C)
5823 <=> RO =< MO | fail.
5824 is_stored(C) <=> true.
5826 % decide whether a constraint is suspends after occurrences
5827 max_occurrence(C,MO), stored_complete(C,RO,_) \ is_finally_stored(C)
5828 <=> RO =< MO | fail.
5829 is_finally_stored(C) <=> true.
5831 storage_analysis(Constraints) :-
5832 ( chr_pp_flag(storage_analysis,on) ->
5833 check_constraint_storages(Constraints)
5838 check_constraint_storages([]).
5839 check_constraint_storages([C|Cs]) :-
5840 check_constraint_storage(C),
5841 check_constraint_storages(Cs).
5843 check_constraint_storage(C) :-
5844 get_max_occurrence(C,MO),
5845 check_occurrences_storage(C,1,MO).
5847 check_occurrences_storage(C,O,MO) :-
5849 stored_completing(C,1,0)
5851 check_occurrence_storage(C,O),
5853 check_occurrences_storage(C,NO,MO)
5856 check_occurrence_storage(C,O) :-
5857 get_occurrence(C,O,RuleNb,ID),
5858 ( is_passive(RuleNb,ID) ->
5861 get_rule(RuleNb,PragmaRule),
5862 PragmaRule = pragma(rule(Heads1,Heads2,Guard,Body),ids(IDs1,IDs2),_,_,_),
5863 ( select2(ID,Head1,IDs1,Heads1,RIDs1,RHeads1) ->
5864 check_storage_head1(Head1,O,Heads1,Heads2,Guard)
5865 ; select2(ID,Head2,IDs2,Heads2,RIDs2,RHeads2) ->
5866 check_storage_head2(Head2,O,Heads1,Body)
5870 check_storage_head1(Head,O,H1,H2,G) :-
5875 % writeq(guard_entailment:entails_guard([chr_pp_headvariables(Head)],G)),nl,
5876 guard_entailment:entails_guard([chr_pp_headvariables(Head)],G),
5878 no_matching(L,[]) ->
5885 no_matching([X|Xs],Prev) :-
5887 \+ memberchk_eq(X,Prev),
5888 no_matching(Xs,[X|Prev]).
5890 check_storage_head2(Head,O,H1,B) :-
5894 ( H1 \== [], B == true )
5896 % \+ is_observed(F/A,O) % always fails because observation analysis has not been performed yet
5904 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5906 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5907 %% ____ _ ____ _ _ _ _
5908 %% | _ \ _ _| | ___ / ___|___ _ __ ___ _ __ (_) | __ _| |_(_) ___ _ __
5909 %% | |_) | | | | |/ _ \ | | / _ \| '_ ` _ \| '_ \| | |/ _` | __| |/ _ \| '_ \
5910 %% | _ <| |_| | | __/ | |__| (_) | | | | | | |_) | | | (_| | |_| | (_) | | | |
5911 %% |_| \_\\__,_|_|\___| \____\___/|_| |_| |_| .__/|_|_|\__,_|\__|_|\___/|_| |_|
5914 constraints_code(Constraints,Clauses) :-
5915 (chr_pp_flag(reduced_indexing,on),
5916 forall(C,Constraints,chr_translate:only_ground_indexed_arguments(C)) ->
5917 none_suspended_on_variables
5921 constraints_code1(Constraints,Clauses,[]).
5923 %===============================================================================
5924 :- chr_constraint constraints_code1/3.
5925 :- chr_option(mode,constraints_code1(+,+,+)).
5926 :- chr_option(type_declaration,constraints_code1(list,any,any)).
5927 %-------------------------------------------------------------------------------
5928 constraints_code1([],L,T) <=> L = T.
5929 constraints_code1([C|RCs],L,T)
5931 constraint_code(C,L,T1),
5932 constraints_code1(RCs,T1,T).
5933 %===============================================================================
5934 :- chr_constraint constraint_code/3.
5935 :- chr_option(mode,constraint_code(+,+,+)).
5936 %-------------------------------------------------------------------------------
5937 %% Generate code for a single CHR constraint
5938 constraint_code(Constraint, L, T)
5940 | ( (chr_pp_flag(debugable,on) ;
5941 is_stored(Constraint), ( has_active_occurrence(Constraint); chr_pp_flag(late_allocation,off)),
5942 ( may_trigger(Constraint) ;
5943 get_allocation_occurrence(Constraint,AO),
5944 get_max_occurrence(Constraint,MO), MO >= AO ) )
5946 constraint_prelude(Constraint,Clause),
5947 add_dummy_location(Clause,LocatedClause),
5948 L = [LocatedClause | L1]
5953 occurrences_code(Constraint,1,Id,NId,L1,L2),
5954 gen_cond_attach_clause(Constraint,NId,L2,T).
5956 %===============================================================================
5957 %% Generate prelude predicate for a constraint.
5958 %% f(...) :- f/a_0(...,Susp).
5959 constraint_prelude(F/A, Clause) :-
5960 vars_susp(A,Vars,Susp,VarsSusp),
5961 Head =.. [ F | Vars],
5962 make_suspension_continuation_goal(F/A,VarsSusp,Continuation),
5963 build_head(F,A,[0],VarsSusp,Delegate),
5964 ( chr_pp_flag(debugable,on) ->
5965 insert_constraint_goal(F/A,Susp,Vars,InsertCall),
5966 attach_constraint_atom(F/A,Vars2,Susp,AttachCall),
5967 delay_phase_end(validate_store_type_assumptions,chr_translate:update_suspension_field(F/A,Susp,state,inactive,Inactive)),
5968 insert_constraint_internal_constraint_goal(F/A, Vars2, Susp, Continuation, Vars,InsertGoal),
5970 ( get_constraint_type(F/A,ArgTypeList) ->
5971 maplist(dynamic_type_check_call,ArgTypeList,Vars,DynamicTypeCheckList),
5972 list2conj(DynamicTypeCheckList,DynamicTypeChecks)
5974 DynamicTypeChecks = true
5984 'chr debug_event'(insert(Head#Susp)),
5986 'chr debug_event'(call(Susp)),
5989 'chr debug_event'(fail(Susp)), !,
5993 'chr debug_event'(exit(Susp))
5995 'chr debug_event'(redo(Susp)),
5999 ; get_allocation_occurrence(F/A,0) ->
6000 gen_insert_constraint_internal_goal(F/A,Goal,VarsSusp,Vars,Susp),
6001 delay_phase_end(validate_store_type_assumptions,chr_translate:update_suspension_field(F/A,Susp,state,inactive,Inactive)),
6002 Clause = ( Head :- Goal, Inactive, Delegate )
6004 Clause = ( Head :- Delegate )
6007 make_suspension_continuation_goal(F/A,VarsSusp,Goal) :-
6008 ( may_trigger(F/A) ->
6009 build_head(F,A,[0],VarsSusp,Delegate),
6010 ( chr_pp_flag(debugable,off) ->
6013 get_target_module(Mod),
6020 %===============================================================================
6021 :- chr_constraint has_active_occurrence/1, has_active_occurrence/2.
6022 :- chr_option(mode,has_active_occurrence(+)).
6023 :- chr_option(mode,has_active_occurrence(+,+)).
6024 %-------------------------------------------------------------------------------
6025 has_active_occurrence(C) <=> has_active_occurrence(C,1).
6027 max_occurrence(C,MO) \ has_active_occurrence(C,O) <=>
6029 passive(RuleNb,ID),occurrence(C,O,RuleNb,ID,_) \
6030 has_active_occurrence(C,O) <=>
6032 has_active_occurrence(C,NO).
6033 has_active_occurrence(C,O) <=> true.
6034 %===============================================================================
6036 gen_cond_attach_clause(F/A,Id,L,T) :-
6037 ( is_finally_stored(F/A) ->
6038 get_allocation_occurrence(F/A,AllocationOccurrence),
6039 get_max_occurrence(F/A,MaxOccurrence),
6040 ( chr_pp_flag(debugable,off), MaxOccurrence < AllocationOccurrence ->
6041 ( only_ground_indexed_arguments(F/A) ->
6042 gen_insert_constraint_internal_goal(F/A,Body,AllArgs,Args,Susp)
6044 gen_cond_attach_goal(F/A,Body,AllArgs,Args,Susp)
6046 ; vars_susp(A,Args,Susp,AllArgs),
6047 gen_uncond_attach_goal(F/A,Susp,Args,Body,_)
6049 build_head(F,A,Id,AllArgs,Head),
6050 Clause = ( Head :- Body ),
6051 add_dummy_location(Clause,LocatedClause),
6052 L = [LocatedClause | T]
6057 :- chr_constraint use_auxiliary_predicate/1.
6058 :- chr_option(mode,use_auxiliary_predicate(+)).
6060 :- chr_constraint use_auxiliary_predicate/2.
6061 :- chr_option(mode,use_auxiliary_predicate(+,+)).
6063 :- chr_constraint is_used_auxiliary_predicate/1.
6064 :- chr_option(mode,is_used_auxiliary_predicate(+)).
6066 :- chr_constraint is_used_auxiliary_predicate/2.
6067 :- chr_option(mode,is_used_auxiliary_predicate(+,+)).
6070 use_auxiliary_predicate(P) \ use_auxiliary_predicate(P) <=> true.
6072 use_auxiliary_predicate(P,C) \ use_auxiliary_predicate(P,C) <=> true.
6074 use_auxiliary_predicate(P) \ is_used_auxiliary_predicate(P) <=> true.
6076 use_auxiliary_predicate(P,_) \ is_used_auxiliary_predicate(P) <=> true.
6078 is_used_auxiliary_predicate(P) <=> fail.
6080 use_auxiliary_predicate(P) \ is_used_auxiliary_predicate(P,_) <=> true.
6081 use_auxiliary_predicate(P,C) \ is_used_auxiliary_predicate(P,C) <=> true.
6083 is_used_auxiliary_predicate(P,C) <=> fail.
6085 %------------------------------------------------------------------------------%
6086 % Only generate import statements for actually used modules.
6087 %------------------------------------------------------------------------------%
6089 :- chr_constraint use_auxiliary_module/1.
6090 :- chr_option(mode,use_auxiliary_module(+)).
6092 :- chr_constraint is_used_auxiliary_module/1.
6093 :- chr_option(mode,is_used_auxiliary_module(+)).
6096 use_auxiliary_module(P) \ use_auxiliary_module(P) <=> true.
6098 use_auxiliary_module(P) \ is_used_auxiliary_module(P) <=> true.
6100 is_used_auxiliary_module(P) <=> fail.
6102 % only called for constraints with
6104 % non-ground indexed argument
6105 gen_cond_attach_goal(F/A,Goal,AllArgs,Args,Susp) :-
6106 vars_susp(A,Args,Susp,AllArgs),
6107 make_suspension_continuation_goal(F/A,AllArgs,Closure),
6108 ( get_store_type(F/A,var_assoc_store(_,_)) ->
6111 attach_constraint_atom(F/A,Vars,Susp,Attach)
6114 insert_constraint_goal(F/A,Susp,Args,InsertCall),
6115 insert_constraint_internal_constraint_goal(F/A, Vars, Susp, Closure, Args,InsertGoal),
6116 ( may_trigger(F/A) ->
6117 activate_constraint_goal(F/A,(InsertCall,Attach),Vars,Susp,_,ActivateGoal),
6121 InsertGoal, % insert_constraint_internal(Stored,Vars,Susp,Closure,F,Args)
6125 ActivateGoal % activate_constraint(Stored,Vars,Susp,_)
6131 InsertGoal, % insert_constraint_internal(Stored,Vars,Susp,Closure,F,Args),
6137 gen_insert_constraint_internal_goal(F/A,Goal,AllArgs,Args,Susp) :-
6138 vars_susp(A,Args,Susp,AllArgs),
6139 make_suspension_continuation_goal(F/A,AllArgs,Cont),
6140 ( \+ only_ground_indexed_arguments(F/A), \+ get_store_type(F/A,var_assoc_store(_,_)) ->
6141 attach_constraint_atom(F/A,Vars,Susp,Attach)
6146 insert_constraint_goal(F/A,Susp,Args,InsertCall),
6147 insert_constraint_internal_constraint_goal(F/A, Vars, Susp, Cont, Args,InsertInternalGoal),
6148 ( only_ground_indexed_arguments(F/A), chr_pp_flag(debugable,off) ->
6151 InsertInternalGoal, % insert_constraint_internal(Susp,F,Args),
6157 InsertInternalGoal, % insert_constraint_internal(_,Vars,Susp,Cont,F,Args),
6163 gen_uncond_attach_goal(FA,Susp,Args,AttachGoal,Generation) :-
6164 ( \+ only_ground_indexed_arguments(FA), \+ get_store_type(FA,var_assoc_store(_,_)) ->
6165 attach_constraint_atom(FA,Vars,Susp,Attach)
6169 insert_constraint_goal(FA,Susp,Args,InsertCall),
6170 ( chr_pp_flag(late_allocation,on) ->
6171 activate_constraint_goal(FA,(InsertCall,Attach),Vars,Susp,Generation,AttachGoal)
6173 activate_constraint_goal(FA,true,Vars,Susp,Generation,AttachGoal)
6176 %-------------------------------------------------------------------------------
6177 :- chr_constraint occurrences_code/6.
6178 :- chr_option(mode,occurrences_code(+,+,+,+,+,+)).
6179 %-------------------------------------------------------------------------------
6180 max_occurrence(C,MO) \ occurrences_code(C,O,Id,NId,L,T)
6183 occurrences_code(C,O,Id,NId,L,T)
6185 occurrence_code(C,O,Id,Id1,L,L1),
6187 occurrences_code(C,NO,Id1,NId,L1,T).
6188 %-------------------------------------------------------------------------------
6189 :- chr_constraint occurrence_code/6.
6190 :- chr_option(mode,occurrence_code(+,+,+,+,+,+)).
6191 %-------------------------------------------------------------------------------
6192 occurrence(C,O,RuleNb,ID,_), passive(RuleNb,ID) \ occurrence_code(C,O,Id,NId,L,T)
6194 ( named_history(RuleNb,_,_) ->
6195 does_use_history(C,O)
6201 occurrence(C,O,RuleNb,ID,_), rule(RuleNb,PragmaRule) \ occurrence_code(C,O,Id,NId,L,T)
6203 PragmaRule = pragma(rule(Heads1,Heads2,_,_),ids(IDs1,IDs2),_,_,_),
6204 ( select2(ID,Head1,IDs1,Heads1,RIDs1,RHeads1) ->
6206 head1_code(Head1,ID,RHeads1,RIDs1,PragmaRule,C,O,Id,L,T)
6207 ; select2(ID,Head2,IDs2,Heads2,RIDs2,RHeads2) ->
6209 head2_code(Head2,ID,RHeads2,RIDs2,PragmaRule,C,O,Id,L,L1),
6210 ( should_skip_to_next_id(C,O) ->
6212 ( unconditional_occurrence(C,O) ->
6215 gen_alloc_inc_clause(C,O,Id,L1,T)
6223 occurrence_code(C,O,_,_,_,_)
6225 chr_error(internal,'occurrence_code/6: missing information to compile ~w:~w\n',[C,O]).
6226 %-------------------------------------------------------------------------------
6228 %% Generate code based on one removed head of a CHR rule
6229 head1_code(Head,ID,OtherHeads,OtherIDs,PragmaRule,FA,O,Id,L,T) :-
6230 PragmaRule = pragma(Rule,_,_,_Name,RuleNb),
6231 Rule = rule(_,Head2,_,_),
6233 reorder_heads(RuleNb,Head,OtherHeads,OtherIDs,NOtherHeads,NOtherIDs),
6234 simplification_code(Head,ID,NOtherHeads,NOtherIDs,PragmaRule,FA,O,Id,L,T)
6236 simpagation_head1_code(Head,ID,OtherHeads,OtherIDs,PragmaRule,FA,O,Id,L,T)
6239 %% Generate code based on one persistent head of a CHR rule
6240 head2_code(Head,ID,OtherHeads,OtherIDs,PragmaRule,FA,O,Id,L,T) :-
6241 PragmaRule = pragma(Rule,_,_,_Name,RuleNb),
6242 Rule = rule(Head1,_,_,_),
6244 reorder_heads(RuleNb,Head,OtherHeads,OtherIDs,NOtherHeads,NOtherIDs),
6245 propagation_code(Head,ID,NOtherHeads,NOtherIDs,Rule,RuleNb,FA,O,Id,L,T)
6247 simpagation_head2_code(Head,ID,OtherHeads,OtherIDs,PragmaRule,FA,O,Id,L,T)
6250 gen_alloc_inc_clause(F/A,O,Id,L,T) :-
6251 vars_susp(A,Vars,Susp,VarsSusp),
6252 build_head(F,A,Id,VarsSusp,Head),
6254 build_head(F,A,IncId,VarsSusp,CallHead),
6255 gen_occ_allocation(F/A,O,Vars,Susp,ConditionalAlloc),
6262 add_dummy_location(Clause,LocatedClause),
6263 L = [LocatedClause|T].
6265 gen_occ_allocation(FA,O,Vars,Susp,Goal) :-
6266 get_allocation_occurrence(FA,AO),
6267 get_occurrence_code_id(FA,AO,AId),
6268 get_occurrence_code_id(FA,O,Id),
6269 ( chr_pp_flag(debugable,off), Id == AId ->
6270 allocate_constraint_goal(FA,Susp,Vars,Goal0),
6271 ( may_trigger(FA) ->
6272 Goal = (var(Susp) -> Goal0 ; true)
6280 gen_occ_allocation_in_guard(FA,O,Vars,Susp,Goal) :-
6281 get_allocation_occurrence(FA,AO),
6282 ( chr_pp_flag(debugable,off), O < AO ->
6283 allocate_constraint_goal(FA,Susp,Vars,Goal0),
6284 ( may_trigger(FA) ->
6285 Goal = (var(Susp) -> Goal0 ; true)
6293 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6295 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6297 % Reorders guard goals with respect to partner constraint retrieval goals and
6298 % active constraint. Returns combined partner retrieval + guard goal.
6300 guard_via_reschedule_new(Retrievals,GuardList,Prelude,GuardListSkeleton,LookupSkeleton,GoalSkeleton) :-
6301 ( chr_pp_flag(guard_via_reschedule,on) ->
6302 guard_via_reschedule_main_new(Retrievals,GuardList,Prelude,GuardListSkeleton,LookupSkeleton,ScheduleSkeleton),
6303 list2conj(ScheduleSkeleton,GoalSkeleton)
6305 length(Retrievals,RL), length(LookupSkeleton,RL),
6306 length(GuardList,GL), length(GuardListSkeleton,GL),
6307 append(LookupSkeleton,GuardListSkeleton,GoalListSkeleton),
6308 list2conj(GoalListSkeleton,GoalSkeleton)
6310 guard_via_reschedule_main_new(PartnerLookups,GuardList,ActiveHead,
6311 GuardListSkeleton,LookupSkeleton,ScheduleSkeleton) :-
6312 initialize_unit_dictionary(ActiveHead,Dict),
6313 maplist(wrap_in_functor(lookup),PartnerLookups,WrappedPartnerLookups),
6314 maplist(wrap_in_functor(guard),GuardList,WrappedGuardList),
6315 build_units(WrappedPartnerLookups,WrappedGuardList,Dict,Units),
6316 dependency_reorder(Units,NUnits),
6317 wrappedunits2lists(NUnits,IndexedGuardListSkeleton,LookupSkeleton,ScheduleSkeleton),
6318 sort(IndexedGuardListSkeleton,SortedIndexedGuardListSkeleton),
6319 snd_of_pairs(SortedIndexedGuardListSkeleton,GuardListSkeleton).
6321 wrappedunits2lists([],[],[],[]).
6322 wrappedunits2lists([unit(N,WrappedGoal,_,_)|Units],Gs,Ls,Ss) :-
6323 Ss = [GoalCopy|TSs],
6324 ( WrappedGoal = lookup(Goal) ->
6325 Ls = [GoalCopy|TLs],
6327 ; WrappedGoal = guard(Goal) ->
6328 Gs = [N-GoalCopy|TGs],
6331 wrappedunits2lists(Units,TGs,TLs,TSs).
6333 guard_splitting(Rule,SplitGuardList) :-
6334 Rule = rule(H1,H2,Guard,_),
6335 append(H1,H2,Heads),
6336 conj2list(Guard,GuardList),
6337 term_variables(Heads,HeadVars),
6338 split_off_simple_guard_new(GuardList,HeadVars,GuardPrefix,RestGuardList),
6339 append(GuardPrefix,[RestGuard],SplitGuardList),
6340 term_variables(RestGuardList,GuardVars1),
6341 % variables that are declared to be ground don't need to be locked
6342 ground_vars(Heads,GroundVars),
6343 list_difference_eq(HeadVars,GroundVars,LockableHeadVars),
6344 intersect_eq(LockableHeadVars,GuardVars1,GuardVars),
6345 ( chr_pp_flag(guard_locks,on),
6346 bagof(('chr lock'(X)) - ('chr unlock'(X)), (lists:member(X,GuardVars)), LocksUnlocks) ->
6347 once(pairup(Locks,Unlocks,LocksUnlocks))
6352 list2conj(Locks,LockPhase),
6353 list2conj(Unlocks,UnlockPhase),
6354 list2conj(RestGuardList,RestGuard1),
6355 RestGuard = (LockPhase,(RestGuard1,UnlockPhase)).
6357 guard_body_copies3(Rule,GuardList,VarDict,GuardCopyList,BodyCopy) :-
6358 Rule = rule(_,_,_,Body),
6359 my_term_copy(GuardList,VarDict,VarDict2,GuardCopyList),
6360 my_term_copy(Body,VarDict2,BodyCopy).
6363 split_off_simple_guard_new([],_,[],[]).
6364 split_off_simple_guard_new([G|Gs],VarDict,S,C) :-
6365 ( simple_guard_new(G,VarDict) ->
6367 split_off_simple_guard_new(Gs,VarDict,Ss,C)
6373 % simple guard: cheap and benign (does not bind variables)
6374 simple_guard_new(G,Vars) :-
6375 builtin_binds_b(G,BoundVars),
6376 \+ (( member(V,BoundVars),
6377 memberchk_eq(V,Vars)
6380 dependency_reorder(Units,NUnits) :-
6381 dependency_reorder(Units,[],NUnits).
6383 dependency_reorder([],Acc,Result) :-
6384 reverse(Acc,Result).
6386 dependency_reorder([Unit|Units],Acc,Result) :-
6387 Unit = unit(_GID,_Goal,Type,GIDs),
6391 dependency_insert(Acc,Unit,GIDs,NAcc)
6393 dependency_reorder(Units,NAcc,Result).
6395 dependency_insert([],Unit,_,[Unit]).
6396 dependency_insert([X|Xs],Unit,GIDs,L) :-
6397 X = unit(GID,_,_,_),
6398 ( memberchk(GID,GIDs) ->
6402 dependency_insert(Xs,Unit,GIDs,T)
6405 build_units(Retrievals,Guard,InitialDict,Units) :-
6406 build_retrieval_units(Retrievals,1,N,InitialDict,Dict,Units,Tail),
6407 build_guard_units(Guard,N,Dict,Tail).
6409 build_retrieval_units([],N,N,Dict,Dict,L,L).
6410 build_retrieval_units([U|Us],N,M,Dict,NDict,L,T) :-
6411 term_variables(U,Vs),
6412 update_unit_dictionary(Vs,N,Dict,Dict1,[],GIDs),
6413 L = [unit(N,U,fixed,GIDs)|L1],
6415 build_retrieval_units(Us,N1,M,Dict1,NDict,L1,T).
6417 initialize_unit_dictionary(Term,Dict) :-
6418 term_variables(Term,Vars),
6419 pair_all_with(Vars,0,Dict).
6421 update_unit_dictionary([],_,Dict,Dict,GIDs,GIDs).
6422 update_unit_dictionary([V|Vs],This,Dict,NDict,GIDs,NGIDs) :-
6423 ( lookup_eq(Dict,V,GID) ->
6424 ( (GID == This ; memberchk(GID,GIDs) ) ->
6431 Dict1 = [V - This|Dict],
6434 update_unit_dictionary(Vs,This,Dict1,NDict,GIDs1,NGIDs).
6436 build_guard_units(Guard,N,Dict,Units) :-
6438 Units = [unit(N,Goal,fixed,[])]
6439 ; Guard = [Goal|Goals] ->
6440 term_variables(Goal,Vs),
6441 update_unit_dictionary2(Vs,N,Dict,NDict,[],GIDs),
6442 Units = [unit(N,Goal,movable,GIDs)|RUnits],
6444 build_guard_units(Goals,N1,NDict,RUnits)
6447 update_unit_dictionary2([],_,Dict,Dict,GIDs,GIDs).
6448 update_unit_dictionary2([V|Vs],This,Dict,NDict,GIDs,NGIDs) :-
6449 ( lookup_eq(Dict,V,GID) ->
6450 ( (GID == This ; memberchk(GID,GIDs) ) ->
6455 Dict1 = [V - This|Dict]
6457 Dict1 = [V - This|Dict],
6460 update_unit_dictionary2(Vs,This,Dict1,NDict,GIDs1,NGIDs).
6462 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6464 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6466 %% / ___| ___| |_ / ___| ___ _ __ ___ __ _ _ __ | |_(_) ___ ___ _
6467 %% \___ \ / _ \ __| \___ \ / _ \ '_ ` _ \ / _` | '_ \| __| |/ __/ __(_)
6468 %% ___) | __/ |_ ___) | __/ | | | | | (_| | | | | |_| | (__\__ \_
6469 %% |____/ \___|\__| |____/ \___|_| |_| |_|\__,_|_| |_|\__|_|\___|___(_)
6472 %% | | | |_ __ (_) __ _ _ _ ___ |_ _|_ __ / _| ___ _ __ ___ _ __ ___ ___
6473 %% | | | | '_ \| |/ _` | | | |/ _ \ | || '_ \| |_ / _ \ '__/ _ \ '_ \ / __/ _ \
6474 %% | |_| | | | | | (_| | |_| | __/ | || | | | _| __/ | | __/ | | | (_| __/
6475 %% \___/|_| |_|_|\__, |\__,_|\___| |___|_| |_|_| \___|_| \___|_| |_|\___\___|
6478 functional_dependency/4,
6479 get_functional_dependency/4.
6481 :- chr_option(mode,functional_dependency(+,+,?,?)).
6482 :- chr_option(mode,get_functional_dependency(+,+,?,?)).
6484 allocation_occurrence(C,AO), occurrence(C,O,RuleNb,_,_) \ functional_dependency(C,RuleNb,Pattern,Key)
6488 functional_dependency(C,1,Pattern,Key).
6490 functional_dependency(C,RuleNb1,Pattern,Key) \ get_functional_dependency(C,RuleNb2,QPattern,QKey)
6494 QPattern = Pattern, QKey = Key.
6495 get_functional_dependency(_,_,_,_)
6499 functional_dependency_analysis(Rules) :-
6500 ( fail, chr_pp_flag(functional_dependency_analysis,on) ->
6501 functional_dependency_analysis_main(Rules)
6506 functional_dependency_analysis_main([]).
6507 functional_dependency_analysis_main([PRule|PRules]) :-
6508 ( discover_unique_pattern(PRule,C,RuleNb,Pattern,Key) ->
6509 functional_dependency(C,RuleNb,Pattern,Key)
6513 functional_dependency_analysis_main(PRules).
6515 discover_unique_pattern(PragmaRule,F/A,RuleNb,Pattern,Key) :-
6516 PragmaRule = pragma(Rule,_,_,Name,RuleNb),
6517 Rule = rule(H1,H2,Guard,_),
6525 check_unique_constraints(C1,C2,Guard,RuleNb,List),
6526 term_variables(C1,Vs),
6529 lookup_eq(List,V1,V2),
6532 select_pragma_unique_variables(Vs,List,Key1),
6533 copy_term_nat(C1-Key1,Pattern-Key),
6536 select_pragma_unique_variables([],_,[]).
6537 select_pragma_unique_variables([V|Vs],List,L) :-
6538 ( lookup_eq(List,V,_) ->
6543 select_pragma_unique_variables(Vs,List,T).
6545 % depends on functional dependency analysis
6546 % and shape of rule: C1 \ C2 <=> true.
6547 set_semantics_rules(Rules) :-
6548 ( fail, chr_pp_flag(set_semantics_rule,on) ->
6549 set_semantics_rules_main(Rules)
6554 set_semantics_rules_main([]).
6555 set_semantics_rules_main([R|Rs]) :-
6556 set_semantics_rule_main(R),
6557 set_semantics_rules_main(Rs).
6559 set_semantics_rule_main(PragmaRule) :-
6560 PragmaRule = pragma(Rule,IDs,Pragmas,_,RuleNb),
6561 ( Rule = rule([C1],[C2],true,_),
6562 IDs = ids([ID1],[ID2]),
6563 \+ is_passive(RuleNb,ID1),
6565 get_functional_dependency(F/A,RuleNb,Pattern,Key),
6566 copy_term_nat(Pattern-Key,C1-Key1),
6567 copy_term_nat(Pattern-Key,C2-Key2),
6574 check_unique_constraints(C1,C2,G,RuleNb,List) :-
6575 \+ any_passive_head(RuleNb),
6576 variable_replacement(C1-C2,C2-C1,List),
6577 copy_with_variable_replacement(G,OtherG,List),
6579 once(entails_b(NotG,OtherG)).
6581 % checks for rules of the shape ...,C1,C2... (<|=)=> ...
6582 % where C1 and C2 are symmteric constraints
6583 symmetry_analysis(Rules) :-
6584 ( chr_pp_flag(check_unnecessary_active,off) ->
6587 symmetry_analysis_main(Rules)
6590 symmetry_analysis_main([]).
6591 symmetry_analysis_main([R|Rs]) :-
6592 R = pragma(Rule,ids(IDs1,IDs2),_,_,RuleNb),
6593 Rule = rule(H1,H2,_,_),
6594 ( ( \+ chr_pp_flag(check_unnecessary_active,simplification) ; H2 == [] ), H1 \== [] ->
6595 symmetry_analysis_heads_simplification(H1,IDs1,[],[],Rule,RuleNb),
6596 symmetry_analysis_heads_propagation(H2,IDs2,[],[],Rule,RuleNb)
6600 symmetry_analysis_main(Rs).
6602 symmetry_analysis_heads_simplification([],[],_,_,_,_).
6603 symmetry_analysis_heads_simplification([H|Hs],[ID|IDs],PreHs,PreIDs,Rule,RuleNb) :-
6604 ( \+ is_passive(RuleNb,ID),
6605 member2(PreHs,PreIDs,PreH-PreID),
6606 \+ is_passive(RuleNb,PreID),
6607 variable_replacement(PreH,H,List),
6608 copy_with_variable_replacement(Rule,Rule2,List),
6609 identical_guarded_rules(Rule,Rule2) ->
6614 symmetry_analysis_heads_simplification(Hs,IDs,[H|PreHs],[ID|PreIDs],Rule,RuleNb).
6616 symmetry_analysis_heads_propagation([],[],_,_,_,_).
6617 symmetry_analysis_heads_propagation([H|Hs],[ID|IDs],PreHs,PreIDs,Rule,RuleNb) :-
6618 ( \+ is_passive(RuleNb,ID),
6619 member2(PreHs,PreIDs,PreH-PreID),
6620 \+ is_passive(RuleNb,PreID),
6621 variable_replacement(PreH,H,List),
6622 copy_with_variable_replacement(Rule,Rule2,List),
6623 identical_rules(Rule,Rule2) ->
6628 symmetry_analysis_heads_propagation(Hs,IDs,[H|PreHs],[ID|PreIDs],Rule,RuleNb).
6630 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6632 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6633 %% ____ _ _ _ __ _ _ _
6634 %% / ___|(_)_ __ ___ _ __ | (_)/ _(_) ___ __ _| |_(_) ___ _ __
6635 %% \___ \| | '_ ` _ \| '_ \| | | |_| |/ __/ _` | __| |/ _ \| '_ \
6636 %% ___) | | | | | | | |_) | | | _| | (_| (_| | |_| | (_) | | | |
6637 %% |____/|_|_| |_| |_| .__/|_|_|_| |_|\___\__,_|\__|_|\___/|_| |_|
6641 simplification_code(Head,ID,RestHeads,RestIDs,PragmaRule,F/A,O,Id,L,T) :-
6642 PragmaRule = pragma(Rule,_,Pragmas,_,RuleNb),
6643 head_info(Head,A,_Vars,Susp,HeadVars,HeadPairs),
6644 build_head(F,A,Id,HeadVars,ClauseHead),
6645 get_constraint_mode(F/A,Mode),
6646 head_arg_matches(HeadPairs,Mode,[],FirstMatching,VarDict1,[],GroundVars),
6649 guard_splitting(Rule,GuardList0),
6650 ( is_stored_in_guard(F/A, RuleNb) ->
6651 GuardList = [Hole1|GuardList0]
6653 GuardList = GuardList0
6655 guard_via_reschedule_new(RestHeads,GuardList,Head,GuardCopyList,GetRestHeads,RescheduledTest),
6657 rest_heads_retrieval_and_matching(RestHeads,RestIDs,Head,GetRestHeads,Susps,VarDict1,VarDict,[],[],[],GroundVars,_),
6659 guard_body_copies3(Rule,GuardList,VarDict,GuardCopyList,BodyCopy),
6661 ( is_stored_in_guard(F/A, RuleNb) ->
6662 gen_occ_allocation_in_guard(F/A,O,Vars,Susp,Allocation),
6663 gen_uncond_attach_goal(F/A,Susp,Vars,Attachment,_),
6664 GuardCopyList = [Hole1Copy|_],
6665 Hole1Copy = (Allocation, Attachment)
6671 partner_constraint_detachments(Susps,RestHeads,VarDict,SuspsDetachments),
6672 active_constraint_detachment(Id,Susp,Head,VarDict,SuspDetachment),
6674 ( chr_pp_flag(debugable,on) ->
6675 Rule = rule(_,_,Guard,Body),
6676 my_term_copy(Guard - Body, VarDict, DebugGuard - DebugBody),
6677 sort_by_key([Susp|Susps],[ID|RestIDs],SortedSusps),
6678 DebugTry = 'chr debug_event'( try(SortedSusps,[],DebugGuard,DebugBody)),
6679 DebugApply = 'chr debug_event'(apply(SortedSusps,[],DebugGuard,DebugBody)),
6680 instrument_goal(ActualCut,DebugTry,DebugApply,Cut)
6684 ( unconditional_occurrence(F/A,O), chr_pp_flag(late_allocation,on) -> ActualCut = true ; ActualCut = (!) ),
6685 Clause = ( ClauseHead :-
6693 add_location(Clause,RuleNb,LocatedClause),
6694 L = [LocatedClause | T].
6698 add_location(Clause,RuleNb,NClause) :-
6699 ( chr_pp_flag(line_numbers,on) ->
6700 get_chr_source_file(File),
6701 get_line_number(RuleNb,LineNb),
6702 NClause = '$source_location'(File,LineNb):Clause
6707 add_dummy_location(Clause,NClause) :-
6708 ( chr_pp_flag(line_numbers,on) ->
6709 get_chr_source_file(File),
6710 NClause = '$source_location'(File,1):Clause
6714 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6715 %% head_arg_matches(+Pairs,+Modes,+VarDict,-Goal,-NVarDict) is det.
6717 % Return goal matching newly introduced variables with variables in
6718 % previously looked-up heads.
6719 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6720 head_arg_matches(Pairs,Modes,VarDict,Goal,NVarDict) :-
6721 head_arg_matches(Pairs,Modes,VarDict,Goal,NVarDict,[],_).
6723 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6724 %% head_arg_matches(+Pairs,+Modes,+VarDict,-Goal,-NVarDict,+GroundVars,-NGroundVars) is det.
6725 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6726 head_arg_matches(Pairs,Modes,VarDict,Goal,NVarDict,GroundVars,NGroundVars) :-
6727 head_arg_matches_(Pairs,Modes,VarDict,GroundVars,GoalList,NVarDict,NGroundVars),
6728 list2conj(GoalList,Goal).
6730 head_arg_matches_([],[],VarDict,GroundVars,[],VarDict,GroundVars).
6731 head_arg_matches_([Arg-Var| Rest],[Mode|Modes],VarDict,GroundVars,GoalList,NVarDict,NGroundVars) :-
6733 ( lookup_eq(VarDict,Arg,OtherVar) ->
6735 ( memberchk_eq(Arg,GroundVars) ->
6736 GoalList = [Var = OtherVar | RestGoalList],
6737 GroundVars1 = GroundVars
6739 GoalList = [Var == OtherVar | RestGoalList],
6740 GroundVars1 = [Arg|GroundVars]
6743 GoalList = [Var == OtherVar | RestGoalList],
6744 GroundVars1 = GroundVars
6748 VarDict1 = [Arg-Var | VarDict],
6749 GoalList = RestGoalList,
6751 GroundVars1 = [Arg|GroundVars]
6753 GroundVars1 = GroundVars
6758 ; ground(Arg), Arg = '$chr_identifier_match'(ActualArg,IndexType) ->
6759 identifier_label_atom(IndexType,Var,ActualArg,Goal),
6760 GoalList = [Goal|RestGoalList],
6762 GroundVars1 = GroundVars,
6767 GoalList = [ Var = Arg | RestGoalList]
6769 GoalList = [ Var == Arg | RestGoalList]
6772 GroundVars1 = GroundVars,
6775 ; Mode == (+), is_ground(GroundVars,Arg) ->
6776 copy_with_variable_replacement(Arg,ArgCopy,VarDict),
6777 GoalList = [ Var = ArgCopy | RestGoalList],
6779 GroundVars1 = GroundVars,
6782 ; Mode == (?), is_ground(GroundVars,Arg) ->
6783 copy_with_variable_replacement(Arg,ArgCopy,VarDict),
6784 GoalList = [ Var == ArgCopy | RestGoalList],
6786 GroundVars1 = GroundVars,
6791 functor(Term,Fct,N),
6794 GoalList = [ Var = Term | RestGoalList ]
6796 GoalList = [ nonvar(Var), Var = Term | RestGoalList ]
6798 pairup(Args,Vars,NewPairs),
6799 append(NewPairs,Rest,Pairs),
6800 replicate(N,Mode,NewModes),
6801 append(NewModes,Modes,RestModes),
6803 GroundVars1 = GroundVars
6805 head_arg_matches_(Pairs,RestModes,VarDict1,GroundVars1,RestGoalList,NVarDict,NGroundVars).
6807 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6808 % add_heads_types(+ListOfHeads,+VarTypes,-NVarTypes) is det.
6809 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6810 add_heads_types([],VarTypes,VarTypes).
6811 add_heads_types([Head|Heads],VarTypes,NVarTypes) :-
6812 add_head_types(Head,VarTypes,VarTypes1),
6813 add_heads_types(Heads,VarTypes1,NVarTypes).
6815 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6816 % add_head_types(+Head,+VarTypes,-NVarTypes) is det.
6817 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6818 add_head_types(Head,VarTypes,NVarTypes) :-
6820 get_constraint_type_det(F/A,ArgTypes),
6822 add_args_types(Args,ArgTypes,VarTypes,NVarTypes).
6824 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6825 % add_args_types(+Terms,+Types,+VarTypes,-NVarTypes) is det.
6826 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6827 add_args_types([],[],VarTypes,VarTypes).
6828 add_args_types([Arg|Args],[Type|Types],VarTypes,NVarTypes) :-
6829 add_arg_types(Arg,Type,VarTypes,VarTypes1),
6830 add_args_types(Args,Types,VarTypes1,NVarTypes).
6832 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6833 % add_arg_types(+Term,+Type,+VarTypes,-NVarTypes) is det.
6834 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6835 add_arg_types(Term,Type,VarTypes,NVarTypes) :-
6837 ( lookup_eq(VarTypes,Term,_) ->
6838 NVarTypes = VarTypes
6840 NVarTypes = [Term-Type|VarTypes]
6843 NVarTypes = VarTypes
6844 ; % TODO improve approximation!
6845 term_variables(Term,Vars),
6847 replicate(VarNb,any,Types),
6848 add_args_types(Vars,Types,VarTypes,NVarTypes)
6853 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6854 %% add_heads_ground_variables(+ListOfHeads,+GroundVars,-NGroundVars) is det.
6856 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6857 add_heads_ground_variables([],GroundVars,GroundVars).
6858 add_heads_ground_variables([Head|Heads],GroundVars,NGroundVars) :-
6859 add_head_ground_variables(Head,GroundVars,GroundVars1),
6860 add_heads_ground_variables(Heads,GroundVars1,NGroundVars).
6862 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6863 %% add_head_ground_variables(+Head,+GroundVars,-GroundVars) is det.
6865 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6866 add_head_ground_variables(Head,GroundVars,NGroundVars) :-
6868 get_constraint_mode(F/A,ArgModes),
6870 add_arg_ground_variables(Args,ArgModes,GroundVars,NGroundVars).
6873 add_arg_ground_variables([],[],GroundVars,GroundVars).
6874 add_arg_ground_variables([Arg|Args],[Mode|Modes],GroundVars,NGroundVars) :-
6876 term_variables(Arg,Vars),
6877 add_var_ground_variables(Vars,GroundVars,GroundVars1)
6879 GroundVars = GroundVars1
6881 add_arg_ground_variables(Args,Modes,GroundVars1,NGroundVars).
6883 add_var_ground_variables([],GroundVars,GroundVars).
6884 add_var_ground_variables([Var|Vars],GroundVars,NGroundVars) :-
6885 ( memberchk_eq(Var,GroundVars) ->
6886 GroundVars1 = GroundVars
6888 GroundVars1 = [Var|GroundVars]
6890 add_var_ground_variables(Vars,GroundVars1,NGroundVars).
6891 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6892 %% is_ground(+GroundVars,+Term) is semidet.
6894 % Determine whether =Term= is always ground.
6895 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6896 is_ground(GroundVars,Term) :-
6901 maplist(is_ground(GroundVars),Args)
6903 memberchk_eq(Term,GroundVars)
6906 %% check_ground(+GroundVars,+Term,-Goal) is det.
6908 % Return runtime check to see whether =Term= is ground.
6909 check_ground(GroundVars,Term,Goal) :-
6910 term_variables(Term,Variables),
6911 check_ground_variables(Variables,GroundVars,Goal).
6913 check_ground_variables([],_,true).
6914 check_ground_variables([Var|Vars],GroundVars,Goal) :-
6915 ( memberchk_eq(Var,GroundVars) ->
6916 check_ground_variables(Vars,GroundVars,Goal)
6918 Goal = (ground(Var), RGoal),
6919 check_ground_variables(Vars,GroundVars,RGoal)
6922 rest_heads_retrieval_and_matching(Heads,IDs,ActiveHead,GoalList,Susps,VarDict,NVarDict,PrevHs,PrevSusps,AttrDict) :-
6923 rest_heads_retrieval_and_matching(Heads,IDs,ActiveHead,GoalList,Susps,VarDict,NVarDict,PrevHs,PrevSusps,AttrDict,[],_).
6925 rest_heads_retrieval_and_matching(Heads,IDs,ActiveHead,GoalList,Susps,VarDict,NVarDict,PrevHs,PrevSusps,AttrDict,GroundVars,NGroundVars) :-
6927 rest_heads_retrieval_and_matching_n(Heads,IDs,PrevHs,PrevSusps,ActiveHead,GoalList,Susps,VarDict,NVarDict,AttrDict,GroundVars,NGroundVars)
6932 GroundVars = NGroundVars
6935 rest_heads_retrieval_and_matching_n([],_,_,_,_,[],[],VarDict,VarDict,_AttrDict,GroundVars,GroundVars).
6936 rest_heads_retrieval_and_matching_n([H|Hs],[ID|IDs],PrevHs,PrevSusps,ActiveHead,
6937 [Goal|Goals],[Susp|Susps],VarDict,NVarDict,_AttrDict,GroundVars,NGroundVars) :-
6939 head_info(H,A,Vars,_,_,Pairs),
6940 get_store_type(F/A,StoreType),
6941 ( StoreType == default ->
6942 passive_head_via(H,[ActiveHead|PrevHs],VarDict,ViaGoal,VarSusps),
6943 delay_phase_end(validate_store_type_assumptions,
6944 ( static_suspension_term(F/A,Suspension),
6945 get_static_suspension_term_field(arguments,F/A,Suspension,Vars),
6946 get_static_suspension_field(F/A,Suspension,state,active,GetState)
6949 % create_get_mutable_ref(active,State,GetMutable),
6950 get_constraint_mode(F/A,Mode),
6951 head_arg_matches(Pairs,Mode,VarDict,MatchingGoal,VarDict1,GroundVars,GroundVars1),
6953 sbag_member_call(Susp,VarSusps,Sbag),
6954 ExistentialLookup = (
6957 Susp = Suspension, % not inlined
6961 delay_phase_end(validate_store_type_assumptions,
6962 ( static_suspension_term(F/A,Suspension),
6963 get_static_suspension_term_field(arguments,F/A,Suspension,Vars)
6966 existential_lookup(StoreType,H,[ActiveHead|PrevHs],VarDict,GroundVars,Suspension,ExistentialLookup,Susp,Pairs,NPairs),
6967 get_constraint_mode(F/A,Mode),
6968 filter_mode(NPairs,Pairs,Mode,NMode),
6969 head_arg_matches(NPairs,NMode,VarDict,MatchingGoal,VarDict1,GroundVars,GroundVars1)
6971 different_from_other_susps(H,Susp,PrevHs,PrevSusps,DiffSuspGoals),
6972 append(NPairs,VarDict1,DA_), % order important here
6973 translate(GroundVars1,DA_,GroundVarsA),
6974 translate(GroundVars1,VarDict1,GroundVarsB),
6975 inline_matching_goal(MatchingGoal,MatchingGoal2,GroundVarsA,GroundVarsB),
6982 rest_heads_retrieval_and_matching_n(Hs,IDs,[H|PrevHs],[Susp|PrevSusps],ActiveHead,Goals,Susps,VarDict1,NVarDict,_NewAttrDict,GroundVars1,NGroundVars).
6984 inline_matching_goal(A==B,true,GVA,GVB) :-
6985 memberchk_eq(A,GVA),
6986 memberchk_eq(B,GVB),
6989 % inline_matching_goal(A=B,true,_,_) :- A=B, !.
6990 inline_matching_goal((A,B),(A2,B2),GVA,GVB) :- !,
6991 inline_matching_goal(A,A2,GVA,GVB),
6992 inline_matching_goal(B,B2,GVA,GVB).
6993 inline_matching_goal(X,X,_,_).
6996 filter_mode([],_,_,[]).
6997 filter_mode([Arg-Var|Rest],[_-V|R],[M|Ms],Modes) :-
7000 filter_mode(Rest,R,Ms,MT)
7002 filter_mode([Arg-Var|Rest],R,Ms,Modes)
7005 check_unique_keys([],_).
7006 check_unique_keys([V|Vs],Dict) :-
7007 lookup_eq(Dict,V,_),
7008 check_unique_keys(Vs,Dict).
7010 % Generates tests to ensure the found constraint differs from previously found constraints
7011 % TODO: detect more cases where constraints need be different
7012 different_from_other_susps(Head,Susp,Heads,Susps,DiffSuspGoals) :-
7013 different_from_other_susps_(Heads,Susps,Head,Susp,DiffSuspGoalList),
7014 list2conj(DiffSuspGoalList,DiffSuspGoals).
7016 different_from_other_susps_(_,[],_,_,[]) :- !.
7017 different_from_other_susps_([PreHead|Heads],[PreSusp|Susps],Head,Susp,List) :-
7018 ( functor(Head,F,A), functor(PreHead,F,A),
7019 copy_term_nat(PreHead-Head,PreHeadCopy-HeadCopy),
7020 \+ \+ PreHeadCopy = HeadCopy ->
7022 List = [Susp \== PreSusp | Tail]
7026 different_from_other_susps_(Heads,Susps,Head,Susp,Tail).
7028 % passive_head_via(in,in,in,in,out,out,out) :-
7029 passive_head_via(Head,PrevHeads,VarDict,Goal,AllSusps) :-
7031 get_constraint_index(F/A,Pos),
7032 common_variables(Head,PrevHeads,CommonVars),
7033 global_list_store_name(F/A,Name),
7034 GlobalGoal = nb_getval(Name,AllSusps),
7035 get_constraint_mode(F/A,ArgModes),
7038 ; member(CommonVar,CommonVars), nth1(I,ArgModes,(-)), arg(I,Head,Arg), Arg == CommonVar ->
7039 translate([CommonVar],VarDict,[Var]),
7040 gen_get_mod_constraints(F/A,Var,AttrGoal,AllSusps),
7043 translate(CommonVars,VarDict,Vars),
7044 add_heads_types(PrevHeads,[],TypeDict),
7045 my_term_copy(TypeDict,VarDict,TypeDictCopy),
7046 gen_get_mod_constraints(F/A,Vars,TypeDictCopy,ViaGoal,AttrGoal,AllSusps),
7055 common_variables(T,Ts,Vs) :-
7056 term_variables(T,V1),
7057 term_variables(Ts,V2),
7058 intersect_eq(V1,V2,Vs).
7060 gen_get_mod_constraints(FA,Vars,TypeDict,ViaGoal,AttrGoal,AllSusps) :-
7061 get_target_module(Mod),
7063 lookup_eq(TypeDict,A,Type),
7064 ( atomic_type(Type) ->
7068 ViaGoal = 'chr newvia_1'(A,V)
7071 ViaGoal = 'chr newvia_2'(A,B,V)
7073 ViaGoal = 'chr newvia'(Vars,V)
7076 ( get_attr(V,Mod,TSusps),
7077 TSuspsEqSusps % TSusps = Susps
7079 get_max_constraint_index(N),
7081 TSuspsEqSusps = true, % TSusps = Susps
7084 get_constraint_index(FA,Pos),
7085 get_suspensions(N,Pos,TSusps,TSuspsEqSusps,AllSusps)
7087 gen_get_mod_constraints(FA,Var,AttrGoal,AllSusps) :-
7088 get_target_module(Mod),
7090 ( get_attr(Var,Mod,TSusps),
7091 TSuspsEqSusps % TSusps = Susps
7093 get_max_constraint_index(N),
7095 TSuspsEqSusps = true, % TSusps = Susps
7098 get_constraint_index(FA,Pos),
7099 get_suspensions(N,Pos,TSusps,TSuspsEqSusps,AllSusps)
7102 guard_body_copies(Rule,VarDict,GuardCopy,BodyCopy) :-
7103 guard_body_copies2(Rule,VarDict,GuardCopyList,BodyCopy),
7104 list2conj(GuardCopyList,GuardCopy).
7106 guard_body_copies2(Rule,VarDict,GuardCopyList,BodyCopy) :-
7107 Rule = rule(_,H,Guard,Body),
7108 conj2list(Guard,GuardList),
7109 split_off_simple_guard(GuardList,VarDict,GuardPrefix,RestGuardList),
7110 my_term_copy(GuardPrefix-RestGuardList,VarDict,VarDict2,GuardPrefixCopy-RestGuardListCopyCore),
7112 append(GuardPrefixCopy,[RestGuardCopy],GuardCopyList),
7113 term_variables(RestGuardList,GuardVars),
7114 term_variables(RestGuardListCopyCore,GuardCopyVars),
7115 % variables that are declared to be ground don't need to be locked
7116 ground_vars(H,GroundVars),
7117 list_difference_eq(GuardVars,GroundVars,LockedGuardVars),
7118 ( chr_pp_flag(guard_locks,on),
7119 bagof(('chr lock'(Y)) - ('chr unlock'(Y)),
7120 X ^ (lists:member(X,LockedGuardVars), % X is a variable appearing in the original guard
7121 pairlist:lookup_eq(VarDict,X,Y), % translate X into new variable
7122 memberchk_eq(Y,GuardCopyVars) % redundant check? or multiple entries for X possible?
7125 once(pairup(Locks,Unlocks,LocksUnlocks))
7130 list2conj(Locks,LockPhase),
7131 list2conj(Unlocks,UnlockPhase),
7132 list2conj(RestGuardListCopyCore,RestGuardCopyCore),
7133 RestGuardCopy = (LockPhase,(RestGuardCopyCore,UnlockPhase)),
7134 my_term_copy(Body,VarDict2,BodyCopy).
7137 split_off_simple_guard([],_,[],[]).
7138 split_off_simple_guard([G|Gs],VarDict,S,C) :-
7139 ( simple_guard(G,VarDict) ->
7141 split_off_simple_guard(Gs,VarDict,Ss,C)
7147 % simple guard: cheap and benign (does not bind variables)
7148 simple_guard(G,VarDict) :-
7150 \+ (( member(V,Vars),
7151 lookup_eq(VarDict,V,_)
7154 active_constraint_detachment(Id,Susp,Head,VarDict,SuspDetachment) :-
7160 Id == [0], chr_pp_flag(store_in_guards, off)
7162 ( get_allocation_occurrence(C,AO),
7163 get_max_occurrence(C,MO),
7166 only_ground_indexed_arguments(C), chr_pp_flag(late_allocation,on) ->
7167 SuspDetachment = true
7169 gen_uncond_susp_detachment(Head,Susp,active,VarDict,UnCondSuspDetachment),
7170 ( chr_pp_flag(late_allocation,on) ->
7175 UnCondSuspDetachment
7178 SuspDetachment = UnCondSuspDetachment
7182 SuspDetachment = true
7185 partner_constraint_detachments([],[],_,true).
7186 partner_constraint_detachments([Susp|Susps],[Head|Heads],VarDict,(SuspDetachment,SuspsDetachments)) :-
7187 gen_uncond_susp_detachment(Head,Susp,partner,VarDict,SuspDetachment),
7188 partner_constraint_detachments(Susps,Heads,VarDict,SuspsDetachments).
7190 gen_uncond_susp_detachment(Head,Susp,Role,VarDict,SuspDetachment) :-
7194 SuspDetachment = ( DebugEvent, RemoveInternalGoal),
7195 ( chr_pp_flag(debugable,on) ->
7196 DebugEvent = 'chr debug_event'(remove(Susp))
7200 remove_constraint_goal(C,Susp,Vars,true,(DeleteCall,Detach),Role,RemoveInternalGoal),
7201 delete_constraint_goal(Head,Susp,VarDict,DeleteCall),
7202 ( \+ only_ground_indexed_arguments(C), \+ get_store_type(C,var_assoc_store(_,_)) ->
7203 detach_constraint_atom(C,Vars,Susp,Detach)
7208 SuspDetachment = true
7211 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7213 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7215 %% / ___|(_)_ __ ___ _ __ __ _ __ _ __ _| |_(_) ___ _ __ / |
7216 %% \___ \| | '_ ` _ \| '_ \ / _` |/ _` |/ _` | __| |/ _ \| '_ \ | |
7217 %% ___) | | | | | | | |_) | (_| | (_| | (_| | |_| | (_) | | | | | |
7218 %% |____/|_|_| |_| |_| .__/ \__,_|\__, |\__,_|\__|_|\___/|_| |_| |_|
7222 simpagation_head1_code(Head,ID,RestHeads,OtherIDs,PragmaRule,F/A,O,Id,L,T) :-
7223 PragmaRule = pragma(Rule,ids(_,Heads2IDs),Pragmas,_Name,RuleNb),
7224 Rule = rule(_Heads,Heads2,Guard,Body),
7226 head_info(Head,A,Vars,Susp,HeadVars,HeadPairs),
7227 get_constraint_mode(F/A,Mode),
7228 head_arg_matches(HeadPairs,Mode,[],FirstMatching,VarDict1,[],GroundVars),
7230 build_head(F,A,Id,HeadVars,ClauseHead),
7232 append(RestHeads,Heads2,Heads),
7233 append(OtherIDs,Heads2IDs,IDs),
7234 reorder_heads(RuleNb,Head,Heads,IDs,NHeads,NIDs),
7236 guard_splitting(Rule,GuardList0),
7237 ( is_stored_in_guard(F/A, RuleNb) ->
7238 GuardList = [Hole1|GuardList0]
7240 GuardList = GuardList0
7242 guard_via_reschedule_new(NHeads,GuardList,Head,GuardCopyList,GetRestHeads,RescheduledTest),
7244 rest_heads_retrieval_and_matching(NHeads,NIDs,Head,GetRestHeads,Susps,VarDict1,VarDict,[],[],[],GroundVars,_),
7245 split_by_ids(NIDs,Susps,OtherIDs,Susps1,Susps1IDs,Susps2,Susps2IDs),
7247 guard_body_copies3(Rule,GuardList,VarDict,GuardCopyList,BodyCopy),
7249 ( is_stored_in_guard(F/A, RuleNb) ->
7250 gen_uncond_attach_goal(F/A,Susp,Vars,Attachment,_),
7251 GuardCopyList = [Hole1Copy|_],
7252 Hole1Copy = Attachment
7257 sort_by_key(Susps1,Susps1IDs,SortedSusps1),
7258 partner_constraint_detachments(SortedSusps1,RestHeads,VarDict,SuspsDetachments),
7259 active_constraint_detachment(Id,Susp,Head,VarDict,SuspDetachment),
7261 ( chr_pp_flag(debugable,on) ->
7262 my_term_copy(Guard - Body, VarDict, DebugGuard - DebugBody),
7263 sort_by_key([Susp|Susps1],[ID|Susps1IDs],RemovedSusps),
7264 sort_by_key(Susps2,Susps2IDs,KeptSusps),
7265 DebugTry = 'chr debug_event'( try(RemovedSusps,KeptSusps,DebugGuard,DebugBody)),
7266 DebugApply = 'chr debug_event'(apply(RemovedSusps,KeptSusps,DebugGuard,DebugBody)),
7267 instrument_goal((!),DebugTry,DebugApply,Cut)
7272 Clause = ( ClauseHead :-
7280 add_location(Clause,RuleNb,LocatedClause),
7281 L = [LocatedClause | T].
7285 split_by_ids([],[],_,[],[]).
7286 split_by_ids([I|Is],[S|Ss],I1s,S1s,S2s) :-
7287 ( memberchk_eq(I,I1s) ->
7294 split_by_ids(Is,Ss,I1s,R1s,R2s).
7296 split_by_ids([],[],_,[],[],[],[]).
7297 split_by_ids([I|Is],[S|Ss],I1s,S1s,SI1s,S2s,SI2s) :-
7298 ( memberchk_eq(I,I1s) ->
7309 split_by_ids(Is,Ss,I1s,R1s,RSI1s,R2s,RSI2s).
7310 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7313 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7315 %% / ___|(_)_ __ ___ _ __ __ _ __ _ __ _| |_(_) ___ _ __ |___ \
7316 %% \___ \| | '_ ` _ \| '_ \ / _` |/ _` |/ _` | __| |/ _ \| '_ \ __) |
7317 %% ___) | | | | | | | |_) | (_| | (_| | (_| | |_| | (_) | | | | / __/
7318 %% |____/|_|_| |_| |_| .__/ \__,_|\__, |\__,_|\__|_|\___/|_| |_| |_____|
7321 %% Genereate prelude + worker predicate
7322 %% prelude calls worker
7323 %% worker iterates over one type of removed constraints
7324 simpagation_head2_code(Head2,ID,RestHeads2,RestIDs,PragmaRule,FA,O,Id,L,T) :-
7325 PragmaRule = pragma(Rule,ids(IDs1,IDs2),Pragmas,_Name,RuleNb),
7326 Rule = rule(Heads1,_,Guard,Body),
7327 append(Heads1,RestHeads2,Heads),
7328 append(IDs1,RestIDs,IDs),
7329 reorder_heads(RuleNb,Head2,Heads,IDs,[NHead|NHeads],[NID|NIDs]),
7330 simpagation_head2_prelude(Head2,NHead,[NHeads,Guard,Body],FA,O,Id,L,L1),
7332 ( memberchk_eq(NID,IDs2) ->
7333 simpagation_universal_searches(NHeads,NIDs,IDs2,[NHead,Head2],Rule,FA,O,NextHeads,PreHeads,NextIDs,Id1,Id2,L1,L2)
7335 L1 = L2, Id1 = Id2,NextHeads = NHeads, PreHeads = [NHead,Head2], NextIDs = NIDs
7337 universal_search_iterator_end(PreHeads,NextHeads,Rule,FA,O,Id2,L2,L3),
7338 simpagation_head2_worker(PreHeads,NextHeads,NextIDs,ID,PragmaRule,FA,O,Id2,L3,T).
7340 simpagation_universal_searches([],[],_,PreHeads,_,_,_,[],PreHeads,[],Id,Id,L,L).
7341 simpagation_universal_searches(Heads,[ID|IDs],IDs2,PreHeads,Rule,C,O,OutHeads,OutPreHeads,OutIDs,Id,NId,L,T) :-
7342 Heads = [Head|RHeads],
7344 universal_search_iterator_end(PreHeads,Heads,Rule,C,O,Id,L,L0),
7345 universal_search_iterator(Heads,PreHeads,Rule,C,O,Id,L0,L1),
7346 ( memberchk_eq(ID,IDs2) ->
7347 simpagation_universal_searches(RHeads,IDs,IDs2,[Head|PreHeads],Rule,C,O,OutHeads,OutPreHeads,OutIDs,Id1,NId,L1,T)
7349 NId = Id1, L1 = T, OutHeads = RHeads, OutPreHeads = [Head|PreHeads], IDs = OutIDs
7352 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7353 simpagation_head2_prelude(Head,Head1,Rest,F/A,O,Id1,L,T) :-
7354 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs),
7355 build_head(F,A,Id1,VarsSusp,ClauseHead),
7356 get_constraint_mode(F/A,Mode),
7357 head_arg_matches(HeadPairs,Mode,[],FirstMatching,VarDict,[],GroundVars),
7359 lookup_passive_head(Head1,[Head],VarDict,GroundVars,ModConstraintsGoal,AllSusps),
7361 gen_occ_allocation(F/A,O,Vars,Susp,ConstraintAllocationGoal),
7363 extend_id(Id1,DelegateId),
7364 extra_active_delegate_variables(Head,[Head1|Rest],VarDict,ExtraVars),
7365 append([AllSusps|VarsSusp],ExtraVars,DelegateCallVars),
7366 build_head(F,A,[O|DelegateId],DelegateCallVars,Delegate),
7373 ConstraintAllocationGoal,
7376 add_dummy_location(PreludeClause,LocatedPreludeClause),
7377 L = [LocatedPreludeClause|T].
7379 extra_active_delegate_variables(Term,Terms,VarDict,Vars) :-
7381 delegate_variables(Term,Terms,VarDict,Args,Vars).
7383 passive_delegate_variables(Term,PrevTerms,NextTerms,VarDict,Vars) :-
7384 term_variables(PrevTerms,PrevVars),
7385 delegate_variables(Term,NextTerms,VarDict,PrevVars,Vars).
7387 delegate_variables(Term,Terms,VarDict,PrevVars,Vars) :-
7388 term_variables(Term,V1),
7389 term_variables(Terms,V2),
7390 intersect_eq(V1,V2,V3),
7391 list_difference_eq(V3,PrevVars,V4),
7392 translate(V4,VarDict,Vars).
7395 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7396 simpagation_head2_worker([CurrentHead|PreHeads],NextHeads,NextIDs,ID,PragmaRule,F/A,O,Id,L,T) :-
7397 PragmaRule = pragma(Rule,ids(IDs1,_),Pragmas,_,RuleNb),
7398 Rule = rule(_,_,Guard,Body),
7399 get_prop_inner_loop_vars(PreHeads,[CurrentHead,NextHeads,Guard,Body],PreVarsAndSusps,VarDict,Susp,Vars,PreSusps),
7402 gen_var(OtherSusps),
7404 functor(CurrentHead,OtherF,OtherA),
7405 gen_vars(OtherA,OtherVars),
7406 head_info(CurrentHead,OtherA,OtherVars,OtherSusp,_VarsSusp,HeadPairs),
7407 get_constraint_mode(OtherF/OtherA,Mode),
7408 head_arg_matches(HeadPairs,Mode,VarDict,FirstMatching,VarDict1,[],GroundVars),
7410 delay_phase_end(validate_store_type_assumptions,
7411 ( static_suspension_term(OtherF/OtherA,OtherSuspension),
7412 get_static_suspension_field(OtherF/OtherA,OtherSuspension,state,active,GetState),
7413 get_static_suspension_term_field(arguments,OtherF/OtherA,OtherSuspension,OtherVars)
7416 % create_get_mutable_ref(active,State,GetMutable),
7417 different_from_other_susps(CurrentHead,OtherSusp,PreHeads,PreSusps,DiffSuspGoals),
7419 OtherSusp = OtherSuspension,
7425 ClauseVars = [[OtherSusp|OtherSusps]|PreVarsAndSusps],
7426 build_head(F,A,[O|Id],ClauseVars,ClauseHead),
7428 guard_splitting(Rule,GuardList0),
7429 ( is_stored_in_guard(F/A, RuleNb) ->
7430 GuardList = [Hole1|GuardList0]
7432 GuardList = GuardList0
7434 guard_via_reschedule_new(NextHeads,GuardList,[CurrentHead|PreHeads],GuardCopyList,RestSuspsRetrieval,RescheduledTest),
7436 rest_heads_retrieval_and_matching(NextHeads,NextIDs,[CurrentHead|PreHeads],RestSuspsRetrieval,Susps,VarDict1,VarDict2,[CurrentHead|PreHeads],[OtherSusp|PreSusps],[]),
7437 split_by_ids(NextIDs,Susps,IDs1,Susps1,Susps2),
7438 split_by_ids(NextIDs,NextHeads,IDs1,RestHeads1,_),
7440 partner_constraint_detachments([OtherSusp | Susps1],[CurrentHead|RestHeads1],VarDict2,Susps1Detachments),
7442 RecursiveVars = [OtherSusps|PreVarsAndSusps],
7443 build_head(F,A,[O|Id],RecursiveVars,RecursiveCall),
7444 RecursiveVars2 = [[]|PreVarsAndSusps],
7445 build_head(F,A,[O|Id],RecursiveVars2,RecursiveCall2),
7447 guard_body_copies3(Rule,GuardList,VarDict2,GuardCopyList,BodyCopy),
7448 ( is_stored_in_guard(F/A, RuleNb) ->
7449 GuardCopyList = [GuardAttachment|_] % once( ) ??
7454 ( is_observed(F/A,O) ->
7455 gen_uncond_attach_goal(F/A,Susp,Vars,Attachment,Generation),
7456 gen_state_cond_call(Susp,F/A,RecursiveCall,Generation,ConditionalRecursiveCall),
7457 gen_state_cond_call(Susp,F/A,RecursiveCall2,Generation,ConditionalRecursiveCall2)
7460 ConditionalRecursiveCall = RecursiveCall,
7461 ConditionalRecursiveCall2 = RecursiveCall2
7464 ( chr_pp_flag(debugable,on) ->
7465 my_term_copy(Guard - Body, VarDict, DebugGuard - DebugBody),
7466 DebugTry = 'chr debug_event'( try([OtherSusp|Susps1],[Susp|Susps2],DebugGuard,DebugBody)),
7467 DebugApply = 'chr debug_event'(apply([OtherSusp|Susps1],[Susp|Susps2],DebugGuard,DebugBody))
7473 ( is_stored_in_guard(F/A, RuleNb) ->
7474 GuardAttachment = Attachment,
7475 BodyAttachment = true
7477 GuardAttachment = true,
7478 BodyAttachment = Attachment % will be true if not observed at all
7481 ( member(unique(ID1,UniqueKeys), Pragmas),
7482 check_unique_keys(UniqueKeys,VarDict) ->
7485 ( CurrentSuspTest ->
7492 ConditionalRecursiveCall2
7510 ConditionalRecursiveCall
7516 add_location(Clause,RuleNb,LocatedClause),
7517 L = [LocatedClause | T].
7519 gen_state_cond_call(Susp,FA,Call,Generation,ConditionalCall) :-
7520 ( may_trigger(FA) ->
7521 does_use_field(FA,generation),
7522 delay_phase_end(validate_store_type_assumptions,
7523 ( static_suspension_term(FA,Suspension),
7524 get_update_static_suspension_field(FA,Susp,Suspension,state,active,inactive,GetState,UpdateState),
7525 get_static_suspension_field(FA,Suspension,generation,Generation,GetGeneration),
7526 get_static_suspension_term_field(arguments,FA,Suspension,Args)
7530 delay_phase_end(validate_store_type_assumptions,
7531 ( static_suspension_term(FA,Suspension),
7532 get_update_static_suspension_field(FA,Susp,Suspension,state,active,inactive,GetState,UpdateState),
7533 get_static_suspension_term_field(arguments,FA,Suspension,Args)
7536 GetGeneration = true
7539 ( Susp = Suspension,
7548 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7551 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7553 %% | _ \ _ __ ___ _ __ __ _ __ _ __ _| |_(_) ___ _ __
7554 %% | |_) | '__/ _ \| '_ \ / _` |/ _` |/ _` | __| |/ _ \| '_ \
7555 %% | __/| | | (_) | |_) | (_| | (_| | (_| | |_| | (_) | | | |
7556 %% |_| |_| \___/| .__/ \__,_|\__, |\__,_|\__|_|\___/|_| |_|
7559 propagation_code(Head,ID,RestHeads,RestIDs,Rule,RuleNb,FA,O,Id,L,T) :-
7560 ( RestHeads == [] ->
7561 propagation_single_headed(Head,ID,Rule,RuleNb,FA,O,Id,L,T)
7563 propagation_multi_headed(Head,RestHeads,RestIDs,Rule,RuleNb,FA,O,Id,L,T)
7565 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7566 %% Single headed propagation
7567 %% everything in a single clause
7568 propagation_single_headed(Head,ID,Rule,RuleNb,F/A,O,Id,ProgramList,ProgramTail) :-
7569 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs),
7570 build_head(F,A,Id,VarsSusp,ClauseHead),
7573 build_head(F,A,NextId,VarsSusp,NextHead),
7575 get_constraint_mode(F/A,Mode),
7576 head_arg_matches(HeadPairs,Mode,[],HeadMatching,VarDict,[],GroundVars),
7577 guard_body_copies(Rule,VarDict,GuardCopy,BodyCopy),
7579 % - recursive call -
7580 RecursiveCall = NextHead,
7582 ( unconditional_occurrence(F/A,O), chr_pp_flag(late_allocation,on) ->
7588 Rule = rule(_,_,Guard,Body),
7589 ( chr_pp_flag(debugable,on) ->
7590 my_term_copy(Guard - Body, VarDict, DebugGuard - DebugBody),
7591 DebugTry = 'chr debug_event'( try([],[Susp],DebugGuard,DebugBody)),
7592 DebugApply = 'chr debug_event'(apply([],[Susp],DebugGuard,DebugBody)),
7593 instrument_goal(ActualCut,DebugTry,DebugApply,Cut)
7597 ( may_trigger(F/A), \+ has_no_history(RuleNb)->
7598 use_auxiliary_predicate(novel_production),
7599 use_auxiliary_predicate(extend_history),
7600 does_use_history(F/A,O),
7601 gen_occ_allocation(F/A,O,Vars,Susp,Allocation),
7603 ( named_history(RuleNb,HistoryName,HistoryIDs) ->
7604 ( HistoryIDs == [] ->
7605 empty_named_history_novel_production(HistoryName,NovelProduction),
7606 empty_named_history_extend_history(HistoryName,ExtendHistory)
7614 ( var(NovelProduction) ->
7615 NovelProduction = '$novel_production'(Susp,Tuple),
7616 ExtendHistory = '$extend_history'(Susp,Tuple)
7621 ( is_observed(F/A,O) ->
7622 gen_uncond_attach_goal(F/A,Susp,Vars,Attachment,Generation),
7623 gen_state_cond_call(Susp,F/A,RecursiveCall,Generation,ConditionalRecursiveCall)
7626 ConditionalRecursiveCall = RecursiveCall
7630 NovelProduction = true,
7631 ExtendHistory = true,
7633 ( is_observed(F/A,O) ->
7634 get_allocation_occurrence(F/A,AllocO),
7636 gen_insert_constraint_internal_goal(F/A,Attachment,VarsSusp,Vars,Susp),
7638 ; % more room for improvement?
7639 Attachment = (Attachment1, Attachment2),
7640 gen_occ_allocation(F/A,O,Vars,Susp,Attachment1),
7641 gen_uncond_attach_goal(F/A,Susp,Vars,Attachment2,Generation)
7643 gen_state_cond_call(Susp,F/A,RecursiveCall,Generation,ConditionalRecursiveCall)
7645 gen_occ_allocation(F/A,O,Vars,Susp,Attachment),
7646 ConditionalRecursiveCall = RecursiveCall
7650 ( is_stored_in_guard(F/A, RuleNb) ->
7651 GuardAttachment = Attachment,
7652 BodyAttachment = true
7654 GuardAttachment = true,
7655 BodyAttachment = Attachment % will be true if not observed at all
7669 ConditionalRecursiveCall
7671 add_location(Clause,RuleNb,LocatedClause),
7672 ProgramList = [LocatedClause | ProgramTail].
7674 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7675 %% multi headed propagation
7676 %% prelude + predicates to accumulate the necessary combinations of suspended
7677 %% constraints + predicate to execute the body
7678 propagation_multi_headed(Head,RestHeads,RestIDs,Rule,RuleNb,FA,O,Id,L,T) :-
7679 RestHeads = [First|Rest],
7680 propagation_prelude(Head,RestHeads,Rule,FA,O,Id,L,L1),
7681 extend_id(Id,ExtendedId),
7682 propagation_nested_code(Rest,[First,Head],RestIDs,Rule,RuleNb,FA,O,ExtendedId,L1,T).
7684 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7685 propagation_prelude(Head,[First|Rest],Rule,F/A,O,Id,L,T) :-
7686 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs),
7687 build_head(F,A,Id,VarsSusp,PreludeHead),
7688 get_constraint_mode(F/A,Mode),
7689 head_arg_matches(HeadPairs,Mode,[],FirstMatching,VarDict,[],GroundVars),
7690 Rule = rule(_,_,Guard,Body),
7691 extra_active_delegate_variables(Head,[First,Rest,Guard,Body],VarDict,ExtraVars),
7693 lookup_passive_head(First,[Head],VarDict,GroundVars,FirstSuspGoal,Susps),
7695 gen_occ_allocation(F/A,O,Vars,Susp,CondAllocation),
7697 extend_id(Id,NestedId),
7698 append([Susps|VarsSusp],ExtraVars,NestedVars),
7699 build_head(F,A,[O|NestedId],NestedVars,NestedHead),
7700 NestedCall = NestedHead,
7710 add_dummy_location(Prelude,LocatedPrelude),
7711 L = [LocatedPrelude|T].
7713 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7714 propagation_nested_code([],[CurrentHead|PreHeads],RestIDs,Rule,RuleNb,FA,O,Id,L,T) :-
7715 universal_search_iterator_end([CurrentHead|PreHeads],[],Rule,FA,O,Id,L,L1),
7716 propagation_body(CurrentHead,PreHeads,RestIDs,Rule,RuleNb,FA,O,Id,L1,T).
7718 propagation_nested_code([Head|RestHeads],PreHeads,RestIDs,Rule,RuleNb,FA,O,Id,L,T) :-
7719 universal_search_iterator_end(PreHeads,[Head|RestHeads],Rule,FA,O,Id,L,L1),
7720 universal_search_iterator([Head|RestHeads],PreHeads,Rule,FA,O,Id,L1,L2),
7722 propagation_nested_code(RestHeads,[Head|PreHeads],RestIDs,Rule,RuleNb,FA,O,IncId,L2,T).
7724 %check_fd_lookup_condition(_,_,_,_) :- fail.
7725 check_fd_lookup_condition(F,A,_,_) :-
7726 get_store_type(F/A,global_singleton), !.
7727 check_fd_lookup_condition(F,A,CurrentHead,PreHeads) :-
7728 \+ may_trigger(F/A),
7729 get_functional_dependency(F/A,1,P,K),
7730 copy_term(P-K,CurrentHead-Key),
7731 term_variables(PreHeads,PreVars),
7732 intersect_eq(Key,PreVars,Key),!.
7734 propagation_body(CurrentHead,PreHeads,RestIDs,Rule,RuleNb,F/A,O,Id,L,T) :-
7735 Rule = rule(_,H2,Guard,Body),
7736 gen_var_susp_list_for_b(PreHeads,[CurrentHead,Guard,Body],VarDict1,PreVarsAndSuspsList,FirstVarsSusp,AllSusps,PrevIterators),
7737 flatten(PreVarsAndSuspsList,PreVarsAndSusps),
7738 init(AllSusps,RestSusps),
7739 last(AllSusps,Susp),
7741 gen_var(OtherSusps),
7742 functor(CurrentHead,OtherF,OtherA),
7743 gen_vars(OtherA,OtherVars),
7744 delay_phase_end(validate_store_type_assumptions,
7745 ( static_suspension_term(OtherF/OtherA,Suspension),
7746 get_static_suspension_field(OtherF/OtherA,Suspension,state,active,GetState),
7747 get_static_suspension_term_field(arguments,OtherF/OtherA,Suspension,OtherVars)
7750 % create_get_mutable_ref(active,State,GetMutable),
7752 OtherSusp = Suspension,
7755 ClauseVars = [[OtherSusp|OtherSusps]|PreVarsAndSusps],
7756 build_head(F,A,[O|Id],ClauseVars,ClauseHead),
7757 ( check_fd_lookup_condition(OtherF,OtherA,CurrentHead,PreHeads) -> % iterator (OtherSusps) is empty at runtime
7758 universal_search_iterator_failure_vars(PreHeads,Id,PreVarsAndSuspsList,FirstVarsSusp,PrevIterators,PreVarsAndSusps1,PrevId0),
7759 RecursiveVars = PreVarsAndSusps1
7761 RecursiveVars = [OtherSusps|PreVarsAndSusps],
7767 PrevId = [O|PrevId0]
7769 build_head(F,A,PrevId,RecursiveVars,RecursiveHead),
7770 RecursiveCall = RecursiveHead,
7771 CurrentHead =.. [_|OtherArgs],
7772 pairup(OtherArgs,OtherVars,OtherPairs),
7773 get_constraint_mode(OtherF/OtherA,Mode),
7774 head_arg_matches(OtherPairs,Mode,VarDict1,Matching,VarDict),
7776 different_from_other_susps(CurrentHead,OtherSusp,PreHeads,RestSusps,DiffSuspGoals),
7777 guard_body_copies(Rule,VarDict,GuardCopy,BodyCopy),
7778 get_occurrence(F/A,O,_,ID),
7780 ( is_observed(F/A,O) ->
7781 init(FirstVarsSusp,FirstVars),
7782 gen_uncond_attach_goal(F/A,Susp,FirstVars,Attachment,Generation),
7783 gen_state_cond_call(Susp,F/A,RecursiveCall,Generation,ConditionalRecursiveCall)
7786 ConditionalRecursiveCall = RecursiveCall
7788 ( (is_least_occurrence(RuleNb) ; has_no_history(RuleNb)) ->
7789 NovelProduction = true,
7790 ExtendHistory = true
7791 ; \+ may_trigger(F/A), maplist(is_passive(RuleNb),RestIDs) ->
7792 NovelProduction = true,
7793 ExtendHistory = true
7795 get_occurrence(F/A,O,_,ID),
7796 use_auxiliary_predicate(novel_production),
7797 use_auxiliary_predicate(extend_history),
7798 does_use_history(F/A,O),
7799 ( named_history(RuleNb,HistoryName,HistoryIDs) ->
7800 ( HistoryIDs == [] ->
7801 empty_named_history_novel_production(HistoryName,NovelProduction),
7802 empty_named_history_extend_history(HistoryName,ExtendHistory)
7804 reverse([OtherSusp|RestSusps],NamedSusps),
7805 named_history_susps(HistoryIDs,[ID|RestIDs],[Susp|NamedSusps],HistorySusps),
7806 HistorySusps = [HistorySusp|_],
7808 ( length(HistoryIDs, 1) ->
7809 ExtendHistory = '$extend_history'(HistorySusp,HistoryName),
7810 NovelProduction = '$novel_production'(HistorySusp,HistoryName)
7812 findall(ConstraintSymbol,(member(SomeID,HistoryIDs),get_occurrence_from_id(ConstraintSymbol,_,RuleNb,SomeID)),ConstraintSymbols),
7813 Tuple =.. [t,HistoryName|HistorySusps]
7818 maplist(extract_symbol,H2,ConstraintSymbols),
7819 sort([ID|RestIDs],HistoryIDs),
7820 history_susps(RestIDs,[OtherSusp|RestSusps],Susp,ID,HistorySusps),
7821 Tuple =.. [t,RuleNb|HistorySusps]
7824 ( var(NovelProduction) ->
7825 novel_production_calls(ConstraintSymbols,HistoryIDs,HistorySusps,RuleNb,TupleVar,NovelProductions),
7826 ExtendHistory = '$extend_history'(HistorySusp,TupleVar),
7827 NovelProduction = ( TupleVar = Tuple, NovelProductions )
7834 ( chr_pp_flag(debugable,on) ->
7835 Rule = rule(_,_,Guard,Body),
7836 my_term_copy(Guard - Body, VarDict, DebugGuard - DebugBody),
7837 get_occurrence(F/A,O,_,ID),
7838 sort_by_key([Susp,OtherSusp|RestSusps],[ID|RestIDs],KeptSusps),
7839 DebugTry = 'chr debug_event'( try([],KeptSusps,DebugGuard,DebugBody)),
7840 DebugApply = 'chr debug_event'(apply([],KeptSusps,DebugGuard,DebugBody))
7846 ( is_stored_in_guard(F/A, RuleNb) ->
7847 GuardAttachment = Attachment,
7848 BodyAttachment = true
7850 GuardAttachment = true,
7851 BodyAttachment = Attachment % will be true if not observed at all
7867 ConditionalRecursiveCall
7871 add_location(Clause,RuleNb,LocatedClause),
7872 L = [LocatedClause|T].
7874 extract_symbol(Head,F/A) :-
7877 novel_production_calls([],[],[],_,_,true).
7878 novel_production_calls([ConstraintSymbol|ConstraintSymbols],[ID|IDs],[Suspension|Suspensions],RuleNb,Tuple,(Goal,Goals)) :-
7879 get_occurrence_from_id(ConstraintSymbol,Occurrence,RuleNb,ID),
7880 delay_phase_end(validate_store_type_assumptions,novel_production_call(ConstraintSymbol,Occurrence,'$novel_production'(Suspension,Tuple),Goal)),
7881 novel_production_calls(ConstraintSymbols,IDs,Suspensions,RuleNb,Tuple,Goals).
7883 history_susps(RestIDs,ReversedRestSusps,Susp,ID,HistorySusps) :-
7884 reverse(ReversedRestSusps,RestSusps),
7885 sort_by_key([Susp|RestSusps],[ID|RestIDs],HistorySusps).
7887 named_history_susps([],_,_,[]).
7888 named_history_susps([HistoryID|HistoryIDs],IDs,Susps,[HistorySusp|HistorySusps]) :-
7889 select2(HistoryID,HistorySusp,IDs,Susps,RestIDs,RestSusps), !,
7890 named_history_susps(HistoryIDs,RestIDs,RestSusps,HistorySusps).
7894 gen_var_susp_list_for([Head],Terms,VarDict,HeadVars,VarsSusp,Susp) :-
7897 head_info(Head,A,_Vars,Susp,VarsSusp,HeadPairs),
7898 get_constraint_mode(F/A,Mode),
7899 head_arg_matches(HeadPairs,Mode,[],_,VarDict),
7900 extra_active_delegate_variables(Head,Terms,VarDict,ExtraVars),
7901 append(VarsSusp,ExtraVars,HeadVars).
7902 gen_var_susp_list_for([Head|Heads],Terms,NVarDict,VarsSusps,Rest,Susps) :-
7903 gen_var_susp_list_for(Heads,[Head|Terms],VarDict,Rest,_,_),
7906 head_info(Head,A,_Vars,Susp,_VarsSusp,HeadPairs),
7907 get_constraint_mode(F/A,Mode),
7908 head_arg_matches(HeadPairs,Mode,VarDict,_,NVarDict),
7909 passive_delegate_variables(Head,Heads,Terms,NVarDict,HeadVars),
7910 append(HeadVars,[Susp,Susps|Rest],VarsSusps).
7913 % VarDict for the copies of variables in the original heads
7914 % VarsSuspsList list of lists of arguments for the successive heads
7915 % FirstVarsSusp top level arguments
7916 % SuspList list of all suspensions
7917 % Iterators list of all iterators
7918 gen_var_susp_list_for_b([Head],NextHeads,VarDict,[HeadVars],VarsSusp,[Susp],[]) :-
7921 head_info(Head,A,_Vars,Susp,VarsSusp,Pairs), % make variables for argument positions
7922 get_constraint_mode(F/A,Mode),
7923 head_arg_matches(Pairs,Mode,[],_,VarDict), % copy variables inside arguments, build dictionary
7924 extra_active_delegate_variables(Head,NextHeads,VarDict,ExtraVars), % decide what additional variables are needed
7925 append(VarsSusp,ExtraVars,HeadVars). % add additional variables to head variables
7926 gen_var_susp_list_for_b([Head|Heads],NextHeads,NVarDict,[Vars|RestVars],FirstVarsSusp,[Susp|SuspList],[Susps|Iterators]) :-
7927 gen_var_susp_list_for_b(Heads,[Head|NextHeads],VarDict,RestVars,FirstVarsSusp,SuspList,Iterators),
7930 head_info(Head,A,_Vars,Susp,_VarsSusp,HeadPairs),
7931 get_constraint_mode(F/A,Mode),
7932 head_arg_matches(HeadPairs,Mode,VarDict,_,NVarDict),
7933 passive_delegate_variables(Head,Heads,NextHeads,NVarDict,HeadVars),
7934 append(HeadVars,[Susp,Susps],Vars).
7936 get_prop_inner_loop_vars([Head],NextHeads,HeadVars,VarDict,Susp,Vars,[]) :-
7939 head_info(Head,A,Vars,Susp,VarsSusp,Pairs),
7940 get_constraint_mode(F/A,Mode),
7941 head_arg_matches(Pairs,Mode,[],_,VarDict),
7942 extra_active_delegate_variables(Head,NextHeads,VarDict,ExtraVars),
7943 append(VarsSusp,ExtraVars,HeadVars).
7944 get_prop_inner_loop_vars([Head|Heads],Terms,VarsSusps,NVarDict,MainSusp,MainVars,[Susp|RestSusps]) :-
7945 get_prop_inner_loop_vars(Heads,[Head|Terms],RestVarsSusp,VarDict,MainSusp,MainVars,RestSusps),
7948 head_info(Head,A,_Vars,Susp,_VarsSusp,Pairs),
7949 get_constraint_mode(F/A,Mode),
7950 head_arg_matches(Pairs,Mode,VarDict,_,NVarDict),
7951 passive_delegate_variables(Head,Heads,Terms,NVarDict,HeadVars),
7952 append(HeadVars,[Susp,Susps|RestVarsSusp],VarsSusps).
7954 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7956 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7958 %% | _ \ __ _ ___ ___(_)_ _____ | | | | ___ __ _ __| |
7959 %% | |_) / _` / __/ __| \ \ / / _ \ | |_| |/ _ \/ _` |/ _` |
7960 %% | __/ (_| \__ \__ \ |\ V / __/ | _ | __/ (_| | (_| |
7961 %% |_| \__,_|___/___/_| \_/ \___| |_| |_|\___|\__,_|\__,_|
7964 %% | _ \ ___| |_ _ __(_) _____ ____ _| |
7965 %% | |_) / _ \ __| '__| |/ _ \ \ / / _` | |
7966 %% | _ < __/ |_| | | | __/\ V / (_| | |
7967 %% |_| \_\___|\__|_| |_|\___| \_/ \__,_|_|
7970 %% | _ \ ___ ___ _ __ __| | ___ _ __(_)_ __ __ _
7971 %% | |_) / _ \/ _ \| '__/ _` |/ _ \ '__| | '_ \ / _` |
7972 %% | _ < __/ (_) | | | (_| | __/ | | | | | | (_| |
7973 %% |_| \_\___|\___/|_| \__,_|\___|_| |_|_| |_|\__, |
7976 reorder_heads(RuleNb,Head,RestHeads,RestIDs,NRestHeads,NRestIDs) :-
7977 ( chr_pp_flag(reorder_heads,on), length(RestHeads,Length), Length =< 6 ->
7978 reorder_heads_main(RuleNb,Head,RestHeads,RestIDs,NRestHeads,NRestIDs)
7980 NRestHeads = RestHeads,
7984 reorder_heads_main(RuleNb,Head,RestHeads,RestIDs,NRestHeads,NRestIDs) :-
7985 term_variables(Head,Vars),
7986 InitialData = entry([],[],Vars,RestHeads,RestIDs,RuleNb),
7987 copy_term_nat(InitialData,InitialDataCopy),
7988 a_star(InitialDataCopy,FD^(chr_translate:final_data(FD)),N^EN^C^(chr_translate:expand_data(N,EN,C)),FinalData),
7989 InitialDataCopy = InitialData,
7990 FinalData = entry(RNRestHeads,RNRestIDs,_,_,_,_),
7991 reverse(RNRestHeads,NRestHeads),
7992 reverse(RNRestIDs,NRestIDs).
7994 final_data(Entry) :-
7995 Entry = entry(_,_,_,_,[],_).
7997 expand_data(Entry,NEntry,Cost) :-
7998 Entry = entry(Heads,IDs,Vars,NHeads,NIDs,RuleNb),
7999 select2(Head1,ID1,NHeads,NIDs,NHeads1,NIDs1),
8000 term_variables([Head1|Vars],Vars1),
8001 NEntry = entry([Head1|Heads],[ID1|IDs],Vars1,NHeads1,NIDs1,RuleNb),
8002 order_score(Head1,ID1,Vars,NHeads1,RuleNb,Cost).
8004 % Assigns score to head based on known variables and heads to lookup
8005 % order_score(+head,+id,+knownvars,+heads,+rule_nb,-score).
8006 order_score(Head,ID,KnownVars,RestHeads,RuleNb,Score) :-
8008 get_store_type(F/A,StoreType),
8009 order_score(StoreType,Head,ID,KnownVars,RestHeads,RuleNb,Score).
8011 order_score(default,Head,_ID,KnownVars,RestHeads,RuleNb,Score) :-
8012 term_variables(Head,HeadVars),
8013 term_variables(RestHeads,RestVars),
8014 order_score_vars(HeadVars,KnownVars,RestVars,Score).
8015 order_score(multi_inthash(Indexes),Head,_ID,KnownVars,RestHeads,RuleNb,Score) :-
8016 order_score_indexes(Indexes,Head,KnownVars,0,Score).
8017 order_score(multi_hash(Indexes),Head,_ID,KnownVars,RestHeads,RuleNb,Score) :-
8018 order_score_indexes(Indexes,Head,KnownVars,0,Score).
8019 order_score(global_ground,Head,ID,KnownVars,RestHeads,RuleNb,Score) :-
8020 term_variables(Head,HeadVars),
8021 term_variables(RestHeads,RestVars),
8022 order_score_vars(HeadVars,KnownVars,RestVars,Score_),
8023 Score is Score_ * 2.
8024 order_score(var_assoc_store(_,_),_,_,_,_,_,1).
8025 order_score(global_singleton,_Head,ID,_KnownVars,_RestHeads,_RuleNb,Score) :-
8026 Score = 1. % guaranteed O(1)
8028 order_score(multi_store(StoreTypes),Head,ID,KnownVars,RestHeads,RuleNb,Score) :-
8029 maplist(order_score1(Head,ID,KnownVars,RestHeads,RuleNb),StoreTypes,Scores),
8030 min_list(Scores,Score).
8031 order_score1(Head,ID,KnownVars,RestHeads,RuleNb,StoreType,Score) :-
8032 ( order_score(StoreType,Head,ID,KnownVars,RestHeads,RuleNb,Score) ->
8037 order_score(identifier_store(Index),Head,ID,KnownVars,RestHeads,RuleNb,Score) :-
8039 order_score(type_indexed_identifier_store(_,_),Head,ID,KnownVars,RestHeads,RuleNb,Score) :-
8042 order_score_indexes([],_,_,Score,NScore) :-
8043 Score > 0, NScore = 100.
8044 order_score_indexes([I|Is],Head,KnownVars,Score,NScore) :-
8045 multi_hash_key_args(I,Head,Args), % TOM: not accurate enough? should look at vars?
8046 ( maplist(memberchk_eq_flip(KnownVars),Args) /* forall(Arg,Args,memberchk_eq(Arg,KnownVars)) */ ->
8051 order_score_indexes(Is,Head,KnownVars,Score1,NScore).
8053 memberchk_eq_flip(List,Element) :- memberchk_eq(Element,List).
8055 order_score_vars(Vars,KnownVars,RestVars,Score) :-
8056 order_score_count_vars(Vars,KnownVars,RestVars,K-R-O),
8060 Score is max(10 - K,0)
8062 Score is max(10 - R,1) * 10
8064 Score is max(10-O,1) * 100
8066 order_score_count_vars([],_,_,0-0-0).
8067 order_score_count_vars([V|Vs],KnownVars,RestVars,NK-NR-NO) :-
8068 order_score_count_vars(Vs,KnownVars,RestVars,K-R-O),
8069 ( memberchk_eq(V,KnownVars) ->
8072 ; memberchk_eq(V,RestVars) ->
8080 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8082 %% |_ _|_ __ | (_)_ __ (_)_ __ __ _
8083 %% | || '_ \| | | '_ \| | '_ \ / _` |
8084 %% | || | | | | | | | | | | | | (_| |
8085 %% |___|_| |_|_|_|_| |_|_|_| |_|\__, |
8089 create_get_mutable_ref(V,M,GM) :- GM = (M = mutable(V)).
8090 create_get_mutable(V,M,GM) :- M = mutable(V), GM = true.
8094 %% create_get_mutable(V,M,GM) :- GM = get_mutable(V,M).
8095 %% create_get_mutable_ref(V,M,GM) :- GM = get_mutable(V,M).
8098 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8100 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8102 %% | | | | |_(_) (_) |_ _ _
8103 %% | | | | __| | | | __| | | |
8104 %% | |_| | |_| | | | |_| |_| |
8105 %% \___/ \__|_|_|_|\__|\__, |
8108 % Create a fresh variable.
8111 % Create =N= fresh variables.
8115 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs) :-
8116 vars_susp(A,Vars,Susp,VarsSusp),
8118 pairup(Args,Vars,HeadPairs).
8120 inc_id([N|Ns],[O|Ns]) :-
8122 dec_id([N|Ns],[M|Ns]) :-
8125 extend_id(Id,[0|Id]).
8127 next_id([_,N|Ns],[O|Ns]) :-
8130 % return clause Head
8131 % for F/A constraint symbol, predicate identifier Id and arguments Head
8132 build_head(F,A,Id,Args,Head) :-
8133 buildName(F,A,Id,Name),
8134 ( (chr_pp_flag(debugable,on) ; is_stored(F/A), ( has_active_occurrence(F/A) ; chr_pp_flag(late_allocation,off)),
8135 ( may_trigger(F/A) ;
8136 get_allocation_occurrence(F/A,AO),
8137 get_max_occurrence(F/A,MO),
8139 Head =.. [Name|Args]
8141 init(Args,ArgsWOSusp), % XXX not entirely correct!
8142 Head =.. [Name|ArgsWOSusp]
8145 % return predicate name Result
8146 % for Fct/Aty constraint symbol and predicate identifier List
8147 buildName(Fct,Aty,List,Result) :-
8148 ( (chr_pp_flag(debugable,on) ; (once((is_stored(Fct/Aty), ( has_active_occurrence(Fct/Aty) ; chr_pp_flag(late_allocation,off)),
8149 ( may_trigger(Fct/Aty) ; get_allocation_occurrence(Fct/Aty,AO), get_max_occurrence(Fct/Aty,MO),
8150 MO >= AO ) ; List \= [0])) ) ) ->
8151 atom_concat(Fct, '___' ,FctSlash),
8152 atomic_concat(FctSlash,Aty,FctSlashAty),
8153 buildName_(List,FctSlashAty,Result)
8158 buildName_([],Name,Name).
8159 buildName_([N|Ns],Name,Result) :-
8160 buildName_(Ns,Name,Name1),
8161 atom_concat(Name1,'__',NameDash), % '_' is a char :-(
8162 atomic_concat(NameDash,N,Result).
8164 vars_susp(A,Vars,Susp,VarsSusp) :-
8166 append(Vars,[Susp],VarsSusp).
8168 or_pattern(Pos,Pat) :-
8170 Pat is 1 << Pow. % was 2 ** X
8172 and_pattern(Pos,Pat) :-
8174 Y is 1 << X, % was 2 ** X
8175 Pat is (-1)*(Y + 1).
8177 make_name(Prefix,F/A,Name) :-
8178 atom_concat_list([Prefix,F,'___',A],Name).
8180 %===============================================================================
8181 % Attribute for attributed variables
8183 make_attr(N,Mask,SuspsList,Attr) :-
8184 length(SuspsList,N),
8185 Attr =.. [v,Mask|SuspsList].
8187 get_all_suspensions2(N,Attr,SuspensionsList) :-
8188 chr_pp_flag(dynattr,off), !,
8189 make_attr(N,_,SuspensionsList,Attr).
8192 get_all_suspensions2(N,Attr,Goal,SuspensionsList) :-
8193 % writeln(get_all_suspensions2),
8194 length(SuspensionsList,N),
8195 Goal = 'chr all_suspensions'(SuspensionsList,1,Attr).
8199 normalize_attr(Attr,NormalGoal,NormalAttr) :-
8200 % writeln(normalize_attr),
8201 NormalGoal = 'chr normalize_attr'(Attr,NormalAttr).
8203 get_suspensions(N,Position,TAttr,(TAttr = Attr),Suspensions) :-
8204 chr_pp_flag(dynattr,off), !,
8205 make_attr(N,_,SuspsList,Attr),
8206 nth1(Position,SuspsList,Suspensions).
8209 get_suspensions(N,Position,TAttr,Goal,Suspensions) :-
8210 % writeln(get_suspensions),
8212 ( memberchk(Position-Suspensions,TAttr) ->
8218 %-------------------------------------------------------------------------------
8219 % +N: number of constraint symbols
8220 % +Suspension: source-level variable, for suspension
8221 % +Position: constraint symbol number
8222 % -Attr: source-level term, for new attribute
8223 singleton_attr(N,Suspension,Position,Attr) :-
8224 chr_pp_flag(dynattr,off), !,
8225 or_pattern(Position,Pattern),
8226 make_attr(N,Pattern,SuspsList,Attr),
8227 nth1(Position,SuspsList,[Suspension]),
8228 chr_delete(SuspsList,[Suspension],RestSuspsList),
8229 set_elems(RestSuspsList,[]).
8232 singleton_attr(N,Suspension,Position,Attr) :-
8233 % writeln(singleton_attr),
8234 Attr = [Position-[Suspension]].
8236 %-------------------------------------------------------------------------------
8237 % +N: number of constraint symbols
8238 % +Suspension: source-level variable, for suspension
8239 % +Position: constraint symbol number
8240 % +TAttr: source-level variable, for old attribute
8241 % -Goal: goal for creating new attribute
8242 % -NTAttr: source-level variable, for new attribute
8243 add_attr(N,Suspension,Position,TAttr,Goal,NTAttr) :-
8244 chr_pp_flag(dynattr,off), !,
8245 make_attr(N,Mask,SuspsList,Attr),
8246 or_pattern(Position,Pattern),
8247 nth1(Position,SuspsList,Susps),
8248 substitute_eq(Susps,SuspsList,[Suspension|Susps],SuspsList1),
8249 make_attr(N,Mask,SuspsList1,NewAttr1),
8250 substitute_eq(Susps,SuspsList,[Suspension],SuspsList2),
8251 make_attr(N,NewMask,SuspsList2,NewAttr2),
8254 ( Mask /\ Pattern =:= Pattern ->
8257 NewMask is Mask \/ Pattern,
8263 add_attr(N,Suspension,Position,TAttr,Goal,NTAttr) :-
8264 % writeln(add_attr),
8266 ( 'chr select'(TAttr,Position-Suspensions,RAttr) ->
8267 NTAttr = [Position-[Suspension|Suspensions]|RAttr]
8269 NTAttr = [Position-[Suspension]|TAttr]
8272 rem_attr(N,Var,Suspension,Position,TAttr,Goal) :-
8273 chr_pp_flag(dynattr,off), !,
8274 or_pattern(Position,Pattern),
8275 and_pattern(Position,DelPattern),
8276 make_attr(N,Mask,SuspsList,Attr),
8277 nth1(Position,SuspsList,Susps),
8278 substitute_eq(Susps,SuspsList,[],SuspsList1),
8279 make_attr(N,NewMask,SuspsList1,Attr1),
8280 substitute_eq(Susps,SuspsList,NewSusps,SuspsList2),
8281 make_attr(N,Mask,SuspsList2,Attr2),
8282 get_target_module(Mod),
8285 ( Mask /\ Pattern =:= Pattern ->
8286 'chr sbag_del_element'(Susps,Suspension,NewSusps),
8288 NewMask is Mask /\ DelPattern,
8292 put_attr(Var,Mod,Attr1)
8295 put_attr(Var,Mod,Attr2)
8303 rem_attr(N,Var,Suspension,Position,TAttr,Goal) :-
8304 % writeln(rem_attr),
8305 get_target_module(Mod),
8307 ( 'chr select'(TAttr,Position-Suspensions,RAttr) ->
8308 'chr sbag_del_element'(Suspensions,Suspension,NSuspensions),
8309 ( NSuspensions == [] ->
8313 put_attr(Var,Mod,RAttr)
8316 put_attr(Var,Mod,[Position-NSuspensions|RAttr])
8322 %-------------------------------------------------------------------------------
8323 % +N: number of constraint symbols
8324 % +TAttr1: source-level variable, for attribute
8325 % +TAttr2: source-level variable, for other attribute
8326 % -Goal: goal for merging the two attributes
8327 % -Attr: source-level term, for merged attribute
8328 merge_attributes(N,TAttr1,TAttr2,Goal,Attr) :-
8329 chr_pp_flag(dynattr,off), !,
8330 make_attr(N,Mask1,SuspsList1,Attr1),
8331 merge_attributes2(N,Mask1,SuspsList1,TAttr2,Goal2,Attr),
8338 merge_attributes(N,TAttr1,TAttr2,Goal,Attr) :-
8339 % writeln(merge_attributes),
8341 sort(TAttr1,Sorted1),
8342 sort(TAttr2,Sorted2),
8343 'chr new_merge_attributes'(Sorted1,Sorted2,Attr)
8347 %-------------------------------------------------------------------------------
8348 % +N: number of constraint symbols
8350 % +SuspsList1: static term, for suspensions list
8351 % +TAttr2: source-level variable, for other attribute
8352 % -Goal: goal for merging the two attributes
8353 % -Attr: source-level term, for merged attribute
8354 merge_attributes2(N,Mask1,SuspsList1,TAttr2,Goal,Attr) :-
8355 make_attr(N,Mask2,SuspsList2,Attr2),
8356 bagof(G,X ^ Y ^ SY ^ M ^ (member2(SuspsList1,SuspsList2,X-Y),G = (sort(Y,SY),'chr merge_attributes'(X,SY,M))),Gs),
8357 list2conj(Gs,SortGoals),
8358 bagof(MS,A ^ B ^ C ^ member((A,'chr merge_attributes'(B,C,MS)),Gs), SuspsList),
8359 make_attr(N,Mask,SuspsList,Attr),
8363 Mask is Mask1 \/ Mask2
8367 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8368 % Storetype dependent lookup
8370 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8371 %% lookup_passive_head(+Head,+PreviousVars,+RenamingVarDict,
8372 %% -Goal,-SuspensionList) is det.
8374 % Create a universal lookup goal for given head.
8375 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8376 lookup_passive_head(Head,PreJoin,VarDict,Goal,AllSusps) :-
8378 get_store_type(F/A,StoreType),
8379 lookup_passive_head(StoreType,Head,PreJoin,VarDict,[],Goal,AllSusps).
8381 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8382 %% lookup_passive_head(+Head,+PreviousVars,+RenamingVarDict,+GroundVars,
8383 %% -Goal,-SuspensionList) is det.
8385 % Create a universal lookup goal for given head.
8386 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8387 lookup_passive_head(Head,PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
8389 get_store_type(F/A,StoreType),
8390 lookup_passive_head(StoreType,Head,PreJoin,VarDict,GroundVars,Goal,AllSusps).
8392 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8393 %% lookup_passive_head(+StoreType,+Head,+PreviousVars,+RenamingVarDict,
8394 %% +GroundVars,-Goal,-SuspensionList) is det.
8396 % Create a universal lookup goal for given head.
8397 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8398 lookup_passive_head(default,Head,PreJoin,VarDict,_,Goal,AllSusps) :-
8400 passive_head_via(Head,PreJoin,VarDict,Goal,AllSusps),
8401 update_store_type(F/A,default).
8402 lookup_passive_head(multi_inthash(Indexes),Head,_PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
8403 hash_lookup_passive_head(inthash,Indexes,Head,VarDict,GroundVars,Goal,AllSusps,_).
8404 lookup_passive_head(multi_hash(Indexes),Head,_PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
8405 hash_lookup_passive_head(hash,Indexes,Head,VarDict,GroundVars,Goal,AllSusps,_).
8406 lookup_passive_head(global_ground,Head,_PreJoin,_VarDict,_,(Goal,AllSusps \== []),AllSusps) :-
8408 global_ground_store_name(F/A,StoreName),
8409 make_get_store_goal(StoreName,AllSusps,Goal), % Goal = nb_getval(StoreName,AllSusps),
8410 update_store_type(F/A,global_ground).
8411 lookup_passive_head(var_assoc_store(VarIndex,KeyIndex),Head,_PreJoin,VarDict,_,Goal,AllSusps) :-
8412 arg(VarIndex,Head,OVar),
8413 arg(KeyIndex,Head,OKey),
8414 translate([OVar,OKey],VarDict,[Var,Key]),
8415 get_target_module(Module),
8417 get_attr(Var,Module,AssocStore),
8418 lookup_assoc_store(AssocStore,Key,AllSusps)
8420 lookup_passive_head(global_singleton,Head,_PreJoin,_VarDict,_,Goal,AllSusps) :-
8422 global_singleton_store_name(F/A,StoreName),
8423 make_get_store_goal(StoreName,Susp,GetStoreGoal),
8424 Goal = (GetStoreGoal,Susp \== [],AllSusps = [Susp]),
8425 update_store_type(F/A,global_singleton).
8426 lookup_passive_head(multi_store(StoreTypes),Head,PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
8428 member(ST,StoreTypes),
8429 lookup_passive_head(ST,Head,PreJoin,VarDict,GroundVars,Goal,AllSusps)
8431 lookup_passive_head(identifier_store(Index),Head,PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
8433 arg(Index,Head,Var),
8434 translate([Var],VarDict,[KeyVar]),
8435 delay_phase_end(validate_store_type_assumptions,
8436 identifier_lookup(F/A,Index,AllSusps,KeyVar,Goal)
8438 update_store_type(F/A,identifier_store(Index)),
8439 get_identifier_index(F/A,Index,_).
8440 lookup_passive_head(type_indexed_identifier_store(Index,IndexType),Head,PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
8442 arg(Index,Head,Var),
8444 translate([Var],VarDict,[KeyVar]),
8446 ; ground(Var), Var = '$chr_identifier_match'(ActualVar,_) ->
8447 lookup_identifier_atom(IndexType,ActualVar,KeyVar,LookupGoal),
8448 Goal = (LookupGoal,StructGoal)
8450 delay_phase_end(validate_store_type_assumptions,
8451 type_indexed_identifier_lookup(F/A,Index,IndexType,AllSusps,KeyVar,StructGoal)
8453 update_store_type(F/A,type_indexed_identifier_store(Index,IndexType)),
8454 get_type_indexed_identifier_index(IndexType,F/A,Index,_).
8456 identifier_lookup(C,Index,AllSusps,KeyVar,Goal) :-
8457 get_identifier_size(ISize),
8458 functor(Struct,struct,ISize),
8459 get_identifier_index(C,Index,IIndex),
8460 arg(IIndex,Struct,AllSusps),
8461 Goal = (KeyVar = Struct).
8463 type_indexed_identifier_lookup(C,Index,IndexType,AllSusps,KeyVar,Goal) :-
8464 type_indexed_identifier_structure(IndexType,Struct),
8465 get_type_indexed_identifier_index(IndexType,C,Index,IIndex),
8466 arg(IIndex,Struct,AllSusps),
8467 Goal = (KeyVar = Struct).
8469 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8470 %% hash_lookup_passive_head(+StoreType,+Indexes,+Head,+RenamingVarDict,
8471 %% +GroundVars,-Goal,-SuspensionList,-Index) is det.
8473 % Create a universal hash lookup goal for given head.
8474 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8475 hash_lookup_passive_head(HashType,Indexes,Head,VarDict,GroundVars,Goal,AllSusps,Index) :-
8477 member(Index,Indexes),
8478 multi_hash_key_args(Index,Head,KeyArgs),
8480 translate(KeyArgs,VarDict,KeyArgCopies)
8482 ground(KeyArgs), KeyArgCopies = KeyArgs
8485 ( KeyArgCopies = [KeyCopy] ->
8488 KeyCopy =.. [k|KeyArgCopies]
8491 multi_hash_lookup_goal(F/A,HashType,Index,KeyCopy,AllSusps,LookupGoal),
8493 check_ground(GroundVars,KeyArgs,OriginalGroundCheck),
8494 my_term_copy(OriginalGroundCheck,VarDict,GroundCheck),
8496 Goal = (GroundCheck,LookupGoal),
8498 ( HashType == inthash ->
8499 update_store_type(F/A,multi_inthash([Index]))
8501 update_store_type(F/A,multi_hash([Index]))
8504 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8505 %% existential_lookup(+StoreType,+Head,+PrevVariablesHead,+RenamingVarDict,
8506 %% +GroundVariables,-SuspensionTerm,-Goal,-SuspVar,
8507 %% +VarArgDict,-NewVarArgDict) is det.
8509 % Create existential lookup goal for given head.
8510 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8511 existential_lookup(var_assoc_store(VarIndex,KeyIndex),Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,Pairs) :- !,
8512 lookup_passive_head(var_assoc_store(VarIndex,KeyIndex),Head,PreJoin,VarDict,GroundVars,UniversalGoal,AllSusps),
8513 sbag_member_call(Susp,AllSusps,Sbag),
8515 delay_phase_end(validate_store_type_assumptions,
8516 ( static_suspension_term(F/A,SuspTerm),
8517 get_static_suspension_field(F/A,SuspTerm,state,active,GetState)
8526 existential_lookup(global_singleton,Head,_PreJoin,_VarDict,_,SuspTerm,Goal,Susp,Pairs,Pairs) :- !,
8528 global_singleton_store_name(F/A,StoreName),
8529 make_get_store_goal(StoreName,Susp,GetStoreGoal),
8531 GetStoreGoal, % nb_getval(StoreName,Susp),
8535 update_store_type(F/A,global_singleton).
8536 existential_lookup(multi_store(StoreTypes),Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :- !,
8538 member(ST,StoreTypes),
8539 existential_lookup(ST,Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs)
8541 existential_lookup(multi_inthash(Indexes),Head,_,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :- !,
8542 existential_hash_lookup(inthash,Indexes,Head,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs).
8543 existential_lookup(multi_hash(Indexes),Head,_,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :- !,
8544 existential_hash_lookup(hash,Indexes,Head,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs).
8545 existential_lookup(identifier_store(Index),Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :- !,
8546 lookup_passive_head(identifier_store(Index),Head,PreJoin,VarDict,GroundVars,LookupGoal,AllSusps),
8547 hash_index_filter(Pairs,Index,NPairs),
8550 ( check_fd_lookup_condition(F,A,Head,KeyArgs) ->
8551 Sbag = (AllSusps = [Susp])
8553 sbag_member_call(Susp,AllSusps,Sbag)
8555 delay_phase_end(validate_store_type_assumptions,
8556 ( static_suspension_term(F/A,SuspTerm),
8557 get_static_suspension_field(F/A,SuspTerm,state,active,GetState)
8563 Susp = SuspTerm, % not inlined
8566 existential_lookup(type_indexed_identifier_store(Index,IndexType),Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :- !,
8567 lookup_passive_head(type_indexed_identifier_store(Index,IndexType),Head,PreJoin,VarDict,GroundVars,LookupGoal,AllSusps),
8568 hash_index_filter(Pairs,Index,NPairs),
8571 ( check_fd_lookup_condition(F,A,Head,KeyArgs) ->
8572 Sbag = (AllSusps = [Susp])
8574 sbag_member_call(Susp,AllSusps,Sbag)
8576 delay_phase_end(validate_store_type_assumptions,
8577 ( static_suspension_term(F/A,SuspTerm),
8578 get_static_suspension_field(F/A,SuspTerm,state,active,GetState)
8584 Susp = SuspTerm, % not inlined
8587 existential_lookup(StoreType,Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,Pairs) :-
8588 lookup_passive_head(StoreType,Head,PreJoin,VarDict,GroundVars,UGoal,Susps),
8589 sbag_member_call(Susp,Susps,Sbag),
8591 delay_phase_end(validate_store_type_assumptions,
8592 ( static_suspension_term(F/A,SuspTerm),
8593 get_static_suspension_field(F/A,SuspTerm,state,active,GetState)
8599 Susp = SuspTerm, % not inlined
8603 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8604 %% existential_hash_lookup(+StoreType,+Indexes,+Head,+RenamingVarDict,
8605 %% +GroundVariables,-SuspensionTerm,-Goal,-SuspVar,
8606 %% +VarArgDict,-NewVarArgDict) is det.
8608 % Create existential hash lookup goal for given head.
8609 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8610 existential_hash_lookup(HashType,Indexes,Head,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :-
8611 hash_lookup_passive_head(HashType,Indexes,Head,VarDict,GroundVars,LookupGoal,AllSusps,Index),
8613 hash_index_filter(Pairs,Index,NPairs),
8616 ( check_fd_lookup_condition(F,A,Head,KeyArgs) ->
8617 Sbag = (AllSusps = [Susp])
8619 sbag_member_call(Susp,AllSusps,Sbag)
8621 delay_phase_end(validate_store_type_assumptions,
8622 ( static_suspension_term(F/A,SuspTerm),
8623 get_static_suspension_field(F/A,SuspTerm,state,active,GetState)
8629 Susp = SuspTerm, % not inlined
8633 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8634 %% hash_index_filter(+Pairs,+Index,-NPairs) is det.
8636 % Filter out pairs already covered by given hash index.
8637 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8638 hash_index_filter(Pairs,Index,NPairs) :-
8639 hash_index_filter(Pairs,Index,1,NPairs).
8641 hash_index_filter([],_,_,[]).
8642 hash_index_filter([P|Ps],Index,N,NPairs) :-
8647 hash_index_filter(Ps,[I|Is],NN,NPs)
8649 hash_index_filter(Ps,Is,NN,NPairs)
8655 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8656 %------------------------------------------------------------------------------%
8657 %% assume_constraint_stores(+ConstraintSymbols) is det.
8659 % Compute all constraint store types that are possible for the given
8660 % =ConstraintSymbols=.
8661 %------------------------------------------------------------------------------%
8662 assume_constraint_stores([]).
8663 assume_constraint_stores([C|Cs]) :-
8664 ( chr_pp_flag(debugable,off),
8665 ( only_ground_indexed_arguments(C) ; chr_pp_flag(mixed_stores,on) ),
8667 get_store_type(C,default) ->
8668 get_indexed_arguments(C,AllIndexedArgs),
8669 get_constraint_mode(C,Modes),
8670 aggregate_all(bag(Index)-count,
8671 (member(Index,AllIndexedArgs),nth1(Index,Modes,+)),
8672 IndexedArgs-NbIndexedArgs),
8673 % Construct Index Combinations
8674 ( NbIndexedArgs > 10 ->
8675 findall([Index],member(Index,IndexedArgs),Indexes)
8677 findall(Index,(sublist(Index,IndexedArgs), Index \== []),UnsortedIndexes),
8678 predsort(longer_list,UnsortedIndexes,Indexes)
8680 % EXPERIMENTAL HEURISTIC
8682 % member(Arg1,IndexedArgs),
8683 % member(Arg2,IndexedArgs),
8685 % sort([Arg1,Arg2], Index)
8686 % ), UnsortedIndexes),
8687 % predsort(longer_list,UnsortedIndexes,Indexes),
8689 ( get_functional_dependency(C,1,Pattern,Key),
8690 all_distinct_var_args(Pattern), Key == [] ->
8691 assumed_store_type(C,global_singleton)
8692 ; ( only_ground_indexed_arguments(C) ; NbIndexedArgs > 0 ) ->
8693 get_constraint_type_det(C,ArgTypes),
8694 partition_indexes(Indexes,ArgTypes,HashIndexes,IntHashIndexes,IdentifierIndexes,CompoundIdentifierIndexes),
8696 ( IntHashIndexes = [] ->
8699 Stores = [multi_inthash(IntHashIndexes)|Stores1]
8701 ( HashIndexes = [] ->
8704 Stores1 = [multi_hash(HashIndexes)|Stores2]
8706 ( IdentifierIndexes = [] ->
8709 maplist(wrap_in_functor(identifier_store),IdentifierIndexes,WrappedIdentifierIndexes),
8710 append(WrappedIdentifierIndexes,Stores3,Stores2)
8712 append(CompoundIdentifierIndexes,Stores4,Stores3),
8713 ( only_ground_indexed_arguments(C)
8714 -> Stores4 = [global_ground]
8715 ; Stores4 = [default]
8717 assumed_store_type(C,multi_store(Stores))
8723 assume_constraint_stores(Cs).
8725 %------------------------------------------------------------------------------%
8726 %% partition_indexes(+Indexes,+Types,
8727 %% -HashIndexes,-IntHashIndexes,-IdentifierIndexes) is det.
8728 %------------------------------------------------------------------------------%
8729 partition_indexes([],_,[],[],[],[]).
8730 partition_indexes([Index|Indexes],Types,HashIndexes,IntHashIndexes,IdentifierIndexes,CompoundIdentifierIndexes) :-
8733 unalias_type(Type,UnAliasedType),
8734 UnAliasedType == chr_identifier ->
8735 IdentifierIndexes = [I|RIdentifierIndexes],
8736 IntHashIndexes = RIntHashIndexes,
8737 HashIndexes = RHashIndexes,
8738 CompoundIdentifierIndexes = RCompoundIdentifierIndexes
8741 unalias_type(Type,UnAliasedType),
8742 nonvar(UnAliasedType),
8743 UnAliasedType = chr_identifier(IndexType) ->
8744 CompoundIdentifierIndexes = [type_indexed_identifier_store(I,IndexType)|RCompoundIdentifierIndexes],
8745 IdentifierIndexes = RIdentifierIndexes,
8746 IntHashIndexes = RIntHashIndexes,
8747 HashIndexes = RHashIndexes
8750 unalias_type(Type,UnAliasedType),
8751 UnAliasedType == dense_int ->
8752 IntHashIndexes = [Index|RIntHashIndexes],
8753 HashIndexes = RHashIndexes,
8754 IdentifierIndexes = RIdentifierIndexes,
8755 CompoundIdentifierIndexes = RCompoundIdentifierIndexes
8758 unalias_type(Type,UnAliasedType),
8759 nonvar(UnAliasedType),
8760 UnAliasedType = chr_identifier(_) ->
8761 % don't use chr_identifiers in hash indexes
8762 IntHashIndexes = RIntHashIndexes,
8763 HashIndexes = RHashIndexes,
8764 IdentifierIndexes = RIdentifierIndexes,
8765 CompoundIdentifierIndexes = RCompoundIdentifierIndexes
8767 IntHashIndexes = RIntHashIndexes,
8768 HashIndexes = [Index|RHashIndexes],
8769 IdentifierIndexes = RIdentifierIndexes,
8770 CompoundIdentifierIndexes = RCompoundIdentifierIndexes
8772 partition_indexes(Indexes,Types,RHashIndexes,RIntHashIndexes,RIdentifierIndexes,RCompoundIdentifierIndexes).
8774 longer_list(R,L1,L2) :-
8784 all_distinct_var_args(Term) :-
8785 copy_term_nat(Term,TermCopy),
8787 functor(Pattern,F,A),
8788 Pattern =@= TermCopy.
8790 get_indexed_arguments(C,IndexedArgs) :-
8792 get_indexed_arguments(1,A,C,IndexedArgs).
8794 get_indexed_arguments(I,N,C,L) :-
8797 ; ( is_indexed_argument(C,I) ->
8803 get_indexed_arguments(J,N,C,T)
8806 validate_store_type_assumptions([]).
8807 validate_store_type_assumptions([C|Cs]) :-
8808 validate_store_type_assumption(C),
8809 validate_store_type_assumptions(Cs).
8811 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8812 % new code generation
8813 universal_search_iterator_end([CurrentHead|PrevHeads],NextHeads,Rule,F/A,O,Id,L,T) :-
8814 Rule = rule(H1,_,Guard,Body),
8815 gen_var_susp_list_for_b(PrevHeads,[CurrentHead,NextHeads,Guard,Body],_,VarsAndSuspsList,FirstVarsSusp,_,PrevIterators),
8816 universal_search_iterator_failure_vars(PrevHeads,Id,VarsAndSuspsList,FirstVarsSusp,PrevIterators,PrevVarsAndSusps,PrevId0),
8817 flatten(VarsAndSuspsList,VarsAndSusps),
8818 Vars = [ [] | VarsAndSusps],
8819 build_head(F,A,[O|Id],Vars,Head),
8821 get_success_continuation_code_id(F/A,O,PredictedPrevId),
8822 % format('~w == ~w ?\n',[PrevId0,PredictedPrevId]),
8823 PrevId = [PredictedPrevId] % PrevId = PrevId0
8825 PrevId = [O|PrevId0]
8827 build_head(F,A,PrevId,PrevVarsAndSusps,PredecessorCall),
8828 Clause = ( Head :- PredecessorCall),
8829 add_dummy_location(Clause,LocatedClause),
8830 L = [LocatedClause | T].
8832 % functor(CurrentHead,CF,CA),
8833 % check_fd_lookup_condition(CF,CA,CurrentHead,PrevHeads) ->
8836 % gen_var_susp_list_for_b(PrevHeads,[CurrentHead,NextHeads,Guard,Body],_,VarsAndSuspsList,FirstVarsSusp,_,PrevIterators),
8837 % universal_search_iterator_failure_vars(PrevHeads,Id,VarsAndSuspsList,FirstVarsSusp,PrevIterators,PrevVarsAndSusps,PrevId),
8838 % flatten(VarsAndSuspsList,VarsAndSusps),
8839 % Vars = [ [] | VarsAndSusps],
8840 % build_head(F,A,Id,Vars,Head),
8841 % build_head(F,A,PrevId,PrevVarsAndSusps,PredecessorCall),
8842 % Clause = ( Head :- PredecessorCall),
8846 % skips back intelligently over global_singleton lookups
8847 universal_search_iterator_failure_vars(PrevHeads,Id,VarsAndSuspsList,BaseCallArgs,PrevIterators,PrevVarsAndSusps,PrevId) :-
8849 % TOM: add partial success continuation optimization here!
8851 PrevVarsAndSusps = BaseCallArgs
8853 VarsAndSuspsList = [_|AllButFirstList],
8855 ( PrevHeads = [PrevHead|PrevHeads1],
8856 functor(PrevHead,F,A),
8857 check_fd_lookup_condition(F,A,PrevHead,PrevHeads1) ->
8858 PrevIterators = [_|PrevIterators1],
8859 universal_search_iterator_failure_vars(PrevHeads1,PrevId1,AllButFirstList,BaseCallArgs,PrevIterators1,PrevVarsAndSusps,PrevId)
8862 flatten(AllButFirstList,AllButFirst),
8863 PrevIterators = [PrevIterator|_],
8864 PrevVarsAndSusps = [PrevIterator|AllButFirst]
8868 universal_search_iterator([NextHead|RestHeads],[CurrentHead|PreHeads],Rule,F/A,O,Id,L,T) :-
8869 Rule = rule(_,_,Guard,Body),
8870 gen_var_susp_list_for_b(PreHeads,[CurrentHead,NextHead,RestHeads,Guard,Body],VarDict,PreVarsAndSuspsList,FirstVarsSusp,AllSusps,PrevIterators),
8871 init(AllSusps,PreSusps),
8872 flatten(PreVarsAndSuspsList,PreVarsAndSusps),
8873 gen_var(OtherSusps),
8874 functor(CurrentHead,OtherF,OtherA),
8875 gen_vars(OtherA,OtherVars),
8876 head_info(CurrentHead,OtherA,OtherVars,OtherSusp,_VarsSusp,HeadPairs),
8877 get_constraint_mode(OtherF/OtherA,Mode),
8878 head_arg_matches(HeadPairs,Mode,VarDict,FirstMatching,VarDict1),
8880 delay_phase_end(validate_store_type_assumptions,
8881 ( static_suspension_term(OtherF/OtherA,OtherSuspension),
8882 get_static_suspension_field(OtherF/OtherA,OtherSuspension,state,active,GetState),
8883 get_static_suspension_term_field(arguments,OtherF/OtherA,OtherSuspension,OtherVars)
8887 different_from_other_susps(CurrentHead,OtherSusp,PreHeads,PreSusps,DiffSuspGoals),
8888 % create_get_mutable_ref(active,State,GetMutable),
8890 OtherSusp = OtherSuspension,
8895 add_heads_ground_variables([CurrentHead|PreHeads],[],GroundVars),
8896 lookup_passive_head(NextHead,[CurrentHead|PreHeads],VarDict1,GroundVars,NextSuspGoal,NextSusps),
8897 inc_id(Id,NestedId),
8898 ClauseVars = [[OtherSusp|OtherSusps]|PreVarsAndSusps],
8899 build_head(F,A,[O|Id],ClauseVars,ClauseHead),
8900 passive_delegate_variables(CurrentHead,PreHeads,[NextHead,RestHeads,Guard,Body],VarDict1,CurrentHeadVars),
8901 append([NextSusps|CurrentHeadVars],[OtherSusp,OtherSusps|PreVarsAndSusps],NestedVars),
8902 build_head(F,A,[O|NestedId],NestedVars,NestedHead),
8904 ( check_fd_lookup_condition(OtherF,OtherA,CurrentHead,PreHeads) -> % iterator (OtherSusps) is empty at runtime
8905 universal_search_iterator_failure_vars(PreHeads,Id,PreVarsAndSuspsList,FirstVarsSusp,PrevIterators,PreVarsAndSusps1,PrevId0),
8906 RecursiveVars = PreVarsAndSusps1
8908 RecursiveVars = [OtherSusps|PreVarsAndSusps],
8914 PrevId = [O|PrevId0]
8916 build_head(F,A,PrevId,RecursiveVars,RecursiveHead),
8927 add_dummy_location(Clause,LocatedClause),
8928 L = [LocatedClause|T].
8930 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8932 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8933 % Observation Analysis
8938 % Analysis based on Abstract Interpretation paper.
8941 % stronger analysis domain [research]
8944 initial_call_pattern/1,
8946 call_pattern_worker/1,
8947 final_answer_pattern/2,
8948 abstract_constraints/1,
8952 ai_observed_internal/2,
8954 ai_not_observed_internal/2,
8958 ai_observation_gather_results/0.
8960 :- chr_type abstract_domain ---> odom(program_point,list(constraint)).
8961 :- chr_type program_point == any.
8963 :- chr_option(mode,initial_call_pattern(+)).
8964 :- chr_option(type_declaration,call_pattern(abstract_domain)).
8966 :- chr_option(mode,call_pattern(+)).
8967 :- chr_option(type_declaration,call_pattern(abstract_domain)).
8969 :- chr_option(mode,call_pattern_worker(+)).
8970 :- chr_option(type_declaration,call_pattern_worker(abstract_domain)).
8972 :- chr_option(mode,final_answer_pattern(+,+)).
8973 :- chr_option(type_declaration,final_answer_pattern(abstract_domain,abstract_domain)).
8975 :- chr_option(mode,abstract_constraints(+)).
8976 :- chr_option(type_declaration,abstract_constraints(list)).
8978 :- chr_option(mode,depends_on(+,+)).
8979 :- chr_option(type_declaration,depends_on(abstract_domain,abstract_domain)).
8981 :- chr_option(mode,depends_on_as(+,+,+)).
8982 :- chr_option(mode,depends_on_ap(+,+,+,+)).
8983 :- chr_option(mode,depends_on_goal(+,+)).
8984 :- chr_option(mode,ai_is_observed(+,+)).
8985 :- chr_option(mode,ai_not_observed(+,+)).
8986 % :- chr_option(mode,ai_observed(+,+)).
8987 :- chr_option(mode,ai_not_observed_internal(+,+)).
8988 :- chr_option(mode,ai_observed_internal(+,+)).
8991 abstract_constraints_fd @
8992 abstract_constraints(_) \ abstract_constraints(_) <=> true.
8994 ai_observed_internal(C,O) \ ai_not_observed_internal(C,O) <=> true.
8995 ai_not_observed_internal(C,O) \ ai_not_observed_internal(C,O) <=> true.
8996 ai_observed_internal(C,O) \ ai_observed_internal(C,O) <=> true.
8998 ai_not_observed(C,O) \ ai_is_observed(C,O) <=> fail.
8999 ai_is_observed(_,_) <=> true.
9001 ai_observation_gather_results \ ai_observed_internal(C,O) <=> true. % ai_observed(C,O).
9002 ai_observation_gather_results \ ai_not_observed_internal(C,O) <=> ai_not_observed(C,O).
9003 ai_observation_gather_results <=> true.
9005 %------------------------------------------------------------------------------%
9006 % Main Analysis Entry
9007 %------------------------------------------------------------------------------%
9008 ai_observation_analysis(ACs) :-
9009 ( chr_pp_flag(ai_observation_analysis,on),
9010 get_target_module(Module), '$chr_compiled_with_version'(3) -> % , Module \== guard_entailment ->
9011 list_to_ord_set(ACs,ACSet),
9012 abstract_constraints(ACSet),
9013 ai_observation_schedule_initial_calls(ACSet,ACSet),
9014 ai_observation_gather_results
9019 ai_observation_schedule_initial_calls([],_).
9020 ai_observation_schedule_initial_calls([AC|RACs],ACs) :-
9021 ai_observation_schedule_initial_call(AC,ACs),
9022 ai_observation_schedule_initial_calls(RACs,ACs).
9024 ai_observation_schedule_initial_call(AC,ACs) :-
9025 ai_observation_top(AC,CallPattern),
9026 % ai_observation_bot(AC,ACs,CallPattern),
9027 initial_call_pattern(CallPattern).
9029 ai_observation_schedule_new_calls([],AP).
9030 ai_observation_schedule_new_calls([AC|ACs],AP) :-
9032 initial_call_pattern(odom(AC,Set)),
9033 ai_observation_schedule_new_calls(ACs,AP).
9035 final_answer_pattern(CP,AP1) \ final_answer_pattern(CP,AP2)
9037 ai_observation_leq(AP2,AP1)
9041 initial_call_pattern(CP) \ initial_call_pattern(CP) <=> true.
9043 initial_call_pattern(CP) ==> call_pattern(CP).
9045 initial_call_pattern(CP), final_answer_pattern(CP,AP), abstract_constraints(ACs) # ID3
9047 ai_observation_schedule_new_calls(ACs,AP)
9051 call_pattern(CP) \ call_pattern(CP) <=> true.
9053 depends_on(CP1,CP2), final_answer_pattern(CP2,AP) ==>
9054 final_answer_pattern(CP1,AP).
9056 %call_pattern(CP) ==> writeln(call_pattern(CP)).
9058 call_pattern(CP) ==> call_pattern_worker(CP).
9060 %------------------------------------------------------------------------------%
9062 %------------------------------------------------------------------------------%
9065 %call_pattern(odom([],Set)) ==>
9066 % final_answer_pattern(odom([],Set),odom([],Set)).
9068 call_pattern_worker(odom([],Set)) <=>
9069 % writeln(' - AbstractGoal'(odom([],Set))),
9070 final_answer_pattern(odom([],Set),odom([],Set)).
9073 call_pattern_worker(odom([G|Gs],Set)) <=>
9074 % writeln(' - AbstractGoal'(odom([G|Gs],Set))),
9076 depends_on_goal(odom([G|Gs],Set),CP1),
9079 depends_on_goal(CP1,CP2), final_answer_pattern(CP2,AP2) \ depends_on(CP1,_) # ID
9080 <=> true pragma passive(ID).
9081 depends_on_goal(CP1,CP2), final_answer_pattern(CP2,AP2)
9083 CP1 = odom([_|Gs],_),
9087 depends_on(CP1,CCP).
9089 %------------------------------------------------------------------------------%
9090 % Abstract Disjunction
9091 %------------------------------------------------------------------------------%
9093 call_pattern_worker(odom((AG1;AG2),Set)) <=>
9094 CP = odom((AG1;AG2),Set),
9095 InitialAnswerApproximation = odom([],Set),
9096 final_answer_pattern(CP,InitialAnswerApproximation),
9097 CP1 = odom(AG1,Set),
9098 CP2 = odom(AG2,Set),
9101 depends_on_as(CP,CP1,CP2).
9103 %------------------------------------------------------------------------------%
9105 %------------------------------------------------------------------------------%
9106 call_pattern_worker(odom(builtin,Set)) <=>
9107 % writeln(' - AbstractSolve'(odom(builtin,Set))),
9108 ord_empty(EmptySet),
9109 final_answer_pattern(odom(builtin,Set),odom([],EmptySet)).
9111 %------------------------------------------------------------------------------%
9113 %------------------------------------------------------------------------------%
9114 max_occurrence(C,MO) # ID2 \ call_pattern_worker(odom(occ(C,O),Set))
9118 % writeln(' - AbstractDrop'(odom(occ(C,O),Set))),
9119 final_answer_pattern(odom(occ(C,O),Set),odom([],Set))
9123 %------------------------------------------------------------------------------%
9125 %------------------------------------------------------------------------------%
9126 call_pattern_worker(odom(AC,Set))
9130 % writeln(' - AbstractActivate'(odom(AC,Set))),
9131 CP = odom(occ(AC,1),Set),
9133 depends_on(odom(AC,Set),CP).
9135 %------------------------------------------------------------------------------%
9137 %------------------------------------------------------------------------------%
9138 occurrence(C,O,RuleNb,ID,_) # ID2 \ call_pattern_worker(odom(occ(C,O),Set))
9140 is_passive(RuleNb,ID)
9142 % writeln(' - AbstractPassive'(odom(occ(C,O),Set))),
9145 DCP = odom(occ(C,NO),Set),
9147 final_answer_pattern(odom(occ(C,O),Set),odom([],Set)),
9148 depends_on(odom(occ(C,O),Set),DCP)
9151 %------------------------------------------------------------------------------%
9153 %------------------------------------------------------------------------------%
9156 occurrence(C,O,RuleNb,ID,simplification) # ID2 \ call_pattern_worker(odom(occ(C,O),Set))
9158 \+ is_passive(RuleNb,ID)
9160 % writeln(' - AbstractPassive'(odom(occ(C,O),Set))),
9161 ai_observation_memo_simplification_rest_heads(C,O,AbstractRestHeads),
9162 ai_observation_observe_set(Set,AbstractRestHeads,Set2),
9163 ai_observation_memo_abstract_goal(RuleNb,AG),
9164 call_pattern(odom(AG,Set2)),
9167 DCP = odom(occ(C,NO),Set),
9169 depends_on_as(odom(occ(C,O),Set),odom(AG,Set2),DCP),
9170 % DEADLOCK AVOIDANCE
9171 final_answer_pattern(odom(occ(C,O),Set),odom([],Set))
9175 depends_on_as(CP,CPS,CPD),
9176 final_answer_pattern(CPS,APS),
9177 final_answer_pattern(CPD,APD) ==>
9178 ai_observation_lub(APS,APD,AP),
9179 final_answer_pattern(CP,AP).
9183 ai_observation_memo_simplification_rest_heads/3,
9184 ai_observation_memoed_simplification_rest_heads/3.
9186 :- chr_option(mode,ai_observation_memo_simplification_rest_heads(+,+,?)).
9187 :- chr_option(mode,ai_observation_memoed_simplification_rest_heads(+,+,+)).
9189 ai_observation_memoed_simplification_rest_heads(C,O,RH) \ ai_observation_memo_simplification_rest_heads(C,O,QRH)
9192 abstract_constraints(ACs) # ID1, occurrence(C,O,RuleNb,ID,_) # ID2, rule(RuleNb,Rule) # ID3 \ ai_observation_memo_simplification_rest_heads(C,O,QRH)
9194 Rule = pragma(rule(H1,H2,_,_),ids(IDs1,_),_,_,_),
9195 once(select2(ID,_,IDs1,H1,_,RestH1)),
9196 ai_observation_abstract_constraints(RestH1,ACs,ARestHeads),
9197 ai_observation_abstract_constraints(H2,ACs,AH2),
9198 append(ARestHeads,AH2,AbstractHeads),
9199 sort(AbstractHeads,QRH),
9200 ai_observation_memoed_simplification_rest_heads(C,O,QRH)
9206 ai_observation_memo_simplification_rest_heads(_,_,_) <=> fail.
9208 %------------------------------------------------------------------------------%
9209 % Abstract Propagate
9210 %------------------------------------------------------------------------------%
9214 occurrence(C,O,RuleNb,ID,propagation) # ID2 \ call_pattern_worker(odom(occ(C,O),Set))
9216 \+ is_passive(RuleNb,ID)
9218 % writeln(' - AbstractPropagate'(odom(occ(C,O),Set))),
9220 ai_observation_memo_propagation_rest_heads(C,O,AHs),
9221 ai_observation_observe_set(Set,AHs,Set2),
9222 ord_add_element(Set2,C,Set3),
9223 ai_observation_memo_abstract_goal(RuleNb,AG),
9224 call_pattern(odom(AG,Set3)),
9225 ( ord_memberchk(C,Set2) ->
9232 DCP = odom(occ(C,NO),Set),
9234 depends_on_ap(odom(occ(C,O),Set),odom(AG,Set3),DCP,Delete)
9239 ai_observation_memo_propagation_rest_heads/3,
9240 ai_observation_memoed_propagation_rest_heads/3.
9242 :- chr_option(mode,ai_observation_memo_propagation_rest_heads(+,+,?)).
9243 :- chr_option(mode,ai_observation_memoed_propagation_rest_heads(+,+,+)).
9245 ai_observation_memoed_propagation_rest_heads(C,O,RH) \ ai_observation_memo_propagation_rest_heads(C,O,QRH)
9248 abstract_constraints(ACs) # ID1, occurrence(C,O,RuleNb,ID,_) # ID2, rule(RuleNb,Rule) # ID3 \ ai_observation_memo_propagation_rest_heads(C,O,QRH)
9250 Rule = pragma(rule(H1,H2,_,_),ids(_,IDs2),_,_,_),
9251 once(select2(ID,_,IDs2,H2,_,RestH2)),
9252 ai_observation_abstract_constraints(RestH2,ACs,ARestHeads),
9253 ai_observation_abstract_constraints(H1,ACs,AH1),
9254 append(ARestHeads,AH1,AbstractHeads),
9255 sort(AbstractHeads,QRH),
9256 ai_observation_memoed_propagation_rest_heads(C,O,QRH)
9262 ai_observation_memo_propagation_rest_heads(_,_,_) <=> fail.
9264 depends_on_ap(CP,CPP,CPD,Delete), final_answer_pattern(CPD,APD) ==>
9265 final_answer_pattern(CP,APD).
9266 depends_on_ap(CP,CPP,CPD,Delete), final_answer_pattern(CPP,APP),
9267 final_answer_pattern(CPD,APD) ==>
9269 CP = odom(occ(C,O),_),
9270 ( ai_observation_is_observed(APP,C) ->
9271 ai_observed_internal(C,O)
9273 ai_not_observed_internal(C,O)
9276 APP = odom([],Set0),
9277 ord_del_element(Set0,C,Set),
9282 ai_observation_lub(NAPP,APD,AP),
9283 final_answer_pattern(CP,AP).
9285 %------------------------------------------------------------------------------%
9287 %------------------------------------------------------------------------------%
9289 call_pattern_worker(CP) <=> chr_error(internal,'AI observation analysis: unexpected abstract state ~w\n',[CP]).
9291 %------------------------------------------------------------------------------%
9292 % Auxiliary Predicates
9293 %------------------------------------------------------------------------------%
9295 ai_observation_lub(odom(AG,S1),odom(AG,S2),odom(AG,S3)) :-
9296 ord_intersection(S1,S2,S3).
9298 ai_observation_bot(AG,AS,odom(AG,AS)).
9300 ai_observation_top(AG,odom(AG,EmptyS)) :-
9303 ai_observation_leq(odom(AG,S1),odom(AG,S2)) :-
9306 ai_observation_observe_set(S,ACSet,NS) :-
9307 ord_subtract(S,ACSet,NS).
9309 ai_observation_abstract_constraint(C,ACs,AC) :-
9314 ai_observation_abstract_constraints(Cs,ACs,NACs) :-
9315 findall(NAC,(member(C,Cs),ai_observation_abstract_constraint(C,ACs,NAC)),NACs).
9317 %------------------------------------------------------------------------------%
9318 % Abstraction of Rule Bodies
9319 %------------------------------------------------------------------------------%
9322 ai_observation_memoed_abstract_goal/2,
9323 ai_observation_memo_abstract_goal/2.
9325 :- chr_option(mode,ai_observation_memoed_abstract_goal(+,+)).
9326 :- chr_option(mode,ai_observation_memo_abstract_goal(+,?)).
9328 ai_observation_memoed_abstract_goal(RuleNb,AG) # ID1 \ ai_observation_memo_abstract_goal(RuleNb,QAG)
9334 rule(RuleNb,Rule) # ID1, abstract_constraints(ACs) # ID2 \ ai_observation_memo_abstract_goal(RuleNb,QAG)
9336 Rule = pragma(rule(H1,H2,Guard,Body),_,_,_,_),
9337 ai_observation_abstract_goal_(H1,H2,Guard,Body,ACs,AG),
9339 ai_observation_memoed_abstract_goal(RuleNb,AG)
9344 ai_observation_abstract_goal_(H1,H2,Guard,G,ACs,AG) :-
9345 % also guard: e.g. b, c(X) ==> Y=X | p(Y).
9346 term_variables((H1,H2,Guard),HVars),
9347 append(H1,H2,Heads),
9348 % variables that are declared to be ground are safe,
9349 ground_vars(Heads,GroundVars),
9350 % so we remove them from the list of 'dangerous' head variables
9351 list_difference_eq(HVars,GroundVars,HV),
9352 ai_observation_abstract_goal(G,ACs,AG,[],HV),!.
9353 % writeln(ai_observation_abstract_goal(G,ACs,AG,[],HV)).
9354 % HV are 'dangerous' variables, all others are fresh and safe
9357 ground_vars([H|Hs],GroundVars) :-
9359 get_constraint_mode(F/A,Mode),
9360 % TOM: fix this code!
9361 head_info(H,A,_Vars,_Susp,_HeadVars,HeadPairs),
9362 head_arg_matches(HeadPairs,Mode,[],_FirstMatching,_VarDict1,[],GroundVars1),
9363 ground_vars(Hs,GroundVars2),
9364 append(GroundVars1,GroundVars2,GroundVars).
9366 ai_observation_abstract_goal((G1,G2),ACs,List,Tail,HV) :- !, % conjunction
9367 ai_observation_abstract_goal(G1,ACs,List,IntermediateList,HV),
9368 ai_observation_abstract_goal(G2,ACs,IntermediateList,Tail,HV).
9369 ai_observation_abstract_goal((G1;G2),ACs,[(ABranch1;ABranch2)|Tail],Tail,HV) :- !, % disjunction
9370 ai_observation_abstract_goal(G1,ACs,ABranch1,[],HV),
9371 ai_observation_abstract_goal(G2,ACs,ABranch2,[],HV).
9372 ai_observation_abstract_goal((G1->G2),ACs,List,Tail,HV) :- !, % if-then
9373 ai_observation_abstract_goal(G1,ACs,List,IntermediateList,HV),
9374 ai_observation_abstract_goal(G2,ACs,IntermediateList,Tail,HV).
9375 ai_observation_abstract_goal(C,ACs,[AC|Tail],Tail,HV) :-
9376 ai_observation_abstract_constraint(C,ACs,AC), !. % CHR constraint
9377 ai_observation_abstract_goal(true,_,Tail,Tail,_) :- !.
9378 ai_observation_abstract_goal(writeln(_),_,Tail,Tail,_) :- !.
9379 % non-CHR constraint is safe if it only binds fresh variables
9380 ai_observation_abstract_goal(G,_,Tail,Tail,HV) :-
9381 builtin_binds_b(G,Vars),
9382 intersect_eq(Vars,HV,[]),
9384 ai_observation_abstract_goal(G,_,[AG|Tail],Tail,_) :-
9385 AG = builtin. % default case if goal is not recognized/safe
9387 ai_observation_is_observed(odom(_,ACSet),AC) :-
9388 \+ ord_memberchk(AC,ACSet).
9390 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9391 unconditional_occurrence(C,O) :-
9392 get_occurrence(C,O,RuleNb,ID),
9393 get_rule(RuleNb,PRule),
9394 PRule = pragma(ORule,_,_,_,_),
9395 copy_term_nat(ORule,Rule),
9396 Rule = rule(H1,H2,Guard,_),
9397 guard_entailment:entails_guard([chr_pp_headvariables(H1,H2)],Guard),
9399 H1 = [Head], H2 == []
9401 H2 = [Head], H1 == [], \+ may_trigger(C)
9403 all_distinct_var_args(Head).
9405 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9407 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9408 % Partial wake analysis
9410 % In a Var = Var unification do not wake up constraints of both variables,
9411 % but rather only those of one variable.
9412 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9414 :- chr_constraint partial_wake_analysis/0.
9415 :- chr_constraint no_partial_wake/1.
9416 :- chr_option(mode,no_partial_wake(+)).
9417 :- chr_constraint wakes_partially/1.
9418 :- chr_option(mode,wakes_partially(+)).
9420 partial_wake_analysis, occurrence(FA,O,RuleNb,ID,Type), rule(RuleNb,Rule), constraint_mode(FA,ArgModes)
9422 Rule = pragma(rule(H1,H2,Guard,Body),_,_,_,_),
9423 ( is_passive(RuleNb,ID) ->
9425 ; Type == simplification ->
9426 select(H,H1,RestH1),
9428 term_variables(Guard,Vars),
9429 partial_wake_args(Args,ArgModes,Vars,FA)
9430 ; % Type == propagation ->
9431 select(H,H2,RestH2),
9433 term_variables(Guard,Vars),
9434 partial_wake_args(Args,ArgModes,Vars,FA)
9437 partial_wake_args([],_,_,_).
9438 partial_wake_args([Arg|Args],[Mode|Modes],Vars,C) :-
9442 ; memberchk_eq(Arg,Vars) ->
9450 partial_wake_args(Args,Modes,Vars,C).
9452 no_partial_wake(C) \ no_partial_wake(C) <=> true.
9454 no_partial_wake(C) \ wakes_partially(C) <=> fail.
9456 wakes_partially(C) <=> true.
9459 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9460 % Generate rules that implement chr_show_store/1 functionality.
9466 % Generates additional rules:
9468 % $show, C1 # ID ==> writeln(C1) pragma passive(ID).
9470 % $show, Cn # ID ==> writeln(Cn) pragma passive(ID).
9473 generate_show_constraint(Constraints0,Constraints,Rules0,Rules) :-
9474 ( chr_pp_flag(show,on) ->
9475 Constraints = ['$show'/0|Constraints0],
9476 generate_show_rules(Constraints0,Rules,[Rule|Rules0]),
9477 inc_rule_count(RuleNb),
9479 rule(['$show'],[],true,true),
9486 Constraints = Constraints0,
9490 generate_show_rules([],Rules,Rules).
9491 generate_show_rules([F/A|Rest],[Rule|Tail],Rules) :-
9493 inc_rule_count(RuleNb),
9495 rule([],['$show',C],true,writeln(C)),
9501 generate_show_rules(Rest,Tail,Rules).
9503 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9504 % Custom supension term layout
9506 static_suspension_term(F/A,Suspension) :-
9507 suspension_term_base(F/A,Base),
9509 functor(Suspension,suspension,Arity).
9511 has_suspension_field(FA,Field) :-
9512 suspension_term_base_fields(FA,Fields),
9513 memberchk(Field,Fields).
9515 suspension_term_base(FA,Base) :-
9516 suspension_term_base_fields(FA,Fields),
9517 length(Fields,Base).
9519 suspension_term_base_fields(FA,Fields) :-
9520 ( chr_pp_flag(debugable,on) ->
9523 % 3. Propagation History
9524 % 4. Generation Number
9525 % 5. Continuation Goal
9527 Fields = [id,state,history,generation,continuation,functor]
9529 ( uses_history(FA) ->
9530 Fields = [id,state,history|Fields2]
9531 ; only_ground_indexed_arguments(FA), get_functional_dependency(FA,1,_,_) ->
9532 Fields = [state|Fields2]
9534 Fields = [id,state|Fields2]
9536 ( only_ground_indexed_arguments(FA) ->
9537 get_store_type(FA,StoreType),
9538 basic_store_types(StoreType,BasicStoreTypes),
9539 ( memberchk(global_ground,BasicStoreTypes) ->
9542 % 3. Propagation History
9543 % 4. Global List Prev
9544 Fields2 = [global_list_prev|Fields3]
9548 % 3. Propagation History
9551 ( chr_pp_flag(ht_removal,on)
9552 -> ht_prev_fields(BasicStoreTypes,Fields3)
9555 ; may_trigger(FA) ->
9558 % 3. Propagation History
9559 ( uses_field(FA,generation) ->
9560 % 4. Generation Number
9561 % 5. Global List Prev
9562 Fields2 = [generation,global_list_prev|Fields3]
9564 Fields2 = [global_list_prev|Fields3]
9566 ( chr_pp_flag(mixed_stores,on),
9567 chr_pp_flag(ht_removal,on)
9568 -> get_store_type(FA,StoreType),
9569 basic_store_types(StoreType,BasicStoreTypes),
9570 ht_prev_fields(BasicStoreTypes,Fields3)
9576 % 3. Propagation History
9577 % 4. Global List Prev
9578 Fields2 = [global_list_prev|Fields3],
9579 ( chr_pp_flag(mixed_stores,on),
9580 chr_pp_flag(ht_removal,on)
9581 -> get_store_type(FA,StoreType),
9582 basic_store_types(StoreType,BasicStoreTypes),
9583 ht_prev_fields(BasicStoreTypes,Fields3)
9589 ht_prev_fields(Stores,Prevs) :-
9590 ht_prev_fields_int(Stores,PrevsList),
9591 append(PrevsList,Prevs).
9592 ht_prev_fields_int([],[]).
9593 ht_prev_fields_int([H|T],Fields) :-
9594 ( H = multi_hash(Indexes)
9595 -> maplist(ht_prev_field,Indexes,FH),
9599 ht_prev_fields_int(T,FT).
9601 ht_prev_field(Index,Field) :-
9602 concat_atom(['multi_hash_prev-'|Index],Field).
9604 get_static_suspension_term_field(FieldName,FA,StaticSuspension,Field) :-
9605 suspension_term_base_fields(FA,Fields),
9606 nth1(Index,Fields,FieldName), !,
9607 arg(Index,StaticSuspension,Field).
9608 get_static_suspension_term_field(arguments,FA,StaticSuspension,Field) :- !,
9609 suspension_term_base(FA,Base),
9610 StaticSuspension =.. [_|Args],
9611 drop(Base,Args,Field).
9612 get_static_suspension_term_field(FieldName,FA,_StaticSuspension,_Field) :-
9613 chr_error(internal,'Trying to obtain field ~w of ~w, wich does not have it!',[FieldName,FA]).
9616 get_dynamic_suspension_term_field(FieldName,FA,DynamicSuspension,Field,Goal) :-
9617 suspension_term_base_fields(FA,Fields),
9618 nth1(Index,Fields,FieldName), !,
9619 Goal = arg(Index,DynamicSuspension,Field).
9620 get_dynamic_suspension_term_field(arguments,FA,DynamicSuspension,Field,Goal) :- !,
9621 static_suspension_term(FA,StaticSuspension),
9622 get_static_suspension_term_field(arguments,FA,StaticSuspension,Field),
9623 Goal = (DynamicSuspension = StaticSuspension).
9624 get_dynamic_suspension_term_field(argument(I),FA,DynamicSuspension,Field,Goal) :- !,
9625 suspension_term_base(FA,Base),
9627 Goal = arg(Index,DynamicSuspension,Field).
9628 get_dynamic_suspension_term_field(FieldName,FA,_DynamicSuspension,_Field,_Goal) :-
9629 chr_error(internal,'Dynamic goal to get ~w of ~w, which does not have this field!',[FieldName,FA]).
9632 set_dynamic_suspension_term_field(FieldName,FA,DynamicSuspension,Field,Goal) :-
9633 suspension_term_base_fields(FA,Fields),
9634 nth1(Index,Fields,FieldName), !,
9635 Goal = setarg(Index,DynamicSuspension,Field).
9636 set_dynamic_suspension_term_field(FieldName,FA,_DynamicSuspension,_Field,_Goal) :-
9637 chr_error(internal,'Dynamic goal to set ~w of ~w, which does not have this field!',[FieldName,FA]).
9639 basic_store_types(multi_store(Types),Types) :- !.
9640 basic_store_types(Type,[Type]).
9642 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9649 :- chr_option(mode,phase_end(+)).
9650 :- chr_option(mode,delay_phase_end(+,?)).
9652 phase_end(Phase) \ delay_phase_end(Phase,Goal) <=> call(Goal).
9653 % phase_end(Phase) <=> true.
9656 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9660 novel_production_call/4.
9662 :- chr_option(mode,uses_history(+)).
9663 :- chr_option(mode,does_use_history(+,+)).
9664 :- chr_option(mode,novel_production_call(+,+,?,?)).
9666 does_use_history(FA,Occ) \ does_use_history(FA,Occ) <=> true.
9667 does_use_history(FA,_) \ uses_history(FA) <=> true.
9668 uses_history(_FA) <=> fail.
9670 does_use_history(FA,Occ) \ novel_production_call(FA,Occ,PossibleGoal,Goal) <=> Goal = PossibleGoal.
9671 novel_production_call(FA,_,_PossibleGoal,Goal) <=> Goal = true.
9677 :- chr_option(mode,uses_field(+,+)).
9678 :- chr_option(mode,does_use_field(+,+)).
9680 does_use_field(FA,Field) \ does_use_field(FA,Field) <=> true.
9681 does_use_field(FA,Field) \ uses_field(FA,Field) <=> true.
9682 uses_field(_FA,_Field) <=> fail.
9687 used_states_known/0.
9689 :- chr_option(mode,uses_state(+,+)).
9690 :- chr_option(mode,if_used_state(+,+,?,?,?)).
9693 % states ::= not_stored_yet | passive | active | triggered | removed
9695 % allocate CREATES not_stored_yet
9696 % remove CHECKS not_stored_yet
9697 % activate CHECKS not_stored_yet
9699 % ==> no allocate THEN no not_stored_yet
9701 % recurs CREATES inactive
9702 % lookup CHECKS inactive
9704 % insert CREATES active
9705 % activate CREATES active
9706 % lookup CHECKS active
9707 % recurs CHECKS active
9709 % runsusp CREATES triggered
9710 % lookup CHECKS triggered
9712 % ==> no runsusp THEN no triggered
9714 % remove CREATES removed
9715 % runsusp CHECKS removed
9716 % lookup CHECKS removed
9717 % recurs CHECKS removed
9719 % ==> no remove THEN no removed
9721 % ==> no allocate, no remove, no active/inactive distinction THEN no state at all...
9723 uses_state(Constraint,State) \ uses_state(Constraint,State) <=> true.
9725 used_states_known, uses_state(Constraint,State) \ if_used_state(Constraint,State,Used,NotUsed,ResultGoal)
9726 <=> ResultGoal = Used.
9727 used_states_known \ if_used_state(Constraint,State,Used,NotUsed,ResultGoal)
9728 <=> ResultGoal = NotUsed.
9730 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9731 % CHECK STOREDNESS ANNOTATIONS AND GENERATE DEFAULT SIMPLIFICATION RULES
9737 % When the programmer enables the `declare_stored_constraints' option, i.e. writes
9739 % :- chr_option(declare_stored_constraints,on).
9741 % the compiler will check for the storedness of constraints.
9743 % By default, the compiler assumes that the programmer wants his constraints to
9744 % be never-stored. Hence, a warning will be issues when a constraint is actually
9747 % Such warnings are suppressed, if the programmer adds the `# stored' modifier
9748 % to a constraint declaration, i.e. writes
9750 % :- chr_constraint c(...) # stored.
9752 % In that case a warning is issued when the constraint is never-stored.
9754 % NOTE: Checking is only performed if `storage_analysis' is on. Otherwise, all
9755 % constraints are stored anyway.
9758 % 2. Rule Generation
9759 % ~~~~~~~~~~~~~~~~~~
9761 % When the programmer enables the `declare_stored_constraints' option, i.e. writes
9763 % :- chr_option(declare_stored_constraints,on).
9765 % the compiler will generate default simplification rules for constraints.
9767 % By default, no default rule is generated for a constraint. However, if the
9768 % programmer writes a default/1 annotation in the constraint declaration, i.e. writes
9770 % :- chr_constraint c(...) # default(Goal).
9772 % where `Goal' is a ground and callable goal (e.g. `true', `fail' or `throw(error)'),
9773 % the compiler generates a rule:
9775 % c(_,...,_) <=> Goal.
9777 % at the end of the program. If multiple default rules are generated, for several constraints,
9778 % then the order of the default rules is not specified.
9781 :- chr_constraint stored_assertion/1.
9782 :- chr_option(mode,stored_assertion(+)).
9783 :- chr_option(type_declaration,stored_assertion(constraint)).
9785 :- chr_constraint never_stored_default/2.
9786 :- chr_option(mode,never_stored_default(+,?)).
9787 :- chr_option(type_declaration,never_stored_default(constraint,any)).
9792 generate_never_stored_rules(Constraints,Rules) :-
9793 ( chr_pp_flag(declare_stored_constraints,on) ->
9794 never_stored_rules(Constraints,Rules)
9799 :- chr_constraint never_stored_rules/2.
9800 :- chr_option(mode,never_stored_rules(+,?)).
9801 :- chr_option(type_declaration,never_stored_rules(list(constraint),any)).
9803 never_stored_rules([],Rules) <=> Rules = [].
9804 never_stored_default(Constraint,Goal) \ never_stored_rules([Constraint|Constraints],Rules) <=>
9807 inc_rule_count(RuleNb),
9809 rule([Head],[],true,Goal),
9815 Rules = [Rule|Tail],
9816 never_stored_rules(Constraints,Tail).
9817 never_stored_rules([_|Constraints],Rules) <=>
9818 never_stored_rules(Constraints,Rules).
9823 check_storedness_assertions(Constraints) :-
9824 ( chr_pp_flag(storage_analysis,on), chr_pp_flag(declare_stored_constraints,on) ->
9825 forall(Constraint,Constraints,check_storedness_assertion(Constraint))
9831 :- chr_constraint check_storedness_assertion/1.
9832 :- chr_option(mode,check_storedness_assertion(+)).
9833 :- chr_option(type_declaration,check_storedness_assertion(constraint)).
9835 check_storedness_assertion(Constraint), stored_assertion(Constraint)
9836 <=> ( is_stored(Constraint) ->
9839 chr_warning(assertion_failed,'Constraint ~w is not stored. However, it was asserted to be stored.\n',[Constraint])
9841 never_stored_default(Constraint,_) \ check_storedness_assertion(Constraint)
9842 <=> ( is_finally_stored(Constraint) ->
9843 chr_warning(assertion_failed,'Constraint ~w is stored. However, it was asserted not to be stored.\n',[Constraint])
9844 ; is_stored(Constraint) ->
9845 chr_warning(assertion_failed,'Constraint ~w is temporarily stored. However, it was asserted not to be stored.\n',[Constraint])
9849 % never-stored, no default goal
9850 check_storedness_assertion(Constraint)
9851 <=> ( is_finally_stored(Constraint) ->
9852 chr_warning(assertion_failed,'Constraint ~w is stored. However, it was asserted not to be stored.\n',[Constraint])
9853 ; is_stored(Constraint) ->
9854 chr_warning(assertion_failed,'Constraint ~w is temporarily stored. However, it was asserted not to be stored.\n',[Constraint])
9859 %^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
9860 % success continuation analysis
9863 % also use for forward jumping improvement!
9864 % use Prolog indexing for generated code
9868 % should_skip_to_next_id(C,O)
9870 % get_occurrence_code_id(C,O,Id)
9872 %vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
9874 continuation_analysis(ConstraintSymbols) :-
9875 maplist(analyse_continuations,ConstraintSymbols).
9877 analyse_continuations(C) :-
9878 % 1. compute success continuations of the
9879 % occurrences of constraint C
9880 continuation_analysis(C,1),
9881 % 2. determine for which occurrences
9882 % to skip to next code id
9883 get_max_occurrence(C,MO),
9885 bulk_propagation(C,1,LO),
9886 % 3. determine code id for each occurrence
9887 set_occurrence_code_id(C,1,0).
9889 % 1. Compute the success continuations of constrait C
9890 %-------------------------------------------------------------------------------
9892 continuation_analysis(C,O) :-
9893 get_max_occurrence(C,MO),
9898 continuation_occurrence(C,O,NextO)
9900 constraint_continuation(C,O,MO,NextO),
9901 continuation_occurrence(C,O,NextO),
9903 continuation_analysis(C,NO)
9906 constraint_continuation(C,O,MO,NextO) :-
9907 ( get_occurrence_head(C,O,Head) ->
9909 ( between(NO,MO,NextO),
9910 get_occurrence_head(C,NextO,NextHead),
9911 unifiable(Head,NextHead,_) ->
9916 ; % current occurrence is passive
9920 get_occurrence_head(C,O,Head) :-
9921 get_occurrence(C,O,RuleNb,Id),
9922 \+ is_passive(RuleNb,Id),
9923 get_rule(RuleNb,Rule),
9924 Rule = pragma(rule(H1,H2,_,_),ids(Ids1,Ids2),_,_,_),
9925 ( select2(Id,Head,Ids1,H1,_,_) -> true
9926 ; select2(Id,Head,Ids2,H2,_,_)
9929 :- chr_constraint continuation_occurrence/3.
9930 :- chr_option(mode,continuation_occurrence(+,+,+)).
9932 :- chr_constraint get_success_continuation_occurrence/3.
9933 :- chr_option(mode,get_success_continuation_occurrence(+,+,-)).
9935 continuation_occurrence(C,O,NO) \ get_success_continuation_occurrence(C,O,X)
9939 get_success_continuation_occurrence(C,O,X)
9941 chr_error(internal,'Success continuation not found for ~w.\n',[C:O]).
9943 % 2. figure out when to skip to next code id
9944 %-------------------------------------------------------------------------------
9945 % don't go beyond the last occurrence
9946 % we have to go to next id for storage here
9948 :- chr_constraint skip_to_next_id/2.
9949 :- chr_option(mode,skip_to_next_id(+,+)).
9951 :- chr_constraint should_skip_to_next_id/2.
9952 :- chr_option(mode,should_skip_to_next_id(+,+)).
9954 skip_to_next_id(C,O) \ should_skip_to_next_id(C,O)
9958 should_skip_to_next_id(_,_)
9962 :- chr_constraint bulk_propagation/3.
9963 :- chr_option(mode,bulk_propagation(+,+,+)).
9965 max_occurrence(C,MO) \ bulk_propagation(C,O,_)
9969 skip_to_next_id(C,O).
9970 % we have to go to the next id here because
9971 % a predecessor needs it
9972 bulk_propagation(C,O,LO)
9976 skip_to_next_id(C,O),
9977 get_max_occurrence(C,MO),
9979 bulk_propagation(C,LO,NLO).
9980 % we have to go to the next id here because
9981 % we're running into a simplification rule
9982 % IMPROVE: propagate back to propagation predecessor (IF ANY)
9983 occurrence(C,NO,_,_,simplification) \ bulk_propagation(C,O,LO)
9987 skip_to_next_id(C,O),
9988 get_max_occurrence(C,MO),
9990 bulk_propagation(C,NO,NLO).
9991 % we skip the next id here
9992 % and go to the next occurrence
9993 continuation_occurrence(C,O,NextO) \ bulk_propagation(C,O,LO)
9997 NLO is min(LO,NextO),
9999 bulk_propagation(C,NO,NLO).
10001 % err on the safe side
10002 bulk_propagation(C,O,LO)
10004 skip_to_next_id(C,O),
10005 get_max_occurrence(C,MO),
10008 bulk_propagation(C,NO,NLO).
10010 skip_to_next_id(C,O) \ skip_to_next_id(C,O) <=> true.
10012 % if this occurrence is passive, but has to skip,
10013 % then the previous one must skip instead...
10014 % IMPROVE reasoning is conservative
10015 occurrence(C,O,RuleNb,Id,_), passive(RuleNb,Id), skip_to_next_id(C,O)
10020 skip_to_next_id(C,PO).
10022 % 3. determine code id of each occurrence
10023 %-------------------------------------------------------------------------------
10025 :- chr_constraint set_occurrence_code_id/3.
10026 :- chr_option(mode,set_occurrence_code_id(+,+,+)).
10028 :- chr_constraint occurrence_code_id/3.
10029 :- chr_option(mode,occurrence_code_id(+,+,+)).
10032 set_occurrence_code_id(C,O,IdNb)
10034 get_max_occurrence(C,MO),
10037 occurrence_code_id(C,O,IdNb).
10039 % passive occurrences don't change the code id
10040 occurrence(C,O,RuleNb,Id,_), passive(RuleNb,Id) \ set_occurrence_code_id(C,O,IdNb)
10042 occurrence_code_id(C,O,IdNb),
10044 set_occurrence_code_id(C,NO,IdNb).
10046 occurrence(C,O,RuleNb,Id,simplification) \ set_occurrence_code_id(C,O,IdNb)
10048 occurrence_code_id(C,O,IdNb),
10050 set_occurrence_code_id(C,NO,IdNb).
10052 occurrence(C,O,RuleNb,Id,propagation), skip_to_next_id(C,O) \ set_occurrence_code_id(C,O,IdNb)
10054 occurrence_code_id(C,O,IdNb),
10057 set_occurrence_code_id(C,NO,NIdNb).
10059 occurrence(C,O,RuleNb,Id,propagation) \ set_occurrence_code_id(C,O,IdNb)
10061 occurrence_code_id(C,O,IdNb),
10063 set_occurrence_code_id(C,NO,IdNb).
10065 % occurrence_code_id(C,O,IdNb) ==> writeln(occurrence_code_id(C,O,IdNb)).
10067 :- chr_constraint get_occurrence_code_id/3.
10068 :- chr_option(mode,get_occurrence_code_id(+,+,-)).
10070 occurrence_code_id(C,O,IdNb) \ get_occurrence_code_id(C,O,X)
10074 get_occurrence_code_id(C,O,X)
10079 format('no occurrence code for ~w!\n',[C:O])
10082 get_success_continuation_code_id(C,O,NextId) :-
10083 get_success_continuation_occurrence(C,O,NextO),
10084 get_occurrence_code_id(C,NextO,NextId).
10086 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10087 % COLLECT CONSTANTS FOR INLINING
10091 % collect_constants(+rules,+constraint_symbols,+clauses) {{{
10092 collect_constants(Rules,Constraints,Clauses0) :-
10094 maplist(collect_rule_constants(Constraints),Rules),
10095 ( chr_pp_flag(verbose,on) ->
10096 print_chr_constants
10100 ( chr_pp_flag(experiment,on) ->
10101 flattening_dictionary(Constraints,Dictionary),
10102 copy_term_nat([dict(Dictionary)|Clauses0],Clauses),
10103 flatten_clauses(Clauses,FlatClauses),
10104 install_new_declarations_and_restart(FlatClauses)
10112 :- chr_constraint chr_constants/2.
10113 :- chr_option(mode,chr_constants(+,+)).
10115 :- chr_constraint get_chr_constants/2.
10117 chr_constants(Key,Constants) \ get_chr_constants(Key,Q) <=> Q = Constants.
10119 get_chr_constants(Key,Q) <=> chr_warning(internal,'No constants found for key ~w.\n',[Key]), Q = [].
10121 % collect_rule_constants(+constraint_symbols,+rule) {{{
10122 collect_rule_constants(Constraints,Rule) :-
10123 Rule = pragma(rule(H1,H2,_,B),_,_,_,_),
10124 maplist(collect_head_constants,H1),
10125 maplist(collect_head_constants,H2),
10126 collect_body_constants(B,Constraints).
10128 collect_body_constants(Body,Constraints) :-
10129 conj2list(Body,Goals),
10130 maplist(collect_goal_constants(Constraints),Goals).
10132 collect_goal_constants(Constraints,Goal) :-
10135 memberchk(C/N,Constraints) ->
10136 collect_head_constants(Goal)
10138 Goal = Mod : TheGoal,
10139 get_target_module(Module),
10142 functor(TheGoal,C,N),
10143 memberchk(C/N,Constraints) ->
10144 collect_head_constants(TheGoal)
10149 collect_head_constants(Head) :-
10151 get_constraint_type_det(C/N,Types),
10153 maplist(collect_arg_constants,Args,Types).
10155 collect_arg_constants(Arg,Type) :-
10157 unalias_type(Type,chr_constants(Key)) ->
10158 add_chr_constant(Key,Arg)
10162 :- chr_constraint add_chr_constant/2.
10163 :- chr_option(mode,add_chr_constant(+,+)).
10165 add_chr_constant(Key,Constant) , chr_constants(Key,Constants) <=>
10166 sort([Constant|Constants],NConstants),
10167 chr_constants(Key,NConstants).
10169 add_chr_constant(Key,Constant) <=>
10170 chr_constants(Key,[Constant]).
10174 :- chr_constraint print_chr_constants/0. % {{{
10176 print_chr_constants, chr_constants(Key,Constants) # Id ==>
10177 format('\t* chr_constants ~w : ~w.\n',[Key,Constants])
10178 pragma passive(Id).
10180 print_chr_constants <=>
10185 % flattening_dictionary(+constraint_symbols,-dictionary) {{{
10186 flattening_dictionary([],[]).
10187 flattening_dictionary([CS|CSs],Dictionary) :-
10188 ( flattening_dictionary_entry(CS,Entry) ->
10189 Dictionary = [Entry|Rest]
10193 flattening_dictionary(CSs,Rest).
10195 flattening_dictionary_entry(CS,Entry) :-
10196 get_constraint_arg_type(CS,Pos,Type),
10197 Type = chr_constants(Key), !,
10198 get_chr_constants(Key,Constants),
10199 Entry = CS-Pos-Specs,
10200 maplist(flat_spec(CS,Pos),Constants,Specs).
10202 flat_spec(C/N,Pos,Term,Spec) :-
10203 Spec = Term - Functor,
10204 term_to_atom(Term,TermAtom),
10205 atom_concat_list(['$flat_',C,'/',N,'___',Pos,'___',TermAtom],Functor).
10209 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10210 % RESTART AFTER FLATTENING {{{
10212 restart_after_flattening(Declarations,Declarations) :-
10213 nb_setval('$chr_restart_after_flattening',started).
10214 restart_after_flattening(_,Declarations) :-
10215 nb_getval('$chr_restart_after_flattening',restart(Declarations)),
10216 nb_setval('$chr_restart_after_flattening',restarted).
10219 nb_getval('$chr_restart_after_flattening',started).
10221 install_new_declarations_and_restart(Declarations) :-
10222 nb_setval('$chr_restart_after_flattening',restart(Declarations)),
10223 fail. /* fails to choicepoint of restart_after_flattening */
10225 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10229 % -) generate dictionary from collected chr_constants
10230 % enable with :- chr_option(experiment,on).
10231 % -) issue constraint declarations for constraints not present in
10235 % -) integrate with CHR compiler
10236 % RELEASE-----------------------------------------------------------------
10237 % -) pass Mike's test code (full syntactic support for current CHR code)
10238 % -) rewrite the body using the inliner
10239 % -) refined semantics correctness issue
10240 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10242 flatten_clauses(Clauses0,NClauses) :-
10243 select(dict(Dict),Clauses0,Clauses),
10244 flatten_readcontent(Clauses,Rules,Symbols,ModeDecls,_TypeDefs,TypeDecls,RestClauses),
10245 flatten_clauses_(Dict,Rules,RestClauses,Symbols,ModeDecls,TypeDecls,NClauses).
10247 flatten_clauses_(Dict,Clauses,RestClauses,Symbols,ModeDecls,TypeDecls,NClauses) :-
10248 auxiliary_constraints_declarations(Dict,ModeDecls,TypeDecls,NClauses0),
10249 dispatching_rules(Dict,NClauses1),
10250 declarations(Symbols,Dict,ModeDecls,TypeDecls,NClauses2),
10251 flatten_rules(Clauses,Dict,NClauses3),
10252 append([RestClauses,NClauses0,NClauses1,NClauses2,NClauses3],NClauses).
10254 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10255 % Declarations for non-flattened constraints
10257 % declarations(+constraint_symbols,+dict,+mode_decls,+type_decls,-clauses) {{{
10258 declarations(ConstraintSymbols,Dict,ModeDecls,TypeDecls,Declarations) :-
10259 findall(Symbol,(member(Symbol,ConstraintSymbols), \+ memberchk(Symbol-_-_,Dict)),Symbols),
10260 maplist(declaration(ModeDecls,TypeDecls),Symbols,DeclarationsList),
10261 flatten(DeclarationsList,Declarations).
10263 declaration(ModeDecls,TypeDecls,ConstraintSymbol,
10264 [(:- chr_constraint ConstraintSymbol),
10265 (:- chr_option(mode,ModeDeclPattern)),
10266 (:- chr_option(type_declaration,TypeDeclPattern))
10268 ConstraintSymbol = Functor / Arity,
10269 % print optional mode declaration
10270 functor(ModeDeclPattern,Functor,Arity),
10271 ( memberchk(ModeDeclPattern,ModeDecls) ->
10274 replicate(Arity,(?),Modes),
10275 ModeDeclPattern =.. [_|Modes]
10277 % print optional type declaration
10278 functor(TypeDeclPattern,Functor,Arity),
10279 ( memberchk(TypeDeclPattern,TypeDecls) ->
10282 replicate(Arity,any,Types),
10283 TypeDeclPattern =.. [_|Types]
10286 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10287 % read clauses from file
10289 % declared constaints are returned
10290 % type definitions are returned and printed
10291 % mode declarations are returned
10292 % other clauses are returned
10294 % flatten_readcontent(+clauses,-rules,-symbols,-mode_decls,-type_defs,-type_decls,-rest_clauses) {{{
10295 flatten_readcontent([],[],[],[],[],[],[]).
10296 flatten_readcontent([Clause|RClauses],Rules,ConstraintSymbols,ModeDecls,TypeDefs,TypeDecls,RestClauses) :-
10298 ( Clause == end_of_file ->
10300 ConstraintSymbols = [],
10305 ; crude_is_rule(Clause) ->
10306 Rules = [Clause|RestRules],
10307 flatten_readcontent(RClauses,RestRules,ConstraintSymbols,ModeDecls,TypeDefs,TypeDecls,RestClauses)
10308 ; pure_is_declaration(Clause,SomeConstraintSymbols,SomeModeDecls,SomeTypeDecls) ->
10309 append(SomeConstraintSymbols,RestConstraintSymbols,ConstraintSymbols),
10310 append(SomeModeDecls,RestModeDecls,ModeDecls),
10311 append(SomeTypeDecls,RestTypeDecls,TypeDecls),
10312 flatten_readcontent(RClauses,Rules,RestConstraintSymbols,RestModeDecls,TypeDefs,RestTypeDecls,RestClauses)
10313 ; is_mode_declaration(Clause,ModeDecl) ->
10314 ModeDecls = [ModeDecl|RestModeDecls],
10315 flatten_readcontent(RClauses,Rules,ConstraintSymbols,RestModeDecls,TypeDefs,TypeDecls,RestClauses)
10316 ; is_type_declaration(Clause,TypeDecl) ->
10317 TypeDecls = [TypeDecl|RestTypeDecls],
10318 flatten_readcontent(RClauses,Rules,ConstraintSymbols,ModeDecls,TypeDefs,RestTypeDecls,RestClauses)
10319 ; is_type_definition(Clause,TypeDef) ->
10320 RestClauses = [Clause|NRestClauses],
10321 TypeDefs = [TypeDef|RestTypeDefs],
10322 flatten_readcontent(RClauses,Rules,ConstraintSymbols,ModeDecls,RestTypeDefs,TypeDecls,NRestClauses)
10323 ; ( Clause = (:- op(A,B,C)) ->
10324 % assert operators in order to read and print them out properly
10329 RestClauses = [Clause|NRestClauses],
10330 flatten_readcontent(RClauses,Rules,ConstraintSymbols,ModeDecls,TypeDefs,TypeDecls,NRestClauses)
10333 crude_is_rule(_ @ _).
10334 crude_is_rule(_ pragma _).
10335 crude_is_rule(_ ==> _).
10336 crude_is_rule(_ <=> _).
10338 pure_is_declaration(D, Constraints,Modes,Types) :- %% constraint declaration
10339 D = (:- Decl), Decl =.. [F,Cs], F == (chr_constraint),
10340 conj2list(Cs,Constraints0),
10341 pure_extract_type_mode(Constraints0,Constraints,Modes,Types).
10343 pure_extract_type_mode([],[],[],[]).
10344 pure_extract_type_mode([F/A|R],[F/A|R2],Modes,Types) :- !,
10345 pure_extract_type_mode(R,R2,Modes,Types).
10346 pure_extract_type_mode([C|R],[ConstraintSymbol|R2],[Mode|Modes],Types) :-
10348 ConstraintSymbol = F/A,
10350 extract_types_and_modes(Args,ArgTypes,ArgModes),
10351 Mode =.. [F|ArgModes],
10352 ( forall(member(ArgType,ArgTypes),ArgType == any) ->
10355 Types = [Type|RTypes],
10356 Type =.. [F|ArgTypes]
10358 pure_extract_type_mode(R,R2,Modes,RTypes).
10360 is_mode_declaration((:- chr_option(mode,ModeDecl)),ModeDecl).
10362 is_type_declaration((:- chr_option(type_declaration,TypeDecl)),TypeDecl).
10364 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10365 % DECLARATIONS FOR FLATTENED CONSTRAINTS
10366 % including mode and type declarations
10368 % auxiliary_constraints_declarations(+dict,+mode_decls,+type_decls,-constraint_specs) {{{
10369 auxiliary_constraints_declarations(Dict,ModeDecls,TypeDecls,ConstraintSpecs) :-
10370 findall(ConstraintSpec,auxiliary_constraints_declaration(Dict,ModeDecls,TypeDecls,ConstraintSpec),ConstraintSpecs0),
10371 flatten(ConstraintSpecs0,ConstraintSpecs).
10373 auxiliary_constraints_declaration(Dict,ModeDecls,TypeDecls,
10374 [(:- chr_constraint ConstraintSpec),
10375 (:- chr_option(mode,NewModeDecl)),
10376 (:- chr_option(type_declaration,NewTypeDecl))]) :-
10377 member(C/N-I-SFs,Dict),
10378 arg_modes(C,N,ModeDecls,Modes),
10379 specialize_modes(Modes,I,SpecializedModes),
10380 arg_types(C,N,TypeDecls,Types),
10381 specialize_types(Types,I,SpecializedTypes),
10383 member(_Term-F,SFs),
10384 ConstraintSpec = F/AN,
10385 NewModeDecl =.. [F|SpecializedModes],
10386 NewTypeDecl =.. [F|SpecializedTypes].
10388 arg_modes(C,N,ModeDecls,ArgModes) :-
10389 functor(ConstraintPattern,C,N),
10390 ( memberchk(ConstraintPattern,ModeDecls) ->
10391 ConstraintPattern =.. [_|ArgModes]
10393 replicate(N,?,ArgModes)
10396 specialize_modes(Modes,I,SpecializedModes) :-
10397 split(Modes,I,Before,_At,After),
10398 append(Before,After,SpecializedModes).
10400 arg_types(C,N,TypeDecls,ArgTypes) :-
10401 functor(ConstraintPattern,C,N),
10402 ( memberchk(ConstraintPattern,TypeDecls) ->
10403 ConstraintPattern =.. [_|ArgTypes]
10405 replicate(N,any,ArgTypes)
10408 specialize_types(Types,I,SpecializedTypes) :-
10409 split(Types,I,Before,_At,After),
10410 append(Before,After,SpecializedTypes).
10413 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10414 % DISPATCHING RULES
10416 % dispatching_rules(+dict,-newrules)
10419 dispatching_rules([],[]).
10420 dispatching_rules([CN-I-SFs|Dict], DispatchingRules) :-
10421 constraint_dispatching_rule(SFs,CN,I,DispatchingRules,RestDispatchingRules),
10422 dispatching_rules(Dict,RestDispatchingRules).
10424 constraint_dispatching_rule(SFs,CN,I,Rules,RestRules) :-
10426 /* index on first argument */
10431 /* reorder arguments for 1st argument indexing */
10434 split(Args,I,BeforeArgs,IndexArg,AfterArgs),
10435 append([IndexArg|BeforeArgs],AfterArgs,ShuffledArgs),
10436 atom_concat(C,'_$shuffled',NC),
10437 Body =.. [NC|ShuffledArgs],
10438 [(Head :- Body)|Rules0] = Rules,
10441 dispatching_rule_term_cases(SFs,NCN,Rules0,RestRules).
10442 % dispatching_rule_cases(SFs,NCN,Rules0,RestRules).
10444 dispatching_rule_term_cases(SFs,NC/N,Rules,RestRules) :-
10445 once(pairup(Terms,Functors,SFs)),
10447 replicate(K,[],MorePatterns),
10449 maplist(wrap_in_functor(dispatching_action),Functors,Actions),
10450 dispatch_trie_index([Terms|MorePatterns],Payload,Actions,NC,Rules,RestRules).
10452 dispatching_action(Functor,PayloadArgs,Goal) :-
10453 Goal =.. [Functor|PayloadArgs].
10455 % dispatching_rule_cases([],C/N,Rules,RestRules) :-
10456 % functor(Head,C,N),
10457 % arg(1,Head,IndexArg),
10458 % Body = throw(wrong_argument(C/N,IndexArg)),
10459 % Rules = [(Head :- Body)|RestRules].
10460 % dispatching_rule_cases([Term-Name|SFs],C/N,[Rule|Rules],RestRules) :-
10461 % functor(Head,C,N),
10462 % Head =.. [_,IndexArg|RestArgs],
10464 % Body =.. [Name|RestArgs],
10465 % Rule = (Head :- !, Body),
10466 % dispatching_rule_special(SFs,C/N,Rules,RestRules).
10468 dispatch_trie_index([Patterns|MorePatterns],Payload,Actions,Prefix,Clauses,Tail) :-
10469 dispatch_trie_step(Patterns,Prefix,Prefix,MorePatterns,Payload,Actions,Clauses,Tail).
10471 dispatch_trie_step([],_,_,_,[],[],L,L) :- !.
10472 % length MorePatterns == length Patterns == length Results
10473 dispatch_trie_step(Patterns,Symbol,Prefix,MorePatterns,Payload,Actions,Clauses,T) :-
10474 writeln(dispatch_trie_step(Patterns,Symbol,Prefix,MorePatterns,Payload,Actions,Clauses,T)),
10475 MorePatterns = [List|_],
10477 aggregate_all(set(F/A),
10478 ( member(Pattern,Patterns),
10479 functor(Pattern,F,A)
10483 dispatch_trie_step_cases(FAs,N1,Patterns,MorePatterns,Payload,Actions,Symbol,Prefix,Clauses,T).
10485 dispatch_trie_step_cases([],_,_,_,_,_,_,_,Clauses,Clauses).
10486 dispatch_trie_step_cases([FA|FAs],N,Pattern,MorePatterns,Payload,Actions,Symbol,Prefix,Clauses,Tail) :-
10487 dispatch_trie_step_case(FA,N,Pattern,MorePatterns,Payload,Actions,Symbol,Prefix,Clauses,Clauses1),
10488 dispatch_trie_step_cases(FAs,N,Pattern,MorePatterns,Payload,Actions,Symbol,Prefix,Clauses1,Tail).
10490 dispatch_trie_step_case(F/A,N,Patterns,MorePatterns,Payload,Actions,Symbol,Prefix,[Clause|List],Tail) :-
10491 Clause = (Head :- Body),
10492 /* Head = Symbol(IndexPattern,V2,...,Vn,Payload) */
10494 functor(Head,Symbol,N1),
10495 arg(1,Head,IndexPattern),
10496 Head =.. [_,_|RestArgs],
10497 length(PayloadArgs,Payload),
10498 once(append(Vs,PayloadArgs,RestArgs)),
10499 /* IndexPattern = F(...) */
10500 functor(IndexPattern,F,A),
10501 IndexPattern =.. [_|Args],
10502 append(Args,RestArgs,RecArgs),
10503 ( RecArgs == PayloadArgs ->
10504 /* nothing more to match on */
10506 rec_cases(Patterns,_,Actions,F/A,_,_,MoreActions),
10507 MoreActions = [Action],
10508 call(Action,PayloadArgs,Body)
10509 ; /* more things to match on */
10510 rec_cases(Patterns,MorePatterns,Actions,F/A,Cases,MoreCases,MoreActions),
10511 ( MoreActions = [OneMoreAction] ->
10512 /* only one more thing to match on */
10514 call(OneMoreAction,PayloadArgs,Body)
10516 /* more than one thing to match on */
10520 pairup(Cases,MoreCases,CasePairs),
10521 common_pattern(CasePairs,CommonPatternPair,DiffVars,Differences),
10522 append(Args,Vs,[First|Rest]),
10523 First-Rest = CommonPatternPair,
10524 gensym(Prefix,RSymbol),
10525 append(DiffVars,PayloadArgs,RecCallVars),
10526 Body =.. [RSymbol|RecCallVars],
10527 findall(CH-CT,member([CH|CT],Differences),CPairs),
10528 once(pairup(CHs,CTs,CPairs)),
10529 dispatch_trie_step(CHs,RSymbol,Prefix,CTs,Payload,MoreActions,List,Tail)
10534 % split(list,int,before,at,after).
10536 split([X|Xs],I,Before,At,After) :-
10543 Before = [X|RBefore],
10544 split(Xs,J,RBefore,At,After)
10548 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10549 % SUBSTITUTE CONSTRAINT SYMBOL FUNCTORS
10551 % flatten_rules(+rule_clauses,+dict,-rule_clauses).
10553 % dict :== list(functor/arity-int-list(term-functor))
10556 flatten_rules(Rules,Dict,FlatRules) :-
10557 flatten_rules1(Rules,Dict,FlatRulesList),
10558 flatten(FlatRulesList,FlatRules).
10560 flatten_rules1([],_,[]).
10561 flatten_rules1([Rule|Rules],Dict,[FlatRules|FlatRulesList]) :-
10562 findall(FlatRule,flatten_rule(Rule,Dict,FlatRule),FlatRules),
10563 flatten_rules1(Rules,Dict,FlatRulesList).
10565 flatten_rule((Name @ Rule),Dict,(Name @ NRule)) :- !,
10566 flatten_rule(Rule,Dict,NRule).
10567 flatten_rule((Rule pragma Pragmas),Dict,(NRule pragma Pragmas)) :- !,
10568 flatten_rule(Rule,Dict,NRule).
10569 flatten_rule((H ==> B),Dict,(NH ==> NB)) :- !,
10570 flatten_heads(H,Dict,NH),
10571 flatten_body(B,Dict,NB).
10572 flatten_rule((H1 \ H2 <=> B),Dict,(NH1 \ NH2 <=> NB)) :- !,
10573 flatten_heads((H1,H2),Dict,(NH1,NH2)),
10574 flatten_body(B,Dict,NB).
10575 flatten_rule((H <=> B),Dict,(NH <=> NB)) :-
10576 flatten_heads(H,Dict,NH),
10577 flatten_body(B,Dict,NB).
10579 flatten_heads((H1,H2),Dict,(NH1,NH2)) :- !,
10580 flatten_heads(H1,Dict,NH1),
10581 flatten_heads(H2,Dict,NH2).
10582 flatten_heads((H # Annotation),Dict,(NH # Annotation)) :- !,
10583 flatten_heads(H,Dict,NH).
10584 flatten_heads(H,Dict,NH) :-
10586 memberchk(C/N-I-SFs,Dict) ->
10588 split(AllArgs,I,PreArgs,Arg,PostArgs),
10589 member(Term-Name,SFs),
10591 append(PreArgs,PostArgs,FlatArgs),
10592 NH =.. [Name|FlatArgs]
10597 flatten_body(Body,Dict,NBody) :-
10598 conj2list(Body,Goals),
10599 maplist(flatten_goal(Dict),Goals,NGoals),
10600 list2conj(NGoals,NBody).
10602 flatten_goal(Dict,Goal,NGoal) :-
10603 ( is_specializable_goal(Goal,Dict,ArgPos)
10605 specialize_goal(Goal,ArgPos,NGoal)
10607 Goal = Mod : TheGoal,
10608 get_target_module(Module),
10610 is_specializable_goal(TheGoal,Dict,ArgPos)
10612 specialize_goal(TheGoal,ArgPos,NTheGoal),
10613 NGoal = Mod : NTheGoal
10618 is_specializable_goal(Goal,Dict,ArgPos) :-
10621 memberchk(C/N-ArgPos-_,Dict),
10622 arg(ArgPos,Goal,Arg),
10626 specialize_goal(Goal,ArgPos,NGoal) :-
10629 split(Args,ArgPos,Before,Arg,After),
10630 append(Before,After,NArgs),
10631 flat_spec(C/N,ArgPos,Arg,_-Functor),
10632 NGoal =.. [Functor|NArgs].
10636 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10637 dump_code(Clauses) :-
10638 ( chr_pp_flag(dump,on) ->
10639 maplist(portray_clause,Clauses)
10645 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',[]).