# POPL Tutorial/CPS Solutions

 This is Literate TwelfCode: hereStatus: %% OK %% Output: here.

## Problem 1: CPS Conversion with Administrative Redices

```tp : type.
o  : tp.
=> : tp -> tp -> tp.           %infix right 3 =>.

exp   : tp -> type.
value : tp -> type.
app   : exp (A => B) -> exp A -> exp B.
lam   : (value A -> exp B) -> value (A => B).
ret   : value A -> exp A.
%block sourceb : some {A : tp} block {x : value A}.
%worlds (sourceb) (exp _) (value _).

contra : type.
cvalue : tp -> type.
ccont  : tp -> type.
capp   : cvalue (A => B) -> cvalue A -> ccont B -> contra.
clam   : (cvalue A -> ccont B -> contra) -> cvalue (A => B).
cconti : (cvalue A -> contra) -> ccont A.
cthrow : ccont A -> cvalue A -> contra.
%block targetb1 : some {A : tp} block {x : cvalue A}.
%block targetb2 : some {A : tp} block {x : ccont A}.
%worlds (targetb1 | targetb2) (contra) (cvalue _) (ccont _).

cps : value A -> cvalue A -> type.
%mode cps +X1 -X2.

cpse : exp A -> (ccont A -> contra) -> type.
%mode cpse +X1 -X2.

cps/lam : cps (lam (E:value A -> exp B))
(clam (E':cvalue A -> ccont B -> contra))
<- ({x:value A}{x':cvalue A} cps x x' -> cpse (E x) (E' x')).
cpse/app : cpse (app (E1:exp (B => A)) (E2:exp B))
([c:ccont A] E1' (cconti ([f:cvalue (B => A)]
E2' (cconti([x:cvalue B]
capp f x c)))))
<- cpse E1 (E1':ccont (B => A) -> contra)
<- cpse E2 (E2':ccont B -> contra).
cpse/ret : cpse (ret (V:value A)) ([c:ccont A] cthrow c V')
<- cps V (V':cvalue A).

%block cpsb : some {A : tp} block {x : value A} {x' : cvalue A} {d : cps x x'}.
%worlds (cpsb) (cps _ _) (cpse _ _).
%total (E V) (cps E _) (cpse V _).```

See POPL Tutorial/CPS_Solution2 for the solution to the second CPS problem.