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.

417 lines
15 KiB

  1. {-# LANGUAGE BlockArguments #-}
  2. {-# LANGUAGE LambdaCase #-}
  3. {-# LANGUAGE OverloadedStrings #-}
  4. {-# LANGUAGE DerivingStrategies #-}
  5. {-# LANGUAGE DeriveAnyClass #-}
  6. {-# LANGUAGE ViewPatterns #-}
  7. module Elab.WiredIn where
  8. import Control.Exception
  9. import qualified Data.Map.Strict as Map
  10. import qualified Data.Sequence as Seq
  11. import qualified Data.Text as T
  12. import Data.Map.Strict (Map)
  13. import Data.Text (Text)
  14. import Data.Typeable
  15. import Elab.Eval
  16. import qualified Presyntax.Presyntax as P
  17. import Syntax
  18. import System.IO.Unsafe
  19. import Syntax.Pretty (prettyTm)
  20. import GHC.Stack (HasCallStack)
  21. wiType :: WiredIn -> NFType
  22. wiType WiType = VType
  23. wiType WiPretype = VTypeω
  24. wiType WiInterval = VTypeω
  25. wiType WiI0 = VI
  26. wiType WiI1 = VI
  27. wiType WiIAnd = VI ~> VI ~> VI
  28. wiType WiIOr = VI ~> VI ~> VI
  29. wiType WiINot = VI ~> VI
  30. wiType WiPathP = dprod (VI ~> VType) \a -> a @@ VI0 ~> a @@ VI1 ~> VType
  31. wiType WiIsOne = VI ~> VTypeω
  32. wiType WiItIsOne = VIsOne VI1
  33. wiType WiIsOne1 = forAll VI \i -> forAll VI \j -> VIsOne i ~> VIsOne (ior i j)
  34. wiType WiIsOne2 = forAll VI \i -> forAll VI \j -> VIsOne j ~> VIsOne (ior i j)
  35. wiType WiPartial = VI ~> VType ~> VTypeω
  36. wiType WiPartialP = dprod VI \x -> VPartial x VType ~> VTypeω
  37. wiType WiSub = dprod VType \a -> dprod VI \phi -> VPartial phi a ~> VTypeω
  38. wiType WiInS = forAll VType \a -> forAll VI \phi -> dprod a \u -> VSub a phi (fun (const u))
  39. wiType WiOutS = forAll VType \a -> forAll VI \phi -> forAll (VPartial phi a) \u -> VSub a phi u ~> a
  40. wiType WiComp = dprod' "A" (VI ~> VType) \a -> forAll VI \phi -> dprod (dprod VI \i -> VPartial phi (a @@ i)) \u -> VSub (a @@ VI0) phi (u @@ VI0) ~> a @@ VI1
  41. -- (A : Type) {phi : I} (T : Partial phi Type) (e : PartialP phi (\o -> Equiv (T o) A)) -> Type
  42. wiType WiGlue = dprod' "A" VType \a -> forAll' "phi" VI \phi -> dprod' "T" (VPartial phi VType) \t -> VPartialP phi (fun \o -> equiv (t @@ o) a) ~> VType
  43. -- {A : Type} {phi : I} {T : Partial phi Type} {e : PartialP phi (\o -> Equiv (T o) A)} -> (t : PartialP phi T) -> Sub A phi (\o -> e o (t o)) -> Glue A phi T e
  44. wiType WiGlueElem = forAll' "A" VType \a -> forAll' "phi" VI \phi -> forAll' "T" (VPartial phi VType) \ty -> forAll' "e" (VPartialP phi (fun \o -> equiv (ty @@ o) a)) \eqv ->
  45. dprod' "t" (VPartialP phi ty) \t -> VSub a phi (fun \o -> vProj1 (eqv @@ o) @@ (t @@ o)) ~> VGlueTy a phi ty eqv
  46. -- {A : Type} {phi : I} {T : Partial phi Type} {e : PartialP phi (\o -> Equiv (T o) A)} -> Glue A phi T e -> A
  47. wiType WiUnglue = forAll' "A" VType \a -> forAll' "phi" VI \phi -> forAll' "T" (VPartial phi VType) \ty -> forAll' "e" (VPartialP phi (fun \o -> equiv (ty @@ o) a)) \e -> VGlueTy a phi ty e ~> a
  48. wiType WiBool = VType
  49. wiType WiTrue = VBool
  50. wiType WiFalse = VBool
  51. wiType WiIf = dprod' "A" (VBool ~> VType) \a -> a @@ VTt ~> a @@ VFf ~> dprod' "b" VBool \b -> a @@ b
  52. wiValue :: WiredIn -> Value
  53. wiValue WiType = VType
  54. wiValue WiPretype = VTypeω
  55. wiValue WiInterval = VI
  56. wiValue WiI0 = VI0
  57. wiValue WiI1 = VI1
  58. wiValue WiIAnd = fun \x -> fun \y -> iand x y
  59. wiValue WiIOr = fun \x -> fun \y -> ior x y
  60. wiValue WiINot = fun inot
  61. wiValue WiPathP = fun \a -> fun \x -> fun \y -> VPath a x y
  62. wiValue WiIsOne = fun VIsOne
  63. wiValue WiItIsOne = VItIsOne
  64. wiValue WiIsOne1 = forallI \_ -> forallI \_ -> fun VIsOne1
  65. wiValue WiIsOne2 = forallI \_ -> forallI \_ -> fun VIsOne2
  66. wiValue WiPartial = fun \phi -> fun \r -> VPartial phi r
  67. wiValue WiPartialP = fun \phi -> fun \r -> VPartialP phi r
  68. wiValue WiSub = fun \a -> fun \phi -> fun \u -> VSub a phi u
  69. wiValue WiInS = forallI \a -> forallI \phi -> fun \u -> VInc a phi u
  70. wiValue WiOutS = forallI \a -> forallI \phi -> forallI \u -> fun \x -> outS a phi u x
  71. wiValue WiComp = fun \a -> forallI \phi -> fun \u -> fun \x -> comp a phi u x
  72. wiValue WiGlue = fun \a -> forallI \phi -> fun \t -> fun \e -> glueType a phi t e
  73. wiValue WiGlueElem = forallI \a -> forallI \phi -> forallI \ty -> forallI \eqv -> fun \x -> fun \y -> glueElem a phi ty eqv x y
  74. wiValue WiUnglue = forallI \a -> forallI \phi -> forallI \ty -> forallI \eqv -> fun \x -> unglue a phi ty eqv x
  75. wiValue WiBool = VBool
  76. wiValue WiTrue = VTt
  77. wiValue WiFalse = VFf
  78. wiValue WiIf = fun \a -> fun \b -> fun \c -> fun \d -> elimBool a b c d
  79. (~>) :: Value -> Value -> Value
  80. a ~> b = VPi P.Ex a (Closure (Bound "_" 0) (const b))
  81. infixr 7 ~>
  82. fun, line :: (Value -> Value) -> Value
  83. fun k = VLam P.Ex $ Closure (Bound "x" 0) (k . force)
  84. line k = VLam P.Ex $ Closure (Bound "i" 0) (k . force)
  85. forallI :: (Value -> Value) -> Value
  86. forallI k = VLam P.Im $ Closure (Bound "x" 0) (k . force)
  87. dprod' :: String -> Value -> (Value -> Value) -> Value
  88. dprod' t a b = VPi P.Ex a (Closure (Bound (T.pack t) 0) b)
  89. dprod :: Value -> (Value -> Value) -> Value
  90. dprod = dprod' "x"
  91. exists' :: String -> Value -> (Value -> Value) -> Value
  92. exists' s a b = VSigma a (Closure (Bound (T.pack s) 0) b)
  93. exists :: Value -> (Value -> Value) -> Value
  94. exists = exists' "x"
  95. forAll' :: String -> Value -> (Value -> Value) -> Value
  96. forAll' n a b = VPi P.Im a (Closure (Bound (T.pack n) 0) b)
  97. forAll :: Value -> (Value -> Value) -> Value
  98. forAll = forAll' "x"
  99. wiredInNames :: Map Text WiredIn
  100. wiredInNames = Map.fromList
  101. [ ("Pretype", WiPretype)
  102. , ("Type", WiType)
  103. , ("Interval", WiInterval)
  104. , ("i0", WiI0)
  105. , ("i1", WiI1)
  106. , ("iand", WiIAnd)
  107. , ("ior", WiIOr)
  108. , ("inot", WiINot)
  109. , ("PathP", WiPathP)
  110. , ("IsOne", WiIsOne)
  111. , ("itIs1", WiItIsOne)
  112. , ("isOneL", WiIsOne1)
  113. , ("isOneR", WiIsOne2)
  114. , ("Partial", WiPartial)
  115. , ("PartialP", WiPartialP)
  116. , ("Sub", WiSub)
  117. , ("inS", WiInS)
  118. , ("outS", WiOutS)
  119. , ("comp", WiComp)
  120. , ("Glue", WiGlue)
  121. , ("glue", WiGlueElem)
  122. , ("unglue", WiUnglue)
  123. , ("Bool", WiBool)
  124. , ("true", WiTrue)
  125. , ("false", WiFalse)
  126. , ("if", WiIf)
  127. ]
  128. newtype NoSuchPrimitive = NoSuchPrimitive { getUnknownPrim :: Text }
  129. deriving (Show, Typeable)
  130. deriving anyclass (Exception)
  131. -- Interval operations
  132. iand, ior :: Value -> Value -> Value
  133. iand = \case
  134. VI1 -> id
  135. VI0 -> const VI0
  136. VIAnd x y -> \case
  137. VI0 -> VI0
  138. VI1 -> VI1
  139. z -> iand x (iand y z)
  140. x -> \case
  141. VI0 -> VI0
  142. VI1 -> x
  143. y -> VIAnd x y
  144. ior = \case
  145. VI0 -> id
  146. VI1 -> const VI1
  147. VIOr x y -> \case
  148. VI1 -> VI1
  149. VI0 -> VIOr x y
  150. z -> ior x (ior y z)
  151. x -> \case
  152. VI1 -> VI1
  153. VI0 -> x
  154. y -> VIOr x y
  155. inot :: Value -> Value
  156. inot = \case
  157. VI0 -> VI1
  158. VI1 -> VI0
  159. VIOr x y -> VIAnd (inot x) (inot y)
  160. VIAnd x y -> VIOr (inot x) (inot y)
  161. VINot x -> x
  162. x -> VINot x
  163. ielim :: Value -> Value -> Value -> Value -> NFEndp -> Value
  164. ielim line left right fn i =
  165. case force fn of
  166. VLine _ _ _ fun -> fun @@ i
  167. x -> case i of
  168. VI1 -> right
  169. VI0 -> left
  170. _ -> case x of
  171. VNe n sp -> VNe n (sp Seq.:|> PIElim line left right i)
  172. VSystem map -> VSystem (fmap (flip (ielim line left right) i) map)
  173. VInc (VPath _ _ _) _ u -> ielim line left right u i
  174. _ -> error $ "can't ielim " ++ show (prettyTm (quote fn))
  175. outS :: NFSort -> NFEndp -> Value -> Value -> Value
  176. outS _ (force -> VI1) u _ = u @@ VItIsOne
  177. outS _ _phi _ (VInc _ _ x) = x
  178. outS _ VI0 _ x = x
  179. outS a phi u (VNe x sp) = VNe x (sp Seq.:|> POuc a phi u)
  180. outS _ _ _ v = error $ "can't outS " ++ show (prettyTm (quote v))
  181. -- Composition
  182. comp :: HasCallStack => NFLine -> NFEndp -> Value -> Value -> Value
  183. comp _ VI1 u _ = u @@ VI1 @@ VItIsOne
  184. comp a psi@phi u (compOutS (a @@ VI1) phi (u @@ VI1 @@ VItIsOne) -> a0) =
  185. case force $ a @@ VVar (Bound (T.pack "i") 0) of
  186. VPi{} ->
  187. let
  188. plic i = let VPi p _ _ = force (a @@ i) in p
  189. dom i = let VPi _ d _ = force (a @@ i) in d
  190. rng i = let VPi _ _ (Closure _ r) = force (a @@ i) in r
  191. y' i y = fill (fun (dom . inot)) VI0 (fun \_ -> fun \_ -> VSystem mempty) (VInc (dom VI0) phi y) i
  192. ybar i y = y' (inot i) y
  193. in VLam (plic VI1) . Closure (Bound "x" 0) $ \arg ->
  194. comp (line \i -> rng i (ybar i arg))
  195. phi
  196. (system \i isone -> vApp (plic i) (u @@ i @@ isone) (ybar i arg))
  197. (VInc (rng VI0 (ybar VI0 arg)) phi (vApp (plic VI0) a0 (ybar VI0 arg)))
  198. VSigma{} ->
  199. let
  200. dom i = let VSigma d _ = force (a @@ i) in d
  201. rng i = let VSigma _ (Closure _ r) = force (a @@ i) in r
  202. w i = fill (fun dom) phi (system \i isone -> vProj1 (u @@ i @@ isone)) (VInc (dom VI0) phi (vProj1 a0)) i
  203. c1 = comp (fun dom) phi (system \i isone -> vProj1 (u @@ i @@ isone)) (VInc (dom VI0) phi (vProj1 a0))
  204. c2 = comp (fun \x -> rng x (w x)) phi (system \i isone -> vProj2 (u @@ i @@ isone)) (VInc (rng VI0 (w VI0)) phi (vProj2 a0))
  205. in
  206. VPair c1 c2
  207. VPath{} ->
  208. let
  209. a' i = let VPath thea _ _ = force (a @@ i) in thea
  210. u' i = let VPath _ theu _ = force (a @@ i) in theu
  211. v' i = let VPath _ _ thev = force (a @@ i) in thev
  212. in
  213. VLine (a' VI1 @@ VI1) (u' VI1) (v' VI1) $ fun \j ->
  214. comp (fun \x -> a' x @@ x)
  215. (phi `ior` j `ior` inot j)
  216. (system \i isone -> mkVSystem (Map.fromList [ (phi, ielim (a' VI0) (u' VI0) (v' VI0) (u @@ i @@ isone) j)
  217. , (j, v' i)
  218. , (inot j, u' i)]))
  219. (VInc (a' VI0 @@ VI0 @@ j) phi (ielim (a' VI0 @@ VI0) (u' VI0) (v' VI0) a0 j))
  220. VGlueTy{} ->
  221. let
  222. b = u
  223. b0 = a0
  224. fam = a
  225. in
  226. let
  227. base i = let VGlueTy base _ _ _ = force (fam @@ i) in base
  228. phi i = let VGlueTy _ phi _ _ = force (fam @@ i) in phi
  229. types i = let VGlueTy _ _ types _ = force (fam @@ i) in types
  230. equivs i = let VGlueTy _ _ _ equivs = force (fam @@ i) in equivs
  231. a i = fun \u -> unglue (base i) (phi i) (types i @@ u) (equivs i @@ u) (b @@ i @@ u)
  232. a0 = unglue (base VI0) (phi VI0) (types VI0) (equivs VI0) b0
  233. del = faceForall phi
  234. a1' = comp (line base) psi (line a) (VInc undefined undefined a0)
  235. t1' = comp (line types) psi (line (b @@)) (VInc undefined undefined b0)
  236. (omega_st, omega_t, omega_rep) = pres types base equivs psi (b @@) b0
  237. omega = outS omega_t psi omega_rep omega_st
  238. (t1alpha_st, t1a_t, t1a_rep) = opEquiv (base VI1) (types VI1 @@ VItIsOne) (equivs VI1 @@ VItIsOne) (del `ior` psi) (fun ts) (fun ps) a1'
  239. t1alpha = outS t1a_t (del `ior` psi) t1a_rep t1alpha_st
  240. (t1, alpha) = (vProj1 t1alpha, vProj2 t1alpha)
  241. ts isone = mkVSystem . Map.fromList $ [(del, t1'), (psi, (b @@ VI1 @@ isone))]
  242. ps _isone = mkVSystem . Map.fromList $ [(del, omega), (psi, VLine (line (const (base VI1))) a1' a1' (fun (const a1')))]
  243. a1 = comp
  244. (fun (const (base VI1 @@ VItIsOne)))
  245. (phi VI1 `ior` psi)
  246. (system \j _u -> mkVSystem (Map.fromList [ (phi VI1, ielim (base VI1) a1' (vProj1 (equivs VI1 @@ VItIsOne)) alpha j)
  247. , (psi, a VI1)]))
  248. a1'
  249. b1 = glueElem (base VI1) (phi VI1) (types VI1) (equivs VI1) (fun (const t1)) a1
  250. in b1
  251. VType -> VGlueTy a0 phi (system \_ _ -> mkVSystem (Map.fromList [(phi, u @@ VI1 @@ VItIsOne)]))
  252. (system \_ _ -> mkVSystem (Map.fromList [(phi, makeEquiv (\j -> (u @@ inot j)))]))
  253. -- fibrancy structure of the booleans is trivial
  254. VBool{} -> a0
  255. _ -> VComp a phi u (VInc (a @@ VI0) phi a0)
  256. compOutS :: NFSort -> NFEndp -> Value -> Value -> Value
  257. compOutS _ _hi _0 vl@VComp{} = vl
  258. compOutS _ _hi _0 (VInc _ _ x) = x
  259. compOutS _ _ _ v = v
  260. system :: (Value -> Value -> Value) -> Value
  261. system k = fun \i -> fun \isone -> k i isone
  262. fill :: NFLine -> NFEndp -> Value -> Value -> NFEndp -> Value
  263. fill a phi u a0 j =
  264. comp (line \i -> a @@ (i `iand` j))
  265. (phi `ior` inot j)
  266. (fun \i -> fun \isone -> mkVSystem (Map.fromList [ (phi, u @@ (i `iand` j) @@ isone)
  267. , (inot j, a0)]))
  268. a0
  269. glueType :: NFSort -> NFEndp -> NFPartial -> NFPartial -> Value
  270. glueType a phi tys eqvs = VGlueTy a phi tys eqvs
  271. glueElem :: NFSort -> NFEndp -> NFPartial -> NFPartial -> NFPartial -> Value -> Value
  272. glueElem _a VI1 _tys _eqvs t _vl = t @@ VItIsOne
  273. glueElem a phi tys eqvs t vl = VGlue a phi tys eqvs t vl
  274. unglue :: NFSort -> NFEndp -> NFPartial -> NFPartial -> Value -> Value
  275. unglue _a VI1 _tys eqvs x = vProj1 (eqvs @@ VItIsOne) @@ x
  276. unglue _a _phi _tys _eqvs (VGlue _ _ _ _ _ vl) = vl
  277. unglue _ _ _ _ (VSystem (Map.toList -> [])) = VSystem (Map.fromList [])
  278. unglue a phi tys eqvs vl = VUnglue a phi tys eqvs vl
  279. -- Definition of equivalences
  280. faceForall :: (NFEndp -> NFEndp) -> Value
  281. faceForall phi = T.length (getNameText name) `seq` go (phi (VVar name)) where
  282. {-# NOINLINE name #-}
  283. name = unsafePerformIO newName
  284. go x@(VVar n)
  285. | n == name = VI0
  286. | otherwise = x
  287. go x@(VINot (VVar n))
  288. | n == name = VI0
  289. | otherwise = x
  290. go (VIAnd x y) = iand (go x) (go y)
  291. go (VIOr x y) = ior (go x) (go y)
  292. go (VINot x) = inot (go x)
  293. go vl = vl
  294. isContr :: Value -> Value
  295. isContr a = exists' "x" a \x -> dprod' "y" a \y -> VPath (line (const a)) x y
  296. fiber :: NFSort -> NFSort -> Value -> Value -> Value
  297. fiber a b f y = exists' "x" a \x -> VPath (line (const b)) (f @@ x) y
  298. isEquiv :: NFSort -> NFSort -> Value -> Value
  299. isEquiv a b f = dprod' "y" b \y -> isContr (fiber a b f y)
  300. equiv :: NFSort -> NFSort -> Value
  301. equiv a b = exists' "f" (a ~> b) \f -> isEquiv a b f
  302. pres :: (NFEndp -> NFSort) -> (NFEndp -> NFSort) -> (NFEndp -> Value) -> NFEndp -> (NFEndp -> Value) -> Value -> (Value, NFSort, Value)
  303. pres tyT tyA f phi t t0 = (VInc pathT phi (VLine (tyA VI1) c1 c2 (line path)), pathT, fun $ \u -> VLine (fun (const (tyA VI1))) c1 c2 (fun (const (f VI1 @@ (t VI1 @@ u))))) where
  304. pathT = VPath (fun (const (tyA VI1))) c1 c2
  305. c1 = comp (line tyA) phi (system \i u -> f i @@ (t i @@ u)) (VInc (tyA VI0) phi (f VI0 @@ t0))
  306. c2 = f VI1 @@ comp (line tyT) phi (system \i u -> t i @@ u) t0
  307. a0 = f VI0 @@ t0
  308. v = fill (fun tyT) phi (system \i u -> t i @@ u) t0
  309. path j = comp (fun tyA) (phi `ior` j) (system \i _ -> f i @@ (v i)) a0
  310. opEquiv :: HasCallStack => Value -> Value -> Value -> NFEndp -> Value -> Value -> Value -> (Value, NFSort, Value)
  311. opEquiv aT tT f phi t p a = (VInc ty phi v, ty, fun \u -> VPair (t @@ u) (p @@ u)) where
  312. fn = vProj1 f
  313. ty = exists' "f" tT \x -> VPath (line (const aT)) a (fn @@ x)
  314. v = contr ty (vProj2 f @@ a) phi (\u -> VPair (t @@ u) (p @@ u))
  315. contr :: HasCallStack => Value -> Value -> NFEndp -> (Value -> Value) -> Value
  316. contr a aC phi u =
  317. comp (line (const a))
  318. phi
  319. (system \i is1 -> ielim (line (const a)) (vProj1 aC) (u is1) (vProj2 aC @@ u is1) i)
  320. (vProj1 aC)
  321. makeEquiv :: (NFEndp -> Value) -> Value
  322. makeEquiv line = comp (fun \i -> equiv a (line i)) VI0 (system \_ _ -> VSystem mempty) (VPair idfun idisequiv) where
  323. a = line VI0
  324. idfun = fun id
  325. -- idEquiv y = ((y, \i -> y), \u i -> (u.2 (inot i), \j -> u.2 (ior (inot i) j)))
  326. u_ty = exists' "y" a \x -> VPath (fun (const a)) x x
  327. idisequiv = fun \y -> VPair (id_fiber y) $ fun \u ->
  328. VLine u_ty (id_fiber y) u $ fun \i -> VPair (ielim (fun (const a)) y y (vProj2 u) i) $
  329. VLine (fun (const a)) y (vProj1 u) $ fun \j ->
  330. ielim (fun (const a)) y y (vProj2 u) (iand i j)
  331. id_fiber y = VPair y (VLine a y y (fun (const y)))
  332. elimBool :: NFSort -> Value -> Value -> Value -> Value
  333. elimBool prop x y bool =
  334. case force bool of
  335. VTt -> x
  336. VFf -> y
  337. _ -> VIf prop x y bool