l3lab/ntp-mathlib huggingface dataset:
@[simp]
lemma bitwise_bit {f : Bool → Bool → Bool} (h : f false false = false := by rfl) (a m b n) :
    bitwise f (bit a m) (bit b n) = bit (f a b) (bitwise f m n) := by
  conv_lhs => unfold bitwise
  simp (config := { unfoldPartialApp := true }) only [bit, bit1, bit0, Bool.cond_eq_ite]
  have h1 x :     (x + x) % 2 = 0 := by rw [← two_mul, mul_comm]; apply mul_mod_left
  have h2 x : (x + x + 1) % 2 = 1 := by rw [← two_mul, add_comm]; apply add_mul_mod_self_left
  have h3 x :     (x + x) / 2 = x := by rw [← two_mul, mul_comm]; apply mul_div_left _ zero_lt_two
  have h4 x : (x + x + 1) / 2 = x := by rw [← two_mul, add_comm]; simp [add_mul_div_left]; rfl
  cases a <;> cases b <;> simp [h1, h2, h3, h4] <;> split_ifs
    <;> 

Proof state:
case pos
f✝ f : Bool → Bool → Bool
h : autoParam (f false false = false) _auto✝
m n : ℕ
h1 : ∀ (x : ℕ), (x + x) % 2 = 0
h2 : ∀ (x : ℕ), (x + x + 1) % 2 = 1
h3 : ∀ (x : ℕ), (x + x) / 2 = x
h4 : ∀ (x : ℕ), (x + x + 1) / 2 = x
h✝³ : ¬m = 0
h✝² : n = 0
h✝¹ : ¬f true false = true
h✝ : f false false = true
⊢ 0 = (fun a => a + a + 1) (bitwise f m n)

Next tactic:
simp_all (config := {decide := true})
@[simp]
lemma bitwise_bit {f : Bool → Bool → Bool} (h : f false false = false := by rfl) (a m b n) :
    bitwise f (bit a m) (bit b n) = bit (f a b) (bitwise f m n) := by
  conv_lhs => unfold bitwise
  simp (config := { unfoldPartialApp := true }) only [bit, bit1, bit0, Bool.cond_eq_ite]
  have h1 x :     (x + x) % 2 = 0 := by rw [← two_mul, mul_comm]; apply mul_mod_left
  have h2 x : (x + x + 1) % 2 = 1 := by rw [← two_mul, add_comm]; apply add_mul_mod_self_left
  have h3 x :     (x + x) / 2 = x := by rw [← two_mul, mul_comm]; apply mul_div_left _ zero_lt_two
  have h4 x : (x + x + 1) / 2 = x := by rw [← two_mul, add_comm]; simp [add_mul_div_left]; rfl
  cases a <;> cases b <;> simp [h1, h2, h3, h4] <;> split_ifs
    <;> 

Proof state:
case neg
f✝ f : Bool → Bool → Bool
h : autoParam (f false false = false) _auto✝
m n : ℕ
h1 : ∀ (x : ℕ), (x + x) % 2 = 0
h2 : ∀ (x : ℕ), (x + x + 1) % 2 = 1
h3 : ∀ (x : ℕ), (x + x) / 2 = x
h4 : ∀ (x : ℕ), (x + x + 1) / 2 = x
h✝³ : ¬m = 0
h✝² : n = 0
h✝¹ : ¬f true false = true
h✝ : ¬f false false = true
⊢ 0 = (fun a => a + a) (bitwise f m n)

Next tactic:
simp_all (config := {decide := true})
@[simp]
lemma bitwise_bit {f : Bool → Bool → Bool} (h : f false false = false := by rfl) (a m b n) :
    bitwise f (bit a m) (bit b n) = bit (f a b) (bitwise f m n) := by
  conv_lhs => unfold bitwise
  simp (config := { unfoldPartialApp := true }) only [bit, bit1, bit0, Bool.cond_eq_ite]
  have h1 x :     (x + x) % 2 = 0 := by rw [← two_mul, mul_comm]; apply mul_mod_left
  have h2 x : (x + x + 1) % 2 = 1 := by rw [← two_mul, add_comm]; apply add_mul_mod_self_left
  have h3 x :     (x + x) / 2 = x := by rw [← two_mul, mul_comm]; apply mul_div_left _ zero_lt_two
  have h4 x : (x + x + 1) / 2 = x := by rw [← two_mul, add_comm]; simp [add_mul_div_left]; rfl
  cases a <;> cases b <;> simp [h1, h2, h3, h4] <;> split_ifs
    <;> 

Proof state:
case pos
f✝ f : Bool → Bool → Bool
h : autoParam (f false false = false) _auto✝
m n : ℕ
h1 : ∀ (x : ℕ), (x + x) % 2 = 0
h2 : ∀ (x : ℕ), (x + x + 1) % 2 = 1
h3 : ∀ (x : ℕ), (x + x) / 2 = x
h4 : ∀ (x : ℕ), (x + x + 1) / 2 = x
h✝² : ¬m = 0
h✝¹ : ¬n = 0
h✝ : f false false = true
⊢ bitwise f m n + bitwise f m n + 1 = (fun a => a + a + 1) (bitwise f m n)

Next tactic:
simp_all (config := {decide := true})
@[simp]
lemma bitwise_bit {f : Bool → Bool → Bool} (h : f false false = false := by rfl) (a m b n) :
    bitwise f (bit a m) (bit b n) = bit (f a b) (bitwise f m n) := by
  conv_lhs => unfold bitwise
  simp (config := { unfoldPartialApp := true }) only [bit, bit1, bit0, Bool.cond_eq_ite]
  have h1 x :     (x + x) % 2 = 0 := by rw [← two_mul, mul_comm]; apply mul_mod_left
  have h2 x : (x + x + 1) % 2 = 1 := by rw [← two_mul, add_comm]; apply add_mul_mod_self_left
  have h3 x :     (x + x) / 2 = x := by rw [← two_mul, mul_comm]; apply mul_div_left _ zero_lt_two
  have h4 x : (x + x + 1) / 2 = x := by rw [← two_mul, add_comm]; simp [add_mul_div_left]; rfl
  cases a <;> cases b <;> simp [h1, h2, h3, h4] <;> split_ifs
    <;> 

Proof state:
case neg
f✝ f : Bool → Bool → Bool
h : autoParam (f false false = false) _auto✝
m n : ℕ
h1 : ∀ (x : ℕ), (x + x) % 2 = 0
h2 : ∀ (x : ℕ), (x + x + 1) % 2 = 1
h3 : ∀ (x : ℕ), (x + x) / 2 = x
h4 : ∀ (x : ℕ), (x + x + 1) / 2 = x
h✝² : ¬m = 0
h✝¹ : ¬n = 0
h✝ : ¬f false false = true
⊢ bitwise f m n + bitwise f m n = (fun a => a + a) (bitwise f m n)

Next tactic:
simp_all (config := {decide := true})
@[simp]
lemma bitwise_bit {f : Bool → Bool → Bool} (h : f false false = false := by rfl) (a m b n) :
    bitwise f (bit a m) (bit b n) = bit (f a b) (bitwise f m n) := by
  conv_lhs => unfold bitwise
  simp (config := { unfoldPartialApp := true }) only [bit, bit1, bit0, Bool.cond_eq_ite]
  have h1 x :     (x + x) % 2 = 0 := by rw [← two_mul, mul_comm]; apply mul_mod_left
  have h2 x : (x + x + 1) % 2 = 1 := by rw [← two_mul, add_comm]; apply add_mul_mod_self_left
  have h3 x :     (x + x) / 2 = x := by rw [← two_mul, mul_comm]; apply mul_div_left _ zero_lt_two
  have h4 x : (x + x + 1) / 2 = x := by rw [← two_mul, add_comm]; simp [add_mul_div_left]; rfl
  cases a <;> cases b <;> simp [h1, h2, h3, h4] <;> split_ifs
    <;> 

Proof state:
case pos
f✝ f : Bool → Bool → Bool
h : autoParam (f false false = false) _auto✝
m n : ℕ
h1 : ∀ (x : ℕ), (x + x) % 2 = 0
h2 : ∀ (x : ℕ), (x + x + 1) % 2 = 1
h3 : ∀ (x : ℕ), (x + x) / 2 = x
h4 : ∀ (x : ℕ), (x + x + 1) / 2 = x
h✝¹ : m = 0
h✝ : f false true = true
⊢ n + n + 1 = (fun a => a + a + 1) (bitwise f m n)

