-- Mathlib/CategoryTheory/Category/RelCat.lean
theorem rel_iso_iff {X Y : RelCat} (r : X ⟶ Y) :
    IsIso (C := RelCat) r ↔ ∃ f : (Iso (C := Type u) X Y), graphFunctor.map f.hom = r

Proof state:
case mp
X Y : RelCat
r : X ⟶ Y
h : IsIso r
h1 : ∀ (a b : X), (r ≫ inv r) a b = 𝟙 X a b
h2 : ∀ (a b : Y), (inv r ≫ r) a b = 𝟙 Y a b
⊢ ∃ f, graphFunctor.map f.hom = r

Tactic:
simp only [RelCat.Hom.rel_comp_apply₂, RelCat.Hom.rel_id_apply₂, eq_iff_iff] at h1 h2

Result:
case mp
X Y : RelCat
r : X ⟶ Y
h : IsIso r
h1 : ∀ (a b : X), (∃ y, r a y ∧ inv r y b) ↔ a = b
h2 : ∀ (a b : Y), (∃ y, inv r a y ∧ r y b) ↔ a = b
⊢ ∃ f, graphFunctor.map f.hom = r

Proof state:
case h.h.mpr
X Y : RelCat
r : X ⟶ Y
h : IsIso r
h1 : ∀ (a b : X), (∃ y, r a y ∧ inv r y b) ↔ a = b
f : X → Y
hf : ∀ (x : X), r x (f x) ∧ inv r (f x) x
g : Y → X
hg : ∀ (x : Y), inv r x (g x) ∧ r (g x) x
hif : IsIso f
x : graphFunctor.obj X
y : graphFunctor.obj Y
hr : r x y
h2 : (∃ y_1, inv r (f x) y_1 ∧ r y_1 y) ↔ f x = y
⊢ ∃ y_1, inv r (f x) y_1 ∧ r y_1 y

Tactic:
use x, (hf x).2, hr

Result:
no goals

Proof state:
case h.right.h
X Y : RelCat
r : X ⟶ Y
h : IsIso r
h1 : ∀ (a b : X), (∃ y, r a y ∧ inv r y b) ↔ a = b
h2 : ∀ (a b : Y), (∃ y, inv r a y ∧ r y b) ↔ a = b
f : X → Y
hf : ∀ (x : X), r x (f x) ∧ inv r (f x) x
g : Y → X
hg : ∀ (x : Y), inv r x (g x) ∧ r (g x) x
y : Y
⊢ ∃ y_1, inv r ((g ≫ f) y) y_1 ∧ r y_1 (𝟙 Y y)

Tactic:
use g y, (hf (g y)).2, (hg y).2

Result:
no goals

Proof state:
case mpr.intro
X Y : RelCat
f : X ≅ Y
⊢ IsIso (graphFunctor.map f.hom)

Tactic:
apply graphFunctor.map_isIso

Result:
no goals

Proof state:
case h.h.mp
X Y : RelCat
r : X ⟶ Y
h : IsIso r
h1 : ∀ (a b : X), (∃ y, r a y ∧ inv r y b) ↔ a = b
h2 : ∀ (a b : Y), (∃ y, inv r a y ∧ r y b) ↔ a = b
f : X → Y
hf : ∀ (x : X), r x (f x) ∧ inv r (f x) x
g : Y → X
hg : ∀ (x : Y), inv r x (g x) ∧ r (g x) x
hif : IsIso f
x : graphFunctor.obj X
⊢ r x (f x)

Tactic:
exact (hf x).1

Result:
no goals

Proof state:
case mp
X Y : RelCat
r : X ⟶ Y
h : IsIso r
h1 : ∀ (a b : X), (∃ y, r a y ∧ inv r y b) ↔ a = b
h2 : ∀ (a b : Y), (∃ y, inv r a y ∧ r y b) ↔ a = b
⊢ ∃ f, graphFunctor.map f.hom = r

Tactic:
obtain ⟨f, hf⟩ := Classical.axiomOfChoice (fun a => (h1 a a).mpr rfl)

Result:
case mp.intro
X Y : RelCat
r : X ⟶ Y
h : IsIso r
h1 : ∀ (a b : X), (∃ y, r a y ∧ inv r y b) ↔ a = b
h2 : ∀ (a b : Y), (∃ y, inv r a y ∧ r y b) ↔ a = b
f : X → Y
hf : ∀ (x : X), r x (f x) ∧ inv r (f x) x
⊢ ∃ f, graphFunctor.map f.hom = r

