File: .lake/packages/lean4/src/lean/Init/Data/Nat/Bitwise/Lemmas.lean

full_name: _private.«.lake».packages.lean4.src.lean.Init.Data.Nat.Bitwise.Lemmas.0.Nat.one_div_two
code: @[local simp]
private theorem one_div_two : 1/2 = 0 
goal: 1 / 2 = 0

full_name: _private.«.lake».packages.lean4.src.lean.Init.Data.Nat.Bitwise.Lemmas.0.Nat.two_pow_succ_sub_succ_div_two
code: private theorem two_pow_succ_sub_succ_div_two : (2 ^ (n+1) - (x + 1)) / 2 = 2^n - (x/2 + 1) 
goal: (2 ^ (n + 1) - (x + 1)) / 2 = 2 ^ n - (x / 2 + 1)

full_name: _private.«.lake».packages.lean4.src.lean.Init.Data.Nat.Bitwise.Lemmas.0.Nat.two_pow_succ_sub_one_div_two
code: private theorem two_pow_succ_sub_one_div_two : (2 ^ (n+1) - 1) / 2 = 2^n - 1 
goal: (2 ^ (n + 1) - 1) / 2 = 2 ^ n - 1

full_name: _private.«.lake».packages.lean4.src.lean.Init.Data.Nat.Bitwise.Lemmas.0.Nat.two_mul_sub_one
code: private theorem two_mul_sub_one {n : Nat} (n_pos : n > 0) : (2*n - 1) % 2 = 1 
goal: (2 * n - 1) % 2 = 1

full_name: Nat.div2Induction
code: /--
An induction principal that works on divison by two.
-/
noncomputable def div2Induction {motive : Nat → Sort u}
    (n : Nat) (ind : ∀(n : Nat), (n > 0 → motive (n/2)) → motive n) : motive n 
goal: motive n

full_name: Nat.zero_and
code: @[simp] theorem zero_and (x : Nat) : 0 &&& x = 0 
goal: 0 &&& x = 0

full_name: Nat.and_zero
code: @[simp] theorem and_zero (x : Nat) : x &&& 0 = 0 
goal: x &&& 0 = 0

full_name: Nat.one_and_eq_mod_two
code: @[simp] theorem one_and_eq_mod_two (n : Nat) : 1 &&& n = n % 2 
goal: 1 &&& n = n % 2

full_name: Nat.and_one_is_mod
code: @[simp] theorem and_one_is_mod (x : Nat) : x &&& 1 = x % 2 
goal: x &&& 1 = x % 2

full_name: Nat.zero_testBit
code: @[simp] theorem zero_testBit (i : Nat) : testBit 0 i = false 
goal: Nat.testBit 0 i = false

full_name: Nat.testBit_zero
code: @[simp] theorem testBit_zero (x : Nat) : testBit x 0 = decide (x % 2 = 1) 
goal: x.testBit 0 = decide (x % 2 = 1)

full_name: Nat.testBit_succ
code: @[simp] theorem testBit_succ (x i : Nat) : testBit x (succ i) = testBit (x/2) i 
goal: x.testBit i.succ = (x / 2).testBit i

full_name: Nat.testBit_add_one
code: @[simp] theorem testBit_add_one (x i : Nat) : testBit x (i + 1) = testBit (x/2) i 
goal: x.testBit (i + 1) = (x / 2).testBit i

full_name: Nat.testBit_to_div_mod
code: theorem testBit_to_div_mod {x : Nat} : testBit x i = decide (x / 2^i % 2 = 1) 
goal: x.testBit i = decide (x / 2 ^ i % 2 = 1)

full_name: Nat.toNat_testBit
code: theorem toNat_testBit (x i : Nat) :
    (x.testBit i).toNat = x / 2 ^ i % 2 
goal: (x.testBit i).toNat = x / 2 ^ i % 2

full_name: Nat.ne_zero_implies_bit_true
code: theorem ne_zero_implies_bit_true {x : Nat} (xnz : x ≠ 0) : ∃ i, testBit x i 
goal: ∃ i, x.testBit i = true

full_name: Nat.ne_implies_bit_diff
code: theorem ne_implies_bit_diff {x y : Nat} (p : x ≠ y) : ∃ i, testBit x i ≠ testBit y i 
goal: ∃ i, x.testBit i ≠ y.testBit i

full_name: Nat.eq_of_testBit_eq
code: /--
`eq_of_testBit_eq` allows proving two natural numbers are equal
if their bits are all equal.
-/
theorem eq_of_testBit_eq {x y : Nat} (pred : ∀i, testBit x i = testBit y i) : x = y 
goal: x = y

full_name: Nat.ge_two_pow_implies_high_bit_true
code: theorem ge_two_pow_implies_high_bit_true {x : Nat} (p : x ≥ 2^n) : ∃ i, i ≥ n ∧ testBit x i 
goal: ∃ i, i ≥ n ∧ x.testBit i = true

