This PR adds support for numerals, lower & upper bounds to the offset
constraint module in the `grind` tactic. `grind` can now solve examples
such as:
```
example (f : Nat → Nat) :
f 2 = a →
b ≤ 1 → b ≥ 1 →
c = b + 1 →
f c = a := by
grind
```
In the example above, the literal `2` and the lower&upper bounds, `b ≤
1` and `b ≥ 1`, are now processed by offset constraint module.
This PR completes aligning `List`/`Array`/`Vector` lemmas about
`flatten`. `Vector.flatten` was previously missing, and has been added
(for rectangular sizes only). A small number of missing `Option` lemmas
were also need to get the proofs to go through.
This PR implements support for offset equality constraints in the
`grind` tactic and exhaustive equality propagation for them. The `grind`
tactic can now solve problems such as the following:
```lean
example (f : Nat → Nat) (a b c d e : Nat) :
f (a + 3) = b →
f (c + 1) = d →
c ≤ a + 2 →
a + 1 ≤ e →
e < c →
b = d := by
grind
```
This PR improves the failure message produced by the `grind` tactic. We
now include information about asserted facts, propositions that are
known to be true and false, and equivalence classes.
This PR adds lemmas describing the behavior of `UIntX.toBitVec` on
`UIntX` operations.
I did not define them for the `IntX` half yet as that lemma file is non
existent so far and we can start working on `UIntX` in `bv_decide` with
this, then add `IntX` when we grow the `IntX` API.
This PR implements exhaustive offset constraint propagation in the
`grind` tactic. This enhancement minimizes the number of case splits
performed by `grind`. For instance, it can solve the following example
without performing any case splits:
```lean
example (p q r s : Prop) (a b : Nat) : (a + 1 ≤ c ↔ p) → (a + 2 ≤ c ↔ s) → (a ≤ c ↔ q) → (a ≤ c + 4 ↔ r) → a ≤ b → b + 2 ≤ c → p ∧ q ∧ r ∧ s := by
grind (splits := 0)
```
TODO: support for equational offset constraints.
This PR implements support for offset constraints in the `grind` tactic.
Several features are still missing, such as constraint propagation and
support for offset equalities, but `grind` can already solve examples
like the following:
```lean
example (a b c : Nat) : a ≤ b → b + 2 ≤ c → a + 1 ≤ c := by
grind
example (a b c : Nat) : a ≤ b → b ≤ c → a ≤ c := by
grind
example (a b c : Nat) : a + 1 ≤ b → b + 1 ≤ c → a + 2 ≤ c := by
grind
example (a b c : Nat) : a + 1 ≤ b → b + 1 ≤ c → a + 1 ≤ c := by
grind
example (a b c : Nat) : a + 1 ≤ b → b ≤ c + 2 → a ≤ c + 1 := by
grind
example (a b c : Nat) : a + 2 ≤ b → b ≤ c + 2 → a ≤ c := by
grind
```
---------
Co-authored-by: Kim Morrison <scott.morrison@gmail.com>
This PR improves the usability of the `[grind =]` attribute by
automatically handling
forbidden pattern symbols. For example, consider the following theorem
tagged with this attribute:
```
getLast?_eq_some_iff {xs : List α} {a : α} : xs.getLast? = some a ↔ ∃ ys, xs = ys ++ [a]
```
Here, the selected pattern is `xs.getLast? = some a`, but `Eq` is a
forbidden pattern symbol.
Instead of producing an error, this function converts the pattern into a
multi-pattern,
allowing the attribute to be used conveniently.
This PR adds a `toFin` and `msb` lemma for unsigned bitvector modulus.
Similar to #6402, we don't provide a general `toInt_umod` lemmas, but
instead choose to provide more specialized rewrites, with extra
side-conditions.
---------
Co-authored-by: Kim Morrison <scott@tqft.net>
This PR adds a `toFin` and `msb` lemma for unsigned bitvector division.
We *don't* have `toInt_udiv`, since the only truly general statement we
can make does no better than unfolding the definition, and it's not
uncontroversially clear how to unfold `toInt` (see
`toInt_eq_msb_cond`/`toInt_eq_toNat_cond`/`toInt_eq_toNat_bmod` for a
few options currently provided). Instead, we do have `toInt_udiv_of_msb`
that's able to provide a more meaningful rewrite given an extra
side-condition (that `x.msb = false`).
This PR also upstreams a minor `Nat` theorem (`Nat.div_le_div_left`)
needed for the above from Mathlib.
---------
Co-authored-by: Kim Morrison <scott@tqft.net>
This PR improves the theorems used to justify the steps performed by the
inequality offset module. See new test for examples of how they are
going to be used.
This PR fixes the location of the error emitted when the `rintro` and
`intro` tactics cannot introduce the requested number of binders.
This patch adds a few `withRef` wrappers to invocations of
`MVarId.intro` to fix error locations. Perhaps `MVarId.intro` should
take a syntax object to set the location itself in the future; however
there are a couple other call sites which would need non-trivial fixup.
Closes #5659.
This PR adds support for case splitting on `match`-expressions in
`grind`.
We still need to add support for resolving the antecedents of
`match`-conditional equations.
This PR modifies the `induction`/`cases` syntax so that the `with`
clause does not need to be followed by any alternatives. This improves
friendliness of these tactics, since this lets them surface the names of
the missing alternatives:
```lean
example (n : Nat) : True := by
induction n with
/- ~~~~
alternative 'zero' has not been provided
alternative 'succ' has not been provided
-/
```
Related to issue #3555
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.
This PR proves the basic theorems about the functions `Int.bdiv` and
`Int.bmod`.
For all integers `x` and all natural numbers `m`, we have:
- `Int.bdiv_add_bmod`: `m * bdiv x m + bmod x m = x` (which is stated in
the docstring for docs#Int.bdiv)
- `Int.bmod_add_bdiv`: `bmod x m + m * bdiv x m = x`
- `Int.bdiv_add_bmod'`: `bdiv x m * m + bmod x m = x`
- `Int.bmod_add_bdiv'`: `bmod x m + bdiv x m * m = x`
- `Int.bmod_eq_self_sub_mul_bdiv`: `bmod x m = x - m * bdiv x m`
- `Int.bmod_eq_self_sub_bdiv_mul`: `bmod x m = x - bdiv x m * m`
These theorems are all equivalent to each other by the basic properties
of addition, multiplication, and subtraction of integers.
The names `Int.bdiv_add_bmod`, `Int.bmod_add_bdiv`,
`Int.bdiv_add_bmod'`, and `Int.bmod_add_bdiv'` are meant to parallel the
names of the existing theorems docs#Int.tmod_add_tdiv,
docs#Int.tdiv_add_tmod, docs#Int.tmod_add_tdiv', and
docs#Int.tdiv_add_tmod'.
The names `Int.bmod_eq_self_sub_mul_bdiv` and
`Int.bmod_eq_self_sub_bdiv_mul` follow mathlib's naming conventions.
Note that there is already a theorem called docs#Int.bmod_def, so it
would not have been possible to parallel the name of the existing
theorem docs#Int.tmod_def.
See
https://leanprover.zulipchat.com/#narrow/channel/217875-Is-there-code-for-X.3F/topic/bdiv.20and.20bmod.
Closes#6493.
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.
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`.