l3lab/ntp-mathlib huggingface dataset:
lemma lt_iff_max'_mem {s t : Colex α} :
    s < t ↔ ∃ h : s ≠ t, (ofColex s ∆ ofColex t).max' (max_mem_aux h) ∈ ofColex t := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : LinearOrder α
inst✝ : LinearOrder β
f : α → β
𝒜 𝒜₁ 𝒜₂ : Finset (Finset α)
s✝ t✝ u : Finset α
a b : α
r : ℕ
s t : Colex α
⊢ s < t ↔ ∃ (h : s ≠ t), max' (s.ofColex ∆ t.ofColex) (_ : Finset.Nonempty (s.ofColex ∆ t.ofColex)) ∈ t.ofColex

Next tactic:
rw [lt_iff_le_and_ne, le_iff_max'_mem]
lemma lt_iff_max'_mem {s t : Colex α} :
    s < t ↔ ∃ h : s ≠ t, (ofColex s ∆ ofColex t).max' (max_mem_aux h) ∈ ofColex t := by
  rw [lt_iff_le_and_ne, le_iff_max'_mem]; 

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : LinearOrder α
inst✝ : LinearOrder β
f : α → β
𝒜 𝒜₁ 𝒜₂ : Finset (Finset α)
s✝ t✝ u : Finset α
a b : α
r : ℕ
s t : Colex α
⊢ (∀ (h : s ≠ t), max' (s.ofColex ∆ t.ofColex) (_ : Finset.Nonempty (s.ofColex ∆ t.ofColex)) ∈ t.ofColex) ∧ s ≠ t ↔
    ∃ (h : s ≠ t), max' (s.ofColex ∆ t.ofColex) (_ : Finset.Nonempty (s.ofColex ∆ t.ofColex)) ∈ t.ofColex

Next tactic:
aesop
/-- Strictly monotone functions preserve the colex ordering. -/
lemma toColex_image_le_toColex_image (hf : StrictMono f) :
    toColex (s.image f) ≤ toColex (t.image f) ↔ toColex s ≤ toColex t := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : LinearOrder α
inst✝ : LinearOrder β
f : α → β
𝒜 𝒜₁ 𝒜₂ : Finset (Finset α)
s t u : Finset α
a b : α
r : ℕ
hf : StrictMono f
⊢ { ofColex := image f s } ≤ { ofColex := image f t } ↔ { ofColex := s } ≤ { ofColex := t }

Next tactic:
simp [toColex_le_toColex, hf.le_iff_le, hf.injective.eq_iff]
@[simp] lemma isInitSeg_empty : IsInitSeg (∅ : Finset (Finset α)) r := by 

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : LinearOrder α
inst✝ : LinearOrder β
f : α → β
𝒜 𝒜₁ 𝒜₂ : Finset (Finset α)
s t u : Finset α
a b : α
r : ℕ
⊢ IsInitSeg ∅ r

Next tactic:
simp [IsInitSeg]
/-- Initial segments are nested in some way. In particular, if they're the same size they're equal.
-/
lemma IsInitSeg.total (h₁ : IsInitSeg 𝒜₁ r) (h₂ : IsInitSeg 𝒜₂ r) : 𝒜₁ ⊆ 𝒜₂ ∨ 𝒜₂ ⊆ 𝒜₁ := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : LinearOrder α
inst✝ : LinearOrder β
f : α → β
𝒜 𝒜₁ 𝒜₂ : Finset (Finset α)
s t u : Finset α
a b : α
r : ℕ
h₁ : IsInitSeg 𝒜₁ r
h₂ : IsInitSeg 𝒜₂ r
⊢ 𝒜₁ ⊆ 𝒜₂ ∨ 𝒜₂ ⊆ 𝒜₁

Next tactic:
classical
  simp_rw [← sdiff_eq_empty_iff_subset, ← not_nonempty_iff_eq_empty]
  by_contra! h
  have ⟨⟨s, hs⟩, t, ht⟩ := h
  rw [mem_sdiff] at hs ht
  obtain hst | hst | hts := trichotomous_of (α := Colex α) (· < ·) (toColex s) (toColex t)
  · exact hs.2 <| h₂.2 ht.1 ⟨hst, h₁.1 hs.1⟩
  · simp only [toColex.injEq] at hst
    exact ht.2 <| hst ▸ hs.1
  · exact ht.2 <| h₁.2 hs.1 ⟨hts, h₂.1 ht.1⟩
/-- Initial segments are nested in some way. In particular, if they're the same size they're equal.
-/
lemma IsInitSeg.total (h₁ : IsInitSeg 𝒜₁ r) (h₂ : IsInitSeg 𝒜₂ r) : 𝒜₁ ⊆ 𝒜₂ ∨ 𝒜₂ ⊆ 𝒜₁ := by
  classical
  

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : LinearOrder α
inst✝ : LinearOrder β
f : α → β
𝒜 𝒜₁ 𝒜₂ : Finset (Finset α)
s t u : Finset α
a b : α
r : ℕ
h₁ : IsInitSeg 𝒜₁ r
h₂ : IsInitSeg 𝒜₂ r
⊢ 𝒜₁ ⊆ 𝒜₂ ∨ 𝒜₂ ⊆ 𝒜₁

Next tactic:
simp_rw [← sdiff_eq_empty_iff_subset, ← not_nonempty_iff_eq_empty]
/-- Initial segments are nested in some way. In particular, if they're the same size they're equal.
-/
lemma IsInitSeg.total (h₁ : IsInitSeg 𝒜₁ r) (h₂ : IsInitSeg 𝒜₂ r) : 𝒜₁ ⊆ 𝒜₂ ∨ 𝒜₂ ⊆ 𝒜₁ := by
  classical
  simp_rw [← sdiff_eq_empty_iff_subset, ← not_nonempty_iff_eq_empty]
  

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : LinearOrder α
inst✝ : LinearOrder β
f : α → β
𝒜 𝒜₁ 𝒜₂ : Finset (Finset α)
s t u : Finset α
a b : α
r : ℕ
h₁ : IsInitSeg 𝒜₁ r
h₂ : IsInitSeg 𝒜₂ r
⊢ ¬Finset.Nonempty (𝒜₁ \ 𝒜₂) ∨ ¬Finset.Nonempty (𝒜₂ \ 𝒜₁)

Next tactic:
by_contra! h
/-- Initial segments are nested in some way. In particular, if they're the same size they're equal.
-/
lemma IsInitSeg.total (h₁ : IsInitSeg 𝒜₁ r) (h₂ : IsInitSeg 𝒜₂ r) : 𝒜₁ ⊆ 𝒜₂ ∨ 𝒜₂ ⊆ 𝒜₁ := by
  classical
  simp_rw [← sdiff_eq_empty_iff_subset, ← not_nonempty_iff_eq_empty]
  by_contra! h
  

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : LinearOrder α
inst✝ : LinearOrder β
f : α → β
𝒜 𝒜₁ 𝒜₂ : Finset (Finset α)
s t u : Finset α
a b : α
r : ℕ
h₁ : IsInitSeg 𝒜₁ r
h₂ : IsInitSeg 𝒜₂ r
h : Finset.Nonempty (𝒜₁ \ 𝒜₂) ∧ Finset.Nonempty (𝒜₂ \ 𝒜₁)
⊢ False

Next tactic:
have ⟨⟨s, hs⟩, t, ht⟩ := h
/-- Initial segments are nested in some way. In particular, if they're the same size they're equal.
-/
lemma IsInitSeg.total (h₁ : IsInitSeg 𝒜₁ r) (h₂ : IsInitSeg 𝒜₂ r) : 𝒜₁ ⊆ 𝒜₂ ∨ 𝒜₂ ⊆ 𝒜₁ := by
  classical
  simp_rw [← sdiff_eq_empty_iff_subset, ← not_nonempty_iff_eq_empty]
  by_contra! h
  have ⟨⟨s, hs⟩, t, ht⟩ := h
  

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : LinearOrder α
inst✝ : LinearOrder β
f : α → β
𝒜 𝒜₁ 𝒜₂ : Finset (Finset α)
s✝ t✝ u : Finset α
a b : α
r : ℕ
h₁ : IsInitSeg 𝒜₁ r
h₂ : IsInitSeg 𝒜₂ r
h : Finset.Nonempty (𝒜₁ \ 𝒜₂) ∧ Finset.Nonempty (𝒜₂ \ 𝒜₁)
s : Finset α
hs : s ∈ 𝒜₁ \ 𝒜₂
t : Finset α
ht : t ∈ 𝒜₂ \ 𝒜₁
⊢ False

Next tactic:
rw [mem_sdiff] at hs ht
/-- Initial segments are nested in some way. In particular, if they're the same size they're equal.
-/
lemma IsInitSeg.total (h₁ : IsInitSeg 𝒜₁ r) (h₂ : IsInitSeg 𝒜₂ r) : 𝒜₁ ⊆ 𝒜₂ ∨ 𝒜₂ ⊆ 𝒜₁ := by
  classical
  simp_rw [← sdiff_eq_empty_iff_subset, ← not_nonempty_iff_eq_empty]
  by_contra! h
  have ⟨⟨s, hs⟩, t, ht⟩ := h
  rw [mem_sdiff] at hs ht
  

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : LinearOrder α
inst✝ : LinearOrder β
f : α → β
𝒜 𝒜₁ 𝒜₂ : Finset (Finset α)
s✝ t✝ u : Finset α
a b : α
r : ℕ
h₁ : IsInitSeg 𝒜₁ r
h₂ : IsInitSeg 𝒜₂ r
h : Finset.Nonempty (𝒜₁ \ 𝒜₂) ∧ Finset.Nonempty (𝒜₂ \ 𝒜₁)
s : Finset α
hs : s ∈ 𝒜₁ ∧ s ∉ 𝒜₂
t : Finset α
ht : t ∈ 𝒜₂ ∧ t ∉ 𝒜₁
⊢ False

Next tactic:
obtain hst | hst | hts := trichotomous_of (α := Colex α) (· < ·) (toColex s) (toColex t)
/-- Initial segments are nested in some way. In particular, if they're the same size they're equal.
-/
lemma IsInitSeg.total (h₁ : IsInitSeg 𝒜₁ r) (h₂ : IsInitSeg 𝒜₂ r) : 𝒜₁ ⊆ 𝒜₂ ∨ 𝒜₂ ⊆ 𝒜₁ := by
  classical
  simp_rw [← sdiff_eq_empty_iff_subset, ← not_nonempty_iff_eq_empty]
  by_contra! h
  have ⟨⟨s, hs⟩, t, ht⟩ := h
  rw [mem_sdiff] at hs ht
  obtain hst | hst | hts := trichotomous_of (α := Colex α) (· < ·) (toColex s) (toColex t)
  · 

Proof state:
case inl
α : Type u_1
β : Type u_2
inst✝¹ : LinearOrder α
inst✝ : LinearOrder β
f : α → β
𝒜 𝒜₁ 𝒜₂ : Finset (Finset α)
s✝ t✝ u : Finset α
a b : α
r : ℕ
h₁ : IsInitSeg 𝒜₁ r
h₂ : IsInitSeg 𝒜₂ r
h : Finset.Nonempty (𝒜₁ \ 𝒜₂) ∧ Finset.Nonempty (𝒜₂ \ 𝒜₁)
s : Finset α
hs : s ∈ 𝒜₁ ∧ s ∉ 𝒜₂
t : Finset α
ht : t ∈ 𝒜₂ ∧ t ∉ 𝒜₁
hst : { ofColex := s } < { ofColex := t }
⊢ False

Next tactic:
exact hs.2 <| h₂.2 ht.1 ⟨hst, h₁.1 hs.1⟩
/-- Initial segments are nested in some way. In particular, if they're the same size they're equal.
-/
lemma IsInitSeg.total (h₁ : IsInitSeg 𝒜₁ r) (h₂ : IsInitSeg 𝒜₂ r) : 𝒜₁ ⊆ 𝒜₂ ∨ 𝒜₂ ⊆ 𝒜₁ := by
  classical
  simp_rw [← sdiff_eq_empty_iff_subset, ← not_nonempty_iff_eq_empty]
  by_contra! h
  have ⟨⟨s, hs⟩, t, ht⟩ := h
  rw [mem_sdiff] at hs ht
  obtain hst | hst | hts := trichotomous_of (α := Colex α) (· < ·) (toColex s) (toColex t)
  · exact hs.2 <| h₂.2 ht.1 ⟨hst, h₁.1 hs.1⟩
  · 

Proof state:
case inr.inl
α : Type u_1
β : Type u_2
inst✝¹ : LinearOrder α
inst✝ : LinearOrder β
f : α → β
𝒜 𝒜₁ 𝒜₂ : Finset (Finset α)
s✝ t✝ u : Finset α
a b : α
r : ℕ
h₁ : IsInitSeg 𝒜₁ r
h₂ : IsInitSeg 𝒜₂ r
h : Finset.Nonempty (𝒜₁ \ 𝒜₂) ∧ Finset.Nonempty (𝒜₂ \ 𝒜₁)
s : Finset α
hs : s ∈ 𝒜₁ ∧ s ∉ 𝒜₂
t : Finset α
ht : t ∈ 𝒜₂ ∧ t ∉ 𝒜₁
hst : { ofColex := s } = { ofColex := t }
⊢ False

Next tactic:
simp only [toColex.injEq] at hst
/-- Initial segments are nested in some way. In particular, if they're the same size they're equal.
-/
lemma IsInitSeg.total (h₁ : IsInitSeg 𝒜₁ r) (h₂ : IsInitSeg 𝒜₂ r) : 𝒜₁ ⊆ 𝒜₂ ∨ 𝒜₂ ⊆ 𝒜₁ := by
  classical
  simp_rw [← sdiff_eq_empty_iff_subset, ← not_nonempty_iff_eq_empty]
  by_contra! h
  have ⟨⟨s, hs⟩, t, ht⟩ := h
  rw [mem_sdiff] at hs ht
  obtain hst | hst | hts := trichotomous_of (α := Colex α) (· < ·) (toColex s) (toColex t)
  · exact hs.2 <| h₂.2 ht.1 ⟨hst, h₁.1 hs.1⟩
  · simp only [toColex.injEq] at hst
    

Proof state:
case inr.inl
α : Type u_1
β : Type u_2
inst✝¹ : LinearOrder α
inst✝ : LinearOrder β
f : α → β
𝒜 𝒜₁ 𝒜₂ : Finset (Finset α)
s✝ t✝ u : Finset α
a b : α
r : ℕ
h₁ : IsInitSeg 𝒜₁ r
h₂ : IsInitSeg 𝒜₂ r
h : Finset.Nonempty (𝒜₁ \ 𝒜₂) ∧ Finset.Nonempty (𝒜₂ \ 𝒜₁)
s : Finset α
hs : s ∈ 𝒜₁ ∧ s ∉ 𝒜₂
t : Finset α
ht : t ∈ 𝒜₂ ∧ t ∉ 𝒜₁
hst : s = t
⊢ False

Next tactic:
exact ht.2 <| hst ▸ hs.1
/-- Initial segments are nested in some way. In particular, if they're the same size they're equal.
-/
lemma IsInitSeg.total (h₁ : IsInitSeg 𝒜₁ r) (h₂ : IsInitSeg 𝒜₂ r) : 𝒜₁ ⊆ 𝒜₂ ∨ 𝒜₂ ⊆ 𝒜₁ := by
  classical
  simp_rw [← sdiff_eq_empty_iff_subset, ← not_nonempty_iff_eq_empty]
  by_contra! h
  have ⟨⟨s, hs⟩, t, ht⟩ := h
  rw [mem_sdiff] at hs ht
  obtain hst | hst | hts := trichotomous_of (α := Colex α) (· < ·) (toColex s) (toColex t)
  · exact hs.2 <| h₂.2 ht.1 ⟨hst, h₁.1 hs.1⟩
  · simp only [toColex.injEq] at hst
    exact ht.2 <| hst ▸ hs.1
  · 

Proof state:
case inr.inr
α : Type u_1
β : Type u_2
inst✝¹ : LinearOrder α
inst✝ : LinearOrder β
f : α → β
𝒜 𝒜₁ 𝒜₂ : Finset (Finset α)
s✝ t✝ u : Finset α
a b : α
r : ℕ
h₁ : IsInitSeg 𝒜₁ r
h₂ : IsInitSeg 𝒜₂ r
h : Finset.Nonempty (𝒜₁ \ 𝒜₂) ∧ Finset.Nonempty (𝒜₂ \ 𝒜₁)
s : Finset α
hs : s ∈ 𝒜₁ ∧ s ∉ 𝒜₂
t : Finset α
ht : t ∈ 𝒜₂ ∧ t ∉ 𝒜₁
hts : { ofColex := t } < { ofColex := s }
⊢ False

Next tactic:
exact ht.2 <| h₁.2 hs.1 ⟨hts, h₂.1 ht.1⟩
@[simp]
lemma mem_initSeg : t ∈ initSeg s ↔ s.card = t.card ∧ toColex t ≤ toColex s := by 

Proof state:
α : Type u_1
β : Type u_2
inst✝² : LinearOrder α
inst✝¹ : LinearOrder β
f : α → β
𝒜 𝒜₁ 𝒜₂ : Finset (Finset α)
s t u : Finset α
a b : α
r : ℕ
inst✝ : Fintype α
⊢ t ∈ initSeg s ↔ card s = card t ∧ { ofColex := t } ≤ { ofColex := s }

Next tactic:
simp [initSeg]
lemma mem_initSeg_self : s ∈ initSeg s := by 

Proof state:
α : Type u_1
β : Type u_2
inst✝² : LinearOrder α
inst✝¹ : LinearOrder β
f : α → β
𝒜 𝒜₁ 𝒜₂ : Finset (Finset α)
s t u : Finset α
a b : α
r : ℕ
inst✝ : Fintype α
⊢ s ∈ initSeg s

Next tactic:
simp
lemma isInitSeg_initSeg : IsInitSeg (initSeg s) s.card := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝² : LinearOrder α
inst✝¹ : LinearOrder β
f : α → β
𝒜 𝒜₁ 𝒜₂ : Finset (Finset α)
s t u : Finset α
a b : α
r : ℕ
inst✝ : Fintype α
⊢ IsInitSeg (initSeg s) (card s)

Next tactic:
refine ⟨fun t ht => (mem_initSeg.1 ht).1.symm, fun t₁ t₂ ht₁ ht₂ ↦ mem_initSeg.2 ⟨ht₂.2.symm, ?_⟩⟩
lemma isInitSeg_initSeg : IsInitSeg (initSeg s) s.card := by
  refine ⟨fun t ht => (mem_initSeg.1 ht).1.symm, fun t₁ t₂ ht₁ ht₂ ↦ mem_initSeg.2 ⟨ht₂.2.symm, ?_⟩⟩
  

Proof state:
α : Type u_1
β : Type u_2
inst✝² : LinearOrder α
inst✝¹ : LinearOrder β
f : α → β
𝒜 𝒜₁ 𝒜₂ : Finset (Finset α)
s t u : Finset α
a b : α
r : ℕ
inst✝ : Fintype α
t₁ t₂ : Finset α
ht₁ : t₁ ∈ initSeg s
ht₂ : { ofColex := t₂ } < { ofColex := t₁ } ∧ card t₂ = card s
⊢ { ofColex := t₂ } ≤ { ofColex := s }

Next tactic:
rw [mem_initSeg] at ht₁
lemma isInitSeg_initSeg : IsInitSeg (initSeg s) s.card := by
  refine ⟨fun t ht => (mem_initSeg.1 ht).1.symm, fun t₁ t₂ ht₁ ht₂ ↦ mem_initSeg.2 ⟨ht₂.2.symm, ?_⟩⟩
  rw [mem_initSeg] at ht₁
  

Proof state:
α : Type u_1
β : Type u_2
inst✝² : LinearOrder α
inst✝¹ : LinearOrder β
f : α → β
𝒜 𝒜₁ 𝒜₂ : Finset (Finset α)
s t u : Finset α
a b : α
r : ℕ
inst✝ : Fintype α
t₁ t₂ : Finset α
ht₁ : card s = card t₁ ∧ { ofColex := t₁ } ≤ { ofColex := s }
ht₂ : { ofColex := t₂ } < { ofColex := t₁ } ∧ card t₂ = card s
⊢ { ofColex := t₂ } ≤ { ofColex := s }

Next tactic:
exact ht₂.1.le.trans ht₁.2
lemma IsInitSeg.exists_initSeg (h𝒜 : IsInitSeg 𝒜 r) (h𝒜₀ : 𝒜.Nonempty) :
    ∃ s : Finset α, s.card = r ∧ 𝒜 = initSeg s := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝² : LinearOrder α
inst✝¹ : LinearOrder β
f : α → β
𝒜 𝒜₁ 𝒜₂ : Finset (Finset α)
s t u : Finset α
a b : α
r : ℕ
inst✝ : Fintype α
h𝒜 : IsInitSeg 𝒜 r
h𝒜₀ : Finset.Nonempty 𝒜
⊢ ∃ s, card s = r ∧ 𝒜 = initSeg s

Next tactic:
have hs := sup'_mem (ofColex ⁻¹' 𝒜) (LinearOrder.supClosed _) 𝒜 h𝒜₀ toColex
    (fun a ha ↦ by simpa using ha)
lemma IsInitSeg.exists_initSeg (h𝒜 : IsInitSeg 𝒜 r) (h𝒜₀ : 𝒜.Nonempty) :
    ∃ s : Finset α, s.card = r ∧ 𝒜 = initSeg s := by
  have hs := sup'_mem (ofColex ⁻¹' 𝒜) (LinearOrder.supClosed _) 𝒜 h𝒜₀ toColex
    (fun a ha ↦ by 

Proof state:
α : Type u_1
β : Type u_2
inst✝² : LinearOrder α
inst✝¹ : LinearOrder β
f : α → β
𝒜 𝒜₁ 𝒜₂ : Finset (Finset α)
s t u : Finset α
a✝ b : α
r : ℕ
inst✝ : Fintype α
h𝒜 : IsInitSeg 𝒜 r
h𝒜₀ : Finset.Nonempty 𝒜
a : Finset α
ha : a ∈ 𝒜
⊢ { ofColex := a } ∈ ofColex ⁻¹' ↑𝒜

Next tactic:
simpa using ha
lemma IsInitSeg.exists_initSeg (h𝒜 : IsInitSeg 𝒜 r) (h𝒜₀ : 𝒜.Nonempty) :
    ∃ s : Finset α, s.card = r ∧ 𝒜 = initSeg s := by
  have hs := sup'_mem (ofColex ⁻¹' 𝒜) (LinearOrder.supClosed _) 𝒜 h𝒜₀ toColex
    (fun a ha ↦ by simpa using ha)
  

Proof state:
α : Type u_1
β : Type u_2
inst✝² : LinearOrder α
inst✝¹ : LinearOrder β
f : α → β
𝒜 𝒜₁ 𝒜₂ : Finset (Finset α)
s t u : Finset α
a b : α
r : ℕ
inst✝ : Fintype α
h𝒜 : IsInitSeg 𝒜 r
h𝒜₀ : Finset.Nonempty 𝒜
hs : sup' 𝒜 h𝒜₀ toColex ∈ ofColex ⁻¹' ↑𝒜
⊢ ∃ s, card s = r ∧ 𝒜 = initSeg s

Next tactic:
refine' ⟨_, h𝒜.1 hs, _⟩
lemma IsInitSeg.exists_initSeg (h𝒜 : IsInitSeg 𝒜 r) (h𝒜₀ : 𝒜.Nonempty) :
    ∃ s : Finset α, s.card = r ∧ 𝒜 = initSeg s := by
  have hs := sup'_mem (ofColex ⁻¹' 𝒜) (LinearOrder.supClosed _) 𝒜 h𝒜₀ toColex
    (fun a ha ↦ by simpa using ha)
  refine' ⟨_, h𝒜.1 hs, _⟩
  

