Skip to content

Instantly share code, notes, and snippets.

@nachivpn
Last active June 18, 2021 13:37
Show Gist options
  • Save nachivpn/b211d476c38285f90b44ad7e524c9fc9 to your computer and use it in GitHub Desktop.
Save nachivpn/b211d476c38285f90b44ad7e524c9fc9 to your computer and use it in GitHub Desktop.
Beta-WHNF NbE for STLC
module STLCBetaWHNF where
open import Data.Sum
open import Data.Unit using (⊀ ; tt)
open import Data.Product
--------------------
-- Term syntax, etc.
--------------------
data Ty : Set where
𝕓 : Ty
_β‡’_ : Ty β†’ Ty β†’ Ty
data Ctx : Set where
[] : Ctx
_`,_ : Ctx β†’ Ty β†’ Ctx
variable
Ξ“ Ξ” Ξ“' Ξ”' : Ctx
a b : Ty
data _≀_ : Ctx β†’ Ctx β†’ Set where
base : [] ≀ []
drop : Ξ“ ≀ Ξ” β†’ (Ξ“ `, a) ≀ Ξ”
keep : Ξ“ ≀ Ξ” β†’ (Ξ“ `, a) ≀ (Ξ” `, a)
idWk : Ξ“ ≀ Ξ“
idWk {[]} = base
idWk {Ξ“ `, x} = keep idWk
_βˆ™_ : {Ξ£ : Ctx} β†’ Ξ” ≀ Ξ£ β†’ Ξ“ ≀ Ξ” β†’ Ξ“ ≀ Ξ£
w βˆ™ base = w
w βˆ™ drop w' = drop (w βˆ™ w')
drop w βˆ™ keep w' = drop (w βˆ™ w')
keep w βˆ™ keep w' = keep (w βˆ™ w')
data Var : Ctx β†’ Ty β†’ Set where
ze : Var (Ξ“ `, a) a
su : (v : Var Ξ“ a) β†’ Var (Ξ“ `, b) a
wkVar : Ξ“' ≀ Ξ“ β†’ Var Ξ“ a β†’ Var Ξ“' a
wkVar (drop w) ze = su (wkVar w ze)
wkVar (keep w) ze = ze
wkVar (drop w) (su v) = su (wkVar w (su v))
wkVar (keep w) (su v) = su (wkVar w v)
data Tm : Ctx β†’ Ty β†’ Set where
var : Var Ξ“ a
---------
β†’ Tm Ξ“ a
lam : Tm (Ξ“ `, a) b
-------------
β†’ Tm Ξ“ (a β‡’ b)
app : Tm Ξ“ (a β‡’ b) β†’ Tm Ξ“ a
---------------------
β†’ Tm Ξ“ b
wkTm : Ξ“' ≀ Ξ“ β†’ Tm Ξ“ a β†’ Tm Ξ“' a
wkTm w (var x) = var (wkVar w x)
wkTm w (lam t) = lam (wkTm (keep w) t)
wkTm w (app t u) = app (wkTm w t) (wkTm w u)
data Sub : Ctx β†’ Ctx β†’ Set where
[] : Sub Ξ” []
_`,_ : Sub Ξ” Ξ“ β†’ Tm Ξ” a β†’ Sub Ξ” (Ξ“ `, a)
wkSub : Ξ“' ≀ Ξ“ β†’ Sub Ξ“ Ξ” β†’ Sub Ξ“' Ξ”
wkSub w [] = []
wkSub w (s `, t) = (wkSub w s) `, wkTm w t
substVar : Sub Ξ“ Ξ” β†’ Var Ξ” a β†’ Tm Ξ“ a
substVar (s `, t) ze = t
substVar (s `, t) (su x) = substVar s x
substTm : Sub Ξ” Ξ“ β†’ Tm Ξ“ a β†’ Tm Ξ” a
substTm s (var x) = substVar s x
substTm s (lam t) = lam (substTm (wkSub (drop idWk) s `, var ze) t)
substTm s (app t u) = app (substTm s t) (substTm s u)
---------------
-- Normal forms
---------------
data Ne : Ctx β†’ Ty β†’ Set
data Nf : Ctx β†’ Ty β†’ Set
data Ne where
var : Var Ξ“ a β†’ Ne Ξ“ a
app : Ne Ξ“ (a β‡’ b) β†’ Nf Ξ“ a β†’ Ne Ξ“ b
-- Ξ²-WHNFs (i.e., no Ξ· for _β‡’_ and no congruence for lam)
data Nf where
up : Ne Ξ“ a β†’ Nf Ξ“ a
lam : Tm (Ξ“ `, a) b β†’ Nf Ξ“ (a β‡’ b)
wkNe : Ξ“' ≀ Ξ“ β†’ Ne Ξ“ a β†’ Ne Ξ“' a
wkNf : Ξ“' ≀ Ξ“ β†’ Nf Ξ“ a β†’ Nf Ξ“' a
wkNe w (var x) = var (wkVar w x)
wkNe w (app m n) = app (wkNe w m) (wkNf w n)
wkNf w (up x) = up (wkNe w x)
wkNf w (lam n) = lam (wkTm (keep w) n)
embNe : Ne Ξ“ a β†’ Tm Ξ“ a
embNf : Nf Ξ“ a β†’ Tm Ξ“ a
embNe (var x) = var x
embNe (app m n) = app (embNe m) (embNf n)
embNf (up x) = embNe x
embNf (lam t) = lam t
------------------------------
-- Normalisation by Evaluation
------------------------------
-- interpretation of types (⟦_⟧)
Tm' : Ctx β†’ Ty β†’ Set
Tm' Ξ“ 𝕓 = Nf Ξ“ 𝕓
Tm' Ξ“ (a β‡’ b) = (Tm' Ξ“ a β†’ Tm' Ξ“ b) Γ— Nf Ξ“ (a β‡’ b)
-- note: `Ξ“' ≀ Ξ“ β†’ Tm' Ξ“ a β†’ Tm' Ξ“' a` is not admissible, fails for _β‡’_ type
-- semantics supports reification
reify : Tm' Ξ“ a β†’ Nf Ξ“ a
reify {a = 𝕓} n = n
reify {a = a β‡’ b} x = projβ‚‚ x
-- semantic domain supports reflection
reflect : Ne Ξ“ a β†’ Tm' Ξ“ a
reflect {a = 𝕓} n = up n
reflect {a = a β‡’ b} n = (Ξ» x β†’ reflect (app n (reify x))) , up n
-- retraction of eval
quot : Tm' Ξ“ a β†’ Tm Ξ“ a
quot x = embNf (reify x)
-- interpretation of contexts
Sub' : Ctx β†’ Ctx β†’ Set
Sub' Ξ” [] = ⊀
Sub' Ξ” (Ξ“ `, a) = Sub' Ξ” Ξ“ Γ— Tm' Ξ” a
-- interpretation of variables
substVar' : Var Ξ“ a β†’ ({Ξ” : Ctx} β†’ Sub' Ξ” Ξ“ β†’ Tm' Ξ” a)
substVar' ze (_ , x) = x
substVar' (su x) (Ξ³ , _) = substVar' x Ξ³
-- retraction of evalβ‚›
quotβ‚› : Sub' Ξ” Ξ“ β†’ Sub Ξ” Ξ“
quotβ‚› {Ξ“ = []} tt = []
quotβ‚› {Ξ“ = Ξ“ `, _} (s , x) = (quotβ‚› s) `, quot x
-- interpretation of terms
eval : Tm Ξ“ a β†’ ({Ξ” : Ctx} β†’ Sub' Ξ” Ξ“ β†’ Tm' Ξ” a)
eval (var x) s = substVar' x s
eval (lam t) s = (Ξ» x β†’ eval t (s , x))
, (lam (substTm (wkSub (drop idWk) (quotβ‚› s) `, (var ze)) t))
eval (app t u) s = proj₁ (eval t s) (eval u s)
-- variable substitution
data VSub : Ctx β†’ Ctx β†’ Set where
[] : VSub Ξ“ []
_`,_ : VSub Ξ“ Ξ” β†’ Var Ξ“ a β†’ VSub Ξ“ (Ξ” `, a)
-- weaken variable substitutions
wkVSub : Ξ“' ≀ Ξ“ β†’ VSub Ξ“ Ξ” β†’ VSub Ξ“' Ξ”
wkVSub w [] = []
wkVSub w (ns `, x) = wkVSub w ns `, wkVar w x
-- identity variable substitution
idVSub : VSub Ξ“ Ξ“
idVSub {[]} = []
idVSub {Ξ“ `, x} = wkVSub (drop idWk) idVSub `, ze
-- reflect a variable substitution
reflectVSub : VSub Ξ“ Ξ” β†’ Sub' Ξ“ Ξ”
reflectVSub [] = tt
reflectVSub (ns `, n) = reflectVSub ns , reflect (var n)
-- identity semantic substitution
idβ‚›' : Sub' Ξ“ Ξ“
idβ‚›' = reflectVSub idVSub
-- normalisation function
norm : Tm Ξ“ a β†’ Nf Ξ“ a
norm t = reify (eval t idβ‚›')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment