cek-call-cc/src/Project/Cesk.agda
2021-12-09 06:13:32 -06:00

66 lines
2.1 KiB
Agda
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

module Project.Cesk where
open import Relation.Binary.PropositionalEquality
open import Data.Nat
open import Data.Product renaming (_,_ to ⦅_,_⦆)
open import Project.Definitions
open import Project.Util using (_$_)
open import Project.Do
open Aexp
open Value
open State
astep : { Γ A} Aexp Γ A Env Γ Value A
astep (value v) _ = v
astep zero _ = zero
astep (suc c) e = suc $ astep c e
astep (` id) e = lookup e id
astep (ƛ body) e = clo body e
inject : {A : Type} Exp A A State A
inject {A} C = mkState A C halt
step : { : Type} State StepResult
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
step (mkState Tc Γ (x₁ x₂) E K) with astep x₁ E
... | cont k =
let val = astep x₂ E in
let K = kont $ letk Γ (atomic $ ` zero) E k in
apply-kont K val
step {} (mkState Tc Γ (call/cc {A} aexp) E K) with astep aexp E
... | clo {Γc} body env =
let Γ′ = Γc , K[ A ] in
let E = env [ K[ A ] cont K ] in
part $ mkState Γ′ body E halt
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)
data EvalResult : Set where
complete : {A} StepResult A EvalResult
exhausted : {A} State A EvalResult
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
eval : {A} Exp A A EvalResult
eval n e = eval n (inject e)
exp : Exp ` `
exp =
`let (call/cc (ƛ (`let (` zero suc (suc zero)) (abort (` zero)))))
((ƛ $ atomic $ suc $ ` zero) · ` zero)
expRes+ : eval 7 exp (complete $ done $ (suc (suc (suc zero))))
expRes+ = refl