Proof state:
α : Type u_1
β : Type u_2
inst✝² : LinearOrder α
inst✝¹ : LinearOrder β
f : α → β
𝒜 𝒜₁ 𝒜₂ : Finset (Finset α)
s t u : Finset α
a b : α
r : ℕ
inst✝ : Fintype α
h𝒜 : IsInitSeg 𝒜 r
h𝒜₀ : Finset.Nonempty 𝒜
hs : sup' 𝒜 h𝒜₀ toColex ∈ ofColex ⁻¹' ↑𝒜
⊢ 𝒜 = initSeg (sup' 𝒜 h𝒜₀ toColex).ofColex

Next tactic:
ext t
lemma IsInitSeg.exists_initSeg (h𝒜 : IsInitSeg 𝒜 r) (h𝒜₀ : 𝒜.Nonempty) :
    ∃ s : Finset α, s.card = r ∧ 𝒜 = initSeg s := by
  have hs := sup'_mem (ofColex ⁻¹' 𝒜) (LinearOrder.supClosed _) 𝒜 h𝒜₀ toColex
    (fun a ha ↦ by simpa using ha)
  refine' ⟨_, h𝒜.1 hs, _⟩
  ext t
  

Proof state:
case a
α : Type u_1
β : Type u_2
inst✝² : LinearOrder α
inst✝¹ : LinearOrder β
f : α → β
𝒜 𝒜₁ 𝒜₂ : Finset (Finset α)
s t✝ u : Finset α
a b : α
r : ℕ
inst✝ : Fintype α
h𝒜 : IsInitSeg 𝒜 r
h𝒜₀ : Finset.Nonempty 𝒜
hs : sup' 𝒜 h𝒜₀ toColex ∈ ofColex ⁻¹' ↑𝒜
t : Finset α
⊢ t ∈ 𝒜 ↔ t ∈ initSeg (sup' 𝒜 h𝒜₀ toColex).ofColex

Next tactic:
rw [mem_initSeg]
lemma IsInitSeg.exists_initSeg (h𝒜 : IsInitSeg 𝒜 r) (h𝒜₀ : 𝒜.Nonempty) :
    ∃ s : Finset α, s.card = r ∧ 𝒜 = initSeg s := by
  have hs := sup'_mem (ofColex ⁻¹' 𝒜) (LinearOrder.supClosed _) 𝒜 h𝒜₀ toColex
    (fun a ha ↦ by simpa using ha)
  refine' ⟨_, h𝒜.1 hs, _⟩
  ext t
  rw [mem_initSeg]
  

