Library Io.Evaluate
Require Import FunctionNinjas.All.
Require Import Io.All.
Import C.Notations.
Require Import Io.All.
Import C.Notations.
Evaluate the commands of a computation.
Fixpoint command {E1 E2 : Effect.t} {A : Type}
(run : ∀ (c : Effect.command E1), C.t E2 (Effect.answer E1 c))
(x : C.t E1 A) : C.t E2 A :=
match x with
| C.Ret _ x ⇒ C.Ret _ x
| C.Call c ⇒ run c
| C.Let _ _ x f ⇒ C.Let _ _ (command run x) (fun x ⇒ command run (f x))
| C.Join _ _ x y ⇒ C.Join _ _ (command run x) (command run y)
| C.Choose _ x y ⇒ C.Choose _ (command run x) (command run y)
end.
Fixpoint exception {E1 E2 : Effect.t} {Exc A : Type}
(run : ∀ (c : Effect.command E1), C.t E2 (Effect.answer E1 c + Exc))
(run_join : Exc → Exc → Exc) (x : C.t E1 A) : C.t E2 (A + Exc) :=
match x with
| C.Ret _ x ⇒ ret @@ inl x
| C.Call c ⇒ run c
| C.Let _ _ x f ⇒
let! x := exception run run_join x in
match x with
| inl x ⇒ exception run run_join (f x)
| inr exc ⇒ ret @@ inr exc
end
| C.Join _ _ x y ⇒
let! xy := join (exception run run_join x) (exception run run_join y) in
match xy with
| (inl x, inl y) ⇒ ret @@ inl (x, y)
| (inr exc, inl _) | (inl _, inr exc) ⇒ ret @@ inr exc
| (inr exc_x, inr exc_y) ⇒ ret @@ inr (run_join exc_x exc_y)
end
| C.Choose _ x y ⇒
choose (exception run run_join x) (exception run run_join y)
end.
(run : ∀ (c : Effect.command E1), C.t E2 (Effect.answer E1 c))
(x : C.t E1 A) : C.t E2 A :=
match x with
| C.Ret _ x ⇒ C.Ret _ x
| C.Call c ⇒ run c
| C.Let _ _ x f ⇒ C.Let _ _ (command run x) (fun x ⇒ command run (f x))
| C.Join _ _ x y ⇒ C.Join _ _ (command run x) (command run y)
| C.Choose _ x y ⇒ C.Choose _ (command run x) (command run y)
end.
Fixpoint exception {E1 E2 : Effect.t} {Exc A : Type}
(run : ∀ (c : Effect.command E1), C.t E2 (Effect.answer E1 c + Exc))
(run_join : Exc → Exc → Exc) (x : C.t E1 A) : C.t E2 (A + Exc) :=
match x with
| C.Ret _ x ⇒ ret @@ inl x
| C.Call c ⇒ run c
| C.Let _ _ x f ⇒
let! x := exception run run_join x in
match x with
| inl x ⇒ exception run run_join (f x)
| inr exc ⇒ ret @@ inr exc
end
| C.Join _ _ x y ⇒
let! xy := join (exception run run_join x) (exception run run_join y) in
match xy with
| (inl x, inl y) ⇒ ret @@ inl (x, y)
| (inr exc, inl _) | (inl _, inr exc) ⇒ ret @@ inr exc
| (inr exc_x, inr exc_y) ⇒ ret @@ inr (run_join exc_x exc_y)
end
| C.Choose _ x y ⇒
choose (exception run run_join x) (exception run run_join y)
end.