-- Mathlib/Order/Height.lean
theorem chainHeight_image (f : α → β) (hf : ∀ {x y}, x < y ↔ f x < f y) (s : Set α) :
    (f '' s).chainHeight = s.chainHeight

Proof state:
case a.cons
α : Type u_1
β : Type u_2
inst✝¹ : LT α
inst✝ : LT β
f : α → β
hf : ∀ {x y : α}, x < y ↔ f x < f y
s : Set α
x : β
xs : List β
hx : xs ∈ (f '' s).subchain → ∃ l' ∈ s.subchain, map f l' = xs
h : x ∈ f '' s ∧ xs ∈ (f '' s).subchain ∧ ∀ b ∈ xs.head?, x < b
⊢ ∃ l' ∈ s.subchain, map f l' = x :: xs

Tactic:
obtain ⟨⟨x, hx', rfl⟩, h₁, h₂⟩ := h

Result:
case a.cons.intro.intro.intro.intro
α : Type u_1
β : Type u_2
inst✝¹ : LT α
inst✝ : LT β
f : α → β
hf : ∀ {x y : α}, x < y ↔ f x < f y
s : Set α
xs : List β
hx : xs ∈ (f '' s).subchain → ∃ l' ∈ s.subchain, map f l' = xs
x : α
hx' : x ∈ s
h₁ : xs ∈ (f '' s).subchain
h₂ : ∀ b ∈ xs.head?, f x < b
⊢ ∃ l' ∈ s.subchain, map f l' = f x :: xs

Proof state:
case a.refine_1
α : Type u_1
β : Type u_2
inst✝¹ : LT α
inst✝ : LT β
f : α → β
hf : ∀ {x y : α}, x < y ↔ f x < f y
s : Set α
l : List α
hl : l ∈ s.subchain
⊢ Chain' (fun a b => a < b) l

Tactic:
exact hl.1

Result:
no goals

Proof state:
case a.refine_3
α : Type u_1
β : Type u_2
inst✝¹ : LT α
inst✝ : LT β
f : α → β
hf : ∀ {x y : α}, x < y ↔ f x < f y
s : Set α
l : List α
hl : l ∈ s.subchain
⊢ l.length = (map f l).length

Tactic:
rw [length_map]

Result:
no goals

Proof state:
case a
α : Type u_1
β : Type u_2
inst✝¹ : LT α
inst✝ : LT β
f : α → β
hf : ∀ {x y : α}, x < y ↔ f x < f y
s : Set α
⊢ ∀ l ∈ s.subchain, ∃ l' ∈ (f '' s).subchain, l.length = l'.length

Tactic:
intro l hl

Result:
case a
α : Type u_1
β : Type u_2
inst✝¹ : LT α
inst✝ : LT β
f : α → β
hf : ∀ {x y : α}, x < y ↔ f x < f y
s : Set α
l : List α
hl : l ∈ s.subchain
⊢ ∃ l' ∈ (f '' s).subchain, l.length = l'.length

Proof state:
case a.cons.intro.intro.intro.intro.intro.intro.nil
α : Type u_1
β : Type u_2
inst✝¹ : LT α
inst✝ : LT β
f : α → β
hf : ∀ {x y : α}, x < y ↔ f x < f y
s : Set α
x : α
hx' : x ∈ s
h₃ : [] ∈ s.subchain
hx : map f [] ∈ (f '' s).subchain → ∃ l' ∈ s.subchain, map f l' = map f []
h₁ : map f [] ∈ (f '' s).subchain
h₂ : ∀ b ∈ (map f []).head?, f x < b
⊢ ∀ b ∈ [].head?, x < b

Tactic:
simp

Result:
no goals

Proof state:
case a
α : Type u_1
β : Type u_2
inst✝¹ : LT α
inst✝ : LT β
f : α → β
hf : ∀ {x y : α}, x < y ↔ f x < f y
s : Set α
l : List β
⊢ l ∈ (f '' s).subchain → ∃ l' ∈ s.subchain, map f l' = l

Tactic:
induction' l with x xs hx

Result:
case a.nil
α : Type u_1
β : Type u_2
inst✝¹ : LT α
inst✝ : LT β
f : α → β
hf : ∀ {x y : α}, x < y ↔ f x < f y
s : Set α
⊢ [] ∈ (f '' s).subchain → ∃ l' ∈ s.subchain, map f l' = []

