Message passing concurrency
Choreographies are a way of describing communicating systems as global programs
A
B
A
B
A.x -> B.x
A.x -> B.x
A
Send("B",x)
B
x = Receive("A")
A.x -> B.x
let y@A = foo()
let w@B = bar()
A
Send("B",x)
y = foo()
B
x = Receive("A")
w = bar()
A.x -> B.x
let y@A = foo()
let w@B = bar()
A.x -> B.x
let y@A = foo()
let w@B = bar()
if y@A
A->B[T]
...
else
A->B[F]
...
A.x -> B.x
let y@A = crunch()
let w@B = crunch()
if y@A
A->B[T]
...
else
A->B[F]
...
A
if y
Choose("B",T)
...
else
Choose("B",F)
...
B
if Choice("A")
...
else
...
A.x -> B.x
B.y -> C.y
...
A.x -> B.x
B.y -> C.y
...
G | ::= |
A.x -> B.y; G | (com) |
| |
A -> B[b]; G | (sel) | |
| |
Let x@A = foo(..); G | (let) | |
| |
If x@A
Then G
Else G | (if) | |
| |
Fix fn G | (fix) | |
| |
Call fn | (call) | |
| |
End | (end) |
Where:
Communication
A.x -> B.y;C
Communication
S
A.x -> B.y;C
Communication
S(A,x) = d
A.x -> B.y;C
Communication
A.x -> B.y;C
S[(B,y)|->d]
Communication
S[(B,y)|->d]
C
Deadlock-freedom
$\text{fv}(c) \subseteq \text{fv}(s)$ |
$c\equiv end \lor \exists{s' c'.}{(s,c) \rightarrow (s',c')}$ |
A.x -> B.x
B.y -> C.y
...
A.x -> B.x
B.y -> C.y
...
EPN
let x@A = [1,2,3]
A.x -> B.y
let y@B = sort x
B.y -> A.y
...
A
Let x = [1,2,3]
Send B x
Receive A y
...
B
Receive A x
Let y = sort x
Send A y
...
A
Let x = [1,2,3]
Send B x
Receive A y
...
B
Receive A x
Let y = sort x
Send A y
...
A
let x = [1,2,3]
let _ = #send B x
let x = #receive A
...
B
let x = #receive A
let y = sort x
let _ = #send A y
...
Semantic preservation
$(s,c)\xrightarrow{}(s',c')$ |
$\exists{c'',s''.\;}(s',c')\rightarrow^{\ast}(s'',c'')\,\land\, [\![s,c]\!]\rightarrow^{\ast}[\![s'',c'']\!]$ |
Semantic reflection
$[\![s,c]\!]\xrightarrow{}epn$ |
$\exists{c',s'.\;}epn\rightarrow^{\ast}[\![s',c']\!]\,\land\, (s,c)\rightarrow^{\ast}(s',c')$ |
A.x -> B.x
B.y -> C.y
...
EPN
EPN
EPN
Selection
Payload
Closure
A.x -> B.x
B.y -> A.y
...
A.x -> B.x
B.y -> A.y
...
Send
and Receive
are FFI primitivesEPN
<-
->
Selection
<-
->
Payload
<-
->
Closure
<-
->
* Cumbersome and repetitive
'a 'e 'r itree =
Ret 'r
| Tau ('a 'e 'r itree)
| Vis 'e ('a -> 'a 'e 'r itree)
A
x = foo()
Send("B",x)
y = Receive("B")
return y
Itree A
A
x = foo()
Send("B",x)
y = Receive("B")
return y
Tau
(
Itree A
)
A
x = foo()
Send("B",x)
y = Receive("B")
return y
Tau
(
Vis (Send B x)
(
λ_->
Itree A
)
)
A
x = foo()
Send("B",x)
y = Receive("B")
return y
Tau
(
Vis (Send B x)
(
λ_->
Itree A
)
)
A
x = foo()
Send("B",x)
y = Receive("B")
return y
(
λ_->
Itree A
)
0
A
x = foo()
Send("B",x)
y = Receive("B")
return y
(
λ_->
Itree A
)
0
Vis (Receive B)
(λy-> Ret y)
A
x = foo()
Send("B",x)
y = Receive("B")
return y
Vis (Receive B)
(λy-> Ret y)
(λy-> Ret y)
(λy-> Ret y)
5
10
100
(λy-> Ret y)
5
Ret 5
10
Ret 10
100
Ret 100
interp : ('a 'e 'r) itree
->
'r
interp : ('a 'e 'r) itree
->
'i
interp (Ret n) = n
interp (Tau t) = interp t
interp (Vis (Send p x) f) = interp (f 0)
interp (Vis (Receive p) f) = interp (f 5)
->
ðŽ?
A.x -> B.x
B.y -> C.y
...
Vis (Send "B" 5) fa
...
fa Ok
(B,A) |-> x
...
(B,A) |-> x
Vis (Receive A) fb
fb x
iforest =
<| forest : 'p |-> ('a,'e,'r) itree
st : 's
act : 's -> 'p -> 'e -> 'a option;
upd : 's -> 'p -> 'e -> 's;
|>
s : 'p ⚯ 'p |-> 'a
chor_act s p (Send q x) = SOME Ok
chor act s p (Receive q) = lookup s (p,q)
...
chor_upd s p (Send q x) =
s with queue := update s (q,p) (Msg x)
...
An interaction forest interpreter
[
("A",Int),
("B",Int),
("A",Ext (Send "B" x)),
("C",Int),
("B",Ext (Receive "A"))
...
]
Kalas
EPN
Kalas
EPN