l3lab/ntp-mathlib huggingface dataset:
theorem bitwise_xor : bitwise xor = Int.xor := by
  funext m n
  cases' m with m m <;> cases' n with n n <;> try {rfl}
    <;> simp only [bitwise, natBitwise, Bool.not_false, Bool.or_true, Bool.bne_eq_xor,
      cond_false, cond_true, lor, Nat.ldiff, Bool.and_true, negSucc.injEq, Bool.false_xor,
      Bool.true_xor, Bool.and_false, Nat.land, Bool.not_true, ldiff,
      HOr.hOr, OrOp.or, Nat.lor, Int.xor, HXor.hXor, Xor.xor, Nat.xor]
  · congr
    funext x y
    cases x <;> cases y <;> rfl
  · congr
    funext x y
    cases x <;> cases y <;> rfl
  · congr
    funext x y
    cases x <;> cases y <;> 

Proof state:
case h.h.negSucc.negSucc.e_a.e_f.h.h.false.true
m n : ℕ
⊢ (xor (!false) !true) = xor false true

Next tactic:
rfl
theorem bitwise_xor : bitwise xor = Int.xor := by
  funext m n
  cases' m with m m <;> cases' n with n n <;> try {rfl}
    <;> simp only [bitwise, natBitwise, Bool.not_false, Bool.or_true, Bool.bne_eq_xor,
      cond_false, cond_true, lor, Nat.ldiff, Bool.and_true, negSucc.injEq, Bool.false_xor,
      Bool.true_xor, Bool.and_false, Nat.land, Bool.not_true, ldiff,
      HOr.hOr, OrOp.or, Nat.lor, Int.xor, HXor.hXor, Xor.xor, Nat.xor]
  · congr
    funext x y
    cases x <;> cases y <;> rfl
  · congr
    funext x y
    cases x <;> cases y <;> rfl
  · congr
    funext x y
    cases x <;> cases y <;> 

Proof state:
case h.h.negSucc.negSucc.e_a.e_f.h.h.true.false
m n : ℕ
⊢ (xor (!true) !false) = xor true false

Next tactic:
rfl
theorem bitwise_xor : bitwise xor = Int.xor := by
  funext m n
  cases' m with m m <;> cases' n with n n <;> try {rfl}
    <;> simp only [bitwise, natBitwise, Bool.not_false, Bool.or_true, Bool.bne_eq_xor,
      cond_false, cond_true, lor, Nat.ldiff, Bool.and_true, negSucc.injEq, Bool.false_xor,
      Bool.true_xor, Bool.and_false, Nat.land, Bool.not_true, ldiff,
      HOr.hOr, OrOp.or, Nat.lor, Int.xor, HXor.hXor, Xor.xor, Nat.xor]
  · congr
    funext x y
    cases x <;> cases y <;> rfl
  · congr
    funext x y
    cases x <;> cases y <;> rfl
  · congr
    funext x y
    cases x <;> cases y <;> 

Proof state:
case h.h.negSucc.negSucc.e_a.e_f.h.h.true.true
m n : ℕ
⊢ (xor (!true) !true) = xor true true

Next tactic:
rfl
@[simp]
theorem bitwise_bit (f : Bool → Bool → Bool) (a m b n) :
    bitwise f (bit a m) (bit b n) = bit (f a b) (bitwise f m n) := by
  

Proof state:
f : Bool → Bool → Bool
a : Bool
m : ℤ
b : Bool
n : ℤ
⊢ bitwise f (bit a m) (bit b n) = bit (f a b) (bitwise f m n)

Next tactic:
cases' m with m m
@[simp]
theorem bitwise_bit (f : Bool → Bool → Bool) (a m b n) :
    bitwise f (bit a m) (bit b n) = bit (f a b) (bitwise f m n) := by
  cases' m with m m <;> 

Proof state:
case ofNat
f : Bool → Bool → Bool
a b : Bool
n : ℤ
m : ℕ
⊢ bitwise f (bit a (ofNat m)) (bit b n) = bit (f a b) (bitwise f (ofNat m) n)

Next tactic:
cases' n with n n
@[simp]
theorem bitwise_bit (f : Bool → Bool → Bool) (a m b n) :
    bitwise f (bit a m) (bit b n) = bit (f a b) (bitwise f m n) := by
  cases' m with m m <;> 

