Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add SMT-LIB overflow on addition for bitvectors (uadd_overflow,sadd_overflow, uadd_overflow_eq,sadd_overflow_eq) and support theorems #6628

Draft
wants to merge 26 commits into
base: master
Choose a base branch
from

Conversation

luisacicolini
Copy link
Contributor

@luisacicolini luisacicolini commented Jan 13, 2025

This PR adds SMT-LIB operators to detect overflow (uadd_overflow,sadd_overflow), according to the definitions here, and the theorems proving equivalence of such definitions with the BitVec library functions (uadd_overflow_eq, sadd_overflow_eq). Support theorems for these proofs are toInt_lt, le_toInt, toInd_add_toInt_lt_two_pow, neg_two_pow_le_toInd_add_toInt, bmod_two_pow_neg_iff, emod_eq_add_self_emo.

@github-actions github-actions bot added the toolchain-available A toolchain is available for this PR, at leanprover/lean4-pr-releases:pr-release-NNNN label Jan 13, 2025
@leanprover-community-bot
Copy link
Collaborator

leanprover-community-bot commented Jan 13, 2025

Mathlib CI status (docs):

  • ❗ Batteries/Mathlib CI will not be attempted unless your PR branches off the nightly-with-mathlib branch. Try git rebase 8483ac7258b84b179f3ec369df533452afdeb758 --onto d2c4471cfa4611977bf4927b5cd849df1a4272b7. (2025-01-13 14:04:32)
  • ❗ Batteries/Mathlib CI will not be attempted unless your PR branches off the nightly-with-mathlib branch. Try git rebase 8483ac7258b84b179f3ec369df533452afdeb758 --onto e9bd9807ef7a983365df9ac55d35040d0b2d5ef2. (2025-01-14 14:29:28)

@github-actions github-actions bot added the changelog-library Library label Jan 13, 2025
@luisacicolini
Copy link
Contributor Author

changelog-library

@luisacicolini luisacicolini marked this pull request as ready for review January 13, 2025 17:37
@luisacicolini luisacicolini requested a review from kim-em as a code owner January 13, 2025 17:37
@leanprover-bot leanprover-bot added the P-medium We may work on this issue if we find the time label Jan 14, 2025
@kim-em
Copy link
Collaborator

kim-em commented Jan 15, 2025

What are your plans for adding theorems about these?

@luisacicolini
Copy link
Contributor Author

Ideally supporting them in bvdecide - although there are some proofs missing (they're taking me more time than I expected), so I'll draft the PR for now and open it when the proofs are done!

@luisacicolini luisacicolini marked this pull request as draft January 15, 2025 08:34
@kim-em
Copy link
Collaborator

kim-em commented Jan 15, 2025

Okay! I'm happy with these definitions, and checked them against the reference, so I'm happy to click merge as soon as we're sure they are going to be used.

@luisacicolini luisacicolini changed the title feat: add SMT-LIB overflow definitions for bitvectors (not_overflow,uadd_overflow,sadd_overflow,umul_overflow,smul_overflow) feat: add SMT-LIB overflow on addition for bitvectors (uadd_overflow,sadd_overflow, uadd_overflow_eq,sadd_overflow_eq) Jan 22, 2025
luisacicolini and others added 2 commits January 22, 2025 12:51
Co-authored-by: Tobias Grosser <[email protected]>
Co-authored-by: Tobias Grosser <[email protected]>
src/Init/Data/BitVec/Basic.lean Outdated Show resolved Hide resolved
src/Init/Data/BitVec/Basic.lean Outdated Show resolved Hide resolved
src/Init/Data/BitVec/Lemmas.lean Outdated Show resolved Hide resolved
Co-authored-by: Alex Keizer <[email protected]>
decide_eq_decide, BitVec.toInt_add]
rw [bmod_two_pow_neg_iff (by omega) (by omega)]
rw_mod_cast [← @Nat.two_pow_pred_add_two_pow_pred w (by omega)] at *
omega
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@luisacicolini, keep these theorems in Lemmas.lean. However, you should add a here lines attribute [bv_normalize] BitVec.saddOverflow_eq ....

