|
|
@ -12,8 +12,6 @@ import Data.Typeable |
|
|
|
import Data.IORef |
|
|
|
import Data.Maybe |
|
|
|
|
|
|
|
import Debug.Trace |
|
|
|
|
|
|
|
import GHC.Stack |
|
|
|
|
|
|
|
import qualified Presyntax as P |
|
|
@ -24,6 +22,7 @@ import Syntax |
|
|
|
import System.IO.Unsafe (unsafePerformIO) |
|
|
|
|
|
|
|
import Systems |
|
|
|
import Debug.Trace (traceShowId) |
|
|
|
|
|
|
|
iand :: Value -> Value -> Value |
|
|
|
iand = \case |
|
|
@ -52,26 +51,37 @@ inot (VINot x) = x |
|
|
|
inot x = VINot x |
|
|
|
|
|
|
|
(@@) :: Value -> Value -> Value |
|
|
|
VNe hd xs @@ vl = VNe hd (PApp vl:xs) |
|
|
|
VLam _ _ k @@ vl = k vl |
|
|
|
VEqGlued a b @@ vl = VEqGlued (a @@ vl) (b @@ vl) |
|
|
|
VOfSub a phi u0 x @@ vl = x @@ vl |
|
|
|
VSystem fs @@ vl = mapVSystem (VSystem fs) (@@ vl) |
|
|
|
f @@ _ = error $ "can't apply argument to " ++ show f |
|
|
|
VNe hd xs @@ vl = VNe hd (PApp vl:xs) |
|
|
|
VLam _ _ k @@ vl = k vl |
|
|
|
VEqGlued a b @@ vl = VEqGlued (a @@ vl) (b @@ vl) |
|
|
|
VOfSub (VPi _ _ k) phi u0 x @@ vl = VOfSub (k vl) phi (u0 @@ vl) (x @@ vl) |
|
|
|
VSystem fs @@ vl = mapVSystem (VSystem fs) (@@ vl) |
|
|
|
VIf (VLam s d k) c t b @@ vl = VIf (VLam s d (ap . force . k)) (c @@ vl) (t @@ vl) b where |
|
|
|
ap (VPi _ _ r) = r vl |
|
|
|
ap _ = error "type error when pushing application into if" |
|
|
|
f @@ _ = error $ "\ncan't apply argument to " ++ show f |
|
|
|
|
|
|
|
proj1 :: Value -> Value |
|
|
|
proj1 (VPair x _) = x |
|
|
|
proj1 (VEqGlued x y) = VEqGlued (proj1 x) (proj1 y) |
|
|
|
proj1 (VNe s xs) = VNe s (PProj1:xs) |
|
|
|
proj1 (VOfSub (VSigma _ d _) phi u0 x) = VOfSub d phi (proj1 u0) (proj1 x) |
|
|
|
proj1 v@VSystem{} = mapVSystem v proj1 |
|
|
|
proj1 (VIf (VLam s d k) c t b) = VIf (VLam s d (proj1t . k)) (proj1 c) (proj1 t) b where |
|
|
|
proj1t (VSigma _ d _) = d |
|
|
|
proj1t _ = error "type error when pushing proj1 into if" |
|
|
|
proj1 x = error $ "can't proj1 " ++ show x |
|
|
|
|
|
|
|
proj2 :: Value -> Value |
|
|
|
proj2 (VPair _ y) = y |
|
|
|
proj2 (VEqGlued x y) = VEqGlued (proj1 x) (proj1 y) |
|
|
|
proj2 (VEqGlued x y) = VEqGlued (proj2 x) (proj2 y) |
|
|
|
proj2 (VNe s xs) = VNe s (PProj2:xs) |
|
|
|
proj2 (VOfSub (VSigma _ d r) phi u0 x) = |
|
|
|
VOfSub (r (proj1 x)) phi (proj2 u0) (proj2 x) |
|
|
|
proj2 v@VSystem{} = mapVSystem v proj2 |
|
|
|
proj2 (VIf (VLam s d k) c t b) = VIf (VLam s d (proj2t . k)) (proj2 c) (proj2 t) b where |
|
|
|
proj2t (VSigma _ d r) = r (VIf (VLam s VBool (const d)) (proj1 c) (proj1 t) b) |
|
|
|
proj2t _ = error "type error when pushing proj1 into if" |
|
|
|
proj2 x = error $ "can't proj2 " ++ show x |
|
|
|
|
|
|
|
pathp :: Env -> Value -> Value -> Value -> Value -> Value -> Value |
|
|
@ -81,12 +91,17 @@ pathp env p x y f@(VLine _a _x _y e) i = |
|
|
|
Just P.Top -> VEqGlued (e i) y |
|
|
|
_ -> e i |
|
|
|
pathp env p x y (VEqGlued e e') i = VEqGlued (pathp env p x y e i) (pathp env p x y e' i) |
|
|
|
|
|
|
|
pathp env p x y (VNe hd sp) i = |
|
|
|
case reduceCube env i of |
|
|
|
Just P.Bot -> VEqGlued (VNe hd (PPathP p x y i:sp)) x |
|
|
|
Just P.Top -> VEqGlued (VNe hd (PPathP p x y i:sp)) y |
|
|
|
_ | quote x == quote y -> VEqGlued (VNe hd (PPathP p x y i:sp)) x |
|
|
|
_ -> VNe hd (PPathP p x y i:sp) |
|
|
|
|
|
|
|
pathp env p x y (VOfSub _ _ _ v) i = pathp env p x y v i |
|
|
|
pathp env p x y v@VSystem{} i = mapVSystem v (\f -> pathp env p x y f i) |
|
|
|
pathp env p x y f i = error $ "Invalid pathP " ++ show f ++ " @@ " ++ show i |
|
|
|
|
|
|
|
comp :: Env -> Value -> Formula -> Value -> Value -> Value |
|
|
|
comp env a@(VLam ivar VI fam) phi u a0 = glue $ go (fam (VVar "woopsie")) phi u a0 where |
|
|
@ -94,7 +109,7 @@ comp env a@(VLam ivar VI fam) phi u a0 = glue $ go (fam (VVar "woopsie")) phi u |
|
|
|
stuck = VComp a (toValue phi) u a0 |
|
|
|
|
|
|
|
glue :: Value -> Value |
|
|
|
glue = VOfSub (fam VI1) (toValue' env phi) (u @@ VI1) |
|
|
|
glue = VOfSub (fam VI1) (toValue phi) (u @@ VI1) |
|
|
|
|
|
|
|
go :: HasCallStack => Value -> Formula -> Value -> Value -> Value |
|
|
|
go VPi{} phi u a0 = |
|
|
@ -148,6 +163,35 @@ comp env a@(VLam ivar VI fam) phi u a0 = glue $ go (fam (VVar "woopsie")) phi u |
|
|
|
]) |
|
|
|
(pathp env (ai0 @@ VI0) u0 v0 p0 j) |
|
|
|
|
|
|
|
go VGlue{} psi b b0 = |
|
|
|
let |
|
|
|
base i = let VGlue base _ _ _ = force $ fam i in base |
|
|
|
phi i = |
|
|
|
case force (fam i) of |
|
|
|
VGlue _ phi _ _ -> fromJust (reduceCube env phi) |
|
|
|
x -> error (show x) |
|
|
|
types i = let VGlue _ _ types _ = force $ fam i in types |
|
|
|
equivs i = let VGlue _ _ _ equivs = force $ fam i in equivs |
|
|
|
|
|
|
|
a i = mapVSystem (b @@ i) (unglue (base i) (phi i) (types i) (equivs i)) |
|
|
|
a0 = unglue (base VI0) (phi VI0) (types VI0) (equivs VI0) b0 |
|
|
|
|
|
|
|
del = faceForall phi |
|
|
|
a1' = comp env (VLam "i" VI base) psi (VLam "i" VI a) a0 |
|
|
|
t1' = comp env (VLam "i" VI types) psi (VLam "i" VI (b @@)) b0 |
|
|
|
omega = pres env types base (flip mapVSystem proj1 . equivs) psi b b0 |
|
|
|
t1alpha = opEquiv env (base VI1) (types VI1) (equivs VI1) (orFormula [del, psi]) ts ps a1' |
|
|
|
(t1, alpha) = (proj1 t1alpha, proj2 t1alpha) |
|
|
|
|
|
|
|
ts = VSystem (FMap (Map.fromList [(del, t1'), (psi, b @@ VI1)])) |
|
|
|
ps = VSystem (FMap (Map.fromList [(del, omega), (psi, VLine (VLam "j" VI \_ -> base VI1) a1' a1' (\j -> a1'))])) |
|
|
|
|
|
|
|
a1 = comp env (VLam "j" VI (const (base VI1))) (orFormula [phi VI1, psi]) (VLam "j" VI \j -> a1_sys j) a1' |
|
|
|
a1_sys j = VSystem (FMap (Map.fromList [(phi VI1, pathp env (base VI1) a1' (mapVSystem (equivs VI1) proj1) alpha j), (psi, a VI1)])) |
|
|
|
b1 = introGlue (base VI1) (phi VI1) (types VI1) (equivs VI1) t1 a1 |
|
|
|
in b1 |
|
|
|
|
|
|
|
go VBool{} _ _ a0 = a0 |
|
|
|
go a P.Top u a0 = u @@ VI1 |
|
|
|
go a phi u a0 = stuck |
|
|
|
|
|
|
@ -158,6 +202,50 @@ comp env va phi u a0 = |
|
|
|
where |
|
|
|
phi' = toValue phi |
|
|
|
|
|
|
|
opEquiv :: Env -> Value -> Value -> Value -> Formula -> Value -> Value -> Value -> Value |
|
|
|
opEquiv env aT tT f phi t p a = VOfSub ty (toValue phi) (VPair t p) v where |
|
|
|
fun = proj1 f |
|
|
|
ty = VSigma "x" tT \x -> VPath (VLam "i" VI (const aT)) a (fun @@ x) |
|
|
|
sys = Map.singleton phi (VPair t p) |
|
|
|
v = contr env ty (proj2 f @@ a) phi (VSystem (FMap sys)) |
|
|
|
|
|
|
|
force :: Value -> Value |
|
|
|
force (VEqGlued x _) = force x |
|
|
|
force (VOfSub _ _ _ x) = force x |
|
|
|
force x = x |
|
|
|
|
|
|
|
faceForall :: (Value -> Formula) -> Formula |
|
|
|
faceForall k = go (k (VVar "$elim")) where |
|
|
|
go (P.Is0 "$elim") = P.Bot |
|
|
|
go (P.Is1 "$elim") = P.Bot |
|
|
|
go (P.Or a b) = orFormula [go a, go b] |
|
|
|
go (P.And a b) = andFormula [go a, go b] |
|
|
|
go x = x |
|
|
|
|
|
|
|
pres :: Env -> (Value -> Value) -> (Value -> Value) -> (Value -> Value) -> Formula -> Value -> Value -> Value |
|
|
|
pres env tT tA f phi t t0 = VOfSub (VPath (tA VI1) c1 c2) (toValue phi) base (VLine (tA VI1) c1 c2 cont) where |
|
|
|
c1 = comp env (VLam "i" VI tA) phi (VLam "i" VI \j -> mapVSystem t (f j @@)) (f VI0 @@ t0) |
|
|
|
c2 = f VI1 @@ comp env (VLam "i" VI tA) phi t t0 |
|
|
|
base = VLine (tA VI1) (f VI1 @@ (t @@ VI1)) (f VI1 @@ (t @@ VI1)) (\i -> f VI1 @@ (t @@ VI1)) |
|
|
|
cont j = |
|
|
|
let v i = fill env i tT phi t t0 |
|
|
|
form = orFormula [phi, fromJust (reduceCube env j)] |
|
|
|
a0 = f VI0 @@ t0 |
|
|
|
in comp env (VLam "I" VI tA) form |
|
|
|
(VLam "I" VI (\j -> VSystem (FMap (Map.fromList [(form, f j @@ v j)])))) |
|
|
|
a0 |
|
|
|
|
|
|
|
contr :: Env -> Value -> Value -> Formula -> Value -> Value |
|
|
|
contr env a aC phi u = |
|
|
|
comp env (VLam "i" VI (const a)) phi |
|
|
|
(VLam "i" VI (pathp env a u (proj1 aC) (proj2 aC @@ u))) |
|
|
|
(proj1 aC) |
|
|
|
|
|
|
|
-- t : Partial phi T |
|
|
|
-- T : Type |
|
|
|
-- a : A |
|
|
|
-- f : Equiv T A |
|
|
|
|
|
|
|
mkVSystem :: Map.Map Formula Value -> Value |
|
|
|
mkVSystem mp |
|
|
|
| Just e <- Map.lookup P.Top mp = e |
|
|
@ -189,6 +277,19 @@ evalSystem env face = mk . Map.fromList . mapMaybe (uncurry go) . Map.toList $ f |
|
|
|
[(_, x)] -> x |
|
|
|
_ -> mkVSystem x |
|
|
|
|
|
|
|
glue :: Value -> Formula -> Value -> Value -> Value |
|
|
|
-- glue baseT P.Top types _equivs = types |
|
|
|
glue baseT phi types equivs = VGlue baseT (toValue phi) types equivs |
|
|
|
|
|
|
|
introGlue :: Value -> Formula -> Value -> Value -> Value -> Value -> Value |
|
|
|
introGlue baseT P.Top types equivs t a = t |
|
|
|
introGlue baseT phi types equivs t a = VGlueIntro baseT (toValue phi) types equivs t a |
|
|
|
|
|
|
|
unglue :: Value -> Formula -> Value -> Value -> Value -> Value |
|
|
|
unglue baseT P.Top types equivs b = mapVSystem equivs ((@@ b) . proj1) |
|
|
|
unglue baseT phi types equivs val = |
|
|
|
VOfSub baseT (toValue phi) (mapVSystem equivs ((@@ val) . proj1)) (VGlueElim baseT (toValue phi) types equivs val) |
|
|
|
|
|
|
|
eval :: Env -> Term -> Value |
|
|
|
eval env = \case |
|
|
|
Var v -> |
|
|
@ -228,6 +329,7 @@ eval env = \case |
|
|
|
|
|
|
|
Path p x y -> VPath (eval env p) (eval env x) (eval env y) |
|
|
|
Partial r a -> VPartial (eval env r) (eval env a) |
|
|
|
PartialP r a -> VPartialP (eval env r) (eval env a) |
|
|
|
|
|
|
|
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) |
|
|
|
PathP p x y f i -> pathp env (eval env p) (eval env x) (eval env y) (eval env f) (eval env i) |
|
|
@ -246,6 +348,50 @@ eval env = \case |
|
|
|
|
|
|
|
System fs -> evalSystem env (getSystem fs) |
|
|
|
|
|
|
|
GlueTy a phi types equivs -> |
|
|
|
let phi' = eval env phi in |
|
|
|
case reduceCube env phi' of |
|
|
|
Just formula -> glue (eval env a) formula (eval env types) (eval env equivs) |
|
|
|
Nothing -> VGlue (eval env a) phi' (eval env types) (eval env equivs) |
|
|
|
|
|
|
|
Glue a phi types equivs t a0 -> |
|
|
|
let phi' = eval env phi |
|
|
|
t' = eval env t |
|
|
|
a0' = eval env a0 |
|
|
|
types' = eval env types |
|
|
|
equivs' = eval env equivs |
|
|
|
a' = eval env a |
|
|
|
in |
|
|
|
case reduceCube env phi' of |
|
|
|
Just formula -> introGlue a' formula types' equivs' t' a0' |
|
|
|
Nothing -> VGlueIntro a' phi' types' equivs' t' a0' |
|
|
|
|
|
|
|
Unglue a phi types equivs val -> |
|
|
|
let phi' = eval env phi |
|
|
|
val' = eval env val |
|
|
|
types' = eval env types |
|
|
|
equivs' = eval env equivs |
|
|
|
a' = eval env a |
|
|
|
in |
|
|
|
case reduceCube env phi' of |
|
|
|
Just formula -> unglue a' formula types' equivs' val' |
|
|
|
Nothing -> VGlueElim a' phi' types' equivs' val' |
|
|
|
|
|
|
|
If p x y t -> elimBool (eval env p) (eval env x) (eval env y) (eval env t) |
|
|
|
Tt -> VTrue |
|
|
|
Ff -> VFalse |
|
|
|
Bool -> VBool |
|
|
|
|
|
|
|
elimBool :: Value -> Value -> Value -> Value -> Value |
|
|
|
elimBool _ x _ (VEqGlued _ VTrue) = x |
|
|
|
elimBool _ x _ (VOfSub _ _ _ VTrue) = x |
|
|
|
elimBool _ x _ VTrue = x |
|
|
|
|
|
|
|
elimBool _ _ y (VEqGlued _ VFalse) = y |
|
|
|
elimBool _ _ y (VOfSub _ _ _ VFalse) = y |
|
|
|
elimBool _ _ y VFalse = y |
|
|
|
|
|
|
|
elimBool p x y t = VIf p x y t |
|
|
|
|
|
|
|
data UnifyError |
|
|
|
= Mismatch Value Value |
|
|
@ -320,10 +466,12 @@ unify env (VSigma x d r) (VSigma _ d' r') = do |
|
|
|
unify env (r (VVar x)) (r' (VVar x)) |
|
|
|
|
|
|
|
unify env VType VType = pure () |
|
|
|
unify env VI VI = pure () |
|
|
|
unify env VBool VBool = pure () |
|
|
|
|
|
|
|
unify env VI VI = pure () |
|
|
|
unify env (VPair a b) e = unify env a (proj1 e) *> unify env b (proj2 e) |
|
|
|
unify env e (VPair a b) = unify env a (proj1 e) *> unify env b (proj2 e) |
|
|
|
|
|
|
|
unify env (VPair a b) (VPair c d) = unify env a c *> unify env b d |
|
|
|
unify env (VPath a x y) (VPath a' x' y') = unify env a a' *> unify env x x' *> unify env y y' |
|
|
|
unify env (VComp a phi u a0) (VComp a' phi' u' a0') = |
|
|
|
traverse_ (uncurry (unify env)) |
|
|
@ -343,15 +491,23 @@ unify env (VSystem fs) vl |
|
|
|
| ((_, vl'):_) <- |
|
|
|
Map.toList (Map.filterWithKey (\f _ -> isTrue (toValue' env f)) (getSystem fs)) |
|
|
|
= unify env vl' vl |
|
|
|
| Map.null (getSystem fs) = pure () |
|
|
|
|
|
|
|
unify env vl (VSystem fs) |
|
|
|
| ((_, vl'):_) <- |
|
|
|
Map.toList (Map.filterWithKey (\f _ -> isTrue (toValue' env f)) (getSystem fs)) |
|
|
|
= unify env vl' vl |
|
|
|
| Map.null (getSystem fs) = pure () |
|
|
|
|
|
|
|
unify env VType VTypeω = pure () |
|
|
|
unify env VTypeω VTypeω = pure () |
|
|
|
|
|
|
|
unify env (VGlue _ VI1 b _) x = unify env b x |
|
|
|
|
|
|
|
unify env VTrue VTrue = pure () |
|
|
|
unify env VFalse VFalse = pure () |
|
|
|
unify env (VIf p a b c) (VIf p' a' b' c') = traverse_ (uncurry (unify env)) [(p, p'), (a, a'), (b, b'), (c, c')] |
|
|
|
|
|
|
|
unify env x y = |
|
|
|
case sameCube env x y of |
|
|
|
Just True -> pure () |
|
|
@ -422,6 +578,10 @@ isPartialType f p@(VPartial x y) = |
|
|
|
case toFormula x of |
|
|
|
Just x -> pure (x, y) |
|
|
|
Nothing -> throwIO $ NotPartialType f p |
|
|
|
isPartialType f p@(VPartialP x y) = |
|
|
|
case toFormula x of |
|
|
|
Just x -> pure (x, y) |
|
|
|
Nothing -> throwIO $ NotPartialType f p |
|
|
|
isPartialType f x = throwIO $ NotPartialType f x |
|
|
|
|
|
|
|
getVar :: IO Value |
|
|
@ -451,7 +611,7 @@ fill env i a phi u a0 = |
|
|
|
a0 |
|
|
|
where |
|
|
|
uiand j = u @@ (i `iand` j) |
|
|
|
ifc = fromJust (reduceCube env i) |
|
|
|
ifc = fromMaybe P.Bot $ (reduceCube env i) |
|
|
|
|
|
|
|
toValue :: Formula -> Value |
|
|
|
toValue P.Top = VI1 |
|
|
@ -475,8 +635,17 @@ toValue' env (P.Is0 x) = |
|
|
|
toValue' env (P.Is1 x) = |
|
|
|
case Map.lookup x (names env) of |
|
|
|
Just (VI, x) -> x |
|
|
|
_ -> error $ "type error in toValue'" |
|
|
|
vl -> error $ "type error in toValue': Is1 " ++ show x ++ ": " ++ show vl |
|
|
|
|
|
|
|
isTrue :: Value -> Bool |
|
|
|
isTrue VI1 = True |
|
|
|
isTrue _ = False |
|
|
|
|
|
|
|
equiv :: Value -> Value -> Value |
|
|
|
equiv t a = VSigma "f" (VPi "_" t (const a)) \f -> isEquiv t a f |
|
|
|
|
|
|
|
isEquiv :: Value -> Value -> Value -> Value |
|
|
|
isEquiv t a f = VPi "y" a \y -> isContr (VSigma "x" t \x -> VPath (VLam "_" VI (const a)) y (f @@ x)) |
|
|
|
|
|
|
|
isContr :: Value -> Value |
|
|
|
isContr t = VSigma "x" t \x -> VPi "y" t \y -> VPath (VLam "_" VI (const t)) x y |