l3lab/ntp-mathlib huggingface dataset:
@[simp]
theorem bit1_eq_one {n : ℕ} : bit1 n = 1 ↔ n = 0 :=
  ⟨@Nat.bit1_inj n 0, fun h => by subst h; 

Proof state:
n : ℕ
⊢ bit1 0 = 1

Next tactic:
rfl
@[simp]
theorem one_eq_bit1 {n : ℕ} : 1 = bit1 n ↔ n = 0 :=
  ⟨fun h => (@Nat.bit1_inj 0 n h).symm, fun h => by 

Proof state:
n✝ n : ℕ
h : n = 0
⊢ 1 = bit1 n

Next tactic:
subst h
@[simp]
theorem one_eq_bit1 {n : ℕ} : 1 = bit1 n ↔ n = 0 :=
  ⟨fun h => (@Nat.bit1_inj 0 n h).symm, fun h => by subst h; 

Proof state:
n : ℕ
⊢ 1 = bit1 0

Next tactic:
rfl
theorem bit_ne_zero (b) {n} (h : n ≠ 0) : bit b n ≠ 0 := by
  

Proof state:
n✝ : ℕ
b : Bool
n : ℕ
h : n ≠ 0
⊢ bit b n ≠ 0

Next tactic:
cases b <;> [exact Nat.bit0_ne_zero h; exact Nat.bit1_ne_zero _]
theorem bit_ne_zero (b) {n} (h : n ≠ 0) : bit b n ≠ 0 := by
  

Proof state:
n✝ : ℕ
b : Bool
n : ℕ
h : n ≠ 0
⊢ bit b n ≠ 0

Next tactic:
cases b
theorem bit_ne_zero (b) {n} (h : n ≠ 0) : bit b n ≠ 0 := by
  cases b <;> [

Proof state:
case false
n✝ n : ℕ
h : n ≠ 0
⊢ bit false n ≠ 0

Next tactic:
exact Nat.bit0_ne_zero h
theorem bit_ne_zero (b) {n} (h : n ≠ 0) : bit b n ≠ 0 := by
  cases b <;> [exact Nat.bit0_ne_zero h; 

Proof state:
case true
n✝ n : ℕ
h : n ≠ 0
⊢ bit true n ≠ 0

Next tactic:
exact Nat.bit1_ne_zero _
theorem bit0_mod_two : bit0 n % 2 = 0 := by
  

Proof state:
n : ℕ
⊢ bit0 n % 2 = 0

Next tactic:
rw [Nat.mod_two_of_bodd]
theorem bit0_mod_two : bit0 n % 2 = 0 := by
  rw [Nat.mod_two_of_bodd]
  

Proof state:
n : ℕ
⊢ (bif bodd (bit0 n) then 1 else 0) = 0

Next tactic:
simp
theorem bit1_mod_two : bit1 n % 2 = 1 := by
  

Proof state:
n : ℕ
⊢ bit1 n % 2 = 1

Next tactic:
rw [Nat.mod_two_of_bodd]
theorem bit1_mod_two : bit1 n % 2 = 1 := by
  rw [Nat.mod_two_of_bodd]
  

Proof state:
n : ℕ
⊢ (bif bodd (bit1 n) then 1 else 0) = 1

Next tactic:
simp
theorem pos_of_bit0_pos {n : ℕ} (h : 0 < bit0 n) : 0 < n := by
  

Proof state:
n✝ n : ℕ
h : 0 < bit0 n
⊢ 0 < n

Next tactic:
cases n
theorem pos_of_bit0_pos {n : ℕ} (h : 0 < bit0 n) : 0 < n := by
  cases n
  · 

Proof state:
case zero
n : ℕ
h : 0 < bit0 zero
⊢ 0 < zero

Next tactic:
cases h
theorem pos_of_bit0_pos {n : ℕ} (h : 0 < bit0 n) : 0 < n := by
  cases n
  · cases h
  · 

Proof state:
case succ
n n✝ : ℕ
h : 0 < bit0 (succ n✝)
⊢ 0 < succ n✝

Next tactic:
apply succ_pos
@[simp]
theorem bitCasesOn_bit {C : ℕ → Sort u} (H : ∀ b n, C (bit b n)) (b : Bool) (n : ℕ) :
    bitCasesOn (bit b n) H = H b n :=
  eq_of_heq <| (eq_rec_heq _ _).trans <| by 

Proof state:
n✝ : ℕ
C : ℕ → Sort u
H : (b : Bool) → (n : ℕ) → C (bit b n)
b : Bool
n : ℕ
⊢ HEq (H (bodd (bit b n)) (div2 (bit b n))) (H b n)

Next tactic:
rw [bodd_bit, div2_bit]
theorem bit_cases_on_injective {C : ℕ → Sort u} :
    Function.Injective fun H : ∀ b n, C (bit b n) => fun n => bitCasesOn n H := by
  

Proof state:
n : ℕ
C : ℕ → Sort u
⊢ Function.Injective fun H n => bitCasesOn n H

Next tactic:
intro H₁ H₂ h
theorem bit_cases_on_injective {C : ℕ → Sort u} :
    Function.Injective fun H : ∀ b n, C (bit b n) => fun n => bitCasesOn n H := by
  intro H₁ H₂ h
  

Proof state:
n : ℕ
C : ℕ → Sort u
H₁ H₂ : (b : Bool) → (n : ℕ) → C (bit b n)
h : (fun H n => bitCasesOn n H) H₁ = (fun H n => bitCasesOn n H) H₂
⊢ H₁ = H₂

Next tactic:
ext b n
theorem bit_cases_on_injective {C : ℕ → Sort u} :
    Function.Injective fun H : ∀ b n, C (bit b n) => fun n => bitCasesOn n H := by
  intro H₁ H₂ h
  ext b n
  

Proof state:
case h.h
n✝ : ℕ
C : ℕ → Sort u
H₁ H₂ : (b : Bool) → (n : ℕ) → C (bit b n)
h : (fun H n => bitCasesOn n H) H₁ = (fun H n => bitCasesOn n H) H₂
b : Bool
n : ℕ
⊢ H₁ b n = H₂ b n

Next tactic:
simpa only [bitCasesOn_bit] using congr_fun h (bit b n)
protected theorem bit0_eq_zero {n : ℕ} : bit0 n = 0 ↔ n = 0 :=
  ⟨Nat.eq_zero_of_add_eq_zero_left, fun h => by 

Proof state:
n✝ n : ℕ
h : n = 0
⊢ bit0 n = 0

Next tactic:
simp [h]
theorem bit_eq_zero_iff {n : ℕ} {b : Bool} : bit b n = 0 ↔ n = 0 ∧ b = false := by
  

Proof state:
n✝ n : ℕ
b : Bool
⊢ bit b n = 0 ↔ n = 0 ∧ b = false

Next tactic:
constructor
theorem bit_eq_zero_iff {n : ℕ} {b : Bool} : bit b n = 0 ↔ n = 0 ∧ b = false := by
  constructor
  · 

Proof state:
case mp
n✝ n : ℕ
b : Bool
⊢ bit b n = 0 → n = 0 ∧ b = false

Next tactic:
cases b
theorem bit_eq_zero_iff {n : ℕ} {b : Bool} : bit b n = 0 ↔ n = 0 ∧ b = false := by
  constructor
  · cases b <;> 

Proof state:
case mp.false
n✝ n : ℕ
⊢ bit false n = 0 → n = 0 ∧ false = false

Next tactic:
simp [Nat.bit, Nat.bit0_eq_zero, Nat.bit1_ne_zero]
theorem bit_eq_zero_iff {n : ℕ} {b : Bool} : bit b n = 0 ↔ n = 0 ∧ b = false := by
  constructor
  · cases b <;> 

Proof state:
case mp.true
n✝ n : ℕ
⊢ bit true n = 0 → n = 0 ∧ true = false

Next tactic:
simp [Nat.bit, Nat.bit0_eq_zero, Nat.bit1_ne_zero]
theorem bit_eq_zero_iff {n : ℕ} {b : Bool} : bit b n = 0 ↔ n = 0 ∧ b = false := by
  constructor
  · cases b <;> simp [Nat.bit, Nat.bit0_eq_zero, Nat.bit1_ne_zero]
  · 

Proof state:
case mpr
n✝ n : ℕ
b : Bool
⊢ n = 0 ∧ b = false → bit b n = 0

Next tactic:
rintro ⟨rfl, rfl⟩
theorem bit_eq_zero_iff {n : ℕ} {b : Bool} : bit b n = 0 ↔ n = 0 ∧ b = false := by
  constructor
  · cases b <;> simp [Nat.bit, Nat.bit0_eq_zero, Nat.bit1_ne_zero]
  · rintro ⟨rfl, rfl⟩
    

Proof state:
case mpr.intro
n : ℕ
⊢ bit false 0 = 0

Next tactic:
rfl
/--
The same as `binaryRec_eq`,
but that one unfortunately requires `f` to be the identity when appending `false` to `0`.
Here, we allow you to explicitly say that that case is not happening,
i.e. supplying `n = 0 → b = true`. -/
theorem binaryRec_eq' {C : ℕ → Sort*} {z : C 0} {f : ∀ b n, C n → C (bit b n)} (b n)
    (h : f false 0 z = z ∨ (n = 0 → b = true)) :
    binaryRec z f (bit b n) = f b n (binaryRec z f n) := by
  

Proof state:
n✝ : ℕ
C : ℕ → Sort u_1
z : C 0
f : (b : Bool) → (n : ℕ) → C n → C (bit b n)
b : Bool
n : ℕ
h : f false 0 z = z ∨ (n = 0 → b = true)
⊢ binaryRec z f (bit b n) = f b n (binaryRec z f n)

Next tactic:
rw [binaryRec]
/--
The same as `binaryRec_eq`,
but that one unfortunately requires `f` to be the identity when appending `false` to `0`.
Here, we allow you to explicitly say that that case is not happening,
i.e. supplying `n = 0 → b = true`. -/
theorem binaryRec_eq' {C : ℕ → Sort*} {z : C 0} {f : ∀ b n, C n → C (bit b n)} (b n)
    (h : f false 0 z = z ∨ (n = 0 → b = true)) :
    binaryRec z f (bit b n) = f b n (binaryRec z f n) := by
  rw [binaryRec]
  

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

Next tactic:
split_ifs with h'
/--
The same as `binaryRec_eq`,
but that one unfortunately requires `f` to be the identity when appending `false` to `0`.
Here, we allow you to explicitly say that that case is not happening,
i.e. supplying `n = 0 → b = true`. -/
theorem binaryRec_eq' {C : ℕ → Sort*} {z : C 0} {f : ∀ b n, C n → C (bit b n)} (b n)
    (h : f false 0 z = z ∨ (n = 0 → b = true)) :
    binaryRec z f (bit b n) = f b n (binaryRec z f n) := by
  rw [binaryRec]
  split_ifs with h'
  · 

Proof state:
case pos
n✝ : ℕ
C : ℕ → Sort u_1
z : C 0
f : (b : Bool) → (n : ℕ) → C n → C (bit b n)
b : Bool
n : ℕ
h : f false 0 z = z ∨ (n = 0 → b = true)
h' : bit b n = 0
⊢ Eq.mpr (_ : C (bit b n) = C 0) z = f b n (binaryRec z f n)

Next tactic:
rcases bit_eq_zero_iff.mp h' with ⟨rfl, rfl⟩
/--
The same as `binaryRec_eq`,
but that one unfortunately requires `f` to be the identity when appending `false` to `0`.
Here, we allow you to explicitly say that that case is not happening,
i.e. supplying `n = 0 → b = true`. -/
theorem binaryRec_eq' {C : ℕ → Sort*} {z : C 0} {f : ∀ b n, C n → C (bit b n)} (b n)
    (h : f false 0 z = z ∨ (n = 0 → b = true)) :
    binaryRec z f (bit b n) = f b n (binaryRec z f n) := by
  rw [binaryRec]
  split_ifs with h'
  · rcases bit_eq_zero_iff.mp h' with ⟨rfl, rfl⟩
    

Proof state:
case pos.intro
n : ℕ
C : ℕ → Sort u_1
z : C 0
f : (b : Bool) → (n : ℕ) → C n → C (bit b n)
h : f false 0 z = z ∨ (0 = 0 → false = true)
h' : bit false 0 = 0
⊢ Eq.mpr (_ : C (bit false 0) = C 0) z = f false 0 (binaryRec z f 0)

Next tactic:
rw [binaryRec_zero]
/--
The same as `binaryRec_eq`,
but that one unfortunately requires `f` to be the identity when appending `false` to `0`.
Here, we allow you to explicitly say that that case is not happening,
i.e. supplying `n = 0 → b = true`. -/
theorem binaryRec_eq' {C : ℕ → Sort*} {z : C 0} {f : ∀ b n, C n → C (bit b n)} (b n)
    (h : f false 0 z = z ∨ (n = 0 → b = true)) :
    binaryRec z f (bit b n) = f b n (binaryRec z f n) := by
  rw [binaryRec]
  split_ifs with h'
  · rcases bit_eq_zero_iff.mp h' with ⟨rfl, rfl⟩
    rw [binaryRec_zero]
    

Proof state:
case pos.intro
n : ℕ
C : ℕ → Sort u_1
z : C 0
f : (b : Bool) → (n : ℕ) → C n → C (bit b n)
h : f false 0 z = z ∨ (0 = 0 → false = true)
h' : bit false 0 = 0
⊢ Eq.mpr (_ : C (bit false 0) = C 0) z = f false 0 z

Next tactic:
simp only [imp_false, or_false_iff, eq_self_iff_true, not_true] at h
/--
The same as `binaryRec_eq`,
but that one unfortunately requires `f` to be the identity when appending `false` to `0`.
Here, we allow you to explicitly say that that case is not happening,
i.e. supplying `n = 0 → b = true`. -/
theorem binaryRec_eq' {C : ℕ → Sort*} {z : C 0} {f : ∀ b n, C n → C (bit b n)} (b n)
    (h : f false 0 z = z ∨ (n = 0 → b = true)) :
    binaryRec z f (bit b n) = f b n (binaryRec z f n) := by
  rw [binaryRec]
  split_ifs with h'
  · rcases bit_eq_zero_iff.mp h' with ⟨rfl, rfl⟩
    rw [binaryRec_zero]
    simp only [imp_false, or_false_iff, eq_self_iff_true, not_true] at h
    

Proof state:
case pos.intro
n : ℕ
C : ℕ → Sort u_1
z : C 0
f : (b : Bool) → (n : ℕ) → C n → C (bit b n)
h' : bit false 0 = 0
h : f false 0 z = z
⊢ Eq.mpr (_ : C (bit false 0) = C 0) z = f false 0 z

Next tactic:
exact h.symm
/--
The same as `binaryRec_eq`,
but that one unfortunately requires `f` to be the identity when appending `false` to `0`.
Here, we allow you to explicitly say that that case is not happening,
i.e. supplying `n = 0 → b = true`. -/
theorem binaryRec_eq' {C : ℕ → Sort*} {z : C 0} {f : ∀ b n, C n → C (bit b n)} (b n)
    (h : f false 0 z = z ∨ (n = 0 → b = true)) :
    binaryRec z f (bit b n) = f b n (binaryRec z f n) := by
  rw [binaryRec]
  split_ifs with h'
  · rcases bit_eq_zero_iff.mp h' with ⟨rfl, rfl⟩
    rw [binaryRec_zero]
    simp only [imp_false, or_false_iff, eq_self_iff_true, not_true] at h
    exact h.symm
  · 

Proof state:
case neg
n✝ : ℕ
C : ℕ → Sort u_1
z : C 0
f : (b : Bool) → (n : ℕ) → C n → C (bit b n)
b : Bool
n : ℕ
h : f false 0 z = z ∨ (n = 0 → b = true)
h' : ¬bit b n = 0
⊢ (let n' := div2 (bit b n);
    let_fun _x := (_ : bit (bodd (bit b n)) (div2 (bit b n)) = bit b n);
    Eq.mpr (_ : C (bit b n) = C (bit (bodd (bit b n)) n')) (f (bodd (bit b n)) n' (binaryRec z f n'))) =
    f b n (binaryRec z f n)

Next tactic:
dsimp only []
/--
The same as `binaryRec_eq`,
but that one unfortunately requires `f` to be the identity when appending `false` to `0`.
Here, we allow you to explicitly say that that case is not happening,
i.e. supplying `n = 0 → b = true`. -/
theorem binaryRec_eq' {C : ℕ → Sort*} {z : C 0} {f : ∀ b n, C n → C (bit b n)} (b n)
    (h : f false 0 z = z ∨ (n = 0 → b = true)) :
    binaryRec z f (bit b n) = f b n (binaryRec z f n) := by
  rw [binaryRec]
  split_ifs with h'
  · rcases bit_eq_zero_iff.mp h' with ⟨rfl, rfl⟩
    rw [binaryRec_zero]
    simp only [imp_false, or_false_iff, eq_self_iff_true, not_true] at h
    exact h.symm
  · dsimp only []
    -- Porting note: this line was `generalize_proofs e`:
    

Proof state:
case neg
n✝ : ℕ
C : ℕ → Sort u_1
z : C 0
f : (b : Bool) → (n : ℕ) → C n → C (bit b n)
b : Bool
n : ℕ
h : f false 0 z = z ∨ (n = 0 → b = true)
h' : ¬bit b n = 0
⊢ Eq.mpr (_ : C (bit b n) = C (bit (bodd (bit b n)) (div2 (bit b n))))
      (f (bodd (bit b n)) (div2 (bit b n)) (binaryRec z f (div2 (bit b n)))) =
    f b n (binaryRec z f n)

Next tactic:
generalize @id (C (bit b n) = C (bit (bodd (bit b n)) (div2 (bit b n))))
      (Eq.symm (bit_decomp (bit b n)) ▸ Eq.refl (C (bit b n))) = e
/--
The same as `binaryRec_eq`,
but that one unfortunately requires `f` to be the identity when appending `false` to `0`.
Here, we allow you to explicitly say that that case is not happening,
i.e. supplying `n = 0 → b = true`. -/
theorem binaryRec_eq' {C : ℕ → Sort*} {z : C 0} {f : ∀ b n, C n → C (bit b n)} (b n)
    (h : f false 0 z = z ∨ (n = 0 → b = true)) :
    binaryRec z f (bit b n) = f b n (binaryRec z f n) := by
  rw [binaryRec]
  split_ifs with h'
  · rcases bit_eq_zero_iff.mp h' with ⟨rfl, rfl⟩
    rw [binaryRec_zero]
    simp only [imp_false, or_false_iff, eq_self_iff_true, not_true] at h
    exact h.symm
  · dsimp only []
    -- Porting note: this line was `generalize_proofs e`:
    generalize @id (C (bit b n) = C (bit (bodd (bit b n)) (div2 (bit b n))))
      (Eq.symm (bit_decomp (bit b n)) ▸ Eq.refl (C (bit b n))) = e
    

Proof state:
case neg
n✝ : ℕ
C : ℕ → Sort u_1
z : C 0
f : (b : Bool) → (n : ℕ) → C n → C (bit b n)
b : Bool
n : ℕ
h : f false 0 z = z ∨ (n = 0 → b = true)
h' : ¬bit b n = 0
e : C (bit b n) = C (bit (bodd (bit b n)) (div2 (bit b n)))
⊢ Eq.mpr e (f (bodd (bit b n)) (div2 (bit b n)) (binaryRec z f (div2 (bit b n)))) = f b n (binaryRec z f n)

Next tactic:
revert e
/--
The same as `binaryRec_eq`,
but that one unfortunately requires `f` to be the identity when appending `false` to `0`.
Here, we allow you to explicitly say that that case is not happening,
i.e. supplying `n = 0 → b = true`. -/
theorem binaryRec_eq' {C : ℕ → Sort*} {z : C 0} {f : ∀ b n, C n → C (bit b n)} (b n)
    (h : f false 0 z = z ∨ (n = 0 → b = true)) :
    binaryRec z f (bit b n) = f b n (binaryRec z f n) := by
  rw [binaryRec]
  split_ifs with h'
  · rcases bit_eq_zero_iff.mp h' with ⟨rfl, rfl⟩
    rw [binaryRec_zero]
    simp only [imp_false, or_false_iff, eq_self_iff_true, not_true] at h
    exact h.symm
  · dsimp only []
    -- Porting note: this line was `generalize_proofs e`:
    generalize @id (C (bit b n) = C (bit (bodd (bit b n)) (div2 (bit b n))))
      (Eq.symm (bit_decomp (bit b n)) ▸ Eq.refl (C (bit b n))) = e
    revert e
    

Proof state:
case neg
n✝ : ℕ
C : ℕ → Sort u_1
z : C 0
f : (b : Bool) → (n : ℕ) → C n → C (bit b n)
b : Bool
n : ℕ
h : f false 0 z = z ∨ (n = 0 → b = true)
h' : ¬bit b n = 0
⊢ ∀ (e : C (bit b n) = C (bit (bodd (bit b n)) (div2 (bit b n)))),
    Eq.mpr e (f (bodd (bit b n)) (div2 (bit b n)) (binaryRec z f (div2 (bit b n)))) = f b n (binaryRec z f n)

Next tactic:
rw [bodd_bit, div2_bit]
/--
The same as `binaryRec_eq`,
but that one unfortunately requires `f` to be the identity when appending `false` to `0`.
Here, we allow you to explicitly say that that case is not happening,
i.e. supplying `n = 0 → b = true`. -/
theorem binaryRec_eq' {C : ℕ → Sort*} {z : C 0} {f : ∀ b n, C n → C (bit b n)} (b n)
    (h : f false 0 z = z ∨ (n = 0 → b = true)) :
    binaryRec z f (bit b n) = f b n (binaryRec z f n) := by
  rw [binaryRec]
  split_ifs with h'
  · rcases bit_eq_zero_iff.mp h' with ⟨rfl, rfl⟩
    rw [binaryRec_zero]
    simp only [imp_false, or_false_iff, eq_self_iff_true, not_true] at h
    exact h.symm
  · dsimp only []
    -- Porting note: this line was `generalize_proofs e`:
    generalize @id (C (bit b n) = C (bit (bodd (bit b n)) (div2 (bit b n))))
      (Eq.symm (bit_decomp (bit b n)) ▸ Eq.refl (C (bit b n))) = e
    revert e
    rw [bodd_bit, div2_bit]
    

Proof state:
case neg
n✝ : ℕ
C : ℕ → Sort u_1
z : C 0
f : (b : Bool) → (n : ℕ) → C n → C (bit b n)
b : Bool
n : ℕ
h : f false 0 z = z ∨ (n = 0 → b = true)
h' : ¬bit b n = 0
⊢ ∀ (e : C (bit b n) = C (bit b n)), Eq.mpr e (f b n (binaryRec z f n)) = f b n (binaryRec z f n)

Next tactic:
intros
/--
The same as `binaryRec_eq`,
but that one unfortunately requires `f` to be the identity when appending `false` to `0`.
Here, we allow you to explicitly say that that case is not happening,
i.e. supplying `n = 0 → b = true`. -/
theorem binaryRec_eq' {C : ℕ → Sort*} {z : C 0} {f : ∀ b n, C n → C (bit b n)} (b n)
    (h : f false 0 z = z ∨ (n = 0 → b = true)) :
    binaryRec z f (bit b n) = f b n (binaryRec z f n) := by
  rw [binaryRec]
  split_ifs with h'
  · rcases bit_eq_zero_iff.mp h' with ⟨rfl, rfl⟩
    rw [binaryRec_zero]
    simp only [imp_false, or_false_iff, eq_self_iff_true, not_true] at h
    exact h.symm
  · dsimp only []
    -- Porting note: this line was `generalize_proofs e`:
    generalize @id (C (bit b n) = C (bit (bodd (bit b n)) (div2 (bit b n))))
      (Eq.symm (bit_decomp (bit b n)) ▸ Eq.refl (C (bit b n))) = e
    revert e
    rw [bodd_bit, div2_bit]
    intros
    

Proof state:
case neg
n✝ : ℕ
C : ℕ → Sort u_1
z : C 0
f : (b : Bool) → (n : ℕ) → C n → C (bit b n)
b : Bool
n : ℕ
h : f false 0 z = z ∨ (n = 0 → b = true)
h' : ¬bit b n = 0
e✝ : C (bit b n) = C (bit b n)
⊢ Eq.mpr e✝ (f b n (binaryRec z f n)) = f b n (binaryRec z f n)

Next tactic:
rfl
/-- The same as `binaryRec`, but the induction step can assume that if `n=0`,
  the bit being appended is `true`-/
@[elab_as_elim]
def binaryRec' {C : ℕ → Sort*} (z : C 0) (f : ∀ b n, (n = 0 → b = true) → C n → C (bit b n)) :
    ∀ n, C n :=
  binaryRec z fun b n ih =>
    if h : n = 0 → b = true then f b n h ih
    else by
      

Proof state:
n✝ : ℕ
C : ℕ → Sort u_1
z : C 0
f : (b : Bool) → (n : ℕ) → (n = 0 → b = true) → C n → C (bit b n)
b : Bool
n : ℕ
ih : C n
h : ¬(n = 0 → b = true)
⊢ C (bit b n)

Next tactic:
convert z
/-- The same as `binaryRec`, but the induction step can assume that if `n=0`,
  the bit being appended is `true`-/
@[elab_as_elim]
def binaryRec' {C : ℕ → Sort*} (z : C 0) (f : ∀ b n, (n = 0 → b = true) → C n → C (bit b n)) :
    ∀ n, C n :=
  binaryRec z fun b n ih =>
    if h : n = 0 → b = true then f b n h ih
    else by
      convert z
      

Proof state:
case h.e'_1
n✝ : ℕ
C : ℕ → Sort u_1
z : C 0
f : (b : Bool) → (n : ℕ) → (n = 0 → b = true) → C n → C (bit b n)
b : Bool
n : ℕ
ih : C n
h : ¬(n = 0 → b = true)
⊢ bit b n = 0

Next tactic:
rw [bit_eq_zero_iff]
/-- The same as `binaryRec`, but the induction step can assume that if `n=0`,
  the bit being appended is `true`-/
@[elab_as_elim]
def binaryRec' {C : ℕ → Sort*} (z : C 0) (f : ∀ b n, (n = 0 → b = true) → C n → C (bit b n)) :
    ∀ n, C n :=
  binaryRec z fun b n ih =>
    if h : n = 0 → b = true then f b n h ih
    else by
      convert z
      rw [bit_eq_zero_iff]
      

Proof state:
case h.e'_1
n✝ : ℕ
C : ℕ → Sort u_1
z : C 0
f : (b : Bool) → (n : ℕ) → (n = 0 → b = true) → C n → C (bit b n)
b : Bool
n : ℕ
ih : C n
h : ¬(n = 0 → b = true)
⊢ n = 0 ∧ b = false

Next tactic:
simpa using h
/-- The same as `binaryRec`, but special casing both 0 and 1 as base cases -/
@[elab_as_elim]
def binaryRecFromOne {C : ℕ → Sort*} (z₀ : C 0) (z₁ : C 1) (f : ∀ b n, n ≠ 0 → C n → C (bit b n)) :
    ∀ n, C n :=
  binaryRec' z₀ fun b n h ih =>
    if h' : n = 0 then by
      

Proof state:
n✝ : ℕ
C : ℕ → Sort u_1
z₀ : C 0
z₁ : C 1
f : (b : Bool) → (n : ℕ) → n ≠ 0 → C n → C (bit b n)
b : Bool
n : ℕ
h : n = 0 → b = true
ih : C n
h' : n = 0
⊢ C (bit b n)

Next tactic:
rw [h', h h']
/-- The same as `binaryRec`, but special casing both 0 and 1 as base cases -/
@[elab_as_elim]
def binaryRecFromOne {C : ℕ → Sort*} (z₀ : C 0) (z₁ : C 1) (f : ∀ b n, n ≠ 0 → C n → C (bit b n)) :
    ∀ n, C n :=
  binaryRec' z₀ fun b n h ih =>
    if h' : n = 0 then by
      rw [h', h h']
      

Proof state:
n✝ : ℕ
C : ℕ → Sort u_1
z₀ : C 0
z₁ : C 1
f : (b : Bool) → (n : ℕ) → n ≠ 0 → C n → C (bit b n)
b : Bool
n : ℕ
h : n = 0 → b = true
ih : C n
h' : n = 0
⊢ C (bit true 0)

Next tactic:
exact z₁
@[simp]
theorem zero_bits : bits 0 = [] := by 

Proof state:
n : ℕ
⊢ bits 0 = []

Next tactic:
simp [Nat.bits]
@[simp]
theorem bits_append_bit (n : ℕ) (b : Bool) (hn : n = 0 → b = true) :
    (bit b n).bits = b :: n.bits := by
  

Proof state:
n✝ n : ℕ
b : Bool
hn : n = 0 → b = true
⊢ bits (bit b n) = b :: bits n

Next tactic:
rw [Nat.bits, binaryRec_eq']
@[simp]
theorem bits_append_bit (n : ℕ) (b : Bool) (hn : n = 0 → b = true) :
    (bit b n).bits = b :: n.bits := by
  rw [Nat.bits, binaryRec_eq']
  

Proof state:
case h
n✝ n : ℕ
b : Bool
hn : n = 0 → b = true
⊢ [false] = [] ∨ (n = 0 → b = true)

Next tactic:
simpa
@[simp]
theorem one_bits : Nat.bits 1 = [true] := by
  

Proof state:
n : ℕ
⊢ bits 1 = [true]

Next tactic:
convert bit1_bits 0
theorem bodd_eq_bits_head (n : ℕ) : n.bodd = n.bits.headI := by
  

Proof state:
n✝ n : ℕ
⊢ bodd n = List.headI (bits n)

Next tactic:
induction' n using Nat.binaryRec' with b n h _
theorem bodd_eq_bits_head (n : ℕ) : n.bodd = n.bits.headI := by
  induction' n using Nat.binaryRec' with b n h _; · 

Proof state:
case z
n : ℕ
⊢ bodd 0 = List.headI (bits 0)

Next tactic:
simp
theorem bodd_eq_bits_head (n : ℕ) : n.bodd = n.bits.headI := by
  induction' n using Nat.binaryRec' with b n h _; · simp
  

Proof state:
case f
n✝ : ℕ
b : Bool
n : ℕ
h : n = 0 → b = true
a✝ : bodd n = List.headI (bits n)
⊢ bodd (bit b n) = List.headI (bits (bit b n))

Next tactic:
simp [bodd_bit, bits_append_bit _ _ h]
theorem div2_bits_eq_tail (n : ℕ) : n.div2.bits = n.bits.tail := by
  

Proof state:
n✝ n : ℕ
⊢ bits (div2 n) = List.tail (bits n)

Next tactic:
induction' n using Nat.binaryRec' with b n h _
theorem div2_bits_eq_tail (n : ℕ) : n.div2.bits = n.bits.tail := by
  induction' n using Nat.binaryRec' with b n h _; · 

Proof state:
case z
n : ℕ
⊢ bits (div2 0) = List.tail (bits 0)

Next tactic:
simp
theorem div2_bits_eq_tail (n : ℕ) : n.div2.bits = n.bits.tail := by
  induction' n using Nat.binaryRec' with b n h _; · simp
  

Proof state:
case f
n✝ : ℕ
b : Bool
n : ℕ
h : n = 0 → b = true
a✝ : bits (div2 n) = List.tail (bits n)
⊢ bits (div2 (bit b n)) = List.tail (bits (bit b n))

Next tactic:
simp [div2_bit, bits_append_bit _ _ h]
/-- If `(f y - f x) / (y - x)` converges to a limit as `y` tends to `x`, then the same goes if
`y` is shifted a little bit, i.e., `f (y + (y-x)^2) - f x) / (y - x)` converges to the same limit.
This lemma contains a slightly more general version of this statement (where one considers
convergence along some subfilter, typically `𝓝[<] x` or `𝓝[>] x`) tailored to the application
to almost everywhere differentiability of monotone functions. -/
theorem tendsto_apply_add_mul_sq_div_sub {f : ℝ → ℝ} {x a c d : ℝ} {l : Filter ℝ} (hl : l ≤ 𝓝[≠] x)
    (hf : Tendsto (fun y => (f y - d) / (y - x)) l (𝓝 a))
    (h' : Tendsto (fun y => y + c * (y - x) ^ 2) l l) :
    Tendsto (fun y => (f (y + c * (y - x) ^ 2) - d) / (y - x)) l (𝓝 a) := by
  

Proof state:
f : ℝ → ℝ
x a c d : ℝ
l : Filter ℝ
hl : l ≤ 𝓝[≠] x
hf : Tendsto (fun y => (f y - d) / (y - x)) l (𝓝 a)
h' : Tendsto (fun y => y + c * (y - x) ^ 2) l l
⊢ Tendsto (fun y => (f (y + c * (y - x) ^ 2) - d) / (y - x)) l (𝓝 a)

Next tactic:
have L : Tendsto (fun y => (y + c * (y - x) ^ 2 - x) / (y - x)) l (𝓝 1) := by
    have : Tendsto (fun y => 1 + c * (y - x)) l (𝓝 (1 + c * (x - x))) := by
      apply Tendsto.mono_left _ (hl.trans nhdsWithin_le_nhds)
      exact ((tendsto_id.sub_const x).const_mul c).const_add 1
    simp only [_root_.sub_self, add_zero, mul_zero] at this
    apply Tendsto.congr' (Eventually.filter_mono hl _) this
    filter_upwards [self_mem_nhdsWithin] with y hy
    field_simp [sub_ne_zero.2 hy]
    ring