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.

546 lines
22 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 GHC.Stack (HasCallStack)
  17. import qualified Presyntax.Presyntax as P
  18. import Syntax.Pretty (prettyTm)
  19. import Syntax
  20. import System.IO.Unsafe
  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 WiPartial = VI ~> VType ~> VTypeω
  34. wiType WiPartialP = dprod VI \x -> VPartial x VType ~> VTypeω
  35. wiType WiSub = dprod VType \a -> dprod VI \phi -> VPartial phi a ~> VTypeω
  36. wiType WiInS = forAll VType \a -> forAll VI \phi -> dprod a \u -> VSub a phi (fun (const u))
  37. wiType WiOutS = forAll VType \a -> forAll VI \phi -> forAll (VPartial phi a) \u -> VSub a phi u ~> a
  38. 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
  39. -- (A : Type) {phi : I} (T : Partial phi Type) (e : PartialP phi (\o -> Equiv (T o) A)) -> Type
  40. 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
  41. -- {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
  42. 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 ->
  43. dprod' "t" (VPartialP phi ty) \t -> VSub a phi (fun \o -> vProj1 (eqv @@ o) @@ (t @@ o)) ~> VGlueTy a phi ty eqv
  44. -- {A : Type} {phi : I} {T : Partial phi Type} {e : PartialP phi (\o -> Equiv (T o) A)} -> Glue A phi T e -> A
  45. 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
  46. wiValue :: WiredIn -> Value
  47. wiValue WiType = VType
  48. wiValue WiPretype = VTypeω
  49. wiValue WiInterval = VI
  50. wiValue WiI0 = VI0
  51. wiValue WiI1 = VI1
  52. wiValue WiIAnd = fun \x -> fun \y -> iand x y
  53. wiValue WiIOr = fun \x -> fun \y -> ior x y
  54. wiValue WiINot = fun inot
  55. wiValue WiPathP = fun \a -> fun \x -> fun \y -> VPath a x y
  56. wiValue WiIsOne = fun VIsOne
  57. wiValue WiItIsOne = VItIsOne
  58. wiValue WiPartial = fun \phi -> fun \r -> VPartial phi r
  59. wiValue WiPartialP = fun \phi -> fun \r -> VPartialP phi r
  60. wiValue WiSub = fun \a -> fun \phi -> fun \u -> VSub a phi u
  61. wiValue WiInS = forallI \a -> forallI \phi -> fun \u -> VInc a phi u
  62. wiValue WiOutS = forallI \a -> forallI \phi -> forallI \u -> fun \x -> outS a phi u x
  63. wiValue WiComp = fun \a -> forallI \phi -> fun \u -> fun \x -> comp a phi u x
  64. wiValue WiGlue = fun \a -> forallI \phi -> fun \t -> fun \e -> glueType a phi t e
  65. wiValue WiGlueElem = forallI \a -> forallI \phi -> forallI \ty -> forallI \eqv -> fun \x -> fun \y -> glueElem a phi ty eqv x y
  66. wiValue WiUnglue = forallI \a -> forallI \phi -> forallI \ty -> forallI \eqv -> fun \x -> unglue a phi ty eqv x
  67. (~>) :: Value -> Value -> Value
  68. a ~> b = VPi P.Ex a (Closure (Bound "_" 0) (const b))
  69. infixr 7 ~>
  70. fun, line :: (Value -> Value) -> Value
  71. fun k = VLam P.Ex $ Closure (Bound "x" 0) (k . force)
  72. line k = VLam P.Ex $ Closure (Bound "i" 0) (k . force)
  73. fun' :: String -> (Value -> Value) -> Value
  74. fun' x k = VLam P.Ex $ Closure (Bound (T.pack x) 0) (k . force)
  75. forallI :: (Value -> Value) -> Value
  76. forallI k = VLam P.Im $ Closure (Bound "x" 0) (k . force)
  77. dprod' :: String -> Value -> (Value -> Value) -> Value
  78. dprod' t a b = VPi P.Ex a (Closure (Bound (T.pack t) 0) b)
  79. dprod :: Value -> (Value -> Value) -> Value
  80. dprod = dprod' "x"
  81. exists' :: String -> Value -> (Value -> Value) -> Value
  82. exists' s a b = VSigma a (Closure (Bound (T.pack s) 0) b)
  83. exists :: Value -> (Value -> Value) -> Value
  84. exists = exists' "x"
  85. forAll' :: String -> Value -> (Value -> Value) -> Value
  86. forAll' n a b = VPi P.Im a (Closure (Bound (T.pack n) 0) b)
  87. forAll :: Value -> (Value -> Value) -> Value
  88. forAll = forAll' "x"
  89. wiredInNames :: Map Text WiredIn
  90. wiredInNames = Map.fromList
  91. [ ("Pretype", WiPretype)
  92. , ("Type", WiType)
  93. , ("Interval", WiInterval)
  94. , ("i0", WiI0)
  95. , ("i1", WiI1)
  96. , ("iand", WiIAnd)
  97. , ("ior", WiIOr)
  98. , ("inot", WiINot)
  99. , ("PathP", WiPathP)
  100. , ("IsOne", WiIsOne)
  101. , ("itIs1", WiItIsOne)
  102. , ("Partial", WiPartial)
  103. , ("PartialP", WiPartialP)
  104. , ("Sub", WiSub)
  105. , ("inS", WiInS)
  106. , ("outS", WiOutS)
  107. , ("comp", WiComp)
  108. , ("Glue", WiGlue)
  109. , ("glue", WiGlueElem)
  110. , ("unglue", WiUnglue)
  111. ]
  112. newtype NoSuchPrimitive = NoSuchPrimitive { getUnknownPrim :: Text }
  113. deriving (Show, Typeable)
  114. deriving anyclass (Exception)
  115. -- Interval operations
  116. iand, ior :: Value -> Value -> Value
  117. iand x = case force x of
  118. VI1 -> id
  119. VI0 -> const VI0
  120. VIAnd x y -> \z -> case force z of
  121. VI0 -> VI0
  122. VI1 -> VI1
  123. z -> iand x (iand y z)
  124. x -> \y -> case force y of
  125. VI0 -> VI0
  126. VI1 -> x
  127. y -> VIAnd x y
  128. ior x = case force x of
  129. VI0 -> id
  130. VI1 -> const VI1
  131. VIOr x y -> \z -> case force z of
  132. VI1 -> VI1
  133. VI0 -> VIOr x y
  134. _ -> ior x (ior y z)
  135. x -> \y -> case force y of
  136. VI1 -> VI1
  137. VI0 -> x
  138. y -> VIOr x y
  139. inot :: Value -> Value
  140. inot x = case force x of
  141. VI0 -> VI1
  142. VI1 -> VI0
  143. VIOr x y -> VIAnd (inot x) (inot y)
  144. VIAnd x y -> VIOr (inot x) (inot y)
  145. VINot x -> x
  146. x -> VINot x
  147. ielim :: Value -> Value -> Value -> Value -> NFEndp -> Value
  148. ielim line left right (GluedVl h sp vl) i =
  149. GluedVl h (sp Seq.:|> PIElim line left right i) (ielim line left right vl i)
  150. ielim line left right fn i =
  151. case force fn of
  152. VLine _ _ _ fun -> fun @@ i
  153. VLam _ (Closure _ k) -> k i
  154. x -> case force i of
  155. VI1 -> right
  156. VI0 -> left
  157. _ -> case x of
  158. VNe n sp -> VNe n (sp Seq.:|> PIElim line left right i)
  159. VSystem map -> VSystem (fmap (flip (ielim line left right) i) map)
  160. VInc (VPath _ _ _) _ u -> ielim line left right u i
  161. VCase env r x xs -> VCase env r x (fmap (fmap (flip (IElim (quote line) (quote left) (quote right)) (quote i))) xs)
  162. _ -> error $ "can't ielim " ++ show (prettyTm (quote fn))
  163. outS :: HasCallStack => NFSort -> NFEndp -> Value -> Value -> Value
  164. outS _ (force -> VI1) u _ = u @@ VItIsOne
  165. outS _ _phi _ (VInc _ _ x) = x
  166. outS _ VI0 _ x = x
  167. outS a phi u (GluedVl x sp vl) = GluedVl x (sp Seq.:|> POuc a phi u) (outS a phi u vl)
  168. outS a phi u (VNe x sp) = VNe x (sp Seq.:|> POuc a phi u)
  169. outS a phi u (VSystem fs) = VSystem (fmap (outS a phi u) fs)
  170. outS _ _ _ v = error $ "can't outS " ++ show (prettyTm (quote v))
  171. -- Composition
  172. comp :: HasCallStack => NFLine -> NFEndp -> Value -> Value -> Value
  173. comp _a VI1 u _a0 = u @@ VI1 @@ VItIsOne
  174. comp a psi@phi u incA0@(compOutS (a @@ VI1) phi (u @@ VI1 @@ VItIsOne) -> a0) =
  175. case force (a @@ VVar name) of
  176. VPi{} ->
  177. let
  178. plic i = let VPi p _ _ = force (a @@ i) in p
  179. dom i = let VPi _ d _ = force (a @@ i) in d
  180. rng i = let VPi _ _ (Closure _ r) = force (a @@ i) in r
  181. y' i y = fill (fun (dom . inot)) VI0 (fun \_ -> fun \_ -> VSystem mempty) (VInc (dom VI0) phi y) i
  182. ybar i y = y' (inot i) y
  183. in VLam (plic VI1) . Closure (Bound "x" 0) $ \arg ->
  184. comp (line \i -> rng i (ybar i arg))
  185. phi
  186. (system \i isone -> vApp (plic i) (u @@ i @@ isone) (ybar i arg))
  187. (VInc (rng VI0 (ybar VI0 arg)) phi (vApp (plic VI0) a0 (ybar VI0 arg)))
  188. VSigma{} ->
  189. let
  190. dom i = let VSigma d _ = force (a @@ i) in d
  191. rng i = let VSigma _ (Closure _ r) = force (a @@ i) in r
  192. w i = fill (fun dom) phi (system \i isone -> vProj1 (u @@ i @@ isone)) (VInc (dom VI0) phi (vProj1 a0)) i
  193. -- c1 = comp (fun dom) phi (system \i isone -> vProj1 (u @@ i @@ isone)) (VInc (dom VI0) phi (vProj1 a0))
  194. c2 = comp (fun \x -> rng x (w x)) phi (system \i isone -> vProj2 (u @@ i @@ isone)) (VInc (rng VI0 (w VI0)) phi (vProj2 a0))
  195. in
  196. VPair (w VI1) c2
  197. VPath{} ->
  198. let
  199. a' i = let VPath thea _ _ = force (a @@ i) in thea
  200. u' i = let VPath _ theu _ = force (a @@ i) in theu
  201. v' i = let VPath _ _ thev = force (a @@ i) in thev
  202. in
  203. VLine (a' VI1 @@ VI1) (u' VI1) (v' VI1) $ fun \j ->
  204. comp (fun \x -> a' x @@ x)
  205. (phi `ior` j `ior` inot j)
  206. (system \i isone -> mkVSystem (Map.fromList [ (phi, ielim (a' VI0) (u' VI0) (v' VI0) (u @@ i @@ isone) j)
  207. , (j, v' i)
  208. , (inot j, u' i)]))
  209. (VInc (a' VI0 @@ VI0 @@ j) phi (ielim (a' VI0 @@ VI0) (u' VI0) (v' VI0) a0 j))
  210. VGlueTy _ thePhi theTypes theEquivs ->
  211. let
  212. b = u
  213. b0 = a0
  214. fam = a
  215. in
  216. let
  217. base i = let VGlueTy b _ _ _ = forceAndGlue (fam @@ i) in b
  218. phi i = substitute (Map.singleton name i) thePhi
  219. types i = substitute (Map.singleton name i) theTypes @@ VItIsOne
  220. equivs i = substitute (Map.singleton name i) theEquivs
  221. a i u = unglue (base i) (phi i) (types i @@ u) (equivs i) (b @@ i @@ u)
  222. a0 = unglue (base VI0) (phi VI0) (types VI0) (equivs VI0) b0
  223. del = faceForall phi
  224. a1' = comp (line base) psi (system a) (VInc (base VI0) psi a0)
  225. t1' = comp (line (const (types VI0))) psi (line (b @@)) (VInc (base VI0) psi b0)
  226. (omega_st, omega_t, omega_rep) = pres types base equivs psi (b @@) b0
  227. omega = outS omega_t psi omega_rep omega_st
  228. (t1alpha_st, t1a_t, t1a_rep) = opEquiv (base VI1) (types VI1) (equivs VI1 @@ VItIsOne) (del `ior` psi) (fun ts) (fun ps) a1'
  229. t1alpha = outS t1a_t (del `ior` psi) t1a_rep t1alpha_st
  230. (t1, alpha) = (vProj1 t1alpha, vProj2 t1alpha)
  231. ts isone = mkVSystem . Map.fromList $ [(del, t1'), (psi, (b @@ VI1 @@ isone))]
  232. ps _isone = mkVSystem . Map.fromList $ [(del, omega), (psi, VLine (line (const (base VI1))) a1' a1' (fun (const a1')))]
  233. a1 = comp
  234. (fun (const (base VI1)))
  235. (phi VI1 `ior` psi)
  236. (system \j _u -> mkVSystem (Map.fromList [ (phi VI1, ielim (base VI1) a1' (vProj1 (equivs VI1 @@ VItIsOne)) alpha j)
  237. , (psi, a VI1 VItIsOne)]))
  238. (VInc (base VI1) (phi VI1 `ior` psi) a1')
  239. b1 = glueElem (base VI1) (phi VI1) (types VI1) (equivs VI1) (fun (const t1)) a1
  240. in b1
  241. VType -> VGlueTy a0 phi (fun' "is1" \is1 -> u @@ VI1 @@ is1)
  242. (fun' "is1" \_ -> mapVSystem (makeEquiv equivVar) (u @@ VVar equivVar @@ VItIsOne))
  243. VNe (HData False _) Seq.Empty -> a0
  244. VNe (HData False _) args ->
  245. case force a0 of
  246. VNe (HCon con_type con_name) con_args ->
  247. VNe (HCon con_type con_name) $ compConArgs makeSetFiller (length args) (a @@) con_type con_args phi u
  248. _ -> VComp a phi u (VInc (a @@ VI0) phi a0)
  249. VNe (HData True name) args -> compHIT name (length args) (a @@) phi u incA0
  250. VLam{} -> error $ "comp VLam " ++ show (prettyTm (quote a))
  251. sys@VSystem{} -> error $ "comp VSystem: " ++ show (prettyTm (quote sys))
  252. _ -> VComp a phi u (VInc (a @@ VI0) phi a0)
  253. where
  254. {-# NOINLINE name #-}
  255. name = unsafePerformIO newName
  256. {-# NOINLINE equivVar #-}
  257. equivVar = unsafePerformIO newName
  258. mapVSystem :: (Value -> Value) -> Value -> Value
  259. mapVSystem f (VSystem fs) = VSystem (fmap f fs)
  260. mapVSystem f x = f x
  261. forceAndGlue :: Value -> Value
  262. forceAndGlue v =
  263. case force v of
  264. v@VGlueTy{} -> v
  265. y -> VGlueTy y VI1 (fun (const y)) (fun (const (idEquiv y)))
  266. compHIT :: HasCallStack => Name -> Int -> (NFEndp -> NFSort) -> NFEndp -> Value -> Value -> Value
  267. compHIT name n a phi u a0 =
  268. case force phi of
  269. VI1 -> u @@ VI1 @@ VItIsOne
  270. VI0 -> transHit name a VI0 (compOutS (a VI0) phi u a0)
  271. x -> go n a x u a0
  272. where
  273. go 0 a phi u a0 = VHComp (a VI0) phi u a0
  274. go _ a phi u a0 = VHComp (a VI1) phi (system \i n -> squeezeHit name a VI0 (\i -> u @@ i @@ n) i) (transHit name a VI0 (compOutS (a VI1) phi (u @@ VI1 @@ VItIsOne) a0))
  275. compConArgs :: (Name -> Int -> Value -> t1 -> t2 -> Value -> Value)
  276. -> Int
  277. -> (Value -> Value)
  278. -> Value
  279. -> Seq.Seq Projection
  280. -> t1 -> t2
  281. -> Seq.Seq Projection
  282. compConArgs makeFiller total_args fam = go total_args where
  283. go _ _ Seq.Empty _ _ = Seq.Empty
  284. go nargs (VPi p dom (Closure _ rng)) (PApp p' y Seq.:<| xs) phi u
  285. | nargs > 0 = assert (p == p') $
  286. PApp p' (nthArg (total_args - nargs) (fam VI1)) Seq.:<| go (nargs - 1) (rng (smuggle (fun (\i -> nthArg (total_args - nargs) (fam i))))) xs phi u
  287. | otherwise = assert (p == p') $
  288. let fill = makeFiller typeArgument nargs dom phi u y
  289. in PApp p' (fill @@ VI1) Seq.:<| go (nargs - 1) (rng fill) xs phi u
  290. go _ _ _ _ _ = error $ "invalid constructor"
  291. smuggle x = VNe (HData False typeArgument) (Seq.singleton (PApp P.Ex x))
  292. typeArgument = unsafePerformIO newName
  293. {-# NOINLINE typeArgument #-}
  294. makeSetFiller :: Name -> Int -> Value -> NFEndp -> Value -> Value -> Value
  295. makeSetFiller typeArgument nth (VNe (HData _ n') args) phi u a0
  296. | n' == typeArgument =
  297. fun $ fill (makeDomain args) phi (system \i is1 -> nthArg nth (u @@ i @@ is1) ) a0
  298. where
  299. makeDomain (PApp _ x Seq.:<| xs) = fun \i -> foldl (\t (~(PApp _ x)) -> t @@ (x @@ i)) (x @@ i) xs
  300. makeDomain _ = error "somebody smuggled something that smells"
  301. makeSetFiller _ _ _ _ _ a0 = fun (const a0)
  302. nthArg :: Int -> Value -> Value
  303. nthArg i (VNe hd s) =
  304. case s Seq.!? i of
  305. Just (PApp _ t) -> t
  306. _ -> error $ "invalid " ++ show i ++ "th argument to data type " ++ show hd
  307. nthArg i (VSystem vs) = VSystem (fmap (nthArg i) vs)
  308. nthArg i xs = error $ "can't get " ++ show i ++ "th argument of " ++ show (prettyTm (quote xs))
  309. compOutS :: HasCallStack => NFSort -> NFEndp -> Value -> Value -> Value
  310. compOutS a b c d = compOutS a b c (force d) where
  311. compOutS _ _hi _0 vl@VComp{} = vl
  312. compOutS _ _hi _0 (VInc _ _ x) = x
  313. compOutS a phi a0 v = outS a phi a0 v
  314. system :: (Value -> Value -> Value) -> Value
  315. system k = VLam P.Ex $ Closure (Bound "i" 0) \i -> VLam P.Ex $ Closure (Bound "phi" 0) \isone -> k i isone
  316. fill :: HasCallStack => NFLine -> NFEndp -> Value -> Value -> NFEndp -> Value
  317. fill a phi u a0 j =
  318. comp (line \i -> a @@ (i `iand` j))
  319. (phi `ior` inot j)
  320. (system \i isone -> mkVSystem (Map.fromList [ (phi, u @@ (i `iand` j) @@ isone)
  321. , (inot j, outS a phi (u @@ VI0) a0)]))
  322. a0
  323. hComp :: NFSort -> NFEndp -> Value -> Value -> Value
  324. hComp _ (force -> VI1) u _ = u @@ VI1 @@ VItIsOne
  325. hComp a phi u a0 = VHComp a phi u a0
  326. glueType :: NFSort -> NFEndp -> NFPartial -> NFPartial -> Value
  327. glueType a phi tys eqvs = VGlueTy a phi tys eqvs
  328. glueElem :: NFSort -> NFEndp -> NFPartial -> NFPartial -> NFPartial -> Value -> Value
  329. glueElem _a (force -> VI1) _tys _eqvs t _vl = t @@ VItIsOne
  330. glueElem a phi tys eqvs t vl = VGlue a phi tys eqvs t vl
  331. unglue :: HasCallStack => NFSort -> NFEndp -> NFPartial -> NFPartial -> Value -> Value
  332. unglue _a (force -> VI1) _tys eqvs x = vProj1 (eqvs @@ VItIsOne) @@ x
  333. unglue _a _phi _tys _eqvs (force -> VGlue _ _ _ _ _ vl) = vl
  334. unglue a phi tys eqvs (force -> VSystem fs) = VSystem (fmap (unglue a phi tys eqvs) fs)
  335. unglue a phi tys eqvs vl = VUnglue a phi tys eqvs vl
  336. -- Definition of equivalences
  337. faceForall :: (NFEndp -> NFEndp) -> Value
  338. faceForall phi = T.length (getNameText name) `seq` go (phi (VVar name)) where
  339. {-# NOINLINE name #-}
  340. name = unsafePerformIO newName
  341. go x@(VVar n)
  342. | n == name = VI0
  343. | otherwise = x
  344. go x@(VINot (VVar n))
  345. | n == name = VI0
  346. | otherwise = x
  347. go (VIAnd x y) = iand (go x) (go y)
  348. go (VIOr x y) = ior (go x) (go y)
  349. go (VINot x) = inot (go x)
  350. go vl = vl
  351. isContr :: Value -> Value
  352. isContr a = exists' "x" a \x -> dprod' "y" a \y -> VPath (line (const a)) x y
  353. fiber :: NFSort -> NFSort -> Value -> Value -> Value
  354. fiber a b f y = exists' "x" a \x -> VPath (line (const b)) (f @@ x) y
  355. isEquiv :: NFSort -> NFSort -> Value -> Value
  356. isEquiv a b f = dprod' "y" b \y -> isContr (fiber a b f y)
  357. equiv :: NFSort -> NFSort -> Value
  358. equiv a b = exists' "f" (a ~> b) \f -> isEquiv a b f
  359. pres :: (NFEndp -> NFSort) -> (NFEndp -> NFSort) -> (NFEndp -> Value) -> NFEndp -> (NFEndp -> Value) -> Value -> (Value, NFSort, Value)
  360. 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
  361. pathT = VPath (fun (const (tyA VI1))) c1 c2
  362. c1 = comp (line tyA) phi (system \i u -> f i @@ (t i @@ u)) (VInc (tyA VI0) phi (f VI0 @@ t0))
  363. c2 = f VI1 @@ comp (line tyT) phi (system \i u -> t i @@ u) t0
  364. a0 = f VI0 @@ t0
  365. v = fill (fun tyT) phi (system \i u -> t i @@ u) t0
  366. path j = comp (fun tyA) (phi `ior` j) (system \i _ -> f i @@ (v i)) a0
  367. opEquiv :: HasCallStack => Value -> Value -> Value -> NFEndp -> Value -> Value -> Value -> (Value, NFSort, Value)
  368. opEquiv aT tT f phi t p a = (VInc ty phi v, ty, fun \u -> VPair (t @@ u) (p @@ u)) where
  369. fn = vProj1 f
  370. ty = exists' "f" tT \x -> VPath (line (const aT)) a (fn @@ x)
  371. v = contr ty (vProj2 f @@ a) phi (\u -> VPair (t @@ u) (p @@ u))
  372. contr :: HasCallStack => Value -> Value -> NFEndp -> (Value -> Value) -> Value
  373. contr a aC phi u =
  374. comp (line (const a))
  375. phi
  376. (system \i is1 -> ielim (line (const a)) (vProj1 aC) (u is1) (vProj2 aC @@ u is1) i)
  377. (VInc a phi (vProj1 aC))
  378. transp :: (NFEndp -> Value) -> Value -> Value
  379. transp line a0 = comp (fun line) VI0 (system \_ _ -> VSystem mempty) (VInc (line VI0) VI0 a0)
  380. gtrans :: (NFEndp -> Value) -> NFEndp -> Value -> Value
  381. gtrans line phi a0 = comp (fun line) phi (system \_ _ -> mkVSystem (Map.singleton phi a0)) (VInc (line VI0) VI0 a0)
  382. transHit :: Name -> (NFEndp -> Value) -> NFEndp -> Value -> Value
  383. transHit name line phi (VHComp _ psi u u0) = VHComp (line VI1) psi (system \i j -> transHit name line phi (u @@ i @@ j)) (transHit name line phi u0)
  384. transHit name line phi (VNe (HCon con_type con_name) spine) | ourType = x' where
  385. x' = VNe (HCon con_type con_name) $ compConArgs (makeTransFiller name) nargs line con_type spine phi ()
  386. (_, VNe hd (length -> nargs)) = unPi con_type
  387. ourType = case hd of
  388. HData True n' -> n' == name
  389. _ -> False
  390. transHit name line phi (VNe (HPCon sys con_type con_name) spine) | ourType = x' where
  391. x' = VNe (HPCon (mapVSystem rec sys) con_type con_name) $ compConArgs (makeTransFiller name) nargs line con_type spine phi ()
  392. rec = transHit name line phi
  393. (_, VNe hd (length -> nargs)) = unPi con_type
  394. ourType = case hd of
  395. HData True n' -> n' == name
  396. _ -> False
  397. transHit name line phi (VSystem xs) = mkVSystem (fmap (transHit name line phi) xs)
  398. transHit _ line phi a0 = gtrans line phi a0
  399. fillHit :: Name -> (NFEndp -> Value) -> NFEndp -> Value -> NFEndp -> Value
  400. fillHit name a phi a0 i = transHit name (\j -> a (iand i j)) (phi `ior` inot i) a0 where
  401. squeezeHit :: Name -> (NFEndp -> Value) -> NFEndp -> (NFEndp -> Value) -> NFEndp -> Value
  402. squeezeHit name a phi x i = transHit name (\j -> a (ior i j)) (phi `ior` i) (x i)
  403. makeTransFiller :: Name -> Name -> p -> Value -> NFEndp -> () -> Value -> Value
  404. makeTransFiller thedata typeArgument _ (VNe (HData _ n') args) phi () a0
  405. | n' == typeArgument = fun (fillHit thedata (makeDomain args) phi a0)
  406. where
  407. makeDomain (PApp _ x Seq.:<| xs) = \i -> foldl (\t (~(PApp _ x)) -> t @@ (x @@ i)) (x @@ i) xs
  408. makeDomain _ = error "somebody smuggled something that smells"
  409. makeTransFiller _ _ _ _ _ _ a0 = fun (const a0)
  410. makeEquiv :: Name -> Value -> Value
  411. makeEquiv var vne = VPair f $ fun \y -> VPair (fib y) (fun \u -> p (vProj1 u) (vProj2 u) y)
  412. where
  413. line = fun \i -> substitute (Map.singleton var (inot i)) vne
  414. a = line @@ VI0
  415. b = line @@ VI1
  416. f = fun \x -> transp (line @@) x
  417. g = fun \x -> transp ((line @@) . inot) x
  418. u i = fun \x -> fill line VI0 (system \_ _ -> mkVSystem mempty) (VInc a VI0 x) i
  419. v i = fun \x -> fill (fun ((line @@) . inot)) VI0 (system \_ _ -> mkVSystem mempty) (VInc a VI1 x) (inot i)
  420. fib y = VPair (g @@ y) (VLine b y (f @@ (g @@ y)) (fun (theta0 y VI1)))
  421. theta0 y i j = fill line (ior j (inot j)) (system \i _ -> mkVSystem (Map.fromList [(j, v i @@ y), (inot j, u i @@ (g @@ y))])) (VInc a (ior j (inot j)) (g @@ y)) i
  422. theta1 x beta y i j =
  423. fill (fun ((line @@) . inot))
  424. (ior j (inot j))
  425. (system \i _ -> mkVSystem (Map.fromList [ (inot j, v (inot i) @@ y)
  426. , (j, u (inot i) @@ x)]))
  427. (VInc b (ior j (inot j)) (ielim b y (f @@ x) beta y))
  428. (inot i)
  429. omega x beta y = theta1 x beta y VI0
  430. delta x beta y j k = comp line (ior k (ior (inot k) (ior j (inot j))))
  431. (system \i _ -> mkVSystem (Map.fromList [ (inot k, theta0 y i j)
  432. , (k, theta1 x beta y i j)
  433. , (inot j, v i @@ y)
  434. , (j, u i @@ omega x beta y k)]))
  435. (VInc a (ior k (ior (inot k) (ior j (inot j)))) (omega x beta y (iand j k)))
  436. p x beta y = VLine (exists a \x -> VPath b y (f @@ x)) (fib y) (VPair x beta) $ fun \k ->
  437. VPair (omega x beta y k) (VLine (VPath b y (f @@ x)) (vProj2 (fib y)) beta $ fun \j -> delta x beta y j k)
  438. idEquiv :: NFSort -> Value
  439. idEquiv a = VPair idfun idisequiv where
  440. idfun = fun id
  441. u_ty = exists' "y" a \x -> VPath (fun (const a)) x x
  442. idisequiv = fun \y -> VPair (id_fiber y) $ fun \u ->
  443. VLine u_ty (id_fiber y) u $ fun \i -> VPair (ielim (fun (const a)) y y (vProj2 u) i) $
  444. VLine (fun (const a)) y (vProj1 u) $ fun \j ->
  445. ielim (fun (const a)) y y (vProj2 u) (iand i j)
  446. id_fiber y = VPair y (VLine a y y (fun (const y)))