l3lab/ntp-mathlib huggingface dataset:
theorem chainHeight_insert_of_forall_gt (a : α) (hx : ∀ b ∈ s, a < b) :
    (insert a s).chainHeight = s.chainHeight + 1 := by
  rw [← add_zero (insert a s).chainHeight]
  change (insert a s).chainHeight + (0 : ℕ) = s.chainHeight + (1 : ℕ)
  apply le_antisymm <;> rw [chainHeight_add_le_chainHeight_add]
  · rintro (_ | ⟨y, ys⟩) h
    · exact ⟨[], nil_mem_subchain _, zero_le _⟩
    · have h' := cons_mem_subchain_iff.mp h
      refine' ⟨ys, ⟨h'.2.1.1, fun i hi ↦ _⟩, by simp⟩
      apply (h'.2.1.2 i hi).resolve_left
      rintro rfl
      cases' chain'_iff_pairwise.mp h.1 with _ _ hy
      

Proof state:
case a.cons.cons
α : Type u_1
β : Type u_2
s t : Set α
inst✝ : Preorder α
y : α
ys : List α
i : α
hi : i ∈ ys
hx : ∀ b ∈ s, i < b
h : y :: ys ∈ subchain (insert i s)
h' : y ∈ insert i s ∧ ys ∈ subchain (insert i s) ∧ ∀ b ∈ head? ys, y < b
a✝ : List.Pairwise (fun x x_1 => x < x_1) ys
hy : ∀ a' ∈ ys, y < a'
⊢ False

Next tactic:
cases' h'.1 with h' h'
theorem chainHeight_insert_of_forall_gt (a : α) (hx : ∀ b ∈ s, a < b) :
    (insert a s).chainHeight = s.chainHeight + 1 := by
  rw [← add_zero (insert a s).chainHeight]
  change (insert a s).chainHeight + (0 : ℕ) = s.chainHeight + (1 : ℕ)
  apply le_antisymm <;> rw [chainHeight_add_le_chainHeight_add]
  · rintro (_ | ⟨y, ys⟩) h
    · exact ⟨[], nil_mem_subchain _, zero_le _⟩
    · have h' := cons_mem_subchain_iff.mp h
      refine' ⟨ys, ⟨h'.2.1.1, fun i hi ↦ _⟩, by simp⟩
      apply (h'.2.1.2 i hi).resolve_left
      rintro rfl
      cases' chain'_iff_pairwise.mp h.1 with _ _ hy
      cases' h'.1 with h' h'
      

Proof state:
case a.cons.cons.inl
α : Type u_1
β : Type u_2
s t : Set α
inst✝ : Preorder α
y : α
ys : List α
i : α
hi : i ∈ ys
hx : ∀ b ∈ s, i < b
h : y :: ys ∈ subchain (insert i s)
h'✝ : y ∈ insert i s ∧ ys ∈ subchain (insert i s) ∧ ∀ b ∈ head? ys, y < b
a✝ : List.Pairwise (fun x x_1 => x < x_1) ys
hy : ∀ a' ∈ ys, y < a'
h' : y = i
⊢ False
case a.cons.cons.inr
α : Type u_1
β : Type u_2
s t : Set α
inst✝ : Preorder α
y : α
ys : List α
i : α
hi : i ∈ ys
hx : ∀ b ∈ s, i < b
h : y :: ys ∈ subchain (insert i s)
h'✝ : y ∈ insert i s ∧ ys ∈ subchain (insert i s) ∧ ∀ b ∈ head? ys, y < b
a✝ : List.Pairwise (fun x x_1 => x < x_1) ys
hy : ∀ a' ∈ ys, y < a'
h' : y ∈ s
⊢ False

Next tactic:
exacts [(hy _ hi).ne h', not_le_of_gt (hy _ hi) (hx _ h').le]
theorem chainHeight_insert_of_forall_gt (a : α) (hx : ∀ b ∈ s, a < b) :
    (insert a s).chainHeight = s.chainHeight + 1 := by
  rw [← add_zero (insert a s).chainHeight]
  change (insert a s).chainHeight + (0 : ℕ) = s.chainHeight + (1 : ℕ)
  apply le_antisymm <;> rw [chainHeight_add_le_chainHeight_add]
  · rintro (_ | ⟨y, ys⟩) h
    · exact ⟨[], nil_mem_subchain _, zero_le _⟩
    · have h' := cons_mem_subchain_iff.mp h
      refine' ⟨ys, ⟨h'.2.1.1, fun i hi ↦ _⟩, by simp⟩
      apply (h'.2.1.2 i hi).resolve_left
      rintro rfl
      cases' chain'_iff_pairwise.mp h.1 with _ _ hy
      cases' h'.1 with h' h'
      exacts [(hy _ hi).ne h', not_le_of_gt (hy _ hi) (hx _ h').le]
  · 

Proof state:
case a
α : Type u_1
β : Type u_2
s t : Set α
inst✝ : Preorder α
a : α
hx : ∀ b ∈ s, a < b
⊢ ∀ l ∈ subchain s, ∃ l' ∈ subchain (insert a s), length l + 1 ≤ length l' + 0

Next tactic:
intro l hl
theorem chainHeight_insert_of_forall_gt (a : α) (hx : ∀ b ∈ s, a < b) :
    (insert a s).chainHeight = s.chainHeight + 1 := by
  rw [← add_zero (insert a s).chainHeight]
  change (insert a s).chainHeight + (0 : ℕ) = s.chainHeight + (1 : ℕ)
  apply le_antisymm <;> rw [chainHeight_add_le_chainHeight_add]
  · rintro (_ | ⟨y, ys⟩) h
    · exact ⟨[], nil_mem_subchain _, zero_le _⟩
    · have h' := cons_mem_subchain_iff.mp h
      refine' ⟨ys, ⟨h'.2.1.1, fun i hi ↦ _⟩, by simp⟩
      apply (h'.2.1.2 i hi).resolve_left
      rintro rfl
      cases' chain'_iff_pairwise.mp h.1 with _ _ hy
      cases' h'.1 with h' h'
      exacts [(hy _ hi).ne h', not_le_of_gt (hy _ hi) (hx _ h').le]
  · intro l hl
    

Proof state:
case a
α : Type u_1
β : Type u_2
s t : Set α
inst✝ : Preorder α
a : α
hx : ∀ b ∈ s, a < b
l : List α
hl : l ∈ subchain s
⊢ ∃ l' ∈ subchain (insert a s), length l + 1 ≤ length l' + 0

Next tactic:
refine' ⟨a::l, ⟨_, _⟩, by simp⟩
theorem chainHeight_insert_of_forall_gt (a : α) (hx : ∀ b ∈ s, a < b) :
    (insert a s).chainHeight = s.chainHeight + 1 := by
  rw [← add_zero (insert a s).chainHeight]
  change (insert a s).chainHeight + (0 : ℕ) = s.chainHeight + (1 : ℕ)
  apply le_antisymm <;> rw [chainHeight_add_le_chainHeight_add]
  · rintro (_ | ⟨y, ys⟩) h
    · exact ⟨[], nil_mem_subchain _, zero_le _⟩
    · have h' := cons_mem_subchain_iff.mp h
      refine' ⟨ys, ⟨h'.2.1.1, fun i hi ↦ _⟩, by simp⟩
      apply (h'.2.1.2 i hi).resolve_left
      rintro rfl
      cases' chain'_iff_pairwise.mp h.1 with _ _ hy
      cases' h'.1 with h' h'
      exacts [(hy _ hi).ne h', not_le_of_gt (hy _ hi) (hx _ h').le]
  · intro l hl
    refine' ⟨a::l, ⟨_, _⟩, by 

Proof state:
α : Type u_1
β : Type u_2
s t : Set α
inst✝ : Preorder α
a : α
hx : ∀ b ∈ s, a < b
l : List α
hl : l ∈ subchain s
⊢ length l + 1 ≤ length (a :: l) + 0

Next tactic:
simp
theorem chainHeight_insert_of_forall_gt (a : α) (hx : ∀ b ∈ s, a < b) :
    (insert a s).chainHeight = s.chainHeight + 1 := by
  rw [← add_zero (insert a s).chainHeight]
  change (insert a s).chainHeight + (0 : ℕ) = s.chainHeight + (1 : ℕ)
  apply le_antisymm <;> rw [chainHeight_add_le_chainHeight_add]
  · rintro (_ | ⟨y, ys⟩) h
    · exact ⟨[], nil_mem_subchain _, zero_le _⟩
    · have h' := cons_mem_subchain_iff.mp h
      refine' ⟨ys, ⟨h'.2.1.1, fun i hi ↦ _⟩, by simp⟩
      apply (h'.2.1.2 i hi).resolve_left
      rintro rfl
      cases' chain'_iff_pairwise.mp h.1 with _ _ hy
      cases' h'.1 with h' h'
      exacts [(hy _ hi).ne h', not_le_of_gt (hy _ hi) (hx _ h').le]
  · intro l hl
    refine' ⟨a::l, ⟨_, _⟩, by simp⟩
    · 

Proof state:
case a.refine'_1
α : Type u_1
β : Type u_2
s t : Set α
inst✝ : Preorder α
a : α
hx : ∀ b ∈ s, a < b
l : List α
hl : l ∈ subchain s
⊢ Chain' (fun x x_1 => x < x_1) (a :: l)

Next tactic:
rw [chain'_cons']
theorem chainHeight_insert_of_forall_gt (a : α) (hx : ∀ b ∈ s, a < b) :
    (insert a s).chainHeight = s.chainHeight + 1 := by
  rw [← add_zero (insert a s).chainHeight]
  change (insert a s).chainHeight + (0 : ℕ) = s.chainHeight + (1 : ℕ)
  apply le_antisymm <;> rw [chainHeight_add_le_chainHeight_add]
  · rintro (_ | ⟨y, ys⟩) h
    · exact ⟨[], nil_mem_subchain _, zero_le _⟩
    · have h' := cons_mem_subchain_iff.mp h
      refine' ⟨ys, ⟨h'.2.1.1, fun i hi ↦ _⟩, by simp⟩
      apply (h'.2.1.2 i hi).resolve_left
      rintro rfl
      cases' chain'_iff_pairwise.mp h.1 with _ _ hy
      cases' h'.1 with h' h'
      exacts [(hy _ hi).ne h', not_le_of_gt (hy _ hi) (hx _ h').le]
  · intro l hl
    refine' ⟨a::l, ⟨_, _⟩, by simp⟩
    · rw [chain'_cons']
      

Proof state:
case a.refine'_1
α : Type u_1
β : Type u_2
s t : Set α
inst✝ : Preorder α
a : α
hx : ∀ b ∈ s, a < b
l : List α
hl : l ∈ subchain s
⊢ (∀ y ∈ head? l, a < y) ∧ Chain' (fun x x_1 => x < x_1) l

Next tactic:
exact ⟨fun y hy ↦ hx _ (hl.2 _ (mem_of_mem_head? hy)), hl.1⟩
theorem chainHeight_insert_of_forall_gt (a : α) (hx : ∀ b ∈ s, a < b) :
    (insert a s).chainHeight = s.chainHeight + 1 := by
  rw [← add_zero (insert a s).chainHeight]
  change (insert a s).chainHeight + (0 : ℕ) = s.chainHeight + (1 : ℕ)
  apply le_antisymm <;> rw [chainHeight_add_le_chainHeight_add]
  · rintro (_ | ⟨y, ys⟩) h
    · exact ⟨[], nil_mem_subchain _, zero_le _⟩
    · have h' := cons_mem_subchain_iff.mp h
      refine' ⟨ys, ⟨h'.2.1.1, fun i hi ↦ _⟩, by simp⟩
      apply (h'.2.1.2 i hi).resolve_left
      rintro rfl
      cases' chain'_iff_pairwise.mp h.1 with _ _ hy
      cases' h'.1 with h' h'
      exacts [(hy _ hi).ne h', not_le_of_gt (hy _ hi) (hx _ h').le]
  · intro l hl
    refine' ⟨a::l, ⟨_, _⟩, by simp⟩
    · rw [chain'_cons']
      exact ⟨fun y hy ↦ hx _ (hl.2 _ (mem_of_mem_head? hy)), hl.1⟩
    · -- Porting note: originally this was
        -- rintro x (rfl | hx)
        -- exacts [Or.inl (Set.mem_singleton x), Or.inr (hl.2 x hx)]
      -- but this fails because `List.Mem` is now an inductive prop.
      -- I couldn't work out how to drive `rcases` here but asked at
      -- https://leanprover.zulipchat.com/#narrow/stream/348111-std4/topic/rcases.3F/near/347976083
      

Proof state:
case a.refine'_2
α : Type u_1
β : Type u_2
s t : Set α
inst✝ : Preorder α
a : α
hx : ∀ b ∈ s, a < b
l : List α
hl : l ∈ subchain s
⊢ ∀ i ∈ a :: l, i ∈ insert a s

Next tactic:
rintro x (_ | _)
theorem chainHeight_insert_of_forall_gt (a : α) (hx : ∀ b ∈ s, a < b) :
    (insert a s).chainHeight = s.chainHeight + 1 := by
  rw [← add_zero (insert a s).chainHeight]
  change (insert a s).chainHeight + (0 : ℕ) = s.chainHeight + (1 : ℕ)
  apply le_antisymm <;> rw [chainHeight_add_le_chainHeight_add]
  · rintro (_ | ⟨y, ys⟩) h
    · exact ⟨[], nil_mem_subchain _, zero_le _⟩
    · have h' := cons_mem_subchain_iff.mp h
      refine' ⟨ys, ⟨h'.2.1.1, fun i hi ↦ _⟩, by simp⟩
      apply (h'.2.1.2 i hi).resolve_left
      rintro rfl
      cases' chain'_iff_pairwise.mp h.1 with _ _ hy
      cases' h'.1 with h' h'
      exacts [(hy _ hi).ne h', not_le_of_gt (hy _ hi) (hx _ h').le]
  · intro l hl
    refine' ⟨a::l, ⟨_, _⟩, by simp⟩
    · rw [chain'_cons']
      exact ⟨fun y hy ↦ hx _ (hl.2 _ (mem_of_mem_head? hy)), hl.1⟩
    · -- Porting note: originally this was
        -- rintro x (rfl | hx)
        -- exacts [Or.inl (Set.mem_singleton x), Or.inr (hl.2 x hx)]
      -- but this fails because `List.Mem` is now an inductive prop.
      -- I couldn't work out how to drive `rcases` here but asked at
      -- https://leanprover.zulipchat.com/#narrow/stream/348111-std4/topic/rcases.3F/near/347976083
      rintro x (_ | _)
      

Proof state:
case a.refine'_2.head
α : Type u_1
β : Type u_2
s t : Set α
inst✝ : Preorder α
a : α
hx : ∀ b ∈ s, a < b
l : List α
hl : l ∈ subchain s
⊢ a ∈ insert a s
case a.refine'_2.tail
α : Type u_1
β : Type u_2
s t : Set α
inst✝ : Preorder α
a : α
hx : ∀ b ∈ s, a < b
l : List α
hl : l ∈ subchain s
x : α
a✝ : Mem x l
⊢ x ∈ insert a s

Next tactic:
exacts [Or.inl (Set.mem_singleton a), Or.inr (hl.2 x ‹_›)]
theorem chainHeight_insert_of_forall_lt (a : α) (ha : ∀ b ∈ s, b < a) :
    (insert a s).chainHeight = s.chainHeight + 1 := by
  

Proof state:
α : Type u_1
β : Type u_2
s t : Set α
inst✝ : Preorder α
a : α
ha : ∀ b ∈ s, b < a
⊢ chainHeight (insert a s) = chainHeight s + 1

Next tactic:
rw [← chainHeight_dual, ← chainHeight_dual s]
theorem chainHeight_insert_of_forall_lt (a : α) (ha : ∀ b ∈ s, b < a) :
    (insert a s).chainHeight = s.chainHeight + 1 := by
  rw [← chainHeight_dual, ← chainHeight_dual s]
  

Proof state:
α : Type u_1
β : Type u_2
s t : Set α
inst✝ : Preorder α
a : α
ha : ∀ b ∈ s, b < a
⊢ chainHeight (⇑ofDual ⁻¹' insert a s) = chainHeight (⇑ofDual ⁻¹' s) + 1

Next tactic:
exact chainHeight_insert_of_forall_gt _ ha
theorem chainHeight_union_le : (s ∪ t).chainHeight ≤ s.chainHeight + t.chainHeight := by
  

Proof state:
α : Type u_1
β : Type u_2
s t : Set α
inst✝ : Preorder α
⊢ chainHeight (s ∪ t) ≤ chainHeight s + chainHeight t

Next tactic:
classical
    refine' iSup₂_le fun l hl ↦ _
    let l₁ := l.filter (· ∈ s)
    let l₂ := l.filter (· ∈ t)
    have hl₁ : ↑l₁.length ≤ s.chainHeight := by
      apply Set.length_le_chainHeight_of_mem_subchain
      exact ⟨hl.1.sublist (filter_sublist _), fun i h ↦ by simpa using (of_mem_filter h : _)⟩
    have hl₂ : ↑l₂.length ≤ t.chainHeight := by
      apply Set.length_le_chainHeight_of_mem_subchain
      exact ⟨hl.1.sublist (filter_sublist _), fun i h ↦ by simpa using (of_mem_filter h : _)⟩
    refine' le_trans _ (add_le_add hl₁ hl₂)
    simp_rw [← Nat.cast_add, ← Multiset.coe_card, ← Multiset.card_add, ← Multiset.coe_filter]
    rw [Multiset.filter_add_filter, Multiset.filter_eq_self.mpr, Multiset.card_add, Nat.cast_add]
    exacts [le_add_right rfl.le, hl.2]
theorem chainHeight_union_le : (s ∪ t).chainHeight ≤ s.chainHeight + t.chainHeight := by
  classical
    

Proof state:
α : Type u_1
β : Type u_2
s t : Set α
inst✝ : Preorder α
⊢ chainHeight (s ∪ t) ≤ chainHeight s + chainHeight t

Next tactic:
refine' iSup₂_le fun l hl ↦ _
theorem chainHeight_union_le : (s ∪ t).chainHeight ≤ s.chainHeight + t.chainHeight := by
  classical
    refine' iSup₂_le fun l hl ↦ _
    

Proof state:
α : Type u_1
β : Type u_2
s t : Set α
inst✝ : Preorder α
l : List α
hl : l ∈ subchain (s ∪ t)
⊢ ↑(length l) ≤ chainHeight s + chainHeight t

Next tactic:
let l₁ := l.filter (· ∈ s)
theorem chainHeight_union_le : (s ∪ t).chainHeight ≤ s.chainHeight + t.chainHeight := by
  classical
    refine' iSup₂_le fun l hl ↦ _
    let l₁ := l.filter (· ∈ s)
    

Proof state:
α : Type u_1
β : Type u_2
s t : Set α
inst✝ : Preorder α
l : List α
hl : l ∈ subchain (s ∪ t)
l₁ : List α := filter (fun x => decide (x ∈ s)) l
⊢ ↑(length l) ≤ chainHeight s + chainHeight t

Next tactic:
let l₂ := l.filter (· ∈ t)
theorem chainHeight_union_le : (s ∪ t).chainHeight ≤ s.chainHeight + t.chainHeight := by
  classical
    refine' iSup₂_le fun l hl ↦ _
    let l₁ := l.filter (· ∈ s)
    let l₂ := l.filter (· ∈ t)
    

Proof state:
α : Type u_1
β : Type u_2
s t : Set α
inst✝ : Preorder α
l : List α
hl : l ∈ subchain (s ∪ t)
l₁ : List α := filter (fun x => decide (x ∈ s)) l
l₂ : List α := filter (fun x => decide (x ∈ t)) l
⊢ ↑(length l) ≤ chainHeight s + chainHeight t

Next tactic:
have hl₁ : ↑l₁.length ≤ s.chainHeight := by
      apply Set.length_le_chainHeight_of_mem_subchain
      exact ⟨hl.1.sublist (filter_sublist _), fun i h ↦ by simpa using (of_mem_filter h : _)⟩
theorem chainHeight_union_le : (s ∪ t).chainHeight ≤ s.chainHeight + t.chainHeight := by
  classical
    refine' iSup₂_le fun l hl ↦ _
    let l₁ := l.filter (· ∈ s)
    let l₂ := l.filter (· ∈ t)
    have hl₁ : ↑l₁.length ≤ s.chainHeight := by
      

Proof state:
α : Type u_1
β : Type u_2
s t : Set α
inst✝ : Preorder α
l : List α
hl : l ∈ subchain (s ∪ t)
l₁ : List α := filter (fun x => decide (x ∈ s)) l
l₂ : List α := filter (fun x => decide (x ∈ t)) l
⊢ ↑(length l₁) ≤ chainHeight s

Next tactic:
apply Set.length_le_chainHeight_of_mem_subchain
theorem chainHeight_union_le : (s ∪ t).chainHeight ≤ s.chainHeight + t.chainHeight := by
  classical
    refine' iSup₂_le fun l hl ↦ _
    let l₁ := l.filter (· ∈ s)
    let l₂ := l.filter (· ∈ t)
    have hl₁ : ↑l₁.length ≤ s.chainHeight := by
      apply Set.length_le_chainHeight_of_mem_subchain
      

Proof state:
case hl
α : Type u_1
β : Type u_2
s t : Set α
inst✝ : Preorder α
l : List α
hl : l ∈ subchain (s ∪ t)
l₁ : List α := filter (fun x => decide (x ∈ s)) l
l₂ : List α := filter (fun x => decide (x ∈ t)) l
⊢ l₁ ∈ subchain s

Next tactic:
exact ⟨hl.1.sublist (filter_sublist _), fun i h ↦ by simpa using (of_mem_filter h : _)⟩
theorem chainHeight_union_le : (s ∪ t).chainHeight ≤ s.chainHeight + t.chainHeight := by
  classical
    refine' iSup₂_le fun l hl ↦ _
    let l₁ := l.filter (· ∈ s)
    let l₂ := l.filter (· ∈ t)
    have hl₁ : ↑l₁.length ≤ s.chainHeight := by
      apply Set.length_le_chainHeight_of_mem_subchain
      exact ⟨hl.1.sublist (filter_sublist _), fun i h ↦ by 

Proof state:
α : Type u_1
β : Type u_2
s t : Set α
inst✝ : Preorder α
l : List α
hl : l ∈ subchain (s ∪ t)
l₁ : List α := filter (fun x => decide (x ∈ s)) l
l₂ : List α := filter (fun x => decide (x ∈ t)) l
i : α
h : i ∈ l₁
⊢ i ∈ s

Next tactic:
simpa using (of_mem_filter h : _)
theorem chainHeight_union_le : (s ∪ t).chainHeight ≤ s.chainHeight + t.chainHeight := by
  classical
    refine' iSup₂_le fun l hl ↦ _
    let l₁ := l.filter (· ∈ s)
    let l₂ := l.filter (· ∈ t)
    have hl₁ : ↑l₁.length ≤ s.chainHeight := by
      apply Set.length_le_chainHeight_of_mem_subchain
      exact ⟨hl.1.sublist (filter_sublist _), fun i h ↦ by simpa using (of_mem_filter h : _)⟩
    

Proof state:
α : Type u_1
β : Type u_2
s t : Set α
inst✝ : Preorder α
l : List α
hl : l ∈ subchain (s ∪ t)
l₁ : List α := filter (fun x => decide (x ∈ s)) l
l₂ : List α := filter (fun x => decide (x ∈ t)) l
hl₁ : ↑(length l₁) ≤ chainHeight s
⊢ ↑(length l) ≤ chainHeight s + chainHeight t

Next tactic:
have hl₂ : ↑l₂.length ≤ t.chainHeight := by
      apply Set.length_le_chainHeight_of_mem_subchain
      exact ⟨hl.1.sublist (filter_sublist _), fun i h ↦ by simpa using (of_mem_filter h : _)⟩
theorem chainHeight_union_le : (s ∪ t).chainHeight ≤ s.chainHeight + t.chainHeight := by
  classical
    refine' iSup₂_le fun l hl ↦ _
    let l₁ := l.filter (· ∈ s)
    let l₂ := l.filter (· ∈ t)
    have hl₁ : ↑l₁.length ≤ s.chainHeight := by
      apply Set.length_le_chainHeight_of_mem_subchain
      exact ⟨hl.1.sublist (filter_sublist _), fun i h ↦ by simpa using (of_mem_filter h : _)⟩
    have hl₂ : ↑l₂.length ≤ t.chainHeight := by
      

Proof state:
α : Type u_1
β : Type u_2
s t : Set α
inst✝ : Preorder α
l : List α
hl : l ∈ subchain (s ∪ t)
l₁ : List α := filter (fun x => decide (x ∈ s)) l
l₂ : List α := filter (fun x => decide (x ∈ t)) l
hl₁ : ↑(length l₁) ≤ chainHeight s
⊢ ↑(length l₂) ≤ chainHeight t

Next tactic:
apply Set.length_le_chainHeight_of_mem_subchain
theorem chainHeight_union_le : (s ∪ t).chainHeight ≤ s.chainHeight + t.chainHeight := by
  classical
    refine' iSup₂_le fun l hl ↦ _
    let l₁ := l.filter (· ∈ s)
    let l₂ := l.filter (· ∈ t)
    have hl₁ : ↑l₁.length ≤ s.chainHeight := by
      apply Set.length_le_chainHeight_of_mem_subchain
      exact ⟨hl.1.sublist (filter_sublist _), fun i h ↦ by simpa using (of_mem_filter h : _)⟩
    have hl₂ : ↑l₂.length ≤ t.chainHeight := by
      apply Set.length_le_chainHeight_of_mem_subchain
      

Proof state:
case hl
α : Type u_1
β : Type u_2
s t : Set α
inst✝ : Preorder α
l : List α
hl : l ∈ subchain (s ∪ t)
l₁ : List α := filter (fun x => decide (x ∈ s)) l
l₂ : List α := filter (fun x => decide (x ∈ t)) l
hl₁ : ↑(length l₁) ≤ chainHeight s
⊢ l₂ ∈ subchain t

Next tactic:
exact ⟨hl.1.sublist (filter_sublist _), fun i h ↦ by simpa using (of_mem_filter h : _)⟩
theorem chainHeight_union_le : (s ∪ t).chainHeight ≤ s.chainHeight + t.chainHeight := by
  classical
    refine' iSup₂_le fun l hl ↦ _
    let l₁ := l.filter (· ∈ s)
    let l₂ := l.filter (· ∈ t)
    have hl₁ : ↑l₁.length ≤ s.chainHeight := by
      apply Set.length_le_chainHeight_of_mem_subchain
      exact ⟨hl.1.sublist (filter_sublist _), fun i h ↦ by simpa using (of_mem_filter h : _)⟩
    have hl₂ : ↑l₂.length ≤ t.chainHeight := by
      apply Set.length_le_chainHeight_of_mem_subchain
      exact ⟨hl.1.sublist (filter_sublist _), fun i h ↦ by 

Proof state:
α : Type u_1
β : Type u_2
s t : Set α
inst✝ : Preorder α
l : List α
hl : l ∈ subchain (s ∪ t)
l₁ : List α := filter (fun x => decide (x ∈ s)) l
l₂ : List α := filter (fun x => decide (x ∈ t)) l
hl₁ : ↑(length l₁) ≤ chainHeight s
i : α
h : i ∈ l₂
⊢ i ∈ t

Next tactic:
simpa using (of_mem_filter h : _)
theorem chainHeight_union_le : (s ∪ t).chainHeight ≤ s.chainHeight + t.chainHeight := by
  classical
    refine' iSup₂_le fun l hl ↦ _
    let l₁ := l.filter (· ∈ s)
    let l₂ := l.filter (· ∈ t)
    have hl₁ : ↑l₁.length ≤ s.chainHeight := by
      apply Set.length_le_chainHeight_of_mem_subchain
      exact ⟨hl.1.sublist (filter_sublist _), fun i h ↦ by simpa using (of_mem_filter h : _)⟩
    have hl₂ : ↑l₂.length ≤ t.chainHeight := by
      apply Set.length_le_chainHeight_of_mem_subchain
      exact ⟨hl.1.sublist (filter_sublist _), fun i h ↦ by simpa using (of_mem_filter h : _)⟩
    

Proof state:
α : Type u_1
β : Type u_2
s t : Set α
inst✝ : Preorder α
l : List α
hl : l ∈ subchain (s ∪ t)
l₁ : List α := filter (fun x => decide (x ∈ s)) l
l₂ : List α := filter (fun x => decide (x ∈ t)) l
hl₁ : ↑(length l₁) ≤ chainHeight s
hl₂ : ↑(length l₂) ≤ chainHeight t
⊢ ↑(length l) ≤ chainHeight s + chainHeight t

Next tactic:
refine' le_trans _ (add_le_add hl₁ hl₂)
theorem chainHeight_union_le : (s ∪ t).chainHeight ≤ s.chainHeight + t.chainHeight := by
  classical
    refine' iSup₂_le fun l hl ↦ _
    let l₁ := l.filter (· ∈ s)
    let l₂ := l.filter (· ∈ t)
    have hl₁ : ↑l₁.length ≤ s.chainHeight := by
      apply Set.length_le_chainHeight_of_mem_subchain
      exact ⟨hl.1.sublist (filter_sublist _), fun i h ↦ by simpa using (of_mem_filter h : _)⟩
    have hl₂ : ↑l₂.length ≤ t.chainHeight := by
      apply Set.length_le_chainHeight_of_mem_subchain
      exact ⟨hl.1.sublist (filter_sublist _), fun i h ↦ by simpa using (of_mem_filter h : _)⟩
    refine' le_trans _ (add_le_add hl₁ hl₂)
    

Proof state:
α : Type u_1
β : Type u_2
s t : Set α
inst✝ : Preorder α
l : List α
hl : l ∈ subchain (s ∪ t)
l₁ : List α := filter (fun x => decide (x ∈ s)) l
l₂ : List α := filter (fun x => decide (x ∈ t)) l
hl₁ : ↑(length l₁) ≤ chainHeight s
hl₂ : ↑(length l₂) ≤ chainHeight t
⊢ ↑(length l) ≤ ↑(length l₁) + ↑(length l₂)

Next tactic:
simp_rw [← Nat.cast_add, ← Multiset.coe_card, ← Multiset.card_add, ← Multiset.coe_filter]
theorem chainHeight_union_le : (s ∪ t).chainHeight ≤ s.chainHeight + t.chainHeight := by
  classical
    refine' iSup₂_le fun l hl ↦ _
    let l₁ := l.filter (· ∈ s)
    let l₂ := l.filter (· ∈ t)
    have hl₁ : ↑l₁.length ≤ s.chainHeight := by
      apply Set.length_le_chainHeight_of_mem_subchain
      exact ⟨hl.1.sublist (filter_sublist _), fun i h ↦ by simpa using (of_mem_filter h : _)⟩
    have hl₂ : ↑l₂.length ≤ t.chainHeight := by
      apply Set.length_le_chainHeight_of_mem_subchain
      exact ⟨hl.1.sublist (filter_sublist _), fun i h ↦ by simpa using (of_mem_filter h : _)⟩
    refine' le_trans _ (add_le_add hl₁ hl₂)
    simp_rw [← Nat.cast_add, ← Multiset.coe_card, ← Multiset.card_add, ← Multiset.coe_filter]
    

Proof state:
α : Type u_1
β : Type u_2
s t : Set α
inst✝ : Preorder α
l : List α
hl : l ∈ subchain (s ∪ t)
l₁ : List α := filter (fun x => decide (x ∈ s)) l
l₂ : List α := filter (fun x => decide (x ∈ t)) l
hl₁ : ↑(length l₁) ≤ chainHeight s
hl₂ : ↑(length l₂) ≤ chainHeight t
⊢ ↑(Multiset.card ↑l) ≤ ↑(Multiset.card (Multiset.filter (fun b => b ∈ s) ↑l + Multiset.filter (fun b => b ∈ t) ↑l))

Next tactic:
rw [Multiset.filter_add_filter, Multiset.filter_eq_self.mpr, Multiset.card_add, Nat.cast_add]
theorem chainHeight_union_le : (s ∪ t).chainHeight ≤ s.chainHeight + t.chainHeight := by
  classical
    refine' iSup₂_le fun l hl ↦ _
    let l₁ := l.filter (· ∈ s)
    let l₂ := l.filter (· ∈ t)
    have hl₁ : ↑l₁.length ≤ s.chainHeight := by
      apply Set.length_le_chainHeight_of_mem_subchain
      exact ⟨hl.1.sublist (filter_sublist _), fun i h ↦ by simpa using (of_mem_filter h : _)⟩
    have hl₂ : ↑l₂.length ≤ t.chainHeight := by
      apply Set.length_le_chainHeight_of_mem_subchain
      exact ⟨hl.1.sublist (filter_sublist _), fun i h ↦ by simpa using (of_mem_filter h : _)⟩
    refine' le_trans _ (add_le_add hl₁ hl₂)
    simp_rw [← Nat.cast_add, ← Multiset.coe_card, ← Multiset.card_add, ← Multiset.coe_filter]
    rw [Multiset.filter_add_filter, Multiset.filter_eq_self.mpr, Multiset.card_add, Nat.cast_add]
    

Proof state:
α : Type u_1
β : Type u_2
s t : Set α
inst✝ : Preorder α
l : List α
hl : l ∈ subchain (s ∪ t)
l₁ : List α := filter (fun x => decide (x ∈ s)) l
l₂ : List α := filter (fun x => decide (x ∈ t)) l
hl₁ : ↑(length l₁) ≤ chainHeight s
hl₂ : ↑(length l₂) ≤ chainHeight t
⊢ ↑(Multiset.card ↑l) ≤ ↑(Multiset.card ↑l) + ↑(Multiset.card (Multiset.filter (fun a => a ∈ s ∧ a ∈ t) ↑l))
α : Type u_1
β : Type u_2
s t : Set α
inst✝ : Preorder α
l : List α
hl : l ∈ subchain (s ∪ t)
l₁ : List α := filter (fun x => decide (x ∈ s)) l
l₂ : List α := filter (fun x => decide (x ∈ t)) l
hl₁ : ↑(length l₁) ≤ chainHeight s
hl₂ : ↑(length l₂) ≤ chainHeight t
⊢ ∀ a ∈ ↑l, a ∈ s ∨ a ∈ t

Next tactic:
exacts [le_add_right rfl.le, hl.2]
theorem chainHeight_union_eq (s t : Set α) (H : ∀ a ∈ s, ∀ b ∈ t, a < b) :
    (s ∪ t).chainHeight = s.chainHeight + t.chainHeight := by
  

Proof state:
α : Type u_1
β : Type u_2
s✝ t✝ : Set α
inst✝ : Preorder α
s t : Set α
H : ∀ a ∈ s, ∀ b ∈ t, a < b
⊢ chainHeight (s ∪ t) = chainHeight s + chainHeight t

Next tactic:
cases h : t.chainHeight
theorem chainHeight_union_eq (s t : Set α) (H : ∀ a ∈ s, ∀ b ∈ t, a < b) :
    (s ∪ t).chainHeight = s.chainHeight + t.chainHeight := by
  cases h : t.chainHeight
  · 

Proof state:
case none
α : Type u_1
β : Type u_2
s✝ t✝ : Set α
inst✝ : Preorder α
s t : Set α
H : ∀ a ∈ s, ∀ b ∈ t, a < b
h : chainHeight t = none
⊢ chainHeight (s ∪ t) = chainHeight s + none

Next tactic:
rw [WithTop.none_eq_top, add_top, eq_top_iff, ← WithTop.none_eq_top, ← h]