l3lab/ntp-mathlib huggingface dataset:
@[simp 1100]
theorem singleton_unop_op (x : αᵒᵖ) : ({unop x} : Set α).op = {x} := by
  ext
  

Proof state:
case h
α : Type u_1
x x✝ : αᵒᵖ
⊢ x✝ ∈ Set.op {x.unop} ↔ x✝ ∈ {x}

Next tactic:
constructor
@[simp 1100]
theorem singleton_unop_op (x : αᵒᵖ) : ({unop x} : Set α).op = {x} := by
  ext
  constructor
  · 

Proof state:
case h.mp
α : Type u_1
x x✝ : αᵒᵖ
⊢ x✝ ∈ Set.op {x.unop} → x✝ ∈ {x}

Next tactic:
apply unop_injective
@[simp 1100]
theorem singleton_unop_op (x : αᵒᵖ) : ({unop x} : Set α).op = {x} := by
  ext
  constructor
  · apply unop_injective
  · 

Proof state:
case h.mpr
α : Type u_1
x x✝ : αᵒᵖ
⊢ x✝ ∈ {x} → x✝ ∈ Set.op {x.unop}

Next tactic:
apply op_injective
@[simp]
theorem bodd_succ (n : ℕ) : bodd (succ n) = not (bodd n) := by
  

Proof state:
n : ℕ
⊢ bodd (succ n) = !bodd n

Next tactic:
simp only [bodd, boddDiv2]
@[simp]
theorem bodd_succ (n : ℕ) : bodd (succ n) = not (bodd n) := by
  simp only [bodd, boddDiv2]
  

Proof state:
n : ℕ
⊢ (match boddDiv2 n with
      | (false, m) => (true, m)
      | (true, m) => (false, succ m)).fst =
    !(boddDiv2 n).fst

Next tactic:
let ⟨b,m⟩ := boddDiv2 n
@[simp]
theorem bodd_succ (n : ℕ) : bodd (succ n) = not (bodd n) := by
  simp only [bodd, boddDiv2]
  let ⟨b,m⟩ := boddDiv2 n
  

Proof state:
n : ℕ
b : Bool
m : ℕ
⊢ (match (b, m) with
      | (false, m) => (true, m)
      | (true, m) => (false, succ m)).fst =
    !(b, m).fst

Next tactic:
cases b
@[simp]
theorem bodd_succ (n : ℕ) : bodd (succ n) = not (bodd n) := by
  simp only [bodd, boddDiv2]
  let ⟨b,m⟩ := boddDiv2 n
  cases b <;> 

Proof state:
case false
n m : ℕ
⊢ (match (false, m) with
      | (false, m) => (true, m)
      | (true, m) => (false, succ m)).fst =
    !(false, m).fst

Next tactic:
rfl
@[simp]
theorem bodd_succ (n : ℕ) : bodd (succ n) = not (bodd n) := by
  simp only [bodd, boddDiv2]
  let ⟨b,m⟩ := boddDiv2 n
  cases b <;> 

Proof state:
case true
n m : ℕ
⊢ (match (true, m) with
      | (false, m) => (true, m)
      | (true, m) => (false, succ m)).fst =
    !(true, m).fst

Next tactic:
rfl
@[simp]
theorem bodd_add (m n : ℕ) : bodd (m + n) = bxor (bodd m) (bodd n) := by
  

Proof state:
m n : ℕ
⊢ bodd (m + n) = bxor (bodd m) (bodd n)

Next tactic:
induction n
@[simp]
theorem bodd_add (m n : ℕ) : bodd (m + n) = bxor (bodd m) (bodd n) := by
  induction n <;> 

Proof state:
case zero
m : ℕ
⊢ bodd (m + zero) = bxor (bodd m) (bodd zero)

Next tactic:
simp_all [add_succ, Bool.xor_not]
@[simp]
theorem bodd_add (m n : ℕ) : bodd (m + n) = bxor (bodd m) (bodd n) := by
  induction n <;> 

Proof state:
case succ
m n✝ : ℕ
n_ih✝ : bodd (m + n✝) = bxor (bodd m) (bodd n✝)
⊢ bodd (m + succ n✝) = bxor (bodd m) (bodd (succ n✝))

Next tactic:
simp_all [add_succ, Bool.xor_not]
@[simp]
theorem bodd_mul (m n : ℕ) : bodd (m * n) = (bodd m && bodd n) := by
  