Next tactic:
simp_all (config := {decide := true})
@[simp]
lemma bitwise_bit {f : Bool → Bool → Bool} (h : f false false = false := by rfl) (a m b n) :
    bitwise f (bit a m) (bit b n) = bit (f a b) (bitwise f m n) := by
  conv_lhs => unfold bitwise
  simp (config := { unfoldPartialApp := true }) only [bit, bit1, bit0, Bool.cond_eq_ite]
  have h1 x :     (x + x) % 2 = 0 := by rw [← two_mul, mul_comm]; apply mul_mod_left
  have h2 x : (x + x + 1) % 2 = 1 := by rw [← two_mul, add_comm]; apply add_mul_mod_self_left
  have h3 x :     (x + x) / 2 = x := by rw [← two_mul, mul_comm]; apply mul_div_left _ zero_lt_two
  have h4 x : (x + x + 1) / 2 = x := by rw [← two_mul, add_comm]; simp [add_mul_div_left]; rfl
  cases a <;> cases b <;> simp [h1, h2, h3, h4] <;> split_ifs
    <;> 

Proof state:
case neg
f✝ f : Bool → Bool → Bool
h : autoParam (f false false = false) _auto✝
m n : ℕ
h1 : ∀ (x : ℕ), (x + x) % 2 = 0
h2 : ∀ (x : ℕ), (x + x + 1) % 2 = 1
h3 : ∀ (x : ℕ), (x + x) / 2 = x
h4 : ∀ (x : ℕ), (x + x + 1) / 2 = x
h✝¹ : m = 0
h✝ : ¬f false true = true
⊢ 0 = (fun a => a + a) (bitwise f m n)

Next tactic:
simp_all (config := {decide := true})
@[simp]
lemma bitwise_bit {f : Bool → Bool → Bool} (h : f false false = false := by rfl) (a m b n) :
    bitwise f (bit a m) (bit b n) = bit (f a b) (bitwise f m n) := by
  conv_lhs => unfold bitwise
  simp (config := { unfoldPartialApp := true }) only [bit, bit1, bit0, Bool.cond_eq_ite]
  have h1 x :     (x + x) % 2 = 0 := by rw [← two_mul, mul_comm]; apply mul_mod_left
  have h2 x : (x + x + 1) % 2 = 1 := by rw [← two_mul, add_comm]; apply add_mul_mod_self_left
  have h3 x :     (x + x) / 2 = x := by rw [← two_mul, mul_comm]; apply mul_div_left _ zero_lt_two
  have h4 x : (x + x + 1) / 2 = x := by rw [← two_mul, add_comm]; simp [add_mul_div_left]; rfl
  cases a <;> cases b <;> simp [h1, h2, h3, h4] <;> split_ifs
    <;> 

Proof state:
case pos
f✝ f : Bool → Bool → Bool
h : autoParam (f false false = false) _auto✝
m n : ℕ
h1 : ∀ (x : ℕ), (x + x) % 2 = 0
h2 : ∀ (x : ℕ), (x + x + 1) % 2 = 1
h3 : ∀ (x : ℕ), (x + x) / 2 = x
h4 : ∀ (x : ℕ), (x + x + 1) / 2 = x
h✝¹ : ¬m = 0
h✝ : f false true = true
⊢ bitwise f m n + bitwise f m n + 1 = (fun a => a + a + 1) (bitwise f m n)

Next tactic:
simp_all (config := {decide := true})
@[simp]
lemma bitwise_bit {f : Bool → Bool → Bool} (h : f false false = false := by rfl) (a m b n) :
    bitwise f (bit a m) (bit b n) = bit (f a b) (bitwise f m n) := by
  conv_lhs => unfold bitwise
  simp (config := { unfoldPartialApp := true }) only [bit, bit1, bit0, Bool.cond_eq_ite]
  have h1 x :     (x + x) % 2 = 0 := by rw [← two_mul, mul_comm]; apply mul_mod_left
  have h2 x : (x + x + 1) % 2 = 1 := by rw [← two_mul, add_comm]; apply add_mul_mod_self_left
  have h3 x :     (x + x) / 2 = x := by rw [← two_mul, mul_comm]; apply mul_div_left _ zero_lt_two
  have h4 x : (x + x + 1) / 2 = x := by rw [← two_mul, add_comm]; simp [add_mul_div_left]; rfl
  cases a <;> cases b <;> simp [h1, h2, h3, h4] <;> split_ifs
    <;> 

Proof state:
case neg
f✝ f : Bool → Bool → Bool
h : autoParam (f false false = false) _auto✝
m n : ℕ
h1 : ∀ (x : ℕ), (x + x) % 2 = 0
h2 : ∀ (x : ℕ), (x + x + 1) % 2 = 1
h3 : ∀ (x : ℕ), (x + x) / 2 = x
h4 : ∀ (x : ℕ), (x + x + 1) / 2 = x
h✝¹ : ¬m = 0
h✝ : ¬f false true = true
⊢ bitwise f m n + bitwise f m n = (fun a => a + a) (bitwise f m n)

