l3lab/ntp-mathlib huggingface dataset:
/-- The "forward" image of a subgroupoid under a functor injective on objects -/
def map (hφ : Function.Injective φ.obj) (S : Subgroupoid C) : Subgroupoid D where
  arrows c d := {x | Map.Arrows φ hφ S c d x}
  inv := by
    

Proof state:
C : Type u
inst✝¹ : Groupoid C
S✝ : Subgroupoid C
D : Type u_1
inst✝ : Groupoid D
φ : C ⥤ D
hφ : Function.Injective φ.obj
S : Subgroupoid C
⊢ ∀ {c d : D} {p : c ⟶ d},
    p ∈ (fun c d => {x | Map.Arrows φ hφ S c d x}) c d → Groupoid.inv p ∈ (fun c d => {x | Map.Arrows φ hφ S c d x}) d c

Next tactic:
rintro _ _ _ ⟨⟩
/-- The "forward" image of a subgroupoid under a functor injective on objects -/
def map (hφ : Function.Injective φ.obj) (S : Subgroupoid C) : Subgroupoid D where
  arrows c d := {x | Map.Arrows φ hφ S c d x}
  inv := by
    rintro _ _ _ ⟨⟩
    

Proof state:
case im
C : Type u
inst✝¹ : Groupoid C
S✝ : Subgroupoid C
D : Type u_1
inst✝ : Groupoid D
φ : C ⥤ D
hφ : Function.Injective φ.obj
S : Subgroupoid C
c d : D
c✝ d✝ : C
f✝ : c✝ ⟶ d✝
hf✝ : f✝ ∈ arrows S c✝ d✝
⊢ Groupoid.inv (φ.map f✝) ∈ (fun c d => {x | Map.Arrows φ hφ S c d x}) (φ.obj d✝) (φ.obj c✝)

Next tactic:
rw [inv_eq_inv, ← Functor.map_inv, ← inv_eq_inv]
/-- The "forward" image of a subgroupoid under a functor injective on objects -/
def map (hφ : Function.Injective φ.obj) (S : Subgroupoid C) : Subgroupoid D where
  arrows c d := {x | Map.Arrows φ hφ S c d x}
  inv := by
    rintro _ _ _ ⟨⟩
    rw [inv_eq_inv, ← Functor.map_inv, ← inv_eq_inv]
    

Proof state:
case im
C : Type u
inst✝¹ : Groupoid C
S✝ : Subgroupoid C
D : Type u_1
inst✝ : Groupoid D
φ : C ⥤ D
hφ : Function.Injective φ.obj
S : Subgroupoid C
c d : D
c✝ d✝ : C
f✝ : c✝ ⟶ d✝
hf✝ : f✝ ∈ arrows S c✝ d✝
⊢ φ.map (Groupoid.inv f✝) ∈ (fun c d => {x | Map.Arrows φ hφ S c d x}) (φ.obj d✝) (φ.obj c✝)

Next tactic:
constructor
/-- The "forward" image of a subgroupoid under a functor injective on objects -/
def map (hφ : Function.Injective φ.obj) (S : Subgroupoid C) : Subgroupoid D where
  arrows c d := {x | Map.Arrows φ hφ S c d x}
  inv := by
    rintro _ _ _ ⟨⟩
    rw [inv_eq_inv, ← Functor.map_inv, ← inv_eq_inv]
    constructor; 

Proof state:
case im.hf
C : Type u
inst✝¹ : Groupoid C
S✝ : Subgroupoid C
D : Type u_1
inst✝ : Groupoid D
φ : C ⥤ D
hφ : Function.Injective φ.obj
S : Subgroupoid C
c d : D
c✝ d✝ : C
f✝ : c✝ ⟶ d✝
hf✝ : f✝ ∈ arrows S c✝ d✝
⊢ Groupoid.inv f✝ ∈ arrows S d✝ c✝

Next tactic:
apply S.inv
/-- The "forward" image of a subgroupoid under a functor injective on objects -/
def map (hφ : Function.Injective φ.obj) (S : Subgroupoid C) : Subgroupoid D where
  arrows c d := {x | Map.Arrows φ hφ S c d x}
  inv := by
    rintro _ _ _ ⟨⟩
    rw [inv_eq_inv, ← Functor.map_inv, ← inv_eq_inv]
    constructor; apply S.inv; 

