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 29 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
8e26dee
feat; add overflow defs
luisacicolini Jan 13, 2025
8c64c87
chore: add smtlib names in docstrings
luisacicolini Jan 13, 2025
8c3448f
chore: fix docstrings
luisacicolini Jan 14, 2025
c8ed74e
chore: fix definition case
luisacicolini Jan 14, 2025
7026bd1
chore: only add
luisacicolini Jan 22, 2025
7d0c873
chore: uadd, sadd
luisacicolini Jan 22, 2025
686141a
chore: add theorems
luisacicolini Jan 22, 2025
b005e45
chore: remove not-overflow
luisacicolini Jan 22, 2025
3f33283
chore: formatting
luisacicolini Jan 22, 2025
95e3c01
chore: formatting
luisacicolini Jan 22, 2025
65be585
choire: move to normalize
luisacicolini Jan 22, 2025
58de782
chore: formatting
luisacicolini Jan 22, 2025
7f4f484
chore: formatting
luisacicolini Jan 22, 2025
befd15a
chore: formatting
luisacicolini Jan 22, 2025
cd84f3a
chore: move overflow theorems back
luisacicolini Jan 22, 2025
77bb974
chore: move all theorems
luisacicolini Jan 22, 2025
a8470b4
chore: add attribute to normalize
luisacicolini Jan 22, 2025
4c582c2
chore: move int theorem
luisacicolini Jan 22, 2025
a315c89
chore: merge master
luisacicolini Jan 22, 2025
1e3e07b
chore: update housing of theorems
luisacicolini Jan 22, 2025
ab1d3d5
chore: formatting
luisacicolini Jan 22, 2025
ffe861e
chore: everyone found their spot but everything is broken
luisacicolini Jan 22, 2025
7af6bb8
chore: more fixing in places
luisacicolini Jan 22, 2025
4115b36
chore: le_toInt works
luisacicolini Jan 22, 2025
04f49e4
chore: fix toInt_lt
luisacicolini Jan 22, 2025
ddceb18
chore: replace rcases
luisacicolini Jan 22, 2025
bd24dbd
chore: uncomment proofs
luisacicolini Jan 23, 2025
df55e51
chore: parentheses format
luisacicolini Jan 23, 2025
cf259c0
feat: add tests
luisacicolini Jan 23, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/Init/Data/BitVec/Basic.lean
Original file line number Diff line number Diff line change
Expand Up @@ -669,4 +669,20 @@ def ofBoolListLE : (bs : List Bool) → BitVec bs.length
| [] => 0#0
| b :: bs => concat (ofBoolListLE bs) b

/-! ## Overflow -/

/-- Overflow predicate for unsigned addition modulo 2^w.

SMT-Lib name: `bvuaddo`.
-/

def uaddOverflow {w : Nat} (x y : BitVec w) : Bool := x.toNat + y.toNat ≥ 2 ^ w
luisacicolini marked this conversation as resolved.
Show resolved Hide resolved

/-- Overflow predicate for signed addition on w-bit 2's complement.

SMT-Lib name: `bvsaddo`.
-/

def saddOverflow {w : Nat} (x y : BitVec w) : Bool := (x.toInt + y.toInt ≥ 2 ^ (w - 1)) || (x.toInt + y.toInt < - 2 ^ (w - 1))
luisacicolini marked this conversation as resolved.
Show resolved Hide resolved

end BitVec
35 changes: 35 additions & 0 deletions src/Init/Data/BitVec/Lemmas.lean
Original file line number Diff line number Diff line change
Expand Up @@ -3536,6 +3536,41 @@ 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)]

/-! ### Overflow definitions -/


luisacicolini marked this conversation as resolved.
Show resolved Hide resolved
theorem Int.bmod_two_pow_neg_iff {w : Nat} {x : Int} (h1 : x < 2 ^ w) (h2 : -(2 ^ w) ≤ x) :
(x.bmod (2 ^ w)) < 0 ↔ (-(2 ^ w) ≤ 2 * x ∧ x < 0) ∨ (2 ^ w ≤ 2 * x) := by
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
luisacicolini marked this conversation as resolved.
Show resolved Hide resolved

theorem uaddOverflow_eq {w : Nat} (x y : BitVec w) :
uaddOverflow x y = BitVec.carry w x y false := by
simp only [uaddOverflow, BitVec.carry]
by_cases h : 2 ^ w ≤ x.toNat + y.toNat <;> simp [h]

theorem saddOverflow_eq {w : Nat} (x y : BitVec w) :
saddOverflow x y = true ↔ x.msb = y.msb ∧ ¬(x + y).msb = x.msb := by
simp only [saddOverflow]
rcases w with _|w'
· revert x y
decide
· have h : 0 < w' + 1 := by omega
generalize w' + 1 = w at *
have := le_toInt x
have := le_toInt y
have := toInt_lt y
have := toInt_lt x
have := toInd_add_toInt_lt_two_pow x y
have := neg_two_pow_le_toInd_add_toInt x y
luisacicolini marked this conversation as resolved.
Show resolved Hide resolved
simp only [ge_iff_le, Bool.or_eq_true, decide_eq_true_eq, BitVec.msb_eq_toInt,
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


luisacicolini marked this conversation as resolved.
Show resolved Hide resolved
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.

/-! ### Non-overflow theorems -/

Expand Down