Prototype, extremely bad code implementation of CCHM Cubical 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.

651 lines
21 KiB

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
  1. {-# LANGUAGE ViewPatterns #-}
  2. {-# LANGUAGE DeriveAnyClass #-}
  3. {-# LANGUAGE BlockArguments #-}
  4. {-# LANGUAGE LambdaCase #-}
  5. module Eval where
  6. import Control.Exception
  7. import qualified Data.Map.Strict as Map
  8. import Data.Foldable
  9. import Data.Typeable
  10. import Data.IORef
  11. import Data.Maybe
  12. import GHC.Stack
  13. import qualified Presyntax as P
  14. import Presyntax (Formula)
  15. import Syntax
  16. import System.IO.Unsafe (unsafePerformIO)
  17. import Systems
  18. import Debug.Trace (traceShowId)
  19. iand :: Value -> Value -> Value
  20. iand = \case
  21. VI1 -> id
  22. VI0 -> const VI0
  23. x -> \case
  24. VI0 -> VI0
  25. VI1 -> x
  26. y -> VIAnd x y
  27. ior :: Value -> Value -> Value
  28. ior = \case
  29. VI0 -> id
  30. VI1 -> const VI1
  31. x -> \case
  32. VI1 -> VI1
  33. VI0 -> x
  34. y -> VIOr x y
  35. inot :: Value -> Value
  36. inot VI1 = VI0
  37. inot VI0 = VI1
  38. inot (VIOr x y) = iand (inot x) (inot y)
  39. inot (VIAnd x y) = ior (inot x) (inot y)
  40. inot (VINot x) = x
  41. inot x = VINot x
  42. (@@) :: Value -> Value -> Value
  43. VNe hd xs @@ vl = VNe hd (PApp vl:xs)
  44. VLam _ _ k @@ vl = k vl
  45. VEqGlued a b @@ vl = VEqGlued (a @@ vl) (b @@ vl)
  46. VOfSub (VPi _ _ k) phi u0 x @@ vl = VOfSub (k vl) phi (u0 @@ vl) (x @@ vl)
  47. VSystem fs @@ vl = mapVSystem (VSystem fs) (@@ vl)
  48. VIf (VLam s d k) c t b @@ vl = VIf (VLam s d (ap . force . k)) (c @@ vl) (t @@ vl) b where
  49. ap (VPi _ _ r) = r vl
  50. ap _ = error "type error when pushing application into if"
  51. f @@ _ = error $ "\ncan't apply argument to " ++ show f
  52. proj1 :: Value -> Value
  53. proj1 (VPair x _) = x
  54. proj1 (VEqGlued x y) = VEqGlued (proj1 x) (proj1 y)
  55. proj1 (VNe s xs) = VNe s (PProj1:xs)
  56. proj1 (VOfSub (VSigma _ d _) phi u0 x) = VOfSub d phi (proj1 u0) (proj1 x)
  57. proj1 v@VSystem{} = mapVSystem v proj1
  58. proj1 (VIf (VLam s d k) c t b) = VIf (VLam s d (proj1t . k)) (proj1 c) (proj1 t) b where
  59. proj1t (VSigma _ d _) = d
  60. proj1t _ = error "type error when pushing proj1 into if"
  61. proj1 x = error $ "can't proj1 " ++ show x
  62. proj2 :: Value -> Value
  63. proj2 (VPair _ y) = y
  64. proj2 (VEqGlued x y) = VEqGlued (proj2 x) (proj2 y)
  65. proj2 (VNe s xs) = VNe s (PProj2:xs)
  66. proj2 (VOfSub (VSigma _ d r) phi u0 x) =
  67. VOfSub (r (proj1 x)) phi (proj2 u0) (proj2 x)
  68. proj2 v@VSystem{} = mapVSystem v proj2
  69. proj2 (VIf (VLam s d k) c t b) = VIf (VLam s d (proj2t . k)) (proj2 c) (proj2 t) b where
  70. proj2t (VSigma _ d r) = r (VIf (VLam s VBool (const d)) (proj1 c) (proj1 t) b)
  71. proj2t _ = error "type error when pushing proj1 into if"
  72. proj2 x = error $ "can't proj2 " ++ show x
  73. pathp :: Env -> Value -> Value -> Value -> Value -> Value -> Value
  74. pathp env p x y f@(VLine _a _x _y e) i =
  75. case reduceCube env i of
  76. Just P.Bot -> VEqGlued (e i) x
  77. Just P.Top -> VEqGlued (e i) y
  78. _ -> e i
  79. pathp env p x y (VEqGlued e e') i = VEqGlued (pathp env p x y e i) (pathp env p x y e' i)
  80. pathp env p x y (VNe hd sp) i =
  81. case reduceCube env i of
  82. Just P.Bot -> VEqGlued (VNe hd (PPathP p x y i:sp)) x
  83. Just P.Top -> VEqGlued (VNe hd (PPathP p x y i:sp)) y
  84. _ | quote x == quote y -> VEqGlued (VNe hd (PPathP p x y i:sp)) x
  85. _ -> VNe hd (PPathP p x y i:sp)
  86. pathp env p x y (VOfSub _ _ _ v) i = pathp env p x y v i
  87. pathp env p x y v@VSystem{} i = mapVSystem v (\f -> pathp env p x y f i)
  88. pathp env p x y f i = error $ "Invalid pathP " ++ show f ++ " @@ " ++ show i
  89. comp :: Env -> Value -> Formula -> Value -> Value -> Value
  90. comp env a@(VLam ivar VI fam) phi u a0 = glue $ go (fam (VVar "woopsie")) phi u a0 where
  91. stuck :: Value
  92. stuck = VComp a (toValue phi) u a0
  93. glue :: Value -> Value
  94. glue = VOfSub (fam VI1) (toValue phi) (u @@ VI1)
  95. go :: HasCallStack => Value -> Formula -> Value -> Value -> Value
  96. go VPi{} phi u a0 =
  97. let
  98. dom x = let VPi _ d _ = fam x in d
  99. rng x = let VPi _ _ r = fam x in r
  100. ai1 = dom VI0
  101. y' i y = fill env i (dom . inot) P.Bot (VSystem emptySystem) y
  102. ybar i y = y' (inot i) y
  103. in VLam "x" ai1 \arg ->
  104. comp env
  105. (VLam ivar VI (\i -> rng i (ybar i arg)))
  106. phi
  107. (VLam "i" VI \i -> mapVSystem (u @@ i) (@@ ybar i arg))
  108. (a0 @@ ybar VI0 arg)
  109. go VSigma{} phi u a0 =
  110. let
  111. dom x = let VSigma _ d _ = fam x in d
  112. rng x = let VSigma _ d _ = fam x in d
  113. a i = fill env i (dom . fam) phi (VLam "j" VI \v -> mapVSystem (u @@ v) proj1) (proj1 a0)
  114. c1 = comp env (VLam ivar VI (getd . fam)) phi (VLam "i" VI \v -> mapVSystem (u @@ v) proj1) (proj1 a0)
  115. c2 = comp env (VLam ivar VI (apr (a VI1) . fam)) phi (VLam "i" VI \v -> mapVSystem (u @@ v) proj2) (proj2 a0)
  116. getd (VSigma _ d _) = d
  117. apr x (VSigma _ _ r) = r x
  118. in VPair c1 c2
  119. go VPath{} phi p p0 =
  120. let
  121. ~(VPath ai1 u1 v1) = fam VI1
  122. ~(VPath ai0 u0 v0) = fam VI0
  123. getA (VPath a _ _) = a
  124. u' x = let ~(VPath _ u _) = fam x in u
  125. v' x = let ~(VPath _ _ v) = fam x in v
  126. in
  127. VLine (ai1 @@ VI1) u1 v1 \j ->
  128. let
  129. jc = reduceCube' env j
  130. in comp env (VLam ivar VI (getA . fam))
  131. (orFormula [phi, jc, notFormula jc])
  132. (VLam "j" VI \v ->
  133. let
  134. VSystem (FMap sys) = p @@ v
  135. sys' = fmap (flip (pathp env ai0 u0 v0) j) sys
  136. in mkVSystem $ Map.fromList [ (phi, mapVSystem (p @@ v) (flip (pathp env ai0 u0 v0) j))
  137. , (notFormula jc, u' v)
  138. , (jc, v' v)
  139. ])
  140. (pathp env (ai0 @@ VI0) u0 v0 p0 j)
  141. go VGlue{} psi b b0 =
  142. let
  143. base i = let VGlue base _ _ _ = force $ fam i in base
  144. phi i =
  145. case force (fam i) of
  146. VGlue _ phi _ _ -> fromJust (reduceCube env phi)
  147. x -> error (show x)
  148. types i = let VGlue _ _ types _ = force $ fam i in types
  149. equivs i = let VGlue _ _ _ equivs = force $ fam i in equivs
  150. a i = mapVSystem (b @@ i) (unglue (base i) (phi i) (types i) (equivs i))
  151. a0 = unglue (base VI0) (phi VI0) (types VI0) (equivs VI0) b0
  152. del = faceForall phi
  153. a1' = comp env (VLam "i" VI base) psi (VLam "i" VI a) a0
  154. t1' = comp env (VLam "i" VI types) psi (VLam "i" VI (b @@)) b0
  155. omega = pres env types base (flip mapVSystem proj1 . equivs) psi b b0
  156. t1alpha = opEquiv env (base VI1) (types VI1) (equivs VI1) (orFormula [del, psi]) ts ps a1'
  157. (t1, alpha) = (proj1 t1alpha, proj2 t1alpha)
  158. ts = VSystem (FMap (Map.fromList [(del, t1'), (psi, b @@ VI1)]))
  159. ps = VSystem (FMap (Map.fromList [(del, omega), (psi, VLine (VLam "j" VI \_ -> base VI1) a1' a1' (\j -> a1'))]))
  160. a1 = comp env (VLam "j" VI (const (base VI1))) (orFormula [phi VI1, psi]) (VLam "j" VI \j -> a1_sys j) a1'
  161. a1_sys j = VSystem (FMap (Map.fromList [(phi VI1, pathp env (base VI1) a1' (mapVSystem (equivs VI1) proj1) alpha j), (psi, a VI1)]))
  162. b1 = introGlue (base VI1) (phi VI1) (types VI1) (equivs VI1) t1 a1
  163. in b1
  164. go VBool{} _ _ a0 = a0
  165. go a P.Top u a0 = u @@ VI1
  166. go a phi u a0 = stuck
  167. comp env va phi u a0 =
  168. if phi == P.Top
  169. then VEqGlued (VComp va phi' u a0) (u @@ VI1)
  170. else VComp va phi' u a0
  171. where
  172. phi' = toValue phi
  173. opEquiv :: Env -> Value -> Value -> Value -> Formula -> Value -> Value -> Value -> Value
  174. opEquiv env aT tT f phi t p a = VOfSub ty (toValue phi) (VPair t p) v where
  175. fun = proj1 f
  176. ty = VSigma "x" tT \x -> VPath (VLam "i" VI (const aT)) a (fun @@ x)
  177. sys = Map.singleton phi (VPair t p)
  178. v = contr env ty (proj2 f @@ a) phi (VSystem (FMap sys))
  179. force :: Value -> Value
  180. force (VEqGlued x _) = force x
  181. force (VOfSub _ _ _ x) = force x
  182. force x = x
  183. faceForall :: (Value -> Formula) -> Formula
  184. faceForall k = go (k (VVar "$elim")) where
  185. go (P.Is0 "$elim") = P.Bot
  186. go (P.Is1 "$elim") = P.Bot
  187. go (P.Or a b) = orFormula [go a, go b]
  188. go (P.And a b) = andFormula [go a, go b]
  189. go x = x
  190. pres :: Env -> (Value -> Value) -> (Value -> Value) -> (Value -> Value) -> Formula -> Value -> Value -> Value
  191. pres env tT tA f phi t t0 = VOfSub (VPath (tA VI1) c1 c2) (toValue phi) base (VLine (tA VI1) c1 c2 cont) where
  192. c1 = comp env (VLam "i" VI tA) phi (VLam "i" VI \j -> mapVSystem t (f j @@)) (f VI0 @@ t0)
  193. c2 = f VI1 @@ comp env (VLam "i" VI tA) phi t t0
  194. base = VLine (tA VI1) (f VI1 @@ (t @@ VI1)) (f VI1 @@ (t @@ VI1)) (\i -> f VI1 @@ (t @@ VI1))
  195. cont j =
  196. let v i = fill env i tT phi t t0
  197. form = orFormula [phi, fromJust (reduceCube env j)]
  198. a0 = f VI0 @@ t0
  199. in comp env (VLam "I" VI tA) form
  200. (VLam "I" VI (\j -> VSystem (FMap (Map.fromList [(form, f j @@ v j)]))))
  201. a0
  202. contr :: Env -> Value -> Value -> Formula -> Value -> Value
  203. contr env a aC phi u =
  204. comp env (VLam "i" VI (const a)) phi
  205. (VLam "i" VI (pathp env a u (proj1 aC) (proj2 aC @@ u)))
  206. (proj1 aC)
  207. -- t : Partial phi T
  208. -- T : Type
  209. -- a : A
  210. -- f : Equiv T A
  211. mkVSystem :: Map.Map Formula Value -> Value
  212. mkVSystem mp
  213. | Just e <- Map.lookup P.Top mp = e
  214. | otherwise = VSystem $ FMap $ Map.filterWithKey f mp
  215. where
  216. f P.Bot _ = False
  217. f _ _ = True
  218. reduceCube' :: Env -> Value -> Formula
  219. reduceCube' env = fromJust . reduceCube env
  220. mapVSystem :: Value -> (Value -> Value) -> Value
  221. mapVSystem (VSystem ss) f = VSystem (mapSystem ss f)
  222. mapVSystem x f = f x
  223. evalSystem :: Env -> Map.Map Formula Term -> Value
  224. evalSystem env face = mk . Map.fromList . mapMaybe (uncurry go) . Map.toList $ face where
  225. go :: Formula -> Term -> Maybe (Formula, Value)
  226. go face tm
  227. | VI0 <- toValue' env face = Nothing
  228. | otherwise = Just (evalF env face, eval env tm)
  229. evalF env tm =
  230. case toFormula (toValue' env tm) of
  231. Just f -> f
  232. Nothing -> error $ "eval turned formula into non formula"
  233. mk x = case Map.toList x of
  234. [(_, x)] -> x
  235. _ -> mkVSystem x
  236. glue :: Value -> Formula -> Value -> Value -> Value
  237. -- glue baseT P.Top types _equivs = types
  238. glue baseT phi types equivs = VGlue baseT (toValue phi) types equivs
  239. introGlue :: Value -> Formula -> Value -> Value -> Value -> Value -> Value
  240. introGlue baseT P.Top types equivs t a = t
  241. introGlue baseT phi types equivs t a = VGlueIntro baseT (toValue phi) types equivs t a
  242. unglue :: Value -> Formula -> Value -> Value -> Value -> Value
  243. unglue baseT P.Top types equivs b = mapVSystem equivs ((@@ b) . proj1)
  244. unglue baseT phi types equivs val =
  245. VOfSub baseT (toValue phi) (mapVSystem equivs ((@@ val) . proj1)) (VGlueElim baseT (toValue phi) types equivs val)
  246. eval :: Env -> Term -> Value
  247. eval env = \case
  248. Var v ->
  249. case Map.lookup v (names env) of
  250. Just (_, vl) -> vl
  251. Nothing -> error $ "variable not in scope: " ++ show v
  252. App f x -> eval env f @@ eval env x
  253. Lam s d b ->
  254. let d' = eval env d
  255. in VLam s d' \a -> eval env{ names = Map.insert s (d', a) (names env) } b
  256. Let s t b d ->
  257. let b' = eval env b
  258. t' = eval env t
  259. in eval env{ names = Map.insert s (t', b') (names env) } d
  260. Pi s d r ->
  261. let d' = eval env d
  262. in VPi s d' \a -> eval env{ names = Map.insert s (d', a) (names env) } r
  263. Sigma s d r ->
  264. let d' = eval env d
  265. in VSigma s d' \a -> eval env{ names = Map.insert s (d', a) (names env) } r
  266. Pair a b -> VPair (eval env a) (eval env b)
  267. Proj1 x -> proj1 (eval env x)
  268. Proj2 y -> proj2 (eval env y)
  269. Type -> VType
  270. Typeω -> VTypeω
  271. I -> VI
  272. I0 -> VI0
  273. I1 -> VI1
  274. Path p x y -> VPath (eval env p) (eval env x) (eval env y)
  275. Partial r a -> VPartial (eval env r) (eval env a)
  276. PartialP r a -> VPartialP (eval env r) (eval env a)
  277. PathI p x y s e -> VLine (eval env p) (eval env x) (eval env y) (\ a -> eval env{ names = Map.insert s (VI, a) (names env) } e)
  278. PathP p x y f i -> pathp env (eval env p) (eval env x) (eval env y) (eval env f) (eval env i)
  279. Sub p x y -> VSub (eval env p) (eval env x) (eval env y)
  280. InclSub a phi u a0 -> VOfSub (eval env a) (eval env phi) (eval env u) (eval env a0)
  281. IAnd x y -> iand (eval env x) (eval env y)
  282. IOr x y -> ior (eval env x) (eval env y)
  283. INot x -> inot (eval env x)
  284. Comp a phi u a0 ->
  285. case reduceCube env (eval env phi) of
  286. Just formula -> comp env (eval env a) formula (eval env u) (eval env a0)
  287. Nothing -> VComp (eval env a) (eval env phi) (eval env u) (eval env a0)
  288. System fs -> evalSystem env (getSystem fs)
  289. GlueTy a phi types equivs ->
  290. let phi' = eval env phi in
  291. case reduceCube env phi' of
  292. Just formula -> glue (eval env a) formula (eval env types) (eval env equivs)
  293. Nothing -> VGlue (eval env a) phi' (eval env types) (eval env equivs)
  294. Glue a phi types equivs t a0 ->
  295. let phi' = eval env phi
  296. t' = eval env t
  297. a0' = eval env a0
  298. types' = eval env types
  299. equivs' = eval env equivs
  300. a' = eval env a
  301. in
  302. case reduceCube env phi' of
  303. Just formula -> introGlue a' formula types' equivs' t' a0'
  304. Nothing -> VGlueIntro a' phi' types' equivs' t' a0'
  305. Unglue a phi types equivs val ->
  306. let phi' = eval env phi
  307. val' = eval env val
  308. types' = eval env types
  309. equivs' = eval env equivs
  310. a' = eval env a
  311. in
  312. case reduceCube env phi' of
  313. Just formula -> unglue a' formula types' equivs' val'
  314. Nothing -> VGlueElim a' phi' types' equivs' val'
  315. If p x y t -> elimBool (eval env p) (eval env x) (eval env y) (eval env t)
  316. Tt -> VTrue
  317. Ff -> VFalse
  318. Bool -> VBool
  319. elimBool :: Value -> Value -> Value -> Value -> Value
  320. elimBool _ x _ (VEqGlued _ VTrue) = x
  321. elimBool _ x _ (VOfSub _ _ _ VTrue) = x
  322. elimBool _ x _ VTrue = x
  323. elimBool _ _ y (VEqGlued _ VFalse) = y
  324. elimBool _ _ y (VOfSub _ _ _ VFalse) = y
  325. elimBool _ _ y VFalse = y
  326. elimBool p x y t = VIf p x y t
  327. data UnifyError
  328. = Mismatch Value Value
  329. | NotPiType Value
  330. | NotPartialType Formula Value
  331. | NotSigmaType Value
  332. | NotSort Value
  333. deriving (Show, Typeable, Exception)
  334. unify :: HasCallStack => Env -> Value -> Value -> IO ()
  335. unify env (VEqGlued a b) c =
  336. unify env a c `catch` \e -> const (unify env b c) (e :: UnifyError)
  337. unify env c (VEqGlued a b) =
  338. unify env c a `catch` \e -> const (unify env c b) (e :: UnifyError)
  339. unify env (VLine a x y f) e =
  340. let env' = env { names = Map.insert "i" (VI, VVar "i") (names env) }
  341. in unify env' (f (VVar "i")) (pathp env' a x y e (VVar "i"))
  342. unify env e (VLine a x y f) =
  343. let env' = env { names = Map.insert "i" (VI, VVar "i") (names env) }
  344. in unify env' (f (VVar "i")) (pathp env' a x y e (VVar "i"))
  345. unify env (VPartial r b) (VPartial r' b') = do
  346. unify env b b'
  347. case sameCube env r r' of
  348. Just True -> pure ()
  349. _ -> unify env r r'
  350. unify env (VPartial r b) x = do
  351. case sameCube env r VI1 of
  352. Just True -> pure ()
  353. _ -> unify env r VI1
  354. unify env b x
  355. unify env x (VPartial r b) = do
  356. case sameCube env r VI1 of
  357. Just True -> pure ()
  358. _ -> unify env r VI1
  359. unify env x b
  360. unify env (VSub a phi _u0) vl = unify env a vl
  361. unify env u1 (VOfSub _a phi u0 a) = do
  362. case sameCube env phi VI1 of
  363. Just True -> unify env u1 u0
  364. _ -> unify env u1 a
  365. unify env (VOfSub _a phi u0 a) u1 = do
  366. case sameCube env phi VI1 of
  367. Just True -> unify env u1 u0
  368. _ -> unify env u1 a
  369. unify env vl1@(VNe x sp) vl2@(VNe y sp')
  370. | x == y = traverse_ (uncurry unifySp) (zip sp sp')
  371. | otherwise = throwIO $ Mismatch vl1 vl2
  372. where
  373. unifySp (PApp x) (PApp y) = unify env x y
  374. unifySp (PPathP _a _x _y i) (PPathP _a' _x' _y' i') = unify env i i'
  375. unifySp PProj1 PProj1 = pure ()
  376. unifySp PProj2 PProj2 = pure ()
  377. unifySp _ _ = throwIO $ Mismatch vl1 vl2
  378. unify env (VLam x _ k) e = unify env (k (VVar x)) (e @@ VVar x)
  379. unify env e (VLam x _ k) = unify env (e @@ VVar x) (k (VVar x))
  380. unify env (VPi x d r) (VPi _ d' r') = do
  381. unify env d d'
  382. unify env (r (VVar x)) (r' (VVar x))
  383. unify env (VSigma x d r) (VSigma _ d' r') = do
  384. unify env d d'
  385. unify env (r (VVar x)) (r' (VVar x))
  386. unify env VType VType = pure ()
  387. unify env VI VI = pure ()
  388. unify env VBool VBool = pure ()
  389. unify env (VPair a b) e = unify env a (proj1 e) *> unify env b (proj2 e)
  390. unify env e (VPair a b) = unify env a (proj1 e) *> unify env b (proj2 e)
  391. unify env (VPath a x y) (VPath a' x' y') = unify env a a' *> unify env x x' *> unify env y y'
  392. unify env (VComp a phi u a0) (VComp a' phi' u' a0') =
  393. traverse_ (uncurry (unify env))
  394. [ (a, a')
  395. , (phi, phi')
  396. , (u, u')
  397. , (a0, a0')
  398. ]
  399. unify env (VComp a (reduceCube env -> Just P.Top) u a0) vl =
  400. unify env (u @@ VI1) vl
  401. unify env vl (VComp a (reduceCube env -> Just P.Top) u a0) =
  402. unify env (u @@ VI1) vl
  403. unify env (VSystem fs) vl
  404. | ((_, vl'):_) <-
  405. Map.toList (Map.filterWithKey (\f _ -> isTrue (toValue' env f)) (getSystem fs))
  406. = unify env vl' vl
  407. | Map.null (getSystem fs) = pure ()
  408. unify env vl (VSystem fs)
  409. | ((_, vl'):_) <-
  410. Map.toList (Map.filterWithKey (\f _ -> isTrue (toValue' env f)) (getSystem fs))
  411. = unify env vl' vl
  412. | Map.null (getSystem fs) = pure ()
  413. unify env VType VTypeω = pure ()
  414. unify env VTypeω VTypeω = pure ()
  415. unify env (VGlue _ VI1 b _) x = unify env b x
  416. unify env VTrue VTrue = pure ()
  417. unify env VFalse VFalse = pure ()
  418. unify env (VIf p a b c) (VIf p' a' b' c') = traverse_ (uncurry (unify env)) [(p, p'), (a, a'), (b, b'), (c, c')]
  419. unify env x y =
  420. case sameCube env x y of
  421. Just True -> pure ()
  422. _ -> throwIO $ Mismatch x y
  423. reduceCube :: Env -> Value -> Maybe Formula
  424. reduceCube env x = fmap (toDNF . simplify) (toFormula x) where
  425. simplify :: Formula -> Formula
  426. simplify (P.Is0 x) =
  427. case Map.lookup x (names env) of
  428. Just (VI, VI0) -> P.Top
  429. Just (VI, VI1) -> P.Bot
  430. _ -> P.Is0 x
  431. simplify (P.Is1 x) =
  432. case Map.lookup x (names env) of
  433. Just (VI, VI1) -> P.Top
  434. Just (VI, VI0) -> P.Bot
  435. _ -> P.Is1 x
  436. simplify (P.And x y) = P.And (simplify x) (simplify y)
  437. simplify (P.Or x y) = P.Or (simplify x) (simplify y)
  438. simplify x = x
  439. sameCube :: Env -> Value -> Value -> Maybe Bool
  440. sameCube env x y =
  441. case (reduceCube env x, reduceCube env y) of
  442. (Just x, Just y) -> Just (x == y)
  443. _ -> Nothing
  444. toFormula :: Value -> Maybe Formula
  445. toFormula VI0 = Just P.Bot
  446. toFormula VI1 = Just P.Top
  447. toFormula (VNe x []) = Just (P.Is1 x)
  448. toFormula (VINot f) = notFormula <$> toFormula f
  449. toFormula (VIAnd x y) = do
  450. s <- toFormula y
  451. t <- toFormula x
  452. pure $ andFormula [s, t]
  453. toFormula (VIOr x y) = do
  454. s <- toFormula y
  455. t <- toFormula x
  456. pure $ orFormula [s, t]
  457. toFormula _ = Nothing
  458. faceInEnv :: Env -> Face -> Bool
  459. faceInEnv e f = Map.isSubmapOf (getFace f) (faceOfEnv (names e)) where
  460. faceOfEnv = Map.map (\(_, v) -> case v of { VI1 -> True; VEqGlued _ VI1 -> True; _ -> False }) . Map.filter (\(_, v) -> isI v)
  461. isI VI1 = True
  462. isI VI0 = True
  463. isI (VEqGlued _ x) = isI x
  464. isI _ = False
  465. isPiType :: Value -> IO (String, Value, Value -> Value)
  466. isPiType (VPi x d r) = pure (x, d, r)
  467. isPiType x = throwIO $ NotPiType x
  468. isSigmaType :: Value -> IO (String, Value, Value -> Value)
  469. isSigmaType (VSigma x d r) = pure (x, d, r)
  470. isSigmaType x = throwIO $ NotSigmaType x
  471. isPiOrPathType :: Value -> IO (Either (String, Value, Value -> Value) (Value, Value, Value))
  472. isPiOrPathType (VPi x d r) = pure (Left (x, d, r))
  473. isPiOrPathType (VPath x d r) = pure (Right (x, d, r))
  474. isPiOrPathType x = throwIO $ NotPiType x
  475. isPartialType :: Formula -> Value -> IO (Formula, Value)
  476. isPartialType f p@(VPartial x y) =
  477. case toFormula x of
  478. Just x -> pure (x, y)
  479. Nothing -> throwIO $ NotPartialType f p
  480. isPartialType f p@(VPartialP x y) =
  481. case toFormula x of
  482. Just x -> pure (x, y)
  483. Nothing -> throwIO $ NotPartialType f p
  484. isPartialType f x = throwIO $ NotPartialType f x
  485. getVar :: IO Value
  486. getVar =
  487. do
  488. n <- atomicModifyIORef ref \x -> (x + 1, x)
  489. pure (VVar (show n))
  490. where
  491. ref :: IORef Int
  492. ref = unsafePerformIO (newIORef 0)
  493. {-# NOINLINE ref #-}
  494. fill :: Env
  495. -> Value
  496. -> (Value -> Value) -- (Γ i : I, A : Type)
  497. -> Formula -- (phi : I)
  498. -> Value -- (u : (i : I) -> Partial phi (A i))
  499. -> Value -- (Sub (A i0) phi (u i0))
  500. -> Value -- -> A i
  501. fill env i a phi u a0 =
  502. comp env
  503. (VLam "j" VI \j -> a (i `iand` j))
  504. (phi `P.Or` notFormula ifc)
  505. (VLam "j" VI \j ->
  506. mkVSystem (Map.fromList [ (phi, uiand j)
  507. , (notFormula ifc, a0) ]))
  508. a0
  509. where
  510. uiand j = u @@ (i `iand` j)
  511. ifc = fromMaybe P.Bot $ (reduceCube env i)
  512. toValue :: Formula -> Value
  513. toValue P.Top = VI1
  514. toValue P.Bot = VI0
  515. toValue (P.And x y) = toValue x `iand` toValue y
  516. toValue (P.Or x y) = toValue x `ior` toValue y
  517. toValue (P.Is0 x) = inot (VVar x)
  518. toValue (P.Is1 x) = VVar x
  519. toValue' :: HasCallStack => Env -> Formula -> Value
  520. toValue' env P.Top = VI1
  521. toValue' env P.Bot = VI0
  522. toValue' env (P.And x y) = toValue x `iand` toValue y
  523. toValue' env (P.Or x y) = toValue x `ior` toValue y
  524. toValue' env (P.Is0 x) =
  525. case Map.lookup x (names env) of
  526. Just (VI, VI0) -> VI1
  527. Just (VI, VI1) -> VI0
  528. Just (VI, x) -> inot x
  529. vl -> error $ "type error in toValue' " ++ x ++ ": " ++ show vl
  530. toValue' env (P.Is1 x) =
  531. case Map.lookup x (names env) of
  532. Just (VI, x) -> x
  533. vl -> error $ "type error in toValue': Is1 " ++ show x ++ ": " ++ show vl
  534. isTrue :: Value -> Bool
  535. isTrue VI1 = True
  536. isTrue _ = False
  537. equiv :: Value -> Value -> Value
  538. equiv t a = VSigma "f" (VPi "_" t (const a)) \f -> isEquiv t a f
  539. isEquiv :: Value -> Value -> Value -> Value
  540. isEquiv t a f = VPi "y" a \y -> isContr (VSigma "x" t \x -> VPath (VLam "_" VI (const a)) y (f @@ x))
  541. isContr :: Value -> Value
  542. isContr t = VSigma "x" t \x -> VPi "y" t \y -> VPath (VLam "_" VI (const t)) x y