This PR moves `ReflBEq` to `Init.Core` and changes `LawfulBEq` to extend
`ReflBEq`.
**BREAKING CHANGES:**
- The `refl` field of `ReflBEq` has been renamed to `rfl` to match
`LawfulBEq`
- `LawfulBEq` extends `ReflBEq`, so in particular `LawfulBEq.rfl` is no
longer valid
This PR adds `BitVec.[toInt_append|toFin_append]`.
`toInt_append` states:
```lean
(x ++ y).toInt = if n == 0 then y.toInt else (2 ^ m) * x.toInt + y.toNat
```
We also add the following `Nat` theorem (derived from a corresponding
theorem `two_pow_add_eq_or_of_lt`) as it faciliates the `append` proofs:
```lean
theorem shiftLeft_add_eq_or_of_lt {b : Nat} (b_lt : b < 2^i) (a : Nat) :
a <<< i + b = a <<< i ||| b
```
This PR provides `Inhabited`, `Ord` (if missing), `TransOrd`,
`LawfulEqOrd` and `LawfulBEqOrd` instances for various types, namely
`Bool`, `String`, `Nat`, `Int`, `UIntX`, `Option`, `Prod` and date/time
types. It also adds a few related theorems, especially about how the
`Ord` instance for `Int` relates to `LE` and `LT`.
---------
Co-authored-by: Paul Reichert <datokrat@users.noreply.github.com>
This PR marks `Nat.div` and `Nat.modCore` as `irreducible`, to recover
the behavior from from before #7558.
Fixes#7612. H't to @tobiasgrosser for the good bug report.
This PR changes the definition of `Nat.div` and `Nat.mod` to use a
structurally recursive, fuel-based implementation rather than
well-founded recursion. This leads to more predicable reduction behavior
in the kernel.
`Nat.div` and `Nat.mod` are somewhat special because the kernel has
native reduction for them when applied to literals. But sometimes this
does not kick in, and the kernel has to unfold `Nat.div`/`Nat.mod` (e.g.
in `lazy_delta_reduction` when there are open terms around). In these
cases we want a well-behaved definition.
We really do not want to reduce proofs in the kernel, which we want to
prevent anyways well-founded recursion (to be prevented by #5182).
Hence we avoid well-founded recursion here, and use a (somewhat
standard) translation to a fuel-based definition.
(If this idiom is needed more often we could even support it in Lean
with `termination_by +fuel <measure>` rather easily.)
This PR adds `BitVec.[toNat|toFin|toInt]_[sshiftRight|sshiftRight']`
plus variants with `of_msb_*`. While at it, we also add
`toInt_zero_length` and `toInt_of_zero_length`. In support of our main
theorem we add `toInt_shiftRight_lt` and `le_toInt_shiftRight`, which
make the main theorem automatically derivable via omega.
We also add four shift lemmas for `Int`: `le_shiftRight_of_nonpos`,
`shiftRight_le_of_nonneg`, `le_shiftRight_of_nonneg`,
`shiftRight_le_of_nonpos`, as well as `emod_eq_add_self_emod`,
`ediv_nonpos_of_nonpos_of_neg `, and`bmod_eq_emod_of_lt `. For `Nat` we
add `shiftRight_le`.
Beyond the lemmas directly needed in the proof, we added a couple more
to ensure the API is complete.
We also fix the casing of `toFin_ushiftRight` and rename `lt_toInt` to
`two_mul_lt_toInt` to avoid `'`-ed lemmas.
This PR fills further gaps in the integer division API, and mostly
achieves parity between the three variants of integer division. There
are still some inequality lemmas about `tdiv` and `fdiv` that are
missing, but as they would have quite awkward statements I'm hoping that
for now no one is going to miss them.
This PR adds theorems comparing `Int.ediv` with `tdiv` and `fdiv`, for
all signs of arguments. (Previously we just had the statements about the
cases in which they agree.)
This PR splits `Int.DivModLemmas` into a `Bootstrap` and `Lemmas` file,
where it is possible to use `omega` in `Lemmas`.
I'm going to add more theory, particularly about `fdiv` and `tdiv` to
the `Lemmas` file, and would prefer to have access to `omega`.
This PR remove simp priorities that are not needed. Some of these will
probably cause complaints from the `simpNF` linter downstream in
Batteries, which I will re-address separately.
This PR fixes a bug in the equational theorem generator for
`match`-expressions. See new test for an example.
Signed-off-by: Leonardo de Moura <leodemoura@amazon.com>
Co-authored-by: Leonardo de Moura <leodemoura@amazon.com>
This PR adds theorems `Nat.[shiftLeft_or_distrib`,
shiftLeft_xor_distrib`, shiftLeft_and_distrib`, `testBit_mul_two_pow`,
`bitwise_mul_two_pow`, `shiftLeft_bitwise_distrib]`, to prove
`Nat.shiftLeft_or_distrib` by emulating the proof strategy of
`shiftRight_and_distrib`.
In particular, `Nat.shiftLeft_or_distrib` is necessary to simplify the
proofs in #6476.
---------
Co-authored-by: Alex Keizer <alex@keizer.dev>
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 adds lemmas reducing for loops over `Std.Range` to for loops
over `List.range'`.
Equivalent theorems previously existed in Batteries, but the underlying
definitions have changed so these are written from scratch.
This PR replaces `List.lt` with `List.Lex`, from Mathlib, and adds the
new `Bool` valued lexicographic comparatory function `List.lex`. This
subtly changes the definition of `<` on Lists in some situations.
`List.lt` was a weaker relation: in particular if `l₁ < l₂`, then
`a :: l₁ < b :: l₂` may hold according to `List.lt` even if `a` and `b`
are merely incomparable
(either neither `a < b` nor `b < a`), whereas according to `List.Lex`
this would require `a = b`.
When `<` is total, in the sense that `¬ · < ·` is antisymmetric, then
the two relations coincide.
Mathlib was already overriding the order instances for `List α`,
so this change should not be noticed by anyone already using Mathlib.
We simultaneously add the boolean valued `List.lex` function,
parameterised by a `BEq` typeclass
and an arbitrary `lt` function. This will support the flexibility
previously provided for `List.lt`,
via a `==` function which is weaker than strict equality.
This PR adds `Nat` theorems for distributing `>>>` over bitwise
operations, paralleling those of `BitVec`.
This enables closing goals like the following using `simp`:
```lean
example (n : Nat) : (n <<< 2 ||| 3) >>> 2 = n := by simp [Nat.shiftRight_or_distrib]
```
It might be nice for these theorems to be `simp` lemmas, but they are
not currently in order to be consistent with the existing `BitVec` and
`div_two` theorems.
This PR adds theorems characterizing the value of the unsigned shift
right of a bitvector in terms of its 2s complement interpretation as an
integer.
Unsigned shift right by at least one bit makes the value of the
bitvector less than or equal to `2^(w-1)`,
makes the interpretation of the bitvector `Int` and `Nat` agree.
In the case when `n = 0`, then the shift right value equals the integer
interpretation.
```lean
theorem toInt_ushiftRight_eq_ite {x : BitVec w} {n : Nat} :
(x >>> n).toInt = if n = 0 then x.toInt else x.toNat >>> n
```
```lean
theorem toFin_uShiftRight {x : BitVec w} {n : Nat} :
(x >>> n).toFin = x.toFin / (Fin.ofNat' (2^w) (2^n))
```
---------
Co-authored-by: Harun Khan <harun19@stanford.edu>
Co-authored-by: Tobias Grosser <github@grosser.es>