Proof state:
m n : ℕ
⊢ bodd (m * n) = (bodd m && bodd n)

Next tactic:
induction' n with n IH
@[simp]
theorem bodd_mul (m n : ℕ) : bodd (m * n) = (bodd m && bodd n) := by
  induction' n with n IH
  · 

Proof state:
case zero
m : ℕ
⊢ bodd (m * zero) = (bodd m && bodd zero)

Next tactic:
simp
@[simp]
theorem bodd_mul (m n : ℕ) : bodd (m * n) = (bodd m && bodd n) := by
  induction' n with n IH
  · simp
  · 

Proof state:
case succ
m n : ℕ
IH : bodd (m * n) = (bodd m && bodd n)
⊢ bodd (m * succ n) = (bodd m && bodd (succ n))

Next tactic:
simp [mul_succ, IH]
@[simp]
theorem bodd_mul (m n : ℕ) : bodd (m * n) = (bodd m && bodd n) := by
  induction' n with n IH
  · simp
  · simp [mul_succ, IH]
    

Proof state:
case succ
m n : ℕ
IH : bodd (m * n) = (bodd m && bodd n)
⊢ bxor (bodd m && bodd n) (bodd m) = (bodd m && !bodd n)

Next tactic:
cases bodd m
@[simp]
theorem bodd_mul (m n : ℕ) : bodd (m * n) = (bodd m && bodd n) := by
  induction' n with n IH
  · simp
  · simp [mul_succ, IH]
    cases bodd m <;> 

Proof state:
case succ.false
m n : ℕ
IH : bodd (m * n) = (bodd m && bodd n)
⊢ bxor (false && bodd n) false = (false && !bodd n)

Next tactic:
cases bodd n
@[simp]
theorem bodd_mul (m n : ℕ) : bodd (m * n) = (bodd m && bodd n) := by
  induction' n with n IH
  · simp
  · simp [mul_succ, IH]
    cases bodd m <;> 

Proof state:
case succ.true
m n : ℕ
IH : bodd (m * n) = (bodd m && bodd n)
⊢ bxor (true && bodd n) true = (true && !bodd n)

Next tactic:
cases bodd n
@[simp]
theorem bodd_mul (m n : ℕ) : bodd (m * n) = (bodd m && bodd n) := by
  induction' n with n IH
  · simp
  · simp [mul_succ, IH]
    cases bodd m <;> cases bodd n <;> 

Proof state:
case succ.false.false
m n : ℕ
IH : bodd (m * n) = (bodd m && bodd n)
⊢ bxor (false && false) false = (false && !false)

Next tactic:
rfl
@[simp]
theorem bodd_mul (m n : ℕ) : bodd (m * n) = (bodd m && bodd n) := by
  induction' n with n IH
  · simp
  · simp [mul_succ, IH]
    cases bodd m <;> cases bodd n <;> 

Proof state:
case succ.false.true
m n : ℕ
IH : bodd (m * n) = (bodd m && bodd n)
⊢ bxor (false && true) false = (false && !true)

Next tactic:
rfl
@[simp]
theorem bodd_mul (m n : ℕ) : bodd (m * n) = (bodd m && bodd n) := by
  induction' n with n IH
  · simp
  · simp [mul_succ, IH]
    cases bodd m <;> cases bodd n <;> 

Proof state:
case succ.true.false
m n : ℕ
IH : bodd (m * n) = (bodd m && bodd n)
⊢ bxor (true && false) true = (true && !false)

Next tactic:
rfl
@[simp]
theorem bodd_mul (m n : ℕ) : bodd (m * n) = (bodd m && bodd n) := by
  induction' n with n IH
  · simp
  · simp [mul_succ, IH]
    cases bodd m <;> cases bodd n <;> 

Proof state:
case succ.true.true
m n : ℕ
IH : bodd (m * n) = (bodd m && bodd n)
⊢ bxor (true && true) true = (true && !true)

Next tactic:
rfl
theorem mod_two_of_bodd (n : ℕ) : n % 2 = cond (bodd n) 1 0 := by
  

Proof state:
n : ℕ
⊢ n % 2 = bif bodd n then 1 else 0

Next tactic:
have := congr_arg bodd (mod_add_div n 2)
theorem mod_two_of_bodd (n : ℕ) : n % 2 = cond (bodd n) 1 0 := by
  have := congr_arg bodd (mod_add_div n 2)
  

