From 3b41e432646accb50006f4d03aeb84fe36a8bf9d Mon Sep 17 00:00:00 2001 From: Luisa Cicolini <48860705+luisacicolini@users.noreply.github.com> Date: Tue, 4 Feb 2025 16:07:29 +0000 Subject: [PATCH] feat: add `BitVec.(getElem_umod_of_lt, getElem_umod, getLsbD_umod, getMsbD_umod)` (#6795) This PR adds theorems `BitVec.(getElem_umod_of_lt, getElem_umod, getLsbD_umod, getMsbD_umod)`. For the defiition of these theorems we rely on `divRec`, excluding the case where `d=0#w`, which is treated separately because there is no infrastructure to reason about this case within `divRec`. In particular, our implementation follows the mathlib standard [where division by 0 yields 0](https://github.com/leanprover/lean4/blob/c7c1e091c9f07ae6f8e8ff7246eb7650e2740dcb/src/Init/Data/BitVec/Basic.lean#L217), while in [SMTLIB this yields `allOnes`](https://github.com/leanprover/lean4/blob/c7c1e091c9f07ae6f8e8ff7246eb7650e2740dcb/src/Init/Data/BitVec/Basic.lean#L237). Co-authored by @bollu. --------- Co-authored-by: Siddharth --- src/Init/Data/BitVec/Bitblast.lean | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/Init/Data/BitVec/Bitblast.lean b/src/Init/Data/BitVec/Bitblast.lean index 003d35aa2c..2b2567224c 100644 --- a/src/Init/Data/BitVec/Bitblast.lean +++ b/src/Init/Data/BitVec/Bitblast.lean @@ -1230,4 +1230,33 @@ theorem shiftRight_eq_ushiftRightRec (x : BitVec w₁) (y : BitVec w₂) : · simp [of_length_zero] · simp [ushiftRightRec_eq] +/- ### umod -/ + +theorem getElem_umod {n d : BitVec w} (hi : i < w) : + (n % d)[i] + = if d = 0#w then n[i] + else (divRec w { n := n, d := d } (DivModState.init w)).r[i] := by + by_cases hd : d = 0#w + · simp [hd] + · have := (BitVec.not_le (x := d) (y := 0#w)).mp + rw [← BitVec.umod_eq_divRec (by simp [hd, this])] + simp [hd] + +theorem getLsbD_umod {n d : BitVec w}: + (n % d).getLsbD i + = if d = 0#w then n.getLsbD i + else (divRec w { n := n, d := d } (DivModState.init w)).r.getLsbD i := by + by_cases hi : i < w + · simp only [BitVec.getLsbD_eq_getElem hi, getElem_umod] + · simp [show w ≤ i by omega] + +theorem getMsbD_umod {n d : BitVec w}: + (n % d).getMsbD i + = if d = 0#w then n.getMsbD i + else (divRec w { n := n, d := d } (DivModState.init w)).r.getMsbD i := by + by_cases hi : i < w + · rw [BitVec.getMsbD_eq_getLsbD, getLsbD_umod] + simp [BitVec.getMsbD_eq_getLsbD, hi] + · simp [show w ≤ i by omega] + end BitVec