Proof state:
case a
α : Type u_1
β : Type u_2
inst✝² : LinearOrder α
inst✝¹ : LinearOrder β
f : α → β
𝒜 𝒜₁ 𝒜₂ : Finset (Finset α)
s t✝ u : Finset α
a b : α
r : ℕ
inst✝ : Fintype α
h𝒜 : IsInitSeg 𝒜 r
h𝒜₀ : Finset.Nonempty 𝒜
hs : sup' 𝒜 h𝒜₀ toColex ∈ ofColex ⁻¹' ↑𝒜
t : Finset α
⊢ t ∈ 𝒜 ↔ card (sup' 𝒜 h𝒜₀ toColex).ofColex = card t ∧ { ofColex := t } ≤ { ofColex := (sup' 𝒜 h𝒜₀ toColex).ofColex }

Next tactic:
refine' ⟨fun p ↦ _, _⟩
lemma IsInitSeg.exists_initSeg (h𝒜 : IsInitSeg 𝒜 r) (h𝒜₀ : 𝒜.Nonempty) :
    ∃ s : Finset α, s.card = r ∧ 𝒜 = initSeg s := by
  have hs := sup'_mem (ofColex ⁻¹' 𝒜) (LinearOrder.supClosed _) 𝒜 h𝒜₀ toColex
    (fun a ha ↦ by simpa using ha)
  refine' ⟨_, h𝒜.1 hs, _⟩
  ext t
  rw [mem_initSeg]
  refine' ⟨fun p ↦ _, _⟩
  · 

