{-# 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)