l3lab/ntp-mathlib huggingface dataset:
/-- Any nonempty perfect set in a complete metric space admits a continuous injection
from the Cantor space, `ℕ → Bool`. -/
theorem Perfect.exists_nat_bool_injection [CompleteSpace α] :
    ∃ f : (ℕ → Bool) → α, range f ⊆ C ∧ Continuous f ∧ Injective f := by
  obtain ⟨u, -, upos', hu⟩ := exists_seq_strictAnti_tendsto' (zero_lt_one' ℝ≥0∞)
  have upos := fun n => (upos' n).1
  let P := Subtype fun E : Set α => Perfect E ∧ E.Nonempty
  choose C0 C1 h0 h1 hdisj using
    fun {C : Set α} (hC : Perfect C) (hnonempty : C.Nonempty) {ε : ℝ≥0∞} (hε : 0 < ε) =>
    hC.small_diam_splitting hnonempty hε
  let DP : List Bool → P := fun l => by
    induction' l with a l ih; · exact ⟨C, ⟨hC, hnonempty⟩⟩
    cases a
    · use C0 ih.property.1 ih.property.2 (upos l.length.succ)
      exact ⟨(h0 _ _ _).1, (h0 _ _ _).2.1⟩
    use C1 ih.property.1 ih.property.2 (upos l.length.succ)
    

Proof state:
case property
α : Type u_1
inst✝¹ : MetricSpace α
C : Set α
hC : Perfect C
ε : ℝ≥0∞
hnonempty : Set.Nonempty C
inst✝ : CompleteSpace α
u : ℕ → ℝ≥0∞
upos' : ∀ (n : ℕ), u n ∈ Ioo 0 1
hu : Tendsto u atTop (𝓝 0)
upos : ∀ (n : ℕ), 0 < u n
P : Type u_1 := { E // Perfect E ∧ Set.Nonempty E }
C0 C1 : {C : Set α} → Perfect C → Set.Nonempty C → {ε : ℝ≥0∞} → 0 < ε → Set α
h0 :
  ∀ {C : Set α} (hC : Perfect C) (hnonempty : Set.Nonempty C) {ε : ℝ≥0∞} (hε : 0 < ε),
    Perfect (C0 hC hnonempty hε) ∧
      Set.Nonempty (C0 hC hnonempty hε) ∧ C0 hC hnonempty hε ⊆ C ∧ EMetric.diam (C0 hC hnonempty hε) ≤ ε
h1 :
  ∀ {C : Set α} (hC : Perfect C) (hnonempty : Set.Nonempty C) {ε : ℝ≥0∞} (hε : 0 < ε),
    Perfect (C1 hC hnonempty hε) ∧
      Set.Nonempty (C1 hC hnonempty hε) ∧ C1 hC hnonempty hε ⊆ C ∧ EMetric.diam (C1 hC hnonempty hε) ≤ ε
hdisj :
  ∀ {C : Set α} (hC : Perfect C) (hnonempty : Set.Nonempty C) {ε : ℝ≥0∞} (hε : 0 < ε),
    Disjoint (C0 hC hnonempty hε) (C1 hC hnonempty hε)
l : List Bool
ih : P
⊢ Perfect (C1 (_ : Perfect ↑ih) (_ : Set.Nonempty ↑ih) (_ : 0 < u (Nat.succ (List.length l)))) ∧
    Set.Nonempty (C1 (_ : Perfect ↑ih) (_ : Set.Nonempty ↑ih) (_ : 0 < u (Nat.succ (List.length l))))

Next tactic:
exact ⟨(h1 _ _ _).1, (h1 _ _ _).2.1⟩
/-- Any nonempty perfect set in a complete metric space admits a continuous injection
from the Cantor space, `ℕ → Bool`. -/
theorem Perfect.exists_nat_bool_injection [CompleteSpace α] :
    ∃ f : (ℕ → Bool) → α, range f ⊆ C ∧ Continuous f ∧ Injective f := by
  obtain ⟨u, -, upos', hu⟩ := exists_seq_strictAnti_tendsto' (zero_lt_one' ℝ≥0∞)
  have upos := fun n => (upos' n).1
  let P := Subtype fun E : Set α => Perfect E ∧ E.Nonempty
  choose C0 C1 h0 h1 hdisj using
    fun {C : Set α} (hC : Perfect C) (hnonempty : C.Nonempty) {ε : ℝ≥0∞} (hε : 0 < ε) =>
    hC.small_diam_splitting hnonempty hε
  let DP : List Bool → P := fun l => by
    induction' l with a l ih; · exact ⟨C, ⟨hC, hnonempty⟩⟩
    cases a
    · use C0 ih.property.1 ih.property.2 (upos l.length.succ)
      exact ⟨(h0 _ _ _).1, (h0 _ _ _).2.1⟩
    use C1 ih.property.1 ih.property.2 (upos l.length.succ)
    exact ⟨(h1 _ _ _).1, (h1 _ _ _).2.1⟩
  

Proof state:
case intro.intro.intro
α : Type u_1
inst✝¹ : MetricSpace α
C : Set α
hC : Perfect C
ε : ℝ≥0∞
hnonempty : Set.Nonempty C
inst✝ : CompleteSpace α
u : ℕ → ℝ≥0∞
upos' : ∀ (n : ℕ), u n ∈ Ioo 0 1
hu : Tendsto u atTop (𝓝 0)
upos : ∀ (n : ℕ), 0 < u n
P : Type u_1 := { E // Perfect E ∧ Set.Nonempty E }
C0 C1 : {C : Set α} → Perfect C → Set.Nonempty C → {ε : ℝ≥0∞} → 0 < ε → Set α
h0 :
  ∀ {C : Set α} (hC : Perfect C) (hnonempty : Set.Nonempty C) {ε : ℝ≥0∞} (hε : 0 < ε),
    Perfect (C0 hC hnonempty hε) ∧
      Set.Nonempty (C0 hC hnonempty hε) ∧ C0 hC hnonempty hε ⊆ C ∧ EMetric.diam (C0 hC hnonempty hε) ≤ ε
h1 :
  ∀ {C : Set α} (hC : Perfect C) (hnonempty : Set.Nonempty C) {ε : ℝ≥0∞} (hε : 0 < ε),
    Perfect (C1 hC hnonempty hε) ∧
      Set.Nonempty (C1 hC hnonempty hε) ∧ C1 hC hnonempty hε ⊆ C ∧ EMetric.diam (C1 hC hnonempty hε) ≤ ε
hdisj :
  ∀ {C : Set α} (hC : Perfect C) (hnonempty : Set.Nonempty C) {ε : ℝ≥0∞} (hε : 0 < ε),
    Disjoint (C0 hC hnonempty hε) (C1 hC hnonempty hε)
DP : List Bool → P :=
  fun l =>
    List.rec { val := C, property := (_ : Perfect C ∧ Set.Nonempty C) }
      (fun a l ih =>
        Bool.casesOn (motive := fun t => a = t → P) a
          (fun h =>
            { val := C0 (_ : Perfect ↑ih) (_ : Set.Nonempty ↑ih) (_ : 0 < u (Nat.succ (List.length l))),
              property :=
                (_ :
                  Perfect (C0 (_ : Perfect ↑ih) (_ : Set.Nonempty ↑ih) (_ : 0 < u (Nat.succ (List.length l)))) ∧
                    Set.Nonempty
                      (C0 (_ : Perfect ↑ih) (_ : Set.Nonempty ↑ih) (_ : 0 < u (Nat.succ (List.length l))))) })
          (fun h =>
            { val := C1 (_ : Perfect ↑ih) (_ : Set.Nonempty ↑ih) (_ : 0 < u (Nat.succ (List.length l))),
              property :=
                (_ :
                  Perfect (C1 (_ : Perfect ↑ih) (_ : Set.Nonempty ↑ih) (_ : 0 < u (Nat.succ (List.length l)))) ∧
                    Set.Nonempty
                      (C1 (_ : Perfect ↑ih) (_ : Set.Nonempty ↑ih) (_ : 0 < u (Nat.succ (List.length l))))) })
          (_ : a = a))
      l
⊢ ∃ f, range f ⊆ C ∧ Continuous f ∧ Injective f

Next tactic:
let D : List Bool → Set α := fun l => (DP l).val
/-- Any closed uncountable subset of a Polish space admits a continuous injection
from the Cantor space `ℕ → Bool`.-/
theorem IsClosed.exists_nat_bool_injection_of_not_countable {α : Type*} [TopologicalSpace α]
    [PolishSpace α] {C : Set α} (hC : IsClosed C) (hunc : ¬C.Countable) :
    ∃ f : (ℕ → Bool) → α, range f ⊆ C ∧ Continuous f ∧ Function.Injective f := by
  

Proof state:
α : Type u_1
inst✝¹ : TopologicalSpace α
inst✝ : PolishSpace α
C : Set α
hC : IsClosed C
hunc : ¬Set.Countable C
⊢ ∃ f, range f ⊆ C ∧ Continuous f ∧ Function.Injective f

Next tactic:
letI := upgradePolishSpace α
/-- Any closed uncountable subset of a Polish space admits a continuous injection
from the Cantor space `ℕ → Bool`.-/
theorem IsClosed.exists_nat_bool_injection_of_not_countable {α : Type*} [TopologicalSpace α]
    [PolishSpace α] {C : Set α} (hC : IsClosed C) (hunc : ¬C.Countable) :
    ∃ f : (ℕ → Bool) → α, range f ⊆ C ∧ Continuous f ∧ Function.Injective f := by
  letI := upgradePolishSpace α
  

Proof state:
α : Type u_1
inst✝¹ : TopologicalSpace α
inst✝ : PolishSpace α
C : Set α
hC : IsClosed C
hunc : ¬Set.Countable C
this : UpgradedPolishSpace α := upgradePolishSpace α
⊢ ∃ f, range f ⊆ C ∧ Continuous f ∧ Function.Injective f

Next tactic:
obtain ⟨D, hD, Dnonempty, hDC⟩ := exists_perfect_nonempty_of_isClosed_of_not_countable hC hunc
/-- Any closed uncountable subset of a Polish space admits a continuous injection
from the Cantor space `ℕ → Bool`.-/
theorem IsClosed.exists_nat_bool_injection_of_not_countable {α : Type*} [TopologicalSpace α]
    [PolishSpace α] {C : Set α} (hC : IsClosed C) (hunc : ¬C.Countable) :
    ∃ f : (ℕ → Bool) → α, range f ⊆ C ∧ Continuous f ∧ Function.Injective f := by
  letI := upgradePolishSpace α
  obtain ⟨D, hD, Dnonempty, hDC⟩ := exists_perfect_nonempty_of_isClosed_of_not_countable hC hunc
  

Proof state:
case intro.intro.intro
α : Type u_1
inst✝¹ : TopologicalSpace α
inst✝ : PolishSpace α
C : Set α
hC : IsClosed C
hunc : ¬Set.Countable C
this : UpgradedPolishSpace α := upgradePolishSpace α
D : Set α
hD : Perfect D
Dnonempty : Set.Nonempty D
hDC : D ⊆ C
⊢ ∃ f, range f ⊆ C ∧ Continuous f ∧ Function.Injective f

Next tactic:
obtain ⟨f, hfD, hf⟩ := hD.exists_nat_bool_injection Dnonempty
/-- Any closed uncountable subset of a Polish space admits a continuous injection
from the Cantor space `ℕ → Bool`.-/
theorem IsClosed.exists_nat_bool_injection_of_not_countable {α : Type*} [TopologicalSpace α]
    [PolishSpace α] {C : Set α} (hC : IsClosed C) (hunc : ¬C.Countable) :
    ∃ f : (ℕ → Bool) → α, range f ⊆ C ∧ Continuous f ∧ Function.Injective f := by
  letI := upgradePolishSpace α
  obtain ⟨D, hD, Dnonempty, hDC⟩ := exists_perfect_nonempty_of_isClosed_of_not_countable hC hunc
  obtain ⟨f, hfD, hf⟩ := hD.exists_nat_bool_injection Dnonempty
  

Proof state:
case intro.intro.intro.intro.intro
α : Type u_1
inst✝¹ : TopologicalSpace α
inst✝ : PolishSpace α
C : Set α
hC : IsClosed C
hunc : ¬Set.Countable C
this : UpgradedPolishSpace α := upgradePolishSpace α
D : Set α
hD : Perfect D
Dnonempty : Set.Nonempty D
hDC : D ⊆ C
f : (ℕ → Bool) → α
hfD : range f ⊆ D
hf : Continuous f ∧ Function.Injective f
⊢ ∃ f, range f ⊆ C ∧ Continuous f ∧ Function.Injective f

Next tactic:
exact ⟨f, hfD.trans hDC, hf⟩
theorem int_gcd_helper' {d : ℕ} {x y : ℤ} (a b : ℤ) (h₁ : (d : ℤ) ∣ x) (h₂ : (d : ℤ) ∣ y)
    (h₃ : x * a + y * b = d) : Int.gcd x y = d := by
  

Proof state:
d : ℕ
x y a b : ℤ
h₁ : ↑d ∣ x
h₂ : ↑d ∣ y
h₃ : x * a + y * b = ↑d
⊢ Int.gcd x y = d

Next tactic:
refine Nat.dvd_antisymm ?_ (Int.coe_nat_dvd.1 (Int.dvd_gcd h₁ h₂))
theorem int_gcd_helper' {d : ℕ} {x y : ℤ} (a b : ℤ) (h₁ : (d : ℤ) ∣ x) (h₂ : (d : ℤ) ∣ y)
    (h₃ : x * a + y * b = d) : Int.gcd x y = d := by
  refine Nat.dvd_antisymm ?_ (Int.coe_nat_dvd.1 (Int.dvd_gcd h₁ h₂))
  

Proof state:
d : ℕ
x y a b : ℤ
h₁ : ↑d ∣ x
h₂ : ↑d ∣ y
h₃ : x * a + y * b = ↑d
⊢ Int.gcd x y ∣ d

Next tactic:
rw [← Int.coe_nat_dvd, ← h₃]
theorem int_gcd_helper' {d : ℕ} {x y : ℤ} (a b : ℤ) (h₁ : (d : ℤ) ∣ x) (h₂ : (d : ℤ) ∣ y)
    (h₃ : x * a + y * b = d) : Int.gcd x y = d := by
  refine Nat.dvd_antisymm ?_ (Int.coe_nat_dvd.1 (Int.dvd_gcd h₁ h₂))
  rw [← Int.coe_nat_dvd, ← h₃]
  

Proof state:
d : ℕ
x y a b : ℤ
h₁ : ↑d ∣ x
h₂ : ↑d ∣ y
h₃ : x * a + y * b = ↑d
⊢ ↑(Int.gcd x y) ∣ x * a + y * b

Next tactic:
apply dvd_add
theorem int_gcd_helper' {d : ℕ} {x y : ℤ} (a b : ℤ) (h₁ : (d : ℤ) ∣ x) (h₂ : (d : ℤ) ∣ y)
    (h₃ : x * a + y * b = d) : Int.gcd x y = d := by
  refine Nat.dvd_antisymm ?_ (Int.coe_nat_dvd.1 (Int.dvd_gcd h₁ h₂))
  rw [← Int.coe_nat_dvd, ← h₃]
  apply dvd_add
  · 

Proof state:
case h₁
d : ℕ
x y a b : ℤ
h₁ : ↑d ∣ x
h₂ : ↑d ∣ y
h₃ : x * a + y * b = ↑d
⊢ ↑(Int.gcd x y) ∣ x * a

Next tactic:
exact (Int.gcd_dvd_left _ _).mul_right _
theorem int_gcd_helper' {d : ℕ} {x y : ℤ} (a b : ℤ) (h₁ : (d : ℤ) ∣ x) (h₂ : (d : ℤ) ∣ y)
    (h₃ : x * a + y * b = d) : Int.gcd x y = d := by
  refine Nat.dvd_antisymm ?_ (Int.coe_nat_dvd.1 (Int.dvd_gcd h₁ h₂))
  rw [← Int.coe_nat_dvd, ← h₃]
  apply dvd_add
  · exact (Int.gcd_dvd_left _ _).mul_right _
  · 

Proof state:
case h₂
d : ℕ
x y a b : ℤ
h₁ : ↑d ∣ x
h₂ : ↑d ∣ y
h₃ : x * a + y * b = ↑d
⊢ ↑(Int.gcd x y) ∣ y * b

Next tactic:
exact (Int.gcd_dvd_right _ _).mul_right _
theorem nat_gcd_helper_2 (d x y a b : ℕ) (hu : x % d = 0) (hv : y % d = 0)
    (h : x * a = y * b + d) : Nat.gcd x y = d := by
  

Proof state:
d x y a b : ℕ
hu : x % d = 0
hv : y % d = 0
h : x * a = y * b + d
⊢ Nat.gcd x y = d

Next tactic:
rw [← Int.coe_nat_gcd]
theorem nat_gcd_helper_2 (d x y a b : ℕ) (hu : x % d = 0) (hv : y % d = 0)
    (h : x * a = y * b + d) : Nat.gcd x y = d := by
  rw [← Int.coe_nat_gcd]
  

Proof state:
d x y a b : ℕ
hu : x % d = 0
hv : y % d = 0
h : x * a = y * b + d
⊢ Int.gcd ↑x ↑y = d

Next tactic:
apply int_gcd_helper' a (-b)
    (Int.coe_nat_dvd.mpr (Nat.dvd_of_mod_eq_zero hu))
    (Int.coe_nat_dvd.mpr (Nat.dvd_of_mod_eq_zero hv))
theorem nat_gcd_helper_2 (d x y a b : ℕ) (hu : x % d = 0) (hv : y % d = 0)
    (h : x * a = y * b + d) : Nat.gcd x y = d := by
  rw [← Int.coe_nat_gcd]
  apply int_gcd_helper' a (-b)
    (Int.coe_nat_dvd.mpr (Nat.dvd_of_mod_eq_zero hu))
    (Int.coe_nat_dvd.mpr (Nat.dvd_of_mod_eq_zero hv))
  

Proof state:
d x y a b : ℕ
hu : x % d = 0
hv : y % d = 0
h : x * a = y * b + d
⊢ ↑x * ↑a + ↑y * -↑b = ↑d

Next tactic:
rw [mul_neg, ← sub_eq_add_neg, sub_eq_iff_eq_add']
theorem nat_gcd_helper_2 (d x y a b : ℕ) (hu : x % d = 0) (hv : y % d = 0)
    (h : x * a = y * b + d) : Nat.gcd x y = d := by
  rw [← Int.coe_nat_gcd]
  apply int_gcd_helper' a (-b)
    (Int.coe_nat_dvd.mpr (Nat.dvd_of_mod_eq_zero hu))
    (Int.coe_nat_dvd.mpr (Nat.dvd_of_mod_eq_zero hv))
  rw [mul_neg, ← sub_eq_add_neg, sub_eq_iff_eq_add']
  

Proof state:
d x y a b : ℕ
hu : x % d = 0
hv : y % d = 0
h : x * a = y * b + d
⊢ ↑x * ↑a = ↑y * ↑b + ↑d

Next tactic:
exact mod_cast h
theorem nat_lcm_helper (x y d m : ℕ) (hd : Nat.gcd x y = d)
    (d0 : Nat.beq d 0 = false)
    (dm : x * y = d * m) : Nat.lcm x y = m :=
  mul_right_injective₀ (Nat.ne_of_beq_eq_false d0) <| by
    

Proof state:
x y d m : ℕ
hd : Nat.gcd x y = d
d0 : Nat.beq d 0 = false
dm : x * y = d * m
⊢ (fun x => d * x) (Nat.lcm x y) = (fun x => d * x) m

Next tactic:
dsimp only
theorem nat_lcm_helper (x y d m : ℕ) (hd : Nat.gcd x y = d)
    (d0 : Nat.beq d 0 = false)
    (dm : x * y = d * m) : Nat.lcm x y = m :=
  mul_right_injective₀ (Nat.ne_of_beq_eq_false d0) <| by
    dsimp only -- Porting note: the `dsimp only` was not necessary in Lean3.
    

Proof state:
x y d m : ℕ
hd : Nat.gcd x y = d
d0 : Nat.beq d 0 = false
dm : x * y = d * m
⊢ d * Nat.lcm x y = d * m

Next tactic:
rw [← dm, ← hd, Nat.gcd_mul_lcm]
theorem int_gcd_helper {x y : ℤ} {x' y' d : ℕ}
    (hx : x.natAbs = x') (hy : y.natAbs = y') (h : Nat.gcd x' y' = d) :
    Int.gcd x y = d := by 

Proof state:
x y : ℤ
x' y' d : ℕ
hx : Int.natAbs x = x'
hy : Int.natAbs y = y'
h : Nat.gcd x' y' = d
⊢ Int.gcd x y = d

Next tactic:
subst_vars
theorem int_gcd_helper {x y : ℤ} {x' y' d : ℕ}
    (hx : x.natAbs = x') (hy : y.natAbs = y') (h : Nat.gcd x' y' = d) :
    Int.gcd x y = d := by subst_vars; 

Proof state:
x y : ℤ
⊢ Int.gcd x y = Nat.gcd (Int.natAbs x) (Int.natAbs y)

Next tactic:
rw [Int.gcd_def]
theorem int_lcm_helper {x y : ℤ} {x' y' d : ℕ}
    (hx : x.natAbs = x') (hy : y.natAbs = y') (h : Nat.lcm x' y' = d) :
    Int.lcm x y = d := by 

Proof state:
x y : ℤ
x' y' d : ℕ
hx : Int.natAbs x = x'
hy : Int.natAbs y = y'
h : Nat.lcm x' y' = d
⊢ Int.lcm x y = d

Next tactic:
subst_vars
theorem int_lcm_helper {x y : ℤ} {x' y' d : ℕ}
    (hx : x.natAbs = x') (hy : y.natAbs = y') (h : Nat.lcm x' y' = d) :
    Int.lcm x y = d := by subst_vars; 

Proof state:
x y : ℤ
⊢ Int.lcm x y = Nat.lcm (Int.natAbs x) (Int.natAbs y)

Next tactic:
rw [Int.lcm_def]
@[simp, norm_cast]
theorem cast_to_int [AddGroupWithOne α] (n : PosNum) : ((n : ℤ) : α) = n := by
  

Proof state:
α : Type u_1
inst✝ : AddGroupWithOne α
n : PosNum
⊢ ↑↑n = ↑n

Next tactic:
rw [← to_nat_to_int, Int.cast_ofNat, cast_to_nat]
theorem succ_to_nat : ∀ n, (succ n : ℕ) = n + 1
  | 1 => rfl
  | bit0 p => rfl
  | bit1 p =>
    (congr_arg _root_.bit0 (succ_to_nat p)).trans <|
      show ↑p + 1 + ↑p + 1 = ↑p + ↑p + 1 + 1 by 

Proof state:
α : Type u_1
p : PosNum
⊢ ↑p + 1 + ↑p + 1 = ↑p + ↑p + 1 + 1

Next tactic:
simp [add_left_comm]
theorem one_add (n : PosNum) : 1 + n = succ n := by 

Proof state:
α : Type u_1
n : PosNum
⊢ 1 + n = succ n

Next tactic:
cases n
theorem one_add (n : PosNum) : 1 + n = succ n := by cases n <;> 

Proof state:
case one
α : Type u_1
⊢ 1 + one = succ one

Next tactic:
rfl
theorem one_add (n : PosNum) : 1 + n = succ n := by cases n <;> 

Proof state:
case bit1
α : Type u_1
a✝ : PosNum
⊢ 1 + bit1 a✝ = succ (bit1 a✝)

Next tactic:
rfl
theorem one_add (n : PosNum) : 1 + n = succ n := by cases n <;> 

Proof state:
case bit0
α : Type u_1
a✝ : PosNum
⊢ 1 + bit0 a✝ = succ (bit0 a✝)

Next tactic:
rfl
theorem add_one (n : PosNum) : n + 1 = succ n := by 

Proof state:
α : Type u_1
n : PosNum
⊢ n + 1 = succ n

Next tactic:
cases n
theorem add_one (n : PosNum) : n + 1 = succ n := by cases n <;> 

Proof state:
case one
α : Type u_1
⊢ one + 1 = succ one

Next tactic:
rfl
theorem add_one (n : PosNum) : n + 1 = succ n := by cases n <;> 

Proof state:
case bit1
α : Type u_1
a✝ : PosNum
⊢ bit1 a✝ + 1 = succ (bit1 a✝)

Next tactic:
rfl
theorem add_one (n : PosNum) : n + 1 = succ n := by cases n <;> 

Proof state:
case bit0
α : Type u_1
a✝ : PosNum
⊢ bit0 a✝ + 1 = succ (bit0 a✝)

Next tactic:
rfl
@[norm_cast]
theorem add_to_nat : ∀ m n, ((m + n : PosNum) : ℕ) = m + n
  | 1, b => by 

Proof state:
α : Type u_1
b : PosNum
⊢ ↑(1 + b) = ↑1 + ↑b

Next tactic:
rw [one_add b, succ_to_nat, add_comm, cast_one]
@[norm_cast]
theorem add_to_nat : ∀ m n, ((m + n : PosNum) : ℕ) = m + n
  | 1, b => by rw [one_add b, succ_to_nat, add_comm, cast_one]
  | a, 1 => by 

Proof state:
α : Type u_1
a : PosNum
⊢ ↑(a + 1) = ↑a + ↑1

Next tactic:
rw [add_one a, succ_to_nat, cast_one]
@[norm_cast]
theorem add_to_nat : ∀ m n, ((m + n : PosNum) : ℕ) = m + n
  | 1, b => by rw [one_add b, succ_to_nat, add_comm, cast_one]
  | a, 1 => by rw [add_one a, succ_to_nat, cast_one]
  | bit0 a, bit0 b => (congr_arg _root_.bit0 (add_to_nat a b)).trans <| add_add_add_comm _ _ _ _
  | bit0 a, bit1 b =>
    (congr_arg _root_.bit1 (add_to_nat a b)).trans <|
      show (a + b + (a + b) + 1 : ℕ) = a + a + (b + b + 1) by 

Proof state:
α : Type u_1
a b : PosNum
⊢ ↑a + ↑b + (↑a + ↑b) + 1 = ↑a + ↑a + (↑b + ↑b + 1)

Next tactic:
simp [add_left_comm]
@[norm_cast]
theorem add_to_nat : ∀ m n, ((m + n : PosNum) : ℕ) = m + n
  | 1, b => by rw [one_add b, succ_to_nat, add_comm, cast_one]
  | a, 1 => by rw [add_one a, succ_to_nat, cast_one]
  | bit0 a, bit0 b => (congr_arg _root_.bit0 (add_to_nat a b)).trans <| add_add_add_comm _ _ _ _
  | bit0 a, bit1 b =>
    (congr_arg _root_.bit1 (add_to_nat a b)).trans <|
      show (a + b + (a + b) + 1 : ℕ) = a + a + (b + b + 1) by simp [add_left_comm]
  | bit1 a, bit0 b =>
    (congr_arg _root_.bit1 (add_to_nat a b)).trans <|
      show (a + b + (a + b) + 1 : ℕ) = a + a + 1 + (b + b) by 

Proof state:
α : Type u_1
a b : PosNum
⊢ ↑a + ↑b + (↑a + ↑b) + 1 = ↑a + ↑a + 1 + (↑b + ↑b)

Next tactic:
simp [add_comm, add_left_comm]
@[norm_cast]
theorem add_to_nat : ∀ m n, ((m + n : PosNum) : ℕ) = m + n
  | 1, b => by rw [one_add b, succ_to_nat, add_comm, cast_one]
  | a, 1 => by rw [add_one a, succ_to_nat, cast_one]
  | bit0 a, bit0 b => (congr_arg _root_.bit0 (add_to_nat a b)).trans <| add_add_add_comm _ _ _ _
  | bit0 a, bit1 b =>
    (congr_arg _root_.bit1 (add_to_nat a b)).trans <|
      show (a + b + (a + b) + 1 : ℕ) = a + a + (b + b + 1) by simp [add_left_comm]
  | bit1 a, bit0 b =>
    (congr_arg _root_.bit1 (add_to_nat a b)).trans <|
      show (a + b + (a + b) + 1 : ℕ) = a + a + 1 + (b + b) by simp [add_comm, add_left_comm]
  | bit1 a, bit1 b =>
    show (succ (a + b) + succ (a + b) : ℕ) = a + a + 1 + (b + b + 1) by
      

Proof state:
α : Type u_1
a b : PosNum
⊢ ↑(succ (a + b)) + ↑(succ (a + b)) = ↑a + ↑a + 1 + (↑b + ↑b + 1)

Next tactic:
rw [succ_to_nat, add_to_nat a b]
@[norm_cast]
theorem add_to_nat : ∀ m n, ((m + n : PosNum) : ℕ) = m + n
  | 1, b => by rw [one_add b, succ_to_nat, add_comm, cast_one]
  | a, 1 => by rw [add_one a, succ_to_nat, cast_one]
  | bit0 a, bit0 b => (congr_arg _root_.bit0 (add_to_nat a b)).trans <| add_add_add_comm _ _ _ _
  | bit0 a, bit1 b =>
    (congr_arg _root_.bit1 (add_to_nat a b)).trans <|
      show (a + b + (a + b) + 1 : ℕ) = a + a + (b + b + 1) by simp [add_left_comm]
  | bit1 a, bit0 b =>
    (congr_arg _root_.bit1 (add_to_nat a b)).trans <|
      show (a + b + (a + b) + 1 : ℕ) = a + a + 1 + (b + b) by simp [add_comm, add_left_comm]
  | bit1 a, bit1 b =>
    show (succ (a + b) + succ (a + b) : ℕ) = a + a + 1 + (b + b + 1) by
      rw [succ_to_nat, add_to_nat a b]; 

Proof state:
α : Type u_1
a b : PosNum
⊢ ↑a + ↑b + 1 + (↑a + ↑b + 1) = ↑a + ↑a + 1 + (↑b + ↑b + 1)

Next tactic:
simp [add_left_comm]
theorem add_succ : ∀ m n : PosNum, m + succ n = succ (m + n)
  | 1, b => by 

Proof state:
α : Type u_1
b : PosNum
⊢ 1 + succ b = succ (1 + b)

Next tactic:
simp [one_add]
theorem bit0_of_bit0 : ∀ n, _root_.bit0 n = bit0 n
  | 1 => rfl
  | bit0 p => congr_arg bit0 (bit0_of_bit0 p)
  | bit1 p => show bit0 (succ (_root_.bit0 p)) = _ by 

Proof state:
α : Type u_1
p : PosNum
⊢ bit0 (succ (_root_.bit0 p)) = bit0 (bit1 p)

Next tactic:
rw [bit0_of_bit0 p, succ]
theorem bit1_of_bit1 (n : PosNum) : _root_.bit1 n = bit1 n :=
  show _root_.bit0 n + 1 = bit1 n by 

Proof state:
α : Type u_1
n : PosNum
⊢ _root_.bit0 n + 1 = bit1 n

Next tactic:
rw [add_one, bit0_of_bit0, succ]
@[norm_cast]
theorem mul_to_nat (m) : ∀ n, ((m * n : PosNum) : ℕ) = m * n
  | 1 => (mul_one _).symm
  | bit0 p => show (↑(m * p) + ↑(m * p) : ℕ) = ↑m * (p + p) by 

Proof state:
α : Type u_1
m p : PosNum
⊢ ↑(m * p) + ↑(m * p) = ↑m * (↑p + ↑p)

Next tactic:
rw [mul_to_nat m p, left_distrib]
@[norm_cast]
theorem mul_to_nat (m) : ∀ n, ((m * n : PosNum) : ℕ) = m * n
  | 1 => (mul_one _).symm
  | bit0 p => show (↑(m * p) + ↑(m * p) : ℕ) = ↑m * (p + p) by rw [mul_to_nat m p, left_distrib]
  | bit1 p =>
    (add_to_nat (bit0 (m * p)) m).trans <|
      show (↑(m * p) + ↑(m * p) + ↑m : ℕ) = ↑m * (p + p) + m by 

Proof state:
α : Type u_1
m p : PosNum
⊢ ↑(m * p) + ↑(m * p) + ↑m = ↑m * (↑p + ↑p) + ↑m

Next tactic:
rw [mul_to_nat m p, left_distrib]
theorem cmp_to_nat_lemma {m n : PosNum} : (m : ℕ) < n → (bit1 m : ℕ) < bit0 n :=
  show (m : ℕ) < n → (m + m + 1 + 1 : ℕ) ≤ n + n by
    

Proof state:
α : Type u_1
m n : PosNum
⊢ ↑m < ↑n → ↑m + ↑m + 1 + 1 ≤ ↑n + ↑n

Next tactic:
intro h
theorem cmp_to_nat_lemma {m n : PosNum} : (m : ℕ) < n → (bit1 m : ℕ) < bit0 n :=
  show (m : ℕ) < n → (m + m + 1 + 1 : ℕ) ≤ n + n by
    intro h; 

Proof state:
α : Type u_1
m n : PosNum
h : ↑m < ↑n
⊢ ↑m + ↑m + 1 + 1 ≤ ↑n + ↑n

Next tactic:
rw [Nat.add_right_comm m m 1, add_assoc]
theorem cmp_to_nat_lemma {m n : PosNum} : (m : ℕ) < n → (bit1 m : ℕ) < bit0 n :=
  show (m : ℕ) < n → (m + m + 1 + 1 : ℕ) ≤ n + n by
    intro h; rw [Nat.add_right_comm m m 1, add_assoc]; 

Proof state:
α : Type u_1
m n : PosNum
h : ↑m < ↑n
⊢ ↑m + 1 + (↑m + 1) ≤ ↑n + ↑n

Next tactic:
exact add_le_add h h
theorem cmp_swap (m) : ∀ n, (cmp m n).swap = cmp n m := by
  

Proof state:
α : Type u_1
m : PosNum
⊢ ∀ (n : PosNum), Ordering.swap (cmp m n) = cmp n m

Next tactic:
induction' m with m IH m IH
theorem cmp_swap (m) : ∀ n, (cmp m n).swap = cmp n m := by
  induction' m with m IH m IH <;> 

Proof state:
case one
α : Type u_1
⊢ ∀ (n : PosNum), Ordering.swap (cmp one n) = cmp n one

Next tactic:
intro n
theorem cmp_swap (m) : ∀ n, (cmp m n).swap = cmp n m := by
  induction' m with m IH m IH <;> 

Proof state:
case bit1
α : Type u_1
m : PosNum
IH : ∀ (n : PosNum), Ordering.swap (cmp m n) = cmp n m
⊢ ∀ (n : PosNum), Ordering.swap (cmp (bit1 m) n) = cmp n (bit1 m)

Next tactic:
intro n
theorem cmp_swap (m) : ∀ n, (cmp m n).swap = cmp n m := by
  induction' m with m IH m IH <;> 

Proof state:
case bit0
α : Type u_1
m : PosNum
IH : ∀ (n : PosNum), Ordering.swap (cmp m n) = cmp n m
⊢ ∀ (n : PosNum), Ordering.swap (cmp (bit0 m) n) = cmp n (bit0 m)

Next tactic:
intro n
theorem cmp_swap (m) : ∀ n, (cmp m n).swap = cmp n m := by
  induction' m with m IH m IH <;> intro n <;> 

Proof state:
case one
α : Type u_1
n : PosNum
⊢ Ordering.swap (cmp one n) = cmp n one

Next tactic:
cases' n with n n
theorem cmp_swap (m) : ∀ n, (cmp m n).swap = cmp n m := by
  induction' m with m IH m IH <;> intro n <;> 

Proof state:
case bit1
α : Type u_1
m : PosNum
IH : ∀ (n : PosNum), Ordering.swap (cmp m n) = cmp n m
n : PosNum
⊢ Ordering.swap (cmp (bit1 m) n) = cmp n (bit1 m)

Next tactic:
cases' n with n n
theorem cmp_swap (m) : ∀ n, (cmp m n).swap = cmp n m := by
  induction' m with m IH m IH <;> intro n <;> 

Proof state:
case bit0
α : Type u_1
m : PosNum
IH : ∀ (n : PosNum), Ordering.swap (cmp m n) = cmp n m
n : PosNum
⊢ Ordering.swap (cmp (bit0 m) n) = cmp n (bit0 m)

Next tactic:
cases' n with n n
theorem cmp_swap (m) : ∀ n, (cmp m n).swap = cmp n m := by
  induction' m with m IH m IH <;> intro n <;> cases' n with n n <;> 

Proof state:
case one.one
α : Type u_1
⊢ Ordering.swap (cmp one one) = cmp one one

Next tactic:
unfold cmp
theorem cmp_swap (m) : ∀ n, (cmp m n).swap = cmp n m := by
  induction' m with m IH m IH <;> intro n <;> cases' n with n n <;> 

Proof state:
case one.bit1
α : Type u_1
n : PosNum
⊢ Ordering.swap (cmp one (bit1 n)) = cmp (bit1 n) one

Next tactic:
unfold cmp
theorem cmp_swap (m) : ∀ n, (cmp m n).swap = cmp n m := by
  induction' m with m IH m IH <;> intro n <;> cases' n with n n <;> 

Proof state:
case one.bit0
α : Type u_1
n : PosNum
⊢ Ordering.swap (cmp one (bit0 n)) = cmp (bit0 n) one

Next tactic:
unfold cmp
theorem cmp_swap (m) : ∀ n, (cmp m n).swap = cmp n m := by
  induction' m with m IH m IH <;> intro n <;> cases' n with n n <;> 

Proof state:
case bit1.one
α : Type u_1
m : PosNum
IH : ∀ (n : PosNum), Ordering.swap (cmp m n) = cmp n m
⊢ Ordering.swap (cmp (bit1 m) one) = cmp one (bit1 m)

Next tactic:
unfold cmp