Proof state:
case negSucc
f : Bool → Bool → Bool
a b : Bool
n : ℤ
m : ℕ
⊢ bitwise f (bit a -[m+1]) (bit b n) = bit (f a b) (bitwise f -[m+1] n)

Next tactic:
cases' n with n n
@[simp]
theorem bitwise_bit (f : Bool → Bool → Bool) (a m b n) :
    bitwise f (bit a m) (bit b n) = bit (f a b) (bitwise f m n) := by
  cases' m with m m <;> cases' n with n n <;>
  

Proof state:
case ofNat.ofNat
f : Bool → Bool → Bool
a b : Bool
m n : ℕ
⊢ bitwise f (bit a (ofNat m)) (bit b (ofNat n)) = bit (f a b) (bitwise f (ofNat m) (ofNat n))

Next tactic:
simp [bitwise, ofNat_eq_coe, bit_coe_nat, natBitwise, Bool.not_false, Bool.not_eq_false',
    bit_negSucc]
@[simp]
theorem bitwise_bit (f : Bool → Bool → Bool) (a m b n) :
    bitwise f (bit a m) (bit b n) = bit (f a b) (bitwise f m n) := by
  cases' m with m m <;> cases' n with n n <;>
  

Proof state:
case ofNat.negSucc
f : Bool → Bool → Bool
a b : Bool
m n : ℕ
⊢ bitwise f (bit a (ofNat m)) (bit b -[n+1]) = bit (f a b) (bitwise f (ofNat m) -[n+1])

Next tactic:
simp [bitwise, ofNat_eq_coe, bit_coe_nat, natBitwise, Bool.not_false, Bool.not_eq_false',
    bit_negSucc]
@[simp]
theorem bitwise_bit (f : Bool → Bool → Bool) (a m b n) :
    bitwise f (bit a m) (bit b n) = bit (f a b) (bitwise f m n) := by
  cases' m with m m <;> cases' n with n n <;>
  

Proof state:
case negSucc.ofNat
f : Bool → Bool → Bool
a b : Bool
m n : ℕ
⊢ bitwise f (bit a -[m+1]) (bit b (ofNat n)) = bit (f a b) (bitwise f -[m+1] (ofNat n))

Next tactic:
simp [bitwise, ofNat_eq_coe, bit_coe_nat, natBitwise, Bool.not_false, Bool.not_eq_false',
    bit_negSucc]
@[simp]
theorem bitwise_bit (f : Bool → Bool → Bool) (a m b n) :
    bitwise f (bit a m) (bit b n) = bit (f a b) (bitwise f m n) := by
  cases' m with m m <;> cases' n with n n <;>
  

Proof state:
case negSucc.negSucc
f : Bool → Bool → Bool
a b : Bool
m n : ℕ
⊢ bitwise f (bit a -[m+1]) (bit b -[n+1]) = bit (f a b) (bitwise f -[m+1] -[n+1])

Next tactic:
simp [bitwise, ofNat_eq_coe, bit_coe_nat, natBitwise, Bool.not_false, Bool.not_eq_false',
    bit_negSucc]
@[simp]
theorem bitwise_bit (f : Bool → Bool → Bool) (a m b n) :
    bitwise f (bit a m) (bit b n) = bit (f a b) (bitwise f m n) := by
  cases' m with m m <;> cases' n with n n <;>
  simp [bitwise, ofNat_eq_coe, bit_coe_nat, natBitwise, Bool.not_false, Bool.not_eq_false',
    bit_negSucc]
  · 

Proof state:
case ofNat.ofNat
f : Bool → Bool → Bool
a b : Bool
m n : ℕ
⊢ (bif f false false then -[Nat.bitwise (fun x y => !f x y) (Nat.bit a m) (Nat.bit b n)+1]
    else ↑(Nat.bitwise f (Nat.bit a m) (Nat.bit b n))) =
    bit (f a b) (bif f false false then -[Nat.bitwise (fun x y => !f x y) m n+1] else ↑(Nat.bitwise f m n))

Next tactic:
by_cases h : f false false
@[simp]
theorem bitwise_bit (f : Bool → Bool → Bool) (a m b n) :
    bitwise f (bit a m) (bit b n) = bit (f a b) (bitwise f m n) := by
  cases' m with m m <;> cases' n with n n <;>
  simp [bitwise, ofNat_eq_coe, bit_coe_nat, natBitwise, Bool.not_false, Bool.not_eq_false',
    bit_negSucc]
  · by_cases h : f false false <;> 

