View
4
Download
0
Category
Preview:
Citation preview
Delimited Continuations for Prolog
T. Schrijvers, B. Demoen, B. Desouter and J. Wielemaker
UGent, KU Leuven, UGent and Universiteit Amsterdam
Motivation
1 / 32
Programming patterns
Minimality
Prolog = Horn clauses + simple builtins
⇒ Lack of infrastructure to capture common patterns
Solutions: meta-programming & program transformations
I Definite clause grammars (DCGs)
I Extended DCGs
I Structured state threading
I . . .
2 / 32
Programming patterns
Minimality
Prolog = Horn clauses + simple builtins
⇒ Lack of infrastructure to capture common patterns
Solutions: meta-programming & program transformations
I Definite clause grammars (DCGs)
I Extended DCGs
I Structured state threading
I . . .
2 / 32
Issues with non-local program transformations
1. O (n2) effort
2. Fragile w.r.t. evolution
3. New feature → impact entire system
Introduce DCGs in an existing code base to pass informationthrough several layers.
3 / 32
Our solution: delimited continuations
I Program-level definitions
I More light-weight
I More robust
I No pervasive changes
M. Felleisen, The theory and practice of first-class prompts, ’88O. Danvy & A. Filinski, Abstracting control, ’90
4 / 32
Outline
1. Definition
2. Applications
3. Implementation in the WAM
5 / 32
Definition
6 / 32
Delimited continuation primitives
p :−q ,w r i t e l n ( c ) .
q :−w r i t e l n ( a ) ,w r i t e l n ( b ) .
?− p .abc
7 / 32
Delimited continuation primitives
p :−q ,w r i t e l n ( c ) .
q :−w r i t e l n ( a ) ,w r i t e l n ( b ) .
?− p .abc
7 / 32
Delimited continuation primitives
reset /3 and shift /1
p :−reset( q , , ) ,w r i t e l n ( c ) .
q :−w r i t e l n ( a ) ,shift( ) ,
writeln(b) . ← Continuation
?− p .ac
8 / 32
Delimited continuation primitives
reset /3 and shift /1
p :−reset( q , , ) ,w r i t e l n ( c ) .
q :−w r i t e l n ( a ) ,shift( ) ,
writeln(b) . ← Continuation
?− p .ac
8 / 32
Delimited continuation primitives
p :−r e s e t ( q , , Term ) ,writeln(Term) ,w r i t e l n ( c ) .
q :−w r i t e l n ( a ) ,s h i f t (hello ) ,w r i t e l n ( b ) .
?− p .ahelloc
9 / 32
Delimited continuation primitives
p :−r e s e t ( q , , Term ) ,writeln(Term) ,w r i t e l n ( c ) .
q :−w r i t e l n ( a ) ,s h i f t (hello ) ,w r i t e l n ( b ) .
?− p .ahelloc
9 / 32
Delimited continuation primitives
p :−r e s e t ( q , Cont , ) ,w r i t e l n ( c ) ,call(Cont) .
q :−w r i t e l n ( a ) ,s h i f t ( ) ,w r i t e l n ( b ) .
?− p .acb
No continuation → Cont = 0
10 / 32
Delimited continuation primitives
p :−r e s e t ( q , Cont , ) ,w r i t e l n ( c ) ,call(Cont) .
q :−w r i t e l n ( a ) ,s h i f t ( ) ,w r i t e l n ( b ) .
?− p .acb
No continuation → Cont = 0
10 / 32
Delimited continuation primitives
p :−r e s e t ( q , Cont , ) ,w r i t e l n ( c ) ,call(Cont) .
q :−w r i t e l n ( a ) ,s h i f t ( ) ,w r i t e l n ( b ) .
?− p .acb
No continuation → Cont = 0
10 / 32
Applications
11 / 32
Effect handlers
12 / 32
Implicit state passing
get/1 & put/1 run state /3
i n c :− get(S) , S1 i s S + 1 , put(S1) .
?− run state ( ( i n c , i n c ) , 0 , S ) .S = 2 .
G. Plotkin & M. Pretnar, Handlers of algebraic effects, ’09
13 / 32
Implicit state passing
g e t ( S ) :− s h i f t ( g ( S ) ) .
put ( S ) :− s h i f t ( p ( S ) ) .
14 / 32
g e t ( S ) :− s h i f t ( g ( S ) ) .put ( S ) :− s h i f t ( p ( S ) ) .
r u n s t a t e ( Goal , Sin , Sout ) :−r e s e t ( Goal , Cont , Command ) ,( Cont == 0 →
Sout = S i n; Command = g(S) →
S = Sin ,r u n s t a t e ( Cont , Sin , Sout )
; Command = p(S) →r u n s t a t e ( Cont , S , Sout )
) .
15 / 32
Definite clause grammars
I Well-known Prolog extension
I Sequential access to elements of implicit list
I Conventionally: program transformation
c/1 phrase/3
Grammar (ab)n
ab ( 0 ) .ab (N) :− c( a ) , c( b ) , ab (M) , N i s M + 1 .
?− p h r a s e ( ab (N) , [ a , b , a , b ] , [ ] ) .N = 2 .
16 / 32
Definite clause grammars
I Well-known Prolog extension
I Sequential access to elements of implicit list
I Conventionally: program transformation
c/1 phrase/3
Grammar (ab)n
ab ( 0 ) .ab (N) :− c( a ) , c( b ) , ab (M) , N i s M + 1 .
?− p h r a s e ( ab (N) , [ a , b , a , b ] , [ ] ) .N = 2 .
16 / 32
Definite clause grammars
I Well-known Prolog extension
I Sequential access to elements of implicit list
I Conventionally: program transformation
c/1 phrase/3
Grammar (ab)n
ab ( 0 ) .ab (N) :− c( a ) , c( b ) , ab (M) , N i s M + 1 .
?− p h r a s e ( ab (N) , [ a , b , a , b ] , [ ] ) .N = 2 .
16 / 32
Definite clause grammars
c (E) :− s h i f t ( c (E ) ) .
p h r a s e ( Goal , L in , Lout ) :−r e s e t ( Goal , Cont , Term ) ,( Cont == 0 →
L i n = Lout; Term = c(E) →
L i n = [ E | Lmid ] ,p h r a s e ( Cont , Lmid , Lout )
) .
17 / 32
Applications
I Implicit state
I Implicitenvironments
I Logging
I Exceptions:alternate semantics
I Iterators
I Iteratees
I Coroutines
I Search heuristics (Tor)
I . . .
18 / 32
Composing effect handlers
I Effect handlers easily made compositional
I Propagate unknown operations
Counting ab
ab .ab :− c ( a ) , c ( b ) , inc, ab.
19 / 32
p h r a s e ( Goal , L in , Lout ) :−r e s e t ( Goal , Cont , Term ) ,( Cont == 0 → . . .; Term = c (E) → . . .;
shift( Term ) ,p h r a s e ( Cont , Lin , Lout )
) .
20 / 32
Composing effect handlers
run :−r u n s t a t e (
p h r a s e ( ab , [ a , b , a , b ] , [ ] ) ,0 ,N) ,
write (N ) .
?− run .2
21 / 32
Implementation
22 / 32
Catch&Throw versus Reset&Shift
Goal :− throw ( Term ) .?− c a t c h ( Goal , B a l l , H a n d l e r ) , . . . .
I unify a copy of Term with Ball
I unwind environment & choice point stacks up to catch/3
I Handler is called before control goes to . . .
Goal :− s h i f t ( Term ) .?− r e s e t ( Goal , Cont , B a l l ) , . . . .
I unify Term with Ball
I leave the stacks intact (protect them)
I unify Cont with copy of the environments up to reset /3
I control goes to . . .
23 / 32
Catch&Throw versus Reset&Shift
Goal :− throw ( Term ) .?− c a t c h ( Goal , B a l l , H a n d l e r ) , . . . .
I unify a copy of Term with Ball
I unwind environment & choice point stacks up to catch/3
I Handler is called before control goes to . . .
Goal :− s h i f t ( Term ) .?− r e s e t ( Goal , Cont , B a l l ) , . . . .
I unify Term with Ball
I leave the stacks intact (protect them)
I unify Cont with copy of the environments up to reset /3
I control goes to . . .
23 / 32
Four Issues
I up to reset /3
I how to copy (a delimited part of) the environment stack
I how to use this delimited continuation
I fineprint
24 / 32
Up to reset/3
I catch-throw does this
I so, re-use same principle
I a marker in code or a marker in the environment
I follow the chain of environments, starting at E
protect the stacks: fiddle with the TOS pointer
easy peasy for systems with stack freezing
25 / 32
Up to reset/3
I catch-throw does this
I so, re-use same principle
I a marker in code or a marker in the environment
I follow the chain of environments, starting at E
protect the stacks: fiddle with the TOS pointer
easy peasy for systems with stack freezing
25 / 32
Copying a delimited part of the environment stack I
caveat: it’s not a deep copy !
I if continuation is first-class citizen: easy - e.g. BinProlog
I in WAM more complicated:I env contains code pointer, env pointer and termsI copying whole environment as is can be arbitrarily bad in terms
of live environment slotsI so, want selective copy
I determine live env slotsI live variable map (hProlog, YAP, . . . )I decompilation based (SWI-Prolog, SICStus Prolog, . . . )
26 / 32
Copying a delimited part of the environment stack II
prevE
contP
Env(a/1)
X
YCP
a(X) :− b, c(X,Y), shift(1), d(Y).
The copied environment is a normal Prolog term:
$cont$(abstraction of(CP), 2-[Y] , 2)
A copy of a continuation chain = a list of $cont$/2 terms
27 / 32
Copying a delimited part of the environment stack II
prevE
contP
Env(a/1)
X
YCP
a(X) :− b, c(X,Y), shift(1), d(Y).
The copied environment is a normal Prolog term:
$cont$(abstraction of(CP), 2-[Y] , 2)
A copy of a continuation chain = a list of $cont$/2 terms
27 / 32
Using a copied continuation
Built-in call tailbody/1 uses $cont$(abstraction of(CP), [Y])
a(X) :− b, c(X,Y), shift(1), d(Y).
Env(a/1)
Y
???
???
P
28 / 32
Fineprint
I abstraction of(CP)
I non-determinism
I cut
I executing a continuation twice
I errors
I interaction with catch&throw . . .
29 / 32
Performance
I silly :-)
I catch&throw: linear in depth
I reset & shift : linear in depth and number of variables
goals hProlog SWI-Prologcatch(throw(1), ,true)/reset(shift(1), , ) 2.5/1 2/1depth 10 - no variables 1.4/1 1/3depth 10 - n (live) variables - break even n = 4.5 –
30 / 32
Performance
I silly :-)
I catch&throw: linear in depth
I reset & shift : linear in depth and number of variables
goals hProlog SWI-Prologcatch(throw(1), ,true)/reset(shift(1), , ) 2.5/1 2/1depth 10 - no variables 1.4/1 1/3depth 10 - n (live) variables - break even n = 4.5 –
30 / 32
Summary
Many useful applications: implicit state, implicitenvironments, logging, nonbacktracking exceptions,iterators, iteratees, coroutines, search heuristics, . . .
Program-level definitions
Lightweight implementation in the WAM
I mostly independent
I performance OK
31 / 32
Do you have . . .
Questions?
Answers?Suggestions?
32 / 32
Do you have . . .
Questions?
Answers?Suggestions?
32 / 32
Recommended