Proof state:
case im.hf
C : Type u
inst✝¹ : Groupoid C
S✝ : Subgroupoid C
D : Type u_1
inst✝ : Groupoid D
φ : C ⥤ D
hφ : Function.Injective φ.obj
S : Subgroupoid C
c d : D
c✝ d✝ : C
f✝ : c✝ ⟶ d✝
hf✝ : f✝ ∈ arrows S c✝ d✝
⊢ f✝ ∈ arrows S c✝ d✝

Next tactic:
assumption
/-- The "forward" image of a subgroupoid under a functor injective on objects -/
def map (hφ : Function.Injective φ.obj) (S : Subgroupoid C) : Subgroupoid D where
  arrows c d := {x | Map.Arrows φ hφ S c d x}
  inv := by
    rintro _ _ _ ⟨⟩
    rw [inv_eq_inv, ← Functor.map_inv, ← inv_eq_inv]
    constructor; apply S.inv; assumption
  mul := by
    

Proof state:
C : Type u
inst✝¹ : Groupoid C
S✝ : Subgroupoid C
D : Type u_1
inst✝ : Groupoid D
φ : C ⥤ D
hφ : Function.Injective φ.obj
S : Subgroupoid C
⊢ ∀ {c d e : D} {p : c ⟶ d},
    p ∈ (fun c d => {x | Map.Arrows φ hφ S c d x}) c d →
      ∀ {q : d ⟶ e},
        q ∈ (fun c d => {x | Map.Arrows φ hφ S c d x}) d e → p ≫ q ∈ (fun c d => {x | Map.Arrows φ hφ S c d x}) c e

Next tactic:
rintro _ _ _ _ ⟨f, hf⟩ q hq
/-- The "forward" image of a subgroupoid under a functor injective on objects -/
def map (hφ : Function.Injective φ.obj) (S : Subgroupoid C) : Subgroupoid D where
  arrows c d := {x | Map.Arrows φ hφ S c d x}
  inv := by
    rintro _ _ _ ⟨⟩
    rw [inv_eq_inv, ← Functor.map_inv, ← inv_eq_inv]
    constructor; apply S.inv; assumption
  mul := by
    rintro _ _ _ _ ⟨f, hf⟩ q hq
    

Proof state:
case im
C : Type u
inst✝¹ : Groupoid C
S✝ : Subgroupoid C
D : Type u_1
inst✝ : Groupoid D
φ : C ⥤ D
hφ : Function.Injective φ.obj
S : Subgroupoid C
e✝ c d : D
c✝ d✝ : C
f : c✝ ⟶ d✝
hf : f ∈ arrows S c✝ d✝
q : φ.obj d✝ ⟶ e✝
hq : q ∈ (fun c d => {x | Map.Arrows φ hφ S c d x}) (φ.obj d✝) e✝
⊢ φ.map f ≫ q ∈ (fun c d => {x | Map.Arrows φ hφ S c d x}) (φ.obj c✝) e✝

Next tactic:
obtain ⟨c₃, c₄, g, he, rfl, hg, gq⟩ := (Map.arrows_iff φ hφ S q).mp hq
/-- The "forward" image of a subgroupoid under a functor injective on objects -/
def map (hφ : Function.Injective φ.obj) (S : Subgroupoid C) : Subgroupoid D where
  arrows c d := {x | Map.Arrows φ hφ S c d x}
  inv := by
    rintro _ _ _ ⟨⟩
    rw [inv_eq_inv, ← Functor.map_inv, ← inv_eq_inv]
    constructor; apply S.inv; assumption
  mul := by
    rintro _ _ _ _ ⟨f, hf⟩ q hq
    obtain ⟨c₃, c₄, g, he, rfl, hg, gq⟩ := (Map.arrows_iff φ hφ S q).mp hq
    

Proof state:
case im.intro.intro.intro.intro.intro.intro
C : Type u
inst✝¹ : Groupoid C
S✝ : Subgroupoid C
D : Type u_1
inst✝ : Groupoid D
φ : C ⥤ D
hφ : Function.Injective φ.obj
S : Subgroupoid C
c d : D
c✝ d✝ : C
f : c✝ ⟶ d✝
hf : f ∈ arrows S c✝ d✝
c₃ c₄ : C
g : c₃ ⟶ c₄
he : φ.obj c₃ = φ.obj d✝
q : φ.obj d✝ ⟶ φ.obj c₄
hq : q ∈ (fun c d => {x | Map.Arrows φ hφ S c d x}) (φ.obj d✝) (φ.obj c₄)
hg : g ∈ arrows S c₃ c₄
gq : q = eqToHom (_ : φ.obj d✝ = φ.obj c₃) ≫ φ.map g ≫ eqToHom (_ : φ.obj c₄ = φ.obj c₄)
⊢ φ.map f ≫ q ∈ (fun c d => {x | Map.Arrows φ hφ S c d x}) (φ.obj c✝) (φ.obj c₄)

