Commit graph

2585 commits

Author SHA1 Message Date
Sebastian Ullrich
bc5526cacb
fix: widgets broken by overzealous modularization (#9548) 2025-07-25 16:51:18 +00:00
Sebastian Ullrich
ff1d3138bf
refactor: module-ize Lean (#9330) 2025-07-25 12:02:51 +00:00
Kim Morrison
0ab69a32cb
chore: parameterize NoNatZeroDivisors by NatModule instead of HMul (#9527)
This PR changes `Lean.Grind.NoNatZeroDivisors` so that it is
parametrised by a `NatModule` instance rather than just a `HMul`
instance. This is sufficiently general for our purposes, and is a
band-aid (~40% improvement) for the performance problems we've been
seeing coming from inference here. The problems observed in Mathlib may
not see much improvement, however.
2025-07-25 08:46:05 +00:00
Joachim Breitner
6995f280b4
fix: unfold abstracted proofs before processing recursion (#9191)
This PR lets the equation compiler unfold abstracted proofs again if
they would otherwise hide recursive calls.
    
This fixes #8939.

---------

Co-authored-by: Sebastian Ullrich <sebasti@nullri.ch>
2025-07-25 08:00:57 +00:00
Leonardo de Moura
92b870da4a
fix: kernel deep recursion with normalizer (#9522)
This PR uses `withAbstractAtoms` to prevent the kernel from accidentally
reducing the atoms in the arith normlizer while typechecking. This PR
also sets `implicitDefEqProofs := false` in the `grind` normalizer
2025-07-25 04:37:17 +00:00
Rob23oba
e148871087
chore: fix spelling errors (#9175)
(Almost) only typos in constant names and doc-strings were considered;
grammar was not considered. Also, along others,
`mkDefinitionValInferrringUnsafe` has been fixed :-)
2025-07-24 23:35:32 +00:00
Joachim Breitner
2075103cd9
fix: show kernel diagnostics even for examples (#9509)
This PR surfaces kernel diagnostics even in `example`.

The problem was that the kernel checking happens asynchronously. We
cannot use `reportDiag` in `addDecl`, which spawns that task, due to the
module hierarchy. For non `example`-declaration, `reportDiag` is called
somewhere else later, but for `example`, the `withoutModifyingEnv` in
`elabMutualDef` hid the kernel diagnostics. (But only the kernel
diagnostics; they are in the `Environment`, while the others are in the
`State`).

I also observed that the `reportDiag` in `elabAsync` (but not in
`elabSync`) duplicated the reporting, so without `elab.Async true` you
get the message twice. To fix this, `reportDiag` now resets the
diagnostics. This should avoid reporting counts twice in general (at
least within a linear use of the state).

---------

Co-authored-by: Sebastian Ullrich <sebasti@nullri.ch>
2025-07-24 09:21:47 +00:00
Kim Morrison
3cde12567f
feat: add HPow Int field to Field (#9500)
This PR adds a `HPow \a Int \a` field to `Lean.Grind.Field`, and
sufficient axioms to connect it to the operations, so that in future we
can reason about exponents in `grind`. To avoid collisions, we also move
the `HPow \a Nat \a` field in `Semiring` from the extends clause to a
field. Finally, we add some failing tests about normalizing exponents.
2025-07-24 06:00:11 +00:00
Leonardo de Moura
2dce18655d
fix: incorrect proof term in grind linarith (#9487)
This PR fixes an incorrect proof term constructed by `grind linarith`,
as reported in #9485.

closes #9485
2025-07-23 17:34:44 +00:00
Sebastian Ullrich
ddc4cf0a97
refactor: private field use in Meta.Context (#9468)
This PR resolves an issue where the `Meta.Context.configKey` field is
private but we still want to use the constructor of the structure for
setting other fields, which would be prevented by the module system
checks:
```lean
structure Context where
  private config    : Config               := {}
  private configKey : UInt64               := config.toKey
...

def ContextInfo.runMetaM (info : ContextInfo) (lctx : LocalContext) (x : MetaM α) : IO α := do
  -- cannot call private constructor of `Meta.Context`!
  (·.1) <$> info.runCoreM (x.run { lctx := lctx } { mctx := info.mctx })
```
Instead, the private field is extracted into an (existing) structure
that applies its default value:
```lean
/-- Configuration with key produced by `Config.toKey`. -/
structure ConfigWithKey where
  private mk ::
  config : Config := {}
  key    : UInt64 := config.toKey
  
structure Context where
  keyedConfig : ConfigWithKey := default
```
Thus `Context`'s constructor remains public without exposing a way to
set `key` directly.
2025-07-23 08:16:44 +00:00
Leonardo de Moura
aa5b392e35
fix: canonicalization of non-standard OfNat.ofNat terms (#9481)
This PR fixes a kernel type mismatch that occurs when using `grind` on
goals containing non-standard `OfNat.ofNat` terms. For example, in issue
#9477, the `0` in the theorem `range_lower` has the form:
```lean
(@OfNat.ofNat
  (Std.PRange.Bound (Std.PRange.RangeShape.lower (Std.PRange.RangeShape.mk Std.PRange.BoundShape.closed Std.PRange.BoundShape.open)) Nat)
  (nat_lit 0)
  (instOfNatNat (nat_lit 0)))
```
instead of the more standard form:
```lean
(@OfNat.ofNat
  Nat
  (nat_lit 0)
  (instOfNatNat (nat_lit 0)))
```

Closes #9477
2025-07-23 04:10:21 +00:00
Leonardo de Moura
7d2a7dba81
fix: improve evalInt? (#9479)
This PR improves the `evalInt?` function, which is used to evaluate
configuration parameters from the `ToInt` type class. This PR also adds
a new `evalNat?` function for handling the `IsCharP` type class, and
introduces a configuration option:
```
grind (exp := <num>)
```
This option controls the maximum exponent size considered during
expression evaluation. Previously, `evalInt?` used `whnf`, which could
run out of stack space when reducing terms such as `2^1024`.

closes #9427
2025-07-23 01:51:04 +00:00
Leonardo de Moura
64219ac91e
fix: assertNatCast in grind (#9476)
This PR fixes the bridge between `Nat` and `Int` in `grind cutsat`.

Closes #9467
2025-07-22 21:59:38 +00:00
Leonardo de Moura
dedd9275ec
fix: mkCongrSimpCore? (#9472)
This PR fixes another issue at the `congr_simp` theorems that was
affecting Mathlib. Many thanks to Johan Commelin for creating the mwe.

closes #9466
2025-07-22 18:09:24 +00:00
Joachim Breitner
ec13bb963f
fix: PProdN.reduceProjs to also look for projection functions (#9464)
This PR makes `PProdN.reduceProjs` also look for projection functions.
Previously, all redexes were created by the functions in `PProdN`, which
used primitive projections. But with `mkAdmProj` the projection
functions creep in via the types of the `admissible_pprod_fst` theorem.
So let's just reduce both of them.

Fixes #9462.
2025-07-22 09:22:50 +00:00
Henrik Böving
09de5cd70e
refactor: remove Lean.RBMap usages (#9260)
This PR removes uses of `Lean.RBMap` in Lean itself.

Furthermore some massaging of the import graph is done in order to avoid
having `Std.Data.TreeMap.AdditionalOperations` (which is quite
expensive) be the critical path for a large chunk of Lean. In particular
we can build `Lean.Meta.Simp` and `Lean.Meta.Grind` without it thanks to
these changes.

We did previously not conduct this change as `Std.TreeMap` was not
outperforming `Lean.RBMap` yet, however this has changed with the new
code generator.
2025-07-21 14:04:45 +00:00
Joachim Breitner
fcd60e73f8
fix: use withIncRecDepth in SizeOf deriving (#9448)
This PR addresses the lean crash (stack overflow) with nested induction
and the generation of the `SizeOf` spec lemmas, reported at #9018.

It does not address the underlying issue that in these cases, the
generated SizeOf code does not match the the SizeOf function found by
instance search, and thus the generation fails.

This seem hard to fix: `mkSizeOfMinors` would have to recognize that
given, say, `List (Id Tree)`, the derived instance (assuming there was
one for `Tree`) is not the same as for `List Tree`.

The problem seems just about as hard as getting derived SizeOf right in
the presence of nested induction and non-canonical SizeOf instances.
2025-07-21 12:43:19 +00:00
jrr6
34bd6e8bfd
feat: improve split error messages (#9424)
This PR improves the error messages produced by the `split` tactic,
including suggesting syntax fixes and related tactics with which it
might be confused.

Note that, to avoid clashing with the new error message styling
conventions used in these messages, this PR also updates the formatting
of the message produced by `throwTacticEx`.

Closes #6224
2025-07-18 22:36:10 +00:00
jrr6
5f4e6a86d5
feat: update and explain "unknown constant" and "failed to infer type" errors (#9423)
This PR updates the formatting of, and adds explanations for, "unknown
identifier" errors as well as "failed to infer type" errors for binders
and definitions.

It attempts to ameliorate some of the confusion encountered in #1592 by
modifying the wording of the "header is elaborated before body is
processed" note and adding further discussion and examples of this
behavior in the corresponding error explanation.
2025-07-18 19:20:31 +00:00
Leonardo de Moura
65abbd90bf
perf: isArrowProposition (#9414)
This PR increases the number of cases where `isArrowProposition` returns
a result other than `.undef`. This function is used to implement the
`isProof` predicate, which is invoked on every subterm visited by
`simp`.
2025-07-17 04:12:15 +00:00
jrr6
fb462fdf9e
feat: add named argument hints (#9315)
This PR adds improves the "invalid named argument" error message in
function applications and match patterns by providing clickable hints
with valid argument names. In so doing, it also fixes an issue where
this error message would erroneously flag valid match-pattern argument
names.
2025-07-17 03:22:25 +00:00
Sebastian Ullrich
f94d7b333a
fix: do not export private instances (#9407)
Fixes #9383
2025-07-16 18:59:48 +00:00
Leonardo de Moura
d7ef2880c8
perf: avoid "dependent implications" as local E-matching theorems in grind (#9408)
This PR implements a simple optimization: dependent implications are no
longer treated as E-matching theorems in `grind`. In
`grind_bitvec2.lean`, this change saves around 3 seconds, as many
dependent implications are generated. Example:
```lean
 ∀ (h : i + 1 ≤ w), x.abs.getLsbD i = x.abs[i]
 ```
2025-07-16 17:13:52 +00:00
Sebastian Ullrich
2584b6abf9
fix: assorted module system fixes (#9406)
Encountered when porting `Std` and `Lean`
2025-07-16 13:31:08 +00:00
Leonardo de Moura
e286f20179
perf: avoid inferType at simpArith (#9398)
This PR avoids the expensive `inferType` call in `simpArith`. It also
cleans up some of the code and removes anti-patterns.
2025-07-16 03:42:26 +00:00
Leonardo de Moura
dc2f256448
fix: bug at mkCongrSimpCore? (#9395)
This PR fixes a bug at `mkCongrSimpCore?`. It fixes the issue reported
by @joehendrix at #9388.
The fix is just commit: afc4ba617fe2ca5828e0e252558d893d7791d56b. The
rest of the PR is just cleaning up the file.

closes #9388
2025-07-16 00:54:31 +00:00
jrr6
e9a318df16
fix: reorder "application type mismatch" message (#9287)
This PR rewords the "application type mismatch" error message so that
the argument and its type precede the application expression.
2025-07-15 19:20:18 +00:00
Leonardo de Moura
166d1c0dab
perf: avoid isDefEq test at simpEq simproc used in grind (#9385)
This PR replaces the `isDefEq` test in the `simpEq` simproc used in
`grind`. It is too expensive.
2025-07-15 18:38:11 +00:00
Leonardo de Moura
96e7ab078d
fix: performance issue when elaborating match-expressions with many literals (#9372)
This PR fixes a performance issue that occurs when generating equation
lemmas for functions that use match-expressions containing several
literals. This issue was exposed by #9322 and arises from a combination
of factors:

1. Literal values are compiled into a chain of dependent if-then-else
expressions.
2. Dependent if-then-else expressions are significantly more expensive
to simplify than regular ones.
3. The `split` tactic selects a target, splits it, and then invokes
`simp` on the resulting subgoals. Moreover, `simp` traverses the entire
goal bottom-up and does not stop after reaching the target.

This PR addresses the issue by introducing a custom simproc that avoids
recursively simplifying nested if-then-else expressions. It does **not**
alter the user-facing behavior of the `split` tactic because such a
change would be highly disruptive. Instead, the PR adds a new flag,
`backward.split` to control the behavior of the user-facing `split`
tactic. It is currently set to `true`, i.e., the old behavior is still
the default one. In a future PR, we should set this flag to `false` by
default and begin repairing all affected proofs.

closes #9322
2025-07-15 03:52:23 +00:00
Leonardo de Moura
a4b5eecb8e
perf: skip unnecessary preprocessing steps in grind when possible (#9369)
This PR optimizes the `grind` preprocessor by skipping unnecessary steps
when possible.
2025-07-14 22:05:02 +00:00
Leonardo de Moura
cfb13b1689
perf: add unfoldReducible' using inShareCommon (#9367)
This PR implements a minor optimization to the `grind` preprocessor.
2025-07-14 19:04:04 +00:00
Leonardo de Moura
bcc6fb54c2
perf: use inShareCommon to skip preprocessing steps (#9351)
This PR optimizes the `grind` preprocessing steps by skipping steps when
the term is already present in the hash-consing table.
2025-07-14 04:53:49 +00:00
Leonardo de Moura
d642880b7d
chore: remove leftovers (#9347)
after update stage0
2025-07-14 00:40:32 +00:00
Leonardo de Moura
c7b4d843e2
refactor: support for Nat in grind cutsat (#9340)
This PR modifies the encoding from `Nat` to `Int` used in `grind
cutsat`. It is simpler, more extensible, and similar to the generic
`ToInt`. After update stage0, we will be able to delete the leftovers.
2025-07-13 23:40:03 +00:00
Leonardo de Moura
243bbd74a5
chore: compilation time for EMatch.lean (#9334)
This PR improves the compilation time for `EMatch.lean`
2025-07-12 22:01:16 +00:00
Leonardo de Moura
ae2a9b4688
perf: propagateEqUp (#9326)
This PR optimizes `propagateEqUp` used in `grind`.
2025-07-12 03:09:59 +00:00
Leonardo de Moura
d36fc8df67
perf: propagateBoolDiseq (#9325)
This PR optimizes the Boolean disequality propagator used in `grind`.
2025-07-12 02:20:48 +00:00
Leonardo de Moura
6c20cd08f1
perf: isDiseq and mkDiseqProof? in grind (#9324)
This PR improves the functions for checking whether two terms are
disequal in `grind`
2025-07-12 01:26:48 +00:00
Leonardo de Moura
0fdb63f258
perf: use mkCongrSimpForConst? (#9305)
This PR uses the `mkCongrSimpForConst?` API in `simp` to reduce the
number of times the same congruence lemma is generated. Before this PR,
`grind` would spend `1.5`s creating congruence theorems during
normalization in the `grind_bitvec2.lean` benchmark. It now spends
`0.6`s. This PR should make an even bigger difference after we merge
#9300.
2025-07-11 02:29:20 +00:00
Leonardo de Moura
4520206f4a
chore: minor perf improvement (#9296) 2025-07-10 05:41:54 +00:00
Leonardo de Moura
62dc8d64fa
perf: use custom reduceCtorEq simproc in grind (#9293)
This PR replaces the `reduceCtorEq` simproc used in `grind` by a much
more efficient one. The default one use in `simp` is just overhead
because the `grind` normalizer is already normalizing arithmetic.
In a separate PR, we will push performance improvements to the default
`reduceCtorEq`.
2025-07-10 03:18:44 +00:00
Leonardo de Moura
4955dde748
perf: grind normalizer (#9271)
This PR improves the performance of the formula normalizer used in
`grind`.
2025-07-09 03:49:44 +00:00
Leonardo de Moura
192c0c8e67
perf: skip canonicalization of Decidable instances and add congruence-closure support (#9267)
This PR optimizes support for `Decidable` instances in `grind`. Because
`Decidable` is a subsingleton, the canonicalizer no longer wastes time
normalizing such instances, a significant performance bottleneck in
benchmarks like `grind_bitvec2.lean`. In addition, the
congruence-closure module now handles `Decidable` instances, and can
solve examples such as:
```lean
example (p q : Prop) (h₁ : Decidable p) (h₂ : Decidable (p ∧ q)) : (p ↔ q) → h₁ ≍ h₂ := by
  grind
```
2025-07-08 21:55:40 +00:00
Sebastian Graf
77442f5486
chore: revert DefEq changes until it has passed proper review (#9254) 2025-07-08 14:54:18 +00:00
Sebastian Graf
0b2bdaebd6
fix: More stuck definitional equalities involving smart unfoldings (#8766) (#9015)
This PR makes `isDefEq` detect more stuck definitional equalities
involving smart unfoldings. Specifically, if `t =?= defn ?m` and `defn`
matches on its argument, then this equality is stuck on `?m`. Prior to
this change, we would not see this dependency and simply return `false`.

Fixes #8766.

Co-authored-by: Kyle Miller <kmill31415@gmail.com>
2025-07-08 12:56:50 +00:00
Kyle Miller
ac600853c0
fix: let the congr tactic handle "under-applied" applications (#9225)
This PR improves the `congr` tactic so that it can handle function
applications with fewer arguments than the arity of the head function.
This also fixes a bug where `congr` could not make progress with
`Set`-valued functions in Mathlib, since `Set` was being unfolded and
making such functions have an apparently higher arity.

This addresses issue #2128 for the `congr` tactic, but not `simp` and
others.
2025-07-08 11:48:08 +00:00
Leonardo de Moura
cf6a182f69
chore: profile grind satellite solvers (#9246) 2025-07-08 05:05:39 +00:00
Leonardo de Moura
655c7ab548
perf: optimize instance generation in grind linarith (#9244)
This PR improves the instance generation in the `grind linarith` module.
2025-07-08 05:04:06 +00:00
Leonardo de Moura
05630fc149
perf: synthesize ToInt instances on demand (#9241)
This PR ensures that the type class instances used to implement the
`ToInt` adapter (in `grind cutsat`) are generated on demand.
2025-07-08 02:36:16 +00:00
Paul Reichert
98e4b2882f
refactor: migrate to new ranges (#8841)
This PR migrates usages of `Std.Range` to the new polymorphic ranges.

This PR unfortunately increases the transitive imports for
frequently-used parts of `Init` because the ranges now rely on iterators
in order to provide their functionality for types other than `Nat`.
However, iteration over ranges in compiled code is as efficient as
before in the examples I checked. This is because of a special
`IteratorLoop` implementation provided in the PR for this purpose.

There were two issues that were uncovered during migration:

* In `IndPredBelow.lean`, migrating the last remaining range causes
`compilerTest1.lean` to break. I have minimized the issue and came to
the conclusion it's a compiler bug. Therefore, I have not replaced said
old range usage yet (see #9186).
* In `BRecOn.lean`, we are publicly importing the ranges. Making this
import private should theoretically work, but there seems to be a
problem with the module system, causing the build to panic later in
`Init.Data.Grind.Poly` (see #9185).
* In `FuzzyMatching.lean`, inlining fails with the new ranges, which
would have led to significant slowdown. Therefore, I have not migrated
this file either.
2025-07-07 12:41:53 +00:00