27:- module('$coroutining',
37:-
'$$compile'/4
use_system_module(
'$_boot', []).
40:-
get_module_atts/2
put_module_atts/2
use_system_module( attributes, [,
80wake_delay(redo_dif(
Done,
X,
Y))
:-
82wake_delay(redo_freeze(
Done,
V,
Goal))
:-
83 redo_freeze(
Done,
V,
Goal).
84wake_delay(redo_eq(
Done,
X,
Y,
Goal))
:-
85 redo_eq(
Done,
X,
Y,
Goal,
_G).
86wake_delay(redo_ground(
Done,
X,
Goal))
:-
87 redo_ground(
Done,
X,
Goal).
91attribute_goals(
Var)
-->
92 {
get_attr(
Var,
'$coroutining',
Delays) },
94 attgoal_for_delays(
Delays,
Var).
96attgoal_for_delays((
G1s,
G2s),
V)
-->
97 attgoal_for_delays(
G1s,
V),
98 attgoal_for_delays(
G2s,
V).
99attgoal_for_delays(
G,
V)
-->
101 attgoal_for_delay(
G,
V).
103attgoal_for_delay(redo_dif(
Done,
X,
Y),
_V)
-->
104 {
var(
Done),
Done = var }, !,
106attgoal_for_delay(redo_freeze(
Done,
V,
Goal),
V)
-->
108 {
remove_when_declarations(
Goal,
NoWGoal) },
110attgoal_for_delay(redo_eq(
Done,
X,
Y,
Goal),
_V)
-->
111 {
var(
Done),
Done = var }, !,
113attgoal_for_delay(redo_ground(
Done,
X,
Goal),
_V)
-->
115 [
:when(ground(
X),
Goal) ].
116attgoal_for_delay(
_,
_V)
--> [].
118remove_when_declarations(when(
Cond,
Goal,
_), when(
Cond,
NoWGoal))
:- ove_when_declarations,
119 remove_when_declarations(
Goal,
NoWGoal).
120remove_when_declarations(
Goal,
Goal).
133ove_when_declarations
:freeze(
V,
G)
:-
136freeze_goal
:freeze(
_,
G)
:-
141 '$current_module'(
M),
142 internal_freeze(
V, redo_freeze(
_Done,
V,
M:VG)).
143freeze_goal(
V,
M:G)
:- freeze_goal,
144 internal_freeze(
V, redo_freeze(
_Done,
V,
M:G)).
146 '$current_module'(
M),
147 internal_freeze(
V, redo_freeze(
_Done,
V,
M:G)).
194internal_freeze
:dif(
X,
Y)
:-
195 '$can_unify'(
X,
Y,
LVars),
'$can_unify',
197 dif_suspend_on_lvars(
LVars, redo_dif(
_Done,
X,
Y)).
198dif_suspend_on_lvars
:dif(
_,
_).
201dif_suspend_on_lvars([],
_).
202dif_suspend_on_lvars([
H|T],
G)
:-
203 internal_freeze(
H,
G),
204 dif_suspend_on_lvars(
T,
G).
215redo_dif(
Done,
_,
_)
:- nonvar(
Done),
nonvar.
216redo_dif(
Done,
X,
Y)
:-
217 '$can_unify'(
X,
Y,
LVars),
'$can_unify',
219 dif_suspend_on_lvars(
LVars, redo_dif(
Done,
X,
Y)).
220redo_dif(
'$done',
_,
_).
222redo_freeze(
Done,
V,
G0)
:-
232 G0 = when(
C,
G,
Done)
-> when(
C,
G,
Done)
;
236 var(
V)
-> internal_freeze(
V, redo_freeze(
Done,
V,
G0))
;
242 Done = '$done',
'$execute'(
G0) ).
246redo_eq(
Done,
_,
_,
_,
_)
:- nonvar(
Done),
nonvar.
247redo_eq(
_,
X,
Y,
_,
G)
:-
248 '$can_unify'(
X,
Y,
LVars),
250 dif_suspend_on_lvars(
LVars,
G).
251redo_eq(
Done,
_,
_, when(
C,
G,
Done),
_)
:- redo_eq,
253redo_eq(
'$done',
_ ,
_ ,
Goal,
_)
:-
258redo_ground(
Done,
_,
_)
:- nonvar(
Done),
nonvar.
259redo_ground(
Done,
X,
Goal)
:-
260 '$non_ground'(
X,
Var),
'$non_ground',
261 internal_freeze(
Var, redo_ground(
Done,
X,
Goal)).
262redo_ground(
Done,
_, when(
C,
G,
Done))
:- redo_ground,
264redo_ground(
'$done',
_,
Goal)
:-
293'$execute'
:when(
Conds,
Goal)
:-
294 '$current_module'(
Mod),
295 prepare_goal_for_when(
Goal,
Mod,
ModG),
296 when(
Conds,
ModG,
Done, [],
LG),
when,
297 suspend_when_goals(
LG,
Done).
298suspend_when_goals
:when(
_,
Goal)
:-
309'$declare_when'(
Cond,
G)
:-
310 generate_code_for_when(
Cond,
G,
Code),
311 '$current_module'(
Module),
312 '$$compile'(
Code,
Code,
5,
Module),
'$$compile'.
318generate_code_for_when(
Conds,
G,
319 (
G :- when(
Conds,
ModG,
Done, [],
LG), !,
320 suspend_when_goals(
LG,
Done)) )
:-
321 '$current_module'(
Mod),
322 prepare_goal_for_when(
G,
Mod,
ModG).
328prepare_goal_for_when(
G,
Mod,
Mod:call(
G))
:- var(
G),
var.
329prepare_goal_for_when(
M:G,
_,
M:G)
:- prepare_goal_for_when.
330prepare_goal_for_when(
G,
Mod,
Mod:G).
343when(
V,
G,
_Done,
LG,
LG)
:- var(
V),
var,
344 '$do_error'(instantiation_error,when(
V,
G)).
345when(nonvar(
V),
G,
Done,
LG0,
LGF)
:-
346 when_suspend(nonvar(
V),
G,
Done,
LG0,
LGF).
347when(?=(
X,
Y),
G,
Done,
LG0,
LGF)
:-
348 when_suspend(?=(
X,
Y),
G,
Done,
LG0,
LGF).
349when(ground(
T),
G,
Done,
LG0,
LGF)
:-
350 when_suspend(ground(
T),
G,
Done,
LG0,
LGF).
351when((
C1,
C2),
G,
Done,
LG0,
LGF)
:-
354 when(
C1, when(
C2,
G,
Done),
Done,
LG0,
LGI)
359 when(
C2,
G,
Done,
LG0,
LGF)
361when((
G1 ; G2),
G,
Done,
LG0,
LGF)
:-
362 when(
G1,
G,
Done,
LG0,
LGI),
363 when(
G2,
G,
Done,
LGI,
LGF).
371when(
Cond,
G,
Done)
:-
372 when(
Cond,
G,
Done, [],
LG),
374 suspend_when_goals(
LG,
Done).
375when(
_,
G,
'$done')
:-
383when_suspend(
_,
_,
Done,
_, [])
:- nonvar(
Done),
nonvar.
387when_suspend(nonvar(
V),
G,
Done,
LG0,
LGF)
:-
388 try_freeze(
V,
G,
Done,
LG0,
LGF).
389when_suspend(?=(
X,
Y),
G,
Done,
LG0,
LGF)
:-
390 try_eq(
X,
Y,
G,
Done,
LG0,
LGF).
391when_suspend(ground(
X),
G,
Done,
LG0,
LGF)
:-
392 try_ground(
X,
G,
Done,
LG0,
LGF).
395try_freeze(
V,
G,
Done,
LG0,
LGF)
:-
397 LGF = [
'$coroutining':internal_freeze(
V, redo_freeze(
Done,
V,
G))
|LG0].
399try_eq(
X,
Y,
G,
Done,
LG0,
LGF)
:-
400 '$can_unify'(
X,
Y,
LVars),
LVars = [
_|_],
401 LGF = [
'$coroutining':dif_suspend_on_lvars(
LVars, redo_eq(
Done,
X,
Y,
G))
|LG0].
403try_ground(
X,
G,
Done,
LG0,
LGF)
:-
404 '$non_ground'(
X,
Var),
409 LGF = [
'$coroutining':internal_freeze(
Var, redo_ground(
Done,
X,
G))
| LG0].
414suspend_when_goals([],
_).
415suspend_when_goals([
'$coroutining':internal_freeze(
V,
G)
|Ls],
Done)
:-
417 internal_freeze(
V,
G),
418 suspend_when_goals(
Ls,
Done).
419suspend_when_goals([dif_suspend_on_lvars(
LVars,
G)
|LG],
Done)
:-
421 dif_suspend_on_lvars(
LVars,
G),
422 suspend_when_goals(
LG,
Done).
423suspend_when_goals([
_|_],
_).
438suspend_when_goals
:'$block'(
Conds)
:-
439 generate_blocking_code(
Conds,
_,
Code),
440 '$current_module'(
Module),
441 '$$compile'(
Code,
Code,
5,
Module),
'$$compile'.
442'$$compile'
:'$block'(
_).
444generate_blocking_code(
Conds,
G,
Code)
:-
445 extract_head_for_block(
Conds,
G),
446 recorded(
'$blocking_code',
'$code'(
G,
OldConds),
R),
recorded,
449 '$current_module'(
M),
451 generate_blocking_code((
Conds,
OldConds),
G,
Code).
452generate_blocking_code(
Conds,
G, (
G :- (
If, !, when(
When,
G))))
:-
453 extract_head_for_block(
Conds,
G),
454 recorda(
'$blocking_code',
'$code'(
G,
Conds),
_),
455 generate_body_for_block(
Conds,
G,
If,
When).
460extract_head_for_block((
C1,
_),
G)
:- extract_head_for_block,
461 extract_head_for_block(
C1,
G).
462extract_head_for_block(
C,
G)
:-
486generate_body_for_block((
C1,
C2),
G, (
Code1 -> true
; Code2), (
WhenConds,
OtherWhenConds))
:- generate_body_for_block,
487 generate_for_cond_in_block(
C1,
G,
Code1,
WhenConds),
488 generate_body_for_block(
C2,
G,
Code2,
OtherWhenConds).
489generate_body_for_block(
C,
G, (
Code -> true
; fail),
WhenConds)
:-
490 generate_for_cond_in_block(
C,
G,
Code,
WhenConds).
492generate_for_cond_in_block(
C,
G,
Code,
Whens)
:-
495 fetch_out_variables_for_block(
Args,
GArgs,
L0Vars),
496 add_blocking_vars(
L0Vars,
LVars),
497 generate_for_each_arg_in_block(
LVars,
Code,
Whens).
499add_blocking_vars([], [
_])
:- add_blocking_vars.
500add_blocking_vars(
LV,
LV).
502fetch_out_variables_for_block([], [], []).
503fetch_out_variables_for_block([
'?'|Args], [
_|GArgs],
LV)
:-
504 fetch_out_variables_for_block(
Args,
GArgs,
LV).
505fetch_out_variables_for_block([
'-'|Args], [
GArg|GArgs],
507 fetch_out_variables_for_block(
Args,
GArgs,
LV).
509generate_for_each_arg_in_block([], false, true).
510generate_for_each_arg_in_block([
V], var(
V), nonvar(
V))
:- generate_for_each_arg_in_block.
511generate_for_each_arg_in_block([
V|L], (var(
V),
If), (nonvar(
V)
;Whens))
:-
512 generate_for_each_arg_in_block(
L,
If,
Whens).
518generate_for_each_arg_in_block
:'$wait'(
Na/Ar)
:-
521 '$current_module'(
M),
522 '$$compile'((
S :- var(
A), !, freeze(
A,
S)), (
S :- var(
A), !, freeze(
A,
S)),
5,
M),
'$$compile'.
523'$$compile'
:'$wait'(
_).
535 '$attributes':attvars_residuals([
V],
Gs, []),
536 simplify_frozen(
Gs,
SGs ),
537 list_to_conj(
SGs,
LG ).
538list_to_conj
:frozen(
V,
G)
:-
539 '$do_error'(uninstantiation_error(
V),frozen(
V,
G)).
541simplify_frozen( [prolog
:freeze(
_,
G)
|Gs], [
G|NGs] )
:-
542 simplify_frozen(
Gs,
NGs ).
543simplify_frozen( [prolog
:when(
_,
G)
|Gs], [
G|NGs] )
:-
544 simplify_frozen(
Gs,
NGs ).
545simplify_frozen( [prolog
:dif(
_,
_)
|Gs],
NGs )
:-
546 simplify_frozen(
Gs,
NGs ).
547simplify_frozen( [], [] ).
549list_to_conj([], true).
550list_to_conj([
El],
El).
551list_to_conj([
E,
E1|Els], (
E,
C) )
:-
552 list_to_conj([
E1|Els],
C).
556internal_freeze(
V,
G)
:-
560 update_att
:get_module_atts(
V, att(
'$coroutining',
Gs,[])),
561 not_cjmember(
G,
Gs),
not_cjmember,
562 not_cjmember
:put_module_atts(
V, att(
'$coroutining',(
G,
Gs),[])).
564 update_att
:put_module_atts(
V, att(
'$coroutining',
G,[])).
571not_cjmember(
A, (
G,
H) )
:-
572 not_cjmember((
A,
G),
_ ),
573 not_cjmember((
A,
H),
_).
579 check_first_attvar(
Vs,
V).
581check_first_attvar([
V|_Vs],
V0)
:- attvar(
V),
attvar,
V == V0.
582check_first_attvar([
_|Vs],
V0)
:-
583 check_first_attvar(
Vs,
V0).
588
attribute_goals(+ Var,- Gs,+ GsRest)
get_attr( + Var,+ Module,- Value)
term_variables(? Term, - Variables)
attr_unify_hook(+ AttValue,+ VarValue)