Next tactic:
cases hφ he
/-- The "forward" image of a subgroupoid under a functor injective on objects -/
def map (hφ : Function.Injective φ.obj) (S : Subgroupoid C) : Subgroupoid D where
  arrows c d := {x | Map.Arrows φ hφ S c d x}
  inv := by
    rintro _ _ _ ⟨⟩
    rw [inv_eq_inv, ← Functor.map_inv, ← inv_eq_inv]
    constructor; apply S.inv; assumption
  mul := by
    rintro _ _ _ _ ⟨f, hf⟩ q hq
    obtain ⟨c₃, c₄, g, he, rfl, hg, gq⟩ := (Map.arrows_iff φ hφ S q).mp hq
    cases hφ he; 

Proof state:
case im.intro.intro.intro.intro.intro.intro.refl
C : Type u
inst✝¹ : Groupoid C
S✝ : Subgroupoid C
D : Type u_1
inst✝ : Groupoid D
φ : C ⥤ D
hφ : Function.Injective φ.obj
S : Subgroupoid C
c d : D
c✝ d✝ : C
f : c✝ ⟶ d✝
hf : f ∈ arrows S c✝ d✝
c₄ : C
q : φ.obj d✝ ⟶ φ.obj c₄
hq : q ∈ (fun c d => {x | Map.Arrows φ hφ S c d x}) (φ.obj d✝) (φ.obj c₄)
g : d✝ ⟶ c₄
he : φ.obj d✝ = φ.obj d✝
hg : g ∈ arrows S d✝ c₄
gq : q = eqToHom (_ : φ.obj d✝ = φ.obj d✝) ≫ φ.map g ≫ eqToHom (_ : φ.obj c₄ = φ.obj c₄)
⊢ φ.map f ≫ q ∈ (fun c d => {x | Map.Arrows φ hφ S c d x}) (φ.obj c✝) (φ.obj c₄)

Next tactic:
rw [gq, ← eq_conj_eqToHom, ← φ.map_comp]
/-- The "forward" image of a subgroupoid under a functor injective on objects -/
def map (hφ : Function.Injective φ.obj) (S : Subgroupoid C) : Subgroupoid D where
  arrows c d := {x | Map.Arrows φ hφ S c d x}
  inv := by
    rintro _ _ _ ⟨⟩
    rw [inv_eq_inv, ← Functor.map_inv, ← inv_eq_inv]
    constructor; apply S.inv; assumption
  mul := by
    rintro _ _ _ _ ⟨f, hf⟩ q hq
    obtain ⟨c₃, c₄, g, he, rfl, hg, gq⟩ := (Map.arrows_iff φ hφ S q).mp hq
    cases hφ he; rw [gq, ← eq_conj_eqToHom, ← φ.map_comp]
    

Proof state:
case im.intro.intro.intro.intro.intro.intro.refl
C : Type u
inst✝¹ : Groupoid C
S✝ : Subgroupoid C
D : Type u_1
inst✝ : Groupoid D
φ : C ⥤ D
hφ : Function.Injective φ.obj
S : Subgroupoid C
c d : D
c✝ d✝ : C
f : c✝ ⟶ d✝
hf : f ∈ arrows S c✝ d✝
c₄ : C
q : φ.obj d✝ ⟶ φ.obj c₄
hq : q ∈ (fun c d => {x | Map.Arrows φ hφ S c d x}) (φ.obj d✝) (φ.obj c₄)
g : d✝ ⟶ c₄
he : φ.obj d✝ = φ.obj d✝
hg : g ∈ arrows S d✝ c₄
gq : q = eqToHom (_ : φ.obj d✝ = φ.obj d✝) ≫ φ.map g ≫ eqToHom (_ : φ.obj c₄ = φ.obj c₄)
⊢ φ.map (f ≫ g) ∈ (fun c d => {x | Map.Arrows φ hφ S c d x}) (φ.obj c✝) (φ.obj c₄)