Next tactic:
simp_all (config := {decide := true})
@[simp]
lemma bitwise_bit {f : Bool → Bool → Bool} (h : f false false = false := by rfl) (a m b n) :
    bitwise f (bit a m) (bit b n) = bit (f a b) (bitwise f m n) := by
  conv_lhs => unfold bitwise
  simp (config := { unfoldPartialApp := true }) only [bit, bit1, bit0, Bool.cond_eq_ite]
  have h1 x :     (x + x) % 2 = 0 := by rw [← two_mul, mul_comm]; apply mul_mod_left
  have h2 x : (x + x + 1) % 2 = 1 := by rw [← two_mul, add_comm]; apply add_mul_mod_self_left
  have h3 x :     (x + x) / 2 = x := by rw [← two_mul, mul_comm]; apply mul_div_left _ zero_lt_two
  have h4 x : (x + x + 1) / 2 = x := by rw [← two_mul, add_comm]; simp [add_mul_div_left]; rfl
  cases a <;> cases b <;> simp [h1, h2, h3, h4] <;> split_ifs
    <;> 

Proof state:
case pos
f✝ f : Bool → Bool → Bool
h : autoParam (f false false = false) _auto✝
m n : ℕ
h1 : ∀ (x : ℕ), (x + x) % 2 = 0
h2 : ∀ (x : ℕ), (x + x + 1) % 2 = 1
h3 : ∀ (x : ℕ), (x + x) / 2 = x
h4 : ∀ (x : ℕ), (x + x + 1) / 2 = x
h✝¹ : n = 0
h✝ : f true false = true
⊢ m + m + 1 = (fun a => a + a + 1) (bitwise f m n)

Next tactic:
simp_all (config := {decide := true})
@[simp]
lemma bitwise_bit {f : Bool → Bool → Bool} (h : f false false = false := by rfl) (a m b n) :
    bitwise f (bit a m) (bit b n) = bit (f a b) (bitwise f m n) := by
  conv_lhs => unfold bitwise
  simp (config := { unfoldPartialApp := true }) only [bit, bit1, bit0, Bool.cond_eq_ite]
  have h1 x :     (x + x) % 2 = 0 := by rw [← two_mul, mul_comm]; apply mul_mod_left
  have h2 x : (x + x + 1) % 2 = 1 := by rw [← two_mul, add_comm]; apply add_mul_mod_self_left
  have h3 x :     (x + x) / 2 = x := by rw [← two_mul, mul_comm]; apply mul_div_left _ zero_lt_two
  have h4 x : (x + x + 1) / 2 = x := by rw [← two_mul, add_comm]; simp [add_mul_div_left]; rfl
  cases a <;> cases b <;> simp [h1, h2, h3, h4] <;> split_ifs
    <;> 

Proof state:
case neg
f✝ f : Bool → Bool → Bool
h : autoParam (f false false = false) _auto✝
m n : ℕ
h1 : ∀ (x : ℕ), (x + x) % 2 = 0
h2 : ∀ (x : ℕ), (x + x + 1) % 2 = 1
h3 : ∀ (x : ℕ), (x + x) / 2 = x
h4 : ∀ (x : ℕ), (x + x + 1) / 2 = x
h✝¹ : n = 0
h✝ : ¬f true false = true
⊢ 0 = (fun a => a + a) (bitwise f m n)

Next tactic:
simp_all (config := {decide := true})
@[simp]
lemma bitwise_bit {f : Bool → Bool → Bool} (h : f false false = false := by rfl) (a m b n) :
    bitwise f (bit a m) (bit b n) = bit (f a b) (bitwise f m n) := by
  conv_lhs => unfold bitwise
  simp (config := { unfoldPartialApp := true }) only [bit, bit1, bit0, Bool.cond_eq_ite]
  have h1 x :     (x + x) % 2 = 0 := by rw [← two_mul, mul_comm]; apply mul_mod_left
  have h2 x : (x + x + 1) % 2 = 1 := by rw [← two_mul, add_comm]; apply add_mul_mod_self_left
  have h3 x :     (x + x) / 2 = x := by rw [← two_mul, mul_comm]; apply mul_div_left _ zero_lt_two
  have h4 x : (x + x + 1) / 2 = x := by rw [← two_mul, add_comm]; simp [add_mul_div_left]; rfl
  cases a <;> cases b <;> simp [h1, h2, h3, h4] <;> split_ifs
    <;> 