Proof state:
n : ℕ
this : bodd (n % 2 + 2 * (n / 2)) = bodd n
⊢ n % 2 = bif bodd n then 1 else 0

Next tactic:
simp? [not]  at this
       says simp only [bodd_add, bodd_mul, bodd_succ, not, bodd_zero, Bool.false_and,
      Bool.xor_false] at this
theorem mod_two_of_bodd (n : ℕ) : n % 2 = cond (bodd n) 1 0 := by
  have := congr_arg bodd (mod_add_div n 2)
  simp? [not]  at this
       says 

Proof state:
n : ℕ
this : bodd (n % 2 + 2 * (n / 2)) = bodd n
⊢ n % 2 = bif bodd n then 1 else 0

Next tactic:
simp only [bodd_add, bodd_mul, bodd_succ, not, bodd_zero, Bool.false_and,
      Bool.xor_false] at this
theorem mod_two_of_bodd (n : ℕ) : n % 2 = cond (bodd n) 1 0 := by
  have := congr_arg bodd (mod_add_div n 2)
  simp? [not]  at this
       says simp only [bodd_add, bodd_mul, bodd_succ, not, bodd_zero, Bool.false_and,
      Bool.xor_false] at this
  

Proof state:
n : ℕ
this : bodd (n % 2) = bodd n
⊢ n % 2 = bif bodd n then 1 else 0

Next tactic:
have _ : ∀ b, and false b = false := by
    intro b
    cases b <;> rfl
theorem mod_two_of_bodd (n : ℕ) : n % 2 = cond (bodd n) 1 0 := by
  have := congr_arg bodd (mod_add_div n 2)
  simp? [not]  at this
       says simp only [bodd_add, bodd_mul, bodd_succ, not, bodd_zero, Bool.false_and,
      Bool.xor_false] at this
  have _ : ∀ b, and false b = false := by
    

Proof state:
n : ℕ
this : bodd (n % 2) = bodd n
⊢ ∀ (b : Bool), (false && b) = false

Next tactic:
intro b
theorem mod_two_of_bodd (n : ℕ) : n % 2 = cond (bodd n) 1 0 := by
  have := congr_arg bodd (mod_add_div n 2)
  simp? [not]  at this
       says simp only [bodd_add, bodd_mul, bodd_succ, not, bodd_zero, Bool.false_and,
      Bool.xor_false] at this
  have _ : ∀ b, and false b = false := by
    intro b
    

Proof state:
n : ℕ
this : bodd (n % 2) = bodd n
b : Bool
⊢ (false && b) = false

Next tactic:
cases b
theorem mod_two_of_bodd (n : ℕ) : n % 2 = cond (bodd n) 1 0 := by
  have := congr_arg bodd (mod_add_div n 2)
  simp? [not]  at this
       says simp only [bodd_add, bodd_mul, bodd_succ, not, bodd_zero, Bool.false_and,
      Bool.xor_false] at this
  have _ : ∀ b, and false b = false := by
    intro b
    cases b <;> 

Proof state:
case false
n : ℕ
this : bodd (n % 2) = bodd n
⊢ (false && false) = false

Next tactic:
rfl
theorem mod_two_of_bodd (n : ℕ) : n % 2 = cond (bodd n) 1 0 := by
  have := congr_arg bodd (mod_add_div n 2)
  simp? [not]  at this
       says simp only [bodd_add, bodd_mul, bodd_succ, not, bodd_zero, Bool.false_and,
      Bool.xor_false] at this
  have _ : ∀ b, and false b = false := by
    intro b
    cases b <;> 

Proof state:
case true
n : ℕ
this : bodd (n % 2) = bodd n
⊢ (false && true) = false

Next tactic:
rfl
theorem mod_two_of_bodd (n : ℕ) : n % 2 = cond (bodd n) 1 0 := by
  have := congr_arg bodd (mod_add_div n 2)
  simp? [not]  at this
       says simp only [bodd_add, bodd_mul, bodd_succ, not, bodd_zero, Bool.false_and,
      Bool.xor_false] at this
  have _ : ∀ b, and false b = false := by
    intro b
    cases b <;> rfl
  

Proof state:
n : ℕ
this : bodd (n % 2) = bodd n
x✝ : ∀ (b : Bool), (false && b) = false
⊢ n % 2 = bif bodd n then 1 else 0

Next tactic:
have _ : ∀ b, bxor b false = b := by
    intro b
    cases b <;> rfl