Next tactic:
constructor
/-- The "forward" image of a subgroupoid under a functor injective on objects -/
def map (hφ : Function.Injective φ.obj) (S : Subgroupoid C) : Subgroupoid D where
  arrows c d := {x | Map.Arrows φ hφ S c d x}
  inv := by
    rintro _ _ _ ⟨⟩
    rw [inv_eq_inv, ← Functor.map_inv, ← inv_eq_inv]
    constructor; apply S.inv; assumption
  mul := by
    rintro _ _ _ _ ⟨f, hf⟩ q hq
    obtain ⟨c₃, c₄, g, he, rfl, hg, gq⟩ := (Map.arrows_iff φ hφ S q).mp hq
    cases hφ he; rw [gq, ← eq_conj_eqToHom, ← φ.map_comp]
    constructor; 

Proof state:
case im.intro.intro.intro.intro.intro.intro.refl.hf
C : Type u
inst✝¹ : Groupoid C
S✝ : Subgroupoid C
D : Type u_1
inst✝ : Groupoid D
φ : C ⥤ D
hφ : Function.Injective φ.obj
S : Subgroupoid C
c d : D
c✝ d✝ : C
f : c✝ ⟶ d✝
hf : f ∈ arrows S c✝ d✝
c₄ : C
q : φ.obj d✝ ⟶ φ.obj c₄
hq : q ∈ (fun c d => {x | Map.Arrows φ hφ S c d x}) (φ.obj d✝) (φ.obj c₄)
g : d✝ ⟶ c₄
he : φ.obj d✝ = φ.obj d✝
hg : g ∈ arrows S d✝ c₄
gq : q = eqToHom (_ : φ.obj d✝ = φ.obj d✝) ≫ φ.map g ≫ eqToHom (_ : φ.obj c₄ = φ.obj c₄)
⊢ f ≫ g ∈ arrows S c✝ c₄

Next tactic:
exact S.mul hf hg
theorem galoisConnection_map_comap (hφ : Function.Injective φ.obj) :
    GaloisConnection (map φ hφ) (comap φ) := by
  

Proof state:
C : Type u
inst✝¹ : Groupoid C
S : Subgroupoid C
D : Type u_1
inst✝ : Groupoid D
φ : C ⥤ D
hφ : Function.Injective φ.obj
⊢ GaloisConnection (map φ hφ) (comap φ)

Next tactic:
rintro S T
theorem galoisConnection_map_comap (hφ : Function.Injective φ.obj) :
    GaloisConnection (map φ hφ) (comap φ) := by
  rintro S T; 

Proof state:
C : Type u
inst✝¹ : Groupoid C
S✝ : Subgroupoid C
D : Type u_1
inst✝ : Groupoid D
φ : C ⥤ D
hφ : Function.Injective φ.obj
S : Subgroupoid C
T : Subgroupoid D
⊢ map φ hφ S ≤ T ↔ S ≤ comap φ T

Next tactic:
simp_rw [le_iff]
theorem galoisConnection_map_comap (hφ : Function.Injective φ.obj) :
    GaloisConnection (map φ hφ) (comap φ) := by
  rintro S T; simp_rw [le_iff]; 

Proof state:
C : Type u
inst✝¹ : Groupoid C
S✝ : Subgroupoid C
D : Type u_1
inst✝ : Groupoid D
φ : C ⥤ D
hφ : Function.Injective φ.obj
S : Subgroupoid C
T : Subgroupoid D
⊢ (∀ {c d : D}, arrows (map φ hφ S) c d ⊆ arrows T c d) ↔ ∀ {c d : C}, arrows S c d ⊆ arrows (comap φ T) c d

Next tactic:
constructor
theorem galoisConnection_map_comap (hφ : Function.Injective φ.obj) :
    GaloisConnection (map φ hφ) (comap φ) := by
  rintro S T; simp_rw [le_iff]; constructor
  · 

Proof state:
case mp
C : Type u
inst✝¹ : Groupoid C
S✝ : Subgroupoid C
D : Type u_1
inst✝ : Groupoid D
φ : C ⥤ D
hφ : Function.Injective φ.obj
S : Subgroupoid C
T : Subgroupoid D
⊢ (∀ {c d : D}, arrows (map φ hφ S) c d ⊆ arrows T c d) → ∀ {c d : C}, arrows S c d ⊆ arrows (comap φ T) c d

