-- NBE for Gödel System T module NBE where module Prelude where -- Zero and One ----------------------------------------------------------- data Zero : Set where data One : Set where unit : One -- Natural numbers -------------------------------------------------------- data Nat : Set where zero : Nat suc : Nat -> Nat (+) : Nat -> Nat -> Nat zero + m = m suc n + m = suc (n + m) -- Props ------------------------------------------------------------------ data True : Prop where tt : True data False : Prop where postulate falseE : (A:Set) -> False -> A infix 3 /\ data (/\)(P Q:Prop) : Prop where andI : P -> Q -> P /\ Q module Fin where open Prelude -- Finite sets ------------------------------------------------------------ data Suc (A:Set) : Set where fzero_ : Suc A fsuc_ : A -> Suc A mutual data Fin (n:Nat) : Set where finI : Fin_ n -> Fin n Fin_ : Nat -> Set Fin_ zero = Zero Fin_ (suc n) = Suc (Fin n) fzero : {n:Nat} -> Fin (suc n) fzero = finI fzero_ fsuc : {n:Nat} -> Fin n -> Fin (suc n) fsuc i = finI (fsuc_ i) finE : {n:Nat} -> Fin n -> Fin_ n finE (finI i) = i module Vec where open Prelude open Fin infixr 15 :: -- Vectors ---------------------------------------------------------------- data Nil : Set where nil_ : Nil data Cons (A As:Set) : Set where cons_ : A -> As -> Cons A As mutual data Vec (A:Set)(n:Nat) : Set where vecI : Vec_ A n -> Vec A n Vec_ : Set -> Nat -> Set Vec_ A zero = Nil Vec_ A (suc n) = Cons A (Vec A n) nil : {A:Set} -> Vec A zero nil = vecI nil_ (::) : {A:Set} -> {n:Nat} -> A -> Vec A n -> Vec A (suc n) x :: xs = vecI (cons_ x xs) vecE : {A:Set} -> {n:Nat} -> Vec A n -> Vec_ A n vecE (vecI xs) = xs vec : {A:Set} -> (n:Nat) -> A -> Vec A n vec zero _ = nil vec (suc n) x = x :: vec n x map : {n:Nat} -> {A B:Set} -> (A -> B) -> Vec A n -> Vec B n map {zero} f (vecI nil_) = nil map {suc n} f (vecI (cons_ x xs)) = f x :: map f xs (!) : {n:Nat} -> {A:Set} -> Vec A n -> Fin n -> A (!) {suc n} (vecI (cons_ x _ )) (finI fzero_) = x (!) {suc n} (vecI (cons_ _ xs)) (finI (fsuc_ i)) = xs ! i tabulate : {n:Nat} -> {A:Set} -> (Fin n -> A) -> Vec A n tabulate {zero} f = nil tabulate {suc n} f = f fzero :: tabulate (\x -> f (fsuc x)) module Syntax where open Prelude open Fin -- Types ------------------------------------------------------------------ infixr 8 => data Type : Set where nat : Type (=>) : Type -> Type -> Type -- Terms ------------------------------------------------------------------ data Term (n:Nat) : Set where eZero : Term n eSuc : Term n eApp : Term n -> Term n -> Term n eLam : Term (suc n) -> Term n eVar : Fin n -> Term n module NormalForms where open Prelude open Syntax open Fin mutual -- Normal terms ----------------------------------------------------------- data Normal (n:Nat) : Set where nZero : Normal n nSuc : Normal n -> Normal n nLam : Normal (suc n) -> Normal n nNeutral : Neutral n -> Normal n nStuck : Normal n -- type error -- Neutral terms ---------------------------------------------------------- data Neutral (n:Nat) : Set where uVar : Fin n -> Neutral n uApp : Neutral n -> Normal n -> Neutral n nVar : {n:Nat} -> Fin n -> Normal n nVar i = nNeutral (uVar i) nApp : {n:Nat} -> Neutral n -> Normal n -> Normal n nApp u n = nNeutral (uApp u n) module Rename where open Prelude open Fin open Vec open NormalForms -- Renamings -------------------------------------------------------------- Ren : Nat -> Nat -> Set Ren m n = Vec (Fin n) m id : {n:Nat} -> Ren n n id = tabulate (\i -> i) compose : {l m n:Nat} -> Ren m n -> Ren l m -> Ren l n compose {l}{m}{n} ρ γ = map (\i -> ρ ! i) γ lift : {m n:Nat} -> Ren m n -> Ren (suc m) (suc n) lift ρ = fzero :: map fsuc ρ mutual rename : {m n:Nat} -> Ren m n -> Normal m -> Normal n rename ρ nZero = nZero rename ρ (nSuc n) = nSuc (rename ρ n) rename ρ (nLam n) = nLam (rename (lift ρ) n) rename ρ (nNeutral u) = nNeutral (renameNe ρ u) rename ρ nStuck = nStuck renameNe : {m n:Nat} -> Ren m n -> Neutral m -> Neutral n renameNe ρ (uVar i) = uVar (ρ ! i) renameNe ρ (uApp u n) = uApp (renameNe ρ u) (rename ρ n) up : {n:Nat} -> Ren n (suc n) up = map fsuc id module Subst where open Prelude open Fin open Vec open NormalForms open Rename using (Ren; rename; up) -- Substitutions ---------------------------------------------------------- Sub : Nat -> Nat -> Set Sub m n = Vec (Normal n) m id : {n:Nat} -> Sub n n id = tabulate nVar ren2sub : {m n:Nat} -> Ren m n -> Sub m n ren2sub ρ = map nVar ρ lift : {m n:Nat} -> Sub m n -> Sub (suc m) (suc n) lift σ = nVar fzero :: map (rename up) σ mutual app : {n:Nat} -> Normal n -> Normal n -> Normal n app nZero _ = nStuck app (nSuc _) _ = nStuck app nStuck _ = nStuck app (nLam u) v = subst (v :: id) u app (nNeutral n) v = nApp n v subst : {m n:Nat} -> Sub m n -> Normal m -> Normal n subst σ nZero = nZero subst σ (nSuc v) = nSuc (subst σ v) subst σ (nLam v) = nLam (subst (lift σ) v) subst σ (nNeutral n) = substNe σ n subst σ nStuck = nStuck substNe : {m n:Nat} -> Sub m n -> Neutral m -> Normal n substNe σ (uVar i) = σ ! i substNe σ (uApp n v) = substNe σ n `app` subst σ v compose : {l m n:Nat} -> Sub m n -> Sub l m -> Sub l n compose σ δ = map (subst σ) δ module TypeSystem where open Prelude open Fin open Vec open Syntax mutual EqType : Type -> Type -> Prop EqType nat nat = True EqType (τ => τ') (σ => σ') = τ == σ /\ τ' == σ' EqType _ _ = False infix 5 == data (==) (τ0 τ1:Type) : Prop where eqTypeI : EqType τ0 τ1 -> τ0 == τ1 eqSubst : {σ τ:Type} -> (C:Type -> Set) -> σ == τ -> C τ -> C σ eqSubst {nat}{nat} C _ x = x eqSubst {σ => τ}{σ' => τ'} C (eqTypeI (andI eqσ eqτ)) x = eqSubst (\μ -> C (μ => τ)) eqσ ( eqSubst (\η -> C (σ' => η)) eqτ x ) Context : Nat -> Set Context n = Vec Type n mutual HasType : {n:Nat} -> Context n -> Term n -> Type -> Set HasType Γ eZero τ = ZeroType Γ τ HasType Γ eSuc τ = SucType Γ τ HasType Γ (eVar i) τ = VarType Γ i τ HasType Γ (eApp e1 e2) τ = AppType Γ e1 e2 τ HasType Γ (eLam e) τ = LamType Γ e τ data ZeroType {n:Nat}(Γ:Context n)(τ:Type) : Set where zeroType : τ == nat -> HasType Γ eZero τ data SucType {n:Nat}(Γ:Context n)(τ:Type) : Set where sucType : τ == (nat => nat) -> HasType Γ eSuc τ data VarType {n:Nat}(Γ:Context n)(i:Fin n)(τ:Type) : Set where varType : τ == (Γ ! i) -> HasType Γ (eVar i) τ data AppType {n:Nat}(Γ:Context n)(e1 e2:Term n)(τ:Type) : Set where appType : (σ:Type) -> HasType Γ e1 (σ => τ) -> HasType Γ e2 σ -> HasType Γ (eApp e1 e2) τ data LamType {n:Nat}(Γ:Context n)(e:Term (suc n))(τ:Type) : Set where lamType : (τ0 τ1:Type) -> τ == (τ0 => τ1) -> HasType (τ0 :: Γ) e τ1 -> HasType Γ (eLam e) τ module NBE where open Prelude open Syntax open Fin open Vec open TypeSystem mutual D_ : Nat -> Type -> Set D_ n nat = NatD n D_ n (σ => τ) = FunD n σ τ data D (n:Nat)(τ:Type) : Set where dI : D_ n τ -> D n τ data NatD (n:Nat) : Set where zeroD_ : D_ n nat sucD_ : D n nat -> D_ n nat neD_ : Term n -> D_ n nat -- Will this pass the positivity check? data FunD (n:Nat)(σ τ:Type) : Set where lamD_ : (D n σ -> D n τ) -> D_ n (σ => τ) zeroD : {n:Nat} -> D n nat zeroD = dI zeroD_ sucD : {n:Nat} -> D n nat -> D n nat sucD d = dI (sucD_ d) neD : {n:Nat} -> Term n -> D n nat neD t = dI (neD_ t) lamD : {n:Nat} -> {σ τ:Type} -> (D n σ -> D n τ) -> D n (σ => τ) lamD f = dI (lamD_ f) coerce : {n:Nat} -> {τ0 τ1:Type} -> τ0 == τ1 -> D n τ1 -> D n τ0 coerce {n} = eqSubst (D n) mutual down : {τ:Type} -> {n:Nat} -> D n τ -> Term n down {σ => τ} (dI (lamD_ f)) = eLam (down {τ} ?) -- doesn't work! down {nat} (dI zeroD_) = eZero down {nat} (dI (sucD_ d)) = eSuc `eApp` down d down {nat} (dI (neD_ t)) = t up : {n:Nat} -> (τ:Type) -> Term n -> D n τ up (σ => τ) t = lamD (\d -> up τ (t `eApp` down d)) up nat t = neD t Valuation : {m:Nat} -> Nat -> Context m -> Set Valuation {zero} n _ = Nil Valuation {suc m} n (vecI (cons_ τ Γ)) = Cons (D n τ) (Valuation n Γ) (!!) : {m n:Nat} -> {Γ:Context m} -> Valuation n Γ -> (i:Fin m) -> D n (Γ ! i) (!!) {suc _} {_} {vecI (cons_ _ _)} (cons_ v ξ) (finI fzero_) = v (!!) {suc _} {_} {vecI (cons_ _ _)} (cons_ v ξ) (finI (fsuc_ i)) = ξ !! i ext : {m n:Nat} -> {τ:Type} -> {Γ:Context m} -> Valuation n Γ -> D n τ -> Valuation n (τ :: Γ) ext ξ v = cons_ v ξ app : {σ τ:Type} -> {n:Nat} -> D n (σ => τ) -> D n σ -> D n τ --app (dI (lamD_ f)) d = f d app (lamD f) d = f d eval : {n:Nat} -> {Γ:Context n} -> (e:Term n) -> (τ:Type) -> HasType Γ e τ -> Valuation n Γ -> D n τ eval (eVar i) τ (varType eq) ξ = coerce eq (ξ !! i) eval (eApp r s) τ (appType σ dr ds) ξ = eval r (σ => τ) dr ξ `app` eval s σ ds ξ eval (eLam r) τ (lamType τ0 τ1 eq dr) ξ = coerce eq (lamD (\d -> ?)) -- doesn't work either eval eZero τ (zeroType eq) ξ = coerce eq zeroD eval eSuc τ (sucType eq) ξ = coerce eq (lamD sucD) module Eval where open Prelude open Fin open Vec open Syntax open NormalForms open Rename using (up; rename) open Subst open TypeSystem eval : {n:Nat} -> (Γ:Context n) -> (e:Term n) -> (τ:Type) -> HasType Γ e τ -> Normal n eval Γ eZero τ _ = nZero eval Γ eSuc τ _ = nLam (nSuc (nVar fzero)) eval Γ (eVar i) τ _ = nVar i eval Γ (eApp e1 e2) τ (appType σ d1 d2) = eval Γ e1 (σ => τ) d1 `app` eval Γ e2 σ d2 eval Γ (eLam e) τ (lamType τ0 τ1 _ d) = nLam (eval (τ0 :: Γ) e τ1 d) open Prelude open Fin open Vec open Syntax