SlideShare ist ein Scribd-Unternehmen logo
1 von 133
Downloaden Sie, um offline zu lesen
Keigo Imai1
(with Rumyana Neykova2, Nobuko Yoshida3 and Shoji Yuen4)
1Gifu University (JP) 2Brunel University London (UK)
3Imperial College London (UK) 4Nagoya University (JP)
PLAS Group Seminar, University of Kent
16th Sept. 2019
1
Global Protocol Combinators:
Static Structural Multiparty Sessions Over
Simply Typed Channels
in OCaml
2
(A supplemental slide at VeTSS 2019 workshop lightning talk)
Deadlocks in message-passing concurrency: Protocols prevent them!
3
A
B C
A ring-form
multiparty
communication:
Concurrent
programming is difficult!
Deadlocks in message-passing concurrency: Protocols prevent them!
4
A
B C
A ring-form
multiparty
communication:
Concurrent
programming is difficult!
C
wrong usage (direction)…
② input① output
order matters…
Deadlocks in message-passing concurrency: Protocols prevent them!
5
A
B C
A ring-form
multiparty
communication:
Concurrent
programming is difficult!
A B C
Communication protocol!
C
wrong usage (direction)…
② input① output
order matters…
Deadlocks in message-passing concurrency: Protocols prevent them!
6
A
B C
A ring-form
multiparty
communication:
Concurrent
programming is difficult!
A B C
Communication protocol!
C
wrong usage (direction)…
② input① output
order matters…
Best practice:
1. Design a communication protocol and check it
2. Focus on its local behaviours
3. Enforce protocol in the program code
deadlock-free?
Multiparty Session Types (MPSTs): Protocol-based deadlock freedom
7
C S
a "ping" protocol
③ Give concurrent processes (programs) and check their types
① Write a Global Type and check it
② Derive Local Types by End Point Projection (↾)
PC | PS
The system PC | PS is
[Honda et al., 2008]
deadlock-free?
Multiparty Session Types (MPSTs): Protocol-based deadlock freedom
8
C S
a "ping" protocol
③ Give concurrent processes (programs) and check their types
① Write a Global Type and check it
② Derive Local Types by End Point Projection (↾)
PC | PS
The system PC | PS is
"well-formed": protocol G iswf(G) ✔
G = C → S. S → C.end
deadlock-free
[Honda et al., 2008]
deadlock-free?
Multiparty Session Types (MPSTs): Protocol-based deadlock freedom
9
C S
a "ping" protocol
③ Give concurrent processes (programs) and check their types
① Write a Global Type and check it
② Derive Local Types by End Point Projection (↾)
PC | PS
The system PC | PS is
"well-formed": protocol G iswf(G) ✔
G = C → S. S → C.end
deadlock-free
G↾C = LC = LSG↾S
S! S?
C? C!
LC =
LS =
: "views" of the protocol
[Honda et al., 2008]
deadlock-free?
Multiparty Session Types (MPSTs): Protocol-based deadlock freedom
10
C S
a "ping" protocol
③ Give concurrent processes (programs) and check their types
① Write a Global Type and check it
② Derive Local Types by End Point Projection (↾)
PC | PS
The system PC | PS is
✔✔ : "these processes respect the protocol"PSPC LS ⊢LC ⊢
"well-formed": protocol G iswf(G) ✔
G = C → S. S → C.end
deadlock-free
G↾C = LC = LSG↾S
S! S?
C? C!
LC =
LS =
: "views" of the protocol
[Honda et al., 2008]
deadlock-free?
Multiparty Session Types (MPSTs): Protocol-based deadlock freedom
11
C S
a "ping" protocol
③ Give concurrent processes (programs) and check their types
① Write a Global Type and check it
② Derive Local Types by End Point Projection (↾)
PC | PS
The system PC | PS is
✔✔ : "these processes respect the protocol"PSPC LS ⊢LC ⊢
"well-formed": protocol G iswf(G) ✔
G = C → S. S → C.end
deadlock-free
G↾C = LC = LSG↾S
S! S?
C? C!
LC =
LS =
: "views" of the protocol
deadlock-free!
[Honda et al., 2008]
deadlock-free?
Multiparty Session Types (MPSTs): Protocol-based deadlock freedom
12
C S
a "ping" protocol
③ Give concurrent processes (programs) and check their types
① Write a Global Type and check it
② Derive Local Types by End Point Projection (↾)
PC | PS
The system PC | PS is
✔✔ : "these processes respect the protocol"PSPC LS ⊢LC ⊢
"well-formed": protocol G iswf(G) ✔
G = C → S. S → C.end
deadlock-free
G↾C = LC = LSG↾S
S! S?
C? C!
LC =
LS =
: "views" of the protocol
deadlock-free!
[Honda et al., 2008]
How to implement MPSTs
in a programming language?
Question
③ LC ⊢ PC ?
Go
Thread
State of the art: Deadlock freedom via code generation
13
① wf(G) ?
② G↾C
Global
Protocol File
Go
Thread
Go
Thread
In a MPST toolchain for programming language Go [D. Castro et al., POPL 2019]:
③ LC ⊢ PC ?
Go
Thread
State of the art: Deadlock freedom via code generation
14
① wf(G) ?
② G↾C
Global
Protocol File
Go
Thread
Go
Thread
In a MPST toolchain for programming language Go [D. Castro et al., POPL 2019]:
deadlock-free
(Well-formedness checking
and End Point Projection)
Go type
(Generated
code)
Go type
(Generated
code)
Go type
(Generated
code)
Code
generation
✔
③ LC ⊢ PC ?
Type checking
by
Go compiler
✔ (type checking to check
protocol conformance)
Go
Thread
State of the art: Deadlock freedom via code generation
15
① wf(G) ?
② G↾C
Global
Protocol File
Go
Thread
Go
Thread
In a MPST toolchain for programming language Go [D. Castro et al., POPL 2019]:
deadlock-free
(Well-formedness checking
and End Point Projection)
Go type
(Generated
code)
Go type
(Generated
code)
Go type
(Generated
code)
Code
generation
✔
③ LC ⊢ PC ?
Type checking
by
Go compiler
✔ (type checking to check
protocol conformance)
Go
Thread
State of the art: Deadlock freedom via code generation
16
① wf(G) ?
② G↾C
Global
Protocol File
Go
Thread
Go
Thread
In a MPST toolchain for programming language Go [D. Castro et al., POPL 2019]:
deadlock-free
(Well-formedness checking
and End Point Projection)
Go type
(Generated
code)
Go type
(Generated
code)
Go type
(Generated
code)
Code
generation
✔
deadlock-free
③ LC ⊢ PC ?
Type checking
by
Go compiler
✔ (type checking to check
protocol conformance)
Go
Thread
State of the art: Deadlock freedom via code generation
17
① wf(G) ?
② G↾C
Global
Protocol File
Go
Thread
Go
Thread
In a MPST toolchain for programming language Go [D. Castro et al., POPL 2019]:
deadlock-free
(Well-formedness checking
and End Point Projection)
Go type
(Generated
code)
Go type
(Generated
code)
Go type
(Generated
code)
Code
generation
✔
deadlock-free
Is it possible to implement MPSTs
without code generation?
Question
③ LC ⊢ PC ?
① wf(G) ?
② G↾C
Global Protocol Combinator : Deadlock freedom solely by Types!
18
Yes (!) How?
↓ A single OCaml program code file (.ml)
OCaml
Thread
OCaml
Thread
OCaml
Thread
Protocol
in OCaml
③ LC ⊢ PC ?
① wf(G) ?
② G↾C
Global Protocol Combinator : Deadlock freedom solely by Types!
19
Yes (!) How?
↓ A single OCaml program code file (.ml)
OCaml
Thread
OCaml
Thread
OCaml
Thread
Protocol
in OCaml
③ LC ⊢ PC ?
① wf(G) ?
② G↾C
Global Protocol Combinator : Deadlock freedom solely by Types!
20
✔
deadlock-free
OCaml types OCaml types OCaml types
Type
checking &
inference
Yes (!) How?
↓ A single OCaml program code file (.ml)
OCaml
Thread
OCaml
Thread
OCaml
Thread
Protocol
in OCaml
③ LC ⊢ PC ?
① wf(G) ?
② G↾C
Global Protocol Combinator : Deadlock freedom solely by Types!
21
Type checking
by
OCaml compiler
✔
✔
deadlock-free
OCaml types OCaml types OCaml types
Type
checking &
inference
Yes (!) How?
↓ A single OCaml program code file (.ml)
OCaml
Thread
OCaml
Thread
OCaml
Thread
Protocol
in OCaml
③ LC ⊢ PC ?
① wf(G) ?
② G↾C
Global Protocol Combinator : Deadlock freedom solely by Types!
22
Type checking
by
OCaml compiler
✔
✔
deadlock-free
OCaml types OCaml types OCaml types
Type
checking &
inference
Yes (!)
deadlock-free!
How?
↓ A single OCaml program code file (.ml)
OCaml
Thread
OCaml
Thread
OCaml
Thread
Protocol
in OCaml
③ LC ⊢ PC ?
① wf(G) ?
② G↾C
Global Protocol Combinator : Deadlock freedom solely by Types!
23
Type checking
by
OCaml compiler
✔
✔
deadlock-free
OCaml types OCaml types OCaml types
Type
checking &
inference
Yes (!)
deadlock-free!
How?
How/why do they work??
Global Combinators and well-formedness check
24
① wf(G) ✔
let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish))
(r1 --> r2) lab : send a label lab from r1 to r2 (with possible payloads)
Example: Simple OAuth protocol
s c a
Global Combinators and well-formedness check
25
① wf(G) ✔
let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish))
(r1 --> r2) lab : send a label lab from r1 to r2 (with possible payloads)
Example: Simple OAuth protocol
s c a
Global Combinators and well-formedness check
26
① wf(G) ✔
let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish))
(r1 --> r2) lab : send a label lab from r1 to r2 (with possible payloads)
Example: Simple OAuth protocol
s c a
Global Combinators and well-formedness check
27
① wf(G) ✔
let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish))
(r1 --> r2) lab : send a label lab from r1 to r2 (with possible payloads)
Example: Simple OAuth protocol
s c a
let oauth_branch =
choice_at s (to_c login_or_cancel)
(s, (s --> c) login ((c --> a) password ((a --> c) auth finish)))
(s, (s --> c) cancel ((c --> a) quit finish))
choice_at r g1 g2 : decide a protocol branching at r, between g1 and g2
Example: Adding a branch to Simple OAuth protocol
(a few plumbings needed to convince the type checker)
Each branch must begin from s
Global Combinators and well-formedness check
28
① wf(G) ✔
let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish))
(r1 --> r2) lab : send a label lab from r1 to r2 (with possible payloads)
Example: Simple OAuth protocol
s c a
let oauth_branch =
choice_at s (to_c login_or_cancel)
(s, (s --> c) login ((c --> a) password ((a --> c) auth finish)))
(s, (s --> c) cancel ((c --> a) quit finish))
choice_at r g1 g2 : decide a protocol branching at r, between g1 and g2
NB: Branching in a protocol is a source of concurrency issues
(a few plumbings needed to convince the type checker)
Global Combinators and well-formedness check
29
① wf(G) ✔
let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish))
(r1 --> r2) lab : send a label lab from r1 to r2 (with possible payloads)
Example: Simple OAuth protocol
s c a
let oauth_branch =
choice_at s (to_c login_or_cancel)
(s, (s --> c) login ((c --> a) password ((a --> c) auth finish)))
(s, (s --> c) cancel ((c --> a) quit finish))
choice_at r g1 g2 : decide a protocol branching at r, between g1 and g2
NB: Branching in a protocol is a source of concurrency issues
(a few plumbings needed to convince the type checker)
Non-determinism/
Deadlock
in a protocol
a
Global Combinators and well-formedness check
30
① wf(G) ✔
let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish))
(r1 --> r2) lab : send a label lab from r1 to r2 (with possible payloads)
Example: Simple OAuth protocol
s c a
let oauth_branch =
choice_at s (to_c login_or_cancel)
(s, (s --> c) login ((c --> a) password ((a --> c) auth finish)))
(s, (s --> c) cancel ((c --> a) quit finish))
choice_at r g1 g2 : decide a protocol branching at r, between g1 and g2
NB: Branching in a protocol is a source of concurrency issues
(a few plumbings needed to convince the type checker)
… is reported as a type error
Non-determinism/
Deadlock
in a protocol
a
(Deadlock and type errors: An analysis)
31
let oauth_branch =
choice_at s (to_c login_or_cancel)
(s, (s --> c) login ((c --> a) password ((a --> c) auth finish)))
(s, (s --> c) cancel ((c --> a) quit finish))a
poke a instead of c
The MPST theory rejects it: they are not "mergeable".
Forming a "mixed choice" (which causes nondeterminism)
c's first action is input from s
c's first action is output to a
Deriving local types via type inference
OCaml infers Local Types from global combinators.
32
② G↾C
let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish))
Example (again): Simple OAuth protocol
s c a
All local types are inferred at once, as a cons-list of structural types (here, s=0, c=1, a=2):
Deriving local types via type inference
OCaml infers Local Types from global combinators.
33
② G↾C
let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish))
Example (again): Simple OAuth protocol
s c a
All local types are inferred at once, as a cons-list of structural types (here, s=0, c=1, a=2):
val oauth :
[ `cons of
< role_C : < login : ('a * close) out lin > > *
[ `cons of
< role_S : [> `login of 'a *
< role_A : < password : ('b *
< role_A : [> `auth of 'c *
close ] inp lin >) out lin > > ] inp lin > *
[ `cons of
< role_C : [> `password of 'b *
< role_C : < auth : ('c *
close) out lin > > ] inp lin > *
([ `cons of close * 'x ] as 'x) ] ] ] Seq.t
c!login
s?login a!pass a?auth
s!pass s?auth
s
c
a
Deriving local types via type inference
OCaml infers Local Types from global combinators.
34
② G↾C
let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish))
Example (again): Simple OAuth protocol
s c a
All local types are inferred at once, as a cons-list of structural types (here, s=0, c=1, a=2):
val oauth :
[ `cons of
< role_C : < login : ('a * close) out lin > > *
[ `cons of
< role_S : [> `login of 'a *
< role_A : < password : ('b *
< role_A : [> `auth of 'c *
close ] inp lin >) out lin > > ] inp lin > *
[ `cons of
< role_C : [> `password of 'b *
< role_C : < auth : ('c *
close) out lin > > ] inp lin > *
([ `cons of close * 'x ] as 'x) ] ] ] Seq.t
c!login
s?login a!pass a?auth
s!pass s?auth
s
c
a
Destination role's names are a method of an object
< role_S
< role_A
< role_A
Deriving local types via type inference
OCaml infers Local Types from global combinators.
35
② G↾C
let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish))
Example (again): Simple OAuth protocol
s c a
All local types are inferred at once, as a cons-list of structural types (here, s=0, c=1, a=2):
val oauth :
[ `cons of
< role_C : < login : ('a * close) out lin > > *
[ `cons of
< role_S : [> `login of 'a *
< role_A : < password : ('b *
< role_A : [> `auth of 'c *
close ] inp lin >) out lin > > ] inp lin > *
[ `cons of
< role_C : [> `password of 'b *
< role_C : < auth : ('c *
close) out lin > > ] inp lin > *
([ `cons of close * 'x ] as 'x) ] ] ] Seq.t
c!login
s?login a!pass a?auth
s!pass s?auth
s
c
a
Output labels are methods in an object
< password
Destination role's names are a method of an object
< role_S
< role_A
< role_A
Deriving local types via type inference
OCaml infers Local Types from global combinators.
36
② G↾C
let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish))
Example (again): Simple OAuth protocol
s c a
All local types are inferred at once, as a cons-list of structural types (here, s=0, c=1, a=2):
val oauth :
[ `cons of
< role_C : < login : ('a * close) out lin > > *
[ `cons of
< role_S : [> `login of 'a *
< role_A : < password : ('b *
< role_A : [> `auth of 'c *
close ] inp lin >) out lin > > ] inp lin > *
[ `cons of
< role_C : [> `password of 'b *
< role_C : < auth : ('c *
close) out lin > > ] inp lin > *
([ `cons of close * 'x ] as 'x) ] ] ] Seq.t
c!login
s?login a!pass a?auth
s!pass s?auth
s
c
a
Input labels are (polymorphic) variant type tags
[ `login
[ `auth
Output labels are methods in an object
< password
Destination role's names are a method of an object
< role_S
< role_A
< role_A
let ch = get_ch c oauth (* get a MPST channel for s *)
val ch :
< role_S : [> `login of 'a *
< role_A : < password : ('b *
< role_A : [> `auth of 'c *
close ] inp lin >) out lin > > ] inp lin >
OCaml>
let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish))
let thread_C () =
match receive ch#role_S with
| `login((u:string), ch)->
let ch = send ch#role_A#password "asdf" in
match receive ch#role_A with
| `auth((b:bool), ch) ->
close ch
Protocol conformance via OCaml's type checking
37
③ LC ⊢ PC ✔
let ch = get_ch c oauth (* get a MPST channel for s *)
val ch :
< role_S : [> `login of 'a *
< role_A : < password : ('b *
< role_A : [> `auth of 'c *
close ] inp lin >) out lin > > ] inp lin >
OCaml>
let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish))
let thread_C () =
match receive ch#role_S with
| `login((u:string), ch)->
let ch = send ch#role_A#password "asdf" in
match receive ch#role_A with
| `auth((b:bool), ch) ->
close ch
Protocol conformance via OCaml's type checking
38
< role_S
Select destination role via method invocation (#)
role_S
③ LC ⊢ PC ✔
let ch = get_ch c oauth (* get a MPST channel for s *)
val ch :
< role_S : [> `login of 'a *
< role_A : < password : ('b *
< role_A : [> `auth of 'c *
close ] inp lin >) out lin > > ] inp lin >
OCaml>
let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish))
let thread_C () =
match receive ch#role_S with
| `login((u:string), ch)->
let ch = send ch#role_A#password "asdf" in
match receive ch#role_A with
| `auth((b:bool), ch) ->
close ch
Protocol conformance via OCaml's type checking
39
< role_S
Select destination role via method invocation (#)
role_S
③ LC ⊢ PC ✔
[ `login
`login
… and receive on it, then pattern-match the value against variant tags (labels)
received payload
let ch = get_ch c oauth (* get a MPST channel for s *)
val ch :
< role_S : [> `login of 'a *
< role_A : < password : ('b *
< role_A : [> `auth of 'c *
close ] inp lin >) out lin > > ] inp lin >
OCaml>
let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish))
let thread_C () =
match receive ch#role_S with
| `login((u:string), ch)->
let ch = send ch#role_A#password "asdf" in
match receive ch#role_A with
| `auth((b:bool), ch) ->
close ch
Protocol conformance via OCaml's type checking
40
< role_S
Select destination role via method invocation (#)
role_S
③ LC ⊢ PC ✔
[ `login
`login
… and receive on it, then pattern-match the value against variant tags (labels)
received payload
"Next" channel is supplied as a part of the returned value
let ch = get_ch c oauth (* get a MPST channel for s *)
val ch :
< role_S : [> `login of 'a *
< role_A : < password : ('b *
< role_A : [> `auth of 'c *
close ] inp lin >) out lin > > ] inp lin >
OCaml>
let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish))
let thread_C () =
match receive ch#role_S with
| `login((u:string), ch)->
let ch = send ch#role_A#password "asdf" in
match receive ch#role_A with
| `auth((b:bool), ch) ->
close ch
Protocol conformance via OCaml's type checking
41
< role_S
Select destination role via method invocation (#)
role_S
< role_A
role_A
③ LC ⊢ PC ✔
[ `login
`login
… and receive on it, then pattern-match the value against variant tags (labels)
received payload
"Next" channel is supplied as a part of the returned value
let ch = get_ch c oauth (* get a MPST channel for s *)
val ch :
< role_S : [> `login of 'a *
< role_A : < password : ('b *
< role_A : [> `auth of 'c *
close ] inp lin >) out lin > > ] inp lin >
OCaml>
let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish))
let thread_C () =
match receive ch#role_S with
| `login((u:string), ch)->
let ch = send ch#role_A#password "asdf" in
match receive ch#role_A with
| `auth((b:bool), ch) ->
close ch
Protocol conformance via OCaml's type checking
42
< role_S
Select destination role via method invocation (#)
role_S
< role_A
role_A
③ LC ⊢ PC ✔
[ `login
`login
… and receive on it, then pattern-match the value against variant tags (labels)
received payload
"Next" channel is supplied as a part of the returned value
< password
#password
Select an output label via method invocation (#), then
send it with a payload
let ch = get_ch c oauth (* get a MPST channel for s *)
val ch :
< role_S : [> `login of 'a *
< role_A : < password : ('b *
< role_A : [> `auth of 'c *
close ] inp lin >) out lin > > ] inp lin >
OCaml>
let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish))
let thread_C () =
match receive ch#role_S with
| `login((u:string), ch)->
let ch = send ch#role_A#password "asdf" in
match receive ch#role_A with
| `auth((b:bool), ch) ->
close ch
Protocol conformance via OCaml's type checking
43
< role_S
Select destination role via method invocation (#)
role_S
< role_A
role_A
role_A
< role_A
③ LC ⊢ PC ✔
[ `login
`login
… and receive on it, then pattern-match the value against variant tags (labels)
received payload
"Next" channel is supplied as a part of the returned value
< password
#password
Select an output label via method invocation (#), then
send it with a payload
let ch = get_ch c oauth (* get a MPST channel for s *)
val ch :
< role_S : [> `login of 'a *
< role_A : < password : ('b *
< role_A : [> `auth of 'c *
close ] inp lin >) out lin > > ] inp lin >
OCaml>
let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish))
let thread_C () =
match receive ch#role_S with
| `login((u:string), ch)->
let ch = send ch#role_A#password "asdf" in
match receive ch#role_A with
| `auth((b:bool), ch) ->
close ch
Protocol conformance via OCaml's type checking
44
< role_S
Select destination role via method invocation (#)
role_S
< role_A
role_A
`auth
[ `auth
role_A
< role_A
③ LC ⊢ PC ✔
[ `login
`login
… and receive on it, then pattern-match the value against variant tags (labels)
received payload
"Next" channel is supplied as a part of the returned value
< password
#password
Select an output label via method invocation (#), then
send it with a payload
let ch = get_ch s oauth (* get a MPST channel for s *)
val ch :
< role_S : [> `login of 'a *
< role_A : < password : ('b *
< role_A : [> `auth of 'c *
close ] inp lin >) out lin > > ] inp lin >
OCaml>
let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish))
let thread_C () =
match receive ch#role_S with
| `login((u:string), ch)->
let ch = send ch#role_A#password "asdf" in
match receive ch#role_A with
| `auth((b:bool), ch) ->
close ch
45
Protocol conformance via OCaml's type checking③ LC ⊢ PC ✔
ro
If there is a
typo …
OCaml reports a type error at this point
↓ A single OCaml Source code file (.ml)
OCaml
Program
OCaml
Program
OCaml
Program
Protocol
in OCaml
③ LC ⊢ PC ?
① wf(G) ?
② G↾C
Global Protocol Combinator : Deadlock freedom by Types!
46
Type checking
by
OCaml compiler
✔
✔
deadlock-free
OCaml types OCaml types OCaml types
Type
checking
& inference
Recap
deadlock-free!
↓ A single OCaml Source code file (.ml)
OCaml
Program
OCaml
Program
OCaml
Program
Protocol
in OCaml
③ LC ⊢ PC ?
① wf(G) ?
② G↾C
Global Protocol Combinator : Deadlock freedom by Types!
47
Type checking
by
OCaml compiler
✔
✔
deadlock-free
OCaml types OCaml types OCaml types
Type
checking
& inference
Recap
deadlock-free!
Are they really correct??
GPC: Are they correct
48
A. Key idea: Global Combinators pre-generate channels
❖ Multiparty channels as nested sequence of simply-typed channels
B. Formalisation of GPC with Deadlock-freedom Theorem
❖ OCamlM: A minimal concurrent language
❖ Typing rules for Global Combinators
C. Implementation: GPC as a typed DSL in OCaml
❖ Based on a set of type manipulation techniques
(GADTs, field label encoding, and plumbings such as polymorphic record extension)
GPC key ingredients
GPC: Are they correct
49
A. Key idea: Global Combinators pre-generate channels
❖ Multiparty channels as nested sequence of simply-typed channels
B. Formalisation of GPC with Deadlock-freedom Theorem
❖ OCamlM: A minimal concurrent language
❖ Typing rules for Global Combinators
C. Implementation: GPC as a typed DSL in OCaml
❖ Based on a set of type manipulation techniques
(GADTs, label encoding, and plumbings such as polymorphic record extension)
GPC key ingredients
50
Let's start cooking!!
A. Key idea: Global Combinators pre-generate channels
A. Key idea: Global Combinators pre-generate channels
51
S
C A
⟨⟩ ⟨⟩
⟨⟩
let oAuth = finish
A. Key idea: Global Combinators pre-generate channels
52
S
C A
Sauth
⟨?Sauth⟩ ⟨!Sauth⟩
⟨⟩
let oAuth = (A → C) auth finish
A. Key idea: Global Combinators pre-generate channels
53
let oAuth = (C → A) password ((A → C) auth finish)
S
C A
Sauth
Spasswd
⟨!Spasswd; ?Sauth⟩ ⟨?Spasswd; !Sauth⟩
⟨⟩
A. Key idea: Global Combinators pre-generate channels
54
let oAuth = (S → C) login ((C → A) password ((A → C) auth finish))
S
C
A
⟨?Slogin ; !Spasswd; ?Sauth.0 ⟩ ⟨?Spasswd; !Sauth⟩
Sauth
Spasswd
Slogin
⟨!Slogin ⟩
A. Key idea: Global Combinators pre-generate channels
55
let oAuth = (S → C) login ((C → A) password ((A → C) auth finish))
S
C
A
⟨?Slogin ; !Spasswd; ?Sauth.0 ⟩ ⟨?Spasswd; !Sauth⟩
Sauth
Spasswd
Slogin
⟨!Slogin ⟩
Distribute them and start the communication
56
PS
PC
PA
!Slogin.0| ?Slogin ; !Spasswd; ?Sauth.0| ?Spasswd;!Sauth.0
Distribute them and start the communication
57
PS
PC
PA
0| !Spasswd; ?Sauth.0| ?Spasswd;!Sauth.0
Distribute them and start the communication
58
PS
PC
PA
0| ?Sauth.0| !Sauth.0
Distribute them and start the communication
59
PS
PC
PA
0| 0| 0
Distribute them and start the communication
60
PS
PC
PA
!Slogin.0| ?Slogin ; !Spasswd; ?Sauth.0| ?Spasswd;!Sauth.0
❖ All these channels are simply-typed (hence no type-errors)
❖ Global combinators aim to be deadlock-free
❖ The nested structure enforces usage order
Point
GPC: Are they correct? (cont.)
61
A. Key idea: Global Combinators pre-generate channels
❖ Multiparty channels as nested sequence of simply-typed channels
B. Formalisation of GPC (with Deadlock-freedom Theorem)
❖ OCamlM: A minimal concurrent language
❖ Typing rules for Global Combinators (with hints to OCaml DSL)
❖ Session Type merging
C. Implementation: GPC as a typed DSL in OCaml
❖ Based on a set of type manipulation techniques
(GADTs, field label encoding, and plumbings such as polymorphic record extension)
GPC key ingredients
B. OCamlM: Formalisation of GPC with Deadlock-freedom Theorem
• A minimal concurrent language with structural subtyping,
equi-recursive types and simply-typed channels
• Typing rules for global combinators
62
Typing rules
63
p1 pn
… … …
Point: give an index for each role (and order roles)
wf(G) ✔, G↾C
The typing rule for (-->)
64
p1 pn
…
pi pj
… …
wf(G) ✔, G↾C
i
The typing rule for (-->)
65
p1 pn
…
pi pj
… …
Index-based type update
wf(G) ✔, G↾C
i
The typing rule for (-->)
66
p1 pn
…
pi pj
… …
Index-based type update
p1 pn
…
pi pj
… …
"Wrap" with opponent's role names and labels
wf(G) ✔, G↾C
i
The typing rule for (-->)
67
p1 pn
…
pi pj
… …
Index-based type update
p1 pn
…
pi pj
… …
"Wrap" with opponent's role names and labels
Implement them by using GADTs and
polymorphic lens (explained later)
available in OCaml
wf(G) ✔, G↾C
i
The typing rule for (-->)
68
p1 pn
…
pi pj
… …
Index-based type update
p1 pn
…
pi pj
… …
"Wrap" with opponent's role names and labels
Requires first-class record fields
(methods) and variant tags
⇒ Encode them as values
encode it in OCaml
Implement them by using GADTs and
polymorphic lens (explained later)
available in OCaml
wf(G) ✔, G↾C
i
The typing rule for branching (choice_at)
69
wf(G) ✔, G↾C
The typing rule for branching (choice_at)
70
Ensure that pa is a sending
wf(G) ✔, G↾C
The typing rule for branching (choice_at)
71
Ensure that pa is a sending
Output labels must be disjoint (deterministic)
wf(G) ✔, G↾C
The typing rule for branching (choice_at)
72
Ensure that pa is a sending
Output labels must be disjoint (deterministic)
Merge two records (objects) into one
wf(G) ✔, G↾C
The typing rule for branching (choice_at)
73
Ensure that pa is a sending
Output labels must be disjoint (deterministic)
Merge two records (objects) into one
Encode disjoint record merging
encode it in OCaml
wf(G) ✔, G↾C
The typing rule for branching (choice_at)
74
wf(G) ✔, G↾C
Too restrictive for communication protocols
Solution: Subtyping!
Requires each role having the same type (behaviour) in each branch
→ seems standard wrt. if-then-else construct, but
The typing rule for branching (choice_at)
75
wf(G) ✔, G↾C
Too restrictive for communication protocols
Solution: Subtyping!
Row polymorphism
(objects and polymorphic variants)
available in OCaml
Requires each role having the same type (behaviour) in each branch
→ seems standard wrt. if-then-else construct, but
Typing rules
76
…
p1 pn
…
pi
…
p1 pn
…
pi
…
p1 pn
…
pi
…
Γ ⊢ choice … {g1; g2} : ⋯×p&{m1:T1, m2:T2}×⋯
Γ ⊢ g1 : ⋯×p&{m1:T1}×⋯ Γ ⊢ g2 : ⋯×p&{m2:T2}×⋯
Desired type
(According to Full Merging in MPST)
A problem:
p&{m1:T1} ≠ p&{m2:T2}
Typing rules
77
…
p1 pn
…
pi
…
p1 pn
…
pi
…
p1 pn
…
pi
…
Γ ⊢ choice … {m1:g1; m2:g2} : ⋯×p&{m1:T1, m2:T2}×⋯
Γ ⊢ g1 : ⋯×p&{m1:T1}×⋯ Γ ⊢ g1 : ⋯×p&{m2:T2}×⋯
? ?
Typing rules
78
…
p1 pn
…
pi
…
p1 pn
…
pi
…
p1 pn
…
pi
…
Γ ⊢ g1 : ⋯×p&{m1:T1, m2:T2}×⋯ Γ ⊢ g2 : ⋯×p&{m1:T1, m2:T2}×⋯
Γ ⊢ g1 : ⋯×p&{m1:T1}×⋯ Γ ⊢ g1 : ⋯×p&{m2:T2}×⋯
Γ ⊢ choice … {g1; g2} : ⋯×p&{m1:T1, m2:T2}×⋯
p&{m1:T1} ≤ p&{m1:T1; m2:T2} p&{m2:T2} ≤ p&{m1:T1; m2:T2}
Subtyping!!
Deadlock and type errors: An analysis
79
let oauth_branch =
choice_at s (to_c login_or_cancel)
(s, (s --> c) login ((c --> a) password ((a --> c) auth finish)))
(s, (s --> c) cancel ((c --> a) quit finish))a
poke a instead of c
The MPST theory rejects it: they are not "mergeable".
Forming a "mixed choice" (which causes nondeterminism)
Deadlock and type errors: An analysis
80
let oauth_branch =
choice_at s (to_c login_or_cancel)
(s, (s --> c) login ((c --> a) password ((a --> c) auth finish)))
(s, (s --> c) cancel ((c --> a) quit finish))a
poke a instead of c
The MPST theory rejects it: they are not "mergeable".
Forming a "mixed choice" (which causes nondeterminism)
c's first action is output to a <a: <quit: !bool*cont2>>
Deadlock and type errors: An analysis
81
let oauth_branch =
choice_at s (to_c login_or_cancel)
(s, (s --> c) login ((c --> a) password ((a --> c) auth finish)))
(s, (s --> c) cancel ((c --> a) quit finish))a
poke a instead of c
The MPST theory rejects it: they are not "mergeable".
Forming a "mixed choice" (which causes nondeterminism)
c's first action is input from s <s: ?[login_str*cont1]>
c's first action is output to a <a: <quit: !bool*cont2>>
Deadlock and type errors: An analysis
82
let oauth_branch =
choice_at s (to_c login_or_cancel)
(s, (s --> c) login ((c --> a) password ((a --> c) auth finish)))
(s, (s --> c) cancel ((c --> a) quit finish))a
poke a instead of c
The MPST theory rejects it: they are not "mergeable".
Forming a "mixed choice" (which causes nondeterminism)
c's first action is input from s <s: ?[login_str*cont1]>
c's first action is output to a <a: <quit: !bool*cont2>>
No least upper bound (common supertype)
⇒ type error
No least upper bound (common supertype)
⇒ type error
A note on typing
83
<r: ?[lab: T1*T2]>
<r: <lab: !T1*T2>>
Input and output session types are not symmetric with each other. Why?
sok : ?bool, scancel : ?int
: ?[ok_(boolו); cancel_(int× …)] (← wanted)
Making a multiplexed channel from
simply-typed channels
A note on typing
84
<r: ?[lab: T1*T2]>
<r: <lab: !T1*T2>>
Input and output session types are not symmetric with each other. Why?
sok : ?bool, scancel : ?int
: ?[ok_(boolו); cancel_(int× …)] (← wanted)
choose : List[?T] -> ?T
makes a (multiplexed) channel (external choice)
wrap : (α -> β) -> ?α -> ?β
makes a wrapped channel
Concurrent ML (Reppy, 1993)
Types are slightly modified, they uses "events" in reality
Making a multiplexed channel from
simply-typed channels
A note on typing
85
<r: ?[lab: T1*T2]>
<r: <lab: !T1*T2>>
Input and output session types are not symmetric with each other. Why?
sok : ?bool, scancel : ?int
wrap (λx.[ok=(x,•)]) sok
: ?[ok_(boolו)]
wrap (λx.[cancel=(x,…)]) scancel
: ?[cancel_(int×…)]
: ?[ok_(boolו); cancel_(int× …)] (← wanted)
choose : List[?T] -> ?T
makes a (multiplexed) channel (external choice)
wrap : (α -> β) -> ?α -> ?β
makes a wrapped channel
Concurrent ML (Reppy, 1993)
Types are slightly modified, they uses "events" in reality
Making a multiplexed channel from
simply-typed channels
A note on typing
86
<r: ?[lab: T1*T2]>
<r: <lab: !T1*T2>>
Input and output session types are not symmetric with each other. Why?
sok : ?bool, scancel : ?int
wrap (λx.[ok=(x,•)]) sok
: ?[ok_(boolו)]
wrap (λx.[cancel=(x,…)]) scancel
: ?[cancel_(int×…)]
List(wrap (λx.[ok=(x,•)]) sok; wrap (λx.[cancel=(x,…)]) scancel)
: List[ ?[ok_(boolו), cancel_(intׅ)] ]
: ?[ok_(boolו); cancel_(int× …)] (← wanted)
choose : List[?T] -> ?T
makes a (multiplexed) channel (external choice)
wrap : (α -> β) -> ?α -> ?β
makes a wrapped channel
Concurrent ML (Reppy, 1993)
Types are slightly modified, they uses "events" in reality
Making a multiplexed channel from
simply-typed channels
A note on typing
87
<r: ?[lab: T1*T2]>
<r: <lab: !T1*T2>>
Input and output session types are not symmetric with each other. Why?
sok : ?bool, scancel : ?int
wrap (λx.[ok=(x,•)]) sok
: ?[ok_(boolו)]
wrap (λx.[cancel=(x,…)]) scancel
: ?[cancel_(int×…)]
List(wrap (λx.[ok=(x,•)]) sok; wrap (λx.[cancel=(x,…)]) scancel)
: List[ ?[ok_(boolו), cancel_(intׅ)] ]
choose (List(wrap (λx.[ok=(x,•)]) sok; wrap (λx.[cancel=(x,…)]) scancel))
: ?[ok_(boolו); cancel_(int× …)] (← wanted)
choose : List[?T] -> ?T
makes a (multiplexed) channel (external choice)
wrap : (α -> β) -> ?α -> ?β
makes a wrapped channel
Concurrent ML (Reppy, 1993)
Types are slightly modified, they uses "events" in reality
Making a multiplexed channel from
simply-typed channels
GPC: Are they correct? (cont.)
88
A. Key idea: Global Combinators pre-generate channels
❖ Multiparty channels as nested sequence of simply-typed channels
B. Formalisation of GPC (with Deadlock-freedom Theorem)
❖ OCamlM: A minimal concurrent language
❖ Typing rules for Global Combinators (with hints to OCaml DSL)
❖ Session Type merging
C. Implementation: GPC as a typed DSL in OCaml
❖ Based on a set of type manipulation techniques
(GADTs, field label encoding, and details of plumbings for polymorphic record extension)
❖ Benchmarks: Garbage collection matters
❖ Linearity monad
GPC key ingredients
Please ask me over beer!
GPC wrap up
89
Global Protocol Combinator: a DSL for writing global protocols
❖ Key Ingredients: Global Combinators
❖ Covers all basic MPST features (including full merging)
❖ Extensions: HTTP, and OAuth Example (on top of it), and more
OCamlM: fomalisation of a minimal programming language for GPC
❖ Subject Reduction, Operational Correspondence and Deadlock-freedom
❖ Types for global combinators
❖ Merging is a least upper bound in subtyping relation
Sauth
Spasswd
let oauth = (s --> c) login …
p1 pn
… … …
Future Work
90
A → B
B → C
A → B
• Deadlock-freedom proof on full global combinators
❖ Including more expressive ones (e.g. relaxed loop conditions)
❖ Scatter/Gather (broadcast), undirected internal choice, …
• Implementation in other programming languages
❖ TypeScript (structural subtyping from beginning, and will have recursive types as well)
❖ Haskell (automatically construct global combinators via type classes)
Thank you!
Extra slides
91
Loops are easy (for now)
92
let oAuth = (S → C) login ((C → A) password ((A → C) auth finish))
S
C
A
⟨?Slogin ; !Spasswd; ?Sauth.0 ⟩ ⟨?Spasswd; !Sauth⟩
Sauth
Spasswd
Slogin
⟨?Slogin ⟩
Loops are easy (for now)
93
let oAuth = fix (λx. (S → C) login ((C → A) password ((A → C) auth x))
S
C
A
μx.⟨?Slogin ; !Spasswd; ?Sauth; x ⟩
μx. ⟨?Spasswd; !Sauth; x⟩
Sauth
Spasswd
Slogin
μx. ⟨?Slogin; x⟩
Branchings?
94
S
C
A
Sauth
Spasswd
Slogin
(S → C) login ((C → A) password ((A → C) auth finish))
(S → C) cancel ((C → A) quit finish)
S
C A
Squit
Scancel
+?
Input / output primitives and row-polymorphism in OCaml
95
let thread_A () =
let `password((p:string), ch) = receive ch#role_C in
let ch = send ch#role_C#auth true in
close ch
(FP's type inference-friendly structural typing)
Input / output primitives and row-polymorphism in OCaml
96
let thread_A () =
let `password((p:string), ch) = receive ch#role_C in
let ch = send ch#role_C#auth true in
close ch
(FP's type inference-friendly structural typing)
Input labels are
polymorphic variants
Input labels are
polymorphic variants
Input / output primitives and row-polymorphism in OCaml
97
let thread_A () =
let `password((p:string), ch) = receive ch#role_C in
let ch = send ch#role_C#auth true in
close ch
(FP's type inference-friendly structural typing)
Input labels are
polymorphic variants
Input labels are
polymorphic variants
Output labels are methods in
an object (fields in a polymorphic record)
Output labels are methods in
an object (fields in a polymorphic record)
Input / output primitives and row-polymorphism in OCaml
98
let thread_A () =
let `password((p:string), ch) = receive ch#role_C in
let ch = send ch#role_C#auth true in
close ch
OCaml's row-polymorphism simulates session-type subtyping
(FP's type inference-friendly structural typing)
Input labels are
polymorphic variants
Input labels are
polymorphic variants
Output labels are methods in
an object (fields in a polymorphic record)
Output labels are methods in
an object (fields in a polymorphic record)
Input / output primitives and row-polymorphism in OCaml
99
let thread_A () =
let `password((p:string), ch) = receive ch#role_C in
let ch = send ch#role_C#auth true in
close ch
OCaml's row-polymorphism simulates session-type subtyping
(FP's type inference-friendly structural typing)
Input labels are
polymorphic variants
Input labels are
polymorphic variants
Output labels are methods in
an object (fields in a polymorphic record)
Output labels are methods in
an object (fields in a polymorphic record)
val ch :
< role_C : [< `password of
string *
< role_C : < auth : (bool * close) out lin; .. >; .. >
] inp lin; .. >
-> unit
Input / output primitives and row-polymorphism in OCaml
100
let thread_A () =
let `password((p:string), ch) = receive ch#role_C in
let ch = send ch#role_C#auth true in
close ch
OCaml's row-polymorphism simulates session-type subtyping
(FP's type inference-friendly structural typing)
Input labels are
polymorphic variants
Input labels are
polymorphic variants
Output labels are methods in
an object (fields in a polymorphic record)
Output labels are methods in
an object (fields in a polymorphic record)
val ch :
< role_C : [< `password of
string *
< role_C : < auth : (bool * close) out lin; .. >; .. >
] inp lin; .. >
-> unit
Inferred polymorphic variant type: it can have less receiving labels
(= in this case it must have password at least since there must be one)
Input / output primitives and row-polymorphism in OCaml
101
let thread_A () =
let `password((p:string), ch) = receive ch#role_C in
let ch = send ch#role_C#auth true in
close ch
OCaml's row-polymorphism simulates session-type subtyping
(FP's type inference-friendly structural typing)
Input labels are
polymorphic variants
Input labels are
polymorphic variants
Output labels are methods in
an object (fields in a polymorphic record)
Output labels are methods in
an object (fields in a polymorphic record)
val ch :
< role_C : [< `password of
string *
< role_C : < auth : (bool * close) out lin; .. >; .. >
] inp lin; .. >
-> unit
Inferred polymorphic variant type: it can have less receiving labels
(= in this case it must have password at least since there must be one)
Inferred object type: it can have more sending labels
Branching
102
let oauth1 =
choice_at s (to_c login_or_cancel)
(s, (s --> c) login @@ (c --> a) password @@ (a --> c) auth finish)
(s, (s --> c) cancel @@ (c --> a) quit finish)
A protocol with branching:
let thread_C () =
match receive ch#role_S with
| `cancel((code:int), ch) -> close (send chc#role_A#quit ())
| `login((), ch) ->
let ch = send ch#role_A#password "asdf" in
let `auth(b, ch) = receive ch#role_A in
close ch
Code for C (waiting for S with an external choice):
Branching
103
let oauth1 =
choice_at s (to_c login_or_cancel)
(s, (s --> c) login @@ (c --> a) password @@ (a --> c) auth finish)
(s, (s --> c) cancel @@ (c --> a) quit finish)
A protocol with branching:
S will decide a branch, then C and A will follow
let thread_C () =
match receive ch#role_S with
| `cancel((code:int), ch) -> close (send chc#role_A#quit ())
| `login((), ch) ->
let ch = send ch#role_A#password "asdf" in
let `auth(b, ch) = receive ch#role_A in
close ch
Code for C (waiting for S with an external choice):
Branching
104
let oauth1 =
choice_at s (to_c login_or_cancel)
(s, (s --> c) login @@ (c --> a) password @@ (a --> c) auth finish)
(s, (s --> c) cancel @@ (c --> a) quit finish)
A protocol with branching:
S will decide a branch, then C and A will follow
let thread_C () =
match receive ch#role_S with
| `cancel((code:int), ch) -> close (send chc#role_A#quit ())
| `login((), ch) ->
let ch = send ch#role_A#password "asdf" in
let `auth(b, ch) = receive ch#role_A in
close ch
Code for C (waiting for S with an external choice):An external choice is a pattern matching
(idiomatic OCaml)
Loops and delegations (1)
105
let oauth2 =
fix (fun self ->
choice_at s (to_c login_cancel_or_retry)
(s, oauth1 ())
(s, (s --> c) retry @@ (c --> a) retry self))
Thanks to OCaml's equi-recursive types (built in polymorphic variants and objects by default),
programmers can handle recursions very naturally:
Loops and delegations (1)
106
let oauth2 =
fix (fun self ->
choice_at s (to_c login_cancel_or_retry)
(s, oauth1 ())
(s, (s --> c) retry @@ (c --> a) retry self))
recursionrecursion
Thanks to OCaml's equi-recursive types (built in polymorphic variants and objects by default),
programmers can handle recursions very naturally:
Loops and delegations (1)
107
let oauth2 =
fix (fun self ->
choice_at s (to_c login_cancel_or_retry)
(s, oauth1 ())
(s, (s --> c) retry @@ (c --> a) retry self))
recursionrecursion
protocol reuse
Thanks to OCaml's equi-recursive types (built in polymorphic variants and objects by default),
programmers can handle recursions very naturally:
Loops and delegations (1)
108
let oauth2 =
fix (fun self ->
choice_at s (to_c login_cancel_or_retry)
(s, oauth1 ())
(s, (s --> c) retry @@ (c --> a) retry self))
recursionrecursion
protocol reuse
val ch_S : < role_C : < cancel : ('_b * close) out lin;
login : ('_c * close) out lin;
retry : ('_d * 'a) out lin > > as 'a
OCaml>
Thanks to OCaml's equi-recursive types (built in polymorphic variants and objects by default),
programmers can handle recursions very naturally:
Loops and delegations (1)
109
let oauth2 =
fix (fun self ->
choice_at s (to_c login_cancel_or_retry)
(s, oauth1 ())
(s, (s --> c) retry @@ (c --> a) retry self))
recursionrecursion
protocol reuse
val ch_S : < role_C : < cancel : ('_b * close) out lin;
login : ('_c * close) out lin;
retry : ('_d * 'a) out lin > > as 'a
OCaml>
recursionrecursion
Thanks to OCaml's equi-recursive types (built in polymorphic variants and objects by default),
programmers can handle recursions very naturally:
Loops and delegations (2)
110
let oauth_deleg =
(mst --> wrk) (msg >: get_prot s oauth2)
finish
Delegation doesn't need any special treatment, since OCaml will just infer the delegated type.
However, you can annotate labels with a delegated protocol, like this:
val ch_Mst :
< role_Wrk : < msg :
(< role_C : < cancel : ('_b * close) out lin;
login : ('_c * close) out lin;
retry : ('_d * 'a) out lin > > as 'a *
close) out lin > >
OCaml>
Delegated type
Detecting protocol errors using types
111
Non-determinism/
Deadlock
in a protocol
let oauth1 =
choice_at s (to_c login_or_cancel)
(s, (s --> c) login @@ (c --> a) password @@ (a --> c) auth finish)
(s, (s --> a) cancel @@ (c --> a) quit finish)
NB: Branching is a source of concurrency issues
Detecting protocol errors using types
112
Non-determinism/
Deadlock
in a protocol
let oauth1 =
choice_at s (to_c login_or_cancel)
(s, (s --> c) login @@ (c --> a) password @@ (a --> c) auth finish)
(s, (s --> a) cancel @@ (c --> a) quit finish)
… is also reported as a type error
NB: Branching is a source of concurrency issues
Detecting protocol errors using types
113
Non-determinism/
Deadlock
in a protocol
let oauth1 =
choice_at s (to_c login_or_cancel)
(s, (s --> c) login @@ (c --> a) password @@ (a --> c) auth finish)
(s, (s --> a) cancel @@ (c --> a) quit finish)
… is also reported as a type error
Theorem: if a global type G is well-formed, its encoding
to a global combinator g =⟦G⟧ is well-typed in OCamlM.
NB: Branching is a source of concurrency issues
Detecting protocol errors using types
114
Non-determinism/
Deadlock
in a protocol
let oauth1 =
choice_at s (to_c login_or_cancel)
(s, (s --> c) login @@ (c --> a) password @@ (a --> c) auth finish)
(s, (s --> a) cancel @@ (c --> a) quit finish)
… is also reported as a type error
Theorem: if a global type G is well-formed, its encoding
to a global combinator g =⟦G⟧ is well-typed in OCamlM.
NB: Branching is a source of concurrency issues
Global Combinators have full expressivity of MPST Global Types
[Formalisation] OCamlM : a Minimal calculus for global combinators
Main results:
115
A calculus with structural subtyping, equi-recursive types and
i/o-typed channels
Theorem (Subject Reduction): if ⊢ e and e→* e' then ⊢ e'
Theorem (Operational Correspondence):
(Completeness)
(Soundness)
Corollary (Deadlock Freedom): If an MPST process P is
deadlock-free, OCamlM expression e=⟦P⟧ is deadlock-free.
Other features and Examples
✔ Branchings, loops, delegations
❖ Allows full merging in a branching (next slide)
✔ MPST as a wrapper
❖ Offers global protocol on top of HTTP, DNS, …
❖ Example: OAuth, DNS server, SMTP client, …
❖ Utilise concurrent/distributed libraries: Lwt (lightweight threads) and Unix IPC
✔ More Extensions
❖ Scatter/Gather (broadcast)
❖ Undirected choice (-nolive)
❖ Unbalanced Loops
116
B⊕m1 C⊕m2
B⊕m1C⊕m2
A → B
B → C
A → B
Full merging
117
let oauth1 =
choice_at s (to_c login_or_cancel)
(s, (s --> c) login @@ (c --> a) password @@ (a --> c) auth finish)
(s, (s --> c) cancel @@ (c --> a) quit finish)
Input labels are
polymorphic variantsA can have different
input branches
Example: A branch happens between S and C.
⇒ Merge A's two behaviours into one
Merging strategy Synopsis Implementations
Plain merging
All branches must have same
labels/continuation (restrictive)
Scalas et al.
(ECOOP 2017)
✔ Full merging
Different input labels/continuations
can be mergeable (more relaxed)
This work
• Benchmarks reflect our design decision to use
mutable long lived objects (e.g channel vectors)
❖ Our work: few mutable long lived objects, created at the start of the protocol
❖ State-of-the-art (linear-decomposition [Scala et.a]): many small channels, created on-demand
(during the protocol execution)
118
Benchmarks
• Comparison with Linear (Binary) Decomposition [Scalas et al., 2017]
❖ Translation from MPST to Linear Types
❖ Continuation Passing Style (CPS):
It creates (and exchanges) a fresh channel at each communication step
❖ Must be slower than us??
• Compete with ours in some cases (!), but CPS is slower in general
❖ OCaml's major GC is doing nice work
• Monad (static linearity checking with overhead) VS. Direct style (dynamic)
119
Put All Slides in right contexts!!
• Most surprising parts:
• (what is it) 簡単に?
programmers can write like this… select opponent role by method, then (a) send by method / (b) receive it and pattern match on variants.
Errors are detected like this… GC well-formedness errors and Local type conformance errors.
Bonus: recursive sessions, session subtyping and delegations are all free.
• (why/how gc-like typing is possible??)
(1) (why EPP is possible, it is operation on types!!: see onion and --> typing.)
(2) (why well-formedness checking is possible? What is well-formedness?: see typing rules)
• (key idea) タマネギ.2枚くらいにおさめる
• (how it is typed) --> typing and implementation (mention that OCaml do not have such first-class?)
• (how deadlock is detected: harder) choice, nondeterminisim and deadlock
choice is like an if-then-else. Two branches are merged into one.
(Sub)typing and global combinator typing prevents occasional wrong branching.
• (how it is imlpemented) lenses and first class record fields
• Choice_at typing and record extensions
❖ Least upper bound is merging
❖ We have more expressive GTs
❖ Subtyping and equi-recursive types
❖ Unguardedness and Unbalanced merging
• Linearity monad
• Deadlock freeness, syntax of local types, and undirected choice (sending and receiving)
• Benchmarks
• Meaning of type errors and relationship to deadlocks
❖ Mergeability and local type syntax
❖ Possibility to extension (i.e. non-directed merging)
❖ Why roles are record fields – what if it was variant tags
120
Channel Vectors: Inhabiting MPSTs as simple channel types
121
TA = B⊕{ok.•; cancel.B&cancel.•} TB = A&{ok.•; cancel.B⊕cancel.•}
Channel Vectors: Inhabiting MPSTs as simple channel types
122
sok scancel1
scancel2
sok scancel1
scancel2
Idea: Put simply-typed channels in a tree-like data structure
TA = B⊕{ok.•; cancel.B&cancel.•} TB = A&{ok.•; cancel.B⊕cancel.•}
Internal Choice is Record
A record having pairs of an output channel and "the rest" in its fields
123
⟦ B⊕{ok.•; cancel.B&cancel(int).•} ⟧s = <B = <ok= (sok, •); cancel= (scancel1, ⟦...⟧s)> >
Pictorially:
Internal Choice is Record
A record having pairs of an output channel and "the rest" in its fields
124
⟦ B⊕{ok.•; cancel.B&cancel(int).•} ⟧s = <B = <ok= (sok, •); cancel= (scancel1, ⟦...⟧s)> >
(scancel, )(sok, )
…
ok cancel
Pictorially:
Internal Choice is Record
A record having pairs of an output channel and "the rest" in its fields
125
⟦ B⊕{ok.•; cancel.B&cancel(int).•} ⟧s =
: ⟨B : ⟨ok: !(int*int)ו; cancel: !(bool) ×⟦…⟧⟩ ⟩
Provided that
• sok : Och, scancel : Och
(! is an output channel type)
<B = <ok= (sok, •); cancel= (scancel1, ⟦...⟧s)> >
(scancel, )(sok, )
…
ok cancel
Pictorially:
External choice is variant input
126
Variant input type: ?[ok_(boolו); cancel_(int× …)]
Variant type: [ok_(boolו); cancel_(int× …)]
("Either ok (with boolו) or cancel (with intׅ)")
("Receives either ok (with boolו) or cancel (with intׅ)")
cancel(_, )ok(_, )
scancel1sok
cancel
external choice
Pictorially: But how?
A Solution from Concurrent ML (Reppy, 1993)
127
… has a set of (event) primitives we need!
choose : List[?T] -> ?T
makes a (multiplexed) channel (external choice)
wrap : (α -> β) -> ?α -> ?β
makes a wrapped channel
sok : ?bool, scancel : ?int
: ?[ok_(boolו); cancel_(int× …)] (← wanted)
A Solution from Concurrent ML (Reppy, 1993)
128
… has a set of (event) primitives we need!
choose : List[?T] -> ?T
makes a (multiplexed) channel (external choice)
wrap : (α -> β) -> ?α -> ?β
makes a wrapped channel
sok : ?bool, scancel : ?int
wrap (λx.[ok=(x,•)]) sok
: ?[ok_(boolו)]
wrap (λx.[cancel=(x,…)]) scancel
: ?[cancel_(int×…)]
: ?[ok_(boolו); cancel_(int× …)] (← wanted)
A Solution from Concurrent ML (Reppy, 1993)
129
… has a set of (event) primitives we need!
choose : List[?T] -> ?T
makes a (multiplexed) channel (external choice)
wrap : (α -> β) -> ?α -> ?β
makes a wrapped channel
sok : ?bool, scancel : ?int
wrap (λx.[ok=(x,•)]) sok
: ?[ok_(boolו)]
wrap (λx.[cancel=(x,…)]) scancel
: ?[cancel_(int×…)]
List(wrap (λx.[ok=(x,•)]) sok; wrap (λx.[cancel=(x,…)]) scancel)
: List[ ?[ok_(boolו), cancel_(intׅ)] ]
: ?[ok_(boolו); cancel_(int× …)] (← wanted)
A Solution from Concurrent ML (Reppy, 1993)
130
… has a set of (event) primitives we need!
choose : List[?T] -> ?T
makes a (multiplexed) channel (external choice)
wrap : (α -> β) -> ?α -> ?β
makes a wrapped channel
sok : ?bool, scancel : ?int
wrap (λx.[ok=(x,•)]) sok
: ?[ok_(boolו)]
wrap (λx.[cancel=(x,…)]) scancel
: ?[cancel_(int×…)]
List(wrap (λx.[ok=(x,•)]) sok; wrap (λx.[cancel=(x,…)]) scancel)
: List[ ?[ok_(boolו), cancel_(intׅ)] ]
choose (List(wrap (λx.[ok=(x,•)]) sok; wrap (λx.[cancel=(x,…)]) scancel))
: ?[ok_(boolו); cancel_(int× …)] (← wanted)
A Solution from Concurrent ML (Reppy, 1993)
131
… has a set of (event) primitives we need!
choose : List[?T] -> ?T
makes a (multiplexed) channel (external choice)
wrap : (α -> β) -> ?α -> ?β
makes a wrapped channel
sok : ?bool, scancel : ?int
wrap (λx.[ok=(x,•)]) sok
: ?[ok_(boolו)]
wrap (λx.[cancel=(x,…)]) scancel
: ?[cancel_(int×…)]
List(wrap (λx.[ok=(x,•)]) sok; wrap (λx.[cancel=(x,…)]) scancel)
: List[ ?[ok_(boolו), cancel_(intׅ)] ]
choose (List(wrap (λx.[ok=(x,•)]) sok; wrap (λx.[cancel=(x,…)]) scancel))
cancel(_, )ok(_, )
scancel1
sok
(scancel2, )
cancel
choose
: ?[ok_(boolו); cancel_(int× …)] (← wanted)
Putting them altogether
132
(scancel, )(sok, )
ok cancel
cancel(_, )ok(_, )
scancel1
sok
(scancel2, )
cancel
choose
B⊕{ok(bool).•; cancel(int).B&cancel(int).•} A&{ok(bool).•; cancel(int).A⊕cancel(int).•}
choice_at A {(A → B) ok finish, (A → B) cancel((B → A) cancel finish)}
cancel(_, )
scancel2
Putting them altogether
133
(scancel, )(sok, )
ok cancel
cancel(_, )ok(_, )
scancel1
sok
(scancel2, )
cancel
choose
B⊕{ok(bool).•; cancel(int).B&cancel(int).•} A&{ok(bool).•; cancel(int).A⊕cancel(int).•}
choice_at A {(A → B) ok finish, (A → B) cancel((B → A) cancel finish)}
cancel(_, )
scancel2

Weitere ähnliche Inhalte

Was ist angesagt?

Was ist angesagt? (20)

よくわかるCoqプログラミング
よくわかるCoqプログラミングよくわかるCoqプログラミング
よくわかるCoqプログラミング
 
曲線から多様体まで駆け抜ける微分幾何学入門
曲線から多様体まで駆け抜ける微分幾何学入門曲線から多様体まで駆け抜ける微分幾何学入門
曲線から多様体まで駆け抜ける微分幾何学入門
 
純粋関数型アルゴリズム入門
純粋関数型アルゴリズム入門純粋関数型アルゴリズム入門
純粋関数型アルゴリズム入門
 
つくってあそぼ ラムダ計算インタプリタ
つくってあそぼ ラムダ計算インタプリタつくってあそぼ ラムダ計算インタプリタ
つくってあそぼ ラムダ計算インタプリタ
 
組合せ最適化を体系的に知ってPythonで実行してみよう PyCon 2015
組合せ最適化を体系的に知ってPythonで実行してみよう PyCon 2015組合せ最適化を体系的に知ってPythonで実行してみよう PyCon 2015
組合せ最適化を体系的に知ってPythonで実行してみよう PyCon 2015
 
Deep generative model.pdf
Deep generative model.pdfDeep generative model.pdf
Deep generative model.pdf
 
ものまね鳥を愛でる 結合子論理と計算
ものまね鳥を愛でる 結合子論理と計算ものまね鳥を愛でる 結合子論理と計算
ものまね鳥を愛でる 結合子論理と計算
 
楽しいクォータニオンの世界 田所 第二回Rogyゼミ
楽しいクォータニオンの世界 田所 第二回Rogyゼミ楽しいクォータニオンの世界 田所 第二回Rogyゼミ
楽しいクォータニオンの世界 田所 第二回Rogyゼミ
 
競技プログラミングのためのC++入門
競技プログラミングのためのC++入門競技プログラミングのためのC++入門
競技プログラミングのためのC++入門
 
TeX言語の展開制御による文書の構造化(TeXユーザの集い2014)
TeX言語の展開制御による文書の構造化(TeXユーザの集い2014)TeX言語の展開制御による文書の構造化(TeXユーザの集い2014)
TeX言語の展開制御による文書の構造化(TeXユーザの集い2014)
 
「日本語LaTeX」が多すぎる件について
「日本語LaTeX」が多すぎる件について「日本語LaTeX」が多すぎる件について
「日本語LaTeX」が多すぎる件について
 
[DLHacks]Comet ML -機械学習のためのGitHub-
[DLHacks]Comet ML -機械学習のためのGitHub-[DLHacks]Comet ML -機械学習のためのGitHub-
[DLHacks]Comet ML -機械学習のためのGitHub-
 
「五次方程式が代数的に解けないわけ」第3回プログラマのための数学勉強会 #maths4pg
「五次方程式が代数的に解けないわけ」第3回プログラマのための数学勉強会 #maths4pg 「五次方程式が代数的に解けないわけ」第3回プログラマのための数学勉強会 #maths4pg
「五次方程式が代数的に解けないわけ」第3回プログラマのための数学勉強会 #maths4pg
 
有向グラフに対する 非線形ラプラシアンと ネットワーク解析
有向グラフに対する 非線形ラプラシアンと ネットワーク解析有向グラフに対する 非線形ラプラシアンと ネットワーク解析
有向グラフに対する 非線形ラプラシアンと ネットワーク解析
 
これから Haskell を書くにあたって
これから Haskell を書くにあたってこれから Haskell を書くにあたって
これから Haskell を書くにあたって
 
Intoduction to Homotopy Type Therory
Intoduction to Homotopy Type TheroryIntoduction to Homotopy Type Therory
Intoduction to Homotopy Type Therory
 
ラマヌジャンやっぱりやばいじゃん - 第15回 #日曜数学会
ラマヌジャンやっぱりやばいじゃん - 第15回 #日曜数学会 ラマヌジャンやっぱりやばいじゃん - 第15回 #日曜数学会
ラマヌジャンやっぱりやばいじゃん - 第15回 #日曜数学会
 
正規言語と代数と論理の対応:An Introduction to Eilenberg’s Variety Theorem
正規言語と代数と論理の対応:An Introduction to Eilenberg’s Variety Theorem正規言語と代数と論理の対応:An Introduction to Eilenberg’s Variety Theorem
正規言語と代数と論理の対応:An Introduction to Eilenberg’s Variety Theorem
 
競技プログラミングにおけるコードの書き方とその利便性
競技プログラミングにおけるコードの書き方とその利便性競技プログラミングにおけるコードの書き方とその利便性
競技プログラミングにおけるコードの書き方とその利便性
 
充足可能性問題のいろいろ
充足可能性問題のいろいろ充足可能性問題のいろいろ
充足可能性問題のいろいろ
 

Ähnlich wie OCaml-MPST / Global Protocol Combinators

Structure-Compiler-phases information about basics of compiler. Pdfpdf
Structure-Compiler-phases information  about basics of compiler. PdfpdfStructure-Compiler-phases information  about basics of compiler. Pdfpdf
Structure-Compiler-phases information about basics of compiler. Pdfpdf
ovidlivi91
 

Ähnlich wie OCaml-MPST / Global Protocol Combinators (20)

Open-DO Update
Open-DO UpdateOpen-DO Update
Open-DO Update
 
Bounded Model Checking for C Programs in an Enterprise Environment
Bounded Model Checking for C Programs in an Enterprise EnvironmentBounded Model Checking for C Programs in an Enterprise Environment
Bounded Model Checking for C Programs in an Enterprise Environment
 
Odog : A Framework for Concurrent and Distributed software design
Odog : A Framework for Concurrent and Distributed software designOdog : A Framework for Concurrent and Distributed software design
Odog : A Framework for Concurrent and Distributed software design
 
F# for BLOBA, by brandon d'imperio
F# for BLOBA, by brandon d'imperioF# for BLOBA, by brandon d'imperio
F# for BLOBA, by brandon d'imperio
 
Padding oracle [opkoko2011]
Padding oracle [opkoko2011]Padding oracle [opkoko2011]
Padding oracle [opkoko2011]
 
不深不淺,帶你認識 LLVM (Found LLVM in your life)
不深不淺,帶你認識 LLVM (Found LLVM in your life)不深不淺,帶你認識 LLVM (Found LLVM in your life)
不深不淺,帶你認識 LLVM (Found LLVM in your life)
 
Keynote (Mike Muller) - Is There Anything New in Heterogeneous Computing - by...
Keynote (Mike Muller) - Is There Anything New in Heterogeneous Computing - by...Keynote (Mike Muller) - Is There Anything New in Heterogeneous Computing - by...
Keynote (Mike Muller) - Is There Anything New in Heterogeneous Computing - by...
 
cReComp : Automated Design Tool for ROS-Compliant FPGA Component
cReComp : Automated Design Tool  for ROS-Compliant FPGA Component cReComp : Automated Design Tool  for ROS-Compliant FPGA Component
cReComp : Automated Design Tool for ROS-Compliant FPGA Component
 
HIS 2017 Mark Batty-Industrial concurrency specification for C/C++
HIS 2017 Mark Batty-Industrial concurrency specification for C/C++HIS 2017 Mark Batty-Industrial concurrency specification for C/C++
HIS 2017 Mark Batty-Industrial concurrency specification for C/C++
 
C language by Dr. D. R. Gholkar
C language by Dr. D. R. GholkarC language by Dr. D. R. Gholkar
C language by Dr. D. R. Gholkar
 
Vlsi lab manual_new
Vlsi lab manual_newVlsi lab manual_new
Vlsi lab manual_new
 
Traitement temps réel chez Streamroot - Golang Paris Juin 2016
Traitement temps réel chez Streamroot - Golang Paris Juin 2016Traitement temps réel chez Streamroot - Golang Paris Juin 2016
Traitement temps réel chez Streamroot - Golang Paris Juin 2016
 
Introduction to Go for Java Developers
Introduction to Go for Java DevelopersIntroduction to Go for Java Developers
Introduction to Go for Java Developers
 
(Open) MPI, Parallel Computing, Life, the Universe, and Everything
(Open) MPI, Parallel Computing, Life, the Universe, and Everything(Open) MPI, Parallel Computing, Life, the Universe, and Everything
(Open) MPI, Parallel Computing, Life, the Universe, and Everything
 
The Onward Journey: Porting Twisted to Python 3
The Onward Journey: Porting Twisted to Python 3The Onward Journey: Porting Twisted to Python 3
The Onward Journey: Porting Twisted to Python 3
 
10 reasons to be excited about go
10 reasons to be excited about go10 reasons to be excited about go
10 reasons to be excited about go
 
Flink Forward Berlin 2018: Thomas Weise & Aljoscha Krettek - "Python Streamin...
Flink Forward Berlin 2018: Thomas Weise & Aljoscha Krettek - "Python Streamin...Flink Forward Berlin 2018: Thomas Weise & Aljoscha Krettek - "Python Streamin...
Flink Forward Berlin 2018: Thomas Weise & Aljoscha Krettek - "Python Streamin...
 
Follow the (Kafka) Streams
Follow the (Kafka) StreamsFollow the (Kafka) Streams
Follow the (Kafka) Streams
 
Structure-Compiler-phases information about basics of compiler. Pdfpdf
Structure-Compiler-phases information  about basics of compiler. PdfpdfStructure-Compiler-phases information  about basics of compiler. Pdfpdf
Structure-Compiler-phases information about basics of compiler. Pdfpdf
 
Portable and reproducible bioinformatic analysis. Neoantigen discovery.
Portable and reproducible bioinformatic analysis. Neoantigen discovery.Portable and reproducible bioinformatic analysis. Neoantigen discovery.
Portable and reproducible bioinformatic analysis. Neoantigen discovery.
 

Kürzlich hochgeladen

introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
VishalKumarJha10
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
Health
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
VictorSzoltysek
 

Kürzlich hochgeladen (20)

Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdfAzure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
 
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS LiveVip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 

OCaml-MPST / Global Protocol Combinators

  • 1. Keigo Imai1 (with Rumyana Neykova2, Nobuko Yoshida3 and Shoji Yuen4) 1Gifu University (JP) 2Brunel University London (UK) 3Imperial College London (UK) 4Nagoya University (JP) PLAS Group Seminar, University of Kent 16th Sept. 2019 1 Global Protocol Combinators: Static Structural Multiparty Sessions Over Simply Typed Channels in OCaml
  • 2. 2 (A supplemental slide at VeTSS 2019 workshop lightning talk)
  • 3. Deadlocks in message-passing concurrency: Protocols prevent them! 3 A B C A ring-form multiparty communication: Concurrent programming is difficult!
  • 4. Deadlocks in message-passing concurrency: Protocols prevent them! 4 A B C A ring-form multiparty communication: Concurrent programming is difficult! C wrong usage (direction)… ② input① output order matters…
  • 5. Deadlocks in message-passing concurrency: Protocols prevent them! 5 A B C A ring-form multiparty communication: Concurrent programming is difficult! A B C Communication protocol! C wrong usage (direction)… ② input① output order matters…
  • 6. Deadlocks in message-passing concurrency: Protocols prevent them! 6 A B C A ring-form multiparty communication: Concurrent programming is difficult! A B C Communication protocol! C wrong usage (direction)… ② input① output order matters… Best practice: 1. Design a communication protocol and check it 2. Focus on its local behaviours 3. Enforce protocol in the program code
  • 7. deadlock-free? Multiparty Session Types (MPSTs): Protocol-based deadlock freedom 7 C S a "ping" protocol ③ Give concurrent processes (programs) and check their types ① Write a Global Type and check it ② Derive Local Types by End Point Projection (↾) PC | PS The system PC | PS is [Honda et al., 2008]
  • 8. deadlock-free? Multiparty Session Types (MPSTs): Protocol-based deadlock freedom 8 C S a "ping" protocol ③ Give concurrent processes (programs) and check their types ① Write a Global Type and check it ② Derive Local Types by End Point Projection (↾) PC | PS The system PC | PS is "well-formed": protocol G iswf(G) ✔ G = C → S. S → C.end deadlock-free [Honda et al., 2008]
  • 9. deadlock-free? Multiparty Session Types (MPSTs): Protocol-based deadlock freedom 9 C S a "ping" protocol ③ Give concurrent processes (programs) and check their types ① Write a Global Type and check it ② Derive Local Types by End Point Projection (↾) PC | PS The system PC | PS is "well-formed": protocol G iswf(G) ✔ G = C → S. S → C.end deadlock-free G↾C = LC = LSG↾S S! S? C? C! LC = LS = : "views" of the protocol [Honda et al., 2008]
  • 10. deadlock-free? Multiparty Session Types (MPSTs): Protocol-based deadlock freedom 10 C S a "ping" protocol ③ Give concurrent processes (programs) and check their types ① Write a Global Type and check it ② Derive Local Types by End Point Projection (↾) PC | PS The system PC | PS is ✔✔ : "these processes respect the protocol"PSPC LS ⊢LC ⊢ "well-formed": protocol G iswf(G) ✔ G = C → S. S → C.end deadlock-free G↾C = LC = LSG↾S S! S? C? C! LC = LS = : "views" of the protocol [Honda et al., 2008]
  • 11. deadlock-free? Multiparty Session Types (MPSTs): Protocol-based deadlock freedom 11 C S a "ping" protocol ③ Give concurrent processes (programs) and check their types ① Write a Global Type and check it ② Derive Local Types by End Point Projection (↾) PC | PS The system PC | PS is ✔✔ : "these processes respect the protocol"PSPC LS ⊢LC ⊢ "well-formed": protocol G iswf(G) ✔ G = C → S. S → C.end deadlock-free G↾C = LC = LSG↾S S! S? C? C! LC = LS = : "views" of the protocol deadlock-free! [Honda et al., 2008]
  • 12. deadlock-free? Multiparty Session Types (MPSTs): Protocol-based deadlock freedom 12 C S a "ping" protocol ③ Give concurrent processes (programs) and check their types ① Write a Global Type and check it ② Derive Local Types by End Point Projection (↾) PC | PS The system PC | PS is ✔✔ : "these processes respect the protocol"PSPC LS ⊢LC ⊢ "well-formed": protocol G iswf(G) ✔ G = C → S. S → C.end deadlock-free G↾C = LC = LSG↾S S! S? C? C! LC = LS = : "views" of the protocol deadlock-free! [Honda et al., 2008] How to implement MPSTs in a programming language? Question
  • 13. ③ LC ⊢ PC ? Go Thread State of the art: Deadlock freedom via code generation 13 ① wf(G) ? ② G↾C Global Protocol File Go Thread Go Thread In a MPST toolchain for programming language Go [D. Castro et al., POPL 2019]:
  • 14. ③ LC ⊢ PC ? Go Thread State of the art: Deadlock freedom via code generation 14 ① wf(G) ? ② G↾C Global Protocol File Go Thread Go Thread In a MPST toolchain for programming language Go [D. Castro et al., POPL 2019]: deadlock-free (Well-formedness checking and End Point Projection) Go type (Generated code) Go type (Generated code) Go type (Generated code) Code generation ✔
  • 15. ③ LC ⊢ PC ? Type checking by Go compiler ✔ (type checking to check protocol conformance) Go Thread State of the art: Deadlock freedom via code generation 15 ① wf(G) ? ② G↾C Global Protocol File Go Thread Go Thread In a MPST toolchain for programming language Go [D. Castro et al., POPL 2019]: deadlock-free (Well-formedness checking and End Point Projection) Go type (Generated code) Go type (Generated code) Go type (Generated code) Code generation ✔
  • 16. ③ LC ⊢ PC ? Type checking by Go compiler ✔ (type checking to check protocol conformance) Go Thread State of the art: Deadlock freedom via code generation 16 ① wf(G) ? ② G↾C Global Protocol File Go Thread Go Thread In a MPST toolchain for programming language Go [D. Castro et al., POPL 2019]: deadlock-free (Well-formedness checking and End Point Projection) Go type (Generated code) Go type (Generated code) Go type (Generated code) Code generation ✔ deadlock-free
  • 17. ③ LC ⊢ PC ? Type checking by Go compiler ✔ (type checking to check protocol conformance) Go Thread State of the art: Deadlock freedom via code generation 17 ① wf(G) ? ② G↾C Global Protocol File Go Thread Go Thread In a MPST toolchain for programming language Go [D. Castro et al., POPL 2019]: deadlock-free (Well-formedness checking and End Point Projection) Go type (Generated code) Go type (Generated code) Go type (Generated code) Code generation ✔ deadlock-free Is it possible to implement MPSTs without code generation? Question
  • 18. ③ LC ⊢ PC ? ① wf(G) ? ② G↾C Global Protocol Combinator : Deadlock freedom solely by Types! 18 Yes (!) How?
  • 19. ↓ A single OCaml program code file (.ml) OCaml Thread OCaml Thread OCaml Thread Protocol in OCaml ③ LC ⊢ PC ? ① wf(G) ? ② G↾C Global Protocol Combinator : Deadlock freedom solely by Types! 19 Yes (!) How?
  • 20. ↓ A single OCaml program code file (.ml) OCaml Thread OCaml Thread OCaml Thread Protocol in OCaml ③ LC ⊢ PC ? ① wf(G) ? ② G↾C Global Protocol Combinator : Deadlock freedom solely by Types! 20 ✔ deadlock-free OCaml types OCaml types OCaml types Type checking & inference Yes (!) How?
  • 21. ↓ A single OCaml program code file (.ml) OCaml Thread OCaml Thread OCaml Thread Protocol in OCaml ③ LC ⊢ PC ? ① wf(G) ? ② G↾C Global Protocol Combinator : Deadlock freedom solely by Types! 21 Type checking by OCaml compiler ✔ ✔ deadlock-free OCaml types OCaml types OCaml types Type checking & inference Yes (!) How?
  • 22. ↓ A single OCaml program code file (.ml) OCaml Thread OCaml Thread OCaml Thread Protocol in OCaml ③ LC ⊢ PC ? ① wf(G) ? ② G↾C Global Protocol Combinator : Deadlock freedom solely by Types! 22 Type checking by OCaml compiler ✔ ✔ deadlock-free OCaml types OCaml types OCaml types Type checking & inference Yes (!) deadlock-free! How?
  • 23. ↓ A single OCaml program code file (.ml) OCaml Thread OCaml Thread OCaml Thread Protocol in OCaml ③ LC ⊢ PC ? ① wf(G) ? ② G↾C Global Protocol Combinator : Deadlock freedom solely by Types! 23 Type checking by OCaml compiler ✔ ✔ deadlock-free OCaml types OCaml types OCaml types Type checking & inference Yes (!) deadlock-free! How? How/why do they work??
  • 24. Global Combinators and well-formedness check 24 ① wf(G) ✔ let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish)) (r1 --> r2) lab : send a label lab from r1 to r2 (with possible payloads) Example: Simple OAuth protocol s c a
  • 25. Global Combinators and well-formedness check 25 ① wf(G) ✔ let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish)) (r1 --> r2) lab : send a label lab from r1 to r2 (with possible payloads) Example: Simple OAuth protocol s c a
  • 26. Global Combinators and well-formedness check 26 ① wf(G) ✔ let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish)) (r1 --> r2) lab : send a label lab from r1 to r2 (with possible payloads) Example: Simple OAuth protocol s c a
  • 27. Global Combinators and well-formedness check 27 ① wf(G) ✔ let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish)) (r1 --> r2) lab : send a label lab from r1 to r2 (with possible payloads) Example: Simple OAuth protocol s c a let oauth_branch = choice_at s (to_c login_or_cancel) (s, (s --> c) login ((c --> a) password ((a --> c) auth finish))) (s, (s --> c) cancel ((c --> a) quit finish)) choice_at r g1 g2 : decide a protocol branching at r, between g1 and g2 Example: Adding a branch to Simple OAuth protocol (a few plumbings needed to convince the type checker) Each branch must begin from s
  • 28. Global Combinators and well-formedness check 28 ① wf(G) ✔ let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish)) (r1 --> r2) lab : send a label lab from r1 to r2 (with possible payloads) Example: Simple OAuth protocol s c a let oauth_branch = choice_at s (to_c login_or_cancel) (s, (s --> c) login ((c --> a) password ((a --> c) auth finish))) (s, (s --> c) cancel ((c --> a) quit finish)) choice_at r g1 g2 : decide a protocol branching at r, between g1 and g2 NB: Branching in a protocol is a source of concurrency issues (a few plumbings needed to convince the type checker)
  • 29. Global Combinators and well-formedness check 29 ① wf(G) ✔ let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish)) (r1 --> r2) lab : send a label lab from r1 to r2 (with possible payloads) Example: Simple OAuth protocol s c a let oauth_branch = choice_at s (to_c login_or_cancel) (s, (s --> c) login ((c --> a) password ((a --> c) auth finish))) (s, (s --> c) cancel ((c --> a) quit finish)) choice_at r g1 g2 : decide a protocol branching at r, between g1 and g2 NB: Branching in a protocol is a source of concurrency issues (a few plumbings needed to convince the type checker) Non-determinism/ Deadlock in a protocol a
  • 30. Global Combinators and well-formedness check 30 ① wf(G) ✔ let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish)) (r1 --> r2) lab : send a label lab from r1 to r2 (with possible payloads) Example: Simple OAuth protocol s c a let oauth_branch = choice_at s (to_c login_or_cancel) (s, (s --> c) login ((c --> a) password ((a --> c) auth finish))) (s, (s --> c) cancel ((c --> a) quit finish)) choice_at r g1 g2 : decide a protocol branching at r, between g1 and g2 NB: Branching in a protocol is a source of concurrency issues (a few plumbings needed to convince the type checker) … is reported as a type error Non-determinism/ Deadlock in a protocol a
  • 31. (Deadlock and type errors: An analysis) 31 let oauth_branch = choice_at s (to_c login_or_cancel) (s, (s --> c) login ((c --> a) password ((a --> c) auth finish))) (s, (s --> c) cancel ((c --> a) quit finish))a poke a instead of c The MPST theory rejects it: they are not "mergeable". Forming a "mixed choice" (which causes nondeterminism) c's first action is input from s c's first action is output to a
  • 32. Deriving local types via type inference OCaml infers Local Types from global combinators. 32 ② G↾C let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish)) Example (again): Simple OAuth protocol s c a All local types are inferred at once, as a cons-list of structural types (here, s=0, c=1, a=2):
  • 33. Deriving local types via type inference OCaml infers Local Types from global combinators. 33 ② G↾C let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish)) Example (again): Simple OAuth protocol s c a All local types are inferred at once, as a cons-list of structural types (here, s=0, c=1, a=2): val oauth : [ `cons of < role_C : < login : ('a * close) out lin > > * [ `cons of < role_S : [> `login of 'a * < role_A : < password : ('b * < role_A : [> `auth of 'c * close ] inp lin >) out lin > > ] inp lin > * [ `cons of < role_C : [> `password of 'b * < role_C : < auth : ('c * close) out lin > > ] inp lin > * ([ `cons of close * 'x ] as 'x) ] ] ] Seq.t c!login s?login a!pass a?auth s!pass s?auth s c a
  • 34. Deriving local types via type inference OCaml infers Local Types from global combinators. 34 ② G↾C let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish)) Example (again): Simple OAuth protocol s c a All local types are inferred at once, as a cons-list of structural types (here, s=0, c=1, a=2): val oauth : [ `cons of < role_C : < login : ('a * close) out lin > > * [ `cons of < role_S : [> `login of 'a * < role_A : < password : ('b * < role_A : [> `auth of 'c * close ] inp lin >) out lin > > ] inp lin > * [ `cons of < role_C : [> `password of 'b * < role_C : < auth : ('c * close) out lin > > ] inp lin > * ([ `cons of close * 'x ] as 'x) ] ] ] Seq.t c!login s?login a!pass a?auth s!pass s?auth s c a Destination role's names are a method of an object < role_S < role_A < role_A
  • 35. Deriving local types via type inference OCaml infers Local Types from global combinators. 35 ② G↾C let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish)) Example (again): Simple OAuth protocol s c a All local types are inferred at once, as a cons-list of structural types (here, s=0, c=1, a=2): val oauth : [ `cons of < role_C : < login : ('a * close) out lin > > * [ `cons of < role_S : [> `login of 'a * < role_A : < password : ('b * < role_A : [> `auth of 'c * close ] inp lin >) out lin > > ] inp lin > * [ `cons of < role_C : [> `password of 'b * < role_C : < auth : ('c * close) out lin > > ] inp lin > * ([ `cons of close * 'x ] as 'x) ] ] ] Seq.t c!login s?login a!pass a?auth s!pass s?auth s c a Output labels are methods in an object < password Destination role's names are a method of an object < role_S < role_A < role_A
  • 36. Deriving local types via type inference OCaml infers Local Types from global combinators. 36 ② G↾C let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish)) Example (again): Simple OAuth protocol s c a All local types are inferred at once, as a cons-list of structural types (here, s=0, c=1, a=2): val oauth : [ `cons of < role_C : < login : ('a * close) out lin > > * [ `cons of < role_S : [> `login of 'a * < role_A : < password : ('b * < role_A : [> `auth of 'c * close ] inp lin >) out lin > > ] inp lin > * [ `cons of < role_C : [> `password of 'b * < role_C : < auth : ('c * close) out lin > > ] inp lin > * ([ `cons of close * 'x ] as 'x) ] ] ] Seq.t c!login s?login a!pass a?auth s!pass s?auth s c a Input labels are (polymorphic) variant type tags [ `login [ `auth Output labels are methods in an object < password Destination role's names are a method of an object < role_S < role_A < role_A
  • 37. let ch = get_ch c oauth (* get a MPST channel for s *) val ch : < role_S : [> `login of 'a * < role_A : < password : ('b * < role_A : [> `auth of 'c * close ] inp lin >) out lin > > ] inp lin > OCaml> let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish)) let thread_C () = match receive ch#role_S with | `login((u:string), ch)-> let ch = send ch#role_A#password "asdf" in match receive ch#role_A with | `auth((b:bool), ch) -> close ch Protocol conformance via OCaml's type checking 37 ③ LC ⊢ PC ✔
  • 38. let ch = get_ch c oauth (* get a MPST channel for s *) val ch : < role_S : [> `login of 'a * < role_A : < password : ('b * < role_A : [> `auth of 'c * close ] inp lin >) out lin > > ] inp lin > OCaml> let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish)) let thread_C () = match receive ch#role_S with | `login((u:string), ch)-> let ch = send ch#role_A#password "asdf" in match receive ch#role_A with | `auth((b:bool), ch) -> close ch Protocol conformance via OCaml's type checking 38 < role_S Select destination role via method invocation (#) role_S ③ LC ⊢ PC ✔
  • 39. let ch = get_ch c oauth (* get a MPST channel for s *) val ch : < role_S : [> `login of 'a * < role_A : < password : ('b * < role_A : [> `auth of 'c * close ] inp lin >) out lin > > ] inp lin > OCaml> let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish)) let thread_C () = match receive ch#role_S with | `login((u:string), ch)-> let ch = send ch#role_A#password "asdf" in match receive ch#role_A with | `auth((b:bool), ch) -> close ch Protocol conformance via OCaml's type checking 39 < role_S Select destination role via method invocation (#) role_S ③ LC ⊢ PC ✔ [ `login `login … and receive on it, then pattern-match the value against variant tags (labels) received payload
  • 40. let ch = get_ch c oauth (* get a MPST channel for s *) val ch : < role_S : [> `login of 'a * < role_A : < password : ('b * < role_A : [> `auth of 'c * close ] inp lin >) out lin > > ] inp lin > OCaml> let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish)) let thread_C () = match receive ch#role_S with | `login((u:string), ch)-> let ch = send ch#role_A#password "asdf" in match receive ch#role_A with | `auth((b:bool), ch) -> close ch Protocol conformance via OCaml's type checking 40 < role_S Select destination role via method invocation (#) role_S ③ LC ⊢ PC ✔ [ `login `login … and receive on it, then pattern-match the value against variant tags (labels) received payload "Next" channel is supplied as a part of the returned value
  • 41. let ch = get_ch c oauth (* get a MPST channel for s *) val ch : < role_S : [> `login of 'a * < role_A : < password : ('b * < role_A : [> `auth of 'c * close ] inp lin >) out lin > > ] inp lin > OCaml> let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish)) let thread_C () = match receive ch#role_S with | `login((u:string), ch)-> let ch = send ch#role_A#password "asdf" in match receive ch#role_A with | `auth((b:bool), ch) -> close ch Protocol conformance via OCaml's type checking 41 < role_S Select destination role via method invocation (#) role_S < role_A role_A ③ LC ⊢ PC ✔ [ `login `login … and receive on it, then pattern-match the value against variant tags (labels) received payload "Next" channel is supplied as a part of the returned value
  • 42. let ch = get_ch c oauth (* get a MPST channel for s *) val ch : < role_S : [> `login of 'a * < role_A : < password : ('b * < role_A : [> `auth of 'c * close ] inp lin >) out lin > > ] inp lin > OCaml> let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish)) let thread_C () = match receive ch#role_S with | `login((u:string), ch)-> let ch = send ch#role_A#password "asdf" in match receive ch#role_A with | `auth((b:bool), ch) -> close ch Protocol conformance via OCaml's type checking 42 < role_S Select destination role via method invocation (#) role_S < role_A role_A ③ LC ⊢ PC ✔ [ `login `login … and receive on it, then pattern-match the value against variant tags (labels) received payload "Next" channel is supplied as a part of the returned value < password #password Select an output label via method invocation (#), then send it with a payload
  • 43. let ch = get_ch c oauth (* get a MPST channel for s *) val ch : < role_S : [> `login of 'a * < role_A : < password : ('b * < role_A : [> `auth of 'c * close ] inp lin >) out lin > > ] inp lin > OCaml> let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish)) let thread_C () = match receive ch#role_S with | `login((u:string), ch)-> let ch = send ch#role_A#password "asdf" in match receive ch#role_A with | `auth((b:bool), ch) -> close ch Protocol conformance via OCaml's type checking 43 < role_S Select destination role via method invocation (#) role_S < role_A role_A role_A < role_A ③ LC ⊢ PC ✔ [ `login `login … and receive on it, then pattern-match the value against variant tags (labels) received payload "Next" channel is supplied as a part of the returned value < password #password Select an output label via method invocation (#), then send it with a payload
  • 44. let ch = get_ch c oauth (* get a MPST channel for s *) val ch : < role_S : [> `login of 'a * < role_A : < password : ('b * < role_A : [> `auth of 'c * close ] inp lin >) out lin > > ] inp lin > OCaml> let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish)) let thread_C () = match receive ch#role_S with | `login((u:string), ch)-> let ch = send ch#role_A#password "asdf" in match receive ch#role_A with | `auth((b:bool), ch) -> close ch Protocol conformance via OCaml's type checking 44 < role_S Select destination role via method invocation (#) role_S < role_A role_A `auth [ `auth role_A < role_A ③ LC ⊢ PC ✔ [ `login `login … and receive on it, then pattern-match the value against variant tags (labels) received payload "Next" channel is supplied as a part of the returned value < password #password Select an output label via method invocation (#), then send it with a payload
  • 45. let ch = get_ch s oauth (* get a MPST channel for s *) val ch : < role_S : [> `login of 'a * < role_A : < password : ('b * < role_A : [> `auth of 'c * close ] inp lin >) out lin > > ] inp lin > OCaml> let oauth = (s --> c) login ((c --> a) password ((a --> c) auth finish)) let thread_C () = match receive ch#role_S with | `login((u:string), ch)-> let ch = send ch#role_A#password "asdf" in match receive ch#role_A with | `auth((b:bool), ch) -> close ch 45 Protocol conformance via OCaml's type checking③ LC ⊢ PC ✔ ro If there is a typo … OCaml reports a type error at this point
  • 46. ↓ A single OCaml Source code file (.ml) OCaml Program OCaml Program OCaml Program Protocol in OCaml ③ LC ⊢ PC ? ① wf(G) ? ② G↾C Global Protocol Combinator : Deadlock freedom by Types! 46 Type checking by OCaml compiler ✔ ✔ deadlock-free OCaml types OCaml types OCaml types Type checking & inference Recap deadlock-free!
  • 47. ↓ A single OCaml Source code file (.ml) OCaml Program OCaml Program OCaml Program Protocol in OCaml ③ LC ⊢ PC ? ① wf(G) ? ② G↾C Global Protocol Combinator : Deadlock freedom by Types! 47 Type checking by OCaml compiler ✔ ✔ deadlock-free OCaml types OCaml types OCaml types Type checking & inference Recap deadlock-free! Are they really correct??
  • 48. GPC: Are they correct 48 A. Key idea: Global Combinators pre-generate channels ❖ Multiparty channels as nested sequence of simply-typed channels B. Formalisation of GPC with Deadlock-freedom Theorem ❖ OCamlM: A minimal concurrent language ❖ Typing rules for Global Combinators C. Implementation: GPC as a typed DSL in OCaml ❖ Based on a set of type manipulation techniques (GADTs, field label encoding, and plumbings such as polymorphic record extension) GPC key ingredients
  • 49. GPC: Are they correct 49 A. Key idea: Global Combinators pre-generate channels ❖ Multiparty channels as nested sequence of simply-typed channels B. Formalisation of GPC with Deadlock-freedom Theorem ❖ OCamlM: A minimal concurrent language ❖ Typing rules for Global Combinators C. Implementation: GPC as a typed DSL in OCaml ❖ Based on a set of type manipulation techniques (GADTs, label encoding, and plumbings such as polymorphic record extension) GPC key ingredients
  • 50. 50 Let's start cooking!! A. Key idea: Global Combinators pre-generate channels
  • 51. A. Key idea: Global Combinators pre-generate channels 51 S C A ⟨⟩ ⟨⟩ ⟨⟩ let oAuth = finish
  • 52. A. Key idea: Global Combinators pre-generate channels 52 S C A Sauth ⟨?Sauth⟩ ⟨!Sauth⟩ ⟨⟩ let oAuth = (A → C) auth finish
  • 53. A. Key idea: Global Combinators pre-generate channels 53 let oAuth = (C → A) password ((A → C) auth finish) S C A Sauth Spasswd ⟨!Spasswd; ?Sauth⟩ ⟨?Spasswd; !Sauth⟩ ⟨⟩
  • 54. A. Key idea: Global Combinators pre-generate channels 54 let oAuth = (S → C) login ((C → A) password ((A → C) auth finish)) S C A ⟨?Slogin ; !Spasswd; ?Sauth.0 ⟩ ⟨?Spasswd; !Sauth⟩ Sauth Spasswd Slogin ⟨!Slogin ⟩
  • 55. A. Key idea: Global Combinators pre-generate channels 55 let oAuth = (S → C) login ((C → A) password ((A → C) auth finish)) S C A ⟨?Slogin ; !Spasswd; ?Sauth.0 ⟩ ⟨?Spasswd; !Sauth⟩ Sauth Spasswd Slogin ⟨!Slogin ⟩
  • 56. Distribute them and start the communication 56 PS PC PA !Slogin.0| ?Slogin ; !Spasswd; ?Sauth.0| ?Spasswd;!Sauth.0
  • 57. Distribute them and start the communication 57 PS PC PA 0| !Spasswd; ?Sauth.0| ?Spasswd;!Sauth.0
  • 58. Distribute them and start the communication 58 PS PC PA 0| ?Sauth.0| !Sauth.0
  • 59. Distribute them and start the communication 59 PS PC PA 0| 0| 0
  • 60. Distribute them and start the communication 60 PS PC PA !Slogin.0| ?Slogin ; !Spasswd; ?Sauth.0| ?Spasswd;!Sauth.0 ❖ All these channels are simply-typed (hence no type-errors) ❖ Global combinators aim to be deadlock-free ❖ The nested structure enforces usage order Point
  • 61. GPC: Are they correct? (cont.) 61 A. Key idea: Global Combinators pre-generate channels ❖ Multiparty channels as nested sequence of simply-typed channels B. Formalisation of GPC (with Deadlock-freedom Theorem) ❖ OCamlM: A minimal concurrent language ❖ Typing rules for Global Combinators (with hints to OCaml DSL) ❖ Session Type merging C. Implementation: GPC as a typed DSL in OCaml ❖ Based on a set of type manipulation techniques (GADTs, field label encoding, and plumbings such as polymorphic record extension) GPC key ingredients
  • 62. B. OCamlM: Formalisation of GPC with Deadlock-freedom Theorem • A minimal concurrent language with structural subtyping, equi-recursive types and simply-typed channels • Typing rules for global combinators 62
  • 63. Typing rules 63 p1 pn … … … Point: give an index for each role (and order roles) wf(G) ✔, G↾C
  • 64. The typing rule for (-->) 64 p1 pn … pi pj … … wf(G) ✔, G↾C i
  • 65. The typing rule for (-->) 65 p1 pn … pi pj … … Index-based type update wf(G) ✔, G↾C i
  • 66. The typing rule for (-->) 66 p1 pn … pi pj … … Index-based type update p1 pn … pi pj … … "Wrap" with opponent's role names and labels wf(G) ✔, G↾C i
  • 67. The typing rule for (-->) 67 p1 pn … pi pj … … Index-based type update p1 pn … pi pj … … "Wrap" with opponent's role names and labels Implement them by using GADTs and polymorphic lens (explained later) available in OCaml wf(G) ✔, G↾C i
  • 68. The typing rule for (-->) 68 p1 pn … pi pj … … Index-based type update p1 pn … pi pj … … "Wrap" with opponent's role names and labels Requires first-class record fields (methods) and variant tags ⇒ Encode them as values encode it in OCaml Implement them by using GADTs and polymorphic lens (explained later) available in OCaml wf(G) ✔, G↾C i
  • 69. The typing rule for branching (choice_at) 69 wf(G) ✔, G↾C
  • 70. The typing rule for branching (choice_at) 70 Ensure that pa is a sending wf(G) ✔, G↾C
  • 71. The typing rule for branching (choice_at) 71 Ensure that pa is a sending Output labels must be disjoint (deterministic) wf(G) ✔, G↾C
  • 72. The typing rule for branching (choice_at) 72 Ensure that pa is a sending Output labels must be disjoint (deterministic) Merge two records (objects) into one wf(G) ✔, G↾C
  • 73. The typing rule for branching (choice_at) 73 Ensure that pa is a sending Output labels must be disjoint (deterministic) Merge two records (objects) into one Encode disjoint record merging encode it in OCaml wf(G) ✔, G↾C
  • 74. The typing rule for branching (choice_at) 74 wf(G) ✔, G↾C Too restrictive for communication protocols Solution: Subtyping! Requires each role having the same type (behaviour) in each branch → seems standard wrt. if-then-else construct, but
  • 75. The typing rule for branching (choice_at) 75 wf(G) ✔, G↾C Too restrictive for communication protocols Solution: Subtyping! Row polymorphism (objects and polymorphic variants) available in OCaml Requires each role having the same type (behaviour) in each branch → seems standard wrt. if-then-else construct, but
  • 76. Typing rules 76 … p1 pn … pi … p1 pn … pi … p1 pn … pi … Γ ⊢ choice … {g1; g2} : ⋯×p&{m1:T1, m2:T2}×⋯ Γ ⊢ g1 : ⋯×p&{m1:T1}×⋯ Γ ⊢ g2 : ⋯×p&{m2:T2}×⋯ Desired type (According to Full Merging in MPST) A problem: p&{m1:T1} ≠ p&{m2:T2}
  • 77. Typing rules 77 … p1 pn … pi … p1 pn … pi … p1 pn … pi … Γ ⊢ choice … {m1:g1; m2:g2} : ⋯×p&{m1:T1, m2:T2}×⋯ Γ ⊢ g1 : ⋯×p&{m1:T1}×⋯ Γ ⊢ g1 : ⋯×p&{m2:T2}×⋯ ? ?
  • 78. Typing rules 78 … p1 pn … pi … p1 pn … pi … p1 pn … pi … Γ ⊢ g1 : ⋯×p&{m1:T1, m2:T2}×⋯ Γ ⊢ g2 : ⋯×p&{m1:T1, m2:T2}×⋯ Γ ⊢ g1 : ⋯×p&{m1:T1}×⋯ Γ ⊢ g1 : ⋯×p&{m2:T2}×⋯ Γ ⊢ choice … {g1; g2} : ⋯×p&{m1:T1, m2:T2}×⋯ p&{m1:T1} ≤ p&{m1:T1; m2:T2} p&{m2:T2} ≤ p&{m1:T1; m2:T2} Subtyping!!
  • 79. Deadlock and type errors: An analysis 79 let oauth_branch = choice_at s (to_c login_or_cancel) (s, (s --> c) login ((c --> a) password ((a --> c) auth finish))) (s, (s --> c) cancel ((c --> a) quit finish))a poke a instead of c The MPST theory rejects it: they are not "mergeable". Forming a "mixed choice" (which causes nondeterminism)
  • 80. Deadlock and type errors: An analysis 80 let oauth_branch = choice_at s (to_c login_or_cancel) (s, (s --> c) login ((c --> a) password ((a --> c) auth finish))) (s, (s --> c) cancel ((c --> a) quit finish))a poke a instead of c The MPST theory rejects it: they are not "mergeable". Forming a "mixed choice" (which causes nondeterminism) c's first action is output to a <a: <quit: !bool*cont2>>
  • 81. Deadlock and type errors: An analysis 81 let oauth_branch = choice_at s (to_c login_or_cancel) (s, (s --> c) login ((c --> a) password ((a --> c) auth finish))) (s, (s --> c) cancel ((c --> a) quit finish))a poke a instead of c The MPST theory rejects it: they are not "mergeable". Forming a "mixed choice" (which causes nondeterminism) c's first action is input from s <s: ?[login_str*cont1]> c's first action is output to a <a: <quit: !bool*cont2>>
  • 82. Deadlock and type errors: An analysis 82 let oauth_branch = choice_at s (to_c login_or_cancel) (s, (s --> c) login ((c --> a) password ((a --> c) auth finish))) (s, (s --> c) cancel ((c --> a) quit finish))a poke a instead of c The MPST theory rejects it: they are not "mergeable". Forming a "mixed choice" (which causes nondeterminism) c's first action is input from s <s: ?[login_str*cont1]> c's first action is output to a <a: <quit: !bool*cont2>> No least upper bound (common supertype) ⇒ type error No least upper bound (common supertype) ⇒ type error
  • 83. A note on typing 83 <r: ?[lab: T1*T2]> <r: <lab: !T1*T2>> Input and output session types are not symmetric with each other. Why? sok : ?bool, scancel : ?int : ?[ok_(boolו); cancel_(int× …)] (← wanted) Making a multiplexed channel from simply-typed channels
  • 84. A note on typing 84 <r: ?[lab: T1*T2]> <r: <lab: !T1*T2>> Input and output session types are not symmetric with each other. Why? sok : ?bool, scancel : ?int : ?[ok_(boolו); cancel_(int× …)] (← wanted) choose : List[?T] -> ?T makes a (multiplexed) channel (external choice) wrap : (α -> β) -> ?α -> ?β makes a wrapped channel Concurrent ML (Reppy, 1993) Types are slightly modified, they uses "events" in reality Making a multiplexed channel from simply-typed channels
  • 85. A note on typing 85 <r: ?[lab: T1*T2]> <r: <lab: !T1*T2>> Input and output session types are not symmetric with each other. Why? sok : ?bool, scancel : ?int wrap (λx.[ok=(x,•)]) sok : ?[ok_(boolו)] wrap (λx.[cancel=(x,…)]) scancel : ?[cancel_(int×…)] : ?[ok_(boolו); cancel_(int× …)] (← wanted) choose : List[?T] -> ?T makes a (multiplexed) channel (external choice) wrap : (α -> β) -> ?α -> ?β makes a wrapped channel Concurrent ML (Reppy, 1993) Types are slightly modified, they uses "events" in reality Making a multiplexed channel from simply-typed channels
  • 86. A note on typing 86 <r: ?[lab: T1*T2]> <r: <lab: !T1*T2>> Input and output session types are not symmetric with each other. Why? sok : ?bool, scancel : ?int wrap (λx.[ok=(x,•)]) sok : ?[ok_(boolו)] wrap (λx.[cancel=(x,…)]) scancel : ?[cancel_(int×…)] List(wrap (λx.[ok=(x,•)]) sok; wrap (λx.[cancel=(x,…)]) scancel) : List[ ?[ok_(boolו), cancel_(int×…)] ] : ?[ok_(boolו); cancel_(int× …)] (← wanted) choose : List[?T] -> ?T makes a (multiplexed) channel (external choice) wrap : (α -> β) -> ?α -> ?β makes a wrapped channel Concurrent ML (Reppy, 1993) Types are slightly modified, they uses "events" in reality Making a multiplexed channel from simply-typed channels
  • 87. A note on typing 87 <r: ?[lab: T1*T2]> <r: <lab: !T1*T2>> Input and output session types are not symmetric with each other. Why? sok : ?bool, scancel : ?int wrap (λx.[ok=(x,•)]) sok : ?[ok_(boolו)] wrap (λx.[cancel=(x,…)]) scancel : ?[cancel_(int×…)] List(wrap (λx.[ok=(x,•)]) sok; wrap (λx.[cancel=(x,…)]) scancel) : List[ ?[ok_(boolו), cancel_(int×…)] ] choose (List(wrap (λx.[ok=(x,•)]) sok; wrap (λx.[cancel=(x,…)]) scancel)) : ?[ok_(boolו); cancel_(int× …)] (← wanted) choose : List[?T] -> ?T makes a (multiplexed) channel (external choice) wrap : (α -> β) -> ?α -> ?β makes a wrapped channel Concurrent ML (Reppy, 1993) Types are slightly modified, they uses "events" in reality Making a multiplexed channel from simply-typed channels
  • 88. GPC: Are they correct? (cont.) 88 A. Key idea: Global Combinators pre-generate channels ❖ Multiparty channels as nested sequence of simply-typed channels B. Formalisation of GPC (with Deadlock-freedom Theorem) ❖ OCamlM: A minimal concurrent language ❖ Typing rules for Global Combinators (with hints to OCaml DSL) ❖ Session Type merging C. Implementation: GPC as a typed DSL in OCaml ❖ Based on a set of type manipulation techniques (GADTs, field label encoding, and details of plumbings for polymorphic record extension) ❖ Benchmarks: Garbage collection matters ❖ Linearity monad GPC key ingredients Please ask me over beer!
  • 89. GPC wrap up 89 Global Protocol Combinator: a DSL for writing global protocols ❖ Key Ingredients: Global Combinators ❖ Covers all basic MPST features (including full merging) ❖ Extensions: HTTP, and OAuth Example (on top of it), and more OCamlM: fomalisation of a minimal programming language for GPC ❖ Subject Reduction, Operational Correspondence and Deadlock-freedom ❖ Types for global combinators ❖ Merging is a least upper bound in subtyping relation Sauth Spasswd let oauth = (s --> c) login … p1 pn … … …
  • 90. Future Work 90 A → B B → C A → B • Deadlock-freedom proof on full global combinators ❖ Including more expressive ones (e.g. relaxed loop conditions) ❖ Scatter/Gather (broadcast), undirected internal choice, … • Implementation in other programming languages ❖ TypeScript (structural subtyping from beginning, and will have recursive types as well) ❖ Haskell (automatically construct global combinators via type classes) Thank you!
  • 92. Loops are easy (for now) 92 let oAuth = (S → C) login ((C → A) password ((A → C) auth finish)) S C A ⟨?Slogin ; !Spasswd; ?Sauth.0 ⟩ ⟨?Spasswd; !Sauth⟩ Sauth Spasswd Slogin ⟨?Slogin ⟩
  • 93. Loops are easy (for now) 93 let oAuth = fix (λx. (S → C) login ((C → A) password ((A → C) auth x)) S C A μx.⟨?Slogin ; !Spasswd; ?Sauth; x ⟩ μx. ⟨?Spasswd; !Sauth; x⟩ Sauth Spasswd Slogin μx. ⟨?Slogin; x⟩
  • 94. Branchings? 94 S C A Sauth Spasswd Slogin (S → C) login ((C → A) password ((A → C) auth finish)) (S → C) cancel ((C → A) quit finish) S C A Squit Scancel +?
  • 95. Input / output primitives and row-polymorphism in OCaml 95 let thread_A () = let `password((p:string), ch) = receive ch#role_C in let ch = send ch#role_C#auth true in close ch (FP's type inference-friendly structural typing)
  • 96. Input / output primitives and row-polymorphism in OCaml 96 let thread_A () = let `password((p:string), ch) = receive ch#role_C in let ch = send ch#role_C#auth true in close ch (FP's type inference-friendly structural typing) Input labels are polymorphic variants Input labels are polymorphic variants
  • 97. Input / output primitives and row-polymorphism in OCaml 97 let thread_A () = let `password((p:string), ch) = receive ch#role_C in let ch = send ch#role_C#auth true in close ch (FP's type inference-friendly structural typing) Input labels are polymorphic variants Input labels are polymorphic variants Output labels are methods in an object (fields in a polymorphic record) Output labels are methods in an object (fields in a polymorphic record)
  • 98. Input / output primitives and row-polymorphism in OCaml 98 let thread_A () = let `password((p:string), ch) = receive ch#role_C in let ch = send ch#role_C#auth true in close ch OCaml's row-polymorphism simulates session-type subtyping (FP's type inference-friendly structural typing) Input labels are polymorphic variants Input labels are polymorphic variants Output labels are methods in an object (fields in a polymorphic record) Output labels are methods in an object (fields in a polymorphic record)
  • 99. Input / output primitives and row-polymorphism in OCaml 99 let thread_A () = let `password((p:string), ch) = receive ch#role_C in let ch = send ch#role_C#auth true in close ch OCaml's row-polymorphism simulates session-type subtyping (FP's type inference-friendly structural typing) Input labels are polymorphic variants Input labels are polymorphic variants Output labels are methods in an object (fields in a polymorphic record) Output labels are methods in an object (fields in a polymorphic record) val ch : < role_C : [< `password of string * < role_C : < auth : (bool * close) out lin; .. >; .. > ] inp lin; .. > -> unit
  • 100. Input / output primitives and row-polymorphism in OCaml 100 let thread_A () = let `password((p:string), ch) = receive ch#role_C in let ch = send ch#role_C#auth true in close ch OCaml's row-polymorphism simulates session-type subtyping (FP's type inference-friendly structural typing) Input labels are polymorphic variants Input labels are polymorphic variants Output labels are methods in an object (fields in a polymorphic record) Output labels are methods in an object (fields in a polymorphic record) val ch : < role_C : [< `password of string * < role_C : < auth : (bool * close) out lin; .. >; .. > ] inp lin; .. > -> unit Inferred polymorphic variant type: it can have less receiving labels (= in this case it must have password at least since there must be one)
  • 101. Input / output primitives and row-polymorphism in OCaml 101 let thread_A () = let `password((p:string), ch) = receive ch#role_C in let ch = send ch#role_C#auth true in close ch OCaml's row-polymorphism simulates session-type subtyping (FP's type inference-friendly structural typing) Input labels are polymorphic variants Input labels are polymorphic variants Output labels are methods in an object (fields in a polymorphic record) Output labels are methods in an object (fields in a polymorphic record) val ch : < role_C : [< `password of string * < role_C : < auth : (bool * close) out lin; .. >; .. > ] inp lin; .. > -> unit Inferred polymorphic variant type: it can have less receiving labels (= in this case it must have password at least since there must be one) Inferred object type: it can have more sending labels
  • 102. Branching 102 let oauth1 = choice_at s (to_c login_or_cancel) (s, (s --> c) login @@ (c --> a) password @@ (a --> c) auth finish) (s, (s --> c) cancel @@ (c --> a) quit finish) A protocol with branching: let thread_C () = match receive ch#role_S with | `cancel((code:int), ch) -> close (send chc#role_A#quit ()) | `login((), ch) -> let ch = send ch#role_A#password "asdf" in let `auth(b, ch) = receive ch#role_A in close ch Code for C (waiting for S with an external choice):
  • 103. Branching 103 let oauth1 = choice_at s (to_c login_or_cancel) (s, (s --> c) login @@ (c --> a) password @@ (a --> c) auth finish) (s, (s --> c) cancel @@ (c --> a) quit finish) A protocol with branching: S will decide a branch, then C and A will follow let thread_C () = match receive ch#role_S with | `cancel((code:int), ch) -> close (send chc#role_A#quit ()) | `login((), ch) -> let ch = send ch#role_A#password "asdf" in let `auth(b, ch) = receive ch#role_A in close ch Code for C (waiting for S with an external choice):
  • 104. Branching 104 let oauth1 = choice_at s (to_c login_or_cancel) (s, (s --> c) login @@ (c --> a) password @@ (a --> c) auth finish) (s, (s --> c) cancel @@ (c --> a) quit finish) A protocol with branching: S will decide a branch, then C and A will follow let thread_C () = match receive ch#role_S with | `cancel((code:int), ch) -> close (send chc#role_A#quit ()) | `login((), ch) -> let ch = send ch#role_A#password "asdf" in let `auth(b, ch) = receive ch#role_A in close ch Code for C (waiting for S with an external choice):An external choice is a pattern matching (idiomatic OCaml)
  • 105. Loops and delegations (1) 105 let oauth2 = fix (fun self -> choice_at s (to_c login_cancel_or_retry) (s, oauth1 ()) (s, (s --> c) retry @@ (c --> a) retry self)) Thanks to OCaml's equi-recursive types (built in polymorphic variants and objects by default), programmers can handle recursions very naturally:
  • 106. Loops and delegations (1) 106 let oauth2 = fix (fun self -> choice_at s (to_c login_cancel_or_retry) (s, oauth1 ()) (s, (s --> c) retry @@ (c --> a) retry self)) recursionrecursion Thanks to OCaml's equi-recursive types (built in polymorphic variants and objects by default), programmers can handle recursions very naturally:
  • 107. Loops and delegations (1) 107 let oauth2 = fix (fun self -> choice_at s (to_c login_cancel_or_retry) (s, oauth1 ()) (s, (s --> c) retry @@ (c --> a) retry self)) recursionrecursion protocol reuse Thanks to OCaml's equi-recursive types (built in polymorphic variants and objects by default), programmers can handle recursions very naturally:
  • 108. Loops and delegations (1) 108 let oauth2 = fix (fun self -> choice_at s (to_c login_cancel_or_retry) (s, oauth1 ()) (s, (s --> c) retry @@ (c --> a) retry self)) recursionrecursion protocol reuse val ch_S : < role_C : < cancel : ('_b * close) out lin; login : ('_c * close) out lin; retry : ('_d * 'a) out lin > > as 'a OCaml> Thanks to OCaml's equi-recursive types (built in polymorphic variants and objects by default), programmers can handle recursions very naturally:
  • 109. Loops and delegations (1) 109 let oauth2 = fix (fun self -> choice_at s (to_c login_cancel_or_retry) (s, oauth1 ()) (s, (s --> c) retry @@ (c --> a) retry self)) recursionrecursion protocol reuse val ch_S : < role_C : < cancel : ('_b * close) out lin; login : ('_c * close) out lin; retry : ('_d * 'a) out lin > > as 'a OCaml> recursionrecursion Thanks to OCaml's equi-recursive types (built in polymorphic variants and objects by default), programmers can handle recursions very naturally:
  • 110. Loops and delegations (2) 110 let oauth_deleg = (mst --> wrk) (msg >: get_prot s oauth2) finish Delegation doesn't need any special treatment, since OCaml will just infer the delegated type. However, you can annotate labels with a delegated protocol, like this: val ch_Mst : < role_Wrk : < msg : (< role_C : < cancel : ('_b * close) out lin; login : ('_c * close) out lin; retry : ('_d * 'a) out lin > > as 'a * close) out lin > > OCaml> Delegated type
  • 111. Detecting protocol errors using types 111 Non-determinism/ Deadlock in a protocol let oauth1 = choice_at s (to_c login_or_cancel) (s, (s --> c) login @@ (c --> a) password @@ (a --> c) auth finish) (s, (s --> a) cancel @@ (c --> a) quit finish) NB: Branching is a source of concurrency issues
  • 112. Detecting protocol errors using types 112 Non-determinism/ Deadlock in a protocol let oauth1 = choice_at s (to_c login_or_cancel) (s, (s --> c) login @@ (c --> a) password @@ (a --> c) auth finish) (s, (s --> a) cancel @@ (c --> a) quit finish) … is also reported as a type error NB: Branching is a source of concurrency issues
  • 113. Detecting protocol errors using types 113 Non-determinism/ Deadlock in a protocol let oauth1 = choice_at s (to_c login_or_cancel) (s, (s --> c) login @@ (c --> a) password @@ (a --> c) auth finish) (s, (s --> a) cancel @@ (c --> a) quit finish) … is also reported as a type error Theorem: if a global type G is well-formed, its encoding to a global combinator g =⟦G⟧ is well-typed in OCamlM. NB: Branching is a source of concurrency issues
  • 114. Detecting protocol errors using types 114 Non-determinism/ Deadlock in a protocol let oauth1 = choice_at s (to_c login_or_cancel) (s, (s --> c) login @@ (c --> a) password @@ (a --> c) auth finish) (s, (s --> a) cancel @@ (c --> a) quit finish) … is also reported as a type error Theorem: if a global type G is well-formed, its encoding to a global combinator g =⟦G⟧ is well-typed in OCamlM. NB: Branching is a source of concurrency issues Global Combinators have full expressivity of MPST Global Types
  • 115. [Formalisation] OCamlM : a Minimal calculus for global combinators Main results: 115 A calculus with structural subtyping, equi-recursive types and i/o-typed channels Theorem (Subject Reduction): if ⊢ e and e→* e' then ⊢ e' Theorem (Operational Correspondence): (Completeness) (Soundness) Corollary (Deadlock Freedom): If an MPST process P is deadlock-free, OCamlM expression e=⟦P⟧ is deadlock-free.
  • 116. Other features and Examples ✔ Branchings, loops, delegations ❖ Allows full merging in a branching (next slide) ✔ MPST as a wrapper ❖ Offers global protocol on top of HTTP, DNS, … ❖ Example: OAuth, DNS server, SMTP client, … ❖ Utilise concurrent/distributed libraries: Lwt (lightweight threads) and Unix IPC ✔ More Extensions ❖ Scatter/Gather (broadcast) ❖ Undirected choice (-nolive) ❖ Unbalanced Loops 116 B⊕m1 C⊕m2 B⊕m1C⊕m2 A → B B → C A → B
  • 117. Full merging 117 let oauth1 = choice_at s (to_c login_or_cancel) (s, (s --> c) login @@ (c --> a) password @@ (a --> c) auth finish) (s, (s --> c) cancel @@ (c --> a) quit finish) Input labels are polymorphic variantsA can have different input branches Example: A branch happens between S and C. ⇒ Merge A's two behaviours into one Merging strategy Synopsis Implementations Plain merging All branches must have same labels/continuation (restrictive) Scalas et al. (ECOOP 2017) ✔ Full merging Different input labels/continuations can be mergeable (more relaxed) This work
  • 118. • Benchmarks reflect our design decision to use mutable long lived objects (e.g channel vectors) ❖ Our work: few mutable long lived objects, created at the start of the protocol ❖ State-of-the-art (linear-decomposition [Scala et.a]): many small channels, created on-demand (during the protocol execution) 118
  • 119. Benchmarks • Comparison with Linear (Binary) Decomposition [Scalas et al., 2017] ❖ Translation from MPST to Linear Types ❖ Continuation Passing Style (CPS): It creates (and exchanges) a fresh channel at each communication step ❖ Must be slower than us?? • Compete with ours in some cases (!), but CPS is slower in general ❖ OCaml's major GC is doing nice work • Monad (static linearity checking with overhead) VS. Direct style (dynamic) 119
  • 120. Put All Slides in right contexts!! • Most surprising parts: • (what is it) 簡単に? programmers can write like this… select opponent role by method, then (a) send by method / (b) receive it and pattern match on variants. Errors are detected like this… GC well-formedness errors and Local type conformance errors. Bonus: recursive sessions, session subtyping and delegations are all free. • (why/how gc-like typing is possible??) (1) (why EPP is possible, it is operation on types!!: see onion and --> typing.) (2) (why well-formedness checking is possible? What is well-formedness?: see typing rules) • (key idea) タマネギ.2枚くらいにおさめる • (how it is typed) --> typing and implementation (mention that OCaml do not have such first-class?) • (how deadlock is detected: harder) choice, nondeterminisim and deadlock choice is like an if-then-else. Two branches are merged into one. (Sub)typing and global combinator typing prevents occasional wrong branching. • (how it is imlpemented) lenses and first class record fields • Choice_at typing and record extensions ❖ Least upper bound is merging ❖ We have more expressive GTs ❖ Subtyping and equi-recursive types ❖ Unguardedness and Unbalanced merging • Linearity monad • Deadlock freeness, syntax of local types, and undirected choice (sending and receiving) • Benchmarks • Meaning of type errors and relationship to deadlocks ❖ Mergeability and local type syntax ❖ Possibility to extension (i.e. non-directed merging) ❖ Why roles are record fields – what if it was variant tags 120
  • 121. Channel Vectors: Inhabiting MPSTs as simple channel types 121 TA = B⊕{ok.•; cancel.B&cancel.•} TB = A&{ok.•; cancel.B⊕cancel.•}
  • 122. Channel Vectors: Inhabiting MPSTs as simple channel types 122 sok scancel1 scancel2 sok scancel1 scancel2 Idea: Put simply-typed channels in a tree-like data structure TA = B⊕{ok.•; cancel.B&cancel.•} TB = A&{ok.•; cancel.B⊕cancel.•}
  • 123. Internal Choice is Record A record having pairs of an output channel and "the rest" in its fields 123 ⟦ B⊕{ok.•; cancel.B&cancel(int).•} ⟧s = <B = <ok= (sok, •); cancel= (scancel1, ⟦...⟧s)> > Pictorially:
  • 124. Internal Choice is Record A record having pairs of an output channel and "the rest" in its fields 124 ⟦ B⊕{ok.•; cancel.B&cancel(int).•} ⟧s = <B = <ok= (sok, •); cancel= (scancel1, ⟦...⟧s)> > (scancel, )(sok, ) … ok cancel Pictorially:
  • 125. Internal Choice is Record A record having pairs of an output channel and "the rest" in its fields 125 ⟦ B⊕{ok.•; cancel.B&cancel(int).•} ⟧s = : ⟨B : ⟨ok: !(int*int)ו; cancel: !(bool) ×⟦…⟧⟩ ⟩ Provided that • sok : Och, scancel : Och (! is an output channel type) <B = <ok= (sok, •); cancel= (scancel1, ⟦...⟧s)> > (scancel, )(sok, ) … ok cancel Pictorially:
  • 126. External choice is variant input 126 Variant input type: ?[ok_(boolו); cancel_(int× …)] Variant type: [ok_(boolו); cancel_(int× …)] ("Either ok (with boolו) or cancel (with int×…)") ("Receives either ok (with boolו) or cancel (with int×…)") cancel(_, )ok(_, ) scancel1sok cancel external choice Pictorially: But how?
  • 127. A Solution from Concurrent ML (Reppy, 1993) 127 … has a set of (event) primitives we need! choose : List[?T] -> ?T makes a (multiplexed) channel (external choice) wrap : (α -> β) -> ?α -> ?β makes a wrapped channel sok : ?bool, scancel : ?int : ?[ok_(boolו); cancel_(int× …)] (← wanted)
  • 128. A Solution from Concurrent ML (Reppy, 1993) 128 … has a set of (event) primitives we need! choose : List[?T] -> ?T makes a (multiplexed) channel (external choice) wrap : (α -> β) -> ?α -> ?β makes a wrapped channel sok : ?bool, scancel : ?int wrap (λx.[ok=(x,•)]) sok : ?[ok_(boolו)] wrap (λx.[cancel=(x,…)]) scancel : ?[cancel_(int×…)] : ?[ok_(boolו); cancel_(int× …)] (← wanted)
  • 129. A Solution from Concurrent ML (Reppy, 1993) 129 … has a set of (event) primitives we need! choose : List[?T] -> ?T makes a (multiplexed) channel (external choice) wrap : (α -> β) -> ?α -> ?β makes a wrapped channel sok : ?bool, scancel : ?int wrap (λx.[ok=(x,•)]) sok : ?[ok_(boolו)] wrap (λx.[cancel=(x,…)]) scancel : ?[cancel_(int×…)] List(wrap (λx.[ok=(x,•)]) sok; wrap (λx.[cancel=(x,…)]) scancel) : List[ ?[ok_(boolו), cancel_(int×…)] ] : ?[ok_(boolו); cancel_(int× …)] (← wanted)
  • 130. A Solution from Concurrent ML (Reppy, 1993) 130 … has a set of (event) primitives we need! choose : List[?T] -> ?T makes a (multiplexed) channel (external choice) wrap : (α -> β) -> ?α -> ?β makes a wrapped channel sok : ?bool, scancel : ?int wrap (λx.[ok=(x,•)]) sok : ?[ok_(boolו)] wrap (λx.[cancel=(x,…)]) scancel : ?[cancel_(int×…)] List(wrap (λx.[ok=(x,•)]) sok; wrap (λx.[cancel=(x,…)]) scancel) : List[ ?[ok_(boolו), cancel_(int×…)] ] choose (List(wrap (λx.[ok=(x,•)]) sok; wrap (λx.[cancel=(x,…)]) scancel)) : ?[ok_(boolו); cancel_(int× …)] (← wanted)
  • 131. A Solution from Concurrent ML (Reppy, 1993) 131 … has a set of (event) primitives we need! choose : List[?T] -> ?T makes a (multiplexed) channel (external choice) wrap : (α -> β) -> ?α -> ?β makes a wrapped channel sok : ?bool, scancel : ?int wrap (λx.[ok=(x,•)]) sok : ?[ok_(boolו)] wrap (λx.[cancel=(x,…)]) scancel : ?[cancel_(int×…)] List(wrap (λx.[ok=(x,•)]) sok; wrap (λx.[cancel=(x,…)]) scancel) : List[ ?[ok_(boolו), cancel_(int×…)] ] choose (List(wrap (λx.[ok=(x,•)]) sok; wrap (λx.[cancel=(x,…)]) scancel)) cancel(_, )ok(_, ) scancel1 sok (scancel2, ) cancel choose : ?[ok_(boolו); cancel_(int× …)] (← wanted)
  • 132. Putting them altogether 132 (scancel, )(sok, ) ok cancel cancel(_, )ok(_, ) scancel1 sok (scancel2, ) cancel choose B⊕{ok(bool).•; cancel(int).B&cancel(int).•} A&{ok(bool).•; cancel(int).A⊕cancel(int).•} choice_at A {(A → B) ok finish, (A → B) cancel((B → A) cancel finish)} cancel(_, ) scancel2
  • 133. Putting them altogether 133 (scancel, )(sok, ) ok cancel cancel(_, )ok(_, ) scancel1 sok (scancel2, ) cancel choose B⊕{ok(bool).•; cancel(int).B&cancel(int).•} A&{ok(bool).•; cancel(int).A⊕cancel(int).•} choice_at A {(A → B) ok finish, (A → B) cancel((B → A) cancel finish)} cancel(_, ) scancel2