Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
The occurs check for unification. Does pruning on the fly.
When hitting a meta variable:
- Compute flex/rigid for its arguments.
- Compare to allowed variables.
- Mark arguments with rigid occurrences of disallowed variables for deletion.
- Attempt to delete marked arguments.
- We don't need to check for success, we can just continue occurs checking.
Synopsis
- modifyOccursCheckDefs :: (Set QName -> Set QName) -> TCM ()
- initOccursCheck :: MetaVariable -> TCM ()
- defNeedsChecking :: QName -> TCM Bool
- tallyDef :: QName -> TCM ()
- data OccursExtra = OccursExtra {
- occUnfold :: UnfoldStrategy
- occVars :: VarMap
- occMeta :: MetaId
- occCxtSize :: Nat
- type OccursCtx = FreeEnv' () OccursExtra AllowedVar
- type OccursM = ReaderT OccursCtx TCM
- type AllowedVar = Modality -> All
- variableCheck :: VarMap -> Maybe Variable -> AllowedVar
- definitionCheck :: QName -> OccursM ()
- metaCheck :: MetaId -> OccursM MetaId
- allowedVars :: OccursM (Nat -> Bool)
- data UnfoldStrategy
- defArgs :: OccursM a -> OccursM a
- conArgs :: Elims -> OccursM a -> OccursM a
- unfoldB :: (Instantiate t, Reduce t) => t -> OccursM (Blocked t)
- unfold :: (Instantiate t, Reduce t) => t -> OccursM t
- weakly :: OccursM a -> OccursM a
- strongly :: OccursM a -> OccursM a
- flexibly :: OccursM a -> OccursM a
- patternViolation' :: MonadTCM m => Blocker -> Int -> String -> m a
- abort :: Blocker -> TypeError -> OccursM a
- class Occurs t where
- occurs :: t -> OccursM t
- metaOccurs :: MetaId -> t -> TCM ()
- occurs_ :: (Occurs t, TypeOf t ~ ()) => t -> OccursM t
- metaOccurs2 :: (Occurs a, Occurs b) => MetaId -> a -> b -> TCM ()
- metaOccurs3 :: (Occurs a, Occurs b, Occurs c) => MetaId -> a -> b -> c -> TCM ()
- occursCheck :: MetaId -> VarMap -> Term -> TCM Term
- metaOccursQName :: MetaId -> QName -> TCM ()
- prune :: (PureTCM m, MonadMetaSolver m) => MetaId -> Args -> (Nat -> Bool) -> m PruneResult
- hasBadRigid :: PureTCM m => (Nat -> Bool) -> Term -> ExceptT () m Bool
- isNeutral :: HasConstInfo m => Blocked t -> QName -> Elims -> m Bool
- rigidVarsNotContainedIn :: (PureTCM m, AnyRigid a) => a -> (Nat -> Bool) -> m Bool
- class AnyRigid a where
- data PruneResult
- killArgs :: MonadMetaSolver m => [Bool] -> MetaId -> m PruneResult
- killedType :: MonadReduce m => [(Dom (ArgName, Type), Bool)] -> Type -> m ([Arg Bool], Type)
- reallyNotFreeIn :: MonadReduce m => IntSet -> Type -> m (IntSet, Type)
- performKill :: MonadMetaSolver m => [Arg Bool] -> MetaId -> Type -> m ()
MetaOccursCheck: going into definitions to exclude cyclic solutions
initOccursCheck :: MetaVariable -> TCM () Source #
Set the names of definitions to be looked at to the defs in the current mutual block.
OccursM monad and its services
data OccursExtra Source #
Extra environment for the occurs check. (Complements FreeEnv'
.)
OccursExtra | |
|
type OccursCtx = FreeEnv' () OccursExtra AllowedVar Source #
Modality handling.
type AllowedVar = Modality -> All Source #
The passed modality is the one of the current context.
variableCheck :: VarMap -> Maybe Variable -> AllowedVar Source #
Check whether a free variable is allowed in the context as specified by the modality.
definitionCheck :: QName -> OccursM () Source #
Occurs check fails if a defined name is not available since it was declared in irrelevant or erased context.
allowedVars :: OccursM (Nat -> Bool) Source #
Construct a test whether a de Bruijn index is allowed or needs to be pruned.
Unfolding during occurs check.
data UnfoldStrategy Source #
Unfold definitions during occurs check? This effectively runs the occurs check on the normal form.
Instances
Show UnfoldStrategy Source # | |
Defined in Agda.TypeChecking.MetaVars.Occurs showsPrec :: Int -> UnfoldStrategy -> ShowS # show :: UnfoldStrategy -> String # showList :: [UnfoldStrategy] -> ShowS # | |
Eq UnfoldStrategy Source # | |
Defined in Agda.TypeChecking.MetaVars.Occurs (==) :: UnfoldStrategy -> UnfoldStrategy -> Bool # (/=) :: UnfoldStrategy -> UnfoldStrategy -> Bool # |
conArgs :: Elims -> OccursM a -> OccursM a Source #
For a path constructor `c : ... -> Path D a b`, we have that e.g. `c es i0` reduces to a
.
So we have to consider its arguments as flexible when we do not actually unfold.
Managing rigidiy during occurs check.
Error throwing during occurs check.
Implementation of the occurs check.
Extended occurs check.
Instances
Occurs QName Source # | |
Occurs Clause Source # | |
Occurs Elims Source # | |
Occurs Level Source # | |
Occurs PlusLevel Source # | |
Occurs Sort Source # | |
Occurs Term Source # | |
Occurs Type Source # | |
Occurs Defn Source # | |
Occurs a => Occurs (Arg a) Source # | |
Occurs (Abs Term) Source # | |
Occurs (Abs Type) Source # | |
Occurs a => Occurs (Dom a) Source # | |
occursCheck :: MetaId -> VarMap -> Term -> TCM Term Source #
When assigning m xs := v
, check that m
does not occur in v
and that the free variables of v
are contained in xs
.
Pruning: getting rid of flexible occurrences.
:: (PureTCM m, MonadMetaSolver m) | |
=> MetaId | Meta to prune. |
-> Args | Arguments to meta variable. |
-> (Nat -> Bool) | Test for allowed variable (de Bruijn index). |
-> m PruneResult |
prune m' vs xs
attempts to remove all arguments from vs
whose
free variables are not contained in xs
.
If successful, m'
is solved by the new, pruned meta variable and we
return True
else False
.
Issue 1147:
If any of the meta args vs
is matchable, e.g., is a constructor term,
we cannot prune, because the offending variables could be removed by
reduction for a suitable instantiation of the meta variable.
:: PureTCM m | |
=> (Nat -> Bool) | Test for allowed variable (de Bruijn index). |
-> Term | Argument of meta variable. |
-> ExceptT () m Bool | Exception if argument is matchable. |
hasBadRigid xs v = Just True
iff one of the rigid variables in v
is not in xs
.
Actually we can only prune if a bad variable is in the head. See issue 458.
Or in a non-eliminateable position (see succeed/PruningNonMillerPattern).
hasBadRigid xs v = Nothing
means that
we cannot prune at all as one of the meta args is matchable.
(See issue 1147.)
isNeutral :: HasConstInfo m => Blocked t -> QName -> Elims -> m Bool Source #
Check whether a term Def f es
is finally stuck.
Currently, we give only a crude approximation.
rigidVarsNotContainedIn Source #
:: (PureTCM m, AnyRigid a) | |
=> a | |
-> (Nat -> Bool) | Test for allowed variable (de Bruijn index). |
-> m Bool |
Check whether any of the variables (given as de Bruijn indices) occurs *definitely* in the term in a rigid position. Reduces the term successively to remove variables in dead subterms. This fixes issue 1386.
class AnyRigid a where Source #
Collect the *definitely* rigid variables in a monoid. We need to successively reduce the expression to do this.
Instances
AnyRigid Level Source # | |
AnyRigid PlusLevel Source # | |
AnyRigid Sort Source # | |
AnyRigid Term Source # | |
AnyRigid Type Source # | |
AnyRigid a => AnyRigid (Arg a) Source # | |
(Subst a, AnyRigid a) => AnyRigid (Abs a) Source # | |
AnyRigid a => AnyRigid (Dom a) Source # | |
AnyRigid a => AnyRigid (Elim' a) Source # | |
AnyRigid a => AnyRigid [a] Source # | |
(AnyRigid a, AnyRigid b) => AnyRigid (a, b) Source # | |
data PruneResult Source #
NothingToPrune | the kill list is empty or only |
PrunedNothing | there is no possible kill (because of type dep.) |
PrunedSomething | managed to kill some args in the list |
PrunedEverything | all prescribed kills where performed |
Instances
Show PruneResult Source # | |
Defined in Agda.TypeChecking.MetaVars.Occurs showsPrec :: Int -> PruneResult -> ShowS # show :: PruneResult -> String # showList :: [PruneResult] -> ShowS # | |
Eq PruneResult Source # | |
Defined in Agda.TypeChecking.MetaVars.Occurs (==) :: PruneResult -> PruneResult -> Bool # (/=) :: PruneResult -> PruneResult -> Bool # |
killArgs :: MonadMetaSolver m => [Bool] -> MetaId -> m PruneResult Source #
killArgs [k1,...,kn] X
prunes argument i
from metavar X
if ki==True
.
Pruning is carried out whenever > 0 arguments can be pruned.
killedType :: MonadReduce m => [(Dom (ArgName, Type), Bool)] -> Type -> m ([Arg Bool], Type) Source #
killedType [((x1,a1),k1)..((xn,an),kn)] b = ([k'1..k'n],t')
(ignoring Dom
). Let t' = (xs:as) -> b
.
Invariant: k'i == True
iff ki == True
and pruning the i
th argument from
type b
is possible without creating unbound variables.
t'
is type t
after pruning all k'i==True
.
reallyNotFreeIn :: MonadReduce m => IntSet -> Type -> m (IntSet, Type) Source #
:: MonadMetaSolver m | |
=> [Arg Bool] | Arguments to old meta var in left to right order
with |
-> MetaId | The old meta var to receive pruning. |
-> Type | The pruned type of the new meta var. |
-> m () |
Instantiate a meta variable with a new one that only takes the arguments which are not pruneable.
Orphan instances
IsVarSet () AllowedVar Source # | |
withVarOcc :: VarOcc' () -> AllowedVar -> AllowedVar Source # |