Proof state:
case pos
f✝ f : Bool → Bool → Bool
h : autoParam (f false false = false) _auto✝
m n : ℕ
h1 : ∀ (x : ℕ), (x + x) % 2 = 0
h2 : ∀ (x : ℕ), (x + x + 1) % 2 = 1
h3 : ∀ (x : ℕ), (x + x) / 2 = x
h4 : ∀ (x : ℕ), (x + x + 1) / 2 = x
h✝¹ : ¬n = 0
h✝ : f true false = true
⊢ bitwise f m n + bitwise f m n + 1 = (fun a => a + a + 1) (bitwise f m n)

Next tactic:
simp_all (config := {decide := true})
@[simp]
lemma bitwise_bit {f : Bool → Bool → Bool} (h : f false false = false := by rfl) (a m b n) :
    bitwise f (bit a m) (bit b n) = bit (f a b) (bitwise f m n) := by
  conv_lhs => unfold bitwise
  simp (config := { unfoldPartialApp := true }) only [bit, bit1, bit0, Bool.cond_eq_ite]
  have h1 x :     (x + x) % 2 = 0 := by rw [← two_mul, mul_comm]; apply mul_mod_left
  have h2 x : (x + x + 1) % 2 = 1 := by rw [← two_mul, add_comm]; apply add_mul_mod_self_left
  have h3 x :     (x + x) / 2 = x := by rw [← two_mul, mul_comm]; apply mul_div_left _ zero_lt_two
  have h4 x : (x + x + 1) / 2 = x := by rw [← two_mul, add_comm]; simp [add_mul_div_left]; rfl
  cases a <;> cases b <;> simp [h1, h2, h3, h4] <;> split_ifs
    <;> 

Proof state:
case neg
f✝ f : Bool → Bool → Bool
h : autoParam (f false false = false) _auto✝
m n : ℕ
h1 : ∀ (x : ℕ), (x + x) % 2 = 0
h2 : ∀ (x : ℕ), (x + x + 1) % 2 = 1
h3 : ∀ (x : ℕ), (x + x) / 2 = x
h4 : ∀ (x : ℕ), (x + x + 1) / 2 = x
h✝¹ : ¬n = 0
h✝ : ¬f true false = true
⊢ bitwise f m n + bitwise f m n = (fun a => a + a) (bitwise f m n)

Next tactic:
simp_all (config := {decide := true})
@[simp]
lemma bitwise_bit {f : Bool → Bool → Bool} (h : f false false = false := by rfl) (a m b n) :
    bitwise f (bit a m) (bit b n) = bit (f a b) (bitwise f m n) := by
  conv_lhs => unfold bitwise
  simp (config := { unfoldPartialApp := true }) only [bit, bit1, bit0, Bool.cond_eq_ite]
  have h1 x :     (x + x) % 2 = 0 := by rw [← two_mul, mul_comm]; apply mul_mod_left
  have h2 x : (x + x + 1) % 2 = 1 := by rw [← two_mul, add_comm]; apply add_mul_mod_self_left
  have h3 x :     (x + x) / 2 = x := by rw [← two_mul, mul_comm]; apply mul_div_left _ zero_lt_two
  have h4 x : (x + x + 1) / 2 = x := by rw [← two_mul, add_comm]; simp [add_mul_div_left]; rfl
  cases a <;> cases b <;> simp [h1, h2, h3, h4] <;> split_ifs
    <;> 

Proof state:
case pos
f✝ f : Bool → Bool → Bool
h : autoParam (f false false = false) _auto✝
m n : ℕ
h1 : ∀ (x : ℕ), (x + x) % 2 = 0
h2 : ∀ (x : ℕ), (x + x + 1) % 2 = 1
h3 : ∀ (x : ℕ), (x + x) / 2 = x
h4 : ∀ (x : ℕ), (x + x + 1) / 2 = x
h✝ : f true true = true
⊢ bitwise f m n + bitwise f m n + 1 = (fun a => a + a + 1) (bitwise f m n)

