This PR makes `IntCast` a field of `Lean.Grind.CommRing`, along with
additional axioms relating it to negation of `OfNat`. This allows use to
use existing instances which are not definitionally equal to the
previously given construction.
---------
Co-authored-by: Leonardo de Moura <leomoura@amazon.com>
This PR implements tactics called `extract_lets` and `lift_lets` that
manipulate `let`/`let_fun` expressions. The `extract_lets` tactic
creates new local declarations extracted from any `let` and `let_fun`
expressions in the main goal. For top-level lets in the target, it is
like the `intros` tactic, but in general it can extract lets from deeper
subexpressions as well. The `lift_lets` tactic moves `let` and `let_fun`
expressions as far out of an expression as possible, but it does not
extract any new local declarations. The option `extract_lets +lift`
combines these behaviors.
This is a re-implementation of `extract_lets` and `lift_lets` from
mathlib. The new `extract_lets` is like doing `lift_lets; extract_lets`,
but it does not lift unextractable lets like `lift_lets`. The
`lift_lets; extract_lets` behavior is now handled by `extract_lets
+lift`. The new `lift_lets` tactic is a frontend to `extract_lets +lift`
machinery, which rather than creating new local definitions instead
represents the accumulated local declarations as top-level lets.
There are also conv tactics for both of these. The `extract_lets` has a
limitation due to the conv architecture; it can extract lets for a given
conv goal, but the local declarations don't survive outside conv. They
get zeta reduced immediately upon leaving conv.
This PR makes the following modifications to the new comm ring procedure
in `grind`
1. Adds data-structures for representing equations (and their
justifications), basis, and queue of equations to be processed.
2. Adds `RingM` helper monad.
3. Adds equation simplification main loop
This PR adds support to `grind` for detecting unsatisfiable commutative
ring equations when the ring characteristic is known. Examples:
```lean
example (x : Int) : (x + 1)*(x - 1) = x^2 → False := by
grind +ring
example (x y : Int) : (x + 1)*(x - 1)*y + y = y*x^2 + 1 → False := by
grind +ring
example (x : UInt8) : (x + 1)*(x - 1) = x^2 → False := by
grind +ring
example (x y : BitVec 8) : (x + 1)*(x - 1)*y + y = y*x^2 + 1 → False := by
grind +ring
```
This PR implements basic support for `CommRing` in `grind`. Terms are
already being reified and normalized. We still need to process the
equations, but `grind` can already prove simple examples such as:
```lean
open Lean.Grind in
example [CommRing α] (x : α) : (x + 1)*(x - 1) = x^2 - 1 := by
grind +ring
open Lean.Grind in
example [CommRing α] [IsCharP α 256] (x : α) : (x + 16)*(x - 16) = x^2 := by
grind +ring
example (x : Int) : (x + 1)*(x - 1) = x^2 - 1 := by
grind +ring
example (x : UInt8) : (x + 16)*(x - 16) = x^2 := by
grind +ring
example (x : Int) : (x + 1)^2 - 1 = x^2 + 2*x := by
grind +ring
example (x : BitVec 8) : (x + 16)*(x - 16) = x^2 := by
grind +ring
example (x : BitVec 8) : (x + 1)^2 - 1 = x^2 + 2*x := by
grind +ring
```
This PR ensures that `mkAppM` can be used to construct terms that are
only type-correct at at default transparency, even if we are in
`withReducible` (e.g. in simp), so that simp does not stumble over
simplifying `let` expression with simplifiable type.reliable.
Here is a reproducer of the issue this solves:
```
example (a b : Nat) (h : a = b):
(let _ : id Bool := true; a) = (let _ : Bool := true; b) := by
simp -zeta -zetaDelta [h]
```
This fixes#7826.
This PR adds the option `debug.terminalTacticsAsSorry`. When enabled,
terminal tactics such as `grind` and `omega` are replaced with `sorry`.
Useful for debugging and fixing bootstrapping issues.
This PR removes all type annotations (optional paramters, auto
parameters, out params, semi-out params, not just optional parameters as
before) from the type of functional induction principles.
This PR adds some docstrings to clarify the functions of
`Lean.mkFreshId`, `Lean.Core.mkFreshUserName`,
`Lean.Elab.Term.mkFreshBinderName`, and
`Lean.Meta.mkFreshBinderNameForTactic`.
This PR adds the attribute `[grind ext]`. It is used to select which
`[ext]` theorems should be used by `grind`. The option `grind +extAll`
instructs `grind` to use all `[ext]` theorems available in the
environment.
After update stage0, we need to add the builtin `[grind ext]`
annotations to key theorems such as `funext`.
This PR fixes two issues that were preventing `grind` to solve
`getElem?_eq_some_iff`.
1. Missing propagation rule for `Exists p = False`
2. Missing conditions at `isCongrToPrevSplit` a filter for discarding
unnecessary case-splits.
This PR fixes two bugs in `grind`.
1. Model-based theory combination was creating type incorrect terms.
2. `Nat.cast` vs `NatCast.natCast` issue during normalization.
This PR fixes a regression where elaboration of a previous document
version is not cancelled on changes to the document.
Done by removing the default from `SnapshotTask.cancelTk?` and
consistently passing the current thread's token for synchronous
elaboration steps.
This PR eliminates another source of facts of the form `-1 *
NatCast.natCast x <= 0` for each `x : Nat` in the local context. These
facts are now stored internally in the cutsat state.
cc @kim-em
This PR adjusts the `TryThis` widget to also work in widget messages
rather than only as a panel widget. It also adds additional
documentation explaining why this change was needed.
This PR improves the normalization of `Bool` terms in `grind`. Recall
that `grind` currently does not case split on Boolean terms to reduce
the size of the search space.
This PR updates `rw?`, `show_term`, and other tactic-suggesting tactics
to suggest `expose_names` when necessary and validate tactics prior to
suggesting them, as `exact?` already did, and it also ensures all such
tactics produce hover info in the messages showing tactic suggestions.
This introduces a breaking change in the `TryThis` API: the `type?`
parameter of `addRewriteSuggestion` is now an `LOption`, not an
`Option`, to obviate the need for a hack we previously used to indicate
that a rewrite closed the goal.
Closes#7350
This PR fixes an issue in the cutsat counterexamples. It removes the
optimization (`Cutsat.State.terms`) that was used to avoid the new
theorem `eq_def`. In the two new tests, prior to this PR, `cutsat`
produced a bogus counterexample with `b := 2`.
This PR prevents redundant invocations to `markAsCutsatTerm` which would
trigger equalities of the form `x = x` being propagated. This redundancy
only affected performance and "polluted" trace messages with redundant
information.
This PR improves support for `Nat` in the `cutsat` procedure used in
`grind`:
- `cutsat` no longer *pollutes* the local context with facts of the form
`-1 * NatCast.natCast x <= 0` for each `x : Nat`. These facts are now
stored internally in the `cutsat` state.
- A single context is now used for all `Nat` terms.
The PR also introduces a mapping mechanism for all "foreign" types that
can be converted to `Int`. Currently, only `Nat` is supported, but
additional types will be added in the future.
This PR adds a new propagation rule for `Bool` disequalities to `grind`.
It now propagates `x = true` (`x = false`) from the disequality `x =
false` (`x = true`). It ensures we don't have to perform case analysis
on `x` to learn this fact. See tests.
This PR adds missing propagation rules for `LawfulBEq A` to `grind`.
They are needed in a context where the instance `DecidableEq A` is not
available. See new test.
This PR improves how `grind` normalizes dependent implications during
introduction.
Previously, `grind` would introduce a hypothesis `h : p` for a goal of
the form `.. ⊢ (h : p) → q h`, and then normalize and assert a
non-dependent copy of `p`. As a result, the local context would contain
both `h : p` and a separate `h' : p'`, where `p'` is the normal form of
`p`. Moreover, `q` would still depend on the original `h`.
After this commit, `grind` avoids creating a copy. The context will now
contain only `h : p'`, and the new goal becomes `.. ⊢ q (he.mpr_prop
h)`, where `he` is a proof of `p = p'`.
This PR adds a feature to `structure`/`class` where binders without
types on a field definition are interpreted as overriding the type's
parameters binder kinds in that field's projection function. The rules
are (1) only a prefix of the binders are interpreted this way, (2)
multi-identifier binders are allowed but they must all be for
parameters, (3) only parameters that appear in the declaration itself
(not from `variables`) can be overridden and (4) the updates will be
applied after parameter binder kind inference is done. Binder updates
are not allowed in default value redefinitions. Example application: In
the following, `(R p)` causes the `R` and `p` parameters to be explicit,
where normally they would be implicit.
```
class CharP (R : Type u) [AddMonoidWithOne R] (p : Nat) : Prop where
cast_eq_zero_iff (R p) : ∀ x : Nat, (x : R) = 0 ↔ p ∣ x
#guard_msgs in #check CharP.cast_eq_zero_iff
/-
info: CharP.cast_eq_zero_iff.{u} (R : Type u) {inst✝ : AddMonoidWithOne R} (p : Nat) [self : CharP R p] (x : Nat) :
↑x = 0 ↔ p ∣ x
-/
```
The rationale for (3) is that there are cases where a module starts with
a large `variables` list and a field only incidentally uses the binder.
Without the restriction, the field ends up depending on that variable,
counterintuitively causing it to be introduced as an additional
parameter for the type. Instead, there is an explicit error. The easy
fix is to add `: _`, which is the bare minimum to make the binder have a
type.
We should consider warning when binders shadow parameters.
Closes#3574
[Zulip
discussion](https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/RFC.3A.20adjust.20argument.20explicitness.20on.20typeclass.20projections/near/508584627)
Mathlib fixes:
https://github.com/leanprover-community/mathlib4/pull/23469