Proof state:
case a.refine'_1
α : Type u_1
β : Type u_2
inst✝² : LinearOrder α
inst✝¹ : LinearOrder β
f : α → β
𝒜 𝒜₁ 𝒜₂ : Finset (Finset α)
s t✝ u : Finset α
a b : α
r : ℕ
inst✝ : Fintype α
h𝒜 : IsInitSeg 𝒜 r
h𝒜₀ : Finset.Nonempty 𝒜
hs : sup' 𝒜 h𝒜₀ toColex ∈ ofColex ⁻¹' ↑𝒜
t : Finset α
p : t ∈ 𝒜
⊢ card (sup' 𝒜 h𝒜₀ toColex).ofColex = card t ∧ { ofColex := t } ≤ { ofColex := (sup' 𝒜 h𝒜₀ toColex).ofColex }

Next tactic:
rw [h𝒜.1 p, h𝒜.1 hs]
lemma IsInitSeg.exists_initSeg (h𝒜 : IsInitSeg 𝒜 r) (h𝒜₀ : 𝒜.Nonempty) :
    ∃ s : Finset α, s.card = r ∧ 𝒜 = initSeg s := by
  have hs := sup'_mem (ofColex ⁻¹' 𝒜) (LinearOrder.supClosed _) 𝒜 h𝒜₀ toColex
    (fun a ha ↦ by simpa using ha)
  refine' ⟨_, h𝒜.1 hs, _⟩
  ext t
  rw [mem_initSeg]
  refine' ⟨fun p ↦ _, _⟩
  · rw [h𝒜.1 p, h𝒜.1 hs]
    