Next tactic:
exact fun h c d f fS => h (Map.Arrows.im f fS)
theorem galoisConnection_map_comap (hφ : Function.Injective φ.obj) :
    GaloisConnection (map φ hφ) (comap φ) := by
  rintro S T; simp_rw [le_iff]; constructor
  · exact fun h c d f fS => h (Map.Arrows.im f fS)
  · 

Proof state:
case mpr
C : Type u
inst✝¹ : Groupoid C
S✝ : Subgroupoid C
D : Type u_1
inst✝ : Groupoid D
φ : C ⥤ D
hφ : Function.Injective φ.obj
S : Subgroupoid C
T : Subgroupoid D
⊢ (∀ {c d : C}, arrows S c d ⊆ arrows (comap φ T) c d) → ∀ {c d : D}, arrows (map φ hφ S) c d ⊆ arrows T c d

Next tactic:
rintro h _ _ g ⟨a, gφS⟩
theorem galoisConnection_map_comap (hφ : Function.Injective φ.obj) :
    GaloisConnection (map φ hφ) (comap φ) := by
  rintro S T; simp_rw [le_iff]; constructor
  · exact fun h c d f fS => h (Map.Arrows.im f fS)
  · rintro h _ _ g ⟨a, gφS⟩
    

Proof state:
case mpr.im
C : Type u
inst✝¹ : Groupoid C
S✝ : Subgroupoid C
D : Type u_1
inst✝ : Groupoid D
φ : C ⥤ D
hφ : Function.Injective φ.obj
S : Subgroupoid C
T : Subgroupoid D
h : ∀ {c d : C}, arrows S c d ⊆ arrows (comap φ T) c d
c d : D
c✝ d✝ : C
a : c✝ ⟶ d✝
gφS : a ∈ arrows S c✝ d✝
⊢ φ.map a ∈ arrows T (φ.obj c✝) (φ.obj d✝)

Next tactic:
exact h gφS
theorem mem_map_objs_iff (hφ : Function.Injective φ.obj) (d : D) :
    d ∈ (map φ hφ S).objs ↔ ∃ c ∈ S.objs, φ.obj c = d := by
  

Proof state:
C : Type u
inst✝¹ : Groupoid C
S : Subgroupoid C
D : Type u_1
inst✝ : Groupoid D
φ : C ⥤ D
hφ : Function.Injective φ.obj
d : D
⊢ d ∈ objs (map φ hφ S) ↔ ∃ c ∈ objs S, φ.obj c = d

Next tactic:
dsimp [objs, map]
theorem mem_map_objs_iff (hφ : Function.Injective φ.obj) (d : D) :
    d ∈ (map φ hφ S).objs ↔ ∃ c ∈ S.objs, φ.obj c = d := by
  dsimp [objs, map]
  

Proof state:
C : Type u
inst✝¹ : Groupoid C
S : Subgroupoid C
D : Type u_1
inst✝ : Groupoid D
φ : C ⥤ D
hφ : Function.Injective φ.obj
d : D
⊢ Set.Nonempty {x | Map.Arrows φ hφ S d d x} ↔ ∃ c, Set.Nonempty (arrows S c c) ∧ φ.obj c = d

Next tactic:
constructor
theorem mem_map_objs_iff (hφ : Function.Injective φ.obj) (d : D) :
    d ∈ (map φ hφ S).objs ↔ ∃ c ∈ S.objs, φ.obj c = d := by
  dsimp [objs, map]
  constructor
  · 

Proof state:
case mp
C : Type u
inst✝¹ : Groupoid C
S : Subgroupoid C
D : Type u_1
inst✝ : Groupoid D
φ : C ⥤ D
hφ : Function.Injective φ.obj
d : D
⊢ Set.Nonempty {x | Map.Arrows φ hφ S d d x} → ∃ c, Set.Nonempty (arrows S c c) ∧ φ.obj c = d

Next tactic:
rintro ⟨f, hf⟩
theorem mem_map_objs_iff (hφ : Function.Injective φ.obj) (d : D) :
    d ∈ (map φ hφ S).objs ↔ ∃ c ∈ S.objs, φ.obj c = d := by
  dsimp [objs, map]
  constructor
  · rintro ⟨f, hf⟩
    

