l3lab/ntp-mathlib huggingface dataset:
theorem binaryRec_of_ne_zero {C : Nat → Sort*} (z : C 0) (f : ∀ b n, C n → C (bit b n)) {n}
    (h : n ≠ 0) :
    binaryRec z f n = bit_decomp n ▸ f (bodd n) (div2 n) (binaryRec z f (div2 n)) := by
  

Proof state:
f✝ : Bool → Bool → Bool
C : ℕ → Sort u_1
z : C 0
f : (b : Bool) → (n : ℕ) → C n → C (bit b n)
n : ℕ
h : n ≠ 0
⊢ binaryRec z f n = (_ : bit (bodd n) (div2 n) = n) ▸ f (bodd n) (div2 n) (binaryRec z f (div2 n))

Next tactic:
rw [Eq.rec_eq_cast]
theorem binaryRec_of_ne_zero {C : Nat → Sort*} (z : C 0) (f : ∀ b n, C n → C (bit b n)) {n}
    (h : n ≠ 0) :
    binaryRec z f n = bit_decomp n ▸ f (bodd n) (div2 n) (binaryRec z f (div2 n)) := by
  rw [Eq.rec_eq_cast]
  

Proof state:
f✝ : Bool → Bool → Bool
C : ℕ → Sort u_1
z : C 0
f : (b : Bool) → (n : ℕ) → C n → C (bit b n)
n : ℕ
h : n ≠ 0
⊢ binaryRec z f n = cast (_ : C (bit (bodd n) (div2 n)) = C n) (f (bodd n) (div2 n) (binaryRec z f (div2 n)))

Next tactic:
rw [binaryRec]
theorem binaryRec_of_ne_zero {C : Nat → Sort*} (z : C 0) (f : ∀ b n, C n → C (bit b n)) {n}
    (h : n ≠ 0) :
    binaryRec z f n = bit_decomp n ▸ f (bodd n) (div2 n) (binaryRec z f (div2 n)) := by
  rw [Eq.rec_eq_cast]
  rw [binaryRec]
  

Proof state:
f✝ : Bool → Bool → Bool
C : ℕ → Sort u_1
z : C 0
f : (b : Bool) → (n : ℕ) → C n → C (bit b n)
n : ℕ
h : n ≠ 0
⊢ (if n0 : n = 0 then Eq.mpr (_ : C n = C 0) z
    else
      let n' := div2 n;
      let_fun _x := (_ : bit (bodd n) (div2 n) = n);
      Eq.mpr (_ : C n = C (bit (bodd n) n')) (f (bodd n) n' (binaryRec z f n'))) =
    cast (_ : C (bit (bodd n) (div2 n)) = C n) (f (bodd n) (div2 n) (binaryRec z f (div2 n)))

Next tactic:
dsimp only
theorem binaryRec_of_ne_zero {C : Nat → Sort*} (z : C 0) (f : ∀ b n, C n → C (bit b n)) {n}
    (h : n ≠ 0) :
    binaryRec z f n = bit_decomp n ▸ f (bodd n) (div2 n) (binaryRec z f (div2 n)) := by
  rw [Eq.rec_eq_cast]
  rw [binaryRec]
  dsimp only
  

Proof state:
f✝ : Bool → Bool → Bool
C : ℕ → Sort u_1
z : C 0
f : (b : Bool) → (n : ℕ) → C n → C (bit b n)
n : ℕ
h : n ≠ 0
⊢ (if n0 : n = 0 then Eq.mpr (_ : C n = C 0) z
    else Eq.mpr (_ : C n = C (bit (bodd n) (div2 n))) (f (bodd n) (div2 n) (binaryRec z f (div2 n)))) =
    cast (_ : C (bit (bodd n) (div2 n)) = C n) (f (bodd n) (div2 n) (binaryRec z f (div2 n)))

Next tactic:
rw [dif_neg h, eq_mpr_eq_cast]
@[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
  

Proof state:
f✝ f : Bool → Bool → Bool
h : autoParam (f false false = false) _auto✝
a : Bool
m : ℕ
b : Bool
n : ℕ
⊢ bitwise f (bit a m) (bit b n) = bit (f a b) (bitwise f m n)

Next tactic:
conv_lhs => unfold bitwise
@[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 => 

Proof state:
f✝ f : Bool → Bool → Bool
h : autoParam (f false false = false) _auto✝
a : Bool
m : ℕ
b : Bool
n : ℕ
| bitwise f (bit a m) (bit b n)

Next tactic:
unfold bitwise
@[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
  

Proof state:
f✝ f : Bool → Bool → Bool
h : autoParam (f false false = false) _auto✝
a : Bool
m : ℕ
b : Bool
n : ℕ
⊢ (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 (config := { unfoldPartialApp := true }) only [bit, bit1, bit0, Bool.cond_eq_ite]
@[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]
  

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

Next tactic:
have h1 x :     (x + x) % 2 = 0 := by rw [← two_mul, mul_comm]; apply mul_mod_left
@[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 

Proof state:
f✝ f : Bool → Bool → Bool
h : autoParam (f false false = false) _auto✝
a : Bool
m : ℕ
b : Bool
n x : ℕ
⊢ (x + x) % 2 = 0

Next tactic:
rw [← two_mul, mul_comm]
@[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]; 

Proof state:
f✝ f : Bool → Bool → Bool
h : autoParam (f false false = false) _auto✝
a : Bool
m : ℕ
b : Bool
n x : ℕ
⊢ x * 2 % 2 = 0

Next tactic:
apply mul_mod_left
@[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
  

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

Next tactic:
have h2 x : (x + x + 1) % 2 = 1 := by rw [← two_mul, add_comm]; apply add_mul_mod_self_left
@[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 

Proof state:
f✝ f : Bool → Bool → Bool
h : autoParam (f false false = false) _auto✝
a : Bool
m : ℕ
b : Bool
n : ℕ
h1 : ∀ (x : ℕ), (x + x) % 2 = 0
x : ℕ
⊢ (x + x + 1) % 2 = 1

Next tactic:
rw [← two_mul, add_comm]
@[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]; 

Proof state:
f✝ f : Bool → Bool → Bool
h : autoParam (f false false = false) _auto✝
a : Bool
m : ℕ
b : Bool
n : ℕ
h1 : ∀ (x : ℕ), (x + x) % 2 = 0
x : ℕ
⊢ (1 + 2 * x) % 2 = 1

Next tactic:
apply add_mul_mod_self_left
@[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
  

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

Next tactic:
have h3 x :     (x + x) / 2 = x := by rw [← two_mul, mul_comm]; apply mul_div_left _ zero_lt_two
@[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 

Proof state:
f✝ f : Bool → Bool → Bool
h : autoParam (f false false = false) _auto✝
a : Bool
m : ℕ
b : Bool
n : ℕ
h1 : ∀ (x : ℕ), (x + x) % 2 = 0
h2 : ∀ (x : ℕ), (x + x + 1) % 2 = 1
x : ℕ
⊢ (x + x) / 2 = x

Next tactic:
rw [← two_mul, mul_comm]
@[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]; 

Proof state:
f✝ f : Bool → Bool → Bool
h : autoParam (f false false = false) _auto✝
a : Bool
m : ℕ
b : Bool
n : ℕ
h1 : ∀ (x : ℕ), (x + x) % 2 = 0
h2 : ∀ (x : ℕ), (x + x + 1) % 2 = 1
x : ℕ
⊢ x * 2 / 2 = x

Next tactic:
apply mul_div_left _ zero_lt_two
@[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
  

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

Next tactic:
have h4 x : (x + x + 1) / 2 = x := by rw [← two_mul, add_comm]; simp [add_mul_div_left]; rfl
@[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 

Proof state:
f✝ f : Bool → Bool → Bool
h : autoParam (f false false = false) _auto✝
a : Bool
m : ℕ
b : Bool
n : ℕ
h1 : ∀ (x : ℕ), (x + x) % 2 = 0
h2 : ∀ (x : ℕ), (x + x + 1) % 2 = 1
h3 : ∀ (x : ℕ), (x + x) / 2 = x
x : ℕ
⊢ (x + x + 1) / 2 = x

Next tactic:
rw [← two_mul, add_comm]
@[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]; 

Proof state:
f✝ f : Bool → Bool → Bool
h : autoParam (f false false = false) _auto✝
a : Bool
m : ℕ
b : Bool
n : ℕ
h1 : ∀ (x : ℕ), (x + x) % 2 = 0
h2 : ∀ (x : ℕ), (x + x + 1) % 2 = 1
h3 : ∀ (x : ℕ), (x + x) / 2 = x
x : ℕ
⊢ (1 + 2 * x) / 2 = x

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

Proof state:
f✝ f : Bool → Bool → Bool
h : autoParam (f false false = false) _auto✝
a : Bool
m : ℕ
b : Bool
n : ℕ
h1 : ∀ (x : ℕ), (x + x) % 2 = 0
h2 : ∀ (x : ℕ), (x + x + 1) % 2 = 1
h3 : ∀ (x : ℕ), (x + x) / 2 = x
x : ℕ
⊢ 1 / 2 = 0

Next tactic:
rfl
@[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
  

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

Next tactic:
cases a
@[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 false
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 (false = 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 (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 (b = 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 (b = 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 (b = 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 (b = 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 (b = true) (fun a => a + a + 1) (fun a => a + a) n / 2)) =
    ite (f false b = true) (fun a => a + a + 1) (fun a => a + a) (bitwise f m n)

Next tactic:
cases b