Proof state:
case pos
f : Bool → Bool → Bool
a b : Bool
m n : ℕ
h : f false false = true
⊢ (bif f false false then -[Nat.bitwise (fun x y => !f x y) (Nat.bit a m) (Nat.bit b n)+1]
    else ↑(Nat.bitwise f (Nat.bit a m) (Nat.bit b n))) =
    bit (f a b) (bif f false false then -[Nat.bitwise (fun x y => !f x y) m n+1] else ↑(Nat.bitwise f m n))

Next tactic:
simp (config := {decide := true}) [h]
@[simp]
theorem bitwise_bit (f : Bool → Bool → Bool) (a m b n) :
    bitwise f (bit a m) (bit b n) = bit (f a b) (bitwise f m n) := by
  cases' m with m m <;> cases' n with n n <;>
  simp [bitwise, ofNat_eq_coe, bit_coe_nat, natBitwise, Bool.not_false, Bool.not_eq_false',
    bit_negSucc]
  · by_cases h : f false false <;> 

Proof state:
case neg
f : Bool → Bool → Bool
a b : Bool
m n : ℕ
h : ¬f false false = true
⊢ (bif f false false then -[Nat.bitwise (fun x y => !f x y) (Nat.bit a m) (Nat.bit b n)+1]
    else ↑(Nat.bitwise f (Nat.bit a m) (Nat.bit b n))) =
    bit (f a b) (bif f false false then -[Nat.bitwise (fun x y => !f x y) m n+1] else ↑(Nat.bitwise f m n))

Next tactic:
simp (config := {decide := true}) [h]
@[simp]
theorem bitwise_bit (f : Bool → Bool → Bool) (a m b n) :
    bitwise f (bit a m) (bit b n) = bit (f a b) (bitwise f m n) := by
  cases' m with m m <;> cases' n with n n <;>
  simp [bitwise, ofNat_eq_coe, bit_coe_nat, natBitwise, Bool.not_false, Bool.not_eq_false',
    bit_negSucc]
  · by_cases h : f false false <;> simp (config := {decide := true}) [h]
  · 

Proof state:
case ofNat.negSucc
f : Bool → Bool → Bool
a b : Bool
m n : ℕ
⊢ (bif f false true then -[Nat.bitwise (fun x y => !f x !y) (Nat.bit a m) (Nat.bit (!b) n)+1]
    else ↑(Nat.bitwise (fun x y => f x !y) (Nat.bit a m) (Nat.bit (!b) n))) =
    bit (f a b)
      (bif f false true then -[Nat.bitwise (fun x y => !f x !y) m n+1] else ↑(Nat.bitwise (fun x y => f x !y) m n))

Next tactic:
by_cases h : f false true
@[simp]
theorem bitwise_bit (f : Bool → Bool → Bool) (a m b n) :
    bitwise f (bit a m) (bit b n) = bit (f a b) (bitwise f m n) := by
  cases' m with m m <;> cases' n with n n <;>
  simp [bitwise, ofNat_eq_coe, bit_coe_nat, natBitwise, Bool.not_false, Bool.not_eq_false',
    bit_negSucc]
  · by_cases h : f false false <;> simp (config := {decide := true}) [h]
  · by_cases h : f false true <;> 

Proof state:
case pos
f : Bool → Bool → Bool
a b : Bool
m n : ℕ
h : f false true = true
⊢ (bif f false true then -[Nat.bitwise (fun x y => !f x !y) (Nat.bit a m) (Nat.bit (!b) n)+1]
    else ↑(Nat.bitwise (fun x y => f x !y) (Nat.bit a m) (Nat.bit (!b) n))) =
    bit (f a b)
      (bif f false true then -[Nat.bitwise (fun x y => !f x !y) m n+1] else ↑(Nat.bitwise (fun x y => f x !y) m n))

Next tactic:
simp (config := {decide := true}) [h]
@[simp]
theorem bitwise_bit (f : Bool → Bool → Bool) (a m b n) :
    bitwise f (bit a m) (bit b n) = bit (f a b) (bitwise f m n) := by
  cases' m with m m <;> cases' n with n n <;>
  simp [bitwise, ofNat_eq_coe, bit_coe_nat, natBitwise, Bool.not_false, Bool.not_eq_false',
    bit_negSucc]
  · by_cases h : f false false <;> simp (config := {decide := true}) [h]
  · by_cases h : f false true <;> 

