Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Session types are broken in CBV mode #225

Open
thwfhk opened this issue Aug 14, 2023 · 0 comments
Open

Session types are broken in CBV mode #225

thwfhk opened this issue Aug 14, 2023 · 0 comments

Comments

@thwfhk
Copy link

thwfhk commented Aug 14, 2023

It seems that the safety of session types is broken due to the existence of Axiom K in the default call-by-value mode. We can write the following well-typed program

forkLinearWrapper : forall {s : Protocol} . () -> (LChan s -> ()) -> LChan (Dual s)
forkLinearWrapper () f = forkLinear f

test : forall {s : Protocol} . (LChan s -> ()) [] -> (LChan (Dual s)) []
test [f] = [forkLinearWrapper () f]

sender : LChan (Send Int End) -> ()
sender c =
  let c' = send c 42 in
  close c'

receiver : LChan (Recv Int End) -> Int
receiver c =
  let (i, c') = recv c in
  let () = close c' in
  i

main : Int
main = let [ch] = test [sender] in receiver ch + receiver ch

which gets stuck:

Granule> main
thread blocked indefinitely in an MVar operation

We can change the definition of test to the following still well-typed version

axiomk : forall {a : Type, b : Type} . (a -> b) [] -> a [] -> b []
axiomk [f] [x] = [f x]

test : forall {s : Protocol} . (LChan s -> ()) [] -> (LChan (Dual s)) []
test [f] = axiomk [forkLinearWrapper ()] [f]

which gives us a different runtime error:

Granule> main
Bug in Granule. Trying to fork: [\( internal1 : LChan (Send Int End)) -> 
    (case ((,) ())  internal1 of
      (,) _ c`0 -> let c'`1 = (send c`0) 42 in close c'`1)]
CallStack (from HasCallStack):
  error, called at src/Language/Granule/Interpreter/Eval.hs:787:15 in granule-interpreter-0.9.4.0-LnVThkA1TJl3beGnwGjlFQ:Language.Granule.Interpreter.Eval

Note that using forkLinearWrapper is necessary, because Granule has some existing mechanism to avoid the issue of Axiom K in CBV mode (probably the resourceAllocator predicate in the slides? I didn't find the corresponding paper). For instance, the following program is ill-typed.

test : forall {s : Protocol} . (LChan s -> ()) [] -> (LChan (Dual s)) []
test [f] = [forkLinear f]

Granule> :l axiomk.gr 
Unpromotable error: axiomk.gr:10:12:
Cannot promote a value of type `(LChan (Dual s)) [(0 : Ext Nat)..∞]` in call-by-value mode.

However, the existing mechanism is quite fragile; it can be easily broken by wrapping resourceAllocators in other functions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant