Commit graph

39036 commits

Author SHA1 Message Date
Leonardo de Moura
b82f969e5b
feat: add Sym.Simp.Theorem.rewrite? (#11868)
This PR implements `Sym.Simp.Theorem.rewrite?` for rewriting terms using
equational theorems in `Sym`.
2026-01-02 02:23:37 +00:00
Leonardo de Moura
97c23abf8e
feat: main loop for Sym.simp (#11866)
This PR implements the core simplification loop for the `Sym` framework,
with efficient congruence-based argument rewriting.
2026-01-01 23:21:22 +00:00
Leonardo de Moura
ef9777ec0d
feat: add getCongrInfo to Sym (#11860)
This PR adds `CongrInfo` analysis for function applications in the
symbolic simulator framework. `CongrInfo` determines how to build
congruence proofs for rewriting subterms efficiently, categorizing
functions into:

- `none`: no arguments can be rewritten (e.g., proofs)
- `fixedPrefix`: common case where implicit/instance arguments form a
fixed prefix and explicit arguments can be rewritten (e.g., `HAdd.hAdd`,
`Eq`)
- `interlaced`: rewritable and non-rewritable arguments alternate (e.g.,
`HEq`)
- `congrTheorem`: uses auto-generated congruence theorems for functions
with dependent proof arguments (e.g., `Array.eraseIdx`)
2026-01-01 17:27:08 +00:00
Henrik Böving
b7360969ed
feat: bv_decide can handle structure fields with parametric width (#11858)
This PR changes `bv_decide`'s heuristic for what kinds of structures to
split on to also allow
splitting on structures where the fields have dependently typed widths.
For example:
```lean
structure Byte (w : Nat) where
  /-- A two's complement integer value of width `w`. -/
  val : BitVec w
  /-- A per-bit poison mask of width `w`. -/
  poison : BitVec w
```
This is to allow handling situations such as `(x : Byte 8)` where the
width becomes concrete after
splitting is done.
2026-01-01 13:36:33 +00:00
Leonardo de Moura
9b1b932242
feat: add shareCommonInc (#11857)
This PR adds an incremental variant of `shareCommon` for expressions
constructed from already-shared subterms. We use this when an expression
`e` was produced by a Lean API (e.g., `inferType`, `mkApp4`) that does
not preserve maximal sharing, but the inputs to that API were already
maximally shared. Unlike `shareCommon`, this function does not use a
local `Std.HashMap ExprPtr Expr` to track visited nodes. This is more
efficient when the number of new (unshared) nodes is small, which is the
common case when wrapping API calls that build a few constructor nodes
around shared inputs.
2026-01-01 05:40:33 +00:00
Leonardo de Moura
d4563a818f
feat: simplifier for Sym (#11856)
This PR adds the basic infrastructure for the structural simplifier used
by the symbolic simulation (`Sym`) framework.
2026-01-01 04:34:50 +00:00
Paul Reichert
e8781f12c0
feat: use MonadAttach in the takeWhileM and dropWhileM iterator combinators (#11852)
This PR changes the definition of the iterator combinators `takeWhileM`
and `dropWhileM` so that they use `MonadAttach`. This is only relevant
in rare cases, but makes it sometimes possible to prove such combinators
finite when the finiteness depends on properties of the monadic
predicate.
2025-12-31 12:38:21 +00:00
Leonardo de Moura
1ca4faae18
fix: Sym.intro for have-declarations (#11851)
This PR fixes `Sym/Intro.lean` support for `have`-declarations.
2025-12-31 01:36:23 +00:00
Leonardo de Moura
3a5887276c
fix: handle assigned metavariables during pattern matching (#11850)
This PR fixes a bug in the new pattern matching procedure for the Sym
framework. It was not correctly handling assigned metavariables during
pattern matching.

It also improves the support for free variables.
2025-12-31 00:50:55 +00:00
Leonardo de Moura
e086b9b5c6
fix: zetaDelta at Sym/Pattern.lean (#11849)
This PR fixes missing zetaDelta support at the pattern
matching/unification procedure in the new Sym framework.
2025-12-30 23:47:22 +00:00
Leonardo de Moura
16ae74e98e
fix: bug at Name.beq (#11848)
This PR fixes a bug at `Name.beq` reported by
gasstationcodemanager@gmail.com
2025-12-30 18:22:47 +00:00
Henrik Böving
2a28cd98fc
feat: allow bv_decide users to configure the SAT solver (#11847)
This PR adds a new `solverMode` field to `bv_decide`'s configuration,
allowing users to configure
the SAT solver for different kinds of workloads.
2025-12-30 13:17:20 +00:00
Leonardo de Moura
bba35e4532
perf: add performance comparison tests for SymM vs MetaM (#11838)
This PR adds performance comparison tests between the new `SymM` monad
and the standard `MetaM` for `intros`/`apply` operations.

The tests solve problems of the form:
```lean
let z := 0; ∀ x, ∃ y, x = z + y ∧ let z := z + x; ∀ x, ∃ y, x = z + y ∧ ... ∧ True
```
using repeated `intros` and `apply` with `Exists.intro`, `And.intro`,
`Eq.refl`, and `True.intro`.

**Results show 10-20x speedup:**

| Size | MetaM | SymM | Speedup |
|------|-------|------|---------|
| 1000 | 226ms | 21ms | 10.8x |
| 2000 | 582ms | 44ms | 13.2x |
| 3000 | 1.08s | 72ms | 15.0x |
| 4000 | 1.72s | 101ms | 17.0x |
| 5000 | 2.49s | 125ms | 19.9x |
| 6000 | 3.45s | 157ms | 22.0x |
2025-12-30 02:42:04 +00:00
Leonardo de Moura
17581a2628
feat: add backward chaining rule application to Sym (#11837)
This PR adds `BackwardRule` for efficient goal transformation via
backward chaining in `SymM`.

`BackwardRule` stores a theorem expression, precomputed pattern for
fast unification, and argument indices that become new subgoals. The
subgoal ordering lists non-dependent goals first to match the behavior
of `MetaM.apply`.

`BackwardRule.apply` unifies the goal type with the rule's pattern,
assigns the goal metavariable to the theorem application, and returns
new subgoals for unassigned arguments.
2025-12-30 00:23:08 +00:00
Paul Reichert
05664b15a3
fix: update naming of FinitenessRelation fields in the sigmaIterator.lean benchmark (#11836)
This PR fixes a broken benchmark that uses an outdated naming of
`FinitenessRelation` and `ProductivenessRelation`'s fields.
2025-12-29 23:13:13 +00:00
Paul Reichert
1590a72913
feat: make FinitenessRelation part of the public API (#11789)
This PR makes the `FinitenessRelation` structure, which is helpful when
proving the finiteness of iterators, part of the public API. Previously,
it was marked internal and experimental.
2025-12-29 20:45:41 +00:00
Leonardo de Moura
f77ce8c669
doc: expand PR creation guidelines in CLAUDE.md (#11835)
This PR expands the pull request creation section with detailed
formatting guidelines including title format (type prefixes, imperative
present tense) and body format requirements (starting with "This PR").
Adds a concrete example for reference.

All modifications were suggested by Claude.
2025-12-29 17:42:28 +00:00
Leonardo de Moura
4e1a2487b7
feat: add optional binder limit to mkPatternFromTheorem (#11834)
This PR adds `num?` parameter to `mkPatternFromTheorem` to control how
many leading quantifiers are stripped when creating a pattern. This
enables matching theorems where only some quantifiers should be
converted to pattern variables.

For example, to match `mk_forall_and : (∀ x, P x) → (∀ x, Q x) → (∀ x, P
x ∧ Q x)` against a goal `∀ x, q x 0 ∧ q (f (f x)) y`, we use
`mkPatternFromTheorem ``mk_forall_and (some 5)` to create the pattern `∀
x, ?P x ∧ ?Q x`, keeping the outermost `∀` in the pattern rather than
converting it to a pattern variable.
2025-12-29 17:38:50 +00:00
Leonardo de Moura
b60556af4e
chore: Sym cleanup (#11833)
This PR fixes a few typos, adds missing docstrings, and adds a (simple)
missing optimization.
2025-12-29 17:07:56 +00:00
Leonardo de Moura
2bca310bea
feat: efficient pattern matching and unification for the symbolic simulation framework (#11825)
This PR completes the new pattern matching and unification procedures
for the symbolic simulation framework using a two-phase approach.

**Phase 1 (Syntactic Matching):**
- Patterns use de Bruijn indices for expression variables and renamed
level params for universe variables
- Purely structural matching after reducible definitions are unfolded
- Universe levels treat `max`/`imax` as uninterpreted functions
- Proof arguments skipped via proof irrelevance
- Instance and binder constraints deferred to Phase 2

**Phase 2 (Pending Constraints):**
- Level constraints: structural equality with mvar assignment
- Instance constraints: `isDefEqI` (full `isDefEq` for TC synthesis)
- Expression constraints: `isDefEqS` with Miller pattern support
- Unassigned instance pattern variables synthesized via
`trySynthInstance`

**`isDefEqS` (Structural DefEq):**
- Miller pattern detection and assignment (`?m x y z := rhs` → `?m :=
fun x y z => rhs`)
- Scope checking via `maxFVar` to prevent out-of-scope assignments
- Optional zeta-delta reduction for let-declarations
- Proof irrelevance and instance delegation to `isDefEqI`

**Key optimizations:**
- `abstractFVars` skips metavariables and uses `maxFVar` for early
cutoff
- Per-pattern `ProofInstInfo` cache for fast argument classification
- Maximal sharing.
2025-12-29 05:18:16 +00:00
Leonardo de Moura
5042c8cc37
feat: isDefEqS, a lightweight structural definitional equality for the symbolic simulation framework (#11824)
This PR implements `isDefEqS`, a lightweight structural definitional
equality for the symbolic simulation framework. Unlike the full
`isDefEq`, it avoids expensive operations while still supporting Miller
pattern unification.

**Key features:**
- Structural matching with optional zeta-delta reduction for
let-declarations
- Miller pattern detection and assignment (`?m x y z := rhs` → `?m :=
fun x y z => rhs`)
- Scope checking via `maxFVar` to prevent out-of-scope assignments
- Proof arguments skipped via proof irrelevance
- Instance arguments delegated to full `isDefEq` (need TC machinery)
- Universe levels treated structurally (`max`/`imax` as uninterpreted)
2025-12-29 03:17:18 +00:00
Leonardo de Moura
1e99ff1dba
feat: optimized abstractFVars and abstractFVarsRange (#11820)
This PR adds optimized `abstractFVars` and `abstractFVarsRange` for
converting free variables to de Bruijn indices during pattern
matching/unification.

**Optimizations:**
- Metavariables are skipped (their contexts must not include abstracted
fvars)
- Subterms whose `maxFVar` is below the minimal abstracted fvar are
skipped via early cutoff
- Results are maximally shared via `AlphaShareBuilderM`

These optimizations are sound for Miller pattern matching where
metavariables are created before entering binders.
2025-12-28 23:12:21 +00:00
Leonardo de Moura
48bb954e4e
feat: structural isDefEq for Sym (#11819)
This PR adds some basic infrastructure for a structural (and cheaper)
`isDefEq` predicate for pattern matching and unification in `Sym`.
2025-12-28 22:37:21 +00:00
Leonardo de Moura
96160e553a
feat: skip proof and instance arguments during pattern matching (#11815)
This PR optimizes pattern matching by skipping proof and instance
arguments during Phase 1 (syntactic matching).
2025-12-28 05:23:32 +00:00
Leonardo de Moura
18702bdd47
feat: add instantiateRevBetaS (#11814)
This PR implements `instantiateRevBetaS`, which is similar to
`instantiateRevS` but beta-reduces nested applications whose function
becomes a lambda after substitution.

For example, if `e` contains a subterm `#0 a` and we apply the
substitution `#0 := fun x => x + 1`, then `instantiateRevBetaS` produces
`a + 1` instead of `(fun x => x + 1) a`.

This is useful when applying theorems. For example, when applying
`Exists.intro`:
```lean
Exists.intro.{u} {α : Sort u} {p : α → Prop} (w : α) (h : p w) : Exists p
```
to a goal of the form `∃ x : Nat, p x ∧ q x`, we create metavariables
`?w` and `?h`. With `instantiateRevBetaS`, the type of `?h` becomes `p
?w ∧ q ?w` instead of `(fun x => p x ∧ q x) ?w`.
2025-12-28 03:28:15 +00:00
Leonardo de Moura
4eaaadf1c1
feat: add pattern matching/unification for symbolic simulation (#11813)
This PR introduces a fast pattern matching and unification module for
the symbolic simulation framework (`Sym`). The design prioritizes
performance by using a two-phase approach:

**Phase 1 (Syntactic Matching)**
- Patterns use de Bruijn indices for expression variables and renamed
level params (`_uvar.0`, `_uvar.1`, ...) for universe variables
- Matching is purely structural after reducible definitions are unfolded
during preprocessing
- Universe levels treat `max` and `imax` as uninterpreted functions (no
AC reasoning)
- Binders and term metavariables are deferred to Phase 2

**Phase 2 (Pending Constraints)** [WIP]
- Handles binders (Miller patterns) and metavariable unification
- Converts remaining de Bruijn variables to metavariables
- Falls back to `isDefEq` when necessary

**Key design decisions:**
- Preprocessing unfolds reducible definitions and performs beta/zeta
reduction
- Kernel projections are expected to be folded as projection
applications before matching
- Assignment conflicts are deferred to pending rather than invoking
`isDefEq` inline
- `instantiateRevS` ensures maximal sharing of result expressions

**TODO:**
- Skip instance arguments during matching, synthesize later
- Skip proof arguments (proof irrelevance)
- Implement `processPending` for Phase 2 constraints
2025-12-28 01:44:36 +00:00
Leonardo de Moura
2234c91163
feat: add TransparencyMode.none (#11810)
This PR adds a new transparency mode `.none` in which no definitions are
unfolded.
2025-12-27 03:10:17 +00:00
Lean stage0 autoupdater
4f7ba5eb09 chore: update stage0 2025-12-27 03:18:33 +00:00
Sofia Rodrigues
da70626e64
fix: Signal.Handler segmentation fault with Selector (#11724)
This PR adds more `event_loop_lock`s to fix race conditions.
2025-12-27 02:07:00 +00:00
Leonardo de Moura
214acc921c
refactor: Goal in grind (#11806)
This PR refactors the `Goal` type used in `grind`. The new
representation allows multiple goals with different metavariables to
share the same `GoalState`. This is useful for automation such as
symbolic simulator, where applying theorems create multiple goals that
inherit the same E-graph, congruence closure and solvers state, and
other accumulated facts.
2025-12-26 23:39:13 +00:00
Robert J. Simmons
f483c6c10f
refactor: move error explanation text to the manual (#11688)
This PR removes error explanation text from the manual, as this content
is now directly incorporated in the manual by
leanprover/reference-manual#704.
2025-12-26 17:14:58 +00:00
Leonardo de Moura
c0d5e8bc2c
feat: intro tactic for SymM (#11803)
This PR implements `intro` (and its variants) for `SymM`. These versions
do not use reduction or infer types, and ensure expressions are
maximally shared.
2025-12-26 03:45:33 +00:00
Leonardo de Moura
c02f570b76
feat: add instantiateS and variants (#11802)
This PR adds the function `Sym.instantiateS` and its variants, which are
similar to `Expr.instantiate` but assumes the input is maximally shared
and ensures the output is also maximally shared.
2025-12-25 23:02:16 +00:00
Leonardo de Moura
19d16ff9b7
feat: add replaceS, liftLooseBVarsS, and lowerBVarsS (#11800)
This PR adds the function `Sym.replaceS`, which is similar to
`replace_fn` available in the kernel but assumes the input is maximally
shared and ensures the output is also maximally shared. The PR also
generalizes the `AlphaShareBuilder` API.
2025-12-25 20:16:45 +00:00
Leonardo de Moura
58420f9416
refactor: simplify AlphaShareCommon.State (#11797)
This PR simplifies `AlphaShareCommon.State` by separating the persistent
and transient parts of the state.

The `map` field caches visited sub-expressions during a single
`shareCommonAlpha` call to handle DAGs efficiently, the input expression
may contain shared sub-expressions that are not yet maximally shared.
However, this cache does not need to persist between different
`shareCommonAlpha` calls.

**Changes:**
- Moved `map` from the persistent `AlphaShareCommon.State` to a private
`State` used only within individual `shareCommonAlpha` calls.
- Replaced `PHashMap ExprPtr Expr` with (the more efficient)
`Std.HashMap ExprPtr Expr` for `map`, since it is now local to each call
and does not need persistence.
- The public `AlphaShareCommon.State` now only contains the `set` of
alpha-equivalent expressions that should persist
2025-12-25 18:06:34 +00:00
Leonardo de Moura
b3b33e85d3
feat: add Sym.getMaxFVar? (#11794)
This PR implements the function `getMaxFVar?` for implementing `SymM`
primitives.
2025-12-25 02:24:00 +00:00
Leonardo de Moura
723acce2a7
feat: add AlphaShareBuilder (#11793)
This PR adds functions for creating maximally shared terms from
maximally shared terms. It is more efficient than creating an expression
and then invoking `shareCommon`. We are going to use these functions for
implementing the symbolic simulation primitives.
2025-12-25 00:05:03 +00:00
Leonardo de Moura
e765138bb4
chore: add isDebugEnabled to grind (#11792)
This PR adds `isDebugEnabled` for checking whether `grind.debug` is set
to `true` when `grind` was initialized.
2025-12-24 23:32:27 +00:00
Leonardo de Moura
501375f340
feat: add SymM monad (#11788)
This PR introduces `SymM`, a new monad for implementing symbolic
simulators (e.g., verification condition generators) in Lean. The monad
addresses performance issues found in symbolic simulators built on top
of user-facing tactics like `apply` and `intros`.

**Key features:**
- Goals are represented by `Grind.Goal` objects, enabling incremental
hypothesis processing
- No `revert` or `clear` operations, allowing O(1) local context checks
instead of O(n log n)
- Carries `GrindM` state across goals to avoid reprocessing shared
hypotheses
- Provides `mkGoal` for creating new goals within the monad

This is the foundational infrastructure for `SymM`. Future PRs will add
operations like `intro`, `apply`, and the optimized definitional
equality test.
2025-12-24 04:05:14 +00:00
Leonardo de Moura
ce56e2139e
feat: support for incrementally processing hypotheses in grind (#11787)
This PR adds support for incrementally processing local declarations in
`grind`. Instead of processing all hypotheses at once during goal
initialization, `grind` now tracks which local declarations have been
processed via `Goal.nextDeclIdx` and provides APIs to process new
hypotheses incrementally.
This feature will be used by the new `SymM` monad for efficient symbolic
simulation.
2025-12-24 02:50:22 +00:00
Henrik Böving
c34e4cf0f7
perf: disable closed term extraction in bv_decide (#11785)
This PR disables closed term extraction in the reflection terms used by
`bv_decide`. These terms do
not profit at all from closed term extraction but can in practice cause
thousands of new closed term
declarations which in turn slows down the compiler.
2025-12-23 23:22:12 +00:00
Leonardo de Moura
f2c9fcc0b2
feat: add optional start position to PersistentArray.forM (#11784)
This PR just adds an optional start position argument to
`PersistentArray.forM`
2025-12-23 22:12:02 +00:00
Sebastian Ullrich
950a2b7896
chore: ensure every pkg/ test has a correct lean-toolchain file (#11782) 2025-12-23 17:17:22 +00:00
Henrik Böving
88f17dee71
perf: tune the behavior of and flattening in bv_decide (#11781)
This PR improves the performance of and flattening in `bv_decide`.

The two main insights of this PR are:
1. When embedded constraint substitution is disabled it makes no sense
to have and flattening on in
   the first place, given that we do not profit from it in any way.
2. The new fvars produced by and flattening can also be inserted into
the rewriting caches of the
preprocessing pipeline if the fvar they were derived from is already in
the cache. This
drastically decreases the amount of work we have to do in the second
rewriting pass after running
   and flattening.
2025-12-23 13:08:31 +00:00
Henrik Böving
4d2647f9c7
fix: foldlM mismatch part 2 (#11779)
This PR fixes an oversight in the initial #11772 PR.

Closes #11778.
2025-12-23 10:29:20 +00:00
Leonardo de Moura
a471f005d6
feat: add [grind norm] and [grind unfold] attributes (#11776)
This PR adds the attributes `[grind norm]` and `[grind unfold]` for
controlling the `grind` normalizer/preprocessor.

The `norm` modifier instructs `grind` to use a theorem as a
normalization rule. That is, the theorem is applied during the
preprocessing step. This feature is meant for advanced users who
understand how the preprocessor and `grind`'s search procedure interact
with each other.
New users can still benefit from this feature by restricting its use to
theorems that completely eliminate a symbol from the goal. Example:
```lean
theorem max_def : max n m = if n ≤ m then m else n
```
For a negative example, consider:
```lean
opaque f : Int → Int → Int → Int
theorem fax1 : f x 0 1 = 1 := sorry
theorem fax2 : f 1 x 1 = 1 := sorry
attribute [grind norm] fax1
attribute [grind =] fax2

example (h : c = 1) : f c 0 c = 1 := by
  grind -- fails
```
In this example, `fax1` is a normalization rule, but it is not
applicable to the input goal since `f c 0 c` is not an instance of `f x
0 1`. However, `f c 0 c` matches the pattern `f 1 x 1` modulo the
equality `c = 1`. Thus, `grind` instantiates `fax2` with `x := 0`,
producing the equality `f 1 0 1 = 1`, which the normalizer simplifies to
`True`. As a result, nothing useful is learned. In the future, we plan
to include linters to automatically detect issues like these. Example:
```lean
opaque f : Nat → Nat
opaque g : Nat → Nat

@[grind norm] axiom fax : f x = x + 2
@[grind norm ←] axiom fg : f x = g x

example : f x ≥ 2 := by grind
example : f x ≥ g x := by grind
example : f x + g x ≥ 4 := by grind
```

The `unfold` modifier instructs `grind` to unfold the given definition
during the preprocessing step. Example:
```lean
@[grind unfold] def h (x : Nat) := 2 * x
example : 6 ∣ 3*h x := by grind
```
2025-12-23 03:54:35 +00:00
Leonardo de Moura
f6a25b13b9
chore: grind cleanup (#11775) 2025-12-22 23:49:14 +00:00
Henrik Böving
a847b13b1a
fix: implemented_by Array.foldlM behavior when stop > start (#11774)
This PR fixes a mismatch between the behavior of `foldlM` and
`foldlMUnsafe` in the three array
types. This mismatch is only exposed when manually specifying a `stop`
value greater than the size
of the array and only exploitable through `native_decide`.

The mismatch was introduced as part of
4ba21ea10c which introduced
`foldlMUnsafe` and thus likely a mistake when building the `unsafe`
implementation instead of a
specification mistake.

Closes #11773
2025-12-22 23:46:45 +00:00
Leonardo de Moura
186a81627b
fix: Array.foldlMUnsafe bug (#11772)
This PR a bug in the optimized and unsafe implementation of
`Array.foldlM`.

Issue was reported here:

https://leanprover.zulipchat.com/#narrow/channel/113488-general/topic/Array.2Efoldl.20bug.20.28can.20prove.20False.29/near/565077432
2025-12-22 23:00:16 +00:00
Lean stage0 autoupdater
0df74178d8 chore: update stage0 2025-12-22 20:55:00 +00:00