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 <;> 

Proof state:
case true
f✝ f : Bool → Bool → Bool
h : autoParam (f false false = false) _auto✝
m : ℕ
b : Bool
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
⊢ (if ite (true = true) (fun a => a + a + 1) (fun a => a + a) m = 0 then
      if f false true = true then ite (b = true) (fun a => a + a + 1) (fun a => a + a) n else 0
    else
      if ite (b = true) (fun a => a + a + 1) (fun a => a + a) n = 0 then
        if f true false = true then ite (true = true) (fun a => a + a + 1) (fun a => a + a) m else 0
      else
        if
            f (decide (ite (true = true) (fun a => a + a + 1) (fun a => a + a) m % 2 = 1))
                (decide (ite (b = true) (fun a => a + a + 1) (fun a => a + a) n % 2 = 1)) =
              true then
          bitwise f (ite (true = true) (fun a => a + a + 1) (fun a => a + a) m / 2)
                (ite (b = true) (fun a => a + a + 1) (fun a => a + a) n / 2) +
              bitwise f (ite (true = true) (fun a => a + a + 1) (fun a => a + a) m / 2)
                (ite (b = true) (fun a => a + a + 1) (fun a => a + a) n / 2) +
            1
        else
          bitwise f (ite (true = true) (fun a => a + a + 1) (fun a => a + a) m / 2)
              (ite (b = true) (fun a => a + a + 1) (fun a => a + a) n / 2) +
            bitwise f (ite (true = true) (fun a => a + a + 1) (fun a => a + a) m / 2)
              (ite (b = true) (fun a => a + a + 1) (fun a => a + a) n / 2)) =
    ite (f true b = true) (fun a => a + a + 1) (fun a => a + a) (bitwise f m n)

