module Agda.TypeChecking.Monad.SizedTypes where import Control.Monad.Error import Agda.Interaction.Options import Agda.Syntax.Common import Agda.Syntax.Internal import Agda.TypeChecking.Monad.Base import Agda.TypeChecking.Monad.Options import Agda.TypeChecking.Monad.Builtin import Agda.TypeChecking.Substitute import Agda.Utils.Monad -- | Check if a type is the 'primSize' type. The argument should be 'reduce'd. isSizeType :: MonadTCM tcm => Type -> tcm Bool isSizeType (El _ v) = liftTCM $ ifM (not . optSizedTypes <$> commandLineOptions) (return False) $ case v of Def x [] -> do Def size [] <- primSize return $ x == size _ -> return False `catchError` \_ -> return False sizeType :: MonadTCM tcm => tcm Type sizeType = El (Type 0) <$> primSize sizeSuc :: MonadTCM tcm => tcm (Maybe QName) sizeSuc = liftTCM $ ifM (not . optSizedTypes <$> commandLineOptions) (return Nothing) $ do Def x [] <- primSizeSuc return $ Just x `catchError` \_ -> return Nothing -- | A useful view on sizes. data SizeView = SizeInf | SizeSuc Term | OtherSize Term -- | Compute the size view of a term. The argument should be 'reduce'd. -- Precondition: sized types are enabled. sizeView :: MonadTCM tcm => Term -> tcm SizeView sizeView v = do Def inf [] <- primSizeInf Def suc [] <- primSizeSuc case v of Def x [] | x == inf -> return SizeInf Def x [u] | x == suc -> return $ SizeSuc (unArg u) _ -> return $ OtherSize v -- | Turn a size view into a term. unSizeView :: MonadTCM tcm => SizeView -> tcm Term unSizeView SizeInf = primSizeInf unSizeView (SizeSuc v) = flip apply [Arg NotHidden v] <$> primSizeSuc unSizeView (OtherSize v) = return v