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(+,+)).
340 :- chr_option(type_declaration,passive(rule_nb,id)).
342 :- chr_constraint is_passive/2.
343 :- chr_option(mode,is_passive(+,+)).
344 :- chr_option(type_declaration,is_passive(rule_nb,id)).
346 :- chr_constraint any_passive_head/1.
347 :- chr_option(mode,any_passive_head(+)).
349 :- chr_constraint new_occurrence/4.
350 :- chr_option(mode,new_occurrence(+,+,+,+)).
352 :- chr_constraint occurrence/5.
353 :- chr_option(mode,occurrence(+,+,+,+,+)).
355 :- chr_type occurrence_type ---> simplification ; propagation.
356 :- chr_option(type_declaration,occurrence(constraint,occurrence,rule_nb,id,occurrence_type)).
358 :- chr_constraint get_occurrence/4.
359 :- chr_option(mode,get_occurrence(+,+,-,-)).
361 :- chr_constraint get_occurrence/5.
362 :- chr_option(mode,get_occurrence(+,+,-,-,-)).
364 :- chr_constraint get_occurrence_from_id/4.
365 :- chr_option(mode,get_occurrence_from_id(+,-,+,+)).
367 :- chr_constraint max_occurrence/2.
368 :- chr_option(mode,max_occurrence(+,+)).
370 :- chr_constraint get_max_occurrence/2.
371 :- chr_option(mode,get_max_occurrence(+,-)).
373 :- chr_constraint allocation_occurrence/2.
374 :- chr_option(mode,allocation_occurrence(+,+)).
376 :- chr_constraint get_allocation_occurrence/2.
377 :- chr_option(mode,get_allocation_occurrence(+,-)).
379 :- chr_constraint rule/2.
380 :- chr_option(mode,rule(+,+)).
381 :- chr_option(type_declaration,rule(rule_nb,pragma_rule)).
383 :- chr_constraint get_rule/2.
384 :- chr_option(mode,get_rule(+,-)).
385 :- chr_option(type_declaration,get_rule(int,pragma_rule)).
387 :- chr_constraint least_occurrence/2.
388 :- chr_option(mode,least_occurrence(+,+)).
389 :- chr_option(type_declaration,least_occurrence(any,list)).
391 :- chr_constraint is_least_occurrence/1.
392 :- chr_option(mode,is_least_occurrence(+)).
395 indexed_argument(FA,I) \ indexed_argument(FA,I) <=> true.
396 indexed_argument(FA,I) \ is_indexed_argument(FA,I) <=> true.
397 is_indexed_argument(_,_) <=> fail.
399 %%% C O N S T R A I N T M O D E %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
401 constraint_mode(FA,_) \ constraint_mode(FA,_) <=> true.
402 constraint_mode(FA,Mode) \ get_constraint_mode(FA,Q) <=>
404 get_constraint_mode(FA,Q) <=>
408 %%% M A Y T R I G G E R %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
410 may_trigger(FA) <=> \+ has_active_occurrence(FA) | fail.
411 constraint_mode(FA,Mode), indexed_argument(FA,I) \ may_trigger(FA) <=>
415 may_trigger(FA) <=> chr_pp_flag(debugable,on). % in debug mode, we assume everything can be triggered
417 constraint_mode(FA,Mode), indexed_argument(FA,I) \ only_ground_indexed_arguments(FA)
423 only_ground_indexed_arguments(_) <=>
426 none_suspended_on_variables \ none_suspended_on_variables <=> true.
427 none_suspended_on_variables \ are_none_suspended_on_variables <=> true.
428 are_none_suspended_on_variables <=> fail.
429 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
432 % The functionality for inspecting and deciding on the different types of constraint
433 % store / indexes for constraints.
435 store_type(FA,StoreType)
436 ==> chr_pp_flag(verbose,on)
438 format('The indexes for ~w are:\n',[FA]),
439 format_storetype(StoreType).
440 % chr_info(verbose,'Storetype of ~w is ~w.\n',[FA,StoreType]).
442 format_storetype(multi_store(StoreTypes)) :- !,
443 maplist(format_storetype,StoreTypes).
444 format_storetype(atomic_constants(Index,Constants,_)) :-
445 format('\t* a trie index on the argument(s) ~w for the ground terms ~w\n',[Index,Constants]).
446 format_storetype(ground_constants(Index,Constants,_)) :-
447 format('\t* a trie index on the argument(s) ~w for the ground terms ~w\n',[Index,Constants]).
448 format_storetype(StoreType) :-
449 format('\t* ~w\n',[StoreType]).
457 get_store_type_normal @
458 store_type(FA,Store) \ get_store_type(FA,Query)
461 get_store_type_assumed @
462 assumed_store_type(FA,Store) \ get_store_type(FA,Query)
465 get_store_type_default @
466 get_store_type(_,Query)
469 % 2. Store type registration
470 % ~~~~~~~~~~~~~~~~~~~~~~~~~~
472 actual_store_types(C,STs) \ update_store_type(C,ST)
473 <=> memberchk(ST,STs) | true.
474 update_store_type(C,ST), actual_store_types(C,STs)
476 actual_store_types(C,[ST|STs]).
477 update_store_type(C,ST)
479 actual_store_types(C,[ST]).
481 % 3. Final decision on store types
482 % ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
484 validate_store_type_assumption(C) \ actual_store_types(C,STs), actual_atomic_multi_hash_keys(C,Index,Keys)
486 true % chr_pp_flag(experiment,on)
488 delete(STs,multi_hash([Index]),STs0),
490 ( get_constraint_arg_type(C,IndexPos,Type),
491 enumerated_atomic_type(Type,Atoms) ->
492 /* use the type constants rather than the collected keys */
494 Completeness = complete
497 Completeness = incomplete
499 actual_store_types(C,[atomic_constants(Index,Constants,Completeness)|STs0]).
500 validate_store_type_assumption(C) \ actual_store_types(C,STs), actual_ground_multi_hash_keys(C,Index,Constants0)
502 true % chr_pp_flag(experiment,on)
504 ( Index = [IndexPos],
505 get_constraint_arg_type(C,IndexPos,Type),
506 Type = chr_enum(Constants)
508 Completeness = complete
510 Constants = Constants0,
511 Completeness = incomplete
513 delete(STs,multi_hash([Index]),STs0),
514 actual_store_types(C,[ground_constants(Index,Constants,Completeness)|STs0]).
516 get_constraint_arg_type(C,Pos,Type) :-
517 get_constraint_type(C,Types),
518 nth1(Pos,Types,Type0),
519 unalias_type(Type0,Type).
521 validate_store_type_assumption(C) \ actual_store_types(C,STs)
523 % chr_pp_flag(experiment,on),
524 memberchk(multi_hash([[Index]]),STs),
525 get_constraint_type(C,Types),
526 nth1(Index,Types,Type),
527 enumerated_atomic_type(Type,Atoms)
529 delete(STs,multi_hash([[Index]]),STs0),
530 actual_store_types(C,[atomic_constants([Index],Atoms,complete)|STs0]).
531 validate_store_type_assumption(C) \ actual_store_types(C,STs)
533 memberchk(multi_hash([[Index]]),STs),
534 get_constraint_arg_type(C,Index,Type),
535 Type = chr_enum(Constants)
537 delete(STs,multi_hash([[Index]]),STs0),
538 actual_store_types(C,[ground_constants([Index],Constants,complete)|STs0]).
539 validate_store_type_assumption(C), actual_store_types(C,STs), assumed_store_type(C,_) % automatic assumption
541 ( /* chr_pp_flag(experiment,on), */ maplist(partial_store,STs) ->
542 Stores = [global_ground|STs]
546 store_type(C,multi_store(Stores)).
547 validate_store_type_assumption(C), actual_store_types(C,STs), store_type(C,_) % user assumption
549 store_type(C,multi_store(STs)).
550 validate_store_type_assumption(C), assumed_store_type(C,_) % no lookups on constraint in debug mode
552 chr_pp_flag(debugable,on)
554 store_type(C,default).
555 validate_store_type_assumption(C), assumed_store_type(C,_) % no lookups on constraint
556 <=> store_type(C,global_ground).
557 validate_store_type_assumption(C)
560 partial_store(ground_constants(_,_,incomplete)).
561 partial_store(atomic_constants(_,_,incomplete)).
563 %%% P A S S I V E %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
564 passive(R,ID) \ passive(R,ID) <=> true.
566 passive(RuleNb,ID) \ is_passive(RuleNb,ID) <=> true.
567 is_passive(_,_) <=> fail.
569 passive(RuleNb,_) \ any_passive_head(RuleNb)
573 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
575 max_occurrence(C,N) \ max_occurrence(C,M)
578 max_occurrence(C,MO), new_occurrence(C,RuleNb,ID,Type) <=>
580 occurrence(C,NO,RuleNb,ID,Type),
581 max_occurrence(C,NO).
582 new_occurrence(C,RuleNb,ID,_) <=>
583 chr_error(internal,'new_occurrence: missing max_occurrence for ~w in rule ~w\n',[C,RuleNb]).
585 max_occurrence(C,MON) \ get_max_occurrence(C,Q)
587 get_max_occurrence(C,Q)
588 <=> chr_error(internal,'get_max_occurrence: missing max occurrence for ~w\n',[C]).
590 occurrence(C,ON,Rule,ID,_) \ get_occurrence(C,ON,QRule,QID)
591 <=> Rule = QRule, ID = QID.
592 get_occurrence(C,O,_,_)
593 <=> chr_error(internal,'get_occurrence: missing occurrence ~w:~w\n',[C,O]).
595 occurrence(C,ON,Rule,ID,OccType) \ get_occurrence(C,ON,QRule,QID,QOccType)
596 <=> Rule = QRule, ID = QID, OccType = QOccType.
597 get_occurrence(C,O,_,_,_)
598 <=> chr_error(internal,'get_occurrence: missing occurrence ~w:~w\n',[C,O]).
600 occurrence(C,ON,Rule,ID,_) \ get_occurrence_from_id(QC,QON,Rule,ID)
601 <=> QC = C, QON = ON.
602 get_occurrence_from_id(C,O,_,_)
603 <=> chr_error(internal,'get_occurrence_from_id: missing occurrence ~w:~w\n',[]).
605 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
608 late_allocation_analysis(Cs) :-
609 ( chr_pp_flag(late_allocation,on) ->
610 maplist(late_allocation, Cs)
615 late_allocation(C) :- late_allocation(C,0).
616 late_allocation(C,O) :- allocation_occurrence(C,O), !.
617 late_allocation(C,O) :- NO is O + 1, late_allocation(C,NO).
619 % A L L O C C A T I O N O C C U R R E N C E %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
621 allocation_occurrence(C,0) ==> stored_in_guard_before_next_kept_occurrence(C,0).
623 rule(RuleNb,Rule), occurrence(C,O,RuleNb,Id,Type), allocation_occurrence(C,O) ==>
624 \+ is_passive(RuleNb,Id),
626 ( stored_in_guard_before_next_kept_occurrence(C,O) ->
628 ; Rule = pragma(rule([_|_],_,_,_),_,_,_,_) -> % simpagation rule
630 ; is_least_occurrence(RuleNb) -> % propagation rule
636 stored_in_guard_before_next_kept_occurrence(C,O) :-
637 chr_pp_flag(store_in_guards, on),
639 stored_in_guard_lookahead(C,NO).
641 :- chr_constraint stored_in_guard_lookahead/2.
642 :- chr_option(mode, stored_in_guard_lookahead(+,+)).
644 occurrence(C,O,RuleNb,Id,_), passive(RuleNb,Id) \ stored_in_guard_lookahead(C,O) <=>
645 NO is O + 1, stored_in_guard_lookahead(C,NO).
646 occurrence(C,O,RuleNb,Id,Type) \ stored_in_guard_lookahead(C,O) <=>
647 Type == simplification,
648 ( is_stored_in_guard(C,RuleNb) ->
651 NO is O + 1, stored_in_guard_lookahead(C,NO)
653 stored_in_guard_lookahead(_,_) <=> fail.
656 rule(RuleNb,Rule), occurrence(C,O,RuleNb,ID,_), allocation_occurrence(C,AO)
657 \ least_occurrence(RuleNb,[ID|IDs])
658 <=> AO >= O, \+ may_trigger(C) |
659 least_occurrence(RuleNb,IDs).
660 rule(RuleNb,Rule), passive(RuleNb,ID)
661 \ least_occurrence(RuleNb,[ID|IDs])
662 <=> least_occurrence(RuleNb,IDs).
665 ==> Rule = pragma(rule([],_,_,_),ids([],IDs),_,_,_) |
666 least_occurrence(RuleNb,IDs).
668 least_occurrence(RuleNb,[]) \ is_least_occurrence(RuleNb)
670 is_least_occurrence(_)
673 allocation_occurrence(C,O) \ get_allocation_occurrence(C,Q)
675 get_allocation_occurrence(_,Q)
676 <=> chr_pp_flag(late_allocation,off), Q=0.
677 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
679 rule(RuleNb,Rule) \ get_rule(RuleNb,Q)
684 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
686 %%% C O N S T R A I N T I N D E X %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
688 % Default store constraint index assignment.
690 :- chr_constraint constraint_index/2. % constraint_index(F/A,DefaultStoreAndAttachedIndex)
691 :- chr_option(mode,constraint_index(+,+)).
692 :- chr_option(type_declaration,constraint_index(constraint,int)).
694 :- chr_constraint get_constraint_index/2.
695 :- chr_option(mode,get_constraint_index(+,-)).
696 :- chr_option(type_declaration,get_constraint_index(constraint,int)).
698 :- chr_constraint get_indexed_constraint/2.
699 :- chr_option(mode,get_indexed_constraint(+,-)).
700 :- chr_option(type_declaration,get_indexed_constraint(int,constraint)).
702 :- chr_constraint max_constraint_index/1. % max_constraint_index(MaxDefaultStoreAndAttachedIndex)
703 :- chr_option(mode,max_constraint_index(+)).
704 :- chr_option(type_declaration,max_constraint_index(int)).
706 :- chr_constraint get_max_constraint_index/1.
707 :- chr_option(mode,get_max_constraint_index(-)).
708 :- chr_option(type_declaration,get_max_constraint_index(int)).
710 constraint_index(C,Index) \ get_constraint_index(C,Query)
712 get_constraint_index(C,Query)
715 constraint_index(C,Index) \ get_indexed_constraint(Index,Q)
717 get_indexed_constraint(Index,Q)
720 max_constraint_index(Index) \ get_max_constraint_index(Query)
722 get_max_constraint_index(Query)
725 set_constraint_indices(Constraints) :-
726 set_constraint_indices(Constraints,1).
727 set_constraint_indices([],M) :-
729 max_constraint_index(N).
730 set_constraint_indices([C|Cs],N) :-
731 ( ( chr_pp_flag(debugable, on) ; \+ only_ground_indexed_arguments(C), is_stored(C) ; is_stored(C), get_store_type(C,default)
732 ; get_store_type(C,var_assoc_store(_,_))) ->
733 constraint_index(C,N),
735 set_constraint_indices(Cs,M)
737 set_constraint_indices(Cs,N)
740 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
743 :- chr_constraint identifier_size/1.
744 :- chr_option(mode,identifier_size(+)).
745 :- chr_option(type_declaration,identifier_size(natural)).
747 identifier_size(_) \ identifier_size(_)
751 :- chr_constraint get_identifier_size/1.
752 :- chr_option(mode,get_identifier_size(-)).
753 :- chr_option(type_declaration,get_identifier_size(natural)).
755 identifier_size(Size) \ get_identifier_size(Q)
759 get_identifier_size(Q)
763 :- chr_constraint identifier_index/3.
764 :- chr_option(mode,identifier_index(+,+,+)).
765 :- chr_option(type_declaration,identifier_index(constraint,natural,natural)).
767 identifier_index(C,I,_) \ identifier_index(C,I,_)
771 :- chr_constraint get_identifier_index/3.
772 :- chr_option(mode,get_identifier_index(+,+,-)).
773 :- chr_option(type_declaration,get_identifier_index(constraint,natural,natural)).
775 identifier_index(C,I,II) \ get_identifier_index(C,I,Q)
778 identifier_size(Size), get_identifier_index(C,I,Q)
781 identifier_index(C,I,NSize),
782 identifier_size(NSize),
784 get_identifier_index(C,I,Q)
786 identifier_index(C,I,2),
790 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
791 % Type Indexed Identifier Indexes
793 :- chr_constraint type_indexed_identifier_size/2.
794 :- chr_option(mode,type_indexed_identifier_size(+,+)).
795 :- chr_option(type_declaration,type_indexed_identifier_size(any,natural)).
797 type_indexed_identifier_size(IndexType,_) \ type_indexed_identifier_size(IndexType,_)
801 :- chr_constraint get_type_indexed_identifier_size/2.
802 :- chr_option(mode,get_type_indexed_identifier_size(+,-)).
803 :- chr_option(type_declaration,get_type_indexed_identifier_size(any,natural)).
805 type_indexed_identifier_size(IndexType,Size) \ get_type_indexed_identifier_size(IndexType,Q)
809 get_type_indexed_identifier_size(IndexType,Q)
813 :- chr_constraint type_indexed_identifier_index/4.
814 :- chr_option(mode,type_indexed_identifier_index(+,+,+,+)).
815 :- chr_option(type_declaration,type_indexed_identifier_index(any,constraint,natural,natural)).
817 type_indexed_identifier_index(_,C,I,_) \ type_indexed_identifier_index(_,C,I,_)
821 :- chr_constraint get_type_indexed_identifier_index/4.
822 :- chr_option(mode,get_type_indexed_identifier_index(+,+,+,-)).
823 :- chr_option(type_declaration,get_type_indexed_identifier_index(any,constraint,natural,natural)).
825 type_indexed_identifier_index(IndexType,C,I,II) \ get_type_indexed_identifier_index(IndexType,C,I,Q)
828 type_indexed_identifier_size(IndexType,Size), get_type_indexed_identifier_index(IndexType,C,I,Q)
831 type_indexed_identifier_index(IndexType,C,I,NSize),
832 type_indexed_identifier_size(IndexType,NSize),
834 get_type_indexed_identifier_index(IndexType,C,I,Q)
836 type_indexed_identifier_index(IndexType,C,I,2),
837 type_indexed_identifier_size(IndexType,2),
840 type_indexed_identifier_structure(IndexType,Structure) :-
841 type_indexed_identifier_name(IndexType,type_indexed_identifier_struct,Functor),
842 get_type_indexed_identifier_size(IndexType,Arity),
843 functor(Structure,Functor,Arity).
844 type_indexed_identifier_name(IndexType,Prefix,Name) :-
846 IndexTypeName = IndexType
848 term_to_atom(IndexType,IndexTypeName)
850 atom_concat_list([Prefix,'_',IndexTypeName],Name).
852 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
857 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
861 chr_translate(Declarations,NewDeclarations) :-
862 chr_translate_line_info(Declarations,'bootstrap',NewDeclarations).
864 chr_translate_line_info(Declarations0,File,NewDeclarations) :-
866 restart_after_flattening(Declarations0,Declarations),
868 chr_source_file(File),
869 /* sort out the interesting stuff from the input */
870 partition_clauses(Declarations,Constraints0,Rules0,OtherClauses),
871 chr_compiler_options:sanity_check,
873 dump_code(Declarations),
875 check_declared_constraints(Constraints0),
876 generate_show_constraint(Constraints0,Constraints,Rules0,Rules1),
877 add_constraints(Constraints),
879 generate_never_stored_rules(Constraints,NewRules),
881 append(Rules1,NewRules,Rules),
882 chr_analysis(Rules,Constraints,Declarations),
883 time('constraint code generation',chr_translate:constraints_code(Constraints,ConstraintClauses)),
884 time('validate store assumptions',chr_translate:validate_store_type_assumptions(Constraints)),
885 phase_end(validate_store_type_assumptions),
887 time('store code generation',chr_translate:store_management_preds(Constraints,StoreClauses)), % depends on actual code used
888 insert_declarations(OtherClauses, Clauses0),
889 chr_module_declaration(CHRModuleDeclaration),
890 append([StoreClauses,ConstraintClauses,CHRModuleDeclaration,[end_of_file]],StuffyGeneratedClauses),
891 clean_clauses(StuffyGeneratedClauses,GeneratedClauses),
892 append([Clauses0,GeneratedClauses], NewDeclarations),
893 dump_code(NewDeclarations),
894 !. /* cut choicepoint of restart_after_flattening */
896 chr_analysis(Rules,Constraints,Declarations) :-
897 maplist(pragma_rule_to_ast_rule,Rules,AstRules),
898 check_rules(Rules,AstRules,Constraints),
899 time('type checking',chr_translate:static_type_check(Rules,AstRules)),
901 collect_constants(Rules,AstRules,Constraints,Declarations),
902 add_occurrences(Rules,AstRules),
903 time('functional dependency',chr_translate:functional_dependency_analysis(Rules)),
904 time('set semantics',chr_translate:set_semantics_rules(Rules)),
905 time('symmetry analysis',chr_translate:symmetry_analysis(Rules)),
906 time('guard simplification',chr_translate:guard_simplification),
907 time('late storage',chr_translate:storage_analysis(Constraints)),
908 time('observation',chr_translate:observation_analysis(Constraints)),
909 time('ai observation',chr_translate:ai_observation_analysis(Constraints)),
910 time('late allocation',chr_translate:late_allocation_analysis(Constraints)),
911 partial_wake_analysis,
912 time('assume constraint stores',chr_translate:assume_constraint_stores(Constraints)),
913 time('default constraint indices',chr_translate:set_constraint_indices(Constraints)),
914 time('check storedness assertions',chr_translate:check_storedness_assertions(Constraints)),
915 time('continuation analysis',chr_translate:continuation_analysis(Constraints)).
917 store_management_preds(Constraints,Clauses) :-
918 generate_attach_detach_a_constraint_all(Constraints,AttachAConstraintClauses),
919 generate_attr_unify_hook(AttrUnifyHookClauses),
920 generate_attach_increment(AttachIncrementClauses),
921 generate_extra_clauses(Constraints,ExtraClauses),
922 generate_insert_delete_constraints(Constraints,DeleteClauses),
923 generate_attach_code(Constraints,StoreClauses),
924 generate_counter_code(CounterClauses),
925 generate_dynamic_type_check_clauses(TypeCheckClauses),
926 append([AttachAConstraintClauses
927 ,AttachIncrementClauses
928 ,AttrUnifyHookClauses
938 insert_declarations(Clauses0, Clauses) :-
939 findall(:- use_module(chr(Module)),(auxiliary_module(Module), is_used_auxiliary_module(Module)),Decls),
940 append(Clauses0, [:- use_module(chr(chr_runtime))|Decls], Clauses).
942 auxiliary_module(chr_hashtable_store).
943 auxiliary_module(chr_integertable_store).
944 auxiliary_module(chr_assoc_store).
946 generate_counter_code(Clauses) :-
947 ( chr_pp_flag(store_counter,on) ->
949 ('$counter_init'(N1) :- nb_setval(N1,0)) ,
950 ('$counter'(N2,X1) :- nb_getval(N2,X1)),
951 ('$counter_inc'(N) :- nb_getval(N,X), Y is X + 1, nb_setval(N,Y)),
952 (:- '$counter_init'('$insert_counter')),
953 (:- '$counter_init'('$delete_counter')),
954 ('$insert_counter_inc' :- '$counter_inc'('$insert_counter')),
955 ('$delete_counter_inc' :- '$counter_inc'('$delete_counter')),
956 ( counter_stats(I,D) :- '$counter'('$insert_counter',I),'$counter'('$delete_counter',D))
962 % for systems with multifile declaration
963 chr_module_declaration(CHRModuleDeclaration) :-
964 get_target_module(Mod),
965 ( Mod \== chr_translate, chr_pp_flag(toplevel_show_store,on) ->
966 CHRModuleDeclaration = [
967 (:- multifile chr:'$chr_module'/1),
968 chr:'$chr_module'(Mod)
971 CHRModuleDeclaration = []
975 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
977 %% Partitioning of clauses into constraint declarations, chr rules and other
980 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
981 %% partition_clauses(+Clauses,-ConstraintDeclarations,-Rules,-OtherClauses) is det.
982 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
983 partition_clauses([],[],[],[]).
984 partition_clauses([Clause|Clauses],ConstraintDeclarations,Rules,OtherClauses) :-
985 ( parse_rule(Clause,Rule) ->
986 ConstraintDeclarations = RestConstraintDeclarations,
987 Rules = [Rule|RestRules],
988 OtherClauses = RestOtherClauses
989 ; is_declaration(Clause,ConstraintDeclaration) ->
990 append(ConstraintDeclaration,RestConstraintDeclarations,ConstraintDeclarations),
992 OtherClauses = RestOtherClauses
993 ; is_module_declaration(Clause,Mod) ->
995 ConstraintDeclarations = RestConstraintDeclarations,
997 OtherClauses = [Clause|RestOtherClauses]
998 ; is_type_definition(Clause) ->
999 ConstraintDeclarations = RestConstraintDeclarations,
1001 OtherClauses = RestOtherClauses
1002 ; is_chr_declaration(Clause) ->
1003 ConstraintDeclarations = RestConstraintDeclarations,
1005 OtherClauses = RestOtherClauses
1006 ; Clause = (handler _) ->
1007 chr_warning(deprecated(Clause),'Backward compatibility: ignoring handler/1 declaration.\n',[]),
1008 ConstraintDeclarations = RestConstraintDeclarations,
1010 OtherClauses = RestOtherClauses
1011 ; Clause = (rules _) ->
1012 chr_warning(deprecated(Clause),'Backward compatibility: ignoring rules/1 declaration.\n',[]),
1013 ConstraintDeclarations = RestConstraintDeclarations,
1015 OtherClauses = RestOtherClauses
1016 ; Clause = option(OptionName,OptionValue) ->
1017 chr_warning(deprecated(Clause),'Instead use `:-chr_option(~w,~w).\'\n',[OptionName,OptionValue]),
1018 handle_option(OptionName,OptionValue),
1019 ConstraintDeclarations = RestConstraintDeclarations,
1021 OtherClauses = RestOtherClauses
1022 ; Clause = (:-chr_option(OptionName,OptionValue)) ->
1023 handle_option(OptionName,OptionValue),
1024 ConstraintDeclarations = RestConstraintDeclarations,
1026 OtherClauses = RestOtherClauses
1027 ; Clause = ('$chr_compiled_with_version'(_)) ->
1028 ConstraintDeclarations = RestConstraintDeclarations,
1030 OtherClauses = ['$chr_compiled_with_version'(3)|RestOtherClauses]
1031 ; ConstraintDeclarations = RestConstraintDeclarations,
1033 OtherClauses = [Clause|RestOtherClauses]
1035 partition_clauses(Clauses,RestConstraintDeclarations,RestRules,RestOtherClauses).
1037 '$chr_compiled_with_version'(2).
1039 is_declaration(D, Constraints) :- %% constraint declaration
1040 ( D = (:- Decl), Decl =.. [F,Cs], F == (chr_constraint) ->
1041 conj2list(Cs,Constraints0)
1044 Decl =.. [constraints,Cs]
1046 D =.. [constraints,Cs]
1048 conj2list(Cs,Constraints0),
1049 chr_warning(deprecated(D),'Instead use :- chr_constraint ~w.\n',[Cs])
1051 extract_type_mode(Constraints0,Constraints).
1053 extract_type_mode([],[]).
1054 extract_type_mode([F/A|R],[F/A|R2]) :- !,extract_type_mode(R,R2).
1055 extract_type_mode([C0|R],[ConstraintSymbol|R2]) :-
1056 ( C0 = C # Annotation ->
1058 extract_annotation(Annotation,F/A)
1063 ConstraintSymbol = F/A,
1065 extract_types_and_modes(Args,ArgTypes,ArgModes),
1066 assert_constraint_type(ConstraintSymbol,ArgTypes),
1067 constraint_mode(ConstraintSymbol,ArgModes),
1068 extract_type_mode(R,R2).
1070 extract_annotation(stored,Symbol) :-
1071 stored_assertion(Symbol).
1072 extract_annotation(default(Goal),Symbol) :-
1073 never_stored_default(Symbol,Goal).
1075 extract_types_and_modes([],[],[]).
1076 extract_types_and_modes([X|R],[T|R2],[M|R3]) :-
1077 extract_type_and_mode(X,T,M),
1078 extract_types_and_modes(R,R2,R3).
1080 extract_type_and_mode(+(T),T,(+)) :- !.
1081 extract_type_and_mode(?(T),T,(?)) :- !.
1082 extract_type_and_mode(-(T),T,(-)) :- !.
1083 extract_type_and_mode((+),any,(+)) :- !.
1084 extract_type_and_mode((?),any,(?)) :- !.
1085 extract_type_and_mode((-),any,(-)) :- !.
1086 extract_type_and_mode(Illegal,_,_) :-
1087 chr_error(syntax(Illegal),'Illegal mode/type declaration.\n\tCorrect syntax is +type, -type or ?type\n\tor +, - or ?.\n',[]).
1089 is_chr_declaration(Declaration) :-
1090 Declaration = (:- chr_declaration Decl),
1091 ( Decl = (Pattern ---> Information) ->
1092 background_info(Pattern,Information)
1093 ; Decl = Information ->
1094 background_info([Information])
1096 is_type_definition(Declaration) :-
1097 is_type_definition(Declaration,Result),
1098 assert_type_definition(Result).
1100 assert_type_definition(typedef(Name,DefList)) :- type_definition(Name,DefList).
1101 assert_type_definition(alias(Alias,Name)) :- type_alias(Alias,Name).
1103 is_type_definition(Declaration,Result) :-
1104 ( Declaration = (:- TDef) ->
1109 TDef =.. [chr_type,TypeDef],
1110 ( TypeDef = (Name ---> Def) ->
1111 tdisj2list(Def,DefList),
1112 Result = typedef(Name,DefList)
1113 ; TypeDef = (Alias == Name) ->
1114 Result = alias(Alias,Name)
1116 Result = typedef(TypeDef,[]),
1117 chr_warning(syntax,'Empty type definition `~w\'.\nAre you sure you want to declare a phantom type?\n',[Declaration])
1120 %% tdisj2list(+Goal,-ListOfGoals) is det.
1122 % no removal of fails, e.g. :- type bool ---> true ; fail.
1123 tdisj2list(Conj,L) :-
1124 tdisj2list(Conj,L,[]).
1126 tdisj2list(Conj,L,T) :-
1128 tdisj2list(G1,L,T1),
1129 tdisj2list(G2,T1,T).
1130 tdisj2list(G,[G | T],T).
1133 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
1134 %% parse_rule(+term,-pragma_rule) is semidet.
1135 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
1136 parse_rule(RI,R) :- %% name @ rule
1137 RI = (Name @ RI2), !,
1138 rule(RI2,yes(Name),R).
1142 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
1143 %% parse_rule(+term,-pragma_rule) is semidet.
1144 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
1146 RI = (RI2 pragma P), !, %% pragmas
1148 Ps = [_] % intercept variable
1152 inc_rule_count(RuleCount),
1153 R = pragma(R1,IDs,Ps,Name,RuleCount),
1154 is_rule(RI2,R1,IDs,R).
1156 inc_rule_count(RuleCount),
1157 R = pragma(R1,IDs,[],Name,RuleCount),
1158 is_rule(RI,R1,IDs,R).
1160 is_rule(RI,R,IDs,RC) :- %% propagation rule
1162 conj2list(H,Head2i),
1163 get_ids(Head2i,IDs2,Head2,RC),
1166 R = rule([],Head2,G,RB)
1168 R = rule([],Head2,true,B)
1170 is_rule(RI,R,IDs,RC) :- %% simplification/simpagation rule
1179 conj2list(H1,Head2i),
1180 conj2list(H2,Head1i),
1181 get_ids(Head2i,IDs2,Head2,0,N,RC),
1182 get_ids(Head1i,IDs1,Head1,N,_,RC),
1183 IDs = ids(IDs1,IDs2)
1184 ; conj2list(H,Head1i),
1186 get_ids(Head1i,IDs1,Head1,RC),
1189 R = rule(Head1,Head2,Guard,Body).
1191 get_ids(Cs,IDs,NCs,RC) :-
1192 get_ids(Cs,IDs,NCs,0,_,RC).
1194 get_ids([],[],[],N,N,_).
1195 get_ids([C|Cs],[N|IDs],[NC|NCs],N,NN,RC) :-
1200 check_direct_pragma(N1,N,RC)
1206 get_ids(Cs,IDs,NCs, M,NN,RC).
1208 check_direct_pragma(passive,Id,PragmaRule) :- !,
1209 PragmaRule = pragma(_,_,_,_,RuleNb),
1211 check_direct_pragma(Abbrev,Id,PragmaRule) :-
1212 ( direct_pragma(FullPragma),
1213 atom_concat(Abbrev,Remainder,FullPragma) ->
1214 chr_warning(problem_pragma(Abbrev,PragmaRule),'completed `~w\' to `~w\'\n',[Abbrev,FullPragma])
1216 chr_warning(unsupported_pragma(Abbrev,PragmaRule),'',[])
1219 direct_pragma(passive).
1221 is_module_declaration((:- module(Mod)),Mod).
1222 is_module_declaration((:- module(Mod,_)),Mod).
1224 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1226 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1228 add_constraints([]).
1229 add_constraints([C|Cs]) :-
1230 max_occurrence(C,0),
1234 constraint_mode(C,Mode),
1235 add_constraints(Cs).
1239 add_rules([Rule|Rules]) :-
1240 Rule = pragma(_,_,_,_,RuleNb),
1244 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1246 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1247 %% Some input verification:
1249 check_declared_constraints(Constraints) :-
1250 tree_set_empty(Acc),
1251 check_declared_constraints(Constraints,Acc).
1253 check_declared_constraints([],_).
1254 check_declared_constraints([C|Cs],Acc) :-
1255 ( tree_set_memberchk(C,Acc) ->
1256 chr_error(syntax(C),'Constraint multiply defined: ~w.\n\tRemove redundant declaration!\n',[C])
1260 tree_set_add(Acc,C,NAcc),
1261 check_declared_constraints(Cs,NAcc).
1263 %% - all constraints in heads are declared constraints
1264 %% - all passive pragmas refer to actual head constraints
1266 check_rules(PragmaRules,AstRules,Decls) :-
1267 maplist(check_rule(Decls),PragmaRules,AstRules).
1269 check_rule(Decls,PragmaRule,AstRule) :-
1270 PragmaRule = pragma(_Rule,_IDs,Pragmas,_Name,_N),
1271 check_ast_rule_indexing(AstRule,PragmaRule),
1272 % check_rule_indexing(PragmaRule),
1273 check_ast_trivial_propagation_rule(AstRule,PragmaRule),
1274 % check_trivial_propagation_rule(PragmaRule),
1275 check_ast_head_constraints(AstRule,Decls,PragmaRule),
1276 % Rule = rule(H1,H2,_,_),
1277 % check_head_constraints(H1,Decls,PragmaRule),
1278 % check_head_constraints(H2,Decls,PragmaRule),
1279 check_pragmas(Pragmas,PragmaRule).
1281 %-------------------------------------------------------------------------------
1282 % Make all heads passive in trivial propagation rule
1283 % ... ==> ... | true.
1284 check_ast_trivial_propagation_rule(AstRule,PragmaRule) :-
1285 AstRule = ast_rule(AstHead,_,_,AstBody,_),
1286 ( AstHead = propagation(_),
1288 chr_warning(weird_program,'Ignoring propagation rule with empty body: ~@.\n\t\n',[format_rule(PragmaRule)]),
1289 set_rule_passive(PragmaRule)
1294 set_rule_passive(PragmaRule) :-
1295 PragmaRule = pragma(_Rule,_IDs,_Pragmas,_Name,RuleNb),
1296 set_all_passive(RuleNb).
1298 check_trivial_propagation_rule(PragmaRule) :-
1299 PragmaRule = pragma(Rule,IDs,Pragmas,Name,RuleNb),
1300 ( Rule = rule([],_,_,true) ->
1301 chr_warning(weird_program,'Ignoring propagation rule with empty body: ~@.\n\t\n',[format_rule(PragmaRule)]),
1302 set_all_passive(RuleNb)
1307 %-------------------------------------------------------------------------------
1308 check_ast_head_constraints(ast_rule(AstHead,_,_,_,_),Decls,PragmaRule) :-
1309 check_ast_head_constraints_(AstHead,Decls,PragmaRule).
1311 check_ast_head_constraints_(simplification(AstConstraints),Decls,PragmaRule) :-
1312 maplist(check_ast_head_constraint(Decls,PragmaRule),AstConstraints).
1313 check_ast_head_constraints_(propagation(AstConstraints),Decls,PragmaRule) :-
1314 maplist(check_ast_head_constraint(Decls,PragmaRule),AstConstraints).
1315 check_ast_head_constraints_(simpagation(AstConstraints1,AstConstraints2),Decls,PragmaRule) :-
1316 maplist(check_ast_head_constraint(Decls,PragmaRule),AstConstraints1).
1317 maplist(check_ast_head_constraint(Decls,PragmaRule),AstConstraints2).
1319 check_ast_head_constraint(Decls,PragmaRule,chr_constraint(Symbol,_,Constraint)) :-
1320 ( memberchk(Symbol,Decls) ->
1323 chr_error(syntax(Constraint),'Undeclared constraint ~w in head of ~@.\n\tConstraint should be one of ~w.\n', [F/A,format_rule(PragmaRule),Decls])
1326 check_head_constraints([],_,_).
1327 check_head_constraints([Constr|Rest],Decls,PragmaRule) :-
1328 functor(Constr,F,A),
1329 ( memberchk(F/A,Decls) ->
1330 check_head_constraints(Rest,Decls,PragmaRule)
1332 chr_error(syntax(Constr),'Undeclared constraint ~w in head of ~@.\n\tConstraint should be one of ~w.\n', [F/A,format_rule(PragmaRule),Decls])
1334 %-------------------------------------------------------------------------------
1336 check_pragmas([],_).
1337 check_pragmas([Pragma|Pragmas],PragmaRule) :-
1338 check_pragma(Pragma,PragmaRule),
1339 check_pragmas(Pragmas,PragmaRule).
1341 check_pragma(Pragma,PragmaRule) :-
1343 chr_error(syntax(Pragma),'Invalid pragma ~w in ~@.\n\tPragma should not be a variable!\n',[Pragma,format_rule(PragmaRule)]).
1344 check_pragma(passive(ID), PragmaRule) :-
1346 PragmaRule = pragma(_,ids(IDs1,IDs2),_,_,RuleNb),
1347 ( memberchk_eq(ID,IDs1) ->
1349 ; memberchk_eq(ID,IDs2) ->
1352 chr_error(syntax(ID),'Invalid identifier ~w in pragma passive in ~@.\n', [ID,format_rule(PragmaRule)])
1356 check_pragma(mpassive(IDs), PragmaRule) :-
1358 PragmaRule = pragma(_,_,_,_,RuleNb),
1359 chr_warning(experimental,'Experimental pragma ~w. Use with care!\n',[mpassive(IDs)]),
1360 maplist(passive(RuleNb),IDs).
1362 check_pragma(Pragma, PragmaRule) :-
1363 Pragma = already_in_heads,
1365 chr_warning(unsupported_pragma(Pragma,PragmaRule),'Termination and correctness may be affected.\n',[]).
1367 check_pragma(Pragma, PragmaRule) :-
1368 Pragma = already_in_head(_),
1370 chr_warning(unsupported_pragma(Pragma,PragmaRule),'Termination and correctness may be affected.\n',[]).
1372 check_pragma(Pragma, PragmaRule) :-
1373 Pragma = no_history,
1375 chr_warning(experimental,'Experimental pragma no_history. Use with care!\n',[]),
1376 PragmaRule = pragma(_,_,_,_,N),
1379 check_pragma(Pragma, PragmaRule) :-
1380 Pragma = history(HistoryName,IDs),
1382 PragmaRule = pragma(_,ids(IDs1,IDs2),_,_,RuleNb),
1383 chr_warning(experimental,'Experimental pragma ~w. Use with care!\n',[Pragma]),
1385 chr_error(syntax(Pragma),'Pragma history only implemented for propagation rules.\n',[])
1386 ; \+ atom(HistoryName) ->
1387 chr_error(syntax(Pragma),'Illegal argument for pragma history: ~w is not an atom (rule number ~w).\n',[HistoryName,RuleNb])
1389 chr_error(syntax(Pragma),'Illegal argument for pragma history: ~w is not a set (rule number ~w).\n',[IDs,RuleNb])
1390 ; check_history_pragma_ids(IDs,IDs1,IDs2) ->
1391 history(RuleNb,HistoryName,IDs)
1393 chr_error(syntax(Pragma),'Invalid identifier(s) in pragma ~w of rule number ~w.\n',[Pragma,RuleNb])
1395 check_pragma(Pragma,PragmaRule) :-
1396 Pragma = line_number(LineNumber),
1398 PragmaRule = pragma(_,_,_,_,RuleNb),
1399 line_number(RuleNb,LineNumber).
1401 check_history_pragma_ids([], _, _).
1402 check_history_pragma_ids([ID|IDs],IDs1,IDs2) :-
1403 ( memberchk_eq(ID,IDs2) ; memberchk_eq(ID,IDs1) ),
1404 check_history_pragma_ids(IDs,IDs1,IDs2).
1406 check_pragma(Pragma,PragmaRule) :-
1407 chr_error(syntax(Pragma),'Unknown pragma ~w in ~@.\n', [Pragma,format_rule(PragmaRule)]).
1409 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1410 %% no_history(+RuleNb) is det.
1411 :- chr_constraint no_history/1.
1412 :- chr_option(mode,no_history(+)).
1413 :- chr_option(type_declaration,no_history(int)).
1415 %% has_no_history(+RuleNb) is semidet.
1416 :- chr_constraint has_no_history/1.
1417 :- chr_option(mode,has_no_history(+)).
1418 :- chr_option(type_declaration,has_no_history(int)).
1420 no_history(RuleNb) \ has_no_history(RuleNb) <=> true.
1421 has_no_history(_) <=> fail.
1423 :- chr_constraint history/3.
1424 :- chr_option(mode,history(+,+,+)).
1425 :- chr_option(type_declaration,history(any,any,list)).
1427 :- chr_constraint named_history/3.
1429 history(RuleNb,_,_), history(RuleNb,_,_) ==>
1430 chr_error(syntax,'Only one pragma history allowed per rule (rule number ~w)\n',[RuleNb]). %'
1432 history(RuleNb1,Name,IDs1), history(RuleNb2,Name,IDs2) ==>
1433 length(IDs1,L1), length(IDs2,L2),
1435 chr_error(syntax,'The history named ~w does not always range over an equal amount of occurrences.\n',[Name])
1437 test_named_history_id_pairs(RuleNb1,IDs1,RuleNb2,IDs2)
1440 test_named_history_id_pairs(_, [], _, []).
1441 test_named_history_id_pairs(RuleNb1, [ID1|IDs1], RuleNb2, [ID2|IDs2]) :-
1442 test_named_history_id_pair(RuleNb1,ID1,RuleNb2,ID2),
1443 test_named_history_id_pairs(RuleNb1,IDs1,RuleNb2,IDs2).
1445 :- chr_constraint test_named_history_id_pair/4.
1446 :- chr_option(mode,test_named_history_id_pair(+,+,+,+)).
1448 occurrence(C,_,RuleNb1,ID1,_), occurrence(C,_,RuleNb2,ID2,_)
1449 \ test_named_history_id_pair(RuleNb1,ID1,RuleNb2,ID2) <=> true.
1450 test_named_history_id_pair(RuleNb1,ID1,RuleNb2,ID2) <=>
1451 chr_error(syntax,'Occurrences of shared history in rules number ~w and ~w do not correspond\n', [RuleNb2,RuleNb1]).
1453 history(RuleNb,Name,IDs) \ named_history(RuleNb,QName,QIDs) <=> QName = Name, QIDs = IDs.
1454 named_history(_,_,_) <=> fail.
1456 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1459 format_rule(PragmaRule) :-
1460 PragmaRule = pragma(_,_,_,MaybeName,RuleNumber),
1461 ( MaybeName = yes(Name) ->
1462 write('rule '), write(Name)
1464 write('rule number '), write(RuleNumber)
1466 get_line_number(RuleNumber,LineNumber),
1471 check_ast_rule_indexing(AstRule,PragmaRule) :-
1472 AstRule = ast_rule(AstHead,AstGuard,_,_,_),
1473 tree_set_empty(EmptyVarSet),
1474 ast_head_variables(AstHead,EmptyVarSet,VarSet),
1475 ast_remove_anti_monotonic_guards(AstGuard,VarSet,MonotonicAstGuard),
1476 ast_term_list_variables(MonotonicAstGuard,EmptyVarSet,GuardVarSet),
1477 check_ast_head_indexing(AstHead,GuardVarSet),
1478 % check_indexing(H1,NG-H2),
1479 % check_indexing(H2,NG-H1),
1481 ( chr_pp_flag(term_indexing,on) ->
1482 PragmaRule = pragma(Rule,_,_,_,_),
1483 Rule = rule(H1,H2,G,_),
1484 term_variables(H1-H2,HeadVars),
1485 remove_anti_monotonic_guards(G,HeadVars,NG),
1486 term_variables(NG,GuardVariables),
1487 append(H1,H2,Heads),
1488 check_specs_indexing(Heads,GuardVariables,Specs)
1493 check_ast_head_indexing(simplification(H1),VarSet) :-
1494 check_ast_indexing(H1,VarSet).
1495 check_ast_head_indexing(propagation(H2),VarSet) :-
1496 check_ast_indexing(H2,VarSet).
1497 check_ast_head_indexing(simpagation(H1,H2),VarSet) :-
1498 ast_constraint_list_variables(H2,VarSet,VarSet1),
1499 check_ast_indexing(H1,VarSet1),
1500 ast_constraint_list_variables(H1,VarSet,VarSet2),
1501 check_ast_indexing(H2,VarSet2).
1503 check_rule_indexing(PragmaRule) :-
1504 PragmaRule = pragma(Rule,_,_,_,_),
1505 Rule = rule(H1,H2,G,_),
1506 term_variables(H1-H2,HeadVars),
1507 remove_anti_monotonic_guards(G,HeadVars,NG),
1508 check_indexing(H1,NG-H2),
1509 check_indexing(H2,NG-H1),
1511 ( chr_pp_flag(term_indexing,on) ->
1512 term_variables(NG,GuardVariables),
1513 append(H1,H2,Heads),
1514 check_specs_indexing(Heads,GuardVariables,Specs)
1519 :- chr_constraint indexing_spec/2.
1520 :- chr_option(mode,indexing_spec(+,+)).
1522 :- chr_constraint get_indexing_spec/2.
1523 :- chr_option(mode,get_indexing_spec(+,-)).
1526 indexing_spec(FA,Spec) \ get_indexing_spec(FA,R) <=> R = Spec.
1527 get_indexing_spec(_,Spec) <=> Spec = [].
1529 indexing_spec(FA,Specs1), indexing_spec(FA,Specs2)
1531 append(Specs1,Specs2,Specs),
1532 indexing_spec(FA,Specs).
1534 remove_anti_monotonic_guards(G,Vars,NG) :-
1536 remove_anti_monotonic_guard_list(GL,Vars,NGL),
1539 remove_anti_monotonic_guard_list([],_,[]).
1540 remove_anti_monotonic_guard_list([G|Gs],Vars,NGs) :-
1541 ( G = var(X), memberchk_eq(X,Vars) ->
1546 remove_anti_monotonic_guard_list(Gs,Vars,RGs).
1548 ast_remove_anti_monotonic_guards([],_,[]).
1549 ast_remove_anti_monotonic_guards([G|Gs],VarSet,NGs) :-
1550 ( G = compound(var,1,[X],_),
1551 ast_var_memberchk(X,VarSet) ->
1556 ast_remove_anti_monotonic_guards(Gs,VarSet,RGs).
1557 %-------------------------------------------------------------------------------
1559 check_ast_indexing([],_).
1560 check_ast_indexing([Head|Heads],VarSet) :-
1561 Head = chr_constraint(Symbol,Args,_Constraint),
1562 ast_constraint_list_variables(Heads,VarSet,VarSet1),
1563 check_ast_indexing(Args,1,Symbol,VarSet1),
1564 ast_constraint_variables(Head,VarSet,NVarSet),
1565 check_ast_indexing(Heads,NVarSet).
1567 check_ast_indexing([],_,_,_).
1568 check_ast_indexing([Arg|Args],I,Symbol,VarSet) :-
1569 ( is_indexed_argument(Symbol,I) ->
1571 ; ast_nonvar(Arg) ->
1572 indexed_argument(Symbol,I)
1574 ast_term_list_variables(Args,VarSet,VarSet1),
1575 ( ast_var_memberchk(Arg,VarSet1) ->
1576 indexed_argument(Symbol,I)
1582 ast_term_variables(Arg,VarSet,NVarSet),
1583 check_ast_indexing(Args,J,Symbol,NVarSet).
1585 % check_indexing(list(chr_constraint),variables)
1586 check_indexing([],_).
1587 check_indexing([Head|Heads],Other) :-
1590 term_variables(Heads-Other,OtherVars),
1591 check_indexing(Args,1,F/A,OtherVars),
1592 check_indexing(Heads,[Head|Other]).
1594 check_indexing([],_,_,_).
1595 check_indexing([Arg|Args],I,FA,OtherVars) :-
1596 ( is_indexed_argument(FA,I) ->
1599 indexed_argument(FA,I)
1601 term_variables(Args,ArgsVars),
1602 append(ArgsVars,OtherVars,RestVars),
1603 ( memberchk_eq(Arg,RestVars) ->
1604 indexed_argument(FA,I)
1610 term_variables(Arg,NVars),
1611 append(NVars,OtherVars,NOtherVars),
1612 check_indexing(Args,J,FA,NOtherVars).
1613 %-------------------------------------------------------------------------------
1615 check_specs_indexing([],_,[]).
1616 check_specs_indexing([Head|Heads],Variables,Specs) :-
1617 Specs = [Spec|RSpecs],
1618 term_variables(Heads,OtherVariables,Variables),
1619 check_spec_indexing(Head,OtherVariables,Spec),
1620 term_variables(Head,NVariables,Variables),
1621 check_specs_indexing(Heads,NVariables,RSpecs).
1623 check_spec_indexing(Head,OtherVariables,Spec) :-
1625 Spec = spec(F,A,ArgSpecs),
1627 check_args_spec_indexing(Args,1,OtherVariables,ArgSpecs),
1628 indexing_spec(F/A,[ArgSpecs]).
1630 check_args_spec_indexing([],_,_,[]).
1631 check_args_spec_indexing([Arg|Args],I,OtherVariables,ArgSpecs) :-
1632 term_variables(Args,Variables,OtherVariables),
1633 ( check_arg_spec_indexing(Arg,I,Variables,ArgSpec) ->
1634 ArgSpecs = [ArgSpec|RArgSpecs]
1636 ArgSpecs = RArgSpecs
1639 term_variables(Arg,NOtherVariables,OtherVariables),
1640 check_args_spec_indexing(Args,J,NOtherVariables,RArgSpecs).
1642 check_arg_spec_indexing(Arg,I,Variables,ArgSpec) :-
1644 memberchk_eq(Arg,Variables),
1645 ArgSpec = specinfo(I,any,[])
1648 ArgSpec = specinfo(I,F/A,[ArgSpecs]),
1650 check_args_spec_indexing(Args,1,Variables,ArgSpecs)
1653 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1655 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1658 add_occurrences(PragmaRules,AstRules) :-
1659 maplist(add_rule_occurrences,PragmaRules,AstRules).
1661 add_rule_occurrences(PragmaRule,AstRule) :-
1662 PragmaRule = pragma(_,IDs,_,_,Nb),
1663 AstRule = ast_rule(AstHead,_,_,_,_),
1664 add_head_occurrences(AstHead,IDs,Nb).
1666 add_head_occurrences(simplification(H1),ids(IDs1,_),Nb) :-
1667 maplist(add_constraint_occurrence(Nb,simplification),H1,IDs1).
1668 add_head_occurrences(propagation(H2),ids(_,IDs2),Nb) :-
1669 maplist(add_constraint_occurrence(Nb,propagation),H2,IDs2).
1670 add_head_occurrences(simpagation(H1,H2),ids(IDs1,IDs2),Nb) :-
1671 maplist(add_constraint_occurrence(Nb,simplification),H1,IDs1),
1672 maplist(add_constraint_occurrence(Nb,propagation),H2,IDs2).
1674 add_constraint_occurrence(Nb,OccType,Constraint,ID) :-
1675 Constraint = chr_constraint(Symbol,_,_),
1676 new_occurrence(Symbol,Nb,ID,OccType).
1678 % add_occurrences([],[]).
1679 % add_occurrences([Rule|Rules],[]) :-
1680 % Rule = pragma(rule(H1,H2,_,_),ids(IDs1,IDs2),_,_,Nb),
1681 % add_occurrences(H1,IDs1,simplification,Nb),
1682 % add_occurrences(H2,IDs2,propagation,Nb),
1683 % add_occurrences(Rules).
1685 % add_occurrences([],[],_,_).
1686 % add_occurrences([H|Hs],[ID|IDs],Type,RuleNb) :-
1689 % new_occurrence(FA,RuleNb,ID,Type),
1690 % add_occurrences(Hs,IDs,Type,RuleNb).
1692 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1694 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1695 % Observation Analysis
1705 :- chr_constraint observation_analysis/1.
1706 :- chr_option(mode, observation_analysis(+)).
1708 observation_analysis(Cs), rule(RuleNb,PragmaRule) # Id ==>
1709 PragmaRule = pragma(rule(_,_,Guard,Body),_,_,_,_),
1710 ( chr_pp_flag(store_in_guards, on) ->
1711 observation_analysis(RuleNb, Guard, guard, Cs)
1715 observation_analysis(RuleNb, Body, body, Cs)
1718 observation_analysis(_) <=> true.
1720 observation_analysis(RuleNb, Term, GB, Cs) :-
1721 ( all_spawned(RuleNb,GB) ->
1724 spawns_all(RuleNb,GB)
1732 observation_analysis(RuleNb,T1,GB,Cs),
1733 observation_analysis(RuleNb,T2,GB,Cs)
1735 observation_analysis(RuleNb,T1,GB,Cs),
1736 observation_analysis(RuleNb,T2,GB,Cs)
1737 ; Term = (T1->T2) ->
1738 observation_analysis(RuleNb,T1,GB,Cs),
1739 observation_analysis(RuleNb,T2,GB,Cs)
1741 observation_analysis(RuleNb,T,GB,Cs)
1742 ; functor(Term,F,A), memberchk(F/A,Cs) ->
1743 spawns(RuleNb,GB,F/A)
1745 spawns_all_triggers(RuleNb,GB)
1746 ; Term = (_ is _) ->
1747 spawns_all_triggers(RuleNb,GB)
1748 ; builtin_binds_b(Term,Vars) ->
1752 spawns_all_triggers(RuleNb,GB)
1755 spawns_all(RuleNb,GB)
1758 :- chr_constraint spawns/3.
1759 :- chr_option(mode, spawns(+,+,+)).
1760 :- chr_type spawns_type ---> guard ; body.
1761 :- chr_option(type_declaration,spawns(any,spawns_type,any)).
1763 :- chr_constraint spawns_all/2, spawns_all_triggers/2.
1764 :- chr_option(mode, spawns_all(+,+)).
1765 :- chr_option(type_declaration,spawns_all(any,spawns_type)).
1766 :- chr_option(mode, spawns_all_triggers(+,+)).
1767 :- chr_option(type_declaration,spawns_all_triggers(any,spawns_type)).
1769 spawns_all(RuleNb,GB) \ spawns_all(RuleNb,GB) <=> true.
1770 spawns_all(RuleNb,guard) \ spawns_all(RuleNb,body) <=> true.
1771 spawns_all_triggers(RuleNb,GB) \ spawns_all_triggers(RuleNb,GB) <=> true.
1772 spawns_all_triggers(RuleNb,guard) \ spawns_all_triggers(RuleNb,body) <=> true.
1773 spawns(RuleNb,GB,C) \ spawns(RuleNb,GB,C) <=> true.
1774 spawns(RuleNb,guard,C) \ spawns(RuleNb,body,C) <=> true.
1776 spawns_all(RuleNb,GB) \ spawns(RuleNb,GB,_) <=> true.
1777 spawns_all(RuleNb,guard) \ spawns(RuleNb,body,_) <=> true.
1778 spawns_all(RuleNb,GB) \ spawns_all_triggers(RuleNb,GB) <=> true.
1779 spawns_all(RuleNb,guard) \ spawns_all_triggers(RuleNb,body) <=> true.
1781 spawns_all_triggers(RuleNb,GB) \ spawns(RuleNb,GB,C) <=> may_trigger(C) | true.
1782 spawns_all_triggers(RuleNb,guard) \ spawns(RuleNb,body,C) <=> may_trigger(C) | true.
1784 spawns_all(RuleNb2,_), occurrence(C1,_,RuleNb2,O,_)#Id
1786 spawns(RuleNb1,GB,C1)
1788 \+ is_passive(RuleNb2,O)
1790 spawns_all(RuleNb1,GB)
1794 occurrence(C1,_,RuleNb2,O,_)#Id, spawns_all(RuleNb2,_)
1796 \+(\+ spawns_all_triggers_implies_spawns_all), % in the hope it schedules this guard early...
1797 \+ is_passive(RuleNb2,O), may_trigger(C1)
1799 spawns_all_triggers_implies_spawns_all
1803 :- chr_constraint spawns_all_triggers_implies_spawns_all/0.
1804 spawns_all_triggers_implies_spawns_all, spawns_all_triggers_implies_spawns_all <=> fail.
1805 spawns_all_triggers_implies_spawns_all \
1806 spawns_all_triggers(RuleNb,GB) <=> spawns_all(RuleNb,GB).
1808 spawns_all_triggers(RuleNb2,_), occurrence(C1,_,RuleNb2,O,_)#Id
1810 spawns(RuleNb1,GB,C1)
1813 \+ is_passive(RuleNb2,O)
1815 spawns_all_triggers(RuleNb1,GB)
1819 spawns_all_triggers(RuleNb2,_), occurrence(C1,_,RuleNb2,O,_)#Id,
1820 spawns(RuleNb1,GB,C1)
1823 \+ is_passive(RuleNb2,O)
1825 spawns_all_triggers(RuleNb1,GB)
1829 % a bit dangerous this rule: could start propagating too much too soon?
1830 spawns(RuleNb2,_,C2), occurrence(C1,_,RuleNb2,O,_)#Id,
1831 spawns(RuleNb1,GB,C1)
1833 RuleNb1 \== RuleNb2, C1 \== C2,
1834 \+ is_passive(RuleNb2,O)
1836 spawns(RuleNb1,GB,C2)
1840 spawns(RuleNb2,_,C2), occurrence(C1,_,RuleNb2,O,_)#Id,
1841 spawns_all_triggers(RuleNb1,GB)
1843 \+ is_passive(RuleNb2,O), may_trigger(C1), \+ may_trigger(C2)
1845 spawns(RuleNb1,GB,C2)
1850 :- chr_constraint all_spawned/2.
1851 :- chr_option(mode, all_spawned(+,+)).
1852 spawns_all(RuleNb,guard) \ all_spawned(RuleNb,_) <=> true.
1853 spawns_all(RuleNb,GB) \ all_spawned(RuleNb,GB) <=> true.
1854 all_spawned(RuleNb,GB) <=> fail.
1857 % Overview of the supported queries:
1858 % is_observed(+functor/artiy, +occurrence_number, +(guard;body))
1859 % only succeeds if the occurrence is observed by the
1860 % guard resp. body (depending on the last argument) of its rule
1861 % is_observed(+functor/artiy, +occurrence_number, -)
1862 % succeeds if the occurrence is observed by either the guard or
1863 % the body of its rule
1864 % NOTE: the last argument is NOT bound by this query
1866 % do_is_observed(+functor/artiy,+rule_number,+(guard;body))
1867 % succeeds if the given constraint is observed by the given
1869 % do_is_observed(+functor/artiy,+rule_number)
1870 % succeeds if the given constraint is observed by the given
1871 % rule (either its guard or its body)
1876 ai_is_observed(C,O).
1878 is_stored_in_guard(C,RuleNb) :-
1879 chr_pp_flag(store_in_guards, on),
1880 do_is_observed(C,RuleNb,guard).
1882 :- chr_constraint is_observed/3.
1883 :- chr_option(mode, is_observed(+,+,+)).
1884 occurrence(C,O,RuleNb,_,_) \ is_observed(C,O,GB) <=> do_is_observed(C,RuleNb,GB).
1885 is_observed(_,_,_) <=> fail. % this will not happen in practice
1888 :- chr_constraint do_is_observed/3.
1889 :- chr_option(mode, do_is_observed(+,+,?)).
1890 :- chr_constraint do_is_observed/2.
1891 :- chr_option(mode, do_is_observed(+,+)).
1893 do_is_observed(C,RuleNb,GB) <=> var(GB) | do_is_observed(C,RuleNb).
1896 % a constraint C is observed if the GB of the rule it occurs in spawns all,
1897 % and some non-passive occurrence of some (possibly other) constraint
1898 % exists in a rule (could be same rule) with at least one occurrence of C
1900 spawns_all(RuleNb,GB),
1901 occurrence(_,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1903 do_is_observed(C,RuleNb,GB)
1905 \+ is_passive(RuleNb2,O)
1909 spawns_all(RuleNb,_),
1910 occurrence(_,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1912 do_is_observed(C,RuleNb)
1914 \+ is_passive(RuleNb2,O)
1919 % a constraint C is observed if the GB of the rule it occurs in spawns a
1920 % constraint C2 that occurs non-passively in a rule (possibly the same rule)
1921 % as an occurrence of C
1923 spawns(RuleNb,GB,C2),
1924 occurrence(C2,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1926 do_is_observed(C,RuleNb,GB)
1928 \+ is_passive(RuleNb2,O)
1932 spawns(RuleNb,_,C2),
1933 occurrence(C2,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1935 do_is_observed(C,RuleNb)
1937 \+ is_passive(RuleNb2,O)
1941 % (3) spawns_all_triggers
1942 % a constraint C is observed if the GB of the rule it occurs in spawns all triggers
1943 % and some non-passive occurrence of some (possibly other) constraint that may trigger
1944 % exists in a rule (could be same rule) with at least one occurrence of C
1946 spawns_all_triggers(RuleNb,GB),
1947 occurrence(C2,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1949 do_is_observed(C,RuleNb,GB)
1951 \+ is_passive(RuleNb2,O), may_trigger(C2)
1955 spawns_all_triggers(RuleNb,_),
1956 occurrence(C2,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1958 do_is_observed(C,RuleNb)
1960 \+ is_passive(RuleNb2,O), may_trigger(C2)
1964 % (4) conservativeness
1965 do_is_observed(_,_,_) <=> chr_pp_flag(observation_analysis,off).
1966 do_is_observed(_,_) <=> chr_pp_flag(observation_analysis,off).
1969 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1971 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1974 %% Generated predicates
1975 %% attach_$CONSTRAINT
1977 %% detach_$CONSTRAINT
1980 %% attach_$CONSTRAINT
1981 generate_attach_detach_a_constraint_all([],[]).
1982 generate_attach_detach_a_constraint_all([Constraint|Constraints],Clauses) :-
1983 ( ( chr_pp_flag(debugable,on) ; is_stored(Constraint), \+ only_ground_indexed_arguments(Constraint), \+ get_store_type(Constraint,var_assoc_store(_,_)) ) ->
1984 generate_attach_a_constraint(Constraint,Clauses1),
1985 generate_detach_a_constraint(Constraint,Clauses2)
1990 generate_attach_detach_a_constraint_all(Constraints,Clauses3),
1991 append([Clauses1,Clauses2,Clauses3],Clauses).
1993 generate_attach_a_constraint(Constraint,[Clause1,Clause2]) :-
1994 generate_attach_a_constraint_nil(Constraint,Clause1),
1995 generate_attach_a_constraint_cons(Constraint,Clause2).
1997 attach_constraint_atom(FA,Vars,Susp,Atom) :-
1998 make_name('attach_',FA,Name),
1999 Atom =.. [Name,Vars,Susp].
2001 generate_attach_a_constraint_nil(FA,Clause) :-
2002 Clause = (Head :- true),
2003 attach_constraint_atom(FA,[],_,Head).
2005 generate_attach_a_constraint_cons(FA,Clause) :-
2006 Clause = (Head :- Body),
2007 attach_constraint_atom(FA,[Var|Vars],Susp,Head),
2008 attach_constraint_atom(FA,Vars,Susp,RecursiveCall),
2009 Body = ( AttachBody, Subscribe, RecursiveCall ),
2010 get_max_constraint_index(N),
2012 generate_attach_body_1(FA,Var,Susp,AttachBody)
2014 generate_attach_body_n(FA,Var,Susp,AttachBody)
2016 % SWI-Prolog specific code
2017 chr_pp_flag(solver_events,NMod),
2019 Args = [[Var|_],Susp],
2020 get_target_module(Mod),
2021 use_auxiliary_predicate(run_suspensions),
2022 Subscribe = clp_events:subscribe(Var,NMod,Mod,Mod:'$run_suspensions'([Susp]))
2027 generate_attach_body_1(FA,Var,Susp,Body) :-
2028 get_target_module(Mod),
2030 ( get_attr(Var, Mod, Susps) ->
2031 put_attr(Var, Mod, [Susp|Susps])
2033 put_attr(Var, Mod, [Susp])
2036 generate_attach_body_n(F/A,Var,Susp,Body) :-
2037 chr_pp_flag(experiment,off), !,
2038 get_constraint_index(F/A,Position),
2039 get_max_constraint_index(Total),
2040 get_target_module(Mod),
2041 add_attr(Total,Susp,Position,TAttr,AddGoal,NTAttr),
2042 singleton_attr(Total,Susp,Position,NewAttr3),
2044 ( get_attr(Var,Mod,TAttr) ->
2046 put_attr(Var,Mod,NTAttr)
2048 put_attr(Var,Mod,NewAttr3)
2050 generate_attach_body_n(F/A,Var,Susp,Body) :-
2051 chr_pp_flag(experiment,on), !,
2052 get_constraint_index(F/A,Position),
2053 or_pattern(Position,Pattern),
2054 Position1 is Position + 1,
2055 get_max_constraint_index(Total),
2056 get_target_module(Mod),
2057 singleton_attr(Total,Susp,Position,NewAttr3),
2059 ( get_attr(Var,Mod,TAttr) ->
2060 arg(1,TAttr,BitVector),
2061 arg(Position1,TAttr,Susps),
2062 NBitVector is BitVector \/ Pattern,
2063 setarg(1,TAttr,NBitVector),
2064 setarg(Position1,TAttr,[Susp|Susps])
2066 put_attr(Var,Mod,NewAttr3)
2069 %% detach_$CONSTRAINT
2070 generate_detach_a_constraint(Constraint,[Clause1,Clause2]) :-
2071 generate_detach_a_constraint_nil(Constraint,Clause1),
2072 generate_detach_a_constraint_cons(Constraint,Clause2).
2074 detach_constraint_atom(FA,Vars,Susp,Atom) :-
2075 make_name('detach_',FA,Name),
2076 Atom =.. [Name,Vars,Susp].
2078 generate_detach_a_constraint_nil(FA,Clause) :-
2079 Clause = ( Head :- true),
2080 detach_constraint_atom(FA,[],_,Head).
2082 generate_detach_a_constraint_cons(FA,Clause) :-
2083 Clause = (Head :- Body),
2084 detach_constraint_atom(FA,[Var|Vars],Susp,Head),
2085 detach_constraint_atom(FA,Vars,Susp,RecursiveCall),
2086 Body = ( DetachBody, RecursiveCall ),
2087 get_max_constraint_index(N),
2089 generate_detach_body_1(FA,Var,Susp,DetachBody)
2091 generate_detach_body_n(FA,Var,Susp,DetachBody)
2094 generate_detach_body_1(FA,Var,Susp,Body) :-
2095 get_target_module(Mod),
2097 ( get_attr(Var,Mod,Susps) ->
2098 'chr sbag_del_element'(Susps,Susp,NewSusps),
2102 put_attr(Var,Mod,NewSusps)
2108 generate_detach_body_n(F/A,Var,Susp,Body) :-
2109 get_constraint_index(F/A,Position),
2110 get_max_constraint_index(Total),
2111 rem_attr(Total,Var,Susp,Position,TAttr,RemGoal),
2112 get_target_module(Mod),
2114 ( get_attr(Var,Mod,TAttr) ->
2120 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2121 %-------------------------------------------------------------------------------
2122 %% generate_indexed_variables_body(+ConstraintSymbol,+ArgList,-Body,-VarList) is det.
2123 :- chr_constraint generate_indexed_variables_body/4.
2124 :- chr_option(mode,generate_indexed_variables_body(+,?,+,?)).
2125 :- chr_option(type_declaration,generate_indexed_variables_body(constraint,any,any,any)).
2126 %-------------------------------------------------------------------------------
2127 constraint_mode(F/A,ArgModes) \ generate_indexed_variables_body(F/A,Args,Body,Vars) <=>
2128 get_indexing_spec(F/A,Specs),
2129 ( chr_pp_flag(term_indexing,on) ->
2130 spectermvars(Specs,Args,F,A,Body,Vars)
2132 get_constraint_type_det(F/A,ArgTypes),
2133 create_indexed_variables_body(Args,ArgModes,ArgTypes,Vars,1,F/A,MaybeBody,N),
2134 ( MaybeBody == empty ->
2141 Term =.. [term|Args]
2143 Body = term_variables(Term,Vars)
2148 generate_indexed_variables_body(FA,_,_,_) <=>
2149 chr_error(internal,'generate_indexed_variables_body: missing mode info for ~w.\n',[FA]).
2150 %===============================================================================
2152 create_indexed_variables_body([],[],[],_,_,_,empty,0).
2153 create_indexed_variables_body([V|Vs],[Mode|Modes],[Type|Types],Vars,I,FA,Body,N) :-
2155 create_indexed_variables_body(Vs,Modes,Types,Tail,J,FA,RBody,M),
2157 is_indexed_argument(FA,I) ->
2158 ( atomic_type(Type) ->
2169 Continuation = true, Tail = []
2171 Continuation = RBody
2175 Body = term_variables(V,Vars)
2177 Body = (term_variables(V,Vars,Tail),RBody)
2181 ; Mode == (-), is_indexed_argument(FA,I) ->
2185 Body = (Vars = [V|Tail],RBody)
2193 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2195 spectermvars(Specs,Args,F,A,Goal,Vars) :-
2196 spectermvars(Args,1,Specs,F,A,Vars,[],Goal).
2198 spectermvars([],B,_,_,A,L,L,true) :- B > A, !.
2199 spectermvars([Arg|Args],I,Specs,F,A,L,T,Goal) :-
2200 Goal = (ArgGoal,RGoal),
2201 argspecs(Specs,I,TempArgSpecs,RSpecs),
2202 merge_argspecs(TempArgSpecs,ArgSpecs),
2203 arggoal(ArgSpecs,Arg,ArgGoal,L,L1),
2205 spectermvars(Args,J,RSpecs,F,A,L1,T,RGoal).
2207 argspecs([],_,[],[]).
2208 argspecs([[]|Rest],I,ArgSpecs,RestSpecs) :-
2209 argspecs(Rest,I,ArgSpecs,RestSpecs).
2210 argspecs([[specinfo(J,Spec,Args)|Specs]|Rest],I,ArgSpecs,RestSpecs) :-
2212 ArgSpecs = [specinfo(J,Spec,Args)|RArgSpecs],
2214 RRestSpecs = RestSpecs
2216 RestSpecs = [Specs|RRestSpecs]
2219 ArgSpecs = RArgSpecs,
2220 RestSpecs = [[specinfo(J,Spec,Args)|Specs]|RRestSpecs]
2222 argspecs(Rest,I,RArgSpecs,RRestSpecs).
2224 merge_argspecs(In,Out) :-
2226 merge_argspecs_(Sorted,Out).
2228 merge_argspecs_([],[]).
2229 merge_argspecs_([X],R) :- !, R = [X].
2230 merge_argspecs_([specinfo(I,F1,A1),specinfo(I,F2,A2)|Rest],R) :-
2231 ( (F1 == any ; F2 == any) ->
2232 merge_argspecs_([specinfo(I,any,[])|Rest],R)
2235 merge_argspecs_([specinfo(I,F1,A)|Rest],R)
2237 R = [specinfo(I,F1,A1)|RR],
2238 merge_argspecs_([specinfo(I,F2,A2)|Rest],RR)
2241 arggoal(List,Arg,Goal,L,T) :-
2245 ; List = [specinfo(_,any,_)] ->
2246 Goal = term_variables(Arg,L,T)
2254 arggoal_cases(List,Arg,L,T,Cases)
2257 arggoal_cases([],_,L,T,L=T).
2258 arggoal_cases([specinfo(_,FA,ArgSpecs)|Rest],Arg,L,T,Cases) :-
2261 ; ArgSpecs == [[]] ->
2264 Cases = (Case ; RCases),
2267 Case = (Arg = Term -> ArgsGoal),
2268 spectermvars(Args,1,ArgSpecs,F,A,L,T,ArgsGoal)
2270 arggoal_cases(Rest,Arg,L,T,RCases).
2271 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2273 generate_extra_clauses(Constraints,List) :-
2274 generate_activate_clauses(Constraints,List,Tail0),
2275 generate_remove_clauses(Constraints,Tail0,Tail1),
2276 generate_allocate_clauses(Constraints,Tail1,Tail2),
2277 generate_insert_constraint_internal_clauses(Constraints,Tail2,Tail3),
2278 generate_novel_production(Tail3,Tail4),
2279 generate_extend_history(Tail4,Tail5),
2280 generate_run_suspensions_clauses(Constraints,Tail5,Tail6),
2281 generate_empty_named_history_initialisations(Tail6,Tail7),
2284 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2285 % remove_constraint_internal/[1/3]
2287 generate_remove_clauses([],List,List).
2288 generate_remove_clauses([C|Cs],List,Tail) :-
2289 generate_remove_clause(C,List,List1),
2290 generate_remove_clauses(Cs,List1,Tail).
2292 remove_constraint_goal(Constraint,Susp,Agenda,DeleteNo,DeleteYes,Role,Goal) :-
2293 uses_state(Constraint,removed),
2294 ( chr_pp_flag(inline_insertremove,off) ->
2295 use_auxiliary_predicate(remove_constraint_internal,Constraint),
2296 Goal = ( DeleteGoal, ( Delete == yes -> DeleteYes ; DeleteNo) ),
2297 remove_constraint_atom(Constraint,Susp,Agenda,Delete,DeleteGoal)
2299 delay_phase_end(validate_store_type_assumptions,
2300 generate_remove_body(Constraint,Susp,Agenda,DeleteNo,DeleteYes,Role,Goal)
2304 remove_constraint_atom(Constraint,Susp,Agenda,Delete,Goal) :-
2305 make_name('$remove_constraint_internal_',Constraint,Name),
2306 ( chr_pp_flag(debugable,off), ( only_ground_indexed_arguments(Constraint) ; get_store_type(Constraint,var_assoc_store(_,_)) ) ->
2307 Goal =.. [Name, Susp,Delete]
2309 Goal =.. [Name,Susp,Agenda,Delete]
2312 generate_remove_clause(Constraint,List,Tail) :-
2313 ( is_used_auxiliary_predicate(remove_constraint_internal,Constraint) ->
2314 List = [RemoveClause|Tail],
2315 RemoveClause = (Head :- RemoveBody),
2316 remove_constraint_atom(Constraint,Susp,Agenda,Delete,Head),
2317 generate_remove_body(Constraint,Susp,Agenda,Delete = no,Delete = yes,active,RemoveBody)
2322 generate_remove_body(Constraint,Susp,Agenda,DeleteNo,DeleteYes,Role,RemoveBody) :-
2323 ( chr_pp_flag(debugable,off), ( only_ground_indexed_arguments(Constraint) ; get_store_type(Constraint,var_assoc_store(_,_))) ->
2325 get_update_suspension_field(Constraint,Susp,state,State,removed,GetState,GetStateValue0,UpdateState),
2326 if_used_state(Constraint,not_stored_yet,GetStateValue0,true,GetStateValue),
2327 if_used_state(Constraint,not_stored_yet,(State == not_stored_yet -> DeleteNo ; DeleteYes),DeleteYes,MaybeDelete)
2328 ; Role == partner ->
2329 get_update_suspension_field(Constraint,Susp,state,State,removed,GetState,_,UpdateState),
2330 GetStateValue = true,
2331 MaybeDelete = DeleteYes
2341 static_suspension_term(Constraint,Susp2),
2342 get_static_suspension_term_field(arguments,Constraint,Susp2,Args),
2343 generate_indexed_variables_body(Constraint,Args,IndexedVariablesBody,Agenda),
2344 ( chr_pp_flag(debugable,on) ->
2345 Constraint = Functor / _,
2346 get_static_suspension_term_field(functor,Constraint,Susp2,Functor)
2351 get_update_static_suspension_field(Constraint,Susp,Susp2,state,State,removed,GetStateValue0,UpdateState),
2352 if_used_state(Constraint,not_stored_yet,GetStateValue0,true,GetStateValue),
2353 if_used_state(Constraint,not_stored_yet,(State == not_stored_yet -> Agenda = [], DeleteNo ; IndexedVariablesBody, DeleteYes),(IndexedVariablesBody,DeleteYes),MaybeDelete)
2354 ; Role == partner ->
2355 get_update_static_suspension_field(Constraint,Susp,Susp2,state,State,removed,_,UpdateState),
2356 GetStateValue = true,
2357 MaybeDelete = (IndexedVariablesBody, DeleteYes)
2368 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2369 % activate_constraint/4
2371 generate_activate_clauses([],List,List).
2372 generate_activate_clauses([C|Cs],List,Tail) :-
2373 generate_activate_clause(C,List,List1),
2374 generate_activate_clauses(Cs,List1,Tail).
2376 activate_constraint_goal(Constraint,StoreAction,Vars,Susp,Generation,Goal) :-
2377 ( chr_pp_flag(inline_insertremove,off) ->
2378 use_auxiliary_predicate(activate_constraint,Constraint),
2379 Goal = ( ActivateGoal , (Store == yes -> StoreAction ; true) ),
2380 activate_constraint_atom(Constraint,Store,Vars,Susp,Generation,ActivateGoal)
2382 delay_phase_end(validate_store_type_assumptions,
2383 activate_constraint_body(Constraint,StoreAction,true,Vars,Susp,Generation,Goal)
2387 activate_constraint_atom(Constraint,Store,Vars,Susp,Generation,Goal) :-
2388 make_name('$activate_constraint_',Constraint,Name),
2389 ( chr_pp_flag(debugable,off), only_ground_indexed_arguments(Constraint) ->
2390 Goal =.. [Name,Store, Susp]
2391 ; chr_pp_flag(debugable,off), may_trigger(Constraint), get_store_type(Constraint,var_assoc_store(_,_)) ->
2392 Goal =.. [Name,Store, Susp, Generation]
2393 ; chr_pp_flag(debugable,off), may_trigger(Constraint), get_store_type(Constraint,var_assoc_store(_,_)) ->
2394 Goal =.. [Name,Store, Vars, Susp, Generation]
2396 Goal =.. [Name,Store, Vars, Susp]
2399 generate_activate_clause(Constraint,List,Tail) :-
2400 ( is_used_auxiliary_predicate(activate_constraint,Constraint) ->
2401 List = [Clause|Tail],
2402 Clause = (Head :- Body),
2403 activate_constraint_atom(Constraint,Store,Vars,Susp,Generation,Head),
2404 activate_constraint_body(Constraint,Store = yes, Store = no,Vars,Susp,Generation,Body)
2409 activate_constraint_body(Constraint,StoreYes,StoreNo,Vars,Susp,Generation,Body) :-
2410 ( chr_pp_flag(debugable,off), may_trigger(Constraint), uses_field(Constraint,generation) ->
2411 get_update_suspension_field(Constraint,Susp,generation,Gen,Generation,GetGeneration,GetGenerationValue,UpdateGeneration),
2412 GenerationHandling = (GetGeneration, GetGenerationValue, Generation is Gen+1, UpdateGeneration)
2414 GenerationHandling = true
2416 get_update_suspension_field(Constraint,Susp,state,State,active,GetState,GetStateValue0,UpdateState),
2417 if_used_state(Constraint,not_stored_yet,GetStateValue0,true,GetStateValue),
2418 ( chr_pp_flag(debugable,off), ( only_ground_indexed_arguments(Constraint) ; get_store_type(Constraint,var_assoc_store(_,_))) ->
2419 if_used_state(Constraint,not_stored_yet,( State == not_stored_yet -> StoreYes ; StoreNo ),StoreNo,StoreVarsGoal)
2421 get_dynamic_suspension_term_field(arguments,Constraint,Susp,Arguments,ArgumentsGoal),
2422 generate_indexed_variables_body(Constraint,Arguments,IndexedVariablesBody,Vars),
2423 chr_none_locked(Vars,NoneLocked),
2424 if_used_state(Constraint,not_stored_yet,
2425 ( State == not_stored_yet ->
2427 IndexedVariablesBody,
2434 % (Vars = [],StoreNo),StoreVarsGoal)
2435 StoreNo,StoreVarsGoal)
2445 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2446 % allocate_constraint/4
2448 generate_allocate_clauses([],List,List).
2449 generate_allocate_clauses([C|Cs],List,Tail) :-
2450 generate_allocate_clause(C,List,List1),
2451 generate_allocate_clauses(Cs,List1,Tail).
2453 allocate_constraint_goal(Constraint,Susp,Args,Goal) :-
2454 uses_state(Constraint,not_stored_yet),
2455 ( chr_pp_flag(inline_insertremove,off) ->
2456 use_auxiliary_predicate(allocate_constraint,Constraint),
2457 allocate_constraint_atom(Constraint,Susp,Args,Goal)
2459 Goal = (Susp = Suspension, Goal0),
2460 delay_phase_end(validate_store_type_assumptions,
2461 allocate_constraint_body(Constraint,Suspension,Args,Goal0)
2465 allocate_constraint_atom(Constraint, Susp, Args,Goal) :-
2466 make_name('$allocate_constraint_',Constraint,Name),
2467 Goal =.. [Name,Susp|Args].
2469 generate_allocate_clause(Constraint,List,Tail) :-
2470 ( is_used_auxiliary_predicate(allocate_constraint,Constraint) ->
2471 List = [Clause|Tail],
2472 Clause = (Head :- Body),
2475 allocate_constraint_atom(Constraint,Susp,Args,Head),
2476 allocate_constraint_body(Constraint,Susp,Args,Body)
2481 allocate_constraint_body(Constraint,Susp,Args,Body) :-
2482 static_suspension_term(Constraint,Suspension),
2483 get_static_suspension_term_field(arguments,Constraint,Suspension,Args),
2484 ( chr_pp_flag(debugable,on) ->
2485 Constraint = Functor / _,
2486 get_static_suspension_term_field(functor,Constraint,Suspension,Functor)
2490 ( chr_pp_flag(debugable,on) ->
2491 ( may_trigger(Constraint) ->
2492 append(Args,[Susp],VarsSusp),
2493 build_head(F,A,[0],VarsSusp, ContinuationGoal),
2494 get_target_module(Mod),
2495 Continuation = Mod : ContinuationGoal
2499 Init = (Susp = Suspension),
2500 create_static_suspension_field(Constraint,Suspension,continuation,Continuation,CreateContinuation),
2501 create_static_suspension_field(Constraint,Suspension,generation,0,CreateGeneration)
2502 ; may_trigger(Constraint), uses_field(Constraint,generation) ->
2503 create_static_suspension_field(Constraint,Suspension,generation,0,CreateGeneration),
2504 Susp = Suspension, Init = true, CreateContinuation = true
2506 CreateGeneration = true, Susp = Suspension, Init = true, CreateContinuation = true
2508 ( uses_history(Constraint) ->
2509 create_static_suspension_field(Constraint,Suspension,history,t,CreateHistory)
2511 CreateHistory = true
2513 create_static_suspension_field(Constraint,Suspension,state,not_stored_yet,CreateState),
2514 ( has_suspension_field(Constraint,id) ->
2515 get_static_suspension_term_field(id,Constraint,Suspension,Id),
2530 gen_id(Id,'chr gen_id'(Id)).
2531 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2532 % insert_constraint_internal
2534 generate_insert_constraint_internal_clauses([],List,List).
2535 generate_insert_constraint_internal_clauses([C|Cs],List,Tail) :-
2536 generate_insert_constraint_internal_clause(C,List,List1),
2537 generate_insert_constraint_internal_clauses(Cs,List1,Tail).
2539 insert_constraint_internal_constraint_goal(Constraint, Vars, Suspension, Continuation, Args,Goal) :-
2540 ( chr_pp_flag(inline_insertremove,off) ->
2541 use_auxiliary_predicate(remove_constraint_internal,Constraint),
2542 insert_constraint_internal_constraint_atom(Constraint,Vars,Suspension,Continuation,Args,Goal)
2544 delay_phase_end(validate_store_type_assumptions,
2545 generate_insert_constraint_internal_body(Constraint,Suspension,Continuation,Args,Vars,Goal)
2550 insert_constraint_internal_constraint_atom(Constraint,Vars,Self,Closure,Args,Goal) :-
2551 insert_constraint_internal_constraint_name(Constraint,Name),
2552 ( chr_pp_flag(debugable,on) ->
2553 Goal =.. [Name, Vars, Self, Closure | Args]
2554 ; ( only_ground_indexed_arguments(Constraint) ; get_store_type(Constraint,var_assoc_store(_,_)))->
2555 Goal =.. [Name,Self | Args]
2557 Goal =.. [Name,Vars, Self | Args]
2560 insert_constraint_internal_constraint_name(Constraint,Name) :-
2561 make_name('$insert_constraint_internal_',Constraint,Name).
2563 generate_insert_constraint_internal_clause(Constraint,List,Tail) :-
2564 ( is_used_auxiliary_predicate(insert_constraint_internal,Constraint) ->
2565 List = [Clause|Tail],
2566 Clause = (Head :- Body),
2569 insert_constraint_internal_constraint_atom(Constraint, Vars, Suspension, Continuation,Args,Head),
2570 generate_insert_constraint_internal_body(Constraint,Suspension,Continuation,Args,Vars,Body)
2576 generate_insert_constraint_internal_body(Constraint,Susp,Continuation,Args,Vars,Body) :-
2577 static_suspension_term(Constraint,Suspension),
2578 create_static_suspension_field(Constraint,Suspension,state,active,CreateState),
2579 ( chr_pp_flag(debugable,on) ->
2580 get_static_suspension_term_field(continuation,Constraint,Suspension,Continuation),
2581 create_static_suspension_field(Constraint,Suspension,generation,0,CreateGeneration)
2582 ; may_trigger(Constraint), uses_field(Constraint,generation) ->
2583 create_static_suspension_field(Constraint,Suspension,generation,0,CreateGeneration)
2585 CreateGeneration = true
2587 ( chr_pp_flag(debugable,on) ->
2588 Constraint = Functor / _,
2589 get_static_suspension_term_field(functor,Constraint,Suspension,Functor)
2593 ( uses_history(Constraint) ->
2594 create_static_suspension_field(Constraint,Suspension,history,t,CreateHistory)
2596 CreateHistory = true
2598 get_static_suspension_term_field(arguments,Constraint,Suspension,Args),
2599 List = [Clause|Tail],
2600 ( chr_pp_flag(debugable,off), ( only_ground_indexed_arguments(Constraint) ; get_store_type(Constraint,var_assoc_store(_,_)))->
2601 suspension_term_base_fields(Constraint,BaseFields),
2602 ( has_suspension_field(Constraint,id) ->
2603 get_static_suspension_term_field(id,Constraint,Suspension,Id),
2617 ( has_suspension_field(Constraint,id) ->
2618 get_static_suspension_term_field(id,Constraint,Suspension,Id),
2623 generate_indexed_variables_body(Constraint,Args,IndexedVariablesBody,Vars),
2624 chr_none_locked(Vars,NoneLocked),
2628 IndexedVariablesBody,
2637 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2638 % novel_production/2
2640 generate_novel_production(List,Tail) :-
2641 ( is_used_auxiliary_predicate(novel_production) ->
2642 List = [Clause|Tail],
2645 '$novel_production'( Self, Tuple) :-
2646 % arg( 3, Self, Ref), % ARGXXX
2647 % 'chr get_mutable'( History, Ref),
2648 arg( 3, Self, History), % ARGXXX
2649 ( hprolog:get_ds( Tuple, History, _) ->
2659 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2662 generate_extend_history(List,Tail) :-
2663 ( is_used_auxiliary_predicate(extend_history) ->
2664 List = [Clause|Tail],
2667 '$extend_history'( Self, Tuple) :-
2668 % arg( 3, Self, Ref), % ARGXXX
2669 % 'chr get_mutable'( History, Ref),
2670 arg( 3, Self, History), % ARGXXX
2671 hprolog:put_ds( Tuple, History, x, NewHistory),
2672 setarg( 3, Self, NewHistory) % ARGXXX
2678 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2681 empty_named_history_initialisations/2,
2682 generate_empty_named_history_initialisation/1,
2683 find_empty_named_histories/0.
2685 generate_empty_named_history_initialisations(List, Tail) :-
2686 empty_named_history_initialisations(List, Tail),
2687 find_empty_named_histories.
2689 find_empty_named_histories, history(_, Name, []) ==>
2690 generate_empty_named_history_initialisation(Name).
2692 generate_empty_named_history_initialisation(Name) \
2693 generate_empty_named_history_initialisation(Name) <=> true.
2694 generate_empty_named_history_initialisation(Name) \
2695 empty_named_history_initialisations(List, Tail) # Passive
2697 empty_named_history_global_variable(Name, GlobalVariable),
2698 List = [(:- nb_setval(GlobalVariable, 0))|Rest],
2699 empty_named_history_initialisations(Rest, Tail)
2700 pragma passive(Passive).
2702 find_empty_named_histories \
2703 generate_empty_named_history_initialisation(_) # Passive <=> true
2704 pragma passive(Passive).
2706 find_empty_named_histories,
2707 empty_named_history_initialisations(List, Tail) # Passive <=> List = Tail
2708 pragma passive(Passive).
2710 find_empty_named_histories <=>
2711 chr_error(internal, 'find_empty_named_histories was not removed', []).
2714 empty_named_history_global_variable(Name, GlobalVariable) :-
2715 atom_concat('chr empty named history ', Name, GlobalVariable).
2717 empty_named_history_novel_production(Name, nb_getval(GlobalVariable, 0)) :-
2718 empty_named_history_global_variable(Name, GlobalVariable).
2720 empty_named_history_extend_history(Name, b_setval(GlobalVariable, 1)) :-
2721 empty_named_history_global_variable(Name, GlobalVariable).
2724 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2727 generate_run_suspensions_clauses([],List,List).
2728 generate_run_suspensions_clauses([C|Cs],List,Tail) :-
2729 generate_run_suspensions_clause(C,List,List1),
2730 generate_run_suspensions_clauses(Cs,List1,Tail).
2732 run_suspensions_goal(Constraint,Suspensions,Goal) :-
2733 make_name('$run_suspensions_',Constraint,Name),
2734 Goal =.. [Name,Suspensions].
2736 generate_run_suspensions_clause(Constraint,List,Tail) :-
2737 ( is_used_auxiliary_predicate(run_suspensions,Constraint) ->
2738 List = [Clause1,Clause2|Tail],
2739 run_suspensions_goal(Constraint,[],Clause1),
2740 ( chr_pp_flag(debugable,on) ->
2741 run_suspensions_goal(Constraint,[Suspension|Suspensions],Clause2Head),
2742 get_update_suspension_field(Constraint,Suspension,state,State,triggered,GetState,GetStateValue,UpdateState),
2743 get_update_suspension_field(Constraint,Suspension,state,Post,active,GetPost,GetPostValue,UpdatePost),
2744 get_update_suspension_field(Constraint,Suspension,generation,Gen,Generation,GetGeneration,GetGenerationValue,UpdateGeneration),
2745 get_dynamic_suspension_term_field(continuation,Constraint,Suspension,Continuation,GetContinuation),
2746 run_suspensions_goal(Constraint,Suspensions,Clause2Recursion),
2756 Generation is Gen+1,
2760 'chr debug_event'(wake(Suspension)),
2763 'chr debug_event'(fail(Suspension)), !,
2767 'chr debug_event'(exit(Suspension))
2769 'chr debug_event'(redo(Suspension)),
2774 ( Post==triggered ->
2775 UpdatePost % catching constraints that did not do anything
2785 run_suspensions_goal(Constraint,[Suspension|Suspensions],Clause2Head),
2786 static_suspension_term(Constraint,SuspensionTerm),
2787 get_static_suspension_term_field(arguments,Constraint,SuspensionTerm,Arguments),
2788 append(Arguments,[Suspension],VarsSusp),
2789 make_suspension_continuation_goal(Constraint,VarsSusp,Continuation),
2790 run_suspensions_goal(Constraint,Suspensions,Clause2Recursion),
2791 ( uses_field(Constraint,generation) ->
2792 get_update_static_suspension_field(Constraint,Suspension,SuspensionTerm,generation,Gen,Generation,GetGeneration,UpdateGeneration),
2793 GenerationHandling = ( GetGeneration, Generation is Gen+1, UpdateGeneration)
2795 GenerationHandling = true
2797 get_update_static_suspension_field(Constraint,Suspension,SuspensionTerm,state,State,triggered,GetState,UpdateState),
2798 get_update_static_suspension_field(Constraint,Suspension,SuspensionTerm,state,Post,active,GetPostState,UpdatePostState),
2799 if_used_state(Constraint,removed,
2802 -> ReactivateConstraint
2804 ),ReactivateConstraint,CondReactivate),
2805 ReactivateConstraint =
2811 ( Post==triggered ->
2812 UpdatePostState % catching constraints that did not do anything
2820 Suspension = SuspensionTerm,
2829 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2831 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2832 generate_attach_increment(Clauses) :-
2833 get_max_constraint_index(N),
2834 ( is_used_auxiliary_predicate(attach_increment), N > 0 ->
2835 Clauses = [Clause1,Clause2],
2836 generate_attach_increment_empty(Clause1),
2838 generate_attach_increment_one(Clause2)
2840 generate_attach_increment_many(N,Clause2)
2846 generate_attach_increment_empty((attach_increment([],_) :- true)).
2848 generate_attach_increment_one(Clause) :-
2849 Head = attach_increment([Var|Vars],Susps),
2850 get_target_module(Mod),
2851 chr_not_locked(Var,NotLocked),
2855 ( get_attr(Var,Mod,VarSusps) ->
2856 sort(VarSusps,SortedVarSusps),
2857 'chr merge_attributes'(Susps,SortedVarSusps,MergedSusps),
2858 put_attr(Var,Mod,MergedSusps)
2860 put_attr(Var,Mod,Susps)
2862 attach_increment(Vars,Susps)
2864 Clause = (Head :- Body).
2866 generate_attach_increment_many(N,Clause) :-
2867 Head = attach_increment([Var|Vars],TAttr1),
2868 % writeln(merge_attributes_1_before),
2869 merge_attributes(N,TAttr1,TAttr2,MergeGoal,Attr),
2870 % writeln(merge_attributes_1_after),
2871 get_target_module(Mod),
2872 chr_not_locked(Var,NotLocked),
2876 ( get_attr(Var,Mod,TAttr2) ->
2878 put_attr(Var,Mod,Attr)
2880 put_attr(Var,Mod,TAttr1)
2882 attach_increment(Vars,TAttr1)
2884 Clause = (Head :- Body).
2887 generate_attr_unify_hook(Clauses) :-
2888 get_max_constraint_index(N),
2892 Clauses = [GoalsClause|HookClauses],
2893 GoalsClause = attribute_goals(_,Goals,Goals),
2895 generate_attr_unify_hook_one(HookClauses)
2897 generate_attr_unify_hook_many(N,HookClauses)
2901 generate_attr_unify_hook_one([Clause]) :-
2902 Head = attr_unify_hook(Susps,Other),
2903 get_target_module(Mod),
2904 get_indexed_constraint(1,C),
2905 ( get_store_type(C,ST),
2906 ( ST = default ; ST = multi_store(STs), memberchk(default,STs) ) ->
2907 make_run_suspensions(NewSusps,SortedSusps,WakeNewSusps),
2908 make_run_suspensions(SortedSusps,SortedSusps,WakeSusps),
2909 ( atomic_types_suspended_constraint(C) ->
2911 SortedSusps = Susps,
2913 SortedOtherSusps = OtherSusps,
2914 MergeGoal = (append(Susps,OtherSusps,List), sort(List,NewSusps)),
2917 SortGoal1 = sort(Susps, SortedSusps),
2918 SortGoal2 = sort(OtherSusps,SortedOtherSusps),
2919 MergeGoal = 'chr merge_attributes'(SortedSusps,SortedOtherSusps,NewSusps),
2920 use_auxiliary_predicate(attach_increment),
2922 ( compound(Other) ->
2923 term_variables(Other,OtherVars),
2924 attach_increment(OtherVars, SortedSusps)
2933 ( get_attr(Other,Mod,OtherSusps) ->
2936 put_attr(Other,Mod,NewSusps),
2939 put_attr(Other,Mod,SortedSusps),
2947 Clause = (Head :- Body)
2948 ; get_store_type(C,var_assoc_store(VarIndex,KeyIndex)) ->
2949 make_run_suspensions(List,List,WakeNewSusps),
2950 MergeGoal = (merge_into_assoc_store(Susps,OtherSusps,List)),
2952 ( get_attr(Other,Mod,OtherSusps) ->
2956 put_attr(Other,Mod,Susps)
2958 Clause = (Head :- Body)
2962 generate_attr_unify_hook_many(N,[Clause]) :-
2963 chr_pp_flag(dynattr,off), !,
2964 Head = attr_unify_hook(Attr,Other),
2965 get_target_module(Mod),
2966 make_attr(N,Mask,SuspsList,Attr),
2967 bagof(Sort,A ^ B ^ ( member(A,SuspsList) , Sort = sort(A,B) ) , SortGoalList),
2968 list2conj(SortGoalList,SortGoals),
2969 bagof(B, A ^ member(sort(A,B),SortGoalList), SortedSuspsList),
2970 merge_attributes2(N,Mask,SortedSuspsList,TOtherAttr,MergeGoal,MergedAttr),
2971 get_all_suspensions2(N,MergedAttr,MergedSuspsList),
2972 make_attr(N,Mask,SortedSuspsList,SortedAttr),
2973 make_run_suspensions_loop(MergedSuspsList,SortedSuspsList,WakeMergedSusps),
2974 make_run_suspensions_loop(SortedSuspsList,SortedSuspsList,WakeSortedSusps),
2975 ( forall((between(1,N,Index), get_indexed_constraint(Index,Constraint)),atomic_types_suspended_constraint(Constraint)) ->
2978 use_auxiliary_predicate(attach_increment),
2980 ( compound(Other) ->
2981 term_variables(Other,OtherVars),
2982 attach_increment(OtherVars,SortedAttr)
2991 ( get_attr(Other,Mod,TOtherAttr) ->
2993 put_attr(Other,Mod,MergedAttr),
2996 put_attr(Other,Mod,SortedAttr),
3004 Clause = (Head :- Body).
3007 generate_attr_unify_hook_many(N,Clauses) :-
3008 Head = attr_unify_hook(Attr,Other),
3009 get_target_module(Mod),
3010 normalize_attr(Attr,NormalGoal,NormalAttr),
3011 normalize_attr(OtherAttr,NormalOtherGoal,NormalOtherAttr),
3012 merge_attributes(N,NormalAttr,NormalOtherAttr,MergeGoal,MergedAttr),
3013 make_run_suspensions(N),
3014 ( forall((between(1,N,Index), get_indexed_constraint(Index,Constraint)),atomic_types_suspended_constraint(Constraint)) ->
3017 use_auxiliary_predicate(attach_increment),
3019 ( compound(Other) ->
3020 term_variables(Other,OtherVars),
3021 attach_increment(OtherVars,NormalAttr)
3030 ( get_attr(Other,Mod,OtherAttr) ->
3033 put_attr(Other,Mod,MergedAttr),
3034 '$dispatch_run_suspensions'(MergedAttr)
3036 put_attr(Other,Mod,NormalAttr),
3037 '$dispatch_run_suspensions'(NormalAttr)
3041 '$dispatch_run_suspensions'(NormalAttr)
3044 Clause = (Head :- Body),
3045 Clauses = [Clause,DispatchList1,DispatchList2|Dispatchers],
3046 DispatchList1 = ('$dispatch_run_suspensions'([])),
3047 DispatchList2 = ('$dispatch_run_suspensions'([Pos-List|Rest]) :- '$dispatch_run_suspensions'(Pos,List),'$dispatch_run_suspensions'(Rest)),
3048 run_suspensions_dispatchers(N,[],Dispatchers).
3051 run_suspensions_dispatchers(N,Acc,Dispatchers) :-
3053 get_indexed_constraint(N,C),
3054 NAcc = [('$dispatch_run_suspensions'(N,List) :- Body)|Acc],
3056 run_suspensions_goal(C,List,Body)
3061 run_suspensions_dispatchers(M,NAcc,Dispatchers)
3067 make_run_suspensions(N) :-
3069 ( get_indexed_constraint(N,C),
3071 use_auxiliary_predicate(run_suspensions,C)
3076 make_run_suspensions(M)
3081 make_run_suspensions(AllSusps,OneSusps,Goal) :-
3082 make_run_suspensions(1,AllSusps,OneSusps,Goal).
3084 make_run_suspensions(Index,AllSusps,OneSusps,Goal) :-
3085 ( get_indexed_constraint(Index,C), may_trigger(C) ->
3086 use_auxiliary_predicate(run_suspensions,C),
3087 ( wakes_partially(C) ->
3088 run_suspensions_goal(C,OneSusps,Goal)
3090 run_suspensions_goal(C,AllSusps,Goal)
3096 make_run_suspensions_loop(AllSuspsList,OneSuspsList,Goal) :-
3097 make_run_suspensions_loop(AllSuspsList,OneSuspsList,1,Goal).
3099 make_run_suspensions_loop([],[],_,true).
3100 make_run_suspensions_loop([AllSusps|AllSuspsList],[OneSusps|OneSuspsList],I,(Goal,Goals)) :-
3101 make_run_suspensions(I,AllSusps,OneSusps,Goal),
3103 make_run_suspensions_loop(AllSuspsList,OneSuspsList,J,Goals).
3105 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3106 % $insert_in_store_F/A
3107 % $delete_from_store_F/A
3109 generate_insert_delete_constraints([],[]).
3110 generate_insert_delete_constraints([FA|Rest],Clauses) :-
3112 generate_insert_delete_constraint(FA,Clauses,RestClauses)
3114 Clauses = RestClauses
3116 generate_insert_delete_constraints(Rest,RestClauses).
3118 generate_insert_delete_constraint(FA,Clauses,RestClauses) :-
3119 insert_constraint_clause(FA,Clauses,RestClauses1),
3120 delete_constraint_clause(FA,RestClauses1,RestClauses).
3122 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3125 insert_constraint_goal(FA,Susp,Vars,Goal) :-
3126 ( chr_pp_flag(inline_insertremove,off) ->
3127 use_auxiliary_predicate(insert_in_store,FA),
3128 insert_constraint_atom(FA,Susp,Goal)
3130 delay_phase_end(validate_store_type_assumptions,
3131 ( insert_constraint_body(FA,Susp,UsedVars,Goal),
3132 insert_constraint_direct_used_vars(UsedVars,Vars)
3137 insert_constraint_direct_used_vars([],_).
3138 insert_constraint_direct_used_vars([Index-Var|Rest],Vars) :-
3139 nth1(Index,Vars,Var),
3140 insert_constraint_direct_used_vars(Rest,Vars).
3142 insert_constraint_atom(FA,Susp,Call) :-
3143 make_name('$insert_in_store_',FA,Functor),
3144 Call =.. [Functor,Susp].
3146 insert_constraint_clause(C,Clauses,RestClauses) :-
3147 ( is_used_auxiliary_predicate(insert_in_store,C) ->
3148 Clauses = [Clause|RestClauses],
3149 Clause = (Head :- InsertCounterInc,VarsBody,Body),
3150 insert_constraint_atom(C,Susp,Head),
3151 insert_constraint_body(C,Susp,UsedVars,Body),
3152 insert_constraint_used_vars(UsedVars,C,Susp,VarsBody),
3153 ( chr_pp_flag(store_counter,on) ->
3154 InsertCounterInc = '$insert_counter_inc'
3156 InsertCounterInc = true
3159 Clauses = RestClauses
3162 insert_constraint_used_vars([],_,_,true).
3163 insert_constraint_used_vars([Index-Var|Rest],C,Susp,(Goal,Goals)) :-
3164 get_dynamic_suspension_term_field(argument(Index),C,Susp,Var,Goal),
3165 insert_constraint_used_vars(Rest,C,Susp,Goals).
3167 insert_constraint_body(C,Susp,UsedVars,Body) :-
3168 get_store_type(C,StoreType),
3169 insert_constraint_body(StoreType,C,Susp,UsedVars,Body).
3171 insert_constraint_body(default,C,Susp,[],Body) :-
3172 global_list_store_name(C,StoreName),
3173 make_get_store_goal(StoreName,Store,GetStoreGoal),
3174 make_update_store_goal(StoreName,Cell,UpdateStoreGoal),
3175 ( chr_pp_flag(debugable,on) ->
3176 Cell = [Susp|Store],
3183 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,Cell,SetGoal),
3187 Cell = [Susp|Store],
3189 ( Store = [NextSusp|_] ->
3196 % get_target_module(Mod),
3197 % get_max_constraint_index(Total),
3199 % generate_attach_body_1(C,Store,Susp,AttachBody)
3201 % generate_attach_body_n(C,Store,Susp,AttachBody)
3205 % 'chr default_store'(Store),
3208 insert_constraint_body(multi_inthash(Indexes),C,Susp,[],Body) :-
3209 generate_multi_inthash_insert_constraint_bodies(Indexes,C,Susp,Body).
3210 insert_constraint_body(multi_hash(Indexes),C,Susp,MixedUsedVars,Body) :-
3211 generate_multi_hash_insert_constraint_bodies(Indexes,C,Susp,Body,MixedUsedVars),
3212 sort_out_used_vars(MixedUsedVars,UsedVars).
3213 insert_constraint_body(atomic_constants(Index,_,_),C,Susp,UsedVars,Body) :-
3214 multi_hash_key_direct(C,Index,Susp,Key,UsedVars),
3215 constants_store_index_name(C,Index,IndexName),
3216 IndexLookup =.. [IndexName,Key,StoreName],
3219 nb_getval(StoreName,Store),
3220 b_setval(StoreName,[Susp|Store])
3224 insert_constraint_body(ground_constants(Index,_,_),C,Susp,UsedVars,Body) :-
3225 multi_hash_key_direct(C,Index,Susp,Key,UsedVars),
3226 constants_store_index_name(C,Index,IndexName),
3227 IndexLookup =.. [IndexName,Key,StoreName],
3230 nb_getval(StoreName,Store),
3231 b_setval(StoreName,[Susp|Store])
3235 insert_constraint_body(global_ground,C,Susp,[],Body) :-
3236 global_ground_store_name(C,StoreName),
3237 make_get_store_goal(StoreName,Store,GetStoreGoal),
3238 make_update_store_goal(StoreName,Cell,UpdateStoreGoal),
3239 ( chr_pp_flag(debugable,on) ->
3240 Cell = [Susp|Store],
3247 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,Cell,SetGoal),
3251 Cell = [Susp|Store],
3253 ( Store = [NextSusp|_] ->
3260 % global_ground_store_name(C,StoreName),
3261 % make_get_store_goal(StoreName,Store,GetStoreGoal),
3262 % make_update_store_goal(StoreName,[Susp|Store],UpdateStoreGoal),
3265 % GetStoreGoal, % nb_getval(StoreName,Store),
3266 % UpdateStoreGoal % b_setval(StoreName,[Susp|Store])
3268 insert_constraint_body(var_assoc_store(VarIndex,AssocIndex),C,Susp,[VarIndex-Variable,AssocIndex-Key],Body) :-
3269 % TODO: generalize to more than one !!!
3270 get_target_module(Module),
3271 Body = ( get_attr(Variable,Module,AssocStore) ->
3272 insert_assoc_store(AssocStore,Key,Susp)
3274 new_assoc_store(AssocStore),
3275 put_attr(Variable,Module,AssocStore),
3276 insert_assoc_store(AssocStore,Key,Susp)
3279 insert_constraint_body(global_singleton,C,Susp,[],Body) :-
3280 global_singleton_store_name(C,StoreName),
3281 make_update_store_goal(StoreName,Susp,UpdateStoreGoal),
3286 insert_constraint_body(multi_store(StoreTypes),C,Susp,UsedVars,Body) :-
3287 maplist(insert_constraint_body1(C,Susp),StoreTypes,NestedUsedVars,Bodies),
3288 list2conj(Bodies,Body),
3289 sort_out_used_vars(NestedUsedVars,UsedVars).
3290 insert_constraint_body1(C,Susp,StoreType,UsedVars,Body) :-
3291 insert_constraint_body(StoreType,C,Susp,UsedVars,Body).
3292 insert_constraint_body(identifier_store(Index),C,Susp,UsedVars,Body) :-
3293 UsedVars = [Index-Var],
3294 get_identifier_size(ISize),
3295 functor(Struct,struct,ISize),
3296 get_identifier_index(C,Index,IIndex),
3297 arg(IIndex,Struct,Susps),
3298 Body = (Var = Struct, setarg(IIndex,Var,[Susp|Susps])).
3299 insert_constraint_body(type_indexed_identifier_store(Index,IndexType),C,Susp,UsedVars,Body) :-
3300 UsedVars = [Index-Var],
3301 type_indexed_identifier_structure(IndexType,Struct),
3302 get_type_indexed_identifier_index(IndexType,C,Index,IIndex),
3303 arg(IIndex,Struct,Susps),
3304 Body = (Var = Struct, setarg(IIndex,Var,[Susp|Susps])).
3306 sort_out_used_vars(NestedUsedVars,UsedVars) :-
3307 flatten(NestedUsedVars,FlatUsedVars),
3308 sort(FlatUsedVars,SortedFlatUsedVars),
3309 sort_out_used_vars1(SortedFlatUsedVars,UsedVars).
3311 sort_out_used_vars1([],[]).
3312 sort_out_used_vars1([I-V],L) :- !, L = [I-V].
3313 sort_out_used_vars1([I-X,J-Y|R],L) :-
3316 sort_out_used_vars1([I-X|R],L)
3319 sort_out_used_vars1([J-Y|R],T)
3322 generate_multi_inthash_insert_constraint_bodies([],_,_,true).
3323 generate_multi_inthash_insert_constraint_bodies([Index|Indexes],FA,Susp,(Body,Bodies)) :-
3324 multi_hash_store_name(FA,Index,StoreName),
3325 multi_hash_key(FA,Index,Susp,KeyBody,Key),
3329 nb_getval(StoreName,Store),
3330 insert_iht(Store,Key,Susp)
3332 generate_multi_inthash_insert_constraint_bodies(Indexes,FA,Susp,Bodies).
3334 generate_multi_hash_insert_constraint_bodies([],_,_,true,[]).
3335 generate_multi_hash_insert_constraint_bodies([Index|Indexes],FA,Susp,(Body,Bodies),[UsedVars|MoreUsedVars]) :-
3336 multi_hash_store_name(FA,Index,StoreName),
3337 multi_hash_key_direct(FA,Index,Susp,Key,UsedVars),
3338 make_get_store_goal(StoreName,Store,GetStoreGoal),
3339 ( chr_pp_flag(ht_removal,on)
3340 -> ht_prev_field(Index,PrevField),
3341 set_dynamic_suspension_term_field(PrevField,FA,NextSusp,Result,
3346 insert_ht(Store,Key,Susp,Result),
3347 ( Result = [_,NextSusp|_]
3355 insert_ht(Store,Key,Susp)
3358 generate_multi_hash_insert_constraint_bodies(Indexes,FA,Susp,Bodies,MoreUsedVars).
3360 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3363 delete_constraint_clause(C,Clauses,RestClauses) :-
3364 ( is_used_auxiliary_predicate(delete_from_store,C) ->
3365 Clauses = [Clause|RestClauses],
3366 Clause = (Head :- Body),
3367 delete_constraint_atom(C,Susp,Head),
3370 delete_constraint_body(C,Head,Susp,[],Body)
3372 Clauses = RestClauses
3375 delete_constraint_goal(Head,Susp,VarDict,Goal) :-
3378 ( chr_pp_flag(inline_insertremove,off) ->
3379 use_auxiliary_predicate(delete_from_store,C),
3380 delete_constraint_atom(C,Susp,Goal)
3382 delay_phase_end(validate_store_type_assumptions, delete_constraint_body(C,Head,Susp,VarDict,Goal))
3385 delete_constraint_atom(C,Susp,Atom) :-
3386 make_name('$delete_from_store_',C,Functor),
3387 Atom =.. [Functor,Susp].
3390 delete_constraint_body(C,Head,Susp,VarDict,Body) :-
3391 Body = (CounterBody,DeleteBody),
3392 ( chr_pp_flag(store_counter,on) ->
3393 CounterBody = '$delete_counter_inc'
3397 get_store_type(C,StoreType),
3398 delete_constraint_body(StoreType,C,Head,Susp,VarDict,DeleteBody).
3400 delete_constraint_body(default,C,_,Susp,_,Body) :-
3401 ( chr_pp_flag(debugable,on) ->
3402 global_list_store_name(C,StoreName),
3403 make_get_store_goal(StoreName,Store,GetStoreGoal),
3404 make_update_store_goal(StoreName,NStore,UpdateStoreGoal),
3407 GetStoreGoal, % nb_getval(StoreName,Store),
3408 'chr sbag_del_element'(Store,Susp,NStore),
3409 UpdateStoreGoal % b_setval(StoreName,NStore)
3412 get_dynamic_suspension_term_field(global_list_prev,C,Susp,PredCell,GetGoal),
3413 global_list_store_name(C,StoreName),
3414 make_get_store_goal(StoreName,Store,GetStoreGoal),
3415 make_update_store_goal(StoreName,Tail,UpdateStoreGoal),
3416 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,_,SetGoal1),
3417 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,PredCell,SetGoal2),
3422 GetStoreGoal, % nb_getval(StoreName,Store),
3425 ( Tail = [NextSusp|_] ->
3431 PredCell = [_,_|Tail],
3432 setarg(2,PredCell,Tail),
3433 ( Tail = [NextSusp|_] ->
3441 % get_target_module(Mod),
3442 % get_max_constraint_index(Total),
3444 % generate_detach_body_1(C,Store,Susp,DetachBody),
3447 % 'chr default_store'(Store),
3451 % generate_detach_body_n(C,Store,Susp,DetachBody),
3454 % 'chr default_store'(Store),
3458 delete_constraint_body(multi_inthash(Indexes),C,_,Susp,_,Body) :-
3459 generate_multi_inthash_delete_constraint_bodies(Indexes,C,Susp,Body).
3460 delete_constraint_body(multi_hash(Indexes),C,Head,Susp,VarDict,Body) :-
3461 generate_multi_hash_delete_constraint_bodies(Indexes,C,Head,Susp,VarDict,Body).
3462 delete_constraint_body(atomic_constants(Index,_,_),C,Head,Susp,VarDict,Body) :-
3463 multi_hash_key(C,Head,Index,Susp,VarDict,KeyBody,Key),
3464 constants_store_index_name(C,Index,IndexName),
3465 IndexLookup =.. [IndexName,Key,StoreName],
3469 nb_getval(StoreName,Store),
3470 'chr sbag_del_element'(Store,Susp,NStore),
3471 b_setval(StoreName,NStore)
3475 delete_constraint_body(ground_constants(Index,_,_),C,Head,Susp,VarDict,Body) :-
3476 multi_hash_key(C,Head,Index,Susp,VarDict,KeyBody,Key),
3477 constants_store_index_name(C,Index,IndexName),
3478 IndexLookup =.. [IndexName,Key,StoreName],
3482 nb_getval(StoreName,Store),
3483 'chr sbag_del_element'(Store,Susp,NStore),
3484 b_setval(StoreName,NStore)
3488 delete_constraint_body(global_ground,C,_,Susp,_,Body) :-
3489 ( chr_pp_flag(debugable,on) ->
3490 global_ground_store_name(C,StoreName),
3491 make_get_store_goal(StoreName,Store,GetStoreGoal),
3492 make_update_store_goal(StoreName,NStore,UpdateStoreGoal),
3495 GetStoreGoal, % nb_getval(StoreName,Store),
3496 'chr sbag_del_element'(Store,Susp,NStore),
3497 UpdateStoreGoal % b_setval(StoreName,NStore)
3500 get_dynamic_suspension_term_field(global_list_prev,C,Susp,PredCell,GetGoal),
3501 global_ground_store_name(C,StoreName),
3502 make_get_store_goal(StoreName,Store,GetStoreGoal),
3503 make_update_store_goal(StoreName,Tail,UpdateStoreGoal),
3504 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,_,SetGoal1),
3505 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,PredCell,SetGoal2),
3510 GetStoreGoal, % nb_getval(StoreName,Store),
3513 ( Tail = [NextSusp|_] ->
3519 PredCell = [_,_|Tail],
3520 setarg(2,PredCell,Tail),
3521 ( Tail = [NextSusp|_] ->
3529 % global_ground_store_name(C,StoreName),
3530 % make_get_store_goal(StoreName,Store,GetStoreGoal),
3531 % make_update_store_goal(StoreName,NStore,UpdateStoreGoal),
3534 % GetStoreGoal, % nb_getval(StoreName,Store),
3535 % 'chr sbag_del_element'(Store,Susp,NStore),
3536 % UpdateStoreGoal % b_setval(StoreName,NStore)
3538 delete_constraint_body(var_assoc_store(VarIndex,AssocIndex),C,_,Susp,_,Body) :-
3539 get_target_module(Module),
3540 get_dynamic_suspension_term_field(argument(VarIndex),C,Susp,Variable,VariableGoal),
3541 get_dynamic_suspension_term_field(argument(AssocIndex),C,Susp,Key,KeyGoal),
3544 get_attr(Variable,Module,AssocStore),
3546 delete_assoc_store(AssocStore,Key,Susp)
3548 delete_constraint_body(global_singleton,C,_,_Susp,_,Body) :-
3549 global_singleton_store_name(C,StoreName),
3550 make_update_store_goal(StoreName,[],UpdateStoreGoal),
3553 UpdateStoreGoal % b_setval(StoreName,[])
3555 delete_constraint_body(multi_store(StoreTypes),C,Head,Susp,VarDict,Body) :-
3556 maplist(delete_constraint_body1(C,Head,Susp,VarDict),StoreTypes,Bodies),
3557 list2conj(Bodies,Body).
3558 delete_constraint_body1(C,Head,Susp,VarDict,StoreType,Body) :-
3559 delete_constraint_body(StoreType,C,Head,Susp,VarDict,Body).
3560 delete_constraint_body(identifier_store(Index),C,Head,Susp,VarDict,Body) :-
3561 get_suspension_argument_possibly_in_scope(Head,VarDict,Susp,Index,Variable,VariableGoal),
3562 get_identifier_size(ISize),
3563 functor(Struct,struct,ISize),
3564 get_identifier_index(C,Index,IIndex),
3565 arg(IIndex,Struct,Susps),
3569 'chr sbag_del_element'(Susps,Susp,NSusps),
3570 setarg(IIndex,Variable,NSusps)
3572 delete_constraint_body(type_indexed_identifier_store(Index,IndexType),C,Head,Susp,VarDict,Body) :-
3573 get_suspension_argument_possibly_in_scope(Head,VarDict,Susp,Index,Variable,VariableGoal),
3574 type_indexed_identifier_structure(IndexType,Struct),
3575 get_type_indexed_identifier_index(IndexType,C,Index,IIndex),
3576 arg(IIndex,Struct,Susps),
3580 'chr sbag_del_element'(Susps,Susp,NSusps),
3581 setarg(IIndex,Variable,NSusps)
3584 generate_multi_inthash_delete_constraint_bodies([],_,_,true).
3585 generate_multi_inthash_delete_constraint_bodies([Index|Indexes],FA,Susp,(Body,Bodies)) :-
3586 multi_hash_store_name(FA,Index,StoreName),
3587 multi_hash_key(FA,Index,Susp,KeyBody,Key),
3591 nb_getval(StoreName,Store),
3592 delete_iht(Store,Key,Susp)
3594 generate_multi_inthash_delete_constraint_bodies(Indexes,FA,Susp,Bodies).
3595 generate_multi_hash_delete_constraint_bodies([],_,_,_,_,true).
3596 generate_multi_hash_delete_constraint_bodies([Index|Indexes],C,Head,Susp,VarDict,(Body,Bodies)) :-
3597 multi_hash_store_name(C,Index,StoreName),
3598 multi_hash_key(C,Head,Index,Susp,VarDict,KeyBody,Key),
3599 make_get_store_goal(StoreName,Store,GetStoreGoal),
3600 ( chr_pp_flag(ht_removal,on)
3601 -> ht_prev_field(Index,PrevField),
3602 get_dynamic_suspension_term_field(PrevField,C,Susp,Prev,GetGoal),
3603 set_dynamic_suspension_term_field(PrevField,C,NextSusp,_,
3605 set_dynamic_suspension_term_field(PrevField,C,NextSusp,Prev,
3613 delete_first_ht(Store,Key,Values),
3614 ( Values = [NextSusp|_]
3618 ; Prev = [_,_|Values],
3619 setarg(2,Prev,Values),
3620 ( Values = [NextSusp|_]
3629 GetStoreGoal, % nb_getval(StoreName,Store),
3630 delete_ht(Store,Key,Susp)
3633 generate_multi_hash_delete_constraint_bodies(Indexes,FA,Head,Susp,VarDict,Bodies).
3635 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3638 module_initializer/1,
3639 module_initializers/1.
3641 module_initializers(G), module_initializer(Initializer) <=>
3642 G = (Initializer,Initializers),
3643 module_initializers(Initializers).
3645 module_initializers(G) <=>
3648 generate_attach_code(Constraints,Clauses) :-
3649 enumerate_stores_code(Constraints,Enumerate),
3650 append(Enumerate,L,Clauses),
3651 generate_attach_code(Constraints,L,T),
3652 module_initializers(Initializers),
3653 prolog_global_variables_code(PrologGlobalVariables),
3654 % Do not rename or the 'chr_initialization' predicate
3655 % without warning SSS
3656 T = [('$chr_initialization' :- Initializers),(:- initialization '$chr_initialization')|PrologGlobalVariables].
3658 generate_attach_code([],L,L).
3659 generate_attach_code([C|Cs],L,T) :-
3660 get_store_type(C,StoreType),
3661 generate_attach_code(StoreType,C,L,L1),
3662 generate_attach_code(Cs,L1,T).
3664 generate_attach_code(default,C,L,T) :-
3665 global_list_store_initialisation(C,L,T).
3666 generate_attach_code(multi_inthash(Indexes),C,L,T) :-
3667 multi_inthash_store_initialisations(Indexes,C,L,L1),
3668 multi_inthash_via_lookups(Indexes,C,L1,T).
3669 generate_attach_code(multi_hash(Indexes),C,L,T) :-
3670 multi_hash_store_initialisations(Indexes,C,L,L1),
3671 multi_hash_lookups(Indexes,C,L1,T).
3672 generate_attach_code(atomic_constants(Index,Constants,_),C,L,T) :-
3673 constants_initializers(C,Index,Constants),
3674 atomic_constants_code(C,Index,Constants,L,T).
3675 generate_attach_code(ground_constants(Index,Constants,_),C,L,T) :-
3676 constants_initializers(C,Index,Constants),
3677 ground_constants_code(C,Index,Constants,L,T).
3678 generate_attach_code(global_ground,C,L,T) :-
3679 global_ground_store_initialisation(C,L,T).
3680 generate_attach_code(var_assoc_store(_,_),_,L,L) :-
3681 use_auxiliary_module(chr_assoc_store).
3682 generate_attach_code(global_singleton,C,L,T) :-
3683 global_singleton_store_initialisation(C,L,T).
3684 generate_attach_code(multi_store(StoreTypes),C,L,T) :-
3685 multi_store_generate_attach_code(StoreTypes,C,L,T).
3686 generate_attach_code(identifier_store(Index),C,L,T) :-
3687 get_identifier_index(C,Index,IIndex),
3689 get_identifier_size(ISize),
3690 functor(Struct,struct,ISize),
3691 Struct =.. [_,Label|Stores],
3692 set_elems(Stores,[]),
3693 Clause1 = new_identifier(Label,Struct),
3694 functor(Struct2,struct,ISize),
3695 arg(1,Struct2,Label2),
3697 ( user:portray(Struct2) :-
3702 functor(Struct3,struct,ISize),
3703 arg(1,Struct3,Label3),
3704 Clause3 = identifier_label(Struct3,Label3),
3705 L = [Clause1,Clause2,Clause3|T]
3709 generate_attach_code(type_indexed_identifier_store(Index,IndexType),C,L,T) :-
3710 get_type_indexed_identifier_index(IndexType,C,Index,IIndex),
3712 identifier_store_initialization(IndexType,L,L1),
3713 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3714 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3715 get_type_indexed_identifier_size(IndexType,ISize),
3716 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3717 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3718 type_indexed_identifier_structure(IndexType,Struct),
3719 Struct =.. [_,Label|Stores],
3720 set_elems(Stores,[]),
3721 type_indexed_identifier_name(IndexType,new_identifier,Name1),
3722 Clause1 =.. [Name1,Label,Struct],
3723 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3724 Goal1 =.. [Name1,Label1b,S1b],
3725 type_indexed_identifier_structure(IndexType,Struct1b),
3726 Struct1b =.. [_,Label1b|Stores1b],
3727 set_elems(Stores1b,[]),
3728 Expansion1 = (S1b = Struct1b),
3729 Clause1b = user:goal_expansion(Goal1,Expansion1),
3730 % writeln(Clause1-Clause1b),
3731 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3732 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3733 type_indexed_identifier_structure(IndexType,Struct2),
3734 arg(1,Struct2,Label2),
3736 ( user:portray(Struct2) :-
3741 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3742 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3743 type_indexed_identifier_structure(IndexType,Struct3),
3744 arg(1,Struct3,Label3),
3745 type_indexed_identifier_name(IndexType,identifier_label,Name3),
3746 Clause3 =.. [Name3,Struct3,Label3],
3747 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3748 Goal3b =.. [Name3,S3b,L3b],
3749 type_indexed_identifier_structure(IndexType,Struct3b),
3750 arg(1,Struct3b,L3b),
3751 Expansion3b = (S3b = Struct3b),
3752 Clause3b = ( user:goal_expansion(Goal3b,Expansion3b) :- writeln(expanding)),
3753 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3754 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3755 identifier_store_name(IndexType,GlobalVariable),
3756 lookup_identifier_atom(IndexType,X,IX,LookupAtom),
3757 type_indexed_identifier_name(IndexType,new_identifier,NewIdentifierFunctor),
3758 NewIdentifierGoal =.. [NewIdentifierFunctor,X,IX],
3761 nb_getval(GlobalVariable,HT),
3762 ( lookup_ht(HT,X,[IX]) ->
3769 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3770 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3771 L1 = [(:- multifile goal_expansion/2),(:- dynamic goal_expansion/2),Clause1,Clause1b,Clause2,Clause3,Clause3b,Clause4|T]
3776 constants_initializers(C,Index,Constants) :-
3777 maplist(constant_initializer(C,Index),Constants).
3779 constant_initializer(C,Index,Constant) :-
3780 constants_store_name(C,Index,Constant,StoreName),
3781 prolog_global_variable(StoreName),
3782 module_initializer(nb_setval(StoreName,[])).
3784 lookup_identifier_atom(Key,X,IX,Atom) :-
3785 atom_concat('lookup_identifier_',Key,LookupFunctor),
3786 Atom =.. [LookupFunctor,X,IX].
3788 identifier_label_atom(IndexType,IX,X,Atom) :-
3789 type_indexed_identifier_name(IndexType,identifier_label,Name),
3790 Atom =.. [Name,IX,X].
3792 multi_store_generate_attach_code([],_,L,L).
3793 multi_store_generate_attach_code([ST|STs],C,L,T) :-
3794 generate_attach_code(ST,C,L,L1),
3795 multi_store_generate_attach_code(STs,C,L1,T).
3797 multi_inthash_store_initialisations([],_,L,L).
3798 multi_inthash_store_initialisations([Index|Indexes],FA,L,T) :-
3799 use_auxiliary_module(chr_integertable_store),
3800 multi_hash_store_name(FA,Index,StoreName),
3801 module_initializer((new_iht(HT),nb_setval(StoreName,HT))),
3802 % L = [(:- (chr_integertable_store:new_ht(HT),nb_setval(StoreName,HT)) )|L1],
3804 multi_inthash_store_initialisations(Indexes,FA,L1,T).
3805 multi_hash_store_initialisations([],_,L,L).
3806 multi_hash_store_initialisations([Index|Indexes],FA,L,T) :-
3807 use_auxiliary_module(chr_hashtable_store),
3808 multi_hash_store_name(FA,Index,StoreName),
3809 prolog_global_variable(StoreName),
3810 make_init_store_goal(StoreName,HT,InitStoreGoal),
3811 module_initializer((new_ht(HT),InitStoreGoal)),
3813 multi_hash_store_initialisations(Indexes,FA,L1,T).
3815 global_list_store_initialisation(C,L,T) :-
3817 global_list_store_name(C,StoreName),
3818 prolog_global_variable(StoreName),
3819 make_init_store_goal(StoreName,[],InitStoreGoal),
3820 module_initializer(InitStoreGoal)
3825 global_ground_store_initialisation(C,L,T) :-
3826 global_ground_store_name(C,StoreName),
3827 prolog_global_variable(StoreName),
3828 make_init_store_goal(StoreName,[],InitStoreGoal),
3829 module_initializer(InitStoreGoal),
3831 global_singleton_store_initialisation(C,L,T) :-
3832 global_singleton_store_name(C,StoreName),
3833 prolog_global_variable(StoreName),
3834 make_init_store_goal(StoreName,[],InitStoreGoal),
3835 module_initializer(InitStoreGoal),
3837 identifier_store_initialization(IndexType,L,T) :-
3838 use_auxiliary_module(chr_hashtable_store),
3839 identifier_store_name(IndexType,StoreName),
3840 prolog_global_variable(StoreName),
3841 make_init_store_goal(StoreName,HT,InitStoreGoal),
3842 module_initializer((new_ht(HT),InitStoreGoal)),
3846 multi_inthash_via_lookups([],_,L,L).
3847 multi_inthash_via_lookups([Index|Indexes],C,L,T) :-
3848 multi_hash_lookup_head(C,Index,Key,SuspsList,Head),
3849 multi_hash_lookup_body(C,inthash,Index,Key,SuspsList,Body),
3850 L = [(Head :- Body)|L1],
3851 multi_inthash_via_lookups(Indexes,C,L1,T).
3852 multi_hash_lookups([],_,L,L).
3853 multi_hash_lookups([Index|Indexes],C,L,T) :-
3854 multi_hash_lookup_head(C,Index,Key,SuspsList,Head),
3855 multi_hash_lookup_body(C,hash,Index,Key,SuspsList,Body),
3856 L = [(Head :- Body)|L1],
3857 multi_hash_lookups(Indexes,C,L1,T).
3859 multi_hash_lookup_head(ConstraintSymbol,Index,Key,SuspsList,Head) :-
3860 multi_hash_lookup_name(ConstraintSymbol,Index,Name),
3861 Head =.. [Name,Key,SuspsList].
3863 %% multi_hash_lookup_body(+ConstraintSymbol,+HashType,+Index,+Key,+SuspsList,-Goal) is det.
3865 % Returns goal that performs hash table lookup.
3866 multi_hash_lookup_body(ConstraintSymbol,HashType,Index,Key,SuspsList,Goal) :-
3868 get_store_type(ConstraintSymbol,multi_store(Stores)),
3869 ( memberchk(atomic_constants(Index,Constants,_),Stores) ->
3871 constants_store_name(ConstraintSymbol,Index,Key,StoreName),
3872 Goal = nb_getval(StoreName,SuspsList)
3874 constants_store_index_name(ConstraintSymbol,Index,IndexName),
3875 Lookup =.. [IndexName,Key,StoreName],
3876 Goal = (Lookup, nb_getval(StoreName,SuspsList))
3878 ; memberchk(ground_constants(Index,Constants,_),Stores) ->
3880 constants_store_name(ConstraintSymbol,Index,Key,StoreName),
3881 Goal = nb_getval(StoreName,SuspsList)
3883 constants_store_index_name(ConstraintSymbol,Index,IndexName),
3884 Lookup =.. [IndexName,Key,StoreName],
3885 Goal = (Lookup, nb_getval(StoreName,SuspsList))
3887 ; memberchk(multi_hash([Index]),Stores) ->
3888 multi_hash_store_name(ConstraintSymbol,Index,StoreName),
3889 make_get_store_goal(StoreName,HT,GetStoreGoal),
3890 ( HashType == hash, specialized_hash_term_call(ConstraintSymbol,Index,Key,Hash,HashCall) ->
3893 GetStoreGoal, % nb_getval(StoreName,HT),
3894 HashCall, % hash_term(Key,Hash),
3895 lookup_ht1(HT,Hash,Key,SuspsList)
3898 lookup_hash_call(HashType,HT,Key,SuspsList,Lookup),
3901 GetStoreGoal, % nb_getval(StoreName,HT),
3905 ; HashType == inthash ->
3906 multi_hash_store_name(ConstraintSymbol,Index,StoreName),
3907 make_get_store_goal(StoreName,HT,GetStoreGoal),
3908 lookup_hash_call(HashType,HT,Key,SuspsList,Lookup),
3911 GetStoreGoal, % nb_getval(StoreName,HT),
3914 % ; % chr_error(internal,'Index ~w for constraint ~w does not exist!\n',[Index,ConstraintSymbol])
3915 % find alternative index
3916 % -> SubIndex + RestIndex
3917 % -> SubKey + RestKeys
3918 % multi_hash_lookup_goal(ConstraintSymbol,HashType,SubIndex,SubKey,SuspsList,SubGoal),
3919 % instantiate rest goal?
3920 % Goal = (SubGoal,RestGoal)
3924 lookup_hash_call(hash,HT,Key,SuspsList,lookup_ht(HT,Key,SuspsList)).
3925 lookup_hash_call(inthash,HT,Key,SuspsList,lookup_iht(HT,Key,SuspsList)).
3927 specialized_hash_term_call(Constraint,Index,Key,Hash,Call) :-
3929 % This is based on a property of SWI-Prolog's
3930 % hash_term/2 predicate:
3931 % the hash value is stable over repeated invocations
3933 hash_term(Key,Hash),
3935 % ; Index = [IndexPos],
3936 % get_constraint_type(Constraint,ArgTypes),
3937 % nth1(IndexPos,ArgTypes,Type),
3938 % unalias_type(Type,NormalType),
3939 % memberchk_eq(NormalType,[int,natural]) ->
3940 % ( NormalType == int ->
3941 % Call = (Hash is abs(Key))
3948 % specialize_hash_term(Key,NewKey),
3950 % Call = hash_term(NewKey,Hash)
3953 % specialize_hash_term(Term,NewTerm) :-
3955 % hash_term(Term,NewTerm)
3959 % Term =.. [F|Args],
3960 % maplist(specialize_hash_term,Args,NewArgs),
3961 % NewTerm =.. [F|NewArgs]
3964 multi_hash_lookup_goal(ConstraintSymbol,HashType,Index,Key,SuspsList,Goal) :-
3965 % format(' * lookup of ~w on ~w with ~w.\n',[ConstraintSymbol,Index,Key]),
3966 ( /* chr_pp_flag(experiment,off) ->
3969 actual_atomic_multi_hash_keys(ConstraintSymbol,Index,[Key])
3971 actual_ground_multi_hash_keys(ConstraintSymbol,Index,[Key])
3974 get_constraint_arg_type(ConstraintSymbol,Pos,Type),
3975 is_chr_constants_type(Type,_,_)
3979 actual_non_ground_multi_hash_key(ConstraintSymbol,Index)
3982 delay_phase_end(validate_store_type_assumptions,
3983 multi_hash_lookup_body(ConstraintSymbol,HashType,Index,Key,SuspsList,Goal)).
3985 :- chr_constraint actual_atomic_multi_hash_keys/3.
3986 :- chr_option(mode,actual_atomic_multi_hash_keys(+,+,?)).
3988 :- chr_constraint actual_ground_multi_hash_keys/3.
3989 :- chr_option(mode,actual_ground_multi_hash_keys(+,+,?)).
3991 :- chr_constraint actual_non_ground_multi_hash_key/2.
3992 :- chr_option(mode,actual_non_ground_multi_hash_key(+,+)).
3995 actual_atomic_multi_hash_keys(C,Index,Keys)
3996 ==> format('Keys: ~w - ~w : ~w\n', [C,Index,Keys]).
3998 actual_ground_multi_hash_keys(C,Index,Keys)
3999 ==> format('Keys: ~w - ~w : ~w\n', [C,Index,Keys]).
4001 actual_non_ground_multi_hash_key(C,Index)
4002 ==> format('Keys: ~w - ~w : N/A\n', [C,Index]).
4004 actual_atomic_multi_hash_keys(C,Index,Keys1), actual_atomic_multi_hash_keys(C,Index,Keys2)
4005 <=> append(Keys1,Keys2,Keys0),
4007 actual_atomic_multi_hash_keys(C,Index,Keys).
4009 actual_ground_multi_hash_keys(C,Index,Keys1), actual_atomic_multi_hash_keys(C,Index,Keys2)
4010 <=> append(Keys1,Keys2,Keys0),
4012 actual_ground_multi_hash_keys(C,Index,Keys).
4014 actual_ground_multi_hash_keys(C,Index,Keys1), actual_ground_multi_hash_keys(C,Index,Keys2)
4015 <=> append(Keys1,Keys2,Keys0),
4017 actual_ground_multi_hash_keys(C,Index,Keys).
4019 actual_non_ground_multi_hash_key(C,Index) \ actual_non_ground_multi_hash_key(C,Index)
4022 actual_non_ground_multi_hash_key(C,Index) \ actual_atomic_multi_hash_keys(C,Index,_)
4025 actual_non_ground_multi_hash_key(C,Index) \ actual_ground_multi_hash_keys(C,Index,_)
4028 %% multi_hash_lookup_name(+ConstraintSymbol,+Index,-Name)
4030 % Returns predicate name of hash table lookup predicate.
4031 multi_hash_lookup_name(F/A,Index,Name) :-
4032 atom_concat_list(Index,IndexName),
4033 atom_concat_list(['$via1_multi_hash_',F,'___',A,'-',IndexName],Name).
4035 multi_hash_store_name(F/A,Index,Name) :-
4036 get_target_module(Mod),
4037 atom_concat_list(Index,IndexName),
4038 atom_concat_list(['$chr_store_multi_hash_',Mod,'____',F,'___',A,'-',IndexName],Name).
4040 multi_hash_key(FA,Index,Susp,KeyBody,Key) :-
4042 get_dynamic_suspension_term_field(argument(I),FA,Susp,Key,KeyBody)
4044 maplist(get_dynamic_suspension_term_field1(FA,Susp),Index,Keys,Bodies),
4046 list2conj(Bodies,KeyBody)
4049 get_dynamic_suspension_term_field1(FA,Susp,I,KeyI,Goal) :-
4050 get_dynamic_suspension_term_field(argument(I),FA,Susp,KeyI,Goal).
4052 multi_hash_key(C,Head,Index,Susp,VarDict,KeyBody,Key) :-
4054 get_suspension_argument_possibly_in_scope(Head,VarDict,Susp,I,Key,KeyBody)
4056 maplist(get_suspension_argument_possibly_in_scope(Head,VarDict,Susp),Index,Keys,Bodies),
4058 list2conj(Bodies,KeyBody)
4061 get_suspension_argument_possibly_in_scope(Head,VarDict,Susp,Index,Arg,Goal) :-
4062 arg(Index,Head,OriginalArg),
4063 ( term_variables(OriginalArg,OriginalVars),
4064 copy_term_nat(OriginalArg-OriginalVars,Arg-Vars),
4065 translate(OriginalVars,VarDict,Vars) ->
4070 get_dynamic_suspension_term_field(argument(Index),C,Susp,Arg,Goal)
4073 multi_hash_key_direct(FA,Index,Susp,Key,UsedVars) :-
4077 pairup(Index,Keys,UsedVars),
4081 args(Index,Head,KeyArgs) :-
4082 maplist(arg1(Head),Index,KeyArgs).
4084 split_args(Indexes,Args,IArgs,NIArgs) :-
4085 split_args(Indexes,Args,1,IArgs,NIArgs).
4087 split_args([],Args,_,[],Args).
4088 split_args([I|Is],[Arg|Args],J,IArgs,NIArgs) :-
4092 split_args(Is,Args,NJ,Rest,NIArgs)
4094 NIArgs = [Arg|Rest],
4095 split_args([I|Is],Args,NJ,IArgs,Rest)
4099 %-------------------------------------------------------------------------------
4100 atomic_constants_code(C,Index,Constants,L,T) :-
4101 constants_store_index_name(C,Index,IndexName),
4102 maplist(atomic_constant_code(C,Index,IndexName),Constants,Clauses),
4103 append(Clauses,T,L).
4105 atomic_constant_code(C,Index,IndexName,Constant,Clause) :-
4106 constants_store_name(C,Index,Constant,StoreName),
4107 Clause =.. [IndexName,Constant,StoreName].
4109 %-------------------------------------------------------------------------------
4110 ground_constants_code(C,Index,Terms,L,T) :-
4111 constants_store_index_name(C,Index,IndexName),
4112 maplist(constants_store_name(C,Index),Terms,StoreNames),
4114 replicate(N,[],More),
4115 trie_index([Terms|More],StoreNames,IndexName,L,T).
4117 constants_store_name(F/A,Index,Term,Name) :-
4118 get_target_module(Mod),
4119 term_to_atom(Term,Constant),
4120 term_to_atom(Index,IndexAtom),
4121 atom_concat_list(['$chr_store_constants_',Mod,'____',F,'___',A,'___',IndexAtom,'___',Constant],Name).
4123 constants_store_index_name(F/A,Index,Name) :-
4124 get_target_module(Mod),
4125 term_to_atom(Index,IndexAtom),
4126 atom_concat_list(['$chr_store_constants_',Mod,'____',F,'___',A,'___',IndexAtom],Name).
4128 % trie index code {{{
4129 trie_index([Patterns|MorePatterns],Results,Prefix,Clauses,Tail) :-
4130 trie_step(Patterns,Prefix,Prefix,MorePatterns,Results,Clauses,Tail).
4132 trie_step([],_,_,[],[],L,L) :- !.
4133 % length MorePatterns == length Patterns == length Results
4134 trie_step(Patterns,Symbol,Prefix,MorePatterns,Results,Clauses,T) :-
4135 MorePatterns = [List|_],
4137 aggregate_all(set(F/A),
4138 ( member(Pattern,Patterns),
4139 functor(Pattern,F,A)
4143 trie_step_cases(FAs,N1,Patterns,MorePatterns,Results,Symbol,Prefix,Clauses,T).
4145 trie_step_cases([],_,_,_,_,_,_,Clauses,Clauses).
4146 trie_step_cases([FA|FAs],N,Pattern,MorePatterns,Results,Symbol,Prefix,Clauses,Tail) :-
4147 trie_step_case(FA,N,Pattern,MorePatterns,Results,Symbol,Prefix,Clauses,Clauses1),
4148 trie_step_cases(FAs,N,Pattern,MorePatterns,Results,Symbol,Prefix,Clauses1,Tail).
4150 trie_step_case(F/A,N,Patterns,MorePatterns,Results,Symbol,Prefix,[Clause|List],Tail) :-
4151 Clause = (Head :- Body),
4152 /* Head = Symbol(IndexPattern,V2,...,Vn,Result) */
4154 functor(Head,Symbol,N1),
4155 arg(1,Head,IndexPattern),
4156 Head =.. [_,_|RestArgs],
4157 once(append(Vs,[Result],RestArgs)),
4158 /* IndexPattern = F() */
4159 functor(IndexPattern,F,A),
4160 IndexPattern =.. [_|Args],
4161 append(Args,RestArgs,RecArgs),
4162 ( RecArgs == [Result] ->
4163 /* nothing more to match on */
4166 rec_cases(Patterns,_,Results,F/A,_,_,MoreResults),
4167 MoreResults = [Result]
4168 ; /* more things to match on */
4169 rec_cases(Patterns,MorePatterns,Results,F/A,Cases,MoreCases,MoreResults),
4170 ( MoreCases = [OneMoreCase] ->
4171 /* only one more thing to match on */
4174 append([Cases,OneMoreCase,MoreResults],RecArgs)
4176 /* more than one thing to match on */
4180 pairup(Cases,MoreCases,CasePairs),
4181 common_pattern(CasePairs,CommonPatternPair,DiffVars,Differences),
4182 append(Args,Vs,[First|Rest]),
4183 First-Rest = CommonPatternPair,
4184 % Body = RSymbol(DiffVars,Result)
4185 gensym(Prefix,RSymbol),
4186 append(DiffVars,[Result],RecCallVars),
4187 Body =.. [RSymbol|RecCallVars],
4188 maplist(head_tail,Differences,CHs,CTs),
4189 trie_step(CHs,RSymbol,Prefix,CTs,MoreResults,List,Tail)
4193 head_tail([H|T],H,T).
4195 rec_cases([],[],[],_,[],[],[]).
4196 rec_cases([Pattern|Patterns],[MorePattern|MorePatterns],[Result|Results],F/A,Cases,MoreCases,MoreResults) :-
4197 ( functor(Pattern,F,A), Pattern =.. [_|ArgPatterns], append(ArgPatterns,MorePattern,[Case|MoreCase]) ->
4198 Cases = [Case|NCases],
4199 MoreCases = [MoreCase|NMoreCases],
4200 MoreResults = [Result|NMoreResults],
4201 rec_cases(Patterns,MorePatterns,Results,F/A,NCases,NMoreCases,NMoreResults)
4203 rec_cases(Patterns,MorePatterns,Results,F/A,Cases,MoreCases,MoreResults)
4207 %% common_pattern(+terms,-term,-vars,-differences) is det.
4208 common_pattern(Ts,T,Vars,Differences) :-
4209 fold1(chr_translate:gct,Ts,T),
4210 term_variables(T,Vars),
4211 findall(Vars,member(T,Ts),Differences).
4216 gct_(T1,T2,T,Dict0,Dict) :-
4227 maplist_dcg(chr_translate:gct_,Args1,Args2,Args,Dict0,Dict)
4229 /* T is a variable */
4230 ( lookup_eq(Dict0,T1+T2,T) ->
4231 /* we already have a variable for this difference */
4234 /* T is a fresh variable */
4235 Dict = [(T1+T2)-T|Dict0]
4240 %-------------------------------------------------------------------------------
4241 global_list_store_name(F/A,Name) :-
4242 get_target_module(Mod),
4243 atom_concat_list(['$chr_store_global_list_',Mod,'____',F,'___',A],Name).
4244 global_ground_store_name(F/A,Name) :-
4245 get_target_module(Mod),
4246 atom_concat_list(['$chr_store_global_ground_',Mod,'____',F,'___',A],Name).
4247 global_singleton_store_name(F/A,Name) :-
4248 get_target_module(Mod),
4249 atom_concat_list(['$chr_store_global_singleton_',Mod,'____',F,'___',A],Name).
4251 identifier_store_name(TypeName,Name) :-
4252 get_target_module(Mod),
4253 atom_concat_list(['$chr_identifier_lookup_',Mod,'____',TypeName],Name).
4255 :- chr_constraint prolog_global_variable/1.
4256 :- chr_option(mode,prolog_global_variable(+)).
4258 :- chr_constraint prolog_global_variables/1.
4259 :- chr_option(mode,prolog_global_variables(-)).
4261 prolog_global_variable(Name) \ prolog_global_variable(Name) <=> true.
4263 prolog_global_variables(List), prolog_global_variable(Name) <=>
4265 prolog_global_variables(Tail).
4266 prolog_global_variables(List) <=> List = [].
4269 prolog_global_variables_code(Code) :-
4270 prolog_global_variables(Names),
4274 maplist(wrap_in_functor('$chr_prolog_global_variable'),Names,NameDeclarations),
4275 Code = [(:- dynamic user:exception/3),
4276 (:- multifile user:exception/3),
4277 (user:exception(undefined_global_variable,Name,retry) :-
4279 '$chr_prolog_global_variable'(Name),
4280 '$chr_initialization'
4289 % prolog_global_variables_code([]).
4291 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4292 %sbag_member_call(S,L,sysh:mem(S,L)).
4293 sbag_member_call(S,L,'chr sbag_member'(S,L)).
4294 %sbag_member_call(S,L,member(S,L)).
4295 update_mutable_call(A,B,'chr update_mutable'( A, B)).
4296 %update_mutable_call(A,B,setarg(1, B, A)).
4297 create_mutable_call(Value,Mutable,true) :- Mutable = mutable(Value).
4298 % create_mutable_call(Value,Mutable,'chr create_mutable'(Value,Mutable)).
4300 % get_suspension_field(Constraint,Susp,FieldName,Value,(Get0,Get1)) :-
4301 % get_dynamic_suspension_term_field(FieldName,Constraint,Susp,Field,Get0),
4302 % create_get_mutable(Value,Field,Get1).
4304 % update_suspension_field(Constraint,Susp,FieldName,NewValue,(Get,Set)) :-
4305 % get_dynamic_suspension_term_field(FieldName,Constraint,Susp,Field,Get),
4306 % update_mutable_call(NewValue,Field,Set).
4308 % get_update_suspension_field(Constraint,Susp,FieldName,Value,NewValue,Get0,Get1,Set) :-
4309 % get_dynamic_suspension_term_field(FieldName,Constraint,Susp,Field,Get0),
4310 % create_get_mutable_ref(Value,Field,Get1),
4311 % update_mutable_call(NewValue,Field,Set).
4313 % create_static_suspension_field(Constraint,Susp,FieldName,Value,Create) :-
4314 % get_static_suspension_term_field(FieldName,Constraint,Susp,Field),
4315 % create_mutable_call(Value,Field,Create).
4317 % get_static_suspension_field(Constraint,Susp,FieldName,Value,Get) :-
4318 % get_static_suspension_term_field(FieldName,Constraint,Susp,Field),
4319 % create_get_mutable(Value,Field,Get).
4321 % get_update_static_suspension_field(Constraint,Susp,SuspTerm,FieldName,Value,NewValue,Get,Set) :-
4322 % get_static_suspension_term_field(FieldName,Constraint,SuspTerm,Field),
4323 % create_get_mutable_ref(Value,Field,Get),
4324 % update_mutable_call(NewValue,Field,Set).
4326 get_suspension_field(Constraint,Susp,FieldName,Value,Get) :-
4327 get_dynamic_suspension_term_field(FieldName,Constraint,Susp,Value,Get).
4329 update_suspension_field(Constraint,Susp,FieldName,NewValue,Set) :-
4330 set_dynamic_suspension_term_field(FieldName,Constraint,Susp,NewValue,Set).
4332 get_update_suspension_field(Constraint,Susp,FieldName,Value,NewValue,true,Get,Set) :-
4333 get_dynamic_suspension_term_field(FieldName,Constraint,Susp,Value,Get),
4334 set_dynamic_suspension_term_field(FieldName,Constraint,Susp,NewValue,Set).
4336 create_static_suspension_field(Constraint,Susp,FieldName,Value,true) :-
4337 get_static_suspension_term_field(FieldName,Constraint,Susp,Value).
4339 get_static_suspension_field(Constraint,Susp,FieldName,Value,true) :-
4340 get_static_suspension_term_field(FieldName,Constraint,Susp,Value).
4342 get_update_static_suspension_field(Constraint,Susp,SuspTerm,FieldName,Value,NewValue,true,Set) :-
4343 get_static_suspension_term_field(FieldName,Constraint,SuspTerm,Value),
4344 set_dynamic_suspension_term_field(FieldName,Constraint,Susp,NewValue,Set).
4346 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4348 enumerate_stores_code(Constraints,[Clause|List]) :-
4349 Head = '$enumerate_constraints'(Constraint),
4350 Clause = ( Head :- Body),
4351 enumerate_store_bodies(Constraints,Constraint,List),
4355 Body = ( nonvar(Constraint) ->
4356 functor(Constraint,Functor,_),
4357 '$enumerate_constraints'(Functor,Constraint)
4359 '$enumerate_constraints'(_,Constraint)
4363 enumerate_store_bodies([],_,[]).
4364 enumerate_store_bodies([C|Cs],Constraint,L) :-
4366 get_store_type(C,StoreType),
4367 ( enumerate_store_body(StoreType,C,Suspension,SuspensionBody) ->
4370 chr_error(internal,'Could not generate enumeration code for constraint ~w.\n',[C])
4372 get_dynamic_suspension_term_field(arguments,C,Suspension,Arguments,DynamicGoal),
4374 Constraint0 =.. [F|Arguments],
4375 Head = '$enumerate_constraints'(F,Constraint),
4376 Body = (SuspensionBody, DynamicGoal, Constraint = Constraint0),
4377 L = [(Head :- Body)|T]
4381 enumerate_store_bodies(Cs,Constraint,T).
4383 enumerate_store_body(default,C,Susp,Body) :-
4384 global_list_store_name(C,StoreName),
4385 sbag_member_call(Susp,List,Sbag),
4386 make_get_store_goal(StoreName,List,GetStoreGoal),
4389 GetStoreGoal, % nb_getval(StoreName,List),
4392 % get_constraint_index(C,Index),
4393 % get_target_module(Mod),
4394 % get_max_constraint_index(MaxIndex),
4397 % 'chr default_store'(GlobalStore),
4398 % get_attr(GlobalStore,Mod,Attr)
4401 % NIndex is Index + 1,
4402 % sbag_member_call(Susp,List,Sbag),
4405 % arg(NIndex,Attr,List),
4409 % sbag_member_call(Susp,Attr,Sbag),
4412 % Body = (Body1,Body2).
4413 enumerate_store_body(multi_inthash([Index|_]),C,Susp,Body) :-
4414 multi_inthash_enumerate_store_body(Index,C,Susp,Body).
4415 enumerate_store_body(multi_hash([Index|_]),C,Susp,Body) :-
4416 multi_hash_enumerate_store_body(Index,C,Susp,Body).
4417 enumerate_store_body(atomic_constants(Index,Constants,Completeness),C,Susp,Body) :-
4418 Completeness == complete, % fail if incomplete
4419 maplist(enumerate_constant_store_body(C,Index,Susps),Constants,Disjuncts),
4420 list2disj(Disjuncts, Disjunction),
4421 Body = ( Disjunction, member(Susp,Susps) ).
4422 enumerate_constant_store_body(C,Index,Susps,Constant,nb_getval(StoreName,Susps)) :-
4423 constants_store_name(C,Index,Constant,StoreName).
4425 enumerate_store_body(ground_constants(Index,Constants,Completeness),C,Susp,Body) :-
4426 enumerate_store_body(atomic_constants(Index,Constants,Completeness),C,Susp,Body).
4427 enumerate_store_body(global_ground,C,Susp,Body) :-
4428 global_ground_store_name(C,StoreName),
4429 sbag_member_call(Susp,List,Sbag),
4430 make_get_store_goal(StoreName,List,GetStoreGoal),
4433 GetStoreGoal, % nb_getval(StoreName,List),
4436 enumerate_store_body(var_assoc_store(_,_),C,_,Body) :-
4438 enumerate_store_body(global_singleton,C,Susp,Body) :-
4439 global_singleton_store_name(C,StoreName),
4440 make_get_store_goal(StoreName,Susp,GetStoreGoal),
4443 GetStoreGoal, % nb_getval(StoreName,Susp),
4446 enumerate_store_body(multi_store(STs),C,Susp,Body) :-
4447 ( memberchk(global_ground,STs) ->
4448 enumerate_store_body(global_ground,C,Susp,Body)
4452 enumerate_store_body(ST,C,Susp,Body)
4455 enumerate_store_body(identifier_store(Index),C,Susp,Body) :-
4457 enumerate_store_body(type_indexed_identifier_store(Index,IndexType),C,Susp,Body) :-
4460 multi_inthash_enumerate_store_body(I,C,Susp,B) :-
4461 multi_hash_store_name(C,I,StoreName),
4464 nb_getval(StoreName,HT),
4467 multi_hash_enumerate_store_body(I,C,Susp,B) :-
4468 multi_hash_store_name(C,I,StoreName),
4469 make_get_store_goal(StoreName,HT,GetStoreGoal),
4472 GetStoreGoal, % nb_getval(StoreName,HT),
4476 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4477 % BACKGROUND INFORMATION (declared using :- chr_declaration)
4478 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4485 get_bg_info_answer/1.
4487 background_info(X), background_info(Y) <=>
4488 append(X,Y,XY), background_info(XY).
4489 background_info(X) \ get_bg_info(Q) <=> Q=X.
4490 get_bg_info(Q) <=> Q = [].
4492 background_info(T,I), get_bg_info(A,Q) ==>
4493 copy_term_nat(T,T1),
4496 copy_term_nat(T-I,A-X),
4497 get_bg_info_answer([X]).
4498 get_bg_info_answer(X), get_bg_info_answer(Y) <=>
4499 append(X,Y,XY), get_bg_info_answer(XY).
4501 get_bg_info_answer(X) # Id, get_bg_info(A,Q) <=> Q=X pragma passive(Id).
4502 get_bg_info(_,Q) <=> Q=[]. % no info found on this term
4504 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4513 :- chr_option(mode,prev_guard_list(+,+,+,+,+,+,+,+)).
4514 :- chr_option(mode,prev_guard_list(+,+,+,+,+,+)).
4515 :- chr_option(type_declaration,prev_guard_list(any,any,any,any,any,list)).
4516 :- chr_option(mode,simplify_guards(+)).
4517 :- chr_option(mode,set_all_passive(+)).
4519 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4520 % GUARD SIMPLIFICATION
4521 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4522 % If the negation of the guards of earlier rules entails (part of)
4523 % the current guard, the current guard can be simplified. We can only
4524 % use earlier rules with a head that matches if the head of the current
4525 % rule does, and which make it impossible for the current rule to match
4526 % if they fire (i.e. they shouldn't be propagation rules and their
4527 % head constraints must be subsets of those of the current rule).
4528 % At this point, we know for sure that the negation of the guard
4529 % of such a rule has to be true (otherwise the earlier rule would have
4530 % fired, because of the refined operational semantics), so we can use
4531 % that information to simplify the guard by replacing all entailed
4532 % conditions by true/0. As a consequence, the never-stored analysis
4533 % (in a further phase) will detect more cases of never-stored constraints.
4535 % e.g. c(X),d(Y) <=> X > 0 | ...
4536 % e(X) <=> X < 0 | ...
4537 % c(X) \ d(Y),e(Z) <=> X =< 0, Z >= 0, ... | ...
4541 guard_simplification :-
4542 ( chr_pp_flag(guard_simplification,on) ->
4543 precompute_head_matchings,
4549 % for every rule, we create a prev_guard_list where the last argument
4550 % eventually is a list of the negations of earlier guards
4551 rule(RuleNb,Rule) \ simplify_guards(RuleNb)
4553 Rule = pragma(rule(Head1,Head2,Guard,_B),ids(IDs1,IDs2),_Pragmas,_Name,RuleNb),
4554 append(Head1,Head2,Heads),
4555 make_head_matchings_explicit_not_negated(Heads,MatchingFreeHeads,Matchings),
4556 tree_set_empty(Done),
4557 multiple_occ_constraints_checked(Done),
4558 apply_guard_wrt_term(Heads,Guard,SubstitutedHeads),
4560 append(IDs1,IDs2,IDs),
4561 findall(tuple(C,O,RuleNb)-(-RuleNb),(member(ID,IDs),get_occurrence_from_id(C,O,RuleNb,ID)),HeapData),
4563 insert_list_q(HeapData,EmptyHeap,Heap),
4564 next_prev_rule(Heap,_,Heap1),
4565 next_prev_rule(Heap1,PrevRuleNb,NHeap),
4566 prev_guard_list(RuleNb,PrevRuleNb,NHeap,MatchingFreeHeads,Guard,[],Matchings,[SubstitutedHeads]),
4567 NextRule is RuleNb+1,
4568 simplify_guards(NextRule).
4570 next_prev_rule(Heap,RuleNb,NHeap) :-
4571 ( find_min_q(Heap,_-Priority) ->
4572 Priority = (-RuleNb),
4573 normalize_heap(Heap,Priority,NHeap)
4579 normalize_heap(Heap,Priority,NHeap) :-
4580 ( find_min_q(Heap,_-Priority) ->
4581 delete_min_q(Heap,Heap1,tuple(C,O,_)-_),
4584 get_occurrence(C,NO,RuleNb,_),
4585 insert_q(Heap1,tuple(C,NO,RuleNb)-(-RuleNb),Heap2)
4589 normalize_heap(Heap2,Priority,NHeap)
4599 % The negation of the guard of a non-propagation rule is added
4600 % if its kept head constraints are a subset of the kept constraints of
4601 % the rule we're working on, and its removed head constraints (at least one)
4602 % are a subset of the removed constraints.
4604 rule(PrevRuleNb,PrevRule) \ prev_guard_list(RuleNb,PrevRuleNb,Heap,CurrentHeads,G,GuardList,Matchings,GH)
4606 PrevRule = pragma(rule(H1,H2,PrevGuard,_B),_Ids,_Pragmas,_Name,_PrevRuleNb), % PrevRuleNb == _PrevRuleNb
4608 make_head_matchings_explicit(PrevRuleNb,MatchingFreeHeads,PrevMatchings),
4609 setof(Renaming,chr_translate:head_subset(MatchingFreeHeads,CurrentHeads,Renaming),Renamings)
4611 append(H1,H2,Heads),
4612 compute_derived_info(Renamings,PrevMatchings,MatchingFreeHeads,Heads,PrevGuard,Matchings,CurrentHeads,GH,DerivedInfo,GH_New1),
4613 append(GuardList,DerivedInfo,GL1),
4614 normalize_conj_list(GL1,GL),
4615 append(GH_New1,GH,GH1),
4616 normalize_conj_list(GH1,GH_New),
4617 next_prev_rule(Heap,PrevPrevRuleNb,NHeap),
4618 % PrevPrevRuleNb is PrevRuleNb-1,
4619 prev_guard_list(RuleNb,PrevPrevRuleNb,NHeap,CurrentHeads,G,GL,Matchings,GH_New).
4621 % if this isn't the case, we skip this one and try the next rule
4622 prev_guard_list(RuleNb,N,Heap,H,G,GuardList,M,GH)
4625 next_prev_rule(Heap,N1,NHeap),
4627 prev_guard_list(RuleNb,N1,NHeap,H,G,GuardList,M,GH)
4629 prev_guard_list(RuleNb,H,G,GuardList,M,GH)
4632 prev_guard_list(RuleNb,H,G,GuardList,M,GH)
4636 head_types_modes_condition(GH,H,TypeInfo),
4637 conj2list(TypeInfo,TI),
4638 term_variables(H,HeadVars),
4639 append([chr_pp_headvariables(HeadVars)|TI],GuardList,Info),
4640 normalize_conj_list(Info,InfoL),
4641 append(H,InfoL,RelevantTerms),
4642 add_background_info([G|RelevantTerms],BGInfo),
4643 append(InfoL,BGInfo,AllInfo_),
4644 normalize_conj_list(AllInfo_,AllInfo),
4645 prev_guard_list(RuleNb,H,G,AllInfo,M,[]).
4647 head_types_modes_condition([],H,true).
4648 head_types_modes_condition([GH|GHs],H,(TI1, TI2)) :-
4649 types_modes_condition(H,GH,TI1),
4650 head_types_modes_condition(GHs,H,TI2).
4652 add_background_info(Term,Info) :-
4653 get_bg_info(GeneralInfo),
4654 add_background_info2(Term,TermInfo),
4655 append(GeneralInfo,TermInfo,Info).
4657 add_background_info2(X,[]) :- var(X), !.
4658 add_background_info2([],[]) :- !.
4659 add_background_info2([X|Xs],Info) :- !,
4660 add_background_info2(X,Info1),
4661 add_background_info2(Xs,Infos),
4662 append(Info1,Infos,Info).
4664 add_background_info2(X,Info) :-
4665 (functor(X,_,A), A>0 ->
4667 add_background_info2(XArgs,XArgInfo)
4671 get_bg_info(X,XInfo),
4672 append(XInfo,XArgInfo,Info).
4675 % when all earlier guards are added or skipped, we simplify the guard.
4676 % if it's different from the original one, we change the rule
4678 prev_guard_list(RuleNb,H,G,GuardList,M,[]), rule(RuleNb,Rule)
4680 Rule = pragma(rule(Head1,Head2,G,B),Ids,Pragmas,Name,RuleNb),
4681 G \== true, % let's not try to simplify this ;)
4682 append(M,GuardList,Info),
4683 (% if guard + context is a contradiction, it should be simplified to "fail"
4684 conj2list(G,GL), append(Info,GL,GuardWithContext),
4685 guard_entailment:entails_guard(GuardWithContext,fail) ->
4688 % otherwise we try to remove redundant conjuncts
4689 simplify_guard(G,B,Info,SimpleGuard,NB)
4691 G \== SimpleGuard % only do this if we can change the guard
4693 rule(RuleNb,pragma(rule(Head1,Head2,SimpleGuard,NB),Ids,Pragmas,Name,RuleNb)),
4694 prev_guard_list(RuleNb,H,SimpleGuard,GuardList,M,[]).
4696 %% normalize_conj_list(+List,-NormalList) is det.
4698 % Removes =true= elements and flattens out conjunctions.
4700 normalize_conj_list(List,NormalList) :-
4701 list2conj(List,Conj),
4702 conj2list(Conj,NormalList).
4704 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4705 % AUXILIARY PREDICATES (GUARD SIMPLIFICATION)
4706 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4708 compute_derived_info([],_PrevMatchings,_MatchingFreeHeads,_Heads,_PrevGuard,_Matchings,_H,_GH,[],[]).
4709 compute_derived_info([Renaming1|RestRenamings],PrevMatchings,PrevMatchingFreeHeads,PrevHeads,PrevGuard,Matchings,H,GH,[DerivedInfo1|DerivedInfo2],[GH3|GH_New2]) :-
4710 copy_term(PrevMatchings-PrevGuard,FreshMatchings),
4711 variable_replacement(PrevMatchings-PrevGuard,FreshMatchings,ExtraRenaming),
4712 append(Renaming1,ExtraRenaming,Renaming2),
4713 list2conj(PrevMatchings,Match),
4714 negate_b(Match,HeadsDontMatch),
4715 make_head_matchings_explicit_not_negated2(PrevHeads,PrevMatchingFreeHeads,HeadsMatch),
4716 list2conj(HeadsMatch,HeadsMatchBut),
4717 term_variables(Renaming2,RenVars),
4718 term_variables(PrevMatchings-PrevGuard-HeadsMatch,MGVars),
4719 new_vars(MGVars,RenVars,ExtraRenaming2),
4720 append(Renaming2,ExtraRenaming2,Renaming),
4721 ( PrevGuard == true -> % true can't fail
4722 Info_ = HeadsDontMatch
4724 negate_b(PrevGuard,TheGuardFailed),
4725 Info_ = (HeadsDontMatch ; (HeadsMatchBut, TheGuardFailed))
4727 copy_with_variable_replacement(Info_,DerivedInfo1,Renaming),
4728 copy_with_variable_replacement(PrevGuard,RenamedG2,Renaming),
4729 copy_with_variable_replacement(PrevMatchings,RenamedMatchings_,Renaming),
4730 list2conj(RenamedMatchings_,RenamedMatchings),
4731 apply_guard_wrt_term(H,RenamedG2,GH2),
4732 apply_guard_wrt_term(GH2,RenamedMatchings,GH3),
4733 compute_derived_info(RestRenamings,PrevMatchings,PrevMatchingFreeHeads,PrevHeads,PrevGuard,Matchings,H,GH,DerivedInfo2,GH_New2).
4735 simplify_guard(G,B,Info,SG,NB) :-
4737 % writeq(guard_entailment:simplify_guards(Info,B,LG,SGL,NB)),nl,
4738 guard_entailment:simplify_guards(Info,B,LG,SGL,NB),
4743 new_vars([A|As],RV,ER) :-
4744 ( memberchk_eq(A,RV) ->
4747 ER = [A-NewA,NewA-A|ER2],
4751 %% head_subset(+Subset,+MultiSet,-Renaming) is nondet.
4753 % check if a list of constraints is a subset of another list of constraints
4754 % (multiset-subset), meanwhile computing a variable renaming to convert
4755 % one into the other.
4756 head_subset(H,Head,Renaming) :-
4757 head_subset(H,Head,Renaming,[],_).
4759 head_subset([],Remainder,Renaming,Renaming,Remainder).
4760 head_subset([X|Xs],MultiSet,Renaming,Acc,Remainder) :-
4761 head_member(MultiSet,X,NAcc,Acc,Remainder1),
4762 head_subset(Xs,Remainder1,Renaming,NAcc,Remainder).
4764 % check if A is in the list, remove it from Headleft
4765 head_member([X|Xs],A,Renaming,Acc,Remainder) :-
4766 ( variable_replacement(A,X,Acc,Renaming),
4769 Remainder = [X|RRemainder],
4770 head_member(Xs,A,Renaming,Acc,RRemainder)
4772 %-------------------------------------------------------------------------------%
4773 % memoing code to speed up repeated computation
4775 :- chr_constraint precompute_head_matchings/0.
4777 rule(RuleNb,PragmaRule), precompute_head_matchings ==>
4778 PragmaRule = pragma(rule(H1,H2,_G,_B),_Ids,_Pragmas,_Name,_PrevRuleNb),
4779 append(H1,H2,Heads),
4780 make_head_matchings_explicit_(Heads,MatchingFreeHeads,Matchings),
4781 copy_term_nat(MatchingFreeHeads-Matchings,A-B),
4782 make_head_matchings_explicit_memo_table(RuleNb,A,B).
4784 precompute_head_matchings <=> true.
4786 :- chr_constraint make_head_matchings_explicit_memo_table/3.
4787 :- chr_constraint make_head_matchings_explicit_memo_lookup/3.
4789 :- chr_option(mode,make_head_matchings_explicit_memo_table(+,?,?)).
4790 :- chr_option(mode,make_head_matchings_explicit_memo_lookup(+,?,?)).
4792 make_head_matchings_explicit_memo_table(RuleNb,NHeads,Matchings) \
4793 make_head_matchings_explicit_memo_lookup(RuleNb,Q1,Q2)
4797 make_head_matchings_explicit_memo_lookup(_,_,_) <=> fail.
4799 make_head_matchings_explicit(RuleNb,MatchingFreeHeads,Matchings) :-
4800 make_head_matchings_explicit_memo_lookup(RuleNb,A,B),
4801 copy_term_nat(A-B,MatchingFreeHeads-Matchings).
4802 %-------------------------------------------------------------------------------%
4804 make_head_matchings_explicit_(Heads,MatchingFreeHeads,Matchings) :-
4805 extract_arguments(Heads,Arguments),
4806 make_matchings_explicit(Arguments,FreeVariables,[],[],_,Matchings),
4807 substitute_arguments(Heads,FreeVariables,MatchingFreeHeads).
4809 make_head_matchings_explicit_not_negated(Heads,MatchingFreeHeads,Matchings) :-
4810 extract_arguments(Heads,Arguments),
4811 make_matchings_explicit_not_negated(Arguments,FreshVariables,Matchings),
4812 substitute_arguments(Heads,FreshVariables,MatchingFreeHeads).
4814 make_head_matchings_explicit_not_negated2(Heads,MatchingFreeHeads,Matchings) :-
4815 extract_arguments(Heads,Arguments1),
4816 extract_arguments(MatchingFreeHeads,Arguments2),
4817 make_matchings_explicit_not_negated(Arguments1,Arguments2,Matchings).
4819 %% extract_arguments(+ListOfConstraints,-ListOfVariables) is det.
4821 % Returns list of arguments of given list of constraints.
4822 extract_arguments([],[]).
4823 extract_arguments([Constraint|Constraints],AllArguments) :-
4824 Constraint =.. [_|Arguments],
4825 append(Arguments,RestArguments,AllArguments),
4826 extract_arguments(Constraints,RestArguments).
4828 %% substitute_arguments(+InListOfConstraints,ListOfVariables,-OutListOfConstraints) is det.
4830 % Substitutes arguments of constraints with those in the given list.
4832 substitute_arguments([],[],[]).
4833 substitute_arguments([Constraint|Constraints],Variables,[NConstraint|NConstraints]) :-
4834 functor(Constraint,F,N),
4835 split_at(N,Variables,Arguments,RestVariables),
4836 NConstraint =.. [F|Arguments],
4837 substitute_arguments(Constraints,RestVariables,NConstraints).
4839 make_matchings_explicit([],[],_,MC,MC,[]).
4840 make_matchings_explicit([Arg|Args],[NewVar|NewVars],VarAcc,MatchingCondition,MatchingConditionO,Matchings) :-
4842 ( memberchk_eq(Arg,VarAcc) ->
4843 list2disj(MatchingCondition,MatchingCondition_disj),
4844 Matchings = [(MatchingCondition_disj ; NewVar == Arg)|RestMatchings], % or only = ??
4847 Matchings = RestMatchings,
4849 NVarAcc = [Arg|VarAcc]
4851 MatchingCondition2 = MatchingCondition
4854 Arg =.. [F|RecArgs],
4855 make_matchings_explicit(RecArgs,RecVars,VarAcc,MatchingCondition,MatchingCondition_,RecMatchings),
4856 FlatArg =.. [F|RecVars],
4857 ( RecMatchings == [] ->
4858 Matchings = [functor(NewVar,F,A)|RestMatchings]
4860 list2conj(RecMatchings,ArgM_conj),
4861 list2disj(MatchingCondition,MatchingCondition_disj),
4862 ArgM_ = (NewVar \= FlatArg ; MatchingCondition_disj ; ArgM_conj),
4863 Matchings = [ functor(NewVar,F,A) , ArgM_|RestMatchings]
4865 MatchingCondition2 = [ NewVar \= FlatArg |MatchingCondition_],
4866 term_variables(Args,ArgVars),
4867 append(ArgVars,VarAcc,NVarAcc)
4869 make_matchings_explicit(Args,NewVars,NVarAcc,MatchingCondition2,MatchingConditionO,RestMatchings).
4872 %% make_matchings_explicit_not_negated(+ListOfTerms,-ListOfVariables,-ListOfMatchings) is det.
4874 % Returns list of new variables and list of pairwise unifications between given list and variables.
4876 make_matchings_explicit_not_negated([],[],[]).
4877 make_matchings_explicit_not_negated([X|Xs],[Var|Vars],Matchings) :-
4878 Matchings = [Var = X|RMatchings],
4879 make_matchings_explicit_not_negated(Xs,Vars,RMatchings).
4881 %% apply_guard_wrt_term(+ListOfConstraints,+Goal,-NewListOfConstraints) is det.
4883 % (Partially) applies substitutions of =Goal= to given list.
4885 apply_guard_wrt_term([],_Guard,[]).
4886 apply_guard_wrt_term([Term|RH],Guard,[NTerm|RGH]) :-
4888 apply_guard_wrt_variable(Guard,Term,NTerm)
4891 apply_guard_wrt_term(HArgs,Guard,NewHArgs),
4892 NTerm =.. [F|NewHArgs]
4894 apply_guard_wrt_term(RH,Guard,RGH).
4896 %% apply_guard_wrt_variable(+Goal,+Variable,-NVariable) is det.
4898 % (Partially) applies goal =Guard= wrt variable.
4900 apply_guard_wrt_variable((Guard1,Guard2),Variable,NVariable) :- !,
4901 apply_guard_wrt_variable(Guard1,Variable,NVariable1),
4902 apply_guard_wrt_variable(Guard2,NVariable1,NVariable).
4903 apply_guard_wrt_variable(Guard,Variable,NVariable) :-
4904 ( Guard = (X = Y), Variable == X ->
4906 ; Guard = functor(AVariable,Functor,Arity), Variable == AVariable, ground(Functor), ground(Arity) ->
4907 functor(NVariable,Functor,Arity)
4909 NVariable = Variable
4913 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4914 % ALWAYS FAILING GUARDS
4915 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4917 prev_guard_list(RuleNb,H,G,GuardList,M,[]),rule(RuleNb,Rule)
4919 chr_pp_flag(check_impossible_rules,on),
4920 Rule = pragma(rule(_,_,G,_),_Ids,_Pragmas,_Name,RuleNb),
4922 append(M,GuardList,Info),
4923 append(Info,GL,GuardWithContext),
4924 guard_entailment:entails_guard(GuardWithContext,fail)
4926 chr_warning(weird_program,'Heads will never match or guard will always fail in ~@.\n\tThis rule will never fire!\n',[format_rule(Rule)]),
4927 set_all_passive(RuleNb).
4929 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4930 % HEAD SIMPLIFICATION
4931 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4933 % now we check the head matchings (guard may have been simplified meanwhile)
4934 prev_guard_list(RuleNb,H,G,GuardList,M,[]) \ rule(RuleNb,Rule)
4936 Rule = pragma(rule(Head1,Head2,G,B),Ids,Pragmas,Name,RuleNb),
4937 simplify_heads(M,GuardList,G,B,NewM,NewB),
4939 extract_arguments(Head1,VH1),
4940 extract_arguments(Head2,VH2),
4941 extract_arguments(H,VH),
4942 replace_some_heads(VH1,VH2,VH,NewM,H1,H2,G,B,NewB_),
4943 substitute_arguments(Head1,H1,NewH1),
4944 substitute_arguments(Head2,H2,NewH2),
4945 append(NewB,NewB_,NewBody),
4946 list2conj(NewBody,BodyMatchings),
4947 NewRule = pragma(rule(NewH1,NewH2,G,(BodyMatchings,B)),Ids,Pragmas,Name,RuleNb),
4948 (Head1 \== NewH1 ; Head2 \== NewH2 )
4950 rule(RuleNb,NewRule).
4952 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4953 % AUXILIARY PREDICATES (HEAD SIMPLIFICATION)
4954 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4956 replace_some_heads(H1,H2,NH,[],H1,H2,G,Body,[]) :- !.
4957 replace_some_heads([],[H2|RH2],[NH|RNH],[M|RM],[],[H2_|RH2_],G,Body,NewB) :- !,
4960 replace_some_heads([],RH2,RNH,RM,[],RH2_,G,Body,NewB)
4962 (M = functor(X,F,A), NH == X ->
4968 H2 =.. [F|OrigArgs],
4969 use_same_args(OrigArgs,A_args,A_args_,G,Body,NewB1),
4972 replace_some_heads([],RH2,RNH,RM,[],RH2_,G,Body,NewB2),
4973 append(NewB1,NewB2,NewB)
4976 replace_some_heads([],RH2,RNH,[M|RM],[],RH2_,G,Body,NewB)
4980 replace_some_heads([H1|RH1],H2,[NH|RNH],[M|RM],[H1_|RH1_],H2_,G,Body,NewB) :- !,
4983 replace_some_heads(RH1,H2,RNH,RM,RH1_,H2_,G,Body,NewB)
4985 (M = functor(X,F,A), NH == X ->
4991 H1 =.. [F|OrigArgs],
4992 use_same_args(OrigArgs,A_args,A_args_,G,Body,NewB1),
4995 replace_some_heads(RH1,H2,RNH,RM,RH1_,H2_,G,Body,NewB2),
4996 append(NewB1,NewB2,NewB)
4999 replace_some_heads(RH1,H2,RNH,[M|RM],RH1_,H2_,G,Body,NewB)
5003 use_same_args([],[],[],_,_,[]).
5004 use_same_args([OA|ROA],[NA|RNA],[Out|ROut],G,Body,NewB) :-
5007 use_same_args(ROA,RNA,ROut,G,Body,NewB).
5008 use_same_args([OA|ROA],[NA|RNA],[Out|ROut],G,Body,NewB) :-
5010 ( common_variables(OA,Body) ->
5011 NewB = [NA = OA|NextB]
5016 use_same_args(ROA,RNA,ROut,G,Body,NextB).
5019 simplify_heads([],_GuardList,_G,_Body,[],[]).
5020 simplify_heads([M|RM],GuardList,G,Body,NewM,NewB) :-
5022 ( (nonvar(B) ; common_variables(B,RM-GuardList)),
5023 guard_entailment:entails_guard(GuardList,(A=B)) ->
5024 ( common_variables(B,G-RM-GuardList) ->
5028 ( common_variables(B,Body) ->
5029 NewB = [A = B|NextB]
5036 ( nonvar(B), functor(B,BFu,BAr),
5037 guard_entailment:entails_guard([functor(A,BFu,BAr)|GuardList],(A=B)) ->
5039 ( common_variables(B,G-RM-GuardList) ->
5042 NewM = [functor(A,BFu,BAr)|NextM]
5049 simplify_heads(RM,[M|GuardList],G,Body,NextM,NextB).
5051 common_variables(B,G) :-
5052 term_variables(B,BVars),
5053 term_variables(G,GVars),
5054 intersect_eq(BVars,GVars,L),
5058 set_all_passive(RuleNb), occurrence(_,_,RuleNb,ID,_) ==> passive(RuleNb,ID).
5059 set_all_passive(_) <=> true.
5063 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5064 % OCCURRENCE SUBSUMPTION
5065 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5068 first_occ_in_rule/4,
5071 :- chr_option(mode,first_occ_in_rule(+,+,+,+)).
5072 :- chr_option(mode,next_occ_in_rule(+,+,+,+,+,+)).
5074 :- chr_constraint multiple_occ_constraints_checked/1.
5075 :- chr_option(mode,multiple_occ_constraints_checked(+)).
5077 prev_guard_list(RuleNb,H,G,GuardList,M,[]),
5078 occurrence(C,O,RuleNb,ID,_),
5079 occurrence(C,O2,RuleNb,ID2,_),
5082 multiple_occ_constraints_checked(Done)
5085 chr_pp_flag(occurrence_subsumption,on),
5086 Rule = pragma(rule(H1,H2,_G,_B),_Ids,_Pragmas,_Name,_RuleNb), % RuleNb == _RuleNb
5088 \+ tree_set_memberchk(C,Done)
5090 first_occ_in_rule(RuleNb,C,O,ID),
5091 tree_set_add(Done,C,NDone),
5092 multiple_occ_constraints_checked(NDone).
5094 % Find first occurrence of constraint =C= in rule =RuleNb=
5095 occurrence(C,O,RuleNb,ID,_) \ first_occ_in_rule(RuleNb,C,O2,_)
5099 first_occ_in_rule(RuleNb,C,O,ID).
5101 first_occ_in_rule(RuleNb,C,O,ID_o1)
5104 functor(FreshHead,F,A),
5105 next_occ_in_rule(RuleNb,C,O,ID_o1,[],FreshHead).
5107 % Skip passive occurrences.
5108 passive(RuleNb,ID_o2), occurrence(C,O2,RuleNb,ID_o2,_) \ next_occ_in_rule(RuleNb,C,O,ID_o1,Cond,FH)
5112 next_occ_in_rule(RuleNb,C,O2,ID_o1,NewCond,FH).
5114 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)
5117 Rule = pragma(rule(H1,H2,G,B),ids(ID1,ID2),_Pragmas,_Name,RuleNb)
5119 append(H1,H2,Heads),
5120 add_failing_occ(Rule,Heads,H,ID_o1,ExtraCond,FH,M,C,Repl),
5121 ( ExtraCond == [chr_pp_void_info] ->
5122 next_occ_in_rule(RuleNb,C,O2,ID_o2,Cond,FH)
5124 append(ExtraCond,Cond,NewCond),
5125 add_failing_occ(Rule,Heads,H,ID_o2,CheckCond,FH,M,C,Repl2),
5126 copy_term(GuardList,FGuardList),
5127 variable_replacement(GuardList,FGuardList,GLRepl),
5128 copy_with_variable_replacement(GuardList,GuardList2,Repl),
5129 copy_with_variable_replacement(GuardList,GuardList3_,Repl2),
5130 copy_with_variable_replacement(GuardList3_,GuardList3,GLRepl),
5131 append(NewCond,GuardList2,BigCond),
5132 append(BigCond,GuardList3,BigCond2),
5133 copy_with_variable_replacement(M,M2,Repl),
5134 copy_with_variable_replacement(M,M3,Repl2),
5135 append(M3,BigCond2,BigCond3),
5136 append([chr_pp_active_constraint(FH)|M2],BigCond3,Info),
5137 list2conj(CheckCond,OccSubsum),
5138 copy_term((NewCond,BigCond2,Info,OccSubsum,FH),(NewCond2,BigCond2_,Info2,OccSubsum2,FH2)),
5139 ( OccSubsum \= chr_pp_void_info ->
5140 ( guard_entailment:entails_guard(Info2,OccSubsum2) ->
5141 passive(RuleNb,ID_o2)
5148 next_occ_in_rule(RuleNb,C,O2,ID_o2,NewCond,FH)
5152 next_occ_in_rule(RuleNb,C,O,ID,Cond,Args)
5156 prev_guard_list(RuleNb,H,G,GuardList,M,[]), multiple_occ_constraints_checked(Done)
5160 add_failing_occ(Rule,Heads,NH,ID_o1,FailCond,FH,M,C,Repl) :-
5161 Rule = pragma(rule(H1,H2,G,B),ids(ID1,ID2),_Pragmas,_Name,RuleNb),
5162 append(ID2,ID1,IDs),
5163 missing_partner_cond(Heads,NH,IDs,ID_o1,MPCond,H,C),
5164 copy_term((H,Heads,NH),(FH2,FHeads,NH2)),
5165 variable_replacement((H,Heads,NH),(FH2,FHeads,NH2),Repl),
5166 copy_with_variable_replacement(G,FG,Repl),
5167 extract_explicit_matchings(FG,FG2),
5168 negate_b(FG2,NotFG),
5169 copy_with_variable_replacement(MPCond,FMPCond,Repl),
5170 ( subsumes(FH,FH2) ->
5171 FailCond = [(NotFG;FMPCond)]
5173 % in this case, not much can be done
5174 % e.g. c(f(...)), c(g(...)) <=> ...
5175 FailCond = [chr_pp_void_info]
5178 missing_partner_cond([],[],[],ID_o1,fail,H2,C).
5179 missing_partner_cond([H|Hs],[H2|H2s],[ID_o1|IDs],ID_o1,Cond,H,C) :- !,
5180 missing_partner_cond(Hs,H2s,IDs,ID_o1,Cond,H,C).
5181 missing_partner_cond([H|Hs],[NH|NHs],[ID|IDs],ID_o1,Cond,H2,F/A) :-
5182 Cond = (chr_pp_not_in_store(H);Cond1),
5183 missing_partner_cond(Hs,NHs,IDs,ID_o1,Cond1,H2,F/A).
5185 extract_explicit_matchings((A,B),D) :- !,
5186 ( extract_explicit_matchings(A) ->
5187 extract_explicit_matchings(B,D)
5190 extract_explicit_matchings(B,E)
5192 extract_explicit_matchings(A,D) :- !,
5193 ( extract_explicit_matchings(A) ->
5199 extract_explicit_matchings(A=B) :-
5200 var(A), var(B), !, A=B.
5201 extract_explicit_matchings(A==B) :-
5202 var(A), var(B), !, A=B.
5204 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5206 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5212 get_type_definition/2,
5213 get_constraint_type/2.
5216 :- chr_option(mode,type_definition(?,?)).
5217 :- chr_option(mode,get_type_definition(?,?)).
5218 :- chr_option(mode,type_alias(?,?)).
5219 :- chr_option(mode,constraint_type(+,+)).
5220 :- chr_option(mode,get_constraint_type(+,-)).
5222 assert_constraint_type(Constraint,ArgTypes) :-
5223 ( ground(ArgTypes) ->
5224 constraint_type(Constraint,ArgTypes)
5226 chr_error(type_error,'Declared argument types "~w" for constraint "~w" must be ground!\n',[ArgTypes,Constraint])
5229 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5230 % Consistency checks of type aliases
5232 type_alias(T1,T2) <=>
5235 chr_error(type_error,'Variable alias definition: "~w".\n',[(:- chr_type T1 == T2)]).
5237 type_alias(T1,T2) <=>
5240 chr_error(type_error,'Variable alias definition: "~w".\n',[(:- chr_type T1 == T2)]).
5242 type_alias(T,T2) <=>
5245 copy_term((T,T2),(X,Y)), subsumes(X,Y)
5247 chr_error(type_error,'Cyclic alias definition: "~w".\n',[(T == T2)]).
5249 type_alias(T1,A1), type_alias(T2,A2) <=>
5254 copy_term_nat(T1,T1_),
5255 copy_term_nat(T2,T2_),
5257 chr_error(type_error,
5258 '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_]).
5260 type_alias(T,B) \ type_alias(X,T2) <=>
5263 copy_term_nat((X,T2,T,B),(X2,T3,T1,D1)),
5266 % chr_info(type_information,'Inferring `~w\' from `~w\' and `~w\'.\n',[X2==D1,X==T2,T==B]),
5269 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5270 % Consistency checks of type definitions
5272 type_definition(T1,_), type_definition(T2,_)
5274 functor(T1,F,A), functor(T2,F,A)
5276 chr_error(type_error,'Multiple definitions for type: ~w/~w.\n',[F,A]).
5278 type_definition(T1,_), type_alias(T2,_)
5280 functor(T1,F,A), functor(T2,F,A)
5282 chr_error(type_error,'Multiple definitions for type, once in a type definition and once as a type alias: ~w/~w.\n',[F,A]).
5284 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5285 %% get_type_definition(+Type,-Definition) is semidet.
5286 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5288 get_type_definition(T,Def)
5292 chr_error(type_error,'Non-ground type in constraint definition: "~w".\n',[T]).
5294 type_alias(T,D) \ get_type_definition(T2,Def)
5296 nonvar(T),nonvar(T2),functor(T,F,A),functor(T2,F,A),
5297 copy_term_nat((T,D),(T1,D1)),T1=T2
5299 ( get_type_definition(D1,Def) ->
5302 chr_error(type_error,'Could not find type definition for "~w" (accessed via alias "~w").\n',[D1,T1]), fail
5305 type_definition(T,D) \ get_type_definition(T2,Def)
5307 nonvar(T),nonvar(T2),functor(T,F,A),functor(T2,F,A),
5308 copy_term_nat((T,D),(T1,D1)),T1=T2
5312 get_type_definition(Type,Def)
5314 atomic_builtin_type(Type,_,_)
5318 get_type_definition(Type,Def)
5320 compound_builtin_type(Type,_,_,_)
5324 get_type_definition(X,Y) <=> fail.
5326 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5327 %% get_type_definition_det(+Type,-Definition) is det.
5328 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5329 get_type_definition_det(Type,Definition) :-
5330 ( get_type_definition(Type,Definition) ->
5333 chr_error(type,'Could not find type definition for type `~w\'.\n',[Type])
5336 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5337 %% get_constraint_type(+ConstraintSymbol,-Types) is semidet.
5339 % Return argument types of =ConstraintSymbol=, but fails if none where
5341 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5342 constraint_type(C,T) \ get_constraint_type(C,Type) <=> Type = T.
5343 get_constraint_type(_,_) <=> fail.
5345 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5346 %% get_constraint_type_det(+ConstraintSymbol,-Types) is det.
5348 % Like =get_constraint_type/2=, but returns list of =any= types when
5349 % no types are declared.
5350 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5351 get_constraint_type_det(ConstraintSymbol,Types) :-
5352 ( get_constraint_type(ConstraintSymbol,Types) ->
5355 ConstraintSymbol = _ / N,
5356 replicate(N,any,Types)
5358 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5359 %% unalias_type(+Alias,-Type) is det.
5361 % Follows alias chain until base type is reached.
5362 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5363 :- chr_constraint unalias_type/2.
5366 unalias_type(Alias,BaseType)
5373 type_alias(AliasProtoType,ProtoType) \ unalias_type(Alias,BaseType)
5375 nonvar(AliasProtoType),
5377 functor(AliasProtoType,F,A),
5379 copy_term_nat((AliasProtoType,ProtoType),(AliasInstance,Type)),
5380 Alias = AliasInstance
5382 unalias_type(Type,BaseType).
5384 unalias_type_definition @
5385 type_definition(ProtoType,Definition) \ unalias_type(Alias,BaseType)
5389 functor(ProtoType,F,A),
5394 unalias_atomic_builtin @
5395 unalias_type(Alias,BaseType)
5397 atomic_builtin_type(Alias,_,_)
5401 unalias_compound_builtin @
5402 unalias_type(Alias,BaseType)
5404 compound_builtin_type(Alias,_,_,_)
5408 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5409 %% types_modes_condition(+Heads,+UnrollHeads,-Condition) is det.
5410 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5411 :- chr_constraint types_modes_condition/3.
5412 :- chr_option(mode,types_modes_condition(+,+,?)).
5413 :- chr_option(type_declaration,types_modes_condition(list,list,goal)).
5415 types_modes_condition([],[],T) <=> T=true.
5417 constraint_mode(F/A,Modes) \ types_modes_condition([Head|Heads],[UnrollHead|UnrollHeads],Condition)
5422 Condition = (ModesCondition, TypesCondition, RestCondition),
5423 modes_condition(Modes,Args,ModesCondition),
5424 get_constraint_type_det(F/A,Types),
5425 UnrollHead =.. [_|RealArgs],
5426 types_condition(Types,Args,RealArgs,Modes,TypesCondition),
5427 types_modes_condition(Heads,UnrollHeads,RestCondition).
5429 types_modes_condition([Head|_],_,_)
5432 chr_error(internal,'Mode information missing for ~w.\n',[F/A]).
5435 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5436 %% modes_condition(+Modes,+Args,-Condition) is det.
5438 % Return =Condition= on =Args= that checks =Modes=.
5439 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5440 modes_condition([],[],true).
5441 modes_condition([Mode|Modes],[Arg|Args],Condition) :-
5443 Condition = ( ground(Arg) , RCondition )
5445 Condition = ( var(Arg) , RCondition )
5447 Condition = RCondition
5449 modes_condition(Modes,Args,RCondition).
5451 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5452 %% types_condition(+Types,+Args,+UnrollArgs,+Modes,-Condition) is det.
5454 % Return =Condition= on =Args= that checks =Types= given =Modes=.
5455 % =UnrollArgs= controls the depth of type definition unrolling.
5456 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5457 types_condition([],[],[],[],true).
5458 types_condition([Type|Types],[Arg|Args],[UnrollArg|UnrollArgs],[Mode|Modes],(DisjTypeConditionList,RCondition)) :-
5460 TypeConditionList = [true] % TypeConditionList = [var(Arg)] already encoded in modes_condition
5462 get_type_definition_det(Type,Def),
5463 type_condition(Def,Arg,UnrollArg,Mode,TypeConditionList1),
5465 TypeConditionList = TypeConditionList1
5467 TypeConditionList = [(\+ ground(Arg))|TypeConditionList1]
5470 list2disj(TypeConditionList,DisjTypeConditionList),
5471 types_condition(Types,Args,UnrollArgs,Modes,RCondition).
5473 type_condition([],_,_,_,[]).
5474 type_condition([DefCase|DefCases],Arg,UnrollArg,Mode,[Condition|Conditions]) :-
5476 chr_error(type,'Unexpected variable type in type definition!\n',[]) % Condition = true
5477 ; atomic_builtin_type(DefCase,Arg,Condition) ->
5479 ; compound_builtin_type(DefCase,Arg,Condition,_) ->
5482 type_def_case_condition(DefCase,Arg,UnrollArg,Mode,Condition)
5484 type_condition(DefCases,Arg,UnrollArg,Mode,Conditions).
5486 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5487 :- chr_type atomic_builtin_type ---> any
5494 ; chr_identifier(any)
5495 ; /* all possible values are given
5498 ; /* all values of interest are given
5499 for the other values a handler is provided */
5500 chr_enum(list(any),any)
5501 ; /* all possible values appear in rule heads;
5502 to distinguish between multiple chr_constants
5505 ; /* all relevant values appear in rule heads;
5506 for other values a handler is provided */
5507 chr_constants(any,any).
5508 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5510 ast_atomic_builtin_type(Type,AstTerm,Goal) :-
5511 ast_term_to_term(AstTerm,Term),
5512 atomic_builtin_type(Type,Term,Goal).
5514 ast_compound_builtin_type(Type,AstTerm,Goal) :-
5515 ast_term_to_term(AstTerm,Term),
5516 compound_builtin_type(Type,Term,_,Goal).
5518 atomic_builtin_type(any,_Arg,true).
5519 atomic_builtin_type(dense_int,Arg,(integer(Arg),Arg>=0)).
5520 atomic_builtin_type(int,Arg,integer(Arg)).
5521 atomic_builtin_type(number,Arg,number(Arg)).
5522 atomic_builtin_type(float,Arg,float(Arg)).
5523 atomic_builtin_type(natural,Arg,(integer(Arg),Arg>=0)).
5524 atomic_builtin_type(chr_identifier,_Arg,true).
5526 compound_builtin_type(chr_constants(_),_Arg,true,true).
5527 compound_builtin_type(chr_constants(_,_),_Arg,true,true).
5528 compound_builtin_type(chr_identifier(_),_Arg,true,true).
5529 compound_builtin_type(chr_enum(Constants),Arg,(ground(Arg), memberchk(Arg,Constants)),
5530 once(( member(Constant,Constants),
5531 unifiable(Arg,Constant,_)
5535 compound_builtin_type(chr_enum(_,_),Arg,true,true).
5537 is_chr_constants_type(chr_constants(Key),Key,no).
5538 is_chr_constants_type(chr_constants(Key,ErrorHandler),Key,yes(ErrorHandler)).
5540 is_chr_enum_type(chr_enum(Constants), Constants, no).
5541 is_chr_enum_type(chr_enum(Constants,Handler), Constants, yes(Handler)).
5543 type_def_case_condition(DefCase,Arg,UnrollArg,Mode,Condition) :-
5544 ( nonvar(DefCase) ->
5545 functor(DefCase,F,A),
5547 Condition = (Arg = DefCase)
5549 Condition = functor(Arg,F,A)
5550 ; functor(UnrollArg,F,A) ->
5551 Condition = (functor(Arg,F,A),Arg=Template,ArgsCondition),
5552 DefCase =.. [_|ArgTypes],
5553 UnrollArg =.. [_|UnrollArgs],
5554 functor(Template,F,A),
5555 Template =.. [_|TemplateArgs],
5556 replicate(A,Mode,ArgModes),
5557 types_condition(ArgTypes,TemplateArgs,UnrollArgs,ArgModes,ArgsCondition)
5559 Condition = functor(Arg,F,A)
5562 chr_error(internal,'Illegal type definition (must be nonvar).\n',[])
5566 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5567 % STATIC TYPE CHECKING
5568 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5569 % Checks head constraints and CHR constraint calls in bodies.
5572 % - type clashes involving built-in types
5573 % - Prolog built-ins in guard and body
5574 % - indicate position in terms in error messages
5575 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5577 static_type_check/2.
5579 % 1. Check the declared types
5581 constraint_type(Constraint,ArgTypes), static_type_check(_,_)
5584 ( member(ArgType,ArgTypes), sub_term(ArgType,Type) ),
5585 ( get_type_definition(Type,_) ->
5588 chr_error(type_error,'Undefined type "~w" used in type declaration of "~w".\n',[Type,Constraint])
5592 % 2. Check the rules
5594 :- chr_type type_error_src ---> head(any) ; body(any).
5596 static_type_check(PragmaRules,AstRules)
5598 maplist(static_type_check_rule,PragmaRules,AstRules).
5600 static_type_check_rule(PragmaRule,AstRule) :-
5601 AstRule = ast_rule(AstHead,_AstGuard,_Guard,AstBody,_Body),
5604 ( ast_static_type_check_head(AstHead),
5605 ast_static_type_check_body(AstBody)
5608 ( Error = invalid_functor(Src,Term,Type) ->
5609 chr_error(type_error,'Invalid functor in ~@ of ~@:\n\t\tfound `~w\',\n\t\texpected type `~w\'!\n',
5610 [chr_translate:format_src(Src),format_rule(PragmaRule),Term,Type])
5611 ; Error = type_clash(Var,Src1,Src2,Type1,Type2) ->
5612 chr_error(type_error,'Type clash for variable ~w in ~@:\n\t\texpected type ~w in ~@\n\t\texpected type ~w in ~@\n',
5613 [Var,format_rule(PragmaRule),Type1,chr_translate:format_src(Src1),Type2,chr_translate:format_src(Src2)])
5616 fail % cleanup constraints
5621 %------------------------------------------------------------------------------%
5622 % Static Type Checking: Head Constraints {{{
5623 ast_static_type_check_head(simplification(AstConstraints)) :-
5624 maplist(ast_static_type_check_head_constraint,AstConstraints).
5625 ast_static_type_check_head(propagation(AstConstraints)) :-
5626 maplist(ast_static_type_check_head_constraint,AstConstraints).
5627 ast_static_type_check_head(simpagation(AstConstraints1,AstConstraints2)) :-
5628 maplist(ast_static_type_check_head_constraint,AstConstraints1),
5629 maplist(ast_static_type_check_head_constraint,AstConstraints2).
5631 ast_static_type_check_head_constraint(AstConstraint) :-
5632 AstConstraint = chr_constraint(Symbol,Arguments,_),
5633 get_constraint_type_det(Symbol,Types),
5634 maplist(ast_static_type_check_term(head(Head)),Arguments,Types).
5636 %------------------------------------------------------------------------------%
5637 % Static Type Checking: Terms {{{
5638 :- chr_constraint ast_static_type_check_term/3.
5639 :- chr_option(mode,ast_static_type_check_term(?,?,?)).
5640 :- chr_option(type_declaration,ast_static_type_check_term(type_error_src,any,any)).
5642 ast_static_type_check_term(_,_,any)
5646 ast_static_type_check_term(Src,var(Id,Var),Type)
5648 ast_static_type_check_var(Id,var(Id,Var),Type,Src).
5650 ast_static_type_check_term(Src,Term,Type)
5652 ast_atomic_builtin_type(Type,Term,Goal)
5657 throw(type_error(invalid_functor(Src,Term,Type)))
5659 ast_static_type_check_term(Src,Term,Type)
5661 ast_compound_builtin_type(Type,Term,Goal)
5666 throw(type_error(invalid_functor(Src,Term,Type)))
5668 type_alias(AType,ADef) \ ast_static_type_check_term(Src,Term,Type)
5673 copy_term_nat(AType-ADef,Type-Def),
5674 ast_static_type_check_term(Src,Term,Def).
5676 type_definition(AType,ADef) \ ast_static_type_check_term(Src,Term,Type)
5681 copy_term_nat(AType-ADef,Type-Variants),
5682 ast_functor(Term,TF,TA),
5683 ( member(Variant,Variants), functor(Variant,TF,TA) ->
5684 ast_args(Term,Args),
5685 Variant =.. [_|Types],
5686 maplist(ast_static_type_check_term(Src),Args,Types)
5688 throw(type_error(invalid_functor(Src,Term,Type)))
5691 ast_static_type_check_term(Src,Term,Type)
5693 chr_error(internal,'Undefined type ~w while type checking term ~w in ~@.\n',[Type,Term,chr_translate:format_src(Src)]).
5695 %------------------------------------------------------------------------------%
5696 % Static Type Checking: Variables {{{
5698 :- chr_constraint ast_static_type_check_var/4.
5699 :- chr_option(mode,ast_static_type_check_var(+,?,?,?)).
5700 :- chr_option(type_declaration,ast_static_type_check_var(var_id,any,any,type_error_src)).
5702 type_alias(AType,ADef) \ ast_static_type_check_var(VarId,Var,Type,Src)
5707 copy_term_nat(AType-ADef,Type-Def),
5708 ast_static_type_check_var(VarId,Var,Def,Src).
5710 ast_static_type_check_var(VarId,Var,Type,Src)
5712 atomic_builtin_type(Type,_,_)
5714 ast_static_atomic_builtin_type_check_var(VarId,Var,Type,Src).
5716 ast_static_type_check_var(VarId,Var,Type,Src)
5718 compound_builtin_type(Type,_,_,_)
5723 ast_static_type_check_var(VarId,Var,Type1,Src1), ast_static_type_check_var(VarId,_Var,Type2,Src2)
5727 throw(type_error(type_clash(Var,Src1,Src2,Type1,Type2))).
5729 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5730 :- chr_constraint ast_static_atomic_builtin_type_check_var/4.
5731 :- chr_option(mode,ast_static_atomic_builtin_type_check_var(+,?,+,?)).
5732 :- chr_option(type_declaration,ast_static_atomic_builtin_type_check_var(var_id,any,atomic_builtin_type,type_error_src)).
5734 ast_static_atomic_builtin_type_check_var(_,_,any,_) <=> true.
5735 ast_static_atomic_builtin_type_check_var(VarId,_,BuiltinType,_) \ ast_static_atomic_builtin_type_check_var(VarId,_,BuiltinType,_)
5738 ast_static_atomic_builtin_type_check_var(VarId,_,float,_) \ ast_static_atomic_builtin_type_check_var(VarId,_,number,_)
5741 ast_static_atomic_builtin_type_check_var(VarId,_,int,_) \ ast_static_atomic_builtin_type_check_var(VarId,_,number,_)
5744 ast_static_atomic_builtin_type_check_var(VarId,_,natural,_) \ ast_static_atomic_builtin_type_check_var(VarId,_,number,_)
5747 ast_static_atomic_builtin_type_check_var(VarId,_,dense_int,_) \ ast_static_atomic_builtin_type_check_var(VarId,_,number,_)
5750 ast_static_atomic_builtin_type_check_var(VarId,_,natural,_) \ ast_static_atomic_builtin_type_check_var(VarId,_,int,_)
5753 ast_static_atomic_builtin_type_check_var(VarId,_,dense_int,_) \ ast_static_atomic_builtin_type_check_var(VarId,_,int,_)
5756 ast_static_atomic_builtin_type_check_var(VarId,_,dense_int,_) \ ast_static_atomic_builtin_type_check_var(VarId,_,natural,_)
5759 ast_static_atomic_builtin_type_check_var(VarId,Var,Type1,Src1), ast_static_atomic_builtin_type_check_var(VarId,_Var,Type2,Src2)
5761 throw(type_error(type_clash(Var,Src1,Src2,Type1,Type2))).
5763 %------------------------------------------------------------------------------%
5764 % Static Type Checking: Bodies {{{
5765 ast_static_type_check_body([]).
5766 ast_static_type_check_body([Goal|Goals]) :-
5767 ast_symbol(Goal,Symbol),
5768 get_constraint_type_det(Symbol,Types),
5769 ast_args(Goal,Args),
5770 maplist(ast_static_type_check_term(body(Goal)),Args,Types),
5771 ast_static_type_check_body(Goals).
5774 %------------------------------------------------------------------------------%
5776 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5777 %% format_src(+type_error_src) is det.
5778 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5779 format_src(head(Head)) :- format('head ~w',[Head]).
5780 format_src(body(Goal)) :- format('body goal ~w',[Goal]).
5782 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5783 % Dynamic type checking
5784 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5787 dynamic_type_check/0,
5788 dynamic_type_check_clauses/1,
5789 get_dynamic_type_check_clauses/1.
5791 generate_dynamic_type_check_clauses(Clauses) :-
5792 ( chr_pp_flag(debugable,on) ->
5794 get_dynamic_type_check_clauses(Clauses0),
5796 [('$dynamic_type_check'(Type,Term) :-
5797 throw(error(type_error(Type,Term),context(_,'CHR Runtime Type Error')))
5804 type_definition(T,D), dynamic_type_check
5806 copy_term_nat(T-D,Type-Definition),
5807 maplist(dynamic_type_check_clause(Type),Definition,DynamicChecks),
5808 dynamic_type_check_clauses(DynamicChecks).
5809 type_alias(A,B), dynamic_type_check
5811 copy_term_nat(A-B,Alias-Body),
5812 dynamic_type_check_alias_clause(Alias,Body,Clause),
5813 dynamic_type_check_clauses([Clause]).
5815 dynamic_type_check <=>
5817 ('$dynamic_type_check'(Type,Term) :- Goal),
5818 ( atomic_builtin_type(Type,Term,Goal) ; compound_builtin_type(Type,Term,Goal,_) ),
5821 dynamic_type_check_clauses(BuiltinChecks).
5823 dynamic_type_check_clause(T,DC,Clause) :-
5824 copy_term(T-DC,Type-DefinitionClause),
5825 functor(DefinitionClause,F,A),
5827 DefinitionClause =.. [_|DCArgs],
5828 Term =.. [_|TermArgs],
5829 maplist(dynamic_type_check_call,DCArgs,TermArgs,RecursiveCallList),
5830 list2conj(RecursiveCallList,RecursiveCalls),
5832 '$dynamic_type_check'(Type,Term) :-
5836 dynamic_type_check_alias_clause(Alias,Body,Clause) :-
5838 '$dynamic_type_check'(Alias,Term) :-
5839 '$dynamic_type_check'(Body,Term)
5842 dynamic_type_check_call(Type,Term,Call) :-
5843 % ( nonvar(Type), atomic_builtin_type(Type,Term,Goal) ->
5844 % Call = when(nonvar(Term),Goal)
5845 % ; nonvar(Type), compound_builtin_type(Type,Term,Goal) ->
5846 % Call = when(nonvar(Term),Goal)
5851 Call = when(nonvar(Term),once('$dynamic_type_check'(Type,Term)))
5856 dynamic_type_check_clauses(C1), dynamic_type_check_clauses(C2)
5859 dynamic_type_check_clauses(C).
5861 get_dynamic_type_check_clauses(Q), dynamic_type_check_clauses(C)
5864 get_dynamic_type_check_clauses(Q)
5868 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5870 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5871 % Some optimizations can be applied for atomic types...
5872 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5874 atomic_types_suspended_constraint(C) :-
5876 get_constraint_type(C,ArgTypes),
5877 get_constraint_mode(C,ArgModes),
5878 numlist(1,N,Indexes),
5879 maplist(atomic_types_suspended_constraint(C),ArgTypes,ArgModes,Indexes).
5881 atomic_types_suspended_constraint(C,Type,Mode,Index) :-
5882 ( is_indexed_argument(C,Index) ->
5892 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5893 %% atomic_type(+Type) is semidet.
5895 % Succeeds when all values of =Type= are atomic.
5896 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5897 :- chr_constraint atomic_type/1.
5899 atomic_type(Type) <=> atomic_builtin_type(Type,_,_) | Type \== any.
5901 type_definition(TypePat,Def) \ atomic_type(Type)
5903 functor(Type,F,A), functor(TypePat,F,A)
5905 maplist(atomic,Def).
5907 type_alias(TypePat,Alias) \ atomic_type(Type)
5909 functor(Type,F,A), functor(TypePat,F,A)
5912 copy_term_nat(TypePat-Alias,Type-NType),
5915 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5916 %% enumerated_atomic_type(+Type,-Atoms) is semidet.
5918 % Succeeds when all values of =Type= are atomic
5919 % and the atom values are finitely enumerable.
5920 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5921 :- chr_constraint enumerated_atomic_type/2.
5923 enumerated_atomic_type(Type,_) <=> atomic_builtin_type(Type,_,_) | fail.
5925 type_definition(TypePat,Def) \ enumerated_atomic_type(Type,Atoms)
5927 functor(Type,F,A), functor(TypePat,F,A)
5929 maplist(atomic,Def),
5932 type_alias(TypePat,Alias) \ enumerated_atomic_type(Type,Atoms)
5934 functor(Type,F,A), functor(TypePat,F,A)
5937 copy_term_nat(TypePat-Alias,Type-NType),
5938 enumerated_atomic_type(NType,Atoms).
5940 enumerated_atomic_type(_,_)
5943 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5946 stored/3, % constraint,occurrence,(yes/no/maybe)
5947 stored_completing/3,
5950 is_finally_stored/1,
5951 check_all_passive/2.
5953 :- chr_option(mode,stored(+,+,+)).
5954 :- chr_option(type_declaration,stored(any,int,storedinfo)).
5955 :- chr_type storedinfo ---> yes ; no ; maybe.
5956 :- chr_option(mode,stored_complete(+,+,+)).
5957 :- chr_option(mode,maybe_complementary_guards(+,+,?,?)).
5958 :- chr_option(mode,guard_list(+,+,+,+)).
5959 :- chr_option(mode,check_all_passive(+,+)).
5960 :- chr_option(type_declaration,check_all_passive(any,list)).
5962 % change yes in maybe when yes becomes passive
5963 passive(RuleNb,ID), occurrence(C,O,RuleNb,ID,_) \
5964 stored(C,O,yes), stored_complete(C,RO,Yesses)
5965 <=> O < RO | NYesses is Yesses - 1,
5966 stored(C,O,maybe), stored_complete(C,RO,NYesses).
5967 % change yes in maybe when not observed
5968 ai_not_observed(C,O) \ stored(C,O,yes), stored_complete(C,RO,Yesses)
5970 NYesses is Yesses - 1,
5971 stored(C,O,maybe), stored_complete(C,RO,NYesses).
5973 occurrence(_,_,RuleNb,ID,_), occurrence(C2,_,RuleNb,_,_), stored_complete(C2,RO,0), max_occurrence(C2,MO2)
5974 ==> RO =< MO2 | % C2 is never stored
5980 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5982 rule(RuleNb,Rule),passive(RuleNb,Id) ==>
5983 Rule = pragma(rule(Head1,Head2,G,B),ids([Id|IDs1],IDs2),Pragmas,Name,RuleNb) |
5984 append(IDs1,IDs2,I), check_all_passive(RuleNb,I).
5986 rule(RuleNb,Rule),passive(RuleNb,Id) ==>
5987 Rule = pragma(rule(Head1,Head2,G,B),ids([],[Id|IDs2]),Pragmas,Name,RuleNb) |
5988 check_all_passive(RuleNb,IDs2).
5990 passive(RuleNb,Id) \ check_all_passive(RuleNb,[Id|IDs]) <=>
5991 check_all_passive(RuleNb,IDs).
5993 rule(RuleNb,Rule) \ check_all_passive(RuleNb,[]) <=>
5994 chr_warning(weird_program,'All heads passive in ~@.\n\tThis rule never fires. Please check your program.\n',[format_rule(Rule)]).
5996 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5998 % collect the storage information
5999 stored(C,O,yes) \ stored_completing(C,O,Yesses)
6000 <=> NO is O + 1, NYesses is Yesses + 1,
6001 stored_completing(C,NO,NYesses).
6002 stored(C,O,maybe) \ stored_completing(C,O,Yesses)
6004 stored_completing(C,NO,Yesses).
6006 stored(C,O,no) \ stored_completing(C,O,Yesses)
6007 <=> stored_complete(C,O,Yesses).
6008 stored_completing(C,O,Yesses)
6009 <=> stored_complete(C,O,Yesses).
6011 stored_complete(C,O,Yesses), occurrence(C,O2,RuleNb,Id,_) ==>
6012 O2 > O | passive(RuleNb,Id).
6014 % decide whether a constraint is stored
6015 max_occurrence(C,MO), stored_complete(C,RO,0) \ is_stored(C)
6016 <=> RO =< MO | fail.
6017 is_stored(C) <=> true.
6019 % decide whether a constraint is suspends after occurrences
6020 max_occurrence(C,MO), stored_complete(C,RO,_) \ is_finally_stored(C)
6021 <=> RO =< MO | fail.
6022 is_finally_stored(C) <=> true.
6024 storage_analysis(Constraints) :-
6025 ( chr_pp_flag(storage_analysis,on) ->
6026 check_constraint_storages(Constraints)
6031 check_constraint_storages(Symbols) :- maplist(check_constraint_storage,Symbols).
6033 check_constraint_storage(C) :-
6034 get_max_occurrence(C,MO),
6035 check_occurrences_storage(C,1,MO).
6037 check_occurrences_storage(C,O,MO) :-
6039 stored_completing(C,1,0)
6041 check_occurrence_storage(C,O),
6043 check_occurrences_storage(C,NO,MO)
6046 check_occurrence_storage(C,O) :-
6047 get_occurrence(C,O,RuleNb,ID,OccType),
6048 ( is_passive(RuleNb,ID) ->
6051 get_rule(RuleNb,PragmaRule),
6052 PragmaRule = pragma(rule(Heads1,Heads2,Guard,Body),ids(IDs1,IDs2),_,_,_),
6053 ( OccType == simplification, select2(ID,Head1,IDs1,Heads1,RIDs1,RHeads1) ->
6054 check_storage_head1(Head1,O,Heads1,Heads2,Guard)
6055 ; OccType == propagation, select2(ID,Head2,IDs2,Heads2,RIDs2,RHeads2) ->
6056 check_storage_head2(Head2,O,Heads1,Body)
6060 check_storage_head1(Head,O,H1,H2,G) :-
6065 % writeq(guard_entailment:entails_guard([chr_pp_headvariables(Head)],G)),nl,
6066 guard_entailment:entails_guard([chr_pp_headvariables(Head)],G),
6068 no_matching(L,[]) ->
6075 no_matching([X|Xs],Prev) :-
6077 \+ memberchk_eq(X,Prev),
6078 no_matching(Xs,[X|Prev]).
6080 check_storage_head2(Head,O,H1,B) :-
6084 ( H1 \== [], B == true )
6086 % \+ is_observed(F/A,O) % always fails because observation analysis has not been performed yet
6094 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6096 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6097 %% ____ _ ____ _ _ _ _
6098 %% | _ \ _ _| | ___ / ___|___ _ __ ___ _ __ (_) | __ _| |_(_) ___ _ __
6099 %% | |_) | | | | |/ _ \ | | / _ \| '_ ` _ \| '_ \| | |/ _` | __| |/ _ \| '_ \
6100 %% | _ <| |_| | | __/ | |__| (_) | | | | | | |_) | | | (_| | |_| | (_) | | | |
6101 %% |_| \_\\__,_|_|\___| \____\___/|_| |_| |_| .__/|_|_|\__,_|\__|_|\___/|_| |_|
6104 constraints_code(Constraints,Clauses) :-
6105 (chr_pp_flag(reduced_indexing,on),
6106 forall(C,Constraints,chr_translate:only_ground_indexed_arguments(C)) ->
6107 none_suspended_on_variables
6111 constraints_code1(Constraints,Clauses,[]).
6113 %===============================================================================
6114 :- chr_constraint constraints_code1/3.
6115 :- chr_option(mode,constraints_code1(+,+,+)).
6116 :- chr_option(type_declaration,constraints_code1(list,any,any)).
6117 %-------------------------------------------------------------------------------
6118 constraints_code1([],L,T) <=> L = T.
6119 constraints_code1([C|RCs],L,T)
6121 constraint_code(C,L,T1),
6122 constraints_code1(RCs,T1,T).
6123 %===============================================================================
6124 :- chr_constraint constraint_code/3.
6125 :- chr_option(mode,constraint_code(+,+,+)).
6126 %-------------------------------------------------------------------------------
6127 %% Generate code for a single CHR constraint
6128 constraint_code(Constraint, L, T)
6130 | ( (chr_pp_flag(debugable,on) ;
6131 is_stored(Constraint), ( has_active_occurrence(Constraint); chr_pp_flag(late_allocation,off)),
6132 ( may_trigger(Constraint) ;
6133 get_allocation_occurrence(Constraint,AO),
6134 get_max_occurrence(Constraint,MO), MO >= AO ) )
6136 constraint_prelude(Constraint,Clause),
6137 add_dummy_location(Clause,LocatedClause),
6138 L = [LocatedClause | L1]
6143 occurrences_code(Constraint,1,Id,NId,L1,L2),
6144 gen_cond_attach_clause(Constraint,NId,L2,T).
6146 %===============================================================================
6147 %% Generate prelude predicate for a constraint.
6148 %% f(...) :- f/a_0(...,Susp).
6149 constraint_prelude(F/A, Clause) :-
6150 vars_susp(A,Vars,Susp,VarsSusp),
6151 Head =.. [ F | Vars],
6152 make_suspension_continuation_goal(F/A,VarsSusp,Continuation),
6153 build_head(F,A,[0],VarsSusp,Delegate),
6154 ( chr_pp_flag(debugable,on) ->
6155 insert_constraint_goal(F/A,Susp,Vars,InsertCall),
6156 attach_constraint_atom(F/A,Vars2,Susp,AttachCall),
6157 delay_phase_end(validate_store_type_assumptions,chr_translate:update_suspension_field(F/A,Susp,state,inactive,Inactive)),
6158 insert_constraint_internal_constraint_goal(F/A, Vars2, Susp, Continuation, Vars,InsertGoal),
6160 ( get_constraint_type(F/A,ArgTypeList) ->
6161 maplist(dynamic_type_check_call,ArgTypeList,Vars,DynamicTypeCheckList),
6162 list2conj(DynamicTypeCheckList,DynamicTypeChecks)
6164 DynamicTypeChecks = true
6174 'chr debug_event'(insert(Head#Susp)),
6176 'chr debug_event'(call(Susp)),
6179 'chr debug_event'(fail(Susp)), !,
6183 'chr debug_event'(exit(Susp))
6185 'chr debug_event'(redo(Susp)),
6189 ; get_allocation_occurrence(F/A,0) ->
6190 gen_insert_constraint_internal_goal(F/A,Goal,VarsSusp,Vars,Susp),
6191 delay_phase_end(validate_store_type_assumptions,chr_translate:update_suspension_field(F/A,Susp,state,inactive,Inactive)),
6192 Clause = ( Head :- Goal, Inactive, Delegate )
6194 Clause = ( Head :- Delegate )
6197 make_suspension_continuation_goal(F/A,VarsSusp,Goal) :-
6198 ( may_trigger(F/A) ->
6199 build_head(F,A,[0],VarsSusp,Delegate),
6200 ( chr_pp_flag(debugable,off) ->
6203 get_target_module(Mod),
6210 %===============================================================================
6211 :- chr_constraint has_active_occurrence/1, has_active_occurrence/2.
6212 :- chr_option(mode,has_active_occurrence(+)).
6213 :- chr_option(mode,has_active_occurrence(+,+)).
6215 :- chr_constraint memo_has_active_occurrence/1.
6216 :- chr_option(mode,memo_has_active_occurrence(+)).
6217 %-------------------------------------------------------------------------------
6218 memo_has_active_occurrence(C) \ has_active_occurrence(C) <=> true.
6219 has_active_occurrence(C) <=> has_active_occurrence(C,1), memo_has_active_occurrence(C).
6221 max_occurrence(C,MO) \ has_active_occurrence(C,O) <=>
6223 passive(RuleNb,ID),occurrence(C,O,RuleNb,ID,_) \
6224 has_active_occurrence(C,O) <=>
6226 has_active_occurrence(C,NO).
6227 has_active_occurrence(C,O) <=> true.
6228 %===============================================================================
6230 gen_cond_attach_clause(F/A,Id,L,T) :-
6231 ( is_finally_stored(F/A) ->
6232 get_allocation_occurrence(F/A,AllocationOccurrence),
6233 get_max_occurrence(F/A,MaxOccurrence),
6234 ( chr_pp_flag(debugable,off), MaxOccurrence < AllocationOccurrence ->
6235 ( only_ground_indexed_arguments(F/A) ->
6236 gen_insert_constraint_internal_goal(F/A,Body,AllArgs,Args,Susp)
6238 gen_cond_attach_goal(F/A,Body,AllArgs,Args,Susp)
6240 ; vars_susp(A,Args,Susp,AllArgs),
6241 gen_uncond_attach_goal(F/A,Susp,Args,Body,_)
6243 build_head(F,A,Id,AllArgs,Head),
6244 Clause = ( Head :- Body ),
6245 add_dummy_location(Clause,LocatedClause),
6246 L = [LocatedClause | T]
6251 :- chr_constraint use_auxiliary_predicate/1.
6252 :- chr_option(mode,use_auxiliary_predicate(+)).
6254 :- chr_constraint use_auxiliary_predicate/2.
6255 :- chr_option(mode,use_auxiliary_predicate(+,+)).
6257 :- chr_constraint is_used_auxiliary_predicate/1.
6258 :- chr_option(mode,is_used_auxiliary_predicate(+)).
6260 :- chr_constraint is_used_auxiliary_predicate/2.
6261 :- chr_option(mode,is_used_auxiliary_predicate(+,+)).
6264 use_auxiliary_predicate(P) \ use_auxiliary_predicate(P) <=> true.
6266 use_auxiliary_predicate(P,C) \ use_auxiliary_predicate(P,C) <=> true.
6268 use_auxiliary_predicate(P) \ is_used_auxiliary_predicate(P) <=> true.
6270 use_auxiliary_predicate(P,_) \ is_used_auxiliary_predicate(P) <=> true.
6272 is_used_auxiliary_predicate(P) <=> fail.
6274 use_auxiliary_predicate(P) \ is_used_auxiliary_predicate(P,_) <=> true.
6275 use_auxiliary_predicate(P,C) \ is_used_auxiliary_predicate(P,C) <=> true.
6277 is_used_auxiliary_predicate(P,C) <=> fail.
6279 %------------------------------------------------------------------------------%
6280 % Only generate import statements for actually used modules.
6281 %------------------------------------------------------------------------------%
6283 :- chr_constraint use_auxiliary_module/1.
6284 :- chr_option(mode,use_auxiliary_module(+)).
6286 :- chr_constraint is_used_auxiliary_module/1.
6287 :- chr_option(mode,is_used_auxiliary_module(+)).
6290 use_auxiliary_module(P) \ use_auxiliary_module(P) <=> true.
6292 use_auxiliary_module(P) \ is_used_auxiliary_module(P) <=> true.
6294 is_used_auxiliary_module(P) <=> fail.
6296 % only called for constraints with
6298 % non-ground indexed argument
6299 gen_cond_attach_goal(F/A,Goal,AllArgs,Args,Susp) :-
6300 vars_susp(A,Args,Susp,AllArgs),
6301 make_suspension_continuation_goal(F/A,AllArgs,Closure),
6302 ( get_store_type(F/A,var_assoc_store(_,_)) ->
6305 attach_constraint_atom(F/A,Vars,Susp,Attach)
6308 insert_constraint_goal(F/A,Susp,Args,InsertCall),
6309 insert_constraint_internal_constraint_goal(F/A, Vars, Susp, Closure, Args,InsertGoal),
6310 ( may_trigger(F/A) ->
6311 activate_constraint_goal(F/A,(InsertCall,Attach),Vars,Susp,_,ActivateGoal),
6315 InsertGoal, % insert_constraint_internal(Stored,Vars,Susp,Closure,F,Args)
6319 ActivateGoal % activate_constraint(Stored,Vars,Susp,_)
6325 InsertGoal, % insert_constraint_internal(Stored,Vars,Susp,Closure,F,Args),
6331 gen_insert_constraint_internal_goal(F/A,Goal,AllArgs,Args,Susp) :-
6332 vars_susp(A,Args,Susp,AllArgs),
6333 make_suspension_continuation_goal(F/A,AllArgs,Cont),
6334 ( \+ only_ground_indexed_arguments(F/A), \+ get_store_type(F/A,var_assoc_store(_,_)) ->
6335 attach_constraint_atom(F/A,Vars,Susp,Attach)
6340 insert_constraint_goal(F/A,Susp,Args,InsertCall),
6341 insert_constraint_internal_constraint_goal(F/A, Vars, Susp, Cont, Args,InsertInternalGoal),
6342 ( only_ground_indexed_arguments(F/A), chr_pp_flag(debugable,off) ->
6345 InsertInternalGoal, % insert_constraint_internal(Susp,F,Args),
6351 InsertInternalGoal, % insert_constraint_internal(_,Vars,Susp,Cont,F,Args),
6357 gen_uncond_attach_goal(FA,Susp,Args,AttachGoal,Generation) :-
6358 ( \+ only_ground_indexed_arguments(FA), \+ get_store_type(FA,var_assoc_store(_,_)) ->
6359 attach_constraint_atom(FA,Vars,Susp,Attach)
6363 insert_constraint_goal(FA,Susp,Args,InsertCall),
6364 ( chr_pp_flag(late_allocation,on) ->
6365 activate_constraint_goal(FA,(InsertCall,Attach),Vars,Susp,Generation,AttachGoal)
6367 activate_constraint_goal(FA,true,Vars,Susp,Generation,AttachGoal)
6370 %-------------------------------------------------------------------------------
6371 :- chr_constraint occurrences_code/6.
6372 :- chr_option(mode,occurrences_code(+,+,+,+,+,+)).
6373 %-------------------------------------------------------------------------------
6374 max_occurrence(C,MO) \ occurrences_code(C,O,Id,NId,L,T)
6377 occurrences_code(C,O,Id,NId,L,T)
6379 occurrence_code(C,O,Id,Id1,L,L1),
6381 occurrences_code(C,NO,Id1,NId,L1,T).
6382 %-------------------------------------------------------------------------------
6383 :- chr_constraint occurrence_code/6.
6384 :- chr_option(mode,occurrence_code(+,+,+,+,+,+)).
6385 %-------------------------------------------------------------------------------
6386 occurrence(C,O,RuleNb,ID,_), passive(RuleNb,ID) \ occurrence_code(C,O,Id,NId,L,T)
6388 ( named_history(RuleNb,_,_) ->
6389 does_use_history(C,O)
6395 occurrence(C,O,RuleNb,ID,_), rule(RuleNb,PragmaRule) \ occurrence_code(C,O,Id,NId,L,T)
6397 PragmaRule = pragma(rule(Heads1,Heads2,_,_),ids(IDs1,IDs2),_,_,_),
6398 ( select2(ID,Head1,IDs1,Heads1,RIDs1,RHeads1) ->
6400 head1_code(Head1,ID,RHeads1,RIDs1,PragmaRule,C,O,Id,L,T)
6401 ; select2(ID,Head2,IDs2,Heads2,RIDs2,RHeads2) ->
6403 head2_code(Head2,ID,RHeads2,RIDs2,PragmaRule,C,O,Id,L,L1),
6404 ( should_skip_to_next_id(C,O) ->
6406 ( unconditional_occurrence(C,O) ->
6409 gen_alloc_inc_clause(C,O,Id,L1,T)
6417 occurrence_code(C,O,_,_,_,_)
6419 chr_error(internal,'occurrence_code/6: missing information to compile ~w:~w\n',[C,O]).
6420 %-------------------------------------------------------------------------------
6422 %% Generate code based on one removed head of a CHR rule
6423 head1_code(Head,ID,OtherHeads,OtherIDs,PragmaRule,FA,O,Id,L,T) :-
6424 PragmaRule = pragma(Rule,_,_,_Name,RuleNb),
6425 Rule = rule(_,Head2,_,_),
6427 reorder_heads(RuleNb,Head,OtherHeads,OtherIDs,NOtherHeads,NOtherIDs),
6428 simplification_code(Head,ID,NOtherHeads,NOtherIDs,PragmaRule,FA,O,Id,L,T)
6430 simpagation_head1_code(Head,ID,OtherHeads,OtherIDs,PragmaRule,FA,O,Id,L,T)
6433 %% Generate code based on one persistent head of a CHR rule
6434 head2_code(Head,ID,OtherHeads,OtherIDs,PragmaRule,FA,O,Id,L,T) :-
6435 PragmaRule = pragma(Rule,_,_,_Name,RuleNb),
6436 Rule = rule(Head1,_,_,_),
6438 reorder_heads(RuleNb,Head,OtherHeads,OtherIDs,NOtherHeads,NOtherIDs),
6439 propagation_code(Head,ID,NOtherHeads,NOtherIDs,Rule,RuleNb,FA,O,Id,L,T)
6441 simpagation_head2_code(Head,ID,OtherHeads,OtherIDs,PragmaRule,FA,O,Id,L,T)
6444 gen_alloc_inc_clause(F/A,O,Id,L,T) :-
6445 vars_susp(A,Vars,Susp,VarsSusp),
6446 build_head(F,A,Id,VarsSusp,Head),
6448 build_head(F,A,IncId,VarsSusp,CallHead),
6449 gen_occ_allocation(F/A,O,Vars,Susp,ConditionalAlloc),
6456 add_dummy_location(Clause,LocatedClause),
6457 L = [LocatedClause|T].
6459 gen_occ_allocation(FA,O,Vars,Susp,Goal) :-
6460 get_allocation_occurrence(FA,AO),
6461 get_occurrence_code_id(FA,AO,AId),
6462 get_occurrence_code_id(FA,O,Id),
6463 ( chr_pp_flag(debugable,off), Id == AId ->
6464 allocate_constraint_goal(FA,Susp,Vars,Goal0),
6465 ( may_trigger(FA) ->
6466 Goal = (var(Susp) -> Goal0 ; true)
6474 gen_occ_allocation_in_guard(FA,O,Vars,Susp,Goal) :-
6475 get_allocation_occurrence(FA,AO),
6476 ( chr_pp_flag(debugable,off), O < AO ->
6477 allocate_constraint_goal(FA,Susp,Vars,Goal0),
6478 ( may_trigger(FA) ->
6479 Goal = (var(Susp) -> Goal0 ; true)
6487 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6489 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6491 % Reorders guard goals with respect to partner constraint retrieval goals and
6492 % active constraint. Returns combined partner retrieval + guard goal.
6494 guard_via_reschedule_new(Retrievals,GuardList,Prelude,GuardListSkeleton,LookupSkeleton,GoalSkeleton) :-
6495 ( chr_pp_flag(guard_via_reschedule,on) ->
6496 guard_via_reschedule_main_new(Retrievals,GuardList,Prelude,GuardListSkeleton,LookupSkeleton,ScheduleSkeleton),
6497 list2conj(ScheduleSkeleton,GoalSkeleton)
6499 length(Retrievals,RL), length(LookupSkeleton,RL),
6500 length(GuardList,GL), length(GuardListSkeleton,GL),
6501 append(LookupSkeleton,GuardListSkeleton,GoalListSkeleton),
6502 list2conj(GoalListSkeleton,GoalSkeleton)
6504 guard_via_reschedule_main_new(PartnerLookups,GuardList,ActiveHead,
6505 GuardListSkeleton,LookupSkeleton,ScheduleSkeleton) :-
6506 initialize_unit_dictionary(ActiveHead,Dict),
6507 maplist(wrap_in_functor(lookup),PartnerLookups,WrappedPartnerLookups),
6508 maplist(wrap_in_functor(guard),GuardList,WrappedGuardList),
6509 build_units(WrappedPartnerLookups,WrappedGuardList,Dict,Units),
6510 dependency_reorder(Units,NUnits),
6511 wrappedunits2lists(NUnits,IndexedGuardListSkeleton,LookupSkeleton,ScheduleSkeleton),
6512 sort(IndexedGuardListSkeleton,SortedIndexedGuardListSkeleton),
6513 snd_of_pairs(SortedIndexedGuardListSkeleton,GuardListSkeleton).
6515 wrappedunits2lists([],[],[],[]).
6516 wrappedunits2lists([unit(N,WrappedGoal,_,_)|Units],Gs,Ls,Ss) :-
6517 Ss = [GoalCopy|TSs],
6518 ( WrappedGoal = lookup(Goal) ->
6519 Ls = [GoalCopy|TLs],
6521 ; WrappedGoal = guard(Goal) ->
6522 Gs = [N-GoalCopy|TGs],
6525 wrappedunits2lists(Units,TGs,TLs,TSs).
6527 guard_splitting(Rule,SplitGuardList) :-
6528 Rule = rule(H1,H2,Guard,_),
6529 append(H1,H2,Heads),
6530 conj2list(Guard,GuardList),
6531 term_variables(Heads,HeadVars),
6532 split_off_simple_guard_new(GuardList,HeadVars,GuardPrefix,RestGuardList),
6533 append(GuardPrefix,[RestGuard],SplitGuardList),
6534 term_variables(RestGuardList,GuardVars1),
6535 % variables that are declared to be ground don't need to be locked
6536 ground_vars(Heads,GroundVars),
6537 list_difference_eq(HeadVars,GroundVars,LockableHeadVars),
6538 intersect_eq(LockableHeadVars,GuardVars1,GuardVars),
6539 maplist(chr_lock,GuardVars,Locks),
6540 maplist(chr_unlock,GuardVars,Unlocks),
6541 list2conj(Locks,LockPhase),
6542 list2conj(Unlocks,UnlockPhase),
6543 list2conj(RestGuardList,RestGuard1),
6544 RestGuard = (LockPhase,(RestGuard1,UnlockPhase)).
6546 guard_body_copies3(Rule,GuardList,VarDict,GuardCopyList,BodyCopy) :-
6547 Rule = rule(_,_,_,Body),
6548 my_term_copy(GuardList,VarDict,VarDict2,GuardCopyList),
6549 my_term_copy(Body,VarDict2,BodyCopy).
6552 split_off_simple_guard_new([],_,[],[]).
6553 split_off_simple_guard_new([G|Gs],VarDict,S,C) :-
6554 ( simple_guard_new(G,VarDict) ->
6556 split_off_simple_guard_new(Gs,VarDict,Ss,C)
6562 % simple guard: cheap and benign (does not bind variables)
6563 simple_guard_new(G,Vars) :-
6564 builtin_binds_b(G,BoundVars),
6565 not(( member(V,BoundVars),
6566 memberchk_eq(V,Vars)
6569 dependency_reorder(Units,NUnits) :-
6570 dependency_reorder(Units,[],NUnits).
6572 dependency_reorder([],Acc,Result) :-
6573 reverse(Acc,Result).
6575 dependency_reorder([Unit|Units],Acc,Result) :-
6576 Unit = unit(_GID,_Goal,Type,GIDs),
6580 dependency_insert(Acc,Unit,GIDs,NAcc)
6582 dependency_reorder(Units,NAcc,Result).
6584 dependency_insert([],Unit,_,[Unit]).
6585 dependency_insert([X|Xs],Unit,GIDs,L) :-
6586 X = unit(GID,_,_,_),
6587 ( memberchk(GID,GIDs) ->
6591 dependency_insert(Xs,Unit,GIDs,T)
6594 build_units(Retrievals,Guard,InitialDict,Units) :-
6595 build_retrieval_units(Retrievals,1,N,InitialDict,Dict,Units,Tail),
6596 build_guard_units(Guard,N,Dict,Tail).
6598 build_retrieval_units([],N,N,Dict,Dict,L,L).
6599 build_retrieval_units([U|Us],N,M,Dict,NDict,L,T) :-
6600 term_variables(U,Vs),
6601 update_unit_dictionary(Vs,N,Dict,Dict1,[],GIDs),
6602 L = [unit(N,U,fixed,GIDs)|L1],
6604 build_retrieval_units(Us,N1,M,Dict1,NDict,L1,T).
6606 initialize_unit_dictionary(Term,Dict) :-
6607 term_variables(Term,Vars),
6608 pair_all_with(Vars,0,Dict).
6610 update_unit_dictionary([],_,Dict,Dict,GIDs,GIDs).
6611 update_unit_dictionary([V|Vs],This,Dict,NDict,GIDs,NGIDs) :-
6612 ( lookup_eq(Dict,V,GID) ->
6613 ( (GID == This ; memberchk(GID,GIDs) ) ->
6620 Dict1 = [V - This|Dict],
6623 update_unit_dictionary(Vs,This,Dict1,NDict,GIDs1,NGIDs).
6625 build_guard_units(Guard,N,Dict,Units) :-
6627 Units = [unit(N,Goal,fixed,[])]
6628 ; Guard = [Goal|Goals] ->
6629 term_variables(Goal,Vs),
6630 update_unit_dictionary2(Vs,N,Dict,NDict,[],GIDs),
6631 Units = [unit(N,Goal,movable,GIDs)|RUnits],
6633 build_guard_units(Goals,N1,NDict,RUnits)
6636 update_unit_dictionary2([],_,Dict,Dict,GIDs,GIDs).
6637 update_unit_dictionary2([V|Vs],This,Dict,NDict,GIDs,NGIDs) :-
6638 ( lookup_eq(Dict,V,GID) ->
6639 ( (GID == This ; memberchk(GID,GIDs) ) ->
6644 Dict1 = [V - This|Dict]
6646 Dict1 = [V - This|Dict],
6649 update_unit_dictionary2(Vs,This,Dict1,NDict,GIDs1,NGIDs).
6651 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6653 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6655 %% / ___| ___| |_ / ___| ___ _ __ ___ __ _ _ __ | |_(_) ___ ___ _
6656 %% \___ \ / _ \ __| \___ \ / _ \ '_ ` _ \ / _` | '_ \| __| |/ __/ __(_)
6657 %% ___) | __/ |_ ___) | __/ | | | | | (_| | | | | |_| | (__\__ \_
6658 %% |____/ \___|\__| |____/ \___|_| |_| |_|\__,_|_| |_|\__|_|\___|___(_)
6661 %% | | | |_ __ (_) __ _ _ _ ___ |_ _|_ __ / _| ___ _ __ ___ _ __ ___ ___
6662 %% | | | | '_ \| |/ _` | | | |/ _ \ | || '_ \| |_ / _ \ '__/ _ \ '_ \ / __/ _ \
6663 %% | |_| | | | | | (_| | |_| | __/ | || | | | _| __/ | | __/ | | | (_| __/
6664 %% \___/|_| |_|_|\__, |\__,_|\___| |___|_| |_|_| \___|_| \___|_| |_|\___\___|
6667 functional_dependency/4,
6668 get_functional_dependency/4.
6670 :- chr_option(mode,functional_dependency(+,+,?,?)).
6671 :- chr_option(mode,get_functional_dependency(+,+,?,?)).
6673 allocation_occurrence(C,AO), occurrence(C,O,RuleNb,_,_) \ functional_dependency(C,RuleNb,Pattern,Key)
6677 functional_dependency(C,1,Pattern,Key).
6679 functional_dependency(C,RuleNb1,Pattern,Key) \ get_functional_dependency(C,RuleNb2,QPattern,QKey)
6683 QPattern = Pattern, QKey = Key.
6684 get_functional_dependency(_,_,_,_)
6688 functional_dependency_analysis(Rules) :-
6689 ( fail, chr_pp_flag(functional_dependency_analysis,on) ->
6690 functional_dependency_analysis_main(Rules)
6695 functional_dependency_analysis_main([]).
6696 functional_dependency_analysis_main([PRule|PRules]) :-
6697 ( discover_unique_pattern(PRule,C,RuleNb,Pattern,Key) ->
6698 functional_dependency(C,RuleNb,Pattern,Key)
6702 functional_dependency_analysis_main(PRules).
6704 discover_unique_pattern(PragmaRule,F/A,RuleNb,Pattern,Key) :-
6705 PragmaRule = pragma(Rule,_,_,Name,RuleNb),
6706 Rule = rule(H1,H2,Guard,_),
6714 check_unique_constraints(C1,C2,Guard,RuleNb,List),
6715 term_variables(C1,Vs),
6718 lookup_eq(List,V1,V2),
6721 select_pragma_unique_variables(Vs,List,Key1),
6722 copy_term_nat(C1-Key1,Pattern-Key),
6725 select_pragma_unique_variables([],_,[]).
6726 select_pragma_unique_variables([V|Vs],List,L) :-
6727 ( lookup_eq(List,V,_) ->
6732 select_pragma_unique_variables(Vs,List,T).
6734 % depends on functional dependency analysis
6735 % and shape of rule: C1 \ C2 <=> true.
6736 set_semantics_rules(Rules) :-
6737 ( fail, chr_pp_flag(set_semantics_rule,on) ->
6738 set_semantics_rules_main(Rules)
6743 set_semantics_rules_main([]).
6744 set_semantics_rules_main([R|Rs]) :-
6745 set_semantics_rule_main(R),
6746 set_semantics_rules_main(Rs).
6748 set_semantics_rule_main(PragmaRule) :-
6749 PragmaRule = pragma(Rule,IDs,Pragmas,_,RuleNb),
6750 ( Rule = rule([C1],[C2],true,_),
6751 IDs = ids([ID1],[ID2]),
6752 \+ is_passive(RuleNb,ID1),
6754 get_functional_dependency(F/A,RuleNb,Pattern,Key),
6755 copy_term_nat(Pattern-Key,C1-Key1),
6756 copy_term_nat(Pattern-Key,C2-Key2),
6763 check_unique_constraints(C1,C2,G,RuleNb,List) :-
6764 \+ any_passive_head(RuleNb),
6765 variable_replacement(C1-C2,C2-C1,List),
6766 copy_with_variable_replacement(G,OtherG,List),
6768 once(entails_b(NotG,OtherG)).
6770 % checks for rules of the shape ...,C1,C2... (<|=)=> ...
6771 % where C1 and C2 are symmteric constraints
6772 symmetry_analysis(Rules) :-
6773 ( chr_pp_flag(check_unnecessary_active,off) ->
6776 symmetry_analysis_main(Rules)
6779 symmetry_analysis_main([]).
6780 symmetry_analysis_main([R|Rs]) :-
6781 R = pragma(Rule,ids(IDs1,IDs2),_,_,RuleNb),
6782 Rule = rule(H1,H2,_,_),
6783 ( ( \+ chr_pp_flag(check_unnecessary_active,simplification) ; H2 == [] ), H1 \== [] ->
6784 symmetry_analysis_heads_simplification(H1,IDs1,[],[],Rule,RuleNb),
6785 symmetry_analysis_heads_propagation(H2,IDs2,[],[],Rule,RuleNb)
6789 symmetry_analysis_main(Rs).
6791 symmetry_analysis_heads_simplification([],[],_,_,_,_).
6792 symmetry_analysis_heads_simplification([H|Hs],[ID|IDs],PreHs,PreIDs,Rule,RuleNb) :-
6793 ( \+ is_passive(RuleNb,ID),
6794 member2(PreHs,PreIDs,PreH-PreID),
6795 \+ is_passive(RuleNb,PreID),
6796 variable_replacement(PreH,H,List),
6797 copy_with_variable_replacement(Rule,Rule2,List),
6798 identical_guarded_rules(Rule,Rule2) ->
6803 symmetry_analysis_heads_simplification(Hs,IDs,[H|PreHs],[ID|PreIDs],Rule,RuleNb).
6805 symmetry_analysis_heads_propagation([],[],_,_,_,_).
6806 symmetry_analysis_heads_propagation([H|Hs],[ID|IDs],PreHs,PreIDs,Rule,RuleNb) :-
6807 ( \+ is_passive(RuleNb,ID),
6808 member2(PreHs,PreIDs,PreH-PreID),
6809 \+ is_passive(RuleNb,PreID),
6810 variable_replacement(PreH,H,List),
6811 copy_with_variable_replacement(Rule,Rule2,List),
6812 identical_rules(Rule,Rule2) ->
6817 symmetry_analysis_heads_propagation(Hs,IDs,[H|PreHs],[ID|PreIDs],Rule,RuleNb).
6819 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6821 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6822 %% ____ _ _ _ __ _ _ _
6823 %% / ___|(_)_ __ ___ _ __ | (_)/ _(_) ___ __ _| |_(_) ___ _ __
6824 %% \___ \| | '_ ` _ \| '_ \| | | |_| |/ __/ _` | __| |/ _ \| '_ \
6825 %% ___) | | | | | | | |_) | | | _| | (_| (_| | |_| | (_) | | | |
6826 %% |____/|_|_| |_| |_| .__/|_|_|_| |_|\___\__,_|\__|_|\___/|_| |_|
6830 simplification_code(Head,ID,RestHeads,RestIDs,PragmaRule,Symbol,O,Id,L,T) :-
6831 PragmaRule = pragma(Rule,_,Pragmas,_,RuleNb),
6832 head_info1(Head,Symbol,_Vars,Susp,HeadVars,HeadPairs),
6833 build_head(Symbol,Id,HeadVars,ClauseHead),
6834 get_constraint_mode(Symbol,Mode),
6835 head_arg_matches(HeadPairs,Mode,[],FirstMatching,VarDict1,[],GroundVars),
6838 guard_splitting(Rule,GuardList0),
6839 ( is_stored_in_guard(Symbol, RuleNb) ->
6840 GuardList = [Hole1|GuardList0]
6842 GuardList = GuardList0
6844 guard_via_reschedule_new(RestHeads,GuardList,Head,GuardCopyList,GetRestHeads,RescheduledTest),
6846 rest_heads_retrieval_and_matching(RestHeads,RestIDs,Head,GetRestHeads,Susps,VarDict1,VarDict,[],[],[],GroundVars,_),
6848 guard_body_copies3(Rule,GuardList,VarDict,GuardCopyList,BodyCopy),
6850 ( is_stored_in_guard(Symbol, RuleNb) ->
6851 gen_occ_allocation_in_guard(Symbol,O,Vars,Susp,Allocation),
6852 gen_uncond_attach_goal(Symbol,Susp,Vars,Attachment,_),
6853 GuardCopyList = [Hole1Copy|_],
6854 Hole1Copy = (Allocation, Attachment)
6860 partner_constraint_detachments(Susps,RestHeads,VarDict,SuspsDetachments),
6861 active_constraint_detachment(Id,Susp,Head,VarDict,SuspDetachment),
6863 ( chr_pp_flag(debugable,on) ->
6864 Rule = rule(_,_,Guard,Body),
6865 my_term_copy(Guard - Body, VarDict, DebugGuard - DebugBody),
6866 sort_by_key([Susp|Susps],[ID|RestIDs],SortedSusps),
6867 DebugTry = 'chr debug_event'( try(SortedSusps,[],DebugGuard,DebugBody)),
6868 DebugApply = 'chr debug_event'(apply(SortedSusps,[],DebugGuard,DebugBody)),
6869 instrument_goal(ActualCut,DebugTry,DebugApply,Cut)
6873 actual_cut(Symbol,O,ActualCut),
6874 Clause = ( ClauseHead :-
6882 add_location(Clause,RuleNb,LocatedClause),
6883 L = [LocatedClause | T].
6885 actual_cut(Symbol,Occurrence,ActualCut) :-
6886 ( unconditional_occurrence(Symbol,Occurrence),
6887 chr_pp_flag(late_allocation,on) ->
6894 add_location(Clause,RuleNb,NClause) :-
6895 ( chr_pp_flag(line_numbers,on) ->
6896 get_chr_source_file(File),
6897 get_line_number(RuleNb,LineNb),
6898 NClause = '$source_location'(File,LineNb):Clause
6903 add_dummy_location(Clause,NClause) :-
6904 ( chr_pp_flag(line_numbers,on) ->
6905 get_chr_source_file(File),
6906 NClause = '$source_location'(File,1):Clause
6910 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6911 %% head_arg_matches(+Pairs,+Modes,+VarDict,-Goal,-NVarDict) is det.
6913 % Return goal matching newly introduced variables with variables in
6914 % previously looked-up heads.
6915 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6916 head_arg_matches(Pairs,Modes,VarDict,Goal,NVarDict) :-
6917 head_arg_matches(Pairs,Modes,VarDict,Goal,NVarDict,[],_).
6919 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6920 %% head_arg_matches(+Pairs,+Modes,+VarDict,-Goal,-NVarDict,+GroundVars,-NGroundVars) is det.
6921 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6922 head_arg_matches(Pairs,Modes,VarDict,Goal,NVarDict,GroundVars,NGroundVars) :-
6923 head_arg_matches_(Pairs,Modes,VarDict,GroundVars,GoalList,NVarDict,NGroundVars),
6924 list2conj(GoalList,Goal).
6926 head_arg_matches_([],[],VarDict,GroundVars,[],VarDict,GroundVars).
6927 head_arg_matches_([silent(Arg-Var)| Rest],[Mode|Modes],VarDict,GroundVars,GoalList,NVarDict,NGroundVars) :- !,
6929 term_variables(Arg,GroundVars0,GroundVars),
6930 head_arg_matches_(Rest,Modes,VarDict,GroundVars0,GoalList,NVarDict,NGroundVars)
6932 head_arg_matches_(Rest,Modes,VarDict,GroundVars,GoalList,NVarDict,NGroundVars)
6934 head_arg_matches_([Arg-Var| Rest],[Mode|Modes],VarDict,GroundVars,GoalList,NVarDict,NGroundVars) :-
6936 ( lookup_eq(VarDict,Arg,OtherVar) ->
6938 ( memberchk_eq(Arg,GroundVars) ->
6939 GoalList = [Var = OtherVar | RestGoalList],
6940 GroundVars1 = GroundVars
6942 GoalList = [Var == OtherVar | RestGoalList],
6943 GroundVars1 = [Arg|GroundVars]
6946 GoalList = [Var == OtherVar | RestGoalList],
6947 GroundVars1 = GroundVars
6951 VarDict1 = [Arg-Var | VarDict],
6952 GoalList = RestGoalList,
6954 GroundVars1 = [Arg|GroundVars]
6956 GroundVars1 = GroundVars
6961 ; ground(Arg), Arg = '$chr_identifier_match'(ActualArg,IndexType) ->
6962 identifier_label_atom(IndexType,Var,ActualArg,Goal),
6963 GoalList = [Goal|RestGoalList],
6965 GroundVars1 = GroundVars,
6970 GoalList = [ Var = Arg | RestGoalList]
6972 GoalList = [ Var == Arg | RestGoalList]
6975 GroundVars1 = GroundVars,
6978 ; Mode == (+), is_ground(GroundVars,Arg) ->
6979 copy_with_variable_replacement(Arg,ArgCopy,VarDict),
6980 GoalList = [ Var = ArgCopy | RestGoalList],
6982 GroundVars1 = GroundVars,
6985 ; Mode == (?), is_ground(GroundVars,Arg) ->
6986 copy_with_variable_replacement(Arg,ArgCopy,VarDict),
6987 GoalList = [ Var == ArgCopy | RestGoalList],
6989 GroundVars1 = GroundVars,
6994 functor(Term,Fct,N),
6997 GoalList = [ Var = Term | RestGoalList ]
6999 GoalList = [ nonvar(Var), Var = Term | RestGoalList ]
7001 pairup(Args,Vars,NewPairs),
7002 append(NewPairs,Rest,Pairs),
7003 replicate(N,Mode,NewModes),
7004 append(NewModes,Modes,RestModes),
7006 GroundVars1 = GroundVars
7008 head_arg_matches_(Pairs,RestModes,VarDict1,GroundVars1,RestGoalList,NVarDict,NGroundVars).
7010 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
7011 % add_heads_types(+ListOfHeads,+VarTypes,-NVarTypes) is det.
7012 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
7013 add_heads_types([],VarTypes,VarTypes).
7014 add_heads_types([Head|Heads],VarTypes,NVarTypes) :-
7015 add_head_types(Head,VarTypes,VarTypes1),
7016 add_heads_types(Heads,VarTypes1,NVarTypes).
7018 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
7019 % add_head_types(+Head,+VarTypes,-NVarTypes) is det.
7020 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
7021 add_head_types(Head,VarTypes,NVarTypes) :-
7023 get_constraint_type_det(F/A,ArgTypes),
7025 add_args_types(Args,ArgTypes,VarTypes,NVarTypes).
7027 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
7028 % add_args_types(+Terms,+Types,+VarTypes,-NVarTypes) is det.
7029 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
7030 add_args_types([],[],VarTypes,VarTypes).
7031 add_args_types([Arg|Args],[Type|Types],VarTypes,NVarTypes) :-
7032 add_arg_types(Arg,Type,VarTypes,VarTypes1),
7033 add_args_types(Args,Types,VarTypes1,NVarTypes).
7035 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
7036 % add_arg_types(+Term,+Type,+VarTypes,-NVarTypes) is det.
7037 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
7038 % OPTIMIZATION: don't add if `any'
7039 add_arg_types(Term,Type,VarTypes,NVarTypes) :-
7041 NVarTypes = VarTypes
7043 ( lookup_eq(VarTypes,Term,_) ->
7044 NVarTypes = VarTypes
7046 NVarTypes = [Term-Type|VarTypes]
7049 NVarTypes = VarTypes % approximate with any
7054 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
7055 %% add_heads_ground_variables(+ListOfHeads,+GroundVars,-NGroundVars) is det.
7057 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
7058 add_heads_ground_variables([],GroundVars,GroundVars).
7059 add_heads_ground_variables([Head|Heads],GroundVars,NGroundVars) :-
7060 add_head_ground_variables(Head,GroundVars,GroundVars1),
7061 add_heads_ground_variables(Heads,GroundVars1,NGroundVars).
7063 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
7064 %% add_head_ground_variables(+Head,+GroundVars,-GroundVars) is det.
7066 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
7067 add_head_ground_variables(Head,GroundVars,NGroundVars) :-
7069 get_constraint_mode(F/A,ArgModes),
7071 add_arg_ground_variables(Args,ArgModes,GroundVars,NGroundVars).
7074 add_arg_ground_variables([],[],GroundVars,GroundVars).
7075 add_arg_ground_variables([Arg|Args],[Mode|Modes],GroundVars,NGroundVars) :-
7077 term_variables(Arg,Vars),
7078 add_var_ground_variables(Vars,GroundVars,GroundVars1)
7080 GroundVars = GroundVars1
7082 add_arg_ground_variables(Args,Modes,GroundVars1,NGroundVars).
7084 add_var_ground_variables([],GroundVars,GroundVars).
7085 add_var_ground_variables([Var|Vars],GroundVars,NGroundVars) :-
7086 ( memberchk_eq(Var,GroundVars) ->
7087 GroundVars1 = GroundVars
7089 GroundVars1 = [Var|GroundVars]
7091 add_var_ground_variables(Vars,GroundVars1,NGroundVars).
7092 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
7093 %% is_ground(+GroundVars,+Term) is semidet.
7095 % Determine whether =Term= is always ground.
7096 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
7097 is_ground(GroundVars,Term) :-
7102 maplist(is_ground(GroundVars),Args)
7104 memberchk_eq(Term,GroundVars)
7107 %% check_ground(+GroundVars,+Term,-Goal) is det.
7109 % Return runtime check to see whether =Term= is ground.
7110 check_ground(GroundVars,Term,Goal) :-
7111 term_variables(Term,Variables),
7112 check_ground_variables(Variables,GroundVars,Goal).
7114 check_ground_variables([],_,true).
7115 check_ground_variables([Var|Vars],GroundVars,Goal) :-
7116 ( memberchk_eq(Var,GroundVars) ->
7117 check_ground_variables(Vars,GroundVars,Goal)
7119 Goal = (ground(Var), RGoal),
7120 check_ground_variables(Vars,GroundVars,RGoal)
7123 rest_heads_retrieval_and_matching(Heads,IDs,ActiveHead,GoalList,Susps,VarDict,NVarDict,PrevHs,PrevSusps,AttrDict) :-
7124 rest_heads_retrieval_and_matching(Heads,IDs,ActiveHead,GoalList,Susps,VarDict,NVarDict,PrevHs,PrevSusps,AttrDict,[],_).
7126 rest_heads_retrieval_and_matching(Heads,IDs,ActiveHead,GoalList,Susps,VarDict,NVarDict,PrevHs,PrevSusps,AttrDict,GroundVars,NGroundVars) :-
7128 rest_heads_retrieval_and_matching_n(Heads,IDs,PrevHs,PrevSusps,ActiveHead,GoalList,Susps,VarDict,NVarDict,AttrDict,GroundVars,NGroundVars)
7133 GroundVars = NGroundVars
7136 rest_heads_retrieval_and_matching_n([],_,_,_,_,[],[],VarDict,VarDict,_AttrDict,GroundVars,GroundVars).
7137 rest_heads_retrieval_and_matching_n([H|Hs],[ID|IDs],PrevHs,PrevSusps,ActiveHead,
7138 [Goal|Goals],[Susp|Susps],VarDict,NVarDict,_AttrDict,GroundVars,NGroundVars) :-
7140 head_info(H,A,Vars,_,_,Pairs),
7141 get_store_type(F/A,StoreType),
7142 ( StoreType == default ->
7143 passive_head_via(H,[ActiveHead|PrevHs],VarDict,ViaGoal,VarSusps),
7144 delay_phase_end(validate_store_type_assumptions,
7145 ( static_suspension_term(F/A,Suspension),
7146 get_static_suspension_term_field(arguments,F/A,Suspension,Vars),
7147 get_static_suspension_field(F/A,Suspension,state,active,GetState)
7150 % create_get_mutable_ref(active,State,GetMutable),
7151 get_constraint_mode(F/A,Mode),
7152 head_arg_matches(Pairs,Mode,VarDict,MatchingGoal,VarDict1,GroundVars,GroundVars1),
7154 sbag_member_call(Susp,VarSusps,Sbag),
7155 ExistentialLookup = (
7158 Susp = Suspension, % not inlined
7161 inline_matching_goal(MatchingGoal,MatchingGoal2)
7163 delay_phase_end(validate_store_type_assumptions,
7164 ( static_suspension_term(F/A,Suspension),
7165 get_static_suspension_term_field(arguments,F/A,Suspension,Vars)
7168 existential_lookup(StoreType,H,[ActiveHead|PrevHs],VarDict,GroundVars,Suspension,ExistentialLookup,Susp,Pairs,NPairs),
7169 get_constraint_mode(F/A,Mode),
7170 NMode = Mode, % filter_mode(NPairs,Pairs,Mode,NMode),
7171 head_arg_matches(NPairs,NMode,VarDict,MatchingGoal,VarDict1,GroundVars,GroundVars1),
7172 filter_append(NPairs,VarDict1,DA_), % order important here
7173 translate(GroundVars1,DA_,GroundVarsA),
7174 translate(GroundVars1,VarDict1,GroundVarsB),
7175 inline_matching_goal(MatchingGoal,MatchingGoal2,GroundVarsA,GroundVarsB)
7177 different_from_other_susps(H,Susp,PrevHs,PrevSusps,DiffSuspGoals),
7184 rest_heads_retrieval_and_matching_n(Hs,IDs,[H|PrevHs],[Susp|PrevSusps],ActiveHead,Goals,Susps,VarDict1,NVarDict,_NewAttrDict,GroundVars1,NGroundVars).
7186 inline_matching_goal(G1,G2) :-
7187 inline_matching_goal(G1,G2,[],[]).
7189 inline_matching_goal(A==B,true,GVA,GVB) :-
7190 memberchk_eq(A,GVA),
7191 memberchk_eq(B,GVB),
7193 % inline_matching_goal(A=B,true,_,_) :- A=B, !.
7194 inline_matching_goal((A,B),(A2,B2),GVA,GVB) :- !,
7195 inline_matching_goal(A,A2,GVA,GVB),
7196 inline_matching_goal(B,B2,GVA,GVB).
7197 inline_matching_goal(X,X,_,_).
7200 filter_mode([],_,_,[]).
7201 filter_mode([Arg-Var|Rest],[_-V|R],[M|Ms],Modes) :-
7204 filter_mode(Rest,R,Ms,MT)
7206 filter_mode([Arg-Var|Rest],R,Ms,Modes)
7209 filter_append([],VarDict,VarDict).
7210 filter_append([X|Xs],VarDict,NVarDict) :-
7212 filter_append(Xs,VarDict,NVarDict)
7214 NVarDict = [X|NVarDict0],
7215 filter_append(Xs,VarDict,NVarDict0)
7218 check_unique_keys([],_).
7219 check_unique_keys([V|Vs],Dict) :-
7220 lookup_eq(Dict,V,_),
7221 check_unique_keys(Vs,Dict).
7223 % Generates tests to ensure the found constraint differs from previously found constraints
7224 % TODO: detect more cases where constraints need be different
7225 different_from_other_susps(Head,Susp,Heads,Susps,DiffSuspGoals) :-
7226 different_from_other_susps_(Heads,Susps,Head,Susp,DiffSuspGoalList),
7227 list2conj(DiffSuspGoalList,DiffSuspGoals).
7229 different_from_other_susps_(_,[],_,_,[]) :- !.
7230 different_from_other_susps_([PreHead|Heads],[PreSusp|Susps],Head,Susp,List) :-
7231 ( functor(Head,F,A), functor(PreHead,F,A),
7232 copy_term_nat(PreHead-Head,PreHeadCopy-HeadCopy),
7233 \+ \+ PreHeadCopy = HeadCopy ->
7235 List = [Susp \== PreSusp | Tail]
7239 different_from_other_susps_(Heads,Susps,Head,Susp,Tail).
7241 % passive_head_via(in,in,in,in,out,out,out) :-
7242 passive_head_via(Head,PrevHeads,VarDict,Goal,AllSusps) :-
7244 get_constraint_index(F/A,Pos),
7245 /* which static variables may contain runtime variables */
7246 common_variables(Head,PrevHeads,CommonVars0),
7247 ground_vars([Head],GroundVars),
7248 list_difference_eq(CommonVars0,GroundVars,CommonVars),
7249 /********************************************************/
7250 global_list_store_name(F/A,Name),
7251 GlobalGoal = nb_getval(Name,AllSusps),
7252 get_constraint_mode(F/A,ArgModes),
7255 ; member(CommonVar,CommonVars), nth1(I,ArgModes,(-)), arg(I,Head,Arg), Arg == CommonVar ->
7256 translate([CommonVar],VarDict,[Var]),
7257 gen_get_mod_constraints(F/A,Var,AttrGoal,AllSusps),
7260 translate(CommonVars,VarDict,Vars),
7261 add_heads_types(PrevHeads,[],TypeDict),
7262 my_term_copy(TypeDict,VarDict,TypeDictCopy),
7263 gen_get_mod_constraints(F/A,Vars,TypeDictCopy,ViaGoal,AttrGoal,AllSusps),
7272 common_variables(T,Ts,Vs) :-
7273 term_variables(T,V1),
7274 term_variables(Ts,V2),
7275 intersect_eq(V1,V2,Vs).
7277 gen_get_mod_constraints(FA,Vars,TypeDict,ViaGoal,AttrGoal,AllSusps) :-
7278 via_goal(Vars,TypeDict,ViaGoal,Var),
7279 get_target_module(Mod),
7281 ( get_attr(Var,Mod,TSusps),
7282 TSuspsEqSusps % TSusps = Susps
7284 get_max_constraint_index(N),
7286 TSuspsEqSusps = true, % TSusps = Susps
7289 get_constraint_index(FA,Pos),
7290 get_suspensions(N,Pos,TSusps,TSuspsEqSusps,AllSusps)
7292 via_goal(Vars,TypeDict,ViaGoal,Var) :-
7296 lookup_type(TypeDict,A,Type),
7297 ( atomic_type(Type) ->
7301 ViaGoal = 'chr newvia_1'(A,Var)
7304 ViaGoal = 'chr newvia_2'(A,B,Var)
7306 ViaGoal = 'chr newvia'(Vars,Var)
7308 lookup_type(TypeDict,Var,Type) :-
7309 ( lookup_eq(TypeDict,Var,Type) ->
7312 Type = any % default type
7314 gen_get_mod_constraints(FA,Var,AttrGoal,AllSusps) :-
7315 get_target_module(Mod),
7317 ( get_attr(Var,Mod,TSusps),
7318 TSuspsEqSusps % TSusps = Susps
7320 get_max_constraint_index(N),
7322 TSuspsEqSusps = true, % TSusps = Susps
7325 get_constraint_index(FA,Pos),
7326 get_suspensions(N,Pos,TSusps,TSuspsEqSusps,AllSusps)
7329 guard_body_copies(Rule,VarDict,GuardCopy,BodyCopy) :-
7330 guard_body_copies2(Rule,VarDict,GuardCopyList,BodyCopy),
7331 list2conj(GuardCopyList,GuardCopy).
7333 guard_body_copies2(Rule,VarDict,GuardCopyList,BodyCopy) :-
7334 Rule = rule(_,H,Guard,Body),
7335 conj2list(Guard,GuardList),
7336 split_off_simple_guard(GuardList,VarDict,GuardPrefix,RestGuardList),
7337 my_term_copy(GuardPrefix-RestGuardList,VarDict,VarDict2,GuardPrefixCopy-RestGuardListCopyCore),
7339 append(GuardPrefixCopy,[RestGuardCopy],GuardCopyList),
7340 term_variables(RestGuardList,GuardVars),
7341 term_variables(RestGuardListCopyCore,GuardCopyVars),
7342 % variables that are declared to be ground don't need to be locked
7343 ground_vars(H,GroundVars),
7344 list_difference_eq(GuardVars,GroundVars,LockedGuardVars),
7345 ( chr_pp_flag(guard_locks,off) ->
7349 bagof(Lock - Unlock,
7350 X ^ Y ^ (lists:member(X,LockedGuardVars), % X is a variable appearing in the original guard
7351 pairlist:lookup_eq(VarDict,X,Y), % translate X into new variable
7352 memberchk_eq(Y,GuardCopyVars), % redundant check? or multiple entries for X possible?
7354 chr_unlock(Y,Unlock)
7357 once(pairup(Locks,Unlocks,LocksUnlocks))
7362 list2conj(Locks,LockPhase),
7363 list2conj(Unlocks,UnlockPhase),
7364 list2conj(RestGuardListCopyCore,RestGuardCopyCore),
7365 RestGuardCopy = (LockPhase,(RestGuardCopyCore,UnlockPhase)),
7366 my_term_copy(Body,VarDict2,BodyCopy).
7369 split_off_simple_guard([],_,[],[]).
7370 split_off_simple_guard([G|Gs],VarDict,S,C) :-
7371 ( simple_guard(G,VarDict) ->
7373 split_off_simple_guard(Gs,VarDict,Ss,C)
7379 % simple guard: cheap and benign (does not bind variables)
7380 simple_guard(G,VarDict) :-
7382 \+ (( member(V,Vars),
7383 lookup_eq(VarDict,V,_)
7386 active_constraint_detachment(Id,Susp,Head,VarDict,SuspDetachment) :-
7392 Id == [0], chr_pp_flag(store_in_guards, off)
7394 ( get_allocation_occurrence(C,AO),
7395 get_max_occurrence(C,MO),
7398 only_ground_indexed_arguments(C), chr_pp_flag(late_allocation,on) ->
7399 SuspDetachment = true
7401 gen_uncond_susp_detachment(Head,Susp,active,VarDict,UnCondSuspDetachment),
7402 ( chr_pp_flag(late_allocation,on) ->
7407 UnCondSuspDetachment
7410 SuspDetachment = UnCondSuspDetachment
7414 SuspDetachment = true
7417 partner_constraint_detachments([],[],_,true).
7418 partner_constraint_detachments([Susp|Susps],[Head|Heads],VarDict,(SuspDetachment,SuspsDetachments)) :-
7419 gen_uncond_susp_detachment(Head,Susp,partner,VarDict,SuspDetachment),
7420 partner_constraint_detachments(Susps,Heads,VarDict,SuspsDetachments).
7422 gen_uncond_susp_detachment(Head,Susp,Role,VarDict,SuspDetachment) :-
7426 SuspDetachment = ( DebugEvent, RemoveInternalGoal),
7427 ( chr_pp_flag(debugable,on) ->
7428 DebugEvent = 'chr debug_event'(remove(Susp))
7432 remove_constraint_goal(C,Susp,Vars,true,(DeleteCall,Detach),Role,RemoveInternalGoal),
7433 delete_constraint_goal(Head,Susp,VarDict,DeleteCall),
7434 ( \+ only_ground_indexed_arguments(C), \+ get_store_type(C,var_assoc_store(_,_)) ->
7435 detach_constraint_atom(C,Vars,Susp,Detach)
7440 SuspDetachment = true
7443 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7445 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7447 %% / ___|(_)_ __ ___ _ __ __ _ __ _ __ _| |_(_) ___ _ __ / |
7448 %% \___ \| | '_ ` _ \| '_ \ / _` |/ _` |/ _` | __| |/ _ \| '_ \ | |
7449 %% ___) | | | | | | | |_) | (_| | (_| | (_| | |_| | (_) | | | | | |
7450 %% |____/|_|_| |_| |_| .__/ \__,_|\__, |\__,_|\__|_|\___/|_| |_| |_|
7454 simpagation_head1_code(Head,ID,RestHeads,OtherIDs,PragmaRule,F/A,O,Id,L,T) :-
7455 PragmaRule = pragma(Rule,ids(_,Heads2IDs),Pragmas,_Name,RuleNb),
7456 Rule = rule(_Heads,Heads2,Guard,Body),
7458 head_info(Head,A,Vars,Susp,HeadVars,HeadPairs),
7459 get_constraint_mode(F/A,Mode),
7460 head_arg_matches(HeadPairs,Mode,[],FirstMatching,VarDict1,[],GroundVars),
7462 build_head(F,A,Id,HeadVars,ClauseHead),
7464 append(RestHeads,Heads2,Heads),
7465 append(OtherIDs,Heads2IDs,IDs),
7466 reorder_heads(RuleNb,Head,Heads,IDs,NHeads,NIDs),
7468 guard_splitting(Rule,GuardList0),
7469 ( is_stored_in_guard(F/A, RuleNb) ->
7470 GuardList = [Hole1|GuardList0]
7472 GuardList = GuardList0
7474 guard_via_reschedule_new(NHeads,GuardList,Head,GuardCopyList,GetRestHeads,RescheduledTest),
7476 rest_heads_retrieval_and_matching(NHeads,NIDs,Head,GetRestHeads,Susps,VarDict1,VarDict,[],[],[],GroundVars,_),
7477 split_by_ids(NIDs,Susps,OtherIDs,Susps1,Susps1IDs,Susps2,Susps2IDs),
7479 guard_body_copies3(Rule,GuardList,VarDict,GuardCopyList,BodyCopy),
7481 ( is_stored_in_guard(F/A, RuleNb) ->
7482 gen_uncond_attach_goal(F/A,Susp,Vars,Attachment,_),
7483 GuardCopyList = [Hole1Copy|_],
7484 Hole1Copy = Attachment
7489 sort_by_key(Susps1,Susps1IDs,SortedSusps1),
7490 partner_constraint_detachments(SortedSusps1,RestHeads,VarDict,SuspsDetachments),
7491 active_constraint_detachment(Id,Susp,Head,VarDict,SuspDetachment),
7493 ( chr_pp_flag(debugable,on) ->
7494 my_term_copy(Guard - Body, VarDict, DebugGuard - DebugBody),
7495 sort_by_key([Susp|Susps1],[ID|Susps1IDs],RemovedSusps),
7496 sort_by_key(Susps2,Susps2IDs,KeptSusps),
7497 DebugTry = 'chr debug_event'( try(RemovedSusps,KeptSusps,DebugGuard,DebugBody)),
7498 DebugApply = 'chr debug_event'(apply(RemovedSusps,KeptSusps,DebugGuard,DebugBody)),
7499 instrument_goal((!),DebugTry,DebugApply,Cut)
7504 Clause = ( ClauseHead :-
7512 add_location(Clause,RuleNb,LocatedClause),
7513 L = [LocatedClause | T].
7517 split_by_ids([],[],_,[],[]).
7518 split_by_ids([I|Is],[S|Ss],I1s,S1s,S2s) :-
7519 ( memberchk_eq(I,I1s) ->
7526 split_by_ids(Is,Ss,I1s,R1s,R2s).
7528 split_by_ids([],[],_,[],[],[],[]).
7529 split_by_ids([I|Is],[S|Ss],I1s,S1s,SI1s,S2s,SI2s) :-
7530 ( memberchk_eq(I,I1s) ->
7541 split_by_ids(Is,Ss,I1s,R1s,RSI1s,R2s,RSI2s).
7542 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7545 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7547 %% / ___|(_)_ __ ___ _ __ __ _ __ _ __ _| |_(_) ___ _ __ |___ \
7548 %% \___ \| | '_ ` _ \| '_ \ / _` |/ _` |/ _` | __| |/ _ \| '_ \ __) |
7549 %% ___) | | | | | | | |_) | (_| | (_| | (_| | |_| | (_) | | | | / __/
7550 %% |____/|_|_| |_| |_| .__/ \__,_|\__, |\__,_|\__|_|\___/|_| |_| |_____|
7553 %% Genereate prelude + worker predicate
7554 %% prelude calls worker
7555 %% worker iterates over one type of removed constraints
7556 simpagation_head2_code(Head2,ID,RestHeads2,RestIDs,PragmaRule,FA,O,Id,L,T) :-
7557 PragmaRule = pragma(Rule,ids(IDs1,IDs2),Pragmas,_Name,RuleNb),
7558 Rule = rule(Heads1,_,Guard,Body),
7559 append(Heads1,RestHeads2,Heads),
7560 append(IDs1,RestIDs,IDs),
7561 reorder_heads(RuleNb,Head2,Heads,IDs,[NHead|NHeads],[NID|NIDs]),
7562 simpagation_head2_prelude(Head2,NHead,[NHeads,Guard,Body],FA,O,Id,L,L1),
7564 ( memberchk_eq(NID,IDs2) ->
7565 simpagation_universal_searches(NHeads,NIDs,IDs2,[NHead,Head2],Rule,FA,O,NextHeads,PreHeads,NextIDs,Id1,Id2,L1,L2)
7567 L1 = L2, Id1 = Id2,NextHeads = NHeads, PreHeads = [NHead,Head2], NextIDs = NIDs
7569 universal_search_iterator_end(PreHeads,NextHeads,Rule,FA,O,Id2,L2,L3),
7570 simpagation_head2_worker(PreHeads,NextHeads,NextIDs,ID,PragmaRule,FA,O,Id2,L3,T).
7572 simpagation_universal_searches([],[],_,PreHeads,_,_,_,[],PreHeads,[],Id,Id,L,L).
7573 simpagation_universal_searches(Heads,[ID|IDs],IDs2,PreHeads,Rule,C,O,OutHeads,OutPreHeads,OutIDs,Id,NId,L,T) :-
7574 Heads = [Head|RHeads],
7576 universal_search_iterator_end(PreHeads,Heads,Rule,C,O,Id,L,L0),
7577 universal_search_iterator(Heads,PreHeads,Rule,C,O,Id,L0,L1),
7578 ( memberchk_eq(ID,IDs2) ->
7579 simpagation_universal_searches(RHeads,IDs,IDs2,[Head|PreHeads],Rule,C,O,OutHeads,OutPreHeads,OutIDs,Id1,NId,L1,T)
7581 NId = Id1, L1 = T, OutHeads = RHeads, OutPreHeads = [Head|PreHeads], IDs = OutIDs
7584 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7585 simpagation_head2_prelude(Head,Head1,Rest,F/A,O,Id1,L,T) :-
7586 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs),
7587 build_head(F,A,Id1,VarsSusp,ClauseHead),
7588 get_constraint_mode(F/A,Mode),
7589 head_arg_matches(HeadPairs,Mode,[],FirstMatching,VarDict,[],GroundVars),
7591 lookup_passive_head(Head1,[Head],VarDict,GroundVars,ModConstraintsGoal,AllSusps),
7593 gen_occ_allocation(F/A,O,Vars,Susp,ConstraintAllocationGoal),
7595 extend_id(Id1,DelegateId),
7596 extra_active_delegate_variables(Head,[Head1|Rest],VarDict,ExtraVars),
7597 append([AllSusps|VarsSusp],ExtraVars,DelegateCallVars),
7598 build_head(F,A,[O|DelegateId],DelegateCallVars,Delegate),
7605 ConstraintAllocationGoal,
7608 add_dummy_location(PreludeClause,LocatedPreludeClause),
7609 L = [LocatedPreludeClause|T].
7611 extra_active_delegate_variables(Term,Terms,VarDict,Vars) :-
7613 delegate_variables(Term,Terms,VarDict,Args,Vars).
7615 passive_delegate_variables(Term,PrevTerms,NextTerms,VarDict,Vars) :-
7616 term_variables(PrevTerms,PrevVars),
7617 delegate_variables(Term,NextTerms,VarDict,PrevVars,Vars).
7619 delegate_variables(Term,Terms,VarDict,PrevVars,Vars) :-
7620 term_variables(Term,V1),
7621 term_variables(Terms,V2),
7622 intersect_eq(V1,V2,V3),
7623 list_difference_eq(V3,PrevVars,V4),
7624 translate(V4,VarDict,Vars).
7627 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7628 simpagation_head2_worker([CurrentHead|PreHeads],NextHeads,NextIDs,ID,PragmaRule,F/A,O,Id,L,T) :-
7629 PragmaRule = pragma(Rule,ids(IDs1,_),Pragmas,_,RuleNb),
7630 Rule = rule(_,_,Guard,Body),
7631 get_prop_inner_loop_vars(PreHeads,[CurrentHead,NextHeads,Guard,Body],PreVarsAndSusps,VarDict,Susp,Vars,PreSusps),
7634 gen_var(OtherSusps),
7636 functor(CurrentHead,OtherF,OtherA),
7637 gen_vars(OtherA,OtherVars),
7638 head_info(CurrentHead,OtherA,OtherVars,OtherSusp,_VarsSusp,HeadPairs),
7639 get_constraint_mode(OtherF/OtherA,Mode),
7640 head_arg_matches(HeadPairs,Mode,VarDict,FirstMatching,VarDict1,[],GroundVars),
7642 delay_phase_end(validate_store_type_assumptions,
7643 ( static_suspension_term(OtherF/OtherA,OtherSuspension),
7644 get_static_suspension_field(OtherF/OtherA,OtherSuspension,state,active,GetState),
7645 get_static_suspension_term_field(arguments,OtherF/OtherA,OtherSuspension,OtherVars)
7648 % create_get_mutable_ref(active,State,GetMutable),
7649 different_from_other_susps(CurrentHead,OtherSusp,PreHeads,PreSusps,DiffSuspGoals),
7651 OtherSusp = OtherSuspension,
7657 ClauseVars = [[OtherSusp|OtherSusps]|PreVarsAndSusps],
7658 build_head(F,A,[O|Id],ClauseVars,ClauseHead),
7660 guard_splitting(Rule,GuardList0),
7661 ( is_stored_in_guard(F/A, RuleNb) ->
7662 GuardList = [Hole1|GuardList0]
7664 GuardList = GuardList0
7666 guard_via_reschedule_new(NextHeads,GuardList,[CurrentHead|PreHeads],GuardCopyList,RestSuspsRetrieval,RescheduledTest),
7668 rest_heads_retrieval_and_matching(NextHeads,NextIDs,[CurrentHead|PreHeads],RestSuspsRetrieval,Susps,VarDict1,VarDict2,[CurrentHead|PreHeads],[OtherSusp|PreSusps],[]),
7669 split_by_ids(NextIDs,Susps,IDs1,Susps1,Susps2),
7670 split_by_ids(NextIDs,NextHeads,IDs1,RestHeads1,_),
7672 partner_constraint_detachments([OtherSusp | Susps1],[CurrentHead|RestHeads1],VarDict2,Susps1Detachments),
7674 RecursiveVars = [OtherSusps|PreVarsAndSusps],
7675 build_head(F,A,[O|Id],RecursiveVars,RecursiveCall),
7676 RecursiveVars2 = [[]|PreVarsAndSusps],
7677 build_head(F,A,[O|Id],RecursiveVars2,RecursiveCall2),
7679 guard_body_copies3(Rule,GuardList,VarDict2,GuardCopyList,BodyCopy),
7680 ( is_stored_in_guard(F/A, RuleNb) ->
7681 GuardCopyList = [GuardAttachment|_] % once( ) ??
7686 ( is_observed(F/A,O) ->
7687 gen_uncond_attach_goal(F/A,Susp,Vars,Attachment,Generation),
7688 gen_state_cond_call(Susp,F/A,RecursiveCall,Generation,ConditionalRecursiveCall),
7689 gen_state_cond_call(Susp,F/A,RecursiveCall2,Generation,ConditionalRecursiveCall2)
7692 ConditionalRecursiveCall = RecursiveCall,
7693 ConditionalRecursiveCall2 = RecursiveCall2
7696 ( chr_pp_flag(debugable,on) ->
7697 my_term_copy(Guard - Body, VarDict, DebugGuard - DebugBody),
7698 DebugTry = 'chr debug_event'( try([OtherSusp|Susps1],[Susp|Susps2],DebugGuard,DebugBody)),
7699 DebugApply = 'chr debug_event'(apply([OtherSusp|Susps1],[Susp|Susps2],DebugGuard,DebugBody))
7705 ( is_stored_in_guard(F/A, RuleNb) ->
7706 GuardAttachment = Attachment,
7707 BodyAttachment = true
7709 GuardAttachment = true,
7710 BodyAttachment = Attachment % will be true if not observed at all
7713 ( member(unique(ID1,UniqueKeys), Pragmas),
7714 check_unique_keys(UniqueKeys,VarDict) ->
7717 ( CurrentSuspTest ->
7724 ConditionalRecursiveCall2
7742 ConditionalRecursiveCall
7748 add_location(Clause,RuleNb,LocatedClause),
7749 L = [LocatedClause | T].
7751 gen_state_cond_call(Susp,FA,Call,Generation,ConditionalCall) :-
7752 ( may_trigger(FA) ->
7753 does_use_field(FA,generation),
7754 delay_phase_end(validate_store_type_assumptions,
7755 ( static_suspension_term(FA,Suspension),
7756 get_update_static_suspension_field(FA,Susp,Suspension,state,active,inactive,GetState,UpdateState),
7757 get_static_suspension_field(FA,Suspension,generation,Generation,GetGeneration),
7758 get_static_suspension_term_field(arguments,FA,Suspension,Args)
7762 delay_phase_end(validate_store_type_assumptions,
7763 ( static_suspension_term(FA,Suspension),
7764 get_update_static_suspension_field(FA,Susp,Suspension,state,active,inactive,GetState,UpdateState),
7765 get_static_suspension_term_field(arguments,FA,Suspension,Args)
7768 GetGeneration = true
7771 ( Susp = Suspension,
7780 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7783 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7785 %% | _ \ _ __ ___ _ __ __ _ __ _ __ _| |_(_) ___ _ __
7786 %% | |_) | '__/ _ \| '_ \ / _` |/ _` |/ _` | __| |/ _ \| '_ \
7787 %% | __/| | | (_) | |_) | (_| | (_| | (_| | |_| | (_) | | | |
7788 %% |_| |_| \___/| .__/ \__,_|\__, |\__,_|\__|_|\___/|_| |_|
7791 propagation_code(Head,ID,RestHeads,RestIDs,Rule,RuleNb,FA,O,Id,L,T) :-
7792 ( RestHeads == [] ->
7793 propagation_single_headed(Head,ID,Rule,RuleNb,FA,O,Id,L,T)
7795 propagation_multi_headed(Head,RestHeads,RestIDs,Rule,RuleNb,FA,O,Id,L,T)
7797 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7798 %% Single headed propagation
7799 %% everything in a single clause
7800 propagation_single_headed(Head,ID,Rule,RuleNb,F/A,O,Id,ProgramList,ProgramTail) :-
7801 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs),
7802 build_head(F,A,Id,VarsSusp,ClauseHead),
7805 build_head(F,A,NextId,VarsSusp,NextHead),
7807 get_constraint_mode(F/A,Mode),
7808 head_arg_matches(HeadPairs,Mode,[],HeadMatching,VarDict,[],GroundVars),
7809 guard_body_copies(Rule,VarDict,GuardCopy,BodyCopy),
7811 % - recursive call -
7812 RecursiveCall = NextHead,
7814 actual_cut(F/A,O,ActualCut),
7816 Rule = rule(_,_,Guard,Body),
7817 ( chr_pp_flag(debugable,on) ->
7818 my_term_copy(Guard - Body, VarDict, DebugGuard - DebugBody),
7819 DebugTry = 'chr debug_event'( try([],[Susp],DebugGuard,DebugBody)),
7820 DebugApply = 'chr debug_event'(apply([],[Susp],DebugGuard,DebugBody)),
7821 instrument_goal(ActualCut,DebugTry,DebugApply,Cut)
7825 ( may_trigger(F/A), \+ has_no_history(RuleNb)->
7826 use_auxiliary_predicate(novel_production),
7827 use_auxiliary_predicate(extend_history),
7828 does_use_history(F/A,O),
7829 gen_occ_allocation(F/A,O,Vars,Susp,Allocation),
7831 ( named_history(RuleNb,HistoryName,HistoryIDs) ->
7832 ( HistoryIDs == [] ->
7833 empty_named_history_novel_production(HistoryName,NovelProduction),
7834 empty_named_history_extend_history(HistoryName,ExtendHistory)
7842 ( var(NovelProduction) ->
7843 NovelProduction = '$novel_production'(Susp,Tuple),
7844 ExtendHistory = '$extend_history'(Susp,Tuple)
7849 ( is_observed(F/A,O) ->
7850 gen_uncond_attach_goal(F/A,Susp,Vars,Attachment,Generation),
7851 gen_state_cond_call(Susp,F/A,RecursiveCall,Generation,ConditionalRecursiveCall)
7854 ConditionalRecursiveCall = RecursiveCall
7858 NovelProduction = true,
7859 ExtendHistory = true,
7861 ( is_observed(F/A,O) ->
7862 get_allocation_occurrence(F/A,AllocO),
7864 gen_insert_constraint_internal_goal(F/A,Attachment,VarsSusp,Vars,Susp),
7866 ; % more room for improvement?
7867 Attachment = (Attachment1, Attachment2),
7868 gen_occ_allocation(F/A,O,Vars,Susp,Attachment1),
7869 gen_uncond_attach_goal(F/A,Susp,Vars,Attachment2,Generation)
7871 gen_state_cond_call(Susp,F/A,RecursiveCall,Generation,ConditionalRecursiveCall)
7873 gen_occ_allocation(F/A,O,Vars,Susp,Attachment),
7874 ConditionalRecursiveCall = RecursiveCall
7878 ( is_stored_in_guard(F/A, RuleNb) ->
7879 GuardAttachment = Attachment,
7880 BodyAttachment = true
7882 GuardAttachment = true,
7883 BodyAttachment = Attachment % will be true if not observed at all
7897 ConditionalRecursiveCall
7899 add_location(Clause,RuleNb,LocatedClause),
7900 ProgramList = [LocatedClause | ProgramTail].
7902 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7903 %% multi headed propagation
7904 %% prelude + predicates to accumulate the necessary combinations of suspended
7905 %% constraints + predicate to execute the body
7906 propagation_multi_headed(Head,RestHeads,RestIDs,Rule,RuleNb,FA,O,Id,L,T) :-
7907 RestHeads = [First|Rest],
7908 propagation_prelude(Head,RestHeads,Rule,FA,O,Id,L,L1),
7909 extend_id(Id,ExtendedId),
7910 propagation_nested_code(Rest,[First,Head],RestIDs,Rule,RuleNb,FA,O,ExtendedId,L1,T).
7912 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7913 propagation_prelude(Head,[First|Rest],Rule,F/A,O,Id,L,T) :-
7914 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs),
7915 build_head(F,A,Id,VarsSusp,PreludeHead),
7916 get_constraint_mode(F/A,Mode),
7917 head_arg_matches(HeadPairs,Mode,[],FirstMatching,VarDict,[],GroundVars),
7918 Rule = rule(_,_,Guard,Body),
7919 extra_active_delegate_variables(Head,[First,Rest,Guard,Body],VarDict,ExtraVars),
7921 lookup_passive_head(First,[Head],VarDict,GroundVars,FirstSuspGoal,Susps),
7923 gen_occ_allocation(F/A,O,Vars,Susp,CondAllocation),
7925 extend_id(Id,NestedId),
7926 append([Susps|VarsSusp],ExtraVars,NestedVars),
7927 build_head(F,A,[O|NestedId],NestedVars,NestedHead),
7928 NestedCall = NestedHead,
7938 add_dummy_location(Prelude,LocatedPrelude),
7939 L = [LocatedPrelude|T].
7941 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7942 propagation_nested_code([],[CurrentHead|PreHeads],RestIDs,Rule,RuleNb,FA,O,Id,L,T) :-
7943 universal_search_iterator_end([CurrentHead|PreHeads],[],Rule,FA,O,Id,L,L1),
7944 propagation_body(CurrentHead,PreHeads,RestIDs,Rule,RuleNb,FA,O,Id,L1,T).
7946 propagation_nested_code([Head|RestHeads],PreHeads,RestIDs,Rule,RuleNb,FA,O,Id,L,T) :-
7947 universal_search_iterator_end(PreHeads,[Head|RestHeads],Rule,FA,O,Id,L,L1),
7948 universal_search_iterator([Head|RestHeads],PreHeads,Rule,FA,O,Id,L1,L2),
7950 propagation_nested_code(RestHeads,[Head|PreHeads],RestIDs,Rule,RuleNb,FA,O,IncId,L2,T).
7952 %check_fd_lookup_condition(_,_,_,_) :- fail.
7953 check_fd_lookup_condition(F,A,_,_) :-
7954 get_store_type(F/A,global_singleton), !.
7955 check_fd_lookup_condition(F,A,CurrentHead,PreHeads) :-
7956 \+ may_trigger(F/A),
7957 get_functional_dependency(F/A,1,P,K),
7958 copy_term(P-K,CurrentHead-Key),
7959 term_variables(PreHeads,PreVars),
7960 intersect_eq(Key,PreVars,Key),!.
7962 propagation_body(CurrentHead,PreHeads,RestIDs,Rule,RuleNb,F/A,O,Id,L,T) :-
7963 Rule = rule(_,H2,Guard,Body),
7964 gen_var_susp_list_for_b(PreHeads,[CurrentHead,Guard,Body],VarDict1,PreVarsAndSuspsList,FirstVarsSusp,AllSusps,PrevIterators),
7965 flatten(PreVarsAndSuspsList,PreVarsAndSusps),
7966 init(AllSusps,RestSusps),
7967 last(AllSusps,Susp),
7969 gen_var(OtherSusps),
7970 functor(CurrentHead,OtherF,OtherA),
7971 gen_vars(OtherA,OtherVars),
7972 delay_phase_end(validate_store_type_assumptions,
7973 ( static_suspension_term(OtherF/OtherA,Suspension),
7974 get_static_suspension_field(OtherF/OtherA,Suspension,state,active,GetState),
7975 get_static_suspension_term_field(arguments,OtherF/OtherA,Suspension,OtherVars)
7978 % create_get_mutable_ref(active,State,GetMutable),
7980 OtherSusp = Suspension,
7983 ClauseVars = [[OtherSusp|OtherSusps]|PreVarsAndSusps],
7984 build_head(F,A,[O|Id],ClauseVars,ClauseHead),
7985 ( check_fd_lookup_condition(OtherF,OtherA,CurrentHead,PreHeads) -> % iterator (OtherSusps) is empty at runtime
7986 universal_search_iterator_failure_vars(PreHeads,Id,PreVarsAndSuspsList,FirstVarsSusp,PrevIterators,PreVarsAndSusps1,PrevId0),
7987 RecursiveVars = PreVarsAndSusps1
7989 RecursiveVars = [OtherSusps|PreVarsAndSusps],
7995 PrevId = [O|PrevId0]
7997 build_head(F,A,PrevId,RecursiveVars,RecursiveHead),
7998 RecursiveCall = RecursiveHead,
7999 CurrentHead =.. [_|OtherArgs],
8000 pairup(OtherArgs,OtherVars,OtherPairs),
8001 get_constraint_mode(OtherF/OtherA,Mode),
8002 head_arg_matches(OtherPairs,Mode,VarDict1,Matching,VarDict),
8004 different_from_other_susps(CurrentHead,OtherSusp,PreHeads,RestSusps,DiffSuspGoals),
8005 guard_body_copies(Rule,VarDict,GuardCopy,BodyCopy),
8006 get_occurrence(F/A,O,_,ID),
8008 ( is_observed(F/A,O) ->
8009 init(FirstVarsSusp,FirstVars),
8010 gen_uncond_attach_goal(F/A,Susp,FirstVars,Attachment,Generation),
8011 gen_state_cond_call(Susp,F/A,RecursiveCall,Generation,ConditionalRecursiveCall)
8014 ConditionalRecursiveCall = RecursiveCall
8016 ( (is_least_occurrence(RuleNb) ; has_no_history(RuleNb)) ->
8017 NovelProduction = true,
8018 ExtendHistory = true
8019 ; \+ may_trigger(F/A), maplist(is_passive(RuleNb),RestIDs) ->
8020 NovelProduction = true,
8021 ExtendHistory = true
8023 get_occurrence(F/A,O,_,ID),
8024 use_auxiliary_predicate(novel_production),
8025 use_auxiliary_predicate(extend_history),
8026 does_use_history(F/A,O),
8027 ( named_history(RuleNb,HistoryName,HistoryIDs) ->
8028 ( HistoryIDs == [] ->
8029 empty_named_history_novel_production(HistoryName,NovelProduction),
8030 empty_named_history_extend_history(HistoryName,ExtendHistory)
8032 reverse([OtherSusp|RestSusps],NamedSusps),
8033 named_history_susps(HistoryIDs,[ID|RestIDs],[Susp|NamedSusps],HistorySusps),
8034 HistorySusps = [HistorySusp|_],
8036 ( length(HistoryIDs, 1) ->
8037 ExtendHistory = '$extend_history'(HistorySusp,HistoryName),
8038 NovelProduction = '$novel_production'(HistorySusp,HistoryName)
8040 findall(ConstraintSymbol,(member(SomeID,HistoryIDs),get_occurrence_from_id(ConstraintSymbol,_,RuleNb,SomeID)),ConstraintSymbols),
8041 Tuple =.. [t,HistoryName|HistorySusps]
8046 maplist(extract_symbol,H2,ConstraintSymbols),
8047 sort([ID|RestIDs],HistoryIDs),
8048 history_susps(RestIDs,[OtherSusp|RestSusps],Susp,ID,HistorySusps),
8049 Tuple =.. [t,RuleNb|HistorySusps]
8052 ( var(NovelProduction) ->
8053 novel_production_calls(ConstraintSymbols,HistoryIDs,HistorySusps,RuleNb,TupleVar,NovelProductions),
8054 ExtendHistory = '$extend_history'(HistorySusp,TupleVar),
8055 NovelProduction = ( TupleVar = Tuple, NovelProductions )
8062 ( chr_pp_flag(debugable,on) ->
8063 Rule = rule(_,_,Guard,Body),
8064 my_term_copy(Guard - Body, VarDict, DebugGuard - DebugBody),
8065 get_occurrence(F/A,O,_,ID),
8066 sort_by_key([Susp,OtherSusp|RestSusps],[ID|RestIDs],KeptSusps),
8067 DebugTry = 'chr debug_event'( try([],KeptSusps,DebugGuard,DebugBody)),
8068 DebugApply = 'chr debug_event'(apply([],KeptSusps,DebugGuard,DebugBody))
8074 ( is_stored_in_guard(F/A, RuleNb) ->
8075 GuardAttachment = Attachment,
8076 BodyAttachment = true
8078 GuardAttachment = true,
8079 BodyAttachment = Attachment % will be true if not observed at all
8095 ConditionalRecursiveCall
8099 add_location(Clause,RuleNb,LocatedClause),
8100 L = [LocatedClause|T].
8102 extract_symbol(Head,F/A) :-
8105 novel_production_calls([],[],[],_,_,true).
8106 novel_production_calls([ConstraintSymbol|ConstraintSymbols],[ID|IDs],[Suspension|Suspensions],RuleNb,Tuple,(Goal,Goals)) :-
8107 get_occurrence_from_id(ConstraintSymbol,Occurrence,RuleNb,ID),
8108 delay_phase_end(validate_store_type_assumptions,novel_production_call(ConstraintSymbol,Occurrence,'$novel_production'(Suspension,Tuple),Goal)),
8109 novel_production_calls(ConstraintSymbols,IDs,Suspensions,RuleNb,Tuple,Goals).
8111 history_susps(RestIDs,ReversedRestSusps,Susp,ID,HistorySusps) :-
8112 reverse(ReversedRestSusps,RestSusps),
8113 sort_by_key([Susp|RestSusps],[ID|RestIDs],HistorySusps).
8115 named_history_susps([],_,_,[]).
8116 named_history_susps([HistoryID|HistoryIDs],IDs,Susps,[HistorySusp|HistorySusps]) :-
8117 select2(HistoryID,HistorySusp,IDs,Susps,RestIDs,RestSusps), !,
8118 named_history_susps(HistoryIDs,RestIDs,RestSusps,HistorySusps).
8122 gen_var_susp_list_for([Head],Terms,VarDict,HeadVars,VarsSusp,Susp) :-
8125 head_info(Head,A,_Vars,Susp,VarsSusp,HeadPairs),
8126 get_constraint_mode(F/A,Mode),
8127 head_arg_matches(HeadPairs,Mode,[],_,VarDict),
8128 extra_active_delegate_variables(Head,Terms,VarDict,ExtraVars),
8129 append(VarsSusp,ExtraVars,HeadVars).
8130 gen_var_susp_list_for([Head|Heads],Terms,NVarDict,VarsSusps,Rest,Susps) :-
8131 gen_var_susp_list_for(Heads,[Head|Terms],VarDict,Rest,_,_),
8134 head_info(Head,A,_Vars,Susp,_VarsSusp,HeadPairs),
8135 get_constraint_mode(F/A,Mode),
8136 head_arg_matches(HeadPairs,Mode,VarDict,_,NVarDict),
8137 passive_delegate_variables(Head,Heads,Terms,NVarDict,HeadVars),
8138 append(HeadVars,[Susp,Susps|Rest],VarsSusps).
8141 % VarDict for the copies of variables in the original heads
8142 % VarsSuspsList list of lists of arguments for the successive heads
8143 % FirstVarsSusp top level arguments
8144 % SuspList list of all suspensions
8145 % Iterators list of all iterators
8146 gen_var_susp_list_for_b([Head],NextHeads,VarDict,[HeadVars],VarsSusp,[Susp],[]) :-
8149 head_info(Head,A,_Vars,Susp,VarsSusp,Pairs), % make variables for argument positions
8150 get_constraint_mode(F/A,Mode),
8151 head_arg_matches(Pairs,Mode,[],_,VarDict), % copy variables inside arguments, build dictionary
8152 extra_active_delegate_variables(Head,NextHeads,VarDict,ExtraVars), % decide what additional variables are needed
8153 append(VarsSusp,ExtraVars,HeadVars). % add additional variables to head variables
8154 gen_var_susp_list_for_b([Head|Heads],NextHeads,NVarDict,[Vars|RestVars],FirstVarsSusp,[Susp|SuspList],[Susps|Iterators]) :-
8155 gen_var_susp_list_for_b(Heads,[Head|NextHeads],VarDict,RestVars,FirstVarsSusp,SuspList,Iterators),
8158 head_info(Head,A,_Vars,Susp,_VarsSusp,HeadPairs),
8159 get_constraint_mode(F/A,Mode),
8160 head_arg_matches(HeadPairs,Mode,VarDict,_,NVarDict),
8161 passive_delegate_variables(Head,Heads,NextHeads,NVarDict,HeadVars),
8162 append(HeadVars,[Susp,Susps],Vars).
8164 get_prop_inner_loop_vars([Head],NextHeads,HeadVars,VarDict,Susp,Vars,[]) :-
8167 head_info(Head,A,Vars,Susp,VarsSusp,Pairs),
8168 get_constraint_mode(F/A,Mode),
8169 head_arg_matches(Pairs,Mode,[],_,VarDict),
8170 extra_active_delegate_variables(Head,NextHeads,VarDict,ExtraVars),
8171 append(VarsSusp,ExtraVars,HeadVars).
8172 get_prop_inner_loop_vars([Head|Heads],Terms,VarsSusps,NVarDict,MainSusp,MainVars,[Susp|RestSusps]) :-
8173 get_prop_inner_loop_vars(Heads,[Head|Terms],RestVarsSusp,VarDict,MainSusp,MainVars,RestSusps),
8176 head_info(Head,A,_Vars,Susp,_VarsSusp,Pairs),
8177 get_constraint_mode(F/A,Mode),
8178 head_arg_matches(Pairs,Mode,VarDict,_,NVarDict),
8179 passive_delegate_variables(Head,Heads,Terms,NVarDict,HeadVars),
8180 append(HeadVars,[Susp,Susps|RestVarsSusp],VarsSusps).
8182 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8184 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8186 %% | _ \ __ _ ___ ___(_)_ _____ | | | | ___ __ _ __| |
8187 %% | |_) / _` / __/ __| \ \ / / _ \ | |_| |/ _ \/ _` |/ _` |
8188 %% | __/ (_| \__ \__ \ |\ V / __/ | _ | __/ (_| | (_| |
8189 %% |_| \__,_|___/___/_| \_/ \___| |_| |_|\___|\__,_|\__,_|
8192 %% | _ \ ___| |_ _ __(_) _____ ____ _| |
8193 %% | |_) / _ \ __| '__| |/ _ \ \ / / _` | |
8194 %% | _ < __/ |_| | | | __/\ V / (_| | |
8195 %% |_| \_\___|\__|_| |_|\___| \_/ \__,_|_|
8198 %% | _ \ ___ ___ _ __ __| | ___ _ __(_)_ __ __ _
8199 %% | |_) / _ \/ _ \| '__/ _` |/ _ \ '__| | '_ \ / _` |
8200 %% | _ < __/ (_) | | | (_| | __/ | | | | | | (_| |
8201 %% |_| \_\___|\___/|_| \__,_|\___|_| |_|_| |_|\__, |
8204 reorder_heads(RuleNb,Head,RestHeads,RestIDs,NRestHeads,NRestIDs) :-
8205 ( chr_pp_flag(reorder_heads,on), length(RestHeads,Length), Length =< 6 ->
8206 reorder_heads_main(RuleNb,Head,RestHeads,RestIDs,NRestHeads,NRestIDs)
8208 NRestHeads = RestHeads,
8212 reorder_heads_main(RuleNb,Head,RestHeads,RestIDs,NRestHeads,NRestIDs) :-
8213 term_variables(Head,Vars),
8214 InitialData = entry([],[],Vars,RestHeads,RestIDs,RuleNb),
8215 copy_term_nat(InitialData,InitialDataCopy),
8216 a_star(InitialDataCopy,FD^(chr_translate:final_data(FD)),N^EN^C^(chr_translate:expand_data(N,EN,C)),FinalData),
8217 InitialDataCopy = InitialData,
8218 FinalData = entry(RNRestHeads,RNRestIDs,_,_,_,_),
8219 reverse(RNRestHeads,NRestHeads),
8220 reverse(RNRestIDs,NRestIDs).
8222 final_data(Entry) :-
8223 Entry = entry(_,_,_,_,[],_).
8225 expand_data(Entry,NEntry,Cost) :-
8226 Entry = entry(Heads,IDs,Vars,NHeads,NIDs,RuleNb),
8227 select2(Head1,ID1,NHeads,NIDs,NHeads1,NIDs1),
8228 term_variables([Head1|Vars],Vars1),
8229 NEntry = entry([Head1|Heads],[ID1|IDs],Vars1,NHeads1,NIDs1,RuleNb),
8230 order_score(Head1,ID1,Vars,NHeads1,RuleNb,Cost).
8232 % Assigns score to head based on known variables and heads to lookup
8233 % order_score(+head,+id,+knownvars,+heads,+rule_nb,-score). {{{
8234 order_score(Head,ID,KnownVars,RestHeads,RuleNb,Score) :-
8236 get_store_type(F/A,StoreType),
8237 order_score(StoreType,Head,ID,KnownVars,RestHeads,RuleNb,99999,Score).
8240 %% order_score(+store+_type,+head,+id,+vars,+heads,+rule_nb,+score,-score) {{{
8241 order_score(default,Head,_ID,KnownVars,RestHeads,RuleNb,CScore,NScore) :-
8242 term_variables(Head,HeadVars0),
8243 term_variables(RestHeads,RestVars),
8244 ground_vars([Head],GroundVars),
8245 list_difference_eq(HeadVars0,GroundVars,HeadVars),
8246 order_score_vars(HeadVars,KnownVars,RestVars,Score),
8247 NScore is min(CScore,Score).
8248 order_score(multi_inthash(Indexes),Head,_ID,KnownVars,RestHeads,RuleNb,CScore,Score) :-
8252 order_score_indexes(Indexes,Head,KnownVars,Score)
8254 order_score(multi_hash(Indexes),Head,_ID,KnownVars,RestHeads,RuleNb,CScore,Score) :-
8258 order_score_indexes(Indexes,Head,KnownVars,Score)
8260 order_score(global_ground,Head,ID,KnownVars,RestHeads,RuleNb,CScore,NScore) :-
8261 term_variables(Head,HeadVars),
8262 term_variables(RestHeads,RestVars),
8263 order_score_vars(HeadVars,KnownVars,RestVars,Score_),
8264 Score is Score_ * 200,
8265 NScore is min(CScore,Score).
8266 order_score(var_assoc_store(_,_),_,_,_,_,_,_,1).
8267 order_score(global_singleton,_Head,ID,_KnownVars,_RestHeads,_RuleNb,_,Score) :-
8268 Score = 1. % guaranteed O(1)
8269 order_score(multi_store(StoreTypes),Head,ID,KnownVars,RestHeads,RuleNb,CScore,Score) :-
8270 multi_order_score(StoreTypes,Head,ID,KnownVars,RestHeads,RuleNb,CScore,Score).
8271 multi_order_score([],_,_,_,_,_,Score,Score).
8272 multi_order_score([StoreType|StoreTypes],Head,ID,KnownVars,RestHeads,RuleNb,Score0,Score) :-
8273 ( order_score(StoreType,Head,ID,KnownVars,RestHeads,RuleNb,Score0,Score1) -> true
8276 multi_order_score(StoreTypes,Head,ID,KnownVars,RestHeads,RuleNb,Score1,Score).
8278 order_score(identifier_store(Index),Head,ID,KnownVars,RestHeads,RuleNb,CScore,Score) :-
8279 Score is min(CScore,10).
8280 order_score(type_indexed_identifier_store(_,_),Head,ID,KnownVars,RestHeads,RuleNb,CScore,Score) :-
8281 Score is min(CScore,10).
8285 %% order_score_indexes(+indexes,+head,+vars,-score). {{{
8286 order_score_indexes(Indexes,Head,Vars,Score) :-
8287 copy_term_nat(Head+Vars,HeadCopy+VarsCopy),
8288 numbervars(VarsCopy,0,_),
8289 order_score_indexes(Indexes,HeadCopy,Score).
8291 order_score_indexes([I|Is],Head,Score) :-
8293 ( maplist(ground,Args) /* forall(Arg,Args,memberchk_eq(Arg,KnownVars)) */ ->
8296 order_score_indexes(Is,Head,Score)
8300 memberchk_eq_flip(List,Element) :- memberchk_eq(Element,List).
8302 order_score_vars(Vars,KnownVars,RestVars,Score) :-
8303 order_score_count_vars(Vars,KnownVars,RestVars,K-R-O),
8307 Score is max(10 - K,0)
8309 Score is max(10 - R,1) * 100
8311 Score is max(10-O,1) * 1000
8313 order_score_count_vars([],_,_,0-0-0).
8314 order_score_count_vars([V|Vs],KnownVars,RestVars,NK-NR-NO) :-
8315 order_score_count_vars(Vs,KnownVars,RestVars,K-R-O),
8316 ( memberchk_eq(V,KnownVars) ->
8319 ; memberchk_eq(V,RestVars) ->
8327 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8329 %% |_ _|_ __ | (_)_ __ (_)_ __ __ _
8330 %% | || '_ \| | | '_ \| | '_ \ / _` |
8331 %% | || | | | | | | | | | | | | (_| |
8332 %% |___|_| |_|_|_|_| |_|_|_| |_|\__, |
8336 create_get_mutable_ref(V,M,GM) :- GM = (M = mutable(V)).
8337 create_get_mutable(V,M,GM) :- M = mutable(V), GM = true.
8341 %% create_get_mutable(V,M,GM) :- GM = get_mutable(V,M).
8342 %% create_get_mutable_ref(V,M,GM) :- GM = get_mutable(V,M).
8345 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8347 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8349 %% | | | | |_(_) (_) |_ _ _
8350 %% | | | | __| | | | __| | | |
8351 %% | |_| | |_| | | | |_| |_| |
8352 %% \___/ \__|_|_|_|\__|\__, |
8355 % Create a fresh variable.
8358 % Create =N= fresh variables.
8362 ast_head_info1(AstHead,Vars,Susp,VarsSusp,HeadPairs) :-
8363 AstHead = chr_constraint(_/A,Args,_),
8364 vars_susp(A,Vars,Susp,VarsSusp),
8365 pairup(Args,Vars,HeadPairs).
8367 head_info1(Head,_/A,Vars,Susp,VarsSusp,HeadPairs) :-
8368 vars_susp(A,Vars,Susp,VarsSusp),
8370 pairup(Args,Vars,HeadPairs).
8372 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs) :-
8373 vars_susp(A,Vars,Susp,VarsSusp),
8375 pairup(Args,Vars,HeadPairs).
8377 inc_id([N|Ns],[O|Ns]) :-
8379 dec_id([N|Ns],[M|Ns]) :-
8382 extend_id(Id,[0|Id]).
8384 next_id([_,N|Ns],[O|Ns]) :-
8387 % return clause Head
8388 % for F/A constraint symbol, predicate identifier Id and arguments Head
8389 build_head(F/A,Id,Args,Head) :-
8390 build_head(F,A,Id,Args,Head).
8391 build_head(F,A,Id,Args,Head) :-
8392 buildName(F,A,Id,Name),
8393 ( (chr_pp_flag(debugable,on) ; is_stored(F/A), ( has_active_occurrence(F/A) ; chr_pp_flag(late_allocation,off)),
8394 ( may_trigger(F/A) ;
8395 get_allocation_occurrence(F/A,AO),
8396 get_max_occurrence(F/A,MO),
8398 Head =.. [Name|Args]
8400 init(Args,ArgsWOSusp), % XXX not entirely correct!
8401 Head =.. [Name|ArgsWOSusp]
8404 % return predicate name Result
8405 % for Fct/Aty constraint symbol and predicate identifier List
8406 buildName(Fct,Aty,List,Result) :-
8407 ( (chr_pp_flag(debugable,on) ; (once((is_stored(Fct/Aty), ( has_active_occurrence(Fct/Aty) ; chr_pp_flag(late_allocation,off)),
8408 ( may_trigger(Fct/Aty) ; get_allocation_occurrence(Fct/Aty,AO), get_max_occurrence(Fct/Aty,MO),
8409 MO >= AO ) ; List \= [0])) ) ) ->
8410 atom_concat(Fct, '___' ,FctSlash),
8411 atomic_concat(FctSlash,Aty,FctSlashAty),
8412 buildName_(List,FctSlashAty,Result)
8417 buildName_([],Name,Name).
8418 buildName_([N|Ns],Name,Result) :-
8419 buildName_(Ns,Name,Name1),
8420 atom_concat(Name1,'__',NameDash), % '_' is a char :-(
8421 atomic_concat(NameDash,N,Result).
8423 vars_susp(A,Vars,Susp,VarsSusp) :-
8425 append(Vars,[Susp],VarsSusp).
8427 or_pattern(Pos,Pat) :-
8429 Pat is 1 << Pow. % was 2 ** X
8431 and_pattern(Pos,Pat) :-
8433 Y is 1 << X, % was 2 ** X
8434 Pat is (-1)*(Y + 1).
8436 make_name(Prefix,F/A,Name) :-
8437 atom_concat_list([Prefix,F,'___',A],Name).
8439 %===============================================================================
8440 % Attribute for attributed variables
8442 make_attr(N,Mask,SuspsList,Attr) :-
8443 length(SuspsList,N),
8444 Attr =.. [v,Mask|SuspsList].
8446 get_all_suspensions2(N,Attr,SuspensionsList) :-
8447 chr_pp_flag(dynattr,off), !,
8448 make_attr(N,_,SuspensionsList,Attr).
8451 get_all_suspensions2(N,Attr,Goal,SuspensionsList) :-
8452 % writeln(get_all_suspensions2),
8453 length(SuspensionsList,N),
8454 Goal = 'chr all_suspensions'(SuspensionsList,1,Attr).
8458 normalize_attr(Attr,NormalGoal,NormalAttr) :-
8459 % writeln(normalize_attr),
8460 NormalGoal = 'chr normalize_attr'(Attr,NormalAttr).
8462 get_suspensions(N,Position,TAttr,(TAttr = Attr),Suspensions) :-
8463 chr_pp_flag(dynattr,off),
8464 !, % chr_pp_flag(experiment,off), !,
8465 make_attr(N,_,SuspsList,Attr),
8466 nth1(Position,SuspsList,Suspensions).
8468 % get_suspensions(N,Position,TAttr,Goal,Suspensions) :-
8469 % chr_pp_flag(dynattr,off),
8470 % chr_pp_flag(experiment,on), !,
8471 % Position1 is Position + 1,
8472 % Goal = arg(Position1,TAttr,Suspensions).
8475 get_suspensions(N,Position,TAttr,Goal,Suspensions) :-
8476 % writeln(get_suspensions),
8478 ( memberchk(Position-Suspensions,TAttr) ->
8484 %-------------------------------------------------------------------------------
8485 % +N: number of constraint symbols
8486 % +Suspension: source-level variable, for suspension
8487 % +Position: constraint symbol number
8488 % -Attr: source-level term, for new attribute
8489 singleton_attr(N,Suspension,Position,Attr) :-
8490 chr_pp_flag(dynattr,off), !,
8491 or_pattern(Position,Pattern),
8492 make_attr(N,Pattern,SuspsList,Attr),
8493 nth1(Position,SuspsList,[Suspension]),
8494 chr_delete(SuspsList,[Suspension],RestSuspsList),
8495 set_elems(RestSuspsList,[]).
8498 singleton_attr(N,Suspension,Position,Attr) :-
8499 % writeln(singleton_attr),
8500 Attr = [Position-[Suspension]].
8502 %-------------------------------------------------------------------------------
8503 % +N: number of constraint symbols
8504 % +Suspension: source-level variable, for suspension
8505 % +Position: constraint symbol number
8506 % +TAttr: source-level variable, for old attribute
8507 % -Goal: goal for creating new attribute
8508 % -NTAttr: source-level variable, for new attribute
8509 add_attr(N,Suspension,Position,TAttr,Goal,NTAttr) :-
8510 chr_pp_flag(dynattr,off), !,
8511 make_attr(N,Mask,SuspsList,Attr),
8512 or_pattern(Position,Pattern),
8513 nth1(Position,SuspsList,Susps),
8514 substitute_eq(Susps,SuspsList,[Suspension|Susps],SuspsList1),
8515 make_attr(N,Mask,SuspsList1,NewAttr1),
8516 substitute_eq(Susps,SuspsList,[Suspension],SuspsList2),
8517 make_attr(N,NewMask,SuspsList2,NewAttr2),
8520 ( Mask /\ Pattern =:= Pattern ->
8523 NewMask is Mask \/ Pattern,
8529 add_attr(N,Suspension,Position,TAttr,Goal,NTAttr) :-
8530 % writeln(add_attr),
8532 ( 'chr select'(TAttr,Position-Suspensions,RAttr) ->
8533 NTAttr = [Position-[Suspension|Suspensions]|RAttr]
8535 NTAttr = [Position-[Suspension]|TAttr]
8538 rem_attr(N,Var,Suspension,Position,TAttr,Goal) :-
8539 chr_pp_flag(dynattr,off),
8540 chr_pp_flag(experiment,off), !,
8541 or_pattern(Position,Pattern),
8542 and_pattern(Position,DelPattern),
8543 make_attr(N,Mask,SuspsList,Attr),
8544 nth1(Position,SuspsList,Susps),
8545 substitute_eq(Susps,SuspsList,[],SuspsList1),
8546 make_attr(N,NewMask,SuspsList1,Attr1),
8547 substitute_eq(Susps,SuspsList,NewSusps,SuspsList2),
8548 make_attr(N,Mask,SuspsList2,Attr2),
8549 get_target_module(Mod),
8552 ( Mask /\ Pattern =:= Pattern ->
8553 'chr sbag_del_element'(Susps,Suspension,NewSusps),
8555 NewMask is Mask /\ DelPattern,
8559 put_attr(Var,Mod,Attr1)
8562 put_attr(Var,Mod,Attr2)
8568 rem_attr(N,Var,Suspension,Position,TAttr,Goal) :-
8569 chr_pp_flag(dynattr,off),
8570 chr_pp_flag(experiment,on), !,
8571 or_pattern(Position,Pattern),
8572 and_pattern(Position,DelPattern),
8573 Position1 is Position + 1,
8574 get_target_module(Mod),
8577 ( Mask /\ Pattern =:= Pattern ->
8578 arg(Position1,TAttr,Susps),
8579 'chr sbag_del_element'(Susps,Suspension,NewSusps),
8581 NewMask is Mask /\ DelPattern,
8585 setarg(1,TAttr,NewMask),
8586 setarg(Position1,TAttr,NewSusps)
8589 setarg(Position1,TAttr,NewSusps)
8597 rem_attr(N,Var,Suspension,Position,TAttr,Goal) :-
8598 % writeln(rem_attr),
8599 get_target_module(Mod),
8601 ( 'chr select'(TAttr,Position-Suspensions,RAttr) ->
8602 'chr sbag_del_element'(Suspensions,Suspension,NSuspensions),
8603 ( NSuspensions == [] ->
8607 put_attr(Var,Mod,RAttr)
8610 put_attr(Var,Mod,[Position-NSuspensions|RAttr])
8616 %-------------------------------------------------------------------------------
8617 % +N: number of constraint symbols
8618 % +TAttr1: source-level variable, for attribute
8619 % +TAttr2: source-level variable, for other attribute
8620 % -Goal: goal for merging the two attributes
8621 % -Attr: source-level term, for merged attribute
8622 merge_attributes(N,TAttr1,TAttr2,Goal,Attr) :-
8623 chr_pp_flag(dynattr,off), !,
8624 make_attr(N,Mask1,SuspsList1,Attr1),
8625 merge_attributes2(N,Mask1,SuspsList1,TAttr2,Goal2,Attr),
8632 merge_attributes(N,TAttr1,TAttr2,Goal,Attr) :-
8633 % writeln(merge_attributes),
8635 sort(TAttr1,Sorted1),
8636 sort(TAttr2,Sorted2),
8637 'chr new_merge_attributes'(Sorted1,Sorted2,Attr)
8641 %-------------------------------------------------------------------------------
8642 % +N: number of constraint symbols
8644 % +SuspsList1: static term, for suspensions list
8645 % +TAttr2: source-level variable, for other attribute
8646 % -Goal: goal for merging the two attributes
8647 % -Attr: source-level term, for merged attribute
8648 merge_attributes2(N,Mask1,SuspsList1,TAttr2,Goal,Attr) :-
8649 make_attr(N,Mask2,SuspsList2,Attr2),
8650 bagof(G,X ^ Y ^ SY ^ M ^ (member2(SuspsList1,SuspsList2,X-Y),G = (sort(Y,SY),'chr merge_attributes'(X,SY,M))),Gs),
8651 list2conj(Gs,SortGoals),
8652 bagof(MS,A ^ B ^ C ^ member((A,'chr merge_attributes'(B,C,MS)),Gs), SuspsList),
8653 make_attr(N,Mask,SuspsList,Attr),
8657 Mask is Mask1 \/ Mask2
8661 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8662 % Storetype dependent lookup
8664 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8665 %% lookup_passive_head(+Head,+PreviousVars,+RenamingVarDict,
8666 %% -Goal,-SuspensionList) is det.
8668 % Create a universal lookup goal for given head.
8669 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8670 lookup_passive_head(Head,PreJoin,VarDict,Goal,AllSusps) :-
8672 get_store_type(F/A,StoreType),
8673 lookup_passive_head(StoreType,Head,PreJoin,VarDict,[],Goal,AllSusps).
8675 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8676 %% lookup_passive_head(+Head,+PreviousVars,+RenamingVarDict,+GroundVars,
8677 %% -Goal,-SuspensionList) is det.
8679 % Create a universal lookup goal for given head.
8680 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8681 lookup_passive_head(Head,PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
8683 get_store_type(F/A,StoreType),
8684 lookup_passive_head(StoreType,Head,PreJoin,VarDict,GroundVars,Goal,AllSusps).
8686 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8687 %% lookup_passive_head(+StoreType,+Head,+PreviousVars,+RenamingVarDict,
8688 %% +GroundVars,-Goal,-SuspensionList) is det.
8690 % Create a universal lookup goal for given head.
8691 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8692 lookup_passive_head(default,Head,PreJoin,VarDict,_,Goal,AllSusps) :-
8694 passive_head_via(Head,PreJoin,VarDict,Goal,AllSusps),
8695 update_store_type(F/A,default).
8696 lookup_passive_head(multi_inthash(Indexes),Head,_PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
8697 hash_lookup_passive_head(inthash,Indexes,Head,VarDict,GroundVars,Goal,AllSusps,_).
8698 lookup_passive_head(multi_hash(Indexes),Head,_PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
8699 hash_lookup_passive_head(hash,Indexes,Head,VarDict,GroundVars,Goal,AllSusps,_).
8700 lookup_passive_head(global_ground,Head,_PreJoin,_VarDict,_,Goal,AllSusps) :-
8702 global_ground_store_name(F/A,StoreName),
8703 make_get_store_goal(StoreName,AllSusps,Goal), % Goal = nb_getval(StoreName,AllSusps),
8704 update_store_type(F/A,global_ground).
8705 lookup_passive_head(var_assoc_store(VarIndex,KeyIndex),Head,_PreJoin,VarDict,_,Goal,AllSusps) :-
8706 arg(VarIndex,Head,OVar),
8707 arg(KeyIndex,Head,OKey),
8708 translate([OVar,OKey],VarDict,[Var,Key]),
8709 get_target_module(Module),
8711 get_attr(Var,Module,AssocStore),
8712 lookup_assoc_store(AssocStore,Key,AllSusps)
8714 lookup_passive_head(global_singleton,Head,_PreJoin,_VarDict,_,Goal,AllSusps) :-
8716 global_singleton_store_name(F/A,StoreName),
8717 make_get_store_goal(StoreName,Susp,GetStoreGoal),
8718 Goal = (GetStoreGoal,Susp \== [],AllSusps = [Susp]),
8719 update_store_type(F/A,global_singleton).
8720 lookup_passive_head(multi_store(StoreTypes),Head,PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
8722 member(ST,StoreTypes),
8723 lookup_passive_head(ST,Head,PreJoin,VarDict,GroundVars,Goal,AllSusps)
8725 lookup_passive_head(identifier_store(Index),Head,PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
8727 arg(Index,Head,Var),
8728 translate([Var],VarDict,[KeyVar]),
8729 delay_phase_end(validate_store_type_assumptions,
8730 identifier_lookup(F/A,Index,AllSusps,KeyVar,Goal)
8732 update_store_type(F/A,identifier_store(Index)),
8733 get_identifier_index(F/A,Index,_).
8734 lookup_passive_head(type_indexed_identifier_store(Index,IndexType),Head,PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
8736 arg(Index,Head,Var),
8738 translate([Var],VarDict,[KeyVar]),
8740 ; ground(Var), Var = '$chr_identifier_match'(ActualVar,_) ->
8741 lookup_identifier_atom(IndexType,ActualVar,KeyVar,LookupGoal),
8742 Goal = (LookupGoal,StructGoal)
8744 delay_phase_end(validate_store_type_assumptions,
8745 type_indexed_identifier_lookup(F/A,Index,IndexType,AllSusps,KeyVar,StructGoal)
8747 update_store_type(F/A,type_indexed_identifier_store(Index,IndexType)),
8748 get_type_indexed_identifier_index(IndexType,F/A,Index,_).
8750 identifier_lookup(C,Index,AllSusps,KeyVar,Goal) :-
8751 get_identifier_size(ISize),
8752 functor(Struct,struct,ISize),
8753 get_identifier_index(C,Index,IIndex),
8754 arg(IIndex,Struct,AllSusps),
8755 Goal = (KeyVar = Struct).
8757 type_indexed_identifier_lookup(C,Index,IndexType,AllSusps,KeyVar,Goal) :-
8758 type_indexed_identifier_structure(IndexType,Struct),
8759 get_type_indexed_identifier_index(IndexType,C,Index,IIndex),
8760 arg(IIndex,Struct,AllSusps),
8761 Goal = (KeyVar = Struct).
8763 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8764 %% hash_lookup_passive_head(+StoreType,+Indexes,+Head,+RenamingVarDict,
8765 %% +GroundVars,-Goal,-SuspensionList,-Index) is det.
8767 % Create a universal hash lookup goal for given head.
8768 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8769 hash_lookup_passive_head(HashType,Indexes,Head,VarDict,GroundVars,Goal,AllSusps,Index) :-
8770 pick_hash_index(Indexes,Head,VarDict,Index,KeyArgs,KeyArgCopies),
8771 ( KeyArgCopies = [KeyCopy] ->
8774 KeyCopy =.. [k|KeyArgCopies]
8777 multi_hash_lookup_goal(F/A,HashType,Index,KeyCopy,AllSusps,LookupGoal),
8779 check_ground(GroundVars,KeyArgs,OriginalGroundCheck),
8780 my_term_copy(OriginalGroundCheck,VarDict,GroundCheck),
8782 Goal = (GroundCheck,LookupGoal),
8784 ( HashType == inthash ->
8785 update_store_type(F/A,multi_inthash([Index]))
8787 update_store_type(F/A,multi_hash([Index]))
8790 pick_hash_index(Indexes,Head,VarDict,Index,KeyArgs,KeyArgCopies) :-
8791 member(Index,Indexes),
8792 args(Index,Head,KeyArgs),
8793 key_in_scope(KeyArgs,VarDict,KeyArgCopies),
8796 % check whether we can copy the given terms
8797 % with the given dictionary, and, if so, do so
8798 key_in_scope([],VarDict,[]).
8799 key_in_scope([Arg|Args],VarDict,[ArgCopy|ArgCopies]) :-
8800 term_variables(Arg,Vars),
8801 translate(Vars,VarDict,VarCopies),
8802 copy_term(Arg/Vars,ArgCopy/VarCopies),
8803 key_in_scope(Args,VarDict,ArgCopies).
8805 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8806 %% existential_lookup(+StoreType,+Head,+PrevVariablesHead,+RenamingVarDict,
8807 %% +GroundVariables,-SuspensionTerm,-Goal,-SuspVar,
8808 %% +VarArgDict,-NewVarArgDict) is det.
8810 % Create existential lookup goal for given head.
8811 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8812 existential_lookup(var_assoc_store(VarIndex,KeyIndex),Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,Pairs) :- !,
8813 lookup_passive_head(var_assoc_store(VarIndex,KeyIndex),Head,PreJoin,VarDict,GroundVars,UniversalGoal,AllSusps),
8814 sbag_member_call(Susp,AllSusps,Sbag),
8816 delay_phase_end(validate_store_type_assumptions,
8817 ( static_suspension_term(F/A,SuspTerm),
8818 get_static_suspension_field(F/A,SuspTerm,state,active,GetState)
8827 existential_lookup(global_singleton,Head,_PreJoin,_VarDict,_,SuspTerm,Goal,Susp,Pairs,Pairs) :- !,
8829 global_singleton_store_name(F/A,StoreName),
8830 make_get_store_goal(StoreName,Susp,GetStoreGoal),
8832 GetStoreGoal, % nb_getval(StoreName,Susp),
8836 update_store_type(F/A,global_singleton).
8837 existential_lookup(multi_store(StoreTypes),Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :- !,
8839 member(ST,StoreTypes),
8840 existential_lookup(ST,Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs)
8842 existential_lookup(multi_inthash(Indexes),Head,_,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :- !,
8843 existential_hash_lookup(inthash,Indexes,Head,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs).
8844 existential_lookup(multi_hash(Indexes),Head,_,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :- !,
8845 existential_hash_lookup(hash,Indexes,Head,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs).
8846 existential_lookup(identifier_store(Index),Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :- !,
8847 lookup_passive_head(identifier_store(Index),Head,PreJoin,VarDict,GroundVars,LookupGoal,AllSusps),
8848 hash_index_filter(Pairs,Index,NPairs),
8851 ( check_fd_lookup_condition(F,A,Head,KeyArgs) ->
8852 Sbag = (AllSusps = [Susp])
8854 sbag_member_call(Susp,AllSusps,Sbag)
8856 delay_phase_end(validate_store_type_assumptions,
8857 ( static_suspension_term(F/A,SuspTerm),
8858 get_static_suspension_field(F/A,SuspTerm,state,active,GetState)
8864 Susp = SuspTerm, % not inlined
8867 existential_lookup(type_indexed_identifier_store(Index,IndexType),Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :- !,
8868 lookup_passive_head(type_indexed_identifier_store(Index,IndexType),Head,PreJoin,VarDict,GroundVars,LookupGoal,AllSusps),
8869 hash_index_filter(Pairs,Index,NPairs),
8872 ( check_fd_lookup_condition(F,A,Head,KeyArgs) ->
8873 Sbag = (AllSusps = [Susp])
8875 sbag_member_call(Susp,AllSusps,Sbag)
8877 delay_phase_end(validate_store_type_assumptions,
8878 ( static_suspension_term(F/A,SuspTerm),
8879 get_static_suspension_field(F/A,SuspTerm,state,active,GetState)
8885 Susp = SuspTerm, % not inlined
8888 existential_lookup(StoreType,Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,Pairs) :-
8889 lookup_passive_head(StoreType,Head,PreJoin,VarDict,GroundVars,UGoal,Susps),
8890 sbag_member_call(Susp,Susps,Sbag),
8892 delay_phase_end(validate_store_type_assumptions,
8893 ( static_suspension_term(F/A,SuspTerm),
8894 get_static_suspension_field(F/A,SuspTerm,state,active,GetState)
8900 Susp = SuspTerm, % not inlined
8904 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8905 %% existential_hash_lookup(+StoreType,+Indexes,+Head,+RenamingVarDict,
8906 %% +GroundVariables,-SuspensionTerm,-Goal,-SuspVar,
8907 %% +VarArgDict,-NewVarArgDict) is det.
8909 % Create existential hash lookup goal for given head.
8910 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8911 existential_hash_lookup(HashType,Indexes,Head,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :-
8912 hash_lookup_passive_head(HashType,Indexes,Head,VarDict,GroundVars,LookupGoal,AllSusps,Index),
8914 hash_index_filter(Pairs,Index,NPairs),
8917 ( check_fd_lookup_condition(F,A,Head,KeyArgs) ->
8918 Sbag = (AllSusps = [Susp])
8920 sbag_member_call(Susp,AllSusps,Sbag)
8922 delay_phase_end(validate_store_type_assumptions,
8923 ( static_suspension_term(F/A,SuspTerm),
8924 get_static_suspension_field(F/A,SuspTerm,state,active,GetState)
8930 Susp = SuspTerm, % not inlined
8934 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8935 %% hash_index_filter(+Pairs,+Index,-NPairs) is det.
8937 % Filter out pairs already covered by given hash index.
8938 % makes them 'silent'
8939 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8940 hash_index_filter(Pairs,Index,NPairs) :-
8941 hash_index_filter(Pairs,Index,1,NPairs).
8943 hash_index_filter([],_,_,[]).
8944 hash_index_filter([P|Ps],Index,N,NPairs) :-
8949 hash_index_filter(Ps,[I|Is],NN,NPs)
8951 NPairs = [silent(P)|NPs],
8952 hash_index_filter(Ps,Is,NN,NPs)
8958 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8959 %------------------------------------------------------------------------------%
8960 %% assume_constraint_stores(+ConstraintSymbols) is det.
8962 % Compute all constraint store types that are possible for the given
8963 % =ConstraintSymbols=.
8964 %------------------------------------------------------------------------------%
8965 assume_constraint_stores([]).
8966 assume_constraint_stores([C|Cs]) :-
8967 ( chr_pp_flag(debugable,off),
8968 ( only_ground_indexed_arguments(C) ; chr_pp_flag(mixed_stores,on) ),
8970 get_store_type(C,default) ->
8971 get_indexed_arguments(C,AllIndexedArgs),
8972 get_constraint_mode(C,Modes),
8973 aggregate_all(bag(Index)-count,
8974 (member(Index,AllIndexedArgs),nth1(Index,Modes,+)),
8975 IndexedArgs-NbIndexedArgs),
8976 % Construct Index Combinations
8977 ( NbIndexedArgs > 10 ->
8978 findall([Index],member(Index,IndexedArgs),Indexes)
8980 findall(Index,(sublist(Index,IndexedArgs), Index \== []),UnsortedIndexes),
8981 predsort(longer_list,UnsortedIndexes,Indexes)
8983 % EXPERIMENTAL HEURISTIC
8985 % member(Arg1,IndexedArgs),
8986 % member(Arg2,IndexedArgs),
8988 % sort([Arg1,Arg2], Index)
8989 % ), UnsortedIndexes),
8990 % predsort(longer_list,UnsortedIndexes,Indexes),
8992 ( get_functional_dependency(C,1,Pattern,Key),
8993 all_distinct_var_args(Pattern), Key == [] ->
8994 assumed_store_type(C,global_singleton)
8995 ; ( only_ground_indexed_arguments(C) ; NbIndexedArgs > 0 ) ->
8996 get_constraint_type_det(C,ArgTypes),
8997 partition_indexes(Indexes,ArgTypes,HashIndexes,IntHashIndexes,IdentifierIndexes,CompoundIdentifierIndexes),
8999 ( IntHashIndexes = [] ->
9002 Stores = [multi_inthash(IntHashIndexes)|Stores1]
9004 ( HashIndexes = [] ->
9007 Stores1 = [multi_hash(HashIndexes)|Stores2]
9009 ( IdentifierIndexes = [] ->
9012 maplist(wrap_in_functor(identifier_store),IdentifierIndexes,WrappedIdentifierIndexes),
9013 append(WrappedIdentifierIndexes,Stores3,Stores2)
9015 append(CompoundIdentifierIndexes,Stores4,Stores3),
9016 ( only_ground_indexed_arguments(C)
9017 -> Stores4 = [global_ground]
9018 ; Stores4 = [default]
9020 assumed_store_type(C,multi_store(Stores))
9026 assume_constraint_stores(Cs).
9028 %------------------------------------------------------------------------------%
9029 %% partition_indexes(+Indexes,+Types,
9030 %% -HashIndexes,-IntHashIndexes,-IdentifierIndexes) is det.
9031 %------------------------------------------------------------------------------%
9032 partition_indexes([],_,[],[],[],[]).
9033 partition_indexes([Index|Indexes],Types,HashIndexes,IntHashIndexes,IdentifierIndexes,CompoundIdentifierIndexes) :-
9036 unalias_type(Type,UnAliasedType),
9037 UnAliasedType == chr_identifier ->
9038 IdentifierIndexes = [I|RIdentifierIndexes],
9039 IntHashIndexes = RIntHashIndexes,
9040 HashIndexes = RHashIndexes,
9041 CompoundIdentifierIndexes = RCompoundIdentifierIndexes
9044 unalias_type(Type,UnAliasedType),
9045 nonvar(UnAliasedType),
9046 UnAliasedType = chr_identifier(IndexType) ->
9047 CompoundIdentifierIndexes = [type_indexed_identifier_store(I,IndexType)|RCompoundIdentifierIndexes],
9048 IdentifierIndexes = RIdentifierIndexes,
9049 IntHashIndexes = RIntHashIndexes,
9050 HashIndexes = RHashIndexes
9053 unalias_type(Type,UnAliasedType),
9054 UnAliasedType == dense_int ->
9055 IntHashIndexes = [Index|RIntHashIndexes],
9056 HashIndexes = RHashIndexes,
9057 IdentifierIndexes = RIdentifierIndexes,
9058 CompoundIdentifierIndexes = RCompoundIdentifierIndexes
9061 unalias_type(Type,UnAliasedType),
9062 nonvar(UnAliasedType),
9063 UnAliasedType = chr_identifier(_) ->
9064 % don't use chr_identifiers in hash indexes
9065 IntHashIndexes = RIntHashIndexes,
9066 HashIndexes = RHashIndexes,
9067 IdentifierIndexes = RIdentifierIndexes,
9068 CompoundIdentifierIndexes = RCompoundIdentifierIndexes
9070 IntHashIndexes = RIntHashIndexes,
9071 HashIndexes = [Index|RHashIndexes],
9072 IdentifierIndexes = RIdentifierIndexes,
9073 CompoundIdentifierIndexes = RCompoundIdentifierIndexes
9075 partition_indexes(Indexes,Types,RHashIndexes,RIntHashIndexes,RIdentifierIndexes,RCompoundIdentifierIndexes).
9077 longer_list(R,L1,L2) :-
9087 all_distinct_var_args(Term) :-
9088 copy_term_nat(Term,TermCopy),
9090 functor(Pattern,F,A),
9091 Pattern =@= TermCopy.
9093 get_indexed_arguments(C,IndexedArgs) :-
9095 get_indexed_arguments(1,A,C,IndexedArgs).
9097 get_indexed_arguments(I,N,C,L) :-
9100 ; ( is_indexed_argument(C,I) ->
9106 get_indexed_arguments(J,N,C,T)
9109 validate_store_type_assumptions([]).
9110 validate_store_type_assumptions([C|Cs]) :-
9111 validate_store_type_assumption(C),
9112 validate_store_type_assumptions(Cs).
9114 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9115 % new code generation
9116 universal_search_iterator_end([CurrentHead|PrevHeads],NextHeads,Rule,F/A,O,Id,L,T) :-
9117 Rule = rule(H1,_,Guard,Body),
9118 gen_var_susp_list_for_b(PrevHeads,[CurrentHead,NextHeads,Guard,Body],_,VarsAndSuspsList,FirstVarsSusp,_,PrevIterators),
9119 universal_search_iterator_failure_vars(PrevHeads,Id,VarsAndSuspsList,FirstVarsSusp,PrevIterators,PrevVarsAndSusps,PrevId0),
9120 flatten(VarsAndSuspsList,VarsAndSusps),
9121 Vars = [ [] | VarsAndSusps],
9122 build_head(F,A,[O|Id],Vars,Head),
9124 get_success_continuation_code_id(F/A,O,PredictedPrevId),
9125 % format('~w == ~w ?\n',[PrevId0,PredictedPrevId]),
9126 PrevId = [PredictedPrevId] % PrevId = PrevId0
9128 PrevId = [O|PrevId0]
9130 build_head(F,A,PrevId,PrevVarsAndSusps,PredecessorCall),
9131 Clause = ( Head :- PredecessorCall),
9132 add_dummy_location(Clause,LocatedClause),
9133 L = [LocatedClause | T].
9135 % functor(CurrentHead,CF,CA),
9136 % check_fd_lookup_condition(CF,CA,CurrentHead,PrevHeads) ->
9139 % gen_var_susp_list_for_b(PrevHeads,[CurrentHead,NextHeads,Guard,Body],_,VarsAndSuspsList,FirstVarsSusp,_,PrevIterators),
9140 % universal_search_iterator_failure_vars(PrevHeads,Id,VarsAndSuspsList,FirstVarsSusp,PrevIterators,PrevVarsAndSusps,PrevId),
9141 % flatten(VarsAndSuspsList,VarsAndSusps),
9142 % Vars = [ [] | VarsAndSusps],
9143 % build_head(F,A,Id,Vars,Head),
9144 % build_head(F,A,PrevId,PrevVarsAndSusps,PredecessorCall),
9145 % Clause = ( Head :- PredecessorCall),
9149 % skips back intelligently over global_singleton lookups
9150 universal_search_iterator_failure_vars(PrevHeads,Id,VarsAndSuspsList,BaseCallArgs,PrevIterators,PrevVarsAndSusps,PrevId) :-
9152 % TOM: add partial success continuation optimization here!
9154 PrevVarsAndSusps = BaseCallArgs
9156 VarsAndSuspsList = [_|AllButFirstList],
9158 ( PrevHeads = [PrevHead|PrevHeads1],
9159 functor(PrevHead,F,A),
9160 check_fd_lookup_condition(F,A,PrevHead,PrevHeads1) ->
9161 PrevIterators = [_|PrevIterators1],
9162 universal_search_iterator_failure_vars(PrevHeads1,PrevId1,AllButFirstList,BaseCallArgs,PrevIterators1,PrevVarsAndSusps,PrevId)
9165 flatten(AllButFirstList,AllButFirst),
9166 PrevIterators = [PrevIterator|_],
9167 PrevVarsAndSusps = [PrevIterator|AllButFirst]
9171 universal_search_iterator([NextHead|RestHeads],[CurrentHead|PreHeads],Rule,F/A,O,Id,L,T) :-
9172 Rule = rule(_,_,Guard,Body),
9173 gen_var_susp_list_for_b(PreHeads,[CurrentHead,NextHead,RestHeads,Guard,Body],VarDict,PreVarsAndSuspsList,FirstVarsSusp,AllSusps,PrevIterators),
9174 init(AllSusps,PreSusps),
9175 flatten(PreVarsAndSuspsList,PreVarsAndSusps),
9176 gen_var(OtherSusps),
9177 functor(CurrentHead,OtherF,OtherA),
9178 gen_vars(OtherA,OtherVars),
9179 head_info(CurrentHead,OtherA,OtherVars,OtherSusp,_VarsSusp,HeadPairs),
9180 get_constraint_mode(OtherF/OtherA,Mode),
9181 head_arg_matches(HeadPairs,Mode,VarDict,FirstMatching,VarDict1),
9183 delay_phase_end(validate_store_type_assumptions,
9184 ( static_suspension_term(OtherF/OtherA,OtherSuspension),
9185 get_static_suspension_field(OtherF/OtherA,OtherSuspension,state,active,GetState),
9186 get_static_suspension_term_field(arguments,OtherF/OtherA,OtherSuspension,OtherVars)
9190 different_from_other_susps(CurrentHead,OtherSusp,PreHeads,PreSusps,DiffSuspGoals),
9191 % create_get_mutable_ref(active,State,GetMutable),
9193 OtherSusp = OtherSuspension,
9198 add_heads_ground_variables([CurrentHead|PreHeads],[],GroundVars),
9199 lookup_passive_head(NextHead,[CurrentHead|PreHeads],VarDict1,GroundVars,NextSuspGoal,NextSusps),
9200 inc_id(Id,NestedId),
9201 ClauseVars = [[OtherSusp|OtherSusps]|PreVarsAndSusps],
9202 build_head(F,A,[O|Id],ClauseVars,ClauseHead),
9203 passive_delegate_variables(CurrentHead,PreHeads,[NextHead,RestHeads,Guard,Body],VarDict1,CurrentHeadVars),
9204 append([NextSusps|CurrentHeadVars],[OtherSusp,OtherSusps|PreVarsAndSusps],NestedVars),
9205 build_head(F,A,[O|NestedId],NestedVars,NestedHead),
9207 ( check_fd_lookup_condition(OtherF,OtherA,CurrentHead,PreHeads) -> % iterator (OtherSusps) is empty at runtime
9208 universal_search_iterator_failure_vars(PreHeads,Id,PreVarsAndSuspsList,FirstVarsSusp,PrevIterators,PreVarsAndSusps1,PrevId0),
9209 RecursiveVars = PreVarsAndSusps1
9211 RecursiveVars = [OtherSusps|PreVarsAndSusps],
9217 PrevId = [O|PrevId0]
9219 build_head(F,A,PrevId,RecursiveVars,RecursiveHead),
9230 add_dummy_location(Clause,LocatedClause),
9231 L = [LocatedClause|T].
9233 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9235 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9236 % Observation Analysis
9241 % Analysis based on Abstract Interpretation paper.
9244 % stronger analysis domain [research]
9247 initial_call_pattern/1,
9249 call_pattern_worker/1,
9250 final_answer_pattern/2,
9251 abstract_constraints/1,
9255 ai_observed_internal/2,
9257 ai_not_observed_internal/2,
9261 ai_observation_gather_results/0.
9263 :- chr_type abstract_domain ---> odom(program_point,list(constraint)).
9264 :- chr_type program_point == any.
9266 :- chr_option(mode,initial_call_pattern(+)).
9267 :- chr_option(type_declaration,call_pattern(abstract_domain)).
9269 :- chr_option(mode,call_pattern(+)).
9270 :- chr_option(type_declaration,call_pattern(abstract_domain)).
9272 :- chr_option(mode,call_pattern_worker(+)).
9273 :- chr_option(type_declaration,call_pattern_worker(abstract_domain)).
9275 :- chr_option(mode,final_answer_pattern(+,+)).
9276 :- chr_option(type_declaration,final_answer_pattern(abstract_domain,abstract_domain)).
9278 :- chr_option(mode,abstract_constraints(+)).
9279 :- chr_option(type_declaration,abstract_constraints(list)).
9281 :- chr_option(mode,depends_on(+,+)).
9282 :- chr_option(type_declaration,depends_on(abstract_domain,abstract_domain)).
9284 :- chr_option(mode,depends_on_as(+,+,+)).
9285 :- chr_option(mode,depends_on_ap(+,+,+,+)).
9286 :- chr_option(mode,depends_on_goal(+,+)).
9287 :- chr_option(mode,ai_is_observed(+,+)).
9288 :- chr_option(mode,ai_not_observed(+,+)).
9289 % :- chr_option(mode,ai_observed(+,+)).
9290 :- chr_option(mode,ai_not_observed_internal(+,+)).
9291 :- chr_option(mode,ai_observed_internal(+,+)).
9294 abstract_constraints_fd @
9295 abstract_constraints(_) \ abstract_constraints(_) <=> true.
9297 ai_observed_internal(C,O) \ ai_not_observed_internal(C,O) <=> true.
9298 ai_not_observed_internal(C,O) \ ai_not_observed_internal(C,O) <=> true.
9299 ai_observed_internal(C,O) \ ai_observed_internal(C,O) <=> true.
9301 ai_not_observed(C,O) \ ai_is_observed(C,O) <=> fail.
9302 ai_is_observed(_,_) <=> true.
9304 ai_observation_gather_results \ ai_observed_internal(C,O) <=> true. % ai_observed(C,O).
9305 ai_observation_gather_results \ ai_not_observed_internal(C,O) <=> ai_not_observed(C,O).
9306 ai_observation_gather_results <=> true.
9308 %------------------------------------------------------------------------------%
9309 % Main Analysis Entry
9310 %------------------------------------------------------------------------------%
9311 ai_observation_analysis(ACs) :-
9312 ( chr_pp_flag(ai_observation_analysis,on),
9313 get_target_module(Module), '$chr_compiled_with_version'(3) -> % , Module \== guard_entailment ->
9314 list_to_ord_set(ACs,ACSet),
9315 abstract_constraints(ACSet),
9316 ai_observation_schedule_initial_calls(ACSet,ACSet),
9317 ai_observation_gather_results
9322 ai_observation_schedule_initial_calls([],_).
9323 ai_observation_schedule_initial_calls([AC|RACs],ACs) :-
9324 ai_observation_schedule_initial_call(AC,ACs),
9325 ai_observation_schedule_initial_calls(RACs,ACs).
9327 ai_observation_schedule_initial_call(AC,ACs) :-
9328 ai_observation_top(AC,CallPattern),
9329 % ai_observation_bot(AC,ACs,CallPattern),
9330 initial_call_pattern(CallPattern).
9332 ai_observation_schedule_new_calls([],AP).
9333 ai_observation_schedule_new_calls([AC|ACs],AP) :-
9335 initial_call_pattern(odom(AC,Set)),
9336 ai_observation_schedule_new_calls(ACs,AP).
9338 final_answer_pattern(CP,AP1) \ final_answer_pattern(CP,AP2)
9340 ai_observation_leq(AP2,AP1)
9344 initial_call_pattern(CP) \ initial_call_pattern(CP) <=> true.
9346 initial_call_pattern(CP) ==> call_pattern(CP).
9348 initial_call_pattern(CP), final_answer_pattern(CP,AP), abstract_constraints(ACs) # ID3
9350 ai_observation_schedule_new_calls(ACs,AP)
9354 call_pattern(CP) \ call_pattern(CP) <=> true.
9356 depends_on(CP1,CP2), final_answer_pattern(CP2,AP) ==>
9357 final_answer_pattern(CP1,AP).
9359 %call_pattern(CP) ==> writeln(call_pattern(CP)).
9361 call_pattern(CP) ==> call_pattern_worker(CP).
9363 %------------------------------------------------------------------------------%
9365 %------------------------------------------------------------------------------%
9368 %call_pattern(odom([],Set)) ==>
9369 % final_answer_pattern(odom([],Set),odom([],Set)).
9371 call_pattern_worker(odom([],Set)) <=>
9372 % writeln(' - AbstractGoal'(odom([],Set))),
9373 final_answer_pattern(odom([],Set),odom([],Set)).
9376 call_pattern_worker(odom([G|Gs],Set)) <=>
9377 % writeln(' - AbstractGoal'(odom([G|Gs],Set))),
9379 depends_on_goal(odom([G|Gs],Set),CP1),
9382 depends_on_goal(CP1,CP2), final_answer_pattern(CP2,AP2) \ depends_on(CP1,_) # ID
9383 <=> true pragma passive(ID).
9384 depends_on_goal(CP1,CP2), final_answer_pattern(CP2,AP2)
9386 CP1 = odom([_|Gs],_),
9390 depends_on(CP1,CCP).
9392 %------------------------------------------------------------------------------%
9393 % Abstract Disjunction
9394 %------------------------------------------------------------------------------%
9396 call_pattern_worker(odom((AG1;AG2),Set)) <=>
9397 CP = odom((AG1;AG2),Set),
9398 InitialAnswerApproximation = odom([],Set),
9399 final_answer_pattern(CP,InitialAnswerApproximation),
9400 CP1 = odom(AG1,Set),
9401 CP2 = odom(AG2,Set),
9404 depends_on_as(CP,CP1,CP2).
9406 %------------------------------------------------------------------------------%
9408 %------------------------------------------------------------------------------%
9409 call_pattern_worker(odom(builtin,Set)) <=>
9410 % writeln(' - AbstractSolve'(odom(builtin,Set))),
9411 ord_empty(EmptySet),
9412 final_answer_pattern(odom(builtin,Set),odom([],EmptySet)).
9414 %------------------------------------------------------------------------------%
9416 %------------------------------------------------------------------------------%
9417 max_occurrence(C,MO) # ID2 \ call_pattern_worker(odom(occ(C,O),Set))
9421 % writeln(' - AbstractDrop'(odom(occ(C,O),Set))),
9422 final_answer_pattern(odom(occ(C,O),Set),odom([],Set))
9426 %------------------------------------------------------------------------------%
9428 %------------------------------------------------------------------------------%
9429 call_pattern_worker(odom(AC,Set))
9433 % writeln(' - AbstractActivate'(odom(AC,Set))),
9434 CP = odom(occ(AC,1),Set),
9436 depends_on(odom(AC,Set),CP).
9438 %------------------------------------------------------------------------------%
9440 %------------------------------------------------------------------------------%
9441 occurrence(C,O,RuleNb,ID,_) # ID2 \ call_pattern_worker(odom(occ(C,O),Set))
9443 is_passive(RuleNb,ID)
9445 % writeln(' - AbstractPassive'(odom(occ(C,O),Set))),
9448 DCP = odom(occ(C,NO),Set),
9450 final_answer_pattern(odom(occ(C,O),Set),odom([],Set)),
9451 depends_on(odom(occ(C,O),Set),DCP)
9454 %------------------------------------------------------------------------------%
9456 %------------------------------------------------------------------------------%
9459 occurrence(C,O,RuleNb,ID,simplification) # ID2 \ call_pattern_worker(odom(occ(C,O),Set))
9461 \+ is_passive(RuleNb,ID)
9463 % writeln(' - AbstractPassive'(odom(occ(C,O),Set))),
9464 ai_observation_memo_simplification_rest_heads(C,O,AbstractRestHeads),
9465 ai_observation_observe_set(Set,AbstractRestHeads,Set2),
9466 ai_observation_memo_abstract_goal(RuleNb,AG),
9467 call_pattern(odom(AG,Set2)),
9470 DCP = odom(occ(C,NO),Set),
9472 depends_on_as(odom(occ(C,O),Set),odom(AG,Set2),DCP),
9473 % DEADLOCK AVOIDANCE
9474 final_answer_pattern(odom(occ(C,O),Set),odom([],Set))
9478 depends_on_as(CP,CPS,CPD),
9479 final_answer_pattern(CPS,APS),
9480 final_answer_pattern(CPD,APD) ==>
9481 ai_observation_lub(APS,APD,AP),
9482 final_answer_pattern(CP,AP).
9486 ai_observation_memo_simplification_rest_heads/3,
9487 ai_observation_memoed_simplification_rest_heads/3.
9489 :- chr_option(mode,ai_observation_memo_simplification_rest_heads(+,+,?)).
9490 :- chr_option(mode,ai_observation_memoed_simplification_rest_heads(+,+,+)).
9492 ai_observation_memoed_simplification_rest_heads(C,O,RH) \ ai_observation_memo_simplification_rest_heads(C,O,QRH)
9495 abstract_constraints(ACs) # ID1, occurrence(C,O,RuleNb,ID,_) # ID2, rule(RuleNb,Rule) # ID3 \ ai_observation_memo_simplification_rest_heads(C,O,QRH)
9497 Rule = pragma(rule(H1,H2,_,_),ids(IDs1,_),_,_,_),
9498 once(select2(ID,_,IDs1,H1,_,RestH1)),
9499 ai_observation_abstract_constraints(RestH1,ACs,ARestHeads),
9500 ai_observation_abstract_constraints(H2,ACs,AH2),
9501 append(ARestHeads,AH2,AbstractHeads),
9502 sort(AbstractHeads,QRH),
9503 ai_observation_memoed_simplification_rest_heads(C,O,QRH)
9509 ai_observation_memo_simplification_rest_heads(_,_,_) <=> fail.
9511 %------------------------------------------------------------------------------%
9512 % Abstract Propagate
9513 %------------------------------------------------------------------------------%
9517 occurrence(C,O,RuleNb,ID,propagation) # ID2 \ call_pattern_worker(odom(occ(C,O),Set))
9519 \+ is_passive(RuleNb,ID)
9521 % writeln(' - AbstractPropagate'(odom(occ(C,O),Set))),
9523 ai_observation_memo_propagation_rest_heads(C,O,AHs),
9524 ai_observation_observe_set(Set,AHs,Set2),
9525 ord_add_element(Set2,C,Set3),
9526 ai_observation_memo_abstract_goal(RuleNb,AG),
9527 call_pattern(odom(AG,Set3)),
9528 ( ord_memberchk(C,Set2) ->
9535 DCP = odom(occ(C,NO),Set),
9537 depends_on_ap(odom(occ(C,O),Set),odom(AG,Set3),DCP,Delete)
9542 ai_observation_memo_propagation_rest_heads/3,
9543 ai_observation_memoed_propagation_rest_heads/3.
9545 :- chr_option(mode,ai_observation_memo_propagation_rest_heads(+,+,?)).
9546 :- chr_option(mode,ai_observation_memoed_propagation_rest_heads(+,+,+)).
9548 ai_observation_memoed_propagation_rest_heads(C,O,RH) \ ai_observation_memo_propagation_rest_heads(C,O,QRH)
9551 abstract_constraints(ACs) # ID1, occurrence(C,O,RuleNb,ID,_) # ID2, rule(RuleNb,Rule) # ID3 \ ai_observation_memo_propagation_rest_heads(C,O,QRH)
9553 Rule = pragma(rule(H1,H2,_,_),ids(_,IDs2),_,_,_),
9554 once(select2(ID,_,IDs2,H2,_,RestH2)),
9555 ai_observation_abstract_constraints(RestH2,ACs,ARestHeads),
9556 ai_observation_abstract_constraints(H1,ACs,AH1),
9557 append(ARestHeads,AH1,AbstractHeads),
9558 sort(AbstractHeads,QRH),
9559 ai_observation_memoed_propagation_rest_heads(C,O,QRH)
9565 ai_observation_memo_propagation_rest_heads(_,_,_) <=> fail.
9567 depends_on_ap(CP,CPP,CPD,Delete), final_answer_pattern(CPD,APD) ==>
9568 final_answer_pattern(CP,APD).
9569 depends_on_ap(CP,CPP,CPD,Delete), final_answer_pattern(CPP,APP),
9570 final_answer_pattern(CPD,APD) ==>
9572 CP = odom(occ(C,O),_),
9573 ( ai_observation_is_observed(APP,C) ->
9574 ai_observed_internal(C,O)
9576 ai_not_observed_internal(C,O)
9579 APP = odom([],Set0),
9580 ord_del_element(Set0,C,Set),
9585 ai_observation_lub(NAPP,APD,AP),
9586 final_answer_pattern(CP,AP).
9588 %------------------------------------------------------------------------------%
9590 %------------------------------------------------------------------------------%
9592 call_pattern_worker(CP) <=> chr_error(internal,'AI observation analysis: unexpected abstract state ~w\n',[CP]).
9594 %------------------------------------------------------------------------------%
9595 % Auxiliary Predicates
9596 %------------------------------------------------------------------------------%
9598 ai_observation_lub(odom(AG,S1),odom(AG,S2),odom(AG,S3)) :-
9599 ord_intersection(S1,S2,S3).
9601 ai_observation_bot(AG,AS,odom(AG,AS)).
9603 ai_observation_top(AG,odom(AG,EmptyS)) :-
9606 ai_observation_leq(odom(AG,S1),odom(AG,S2)) :-
9609 ai_observation_observe_set(S,ACSet,NS) :-
9610 ord_subtract(S,ACSet,NS).
9612 ai_observation_abstract_constraint(C,ACs,AC) :-
9617 ai_observation_abstract_constraints(Cs,ACs,NACs) :-
9618 findall(NAC,(member(C,Cs),ai_observation_abstract_constraint(C,ACs,NAC)),NACs).
9620 %------------------------------------------------------------------------------%
9621 % Abstraction of Rule Bodies
9622 %------------------------------------------------------------------------------%
9625 ai_observation_memoed_abstract_goal/2,
9626 ai_observation_memo_abstract_goal/2.
9628 :- chr_option(mode,ai_observation_memoed_abstract_goal(+,+)).
9629 :- chr_option(mode,ai_observation_memo_abstract_goal(+,?)).
9631 ai_observation_memoed_abstract_goal(RuleNb,AG) # ID1 \ ai_observation_memo_abstract_goal(RuleNb,QAG)
9637 rule(RuleNb,Rule) # ID1, abstract_constraints(ACs) # ID2 \ ai_observation_memo_abstract_goal(RuleNb,QAG)
9639 Rule = pragma(rule(H1,H2,Guard,Body),_,_,_,_),
9640 ai_observation_abstract_goal_(H1,H2,Guard,Body,ACs,AG),
9642 ai_observation_memoed_abstract_goal(RuleNb,AG)
9647 ai_observation_abstract_goal_(H1,H2,Guard,G,ACs,AG) :-
9648 % also guard: e.g. b, c(X) ==> Y=X | p(Y).
9649 term_variables((H1,H2,Guard),HVars),
9650 append(H1,H2,Heads),
9651 % variables that are declared to be ground are safe,
9652 ground_vars(Heads,GroundVars),
9653 % so we remove them from the list of 'dangerous' head variables
9654 list_difference_eq(HVars,GroundVars,HV),
9655 ai_observation_abstract_goal(G,ACs,AG,[],HV),!.
9656 % writeln(ai_observation_abstract_goal(G,ACs,AG,[],HV)).
9657 % HV are 'dangerous' variables, all others are fresh and safe
9660 ground_vars([H|Hs],GroundVars) :-
9662 get_constraint_mode(F/A,Mode),
9663 % TOM: fix this code!
9664 head_info(H,A,_Vars,_Susp,_HeadVars,HeadPairs),
9665 head_arg_matches(HeadPairs,Mode,[],_FirstMatching,_VarDict1,[],GroundVars1),
9666 ground_vars(Hs,GroundVars2),
9667 append(GroundVars1,GroundVars2,GroundVars).
9669 ai_observation_abstract_goal((G1,G2),ACs,List,Tail,HV) :- !, % conjunction
9670 ai_observation_abstract_goal(G1,ACs,List,IntermediateList,HV),
9671 ai_observation_abstract_goal(G2,ACs,IntermediateList,Tail,HV).
9672 ai_observation_abstract_goal((G1;G2),ACs,[(ABranch1;ABranch2)|Tail],Tail,HV) :- !, % disjunction
9673 ai_observation_abstract_goal(G1,ACs,ABranch1,[],HV),
9674 ai_observation_abstract_goal(G2,ACs,ABranch2,[],HV).
9675 ai_observation_abstract_goal((G1->G2),ACs,List,Tail,HV) :- !, % if-then
9676 ai_observation_abstract_goal(G1,ACs,List,IntermediateList,HV),
9677 ai_observation_abstract_goal(G2,ACs,IntermediateList,Tail,HV).
9678 ai_observation_abstract_goal(C,ACs,[AC|Tail],Tail,HV) :-
9679 ai_observation_abstract_constraint(C,ACs,AC), !. % CHR constraint
9680 ai_observation_abstract_goal(true,_,Tail,Tail,_) :- !.
9681 ai_observation_abstract_goal(writeln(_),_,Tail,Tail,_) :- !.
9682 % non-CHR constraint is safe if it only binds fresh variables
9683 ai_observation_abstract_goal(G,_,Tail,Tail,HV) :-
9684 builtin_binds_b(G,Vars),
9685 intersect_eq(Vars,HV,[]),
9687 ai_observation_abstract_goal(G,_,[AG|Tail],Tail,_) :-
9688 AG = builtin. % default case if goal is not recognized/safe
9690 ai_observation_is_observed(odom(_,ACSet),AC) :-
9691 \+ ord_memberchk(AC,ACSet).
9693 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9694 unconditional_occurrence(C,O) :-
9695 get_occurrence(C,O,RuleNb,ID),
9696 get_rule(RuleNb,PRule),
9697 PRule = pragma(ORule,_,_,_,_),
9698 copy_term_nat(ORule,Rule),
9699 Rule = rule(H1,H2,Guard,_),
9700 guard_entailment:entails_guard([chr_pp_headvariables(H1,H2)],Guard),
9702 H1 = [Head], H2 == []
9704 H2 = [Head], H1 == [], \+ may_trigger(C)
9706 all_distinct_var_args(Head).
9708 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9710 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9711 % Partial wake analysis
9713 % In a Var = Var unification do not wake up constraints of both variables,
9714 % but rather only those of one variable.
9715 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9717 :- chr_constraint partial_wake_analysis/0.
9718 :- chr_constraint no_partial_wake/1.
9719 :- chr_option(mode,no_partial_wake(+)).
9720 :- chr_constraint wakes_partially/1.
9721 :- chr_option(mode,wakes_partially(+)).
9723 partial_wake_analysis, occurrence(FA,O,RuleNb,ID,Type), rule(RuleNb,Rule), constraint_mode(FA,ArgModes)
9725 Rule = pragma(rule(H1,H2,Guard,Body),_,_,_,_),
9726 ( is_passive(RuleNb,ID) ->
9728 ; Type == simplification ->
9729 select(H,H1,RestH1),
9731 term_variables(Guard,Vars),
9732 partial_wake_args(Args,ArgModes,Vars,FA)
9733 ; % Type == propagation ->
9734 select(H,H2,RestH2),
9736 term_variables(Guard,Vars),
9737 partial_wake_args(Args,ArgModes,Vars,FA)
9740 partial_wake_args([],_,_,_).
9741 partial_wake_args([Arg|Args],[Mode|Modes],Vars,C) :-
9745 ; memberchk_eq(Arg,Vars) ->
9753 partial_wake_args(Args,Modes,Vars,C).
9755 no_partial_wake(C) \ no_partial_wake(C) <=> true.
9757 no_partial_wake(C) \ wakes_partially(C) <=> fail.
9759 wakes_partially(C) <=> true.
9762 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9763 % Generate rules that implement chr_show_store/1 functionality.
9769 % Generates additional rules:
9771 % $show, C1 # ID ==> writeln(C1) pragma passive(ID).
9773 % $show, Cn # ID ==> writeln(Cn) pragma passive(ID).
9776 generate_show_constraint(Constraints0,Constraints,Rules0,Rules) :-
9777 ( chr_pp_flag(show,on) ->
9778 Constraints = ['$show'/0|Constraints0],
9779 generate_show_rules(Constraints0,Rules,[Rule|Rules0]),
9780 inc_rule_count(RuleNb),
9782 rule(['$show'],[],true,true),
9789 Constraints = Constraints0,
9793 generate_show_rules([],Rules,Rules).
9794 generate_show_rules([F/A|Rest],[Rule|Tail],Rules) :-
9796 inc_rule_count(RuleNb),
9798 rule([],['$show',C],true,writeln(C)),
9804 generate_show_rules(Rest,Tail,Rules).
9806 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9807 % Custom supension term layout
9809 static_suspension_term(F/A,Suspension) :-
9810 suspension_term_base(F/A,Base),
9812 functor(Suspension,suspension,Arity).
9814 has_suspension_field(FA,Field) :-
9815 suspension_term_base_fields(FA,Fields),
9816 memberchk(Field,Fields).
9818 suspension_term_base(FA,Base) :-
9819 suspension_term_base_fields(FA,Fields),
9820 length(Fields,Base).
9822 suspension_term_base_fields(FA,Fields) :-
9823 ( chr_pp_flag(debugable,on) ->
9826 % 3. Propagation History
9827 % 4. Generation Number
9828 % 5. Continuation Goal
9830 Fields = [id,state,history,generation,continuation,functor]
9832 ( uses_history(FA) ->
9833 Fields = [id,state,history|Fields2]
9834 ; only_ground_indexed_arguments(FA), get_functional_dependency(FA,1,_,_) ->
9835 Fields = [state|Fields2]
9837 Fields = [id,state|Fields2]
9839 ( only_ground_indexed_arguments(FA) ->
9840 get_store_type(FA,StoreType),
9841 basic_store_types(StoreType,BasicStoreTypes),
9842 ( memberchk(global_ground,BasicStoreTypes) ->
9845 % 3. Propagation History
9846 % 4. Global List Prev
9847 Fields2 = [global_list_prev|Fields3]
9851 % 3. Propagation History
9854 ( chr_pp_flag(ht_removal,on)
9855 -> ht_prev_fields(BasicStoreTypes,Fields3)
9858 ; may_trigger(FA) ->
9861 % 3. Propagation History
9862 ( uses_field(FA,generation) ->
9863 % 4. Generation Number
9864 % 5. Global List Prev
9865 Fields2 = [generation,global_list_prev|Fields3]
9867 Fields2 = [global_list_prev|Fields3]
9869 ( chr_pp_flag(mixed_stores,on),
9870 chr_pp_flag(ht_removal,on)
9871 -> get_store_type(FA,StoreType),
9872 basic_store_types(StoreType,BasicStoreTypes),
9873 ht_prev_fields(BasicStoreTypes,Fields3)
9879 % 3. Propagation History
9880 % 4. Global List Prev
9881 Fields2 = [global_list_prev|Fields3],
9882 ( chr_pp_flag(mixed_stores,on),
9883 chr_pp_flag(ht_removal,on)
9884 -> get_store_type(FA,StoreType),
9885 basic_store_types(StoreType,BasicStoreTypes),
9886 ht_prev_fields(BasicStoreTypes,Fields3)
9892 ht_prev_fields(Stores,Prevs) :-
9893 ht_prev_fields_int(Stores,PrevsList),
9894 append(PrevsList,Prevs).
9895 ht_prev_fields_int([],[]).
9896 ht_prev_fields_int([H|T],Fields) :-
9897 ( H = multi_hash(Indexes)
9898 -> maplist(ht_prev_field,Indexes,FH),
9902 ht_prev_fields_int(T,FT).
9904 ht_prev_field(Index,Field) :-
9905 concat_atom(['multi_hash_prev-'|Index],Field).
9907 get_static_suspension_term_field(FieldName,FA,StaticSuspension,Field) :-
9908 suspension_term_base_fields(FA,Fields),
9909 nth1(Index,Fields,FieldName), !,
9910 arg(Index,StaticSuspension,Field).
9911 get_static_suspension_term_field(arguments,FA,StaticSuspension,Field) :- !,
9912 suspension_term_base(FA,Base),
9913 StaticSuspension =.. [_|Args],
9914 drop(Base,Args,Field).
9915 get_static_suspension_term_field(FieldName,FA,_StaticSuspension,_Field) :-
9916 chr_error(internal,'Trying to obtain field ~w of ~w, wich does not have it!',[FieldName,FA]).
9919 get_dynamic_suspension_term_field(FieldName,FA,DynamicSuspension,Field,Goal) :-
9920 suspension_term_base_fields(FA,Fields),
9921 nth1(Index,Fields,FieldName), !,
9922 Goal = arg(Index,DynamicSuspension,Field).
9923 get_dynamic_suspension_term_field(arguments,FA,DynamicSuspension,Field,Goal) :- !,
9924 static_suspension_term(FA,StaticSuspension),
9925 get_static_suspension_term_field(arguments,FA,StaticSuspension,Field),
9926 Goal = (DynamicSuspension = StaticSuspension).
9927 get_dynamic_suspension_term_field(argument(I),FA,DynamicSuspension,Field,Goal) :- !,
9928 suspension_term_base(FA,Base),
9930 Goal = arg(Index,DynamicSuspension,Field).
9931 get_dynamic_suspension_term_field(FieldName,FA,_DynamicSuspension,_Field,_Goal) :-
9932 chr_error(internal,'Dynamic goal to get ~w of ~w, which does not have this field!',[FieldName,FA]).
9935 set_dynamic_suspension_term_field(FieldName,FA,DynamicSuspension,Field,Goal) :-
9936 suspension_term_base_fields(FA,Fields),
9937 nth1(Index,Fields,FieldName), !,
9938 Goal = setarg(Index,DynamicSuspension,Field).
9939 set_dynamic_suspension_term_field(FieldName,FA,_DynamicSuspension,_Field,_Goal) :-
9940 chr_error(internal,'Dynamic goal to set ~w of ~w, which does not have this field!',[FieldName,FA]).
9942 basic_store_types(multi_store(Types),Types) :- !.
9943 basic_store_types(Type,[Type]).
9945 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9952 :- chr_option(mode,phase_end(+)).
9953 :- chr_option(mode,delay_phase_end(+,?)).
9955 phase_end(Phase) \ delay_phase_end(Phase,Goal) <=> call(Goal).
9956 % phase_end(Phase) <=> true.
9959 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9963 novel_production_call/4.
9965 :- chr_option(mode,uses_history(+)).
9966 :- chr_option(mode,does_use_history(+,+)).
9967 :- chr_option(mode,novel_production_call(+,+,?,?)).
9969 does_use_history(FA,Occ) \ does_use_history(FA,Occ) <=> true.
9970 does_use_history(FA,_) \ uses_history(FA) <=> true.
9971 uses_history(_FA) <=> fail.
9973 does_use_history(FA,Occ) \ novel_production_call(FA,Occ,PossibleGoal,Goal) <=> Goal = PossibleGoal.
9974 novel_production_call(FA,_,_PossibleGoal,Goal) <=> Goal = true.
9980 :- chr_option(mode,uses_field(+,+)).
9981 :- chr_option(mode,does_use_field(+,+)).
9983 does_use_field(FA,Field) \ does_use_field(FA,Field) <=> true.
9984 does_use_field(FA,Field) \ uses_field(FA,Field) <=> true.
9985 uses_field(_FA,_Field) <=> fail.
9990 used_states_known/0.
9992 :- chr_option(mode,uses_state(+,+)).
9993 :- chr_option(mode,if_used_state(+,+,?,?,?)).
9996 % states ::= not_stored_yet | passive | active | triggered | removed
9998 % allocate CREATES not_stored_yet
9999 % remove CHECKS not_stored_yet
10000 % activate CHECKS not_stored_yet
10002 % ==> no allocate THEN no not_stored_yet
10004 % recurs CREATES inactive
10005 % lookup CHECKS inactive
10007 % insert CREATES active
10008 % activate CREATES active
10009 % lookup CHECKS active
10010 % recurs CHECKS active
10012 % runsusp CREATES triggered
10013 % lookup CHECKS triggered
10015 % ==> no runsusp THEN no triggered
10017 % remove CREATES removed
10018 % runsusp CHECKS removed
10019 % lookup CHECKS removed
10020 % recurs CHECKS removed
10022 % ==> no remove THEN no removed
10024 % ==> no allocate, no remove, no active/inactive distinction THEN no state at all...
10026 uses_state(Constraint,State) \ uses_state(Constraint,State) <=> true.
10028 used_states_known, uses_state(Constraint,State) \ if_used_state(Constraint,State,Used,NotUsed,ResultGoal)
10029 <=> ResultGoal = Used.
10030 used_states_known \ if_used_state(Constraint,State,Used,NotUsed,ResultGoal)
10031 <=> ResultGoal = NotUsed.
10033 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10034 % CHECK STOREDNESS ANNOTATIONS AND GENERATE DEFAULT SIMPLIFICATION RULES
10035 % (Feature for SSS)
10040 % When the programmer enables the `declare_stored_constraints' option, i.e. writes
10042 % :- chr_option(declare_stored_constraints,on).
10044 % the compiler will check for the storedness of constraints.
10046 % By default, the compiler assumes that the programmer wants his constraints to
10047 % be never-stored. Hence, a warning will be issues when a constraint is actually
10050 % Such warnings are suppressed, if the programmer adds the `# stored' modifier
10051 % to a constraint declaration, i.e. writes
10053 % :- chr_constraint c(...) # stored.
10055 % In that case a warning is issued when the constraint is never-stored.
10057 % NOTE: Checking is only performed if `storage_analysis' is on. Otherwise, all
10058 % constraints are stored anyway.
10061 % 2. Rule Generation
10062 % ~~~~~~~~~~~~~~~~~~
10064 % When the programmer enables the `declare_stored_constraints' option, i.e. writes
10066 % :- chr_option(declare_stored_constraints,on).
10068 % the compiler will generate default simplification rules for constraints.
10070 % By default, no default rule is generated for a constraint. However, if the
10071 % programmer writes a default/1 annotation in the constraint declaration, i.e. writes
10073 % :- chr_constraint c(...) # default(Goal).
10075 % where `Goal' is a ground and callable goal (e.g. `true', `fail' or `throw(error)'),
10076 % the compiler generates a rule:
10078 % c(_,...,_) <=> Goal.
10080 % at the end of the program. If multiple default rules are generated, for several constraints,
10081 % then the order of the default rules is not specified.
10084 :- chr_constraint stored_assertion/1.
10085 :- chr_option(mode,stored_assertion(+)).
10086 :- chr_option(type_declaration,stored_assertion(constraint)).
10088 :- chr_constraint never_stored_default/2.
10089 :- chr_option(mode,never_stored_default(+,?)).
10090 :- chr_option(type_declaration,never_stored_default(constraint,any)).
10095 generate_never_stored_rules(Constraints,Rules) :-
10096 ( chr_pp_flag(declare_stored_constraints,on) ->
10097 never_stored_rules(Constraints,Rules)
10102 :- chr_constraint never_stored_rules/2.
10103 :- chr_option(mode,never_stored_rules(+,?)).
10104 :- chr_option(type_declaration,never_stored_rules(list(constraint),any)).
10106 never_stored_rules([],Rules) <=> Rules = [].
10107 never_stored_default(Constraint,Goal) \ never_stored_rules([Constraint|Constraints],Rules) <=>
10110 inc_rule_count(RuleNb),
10112 rule([Head],[],true,Goal),
10118 Rules = [Rule|Tail],
10119 never_stored_rules(Constraints,Tail).
10120 never_stored_rules([_|Constraints],Rules) <=>
10121 never_stored_rules(Constraints,Rules).
10126 check_storedness_assertions(Constraints) :-
10127 ( chr_pp_flag(storage_analysis,on), chr_pp_flag(declare_stored_constraints,on) ->
10128 forall(Constraint,Constraints,check_storedness_assertion(Constraint))
10134 :- chr_constraint check_storedness_assertion/1.
10135 :- chr_option(mode,check_storedness_assertion(+)).
10136 :- chr_option(type_declaration,check_storedness_assertion(constraint)).
10138 check_storedness_assertion(Constraint), stored_assertion(Constraint)
10139 <=> ( is_stored(Constraint) ->
10142 chr_warning(assertion_failed,'Constraint ~w is not stored. However, it was asserted to be stored.\n',[Constraint])
10144 never_stored_default(Constraint,_) \ check_storedness_assertion(Constraint)
10145 <=> ( is_finally_stored(Constraint) ->
10146 chr_warning(assertion_failed,'Constraint ~w is stored. However, it was asserted not to be stored.\n',[Constraint])
10147 ; is_stored(Constraint) ->
10148 chr_warning(assertion_failed,'Constraint ~w is temporarily stored. However, it was asserted not to be stored.\n',[Constraint])
10152 % never-stored, no default goal
10153 check_storedness_assertion(Constraint)
10154 <=> ( is_finally_stored(Constraint) ->
10155 chr_warning(assertion_failed,'Constraint ~w is stored. However, it was asserted not to be stored.\n',[Constraint])
10156 ; is_stored(Constraint) ->
10157 chr_warning(assertion_failed,'Constraint ~w is temporarily stored. However, it was asserted not to be stored.\n',[Constraint])
10162 %^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
10163 % success continuation analysis
10166 % also use for forward jumping improvement!
10167 % use Prolog indexing for generated code
10171 % should_skip_to_next_id(C,O)
10173 % get_occurrence_code_id(C,O,Id)
10175 %vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
10177 continuation_analysis(ConstraintSymbols) :-
10178 maplist(analyse_continuations,ConstraintSymbols).
10180 analyse_continuations(C) :-
10181 % 1. compute success continuations of the
10182 % occurrences of constraint C
10183 continuation_analysis(C,1),
10184 % 2. determine for which occurrences
10185 % to skip to next code id
10186 get_max_occurrence(C,MO),
10188 bulk_propagation(C,1,LO),
10189 % 3. determine code id for each occurrence
10190 set_occurrence_code_id(C,1,0).
10192 % 1. Compute the success continuations of constrait C
10193 %-------------------------------------------------------------------------------
10195 continuation_analysis(C,O) :-
10196 get_max_occurrence(C,MO),
10201 continuation_occurrence(C,O,NextO)
10203 constraint_continuation(C,O,MO,NextO),
10204 continuation_occurrence(C,O,NextO),
10206 continuation_analysis(C,NO)
10209 constraint_continuation(C,O,MO,NextO) :-
10210 ( get_occurrence_head(C,O,Head) ->
10212 ( between(NO,MO,NextO),
10213 get_occurrence_head(C,NextO,NextHead),
10214 unifiable(Head,NextHead,_) ->
10219 ; % current occurrence is passive
10223 get_occurrence_head(C,O,Head) :-
10224 get_occurrence(C,O,RuleNb,Id),
10225 \+ is_passive(RuleNb,Id),
10226 get_rule(RuleNb,Rule),
10227 Rule = pragma(rule(H1,H2,_,_),ids(Ids1,Ids2),_,_,_),
10228 ( select2(Id,Head,Ids1,H1,_,_) -> true
10229 ; select2(Id,Head,Ids2,H2,_,_)
10232 :- chr_constraint continuation_occurrence/3.
10233 :- chr_option(mode,continuation_occurrence(+,+,+)).
10235 :- chr_constraint get_success_continuation_occurrence/3.
10236 :- chr_option(mode,get_success_continuation_occurrence(+,+,-)).
10238 continuation_occurrence(C,O,NO) \ get_success_continuation_occurrence(C,O,X)
10242 get_success_continuation_occurrence(C,O,X)
10244 chr_error(internal,'Success continuation not found for ~w.\n',[C:O]).
10246 % 2. figure out when to skip to next code id
10247 %-------------------------------------------------------------------------------
10248 % don't go beyond the last occurrence
10249 % we have to go to next id for storage here
10251 :- chr_constraint skip_to_next_id/2.
10252 :- chr_option(mode,skip_to_next_id(+,+)).
10254 :- chr_constraint should_skip_to_next_id/2.
10255 :- chr_option(mode,should_skip_to_next_id(+,+)).
10257 skip_to_next_id(C,O) \ should_skip_to_next_id(C,O)
10261 should_skip_to_next_id(_,_)
10265 :- chr_constraint bulk_propagation/3.
10266 :- chr_option(mode,bulk_propagation(+,+,+)).
10268 max_occurrence(C,MO) \ bulk_propagation(C,O,_)
10272 skip_to_next_id(C,O).
10273 % we have to go to the next id here because
10274 % a predecessor needs it
10275 bulk_propagation(C,O,LO)
10279 skip_to_next_id(C,O),
10280 get_max_occurrence(C,MO),
10282 bulk_propagation(C,LO,NLO).
10283 % we have to go to the next id here because
10284 % we're running into a simplification rule
10285 % IMPROVE: propagate back to propagation predecessor (IF ANY)
10286 occurrence(C,NO,_,_,simplification) \ bulk_propagation(C,O,LO)
10290 skip_to_next_id(C,O),
10291 get_max_occurrence(C,MO),
10293 bulk_propagation(C,NO,NLO).
10294 % we skip the next id here
10295 % and go to the next occurrence
10296 continuation_occurrence(C,O,NextO) \ bulk_propagation(C,O,LO)
10300 NLO is min(LO,NextO),
10302 bulk_propagation(C,NO,NLO).
10304 % err on the safe side
10305 bulk_propagation(C,O,LO)
10307 skip_to_next_id(C,O),
10308 get_max_occurrence(C,MO),
10311 bulk_propagation(C,NO,NLO).
10313 skip_to_next_id(C,O) \ skip_to_next_id(C,O) <=> true.
10315 % if this occurrence is passive, but has to skip,
10316 % then the previous one must skip instead...
10317 % IMPROVE reasoning is conservative
10318 occurrence(C,O,RuleNb,Id,_), passive(RuleNb,Id), skip_to_next_id(C,O)
10323 skip_to_next_id(C,PO).
10325 % 3. determine code id of each occurrence
10326 %-------------------------------------------------------------------------------
10328 :- chr_constraint set_occurrence_code_id/3.
10329 :- chr_option(mode,set_occurrence_code_id(+,+,+)).
10331 :- chr_constraint occurrence_code_id/3.
10332 :- chr_option(mode,occurrence_code_id(+,+,+)).
10335 set_occurrence_code_id(C,O,IdNb)
10337 get_max_occurrence(C,MO),
10340 occurrence_code_id(C,O,IdNb).
10342 % passive occurrences don't change the code id
10343 occurrence(C,O,RuleNb,Id,_), passive(RuleNb,Id) \ set_occurrence_code_id(C,O,IdNb)
10345 occurrence_code_id(C,O,IdNb),
10347 set_occurrence_code_id(C,NO,IdNb).
10349 occurrence(C,O,RuleNb,Id,simplification) \ set_occurrence_code_id(C,O,IdNb)
10351 occurrence_code_id(C,O,IdNb),
10353 set_occurrence_code_id(C,NO,IdNb).
10355 occurrence(C,O,RuleNb,Id,propagation), skip_to_next_id(C,O) \ set_occurrence_code_id(C,O,IdNb)
10357 occurrence_code_id(C,O,IdNb),
10360 set_occurrence_code_id(C,NO,NIdNb).
10362 occurrence(C,O,RuleNb,Id,propagation) \ set_occurrence_code_id(C,O,IdNb)
10364 occurrence_code_id(C,O,IdNb),
10366 set_occurrence_code_id(C,NO,IdNb).
10368 % occurrence_code_id(C,O,IdNb) ==> writeln(occurrence_code_id(C,O,IdNb)).
10370 :- chr_constraint get_occurrence_code_id/3.
10371 :- chr_option(mode,get_occurrence_code_id(+,+,-)).
10373 occurrence_code_id(C,O,IdNb) \ get_occurrence_code_id(C,O,X)
10377 get_occurrence_code_id(C,O,X)
10382 format('no occurrence code for ~w!\n',[C:O])
10385 get_success_continuation_code_id(C,O,NextId) :-
10386 get_success_continuation_occurrence(C,O,NextO),
10387 get_occurrence_code_id(C,NextO,NextId).
10389 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10390 % COLLECT CONSTANTS FOR INLINING
10394 %%% TODO: APPLY NEW DICT FORMAT DOWNWARDS
10396 % collect_constants(+rules,+ast_rules,+constraint_symbols,+clauses) {{{
10397 collect_constants(Rules,AstRules,Constraints,Clauses0) :-
10398 ( not_restarted, chr_pp_flag(experiment,on) ->
10399 ( chr_pp_flag(sss,on) ->
10400 Dictionary = [fep/4-[2,3]-[[a,b]-fep1,[c,d]-fep2]-no],
10401 copy_term_nat(Clauses0,Clauses),
10402 flatten_clauses(Clauses,Dictionary,FlatClauses),
10403 install_new_declarations_and_restart(FlatClauses)
10405 maplist(collect_rule_constants(Constraints),AstRules),
10406 ( chr_pp_flag(verbose,on) ->
10407 print_chr_constants
10411 ( chr_pp_flag(experiment,on) ->
10412 flattening_dictionary(Constraints,Dictionary),
10413 copy_term_nat(Clauses0,Clauses),
10414 flatten_clauses(Clauses,Dictionary,FlatClauses),
10415 install_new_declarations_and_restart(FlatClauses)
10424 :- chr_constraint chr_constants/1.
10425 :- chr_option(mode,chr_constants(+)).
10427 :- chr_constraint get_chr_constants/1.
10429 chr_constants(Constants) \ get_chr_constants(Q) <=> Q = Constants.
10431 get_chr_constants(Q) <=> chr_warning(internal,'No constants found for key ~w.\n',[Key]), Q = [].
10433 % collect_rule_constants(+constraint_symbols,+ast_rule) {{{
10434 collect_rule_constants(Constraints,AstRule) :-
10435 AstRule = ast_rule(AstHead,_,_,AstBody,_),
10436 collect_head_constants(AstHead),
10437 collect_body_constants(AstBody,Constraints).
10439 collect_head_constants(simplification(H1)) :-
10440 maplist(collect_constraint_constants,H1).
10441 collect_head_constants(propagation(H2)) :-
10442 maplist(collect_constraint_constants,H2).
10443 collect_head_constants(simpagation(H1,H2)) :-
10444 maplist(collect_constraint_constants,H1),
10445 maplist(collect_constraint_constants,H2).
10447 collect_body_constants(AstBody,Constraints) :-
10448 maplist(collect_goal_constants(Constraints),AstBody).
10450 collect_goal_constants(Constraints,Goal) :-
10451 ( ast_nonvar(Goal) ->
10452 ast_symbol(Goal,Symbol),
10453 ( memberchk(Symbol,Constraints) ->
10454 ast_term_to_term(Goal,Term),
10455 ast_args(Goal,Arguments),
10456 collect_constraint_constants(chr_constraint(Symbol,Arguments,Term))
10458 ast_args(Goal,[Arg1,Goal2]),
10459 Arg1 = atomic(Mod),
10460 get_target_module(Module),
10463 ast_symbol(Goal2,Symbol2),
10464 memberchk(Symbol2,Constraints) ->
10465 ast_term_to_term(Goal2,Term2),
10466 ast_args(Goal2,Arguments2),
10467 collect_constraint_constants(chr_constraint(Symbol2,Arguments2,Term2))
10475 collect_constraint_constants(Head) :-
10476 Head = chr_constraint(Symbol,Arguments,_),
10477 get_constraint_type_det(Symbol,Types),
10478 collect_all_arg_constants(Arguments,Types,[]).
10480 collect_all_arg_constants([],[],Constants) :-
10481 ( Constants \== [] ->
10482 add_chr_constants(Constants)
10486 collect_all_arg_constants([Arg|Args],[Type|Types],Constants0) :-
10487 unalias_type(Type,NormalizedType),
10488 ( is_chr_constants_type(NormalizedType,Key,_) ->
10489 ( ast_ground(Arg) ->
10490 ast_term_to_term(Arg,Term),
10491 collect_all_arg_constants(Args,Types,[Key-Term|Constants0])
10492 ; % no useful information here
10496 collect_all_arg_constants(Args,Types,Constants0)
10499 add_chr_constants(Pairs) :-
10500 keysort(Pairs,SortedPairs),
10501 add_chr_constants_(SortedPairs).
10503 :- chr_constraint add_chr_constants_/1.
10504 :- chr_option(mode,add_chr_constants_(+)).
10506 add_chr_constants_(Constants), chr_constants(MoreConstants) <=>
10507 sort([Constants|MoreConstants],NConstants),
10508 chr_constants(NConstants).
10510 add_chr_constants_(Constants) <=>
10511 chr_constants([Constants]).
10515 :- chr_constraint print_chr_constants/0. % {{{
10517 print_chr_constants, chr_constants(Constants) # Id ==>
10518 format('\t* chr_constants : ~w.\n',[Constants])
10519 pragma passive(Id).
10521 print_chr_constants <=>
10526 % flattening_dictionary(+constraint_symbols,-dictionary) {{{
10527 flattening_dictionary([],[]).
10528 flattening_dictionary([CS|CSs],Dictionary) :-
10529 ( flattening_dictionary_entry(CS,Entry) ->
10530 Dictionary = [Entry|Rest]
10534 flattening_dictionary(CSs,Rest).
10536 flattening_dictionary_entry(CS,Entry) :-
10537 get_constraint_type_det(CS,Types),
10538 constant_positions(Types,1,Positions,Keys,Handler,MaybeEnum),
10539 ( Positions \== [] -> % there are chr_constant arguments
10540 pairup(Keys,Constants,Pairs0),
10541 keysort(Pairs0,Pairs),
10542 Entry = CS-Positions-Specs-Handler,
10543 get_chr_constants(ConstantsList),
10545 ( member(Pairs,ConstantsList)
10546 , flat_spec(CS,Positions,Constants,Spec)
10549 ; MaybeEnum == yes ->
10550 enum_positions(Types,1,EnumPositions,ConstantsLists,EnumHandler),
10551 Entry = CS-EnumPositions-Specs-EnumHandler,
10553 ( cartesian_product(Terms,ConstantsLists)
10554 , flat_spec(CS,EnumPositions,Terms,Spec)
10559 constant_positions([],_,[],[],no,no).
10560 constant_positions([Type|Types],I,Positions,Keys,Handler,MaybeEnum) :-
10561 unalias_type(Type,NormalizedType),
10562 ( is_chr_constants_type(NormalizedType,Key,ErrorHandler) ->
10563 compose_error_handlers(ErrorHandler,NHandler,Handler),
10564 Positions = [I|NPositions],
10565 Keys = [Key|NKeys],
10566 MaybeEnum = NMaybeEnum
10568 ( is_chr_enum_type(NormalizedType,_,_) ->
10571 MaybeEnum = NMaybeEnum
10573 NPositions = Positions,
10578 constant_positions(Types,J,NPositions,NKeys,NHandler,NMaybeEnum).
10580 compose_error_handlers(no,Handler,Handler).
10581 compose_error_handlers(yes(Handler),_,yes(Handler)).
10583 enum_positions([],_,[],[],no).
10584 enum_positions([Type|Types],I,Positions,ConstantsLists,Handler) :-
10585 unalias_type(Type,NormalizedType),
10586 ( is_chr_enum_type(NormalizedType,Constants,ErrorHandler) ->
10587 compose_error_handlers(ErrorHandler,NHandler,Handler),
10588 Positions = [I|NPositions],
10589 ConstantsLists = [Constants|NConstantsLists]
10590 ; Positions = NPositions,
10591 ConstantsLists = NConstantsLists,
10595 enum_positions(Types,J,NPositions,NConstantsLists,NHandler).
10597 cartesian_product([],[]).
10598 cartesian_product([E|Es],[L|Ls]) :-
10600 cartesian_product(Es,Ls).
10602 flat_spec(C/N,Positions,Terms,Spec) :-
10603 Spec = Terms - Functor,
10604 term_to_atom(Terms,TermsAtom),
10605 term_to_atom(Positions,PositionsAtom),
10606 atom_concat_list(['$flat_',C,'/',N,'___',PositionsAtom,'___',TermsAtom],Functor).
10611 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10612 % RESTART AFTER FLATTENING {{{
10614 restart_after_flattening(Declarations,Declarations) :-
10615 nb_setval('$chr_restart_after_flattening',started).
10616 restart_after_flattening(_,Declarations) :-
10617 nb_getval('$chr_restart_after_flattening',restart(Declarations)),
10618 nb_setval('$chr_restart_after_flattening',restarted).
10621 nb_getval('$chr_restart_after_flattening',started).
10623 install_new_declarations_and_restart(Declarations) :-
10624 nb_setval('$chr_restart_after_flattening',restart(Declarations)),
10625 fail. /* fails to choicepoint of restart_after_flattening */
10627 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10631 % -) generate dictionary from collected chr_constants
10632 % enable with :- chr_option(experiment,on).
10633 % -) issue constraint declarations for constraints not present in
10635 % -) integrate with CHR compiler
10636 % -) pass Mike's test code (full syntactic support for current CHR code)
10637 % -) rewrite the body using the inliner
10640 % -) refined semantics correctness issue
10641 % -) incorporate chr_enum into dictionary generation
10642 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10644 flatten_clauses(Clauses,Dict,NClauses) :-
10645 flatten_readcontent(Clauses,Rules,Symbols,ModeDecls,_TypeDefs,TypeDecls,RestClauses),
10646 flatten_clauses_(Dict,Rules,RestClauses,Symbols,ModeDecls,TypeDecls,NClauses).
10648 flatten_clauses_(Dict,Clauses,RestClauses,Symbols,ModeDecls,TypeDecls,NClauses) :-
10649 auxiliary_constraints_declarations(Dict,ModeDecls,TypeDecls,NClauses0),
10650 dispatching_rules(Dict,NClauses1),
10651 declarations(Symbols,Dict,ModeDecls,TypeDecls,NClauses2),
10652 flatten_rules(Clauses,Dict,NClauses3),
10653 append([RestClauses,NClauses0,NClauses1,NClauses2,NClauses3],NClauses).
10655 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10656 % Declarations for non-flattened constraints
10658 % declarations(+constraint_symbols,+dict,+mode_decls,+type_decls,-clauses) {{{
10659 declarations(ConstraintSymbols,Dict,ModeDecls,TypeDecls,Declarations) :-
10660 findall(Symbol,(member(Symbol,ConstraintSymbols), \+ memberchk(Symbol-_-_-_,Dict)),Symbols),
10661 maplist(declaration(ModeDecls,TypeDecls),Symbols,DeclarationsList),
10662 flatten(DeclarationsList,Declarations).
10664 declaration(ModeDecls,TypeDecls,ConstraintSymbol,
10665 [(:- chr_constraint ConstraintSymbol),
10666 (:- chr_option(mode,ModeDeclPattern)),
10667 (:- chr_option(type_declaration,TypeDeclPattern))
10669 ConstraintSymbol = Functor / Arity,
10670 % print optional mode declaration
10671 functor(ModeDeclPattern,Functor,Arity),
10672 ( memberchk(ModeDeclPattern,ModeDecls) ->
10675 replicate(Arity,(?),Modes),
10676 ModeDeclPattern =.. [_|Modes]
10678 % print optional type declaration
10679 functor(TypeDeclPattern,Functor,Arity),
10680 ( memberchk(TypeDeclPattern,TypeDecls) ->
10683 replicate(Arity,any,Types),
10684 TypeDeclPattern =.. [_|Types]
10687 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10688 % read clauses from file
10690 % declared constaints are returned
10691 % type definitions are returned and printed
10692 % mode declarations are returned
10693 % other clauses are returned
10695 % flatten_readcontent(+clauses,-rules,-symbols,-mode_decls,-type_defs,-type_decls,-rest_clauses) {{{
10696 flatten_readcontent([],[],[],[],[],[],[]).
10697 flatten_readcontent([Clause|RClauses],Rules,ConstraintSymbols,ModeDecls,TypeDefs,TypeDecls,RestClauses) :-
10699 ( Clause == end_of_file ->
10701 ConstraintSymbols = [],
10706 ; crude_is_rule(Clause) ->
10707 Rules = [Clause|RestRules],
10708 flatten_readcontent(RClauses,RestRules,ConstraintSymbols,ModeDecls,TypeDefs,TypeDecls,RestClauses)
10709 ; pure_is_declaration(Clause,SomeConstraintSymbols,SomeModeDecls,SomeTypeDecls) ->
10710 append(SomeConstraintSymbols,RestConstraintSymbols,ConstraintSymbols),
10711 append(SomeModeDecls,RestModeDecls,ModeDecls),
10712 append(SomeTypeDecls,RestTypeDecls,TypeDecls),
10713 flatten_readcontent(RClauses,Rules,RestConstraintSymbols,RestModeDecls,TypeDefs,RestTypeDecls,RestClauses)
10714 ; is_mode_declaration(Clause,ModeDecl) ->
10715 ModeDecls = [ModeDecl|RestModeDecls],
10716 flatten_readcontent(RClauses,Rules,ConstraintSymbols,RestModeDecls,TypeDefs,TypeDecls,RestClauses)
10717 ; is_type_declaration(Clause,TypeDecl) ->
10718 TypeDecls = [TypeDecl|RestTypeDecls],
10719 flatten_readcontent(RClauses,Rules,ConstraintSymbols,ModeDecls,TypeDefs,RestTypeDecls,RestClauses)
10720 ; is_type_definition(Clause,TypeDef) ->
10721 RestClauses = [Clause|NRestClauses],
10722 TypeDefs = [TypeDef|RestTypeDefs],
10723 flatten_readcontent(RClauses,Rules,ConstraintSymbols,ModeDecls,RestTypeDefs,TypeDecls,NRestClauses)
10724 ; ( Clause = (:- op(A,B,C)) ->
10725 % assert operators in order to read and print them out properly
10730 RestClauses = [Clause|NRestClauses],
10731 flatten_readcontent(RClauses,Rules,ConstraintSymbols,ModeDecls,TypeDefs,TypeDecls,NRestClauses)
10734 crude_is_rule(_ @ _).
10735 crude_is_rule(_ pragma _).
10736 crude_is_rule(_ ==> _).
10737 crude_is_rule(_ <=> _).
10739 pure_is_declaration(D, Constraints,Modes,Types) :- %% constraint declaration
10740 D = (:- Decl), Decl =.. [F,Cs], F == (chr_constraint),
10741 conj2list(Cs,Constraints0),
10742 pure_extract_type_mode(Constraints0,Constraints,Modes,Types).
10744 pure_extract_type_mode([],[],[],[]).
10745 pure_extract_type_mode([F/A|R],[F/A|R2],Modes,Types) :- !,
10746 pure_extract_type_mode(R,R2,Modes,Types).
10747 pure_extract_type_mode([C|R],[ConstraintSymbol|R2],[Mode|Modes],Types) :-
10749 ConstraintSymbol = F/A,
10751 extract_types_and_modes(Args,ArgTypes,ArgModes),
10752 Mode =.. [F|ArgModes],
10753 ( forall(member(ArgType,ArgTypes),ArgType == any) ->
10756 Types = [Type|RTypes],
10757 Type =.. [F|ArgTypes]
10759 pure_extract_type_mode(R,R2,Modes,RTypes).
10761 is_mode_declaration((:- chr_option(mode,ModeDecl)),ModeDecl).
10763 is_type_declaration((:- chr_option(type_declaration,TypeDecl)),TypeDecl).
10765 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10766 % DECLARATIONS FOR FLATTENED CONSTRAINTS
10767 % including mode and type declarations
10769 % auxiliary_constraints_declarations(+dict,+mode_decls,+type_decls,-constraint_specs) {{{
10770 auxiliary_constraints_declarations(Dict,ModeDecls,TypeDecls,ConstraintSpecs) :-
10771 findall(ConstraintSpec,auxiliary_constraints_declaration(Dict,ModeDecls,TypeDecls,ConstraintSpec),ConstraintSpecs0),
10772 flatten(ConstraintSpecs0,ConstraintSpecs).
10774 auxiliary_constraints_declaration(Dict,ModeDecls,TypeDecls,
10775 [(:- chr_constraint ConstraintSpec),
10776 (:- chr_option(mode,NewModeDecl)),
10777 (:- chr_option(type_declaration,NewTypeDecl))]) :-
10778 member(C/N-I-SFs-_,Dict),
10779 arg_modes(C,N,ModeDecls,Modes),
10780 specialize_modes(Modes,I,SpecializedModes),
10781 arg_types(C,N,TypeDecls,Types),
10782 specialize_types(Types,I,SpecializedTypes),
10783 length(I,IndexSize),
10784 AN is N - IndexSize,
10785 member(_Term-F,SFs),
10786 ConstraintSpec = F/AN,
10787 NewModeDecl =.. [F|SpecializedModes],
10788 NewTypeDecl =.. [F|SpecializedTypes].
10790 arg_modes(C,N,ModeDecls,ArgModes) :-
10791 functor(ConstraintPattern,C,N),
10792 ( memberchk(ConstraintPattern,ModeDecls) ->
10793 ConstraintPattern =.. [_|ArgModes]
10795 replicate(N,?,ArgModes)
10798 specialize_modes(Modes,I,SpecializedModes) :-
10799 split_args(I,Modes,_,SpecializedModes).
10801 arg_types(C,N,TypeDecls,ArgTypes) :-
10802 functor(ConstraintPattern,C,N),
10803 ( memberchk(ConstraintPattern,TypeDecls) ->
10804 ConstraintPattern =.. [_|ArgTypes]
10806 replicate(N,any,ArgTypes)
10809 specialize_types(Types,I,SpecializedTypes) :-
10810 split_args(I,Types,_,SpecializedTypes).
10812 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10813 % DISPATCHING RULES
10815 % dispatching_rules(+dict,-newrules)
10820 % This code generates a decision tree for calling the appropriate specialized
10821 % constraint based on the particular value of the argument the constraint
10822 % is being specialized on.
10824 % In case an error handler is provided, the handler is called with the
10825 % unexpected constraint.
10827 dispatching_rules([],[]).
10828 dispatching_rules([CN-I-SFs-MaybeErrorHandler|Dict], DispatchingRules) :-
10829 constraint_dispatching_rule(SFs,CN,I,MaybeErrorHandler,DispatchingRules,RestDispatchingRules),
10830 dispatching_rules(Dict,RestDispatchingRules).
10832 constraint_dispatching_rule(SFs,C/N,I,MaybeErrorHandler,Rules,RestRules) :-
10833 ( increasing_numbers(I,1) ->
10834 /* index on first arguments */
10838 /* reorder arguments for 1st argument indexing */
10841 split_args(I,Args,GroundArgs,OtherArgs),
10842 append(GroundArgs,OtherArgs,ShuffledArgs),
10843 atom_concat(C,'_$shuffled',NC),
10844 Body =.. [NC|ShuffledArgs],
10845 [(Head :- Body)|Rules0] = Rules,
10848 Context = swap(C,I),
10849 dispatching_rule_term_cases(SFs,I,NCN,MaybeErrorHandler,Context,Rules0,RestRules).
10851 increasing_numbers([],_).
10852 increasing_numbers([X|Ys],X) :-
10854 increasing_numbers(Ys,Y).
10856 dispatching_rule_term_cases(SFs,I,NC/N,MaybeErrorHandler,Context,Rules,RestRules) :-
10857 length(I,IndexLength),
10858 once(pairup(TermLists,Functors,SFs)),
10859 maplist(head_tail,TermLists,Heads,Tails),
10860 Payload is N - IndexLength,
10861 maplist(wrap_in_functor(dispatching_action),Functors,Actions),
10862 dispatch_trie_index(Heads,Tails,Payload,MaybeErrorHandler,Context,Actions,NC,Rules,RestRules).
10864 dispatching_action(Functor,PayloadArgs,Goal) :-
10865 Goal =.. [Functor|PayloadArgs].
10867 dispatch_trie_index(Patterns,MorePatterns,Payload,MaybeErrorHandler,Context,Actions,Prefix,Clauses,Tail) :-
10868 dispatch_trie_step(Patterns,Prefix,Prefix,MorePatterns,Payload,MaybeErrorHandler,Context,Actions,Clauses,Tail).
10870 dispatch_trie_step([],_,_,_,[],_,_,[],L,L) :- !.
10871 % length MorePatterns == length Patterns == length Results
10872 dispatch_trie_step(Patterns,Symbol,Prefix,MorePatterns,Payload,MaybeErrorHandler,Context,Actions,Clauses,T) :-
10873 MorePatterns = [List|_],
10875 aggregate_all(set(F/A),
10876 ( member(Pattern,Patterns),
10877 functor(Pattern,F,A)
10881 dispatch_trie_step_cases(FAs,N1,Patterns,MorePatterns,Payload,MaybeErrorHandler,Context,Actions,Symbol,Prefix,Clauses,T).
10883 dispatch_trie_step_cases([],N,_,_,Payload,MaybeErrorHandler,Context,_,Symbol,_,Clauses0,Clauses) :-
10884 ( MaybeErrorHandler = yes(ErrorHandler) ->
10885 Clauses0 = [ErrorClause|Clauses],
10886 ErrorClause = (Head :- Body),
10887 Arity is N + Payload,
10888 functor(Head,Symbol,Arity),
10889 reconstruct_original_term(Context,Head,Term),
10890 Body =.. [ErrorHandler,Term]
10894 dispatch_trie_step_cases([FA|FAs],N,Pattern,MorePatterns,Payload,MaybeErrorHandler,Context,Actions,Symbol,Prefix,Clauses,Tail) :-
10895 dispatch_trie_step_case(FA,N,Pattern,MorePatterns,Payload,MaybeErrorHandler,Context,Actions,Symbol,Prefix,Clauses,Clauses1),
10896 dispatch_trie_step_cases(FAs,N,Pattern,MorePatterns,Payload,MaybeErrorHandler,Context,Actions,Symbol,Prefix,Clauses1,Tail).
10898 dispatch_trie_step_case(F/A,N,Patterns,MorePatterns,Payload,MaybeErrorHandler,Context0,Actions,Symbol,Prefix,[Clause|List],Tail) :-
10899 Clause = (Head :- Cut, Body),
10900 ( MaybeErrorHandler = yes(_) ->
10905 /* Head = Symbol(IndexPattern,V2,...,Vn,Payload) */
10907 functor(Head,Symbol,N1),
10908 arg(1,Head,IndexPattern),
10909 Head =.. [_,_|RestArgs],
10910 length(PayloadArgs,Payload),
10911 once(append(Vs,PayloadArgs,RestArgs)),
10912 /* IndexPattern = F(...) */
10913 functor(IndexPattern,F,A),
10914 Context1 = index_functor(F,A,Context0),
10915 IndexPattern =.. [_|Args],
10916 append(Args,RestArgs,RecArgs),
10917 ( RecArgs == PayloadArgs ->
10918 /* nothing more to match on */
10920 rec_cases(Patterns,_,Actions,F/A,_,_,MoreActions),
10921 MoreActions = [Action],
10922 call(Action,PayloadArgs,Body)
10923 ; /* more things to match on */
10924 rec_cases(Patterns,MorePatterns,Actions,F/A,Cases,MoreCases,MoreActions),
10925 ( MoreActions = [OneMoreAction] ->
10926 /* only one more thing to match on */
10927 MoreCases = [OneMoreCase],
10928 append([Cases,OneMoreCase,PayloadArgs],RecArgs),
10930 call(OneMoreAction,PayloadArgs,Body)
10932 /* more than one thing to match on */
10936 pairup(Cases,MoreCases,CasePairs),
10937 common_pattern(CasePairs,CommonPatternPair,DiffVars,Differences),
10938 append(Args,Vs,[First|Rest]),
10939 First-Rest = CommonPatternPair,
10940 Context2 = gct([First|Rest],Context1),
10941 gensym(Prefix,RSymbol),
10942 append(DiffVars,PayloadArgs,RecCallVars),
10943 Body =.. [RSymbol|RecCallVars],
10944 findall(CH-CT,member([CH|CT],Differences),CPairs),
10945 once(pairup(CHs,CTs,CPairs)),
10946 dispatch_trie_step(CHs,RSymbol,Prefix,CTs,Payload,MaybeErrorHandler,Context2,MoreActions,List,Tail)
10951 % split(list,int,before,at,after).
10953 split([X|Xs],I,Before,At,After) :-
10960 Before = [X|RBefore],
10961 split(Xs,J,RBefore,At,After)
10964 % reconstruct_original_term(Context,CurrentTerm,OriginalTerm)
10966 % context ::= swap(functor,positions)
10967 % | index_functor(functor,arity,context)
10968 % | gct(Pattern,Context)
10970 reconstruct_original_term(swap(Functor,Positions),Term,OriginalTerm) :-
10971 functor(Term,_,Arity),
10972 functor(OriginalTerm,Functor,Arity),
10973 OriginalTerm =.. [_|OriginalArgs],
10974 split_args(Positions,OriginalArgs,IndexArgs,OtherArgs),
10976 append(IndexArgs,OtherArgs,Args).
10977 reconstruct_original_term(index_functor(Functor,Arity,Context),Term0,OriginalTerm) :-
10978 Term0 =.. [Predicate|Args],
10979 split_at(Arity,Args,IndexArgs,RestArgs),
10980 Index =.. [Functor|IndexArgs],
10981 Term1 =.. [Predicate,Index|RestArgs],
10982 reconstruct_original_term(Context,Term1,OriginalTerm).
10983 reconstruct_original_term(gct(PatternList,Context),Term0,OriginalTerm) :-
10984 copy_term_nat(PatternList,IndexTerms),
10985 term_variables(IndexTerms,Variables),
10986 Term0 =.. [Predicate|Args0],
10987 append(Variables,RestArgs,Args0),
10988 append(IndexTerms,RestArgs,Args1),
10989 Term1 =.. [Predicate|Args1],
10990 reconstruct_original_term(Context,Term1,OriginalTerm).
10993 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10994 % SUBSTITUTE CONSTRAINT SYMBOL FUNCTORS
10996 % flatten_rules(+rule_clauses,+dict,-rule_clauses).
10998 % dict :== list(functor/arity-list(int)-list(list(term)-functor)-maybe(error_handler))
11001 flatten_rules(Rules,Dict,FlatRules) :-
11002 flatten_rules1(Rules,Dict,FlatRulesList),
11003 flatten(FlatRulesList,FlatRules).
11005 flatten_rules1([],_,[]).
11006 flatten_rules1([Rule|Rules],Dict,[FlatRules|FlatRulesList]) :-
11007 findall(FlatRule,flatten_rule(Rule,Dict,FlatRule),FlatRules),
11008 flatten_rules1(Rules,Dict,FlatRulesList).
11010 flatten_rule((Name @ Rule),Dict,(Name @ NRule)) :- !,
11011 flatten_rule(Rule,Dict,NRule).
11012 flatten_rule((Rule pragma Pragmas),Dict,(NRule pragma Pragmas)) :- !,
11013 flatten_rule(Rule,Dict,NRule).
11014 flatten_rule((H ==> B),Dict,(NH ==> NB)) :- !,
11015 flatten_heads(H,Dict,NH),
11016 flatten_body(B,Dict,NB).
11017 flatten_rule((H1 \ H2 <=> B),Dict,(NH1 \ NH2 <=> NB)) :- !,
11018 flatten_heads((H1,H2),Dict,(NH1,NH2)),
11019 flatten_body(B,Dict,NB).
11020 flatten_rule((H <=> B),Dict,(NH <=> NB)) :-
11021 flatten_heads(H,Dict,NH),
11022 flatten_body(B,Dict,NB).
11024 flatten_heads((H1,H2),Dict,(NH1,NH2)) :- !,
11025 flatten_heads(H1,Dict,NH1),
11026 flatten_heads(H2,Dict,NH2).
11027 flatten_heads((H # Annotation),Dict,(NH # Annotation)) :- !,
11028 flatten_heads(H,Dict,NH).
11029 flatten_heads(H,Dict,NH) :-
11031 memberchk(C/N-ArgPositions-SFs-_,Dict) ->
11033 split_args(ArgPositions,AllArgs,GroundArgs,OtherArgs),
11034 member(GroundArgs-Name,SFs),
11035 NH =.. [Name|OtherArgs]
11040 flatten_body((Guard | Body),Dict,(NGuard | NBody)) :- !,
11041 conj2list(Guard,Guards),
11042 maplist(flatten_goal(Dict),Guards,NGuards),
11043 list2conj(NGuards,NGuard),
11044 conj2list(Body,Goals),
11045 maplist(flatten_goal(Dict),Goals,NGoals),
11046 list2conj(NGoals,NBody).
11047 flatten_body(Body,Dict,NBody) :-
11048 conj2list(Body,Goals),
11049 maplist(flatten_goal(Dict),Goals,NGoals),
11050 list2conj(NGoals,NBody).
11052 flatten_goal(Dict,Goal,NGoal) :- var(Goal), !, NGoal = Goal.
11053 flatten_goal(Dict,Goal,NGoal) :-
11054 ( is_specializable_goal(Goal,Dict,ArgPositions)
11056 specialize_goal(Goal,ArgPositions,NGoal)
11057 ; Goal = Mod : TheGoal,
11058 get_target_module(Module),
11061 is_specializable_goal(TheGoal,Dict,ArgPositions)
11063 specialize_goal(TheGoal,ArgPositions,NTheGoal),
11064 NGoal = Mod : NTheGoal
11065 ; partial_eval(Goal,NGoal)
11072 %-------------------------------------------------------------------------------%
11073 % Specialize body/guard goal
11074 %-------------------------------------------------------------------------------%
11075 is_specializable_goal(Goal,Dict,ArgPositions) :-
11077 memberchk(C/N-ArgPositions-_-_,Dict),
11078 args(ArgPositions,Goal,Args),
11081 specialize_goal(Goal,ArgPositions,NGoal) :-
11084 split_args(ArgPositions,Args,GroundTerms,Others),
11085 flat_spec(C/N,ArgPositions,GroundTerms,_-Functor),
11086 NGoal =.. [Functor|Others].
11088 %-------------------------------------------------------------------------------%
11089 % Partially evaluate predicates
11090 %-------------------------------------------------------------------------------%
11092 % append([],Y,Z) >--> Y = Z
11093 % append(X,[],Z) >--> X = Z
11094 partial_eval(append(L1,L2,L3),NGoal) :-
11101 % flatten_path(L1,L2) >--> flatten_path(L1',L2)
11102 % where flatten(L1,L1')
11103 partial_eval(flatten_path(L1,L2),NGoal) :-
11105 flatten(L1,FlatterL1),
11106 FlatterL1 \== L1 ->
11107 NGoal = flatten_path(FlatterL1,L2).
11113 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
11114 dump_code(Clauses) :-
11115 ( chr_pp_flag(dump,on) ->
11116 maplist(portray_clause,Clauses)
11122 chr_info(banner,'\tThe K.U.Leuven CHR System\n\t\tMain Developer:\tTom Schrijvers\n\t\tContributors:\tJon Sneyers, Bart Demoen, Jan Wielemaker\n\t\tCopyright:\tK.U.Leuven, Belgium\n\t\tURL:\t\thttp://www.cs.kuleuven.be/~~toms/CHR/\n',[]).
11124 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
11127 chr_none_locked(Vars,Goal) :-
11128 chr_pp_flag(guard_locks,Flag),
11132 Goal = 'chr none_locked'( Vars)
11134 Goal = 'chr none_error_locked'( Vars)
11137 chr_not_locked(Var,Goal) :-
11138 chr_pp_flag(guard_locks,Flag),
11142 Goal = 'chr not_locked'( Var)
11144 Goal = 'chr not_error_locked'( Var)
11147 chr_lock(Var,Goal) :-
11148 chr_pp_flag(guard_locks,Flag),
11152 Goal = 'chr lock'( Var)
11154 Goal = 'chr error_lock'( Var)
11157 chr_unlock(Var,Goal) :-
11158 chr_pp_flag(guard_locks,Flag),
11162 Goal = 'chr unlock'( Var)
11164 Goal = 'chr unerror_lock'( Var)
11167 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
11168 % AST representation
11169 % each AST representation caches the original term
11171 % ast_term ::= atomic(Term)
11172 % | compound(Functor,Arity,list(ast_term),Term)
11174 % -- unique integer identifier
11176 % Conversion Predicate {{{
11177 :- chr_type var_id == natural.
11179 term_to_ast_term(Term,AstTerm,VarEnv,NVarEnv) :-
11181 AstTerm = atomic(Term),
11183 ; compound(Term) ->
11184 functor(Term,Functor,Arity),
11185 AstTerm = compound(Functor,Arity,AstTerms,Term),
11187 maplist_dcg(chr_translate:term_to_ast_term,Args,AstTerms,VarEnv,NVarEnv)
11189 var_to_ast_term(Term,VarEnv,AstTerm,NVarEnv)
11192 var_to_ast_term(Var,Env,AstTerm,NVarEnv) :-
11193 Env = VarDict - VarId,
11194 ( lookup_eq(VarDict,Var,AstTerm) ->
11197 AstTerm = var(VarId,Var),
11198 NVarId is VarId + 1,
11199 NVarDict = [Var - AstTerm|VarDict],
11200 NVarEnv = NVarDict - NVarId
11203 % ast_constraint ::= chr_constraint(Symbol,Arguments,Constraint)
11204 chr_constraint_to_ast_constraint(CHRConstraint,AstConstraint,VarEnv,NVarEnv) :-
11205 AstConstraint = chr_constraint(Functor/Arity,AstTerms,CHRConstraint),
11206 functor(CHRConstraint,Functor,Arity),
11207 CHRConstraint =.. [_|Arguments],
11208 maplist_dcg(chr_translate:term_to_ast_term,Arguments,AstTerms,VarEnv,NVarEnv).
11210 % ast_head ::= simplification(list(chr_constraint))
11211 % | propagation(list(chr_constraint))
11212 % | simpagation(list(chr_constraint),list(chr_constraint))
11216 % ast_guard ::= list(ast_term)
11217 % ast_body ::= list(ast_term)
11219 % ast_rule ::= ast_rule(ast_head,ast_guard,guard,ast_body,body)
11221 rule_to_ast_rule(Rule,AstRule) :-
11222 AstRule = ast_rule(Head,AstGuard,Guard,AstBody,Body),
11223 Rule = rule(H1,H2,Guard,Body),
11224 EmptyVarEnv = []-1,
11226 Head = propagation(AstConstraints),
11227 maplist_dcg(chr_translate:chr_constraint_to_ast_constraint,H2,AstConstraints,EmptyVarEnv,VarEnv1)
11229 Head = simplification(AstConstraints),
11230 maplist_dcg(chr_translate:chr_constraint_to_ast_constraint,H1,AstConstraints,EmptyVarEnv,VarEnv1)
11232 Head = simpagation(RemovedAstConstraints,KeptAstConstraints),
11233 maplist_dcg(chr_translate:chr_constraint_to_ast_constraint,H1,RemovedAstConstraints,EmptyVarEnv,VarEnv0),
11234 maplist_dcg(chr_translate:chr_constraint_to_ast_constraint,H2,KeptAstConstraints,VarEnv0,VarEnv1)
11236 conj2list(Guard,GuardList),
11237 maplist_dcg(chr_translate:term_to_ast_term,GuardList,AstGuard,VarEnv1,VarEnv2),
11238 conj2list(Body,BodyList),
11239 maplist_dcg(chr_translate:term_to_ast_term,BodyList,AstBody,VarEnv2,_).
11241 pragma_rule_to_ast_rule(pragma(Rule,_,_,_,_),AstRule) :-
11242 rule_to_ast_rule(Rule,AstRule).
11244 check_rule_to_ast_rule(Rule) :-
11245 ( rule_to_ast_rule(Rule,AstRule) ->
11248 writeln(failed(rule_to_ast_rule(Rule,AstRule)))
11253 % AST Utility Predicates {{{
11254 ast_term_to_term(var(_,Var),Var).
11255 ast_term_to_term(atomic(Atom),Atom).
11256 ast_term_to_term(compound(_,_,_,Compound),Compound).
11258 ast_nonvar(atomic(_)).
11259 ast_nonvar(compound(_,_,_,_)).
11261 ast_ground(atomic(_)).
11262 ast_ground(compound(_,_,Arguments,_)) :-
11263 maplist(ast_ground,Arguments).
11265 %------------------------------------------------------------------------------%
11266 % Check whether a term is ground, given a set of variables that are ground.
11267 %------------------------------------------------------------------------------%
11268 ast_is_ground(VarSet,AstTerm) :-
11269 ast_is_ground_(AstTerm,VarSet).
11271 ast_is_ground_(var(VarId,_),VarSet) :-
11272 tree_set_memberchk(VarId,VarSet).
11273 ast_is_ground_(atomic(_),_).
11274 ast_is_ground_(compound(_,_,Arguments,_),VarSet) :-
11275 maplist(ast_is_ground(VarSet),Arguments).
11276 %------------------------------------------------------------------------------%
11278 ast_functor(atomic(Atom),Atom,0).
11279 ast_functor(compound(Functor,Arity,_,_),Functor,Arity).
11281 ast_symbol(atomic(Atom),Atom/0).
11282 ast_symbol(compound(Functor,Arity,_,_),Functor/Arity).
11284 ast_args(atomic(_),[]).
11285 ast_args(compound(_,_,Arguments,_),Arguments).
11287 %------------------------------------------------------------------------------%
11288 % Add variables in a term to a given set.
11289 %------------------------------------------------------------------------------%
11290 ast_term_variables(atomic(_),Set,Set).
11291 ast_term_variables(compound(_,_,Args,_),Set,NSet) :-
11292 ast_term_list_variables(Args,Set,NSet).
11293 ast_term_variables(var(VarId,_),Set,NSet) :-
11294 tree_set_add(Set,VarId,NSet).
11296 ast_term_list_variables(Terms,Set,NSet) :-
11297 fold(Terms,chr_translate:ast_term_variables,Set,NSet).
11298 %------------------------------------------------------------------------------%
11300 ast_constraint_variables(chr_constraint(_,Args,_),Set,NSet) :-
11301 ast_term_list_variables(Args,Set,NSet).
11303 ast_constraint_list_variables(Constraints,Set,NSet) :-
11304 fold(Constraints,chr_translate:ast_constraint_variables,Set,NSet).
11306 ast_head_variables(simplification(H1),Set,NSet) :-
11307 ast_constraint_list_variables(H1,Set,NSet).
11308 ast_head_variables(propagation(H2),Set,NSet) :-
11309 ast_constraint_list_variables(H2,Set,NSet).
11310 ast_head_variables(simpagation(H1,H2),Set,NSet) :-
11311 ast_constraint_list_variables(H1,Set,Set1),
11312 ast_constraint_list_variables(H2,Set1,NSet).
11314 ast_var_memberchk(var(VarId,_),Set) :-
11315 tree_set_memberchk(VarId,Set).
11317 %------------------------------------------------------------------------------%
11318 % Return term based on AST-term with variables mapped.
11319 %------------------------------------------------------------------------------%
11320 ast_instantiate(Map,AstTerm,Term) :-
11321 ast_instantiate_(AstTerm,Map,Term).
11323 ast_instantiate_(var(VarId,_),Map,Term) :-
11324 get_assoc(VarId,Map,Term).
11325 ast_instantiate_(atomic(Atom),_,Atom).
11326 ast_instantiate_(compound(Functor,Arity,Arguments,_),Map,Term) :-
11327 functor(Term,Functor,Arity),
11328 Term =.. [_|Terms],
11329 maplist(ast_instantiate(Map),Arguments,Terms).
11330 %------------------------------------------------------------------------------%
11333 %------------------------------------------------------------------------------%
11334 % ast_head_arg_matches_(list(silent_pair(ast_term,var)
11342 %------------------------------------------------------------------------------%
11344 ast_head_arg_matches_([],[],VarDict,GroundVars,[],VarDict,GroundVars).
11345 ast_head_arg_matches_([silent(Arg-Var)| Rest],[Mode|Modes],VarDict,GroundVars,GoalList,NVarDict,NGroundVars) :- !,
11347 ast_term_variables(Arg,GroundVars0,GroundVars),
11348 ast_head_arg_matches_(Rest,Modes,VarDict,GroundVars0,GoalList,NVarDict,NGroundVars)
11350 ast_head_arg_matches_(Rest,Modes,VarDict,GroundVars,GoalList,NVarDict,NGroundVars)
11352 ast_head_arg_matches_([Arg-Var| Rest],[Mode|Modes],VarDict,GroundVars,GoalList,NVarDict,NGroundVars) :-
11353 ( Arg = var(VarId,_) ->
11354 ( get_assoc(VarId,VarDict,OtherVar) ->
11356 ( tree_set_memberchk(VarId,GroundVars) ->
11357 GoalList = [Var = OtherVar | RestGoalList],
11358 GroundVars1 = GroundVars
11360 GoalList = [Var == OtherVar | RestGoalList],
11361 tree_set_add(GroundVars,VarId,GroundVars1)
11364 GoalList = [Var == OtherVar | RestGoalList],
11365 GroundVars1 = GroundVars
11369 put_assoc(VarId,VarDict,Var,VarDict1),
11370 GoalList = RestGoalList,
11373 tree_set_add(GroundVars,VarId,GroundVars1)
11375 GroundVars1 = GroundVars
11380 ; ground(Arg), Arg = '$chr_identifier_match'(ActualArg,IndexType) -> % TODO
11381 identifier_label_atom(IndexType,Var,ActualArg,Goal),
11382 GoalList = [Goal|RestGoalList],
11383 VarDict = VarDict1,
11384 GroundVars1 = GroundVars,
11387 ; Arg = atomic(Atom) ->
11389 GoalList = [ Var = Atom | RestGoalList]
11391 GoalList = [ Var == Atom | RestGoalList]
11393 VarDict = VarDict1,
11394 GroundVars1 = GroundVars,
11397 ; Mode == (+), ast_is_ground(GroundVars,Arg) ->
11398 ast_instantiate(VarDict,Arg,ArgInst),
11399 GoalList = [ Var = ArgInst | RestGoalList],
11400 VarDict = VarDict1,
11401 GroundVars1 = GroundVars,
11404 ; Mode == (?), ast_is_ground(GroundVars,Arg) ->
11405 ast_instantiate(VarDict,Arg,ArgInst),
11406 GoalList = [ Var == ArgInst | RestGoalList],
11407 VarDict = VarDict1,
11408 GroundVars1 = GroundVars,
11411 ; Arg = compound(Functor,Arity,Arguments,_),
11412 functor(Term,Functor,Arity),
11415 GoalList = [ Var = Term | RestGoalList ]
11417 GoalList = [ nonvar(Var), Var = Term | RestGoalList ]
11419 pairup(Arguments,Vars,NewPairs),
11420 append(NewPairs,Rest,Pairs),
11421 replicate(N,Mode,NewModes),
11422 append(NewModes,Modes,RestModes),
11423 VarDict1 = VarDict,
11424 GroundVars1 = GroundVars
11426 ast_head_arg_matches_(Pairs,RestModes,VarDict1,GroundVars1,RestGoalList,NVarDict,NGroundVars).