Next tactic:
simp_all (config := {decide := true})
@[simp]
lemma bitwise_bit {f : Bool → Bool → Bool} (h : f false false = false := by rfl) (a m b n) :
    bitwise f (bit a m) (bit b n) = bit (f a b) (bitwise f m n) := by
  conv_lhs => unfold bitwise
  simp (config := { unfoldPartialApp := true }) only [bit, bit1, bit0, Bool.cond_eq_ite]
  have h1 x :     (x + x) % 2 = 0 := by rw [← two_mul, mul_comm]; apply mul_mod_left
  have h2 x : (x + x + 1) % 2 = 1 := by rw [← two_mul, add_comm]; apply add_mul_mod_self_left
  have h3 x :     (x + x) / 2 = x := by rw [← two_mul, mul_comm]; apply mul_div_left _ zero_lt_two
  have h4 x : (x + x + 1) / 2 = x := by rw [← two_mul, add_comm]; simp [add_mul_div_left]; rfl
  cases a <;> cases b <;> simp [h1, h2, h3, h4] <;> split_ifs
    <;> 

Proof state:
case neg
f✝ f : Bool → Bool → Bool
h : autoParam (f false false = false) _auto✝
m n : ℕ
h1 : ∀ (x : ℕ), (x + x) % 2 = 0
h2 : ∀ (x : ℕ), (x + x + 1) % 2 = 1
h3 : ∀ (x : ℕ), (x + x) / 2 = x
h4 : ∀ (x : ℕ), (x + x + 1) / 2 = x
h✝ : ¬f true true = true
⊢ bitwise f m n + bitwise f m n = (fun a => a + a) (bitwise f m n)

Next tactic:
simp_all (config := {decide := true})
lemma bit_mod_two (a : Bool) (x : ℕ) :
    bit a x % 2 = if a then 1 else 0 := by
  

Proof state:
f : Bool → Bool → Bool
a : Bool
x : ℕ
⊢ bit a x % 2 = if a = true then 1 else 0

Next tactic:
simp (config := { unfoldPartialApp := true }) [bit, bit0, bit1, Bool.cond_eq_ite, ← mul_two]
lemma bit_mod_two (a : Bool) (x : ℕ) :
    bit a x % 2 = if a then 1 else 0 := by
  simp (config := { unfoldPartialApp := true }) [bit, bit0, bit1, Bool.cond_eq_ite, ← mul_two]
  

Proof state:
f : Bool → Bool → Bool
a : Bool
x : ℕ
⊢ ite (a = true) (fun a => a * 2 + 1) (fun a => a * 2) x % 2 = if a = true then 1 else 0

Next tactic:
split_ifs
lemma bit_mod_two (a : Bool) (x : ℕ) :
    bit a x % 2 = if a then 1 else 0 := by
  simp (config := { unfoldPartialApp := true }) [bit, bit0, bit1, Bool.cond_eq_ite, ← mul_two]
  split_ifs <;> 

Proof state:
case pos
f : Bool → Bool → Bool
a : Bool
x : ℕ
h✝ : a = true
⊢ (fun a => a * 2 + 1) x % 2 = 1

Next tactic:
simp [Nat.add_mod]
lemma bit_mod_two (a : Bool) (x : ℕ) :
    bit a x % 2 = if a then 1 else 0 := by
  simp (config := { unfoldPartialApp := true }) [bit, bit0, bit1, Bool.cond_eq_ite, ← mul_two]
  split_ifs <;> 

Proof state:
case neg
f : Bool → Bool → Bool
a : Bool
x : ℕ
h✝ : ¬a = true
⊢ (fun a => a * 2) x % 2 = 0

Next tactic:
simp [Nat.add_mod]
@[simp]
lemma bit_mod_two_eq_zero_iff (a x) :
    bit a x % 2 = 0 ↔ !a := by
  

Proof state:
f : Bool → Bool → Bool
a : Bool
x : ℕ
⊢ bit a x % 2 = 0 ↔ (!a) = true

Next tactic:
rw [bit_mod_two]
@[simp]
lemma bit_mod_two_eq_zero_iff (a x) :
    bit a x % 2 = 0 ↔ !a := by
  rw [bit_mod_two]; 

Proof state:
f : Bool → Bool → Bool
a : Bool
x : ℕ
⊢ (if a = true then 1 else 0) = 0 ↔ (!a) = true

Next tactic:
split_ifs
@[simp]
lemma bit_mod_two_eq_zero_iff (a x) :
    bit a x % 2 = 0 ↔ !a := by
  rw [bit_mod_two]; split_ifs <;> 

Proof state:
case pos
f : Bool → Bool → Bool
a : Bool
x : ℕ
h✝ : a = true
⊢ False ↔ (!a) = true

Next tactic:
simp_all
@[simp]
lemma bit_mod_two_eq_zero_iff (a x) :
    bit a x % 2 = 0 ↔ !a := by
  rw [bit_mod_two]; split_ifs <;> 