Proof state:
case mp.intro
X Y : RelCat
r : X ⟶ Y
h : IsIso r
h1 : ∀ (a b : X), (∃ y, r a y ∧ inv r y b) ↔ a = b
h2 : ∀ (a b : Y), (∃ y, inv r a y ∧ r y b) ↔ a = b
f : X → Y
hf : ∀ (x : X), r x (f x) ∧ inv r (f x) x
⊢ ∃ f, graphFunctor.map f.hom = r

Tactic:
obtain ⟨g, hg⟩ := Classical.axiomOfChoice (fun a => (h2 a a).mpr rfl)

Result:
case mp.intro.intro
X Y : RelCat
r : X ⟶ Y
h : IsIso r
h1 : ∀ (a b : X), (∃ y, r a y ∧ inv r y b) ↔ a = b
h2 : ∀ (a b : Y), (∃ y, inv r a y ∧ r y b) ↔ a = b
f : X → Y
hf : ∀ (x : X), r x (f x) ∧ inv r (f x) x
g : Y → X
hg : ∀ (x : Y), inv r x (g x) ∧ r (g x) x
⊢ ∃ f, graphFunctor.map f.hom = r

Proof state:
case mp
X Y : RelCat
r : X ⟶ Y
h : IsIso r
h1 : ∀ (a b : X), (r ≫ inv r) a b = 𝟙 X a b
⊢ ∃ f, graphFunctor.map f.hom = r

Tactic:
have h2 := congr_fun₂ h.inv_hom_id

Result:
case mp
X Y : RelCat
r : X ⟶ Y
h : IsIso r
h1 : ∀ (a b : X), (r ≫ inv r) a b = 𝟙 X a b
h2 : ∀ (a b : Y), (inv r ≫ r) a b = 𝟙 Y a b
⊢ ∃ f, graphFunctor.map f.hom = r

Proof state:
case h
X Y : RelCat
r : X ⟶ Y
h : IsIso r
h1 : ∀ (a b : X), (∃ y, r a y ∧ inv r y b) ↔ a = b
h2 : ∀ (a b : Y), (∃ y, inv r a y ∧ r y b) ↔ a = b
f : X → Y
hf : ∀ (x : X), r x (f x) ∧ inv r (f x) x
g : Y → X
hg : ∀ (x : Y), inv r x (g x) ∧ r (g x) x
⊢ f ≫ g = 𝟙 X ∧ g ≫ f = 𝟙 Y

Tactic:
constructor

Result:
case h.left
X Y : RelCat
r : X ⟶ Y
h : IsIso r
h1 : ∀ (a b : X), (∃ y, r a y ∧ inv r y b) ↔ a = b
h2 : ∀ (a b : Y), (∃ y, inv r a y ∧ r y b) ↔ a = b
f : X → Y
hf : ∀ (x : X), r x (f x) ∧ inv r (f x) x
g : Y → X
hg : ∀ (x : Y), inv r x (g x) ∧ r (g x) x
⊢ f ≫ g = 𝟙 X

case h.right
X Y : RelCat
r : X ⟶ Y
h : IsIso r
h1 : ∀ (a b : X), (∃ y, r a y ∧ inv r y b) ↔ a = b
h2 : ∀ (a b : Y), (∃ y, inv r a y ∧ r y b) ↔ a = b
f : X → Y
hf : ∀ (x : X), r x (f x) ∧ inv r (f x) x
g : Y → X
hg : ∀ (x : Y), inv r x (g x) ∧ r (g x) x
⊢ g ≫ f = 𝟙 Y

Proof state:
X Y : RelCat
r : X ⟶ Y
⊢ IsIso r ↔ ∃ f, graphFunctor.map f.hom = r

Tactic:
constructor

Result:
case mp
X Y : RelCat
r : X ⟶ Y
⊢ IsIso r → ∃ f, graphFunctor.map f.hom = r

case mpr
X Y : RelCat
r : X ⟶ Y
⊢ (∃ f, graphFunctor.map f.hom = r) → IsIso r

Proof state:
case h.left
X Y : RelCat
r : X ⟶ Y
h : IsIso r
h1 : ∀ (a b : X), (∃ y, r a y ∧ inv r y b) ↔ a = b
h2 : ∀ (a b : Y), (∃ y, inv r a y ∧ r y b) ↔ a = b
f : X → Y
hf : ∀ (x : X), r x (f x) ∧ inv r (f x) x
g : Y → X
hg : ∀ (x : Y), inv r x (g x) ∧ r (g x) x
⊢ f ≫ g = 𝟙 X

Tactic:
ext x

Result:
case h.left.h
X Y : RelCat
r : X ⟶ Y
h : IsIso r
h1 : ∀ (a b : X), (∃ y, r a y ∧ inv r y b) ↔ a = b
h2 : ∀ (a b : Y), (∃ y, inv r a y ∧ r y b) ↔ a = b
f : X → Y
hf : ∀ (x : X), r x (f x) ∧ inv r (f x) x
g : Y → X
hg : ∀ (x : Y), inv r x (g x) ∧ r (g x) x
x : X
⊢ (f ≫ g) x = 𝟙 X x