theorem mod_two_of_bodd (n : ℕ) : n % 2 = cond (bodd n) 1 0 := by
  have := congr_arg bodd (mod_add_div n 2)
  simp? [not]  at this
       says simp only [bodd_add, bodd_mul, bodd_succ, not, bodd_zero, Bool.false_and,
      Bool.xor_false] at this
  have _ : ∀ b, and false b = false := by
    intro b
    cases b <;> rfl
  have _ : ∀ b, bxor b false = b := by
    

Proof state:
n : ℕ
this : bodd (n % 2) = bodd n
x✝ : ∀ (b : Bool), (false && b) = false
⊢ ∀ (b : Bool), bxor b false = b

Next tactic:
intro b
theorem mod_two_of_bodd (n : ℕ) : n % 2 = cond (bodd n) 1 0 := by
  have := congr_arg bodd (mod_add_div n 2)
  simp? [not]  at this
       says simp only [bodd_add, bodd_mul, bodd_succ, not, bodd_zero, Bool.false_and,
      Bool.xor_false] at this
  have _ : ∀ b, and false b = false := by
    intro b
    cases b <;> rfl
  have _ : ∀ b, bxor b false = b := by
    intro b
    

Proof state:
n : ℕ
this : bodd (n % 2) = bodd n
x✝ : ∀ (b : Bool), (false && b) = false
b : Bool
⊢ bxor b false = b

Next tactic:
cases b
theorem mod_two_of_bodd (n : ℕ) : n % 2 = cond (bodd n) 1 0 := by
  have := congr_arg bodd (mod_add_div n 2)
  simp? [not]  at this
       says simp only [bodd_add, bodd_mul, bodd_succ, not, bodd_zero, Bool.false_and,
      Bool.xor_false] at this
  have _ : ∀ b, and false b = false := by
    intro b
    cases b <;> rfl
  have _ : ∀ b, bxor b false = b := by
    intro b
    cases b <;> 

Proof state:
case false
n : ℕ
this : bodd (n % 2) = bodd n
x✝ : ∀ (b : Bool), (false && b) = false
⊢ bxor false false = false

Next tactic:
rfl
theorem mod_two_of_bodd (n : ℕ) : n % 2 = cond (bodd n) 1 0 := by
  have := congr_arg bodd (mod_add_div n 2)
  simp? [not]  at this
       says simp only [bodd_add, bodd_mul, bodd_succ, not, bodd_zero, Bool.false_and,
      Bool.xor_false] at this
  have _ : ∀ b, and false b = false := by
    intro b
    cases b <;> rfl
  have _ : ∀ b, bxor b false = b := by
    intro b
    cases b <;> 

Proof state:
case true
n : ℕ
this : bodd (n % 2) = bodd n
x✝ : ∀ (b : Bool), (false && b) = false
⊢ bxor true false = true

Next tactic:
rfl
theorem mod_two_of_bodd (n : ℕ) : n % 2 = cond (bodd n) 1 0 := by
  have := congr_arg bodd (mod_add_div n 2)
  simp? [not]  at this
       says simp only [bodd_add, bodd_mul, bodd_succ, not, bodd_zero, Bool.false_and,
      Bool.xor_false] at this
  have _ : ∀ b, and false b = false := by
    intro b
    cases b <;> rfl
  have _ : ∀ b, bxor b false = b := by
    intro b
    cases b <;> rfl
  

Proof state:
n : ℕ
this : bodd (n % 2) = bodd n
x✝¹ : ∀ (b : Bool), (false && b) = false
x✝ : ∀ (b : Bool), bxor b false = b
⊢ n % 2 = bif bodd n then 1 else 0

Next tactic:
rw [← this]
theorem mod_two_of_bodd (n : ℕ) : n % 2 = cond (bodd n) 1 0 := by
  have := congr_arg bodd (mod_add_div n 2)
  simp? [not]  at this
       says simp only [bodd_add, bodd_mul, bodd_succ, not, bodd_zero, Bool.false_and,
      Bool.xor_false] at this
  have _ : ∀ b, and false b = false := by
    intro b
    cases b <;> rfl
  have _ : ∀ b, bxor b false = b := by
    intro b
    cases b <;> rfl
  rw [← this]
  

Proof state:
n : ℕ
this : bodd (n % 2) = bodd n
x✝¹ : ∀ (b : Bool), (false && b) = false
x✝ : ∀ (b : Bool), bxor b false = b
⊢ n % 2 = bif bodd (n % 2) then 1 else 0

Next tactic:
cases' mod_two_eq_zero_or_one n with h h
theorem mod_two_of_bodd (n : ℕ) : n % 2 = cond (bodd n) 1 0 := by
  have := congr_arg bodd (mod_add_div n 2)
  simp? [not]  at this
       says simp only [bodd_add, bodd_mul, bodd_succ, not, bodd_zero, Bool.false_and,
      Bool.xor_false] at this
  have _ : ∀ b, and false b = false := by
    intro b
    cases b <;> rfl
  have _ : ∀ b, bxor b false = b := by
    intro b
    cases b <;> rfl
  rw [← this]
  cases' mod_two_eq_zero_or_one n with h h <;> 

Proof state:
case inl
n : ℕ
this : bodd (n % 2) = bodd n
x✝¹ : ∀ (b : Bool), (false && b) = false
x✝ : ∀ (b : Bool), bxor b false = b
h : n % 2 = 0
⊢ n % 2 = bif bodd (n % 2) then 1 else 0

Next tactic:
rw [h]
theorem mod_two_of_bodd (n : ℕ) : n % 2 = cond (bodd n) 1 0 := by
  have := congr_arg bodd (mod_add_div n 2)
  simp? [not]  at this
       says simp only [bodd_add, bodd_mul, bodd_succ, not, bodd_zero, Bool.false_and,
      Bool.xor_false] at this
  have _ : ∀ b, and false b = false := by
    intro b
    cases b <;> rfl
  have _ : ∀ b, bxor b false = b := by
    intro b
    cases b <;> rfl
  rw [← this]
  cases' mod_two_eq_zero_or_one n with h h <;> 

Proof state:
case inr
n : ℕ
this : bodd (n % 2) = bodd n
x✝¹ : ∀ (b : Bool), (false && b) = false
x✝ : ∀ (b : Bool), bxor b false = b
h : n % 2 = 1
⊢ n % 2 = bif bodd (n % 2) then 1 else 0

Next tactic:
rw [h]
theorem mod_two_of_bodd (n : ℕ) : n % 2 = cond (bodd n) 1 0 := by
  have := congr_arg bodd (mod_add_div n 2)
  simp? [not]  at this
       says simp only [bodd_add, bodd_mul, bodd_succ, not, bodd_zero, Bool.false_and,
      Bool.xor_false] at this
  have _ : ∀ b, and false b = false := by
    intro b
    cases b <;> rfl
  have _ : ∀ b, bxor b false = b := by
    intro b
    cases b <;> rfl
  rw [← this]
  cases' mod_two_eq_zero_or_one n with h h <;> rw [h] <;> 

Proof state:
case inl
n : ℕ
this : bodd (n % 2) = bodd n
x✝¹ : ∀ (b : Bool), (false && b) = false
x✝ : ∀ (b : Bool), bxor b false = b
h : n % 2 = 0
⊢ 0 = bif bodd 0 then 1 else 0

Next tactic:
rfl
theorem mod_two_of_bodd (n : ℕ) : n % 2 = cond (bodd n) 1 0 := by
  have := congr_arg bodd (mod_add_div n 2)
  simp? [not]  at this
       says simp only [bodd_add, bodd_mul, bodd_succ, not, bodd_zero, Bool.false_and,
      Bool.xor_false] at this
  have _ : ∀ b, and false b = false := by
    intro b
    cases b <;> rfl
  have _ : ∀ b, bxor b false = b := by
    intro b
    cases b <;> rfl
  rw [← this]
  cases' mod_two_eq_zero_or_one n with h h <;> rw [h] <;> 

Proof state:
case inr
n : ℕ
this : bodd (n % 2) = bodd n
x✝¹ : ∀ (b : Bool), (false && b) = false
x✝ : ∀ (b : Bool), bxor b false = b
h : n % 2 = 1
⊢ 1 = bif bodd 1 then 1 else 0

Next tactic:
rfl
@[simp]
theorem div2_succ (n : ℕ) : div2 (succ n) = cond (bodd n) (succ (div2 n)) (div2 n) := by
  

Proof state:
n : ℕ
⊢ div2 (succ n) = bif bodd n then succ (div2 n) else div2 n

Next tactic:
simp only [bodd, boddDiv2, div2]
@[simp]
theorem div2_succ (n : ℕ) : div2 (succ n) = cond (bodd n) (succ (div2 n)) (div2 n) := by
  simp only [bodd, boddDiv2, div2]
  

