Smart unfolding support #
Forward declaration. It is defined in the module src/Lean/Elab/PreDefinition/Structural/Eqns.lean
.
It is possible to avoid this hack if we move Structural.EqnInfo
and Structural.eqnInfoExt
to this module.
Equations
- Lean.Meta.smartUnfoldingSuffix = "_sunfold"
Instances For
Equations
- Lean.Meta.mkSmartUnfoldingNameFor declName = declName.mkStr Lean.Meta.smartUnfoldingSuffix
Instances For
Equations
- Lean.Meta.hasSmartUnfoldingDecl env declName = env.contains (Lean.Meta.mkSmartUnfoldingNameFor declName)
Instances For
Add auxiliary annotation to indicate the match
-expression e
must be reduced when performing smart unfolding.
Equations
- Lean.Meta.markSmartUnfoldingMatch e = Lean.mkAnnotation `sunfoldMatch e
Instances For
Equations
- Lean.Meta.smartUnfoldingMatch? e = Lean.annotation? `sunfoldMatch e
Instances For
Add auxiliary annotation to indicate expression e
(a match
alternative rhs) was successfully reduced by smart unfolding.
Equations
- Lean.Meta.markSmartUnfoldingMatchAlt e = Lean.mkAnnotation `sunfoldMatchAlt e
Instances For
Equations
- Lean.Meta.smartUnfoldingMatchAlt? e = Lean.annotation? `sunfoldMatchAlt e
Instances For
Helper methods #
Equations
- Lean.Meta.isAuxDef constName = do let env ← Lean.getEnv pure (Lean.isAuxRecursor env constName || Lean.isNoConfusion env constName)
Instances For
Helper functions for reducing recursors #
Create the i
th projection major
. It tries to use the auto-generated projection functions if available. Otherwise falls back
to Expr.proj
.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Helper functions for reducing Quot.lift and Quot.ind #
Helper function for extracting "stuck term" #
Return some (Expr.mvar mvarId)
if metavariable mvarId
is blocking reduction.
Weak Head Normal Form auxiliary combinators #
Configuration for projection reduction. See whnfCore
.
- no: Lean.Meta.ProjReductionKind
Projections
s.i
are not reduced atwhnfCore
. - yes: Lean.Meta.ProjReductionKind
- yesWithDelta: Lean.Meta.ProjReductionKind
- yesWithDeltaI: Lean.Meta.ProjReductionKind
Projections
s.i
are reduced atwhnfCore
, andwhnfAtMostI
is used ats
during the process. Recall thatwhnfAtMostI
is likewhnf
but uses transparency at mostinstances
. This option is stronger thanyes
, but weaker thanyesWithDelta
. We use this option to ensure we reduce projections to prevent expensive defeq checks when unifying TC operations. When unifying e.g.(@Field.toNeg α inst1).1 =?= (@Field.toNeg α inst2).1
, we only want to unify negation (and not all other field operations as well). Unifying the field instances slowed down unification: https://github.com/leanprover/lean4/issues/1986
Instances For
Equations
- Lean.Meta.instDecidableEqProjReductionKind x y = if h : x.toCtorIdx = y.toCtorIdx then isTrue ⋯ else isFalse ⋯
Equations
- Lean.Meta.instReprProjReductionKind = { reprPrec := Lean.Meta.reprProjReductionKind✝ }
Configuration options for whnfEasyCases
and whnfCore
.
- iota : Bool
- beta : Bool
If
true
, reduce terms such as(fun x => t[x]) a
intot[a]
- proj : Lean.Meta.ProjReductionKind
Control projection reduction at
whnfCore
. - zeta : Bool
Zeta reduction:
let x := v; e[x]
reduces toe[v]
. We say a let-declarationlet x := v; e
is non dependent if it is equivalent to(fun x => e) v
. Recall thatfun x : BitVec 5 => let n := 5; fun y : BitVec n => x = y
is type correct, but
fun x : BitVec 5 => (fun n => fun y : BitVec n => x = y) 5
is not.
- zetaDelta : Bool
Zeta-delta reduction: given a local context containing entry
x : t := e
, free variablex
reduces toe
.
Instances For
Auxiliary combinator for handling easy WHNF cases. It takes a function for handling the "hard" cases as an argument
- reduced: Lean.Expr → Lean.Meta.ReduceMatcherResult
- stuck: Lean.Expr → Lean.Meta.ReduceMatcherResult
- notMatcher: Lean.Meta.ReduceMatcherResult
- partialApp: Lean.Meta.ReduceMatcherResult
Instances For
The "match" compiler uses dependent if-then-else dite
and other auxiliary declarations to compile match-expressions such as
match v with
| 'a' => 1
| 'b' => 2
| _ => 3
because it is more efficient than using casesOn
recursors.
The method reduceMatcher?
fails if these auxiliary definitions cannot be unfolded in the current
transparency setting. This is problematic because tactics such as simp
use TransparencyMode.reducible
, and
most users assume that expressions such as
match 0 with
| 0 => 1
| 100 => 2
| _ => 3
should reduce in any transparency mode.
Thus, if the transparency mode is .reducible
or .instances
, we first
eagerly unfold dite
constants used in the auxiliary match-declaration, and then
use a custom canUnfoldAtMatcher
predicate for whnfMatcher
.
Remark: we used to include dite
(and ite
) as auxiliary declarations to unfold at
canUnfoldAtMatcher
, but this is problematic because the dite
/ite
may occur in the
discriminant. See issue #5388.
This solution is not very modular because modifications at the match
compiler require changes here.
We claim this is defensible because it is reducing the auxiliary declaration defined by the match
compiler.
Remark: if the eager unfolding is problematic, we may cache the result.
We may also consider not using dite
in the match
-compiler and use Decidable.casesOn
, but it will require changes
in how we generate equation lemmas.
Alternative solution: tactics that use TransparencyMode.reducible
should rely on the equations we generated for match-expressions.
This solution is also not perfect because the match-expression above will not reduce during type checking when we are not using
TransparencyMode.default
or TransparencyMode.all
.
Auxiliary predicate for whnfMatcher
.
See comment above.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- Lean.Meta.project? e i = do let __do_lift ← Lean.Meta.whnf e Lean.Meta.projectCore? __do_lift i
Instances For
Reduce kernel projection Expr.proj ..
expression.
Equations
- Lean.Meta.reduceProj? (Lean.Expr.proj typeName i c) = Lean.Meta.project? c i
- Lean.Meta.reduceProj? e = pure none
Instances For
Apply beta-reduction, zeta-reduction (i.e., unfold let local-decls), iota-reduction, expand let-expressions, expand assigned meta-variables.
Equations
- Lean.Meta.whnfCore e config = Lean.Meta.whnfCore.go config e
Instances For
Recall that _sunfold
auxiliary definitions contains the markers: markSmartUnfoldingMatch
(*) and markSmartUnfoldingMatchAlt
(**).
For example, consider the following definition
def r (i j : Nat) : Nat :=
i +
match j with
| Nat.zero => 1
| Nat.succ j =>
i + match j with
| Nat.zero => 2
| Nat.succ j => r i j
produces the following _sunfold
auxiliary definition with the markers
def r._sunfold (i j : Nat) : Nat :=
i +
(*) match j with
| Nat.zero => (**) 1
| Nat.succ j =>
i + (*) match j with
| Nat.zero => (**) 2
| Nat.succ j => (**) r i j
match
expressions marked with markSmartUnfoldingMatch
(*) must be reduced, otherwise the resulting term is not definitionally
equal to the given expression. The recursion may be interrupted as soon as the annotation markSmartUnfoldingAlt
(**) is reached.
For example, the term r i j.succ.succ
reduces to the definitionally equal term i + i * r i j
Equations
Instances For
Auxiliary method for unfolding a class projection.
Auxiliary method for unfolding a class projection when transparency is set to TransparencyMode.instances
.
Recall that class instance projections are not marked with [reducible]
because we want them to be
in "reducible canonical form".
Unfold definition using "smart unfolding" if possible.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
Instances For
Try to reduce matcher/recursor/quot applications. We say they are all "morally" recursor applications.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Instances For
Instances For
Equations
- One or more equations did not get rendered due to their size.
- Lean.Meta.reduceNative? e = pure none
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- Lean.Meta.reduceUnaryNatOp f a = Lean.Meta.withNatValue a fun (a : Nat) => pure (some (Lean.mkRawNatLit (f a)))
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- Lean.Meta.reduceBinNatPred f a b = Lean.Meta.withNatValue a fun (a : Nat) => Lean.Meta.withNatValue b fun (b : Nat) => pure (some (Lean.toExpr (f a b)))
Instances For
If e
is a projection function that satisfies p
, then reduce it
Equations
- One or more equations did not get rendered due to their size.