Proof state:
case neg
f : Bool → Bool → Bool
a b : Bool
m n : ℕ
h : ¬f false true = true
⊢ (bif f false true then -[Nat.bitwise (fun x y => !f x !y) (Nat.bit a m) (Nat.bit (!b) n)+1]
    else ↑(Nat.bitwise (fun x y => f x !y) (Nat.bit a m) (Nat.bit (!b) n))) =
    bit (f a b)
      (bif f false true then -[Nat.bitwise (fun x y => !f x !y) m n+1] else ↑(Nat.bitwise (fun x y => f x !y) m n))

Next tactic:
simp (config := {decide := true}) [h]
@[simp]
theorem bitwise_bit (f : Bool → Bool → Bool) (a m b n) :
    bitwise f (bit a m) (bit b n) = bit (f a b) (bitwise f m n) := by
  cases' m with m m <;> cases' n with n n <;>
  simp [bitwise, ofNat_eq_coe, bit_coe_nat, natBitwise, Bool.not_false, Bool.not_eq_false',
    bit_negSucc]
  · by_cases h : f false false <;> simp (config := {decide := true}) [h]
  · by_cases h : f false true <;> simp (config := {decide := true}) [h]
  · 

Proof state:
case negSucc.ofNat
f : Bool → Bool → Bool
a b : Bool
m n : ℕ
⊢ (bif f true false then -[Nat.bitwise (fun x y => !f (!x) y) (Nat.bit (!a) m) (Nat.bit b n)+1]
    else ↑(Nat.bitwise (fun x y => f (!x) y) (Nat.bit (!a) m) (Nat.bit b n))) =
    bit (f a b)
      (bif f true false then -[Nat.bitwise (fun x y => !f (!x) y) m n+1] else ↑(Nat.bitwise (fun x y => f (!x) y) m n))

Next tactic:
by_cases h : f true false
@[simp]
theorem bitwise_bit (f : Bool → Bool → Bool) (a m b n) :
    bitwise f (bit a m) (bit b n) = bit (f a b) (bitwise f m n) := by
  cases' m with m m <;> cases' n with n n <;>
  simp [bitwise, ofNat_eq_coe, bit_coe_nat, natBitwise, Bool.not_false, Bool.not_eq_false',
    bit_negSucc]
  · by_cases h : f false false <;> simp (config := {decide := true}) [h]
  · by_cases h : f false true <;> simp (config := {decide := true}) [h]
  · by_cases h : f true false <;> 

Proof state:
case pos
f : Bool → Bool → Bool
a b : Bool
m n : ℕ
h : f true false = true
⊢ (bif f true false then -[Nat.bitwise (fun x y => !f (!x) y) (Nat.bit (!a) m) (Nat.bit b n)+1]
    else ↑(Nat.bitwise (fun x y => f (!x) y) (Nat.bit (!a) m) (Nat.bit b n))) =
    bit (f a b)
      (bif f true false then -[Nat.bitwise (fun x y => !f (!x) y) m n+1] else ↑(Nat.bitwise (fun x y => f (!x) y) m n))

Next tactic:
simp (config := {decide := true}) [h]
@[simp]
theorem bitwise_bit (f : Bool → Bool → Bool) (a m b n) :
    bitwise f (bit a m) (bit b n) = bit (f a b) (bitwise f m n) := by
  cases' m with m m <;> cases' n with n n <;>
  simp [bitwise, ofNat_eq_coe, bit_coe_nat, natBitwise, Bool.not_false, Bool.not_eq_false',
    bit_negSucc]
  · by_cases h : f false false <;> simp (config := {decide := true}) [h]
  · by_cases h : f false true <;> simp (config := {decide := true}) [h]
  · by_cases h : f true false <;> 

Proof state:
case neg
f : Bool → Bool → Bool
a b : Bool
m n : ℕ
h : ¬f true false = true
⊢ (bif f true false then -[Nat.bitwise (fun x y => !f (!x) y) (Nat.bit (!a) m) (Nat.bit b n)+1]
    else ↑(Nat.bitwise (fun x y => f (!x) y) (Nat.bit (!a) m) (Nat.bit b n))) =
    bit (f a b)
      (bif f true false then -[Nat.bitwise (fun x y => !f (!x) y) m n+1] else ↑(Nat.bitwise (fun x y => f (!x) y) m n))