@@ -542,6 +542,62 @@ theorem eq_zero_or_eq_one (a : BitVec 1) : a = 0#1 ∨ a = 1#1 := by
theorem toInt_zero {w : Nat} : (0#w).toInt = 0 := by
simp [BitVec.toInt, show 0 < 2^w by exact Nat.two_pow_pos w]

theorem toInt_lt {w : Nat} (x : BitVec w) : x.toInt < 2 ^ (w - 1) := by
simp only [BitVec.toInt, Nat.cast_pow]
by_cases hw : w = 0
Copy link
Contributor

@tobiasgrosser tobiasgrosser Jan 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would using cases or rcases remove the need for a subst here? Similarly, below.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it should, will give it a try

@luisacicolini
Copy link
Contributor Author

Unfortunately, some theorems live in Mathlib and quite a few things break as a consequence. I'm specializing some of these to see whether we can continue using them, but would be great to just avoid them (and find alternative proof strategies)

@@ -3579,7 +3635,6 @@ theorem getLsbD_intMax (w : Nat) : (intMax w).getLsbD i = decide (i + 1 < w) :=
· simp [h]
· rw [Nat.sub_add_cancel (Nat.two_pow_pos (w - 1)), Nat.two_pow_pred_mod_two_pow (by omega)]


Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems unrelated.

@luisacicolini luisacicolini changed the title feat: add SMT-LIB overflow on addition for bitvectors (uadd_overflow,sadd_overflow, uadd_overflow_eq,sadd_overflow_eq) feat: add SMT-LIB overflow on addition for bitvectors (uadd_overflow,sadd_overflow, uadd_overflow_eq,sadd_overflow_eq) and support theorems (toInt_lt, le_toInt, toInd_add_toInt_lt_two_pow, neg_two_pow_le_toInd_add_toInt, bmod_two_pow_neg_iff, emod_eq_add_self_emo) Jan 22, 2025
@luisacicolini luisacicolini changed the title feat: add SMT-LIB overflow on addition for bitvectors (uadd_overflow,sadd_overflow, uadd_overflow_eq,sadd_overflow_eq) and support theorems (toInt_lt, le_toInt, toInd_add_toInt_lt_two_pow, neg_two_pow_le_toInd_add_toInt, bmod_two_pow_neg_iff, emod_eq_add_self_emo) feat: add SMT-LIB overflow on addition for bitvectors (uadd_overflow,sadd_overflow, uadd_overflow_eq,sadd_overflow_eq) and support theorems Jan 22, 2025
@luisacicolini
Copy link
Contributor Author

luisacicolini commented Jan 22, 2025

Fixed what I could, I am now stuck on bmod_two_pow_neg_iff, @alexkeizer or @tobiasgrosser if you could take a look it would be great!

-- simp only [Int.bmod_def, Nat.cast_pow, Nat.cast_ofNat]
-- by_cases xpos : 0 ≤ x
-- · rw [Int.emod_eq_of_lt (by omega) (by omega)]; omega
-- · rw [Int.emod_eq_add_self_emod, Int.emod_eq_of_lt (by omega) (by omega)]; omega
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why don't you pull the missing theorems from mathlib?

@@ -319,6 +319,9 @@ attribute [bv_normalize] BitVec.umod_zero
attribute [bv_normalize] BitVec.umod_one
attribute [bv_normalize] BitVec.umod_eq_and

attribute [bv_normalize] BitVec.saddOverflow_eq
attribute [bv_normalize] BitVec.uaddOverflow_eq

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We still need test cases of bv_normalize.

@@ -1348,3 +1348,16 @@ theorem bmod_natAbs_plus_one (x : Int) (w : 1 < x.natAbs) : bmod x (x.natAbs + 1
all_goals decide
· exact ofNat_nonneg x
· exact succ_ofNat_pos (x + 1)

-- stolen from Mathlib as-is
theorem emod_eq_add_self_emod {a b : Int} : a % b = (a + b) % b :=
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop this comment, instead add it to the PR message.

Comment on lines +573 to +574
(x.toInt + y.toInt) < 2 ^ w := by
rcases w with _|w'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
(x.toInt + y.toInt) < 2 ^ w := by
rcases w with _|w'
x.toInt + y.toInt < 2 ^ w := by
rcases w with _|w'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
changelog-library Library P-medium We may work on this issue if we find the time toolchain-available A toolchain is available for this PR, at leanprover/lean4-pr-releases:pr-release-NNNN
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants