-- Mathlib/Data/Nat/Bitwise.lean
@[simp]
lemma bitwise_bit {f : Bool → Bool → Bool} (h : f false false = false

Proof state:
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)

Tactic:
simp only [bit, ite_apply, Bool.cond_eq_ite]

Result:
f : Bool → Bool → Bool
h : autoParam (f false false = false) _auto✝
a : Bool
m : ℕ
b : Bool
n : ℕ
⊢ (if (if a = true then 2 * m + 1 else 2 * m) = 0 then
      if f false true = true then if b = true then 2 * n + 1 else 2 * n else 0
    else
      if (if b = true then 2 * n + 1 else 2 * n) = 0 then
        if f true false = true then if a = true then 2 * m + 1 else 2 * m else 0
      else
        if
            f (decide ((if a = true then 2 * m + 1 else 2 * m) % 2 = 1))
                (decide ((if b = true then 2 * n + 1 else 2 * n) % 2 = 1)) =
              true then
          bitwise f ((if a = true then 2 * m + 1 else 2 * m) / 2) ((if b = true then 2 * n + 1 else 2 * n) / 2) +
              bitwise f ((if a = true then 2 * m + 1 else 2 * m) / 2) ((if b = true then 2 * n + 1 else 2 * n) / 2) +
            1
        else
          bitwise f ((if a = true then 2 * m + 1 else 2 * m) / 2) ((if b = true then 2 * n + 1 else 2 * n) / 2) +
            bitwise f ((if a = true then 2 * m + 1 else 2 * m) / 2) ((if b = true then 2 * n + 1 else 2 * n) / 2)) =
    if f a b = true then 2 * bitwise f m n + 1 else 2 * bitwise f m n

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

Tactic:
rw [← two_mul, add_comm]

Result:
f : Bool → Bool → Bool
h : autoParam (f false false = false) _auto✝
a : Bool
m : ℕ
b : Bool
n x : ℕ
⊢ (1 + 2 * x) / 2 = x

Proof state:
f : Bool → Bool → Bool
h : autoParam (f false false = false) _auto✝
a : Bool
m : ℕ
b : Bool
n : ℕ
⊢ (if (if a = true then 2 * m + 1 else 2 * m) = 0 then
      if f false true = true then if b = true then 2 * n + 1 else 2 * n else 0
    else
      if (if b = true then 2 * n + 1 else 2 * n) = 0 then
        if f true false = true then if a = true then 2 * m + 1 else 2 * m else 0
      else
        if
            f (decide ((if a = true then 2 * m + 1 else 2 * m) % 2 = 1))
                (decide ((if b = true then 2 * n + 1 else 2 * n) % 2 = 1)) =
              true then
          bitwise f ((if a = true then 2 * m + 1 else 2 * m) / 2) ((if b = true then 2 * n + 1 else 2 * n) / 2) +
              bitwise f ((if a = true then 2 * m + 1 else 2 * m) / 2) ((if b = true then 2 * n + 1 else 2 * n) / 2) +
            1
        else
          bitwise f ((if a = true then 2 * m + 1 else 2 * m) / 2) ((if b = true then 2 * n + 1 else 2 * n) / 2) +
            bitwise f ((if a = true then 2 * m + 1 else 2 * m) / 2) ((if b = true then 2 * n + 1 else 2 * n) / 2)) =
    if f a b = true then 2 * bitwise f m n + 1 else 2 * bitwise f m n

Tactic:
have h4 x : (x + x + 1) / 2 = x := by rw [← two_mul, add_comm]; simp [add_mul_div_left]

Result:
f : Bool → Bool → Bool
h : autoParam (f false false = false) _auto✝
a : Bool
m : ℕ
b : Bool
n : ℕ
h4 : ∀ (x : ℕ), (x + x + 1) / 2 = x
⊢ (if (if a = true then 2 * m + 1 else 2 * m) = 0 then
      if f false true = true then if b = true then 2 * n + 1 else 2 * n else 0
    else
      if (if b = true then 2 * n + 1 else 2 * n) = 0 then
        if f true false = true then if a = true then 2 * m + 1 else 2 * m else 0
      else
        if
            f (decide ((if a = true then 2 * m + 1 else 2 * m) % 2 = 1))
                (decide ((if b = true then 2 * n + 1 else 2 * n) % 2 = 1)) =
              true then
          bitwise f ((if a = true then 2 * m + 1 else 2 * m) / 2) ((if b = true then 2 * n + 1 else 2 * n) / 2) +
              bitwise f ((if a = true then 2 * m + 1 else 2 * m) / 2) ((if b = true then 2 * n + 1 else 2 * n) / 2) +
            1
        else
          bitwise f ((if a = true then 2 * m + 1 else 2 * m) / 2) ((if b = true then 2 * n + 1 else 2 * n) / 2) +
            bitwise f ((if a = true then 2 * m + 1 else 2 * m) / 2) ((if b = true then 2 * n + 1 else 2 * n) / 2)) =
    if f a b = true then 2 * bitwise f m n + 1 else 2 * bitwise f m n

Proof state:
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)

Tactic:
conv_lhs => unfold bitwise

Result:
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)

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

Tactic:
simp [add_mul_div_left]

Result:
no goals

Proof state:
f : Bool → Bool → Bool
h : autoParam (f false false = false) _auto✝
a : Bool
m : ℕ
b : Bool
n : ℕ
h4 : ∀ (x : ℕ), (x + x + 1) / 2 = x
⊢ (if (if a = true then 2 * m + 1 else 2 * m) = 0 then
      if f false true = true then if b = true then 2 * n + 1 else 2 * n else 0
    else
      if (if b = true then 2 * n + 1 else 2 * n) = 0 then
        if f true false = true then if a = true then 2 * m + 1 else 2 * m else 0
      else
        if
            f (decide ((if a = true then 2 * m + 1 else 2 * m) % 2 = 1))
                (decide ((if b = true then 2 * n + 1 else 2 * n) % 2 = 1)) =
              true then
          bitwise f ((if a = true then 2 * m + 1 else 2 * m) / 2) ((if b = true then 2 * n + 1 else 2 * n) / 2) +
              bitwise f ((if a = true then 2 * m + 1 else 2 * m) / 2) ((if b = true then 2 * n + 1 else 2 * n) / 2) +
            1
        else
          bitwise f ((if a = true then 2 * m + 1 else 2 * m) / 2) ((if b = true then 2 * n + 1 else 2 * n) / 2) +
            bitwise f ((if a = true then 2 * m + 1 else 2 * m) / 2) ((if b = true then 2 * n + 1 else 2 * n) / 2)) =
    if f a b = true then 2 * bitwise f m n + 1 else 2 * bitwise f m n

Tactic:
cases a <;> cases b <;> simp [h4] <;> split_ifs
  <;> simp_all +decide [two_mul]

Result:
no goals