Compare commits

..

2 Commits

Author SHA1 Message Date
Leonardo de Moura
114664341e refactor: remove Cbv.mkAppNS alias, use Sym.Internal.mkAppNS directly
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 19:21:10 -07:00
Leonardo de Moura
dd6947548b feat: add mkAppNS, mkAppRevS, betaRevS, betaS, and related Sym functions
This PR adds a comprehensive public API for constructing maximally shared
expression applications and performing beta reduction in the `Sym` framework.
These functions were previously defined locally in the VC generator and cbv
tactic, and are needed by downstream `SymM`-based tools.

New functions in `Lean.Meta.Sym.Internal` (generic over `MonadShareCommon`):
- `mkAppS₆` through `mkAppS₁₁`
- `mkAppRangeS`, `mkAppNS`, `mkAppRevRangeS`, `mkAppRevS`

New public functions in `Lean.Meta.Sym` (`SymM`):
- `betaRevS`, `betaS`
- `mkForallFVarsS`

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 19:18:57 -07:00
246 changed files with 126 additions and 238 deletions

View File

@@ -271,7 +271,7 @@ private def optionPelim' {α : Type u_1} (t : Option α) {β : Sort u_2}
/--
Inserts an `Option` case distinction after the first computation of a call to `MonadAttach.pbind`.
This lemma is useful for simplifying the second computation, which often involves `match` expressions
This lemma is useful for simplifying the second computation, which often involes `match` expressions
that use `pbind`'s proof term.
-/
private theorem pbind_eq_pbind_if_isSome [Monad m] [MonadAttach m] (x : m (Option α)) (f : (_ : _) _ m β) :

View File

