|
|
@ -1,5 +1,6 @@ |
|
|
|
{-# LANGUAGE LambdaCase #-} |
|
|
|
{-# LANGUAGE DeriveAnyClass #-} |
|
|
|
{-# LANGUAGE ScopedTypeVariables #-} |
|
|
|
module Elab.Eval where |
|
|
|
|
|
|
|
import Control.Monad.Reader |
|
|
@ -15,6 +16,7 @@ import Data.Foldable |
|
|
|
import Data.IORef |
|
|
|
import Data.Maybe |
|
|
|
|
|
|
|
import {-# SOURCE #-} Elab.WiredIn |
|
|
|
import Elab.Monad |
|
|
|
|
|
|
|
import Presyntax.Presyntax (Plicity(..)) |
|
|
@ -22,6 +24,7 @@ import Presyntax.Presyntax (Plicity(..)) |
|
|
|
import Syntax |
|
|
|
|
|
|
|
import System.IO.Unsafe |
|
|
|
import Syntax.Pretty |
|
|
|
|
|
|
|
eval :: Term -> ElabM Value |
|
|
|
eval t = asks (flip evalWithEnv t) |
|
|
@ -61,7 +64,18 @@ zonkIO (VLam p (Closure s k)) = pure $ VLam p (Closure s (zonk . k)) |
|
|
|
zonkIO (VPi p d (Closure s k)) = VPi p <$> zonkIO d <*> pure (Closure s (zonk . k)) |
|
|
|
zonkIO (VSigma d (Closure s k)) = VSigma <$> zonkIO d <*> pure (Closure s (zonk . k)) |
|
|
|
zonkIO (VPair a b) = VPair <$> zonkIO a <*> zonkIO b |
|
|
|
|
|
|
|
-- Sorts |
|
|
|
zonkIO VType = pure VType |
|
|
|
zonkIO VTypeω = pure VTypeω |
|
|
|
|
|
|
|
zonkIO VI = pure VI |
|
|
|
zonkIO VI0 = pure VI0 |
|
|
|
zonkIO VI1 = pure VI1 |
|
|
|
|
|
|
|
zonkIO (VIAnd x y) = iand <$> zonkIO x <*> zonkIO y |
|
|
|
zonkIO (VIOr x y) = ior <$> zonkIO x <*> zonkIO y |
|
|
|
zonkIO (VINot x) = inot <$> zonkIO x |
|
|
|
|
|
|
|
zonk :: Value -> Value |
|
|
|
zonk = unsafePerformIO . zonkIO |
|
|
@ -93,6 +107,14 @@ evalWithEnv e (Proj1 a) = vProj1 (evalWithEnv e a) |
|
|
|
evalWithEnv e (Proj2 a) = vProj2 (evalWithEnv e a) |
|
|
|
|
|
|
|
evalWithEnv _ Type = VType |
|
|
|
evalWithEnv _ Typeω = VTypeω |
|
|
|
evalWithEnv _ I = VI |
|
|
|
evalWithEnv _ I0 = VI0 |
|
|
|
evalWithEnv _ I1 = VI1 |
|
|
|
|
|
|
|
evalWithEnv e (IAnd x y) = iand (evalWithEnv e x) (evalWithEnv e y) |
|
|
|
evalWithEnv e (IOr x y) = ior (evalWithEnv e x) (evalWithEnv e y) |
|
|
|
evalWithEnv e (INot x) = inot (evalWithEnv e x) |
|
|
|
|
|
|
|
vApp :: Plicity -> Value -> Value -> Value |
|
|
|
vApp p (VLam p' k) arg = assert (p == p') $ clCont k arg |
|
|
@ -112,58 +134,67 @@ vProj2 x = error $ "can't proj2 " ++ show x |
|
|
|
data NotEqual = NotEqual Value Value |
|
|
|
deriving (Show, Typeable, Exception) |
|
|
|
|
|
|
|
unify :: Value -> Value -> ElabM () |
|
|
|
unify topa topb = join $ go <$> forceIO topa <*> forceIO topb where |
|
|
|
unify' :: Value -> Value -> ElabM () |
|
|
|
unify' topa topb = join $ go <$> forceIO topa <*> forceIO topb where |
|
|
|
go (VNe (HMeta mv) sp) rhs = solveMeta mv sp rhs |
|
|
|
go rhs (VNe (HMeta mv) sp) = solveMeta mv sp rhs |
|
|
|
|
|
|
|
go (VNe x a) (VNe x' a') |
|
|
|
| x == x', length a == length a' = |
|
|
|
traverse_ (uncurry unifySpine) (zip a a') |
|
|
|
traverse_ (uncurry unify'Spine) (zip a a') |
|
|
|
| otherwise = fail |
|
|
|
|
|
|
|
go (VLam p (Closure _ k)) vl = do |
|
|
|
t <- VVar . Bound <$> newName |
|
|
|
unify (k t) (vApp p vl t) |
|
|
|
unify' (k t) (vApp p vl t) |
|
|
|
|
|
|
|
go vl (VLam p (Closure _ k)) = do |
|
|
|
t <- VVar . Bound <$> newName |
|
|
|
unify (vApp p vl t) (k t) |
|
|
|
unify' (vApp p vl t) (k t) |
|
|
|
|
|
|
|
go (VPair a b) vl = unify a (vProj1 vl) *> unify b (vProj2 vl) |
|
|
|
go vl (VPair a b) = unify (vProj1 vl) a *> unify (vProj2 vl) b |
|
|
|
go (VPair a b) vl = unify' a (vProj1 vl) *> unify' b (vProj2 vl) |
|
|
|
go vl (VPair a b) = unify' (vProj1 vl) a *> unify' (vProj2 vl) b |
|
|
|
|
|
|
|
go (VPi p d (Closure _ k)) (VPi p' d' (Closure _ k')) | p == p' = do |
|
|
|
t <- VVar . Bound <$> newName |
|
|
|
unify d d' |
|
|
|
unify (k t) (k' t) |
|
|
|
unify' d d' |
|
|
|
unify' (k t) (k' t) |
|
|
|
|
|
|
|
go (VSigma d (Closure _ k)) (VSigma d' (Closure _ k')) = do |
|
|
|
t <- VVar . Bound <$> newName |
|
|
|
unify d d' |
|
|
|
unify (k t) (k' t) |
|
|
|
unify' d d' |
|
|
|
unify' (k t) (k' t) |
|
|
|
|
|
|
|
go VType VType = pure () |
|
|
|
go VType VType = pure () |
|
|
|
go VTypeω VTypeω = pure () |
|
|
|
|
|
|
|
go VI VI = pure () |
|
|
|
go VI0 VI0 = pure () |
|
|
|
go VI1 VI1 = pure () |
|
|
|
|
|
|
|
go _ _ = fail |
|
|
|
|
|
|
|
fail = liftIO . throwIO $ NotEqual topa topb |
|
|
|
|
|
|
|
unifySpine (PApp a v) (PApp a' v') |
|
|
|
| a == a' = unify v v' |
|
|
|
unify'Spine (PApp a v) (PApp a' v') |
|
|
|
| a == a' = unify' v v' |
|
|
|
|
|
|
|
unify'Spine PProj1 PProj1 = pure () |
|
|
|
unify'Spine PProj2 PProj2 = pure () |
|
|
|
|
|
|
|
unifySpine PProj1 PProj1 = pure () |
|
|
|
unifySpine PProj2 PProj2 = pure () |
|
|
|
unify'Spine _ _ = fail |
|
|
|
|
|
|
|
unifySpine _ _ = fail |
|
|
|
unify :: Value -> Value -> ElabM () |
|
|
|
unify a b = unify' a b `catchElab` \(_ :: SomeException) -> liftIO $ throwIO (NotEqual a b) |
|
|
|
|
|
|
|
isConvertibleTo :: Value -> Value -> ElabM (Term -> Term) |
|
|
|
VPi Im d (Closure _v k) `isConvertibleTo` ty = do |
|
|
|
meta <- newMeta d |
|
|
|
cont <- k meta `isConvertibleTo` ty |
|
|
|
pure (\f -> cont (App Ex f (quote meta))) |
|
|
|
VType `isConvertibleTo` VTypeω = pure id |
|
|
|
isConvertibleTo a b = do |
|
|
|
unify a b |
|
|
|
unify' a b |
|
|
|
pure id |
|
|
|
|
|
|
|
newMeta :: Value -> ElabM Value |
|
|
@ -193,7 +224,7 @@ _nameCounter = unsafePerformIO $ newIORef 0 |
|
|
|
solveMeta :: MV -> [Projection] -> Value -> ElabM () |
|
|
|
solveMeta m@(MV _ cell) sp rhs = do |
|
|
|
env <- ask |
|
|
|
liftIO $ print (m, sp, rhs) |
|
|
|
liftIO $ putStrLn (showValue (VNe (HMeta m) sp) ++ " ≡? " ++ showValue rhs) |
|
|
|
names <- checkSpine Set.empty sp |
|
|
|
checkScope (Set.fromList (Bound <$> names)) rhs |
|
|
|
let tm = quote rhs |
|
|
@ -231,6 +262,15 @@ checkScope scope (VSigma d (Closure n k)) = do |
|
|
|
checkScope s (VPair a b) = traverse_ (checkScope s) [a, b] |
|
|
|
|
|
|
|
checkScope _ VType = pure () |
|
|
|
checkScope _ VTypeω = pure () |
|
|
|
|
|
|
|
checkScope _ VI = pure () |
|
|
|
checkScope _ VI0 = pure () |
|
|
|
checkScope _ VI1 = pure () |
|
|
|
|
|
|
|
checkScope s (VIAnd x y) = traverse_ (checkScope s) [x, y] |
|
|
|
checkScope s (VIOr x y) = traverse_ (checkScope s) [x, y] |
|
|
|
checkScope s (VINot x) = checkScope s x |
|
|
|
|
|
|
|
checkSpine :: Set Name -> [Projection] -> ElabM [T.Text] |
|
|
|
checkSpine scope (PApp Ex (VVar n@(Bound t)):xs) |
|
|
|