Next tactic:
simp (config := {decide := true}) [h]
@[simp]
theorem bitwise_bit (f : Bool → Bool → Bool) (a m b n) :
    bitwise f (bit a m) (bit b n) = bit (f a b) (bitwise f m n) := by
  cases' m with m m <;> cases' n with n n <;>
  simp [bitwise, ofNat_eq_coe, bit_coe_nat, natBitwise, Bool.not_false, Bool.not_eq_false',
    bit_negSucc]
  · by_cases h : f false false <;> simp (config := {decide := true}) [h]
  · by_cases h : f false true <;> simp (config := {decide := true}) [h]
  · by_cases h : f true false <;> simp (config := {decide := true}) [h]
  · 

Proof state:
case negSucc.negSucc
f : Bool → Bool → Bool
a b : Bool
m n : ℕ
⊢ (bif f true true then -[Nat.bitwise (fun x y => !f (!x) !y) (Nat.bit (!a) m) (Nat.bit (!b) n)+1]
    else ↑(Nat.bitwise (fun x y => f (!x) !y) (Nat.bit (!a) m) (Nat.bit (!b) n))) =
    bit (f a b)
      (bif f true true then -[Nat.bitwise (fun x y => !f (!x) !y) m n+1] else ↑(Nat.bitwise (fun x y => f (!x) !y) m n))

Next tactic:
by_cases h : f true true
@[simp]
theorem bitwise_bit (f : Bool → Bool → Bool) (a m b n) :
    bitwise f (bit a m) (bit b n) = bit (f a b) (bitwise f m n) := by
  cases' m with m m <;> cases' n with n n <;>
  simp [bitwise, ofNat_eq_coe, bit_coe_nat, natBitwise, Bool.not_false, Bool.not_eq_false',
    bit_negSucc]
  · by_cases h : f false false <;> simp (config := {decide := true}) [h]
  · by_cases h : f false true <;> simp (config := {decide := true}) [h]
  · by_cases h : f true false <;> simp (config := {decide := true}) [h]
  · by_cases h : f true true <;> 

Proof state:
case pos
f : Bool → Bool → Bool
a b : Bool
m n : ℕ
h : f true true = true
⊢ (bif f true true then -[Nat.bitwise (fun x y => !f (!x) !y) (Nat.bit (!a) m) (Nat.bit (!b) n)+1]
    else ↑(Nat.bitwise (fun x y => f (!x) !y) (Nat.bit (!a) m) (Nat.bit (!b) n))) =
    bit (f a b)
      (bif f true true then -[Nat.bitwise (fun x y => !f (!x) !y) m n+1] else ↑(Nat.bitwise (fun x y => f (!x) !y) m n))

Next tactic:
simp (config := {decide := true}) [h]
@[simp]
theorem bitwise_bit (f : Bool → Bool → Bool) (a m b n) :
    bitwise f (bit a m) (bit b n) = bit (f a b) (bitwise f m n) := by
  cases' m with m m <;> cases' n with n n <;>
  simp [bitwise, ofNat_eq_coe, bit_coe_nat, natBitwise, Bool.not_false, Bool.not_eq_false',
    bit_negSucc]
  · by_cases h : f false false <;> simp (config := {decide := true}) [h]
  · by_cases h : f false true <;> simp (config := {decide := true}) [h]
  · by_cases h : f true false <;> simp (config := {decide := true}) [h]
  · by_cases h : f true true <;> 

Proof state:
case neg
f : Bool → Bool → Bool
a b : Bool
m n : ℕ
h : ¬f true true = true
⊢ (bif f true true then -[Nat.bitwise (fun x y => !f (!x) !y) (Nat.bit (!a) m) (Nat.bit (!b) n)+1]
    else ↑(Nat.bitwise (fun x y => f (!x) !y) (Nat.bit (!a) m) (Nat.bit (!b) n))) =
    bit (f a b)
      (bif f true true then -[Nat.bitwise (fun x y => !f (!x) !y) m n+1] else ↑(Nat.bitwise (fun x y => f (!x) !y) m n))

Next tactic:
simp (config := {decide := true}) [h]
@[simp]
theorem lor_bit (a m b n) : lor (bit a m) (bit b n) = bit (a || b) (lor m n) := by
  