case a.cons
α : Type u_1
β : Type u_2
inst✝¹ : LT α
inst✝ : LT β
f : α → β
hf : ∀ {x y : α}, x < y ↔ f x < f y
s : Set α
x : β
xs : List β
hx : xs ∈ (f '' s).subchain → ∃ l' ∈ s.subchain, map f l' = xs
⊢ x :: xs ∈ (f '' s).subchain → ∃ l' ∈ s.subchain, map f l' = x :: xs

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : LT α
inst✝ : LT β
f : α → β
hf : ∀ {x y : α}, x < y ↔ f x < f y
s : Set α
this : ∀ l ∈ (f '' s).subchain, ∃ l' ∈ s.subchain, map f l' = l
l : List β
hl : l ∈ (f '' s).subchain
⊢ ∃ l' ∈ s.subchain, l.length = l'.length

Tactic:
obtain ⟨l', h₁, rfl⟩ := this l hl

Result:
case intro.intro
α : Type u_1
β : Type u_2
inst✝¹ : LT α
inst✝ : LT β
f : α → β
hf : ∀ {x y : α}, x < y ↔ f x < f y
s : Set α
this : ∀ l ∈ (f '' s).subchain, ∃ l' ∈ s.subchain, map f l' = l
l' : List α
h₁ : l' ∈ s.subchain
hl : map f l' ∈ (f '' s).subchain
⊢ ∃ l'_1 ∈ s.subchain, (map f l').length = l'_1.length

Proof state:
case a.nil
α : Type u_1
β : Type u_2
inst✝¹ : LT α
inst✝ : LT β
f : α → β
hf : ∀ {x y : α}, x < y ↔ f x < f y
s : Set α
⊢ [] ∈ (f '' s).subchain → ∃ l' ∈ s.subchain, map f l' = []

Tactic:
exact fun _ ↦ ⟨nil, ⟨trivial, fun x h ↦ (not_mem_nil x h).elim⟩, rfl⟩

Result:
no goals

Proof state:
case a.cons.intro.intro.intro.intro.intro.intro
α : Type u_1
β : Type u_2
inst✝¹ : LT α
inst✝ : LT β
f : α → β
hf : ∀ {x y : α}, x < y ↔ f x < f y
s : Set α
x : α
hx' : x ∈ s
l' : List α
h₃ : l' ∈ s.subchain
hx : map f l' ∈ (f '' s).subchain → ∃ l'_1 ∈ s.subchain, map f l'_1 = map f l'
h₁ : map f l' ∈ (f '' s).subchain
h₂ : ∀ b ∈ (map f l').head?, f x < b
⊢ ∀ b ∈ l'.head?, x < b

Tactic:
cases l'

Result:
case a.cons.intro.intro.intro.intro.intro.intro.nil
α : Type u_1
β : Type u_2
inst✝¹ : LT α
inst✝ : LT β
f : α → β
hf : ∀ {x y : α}, x < y ↔ f x < f y
s : Set α
x : α
hx' : x ∈ s
h₃ : [] ∈ s.subchain
hx : map f [] ∈ (f '' s).subchain → ∃ l' ∈ s.subchain, map f l' = map f []
h₁ : map f [] ∈ (f '' s).subchain
h₂ : ∀ b ∈ (map f []).head?, f x < b
⊢ ∀ b ∈ [].head?, x < b

case a.cons.intro.intro.intro.intro.intro.intro.cons
α : Type u_1
β : Type u_2
inst✝¹ : LT α
inst✝ : LT β
f : α → β
hf : ∀ {x y : α}, x < y ↔ f x < f y
s : Set α
x : α
hx' : x ∈ s
head✝ : α
tail✝ : List α
h₃ : head✝ :: tail✝ ∈ s.subchain
hx : map f (head✝ :: tail✝) ∈ (f '' s).subchain → ∃ l' ∈ s.subchain, map f l' = map f (head✝ :: tail✝)
h₁ : map f (head✝ :: tail✝) ∈ (f '' s).subchain
h₂ : ∀ b ∈ (map f (head✝ :: tail✝)).head?, f x < b
⊢ ∀ b ∈ (head✝ :: tail✝).head?, x < b

Proof state:
case intro.intro
α : Type u_1
β : Type u_2
inst✝¹ : LT α
inst✝ : LT β
f : α → β
hf : ∀ {x y : α}, x < y ↔ f x < f y
s : Set α
this : ∀ l ∈ (f '' s).subchain, ∃ l' ∈ s.subchain, map f l' = l
l' : List α
h₁ : l' ∈ s.subchain
hl : map f l' ∈ (f '' s).subchain
⊢ ∃ l'_1 ∈ s.subchain, (map f l').length = l'_1.length