Proof state:
n : ℕ
⊢ (match boddDiv2 n with
      | (false, m) => (true, m)
      | (true, m) => (false, succ m)).snd =
    bif (boddDiv2 n).fst then succ (boddDiv2 n).snd else (boddDiv2 n).snd

Next tactic:
cases' boddDiv2 n with fst snd
@[simp]
theorem div2_succ (n : ℕ) : div2 (succ n) = cond (bodd n) (succ (div2 n)) (div2 n) := by
  simp only [bodd, boddDiv2, div2]
  cases' boddDiv2 n with fst snd
  

Proof state:
case mk
n : ℕ
fst : Bool
snd : ℕ
⊢ (match (fst, snd) with
      | (false, m) => (true, m)
      | (true, m) => (false, succ m)).snd =
    bif (fst, snd).fst then succ (fst, snd).snd else (fst, snd).snd

Next tactic:
cases fst
@[simp]
theorem div2_succ (n : ℕ) : div2 (succ n) = cond (bodd n) (succ (div2 n)) (div2 n) := by
  simp only [bodd, boddDiv2, div2]
  cases' boddDiv2 n with fst snd
  cases fst
  

Proof state:
case mk.false
n snd : ℕ
⊢ (match (false, snd) with
      | (false, m) => (true, m)
      | (true, m) => (false, succ m)).snd =
    bif (false, snd).fst then succ (false, snd).snd else (false, snd).snd
case mk.true
n snd : ℕ
⊢ (match (true, snd) with
      | (false, m) => (true, m)
      | (true, m) => (false, succ m)).snd =
    bif (true, snd).fst then succ (true, snd).snd else (true, snd).snd

Next tactic:
case mk.false =>
    simp
@[simp]
theorem div2_succ (n : ℕ) : div2 (succ n) = cond (bodd n) (succ (div2 n)) (div2 n) := by
  simp only [bodd, boddDiv2, div2]
  cases' boddDiv2 n with fst snd
  cases fst
  

Proof state:
n snd : ℕ
⊢ (match (false, snd) with
      | (false, m) => (true, m)
      | (true, m) => (false, succ m)).snd =
    bif (false, snd).fst then succ (false, snd).snd else (false, snd).snd

Next tactic:
case mk.false =>
    simp
@[simp]
theorem div2_succ (n : ℕ) : div2 (succ n) = cond (bodd n) (succ (div2 n)) (div2 n) := by
  simp only [bodd, boddDiv2, div2]
  cases' boddDiv2 n with fst snd
  cases fst
  case mk.false =>
    

Proof state:
n snd : ℕ
⊢ (match (false, snd) with
      | (false, m) => (true, m)
      | (true, m) => (false, succ m)).snd =
    bif (false, snd).fst then succ (false, snd).snd else (false, snd).snd

Next tactic:
simp
@[simp]
theorem div2_succ (n : ℕ) : div2 (succ n) = cond (bodd n) (succ (div2 n)) (div2 n) := by
  simp only [bodd, boddDiv2, div2]
  cases' boddDiv2 n with fst snd
  cases fst
  case mk.false =>
    simp
  

Proof state:
case mk.true
n snd : ℕ
⊢ (match (true, snd) with
      | (false, m) => (true, m)
      | (true, m) => (false, succ m)).snd =
    bif (true, snd).fst then succ (true, snd).snd else (true, snd).snd

Next tactic:
case mk.true =>
    simp
@[simp]
theorem div2_succ (n : ℕ) : div2 (succ n) = cond (bodd n) (succ (div2 n)) (div2 n) := by
  simp only [bodd, boddDiv2, div2]
  cases' boddDiv2 n with fst snd
  cases fst
  case mk.false =>
    simp
  

Proof state:
n snd : ℕ
⊢ (match (true, snd) with
      | (false, m) => (true, m)
      | (true, m) => (false, succ m)).snd =
    bif (true, snd).fst then succ (true, snd).snd else (true, snd).snd

Next tactic:
case mk.true =>
    simp
@[simp]
theorem div2_succ (n : ℕ) : div2 (succ n) = cond (bodd n) (succ (div2 n)) (div2 n) := by
  simp only [bodd, boddDiv2, div2]
  cases' boddDiv2 n with fst snd
  cases fst
  case mk.false =>
    simp
  case mk.true =>
    