Proof state:
a : Bool
m : ℤ
b : Bool
n : ℤ
⊢ lor (bit a m) (bit b n) = bit (a || b) (lor m n)

Next tactic:
rw [← bitwise_or, bitwise_bit]
@[simp]
theorem land_bit (a m b n) : land (bit a m) (bit b n) = bit (a && b) (land m n) := by
  

Proof state:
a : Bool
m : ℤ
b : Bool
n : ℤ
⊢ land (bit a m) (bit b n) = bit (a && b) (land m n)

Next tactic:
rw [← bitwise_and, bitwise_bit]
@[simp]
theorem ldiff_bit (a m b n) : ldiff (bit a m) (bit b n) = bit (a && not b) (ldiff m n) := by
  

Proof state:
a : Bool
m : ℤ
b : Bool
n : ℤ
⊢ ldiff (bit a m) (bit b n) = bit (a && !b) (ldiff m n)

Next tactic:
rw [← bitwise_diff, bitwise_bit]
@[simp]
theorem lxor_bit (a m b n) : Int.xor (bit a m) (bit b n) = bit (xor a b) (Int.xor m n) := by
  

Proof state:
a : Bool
m : ℤ
b : Bool
n : ℤ
⊢ Int.xor (bit a m) (bit b n) = bit (xor a b) (Int.xor m n)

Next tactic:
rw [← bitwise_xor, bitwise_bit]
@[simp]
theorem lnot_bit (b) : ∀ n, lnot (bit b n) = bit (not b) (lnot n)
  | (n : ℕ) => by 

Proof state:
b : Bool
n : ℕ
⊢ lnot (bit b ↑n) = bit (!b) (lnot ↑n)

Next tactic:
simp [lnot]
@[simp]
theorem lnot_bit (b) : ∀ n, lnot (bit b n) = bit (not b) (lnot n)
  | (n : ℕ) => by simp [lnot]
  | -[n+1] => by 

Proof state:
b : Bool
n : ℕ
⊢ lnot (bit b -[n+1]) = bit (!b) (lnot -[n+1])

Next tactic:
simp [lnot]
@[simp]
theorem testBit_bitwise (f : Bool → Bool → Bool) (m n k) :
    testBit (bitwise f m n) k = f (testBit m k) (testBit n k) := by
  

Proof state:
f : Bool → Bool → Bool
m n : ℤ
k : ℕ
⊢ testBit (bitwise f m n) k = f (testBit m k) (testBit n k)

Next tactic:
cases m
@[simp]
theorem testBit_bitwise (f : Bool → Bool → Bool) (m n k) :
    testBit (bitwise f m n) k = f (testBit m k) (testBit n k) := by
  cases m <;> 

Proof state:
case ofNat
f : Bool → Bool → Bool
n : ℤ
k a✝ : ℕ
⊢ testBit (bitwise f (ofNat a✝) n) k = f (testBit (ofNat a✝) k) (testBit n k)

Next tactic:
cases n
@[simp]
theorem testBit_bitwise (f : Bool → Bool → Bool) (m n k) :
    testBit (bitwise f m n) k = f (testBit m k) (testBit n k) := by
  cases m <;> 

Proof state:
case negSucc
f : Bool → Bool → Bool
n : ℤ
k a✝ : ℕ
⊢ testBit (bitwise f -[a✝+1] n) k = f (testBit -[a✝+1] k) (testBit n k)

Next tactic:
cases n
@[simp]
theorem testBit_bitwise (f : Bool → Bool → Bool) (m n k) :
    testBit (bitwise f m n) k = f (testBit m k) (testBit n k) := by
  cases m <;> cases n <;> 

Proof state:
case ofNat.ofNat
f : Bool → Bool → Bool
k a✝¹ a✝ : ℕ
⊢ testBit (bitwise f (ofNat a✝¹) (ofNat a✝)) k = f (testBit (ofNat a✝¹) k) (testBit (ofNat a✝) k)

Next tactic:
simp only [testBit, bitwise, natBitwise]
@[simp]
theorem testBit_bitwise (f : Bool → Bool → Bool) (m n k) :
    testBit (bitwise f m n) k = f (testBit m k) (testBit n k) := by
  cases m <;> cases n <;> 

