Skip to content

Instantly share code, notes, and snippets.

@evincarofautumn
Created May 1, 2022 05:39
Show Gist options
  • Save evincarofautumn/8c96ee4f806a54725647c2c97bc12f8f to your computer and use it in GitHub Desktop.
Save evincarofautumn/8c96ee4f806a54725647c2c97bc12f8f to your computer and use it in GitHub Desktop.
Overcomplicated STLC
{-# Language
BlockArguments,
DataKinds,
DerivingStrategies,
GADTs,
InstanceSigs,
LambdaCase,
PatternSynonyms,
PolyKinds,
RankNTypes,
ScopedTypeVariables,
StandaloneDeriving,
TypeOperators,
UnicodeSyntax
#-}
{-# Options_GHC
-Wall
-Wno-unticked-promoted-constructors
#-}
import Control.Category (Category(..))
import Data.Kind (Type)
import Prelude hiding ((.), id)
main IO ()
main = pure ()
--------------------------------------------------------------------------------
-- ASCII Aliases
--------------------------------------------------------------------------------
type Ctx0 = Γ-- \Gamma_0 \x0393\x2080
type Ctx1 c = Γc -- \Gamma_1 \x0393\x2081
type SubCtx c1 c2 = c1 c2 -- \subseteq \x2286
type T0 = T-- \Tau \x03A4\x2080
type T1 t = T₁(t) -- \Tau_ \x03A4\x2081
type Term c t = c t -- \vdash \x22A2
type Value c t = c t -- \vDash \x22A8
type c `Ni` t = c t -- \ni \x220B
type t `In` c = t c -- \in \x2208
type c2 ~> c1 = c2 c1 -- \leadsto \x219D
type c1 <~ c2 = c1 c2 -- \leadsfrom \x219C
pattern (:<~) (γ τ) (γ γ₁) (γ& τ γ₁)
pattern c1 :<~ c2 = c1 :↜ c2
pattern Del0 '[] γ
pattern Del0 = Δ
pattern Lam0 T E E
pattern Lam0 t e = Λ₀ t e
pattern Lam1 T₁(α) (γ & α β) (γ α :→ β)
pattern Lam1 t e = Λ₁ t e
pattern (:->) T T T
pattern a :-> b = a :→ b
pattern N0 T
pattern N0 = TN
pattern T0 T
pattern T0 = TT
pattern K0 T
pattern K0 = TK
pattern (:=>) T₁(α) T₁(β) T₁(α :→ β)
pattern a :=> b = a :⇒ b
pattern N1 T₁(TN₀)
pattern N1 = TN
pattern T1 T₁(TT₀)
pattern T1 = TT
pattern K1 T₁(TK₀)
pattern K1 = TK
pattern CtxEqZ (γ γ)
pattern CtxEqZ = ΓEqZ
pattern CtxLt (γ γ₂) (γ γ& τ)
pattern CtxLt p = ΓLt p
pattern CtxEqS (γ γ₂) (γ& τ γ& τ)
pattern CtxEqS p = ΓEqS p
wmap (Affine p) (γ γ₂) (p γα) (p γα)
wmap = (↪)
--------------------------------------------------------------------------------
-- Fixities
--------------------------------------------------------------------------------
infix 1 , <~
infix 1 , ~>
infix 1
infix 1
infix 2
infix 2
infix 2
infixr 4 :→, :->
infixr 4 :⇒, :=>
infixr 5 :↜, :<~
infixl 5 &
infixl 5 :&
infixr 6
--------------------------------------------------------------------------------
-- Types
--------------------------------------------------------------------------------
data Twhere -- untyped types
(:→) T T T-- function type
TN {}T-- natural type
TT {}T-- value kind
TK {}T-- type kind
data T₁(τ T₀) where -- and their typed kin
(:⇒) T₁(α) T₁(β) T₁(α :→ β)
TN {}T₁(TN₀)
TT {}T₁(TT₀)
TK {}T₁(TK₀)
type Γ= [T₀] -- untyped typing context
type (γ Γ₀) & (τ T₀) = τ ': γ
data Γ₁(γ Γ₀) where -- typed typing context
Γ {}Γ₁('[]) -- nil
(:&) Γ₁(γ) T₁(τ) Γ₁(γ & τ) -- cons
data (γ Γ₀) (γ Γ₀) where -- context inclusion proof
ΓEqZ -- base case: contexts are equal (reflexivity)
{}
-- ─────────────
→ γ ⊆ γ
ΓLt -- one context is a subcontext of another
γ γ
-- ─────────────
γ γ& τ
ΓEqS -- inductive case: contexts have a common supercontext
γ γ
-- ───────────────
γ& τ γ& τ
type τ γ -- in
= γ τ -- ni
data (γ [κ]) (α κ) where -- context containment proof
-- made of a fancy index
SZ {} -- zero, head of context
-- ─────────
→ α ∈ γ & α
SS α γ -- the variable is in another castle
-- ─────────
→ α ∈ γ & β
data E where -- an untyped term
L A E -- literal
V Int E -- variable
Λ T E E -- abstraction
A E E E -- application
-- typed term, per a context
data (γ Γ₀) (τ T₀) where
L-- typed literal
A₁(τ)
-- ───── [lit]
γ τ
V-- typed variable
τ γ
-- ───── [var]
γ τ
Λ-- typed abstraction
T₁(α)
γ & α β
-- ────────── [abs]
γ α :→ β
A-- typed application
γ α :→ β
γ α
-- ──────────
γ β
data Awhere -- atomic elements
Zero A-- natural zero
Succ A-- natural successor
Nat A-- type of naturals
Star A-- kind of types inhabited by values
Box A-- kind of types inhabited by types
Arr A-- function type constructor
--
data A₁(τ T₀) where -- and their typed kin
Zero A₁(TN₀)
Succ A₁(TN:→ TN₀)
Nat A₁(TT₀)
Star A₁(TT₀)
Box A₁(TK₀)
Arr A₁(TT:→ TT:→ TT₀)
data (γ Γ₀) (τ T₀) where -- valuation of a term in a model
Constant
{ inconstant
A₁(τ) -- from a typed atom
-- ───── -- obtain
} → γ ⊨ τ -- a constant value of that type
Natural
{ unnatural
γ TN-- from a natural term
-- ────── -- obtain
} → γ ⊨ TN-- a natural value
Neutral -- a neutral application
γ α :→ β -- comprises a function
γ α -- and argument
-- ────────── --
γ β -- yet to reduce
Close
{ open
∷ ∀γ₂ -- for any
. Γ₁(γ₂) -- valid context
→ γ₁ ⊆ γ₂ -- in which it finds itself
→ γ₂ ⊨ α -- therein applied to an argument
→ γ₂ ⊨ β -- therein gives its result
-- ─────────── --
} → γ₁ ⊨ α :→ β -- a closure
type γ γ-- thence hither
= γ γ-- hither thence
data (γ Γ₀) (γ Γ₀) where -- an environment
Δ
{}
-- ────────
→ '[] ↝ γ₁ -- empty
(:↜)
∷ γ₁ ⊨ τ -- if there is a thing
→ γ₂ ↝ γ₁ -- and where it is may be here
-- ───────────
→ γ₂ & τ ↝ γ₁ -- then the thing may be here
--------------------------------------------------------------------------------
-- Classes & Instances
--------------------------------------------------------------------------------
class Affine (p Γ κ Type) where -- context-indexed constructors
(↪) -- whose demands can be weakened
γ γ
p γα
-- ───────
p γ₂ α
instance Affine () where
(↪)
γ γ
τ γ
-- ───────
τ γ₂
(↪) = \ case
ΓEqZ id
ΓLt p \ x SS (p x)
ΓEqS p \ case
SZ SZ
SS x SS (p x)
instance Affine () where
(↪)
γ γ
γ α
γ α
(↪) p = \ case
L₁ a L₁ a
V₁ x V₁ (p x)
Λ₁ α e Λ₁ α (ΓEqS p e)
A₁ e₁ e₂ A₁ (p e₁) (p e₂)
instance Show (γ τ) where
showsPrec p = showParen (p > 10) . \ case
Constant a showString "Constant " . showsPrec 10 a
Natural n showString "Natural " . showsPrec 10 n
Neutral f x showsPrec 11 f . showString " " . showsPrec 10 x
Close _f showString "Close (error \"⟨closure⟩\")"
instance Affine () where
(↪)
γ γ
γ τ
-- ───────
γ₂ τ
(↪) p = \ case
Constant a Constant a
Natural n Natural (p n)
Neutral e₁ e₂ Neutral (p e₁) (p e₂)
Close f Close \ γ q f γ (q . p)
instance Category () where
id γ γ
id = ΓEqZ
(.)
γ γ
γ γ
γ γ
ΓEqZ . f = f
g . ΓEqZ = g
ΓLt p . f = ΓLt (p . f)
ΓEqS p . ΓLt q = ΓLt (p . q)
ΓEqS p . ΓEqS q = ΓEqS (p . q)
instance Affine () where
(↪)
γ γ
γ γ
-- ───────
γ₃ γ₂
(↪) p = \ case
Δ Δ
v :↜ e (p v) :↜ (p e)
deriving stock instance Show (A₁(τ))
deriving stock instance Show (T₁(τ))
deriving stock instance Show (γ α)
deriving stock instance Show (γ τ)
deriving stock instance Show (γ γ₂)
deriving stock instance Show A
deriving stock instance Show E
deriving stock instance Show T
--------------------------------------------------------------------------------
-- Evaluation
--------------------------------------------------------------------------------
(!)
γ γ
τ γ
-- ───────
γ₁ τ
(v :↜ _δ) ! SZ = v
(_v :↜ δ) ! SS x = δ ! x
Δ! _ = error "impossible"
reify
Γ₁(γ)
T₁(τ)
γ τ
-- ─────
γ τ
reify γ = \ case
TN unnatural
α :⇒ β \ v Λ₁ α (reify γ' β (open v γ' (ΓLt id) (reflect γ' α (VSZ))))
where
γ' = γ :& α
TT \ (Constant Star) LStar
TK \ (Constant Box) LBox
reflect
Γ₁(γ)
T₁(τ)
γ τ
-- ─────
γ τ
reflect _γ = \ case
TN Natural
α :⇒ β \ e Close \ γ' p reflect γ' β . A₁ (p e) . reify γ' α
TT \ (LStar) Constant Star
TK \ (LBox) Constant Box
eval
γγτ
. Γ₁(γ₁)
γ γ
γ τ
-- ───────
γ₁ τ
eval γ δ = eval'
where
eval'
τ'
. γ τ'
-- ───────
γ₁ τ'
eval' = \ case
L₁ a Constant a
V₁ x δ ! x
Λ₁ _α e Close \ γ' p v let δ' = v :↜ p δ in eval γ' δ' e
A₁ e₁ e₂ let
v₂ = eval' e₂
in case eval' e₁ of
Constant Succ Natural $ A₁ (LSucc) (unnatural v₂)
Close f f γ id v₂
v₁ Neutral v₁ v₂
normalize
γγτ
. Γ₁(γ₁)
T₁(τ)
γ γ
γ τ
γ τ
normalize γ τ δ = reify γ τ . eval γ δ
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment