3 Part of CHR (Constraint Handling Rules)
6 E-mail: Tom.Schrijvers@cs.kuleuven.be
7 WWW: http://www.swi-prolog.org
8 Copyright (C): 2003-2004, K.U. Leuven
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License
12 as published by the Free Software Foundation; either version 2
13 of the License, or (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU Lesser General Public
21 License along with this library; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 As a special exception, if you link this library with other files,
25 compiled with a Free Software compiler, to produce an executable, this
26 library does not by itself cause the resulting executable to be covered
27 by the GNU General Public License. This exception does not however
28 invalidate any other reasons why the executable file might be covered by
29 the GNU General Public License.
32 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
34 %% ____ _ _ ____ ____ _ _
35 %% / ___| | | | _ \ / ___|___ _ __ ___ _ __ (_) | ___ _ __
36 %% | | | |_| | |_) | | | / _ \| '_ ` _ \| '_ \| | |/ _ \ '__|
37 %% | |___| _ | _ < | |__| (_) | | | | | | |_) | | | __/ |
38 %% \____|_| |_|_| \_\ \____\___/|_| |_| |_| .__/|_|_|\___|_|
41 %% hProlog CHR compiler:
43 %% * by Tom Schrijvers, K.U. Leuven, Tom.Schrijvers@cs.kuleuven.be
45 %% * based on the SICStus CHR compilation by Christian Holzbaur
47 %% First working version: 6 June 2003
49 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
55 %% * add mode checking to debug mode
56 %% * add groundness info to a.i.-based observation analysis
57 %% * proper fd/index analysis
58 %% * re-add generation checking
59 %% * untangle CHR-level and target source-level generation & optimization
61 %% AGGRESSIVE OPTIMISATION IDEAS
63 %% * analyze history usage to determine whether/when
64 %% cheaper suspension is possible:
65 %% don't use history when all partners are passive and self never triggers
66 %% * store constraint unconditionally for unconditional propagation rule,
67 %% if first, i.e. without checking history and set trigger cont to next occ
68 %% * get rid of suspension passing for never triggered constraints,
69 %% up to allocation occurrence
70 %% * get rid of call indirection for never triggered constraints
71 %% up to first allocation occurrence.
72 %% * get rid of unnecessary indirection if last active occurrence
73 %% before unconditional removal is head2, e.g.
76 %% * Eliminate last clause of never stored constraint, if its body
80 %% * Specialize lookup operations and indexes for functional dependencies.
84 %% * map A \ B <=> true | true rules
85 %% onto efficient code that empties the constraint stores of B
86 %% in O(1) time for ground constraints where A and B do not share
88 %% * ground matching seems to be not optimized for compound terms
89 %% in case of simpagation_head2 and propagation occurrences
90 %% * analysis for storage delaying (see primes for case)
91 %% * internal constraints declaration + analyses?
92 %% * Do not store in global variable store if not necessary
93 %% NOTE: affects show_store/1
94 %% * var_assoc multi-level store: variable - ground
95 %% * Do not maintain/check unnecessary propagation history
96 %% for reasons of anti-monotony
97 %% * Strengthen storage analysis for propagation rules
98 %% reason about bodies of rules only containing constraints
99 %% -> fixpoint with observation analysis
100 %% * instantiation declarations
101 %% COMPOUND (bound to nonvar)
102 %% avoid nonvar tests
104 %% * make difference between cheap guards for reordering
105 %% and non-binding guards for lock removal
106 %% * fd -> once/[] transformation for propagation
107 %% * cheap guards interleaved with head retrieval + faster
108 %% via-retrieval + non-empty checking for propagation rules
109 %% redo for simpagation_head2 prelude
110 %% * intelligent backtracking for simplification/simpagation rule
111 %% generator_1(X),'_$savecp'(CP_1),
118 %% ('_$cutto'(CP_1), fail)
122 %% or recently developped cascading-supported approach
123 %% * intelligent backtracking for propagation rule
124 %% use additional boolean argument for each possible smart backtracking
125 %% when boolean at end of list true -> no smart backtracking
126 %% false -> smart backtracking
127 %% only works for rules with at least 3 constraints in the head
128 %% * (set semantics + functional dependency) declaration + resolution
130 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
131 :- module(chr_translate,
132 [ chr_translate/2 % +Decls, -TranslatedDecls
133 , chr_translate_line_info/3 % +DeclsWithLines, -TranslatedDecls
136 :- use_module(library(lists),[member/2, append/3,reverse/2,permutation/2,last/2]).
137 :- use_module(library(ordsets)).
138 :- use_module(library(aggregate)).
139 :- use_module(library(apply_macros)).
140 :- use_module(library(occurs)).
141 :- use_module(library(assoc)).
144 % imports and operators {{{
145 :- use_module(hprolog).
146 :- use_module(pairlist).
147 :- use_module(a_star).
148 :- use_module(listmap).
149 :- use_module(clean_code).
150 :- use_module(builtins).
152 :- use_module(binomialheap).
153 :- use_module(guard_entailment).
154 :- use_module(chr_compiler_options).
155 :- use_module(chr_compiler_utility).
156 :- use_module(chr_compiler_errors).
158 :- op(1150, fx, chr_type).
159 :- op(1150, fx, chr_declaration).
160 :- op(1130, xfx, --->).
164 :- op(1150, fx, constraints).
165 :- op(1150, fx, chr_constraint).
168 :- chr_option(debug,off).
169 :- chr_option(optimize,full).
170 :- chr_option(check_guard_bindings,off).
172 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
173 % Type Declarations {{{
174 :- chr_type list(T) ---> [] ; [T|list(T)].
176 :- chr_type list == list(any).
178 :- chr_type mode ---> (+) ; (-) ; (?).
180 :- chr_type maybe(T) ---> yes(T) ; no.
182 :- chr_type constraint ---> any / any.
184 :- chr_type module_name == any.
186 :- chr_type pragma_rule ---> pragma(rule,idspair,list(pragma_type),maybe(rule_name),rule_nb).
187 :- chr_type rule ---> rule(list(any),list(any),goal,goal).
188 :- chr_type idspair ---> ids(list(id),list(id)).
190 :- chr_type pragma_type ---> passive(id)
193 ; already_in_heads(id)
195 ; history(history_name,list(id)).
196 :- chr_type history_name== any.
198 :- chr_type rule_name == any.
199 :- chr_type rule_nb == natural.
200 :- chr_type id == natural.
201 :- chr_type occurrence == int.
203 :- chr_type goal == any.
205 :- chr_type store_type ---> default
206 ; multi_store(list(store_type))
207 ; multi_hash(list(list(int)))
208 ; multi_inthash(list(list(int)))
211 % EXPERIMENTAL STORES
212 ; atomic_constants(list(int),list(any),coverage)
213 ; ground_constants(list(int),list(any),coverage)
214 ; var_assoc_store(int,list(int))
215 ; identifier_store(int)
216 ; type_indexed_identifier_store(int,any).
217 :- chr_type coverage ---> complete ; incomplete.
219 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
221 %------------------------------------------------------------------------------%
222 :- chr_constraint chr_source_file/1.
223 :- chr_option(mode,chr_source_file(+)).
224 :- chr_option(type_declaration,chr_source_file(module_name)).
225 %------------------------------------------------------------------------------%
226 chr_source_file(_) \ chr_source_file(_) <=> true.
228 %------------------------------------------------------------------------------%
229 :- chr_constraint get_chr_source_file/1.
230 :- chr_option(mode,get_chr_source_file(-)).
231 :- chr_option(type_declaration,get_chr_source_file(module_name)).
232 %------------------------------------------------------------------------------%
233 chr_source_file(Mod) \ get_chr_source_file(Query)
235 get_chr_source_file(Query)
239 %------------------------------------------------------------------------------%
240 :- chr_constraint target_module/1.
241 :- chr_option(mode,target_module(+)).
242 :- chr_option(type_declaration,target_module(module_name)).
243 %------------------------------------------------------------------------------%
244 target_module(_) \ target_module(_) <=> true.
246 %------------------------------------------------------------------------------%
247 :- chr_constraint get_target_module/1.
248 :- chr_option(mode,get_target_module(-)).
249 :- chr_option(type_declaration,get_target_module(module_name)).
250 %------------------------------------------------------------------------------%
251 target_module(Mod) \ get_target_module(Query)
253 get_target_module(Query)
256 %------------------------------------------------------------------------------%
257 :- chr_constraint line_number/2.
258 :- chr_option(mode,line_number(+,+)).
259 :- chr_option(type_declaration,line_number(rule_nb,int)).
260 %------------------------------------------------------------------------------%
261 line_number(RuleNb,LineNb) \ line_number(RuleNb,LineNumber) <=> true.
263 %------------------------------------------------------------------------------%
264 :- chr_constraint get_line_number/2.
265 :- chr_option(mode,get_line_number(+,-)).
266 :- chr_option(type_declaration,get_line_number(rule_nb,int)).
267 %------------------------------------------------------------------------------%
268 line_number(RuleNb,LineNb) \ get_line_number(RuleNb,Q) <=> Q = LineNb.
269 get_line_number(RuleNb,Q) <=> Q = 0. % no line number available
271 :- chr_constraint indexed_argument/2. % argument instantiation may enable applicability of rule
272 :- chr_option(mode,indexed_argument(+,+)).
273 :- chr_option(type_declaration,indexed_argument(constraint,int)).
275 :- chr_constraint is_indexed_argument/2.
276 :- chr_option(mode,is_indexed_argument(+,+)).
277 :- chr_option(type_declaration,is_indexed_argument(constraint,int)).
279 :- chr_constraint constraint_mode/2.
280 :- chr_option(mode,constraint_mode(+,+)).
281 :- chr_option(type_declaration,constraint_mode(constraint,list(mode))).
283 :- chr_constraint get_constraint_mode/2.
284 :- chr_option(mode,get_constraint_mode(+,-)).
285 :- chr_option(type_declaration,get_constraint_mode(constraint,list(mode))).
287 :- chr_constraint may_trigger/1.
288 :- chr_option(mode,may_trigger(+)).
289 :- chr_option(type_declaration,may_trigger(constraint)).
291 :- chr_constraint only_ground_indexed_arguments/1.
292 :- chr_option(mode,only_ground_indexed_arguments(+)).
293 :- chr_option(type_declaration,only_ground_indexed_arguments(constraint)).
295 :- chr_constraint none_suspended_on_variables/0.
297 :- chr_constraint are_none_suspended_on_variables/0.
299 :- chr_constraint store_type/2.
300 :- chr_option(mode,store_type(+,+)).
301 :- chr_option(type_declaration,store_type(constraint,store_type)).
303 :- chr_constraint get_store_type/2.
304 :- chr_option(mode,get_store_type(+,?)).
305 :- chr_option(type_declaration,get_store_type(constraint,store_type)).
307 :- chr_constraint update_store_type/2.
308 :- chr_option(mode,update_store_type(+,+)).
309 :- chr_option(type_declaration,update_store_type(constraint,store_type)).
311 :- chr_constraint actual_store_types/2.
312 :- chr_option(mode,actual_store_types(+,+)).
313 :- chr_option(type_declaration,actual_store_types(constraint,list(store_type))).
315 :- chr_constraint assumed_store_type/2.
316 :- chr_option(mode,assumed_store_type(+,+)).
317 :- chr_option(type_declaration,assumed_store_type(constraint,store_type)).
319 :- chr_constraint validate_store_type_assumption/1.
320 :- chr_option(mode,validate_store_type_assumption(+)).
321 :- chr_option(type_declaration,validate_store_type_assumption(constraint)).
323 :- chr_constraint rule_count/1.
324 :- chr_option(mode,rule_count(+)).
325 :- chr_option(type_declaration,rule_count(natural)).
327 :- chr_constraint inc_rule_count/1.
328 :- chr_option(mode,inc_rule_count(-)).
329 :- chr_option(type_declaration,inc_rule_count(natural)).
331 rule_count(_) \ rule_count(_)
333 rule_count(C), inc_rule_count(NC)
334 <=> NC is C + 1, rule_count(NC).
336 <=> NC = 1, rule_count(NC).
338 :- chr_constraint passive/2.
339 :- chr_option(mode,passive(+,+)).
341 :- chr_constraint is_passive/2.
342 :- chr_option(mode,is_passive(+,+)).
344 :- chr_constraint any_passive_head/1.
345 :- chr_option(mode,any_passive_head(+)).
347 :- chr_constraint new_occurrence/4.
348 :- chr_option(mode,new_occurrence(+,+,+,+)).
350 :- chr_constraint occurrence/5.
351 :- chr_option(mode,occurrence(+,+,+,+,+)).
352 :- chr_type occurrence_type ---> simplification ; propagation.
353 :- chr_option(type_declaration,occurrence(constraint,occurrence,rule_nb,id,occurrence_type)).
355 :- chr_constraint get_occurrence/4.
356 :- chr_option(mode,get_occurrence(+,+,-,-)).
358 :- chr_constraint get_occurrence_from_id/4.
359 :- chr_option(mode,get_occurrence_from_id(+,-,+,+)).
361 :- chr_constraint max_occurrence/2.
362 :- chr_option(mode,max_occurrence(+,+)).
364 :- chr_constraint get_max_occurrence/2.
365 :- chr_option(mode,get_max_occurrence(+,-)).
367 :- chr_constraint allocation_occurrence/2.
368 :- chr_option(mode,allocation_occurrence(+,+)).
370 :- chr_constraint get_allocation_occurrence/2.
371 :- chr_option(mode,get_allocation_occurrence(+,-)).
373 :- chr_constraint rule/2.
374 :- chr_option(mode,rule(+,+)).
375 :- chr_option(type_declaration,rule(rule_nb,pragma_rule)).
377 :- chr_constraint get_rule/2.
378 :- chr_option(mode,get_rule(+,-)).
379 :- chr_option(type_declaration,get_rule(int,pragma_rule)).
381 :- chr_constraint least_occurrence/2.
382 :- chr_option(mode,least_occurrence(+,+)).
383 :- chr_option(type_declaration,least_occurrence(any,list)).
385 :- chr_constraint is_least_occurrence/1.
386 :- chr_option(mode,is_least_occurrence(+)).
389 indexed_argument(FA,I) \ indexed_argument(FA,I) <=> true.
390 indexed_argument(FA,I) \ is_indexed_argument(FA,I) <=> true.
391 is_indexed_argument(_,_) <=> fail.
393 %%% C O N S T R A I N T M O D E %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
395 constraint_mode(FA,_) \ constraint_mode(FA,_) <=> true.
396 constraint_mode(FA,Mode) \ get_constraint_mode(FA,Q) <=>
398 get_constraint_mode(FA,Q) <=>
402 %%% M A Y T R I G G E R %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
404 may_trigger(FA) <=> \+ has_active_occurrence(FA) | fail.
405 constraint_mode(FA,Mode), indexed_argument(FA,I) \ may_trigger(FA) <=>
409 may_trigger(FA) <=> chr_pp_flag(debugable,on). % in debug mode, we assume everything can be triggered
411 constraint_mode(FA,Mode), indexed_argument(FA,I) \ only_ground_indexed_arguments(FA)
417 only_ground_indexed_arguments(_) <=>
420 none_suspended_on_variables \ none_suspended_on_variables <=> true.
421 none_suspended_on_variables \ are_none_suspended_on_variables <=> true.
422 are_none_suspended_on_variables <=> fail.
423 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
426 % The functionality for inspecting and deciding on the different types of constraint
427 % store / indexes for constraints.
429 store_type(FA,StoreType)
430 ==> chr_pp_flag(verbose,on)
432 format('The indexes for ~w are:\n',[FA]),
433 format_storetype(StoreType).
434 % chr_info(verbose,'Storetype of ~w is ~w.\n',[FA,StoreType]).
436 format_storetype(multi_store(StoreTypes)) :- !,
437 maplist(format_storetype,StoreTypes).
438 format_storetype(atomic_constants(Index,Constants,_)) :-
439 format('\t* a trie index on the argument(s) ~w for the ground terms ~w\n',[Index,Constants]).
440 format_storetype(ground_constants(Index,Constants,_)) :-
441 format('\t* a trie index on the argument(s) ~w for the ground terms ~w\n',[Index,Constants]).
442 format_storetype(StoreType) :-
443 format('\t* ~w\n',[StoreType]).
451 get_store_type_normal @
452 store_type(FA,Store) \ get_store_type(FA,Query)
455 get_store_type_assumed @
456 assumed_store_type(FA,Store) \ get_store_type(FA,Query)
459 get_store_type_default @
460 get_store_type(_,Query)
463 % 2. Store type registration
464 % ~~~~~~~~~~~~~~~~~~~~~~~~~~
466 actual_store_types(C,STs) \ update_store_type(C,ST)
467 <=> memberchk(ST,STs) | true.
468 update_store_type(C,ST), actual_store_types(C,STs)
470 actual_store_types(C,[ST|STs]).
471 update_store_type(C,ST)
473 actual_store_types(C,[ST]).
475 % 3. Final decision on store types
476 % ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
478 validate_store_type_assumption(C) \ actual_store_types(C,STs), actual_atomic_multi_hash_keys(C,Index,Keys)
480 true % chr_pp_flag(experiment,on)
482 delete(STs,multi_hash([Index]),STs0),
484 ( get_constraint_arg_type(C,IndexPos,Type),
485 enumerated_atomic_type(Type,Atoms) ->
486 /* use the type constants rather than the collected keys */
488 Completeness = complete
491 Completeness = incomplete
493 actual_store_types(C,[atomic_constants(Index,Constants,Completeness)|STs0]).
494 validate_store_type_assumption(C) \ actual_store_types(C,STs), actual_ground_multi_hash_keys(C,Index,Constants0)
496 true % chr_pp_flag(experiment,on)
498 ( Index = [IndexPos],
499 get_constraint_arg_type(C,IndexPos,Type),
500 % ( fail , is_chr_constants_type(Type,Key,_) -> get_chr_constants(Key,Constants)
502 Type = chr_enum(Constants) % -> true
505 Completeness = complete
507 Constants = Constants0,
508 Completeness = incomplete
510 delete(STs,multi_hash([Index]),STs0),
511 actual_store_types(C,[ground_constants(Index,Constants,Completeness)|STs0]).
513 get_constraint_arg_type(C,Pos,Type) :-
514 get_constraint_type(C,Types),
515 nth1(Pos,Types,Type0),
516 unalias_type(Type0,Type).
518 validate_store_type_assumption(C) \ actual_store_types(C,STs)
520 % chr_pp_flag(experiment,on),
521 memberchk(multi_hash([[Index]]),STs),
522 get_constraint_type(C,Types),
523 nth1(Index,Types,Type),
524 enumerated_atomic_type(Type,Atoms)
526 delete(STs,multi_hash([[Index]]),STs0),
527 actual_store_types(C,[atomic_constants([Index],Atoms,complete)|STs0]).
528 validate_store_type_assumption(C) \ actual_store_types(C,STs)
530 memberchk(multi_hash([[Index]]),STs),
531 get_constraint_arg_type(C,Index,Type),
533 Type = chr_enum(Constants) % -> true
534 % ; fail, is_chr_constants_type(Type,Key,_) -> get_chr_constants(Key,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,_) \ get_occurrence_from_id(QC,QON,Rule,ID)
596 <=> QC = C, QON = ON.
597 get_occurrence_from_id(C,O,_,_)
598 <=> chr_error(internal,'get_occurrence_from_id: missing occurrence ~w:~w\n',[]).
600 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
603 late_allocation_analysis(Cs) :-
604 ( chr_pp_flag(late_allocation,on) ->
605 maplist(late_allocation, Cs)
610 late_allocation(C) :- late_allocation(C,0).
611 late_allocation(C,O) :- allocation_occurrence(C,O), !.
612 late_allocation(C,O) :- NO is O + 1, late_allocation(C,NO).
614 % A L L O C C A T I O N O C C U R R E N C E %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
616 allocation_occurrence(C,0) ==> stored_in_guard_before_next_kept_occurrence(C,0).
618 rule(RuleNb,Rule), occurrence(C,O,RuleNb,Id,Type), allocation_occurrence(C,O) ==>
619 \+ is_passive(RuleNb,Id),
621 ( stored_in_guard_before_next_kept_occurrence(C,O) ->
623 ; Rule = pragma(rule([_|_],_,_,_),_,_,_,_) -> % simpagation rule
625 ; is_least_occurrence(RuleNb) -> % propagation rule
631 stored_in_guard_before_next_kept_occurrence(C,O) :-
632 chr_pp_flag(store_in_guards, on),
634 stored_in_guard_lookahead(C,NO).
636 :- chr_constraint stored_in_guard_lookahead/2.
637 :- chr_option(mode, stored_in_guard_lookahead(+,+)).
639 occurrence(C,O,RuleNb,Id,_), passive(RuleNb,Id) \ stored_in_guard_lookahead(C,O) <=>
640 NO is O + 1, stored_in_guard_lookahead(C,NO).
641 occurrence(C,O,RuleNb,Id,Type) \ stored_in_guard_lookahead(C,O) <=>
642 Type == simplification,
643 ( is_stored_in_guard(C,RuleNb) ->
646 NO is O + 1, stored_in_guard_lookahead(C,NO)
648 stored_in_guard_lookahead(_,_) <=> fail.
651 rule(RuleNb,Rule), occurrence(C,O,RuleNb,ID,_), allocation_occurrence(C,AO)
652 \ least_occurrence(RuleNb,[ID|IDs])
653 <=> AO >= O, \+ may_trigger(C) |
654 least_occurrence(RuleNb,IDs).
655 rule(RuleNb,Rule), passive(RuleNb,ID)
656 \ least_occurrence(RuleNb,[ID|IDs])
657 <=> least_occurrence(RuleNb,IDs).
660 ==> Rule = pragma(rule([],_,_,_),ids([],IDs),_,_,_) |
661 least_occurrence(RuleNb,IDs).
663 least_occurrence(RuleNb,[]) \ is_least_occurrence(RuleNb)
665 is_least_occurrence(_)
668 allocation_occurrence(C,O) \ get_allocation_occurrence(C,Q)
670 get_allocation_occurrence(_,Q)
671 <=> chr_pp_flag(late_allocation,off), Q=0.
672 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
674 rule(RuleNb,Rule) \ get_rule(RuleNb,Q)
679 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
681 %%% C O N S T R A I N T I N D E X %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
683 % Default store constraint index assignment.
685 :- chr_constraint constraint_index/2. % constraint_index(F/A,DefaultStoreAndAttachedIndex)
686 :- chr_option(mode,constraint_index(+,+)).
687 :- chr_option(type_declaration,constraint_index(constraint,int)).
689 :- chr_constraint get_constraint_index/2.
690 :- chr_option(mode,get_constraint_index(+,-)).
691 :- chr_option(type_declaration,get_constraint_index(constraint,int)).
693 :- chr_constraint get_indexed_constraint/2.
694 :- chr_option(mode,get_indexed_constraint(+,-)).
695 :- chr_option(type_declaration,get_indexed_constraint(int,constraint)).
697 :- chr_constraint max_constraint_index/1. % max_constraint_index(MaxDefaultStoreAndAttachedIndex)
698 :- chr_option(mode,max_constraint_index(+)).
699 :- chr_option(type_declaration,max_constraint_index(int)).
701 :- chr_constraint get_max_constraint_index/1.
702 :- chr_option(mode,get_max_constraint_index(-)).
703 :- chr_option(type_declaration,get_max_constraint_index(int)).
705 constraint_index(C,Index) \ get_constraint_index(C,Query)
707 get_constraint_index(C,Query)
710 constraint_index(C,Index) \ get_indexed_constraint(Index,Q)
712 get_indexed_constraint(Index,Q)
715 max_constraint_index(Index) \ get_max_constraint_index(Query)
717 get_max_constraint_index(Query)
720 set_constraint_indices(Constraints) :-
721 set_constraint_indices(Constraints,1).
722 set_constraint_indices([],M) :-
724 max_constraint_index(N).
725 set_constraint_indices([C|Cs],N) :-
726 ( ( chr_pp_flag(debugable, on) ; \+ only_ground_indexed_arguments(C), is_stored(C) ; is_stored(C), get_store_type(C,default)
727 ; get_store_type(C,var_assoc_store(_,_))) ->
728 constraint_index(C,N),
730 set_constraint_indices(Cs,M)
732 set_constraint_indices(Cs,N)
735 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
738 :- chr_constraint identifier_size/1.
739 :- chr_option(mode,identifier_size(+)).
740 :- chr_option(type_declaration,identifier_size(natural)).
742 identifier_size(_) \ identifier_size(_)
746 :- chr_constraint get_identifier_size/1.
747 :- chr_option(mode,get_identifier_size(-)).
748 :- chr_option(type_declaration,get_identifier_size(natural)).
750 identifier_size(Size) \ get_identifier_size(Q)
754 get_identifier_size(Q)
758 :- chr_constraint identifier_index/3.
759 :- chr_option(mode,identifier_index(+,+,+)).
760 :- chr_option(type_declaration,identifier_index(constraint,natural,natural)).
762 identifier_index(C,I,_) \ identifier_index(C,I,_)
766 :- chr_constraint get_identifier_index/3.
767 :- chr_option(mode,get_identifier_index(+,+,-)).
768 :- chr_option(type_declaration,get_identifier_index(constraint,natural,natural)).
770 identifier_index(C,I,II) \ get_identifier_index(C,I,Q)
773 identifier_size(Size), get_identifier_index(C,I,Q)
776 identifier_index(C,I,NSize),
777 identifier_size(NSize),
779 get_identifier_index(C,I,Q)
781 identifier_index(C,I,2),
785 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
786 % Type Indexed Identifier Indexes
788 :- chr_constraint type_indexed_identifier_size/2.
789 :- chr_option(mode,type_indexed_identifier_size(+,+)).
790 :- chr_option(type_declaration,type_indexed_identifier_size(any,natural)).
792 type_indexed_identifier_size(IndexType,_) \ type_indexed_identifier_size(IndexType,_)
796 :- chr_constraint get_type_indexed_identifier_size/2.
797 :- chr_option(mode,get_type_indexed_identifier_size(+,-)).
798 :- chr_option(type_declaration,get_type_indexed_identifier_size(any,natural)).
800 type_indexed_identifier_size(IndexType,Size) \ get_type_indexed_identifier_size(IndexType,Q)
804 get_type_indexed_identifier_size(IndexType,Q)
808 :- chr_constraint type_indexed_identifier_index/4.
809 :- chr_option(mode,type_indexed_identifier_index(+,+,+,+)).
810 :- chr_option(type_declaration,type_indexed_identifier_index(any,constraint,natural,natural)).
812 type_indexed_identifier_index(_,C,I,_) \ type_indexed_identifier_index(_,C,I,_)
816 :- chr_constraint get_type_indexed_identifier_index/4.
817 :- chr_option(mode,get_type_indexed_identifier_index(+,+,+,-)).
818 :- chr_option(type_declaration,get_type_indexed_identifier_index(any,constraint,natural,natural)).
820 type_indexed_identifier_index(IndexType,C,I,II) \ get_type_indexed_identifier_index(IndexType,C,I,Q)
823 type_indexed_identifier_size(IndexType,Size), get_type_indexed_identifier_index(IndexType,C,I,Q)
826 type_indexed_identifier_index(IndexType,C,I,NSize),
827 type_indexed_identifier_size(IndexType,NSize),
829 get_type_indexed_identifier_index(IndexType,C,I,Q)
831 type_indexed_identifier_index(IndexType,C,I,2),
832 type_indexed_identifier_size(IndexType,2),
835 type_indexed_identifier_structure(IndexType,Structure) :-
836 type_indexed_identifier_name(IndexType,type_indexed_identifier_struct,Functor),
837 get_type_indexed_identifier_size(IndexType,Arity),
838 functor(Structure,Functor,Arity).
839 type_indexed_identifier_name(IndexType,Prefix,Name) :-
841 IndexTypeName = IndexType
843 term_to_atom(IndexType,IndexTypeName)
845 atom_concat_list([Prefix,'_',IndexTypeName],Name).
847 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
852 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
856 chr_translate(Declarations,NewDeclarations) :-
857 chr_translate_line_info(Declarations,'bootstrap',NewDeclarations).
859 chr_translate_line_info(Declarations0,File,NewDeclarations) :-
861 restart_after_flattening(Declarations0,Declarations),
863 chr_source_file(File),
864 /* sort out the interesting stuff from the input */
865 partition_clauses(Declarations,Constraints0,Rules0,OtherClauses),
866 chr_compiler_options:sanity_check,
868 dump_code(Declarations),
870 check_declared_constraints(Constraints0),
871 generate_show_constraint(Constraints0,Constraints,Rules0,Rules1),
872 add_constraints(Constraints),
874 generate_never_stored_rules(Constraints,NewRules),
876 append(Rules1,NewRules,Rules),
877 chr_analysis(Rules,Constraints,Declarations),
878 time('constraint code generation',chr_translate:constraints_code(Constraints,ConstraintClauses)),
879 time('validate store assumptions',chr_translate:validate_store_type_assumptions(Constraints)),
880 phase_end(validate_store_type_assumptions),
882 time('store code generation',chr_translate:store_management_preds(Constraints,StoreClauses)), % depends on actual code used
883 insert_declarations(OtherClauses, Clauses0),
884 chr_module_declaration(CHRModuleDeclaration),
885 append([StoreClauses,ConstraintClauses,CHRModuleDeclaration,[end_of_file]],StuffyGeneratedClauses),
886 clean_clauses(StuffyGeneratedClauses,GeneratedClauses),
887 append([Clauses0,GeneratedClauses], NewDeclarations),
888 dump_code(NewDeclarations),
889 !. /* cut choicepoint of restart_after_flattening */
891 chr_analysis(Rules,Constraints,Declarations) :-
892 check_rules(Rules,Constraints),
893 time('type checking',chr_translate:static_type_check),
895 collect_constants(Rules,Constraints,Declarations),
896 add_occurrences(Rules),
897 time('functional dependency',chr_translate:functional_dependency_analysis(Rules)),
898 time('set semantics',chr_translate:set_semantics_rules(Rules)),
899 time('symmetry analysis',chr_translate:symmetry_analysis(Rules)),
900 time('guard simplification',chr_translate:guard_simplification),
901 time('late storage',chr_translate:storage_analysis(Constraints)),
902 time('observation',chr_translate:observation_analysis(Constraints)),
903 time('ai observation',chr_translate:ai_observation_analysis(Constraints)),
904 time('late allocation',chr_translate:late_allocation_analysis(Constraints)),
905 partial_wake_analysis,
906 time('assume constraint stores',chr_translate:assume_constraint_stores(Constraints)),
907 time('default constraint indices',chr_translate:set_constraint_indices(Constraints)),
908 time('check storedness assertions',chr_translate:check_storedness_assertions(Constraints)),
909 time('continuation analysis',chr_translate:continuation_analysis(Constraints)).
911 store_management_preds(Constraints,Clauses) :-
912 generate_attach_detach_a_constraint_all(Constraints,AttachAConstraintClauses),
913 generate_attr_unify_hook(AttrUnifyHookClauses),
914 generate_attach_increment(AttachIncrementClauses),
915 generate_extra_clauses(Constraints,ExtraClauses),
916 generate_insert_delete_constraints(Constraints,DeleteClauses),
917 generate_attach_code(Constraints,StoreClauses),
918 generate_counter_code(CounterClauses),
919 generate_dynamic_type_check_clauses(TypeCheckClauses),
920 append([AttachAConstraintClauses
921 ,AttachIncrementClauses
922 ,AttrUnifyHookClauses
932 insert_declarations(Clauses0, Clauses) :-
933 findall(:- use_module(chr(Module)),(auxiliary_module(Module), is_used_auxiliary_module(Module)),Decls),
934 append(Clauses0, [:- use_module(chr(chr_runtime))|Decls], Clauses).
936 auxiliary_module(chr_hashtable_store).
937 auxiliary_module(chr_integertable_store).
938 auxiliary_module(chr_assoc_store).
940 generate_counter_code(Clauses) :-
941 ( chr_pp_flag(store_counter,on) ->
943 ('$counter_init'(N1) :- nb_setval(N1,0)) ,
944 ('$counter'(N2,X1) :- nb_getval(N2,X1)),
945 ('$counter_inc'(N) :- nb_getval(N,X), Y is X + 1, nb_setval(N,Y)),
946 (:- '$counter_init'('$insert_counter')),
947 (:- '$counter_init'('$delete_counter')),
948 ('$insert_counter_inc' :- '$counter_inc'('$insert_counter')),
949 ('$delete_counter_inc' :- '$counter_inc'('$delete_counter')),
950 ( counter_stats(I,D) :- '$counter'('$insert_counter',I),'$counter'('$delete_counter',D))
956 % for systems with multifile declaration
957 chr_module_declaration(CHRModuleDeclaration) :-
958 get_target_module(Mod),
959 ( Mod \== chr_translate, chr_pp_flag(toplevel_show_store,on) ->
960 CHRModuleDeclaration = [
961 (:- multifile chr:'$chr_module'/1),
962 chr:'$chr_module'(Mod)
965 CHRModuleDeclaration = []
969 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
971 %% Partitioning of clauses into constraint declarations, chr rules and other
974 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
975 %% partition_clauses(+Clauses,-ConstraintDeclarations,-Rules,-OtherClauses) is det.
976 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
977 partition_clauses([],[],[],[]).
978 partition_clauses([Clause|Clauses],ConstraintDeclarations,Rules,OtherClauses) :-
979 ( parse_rule(Clause,Rule) ->
980 ConstraintDeclarations = RestConstraintDeclarations,
981 Rules = [Rule|RestRules],
982 OtherClauses = RestOtherClauses
983 ; is_declaration(Clause,ConstraintDeclaration) ->
984 append(ConstraintDeclaration,RestConstraintDeclarations,ConstraintDeclarations),
986 OtherClauses = RestOtherClauses
987 ; is_module_declaration(Clause,Mod) ->
989 ConstraintDeclarations = RestConstraintDeclarations,
991 OtherClauses = [Clause|RestOtherClauses]
992 ; is_type_definition(Clause) ->
993 ConstraintDeclarations = RestConstraintDeclarations,
995 OtherClauses = RestOtherClauses
996 ; is_chr_declaration(Clause) ->
997 ConstraintDeclarations = RestConstraintDeclarations,
999 OtherClauses = RestOtherClauses
1000 ; Clause = (handler _) ->
1001 chr_warning(deprecated(Clause),'Backward compatibility: ignoring handler/1 declaration.\n',[]),
1002 ConstraintDeclarations = RestConstraintDeclarations,
1004 OtherClauses = RestOtherClauses
1005 ; Clause = (rules _) ->
1006 chr_warning(deprecated(Clause),'Backward compatibility: ignoring rules/1 declaration.\n',[]),
1007 ConstraintDeclarations = RestConstraintDeclarations,
1009 OtherClauses = RestOtherClauses
1010 ; Clause = option(OptionName,OptionValue) ->
1011 chr_warning(deprecated(Clause),'Instead use `:-chr_option(~w,~w).\'\n',[OptionName,OptionValue]),
1012 handle_option(OptionName,OptionValue),
1013 ConstraintDeclarations = RestConstraintDeclarations,
1015 OtherClauses = RestOtherClauses
1016 ; Clause = (:-chr_option(OptionName,OptionValue)) ->
1017 handle_option(OptionName,OptionValue),
1018 ConstraintDeclarations = RestConstraintDeclarations,
1020 OtherClauses = RestOtherClauses
1021 ; Clause = ('$chr_compiled_with_version'(_)) ->
1022 ConstraintDeclarations = RestConstraintDeclarations,
1024 OtherClauses = ['$chr_compiled_with_version'(3)|RestOtherClauses]
1025 ; ConstraintDeclarations = RestConstraintDeclarations,
1027 OtherClauses = [Clause|RestOtherClauses]
1029 partition_clauses(Clauses,RestConstraintDeclarations,RestRules,RestOtherClauses).
1031 '$chr_compiled_with_version'(2).
1033 is_declaration(D, Constraints) :- %% constraint declaration
1034 ( D = (:- Decl), Decl =.. [F,Cs], F == (chr_constraint) ->
1035 conj2list(Cs,Constraints0)
1038 Decl =.. [constraints,Cs]
1040 D =.. [constraints,Cs]
1042 conj2list(Cs,Constraints0),
1043 chr_warning(deprecated(D),'Instead use :- chr_constraint ~w.\n',[Cs])
1045 extract_type_mode(Constraints0,Constraints).
1047 extract_type_mode([],[]).
1048 extract_type_mode([F/A|R],[F/A|R2]) :- !,extract_type_mode(R,R2).
1049 extract_type_mode([C0|R],[ConstraintSymbol|R2]) :-
1050 ( C0 = C # Annotation ->
1052 extract_annotation(Annotation,F/A)
1057 ConstraintSymbol = F/A,
1059 extract_types_and_modes(Args,ArgTypes,ArgModes),
1060 assert_constraint_type(ConstraintSymbol,ArgTypes),
1061 constraint_mode(ConstraintSymbol,ArgModes),
1062 extract_type_mode(R,R2).
1064 extract_annotation(stored,Symbol) :-
1065 stored_assertion(Symbol).
1066 extract_annotation(default(Goal),Symbol) :-
1067 never_stored_default(Symbol,Goal).
1069 extract_types_and_modes([],[],[]).
1070 extract_types_and_modes([X|R],[T|R2],[M|R3]) :-
1071 extract_type_and_mode(X,T,M),
1072 extract_types_and_modes(R,R2,R3).
1074 extract_type_and_mode(+(T),T,(+)) :- !.
1075 extract_type_and_mode(?(T),T,(?)) :- !.
1076 extract_type_and_mode(-(T),T,(-)) :- !.
1077 extract_type_and_mode((+),any,(+)) :- !.
1078 extract_type_and_mode((?),any,(?)) :- !.
1079 extract_type_and_mode((-),any,(-)) :- !.
1080 extract_type_and_mode(Illegal,_,_) :-
1081 chr_error(syntax(Illegal),'Illegal mode/type declaration.\n\tCorrect syntax is +type, -type or ?type\n\tor +, - or ?.\n',[]).
1083 is_chr_declaration(Declaration) :-
1084 Declaration = (:- chr_declaration Decl),
1085 ( Decl = (Pattern ---> Information) ->
1086 background_info(Pattern,Information)
1087 ; Decl = Information ->
1088 background_info([Information])
1090 is_type_definition(Declaration) :-
1091 is_type_definition(Declaration,Result),
1092 assert_type_definition(Result).
1094 assert_type_definition(typedef(Name,DefList)) :- type_definition(Name,DefList).
1095 assert_type_definition(alias(Alias,Name)) :- type_alias(Alias,Name).
1097 is_type_definition(Declaration,Result) :-
1098 ( Declaration = (:- TDef) ->
1103 TDef =.. [chr_type,TypeDef],
1104 ( TypeDef = (Name ---> Def) ->
1105 tdisj2list(Def,DefList),
1106 Result = typedef(Name,DefList)
1107 ; TypeDef = (Alias == Name) ->
1108 Result = alias(Alias,Name)
1110 Result = typedef(TypeDef,[]),
1111 chr_warning(syntax,'Empty type definition `~w\'.\nAre you sure you want to declare a phantom type?\n',[Declaration])
1114 %% tdisj2list(+Goal,-ListOfGoals) is det.
1116 % no removal of fails, e.g. :- type bool ---> true ; fail.
1117 tdisj2list(Conj,L) :-
1118 tdisj2list(Conj,L,[]).
1120 tdisj2list(Conj,L,T) :-
1122 tdisj2list(G1,L,T1),
1123 tdisj2list(G2,T1,T).
1124 tdisj2list(G,[G | T],T).
1127 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
1128 %% parse_rule(+term,-pragma_rule) is semidet.
1129 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
1130 parse_rule(RI,R) :- %% name @ rule
1131 RI = (Name @ RI2), !,
1132 rule(RI2,yes(Name),R).
1136 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
1137 %% parse_rule(+term,-pragma_rule) is semidet.
1138 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
1140 RI = (RI2 pragma P), !, %% pragmas
1142 Ps = [_] % intercept variable
1146 inc_rule_count(RuleCount),
1147 R = pragma(R1,IDs,Ps,Name,RuleCount),
1148 is_rule(RI2,R1,IDs,R).
1150 inc_rule_count(RuleCount),
1151 R = pragma(R1,IDs,[],Name,RuleCount),
1152 is_rule(RI,R1,IDs,R).
1154 is_rule(RI,R,IDs,RC) :- %% propagation rule
1156 conj2list(H,Head2i),
1157 get_ids(Head2i,IDs2,Head2,RC),
1160 R = rule([],Head2,G,RB)
1162 R = rule([],Head2,true,B)
1164 is_rule(RI,R,IDs,RC) :- %% simplification/simpagation rule
1173 conj2list(H1,Head2i),
1174 conj2list(H2,Head1i),
1175 get_ids(Head2i,IDs2,Head2,0,N,RC),
1176 get_ids(Head1i,IDs1,Head1,N,_,RC),
1177 IDs = ids(IDs1,IDs2)
1178 ; conj2list(H,Head1i),
1180 get_ids(Head1i,IDs1,Head1,RC),
1183 R = rule(Head1,Head2,Guard,Body).
1185 get_ids(Cs,IDs,NCs,RC) :-
1186 get_ids(Cs,IDs,NCs,0,_,RC).
1188 get_ids([],[],[],N,N,_).
1189 get_ids([C|Cs],[N|IDs],[NC|NCs],N,NN,RC) :-
1194 check_direct_pragma(N1,N,RC)
1200 get_ids(Cs,IDs,NCs, M,NN,RC).
1202 check_direct_pragma(passive,Id,PragmaRule) :- !,
1203 PragmaRule = pragma(_,_,_,_,RuleNb),
1205 check_direct_pragma(Abbrev,Id,PragmaRule) :-
1206 ( direct_pragma(FullPragma),
1207 atom_concat(Abbrev,Remainder,FullPragma) ->
1208 chr_warning(problem_pragma(Abbrev,PragmaRule),'completed `~w\' to `~w\'\n',[Abbrev,FullPragma])
1210 chr_warning(unsupported_pragma(Abbrev,PragmaRule),'',[])
1213 direct_pragma(passive).
1215 is_module_declaration((:- module(Mod)),Mod).
1216 is_module_declaration((:- module(Mod,_)),Mod).
1218 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1220 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1222 add_constraints([]).
1223 add_constraints([C|Cs]) :-
1224 max_occurrence(C,0),
1228 constraint_mode(C,Mode),
1229 add_constraints(Cs).
1233 add_rules([Rule|Rules]) :-
1234 Rule = pragma(_,_,_,_,RuleNb),
1238 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1240 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1241 %% Some input verification:
1243 check_declared_constraints(Constraints) :-
1244 tree_set_empty(Acc),
1245 check_declared_constraints(Constraints,Acc).
1247 check_declared_constraints([],_).
1248 check_declared_constraints([C|Cs],Acc) :-
1249 ( tree_set_memberchk(C,Acc) ->
1250 chr_error(syntax(C),'Constraint multiply defined: ~w.\n\tRemove redundant declaration!\n',[C])
1254 tree_set_add(Acc,C,NAcc),
1255 check_declared_constraints(Cs,NAcc).
1257 %% - all constraints in heads are declared constraints
1258 %% - all passive pragmas refer to actual head constraints
1261 check_rules([PragmaRule|Rest],Decls) :-
1262 check_rule(PragmaRule,Decls),
1263 check_rules(Rest,Decls).
1265 check_rule(PragmaRule,Decls) :-
1266 check_rule_indexing(PragmaRule),
1267 check_trivial_propagation_rule(PragmaRule),
1268 PragmaRule = pragma(Rule,_IDs,Pragmas,_Name,_N),
1269 Rule = rule(H1,H2,_,_),
1270 append(H1,H2,HeadConstraints),
1271 check_head_constraints(HeadConstraints,Decls,PragmaRule),
1272 check_pragmas(Pragmas,PragmaRule).
1274 % Make all heads passive in trivial propagation rule
1275 % ... ==> ... | true.
1276 check_trivial_propagation_rule(PragmaRule) :-
1277 PragmaRule = pragma(Rule,IDs,Pragmas,Name,RuleNb),
1278 ( Rule = rule([],_,_,true) ->
1279 chr_warning(weird_program,'Ignoring propagation rule with empty body: ~@.\n\t\n',[format_rule(PragmaRule)]),
1280 set_all_passive(RuleNb)
1285 check_head_constraints([],_,_).
1286 check_head_constraints([Constr|Rest],Decls,PragmaRule) :-
1287 functor(Constr,F,A),
1288 ( memberchk(F/A,Decls) ->
1289 check_head_constraints(Rest,Decls,PragmaRule)
1291 chr_error(syntax(Constr),'Undeclared constraint ~w in head of ~@.\n\tConstraint should be one of ~w.\n', [F/A,format_rule(PragmaRule),Decls])
1294 check_pragmas([],_).
1295 check_pragmas([Pragma|Pragmas],PragmaRule) :-
1296 check_pragma(Pragma,PragmaRule),
1297 check_pragmas(Pragmas,PragmaRule).
1299 check_pragma(Pragma,PragmaRule) :-
1301 chr_error(syntax(Pragma),'Invalid pragma ~w in ~@.\n\tPragma should not be a variable!\n',[Pragma,format_rule(PragmaRule)]).
1302 check_pragma(passive(ID), PragmaRule) :-
1304 PragmaRule = pragma(_,ids(IDs1,IDs2),_,_,RuleNb),
1305 ( memberchk_eq(ID,IDs1) ->
1307 ; memberchk_eq(ID,IDs2) ->
1310 chr_error(syntax(ID),'Invalid identifier ~w in pragma passive in ~@.\n', [ID,format_rule(PragmaRule)])
1314 check_pragma(mpassive(IDs), PragmaRule) :-
1316 PragmaRule = pragma(_,_,_,_,RuleNb),
1317 chr_warning(experimental,'Experimental pragma ~w. Use with care!\n',[mpassive(IDs)]),
1318 maplist(passive(RuleNb),IDs).
1320 check_pragma(Pragma, PragmaRule) :-
1321 Pragma = already_in_heads,
1323 chr_warning(unsupported_pragma(Pragma,PragmaRule),'Termination and correctness may be affected.\n',[]).
1325 check_pragma(Pragma, PragmaRule) :-
1326 Pragma = already_in_head(_),
1328 chr_warning(unsupported_pragma(Pragma,PragmaRule),'Termination and correctness may be affected.\n',[]).
1330 check_pragma(Pragma, PragmaRule) :-
1331 Pragma = no_history,
1333 chr_warning(experimental,'Experimental pragma no_history. Use with care!\n',[]),
1334 PragmaRule = pragma(_,_,_,_,N),
1337 check_pragma(Pragma, PragmaRule) :-
1338 Pragma = history(HistoryName,IDs),
1340 PragmaRule = pragma(_,ids(IDs1,IDs2),_,_,RuleNb),
1341 chr_warning(experimental,'Experimental pragma ~w. Use with care!\n',[Pragma]),
1343 chr_error(syntax(Pragma),'Pragma history only implemented for propagation rules.\n',[])
1344 ; \+ atom(HistoryName) ->
1345 chr_error(syntax(Pragma),'Illegal argument for pragma history: ~w is not an atom (rule number ~w).\n',[HistoryName,RuleNb])
1347 chr_error(syntax(Pragma),'Illegal argument for pragma history: ~w is not a set (rule number ~w).\n',[IDs,RuleNb])
1348 ; check_history_pragma_ids(IDs,IDs1,IDs2) ->
1349 history(RuleNb,HistoryName,IDs)
1351 chr_error(syntax(Pragma),'Invalid identifier(s) in pragma ~w of rule number ~w.\n',[Pragma,RuleNb])
1353 check_pragma(Pragma,PragmaRule) :-
1354 Pragma = line_number(LineNumber),
1356 PragmaRule = pragma(_,_,_,_,RuleNb),
1357 line_number(RuleNb,LineNumber).
1359 check_history_pragma_ids([], _, _).
1360 check_history_pragma_ids([ID|IDs],IDs1,IDs2) :-
1361 ( memberchk_eq(ID,IDs2) ; memberchk_eq(ID,IDs1) ),
1362 check_history_pragma_ids(IDs,IDs1,IDs2).
1364 check_pragma(Pragma,PragmaRule) :-
1365 chr_error(syntax(Pragma),'Unknown pragma ~w in ~@.\n', [Pragma,format_rule(PragmaRule)]).
1367 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1368 %% no_history(+RuleNb) is det.
1369 :- chr_constraint no_history/1.
1370 :- chr_option(mode,no_history(+)).
1371 :- chr_option(type_declaration,no_history(int)).
1373 %% has_no_history(+RuleNb) is semidet.
1374 :- chr_constraint has_no_history/1.
1375 :- chr_option(mode,has_no_history(+)).
1376 :- chr_option(type_declaration,has_no_history(int)).
1378 no_history(RuleNb) \ has_no_history(RuleNb) <=> true.
1379 has_no_history(_) <=> fail.
1381 :- chr_constraint history/3.
1382 :- chr_option(mode,history(+,+,+)).
1383 :- chr_option(type_declaration,history(any,any,list)).
1385 :- chr_constraint named_history/3.
1387 history(RuleNb,_,_), history(RuleNb,_,_) ==>
1388 chr_error(syntax,'Only one pragma history allowed per rule (rule number ~w)\n',[RuleNb]). %'
1390 history(RuleNb1,Name,IDs1), history(RuleNb2,Name,IDs2) ==>
1391 length(IDs1,L1), length(IDs2,L2),
1393 chr_error(syntax,'The history named ~w does not always range over an equal amount of occurrences.\n',[Name])
1395 test_named_history_id_pairs(RuleNb1,IDs1,RuleNb2,IDs2)
1398 test_named_history_id_pairs(_, [], _, []).
1399 test_named_history_id_pairs(RuleNb1, [ID1|IDs1], RuleNb2, [ID2|IDs2]) :-
1400 test_named_history_id_pair(RuleNb1,ID1,RuleNb2,ID2),
1401 test_named_history_id_pairs(RuleNb1,IDs1,RuleNb2,IDs2).
1403 :- chr_constraint test_named_history_id_pair/4.
1404 :- chr_option(mode,test_named_history_id_pair(+,+,+,+)).
1406 occurrence(C,_,RuleNb1,ID1,_), occurrence(C,_,RuleNb2,ID2,_)
1407 \ test_named_history_id_pair(RuleNb1,ID1,RuleNb2,ID2) <=> true.
1408 test_named_history_id_pair(RuleNb1,ID1,RuleNb2,ID2) <=>
1409 chr_error(syntax,'Occurrences of shared history in rules number ~w and ~w do not correspond\n', [RuleNb2,RuleNb1]).
1411 history(RuleNb,Name,IDs) \ named_history(RuleNb,QName,QIDs) <=> QName = Name, QIDs = IDs.
1412 named_history(_,_,_) <=> fail.
1414 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1417 format_rule(PragmaRule) :-
1418 PragmaRule = pragma(_,_,_,MaybeName,RuleNumber),
1419 ( MaybeName = yes(Name) ->
1420 write('rule '), write(Name)
1422 write('rule number '), write(RuleNumber)
1424 get_line_number(RuleNumber,LineNumber),
1429 check_rule_indexing(PragmaRule) :-
1430 PragmaRule = pragma(Rule,_,_,_,_),
1431 Rule = rule(H1,H2,G,_),
1432 term_variables(H1-H2,HeadVars),
1433 remove_anti_monotonic_guards(G,HeadVars,NG),
1434 check_indexing(H1,NG-H2),
1435 check_indexing(H2,NG-H1),
1437 ( chr_pp_flag(term_indexing,on) ->
1438 term_variables(NG,GuardVariables),
1439 append(H1,H2,Heads),
1440 check_specs_indexing(Heads,GuardVariables,Specs)
1445 :- chr_constraint indexing_spec/2.
1446 :- chr_option(mode,indexing_spec(+,+)).
1448 :- chr_constraint get_indexing_spec/2.
1449 :- chr_option(mode,get_indexing_spec(+,-)).
1452 indexing_spec(FA,Spec) \ get_indexing_spec(FA,R) <=> R = Spec.
1453 get_indexing_spec(_,Spec) <=> Spec = [].
1455 indexing_spec(FA,Specs1), indexing_spec(FA,Specs2)
1457 append(Specs1,Specs2,Specs),
1458 indexing_spec(FA,Specs).
1460 remove_anti_monotonic_guards(G,Vars,NG) :-
1462 remove_anti_monotonic_guard_list(GL,Vars,NGL),
1465 remove_anti_monotonic_guard_list([],_,[]).
1466 remove_anti_monotonic_guard_list([G|Gs],Vars,NGs) :-
1467 ( G = var(X), memberchk_eq(X,Vars) ->
1469 % TODO: this is not correct
1470 % ; G = functor(Term,Functor,Arity), % isotonic
1471 % \+ memberchk_eq(Functor,Vars), \+ memberchk_eq(Arity,Vars) ->
1476 remove_anti_monotonic_guard_list(Gs,Vars,RGs).
1478 check_indexing([],_).
1479 check_indexing([Head|Heads],Other) :-
1482 term_variables(Heads-Other,OtherVars),
1483 check_indexing(Args,1,F/A,OtherVars),
1484 check_indexing(Heads,[Head|Other]).
1486 check_indexing([],_,_,_).
1487 check_indexing([Arg|Args],I,FA,OtherVars) :-
1488 ( is_indexed_argument(FA,I) ->
1491 indexed_argument(FA,I)
1493 term_variables(Args,ArgsVars),
1494 append(ArgsVars,OtherVars,RestVars),
1495 ( memberchk_eq(Arg,RestVars) ->
1496 indexed_argument(FA,I)
1502 term_variables(Arg,NVars),
1503 append(NVars,OtherVars,NOtherVars),
1504 check_indexing(Args,J,FA,NOtherVars).
1506 check_specs_indexing([],_,[]).
1507 check_specs_indexing([Head|Heads],Variables,Specs) :-
1508 Specs = [Spec|RSpecs],
1509 term_variables(Heads,OtherVariables,Variables),
1510 check_spec_indexing(Head,OtherVariables,Spec),
1511 term_variables(Head,NVariables,Variables),
1512 check_specs_indexing(Heads,NVariables,RSpecs).
1514 check_spec_indexing(Head,OtherVariables,Spec) :-
1516 Spec = spec(F,A,ArgSpecs),
1518 check_args_spec_indexing(Args,1,OtherVariables,ArgSpecs),
1519 indexing_spec(F/A,[ArgSpecs]).
1521 check_args_spec_indexing([],_,_,[]).
1522 check_args_spec_indexing([Arg|Args],I,OtherVariables,ArgSpecs) :-
1523 term_variables(Args,Variables,OtherVariables),
1524 ( check_arg_spec_indexing(Arg,I,Variables,ArgSpec) ->
1525 ArgSpecs = [ArgSpec|RArgSpecs]
1527 ArgSpecs = RArgSpecs
1530 term_variables(Arg,NOtherVariables,OtherVariables),
1531 check_args_spec_indexing(Args,J,NOtherVariables,RArgSpecs).
1533 check_arg_spec_indexing(Arg,I,Variables,ArgSpec) :-
1535 memberchk_eq(Arg,Variables),
1536 ArgSpec = specinfo(I,any,[])
1539 ArgSpec = specinfo(I,F/A,[ArgSpecs]),
1541 check_args_spec_indexing(Args,1,Variables,ArgSpecs)
1544 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1546 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1549 add_occurrences([]).
1550 add_occurrences([Rule|Rules]) :-
1551 Rule = pragma(rule(H1,H2,_,_),ids(IDs1,IDs2),_,_,Nb),
1552 add_occurrences(H1,IDs1,simplification,Nb),
1553 add_occurrences(H2,IDs2,propagation,Nb),
1554 add_occurrences(Rules).
1556 add_occurrences([],[],_,_).
1557 add_occurrences([H|Hs],[ID|IDs],Type,RuleNb) :-
1560 new_occurrence(FA,RuleNb,ID,Type),
1561 add_occurrences(Hs,IDs,Type,RuleNb).
1563 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1565 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1566 % Observation Analysis
1576 :- chr_constraint observation_analysis/1.
1577 :- chr_option(mode, observation_analysis(+)).
1579 observation_analysis(Cs), rule(RuleNb,PragmaRule) # Id ==>
1580 PragmaRule = pragma(rule(_,_,Guard,Body),_,_,_,_),
1581 ( chr_pp_flag(store_in_guards, on) ->
1582 observation_analysis(RuleNb, Guard, guard, Cs)
1586 observation_analysis(RuleNb, Body, body, Cs)
1589 observation_analysis(_) <=> true.
1591 observation_analysis(RuleNb, Term, GB, Cs) :-
1592 ( all_spawned(RuleNb,GB) ->
1595 spawns_all(RuleNb,GB)
1603 observation_analysis(RuleNb,T1,GB,Cs),
1604 observation_analysis(RuleNb,T2,GB,Cs)
1606 observation_analysis(RuleNb,T1,GB,Cs),
1607 observation_analysis(RuleNb,T2,GB,Cs)
1608 ; Term = (T1->T2) ->
1609 observation_analysis(RuleNb,T1,GB,Cs),
1610 observation_analysis(RuleNb,T2,GB,Cs)
1612 observation_analysis(RuleNb,T,GB,Cs)
1613 ; functor(Term,F,A), memberchk(F/A,Cs) ->
1614 spawns(RuleNb,GB,F/A)
1616 spawns_all_triggers(RuleNb,GB)
1617 ; Term = (_ is _) ->
1618 spawns_all_triggers(RuleNb,GB)
1619 ; builtin_binds_b(Term,Vars) ->
1623 spawns_all_triggers(RuleNb,GB)
1626 spawns_all(RuleNb,GB)
1629 :- chr_constraint spawns/3.
1630 :- chr_option(mode, spawns(+,+,+)).
1631 :- chr_type spawns_type ---> guard ; body.
1632 :- chr_option(type_declaration,spawns(any,spawns_type,any)).
1634 :- chr_constraint spawns_all/2, spawns_all_triggers/2.
1635 :- chr_option(mode, spawns_all(+,+)).
1636 :- chr_option(type_declaration,spawns_all(any,spawns_type)).
1637 :- chr_option(mode, spawns_all_triggers(+,+)).
1638 :- chr_option(type_declaration,spawns_all_triggers(any,spawns_type)).
1640 spawns_all(RuleNb,GB) \ spawns_all(RuleNb,GB) <=> true.
1641 spawns_all(RuleNb,guard) \ spawns_all(RuleNb,body) <=> true.
1642 spawns_all_triggers(RuleNb,GB) \ spawns_all_triggers(RuleNb,GB) <=> true.
1643 spawns_all_triggers(RuleNb,guard) \ spawns_all_triggers(RuleNb,body) <=> true.
1644 spawns(RuleNb,GB,C) \ spawns(RuleNb,GB,C) <=> true.
1645 spawns(RuleNb,guard,C) \ spawns(RuleNb,body,C) <=> true.
1647 spawns_all(RuleNb,GB) \ spawns(RuleNb,GB,_) <=> true.
1648 spawns_all(RuleNb,guard) \ spawns(RuleNb,body,_) <=> true.
1649 spawns_all(RuleNb,GB) \ spawns_all_triggers(RuleNb,GB) <=> true.
1650 spawns_all(RuleNb,guard) \ spawns_all_triggers(RuleNb,body) <=> true.
1652 spawns_all_triggers(RuleNb,GB) \ spawns(RuleNb,GB,C) <=> may_trigger(C) | true.
1653 spawns_all_triggers(RuleNb,guard) \ spawns(RuleNb,body,C) <=> may_trigger(C) | true.
1655 spawns_all(RuleNb2,_), occurrence(C1,_,RuleNb2,O,_)#Id
1657 spawns(RuleNb1,GB,C1)
1659 \+ is_passive(RuleNb2,O)
1661 spawns_all(RuleNb1,GB)
1665 occurrence(C1,_,RuleNb2,O,_)#Id, spawns_all(RuleNb2,_)
1667 \+(\+ spawns_all_triggers_implies_spawns_all), % in the hope it schedules this guard early...
1668 \+ is_passive(RuleNb2,O), may_trigger(C1)
1670 spawns_all_triggers_implies_spawns_all
1674 :- chr_constraint spawns_all_triggers_implies_spawns_all/0.
1675 spawns_all_triggers_implies_spawns_all, spawns_all_triggers_implies_spawns_all <=> fail.
1676 spawns_all_triggers_implies_spawns_all \
1677 spawns_all_triggers(RuleNb,GB) <=> spawns_all(RuleNb,GB).
1679 spawns_all_triggers(RuleNb2,_), occurrence(C1,_,RuleNb2,O,_)#Id
1681 spawns(RuleNb1,GB,C1)
1684 \+ is_passive(RuleNb2,O)
1686 spawns_all_triggers(RuleNb1,GB)
1690 spawns_all_triggers(RuleNb2,_), occurrence(C1,_,RuleNb2,O,_)#Id,
1691 spawns(RuleNb1,GB,C1)
1694 \+ is_passive(RuleNb2,O)
1696 spawns_all_triggers(RuleNb1,GB)
1700 % a bit dangerous this rule: could start propagating too much too soon?
1701 spawns(RuleNb2,_,C2), occurrence(C1,_,RuleNb2,O,_)#Id,
1702 spawns(RuleNb1,GB,C1)
1704 RuleNb1 \== RuleNb2, C1 \== C2,
1705 \+ is_passive(RuleNb2,O)
1707 spawns(RuleNb1,GB,C2)
1711 spawns(RuleNb2,_,C2), occurrence(C1,_,RuleNb2,O,_)#Id,
1712 spawns_all_triggers(RuleNb1,GB)
1714 \+ is_passive(RuleNb2,O), may_trigger(C1), \+ may_trigger(C2)
1716 spawns(RuleNb1,GB,C2)
1721 :- chr_constraint all_spawned/2.
1722 :- chr_option(mode, all_spawned(+,+)).
1723 spawns_all(RuleNb,guard) \ all_spawned(RuleNb,_) <=> true.
1724 spawns_all(RuleNb,GB) \ all_spawned(RuleNb,GB) <=> true.
1725 all_spawned(RuleNb,GB) <=> fail.
1728 % Overview of the supported queries:
1729 % is_observed(+functor/artiy, +occurrence_number, +(guard;body))
1730 % only succeeds if the occurrence is observed by the
1731 % guard resp. body (depending on the last argument) of its rule
1732 % is_observed(+functor/artiy, +occurrence_number, -)
1733 % succeeds if the occurrence is observed by either the guard or
1734 % the body of its rule
1735 % NOTE: the last argument is NOT bound by this query
1737 % do_is_observed(+functor/artiy,+rule_number,+(guard;body))
1738 % succeeds if the given constraint is observed by the given
1740 % do_is_observed(+functor/artiy,+rule_number)
1741 % succeeds if the given constraint is observed by the given
1742 % rule (either its guard or its body)
1747 ai_is_observed(C,O).
1749 is_stored_in_guard(C,RuleNb) :-
1750 chr_pp_flag(store_in_guards, on),
1751 do_is_observed(C,RuleNb,guard).
1753 :- chr_constraint is_observed/3.
1754 :- chr_option(mode, is_observed(+,+,+)).
1755 occurrence(C,O,RuleNb,_,_) \ is_observed(C,O,GB) <=> do_is_observed(C,RuleNb,GB).
1756 is_observed(_,_,_) <=> fail. % this will not happen in practice
1759 :- chr_constraint do_is_observed/3.
1760 :- chr_option(mode, do_is_observed(+,+,?)).
1761 :- chr_constraint do_is_observed/2.
1762 :- chr_option(mode, do_is_observed(+,+)).
1764 do_is_observed(C,RuleNb,GB) <=> var(GB) | do_is_observed(C,RuleNb).
1767 % a constraint C is observed if the GB of the rule it occurs in spawns all,
1768 % and some non-passive occurrence of some (possibly other) constraint
1769 % exists in a rule (could be same rule) with at least one occurrence of C
1771 spawns_all(RuleNb,GB),
1772 occurrence(_,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1774 do_is_observed(C,RuleNb,GB)
1776 \+ is_passive(RuleNb2,O)
1780 spawns_all(RuleNb,_),
1781 occurrence(_,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1783 do_is_observed(C,RuleNb)
1785 \+ is_passive(RuleNb2,O)
1790 % a constraint C is observed if the GB of the rule it occurs in spawns a
1791 % constraint C2 that occurs non-passively in a rule (possibly the same rule)
1792 % as an occurrence of C
1794 spawns(RuleNb,GB,C2),
1795 occurrence(C2,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1797 do_is_observed(C,RuleNb,GB)
1799 \+ is_passive(RuleNb2,O)
1803 spawns(RuleNb,_,C2),
1804 occurrence(C2,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1806 do_is_observed(C,RuleNb)
1808 \+ is_passive(RuleNb2,O)
1812 % (3) spawns_all_triggers
1813 % a constraint C is observed if the GB of the rule it occurs in spawns all triggers
1814 % and some non-passive occurrence of some (possibly other) constraint that may trigger
1815 % exists in a rule (could be same rule) with at least one occurrence of C
1817 spawns_all_triggers(RuleNb,GB),
1818 occurrence(C2,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1820 do_is_observed(C,RuleNb,GB)
1822 \+ is_passive(RuleNb2,O), may_trigger(C2)
1826 spawns_all_triggers(RuleNb,_),
1827 occurrence(C2,_,RuleNb2,O,_), occurrence(C,_,RuleNb2,_,_)
1829 do_is_observed(C,RuleNb)
1831 \+ is_passive(RuleNb2,O), may_trigger(C2)
1835 % (4) conservativeness
1836 do_is_observed(_,_,_) <=> chr_pp_flag(observation_analysis,off).
1837 do_is_observed(_,_) <=> chr_pp_flag(observation_analysis,off).
1840 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1842 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1845 %% Generated predicates
1846 %% attach_$CONSTRAINT
1848 %% detach_$CONSTRAINT
1851 %% attach_$CONSTRAINT
1852 generate_attach_detach_a_constraint_all([],[]).
1853 generate_attach_detach_a_constraint_all([Constraint|Constraints],Clauses) :-
1854 ( ( chr_pp_flag(debugable,on) ; is_stored(Constraint), \+ only_ground_indexed_arguments(Constraint), \+ get_store_type(Constraint,var_assoc_store(_,_)) ) ->
1855 generate_attach_a_constraint(Constraint,Clauses1),
1856 generate_detach_a_constraint(Constraint,Clauses2)
1861 generate_attach_detach_a_constraint_all(Constraints,Clauses3),
1862 append([Clauses1,Clauses2,Clauses3],Clauses).
1864 generate_attach_a_constraint(Constraint,[Clause1,Clause2]) :-
1865 generate_attach_a_constraint_nil(Constraint,Clause1),
1866 generate_attach_a_constraint_cons(Constraint,Clause2).
1868 attach_constraint_atom(FA,Vars,Susp,Atom) :-
1869 make_name('attach_',FA,Name),
1870 Atom =.. [Name,Vars,Susp].
1872 generate_attach_a_constraint_nil(FA,Clause) :-
1873 Clause = (Head :- true),
1874 attach_constraint_atom(FA,[],_,Head).
1876 generate_attach_a_constraint_cons(FA,Clause) :-
1877 Clause = (Head :- Body),
1878 attach_constraint_atom(FA,[Var|Vars],Susp,Head),
1879 attach_constraint_atom(FA,Vars,Susp,RecursiveCall),
1880 Body = ( AttachBody, Subscribe, RecursiveCall ),
1881 get_max_constraint_index(N),
1883 generate_attach_body_1(FA,Var,Susp,AttachBody)
1885 generate_attach_body_n(FA,Var,Susp,AttachBody)
1887 % SWI-Prolog specific code
1888 chr_pp_flag(solver_events,NMod),
1890 Args = [[Var|_],Susp],
1891 get_target_module(Mod),
1892 use_auxiliary_predicate(run_suspensions),
1893 Subscribe = clp_events:subscribe(Var,NMod,Mod,Mod:'$run_suspensions'([Susp]))
1898 generate_attach_body_1(FA,Var,Susp,Body) :-
1899 get_target_module(Mod),
1901 ( get_attr(Var, Mod, Susps) ->
1902 put_attr(Var, Mod, [Susp|Susps])
1904 put_attr(Var, Mod, [Susp])
1907 generate_attach_body_n(F/A,Var,Susp,Body) :-
1908 get_constraint_index(F/A,Position),
1909 get_max_constraint_index(Total),
1910 get_target_module(Mod),
1911 add_attr(Total,Susp,Position,TAttr,AddGoal,NTAttr),
1912 singleton_attr(Total,Susp,Position,NewAttr3),
1914 ( get_attr(Var,Mod,TAttr) ->
1916 put_attr(Var,Mod,NTAttr)
1918 put_attr(Var,Mod,NewAttr3)
1921 %% detach_$CONSTRAINT
1922 generate_detach_a_constraint(Constraint,[Clause1,Clause2]) :-
1923 generate_detach_a_constraint_nil(Constraint,Clause1),
1924 generate_detach_a_constraint_cons(Constraint,Clause2).
1926 detach_constraint_atom(FA,Vars,Susp,Atom) :-
1927 make_name('detach_',FA,Name),
1928 Atom =.. [Name,Vars,Susp].
1930 generate_detach_a_constraint_nil(FA,Clause) :-
1931 Clause = ( Head :- true),
1932 detach_constraint_atom(FA,[],_,Head).
1934 generate_detach_a_constraint_cons(FA,Clause) :-
1935 Clause = (Head :- Body),
1936 detach_constraint_atom(FA,[Var|Vars],Susp,Head),
1937 detach_constraint_atom(FA,Vars,Susp,RecursiveCall),
1938 Body = ( DetachBody, RecursiveCall ),
1939 get_max_constraint_index(N),
1941 generate_detach_body_1(FA,Var,Susp,DetachBody)
1943 generate_detach_body_n(FA,Var,Susp,DetachBody)
1946 generate_detach_body_1(FA,Var,Susp,Body) :-
1947 get_target_module(Mod),
1949 ( get_attr(Var,Mod,Susps) ->
1950 'chr sbag_del_element'(Susps,Susp,NewSusps),
1954 put_attr(Var,Mod,NewSusps)
1960 generate_detach_body_n(F/A,Var,Susp,Body) :-
1961 get_constraint_index(F/A,Position),
1962 get_max_constraint_index(Total),
1963 rem_attr(Total,Var,Susp,Position,TAttr,RemGoal),
1964 get_target_module(Mod),
1966 ( get_attr(Var,Mod,TAttr) ->
1972 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1973 %-------------------------------------------------------------------------------
1974 %% generate_indexed_variables_body(+ConstraintSymbol,+ArgList,-Body,-VarList) is det.
1975 :- chr_constraint generate_indexed_variables_body/4.
1976 :- chr_option(mode,generate_indexed_variables_body(+,?,+,?)).
1977 :- chr_option(type_declaration,generate_indexed_variables_body(constraint,any,any,any)).
1978 %-------------------------------------------------------------------------------
1979 constraint_mode(F/A,ArgModes) \ generate_indexed_variables_body(F/A,Args,Body,Vars) <=>
1980 get_indexing_spec(F/A,Specs),
1981 ( chr_pp_flag(term_indexing,on) ->
1982 spectermvars(Specs,Args,F,A,Body,Vars)
1984 get_constraint_type_det(F/A,ArgTypes),
1985 create_indexed_variables_body(Args,ArgModes,ArgTypes,Vars,1,F/A,MaybeBody,N),
1986 ( MaybeBody == empty ->
1993 Term =.. [term|Args]
1995 Body = term_variables(Term,Vars)
2000 generate_indexed_variables_body(FA,_,_,_) <=>
2001 chr_error(internal,'generate_indexed_variables_body: missing mode info for ~w.\n',[FA]).
2002 %===============================================================================
2004 create_indexed_variables_body([],[],[],_,_,_,empty,0).
2005 create_indexed_variables_body([V|Vs],[Mode|Modes],[Type|Types],Vars,I,FA,Body,N) :-
2007 create_indexed_variables_body(Vs,Modes,Types,Tail,J,FA,RBody,M),
2009 is_indexed_argument(FA,I) ->
2010 ( atomic_type(Type) ->
2021 Continuation = true, Tail = []
2023 Continuation = RBody
2027 Body = term_variables(V,Vars)
2029 Body = (term_variables(V,Vars,Tail),RBody)
2033 ; Mode == (-), is_indexed_argument(FA,I) ->
2037 Body = (Vars = [V|Tail],RBody)
2045 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2047 spectermvars(Specs,Args,F,A,Goal,Vars) :-
2048 spectermvars(Args,1,Specs,F,A,Vars,[],Goal).
2050 spectermvars([],B,_,_,A,L,L,true) :- B > A, !.
2051 spectermvars([Arg|Args],I,Specs,F,A,L,T,Goal) :-
2052 Goal = (ArgGoal,RGoal),
2053 argspecs(Specs,I,TempArgSpecs,RSpecs),
2054 merge_argspecs(TempArgSpecs,ArgSpecs),
2055 arggoal(ArgSpecs,Arg,ArgGoal,L,L1),
2057 spectermvars(Args,J,RSpecs,F,A,L1,T,RGoal).
2059 argspecs([],_,[],[]).
2060 argspecs([[]|Rest],I,ArgSpecs,RestSpecs) :-
2061 argspecs(Rest,I,ArgSpecs,RestSpecs).
2062 argspecs([[specinfo(J,Spec,Args)|Specs]|Rest],I,ArgSpecs,RestSpecs) :-
2064 ArgSpecs = [specinfo(J,Spec,Args)|RArgSpecs],
2066 RRestSpecs = RestSpecs
2068 RestSpecs = [Specs|RRestSpecs]
2071 ArgSpecs = RArgSpecs,
2072 RestSpecs = [[specinfo(J,Spec,Args)|Specs]|RRestSpecs]
2074 argspecs(Rest,I,RArgSpecs,RRestSpecs).
2076 merge_argspecs(In,Out) :-
2078 merge_argspecs_(Sorted,Out).
2080 merge_argspecs_([],[]).
2081 merge_argspecs_([X],R) :- !, R = [X].
2082 merge_argspecs_([specinfo(I,F1,A1),specinfo(I,F2,A2)|Rest],R) :-
2083 ( (F1 == any ; F2 == any) ->
2084 merge_argspecs_([specinfo(I,any,[])|Rest],R)
2087 merge_argspecs_([specinfo(I,F1,A)|Rest],R)
2089 R = [specinfo(I,F1,A1)|RR],
2090 merge_argspecs_([specinfo(I,F2,A2)|Rest],RR)
2093 arggoal(List,Arg,Goal,L,T) :-
2097 ; List = [specinfo(_,any,_)] ->
2098 Goal = term_variables(Arg,L,T)
2106 arggoal_cases(List,Arg,L,T,Cases)
2109 arggoal_cases([],_,L,T,L=T).
2110 arggoal_cases([specinfo(_,FA,ArgSpecs)|Rest],Arg,L,T,Cases) :-
2113 ; ArgSpecs == [[]] ->
2116 Cases = (Case ; RCases),
2119 Case = (Arg = Term -> ArgsGoal),
2120 spectermvars(Args,1,ArgSpecs,F,A,L,T,ArgsGoal)
2122 arggoal_cases(Rest,Arg,L,T,RCases).
2123 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2125 generate_extra_clauses(Constraints,List) :-
2126 generate_activate_clauses(Constraints,List,Tail0),
2127 generate_remove_clauses(Constraints,Tail0,Tail1),
2128 generate_allocate_clauses(Constraints,Tail1,Tail2),
2129 generate_insert_constraint_internal_clauses(Constraints,Tail2,Tail3),
2130 generate_novel_production(Tail3,Tail4),
2131 generate_extend_history(Tail4,Tail5),
2132 generate_run_suspensions_clauses(Constraints,Tail5,Tail6),
2133 generate_empty_named_history_initialisations(Tail6,Tail7),
2136 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2137 % remove_constraint_internal/[1/3]
2139 generate_remove_clauses([],List,List).
2140 generate_remove_clauses([C|Cs],List,Tail) :-
2141 generate_remove_clause(C,List,List1),
2142 generate_remove_clauses(Cs,List1,Tail).
2144 remove_constraint_goal(Constraint,Susp,Agenda,DeleteNo,DeleteYes,Role,Goal) :-
2145 uses_state(Constraint,removed),
2146 ( chr_pp_flag(inline_insertremove,off) ->
2147 use_auxiliary_predicate(remove_constraint_internal,Constraint),
2148 Goal = ( DeleteGoal, ( Delete == yes -> DeleteYes ; DeleteNo) ),
2149 remove_constraint_atom(Constraint,Susp,Agenda,Delete,DeleteGoal)
2151 delay_phase_end(validate_store_type_assumptions,
2152 generate_remove_body(Constraint,Susp,Agenda,DeleteNo,DeleteYes,Role,Goal)
2156 remove_constraint_atom(Constraint,Susp,Agenda,Delete,Goal) :-
2157 make_name('$remove_constraint_internal_',Constraint,Name),
2158 ( chr_pp_flag(debugable,off), ( only_ground_indexed_arguments(Constraint) ; get_store_type(Constraint,var_assoc_store(_,_)) ) ->
2159 Goal =.. [Name, Susp,Delete]
2161 Goal =.. [Name,Susp,Agenda,Delete]
2164 generate_remove_clause(Constraint,List,Tail) :-
2165 ( is_used_auxiliary_predicate(remove_constraint_internal,Constraint) ->
2166 List = [RemoveClause|Tail],
2167 RemoveClause = (Head :- RemoveBody),
2168 remove_constraint_atom(Constraint,Susp,Agenda,Delete,Head),
2169 generate_remove_body(Constraint,Susp,Agenda,Delete = no,Delete = yes,active,RemoveBody)
2174 generate_remove_body(Constraint,Susp,Agenda,DeleteNo,DeleteYes,Role,RemoveBody) :-
2175 ( chr_pp_flag(debugable,off), ( only_ground_indexed_arguments(Constraint) ; get_store_type(Constraint,var_assoc_store(_,_))) ->
2177 get_update_suspension_field(Constraint,Susp,state,State,removed,GetState,GetStateValue0,UpdateState),
2178 if_used_state(Constraint,not_stored_yet,GetStateValue0,true,GetStateValue),
2179 if_used_state(Constraint,not_stored_yet,(State == not_stored_yet -> DeleteNo ; DeleteYes),DeleteYes,MaybeDelete)
2180 ; Role == partner ->
2181 get_update_suspension_field(Constraint,Susp,state,State,removed,GetState,_,UpdateState),
2182 GetStateValue = true,
2183 MaybeDelete = DeleteYes
2193 static_suspension_term(Constraint,Susp2),
2194 get_static_suspension_term_field(arguments,Constraint,Susp2,Args),
2195 generate_indexed_variables_body(Constraint,Args,IndexedVariablesBody,Agenda),
2196 ( chr_pp_flag(debugable,on) ->
2197 Constraint = Functor / _,
2198 get_static_suspension_term_field(functor,Constraint,Susp2,Functor)
2203 get_update_static_suspension_field(Constraint,Susp,Susp2,state,State,removed,GetStateValue0,UpdateState),
2204 if_used_state(Constraint,not_stored_yet,GetStateValue0,true,GetStateValue),
2205 if_used_state(Constraint,not_stored_yet,(State == not_stored_yet -> Agenda = [], DeleteNo ; IndexedVariablesBody, DeleteYes),(IndexedVariablesBody,DeleteYes),MaybeDelete)
2206 ; Role == partner ->
2207 get_update_static_suspension_field(Constraint,Susp,Susp2,state,State,removed,_,UpdateState),
2208 GetStateValue = true,
2209 MaybeDelete = (IndexedVariablesBody, DeleteYes)
2220 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2221 % activate_constraint/4
2223 generate_activate_clauses([],List,List).
2224 generate_activate_clauses([C|Cs],List,Tail) :-
2225 generate_activate_clause(C,List,List1),
2226 generate_activate_clauses(Cs,List1,Tail).
2228 activate_constraint_goal(Constraint,StoreAction,Vars,Susp,Generation,Goal) :-
2229 ( chr_pp_flag(inline_insertremove,off) ->
2230 use_auxiliary_predicate(activate_constraint,Constraint),
2231 Goal = ( ActivateGoal , (Store == yes -> StoreAction ; true) ),
2232 activate_constraint_atom(Constraint,Store,Vars,Susp,Generation,ActivateGoal)
2234 delay_phase_end(validate_store_type_assumptions,
2235 activate_constraint_body(Constraint,StoreAction,true,Vars,Susp,Generation,Goal)
2239 activate_constraint_atom(Constraint,Store,Vars,Susp,Generation,Goal) :-
2240 make_name('$activate_constraint_',Constraint,Name),
2241 ( chr_pp_flag(debugable,off), only_ground_indexed_arguments(Constraint) ->
2242 Goal =.. [Name,Store, Susp]
2243 ; chr_pp_flag(debugable,off), may_trigger(Constraint), get_store_type(Constraint,var_assoc_store(_,_)) ->
2244 Goal =.. [Name,Store, Susp, Generation]
2245 ; chr_pp_flag(debugable,off), may_trigger(Constraint), get_store_type(Constraint,var_assoc_store(_,_)) ->
2246 Goal =.. [Name,Store, Vars, Susp, Generation]
2248 Goal =.. [Name,Store, Vars, Susp]
2251 generate_activate_clause(Constraint,List,Tail) :-
2252 ( is_used_auxiliary_predicate(activate_constraint,Constraint) ->
2253 List = [Clause|Tail],
2254 Clause = (Head :- Body),
2255 activate_constraint_atom(Constraint,Store,Vars,Susp,Generation,Head),
2256 activate_constraint_body(Constraint,Store = yes, Store = no,Vars,Susp,Generation,Body)
2261 activate_constraint_body(Constraint,StoreYes,StoreNo,Vars,Susp,Generation,Body) :-
2262 ( chr_pp_flag(debugable,off), may_trigger(Constraint), uses_field(Constraint,generation) ->
2263 get_update_suspension_field(Constraint,Susp,generation,Gen,Generation,GetGeneration,GetGenerationValue,UpdateGeneration),
2264 GenerationHandling = (GetGeneration, GetGenerationValue, Generation is Gen+1, UpdateGeneration)
2266 GenerationHandling = true
2268 get_update_suspension_field(Constraint,Susp,state,State,active,GetState,GetStateValue0,UpdateState),
2269 if_used_state(Constraint,not_stored_yet,GetStateValue0,true,GetStateValue),
2270 ( chr_pp_flag(debugable,off), ( only_ground_indexed_arguments(Constraint) ; get_store_type(Constraint,var_assoc_store(_,_))) ->
2271 if_used_state(Constraint,not_stored_yet,( State == not_stored_yet -> StoreYes ; StoreNo ),StoreNo,StoreVarsGoal)
2273 get_dynamic_suspension_term_field(arguments,Constraint,Susp,Arguments,ArgumentsGoal),
2274 generate_indexed_variables_body(Constraint,Arguments,IndexedVariablesBody,Vars),
2275 ( chr_pp_flag(guard_locks,off) ->
2278 NoneLocked = 'chr none_locked'( Vars)
2280 if_used_state(Constraint,not_stored_yet,
2281 ( State == not_stored_yet ->
2283 IndexedVariablesBody,
2290 % (Vars = [],StoreNo),StoreVarsGoal)
2291 StoreNo,StoreVarsGoal)
2301 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2302 % allocate_constraint/4
2304 generate_allocate_clauses([],List,List).
2305 generate_allocate_clauses([C|Cs],List,Tail) :-
2306 generate_allocate_clause(C,List,List1),
2307 generate_allocate_clauses(Cs,List1,Tail).
2309 allocate_constraint_goal(Constraint,Susp,Args,Goal) :-
2310 uses_state(Constraint,not_stored_yet),
2311 ( chr_pp_flag(inline_insertremove,off) ->
2312 use_auxiliary_predicate(allocate_constraint,Constraint),
2313 allocate_constraint_atom(Constraint,Susp,Args,Goal)
2315 Goal = (Susp = Suspension, Goal0),
2316 delay_phase_end(validate_store_type_assumptions,
2317 allocate_constraint_body(Constraint,Suspension,Args,Goal0)
2321 allocate_constraint_atom(Constraint, Susp, Args,Goal) :-
2322 make_name('$allocate_constraint_',Constraint,Name),
2323 Goal =.. [Name,Susp|Args].
2325 generate_allocate_clause(Constraint,List,Tail) :-
2326 ( is_used_auxiliary_predicate(allocate_constraint,Constraint) ->
2327 List = [Clause|Tail],
2328 Clause = (Head :- Body),
2331 allocate_constraint_atom(Constraint,Susp,Args,Head),
2332 allocate_constraint_body(Constraint,Susp,Args,Body)
2337 allocate_constraint_body(Constraint,Susp,Args,Body) :-
2338 static_suspension_term(Constraint,Suspension),
2339 get_static_suspension_term_field(arguments,Constraint,Suspension,Args),
2340 ( chr_pp_flag(debugable,on) ->
2341 Constraint = Functor / _,
2342 get_static_suspension_term_field(functor,Constraint,Suspension,Functor)
2346 ( chr_pp_flag(debugable,on) ->
2347 ( may_trigger(Constraint) ->
2348 append(Args,[Susp],VarsSusp),
2349 build_head(F,A,[0],VarsSusp, ContinuationGoal),
2350 get_target_module(Mod),
2351 Continuation = Mod : ContinuationGoal
2355 Init = (Susp = Suspension),
2356 create_static_suspension_field(Constraint,Suspension,continuation,Continuation,CreateContinuation),
2357 create_static_suspension_field(Constraint,Suspension,generation,0,CreateGeneration)
2358 ; may_trigger(Constraint), uses_field(Constraint,generation) ->
2359 create_static_suspension_field(Constraint,Suspension,generation,0,CreateGeneration),
2360 Susp = Suspension, Init = true, CreateContinuation = true
2362 CreateGeneration = true, Susp = Suspension, Init = true, CreateContinuation = true
2364 ( uses_history(Constraint) ->
2365 create_static_suspension_field(Constraint,Suspension,history,t,CreateHistory)
2367 CreateHistory = true
2369 create_static_suspension_field(Constraint,Suspension,state,not_stored_yet,CreateState),
2370 ( has_suspension_field(Constraint,id) ->
2371 get_static_suspension_term_field(id,Constraint,Suspension,Id),
2386 gen_id(Id,'chr gen_id'(Id)).
2387 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2388 % insert_constraint_internal
2390 generate_insert_constraint_internal_clauses([],List,List).
2391 generate_insert_constraint_internal_clauses([C|Cs],List,Tail) :-
2392 generate_insert_constraint_internal_clause(C,List,List1),
2393 generate_insert_constraint_internal_clauses(Cs,List1,Tail).
2395 insert_constraint_internal_constraint_goal(Constraint, Vars, Suspension, Continuation, Args,Goal) :-
2396 ( chr_pp_flag(inline_insertremove,off) ->
2397 use_auxiliary_predicate(remove_constraint_internal,Constraint),
2398 insert_constraint_internal_constraint_atom(Constraint,Vars,Suspension,Continuation,Args,Goal)
2400 delay_phase_end(validate_store_type_assumptions,
2401 generate_insert_constraint_internal_body(Constraint,Suspension,Continuation,Args,Vars,Goal)
2406 insert_constraint_internal_constraint_atom(Constraint,Vars,Self,Closure,Args,Goal) :-
2407 insert_constraint_internal_constraint_name(Constraint,Name),
2408 ( chr_pp_flag(debugable,on) ->
2409 Goal =.. [Name, Vars, Self, Closure | Args]
2410 ; ( only_ground_indexed_arguments(Constraint) ; get_store_type(Constraint,var_assoc_store(_,_)))->
2411 Goal =.. [Name,Self | Args]
2413 Goal =.. [Name,Vars, Self | Args]
2416 insert_constraint_internal_constraint_name(Constraint,Name) :-
2417 make_name('$insert_constraint_internal_',Constraint,Name).
2419 generate_insert_constraint_internal_clause(Constraint,List,Tail) :-
2420 ( is_used_auxiliary_predicate(insert_constraint_internal,Constraint) ->
2421 List = [Clause|Tail],
2422 Clause = (Head :- Body),
2425 insert_constraint_internal_constraint_atom(Constraint, Vars, Suspension, Continuation,Args,Head),
2426 generate_insert_constraint_internal_body(Constraint,Suspension,Continuation,Args,Vars,Body)
2432 generate_insert_constraint_internal_body(Constraint,Susp,Continuation,Args,Vars,Body) :-
2433 static_suspension_term(Constraint,Suspension),
2434 create_static_suspension_field(Constraint,Suspension,state,active,CreateState),
2435 ( chr_pp_flag(debugable,on) ->
2436 get_static_suspension_term_field(continuation,Constraint,Suspension,Continuation),
2437 create_static_suspension_field(Constraint,Suspension,generation,0,CreateGeneration)
2438 ; may_trigger(Constraint), uses_field(Constraint,generation) ->
2439 create_static_suspension_field(Constraint,Suspension,generation,0,CreateGeneration)
2441 CreateGeneration = true
2443 ( chr_pp_flag(debugable,on) ->
2444 Constraint = Functor / _,
2445 get_static_suspension_term_field(functor,Constraint,Suspension,Functor)
2449 ( uses_history(Constraint) ->
2450 create_static_suspension_field(Constraint,Suspension,history,t,CreateHistory)
2452 CreateHistory = true
2454 get_static_suspension_term_field(arguments,Constraint,Suspension,Args),
2455 List = [Clause|Tail],
2456 ( chr_pp_flag(debugable,off), ( only_ground_indexed_arguments(Constraint) ; get_store_type(Constraint,var_assoc_store(_,_)))->
2457 suspension_term_base_fields(Constraint,BaseFields),
2458 ( has_suspension_field(Constraint,id) ->
2459 get_static_suspension_term_field(id,Constraint,Suspension,Id),
2473 ( has_suspension_field(Constraint,id) ->
2474 get_static_suspension_term_field(id,Constraint,Suspension,Id),
2479 generate_indexed_variables_body(Constraint,Args,IndexedVariablesBody,Vars),
2480 ( chr_pp_flag(guard_locks,off) ->
2483 NoneLocked = 'chr none_locked'( Vars)
2488 IndexedVariablesBody,
2497 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2498 % novel_production/2
2500 generate_novel_production(List,Tail) :-
2501 ( is_used_auxiliary_predicate(novel_production) ->
2502 List = [Clause|Tail],
2505 '$novel_production'( Self, Tuple) :-
2506 % arg( 3, Self, Ref), % ARGXXX
2507 % 'chr get_mutable'( History, Ref),
2508 arg( 3, Self, History), % ARGXXX
2509 ( hprolog:get_ds( Tuple, History, _) ->
2519 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2522 generate_extend_history(List,Tail) :-
2523 ( is_used_auxiliary_predicate(extend_history) ->
2524 List = [Clause|Tail],
2527 '$extend_history'( Self, Tuple) :-
2528 % arg( 3, Self, Ref), % ARGXXX
2529 % 'chr get_mutable'( History, Ref),
2530 arg( 3, Self, History), % ARGXXX
2531 hprolog:put_ds( Tuple, History, x, NewHistory),
2532 setarg( 3, Self, NewHistory) % ARGXXX
2538 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2541 empty_named_history_initialisations/2,
2542 generate_empty_named_history_initialisation/1,
2543 find_empty_named_histories/0.
2545 generate_empty_named_history_initialisations(List, Tail) :-
2546 empty_named_history_initialisations(List, Tail),
2547 find_empty_named_histories.
2549 find_empty_named_histories, history(_, Name, []) ==>
2550 generate_empty_named_history_initialisation(Name).
2552 generate_empty_named_history_initialisation(Name) \
2553 generate_empty_named_history_initialisation(Name) <=> true.
2554 generate_empty_named_history_initialisation(Name) \
2555 empty_named_history_initialisations(List, Tail) # Passive
2557 empty_named_history_global_variable(Name, GlobalVariable),
2558 List = [(:- nb_setval(GlobalVariable, 0))|Rest],
2559 empty_named_history_initialisations(Rest, Tail)
2560 pragma passive(Passive).
2562 find_empty_named_histories \
2563 generate_empty_named_history_initialisation(_) # Passive <=> true
2564 pragma passive(Passive).
2566 find_empty_named_histories,
2567 empty_named_history_initialisations(List, Tail) # Passive <=> List = Tail
2568 pragma passive(Passive).
2570 find_empty_named_histories <=>
2571 chr_error(internal, 'find_empty_named_histories was not removed', []).
2574 empty_named_history_global_variable(Name, GlobalVariable) :-
2575 atom_concat('chr empty named history ', Name, GlobalVariable).
2577 empty_named_history_novel_production(Name, nb_getval(GlobalVariable, 0)) :-
2578 empty_named_history_global_variable(Name, GlobalVariable).
2580 empty_named_history_extend_history(Name, b_setval(GlobalVariable, 1)) :-
2581 empty_named_history_global_variable(Name, GlobalVariable).
2584 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2587 generate_run_suspensions_clauses([],List,List).
2588 generate_run_suspensions_clauses([C|Cs],List,Tail) :-
2589 generate_run_suspensions_clause(C,List,List1),
2590 generate_run_suspensions_clauses(Cs,List1,Tail).
2592 run_suspensions_goal(Constraint,Suspensions,Goal) :-
2593 make_name('$run_suspensions_',Constraint,Name),
2594 Goal =.. [Name,Suspensions].
2596 generate_run_suspensions_clause(Constraint,List,Tail) :-
2597 ( is_used_auxiliary_predicate(run_suspensions,Constraint) ->
2598 List = [Clause1,Clause2|Tail],
2599 run_suspensions_goal(Constraint,[],Clause1),
2600 ( chr_pp_flag(debugable,on) ->
2601 run_suspensions_goal(Constraint,[Suspension|Suspensions],Clause2Head),
2602 get_update_suspension_field(Constraint,Suspension,state,State,triggered,GetState,GetStateValue,UpdateState),
2603 get_update_suspension_field(Constraint,Suspension,state,Post,active,GetPost,GetPostValue,UpdatePost),
2604 get_update_suspension_field(Constraint,Suspension,generation,Gen,Generation,GetGeneration,GetGenerationValue,UpdateGeneration),
2605 get_dynamic_suspension_term_field(continuation,Constraint,Suspension,Continuation,GetContinuation),
2606 run_suspensions_goal(Constraint,Suspensions,Clause2Recursion),
2616 Generation is Gen+1,
2620 'chr debug_event'(wake(Suspension)),
2623 'chr debug_event'(fail(Suspension)), !,
2627 'chr debug_event'(exit(Suspension))
2629 'chr debug_event'(redo(Suspension)),
2634 ( Post==triggered ->
2635 UpdatePost % catching constraints that did not do anything
2645 run_suspensions_goal(Constraint,[Suspension|Suspensions],Clause2Head),
2646 static_suspension_term(Constraint,SuspensionTerm),
2647 get_static_suspension_term_field(arguments,Constraint,SuspensionTerm,Arguments),
2648 append(Arguments,[Suspension],VarsSusp),
2649 make_suspension_continuation_goal(Constraint,VarsSusp,Continuation),
2650 run_suspensions_goal(Constraint,Suspensions,Clause2Recursion),
2651 ( uses_field(Constraint,generation) ->
2652 get_update_static_suspension_field(Constraint,Suspension,SuspensionTerm,generation,Gen,Generation,GetGeneration,UpdateGeneration),
2653 GenerationHandling = ( GetGeneration, Generation is Gen+1, UpdateGeneration)
2655 GenerationHandling = true
2657 get_update_static_suspension_field(Constraint,Suspension,SuspensionTerm,state,State,triggered,GetState,UpdateState),
2658 get_update_static_suspension_field(Constraint,Suspension,SuspensionTerm,state,Post,active,GetPostState,UpdatePostState),
2659 if_used_state(Constraint,removed,
2662 -> ReactivateConstraint
2664 ),ReactivateConstraint,CondReactivate),
2665 ReactivateConstraint =
2671 ( Post==triggered ->
2672 UpdatePostState % catching constraints that did not do anything
2680 Suspension = SuspensionTerm,
2689 %~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
2691 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2692 generate_attach_increment(Clauses) :-
2693 get_max_constraint_index(N),
2694 ( is_used_auxiliary_predicate(attach_increment), N > 0 ->
2695 Clauses = [Clause1,Clause2],
2696 generate_attach_increment_empty(Clause1),
2698 generate_attach_increment_one(Clause2)
2700 generate_attach_increment_many(N,Clause2)
2706 generate_attach_increment_empty((attach_increment([],_) :- true)).
2708 generate_attach_increment_one(Clause) :-
2709 Head = attach_increment([Var|Vars],Susps),
2710 get_target_module(Mod),
2711 ( chr_pp_flag(guard_locks,off) ->
2714 NotLocked = 'chr not_locked'( Var)
2719 ( get_attr(Var,Mod,VarSusps) ->
2720 sort(VarSusps,SortedVarSusps),
2721 'chr merge_attributes'(Susps,SortedVarSusps,MergedSusps),
2722 put_attr(Var,Mod,MergedSusps)
2724 put_attr(Var,Mod,Susps)
2726 attach_increment(Vars,Susps)
2728 Clause = (Head :- Body).
2730 generate_attach_increment_many(N,Clause) :-
2731 Head = attach_increment([Var|Vars],TAttr1),
2732 % writeln(merge_attributes_1_before),
2733 merge_attributes(N,TAttr1,TAttr2,MergeGoal,Attr),
2734 % writeln(merge_attributes_1_after),
2735 get_target_module(Mod),
2736 ( chr_pp_flag(guard_locks,off) ->
2739 NotLocked = 'chr not_locked'( Var)
2744 ( get_attr(Var,Mod,TAttr2) ->
2746 put_attr(Var,Mod,Attr)
2748 put_attr(Var,Mod,TAttr1)
2750 attach_increment(Vars,TAttr1)
2752 Clause = (Head :- Body).
2755 generate_attr_unify_hook(Clauses) :-
2756 get_max_constraint_index(N),
2761 generate_attr_unify_hook_one(Clauses)
2763 generate_attr_unify_hook_many(N,Clauses)
2767 generate_attr_unify_hook_one([Clause]) :-
2768 Head = attr_unify_hook(Susps,Other),
2769 get_target_module(Mod),
2770 get_indexed_constraint(1,C),
2771 ( get_store_type(C,ST),
2772 ( ST = default ; ST = multi_store(STs), memberchk(default,STs) ) ->
2773 make_run_suspensions(NewSusps,SortedSusps,WakeNewSusps),
2774 make_run_suspensions(SortedSusps,SortedSusps,WakeSusps),
2775 ( atomic_types_suspended_constraint(C) ->
2777 SortedSusps = Susps,
2779 SortedOtherSusps = OtherSusps,
2780 MergeGoal = (append(Susps,OtherSusps,List), sort(List,NewSusps)),
2783 SortGoal1 = sort(Susps, SortedSusps),
2784 SortGoal2 = sort(OtherSusps,SortedOtherSusps),
2785 MergeGoal = 'chr merge_attributes'(SortedSusps,SortedOtherSusps,NewSusps),
2786 use_auxiliary_predicate(attach_increment),
2788 ( compound(Other) ->
2789 term_variables(Other,OtherVars),
2790 attach_increment(OtherVars, SortedSusps)
2799 ( get_attr(Other,Mod,OtherSusps) ->
2802 put_attr(Other,Mod,NewSusps),
2805 put_attr(Other,Mod,SortedSusps),
2813 Clause = (Head :- Body)
2814 ; get_store_type(C,var_assoc_store(VarIndex,KeyIndex)) ->
2815 make_run_suspensions(List,List,WakeNewSusps),
2816 MergeGoal = (merge_into_assoc_store(Susps,OtherSusps,List)),
2818 ( get_attr(Other,Mod,OtherSusps) ->
2822 put_attr(Other,Mod,Susps)
2824 Clause = (Head :- Body)
2828 generate_attr_unify_hook_many(N,[Clause]) :-
2829 chr_pp_flag(dynattr,off), !,
2830 Head = attr_unify_hook(Attr,Other),
2831 get_target_module(Mod),
2832 make_attr(N,Mask,SuspsList,Attr),
2833 bagof(Sort,A ^ B ^ ( member(A,SuspsList) , Sort = sort(A,B) ) , SortGoalList),
2834 list2conj(SortGoalList,SortGoals),
2835 bagof(B, A ^ member(sort(A,B),SortGoalList), SortedSuspsList),
2836 merge_attributes2(N,Mask,SortedSuspsList,TOtherAttr,MergeGoal,MergedAttr),
2837 get_all_suspensions2(N,MergedAttr,MergedSuspsList),
2838 make_attr(N,Mask,SortedSuspsList,SortedAttr),
2839 make_run_suspensions_loop(MergedSuspsList,SortedSuspsList,WakeMergedSusps),
2840 make_run_suspensions_loop(SortedSuspsList,SortedSuspsList,WakeSortedSusps),
2841 ( forall((between(1,N,Index), get_indexed_constraint(Index,Constraint)),atomic_types_suspended_constraint(Constraint)) ->
2844 use_auxiliary_predicate(attach_increment),
2846 ( compound(Other) ->
2847 term_variables(Other,OtherVars),
2848 attach_increment(OtherVars,SortedAttr)
2857 ( get_attr(Other,Mod,TOtherAttr) ->
2859 put_attr(Other,Mod,MergedAttr),
2862 put_attr(Other,Mod,SortedAttr),
2870 Clause = (Head :- Body).
2873 generate_attr_unify_hook_many(N,Clauses) :-
2874 Head = attr_unify_hook(Attr,Other),
2875 get_target_module(Mod),
2876 normalize_attr(Attr,NormalGoal,NormalAttr),
2877 normalize_attr(OtherAttr,NormalOtherGoal,NormalOtherAttr),
2878 merge_attributes(N,NormalAttr,NormalOtherAttr,MergeGoal,MergedAttr),
2879 make_run_suspensions(N),
2880 ( forall((between(1,N,Index), get_indexed_constraint(Index,Constraint)),atomic_types_suspended_constraint(Constraint)) ->
2883 use_auxiliary_predicate(attach_increment),
2885 ( compound(Other) ->
2886 term_variables(Other,OtherVars),
2887 attach_increment(OtherVars,NormalAttr)
2896 ( get_attr(Other,Mod,OtherAttr) ->
2899 put_attr(Other,Mod,MergedAttr),
2900 '$dispatch_run_suspensions'(MergedAttr)
2902 put_attr(Other,Mod,NormalAttr),
2903 '$dispatch_run_suspensions'(NormalAttr)
2907 '$dispatch_run_suspensions'(NormalAttr)
2910 Clause = (Head :- Body),
2911 Clauses = [Clause,DispatchList1,DispatchList2|Dispatchers],
2912 DispatchList1 = ('$dispatch_run_suspensions'([])),
2913 DispatchList2 = ('$dispatch_run_suspensions'([Pos-List|Rest]) :- '$dispatch_run_suspensions'(Pos,List),'$dispatch_run_suspensions'(Rest)),
2914 run_suspensions_dispatchers(N,[],Dispatchers).
2917 run_suspensions_dispatchers(N,Acc,Dispatchers) :-
2919 get_indexed_constraint(N,C),
2920 NAcc = [('$dispatch_run_suspensions'(N,List) :- Body)|Acc],
2922 run_suspensions_goal(C,List,Body)
2927 run_suspensions_dispatchers(M,NAcc,Dispatchers)
2933 make_run_suspensions(N) :-
2935 ( get_indexed_constraint(N,C),
2937 use_auxiliary_predicate(run_suspensions,C)
2942 make_run_suspensions(M)
2947 make_run_suspensions(AllSusps,OneSusps,Goal) :-
2948 make_run_suspensions(1,AllSusps,OneSusps,Goal).
2950 make_run_suspensions(Index,AllSusps,OneSusps,Goal) :-
2951 ( get_indexed_constraint(Index,C), may_trigger(C) ->
2952 use_auxiliary_predicate(run_suspensions,C),
2953 ( wakes_partially(C) ->
2954 run_suspensions_goal(C,OneSusps,Goal)
2956 run_suspensions_goal(C,AllSusps,Goal)
2962 make_run_suspensions_loop(AllSuspsList,OneSuspsList,Goal) :-
2963 make_run_suspensions_loop(AllSuspsList,OneSuspsList,1,Goal).
2965 make_run_suspensions_loop([],[],_,true).
2966 make_run_suspensions_loop([AllSusps|AllSuspsList],[OneSusps|OneSuspsList],I,(Goal,Goals)) :-
2967 make_run_suspensions(I,AllSusps,OneSusps,Goal),
2969 make_run_suspensions_loop(AllSuspsList,OneSuspsList,J,Goals).
2971 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2972 % $insert_in_store_F/A
2973 % $delete_from_store_F/A
2975 generate_insert_delete_constraints([],[]).
2976 generate_insert_delete_constraints([FA|Rest],Clauses) :-
2978 generate_insert_delete_constraint(FA,Clauses,RestClauses)
2980 Clauses = RestClauses
2982 generate_insert_delete_constraints(Rest,RestClauses).
2984 generate_insert_delete_constraint(FA,Clauses,RestClauses) :-
2985 insert_constraint_clause(FA,Clauses,RestClauses1),
2986 delete_constraint_clause(FA,RestClauses1,RestClauses).
2988 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
2991 insert_constraint_goal(FA,Susp,Vars,Goal) :-
2992 ( chr_pp_flag(inline_insertremove,off) ->
2993 use_auxiliary_predicate(insert_in_store,FA),
2994 insert_constraint_atom(FA,Susp,Goal)
2996 delay_phase_end(validate_store_type_assumptions,
2997 ( insert_constraint_body(FA,Susp,UsedVars,Goal),
2998 insert_constraint_direct_used_vars(UsedVars,Vars)
3003 insert_constraint_direct_used_vars([],_).
3004 insert_constraint_direct_used_vars([Index-Var|Rest],Vars) :-
3005 nth1(Index,Vars,Var),
3006 insert_constraint_direct_used_vars(Rest,Vars).
3008 insert_constraint_atom(FA,Susp,Call) :-
3009 make_name('$insert_in_store_',FA,Functor),
3010 Call =.. [Functor,Susp].
3012 insert_constraint_clause(C,Clauses,RestClauses) :-
3013 ( is_used_auxiliary_predicate(insert_in_store,C) ->
3014 Clauses = [Clause|RestClauses],
3015 Clause = (Head :- InsertCounterInc,VarsBody,Body),
3016 insert_constraint_atom(C,Susp,Head),
3017 insert_constraint_body(C,Susp,UsedVars,Body),
3018 insert_constraint_used_vars(UsedVars,C,Susp,VarsBody),
3019 ( chr_pp_flag(store_counter,on) ->
3020 InsertCounterInc = '$insert_counter_inc'
3022 InsertCounterInc = true
3025 Clauses = RestClauses
3028 insert_constraint_used_vars([],_,_,true).
3029 insert_constraint_used_vars([Index-Var|Rest],C,Susp,(Goal,Goals)) :-
3030 get_dynamic_suspension_term_field(argument(Index),C,Susp,Var,Goal),
3031 insert_constraint_used_vars(Rest,C,Susp,Goals).
3033 insert_constraint_body(C,Susp,UsedVars,Body) :-
3034 get_store_type(C,StoreType),
3035 insert_constraint_body(StoreType,C,Susp,UsedVars,Body).
3037 insert_constraint_body(default,C,Susp,[],Body) :-
3038 global_list_store_name(C,StoreName),
3039 make_get_store_goal(StoreName,Store,GetStoreGoal),
3040 make_update_store_goal(StoreName,Cell,UpdateStoreGoal),
3041 ( chr_pp_flag(debugable,on) ->
3042 Cell = [Susp|Store],
3049 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,Cell,SetGoal),
3053 Cell = [Susp|Store],
3055 ( Store = [NextSusp|_] ->
3062 % get_target_module(Mod),
3063 % get_max_constraint_index(Total),
3065 % generate_attach_body_1(C,Store,Susp,AttachBody)
3067 % generate_attach_body_n(C,Store,Susp,AttachBody)
3071 % 'chr default_store'(Store),
3074 insert_constraint_body(multi_inthash(Indexes),C,Susp,[],Body) :-
3075 generate_multi_inthash_insert_constraint_bodies(Indexes,C,Susp,Body).
3076 insert_constraint_body(multi_hash(Indexes),C,Susp,MixedUsedVars,Body) :-
3077 generate_multi_hash_insert_constraint_bodies(Indexes,C,Susp,Body,MixedUsedVars),
3078 sort_out_used_vars(MixedUsedVars,UsedVars).
3079 insert_constraint_body(atomic_constants(Index,_,_),C,Susp,UsedVars,Body) :-
3080 multi_hash_key_direct(C,Index,Susp,Key,UsedVars),
3081 constants_store_index_name(C,Index,IndexName),
3082 IndexLookup =.. [IndexName,Key,StoreName],
3085 nb_getval(StoreName,Store),
3086 b_setval(StoreName,[Susp|Store])
3090 insert_constraint_body(ground_constants(Index,_,_),C,Susp,UsedVars,Body) :-
3091 multi_hash_key_direct(C,Index,Susp,Key,UsedVars),
3092 constants_store_index_name(C,Index,IndexName),
3093 IndexLookup =.. [IndexName,Key,StoreName],
3096 nb_getval(StoreName,Store),
3097 b_setval(StoreName,[Susp|Store])
3101 insert_constraint_body(global_ground,C,Susp,[],Body) :-
3102 global_ground_store_name(C,StoreName),
3103 make_get_store_goal(StoreName,Store,GetStoreGoal),
3104 make_update_store_goal(StoreName,Cell,UpdateStoreGoal),
3105 ( chr_pp_flag(debugable,on) ->
3106 Cell = [Susp|Store],
3113 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,Cell,SetGoal),
3117 Cell = [Susp|Store],
3119 ( Store = [NextSusp|_] ->
3126 % global_ground_store_name(C,StoreName),
3127 % make_get_store_goal(StoreName,Store,GetStoreGoal),
3128 % make_update_store_goal(StoreName,[Susp|Store],UpdateStoreGoal),
3131 % GetStoreGoal, % nb_getval(StoreName,Store),
3132 % UpdateStoreGoal % b_setval(StoreName,[Susp|Store])
3134 insert_constraint_body(var_assoc_store(VarIndex,AssocIndex),C,Susp,[VarIndex-Variable,AssocIndex-Key],Body) :-
3135 % TODO: generalize to more than one !!!
3136 get_target_module(Module),
3137 Body = ( get_attr(Variable,Module,AssocStore) ->
3138 insert_assoc_store(AssocStore,Key,Susp)
3140 new_assoc_store(AssocStore),
3141 put_attr(Variable,Module,AssocStore),
3142 insert_assoc_store(AssocStore,Key,Susp)
3145 insert_constraint_body(global_singleton,C,Susp,[],Body) :-
3146 global_singleton_store_name(C,StoreName),
3147 make_update_store_goal(StoreName,Susp,UpdateStoreGoal),
3152 insert_constraint_body(multi_store(StoreTypes),C,Susp,UsedVars,Body) :-
3153 maplist(insert_constraint_body1(C,Susp),StoreTypes,NestedUsedVars,Bodies),
3154 list2conj(Bodies,Body),
3155 sort_out_used_vars(NestedUsedVars,UsedVars).
3156 insert_constraint_body1(C,Susp,StoreType,UsedVars,Body) :-
3157 insert_constraint_body(StoreType,C,Susp,UsedVars,Body).
3158 insert_constraint_body(identifier_store(Index),C,Susp,UsedVars,Body) :-
3159 UsedVars = [Index-Var],
3160 get_identifier_size(ISize),
3161 functor(Struct,struct,ISize),
3162 get_identifier_index(C,Index,IIndex),
3163 arg(IIndex,Struct,Susps),
3164 Body = (Var = Struct, setarg(IIndex,Var,[Susp|Susps])).
3165 insert_constraint_body(type_indexed_identifier_store(Index,IndexType),C,Susp,UsedVars,Body) :-
3166 UsedVars = [Index-Var],
3167 type_indexed_identifier_structure(IndexType,Struct),
3168 get_type_indexed_identifier_index(IndexType,C,Index,IIndex),
3169 arg(IIndex,Struct,Susps),
3170 Body = (Var = Struct, setarg(IIndex,Var,[Susp|Susps])).
3172 sort_out_used_vars(NestedUsedVars,UsedVars) :-
3173 flatten(NestedUsedVars,FlatUsedVars),
3174 sort(FlatUsedVars,SortedFlatUsedVars),
3175 sort_out_used_vars1(SortedFlatUsedVars,UsedVars).
3177 sort_out_used_vars1([],[]).
3178 sort_out_used_vars1([I-V],L) :- !, L = [I-V].
3179 sort_out_used_vars1([I-X,J-Y|R],L) :-
3182 sort_out_used_vars1([I-X|R],L)
3185 sort_out_used_vars1([J-Y|R],T)
3188 generate_multi_inthash_insert_constraint_bodies([],_,_,true).
3189 generate_multi_inthash_insert_constraint_bodies([Index|Indexes],FA,Susp,(Body,Bodies)) :-
3190 multi_hash_store_name(FA,Index,StoreName),
3191 multi_hash_key(FA,Index,Susp,KeyBody,Key),
3195 nb_getval(StoreName,Store),
3196 insert_iht(Store,Key,Susp)
3198 generate_multi_inthash_insert_constraint_bodies(Indexes,FA,Susp,Bodies).
3200 generate_multi_hash_insert_constraint_bodies([],_,_,true,[]).
3201 generate_multi_hash_insert_constraint_bodies([Index|Indexes],FA,Susp,(Body,Bodies),[UsedVars|MoreUsedVars]) :-
3202 multi_hash_store_name(FA,Index,StoreName),
3203 multi_hash_key_direct(FA,Index,Susp,Key,UsedVars),
3204 make_get_store_goal(StoreName,Store,GetStoreGoal),
3205 ( chr_pp_flag(ht_removal,on)
3206 -> ht_prev_field(Index,PrevField),
3207 set_dynamic_suspension_term_field(PrevField,FA,NextSusp,Result,
3212 insert_ht(Store,Key,Susp,Result),
3213 ( Result = [_,NextSusp|_]
3221 insert_ht(Store,Key,Susp)
3224 generate_multi_hash_insert_constraint_bodies(Indexes,FA,Susp,Bodies,MoreUsedVars).
3226 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3229 delete_constraint_clause(C,Clauses,RestClauses) :-
3230 ( is_used_auxiliary_predicate(delete_from_store,C) ->
3231 Clauses = [Clause|RestClauses],
3232 Clause = (Head :- Body),
3233 delete_constraint_atom(C,Susp,Head),
3236 delete_constraint_body(C,Head,Susp,[],Body)
3238 Clauses = RestClauses
3241 delete_constraint_goal(Head,Susp,VarDict,Goal) :-
3244 ( chr_pp_flag(inline_insertremove,off) ->
3245 use_auxiliary_predicate(delete_from_store,C),
3246 delete_constraint_atom(C,Susp,Goal)
3248 delay_phase_end(validate_store_type_assumptions, delete_constraint_body(C,Head,Susp,VarDict,Goal))
3251 delete_constraint_atom(C,Susp,Atom) :-
3252 make_name('$delete_from_store_',C,Functor),
3253 Atom =.. [Functor,Susp].
3256 delete_constraint_body(C,Head,Susp,VarDict,Body) :-
3257 Body = (CounterBody,DeleteBody),
3258 ( chr_pp_flag(store_counter,on) ->
3259 CounterBody = '$delete_counter_inc'
3263 get_store_type(C,StoreType),
3264 delete_constraint_body(StoreType,C,Head,Susp,VarDict,DeleteBody).
3266 delete_constraint_body(default,C,_,Susp,_,Body) :-
3267 ( chr_pp_flag(debugable,on) ->
3268 global_list_store_name(C,StoreName),
3269 make_get_store_goal(StoreName,Store,GetStoreGoal),
3270 make_update_store_goal(StoreName,NStore,UpdateStoreGoal),
3273 GetStoreGoal, % nb_getval(StoreName,Store),
3274 'chr sbag_del_element'(Store,Susp,NStore),
3275 UpdateStoreGoal % b_setval(StoreName,NStore)
3278 get_dynamic_suspension_term_field(global_list_prev,C,Susp,PredCell,GetGoal),
3279 global_list_store_name(C,StoreName),
3280 make_get_store_goal(StoreName,Store,GetStoreGoal),
3281 make_update_store_goal(StoreName,Tail,UpdateStoreGoal),
3282 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,_,SetGoal1),
3283 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,PredCell,SetGoal2),
3288 GetStoreGoal, % nb_getval(StoreName,Store),
3291 ( Tail = [NextSusp|_] ->
3297 PredCell = [_,_|Tail],
3298 setarg(2,PredCell,Tail),
3299 ( Tail = [NextSusp|_] ->
3307 % get_target_module(Mod),
3308 % get_max_constraint_index(Total),
3310 % generate_detach_body_1(C,Store,Susp,DetachBody),
3313 % 'chr default_store'(Store),
3317 % generate_detach_body_n(C,Store,Susp,DetachBody),
3320 % 'chr default_store'(Store),
3324 delete_constraint_body(multi_inthash(Indexes),C,_,Susp,_,Body) :-
3325 generate_multi_inthash_delete_constraint_bodies(Indexes,C,Susp,Body).
3326 delete_constraint_body(multi_hash(Indexes),C,Head,Susp,VarDict,Body) :-
3327 generate_multi_hash_delete_constraint_bodies(Indexes,C,Head,Susp,VarDict,Body).
3328 delete_constraint_body(atomic_constants(Index,_,_),C,Head,Susp,VarDict,Body) :-
3329 multi_hash_key(C,Head,Index,Susp,VarDict,KeyBody,Key),
3330 constants_store_index_name(C,Index,IndexName),
3331 IndexLookup =.. [IndexName,Key,StoreName],
3335 nb_getval(StoreName,Store),
3336 'chr sbag_del_element'(Store,Susp,NStore),
3337 b_setval(StoreName,NStore)
3341 delete_constraint_body(ground_constants(Index,_,_),C,Head,Susp,VarDict,Body) :-
3342 multi_hash_key(C,Head,Index,Susp,VarDict,KeyBody,Key),
3343 constants_store_index_name(C,Index,IndexName),
3344 IndexLookup =.. [IndexName,Key,StoreName],
3348 nb_getval(StoreName,Store),
3349 'chr sbag_del_element'(Store,Susp,NStore),
3350 b_setval(StoreName,NStore)
3354 delete_constraint_body(global_ground,C,_,Susp,_,Body) :-
3355 ( chr_pp_flag(debugable,on) ->
3356 global_ground_store_name(C,StoreName),
3357 make_get_store_goal(StoreName,Store,GetStoreGoal),
3358 make_update_store_goal(StoreName,NStore,UpdateStoreGoal),
3361 GetStoreGoal, % nb_getval(StoreName,Store),
3362 'chr sbag_del_element'(Store,Susp,NStore),
3363 UpdateStoreGoal % b_setval(StoreName,NStore)
3366 get_dynamic_suspension_term_field(global_list_prev,C,Susp,PredCell,GetGoal),
3367 global_ground_store_name(C,StoreName),
3368 make_get_store_goal(StoreName,Store,GetStoreGoal),
3369 make_update_store_goal(StoreName,Tail,UpdateStoreGoal),
3370 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,_,SetGoal1),
3371 set_dynamic_suspension_term_field(global_list_prev,C,NextSusp,PredCell,SetGoal2),
3376 GetStoreGoal, % nb_getval(StoreName,Store),
3379 ( Tail = [NextSusp|_] ->
3385 PredCell = [_,_|Tail],
3386 setarg(2,PredCell,Tail),
3387 ( Tail = [NextSusp|_] ->
3395 % global_ground_store_name(C,StoreName),
3396 % make_get_store_goal(StoreName,Store,GetStoreGoal),
3397 % make_update_store_goal(StoreName,NStore,UpdateStoreGoal),
3400 % GetStoreGoal, % nb_getval(StoreName,Store),
3401 % 'chr sbag_del_element'(Store,Susp,NStore),
3402 % UpdateStoreGoal % b_setval(StoreName,NStore)
3404 delete_constraint_body(var_assoc_store(VarIndex,AssocIndex),C,_,Susp,_,Body) :-
3405 get_target_module(Module),
3406 get_dynamic_suspension_term_field(argument(VarIndex),C,Susp,Variable,VariableGoal),
3407 get_dynamic_suspension_term_field(argument(AssocIndex),C,Susp,Key,KeyGoal),
3410 get_attr(Variable,Module,AssocStore),
3412 delete_assoc_store(AssocStore,Key,Susp)
3414 delete_constraint_body(global_singleton,C,_,_Susp,_,Body) :-
3415 global_singleton_store_name(C,StoreName),
3416 make_update_store_goal(StoreName,[],UpdateStoreGoal),
3419 UpdateStoreGoal % b_setval(StoreName,[])
3421 delete_constraint_body(multi_store(StoreTypes),C,Head,Susp,VarDict,Body) :-
3422 maplist(delete_constraint_body1(C,Head,Susp,VarDict),StoreTypes,Bodies),
3423 list2conj(Bodies,Body).
3424 delete_constraint_body1(C,Head,Susp,VarDict,StoreType,Body) :-
3425 delete_constraint_body(StoreType,C,Head,Susp,VarDict,Body).
3426 delete_constraint_body(identifier_store(Index),C,Head,Susp,VarDict,Body) :-
3427 get_suspension_argument_possibly_in_scope(Head,VarDict,Susp,Index,Variable,VariableGoal),
3428 get_identifier_size(ISize),
3429 functor(Struct,struct,ISize),
3430 get_identifier_index(C,Index,IIndex),
3431 arg(IIndex,Struct,Susps),
3435 'chr sbag_del_element'(Susps,Susp,NSusps),
3436 setarg(IIndex,Variable,NSusps)
3438 delete_constraint_body(type_indexed_identifier_store(Index,IndexType),C,Head,Susp,VarDict,Body) :-
3439 get_suspension_argument_possibly_in_scope(Head,VarDict,Susp,Index,Variable,VariableGoal),
3440 type_indexed_identifier_structure(IndexType,Struct),
3441 get_type_indexed_identifier_index(IndexType,C,Index,IIndex),
3442 arg(IIndex,Struct,Susps),
3446 'chr sbag_del_element'(Susps,Susp,NSusps),
3447 setarg(IIndex,Variable,NSusps)
3450 generate_multi_inthash_delete_constraint_bodies([],_,_,true).
3451 generate_multi_inthash_delete_constraint_bodies([Index|Indexes],FA,Susp,(Body,Bodies)) :-
3452 multi_hash_store_name(FA,Index,StoreName),
3453 multi_hash_key(FA,Index,Susp,KeyBody,Key),
3457 nb_getval(StoreName,Store),
3458 delete_iht(Store,Key,Susp)
3460 generate_multi_inthash_delete_constraint_bodies(Indexes,FA,Susp,Bodies).
3461 generate_multi_hash_delete_constraint_bodies([],_,_,_,_,true).
3462 generate_multi_hash_delete_constraint_bodies([Index|Indexes],C,Head,Susp,VarDict,(Body,Bodies)) :-
3463 multi_hash_store_name(C,Index,StoreName),
3464 multi_hash_key(C,Head,Index,Susp,VarDict,KeyBody,Key),
3465 make_get_store_goal(StoreName,Store,GetStoreGoal),
3466 ( chr_pp_flag(ht_removal,on)
3467 -> ht_prev_field(Index,PrevField),
3468 get_dynamic_suspension_term_field(PrevField,C,Susp,Prev,GetGoal),
3469 set_dynamic_suspension_term_field(PrevField,C,NextSusp,_,
3471 set_dynamic_suspension_term_field(PrevField,C,NextSusp,Prev,
3479 delete_first_ht(Store,Key,Values),
3480 ( Values = [NextSusp|_]
3484 ; Prev = [_,_|Values],
3485 setarg(2,Prev,Values),
3486 ( Values = [NextSusp|_]
3495 GetStoreGoal, % nb_getval(StoreName,Store),
3496 delete_ht(Store,Key,Susp)
3499 generate_multi_hash_delete_constraint_bodies(Indexes,FA,Head,Susp,VarDict,Bodies).
3501 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3504 module_initializer/1,
3505 module_initializers/1.
3507 module_initializers(G), module_initializer(Initializer) <=>
3508 G = (Initializer,Initializers),
3509 module_initializers(Initializers).
3511 module_initializers(G) <=>
3514 generate_attach_code(Constraints,Clauses) :-
3515 enumerate_stores_code(Constraints,Enumerate),
3516 append(Enumerate,L,Clauses),
3517 generate_attach_code(Constraints,L,T),
3518 module_initializers(Initializers),
3519 prolog_global_variables_code(PrologGlobalVariables),
3520 % Do not rename or the 'chr_initialization' predicate
3521 % without warning SSS
3522 T = [('$chr_initialization' :- Initializers),(:- initialization '$chr_initialization')|PrologGlobalVariables].
3524 generate_attach_code([],L,L).
3525 generate_attach_code([C|Cs],L,T) :-
3526 get_store_type(C,StoreType),
3527 generate_attach_code(StoreType,C,L,L1),
3528 generate_attach_code(Cs,L1,T).
3530 generate_attach_code(default,C,L,T) :-
3531 global_list_store_initialisation(C,L,T).
3532 generate_attach_code(multi_inthash(Indexes),C,L,T) :-
3533 multi_inthash_store_initialisations(Indexes,C,L,L1),
3534 multi_inthash_via_lookups(Indexes,C,L1,T).
3535 generate_attach_code(multi_hash(Indexes),C,L,T) :-
3536 multi_hash_store_initialisations(Indexes,C,L,L1),
3537 multi_hash_lookups(Indexes,C,L1,T).
3538 generate_attach_code(atomic_constants(Index,Constants,_),C,L,T) :-
3539 constants_initializers(C,Index,Constants),
3540 atomic_constants_code(C,Index,Constants,L,T).
3541 generate_attach_code(ground_constants(Index,Constants,_),C,L,T) :-
3542 constants_initializers(C,Index,Constants),
3543 ground_constants_code(C,Index,Constants,L,T).
3544 generate_attach_code(global_ground,C,L,T) :-
3545 global_ground_store_initialisation(C,L,T).
3546 generate_attach_code(var_assoc_store(_,_),_,L,L) :-
3547 use_auxiliary_module(chr_assoc_store).
3548 generate_attach_code(global_singleton,C,L,T) :-
3549 global_singleton_store_initialisation(C,L,T).
3550 generate_attach_code(multi_store(StoreTypes),C,L,T) :-
3551 multi_store_generate_attach_code(StoreTypes,C,L,T).
3552 generate_attach_code(identifier_store(Index),C,L,T) :-
3553 get_identifier_index(C,Index,IIndex),
3555 get_identifier_size(ISize),
3556 functor(Struct,struct,ISize),
3557 Struct =.. [_,Label|Stores],
3558 set_elems(Stores,[]),
3559 Clause1 = new_identifier(Label,Struct),
3560 functor(Struct2,struct,ISize),
3561 arg(1,Struct2,Label2),
3563 ( user:portray(Struct2) :-
3568 functor(Struct3,struct,ISize),
3569 arg(1,Struct3,Label3),
3570 Clause3 = identifier_label(Struct3,Label3),
3571 L = [Clause1,Clause2,Clause3|T]
3575 generate_attach_code(type_indexed_identifier_store(Index,IndexType),C,L,T) :-
3576 get_type_indexed_identifier_index(IndexType,C,Index,IIndex),
3578 identifier_store_initialization(IndexType,L,L1),
3579 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3580 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3581 get_type_indexed_identifier_size(IndexType,ISize),
3582 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3583 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3584 type_indexed_identifier_structure(IndexType,Struct),
3585 Struct =.. [_,Label|Stores],
3586 set_elems(Stores,[]),
3587 type_indexed_identifier_name(IndexType,new_identifier,Name1),
3588 Clause1 =.. [Name1,Label,Struct],
3589 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3590 Goal1 =.. [Name1,Label1b,S1b],
3591 type_indexed_identifier_structure(IndexType,Struct1b),
3592 Struct1b =.. [_,Label1b|Stores1b],
3593 set_elems(Stores1b,[]),
3594 Expansion1 = (S1b = Struct1b),
3595 Clause1b = user:goal_expansion(Goal1,Expansion1),
3596 % writeln(Clause1-Clause1b),
3597 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3598 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3599 type_indexed_identifier_structure(IndexType,Struct2),
3600 arg(1,Struct2,Label2),
3602 ( user:portray(Struct2) :-
3607 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3608 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3609 type_indexed_identifier_structure(IndexType,Struct3),
3610 arg(1,Struct3,Label3),
3611 type_indexed_identifier_name(IndexType,identifier_label,Name3),
3612 Clause3 =.. [Name3,Struct3,Label3],
3613 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3614 Goal3b =.. [Name3,S3b,L3b],
3615 type_indexed_identifier_structure(IndexType,Struct3b),
3616 arg(1,Struct3b,L3b),
3617 Expansion3b = (S3 = Struct3b),
3618 Clause3b = ( user:goal_expansion(Goal3b,Expansion3b) :- writeln(expanding)),
3619 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3620 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3621 identifier_store_name(IndexType,GlobalVariable),
3622 lookup_identifier_atom(IndexType,X,IX,LookupAtom),
3623 type_indexed_identifier_name(IndexType,new_identifier,NewIdentifierFunctor),
3624 NewIdentifierGoal =.. [NewIdentifierFunctor,X,IX],
3627 nb_getval(GlobalVariable,HT),
3628 ( lookup_ht(HT,X,[IX]) ->
3635 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3636 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
3637 L1 = [(:- multifile goal_expansion/2),(:- dynamic goal_expansion/2),Clause1,Clause1b,Clause2,Clause3,Clause3b,Clause4|T]
3642 constants_initializers(C,Index,Constants) :-
3643 maplist(constant_initializer(C,Index),Constants).
3645 constant_initializer(C,Index,Constant) :-
3646 constants_store_name(C,Index,Constant,StoreName),
3647 prolog_global_variable(StoreName),
3648 module_initializer(nb_setval(StoreName,[])).
3650 lookup_identifier_atom(Key,X,IX,Atom) :-
3651 atom_concat('lookup_identifier_',Key,LookupFunctor),
3652 Atom =.. [LookupFunctor,X,IX].
3654 identifier_label_atom(IndexType,IX,X,Atom) :-
3655 type_indexed_identifier_name(IndexType,identifier_label,Name),
3656 Atom =.. [Name,IX,X].
3658 multi_store_generate_attach_code([],_,L,L).
3659 multi_store_generate_attach_code([ST|STs],C,L,T) :-
3660 generate_attach_code(ST,C,L,L1),
3661 multi_store_generate_attach_code(STs,C,L1,T).
3663 multi_inthash_store_initialisations([],_,L,L).
3664 multi_inthash_store_initialisations([Index|Indexes],FA,L,T) :-
3665 use_auxiliary_module(chr_integertable_store),
3666 multi_hash_store_name(FA,Index,StoreName),
3667 module_initializer((new_iht(HT),nb_setval(StoreName,HT))),
3668 % L = [(:- (chr_integertable_store:new_ht(HT),nb_setval(StoreName,HT)) )|L1],
3670 multi_inthash_store_initialisations(Indexes,FA,L1,T).
3671 multi_hash_store_initialisations([],_,L,L).
3672 multi_hash_store_initialisations([Index|Indexes],FA,L,T) :-
3673 use_auxiliary_module(chr_hashtable_store),
3674 multi_hash_store_name(FA,Index,StoreName),
3675 prolog_global_variable(StoreName),
3676 make_init_store_goal(StoreName,HT,InitStoreGoal),
3677 module_initializer((new_ht(HT),InitStoreGoal)),
3679 multi_hash_store_initialisations(Indexes,FA,L1,T).
3681 global_list_store_initialisation(C,L,T) :-
3683 global_list_store_name(C,StoreName),
3684 prolog_global_variable(StoreName),
3685 make_init_store_goal(StoreName,[],InitStoreGoal),
3686 module_initializer(InitStoreGoal)
3691 global_ground_store_initialisation(C,L,T) :-
3692 global_ground_store_name(C,StoreName),
3693 prolog_global_variable(StoreName),
3694 make_init_store_goal(StoreName,[],InitStoreGoal),
3695 module_initializer(InitStoreGoal),
3697 global_singleton_store_initialisation(C,L,T) :-
3698 global_singleton_store_name(C,StoreName),
3699 prolog_global_variable(StoreName),
3700 make_init_store_goal(StoreName,[],InitStoreGoal),
3701 module_initializer(InitStoreGoal),
3703 identifier_store_initialization(IndexType,L,T) :-
3704 use_auxiliary_module(chr_hashtable_store),
3705 identifier_store_name(IndexType,StoreName),
3706 prolog_global_variable(StoreName),
3707 make_init_store_goal(StoreName,HT,InitStoreGoal),
3708 module_initializer((new_ht(HT),InitStoreGoal)),
3712 multi_inthash_via_lookups([],_,L,L).
3713 multi_inthash_via_lookups([Index|Indexes],C,L,T) :-
3714 multi_hash_lookup_head(C,Index,Key,SuspsList,Head),
3715 multi_hash_lookup_body(C,inthash,Index,Key,SuspsList,Body),
3716 L = [(Head :- Body)|L1],
3717 multi_inthash_via_lookups(Indexes,C,L1,T).
3718 multi_hash_lookups([],_,L,L).
3719 multi_hash_lookups([Index|Indexes],C,L,T) :-
3720 multi_hash_lookup_head(C,Index,Key,SuspsList,Head),
3721 multi_hash_lookup_body(C,hash,Index,Key,SuspsList,Body),
3722 L = [(Head :- Body)|L1],
3723 multi_hash_lookups(Indexes,C,L1,T).
3725 multi_hash_lookup_head(ConstraintSymbol,Index,Key,SuspsList,Head) :-
3726 multi_hash_lookup_name(ConstraintSymbol,Index,Name),
3727 Head =.. [Name,Key,SuspsList].
3729 %% multi_hash_lookup_body(+ConstraintSymbol,+HashType,+Index,+Key,+SuspsList,-Goal) is det.
3731 % Returns goal that performs hash table lookup.
3732 multi_hash_lookup_body(ConstraintSymbol,HashType,Index,Key,SuspsList,Goal) :-
3734 get_store_type(ConstraintSymbol,multi_store(Stores)),
3735 ( memberchk(atomic_constants(Index,Constants,_),Stores) ->
3737 constants_store_name(ConstraintSymbol,Index,Key,StoreName),
3738 Goal = nb_getval(StoreName,SuspsList)
3740 constants_store_index_name(ConstraintSymbol,Index,IndexName),
3741 Lookup =.. [IndexName,Key,StoreName],
3742 Goal = (Lookup, nb_getval(StoreName,SuspsList))
3744 ; memberchk(ground_constants(Index,Constants,_),Stores) ->
3746 constants_store_name(ConstraintSymbol,Index,Key,StoreName),
3747 Goal = nb_getval(StoreName,SuspsList)
3749 constants_store_index_name(ConstraintSymbol,Index,IndexName),
3750 Lookup =.. [IndexName,Key,StoreName],
3751 Goal = (Lookup, nb_getval(StoreName,SuspsList))
3753 ; memberchk(multi_hash([Index]),Stores) ->
3754 multi_hash_store_name(ConstraintSymbol,Index,StoreName),
3755 make_get_store_goal(StoreName,HT,GetStoreGoal),
3756 ( HashType == hash, specialized_hash_term_call(ConstraintSymbol,Index,Key,Hash,HashCall) ->
3759 GetStoreGoal, % nb_getval(StoreName,HT),
3760 HashCall, % hash_term(Key,Hash),
3761 lookup_ht1(HT,Hash,Key,SuspsList)
3764 lookup_hash_call(HashType,HT,Key,SuspsList,Lookup),
3767 GetStoreGoal, % nb_getval(StoreName,HT),
3771 ; HashType == inthash ->
3772 multi_hash_store_name(ConstraintSymbol,Index,StoreName),
3773 make_get_store_goal(StoreName,HT,GetStoreGoal),
3774 lookup_hash_call(HashType,HT,Key,SuspsList,Lookup),
3777 GetStoreGoal, % nb_getval(StoreName,HT),
3780 % ; % chr_error(internal,'Index ~w for constraint ~w does not exist!\n',[Index,ConstraintSymbol])
3781 % find alternative index
3782 % -> SubIndex + RestIndex
3783 % -> SubKey + RestKeys
3784 % multi_hash_lookup_goal(ConstraintSymbol,HashType,SubIndex,SubKey,SuspsList,SubGoal),
3785 % instantiate rest goal?
3786 % Goal = (SubGoal,RestGoal)
3790 lookup_hash_call(hash,HT,Key,SuspsList,lookup_ht(HT,Key,SuspsList)).
3791 lookup_hash_call(inthash,HT,Key,SuspsList,lookup_iht(HT,Key,SuspsList)).
3793 specialized_hash_term_call(Constraint,Index,Key,Hash,Call) :-
3795 % This is based on a property of SWI-Prolog's
3796 % hash_term/2 predicate:
3797 % the hash value is stable over repeated invocations
3799 hash_term(Key,Hash),
3801 % ; Index = [IndexPos],
3802 % get_constraint_type(Constraint,ArgTypes),
3803 % nth1(IndexPos,ArgTypes,Type),
3804 % unalias_type(Type,NormalType),
3805 % memberchk_eq(NormalType,[int,natural]) ->
3806 % ( NormalType == int ->
3807 % Call = (Hash is abs(Key))
3814 % specialize_hash_term(Key,NewKey),
3816 % Call = hash_term(NewKey,Hash)
3819 % specialize_hash_term(Term,NewTerm) :-
3821 % hash_term(Term,NewTerm)
3825 % Term =.. [F|Args],
3826 % maplist(specialize_hash_term,Args,NewArgs),
3827 % NewTerm =.. [F|NewArgs]
3830 multi_hash_lookup_goal(ConstraintSymbol,HashType,Index,Key,SuspsList,Goal) :-
3831 % format(' * lookup of ~w on ~w with ~w.\n',[ConstraintSymbol,Index,Key]),
3832 ( /* chr_pp_flag(experiment,off) ->
3835 actual_atomic_multi_hash_keys(ConstraintSymbol,Index,[Key])
3837 actual_ground_multi_hash_keys(ConstraintSymbol,Index,[Key])
3840 get_constraint_arg_type(ConstraintSymbol,Pos,Type),
3841 is_chr_constants_type(Type,_,_)
3845 actual_non_ground_multi_hash_key(ConstraintSymbol,Index)
3848 delay_phase_end(validate_store_type_assumptions,
3849 multi_hash_lookup_body(ConstraintSymbol,HashType,Index,Key,SuspsList,Goal)).
3851 :- chr_constraint actual_atomic_multi_hash_keys/3.
3852 :- chr_option(mode,actual_atomic_multi_hash_keys(+,+,?)).
3854 :- chr_constraint actual_ground_multi_hash_keys/3.
3855 :- chr_option(mode,actual_ground_multi_hash_keys(+,+,?)).
3857 :- chr_constraint actual_non_ground_multi_hash_key/2.
3858 :- chr_option(mode,actual_non_ground_multi_hash_key(+,+)).
3861 actual_atomic_multi_hash_keys(C,Index,Keys)
3862 ==> format('Keys: ~w - ~w : ~w\n', [C,Index,Keys]).
3864 actual_ground_multi_hash_keys(C,Index,Keys)
3865 ==> format('Keys: ~w - ~w : ~w\n', [C,Index,Keys]).
3867 actual_non_ground_multi_hash_key(C,Index)
3868 ==> format('Keys: ~w - ~w : N/A\n', [C,Index]).
3870 actual_atomic_multi_hash_keys(C,Index,Keys1), actual_atomic_multi_hash_keys(C,Index,Keys2)
3871 <=> append(Keys1,Keys2,Keys0),
3873 actual_atomic_multi_hash_keys(C,Index,Keys).
3875 actual_ground_multi_hash_keys(C,Index,Keys1), actual_atomic_multi_hash_keys(C,Index,Keys2)
3876 <=> append(Keys1,Keys2,Keys0),
3878 actual_ground_multi_hash_keys(C,Index,Keys).
3880 actual_ground_multi_hash_keys(C,Index,Keys1), actual_ground_multi_hash_keys(C,Index,Keys2)
3881 <=> append(Keys1,Keys2,Keys0),
3883 actual_ground_multi_hash_keys(C,Index,Keys).
3885 actual_non_ground_multi_hash_key(C,Index) \ actual_non_ground_multi_hash_key(C,Index)
3888 actual_non_ground_multi_hash_key(C,Index) \ actual_atomic_multi_hash_keys(C,Index,_)
3891 actual_non_ground_multi_hash_key(C,Index) \ actual_ground_multi_hash_keys(C,Index,_)
3894 %% multi_hash_lookup_name(+ConstraintSymbol,+Index,-Name)
3896 % Returns predicate name of hash table lookup predicate.
3897 multi_hash_lookup_name(F/A,Index,Name) :-
3898 atom_concat_list(Index,IndexName),
3899 atom_concat_list(['$via1_multi_hash_',F,'___',A,'-',IndexName],Name).
3901 multi_hash_store_name(F/A,Index,Name) :-
3902 get_target_module(Mod),
3903 atom_concat_list(Index,IndexName),
3904 atom_concat_list(['$chr_store_multi_hash_',Mod,'____',F,'___',A,'-',IndexName],Name).
3906 multi_hash_key(FA,Index,Susp,KeyBody,Key) :-
3908 get_dynamic_suspension_term_field(argument(I),FA,Susp,Key,KeyBody)
3910 maplist(get_dynamic_suspension_term_field1(FA,Susp),Index,Keys,Bodies),
3912 list2conj(Bodies,KeyBody)
3915 get_dynamic_suspension_term_field1(FA,Susp,I,KeyI,Goal) :-
3916 get_dynamic_suspension_term_field(argument(I),FA,Susp,KeyI,Goal).
3918 multi_hash_key(C,Head,Index,Susp,VarDict,KeyBody,Key) :-
3920 get_suspension_argument_possibly_in_scope(Head,VarDict,Susp,I,Key,KeyBody)
3922 maplist(get_suspension_argument_possibly_in_scope(Head,VarDict,Susp),Index,Keys,Bodies),
3924 list2conj(Bodies,KeyBody)
3927 get_suspension_argument_possibly_in_scope(Head,VarDict,Susp,Index,Arg,Goal) :-
3928 arg(Index,Head,OriginalArg),
3929 ( term_variables(OriginalArg,OriginalVars),
3930 copy_term_nat(OriginalArg-OriginalVars,Arg-Vars),
3931 translate(OriginalVars,VarDict,Vars) ->
3936 get_dynamic_suspension_term_field(argument(Index),C,Susp,Arg,Goal)
3939 multi_hash_key_direct(FA,Index,Susp,Key,UsedVars) :-
3943 pairup(Index,Keys,UsedVars),
3947 args(Index,Head,KeyArgs) :-
3948 maplist(arg1(Head),Index,KeyArgs).
3950 split_args(Indexes,Args,IArgs,NIArgs) :-
3951 split_args(Indexes,Args,1,IArgs,NIArgs).
3953 split_args([],Args,_,[],Args).
3954 split_args([I|Is],[Arg|Args],J,IArgs,NIArgs) :-
3958 split_args(Is,Args,NJ,Rest,NIArgs)
3960 NIArgs = [Arg|Rest],
3961 split_args([I|Is],Args,NJ,IArgs,Rest)
3965 %-------------------------------------------------------------------------------
3966 atomic_constants_code(C,Index,Constants,L,T) :-
3967 constants_store_index_name(C,Index,IndexName),
3968 maplist(atomic_constant_code(C,Index,IndexName),Constants,Clauses),
3969 append(Clauses,T,L).
3971 atomic_constant_code(C,Index,IndexName,Constant,Clause) :-
3972 constants_store_name(C,Index,Constant,StoreName),
3973 Clause =.. [IndexName,Constant,StoreName].
3975 %-------------------------------------------------------------------------------
3976 ground_constants_code(C,Index,Terms,L,T) :-
3977 constants_store_index_name(C,Index,IndexName),
3978 maplist(constants_store_name(C,Index),Terms,StoreNames),
3980 replicate(N,[],More),
3981 trie_index([Terms|More],StoreNames,IndexName,L,T).
3983 constants_store_name(F/A,Index,Term,Name) :-
3984 get_target_module(Mod),
3985 term_to_atom(Term,Constant),
3986 term_to_atom(Index,IndexAtom),
3987 atom_concat_list(['$chr_store_constants_',Mod,'____',F,'___',A,'___',IndexAtom,'___',Constant],Name).
3989 constants_store_index_name(F/A,Index,Name) :-
3990 get_target_module(Mod),
3991 term_to_atom(Index,IndexAtom),
3992 atom_concat_list(['$chr_store_constants_',Mod,'____',F,'___',A,'___',IndexAtom],Name).
3994 % trie index code {{{
3995 trie_index([Patterns|MorePatterns],Results,Prefix,Clauses,Tail) :-
3996 trie_step(Patterns,Prefix,Prefix,MorePatterns,Results,Clauses,Tail).
3998 trie_step([],_,_,[],[],L,L) :- !.
3999 % length MorePatterns == length Patterns == length Results
4000 trie_step(Patterns,Symbol,Prefix,MorePatterns,Results,Clauses,T) :-
4001 MorePatterns = [List|_],
4003 aggregate_all(set(F/A),
4004 ( member(Pattern,Patterns),
4005 functor(Pattern,F,A)
4009 trie_step_cases(FAs,N1,Patterns,MorePatterns,Results,Symbol,Prefix,Clauses,T).
4011 trie_step_cases([],_,_,_,_,_,_,Clauses,Clauses).
4012 trie_step_cases([FA|FAs],N,Pattern,MorePatterns,Results,Symbol,Prefix,Clauses,Tail) :-
4013 trie_step_case(FA,N,Pattern,MorePatterns,Results,Symbol,Prefix,Clauses,Clauses1),
4014 trie_step_cases(FAs,N,Pattern,MorePatterns,Results,Symbol,Prefix,Clauses1,Tail).
4016 trie_step_case(F/A,N,Patterns,MorePatterns,Results,Symbol,Prefix,[Clause|List],Tail) :-
4017 Clause = (Head :- Body),
4018 /* Head = Symbol(IndexPattern,V2,...,Vn,Result) */
4020 functor(Head,Symbol,N1),
4021 arg(1,Head,IndexPattern),
4022 Head =.. [_,_|RestArgs],
4023 once(append(Vs,[Result],RestArgs)),
4024 /* IndexPattern = F() */
4025 functor(IndexPattern,F,A),
4026 IndexPattern =.. [_|Args],
4027 append(Args,RestArgs,RecArgs),
4028 ( RecArgs == [Result] ->
4029 /* nothing more to match on */
4032 rec_cases(Patterns,_,Results,F/A,_,_,MoreResults),
4033 MoreResults = [Result]
4034 ; /* more things to match on */
4035 rec_cases(Patterns,MorePatterns,Results,F/A,Cases,MoreCases,MoreResults),
4036 ( MoreCases = [OneMoreCase] ->
4037 /* only one more thing to match on */
4040 append([Cases,OneMoreCase,MoreResults],RecArgs)
4042 /* more than one thing to match on */
4046 pairup(Cases,MoreCases,CasePairs),
4047 common_pattern(CasePairs,CommonPatternPair,DiffVars,Differences),
4048 append(Args,Vs,[First|Rest]),
4049 First-Rest = CommonPatternPair,
4050 % Body = RSymbol(DiffVars,Result)
4051 gensym(Prefix,RSymbol),
4052 append(DiffVars,[Result],RecCallVars),
4053 Body =.. [RSymbol|RecCallVars],
4054 maplist(head_tail,Differences,CHs,CTs),
4055 trie_step(CHs,RSymbol,Prefix,CTs,MoreResults,List,Tail)
4059 head_tail([H|T],H,T).
4061 rec_cases([],[],[],_,[],[],[]).
4062 rec_cases([Pattern|Patterns],[MorePattern|MorePatterns],[Result|Results],F/A,Cases,MoreCases,MoreResults) :-
4063 ( functor(Pattern,F,A), Pattern =.. [_|ArgPatterns], append(ArgPatterns,MorePattern,[Case|MoreCase]) ->
4064 Cases = [Case|NCases],
4065 MoreCases = [MoreCase|NMoreCases],
4066 MoreResults = [Result|NMoreResults],
4067 rec_cases(Patterns,MorePatterns,Results,F/A,NCases,NMoreCases,NMoreResults)
4069 rec_cases(Patterns,MorePatterns,Results,F/A,Cases,MoreCases,MoreResults)
4073 %% common_pattern(+terms,-term,-vars,-differences) is det.
4074 common_pattern(Ts,T,Vars,Differences) :-
4076 term_variables(T,Vars),
4077 findall(Vars,member(T,Ts),Differences).
4082 gct_(T1,T2,T,Dict0,Dict) :-
4093 maplist_dcg(gct_,Args1,Args2,Args,Dict0,Dict)
4095 /* T is a variable */
4096 ( lookup_eq(Dict0,T1+T2,T) ->
4097 /* we already have a variable for this difference */
4100 /* T is a fresh variable */
4101 Dict = [(T1+T2)-T|Dict0]
4106 fold1(P,[Head|Tail],Result) :-
4107 fold(Tail,P,Head,Result).
4110 fold([X|Xs],P,Acc,Res) :-
4112 fold(Xs,P,NAcc,Res).
4114 maplist_dcg(P,L1,L2,L) -->
4115 maplist_dcg_(L1,L2,L,P).
4117 maplist_dcg_([],[],[],_) --> [].
4118 maplist_dcg_([X|Xs],[Y|Ys],[Z|Zs],P) -->
4120 maplist_dcg_(Xs,Ys,Zs,P).
4122 %-------------------------------------------------------------------------------
4123 global_list_store_name(F/A,Name) :-
4124 get_target_module(Mod),
4125 atom_concat_list(['$chr_store_global_list_',Mod,'____',F,'___',A],Name).
4126 global_ground_store_name(F/A,Name) :-
4127 get_target_module(Mod),
4128 atom_concat_list(['$chr_store_global_ground_',Mod,'____',F,'___',A],Name).
4129 global_singleton_store_name(F/A,Name) :-
4130 get_target_module(Mod),
4131 atom_concat_list(['$chr_store_global_singleton_',Mod,'____',F,'___',A],Name).
4133 identifier_store_name(TypeName,Name) :-
4134 get_target_module(Mod),
4135 atom_concat_list(['$chr_identifier_lookup_',Mod,'____',TypeName],Name).
4137 :- chr_constraint prolog_global_variable/1.
4138 :- chr_option(mode,prolog_global_variable(+)).
4140 :- chr_constraint prolog_global_variables/1.
4141 :- chr_option(mode,prolog_global_variables(-)).
4143 prolog_global_variable(Name) \ prolog_global_variable(Name) <=> true.
4145 prolog_global_variables(List), prolog_global_variable(Name) <=>
4147 prolog_global_variables(Tail).
4148 prolog_global_variables(List) <=> List = [].
4151 prolog_global_variables_code(Code) :-
4152 prolog_global_variables(Names),
4156 maplist(wrap_in_functor('$chr_prolog_global_variable'),Names,NameDeclarations),
4157 Code = [(:- dynamic user:exception/3),
4158 (:- multifile user:exception/3),
4159 (user:exception(undefined_global_variable,Name,retry) :-
4161 '$chr_prolog_global_variable'(Name),
4162 '$chr_initialization'
4171 % prolog_global_variables_code([]).
4173 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4174 %sbag_member_call(S,L,sysh:mem(S,L)).
4175 sbag_member_call(S,L,'chr sbag_member'(S,L)).
4176 %sbag_member_call(S,L,member(S,L)).
4177 update_mutable_call(A,B,'chr update_mutable'( A, B)).
4178 %update_mutable_call(A,B,setarg(1, B, A)).
4179 create_mutable_call(Value,Mutable,true) :- Mutable = mutable(Value).
4180 % create_mutable_call(Value,Mutable,'chr create_mutable'(Value,Mutable)).
4182 % get_suspension_field(Constraint,Susp,FieldName,Value,(Get0,Get1)) :-
4183 % get_dynamic_suspension_term_field(FieldName,Constraint,Susp,Field,Get0),
4184 % create_get_mutable(Value,Field,Get1).
4186 % update_suspension_field(Constraint,Susp,FieldName,NewValue,(Get,Set)) :-
4187 % get_dynamic_suspension_term_field(FieldName,Constraint,Susp,Field,Get),
4188 % update_mutable_call(NewValue,Field,Set).
4190 % get_update_suspension_field(Constraint,Susp,FieldName,Value,NewValue,Get0,Get1,Set) :-
4191 % get_dynamic_suspension_term_field(FieldName,Constraint,Susp,Field,Get0),
4192 % create_get_mutable_ref(Value,Field,Get1),
4193 % update_mutable_call(NewValue,Field,Set).
4195 % create_static_suspension_field(Constraint,Susp,FieldName,Value,Create) :-
4196 % get_static_suspension_term_field(FieldName,Constraint,Susp,Field),
4197 % create_mutable_call(Value,Field,Create).
4199 % get_static_suspension_field(Constraint,Susp,FieldName,Value,Get) :-
4200 % get_static_suspension_term_field(FieldName,Constraint,Susp,Field),
4201 % create_get_mutable(Value,Field,Get).
4203 % get_update_static_suspension_field(Constraint,Susp,SuspTerm,FieldName,Value,NewValue,Get,Set) :-
4204 % get_static_suspension_term_field(FieldName,Constraint,SuspTerm,Field),
4205 % create_get_mutable_ref(Value,Field,Get),
4206 % update_mutable_call(NewValue,Field,Set).
4208 get_suspension_field(Constraint,Susp,FieldName,Value,Get) :-
4209 get_dynamic_suspension_term_field(FieldName,Constraint,Susp,Value,Get).
4211 update_suspension_field(Constraint,Susp,FieldName,NewValue,Set) :-
4212 set_dynamic_suspension_term_field(FieldName,Constraint,Susp,NewValue,Set).
4214 get_update_suspension_field(Constraint,Susp,FieldName,Value,NewValue,true,Get,Set) :-
4215 get_dynamic_suspension_term_field(FieldName,Constraint,Susp,Value,Get),
4216 set_dynamic_suspension_term_field(FieldName,Constraint,Susp,NewValue,Set).
4218 create_static_suspension_field(Constraint,Susp,FieldName,Value,true) :-
4219 get_static_suspension_term_field(FieldName,Constraint,Susp,Value).
4221 get_static_suspension_field(Constraint,Susp,FieldName,Value,true) :-
4222 get_static_suspension_term_field(FieldName,Constraint,Susp,Value).
4224 get_update_static_suspension_field(Constraint,Susp,SuspTerm,FieldName,Value,NewValue,true,Set) :-
4225 get_static_suspension_term_field(FieldName,Constraint,SuspTerm,Value),
4226 set_dynamic_suspension_term_field(FieldName,Constraint,Susp,NewValue,Set).
4228 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4230 enumerate_stores_code(Constraints,[Clause|List]) :-
4231 Head = '$enumerate_constraints'(Constraint),
4232 Clause = ( Head :- Body),
4233 enumerate_store_bodies(Constraints,Constraint,List),
4237 Body = ( nonvar(Constraint) ->
4238 functor(Constraint,Functor,_),
4239 '$enumerate_constraints'(Functor,Constraint)
4241 '$enumerate_constraints'(_,Constraint)
4245 enumerate_store_bodies([],_,[]).
4246 enumerate_store_bodies([C|Cs],Constraint,L) :-
4248 get_store_type(C,StoreType),
4249 ( enumerate_store_body(StoreType,C,Suspension,SuspensionBody) ->
4252 chr_error(internal,'Could not generate enumeration code for constraint ~w.\n',[C])
4254 get_dynamic_suspension_term_field(arguments,C,Suspension,Arguments,DynamicGoal),
4256 Constraint0 =.. [F|Arguments],
4257 Head = '$enumerate_constraints'(F,Constraint),
4258 Body = (SuspensionBody, DynamicGoal, Constraint = Constraint0),
4259 L = [(Head :- Body)|T]
4263 enumerate_store_bodies(Cs,Constraint,T).
4265 enumerate_store_body(default,C,Susp,Body) :-
4266 global_list_store_name(C,StoreName),
4267 sbag_member_call(Susp,List,Sbag),
4268 make_get_store_goal(StoreName,List,GetStoreGoal),
4271 GetStoreGoal, % nb_getval(StoreName,List),
4274 % get_constraint_index(C,Index),
4275 % get_target_module(Mod),
4276 % get_max_constraint_index(MaxIndex),
4279 % 'chr default_store'(GlobalStore),
4280 % get_attr(GlobalStore,Mod,Attr)
4283 % NIndex is Index + 1,
4284 % sbag_member_call(Susp,List,Sbag),
4287 % arg(NIndex,Attr,List),
4291 % sbag_member_call(Susp,Attr,Sbag),
4294 % Body = (Body1,Body2).
4295 enumerate_store_body(multi_inthash([Index|_]),C,Susp,Body) :-
4296 multi_inthash_enumerate_store_body(Index,C,Susp,Body).
4297 enumerate_store_body(multi_hash([Index|_]),C,Susp,Body) :-
4298 multi_hash_enumerate_store_body(Index,C,Susp,Body).
4299 enumerate_store_body(atomic_constants(Index,Constants,Completeness),C,Susp,Body) :-
4300 Completeness == complete, % fail if incomplete
4301 maplist(enumerate_constant_store_body(C,Index,Susps),Constants,Disjuncts),
4302 list2disj(Disjuncts, Disjunction),
4303 Body = ( Disjunction, member(Susp,Susps) ).
4304 enumerate_constant_store_body(C,Index,Susps,Constant,nb_getval(StoreName,Susps)) :-
4305 constants_store_name(C,Index,Constant,StoreName).
4307 enumerate_store_body(ground_constants(Index,Constants,Completeness),C,Susp,Body) :-
4308 enumerate_store_body(atomic_constants(Index,Constants,Completeness),C,Susp,Body).
4309 enumerate_store_body(global_ground,C,Susp,Body) :-
4310 global_ground_store_name(C,StoreName),
4311 sbag_member_call(Susp,List,Sbag),
4312 make_get_store_goal(StoreName,List,GetStoreGoal),
4315 GetStoreGoal, % nb_getval(StoreName,List),
4318 enumerate_store_body(var_assoc_store(_,_),C,_,Body) :-
4320 enumerate_store_body(global_singleton,C,Susp,Body) :-
4321 global_singleton_store_name(C,StoreName),
4322 make_get_store_goal(StoreName,Susp,GetStoreGoal),
4325 GetStoreGoal, % nb_getval(StoreName,Susp),
4328 enumerate_store_body(multi_store(STs),C,Susp,Body) :-
4329 ( memberchk(global_ground,STs) ->
4330 enumerate_store_body(global_ground,C,Susp,Body)
4334 enumerate_store_body(ST,C,Susp,Body)
4337 enumerate_store_body(identifier_store(Index),C,Susp,Body) :-
4339 enumerate_store_body(type_indexed_identifier_store(Index,IndexType),C,Susp,Body) :-
4342 multi_inthash_enumerate_store_body(I,C,Susp,B) :-
4343 multi_hash_store_name(C,I,StoreName),
4346 nb_getval(StoreName,HT),
4349 multi_hash_enumerate_store_body(I,C,Susp,B) :-
4350 multi_hash_store_name(C,I,StoreName),
4351 make_get_store_goal(StoreName,HT,GetStoreGoal),
4354 GetStoreGoal, % nb_getval(StoreName,HT),
4358 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4359 % BACKGROUND INFORMATION (declared using :- chr_declaration)
4360 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4367 get_bg_info_answer/1.
4369 background_info(X), background_info(Y) <=>
4370 append(X,Y,XY), background_info(XY).
4371 background_info(X) \ get_bg_info(Q) <=> Q=X.
4372 get_bg_info(Q) <=> Q = [].
4374 background_info(T,I), get_bg_info(A,Q) ==>
4375 copy_term_nat(T,T1),
4378 copy_term_nat(T-I,A-X),
4379 get_bg_info_answer([X]).
4380 get_bg_info_answer(X), get_bg_info_answer(Y) <=>
4381 append(X,Y,XY), get_bg_info_answer(XY).
4383 get_bg_info_answer(X) # Id, get_bg_info(A,Q) <=> Q=X pragma passive(Id).
4384 get_bg_info(_,Q) <=> Q=[]. % no info found on this term
4386 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4395 :- chr_option(mode,prev_guard_list(+,+,+,+,+,+,+,+)).
4396 :- chr_option(mode,prev_guard_list(+,+,+,+,+,+)).
4397 :- chr_option(type_declaration,prev_guard_list(any,any,any,any,any,list)).
4398 :- chr_option(mode,simplify_guards(+)).
4399 :- chr_option(mode,set_all_passive(+)).
4401 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4402 % GUARD SIMPLIFICATION
4403 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4404 % If the negation of the guards of earlier rules entails (part of)
4405 % the current guard, the current guard can be simplified. We can only
4406 % use earlier rules with a head that matches if the head of the current
4407 % rule does, and which make it impossible for the current rule to match
4408 % if they fire (i.e. they shouldn't be propagation rules and their
4409 % head constraints must be subsets of those of the current rule).
4410 % At this point, we know for sure that the negation of the guard
4411 % of such a rule has to be true (otherwise the earlier rule would have
4412 % fired, because of the refined operational semantics), so we can use
4413 % that information to simplify the guard by replacing all entailed
4414 % conditions by true/0. As a consequence, the never-stored analysis
4415 % (in a further phase) will detect more cases of never-stored constraints.
4417 % e.g. c(X),d(Y) <=> X > 0 | ...
4418 % e(X) <=> X < 0 | ...
4419 % c(X) \ d(Y),e(Z) <=> X =< 0, Z >= 0, ... | ...
4423 guard_simplification :-
4424 ( chr_pp_flag(guard_simplification,on) ->
4425 precompute_head_matchings,
4431 % for every rule, we create a prev_guard_list where the last argument
4432 % eventually is a list of the negations of earlier guards
4433 rule(RuleNb,Rule) \ simplify_guards(RuleNb)
4435 Rule = pragma(rule(Head1,Head2,Guard,_B),ids(IDs1,IDs2),_Pragmas,_Name,RuleNb),
4436 append(Head1,Head2,Heads),
4437 make_head_matchings_explicit_not_negated(Heads,MatchingFreeHeads,Matchings),
4438 tree_set_empty(Done),
4439 multiple_occ_constraints_checked(Done),
4440 apply_guard_wrt_term(Heads,Guard,SubstitutedHeads),
4442 append(IDs1,IDs2,IDs),
4443 findall(tuple(C,O,RuleNb)-(-RuleNb),(member(ID,IDs),get_occurrence_from_id(C,O,RuleNb,ID)),HeapData),
4445 insert_list_q(HeapData,EmptyHeap,Heap),
4446 next_prev_rule(Heap,_,Heap1),
4447 next_prev_rule(Heap1,PrevRuleNb,NHeap),
4448 prev_guard_list(RuleNb,PrevRuleNb,NHeap,MatchingFreeHeads,Guard,[],Matchings,[SubstitutedHeads]),
4449 NextRule is RuleNb+1,
4450 simplify_guards(NextRule).
4452 next_prev_rule(Heap,RuleNb,NHeap) :-
4453 ( find_min_q(Heap,_-Priority) ->
4454 Priority = (-RuleNb),
4455 normalize_heap(Heap,Priority,NHeap)
4461 normalize_heap(Heap,Priority,NHeap) :-
4462 ( find_min_q(Heap,_-Priority) ->
4463 delete_min_q(Heap,Heap1,tuple(C,O,_)-_),
4466 get_occurrence(C,NO,RuleNb,_),
4467 insert_q(Heap1,tuple(C,NO,RuleNb)-(-RuleNb),Heap2)
4471 normalize_heap(Heap2,Priority,NHeap)
4481 % The negation of the guard of a non-propagation rule is added
4482 % if its kept head constraints are a subset of the kept constraints of
4483 % the rule we're working on, and its removed head constraints (at least one)
4484 % are a subset of the removed constraints.
4486 rule(PrevRuleNb,PrevRule) \ prev_guard_list(RuleNb,PrevRuleNb,Heap,CurrentHeads,G,GuardList,Matchings,GH)
4488 PrevRule = pragma(rule(H1,H2,PrevGuard,_B),_Ids,_Pragmas,_Name,_PrevRuleNb), % PrevRuleNb == _PrevRuleNb
4490 make_head_matchings_explicit(PrevRuleNb,MatchingFreeHeads,PrevMatchings),
4491 setof(Renaming,chr_translate:head_subset(MatchingFreeHeads,CurrentHeads,Renaming),Renamings)
4493 append(H1,H2,Heads),
4494 compute_derived_info(Renamings,PrevMatchings,MatchingFreeHeads,Heads,PrevGuard,Matchings,CurrentHeads,GH,DerivedInfo,GH_New1),
4495 append(GuardList,DerivedInfo,GL1),
4496 normalize_conj_list(GL1,GL),
4497 append(GH_New1,GH,GH1),
4498 normalize_conj_list(GH1,GH_New),
4499 next_prev_rule(Heap,PrevPrevRuleNb,NHeap),
4500 % PrevPrevRuleNb is PrevRuleNb-1,
4501 prev_guard_list(RuleNb,PrevPrevRuleNb,NHeap,CurrentHeads,G,GL,Matchings,GH_New).
4503 % if this isn't the case, we skip this one and try the next rule
4504 prev_guard_list(RuleNb,N,Heap,H,G,GuardList,M,GH)
4507 next_prev_rule(Heap,N1,NHeap),
4509 prev_guard_list(RuleNb,N1,NHeap,H,G,GuardList,M,GH)
4511 prev_guard_list(RuleNb,H,G,GuardList,M,GH)
4514 prev_guard_list(RuleNb,H,G,GuardList,M,GH)
4518 head_types_modes_condition(GH,H,TypeInfo),
4519 conj2list(TypeInfo,TI),
4520 term_variables(H,HeadVars),
4521 append([chr_pp_headvariables(HeadVars)|TI],GuardList,Info),
4522 normalize_conj_list(Info,InfoL),
4523 append(H,InfoL,RelevantTerms),
4524 add_background_info([G|RelevantTerms],BGInfo),
4525 append(InfoL,BGInfo,AllInfo_),
4526 normalize_conj_list(AllInfo_,AllInfo),
4527 prev_guard_list(RuleNb,H,G,AllInfo,M,[]).
4529 head_types_modes_condition([],H,true).
4530 head_types_modes_condition([GH|GHs],H,(TI1, TI2)) :-
4531 types_modes_condition(H,GH,TI1),
4532 head_types_modes_condition(GHs,H,TI2).
4534 add_background_info(Term,Info) :-
4535 get_bg_info(GeneralInfo),
4536 add_background_info2(Term,TermInfo),
4537 append(GeneralInfo,TermInfo,Info).
4539 add_background_info2(X,[]) :- var(X), !.
4540 add_background_info2([],[]) :- !.
4541 add_background_info2([X|Xs],Info) :- !,
4542 add_background_info2(X,Info1),
4543 add_background_info2(Xs,Infos),
4544 append(Info1,Infos,Info).
4546 add_background_info2(X,Info) :-
4547 (functor(X,_,A), A>0 ->
4549 add_background_info2(XArgs,XArgInfo)
4553 get_bg_info(X,XInfo),
4554 append(XInfo,XArgInfo,Info).
4557 % when all earlier guards are added or skipped, we simplify the guard.
4558 % if it's different from the original one, we change the rule
4560 prev_guard_list(RuleNb,H,G,GuardList,M,[]), rule(RuleNb,Rule)
4562 Rule = pragma(rule(Head1,Head2,G,B),Ids,Pragmas,Name,RuleNb),
4563 G \== true, % let's not try to simplify this ;)
4564 append(M,GuardList,Info),
4565 (% if guard + context is a contradiction, it should be simplified to "fail"
4566 conj2list(G,GL), append(Info,GL,GuardWithContext),
4567 guard_entailment:entails_guard(GuardWithContext,fail) ->
4570 % otherwise we try to remove redundant conjuncts
4571 simplify_guard(G,B,Info,SimpleGuard,NB)
4573 G \== SimpleGuard % only do this if we can change the guard
4575 rule(RuleNb,pragma(rule(Head1,Head2,SimpleGuard,NB),Ids,Pragmas,Name,RuleNb)),
4576 prev_guard_list(RuleNb,H,SimpleGuard,GuardList,M,[]).
4578 %% normalize_conj_list(+List,-NormalList) is det.
4580 % Removes =true= elements and flattens out conjunctions.
4582 normalize_conj_list(List,NormalList) :-
4583 list2conj(List,Conj),
4584 conj2list(Conj,NormalList).
4586 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4587 % AUXILIARY PREDICATES (GUARD SIMPLIFICATION)
4588 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4590 compute_derived_info([],_PrevMatchings,_MatchingFreeHeads,_Heads,_PrevGuard,_Matchings,_H,_GH,[],[]).
4591 compute_derived_info([Renaming1|RestRenamings],PrevMatchings,PrevMatchingFreeHeads,PrevHeads,PrevGuard,Matchings,H,GH,[DerivedInfo1|DerivedInfo2],[GH3|GH_New2]) :-
4592 copy_term(PrevMatchings-PrevGuard,FreshMatchings),
4593 variable_replacement(PrevMatchings-PrevGuard,FreshMatchings,ExtraRenaming),
4594 append(Renaming1,ExtraRenaming,Renaming2),
4595 list2conj(PrevMatchings,Match),
4596 negate_b(Match,HeadsDontMatch),
4597 make_head_matchings_explicit_not_negated2(PrevHeads,PrevMatchingFreeHeads,HeadsMatch),
4598 list2conj(HeadsMatch,HeadsMatchBut),
4599 term_variables(Renaming2,RenVars),
4600 term_variables(PrevMatchings-PrevGuard-HeadsMatch,MGVars),
4601 new_vars(MGVars,RenVars,ExtraRenaming2),
4602 append(Renaming2,ExtraRenaming2,Renaming),
4603 ( PrevGuard == true -> % true can't fail
4604 Info_ = HeadsDontMatch
4606 negate_b(PrevGuard,TheGuardFailed),
4607 Info_ = (HeadsDontMatch ; (HeadsMatchBut, TheGuardFailed))
4609 copy_with_variable_replacement(Info_,DerivedInfo1,Renaming),
4610 copy_with_variable_replacement(PrevGuard,RenamedG2,Renaming),
4611 copy_with_variable_replacement(PrevMatchings,RenamedMatchings_,Renaming),
4612 list2conj(RenamedMatchings_,RenamedMatchings),
4613 apply_guard_wrt_term(H,RenamedG2,GH2),
4614 apply_guard_wrt_term(GH2,RenamedMatchings,GH3),
4615 compute_derived_info(RestRenamings,PrevMatchings,PrevMatchingFreeHeads,PrevHeads,PrevGuard,Matchings,H,GH,DerivedInfo2,GH_New2).
4617 simplify_guard(G,B,Info,SG,NB) :-
4619 % writeq(guard_entailment:simplify_guards(Info,B,LG,SGL,NB)),nl,
4620 guard_entailment:simplify_guards(Info,B,LG,SGL,NB),
4625 new_vars([A|As],RV,ER) :-
4626 ( memberchk_eq(A,RV) ->
4629 ER = [A-NewA,NewA-A|ER2],
4633 %% head_subset(+Subset,+MultiSet,-Renaming) is nondet.
4635 % check if a list of constraints is a subset of another list of constraints
4636 % (multiset-subset), meanwhile computing a variable renaming to convert
4637 % one into the other.
4638 head_subset(H,Head,Renaming) :-
4639 head_subset(H,Head,Renaming,[],_).
4641 head_subset([],Remainder,Renaming,Renaming,Remainder).
4642 head_subset([X|Xs],MultiSet,Renaming,Acc,Remainder) :-
4643 head_member(MultiSet,X,NAcc,Acc,Remainder1),
4644 head_subset(Xs,Remainder1,Renaming,NAcc,Remainder).
4646 % check if A is in the list, remove it from Headleft
4647 head_member([X|Xs],A,Renaming,Acc,Remainder) :-
4648 ( variable_replacement(A,X,Acc,Renaming),
4651 Remainder = [X|RRemainder],
4652 head_member(Xs,A,Renaming,Acc,RRemainder)
4654 %-------------------------------------------------------------------------------%
4655 % memoing code to speed up repeated computation
4657 :- chr_constraint precompute_head_matchings/0.
4659 rule(RuleNb,PragmaRule), precompute_head_matchings ==>
4660 PragmaRule = pragma(rule(H1,H2,_G,_B),_Ids,_Pragmas,_Name,_PrevRuleNb),
4661 append(H1,H2,Heads),
4662 make_head_matchings_explicit_(Heads,MatchingFreeHeads,Matchings),
4663 copy_term_nat(MatchingFreeHeads-Matchings,A-B),
4664 make_head_matchings_explicit_memo_table(RuleNb,A,B).
4666 precompute_head_matchings <=> true.
4668 :- chr_constraint make_head_matchings_explicit_memo_table/3.
4669 :- chr_constraint make_head_matchings_explicit_memo_lookup/3.
4671 :- chr_option(mode,make_head_matchings_explicit_memo_table(+,?,?)).
4672 :- chr_option(mode,make_head_matchings_explicit_memo_lookup(+,?,?)).
4674 make_head_matchings_explicit_memo_table(RuleNb,NHeads,Matchings) \
4675 make_head_matchings_explicit_memo_lookup(RuleNb,Q1,Q2)
4679 make_head_matchings_explicit_memo_lookup(_,_,_) <=> fail.
4681 make_head_matchings_explicit(RuleNb,MatchingFreeHeads,Matchings) :-
4682 make_head_matchings_explicit_memo_lookup(RuleNb,A,B),
4683 copy_term_nat(A-B,MatchingFreeHeads-Matchings).
4684 %-------------------------------------------------------------------------------%
4686 make_head_matchings_explicit_(Heads,MatchingFreeHeads,Matchings) :-
4687 extract_arguments(Heads,Arguments),
4688 make_matchings_explicit(Arguments,FreeVariables,[],[],_,Matchings),
4689 substitute_arguments(Heads,FreeVariables,MatchingFreeHeads).
4691 make_head_matchings_explicit_not_negated(Heads,MatchingFreeHeads,Matchings) :-
4692 extract_arguments(Heads,Arguments),
4693 make_matchings_explicit_not_negated(Arguments,FreshVariables,Matchings),
4694 substitute_arguments(Heads,FreshVariables,MatchingFreeHeads).
4696 make_head_matchings_explicit_not_negated2(Heads,MatchingFreeHeads,Matchings) :-
4697 extract_arguments(Heads,Arguments1),
4698 extract_arguments(MatchingFreeHeads,Arguments2),
4699 make_matchings_explicit_not_negated(Arguments1,Arguments2,Matchings).
4701 %% extract_arguments(+ListOfConstraints,-ListOfVariables) is det.
4703 % Returns list of arguments of given list of constraints.
4704 extract_arguments([],[]).
4705 extract_arguments([Constraint|Constraints],AllArguments) :-
4706 Constraint =.. [_|Arguments],
4707 append(Arguments,RestArguments,AllArguments),
4708 extract_arguments(Constraints,RestArguments).
4710 %% substitute_arguments(+InListOfConstraints,ListOfVariables,-OutListOfConstraints) is det.
4712 % Substitutes arguments of constraints with those in the given list.
4714 substitute_arguments([],[],[]).
4715 substitute_arguments([Constraint|Constraints],Variables,[NConstraint|NConstraints]) :-
4716 functor(Constraint,F,N),
4717 split_at(N,Variables,Arguments,RestVariables),
4718 NConstraint =.. [F|Arguments],
4719 substitute_arguments(Constraints,RestVariables,NConstraints).
4721 make_matchings_explicit([],[],_,MC,MC,[]).
4722 make_matchings_explicit([Arg|Args],[NewVar|NewVars],VarAcc,MatchingCondition,MatchingConditionO,Matchings) :-
4724 ( memberchk_eq(Arg,VarAcc) ->
4725 list2disj(MatchingCondition,MatchingCondition_disj),
4726 Matchings = [(MatchingCondition_disj ; NewVar == Arg)|RestMatchings], % or only = ??
4729 Matchings = RestMatchings,
4731 NVarAcc = [Arg|VarAcc]
4733 MatchingCondition2 = MatchingCondition
4736 Arg =.. [F|RecArgs],
4737 make_matchings_explicit(RecArgs,RecVars,VarAcc,MatchingCondition,MatchingCondition_,RecMatchings),
4738 FlatArg =.. [F|RecVars],
4739 ( RecMatchings == [] ->
4740 Matchings = [functor(NewVar,F,A)|RestMatchings]
4742 list2conj(RecMatchings,ArgM_conj),
4743 list2disj(MatchingCondition,MatchingCondition_disj),
4744 ArgM_ = (NewVar \= FlatArg ; MatchingCondition_disj ; ArgM_conj),
4745 Matchings = [ functor(NewVar,F,A) , ArgM_|RestMatchings]
4747 MatchingCondition2 = [ NewVar \= FlatArg |MatchingCondition_],
4748 term_variables(Args,ArgVars),
4749 append(ArgVars,VarAcc,NVarAcc)
4751 make_matchings_explicit(Args,NewVars,NVarAcc,MatchingCondition2,MatchingConditionO,RestMatchings).
4754 %% make_matchings_explicit_not_negated(+ListOfTerms,-ListOfVariables,-ListOfMatchings) is det.
4756 % Returns list of new variables and list of pairwise unifications between given list and variables.
4758 make_matchings_explicit_not_negated([],[],[]).
4759 make_matchings_explicit_not_negated([X|Xs],[Var|Vars],Matchings) :-
4760 Matchings = [Var = X|RMatchings],
4761 make_matchings_explicit_not_negated(Xs,Vars,RMatchings).
4763 %% apply_guard_wrt_term(+ListOfConstraints,+Goal,-NewListOfConstraints) is det.
4765 % (Partially) applies substitutions of =Goal= to given list.
4767 apply_guard_wrt_term([],_Guard,[]).
4768 apply_guard_wrt_term([Term|RH],Guard,[NTerm|RGH]) :-
4770 apply_guard_wrt_variable(Guard,Term,NTerm)
4773 apply_guard_wrt_term(HArgs,Guard,NewHArgs),
4774 NTerm =.. [F|NewHArgs]
4776 apply_guard_wrt_term(RH,Guard,RGH).
4778 %% apply_guard_wrt_variable(+Goal,+Variable,-NVariable) is det.
4780 % (Partially) applies goal =Guard= wrt variable.
4782 apply_guard_wrt_variable((Guard1,Guard2),Variable,NVariable) :- !,
4783 apply_guard_wrt_variable(Guard1,Variable,NVariable1),
4784 apply_guard_wrt_variable(Guard2,NVariable1,NVariable).
4785 apply_guard_wrt_variable(Guard,Variable,NVariable) :-
4786 ( Guard = (X = Y), Variable == X ->
4788 ; Guard = functor(AVariable,Functor,Arity), Variable == AVariable, ground(Functor), ground(Arity) ->
4789 functor(NVariable,Functor,Arity)
4791 NVariable = Variable
4795 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4796 % ALWAYS FAILING GUARDS
4797 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4799 prev_guard_list(RuleNb,H,G,GuardList,M,[]),rule(RuleNb,Rule)
4801 chr_pp_flag(check_impossible_rules,on),
4802 Rule = pragma(rule(_,_,G,_),_Ids,_Pragmas,_Name,RuleNb),
4804 append(M,GuardList,Info),
4805 append(Info,GL,GuardWithContext),
4806 guard_entailment:entails_guard(GuardWithContext,fail)
4808 chr_warning(weird_program,'Heads will never match or guard will always fail in ~@.\n\tThis rule will never fire!\n',[format_rule(Rule)]),
4809 set_all_passive(RuleNb).
4811 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4812 % HEAD SIMPLIFICATION
4813 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4815 % now we check the head matchings (guard may have been simplified meanwhile)
4816 prev_guard_list(RuleNb,H,G,GuardList,M,[]) \ rule(RuleNb,Rule)
4818 Rule = pragma(rule(Head1,Head2,G,B),Ids,Pragmas,Name,RuleNb),
4819 simplify_heads(M,GuardList,G,B,NewM,NewB),
4821 extract_arguments(Head1,VH1),
4822 extract_arguments(Head2,VH2),
4823 extract_arguments(H,VH),
4824 replace_some_heads(VH1,VH2,VH,NewM,H1,H2,G,B,NewB_),
4825 substitute_arguments(Head1,H1,NewH1),
4826 substitute_arguments(Head2,H2,NewH2),
4827 append(NewB,NewB_,NewBody),
4828 list2conj(NewBody,BodyMatchings),
4829 NewRule = pragma(rule(NewH1,NewH2,G,(BodyMatchings,B)),Ids,Pragmas,Name,RuleNb),
4830 (Head1 \== NewH1 ; Head2 \== NewH2 )
4832 rule(RuleNb,NewRule).
4834 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4835 % AUXILIARY PREDICATES (HEAD SIMPLIFICATION)
4836 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4838 replace_some_heads(H1,H2,NH,[],H1,H2,G,Body,[]) :- !.
4839 replace_some_heads([],[H2|RH2],[NH|RNH],[M|RM],[],[H2_|RH2_],G,Body,NewB) :- !,
4842 replace_some_heads([],RH2,RNH,RM,[],RH2_,G,Body,NewB)
4844 (M = functor(X,F,A), NH == X ->
4850 H2 =.. [F|OrigArgs],
4851 use_same_args(OrigArgs,A_args,A_args_,G,Body,NewB1),
4854 replace_some_heads([],RH2,RNH,RM,[],RH2_,G,Body,NewB2),
4855 append(NewB1,NewB2,NewB)
4858 replace_some_heads([],RH2,RNH,[M|RM],[],RH2_,G,Body,NewB)
4862 replace_some_heads([H1|RH1],H2,[NH|RNH],[M|RM],[H1_|RH1_],H2_,G,Body,NewB) :- !,
4865 replace_some_heads(RH1,H2,RNH,RM,RH1_,H2_,G,Body,NewB)
4867 (M = functor(X,F,A), NH == X ->
4873 H1 =.. [F|OrigArgs],
4874 use_same_args(OrigArgs,A_args,A_args_,G,Body,NewB1),
4877 replace_some_heads(RH1,H2,RNH,RM,RH1_,H2_,G,Body,NewB2),
4878 append(NewB1,NewB2,NewB)
4881 replace_some_heads(RH1,H2,RNH,[M|RM],RH1_,H2_,G,Body,NewB)
4885 use_same_args([],[],[],_,_,[]).
4886 use_same_args([OA|ROA],[NA|RNA],[Out|ROut],G,Body,NewB) :-
4889 use_same_args(ROA,RNA,ROut,G,Body,NewB).
4890 use_same_args([OA|ROA],[NA|RNA],[Out|ROut],G,Body,NewB) :-
4892 ( common_variables(OA,Body) ->
4893 NewB = [NA = OA|NextB]
4898 use_same_args(ROA,RNA,ROut,G,Body,NextB).
4901 simplify_heads([],_GuardList,_G,_Body,[],[]).
4902 simplify_heads([M|RM],GuardList,G,Body,NewM,NewB) :-
4904 ( (nonvar(B) ; common_variables(B,RM-GuardList)),
4905 guard_entailment:entails_guard(GuardList,(A=B)) ->
4906 ( common_variables(B,G-RM-GuardList) ->
4910 ( common_variables(B,Body) ->
4911 NewB = [A = B|NextB]
4918 ( nonvar(B), functor(B,BFu,BAr),
4919 guard_entailment:entails_guard([functor(A,BFu,BAr)|GuardList],(A=B)) ->
4921 ( common_variables(B,G-RM-GuardList) ->
4924 NewM = [functor(A,BFu,BAr)|NextM]
4931 simplify_heads(RM,[M|GuardList],G,Body,NextM,NextB).
4933 common_variables(B,G) :-
4934 term_variables(B,BVars),
4935 term_variables(G,GVars),
4936 intersect_eq(BVars,GVars,L),
4940 set_all_passive(RuleNb), occurrence(_,_,RuleNb,ID,_) ==> passive(RuleNb,ID).
4941 set_all_passive(_) <=> true.
4945 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4946 % OCCURRENCE SUBSUMPTION
4947 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4950 first_occ_in_rule/4,
4953 :- chr_option(mode,first_occ_in_rule(+,+,+,+)).
4954 :- chr_option(mode,next_occ_in_rule(+,+,+,+,+,+)).
4956 :- chr_constraint multiple_occ_constraints_checked/1.
4957 :- chr_option(mode,multiple_occ_constraints_checked(+)).
4959 prev_guard_list(RuleNb,H,G,GuardList,M,[]),
4960 occurrence(C,O,RuleNb,ID,_),
4961 occurrence(C,O2,RuleNb,ID2,_),
4964 multiple_occ_constraints_checked(Done)
4967 chr_pp_flag(occurrence_subsumption,on),
4968 Rule = pragma(rule(H1,H2,_G,_B),_Ids,_Pragmas,_Name,_RuleNb), % RuleNb == _RuleNb
4970 \+ tree_set_memberchk(C,Done)
4972 first_occ_in_rule(RuleNb,C,O,ID),
4973 tree_set_add(Done,C,NDone),
4974 multiple_occ_constraints_checked(NDone).
4976 % Find first occurrence of constraint =C= in rule =RuleNb=
4977 occurrence(C,O,RuleNb,ID,_) \ first_occ_in_rule(RuleNb,C,O2,_)
4981 first_occ_in_rule(RuleNb,C,O,ID).
4983 first_occ_in_rule(RuleNb,C,O,ID_o1)
4986 functor(FreshHead,F,A),
4987 next_occ_in_rule(RuleNb,C,O,ID_o1,[],FreshHead).
4989 % Skip passive occurrences.
4990 passive(RuleNb,ID_o2), occurrence(C,O2,RuleNb,ID_o2,_) \ next_occ_in_rule(RuleNb,C,O,ID_o1,Cond,FH)
4994 next_occ_in_rule(RuleNb,C,O2,ID_o1,NewCond,FH).
4996 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)
4999 Rule = pragma(rule(H1,H2,G,B),ids(ID1,ID2),_Pragmas,_Name,RuleNb)
5001 append(H1,H2,Heads),
5002 add_failing_occ(Rule,Heads,H,ID_o1,ExtraCond,FH,M,C,Repl),
5003 ( ExtraCond == [chr_pp_void_info] ->
5004 next_occ_in_rule(RuleNb,C,O2,ID_o2,Cond,FH)
5006 append(ExtraCond,Cond,NewCond),
5007 add_failing_occ(Rule,Heads,H,ID_o2,CheckCond,FH,M,C,Repl2),
5008 copy_term(GuardList,FGuardList),
5009 variable_replacement(GuardList,FGuardList,GLRepl),
5010 copy_with_variable_replacement(GuardList,GuardList2,Repl),
5011 copy_with_variable_replacement(GuardList,GuardList3_,Repl2),
5012 copy_with_variable_replacement(GuardList3_,GuardList3,GLRepl),
5013 append(NewCond,GuardList2,BigCond),
5014 append(BigCond,GuardList3,BigCond2),
5015 copy_with_variable_replacement(M,M2,Repl),
5016 copy_with_variable_replacement(M,M3,Repl2),
5017 append(M3,BigCond2,BigCond3),
5018 append([chr_pp_active_constraint(FH)|M2],BigCond3,Info),
5019 list2conj(CheckCond,OccSubsum),
5020 copy_term((NewCond,BigCond2,Info,OccSubsum,FH),(NewCond2,BigCond2_,Info2,OccSubsum2,FH2)),
5021 ( OccSubsum \= chr_pp_void_info ->
5022 ( guard_entailment:entails_guard(Info2,OccSubsum2) ->
5023 passive(RuleNb,ID_o2)
5030 next_occ_in_rule(RuleNb,C,O2,ID_o2,NewCond,FH)
5034 next_occ_in_rule(RuleNb,C,O,ID,Cond,Args)
5038 prev_guard_list(RuleNb,H,G,GuardList,M,[]), multiple_occ_constraints_checked(Done)
5042 add_failing_occ(Rule,Heads,NH,ID_o1,FailCond,FH,M,C,Repl) :-
5043 Rule = pragma(rule(H1,H2,G,B),ids(ID1,ID2),_Pragmas,_Name,RuleNb),
5044 append(ID2,ID1,IDs),
5045 missing_partner_cond(Heads,NH,IDs,ID_o1,MPCond,H,C),
5046 copy_term((H,Heads,NH),(FH2,FHeads,NH2)),
5047 variable_replacement((H,Heads,NH),(FH2,FHeads,NH2),Repl),
5048 copy_with_variable_replacement(G,FG,Repl),
5049 extract_explicit_matchings(FG,FG2),
5050 negate_b(FG2,NotFG),
5051 copy_with_variable_replacement(MPCond,FMPCond,Repl),
5052 ( subsumes(FH,FH2) ->
5053 FailCond = [(NotFG;FMPCond)]
5055 % in this case, not much can be done
5056 % e.g. c(f(...)), c(g(...)) <=> ...
5057 FailCond = [chr_pp_void_info]
5060 missing_partner_cond([],[],[],ID_o1,fail,H2,C).
5061 missing_partner_cond([H|Hs],[H2|H2s],[ID_o1|IDs],ID_o1,Cond,H,C) :- !,
5062 missing_partner_cond(Hs,H2s,IDs,ID_o1,Cond,H,C).
5063 missing_partner_cond([H|Hs],[NH|NHs],[ID|IDs],ID_o1,Cond,H2,F/A) :-
5064 Cond = (chr_pp_not_in_store(H);Cond1),
5065 missing_partner_cond(Hs,NHs,IDs,ID_o1,Cond1,H2,F/A).
5067 extract_explicit_matchings((A,B),D) :- !,
5068 ( extract_explicit_matchings(A) ->
5069 extract_explicit_matchings(B,D)
5072 extract_explicit_matchings(B,E)
5074 extract_explicit_matchings(A,D) :- !,
5075 ( extract_explicit_matchings(A) ->
5081 extract_explicit_matchings(A=B) :-
5082 var(A), var(B), !, A=B.
5083 extract_explicit_matchings(A==B) :-
5084 var(A), var(B), !, A=B.
5086 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5088 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5094 get_type_definition/2,
5095 get_constraint_type/2.
5098 :- chr_option(mode,type_definition(?,?)).
5099 :- chr_option(mode,get_type_definition(?,?)).
5100 :- chr_option(mode,type_alias(?,?)).
5101 :- chr_option(mode,constraint_type(+,+)).
5102 :- chr_option(mode,get_constraint_type(+,-)).
5104 assert_constraint_type(Constraint,ArgTypes) :-
5105 ( ground(ArgTypes) ->
5106 constraint_type(Constraint,ArgTypes)
5108 chr_error(type_error,'Declared argument types "~w" for constraint "~w" must be ground!\n',[ArgTypes,Constraint])
5111 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5112 % Consistency checks of type aliases
5114 type_alias(T1,T2) <=>
5117 chr_error(type_error,'Variable alias definition: "~w".\n',[(:- chr_type T1 == T2)]).
5119 type_alias(T1,T2) <=>
5122 chr_error(type_error,'Variable alias definition: "~w".\n',[(:- chr_type T1 == T2)]).
5124 type_alias(T,T2) <=>
5127 copy_term((T,T2),(X,Y)), subsumes(X,Y)
5129 chr_error(type_error,'Cyclic alias definition: "~w".\n',[(T == T2)]).
5131 type_alias(T1,A1), type_alias(T2,A2) <=>
5136 copy_term_nat(T1,T1_),
5137 copy_term_nat(T2,T2_),
5139 chr_error(type_error,
5140 '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_]).
5142 type_alias(T,B) \ type_alias(X,T2) <=>
5145 copy_term_nat((X,T2,T,B),(X2,T3,T1,D1)),
5148 % chr_info(type_information,'Inferring `~w\' from `~w\' and `~w\'.\n',[X2==D1,X==T2,T==B]),
5151 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5152 % Consistency checks of type definitions
5154 type_definition(T1,_), type_definition(T2,_)
5156 functor(T1,F,A), functor(T2,F,A)
5158 chr_error(type_error,'Multiple definitions for type: ~w/~w.\n',[F,A]).
5160 type_definition(T1,_), type_alias(T2,_)
5162 functor(T1,F,A), functor(T2,F,A)
5164 chr_error(type_error,'Multiple definitions for type, once in a type definition and once as a type alias: ~w/~w.\n',[F,A]).
5166 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5167 %% get_type_definition(+Type,-Definition) is semidet.
5168 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5170 get_type_definition(T,Def)
5174 chr_error(type_error,'Non-ground type in constraint definition: "~w".\n',[T]).
5176 type_alias(T,D) \ get_type_definition(T2,Def)
5178 nonvar(T),nonvar(T2),functor(T,F,A),functor(T2,F,A),
5179 copy_term_nat((T,D),(T1,D1)),T1=T2
5181 ( get_type_definition(D1,Def) ->
5184 chr_error(type_error,'Could not find type definition for "~w" (accessed via alias "~w").\n',[D1,T1]), fail
5187 type_definition(T,D) \ get_type_definition(T2,Def)
5189 nonvar(T),nonvar(T2),functor(T,F,A),functor(T2,F,A),
5190 copy_term_nat((T,D),(T1,D1)),T1=T2
5194 get_type_definition(Type,Def)
5196 atomic_builtin_type(Type,_,_)
5200 get_type_definition(Type,Def)
5202 compound_builtin_type(Type,_,_,_)
5206 get_type_definition(X,Y) <=> fail.
5208 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5209 %% get_type_definition_det(+Type,-Definition) is det.
5210 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5211 get_type_definition_det(Type,Definition) :-
5212 ( get_type_definition(Type,Definition) ->
5215 chr_error(type,'Could not find type definition for type `~w\'.\n',[Type])
5218 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5219 %% get_constraint_type(+ConstraintSymbol,-Types) is semidet.
5221 % Return argument types of =ConstraintSymbol=, but fails if none where
5223 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5224 constraint_type(C,T) \ get_constraint_type(C,Type) <=> Type = T.
5225 get_constraint_type(_,_) <=> fail.
5227 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5228 %% get_constraint_type_det(+ConstraintSymbol,-Types) is det.
5230 % Like =get_constraint_type/2=, but returns list of =any= types when
5231 % no types are declared.
5232 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5233 get_constraint_type_det(ConstraintSymbol,Types) :-
5234 ( get_constraint_type(ConstraintSymbol,Types) ->
5237 ConstraintSymbol = _ / N,
5238 replicate(N,any,Types)
5240 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5241 %% unalias_type(+Alias,-Type) is det.
5243 % Follows alias chain until base type is reached.
5244 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5245 :- chr_constraint unalias_type/2.
5248 unalias_type(Alias,BaseType)
5255 type_alias(AliasProtoType,ProtoType) \ unalias_type(Alias,BaseType)
5257 nonvar(AliasProtoType),
5259 functor(AliasProtoType,F,A),
5261 copy_term_nat((AliasProtoType,ProtoType),(AliasInstance,Type)),
5262 Alias = AliasInstance
5264 unalias_type(Type,BaseType).
5266 unalias_type_definition @
5267 type_definition(ProtoType,Definition) \ unalias_type(Alias,BaseType)
5271 functor(ProtoType,F,A),
5276 unalias_atomic_builtin @
5277 unalias_type(Alias,BaseType)
5279 atomic_builtin_type(Alias,_,_)
5283 unalias_compound_builtin @
5284 unalias_type(Alias,BaseType)
5286 compound_builtin_type(Alias,_,_,_)
5290 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5291 %% types_modes_condition(+Heads,+UnrollHeads,-Condition) is det.
5292 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5293 :- chr_constraint types_modes_condition/3.
5294 :- chr_option(mode,types_modes_condition(+,+,?)).
5295 :- chr_option(type_declaration,types_modes_condition(list,list,goal)).
5297 types_modes_condition([],[],T) <=> T=true.
5299 constraint_mode(F/A,Modes) \ types_modes_condition([Head|Heads],[UnrollHead|UnrollHeads],Condition)
5304 Condition = (ModesCondition, TypesCondition, RestCondition),
5305 modes_condition(Modes,Args,ModesCondition),
5306 get_constraint_type_det(F/A,Types),
5307 UnrollHead =.. [_|RealArgs],
5308 types_condition(Types,Args,RealArgs,Modes,TypesCondition),
5309 types_modes_condition(Heads,UnrollHeads,RestCondition).
5311 types_modes_condition([Head|_],_,_)
5314 chr_error(internal,'Mode information missing for ~w.\n',[F/A]).
5317 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5318 %% modes_condition(+Modes,+Args,-Condition) is det.
5320 % Return =Condition= on =Args= that checks =Modes=.
5321 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5322 modes_condition([],[],true).
5323 modes_condition([Mode|Modes],[Arg|Args],Condition) :-
5325 Condition = ( ground(Arg) , RCondition )
5327 Condition = ( var(Arg) , RCondition )
5329 Condition = RCondition
5331 modes_condition(Modes,Args,RCondition).
5333 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5334 %% types_condition(+Types,+Args,+UnrollArgs,+Modes,-Condition) is det.
5336 % Return =Condition= on =Args= that checks =Types= given =Modes=.
5337 % =UnrollArgs= controls the depth of type definition unrolling.
5338 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5339 types_condition([],[],[],[],true).
5340 types_condition([Type|Types],[Arg|Args],[UnrollArg|UnrollArgs],[Mode|Modes],(DisjTypeConditionList,RCondition)) :-
5342 TypeConditionList = [true] % TypeConditionList = [var(Arg)] already encoded in modes_condition
5344 get_type_definition_det(Type,Def),
5345 type_condition(Def,Arg,UnrollArg,Mode,TypeConditionList1),
5347 TypeConditionList = TypeConditionList1
5349 TypeConditionList = [(\+ ground(Arg))|TypeConditionList1]
5352 list2disj(TypeConditionList,DisjTypeConditionList),
5353 types_condition(Types,Args,UnrollArgs,Modes,RCondition).
5355 type_condition([],_,_,_,[]).
5356 type_condition([DefCase|DefCases],Arg,UnrollArg,Mode,[Condition|Conditions]) :-
5358 chr_error(type,'Unexpected variable type in type definition!\n',[]) % Condition = true
5359 ; atomic_builtin_type(DefCase,Arg,Condition) ->
5361 ; compound_builtin_type(DefCase,Arg,Condition,_) ->
5364 type_def_case_condition(DefCase,Arg,UnrollArg,Mode,Condition)
5366 type_condition(DefCases,Arg,UnrollArg,Mode,Conditions).
5368 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5369 :- chr_type atomic_builtin_type ---> any
5376 ; chr_identifier(any)
5377 ; /* all possible values are given */
5379 ; /* all possible values appear in rule heads;
5380 to distinguish between multiple chr_constants
5383 ; /* all relevant values appear in rule heads;
5384 for other values a handler is provided */
5385 chr_constants(any,any).
5386 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5388 atomic_builtin_type(any,_Arg,true).
5389 atomic_builtin_type(dense_int,Arg,(integer(Arg),Arg>=0)).
5390 atomic_builtin_type(int,Arg,integer(Arg)).
5391 atomic_builtin_type(number,Arg,number(Arg)).
5392 atomic_builtin_type(float,Arg,float(Arg)).
5393 atomic_builtin_type(natural,Arg,(integer(Arg),Arg>=0)).
5394 atomic_builtin_type(chr_identifier,_Arg,true).
5396 compound_builtin_type(chr_constants(_),_Arg,true,true).
5397 compound_builtin_type(chr_constants(_,_),_Arg,true,true).
5398 compound_builtin_type(chr_identifier(_),_Arg,true,true).
5399 compound_builtin_type(chr_enum(Constants),Arg,(ground(Arg), memberchk(Arg,Constants)),
5400 once(( member(Constant,Constants),
5401 unifiable(Arg,Constant,_)
5406 is_chr_constants_type(chr_constants(Key),Key,no).
5407 is_chr_constants_type(chr_constants(Key,ErrorHandler),Key,yes(ErrorHandler)).
5409 type_def_case_condition(DefCase,Arg,UnrollArg,Mode,Condition) :-
5410 ( nonvar(DefCase) ->
5411 functor(DefCase,F,A),
5413 Condition = (Arg = DefCase)
5415 Condition = functor(Arg,F,A)
5416 ; functor(UnrollArg,F,A) ->
5417 Condition = (functor(Arg,F,A),Arg=Template,ArgsCondition),
5418 DefCase =.. [_|ArgTypes],
5419 UnrollArg =.. [_|UnrollArgs],
5420 functor(Template,F,A),
5421 Template =.. [_|TemplateArgs],
5422 replicate(A,Mode,ArgModes),
5423 types_condition(ArgTypes,TemplateArgs,UnrollArgs,ArgModes,ArgsCondition)
5425 Condition = functor(Arg,F,A)
5428 chr_error(internal,'Illegal type definition (must be nonvar).\n',[])
5432 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5433 % STATIC TYPE CHECKING
5434 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5435 % Checks head constraints and CHR constraint calls in bodies.
5438 % - type clashes involving built-in types
5439 % - Prolog built-ins in guard and body
5440 % - indicate position in terms in error messages
5441 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5443 static_type_check/0.
5446 % 1. Check the declared types
5448 constraint_type(Constraint,ArgTypes), static_type_check
5451 ( member(ArgType,ArgTypes), sub_term(ArgType,Type) ),
5452 ( get_type_definition(Type,_) ->
5455 chr_error(type_error,'Undefined type "~w" used in type declaration of "~w".\n',[Type,Constraint])
5459 % 2. Check the rules
5461 :- chr_type type_error_src ---> head(any) ; body(any).
5463 rule(_,Rule), static_type_check
5465 copy_term_nat(Rule,RuleCopy),
5466 RuleCopy = pragma(rule(Head1,Head2,G,Body),ids(IDs1,IDs2),Pragmas,Name,RuleNb),
5469 ( static_type_check_heads(Head1),
5470 static_type_check_heads(Head2),
5471 conj2list(Body,GoalList),
5472 static_type_check_body(GoalList)
5475 ( Error = invalid_functor(Src,Term,Type) ->
5476 chr_error(type_error,'Invalid functor in ~@ of ~@:\n\t\tfound `~w\',\n\t\texpected type `~w\'!\n',
5477 [chr_translate:format_src(Src),format_rule(Rule),Term,Type])
5478 ; Error = type_clash(Var,Src1,Src2,Type1,Type2) ->
5479 chr_error(type_error,'Type clash for variable ~w in ~@:\n\t\texpected type ~w in ~@\n\t\texpected type ~w in ~@\n',
5480 [Var,format_rule(Rule),Type1,chr_translate:format_src(Src1),Type2,chr_translate:format_src(Src2)])
5483 fail % cleanup constraints
5489 static_type_check <=> true.
5491 static_type_check_heads([]).
5492 static_type_check_heads([Head|Heads]) :-
5493 static_type_check_head(Head),
5494 static_type_check_heads(Heads).
5496 static_type_check_head(Head) :-
5498 get_constraint_type_det(F/A,Types),
5500 maplist(static_type_check_term(head(Head)),Args,Types).
5502 static_type_check_body([]).
5503 static_type_check_body([Goal|Goals]) :-
5505 get_constraint_type_det(F/A,Types),
5507 maplist(static_type_check_term(body(Goal)),Args,Types),
5508 static_type_check_body(Goals).
5510 :- chr_constraint static_type_check_term/3.
5511 :- chr_option(mode,static_type_check_term(?,?,?)).
5512 :- chr_option(type_declaration,static_type_check_term(type_error_src,any,any)).
5514 static_type_check_term(Src,Term,Type)
5518 static_type_check_var(Src,Term,Type).
5519 static_type_check_term(Src,Term,Type)
5521 atomic_builtin_type(Type,Term,Goal)
5526 throw(type_error(invalid_functor(Src,Term,Type)))
5528 static_type_check_term(Src,Term,Type)
5530 compound_builtin_type(Type,Term,_,Goal)
5535 throw(type_error(invalid_functor(Src,Term,Type)))
5537 type_alias(AType,ADef) \ static_type_check_term(Src,Term,Type)
5542 copy_term_nat(AType-ADef,Type-Def),
5543 static_type_check_term(Src,Term,Def).
5545 type_definition(AType,ADef) \ static_type_check_term(Src,Term,Type)
5550 copy_term_nat(AType-ADef,Type-Variants),
5551 functor(Term,TF,TA),
5552 ( member(Variant,Variants), functor(Variant,TF,TA) ->
5554 Variant =.. [_|Types],
5555 maplist(static_type_check_term(Src),Args,Types)
5557 throw(type_error(invalid_functor(Src,Term,Type)))
5560 static_type_check_term(Src,Term,Type)
5562 chr_error(internal,'Undefined type ~w while type checking term ~w in ~@.\n',[Type,Term,chr_translate:format_src(Src)]).
5564 :- chr_constraint static_type_check_var/3.
5565 :- chr_option(mode,static_type_check_var(?,-,?)).
5566 :- chr_option(type_declaration,static_type_check_term(type_error_src,any,any)).
5568 type_alias(AType,ADef) \ static_type_check_var(Src,Var,Type)
5573 copy_term_nat(AType-ADef,Type-Def),
5574 static_type_check_var(Src,Var,Def).
5576 static_type_check_var(Src,Var,Type)
5578 atomic_builtin_type(Type,_,_)
5580 static_atomic_builtin_type_check_var(Src,Var,Type).
5582 static_type_check_var(Src,Var,Type)
5584 compound_builtin_type(Type,_,_,_)
5589 static_type_check_var(Src1,Var,Type1), static_type_check_var(Src2,Var,Type2)
5593 throw(type_error(type_clash(Var,Src1,Src2,Type1,Type2))).
5595 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5596 %% static_atomic_builtin_type_check_var(+type_error_src,-Var,+atomic_builtin_type)
5597 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5598 :- chr_constraint static_atomic_builtin_type_check_var/3.
5599 :- chr_option(mode,static_type_check_var(?,-,+)).
5600 :- chr_option(type_declaration,static_type_check_term(type_error_src,any,atomic_builtin_type)).
5602 static_atomic_builtin_type_check_var(_,_,any) <=> true.
5603 static_atomic_builtin_type_check_var(_,Var,BuiltinType) \ static_atomic_builtin_type_check_var(_,Var,BuiltinType)
5606 static_atomic_builtin_type_check_var(_,Var,float) \ static_atomic_builtin_type_check_var(_,Var,number)
5609 static_atomic_builtin_type_check_var(_,Var,int) \ static_atomic_builtin_type_check_var(_,Var,number)
5612 static_atomic_builtin_type_check_var(_,Var,natural) \ static_atomic_builtin_type_check_var(_,Var,number)
5615 static_atomic_builtin_type_check_var(_,Var,dense_int) \ static_atomic_builtin_type_check_var(_,Var,number)
5618 static_atomic_builtin_type_check_var(_,Var,natural) \ static_atomic_builtin_type_check_var(_,Var,int)
5621 static_atomic_builtin_type_check_var(_,Var,dense_int) \ static_atomic_builtin_type_check_var(_,Var,int)
5624 static_atomic_builtin_type_check_var(_,Var,dense_int) \ static_atomic_builtin_type_check_var(_,Var,natural)
5627 static_atomic_builtin_type_check_var(Src1,Var,Type1), static_atomic_builtin_type_check_var(Src2,Var,Type2)
5629 throw(type_error(type_clash(Var,Src1,Src2,Type1,Type2))).
5631 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5632 %% format_src(+type_error_src) is det.
5633 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5634 format_src(head(Head)) :- format('head ~w',[Head]).
5635 format_src(body(Goal)) :- format('body goal ~w',[Goal]).
5637 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5638 % Dynamic type checking
5639 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5642 dynamic_type_check/0,
5643 dynamic_type_check_clauses/1,
5644 get_dynamic_type_check_clauses/1.
5646 generate_dynamic_type_check_clauses(Clauses) :-
5647 ( chr_pp_flag(debugable,on) ->
5649 get_dynamic_type_check_clauses(Clauses0),
5651 [('$dynamic_type_check'(Type,Term) :-
5652 throw(error(type_error(Type,Term),context(_,'CHR Runtime Type Error')))
5659 type_definition(T,D), dynamic_type_check
5661 copy_term_nat(T-D,Type-Definition),
5662 maplist(dynamic_type_check_clause(Type),Definition,DynamicChecks),
5663 dynamic_type_check_clauses(DynamicChecks).
5664 type_alias(A,B), dynamic_type_check
5666 copy_term_nat(A-B,Alias-Body),
5667 dynamic_type_check_alias_clause(Alias,Body,Clause),
5668 dynamic_type_check_clauses([Clause]).
5670 dynamic_type_check <=>
5672 ('$dynamic_type_check'(Type,Term) :- Goal),
5673 ( atomic_builtin_type(Type,Term,Goal) ; compound_builtin_type(Type,Term,Goal,_) ),
5676 dynamic_type_check_clauses(BuiltinChecks).
5678 dynamic_type_check_clause(T,DC,Clause) :-
5679 copy_term(T-DC,Type-DefinitionClause),
5680 functor(DefinitionClause,F,A),
5682 DefinitionClause =.. [_|DCArgs],
5683 Term =.. [_|TermArgs],
5684 maplist(dynamic_type_check_call,DCArgs,TermArgs,RecursiveCallList),
5685 list2conj(RecursiveCallList,RecursiveCalls),
5687 '$dynamic_type_check'(Type,Term) :-
5691 dynamic_type_check_alias_clause(Alias,Body,Clause) :-
5693 '$dynamic_type_check'(Alias,Term) :-
5694 '$dynamic_type_check'(Body,Term)
5697 dynamic_type_check_call(Type,Term,Call) :-
5698 % ( nonvar(Type), atomic_builtin_type(Type,Term,Goal) ->
5699 % Call = when(nonvar(Term),Goal)
5700 % ; nonvar(Type), compound_builtin_type(Type,Term,Goal) ->
5701 % Call = when(nonvar(Term),Goal)
5706 Call = when(nonvar(Term),once('$dynamic_type_check'(Type,Term)))
5711 dynamic_type_check_clauses(C1), dynamic_type_check_clauses(C2)
5714 dynamic_type_check_clauses(C).
5716 get_dynamic_type_check_clauses(Q), dynamic_type_check_clauses(C)
5719 get_dynamic_type_check_clauses(Q)
5723 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5725 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5726 % Some optimizations can be applied for atomic types...
5727 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5729 atomic_types_suspended_constraint(C) :-
5731 get_constraint_type(C,ArgTypes),
5732 get_constraint_mode(C,ArgModes),
5733 numlist(1,N,Indexes),
5734 maplist(atomic_types_suspended_constraint(C),ArgTypes,ArgModes,Indexes).
5736 atomic_types_suspended_constraint(C,Type,Mode,Index) :-
5737 ( is_indexed_argument(C,Index) ->
5747 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5748 %% atomic_type(+Type) is semidet.
5750 % Succeeds when all values of =Type= are atomic.
5751 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5752 :- chr_constraint atomic_type/1.
5754 atomic_type(Type) <=> atomic_builtin_type(Type,_,_) | Type \== any.
5756 type_definition(TypePat,Def) \ atomic_type(Type)
5758 functor(Type,F,A), functor(TypePat,F,A)
5760 maplist(atomic,Def).
5762 type_alias(TypePat,Alias) \ atomic_type(Type)
5764 functor(Type,F,A), functor(TypePat,F,A)
5767 copy_term_nat(TypePat-Alias,Type-NType),
5770 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5771 %% enumerated_atomic_type(+Type,-Atoms) is semidet.
5773 % Succeeds when all values of =Type= are atomic
5774 % and the atom values are finitely enumerable.
5775 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
5776 :- chr_constraint enumerated_atomic_type/2.
5778 enumerated_atomic_type(Type,_) <=> atomic_builtin_type(Type,_,_) | fail.
5780 type_definition(TypePat,Def) \ enumerated_atomic_type(Type,Atoms)
5782 functor(Type,F,A), functor(TypePat,F,A)
5784 maplist(atomic,Def),
5787 type_alias(TypePat,Alias) \ enumerated_atomic_type(Type,Atoms)
5789 functor(Type,F,A), functor(TypePat,F,A)
5792 copy_term_nat(TypePat-Alias,Type-NType),
5793 enumerated_atomic_type(NType,Atoms).
5794 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5797 stored/3, % constraint,occurrence,(yes/no/maybe)
5798 stored_completing/3,
5801 is_finally_stored/1,
5802 check_all_passive/2.
5804 :- chr_option(mode,stored(+,+,+)).
5805 :- chr_option(type_declaration,stored(any,int,storedinfo)).
5806 :- chr_type storedinfo ---> yes ; no ; maybe.
5807 :- chr_option(mode,stored_complete(+,+,+)).
5808 :- chr_option(mode,maybe_complementary_guards(+,+,?,?)).
5809 :- chr_option(mode,guard_list(+,+,+,+)).
5810 :- chr_option(mode,check_all_passive(+,+)).
5811 :- chr_option(type_declaration,check_all_passive(any,list)).
5813 % change yes in maybe when yes becomes passive
5814 passive(RuleNb,ID), occurrence(C,O,RuleNb,ID,_) \
5815 stored(C,O,yes), stored_complete(C,RO,Yesses)
5816 <=> O < RO | NYesses is Yesses - 1,
5817 stored(C,O,maybe), stored_complete(C,RO,NYesses).
5818 % change yes in maybe when not observed
5819 ai_not_observed(C,O) \ stored(C,O,yes), stored_complete(C,RO,Yesses)
5821 NYesses is Yesses - 1,
5822 stored(C,O,maybe), stored_complete(C,RO,NYesses).
5824 occurrence(_,_,RuleNb,ID,_), occurrence(C2,_,RuleNb,_,_), stored_complete(C2,RO,0), max_occurrence(C2,MO2)
5825 ==> RO =< MO2 | % C2 is never stored
5831 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5833 rule(RuleNb,Rule),passive(RuleNb,Id) ==>
5834 Rule = pragma(rule(Head1,Head2,G,B),ids([Id|IDs1],IDs2),Pragmas,Name,RuleNb) |
5835 append(IDs1,IDs2,I), check_all_passive(RuleNb,I).
5837 rule(RuleNb,Rule),passive(RuleNb,Id) ==>
5838 Rule = pragma(rule(Head1,Head2,G,B),ids([],[Id|IDs2]),Pragmas,Name,RuleNb) |
5839 check_all_passive(RuleNb,IDs2).
5841 passive(RuleNb,Id) \ check_all_passive(RuleNb,[Id|IDs]) <=>
5842 check_all_passive(RuleNb,IDs).
5844 rule(RuleNb,Rule) \ check_all_passive(RuleNb,[]) <=>
5845 chr_warning(weird_program,'All heads passive in ~@.\n\tThis rule never fires. Please check your program.\n',[format_rule(Rule)]).
5847 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5849 % collect the storage information
5850 stored(C,O,yes) \ stored_completing(C,O,Yesses)
5851 <=> NO is O + 1, NYesses is Yesses + 1,
5852 stored_completing(C,NO,NYesses).
5853 stored(C,O,maybe) \ stored_completing(C,O,Yesses)
5855 stored_completing(C,NO,Yesses).
5857 stored(C,O,no) \ stored_completing(C,O,Yesses)
5858 <=> stored_complete(C,O,Yesses).
5859 stored_completing(C,O,Yesses)
5860 <=> stored_complete(C,O,Yesses).
5862 stored_complete(C,O,Yesses), occurrence(C,O2,RuleNb,Id,_) ==>
5863 O2 > O | passive(RuleNb,Id).
5865 % decide whether a constraint is stored
5866 max_occurrence(C,MO), stored_complete(C,RO,0) \ is_stored(C)
5867 <=> RO =< MO | fail.
5868 is_stored(C) <=> true.
5870 % decide whether a constraint is suspends after occurrences
5871 max_occurrence(C,MO), stored_complete(C,RO,_) \ is_finally_stored(C)
5872 <=> RO =< MO | fail.
5873 is_finally_stored(C) <=> true.
5875 storage_analysis(Constraints) :-
5876 ( chr_pp_flag(storage_analysis,on) ->
5877 check_constraint_storages(Constraints)
5882 check_constraint_storages([]).
5883 check_constraint_storages([C|Cs]) :-
5884 check_constraint_storage(C),
5885 check_constraint_storages(Cs).
5887 check_constraint_storage(C) :-
5888 get_max_occurrence(C,MO),
5889 check_occurrences_storage(C,1,MO).
5891 check_occurrences_storage(C,O,MO) :-
5893 stored_completing(C,1,0)
5895 check_occurrence_storage(C,O),
5897 check_occurrences_storage(C,NO,MO)
5900 check_occurrence_storage(C,O) :-
5901 get_occurrence(C,O,RuleNb,ID),
5902 ( is_passive(RuleNb,ID) ->
5905 get_rule(RuleNb,PragmaRule),
5906 PragmaRule = pragma(rule(Heads1,Heads2,Guard,Body),ids(IDs1,IDs2),_,_,_),
5907 ( select2(ID,Head1,IDs1,Heads1,RIDs1,RHeads1) ->
5908 check_storage_head1(Head1,O,Heads1,Heads2,Guard)
5909 ; select2(ID,Head2,IDs2,Heads2,RIDs2,RHeads2) ->
5910 check_storage_head2(Head2,O,Heads1,Body)
5914 check_storage_head1(Head,O,H1,H2,G) :-
5919 % writeq(guard_entailment:entails_guard([chr_pp_headvariables(Head)],G)),nl,
5920 guard_entailment:entails_guard([chr_pp_headvariables(Head)],G),
5922 no_matching(L,[]) ->
5929 no_matching([X|Xs],Prev) :-
5931 \+ memberchk_eq(X,Prev),
5932 no_matching(Xs,[X|Prev]).
5934 check_storage_head2(Head,O,H1,B) :-
5938 ( H1 \== [], B == true )
5940 % \+ is_observed(F/A,O) % always fails because observation analysis has not been performed yet
5948 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5950 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5951 %% ____ _ ____ _ _ _ _
5952 %% | _ \ _ _| | ___ / ___|___ _ __ ___ _ __ (_) | __ _| |_(_) ___ _ __
5953 %% | |_) | | | | |/ _ \ | | / _ \| '_ ` _ \| '_ \| | |/ _` | __| |/ _ \| '_ \
5954 %% | _ <| |_| | | __/ | |__| (_) | | | | | | |_) | | | (_| | |_| | (_) | | | |
5955 %% |_| \_\\__,_|_|\___| \____\___/|_| |_| |_| .__/|_|_|\__,_|\__|_|\___/|_| |_|
5958 constraints_code(Constraints,Clauses) :-
5959 (chr_pp_flag(reduced_indexing,on),
5960 forall(C,Constraints,chr_translate:only_ground_indexed_arguments(C)) ->
5961 none_suspended_on_variables
5965 constraints_code1(Constraints,Clauses,[]).
5967 %===============================================================================
5968 :- chr_constraint constraints_code1/3.
5969 :- chr_option(mode,constraints_code1(+,+,+)).
5970 :- chr_option(type_declaration,constraints_code1(list,any,any)).
5971 %-------------------------------------------------------------------------------
5972 constraints_code1([],L,T) <=> L = T.
5973 constraints_code1([C|RCs],L,T)
5975 constraint_code(C,L,T1),
5976 constraints_code1(RCs,T1,T).
5977 %===============================================================================
5978 :- chr_constraint constraint_code/3.
5979 :- chr_option(mode,constraint_code(+,+,+)).
5980 %-------------------------------------------------------------------------------
5981 %% Generate code for a single CHR constraint
5982 constraint_code(Constraint, L, T)
5984 | ( (chr_pp_flag(debugable,on) ;
5985 is_stored(Constraint), ( has_active_occurrence(Constraint); chr_pp_flag(late_allocation,off)),
5986 ( may_trigger(Constraint) ;
5987 get_allocation_occurrence(Constraint,AO),
5988 get_max_occurrence(Constraint,MO), MO >= AO ) )
5990 constraint_prelude(Constraint,Clause),
5991 add_dummy_location(Clause,LocatedClause),
5992 L = [LocatedClause | L1]
5997 occurrences_code(Constraint,1,Id,NId,L1,L2),
5998 gen_cond_attach_clause(Constraint,NId,L2,T).
6000 %===============================================================================
6001 %% Generate prelude predicate for a constraint.
6002 %% f(...) :- f/a_0(...,Susp).
6003 constraint_prelude(F/A, Clause) :-
6004 vars_susp(A,Vars,Susp,VarsSusp),
6005 Head =.. [ F | Vars],
6006 make_suspension_continuation_goal(F/A,VarsSusp,Continuation),
6007 build_head(F,A,[0],VarsSusp,Delegate),
6008 ( chr_pp_flag(debugable,on) ->
6009 insert_constraint_goal(F/A,Susp,Vars,InsertCall),
6010 attach_constraint_atom(F/A,Vars2,Susp,AttachCall),
6011 delay_phase_end(validate_store_type_assumptions,chr_translate:update_suspension_field(F/A,Susp,state,inactive,Inactive)),
6012 insert_constraint_internal_constraint_goal(F/A, Vars2, Susp, Continuation, Vars,InsertGoal),
6014 ( get_constraint_type(F/A,ArgTypeList) ->
6015 maplist(dynamic_type_check_call,ArgTypeList,Vars,DynamicTypeCheckList),
6016 list2conj(DynamicTypeCheckList,DynamicTypeChecks)
6018 DynamicTypeChecks = true
6028 'chr debug_event'(insert(Head#Susp)),
6030 'chr debug_event'(call(Susp)),
6033 'chr debug_event'(fail(Susp)), !,
6037 'chr debug_event'(exit(Susp))
6039 'chr debug_event'(redo(Susp)),
6043 ; get_allocation_occurrence(F/A,0) ->
6044 gen_insert_constraint_internal_goal(F/A,Goal,VarsSusp,Vars,Susp),
6045 delay_phase_end(validate_store_type_assumptions,chr_translate:update_suspension_field(F/A,Susp,state,inactive,Inactive)),
6046 Clause = ( Head :- Goal, Inactive, Delegate )
6048 Clause = ( Head :- Delegate )
6051 make_suspension_continuation_goal(F/A,VarsSusp,Goal) :-
6052 ( may_trigger(F/A) ->
6053 build_head(F,A,[0],VarsSusp,Delegate),
6054 ( chr_pp_flag(debugable,off) ->
6057 get_target_module(Mod),
6064 %===============================================================================
6065 :- chr_constraint has_active_occurrence/1, has_active_occurrence/2.
6066 :- chr_option(mode,has_active_occurrence(+)).
6067 :- chr_option(mode,has_active_occurrence(+,+)).
6069 :- chr_constraint memo_has_active_occurrence/1.
6070 :- chr_option(mode,memo_has_active_occurrence(+)).
6071 %-------------------------------------------------------------------------------
6072 memo_has_active_occurrence(C) \ has_active_occurrence(C) <=> true.
6073 has_active_occurrence(C) <=> has_active_occurrence(C,1), memo_has_active_occurrence(C).
6075 max_occurrence(C,MO) \ has_active_occurrence(C,O) <=>
6077 passive(RuleNb,ID),occurrence(C,O,RuleNb,ID,_) \
6078 has_active_occurrence(C,O) <=>
6080 has_active_occurrence(C,NO).
6081 has_active_occurrence(C,O) <=> true.
6082 %===============================================================================
6084 gen_cond_attach_clause(F/A,Id,L,T) :-
6085 ( is_finally_stored(F/A) ->
6086 get_allocation_occurrence(F/A,AllocationOccurrence),
6087 get_max_occurrence(F/A,MaxOccurrence),
6088 ( chr_pp_flag(debugable,off), MaxOccurrence < AllocationOccurrence ->
6089 ( only_ground_indexed_arguments(F/A) ->
6090 gen_insert_constraint_internal_goal(F/A,Body,AllArgs,Args,Susp)
6092 gen_cond_attach_goal(F/A,Body,AllArgs,Args,Susp)
6094 ; vars_susp(A,Args,Susp,AllArgs),
6095 gen_uncond_attach_goal(F/A,Susp,Args,Body,_)
6097 build_head(F,A,Id,AllArgs,Head),
6098 Clause = ( Head :- Body ),
6099 add_dummy_location(Clause,LocatedClause),
6100 L = [LocatedClause | T]
6105 :- chr_constraint use_auxiliary_predicate/1.
6106 :- chr_option(mode,use_auxiliary_predicate(+)).
6108 :- chr_constraint use_auxiliary_predicate/2.
6109 :- chr_option(mode,use_auxiliary_predicate(+,+)).
6111 :- chr_constraint is_used_auxiliary_predicate/1.
6112 :- chr_option(mode,is_used_auxiliary_predicate(+)).
6114 :- chr_constraint is_used_auxiliary_predicate/2.
6115 :- chr_option(mode,is_used_auxiliary_predicate(+,+)).
6118 use_auxiliary_predicate(P) \ use_auxiliary_predicate(P) <=> true.
6120 use_auxiliary_predicate(P,C) \ use_auxiliary_predicate(P,C) <=> true.
6122 use_auxiliary_predicate(P) \ is_used_auxiliary_predicate(P) <=> true.
6124 use_auxiliary_predicate(P,_) \ is_used_auxiliary_predicate(P) <=> true.
6126 is_used_auxiliary_predicate(P) <=> fail.
6128 use_auxiliary_predicate(P) \ is_used_auxiliary_predicate(P,_) <=> true.
6129 use_auxiliary_predicate(P,C) \ is_used_auxiliary_predicate(P,C) <=> true.
6131 is_used_auxiliary_predicate(P,C) <=> fail.
6133 %------------------------------------------------------------------------------%
6134 % Only generate import statements for actually used modules.
6135 %------------------------------------------------------------------------------%
6137 :- chr_constraint use_auxiliary_module/1.
6138 :- chr_option(mode,use_auxiliary_module(+)).
6140 :- chr_constraint is_used_auxiliary_module/1.
6141 :- chr_option(mode,is_used_auxiliary_module(+)).
6144 use_auxiliary_module(P) \ use_auxiliary_module(P) <=> true.
6146 use_auxiliary_module(P) \ is_used_auxiliary_module(P) <=> true.
6148 is_used_auxiliary_module(P) <=> fail.
6150 % only called for constraints with
6152 % non-ground indexed argument
6153 gen_cond_attach_goal(F/A,Goal,AllArgs,Args,Susp) :-
6154 vars_susp(A,Args,Susp,AllArgs),
6155 make_suspension_continuation_goal(F/A,AllArgs,Closure),
6156 ( get_store_type(F/A,var_assoc_store(_,_)) ->
6159 attach_constraint_atom(F/A,Vars,Susp,Attach)
6162 insert_constraint_goal(F/A,Susp,Args,InsertCall),
6163 insert_constraint_internal_constraint_goal(F/A, Vars, Susp, Closure, Args,InsertGoal),
6164 ( may_trigger(F/A) ->
6165 activate_constraint_goal(F/A,(InsertCall,Attach),Vars,Susp,_,ActivateGoal),
6169 InsertGoal, % insert_constraint_internal(Stored,Vars,Susp,Closure,F,Args)
6173 ActivateGoal % activate_constraint(Stored,Vars,Susp,_)
6179 InsertGoal, % insert_constraint_internal(Stored,Vars,Susp,Closure,F,Args),
6185 gen_insert_constraint_internal_goal(F/A,Goal,AllArgs,Args,Susp) :-
6186 vars_susp(A,Args,Susp,AllArgs),
6187 make_suspension_continuation_goal(F/A,AllArgs,Cont),
6188 ( \+ only_ground_indexed_arguments(F/A), \+ get_store_type(F/A,var_assoc_store(_,_)) ->
6189 attach_constraint_atom(F/A,Vars,Susp,Attach)
6194 insert_constraint_goal(F/A,Susp,Args,InsertCall),
6195 insert_constraint_internal_constraint_goal(F/A, Vars, Susp, Cont, Args,InsertInternalGoal),
6196 ( only_ground_indexed_arguments(F/A), chr_pp_flag(debugable,off) ->
6199 InsertInternalGoal, % insert_constraint_internal(Susp,F,Args),
6205 InsertInternalGoal, % insert_constraint_internal(_,Vars,Susp,Cont,F,Args),
6211 gen_uncond_attach_goal(FA,Susp,Args,AttachGoal,Generation) :-
6212 ( \+ only_ground_indexed_arguments(FA), \+ get_store_type(FA,var_assoc_store(_,_)) ->
6213 attach_constraint_atom(FA,Vars,Susp,Attach)
6217 insert_constraint_goal(FA,Susp,Args,InsertCall),
6218 ( chr_pp_flag(late_allocation,on) ->
6219 activate_constraint_goal(FA,(InsertCall,Attach),Vars,Susp,Generation,AttachGoal)
6221 activate_constraint_goal(FA,true,Vars,Susp,Generation,AttachGoal)
6224 %-------------------------------------------------------------------------------
6225 :- chr_constraint occurrences_code/6.
6226 :- chr_option(mode,occurrences_code(+,+,+,+,+,+)).
6227 %-------------------------------------------------------------------------------
6228 max_occurrence(C,MO) \ occurrences_code(C,O,Id,NId,L,T)
6231 occurrences_code(C,O,Id,NId,L,T)
6233 occurrence_code(C,O,Id,Id1,L,L1),
6235 occurrences_code(C,NO,Id1,NId,L1,T).
6236 %-------------------------------------------------------------------------------
6237 :- chr_constraint occurrence_code/6.
6238 :- chr_option(mode,occurrence_code(+,+,+,+,+,+)).
6239 %-------------------------------------------------------------------------------
6240 occurrence(C,O,RuleNb,ID,_), passive(RuleNb,ID) \ occurrence_code(C,O,Id,NId,L,T)
6242 ( named_history(RuleNb,_,_) ->
6243 does_use_history(C,O)
6249 occurrence(C,O,RuleNb,ID,_), rule(RuleNb,PragmaRule) \ occurrence_code(C,O,Id,NId,L,T)
6251 PragmaRule = pragma(rule(Heads1,Heads2,_,_),ids(IDs1,IDs2),_,_,_),
6252 ( select2(ID,Head1,IDs1,Heads1,RIDs1,RHeads1) ->
6254 head1_code(Head1,ID,RHeads1,RIDs1,PragmaRule,C,O,Id,L,T)
6255 ; select2(ID,Head2,IDs2,Heads2,RIDs2,RHeads2) ->
6257 head2_code(Head2,ID,RHeads2,RIDs2,PragmaRule,C,O,Id,L,L1),
6258 ( should_skip_to_next_id(C,O) ->
6260 ( unconditional_occurrence(C,O) ->
6263 gen_alloc_inc_clause(C,O,Id,L1,T)
6271 occurrence_code(C,O,_,_,_,_)
6273 chr_error(internal,'occurrence_code/6: missing information to compile ~w:~w\n',[C,O]).
6274 %-------------------------------------------------------------------------------
6276 %% Generate code based on one removed head of a CHR rule
6277 head1_code(Head,ID,OtherHeads,OtherIDs,PragmaRule,FA,O,Id,L,T) :-
6278 PragmaRule = pragma(Rule,_,_,_Name,RuleNb),
6279 Rule = rule(_,Head2,_,_),
6281 reorder_heads(RuleNb,Head,OtherHeads,OtherIDs,NOtherHeads,NOtherIDs),
6282 simplification_code(Head,ID,NOtherHeads,NOtherIDs,PragmaRule,FA,O,Id,L,T)
6284 simpagation_head1_code(Head,ID,OtherHeads,OtherIDs,PragmaRule,FA,O,Id,L,T)
6287 %% Generate code based on one persistent head of a CHR rule
6288 head2_code(Head,ID,OtherHeads,OtherIDs,PragmaRule,FA,O,Id,L,T) :-
6289 PragmaRule = pragma(Rule,_,_,_Name,RuleNb),
6290 Rule = rule(Head1,_,_,_),
6292 reorder_heads(RuleNb,Head,OtherHeads,OtherIDs,NOtherHeads,NOtherIDs),
6293 propagation_code(Head,ID,NOtherHeads,NOtherIDs,Rule,RuleNb,FA,O,Id,L,T)
6295 simpagation_head2_code(Head,ID,OtherHeads,OtherIDs,PragmaRule,FA,O,Id,L,T)
6298 gen_alloc_inc_clause(F/A,O,Id,L,T) :-
6299 vars_susp(A,Vars,Susp,VarsSusp),
6300 build_head(F,A,Id,VarsSusp,Head),
6302 build_head(F,A,IncId,VarsSusp,CallHead),
6303 gen_occ_allocation(F/A,O,Vars,Susp,ConditionalAlloc),
6310 add_dummy_location(Clause,LocatedClause),
6311 L = [LocatedClause|T].
6313 gen_occ_allocation(FA,O,Vars,Susp,Goal) :-
6314 get_allocation_occurrence(FA,AO),
6315 get_occurrence_code_id(FA,AO,AId),
6316 get_occurrence_code_id(FA,O,Id),
6317 ( chr_pp_flag(debugable,off), Id == AId ->
6318 allocate_constraint_goal(FA,Susp,Vars,Goal0),
6319 ( may_trigger(FA) ->
6320 Goal = (var(Susp) -> Goal0 ; true)
6328 gen_occ_allocation_in_guard(FA,O,Vars,Susp,Goal) :-
6329 get_allocation_occurrence(FA,AO),
6330 ( chr_pp_flag(debugable,off), O < AO ->
6331 allocate_constraint_goal(FA,Susp,Vars,Goal0),
6332 ( may_trigger(FA) ->
6333 Goal = (var(Susp) -> Goal0 ; true)
6341 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6343 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6345 % Reorders guard goals with respect to partner constraint retrieval goals and
6346 % active constraint. Returns combined partner retrieval + guard goal.
6348 guard_via_reschedule_new(Retrievals,GuardList,Prelude,GuardListSkeleton,LookupSkeleton,GoalSkeleton) :-
6349 ( chr_pp_flag(guard_via_reschedule,on) ->
6350 guard_via_reschedule_main_new(Retrievals,GuardList,Prelude,GuardListSkeleton,LookupSkeleton,ScheduleSkeleton),
6351 list2conj(ScheduleSkeleton,GoalSkeleton)
6353 length(Retrievals,RL), length(LookupSkeleton,RL),
6354 length(GuardList,GL), length(GuardListSkeleton,GL),
6355 append(LookupSkeleton,GuardListSkeleton,GoalListSkeleton),
6356 list2conj(GoalListSkeleton,GoalSkeleton)
6358 guard_via_reschedule_main_new(PartnerLookups,GuardList,ActiveHead,
6359 GuardListSkeleton,LookupSkeleton,ScheduleSkeleton) :-
6360 initialize_unit_dictionary(ActiveHead,Dict),
6361 maplist(wrap_in_functor(lookup),PartnerLookups,WrappedPartnerLookups),
6362 maplist(wrap_in_functor(guard),GuardList,WrappedGuardList),
6363 build_units(WrappedPartnerLookups,WrappedGuardList,Dict,Units),
6364 dependency_reorder(Units,NUnits),
6365 wrappedunits2lists(NUnits,IndexedGuardListSkeleton,LookupSkeleton,ScheduleSkeleton),
6366 sort(IndexedGuardListSkeleton,SortedIndexedGuardListSkeleton),
6367 snd_of_pairs(SortedIndexedGuardListSkeleton,GuardListSkeleton).
6369 wrappedunits2lists([],[],[],[]).
6370 wrappedunits2lists([unit(N,WrappedGoal,_,_)|Units],Gs,Ls,Ss) :-
6371 Ss = [GoalCopy|TSs],
6372 ( WrappedGoal = lookup(Goal) ->
6373 Ls = [GoalCopy|TLs],
6375 ; WrappedGoal = guard(Goal) ->
6376 Gs = [N-GoalCopy|TGs],
6379 wrappedunits2lists(Units,TGs,TLs,TSs).
6381 guard_splitting(Rule,SplitGuardList) :-
6382 Rule = rule(H1,H2,Guard,_),
6383 append(H1,H2,Heads),
6384 conj2list(Guard,GuardList),
6385 term_variables(Heads,HeadVars),
6386 split_off_simple_guard_new(GuardList,HeadVars,GuardPrefix,RestGuardList),
6387 append(GuardPrefix,[RestGuard],SplitGuardList),
6388 term_variables(RestGuardList,GuardVars1),
6389 % variables that are declared to be ground don't need to be locked
6390 ground_vars(Heads,GroundVars),
6391 list_difference_eq(HeadVars,GroundVars,LockableHeadVars),
6392 intersect_eq(LockableHeadVars,GuardVars1,GuardVars),
6393 ( chr_pp_flag(guard_locks,on),
6394 bagof(('chr lock'(X)) - ('chr unlock'(X)), (lists:member(X,GuardVars)), LocksUnlocks) ->
6395 once(pairup(Locks,Unlocks,LocksUnlocks))
6400 list2conj(Locks,LockPhase),
6401 list2conj(Unlocks,UnlockPhase),
6402 list2conj(RestGuardList,RestGuard1),
6403 RestGuard = (LockPhase,(RestGuard1,UnlockPhase)).
6405 guard_body_copies3(Rule,GuardList,VarDict,GuardCopyList,BodyCopy) :-
6406 Rule = rule(_,_,_,Body),
6407 my_term_copy(GuardList,VarDict,VarDict2,GuardCopyList),
6408 my_term_copy(Body,VarDict2,BodyCopy).
6411 split_off_simple_guard_new([],_,[],[]).
6412 split_off_simple_guard_new([G|Gs],VarDict,S,C) :-
6413 ( simple_guard_new(G,VarDict) ->
6415 split_off_simple_guard_new(Gs,VarDict,Ss,C)
6421 % simple guard: cheap and benign (does not bind variables)
6422 simple_guard_new(G,Vars) :-
6423 builtin_binds_b(G,BoundVars),
6424 not(( member(V,BoundVars),
6425 memberchk_eq(V,Vars)
6428 dependency_reorder(Units,NUnits) :-
6429 dependency_reorder(Units,[],NUnits).
6431 dependency_reorder([],Acc,Result) :-
6432 reverse(Acc,Result).
6434 dependency_reorder([Unit|Units],Acc,Result) :-
6435 Unit = unit(_GID,_Goal,Type,GIDs),
6439 dependency_insert(Acc,Unit,GIDs,NAcc)
6441 dependency_reorder(Units,NAcc,Result).
6443 dependency_insert([],Unit,_,[Unit]).
6444 dependency_insert([X|Xs],Unit,GIDs,L) :-
6445 X = unit(GID,_,_,_),
6446 ( memberchk(GID,GIDs) ->
6450 dependency_insert(Xs,Unit,GIDs,T)
6453 build_units(Retrievals,Guard,InitialDict,Units) :-
6454 build_retrieval_units(Retrievals,1,N,InitialDict,Dict,Units,Tail),
6455 build_guard_units(Guard,N,Dict,Tail).
6457 build_retrieval_units([],N,N,Dict,Dict,L,L).
6458 build_retrieval_units([U|Us],N,M,Dict,NDict,L,T) :-
6459 term_variables(U,Vs),
6460 update_unit_dictionary(Vs,N,Dict,Dict1,[],GIDs),
6461 L = [unit(N,U,fixed,GIDs)|L1],
6463 build_retrieval_units(Us,N1,M,Dict1,NDict,L1,T).
6465 initialize_unit_dictionary(Term,Dict) :-
6466 term_variables(Term,Vars),
6467 pair_all_with(Vars,0,Dict).
6469 update_unit_dictionary([],_,Dict,Dict,GIDs,GIDs).
6470 update_unit_dictionary([V|Vs],This,Dict,NDict,GIDs,NGIDs) :-
6471 ( lookup_eq(Dict,V,GID) ->
6472 ( (GID == This ; memberchk(GID,GIDs) ) ->
6479 Dict1 = [V - This|Dict],
6482 update_unit_dictionary(Vs,This,Dict1,NDict,GIDs1,NGIDs).
6484 build_guard_units(Guard,N,Dict,Units) :-
6486 Units = [unit(N,Goal,fixed,[])]
6487 ; Guard = [Goal|Goals] ->
6488 term_variables(Goal,Vs),
6489 update_unit_dictionary2(Vs,N,Dict,NDict,[],GIDs),
6490 Units = [unit(N,Goal,movable,GIDs)|RUnits],
6492 build_guard_units(Goals,N1,NDict,RUnits)
6495 update_unit_dictionary2([],_,Dict,Dict,GIDs,GIDs).
6496 update_unit_dictionary2([V|Vs],This,Dict,NDict,GIDs,NGIDs) :-
6497 ( lookup_eq(Dict,V,GID) ->
6498 ( (GID == This ; memberchk(GID,GIDs) ) ->
6503 Dict1 = [V - This|Dict]
6505 Dict1 = [V - This|Dict],
6508 update_unit_dictionary2(Vs,This,Dict1,NDict,GIDs1,NGIDs).
6510 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6512 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6514 %% / ___| ___| |_ / ___| ___ _ __ ___ __ _ _ __ | |_(_) ___ ___ _
6515 %% \___ \ / _ \ __| \___ \ / _ \ '_ ` _ \ / _` | '_ \| __| |/ __/ __(_)
6516 %% ___) | __/ |_ ___) | __/ | | | | | (_| | | | | |_| | (__\__ \_
6517 %% |____/ \___|\__| |____/ \___|_| |_| |_|\__,_|_| |_|\__|_|\___|___(_)
6520 %% | | | |_ __ (_) __ _ _ _ ___ |_ _|_ __ / _| ___ _ __ ___ _ __ ___ ___
6521 %% | | | | '_ \| |/ _` | | | |/ _ \ | || '_ \| |_ / _ \ '__/ _ \ '_ \ / __/ _ \
6522 %% | |_| | | | | | (_| | |_| | __/ | || | | | _| __/ | | __/ | | | (_| __/
6523 %% \___/|_| |_|_|\__, |\__,_|\___| |___|_| |_|_| \___|_| \___|_| |_|\___\___|
6526 functional_dependency/4,
6527 get_functional_dependency/4.
6529 :- chr_option(mode,functional_dependency(+,+,?,?)).
6530 :- chr_option(mode,get_functional_dependency(+,+,?,?)).
6532 allocation_occurrence(C,AO), occurrence(C,O,RuleNb,_,_) \ functional_dependency(C,RuleNb,Pattern,Key)
6536 functional_dependency(C,1,Pattern,Key).
6538 functional_dependency(C,RuleNb1,Pattern,Key) \ get_functional_dependency(C,RuleNb2,QPattern,QKey)
6542 QPattern = Pattern, QKey = Key.
6543 get_functional_dependency(_,_,_,_)
6547 functional_dependency_analysis(Rules) :-
6548 ( fail, chr_pp_flag(functional_dependency_analysis,on) ->
6549 functional_dependency_analysis_main(Rules)
6554 functional_dependency_analysis_main([]).
6555 functional_dependency_analysis_main([PRule|PRules]) :-
6556 ( discover_unique_pattern(PRule,C,RuleNb,Pattern,Key) ->
6557 functional_dependency(C,RuleNb,Pattern,Key)
6561 functional_dependency_analysis_main(PRules).
6563 discover_unique_pattern(PragmaRule,F/A,RuleNb,Pattern,Key) :-
6564 PragmaRule = pragma(Rule,_,_,Name,RuleNb),
6565 Rule = rule(H1,H2,Guard,_),
6573 check_unique_constraints(C1,C2,Guard,RuleNb,List),
6574 term_variables(C1,Vs),
6577 lookup_eq(List,V1,V2),
6580 select_pragma_unique_variables(Vs,List,Key1),
6581 copy_term_nat(C1-Key1,Pattern-Key),
6584 select_pragma_unique_variables([],_,[]).
6585 select_pragma_unique_variables([V|Vs],List,L) :-
6586 ( lookup_eq(List,V,_) ->
6591 select_pragma_unique_variables(Vs,List,T).
6593 % depends on functional dependency analysis
6594 % and shape of rule: C1 \ C2 <=> true.
6595 set_semantics_rules(Rules) :-
6596 ( fail, chr_pp_flag(set_semantics_rule,on) ->
6597 set_semantics_rules_main(Rules)
6602 set_semantics_rules_main([]).
6603 set_semantics_rules_main([R|Rs]) :-
6604 set_semantics_rule_main(R),
6605 set_semantics_rules_main(Rs).
6607 set_semantics_rule_main(PragmaRule) :-
6608 PragmaRule = pragma(Rule,IDs,Pragmas,_,RuleNb),
6609 ( Rule = rule([C1],[C2],true,_),
6610 IDs = ids([ID1],[ID2]),
6611 \+ is_passive(RuleNb,ID1),
6613 get_functional_dependency(F/A,RuleNb,Pattern,Key),
6614 copy_term_nat(Pattern-Key,C1-Key1),
6615 copy_term_nat(Pattern-Key,C2-Key2),
6622 check_unique_constraints(C1,C2,G,RuleNb,List) :-
6623 \+ any_passive_head(RuleNb),
6624 variable_replacement(C1-C2,C2-C1,List),
6625 copy_with_variable_replacement(G,OtherG,List),
6627 once(entails_b(NotG,OtherG)).
6629 % checks for rules of the shape ...,C1,C2... (<|=)=> ...
6630 % where C1 and C2 are symmteric constraints
6631 symmetry_analysis(Rules) :-
6632 ( chr_pp_flag(check_unnecessary_active,off) ->
6635 symmetry_analysis_main(Rules)
6638 symmetry_analysis_main([]).
6639 symmetry_analysis_main([R|Rs]) :-
6640 R = pragma(Rule,ids(IDs1,IDs2),_,_,RuleNb),
6641 Rule = rule(H1,H2,_,_),
6642 ( ( \+ chr_pp_flag(check_unnecessary_active,simplification) ; H2 == [] ), H1 \== [] ->
6643 symmetry_analysis_heads_simplification(H1,IDs1,[],[],Rule,RuleNb),
6644 symmetry_analysis_heads_propagation(H2,IDs2,[],[],Rule,RuleNb)
6648 symmetry_analysis_main(Rs).
6650 symmetry_analysis_heads_simplification([],[],_,_,_,_).
6651 symmetry_analysis_heads_simplification([H|Hs],[ID|IDs],PreHs,PreIDs,Rule,RuleNb) :-
6652 ( \+ is_passive(RuleNb,ID),
6653 member2(PreHs,PreIDs,PreH-PreID),
6654 \+ is_passive(RuleNb,PreID),
6655 variable_replacement(PreH,H,List),
6656 copy_with_variable_replacement(Rule,Rule2,List),
6657 identical_guarded_rules(Rule,Rule2) ->
6662 symmetry_analysis_heads_simplification(Hs,IDs,[H|PreHs],[ID|PreIDs],Rule,RuleNb).
6664 symmetry_analysis_heads_propagation([],[],_,_,_,_).
6665 symmetry_analysis_heads_propagation([H|Hs],[ID|IDs],PreHs,PreIDs,Rule,RuleNb) :-
6666 ( \+ is_passive(RuleNb,ID),
6667 member2(PreHs,PreIDs,PreH-PreID),
6668 \+ is_passive(RuleNb,PreID),
6669 variable_replacement(PreH,H,List),
6670 copy_with_variable_replacement(Rule,Rule2,List),
6671 identical_rules(Rule,Rule2) ->
6676 symmetry_analysis_heads_propagation(Hs,IDs,[H|PreHs],[ID|PreIDs],Rule,RuleNb).
6678 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6680 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6681 %% ____ _ _ _ __ _ _ _
6682 %% / ___|(_)_ __ ___ _ __ | (_)/ _(_) ___ __ _| |_(_) ___ _ __
6683 %% \___ \| | '_ ` _ \| '_ \| | | |_| |/ __/ _` | __| |/ _ \| '_ \
6684 %% ___) | | | | | | | |_) | | | _| | (_| (_| | |_| | (_) | | | |
6685 %% |____/|_|_| |_| |_| .__/|_|_|_| |_|\___\__,_|\__|_|\___/|_| |_|
6689 simplification_code(Head,ID,RestHeads,RestIDs,PragmaRule,F/A,O,Id,L,T) :-
6690 PragmaRule = pragma(Rule,_,Pragmas,_,RuleNb),
6691 head_info(Head,A,_Vars,Susp,HeadVars,HeadPairs),
6692 build_head(F,A,Id,HeadVars,ClauseHead),
6693 get_constraint_mode(F/A,Mode),
6694 head_arg_matches(HeadPairs,Mode,[],FirstMatching,VarDict1,[],GroundVars),
6697 guard_splitting(Rule,GuardList0),
6698 ( is_stored_in_guard(F/A, RuleNb) ->
6699 GuardList = [Hole1|GuardList0]
6701 GuardList = GuardList0
6703 guard_via_reschedule_new(RestHeads,GuardList,Head,GuardCopyList,GetRestHeads,RescheduledTest),
6705 rest_heads_retrieval_and_matching(RestHeads,RestIDs,Head,GetRestHeads,Susps,VarDict1,VarDict,[],[],[],GroundVars,_),
6707 guard_body_copies3(Rule,GuardList,VarDict,GuardCopyList,BodyCopy),
6709 ( is_stored_in_guard(F/A, RuleNb) ->
6710 gen_occ_allocation_in_guard(F/A,O,Vars,Susp,Allocation),
6711 gen_uncond_attach_goal(F/A,Susp,Vars,Attachment,_),
6712 GuardCopyList = [Hole1Copy|_],
6713 Hole1Copy = (Allocation, Attachment)
6719 partner_constraint_detachments(Susps,RestHeads,VarDict,SuspsDetachments),
6720 active_constraint_detachment(Id,Susp,Head,VarDict,SuspDetachment),
6722 ( chr_pp_flag(debugable,on) ->
6723 Rule = rule(_,_,Guard,Body),
6724 my_term_copy(Guard - Body, VarDict, DebugGuard - DebugBody),
6725 sort_by_key([Susp|Susps],[ID|RestIDs],SortedSusps),
6726 DebugTry = 'chr debug_event'( try(SortedSusps,[],DebugGuard,DebugBody)),
6727 DebugApply = 'chr debug_event'(apply(SortedSusps,[],DebugGuard,DebugBody)),
6728 instrument_goal(ActualCut,DebugTry,DebugApply,Cut)
6732 ( unconditional_occurrence(F/A,O), chr_pp_flag(late_allocation,on) -> ActualCut = true ; ActualCut = (!) ),
6733 Clause = ( ClauseHead :-
6741 add_location(Clause,RuleNb,LocatedClause),
6742 L = [LocatedClause | T].
6746 add_location(Clause,RuleNb,NClause) :-
6747 ( chr_pp_flag(line_numbers,on) ->
6748 get_chr_source_file(File),
6749 get_line_number(RuleNb,LineNb),
6750 NClause = '$source_location'(File,LineNb):Clause
6755 add_dummy_location(Clause,NClause) :-
6756 ( chr_pp_flag(line_numbers,on) ->
6757 get_chr_source_file(File),
6758 NClause = '$source_location'(File,1):Clause
6762 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6763 %% head_arg_matches(+Pairs,+Modes,+VarDict,-Goal,-NVarDict) is det.
6765 % Return goal matching newly introduced variables with variables in
6766 % previously looked-up heads.
6767 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6768 head_arg_matches(Pairs,Modes,VarDict,Goal,NVarDict) :-
6769 head_arg_matches(Pairs,Modes,VarDict,Goal,NVarDict,[],_).
6771 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6772 %% head_arg_matches(+Pairs,+Modes,+VarDict,-Goal,-NVarDict,+GroundVars,-NGroundVars) is det.
6773 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6774 head_arg_matches(Pairs,Modes,VarDict,Goal,NVarDict,GroundVars,NGroundVars) :-
6775 head_arg_matches_(Pairs,Modes,VarDict,GroundVars,GoalList,NVarDict,NGroundVars),
6776 list2conj(GoalList,Goal).
6778 head_arg_matches_([],[],VarDict,GroundVars,[],VarDict,GroundVars).
6779 head_arg_matches_([silent(Arg-Var)| Rest],[Mode|Modes],VarDict,GroundVars,GoalList,NVarDict,NGroundVars) :- !,
6781 term_variables(Arg,GroundVars0,GroundVars),
6782 head_arg_matches_(Rest,Modes,VarDict,GroundVars0,GoalList,NVarDict,NGroundVars)
6784 head_arg_matches_(Rest,Modes,VarDict,GroundVars,GoalList,NVarDict,NGroundVars)
6786 head_arg_matches_([Arg-Var| Rest],[Mode|Modes],VarDict,GroundVars,GoalList,NVarDict,NGroundVars) :-
6788 ( lookup_eq(VarDict,Arg,OtherVar) ->
6790 ( memberchk_eq(Arg,GroundVars) ->
6791 GoalList = [Var = OtherVar | RestGoalList],
6792 GroundVars1 = GroundVars
6794 GoalList = [Var == OtherVar | RestGoalList],
6795 GroundVars1 = [Arg|GroundVars]
6798 GoalList = [Var == OtherVar | RestGoalList],
6799 GroundVars1 = GroundVars
6803 VarDict1 = [Arg-Var | VarDict],
6804 GoalList = RestGoalList,
6806 GroundVars1 = [Arg|GroundVars]
6808 GroundVars1 = GroundVars
6813 ; ground(Arg), Arg = '$chr_identifier_match'(ActualArg,IndexType) ->
6814 identifier_label_atom(IndexType,Var,ActualArg,Goal),
6815 GoalList = [Goal|RestGoalList],
6817 GroundVars1 = GroundVars,
6822 GoalList = [ Var = Arg | RestGoalList]
6824 GoalList = [ Var == Arg | RestGoalList]
6827 GroundVars1 = GroundVars,
6830 ; Mode == (+), is_ground(GroundVars,Arg) ->
6831 copy_with_variable_replacement(Arg,ArgCopy,VarDict),
6832 GoalList = [ Var = ArgCopy | RestGoalList],
6834 GroundVars1 = GroundVars,
6837 ; Mode == (?), is_ground(GroundVars,Arg) ->
6838 copy_with_variable_replacement(Arg,ArgCopy,VarDict),
6839 GoalList = [ Var == ArgCopy | RestGoalList],
6841 GroundVars1 = GroundVars,
6846 functor(Term,Fct,N),
6849 GoalList = [ Var = Term | RestGoalList ]
6851 GoalList = [ nonvar(Var), Var = Term | RestGoalList ]
6853 pairup(Args,Vars,NewPairs),
6854 append(NewPairs,Rest,Pairs),
6855 replicate(N,Mode,NewModes),
6856 append(NewModes,Modes,RestModes),
6858 GroundVars1 = GroundVars
6860 head_arg_matches_(Pairs,RestModes,VarDict1,GroundVars1,RestGoalList,NVarDict,NGroundVars).
6862 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6863 % add_heads_types(+ListOfHeads,+VarTypes,-NVarTypes) is det.
6864 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6865 add_heads_types([],VarTypes,VarTypes).
6866 add_heads_types([Head|Heads],VarTypes,NVarTypes) :-
6867 add_head_types(Head,VarTypes,VarTypes1),
6868 add_heads_types(Heads,VarTypes1,NVarTypes).
6870 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6871 % add_head_types(+Head,+VarTypes,-NVarTypes) is det.
6872 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6873 add_head_types(Head,VarTypes,NVarTypes) :-
6875 get_constraint_type_det(F/A,ArgTypes),
6877 add_args_types(Args,ArgTypes,VarTypes,NVarTypes).
6879 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6880 % add_args_types(+Terms,+Types,+VarTypes,-NVarTypes) is det.
6881 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6882 add_args_types([],[],VarTypes,VarTypes).
6883 add_args_types([Arg|Args],[Type|Types],VarTypes,NVarTypes) :-
6884 add_arg_types(Arg,Type,VarTypes,VarTypes1),
6885 add_args_types(Args,Types,VarTypes1,NVarTypes).
6887 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6888 % add_arg_types(+Term,+Type,+VarTypes,-NVarTypes) is det.
6889 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6890 add_arg_types(Term,Type,VarTypes,NVarTypes) :-
6892 ( lookup_eq(VarTypes,Term,_) ->
6893 NVarTypes = VarTypes
6895 NVarTypes = [Term-Type|VarTypes]
6898 NVarTypes = VarTypes
6899 ; % TODO improve approximation!
6900 term_variables(Term,Vars),
6902 replicate(VarNb,any,Types),
6903 add_args_types(Vars,Types,VarTypes,NVarTypes)
6908 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6909 %% add_heads_ground_variables(+ListOfHeads,+GroundVars,-NGroundVars) is det.
6911 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6912 add_heads_ground_variables([],GroundVars,GroundVars).
6913 add_heads_ground_variables([Head|Heads],GroundVars,NGroundVars) :-
6914 add_head_ground_variables(Head,GroundVars,GroundVars1),
6915 add_heads_ground_variables(Heads,GroundVars1,NGroundVars).
6917 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6918 %% add_head_ground_variables(+Head,+GroundVars,-GroundVars) is det.
6920 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6921 add_head_ground_variables(Head,GroundVars,NGroundVars) :-
6923 get_constraint_mode(F/A,ArgModes),
6925 add_arg_ground_variables(Args,ArgModes,GroundVars,NGroundVars).
6928 add_arg_ground_variables([],[],GroundVars,GroundVars).
6929 add_arg_ground_variables([Arg|Args],[Mode|Modes],GroundVars,NGroundVars) :-
6931 term_variables(Arg,Vars),
6932 add_var_ground_variables(Vars,GroundVars,GroundVars1)
6934 GroundVars = GroundVars1
6936 add_arg_ground_variables(Args,Modes,GroundVars1,NGroundVars).
6938 add_var_ground_variables([],GroundVars,GroundVars).
6939 add_var_ground_variables([Var|Vars],GroundVars,NGroundVars) :-
6940 ( memberchk_eq(Var,GroundVars) ->
6941 GroundVars1 = GroundVars
6943 GroundVars1 = [Var|GroundVars]
6945 add_var_ground_variables(Vars,GroundVars1,NGroundVars).
6946 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6947 %% is_ground(+GroundVars,+Term) is semidet.
6949 % Determine whether =Term= is always ground.
6950 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
6951 is_ground(GroundVars,Term) :-
6956 maplist(is_ground(GroundVars),Args)
6958 memberchk_eq(Term,GroundVars)
6961 %% check_ground(+GroundVars,+Term,-Goal) is det.
6963 % Return runtime check to see whether =Term= is ground.
6964 check_ground(GroundVars,Term,Goal) :-
6965 term_variables(Term,Variables),
6966 check_ground_variables(Variables,GroundVars,Goal).
6968 check_ground_variables([],_,true).
6969 check_ground_variables([Var|Vars],GroundVars,Goal) :-
6970 ( memberchk_eq(Var,GroundVars) ->
6971 check_ground_variables(Vars,GroundVars,Goal)
6973 Goal = (ground(Var), RGoal),
6974 check_ground_variables(Vars,GroundVars,RGoal)
6977 rest_heads_retrieval_and_matching(Heads,IDs,ActiveHead,GoalList,Susps,VarDict,NVarDict,PrevHs,PrevSusps,AttrDict) :-
6978 rest_heads_retrieval_and_matching(Heads,IDs,ActiveHead,GoalList,Susps,VarDict,NVarDict,PrevHs,PrevSusps,AttrDict,[],_).
6980 rest_heads_retrieval_and_matching(Heads,IDs,ActiveHead,GoalList,Susps,VarDict,NVarDict,PrevHs,PrevSusps,AttrDict,GroundVars,NGroundVars) :-
6982 rest_heads_retrieval_and_matching_n(Heads,IDs,PrevHs,PrevSusps,ActiveHead,GoalList,Susps,VarDict,NVarDict,AttrDict,GroundVars,NGroundVars)
6987 GroundVars = NGroundVars
6990 rest_heads_retrieval_and_matching_n([],_,_,_,_,[],[],VarDict,VarDict,_AttrDict,GroundVars,GroundVars).
6991 rest_heads_retrieval_and_matching_n([H|Hs],[ID|IDs],PrevHs,PrevSusps,ActiveHead,
6992 [Goal|Goals],[Susp|Susps],VarDict,NVarDict,_AttrDict,GroundVars,NGroundVars) :-
6994 head_info(H,A,Vars,_,_,Pairs),
6995 get_store_type(F/A,StoreType),
6996 ( StoreType == default ->
6997 passive_head_via(H,[ActiveHead|PrevHs],VarDict,ViaGoal,VarSusps),
6998 delay_phase_end(validate_store_type_assumptions,
6999 ( static_suspension_term(F/A,Suspension),
7000 get_static_suspension_term_field(arguments,F/A,Suspension,Vars),
7001 get_static_suspension_field(F/A,Suspension,state,active,GetState)
7004 % create_get_mutable_ref(active,State,GetMutable),
7005 get_constraint_mode(F/A,Mode),
7006 head_arg_matches(Pairs,Mode,VarDict,MatchingGoal,VarDict1,GroundVars,GroundVars1),
7008 sbag_member_call(Susp,VarSusps,Sbag),
7009 ExistentialLookup = (
7012 Susp = Suspension, % not inlined
7016 delay_phase_end(validate_store_type_assumptions,
7017 ( static_suspension_term(F/A,Suspension),
7018 get_static_suspension_term_field(arguments,F/A,Suspension,Vars)
7021 existential_lookup(StoreType,H,[ActiveHead|PrevHs],VarDict,GroundVars,Suspension,ExistentialLookup,Susp,Pairs,NPairs),
7022 get_constraint_mode(F/A,Mode),
7023 NMode = Mode, % filter_mode(NPairs,Pairs,Mode,NMode),
7024 head_arg_matches(NPairs,NMode,VarDict,MatchingGoal,VarDict1,GroundVars,GroundVars1)
7026 different_from_other_susps(H,Susp,PrevHs,PrevSusps,DiffSuspGoals),
7027 filter_append(NPairs,VarDict1,DA_), % order important here
7028 translate(GroundVars1,DA_,GroundVarsA),
7029 translate(GroundVars1,VarDict1,GroundVarsB),
7030 inline_matching_goal(MatchingGoal,MatchingGoal2,GroundVarsA,GroundVarsB),
7037 rest_heads_retrieval_and_matching_n(Hs,IDs,[H|PrevHs],[Susp|PrevSusps],ActiveHead,Goals,Susps,VarDict1,NVarDict,_NewAttrDict,GroundVars1,NGroundVars).
7039 inline_matching_goal(A==B,true,GVA,GVB) :-
7040 memberchk_eq(A,GVA),
7041 memberchk_eq(B,GVB),
7044 % inline_matching_goal(A=B,true,_,_) :- A=B, !.
7045 inline_matching_goal((A,B),(A2,B2),GVA,GVB) :- !,
7046 inline_matching_goal(A,A2,GVA,GVB),
7047 inline_matching_goal(B,B2,GVA,GVB).
7048 inline_matching_goal(X,X,_,_).
7051 filter_mode([],_,_,[]).
7052 filter_mode([Arg-Var|Rest],[_-V|R],[M|Ms],Modes) :-
7055 filter_mode(Rest,R,Ms,MT)
7057 filter_mode([Arg-Var|Rest],R,Ms,Modes)
7060 filter_append([],VarDict,VarDict).
7061 filter_append([X|Xs],VarDict,NVarDict) :-
7063 filter_append(Xs,VarDict,NVarDict)
7065 NVarDict = [X|NVarDict0],
7066 filter_append(Xs,VarDict,NVarDict0)
7069 check_unique_keys([],_).
7070 check_unique_keys([V|Vs],Dict) :-
7071 lookup_eq(Dict,V,_),
7072 check_unique_keys(Vs,Dict).
7074 % Generates tests to ensure the found constraint differs from previously found constraints
7075 % TODO: detect more cases where constraints need be different
7076 different_from_other_susps(Head,Susp,Heads,Susps,DiffSuspGoals) :-
7077 different_from_other_susps_(Heads,Susps,Head,Susp,DiffSuspGoalList),
7078 list2conj(DiffSuspGoalList,DiffSuspGoals).
7080 different_from_other_susps_(_,[],_,_,[]) :- !.
7081 different_from_other_susps_([PreHead|Heads],[PreSusp|Susps],Head,Susp,List) :-
7082 ( functor(Head,F,A), functor(PreHead,F,A),
7083 copy_term_nat(PreHead-Head,PreHeadCopy-HeadCopy),
7084 \+ \+ PreHeadCopy = HeadCopy ->
7086 List = [Susp \== PreSusp | Tail]
7090 different_from_other_susps_(Heads,Susps,Head,Susp,Tail).
7092 % passive_head_via(in,in,in,in,out,out,out) :-
7093 passive_head_via(Head,PrevHeads,VarDict,Goal,AllSusps) :-
7095 get_constraint_index(F/A,Pos),
7096 /* which static variables may contain runtime variables */
7097 common_variables(Head,PrevHeads,CommonVars0),
7098 ground_vars([Head],GroundVars),
7099 list_difference_eq(CommonVars0,GroundVars,CommonVars),
7100 /********************************************************/
7101 global_list_store_name(F/A,Name),
7102 GlobalGoal = nb_getval(Name,AllSusps),
7103 get_constraint_mode(F/A,ArgModes),
7106 ; member(CommonVar,CommonVars), nth1(I,ArgModes,(-)), arg(I,Head,Arg), Arg == CommonVar ->
7107 translate([CommonVar],VarDict,[Var]),
7108 gen_get_mod_constraints(F/A,Var,AttrGoal,AllSusps),
7111 translate(CommonVars,VarDict,Vars),
7112 add_heads_types(PrevHeads,[],TypeDict),
7113 my_term_copy(TypeDict,VarDict,TypeDictCopy),
7114 gen_get_mod_constraints(F/A,Vars,TypeDictCopy,ViaGoal,AttrGoal,AllSusps),
7123 common_variables(T,Ts,Vs) :-
7124 term_variables(T,V1),
7125 term_variables(Ts,V2),
7126 intersect_eq(V1,V2,Vs).
7128 gen_get_mod_constraints(FA,Vars,TypeDict,ViaGoal,AttrGoal,AllSusps) :-
7129 via_goal(Vars,TypeDict,ViaGoal,Var),
7130 get_target_module(Mod),
7132 ( get_attr(Var,Mod,TSusps),
7133 TSuspsEqSusps % TSusps = Susps
7135 get_max_constraint_index(N),
7137 TSuspsEqSusps = true, % TSusps = Susps
7140 get_constraint_index(FA,Pos),
7141 get_suspensions(N,Pos,TSusps,TSuspsEqSusps,AllSusps)
7143 via_goal(Vars,TypeDict,ViaGoal,Var) :-
7147 lookup_eq(TypeDict,A,Type),
7148 ( atomic_type(Type) ->
7152 ViaGoal = 'chr newvia_1'(A,Var)
7155 ViaGoal = 'chr newvia_2'(A,B,Var)
7157 ViaGoal = 'chr newvia'(Vars,Var)
7159 gen_get_mod_constraints(FA,Var,AttrGoal,AllSusps) :-
7160 get_target_module(Mod),
7162 ( get_attr(Var,Mod,TSusps),
7163 TSuspsEqSusps % TSusps = Susps
7165 get_max_constraint_index(N),
7167 TSuspsEqSusps = true, % TSusps = Susps
7170 get_constraint_index(FA,Pos),
7171 get_suspensions(N,Pos,TSusps,TSuspsEqSusps,AllSusps)
7174 guard_body_copies(Rule,VarDict,GuardCopy,BodyCopy) :-
7175 guard_body_copies2(Rule,VarDict,GuardCopyList,BodyCopy),
7176 list2conj(GuardCopyList,GuardCopy).
7178 guard_body_copies2(Rule,VarDict,GuardCopyList,BodyCopy) :-
7179 Rule = rule(_,H,Guard,Body),
7180 conj2list(Guard,GuardList),
7181 split_off_simple_guard(GuardList,VarDict,GuardPrefix,RestGuardList),
7182 my_term_copy(GuardPrefix-RestGuardList,VarDict,VarDict2,GuardPrefixCopy-RestGuardListCopyCore),
7184 append(GuardPrefixCopy,[RestGuardCopy],GuardCopyList),
7185 term_variables(RestGuardList,GuardVars),
7186 term_variables(RestGuardListCopyCore,GuardCopyVars),
7187 % variables that are declared to be ground don't need to be locked
7188 ground_vars(H,GroundVars),
7189 list_difference_eq(GuardVars,GroundVars,LockedGuardVars),
7190 ( chr_pp_flag(guard_locks,on),
7191 bagof(('chr lock'(Y)) - ('chr unlock'(Y)),
7192 X ^ (lists:member(X,LockedGuardVars), % X is a variable appearing in the original guard
7193 pairlist:lookup_eq(VarDict,X,Y), % translate X into new variable
7194 memberchk_eq(Y,GuardCopyVars) % redundant check? or multiple entries for X possible?
7197 once(pairup(Locks,Unlocks,LocksUnlocks))
7202 list2conj(Locks,LockPhase),
7203 list2conj(Unlocks,UnlockPhase),
7204 list2conj(RestGuardListCopyCore,RestGuardCopyCore),
7205 RestGuardCopy = (LockPhase,(RestGuardCopyCore,UnlockPhase)),
7206 my_term_copy(Body,VarDict2,BodyCopy).
7209 split_off_simple_guard([],_,[],[]).
7210 split_off_simple_guard([G|Gs],VarDict,S,C) :-
7211 ( simple_guard(G,VarDict) ->
7213 split_off_simple_guard(Gs,VarDict,Ss,C)
7219 % simple guard: cheap and benign (does not bind variables)
7220 simple_guard(G,VarDict) :-
7222 \+ (( member(V,Vars),
7223 lookup_eq(VarDict,V,_)
7226 active_constraint_detachment(Id,Susp,Head,VarDict,SuspDetachment) :-
7232 Id == [0], chr_pp_flag(store_in_guards, off)
7234 ( get_allocation_occurrence(C,AO),
7235 get_max_occurrence(C,MO),
7238 only_ground_indexed_arguments(C), chr_pp_flag(late_allocation,on) ->
7239 SuspDetachment = true
7241 gen_uncond_susp_detachment(Head,Susp,active,VarDict,UnCondSuspDetachment),
7242 ( chr_pp_flag(late_allocation,on) ->
7247 UnCondSuspDetachment
7250 SuspDetachment = UnCondSuspDetachment
7254 SuspDetachment = true
7257 partner_constraint_detachments([],[],_,true).
7258 partner_constraint_detachments([Susp|Susps],[Head|Heads],VarDict,(SuspDetachment,SuspsDetachments)) :-
7259 gen_uncond_susp_detachment(Head,Susp,partner,VarDict,SuspDetachment),
7260 partner_constraint_detachments(Susps,Heads,VarDict,SuspsDetachments).
7262 gen_uncond_susp_detachment(Head,Susp,Role,VarDict,SuspDetachment) :-
7266 SuspDetachment = ( DebugEvent, RemoveInternalGoal),
7267 ( chr_pp_flag(debugable,on) ->
7268 DebugEvent = 'chr debug_event'(remove(Susp))
7272 remove_constraint_goal(C,Susp,Vars,true,(DeleteCall,Detach),Role,RemoveInternalGoal),
7273 delete_constraint_goal(Head,Susp,VarDict,DeleteCall),
7274 ( \+ only_ground_indexed_arguments(C), \+ get_store_type(C,var_assoc_store(_,_)) ->
7275 detach_constraint_atom(C,Vars,Susp,Detach)
7280 SuspDetachment = true
7283 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7285 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7287 %% / ___|(_)_ __ ___ _ __ __ _ __ _ __ _| |_(_) ___ _ __ / |
7288 %% \___ \| | '_ ` _ \| '_ \ / _` |/ _` |/ _` | __| |/ _ \| '_ \ | |
7289 %% ___) | | | | | | | |_) | (_| | (_| | (_| | |_| | (_) | | | | | |
7290 %% |____/|_|_| |_| |_| .__/ \__,_|\__, |\__,_|\__|_|\___/|_| |_| |_|
7294 simpagation_head1_code(Head,ID,RestHeads,OtherIDs,PragmaRule,F/A,O,Id,L,T) :-
7295 PragmaRule = pragma(Rule,ids(_,Heads2IDs),Pragmas,_Name,RuleNb),
7296 Rule = rule(_Heads,Heads2,Guard,Body),
7298 head_info(Head,A,Vars,Susp,HeadVars,HeadPairs),
7299 get_constraint_mode(F/A,Mode),
7300 head_arg_matches(HeadPairs,Mode,[],FirstMatching,VarDict1,[],GroundVars),
7302 build_head(F,A,Id,HeadVars,ClauseHead),
7304 append(RestHeads,Heads2,Heads),
7305 append(OtherIDs,Heads2IDs,IDs),
7306 reorder_heads(RuleNb,Head,Heads,IDs,NHeads,NIDs),
7308 guard_splitting(Rule,GuardList0),
7309 ( is_stored_in_guard(F/A, RuleNb) ->
7310 GuardList = [Hole1|GuardList0]
7312 GuardList = GuardList0
7314 guard_via_reschedule_new(NHeads,GuardList,Head,GuardCopyList,GetRestHeads,RescheduledTest),
7316 rest_heads_retrieval_and_matching(NHeads,NIDs,Head,GetRestHeads,Susps,VarDict1,VarDict,[],[],[],GroundVars,_),
7317 split_by_ids(NIDs,Susps,OtherIDs,Susps1,Susps1IDs,Susps2,Susps2IDs),
7319 guard_body_copies3(Rule,GuardList,VarDict,GuardCopyList,BodyCopy),
7321 ( is_stored_in_guard(F/A, RuleNb) ->
7322 gen_uncond_attach_goal(F/A,Susp,Vars,Attachment,_),
7323 GuardCopyList = [Hole1Copy|_],
7324 Hole1Copy = Attachment
7329 sort_by_key(Susps1,Susps1IDs,SortedSusps1),
7330 partner_constraint_detachments(SortedSusps1,RestHeads,VarDict,SuspsDetachments),
7331 active_constraint_detachment(Id,Susp,Head,VarDict,SuspDetachment),
7333 ( chr_pp_flag(debugable,on) ->
7334 my_term_copy(Guard - Body, VarDict, DebugGuard - DebugBody),
7335 sort_by_key([Susp|Susps1],[ID|Susps1IDs],RemovedSusps),
7336 sort_by_key(Susps2,Susps2IDs,KeptSusps),
7337 DebugTry = 'chr debug_event'( try(RemovedSusps,KeptSusps,DebugGuard,DebugBody)),
7338 DebugApply = 'chr debug_event'(apply(RemovedSusps,KeptSusps,DebugGuard,DebugBody)),
7339 instrument_goal((!),DebugTry,DebugApply,Cut)
7344 Clause = ( ClauseHead :-
7352 add_location(Clause,RuleNb,LocatedClause),
7353 L = [LocatedClause | T].
7357 split_by_ids([],[],_,[],[]).
7358 split_by_ids([I|Is],[S|Ss],I1s,S1s,S2s) :-
7359 ( memberchk_eq(I,I1s) ->
7366 split_by_ids(Is,Ss,I1s,R1s,R2s).
7368 split_by_ids([],[],_,[],[],[],[]).
7369 split_by_ids([I|Is],[S|Ss],I1s,S1s,SI1s,S2s,SI2s) :-
7370 ( memberchk_eq(I,I1s) ->
7381 split_by_ids(Is,Ss,I1s,R1s,RSI1s,R2s,RSI2s).
7382 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7385 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7387 %% / ___|(_)_ __ ___ _ __ __ _ __ _ __ _| |_(_) ___ _ __ |___ \
7388 %% \___ \| | '_ ` _ \| '_ \ / _` |/ _` |/ _` | __| |/ _ \| '_ \ __) |
7389 %% ___) | | | | | | | |_) | (_| | (_| | (_| | |_| | (_) | | | | / __/
7390 %% |____/|_|_| |_| |_| .__/ \__,_|\__, |\__,_|\__|_|\___/|_| |_| |_____|
7393 %% Genereate prelude + worker predicate
7394 %% prelude calls worker
7395 %% worker iterates over one type of removed constraints
7396 simpagation_head2_code(Head2,ID,RestHeads2,RestIDs,PragmaRule,FA,O,Id,L,T) :-
7397 PragmaRule = pragma(Rule,ids(IDs1,IDs2),Pragmas,_Name,RuleNb),
7398 Rule = rule(Heads1,_,Guard,Body),
7399 append(Heads1,RestHeads2,Heads),
7400 append(IDs1,RestIDs,IDs),
7401 reorder_heads(RuleNb,Head2,Heads,IDs,[NHead|NHeads],[NID|NIDs]),
7402 simpagation_head2_prelude(Head2,NHead,[NHeads,Guard,Body],FA,O,Id,L,L1),
7404 ( memberchk_eq(NID,IDs2) ->
7405 simpagation_universal_searches(NHeads,NIDs,IDs2,[NHead,Head2],Rule,FA,O,NextHeads,PreHeads,NextIDs,Id1,Id2,L1,L2)
7407 L1 = L2, Id1 = Id2,NextHeads = NHeads, PreHeads = [NHead,Head2], NextIDs = NIDs
7409 universal_search_iterator_end(PreHeads,NextHeads,Rule,FA,O,Id2,L2,L3),
7410 simpagation_head2_worker(PreHeads,NextHeads,NextIDs,ID,PragmaRule,FA,O,Id2,L3,T).
7412 simpagation_universal_searches([],[],_,PreHeads,_,_,_,[],PreHeads,[],Id,Id,L,L).
7413 simpagation_universal_searches(Heads,[ID|IDs],IDs2,PreHeads,Rule,C,O,OutHeads,OutPreHeads,OutIDs,Id,NId,L,T) :-
7414 Heads = [Head|RHeads],
7416 universal_search_iterator_end(PreHeads,Heads,Rule,C,O,Id,L,L0),
7417 universal_search_iterator(Heads,PreHeads,Rule,C,O,Id,L0,L1),
7418 ( memberchk_eq(ID,IDs2) ->
7419 simpagation_universal_searches(RHeads,IDs,IDs2,[Head|PreHeads],Rule,C,O,OutHeads,OutPreHeads,OutIDs,Id1,NId,L1,T)
7421 NId = Id1, L1 = T, OutHeads = RHeads, OutPreHeads = [Head|PreHeads], IDs = OutIDs
7424 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7425 simpagation_head2_prelude(Head,Head1,Rest,F/A,O,Id1,L,T) :-
7426 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs),
7427 build_head(F,A,Id1,VarsSusp,ClauseHead),
7428 get_constraint_mode(F/A,Mode),
7429 head_arg_matches(HeadPairs,Mode,[],FirstMatching,VarDict,[],GroundVars),
7431 lookup_passive_head(Head1,[Head],VarDict,GroundVars,ModConstraintsGoal,AllSusps),
7433 gen_occ_allocation(F/A,O,Vars,Susp,ConstraintAllocationGoal),
7435 extend_id(Id1,DelegateId),
7436 extra_active_delegate_variables(Head,[Head1|Rest],VarDict,ExtraVars),
7437 append([AllSusps|VarsSusp],ExtraVars,DelegateCallVars),
7438 build_head(F,A,[O|DelegateId],DelegateCallVars,Delegate),
7445 ConstraintAllocationGoal,
7448 add_dummy_location(PreludeClause,LocatedPreludeClause),
7449 L = [LocatedPreludeClause|T].
7451 extra_active_delegate_variables(Term,Terms,VarDict,Vars) :-
7453 delegate_variables(Term,Terms,VarDict,Args,Vars).
7455 passive_delegate_variables(Term,PrevTerms,NextTerms,VarDict,Vars) :-
7456 term_variables(PrevTerms,PrevVars),
7457 delegate_variables(Term,NextTerms,VarDict,PrevVars,Vars).
7459 delegate_variables(Term,Terms,VarDict,PrevVars,Vars) :-
7460 term_variables(Term,V1),
7461 term_variables(Terms,V2),
7462 intersect_eq(V1,V2,V3),
7463 list_difference_eq(V3,PrevVars,V4),
7464 translate(V4,VarDict,Vars).
7467 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7468 simpagation_head2_worker([CurrentHead|PreHeads],NextHeads,NextIDs,ID,PragmaRule,F/A,O,Id,L,T) :-
7469 PragmaRule = pragma(Rule,ids(IDs1,_),Pragmas,_,RuleNb),
7470 Rule = rule(_,_,Guard,Body),
7471 get_prop_inner_loop_vars(PreHeads,[CurrentHead,NextHeads,Guard,Body],PreVarsAndSusps,VarDict,Susp,Vars,PreSusps),
7474 gen_var(OtherSusps),
7476 functor(CurrentHead,OtherF,OtherA),
7477 gen_vars(OtherA,OtherVars),
7478 head_info(CurrentHead,OtherA,OtherVars,OtherSusp,_VarsSusp,HeadPairs),
7479 get_constraint_mode(OtherF/OtherA,Mode),
7480 head_arg_matches(HeadPairs,Mode,VarDict,FirstMatching,VarDict1,[],GroundVars),
7482 delay_phase_end(validate_store_type_assumptions,
7483 ( static_suspension_term(OtherF/OtherA,OtherSuspension),
7484 get_static_suspension_field(OtherF/OtherA,OtherSuspension,state,active,GetState),
7485 get_static_suspension_term_field(arguments,OtherF/OtherA,OtherSuspension,OtherVars)
7488 % create_get_mutable_ref(active,State,GetMutable),
7489 different_from_other_susps(CurrentHead,OtherSusp,PreHeads,PreSusps,DiffSuspGoals),
7491 OtherSusp = OtherSuspension,
7497 ClauseVars = [[OtherSusp|OtherSusps]|PreVarsAndSusps],
7498 build_head(F,A,[O|Id],ClauseVars,ClauseHead),
7500 guard_splitting(Rule,GuardList0),
7501 ( is_stored_in_guard(F/A, RuleNb) ->
7502 GuardList = [Hole1|GuardList0]
7504 GuardList = GuardList0
7506 guard_via_reschedule_new(NextHeads,GuardList,[CurrentHead|PreHeads],GuardCopyList,RestSuspsRetrieval,RescheduledTest),
7508 rest_heads_retrieval_and_matching(NextHeads,NextIDs,[CurrentHead|PreHeads],RestSuspsRetrieval,Susps,VarDict1,VarDict2,[CurrentHead|PreHeads],[OtherSusp|PreSusps],[]),
7509 split_by_ids(NextIDs,Susps,IDs1,Susps1,Susps2),
7510 split_by_ids(NextIDs,NextHeads,IDs1,RestHeads1,_),
7512 partner_constraint_detachments([OtherSusp | Susps1],[CurrentHead|RestHeads1],VarDict2,Susps1Detachments),
7514 RecursiveVars = [OtherSusps|PreVarsAndSusps],
7515 build_head(F,A,[O|Id],RecursiveVars,RecursiveCall),
7516 RecursiveVars2 = [[]|PreVarsAndSusps],
7517 build_head(F,A,[O|Id],RecursiveVars2,RecursiveCall2),
7519 guard_body_copies3(Rule,GuardList,VarDict2,GuardCopyList,BodyCopy),
7520 ( is_stored_in_guard(F/A, RuleNb) ->
7521 GuardCopyList = [GuardAttachment|_] % once( ) ??
7526 ( is_observed(F/A,O) ->
7527 gen_uncond_attach_goal(F/A,Susp,Vars,Attachment,Generation),
7528 gen_state_cond_call(Susp,F/A,RecursiveCall,Generation,ConditionalRecursiveCall),
7529 gen_state_cond_call(Susp,F/A,RecursiveCall2,Generation,ConditionalRecursiveCall2)
7532 ConditionalRecursiveCall = RecursiveCall,
7533 ConditionalRecursiveCall2 = RecursiveCall2
7536 ( chr_pp_flag(debugable,on) ->
7537 my_term_copy(Guard - Body, VarDict, DebugGuard - DebugBody),
7538 DebugTry = 'chr debug_event'( try([OtherSusp|Susps1],[Susp|Susps2],DebugGuard,DebugBody)),
7539 DebugApply = 'chr debug_event'(apply([OtherSusp|Susps1],[Susp|Susps2],DebugGuard,DebugBody))
7545 ( is_stored_in_guard(F/A, RuleNb) ->
7546 GuardAttachment = Attachment,
7547 BodyAttachment = true
7549 GuardAttachment = true,
7550 BodyAttachment = Attachment % will be true if not observed at all
7553 ( member(unique(ID1,UniqueKeys), Pragmas),
7554 check_unique_keys(UniqueKeys,VarDict) ->
7557 ( CurrentSuspTest ->
7564 ConditionalRecursiveCall2
7582 ConditionalRecursiveCall
7588 add_location(Clause,RuleNb,LocatedClause),
7589 L = [LocatedClause | T].
7591 gen_state_cond_call(Susp,FA,Call,Generation,ConditionalCall) :-
7592 ( may_trigger(FA) ->
7593 does_use_field(FA,generation),
7594 delay_phase_end(validate_store_type_assumptions,
7595 ( static_suspension_term(FA,Suspension),
7596 get_update_static_suspension_field(FA,Susp,Suspension,state,active,inactive,GetState,UpdateState),
7597 get_static_suspension_field(FA,Suspension,generation,Generation,GetGeneration),
7598 get_static_suspension_term_field(arguments,FA,Suspension,Args)
7602 delay_phase_end(validate_store_type_assumptions,
7603 ( static_suspension_term(FA,Suspension),
7604 get_update_static_suspension_field(FA,Susp,Suspension,state,active,inactive,GetState,UpdateState),
7605 get_static_suspension_term_field(arguments,FA,Suspension,Args)
7608 GetGeneration = true
7611 ( Susp = Suspension,
7620 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7623 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7625 %% | _ \ _ __ ___ _ __ __ _ __ _ __ _| |_(_) ___ _ __
7626 %% | |_) | '__/ _ \| '_ \ / _` |/ _` |/ _` | __| |/ _ \| '_ \
7627 %% | __/| | | (_) | |_) | (_| | (_| | (_| | |_| | (_) | | | |
7628 %% |_| |_| \___/| .__/ \__,_|\__, |\__,_|\__|_|\___/|_| |_|
7631 propagation_code(Head,ID,RestHeads,RestIDs,Rule,RuleNb,FA,O,Id,L,T) :-
7632 ( RestHeads == [] ->
7633 propagation_single_headed(Head,ID,Rule,RuleNb,FA,O,Id,L,T)
7635 propagation_multi_headed(Head,RestHeads,RestIDs,Rule,RuleNb,FA,O,Id,L,T)
7637 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7638 %% Single headed propagation
7639 %% everything in a single clause
7640 propagation_single_headed(Head,ID,Rule,RuleNb,F/A,O,Id,ProgramList,ProgramTail) :-
7641 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs),
7642 build_head(F,A,Id,VarsSusp,ClauseHead),
7645 build_head(F,A,NextId,VarsSusp,NextHead),
7647 get_constraint_mode(F/A,Mode),
7648 head_arg_matches(HeadPairs,Mode,[],HeadMatching,VarDict,[],GroundVars),
7649 guard_body_copies(Rule,VarDict,GuardCopy,BodyCopy),
7651 % - recursive call -
7652 RecursiveCall = NextHead,
7654 ( unconditional_occurrence(F/A,O), chr_pp_flag(late_allocation,on) ->
7660 Rule = rule(_,_,Guard,Body),
7661 ( chr_pp_flag(debugable,on) ->
7662 my_term_copy(Guard - Body, VarDict, DebugGuard - DebugBody),
7663 DebugTry = 'chr debug_event'( try([],[Susp],DebugGuard,DebugBody)),
7664 DebugApply = 'chr debug_event'(apply([],[Susp],DebugGuard,DebugBody)),
7665 instrument_goal(ActualCut,DebugTry,DebugApply,Cut)
7669 ( may_trigger(F/A), \+ has_no_history(RuleNb)->
7670 use_auxiliary_predicate(novel_production),
7671 use_auxiliary_predicate(extend_history),
7672 does_use_history(F/A,O),
7673 gen_occ_allocation(F/A,O,Vars,Susp,Allocation),
7675 ( named_history(RuleNb,HistoryName,HistoryIDs) ->
7676 ( HistoryIDs == [] ->
7677 empty_named_history_novel_production(HistoryName,NovelProduction),
7678 empty_named_history_extend_history(HistoryName,ExtendHistory)
7686 ( var(NovelProduction) ->
7687 NovelProduction = '$novel_production'(Susp,Tuple),
7688 ExtendHistory = '$extend_history'(Susp,Tuple)
7693 ( is_observed(F/A,O) ->
7694 gen_uncond_attach_goal(F/A,Susp,Vars,Attachment,Generation),
7695 gen_state_cond_call(Susp,F/A,RecursiveCall,Generation,ConditionalRecursiveCall)
7698 ConditionalRecursiveCall = RecursiveCall
7702 NovelProduction = true,
7703 ExtendHistory = true,
7705 ( is_observed(F/A,O) ->
7706 get_allocation_occurrence(F/A,AllocO),
7708 gen_insert_constraint_internal_goal(F/A,Attachment,VarsSusp,Vars,Susp),
7710 ; % more room for improvement?
7711 Attachment = (Attachment1, Attachment2),
7712 gen_occ_allocation(F/A,O,Vars,Susp,Attachment1),
7713 gen_uncond_attach_goal(F/A,Susp,Vars,Attachment2,Generation)
7715 gen_state_cond_call(Susp,F/A,RecursiveCall,Generation,ConditionalRecursiveCall)
7717 gen_occ_allocation(F/A,O,Vars,Susp,Attachment),
7718 ConditionalRecursiveCall = RecursiveCall
7722 ( is_stored_in_guard(F/A, RuleNb) ->
7723 GuardAttachment = Attachment,
7724 BodyAttachment = true
7726 GuardAttachment = true,
7727 BodyAttachment = Attachment % will be true if not observed at all
7741 ConditionalRecursiveCall
7743 add_location(Clause,RuleNb,LocatedClause),
7744 ProgramList = [LocatedClause | ProgramTail].
7746 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7747 %% multi headed propagation
7748 %% prelude + predicates to accumulate the necessary combinations of suspended
7749 %% constraints + predicate to execute the body
7750 propagation_multi_headed(Head,RestHeads,RestIDs,Rule,RuleNb,FA,O,Id,L,T) :-
7751 RestHeads = [First|Rest],
7752 propagation_prelude(Head,RestHeads,Rule,FA,O,Id,L,L1),
7753 extend_id(Id,ExtendedId),
7754 propagation_nested_code(Rest,[First,Head],RestIDs,Rule,RuleNb,FA,O,ExtendedId,L1,T).
7756 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7757 propagation_prelude(Head,[First|Rest],Rule,F/A,O,Id,L,T) :-
7758 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs),
7759 build_head(F,A,Id,VarsSusp,PreludeHead),
7760 get_constraint_mode(F/A,Mode),
7761 head_arg_matches(HeadPairs,Mode,[],FirstMatching,VarDict,[],GroundVars),
7762 Rule = rule(_,_,Guard,Body),
7763 extra_active_delegate_variables(Head,[First,Rest,Guard,Body],VarDict,ExtraVars),
7765 lookup_passive_head(First,[Head],VarDict,GroundVars,FirstSuspGoal,Susps),
7767 gen_occ_allocation(F/A,O,Vars,Susp,CondAllocation),
7769 extend_id(Id,NestedId),
7770 append([Susps|VarsSusp],ExtraVars,NestedVars),
7771 build_head(F,A,[O|NestedId],NestedVars,NestedHead),
7772 NestedCall = NestedHead,
7782 add_dummy_location(Prelude,LocatedPrelude),
7783 L = [LocatedPrelude|T].
7785 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7786 propagation_nested_code([],[CurrentHead|PreHeads],RestIDs,Rule,RuleNb,FA,O,Id,L,T) :-
7787 universal_search_iterator_end([CurrentHead|PreHeads],[],Rule,FA,O,Id,L,L1),
7788 propagation_body(CurrentHead,PreHeads,RestIDs,Rule,RuleNb,FA,O,Id,L1,T).
7790 propagation_nested_code([Head|RestHeads],PreHeads,RestIDs,Rule,RuleNb,FA,O,Id,L,T) :-
7791 universal_search_iterator_end(PreHeads,[Head|RestHeads],Rule,FA,O,Id,L,L1),
7792 universal_search_iterator([Head|RestHeads],PreHeads,Rule,FA,O,Id,L1,L2),
7794 propagation_nested_code(RestHeads,[Head|PreHeads],RestIDs,Rule,RuleNb,FA,O,IncId,L2,T).
7796 %check_fd_lookup_condition(_,_,_,_) :- fail.
7797 check_fd_lookup_condition(F,A,_,_) :-
7798 get_store_type(F/A,global_singleton), !.
7799 check_fd_lookup_condition(F,A,CurrentHead,PreHeads) :-
7800 \+ may_trigger(F/A),
7801 get_functional_dependency(F/A,1,P,K),
7802 copy_term(P-K,CurrentHead-Key),
7803 term_variables(PreHeads,PreVars),
7804 intersect_eq(Key,PreVars,Key),!.
7806 propagation_body(CurrentHead,PreHeads,RestIDs,Rule,RuleNb,F/A,O,Id,L,T) :-
7807 Rule = rule(_,H2,Guard,Body),
7808 gen_var_susp_list_for_b(PreHeads,[CurrentHead,Guard,Body],VarDict1,PreVarsAndSuspsList,FirstVarsSusp,AllSusps,PrevIterators),
7809 flatten(PreVarsAndSuspsList,PreVarsAndSusps),
7810 init(AllSusps,RestSusps),
7811 last(AllSusps,Susp),
7813 gen_var(OtherSusps),
7814 functor(CurrentHead,OtherF,OtherA),
7815 gen_vars(OtherA,OtherVars),
7816 delay_phase_end(validate_store_type_assumptions,
7817 ( static_suspension_term(OtherF/OtherA,Suspension),
7818 get_static_suspension_field(OtherF/OtherA,Suspension,state,active,GetState),
7819 get_static_suspension_term_field(arguments,OtherF/OtherA,Suspension,OtherVars)
7822 % create_get_mutable_ref(active,State,GetMutable),
7824 OtherSusp = Suspension,
7827 ClauseVars = [[OtherSusp|OtherSusps]|PreVarsAndSusps],
7828 build_head(F,A,[O|Id],ClauseVars,ClauseHead),
7829 ( check_fd_lookup_condition(OtherF,OtherA,CurrentHead,PreHeads) -> % iterator (OtherSusps) is empty at runtime
7830 universal_search_iterator_failure_vars(PreHeads,Id,PreVarsAndSuspsList,FirstVarsSusp,PrevIterators,PreVarsAndSusps1,PrevId0),
7831 RecursiveVars = PreVarsAndSusps1
7833 RecursiveVars = [OtherSusps|PreVarsAndSusps],
7839 PrevId = [O|PrevId0]
7841 build_head(F,A,PrevId,RecursiveVars,RecursiveHead),
7842 RecursiveCall = RecursiveHead,
7843 CurrentHead =.. [_|OtherArgs],
7844 pairup(OtherArgs,OtherVars,OtherPairs),
7845 get_constraint_mode(OtherF/OtherA,Mode),
7846 head_arg_matches(OtherPairs,Mode,VarDict1,Matching,VarDict),
7848 different_from_other_susps(CurrentHead,OtherSusp,PreHeads,RestSusps,DiffSuspGoals),
7849 guard_body_copies(Rule,VarDict,GuardCopy,BodyCopy),
7850 get_occurrence(F/A,O,_,ID),
7852 ( is_observed(F/A,O) ->
7853 init(FirstVarsSusp,FirstVars),
7854 gen_uncond_attach_goal(F/A,Susp,FirstVars,Attachment,Generation),
7855 gen_state_cond_call(Susp,F/A,RecursiveCall,Generation,ConditionalRecursiveCall)
7858 ConditionalRecursiveCall = RecursiveCall
7860 ( (is_least_occurrence(RuleNb) ; has_no_history(RuleNb)) ->
7861 NovelProduction = true,
7862 ExtendHistory = true
7863 ; \+ may_trigger(F/A), maplist(is_passive(RuleNb),RestIDs) ->
7864 NovelProduction = true,
7865 ExtendHistory = true
7867 get_occurrence(F/A,O,_,ID),
7868 use_auxiliary_predicate(novel_production),
7869 use_auxiliary_predicate(extend_history),
7870 does_use_history(F/A,O),
7871 ( named_history(RuleNb,HistoryName,HistoryIDs) ->
7872 ( HistoryIDs == [] ->
7873 empty_named_history_novel_production(HistoryName,NovelProduction),
7874 empty_named_history_extend_history(HistoryName,ExtendHistory)
7876 reverse([OtherSusp|RestSusps],NamedSusps),
7877 named_history_susps(HistoryIDs,[ID|RestIDs],[Susp|NamedSusps],HistorySusps),
7878 HistorySusps = [HistorySusp|_],
7880 ( length(HistoryIDs, 1) ->
7881 ExtendHistory = '$extend_history'(HistorySusp,HistoryName),
7882 NovelProduction = '$novel_production'(HistorySusp,HistoryName)
7884 findall(ConstraintSymbol,(member(SomeID,HistoryIDs),get_occurrence_from_id(ConstraintSymbol,_,RuleNb,SomeID)),ConstraintSymbols),
7885 Tuple =.. [t,HistoryName|HistorySusps]
7890 maplist(extract_symbol,H2,ConstraintSymbols),
7891 sort([ID|RestIDs],HistoryIDs),
7892 history_susps(RestIDs,[OtherSusp|RestSusps],Susp,ID,HistorySusps),
7893 Tuple =.. [t,RuleNb|HistorySusps]
7896 ( var(NovelProduction) ->
7897 novel_production_calls(ConstraintSymbols,HistoryIDs,HistorySusps,RuleNb,TupleVar,NovelProductions),
7898 ExtendHistory = '$extend_history'(HistorySusp,TupleVar),
7899 NovelProduction = ( TupleVar = Tuple, NovelProductions )
7906 ( chr_pp_flag(debugable,on) ->
7907 Rule = rule(_,_,Guard,Body),
7908 my_term_copy(Guard - Body, VarDict, DebugGuard - DebugBody),
7909 get_occurrence(F/A,O,_,ID),
7910 sort_by_key([Susp,OtherSusp|RestSusps],[ID|RestIDs],KeptSusps),
7911 DebugTry = 'chr debug_event'( try([],KeptSusps,DebugGuard,DebugBody)),
7912 DebugApply = 'chr debug_event'(apply([],KeptSusps,DebugGuard,DebugBody))
7918 ( is_stored_in_guard(F/A, RuleNb) ->
7919 GuardAttachment = Attachment,
7920 BodyAttachment = true
7922 GuardAttachment = true,
7923 BodyAttachment = Attachment % will be true if not observed at all
7939 ConditionalRecursiveCall
7943 add_location(Clause,RuleNb,LocatedClause),
7944 L = [LocatedClause|T].
7946 extract_symbol(Head,F/A) :-
7949 novel_production_calls([],[],[],_,_,true).
7950 novel_production_calls([ConstraintSymbol|ConstraintSymbols],[ID|IDs],[Suspension|Suspensions],RuleNb,Tuple,(Goal,Goals)) :-
7951 get_occurrence_from_id(ConstraintSymbol,Occurrence,RuleNb,ID),
7952 delay_phase_end(validate_store_type_assumptions,novel_production_call(ConstraintSymbol,Occurrence,'$novel_production'(Suspension,Tuple),Goal)),
7953 novel_production_calls(ConstraintSymbols,IDs,Suspensions,RuleNb,Tuple,Goals).
7955 history_susps(RestIDs,ReversedRestSusps,Susp,ID,HistorySusps) :-
7956 reverse(ReversedRestSusps,RestSusps),
7957 sort_by_key([Susp|RestSusps],[ID|RestIDs],HistorySusps).
7959 named_history_susps([],_,_,[]).
7960 named_history_susps([HistoryID|HistoryIDs],IDs,Susps,[HistorySusp|HistorySusps]) :-
7961 select2(HistoryID,HistorySusp,IDs,Susps,RestIDs,RestSusps), !,
7962 named_history_susps(HistoryIDs,RestIDs,RestSusps,HistorySusps).
7966 gen_var_susp_list_for([Head],Terms,VarDict,HeadVars,VarsSusp,Susp) :-
7969 head_info(Head,A,_Vars,Susp,VarsSusp,HeadPairs),
7970 get_constraint_mode(F/A,Mode),
7971 head_arg_matches(HeadPairs,Mode,[],_,VarDict),
7972 extra_active_delegate_variables(Head,Terms,VarDict,ExtraVars),
7973 append(VarsSusp,ExtraVars,HeadVars).
7974 gen_var_susp_list_for([Head|Heads],Terms,NVarDict,VarsSusps,Rest,Susps) :-
7975 gen_var_susp_list_for(Heads,[Head|Terms],VarDict,Rest,_,_),
7978 head_info(Head,A,_Vars,Susp,_VarsSusp,HeadPairs),
7979 get_constraint_mode(F/A,Mode),
7980 head_arg_matches(HeadPairs,Mode,VarDict,_,NVarDict),
7981 passive_delegate_variables(Head,Heads,Terms,NVarDict,HeadVars),
7982 append(HeadVars,[Susp,Susps|Rest],VarsSusps).
7985 % VarDict for the copies of variables in the original heads
7986 % VarsSuspsList list of lists of arguments for the successive heads
7987 % FirstVarsSusp top level arguments
7988 % SuspList list of all suspensions
7989 % Iterators list of all iterators
7990 gen_var_susp_list_for_b([Head],NextHeads,VarDict,[HeadVars],VarsSusp,[Susp],[]) :-
7993 head_info(Head,A,_Vars,Susp,VarsSusp,Pairs), % make variables for argument positions
7994 get_constraint_mode(F/A,Mode),
7995 head_arg_matches(Pairs,Mode,[],_,VarDict), % copy variables inside arguments, build dictionary
7996 extra_active_delegate_variables(Head,NextHeads,VarDict,ExtraVars), % decide what additional variables are needed
7997 append(VarsSusp,ExtraVars,HeadVars). % add additional variables to head variables
7998 gen_var_susp_list_for_b([Head|Heads],NextHeads,NVarDict,[Vars|RestVars],FirstVarsSusp,[Susp|SuspList],[Susps|Iterators]) :-
7999 gen_var_susp_list_for_b(Heads,[Head|NextHeads],VarDict,RestVars,FirstVarsSusp,SuspList,Iterators),
8002 head_info(Head,A,_Vars,Susp,_VarsSusp,HeadPairs),
8003 get_constraint_mode(F/A,Mode),
8004 head_arg_matches(HeadPairs,Mode,VarDict,_,NVarDict),
8005 passive_delegate_variables(Head,Heads,NextHeads,NVarDict,HeadVars),
8006 append(HeadVars,[Susp,Susps],Vars).
8008 get_prop_inner_loop_vars([Head],NextHeads,HeadVars,VarDict,Susp,Vars,[]) :-
8011 head_info(Head,A,Vars,Susp,VarsSusp,Pairs),
8012 get_constraint_mode(F/A,Mode),
8013 head_arg_matches(Pairs,Mode,[],_,VarDict),
8014 extra_active_delegate_variables(Head,NextHeads,VarDict,ExtraVars),
8015 append(VarsSusp,ExtraVars,HeadVars).
8016 get_prop_inner_loop_vars([Head|Heads],Terms,VarsSusps,NVarDict,MainSusp,MainVars,[Susp|RestSusps]) :-
8017 get_prop_inner_loop_vars(Heads,[Head|Terms],RestVarsSusp,VarDict,MainSusp,MainVars,RestSusps),
8020 head_info(Head,A,_Vars,Susp,_VarsSusp,Pairs),
8021 get_constraint_mode(F/A,Mode),
8022 head_arg_matches(Pairs,Mode,VarDict,_,NVarDict),
8023 passive_delegate_variables(Head,Heads,Terms,NVarDict,HeadVars),
8024 append(HeadVars,[Susp,Susps|RestVarsSusp],VarsSusps).
8026 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8028 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8030 %% | _ \ __ _ ___ ___(_)_ _____ | | | | ___ __ _ __| |
8031 %% | |_) / _` / __/ __| \ \ / / _ \ | |_| |/ _ \/ _` |/ _` |
8032 %% | __/ (_| \__ \__ \ |\ V / __/ | _ | __/ (_| | (_| |
8033 %% |_| \__,_|___/___/_| \_/ \___| |_| |_|\___|\__,_|\__,_|
8036 %% | _ \ ___| |_ _ __(_) _____ ____ _| |
8037 %% | |_) / _ \ __| '__| |/ _ \ \ / / _` | |
8038 %% | _ < __/ |_| | | | __/\ V / (_| | |
8039 %% |_| \_\___|\__|_| |_|\___| \_/ \__,_|_|
8042 %% | _ \ ___ ___ _ __ __| | ___ _ __(_)_ __ __ _
8043 %% | |_) / _ \/ _ \| '__/ _` |/ _ \ '__| | '_ \ / _` |
8044 %% | _ < __/ (_) | | | (_| | __/ | | | | | | (_| |
8045 %% |_| \_\___|\___/|_| \__,_|\___|_| |_|_| |_|\__, |
8048 reorder_heads(RuleNb,Head,RestHeads,RestIDs,NRestHeads,NRestIDs) :-
8049 ( chr_pp_flag(reorder_heads,on), length(RestHeads,Length), Length =< 6 ->
8050 reorder_heads_main(RuleNb,Head,RestHeads,RestIDs,NRestHeads,NRestIDs)
8052 NRestHeads = RestHeads,
8056 reorder_heads_main(RuleNb,Head,RestHeads,RestIDs,NRestHeads,NRestIDs) :-
8057 term_variables(Head,Vars),
8058 InitialData = entry([],[],Vars,RestHeads,RestIDs,RuleNb),
8059 copy_term_nat(InitialData,InitialDataCopy),
8060 a_star(InitialDataCopy,FD^(chr_translate:final_data(FD)),N^EN^C^(chr_translate:expand_data(N,EN,C)),FinalData),
8061 InitialDataCopy = InitialData,
8062 FinalData = entry(RNRestHeads,RNRestIDs,_,_,_,_),
8063 reverse(RNRestHeads,NRestHeads),
8064 reverse(RNRestIDs,NRestIDs).
8066 final_data(Entry) :-
8067 Entry = entry(_,_,_,_,[],_).
8069 expand_data(Entry,NEntry,Cost) :-
8070 Entry = entry(Heads,IDs,Vars,NHeads,NIDs,RuleNb),
8071 select2(Head1,ID1,NHeads,NIDs,NHeads1,NIDs1),
8072 term_variables([Head1|Vars],Vars1),
8073 NEntry = entry([Head1|Heads],[ID1|IDs],Vars1,NHeads1,NIDs1,RuleNb),
8074 order_score(Head1,ID1,Vars,NHeads1,RuleNb,Cost).
8076 % Assigns score to head based on known variables and heads to lookup
8077 % order_score(+head,+id,+knownvars,+heads,+rule_nb,-score). {{{
8078 order_score(Head,ID,KnownVars,RestHeads,RuleNb,Score) :-
8080 get_store_type(F/A,StoreType),
8081 order_score(StoreType,Head,ID,KnownVars,RestHeads,RuleNb,99999,Score).
8084 %% order_score(+store+_type,+head,+id,+vars,+heads,+rule_nb,+score,-score) {{{
8085 order_score(default,Head,_ID,KnownVars,RestHeads,RuleNb,CScore,NScore) :-
8086 term_variables(Head,HeadVars0),
8087 term_variables(RestHeads,RestVars),
8088 ground_vars([Head],GroundVars),
8089 list_difference_eq(HeadVars0,GroundVars,HeadVars),
8090 order_score_vars(HeadVars,KnownVars,RestVars,Score),
8091 NScore is min(CScore,Score).
8092 order_score(multi_inthash(Indexes),Head,_ID,KnownVars,RestHeads,RuleNb,CScore,Score) :-
8096 order_score_indexes(Indexes,Head,KnownVars,Score)
8098 order_score(multi_hash(Indexes),Head,_ID,KnownVars,RestHeads,RuleNb,CScore,Score) :-
8102 order_score_indexes(Indexes,Head,KnownVars,Score)
8104 order_score(global_ground,Head,ID,KnownVars,RestHeads,RuleNb,CScore,NScore) :-
8105 term_variables(Head,HeadVars),
8106 term_variables(RestHeads,RestVars),
8107 order_score_vars(HeadVars,KnownVars,RestVars,Score_),
8108 Score is Score_ * 200,
8109 NScore is min(CScore,Score).
8110 order_score(var_assoc_store(_,_),_,_,_,_,_,_,1).
8111 order_score(global_singleton,_Head,ID,_KnownVars,_RestHeads,_RuleNb,_,Score) :-
8112 Score = 1. % guaranteed O(1)
8113 order_score(multi_store(StoreTypes),Head,ID,KnownVars,RestHeads,RuleNb,CScore,Score) :-
8114 multi_order_score(StoreTypes,Head,ID,KnownVars,RestHeads,RuleNb,CScore,Score).
8115 multi_order_score([],_,_,_,_,_,Score,Score).
8116 multi_order_score([StoreType|StoreTypes],Head,ID,KnownVars,RestHeads,RuleNb,Score0,Score) :-
8117 ( order_score(StoreType,Head,ID,KnownVars,RestHeads,RuleNb,Score0,Score1) -> true
8120 multi_order_score(StoreTypes,Head,ID,KnownVars,RestHeads,RuleNb,Score1,Score).
8122 order_score(identifier_store(Index),Head,ID,KnownVars,RestHeads,RuleNb,CScore,Score) :-
8123 Score is min(CScore,10).
8124 order_score(type_indexed_identifier_store(_,_),Head,ID,KnownVars,RestHeads,RuleNb,CScore,Score) :-
8125 Score is min(CScore,10).
8129 %% order_score_indexes(+indexes,+head,+vars,-score). {{{
8130 order_score_indexes(Indexes,Head,Vars,Score) :-
8131 copy_term_nat(Head+Vars,HeadCopy+VarsCopy),
8132 numbervars(VarsCopy,0,_),
8133 order_score_indexes(Indexes,HeadCopy,Score).
8135 order_score_indexes([I|Is],Head,Score) :-
8137 ( maplist(ground,Args) /* forall(Arg,Args,memberchk_eq(Arg,KnownVars)) */ ->
8140 order_score_indexes(Is,Head,Score)
8144 memberchk_eq_flip(List,Element) :- memberchk_eq(Element,List).
8146 order_score_vars(Vars,KnownVars,RestVars,Score) :-
8147 order_score_count_vars(Vars,KnownVars,RestVars,K-R-O),
8151 Score is max(10 - K,0)
8153 Score is max(10 - R,1) * 100
8155 Score is max(10-O,1) * 1000
8157 order_score_count_vars([],_,_,0-0-0).
8158 order_score_count_vars([V|Vs],KnownVars,RestVars,NK-NR-NO) :-
8159 order_score_count_vars(Vs,KnownVars,RestVars,K-R-O),
8160 ( memberchk_eq(V,KnownVars) ->
8163 ; memberchk_eq(V,RestVars) ->
8171 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8173 %% |_ _|_ __ | (_)_ __ (_)_ __ __ _
8174 %% | || '_ \| | | '_ \| | '_ \ / _` |
8175 %% | || | | | | | | | | | | | | (_| |
8176 %% |___|_| |_|_|_|_| |_|_|_| |_|\__, |
8180 create_get_mutable_ref(V,M,GM) :- GM = (M = mutable(V)).
8181 create_get_mutable(V,M,GM) :- M = mutable(V), GM = true.
8185 %% create_get_mutable(V,M,GM) :- GM = get_mutable(V,M).
8186 %% create_get_mutable_ref(V,M,GM) :- GM = get_mutable(V,M).
8189 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8191 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8193 %% | | | | |_(_) (_) |_ _ _
8194 %% | | | | __| | | | __| | | |
8195 %% | |_| | |_| | | | |_| |_| |
8196 %% \___/ \__|_|_|_|\__|\__, |
8199 % Create a fresh variable.
8202 % Create =N= fresh variables.
8206 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs) :-
8207 vars_susp(A,Vars,Susp,VarsSusp),
8209 pairup(Args,Vars,HeadPairs).
8211 inc_id([N|Ns],[O|Ns]) :-
8213 dec_id([N|Ns],[M|Ns]) :-
8216 extend_id(Id,[0|Id]).
8218 next_id([_,N|Ns],[O|Ns]) :-
8221 % return clause Head
8222 % for F/A constraint symbol, predicate identifier Id and arguments Head
8223 build_head(F,A,Id,Args,Head) :-
8224 buildName(F,A,Id,Name),
8225 ( (chr_pp_flag(debugable,on) ; is_stored(F/A), ( has_active_occurrence(F/A) ; chr_pp_flag(late_allocation,off)),
8226 ( may_trigger(F/A) ;
8227 get_allocation_occurrence(F/A,AO),
8228 get_max_occurrence(F/A,MO),
8230 Head =.. [Name|Args]
8232 init(Args,ArgsWOSusp), % XXX not entirely correct!
8233 Head =.. [Name|ArgsWOSusp]
8236 % return predicate name Result
8237 % for Fct/Aty constraint symbol and predicate identifier List
8238 buildName(Fct,Aty,List,Result) :-
8239 ( (chr_pp_flag(debugable,on) ; (once((is_stored(Fct/Aty), ( has_active_occurrence(Fct/Aty) ; chr_pp_flag(late_allocation,off)),
8240 ( may_trigger(Fct/Aty) ; get_allocation_occurrence(Fct/Aty,AO), get_max_occurrence(Fct/Aty,MO),
8241 MO >= AO ) ; List \= [0])) ) ) ->
8242 atom_concat(Fct, '___' ,FctSlash),
8243 atomic_concat(FctSlash,Aty,FctSlashAty),
8244 buildName_(List,FctSlashAty,Result)
8249 buildName_([],Name,Name).
8250 buildName_([N|Ns],Name,Result) :-
8251 buildName_(Ns,Name,Name1),
8252 atom_concat(Name1,'__',NameDash), % '_' is a char :-(
8253 atomic_concat(NameDash,N,Result).
8255 vars_susp(A,Vars,Susp,VarsSusp) :-
8257 append(Vars,[Susp],VarsSusp).
8259 or_pattern(Pos,Pat) :-
8261 Pat is 1 << Pow. % was 2 ** X
8263 and_pattern(Pos,Pat) :-
8265 Y is 1 << X, % was 2 ** X
8266 Pat is (-1)*(Y + 1).
8268 make_name(Prefix,F/A,Name) :-
8269 atom_concat_list([Prefix,F,'___',A],Name).
8271 %===============================================================================
8272 % Attribute for attributed variables
8274 make_attr(N,Mask,SuspsList,Attr) :-
8275 length(SuspsList,N),
8276 Attr =.. [v,Mask|SuspsList].
8278 get_all_suspensions2(N,Attr,SuspensionsList) :-
8279 chr_pp_flag(dynattr,off), !,
8280 make_attr(N,_,SuspensionsList,Attr).
8283 get_all_suspensions2(N,Attr,Goal,SuspensionsList) :-
8284 % writeln(get_all_suspensions2),
8285 length(SuspensionsList,N),
8286 Goal = 'chr all_suspensions'(SuspensionsList,1,Attr).
8290 normalize_attr(Attr,NormalGoal,NormalAttr) :-
8291 % writeln(normalize_attr),
8292 NormalGoal = 'chr normalize_attr'(Attr,NormalAttr).
8294 get_suspensions(N,Position,TAttr,(TAttr = Attr),Suspensions) :-
8295 chr_pp_flag(dynattr,off), !,
8296 make_attr(N,_,SuspsList,Attr),
8297 nth1(Position,SuspsList,Suspensions).
8300 get_suspensions(N,Position,TAttr,Goal,Suspensions) :-
8301 % writeln(get_suspensions),
8303 ( memberchk(Position-Suspensions,TAttr) ->
8309 %-------------------------------------------------------------------------------
8310 % +N: number of constraint symbols
8311 % +Suspension: source-level variable, for suspension
8312 % +Position: constraint symbol number
8313 % -Attr: source-level term, for new attribute
8314 singleton_attr(N,Suspension,Position,Attr) :-
8315 chr_pp_flag(dynattr,off), !,
8316 or_pattern(Position,Pattern),
8317 make_attr(N,Pattern,SuspsList,Attr),
8318 nth1(Position,SuspsList,[Suspension]),
8319 chr_delete(SuspsList,[Suspension],RestSuspsList),
8320 set_elems(RestSuspsList,[]).
8323 singleton_attr(N,Suspension,Position,Attr) :-
8324 % writeln(singleton_attr),
8325 Attr = [Position-[Suspension]].
8327 %-------------------------------------------------------------------------------
8328 % +N: number of constraint symbols
8329 % +Suspension: source-level variable, for suspension
8330 % +Position: constraint symbol number
8331 % +TAttr: source-level variable, for old attribute
8332 % -Goal: goal for creating new attribute
8333 % -NTAttr: source-level variable, for new attribute
8334 add_attr(N,Suspension,Position,TAttr,Goal,NTAttr) :-
8335 chr_pp_flag(dynattr,off), !,
8336 make_attr(N,Mask,SuspsList,Attr),
8337 or_pattern(Position,Pattern),
8338 nth1(Position,SuspsList,Susps),
8339 substitute_eq(Susps,SuspsList,[Suspension|Susps],SuspsList1),
8340 make_attr(N,Mask,SuspsList1,NewAttr1),
8341 substitute_eq(Susps,SuspsList,[Suspension],SuspsList2),
8342 make_attr(N,NewMask,SuspsList2,NewAttr2),
8345 ( Mask /\ Pattern =:= Pattern ->
8348 NewMask is Mask \/ Pattern,
8354 add_attr(N,Suspension,Position,TAttr,Goal,NTAttr) :-
8355 % writeln(add_attr),
8357 ( 'chr select'(TAttr,Position-Suspensions,RAttr) ->
8358 NTAttr = [Position-[Suspension|Suspensions]|RAttr]
8360 NTAttr = [Position-[Suspension]|TAttr]
8363 rem_attr(N,Var,Suspension,Position,TAttr,Goal) :-
8364 chr_pp_flag(dynattr,off), !,
8365 or_pattern(Position,Pattern),
8366 and_pattern(Position,DelPattern),
8367 make_attr(N,Mask,SuspsList,Attr),
8368 nth1(Position,SuspsList,Susps),
8369 substitute_eq(Susps,SuspsList,[],SuspsList1),
8370 make_attr(N,NewMask,SuspsList1,Attr1),
8371 substitute_eq(Susps,SuspsList,NewSusps,SuspsList2),
8372 make_attr(N,Mask,SuspsList2,Attr2),
8373 get_target_module(Mod),
8376 ( Mask /\ Pattern =:= Pattern ->
8377 'chr sbag_del_element'(Susps,Suspension,NewSusps),
8379 NewMask is Mask /\ DelPattern,
8383 put_attr(Var,Mod,Attr1)
8386 put_attr(Var,Mod,Attr2)
8394 rem_attr(N,Var,Suspension,Position,TAttr,Goal) :-
8395 % writeln(rem_attr),
8396 get_target_module(Mod),
8398 ( 'chr select'(TAttr,Position-Suspensions,RAttr) ->
8399 'chr sbag_del_element'(Suspensions,Suspension,NSuspensions),
8400 ( NSuspensions == [] ->
8404 put_attr(Var,Mod,RAttr)
8407 put_attr(Var,Mod,[Position-NSuspensions|RAttr])
8413 %-------------------------------------------------------------------------------
8414 % +N: number of constraint symbols
8415 % +TAttr1: source-level variable, for attribute
8416 % +TAttr2: source-level variable, for other attribute
8417 % -Goal: goal for merging the two attributes
8418 % -Attr: source-level term, for merged attribute
8419 merge_attributes(N,TAttr1,TAttr2,Goal,Attr) :-
8420 chr_pp_flag(dynattr,off), !,
8421 make_attr(N,Mask1,SuspsList1,Attr1),
8422 merge_attributes2(N,Mask1,SuspsList1,TAttr2,Goal2,Attr),
8429 merge_attributes(N,TAttr1,TAttr2,Goal,Attr) :-
8430 % writeln(merge_attributes),
8432 sort(TAttr1,Sorted1),
8433 sort(TAttr2,Sorted2),
8434 'chr new_merge_attributes'(Sorted1,Sorted2,Attr)
8438 %-------------------------------------------------------------------------------
8439 % +N: number of constraint symbols
8441 % +SuspsList1: static term, for suspensions list
8442 % +TAttr2: source-level variable, for other attribute
8443 % -Goal: goal for merging the two attributes
8444 % -Attr: source-level term, for merged attribute
8445 merge_attributes2(N,Mask1,SuspsList1,TAttr2,Goal,Attr) :-
8446 make_attr(N,Mask2,SuspsList2,Attr2),
8447 bagof(G,X ^ Y ^ SY ^ M ^ (member2(SuspsList1,SuspsList2,X-Y),G = (sort(Y,SY),'chr merge_attributes'(X,SY,M))),Gs),
8448 list2conj(Gs,SortGoals),
8449 bagof(MS,A ^ B ^ C ^ member((A,'chr merge_attributes'(B,C,MS)),Gs), SuspsList),
8450 make_attr(N,Mask,SuspsList,Attr),
8454 Mask is Mask1 \/ Mask2
8458 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8459 % Storetype dependent lookup
8461 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8462 %% lookup_passive_head(+Head,+PreviousVars,+RenamingVarDict,
8463 %% -Goal,-SuspensionList) is det.
8465 % Create a universal lookup goal for given head.
8466 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8467 lookup_passive_head(Head,PreJoin,VarDict,Goal,AllSusps) :-
8469 get_store_type(F/A,StoreType),
8470 lookup_passive_head(StoreType,Head,PreJoin,VarDict,[],Goal,AllSusps).
8472 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8473 %% lookup_passive_head(+Head,+PreviousVars,+RenamingVarDict,+GroundVars,
8474 %% -Goal,-SuspensionList) is det.
8476 % Create a universal lookup goal for given head.
8477 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8478 lookup_passive_head(Head,PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
8480 get_store_type(F/A,StoreType),
8481 lookup_passive_head(StoreType,Head,PreJoin,VarDict,GroundVars,Goal,AllSusps).
8483 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8484 %% lookup_passive_head(+StoreType,+Head,+PreviousVars,+RenamingVarDict,
8485 %% +GroundVars,-Goal,-SuspensionList) is det.
8487 % Create a universal lookup goal for given head.
8488 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8489 lookup_passive_head(default,Head,PreJoin,VarDict,_,Goal,AllSusps) :-
8491 passive_head_via(Head,PreJoin,VarDict,Goal,AllSusps),
8492 update_store_type(F/A,default).
8493 lookup_passive_head(multi_inthash(Indexes),Head,_PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
8494 hash_lookup_passive_head(inthash,Indexes,Head,VarDict,GroundVars,Goal,AllSusps,_).
8495 lookup_passive_head(multi_hash(Indexes),Head,_PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
8496 hash_lookup_passive_head(hash,Indexes,Head,VarDict,GroundVars,Goal,AllSusps,_).
8497 lookup_passive_head(global_ground,Head,_PreJoin,_VarDict,_,Goal,AllSusps) :-
8499 global_ground_store_name(F/A,StoreName),
8500 make_get_store_goal(StoreName,AllSusps,Goal), % Goal = nb_getval(StoreName,AllSusps),
8501 update_store_type(F/A,global_ground).
8502 lookup_passive_head(var_assoc_store(VarIndex,KeyIndex),Head,_PreJoin,VarDict,_,Goal,AllSusps) :-
8503 arg(VarIndex,Head,OVar),
8504 arg(KeyIndex,Head,OKey),
8505 translate([OVar,OKey],VarDict,[Var,Key]),
8506 get_target_module(Module),
8508 get_attr(Var,Module,AssocStore),
8509 lookup_assoc_store(AssocStore,Key,AllSusps)
8511 lookup_passive_head(global_singleton,Head,_PreJoin,_VarDict,_,Goal,AllSusps) :-
8513 global_singleton_store_name(F/A,StoreName),
8514 make_get_store_goal(StoreName,Susp,GetStoreGoal),
8515 Goal = (GetStoreGoal,Susp \== [],AllSusps = [Susp]),
8516 update_store_type(F/A,global_singleton).
8517 lookup_passive_head(multi_store(StoreTypes),Head,PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
8519 member(ST,StoreTypes),
8520 lookup_passive_head(ST,Head,PreJoin,VarDict,GroundVars,Goal,AllSusps)
8522 lookup_passive_head(identifier_store(Index),Head,PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
8524 arg(Index,Head,Var),
8525 translate([Var],VarDict,[KeyVar]),
8526 delay_phase_end(validate_store_type_assumptions,
8527 identifier_lookup(F/A,Index,AllSusps,KeyVar,Goal)
8529 update_store_type(F/A,identifier_store(Index)),
8530 get_identifier_index(F/A,Index,_).
8531 lookup_passive_head(type_indexed_identifier_store(Index,IndexType),Head,PreJoin,VarDict,GroundVars,Goal,AllSusps) :-
8533 arg(Index,Head,Var),
8535 translate([Var],VarDict,[KeyVar]),
8537 ; ground(Var), Var = '$chr_identifier_match'(ActualVar,_) ->
8538 lookup_identifier_atom(IndexType,ActualVar,KeyVar,LookupGoal),
8539 Goal = (LookupGoal,StructGoal)
8541 delay_phase_end(validate_store_type_assumptions,
8542 type_indexed_identifier_lookup(F/A,Index,IndexType,AllSusps,KeyVar,StructGoal)
8544 update_store_type(F/A,type_indexed_identifier_store(Index,IndexType)),
8545 get_type_indexed_identifier_index(IndexType,F/A,Index,_).
8547 identifier_lookup(C,Index,AllSusps,KeyVar,Goal) :-
8548 get_identifier_size(ISize),
8549 functor(Struct,struct,ISize),
8550 get_identifier_index(C,Index,IIndex),
8551 arg(IIndex,Struct,AllSusps),
8552 Goal = (KeyVar = Struct).
8554 type_indexed_identifier_lookup(C,Index,IndexType,AllSusps,KeyVar,Goal) :-
8555 type_indexed_identifier_structure(IndexType,Struct),
8556 get_type_indexed_identifier_index(IndexType,C,Index,IIndex),
8557 arg(IIndex,Struct,AllSusps),
8558 Goal = (KeyVar = Struct).
8560 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8561 %% hash_lookup_passive_head(+StoreType,+Indexes,+Head,+RenamingVarDict,
8562 %% +GroundVars,-Goal,-SuspensionList,-Index) is det.
8564 % Create a universal hash lookup goal for given head.
8565 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8566 hash_lookup_passive_head(HashType,Indexes,Head,VarDict,GroundVars,Goal,AllSusps,Index) :-
8567 pick_hash_index(Indexes,Head,VarDict,Index,KeyArgs,KeyArgCopies),
8568 ( KeyArgCopies = [KeyCopy] ->
8571 KeyCopy =.. [k|KeyArgCopies]
8574 multi_hash_lookup_goal(F/A,HashType,Index,KeyCopy,AllSusps,LookupGoal),
8576 check_ground(GroundVars,KeyArgs,OriginalGroundCheck),
8577 my_term_copy(OriginalGroundCheck,VarDict,GroundCheck),
8579 Goal = (GroundCheck,LookupGoal),
8581 ( HashType == inthash ->
8582 update_store_type(F/A,multi_inthash([Index]))
8584 update_store_type(F/A,multi_hash([Index]))
8587 pick_hash_index(Indexes,Head,VarDict,Index,KeyArgs,KeyArgCopies) :-
8588 member(Index,Indexes),
8589 args(Index,Head,KeyArgs),
8590 key_in_scope(KeyArgs,VarDict,KeyArgCopies),
8593 % check whether we can copy the given terms
8594 % with the given dictionary, and, if so, do so
8595 key_in_scope([],VarDict,[]).
8596 key_in_scope([Arg|Args],VarDict,[ArgCopy|ArgCopies]) :-
8597 term_variables(Arg,Vars),
8598 translate(Vars,VarDict,VarCopies),
8599 copy_term(Arg/Vars,ArgCopy/VarCopies),
8600 key_in_scope(Args,VarDict,ArgCopies).
8602 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8603 %% existential_lookup(+StoreType,+Head,+PrevVariablesHead,+RenamingVarDict,
8604 %% +GroundVariables,-SuspensionTerm,-Goal,-SuspVar,
8605 %% +VarArgDict,-NewVarArgDict) is det.
8607 % Create existential lookup goal for given head.
8608 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8609 existential_lookup(var_assoc_store(VarIndex,KeyIndex),Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,Pairs) :- !,
8610 lookup_passive_head(var_assoc_store(VarIndex,KeyIndex),Head,PreJoin,VarDict,GroundVars,UniversalGoal,AllSusps),
8611 sbag_member_call(Susp,AllSusps,Sbag),
8613 delay_phase_end(validate_store_type_assumptions,
8614 ( static_suspension_term(F/A,SuspTerm),
8615 get_static_suspension_field(F/A,SuspTerm,state,active,GetState)
8624 existential_lookup(global_singleton,Head,_PreJoin,_VarDict,_,SuspTerm,Goal,Susp,Pairs,Pairs) :- !,
8626 global_singleton_store_name(F/A,StoreName),
8627 make_get_store_goal(StoreName,Susp,GetStoreGoal),
8629 GetStoreGoal, % nb_getval(StoreName,Susp),
8633 update_store_type(F/A,global_singleton).
8634 existential_lookup(multi_store(StoreTypes),Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :- !,
8636 member(ST,StoreTypes),
8637 existential_lookup(ST,Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs)
8639 existential_lookup(multi_inthash(Indexes),Head,_,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :- !,
8640 existential_hash_lookup(inthash,Indexes,Head,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs).
8641 existential_lookup(multi_hash(Indexes),Head,_,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :- !,
8642 existential_hash_lookup(hash,Indexes,Head,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs).
8643 existential_lookup(identifier_store(Index),Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :- !,
8644 lookup_passive_head(identifier_store(Index),Head,PreJoin,VarDict,GroundVars,LookupGoal,AllSusps),
8645 hash_index_filter(Pairs,Index,NPairs),
8648 ( check_fd_lookup_condition(F,A,Head,KeyArgs) ->
8649 Sbag = (AllSusps = [Susp])
8651 sbag_member_call(Susp,AllSusps,Sbag)
8653 delay_phase_end(validate_store_type_assumptions,
8654 ( static_suspension_term(F/A,SuspTerm),
8655 get_static_suspension_field(F/A,SuspTerm,state,active,GetState)
8661 Susp = SuspTerm, % not inlined
8664 existential_lookup(type_indexed_identifier_store(Index,IndexType),Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :- !,
8665 lookup_passive_head(type_indexed_identifier_store(Index,IndexType),Head,PreJoin,VarDict,GroundVars,LookupGoal,AllSusps),
8666 hash_index_filter(Pairs,Index,NPairs),
8669 ( check_fd_lookup_condition(F,A,Head,KeyArgs) ->
8670 Sbag = (AllSusps = [Susp])
8672 sbag_member_call(Susp,AllSusps,Sbag)
8674 delay_phase_end(validate_store_type_assumptions,
8675 ( static_suspension_term(F/A,SuspTerm),
8676 get_static_suspension_field(F/A,SuspTerm,state,active,GetState)
8682 Susp = SuspTerm, % not inlined
8685 existential_lookup(StoreType,Head,PreJoin,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,Pairs) :-
8686 lookup_passive_head(StoreType,Head,PreJoin,VarDict,GroundVars,UGoal,Susps),
8687 sbag_member_call(Susp,Susps,Sbag),
8689 delay_phase_end(validate_store_type_assumptions,
8690 ( static_suspension_term(F/A,SuspTerm),
8691 get_static_suspension_field(F/A,SuspTerm,state,active,GetState)
8697 Susp = SuspTerm, % not inlined
8701 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8702 %% existential_hash_lookup(+StoreType,+Indexes,+Head,+RenamingVarDict,
8703 %% +GroundVariables,-SuspensionTerm,-Goal,-SuspVar,
8704 %% +VarArgDict,-NewVarArgDict) is det.
8706 % Create existential hash lookup goal for given head.
8707 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8708 existential_hash_lookup(HashType,Indexes,Head,VarDict,GroundVars,SuspTerm,Goal,Susp,Pairs,NPairs) :-
8709 hash_lookup_passive_head(HashType,Indexes,Head,VarDict,GroundVars,LookupGoal,AllSusps,Index),
8711 hash_index_filter(Pairs,Index,NPairs),
8714 ( check_fd_lookup_condition(F,A,Head,KeyArgs) ->
8715 Sbag = (AllSusps = [Susp])
8717 sbag_member_call(Susp,AllSusps,Sbag)
8719 delay_phase_end(validate_store_type_assumptions,
8720 ( static_suspension_term(F/A,SuspTerm),
8721 get_static_suspension_field(F/A,SuspTerm,state,active,GetState)
8727 Susp = SuspTerm, % not inlined
8731 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8732 %% hash_index_filter(+Pairs,+Index,-NPairs) is det.
8734 % Filter out pairs already covered by given hash index.
8735 % makes them 'silent'
8736 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%
8737 hash_index_filter(Pairs,Index,NPairs) :-
8738 hash_index_filter(Pairs,Index,1,NPairs).
8740 hash_index_filter([],_,_,[]).
8741 hash_index_filter([P|Ps],Index,N,NPairs) :-
8746 hash_index_filter(Ps,[I|Is],NN,NPs)
8748 NPairs = [silent(P)|NPs],
8749 hash_index_filter(Ps,Is,NN,NPs)
8755 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8756 %------------------------------------------------------------------------------%
8757 %% assume_constraint_stores(+ConstraintSymbols) is det.
8759 % Compute all constraint store types that are possible for the given
8760 % =ConstraintSymbols=.
8761 %------------------------------------------------------------------------------%
8762 assume_constraint_stores([]).
8763 assume_constraint_stores([C|Cs]) :-
8764 ( chr_pp_flag(debugable,off),
8765 ( only_ground_indexed_arguments(C) ; chr_pp_flag(mixed_stores,on) ),
8767 get_store_type(C,default) ->
8768 get_indexed_arguments(C,AllIndexedArgs),
8769 get_constraint_mode(C,Modes),
8770 aggregate_all(bag(Index)-count,
8771 (member(Index,AllIndexedArgs),nth1(Index,Modes,+)),
8772 IndexedArgs-NbIndexedArgs),
8773 % Construct Index Combinations
8774 ( NbIndexedArgs > 10 ->
8775 findall([Index],member(Index,IndexedArgs),Indexes)
8777 findall(Index,(sublist(Index,IndexedArgs), Index \== []),UnsortedIndexes),
8778 predsort(longer_list,UnsortedIndexes,Indexes)
8780 % EXPERIMENTAL HEURISTIC
8782 % member(Arg1,IndexedArgs),
8783 % member(Arg2,IndexedArgs),
8785 % sort([Arg1,Arg2], Index)
8786 % ), UnsortedIndexes),
8787 % predsort(longer_list,UnsortedIndexes,Indexes),
8789 ( get_functional_dependency(C,1,Pattern,Key),
8790 all_distinct_var_args(Pattern), Key == [] ->
8791 assumed_store_type(C,global_singleton)
8792 ; ( only_ground_indexed_arguments(C) ; NbIndexedArgs > 0 ) ->
8793 get_constraint_type_det(C,ArgTypes),
8794 partition_indexes(Indexes,ArgTypes,HashIndexes,IntHashIndexes,IdentifierIndexes,CompoundIdentifierIndexes),
8796 ( IntHashIndexes = [] ->
8799 Stores = [multi_inthash(IntHashIndexes)|Stores1]
8801 ( HashIndexes = [] ->
8804 Stores1 = [multi_hash(HashIndexes)|Stores2]
8806 ( IdentifierIndexes = [] ->
8809 maplist(wrap_in_functor(identifier_store),IdentifierIndexes,WrappedIdentifierIndexes),
8810 append(WrappedIdentifierIndexes,Stores3,Stores2)
8812 append(CompoundIdentifierIndexes,Stores4,Stores3),
8813 ( only_ground_indexed_arguments(C)
8814 -> Stores4 = [global_ground]
8815 ; Stores4 = [default]
8817 assumed_store_type(C,multi_store(Stores))
8823 assume_constraint_stores(Cs).
8825 %------------------------------------------------------------------------------%
8826 %% partition_indexes(+Indexes,+Types,
8827 %% -HashIndexes,-IntHashIndexes,-IdentifierIndexes) is det.
8828 %------------------------------------------------------------------------------%
8829 partition_indexes([],_,[],[],[],[]).
8830 partition_indexes([Index|Indexes],Types,HashIndexes,IntHashIndexes,IdentifierIndexes,CompoundIdentifierIndexes) :-
8833 unalias_type(Type,UnAliasedType),
8834 UnAliasedType == chr_identifier ->
8835 IdentifierIndexes = [I|RIdentifierIndexes],
8836 IntHashIndexes = RIntHashIndexes,
8837 HashIndexes = RHashIndexes,
8838 CompoundIdentifierIndexes = RCompoundIdentifierIndexes
8841 unalias_type(Type,UnAliasedType),
8842 nonvar(UnAliasedType),
8843 UnAliasedType = chr_identifier(IndexType) ->
8844 CompoundIdentifierIndexes = [type_indexed_identifier_store(I,IndexType)|RCompoundIdentifierIndexes],
8845 IdentifierIndexes = RIdentifierIndexes,
8846 IntHashIndexes = RIntHashIndexes,
8847 HashIndexes = RHashIndexes
8850 unalias_type(Type,UnAliasedType),
8851 UnAliasedType == dense_int ->
8852 IntHashIndexes = [Index|RIntHashIndexes],
8853 HashIndexes = RHashIndexes,
8854 IdentifierIndexes = RIdentifierIndexes,
8855 CompoundIdentifierIndexes = RCompoundIdentifierIndexes
8858 unalias_type(Type,UnAliasedType),
8859 nonvar(UnAliasedType),
8860 UnAliasedType = chr_identifier(_) ->
8861 % don't use chr_identifiers in hash indexes
8862 IntHashIndexes = RIntHashIndexes,
8863 HashIndexes = RHashIndexes,
8864 IdentifierIndexes = RIdentifierIndexes,
8865 CompoundIdentifierIndexes = RCompoundIdentifierIndexes
8867 IntHashIndexes = RIntHashIndexes,
8868 HashIndexes = [Index|RHashIndexes],
8869 IdentifierIndexes = RIdentifierIndexes,
8870 CompoundIdentifierIndexes = RCompoundIdentifierIndexes
8872 partition_indexes(Indexes,Types,RHashIndexes,RIntHashIndexes,RIdentifierIndexes,RCompoundIdentifierIndexes).
8874 longer_list(R,L1,L2) :-
8884 all_distinct_var_args(Term) :-
8885 copy_term_nat(Term,TermCopy),
8887 functor(Pattern,F,A),
8888 Pattern =@= TermCopy.
8890 get_indexed_arguments(C,IndexedArgs) :-
8892 get_indexed_arguments(1,A,C,IndexedArgs).
8894 get_indexed_arguments(I,N,C,L) :-
8897 ; ( is_indexed_argument(C,I) ->
8903 get_indexed_arguments(J,N,C,T)
8906 validate_store_type_assumptions([]).
8907 validate_store_type_assumptions([C|Cs]) :-
8908 validate_store_type_assumption(C),
8909 validate_store_type_assumptions(Cs).
8911 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8912 % new code generation
8913 universal_search_iterator_end([CurrentHead|PrevHeads],NextHeads,Rule,F/A,O,Id,L,T) :-
8914 Rule = rule(H1,_,Guard,Body),
8915 gen_var_susp_list_for_b(PrevHeads,[CurrentHead,NextHeads,Guard,Body],_,VarsAndSuspsList,FirstVarsSusp,_,PrevIterators),
8916 universal_search_iterator_failure_vars(PrevHeads,Id,VarsAndSuspsList,FirstVarsSusp,PrevIterators,PrevVarsAndSusps,PrevId0),
8917 flatten(VarsAndSuspsList,VarsAndSusps),
8918 Vars = [ [] | VarsAndSusps],
8919 build_head(F,A,[O|Id],Vars,Head),
8921 get_success_continuation_code_id(F/A,O,PredictedPrevId),
8922 % format('~w == ~w ?\n',[PrevId0,PredictedPrevId]),
8923 PrevId = [PredictedPrevId] % PrevId = PrevId0
8925 PrevId = [O|PrevId0]
8927 build_head(F,A,PrevId,PrevVarsAndSusps,PredecessorCall),
8928 Clause = ( Head :- PredecessorCall),
8929 add_dummy_location(Clause,LocatedClause),
8930 L = [LocatedClause | T].
8932 % functor(CurrentHead,CF,CA),
8933 % check_fd_lookup_condition(CF,CA,CurrentHead,PrevHeads) ->
8936 % gen_var_susp_list_for_b(PrevHeads,[CurrentHead,NextHeads,Guard,Body],_,VarsAndSuspsList,FirstVarsSusp,_,PrevIterators),
8937 % universal_search_iterator_failure_vars(PrevHeads,Id,VarsAndSuspsList,FirstVarsSusp,PrevIterators,PrevVarsAndSusps,PrevId),
8938 % flatten(VarsAndSuspsList,VarsAndSusps),
8939 % Vars = [ [] | VarsAndSusps],
8940 % build_head(F,A,Id,Vars,Head),
8941 % build_head(F,A,PrevId,PrevVarsAndSusps,PredecessorCall),
8942 % Clause = ( Head :- PredecessorCall),
8946 % skips back intelligently over global_singleton lookups
8947 universal_search_iterator_failure_vars(PrevHeads,Id,VarsAndSuspsList,BaseCallArgs,PrevIterators,PrevVarsAndSusps,PrevId) :-
8949 % TOM: add partial success continuation optimization here!
8951 PrevVarsAndSusps = BaseCallArgs
8953 VarsAndSuspsList = [_|AllButFirstList],
8955 ( PrevHeads = [PrevHead|PrevHeads1],
8956 functor(PrevHead,F,A),
8957 check_fd_lookup_condition(F,A,PrevHead,PrevHeads1) ->
8958 PrevIterators = [_|PrevIterators1],
8959 universal_search_iterator_failure_vars(PrevHeads1,PrevId1,AllButFirstList,BaseCallArgs,PrevIterators1,PrevVarsAndSusps,PrevId)
8962 flatten(AllButFirstList,AllButFirst),
8963 PrevIterators = [PrevIterator|_],
8964 PrevVarsAndSusps = [PrevIterator|AllButFirst]
8968 universal_search_iterator([NextHead|RestHeads],[CurrentHead|PreHeads],Rule,F/A,O,Id,L,T) :-
8969 Rule = rule(_,_,Guard,Body),
8970 gen_var_susp_list_for_b(PreHeads,[CurrentHead,NextHead,RestHeads,Guard,Body],VarDict,PreVarsAndSuspsList,FirstVarsSusp,AllSusps,PrevIterators),
8971 init(AllSusps,PreSusps),
8972 flatten(PreVarsAndSuspsList,PreVarsAndSusps),
8973 gen_var(OtherSusps),
8974 functor(CurrentHead,OtherF,OtherA),
8975 gen_vars(OtherA,OtherVars),
8976 head_info(CurrentHead,OtherA,OtherVars,OtherSusp,_VarsSusp,HeadPairs),
8977 get_constraint_mode(OtherF/OtherA,Mode),
8978 head_arg_matches(HeadPairs,Mode,VarDict,FirstMatching,VarDict1),
8980 delay_phase_end(validate_store_type_assumptions,
8981 ( static_suspension_term(OtherF/OtherA,OtherSuspension),
8982 get_static_suspension_field(OtherF/OtherA,OtherSuspension,state,active,GetState),
8983 get_static_suspension_term_field(arguments,OtherF/OtherA,OtherSuspension,OtherVars)
8987 different_from_other_susps(CurrentHead,OtherSusp,PreHeads,PreSusps,DiffSuspGoals),
8988 % create_get_mutable_ref(active,State,GetMutable),
8990 OtherSusp = OtherSuspension,
8995 add_heads_ground_variables([CurrentHead|PreHeads],[],GroundVars),
8996 lookup_passive_head(NextHead,[CurrentHead|PreHeads],VarDict1,GroundVars,NextSuspGoal,NextSusps),
8997 inc_id(Id,NestedId),
8998 ClauseVars = [[OtherSusp|OtherSusps]|PreVarsAndSusps],
8999 build_head(F,A,[O|Id],ClauseVars,ClauseHead),
9000 passive_delegate_variables(CurrentHead,PreHeads,[NextHead,RestHeads,Guard,Body],VarDict1,CurrentHeadVars),
9001 append([NextSusps|CurrentHeadVars],[OtherSusp,OtherSusps|PreVarsAndSusps],NestedVars),
9002 build_head(F,A,[O|NestedId],NestedVars,NestedHead),
9004 ( check_fd_lookup_condition(OtherF,OtherA,CurrentHead,PreHeads) -> % iterator (OtherSusps) is empty at runtime
9005 universal_search_iterator_failure_vars(PreHeads,Id,PreVarsAndSuspsList,FirstVarsSusp,PrevIterators,PreVarsAndSusps1,PrevId0),
9006 RecursiveVars = PreVarsAndSusps1
9008 RecursiveVars = [OtherSusps|PreVarsAndSusps],
9014 PrevId = [O|PrevId0]
9016 build_head(F,A,PrevId,RecursiveVars,RecursiveHead),
9027 add_dummy_location(Clause,LocatedClause),
9028 L = [LocatedClause|T].
9030 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9032 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9033 % Observation Analysis
9038 % Analysis based on Abstract Interpretation paper.
9041 % stronger analysis domain [research]
9044 initial_call_pattern/1,
9046 call_pattern_worker/1,
9047 final_answer_pattern/2,
9048 abstract_constraints/1,
9052 ai_observed_internal/2,
9054 ai_not_observed_internal/2,
9058 ai_observation_gather_results/0.
9060 :- chr_type abstract_domain ---> odom(program_point,list(constraint)).
9061 :- chr_type program_point == any.
9063 :- chr_option(mode,initial_call_pattern(+)).
9064 :- chr_option(type_declaration,call_pattern(abstract_domain)).
9066 :- chr_option(mode,call_pattern(+)).
9067 :- chr_option(type_declaration,call_pattern(abstract_domain)).
9069 :- chr_option(mode,call_pattern_worker(+)).
9070 :- chr_option(type_declaration,call_pattern_worker(abstract_domain)).
9072 :- chr_option(mode,final_answer_pattern(+,+)).
9073 :- chr_option(type_declaration,final_answer_pattern(abstract_domain,abstract_domain)).
9075 :- chr_option(mode,abstract_constraints(+)).
9076 :- chr_option(type_declaration,abstract_constraints(list)).
9078 :- chr_option(mode,depends_on(+,+)).
9079 :- chr_option(type_declaration,depends_on(abstract_domain,abstract_domain)).
9081 :- chr_option(mode,depends_on_as(+,+,+)).
9082 :- chr_option(mode,depends_on_ap(+,+,+,+)).
9083 :- chr_option(mode,depends_on_goal(+,+)).
9084 :- chr_option(mode,ai_is_observed(+,+)).
9085 :- chr_option(mode,ai_not_observed(+,+)).
9086 % :- chr_option(mode,ai_observed(+,+)).
9087 :- chr_option(mode,ai_not_observed_internal(+,+)).
9088 :- chr_option(mode,ai_observed_internal(+,+)).
9091 abstract_constraints_fd @
9092 abstract_constraints(_) \ abstract_constraints(_) <=> true.
9094 ai_observed_internal(C,O) \ ai_not_observed_internal(C,O) <=> true.
9095 ai_not_observed_internal(C,O) \ ai_not_observed_internal(C,O) <=> true.
9096 ai_observed_internal(C,O) \ ai_observed_internal(C,O) <=> true.
9098 ai_not_observed(C,O) \ ai_is_observed(C,O) <=> fail.
9099 ai_is_observed(_,_) <=> true.
9101 ai_observation_gather_results \ ai_observed_internal(C,O) <=> true. % ai_observed(C,O).
9102 ai_observation_gather_results \ ai_not_observed_internal(C,O) <=> ai_not_observed(C,O).
9103 ai_observation_gather_results <=> true.
9105 %------------------------------------------------------------------------------%
9106 % Main Analysis Entry
9107 %------------------------------------------------------------------------------%
9108 ai_observation_analysis(ACs) :-
9109 ( chr_pp_flag(ai_observation_analysis,on),
9110 get_target_module(Module), '$chr_compiled_with_version'(3) -> % , Module \== guard_entailment ->
9111 list_to_ord_set(ACs,ACSet),
9112 abstract_constraints(ACSet),
9113 ai_observation_schedule_initial_calls(ACSet,ACSet),
9114 ai_observation_gather_results
9119 ai_observation_schedule_initial_calls([],_).
9120 ai_observation_schedule_initial_calls([AC|RACs],ACs) :-
9121 ai_observation_schedule_initial_call(AC,ACs),
9122 ai_observation_schedule_initial_calls(RACs,ACs).
9124 ai_observation_schedule_initial_call(AC,ACs) :-
9125 ai_observation_top(AC,CallPattern),
9126 % ai_observation_bot(AC,ACs,CallPattern),
9127 initial_call_pattern(CallPattern).
9129 ai_observation_schedule_new_calls([],AP).
9130 ai_observation_schedule_new_calls([AC|ACs],AP) :-
9132 initial_call_pattern(odom(AC,Set)),
9133 ai_observation_schedule_new_calls(ACs,AP).
9135 final_answer_pattern(CP,AP1) \ final_answer_pattern(CP,AP2)
9137 ai_observation_leq(AP2,AP1)
9141 initial_call_pattern(CP) \ initial_call_pattern(CP) <=> true.
9143 initial_call_pattern(CP) ==> call_pattern(CP).
9145 initial_call_pattern(CP), final_answer_pattern(CP,AP), abstract_constraints(ACs) # ID3
9147 ai_observation_schedule_new_calls(ACs,AP)
9151 call_pattern(CP) \ call_pattern(CP) <=> true.
9153 depends_on(CP1,CP2), final_answer_pattern(CP2,AP) ==>
9154 final_answer_pattern(CP1,AP).
9156 %call_pattern(CP) ==> writeln(call_pattern(CP)).
9158 call_pattern(CP) ==> call_pattern_worker(CP).
9160 %------------------------------------------------------------------------------%
9162 %------------------------------------------------------------------------------%
9165 %call_pattern(odom([],Set)) ==>
9166 % final_answer_pattern(odom([],Set),odom([],Set)).
9168 call_pattern_worker(odom([],Set)) <=>
9169 % writeln(' - AbstractGoal'(odom([],Set))),
9170 final_answer_pattern(odom([],Set),odom([],Set)).
9173 call_pattern_worker(odom([G|Gs],Set)) <=>
9174 % writeln(' - AbstractGoal'(odom([G|Gs],Set))),
9176 depends_on_goal(odom([G|Gs],Set),CP1),
9179 depends_on_goal(CP1,CP2), final_answer_pattern(CP2,AP2) \ depends_on(CP1,_) # ID
9180 <=> true pragma passive(ID).
9181 depends_on_goal(CP1,CP2), final_answer_pattern(CP2,AP2)
9183 CP1 = odom([_|Gs],_),
9187 depends_on(CP1,CCP).
9189 %------------------------------------------------------------------------------%
9190 % Abstract Disjunction
9191 %------------------------------------------------------------------------------%
9193 call_pattern_worker(odom((AG1;AG2),Set)) <=>
9194 CP = odom((AG1;AG2),Set),
9195 InitialAnswerApproximation = odom([],Set),
9196 final_answer_pattern(CP,InitialAnswerApproximation),
9197 CP1 = odom(AG1,Set),
9198 CP2 = odom(AG2,Set),
9201 depends_on_as(CP,CP1,CP2).
9203 %------------------------------------------------------------------------------%
9205 %------------------------------------------------------------------------------%
9206 call_pattern_worker(odom(builtin,Set)) <=>
9207 % writeln(' - AbstractSolve'(odom(builtin,Set))),
9208 ord_empty(EmptySet),
9209 final_answer_pattern(odom(builtin,Set),odom([],EmptySet)).
9211 %------------------------------------------------------------------------------%
9213 %------------------------------------------------------------------------------%
9214 max_occurrence(C,MO) # ID2 \ call_pattern_worker(odom(occ(C,O),Set))
9218 % writeln(' - AbstractDrop'(odom(occ(C,O),Set))),
9219 final_answer_pattern(odom(occ(C,O),Set),odom([],Set))
9223 %------------------------------------------------------------------------------%
9225 %------------------------------------------------------------------------------%
9226 call_pattern_worker(odom(AC,Set))
9230 % writeln(' - AbstractActivate'(odom(AC,Set))),
9231 CP = odom(occ(AC,1),Set),
9233 depends_on(odom(AC,Set),CP).
9235 %------------------------------------------------------------------------------%
9237 %------------------------------------------------------------------------------%
9238 occurrence(C,O,RuleNb,ID,_) # ID2 \ call_pattern_worker(odom(occ(C,O),Set))
9240 is_passive(RuleNb,ID)
9242 % writeln(' - AbstractPassive'(odom(occ(C,O),Set))),
9245 DCP = odom(occ(C,NO),Set),
9247 final_answer_pattern(odom(occ(C,O),Set),odom([],Set)),
9248 depends_on(odom(occ(C,O),Set),DCP)
9251 %------------------------------------------------------------------------------%
9253 %------------------------------------------------------------------------------%
9256 occurrence(C,O,RuleNb,ID,simplification) # ID2 \ call_pattern_worker(odom(occ(C,O),Set))
9258 \+ is_passive(RuleNb,ID)
9260 % writeln(' - AbstractPassive'(odom(occ(C,O),Set))),
9261 ai_observation_memo_simplification_rest_heads(C,O,AbstractRestHeads),
9262 ai_observation_observe_set(Set,AbstractRestHeads,Set2),
9263 ai_observation_memo_abstract_goal(RuleNb,AG),
9264 call_pattern(odom(AG,Set2)),
9267 DCP = odom(occ(C,NO),Set),
9269 depends_on_as(odom(occ(C,O),Set),odom(AG,Set2),DCP),
9270 % DEADLOCK AVOIDANCE
9271 final_answer_pattern(odom(occ(C,O),Set),odom([],Set))
9275 depends_on_as(CP,CPS,CPD),
9276 final_answer_pattern(CPS,APS),
9277 final_answer_pattern(CPD,APD) ==>
9278 ai_observation_lub(APS,APD,AP),
9279 final_answer_pattern(CP,AP).
9283 ai_observation_memo_simplification_rest_heads/3,
9284 ai_observation_memoed_simplification_rest_heads/3.
9286 :- chr_option(mode,ai_observation_memo_simplification_rest_heads(+,+,?)).
9287 :- chr_option(mode,ai_observation_memoed_simplification_rest_heads(+,+,+)).
9289 ai_observation_memoed_simplification_rest_heads(C,O,RH) \ ai_observation_memo_simplification_rest_heads(C,O,QRH)
9292 abstract_constraints(ACs) # ID1, occurrence(C,O,RuleNb,ID,_) # ID2, rule(RuleNb,Rule) # ID3 \ ai_observation_memo_simplification_rest_heads(C,O,QRH)
9294 Rule = pragma(rule(H1,H2,_,_),ids(IDs1,_),_,_,_),
9295 once(select2(ID,_,IDs1,H1,_,RestH1)),
9296 ai_observation_abstract_constraints(RestH1,ACs,ARestHeads),
9297 ai_observation_abstract_constraints(H2,ACs,AH2),
9298 append(ARestHeads,AH2,AbstractHeads),
9299 sort(AbstractHeads,QRH),
9300 ai_observation_memoed_simplification_rest_heads(C,O,QRH)
9306 ai_observation_memo_simplification_rest_heads(_,_,_) <=> fail.
9308 %------------------------------------------------------------------------------%
9309 % Abstract Propagate
9310 %------------------------------------------------------------------------------%
9314 occurrence(C,O,RuleNb,ID,propagation) # ID2 \ call_pattern_worker(odom(occ(C,O),Set))
9316 \+ is_passive(RuleNb,ID)
9318 % writeln(' - AbstractPropagate'(odom(occ(C,O),Set))),
9320 ai_observation_memo_propagation_rest_heads(C,O,AHs),
9321 ai_observation_observe_set(Set,AHs,Set2),
9322 ord_add_element(Set2,C,Set3),
9323 ai_observation_memo_abstract_goal(RuleNb,AG),
9324 call_pattern(odom(AG,Set3)),
9325 ( ord_memberchk(C,Set2) ->
9332 DCP = odom(occ(C,NO),Set),
9334 depends_on_ap(odom(occ(C,O),Set),odom(AG,Set3),DCP,Delete)
9339 ai_observation_memo_propagation_rest_heads/3,
9340 ai_observation_memoed_propagation_rest_heads/3.
9342 :- chr_option(mode,ai_observation_memo_propagation_rest_heads(+,+,?)).
9343 :- chr_option(mode,ai_observation_memoed_propagation_rest_heads(+,+,+)).
9345 ai_observation_memoed_propagation_rest_heads(C,O,RH) \ ai_observation_memo_propagation_rest_heads(C,O,QRH)
9348 abstract_constraints(ACs) # ID1, occurrence(C,O,RuleNb,ID,_) # ID2, rule(RuleNb,Rule) # ID3 \ ai_observation_memo_propagation_rest_heads(C,O,QRH)
9350 Rule = pragma(rule(H1,H2,_,_),ids(_,IDs2),_,_,_),
9351 once(select2(ID,_,IDs2,H2,_,RestH2)),
9352 ai_observation_abstract_constraints(RestH2,ACs,ARestHeads),
9353 ai_observation_abstract_constraints(H1,ACs,AH1),
9354 append(ARestHeads,AH1,AbstractHeads),
9355 sort(AbstractHeads,QRH),
9356 ai_observation_memoed_propagation_rest_heads(C,O,QRH)
9362 ai_observation_memo_propagation_rest_heads(_,_,_) <=> fail.
9364 depends_on_ap(CP,CPP,CPD,Delete), final_answer_pattern(CPD,APD) ==>
9365 final_answer_pattern(CP,APD).
9366 depends_on_ap(CP,CPP,CPD,Delete), final_answer_pattern(CPP,APP),
9367 final_answer_pattern(CPD,APD) ==>
9369 CP = odom(occ(C,O),_),
9370 ( ai_observation_is_observed(APP,C) ->
9371 ai_observed_internal(C,O)
9373 ai_not_observed_internal(C,O)
9376 APP = odom([],Set0),
9377 ord_del_element(Set0,C,Set),
9382 ai_observation_lub(NAPP,APD,AP),
9383 final_answer_pattern(CP,AP).
9385 %------------------------------------------------------------------------------%
9387 %------------------------------------------------------------------------------%
9389 call_pattern_worker(CP) <=> chr_error(internal,'AI observation analysis: unexpected abstract state ~w\n',[CP]).
9391 %------------------------------------------------------------------------------%
9392 % Auxiliary Predicates
9393 %------------------------------------------------------------------------------%
9395 ai_observation_lub(odom(AG,S1),odom(AG,S2),odom(AG,S3)) :-
9396 ord_intersection(S1,S2,S3).
9398 ai_observation_bot(AG,AS,odom(AG,AS)).
9400 ai_observation_top(AG,odom(AG,EmptyS)) :-
9403 ai_observation_leq(odom(AG,S1),odom(AG,S2)) :-
9406 ai_observation_observe_set(S,ACSet,NS) :-
9407 ord_subtract(S,ACSet,NS).
9409 ai_observation_abstract_constraint(C,ACs,AC) :-
9414 ai_observation_abstract_constraints(Cs,ACs,NACs) :-
9415 findall(NAC,(member(C,Cs),ai_observation_abstract_constraint(C,ACs,NAC)),NACs).
9417 %------------------------------------------------------------------------------%
9418 % Abstraction of Rule Bodies
9419 %------------------------------------------------------------------------------%
9422 ai_observation_memoed_abstract_goal/2,
9423 ai_observation_memo_abstract_goal/2.
9425 :- chr_option(mode,ai_observation_memoed_abstract_goal(+,+)).
9426 :- chr_option(mode,ai_observation_memo_abstract_goal(+,?)).
9428 ai_observation_memoed_abstract_goal(RuleNb,AG) # ID1 \ ai_observation_memo_abstract_goal(RuleNb,QAG)
9434 rule(RuleNb,Rule) # ID1, abstract_constraints(ACs) # ID2 \ ai_observation_memo_abstract_goal(RuleNb,QAG)
9436 Rule = pragma(rule(H1,H2,Guard,Body),_,_,_,_),
9437 ai_observation_abstract_goal_(H1,H2,Guard,Body,ACs,AG),
9439 ai_observation_memoed_abstract_goal(RuleNb,AG)
9444 ai_observation_abstract_goal_(H1,H2,Guard,G,ACs,AG) :-
9445 % also guard: e.g. b, c(X) ==> Y=X | p(Y).
9446 term_variables((H1,H2,Guard),HVars),
9447 append(H1,H2,Heads),
9448 % variables that are declared to be ground are safe,
9449 ground_vars(Heads,GroundVars),
9450 % so we remove them from the list of 'dangerous' head variables
9451 list_difference_eq(HVars,GroundVars,HV),
9452 ai_observation_abstract_goal(G,ACs,AG,[],HV),!.
9453 % writeln(ai_observation_abstract_goal(G,ACs,AG,[],HV)).
9454 % HV are 'dangerous' variables, all others are fresh and safe
9457 ground_vars([H|Hs],GroundVars) :-
9459 get_constraint_mode(F/A,Mode),
9460 % TOM: fix this code!
9461 head_info(H,A,_Vars,_Susp,_HeadVars,HeadPairs),
9462 head_arg_matches(HeadPairs,Mode,[],_FirstMatching,_VarDict1,[],GroundVars1),
9463 ground_vars(Hs,GroundVars2),
9464 append(GroundVars1,GroundVars2,GroundVars).
9466 ai_observation_abstract_goal((G1,G2),ACs,List,Tail,HV) :- !, % conjunction
9467 ai_observation_abstract_goal(G1,ACs,List,IntermediateList,HV),
9468 ai_observation_abstract_goal(G2,ACs,IntermediateList,Tail,HV).
9469 ai_observation_abstract_goal((G1;G2),ACs,[(ABranch1;ABranch2)|Tail],Tail,HV) :- !, % disjunction
9470 ai_observation_abstract_goal(G1,ACs,ABranch1,[],HV),
9471 ai_observation_abstract_goal(G2,ACs,ABranch2,[],HV).
9472 ai_observation_abstract_goal((G1->G2),ACs,List,Tail,HV) :- !, % if-then
9473 ai_observation_abstract_goal(G1,ACs,List,IntermediateList,HV),
9474 ai_observation_abstract_goal(G2,ACs,IntermediateList,Tail,HV).
9475 ai_observation_abstract_goal(C,ACs,[AC|Tail],Tail,HV) :-
9476 ai_observation_abstract_constraint(C,ACs,AC), !. % CHR constraint
9477 ai_observation_abstract_goal(true,_,Tail,Tail,_) :- !.
9478 ai_observation_abstract_goal(writeln(_),_,Tail,Tail,_) :- !.
9479 % non-CHR constraint is safe if it only binds fresh variables
9480 ai_observation_abstract_goal(G,_,Tail,Tail,HV) :-
9481 builtin_binds_b(G,Vars),
9482 intersect_eq(Vars,HV,[]),
9484 ai_observation_abstract_goal(G,_,[AG|Tail],Tail,_) :-
9485 AG = builtin. % default case if goal is not recognized/safe
9487 ai_observation_is_observed(odom(_,ACSet),AC) :-
9488 \+ ord_memberchk(AC,ACSet).
9490 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9491 unconditional_occurrence(C,O) :-
9492 get_occurrence(C,O,RuleNb,ID),
9493 get_rule(RuleNb,PRule),
9494 PRule = pragma(ORule,_,_,_,_),
9495 copy_term_nat(ORule,Rule),
9496 Rule = rule(H1,H2,Guard,_),
9497 guard_entailment:entails_guard([chr_pp_headvariables(H1,H2)],Guard),
9499 H1 = [Head], H2 == []
9501 H2 = [Head], H1 == [], \+ may_trigger(C)
9503 all_distinct_var_args(Head).
9505 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9507 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9508 % Partial wake analysis
9510 % In a Var = Var unification do not wake up constraints of both variables,
9511 % but rather only those of one variable.
9512 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9514 :- chr_constraint partial_wake_analysis/0.
9515 :- chr_constraint no_partial_wake/1.
9516 :- chr_option(mode,no_partial_wake(+)).
9517 :- chr_constraint wakes_partially/1.
9518 :- chr_option(mode,wakes_partially(+)).
9520 partial_wake_analysis, occurrence(FA,O,RuleNb,ID,Type), rule(RuleNb,Rule), constraint_mode(FA,ArgModes)
9522 Rule = pragma(rule(H1,H2,Guard,Body),_,_,_,_),
9523 ( is_passive(RuleNb,ID) ->
9525 ; Type == simplification ->
9526 select(H,H1,RestH1),
9528 term_variables(Guard,Vars),
9529 partial_wake_args(Args,ArgModes,Vars,FA)
9530 ; % Type == propagation ->
9531 select(H,H2,RestH2),
9533 term_variables(Guard,Vars),
9534 partial_wake_args(Args,ArgModes,Vars,FA)
9537 partial_wake_args([],_,_,_).
9538 partial_wake_args([Arg|Args],[Mode|Modes],Vars,C) :-
9542 ; memberchk_eq(Arg,Vars) ->
9550 partial_wake_args(Args,Modes,Vars,C).
9552 no_partial_wake(C) \ no_partial_wake(C) <=> true.
9554 no_partial_wake(C) \ wakes_partially(C) <=> fail.
9556 wakes_partially(C) <=> true.
9559 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9560 % Generate rules that implement chr_show_store/1 functionality.
9566 % Generates additional rules:
9568 % $show, C1 # ID ==> writeln(C1) pragma passive(ID).
9570 % $show, Cn # ID ==> writeln(Cn) pragma passive(ID).
9573 generate_show_constraint(Constraints0,Constraints,Rules0,Rules) :-
9574 ( chr_pp_flag(show,on) ->
9575 Constraints = ['$show'/0|Constraints0],
9576 generate_show_rules(Constraints0,Rules,[Rule|Rules0]),
9577 inc_rule_count(RuleNb),
9579 rule(['$show'],[],true,true),
9586 Constraints = Constraints0,
9590 generate_show_rules([],Rules,Rules).
9591 generate_show_rules([F/A|Rest],[Rule|Tail],Rules) :-
9593 inc_rule_count(RuleNb),
9595 rule([],['$show',C],true,writeln(C)),
9601 generate_show_rules(Rest,Tail,Rules).
9603 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9604 % Custom supension term layout
9606 static_suspension_term(F/A,Suspension) :-
9607 suspension_term_base(F/A,Base),
9609 functor(Suspension,suspension,Arity).
9611 has_suspension_field(FA,Field) :-
9612 suspension_term_base_fields(FA,Fields),
9613 memberchk(Field,Fields).
9615 suspension_term_base(FA,Base) :-
9616 suspension_term_base_fields(FA,Fields),
9617 length(Fields,Base).
9619 suspension_term_base_fields(FA,Fields) :-
9620 ( chr_pp_flag(debugable,on) ->
9623 % 3. Propagation History
9624 % 4. Generation Number
9625 % 5. Continuation Goal
9627 Fields = [id,state,history,generation,continuation,functor]
9629 ( uses_history(FA) ->
9630 Fields = [id,state,history|Fields2]
9631 ; only_ground_indexed_arguments(FA), get_functional_dependency(FA,1,_,_) ->
9632 Fields = [state|Fields2]
9634 Fields = [id,state|Fields2]
9636 ( only_ground_indexed_arguments(FA) ->
9637 get_store_type(FA,StoreType),
9638 basic_store_types(StoreType,BasicStoreTypes),
9639 ( memberchk(global_ground,BasicStoreTypes) ->
9642 % 3. Propagation History
9643 % 4. Global List Prev
9644 Fields2 = [global_list_prev|Fields3]
9648 % 3. Propagation History
9651 ( chr_pp_flag(ht_removal,on)
9652 -> ht_prev_fields(BasicStoreTypes,Fields3)
9655 ; may_trigger(FA) ->
9658 % 3. Propagation History
9659 ( uses_field(FA,generation) ->
9660 % 4. Generation Number
9661 % 5. Global List Prev
9662 Fields2 = [generation,global_list_prev|Fields3]
9664 Fields2 = [global_list_prev|Fields3]
9666 ( chr_pp_flag(mixed_stores,on),
9667 chr_pp_flag(ht_removal,on)
9668 -> get_store_type(FA,StoreType),
9669 basic_store_types(StoreType,BasicStoreTypes),
9670 ht_prev_fields(BasicStoreTypes,Fields3)
9676 % 3. Propagation History
9677 % 4. Global List Prev
9678 Fields2 = [global_list_prev|Fields3],
9679 ( chr_pp_flag(mixed_stores,on),
9680 chr_pp_flag(ht_removal,on)
9681 -> get_store_type(FA,StoreType),
9682 basic_store_types(StoreType,BasicStoreTypes),
9683 ht_prev_fields(BasicStoreTypes,Fields3)
9689 ht_prev_fields(Stores,Prevs) :-
9690 ht_prev_fields_int(Stores,PrevsList),
9691 append(PrevsList,Prevs).
9692 ht_prev_fields_int([],[]).
9693 ht_prev_fields_int([H|T],Fields) :-
9694 ( H = multi_hash(Indexes)
9695 -> maplist(ht_prev_field,Indexes,FH),
9699 ht_prev_fields_int(T,FT).
9701 ht_prev_field(Index,Field) :-
9702 concat_atom(['multi_hash_prev-'|Index],Field).
9704 get_static_suspension_term_field(FieldName,FA,StaticSuspension,Field) :-
9705 suspension_term_base_fields(FA,Fields),
9706 nth1(Index,Fields,FieldName), !,
9707 arg(Index,StaticSuspension,Field).
9708 get_static_suspension_term_field(arguments,FA,StaticSuspension,Field) :- !,
9709 suspension_term_base(FA,Base),
9710 StaticSuspension =.. [_|Args],
9711 drop(Base,Args,Field).
9712 get_static_suspension_term_field(FieldName,FA,_StaticSuspension,_Field) :-
9713 chr_error(internal,'Trying to obtain field ~w of ~w, wich does not have it!',[FieldName,FA]).
9716 get_dynamic_suspension_term_field(FieldName,FA,DynamicSuspension,Field,Goal) :-
9717 suspension_term_base_fields(FA,Fields),
9718 nth1(Index,Fields,FieldName), !,
9719 Goal = arg(Index,DynamicSuspension,Field).
9720 get_dynamic_suspension_term_field(arguments,FA,DynamicSuspension,Field,Goal) :- !,
9721 static_suspension_term(FA,StaticSuspension),
9722 get_static_suspension_term_field(arguments,FA,StaticSuspension,Field),
9723 Goal = (DynamicSuspension = StaticSuspension).
9724 get_dynamic_suspension_term_field(argument(I),FA,DynamicSuspension,Field,Goal) :- !,
9725 suspension_term_base(FA,Base),
9727 Goal = arg(Index,DynamicSuspension,Field).
9728 get_dynamic_suspension_term_field(FieldName,FA,_DynamicSuspension,_Field,_Goal) :-
9729 chr_error(internal,'Dynamic goal to get ~w of ~w, which does not have this field!',[FieldName,FA]).
9732 set_dynamic_suspension_term_field(FieldName,FA,DynamicSuspension,Field,Goal) :-
9733 suspension_term_base_fields(FA,Fields),
9734 nth1(Index,Fields,FieldName), !,
9735 Goal = setarg(Index,DynamicSuspension,Field).
9736 set_dynamic_suspension_term_field(FieldName,FA,_DynamicSuspension,_Field,_Goal) :-
9737 chr_error(internal,'Dynamic goal to set ~w of ~w, which does not have this field!',[FieldName,FA]).
9739 basic_store_types(multi_store(Types),Types) :- !.
9740 basic_store_types(Type,[Type]).
9742 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9749 :- chr_option(mode,phase_end(+)).
9750 :- chr_option(mode,delay_phase_end(+,?)).
9752 phase_end(Phase) \ delay_phase_end(Phase,Goal) <=> call(Goal).
9753 % phase_end(Phase) <=> true.
9756 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9760 novel_production_call/4.
9762 :- chr_option(mode,uses_history(+)).
9763 :- chr_option(mode,does_use_history(+,+)).
9764 :- chr_option(mode,novel_production_call(+,+,?,?)).
9766 does_use_history(FA,Occ) \ does_use_history(FA,Occ) <=> true.
9767 does_use_history(FA,_) \ uses_history(FA) <=> true.
9768 uses_history(_FA) <=> fail.
9770 does_use_history(FA,Occ) \ novel_production_call(FA,Occ,PossibleGoal,Goal) <=> Goal = PossibleGoal.
9771 novel_production_call(FA,_,_PossibleGoal,Goal) <=> Goal = true.
9777 :- chr_option(mode,uses_field(+,+)).
9778 :- chr_option(mode,does_use_field(+,+)).
9780 does_use_field(FA,Field) \ does_use_field(FA,Field) <=> true.
9781 does_use_field(FA,Field) \ uses_field(FA,Field) <=> true.
9782 uses_field(_FA,_Field) <=> fail.
9787 used_states_known/0.
9789 :- chr_option(mode,uses_state(+,+)).
9790 :- chr_option(mode,if_used_state(+,+,?,?,?)).
9793 % states ::= not_stored_yet | passive | active | triggered | removed
9795 % allocate CREATES not_stored_yet
9796 % remove CHECKS not_stored_yet
9797 % activate CHECKS not_stored_yet
9799 % ==> no allocate THEN no not_stored_yet
9801 % recurs CREATES inactive
9802 % lookup CHECKS inactive
9804 % insert CREATES active
9805 % activate CREATES active
9806 % lookup CHECKS active
9807 % recurs CHECKS active
9809 % runsusp CREATES triggered
9810 % lookup CHECKS triggered
9812 % ==> no runsusp THEN no triggered
9814 % remove CREATES removed
9815 % runsusp CHECKS removed
9816 % lookup CHECKS removed
9817 % recurs CHECKS removed
9819 % ==> no remove THEN no removed
9821 % ==> no allocate, no remove, no active/inactive distinction THEN no state at all...
9823 uses_state(Constraint,State) \ uses_state(Constraint,State) <=> true.
9825 used_states_known, uses_state(Constraint,State) \ if_used_state(Constraint,State,Used,NotUsed,ResultGoal)
9826 <=> ResultGoal = Used.
9827 used_states_known \ if_used_state(Constraint,State,Used,NotUsed,ResultGoal)
9828 <=> ResultGoal = NotUsed.
9830 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9831 % CHECK STOREDNESS ANNOTATIONS AND GENERATE DEFAULT SIMPLIFICATION RULES
9837 % When the programmer enables the `declare_stored_constraints' option, i.e. writes
9839 % :- chr_option(declare_stored_constraints,on).
9841 % the compiler will check for the storedness of constraints.
9843 % By default, the compiler assumes that the programmer wants his constraints to
9844 % be never-stored. Hence, a warning will be issues when a constraint is actually
9847 % Such warnings are suppressed, if the programmer adds the `# stored' modifier
9848 % to a constraint declaration, i.e. writes
9850 % :- chr_constraint c(...) # stored.
9852 % In that case a warning is issued when the constraint is never-stored.
9854 % NOTE: Checking is only performed if `storage_analysis' is on. Otherwise, all
9855 % constraints are stored anyway.
9858 % 2. Rule Generation
9859 % ~~~~~~~~~~~~~~~~~~
9861 % When the programmer enables the `declare_stored_constraints' option, i.e. writes
9863 % :- chr_option(declare_stored_constraints,on).
9865 % the compiler will generate default simplification rules for constraints.
9867 % By default, no default rule is generated for a constraint. However, if the
9868 % programmer writes a default/1 annotation in the constraint declaration, i.e. writes
9870 % :- chr_constraint c(...) # default(Goal).
9872 % where `Goal' is a ground and callable goal (e.g. `true', `fail' or `throw(error)'),
9873 % the compiler generates a rule:
9875 % c(_,...,_) <=> Goal.
9877 % at the end of the program. If multiple default rules are generated, for several constraints,
9878 % then the order of the default rules is not specified.
9881 :- chr_constraint stored_assertion/1.
9882 :- chr_option(mode,stored_assertion(+)).
9883 :- chr_option(type_declaration,stored_assertion(constraint)).
9885 :- chr_constraint never_stored_default/2.
9886 :- chr_option(mode,never_stored_default(+,?)).
9887 :- chr_option(type_declaration,never_stored_default(constraint,any)).
9892 generate_never_stored_rules(Constraints,Rules) :-
9893 ( chr_pp_flag(declare_stored_constraints,on) ->
9894 never_stored_rules(Constraints,Rules)
9899 :- chr_constraint never_stored_rules/2.
9900 :- chr_option(mode,never_stored_rules(+,?)).
9901 :- chr_option(type_declaration,never_stored_rules(list(constraint),any)).
9903 never_stored_rules([],Rules) <=> Rules = [].
9904 never_stored_default(Constraint,Goal) \ never_stored_rules([Constraint|Constraints],Rules) <=>
9907 inc_rule_count(RuleNb),
9909 rule([Head],[],true,Goal),
9915 Rules = [Rule|Tail],
9916 never_stored_rules(Constraints,Tail).
9917 never_stored_rules([_|Constraints],Rules) <=>
9918 never_stored_rules(Constraints,Rules).
9923 check_storedness_assertions(Constraints) :-
9924 ( chr_pp_flag(storage_analysis,on), chr_pp_flag(declare_stored_constraints,on) ->
9925 forall(Constraint,Constraints,check_storedness_assertion(Constraint))
9931 :- chr_constraint check_storedness_assertion/1.
9932 :- chr_option(mode,check_storedness_assertion(+)).
9933 :- chr_option(type_declaration,check_storedness_assertion(constraint)).
9935 check_storedness_assertion(Constraint), stored_assertion(Constraint)
9936 <=> ( is_stored(Constraint) ->
9939 chr_warning(assertion_failed,'Constraint ~w is not stored. However, it was asserted to be stored.\n',[Constraint])
9941 never_stored_default(Constraint,_) \ check_storedness_assertion(Constraint)
9942 <=> ( is_finally_stored(Constraint) ->
9943 chr_warning(assertion_failed,'Constraint ~w is stored. However, it was asserted not to be stored.\n',[Constraint])
9944 ; is_stored(Constraint) ->
9945 chr_warning(assertion_failed,'Constraint ~w is temporarily stored. However, it was asserted not to be stored.\n',[Constraint])
9949 % never-stored, no default goal
9950 check_storedness_assertion(Constraint)
9951 <=> ( is_finally_stored(Constraint) ->
9952 chr_warning(assertion_failed,'Constraint ~w is stored. However, it was asserted not to be stored.\n',[Constraint])
9953 ; is_stored(Constraint) ->
9954 chr_warning(assertion_failed,'Constraint ~w is temporarily stored. However, it was asserted not to be stored.\n',[Constraint])
9959 %^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
9960 % success continuation analysis
9963 % also use for forward jumping improvement!
9964 % use Prolog indexing for generated code
9968 % should_skip_to_next_id(C,O)
9970 % get_occurrence_code_id(C,O,Id)
9972 %vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
9974 continuation_analysis(ConstraintSymbols) :-
9975 maplist(analyse_continuations,ConstraintSymbols).
9977 analyse_continuations(C) :-
9978 % 1. compute success continuations of the
9979 % occurrences of constraint C
9980 continuation_analysis(C,1),
9981 % 2. determine for which occurrences
9982 % to skip to next code id
9983 get_max_occurrence(C,MO),
9985 bulk_propagation(C,1,LO),
9986 % 3. determine code id for each occurrence
9987 set_occurrence_code_id(C,1,0).
9989 % 1. Compute the success continuations of constrait C
9990 %-------------------------------------------------------------------------------
9992 continuation_analysis(C,O) :-
9993 get_max_occurrence(C,MO),
9998 continuation_occurrence(C,O,NextO)
10000 constraint_continuation(C,O,MO,NextO),
10001 continuation_occurrence(C,O,NextO),
10003 continuation_analysis(C,NO)
10006 constraint_continuation(C,O,MO,NextO) :-
10007 ( get_occurrence_head(C,O,Head) ->
10009 ( between(NO,MO,NextO),
10010 get_occurrence_head(C,NextO,NextHead),
10011 unifiable(Head,NextHead,_) ->
10016 ; % current occurrence is passive
10020 get_occurrence_head(C,O,Head) :-
10021 get_occurrence(C,O,RuleNb,Id),
10022 \+ is_passive(RuleNb,Id),
10023 get_rule(RuleNb,Rule),
10024 Rule = pragma(rule(H1,H2,_,_),ids(Ids1,Ids2),_,_,_),
10025 ( select2(Id,Head,Ids1,H1,_,_) -> true
10026 ; select2(Id,Head,Ids2,H2,_,_)
10029 :- chr_constraint continuation_occurrence/3.
10030 :- chr_option(mode,continuation_occurrence(+,+,+)).
10032 :- chr_constraint get_success_continuation_occurrence/3.
10033 :- chr_option(mode,get_success_continuation_occurrence(+,+,-)).
10035 continuation_occurrence(C,O,NO) \ get_success_continuation_occurrence(C,O,X)
10039 get_success_continuation_occurrence(C,O,X)
10041 chr_error(internal,'Success continuation not found for ~w.\n',[C:O]).
10043 % 2. figure out when to skip to next code id
10044 %-------------------------------------------------------------------------------
10045 % don't go beyond the last occurrence
10046 % we have to go to next id for storage here
10048 :- chr_constraint skip_to_next_id/2.
10049 :- chr_option(mode,skip_to_next_id(+,+)).
10051 :- chr_constraint should_skip_to_next_id/2.
10052 :- chr_option(mode,should_skip_to_next_id(+,+)).
10054 skip_to_next_id(C,O) \ should_skip_to_next_id(C,O)
10058 should_skip_to_next_id(_,_)
10062 :- chr_constraint bulk_propagation/3.
10063 :- chr_option(mode,bulk_propagation(+,+,+)).
10065 max_occurrence(C,MO) \ bulk_propagation(C,O,_)
10069 skip_to_next_id(C,O).
10070 % we have to go to the next id here because
10071 % a predecessor needs it
10072 bulk_propagation(C,O,LO)
10076 skip_to_next_id(C,O),
10077 get_max_occurrence(C,MO),
10079 bulk_propagation(C,LO,NLO).
10080 % we have to go to the next id here because
10081 % we're running into a simplification rule
10082 % IMPROVE: propagate back to propagation predecessor (IF ANY)
10083 occurrence(C,NO,_,_,simplification) \ bulk_propagation(C,O,LO)
10087 skip_to_next_id(C,O),
10088 get_max_occurrence(C,MO),
10090 bulk_propagation(C,NO,NLO).
10091 % we skip the next id here
10092 % and go to the next occurrence
10093 continuation_occurrence(C,O,NextO) \ bulk_propagation(C,O,LO)
10097 NLO is min(LO,NextO),
10099 bulk_propagation(C,NO,NLO).
10101 % err on the safe side
10102 bulk_propagation(C,O,LO)
10104 skip_to_next_id(C,O),
10105 get_max_occurrence(C,MO),
10108 bulk_propagation(C,NO,NLO).
10110 skip_to_next_id(C,O) \ skip_to_next_id(C,O) <=> true.
10112 % if this occurrence is passive, but has to skip,
10113 % then the previous one must skip instead...
10114 % IMPROVE reasoning is conservative
10115 occurrence(C,O,RuleNb,Id,_), passive(RuleNb,Id), skip_to_next_id(C,O)
10120 skip_to_next_id(C,PO).
10122 % 3. determine code id of each occurrence
10123 %-------------------------------------------------------------------------------
10125 :- chr_constraint set_occurrence_code_id/3.
10126 :- chr_option(mode,set_occurrence_code_id(+,+,+)).
10128 :- chr_constraint occurrence_code_id/3.
10129 :- chr_option(mode,occurrence_code_id(+,+,+)).
10132 set_occurrence_code_id(C,O,IdNb)
10134 get_max_occurrence(C,MO),
10137 occurrence_code_id(C,O,IdNb).
10139 % passive occurrences don't change the code id
10140 occurrence(C,O,RuleNb,Id,_), passive(RuleNb,Id) \ set_occurrence_code_id(C,O,IdNb)
10142 occurrence_code_id(C,O,IdNb),
10144 set_occurrence_code_id(C,NO,IdNb).
10146 occurrence(C,O,RuleNb,Id,simplification) \ set_occurrence_code_id(C,O,IdNb)
10148 occurrence_code_id(C,O,IdNb),
10150 set_occurrence_code_id(C,NO,IdNb).
10152 occurrence(C,O,RuleNb,Id,propagation), skip_to_next_id(C,O) \ set_occurrence_code_id(C,O,IdNb)
10154 occurrence_code_id(C,O,IdNb),
10157 set_occurrence_code_id(C,NO,NIdNb).
10159 occurrence(C,O,RuleNb,Id,propagation) \ set_occurrence_code_id(C,O,IdNb)
10161 occurrence_code_id(C,O,IdNb),
10163 set_occurrence_code_id(C,NO,IdNb).
10165 % occurrence_code_id(C,O,IdNb) ==> writeln(occurrence_code_id(C,O,IdNb)).
10167 :- chr_constraint get_occurrence_code_id/3.
10168 :- chr_option(mode,get_occurrence_code_id(+,+,-)).
10170 occurrence_code_id(C,O,IdNb) \ get_occurrence_code_id(C,O,X)
10174 get_occurrence_code_id(C,O,X)
10179 format('no occurrence code for ~w!\n',[C:O])
10182 get_success_continuation_code_id(C,O,NextId) :-
10183 get_success_continuation_occurrence(C,O,NextO),
10184 get_occurrence_code_id(C,NextO,NextId).
10186 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10187 % COLLECT CONSTANTS FOR INLINING
10191 %%% TODO: APPLY NEW DICT FORMAT DOWNWARDS
10193 % collect_constants(+rules,+constraint_symbols,+clauses) {{{
10194 collect_constants(Rules,Constraints,Clauses0) :-
10195 ( not_restarted, chr_pp_flag(experiment,on) ->
10196 ( chr_pp_flag(sss,on) ->
10197 Dictionary = [fep/4-[2,3]-[[a,b]-fep1,[c,d]-fep2]-no],
10198 copy_term_nat(Clauses0,Clauses),
10199 flatten_clauses(Clauses,Dictionary,FlatClauses),
10200 install_new_declarations_and_restart(FlatClauses)
10202 maplist(collect_rule_constants(Constraints),Rules),
10203 ( chr_pp_flag(verbose,on) ->
10204 print_chr_constants
10208 ( chr_pp_flag(experiment,on) ->
10209 flattening_dictionary(Constraints,Dictionary),
10210 copy_term_nat(Clauses0,Clauses),
10211 flatten_clauses(Clauses,Dictionary,FlatClauses),
10212 install_new_declarations_and_restart(FlatClauses)
10221 :- chr_constraint chr_constants/1.
10222 :- chr_option(mode,chr_constants(+)).
10224 :- chr_constraint get_chr_constants/1.
10226 chr_constants(Constants) \ get_chr_constants(Q) <=> Q = Constants.
10228 get_chr_constants(Q) <=> chr_warning(internal,'No constants found for key ~w.\n',[Key]), Q = [].
10230 % collect_rule_constants(+constraint_symbols,+rule) {{{
10231 collect_rule_constants(Constraints,Rule) :-
10232 Rule = pragma(rule(H1,H2,_,B),_,_,_,_),
10233 maplist(collect_head_constants,H1),
10234 maplist(collect_head_constants,H2),
10235 collect_body_constants(B,Constraints).
10237 collect_body_constants(Body,Constraints) :-
10238 conj2list(Body,Goals),
10239 maplist(collect_goal_constants(Constraints),Goals).
10241 collect_goal_constants(Constraints,Goal) :-
10244 memberchk(C/N,Constraints) ->
10245 collect_head_constants(Goal)
10247 Goal = Mod : TheGoal,
10248 get_target_module(Module),
10251 functor(TheGoal,C,N),
10252 memberchk(C/N,Constraints) ->
10253 collect_head_constants(TheGoal)
10258 collect_head_constants(Head) :-
10260 get_constraint_type_det(C/N,Types),
10262 collect_all_arg_constants(Args,Types,[]).
10264 collect_all_arg_constants([],[],Constants) :-
10265 ( Constants \== [] ->
10266 add_chr_constants(Constants)
10270 collect_all_arg_constants([Arg|Args],[Type|Types],Constants0) :-
10271 unalias_type(Type,NormalizedType),
10272 ( is_chr_constants_type(NormalizedType,Key,_) ->
10274 collect_all_arg_constants(Args,Types,[Key-Arg|Constants0])
10275 ; % no useful information here
10279 collect_all_arg_constants(Args,Types,Constants0)
10282 add_chr_constants(Pairs) :-
10283 keysort(Pairs,SortedPairs),
10284 add_chr_constants_(SortedPairs).
10286 :- chr_constraint add_chr_constants_/1.
10287 :- chr_option(mode,add_chr_constants_(+)).
10289 add_chr_constants_(Constants), chr_constants(MoreConstants) <=>
10290 sort([Constants|MoreConstants],NConstants),
10291 chr_constants(NConstants).
10293 add_chr_constants_(Constants) <=>
10294 chr_constants([Constants]).
10298 :- chr_constraint print_chr_constants/0. % {{{
10300 print_chr_constants, chr_constants(Constants) # Id ==>
10301 format('\t* chr_constants : ~w.\n',[Constants])
10302 pragma passive(Id).
10304 print_chr_constants <=>
10309 % flattening_dictionary(+constraint_symbols,-dictionary) {{{
10310 flattening_dictionary([],[]).
10311 flattening_dictionary([CS|CSs],Dictionary) :-
10312 ( flattening_dictionary_entry(CS,Entry) ->
10313 Dictionary = [Entry|Rest]
10317 flattening_dictionary(CSs,Rest).
10319 flattening_dictionary_entry(CS,Entry) :-
10320 get_constraint_type_det(CS,Types),
10321 constant_positions(Types,1,Positions,Keys,Handler),
10322 Positions \== [], % there are chr_constant arguments
10323 pairup(Keys,Constants,Pairs0),
10324 keysort(Pairs0,Pairs),
10325 Entry = CS-Positions-Specs-Handler,
10326 get_chr_constants(ConstantsList),
10328 ( member(Pairs,ConstantsList)
10329 , flat_spec(CS,Positions,Constants,Spec)
10333 constant_positions([],_,[],[],no).
10334 constant_positions([Type|Types],I,Positions,Keys,Handler) :-
10335 unalias_type(Type,NormalizedType),
10336 ( is_chr_constants_type(NormalizedType,Key,ErrorHandler) ->
10337 compose_error_handlers(ErrorHandler,NHandler,Handler),
10338 Positions = [I|NPositions],
10341 NPositions = Positions,
10346 constant_positions(Types,J,NPositions,NKeys,NHandler).
10348 compose_error_handlers(no,Handler,Handler).
10349 compose_error_handlers(yes(Handler),_,yes(Handler)).
10351 flat_spec(C/N,Positions,Terms,Spec) :-
10352 Spec = Terms - Functor,
10353 term_to_atom(Terms,TermsAtom),
10354 term_to_atom(Positions,PositionsAtom),
10355 atom_concat_list(['$flat_',C,'/',N,'___',PositionsAtom,'___',TermsAtom],Functor).
10360 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10361 % RESTART AFTER FLATTENING {{{
10363 restart_after_flattening(Declarations,Declarations) :-
10364 nb_setval('$chr_restart_after_flattening',started).
10365 restart_after_flattening(_,Declarations) :-
10366 nb_getval('$chr_restart_after_flattening',restart(Declarations)),
10367 nb_setval('$chr_restart_after_flattening',restarted).
10370 nb_getval('$chr_restart_after_flattening',started).
10372 install_new_declarations_and_restart(Declarations) :-
10373 nb_setval('$chr_restart_after_flattening',restart(Declarations)),
10374 fail. /* fails to choicepoint of restart_after_flattening */
10376 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10380 % -) generate dictionary from collected chr_constants
10381 % enable with :- chr_option(experiment,on).
10382 % -) issue constraint declarations for constraints not present in
10384 % -) integrate with CHR compiler
10385 % -) pass Mike's test code (full syntactic support for current CHR code)
10386 % -) rewrite the body using the inliner
10389 % -) refined semantics correctness issue
10390 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10392 flatten_clauses(Clauses,Dict,NClauses) :-
10393 flatten_readcontent(Clauses,Rules,Symbols,ModeDecls,_TypeDefs,TypeDecls,RestClauses),
10394 flatten_clauses_(Dict,Rules,RestClauses,Symbols,ModeDecls,TypeDecls,NClauses).
10396 flatten_clauses_(Dict,Clauses,RestClauses,Symbols,ModeDecls,TypeDecls,NClauses) :-
10397 auxiliary_constraints_declarations(Dict,ModeDecls,TypeDecls,NClauses0),
10398 dispatching_rules(Dict,NClauses1),
10399 declarations(Symbols,Dict,ModeDecls,TypeDecls,NClauses2),
10400 flatten_rules(Clauses,Dict,NClauses3),
10401 append([RestClauses,NClauses0,NClauses1,NClauses2,NClauses3],NClauses).
10403 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10404 % Declarations for non-flattened constraints
10406 % declarations(+constraint_symbols,+dict,+mode_decls,+type_decls,-clauses) {{{
10407 declarations(ConstraintSymbols,Dict,ModeDecls,TypeDecls,Declarations) :-
10408 findall(Symbol,(member(Symbol,ConstraintSymbols), \+ memberchk(Symbol-_-_-_,Dict)),Symbols),
10409 maplist(declaration(ModeDecls,TypeDecls),Symbols,DeclarationsList),
10410 flatten(DeclarationsList,Declarations).
10412 declaration(ModeDecls,TypeDecls,ConstraintSymbol,
10413 [(:- chr_constraint ConstraintSymbol),
10414 (:- chr_option(mode,ModeDeclPattern)),
10415 (:- chr_option(type_declaration,TypeDeclPattern))
10417 ConstraintSymbol = Functor / Arity,
10418 % print optional mode declaration
10419 functor(ModeDeclPattern,Functor,Arity),
10420 ( memberchk(ModeDeclPattern,ModeDecls) ->
10423 replicate(Arity,(?),Modes),
10424 ModeDeclPattern =.. [_|Modes]
10426 % print optional type declaration
10427 functor(TypeDeclPattern,Functor,Arity),
10428 ( memberchk(TypeDeclPattern,TypeDecls) ->
10431 replicate(Arity,any,Types),
10432 TypeDeclPattern =.. [_|Types]
10435 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10436 % read clauses from file
10438 % declared constaints are returned
10439 % type definitions are returned and printed
10440 % mode declarations are returned
10441 % other clauses are returned
10443 % flatten_readcontent(+clauses,-rules,-symbols,-mode_decls,-type_defs,-type_decls,-rest_clauses) {{{
10444 flatten_readcontent([],[],[],[],[],[],[]).
10445 flatten_readcontent([Clause|RClauses],Rules,ConstraintSymbols,ModeDecls,TypeDefs,TypeDecls,RestClauses) :-
10447 ( Clause == end_of_file ->
10449 ConstraintSymbols = [],
10454 ; crude_is_rule(Clause) ->
10455 Rules = [Clause|RestRules],
10456 flatten_readcontent(RClauses,RestRules,ConstraintSymbols,ModeDecls,TypeDefs,TypeDecls,RestClauses)
10457 ; pure_is_declaration(Clause,SomeConstraintSymbols,SomeModeDecls,SomeTypeDecls) ->
10458 append(SomeConstraintSymbols,RestConstraintSymbols,ConstraintSymbols),
10459 append(SomeModeDecls,RestModeDecls,ModeDecls),
10460 append(SomeTypeDecls,RestTypeDecls,TypeDecls),
10461 flatten_readcontent(RClauses,Rules,RestConstraintSymbols,RestModeDecls,TypeDefs,RestTypeDecls,RestClauses)
10462 ; is_mode_declaration(Clause,ModeDecl) ->
10463 ModeDecls = [ModeDecl|RestModeDecls],
10464 flatten_readcontent(RClauses,Rules,ConstraintSymbols,RestModeDecls,TypeDefs,TypeDecls,RestClauses)
10465 ; is_type_declaration(Clause,TypeDecl) ->
10466 TypeDecls = [TypeDecl|RestTypeDecls],
10467 flatten_readcontent(RClauses,Rules,ConstraintSymbols,ModeDecls,TypeDefs,RestTypeDecls,RestClauses)
10468 ; is_type_definition(Clause,TypeDef) ->
10469 RestClauses = [Clause|NRestClauses],
10470 TypeDefs = [TypeDef|RestTypeDefs],
10471 flatten_readcontent(RClauses,Rules,ConstraintSymbols,ModeDecls,RestTypeDefs,TypeDecls,NRestClauses)
10472 ; ( Clause = (:- op(A,B,C)) ->
10473 % assert operators in order to read and print them out properly
10478 RestClauses = [Clause|NRestClauses],
10479 flatten_readcontent(RClauses,Rules,ConstraintSymbols,ModeDecls,TypeDefs,TypeDecls,NRestClauses)
10482 crude_is_rule(_ @ _).
10483 crude_is_rule(_ pragma _).
10484 crude_is_rule(_ ==> _).
10485 crude_is_rule(_ <=> _).
10487 pure_is_declaration(D, Constraints,Modes,Types) :- %% constraint declaration
10488 D = (:- Decl), Decl =.. [F,Cs], F == (chr_constraint),
10489 conj2list(Cs,Constraints0),
10490 pure_extract_type_mode(Constraints0,Constraints,Modes,Types).
10492 pure_extract_type_mode([],[],[],[]).
10493 pure_extract_type_mode([F/A|R],[F/A|R2],Modes,Types) :- !,
10494 pure_extract_type_mode(R,R2,Modes,Types).
10495 pure_extract_type_mode([C|R],[ConstraintSymbol|R2],[Mode|Modes],Types) :-
10497 ConstraintSymbol = F/A,
10499 extract_types_and_modes(Args,ArgTypes,ArgModes),
10500 Mode =.. [F|ArgModes],
10501 ( forall(member(ArgType,ArgTypes),ArgType == any) ->
10504 Types = [Type|RTypes],
10505 Type =.. [F|ArgTypes]
10507 pure_extract_type_mode(R,R2,Modes,RTypes).
10509 is_mode_declaration((:- chr_option(mode,ModeDecl)),ModeDecl).
10511 is_type_declaration((:- chr_option(type_declaration,TypeDecl)),TypeDecl).
10513 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10514 % DECLARATIONS FOR FLATTENED CONSTRAINTS
10515 % including mode and type declarations
10517 % auxiliary_constraints_declarations(+dict,+mode_decls,+type_decls,-constraint_specs) {{{
10518 auxiliary_constraints_declarations(Dict,ModeDecls,TypeDecls,ConstraintSpecs) :-
10519 findall(ConstraintSpec,auxiliary_constraints_declaration(Dict,ModeDecls,TypeDecls,ConstraintSpec),ConstraintSpecs0),
10520 flatten(ConstraintSpecs0,ConstraintSpecs).
10522 auxiliary_constraints_declaration(Dict,ModeDecls,TypeDecls,
10523 [(:- chr_constraint ConstraintSpec),
10524 (:- chr_option(mode,NewModeDecl)),
10525 (:- chr_option(type_declaration,NewTypeDecl))]) :-
10526 member(C/N-I-SFs-_,Dict),
10527 arg_modes(C,N,ModeDecls,Modes),
10528 specialize_modes(Modes,I,SpecializedModes),
10529 arg_types(C,N,TypeDecls,Types),
10530 specialize_types(Types,I,SpecializedTypes),
10531 length(I,IndexSize),
10532 AN is N - IndexSize,
10533 member(_Term-F,SFs),
10534 ConstraintSpec = F/AN,
10535 NewModeDecl =.. [F|SpecializedModes],
10536 NewTypeDecl =.. [F|SpecializedTypes].
10538 arg_modes(C,N,ModeDecls,ArgModes) :-
10539 functor(ConstraintPattern,C,N),
10540 ( memberchk(ConstraintPattern,ModeDecls) ->
10541 ConstraintPattern =.. [_|ArgModes]
10543 replicate(N,?,ArgModes)
10546 specialize_modes(Modes,I,SpecializedModes) :-
10547 split_args(I,Modes,_,SpecializedModes).
10549 arg_types(C,N,TypeDecls,ArgTypes) :-
10550 functor(ConstraintPattern,C,N),
10551 ( memberchk(ConstraintPattern,TypeDecls) ->
10552 ConstraintPattern =.. [_|ArgTypes]
10554 replicate(N,any,ArgTypes)
10557 specialize_types(Types,I,SpecializedTypes) :-
10558 split_args(I,Types,_,SpecializedTypes).
10560 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10561 % DISPATCHING RULES
10563 % dispatching_rules(+dict,-newrules)
10568 % This code generates a decision tree for calling the appropriate specialized
10569 % constraint based on the particular value of the argument the constraint
10570 % is being specialized on.
10572 % In case an error handler is provided, the handler is called with the
10573 % unexpected constraint.
10575 dispatching_rules([],[]).
10576 dispatching_rules([CN-I-SFs-MaybeErrorHandler|Dict], DispatchingRules) :-
10577 constraint_dispatching_rule(SFs,CN,I,MaybeErrorHandler,DispatchingRules,RestDispatchingRules),
10578 dispatching_rules(Dict,RestDispatchingRules).
10580 constraint_dispatching_rule(SFs,C/N,I,MaybeErrorHandler,Rules,RestRules) :-
10581 ( increasing_numbers(I,1) ->
10582 /* index on first arguments */
10586 /* reorder arguments for 1st argument indexing */
10589 split_args(I,Args,GroundArgs,OtherArgs),
10590 append(GroundArgs,OtherArgs,ShuffledArgs),
10591 atom_concat(C,'_$shuffled',NC),
10592 Body =.. [NC|ShuffledArgs],
10593 [(Head :- Body)|Rules0] = Rules,
10596 Context = swap(C,I),
10597 dispatching_rule_term_cases(SFs,I,NCN,MaybeErrorHandler,Context,Rules0,RestRules).
10599 increasing_numbers([],_).
10600 increasing_numbers([X|Ys],X) :-
10602 increasing_numbers(Ys,Y).
10604 dispatching_rule_term_cases(SFs,I,NC/N,MaybeErrorHandler,Context,Rules,RestRules) :-
10605 length(I,IndexLength),
10606 once(pairup(TermLists,Functors,SFs)),
10607 maplist(head_tail,TermLists,Heads,Tails),
10608 Payload is N - IndexLength,
10609 maplist(wrap_in_functor(dispatching_action),Functors,Actions),
10610 dispatch_trie_index(Heads,Tails,Payload,MaybeErrorHandler,Context,Actions,NC,Rules,RestRules).
10612 dispatching_action(Functor,PayloadArgs,Goal) :-
10613 Goal =.. [Functor|PayloadArgs].
10615 dispatch_trie_index(Patterns,MorePatterns,Payload,MaybeErrorHandler,Context,Actions,Prefix,Clauses,Tail) :-
10616 dispatch_trie_step(Patterns,Prefix,Prefix,MorePatterns,Payload,MaybeErrorHandler,Context,Actions,Clauses,Tail).
10618 dispatch_trie_step([],_,_,_,[],_,_,[],L,L) :- !.
10619 % length MorePatterns == length Patterns == length Results
10620 dispatch_trie_step(Patterns,Symbol,Prefix,MorePatterns,Payload,MaybeErrorHandler,Context,Actions,Clauses,T) :-
10621 MorePatterns = [List|_],
10623 aggregate_all(set(F/A),
10624 ( member(Pattern,Patterns),
10625 functor(Pattern,F,A)
10629 dispatch_trie_step_cases(FAs,N1,Patterns,MorePatterns,Payload,MaybeErrorHandler,Context,Actions,Symbol,Prefix,Clauses,T).
10631 dispatch_trie_step_cases([],N,_,_,Payload,MaybeErrorHandler,Context,_,Symbol,_,Clauses0,Clauses) :-
10632 ( MaybeErrorHandler = yes(ErrorHandler) ->
10633 Clauses0 = [ErrorClause|Clauses],
10634 ErrorClause = (Head :- Body),
10635 Arity is N + Payload,
10636 functor(Head,Symbol,Arity),
10637 reconstruct_original_term(Context,Head,Term),
10638 Body =.. [ErrorHandler,Term]
10642 dispatch_trie_step_cases([FA|FAs],N,Pattern,MorePatterns,Payload,MaybeErrorHandler,Context,Actions,Symbol,Prefix,Clauses,Tail) :-
10643 dispatch_trie_step_case(FA,N,Pattern,MorePatterns,Payload,MaybeErrorHandler,Context,Actions,Symbol,Prefix,Clauses,Clauses1),
10644 dispatch_trie_step_cases(FAs,N,Pattern,MorePatterns,Payload,MaybeErrorHandler,Context,Actions,Symbol,Prefix,Clauses1,Tail).
10646 dispatch_trie_step_case(F/A,N,Patterns,MorePatterns,Payload,MaybeErrorHandler,Context0,Actions,Symbol,Prefix,[Clause|List],Tail) :-
10647 Clause = (Head :- Cut, Body),
10648 ( MaybeErrorHandler = yes(_) ->
10653 /* Head = Symbol(IndexPattern,V2,...,Vn,Payload) */
10655 functor(Head,Symbol,N1),
10656 arg(1,Head,IndexPattern),
10657 Head =.. [_,_|RestArgs],
10658 length(PayloadArgs,Payload),
10659 once(append(Vs,PayloadArgs,RestArgs)),
10660 /* IndexPattern = F(...) */
10661 functor(IndexPattern,F,A),
10662 Context1 = index_functor(F,A,Context0),
10663 IndexPattern =.. [_|Args],
10664 append(Args,RestArgs,RecArgs),
10665 ( RecArgs == PayloadArgs ->
10666 /* nothing more to match on */
10668 rec_cases(Patterns,_,Actions,F/A,_,_,MoreActions),
10669 MoreActions = [Action],
10670 call(Action,PayloadArgs,Body)
10671 ; /* more things to match on */
10672 rec_cases(Patterns,MorePatterns,Actions,F/A,Cases,MoreCases,MoreActions),
10673 ( MoreActions = [OneMoreAction] ->
10674 /* only one more thing to match on */
10675 MoreCases = [OneMoreCase],
10676 append([Cases,OneMoreCase,PayloadArgs],RecArgs),
10678 call(OneMoreAction,PayloadArgs,Body)
10680 /* more than one thing to match on */
10684 pairup(Cases,MoreCases,CasePairs),
10685 common_pattern(CasePairs,CommonPatternPair,DiffVars,Differences),
10686 append(Args,Vs,[First|Rest]),
10687 First-Rest = CommonPatternPair,
10688 Context2 = gct([First|Rest],Context1),
10689 gensym(Prefix,RSymbol),
10690 append(DiffVars,PayloadArgs,RecCallVars),
10691 Body =.. [RSymbol|RecCallVars],
10692 findall(CH-CT,member([CH|CT],Differences),CPairs),
10693 once(pairup(CHs,CTs,CPairs)),
10694 dispatch_trie_step(CHs,RSymbol,Prefix,CTs,Payload,MaybeErrorHandler,Context2,MoreActions,List,Tail)
10699 % split(list,int,before,at,after).
10701 split([X|Xs],I,Before,At,After) :-
10708 Before = [X|RBefore],
10709 split(Xs,J,RBefore,At,After)
10712 % reconstruct_original_term(Context,CurrentTerm,OriginalTerm)
10714 % context ::= swap(functor,positions)
10715 % | index_functor(functor,arity,context)
10716 % | gct(Pattern,Context)
10718 reconstruct_original_term(swap(Functor,Positions),Term,OriginalTerm) :-
10719 functor(Term,_,Arity),
10720 functor(OriginalTerm,Functor,Arity),
10721 OriginalTerm =.. [_|OriginalArgs],
10722 split_args(Positions,OriginalArgs,IndexArgs,OtherArgs),
10724 append(IndexArgs,OtherArgs,Args).
10725 reconstruct_original_term(index_functor(Functor,Arity,Context),Term0,OriginalTerm) :-
10726 Term0 =.. [Predicate|Args],
10727 split_at(Arity,Args,IndexArgs,RestArgs),
10728 Index =.. [Functor|IndexArgs],
10729 Term1 =.. [Predicate,Index|RestArgs],
10730 reconstruct_original_term(Context,Term1,OriginalTerm).
10731 reconstruct_original_term(gct(PatternList,Context),Term0,OriginalTerm) :-
10732 copy_term_nat(PatternList,IndexTerms),
10733 term_variables(IndexTerms,Variables),
10734 Term0 =.. [Predicate|Args0],
10735 append(Variables,RestArgs,Args0),
10736 append(IndexTerms,RestArgs,Args1),
10737 Term1 =.. [Predicate|Args1],
10738 reconstruct_original_term(Context,Term1,OriginalTerm).
10741 %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10742 % SUBSTITUTE CONSTRAINT SYMBOL FUNCTORS
10744 % flatten_rules(+rule_clauses,+dict,-rule_clauses).
10746 % dict :== list(functor/arity-list(int)-list(list(term)-functor)-maybe(error_handler))
10749 flatten_rules(Rules,Dict,FlatRules) :-
10750 flatten_rules1(Rules,Dict,FlatRulesList),
10751 flatten(FlatRulesList,FlatRules).
10753 flatten_rules1([],_,[]).
10754 flatten_rules1([Rule|Rules],Dict,[FlatRules|FlatRulesList]) :-
10755 findall(FlatRule,flatten_rule(Rule,Dict,FlatRule),FlatRules),
10756 flatten_rules1(Rules,Dict,FlatRulesList).
10758 flatten_rule((Name @ Rule),Dict,(Name @ NRule)) :- !,
10759 flatten_rule(Rule,Dict,NRule).
10760 flatten_rule((Rule pragma Pragmas),Dict,(NRule pragma Pragmas)) :- !,
10761 flatten_rule(Rule,Dict,NRule).
10762 flatten_rule((H ==> B),Dict,(NH ==> NB)) :- !,
10763 flatten_heads(H,Dict,NH),
10764 flatten_body(B,Dict,NB).
10765 flatten_rule((H1 \ H2 <=> B),Dict,(NH1 \ NH2 <=> NB)) :- !,
10766 flatten_heads((H1,H2),Dict,(NH1,NH2)),
10767 flatten_body(B,Dict,NB).
10768 flatten_rule((H <=> B),Dict,(NH <=> NB)) :-
10769 flatten_heads(H,Dict,NH),
10770 flatten_body(B,Dict,NB).
10772 flatten_heads((H1,H2),Dict,(NH1,NH2)) :- !,
10773 flatten_heads(H1,Dict,NH1),
10774 flatten_heads(H2,Dict,NH2).
10775 flatten_heads((H # Annotation),Dict,(NH # Annotation)) :- !,
10776 flatten_heads(H,Dict,NH).
10777 flatten_heads(H,Dict,NH) :-
10779 memberchk(C/N-ArgPositions-SFs-_,Dict) ->
10781 split_args(ArgPositions,AllArgs,GroundArgs,OtherArgs),
10782 member(GroundArgs-Name,SFs),
10783 NH =.. [Name|OtherArgs]
10788 flatten_body((Guard | Body),Dict,(NGuard | NBody)) :- !,
10789 conj2list(Guard,Guards),
10790 maplist(flatten_goal(Dict),Guards,NGuards),
10791 list2conj(NGuards,NGuard),
10792 conj2list(Body,Goals),
10793 maplist(flatten_goal(Dict),Goals,NGoals),
10794 list2conj(NGoals,NBody).
10795 flatten_body(Body,Dict,NBody) :-
10796 conj2list(Body,Goals),
10797 maplist(flatten_goal(Dict),Goals,NGoals),
10798 list2conj(NGoals,NBody).
10800 flatten_goal(Dict,Goal,NGoal) :- var(Goal), !, NGoal = Goal.
10801 flatten_goal(Dict,Goal,NGoal) :-
10802 ( is_specializable_goal(Goal,Dict,ArgPositions)
10804 specialize_goal(Goal,ArgPositions,NGoal)
10805 ; Goal = Mod : TheGoal,
10806 get_target_module(Module),
10809 is_specializable_goal(TheGoal,Dict,ArgPositions)
10811 specialize_goal(TheGoal,ArgPositions,NTheGoal),
10812 NGoal = Mod : NTheGoal
10813 ; partial_eval(Goal,NGoal)
10820 %-------------------------------------------------------------------------------%
10821 % Specialize body/guard goal
10822 %-------------------------------------------------------------------------------%
10823 is_specializable_goal(Goal,Dict,ArgPositions) :-
10825 memberchk(C/N-ArgPositions-_-_,Dict),
10826 args(ArgPositions,Goal,Args),
10829 specialize_goal(Goal,ArgPositions,NGoal) :-
10832 split_args(ArgPositions,Args,GroundTerms,Others),
10833 flat_spec(C/N,ArgPositions,GroundTerms,_-Functor),
10834 NGoal =.. [Functor|Others].
10836 %-------------------------------------------------------------------------------%
10837 % Partially evaluate predicates
10838 %-------------------------------------------------------------------------------%
10840 % append([],Y,Z) >--> Y = Z
10841 % append(X,[],Z) >--> X = Z
10842 partial_eval(append(L1,L2,L3),NGoal) :-
10849 % flatten_path(L1,L2) >--> flatten_path(L1',L2)
10850 % where flatten(L1,L1')
10851 partial_eval(flatten_path(L1,L2),NGoal) :-
10853 flatten(L1,FlatterL1),
10854 FlatterL1 \== L1 ->
10855 NGoal = flatten_path(FlatterL1,L2).
10861 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10862 dump_code(Clauses) :-
10863 ( chr_pp_flag(dump,on) ->
10864 maplist(portray_clause,Clauses)
10870 chr_info(banner,'\tThe K.U.Leuven CHR System\t\n\t\tContributors:\tTom Schrijvers, Jon Sneyers, Bart Demoen,\n\t\t\t\tJan Wielemaker\n\t\tCopyright:\tK.U.Leuven, Belgium\n\t\tURL:\t\thttp://www.cs.kuleuven.be/~~toms/CHR/\n',[]).