Proof state:
case a.refine'_1
α : Type u_1
β : Type u_2
inst✝² : LinearOrder α
inst✝¹ : LinearOrder β
f : α → β
𝒜 𝒜₁ 𝒜₂ : Finset (Finset α)
s t✝ u : Finset α
a b : α
r : ℕ
inst✝ : Fintype α
h𝒜 : IsInitSeg 𝒜 r
h𝒜₀ : Finset.Nonempty 𝒜
hs : sup' 𝒜 h𝒜₀ toColex ∈ ofColex ⁻¹' ↑𝒜
t : Finset α
p : t ∈ 𝒜
⊢ r = r ∧ { ofColex := t } ≤ { ofColex := (sup' 𝒜 h𝒜₀ toColex).ofColex }

Next tactic:
exact ⟨rfl, le_sup' _ p⟩
lemma IsInitSeg.exists_initSeg (h𝒜 : IsInitSeg 𝒜 r) (h𝒜₀ : 𝒜.Nonempty) :
    ∃ s : Finset α, s.card = r ∧ 𝒜 = initSeg s := by
  have hs := sup'_mem (ofColex ⁻¹' 𝒜) (LinearOrder.supClosed _) 𝒜 h𝒜₀ toColex
    (fun a ha ↦ by simpa using ha)
  refine' ⟨_, h𝒜.1 hs, _⟩
  ext t
  rw [mem_initSeg]
  refine' ⟨fun p ↦ _, _⟩
  · rw [h𝒜.1 p, h𝒜.1 hs]
    exact ⟨rfl, le_sup' _ p⟩
  

Proof state:
case a.refine'_2
α : Type u_1
β : Type u_2
inst✝² : LinearOrder α
inst✝¹ : LinearOrder β
f : α → β
𝒜 𝒜₁ 𝒜₂ : Finset (Finset α)
s t✝ u : Finset α
a b : α
r : ℕ
inst✝ : Fintype α
h𝒜 : IsInitSeg 𝒜 r
h𝒜₀ : Finset.Nonempty 𝒜
hs : sup' 𝒜 h𝒜₀ toColex ∈ ofColex ⁻¹' ↑𝒜
t : Finset α
⊢ card (sup' 𝒜 h𝒜₀ toColex).ofColex = card t ∧ { ofColex := t } ≤ { ofColex := (sup' 𝒜 h𝒜₀ toColex).ofColex } → t ∈ 𝒜

