This PR replaces all usages of `[:]` slice notation in `src` with the new `[...]` notation in production code, tests and comments. The underlying implementation of the `Subarray` functions stays the same. Notation cheat sheet: * `*...*` is the doubly-unbounded range. * `*...a` or `*...<a` contains all elements that are less than `a`. * `*...=a` contains all elements that are less than or equal to `a`. * `a...*` contains all elements that are greater than or equal to `a`. * `a...b` or `a...<b` contains all elements that are greater than or equal to `a` and less than `b`. * `a...=b` contains all elements that are greater than or equal to `a` and less than or equal to `b`. * `a<...*` contains all elements that are greater than `a`. * `a<...b` or `a<...<b` contains all elements that are greater than `a` and less than `b`. * `a<...=b` contains all elements that are greater than `a` and less than or equal to `b`. Benchmarks have shown that importing the iterator-backed parts of the polymorphic slice library in `Init` impacts build performance. This PR avoids this problem by separating those parts of the library that do not rely on iterators from those those that do. Whereever the new slice notation is used, only the iterator-independent files are imported.
84 lines
3 KiB
Text
84 lines
3 KiB
Text
/-
|
|
Copyright (c) 2020 Microsoft Corporation. All rights reserved.
|
|
Released under Apache 2.0 license as described in the file LICENSE.
|
|
Authors: Leonardo de Moura
|
|
-/
|
|
prelude
|
|
import Lean.Util.CollectMVars
|
|
import Lean.Meta.Basic
|
|
|
|
namespace Lean.Meta
|
|
|
|
/--
|
|
Collect unassigned metavariables occurring in the given expression.
|
|
|
|
Remark: if `e` contains `?m` and there is a `t` assigned to `?m`, we
|
|
collect unassigned metavariables occurring in `t`.
|
|
|
|
Remark: if `e` contains `?m` and `?m` is delayed assigned to some term `t`,
|
|
we collect `?m` and unassigned metavariables occurring in `t`.
|
|
We collect `?m` because it has not been assigned yet. -/
|
|
partial def collectMVars (e : Expr) : StateRefT CollectMVars.State MetaM Unit := do
|
|
let e ← instantiateMVars e
|
|
let s ← get
|
|
let resultSavedSize := s.result.size
|
|
let s := e.collectMVars s
|
|
set s
|
|
for mvarId in s.result[resultSavedSize...*] do
|
|
match (← getDelayedMVarAssignment? mvarId) with
|
|
| none => pure ()
|
|
| some d => collectMVars (mkMVar d.mvarIdPending)
|
|
|
|
/-- Return metavariables occurring in the given expression. See `collectMVars` -/
|
|
def getMVars (e : Expr) : MetaM (Array MVarId) := do
|
|
let (_, s) ← (collectMVars e).run {}
|
|
pure s.result
|
|
|
|
/-- Similar to `getMVars`, but removes delayed assignments. -/
|
|
def getMVarsNoDelayed (e : Expr) : MetaM (Array MVarId) := do
|
|
let mvarIds ← getMVars e
|
|
mvarIds.filterM fun mvarId => not <$> mvarId.isDelayedAssigned
|
|
|
|
def collectMVarsAtDecl (d : Declaration) : StateRefT CollectMVars.State MetaM Unit :=
|
|
d.forExprM collectMVars
|
|
|
|
def getMVarsAtDecl (d : Declaration) : MetaM (Array MVarId) := do
|
|
let (_, s) ← (collectMVarsAtDecl d).run {}
|
|
pure s.result
|
|
|
|
/--
|
|
Collect the metavariables which `mvarId` depends on. These are the metavariables
|
|
which appear in the type and local context of `mvarId`, as well as the
|
|
metavariables which *those* metavariables depend on, etc.
|
|
-/
|
|
partial def _root_.Lean.MVarId.getMVarDependencies (mvarId : MVarId) (includeDelayed := false) :
|
|
MetaM (Std.HashSet MVarId) :=
|
|
(·.snd) <$> (go mvarId).run {}
|
|
where
|
|
/-- Auxiliary definition for `getMVarDependencies`. -/
|
|
addMVars (e : Expr) : StateRefT (Std.HashSet MVarId) MetaM Unit := do
|
|
let mvars ← getMVars e
|
|
let mut s ← get
|
|
set ({} : Std.HashSet MVarId) -- Ensure that `s` is not shared.
|
|
for mvarId in mvars do
|
|
if ← pure includeDelayed <||> notM (mvarId.isDelayedAssigned) then
|
|
s := s.insert mvarId
|
|
set s
|
|
mvars.forM go
|
|
|
|
/-- Auxiliary definition for `getMVarDependencies`. -/
|
|
go (mvarId : MVarId) : StateRefT (Std.HashSet MVarId) MetaM Unit :=
|
|
withIncRecDepth do
|
|
let mdecl ← mvarId.getDecl
|
|
addMVars mdecl.type
|
|
for ldecl in mdecl.lctx do
|
|
addMVars ldecl.type
|
|
if let (some val) := ldecl.value? then
|
|
addMVars val
|
|
if let (some ass) ← getDelayedMVarAssignment? mvarId then
|
|
let pendingMVarId := ass.mvarIdPending
|
|
if ← notM pendingMVarId.isAssignedOrDelayedAssigned then
|
|
modify (·.insert pendingMVarId)
|
|
go pendingMVarId
|
|
|
|
end Lean.Meta
|