l3lab/ntp-mathlib huggingface dataset:
/-- Given an adjunction `F ⊣ G`, this provides the natural adjunction
  `(whiskeringLeft _ _ C).obj G ⊣ (whiskeringLeft _ _ C).obj F`. -/
@[simps! unit_app_app counit_app_app]
protected def whiskerLeft (adj : F ⊣ G) :
    (whiskeringLeft E D C).obj G ⊣ (whiskeringLeft D E C).obj F :=
  mkOfUnitCounit
    { unit :=
        { app := fun X =>
            (Functor.leftUnitor _).inv ≫ whiskerRight adj.unit X ≫ (Functor.associator _ _ _).hom
          naturality := by intros; ext; dsimp; simp }
      counit :=
        { app := fun X =>
            (Functor.associator _ _ _).inv ≫ whiskerRight adj.counit X ≫ (Functor.leftUnitor _).hom
          naturality := by intros; ext; dsimp; simp }
      left_triangle  := by ext x; dsimp; simp [Category.id_comp, Category.comp_id, ← x.map_comp]
      right_triangle := by ext x; 

Proof state:
case w.h.w.h
C : Type u_1
D : Type u_2
E : Type u_3
inst✝² : Category.{?u.21084, u_1} C
inst✝¹ : Category.{?u.21088, u_2} D
inst✝ : Category.{?u.21092, u_3} E
F : D ⥤ E
G : E ⥤ D
adj : F ⊣ G
x : E ⥤ C
x✝ : D
⊢ ((whiskerLeft ((whiskeringLeft D E C).obj F)
                (NatTrans.mk fun X =>
                  (Functor.leftUnitor ((𝟭 (D ⥤ C)).obj X)).inv ≫
                    whiskerRight adj.unit X ≫ (Functor.associator F G X).hom) ≫
              (Functor.associator ((whiskeringLeft D E C).obj F) ((whiskeringLeft E D C).obj G)
                    ((whiskeringLeft D E C).obj F)).inv ≫
                whiskerRight
                  (NatTrans.mk fun X =>
                    (Functor.associator G F X).inv ≫ whiskerRight adj.counit X ≫ (Functor.leftUnitor X).hom)
                  ((whiskeringLeft D E C).obj F)).app
          x).app
      x✝ =
    ((NatTrans.id ((whiskeringLeft D E C).obj F ⋙ 𝟭 (D ⥤ C))).app x).app x✝

Next tactic:
dsimp
/-- Given an adjunction `F ⊣ G`, this provides the natural adjunction
  `(whiskeringLeft _ _ C).obj G ⊣ (whiskeringLeft _ _ C).obj F`. -/
@[simps! unit_app_app counit_app_app]
protected def whiskerLeft (adj : F ⊣ G) :
    (whiskeringLeft E D C).obj G ⊣ (whiskeringLeft D E C).obj F :=
  mkOfUnitCounit
    { unit :=
        { app := fun X =>
            (Functor.leftUnitor _).inv ≫ whiskerRight adj.unit X ≫ (Functor.associator _ _ _).hom
          naturality := by intros; ext; dsimp; simp }
      counit :=
        { app := fun X =>
            (Functor.associator _ _ _).inv ≫ whiskerRight adj.counit X ≫ (Functor.leftUnitor _).hom
          naturality := by intros; ext; dsimp; simp }
      left_triangle  := by ext x; dsimp; simp [Category.id_comp, Category.comp_id, ← x.map_comp]
      right_triangle := by ext x; dsimp; 

Proof state:
case w.h.w.h
C : Type u_1
D : Type u_2
E : Type u_3
inst✝² : Category.{?u.21084, u_1} C
inst✝¹ : Category.{?u.21088, u_2} D
inst✝ : Category.{?u.21092, u_3} E
F : D ⥤ E
G : E ⥤ D
adj : F ⊣ G
x : E ⥤ C
x✝ : D
⊢ (𝟙 (x.obj (F.obj x✝)) ≫ x.map (F.map (adj.unit.app x✝)) ≫ 𝟙 (x.obj (F.obj (G.obj (F.obj x✝))))) ≫
      𝟙 (x.obj (F.obj (G.obj (F.obj x✝)))) ≫
        𝟙 (x.obj (F.obj (G.obj (F.obj x✝)))) ≫ x.map (adj.counit.app (F.obj x✝)) ≫ 𝟙 (x.obj (F.obj x✝)) =
    𝟙 (x.obj (F.obj x✝))

Next tactic:
simp [Category.id_comp, Category.comp_id, ← x.map_comp]
theorem wellFoundedOn_iff :
    s.WellFoundedOn r ↔ WellFounded fun a b : α => r a b ∧ a ∈ s ∧ b ∈ s := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
π : ι → Type u_5
r r' : α → α → Prop
f : β → α
s t : Set α
x y : α
⊢ WellFoundedOn s r ↔ WellFounded fun a b => r a b ∧ a ∈ s ∧ b ∈ s

Next tactic:
have f : RelEmbedding (fun (a : s) (b : s) => r a b) fun a b : α => r a b ∧ a ∈ s ∧ b ∈ s :=
    ⟨⟨(↑), Subtype.coe_injective⟩, by simp⟩
theorem wellFoundedOn_iff :
    s.WellFoundedOn r ↔ WellFounded fun a b : α => r a b ∧ a ∈ s ∧ b ∈ s := by
  have f : RelEmbedding (fun (a : s) (b : s) => r a b) fun a b : α => r a b ∧ a ∈ s ∧ b ∈ s :=
    ⟨⟨(↑), Subtype.coe_injective⟩, by 

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
π : ι → Type u_5
r r' : α → α → Prop
f : β → α
s t : Set α
x y : α
⊢ ∀ {a b : ↑s},
    r ({ toFun := Subtype.val, inj' := (_ : Function.Injective fun a => ↑a) } a)
          ({ toFun := Subtype.val, inj' := (_ : Function.Injective fun a => ↑a) } b) ∧
        { toFun := Subtype.val, inj' := (_ : Function.Injective fun a => ↑a) } a ∈ s ∧
          { toFun := Subtype.val, inj' := (_ : Function.Injective fun a => ↑a) } b ∈ s ↔
      r ↑a ↑b

Next tactic:
simp
theorem wellFoundedOn_iff :
    s.WellFoundedOn r ↔ WellFounded fun a b : α => r a b ∧ a ∈ s ∧ b ∈ s := by
  have f : RelEmbedding (fun (a : s) (b : s) => r a b) fun a b : α => r a b ∧ a ∈ s ∧ b ∈ s :=
    ⟨⟨(↑), Subtype.coe_injective⟩, by simp⟩
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
π : ι → Type u_5
r r' : α → α → Prop
f✝ : β → α
s t : Set α
x y : α
f : (fun a b => r ↑a ↑b) ↪r fun a b => r a b ∧ a ∈ s ∧ b ∈ s
⊢ WellFoundedOn s r ↔ WellFounded fun a b => r a b ∧ a ∈ s ∧ b ∈ s

Next tactic:
refine' ⟨fun h => _, f.wellFounded⟩
theorem wellFoundedOn_iff :
    s.WellFoundedOn r ↔ WellFounded fun a b : α => r a b ∧ a ∈ s ∧ b ∈ s := by
  have f : RelEmbedding (fun (a : s) (b : s) => r a b) fun a b : α => r a b ∧ a ∈ s ∧ b ∈ s :=
    ⟨⟨(↑), Subtype.coe_injective⟩, by simp⟩
  refine' ⟨fun h => _, f.wellFounded⟩
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
π : ι → Type u_5
r r' : α → α → Prop
f✝ : β → α
s t : Set α
x y : α
f : (fun a b => r ↑a ↑b) ↪r fun a b => r a b ∧ a ∈ s ∧ b ∈ s
h : WellFoundedOn s r
⊢ WellFounded fun a b => r a b ∧ a ∈ s ∧ b ∈ s

Next tactic:
rw [WellFounded.wellFounded_iff_has_min]
theorem wellFoundedOn_iff :
    s.WellFoundedOn r ↔ WellFounded fun a b : α => r a b ∧ a ∈ s ∧ b ∈ s := by
  have f : RelEmbedding (fun (a : s) (b : s) => r a b) fun a b : α => r a b ∧ a ∈ s ∧ b ∈ s :=
    ⟨⟨(↑), Subtype.coe_injective⟩, by simp⟩
  refine' ⟨fun h => _, f.wellFounded⟩
  rw [WellFounded.wellFounded_iff_has_min]
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
π : ι → Type u_5
r r' : α → α → Prop
f✝ : β → α
s t : Set α
x y : α
f : (fun a b => r ↑a ↑b) ↪r fun a b => r a b ∧ a ∈ s ∧ b ∈ s
h : WellFoundedOn s r
⊢ ∀ (s_1 : Set α), Set.Nonempty s_1 → ∃ m ∈ s_1, ∀ x ∈ s_1, ¬(r x m ∧ x ∈ s ∧ m ∈ s)

Next tactic:
intro t ht
theorem wellFoundedOn_iff :
    s.WellFoundedOn r ↔ WellFounded fun a b : α => r a b ∧ a ∈ s ∧ b ∈ s := by
  have f : RelEmbedding (fun (a : s) (b : s) => r a b) fun a b : α => r a b ∧ a ∈ s ∧ b ∈ s :=
    ⟨⟨(↑), Subtype.coe_injective⟩, by simp⟩
  refine' ⟨fun h => _, f.wellFounded⟩
  rw [WellFounded.wellFounded_iff_has_min]
  intro t ht
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
π : ι → Type u_5
r r' : α → α → Prop
f✝ : β → α
s t✝ : Set α
x y : α
f : (fun a b => r ↑a ↑b) ↪r fun a b => r a b ∧ a ∈ s ∧ b ∈ s
h : WellFoundedOn s r
t : Set α
ht : Set.Nonempty t
⊢ ∃ m ∈ t, ∀ x ∈ t, ¬(r x m ∧ x ∈ s ∧ m ∈ s)

Next tactic:
by_cases hst : (s ∩ t).Nonempty
theorem wellFoundedOn_iff :
    s.WellFoundedOn r ↔ WellFounded fun a b : α => r a b ∧ a ∈ s ∧ b ∈ s := by
  have f : RelEmbedding (fun (a : s) (b : s) => r a b) fun a b : α => r a b ∧ a ∈ s ∧ b ∈ s :=
    ⟨⟨(↑), Subtype.coe_injective⟩, by simp⟩
  refine' ⟨fun h => _, f.wellFounded⟩
  rw [WellFounded.wellFounded_iff_has_min]
  intro t ht
  by_cases hst : (s ∩ t).Nonempty
  · 

Proof state:
case pos
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
π : ι → Type u_5
r r' : α → α → Prop
f✝ : β → α
s t✝ : Set α
x y : α
f : (fun a b => r ↑a ↑b) ↪r fun a b => r a b ∧ a ∈ s ∧ b ∈ s
h : WellFoundedOn s r
t : Set α
ht : Set.Nonempty t
hst : Set.Nonempty (s ∩ t)
⊢ ∃ m ∈ t, ∀ x ∈ t, ¬(r x m ∧ x ∈ s ∧ m ∈ s)

Next tactic:
rw [← Subtype.preimage_coe_nonempty] at hst
theorem wellFoundedOn_iff :
    s.WellFoundedOn r ↔ WellFounded fun a b : α => r a b ∧ a ∈ s ∧ b ∈ s := by
  have f : RelEmbedding (fun (a : s) (b : s) => r a b) fun a b : α => r a b ∧ a ∈ s ∧ b ∈ s :=
    ⟨⟨(↑), Subtype.coe_injective⟩, by simp⟩
  refine' ⟨fun h => _, f.wellFounded⟩
  rw [WellFounded.wellFounded_iff_has_min]
  intro t ht
  by_cases hst : (s ∩ t).Nonempty
  · rw [← Subtype.preimage_coe_nonempty] at hst
    

Proof state:
case pos
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
π : ι → Type u_5
r r' : α → α → Prop
f✝ : β → α
s t✝ : Set α
x y : α
f : (fun a b => r ↑a ↑b) ↪r fun a b => r a b ∧ a ∈ s ∧ b ∈ s
h : WellFoundedOn s r
t : Set α
ht : Set.Nonempty t
hst : Set.Nonempty (Subtype.val ⁻¹' t)
⊢ ∃ m ∈ t, ∀ x ∈ t, ¬(r x m ∧ x ∈ s ∧ m ∈ s)

Next tactic:
rcases h.has_min (Subtype.val ⁻¹' t) hst with ⟨⟨m, ms⟩, mt, hm⟩
theorem wellFoundedOn_iff :
    s.WellFoundedOn r ↔ WellFounded fun a b : α => r a b ∧ a ∈ s ∧ b ∈ s := by
  have f : RelEmbedding (fun (a : s) (b : s) => r a b) fun a b : α => r a b ∧ a ∈ s ∧ b ∈ s :=
    ⟨⟨(↑), Subtype.coe_injective⟩, by simp⟩
  refine' ⟨fun h => _, f.wellFounded⟩
  rw [WellFounded.wellFounded_iff_has_min]
  intro t ht
  by_cases hst : (s ∩ t).Nonempty
  · rw [← Subtype.preimage_coe_nonempty] at hst
    rcases h.has_min (Subtype.val ⁻¹' t) hst with ⟨⟨m, ms⟩, mt, hm⟩
    

Proof state:
case pos.intro.mk.intro
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
π : ι → Type u_5
r r' : α → α → Prop
f✝ : β → α
s t✝ : Set α
x y : α
f : (fun a b => r ↑a ↑b) ↪r fun a b => r a b ∧ a ∈ s ∧ b ∈ s
h : WellFoundedOn s r
t : Set α
ht : Set.Nonempty t
hst : Set.Nonempty (Subtype.val ⁻¹' t)
m : α
ms : m ∈ s
mt : { val := m, property := ms } ∈ Subtype.val ⁻¹' t
hm : ∀ x ∈ Subtype.val ⁻¹' t, ¬r ↑x ↑{ val := m, property := ms }
⊢ ∃ m ∈ t, ∀ x ∈ t, ¬(r x m ∧ x ∈ s ∧ m ∈ s)

Next tactic:
exact ⟨m, mt, fun x xt ⟨xm, xs, _⟩ => hm ⟨x, xs⟩ xt xm⟩
theorem wellFoundedOn_iff :
    s.WellFoundedOn r ↔ WellFounded fun a b : α => r a b ∧ a ∈ s ∧ b ∈ s := by
  have f : RelEmbedding (fun (a : s) (b : s) => r a b) fun a b : α => r a b ∧ a ∈ s ∧ b ∈ s :=
    ⟨⟨(↑), Subtype.coe_injective⟩, by simp⟩
  refine' ⟨fun h => _, f.wellFounded⟩
  rw [WellFounded.wellFounded_iff_has_min]
  intro t ht
  by_cases hst : (s ∩ t).Nonempty
  · rw [← Subtype.preimage_coe_nonempty] at hst
    rcases h.has_min (Subtype.val ⁻¹' t) hst with ⟨⟨m, ms⟩, mt, hm⟩
    exact ⟨m, mt, fun x xt ⟨xm, xs, _⟩ => hm ⟨x, xs⟩ xt xm⟩
  · 

Proof state:
case neg
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
π : ι → Type u_5
r r' : α → α → Prop
f✝ : β → α
s t✝ : Set α
x y : α
f : (fun a b => r ↑a ↑b) ↪r fun a b => r a b ∧ a ∈ s ∧ b ∈ s
h : WellFoundedOn s r
t : Set α
ht : Set.Nonempty t
hst : ¬Set.Nonempty (s ∩ t)
⊢ ∃ m ∈ t, ∀ x ∈ t, ¬(r x m ∧ x ∈ s ∧ m ∈ s)

Next tactic:
rcases ht with ⟨m, mt⟩
theorem wellFoundedOn_iff :
    s.WellFoundedOn r ↔ WellFounded fun a b : α => r a b ∧ a ∈ s ∧ b ∈ s := by
  have f : RelEmbedding (fun (a : s) (b : s) => r a b) fun a b : α => r a b ∧ a ∈ s ∧ b ∈ s :=
    ⟨⟨(↑), Subtype.coe_injective⟩, by simp⟩
  refine' ⟨fun h => _, f.wellFounded⟩
  rw [WellFounded.wellFounded_iff_has_min]
  intro t ht
  by_cases hst : (s ∩ t).Nonempty
  · rw [← Subtype.preimage_coe_nonempty] at hst
    rcases h.has_min (Subtype.val ⁻¹' t) hst with ⟨⟨m, ms⟩, mt, hm⟩
    exact ⟨m, mt, fun x xt ⟨xm, xs, _⟩ => hm ⟨x, xs⟩ xt xm⟩
  · rcases ht with ⟨m, mt⟩
    

Proof state:
case neg.intro
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
π : ι → Type u_5
r r' : α → α → Prop
f✝ : β → α
s t✝ : Set α
x y : α
f : (fun a b => r ↑a ↑b) ↪r fun a b => r a b ∧ a ∈ s ∧ b ∈ s
h : WellFoundedOn s r
t : Set α
hst : ¬Set.Nonempty (s ∩ t)
m : α
mt : m ∈ t
⊢ ∃ m ∈ t, ∀ x ∈ t, ¬(r x m ∧ x ∈ s ∧ m ∈ s)

Next tactic:
exact ⟨m, mt, fun x _ ⟨_, _, ms⟩ => hst ⟨m, ⟨ms, mt⟩⟩⟩
@[simp]
theorem wellFoundedOn_univ : (univ : Set α).WellFoundedOn r ↔ WellFounded r := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
π : ι → Type u_5
r r' : α → α → Prop
f : β → α
s t : Set α
x y : α
⊢ WellFoundedOn univ r ↔ WellFounded r

Next tactic:
simp [wellFoundedOn_iff]
@[simp]
theorem wellFoundedOn_range : (range f).WellFoundedOn r ↔ WellFounded (r on f) := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
π : ι → Type u_5
r r' : α → α → Prop
f : β → α
s t : Set α
x y : α
⊢ WellFoundedOn (range f) r ↔ WellFounded (r on f)

Next tactic:
let f' : β → range f := fun c => ⟨f c, c, rfl⟩
@[simp]
theorem wellFoundedOn_range : (range f).WellFoundedOn r ↔ WellFounded (r on f) := by
  let f' : β → range f := fun c => ⟨f c, c, rfl⟩
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
π : ι → Type u_5
r r' : α → α → Prop
f : β → α
s t : Set α
x y : α
f' : β → ↑(range f) := fun c => { val := f c, property := (_ : ∃ y, f y = f c) }
⊢ WellFoundedOn (range f) r ↔ WellFounded (r on f)

Next tactic:
refine' ⟨fun h => (InvImage.wf f' h).mono fun c c' => id, fun h => ⟨_⟩⟩
@[simp]
theorem wellFoundedOn_range : (range f).WellFoundedOn r ↔ WellFounded (r on f) := by
  let f' : β → range f := fun c => ⟨f c, c, rfl⟩
  refine' ⟨fun h => (InvImage.wf f' h).mono fun c c' => id, fun h => ⟨_⟩⟩
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
π : ι → Type u_5
r r' : α → α → Prop
f : β → α
s t : Set α
x y : α
f' : β → ↑(range f) := fun c => { val := f c, property := (_ : ∃ y, f y = f c) }
h : WellFounded (r on f)
⊢ ∀ (a : ↑(range f)), Acc (fun a b => r ↑a ↑b) a

Next tactic:
rintro ⟨_, c, rfl⟩
@[simp]
theorem wellFoundedOn_range : (range f).WellFoundedOn r ↔ WellFounded (r on f) := by
  let f' : β → range f := fun c => ⟨f c, c, rfl⟩
  refine' ⟨fun h => (InvImage.wf f' h).mono fun c c' => id, fun h => ⟨_⟩⟩
  rintro ⟨_, c, rfl⟩
  

Proof state:
case mk.intro
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
π : ι → Type u_5
r r' : α → α → Prop
f : β → α
s t : Set α
x y : α
f' : β → ↑(range f) := fun c => { val := f c, property := (_ : ∃ y, f y = f c) }
h : WellFounded (r on f)
c : β
⊢ Acc (fun a b => r ↑a ↑b) { val := f c, property := (_ : ∃ y, f y = f c) }

Next tactic:
refine' Acc.of_downward_closed f' _ _ _
@[simp]
theorem wellFoundedOn_range : (range f).WellFoundedOn r ↔ WellFounded (r on f) := by
  let f' : β → range f := fun c => ⟨f c, c, rfl⟩
  refine' ⟨fun h => (InvImage.wf f' h).mono fun c c' => id, fun h => ⟨_⟩⟩
  rintro ⟨_, c, rfl⟩
  refine' Acc.of_downward_closed f' _ _ _
  · 

Proof state:
case mk.intro.refine'_1
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
π : ι → Type u_5
r r' : α → α → Prop
f : β → α
s t : Set α
x y : α
f' : β → ↑(range f) := fun c => { val := f c, property := (_ : ∃ y, f y = f c) }
h : WellFounded (r on f)
c : β
⊢ ∀ {a : β} {b : ↑(range f)}, r ↑b ↑(f' a) → ∃ c, f' c = b

Next tactic:
rintro _ ⟨_, c', rfl⟩ -
@[simp]
theorem wellFoundedOn_range : (range f).WellFoundedOn r ↔ WellFounded (r on f) := by
  let f' : β → range f := fun c => ⟨f c, c, rfl⟩
  refine' ⟨fun h => (InvImage.wf f' h).mono fun c c' => id, fun h => ⟨_⟩⟩
  rintro ⟨_, c, rfl⟩
  refine' Acc.of_downward_closed f' _ _ _
  · rintro _ ⟨_, c', rfl⟩ -
    

Proof state:
case mk.intro.refine'_1.mk.intro
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
π : ι → Type u_5
r r' : α → α → Prop
f : β → α
s t : Set α
x y : α
f' : β → ↑(range f) := fun c => { val := f c, property := (_ : ∃ y, f y = f c) }
h : WellFounded (r on f)
c a✝ c' : β
⊢ ∃ c, f' c = { val := f c', property := (_ : ∃ y, f y = f c') }

Next tactic:
exact ⟨c', rfl⟩
@[simp]
theorem wellFoundedOn_range : (range f).WellFoundedOn r ↔ WellFounded (r on f) := by
  let f' : β → range f := fun c => ⟨f c, c, rfl⟩
  refine' ⟨fun h => (InvImage.wf f' h).mono fun c c' => id, fun h => ⟨_⟩⟩
  rintro ⟨_, c, rfl⟩
  refine' Acc.of_downward_closed f' _ _ _
  · rintro _ ⟨_, c', rfl⟩ -
    exact ⟨c', rfl⟩
  · 

Proof state:
case mk.intro.refine'_2
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
π : ι → Type u_5
r r' : α → α → Prop
f : β → α
s t : Set α
x y : α
f' : β → ↑(range f) := fun c => { val := f c, property := (_ : ∃ y, f y = f c) }
h : WellFounded (r on f)
c : β
⊢ Acc (InvImage (fun a b => r ↑a ↑b) f') c

Next tactic:
exact h.apply _
@[simp]
theorem wellFoundedOn_image {s : Set β} : (f '' s).WellFoundedOn r ↔ s.WellFoundedOn (r on f) := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
π : ι → Type u_5
r r' : α → α → Prop
f : β → α
s✝ t : Set α
x y : α
s : Set β
⊢ WellFoundedOn (f '' s) r ↔ WellFoundedOn s (r on f)

Next tactic:
rw [image_eq_range]
@[simp]
theorem wellFoundedOn_image {s : Set β} : (f '' s).WellFoundedOn r ↔ s.WellFoundedOn (r on f) := by
  rw [image_eq_range]; 

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
π : ι → Type u_5
r r' : α → α → Prop
f : β → α
s✝ t : Set α
x y : α
s : Set β
⊢ WellFoundedOn (range fun x => f ↑x) r ↔ WellFoundedOn s (r on f)

Next tactic:
exact wellFoundedOn_range
protected theorem induction (hs : s.WellFoundedOn r) (hx : x ∈ s) {P : α → Prop}
    (hP : ∀ y ∈ s, (∀ z ∈ s, r z y → P z) → P y) : P x := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
π : ι → Type u_5
r r' : α → α → Prop
f : β → α
s t : Set α
x y : α
hs : WellFoundedOn s r
hx : x ∈ s
P : α → Prop
hP : ∀ y ∈ s, (∀ z ∈ s, r z y → P z) → P y
⊢ P x

Next tactic:
let Q : s → Prop := fun y => P y
protected theorem induction (hs : s.WellFoundedOn r) (hx : x ∈ s) {P : α → Prop}
    (hP : ∀ y ∈ s, (∀ z ∈ s, r z y → P z) → P y) : P x := by
  let Q : s → Prop := fun y => P y
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
π : ι → Type u_5
r r' : α → α → Prop
f : β → α
s t : Set α
x y : α
hs : WellFoundedOn s r
hx : x ∈ s
P : α → Prop
hP : ∀ y ∈ s, (∀ z ∈ s, r z y → P z) → P y
Q : ↑s → Prop := fun y => P ↑y
⊢ P x

Next tactic:
change Q ⟨x, hx⟩
protected theorem induction (hs : s.WellFoundedOn r) (hx : x ∈ s) {P : α → Prop}
    (hP : ∀ y ∈ s, (∀ z ∈ s, r z y → P z) → P y) : P x := by
  let Q : s → Prop := fun y => P y
  change Q ⟨x, hx⟩
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
π : ι → Type u_5
r r' : α → α → Prop
f : β → α
s t : Set α
x y : α
hs : WellFoundedOn s r
hx : x ∈ s
P : α → Prop
hP : ∀ y ∈ s, (∀ z ∈ s, r z y → P z) → P y
Q : ↑s → Prop := fun y => P ↑y
⊢ Q { val := x, property := hx }

Next tactic:
refine' WellFounded.induction hs ⟨x, hx⟩ _
protected theorem induction (hs : s.WellFoundedOn r) (hx : x ∈ s) {P : α → Prop}
    (hP : ∀ y ∈ s, (∀ z ∈ s, r z y → P z) → P y) : P x := by
  let Q : s → Prop := fun y => P y
  change Q ⟨x, hx⟩
  refine' WellFounded.induction hs ⟨x, hx⟩ _
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
π : ι → Type u_5
r r' : α → α → Prop
f : β → α
s t : Set α
x y : α
hs : WellFoundedOn s r
hx : x ∈ s
P : α → Prop
hP : ∀ y ∈ s, (∀ z ∈ s, r z y → P z) → P y
Q : ↑s → Prop := fun y => P ↑y
⊢ ∀ (x : ↑s), (∀ (y : ↑s), r ↑y ↑x → Q y) → Q x

Next tactic:
simpa only [Subtype.forall]
protected theorem mono (h : t.WellFoundedOn r') (hle : r ≤ r') (hst : s ⊆ t) :
    s.WellFoundedOn r := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
π : ι → Type u_5
r r' : α → α → Prop
f : β → α
s t : Set α
x y : α
h : WellFoundedOn t r'
hle : r ≤ r'
hst : s ⊆ t
⊢ WellFoundedOn s r

Next tactic:
rw [wellFoundedOn_iff] at *
protected theorem mono (h : t.WellFoundedOn r') (hle : r ≤ r') (hst : s ⊆ t) :
    s.WellFoundedOn r := by
  rw [wellFoundedOn_iff] at *
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
π : ι → Type u_5
r r' : α → α → Prop
f : β → α
s t : Set α
x y : α
h : WellFounded fun a b => r' a b ∧ a ∈ t ∧ b ∈ t
hle : r ≤ r'
hst : s ⊆ t
⊢ WellFounded fun a b => r a b ∧ a ∈ s ∧ b ∈ s

Next tactic:
exact Subrelation.wf (fun xy => ⟨hle _ _ xy.1, hst xy.2.1, hst xy.2.2⟩) h
open List in
/-- `a` is accessible under the relation `r` iff `r` is well-founded on the downward transitive
closure of `a` under `r` (including `a` or not). -/
theorem acc_iff_wellFoundedOn {α} {r : α → α → Prop} {a : α} :
    TFAE [Acc r a,
      WellFoundedOn { b | ReflTransGen r b a } r,
      WellFoundedOn { b | TransGen r b a } r] := by
  

Proof state:
ι : Type u_1
α✝ : Type u_2
β : Type u_3
γ : Type u_4
π : ι → Type u_5
r✝ r' : α✝ → α✝ → Prop
f : β → α✝
s t : Set α✝
x y : α✝
α : Type u_6
r : α → α → Prop
a : α
⊢ TFAE [Acc r a, WellFoundedOn {b | ReflTransGen r b a} r, WellFoundedOn {b | TransGen r b a} r]

Next tactic:
tfae_have 1 → 2
open List in
/-- `a` is accessible under the relation `r` iff `r` is well-founded on the downward transitive
closure of `a` under `r` (including `a` or not). -/
theorem acc_iff_wellFoundedOn {α} {r : α → α → Prop} {a : α} :
    TFAE [Acc r a,
      WellFoundedOn { b | ReflTransGen r b a } r,
      WellFoundedOn { b | TransGen r b a } r] := by
  tfae_have 1 → 2
  · 

Proof state:
case tfae_1_to_2
ι : Type u_1
α✝ : Type u_2
β : Type u_3
γ : Type u_4
π : ι → Type u_5
r✝ r' : α✝ → α✝ → Prop
f : β → α✝
s t : Set α✝
x y : α✝
α : Type u_6
r : α → α → Prop
a : α
⊢ Acc r a → WellFoundedOn {b | ReflTransGen r b a} r

Next tactic:
refine fun h => ⟨fun b => InvImage.accessible _ ?_⟩
open List in
/-- `a` is accessible under the relation `r` iff `r` is well-founded on the downward transitive
closure of `a` under `r` (including `a` or not). -/
theorem acc_iff_wellFoundedOn {α} {r : α → α → Prop} {a : α} :
    TFAE [Acc r a,
      WellFoundedOn { b | ReflTransGen r b a } r,
      WellFoundedOn { b | TransGen r b a } r] := by
  tfae_have 1 → 2
  · refine fun h => ⟨fun b => InvImage.accessible _ ?_⟩
    

Proof state:
case tfae_1_to_2
ι : Type u_1
α✝ : Type u_2
β : Type u_3
γ : Type u_4
π : ι → Type u_5
r✝ r' : α✝ → α✝ → Prop
f : β → α✝
s t : Set α✝
x y : α✝
α : Type u_6
r : α → α → Prop
a : α
h : Acc r a
b : ↑{b | ReflTransGen r b a}
⊢ Acc r ↑b

Next tactic:
rw [← acc_transGen_iff] at h ⊢
open List in
/-- `a` is accessible under the relation `r` iff `r` is well-founded on the downward transitive
closure of `a` under `r` (including `a` or not). -/
theorem acc_iff_wellFoundedOn {α} {r : α → α → Prop} {a : α} :
    TFAE [Acc r a,
      WellFoundedOn { b | ReflTransGen r b a } r,
      WellFoundedOn { b | TransGen r b a } r] := by
  tfae_have 1 → 2
  · refine fun h => ⟨fun b => InvImage.accessible _ ?_⟩
    rw [← acc_transGen_iff] at h ⊢
    

Proof state:
case tfae_1_to_2
ι : Type u_1
α✝ : Type u_2
β : Type u_3
γ : Type u_4
π : ι → Type u_5
r✝ r' : α✝ → α✝ → Prop
f : β → α✝
s t : Set α✝
x y : α✝
α : Type u_6
r : α → α → Prop
a : α
h : Acc (TransGen r) a
b : ↑{b | ReflTransGen r b a}
⊢ Acc (TransGen r) ↑b

Next tactic:
obtain h' | h' := reflTransGen_iff_eq_or_transGen.1 b.2
open List in
/-- `a` is accessible under the relation `r` iff `r` is well-founded on the downward transitive
closure of `a` under `r` (including `a` or not). -/
theorem acc_iff_wellFoundedOn {α} {r : α → α → Prop} {a : α} :
    TFAE [Acc r a,
      WellFoundedOn { b | ReflTransGen r b a } r,
      WellFoundedOn { b | TransGen r b a } r] := by
  tfae_have 1 → 2
  · refine fun h => ⟨fun b => InvImage.accessible _ ?_⟩
    rw [← acc_transGen_iff] at h ⊢
    obtain h' | h' := reflTransGen_iff_eq_or_transGen.1 b.2
    · 

Proof state:
case tfae_1_to_2.inl
ι : Type u_1
α✝ : Type u_2
β : Type u_3
γ : Type u_4
π : ι → Type u_5
r✝ r' : α✝ → α✝ → Prop
f : β → α✝
s t : Set α✝
x y : α✝
α : Type u_6
r : α → α → Prop
a : α
h : Acc (TransGen r) a
b : ↑{b | ReflTransGen r b a}
h' : a = ↑b
⊢ Acc (TransGen r) ↑b

Next tactic:
rwa [h'] at h
open List in
/-- `a` is accessible under the relation `r` iff `r` is well-founded on the downward transitive
closure of `a` under `r` (including `a` or not). -/
theorem acc_iff_wellFoundedOn {α} {r : α → α → Prop} {a : α} :
    TFAE [Acc r a,
      WellFoundedOn { b | ReflTransGen r b a } r,
      WellFoundedOn { b | TransGen r b a } r] := by
  tfae_have 1 → 2
  · refine fun h => ⟨fun b => InvImage.accessible _ ?_⟩
    rw [← acc_transGen_iff] at h ⊢
    obtain h' | h' := reflTransGen_iff_eq_or_transGen.1 b.2
    · rwa [h'] at h
    · 

Proof state:
case tfae_1_to_2.inr
ι : Type u_1
α✝ : Type u_2
β : Type u_3
γ : Type u_4
π : ι → Type u_5
r✝ r' : α✝ → α✝ → Prop
f : β → α✝
s t : Set α✝
x y : α✝
α : Type u_6
r : α → α → Prop
a : α
h : Acc (TransGen r) a
b : ↑{b | ReflTransGen r b a}
h' : TransGen r (↑b) a
⊢ Acc (TransGen r) ↑b

Next tactic:
exact h.inv h'