Safe Haskell | None |
---|---|
Language | Haskell2010 |
Computing the free variables of a term lazily.
We implement a reduce (traversal into monoid) over internal syntax for a generic collection (monoid with singletons). This should allow a more efficient test for the presence of a particular variable.
Worst-case complexity does not change (i.e. the case when a variable
does not occur), but best case-complexity does matter. For instance,
see mkAbs
: each time we construct
a dependent function type, we check it is actually dependent.
The distinction between rigid and strongly rigid occurrences comes from: Jason C. Reed, PhD thesis, 2009, page 96 (see also his LFMTP 2009 paper)
The main idea is that x = t(x) is unsolvable if x occurs strongly rigidly in t. It might have a solution if the occurrence is not strongly rigid, e.g.
x = f -> suc (f (x ( y -> k))) has x = f -> suc (f (suc k))
- Jason C. Reed, PhD thesis, page 106
Under coinductive constructors, occurrences are never strongly rigid. Also, function types and lambdas do not establish strong rigidity. Only inductive constructors do so. (See issue 1271).
Synopsis
- type MetaSet = Set MetaId
- data FlexRig
- composeFlexRig :: FlexRig -> FlexRig -> FlexRig
- data VarOcc = VarOcc {}
- maxVarOcc :: VarOcc -> VarOcc -> VarOcc
- topVarOcc :: VarOcc
- botVarOcc :: VarOcc
- composeVarOcc :: VarOcc -> VarOcc -> VarOcc
- class (Semigroup a, Monoid a) => IsVarSet a where
- withVarOcc :: VarOcc -> a -> a
- type TheVarMap = IntMap VarOcc
- newtype VarMap = VarMap {}
- mapVarMap :: (TheVarMap -> TheVarMap) -> VarMap -> VarMap
- data IgnoreSorts
- data FreeEnv c = FreeEnv {
- feIgnoreSorts :: !IgnoreSorts
- feFlexRig :: !FlexRig
- feRelevance :: !Relevance
- feSingleton :: Maybe Variable -> c
- type Variable = Int
- type SingleVar c = Variable -> c
- initFreeEnv :: Monoid c => SingleVar c -> FreeEnv c
- type FreeM c = Reader (FreeEnv c) c
- runFreeM :: IsVarSet c => SingleVar c -> IgnoreSorts -> FreeM c -> c
- variable :: IsVarSet c => Int -> FreeM c
- subVar :: Int -> Maybe Variable -> Maybe Variable
- bind :: FreeM a -> FreeM a
- bind' :: Nat -> FreeM a -> FreeM a
- go :: FlexRig -> FreeM a -> FreeM a
- goRel :: Relevance -> FreeM a -> FreeM a
- underConstructor :: ConHead -> FreeM a -> FreeM a
- class Free a where
Documentation
Depending on the surrounding context of a variable, it's occurrence can be classified as flexible or rigid, with finer distinctions.
The constructors are listed in increasing order (wrt. information content).
Flexible MetaSet | In arguments of metas.
The set of metas is used by ' |
WeaklyRigid | In arguments to variables and definitions. |
Unguarded | In top position, or only under inductive record constructors. |
StronglyRigid | Under at least one and only inductive constructors. |
composeFlexRig :: FlexRig -> FlexRig -> FlexRig Source #
FlexRig
composition. For accumulating the context of a variable.
Flexible
is dominant. Once we are under a meta, we are flexible
regardless what else comes.
WeaklyRigid
is next in strength. Destroys strong rigidity.
StronglyRigid
is still dominant over Unguarded
.
Unguarded
is the unit. It is the top (identity) context.
Occurrence of free variables is classified by several dimensions.
Currently, we have FlexRig
and Relevance
.
maxVarOcc :: VarOcc -> VarOcc -> VarOcc Source #
When we extract information about occurrence, we care most about
about StronglyRigid
Relevant
occurrences.
composeVarOcc :: VarOcc -> VarOcc -> VarOcc Source #
First argument is the outer occurrence and second is the inner.
class (Semigroup a, Monoid a) => IsVarSet a where Source #
Any representation of a set of variables need to be able to be modified by a variable occurrence. This is to ensure that free variable analysis is compositional. For instance, it should be possible to compute `fv (v [u/x])` from `fv v` and `fv u`.
withVarOcc :: VarOcc -> a -> a Source #
Laws * Respects monoid operations: ``` withVarOcc o mempty == mempty withVarOcc o (x <> y) == withVarOcc o x <> withVarOcc o y ``` * Respects VarOcc composition ``` withVarOcc (composeVarOcc o1 o2) = withVarOcc o1 . withVarOcc o2 ```
Instances
IsVarSet All Source # | |
Defined in Agda.TypeChecking.Free | |
IsVarSet Any Source # | |
Defined in Agda.TypeChecking.Free | |
IsVarSet VarMap Source # | |
Defined in Agda.TypeChecking.Free.Lazy | |
IsVarSet VarCounts Source # | |
Defined in Agda.TypeChecking.Free | |
IsVarSet FreeVars Source # | |
Defined in Agda.TypeChecking.Free | |
IsVarSet [Int] Source # | |
Defined in Agda.TypeChecking.Free |
Instances
Show VarMap Source # | |
Semigroup VarMap Source # | |
Monoid VarMap Source # | Proper monoid instance for |
IsVarSet VarMap Source # | |
Defined in Agda.TypeChecking.Free.Lazy | |
Singleton (Variable, VarOcc) VarMap Source # | |
Collecting free variables.
data IgnoreSorts Source #
Where should we skip sorts in free variable analysis?
IgnoreNot | Do not skip. |
IgnoreInAnnotations | Skip when annotation to a type. |
IgnoreAll | Skip unconditionally. |
Instances
Eq IgnoreSorts Source # | |
Defined in Agda.TypeChecking.Free.Lazy (==) :: IgnoreSorts -> IgnoreSorts -> Bool # (/=) :: IgnoreSorts -> IgnoreSorts -> Bool # | |
Show IgnoreSorts Source # | |
Defined in Agda.TypeChecking.Free.Lazy showsPrec :: Int -> IgnoreSorts -> ShowS # show :: IgnoreSorts -> String # showList :: [IgnoreSorts] -> ShowS # |
The current context.
FreeEnv | |
|
runFreeM :: IsVarSet c => SingleVar c -> IgnoreSorts -> FreeM c -> c Source #
Run function for FreeM.
subVar :: Int -> Maybe Variable -> Maybe Variable Source #
Subtract, but return Nothing if result is negative.
underConstructor :: ConHead -> FreeM a -> FreeM a Source #
What happens to the variables occurring under a constructor?
Gather free variables in a collection.
Instances
Free EqualityView Source # | |
Defined in Agda.TypeChecking.Free.Lazy | |
Free Clause Source # | |
Free LevelAtom Source # | |
Free PlusLevel Source # | |
Free Level Source # | |
Free Sort Source # | |
Free Term Source # | |
Free Candidate Source # | |
Free NLPType Source # | |
Free NLPat Source # | |
Free DisplayTerm Source # | |
Defined in Agda.TypeChecking.Monad.Base | |
Free DisplayForm Source # | |
Defined in Agda.TypeChecking.Monad.Base | |
Free Constraint Source # | |
Defined in Agda.TypeChecking.Monad.Base | |
Free a => Free [a] Source # | |
Free a => Free (Maybe a) Source # | |
Free a => Free (Dom a) Source # | |
Free a => Free (Arg a) Source # | |
Free a => Free (Tele a) Source # | |
Free a => Free (Type' a) Source # | |
Free a => Free (Abs a) Source # | |
Free a => Free (Elim' a) Source # | |
(Free a, Free b) => Free (a, b) Source # | |