Next tactic:
cases b
@[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 <;> 

Proof state:
case false.false
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
⊢ (if ite (false = true) (fun a => a + a + 1) (fun a => a + a) m = 0 then
      if f false true = true then ite (false = true) (fun a => a + a + 1) (fun a => a + a) n else 0
    else
      if ite (false = true) (fun a => a + a + 1) (fun a => a + a) n = 0 then
        if f true false = true then ite (false = true) (fun a => a + a + 1) (fun a => a + a) m else 0
      else
        if
            f (decide (ite (false = true) (fun a => a + a + 1) (fun a => a + a) m % 2 = 1))
                (decide (ite (false = true) (fun a => a + a + 1) (fun a => a + a) n % 2 = 1)) =
              true then
          bitwise f (ite (false = true) (fun a => a + a + 1) (fun a => a + a) m / 2)
                (ite (false = true) (fun a => a + a + 1) (fun a => a + a) n / 2) +
              bitwise f (ite (false = true) (fun a => a + a + 1) (fun a => a + a) m / 2)
                (ite (false = true) (fun a => a + a + 1) (fun a => a + a) n / 2) +
            1
        else
          bitwise f (ite (false = true) (fun a => a + a + 1) (fun a => a + a) m / 2)
              (ite (false = true) (fun a => a + a + 1) (fun a => a + a) n / 2) +
            bitwise f (ite (false = true) (fun a => a + a + 1) (fun a => a + a) m / 2)
              (ite (false = true) (fun a => a + a + 1) (fun a => a + a) n / 2)) =
    ite (f false false = true) (fun a => a + a + 1) (fun a => a + a) (bitwise f m n)

Next tactic:
simp [h1, h2, h3, h4]
@[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 <;> 

Proof state:
case false.true
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
⊢ (if ite (false = true) (fun a => a + a + 1) (fun a => a + a) m = 0 then
      if f false true = true then ite (true = true) (fun a => a + a + 1) (fun a => a + a) n else 0
    else
      if ite (true = true) (fun a => a + a + 1) (fun a => a + a) n = 0 then
        if f true false = true then ite (false = true) (fun a => a + a + 1) (fun a => a + a) m else 0
      else
        if
            f (decide (ite (false = true) (fun a => a + a + 1) (fun a => a + a) m % 2 = 1))
                (decide (ite (true = true) (fun a => a + a + 1) (fun a => a + a) n % 2 = 1)) =
              true then
          bitwise f (ite (false = true) (fun a => a + a + 1) (fun a => a + a) m / 2)
                (ite (true = true) (fun a => a + a + 1) (fun a => a + a) n / 2) +
              bitwise f (ite (false = true) (fun a => a + a + 1) (fun a => a + a) m / 2)
                (ite (true = true) (fun a => a + a + 1) (fun a => a + a) n / 2) +
            1
        else
          bitwise f (ite (false = true) (fun a => a + a + 1) (fun a => a + a) m / 2)
              (ite (true = true) (fun a => a + a + 1) (fun a => a + a) n / 2) +
            bitwise f (ite (false = true) (fun a => a + a + 1) (fun a => a + a) m / 2)
              (ite (true = true) (fun a => a + a + 1) (fun a => a + a) n / 2)) =
    ite (f false true = true) (fun a => a + a + 1) (fun a => a + a) (bitwise f m n)

Next tactic:
simp [h1, h2, h3, h4]
@[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 <;> 

Proof state:
case true.false
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
⊢ (if ite (true = true) (fun a => a + a + 1) (fun a => a + a) m = 0 then
      if f false true = true then ite (false = true) (fun a => a + a + 1) (fun a => a + a) n else 0
    else
      if ite (false = true) (fun a => a + a + 1) (fun a => a + a) n = 0 then
        if f true false = true then ite (true = true) (fun a => a + a + 1) (fun a => a + a) m else 0
      else
        if
            f (decide (ite (true = true) (fun a => a + a + 1) (fun a => a + a) m % 2 = 1))
                (decide (ite (false = true) (fun a => a + a + 1) (fun a => a + a) n % 2 = 1)) =
              true then
          bitwise f (ite (true = true) (fun a => a + a + 1) (fun a => a + a) m / 2)
                (ite (false = true) (fun a => a + a + 1) (fun a => a + a) n / 2) +
              bitwise f (ite (true = true) (fun a => a + a + 1) (fun a => a + a) m / 2)
                (ite (false = true) (fun a => a + a + 1) (fun a => a + a) n / 2) +
            1
        else
          bitwise f (ite (true = true) (fun a => a + a + 1) (fun a => a + a) m / 2)
              (ite (false = true) (fun a => a + a + 1) (fun a => a + a) n / 2) +
            bitwise f (ite (true = true) (fun a => a + a + 1) (fun a => a + a) m / 2)
              (ite (false = true) (fun a => a + a + 1) (fun a => a + a) n / 2)) =
    ite (f true false = true) (fun a => a + a + 1) (fun a => a + a) (bitwise f m n)

Next tactic:
simp [h1, h2, h3, h4]
@[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 <;> 

Proof state:
case true.true
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
⊢ (if ite (true = true) (fun a => a + a + 1) (fun a => a + a) m = 0 then
      if f false true = true then ite (true = true) (fun a => a + a + 1) (fun a => a + a) n else 0
    else
      if ite (true = true) (fun a => a + a + 1) (fun a => a + a) n = 0 then
        if f true false = true then ite (true = true) (fun a => a + a + 1) (fun a => a + a) m else 0
      else
        if
            f (decide (ite (true = true) (fun a => a + a + 1) (fun a => a + a) m % 2 = 1))
                (decide (ite (true = true) (fun a => a + a + 1) (fun a => a + a) n % 2 = 1)) =
              true then
          bitwise f (ite (true = true) (fun a => a + a + 1) (fun a => a + a) m / 2)
                (ite (true = true) (fun a => a + a + 1) (fun a => a + a) n / 2) +
              bitwise f (ite (true = true) (fun a => a + a + 1) (fun a => a + a) m / 2)
                (ite (true = true) (fun a => a + a + 1) (fun a => a + a) n / 2) +
            1
        else
          bitwise f (ite (true = true) (fun a => a + a + 1) (fun a => a + a) m / 2)
              (ite (true = true) (fun a => a + a + 1) (fun a => a + a) n / 2) +
            bitwise f (ite (true = true) (fun a => a + a + 1) (fun a => a + a) m / 2)
              (ite (true = true) (fun a => a + a + 1) (fun a => a + a) n / 2)) =
    ite (f true true = true) (fun a => a + a + 1) (fun a => a + a) (bitwise f m n)

Next tactic:
simp [h1, h2, h3, h4]
@[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] <;> 

Proof state:
case false.false
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
⊢ (if m = 0 then if f false true = true then n + n else 0
    else
      if n = 0 then if f true false = true then m + m else 0
      else if f false false = true then bitwise f m n + bitwise f m n + 1 else bitwise f m n + bitwise f m n) =
    ite (f false false = true) (fun a => a + a + 1) (fun a => a + a) (bitwise f m n)

Next tactic:
split_ifs
@[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] <;> 

Proof state:
case false.true
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
⊢ (if m = 0 then if f false true = true then n + n + 1 else 0
    else if f false true = true then bitwise f m n + bitwise f m n + 1 else bitwise f m n + bitwise f m n) =
    ite (f false true = true) (fun a => a + a + 1) (fun a => a + a) (bitwise f m n)

Next tactic:
split_ifs
@[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] <;> 

Proof state:
case true.false
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
⊢ (if n = 0 then if f true false = true then m + m + 1 else 0
    else if f true false = true then bitwise f m n + bitwise f m n + 1 else bitwise f m n + bitwise f m n) =
    ite (f true false = true) (fun a => a + a + 1) (fun a => a + a) (bitwise f m n)

Next tactic:
split_ifs
@[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] <;> 

Proof state:
case true.true
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
⊢ (if f true true = true then bitwise f m n + bitwise f m n + 1 else bitwise f m n + bitwise f m n) =
    ite (f true true = true) (fun a => a + a + 1) (fun a => a + a) (bitwise f m n)

Next tactic:
split_ifs
@[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
h✝ : f false false = true
⊢ n + n = (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
h✝ : ¬f false false = true
⊢ n + 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
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✝¹ : ¬f false true = 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 true false = true
h✝ : f false false = true
⊢ m + m = (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
⊢ m + m = (fun a => a + a) (bitwise f m n)

Next tactic:
simp_all (config := {decide := true})