This PR ensures that we use the same ordering to normalize linear `Int`
terms and relations. This change affects `simp +arith` and `grind`
normalizer.
This consistency is important in the cutsat procedure. We want to avoid
a situation where the cutsat state contains both "atoms":
- `「(NatCast.natCast x + NatCast.natCast y) % 8」`
- `「(NatCast.natCast y + NatCast.natCast x) % 8」`
This was happening because we were using different orderings for
(nested) terms and relations (`=`, `<=`).
This PR allows the use of `dsimp` during preprocessing of well-founded
definitions. This fixes regressions when using `if-then-else` without
giving a name to the condition, but where the condition is needed for
the termination proof, in cases where that subexpression is reachable
only by dsimp, but not by simp (e.g. inside a dependent let)
Also fixes some preprocessing lemmas to not be bad simp lemmas (with
lambdas on the LHS, due to dot notation and unfortunate argument order)
This fixes#7408.
This PR makes the docstrings in the `Char` namespace follow the
documentation conventions.
---------
Co-authored-by: Markus Himmel <markus@himmel-villmar.de>
This PR gives the `induction` tactic the ability to name hypotheses to
use when generalizing targets, just like in `cases`. For example,
`induction h : xs.length` leads to goals with hypotheses `h : xs.length
= 0` and `h : xs.length = n + 1`. Target handling is also slightly
modified for multi-target induction principles: it used to be that if
any target was not a free variable, all of the targets would be
generalized (thus causing free variables to lose their connection to the
local hypotheses they appear in); now only the non-free-variable targets
are generalized.
This gives `induction` the last basic feature of the mathlib
`induction'` tactic, which has been long-requested. Recent Zulip
discussion:
https://leanprover.zulipchat.com/#narrow/channel/270676-lean4/topic/To.20replace.20.60induction'.20h.20.3A.20f.20x.60/near/499482173
This PR modifies `grind` to run with the `reducible` transparency
setting. We do not want `grind` to unfold arbitrary terms during
definitional equality tests. This PR also fixes several issues
introduced by this change. The most common problem was the lack of a
hint in proofs, particularly in those constructed using proof by
reflection. This PR also introduces new sanity checks when `set_option
grind.debug true` is used.
This PR implements several modifications for the cutsat procedure in
`grind`.
- The maximal variable is now at the beginning of linear polynomials.
- The old `LinearArith.Solver` was deleted, and the normalizer was moved
to `Simp`.
- cutsat first files were created, and basic infrastructure for
representing divisibility constraints was added.
This PR makes `BitVec.getElem` the simp normal form in case a proof is
available and changes `ext` to return `x[i]` + a hypothesis that proves
that we are in-bounds. This aligns `BitVec` further with the API
conventions of the Lean standard datatypes.
We move our proofs to this new normal form, which results in slightly
smaller proofs. With the exception of `getElem_ofFin`, no new API
surface is added as the `getElem` API has already been completed over
the previous months. We also move `getElem_shiftConcat_*` a bit higher
as they are needed in earlier proofs. To keep the changeset small, we do
not update the API of `BVDecide` but insert `←
BitVec.getLsbD_eq_getElem` at the few locations where it is needed.
Finally, we add a simproc for getElem, mirroring the existing ones for
getLsbD/getMsdD.
---------
Co-authored-by: Alex Keizer <alex@keizer.dev>
This PR cleans up the `Int.Linear` module by normalizing function and
type names and adding documentation strings. We will use it to implement
cutsat in the `grind` tactic.
This PR is a follow-up to #7057 and adds a builtin dsimproc for
`UIntX.ofNatLT` which it turns out we need in stage0 before we can get
the deprecation of `UIntX.ofNatCore` in favor of `UIntX.ofNatLT` off the
ground.
This PR extend the preprocessing of well-founded recursive definitions
to bring assumptions like `h✝ : x ∈ xs` into scope automatically.
This fixes#5471, and follows (roughly) the design written there.
See the module docs at `src/Lean/Elab/PreDefinition/WF/AutoAttach.lean`
for details on the implementation.
This only works for higher-order functions that have a suitable setup.
See for example section “Well-founded recursion preprocessing setup” in
`src/Init/Data/List/Attach.lean`.
This does not change the `decreasing_tactic`, so in some cases there is
still the need for a manual termination proof some cases. We expect a
better termination tactic in the near future.
This PR adds `simp +arith` for integers. It uses the new `grind`
normalizer for linear integer arithmetic. We still need to implement
support for dividing the coefficients by their GCD. It also fixes
several bugs in the normalizer.
This PR adds the `binderNameHint` gadget. It can be used in rewrite and
simp rules to preserve a user-provided name where possible.
The expression `binderNameHint v binder e` defined to be `e`.
If it is used on the right-hand side of an equation that is applied by a
tactic like `rw` or `simp`,
and `v` is a local variable, and `binder` is an expression that (after
beta-reduction) is a binder
(so `fun w => …` or `∀ w, …`), then it will rename `v` to the name used
in the binder, and remove
the `binderNameHint`.
A typical use of this gadget would be as follows; the gadget ensures
that after rewriting, the local
variable is still `name`, and not `x`:
```
theorem all_eq_not_any_not (l : List α) (p : α → Bool) :
l.all p = !l.any fun x => binderNameHint x p (!p x) := sorry
example (names : List String) : names.all (fun name => "Waldo".isPrefixOf name) = true := by
rw [all_eq_not_any_not]
-- ⊢ (!names.any fun name => !"Waldo".isPrefixOf name) = true
```
This gadget is supported by `simp`, `dsimp` and `rw` in the
right-hand-side of an equation, but not
in hypotheses or by other tactics.
This PR changes the `simpMatch` function, used inside the equation
generator for WF-rec functions, to not do eta-expansion.
This makes the process a bit more robust and disciplined, and avoids
removing match-statements (and introduce projections and dependencies)
that we'd rather split instead.
Also adds more tracing to the equational theorem generator.
Extracted from #6898.
This PR implements the `zetaUnused` simp and reduction option (added in
#6754).
True by default, and implied by `zeta`, this can be turned off to make
simp even more careful about preserving the expression structure,
including unused let and have expressions.
Breaking change: The `split` tactic no longer removes unused let and
have expressions as a side-effect, in rare cases this may break proofs.
`dsimp only` can be used to remove unused have and let expressions.
This PR ensures that `simp` and `dsimp` do not unfold definitions that
are not intended to be unfolded by the user. See issue #5755 for an
example affected by this issue.
Closes#5755
---------
Co-authored-by: Kim Morrison <kim@tqft.net>
This PR ensures that the configuration in `Simp.Config` is used when
reducing terms and checking definitional equality in `simp`.
closes#5455
---------
Co-authored-by: Kim Morrison <kim@tqft.net>
This PR fixes a bug in the simplifier. It was producing terms with loose
bound variables when eliminating unused `let_fun` expressions.
This issue was affecting the example at #6374. The example is now timing
out.
This PR removes the deprecated aliases `Int.div := Int.tdiv` and
`Int.mod := Int.tmod`. Later we will rename `Int.ediv` to `Int.div` and
`Int.emod` to `Int.mod`.
This PR implements `Simp.Config.implicitDefEqsProofs`. When `true`
(default: `true`), `simp` will **not** create a proof term for a
rewriting rule associated with an `rfl`-theorem. Rewriting rules are
provided by users by annotating theorems with the attribute `@[simp]`.
If the proof of the theorem is just `rfl` (reflexivity), and
`implicitDefEqProofs := true`, `simp` will **not** create a proof term
which is an application of the annotated theorem.
The default setting does change the existing behavior. Users can use
`simp -implicitDefEqProofs` to force `simp` to create a proof term for
`rfl`-theorems. This can positively impact proof checking time in the
kernel.
This PR also fixes an issue in the `split` tactic that has been exposed
by this feature. It was looking for `split` candidates in proofs and
implicit arguments. See new test for issue exposed by the previous
feature.
---------
Co-authored-by: Kim Morrison <kim@tqft.net>
This PR adds the builtin simproc `USize.reduceToNat` which reduces the
`USize.toNat` operation on literals less than `UInt32.size` (i.e.,
`4294967296`).