less prototype, less bad code implementation of CCHM 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.

208 lines
6.6 KiB

  1. {-# LANGUAGE LambdaCase #-}
  2. {-# OPTIONS_GHC -Wno-orphans #-}
  3. {-# LANGUAGE ViewPatterns #-}
  4. {-# LANGUAGE NamedFieldPuns #-}
  5. module Syntax.Pretty where
  6. import qualified Data.Map.Strict as Map
  7. import qualified Data.Text.Lazy as L
  8. import qualified Data.Text as T
  9. import Data.Map.Strict (Map)
  10. import Data.Text (Text)
  11. import Presyntax.Presyntax (Plicity(..))
  12. import Prettyprinter.Render.Terminal
  13. import Prettyprinter
  14. import Syntax
  15. instance Pretty Name where
  16. pretty = pretty . getNameText
  17. prettyTm :: Term -> Doc AnsiStyle
  18. prettyTm = go True 0 where
  19. go t p =
  20. \case
  21. Ref v -> pretty v
  22. Con v -> keyword $ pretty v
  23. PCon _ v -> keyword $ pretty v
  24. Data _ v -> keyword $ pretty v
  25. App Im f _ -> go t p f
  26. App Ex f x ->
  27. parenIf (p >= arg_prec) $
  28. go False fun_prec f
  29. <+> group (go False arg_prec x)
  30. Lam Ex v (App Ex f (Ref v')) | v == v' -> instead f
  31. Lam i v t ->
  32. let
  33. getArgs (Lam i v t) =
  34. let (as, b) = getArgs t in ((i, v):as, b)
  35. getArgs (PathIntro _ _ _ (Lam _ v t)) =
  36. let (as, b) = getArgs t in ((Ex, v):as, b)
  37. getArgs t = ([], t)
  38. (as, b) = getArgs (Lam i v t)
  39. in
  40. parenIf (p >= fun_prec) . group $
  41. pretty '\\' <> hsep (map (\(i, v) -> braceIf (i == Im) (pretty v)) as)
  42. <+> arrow
  43. <+> nest 2 (go False 0 b)
  44. Pi _ (T.unpack . getNameText -> "_") d r ->
  45. parenIf (p >= fun_prec) $
  46. group (go False dom_prec d)
  47. <> space <> arrow <> sp
  48. <> go t 0 r
  49. Pi i x d r ->
  50. let
  51. c = case r of
  52. Pi _ (getNameText -> x) _ _ | x /= T.pack "_" -> sp
  53. _ -> space <> arrow <> sp
  54. in
  55. parenIf (p >= fun_prec) $
  56. plic i (pretty x <+> colon <+> go False 0 d)
  57. <> c <> go t 0 r
  58. Let binds body ->
  59. parenIf (p >= fun_prec) $
  60. align $ keyword (pretty "let")
  61. <> line
  62. <> indent 2 (prettyBinds binds)
  63. <> keyword (pretty "in")
  64. <+> go False 0 body
  65. Meta MV{mvName} -> keyword (pretty mvName)
  66. Type -> keyword (pretty "Type")
  67. Typeω -> keyword (pretty "Pretype")
  68. Sigma v d r ->
  69. parenIf (p >= fun_prec) . align $
  70. group (parens (pretty v <+> colon <+> go False 0 d))
  71. <+> operator (pretty "*") <+> go False 0 r
  72. Pair a b -> parens $ go False 0 a <> comma <+> go False 0 b
  73. Proj1 a -> parenIf (p >= arg_prec) $ go False 0 a <> keyword (pretty ".1")
  74. Proj2 a -> parenIf (p >= arg_prec) $ go False 0 a <> keyword (pretty ".2")
  75. I -> keyword (pretty "I")
  76. I0 -> keyword (pretty "i0")
  77. I1 -> keyword (pretty "i1")
  78. IAnd x y -> parenIf (p > and_prec) $
  79. go False and_prec x <+> operator (pretty "/\\") <+> go False and_prec y
  80. IOr x y -> parenIf (p > or_prec) $
  81. go False or_prec x <+> operator (pretty "\\/") <+> go False or_prec y
  82. INot x -> operator (pretty "~") <> go False p x
  83. PathP _ x y -> parenIf (p >= arg_prec) $
  84. go False 0 x <+> operator (pretty "") <+> go False 0 y
  85. IElim _a _x _y f i -> instead (App Ex f i)
  86. PathIntro _a _x _y f -> instead f
  87. IsOne p -> brackets (go False 0 p)
  88. ItIsOne -> keyword (pretty "1=1")
  89. Partial a p -> apps (con "Partial") [(Ex, a), (Ex, p)]
  90. PartialP a p -> apps (con "PartialP") [(Ex, a), (Ex, p)]
  91. System fs | Map.null fs -> braces mempty
  92. System fs ->
  93. let
  94. face (f, t) = go False 0 f <+> operator (pretty "=>") <+> align (go False 0 t)
  95. in
  96. braces (line <> indent 2 (vsep (map face (Map.toList fs))) <> line)
  97. Sub a phi u -> apps (con "Sub") [(Ex, a), (Ex, phi), (Ex, u)]
  98. Inc _ _hi u -> apps (con "inS") [(Ex, u)]
  99. Ouc _ _hi _ a0 -> apps (con "outS") [(Ex, a0)]
  100. GlueTy a phi t e -> apps (con "primGlue") [(Ex, a), (Ex, phi), (Ex, t), (Ex, e)]
  101. Glue _a _phi _ty _e t im -> apps (con "glue") [(Ex, t), (Ex, im)]
  102. Unglue _a _phi _ty _e t -> apps (con "unglue") [(Ex, t)]
  103. Comp a phi u a0 -> apps (con "comp") [(Ex, a), (Ex, phi), (Ex, u), (Ex, a0)]
  104. HComp a phi u a0 -> apps (con "hcomp") [(Ex, a), (Ex, phi), (Ex, u), (Ex, a0)]
  105. Case _ t cs ->
  106. let
  107. oneCase (c, 0, l) = go False 0 c <+> operator (pretty "=>") <+> go False 0 l
  108. oneCase (c, i, l) =
  109. let (args, bd) = getLams i l
  110. in go False 0 c <+> hsep (map pretty args) <+> operator (pretty "=>") <+> go False 0 bd
  111. getLams 0 x = ([], x)
  112. getLams n (Lam _ v t) = let (as, b) = getLams (n - 1) t in (v:as, b)
  113. getLams _ x = ([], x)
  114. in
  115. parenIf (p >= fun_prec) $
  116. keyword (pretty "case") <+> go False 0 t <+> keyword (pretty "of")
  117. <> line
  118. <> indent 2 (vsep (map oneCase cs))
  119. EqS _ x y -> parenIf (p >= arg_prec) $
  120. go False 0 x <+> operator (pretty "≡S") <+> go False 0 y
  121. Syntax.Refl _ _ -> keyword (pretty "refl")
  122. Syntax.AxK _ _ bigp pr eq -> apps (con "K_s") [(Ex, bigp), (Ex, pr), (Ex, eq)]
  123. Syntax.AxJ _ _ bigp pr _ eq -> apps (con "J_s") [(Ex, bigp), (Ex, pr), (Ex, eq)]
  124. where
  125. sp | t = softline
  126. | otherwise = space
  127. parenIf p x | p = parens x
  128. | otherwise = x
  129. braceIf p x | p = braces x
  130. | otherwise = x
  131. con x = Con (Bound (T.pack x) 0)
  132. plic = \case
  133. Ex -> parens
  134. Im -> braces
  135. arrow = operator (pretty "->")
  136. instead = go t p
  137. apps :: Term -> [(Plicity, Term)] -> Doc AnsiStyle
  138. apps f xs = instead (foldl (\f (p, x) -> App p f x) f xs)
  139. prettyBinds :: [(Name, Term, Term)] -> Doc AnsiStyle
  140. prettyBinds [] = mempty
  141. prettyBinds ((x, ty, tm):bs) =
  142. pretty x <+> colon <+> align (prettyTm ty)
  143. <> line
  144. <> pretty x <+> equals <+> align (prettyTm tm)
  145. <> line
  146. <> prettyBinds bs
  147. showFace :: Map Head Bool -> Doc AnsiStyle
  148. showFace = hsep . map go . Map.toList where
  149. go (h, b) = parens $ prettyTm (quote (VNe h mempty)) <+> operator (pretty "=") <+> pretty (if b then "i1" else "i0")
  150. prettyVl :: Value -> Doc AnsiStyle
  151. prettyVl = prettyTm . quote
  152. render :: Doc AnsiStyle -> Text
  153. render = L.toStrict . renderLazy . layoutSmart defaultLayoutOptions
  154. arg_prec, fun_prec, dom_prec, and_prec, or_prec :: Int
  155. dom_prec = succ fun_prec
  156. arg_prec = succ and_prec
  157. and_prec = succ or_prec
  158. or_prec = succ fun_prec
  159. fun_prec = 1
  160. keyword :: Doc AnsiStyle -> Doc AnsiStyle
  161. keyword = annotate (color Magenta)
  162. operator :: Doc AnsiStyle -> Doc AnsiStyle
  163. operator = annotate (color Yellow)