Proof state:
case ofNat.negSucc
f : Bool → Bool → Bool
k a✝¹ a✝ : ℕ
⊢ testBit (bitwise f (ofNat a✝¹) -[a✝+1]) k = f (testBit (ofNat a✝¹) k) (testBit -[a✝+1] k)

Next tactic:
simp only [testBit, bitwise, natBitwise]
@[simp]
theorem testBit_bitwise (f : Bool → Bool → Bool) (m n k) :
    testBit (bitwise f m n) k = f (testBit m k) (testBit n k) := by
  cases m <;> cases n <;> 

Proof state:
case negSucc.ofNat
f : Bool → Bool → Bool
k a✝¹ a✝ : ℕ
⊢ testBit (bitwise f -[a✝¹+1] (ofNat a✝)) k = f (testBit -[a✝¹+1] k) (testBit (ofNat a✝) k)

Next tactic:
simp only [testBit, bitwise, natBitwise]
@[simp]
theorem testBit_bitwise (f : Bool → Bool → Bool) (m n k) :
    testBit (bitwise f m n) k = f (testBit m k) (testBit n k) := by
  cases m <;> cases n <;> 

Proof state:
case negSucc.negSucc
f : Bool → Bool → Bool
k a✝¹ a✝ : ℕ
⊢ testBit (bitwise f -[a✝¹+1] -[a✝+1]) k = f (testBit -[a✝¹+1] k) (testBit -[a✝+1] k)

Next tactic:
simp only [testBit, bitwise, natBitwise]
@[simp]
theorem testBit_bitwise (f : Bool → Bool → Bool) (m n k) :
    testBit (bitwise f m n) k = f (testBit m k) (testBit n k) := by
  cases m <;> cases n <;> simp only [testBit, bitwise, natBitwise]
  · 

Proof state:
case ofNat.ofNat
f : Bool → Bool → Bool
k a✝¹ a✝ : ℕ
⊢ (match bif f false false then -[Nat.bitwise (fun x y => !f x y) a✝¹ a✝+1] else ↑(Nat.bitwise f a✝¹ a✝), k with
    | ofNat m, n => Nat.testBit m n
    | -[m+1], n => !Nat.testBit m n) =
    f (Nat.testBit a✝¹ k) (Nat.testBit a✝ k)

Next tactic:
by_cases h : f false false
@[simp]
theorem testBit_bitwise (f : Bool → Bool → Bool) (m n k) :
    testBit (bitwise f m n) k = f (testBit m k) (testBit n k) := by
  cases m <;> cases n <;> simp only [testBit, bitwise, natBitwise]
  · by_cases h : f false false <;> 

Proof state:
case pos
f : Bool → Bool → Bool
k a✝¹ a✝ : ℕ
h : f false false = true
⊢ (match bif f false false then -[Nat.bitwise (fun x y => !f x y) a✝¹ a✝+1] else ↑(Nat.bitwise f a✝¹ a✝), k with
    | ofNat m, n => Nat.testBit m n
    | -[m+1], n => !Nat.testBit m n) =
    f (Nat.testBit a✝¹ k) (Nat.testBit a✝ k)

Next tactic:
simp [h]
@[simp]
theorem testBit_bitwise (f : Bool → Bool → Bool) (m n k) :
    testBit (bitwise f m n) k = f (testBit m k) (testBit n k) := by
  cases m <;> cases n <;> simp only [testBit, bitwise, natBitwise]
  · by_cases h : f false false <;> 

Proof state:
case neg
f : Bool → Bool → Bool
k a✝¹ a✝ : ℕ
h : ¬f false false = true
⊢ (match bif f false false then -[Nat.bitwise (fun x y => !f x y) a✝¹ a✝+1] else ↑(Nat.bitwise f a✝¹ a✝), k with
    | ofNat m, n => Nat.testBit m n
    | -[m+1], n => !Nat.testBit m n) =
    f (Nat.testBit a✝¹ k) (Nat.testBit a✝ k)

Next tactic:
simp [h]
@[simp]
theorem testBit_bitwise (f : Bool → Bool → Bool) (m n k) :
    testBit (bitwise f m n) k = f (testBit m k) (testBit n k) := by
  cases m <;> cases n <;> simp only [testBit, bitwise, natBitwise]
  · by_cases h : f false false <;> simp [h]
  · 