full_name: Nat.testBit_implies_ge
code: theorem testBit_implies_ge {x : Nat} (p : testBit x i = true) : x ≥ 2^i 
goal: x ≥ 2 ^ i

full_name: Nat.testBit_lt_two_pow
code: theorem testBit_lt_two_pow {x i : Nat} (lt : x < 2^i) : x.testBit i = false 
goal: x.testBit i = false

full_name: Nat.lt_pow_two_of_testBit
code: theorem lt_pow_two_of_testBit (x : Nat) (p : ∀i, i ≥ n → testBit x i = false) : x < 2^n 
goal: x < 2 ^ n

full_name: _private.«.lake».packages.lean4.src.lean.Init.Data.Nat.Bitwise.Lemmas.0.Nat.succ_mod_two
code: private theorem succ_mod_two : succ x % 2 = 1 - x % 2 
goal: x.succ % 2 = 1 - x % 2

full_name: _private.«.lake».packages.lean4.src.lean.Init.Data.Nat.Bitwise.Lemmas.0.Nat.testBit_succ_zero
code: private theorem testBit_succ_zero : testBit (x + 1) 0 = not (testBit x 0) 
goal: (x + 1).testBit 0 = !x.testBit 0

full_name: Nat.testBit_two_pow_add_eq
code: theorem testBit_two_pow_add_eq (x i : Nat) : testBit (2^i + x) i = not (testBit x i) 
goal: (2 ^ i + x).testBit i = !x.testBit i

full_name: Nat.testBit_mul_two_pow_add_eq
code: theorem testBit_mul_two_pow_add_eq (a b i : Nat) :
    testBit (2^i*a + b) i = Bool.xor (a%2 = 1) (testBit b i) 
goal: (2 ^ i * a + b).testBit i = (decide (a % 2 = 1)).xor (b.testBit i)

full_name: Nat.testBit_two_pow_add_gt
code: theorem testBit_two_pow_add_gt {i j : Nat} (j_lt_i : j < i) (x : Nat) :
    testBit (2^i + x) j = testBit x j 
goal: (2 ^ i + x).testBit j = x.testBit j

full_name: Nat.testBit_mod_two_pow
code: @[simp] theorem testBit_mod_two_pow (x j i : Nat) :
    testBit (x % 2^j) i = (decide (i < j) && testBit x i) 
goal: (x % 2 ^ j).testBit i = (decide (i < j) && x.testBit i)

full_name: Nat.testBit_one_zero
code: theorem testBit_one_zero : testBit 1 0 = true 
goal: Nat.testBit 1 0 = true

full_name: Nat.not_decide_mod_two_eq_one
code: theorem not_decide_mod_two_eq_one (x : Nat)
    : (!decide (x % 2 = 1)) = decide (x % 2 = 0) 
goal: (!decide (x % 2 = 1)) = decide (x % 2 = 0)

full_name: Nat.testBit_two_pow_sub_succ
code: theorem testBit_two_pow_sub_succ (h₂ : x < 2 ^ n) (i : Nat) :
    testBit (2^n - (x + 1)) i = (decide (i < n) && ! testBit x i) 
goal: (2 ^ n - (x + 1)).testBit i = (decide (i < n) && !x.testBit i)

full_name: Nat.testBit_two_pow_sub_one
code: @[simp] theorem testBit_two_pow_sub_one (n i : Nat) : testBit (2^n-1) i = decide (i < n) 
goal: (2 ^ n - 1).testBit i = decide (i < n)

full_name: Nat.testBit_bool_to_nat
code: theorem testBit_bool_to_nat (b : Bool) (i : Nat) :
    testBit (Bool.toNat b) i = (decide (i = 0) && b) 
goal: b.toNat.testBit i = (decide (i = 0) && b)

full_name: Nat.testBit_one_eq_true_iff_self_eq_zero
code: /-- `testBit 1 i` is true iff the index `i` equals 0. -/
theorem testBit_one_eq_true_iff_self_eq_zero {i : Nat} :
    Nat.testBit 1 i = true ↔ i = 0 
goal: Nat.testBit 1 i = true ↔ i = 0

full_name: Nat.testBit_bitwise
code: theorem testBit_bitwise
  (false_false_axiom : f false false = false) (x y i : Nat)
: (bitwise f x y).testBit i = f (x.testBit i) (y.testBit i) 
goal: (Nat.bitwise f x y).testBit i = f (x.testBit i) (y.testBit i)

full_name: _private.«.lake».packages.lean4.src.lean.Init.Data.Nat.Bitwise.Lemmas.0.Nat.eq_0_of_lt_one
code: @[local simp]
private theorem eq_0_of_lt_one (x : Nat) : x < 1 ↔ x = 0 
goal: x < 1 ↔ x = 0