Proof state:
case mp.intro
C : Type u
inst✝¹ : Groupoid C
S : Subgroupoid C
D : Type u_1
inst✝ : Groupoid D
φ : C ⥤ D
hφ : Function.Injective φ.obj
d : D
f : d ⟶ d
hf : f ∈ {x | Map.Arrows φ hφ S d d x}
⊢ ∃ c, Set.Nonempty (arrows S c c) ∧ φ.obj c = d

Next tactic:
change Map.Arrows φ hφ S d d f at hf
theorem mem_map_objs_iff (hφ : Function.Injective φ.obj) (d : D) :
    d ∈ (map φ hφ S).objs ↔ ∃ c ∈ S.objs, φ.obj c = d := by
  dsimp [objs, map]
  constructor
  · rintro ⟨f, hf⟩
    change Map.Arrows φ hφ S d d f at hf; 

Proof state:
case mp.intro
C : Type u
inst✝¹ : Groupoid C
S : Subgroupoid C
D : Type u_1
inst✝ : Groupoid D
φ : C ⥤ D
hφ : Function.Injective φ.obj
d : D
f : d ⟶ d
hf : Map.Arrows φ hφ S d d f
⊢ ∃ c, Set.Nonempty (arrows S c c) ∧ φ.obj c = d

Next tactic:
rw [Map.arrows_iff] at hf
theorem mem_map_objs_iff (hφ : Function.Injective φ.obj) (d : D) :
    d ∈ (map φ hφ S).objs ↔ ∃ c ∈ S.objs, φ.obj c = d := by
  dsimp [objs, map]
  constructor
  · rintro ⟨f, hf⟩
    change Map.Arrows φ hφ S d d f at hf; rw [Map.arrows_iff] at hf
    

Proof state:
case mp.intro
C : Type u
inst✝¹ : Groupoid C
S : Subgroupoid C
D : Type u_1
inst✝ : Groupoid D
φ : C ⥤ D
hφ : Function.Injective φ.obj
d : D
f : d ⟶ d
hf :
  ∃ a b g,
    ∃ (ha : φ.obj a = d) (hb : φ.obj b = d) (_ : g ∈ arrows S a b), f = eqToHom (_ : d = φ.obj a) ≫ φ.map g ≫ eqToHom hb
⊢ ∃ c, Set.Nonempty (arrows S c c) ∧ φ.obj c = d

Next tactic:
obtain ⟨c, d, g, ec, ed, eg, gS, eg⟩ := hf
theorem mem_map_objs_iff (hφ : Function.Injective φ.obj) (d : D) :
    d ∈ (map φ hφ S).objs ↔ ∃ c ∈ S.objs, φ.obj c = d := by
  dsimp [objs, map]
  constructor
  · rintro ⟨f, hf⟩
    change Map.Arrows φ hφ S d d f at hf; rw [Map.arrows_iff] at hf
    obtain ⟨c, d, g, ec, ed, eg, gS, eg⟩ := hf
    

Proof state:
case mp.intro.intro.intro.intro.intro.intro.intro.refl
C : Type u
inst✝¹ : Groupoid C
S : Subgroupoid C
D : Type u_1
inst✝ : Groupoid D
φ : C ⥤ D
hφ : Function.Injective φ.obj
d✝ : D
c d : C
g : c ⟶ d
ec : φ.obj c = d✝
ed : φ.obj d = d✝
eg : g ∈ arrows S c d
⊢ ∃ c, Set.Nonempty (arrows S c c) ∧ φ.obj c = d✝

Next tactic:
exact ⟨c, ⟨mem_objs_of_src S eg, ec⟩⟩
theorem mem_map_objs_iff (hφ : Function.Injective φ.obj) (d : D) :
    d ∈ (map φ hφ S).objs ↔ ∃ c ∈ S.objs, φ.obj c = d := by
  dsimp [objs, map]
  constructor
  · rintro ⟨f, hf⟩
    change Map.Arrows φ hφ S d d f at hf; rw [Map.arrows_iff] at hf
    obtain ⟨c, d, g, ec, ed, eg, gS, eg⟩ := hf
    exact ⟨c, ⟨mem_objs_of_src S eg, ec⟩⟩
  · 

Proof state:
case mpr
C : Type u
inst✝¹ : Groupoid C
S : Subgroupoid C
D : Type u_1
inst✝ : Groupoid D
φ : C ⥤ D
hφ : Function.Injective φ.obj
d : D
⊢ (∃ c, Set.Nonempty (arrows S c c) ∧ φ.obj c = d) → Set.Nonempty {x | Map.Arrows φ hφ S d d x}

