| 
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -7,8 +7,10 @@ import Control.Monad.Reader | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import Control.Exception | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import qualified Data.Map.Strict as Map | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import qualified Data.Sequence as Seq | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import qualified Data.Set as Set | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import qualified Data.Text as T | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import Data.Sequence (Seq) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import Data.Traversable | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import Data.Set (Set) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import Data.Typeable | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -16,31 +18,34 @@ import Data.Foldable | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import Data.IORef | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import Data.Maybe | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import {-# SOURCE #-} Elab.WiredIn | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import Elab.Monad | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import Presyntax.Presyntax (Plicity(..)) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import Syntax.Pretty | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import Syntax | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import System.IO.Unsafe | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import Syntax.Pretty | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import {-# SOURCE #-} Elab.WiredIn | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					import Prettyprinter | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					eval :: Term -> ElabM Value | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					eval t = asks (flip evalWithEnv t) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					eval t = asks (flip eval' t) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					forceIO :: MonadIO m => Value -> m Value | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					forceIO vl@(VNe (HMeta (MV _ cell)) args) = do | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  solved <- liftIO $ readIORef cell | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  case solved of | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    Just vl -> forceIO $ foldl applProj vl (reverse args) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    Just vl -> forceIO $ foldl applProj vl args | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    Nothing -> pure vl | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					forceIO x = pure x | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					applProj :: Value -> Projection -> Value | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					applProj fun (PApp p arg) = vApp p fun arg | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					applProj fun PProj1 = vProj1 fun | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					applProj fun PProj2 = vProj2 fun | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					applProj fun (PApp p arg)     = vApp p fun arg | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					applProj fun (PIElim l x y i) = ielim l x y fun i | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					applProj fun PProj1           = vProj1 fun | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					applProj fun PProj2           = vProj2 fun | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					force :: Value -> Value | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					force = unsafePerformIO . forceIO | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -53,11 +58,12 @@ zonkIO (VNe hd sp) = do | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    HMeta (MV _ cell) -> do | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      solved <- liftIO $ readIORef cell | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      case solved of | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        Just vl -> zonkIO $ foldl applProj vl (reverse sp') | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        Just vl -> zonkIO $ foldl applProj vl sp' | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        Nothing -> pure $ VNe hd sp' | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    hd -> pure $ VNe hd sp' | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  where | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    zonkSp (PApp p x) = PApp p <$> zonkIO x | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    zonkSp (PIElim l x y i) = PIElim <$> zonkIO l <*> zonkIO x <*> zonkIO y <*> zonkIO i | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    zonkSp PProj1 = pure PProj1 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    zonkSp PProj2 = pure PProj2 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					zonkIO (VLam p (Closure s k)) = pure $ VLam p (Closure s (zonk . k)) | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -65,6 +71,9 @@ zonkIO (VPi p d (Closure s k)) = VPi p <$> zonkIO d <*> pure (Closure s (zonk . | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					zonkIO (VSigma d (Closure s k)) = VSigma <$> zonkIO d <*> pure (Closure s (zonk . k)) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					zonkIO (VPair a b) = VPair <$> zonkIO a <*> zonkIO b | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					zonkIO (VPath line x y) = VPath <$> zonkIO line <*> zonkIO x <*> zonkIO y | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					zonkIO (VLine line f) = VLine <$> zonkIO line <*> zonkIO f | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					-- Sorts | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					zonkIO VType = pure VType | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					zonkIO VTypeω = pure VTypeω | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -80,55 +89,65 @@ zonkIO (VINot x) = inot <$> zonkIO x | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					zonk :: Value -> Value | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					zonk = unsafePerformIO . zonkIO | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					evalWithEnv :: ElabEnv -> Term -> Value | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					evalWithEnv env (Ref x) = | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					eval' :: ElabEnv -> Term -> Value | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					eval' env (Ref x) = | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  case Map.lookup x (getEnv env) of | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    Just (_, vl) -> vl | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    _ -> error "variable not in scope when evaluating" | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					evalWithEnv env (App p f x) = vApp p (evalWithEnv env f) (evalWithEnv env x) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					eval' env (App p f x) = vApp p (eval' env f) (eval' env x) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					evalWithEnv env (Lam p s t) = | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					eval' env (Lam p s t) = | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  VLam p $ Closure s $ \a -> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    evalWithEnv env { getEnv = Map.insert (Bound s) (error "type of abs", a) (getEnv env) } t | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    eval' env { getEnv = Map.insert (Bound s) (error "type of abs", a) (getEnv env) } t | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					eval' env (Pi p s d t) = | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  VPi p (eval' env d) $ Closure s $ \a -> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    eval' env { getEnv = (Map.insert (Bound s) (error "type of abs", a) (getEnv env))} t | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					evalWithEnv env (Pi p s d t) = | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  VPi p (evalWithEnv env d) $ Closure s $ \a -> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    evalWithEnv env { getEnv = (Map.insert (Bound s) (error "type of abs", a) (getEnv env))} t | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					eval' _ (Meta m) = VNe (HMeta m) mempty | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					evalWithEnv _ (Meta m) = VNe (HMeta m) [] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					eval' env (Sigma s d t) = | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  VSigma (eval' env d) $ Closure s $ \a -> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    eval' env { getEnv = Map.insert (Bound s) (error "type of abs", a) (getEnv env) } t | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					evalWithEnv env (Sigma s d t) = | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  VSigma (evalWithEnv env d) $ Closure s $ \a -> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    evalWithEnv env { getEnv = Map.insert (Bound s) (error "type of abs", a) (getEnv env) } t | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					eval' e (Pair a b) = VPair (eval' e a) (eval' e b) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					evalWithEnv e (Pair a b) = VPair (evalWithEnv e a) (evalWithEnv e b)  | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					eval' e (Proj1 a) = vProj1 (eval' e a) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					eval' e (Proj2 a) = vProj2 (eval' e a) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					evalWithEnv e (Proj1 a) = vProj1 (evalWithEnv e a) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					evalWithEnv e (Proj2 a) = vProj2 (evalWithEnv e a) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					eval' _ Type = VType | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					eval' _ Typeω = VTypeω | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					eval' _ I = VI | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					eval' _ I0 = VI0 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					eval' _ I1 = VI1 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					evalWithEnv _ Type = VType | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					evalWithEnv _ Typeω = VTypeω | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					evalWithEnv _ I = VI | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					evalWithEnv _ I0 = VI0 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					evalWithEnv _ I1 = VI1 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					eval' e (IAnd x y) = iand (eval' e x) (eval' e y) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					eval' e (IOr x y) = ior (eval' e x) (eval' e y) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					eval' e (INot x) = inot (eval' e x) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					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) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					eval' e (PathP l a b) = VPath (eval' e l) (eval' e a) (eval' e b) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					eval' e (IElim l x y f i) = ielim (eval' e l) (eval' e x) (eval' e y) (eval' e f) (eval' e i) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					eval' e (PathIntro p f) = VLine (eval' e p) (eval' e f) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					vApp :: Plicity -> Value -> Value -> Value | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					vApp p (VLam p' k) arg = assert (p == p') $ clCont k arg | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					vApp p (VNe h sp) arg  = VNe h (PApp p arg:sp) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					vApp p (VLam p' k) arg | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  | p == p'   = clCont k arg | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  | otherwise = error $ "wrong plicity " ++ show p ++ " vs " ++ show p' ++ " in app " ++ show (App p (quote (VLam p' k)) (quote arg)) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					vApp p (VNe h sp) arg  = VNe h (sp Seq.:|> PApp p arg) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					vApp _ x _             = error $ "can't apply " ++ show x | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					(@@) :: Value -> Value -> Value | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					(@@) = vApp Ex | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					infixl 9 @@ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					vProj1 :: Value -> Value | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					vProj1 (VPair a _) = a | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					vProj1 (VNe h sp) = VNe h (PProj1:sp) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					vProj1 (VNe h sp) = VNe h (sp Seq.:|> PProj1) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					vProj1 x = error $ "can't proj1 " ++ show x | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					vProj2 :: Value -> Value | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					vProj2 (VPair _ b) = b | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					vProj2 (VNe h sp)  = VNe h (PProj2:sp) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					vProj2 (VNe h sp)  = VNe h (sp Seq.:|> PProj2) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					vProj2 x = error $ "can't proj2 " ++ show x | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					data NotEqual = NotEqual Value Value | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -141,8 +160,13 @@ unify' topa topb = join $ go <$> forceIO topa <*> forceIO topb where | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  go (VNe x a) (VNe x' a') | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    | x == x', length a == length a' = | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      traverse_ (uncurry unify'Spine) (zip a a') | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    | otherwise = fail | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      traverse_ (uncurry unify'Spine) (Seq.zip a a') | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					   | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  go (VNe _hd (_ Seq.:|> PIElim _l x y i)) rhs = | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    case force i of | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      VI0 -> unify' x rhs | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      VI1 -> unify' y rhs | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      _   -> fail | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  go (VLam p (Closure _ k)) vl = do | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    t <- VVar . Bound <$> newName | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -171,6 +195,23 @@ unify' topa topb = join $ go <$> forceIO topa <*> forceIO topb where | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  go VI VI   = pure () | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  go VI0 VI0 = pure () | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  go VI1 VI1 = pure () | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					   | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  go (VINot x)   (VINot y)     = unify' x y | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  go (VIAnd x y) (VIAnd x' y') = unify' x x' *> unify' y y' | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  go (VIOr x y)  (VIOr x' y')  = unify' x x' *> unify' y y' | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  go (VPath l x y) (VPath l' x' y') = do | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    unify' l l' | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    unify' x x' | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    unify' y y' | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					   | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  go (VLine l p) p' = do | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    n <- VVar . Bound <$> newName | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    unify (p @@ n) (ielim l (l @@ VI0) (l @@ VI1) p' n) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  go p' (VLine l p) = do | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    n <- VVar . Bound <$> newName | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    unify (ielim l (l @@ VI0) (l @@ VI1) p' n) (p @@ n) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  go _ _ = fail | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -182,6 +223,8 @@ unify' topa topb = join $ go <$> forceIO topa <*> forceIO topb where | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  unify'Spine PProj1 PProj1 = pure () | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  unify'Spine PProj2 PProj2 = pure () | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  unify'Spine (PIElim _ _ _ i) (PIElim _ _ _ j) = unify' i j | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  unify'Spine _ _ = fail | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					unify :: Value -> Value -> ElabM () | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -191,8 +234,17 @@ 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))) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  pure (\f -> cont (App Im f (quote meta))) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					VType `isConvertibleTo` VTypeω = pure id | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					VPi p d (Closure _ k) `isConvertibleTo` VPi p' d' (Closure _ k') | p == p' = do | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  wp <- d' `isConvertibleTo` d | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  n <- newName | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  wp_n <- eval (Lam Ex n (wp (Ref (Bound n)))) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  wp' <- k (VVar (Bound n)) `isConvertibleTo` k' (wp_n @@ VVar (Bound n)) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  pure (\f -> Lam p n (wp' (App p f (wp (Ref (Bound n)))))) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					isConvertibleTo a b = do | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  unify' a b | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  pure id | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -210,7 +262,7 @@ newMeta _dom = do | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      Bound{} -> Just (PApp Ex (VVar n)) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      _ -> Nothing | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  pure (VNe (HMeta m) (catMaybes t)) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  pure (VNe (HMeta m) (Seq.fromList (catMaybes t))) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					newName :: MonadIO m => m T.Text | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					newName = liftIO $ do | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -221,14 +273,14 @@ _nameCounter :: IORef Int | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					_nameCounter = unsafePerformIO $ newIORef 0 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{-# NOINLINE _nameCounter #-} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					solveMeta :: MV -> [Projection] -> Value -> ElabM () | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					solveMeta :: MV -> Seq Projection -> Value -> ElabM () | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					solveMeta m@(MV _ cell) sp rhs = do | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  env <- ask | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  liftIO $ putStrLn (showValue (VNe (HMeta m) sp) ++ " ≡? " ++ showValue rhs) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  names <- checkSpine Set.empty sp | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  checkScope (Set.fromList (Bound <$> names)) rhs | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    `withNote` hsep [prettyTm (quote (VNe (HMeta m) sp)), pretty '≡', prettyTm (quote rhs)] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  let tm = quote rhs | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      lam = evalWithEnv env $ foldr (Lam Ex) tm names | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      lam = eval' env $ foldr (Lam Ex) tm names | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  liftIO . atomicModifyIORef' cell $ \case | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    Just _ -> error "filled cell in solvedMeta" | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    Nothing -> (Just lam, ()) | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -245,6 +297,7 @@ checkScope scope (VNe h sp) = | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    traverse_ checkProj sp | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  where | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    checkProj (PApp _ t) = checkScope scope t | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    checkProj (PIElim l x y i) = traverse_ (checkScope scope) [l, x, y, i] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    checkProj PProj1 = pure () | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    checkProj PProj2 = pure () | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -272,12 +325,15 @@ 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) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					checkScope s (VPath line a b) = traverse_ (checkScope s) [line, a, b] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					checkScope s (VLine _ line) = checkScope s line | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					checkSpine :: Set Name -> Seq Projection -> ElabM [T.Text] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					checkSpine scope (PApp Ex (VVar n@(Bound t)) Seq.:<| xs) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  | n `Set.member` scope = liftIO . throwIO $ NonLinearSpine n | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  | otherwise = (t:) <$> checkSpine scope xs | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					checkSpine _     (p:_) = liftIO . throwIO $ SpineProj p | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					checkSpine _     [] = pure [] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					checkSpine _     (p Seq.:<| _) = liftIO . throwIO $ SpineProj p | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					checkSpine _     Seq.Empty = pure [] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					newtype NonLinearSpine = NonLinearSpine { getDupeName :: Name } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  deriving (Show, Typeable, Exception) | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
				
				 | 
				
					
  |