full_name: _private.«.lake».packages.lean4.src.lean.Init.Data.Nat.Bitwise.Lemmas.0.Nat.eq_0_of_lt
code: private theorem eq_0_of_lt (x : Nat) : x < 2^ 0 ↔ x = 0 
goal: x < 2 ^ 0 ↔ x = 0

full_name: _private.«.lake».packages.lean4.src.lean.Init.Data.Nat.Bitwise.Lemmas.0.Nat.zero_lt_pow
code: @[local simp]
private theorem zero_lt_pow (n : Nat) : 0 < 2^n 
goal: 0 < 2 ^ n

full_name: _private.«.lake».packages.lean4.src.lean.Init.Data.Nat.Bitwise.Lemmas.0.Nat.div_two_le_of_lt_two
code: private theorem div_two_le_of_lt_two {m n : Nat} (p : m < 2 ^ succ n) : m / 2 < 2^n 
goal: m / 2 < 2 ^ n

full_name: Nat.bitwise_lt_two_pow
code: /-- This provides a bound on bitwise operations. -/
theorem bitwise_lt_two_pow (left : x < 2^n) (right : y < 2^n) : (Nat.bitwise f x y) < 2^n 
goal: Nat.bitwise f x y < 2 ^ n

full_name: Nat.testBit_and
code: @[simp] theorem testBit_and (x y i : Nat) : (x &&& y).testBit i = (x.testBit i && y.testBit i) 
goal: (x &&& y).testBit i = (x.testBit i && y.testBit i)

full_name: Nat.and_lt_two_pow
code: theorem and_lt_two_pow (x : Nat) {y n : Nat} (right : y < 2^n) : (x &&& y) < 2^n 
goal: x &&& y < 2 ^ n

full_name: Nat.and_pow_two_is_mod
code: @[simp] theorem and_pow_two_is_mod (x n : Nat) : x &&& (2^n-1) = x % 2^n 
goal: x &&& 2 ^ n - 1 = x % 2 ^ n

full_name: Nat.and_pow_two_identity
code: theorem and_pow_two_identity {x : Nat} (lt : x < 2^n) : x &&& 2^n-1 = x 
goal: x &&& 2 ^ n - 1 = x

full_name: Nat.zero_or
code: @[simp] theorem zero_or (x : Nat) : 0 ||| x = x 
goal: 0 ||| x = x

full_name: Nat.or_zero
code: @[simp] theorem or_zero (x : Nat) : x ||| 0 = x 
goal: x ||| 0 = x

full_name: Nat.testBit_or
code: @[simp] theorem testBit_or (x y i : Nat) : (x ||| y).testBit i = (x.testBit i || y.testBit i) 
goal: (x ||| y).testBit i = (x.testBit i || y.testBit i)

full_name: Nat.or_lt_two_pow
code: theorem or_lt_two_pow {x y n : Nat} (left : x < 2^n) (right : y < 2^n) : x ||| y < 2^n 
goal: x ||| y < 2 ^ n

full_name: Nat.testBit_xor
code: @[simp] theorem testBit_xor (x y i : Nat) :
    (x ^^^ y).testBit i = Bool.xor (x.testBit i) (y.testBit i) 
goal: (x ^^^ y).testBit i = (x.testBit i).xor (y.testBit i)

full_name: Nat.xor_lt_two_pow
code: theorem xor_lt_two_pow {x y n : Nat} (left : x < 2^n) (right : y < 2^n) : x ^^^ y < 2^n 
goal: x ^^^ y < 2 ^ n

full_name: Nat.testBit_mul_pow_two_add
code: theorem testBit_mul_pow_two_add (a : Nat) {b i : Nat} (b_lt : b < 2^i) (j : Nat) :
    testBit (2 ^ i * a + b) j =
      if j < i then
        testBit b j
      else
        testBit a (j - i) 
goal: (2 ^ i * a + b).testBit j = if j < i then b.testBit j else a.testBit (j - i)

full_name: Nat.testBit_mul_pow_two
code: theorem testBit_mul_pow_two :
    testBit (2 ^ i * a) j = (decide (j ≥ i) && testBit a (j-i)) 
goal: (2 ^ i * a).testBit j = (decide (j ≥ i) && a.testBit (j - i))

full_name: Nat.mul_add_lt_is_or
code: theorem mul_add_lt_is_or {b : Nat} (b_lt : b < 2^i) (a : Nat) : 2^i * a + b = 2^i * a ||| b 
goal: 2 ^ i * a + b = 2 ^ i * a ||| b

full_name: Nat.testBit_shiftLeft
code: @[simp] theorem testBit_shiftLeft (x : Nat) : testBit (x <<< i) j =
    (decide (j ≥ i) && testBit x (j-i)) 
goal: (x <<< i).testBit j = (decide (j ≥ i) && x.testBit (j - i))

full_name: Nat.testBit_shiftRight
code: @[simp] theorem testBit_shiftRight (x : Nat) : testBit (x >>> i) j = testBit x (i+j) 
goal: (x >>> i).testBit j = x.testBit (i + j)