Replaying the Past James Koppel MIT Gabriel Scherer INRIA Armando Solar Lezama MIT Nondeterminism choose 3 4 3 4 Splits the world Returns both What language has this ID: 746755
Download Presentation The PPT/PDF document "1 Capturing the Future by" is the property of its rightful owner. Permission is granted to download and print the materials on this web site for personal, non-commercial use only, and to display it on your personal computer provided you do not modify the materials and that you retain all copyright notices contained in the materials. By downloading content from our website, you accept the terms of this agreement.
Slide1
1
Capturing the
Future byReplaying the Past
James Koppel
, MIT
Gabriel Scherer, INRIA
Armando Solar-
Lezama
, MITSlide2
Nondeterminism
choose(
3, 4)
3
4
Splits the world
Returns both
What
language
has this
?
2Slide3
3
>
withNondeterminism(() -> choose(3,4
) * choose(
5
,
6
))
List
([15
,18,20,
24
])
Completely
normalJava program
Java Does!Slide4
4
Delimited Control
1 + reset { let x = shift (λ k
1
+
k (k
5
))
x *
2
}
(aka Delimited Continuations)Slide5
5
Delimited Control
1 + reset {}
shift (
λ
k
1+
k (k 5))
let x =
x * 2
(aka Delimited Continuations)Slide6
1
+ reset {
} 1+(λ x
2
*x)
(
λ
x
2*x)
5
226
Delimited Control
(aka Delimited Continuations)Slide7
7
Delimited Control
3
4
5
Traversal
1
2
shift
Iterator
foo
What
language
has this
?
(aka Delimited Continuations)Slide8
8
Completely normal Java program
> 1
+reset(() ->
2
* shift((k) -> k.
apply
(k.apply(
5
)))) 22
Java Does!Slide9
• Any monadic effect (
callcc, probabilistic programming) • In direct style (no do-notation, no callbacks) • In
almost any
language
(anything
with exceptions + state)
9
We can do:Slide10
Any monadic effect
Delimited control
Fillinski 1994
“Delimited control is the mother of all monads”
10
SetupSlide11
Any monadic effect
Delimited control
Fillinski 1994
Mutable State
Fillinski 1994
call/cc
11
SetupSlide12
Any monadic effect
Delimited control
Fillinski 1994
Mutable State
This work
call/cc
Exceptions
12
SetupSlide13
Thermometer Continuations
Replay-Based
Nondeterminism
Special case
Language of Choice:
13
Overview
thermometerSlide14
withNondeterminism2
(
fn () =>
3
*
choose2
(5
,
6)) [
15
,
18
]
14choose2 (5, 6)
6
5
15
18
Replay-Based
Nondeterminism
:
Easiest VersionSlide15
15
choose2 (5, 6)
6
5
15
18
Replay-Based
Nondeterminism
:
Easiest Version
withNondeterminism
(
fn
()
=>
3
*
choose2
(
5
,
6
))
[
15
,
18
]
val
firstTime
=
ref
false
fun
choose2
(
x1
,
x2
)
=
if
deref
firstTime
then
x1
else
x2
fun
withNondeterminism2
f
=
[ (
firstTime
:=
true
;
f
()
)
, (
firstTime
:=
false
;
f
()
)]Slide16
16
Scaling Up
withNondeterminism
(
fn
()
=>
if
choose
[
true
,
false
]
then
choose
[
5
,
6
]
else
choose
[
7
,
8
,
9
])
choose [true, false
]
choose [5, 6]
choose [7, 8, 9]Slide17
withNondeterminism
(
fn () =>
if
choose
[
true
,
false]
then choose
[
5
,6]
else
choose
[
7
,
8
,
9
])
type
idx
=
int
type
len
=
int
v
al
past
=
(idx * len)
stack
val
future
=
int
stack
17
Scaling Up
0
0
0
1
1
1
2
past
future
idx
len
idx
len
0
2
0
2
cur
cur
cur
Path IndexSlide18
withNondeterminism
(
fn () =>
if
choose
[
true
,
false]
then choose
[
5
,6]
else
choose
[
7
,
8
,
9
])
type
idx
=
int
type
len
=
int
v
al
past
=
(idx * len)
stack
val
future
=
int
stack
18
Scaling Up
0
0
0
1
1
1
2
past
future
idx
len
idx
len
0
2
1
2
Path IndexSlide19
withNondeterminism
(
fn () =>
if
choose
[
true
,
false]
then choose
[
5
,6]
else
choose
[
7
,
8
,
9
])
type
idx
=
int
type
len
=
int
v
al
past
=
(idx * len)
stack
val
future
=
int
stack
19
Scaling Up
0
0
0
1
1
1
2
past
future
idx
len
idx
len
1
2
0
2
cur
cur
curSlide20
withNondeterminism
(
fn () =>
if
choose
[
true
,
false]
then choose
[
5
,6]
else
choose
[
7
,
8
,
9
])
type
idx
=
int
type
len
=
int
v
al
past
=
(idx * len)
stack
val
future
=
int
stack
20
Scaling Up
0
0
0
1
1
1
2
past
future
idx
len
idx
len
1
2
2
0
2
1Slide21
withNondeterminism
(
fn () =>
if
choose
[
true
,
false]
then choose
[
5
,6]
else
choose
[
7
,
8
,
9
])
type
idx
=
int
type
len
=
int
v
al
past
=
(idx * len)
stack
val
future
=
int
stack
21
Scaling Up
0
0
0
1
1
1
2
past
future
idx
len
idx
len
1
2
cur
cur
cur
0
3Slide22
withNondeterminism
(fn
() => print "Hello";
choose
[
1
,
2])
Prints twice!
Quadratic blowup from replay (Benchmarks: Not actually that bad)
No native effects
22
CatchesSlide23
23
Thermometer ContinuationsSlide24
withNondeterminism
(
fn () =>
(
1
+
2
)
*
choose
[5, 6
]
)
withNondeterminism
(fn
()
=>
3
*
)
withNondeterminism
(
fn
()
=>
3
*
)
5
6
Continuations
First copy:
Keep running the program
Second copy:
Replay
24
Nondet: Where are the continuations?Slide25
25
Capturing a Continuation
val f =
reset
(
fn
() =>
let val
x =
effectfulFn1 () val
y
=
effectfulFn2 ()
val yielded =
shift
(
fn
k
=>
k)
in
x
+
y
+
yielded
end
)
3
7
f
=
(
fn
=>
3
+
7
+
)
How to represent?
With theseSlide26
26
Thermometer Continuations
(fn () =>
let
val
x
= effectfulFn1 ()
val
y = effectfulFn2 ()
val
yielded = shift
(fn k =>
k)
in
x
+
y
+
yielded
end
)
f
=
past
3
7
Function
Thermometer ContinuationSlide27
27
Thermometer Continuations
(fn () =>
let
val
x
= effectfulFn1 ()
val
y = effectfulFn2 ()
val
yielded = shift
(fn k =>
k)
in
x
+
y
+
yielded
end
)
f 5
past
Function
3
7Slide28
28
Thermometer Continuations
(fn () =>
let
val
x
= effectfulFn1 ()
val
y = effectfulFn2 ()
val
yielded = shift
(fn k =>
k)
in
x
+
y
+
yielded
end
)
f 5
past
Function
3
7
5Slide29
29
Thermometer Continuations
(fn () =>
let
val
x
= effectfulFn1 ()
val
y = effectfulFn2 ()
val
yielded = shift
(fn k =>
k)
in
x
+
y
+
yielded
end
)
f 5
past
Function
3
future
3
3
7
7
7
5
5
5
(
fn
=>
3
+
7
+
)
The state we were looking forSlide30
30
Implementing
shiftreset (fn
()
=>
shift
(fn
k => concat
[k
3, k
4])
*
shift
(
fn
l
=>
[l
5
,
l
6
])
fun
shift
f
=
case
pop
future
of
SOME
v
=>
...
NONE
=>
(...
raise
(Done
result))
past
future
cur_fn
k =
cur_fn
past
cur_fn
Exception
reset
(
fn
()
=>
shift
(
fn
k
=>
concat
[k
3
,
k
4
])
*
shift
(
fn
l
=>
[l
5
,
l
6
])
past
future
3
3
cur_fn
past
3
l =
cur_fn
3
Exception
cur_fnSlide31
31
Implementing
shiftfun shift
f
=
case
pop
future
of SOME
v
=>
...
NONE =>
(...
raise
(Done
result))
k =
cur_fn
l =
cur_fn
3
[l
5
,
l
6
]
concat [k
3
,
k
4
]Slide32
32
Implementing
shiftfun shift
f
=
case
pop
future
of SOME
v
=>
...
NONE =>
(...
raise
(Done
result))
k =
cur_fn
l =
cur_fn
3
[l
5
,
l
6
]
concat [k
3
,
k
4
]
cur_fn
3
reset
(
fn
()
=>
shift
(
fn
k
=>
concat
[k
3
,
k
4
])
*
shift
(
fn
l
=>
[l
5
,
l
6
])
past
future
3
5
3
5
15
18
[15, 18]
[20, 24]
Final answer: [15, 18, 20, 24]Slide33
33
Efficiency
Asymptotic blowup: quadratic in # calls to shiftLast example: 7 total replays
Practical worst case
withNondeterminism (
fn
()
=>
long_running_computation (); choose [1
,
2
,
3,4,5,
6,7,8,
9
,
10
])Slide34
34
Benchmark:
N-queensSlide35
35
n = 13
Replay-Based
Indirect
7s
2s
Thermometer
14s
Therm. Opt
7s
callcc
3s
Indirect
1.3s
Therm Opt.
3.9s
Delimcc
14.4s
Indirect
1.1s
Replay-Based
4.3s
callcc
12.6s
GNU
Prolog
>20min
20s
(Both PAKCS, KiCS2)
for
n=11
2minSlide36
36
Nested
shift
’s
Optimized thermometer continuations
Fused with Fillinski construction. Less replay/stack-usage
Theorem (
Thielecke
, 2001): Exceptions and state cannot “macro-express” call/cc
Why this doesn’t stop us
Correctness proof of nondeterminism
More benchmarks
Also in the paperSlide37
37
THANK YOU!
James Koppel
, MIT
Gabriel Scherer, INRIA
Armando Solar-
Lezama
, MIT
www.thermometer-continuations.comSlide38
0.011
0.064
0.173
38
Benchmark:
N-queens
Replay-Based
10
11
12
13
0.021
0.164
Times (s)
n
1.051
6.526
Thermometer
Therm Opt.
0.060
0.344
2.152
14.305
0.003
1.151
6.793
callcc
Indirect
0.079
0.015
0.493
2.941
0.360
2.166
10
11
12
13
Times (s)
n
Delimcc
0.185
0.035
1.236
14.412
Therm Opt.
0.111
0.019
0.650
3.924
callcc
0.399
0.078
2.138
12.620
Replay-
based
0.099
0.016
0.637
4.295
Times (s)
nSlide39
39
Benchmark:
N-queens
Plan: Show Replay, then Therm and Therm Opt., then Indirect and callcc .
Then Show Ocaml Delimcc/Therm Opt, and MLTon Replay/Callcc.
Then show Prolog.