Proof state:
n snd : ℕ
⊢ (match (true, snd) with
      | (false, m) => (true, m)
      | (true, m) => (false, succ m)).snd =
    bif (true, snd).fst then succ (true, snd).snd else (true, snd).snd

Next tactic:
simp
theorem bodd_add_div2 : ∀ n, cond (bodd n) 1 0 + 2 * div2 n = n
  | 0 => rfl
  | succ n => by
    

Proof state:
n : ℕ
⊢ (bif bodd (succ n) then 1 else 0) + 2 * div2 (succ n) = succ n

Next tactic:
simp only [bodd_succ, Bool.cond_not, div2_succ, Nat.mul_comm]
theorem bodd_add_div2 : ∀ n, cond (bodd n) 1 0 + 2 * div2 n = n
  | 0 => rfl
  | succ n => by
    simp only [bodd_succ, Bool.cond_not, div2_succ, Nat.mul_comm]
    

Proof state:
n : ℕ
⊢ (bif bodd n then 0 else 1) + (bif bodd n then succ (div2 n) else div2 n) * 2 = succ n

Next tactic:
refine' Eq.trans _ (congr_arg succ (bodd_add_div2 n))
theorem bodd_add_div2 : ∀ n, cond (bodd n) 1 0 + 2 * div2 n = n
  | 0 => rfl
  | succ n => by
    simp only [bodd_succ, Bool.cond_not, div2_succ, Nat.mul_comm]
    refine' Eq.trans _ (congr_arg succ (bodd_add_div2 n))
    

Proof state:
n : ℕ
⊢ (bif bodd n then 0 else 1) + (bif bodd n then succ (div2 n) else div2 n) * 2 =
    succ ((bif bodd n then 1 else 0) + 2 * div2 n)

Next tactic:
cases bodd n
theorem bodd_add_div2 : ∀ n, cond (bodd n) 1 0 + 2 * div2 n = n
  | 0 => rfl
  | succ n => by
    simp only [bodd_succ, Bool.cond_not, div2_succ, Nat.mul_comm]
    refine' Eq.trans _ (congr_arg succ (bodd_add_div2 n))
    cases bodd n <;> 

Proof state:
case false
n : ℕ
⊢ (bif false then 0 else 1) + (bif false then succ (div2 n) else div2 n) * 2 =
    succ ((bif false then 1 else 0) + 2 * div2 n)

Next tactic:
simp [cond, not]
theorem bodd_add_div2 : ∀ n, cond (bodd n) 1 0 + 2 * div2 n = n
  | 0 => rfl
  | succ n => by
    simp only [bodd_succ, Bool.cond_not, div2_succ, Nat.mul_comm]
    refine' Eq.trans _ (congr_arg succ (bodd_add_div2 n))
    cases bodd n <;> 

Proof state:
case true
n : ℕ
⊢ (bif true then 0 else 1) + (bif true then succ (div2 n) else div2 n) * 2 =
    succ ((bif true then 1 else 0) + 2 * div2 n)

Next tactic:
simp [cond, not]
theorem bodd_add_div2 : ∀ n, cond (bodd n) 1 0 + 2 * div2 n = n
  | 0 => rfl
  | succ n => by
    simp only [bodd_succ, Bool.cond_not, div2_succ, Nat.mul_comm]
    refine' Eq.trans _ (congr_arg succ (bodd_add_div2 n))
    cases bodd n <;> simp [cond, not]
    · 

Proof state:
case false
n : ℕ
⊢ 1 + div2 n * 2 = succ (div2 n * 2)

Next tactic:
rw [Nat.add_comm, Nat.add_succ]
theorem bodd_add_div2 : ∀ n, cond (bodd n) 1 0 + 2 * div2 n = n
  | 0 => rfl
  | succ n => by
    simp only [bodd_succ, Bool.cond_not, div2_succ, Nat.mul_comm]
    refine' Eq.trans _ (congr_arg succ (bodd_add_div2 n))
    cases bodd n <;> simp [cond, not]
    · rw [Nat.add_comm, Nat.add_succ]
    · 

Proof state:
case true
n : ℕ
⊢ succ (div2 n) * 2 = succ (1 + div2 n * 2)

Next tactic:
rw [succ_mul, Nat.add_comm 1, Nat.add_succ]
theorem div2_val (n) : div2 n = n / 2 := by
  

Proof state:
n : ℕ
⊢ div2 n = n / 2

