From 597ef8cfee46b87d573f58d3ae28db7c5b71d983 Mon Sep 17 00:00:00 2001 From: Luisa Cicolini <48860705+luisacicolini@users.noreply.github.com> Date: Wed, 27 Nov 2024 03:48:59 +0000 Subject: [PATCH] feat: add `Nat.mod_eq_sub` and fix dependencies from `Nat.sub_mul_eq_mod_of_lt_of_le` (#6160) This PR adds theorem `mod_eq_sub`, makes theorem `sub_mul_eq_mod_of_lt_of_le` not private anymore and moves its location within the `rotate*` section to use it in other proofs. --- src/Init/Data/BitVec/Lemmas.lean | 36 +++++++++++++------------------- src/Init/Data/Nat/Lemmas.lean | 4 ++++ 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/src/Init/Data/BitVec/Lemmas.lean b/src/Init/Data/BitVec/Lemmas.lean index 5c931f353c4f..5399381b3e49 100644 --- a/src/Init/Data/BitVec/Lemmas.lean +++ b/src/Init/Data/BitVec/Lemmas.lean @@ -2758,12 +2758,6 @@ theorem getElem_rotateLeft {x : BitVec w} {r i : Nat} (h : i < w) : if h' : i < r % w then x[(w - (r % w) + i)] else x[i - (r % w)] := by simp [← BitVec.getLsbD_eq_getElem, h] -/-- If `w ≤ x < 2 * w`, then `x % w = x - w` -/ -theorem mod_eq_sub_of_le_of_lt {x w : Nat} (x_le : w ≤ x) (x_lt : x < 2 * w) : - x % w = x - w := by - rw [Nat.mod_eq_sub_mod, Nat.mod_eq_of_lt (by omega)] - omega - theorem getMsbD_rotateLeftAux_of_lt {x : BitVec w} {r : Nat} {i : Nat} (hi : i < w - r) : (x.rotateLeftAux r).getMsbD i = x.getMsbD (r + i) := by rw [rotateLeftAux, getMsbD_or] @@ -2773,6 +2767,20 @@ theorem getMsbD_rotateLeftAux_of_ge {x : BitVec w} {r : Nat} {i : Nat} (hi : i (x.rotateLeftAux r).getMsbD i = (decide (i < w) && x.getMsbD (i - (w - r))) := by simp [rotateLeftAux, getMsbD_or, show i + r ≥ w by omega, show ¬i < w - r by omega] +/-- +If a number `w * n ≤ i < w * (n + 1)`, then `i - w * n` equals `i % w`. +This is true by subtracting `w * n` from the inequality, giving +`0 ≤ i - w * n < w`, which uniquely identifies `i % w`. +-/ +private theorem Nat.sub_mul_eq_mod_of_lt_of_le (hlo : w * n ≤ i) (hhi : i < w * (n + 1)) : + i - w * n = i % w := by + rw [Nat.mod_def] + congr + symm + apply Nat.div_eq_of_lt_le + (by rw [Nat.mul_comm]; omega) + (by rw [Nat.mul_comm]; omega) + /-- When `r < w`, we give a formula for `(x.rotateLeft r).getMsbD i`. -/ theorem getMsbD_rotateLeft_of_lt {n w : Nat} {x : BitVec w} (hi : r < w): (x.rotateLeft r).getMsbD n = (decide (n < w) && x.getMsbD ((r + n) % w)) := by @@ -2785,8 +2793,8 @@ theorem getMsbD_rotateLeft_of_lt {n w : Nat} {x : BitVec w} (hi : r < w): by_cases h₁ : n < w + 1 · simp only [h₁, decide_true, Bool.true_and] have h₂ : (r + n) < 2 * (w + 1) := by omega - rw [mod_eq_sub_of_le_of_lt (by omega) (by omega)] congr 1 + rw [← Nat.sub_mul_eq_mod_of_lt_of_le (n := 1) (by omega) (by omega), Nat.mul_one] omega · simp [h₁] @@ -3103,20 +3111,6 @@ theorem replicate_succ_eq {x : BitVec w} : (x ++ replicate n x).cast (by rw [Nat.mul_succ]; omega) := by simp [replicate] -/-- -If a number `w * n ≤ i < w * (n + 1)`, then `i - w * n` equals `i % w`. -This is true by subtracting `w * n` from the inequality, giving -`0 ≤ i - w * n < w`, which uniquely identifies `i % w`. --/ -private theorem Nat.sub_mul_eq_mod_of_lt_of_le (hlo : w * n ≤ i) (hhi : i < w * (n + 1)) : - i - w * n = i % w := by - rw [Nat.mod_def] - congr - symm - apply Nat.div_eq_of_lt_le - (by rw [Nat.mul_comm]; omega) - (by rw [Nat.mul_comm]; omega) - @[simp] theorem getLsbD_replicate {n w : Nat} (x : BitVec w) : (x.replicate n).getLsbD i = diff --git a/src/Init/Data/Nat/Lemmas.lean b/src/Init/Data/Nat/Lemmas.lean index 4b9bad521f4d..b0530b5a6a86 100644 --- a/src/Init/Data/Nat/Lemmas.lean +++ b/src/Init/Data/Nat/Lemmas.lean @@ -679,6 +679,10 @@ theorem add_mod (a b n : Nat) : (a + b) % n = ((a % n) + (b % n)) % n := by @[simp] theorem mod_mul_mod {a b c : Nat} : (a % c * b) % c = a * b % c := by rw [mul_mod, mod_mod, ← mul_mod] +theorem mod_eq_sub (x w : Nat) : x % w = x - w * (x / w) := by + conv => rhs; congr; rw [← mod_add_div x w] + simp + /-! ### pow -/ theorem pow_succ' {m n : Nat} : m ^ n.succ = m * m ^ n := by