|
@ -1,4 +1,4 @@ |
|
|
{-# LANGUAGE TupleSections, OverloadedStrings #-} |
|
|
|
|
|
|
|
|
{-# LANGUAGE TupleSections #-} |
|
|
{-# LANGUAGE DeriveAnyClass #-} |
|
|
{-# LANGUAGE DeriveAnyClass #-} |
|
|
{-# LANGUAGE ScopedTypeVariables #-} |
|
|
{-# LANGUAGE ScopedTypeVariables #-} |
|
|
module Elab where |
|
|
module Elab where |
|
@ -7,8 +7,11 @@ import Control.Monad.Reader |
|
|
import Control.Exception |
|
|
import Control.Exception |
|
|
|
|
|
|
|
|
import qualified Data.Map.Strict as Map |
|
|
import qualified Data.Map.Strict as Map |
|
|
|
|
|
import Data.Traversable |
|
|
import Data.Typeable |
|
|
import Data.Typeable |
|
|
|
|
|
import Data.Foldable |
|
|
|
|
|
|
|
|
|
|
|
import Elab.Eval.Formula (possible) |
|
|
import Elab.WiredIn |
|
|
import Elab.WiredIn |
|
|
import Elab.Monad |
|
|
import Elab.Monad |
|
|
import Elab.Eval |
|
|
import Elab.Eval |
|
@ -17,8 +20,9 @@ import qualified Presyntax.Presyntax as P |
|
|
|
|
|
|
|
|
import Prettyprinter |
|
|
import Prettyprinter |
|
|
|
|
|
|
|
|
import Syntax.Pretty |
|
|
|
|
|
import Syntax |
|
|
import Syntax |
|
|
|
|
|
import Syntax.Pretty |
|
|
|
|
|
import qualified Data.Text as T |
|
|
|
|
|
|
|
|
infer :: P.Expr -> ElabM (Term, NFType) |
|
|
infer :: P.Expr -> ElabM (Term, NFType) |
|
|
infer (P.Span ex a b) = withSpan a b $ infer ex |
|
|
infer (P.Span ex a b) = withSpan a b $ infer ex |
|
@ -40,6 +44,27 @@ infer (P.App p f x) = do |
|
|
x <- check x VI |
|
|
x <- check x VI |
|
|
x_nf <- eval x |
|
|
x_nf <- eval x |
|
|
pure (IElim (quote (fun li)) (quote le) (quote ri) (wp f) x, li x_nf) |
|
|
pure (IElim (quote (fun li)) (quote le) (quote ri) (wp f) x, li x_nf) |
|
|
|
|
|
It'sPartial phi a w -> do |
|
|
|
|
|
x <- check x (VIsOne phi) |
|
|
|
|
|
pure (App P.Ex (w f) x, a) |
|
|
|
|
|
It'sPartialP phi a w -> do |
|
|
|
|
|
x <- check x (VIsOne phi) |
|
|
|
|
|
x_nf <- eval x |
|
|
|
|
|
pure (App P.Ex (w f) x, a @@ x_nf) |
|
|
|
|
|
|
|
|
|
|
|
infer (P.Bracket ex) = do |
|
|
|
|
|
nm <- getNameFor (T.pack "IsOne") |
|
|
|
|
|
ty <- getNfType nm |
|
|
|
|
|
porp <- isPiType P.Ex ty |
|
|
|
|
|
case porp of |
|
|
|
|
|
It'sProd d r w -> do |
|
|
|
|
|
t <- check ex d |
|
|
|
|
|
t_nf <- eval t |
|
|
|
|
|
pure (App P.Ex (w (Ref nm)) t, r t_nf) |
|
|
|
|
|
_ -> do |
|
|
|
|
|
d <- newMeta VType |
|
|
|
|
|
r <- newMeta VType |
|
|
|
|
|
throwElab $ NotEqual ty (VPi P.Ex d (Closure (T.pack "x") (const r))) |
|
|
|
|
|
|
|
|
infer (P.Proj1 x) = do |
|
|
infer (P.Proj1 x) = do |
|
|
(tm, ty) <- infer x |
|
|
(tm, ty) <- infer x |
|
@ -71,19 +96,32 @@ check tm (VPi P.Im dom (Closure var rng)) = |
|
|
check (P.Lam p v b) ty = do |
|
|
check (P.Lam p v b) ty = do |
|
|
porp <- isPiType p =<< forceIO ty |
|
|
porp <- isPiType p =<< forceIO ty |
|
|
case porp of |
|
|
case porp of |
|
|
It'sProd d r wp -> do |
|
|
|
|
|
|
|
|
It'sProd d r wp -> |
|
|
assume (Bound v) d $ |
|
|
assume (Bound v) d $ |
|
|
wp . Lam p v <$> check b (r (VVar (Bound v))) |
|
|
wp . Lam p v <$> check b (r (VVar (Bound v))) |
|
|
|
|
|
|
|
|
It'sPath li le ri wp -> do |
|
|
It'sPath li le ri wp -> do |
|
|
tm <- assume (Bound v) VI $ |
|
|
tm <- assume (Bound v) VI $ |
|
|
Lam P.Ex v <$> check b (li (VVar (Bound v))) |
|
|
|
|
|
|
|
|
Lam P.Ex v <$> check b (force (li (VVar (Bound v)))) |
|
|
|
|
|
|
|
|
tm_nf <- eval tm |
|
|
tm_nf <- eval tm |
|
|
|
|
|
|
|
|
unify (tm_nf @@ VI0) le |
|
|
unify (tm_nf @@ VI0) le |
|
|
`catchElab` (throwElab . WhenCheckingEndpoint le ri VI0) |
|
|
`catchElab` (throwElab . WhenCheckingEndpoint le ri VI0) |
|
|
|
|
|
|
|
|
unify (tm_nf @@ VI1) ri |
|
|
unify (tm_nf @@ VI1) ri |
|
|
`catchElab` (throwElab . WhenCheckingEndpoint le ri VI1) |
|
|
`catchElab` (throwElab . WhenCheckingEndpoint le ri VI1) |
|
|
|
|
|
|
|
|
pure (wp (PathIntro (quote (fun li)) tm)) |
|
|
pure (wp (PathIntro (quote (fun li)) tm)) |
|
|
|
|
|
|
|
|
|
|
|
It'sPartial phi a wp -> |
|
|
|
|
|
assume (Bound v) (VIsOne phi) $ |
|
|
|
|
|
wp . Lam p v <$> check b a |
|
|
|
|
|
|
|
|
|
|
|
It'sPartialP phi a wp -> |
|
|
|
|
|
assume (Bound v) (VIsOne phi) $ |
|
|
|
|
|
wp . Lam p v <$> check b (a @@ VVar (Bound v)) |
|
|
|
|
|
|
|
|
check (P.Pair a b) ty = do |
|
|
check (P.Pair a b) ty = do |
|
|
(d, r, wp) <- isSigmaType =<< forceIO ty |
|
|
(d, r, wp) <- isSigmaType =<< forceIO ty |
|
|
a <- check a d |
|
|
a <- check a d |
|
@ -107,11 +145,52 @@ check (P.Sigma s d r) ty = do |
|
|
r <- check r ty |
|
|
r <- check r ty |
|
|
pure (Sigma s d r) |
|
|
pure (Sigma s d r) |
|
|
|
|
|
|
|
|
|
|
|
check (P.LamSystem bs) ty = do |
|
|
|
|
|
(extent, dom) <- isPartialType ty |
|
|
|
|
|
eqns <- for (zip [(0 :: Int)..] bs) $ \(n, (formula, rhs)) -> do |
|
|
|
|
|
formula <- checkFormula formula |
|
|
|
|
|
rhs <- check rhs dom |
|
|
|
|
|
pure (n, (formula, rhs)) |
|
|
|
|
|
|
|
|
|
|
|
unify extent (foldl ior VI0 (map (fst . snd) eqns)) |
|
|
|
|
|
|
|
|
|
|
|
for_ eqns $ \(n, (formula, rhs)) -> |
|
|
|
|
|
for_ eqns $ \(n', (formula', rhs')) -> do |
|
|
|
|
|
let truth = possible mempty (iand formula formula') |
|
|
|
|
|
when ((n /= n') && fst truth) $ do |
|
|
|
|
|
vl <- eval rhs |
|
|
|
|
|
vl' <- eval rhs' |
|
|
|
|
|
unify vl vl' |
|
|
|
|
|
`withNote` vsep [ pretty "These two cases must agree because they are both possible:" |
|
|
|
|
|
, indent 2 $ pretty '*' <+> prettyTm (quote formula) <+> operator (pretty "=>") <+> prettyTm rhs |
|
|
|
|
|
, indent 2 $ pretty '*' <+> prettyTm (quote formula') <+> operator (pretty "=>") <+> prettyTm rhs' |
|
|
|
|
|
] |
|
|
|
|
|
`withNote` (pretty "Consider this face, where both are true:" <+> showFace (snd truth)) |
|
|
|
|
|
|
|
|
|
|
|
name <- newName |
|
|
|
|
|
pure (Lam P.Ex name (System (Map.fromList (map (\(_, (x, y)) -> (quote x, y)) eqns)))) |
|
|
|
|
|
|
|
|
check exp ty = do |
|
|
check exp ty = do |
|
|
(tm, has) <- switch $ infer exp |
|
|
(tm, has) <- switch $ infer exp |
|
|
wp <- isConvertibleTo has ty |
|
|
wp <- isConvertibleTo has ty |
|
|
pure (wp tm) |
|
|
pure (wp tm) |
|
|
|
|
|
|
|
|
|
|
|
checkFormula :: P.Formula -> ElabM Value |
|
|
|
|
|
checkFormula P.FTop = pure VI1 |
|
|
|
|
|
checkFormula P.FBot = pure VI0 |
|
|
|
|
|
checkFormula (P.FAnd x y) = iand <$> checkFormula x <*> checkFormula y |
|
|
|
|
|
checkFormula (P.FOr x y) = ior <$> checkFormula x <*> checkFormula y |
|
|
|
|
|
checkFormula (P.FIs0 x) = do |
|
|
|
|
|
nm <- getNameFor x |
|
|
|
|
|
ty <- getNfType nm |
|
|
|
|
|
unify ty VI |
|
|
|
|
|
pure (inot (VVar nm)) |
|
|
|
|
|
checkFormula (P.FIs1 x) = do |
|
|
|
|
|
nm <- getNameFor x |
|
|
|
|
|
ty <- getNfType nm |
|
|
|
|
|
unify ty VI |
|
|
|
|
|
pure (VVar nm) |
|
|
|
|
|
|
|
|
isSort :: NFType -> ElabM () |
|
|
isSort :: NFType -> ElabM () |
|
|
isSort VType = pure () |
|
|
isSort VType = pure () |
|
|
isSort VTypeω = pure () |
|
|
isSort VTypeω = pure () |
|
@ -128,16 +207,29 @@ data ProdOrPath |
|
|
, pathRight :: Value |
|
|
, pathRight :: Value |
|
|
, pathWrap :: Term -> Term |
|
|
, pathWrap :: Term -> Term |
|
|
} |
|
|
} |
|
|
|
|
|
| It'sPartial { partialExtent :: NFEndp |
|
|
|
|
|
, partialDomain :: Value |
|
|
|
|
|
, partialWrap :: Term -> Term |
|
|
|
|
|
} |
|
|
|
|
|
| It'sPartialP { partialExtent :: NFEndp |
|
|
|
|
|
, partialDomain :: Value |
|
|
|
|
|
, partialWrap :: Term -> Term |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
isPiType :: P.Plicity -> NFType -> ElabM ProdOrPath |
|
|
isPiType :: P.Plicity -> NFType -> ElabM ProdOrPath |
|
|
isPiType p (VPi p' d (Closure _ k)) | p == p' = pure (It'sProd d k id) |
|
|
isPiType p (VPi p' d (Closure _ k)) | p == p' = pure (It'sProd d k id) |
|
|
isPiType P.Ex (VPath li le ri) = pure (It'sPath (li @@) le ri id) |
|
|
isPiType P.Ex (VPath li le ri) = pure (It'sPath (li @@) le ri id) |
|
|
|
|
|
isPiType P.Ex (VPartial phi a) = pure (It'sPartial phi a id) |
|
|
|
|
|
isPiType P.Ex (VPartialP phi a) = pure (It'sPartialP phi a id) |
|
|
|
|
|
|
|
|
isPiType P.Ex (VPi P.Im d (Closure _ k)) = do |
|
|
isPiType P.Ex (VPi P.Im d (Closure _ k)) = do |
|
|
meta <- newMeta d |
|
|
meta <- newMeta d |
|
|
porp <- isPiType P.Ex (k meta) |
|
|
porp <- isPiType P.Ex (k meta) |
|
|
pure $ case porp of |
|
|
pure $ case porp of |
|
|
It'sProd d r w -> It'sProd d r (\f -> w (App P.Im f (quote meta))) |
|
|
It'sProd d r w -> It'sProd d r (\f -> w (App P.Im f (quote meta))) |
|
|
It'sPath l x y w -> It'sPath l x y (\f -> w (App P.Im f (quote meta))) |
|
|
It'sPath l x y w -> It'sPath l x y (\f -> w (App P.Im f (quote meta))) |
|
|
|
|
|
It'sPartial phi a w -> It'sPartial phi a (\f -> w (App P.Im f (quote meta))) |
|
|
|
|
|
It'sPartialP phi a w -> It'sPartialP phi a (\f -> w (App P.Im f (quote meta))) |
|
|
isPiType p t = do |
|
|
isPiType p t = do |
|
|
dom <- newMeta VType |
|
|
dom <- newMeta VType |
|
|
name <- newName |
|
|
name <- newName |
|
@ -156,8 +248,14 @@ isSigmaType t = do |
|
|
wp <- isConvertibleTo t (VSigma dom (Closure name (const rng))) |
|
|
wp <- isConvertibleTo t (VSigma dom (Closure name (const rng))) |
|
|
pure (dom, const rng, wp) |
|
|
pure (dom, const rng, wp) |
|
|
|
|
|
|
|
|
identityTy :: NFType |
|
|
|
|
|
identityTy = VPi P.Im VType (Closure "A" $ \t -> VPi P.Ex t (Closure "_" (const t))) |
|
|
|
|
|
|
|
|
isPartialType :: NFType -> ElabM (NFEndp, Value) |
|
|
|
|
|
isPartialType (VPartial phi a) = pure (phi, a) |
|
|
|
|
|
isPartialType (VPartialP phi a) = pure (phi, a) |
|
|
|
|
|
isPartialType t = do |
|
|
|
|
|
phi <- newMeta VI |
|
|
|
|
|
dom <- newMeta (VPartial phi VType) |
|
|
|
|
|
unify t (VPartial phi dom) |
|
|
|
|
|
pure (phi, dom) |
|
|
|
|
|
|
|
|
checkStatement :: P.Statement -> ElabM a -> ElabM a |
|
|
checkStatement :: P.Statement -> ElabM a -> ElabM a |
|
|
checkStatement (P.SpanSt s a b) k = withSpan a b $ checkStatement s k |
|
|
checkStatement (P.SpanSt s a b) k = withSpan a b $ checkStatement s k |
|
@ -194,7 +292,7 @@ checkStatement (P.Builtin winame var) k = do |
|
|
nm <- getNameFor var |
|
|
nm <- getNameFor var |
|
|
ty <- getNfType nm |
|
|
ty <- getNfType nm |
|
|
unify ty (wiType wi) |
|
|
unify ty (wiType wi) |
|
|
`withNote` hsep [ "Previous definition of", pretty nm, "here" ] |
|
|
|
|
|
|
|
|
`withNote` hsep [ pretty "Previous definition of", pretty nm, pretty "here" ] |
|
|
`seeAlso` nm |
|
|
`seeAlso` nm |
|
|
|
|
|
|
|
|
env <- ask |
|
|
env <- ask |
|
|