|
1 | 1 | /-
|
2 | 2 | Copyright (c) 2020 Markus Himmel. All rights reserved.
|
3 | 3 | Released under Apache 2.0 license as described in the file LICENSE.
|
4 |
| -Authors: Markus Himmel |
| 4 | +Authors: Markus Himmel, Alex Keizer |
5 | 5 | -/
|
6 | 6 | import Lean.Elab.Tactic
|
7 | 7 | import Mathlib.Data.List.Basic
|
8 | 8 | import Mathlib.Data.Nat.Bits
|
9 | 9 | import Mathlib.Data.Nat.Size
|
10 | 10 | import Mathlib.Data.Nat.Order.Lemmas
|
11 | 11 | import Mathlib.Tactic.Linarith
|
| 12 | +import Mathlib.Tactic.Ring |
12 | 13 |
|
13 | 14 | #align_import data.nat.bitwise from "leanprover-community/mathlib"@"6afc9b06856ad973f6a2619e3e8a0a8d537a58f2"
|
14 | 15 |
|
@@ -44,6 +45,104 @@ namespace Nat
|
44 | 45 |
|
45 | 46 | set_option linter.deprecated false
|
46 | 47 |
|
| 48 | +section |
| 49 | +variable {f : Bool → Bool → Bool} |
| 50 | + |
| 51 | +lemma bitwise'_bit' {f : Bool → Bool → Bool} (a : Bool) (m : Nat) (b : Bool) (n : Nat) |
| 52 | + (ham : m = 0 → a = true) (hbn : n = 0 → b = true) : |
| 53 | + bitwise' f (bit a m) (bit b n) = bit (f a b) (bitwise' f m n) := by |
| 54 | + rw [bitwise', binaryRec_eq', binaryRec_eq'] |
| 55 | + · apply Or.inr hbn |
| 56 | + · apply Or.inr ham |
| 57 | + |
| 58 | +@[simp] |
| 59 | +lemma bitwise_zero_left (m : Nat) : bitwise f 0 m = if f false true then m else 0 := |
| 60 | + rfl |
| 61 | + |
| 62 | +@[simp] |
| 63 | +lemma bitwise_zero_right (n : Nat) : bitwise f n 0 = if f true false then n else 0 := by |
| 64 | + unfold bitwise |
| 65 | + simp only [ite_self, decide_False, Nat.zero_div, ite_true, ite_eq_right_iff] |
| 66 | + rintro ⟨⟩ |
| 67 | + split_ifs <;> rfl |
| 68 | + |
| 69 | +@[simp] |
| 70 | +theorem bitwise'_zero_right (m : Nat) : |
| 71 | + bitwise' f m 0 = bif f true false then m else 0 := by |
| 72 | + unfold bitwise' binaryRec |
| 73 | + simp only [Bool.cond_eq_ite, eq_mpr_eq_cast, cast_eq, dite_eq_ite] |
| 74 | + split_ifs with hx <;> simp only [bit_decomp, binaryRec_zero, hx] |
| 75 | + |
| 76 | +lemma bitwise_zero : bitwise f 0 0 = 0 := by |
| 77 | + simp only [bitwise_zero_right, ite_self] |
| 78 | + |
| 79 | +@[simp] |
| 80 | +lemma bitwise_of_ne_zero {n m : Nat} (hn : n ≠ 0) (hm : m ≠ 0) : |
| 81 | + bitwise f n m = bit (f (bodd n) (bodd m)) (bitwise f (n / 2) (m / 2)) := by |
| 82 | + conv_lhs => { unfold bitwise } |
| 83 | + have mod_two_iff_bod x : (x % 2 = 1 : Bool) = bodd x := by |
| 84 | + simp [mod_two_of_bodd, cond]; cases bodd x <;> rfl |
| 85 | + simp only [hn, hm, mod_two_iff_bod, ite_false, bit, bit1, bit0, Bool.cond_eq_ite] |
| 86 | + split_ifs <;> rfl |
| 87 | + |
| 88 | +@[simp] |
| 89 | +lemma bitwise'_of_ne_zero {n m : Nat} (hn : n ≠ 0) (hm : m ≠ 0) : |
| 90 | + bitwise' f n m = bit (f (bodd n) (bodd m)) (bitwise' f (n / 2) (m / 2)) := by |
| 91 | + conv_lhs => { rw [←bit_decomp n, ←bit_decomp m] } |
| 92 | + rw [bitwise'_bit', bit, div2_val, div2_val] |
| 93 | + case ham => |
| 94 | + obtain ⟨⟩ | n := n |
| 95 | + · contradiction |
| 96 | + · simp only [div2_succ, cond, bodd_succ, Bool.not_not] |
| 97 | + cases bodd n <;> simp |
| 98 | + case hbn => |
| 99 | + obtain ⟨⟩ | m := m |
| 100 | + · contradiction |
| 101 | + · simp only [div2_succ, cond, bodd_succ, Bool.not_not] |
| 102 | + cases bodd m <;> simp |
| 103 | + |
| 104 | +lemma bitwise'_eq_bitwise (f) : bitwise' f = bitwise f := by |
| 105 | + funext x y |
| 106 | + induction' x using Nat.strongInductionOn with x ih generalizing y |
| 107 | + cases' x with x <;> cases' y with y |
| 108 | + · simp only [bitwise_zero, bitwise'_zero] |
| 109 | + · simp only [bitwise_zero_left, bitwise'_zero_left, Bool.cond_eq_ite] |
| 110 | + · simp only [bitwise_zero_right, bitwise'_zero_right, Bool.cond_eq_ite] |
| 111 | + · specialize ih ((x+1) / 2) (div_lt_self' ..) |
| 112 | + simp only [ne_eq, succ_ne_zero, not_false_eq_true, bitwise'_of_ne_zero, ih, bitwise_of_ne_zero] |
| 113 | + |
| 114 | +theorem lor'_eq_lor : lor' = lor := |
| 115 | + bitwise'_eq_bitwise _ |
| 116 | + |
| 117 | +theorem land'_eq_land : land' = land := |
| 118 | + bitwise'_eq_bitwise _ |
| 119 | + |
| 120 | +theorem xor'_eq_xor : lxor' = xor := by |
| 121 | + unfold lxor' xor |
| 122 | + have : _root_.xor = bne := by |
| 123 | + funext x y; cases x <;> cases y <;> rfl |
| 124 | + rw [this] |
| 125 | + exact bitwise'_eq_bitwise _ |
| 126 | + |
| 127 | +@[simp] |
| 128 | +lemma bitwise_bit {f : Bool → Bool → Bool} (h : f false false = false := by rfl) (a m b n) : |
| 129 | + bitwise f (bit a m) (bit b n) = bit (f a b) (bitwise f m n) := by |
| 130 | + simp only [←bitwise'_eq_bitwise, bitwise'_bit h] |
| 131 | + |
| 132 | +@[simp] |
| 133 | +theorem lor_bit : ∀ a m b n, lor (bit a m) (bit b n) = bit (a || b) (lor m n) := |
| 134 | + bitwise_bit |
| 135 | + |
| 136 | +@[simp] |
| 137 | +theorem land_bit : ∀ a m b n, land (bit a m) (bit b n) = bit (a && b) (land m n) := |
| 138 | + bitwise_bit |
| 139 | + |
| 140 | +@[simp] |
| 141 | +theorem lxor_bit : ∀ a m b n, xor (bit a m) (bit b n) = bit (bne a b) (xor m n) := |
| 142 | + bitwise_bit |
| 143 | + |
| 144 | +end |
| 145 | + |
47 | 146 | @[simp]
|
48 | 147 | theorem bit_false : bit false = bit0 :=
|
49 | 148 | rfl
|
@@ -161,6 +260,17 @@ theorem testBit_two_pow (n m : ℕ) : testBit (2 ^ n) m = (n = m) := by
|
161 | 260 | simp [h]
|
162 | 261 | #align nat.test_bit_two_pow Nat.testBit_two_pow
|
163 | 262 |
|
| 263 | +theorem bitwise'_swap {f : Bool → Bool → Bool} (h : f false false = false) : |
| 264 | + bitwise' (Function.swap f) = Function.swap (bitwise' f) := by |
| 265 | + funext m n; revert n |
| 266 | + dsimp [Function.swap] |
| 267 | + apply binaryRec _ _ m <;> intro n |
| 268 | + · rw [bitwise'_zero_left, bitwise'_zero_right, Bool.cond_eq_ite] |
| 269 | + · intros a ih m' |
| 270 | + apply bitCasesOn m'; intro b n' |
| 271 | + rw [bitwise'_bit, bitwise'_bit, ih] <;> exact h |
| 272 | +#align nat.bitwise_swap Nat.bitwise'_swap |
| 273 | + |
164 | 274 | /-- If `f` is a commutative operation on bools such that `f false false = false`, then `bitwise f`
|
165 | 275 | is also commutative. -/
|
166 | 276 | theorem bitwise'_comm {f : Bool → Bool → Bool} (hf : ∀ b b', f b b' = f b' b)
|
|
0 commit comments