Proof state:
case ofNat.negSucc
f : Bool → Bool → Bool
k a✝¹ a✝ : ℕ
⊢ (match
      bif f false !false then -[Nat.bitwise (fun x y => !f x !y) a✝¹ a✝+1]
      else ↑(Nat.bitwise (fun x y => f x !y) a✝¹ a✝),
      k with
    | ofNat m, n => Nat.testBit m n
    | -[m+1], n => !Nat.testBit m n) =
    f (Nat.testBit a✝¹ k) !Nat.testBit a✝ k

Next tactic:
by_cases h : f false true
@[simp]
theorem testBit_bitwise (f : Bool → Bool → Bool) (m n k) :
    testBit (bitwise f m n) k = f (testBit m k) (testBit n k) := by
  cases m <;> cases n <;> simp only [testBit, bitwise, natBitwise]
  · by_cases h : f false false <;> simp [h]
  · by_cases h : f false true <;> 

Proof state:
case pos
f : Bool → Bool → Bool
k a✝¹ a✝ : ℕ
h : f false true = true
⊢ (match
      bif f false !false then -[Nat.bitwise (fun x y => !f x !y) a✝¹ a✝+1]
      else ↑(Nat.bitwise (fun x y => f x !y) a✝¹ a✝),
      k with
    | ofNat m, n => Nat.testBit m n
    | -[m+1], n => !Nat.testBit m n) =
    f (Nat.testBit a✝¹ k) !Nat.testBit a✝ k

Next tactic:
simp [h]
@[simp]
theorem testBit_bitwise (f : Bool → Bool → Bool) (m n k) :
    testBit (bitwise f m n) k = f (testBit m k) (testBit n k) := by
  cases m <;> cases n <;> simp only [testBit, bitwise, natBitwise]
  · by_cases h : f false false <;> simp [h]
  · by_cases h : f false true <;> 

Proof state:
case neg
f : Bool → Bool → Bool
k a✝¹ a✝ : ℕ
h : ¬f false true = true
⊢ (match
      bif f false !false then -[Nat.bitwise (fun x y => !f x !y) a✝¹ a✝+1]
      else ↑(Nat.bitwise (fun x y => f x !y) a✝¹ a✝),
      k with
    | ofNat m, n => Nat.testBit m n
    | -[m+1], n => !Nat.testBit m n) =
    f (Nat.testBit a✝¹ k) !Nat.testBit a✝ k

Next tactic:
simp [h]
@[simp]
theorem testBit_bitwise (f : Bool → Bool → Bool) (m n k) :
    testBit (bitwise f m n) k = f (testBit m k) (testBit n k) := by
  cases m <;> cases n <;> simp only [testBit, bitwise, natBitwise]
  · by_cases h : f false false <;> simp [h]
  · by_cases h : f false true <;> simp [h]
  · 

Proof state:
case negSucc.ofNat
f : Bool → Bool → Bool
k a✝¹ a✝ : ℕ
⊢ (match
      bif f (!false) false then -[Nat.bitwise (fun x y => !f (!x) y) a✝¹ a✝+1]
      else ↑(Nat.bitwise (fun x y => f (!x) y) a✝¹ a✝),
      k with
    | ofNat m, n => Nat.testBit m n
    | -[m+1], n => !Nat.testBit m n) =
    f (!Nat.testBit a✝¹ k) (Nat.testBit a✝ k)

Next tactic:
by_cases h : f true false
@[simp]
theorem testBit_bitwise (f : Bool → Bool → Bool) (m n k) :
    testBit (bitwise f m n) k = f (testBit m k) (testBit n k) := by
  cases m <;> cases n <;> simp only [testBit, bitwise, natBitwise]
  · by_cases h : f false false <;> simp [h]
  · by_cases h : f false true <;> simp [h]
  · by_cases h : f true false <;> 

Proof state:
case pos
f : Bool → Bool → Bool
k a✝¹ a✝ : ℕ
h : f true false = true
⊢ (match
      bif f (!false) false then -[Nat.bitwise (fun x y => !f (!x) y) a✝¹ a✝+1]
      else ↑(Nat.bitwise (fun x y => f (!x) y) a✝¹ a✝),
      k with
    | ofNat m, n => Nat.testBit m n
    | -[m+1], n => !Nat.testBit m n) =
    f (!Nat.testBit a✝¹ k) (Nat.testBit a✝ k)

Next tactic:
simp [h]