Tactic:
exact ⟨l', h₁, length_map _ _⟩

Result:
no goals

Proof state:
case a.cons.intro.intro.intro.intro.intro.intro.cons
α : Type u_1
β : Type u_2
inst✝¹ : LT α
inst✝ : LT β
f : α → β
hf : ∀ {x y : α}, x < y ↔ f x < f y
s : Set α
x : α
hx' : x ∈ s
head✝ : α
tail✝ : List α
h₃ : head✝ :: tail✝ ∈ s.subchain
hx : map f (head✝ :: tail✝) ∈ (f '' s).subchain → ∃ l' ∈ s.subchain, map f l' = map f (head✝ :: tail✝)
h₁ : map f (head✝ :: tail✝) ∈ (f '' s).subchain
h₂ : ∀ b ∈ (map f (head✝ :: tail✝)).head?, f x < b
⊢ ∀ b ∈ (head✝ :: tail✝).head?, x < b

Tactic:
simpa [← hf] using h₂

Result:
no goals

Proof state:
case a.cons.intro.intro.intro.intro
α : Type u_1
β : Type u_2
inst✝¹ : LT α
inst✝ : LT β
f : α → β
hf : ∀ {x y : α}, x < y ↔ f x < f y
s : Set α
xs : List β
hx : xs ∈ (f '' s).subchain → ∃ l' ∈ s.subchain, map f l' = xs
x : α
hx' : x ∈ s
h₁ : xs ∈ (f '' s).subchain
h₂ : ∀ b ∈ xs.head?, f x < b
⊢ ∃ l' ∈ s.subchain, map f l' = f x :: xs

Tactic:
obtain ⟨l', h₃, rfl⟩ := hx h₁

Result:
case a.cons.intro.intro.intro.intro.intro.intro
α : Type u_1
β : Type u_2
inst✝¹ : LT α
inst✝ : LT β
f : α → β
hf : ∀ {x y : α}, x < y ↔ f x < f y
s : Set α
x : α
hx' : x ∈ s
l' : List α
h₃ : l' ∈ s.subchain
hx : map f l' ∈ (f '' s).subchain → ∃ l'_1 ∈ s.subchain, map f l'_1 = map f l'
h₁ : map f l' ∈ (f '' s).subchain
h₂ : ∀ b ∈ (map f l').head?, f x < b
⊢ ∃ l'_1 ∈ s.subchain, map f l'_1 = f x :: map f l'

Proof state:
case a.refine_2
α : Type u_1
β : Type u_2
inst✝¹ : LT α
inst✝ : LT β
f : α → β
hf : ∀ {x y : α}, x < y ↔ f x < f y
s : Set α
l : List α
hl : l ∈ s.subchain
⊢ ∀ i ∈ map f l, i ∈ f '' s

Tactic:
intro _ e

Result:
case a.refine_2
α : Type u_1
β : Type u_2
inst✝¹ : LT α
inst✝ : LT β
f : α → β
hf : ∀ {x y : α}, x < y ↔ f x < f y
s : Set α
l : List α
hl : l ∈ s.subchain
i✝ : β
e : i✝ ∈ map f l
⊢ i✝ ∈ f '' s

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : LT α
inst✝ : LT β
f : α → β
hf : ∀ {x y : α}, x < y ↔ f x < f y
s : Set α
⊢ (f '' s).chainHeight = s.chainHeight

Tactic:
apply le_antisymm <;> rw [chainHeight_le_chainHeight_iff]

Result:
case a
α : Type u_1
β : Type u_2
inst✝¹ : LT α
inst✝ : LT β
f : α → β
hf : ∀ {x y : α}, x < y ↔ f x < f y
s : Set α
⊢ ∀ l ∈ (f '' s).subchain, ∃ l' ∈ s.subchain, l.length = l'.length

case a
α : Type u_1
β : Type u_2
inst✝¹ : LT α
inst✝ : LT β
f : α → β
hf : ∀ {x y : α}, x < y ↔ f x < f y
s : Set α
⊢ ∀ l ∈ s.subchain, ∃ l' ∈ (f '' s).subchain, l.length = l'.length