Proof state:
case h.right
X Y : RelCat
r : X ⟶ Y
h : IsIso r
h1 : ∀ (a b : X), (∃ y, r a y ∧ inv r y b) ↔ a = b
h2 : ∀ (a b : Y), (∃ y, inv r a y ∧ r y b) ↔ a = b
f : X → Y
hf : ∀ (x : X), r x (f x) ∧ inv r (f x) x
g : Y → X
hg : ∀ (x : Y), inv r x (g x) ∧ r (g x) x
⊢ g ≫ f = 𝟙 Y

Tactic:
ext y

Result:
case h.right.h
X Y : RelCat
r : X ⟶ Y
h : IsIso r
h1 : ∀ (a b : X), (∃ y, r a y ∧ inv r y b) ↔ a = b
h2 : ∀ (a b : Y), (∃ y, inv r a y ∧ r y b) ↔ a = b
f : X → Y
hf : ∀ (x : X), r x (f x) ∧ inv r (f x) x
g : Y → X
hg : ∀ (x : Y), inv r x (g x) ∧ r (g x) x
y : Y
⊢ (g ≫ f) y = 𝟙 Y y

Proof state:
case h.right.h
X Y : RelCat
r : X ⟶ Y
h : IsIso r
h1 : ∀ (a b : X), (∃ y, r a y ∧ inv r y b) ↔ a = b
h2 : ∀ (a b : Y), (∃ y, inv r a y ∧ r y b) ↔ a = b
f : X → Y
hf : ∀ (x : X), r x (f x) ∧ inv r (f x) x
g : Y → X
hg : ∀ (x : Y), inv r x (g x) ∧ r (g x) x
y : Y
⊢ (g ≫ f) y = 𝟙 Y y

Tactic:
apply (h2 _ _).mp

Result:
case h.right.h
X Y : RelCat
r : X ⟶ Y
h : IsIso r
h1 : ∀ (a b : X), (∃ y, r a y ∧ inv r y b) ↔ a = b
h2 : ∀ (a b : Y), (∃ y, inv r a y ∧ r y b) ↔ a = b
f : X → Y
hf : ∀ (x : X), r x (f x) ∧ inv r (f x) x
g : Y → X
hg : ∀ (x : Y), inv r x (g x) ∧ r (g x) x
y : Y
⊢ ∃ y_1, inv r ((g ≫ f) y) y_1 ∧ r y_1 (𝟙 Y y)

Proof state:
case h.left.h
X Y : RelCat
r : X ⟶ Y
h : IsIso r
h1 : ∀ (a b : X), (∃ y, r a y ∧ inv r y b) ↔ a = b
h2 : ∀ (a b : Y), (∃ y, inv r a y ∧ r y b) ↔ a = b
f : X → Y
hf : ∀ (x : X), r x (f x) ∧ inv r (f x) x
g : Y → X
hg : ∀ (x : Y), inv r x (g x) ∧ r (g x) x
x : X
⊢ ∃ y, r ((f ≫ g) x) y ∧ inv r y (𝟙 X x)

Tactic:
use f x, (hg _).2, (hf _).2

Result:
no goals

Proof state:
case h.h.mpr
X Y : RelCat
r : X ⟶ Y
h : IsIso r
h1 : ∀ (a b : X), (∃ y, r a y ∧ inv r y b) ↔ a = b
f : X → Y
hf : ∀ (x : X), r x (f x) ∧ inv r (f x) x
g : Y → X
hg : ∀ (x : Y), inv r x (g x) ∧ r (g x) x
hif : IsIso f
x : graphFunctor.obj X
y : graphFunctor.obj Y
hr : r x y
h2 : (∃ y_1, inv r (f x) y_1 ∧ r y_1 y) ↔ f x = y
⊢ f x = y

Tactic:
rw [← h2]

Result:
case h.h.mpr
X Y : RelCat
r : X ⟶ Y
h : IsIso r
h1 : ∀ (a b : X), (∃ y, r a y ∧ inv r y b) ↔ a = b
f : X → Y
hf : ∀ (x : X), r x (f x) ∧ inv r (f x) x
g : Y → X
hg : ∀ (x : Y), inv r x (g x) ∧ r (g x) x
hif : IsIso f
x : graphFunctor.obj X
y : graphFunctor.obj Y
hr : r x y
h2 : (∃ y_1, inv r (f x) y_1 ∧ r y_1 y) ↔ f x = y
⊢ ∃ y_1, inv r (f x) y_1 ∧ r y_1 y