Proof state:
case neg
f : Bool → Bool → Bool
a : Bool
x : ℕ
h✝ : ¬a = true
⊢ 0 = 0 ↔ (!a) = true

Next tactic:
simp_all
@[simp]
lemma bit_mod_two_eq_one_iff (a x) :
    bit a x % 2 = 1 ↔ a := by
  

Proof state:
f : Bool → Bool → Bool
a : Bool
x : ℕ
⊢ bit a x % 2 = 1 ↔ a = true

Next tactic:
rw [bit_mod_two]
@[simp]
lemma bit_mod_two_eq_one_iff (a x) :
    bit a x % 2 = 1 ↔ a := by
  rw [bit_mod_two]; 

Proof state:
f : Bool → Bool → Bool
a : Bool
x : ℕ
⊢ (if a = true then 1 else 0) = 1 ↔ a = true

Next tactic:
split_ifs
@[simp]
lemma bit_mod_two_eq_one_iff (a x) :
    bit a x % 2 = 1 ↔ a := by
  rw [bit_mod_two]; split_ifs <;> 

Proof state:
case pos
f : Bool → Bool → Bool
a : Bool
x : ℕ
h✝ : a = true
⊢ 1 = 1 ↔ a = true

Next tactic:
simp_all
@[simp]
lemma bit_mod_two_eq_one_iff (a x) :
    bit a x % 2 = 1 ↔ a := by
  rw [bit_mod_two]; split_ifs <;> 

Proof state:
case neg
f : Bool → Bool → Bool
a : Bool
x : ℕ
h✝ : ¬a = true
⊢ False ↔ a = true

Next tactic:
simp_all
@[simp]
theorem bit_eq_zero {n : ℕ} {b : Bool} : n.bit b = 0 ↔ n = 0 ∧ b = false := by
  

Proof state:
n : ℕ
b : Bool
⊢ bit b n = 0 ↔ n = 0 ∧ b = false

Next tactic:
cases b
@[simp]
theorem bit_eq_zero {n : ℕ} {b : Bool} : n.bit b = 0 ↔ n = 0 ∧ b = false := by
  cases b <;> 

Proof state:
case false
n : ℕ
⊢ bit false n = 0 ↔ n = 0 ∧ false = false

Next tactic:
simp [Nat.bit0_eq_zero, Nat.bit1_ne_zero]
@[simp]
theorem bit_eq_zero {n : ℕ} {b : Bool} : n.bit b = 0 ↔ n = 0 ∧ b = false := by
  cases b <;> 

Proof state:
case true
n : ℕ
⊢ bit true n = 0 ↔ n = 0 ∧ true = false

Next tactic:
simp [Nat.bit0_eq_zero, Nat.bit1_ne_zero]
theorem bit_ne_zero_iff {n : ℕ} {b : Bool} : n.bit b ≠ 0 ↔ n = 0 → b = true := by
  

Proof state:
n : ℕ
b : Bool
⊢ bit b n ≠ 0 ↔ n = 0 → b = true

Next tactic:
simpa only [not_and, Bool.not_eq_false] using (@bit_eq_zero n b).not
/-- An alternative for `bitwise_bit` which replaces the `f false false = false` assumption
with assumptions that neither `bit a m` nor `bit b n` are `0`
(albeit, phrased as the implications `m = 0 → a = true` and `n = 0 → b = true`) -/
lemma bitwise_bit' {f : Bool → Bool → Bool} (a : Bool) (m : Nat) (b : Bool) (n : Nat)
    (ham : m = 0 → a = true) (hbn : n = 0 → b = true) :
    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 : ℕ
ham : m = 0 → a = true
hbn : n = 0 → b = true
⊢ bitwise f (bit a m) (bit b n) = bit (f a b) (bitwise f m n)

Next tactic:
conv_lhs => unfold bitwise
/-- An alternative for `bitwise_bit` which replaces the `f false false = false` assumption
with assumptions that neither `bit a m` nor `bit b n` are `0`
(albeit, phrased as the implications `m = 0 → a = true` and `n = 0 → b = true`) -/
lemma bitwise_bit' {f : Bool → Bool → Bool} (a : Bool) (m : Nat) (b : Bool) (n : Nat)
    (ham : m = 0 → a = true) (hbn : n = 0 → b = true) :
    bitwise f (bit a m) (bit b n) = bit (f a b) (bitwise f m n) := by
  conv_lhs => 