Next tactic:
rintro ⟨c, ⟨γ, γS⟩, rfl⟩
theorem mem_map_objs_iff (hφ : Function.Injective φ.obj) (d : D) :
    d ∈ (map φ hφ S).objs ↔ ∃ c ∈ S.objs, φ.obj c = d := by
  dsimp [objs, map]
  constructor
  · rintro ⟨f, hf⟩
    change Map.Arrows φ hφ S d d f at hf; rw [Map.arrows_iff] at hf
    obtain ⟨c, d, g, ec, ed, eg, gS, eg⟩ := hf
    exact ⟨c, ⟨mem_objs_of_src S eg, ec⟩⟩
  · rintro ⟨c, ⟨γ, γS⟩, rfl⟩
    

Proof state:
case mpr.intro.intro.intro
C : Type u
inst✝¹ : Groupoid C
S : Subgroupoid C
D : Type u_1
inst✝ : Groupoid D
φ : C ⥤ D
hφ : Function.Injective φ.obj
c : C
γ : c ⟶ c
γS : γ ∈ arrows S c c
⊢ Set.Nonempty {x | Map.Arrows φ hφ S (φ.obj c) (φ.obj c) x}

Next tactic:
exact ⟨φ.map γ, ⟨γ, γS⟩⟩
@[simp]
theorem map_objs_eq (hφ : Function.Injective φ.obj) : (map φ hφ S).objs = φ.obj '' S.objs := by
  

Proof state:
C : Type u
inst✝¹ : Groupoid C
S : Subgroupoid C
D : Type u_1
inst✝ : Groupoid D
φ : C ⥤ D
hφ : Function.Injective φ.obj
⊢ objs (map φ hφ S) = φ.obj '' objs S

Next tactic:
ext x
@[simp]
theorem map_objs_eq (hφ : Function.Injective φ.obj) : (map φ hφ S).objs = φ.obj '' S.objs := by
  ext x; 

Proof state:
case h
C : Type u
inst✝¹ : Groupoid C
S : Subgroupoid C
D : Type u_1
inst✝ : Groupoid D
φ : C ⥤ D
hφ : Function.Injective φ.obj
x : D
⊢ x ∈ objs (map φ hφ S) ↔ x ∈ φ.obj '' objs S

Next tactic:
convert mem_map_objs_iff S φ hφ x
theorem mem_im_iff (hφ : Function.Injective φ.obj) {c d : D} (f : c ⟶ d) :
    f ∈ (im φ hφ).arrows c d ↔
      ∃ (a b : C) (g : a ⟶ b) (ha : φ.obj a = c) (hb : φ.obj b = d),
        f = eqToHom ha.symm ≫ φ.map g ≫ eqToHom hb :=
  by 

Proof state:
C : Type u
inst✝¹ : Groupoid C
S : Subgroupoid C
D : Type u_1
inst✝ : Groupoid D
φ : C ⥤ D
hφ : Function.Injective φ.obj
c d : D
f : c ⟶ d
⊢ f ∈ arrows (im φ hφ) c d ↔
    ∃ a b g, ∃ (ha : φ.obj a = c) (hb : φ.obj b = d), f = eqToHom (_ : c = φ.obj a) ≫ φ.map g ≫ eqToHom hb

Next tactic:
convert Map.arrows_iff φ hφ ⊤ f
theorem mem_im_iff (hφ : Function.Injective φ.obj) {c d : D} (f : c ⟶ d) :
    f ∈ (im φ hφ).arrows c d ↔
      ∃ (a b : C) (g : a ⟶ b) (ha : φ.obj a = c) (hb : φ.obj b = d),
        f = eqToHom ha.symm ≫ φ.map g ≫ eqToHom hb :=
  by convert Map.arrows_iff φ hφ ⊤ f; 

