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.

210 lines
8.3 KiB

  1. {-# OPTIONS_GHC -Wno-orphans #-}
  2. {-# LANGUAGE ViewPatterns #-}
  3. module Syntax.Pretty where
  4. import Control.Arrow (Arrow(first))
  5. import qualified Data.Map.Strict as Map
  6. import qualified Data.Text.Lazy as L
  7. import qualified Data.Set as Set
  8. import qualified Data.Text as T
  9. import Data.Map.Strict (Map)
  10. import Data.Text (Text)
  11. import Data.Set (Set)
  12. import Data.Generics
  13. import Presyntax.Presyntax (Plicity(..))
  14. import Prettyprinter.Render.Terminal
  15. import Prettyprinter
  16. import Syntax
  17. instance Pretty Name where
  18. pretty = pretty . getNameText
  19. prettyTm :: Term -> Doc AnsiStyle
  20. prettyTm = prettyTm . everywhere (mkT beautify) where
  21. prettyTm (Ref v) =
  22. case T.uncons (getNameText v) of
  23. Just ('.', w) -> keyword (pretty w)
  24. _ -> pretty v
  25. prettyTm (Con v) = keyword (pretty v)
  26. prettyTm (PCon _ v) = keyword (pretty v)
  27. prettyTm (Data _ v) = operator (pretty v)
  28. prettyTm (App Im f _) = prettyTm f
  29. prettyTm (App Ex f x) = parenFun f <+> parenArg x
  30. prettyTm (Pair x y) = parens $ prettyTm x <> operator comma <+> prettyTm y
  31. prettyTm (Proj1 x) = prettyTm x <> operator (pretty ".1")
  32. prettyTm (Proj2 x) = prettyTm x <> operator (pretty ".2")
  33. prettyTm l@(Lam _ _ _) = pretty '\\' <> hsep (map prettyArgList al) <+> pretty "->" <+> nest 2 (prettyTm bod) where
  34. unwindLam (Lam p x y) = first ((p, x):) (unwindLam y)
  35. unwindLam (PathIntro _ _ _ (Lam p x y)) = first ((p, x):) (unwindLam y)
  36. unwindLam t = ([], t)
  37. (al, bod) = unwindLam l
  38. used = freeVars bod
  39. prettyArgList (Ex, v)
  40. | v `Set.member` used = pretty v
  41. | otherwise = pretty "_"
  42. prettyArgList (Im, v)
  43. | v `Set.member` used = braces $ pretty v
  44. | otherwise = pretty "_"
  45. prettyTm (Meta x) = keyword $ pretty '?' <> pretty (mvName x)
  46. prettyTm Type{} = keyword $ pretty "Type"
  47. prettyTm Typeω{} = keyword $ pretty "Typeω"
  48. prettyTm I{} = keyword $ pretty "I"
  49. prettyTm I0{} = keyword $ pretty "i0"
  50. prettyTm I1{} = keyword $ pretty "i1"
  51. prettyTm (Pi Ex (T.unpack . getNameText -> "_") d r) = prettyDom d <+> pretty "->" <+> prettyTm r
  52. prettyTm (Pi Im v d r) = group (braces (pretty v <+> colon <+> prettyTm d)) <> softline <> pretty "->" <+> prettyTm r
  53. prettyTm (Pi Ex v d r) = group (parens (pretty v <+> colon <+> prettyTm d)) <> softline <> pretty "->" <+> prettyTm r
  54. prettyTm (Sigma (T.unpack . getNameText -> "_") d r) = prettyDom d <+> pretty "*" <+> prettyTm r
  55. prettyTm (Sigma v d r) = parens (pretty v <+> colon <+> prettyTm d) <+> pretty "*" <+> prettyTm r
  56. prettyTm (IAnd x y) = parens $ prettyTm x <+> operator (pretty "&&") <+> prettyTm y
  57. prettyTm (IOr x y) = parens $ prettyTm x <+> operator (pretty "||") <+> prettyTm y
  58. prettyTm (INot x) = operator (pretty '~') <> prettyTm x
  59. prettyTm (System (Map.null -> True)) = braces mempty
  60. prettyTm (System xs) = braces (line <> indent 2 (vcat (punctuate comma (map go (Map.toList xs)))) <> line) where
  61. go (f, t) = prettyTm f <+> operator (pretty "=>") <+> prettyTm t
  62. prettyTm (Case _ x xs) = keyword (pretty "case") <+> prettyTm x <+> keyword (pretty "of") <+> braces (line <> indent 2 (prettyCase xs) <> line)
  63. prettyTm (Let xs e) = align $ keyword (pretty "let") <+> braces (line <> indent 2 (prettyLet xs) <> line) <+> keyword (pretty "in") <+> prettyTm e
  64. prettyTm x = error (show x)
  65. prettyCase = vcat . map go where
  66. go (x, xs) = prettyTm x <+> operator (pretty "=>") <+> prettyTm xs
  67. prettyLet = vcat . map go where
  68. go (x, t, y) = pretty x <+> align (colon <+> nest (- 1) (prettyTm t)) <> line <> pretty x <+> pretty "=" <+> prettyTm y
  69. beautify (PathP l x y) = toFun "PathP" [l, x, y]
  70. beautify (IElim _ _ _ f i) = App Ex f i
  71. beautify (PathIntro _ _ _ f) = f
  72. beautify (App _ (Lam _ v b) _)
  73. | v `Set.notMember` freeVars b = beautify b
  74. beautify (IsOne phi) = toFun "IsOne" [phi]
  75. beautify ItIsOne = Ref (Bound (T.pack ".1=1") 0)
  76. beautify (Lam Ex v (App Ex f (Ref v')))
  77. | v == v', v `Set.notMember` freeVars f = f
  78. beautify (Comp a I0 (System (Map.null -> True)) a0) = toFun "transp" [a, a0]
  79. beautify (Lam _ _ (Lam _ _ (System (Map.null -> True)))) = System mempty
  80. beautify (Partial phi a) = toFun "Partial" [phi, a]
  81. beautify (PartialP phi a) = toFun "PartialP" [phi, a]
  82. beautify (Comp a phi u a0) = toFun "comp" [a, phi, u, a0]
  83. beautify (HComp a phi u a0) = toFun "hcomp" [a, phi, u, a0]
  84. beautify (Sub a phi u) = toFun "Sub" [a, phi, u]
  85. beautify (Inc _ _ u) = toFun "inS" [u]
  86. beautify (Ouc a phi u u0) = toFun "outS" [a, phi, u, u0]
  87. beautify (GlueTy a I1 _ _) = a
  88. beautify (GlueTy a b c d) = toFun "Glue" [a,b,c,d]
  89. beautify (Glue a b c d e f) = toFun "glue" [a,b,c,d,e,f]
  90. beautify (Unglue a b c d e) = toFun "unglue" [a,b,c,d,e]
  91. beautify x = x
  92. toFun s a = foldl (App Ex) (Ref (Bound (T.pack ('.':s)) 0)) a
  93. keyword :: Doc AnsiStyle -> Doc AnsiStyle
  94. keyword = annotate (color Magenta)
  95. operator :: Doc AnsiStyle -> Doc AnsiStyle
  96. operator = annotate (color Yellow)
  97. parenArg :: Term -> Doc AnsiStyle
  98. parenArg x@App{} = parens (prettyTm x)
  99. parenArg x@IElim{} = parens (prettyTm x)
  100. parenArg x@IsOne{} = parens $ prettyTm x
  101. parenArg x@Partial{} = parens $ prettyTm x
  102. parenArg x@PartialP{} = parens $ prettyTm x
  103. parenArg x@Sub{} = parens $ prettyTm x
  104. parenArg x@Inc{} = parens $ prettyTm x
  105. parenArg x@Ouc{} = parens $ prettyTm x
  106. parenArg x@Comp{} = parens $ prettyTm x
  107. parenArg x@Case{} = parens $ prettyTm x
  108. parenArg x = prettyDom x
  109. prettyDom :: Term -> Doc AnsiStyle
  110. prettyDom x@Pi{} = parens (prettyTm x)
  111. prettyDom x@Sigma{} = parens (prettyTm x)
  112. prettyDom x = parenFun x
  113. parenFun :: Term -> Doc AnsiStyle
  114. parenFun x@Lam{} = parens $ prettyTm x
  115. parenFun x@PathIntro{} = parens $ prettyTm x
  116. parenFun x = prettyTm x
  117. render :: Doc AnsiStyle -> Text
  118. render = L.toStrict . renderLazy . layoutSmart defaultLayoutOptions
  119. showValue :: Value -> String
  120. showValue = L.unpack . renderLazy . layoutSmart defaultLayoutOptions . prettyTm . quote
  121. showFace :: Map Head Bool -> Doc AnsiStyle
  122. showFace = hsep . map go . Map.toList where
  123. go (h, b) = parens $ prettyTm (quote (VNe h mempty)) <+> operator (pretty "=") <+> pretty (if b then "i1" else "i0")
  124. freeVars :: Term -> Set Name
  125. freeVars (Ref v) = Set.singleton v
  126. freeVars (App _ f x) = Set.union (freeVars f) (freeVars x)
  127. freeVars (Pi _ n x y) = Set.union (freeVars x) (n `Set.delete` freeVars y)
  128. freeVars (Lam _ n x) = n `Set.delete` freeVars x
  129. freeVars (Let ns x) = Set.union (freeVars x `Set.difference` bound) freed where
  130. bound = Set.fromList (map (\(x, _, _) -> x) ns)
  131. freed = foldr (\(_, x, y) -> Set.union (Set.union (freeVars x) (freeVars y))) mempty ns
  132. freeVars Meta{} = mempty
  133. freeVars Con{} = mempty
  134. freeVars PCon{} = mempty
  135. freeVars Data{} = mempty
  136. freeVars Type{} = mempty
  137. freeVars Typeω{} = mempty
  138. freeVars I{} = mempty
  139. freeVars I0{} = mempty
  140. freeVars I1{} = mempty
  141. freeVars (Sigma n x y) = Set.union (freeVars x) (n `Set.delete` freeVars y)
  142. freeVars (Pair x y) = Set.unions $ map freeVars [x, y]
  143. freeVars (Proj1 x) = Set.unions $ map freeVars [x]
  144. freeVars (Proj2 x) = Set.unions $ map freeVars [x]
  145. freeVars (IAnd x y) = Set.unions $ map freeVars [x, y]
  146. freeVars (IOr x y) = Set.unions $ map freeVars [x, y]
  147. freeVars (INot x) = Set.unions $ map freeVars [x]
  148. freeVars (PathP x y z) = Set.unions $ map freeVars [x, y, z]
  149. freeVars (IElim x y z a b) = Set.unions $ map freeVars [x, y, z, a, b]
  150. freeVars (PathIntro x y z a) = Set.unions $ map freeVars [x, y, z, a]
  151. freeVars (IsOne a) = Set.unions $ map freeVars [a]
  152. freeVars ItIsOne{} = mempty
  153. freeVars (Partial x y) = Set.unions $ map freeVars [x, y]
  154. freeVars (PartialP x y) = Set.unions $ map freeVars [x, y]
  155. freeVars (System fs) = foldr (\(x, y) -> Set.union (Set.union (freeVars x) (freeVars y))) mempty (Map.toList fs)
  156. freeVars (Sub x y z) = Set.unions $ map freeVars [x, y, z]
  157. freeVars (Inc x y z) = Set.unions $ map freeVars [x, y, z]
  158. freeVars (Ouc x y z a) = Set.unions $ map freeVars [x, y, z, a]
  159. freeVars (Comp x y z a) = Set.unions $ map freeVars [x, y, z, a]
  160. freeVars (HComp x y z a) = Set.unions $ map freeVars [x, y, z, a]
  161. freeVars (GlueTy x y z a) = Set.unions $ map freeVars [x, y, z, a]
  162. freeVars (Glue x y z a b c) = Set.unions $ map freeVars [x, y, z, a, b, c]
  163. freeVars (Unglue x y z a c) = Set.unions $ map freeVars [x, y, z, a, c]
  164. freeVars (Case rng x y) = freeVars rng <> freeVars x <> foldMap (freeVars . snd) y