l3lab/ntp-mathlib huggingface dataset:
theorem isNormal_map (hφ : Function.Injective φ.obj) (hφ' : im φ hφ = ⊤) (Sn : S.IsNormal) :
    (map φ hφ S).IsNormal :=
  { wide := fun d => by
      obtain ⟨c, rfl⟩ := obj_surjective_of_im_eq_top φ hφ hφ' d
      change Map.Arrows φ hφ S _ _ (𝟙 _); rw [← Functor.map_id]
      constructor; exact Sn.wide c
    conj := fun {d d'} g δ hδ => by
      rw [mem_map_iff] at hδ
      obtain ⟨c, c', γ, cd, cd', γS, hγ⟩ := hδ; subst_vars; cases hφ cd'
      have : d' ∈ (im φ hφ).objs := by rw [hφ']; apply mem_top_objs
      rw [mem_im_objs_iff] at this
      obtain ⟨c', rfl⟩ := this
      have : g ∈ (im φ hφ).arrows (φ.obj c) (φ.obj c') := by rw [hφ']; trivial
      rw [mem_im_iff] at this
      obtain ⟨b, b', f, hb, hb', _, hf⟩ := this; subst_vars; cases hφ hb; cases hφ hb'
      change Map.Arrows φ hφ S (φ.obj c') (φ.obj c') _
      simp only [eqToHom_refl, Category.comp_id, Category.id_comp, inv_eq_inv]
      suffices Map.Arrows φ hφ S (φ.obj c') (φ.obj c') (φ.map <| Groupoid.inv f ≫ γ ≫ f) by
        simp only [inv_eq_inv, Functor.map_comp, Functor.map_inv] at this; exact this
      · 

Proof state:
case intro.intro.intro.intro.intro.intro.refl.intro.intro.intro.intro.intro.intro.refl.refl.refl
C : Type u
inst✝¹ : Groupoid C
S : Subgroupoid C
D : Type u_1
inst✝ : Groupoid D
φ : C ⥤ D
hφ : Function.Injective φ.obj
hφ' : im φ hφ = ⊤
Sn : IsNormal S
c : C
γ : c ⟶ c
γS : γ ∈ arrows S c c
cd' : φ.obj c = φ.obj c
c' : C
hb : φ.obj c = φ.obj c
hb' : φ.obj c' = φ.obj c'
f : c ⟶ c'
⊢ Map.Arrows φ hφ S (φ.obj c') (φ.obj c') (φ.map (Groupoid.inv f ≫ γ ≫ f))

Next tactic:
constructor
theorem isNormal_map (hφ : Function.Injective φ.obj) (hφ' : im φ hφ = ⊤) (Sn : S.IsNormal) :
    (map φ hφ S).IsNormal :=
  { wide := fun d => by
      obtain ⟨c, rfl⟩ := obj_surjective_of_im_eq_top φ hφ hφ' d
      change Map.Arrows φ hφ S _ _ (𝟙 _); rw [← Functor.map_id]
      constructor; exact Sn.wide c
    conj := fun {d d'} g δ hδ => by
      rw [mem_map_iff] at hδ
      obtain ⟨c, c', γ, cd, cd', γS, hγ⟩ := hδ; subst_vars; cases hφ cd'
      have : d' ∈ (im φ hφ).objs := by rw [hφ']; apply mem_top_objs
      rw [mem_im_objs_iff] at this
      obtain ⟨c', rfl⟩ := this
      have : g ∈ (im φ hφ).arrows (φ.obj c) (φ.obj c') := by rw [hφ']; trivial
      rw [mem_im_iff] at this
      obtain ⟨b, b', f, hb, hb', _, hf⟩ := this; subst_vars; cases hφ hb; cases hφ hb'
      change Map.Arrows φ hφ S (φ.obj c') (φ.obj c') _
      simp only [eqToHom_refl, Category.comp_id, Category.id_comp, inv_eq_inv]
      suffices Map.Arrows φ hφ S (φ.obj c') (φ.obj c') (φ.map <| Groupoid.inv f ≫ γ ≫ f) by
        simp only [inv_eq_inv, Functor.map_comp, Functor.map_inv] at this; exact this
      · constructor; 

Proof state:
case intro.intro.intro.intro.intro.intro.refl.intro.intro.intro.intro.intro.intro.refl.refl.refl.hf
C : Type u
inst✝¹ : Groupoid C
S : Subgroupoid C
D : Type u_1
inst✝ : Groupoid D
φ : C ⥤ D
hφ : Function.Injective φ.obj
hφ' : im φ hφ = ⊤
Sn : IsNormal S
c : C
γ : c ⟶ c
γS : γ ∈ arrows S c c
cd' : φ.obj c = φ.obj c
c' : C
hb : φ.obj c = φ.obj c
hb' : φ.obj c' = φ.obj c'
f : c ⟶ c'
⊢ Groupoid.inv f ≫ γ ≫ f ∈ arrows S c' c'

Next tactic:
apply Sn.conj f γS
theorem isTotallyDisconnected_iff :
    S.IsTotallyDisconnected ↔ ∀ c d, (S.arrows c d).Nonempty → c = d := by
  

Proof state:
C : Type u
inst✝ : Groupoid C
S : Subgroupoid C
⊢ IsTotallyDisconnected S ↔ ∀ (c d : C), Set.Nonempty (arrows S c d) → c = d

Next tactic:
constructor
theorem isTotallyDisconnected_iff :
    S.IsTotallyDisconnected ↔ ∀ c d, (S.arrows c d).Nonempty → c = d := by
  constructor
  · 

Proof state:
case mp
C : Type u
inst✝ : Groupoid C
S : Subgroupoid C
⊢ IsTotallyDisconnected S → ∀ (c d : C), Set.Nonempty (arrows S c d) → c = d

Next tactic:
rintro h c d ⟨f, fS⟩
theorem isTotallyDisconnected_iff :
    S.IsTotallyDisconnected ↔ ∀ c d, (S.arrows c d).Nonempty → c = d := by
  constructor
  · rintro h c d ⟨f, fS⟩
    

Proof state:
case mp.intro
C : Type u
inst✝ : Groupoid C
S : Subgroupoid C
h : IsTotallyDisconnected S
c d : C
f : c ⟶ d
fS : f ∈ arrows S c d
⊢ c = d

Next tactic:
have := h ⟨c, mem_objs_of_src S fS⟩ ⟨d, mem_objs_of_tgt S fS⟩ ⟨f, fS⟩
theorem isTotallyDisconnected_iff :
    S.IsTotallyDisconnected ↔ ∀ c d, (S.arrows c d).Nonempty → c = d := by
  constructor
  · rintro h c d ⟨f, fS⟩
    have := h ⟨c, mem_objs_of_src S fS⟩ ⟨d, mem_objs_of_tgt S fS⟩ ⟨f, fS⟩
    

Proof state:
case mp.intro
C : Type u
inst✝ : Groupoid C
S : Subgroupoid C
h : IsTotallyDisconnected S
c d : C
f : c ⟶ d
fS : f ∈ arrows S c d
this : { val := c, property := (_ : c ∈ objs S) } = { val := d, property := (_ : d ∈ objs S) }
⊢ c = d

Next tactic:
exact congr_arg Subtype.val this
theorem isTotallyDisconnected_iff :
    S.IsTotallyDisconnected ↔ ∀ c d, (S.arrows c d).Nonempty → c = d := by
  constructor
  · rintro h c d ⟨f, fS⟩
    have := h ⟨c, mem_objs_of_src S fS⟩ ⟨d, mem_objs_of_tgt S fS⟩ ⟨f, fS⟩
    exact congr_arg Subtype.val this
  · 

Proof state:
case mpr
C : Type u
inst✝ : Groupoid C
S : Subgroupoid C
⊢ (∀ (c d : C), Set.Nonempty (arrows S c d) → c = d) → IsTotallyDisconnected S

Next tactic:
rintro h ⟨c, hc⟩ ⟨d, hd⟩ ⟨f, fS⟩
theorem isTotallyDisconnected_iff :
    S.IsTotallyDisconnected ↔ ∀ c d, (S.arrows c d).Nonempty → c = d := by
  constructor
  · rintro h c d ⟨f, fS⟩
    have := h ⟨c, mem_objs_of_src S fS⟩ ⟨d, mem_objs_of_tgt S fS⟩ ⟨f, fS⟩
    exact congr_arg Subtype.val this
  · rintro h ⟨c, hc⟩ ⟨d, hd⟩ ⟨f, fS⟩
    

Proof state:
case mpr.mk.mk.mk
C : Type u
inst✝ : Groupoid C
S : Subgroupoid C
h : ∀ (c d : C), Set.Nonempty (arrows S c d) → c = d
c : C
hc : c ∈ objs S
d : C
hd : d ∈ objs S
f : ↑{ val := c, property := hc } ⟶ ↑{ val := d, property := hd }
fS : f ∈ arrows S ↑{ val := c, property := hc } ↑{ val := d, property := hd }
⊢ { val := c, property := hc } = { val := d, property := hd }

Next tactic:
simp only [Subtype.mk_eq_mk]
theorem isTotallyDisconnected_iff :
    S.IsTotallyDisconnected ↔ ∀ c d, (S.arrows c d).Nonempty → c = d := by
  constructor
  · rintro h c d ⟨f, fS⟩
    have := h ⟨c, mem_objs_of_src S fS⟩ ⟨d, mem_objs_of_tgt S fS⟩ ⟨f, fS⟩
    exact congr_arg Subtype.val this
  · rintro h ⟨c, hc⟩ ⟨d, hd⟩ ⟨f, fS⟩
    simp only [Subtype.mk_eq_mk]
    

Proof state:
case mpr.mk.mk.mk
C : Type u
inst✝ : Groupoid C
S : Subgroupoid C
h : ∀ (c d : C), Set.Nonempty (arrows S c d) → c = d
c : C
hc : c ∈ objs S
d : C
hd : d ∈ objs S
f : ↑{ val := c, property := hc } ⟶ ↑{ val := d, property := hd }
fS : f ∈ arrows S ↑{ val := c, property := hc } ↑{ val := d, property := hd }
⊢ c = d

Next tactic:
exact h c d ⟨f, fS⟩
/-- The isotropy subgroupoid of `S` -/
def disconnect : Subgroupoid C where
  arrows c d := {f | c = d ∧ f ∈ S.arrows c d}
  inv := by 

Proof state:
C : Type u
inst✝ : Groupoid C
S : Subgroupoid C
⊢ ∀ {c d : C} {p : c ⟶ d},
    p ∈ (fun c d => {f | c = d ∧ f ∈ arrows S c d}) c d →
      Groupoid.inv p ∈ (fun c d => {f | c = d ∧ f ∈ arrows S c d}) d c

Next tactic:
rintro _ _ _ ⟨rfl, h⟩
/-- The isotropy subgroupoid of `S` -/
def disconnect : Subgroupoid C where
  arrows c d := {f | c = d ∧ f ∈ S.arrows c d}
  inv := by rintro _ _ _ ⟨rfl, h⟩; 

Proof state:
case intro
C : Type u
inst✝ : Groupoid C
S : Subgroupoid C
c✝ : C
p✝ : c✝ ⟶ c✝
h : p✝ ∈ arrows S c✝ c✝
⊢ Groupoid.inv p✝ ∈ (fun c d => {f | c = d ∧ f ∈ arrows S c d}) c✝ c✝

Next tactic:
exact ⟨rfl, S.inv h⟩
/-- The isotropy subgroupoid of `S` -/
def disconnect : Subgroupoid C where
  arrows c d := {f | c = d ∧ f ∈ S.arrows c d}
  inv := by rintro _ _ _ ⟨rfl, h⟩; exact ⟨rfl, S.inv h⟩
  mul := by 

Proof state:
C : Type u
inst✝ : Groupoid C
S : Subgroupoid C
⊢ ∀ {c d e : C} {p : c ⟶ d},
    p ∈ (fun c d => {f | c = d ∧ f ∈ arrows S c d}) c d →
      ∀ {q : d ⟶ e},
        q ∈ (fun c d => {f | c = d ∧ f ∈ arrows S c d}) d e → p ≫ q ∈ (fun c d => {f | c = d ∧ f ∈ arrows S c d}) c e

Next tactic:
rintro _ _ _ _ ⟨rfl, h⟩ _ ⟨rfl, h'⟩
/-- The isotropy subgroupoid of `S` -/
def disconnect : Subgroupoid C where
  arrows c d := {f | c = d ∧ f ∈ S.arrows c d}
  inv := by rintro _ _ _ ⟨rfl, h⟩; exact ⟨rfl, S.inv h⟩
  mul := by rintro _ _ _ _ ⟨rfl, h⟩ _ ⟨rfl, h'⟩; 

Proof state:
case intro.intro
C : Type u
inst✝ : Groupoid C
S : Subgroupoid C
c✝ : C
p✝ : c✝ ⟶ c✝
h : p✝ ∈ arrows S c✝ c✝
q✝ : c✝ ⟶ c✝
h' : q✝ ∈ arrows S c✝ c✝
⊢ p✝ ≫ q✝ ∈ (fun c d => {f | c = d ∧ f ∈ arrows S c d}) c✝ c✝

Next tactic:
exact ⟨rfl, S.mul h h'⟩
theorem disconnect_le : S.disconnect ≤ S := by 

Proof state:
C : Type u
inst✝ : Groupoid C
S : Subgroupoid C
⊢ disconnect S ≤ S

Next tactic:
rw [le_iff]
theorem disconnect_le : S.disconnect ≤ S := by rw [le_iff]; 

Proof state:
C : Type u
inst✝ : Groupoid C
S : Subgroupoid C
⊢ ∀ {c d : C}, arrows (disconnect S) c d ⊆ arrows S c d

Next tactic:
rintro _ _ _ ⟨⟩
theorem disconnect_le : S.disconnect ≤ S := by rw [le_iff]; rintro _ _ _ ⟨⟩; 

Proof state:
case intro
C : Type u
inst✝ : Groupoid C
S : Subgroupoid C
c✝ d✝ : C
a✝ : c✝ ⟶ d✝
left✝ : c✝ = d✝
right✝ : a✝ ∈ arrows S c✝ d✝
⊢ a✝ ∈ arrows S c✝ d✝

Next tactic:
assumption
theorem disconnect_isTotallyDisconnected : S.disconnect.IsTotallyDisconnected := by
  

Proof state:
C : Type u
inst✝ : Groupoid C
S : Subgroupoid C
⊢ IsTotallyDisconnected (disconnect S)

Next tactic:
rw [isTotallyDisconnected_iff]
theorem disconnect_isTotallyDisconnected : S.disconnect.IsTotallyDisconnected := by
  rw [isTotallyDisconnected_iff]; 

Proof state:
C : Type u
inst✝ : Groupoid C
S : Subgroupoid C
⊢ ∀ (c d : C), Set.Nonempty (arrows (disconnect S) c d) → c = d

Next tactic:
exact fun c d ⟨_, h, _⟩ => h
/-- The full subgroupoid on a set `D : Set C` -/
def full : Subgroupoid C where
  arrows c d := {_f | c ∈ D ∧ d ∈ D}
  inv := by 

Proof state:
C : Type u
inst✝ : Groupoid C
S : Subgroupoid C
D : Set C
⊢ ∀ {c d : C} {p : c ⟶ d},
    p ∈ (fun c d => {_f | c ∈ D ∧ d ∈ D}) c d → Groupoid.inv p ∈ (fun c d => {_f | c ∈ D ∧ d ∈ D}) d c

Next tactic:
rintro _ _ _ ⟨⟩
/-- The full subgroupoid on a set `D : Set C` -/
def full : Subgroupoid C where
  arrows c d := {_f | c ∈ D ∧ d ∈ D}
  inv := by rintro _ _ _ ⟨⟩; 

Proof state:
case intro
C : Type u
inst✝ : Groupoid C
S : Subgroupoid C
D : Set C
c✝ d✝ : C
p✝ : c✝ ⟶ d✝
left✝ : c✝ ∈ D
right✝ : d✝ ∈ D
⊢ Groupoid.inv p✝ ∈ (fun c d => {_f | c ∈ D ∧ d ∈ D}) d✝ c✝

Next tactic:
constructor
/-- The full subgroupoid on a set `D : Set C` -/
def full : Subgroupoid C where
  arrows c d := {_f | c ∈ D ∧ d ∈ D}
  inv := by rintro _ _ _ ⟨⟩; constructor <;> 

Proof state:
case intro.left
C : Type u
inst✝ : Groupoid C
S : Subgroupoid C
D : Set C
c✝ d✝ : C
p✝ : c✝ ⟶ d✝
left✝ : c✝ ∈ D
right✝ : d✝ ∈ D
⊢ d✝ ∈ D

Next tactic:
assumption
/-- The full subgroupoid on a set `D : Set C` -/
def full : Subgroupoid C where
  arrows c d := {_f | c ∈ D ∧ d ∈ D}
  inv := by rintro _ _ _ ⟨⟩; constructor <;> 

Proof state:
case intro.right
C : Type u
inst✝ : Groupoid C
S : Subgroupoid C
D : Set C
c✝ d✝ : C
p✝ : c✝ ⟶ d✝
left✝ : c✝ ∈ D
right✝ : d✝ ∈ D
⊢ c✝ ∈ D

Next tactic:
assumption
/-- The full subgroupoid on a set `D : Set C` -/
def full : Subgroupoid C where
  arrows c d := {_f | c ∈ D ∧ d ∈ D}
  inv := by rintro _ _ _ ⟨⟩; constructor <;> assumption
  mul := by 

Proof state:
C : Type u
inst✝ : Groupoid C
S : Subgroupoid C
D : Set C
⊢ ∀ {c d e : C} {p : c ⟶ d},
    p ∈ (fun c d => {_f | c ∈ D ∧ d ∈ D}) c d →
      ∀ {q : d ⟶ e}, q ∈ (fun c d => {_f | c ∈ D ∧ d ∈ D}) d e → p ≫ q ∈ (fun c d => {_f | c ∈ D ∧ d ∈ D}) c e

Next tactic:
rintro _ _ _ _ ⟨⟩ _ ⟨⟩
/-- The full subgroupoid on a set `D : Set C` -/
def full : Subgroupoid C where
  arrows c d := {_f | c ∈ D ∧ d ∈ D}
  inv := by rintro _ _ _ ⟨⟩; constructor <;> assumption
  mul := by rintro _ _ _ _ ⟨⟩ _ ⟨⟩; 

Proof state:
case intro.intro
C : Type u
inst✝ : Groupoid C
S : Subgroupoid C
D : Set C
c✝ d✝ e✝ : C
p✝ : c✝ ⟶ d✝
left✝¹ : c✝ ∈ D
right✝¹ : d✝ ∈ D
q✝ : d✝ ⟶ e✝
left✝ : d✝ ∈ D
right✝ : e✝ ∈ D
⊢ p✝ ≫ q✝ ∈ (fun c d => {_f | c ∈ D ∧ d ∈ D}) c✝ e✝

Next tactic:
constructor
/-- The full subgroupoid on a set `D : Set C` -/
def full : Subgroupoid C where
  arrows c d := {_f | c ∈ D ∧ d ∈ D}
  inv := by rintro _ _ _ ⟨⟩; constructor <;> assumption
  mul := by rintro _ _ _ _ ⟨⟩ _ ⟨⟩; constructor <;> 

Proof state:
case intro.intro.left
C : Type u
inst✝ : Groupoid C
S : Subgroupoid C
D : Set C
c✝ d✝ e✝ : C
p✝ : c✝ ⟶ d✝
left✝¹ : c✝ ∈ D
right✝¹ : d✝ ∈ D
q✝ : d✝ ⟶ e✝
left✝ : d✝ ∈ D
right✝ : e✝ ∈ D
⊢ c✝ ∈ D

Next tactic:
assumption
/-- The full subgroupoid on a set `D : Set C` -/
def full : Subgroupoid C where
  arrows c d := {_f | c ∈ D ∧ d ∈ D}
  inv := by rintro _ _ _ ⟨⟩; constructor <;> assumption
  mul := by rintro _ _ _ _ ⟨⟩ _ ⟨⟩; constructor <;> 

Proof state:
case intro.intro.right
C : Type u
inst✝ : Groupoid C
S : Subgroupoid C
D : Set C
c✝ d✝ e✝ : C
p✝ : c✝ ⟶ d✝
left✝¹ : c✝ ∈ D
right✝¹ : d✝ ∈ D
q✝ : d✝ ⟶ e✝
left✝ : d✝ ∈ D
right✝ : e✝ ∈ D
⊢ e✝ ∈ D

Next tactic:
assumption
@[simp]
theorem mem_full_objs_iff {c : C} : c ∈ (full D).objs ↔ c ∈ D := by 

Proof state:
C : Type u
inst✝ : Groupoid C
S : Subgroupoid C
D : Set C
c : C
⊢ c ∈ objs (full D) ↔ c ∈ D

Next tactic:
rw [full_objs]
@[simp]
theorem full_empty : full ∅ = (⊥ : Subgroupoid C) := by
  

Proof state:
C : Type u
inst✝ : Groupoid C
S : Subgroupoid C
D : Set C
⊢ full ∅ = ⊥

Next tactic:
ext
@[simp]
theorem full_empty : full ∅ = (⊥ : Subgroupoid C) := by
  ext
  

Proof state:
case arrows.h.h.h
C : Type u
inst✝ : Groupoid C
S : Subgroupoid C
D : Set C
x✝² x✝¹ : C
x✝ : x✝² ⟶ x✝¹
⊢ x✝ ∈ arrows (full ∅) x✝² x✝¹ ↔ x✝ ∈ arrows ⊥ x✝² x✝¹

Next tactic:
simp only [Bot.bot, mem_full_iff, mem_empty_iff_false, and_self_iff]
@[simp]
theorem full_univ : full Set.univ = (⊤ : Subgroupoid C) := by
  

Proof state:
C : Type u
inst✝ : Groupoid C
S : Subgroupoid C
D : Set C
⊢ full univ = ⊤

Next tactic:
ext
@[simp]
theorem full_univ : full Set.univ = (⊤ : Subgroupoid C) := by
  ext
  

Proof state:
case arrows.h.h.h
C : Type u
inst✝ : Groupoid C
S : Subgroupoid C
D : Set C
x✝² x✝¹ : C
x✝ : x✝² ⟶ x✝¹
⊢ x✝ ∈ arrows (full univ) x✝² x✝¹ ↔ x✝ ∈ arrows ⊤ x✝² x✝¹

Next tactic:
simp only [mem_full_iff, mem_univ, and_self, mem_top]
theorem full_mono {D E : Set C} (h : D ≤ E) : full D ≤ full E := by
  

Proof state:
C : Type u
inst✝ : Groupoid C
S : Subgroupoid C
D✝ D E : Set C
h : D ≤ E
⊢ full D ≤ full E

Next tactic:
rw [le_iff]
theorem full_mono {D E : Set C} (h : D ≤ E) : full D ≤ full E := by
  rw [le_iff]
  

Proof state:
C : Type u
inst✝ : Groupoid C
S : Subgroupoid C
D✝ D E : Set C
h : D ≤ E
⊢ ∀ {c d : C}, arrows (full D) c d ⊆ arrows (full E) c d

Next tactic:
rintro c d f
theorem full_mono {D E : Set C} (h : D ≤ E) : full D ≤ full E := by
  rw [le_iff]
  rintro c d f
  

Proof state:
C : Type u
inst✝ : Groupoid C
S : Subgroupoid C
D✝ D E : Set C
h : D ≤ E
c d : C
f : c ⟶ d
⊢ f ∈ arrows (full D) c d → f ∈ arrows (full E) c d

Next tactic:
simp only [mem_full_iff]
theorem full_mono {D E : Set C} (h : D ≤ E) : full D ≤ full E := by
  rw [le_iff]
  rintro c d f
  simp only [mem_full_iff]
  

Proof state:
C : Type u
inst✝ : Groupoid C
S : Subgroupoid C
D✝ D E : Set C
h : D ≤ E
c d : C
f : c ⟶ d
⊢ c ∈ D ∧ d ∈ D → c ∈ E ∧ d ∈ E

Next tactic:
exact fun ⟨hc, hd⟩ => ⟨h hc, h hd⟩
/-- When we have an adjunction `G ⊣ F`, any commutative square where the left
map is of the form `G.map i` and the right map is `p` has an "adjoint" commutative
square whose left map is `i` and whose right map is `F.map p`. -/
theorem right_adjoint : CommSq (adj.homEquiv _ _ u) i (F.map p) (adj.homEquiv _ _ v) :=
  ⟨by
    

Proof state:
C : Type u_1
D : Type u_2
inst✝¹ : Category.{u_3, u_1} C
inst✝ : Category.{u_4, u_2} D
G : C ⥤ D
F : D ⥤ C
A B : C
X Y : D
i : A ⟶ B
p : X ⟶ Y
u : G.obj A ⟶ X
v : G.obj B ⟶ Y
sq : CommSq u (G.map i) p v
adj : G ⊣ F
⊢ (Adjunction.homEquiv adj A X) u ≫ F.map p = i ≫ (Adjunction.homEquiv adj B Y) v

Next tactic:
simp only [Adjunction.homEquiv_unit, assoc, ← F.map_comp, sq.w]
/-- When we have an adjunction `G ⊣ F`, any commutative square where the left
map is of the form `G.map i` and the right map is `p` has an "adjoint" commutative
square whose left map is `i` and whose right map is `F.map p`. -/
theorem right_adjoint : CommSq (adj.homEquiv _ _ u) i (F.map p) (adj.homEquiv _ _ v) :=
  ⟨by
    simp only [Adjunction.homEquiv_unit, assoc, ← F.map_comp, sq.w]
    

Proof state:
C : Type u_1
D : Type u_2
inst✝¹ : Category.{u_3, u_1} C
inst✝ : Category.{u_4, u_2} D
G : C ⥤ D
F : D ⥤ C
A B : C
X Y : D
i : A ⟶ B
p : X ⟶ Y
u : G.obj A ⟶ X
v : G.obj B ⟶ Y
sq : CommSq u (G.map i) p v
adj : G ⊣ F
⊢ adj.unit.app A ≫ F.map (G.map i ≫ v) = i ≫ adj.unit.app B ≫ F.map v

Next tactic:
rw [F.map_comp, Adjunction.unit_naturality_assoc]
/-- The liftings of a commutative are in bijection with the liftings of its (right)
adjoint square. -/
def rightAdjointLiftStructEquiv : sq.LiftStruct ≃ (sq.right_adjoint adj).LiftStruct
    where
  toFun l :=
    { l := adj.homEquiv _ _ l.l
      fac_left := by 

Proof state:
C : Type u_1
D : Type u_2
inst✝¹ : Category.{?u.1881, u_1} C
inst✝ : Category.{?u.1885, u_2} D
G : C ⥤ D
F : D ⥤ C
A B : C
X Y : D
i : A ⟶ B
p : X ⟶ Y
u : G.obj A ⟶ X
v : G.obj B ⟶ Y
sq : CommSq u (G.map i) p v
adj : G ⊣ F
l : LiftStruct sq
⊢ i ≫ (Adjunction.homEquiv adj B X) l.l = (Adjunction.homEquiv adj A X) u

Next tactic:
rw [← adj.homEquiv_naturality_left, l.fac_left]
/-- The liftings of a commutative are in bijection with the liftings of its (right)
adjoint square. -/
def rightAdjointLiftStructEquiv : sq.LiftStruct ≃ (sq.right_adjoint adj).LiftStruct
    where
  toFun l :=
    { l := adj.homEquiv _ _ l.l
      fac_left := by rw [← adj.homEquiv_naturality_left, l.fac_left]
      fac_right := by 

Proof state:
C : Type u_1
D : Type u_2
inst✝¹ : Category.{?u.1881, u_1} C
inst✝ : Category.{?u.1885, u_2} D
G : C ⥤ D
F : D ⥤ C
A B : C
X Y : D
i : A ⟶ B
p : X ⟶ Y
u : G.obj A ⟶ X
v : G.obj B ⟶ Y
sq : CommSq u (G.map i) p v
adj : G ⊣ F
l : LiftStruct sq
⊢ (Adjunction.homEquiv adj B X) l.l ≫ F.map p = (Adjunction.homEquiv adj B Y) v

Next tactic:
rw [← Adjunction.homEquiv_naturality_right, l.fac_right]
/-- The liftings of a commutative are in bijection with the liftings of its (right)
adjoint square. -/
def rightAdjointLiftStructEquiv : sq.LiftStruct ≃ (sq.right_adjoint adj).LiftStruct
    where
  toFun l :=
    { l := adj.homEquiv _ _ l.l
      fac_left := by rw [← adj.homEquiv_naturality_left, l.fac_left]
      fac_right := by rw [← Adjunction.homEquiv_naturality_right, l.fac_right] }
  invFun l :=
    { l := (adj.homEquiv _ _).symm l.l
      fac_left := by
        

Proof state:
C : Type u_1
D : Type u_2
inst✝¹ : Category.{?u.1881, u_1} C
inst✝ : Category.{?u.1885, u_2} D
G : C ⥤ D
F : D ⥤ C
A B : C
X Y : D
i : A ⟶ B
p : X ⟶ Y
u : G.obj A ⟶ X
v : G.obj B ⟶ Y
sq : CommSq u (G.map i) p v
adj : G ⊣ F
l : LiftStruct (_ : CommSq ((Adjunction.homEquiv adj A X) u) i (F.map p) ((Adjunction.homEquiv adj B Y) v))
⊢ G.map i ≫ (Adjunction.homEquiv adj B X).symm l.l = u

Next tactic:
rw [← Adjunction.homEquiv_naturality_left_symm, l.fac_left]
/-- The liftings of a commutative are in bijection with the liftings of its (right)
adjoint square. -/
def rightAdjointLiftStructEquiv : sq.LiftStruct ≃ (sq.right_adjoint adj).LiftStruct
    where
  toFun l :=
    { l := adj.homEquiv _ _ l.l
      fac_left := by rw [← adj.homEquiv_naturality_left, l.fac_left]
      fac_right := by rw [← Adjunction.homEquiv_naturality_right, l.fac_right] }
  invFun l :=
    { l := (adj.homEquiv _ _).symm l.l
      fac_left := by
        rw [← Adjunction.homEquiv_naturality_left_symm, l.fac_left]
        

Proof state:
C : Type u_1
D : Type u_2
inst✝¹ : Category.{?u.1881, u_1} C
inst✝ : Category.{?u.1885, u_2} D
G : C ⥤ D
F : D ⥤ C
A B : C
X Y : D
i : A ⟶ B
p : X ⟶ Y
u : G.obj A ⟶ X
v : G.obj B ⟶ Y
sq : CommSq u (G.map i) p v
adj : G ⊣ F
l : LiftStruct (_ : CommSq ((Adjunction.homEquiv adj A X) u) i (F.map p) ((Adjunction.homEquiv adj B Y) v))
⊢ (Adjunction.homEquiv adj A X).symm ((Adjunction.homEquiv adj A X) u) = u

Next tactic:
apply (adj.homEquiv _ _).left_inv
/-- The liftings of a commutative are in bijection with the liftings of its (right)
adjoint square. -/
def rightAdjointLiftStructEquiv : sq.LiftStruct ≃ (sq.right_adjoint adj).LiftStruct
    where
  toFun l :=
    { l := adj.homEquiv _ _ l.l
      fac_left := by rw [← adj.homEquiv_naturality_left, l.fac_left]
      fac_right := by rw [← Adjunction.homEquiv_naturality_right, l.fac_right] }
  invFun l :=
    { l := (adj.homEquiv _ _).symm l.l
      fac_left := by
        rw [← Adjunction.homEquiv_naturality_left_symm, l.fac_left]
        apply (adj.homEquiv _ _).left_inv
      fac_right := by
        

Proof state:
C : Type u_1
D : Type u_2
inst✝¹ : Category.{?u.1881, u_1} C
inst✝ : Category.{?u.1885, u_2} D
G : C ⥤ D
F : D ⥤ C
A B : C
X Y : D
i : A ⟶ B
p : X ⟶ Y
u : G.obj A ⟶ X
v : G.obj B ⟶ Y
sq : CommSq u (G.map i) p v
adj : G ⊣ F
l : LiftStruct (_ : CommSq ((Adjunction.homEquiv adj A X) u) i (F.map p) ((Adjunction.homEquiv adj B Y) v))
⊢ (Adjunction.homEquiv adj B X).symm l.l ≫ p = v

Next tactic:
rw [← Adjunction.homEquiv_naturality_right_symm, l.fac_right]
/-- The liftings of a commutative are in bijection with the liftings of its (right)
adjoint square. -/
def rightAdjointLiftStructEquiv : sq.LiftStruct ≃ (sq.right_adjoint adj).LiftStruct
    where
  toFun l :=
    { l := adj.homEquiv _ _ l.l
      fac_left := by rw [← adj.homEquiv_naturality_left, l.fac_left]
      fac_right := by rw [← Adjunction.homEquiv_naturality_right, l.fac_right] }
  invFun l :=
    { l := (adj.homEquiv _ _).symm l.l
      fac_left := by
        rw [← Adjunction.homEquiv_naturality_left_symm, l.fac_left]
        apply (adj.homEquiv _ _).left_inv
      fac_right := by
        rw [← Adjunction.homEquiv_naturality_right_symm, l.fac_right]
        

Proof state:
C : Type u_1
D : Type u_2
inst✝¹ : Category.{?u.1881, u_1} C
inst✝ : Category.{?u.1885, u_2} D
G : C ⥤ D
F : D ⥤ C
A B : C
X Y : D
i : A ⟶ B
p : X ⟶ Y
u : G.obj A ⟶ X
v : G.obj B ⟶ Y
sq : CommSq u (G.map i) p v
adj : G ⊣ F
l : LiftStruct (_ : CommSq ((Adjunction.homEquiv adj A X) u) i (F.map p) ((Adjunction.homEquiv adj B Y) v))
⊢ (Adjunction.homEquiv adj B Y).symm ((Adjunction.homEquiv adj B Y) v) = v

Next tactic:
apply (adj.homEquiv _ _).left_inv
/-- The liftings of a commutative are in bijection with the liftings of its (right)
adjoint square. -/
def rightAdjointLiftStructEquiv : sq.LiftStruct ≃ (sq.right_adjoint adj).LiftStruct
    where
  toFun l :=
    { l := adj.homEquiv _ _ l.l
      fac_left := by rw [← adj.homEquiv_naturality_left, l.fac_left]
      fac_right := by rw [← Adjunction.homEquiv_naturality_right, l.fac_right] }
  invFun l :=
    { l := (adj.homEquiv _ _).symm l.l
      fac_left := by
        rw [← Adjunction.homEquiv_naturality_left_symm, l.fac_left]
        apply (adj.homEquiv _ _).left_inv
      fac_right := by
        rw [← Adjunction.homEquiv_naturality_right_symm, l.fac_right]
        apply (adj.homEquiv _ _).left_inv }
  left_inv := by 

Proof state:
C : Type u_1
D : Type u_2
inst✝¹ : Category.{?u.1881, u_1} C
inst✝ : Category.{?u.1885, u_2} D
G : C ⥤ D
F : D ⥤ C
A B : C
X Y : D
i : A ⟶ B
p : X ⟶ Y
u : G.obj A ⟶ X
v : G.obj B ⟶ Y
sq : CommSq u (G.map i) p v
adj : G ⊣ F
⊢ Function.LeftInverse
    (fun l =>
      { l := (Adjunction.homEquiv adj B X).symm l.l,
        fac_left := (_ : G.map i ≫ (Adjunction.homEquiv adj B X).symm l.l = u),
        fac_right := (_ : (Adjunction.homEquiv adj B X).symm l.l ≫ p = v) })
    fun l =>
    { l := (Adjunction.homEquiv adj B X) l.l,
      fac_left := (_ : i ≫ (Adjunction.homEquiv adj B X) l.l = (Adjunction.homEquiv adj A X) u),
      fac_right := (_ : (Adjunction.homEquiv adj B X) l.l ≫ F.map p = (Adjunction.homEquiv adj B Y) v) }

Next tactic:
aesop_cat