Prototype, extremely bad code implementation of CCHM Cubical Type Theory
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

325 lines
9.1 KiB

{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE PatternSynonyms #-}
module Syntax where
import qualified Data.Map.Strict as Map
import qualified Data.Set as Set
import Data.Map.Strict (Map)
import Data.Set (Set)
import Presyntax (Formula)
import Systems
import Text.Show (showListWith)
type Space = Term
data Term
= Var String
| App Term Term
| Lam String Term Term
| Let String Term Term Term
| Pi String Term Term
| Type | Typeω
| I
| I0 | I1
| IAnd Term Term
| IOr Term Term
| INot Term
| Path Space Term Term
| PathI Space Term Term String Term
| PathP Space Term Term Term Term
| Sigma String Term Term
| Pair Term Term
| Proj1 Term
| Proj2 Term
| System (System Term)
| Partial Term Term
| PartialP Term Term
| Comp Term Term Term Term
| Sub Term Term Term
| InclSub Term Term Term Term
| GlueTy
Term -- Base type
Term -- Extent
Term -- Partial types
Term -- Partial equivs
| Glue
Term -- Base
Term -- Extent
Term -- Partial types
Term -- Partial equivs
Term -- t
Term -- a
| Unglue
Term -- Base
Term -- Extent
Term -- Partial types
Term -- Partial equivs
Term -- glued value
| Bool
| Tt | Ff
| If Term Term Term Term
deriving (Eq, Ord)
instance Show Term where
showsPrec p =
\case
Var s -> showString s
System fs -> showListWith showPE (Map.toList (getSystem fs))
-- ew
App (App (App (Lam _ _ (Lam _ _ (Lam _ _ Path{}))) a) x) y -> showsPrec p (Path a x y)
App (App (App (Lam _ _ (Lam _ _ (Lam _ _ Sub{}))) a) x) y -> showsPrec p (Sub a x y)
App (App (Lam _ _ (Lam _ _ Partial{})) phi) r -> showsPrec p (Partial phi r)
App (App (Lam _ _ (Lam _ _ PartialP{})) phi) r -> showsPrec p (PartialP phi r)
App (App (App (App (Lam _ _ (Lam _ _ (Lam _ _ (Lam _ _ Comp{})))) a) phi) u) a0 ->
showsPrec p (Comp a phi u a0)
App (App (App (App (Lam _ _ (Lam _ _ (Lam _ _ (Lam _ _ GlueTy{})))) a) phi) u) a0 ->
showsPrec p (GlueTy a phi u a0)
App f x -> showParen (p >= app_prec) $
showsPrec fun_prec f
. showChar ' '
. showsPrec app_prec x
Lam s t b ->
let
getLams (Lam s _ b) =
let (as, b') = getLams b
in (s:as, b')
getLams (PathI _a _x _y s b) =
let (as, b') = getLams b
in (("(" ++ s ++ " : I)"):as, b')
getLams t = ([], t)
(args, bd) = getLams (Lam s t b)
in showParen (p >= fun_prec) $
showString ("λ " ++ unwords args ++ " -> ")
. shows bd
Let s t d b -> showParen (p > fun_prec) $
showString "let\n "
. showString s
. showString " : "
. shows t
. showString " = "
. shows d
. showString " in "
. shows b
Pi "_" d r ->
showParen (p >= domain_prec) $
showsPrec domain_prec d
. showString " -> "
. shows r
Pi v d r -> showParen (p >= domain_prec) $
let
showBinder (Pi "_" d r) =
showsPrec domain_prec d
. showString " -> "
. shows r
showBinder (Pi n d r) =
let
arr = case r of
Pi n _ _ | n /= "_" -> " "
_ -> " -> "
in
showParen True (showString n . showString " : " . shows d)
. showString arr
. showBinder r
showBinder t = shows t
in showBinder (Pi v d r)
Type -> showString "Type"
Typeω -> showString "Typeω"
I -> showChar 'I'
I0 -> showString "i0"
I1 -> showString "i1"
IAnd i j -> showParen (p >= and_prec) $
showsPrec or_prec i
. showString " && "
. showsPrec or_prec j
IOr i j -> showParen (p >= or_prec) $
showsPrec app_prec i
. showString " || "
. showsPrec app_prec j
INot s -> showChar '~' . showsPrec p s
Path a x y -> showApps p (Var "Path") [a, x, y]
Sub a x y -> showApps p (Var "Sub") [a, x, y]
InclSub _a _phi _u0 a0 -> showsPrec p a0
GlueTy a phi t e -> showApps p (Var "Glue") [a, phi, t, e]
Glue base phi ty te t a ->
showApps p (Var "glue") [phi, t, a]
Unglue base phi ty te a ->
showApps p (Var "unglue") [a]
Partial r a -> showApps p (Var "Partial") [r, a]
PartialP r a -> showApps p (Var "PartialP") [r, a]
Comp a phi u a0 -> showApps p (Var "comp") [a, phi, u, a0]
If _ Ff Tt d -> showApps p (Var "not") [d]
If _ b c d -> showApps p (Var "if") [b, c, d]
Bool -> showString "Bool"
Tt -> showString "tt"
Ff -> showString "ff"
PathI a x y s b -> showParen (p >= fun_prec) $
showString ("λ " ++ s ++ " -> ")
. shows b
PathP _a _x _y f i -> showsPrec p (App f i)
Pair a b -> showParen True $
shows a
. showString ", "
. shows b
Proj1 b -> showsPrec p b . showString ".1"
Proj2 b -> showsPrec p b . showString ".1"
Sigma v d r ->
showParen (p >= app_prec) $
showParen True (showString v . showString " : " . shows d)
. showString " × "
. shows r
where
app_prec = 6
domain_prec = 5
and_prec = 4
or_prec = 3
fun_prec = 1
showApps :: Int -> Term -> [Term] -> ShowS
showApps p f xs = showsPrec p (foldl App f xs)
showPE :: (Formula, Term) -> String -> String
showPE (f, t) = shows f . showString " -> " . shows t
data Value
= VNe String [Proj]
| VLam String Value (Value -> Value)
| VPi String Value (Value -> Value)
| VType | VTypeω
| VI | VI0 | VI1
| VEqGlued Value Value -- e which is def. eq. to e'
| VPair Value Value
| VSigma String Value (Value -> Value)
| VLine Value Value Value (Value -> Value)
-- (λ i → ...) : Path A x y
-- order: A x y k
| VSystem (System Value)
| VOfSub Value Value Value Value
| VIAnd Value Value
| VIOr Value Value
| VINot Value
| VPath Value Value Value
| VSub Value Value Value
| VPartial Value Value
| VPartialP Value Value
| VComp Value Value Value Value
| VGlue Value Value Value Value
| VGlueIntro Value Value Value Value Value Value
| VGlueElim Value Value Value Value Value
| VBool
| VTrue
| VFalse
| VIf Value Value Value Value
data Proj
= PApp Value
| PPathP Value Value Value Value
-- a x y i
| PProj1
| PProj2
pattern VVar :: String -> Value
pattern VVar x = VNe x []
quote :: Value -> Term
quote = go mempty where
go :: Set String -> Value -> Term
go scope (VNe hd spine) = foldl (goSpine scope) (Var hd) (reverse spine)
go scope (VLam s a k) =
let n = rename s scope
in Lam n (go scope a) (go (Set.insert n scope) (k (VVar n)))
go scope (VPi s d r) =
let n = rename s scope
in Pi n (go scope d) (go (Set.insert n scope) (r (VVar n)))
go scope (VSigma s d r) =
let n = rename s scope
in Sigma n (go scope d) (go (Set.insert n scope) (r (VVar n)))
go _ VType = Type
go _ VI0 = I0
go _ VI1 = I1
go _ VI = I
go _ VTypeω = Typeω
go scope (VIAnd x y) = IAnd (go scope x) (go scope y)
go scope (VIOr x y) = IOr (go scope x) (go scope y)
go scope (VINot x) = INot (go scope x)
go scope (VPath a x y) = Path (go scope a) (go scope x) (go scope y)
go scope (VSub a x y) = Sub (go scope a) (go scope x) (go scope y)
go scope (VPartial r a) = Partial (go scope r) (go scope a)
go scope (VPartialP r a) = PartialP (go scope r) (go scope a)
go scope (VComp a b c d) = Comp (go scope a) (go scope b) (go scope c) (go scope d)
go scope (VEqGlued e _) = go scope e
go scope (VPair a b) = Pair (go scope a) (go scope b)
go scope (VLine a x y k) =
let n = rename "i" scope
in PathI (go scope a) (go scope x) (go scope y) n (go (Set.insert n scope) (k (VVar n)))
go scope (VSystem (FMap fs)) = System (FMap (fmap (go scope) fs))
go scope (VOfSub _ _ _ x) = go scope x
go scope (VGlue a phi tys eqvs) = GlueTy (go scope a) (go scope phi) (go scope tys) (go scope eqvs)
go scope (VGlueIntro base phi tys eqvs t a) =
Glue (go scope base) (go scope phi) (go scope tys) (go scope eqvs) (go scope t) (go scope a)
go scope (VGlueElim base phi tys eqvs a) =
Unglue (go scope base) (go scope phi) (go scope tys) (go scope eqvs) (go scope a)
go scope VBool = Bool
go scope VTrue = Tt
go scope VFalse = Ff
go scope (VIf a b c d) = If (go scope a) (go scope b) (go scope c) (go scope d)
goSpine :: Set String -> Term -> Proj -> Term
goSpine scope t (PApp x) = App t (go scope x)
goSpine scope t (PPathP a x y i) = PathP (go scope a) (go scope x) (go scope y) t (go scope i)
goSpine scope t PProj1 = Proj1 t
goSpine scope t PProj2 = Proj2 t
rename :: String -> Set String -> String
rename x s
| x == "_" = x
| x `Set.member` s = rename (x ++ "'") s
| otherwise = x
instance Show Value where
showsPrec p = showsPrec p . quote
data Env =
Env { names :: Map String (Value, Value)
}
deriving (Show)