Theorem: Nat.bitwise_bit
File: Mathlib/Data/Nat/Bitwise.lean

tactic: conv_lhs => unfold bitwise
state_before: 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)
state_after: 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)

tactic: simp only [bit, ite_apply, bit1, bit0, Bool.cond_eq_ite]
state_before: 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)
state_after: f✝ f : Bool → Bool → Bool
h : autoParam (f false false = false) _auto✝
a : Bool
m : ℕ
b : Bool
n : ℕ
⊢ (if (if a = true then m + m + 1 else m + m) = 0 then
      if f false true = true then if b = true then n + n + 1 else n + n else 0
    else
      if (if b = true then n + n + 1 else n + n) = 0 then
        if f true false = true then if a = true then m + m + 1 else m + m else 0
      else
        if
            f (decide ((if a = true then m + m + 1 else m + m) % 2 = 1))
                (decide ((if b = true then n + n + 1 else n + n) % 2 = 1)) =
              true then
          bitwise f ((if a = true then m + m + 1 else m + m) / 2) ((if b = true then n + n + 1 else n + n) / 2) +
              bitwise f ((if a = true then m + m + 1 else m + m) / 2) ((if b = true then n + n + 1 else n + n) / 2) +
            1
        else
          bitwise f ((if a = true then m + m + 1 else m + m) / 2) ((if b = true then n + n + 1 else n + n) / 2) +
            bitwise f ((if a = true then m + m + 1 else m + m) / 2) ((if b = true then n + n + 1 else n + n) / 2)) =
    if f a b = true then bitwise f m n + bitwise f m n + 1 else bitwise f m n + bitwise f m n

tactic: have h1 x :     (x + x) % 2 = 0 := by rw [← two_mul, mul_comm]; apply mul_mod_left
state_before: f✝ f : Bool → Bool → Bool
h : autoParam (f false false = false) _auto✝
a : Bool
m : ℕ
b : Bool
n : ℕ
⊢ (if (if a = true then m + m + 1 else m + m) = 0 then
      if f false true = true then if b = true then n + n + 1 else n + n else 0
    else
      if (if b = true then n + n + 1 else n + n) = 0 then
        if f true false = true then if a = true then m + m + 1 else m + m else 0
      else
        if
            f (decide ((if a = true then m + m + 1 else m + m) % 2 = 1))
                (decide ((if b = true then n + n + 1 else n + n) % 2 = 1)) =
              true then
          bitwise f ((if a = true then m + m + 1 else m + m) / 2) ((if b = true then n + n + 1 else n + n) / 2) +
              bitwise f ((if a = true then m + m + 1 else m + m) / 2) ((if b = true then n + n + 1 else n + n) / 2) +
            1
        else
          bitwise f ((if a = true then m + m + 1 else m + m) / 2) ((if b = true then n + n + 1 else n + n) / 2) +
            bitwise f ((if a = true then m + m + 1 else m + m) / 2) ((if b = true then n + n + 1 else n + n) / 2)) =
    if f a b = true then bitwise f m n + bitwise f m n + 1 else bitwise f m n + bitwise f m n
state_after: 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 (if a = true then m + m + 1 else m + m) = 0 then
      if f false true = true then if b = true then n + n + 1 else n + n else 0
    else
      if (if b = true then n + n + 1 else n + n) = 0 then
        if f true false = true then if a = true then m + m + 1 else m + m else 0
      else
        if
            f (decide ((if a = true then m + m + 1 else m + m) % 2 = 1))
                (decide ((if b = true then n + n + 1 else n + n) % 2 = 1)) =
              true then
          bitwise f ((if a = true then m + m + 1 else m + m) / 2) ((if b = true then n + n + 1 else n + n) / 2) +
              bitwise f ((if a = true then m + m + 1 else m + m) / 2) ((if b = true then n + n + 1 else n + n) / 2) +
            1
        else
          bitwise f ((if a = true then m + m + 1 else m + m) / 2) ((if b = true then n + n + 1 else n + n) / 2) +
            bitwise f ((if a = true then m + m + 1 else m + m) / 2) ((if b = true then n + n + 1 else n + n) / 2)) =
    if f a b = true then bitwise f m n + bitwise f m n + 1 else bitwise f m n + bitwise f m n