@@ -31,7 +31,7 @@ namespace Slice
/--
A list of all positions starting at {name}`p`.
This function is not meant to be used in actual programs. Actual programs should use
This function is not meant to be used in actual progams. Actual programs should use
{name}`Slice.positionsFrom` or {name}`Slice.positions`.
-/
protected def Model.positionsFrom {s : Slice} (p : s.Pos) : List { p : s.Pos // p s.endPos } :=
@@ -206,7 +206,7 @@ end Slice
/--
A list of all positions starting at {name}`p`.
This function is not meant to be used in actual programs. Actual programs should use
This function is not meant to be used in actual progams. Actual programs should use
{name}`Slice.positionsFrom` or {name}`Slice.positions`.
-/
protected def Model.positionsFrom {s : String} (p : s.Pos) : List { p : s.Pos // p s.endPos } :=

View File

@@ -23,7 +23,7 @@ Given a {name}`Slice` {name}`s`, the type {lean}`s.Subslice` is the type of half
in {name}`s` delineated by a valid position on both sides.
This type is useful to track regions of interest within some larger slice that is also of interest.
In contrast, {name}`Slice` is used to track regions of interest within some larger string that is
In contrast, {name}`Slice` is used to track regions of interest whithin some larger string that is
not or no longer relevant.
Equality on {name}`Subslice` is somewhat better behaved than on {name}`Slice`, but note that there

View File

@@ -145,7 +145,7 @@ Examples:
The constant function that ignores its argument.
If `a : α`, then `Function.const β a : β → α` is the “constant function with value `a`”. For all
arguments `b : β`, `Function.const β a b = a`. It is often written directly as `fun _ => a`.
arguments `b : β`, `Function.const β a b = a`.
Examples:
* `Function.const Bool 10 true = 10`
@@ -3754,7 +3754,7 @@ class Functor (f : Type u → Type v) : Type (max (u+1) v) where
/--
Mapping a constant function.
Given `a : α` and `v : f β`, `mapConst a v` is equivalent to `(fun _ => a) <$> v`. For some
Given `a : α` and `v : f α`, `mapConst a v` is equivalent to `Function.const _ a <$> v`. For some
functors, this can be implemented more efficiently; for all other functors, the default
implementation may be used.
-/

View File

@@ -28,7 +28,7 @@ inserts addition instructions to attempt to reuse the memory right away instead
allocator.
For this the paper defines three functions:
- `R` (called `Decl.insertResetReuse` here) which looks for candidates that might be eligible for
- `R` (called `Decl.insertResetReuse` here) which looks for candidates that might be elligible for
reuse. For these variables it invokes `D`.
- `D` which looks for code regions in which the target variable is dead (i.e. no longer read from),
it then invokes `S`. If `S` succeeds it inserts a `reset` instruction to match the `reuse`

View File

@@ -24,7 +24,7 @@ In particular we perform:
- folding of the most common cases arm into the default arm if possible
Note: Currently the simplifier still contains almost equivalent simplifications to the ones shown
here. We know that this causes unforeseen behavior and do plan on changing it eventually.
here. We know that this causes unforseen behavior and do plan on changing it eventually.
-/
-- TODO: the following functions are duplicated from simp and should be deleted in simp once we

View File

@@ -171,7 +171,7 @@ def toDecl (declName : Name) : CompilerM (Decl .pure) := do
if compiler.ignoreBorrowAnnotation.get ( getOptions) then
decl := { decl with params := decl.params.mapM (·.updateBorrow false) }
if isExport env decl.name && decl.params.any (·.borrow) then
throwError m!" Declaration {decl.name} is marked as `export` but some of its parameters have borrow annotations.\n Consider using `set_option compiler.ignoreBorrowAnnotation true in` to suppress the borrow annotations in its type.\n If the declaration is part of an `export`/`extern` pair make sure to also suppress the annotations at the `extern` declaration."
throwError m!" Declaration {decl.name} is marked as `export` but some of its parameters have borrow annotations.\n Consider using `set_option compiler.ignoreBorrowAnnotation true in` to supress the borrow annotations in its type.\n If the declaration is part of an `export`/`extern` pair make sure to also supress the annotations at the `extern` declaration."
return decl
end Lean.Compiler.LCNF

View File

@@ -20,8 +20,6 @@ register_builtin_option diagnostics : Bool := {
descr := "collect diagnostic information"
}
builtin_initialize registerTraceClass `diagnostics
register_builtin_option diagnostics.threshold : Nat := {
defValue := 20
descr := "only diagnostic counters above this threshold are reported by the definitional equality"

View File

@@ -111,7 +111,7 @@ def mkMatchNew (ctx : Context) (header : Header) (indVal : InductiveVal) : TermE
let x1 := mkIdent header.targetNames[0]!
let x2 := mkIdent header.targetNames[1]!
let ctorIdxName := mkCtorIdxName indVal.name
-- NB: the getMatcherInfo? assumes all matchers are called `match_`
-- NB: the getMatcherInfo? assumes all mathcers are called `match_`
let casesOnSameCtorName mkFreshUserName (indVal.name ++ `match_on_same_ctor)
mkCasesOnSameCtor casesOnSameCtorName indVal.name
let alts Array.ofFnM (n := indVal.numCtors) fun ctorIdx, _ => do

View File

@@ -36,7 +36,7 @@ def mkContext (lratPath : System.FilePath) (cfg : BVDecideConfig) : TermElabM Ta
TacticContext.new lratPath cfg
/--
Prepare an `Expr` that proves `bvExpr.unsat` using native evaluation.
Prepare an `Expr` that proves `bvExpr.unsat` using native evalution.
-/
def lratChecker (ctx : TacticContext) (reflectionResult : ReflectionResult) : MetaM Expr := do
let cert LratCert.ofFile ctx.lratPath ctx.config.trimProofs

View File

@@ -357,7 +357,6 @@ def reflectBV (g : MVarId) : M ReflectionResult := g.withContext do
let mut sats := #[]
let mut unusedHypotheses := {}
for hyp in hyps do
checkSystem "bv_decide"
if let (some reflected, lemmas) (SatAtBVLogical.of (mkFVar hyp)).run then
sats := (sats ++ lemmas).push reflected
else

View File

@@ -33,7 +33,6 @@ where
Reify `x`, returns `none` if the reification procedure failed.
-/
go (origExpr : Expr) : LemmaM (Option ReifiedBVExpr) := do
checkSystem "bv_decide"
match_expr origExpr with
| BitVec.ofNat _ _ => goBvLit origExpr
| HAnd.hAnd _ _ _ _ lhsExpr rhsExpr =>
@@ -341,7 +340,6 @@ where
Reify `t`, returns `none` if the reification procedure failed.
-/
go (origExpr : Expr) : LemmaM (Option ReifiedBVLogical) := do
checkSystem "bv_decide"
match_expr origExpr with
| Bool.true => ReifiedBVLogical.mkBoolConst true
| Bool.false => ReifiedBVLogical.mkBoolConst false

View File

@@ -159,7 +159,6 @@ Repeatedly run a list of `Pass` until they either close the goal or an iteration
the goal anymore.
-/
partial def fixpointPipeline (passes : List Pass) (goal : MVarId) : PreProcessM (Option MVarId) := do
checkSystem "bv_decide"
let mut newGoal := goal
for pass in passes do
if let some nextGoal pass.run newGoal then

View File

@@ -48,16 +48,6 @@ register_builtin_option backward.isDefEq.respectTransparency : Bool := {
when checking whether implicit arguments are definitionally equal"
}
/--
Controls the transparency used to check whether the type of metavariable matches the type of the
term being assigned to it.
-/
register_builtin_option backward.isDefEq.respectTransparency.types : Bool := {
defValue := false -- TODO: replace with `true` after we fix stage0
descr := "if true, do not bump transparency to `.default` \
when checking whether the type of a metavariable matches the type of the term being assigned to it."
}
/--
Controls whether *all* implicit arguments (not just instance-implicit `[..]`) get their
transparency bumped to `TransparencyMode.instances` during `isDefEq`.
@@ -345,10 +335,10 @@ private def isDefEqArgsFirstPass
/--
Ensure `MetaM` configuration is strong enough for checking definitional equality of
implicit arguments (e.g., instances) and types.
For example, we must be able to unfold instances, `beta := true`, `proj := .yesWithDelta` are essential.
instances. For example, we must be able to unfold instances, `beta := true`, `proj := .yesWithDelta`
are essential.
-/
@[inline] def withImplicitConfig (x : MetaM α) : MetaM α :=
@[inline] def withInstanceConfig (x : MetaM α) : MetaM α :=
withAtLeastTransparency .instances do
let cfg getConfig
if cfg.beta && cfg.iota && cfg.zeta && cfg.zetaHave && cfg.zetaDelta && cfg.proj == .yesWithDelta then
@@ -392,7 +382,7 @@ private partial def isDefEqArgs (f : Expr) (args₁ args₂ : Array Expr) : Meta
-- Bump to `.instances` so that `[implicit_reducible]` definitions (instances, `Nat.add`,
-- `Array.size`, etc.) are unfolded. The user doesn't choose implicit arguments directly,
-- so Lean should try harder than the caller's transparency to make them match.
unless ( withImplicitConfig <| Meta.isExprDefEqAux a₁ a₂) do return false
unless ( withInstanceConfig <| Meta.isExprDefEqAux a₁ a₂) do return false
else if respectTransparency then
unless ( Meta.isExprDefEqAux a₁ a₂) do return false
else
@@ -402,7 +392,7 @@ private partial def isDefEqArgs (f : Expr) (args₁ args₂ : Array Expr) : Meta
let a₁ := args₁[i]!
let a₂ := args₂[i]!
if respectTransparency && (implicitBump || finfo.paramInfo[i]!.isInstance) then
unless ( withImplicitConfig <| Meta.isExprDefEqAux a₁ a₂) do return false
unless ( withInstanceConfig <| Meta.isExprDefEqAux a₁ a₂) do return false
else if !respectTransparency && finfo.paramInfo[i]!.isInstance then
-- Old behavior
unless ( withInferTypeConfig <| Meta.isExprDefEqAux a₁ a₂) do return false
@@ -464,19 +454,6 @@ private partial def isDefEqBindingAux (lctx : LocalContext) (fvars : Array Expr)
let lctx getLCtx
isDefEqBindingAux lctx #[] a b #[]
/--
Returns `true` if both `backward.isDefEq.respectTransparency` and `backward.isDefEq.respectTransparency.types` is true.
The option `backward.isDefEq.respectTransparency.types` is newer than ``backward.isDefEq.respectTransparency`,
and is used to enable the transparency bump when checking metavariable assignments.
If `backward.isDefEq.respectTransparency` is `false`, then we automatically disable
`backward.isDefEq.respectTransparency.types` too.
-/
abbrev respectTransparencyAtTypes : CoreM Bool := do
let opts getOptions
return backward.isDefEq.respectTransparency.types.get opts && backward.isDefEq.respectTransparency.get opts
private def checkTypesAndAssign (mvar : Expr) (v : Expr) : MetaM Bool :=
withTraceNodeBefore `Meta.isDefEq.assign.checkTypes (fun _ => return m!"({mvar} : {← inferType mvar}) := ({v} : {← inferType v})") do
if !mvar.isMVar then
@@ -485,24 +462,14 @@ private def checkTypesAndAssign (mvar : Expr) (v : Expr) : MetaM Bool :=
else
-- must check whether types are definitionally equal or not, before assigning and returning true
let mvarType inferType mvar
let vType inferType v
if ( respectTransparencyAtTypes) then
withImplicitConfig do
if ( Meta.isExprDefEqAux mvarType vType) then
mvar.mvarId!.assign v
return true
else
if ( isDiagnosticsEnabled) then withInferTypeConfig do
if ( Meta.isExprDefEqAux mvarType vType) then
trace[diagnostics] "failure when assigning metavariable with type{indentExpr mvarType}\nwhich is not definitionally equal to{indentExpr vType}\nwhen using `.instances` transparency, but it is with `.default`.\nWorkaround: `set_option backward.isDefEq.respectTransparency.types false`"
return false
else
withInferTypeConfig do
if ( Meta.isExprDefEqAux mvarType vType) then
mvar.mvarId!.assign v
return true
else
return false
-- **TODO**: avoid transparency bump. Let's fix other issues first
withInferTypeConfig do
let vType inferType v
if ( Meta.isExprDefEqAux mvarType vType) then
mvar.mvarId!.assign v
pure true
else
pure false
/--
Auxiliary method for solving constraints of the form `?m xs := v`.
@@ -2095,7 +2062,7 @@ private def isDefEqProj : Expr → Expr → MetaM Bool
for instance-implicit parameters. -/
let fromClass := isClass ( getEnv) m
let isDefEqStructArgs (x : MetaM Bool) : MetaM Bool :=
if fromClass then withImplicitConfig x else x
if fromClass then withInstanceConfig x else x
if ( read).inTypeClassResolution then
-- See comment at `inTypeClassResolution`
pure (i == j && m == n) <&&> isDefEqStructArgs (Meta.isExprDefEqAux t s)

View File

@@ -33,12 +33,12 @@ The high-level overview of moves are
* If there is an alternative, solve its constraints
* Else use `contradiction` to prove completeness of the match
* Process “independent prefixes” of patterns. These are patterns that can be processed without
affecting the other alternatives, and without side effects in the sense of updating the `mvarId`.
affecting the aother alternatives, and without side effects in the sense of updating the `mvarId`.
These are
- variable patterns; substitute
- inaccessible patterns; add equality constraints
- as-patterns: substitute value and equality
After these have been processed, we use `.inaccessible x` where `x` is the variable being matched
After thes have been processed, we use `.inaccessible x` where `x` is the variable being matched
to mark them as “done”.
* If all patterns start with “done”, drop the first variable
* The first alt has only “done” patterns, drop remaining alts (they're overlapped)
@@ -1108,9 +1108,6 @@ def mkMatcherAuxDefinition (name : Name) (type : Expr) (value : Expr) (isSplitte
-- matcher bodies should always be exported, if not private anyway
withExporting do
addDecl decl
-- if `matcher` is not private, we mark it as `implicit_reducible` too
unless isPrivateName name do
setReducibilityStatus name .implicitReducible
unless isSplitter do
modifyEnv fun env => matcherExt.modifyState env fun s => s.insert key name
addMatcherInfo name mi

View File

@@ -17,7 +17,7 @@ namespace Lean.Meta
/--
Tries to rewrite the `ite`, `dite` or `cond` expression `e` with the hypothesis `hc`.
If it fails, it returns a rewrite with `proof? := none` and unchanged expression.
If it fails, it returns a rewrite with `proof? := none` and unchaged expression.
-/
def rwIfWith (hc : Expr) (e : Expr) : MetaM Simp.Result := do
match_expr e with

View File

@@ -22,9 +22,9 @@ of that computation as an axiom towards the logic.
-/
public inductive NativeEqTrueResult where
/-- The given expression `e` evaluates to true. `prf` is a proof of `e = true`. -/
/-- The given expression `e` evalutes to true. `prf` is a proof of `e = true`. -/
| success (prf : Expr)
/-- The given expression `e` evaluates to false. -/
/-- The given expression `e` evalutes to false. -/
| notTrue
/--

View File

@@ -14,7 +14,7 @@ This module contains utilities for dealing with equalities between constructor a
in particular about which fields must be the same a-priori for the equality to type check.
Users include (or will include) the injectivity theorems, the per-constructor no-confusion
construction and deriving type classes like `BEq`, `DecidableEq` or `Ord`.
construction and deriving type classes lik `BEq`, `DecidableEq` or `Ord`.
-/
namespace Lean.Meta

View File

@@ -24,19 +24,14 @@ builtin_initialize registerTraceClass `sym.debug.canon
Canonicalizes expressions by normalizing types and instances. At the top level, it traverses
applications, foralls, lambdas, and let-bindings, classifying each argument as a type, instance,
implicit, or value using `shouldCanon`. Targeted reductions (projection, match/ite/cond, Nat
arithmetic) are applied to all positions; instances are re-synthesized.
implicit, or value using `shouldCanon`. Values are recursively visited but not normalized.
Types and instances receive targeted reductions.
**Note about types:** `grind` is not built for reasoning about types that are not propositions.
We assume that definitionally equal types will be structurally identical after we apply the
canonicalizer. We also erase most of the subsingleton markers occurring inside types.
## Reductions
It also normalizes expressions using the following reductions. We can view it as a cheap/custom `dsimp`.
We used to reduce only terms inside types, but it restricted important normalizations that were important
when, for example, a term had a forward dependency. That is, the term is not directly in a type, but
there is a type that depends on it.
## Reductions (applied only in type positions)
- **Eta**: `fun x => f x` → `f`
- **Projection**: `⟨a, b⟩.1` → `a` (structure projections, not class projections)
@@ -44,9 +39,6 @@ there is a type that depends on it.
- **Nat arithmetic**: ground evaluation (`2 + 1` → `3`) and offset normalization
(`n.succ + 1` → `n + 2`)
**Note**: Eta is applied only if the lambda is occurring inside of a type. For lambdas occurring
in non type positions, we want to leverage the support in `grind` for lambda-expressions.
## Instance canonicalization
Instances are re-synthesized via `synthInstance`. The instance type is first normalized
@@ -63,11 +55,7 @@ produce the same canonical instance. Two special cases:
canonicalized, then the proof is re-synthesized. If resynthesis fails, the original
proof is kept. No definitional-equality check is needed thanks to proof irrelevance.
In both cases, resynthesis failure is silent — the original instance or proof is kept.
Ideally we would report an issue when resynthesis fails inside a type (where structural
agreement matters most), but in practice users provide non-synthesizable instances via `haveI`,
and these instances propagate into types through forward dependencies. Reporting failures
for such instances produces noise that obscures real issues.
Inside types, both cases are strict: resynthesis failure is reported as an issue.
## Two caches
@@ -241,7 +229,7 @@ def checkDefEqInst (e : Expr) (inst : Expr) : SymM Expr := do
return e
return inst
/-- Canonicalize `e`. Applies targeted reductions and re-synthesizes instances. -/
/-- Canonicalize `e`. Applies targeted reductions in type positions; recursively visits value positions. -/
partial def canon (e : Expr) : CanonM Expr := do
match e with
| .forallE .. => withCaching e <| canonForall #[] e
@@ -276,12 +264,11 @@ where
/--
Canonicalize `e : type` where `e` is an instance by trying to resynthesize `type`.
If `report` is `true`, we report an issue when the instance cannot be resynthesized.
We report an issue if the instance cannot be resynthesized.
-/
canonInstCore (e : Expr) (type : Expr) (report := true) : CanonM Expr := do
canonInstCore (e : Expr) (type : Expr) : CanonM Expr := do
let some inst Sym.synthInstance? type |
if report then
reportIssue! "failed to canonicalize instance{indentExpr e}\nfailed to synthesize{indentExpr type}"
reportIssue! "failed to canonicalize instance{indentExpr e}\nfailed to synthesize{indentExpr type}"
return e
checkDefEqInst e inst
@@ -289,18 +276,18 @@ where
Canonicalize an instance by trying to resynthesize it without caching.
Recall that we have special support for `Decidable` and propositional instances.
-/
canonInst' (e : Expr) (report := true) : CanonM Expr := do
canonInst' (e : Expr) : CanonM Expr := do
/-
We normalize the type to make sure `OfNat (Fin (2+1)) 1` and `OfNat (Fin 3) 1` will produce
the same instances.
-/
let type inferType e
let type' canonInsideType' type
canonInstCore e type' report
canonInstCore e type'
/-- `withCaching` + `canonInst'` -/
canonInst (e : Expr) (report := true) : CanonM Expr := withCaching e do
canonInst' e report
canonInst (e : Expr) : CanonM Expr := withCaching e do
canonInst' e
/--
Canonicalize a proposition that is also a term instance.
@@ -313,9 +300,7 @@ where
canonInstProp (g : Expr) (prop : Expr) (h : Expr) (e : Expr) : CanonM Expr := withCaching e do
let prop' canon prop
if ( read).insideType then
/- We suppress reporting here because `haveI`-provided instances propagate into types
through forward dependencies, and reporting them produces noise. See module doc. -/
canonInstCore h prop' (report := false)
canonInstCore h prop'
else
/-
**Note**: We try to resynthesize the proposition, but if it fails we keep the current one.
@@ -337,8 +322,7 @@ where
let prop' canon prop
let type := mkApp (mkConst ``Decidable) prop'
if ( read).insideType then
/- See comment in `canonInstProp` for why we suppress reporting here. -/
canonInstCore inst type (report := false)
canonInstCore inst type
else
/-
**Note**: We try to resynthesize the instance, but if it fails we keep the current one.
@@ -354,12 +338,6 @@ where
canonInstDec (g : Expr) (prop : Expr) (h : Expr) (e : Expr) : CanonM Expr := withCaching e do
canonInstDec' g prop h e
/-- `canonInstDec` variant for normalizing `if-then-else` expressions. -/
canonInstDecCore (e : Expr) : CanonM Expr := do
match_expr e with
| g@Grind.nestedDecidable prop inst => canonInstDec g prop inst e
| _ => canonInst e (report := false)
canonLambda (e : Expr) : CanonM Expr := do
if ( read).insideType then
canonLambdaLoop #[] (etaReduce e)
@@ -440,7 +418,7 @@ where
let c canon c
if isTrueCond c then canon a
else if isFalseCond c then canon b
else return mkApp5 f ( canonInsideType α) c ( canonInstDecCore inst) ( canon a) ( canon b)
else return mkApp5 f ( canonInsideType α) c ( canonInst inst) ( canon a) ( canon b)
canonCond (f : Expr) (α c a b : Expr) : CanonM Expr := do
let c canon c
@@ -481,21 +459,27 @@ where
return e
canonApp (e : Expr) : CanonM Expr := do
match_expr e with
| f@ite α c i a b => canonIte f α c i a b
| f@cond α c a b => canonCond f α c a b
-- Remark: We currently don't normalize dependent-if-then-else occurring in types.
| _ =>
let f := e.getAppFn
let .const declName _ := f | canonAppAndPost e
if ( isMatcher declName) then
canonMatch e
else
canonAppAndPost e
if ( read).insideType then
match_expr e with
| f@ite α c i a b => canonIte f α c i a b
| f@cond α c a b => canonCond f α c a b
-- Remark: We currently don't normalize dependent-if-then-else occurring in types.
| _ =>
let f := e.getAppFn
let .const declName _ := f | canonAppAndPost e
if ( isMatcher declName) then
canonMatch e
else
canonAppAndPost e
else
canonAppDefault e
canonProj (e : Expr) : CanonM Expr := do
let e := e.updateProj! ( canon e.projExpr!)
return ( reduceProj? e).getD e
if ( read).insideType then
return ( reduceProj? e).getD e
else
return e
/--
Returns `true` if `shouldCanon pinfos i arg` is not `.visit`.
@@ -509,8 +493,8 @@ end Canon
/--
Canonicalize `e` by normalizing types, instances, and support arguments.
Applies targeted reductions (projection, match/ite/cond, Nat arithmetic) in all positions;
eta reduction is applied only inside types. Instances are re-synthesized.
Types receive targeted reductions (eta, projection, match/ite, Nat arithmetic).
Instances are re-synthesized. Values are traversed but not reduced.
Runs at reducible transparency.
-/
public def canon (e : Expr) : SymM Expr := do profileitM Exception "sym canon" ( getOptions) do

View File

@@ -44,7 +44,7 @@ def isCbvNoncomputable (p : Name) : CoreM Bool := do
return evalLemmas.isNone && Lean.isNoncomputable ( getEnv) p
/--
Attempts to synthesize `Decidable p` instance and guards against picking up a `noncomputable` instance
Attemps to synthesize `Decidable p` instance and guards against picking up a `noncomputable` instance
-/
def trySynthComputableInstance (p : Expr) : SymM <| Option Expr := do
let .some inst' trySynthInstance (mkApp (mkConst ``Decidable) p) | return .none
@@ -112,7 +112,7 @@ builtin_cbv_simproc ↓ simpIteCbv (@ite _ _ _ _ _) := fun e => do
else if ( isFalseExpr c') then
return .step b (mkApp (e.replaceFn ``ite_cond_eq_false) h) (contextDependent := cd)
else
-- If we got stuck with simplifying `p` then let's try evaluating the original instance
-- If we got stuck with simplifying `p` then let's try evaluating the original isntance
simpAndMatchIteDecidable f α c inst a b do
-- If we get stuck here, maybe the problem is that we need to look at `Decidable c'`
let inst' := mkApp4 (mkConst ``decidable_of_decidable_of_eq) c c' inst h
@@ -317,7 +317,7 @@ public def reduceRecMatcher : Simproc := fun e => do
else
return .rfl
builtin_cbv_simproc simpDecidableRec (@Decidable.rec _ _ _ _ _) :=
builtin_cbv_simproc simpDecidableRec (@Decidable.rec _ _ _ _ _) :=
(simpInterlaced · #[false,false,false,false,true]) >> reduceRecMatcher
def tryMatchEquations (appFn : Name) : Simproc := fun e => do

View File

@@ -272,7 +272,7 @@ def handleProj : Simproc := fun e => do
let reduced Sym.share reduced
return .step reduced ( Sym.mkEqRefl reduced)
| .none =>
-- If we failed to reduce it, we turn to a last resort; we try use heterogeneous congruence lemma that we then try to turn into an equality.
-- If we failed to reduce it, we turn to a last resort; we try use heterogenous congruence lemma that we then try to turn into an equality.
unless ( isDefEq struct e') do
-- If we rewrote the projection body using something that holds up to propositional equality, then there is nothing we can do.
-- TODO: Check if there is a need to report this to a user, or shall we fail silently.

View File

@@ -172,7 +172,7 @@ private partial def addEqStep (lhs rhs proof : Expr) (isHEq : Bool) : GoalM Unit
trueEqFalse := true
else
let hasHEq := isHEq || lhsRoot.heqProofs || rhsRoot.heqProofs
-- **Note**: We only have to check the types if there are heterogeneous equalities.
-- **Note**: We only have to check the types if there are heterogenous equalities.
if ( pure !hasHEq <||> hasSameType lhsRoot.self rhsRoot.self) then
valueInconsistency := true
if (lhsRoot.interpreted && !rhsRoot.interpreted)

View File

@@ -1973,7 +1973,7 @@ def SolverExtension.markTerm (ext : SolverExtension σ) (e : Expr) : GoalM Unit
| .next id' e' sTerms' =>
if id == id' then
-- Skip if `e` and `e'` have different types (e.g., they were merged via `HEq` from `cast`).
-- This can happen when we have heterogeneous equalities in an equivalence class containing types such as `Fin n` and `Fin m`
-- This can happen when we have heterogenous equalities in an equivalence class containing types such as `Fin n` and `Fin m`
if ( pure !root.heqProofs <||> hasSameType e e') then
( solverExtensionsRef.get)[id]!.newEq e e'
return sTerms
@@ -2056,7 +2056,7 @@ where
| .nil => return ()
| .eq solverId lhs rhs rest =>
-- Skip if `lhs` and `rhs` have different types (e.g., they were merged via `HEq` from `cast`).
-- This can happen when we have heterogeneous equalities in an equivalence class containing types such as `Fin n` and `Fin m`
-- This can happen when we have heterogenous equalities in an equivalence class containing types such as `Fin n` and `Fin m`
let root getRootENode lhs
if ( pure !root.heqProofs <||> hasSameType lhs rhs) then
( solverExtensionsRef.get)[solverId]!.newEq lhs rhs

View File

@@ -192,7 +192,7 @@ private def matchEndPos (query : String) (startPos : String.Pos.Raw) : String.Po
startPos + query
@[specialize]
private def highlightStringMatches? (query text : String) (matchPositions : Array String.Pos.Raw)
private def hightlightStringMatches? (query text : String) (matchPositions : Array String.Pos.Raw)
(highlight : α) (offset : String.Pos.Raw := 0) (mapIdx : Nat Nat := id) :
Option (TaggedText α) := Id.run do
if query.isEmpty || text.isEmpty || matchPositions.isEmpty then
@@ -245,7 +245,7 @@ private def advanceTaggedTextHighlightState (text : String) (highlighted : α) :
let query := ( get).query
let p := ( get).p
let ms := ( get).ms
let highlighted? := highlightStringMatches? query text ms highlighted (offset := p)
let highlighted? := hightlightStringMatches? query text ms highlighted (offset := p)
(mapIdx := fun i => ms.size - i - 1)
updateState text highlighted?.isSome
return highlighted?.getD (.text text)

View File

@@ -53,7 +53,7 @@ structure BVDecideConfig where
/--
Split hypotheses of the form `h : (x && y) = true` into `h1 : x = true` and `h2 : y = true`.
This has synergy potential with embedded constraint substitution. Because embedded constraint
substitution is the only use case for this feature it is automatically disabled whenever embedded
subsitution is the only use case for this feature it is automatically disabled whenever embedded
constraint substitution is disabled.
-/
andFlattening : Bool := true

View File

@@ -226,7 +226,7 @@ public:
bool is_unsafe() const;
/** \brief Only definitions have values for the purpose of reduction and
type checking. Theorems used to be like that; now they are treated like
opaque declarations. */
opaque declations. */
bool has_value() const { return is_definition(); }
axiom_val const & to_axiom_val() const { lean_assert(is_axiom()); return static_cast<axiom_val const &>(cnstr_get_ref(raw(), 0)); }

View File

@@ -271,7 +271,7 @@ Returns `true` if the saved trace exists and its hash matches `inputHash`.
If up-to-date, replays the saved log from the trace and sets the current
build action to `replay`. Otherwise, if the log is empty and trace is synthetic,
or if the trace is not up-to-date, the build action will be set to `fetch`.
or if the trace is not up-to-date, the build action will be set ot `fetch`.
-/
public def SavedTrace.replayOrFetchIfUpToDate (inputHash : Hash) (self : SavedTrace) : JobM Bool := do
if let .ok data := self then

View File

@@ -705,7 +705,7 @@ private def Module.restoreAllArtifacts (mod : Module) (cached : ModuleOutputArti
where
@[inline] restoreSome file art? := art?.mapM (restoreArtifact file ·)
public def Module.checkArtifactsExist (self : Module) (isModule : Bool) : BaseIO Bool := do
public def Module.checkArtifactsExsist (self : Module) (isModule : Bool) : BaseIO Bool := do
unless ( self.oleanFile.pathExists) do return false
unless ( self.ileanFile.pathExists) do return false
unless ( self.cFile.pathExists) do return false
@@ -718,7 +718,7 @@ public def Module.checkArtifactsExist (self : Module) (isModule : Bool) : BaseIO
return true
public protected def Module.checkExists (self : Module) (isModule : Bool) : BaseIO Bool := do
self.ltarFile.pathExists <||> self.checkArtifactsExist isModule
self.ltarFile.pathExists <||> self.checkArtifactsExsist isModule
@[deprecated Module.checkExists (since := "2025-03-04")]
public instance : CheckExists Module := Module.checkExists (isModule := false)
@@ -788,7 +788,7 @@ instance : ToOutputJson ModuleOutputArtifacts := ⟨(toJson ·.descrs)⟩
def Module.packLtar (self : Module) (arts : ModuleOutputArtifacts) : JobM Artifact := do
let arts id do
if ( self.checkArtifactsExist arts.isModule) then
if ( self.checkArtifactsExsist arts.isModule) then
return arts
else self.restoreAllArtifacts arts
let args id do
@@ -941,7 +941,7 @@ where
| .inr savedTrace =>
let status savedTrace.replayIfUpToDate' (oldTrace := srcTrace.mtime) mod depTrace
if status.isUpToDate then
unless ( mod.checkArtifactsExist setup.isModule) do
unless ( mod.checkArtifactsExsist setup.isModule) do
mod.unpackLtar mod.ltarFile
else
discard <| mod.buildLean depTrace srcFile setup
@@ -953,7 +953,7 @@ where
mod.computeArtifacts setup.isModule
else
if ( savedTrace.replayIfUpToDate (oldTrace := srcTrace.mtime) mod depTrace) then
unless ( mod.checkArtifactsExist setup.isModule) do
unless ( mod.checkArtifactsExsist setup.isModule) do
mod.unpackLtar mod.ltarFile
mod.computeArtifacts setup.isModule
else

View File

@@ -151,7 +151,7 @@ public def ofDecimal? (s : String) : Option Hash :=
@[inline] public def ofString? (s : String) : Option Hash :=
ofHex? s
/-- Load a hash from a `.hash` file. -/
/-- Laod a hash from a `.hash` file. -/
public def load? (hashFile : FilePath) : BaseIO (Option Hash) :=
ofString? <$> IO.FS.readFile hashFile |>.catchExceptions fun _ => pure none

View File

@@ -356,9 +356,9 @@ USAGE:
COMMANDS:
get [<mappings>] download build outputs into the local Lake cache
put <mappings> upload build outputs to a remote cache
put <mappings> upload build ouptuts to a remote cache
add <mappings> add input-to-output mappings to the Lake cache
clean removes ALL from the local Lake cache
clean removes ALL froms the local Lake cache
services print configured remote cache services
STAGING COMMANDS:
@@ -415,7 +415,7 @@ will search the repository's entire history (or as far as Git will allow).
By default, Lake will download both the input-to-output mappings and the
output artifacts for a package. By using `--mappings-onlys`, Lake will only
download the mappings and delay downloading artifacts until they are needed.
download the mappings abd delay downloading artifacts until they are needed.
If a download for an artifact fails or the download process for a whole
package fails, Lake will report this and continue on to the next. Once done,
@@ -469,7 +469,7 @@ OPTIONS:
--scope=<remote-scope> the prefix of artifacts within the service
--repo=<github-repo> for Reservoir, a GitHub repository scope
Reads a list of input-to-output mappings from the provided file and adds
Reads a list of input-to-output mapppings from the provided file and adds
them to the local Lake cache. If `--service` is provided, the output artifacts
can then be fetched lazily from that service during a Lake build. The service
must either be `reservoir` or be configured through the Lake system

View File

@@ -58,7 +58,7 @@ public structure Env where
If `none`, no suitable system directory for the cache exists.
-/
lakeSystemCache? : Option Cache := none
/-- The path to the system Lake configuration (i.e., `LAKE_CONFIG`). -/
/-- The path to the sytem Lake configuration (i.e., `LAKE_CONFIG`). -/
lakeConfig? : Option FilePath
/-- The authentication key for cache uploads (i.e., `LAKE_CACHE_KEY`). -/
cacheKey? : Option String

View File

@@ -220,7 +220,7 @@ private structure ToolchainCandidate where
fixed : Bool := false
private structure ToolchainState where
/-- The name of dependency which provided the current candidate toolchain. -/
/-- The name of depedency which provided the current candidate toolchain. -/
src : Name
/-- The current candidate toolchain version (if any). -/
tc? : Option ToolchainVer

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More