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 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
52 %% * SICStus compatibility
53 %% - rules/1 declaration
59 %% * do not suspend on variables that don't matter
60 %% * make difference between cheap guards
for reordering
61 %% and non
-binding guards
for lock removal
63 %% * unqiue
-> once
/[] transformation
for propagation
65 %% * cheap guards interleaved with head retrieval
+ faster
66 %% via
-retrieval
+ non
-empty checking
for propagation rules
67 %% redo for simpagation_head2 prelude
69 %% * intelligent backtracking
for simplification
/simpagation rule
70 %% generator_1
(X
),'_$savecp'(CP_1
),
77 %% ('_$cutto'(CP_1
), fail
)
81 %% or recently developped cascading
-supported approach
83 %% * intelligent backtracking
for propagation rule
84 %% use additional boolean argument
for each possible smart backtracking
85 %% when boolean at end of list true
-> no smart backtracking
86 %% false
-> smart backtracking
87 %% only works
for rules with at least
3 constraints
in the head
89 %% * mutually exclusive rules
91 %% * constraints that can never be attached
/ always simplified away
92 %% -> need
not be considered
in diverse operations
94 %% * (set semantics
+ functional dependency
) declaration
+ resolution
96 %% * type
and instantiation declarations
+ optimisations
99 %% * disable global store option
103 %% * clean up generated code
104 %% * input verification
: pragmas
105 %% * SICStus compatibility
: handler
/1, constraints/1
106 %% * optimise variable passing
for propagation rule
107 %% * reordering of head constraints
for passive head search
108 %% * unique inference
for simpagation rules
109 %% * unique optimisation
for simpagation
and simplification rules
110 %% * cheap guards interleaved with head retrieval
+ faster
111 %% via
-retrieval
+ non
-empty checking
for simplification
/ simpagation rules
115 %% C
# ID \ C <=> true pragma passive.
116 %% * valid to disregard body
in uniqueness inference?
117 %% * unique inference
for simplification rules
119 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
121 :- module
(chr_translate
,
122 [ chr_translate
/2 % +Decls
, -TranslatedDecls
125 :- use_module
(library
(lists
),[member
/2,append/3,permutation
/2,reverse/2]).
126 :- use_module
(library
(ordsets
)).
128 :- use_module
(hprolog
).
129 :- use_module
(pairlist
).
132 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
136 chr_translate
(Declarations
,NewDeclarations
) :-
138 partition_clauses
(Declarations
,Decls
,Rules
,OtherClauses
,Mod
),
141 NewDeclarations
= OtherClauses
143 check_rules
(Rules
,Decls
),
144 unique_analyse_optimise
(Rules
,1,[],NRules
),
145 generate_attach_a_constraint_all
(Decls
,Mod
,AttachAConstraintClauses
),
146 generate_detach_a_constraint_all
(Decls
,Mod
,DettachAConstraintClauses
),
147 generate_attach_increment
(Decls
,Mod
,AttachIncrementClauses
),
148 generate_attr_unify_hook
(Decls
,Mod
,AttrUnifyHookClauses
),
149 constraints_code
(Decls
,NRules
,Mod
,ConstraintClauses
),
150 append
([ OtherClauses
,
151 AttachAConstraintClauses
,
152 DettachAConstraintClauses
,
153 AttachIncrementClauses
,
154 AttrUnifyHookClauses
,
162 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
164 %% Partitioning of clauses into constraint declarations
, chr rules
and other
167 partition_clauses
([],[],[],[],_
).
168 partition_clauses
([C
|Cs
],Ds
,Rs
,OCs
,Mod
) :-
173 ; is_declaration
(C
,D
) ->
177 ; is_module_declaration
(C
,Mod
) ->
182 format
('CHR compiler WARNING: ~w.\n',[C
]),
183 format
(' `--> SICStus compatibility: ignoring handler/1 declaration.\n',[]),
188 format
('CHR compiler WARNING: ~w.\n',[C
]),
189 format
(' `--> SICStus compatibility: ignoring rules/1 declaration.\n',[]),
193 ; C
= (:- chr_option
(OptionName
,OptionValue
)) ->
194 handle_option
(OptionName
,OptionValue
),
202 partition_clauses
(Cs
,RDs
,RRs
,ROCs
,Mod
).
204 is_declaration
(D
, Constraints
) :- %% constraint declaration
206 ( Decl
=.. [chr_constraint
,Cs
] ; Decl
=.. [chr_constraint
,Cs
]),
207 conj2list
(Cs
,Constraints
).
225 %% list
(constraint
), :: constraints to be removed
226 %% list
(constraint
), :: surviving constraints
231 rule
(RI
,R
) :- %% name @ rule
232 RI
= (Name @ RI2
), !,
233 rule
(RI2
,yes
(Name
),R
).
238 RI
= (RI2 pragma P
), !, %% pragmas
241 R
= pragma
(R1
,IDs
,Ps
,Name
).
244 R
= pragma
(R1
,IDs
,[],Name
).
246 is_rule
(RI
,R
,IDs
) :- %% propagation rule
249 get_ids
(Head2i
,IDs2
,Head2
),
252 R
= rule
([],Head2
,G
,RB
)
254 R
= rule
([],Head2
,true
,B
)
256 is_rule
(RI
,R
,IDs
) :- %% simplification
/simpagation rule
265 conj2list
(H1
,Head2i
),
266 conj2list
(H2
,Head1i
),
267 get_ids
(Head2i
,IDs2
,Head2
,0,N
),
268 get_ids
(Head1i
,IDs1
,Head1
,N
,_
),
270 ; conj2list
(H
,Head1i
),
272 get_ids
(Head1i
,IDs1
,Head1
),
275 R
= rule
(Head1
,Head2
,Guard
,Body
).
277 get_ids
(Cs
,IDs
,NCs
) :-
278 get_ids
(Cs
,IDs
,NCs
,0,_
).
280 get_ids
([],[],[],N
,N
).
281 get_ids
([C
|Cs
],[N
|IDs
],[NC
|NCs
],N
,NN
) :-
288 get_ids
(Cs
,IDs
,NCs
, M
,NN
).
290 is_module_declaration
((:- module
(Mod
)),Mod
).
291 is_module_declaration
((:- module
(Mod
,_
)),Mod
).
293 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
295 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
296 %% Some input verification
:
297 %% - all constraints
in heads are declared constraints
299 check_rules
(Rules
,Decls
) :-
300 check_rules
(Rules
,Decls
,1).
303 check_rules
([PragmaRule
|Rest
],Decls
,N
) :-
304 check_rule
(PragmaRule
,Decls
,N
),
306 check_rules
(Rest
,Decls
,N1
).
308 check_rule
(PragmaRule
,Decls
,N
) :-
309 PragmaRule
= pragma
(Rule
,_IDs
,Pragmas
,_Name
),
310 Rule
= rule
(H1
,H2
,_
,_
),
311 append
(H1
,H2
,HeadConstraints
),
312 check_head_constraints
(HeadConstraints
,Decls
,PragmaRule
,N
),
313 check_pragmas
(Pragmas
,PragmaRule
,N
).
315 check_head_constraints
([],_
,_
,_
).
316 check_head_constraints
([Constr
|Rest
],Decls
,PragmaRule
,N
) :-
318 ( member
(F
/A
,Decls
) ->
319 check_head_constraints
(Rest
,Decls
,PragmaRule
,N
)
321 format
('CHR compiler ERROR: Undeclared constraint ~w in head of ~@.\n',
322 [F
/A
,format_rule
(PragmaRule
,N
)]),
323 format
(' `--> Constraint should be on of ~w.\n',[Decls
]),
327 check_pragmas
([],_
,_
).
328 check_pragmas
([Pragma
|Pragmas
],PragmaRule
,N
) :-
329 check_pragma
(Pragma
,PragmaRule
,N
),
330 check_pragmas
(Pragmas
,PragmaRule
,N
).
332 check_pragma
(Pragma
,PragmaRule
,N
) :-
334 format
('CHR compiler ERROR: invalid pragma ~w in ~@.\n',
335 [Pragma
,format_rule
(PragmaRule
,N
)]),
336 format
(' `--> Pragma should not be a variable!\n',[]),
339 check_pragma
(passive
(ID
), PragmaRule
, N
) :-
341 PragmaRule
= pragma
(_
,ids
(IDs1
,IDs2
),_
,_
),
342 ( memberchk_eq
(ID
,IDs1
) ->
344 ; memberchk_eq
(ID
,IDs2
) ->
347 format
('CHR compiler ERROR: invalid identifier ~w in pragma passive in ~@.\n',
348 [ID
,format_rule
(PragmaRule
,N
)]),
352 check_pragma
(Pragma
, PragmaRule
, N
) :-
353 Pragma
= unique
(_
,_
),
355 format
('CHR compiler WARNING: undocumented pragma ~w in ~@.\n',[Pragma
,format_rule
(PragmaRule
,N
)]),
356 format
(' `--> Only use this pragma if you know what you are doing.\n',[]).
358 check_pragma
(Pragma
, PragmaRule
, N
) :-
359 Pragma
= already_in_heads
,
361 format
('CHR compiler WARNING: currently unsupported pragma ~w in ~@.\n',[Pragma
,format_rule
(PragmaRule
,N
)]),
362 format
(' `--> Pragma is ignored. Termination and correctness may be affected \n',[]).
364 check_pragma
(Pragma
, PragmaRule
, N
) :-
365 Pragma
= already_in_head
(_
),
367 format
('CHR compiler WARNING: currently unsupported pragma ~w in ~@.\n',[Pragma
,format_rule
(PragmaRule
,N
)]),
368 format
(' `--> Pragma is ignored. Termination and correctness may be affected \n',[]).
370 check_pragma
(Pragma
,PragmaRule
,N
) :-
371 format
('CHR compiler ERROR: invalid pragma ~w in ~@.\n',[Pragma
,format_rule
(PragmaRule
,N
)]),
372 format
(' `--> Pragma should be one of passive/1!\n',[]),
375 format_rule
(PragmaRule
,N
) :-
376 PragmaRule
= pragma
(_
,_
,_
,MaybeName
),
377 ( MaybeName
= yes
(Name
) ->
378 write('rule '), write(Name
)
380 write('rule number '), write(N
)
383 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
385 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
389 handle_option
(Var
,Value
) :-
391 format
('CHR compiler ERROR: ~w.\n',[option
(Var
,Value
)]),
392 format
(' `--> First argument should be an atom, not a variable.\n',[]),
395 handle_option
(Name
,Value
) :-
397 format
('CHR compiler ERROR: ~w.\n',[option
(Name
,Value
)]),
398 format
(' `--> Second argument should be a nonvariable.\n',[]),
401 handle_option
(Name
,Value
) :-
402 option_definition
(Name
,Value
,Flags
),
404 set_chr_pp_flags
(Flags
).
406 handle_option
(Name
,Value
) :-
407 \
+ option_definition
(Name
,_
,_
), !,
408 setof
(N
,_V
^ _F
^ (option_definition
(N
,_V
,_F
)),Ns
),
409 format
('CHR compiler ERROR: ~w.\n',[option
(Name
,Value
)]),
410 format
(' `--> Invalid option name ~w: should be one of ~w.\n',[Name
,Ns
]),
413 handle_option
(Name
,Value
) :-
414 findall
(V
,option_definition
(Name
,V
,_
),Vs
),
415 format
('CHR compiler ERROR: ~w.\n',[option
(Name
,Value
)]),
416 format
(' `--> Invalid value ~w: should be one of ~w.\n',[Value
,Vs
]),
419 option_definition
(optimize
,full
,Flags
) :-
420 Flags
= [ unique_analyse_optimise
- on
,
421 check_unnecessary_active
- full
,
423 set_semantics_rule
- on
,
424 guard_via_reschedule
- on
427 option_definition
(optimize
,sicstus
,Flags
) :-
428 Flags
= [ unique_analyse_optimise
- off
,
429 check_unnecessary_active
- simplification
,
431 set_semantics_rule
- off
,
432 guard_via_reschedule
- off
435 option_definition
(optimize
,off
,Flags
) :-
436 Flags
= [ unique_analyse_optimise
- off
,
437 check_unnecessary_active
- off
,
439 set_semantics_rule
- off
,
440 guard_via_reschedule
- off
443 option_definition
(check_guard_bindings
,on
,Flags
) :-
444 Flags
= [ guard_locks
- on
].
446 option_definition
(check_guard_bindings
,off
,Flags
) :-
447 Flags
= [ guard_locks
- off
].
450 chr_pp_flag_definition
(Name
,[DefaultValue
|_
]),
451 set_chr_pp_flag
(Name
,DefaultValue
),
455 set_chr_pp_flags
([]).
456 set_chr_pp_flags
([Name
-Value
|Flags
]) :-
457 set_chr_pp_flag
(Name
,Value
),
458 set_chr_pp_flags
(Flags
).
460 set_chr_pp_flag
(Name
,Value
) :-
461 atom_concat
('$chr_pp_',Name
,GlobalVar
),
462 nb_setval
(GlobalVar
,Value
).
464 chr_pp_flag_definition
(unique_analyse_optimise
,[on
,off
]).
465 chr_pp_flag_definition
(check_unnecessary_active
,[full
,simplification
,off
]).
466 chr_pp_flag_definition
(reorder_heads
,[on
,off
]).
467 chr_pp_flag_definition
(set_semantics_rule
,[on
,off
]).
468 chr_pp_flag_definition
(guard_via_reschedule
,[on
,off
]).
469 chr_pp_flag_definition
(guard_locks
,[on
,off
]).
471 chr_pp_flag
(Name
,Value
) :-
472 atom_concat
('$chr_pp_',Name
,GlobalVar
),
473 nb_getval
(GlobalVar
,V
),
475 chr_pp_flag_definition
(Name
,[Value
|_
])
479 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
481 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
483 %% Generated predicates
484 %% attach_
$CONSTRAINT
486 %% detach_
$CONSTRAINT
489 %% attach_
$CONSTRAINT
490 generate_attach_a_constraint_all
(Constraints
,Mod
,Clauses
) :-
491 length(Constraints
,Total
),
492 generate_attach_a_constraint_all
(Constraints
,1,Total
,Mod
,Clauses
).
494 generate_attach_a_constraint_all
([],_
,_
,_
,[]).
495 generate_attach_a_constraint_all
([Constraint
|Constraints
],Position
,Total
,Mod
,Clauses
) :-
496 generate_attach_a_constraint
(Total
,Position
,Constraint
,Mod
,Clauses1
),
497 NextPosition is Position
+ 1,
498 generate_attach_a_constraint_all
(Constraints
,NextPosition
,Total
,Mod
,Clauses2
),
499 append
(Clauses1
,Clauses2
,Clauses
).
501 generate_attach_a_constraint
(Total
,Position
,Constraint
,Mod
,[Clause1
,Clause2
]) :-
502 generate_attach_a_constraint_empty_list
(Constraint
,Clause1
),
504 generate_attach_a_constraint_1_1
(Constraint
,Mod
,Clause2
)
506 generate_attach_a_constraint_t_p
(Total
,Position
,Constraint
,Mod
,Clause2
)
509 generate_attach_a_constraint_empty_list
(CFct
/ CAty
,Clause
) :-
510 atom_concat_list
(['attach_',CFct
, (/) ,CAty
],Fct
),
512 Head
=.. [Fct
| Args
],
513 Clause
= ( Head
:- true
).
515 generate_attach_a_constraint_1_1
(CFct
/ CAty
,Mod
,Clause
) :-
516 atom_concat_list
(['attach_',CFct
, (/) ,CAty
],Fct
),
517 Args
= [[Var
|Vars
],Susp
],
518 Head
=.. [Fct
| Args
],
519 RecursiveCall
=.. [Fct
,Vars
,Susp
],
522 ( get_attr
(Var
, Mod
, Susps
) ->
523 NewSusps
=[Susp
|Susps
],
524 put_attr
(Var
, Mod
, NewSusps
)
526 put_attr
(Var
, Mod
, [Susp
])
530 Clause
= (Head
:- Body
).
532 generate_attach_a_constraint_t_p
(Total
,Position
,CFct
/ CAty
,Mod
,Clause
) :-
533 atom_concat_list
(['attach_',CFct
, (/) ,CAty
],Fct
),
534 Args
= [[Var
|Vars
],Susp
],
535 Head
=.. [Fct
| Args
],
536 RecursiveCall
=.. [Fct
,Vars
,Susp
],
537 or_pattern
(Position
,Pattern
),
538 make_attr
(Total
,Mask
,SuspsList
,Attr
),
539 nth1
(Position
,SuspsList
,Susps
),
540 substitute_eq
(Susps
,SuspsList
,[Susp
|Susps
],SuspsList1
),
541 make_attr
(Total
,Mask
,SuspsList1
,NewAttr1
),
542 substitute_eq
(Susps
,SuspsList
,[Susp
],SuspsList2
),
543 make_attr
(Total
,NewMask
,SuspsList2
,NewAttr2
),
544 copy_term_nat
(SuspsList
,SuspsList3
),
545 nth1
(Position
,SuspsList3
,[Susp
]),
546 chr_delete
(SuspsList3
,[Susp
],RestSuspsList
),
547 set_elems
(RestSuspsList
,[]),
548 make_attr
(Total
,Pattern
,SuspsList3
,NewAttr3
),
551 ( get_attr
(Var
,Mod
,TAttr
) ->
553 ( Mask
/\ Pattern
=:= Pattern
->
554 put_attr
(Var
, Mod
, NewAttr1
)
556 NewMask is Mask \
/ Pattern
,
557 put_attr
(Var
, Mod
, NewAttr2
)
560 put_attr
(Var
,Mod
,NewAttr3
)
564 Clause
= (Head
:- Body
).
566 %% detach_
$CONSTRAINT
567 generate_detach_a_constraint_all
(Constraints
,Mod
,Clauses
) :-
568 length(Constraints
,Total
),
569 generate_detach_a_constraint_all
(Constraints
,1,Total
,Mod
,Clauses
).
571 generate_detach_a_constraint_all
([],_
,_
,_
,[]).
572 generate_detach_a_constraint_all
([Constraint
|Constraints
],Position
,Total
,Mod
,Clauses
) :-
573 generate_detach_a_constraint
(Total
,Position
,Constraint
,Mod
,Clauses1
),
574 NextPosition is Position
+ 1,
575 generate_detach_a_constraint_all
(Constraints
,NextPosition
,Total
,Mod
,Clauses2
),
576 append
(Clauses1
,Clauses2
,Clauses
).
578 generate_detach_a_constraint
(Total
,Position
,Constraint
,Mod
,[Clause1
,Clause2
]) :-
579 generate_detach_a_constraint_empty_list
(Constraint
,Clause1
),
581 generate_detach_a_constraint_1_1
(Constraint
,Mod
,Clause2
)
583 generate_detach_a_constraint_t_p
(Total
,Position
,Constraint
,Mod
,Clause2
)
586 generate_detach_a_constraint_empty_list
(CFct
/ CAty
,Clause
) :-
587 atom_concat_list
(['detach_',CFct
, (/) ,CAty
],Fct
),
589 Head
=.. [Fct
| Args
],
590 Clause
= ( Head
:- true
).
592 generate_detach_a_constraint_1_1
(CFct
/ CAty
,Mod
,Clause
) :-
593 atom_concat_list
(['detach_',CFct
, (/) ,CAty
],Fct
),
594 Args
= [[Var
|Vars
],Susp
],
595 Head
=.. [Fct
| Args
],
596 RecursiveCall
=.. [Fct
,Vars
,Susp
],
599 ( get_attr
(Var
,Mod
,Susps
) ->
600 'chr sbag_del_element'(Susps
,Susp
,NewSusps
),
604 put_attr
(Var
,Mod
,NewSusps
)
611 Clause
= (Head
:- Body
).
613 generate_detach_a_constraint_t_p
(Total
,Position
,CFct
/ CAty
,Mod
,Clause
) :-
614 atom_concat_list
(['detach_',CFct
, (/) ,CAty
],Fct
),
615 Args
= [[Var
|Vars
],Susp
],
616 Head
=.. [Fct
| Args
],
617 RecursiveCall
=.. [Fct
,Vars
,Susp
],
618 or_pattern
(Position
,Pattern
),
619 and_pattern
(Position
,DelPattern
),
620 make_attr
(Total
,Mask
,SuspsList
,Attr
),
621 nth1
(Position
,SuspsList
,Susps
),
622 substitute_eq
(Susps
,SuspsList
,[],SuspsList1
),
623 make_attr
(Total
,NewMask
,SuspsList1
,Attr1
),
624 substitute_eq
(Susps
,SuspsList
,NewSusps
,SuspsList2
),
625 make_attr
(Total
,Mask
,SuspsList2
,Attr2
),
628 ( get_attr
(Var
,Mod
,TAttr
) ->
630 ( Mask
/\ Pattern
=:= Pattern
->
631 'chr sbag_del_element'(Susps
,Susp
,NewSusps
),
633 NewMask is Mask
/\ DelPattern
,
637 put_attr
(Var
,Mod
,Attr1
)
640 put_attr
(Var
,Mod
,Attr2
)
650 Clause
= (Head
:- Body
).
652 %% detach_
$CONSTRAINT
653 generate_attach_increment
(Constraints
,Mod
,[Clause1
,Clause2
]) :-
654 generate_attach_increment_empty
(Clause1
),
655 length(Constraints
,N
),
657 generate_attach_increment_one
(Mod
,Clause2
)
659 generate_attach_increment_many
(N
,Mod
,Clause2
)
662 generate_attach_increment_empty
((attach_increment
([],_
) :- true
)).
664 generate_attach_increment_one
(Mod
,Clause
) :-
665 Head
= attach_increment
([Var
|Vars
],Susps
),
668 'chr not_locked'(Var
),
669 ( get_attr
(Var
,Mod
,VarSusps
) ->
670 sort(VarSusps
,SortedVarSusps
),
671 merge
(Susps
,SortedVarSusps
,MergedSusps
),
672 put_attr
(Var
,Mod
,MergedSusps
)
674 put_attr
(Var
,Mod
,Susps
)
676 attach_increment
(Vars
,Susps
)
678 Clause
= (Head
:- Body
).
680 generate_attach_increment_many
(N
,Mod
,Clause
) :-
681 make_attr
(N
,Mask
,SuspsList
,Attr
),
682 make_attr
(N
,OtherMask
,OtherSuspsList
,OtherAttr
),
683 Head
= attach_increment
([Var
|Vars
],Attr
),
684 bagof
(G
,X
^ Y
^ SY
^ M
^ (member2
(SuspsList
,OtherSuspsList
,X
-Y
),G
= (sort(Y
,SY
),'chr merge_attributes'(X
,SY
,M
))),Gs
),
685 list2conj
(Gs
,SortGoals
),
686 bagof
(MS
,A
^ B
^ C
^ member
((A
,'chr merge_attributes'(B
,C
,MS
)),Gs
), MergedSuspsList
),
687 make_attr
(N
,MergedMask
,MergedSuspsList
,NewAttr
),
690 'chr not_locked'(Var
),
691 ( get_attr
(Var
,Mod
,TOtherAttr
) ->
692 TOtherAttr
= OtherAttr
,
694 MergedMask is Mask \
/ OtherMask
,
695 put_attr
(Var
,Mod
,NewAttr
)
697 put_attr
(Var
,Mod
,Attr
)
699 attach_increment
(Vars
,Attr
)
701 Clause
= (Head
:- Body
).
704 generate_attr_unify_hook
(Constraints
,Mod
,[Clause
]) :-
705 length(Constraints
,N
),
707 generate_attr_unify_hook_one
(Mod
,Clause
)
709 generate_attr_unify_hook_many
(N
,Mod
,Clause
)
712 generate_attr_unify_hook_one
(Mod
,Clause
) :-
713 Head
= attr_unify_hook
(Susps
,Other
),
716 sort(Susps
, SortedSusps
),
718 ( get_attr
(Other
,Mod
,OtherSusps
) ->
723 sort(OtherSusps
,SortedOtherSusps
),
724 'chr merge_attributes'(SortedSusps
,SortedOtherSusps
,NewSusps
),
725 put_attr
(Other
,Mod
,NewSusps
),
726 'chr run_suspensions'(NewSusps
)
729 term_variables
(Other
,OtherVars
),
730 attach_increment
(OtherVars
, SortedSusps
)
734 'chr run_suspensions'(Susps
)
737 Clause
= (Head
:- Body
).
739 generate_attr_unify_hook_many
(N
,Mod
,Clause
) :-
740 make_attr
(N
,Mask
,SuspsList
,Attr
),
741 make_attr
(N
,OtherMask
,OtherSuspsList
,OtherAttr
),
742 bagof
(Sort
,A
^ B
^ ( member
(A
,SuspsList
) , Sort
= sort(A
,B
) ) , SortGoalList
),
743 list2conj
(SortGoalList
,SortGoals
),
744 bagof
(B
, A
^ member
(sort(A
,B
),SortGoalList
), SortedSuspsList
),
745 bagof
(C
, D
^ E
^ F
^ G
^ (member2
(SortedSuspsList
,OtherSuspsList
,D
-E
),
747 'chr merge_attributes'(D
,F
,G
)) ),
749 bagof
(G
, D
^ F
^ H
^ member
((H
,'chr merge_attributes'(D
,F
,G
)),SortMergeGoalList
) , MergedSuspsList
),
750 list2conj
(SortMergeGoalList
,SortMergeGoals
),
751 make_attr
(N
,MergedMask
,MergedSuspsList
,MergedAttr
),
752 make_attr
(N
,Mask
,SortedSuspsList
,SortedAttr
),
753 Head
= attr_unify_hook
(Attr
,Other
),
758 ( get_attr
(Other
,Mod
,TOtherAttr
) ->
759 TOtherAttr
= OtherAttr
,
761 MergedMask is Mask \
/ OtherMask
,
762 put_attr
(Other
,Mod
,MergedAttr
),
763 'chr run_suspensions_loop'(MergedSuspsList
)
765 put_attr
(Other
,Mod
,SortedAttr
),
766 'chr run_suspensions_loop'(SortedSuspsList
)
770 term_variables
(Other
,OtherVars
),
771 attach_increment
(OtherVars
,SortedAttr
)
775 'chr run_suspensions_loop'(SortedSuspsList
)
778 Clause
= (Head
:- Body
).
780 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
782 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
783 %% ____ _ ____ _ _ _ _
784 %% | _ \ _ _
| | ___
/ ___
|___ _ __ ___ _ __
(_
) | __ _
| |_
(_
) ___ _ __
785 %% | |_
) | | | | |/ _ \ | | / _ \
| '_ ` _ \| '_ \
| | |/ _` | __| |/ _ \
| '_ \
786 %% | _ <| |_| | | __/ | |__| (_) | | | | | | |_) | | | (_| | |_| | (_) | | | |
787 %% |_| \_\\__,_|_|\___| \____\___/|_| |_| |_| .__/|_|_|\__,_|\__|_|\___/|_| |_|
790 constraints_code(Constraints,Rules,Mod,Clauses) :-
791 constraints_code(Constraints,Rules,Mod,L,[]),
792 clean_clauses(L,Clauses).
794 %% Generate code for all the CHR constraints
795 constraints_code(Constraints,Rules,Mod,L,T) :-
796 length(Constraints,N),
797 constraints_code(Constraints,1,N,Constraints,Rules,Mod,L,T).
799 constraints_code([],_,_,_,_,_,L,L).
800 constraints_code([Constr|Constrs],I,N,Constraints,Rules,Mod,L,T) :-
801 constraint_code(Constr,I,N,Constraints,Rules,Mod,L,T1),
803 constraints_code(Constrs,J,N,Constraints,Rules,Mod,T1,T).
805 %% Generate code for a single CHR constraint
806 constraint_code(Constraint, I, N, Constraints, Rules, Mod, L, T) :-
807 constraint_prelude(Constraint,Mod,Clause),
810 rules_code(Rules,1,Constraint,I,N,Constraints,Mod,Id1,Id2,L1,L2),
811 gen_cond_attach_clause(Mod,Constraint,I,N,Constraints,Id2,L2,T).
813 %% Generate prelude predicate for a constraint.
814 %% f(...) :- f/a_0(...,Susp).
815 constraint_prelude(F/A, _Mod, Clause) :-
816 vars_susp(A,Vars,_Susp,VarsSusp),
817 Head =.. [ F | Vars],
818 build_head(F,A,[0],VarsSusp,Delegate),
819 Clause = ( Head :- Delegate ).
821 gen_cond_attach_clause(Mod,F/A,_I,_N,_Constraints,Id,L,T) :-
823 gen_cond_attach_goal(Mod,F/A,Body,AllArgs)
824 ; vars_susp(A,_Args,Susp,AllArgs),
825 gen_uncond_attach_goal(F/A,Susp,Mod,Body,_)
827 build_head(F,A,Id,AllArgs,Head),
828 Clause = ( Head :- Body ),
831 gen_cond_attach_goal(Mod,F/A,Goal,AllArgs) :-
832 vars_susp(A,Args,Susp,AllArgs),
833 build_head(F,A,[0],AllArgs,Closure),
834 atom_concat_list(['attach_
',F, (/) ,A],AttachF),
835 Attach =.. [AttachF,Vars,Susp],
839 'chr insert_constraint_internal
'(Vars,Susp,Mod:Closure,F,Args)
841 'chr activate_constraint
'(Vars,Susp,_)
846 gen_uncond_attach_goal(F/A,Susp,_Mod,AttachGoal,Generation) :-
847 atom_concat_list(['attach_
',F, (/) ,A],AttachF),
848 Attach =.. [AttachF,Vars,Susp],
851 'chr activate_constraint
'(Vars, Susp, Generation),
855 %% Generate all the code for a constraint based on all CHR rules
856 rules_code([],_,_,_,_,_,_,Id,Id,L,L).
857 rules_code([R |Rs],RuleNb,FA,I,N,Constraints,Mod,Id1,Id3,L,T) :-
858 rule_code(R,RuleNb,FA,I,N,Constraints,Mod,Id1,Id2,L,T1),
859 NextRuleNb is RuleNb + 1,
860 rules_code(Rs,NextRuleNb,FA,I,N,Constraints,Mod,Id2,Id3,T1,T).
862 %% Generate code for a constraint based on a single CHR rule
863 rule_code(PragmaRule,RuleNb,FA,I,N,Constraints,Mod,Id1,Id2,L,T) :-
864 PragmaRule = pragma(Rule,HeadIDs,_Pragmas,_Name),
865 HeadIDs = ids(Head1IDs,Head2IDs),
866 Rule = rule(Head1,Head2,_,_),
867 heads1_code(Head1,[],Head1IDs,[],PragmaRule,FA,I,N,Constraints,Mod,Id1,L,L1),
868 heads2_code(Head2,[],Head2IDs,[],PragmaRule,RuleNb,FA,I,N,Constraints,Mod,Id1,Id2,L1,T).
870 %% Generate code based on all the removed heads of a CHR rule
871 heads1_code([],_,_,_,_,_,_,_,_,_,_,L,L).
872 heads1_code([Head|Heads],RestHeads,[HeadID|HeadIDs],RestIDs,PragmaRule,F/A,I,N,Constraints,Mod,Id,L,T) :-
873 PragmaRule = pragma(Rule,_,Pragmas,_Name),
875 \+ check_unnecessary_active(Head,RestHeads,Rule),
876 \+ memberchk_eq(passive(HeadID),Pragmas) ->
877 append(Heads,RestHeads,OtherHeads),
878 append(HeadIDs,RestIDs,OtherIDs),
879 head1_code(Head,OtherHeads,OtherIDs,PragmaRule,F/A,I,N,Constraints,Mod,Id,L,L1)
883 heads1_code(Heads,[Head|RestHeads],HeadIDs,[HeadID|RestIDs],PragmaRule,F/A,I,N,Constraints,Mod,Id,L1,T).
885 %% Generate code based on one removed head of a CHR rule
886 head1_code(Head,OtherHeads,OtherIDs,PragmaRule,FA,I,N,Constraints,Mod,Id,L,T) :-
887 PragmaRule = pragma(Rule,_,_,_Name),
888 Rule = rule(_,Head2,_,_),
890 reorder_heads(Head,OtherHeads,OtherIDs,NOtherHeads,NOtherIDs),
891 simplification_code(Head,NOtherHeads,NOtherIDs,PragmaRule,FA,I,N,Constraints,Mod,Id,L,T)
893 simpagation_head1_code(Head,OtherHeads,OtherIDs,PragmaRule,FA,I,N,Constraints,Mod,Id,L,T)
896 %% Generate code based on all the persistent heads of a CHR rule
897 heads2_code([],_,_,_,_,_,_,_,_,_,_,Id,Id,L,L).
898 heads2_code([Head|Heads],RestHeads,[HeadID|HeadIDs],RestIDs,PragmaRule,RuleNb,F/A,I,N,Constraints,Mod,Id1,Id3,L,T) :-
899 PragmaRule = pragma(Rule,_,Pragmas,_Name),
901 \+ check_unnecessary_active(Head,RestHeads,Rule),
902 \+ memberchk_eq(passive(HeadID),Pragmas),
903 \+ set_semantics_rule(PragmaRule) ->
904 append(Heads,RestHeads,OtherHeads),
905 append(HeadIDs,RestIDs,OtherIDs),
906 length(Heads,RestHeadNb),
907 head2_code(Head,OtherHeads,OtherIDs,PragmaRule,RuleNb,RestHeadNb,F/A,I,N,Constraints,Mod,Id1,L,L0),
909 gen_alloc_inc_clause(F/A,Mod,Id1,L0,L1)
914 heads2_code(Heads,[Head|RestHeads],HeadIDs,[HeadID|RestIDs],PragmaRule,RuleNb,F/A,I,N,Constraints,Mod,Id2,Id3,L1,T).
916 %% Generate code based on one persistent head of a CHR rule
917 head2_code(Head,OtherHeads,OtherIDs,PragmaRule,RuleNb,RestHeadNb,FA,I,N,Constraints,Mod,Id,L,T) :-
918 PragmaRule = pragma(Rule,_,_,_Name),
919 Rule = rule(Head1,_,_,_),
921 reorder_heads(Head,OtherHeads,NOtherHeads),
922 propagation_code(Head,NOtherHeads,Rule,RuleNb,RestHeadNb,FA,N,Constraints,Mod,Id,L,T)
924 simpagation_head2_code(Head,OtherHeads,OtherIDs,PragmaRule,FA,I,N,Constraints,Mod,Id,L,T)
927 gen_alloc_inc_clause(F/A,Mod,Id,L,T) :-
928 vars_susp(A,Vars,Susp,VarsSusp),
929 build_head(F,A,Id,VarsSusp,Head),
931 build_head(F,A,IncId,VarsSusp,CallHead),
933 gen_cond_allocation(Vars,Susp,F/A,VarsSusp,Mod,ConditionalAlloc)
935 ConditionalAlloc = true
945 gen_cond_allocation(Vars,Susp,F/A,VarsSusp,Mod,ConstraintAllocationGoal) :-
946 build_head(F,A,[0],VarsSusp,Term),
947 ConstraintAllocationGoal =
949 'chr allocate_constraint
'(Mod : Term, Susp, F, Vars)
954 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
957 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
959 guard_via_reschedule(Retrievals,GuardList,Prelude,Goal) :-
960 ( chr_pp_flag(guard_via_reschedule,on) ->
961 guard_via_reschedule_main(Retrievals,GuardList,Prelude,Goal)
963 append(Retrievals,GuardList,GoalList),
964 list2conj(GoalList,Goal)
967 guard_via_reschedule_main(Retrievals,GuardList,Prelude,Goal) :-
968 initialize_unit_dictionary(Prelude,Dict),
969 build_units(Retrievals,GuardList,Dict,Units),
970 dependency_reorder(Units,NUnits),
971 units2goal(NUnits,Goal).
974 units2goal([unit(_,Goal,_,_)|Units],(Goal,Goals)) :-
975 units2goal(Units,Goals).
977 dependency_reorder(Units,NUnits) :-
978 dependency_reorder(Units,[],NUnits).
980 dependency_reorder([],Acc,Result) :-
983 dependency_reorder([Unit|Units],Acc,Result) :-
984 Unit = unit(_GID,_Goal,Type,GIDs),
988 dependency_insert(Acc,Unit,GIDs,NAcc)
990 dependency_reorder(Units,NAcc,Result).
992 dependency_insert([],Unit,_,[Unit]).
993 dependency_insert([X|Xs],Unit,GIDs,L) :-
995 ( memberchk(GID,GIDs) ->
999 dependency_insert(Xs,Unit,GIDs,T)
1002 build_units(Retrievals,Guard,InitialDict,Units) :-
1003 build_retrieval_units(Retrievals,1,N,InitialDict,Dict,Units,Tail),
1004 build_guard_units(Guard,N,Dict,Tail).
1006 build_retrieval_units([],N,N,Dict,Dict,L,L).
1007 build_retrieval_units([U|Us],N,M,Dict,NDict,L,T) :-
1008 term_variables(U,Vs),
1009 update_unit_dictionary(Vs,N,Dict,Dict1,[],GIDs),
1010 L = [unit(N,U,movable,GIDs)|L1],
1012 build_retrieval_units2(Us,N1,M,Dict1,NDict,L1,T).
1014 build_retrieval_units2([],N,N,Dict,Dict,L,L).
1015 build_retrieval_units2([U|Us],N,M,Dict,NDict,L,T) :-
1016 term_variables(U,Vs),
1017 update_unit_dictionary(Vs,N,Dict,Dict1,[],GIDs),
1018 L = [unit(N,U,fixed,GIDs)|L1],
1020 build_retrieval_units(Us,N1,M,Dict1,NDict,L1,T).
1022 initialize_unit_dictionary(Term,Dict) :-
1023 term_variables(Term,Vars),
1024 pair_all_with(Vars,0,Dict).
1026 update_unit_dictionary([],_,Dict,Dict,GIDs,GIDs).
1027 update_unit_dictionary([V|Vs],This,Dict,NDict,GIDs,NGIDs) :-
1028 ( lookup_eq(Dict,V,GID) ->
1029 ( (GID == This ; memberchk(GID,GIDs) ) ->
1036 Dict1 = [V - This|Dict],
1039 update_unit_dictionary(Vs,This,Dict1,NDict,GIDs1,NGIDs).
1041 build_guard_units(Guard,N,Dict,Units) :-
1043 Units = [unit(N,Goal,fixed,[])]
1044 ; Guard = [Goal|Goals] ->
1045 term_variables(Goal,Vs),
1046 update_unit_dictionary2(Vs,N,Dict,NDict,[],GIDs),
1047 Units = [unit(N,Goal,movable,GIDs)|RUnits],
1049 build_guard_units(Goals,N1,NDict,RUnits)
1052 update_unit_dictionary2([],_,Dict,Dict,GIDs,GIDs).
1053 update_unit_dictionary2([V|Vs],This,Dict,NDict,GIDs,NGIDs) :-
1054 ( lookup_eq(Dict,V,GID) ->
1055 ( (GID == This ; memberchk(GID,GIDs) ) ->
1060 Dict1 = [V - This|Dict]
1062 Dict1 = [V - This|Dict],
1065 update_unit_dictionary2(Vs,This,Dict1,NDict,GIDs1,NGIDs).
1067 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1069 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1071 %% / ___| ___| |_ / ___| ___ _ __ ___ __ _ _ __ | |_(_) ___ ___ _
1072 %% \___ \ / _ \ __| \___ \ / _ \ '_
` _ \ / _` | '_ \| __| |/ __/ __(_)
1073 %% ___) | __/ |_ ___) | __/ | | | | | (_| | | | | |_| | (__\__ \_
1074 %% |____/ \___|\__| |____/ \___|_| |_| |_|\__,_|_| |_|\__|_|\___|___(_)
1077 %% | | | |_ __ (_) __ _ _ _ ___ |_ _|_ __ / _| ___ _ __ ___ _ __ ___ ___
1078 %% | | | | '_ \
| |/ _` | | | |/ _ \
| || '_ \| |_ / _ \ '__
/ _ \
'_ \ / __/ _ \
1079 %% | |_| | | | | | (_| | |_| | __/ | || | | | _| __/ | | __/ | | | (_| __/
1080 %% \___/|_| |_|_|\__, |\__,_|\___| |___|_| |_|_| \___|_| \___|_| |_|\___\___|
1082 unique_analyse_optimise(Rules,N,PatternList,NRules) :-
1083 ( chr_pp_flag(unique_analyse_optimise,on) ->
1084 unique_analyse_optimise_main(Rules,N,PatternList,NRules)
1089 unique_analyse_optimise_main([],_,_,[]).
1090 unique_analyse_optimise_main([PRule|PRules],N,PatternList,[NPRule|NPRules]) :-
1091 ( discover_unique_pattern(PRule,N,Pattern) ->
1092 NPatternList = [Pattern|PatternList]
1094 NPatternList = PatternList
1096 PRule = pragma(Rule,Ids,Pragmas,Name),
1097 Rule = rule(H1,H2,_,_),
1098 Ids = ids(Ids1,Ids2),
1099 apply_unique_patterns_to_constraints(H1,Ids1,NPatternList,MorePragmas1),
1100 apply_unique_patterns_to_constraints(H2,Ids2,NPatternList,MorePragmas2),
1101 append([MorePragmas1,MorePragmas2,Pragmas],NPragmas),
1102 NPRule = pragma(Rule,Ids,NPragmas,Name),
1104 unique_analyse_optimise_main(PRules,N1,NPatternList,NPRules).
1106 apply_unique_patterns_to_constraints([],_,_,[]).
1107 apply_unique_patterns_to_constraints([C|Cs],[Id|Ids],Patterns,Pragmas) :-
1108 ( member(Pattern,Patterns),
1109 apply_unique_pattern(C,Id,Pattern,Pragma) ->
1110 Pragmas = [Pragma | RPragmas]
1114 apply_unique_patterns_to_constraints(Cs,Ids,Patterns,RPragmas).
1116 apply_unique_pattern(Constraint,Id,Pattern,Pragma) :-
1117 Pattern = unique(PatternConstraint,PatternKey),
1118 subsumes(Constraint,PatternConstraint,Unifier),
1121 member(T,PatternKey),
1122 lookup_eq(Unifier,T,Term),
1123 term_variables(Term,Vs),
1131 Pragma = unique(Id,Vars).
1133 % subsumes(+Term1, +Term2, -Unifier)
1135 % If Term1 is a more general term than Term2 (e.g. has a larger
1136 % part instantiated), unify Unifier with a list Var-Value of
1137 % variables from Term2 and their corresponding values in Term1.
1139 subsumes(Term1,Term2,Unifier) :-
1141 subsumes_aux(Term1,Term2,S0,S),
1143 build_unifier(L,Unifier).
1145 subsumes_aux(Term1, Term2, S0, S) :-
1147 functor(Term2, F, N)
1148 -> compound(Term1), functor(Term1, F, N),
1149 subsumes_aux(N, Term1, Term2, S0, S)
1154 -> V == Term2, S = S0
1156 put_ds(Term1, S0, Term2, S)
1159 subsumes_aux(0, _, _, S, S) :- ! .
1160 subsumes_aux(N, T1, T2, S0, S) :-
1163 subsumes_aux(T1x, T2x, S0, S1),
1165 subsumes_aux(M, T1, T2, S1, S).
1167 build_unifier([],[]).
1168 build_unifier([X-V|R],[V - X | T]) :-
1171 discover_unique_pattern(PragmaRule,RuleNb,Pattern) :-
1172 PragmaRule = pragma(Rule,_,Pragmas,Name),
1173 ( Rule = rule([C1],[C2],Guard,Body) ->
1176 Rule = rule([C1,C2],[],Guard,Body)
1178 check_unique_constraints(C1,C2,Guard,Body,Pragmas,List),
1179 term_variables(C1,Vs),
1180 select_pragma_unique_variables(List,Vs,Key),
1181 Pattern0 = unique(C1,Key),
1182 copy_term_nat(Pattern0,Pattern),
1184 format('Found unique pattern
~w
in rule
~d
~@
\n',
1185 [Pattern,RuleNb,(Name=yes(N) -> write(": "),write(N) ; true)])
1190 select_pragma_unique_variables([],_,[]).
1191 select_pragma_unique_variables([X-Y|R],Vs,L) :-
1196 \+ memberchk_eq(X,Vs)
1198 \+ memberchk_eq(Y,Vs)
1202 select_pragma_unique_variables(R,Vs,T).
1204 check_unique_constraints(C1,C2,G,_Body,Pragmas,List) :-
1205 \+ member(passive(_),Pragmas),
1206 variable_replacement(C1-C2,C2-C1,List),
1207 copy_with_variable_replacement(G,OtherG,List),
1209 once(entails(NotG,OtherG)).
1213 negate(X =< Y, Y < X).
1214 negate(X > Y, Y >= X).
1215 negate(X >= Y, Y > X).
1216 negate(X < Y, Y =< X).
1217 negate(var(X),nonvar(X)).
1218 negate(nonvar(X),var(X)).
1220 entails(X,X1) :- X1 == X.
1222 entails(X > Y, X1 >= Y1) :- X1 == X, Y1 == Y.
1223 entails(X < Y, X1 =< Y1) :- X1 == X, Y1 == Y.
1224 entails(ground(X),var(X1)) :- X1 == X.
1226 check_unnecessary_active(Constraint,Previous,Rule) :-
1227 ( chr_pp_flag(check_unnecessary_active,full) ->
1228 check_unnecessary_active_main(Constraint,Previous,Rule)
1229 ; chr_pp_flag(check_unnecessary_active,simplification),
1230 Rule = rule(_,[],_,_) ->
1231 check_unnecessary_active_main(Constraint,Previous,Rule)
1236 check_unnecessary_active_main(Constraint,Previous,Rule) :-
1237 member(Other,Previous),
1238 variable_replacement(Other,Constraint,List),
1239 copy_with_variable_replacement(Rule,Rule2,List),
1240 identical_rules(Rule,Rule2), ! .
1242 set_semantics_rule(PragmaRule) :-
1243 ( chr_pp_flag(set_semantics_rule,on) ->
1244 set_semantics_rule_main(PragmaRule)
1249 set_semantics_rule_main(PragmaRule) :-
1250 PragmaRule = pragma(Rule,IDs,Pragmas,_),
1251 Rule = rule([C1],[C2],true,true),
1254 \+ memberchk_eq(passive(ID1),Pragmas).
1255 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1257 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1259 %% | _ \ _ _| | ___ | ____|__ _ _ _(_)_ ____ _| | ___ _ __ ___ ___
1260 %% | |_) | | | | |/ _ \ | _| / _` | | | | \ \ / / _` | |/ _ \ '_ \
/ __
/ _ \
1261 %% | _
<| |_
| | | __
/ | |__| (_| | |_| | |\ V / (_
| | | __
/ | | | (_| __/
1262 %% |_
| \_
\\__
,_
|_
|\___
| |_____\__
, |\__
,_
|_
| \_
/ \__
,_
|_
|\___
|_
| |_
|\___\___
|
1264 % have to check
for no duplicates
in value list
1266 % check wether two rules are identical
1268 identical_rules
(rule
(H11
,H21
,G1
,B1
),rule
(H12
,H22
,G2
,B2
)) :-
1270 identical_bodies
(B1
,B2
),
1271 permutation
(H11
,P1
),
1273 permutation
(H21
,P2
),
1276 identical_bodies
(B1
,B2
) :-
1288 % replace variables
in list
1290 copy_with_variable_replacement
(X
,Y
,L
) :-
1292 ( lookup_eq
(L
,X
,Y
) ->
1300 copy_with_variable_replacement_l
(XArgs
,YArgs
,L
)
1303 copy_with_variable_replacement_l
([],[],_
).
1304 copy_with_variable_replacement_l
([X
|Xs
],[Y
|Ys
],L
) :-
1305 copy_with_variable_replacement
(X
,Y
,L
),
1306 copy_with_variable_replacement_l
(Xs
,Ys
,L
).
1308 %% build variable replacement list
1310 variable_replacement
(X
,Y
,L
) :-
1311 variable_replacement
(X
,Y
,[],L
).
1313 variable_replacement
(X
,Y
,L1
,L2
) :-
1316 ( lookup_eq
(L1
,X
,Z
) ->
1324 variable_replacement_l
(XArgs
,YArgs
,L1
,L2
)
1327 variable_replacement_l
([],[],L
,L
).
1328 variable_replacement_l
([X
|Xs
],[Y
|Ys
],L1
,L3
) :-
1329 variable_replacement
(X
,Y
,L1
,L2
),
1330 variable_replacement_l
(Xs
,Ys
,L2
,L3
).
1331 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1333 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1334 %% ____ _ _ _ __ _ _ _
1335 %% / ___|(_)_ __ ___ _ __ | (_)/ _
(_
) ___ __ _
| |_
(_
) ___ _ __
1336 %% \___ \
| | '_ ` _ \| '_ \
| | | |_
| |/ __/ _
` | __| |/ _ \| '_ \
1337 %% ___) | | | | | | | |_) | | | _| | (_| (_| | |_| | (_) | | | |
1338 %% |____/|_|_| |_| |_| .__/|_|_|_| |_|\___\__,_|\__|_|\___/|_| |_|
1341 simplification_code(Head,RestHeads,RestIDs,PragmaRule,F/A,_I,N,Constraints,Mod,Id,L,T) :-
1342 PragmaRule = pragma(Rule,_,Pragmas,_),
1343 head_info(Head,A,_Vars,Susp,HeadVars,HeadPairs),
1344 build_head(F,A,Id,HeadVars,ClauseHead),
1345 head_arg_matches(HeadPairs,[],FirstMatching,VarDict1),
1347 ( RestHeads == [] ->
1352 rest_heads_retrieval_and_matching(RestHeads,RestIDs,Pragmas,Head,Mod,N,Constraints,GetRestHeads,Susps,VarDict1,VarDict)
1355 guard_body_copies2(Rule,VarDict,GuardCopyList,BodyCopy),
1356 guard_via_reschedule(GetRestHeads,GuardCopyList,ClauseHead-FirstMatching,RescheduledTest),
1358 gen_uncond_susps_detachments(Susps,RestHeads,SuspsDetachments),
1359 gen_cond_susp_detachment(Susp,F/A,SuspDetachment),
1361 Clause = ( ClauseHead :-
1371 head_arg_matches(Pairs,VarDict,Goal,NVarDict) :-
1372 head_arg_matches_(Pairs,VarDict,GoalList,NVarDict),
1373 list2conj(GoalList,Goal).
1375 head_arg_matches_([],VarDict,[],VarDict).
1376 head_arg_matches_([Arg-Var| Rest],VarDict,GoalList,NVarDict) :-
1378 ( lookup_eq(VarDict,Arg,OtherVar) ->
1379 GoalList = [Var == OtherVar | RestGoalList],
1381 ; VarDict1 = [Arg-Var | VarDict],
1382 GoalList = RestGoalList
1386 GoalList = [ Var == Arg | RestGoalList],
1391 functor(Term,Fct,N),
1393 GoalList =[ nonvar(Var), Var = Term | RestGoalList ],
1394 pairup(Args,Vars,NewPairs),
1395 append(NewPairs,Rest,Pairs),
1398 head_arg_matches_(Pairs,VarDict1,RestGoalList,NVarDict).
1400 rest_heads_retrieval_and_matching(Heads,IDs,Pragmas,ActiveHead,Mod,N,Constraints,GoalList,Susps,VarDict,NVarDict):-
1401 rest_heads_retrieval_and_matching(Heads,IDs,Pragmas,ActiveHead,Mod,N,Constraints,GoalList,Susps,VarDict,NVarDict,[],[],[]).
1403 rest_heads_retrieval_and_matching(Heads,IDs,Pragmas,ActiveHead,Mod,N,Constraints,GoalList,Susps,VarDict,NVarDict,PrevHs,PrevSusps,AttrDict) :-
1405 rest_heads_retrieval_and_matching_n(Heads,IDs,Pragmas,PrevHs,PrevSusps,ActiveHead,Mod,N,Constraints,GoalList,Susps,VarDict,NVarDict,AttrDict)
1412 rest_heads_retrieval_and_matching_n([],_,_,_,_,_,_,N,_,[],[],VarDict,VarDict,AttrDict) :-
1413 instantiate_pattern_goals(AttrDict,N).
1414 rest_heads_retrieval_and_matching_n([H|Hs],[ID|IDs],Pragmas,PrevHs,PrevSusps,ActiveHead,Mod,N,Constraints,[ViaGoal,Goal|Goals],[Susp|Susps],VarDict,NVarDict,AttrDict) :-
1415 passive_head_via(H,[ActiveHead|PrevHs],AttrDict,Constraints,Mod,VarDict,ViaGoal,Attr,NewAttrDict),
1417 head_info(H,Aty,Vars,_,_,Pairs),
1418 head_arg_matches(Pairs,VarDict,MatchingGoal,VarDict1),
1419 Suspension =.. [suspension,_,State,_,_,_,_|Vars],
1423 nth1(Pos,Constraints,Fct/Aty), !,
1424 make_attr(N,_Mask,SuspsList,Attr),
1425 nth1(Pos,SuspsList,VarSusps)
1427 different_from_other_susps(H,Susp,PrevHs,PrevSusps,DiffSuspGoals),
1428 create_get_mutable_ref(active,State,GetMutable),
1431 'chr sbag_member'(Susp,VarSusps),
1437 ( member(unique(ID,UniqueKeus),Pragmas),
1438 check_unique_keys(UniqueKeus,VarDict) ->
1439 Goal = (Goal1 -> true) % once(Goal1)
1443 rest_heads_retrieval_and_matching_n(Hs,IDs,Pragmas,[H|PrevHs],[Susp|PrevSusps],ActiveHead,Mod,N,Constraints,Goals,Susps,VarDict1,NVarDict,NewAttrDict).
1445 instantiate_pattern_goals([],_).
1446 instantiate_pattern_goals([_-attr(Attr,Bits,Goal)|Rest],N) :-
1450 make_attr(N,Mask,_,Attr),
1451 or_list(Bits,Pattern), !,
1452 Goal = (Mask /\ Pattern =:= Pattern)
1454 instantiate_pattern_goals(Rest,N).
1457 check_unique_keys([],_).
1458 check_unique_keys([V|Vs],Dict) :-
1459 lookup_eq(Dict,V,_),
1460 check_unique_keys(Vs,Dict).
1462 % Generates tests to ensure the found constraint differs from previously found constraints
1463 different_from_other_susps(Head,Susp,Heads,Susps,DiffSuspGoals) :-
1464 ( bagof(DiffSuspGoal, Pos ^ ( nth1(Pos,Heads,PreHead), \+ Head \= PreHead, nth1(Pos,Susps,PreSusp), DiffSuspGoal = (Susp \== PreSusp) ),DiffSuspGoalList) ->
1465 list2conj(DiffSuspGoalList,DiffSuspGoals)
1467 DiffSuspGoals = true
1470 passive_head_via(Head,PrevHeads,AttrDict,Constraints,Mod,VarDict,Goal,Attr,NewAttrDict) :-
1472 nth1(Pos,Constraints,F/A),!,
1473 common_variables(Head,PrevHeads,CommonVars),
1474 translate(CommonVars,VarDict,Vars),
1475 or_pattern(Pos,Bit),
1476 ( permutation(Vars,PermutedVars),
1477 lookup_eq(AttrDict,PermutedVars,attr(Attr,Positions,_)) ->
1478 member(Bit,Positions), !,
1479 NewAttrDict = AttrDict,
1482 Goal = (Goal1, PatternGoal),
1483 gen_get_mod_constraints(Mod,Vars,Goal1,Attr),
1484 NewAttrDict = [Vars - attr(Attr,[Bit|_],PatternGoal) | AttrDict]
1487 common_variables(T,Ts,Vs) :-
1488 term_variables(T,V1),
1489 term_variables(Ts,V2),
1490 intersect_eq(V1,V2,Vs).
1492 gen_get_mod_constraints(Mod,L,Goal,Susps) :-
1495 ( 'chr default_store'(Global),
1496 get_attr(Global,Mod,TSusps),
1501 VIA = 'chr via_1'(A,V)
1503 VIA = 'chr via_2'(A,B,V)
1504 ; VIA = 'chr via'(L,V)
1509 get_attr(V,Mod,TSusps),
1514 guard_body_copies(Rule,VarDict,GuardCopy,BodyCopy) :-
1515 guard_body_copies2(Rule,VarDict,GuardCopyList,BodyCopy),
1516 list2conj(GuardCopyList,GuardCopy).
1518 guard_body_copies2(Rule,VarDict,GuardCopyList,BodyCopy) :-
1519 Rule = rule(_,_,Guard,Body),
1520 conj2list(Guard,GuardList),
1521 split_off_simple_guard(GuardList,VarDict,GuardPrefix,RestGuardList),
1522 my_term_copy(GuardPrefix-RestGuardList,VarDict,VarDict2,GuardPrefixCopy-RestGuardListCopyCore),
1524 append(GuardPrefixCopy,[RestGuardCopy],GuardCopyList),
1525 term_variables(RestGuardList,GuardVars),
1526 term_variables(RestGuardListCopyCore,GuardCopyVars),
1527 ( chr_pp_flag(guard_locks,on),
1528 bagof(('chr lock'(Y)) - ('chr unlock'(Y)),
1529 X ^ (member(X,GuardVars), % X is a variable appearing in the original guard
1530 lookup_eq(VarDict,X,Y), % translate X into new variable
1531 memberchk_eq(Y,GuardCopyVars) % redundant check? or multiple entries for X possible?
1534 once(pairup(Locks,Unlocks,LocksUnlocks))
1539 list2conj(Locks,LockPhase),
1540 list2conj(Unlocks,UnlockPhase),
1541 list2conj(RestGuardListCopyCore,RestGuardCopyCore),
1542 RestGuardCopy = (LockPhase,(RestGuardCopyCore,UnlockPhase)),
1543 my_term_copy(Body,VarDict2,BodyCopy).
1546 split_off_simple_guard([],_,[],[]).
1547 split_off_simple_guard([G|Gs],VarDict,S,C) :-
1548 ( simple_guard(G,VarDict) ->
1550 split_off_simple_guard(Gs,VarDict,Ss,C)
1556 % simple guard: cheap and benign (does not bind variables)
1558 simple_guard(var(_), _).
1559 simple_guard(nonvar(_), _).
1560 simple_guard(ground(_), _).
1561 simple_guard(number(_), _).
1562 simple_guard(atom(_), _).
1563 simple_guard(integer(_), _).
1564 simple_guard(float(_), _).
1566 simple_guard(_ > _ , _).
1567 simple_guard(_ < _ , _).
1568 simple_guard(_ =< _, _).
1569 simple_guard(_ >= _, _).
1570 simple_guard(_ =:= _, _).
1571 simple_guard(_ == _, _).
1573 simple_guard(X is _, VarDict) :-
1574 \+ lookup_eq(VarDict,X,_).
1576 simple_guard((G1,G2),VarDict) :-
1577 simple_guard(G1,VarDict),
1578 simple_guard(G2,VarDict).
1580 simple_guard(\+ G, VarDict) :-
1581 simple_guard(G, VarDict).
1583 my_term_copy(X,Dict,Y) :-
1584 my_term_copy(X,Dict,_,Y).
1586 my_term_copy(X,Dict1,Dict2,Y) :-
1588 ( lookup_eq(Dict1,X,Y) ->
1590 ; Dict2 = [X-Y|Dict1]
1596 my_term_copy_list(XArgs,Dict1,Dict2,YArgs)
1599 my_term_copy_list([],Dict,Dict,[]).
1600 my_term_copy_list([X|Xs],Dict1,Dict3,[Y|Ys]) :-
1601 my_term_copy(X,Dict1,Dict2,Y),
1602 my_term_copy_list(Xs,Dict2,Dict3,Ys).
1604 gen_cond_susp_detachment(Susp,FA,SuspDetachment) :-
1605 gen_uncond_susp_detachment(Susp,FA,UnCondSuspDetachment),
1609 ; UnCondSuspDetachment
1612 gen_uncond_susp_detachment(Susp,CFct/CAty,SuspDetachment) :-
1613 atom_concat_list(['detach_',CFct, (/) ,CAty],Fct),
1614 Detach =.. [Fct,Vars,Susp],
1617 'chr remove_constraint_internal'(Susp, Vars),
1621 gen_uncond_susps_detachments([],[],true).
1622 gen_uncond_susps_detachments([Susp|Susps],[Term|Terms],(SuspDetachment,SuspsDetachments)) :-
1624 gen_uncond_susp_detachment(Susp,F/A,SuspDetachment),
1625 gen_uncond_susps_detachments(Susps,Terms,SuspsDetachments).
1627 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1629 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1631 %% / ___|(_)_ __ ___ _ __ __ _ __ _ __ _| |_(_) ___ _ __ / |
1632 %% \___ \| | '_ ` _ \
| '_ \ / _` |/ _` |/ _` | __| |/ _ \| '_ \
| |
1633 %% ___
) | | | | | | | |_
) | (_
| | (_
| | (_
| | |_
| | (_
) | | | | | |
1634 %% |____
/|_|_| |_| |_| .__/ \__
,_
|\__
, |\__
,_
|\__
|_
|\___
/|_
| |_
| |_
|
1637 simpagation_head1_code
(Head
,RestHeads
,OtherIDs
,PragmaRule
,F
/A
,_I
,N
,Constraints
,Mod
,Id
,L
,T
) :-
1638 PragmaRule
= pragma
(Rule
,ids
(_
,Heads2IDs
),Pragmas
,_Name
),
1639 Rule
= rule
(_Heads
,Heads2
,_Guard
,_Body
),
1641 head_info
(Head
,A
,_Vars
,Susp
,HeadVars
,HeadPairs
),
1642 head_arg_matches
(HeadPairs
,[],FirstMatching
,VarDict1
),
1644 build_head
(F
,A
,Id
,HeadVars
,ClauseHead
),
1646 append
(RestHeads
,Heads2
,Heads
),
1647 append
(OtherIDs
,Heads2IDs
,IDs
),
1648 reorder_heads
(Head
,Heads
,IDs
,NHeads
,NIDs
),
1649 rest_heads_retrieval_and_matching
(NHeads
,NIDs
,Pragmas
,Head
,Mod
,N
,Constraints
,GetRestHeads
,Susps
,VarDict1
,VarDict
),
1650 length(RestHeads
,RN
),
1651 take
(RN
,Susps
,Susps1
),
1653 guard_body_copies2
(Rule
,VarDict
,GuardCopyList
,BodyCopy
),
1654 guard_via_reschedule
(GetRestHeads
,GuardCopyList
,ClauseHead
-FirstMatching
,RescheduledTest
),
1656 gen_uncond_susps_detachments
(Susps1
,RestHeads
,SuspsDetachments
),
1657 gen_cond_susp_detachment
(Susp
,F
/A
,SuspDetachment
),
1659 Clause
= ( ClauseHead
:-
1668 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1671 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1673 %% / ___
|(_
)_ __ ___ _ __ __ _ __ _ __ _
| |_
(_
) ___ _ __
|___ \
1674 %% \___ \
| | '_ ` _ \| '_ \
/ _` |/ _
` |/ _` | __
| |/ _ \
| '_ \ __) |
1675 %% ___) | | | | | | | |_) | (_| | (_| | (_| | |_| | (_) | | | | / __/
1676 %% |____/|_|_| |_| |_| .__/ \__,_|\__, |\__,_|\__|_|\___/|_| |_| |_____|
1679 %% Genereate prelude + worker predicate
1680 %% prelude calls worker
1681 %% worker iterates over one type of removed constraints
1682 simpagation_head2_code(Head2,RestHeads2,RestIDs,PragmaRule,FA,I,N,Constraints,Mod,Id,L,T) :-
1683 PragmaRule = pragma(Rule,ids(IDs1,_),Pragmas,_Name),
1684 Rule = rule(Heads1,_,Guard,Body),
1685 reorder_heads(Head2,Heads1,IDs1,[Head1|RestHeads1],[ID1|RestIDs1]), % Heads1 = [Head1|RestHeads1],
1686 % IDs1 = [ID1|RestIDs1],
1687 simpagation_head2_prelude(Head2,Head1,[RestHeads2,Heads1,Guard,Body],FA,I,N,Constraints,Mod,Id,L,L1),
1689 simpagation_head2_worker(Head2,Head1,ID1,RestHeads1,RestIDs1,RestHeads2,RestIDs,Rule,Pragmas,FA,I,N,Constraints,Mod,Id2,L1,T).
1691 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1692 simpagation_head2_prelude(Head,Head1,Rest,F/A,_I,N,Constraints,Mod,Id1,L,T) :-
1693 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs),
1694 build_head(F,A,Id1,VarsSusp,ClauseHead),
1695 head_arg_matches(HeadPairs,[],FirstMatching,VarDict),
1697 passive_head_via(Head1,[Head],[],Constraints,Mod,VarDict,ModConstraintsGoal,Attr,AttrDict),
1698 instantiate_pattern_goals(AttrDict,N),
1702 functor(Head1,F1,A1),
1703 nth1(Pos,Constraints,F1/A1), !,
1704 make_attr(N,_,SuspsList,Attr),
1705 nth1(Pos,SuspsList,AllSusps)
1708 ( Id1 == [0] -> % create suspension
1709 gen_cond_allocation(Vars,Susp,F/A,VarsSusp,Mod,ConstraintAllocationGoal)
1710 ; ConstraintAllocationGoal = true
1713 extend_id(Id1,DelegateId),
1714 extra_active_delegate_variables(Head,Rest,VarDict,ExtraVars),
1715 append([AllSusps|VarsSusp],ExtraVars,DelegateCallVars),
1716 build_head(F,A,DelegateId,DelegateCallVars,Delegate),
1723 ConstraintAllocationGoal,
1726 L = [PreludeClause|T].
1728 extra_active_delegate_variables(Term,Terms,VarDict,Vars) :-
1730 delegate_variables(Term,Terms,VarDict,Args,Vars).
1732 passive_delegate_variables(Term,PrevTerms,NextTerms,VarDict,Vars) :-
1733 term_variables(PrevTerms,PrevVars),
1734 delegate_variables(Term,NextTerms,VarDict,PrevVars,Vars).
1736 delegate_variables(Term,Terms,VarDict,PrevVars,Vars) :-
1737 term_variables(Term,V1),
1738 term_variables(Terms,V2),
1739 intersect_eq(V1,V2,V3),
1740 list_difference_eq(V3,PrevVars,V4),
1741 translate(V4,VarDict,Vars).
1744 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1745 simpagation_head2_worker(Head2,Head1,ID1,RestHeads1,IDs1,RestHeads2,IDs2,Rule,Pragmas,FA,I,N,Constraints,Mod,Id,L,T) :-
1746 Rule = rule(_,_,Guard,Body),
1747 simpagation_head2_worker_end(Head2,[Head1,RestHeads1,RestHeads2,Guard,Body],FA,Id,L,L1),
1748 simpagation_head2_worker_body(Head2,Head1,ID1,RestHeads1,IDs1,RestHeads2,IDs2,Rule,Pragmas,FA,I,N,Constraints,Mod,Id,L1,T).
1750 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1751 simpagation_head2_worker_body(Head2,Head1,ID1,RestHeads1,IDs1,RestHeads2,IDs2,Rule,Pragmas,F/A,_I,N,Constraints,Mod,Id,L,T) :-
1753 gen_var(OtherSusps),
1755 head_info(Head2,A,_Vars,Susp,VarsSusp,Head2Pairs),
1756 head_arg_matches(Head2Pairs,[],_,VarDict1),
1758 Rule = rule(_,_,Guard,Body),
1759 extra_active_delegate_variables(Head2,[Head1,RestHeads1,RestHeads2,Guard,Body],VarDict1,ExtraVars),
1760 append([[OtherSusp|OtherSusps]|VarsSusp],ExtraVars,HeadVars),
1761 build_head(F,A,Id,HeadVars,ClauseHead),
1763 functor(Head1,_OtherF,OtherA),
1764 head_info(Head1,OtherA,OtherVars,_,_,Head1Pairs),
1765 head_arg_matches(Head1Pairs,VarDict1,FirstMatching,VarDict2),
1767 OtherSuspension =.. [suspension,_,OtherState,_,_,_,_|OtherVars],
1768 create_get_mutable_ref(active,OtherState,GetMutable),
1770 ( OtherSusp = OtherSuspension,
1774 ( (RestHeads1 \== [] ; RestHeads2 \== []) ->
1775 append(RestHeads1,RestHeads2,RestHeads),
1776 append(IDs1,IDs2,IDs),
1777 reorder_heads(Head1-Head2,RestHeads,IDs,NRestHeads,NIDs),
1778 rest_heads_retrieval_and_matching(NRestHeads,NIDs,Pragmas,[Head1,Head2],Mod,N,Constraints,RestSuspsRetrieval,Susps,VarDict2,VarDict,[Head1],[OtherSusp],[]),
1779 length(RestHeads1,RH1N),
1780 take(RH1N,Susps,Susps1)
1781 ; RestSuspsRetrieval = [],
1786 gen_uncond_susps_detachments([OtherSusp | Susps1],[Head1|RestHeads1],Susps1Detachments),
1788 append([OtherSusps|VarsSusp],ExtraVars,RecursiveVars),
1789 build_head(F,A,Id,RecursiveVars,RecursiveCall),
1790 append([[]|VarsSusp],ExtraVars,RecursiveVars2),
1791 build_head(F,A,Id,RecursiveVars2,RecursiveCall2),
1793 guard_body_copies2(Rule,VarDict,GuardCopyList,BodyCopy),
1794 guard_via_reschedule(RestSuspsRetrieval,GuardCopyList,v(ClauseHead,IteratorSuspTest,FirstMatching),RescheduledTest),
1795 ( BodyCopy \== true ->
1796 gen_uncond_attach_goal(F/A,Susp,Mod,Attachment,Generation),
1797 gen_state_cond_call(Susp,A,RecursiveCall,Generation,ConditionalRecursiveCall),
1798 gen_state_cond_call(Susp,A,RecursiveCall2,Generation,ConditionalRecursiveCall2)
1799 ; Attachment = true,
1800 ConditionalRecursiveCall = RecursiveCall,
1801 ConditionalRecursiveCall2 = RecursiveCall2
1804 ( member(unique(ID1,UniqueKeys), Pragmas),
1805 check_unique_keys(UniqueKeys,VarDict1) ->
1810 ( RescheduledTest ->
1814 ConditionalRecursiveCall2
1831 ConditionalRecursiveCall
1839 gen_state_cond_call(Susp,N,Call,Generation,ConditionalCall) :-
1841 Suspension =.. [suspension,_,State,_,NewGeneration,_,_|Args],
1842 create_get_mutable_ref(active,State,GetState),
1843 create_get_mutable_ref(Generation,NewGeneration,GetGeneration),
1845 ( Susp = Suspension,
1848 'chr update_mutable
'(inactive,State),
1853 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1854 simpagation_head2_worker_end(Head,Rest,F/A,Id,L,T) :-
1855 head_info(Head,A,_Vars,_Susp,VarsSusp,Pairs),
1856 head_arg_matches(Pairs,[],_,VarDict),
1857 extra_active_delegate_variables(Head,Rest,VarDict,ExtraVars),
1858 append([[]|VarsSusp],ExtraVars,HeadVars),
1859 build_head(F,A,Id,HeadVars,ClauseHead),
1860 next_id(Id,ContinuationId),
1861 build_head(F,A,ContinuationId,VarsSusp,ContinuationHead),
1862 Clause = ( ClauseHead :- ContinuationHead ),
1865 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1868 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1870 %% | _ \ _ __ ___ _ __ __ _ __ _ __ _| |_(_) ___ _ __
1871 %% | |_) | '__
/ _ \| '_ \ / _
` |/ _` |/ _
` | __| |/ _ \| '_ \
1872 %% | __/| | | (_) | |_) | (_| | (_| | (_| | |_| | (_) | | | |
1873 %% |_| |_| \___/| .__/ \__,_|\__, |\__,_|\__|_|\___/|_| |_|
1876 propagation_code(Head,RestHeads,Rule,RuleNb,RestHeadNb,FA,N,Constraints,Mod,Id,L,T) :-
1877 ( RestHeads == [] ->
1878 propagation_single_headed(Head,Rule,RuleNb,FA,Mod,Id,L,T)
1880 propagation_multi_headed(Head,RestHeads,Rule,RuleNb,RestHeadNb,FA,N,Constraints,Mod,Id,L,T)
1882 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1883 %% Single headed propagation
1884 %% everything in a single clause
1885 propagation_single_headed(Head,Rule,RuleNb,F/A,Mod,Id,L,T) :-
1886 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs),
1887 build_head(F,A,Id,VarsSusp,ClauseHead),
1890 build_head(F,A,NextId,VarsSusp,NextHead),
1892 NextCall = NextHead,
1894 head_arg_matches(HeadPairs,[],HeadMatching,VarDict),
1895 guard_body_copies(Rule,VarDict,GuardCopy,BodyCopy),
1897 gen_cond_allocation(Vars,Susp,F/A,VarsSusp,Mod,Allocation),
1898 Allocation1 = Allocation
1902 gen_uncond_attach_goal(F/A,Susp,Mod,Attachment,Generation),
1904 gen_state_cond_call(Susp,A,NextCall,Generation,ConditionalNextCall),
1910 'chr novel_production'(Susp,RuleNb), % optimisation of t(RuleNb,Susp)
1913 'chr extend_history'(Susp,RuleNb),
1920 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1921 %% multi headed propagation
1922 %% prelude + predicates to accumulate the necessary combinations of suspended
1923 %% constraints + predicate to execute the body
1924 propagation_multi_headed(Head,RestHeads,Rule,RuleNb,RestHeadNb,FA,N,Constraints,Mod,Id,L,T) :-
1925 RestHeads = [First|Rest],
1926 propagation_prelude(Head,RestHeads,Rule,FA,N,Constraints,Mod,Id,L,L1),
1927 extend_id(Id,ExtendedId),
1928 propagation_nested_code(Rest,[First,Head],Rule,RuleNb,RestHeadNb,FA,N,Constraints,Mod,ExtendedId,L1,T).
1930 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1931 propagation_prelude(Head,[First|Rest],Rule,F/A,N,Constraints,Mod,Id,L,T) :-
1932 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs),
1933 build_head(F,A,Id,VarsSusp,PreludeHead),
1934 head_arg_matches(HeadPairs,[],FirstMatching,VarDict),
1935 Rule = rule(_,_,Guard,Body),
1936 extra_active_delegate_variables(Head,[First,Rest,Guard,Body],VarDict,ExtraVars),
1938 passive_head_via(First,[Head],[],Constraints,Mod,VarDict,FirstSuspGoal,Attr,AttrDict),
1939 instantiate_pattern_goals(AttrDict,N),
1943 functor(First,FirstFct,FirstAty),
1944 make_attr(N,_Mask,SuspsList,Attr),
1945 nth1(Pos,Constraints,FirstFct/FirstAty), !,
1946 nth1(Pos,SuspsList,Susps)
1950 gen_cond_allocation(Vars,Susp,F/A,VarsSusp,Mod,CondAllocation)
1951 ; CondAllocation = true
1954 extend_id(Id,NestedId),
1955 append([Susps|VarsSusp],ExtraVars,NestedVars),
1956 build_head(F,A,NestedId,NestedVars,NestedHead),
1957 NestedCall = NestedHead,
1969 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1970 propagation_nested_code([],[CurrentHead|PreHeads],Rule,RuleNb,RestHeadNb,FA,_,_Constraints,Mod,Id,L,T) :-
1971 propagation_end([CurrentHead|PreHeads],[],Rule,FA,Id,L,L1),
1972 propagation_body(CurrentHead,PreHeads,Rule,RuleNb,RestHeadNb,FA,Mod,Id,L1,T).
1974 propagation_nested_code([Head|RestHeads],PreHeads,Rule,RuleNb,RestHeadNb,FA,N,Constraints,Mod,Id,L,T) :-
1975 propagation_end(PreHeads,[Head|RestHeads],Rule,FA,Id,L,L1),
1976 propagation_accumulator([Head|RestHeads],PreHeads,Rule,FA,N,Constraints,Mod,Id,L1,L2),
1978 propagation_nested_code(RestHeads,[Head|PreHeads],Rule,RuleNb,RestHeadNb,FA,N,Constraints,Mod,IncId,L2,T).
1980 propagation_body(CurrentHead,PreHeads,Rule,RuleNb,RestHeadNb,F/A,Mod,Id,L,T) :-
1981 Rule = rule(_,_,Guard,Body),
1982 get_prop_inner_loop_vars(PreHeads,[CurrentHead,Guard,Body],PreVarsAndSusps,VarDict1,Susp,RestSusps),
1984 gen_var(OtherSusps),
1985 functor(CurrentHead,_OtherF,OtherA),
1986 gen_vars(OtherA,OtherVars),
1987 Suspension =.. [suspension,_,State,_,_,_,_|OtherVars],
1988 create_get_mutable_ref(active,State,GetMutable),
1990 OtherSusp = Suspension,
1993 ClauseVars = [[OtherSusp|OtherSusps]|PreVarsAndSusps],
1994 build_head(F,A,Id,ClauseVars,ClauseHead),
1995 RecursiveVars = [OtherSusps|PreVarsAndSusps],
1996 build_head(F,A,Id,RecursiveVars,RecursiveHead),
1997 RecursiveCall = RecursiveHead,
1998 CurrentHead =.. [_|OtherArgs],
1999 pairup(OtherArgs,OtherVars,OtherPairs),
2000 head_arg_matches(OtherPairs,VarDict1,Matching,VarDict),
2002 different_from_other_susps(CurrentHead,OtherSusp,PreHeads,RestSusps,DiffSuspGoals),
2004 guard_body_copies(Rule,VarDict,GuardCopy,BodyCopy),
2005 gen_uncond_attach_goal(F/A,Susp,Mod,Attach,Generation),
2006 gen_state_cond_call(Susp,A,RecursiveCall,Generation,ConditionalRecursiveCall),
2008 history_susps(RestHeadNb,[OtherSusp|RestSusps],Susp,[],HistorySusps),
2009 bagof('chr novel_production'(X,Y),( member(X,HistorySusps), Y = TupleVar) ,NovelProductionsList),
2010 list2conj(NovelProductionsList,NovelProductions),
2011 Tuple =.. [t,RuleNb|HistorySusps],
2021 'chr extend_history'(Susp,TupleVar),
2024 ConditionalRecursiveCall
2031 history_susps(Count,OtherSusps,Susp,Acc,HistorySusps) :-
2033 reverse(OtherSusps,ReversedSusps),
2034 append(ReversedSusps,[Susp|Acc],HistorySusps)
2036 OtherSusps = [OtherSusp|RestOtherSusps],
2037 NCount is Count - 1,
2038 history_susps(NCount,RestOtherSusps,Susp,[OtherSusp|Acc],HistorySusps)
2042 get_prop_inner_loop_vars([Head],Terms,HeadVars,VarDict,Susp,[]) :-
2045 head_info(Head,A,_Vars,Susp,VarsSusp,Pairs),
2046 head_arg_matches(Pairs,[],_,VarDict),
2047 extra_active_delegate_variables(Head,Terms,VarDict,ExtraVars),
2048 append(VarsSusp,ExtraVars,HeadVars).
2049 get_prop_inner_loop_vars([Head|Heads],Terms,VarsSusps,NVarDict,MainSusp,[Susp|RestSusps]) :-
2050 get_prop_inner_loop_vars(Heads,[Head|Terms],RestVarsSusp,VarDict,MainSusp,RestSusps),
2053 head_info(Head,A,_Vars,Susp,_VarsSusp,Pairs),
2054 head_arg_matches(Pairs,VarDict,_,NVarDict),
2055 passive_delegate_variables(Head,Heads,Terms,NVarDict,HeadVars),
2056 append(HeadVars,[Susp,Susps|RestVarsSusp],VarsSusps).
2058 propagation_end([CurrentHead|PrevHeads],NextHeads,Rule,F/A,Id,L,T) :-
2059 Rule = rule(_,_,Guard,Body),
2060 gen_var_susp_list_for(PrevHeads,[CurrentHead,NextHeads,Guard,Body],_,VarsAndSusps,AllButFirst,FirstSusp),
2062 Vars = [ [] | VarsAndSusps],
2064 build_head(F,A,Id,Vars,Head),
2068 PrevVarsAndSusps = AllButFirst
2071 PrevVarsAndSusps = [FirstSusp|AllButFirst]
2074 build_head(F,A,PrevId,PrevVarsAndSusps,PrevHead),
2075 PredecessorCall = PrevHead,
2083 gen_var_susp_list_for([Head],Terms,VarDict,HeadVars,VarsSusp,Susp) :-
2086 head_info(Head,A,_Vars,Susp,VarsSusp,HeadPairs),
2087 head_arg_matches(HeadPairs,[],_,VarDict),
2088 extra_active_delegate_variables(Head,Terms,VarDict,ExtraVars),
2089 append(VarsSusp,ExtraVars,HeadVars).
2090 gen_var_susp_list_for([Head|Heads],Terms,NVarDict,VarsSusps,Rest,Susps) :-
2091 gen_var_susp_list_for(Heads,[Head|Terms],VarDict,Rest,_,_),
2094 head_info(Head,A,_Vars,Susp,_VarsSusp,HeadPairs),
2095 head_arg_matches(HeadPairs,VarDict,_,NVarDict),
2096 passive_delegate_variables(Head,Heads,Terms,NVarDict,HeadVars),
2097 append(HeadVars,[Susp,Susps|Rest],VarsSusps).
2099 propagation_accumulator([NextHead|RestHeads],[CurrentHead|PreHeads],Rule,F/A,N,Constraints,Mod,Id,L,T) :-
2100 Rule = rule(_,_,Guard,Body),
2101 pre_vars_and_susps(PreHeads,[CurrentHead,NextHead,RestHeads,Guard,Body],PreVarsAndSusps,VarDict,PreSusps),
2102 gen_var(OtherSusps),
2103 functor(CurrentHead,_OtherF,OtherA),
2104 gen_vars(OtherA,OtherVars),
2105 head_info(CurrentHead,OtherA,OtherVars,OtherSusp,_VarsSusp,HeadPairs),
2106 head_arg_matches(HeadPairs,VarDict,FirstMatching,VarDict1),
2108 OtherSuspension =.. [suspension,_,State,_,_,_,_|OtherVars],
2110 different_from_other_susps(CurrentHead,OtherSusp,PreHeads,PreSusps,DiffSuspGoals),
2111 create_get_mutable_ref(active,State,GetMutable),
2113 OtherSusp = OtherSuspension,
2118 functor(NextHead,NextF,NextA),
2119 passive_head_via(NextHead,[CurrentHead|PreHeads],[],Constraints,Mod,VarDict1,NextSuspGoal,Attr,AttrDict),
2120 instantiate_pattern_goals(AttrDict,N),
2124 nth1(Position,Constraints,NextF/NextA), !,
2125 make_attr(N,_Mask,SuspsList,Attr),
2126 nth1(Position,SuspsList,NextSusps)
2128 inc_id(Id,NestedId),
2129 ClauseVars = [[OtherSusp|OtherSusps]|PreVarsAndSusps],
2130 build_head(F,A,Id,ClauseVars,ClauseHead),
2131 passive_delegate_variables(CurrentHead,PreHeads,[NextHead,RestHeads,Guard,Body],VarDict1,CurrentHeadVars),
2132 append([NextSusps|CurrentHeadVars],[OtherSusp,OtherSusps|PreVarsAndSusps],NestedVars),
2133 build_head(F,A,NestedId,NestedVars,NestedHead),
2135 RecursiveVars = [OtherSusps|PreVarsAndSusps],
2136 build_head(F,A,Id,RecursiveVars,RecursiveHead),
2148 pre_vars_and_susps([Head],Terms,HeadVars,VarDict,[]) :-
2151 head_info(Head,A,_Vars,_Susp,VarsSusp,HeadPairs),
2152 head_arg_matches(HeadPairs,[],_,VarDict),
2153 extra_active_delegate_variables(Head,Terms,VarDict,ExtraVars),
2154 append(VarsSusp,ExtraVars,HeadVars).
2155 pre_vars_and_susps([Head|Heads],Terms,NVSs,NVarDict,[Susp|Susps]) :-
2156 pre_vars_and_susps(Heads,[Head|Terms],VSs,VarDict,Susps),
2159 head_info(Head,A,_Vars,Susp,_VarsSusp,HeadPairs),
2160 head_arg_matches(HeadPairs,VarDict,_,NVarDict),
2161 passive_delegate_variables(Head,Heads,Terms,NVarDict,HeadVars),
2162 append(HeadVars,[Susp,NextSusps|VSs],NVSs).
2164 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2166 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2168 %% | _ \ __ _ ___ ___(_)_ _____ | | | | ___ __ _ __| |
2169 %% | |_) / _` / __
/ __| \ \ / / _ \ | |_| |/ _ \
/ _` |/ _
` |
2170 %% | __/ (_| \__ \__ \ |\ V / __/ | _ | __/ (_| | (_| |
2171 %% |_| \__,_|___/___/_| \_/ \___| |_| |_|\___|\__,_|\__,_|
2174 %% | _ \ ___| |_ _ __(_) _____ ____ _| |
2175 %% | |_) / _ \ __| '__| |/ _ \ \ / / _` | |
2176 %% | _
< __
/ |_| | | | __/\ V
/ (_
| | |
2177 %% |_
| \_\___
|\__
|_
| |_
|\___
| \_
/ \__
,_
|_
|
2180 %% | _ \ ___ ___ _ __ __
| | ___ _ __
(_
)_ __ __ _
2181 %% | |_
) / _ \/ _ \
| '__/ _` |/ _ \ '__
| | '_ \ / _` |
2182 %% | _ < __/ (_) | | | (_| | __/ | | | | | | (_| |
2183 %% |_| \_\___|\___/|_| \__,_|\___|_| |_|_| |_|\__, |
2186 reorder_heads(Head,RestHeads,RestIDs,NRestHeads,NRestIDs) :-
2187 ( chr_pp_flag(reorder_heads,on) ->
2188 reorder_heads_main(Head,RestHeads,RestIDs,NRestHeads,NRestIDs)
2190 NRestHeads = RestHeads,
2194 reorder_heads_main(Head,RestHeads,RestIDs,NRestHeads,NRestIDs) :-
2195 term_variables(Head,KnownVars),
2196 reorder_heads1(RestHeads,RestIDs,KnownVars,NRestHeads,NRestIDs).
2198 reorder_heads1(Heads,IDs,KnownVars,NHeads,NIDs) :-
2203 NHeads = [BestHead|BestTail],
2204 NIDs = [BestID | BestIDs],
2205 select_best_head(Heads,IDs,KnownVars,BestHead,BestID,RestHeads,RestIDs,NKnownVars),
2206 reorder_heads1(RestHeads,RestIDs,NKnownVars,BestTail,BestIDs)
2209 select_best_head(Heads,IDs,KnownVars,BestHead,BestID,RestHeads,RestIDs,NKnownVars) :-
2210 ( bagof(tuple(Score,Head,ID,Rest,RIDs), (
2211 select2(Head,ID, Heads,IDs,Rest,RIDs) ,
2212 order_score(Head,KnownVars,Rest,Score)
2214 Scores) -> true ; Scores = []),
2215 max_go_list(Scores,tuple(_,BestHead,BestID,RestHeads,RestIDs)),
2216 term_variables(BestHead,BestHeadVars),
2218 member(V,BestHeadVars),
2219 \+ memberchk_eq(V,KnownVars)
2221 NewVars) -> true ; NewVars = []),
2222 append(NewVars,KnownVars,NKnownVars).
2224 reorder_heads(Head,RestHeads,NRestHeads) :-
2225 term_variables(Head,KnownVars),
2226 reorder_heads1(RestHeads,KnownVars,NRestHeads).
2228 reorder_heads1(Heads,KnownVars,NHeads) :-
2232 NHeads = [BestHead|BestTail],
2233 select_best_head(Heads,KnownVars,BestHead,RestHeads,NKnownVars),
2234 reorder_heads1(RestHeads,NKnownVars,BestTail)
2237 select_best_head(Heads,KnownVars,BestHead,RestHeads,NKnownVars) :-
2238 ( bagof(tuple(Score,Head,Rest), (
2239 select(Head,Heads,Rest) ,
2240 order_score(Head,KnownVars,Rest,Score)
2242 Scores) -> true ; Scores = []),
2243 max_go_list(Scores,tuple(_,BestHead,RestHeads)),
2244 term_variables(BestHead,BestHeadVars),
2246 member(V,BestHeadVars),
2247 \+ memberchk_eq(V,KnownVars)
2249 NewVars) -> true ; NewVars = []),
2250 append(NewVars,KnownVars,NKnownVars).
2252 order_score(Head,KnownVars,Rest,Score) :-
2253 term_variables(Head,HeadVars),
2254 term_variables(Rest,RestVars),
2255 order_score_vars(HeadVars,KnownVars,RestVars,0,Score).
2257 order_score_vars([],_,_,Score,NScore) :-
2263 order_score_vars([V|Vs],KnownVars,RestVars,Score,NScore) :-
2264 ( memberchk_eq(V,KnownVars) ->
2266 ; memberchk_eq(V,RestVars) ->
2271 order_score_vars(Vs,KnownVars,RestVars,TScore,NScore).
2273 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2275 %% |_ _|_ __ | (_)_ __ (_)_ __ __ _
2276 %% | || '_ \
| | | '_ \| | '_ \
/ _
` |
2277 %% | || | | | | | | | | | | | | (_| |
2278 %% |___|_| |_|_|_|_| |_|_|_| |_|\__, |
2282 create_get_mutable_ref(V,M,GM) :- GM = (M = mutable(V)).
2286 %% create_get_mutable_ref(V,M,GM) :- GM = (get_mutable(V,M)).
2291 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2293 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2295 %% / ___|___ __| | ___ / ___| | ___ __ _ _ __ (_)_ __ __ _
2296 %% | | / _ \ / _` |/ _ \ | | | |/ _ \
/ _` | '_ \| | '_ \ / _
` |
2297 %% | |__| (_) | (_| | __/ | |___| | __/ (_| | | | | | | | | (_| |
2298 %% \____\___/ \__,_|\___| \____|_|\___|\__,_|_| |_|_|_| |_|\__, |
2301 %% removes redundant 'true's and other trivial but potentially non-free constructs
2303 clean_clauses([],[]).
2304 clean_clauses([C|Cs],[NC|NCs]) :-
2306 clean_clauses(Cs,NCs).
2308 clean_clause(Clause,NClause) :-
2309 ( Clause = (Head :- Body) ->
2310 clean_goal(Body,NBody),
2314 NClause = (Head :- NBody)
2320 clean_goal(Goal,NGoal) :-
2323 clean_goal((G1,G2),NGoal) :-
2334 clean_goal((If -> Then ; Else),NGoal) :-
2338 clean_goal(Then,NThen),
2341 clean_goal(Else,NElse),
2344 clean_goal(Then,NThen),
2345 clean_goal(Else,NElse),
2346 NGoal = (NIf -> NThen; NElse)
2348 clean_goal((G1 ; G2),NGoal) :-
2359 clean_goal(once(G),NGoal) :-
2369 clean_goal((G1 -> G2),NGoal) :-
2373 clean_goal(G2,NGoal)
2378 NGoal = (NG1 -> NG2)
2380 clean_goal(Goal,Goal).
2381 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2383 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2385 %% | | | | |_(_) (_) |_ _ _
2386 %% | | | | __| | | | __| | | |
2387 %% | |_| | |_| | | | |_| |_| |
2388 %% \___/ \__|_|_|_|\__|\__, |
2395 head_info(Head,A,Vars,Susp,VarsSusp,HeadPairs) :-
2396 vars_susp(A,Vars,Susp,VarsSusp),
2398 pairup(Args,Vars,HeadPairs).
2400 inc_id([N|Ns],[O|Ns]) :-
2402 dec_id([N|Ns],[M|Ns]) :-
2405 extend_id(Id,[0|Id]).
2407 next_id([_,N|Ns],[O|Ns]) :-
2410 build_head(F,A,Id,Args,Head) :-
2411 buildName(F,A,Id,Name),
2412 Head =.. [Name|Args].
2414 buildName(Fct,Aty,List,Result) :-
2415 atom_concat(Fct, (/) ,FctSlash),
2416 atomic_concat(FctSlash,Aty,FctSlashAty),
2417 buildName_(List,FctSlashAty,Result).
2419 buildName_([],Name,Name).
2420 buildName_([N|Ns],Name,Result) :-
2421 buildName_(Ns,Name,Name1),
2422 atom_concat(Name1,'__',NameDash), % '_' is a char :-(
2423 atomic_concat(NameDash,N,Result).
2425 vars_susp(A,Vars,Susp,VarsSusp) :-
2427 append(Vars,[Susp],VarsSusp).
2429 make_attr(N,Mask,SuspsList,Attr) :-
2430 length(SuspsList,N),
2431 Attr =.. [v,Mask|SuspsList].
2433 or_pattern(Pos,Pat) :-
2435 Pat is 1 << Pow. % was 2 ** X
2437 and_pattern(Pos,Pat) :-
2439 Y is 1 << X, % was 2 ** X
2442 conj2list(Conj,L) :- %% transform conjunctions to list
2443 conj2list(Conj,L,[]).
2445 conj2list(Conj,L,T) :-
2449 conj2list(G,[G | T],T).
2452 list2conj([G],X) :- !, X = G.
2453 list2conj([G|Gs],C) :-
2454 ( G == true -> %% remove some redundant trues
2461 atom_concat_list([X],X) :- ! .
2462 atom_concat_list([X|Xs],A) :-
2463 atom_concat_list(Xs,B),
2464 atomic_concat(X,B,A).
2466 atomic_concat(A,B,C) :-
2469 atom_concat(AA,BB,C).
2483 set_elems([X|Xs],X) :-
2486 member2([X|_],[Y|_],X-Y).
2487 member2([_|Xs],[_|Ys],P) :-
2490 select2(X, Y, [X|Xs], [Y|Ys], Xs, Ys).
2491 select2(X, Y, [X1|Xs], [Y1|Ys], [X1|NXs], [Y1|NYs]) :-
2492 select2(X, Y, Xs, Ys, NXs, NYs).
2494 pair_all_with([],_,[]).
2495 pair_all_with([X|Xs],Y,[X-Y|Rest]) :-
2496 pair_all_with(Xs,Y,Rest).
2499 ( var(X) -> X = Def ; true).
2501 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2504 verbosity_on :- prolog_flag(verbose,V), V == yes.
2508 %% verbosity_on. % at the moment