tactic: have h2 x : (x + x + 1) % 2 = 1 := by rw [← two_mul, add_comm]; apply add_mul_mod_self_left
state_before: 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 (if a = true then m + m + 1 else m + m) = 0 then
      if f false true = true then if b = true then n + n + 1 else n + n else 0
    else
      if (if b = true then n + n + 1 else n + n) = 0 then
        if f true false = true then if a = true then m + m + 1 else m + m else 0
      else
        if
            f (decide ((if a = true then m + m + 1 else m + m) % 2 = 1))
                (decide ((if b = true then n + n + 1 else n + n) % 2 = 1)) =
              true then
          bitwise f ((if a = true then m + m + 1 else m + m) / 2) ((if b = true then n + n + 1 else n + n) / 2) +
              bitwise f ((if a = true then m + m + 1 else m + m) / 2) ((if b = true then n + n + 1 else n + n) / 2) +
            1
        else
          bitwise f ((if a = true then m + m + 1 else m + m) / 2) ((if b = true then n + n + 1 else n + n) / 2) +
            bitwise f ((if a = true then m + m + 1 else m + m) / 2) ((if b = true then n + n + 1 else n + n) / 2)) =
    if f a b = true then bitwise f m n + bitwise f m n + 1 else bitwise f m n + bitwise f m n
state_after: 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 (if a = true then m + m + 1 else m + m) = 0 then
      if f false true = true then if b = true then n + n + 1 else n + n else 0
    else
      if (if b = true then n + n + 1 else n + n) = 0 then
        if f true false = true then if a = true then m + m + 1 else m + m else 0
      else
        if
            f (decide ((if a = true then m + m + 1 else m + m) % 2 = 1))
                (decide ((if b = true then n + n + 1 else n + n) % 2 = 1)) =
              true then
          bitwise f ((if a = true then m + m + 1 else m + m) / 2) ((if b = true then n + n + 1 else n + n) / 2) +
              bitwise f ((if a = true then m + m + 1 else m + m) / 2) ((if b = true then n + n + 1 else n + n) / 2) +
            1
        else
          bitwise f ((if a = true then m + m + 1 else m + m) / 2) ((if b = true then n + n + 1 else n + n) / 2) +
            bitwise f ((if a = true then m + m + 1 else m + m) / 2) ((if b = true then n + n + 1 else n + n) / 2)) =
    if f a b = true then bitwise f m n + bitwise f m n + 1 else bitwise f m n + bitwise f m n

tactic: have h3 x :     (x + x) / 2 = x := by omega
state_before: 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 (if a = true then m + m + 1 else m + m) = 0 then
      if f false true = true then if b = true then n + n + 1 else n + n else 0
    else
      if (if b = true then n + n + 1 else n + n) = 0 then
        if f true false = true then if a = true then m + m + 1 else m + m else 0
      else
        if
            f (decide ((if a = true then m + m + 1 else m + m) % 2 = 1))
                (decide ((if b = true then n + n + 1 else n + n) % 2 = 1)) =
              true then
          bitwise f ((if a = true then m + m + 1 else m + m) / 2) ((if b = true then n + n + 1 else n + n) / 2) +
              bitwise f ((if a = true then m + m + 1 else m + m) / 2) ((if b = true then n + n + 1 else n + n) / 2) +
            1
        else
          bitwise f ((if a = true then m + m + 1 else m + m) / 2) ((if b = true then n + n + 1 else n + n) / 2) +
            bitwise f ((if a = true then m + m + 1 else m + m) / 2) ((if b = true then n + n + 1 else n + n) / 2)) =
    if f a b = true then bitwise f m n + bitwise f m n + 1 else bitwise f m n + bitwise f m n
state_after: 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 (if a = true then m + m + 1 else m + m) = 0 then
      if f false true = true then if b = true then n + n + 1 else n + n else 0
    else
      if (if b = true then n + n + 1 else n + n) = 0 then
        if f true false = true then if a = true then m + m + 1 else m + m else 0
      else
        if
            f (decide ((if a = true then m + m + 1 else m + m) % 2 = 1))
                (decide ((if b = true then n + n + 1 else n + n) % 2 = 1)) =
              true then
          bitwise f ((if a = true then m + m + 1 else m + m) / 2) ((if b = true then n + n + 1 else n + n) / 2) +
              bitwise f ((if a = true then m + m + 1 else m + m) / 2) ((if b = true then n + n + 1 else n + n) / 2) +
            1
        else
          bitwise f ((if a = true then m + m + 1 else m + m) / 2) ((if b = true then n + n + 1 else n + n) / 2) +
            bitwise f ((if a = true then m + m + 1 else m + m) / 2) ((if b = true then n + n + 1 else n + n) / 2)) =
    if f a b = true then bitwise f m n + bitwise f m n + 1 else bitwise f m n + bitwise f m n