Proof state:
case h.e'_2.h.e'_2.h.h.e'_2.h.h.e'_2.h.h.e'_2.h.h.e'_2.h.a
C : Type u
inst✝¹ : Groupoid C
S : Subgroupoid C
D : Type u_1
inst✝ : Groupoid D
φ : C ⥤ D
hφ : Function.Injective φ.obj
c d : D
f : c ⟶ d
x✝⁴ x✝³ : C
x✝² : x✝⁴ ⟶ x✝³
x✝¹ : φ.obj x✝⁴ = c
x✝ : φ.obj x✝³ = d
⊢ f = eqToHom (_ : c = φ.obj x✝⁴) ≫ φ.map x✝² ≫ eqToHom x✝ ↔
    ∃ (_ : x✝² ∈ arrows ⊤ x✝⁴ x✝³), f = eqToHom (_ : c = φ.obj x✝⁴) ≫ φ.map x✝² ≫ eqToHom x✝

Next tactic:
simp only [Top.top, mem_univ, exists_true_left]
theorem mem_im_objs_iff (hφ : Function.Injective φ.obj) (d : D) :
    d ∈ (im φ hφ).objs ↔ ∃ c : C, φ.obj c = d := by
  

Proof state:
C : Type u
inst✝¹ : Groupoid C
S : Subgroupoid C
D : Type u_1
inst✝ : Groupoid D
φ : C ⥤ D
hφ : Function.Injective φ.obj
d : D
⊢ d ∈ objs (im φ hφ) ↔ ∃ c, φ.obj c = d

Next tactic:
simp only [im, mem_map_objs_iff, mem_top_objs, true_and]
theorem obj_surjective_of_im_eq_top (hφ : Function.Injective φ.obj) (hφ' : im φ hφ = ⊤) :
    Function.Surjective φ.obj := by
  

Proof state:
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φ = ⊤
⊢ Function.Surjective φ.obj

Next tactic:
rintro d
theorem obj_surjective_of_im_eq_top (hφ : Function.Injective φ.obj) (hφ' : im φ hφ = ⊤) :
    Function.Surjective φ.obj := by
  rintro d
  

Proof state:
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φ = ⊤
d : D
⊢ ∃ a, φ.obj a = d

Next tactic:
rw [← mem_im_objs_iff, hφ']
theorem obj_surjective_of_im_eq_top (hφ : Function.Injective φ.obj) (hφ' : im φ hφ = ⊤) :
    Function.Surjective φ.obj := by
  rintro d
  rw [← mem_im_objs_iff, hφ']
  

Proof state:
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φ = ⊤
d : D
⊢ d ∈ objs ⊤

Next tactic:
apply mem_top_objs
theorem isNormal_map (hφ : Function.Injective φ.obj) (hφ' : im φ hφ = ⊤) (Sn : S.IsNormal) :
    (map φ hφ S).IsNormal :=
  { wide := fun d => by
      

Proof state:
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
d : D
⊢ 𝟙 d ∈ arrows (map φ hφ S) d d

Next tactic:
obtain ⟨c, rfl⟩ := obj_surjective_of_im_eq_top φ hφ hφ' d
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
      

Proof state:
case intro
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
⊢ 𝟙 (φ.obj c) ∈ arrows (map φ hφ S) (φ.obj c) (φ.obj c)

Next tactic:
change Map.Arrows φ hφ S _ _ (𝟙 _)
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 _ _ (𝟙 _); 

Proof state:
case intro
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
⊢ Map.Arrows φ hφ S (φ.obj c) (φ.obj c) (𝟙 (φ.obj c))

Next tactic:
rw [← Functor.map_id]
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]
      

Proof state:
case intro
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
⊢ Map.Arrows φ hφ S (φ.obj c) (φ.obj c) (φ.map (𝟙 c))

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; 

Proof state:
case intro.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 ∈ arrows S c c

Next tactic:
exact Sn.wide c
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
      

Proof state:
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
d d' : D
g : d ⟶ d'
δ : d ⟶ d
hδ : δ ∈ arrows (map φ hφ S) d d
⊢ Groupoid.inv g ≫ δ ≫ g ∈ arrows (map φ hφ S) d' d'

Next tactic:
rw [mem_map_iff] at hδ
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δ
      

Proof state:
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
d d' : D
g : d ⟶ d'
δ : d ⟶ d
hδ :
  ∃ a b g,
    ∃ (ha : φ.obj a = d) (hb : φ.obj b = d) (_ : g ∈ arrows S a b), δ = eqToHom (_ : d = φ.obj a) ≫ φ.map g ≫ eqToHom hb
⊢ Groupoid.inv g ≫ δ ≫ g ∈ arrows (map φ hφ S) d' d'

Next tactic:
obtain ⟨c, c', γ, cd, cd', γS, hγ⟩ := hδ