Proof state:
f : Bool → Bool → Bool
a : Bool
m : ℕ
b : Bool
n : ℕ
ham : m = 0 → a = true
hbn : n = 0 → b = true
| bitwise f (bit a m) (bit b n)

Next tactic:
unfold bitwise
/-- An alternative for `bitwise_bit` which replaces the `f false false = false` assumption
with assumptions that neither `bit a m` nor `bit b n` are `0`
(albeit, phrased as the implications `m = 0 → a = true` and `n = 0 → b = true`) -/
lemma bitwise_bit' {f : Bool → Bool → Bool} (a : Bool) (m : Nat) (b : Bool) (n : Nat)
    (ham : m = 0 → a = true) (hbn : n = 0 → b = true) :
    bitwise f (bit a m) (bit b n) = bit (f a b) (bitwise f m n) := by
  conv_lhs => unfold bitwise
  

Proof state:
f : Bool → Bool → Bool
a : Bool
m : ℕ
b : Bool
n : ℕ
ham : m = 0 → a = true
hbn : n = 0 → b = true
⊢ (if bit a m = 0 then if f false true = true then bit b n else 0
    else
      if bit b n = 0 then if f true false = true then bit a m else 0
      else
        let n' := bit a m / 2;
        let m' := bit b n / 2;
        let b₁ := bit a m % 2 = 1;
        let b₂ := bit b n % 2 = 1;
        let r := bitwise f n' m';
        if f (decide b₁) (decide b₂) = true then r + r + 1 else r + r) =
    bit (f a b) (bitwise f m n)

Next tactic:
rw [← bit_ne_zero_iff] at ham hbn
/-- An alternative for `bitwise_bit` which replaces the `f false false = false` assumption
with assumptions that neither `bit a m` nor `bit b n` are `0`
(albeit, phrased as the implications `m = 0 → a = true` and `n = 0 → b = true`) -/
lemma bitwise_bit' {f : Bool → Bool → Bool} (a : Bool) (m : Nat) (b : Bool) (n : Nat)
    (ham : m = 0 → a = true) (hbn : n = 0 → b = true) :
    bitwise f (bit a m) (bit b n) = bit (f a b) (bitwise f m n) := by
  conv_lhs => unfold bitwise
  rw [← bit_ne_zero_iff] at ham hbn
  

Proof state:
f : Bool → Bool → Bool
a : Bool
m : ℕ
b : Bool
n : ℕ
ham : bit a m ≠ 0
hbn : bit b n ≠ 0
⊢ (if bit a m = 0 then if f false true = true then bit b n else 0
    else
      if bit b n = 0 then if f true false = true then bit a m else 0
      else
        let n' := bit a m / 2;
        let m' := bit b n / 2;
        let b₁ := bit a m % 2 = 1;
        let b₂ := bit b n % 2 = 1;
        let r := bitwise f n' m';
        if f (decide b₁) (decide b₂) = true then r + r + 1 else r + r) =
    bit (f a b) (bitwise f m n)

Next tactic:
simp only [ham, hbn, bit_mod_two_eq_one_iff, Bool.decide_coe, ← div2_val, div2_bit, ne_eq,
    ite_false]
/-- An alternative for `bitwise_bit` which replaces the `f false false = false` assumption
with assumptions that neither `bit a m` nor `bit b n` are `0`
(albeit, phrased as the implications `m = 0 → a = true` and `n = 0 → b = true`) -/
lemma bitwise_bit' {f : Bool → Bool → Bool} (a : Bool) (m : Nat) (b : Bool) (n : Nat)
    (ham : m = 0 → a = true) (hbn : n = 0 → b = true) :
    bitwise f (bit a m) (bit b n) = bit (f a b) (bitwise f m n) := by
  conv_lhs => unfold bitwise
  rw [← bit_ne_zero_iff] at ham hbn
  simp only [ham, hbn, bit_mod_two_eq_one_iff, Bool.decide_coe, ← div2_val, div2_bit, ne_eq,
    ite_false]
  

Proof state:
f : Bool → Bool → Bool
a : Bool
m : ℕ
b : Bool
n : ℕ
ham : bit a m ≠ 0
hbn : bit b n ≠ 0
⊢ (if f a b = true then bitwise f m n + bitwise f m n + 1 else bitwise f m n + bitwise f m n) =
    bit (f a b) (bitwise f m n)

Next tactic:
conv_rhs => simp only [bit, bit1, bit0, Bool.cond_eq_ite]