tactic: have h4 x : (x + x + 1) / 2 = x := by rw [← two_mul, add_comm]; simp [add_mul_div_left]
state_before: 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 (if a = true then m + m + 1 else m + m) = 0 then
      if f false true = true then if b = true then n + n + 1 else n + n else 0
    else
      if (if b = true then n + n + 1 else n + n) = 0 then
        if f true false = true then if a = true then m + m + 1 else m + m else 0
      else
        if
            f (decide ((if a = true then m + m + 1 else m + m) % 2 = 1))
                (decide ((if b = true then n + n + 1 else n + n) % 2 = 1)) =
              true then
          bitwise f ((if a = true then m + m + 1 else m + m) / 2) ((if b = true then n + n + 1 else n + n) / 2) +
              bitwise f ((if a = true then m + m + 1 else m + m) / 2) ((if b = true then n + n + 1 else n + n) / 2) +
            1
        else
          bitwise f ((if a = true then m + m + 1 else m + m) / 2) ((if b = true then n + n + 1 else n + n) / 2) +
            bitwise f ((if a = true then m + m + 1 else m + m) / 2) ((if b = true then n + n + 1 else n + n) / 2)) =
    if f a b = true then bitwise f m n + bitwise f m n + 1 else bitwise f m n + bitwise f m n
state_after: 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 (if a = true then m + m + 1 else m + m) = 0 then
      if f false true = true then if b = true then n + n + 1 else n + n else 0
    else
      if (if b = true then n + n + 1 else n + n) = 0 then
        if f true false = true then if a = true then m + m + 1 else m + m else 0
      else
        if
            f (decide ((if a = true then m + m + 1 else m + m) % 2 = 1))
                (decide ((if b = true then n + n + 1 else n + n) % 2 = 1)) =
              true then
          bitwise f ((if a = true then m + m + 1 else m + m) / 2) ((if b = true then n + n + 1 else n + n) / 2) +
              bitwise f ((if a = true then m + m + 1 else m + m) / 2) ((if b = true then n + n + 1 else n + n) / 2) +
            1
        else
          bitwise f ((if a = true then m + m + 1 else m + m) / 2) ((if b = true then n + n + 1 else n + n) / 2) +
            bitwise f ((if a = true then m + m + 1 else m + m) / 2) ((if b = true then n + n + 1 else n + n) / 2)) =
    if f a b = true then bitwise f m n + bitwise f m n + 1 else bitwise f m n + bitwise f m n

tactic: cases a <;> cases b <;> simp [h1, h2, h3, h4] <;> split_ifs
  <;> simp_all (config := {decide := true})
state_before: 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 (if a = true then m + m + 1 else m + m) = 0 then
      if f false true = true then if b = true then n + n + 1 else n + n else 0
    else
      if (if b = true then n + n + 1 else n + n) = 0 then
        if f true false = true then if a = true then m + m + 1 else m + m else 0
      else
        if
            f (decide ((if a = true then m + m + 1 else m + m) % 2 = 1))
                (decide ((if b = true then n + n + 1 else n + n) % 2 = 1)) =
              true then
          bitwise f ((if a = true then m + m + 1 else m + m) / 2) ((if b = true then n + n + 1 else n + n) / 2) +
              bitwise f ((if a = true then m + m + 1 else m + m) / 2) ((if b = true then n + n + 1 else n + n) / 2) +
            1
        else
          bitwise f ((if a = true then m + m + 1 else m + m) / 2) ((if b = true then n + n + 1 else n + n) / 2) +
            bitwise f ((if a = true then m + m + 1 else m + m) / 2) ((if b = true then n + n + 1 else n + n) / 2)) =
    if f a b = true then bitwise f m n + bitwise f m n + 1 else bitwise f m n + bitwise f m n
state_after: no goals

tactic: rw [← two_mul, mul_comm]
state_before: f✝ f : Bool → Bool → Bool
h : autoParam (f false false = false) _auto✝
a : Bool
m : ℕ
b : Bool
n x : ℕ
⊢ (x + x) % 2 = 0
state_after: f✝ f : Bool → Bool → Bool
h : autoParam (f false false = false) _auto✝
a : Bool
m : ℕ
b : Bool
n x : ℕ
⊢ x * 2 % 2 = 0

tactic: apply mul_mod_left
state_before: f✝ f : Bool → Bool → Bool
h : autoParam (f false false = false) _auto✝
a : Bool
m : ℕ
b : Bool
n x : ℕ
⊢ x * 2 % 2 = 0
state_after: no goals

tactic: rw [← two_mul, add_comm]
state_before: 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
state_after: 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

tactic: apply add_mul_mod_self_left
state_before: 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
state_after: no goals

tactic: omega
state_before: 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
state_after: no goals

tactic: rw [← two_mul, add_comm]
state_before: 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
state_after: 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

tactic: simp [add_mul_div_left]
state_before: 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
state_after: no goals