Next tactic:
rintro ⟨cards, le⟩
lemma IsInitSeg.exists_initSeg (h𝒜 : IsInitSeg 𝒜 r) (h𝒜₀ : 𝒜.Nonempty) :
    ∃ s : Finset α, s.card = r ∧ 𝒜 = initSeg s := by
  have hs := sup'_mem (ofColex ⁻¹' 𝒜) (LinearOrder.supClosed _) 𝒜 h𝒜₀ toColex
    (fun a ha ↦ by simpa using ha)
  refine' ⟨_, h𝒜.1 hs, _⟩
  ext t
  rw [mem_initSeg]
  refine' ⟨fun p ↦ _, _⟩
  · rw [h𝒜.1 p, h𝒜.1 hs]
    exact ⟨rfl, le_sup' _ p⟩
  rintro ⟨cards, le⟩
  

Proof state:
case a.refine'_2.intro
α : Type u_1
β : Type u_2
inst✝² : LinearOrder α
inst✝¹ : LinearOrder β
f : α → β
𝒜 𝒜₁ 𝒜₂ : Finset (Finset α)
s t✝ u : Finset α
a b : α
r : ℕ
inst✝ : Fintype α
h𝒜 : IsInitSeg 𝒜 r
h𝒜₀ : Finset.Nonempty 𝒜
hs : sup' 𝒜 h𝒜₀ toColex ∈ ofColex ⁻¹' ↑𝒜
t : Finset α
cards : card (sup' 𝒜 h𝒜₀ toColex).ofColex = card t
le : { ofColex := t } ≤ { ofColex := (sup' 𝒜 h𝒜₀ toColex).ofColex }
⊢ t ∈ 𝒜

Next tactic:
obtain p | p := le.eq_or_lt
lemma IsInitSeg.exists_initSeg (h𝒜 : IsInitSeg 𝒜 r) (h𝒜₀ : 𝒜.Nonempty) :
    ∃ s : Finset α, s.card = r ∧ 𝒜 = initSeg s := by
  have hs := sup'_mem (ofColex ⁻¹' 𝒜) (LinearOrder.supClosed _) 𝒜 h𝒜₀ toColex
    (fun a ha ↦ by simpa using ha)
  refine' ⟨_, h𝒜.1 hs, _⟩
  ext t
  rw [mem_initSeg]
  refine' ⟨fun p ↦ _, _⟩
  · rw [h𝒜.1 p, h𝒜.1 hs]
    exact ⟨rfl, le_sup' _ p⟩
  rintro ⟨cards, le⟩
  obtain p | p := le.eq_or_lt
  · 

Proof state:
case a.refine'_2.intro.inl
α : Type u_1
β : Type u_2
inst✝² : LinearOrder α
inst✝¹ : LinearOrder β
f : α → β
𝒜 𝒜₁ 𝒜₂ : Finset (Finset α)
s t✝ u : Finset α
a b : α
r : ℕ
inst✝ : Fintype α
h𝒜 : IsInitSeg 𝒜 r
h𝒜₀ : Finset.Nonempty 𝒜
hs : sup' 𝒜 h𝒜₀ toColex ∈ ofColex ⁻¹' ↑𝒜
t : Finset α
cards : card (sup' 𝒜 h𝒜₀ toColex).ofColex = card t
le : { ofColex := t } ≤ { ofColex := (sup' 𝒜 h𝒜₀ toColex).ofColex }
p : { ofColex := t } = { ofColex := (sup' 𝒜 h𝒜₀ toColex).ofColex }
⊢ t ∈ 𝒜

Next tactic:
rwa [toColex_inj.1 p]
lemma IsInitSeg.exists_initSeg (h𝒜 : IsInitSeg 𝒜 r) (h𝒜₀ : 𝒜.Nonempty) :
    ∃ s : Finset α, s.card = r ∧ 𝒜 = initSeg s := by
  have hs := sup'_mem (ofColex ⁻¹' 𝒜) (LinearOrder.supClosed _) 𝒜 h𝒜₀ toColex
    (fun a ha ↦ by simpa using ha)
  refine' ⟨_, h𝒜.1 hs, _⟩
  ext t
  rw [mem_initSeg]
  refine' ⟨fun p ↦ _, _⟩
  · rw [h𝒜.1 p, h𝒜.1 hs]
    exact ⟨rfl, le_sup' _ p⟩
  rintro ⟨cards, le⟩
  obtain p | p := le.eq_or_lt
  · rwa [toColex_inj.1 p]
  · 

Proof state:
case a.refine'_2.intro.inr
α : Type u_1
β : Type u_2
inst✝² : LinearOrder α
inst✝¹ : LinearOrder β
f : α → β
𝒜 𝒜₁ 𝒜₂ : Finset (Finset α)
s t✝ u : Finset α
a b : α
r : ℕ
inst✝ : Fintype α
h𝒜 : IsInitSeg 𝒜 r
h𝒜₀ : Finset.Nonempty 𝒜
hs : sup' 𝒜 h𝒜₀ toColex ∈ ofColex ⁻¹' ↑𝒜
t : Finset α
cards : card (sup' 𝒜 h𝒜₀ toColex).ofColex = card t
le : { ofColex := t } ≤ { ofColex := (sup' 𝒜 h𝒜₀ toColex).ofColex }
p : { ofColex := t } < { ofColex := (sup' 𝒜 h𝒜₀ toColex).ofColex }
⊢ t ∈ 𝒜

Next tactic:
exact h𝒜.2 hs ⟨p, cards ▸ h𝒜.1 hs⟩
/-- Being a nonempty initial segment of colex is equivalent to being an `initSeg`. -/
lemma isInitSeg_iff_exists_initSeg :
    IsInitSeg 𝒜 r ∧ 𝒜.Nonempty ↔ ∃ s : Finset α, s.card = r ∧ 𝒜 = initSeg s := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝² : LinearOrder α
inst✝¹ : LinearOrder β
f : α → β
𝒜 𝒜₁ 𝒜₂ : Finset (Finset α)
s t u : Finset α
a b : α
r : ℕ
inst✝ : Fintype α
⊢ IsInitSeg 𝒜 r ∧ Finset.Nonempty 𝒜 ↔ ∃ s, card s = r ∧ 𝒜 = initSeg s

Next tactic:
refine ⟨fun h𝒜 ↦ h𝒜.1.exists_initSeg h𝒜.2, ?_⟩
/-- Being a nonempty initial segment of colex is equivalent to being an `initSeg`. -/
lemma isInitSeg_iff_exists_initSeg :
    IsInitSeg 𝒜 r ∧ 𝒜.Nonempty ↔ ∃ s : Finset α, s.card = r ∧ 𝒜 = initSeg s := by
  refine ⟨fun h𝒜 ↦ h𝒜.1.exists_initSeg h𝒜.2, ?_⟩
  

Proof state:
α : Type u_1
β : Type u_2
inst✝² : LinearOrder α
inst✝¹ : LinearOrder β
f : α → β
𝒜 𝒜₁ 𝒜₂ : Finset (Finset α)
s t u : Finset α
a b : α
r : ℕ
inst✝ : Fintype α
⊢ (∃ s, card s = r ∧ 𝒜 = initSeg s) → IsInitSeg 𝒜 r ∧ Finset.Nonempty 𝒜

Next tactic:
rintro ⟨s, rfl, rfl⟩
/-- Being a nonempty initial segment of colex is equivalent to being an `initSeg`. -/
lemma isInitSeg_iff_exists_initSeg :
    IsInitSeg 𝒜 r ∧ 𝒜.Nonempty ↔ ∃ s : Finset α, s.card = r ∧ 𝒜 = initSeg s := by
  refine ⟨fun h𝒜 ↦ h𝒜.1.exists_initSeg h𝒜.2, ?_⟩
  rintro ⟨s, rfl, rfl⟩
  

Proof state:
case intro.intro
α : Type u_1
β : Type u_2
inst✝² : LinearOrder α
inst✝¹ : LinearOrder β
f : α → β
𝒜₁ 𝒜₂ : Finset (Finset α)
s✝ t u : Finset α
a b : α
inst✝ : Fintype α
s : Finset α
⊢ IsInitSeg (initSeg s) (card s) ∧ Finset.Nonempty (initSeg s)

Next tactic:
exact ⟨isInitSeg_initSeg, initSeg_nonempty⟩
lemma geomSum_ofColex_strictMono (hn : 2 ≤ n) : StrictMono fun s ↦ ∑ k in ofColex s, n ^ k := by
  

Proof state:
α : Type u_1
β : Type u_2
s t : Finset ℕ
n : ℕ
hn : 2 ≤ n
⊢ StrictMono fun s => ∑ k in s.ofColex, n ^ k

Next tactic:
rintro ⟨s⟩ ⟨t⟩ hst
lemma geomSum_ofColex_strictMono (hn : 2 ≤ n) : StrictMono fun s ↦ ∑ k in ofColex s, n ^ k := by
  rintro ⟨s⟩ ⟨t⟩ hst
  

Proof state:
case toColex.toColex
α : Type u_1
β : Type u_2
s✝ t✝ : Finset ℕ
n : ℕ
hn : 2 ≤ n
s t : Finset ℕ
hst : { ofColex := s } < { ofColex := t }
⊢ (fun s => ∑ k in s.ofColex, n ^ k) { ofColex := s } < (fun s => ∑ k in s.ofColex, n ^ k) { ofColex := t }

Next tactic:
rw [toColex_lt_toColex_iff_exists_forall_lt] at hst
lemma geomSum_ofColex_strictMono (hn : 2 ≤ n) : StrictMono fun s ↦ ∑ k in ofColex s, n ^ k := by
  rintro ⟨s⟩ ⟨t⟩ hst
  rw [toColex_lt_toColex_iff_exists_forall_lt] at hst
  

Proof state:
case toColex.toColex
α : Type u_1
β : Type u_2
s✝ t✝ : Finset ℕ
n : ℕ
hn : 2 ≤ n
s t : Finset ℕ
hst : ∃ a ∈ t, a ∉ s ∧ ∀ b ∈ s, b ∉ t → b < a
⊢ (fun s => ∑ k in s.ofColex, n ^ k) { ofColex := s } < (fun s => ∑ k in s.ofColex, n ^ k) { ofColex := t }

Next tactic:
obtain ⟨a, hat, has, ha⟩ := hst
lemma geomSum_ofColex_strictMono (hn : 2 ≤ n) : StrictMono fun s ↦ ∑ k in ofColex s, n ^ k := by
  rintro ⟨s⟩ ⟨t⟩ hst
  rw [toColex_lt_toColex_iff_exists_forall_lt] at hst
  obtain ⟨a, hat, has, ha⟩ := hst
  

Proof state:
case toColex.toColex.intro.intro.intro
α : Type u_1
β : Type u_2
s✝ t✝ : Finset ℕ
n : ℕ
hn : 2 ≤ n
s t : Finset ℕ
a : ℕ
hat : a ∈ t
has : a ∉ s
ha : ∀ b ∈ s, b ∉ t → b < a
⊢ (fun s => ∑ k in s.ofColex, n ^ k) { ofColex := s } < (fun s => ∑ k in s.ofColex, n ^ k) { ofColex := t }

Next tactic:
rw [← sum_sdiff_lt_sum_sdiff]
lemma geomSum_ofColex_strictMono (hn : 2 ≤ n) : StrictMono fun s ↦ ∑ k in ofColex s, n ^ k := by
  rintro ⟨s⟩ ⟨t⟩ hst
  rw [toColex_lt_toColex_iff_exists_forall_lt] at hst
  obtain ⟨a, hat, has, ha⟩ := hst
  rw [← sum_sdiff_lt_sum_sdiff]
  

Proof state:
case toColex.toColex.intro.intro.intro
α : Type u_1
β : Type u_2
s✝ t✝ : Finset ℕ
n : ℕ
hn : 2 ≤ n
s t : Finset ℕ
a : ℕ
hat : a ∈ t
has : a ∉ s
ha : ∀ b ∈ s, b ∉ t → b < a
⊢ ∑ i in { ofColex := s }.ofColex \ { ofColex := t }.ofColex, n ^ i <
    ∑ i in { ofColex := t }.ofColex \ { ofColex := s }.ofColex, n ^ i

Next tactic:
exact (Nat.geomSum_lt hn $ by simpa).trans_le <| single_le_sum (fun _ _ ↦ by positivity) <|
    mem_sdiff.2 ⟨hat, has⟩