Next tactic:
refine'
    Nat.eq_of_mul_eq_mul_left (by decide)
      (Nat.add_left_cancel (Eq.trans _ (Nat.mod_add_div n 2).symm))
theorem div2_val (n) : div2 n = n / 2 := by
  refine'
    Nat.eq_of_mul_eq_mul_left (by 

Proof state:
n : ℕ
⊢ 0 < 2

Next tactic:
decide
theorem div2_val (n) : div2 n = n / 2 := by
  refine'
    Nat.eq_of_mul_eq_mul_left (by decide)
      (Nat.add_left_cancel (Eq.trans _ (Nat.mod_add_div n 2).symm))
  

Proof state:
n : ℕ
⊢ n % 2 + 2 * div2 n = n

Next tactic:
rw [mod_two_of_bodd, bodd_add_div2]
theorem bit0_val (n : Nat) : bit0 n = 2 * n :=
  calc
    n + n = 0 + n + n := by 

Proof state:
n : ℕ
⊢ n + n = 0 + n + n

Next tactic:
rw [Nat.zero_add]
theorem bit_val (b n) : bit b n = 2 * n + cond b 1 0 := by
  

Proof state:
b : Bool
n : ℕ
⊢ bit b n = 2 * n + bif b then 1 else 0

Next tactic:
cases b
theorem bit_val (b n) : bit b n = 2 * n + cond b 1 0 := by
  cases b
  

Proof state:
case false
n : ℕ
⊢ bit false n = 2 * n + bif false then 1 else 0
case true n : ℕ ⊢ bit true n = 2 * n + bif true then 1 else 0

Next tactic:
apply bit0_val
theorem bit_val (b n) : bit b n = 2 * n + cond b 1 0 := by
  cases b
  apply bit0_val
  

Proof state:
case true
n : ℕ
⊢ bit true n = 2 * n + bif true then 1 else 0

Next tactic:
apply bit1_val
@[simp]
theorem shiftLeft'_false : ∀ n, shiftLeft' false m n = m <<< n
  | 0 => rfl
  | n + 1 => by
    

Proof state:
m n : ℕ
⊢ shiftLeft' false m (n + 1) = m <<< (n + 1)

Next tactic:
have : 2 * (m * 2^n) = 2^(n+1)*m := by
      rw [Nat.mul_comm, Nat.mul_assoc, ← pow_succ]; simp
@[simp]
theorem shiftLeft'_false : ∀ n, shiftLeft' false m n = m <<< n
  | 0 => rfl
  | n + 1 => by
    have : 2 * (m * 2^n) = 2^(n+1)*m := by
      

Proof state:
m n : ℕ
⊢ 2 * (m * 2 ^ n) = 2 ^ (n + 1) * m

Next tactic:
rw [Nat.mul_comm, Nat.mul_assoc, ← pow_succ]
@[simp]
theorem shiftLeft'_false : ∀ n, shiftLeft' false m n = m <<< n
  | 0 => rfl
  | n + 1 => by
    have : 2 * (m * 2^n) = 2^(n+1)*m := by
      rw [Nat.mul_comm, Nat.mul_assoc, ← pow_succ]; 

Proof state:
m n : ℕ
⊢ m * 2 ^ succ n = 2 ^ (n + 1) * m

Next tactic:
simp
@[simp]
theorem shiftLeft'_false : ∀ n, shiftLeft' false m n = m <<< n
  | 0 => rfl
  | n + 1 => by
    have : 2 * (m * 2^n) = 2^(n+1)*m := by
      rw [Nat.mul_comm, Nat.mul_assoc, ← pow_succ]; simp
    

Proof state:
m n : ℕ
this : 2 * (m * 2 ^ n) = 2 ^ (n + 1) * m
⊢ shiftLeft' false m (n + 1) = m <<< (n + 1)

Next tactic:
simp [shiftLeft_eq, shiftLeft', bit_val, shiftLeft'_false, this]
lemma binaryRec_decreasing (h : n ≠ 0) : div2 n < n := by
  

Proof state:
n : ℕ
h : n ≠ 0
⊢ div2 n < n

Next tactic:
rw [div2_val]
lemma binaryRec_decreasing (h : n ≠ 0) : div2 n < n := by
  rw [div2_val]
  

Proof state:
n : ℕ
h : n ≠ 0
⊢ n / 2 < n

Next tactic:
apply (div_lt_iff_lt_mul <| succ_pos 1).2