cek-call-cc/src/Project/Cesk.agda

67 lines
2.1 KiB
Agda
Raw Normal View History

2021-12-08 00:33:28 -06:00
module Project.Cesk where
2021-12-09 05:28:25 -06:00
open import Relation.Binary.PropositionalEquality
open import Data.Nat
2021-12-08 00:33:28 -06:00
open import Data.Product renaming (_,_ to ⦅_,_⦆)
2021-12-09 02:05:20 -06:00
open import Project.Definitions
2021-12-08 00:33:28 -06:00
open import Project.Util using (_$_)
2021-12-09 02:05:20 -06:00
open import Project.Do
2021-12-08 00:33:28 -06:00
open Aexp
open Value
open State
2021-12-09 06:00:09 -06:00
astep : { Γ A} Aexp Γ A Env Γ Value A
2021-12-09 02:05:20 -06:00
astep (value v) _ = v
2021-12-08 00:33:28 -06:00
astep zero _ = zero
astep (suc c) e = suc $ astep c e
astep (` id) e = lookup e id
astep (ƛ body) e = clo body e
2021-12-09 06:00:09 -06:00
inject : {A : Type} Exp A A State A
2021-12-08 02:30:29 -06:00
inject {A} C = mkState A C halt
2021-12-08 00:33:28 -06:00
step : { : Type} State StepResult
2021-12-09 02:05:20 -06:00
step (mkState Tc Γ (atomic x) E K) = apply-kont K $ astep x E
step (mkState Tc Γ (case C isZ isS) E K) with astep C E
... | zero = part $ mkState Tc Γ isZ E K
... | suc n = part $ mkState Tc Γ (isS · value n) E K
step (mkState Tc Γ (x₁ · x₂) E K) with astep x₁ E
... | clo body env = apply-proc-clo body env (astep x₂ E) K
2021-12-09 05:28:25 -06:00
step (mkState Tc Γ (x₁ x₂) E K) with astep x₁ E
2021-12-09 06:00:09 -06:00
... | cont k =
2021-12-09 05:28:25 -06:00
let val = astep x₂ E in
2021-12-09 06:00:09 -06:00
let K = kont $ letk Γ (atomic $ ` zero) E k in
apply-kont K val
2021-12-09 05:28:25 -06:00
step {} (mkState Tc Γ (call/cc {A} aexp) E K) with astep aexp E
2021-12-09 04:32:32 -06:00
... | clo {Γc} body env =
2021-12-09 05:28:25 -06:00
let Γ′ = Γc , K[ A ] in
2021-12-09 06:00:09 -06:00
let E = env [ K[ A ] cont K ] in
part $ mkState Γ′ body E halt
2021-12-09 04:32:32 -06:00
step (mkState Tc Γ (abort V⊥) E K) with astep V⊥ E
... | ()
step (mkState Tc Γ (`let {A} C₁ C₂) E K) =
let K = letk Γ C₂ E K in
part $ mkState A Γ C₁ E (kont K)
2021-12-09 02:05:20 -06:00
2021-12-09 05:28:25 -06:00
data EvalResult : Set where
complete : {A} StepResult A EvalResult
exhausted : {A} State A EvalResult
2021-12-09 02:05:20 -06:00
2021-12-09 05:28:25 -06:00
eval : {A} State A EvalResult
eval 0 s = exhausted s
eval (suc n) s with step s
... | part x = eval n x
... | done x = complete $ done x
2021-12-09 06:00:09 -06:00
eval : {A} Exp A A EvalResult
2021-12-09 05:28:25 -06:00
eval n e = eval n (inject e)
2021-12-09 06:02:52 -06:00
exp : Exp ` `
exp =
`let (call/cc (ƛ (`let (` zero suc (suc zero)) (abort (` zero)))))
((ƛ $ atomic $ suc $ ` zero) · ` zero)
2021-12-09 05:28:25 -06:00
2021-12-09 06:02:52 -06:00
expRes+ : eval 7 exp (complete $ done $ (suc (suc (suc zero))))
2021-12-09 06:13:32 -06:00
expRes+ = refl