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.

636 lines
27 KiB

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