| 
						
						
						
					 | 
				
				 | 
				
					@ -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) | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
				
				 | 
				
					
  |