Commit graph

8614 commits

Author SHA1 Message Date
Leonardo de Moura
2ed77f3b26
feat: attribute [grind] (#6545)
This PR introduces the parametric attribute `[grind]` for annotating
theorems and definitions. It also replaces `[grind_eq]` with `[grind
=]`. For definitions, `[grind]` is equivalent to `[grind =]`.

The new attribute supports the following variants:

- **`[grind =]`**: Uses the left-hand side of the theorem's conclusion
as the pattern for E-matching.
- **`[grind =_]`**: Uses the right-hand side of the theorem's conclusion
as the pattern for E-matching.
- **`[grind _=_]`**: Creates two patterns. One for the left-hand side
and one for the right-hand side.
- **`[grind →]`**: Searches for (multi-)patterns in the theorem's
antecedents, stopping once a usable multi-pattern is found.
- **`[grind ←]`**: Searches for (multi-)patterns in the theorem's
conclusion, stopping once a usable multi-pattern is found.
- **`[grind]`**: Searches for (multi-)patterns in both the theorem's
conclusion and antecedents. It starts with the conclusion and stops once
a usable multi-pattern is found.

The `grind_pattern` command remains available for cases where these
attributes do not yield the desired result.
2025-01-06 03:05:20 +00:00
Leonardo de Moura
675244de76
feat: [grind_eq] attribute for the grind tactic (#6539)
This PR introduces the `[grind_eq]` attribute, designed to annotate
equational theorems and functions for heuristic instantiations in the
`grind` tactic.
When applied to an equational theorem, the `[grind_eq]` attribute
instructs the `grind` tactic to automatically use the annotated theorem
to instantiate patterns during proof search. If applied to a function,
it marks all equational theorems associated with that function.

```lean
@[grind_eq]
theorem foo_idempotent : foo (foo x) = foo x := ...

@[grind_eq] def f (a : Nat) :=
  match a with
  | 0 => 10
  | x+1 => g (f x)
```

In the example above, the `grind` tactic will add instances of the
theorem `foo_idempotent` to the local context whenever it encounters the
pattern `foo (foo x)`. Similarly, functions annotated with `[grind_eq]`
will propagate this annotation to their associated equational theorems.
2025-01-05 21:38:05 +00:00
Leonardo de Moura
fd091d1dfe
feat: pattern normalization in the grind tactic (#6538)
This PR ensures patterns provided by users are normalized. See new test
to understand why this is needed.
2025-01-05 19:35:52 +00:00
Leonardo de Moura
7b29f488df
fix: E-matching thresholds in the grind tactic (#6536)
This PR fixes different thresholds for controlling E-matching in the
`grind` tactic.
2025-01-05 17:34:56 +00:00
Leonardo de Moura
fb506b957c
fix: allow projections in E-matching patterns (#6534)
This PR ensures that users can utilize projections in E-matching
patterns within the `grind` tactic.
2025-01-05 16:20:54 +00:00
Leonardo de Moura
dc5c8097b5
feat: add term offset support to the grind E-matching modulo (#6533)
This PR adds support to E-matching offset patterns. For example, we want
to be able to E-match the pattern `f (#0 + 1)` with term `f (a + 2)`.
2025-01-05 02:20:17 +00:00
Leonardo de Moura
d22233fc7b
fix: let_fun support in grind (#6531)
This PR fixes the support for `let_fun` in `grind`.
2025-01-04 22:22:55 +00:00
Leonardo de Moura
ad2c16dade
feat: add support for let-declarations to grind (#6529)
This PR adds support for `let`-declarations to the (WIP) `grind` tactic.
2025-01-04 19:24:56 +00:00
Leonardo de Moura
37127ead07
fix: missing propagation in grind (#6528)
This PR adds a missing propagation rule to the (WIP) `grind` tactic.
2025-01-04 18:45:55 +00:00
Leonardo de Moura
ad593b36d9
feat: add support for match-expressions to grind (#6521)
This PR adds support for activating relevant `match`-equations as
E-matching theorems. It uses the `match`-equation lhs as the pattern.
2025-01-04 02:18:43 +00:00
Leonardo de Moura
7b496bf44b
feat: improve cases tactic used in grind (#6516)
This PR enhances the `cases` tactic used in the `grind` tactic and
ensures that it can be applied to arbitrary expressions.
2025-01-03 15:54:55 +00:00
Leonardo de Moura
df9ed20385
feat: ite and dite support in grind (#6513)
This PR adds support for (dependent) if-then-else terms (i.e., `ite` and
`dite` applications) in the `grind` tactic.
2025-01-03 01:05:44 +00:00
Leonardo de Moura
3e2f1faebf
feat: add user-defined fallback procedure for the grind tactic (#6512)
This PR introduces support for user-defined fallback code in the `grind`
tactic. The fallback code can be utilized to inspect the state of
failing `grind` subgoals and/or invoke user-defined automation. Users
can now write `grind on_failure <code>`, where `<code>` should have the
type `GoalM Unit`. See the modified tests in this PR for examples.
2025-01-02 23:56:51 +00:00
Leonardo de Moura
9d622270a1
feat: custom congruence rule for equality in grind (#6510)
This PR adds a custom congruence rule for equality in `grind`. The new
rule takes into account that `Eq` is a symmetric relation. In the
future, we will add support for arbitrary symmetric relations. The
current rule is important for propagating disequalities effectively in
`grind`.
2025-01-02 22:08:19 +00:00
Leonardo de Moura
e46b5f39bf
fix: congruence closure in the grind tactic (#6509)
This PR fixes a bug in the congruence closure data structure used in the
`grind` tactic. The new test includes an example that previously caused
a panic. A similar panic was also occurring in the test
`grind_nested_proofs.lean`.
2025-01-02 19:08:02 +00:00
Leonardo de Moura
3cba17140f
fix: missing case in checkParents (#6508)
This PR fixes a bug in the sanity checkers for the `grind` tactic. See
the new test for an example of a case where it was panicking.
2025-01-02 16:06:52 +00:00
Joachim Breitner
e9f069146c
feat: partial_fixpoint: monotonicity tactic (#6506)
This PR adds the `monotonicity` tactic, intended to be used inside the
`partial_fixpoint` feature.

Part of #6355.
2025-01-02 11:07:05 +00:00
Leonardo de Moura
8d9d81453b
feat: grind simple strategy (#6503)
This PR adds a simple strategy to the (WIP) `grind` tactic. It just
keeps internalizing new theorem instances found by E-matching. The
simple strategy can solve examples such as:

```lean
grind_pattern Array.size_set => Array.set a i v h
grind_pattern Array.get_set_eq  => a.set i v h
grind_pattern Array.get_set_ne => (a.set i v hi)[j]

example (as bs : Array α) (v : α)
        (i : Nat)
        (h₁ : i < as.size)
        (h₂ : bs = as.set i v)
        : as.size = bs.size := by
  grind

example (as bs cs : Array α) (v : α)
        (i : Nat)
        (h₁ : i < as.size)
        (h₂ : bs = as.set i v)
        (h₃ : cs = bs)
        (h₄ : i ≠ j)
        (h₅ : j < cs.size)
        (h₆ : j < as.size)
        : cs[j] = as[j] := by
  grind


opaque R : Nat → Nat → Prop
theorem Rtrans (a b c : Nat) : R a b → R b c → R a c := sorry

grind_pattern Rtrans => R a b, R b c

example : R a b → R b c → R c d → R d e → R a d := by
  grind
```
2025-01-02 05:36:01 +00:00
Leonardo de Moura
a08379ce2e
fix: proof generation for grind tactic (#6502)
This PR fixes a bug in the proof assembly procedure utilized by the
`grind` tactic.
2025-01-02 04:42:31 +00:00
Leonardo de Moura
c0d67e2a65
fix: bug in markNestedProofs within grind (#6500)
This PR fixes a bug in the `markNestedProofs` used in `grind`. See new
test.
2025-01-02 02:14:45 +00:00
Leonardo de Moura
f7c4edc2b7
feat: dependent forall propagator in grind (#6498)
This PR adds support in the `grind` tactic for propagating dependent
forall terms `forall (h : p), q[h]` where `p` is a proposition.
2025-01-02 00:08:36 +00:00
Leonardo de Moura
fedaf850bb
fix: theorem instantiation in grind (#6492)
This PR fixes a bug in the theorem instantiation procedure in the (WIP)
`grind` tactic. For example, it was missing the following instance in
one of the tests:

```lean
[grind.ematch.instance] Array.get_set_ne: ∀ (hj : i < bs.size), j ≠ i → (bs.set j w ⋯)[i] = bs[i]
```

This PR also renames the `grind` base monad to `GrindCoreM`.
2025-01-01 17:56:27 +00:00
Leonardo de Moura
3427630a14
feat: configuration options for the grind tactic (#6490)
This PR adds basic configuration options for the `grind` tactic.
2024-12-31 21:09:41 +00:00
Leonardo de Moura
8899c7ed8c
feat: instantiate ematch theorems in grind (#6485)
This PR implements `Grind.EMatch.instantiateTheorem` in the (WIP)
`grind` tactic.
2024-12-31 19:25:12 +00:00
Kyle Miller
8f5ce3a356
feat: upstream ToExpr deriving handler from Mathlib (#6473)
This PR adds a deriving handler for the `ToExpr` class. It can handle
mutual and nested inductive types, however it falls back to creating
`partial` instances in such cases. This is upstreamed from the Mathlib
deriving handler written by @kmill, but has fixes to handle autoimplicit
universe level variables.

This is a followup to #6285 (adding the `ToLevel` class). This PR
supersedes #5906.

Co-authored-by: Alex Keizer <alex@keizer.dev>

---------

Co-authored-by: Alex Keizer <alex@keizer.dev>
2024-12-31 15:11:53 +00:00
Leonardo de Moura
2c87905d77
feat: E-matching procedure for the grind tactic (#6481)
This PR implements E-matching for the (WIP) `grind` tactic. We still
need to finalize and internalize the new instances.
2024-12-31 02:46:09 +00:00
Cameron Zwarich
32dc16590b
chore: reduce churn in tests/lean/run/meta5.lean (#6480) 2024-12-31 02:32:56 +00:00
Leonardo de Moura
7e8e22e2bd
fix: internalize nested ground patterns when activating ematch theorems (#6478)
This PR internalize nested ground patterns when activating ematch
theorems in the (WIP) `grind` tactic.
2024-12-30 16:13:47 +00:00
Leonardo de Moura
9b28c5879a
feat: ematch theorem activation for grind (#6475)
This PR adds support for activating relevant theorems for the (WIP)
`grind` tactic. We say a theorem is relevant to a `grind` goal if the
symbols occurring in its patterns also occur in the goal.
2024-12-30 09:57:33 +00:00
Leonardo de Moura
24a8561ec4
feat: check pattern coverage in the grind_pattern command (#6474)
This PR adds pattern validation to the `grind_pattern` command. The new
`checkCoverage` function will also be used to implement the attributes
`@[grind_eq]`, `@[grind_fwd]`, and `@[grind_bwd]`.
2024-12-30 03:40:43 +00:00
Leonardo de Moura
7433e74fc4
feat: theorem patterns for heuristic instantiation in grind (#6472)
This PR implements the command `grind_pattern`. The new command allows
users to associate patterns with theorems. These patterns are used for
performing heuristic instantiation with e-matching. In the future, we
will add the attributes `@[grind_eq]`, `@[grind_fwd]`, and
`@[grind_bwd]` to compute the patterns automatically for theorems.
2024-12-29 20:26:58 +00:00
Leonardo de Moura
5930db946c
fix: Int.reduceNeg simproc (#6468)
This PR fixes issue #6467 


closes #6467
2024-12-28 22:58:09 +00:00
Leonardo de Moura
3fc74854d7
fix: check function types when detecting congruences in grind (#6466)
This PR completes the implementation of `addCongrTable` in the (WIP)
`grind` tactic. It also adds a new test to demonstrate why the extra
check is needed. It also updates the field `cgRoot` (congruence root).
2024-12-28 19:53:02 +00:00
Leonardo de Moura
fe45ddd610
feat: projections in grind (#6465)
This PR adds support for projection functions to the (WIP) `grind`
tactic.
2024-12-27 23:50:58 +00:00
Leonardo de Moura
f545df9922
feat: literal values in grind (#6464)
This PR completes support for literal values in the (WIP) `grind`
tactic. `grind` now closes the goal whenever it merges two equivalence
classes with distinct literal values.
2024-12-27 22:18:56 +00:00
Leonardo de Moura
844e82e176
feat: constructors in grind (#6463)
This PR adds support for constructors to the (WIP) `grind` tactic. When
merging equivalence classes, `grind` checks for equalities between
constructors. If they are distinct, it closes the goal; if they are the
same, it applies injectivity.
2024-12-27 21:15:02 +00:00
Leonardo de Moura
2d7d3388e2
fix: missing Not propagation rule in grind (#6461)
This PR adds a new propagation rule for negation to the (WIP) `grind`
tactic.
2024-12-27 17:37:32 +00:00
Leonardo de Moura
6a839796fd
feat: add grind tactic (#6459)
This PR adds the (WIP) `grind` tactic. It currently generates a warning
message to make it clear that the tactic is not ready for production.
2024-12-27 03:48:01 +00:00
Leonardo de Moura
e76dc20200
feat: use compact congruence proofs in grind if applicable (#6458)
This PR adds support for compact congruence proofs in the (WIP) `grind`
tactic. The `mkCongrProof` function now verifies whether the congruence
proof can be constructed using only `congr`, `congrFun`, and `congrArg`,
avoiding the need to generate the more complex `hcongr` auxiliary
theorems.
2024-12-26 23:58:04 +00:00
Leonardo de Moura
dca874ea57
feat: congruence proofs for grind (#6457)
This PR adds support for generating congruence proofs for congruences
detected by the `grind` tactic.
2024-12-26 22:20:36 +00:00
Leonardo de Moura
c282d558fa
fix: fix: bug in mkEqProof within grind (#6456)
This PR fixes another bug in the equality proof generator in the (WIP)
`grind` tactic.
2024-12-26 19:03:35 +00:00
Leonardo de Moura
57050be3ab
fix: bug in mkEqProof within grind (#6455)
This PR fixes a bug in the equality proof generator in the (WIP) `grind`
tactic.
2024-12-26 18:25:11 +00:00
Henrik Böving
37b53b70d0
perf: improve bv_decide performance with large literals (#6453)
This PR improves bv_decide's performance in the presence of large
literals.

The core change of this PR is the reformulation of the reflection code
for literals to:
```diff
 def eval (assign : Assignment) : BVExpr w → BitVec w
   | .var idx =>
-    let ⟨bv⟩ := assign.get idx
-    bv.truncate w
+    let packedBv := assign.get idx
+    /-
+    This formulation improves performance, as in a well formed expression the condition always holds
+    so there is no need for the more involved `BitVec.truncate` logic.
+    -/
+    if h : packedBv.w = w then
+      h ▸ packedBv.bv
+    else
+      packedBv.bv.truncate w
```
The remainder is merely further simplifications that make the terms
smaller and easier to deal with in general. This change is motivated by
applying the following diff to the kernel:
```diff
diff --git a/src/kernel/type_checker.cpp b/src/kernel/type_checker.cpp
index b0e6844dca..f13bb96bd4 100644
--- a/src/kernel/type_checker.cpp
+++ b/src/kernel/type_checker.cpp
@@ -518,6 +518,7 @@ optional<constant_info> type_checker::is_delta(expr const & e) const {
 optional<expr> type_checker::unfold_definition_core(expr const & e) {
     if (is_constant(e)) {
         if (auto d = is_delta(e)) {
+//            std::cout << "Working on unfolding: " << d->get_name() << std::endl;
             if (length(const_levels(e)) == d->get_num_lparams()) {
                 if (m_diag) {
                     m_diag->record_unfold(d->get_name());
```
and observing that in the test case from #6043 we see a long series of
```
Working on unfolding: Bool.decEq
Working on unfolding: Bool.decEq.match_1
Working on unfolding: Bool.casesOn
Working on unfolding: Nat.ble
Working on unfolding: Nat.brecOn
Working on unfolding: Nat.beq.match_1
Working on unfolding: Nat.casesOn
Working on unfolding: Nat.casesOn
Working on unfolding: Nat.beq.match_1
Working on unfolding: Nat.casesOn
Working on unfolding: Nat.casesOn
```
the chain begins with `BitVec.truncate`, works through a few
abstractions and then continues like above forever, so I avoid the call
to truncate like this. It is not quite clear to me why removing `ofBool`
helps so much here, maybe some other kernel heuristic kicks in to rescue
us.

Either way this diff is a general improvement for reflection of `BitVec`
constants as we should never have to run `BitVec.truncate` again!

Fixes: #6043
2024-12-26 16:50:00 +00:00
Leonardo de Moura
8a1e50f0b9
feat: equality proof generation for grind (#6452)
This PR adds support for generating (small) proofs for any two
expressions that belong to the same equivalence class in the `grind`
tactic state.
2024-12-26 06:01:45 +00:00
Leonardo de Moura
f9f8abe2a3
feat: propagate equality in grind (#6443)
This PR adds support for propagating the truth value of equalities in
the (WIP) `grind` tactic.
2024-12-24 23:54:36 +00:00
Leonardo de Moura
ec80de231e
fix: checkParents in grind (#6442)
This PR fixes the `checkParents` sanity check in `grind`.
2024-12-24 22:45:18 +00:00
Leonardo de Moura
630577a9ea
feat: truth value propagation for grind (#6441)
This PR adds basic truth value propagation rules to the (WIP) `grind`
tactic.
2024-12-24 21:12:53 +00:00
Leonardo de Moura
cde35bcc0d
test: grind (#6440)
This PR adds additional tests for `grind` and fixed minor issues.
2024-12-24 04:33:05 +00:00
Leonardo de Moura
b18f3a3877
feat: detect congruent terms in grind (#6437)
This PR adds support for detecting congruent terms in the (WIP) `grind`
tactic. It also introduces the `grind.debug` option, which, when set to
`true`, checks many invariants after each equivalence class is merged.
This option is intended solely for debugging purposes.
2024-12-24 00:11:36 +00:00
Leonardo de Moura
5240405cf4
feat: congruence table for grind tactic (#6435)
This PR implements the congruence table for the (WIP) `grind` tactic. It
also fixes several bugs, and adds a new preprocessing step.
2024-12-23 02:31:42 +00:00