{-# LANGUAGE NondecreasingIndentation #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
module Agda.TypeChecking.Rewriting where
import Prelude hiding (null)
import Control.Monad.Trans.Maybe ( MaybeT(..), runMaybeT )
import Data.Either (partitionEithers)
import Data.Foldable (toList)
import qualified Data.List as List
import Data.Set (Set)
import qualified Data.Set as Set
import Agda.Interaction.Options
import Agda.Syntax.Abstract.Name
import Agda.Syntax.Common
import Agda.Syntax.Internal as I
import Agda.Syntax.Internal.MetaVars
import Agda.Syntax.Internal.Pattern
import Agda.TypeChecking.Datatypes
import Agda.TypeChecking.Monad
import Agda.TypeChecking.Free
import Agda.TypeChecking.Conversion
import qualified Agda.TypeChecking.Positivity.Occurrence as Pos
import Agda.TypeChecking.Pretty
import Agda.TypeChecking.Reduce
import Agda.TypeChecking.Substitute
import Agda.TypeChecking.Telescope
import Agda.TypeChecking.Rewriting.Confluence
import Agda.TypeChecking.Rewriting.NonLinMatch
import Agda.TypeChecking.Rewriting.NonLinPattern
import Agda.TypeChecking.Warnings
import Agda.Utils.Functor
import Agda.Utils.List
import Agda.Utils.Maybe
import Agda.Utils.Monad
import Agda.Utils.Null
import qualified Agda.Utils.Set1 as Set1
import Agda.Utils.Size
import qualified Agda.Utils.SmallSet as SmallSet
import qualified Agda.Utils.VarSet as VarSet
import Agda.Utils.VarSet (VarSet)
import Agda.Utils.Impossible
import Agda.Utils.Either
import Agda.Utils.List1 (nonEmpty)
requireOptionRewriting :: TCM ()
requireOptionRewriting :: TCM ()
requireOptionRewriting =
TCMT IO Bool -> TCM () -> TCM ()
forall (m :: * -> *). Monad m => m Bool -> m () -> m ()
unlessM (PragmaOptions -> Bool
optRewriting (PragmaOptions -> Bool) -> TCMT IO PragmaOptions -> TCMT IO Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TCMT IO PragmaOptions
forall (m :: * -> *). HasOptions m => m PragmaOptions
pragmaOptions) (TCM () -> TCM ()) -> TCM () -> TCM ()
forall a b. (a -> b) -> a -> b
$ TypeError -> TCM ()
forall (m :: * -> *) a.
(HasCallStack, MonadTCError m) =>
TypeError -> m a
typeError TypeError
NeedOptionRewriting
verifyBuiltinRewrite :: Term -> Type -> TCM ()
verifyBuiltinRewrite :: Term -> Type -> TCM ()
verifyBuiltinRewrite Term
v Type
t = do
TCMT IO (Maybe RelView) -> TCM () -> (RelView -> TCM ()) -> TCM ()
forall (m :: * -> *) a b.
Monad m =>
m (Maybe a) -> m b -> (a -> m b) -> m b
caseMaybeM (Type -> TCMT IO (Maybe RelView)
relView Type
t)
(TypeError -> TCM ()
forall (m :: * -> *) a.
(HasCallStack, MonadTCError m) =>
TypeError -> m a
typeError (TypeError -> TCM ()) -> TypeError -> TCM ()
forall a b. (a -> b) -> a -> b
$ Term -> IncorrectTypeForRewriteRelationReason -> TypeError
IncorrectTypeForRewriteRelation Term
v IncorrectTypeForRewriteRelationReason
ShouldAcceptAtLeastTwoArguments) ((RelView -> TCM ()) -> TCM ()) -> (RelView -> TCM ()) -> TCM ()
forall a b. (a -> b) -> a -> b
$
\ (RelView Tele (Dom' Term Type)
tel [Dom (ArgName, Type)]
delta Dom' Term Type
a Dom' Term Type
b Type
core) -> do
Bool -> TCM () -> TCM ()
forall b (m :: * -> *). (IsBool b, Monad m) => b -> m () -> m ()
unless (Dom' Term Type -> Bool
forall a. LensHiding a => a -> Bool
visible Dom' Term Type
a Bool -> Bool -> Bool
&& Dom' Term Type -> Bool
forall a. LensHiding a => a -> Bool
visible Dom' Term Type
b) (TCM () -> TCM ()) -> TCM () -> TCM ()
forall a b. (a -> b) -> a -> b
$ TypeError -> TCM ()
forall (m :: * -> *) a.
(HasCallStack, MonadTCError m) =>
TypeError -> m a
typeError (TypeError -> TCM ()) -> TypeError -> TCM ()
forall a b. (a -> b) -> a -> b
$ Term -> IncorrectTypeForRewriteRelationReason -> TypeError
IncorrectTypeForRewriteRelation Term
v IncorrectTypeForRewriteRelationReason
FinalTwoArgumentsNotVisible
case Type -> Term
forall t a. Type'' t a -> a
unEl Type
core of
Sort{} -> () -> TCM ()
forall a. a -> TCMT IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
Con{} -> TCM ()
forall a. HasCallStack => a
__IMPOSSIBLE__
Level{} -> TCM ()
forall a. HasCallStack => a
__IMPOSSIBLE__
Lam{} -> TCM ()
forall a. HasCallStack => a
__IMPOSSIBLE__
Pi{} -> TCM ()
forall a. HasCallStack => a
__IMPOSSIBLE__
Term
_ -> TypeError -> TCM ()
forall (m :: * -> *) a.
(HasCallStack, MonadTCError m) =>
TypeError -> m a
typeError (TypeError -> TCM ()) -> TypeError -> TCM ()
forall a b. (a -> b) -> a -> b
$ Term -> IncorrectTypeForRewriteRelationReason -> TypeError
IncorrectTypeForRewriteRelation Term
v (Type
-> Tele (Dom' Term Type) -> IncorrectTypeForRewriteRelationReason
TypeDoesNotEndInSort Type
core Tele (Dom' Term Type)
tel)
data RelView = RelView
{ RelView -> Tele (Dom' Term Type)
relViewTel :: Telescope
, RelView -> [Dom (ArgName, Type)]
relViewDelta :: ListTel
, RelView -> Dom' Term Type
relViewType :: Dom Type
, RelView -> Dom' Term Type
relViewType' :: Dom Type
, RelView -> Type
relViewCore :: Type
}
relView :: Type -> TCM (Maybe RelView)
relView :: Type -> TCMT IO (Maybe RelView)
relView Type
t = do
TelV tel core <- Type -> TCMT IO (TelV Type)
forall (m :: * -> *).
(MonadReduce m, MonadAddContext m) =>
Type -> m (TelV Type)
telView Type
t
let n = Tele (Dom' Term Type) -> Int
forall a. Sized a => a -> Int
size Tele (Dom' Term Type)
tel
(delta, lastTwo) = splitAt (n - 2) $ telToList tel
if size lastTwo < 2 then return Nothing else do
let [a, b] = fmap snd <$> lastTwo
return $ Just $ RelView tel delta a b core
addRewriteRules :: [QName] -> TCM ()
addRewriteRules :: [QName] -> TCM ()
addRewriteRules [QName]
qs = do
rews <- (QName -> TCMT IO (Maybe GlobalRewriteRule))
-> [QName] -> TCMT IO [GlobalRewriteRule]
forall (m :: * -> *) a b.
Monad m =>
(a -> m (Maybe b)) -> [a] -> m [b]
mapMaybeM QName -> TCMT IO (Maybe GlobalRewriteRule)
checkRewriteRule [QName]
qs
forM_ rews $ \GlobalRewriteRule
rew -> do
let f :: QName
f = GlobalRewriteRule -> QName
grHead GlobalRewriteRule
rew
matchables :: [QName]
matchables = GlobalRewriteRule -> [QName]
forall a. GetMatchables a => a -> [QName]
getMatchables GlobalRewriteRule
rew
ArgName -> Int -> TCMT IO Doc -> TCM ()
forall (m :: * -> *).
MonadDebug m =>
ArgName -> Int -> TCMT IO Doc -> m ()
reportSDoc ArgName
"rewriting" Int
10 (TCMT IO Doc -> TCM ()) -> TCMT IO Doc -> TCM ()
forall a b. (a -> b) -> a -> b
$
TCMT IO Doc
"adding rule" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> QName -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => QName -> m Doc
prettyTCM (GlobalRewriteRule -> QName
grName GlobalRewriteRule
rew) TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+>
TCMT IO Doc
"to the definition of" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> QName -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => QName -> m Doc
prettyTCM QName
f
ArgName -> Int -> TCMT IO Doc -> TCM ()
forall (m :: * -> *).
MonadDebug m =>
ArgName -> Int -> TCMT IO Doc -> m ()
reportSDoc ArgName
"rewriting" Int
30 (TCMT IO Doc -> TCM ()) -> TCMT IO Doc -> TCM ()
forall a b. (a -> b) -> a -> b
$ TCMT IO Doc
"matchable symbols: " TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> [QName] -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => [QName] -> m Doc
prettyTCM [QName]
matchables
QName -> [GlobalRewriteRule] -> [QName] -> TCM ()
addRewriteRulesFor QName
f [GlobalRewriteRule
rew] [QName]
matchables
whenJustM (optConfluenceCheck <$> pragmaOptions) $ \ConfluenceCheck
confChk -> do
TCMT IO (Maybe Cubical) -> (Cubical -> TCM ()) -> TCM ()
forall (m :: * -> *) a.
Monad m =>
m (Maybe a) -> (a -> m ()) -> m ()
whenJustM TCMT IO (Maybe Cubical)
forall (m :: * -> *). HasOptions m => m (Maybe Cubical)
cubicalOption ((Cubical -> TCM ()) -> TCM ()) -> (Cubical -> TCM ()) -> TCM ()
forall a b. (a -> b) -> a -> b
$ \Cubical
_ -> Warning -> TCM ()
forall (m :: * -> *).
(HasCallStack, MonadWarning m) =>
Warning -> m ()
warning Warning
ConfluenceForCubicalNotSupported
Bool -> TCM () -> TCM ()
forall b (m :: * -> *). (IsBool b, Monad m) => b -> m () -> m ()
when (ConfluenceCheck
confChk ConfluenceCheck -> ConfluenceCheck -> Bool
forall a. Eq a => a -> a -> Bool
== ConfluenceCheck
GlobalConfluenceCheck) (TCM () -> TCM ()) -> TCM () -> TCM ()
forall a b. (a -> b) -> a -> b
$
[QName] -> (QName -> TCM ()) -> TCM ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ ((QName -> QName) -> [QName] -> [QName]
forall b a. Ord b => (a -> b) -> [a] -> [a]
nubOn QName -> QName
forall a. a -> a
id ([QName] -> [QName]) -> [QName] -> [QName]
forall a b. (a -> b) -> a -> b
$ (GlobalRewriteRule -> QName) -> [GlobalRewriteRule] -> [QName]
forall a b. (a -> b) -> [a] -> [b]
map GlobalRewriteRule -> QName
grHead [GlobalRewriteRule]
rews) QName -> TCM ()
sortRulesOfSymbol
ConfluenceCheck -> [GlobalRewriteRule] -> TCM ()
checkConfluenceOfRules ConfluenceCheck
confChk [GlobalRewriteRule]
rews
ArgName -> Int -> TCMT IO Doc -> TCM ()
forall (m :: * -> *).
MonadDebug m =>
ArgName -> Int -> TCMT IO Doc -> m ()
reportSDoc ArgName
"rewriting" Int
10 (TCMT IO Doc -> TCM ()) -> TCMT IO Doc -> TCM ()
forall a b. (a -> b) -> a -> b
$
TCMT IO Doc
"done checking confluence of rules" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+>
[TCMT IO Doc] -> TCMT IO Doc
forall (m :: * -> *) (t :: * -> *).
(Applicative m, Semigroup (m Doc), Foldable t) =>
t (m Doc) -> m Doc
prettyList_ ((GlobalRewriteRule -> TCMT IO Doc)
-> [GlobalRewriteRule] -> [TCMT IO Doc]
forall a b. (a -> b) -> [a] -> [b]
map (QName -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => QName -> m Doc
prettyTCM (QName -> TCMT IO Doc)
-> (GlobalRewriteRule -> QName) -> GlobalRewriteRule -> TCMT IO Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GlobalRewriteRule -> QName
grName) [GlobalRewriteRule]
rews)
rewriteRelationDom :: QName -> TCM (ListTel, Dom Type)
rewriteRelationDom :: QName -> TCM ([Dom (ArgName, Type)], Dom' Term Type)
rewriteRelationDom QName
rel = do
relV <- Type -> TCMT IO (Maybe RelView)
relView (Type -> TCMT IO (Maybe RelView))
-> TCMT IO Type -> TCMT IO (Maybe RelView)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< do Definition -> Type
defType (Definition -> Type) -> TCMT IO Definition -> TCMT IO Type
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> QName -> TCMT IO Definition
forall (m :: * -> *).
(HasConstInfo m, HasCallStack) =>
QName -> m Definition
getConstInfo QName
rel
let RelView _tel delta a _a' _core = fromMaybe __IMPOSSIBLE__ relV
reportSDoc "rewriting" 30 $ do
"rewrite relation at type " <+> do
inTopContext $ prettyTCM (telFromList delta) <+> " |- " <+> do
addContext delta $ prettyTCM a
return (delta, a)
checkEquationValid ::
RewriteSource -> RewriteAnn -> Type -> TCM (Maybe LocalEquation)
checkEquationValid :: RewriteSource -> RewriteAnn -> Type -> TCM (Maybe LocalEquation)
checkEquationValid RewriteSource
s RewriteAnn
rewAnn Type
t
| RewriteAnn -> Bool
forall a. LensRewriteAnn a => a -> Bool
isRewrite RewriteAnn
rewAnn = MaybeT (TCMT IO) LocalEquation -> TCM (Maybe LocalEquation)
forall (m :: * -> *) a. MaybeT m a -> m (Maybe a)
runMaybeT (MaybeT (TCMT IO) LocalEquation -> TCM (Maybe LocalEquation))
-> MaybeT (TCMT IO) LocalEquation -> TCM (Maybe LocalEquation)
forall a b. (a -> b) -> a -> b
$ RewriteSource -> Type -> MaybeT (TCMT IO) LocalEquation
checkIsRewriteRelation RewriteSource
s Type
t
| Bool
otherwise = Maybe LocalEquation -> TCM (Maybe LocalEquation)
forall a. a -> TCMT IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe LocalEquation
forall a. Maybe a
Nothing
checkIsRewriteRelation ::
RewriteSource -> Type -> MaybeT TCM LocalEquation
checkIsRewriteRelation :: RewriteSource -> Type -> MaybeT (TCMT IO) LocalEquation
checkIsRewriteRelation RewriteSource
q Type
t = do
rels <- TCM (Set QName) -> MaybeT (TCMT IO) (Set QName)
forall (m :: * -> *) a. Monad m => m a -> MaybeT m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift TCM (Set QName)
forall (m :: * -> *).
(HasBuiltins m, MonadTCError m) =>
m (Set QName)
getBuiltinRewriteRelations
reportSDoc "rewriting.relations" 40 $ vcat
[ "Rewrite relations:"
, prettyList $ map prettyTCM $ toList rels
]
TelV gamma1 core <- telView $ t
reportSDoc "rewriting" 30 $ vcat
[ "attempting to add rewrite rule of type "
, prettyTCM gamma1
, " |- " <+> do addContext gamma1 $ prettyTCM core
]
case unEl core of
Def QName
rel es :: Elims
es@(Elim' Term
_:Elim' Term
_:Elims
_) | QName
rel QName -> Set QName -> Bool
forall a. Eq a => a -> Set a -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` Set QName
rels -> do
(delta, a) <- TCM ([Dom (ArgName, Type)], Dom' Term Type)
-> MaybeT (TCMT IO) ([Dom (ArgName, Type)], Dom' Term Type)
forall (m :: * -> *) a. Monad m => m a -> MaybeT m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (TCM ([Dom (ArgName, Type)], Dom' Term Type)
-> MaybeT (TCMT IO) ([Dom (ArgName, Type)], Dom' Term Type))
-> TCM ([Dom (ArgName, Type)], Dom' Term Type)
-> MaybeT (TCMT IO) ([Dom (ArgName, Type)], Dom' Term Type)
forall a b. (a -> b) -> a -> b
$ QName -> TCM ([Dom (ArgName, Type)], Dom' Term Type)
rewriteRelationDom QName
rel
let vs = (Arg Term -> Term) -> [Arg Term] -> [Term]
forall a b. (a -> b) -> [a] -> [b]
map Arg Term -> Term
forall e. Arg e -> e
unArg ([Arg Term] -> [Term]) -> [Arg Term] -> [Term]
forall a b. (a -> b) -> a -> b
$ [Arg Term] -> Maybe [Arg Term] -> [Arg Term]
forall a. a -> Maybe a -> a
fromMaybe [Arg Term]
forall a. HasCallStack => a
__IMPOSSIBLE__ (Maybe [Arg Term] -> [Arg Term]) -> Maybe [Arg Term] -> [Arg Term]
forall a b. (a -> b) -> a -> b
$ Elims -> Maybe [Arg Term]
forall a. [Elim' a] -> Maybe [Arg a]
allApplyElims Elims
es
n = [Term] -> Int
forall a. Sized a => a -> Int
size [Term]
vs
(us, [lhs, rhs]) = splitAt (n - 2) vs
unless (size delta == size us) __IMPOSSIBLE__
lhs <- instantiateFull lhs
rhs <- instantiateFull rhs
b <- instantiateFull $ applySubst (parallelS $ reverse us) a
gamma1 <- instantiateFull gamma1
pure $ LocalEquation gamma1 lhs rhs (unDom b)
Term
_ -> RewriteSource
-> IllegalRewriteRuleReason -> MaybeT (TCMT IO) LocalEquation
forall (m :: * -> *) a.
MonadWarning m =>
RewriteSource -> IllegalRewriteRuleReason -> MaybeT m a
illegalRule RewriteSource
q IllegalRewriteRuleReason
DoesNotTargetRewriteRelation
checkRewriteRule :: QName -> TCM (Maybe GlobalRewriteRule)
checkRewriteRule :: QName -> TCMT IO (Maybe GlobalRewriteRule)
checkRewriteRule QName
q = MaybeT (TCMT IO) GlobalRewriteRule
-> TCMT IO (Maybe GlobalRewriteRule)
forall (m :: * -> *) a. MaybeT m a -> m (Maybe a)
runMaybeT (MaybeT (TCMT IO) GlobalRewriteRule
-> TCMT IO (Maybe GlobalRewriteRule))
-> MaybeT (TCMT IO) GlobalRewriteRule
-> TCMT IO (Maybe GlobalRewriteRule)
forall a b. (a -> b) -> a -> b
$ QName
-> MaybeT (TCMT IO) GlobalRewriteRule
-> MaybeT (TCMT IO) GlobalRewriteRule
forall (m :: * -> *) x a.
(MonadTrace m, HasRange x) =>
x -> m a -> m a
setCurrentRange QName
q do
TCM () -> MaybeT (TCMT IO) ()
forall (m :: * -> *) a. Monad m => m a -> MaybeT m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift TCM ()
requireOptionRewriting
rels <- TCM (Set QName) -> MaybeT (TCMT IO) (Set QName)
forall (m :: * -> *) a. Monad m => m a -> MaybeT m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift TCM (Set QName)
forall (m :: * -> *).
(HasBuiltins m, MonadTCError m) =>
m (Set QName)
getBuiltinRewriteRelations
reportSDoc "rewriting.relations" 40 $ vcat
[ "Rewrite relations:"
, prettyList $ map prettyTCM $ toList rels
]
def <- instantiateDef =<< getConstInfo q
when (isEmptyFunction $ theDef def) $
illegalRule (GlobalRewrite def) BeforeFunctionDefinition
whenJustM (viewTC eMutualBlock) \ MutualId
mb -> do
qs <- MutualBlock -> Set QName
mutualNames (MutualBlock -> Set QName)
-> MaybeT (TCMT IO) MutualBlock -> MaybeT (TCMT IO) (Set QName)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MutualId -> MaybeT (TCMT IO) MutualBlock
forall (tcm :: * -> *).
ReadTCState tcm =>
MutualId -> tcm MutualBlock
lookupMutualBlock MutualId
mb
when (Set.member q qs) $ forM_ qs $ \QName
r -> do
MaybeT (TCMT IO) Bool -> MaybeT (TCMT IO) () -> MaybeT (TCMT IO) ()
forall (m :: * -> *). Monad m => m Bool -> m () -> m ()
whenM (Defn -> Bool
isEmptyFunction (Defn -> Bool) -> (Definition -> Defn) -> Definition -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Definition -> Defn
theDef (Definition -> Bool)
-> MaybeT (TCMT IO) Definition -> MaybeT (TCMT IO) Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> QName -> MaybeT (TCMT IO) Definition
forall (m :: * -> *).
(HasConstInfo m, HasCallStack) =>
QName -> m Definition
getConstInfo QName
r) (MaybeT (TCMT IO) () -> MaybeT (TCMT IO) ())
-> MaybeT (TCMT IO) () -> MaybeT (TCMT IO) ()
forall a b. (a -> b) -> a -> b
$
RewriteSource -> IllegalRewriteRuleReason -> MaybeT (TCMT IO) ()
forall (m :: * -> *) a.
MonadWarning m =>
RewriteSource -> IllegalRewriteRuleReason -> MaybeT m a
illegalRule (Definition -> RewriteSource
GlobalRewrite Definition
def) (IllegalRewriteRuleReason -> MaybeT (TCMT IO) ())
-> IllegalRewriteRuleReason -> MaybeT (TCMT IO) ()
forall a b. (a -> b) -> a -> b
$ QName -> IllegalRewriteRuleReason
BeforeMutualFunctionDefinition QName
r
eq <- checkIsRewriteRelation (GlobalRewrite def) (defType def)
RewriteRule g h ps rhs b <- checkRewriteRule' eq (GlobalRewrite def)
f <- case h of
RewDefHead QName
f -> QName -> MaybeT (TCMT IO) QName
forall a. a -> MaybeT (TCMT IO) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure QName
f
RewVarHead Int
x -> RewriteSource -> IllegalRewriteRuleReason -> MaybeT (TCMT IO) QName
forall (m :: * -> *) a.
MonadWarning m =>
RewriteSource -> IllegalRewriteRuleReason -> MaybeT m a
illegalRule (Definition -> RewriteSource
GlobalRewrite Definition
def) IllegalRewriteRuleReason
LHSNotDefinitionOrConstructor
top <- fromMaybe __IMPOSSIBLE__ <$> currentTopLevelModule
pure $ GlobalRewriteRule q g f ps rhs b False top
checkLocalRewriteRule ::
RewriteSource -> LocalEquation -> TCM (Maybe RewriteRule)
checkLocalRewriteRule :: RewriteSource -> LocalEquation -> TCM (Maybe RewriteRule)
checkLocalRewriteRule RewriteSource
s LocalEquation
eq = MaybeT (TCMT IO) RewriteRule -> TCM (Maybe RewriteRule)
forall (m :: * -> *) a. MaybeT m a -> m (Maybe a)
runMaybeT (MaybeT (TCMT IO) RewriteRule -> TCM (Maybe RewriteRule))
-> MaybeT (TCMT IO) RewriteRule -> TCM (Maybe RewriteRule)
forall a b. (a -> b) -> a -> b
$
Set MetaId
-> MaybeT (TCMT IO) RewriteRule
-> (Set1 MetaId -> MaybeT (TCMT IO) RewriteRule)
-> MaybeT (TCMT IO) RewriteRule
forall a b. Set a -> b -> (Set1 a -> b) -> b
Set1.ifNull ((MetaId -> Set MetaId) -> LocalEquation -> Set MetaId
forall m. Monoid m => (MetaId -> m) -> LocalEquation -> m
forall t m. (AllMetas t, Monoid m) => (MetaId -> m) -> t -> m
allMetas MetaId -> Set MetaId
forall a. a -> Set a
Set.singleton LocalEquation
eq)
(LocalEquation -> RewriteSource -> MaybeT (TCMT IO) RewriteRule
checkRewriteRule' LocalEquation
eq RewriteSource
s)
(RewriteSource
-> IllegalRewriteRuleReason -> MaybeT (TCMT IO) RewriteRule
forall (m :: * -> *) a.
MonadWarning m =>
RewriteSource -> IllegalRewriteRuleReason -> MaybeT m a
illegalRule RewriteSource
s (IllegalRewriteRuleReason -> MaybeT (TCMT IO) RewriteRule)
-> (Set1 MetaId -> IllegalRewriteRuleReason)
-> Set1 MetaId
-> MaybeT (TCMT IO) RewriteRule
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Set1 MetaId -> IllegalRewriteRuleReason
ContainsUnsolvedMetaVariables)
checkRewriteRule' :: LocalEquation -> RewriteSource -> MaybeT TCM RewriteRule
checkRewriteRule' :: LocalEquation -> RewriteSource -> MaybeT (TCMT IO) RewriteRule
checkRewriteRule' eq :: LocalEquation
eq@(LocalEquation Tele (Dom' Term Type)
gamma1 Term
lhs Term
rhs Type
b) RewriteSource
s = do
ArgName -> Int -> TCMT IO Doc -> MaybeT (TCMT IO) ()
forall (m :: * -> *).
MonadDebug m =>
ArgName -> Int -> TCMT IO Doc -> m ()
reportSDoc ArgName
"rewriting" Int
30 (TCMT IO Doc -> MaybeT (TCMT IO) ())
-> TCMT IO Doc -> MaybeT (TCMT IO) ()
forall a b. (a -> b) -> a -> b
$
TCMT IO Doc
"Checking rewrite rule: " TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> LocalEquation -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => LocalEquation -> m Doc
prettyTCM LocalEquation
eq
let failureBlocked :: Blocker -> MaybeT TCM a
failureBlocked :: forall a. Blocker -> MaybeT (TCMT IO) a
failureBlocked Blocker
b
| Set1.IsNonEmpty Set1 MetaId
ms <- Blocker -> Set MetaId
allBlockingMetas Blocker
b = RewriteSource -> IllegalRewriteRuleReason -> MaybeT (TCMT IO) a
forall (m :: * -> *) a.
MonadWarning m =>
RewriteSource -> IllegalRewriteRuleReason -> MaybeT m a
illegalRule RewriteSource
s (IllegalRewriteRuleReason -> MaybeT (TCMT IO) a)
-> IllegalRewriteRuleReason -> MaybeT (TCMT IO) a
forall a b. (a -> b) -> a -> b
$ Set1 MetaId -> IllegalRewriteRuleReason
ContainsUnsolvedMetaVariables Set1 MetaId
ms
| Set1.IsNonEmpty NESet ProblemId
ps <- Blocker -> Set ProblemId
allBlockingProblems Blocker
b = RewriteSource -> IllegalRewriteRuleReason -> MaybeT (TCMT IO) a
forall (m :: * -> *) a.
MonadWarning m =>
RewriteSource -> IllegalRewriteRuleReason -> MaybeT m a
illegalRule RewriteSource
s (IllegalRewriteRuleReason -> MaybeT (TCMT IO) a)
-> IllegalRewriteRuleReason -> MaybeT (TCMT IO) a
forall a b. (a -> b) -> a -> b
$ NESet ProblemId -> IllegalRewriteRuleReason
BlockedOnProblems NESet ProblemId
ps
| Set1.IsNonEmpty NESet QName
qs <- Blocker -> Set QName
allBlockingDefs Blocker
b = RewriteSource -> IllegalRewriteRuleReason -> MaybeT (TCMT IO) a
forall (m :: * -> *) a.
MonadWarning m =>
RewriteSource -> IllegalRewriteRuleReason -> MaybeT m a
illegalRule RewriteSource
s (IllegalRewriteRuleReason -> MaybeT (TCMT IO) a)
-> IllegalRewriteRuleReason -> MaybeT (TCMT IO) a
forall a b. (a -> b) -> a -> b
$ NESet QName -> IllegalRewriteRuleReason
RequiresDefinitions NESet QName
qs
| Bool
otherwise = MaybeT (TCMT IO) a
forall a. HasCallStack => a
__IMPOSSIBLE__
let failureFreeVars :: VarSet -> MaybeT TCM a
failureFreeVars :: forall a. VarSet -> MaybeT (TCMT IO) a
failureFreeVars VarSet
xs = RewriteSource -> IllegalRewriteRuleReason -> MaybeT (TCMT IO) a
forall (m :: * -> *) a.
MonadWarning m =>
RewriteSource -> IllegalRewriteRuleReason -> MaybeT m a
illegalRule RewriteSource
s (IllegalRewriteRuleReason -> MaybeT (TCMT IO) a)
-> IllegalRewriteRuleReason -> MaybeT (TCMT IO) a
forall a b. (a -> b) -> a -> b
$ VarSet -> IllegalRewriteRuleReason
VariablesNotBoundByLHS VarSet
xs
let warnUnsafeVars :: VarSet -> MaybeT TCM ()
warnUnsafeVars :: VarSet -> MaybeT (TCMT IO) ()
warnUnsafeVars VarSet
xs = RewriteSource -> IllegalRewriteRuleReason -> MaybeT (TCMT IO) ()
forall (m :: * -> *).
MonadWarning m =>
RewriteSource -> IllegalRewriteRuleReason -> MaybeT m ()
unsafeRule RewriteSource
s (IllegalRewriteRuleReason -> MaybeT (TCMT IO) ())
-> IllegalRewriteRuleReason -> MaybeT (TCMT IO) ()
forall a b. (a -> b) -> a -> b
$ VarSet -> IllegalRewriteRuleReason
VariablesBoundInSingleton VarSet
xs
let failureNonLinearPars :: VarSet -> MaybeT TCM a
failureNonLinearPars :: forall a. VarSet -> MaybeT (TCMT IO) a
failureNonLinearPars VarSet
xs = RewriteSource -> IllegalRewriteRuleReason -> MaybeT (TCMT IO) a
forall (m :: * -> *) a.
MonadWarning m =>
RewriteSource -> IllegalRewriteRuleReason -> MaybeT m a
illegalRule RewriteSource
s (IllegalRewriteRuleReason -> MaybeT (TCMT IO) a)
-> IllegalRewriteRuleReason -> MaybeT (TCMT IO) a
forall a b. (a -> b) -> a -> b
$ VarSet -> IllegalRewriteRuleReason
VariablesBoundMoreThanOnce VarSet
xs
gamma0 <- MaybeT (TCMT IO) (Tele (Dom' Term Type))
forall (m :: * -> *). MonadTCEnv m => m (Tele (Dom' Term Type))
getContextTelescope
let gamma = Tele (Dom' Term Type)
gamma0 Tele (Dom' Term Type)
-> Tele (Dom' Term Type) -> Tele (Dom' Term Type)
forall t. Abstract t => Tele (Dom' Term Type) -> t -> t
`abstract` Tele (Dom' Term Type)
gamma1
reportSDoc "rewriting" 40 $
"Full context: " <+> prettyTCM gamma
lhs <- modifyAllowedReductions (const $ SmallSet.singleton InlineReductions) $ reduce lhs
(f , hd , t , pars , es) <- case lhs of
Def QName
f Elims
es -> do
def <- QName -> MaybeT (TCMT IO) Definition
forall (m :: * -> *).
(HasConstInfo m, HasCallStack) =>
QName -> m Definition
getConstInfo QName
f
checkAxFunOrCon f def
return (RewDefHead f , Def f , defType def , [] , es)
Con ConHead
c ConInfo
ci Elims
vs -> do
let hd :: Elims -> Term
hd = ConHead -> ConInfo -> Elims -> Term
Con ConHead
c ConInfo
ci
~(Just ((_ , _ , pars) , t)) <- ConHead
-> Type
-> MaybeT (TCMT IO) (Maybe ((QName, Type, [Arg Term]), Type))
forall (m :: * -> *).
PureTCM m =>
ConHead -> Type -> m (Maybe ((QName, Type, [Arg Term]), Type))
getFullyAppliedConType ConHead
c Type
b
pars <- addContext gamma1 $ checkParametersAreGeneral c pars
return (RewDefHead $ conName c , hd , t , pars , vs)
Var Int
x Elims
es | RewriteSource -> Bool
isLocalRewrite RewriteSource
s -> do
t <- Tele (Dom' Term Type)
-> MaybeT (TCMT IO) Type -> MaybeT (TCMT IO) Type
forall b (m :: * -> *) a.
(AddContext b, MonadAddContext m) =>
b -> m a -> m a
forall (m :: * -> *) a.
MonadAddContext m =>
Tele (Dom' Term Type) -> m a -> m a
addContext Tele (Dom' Term Type)
gamma1 (MaybeT (TCMT IO) Type -> MaybeT (TCMT IO) Type)
-> MaybeT (TCMT IO) Type -> MaybeT (TCMT IO) Type
forall a b. (a -> b) -> a -> b
$ Int -> MaybeT (TCMT IO) Type
forall (m :: * -> *). (MonadDebug m, MonadTCEnv m) => Int -> m Type
typeOfBV Int
x
return (RewVarHead (x - size gamma1), Var x , t , [] , es)
Term
_ -> do
ArgName -> Int -> TCMT IO Doc -> MaybeT (TCMT IO) ()
forall (m :: * -> *).
MonadDebug m =>
ArgName -> Int -> TCMT IO Doc -> m ()
reportSDoc ArgName
"rewriting.rule.check" Int
30 (TCMT IO Doc -> MaybeT (TCMT IO) ())
-> TCMT IO Doc -> MaybeT (TCMT IO) ()
forall a b. (a -> b) -> a -> b
$ [TCMT IO Doc] -> TCMT IO Doc
forall (m :: * -> *) (t :: * -> *).
(Applicative m, Foldable t) =>
t (m Doc) -> m Doc
hsep
[ TCMT IO Doc
"LHSNotDefinitionOrConstructor: ", Term -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => Term -> m Doc
prettyTCM Term
lhs ]
RewriteSource
-> IllegalRewriteRuleReason
-> MaybeT
(TCMT IO) (RewriteHead, Elims -> Term, Type, [Int], Elims)
forall (m :: * -> *) a.
MonadWarning m =>
RewriteSource -> IllegalRewriteRuleReason -> MaybeT m a
illegalRule RewriteSource
s IllegalRewriteRuleReason
LHSNotDefinitionOrConstructor
ifNotAlreadyAdded s f $ do
let rewGamma = if RewriteSource -> Bool
isLocalRewrite RewriteSource
s then Tele (Dom' Term Type)
gamma1 else Tele (Dom' Term Type)
gamma
telStart = Tele (Dom' Term Type) -> Int
forall a. Sized a => a -> Int
size Tele (Dom' Term Type)
rewGamma
addContext gamma1 $ do
checkNoLhsReduction telStart f hd es
ps <- fromRightM failureBlocked $ lift $
catchPatternErr (pure . Left) $
Right <$> patternFrom
NeverSing NeverSing telStart 0 (t , headToTerm telStart f) es
reportSDoc "rewriting" 30 $
"Pattern generated from lhs: " <+> prettyTCM (headToPat telStart f ps)
let PatVars neverSingPatVars maybeSingPatVars = nlPatVars ps
boundVars = VarSet
neverSingPatVars VarSet -> VarSet -> VarSet
forall a. Semigroup a => a -> a -> a
<> VarSet
maybeSingPatVars
telVars = Int -> VarSet
VarSet.full Int
telStart
freeVarsLhs = VarSet
telVars VarSet -> VarSet -> VarSet
`VarSet.intersection` Term -> VarSet
forall t. Free t => t -> VarSet
freeVarSet Term
lhs
freeVarsRhs = VarSet
telVars VarSet -> VarSet -> VarSet
`VarSet.intersection` Term -> VarSet
forall t. Free t => t -> VarSet
freeVarSet Term
rhs
freeVars = VarSet
freeVarsLhs VarSet -> VarSet -> VarSet
forall a. Semigroup a => a -> a -> a
<> VarSet
freeVarsRhs
usedVars = case RewriteSource
s of
LocalRewrite Context
_ Maybe Name
_ Type
_ -> VarSet
VarSet.empty
GlobalRewrite Definition
def -> case Definition -> Defn
theDef Definition
def of
Function{} -> Definition -> VarSet
usedArgs Definition
def
Axiom{} -> VarSet
telVars
AbstractDefn{} -> VarSet
telVars
Constructor{} -> VarSet
telVars
Primitive{} -> VarSet
telVars
DataOrRecSig{} -> VarSet
forall a. HasCallStack => a
__IMPOSSIBLE__
GeneralizableVar{} -> VarSet
forall a. HasCallStack => a
__IMPOSSIBLE__
Datatype{} -> VarSet
forall a. HasCallStack => a
__IMPOSSIBLE__
Record{} -> VarSet
forall a. HasCallStack => a
__IMPOSSIBLE__
PrimitiveSort{} -> VarSet
forall a. HasCallStack => a
__IMPOSSIBLE__
reportSDoc "rewriting" 70 $
"variables bound by pattern never singularly: " <+>
text (show neverSingPatVars)
reportSDoc "rewriting" 70 $
"variables bound by the pattern: " <+> text (show boundVars)
reportSDoc "rewriting" 70 $
"variables free in the lhs: " <+> text (show freeVarsLhs)
reportSDoc "rewriting" 70 $
"variables free in the rhs: " <+> text (show freeVarsRhs)
reportSDoc "rewriting" 70 $
"variables used by the rewrite rule: " <+> text (show usedVars)
unlessNull (freeVars VarSet.\\ boundVars) failureFreeVars
unlessNull (usedVars VarSet.\\ (boundVars `VarSet.union` VarSet.fromList pars)) failureFreeVars
reportSDoc "rewriting" 70 $
"variables bound in (erased) parameter position: " <+> text (show pars)
unlessNull (boundVars `VarSet.intersection` VarSet.fromList pars) failureNonLinearPars
unlessNull (freeVarsRhs VarSet.\\ neverSingPatVars) warnUnsafeVars
top <- fromMaybe __IMPOSSIBLE__ <$> currentTopLevelModule
let rew = Tele (Dom' Term Type)
-> RewriteHead -> PElims -> Term -> Type -> RewriteRule
RewriteRule Tele (Dom' Term Type)
rewGamma RewriteHead
f PElims
ps Term
rhs Type
b
reportSDoc "rewriting" 10 $ vcat
[ "checked rewrite rule" , prettyTCM rew ]
reportSDoc "rewriting" 90 $ vcat
[ "checked rewrite rule" , text (show rew) ]
return rew
where
ifNotAlreadyAdded ::
RewriteSource -> RewriteHead -> MaybeT TCM RewriteRule
-> MaybeT TCM RewriteRule
ifNotAlreadyAdded :: RewriteSource
-> RewriteHead
-> MaybeT (TCMT IO) RewriteRule
-> MaybeT (TCMT IO) RewriteRule
ifNotAlreadyAdded (GlobalRewrite Definition
def) (RewDefHead QName
f) MaybeT (TCMT IO) RewriteRule
cont = do
rews <- QName -> MaybeT (TCMT IO) [GlobalRewriteRule]
forall (m :: * -> *).
HasConstInfo m =>
QName -> m [GlobalRewriteRule]
getGlobalRewriteRulesFor QName
f
case List.find ((defName def ==) . grName) rews of
Just GlobalRewriteRule
rew -> RewriteSource
-> IllegalRewriteRuleReason -> MaybeT (TCMT IO) RewriteRule
forall (m :: * -> *) a.
MonadWarning m =>
RewriteSource -> IllegalRewriteRuleReason -> MaybeT m a
illegalRule (Definition -> RewriteSource
GlobalRewrite Definition
def) IllegalRewriteRuleReason
DuplicateRewriteRule
Maybe GlobalRewriteRule
Nothing -> MaybeT (TCMT IO) RewriteRule
cont
ifNotAlreadyAdded (GlobalRewrite Definition
def) (RewVarHead Int
x) MaybeT (TCMT IO) RewriteRule
cont = MaybeT (TCMT IO) RewriteRule
forall a. HasCallStack => a
__IMPOSSIBLE__
ifNotAlreadyAdded (LocalRewrite Context
_ Maybe Name
_ Type
_) RewriteHead
f MaybeT (TCMT IO) RewriteRule
cont = MaybeT (TCMT IO) RewriteRule
cont
checkNoLhsReduction ::
Nat -> RewriteHead -> (Elims -> Term) -> Elims
-> MaybeT TCM ()
checkNoLhsReduction :: Int
-> RewriteHead -> (Elims -> Term) -> Elims -> MaybeT (TCMT IO) ()
checkNoLhsReduction Int
telStart RewriteHead
f Elims -> Term
hd Elims
es = do
MaybeT (TCMT IO) Bool -> MaybeT (TCMT IO) () -> MaybeT (TCMT IO) ()
forall (m :: * -> *). Monad m => m Bool -> m () -> m ()
unlessM ((Maybe ConfluenceCheck -> Maybe ConfluenceCheck -> Bool
forall a. Eq a => a -> a -> Bool
== ConfluenceCheck -> Maybe ConfluenceCheck
forall a. a -> Maybe a
Just ConfluenceCheck
GlobalConfluenceCheck) (Maybe ConfluenceCheck -> Bool)
-> (PragmaOptions -> Maybe ConfluenceCheck)
-> PragmaOptions
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PragmaOptions -> Maybe ConfluenceCheck
optConfluenceCheck (PragmaOptions -> Bool)
-> MaybeT (TCMT IO) PragmaOptions -> MaybeT (TCMT IO) Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MaybeT (TCMT IO) PragmaOptions
forall (m :: * -> *). HasOptions m => m PragmaOptions
pragmaOptions) (MaybeT (TCMT IO) () -> MaybeT (TCMT IO) ())
-> MaybeT (TCMT IO) () -> MaybeT (TCMT IO) ()
forall a b. (a -> b) -> a -> b
$ do
let v :: Term
v = Elims -> Term
hd Elims
es
v' <- Term -> MaybeT (TCMT IO) Term
forall a (m :: * -> *). (Reduce a, MonadReduce m) => a -> m a
reduce Term
v
let fail :: MaybeT TCM a
fail = do
ArgName -> Int -> TCMT IO Doc -> MaybeT (TCMT IO) ()
forall (m :: * -> *).
MonadDebug m =>
ArgName -> Int -> TCMT IO Doc -> m ()
reportSDoc ArgName
"rewriting" Int
20 (TCMT IO Doc -> MaybeT (TCMT IO) ())
-> TCMT IO Doc -> MaybeT (TCMT IO) ()
forall a b. (a -> b) -> a -> b
$ TCMT IO Doc
"v = " TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> ArgName -> TCMT IO Doc
forall (m :: * -> *). Applicative m => ArgName -> m Doc
text (Term -> ArgName
forall a. Show a => a -> ArgName
show Term
v)
ArgName -> Int -> TCMT IO Doc -> MaybeT (TCMT IO) ()
forall (m :: * -> *).
MonadDebug m =>
ArgName -> Int -> TCMT IO Doc -> m ()
reportSDoc ArgName
"rewriting" Int
20 (TCMT IO Doc -> MaybeT (TCMT IO) ())
-> TCMT IO Doc -> MaybeT (TCMT IO) ()
forall a b. (a -> b) -> a -> b
$ TCMT IO Doc
"v' = " TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> ArgName -> TCMT IO Doc
forall (m :: * -> *). Applicative m => ArgName -> m Doc
text (Term -> ArgName
forall a. Show a => a -> ArgName
show Term
v')
RewriteSource -> IllegalRewriteRuleReason -> MaybeT (TCMT IO) a
forall (m :: * -> *) a.
MonadWarning m =>
RewriteSource -> IllegalRewriteRuleReason -> MaybeT m a
illegalRule RewriteSource
s (IllegalRewriteRuleReason -> MaybeT (TCMT IO) a)
-> IllegalRewriteRuleReason -> MaybeT (TCMT IO) a
forall a b. (a -> b) -> a -> b
$ Term -> Term -> IllegalRewriteRuleReason
LHSReduces Term
v Term
v'
es' <- case (f, v') of
(RewDefHead QName
f, Def QName
f' Elims
es') | QName
f QName -> QName -> Bool
forall a. Eq a => a -> a -> Bool
== QName
f' -> Elims -> MaybeT (TCMT IO) Elims
forall a. a -> MaybeT (TCMT IO) a
forall (m :: * -> *) a. Monad m => a -> m a
return Elims
es'
(RewDefHead QName
f, Con ConHead
c' ConInfo
_ Elims
es') | QName
f QName -> QName -> Bool
forall a. Eq a => a -> a -> Bool
== ConHead -> QName
conName ConHead
c' -> Elims -> MaybeT (TCMT IO) Elims
forall a. a -> MaybeT (TCMT IO) a
forall (m :: * -> *) a. Monad m => a -> m a
return Elims
es'
(RewVarHead Int
x, Var Int
x' Elims
es') | Int
x Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
telStart Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
x' -> Elims -> MaybeT (TCMT IO) Elims
forall a. a -> MaybeT (TCMT IO) a
forall (m :: * -> *) a. Monad m => a -> m a
return Elims
es'
(RewriteHead, Term)
_ -> MaybeT (TCMT IO) Elims
forall a. MaybeT (TCMT IO) a
fail
unless (null es && null es') $ do
a <- lift $ computeRewHeadType telStart f es es'
pol <- case f of
RewDefHead QName
f -> Comparison -> QName -> MaybeT (TCMT IO) [Polarity]
forall (m :: * -> *).
(HasCallStack, HasConstInfo m) =>
Comparison -> QName -> m [Polarity]
getPolarity' Comparison
CmpEq QName
f
RewVarHead Int
x -> [Polarity] -> MaybeT (TCMT IO) [Polarity]
forall a. a -> MaybeT (TCMT IO) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
ok <- lift $ dontAssignMetas $ tryConversion $
compareElims pol [] a (headToTerm telStart f []) es es'
unless ok fail
checkAxFunOrCon :: QName -> Definition -> MaybeT TCM ()
checkAxFunOrCon :: QName -> Definition -> MaybeT (TCMT IO) ()
checkAxFunOrCon QName
f Definition
def = case Definition -> Defn
theDef Definition
def of
Axiom{} -> () -> MaybeT (TCMT IO) ()
forall a. a -> MaybeT (TCMT IO) a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
def :: Defn
def@Function{} -> do
Maybe Projection
-> (Projection -> MaybeT (TCMT IO) ()) -> MaybeT (TCMT IO) ()
forall (m :: * -> *) a. Monad m => Maybe a -> (a -> m ()) -> m ()
whenJust (Either ProjectionLikenessMissing Projection -> Maybe Projection
forall a b. Either a b -> Maybe b
maybeRight (Defn -> Either ProjectionLikenessMissing Projection
funProjection Defn
def)) ((Projection -> MaybeT (TCMT IO) ()) -> MaybeT (TCMT IO) ())
-> (Projection -> MaybeT (TCMT IO) ()) -> MaybeT (TCMT IO) ()
forall a b. (a -> b) -> a -> b
$ \Projection
proj -> case Projection -> Maybe QName
projProper Projection
proj of
Maybe QName
Nothing -> RewriteSource -> IllegalRewriteRuleReason -> MaybeT (TCMT IO) ()
forall (m :: * -> *) a.
MonadWarning m =>
RewriteSource -> IllegalRewriteRuleReason -> MaybeT m a
illegalRule RewriteSource
s (IllegalRewriteRuleReason -> MaybeT (TCMT IO) ())
-> IllegalRewriteRuleReason -> MaybeT (TCMT IO) ()
forall a b. (a -> b) -> a -> b
$ QName -> IllegalRewriteRuleReason
HeadSymbolIsProjectionLikeFunction QName
f
Just{} -> MaybeT (TCMT IO) ()
forall a. HasCallStack => a
__IMPOSSIBLE__
MaybeT (TCMT IO) Bool -> MaybeT (TCMT IO) () -> MaybeT (TCMT IO) ()
forall (m :: * -> *). Monad m => m Bool -> m () -> m ()
whenM (Maybe ConfluenceCheck -> Bool
forall a. Maybe a -> Bool
isJust (Maybe ConfluenceCheck -> Bool)
-> (PragmaOptions -> Maybe ConfluenceCheck)
-> PragmaOptions
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PragmaOptions -> Maybe ConfluenceCheck
optConfluenceCheck (PragmaOptions -> Bool)
-> MaybeT (TCMT IO) PragmaOptions -> MaybeT (TCMT IO) Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MaybeT (TCMT IO) PragmaOptions
forall (m :: * -> *). HasOptions m => m PragmaOptions
pragmaOptions) (MaybeT (TCMT IO) () -> MaybeT (TCMT IO) ())
-> MaybeT (TCMT IO) () -> MaybeT (TCMT IO) ()
forall a b. (a -> b) -> a -> b
$ do
let simpleClause :: Clause -> (Elims, Maybe Term)
simpleClause Clause
cl = ([NamedArg DeBruijnPattern] -> Elims
patternsToElims (Clause -> [NamedArg DeBruijnPattern]
namedClausePats Clause
cl) , Clause -> Maybe Term
clauseBody Clause
cl)
cls <- [(Elims, Maybe Term)] -> MaybeT (TCMT IO) [(Elims, Maybe Term)]
forall a (m :: * -> *).
(InstantiateFull a, MonadReduce m) =>
a -> m a
instantiateFull ([(Elims, Maybe Term)] -> MaybeT (TCMT IO) [(Elims, Maybe Term)])
-> [(Elims, Maybe Term)] -> MaybeT (TCMT IO) [(Elims, Maybe Term)]
forall a b. (a -> b) -> a -> b
$ (Clause -> (Elims, Maybe Term))
-> [Clause] -> [(Elims, Maybe Term)]
forall a b. (a -> b) -> [a] -> [b]
map Clause -> (Elims, Maybe Term)
simpleClause ([Clause] -> [(Elims, Maybe Term)])
-> [Clause] -> [(Elims, Maybe Term)]
forall a b. (a -> b) -> a -> b
$ Defn -> [Clause]
funClauses Defn
def
unless (noMetas cls) $ illegalRule s $ HeadSymbolContainsMetas f
Constructor{} -> () -> MaybeT (TCMT IO) ()
forall a. a -> MaybeT (TCMT IO) a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
AbstractDefn{} -> () -> MaybeT (TCMT IO) ()
forall a. a -> MaybeT (TCMT IO) a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
Primitive{} -> () -> MaybeT (TCMT IO) ()
forall a. a -> MaybeT (TCMT IO) a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
Datatype{} -> MaybeT (TCMT IO) ()
illegalHead
Record{} -> MaybeT (TCMT IO) ()
illegalHead
DatatypeDefn{} -> MaybeT (TCMT IO) ()
illegalHead
RecordDefn{} -> MaybeT (TCMT IO) ()
illegalHead
DataOrRecSig{} -> MaybeT (TCMT IO) ()
illegalHead
PrimitiveSort{}-> MaybeT (TCMT IO) ()
illegalHead
GeneralizableVar{} -> MaybeT (TCMT IO) ()
forall a. HasCallStack => a
__IMPOSSIBLE__
where
illegalHead :: MaybeT (TCMT IO) ()
illegalHead = RewriteSource -> IllegalRewriteRuleReason -> MaybeT (TCMT IO) ()
forall (m :: * -> *) a.
MonadWarning m =>
RewriteSource -> IllegalRewriteRuleReason -> MaybeT m a
illegalRule RewriteSource
s (IllegalRewriteRuleReason -> MaybeT (TCMT IO) ())
-> IllegalRewriteRuleReason -> MaybeT (TCMT IO) ()
forall a b. (a -> b) -> a -> b
$ QName -> IllegalRewriteRuleReason
HeadSymbolIsTypeConstructor QName
f
usedArgs :: Definition -> VarSet
usedArgs :: Definition -> VarSet
usedArgs Definition
def = [Int] -> VarSet
VarSet.fromList ([Int] -> VarSet) -> [Int] -> VarSet
forall a b. (a -> b) -> a -> b
$ ((Occurrence, Int) -> Int) -> [(Occurrence, Int)] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map (Occurrence, Int) -> Int
forall a b. (a, b) -> b
snd ([(Occurrence, Int)] -> [Int]) -> [(Occurrence, Int)] -> [Int]
forall a b. (a -> b) -> a -> b
$ [(Occurrence, Int)]
usedIxs
where
occs :: [Occurrence]
occs = Definition -> [Occurrence]
defArgOccurrences Definition
def
allIxs :: [(Occurrence, Int)]
allIxs = [Occurrence] -> [Int] -> [(Occurrence, Int)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Occurrence]
occs ([Int] -> [(Occurrence, Int)]) -> [Int] -> [(Occurrence, Int)]
forall a b. (a -> b) -> a -> b
$ Int -> [Int]
forall a. Integral a => a -> [a]
downFrom (Int -> [Int]) -> Int -> [Int]
forall a b. (a -> b) -> a -> b
$ [Occurrence] -> Int
forall a. Sized a => a -> Int
size [Occurrence]
occs
usedIxs :: [(Occurrence, Int)]
usedIxs = ((Occurrence, Int) -> Bool)
-> [(Occurrence, Int)] -> [(Occurrence, Int)]
forall a. (a -> Bool) -> [a] -> [a]
filter (Occurrence -> Bool
used (Occurrence -> Bool)
-> ((Occurrence, Int) -> Occurrence) -> (Occurrence, Int) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Occurrence, Int) -> Occurrence
forall a b. (a, b) -> a
fst) [(Occurrence, Int)]
allIxs
used :: Occurrence -> Bool
used Occurrence
Pos.Unused = Bool
False
used Occurrence
_ = Bool
True
checkParametersAreGeneral :: ConHead -> Args -> MaybeT TCM [Int]
checkParametersAreGeneral :: ConHead -> [Arg Term] -> MaybeT (TCMT IO) [Int]
checkParametersAreGeneral ConHead
c [Arg Term]
vs = do
is <- [Arg Term] -> MaybeT (TCMT IO) [Int]
loop [Arg Term]
vs
unless (fastDistinct is) $ errorNotGeneral
return is
where
loop :: [Arg Term] -> MaybeT (TCMT IO) [Int]
loop [] = [Int] -> MaybeT (TCMT IO) [Int]
forall a. a -> MaybeT (TCMT IO) a
forall (m :: * -> *) a. Monad m => a -> m a
return []
loop (Arg Term
v : [Arg Term]
vs) = case Arg Term -> Term
forall e. Arg e -> e
unArg Arg Term
v of
Var Int
i [] -> (Int
i Int -> [Int] -> [Int]
forall a. a -> [a] -> [a]
:) ([Int] -> [Int])
-> MaybeT (TCMT IO) [Int] -> MaybeT (TCMT IO) [Int]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Arg Term] -> MaybeT (TCMT IO) [Int]
loop [Arg Term]
vs
Term
_ -> MaybeT (TCMT IO) [Int]
forall a. MaybeT (TCMT IO) a
errorNotGeneral
errorNotGeneral :: MaybeT TCM a
errorNotGeneral :: forall a. MaybeT (TCMT IO) a
errorNotGeneral = RewriteSource -> IllegalRewriteRuleReason -> MaybeT (TCMT IO) a
forall (m :: * -> *) a.
MonadWarning m =>
RewriteSource -> IllegalRewriteRuleReason -> MaybeT m a
illegalRule RewriteSource
s (IllegalRewriteRuleReason -> MaybeT (TCMT IO) a)
-> IllegalRewriteRuleReason -> MaybeT (TCMT IO) a
forall a b. (a -> b) -> a -> b
$ ConHead -> Args1 -> IllegalRewriteRuleReason
ConstructorParametersNotGeneral ConHead
c (Args1 -> IllegalRewriteRuleReason)
-> Args1 -> IllegalRewriteRuleReason
forall a b. (a -> b) -> a -> b
$
Args1 -> Maybe Args1 -> Args1
forall a. a -> Maybe a -> a
fromMaybe Args1
forall a. HasCallStack => a
__IMPOSSIBLE__ (Maybe Args1 -> Args1) -> Maybe Args1 -> Args1
forall a b. (a -> b) -> a -> b
$ [Arg Term] -> Maybe Args1
forall a. [a] -> Maybe (NonEmpty a)
nonEmpty [Arg Term]
vs
checkRewConstraint :: LocalEquation -> TCM ()
checkRewConstraint :: LocalEquation -> TCM ()
checkRewConstraint
eq :: LocalEquation
eq@(LocalEquation {lEqContext :: forall t. LocalEquation' t -> Tele (Dom' t (Type'' t t))
lEqContext = Tele (Dom' Term Type)
g, lEqLHS :: forall t. LocalEquation' t -> t
lEqLHS = Term
l, lEqRHS :: forall t. LocalEquation' t -> t
lEqRHS = Term
r, lEqType :: forall t. LocalEquation' t -> Type'' t t
lEqType = Type
t}) = do
c <- Lens' TCEnv (Maybe (Closure Call))
-> TCMT IO (Maybe (Closure Call))
forall (m :: * -> *) a. MonadTCEnv m => Lens' TCEnv a -> m a
viewTC (Maybe (Closure Call) -> f (Maybe (Closure Call)))
-> TCEnv -> f TCEnv
Lens' TCEnv (Maybe (Closure Call))
eCall
traceCall (CheckLocalRewriteConstraint eq c) $ addContext g $ equalTerm t l r
rewriteWith :: Type
-> (Elims -> Term)
-> RewriteRule
-> Elims
-> ReduceM (Either (Blocked Term) Term)
rewriteWith :: Type
-> (Elims -> Term)
-> RewriteRule
-> Elims
-> ReduceM (Either (Blocked Term) Term)
rewriteWith Type
t Elims -> Term
hd rew :: RewriteRule
rew@(RewriteRule Tele (Dom' Term Type)
gamma RewriteHead
_ PElims
ps Term
rhs Type
b) Elims
es = do
ArgName
-> Int
-> TCMT IO Doc
-> ReduceM (Either (Blocked Term) Term)
-> ReduceM (Either (Blocked Term) Term)
forall (m :: * -> *) a.
MonadDebug m =>
ArgName -> Int -> TCMT IO Doc -> m a -> m a
traceSDoc ArgName
"rewriting.rewrite" Int
50 ([TCMT IO Doc] -> TCMT IO Doc
forall (m :: * -> *) (t :: * -> *).
(Applicative m, Foldable t) =>
t (m Doc) -> m Doc
sep
[ TCMT IO Doc
"{ attempting to rewrite term " TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> Term -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => Term -> m Doc
prettyTCM (Elims -> Term
hd Elims
es)
, TCMT IO Doc
" having head " TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> Term -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => Term -> m Doc
prettyTCM (Elims -> Term
hd []) TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> TCMT IO Doc
" of type " TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> Type -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => Type -> m Doc
prettyTCM Type
t
, TCMT IO Doc
" with rule " TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> RewriteRule -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => RewriteRule -> m Doc
prettyTCM RewriteRule
rew
]) (ReduceM (Either (Blocked Term) Term)
-> ReduceM (Either (Blocked Term) Term))
-> ReduceM (Either (Blocked Term) Term)
-> ReduceM (Either (Blocked Term) Term)
forall a b. (a -> b) -> a -> b
$ do
ArgName
-> Int
-> TCMT IO Doc
-> ReduceM (Either (Blocked Term) Term)
-> ReduceM (Either (Blocked Term) Term)
forall (m :: * -> *) a.
MonadDebug m =>
ArgName -> Int -> TCMT IO Doc -> m a -> m a
traceSDoc ArgName
"rewriting.rewrite" Int
90 ([TCMT IO Doc] -> TCMT IO Doc
forall (m :: * -> *) (t :: * -> *).
(Applicative m, Foldable t) =>
t (m Doc) -> m Doc
sep
[ TCMT IO Doc
"raw: attempting to rewrite term " TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> (ArgName -> TCMT IO Doc
forall (m :: * -> *). Applicative m => ArgName -> m Doc
text (ArgName -> TCMT IO Doc)
-> (Term -> ArgName) -> Term -> TCMT IO Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Term -> ArgName
forall a. Show a => a -> ArgName
show) (Elims -> Term
hd Elims
es)
, TCMT IO Doc
" having head " TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> (ArgName -> TCMT IO Doc
forall (m :: * -> *). Applicative m => ArgName -> m Doc
text (ArgName -> TCMT IO Doc)
-> (Term -> ArgName) -> Term -> TCMT IO Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Term -> ArgName
forall a. Show a => a -> ArgName
show) (Elims -> Term
hd []) TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> TCMT IO Doc
" of type " TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> (ArgName -> TCMT IO Doc
forall (m :: * -> *). Applicative m => ArgName -> m Doc
text (ArgName -> TCMT IO Doc)
-> (Type -> ArgName) -> Type -> TCMT IO Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Type -> ArgName
forall a. Show a => a -> ArgName
show) Type
t
, TCMT IO Doc
" with rule " TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> (ArgName -> TCMT IO Doc
forall (m :: * -> *). Applicative m => ArgName -> m Doc
text (ArgName -> TCMT IO Doc)
-> (RewriteRule -> ArgName) -> RewriteRule -> TCMT IO Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RewriteRule -> ArgName
forall a. Show a => a -> ArgName
show) RewriteRule
rew
]) (ReduceM (Either (Blocked Term) Term)
-> ReduceM (Either (Blocked Term) Term))
-> ReduceM (Either (Blocked Term) Term)
-> ReduceM (Either (Blocked Term) Term)
forall a b. (a -> b) -> a -> b
$ do
result <- Tele (Dom' Term Type)
-> TypeOf Elims
-> PElims
-> Elims
-> ReduceM (Either Blocked_ Substitution)
forall (m :: * -> *) a b.
(PureTCM m, Match a b) =>
Tele (Dom' Term Type)
-> TypeOf b -> a -> b -> m (Either Blocked_ Substitution)
nonLinMatch Tele (Dom' Term Type)
gamma (Type
t,Elims -> Term
hd) PElims
ps Elims
es
case result of
Left Blocked_
block -> ArgName
-> Int
-> TCMT IO Doc
-> ReduceM (Either (Blocked Term) Term)
-> ReduceM (Either (Blocked Term) Term)
forall (m :: * -> *) a.
MonadDebug m =>
ArgName -> Int -> TCMT IO Doc -> m a -> m a
traceSDoc ArgName
"rewriting.rewrite" Int
50 TCMT IO Doc
"}" (ReduceM (Either (Blocked Term) Term)
-> ReduceM (Either (Blocked Term) Term))
-> ReduceM (Either (Blocked Term) Term)
-> ReduceM (Either (Blocked Term) Term)
forall a b. (a -> b) -> a -> b
$
Either (Blocked Term) Term -> ReduceM (Either (Blocked Term) Term)
forall a. a -> ReduceM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either (Blocked Term) Term
-> ReduceM (Either (Blocked Term) Term))
-> Either (Blocked Term) Term
-> ReduceM (Either (Blocked Term) Term)
forall a b. (a -> b) -> a -> b
$ Blocked Term -> Either (Blocked Term) Term
forall a b. a -> Either a b
Left (Blocked Term -> Either (Blocked Term) Term)
-> Blocked Term -> Either (Blocked Term) Term
forall a b. (a -> b) -> a -> b
$ Blocked_
block Blocked_ -> Term -> Blocked Term
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Elims -> Term
hd Elims
es
Right Substitution
sub -> do
let v' :: Term
v' = Substitution' (SubstArg Term) -> Term -> Term
forall a. Subst a => Substitution' (SubstArg a) -> a -> a
applySubst Substitution
Substitution' (SubstArg Term)
sub Term
rhs
ArgName
-> Int
-> TCMT IO Doc
-> ReduceM (Either (Blocked Term) Term)
-> ReduceM (Either (Blocked Term) Term)
forall (m :: * -> *) a.
MonadDebug m =>
ArgName -> Int -> TCMT IO Doc -> m a -> m a
traceSDoc ArgName
"rewriting.rewrite" Int
50 ([TCMT IO Doc] -> TCMT IO Doc
forall (m :: * -> *) (t :: * -> *).
(Applicative m, Foldable t) =>
t (m Doc) -> m Doc
sep
[ TCMT IO Doc
"rewrote " TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> Term -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => Term -> m Doc
prettyTCM (Elims -> Term
hd Elims
es)
, TCMT IO Doc
" to " TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> Term -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => Term -> m Doc
prettyTCM Term
v' TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> TCMT IO Doc
"}"
]) (ReduceM (Either (Blocked Term) Term)
-> ReduceM (Either (Blocked Term) Term))
-> ReduceM (Either (Blocked Term) Term)
-> ReduceM (Either (Blocked Term) Term)
forall a b. (a -> b) -> a -> b
$ do
Either (Blocked Term) Term -> ReduceM (Either (Blocked Term) Term)
forall a. a -> ReduceM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either (Blocked Term) Term
-> ReduceM (Either (Blocked Term) Term))
-> Either (Blocked Term) Term
-> ReduceM (Either (Blocked Term) Term)
forall a b. (a -> b) -> a -> b
$ Term -> Either (Blocked Term) Term
forall a b. b -> Either a b
Right Term
v'
rewrite ::
Blocked_ -> (Elims -> Term) -> RewriteRules -> Elims
-> ReduceM (Reduced (Blocked Term) Term)
rewrite :: Blocked_
-> (Elims -> Term)
-> RewriteRules
-> Elims
-> ReduceM (Reduced (Blocked Term) Term)
rewrite Blocked_
block Elims -> Term
hd RewriteRules
rules Elims
es = do
rewritingAllowed <- ReduceM Bool
forall (m :: * -> *). HasOptions m => m Bool
anyRewritingOption
if (rewritingAllowed && not (null rules)) then do
(_ , t) <- fromMaybe __IMPOSSIBLE__ <$> getLocalHeadType (hd [])
loop block t rules es
else
return $ NoReduction (block $> hd es)
where
loop ::
Blocked_ -> Type -> RewriteRules -> Elims
-> ReduceM (Reduced (Blocked Term) Term)
loop :: Blocked_
-> Type
-> RewriteRules
-> Elims
-> ReduceM (Reduced (Blocked Term) Term)
loop Blocked_
block Type
t [] Elims
es =
ArgName
-> Int
-> TCMT IO Doc
-> ReduceM (Reduced (Blocked Term) Term)
-> ReduceM (Reduced (Blocked Term) Term)
forall (m :: * -> *) a.
MonadDebug m =>
ArgName -> Int -> TCMT IO Doc -> m a -> m a
traceSDoc ArgName
"rewriting.rewrite" Int
20 ([TCMT IO Doc] -> TCMT IO Doc
forall (m :: * -> *) (t :: * -> *).
(Applicative m, Foldable t) =>
t (m Doc) -> m Doc
sep
[ TCMT IO Doc
"failed to rewrite " TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> Term -> TCMT IO Doc
forall a (m :: * -> *). (PrettyTCM a, MonadPretty m) => a -> m Doc
forall (m :: * -> *). MonadPretty m => Term -> m Doc
prettyTCM (Elims -> Term
hd Elims
es)
, TCMT IO Doc
"blocking tag" TCMT IO Doc -> TCMT IO Doc -> TCMT IO Doc
forall (m :: * -> *). Applicative m => m Doc -> m Doc -> m Doc
<+> ArgName -> TCMT IO Doc
forall (m :: * -> *). Applicative m => ArgName -> m Doc
text (Blocked_ -> ArgName
forall a. Show a => a -> ArgName
show Blocked_
block)
]) (ReduceM (Reduced (Blocked Term) Term)
-> ReduceM (Reduced (Blocked Term) Term))
-> ReduceM (Reduced (Blocked Term) Term)
-> ReduceM (Reduced (Blocked Term) Term)
forall a b. (a -> b) -> a -> b
$ do
Reduced (Blocked Term) Term
-> ReduceM (Reduced (Blocked Term) Term)
forall a. a -> ReduceM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Reduced (Blocked Term) Term
-> ReduceM (Reduced (Blocked Term) Term))
-> Reduced (Blocked Term) Term
-> ReduceM (Reduced (Blocked Term) Term)
forall a b. (a -> b) -> a -> b
$ Blocked Term -> Reduced (Blocked Term) Term
forall no yes. no -> Reduced no yes
NoReduction (Blocked Term -> Reduced (Blocked Term) Term)
-> Blocked Term -> Reduced (Blocked Term) Term
forall a b. (a -> b) -> a -> b
$ Blocked_
block Blocked_ -> Term -> Blocked Term
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Elims -> Term
hd Elims
es
loop Blocked_
block Type
t (RewriteRule
rew:RewriteRules
rews) Elims
es
| let n :: Int
n = RewriteRule -> Int
rewArity RewriteRule
rew, Elims -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length Elims
es Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
n = do
let (Elims
es1, Elims
es2) = Int -> Elims -> (Elims, Elims)
forall i a. Integral i => i -> [a] -> ([a], [a])
List.genericSplitAt Int
n Elims
es
result <- Type
-> (Elims -> Term)
-> RewriteRule
-> Elims
-> ReduceM (Either (Blocked Term) Term)
rewriteWith Type
t Elims -> Term
hd RewriteRule
rew Elims
es1
case result of
Left (Blocked Blocker
m Term
u) -> Blocked_
-> Type
-> RewriteRules
-> Elims
-> ReduceM (Reduced (Blocked Term) Term)
loop (Blocked_
block Blocked_ -> Blocked_ -> Blocked_
forall a. Monoid a => a -> a -> a
`mappend` Blocker -> () -> Blocked_
forall t a. Blocker -> a -> Blocked' t a
Blocked Blocker
m ()) Type
t RewriteRules
rews Elims
es
Left (NotBlocked NotBlocked' Term
_ Term
_) -> Blocked_
-> Type
-> RewriteRules
-> Elims
-> ReduceM (Reduced (Blocked Term) Term)
loop Blocked_
block Type
t RewriteRules
rews Elims
es
Right Term
w -> Reduced (Blocked Term) Term
-> ReduceM (Reduced (Blocked Term) Term)
forall a. a -> ReduceM a
forall (m :: * -> *) a. Monad m => a -> m a
return (Reduced (Blocked Term) Term
-> ReduceM (Reduced (Blocked Term) Term))
-> Reduced (Blocked Term) Term
-> ReduceM (Reduced (Blocked Term) Term)
forall a b. (a -> b) -> a -> b
$ Simplification -> Term -> Reduced (Blocked Term) Term
forall no yes. Simplification -> yes -> Reduced no yes
YesReduction Simplification
YesSimplification (Term -> Reduced (Blocked Term) Term)
-> Term -> Reduced (Blocked Term) Term
forall a b. (a -> b) -> a -> b
$ Term
w Term -> Elims -> Term
forall t. Apply t => t -> Elims -> t
`applyE` Elims
es2
| Bool
otherwise = Blocked_
-> Type
-> RewriteRules
-> Elims
-> ReduceM (Reduced (Blocked Term) Term)
loop (Blocked_
block Blocked_ -> Blocked_ -> Blocked_
forall a. Monoid a => a -> a -> a
`mappend` NotBlocked' Term -> () -> Blocked_
forall t a. NotBlocked' t -> a -> Blocked' t a
NotBlocked NotBlocked' Term
forall t. NotBlocked' t
Underapplied ()) Type
t RewriteRules
rews Elims
es
rewArity :: RewriteRule -> Int
rewArity = PElims -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length (PElims -> Int) -> (RewriteRule -> PElims) -> RewriteRule -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RewriteRule -> PElims
rewPats