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.
89 lines
2.8 KiB
Text
89 lines
2.8 KiB
Text
import Lean.Meta.ExprLens
|
|
import Lean.Meta.ExprTraverse
|
|
import Lean
|
|
|
|
open Lean Meta Elab Term SubExpr
|
|
|
|
def Lean.LocalContext.subtract (Γ Δ : LocalContext) : Array Expr :=
|
|
-- have Δ = Γ ++ E
|
|
let Δ := Δ.getFVars
|
|
let Γ := Γ.getFVars
|
|
let E := Δ[*...(Δ.size - Γ.size)]
|
|
E.toArray
|
|
|
|
def ExprTraversal := ∀{M : _} [Monad M] [MonadLiftT MetaM M] [MonadControlT MetaM M] [MonadOptions M], (Pos → Expr → M Expr) → Pos → Expr → M Expr
|
|
|
|
instance : Inhabited ExprTraversal where
|
|
default := traverseChildrenWithPos
|
|
|
|
partial def traverseAll : ExprTraversal := fun
|
|
| visit, p, e => visit p e >>= traverseChildrenWithPos (fun p e => traverseAll visit p e) p
|
|
|
|
def testTraversal
|
|
(traversalWithPos : ExprTraversal)
|
|
(expectedLen : Nat): TermElabM Unit := do
|
|
-- make a sample expression `e` that has all of the different kinds of expressions.
|
|
let s ← `(
|
|
∀ x y : Nat,
|
|
∀ {zz : Fin x},
|
|
∃ (z : {z: Nat // z = x + y}),
|
|
let p := z.1
|
|
p + x + y = 3
|
|
)
|
|
let e ← elabTerm s none
|
|
let Γ ← getLCtx
|
|
|
|
-- traverse `e` using the `traversalWithPos` function
|
|
-- leave `e` unmodified but at each point accumulate
|
|
-- the abstracted subexpression
|
|
let (e', subexprs) ← StateT.run (
|
|
traversalWithPos (fun p s => do
|
|
let a ← get
|
|
let Δ ← getLCtx
|
|
let E := Lean.LocalContext.subtract Γ Δ
|
|
|
|
-- check that numBinders works
|
|
let nBinders ← Lean.Core.numBinders p e
|
|
if E.size != nBinders then
|
|
throwError "bad number of binders"
|
|
|
|
set <| a.push (p, Expr.abstract s E)
|
|
return s
|
|
) Pos.root e) #[]
|
|
-- the traversal output should be equal to the original
|
|
-- that is: `traversal pure e ≡ e`
|
|
if not (← liftM $ isDefEq e e') then
|
|
throwError "\n{e} \nand \n{e'} are different!"
|
|
|
|
-- check that the number of subexpressions is what we expect
|
|
-- and if it isn't then print them out for debugging.
|
|
if subexprs.size != expectedLen then
|
|
for (p, s) in subexprs do
|
|
let ppt ← PrettyPrinter.ppExpr s
|
|
dbg_trace s!"{p}, {ppt}\n"
|
|
throwError "expected size: {expectedLen}\nactual size: {subexprs.size}"
|
|
|
|
-- for each subexpression `p`, make sure that viewSubexpr produces the same
|
|
-- subexpression as that found in the traversal.
|
|
for (p, s) in subexprs do
|
|
viewSubexpr (fun fvars t => do
|
|
let t := Expr.abstract t fvars
|
|
let de ← liftM $ isDefEq t s
|
|
if not de then
|
|
throwError "\n{t} \nand \n{s} are different!"
|
|
return ()
|
|
) p e
|
|
|
|
-- check that replaceSubexpr pure is the identity
|
|
let e' ← replaceSubexpr pure p e
|
|
if not (← liftM $ isDefEq e e') then
|
|
throwError "\n{e} \nand \n{e'} are different!"
|
|
|
|
#guard_msgs in
|
|
#eval ((do
|
|
testTraversal traverseLambdaWithPos 1
|
|
testTraversal traverseChildrenWithPos 4
|
|
testTraversal traverseAll 103
|
|
return ())
|
|
: TermElabM Unit
|
|
)
|