l3lab/ntp-mathlib huggingface dataset:
/-- Two maps out of the semidirect product are equal if they're equal after composition
  with both `inl` and `inr` -/
theorem hom_ext {f g : N ⋊[φ] G →* H} (hl : f.comp inl = g.comp inl)
    (hr : f.comp inr = g.comp inr) : f = g := by
  rw [lift_unique f, lift_unique g]
  

Proof state:
N : Type u_1
G : Type u_2
H : Type u_3
inst✝² : Group N
inst✝¹ : Group G
inst✝ : Group H
φ : G →* MulAut N
f₁ : N →* H
f₂ : G →* H
h :
  ∀ (g : G),
    MonoidHom.comp f₁ (MulEquiv.toMonoidHom (φ g)) = MonoidHom.comp (MulEquiv.toMonoidHom (MulAut.conj (f₂ g))) f₁
f g : N ⋊[φ] G →* H
hl : MonoidHom.comp f inl = MonoidHom.comp g inl
hr : MonoidHom.comp f inr = MonoidHom.comp g inr
⊢ lift (MonoidHom.comp f inl) (MonoidHom.comp f inr)
      (_ :
        ∀ (x : G),
          MonoidHom.comp (MonoidHom.comp f inl) (MulEquiv.toMonoidHom (φ x)) =
            MonoidHom.comp (MulEquiv.toMonoidHom (MulAut.conj ((MonoidHom.comp f inr) x))) (MonoidHom.comp f inl)) =
    lift (MonoidHom.comp g inl) (MonoidHom.comp g inr)
      (_ :
        ∀ (x : G),
          MonoidHom.comp (MonoidHom.comp g inl) (MulEquiv.toMonoidHom (φ x)) =
            MonoidHom.comp (MulEquiv.toMonoidHom (MulAut.conj ((MonoidHom.comp g inr) x))) (MonoidHom.comp g inl))

Next tactic:
simp only [*]
/-- Define a map from `N ⋊[φ] G` to `N₁ ⋊[φ₁] G₁` given maps `N →* N₁` and `G →* G₁` that
  satisfy a commutativity condition `∀ n g, f₁ (φ g n) = φ₁ (f₂ g) (f₁ n)`.  -/
def map (f₁ : N →* N₁) (f₂ : G →* G₁)
    (h : ∀ g : G, f₁.comp (φ g).toMonoidHom = (φ₁ (f₂ g)).toMonoidHom.comp f₁) :
    N ⋊[φ] G →* N₁ ⋊[φ₁] G₁ where
  toFun x := ⟨f₁ x.1, f₂ x.2⟩
  map_one' := by 

Proof state:
N : Type u_1
G : Type u_2
H : Type u_3
inst✝⁴ : Group N
inst✝³ : Group G
inst✝² : Group H
φ : G →* MulAut N
N₁ : Type u_4
G₁ : Type u_5
inst✝¹ : Group N₁
inst✝ : Group G₁
φ₁ : G₁ →* MulAut N₁
f₁ : N →* N₁
f₂ : G →* G₁
h : ∀ (g : G), MonoidHom.comp f₁ (MulEquiv.toMonoidHom (φ g)) = MonoidHom.comp (MulEquiv.toMonoidHom (φ₁ (f₂ g))) f₁
⊢ (fun x => { left := f₁ x.left, right := f₂ x.right }) 1 = 1

Next tactic:
simp
/-- Define a map from `N ⋊[φ] G` to `N₁ ⋊[φ₁] G₁` given maps `N →* N₁` and `G →* G₁` that
  satisfy a commutativity condition `∀ n g, f₁ (φ g n) = φ₁ (f₂ g) (f₁ n)`.  -/
def map (f₁ : N →* N₁) (f₂ : G →* G₁)
    (h : ∀ g : G, f₁.comp (φ g).toMonoidHom = (φ₁ (f₂ g)).toMonoidHom.comp f₁) :
    N ⋊[φ] G →* N₁ ⋊[φ₁] G₁ where
  toFun x := ⟨f₁ x.1, f₂ x.2⟩
  map_one' := by simp
  map_mul' x y := by
    

Proof state:
N : Type u_1
G : Type u_2
H : Type u_3
inst✝⁴ : Group N
inst✝³ : Group G
inst✝² : Group H
φ : G →* MulAut N
N₁ : Type u_4
G₁ : Type u_5
inst✝¹ : Group N₁
inst✝ : Group G₁
φ₁ : G₁ →* MulAut N₁
f₁ : N →* N₁
f₂ : G →* G₁
h : ∀ (g : G), MonoidHom.comp f₁ (MulEquiv.toMonoidHom (φ g)) = MonoidHom.comp (MulEquiv.toMonoidHom (φ₁ (f₂ g))) f₁
x y : N ⋊[φ] G
⊢ OneHom.toFun
      { toFun := fun x => { left := f₁ x.left, right := f₂ x.right },
        map_one' := (_ : { left := f₁ 1, right := f₂ 1 } = 1) }
      (x * y) =
    OneHom.toFun
        { toFun := fun x => { left := f₁ x.left, right := f₂ x.right },
          map_one' := (_ : { left := f₁ 1, right := f₂ 1 } = 1) }
        x *
      OneHom.toFun
        { toFun := fun x => { left := f₁ x.left, right := f₂ x.right },
          map_one' := (_ : { left := f₁ 1, right := f₂ 1 } = 1) }
        y

Next tactic:
replace h := FunLike.ext_iff.1 (h x.right) y.left
/-- Define a map from `N ⋊[φ] G` to `N₁ ⋊[φ₁] G₁` given maps `N →* N₁` and `G →* G₁` that
  satisfy a commutativity condition `∀ n g, f₁ (φ g n) = φ₁ (f₂ g) (f₁ n)`.  -/
def map (f₁ : N →* N₁) (f₂ : G →* G₁)
    (h : ∀ g : G, f₁.comp (φ g).toMonoidHom = (φ₁ (f₂ g)).toMonoidHom.comp f₁) :
    N ⋊[φ] G →* N₁ ⋊[φ₁] G₁ where
  toFun x := ⟨f₁ x.1, f₂ x.2⟩
  map_one' := by simp
  map_mul' x y := by
    replace h := FunLike.ext_iff.1 (h x.right) y.left
    

Proof state:
N : Type u_1
G : Type u_2
H : Type u_3
inst✝⁴ : Group N
inst✝³ : Group G
inst✝² : Group H
φ : G →* MulAut N
N₁ : Type u_4
G₁ : Type u_5
inst✝¹ : Group N₁
inst✝ : Group G₁
φ₁ : G₁ →* MulAut N₁
f₁ : N →* N₁
f₂ : G →* G₁
x y : N ⋊[φ] G
h :
  (MonoidHom.comp f₁ (MulEquiv.toMonoidHom (φ x.right))) y.left =
    (MonoidHom.comp (MulEquiv.toMonoidHom (φ₁ (f₂ x.right))) f₁) y.left
⊢ OneHom.toFun
      { toFun := fun x => { left := f₁ x.left, right := f₂ x.right },
        map_one' := (_ : { left := f₁ 1, right := f₂ 1 } = 1) }
      (x * y) =
    OneHom.toFun
        { toFun := fun x => { left := f₁ x.left, right := f₂ x.right },
          map_one' := (_ : { left := f₁ 1, right := f₂ 1 } = 1) }
        x *
      OneHom.toFun
        { toFun := fun x => { left := f₁ x.left, right := f₂ x.right },
          map_one' := (_ : { left := f₁ 1, right := f₂ 1 } = 1) }
        y

Next tactic:
ext
/-- Define a map from `N ⋊[φ] G` to `N₁ ⋊[φ₁] G₁` given maps `N →* N₁` and `G →* G₁` that
  satisfy a commutativity condition `∀ n g, f₁ (φ g n) = φ₁ (f₂ g) (f₁ n)`.  -/
def map (f₁ : N →* N₁) (f₂ : G →* G₁)
    (h : ∀ g : G, f₁.comp (φ g).toMonoidHom = (φ₁ (f₂ g)).toMonoidHom.comp f₁) :
    N ⋊[φ] G →* N₁ ⋊[φ₁] G₁ where
  toFun x := ⟨f₁ x.1, f₂ x.2⟩
  map_one' := by simp
  map_mul' x y := by
    replace h := FunLike.ext_iff.1 (h x.right) y.left
    ext <;> 

Proof state:
case left
N : Type u_1
G : Type u_2
H : Type u_3
inst✝⁴ : Group N
inst✝³ : Group G
inst✝² : Group H
φ : G →* MulAut N
N₁ : Type u_4
G₁ : Type u_5
inst✝¹ : Group N₁
inst✝ : Group G₁
φ₁ : G₁ →* MulAut N₁
f₁ : N →* N₁
f₂ : G →* G₁
x y : N ⋊[φ] G
h :
  (MonoidHom.comp f₁ (MulEquiv.toMonoidHom (φ x.right))) y.left =
    (MonoidHom.comp (MulEquiv.toMonoidHom (φ₁ (f₂ x.right))) f₁) y.left
⊢ (OneHom.toFun
        { toFun := fun x => { left := f₁ x.left, right := f₂ x.right },
          map_one' := (_ : { left := f₁ 1, right := f₂ 1 } = 1) }
        (x * y)).left =
    (OneHom.toFun
          { toFun := fun x => { left := f₁ x.left, right := f₂ x.right },
            map_one' := (_ : { left := f₁ 1, right := f₂ 1 } = 1) }
          x *
        OneHom.toFun
          { toFun := fun x => { left := f₁ x.left, right := f₂ x.right },
            map_one' := (_ : { left := f₁ 1, right := f₂ 1 } = 1) }
          y).left

Next tactic:
simp_all
/-- Define a map from `N ⋊[φ] G` to `N₁ ⋊[φ₁] G₁` given maps `N →* N₁` and `G →* G₁` that
  satisfy a commutativity condition `∀ n g, f₁ (φ g n) = φ₁ (f₂ g) (f₁ n)`.  -/
def map (f₁ : N →* N₁) (f₂ : G →* G₁)
    (h : ∀ g : G, f₁.comp (φ g).toMonoidHom = (φ₁ (f₂ g)).toMonoidHom.comp f₁) :
    N ⋊[φ] G →* N₁ ⋊[φ₁] G₁ where
  toFun x := ⟨f₁ x.1, f₂ x.2⟩
  map_one' := by simp
  map_mul' x y := by
    replace h := FunLike.ext_iff.1 (h x.right) y.left
    ext <;> 

Proof state:
case right
N : Type u_1
G : Type u_2
H : Type u_3
inst✝⁴ : Group N
inst✝³ : Group G
inst✝² : Group H
φ : G →* MulAut N
N₁ : Type u_4
G₁ : Type u_5
inst✝¹ : Group N₁
inst✝ : Group G₁
φ₁ : G₁ →* MulAut N₁
f₁ : N →* N₁
f₂ : G →* G₁
x y : N ⋊[φ] G
h :
  (MonoidHom.comp f₁ (MulEquiv.toMonoidHom (φ x.right))) y.left =
    (MonoidHom.comp (MulEquiv.toMonoidHom (φ₁ (f₂ x.right))) f₁) y.left
⊢ (OneHom.toFun
        { toFun := fun x => { left := f₁ x.left, right := f₂ x.right },
          map_one' := (_ : { left := f₁ 1, right := f₂ 1 } = 1) }
        (x * y)).right =
    (OneHom.toFun
          { toFun := fun x => { left := f₁ x.left, right := f₂ x.right },
            map_one' := (_ : { left := f₁ 1, right := f₂ 1 } = 1) }
          x *
        OneHom.toFun
          { toFun := fun x => { left := f₁ x.left, right := f₂ x.right },
            map_one' := (_ : { left := f₁ 1, right := f₂ 1 } = 1) }
          y).right

Next tactic:
simp_all
@[simp]
theorem map_inl (n : N) : map f₁ f₂ h (inl n) = inl (f₁ n) := by 

Proof state:
N : Type u_1
G : Type u_2
H : Type u_3
inst✝⁴ : Group N
inst✝³ : Group G
inst✝² : Group H
φ : G →* MulAut N
N₁ : Type u_4
G₁ : Type u_5
inst✝¹ : Group N₁
inst✝ : Group G₁
φ₁ : G₁ →* MulAut N₁
f₁ : N →* N₁
f₂ : G →* G₁
h : ∀ (g : G), MonoidHom.comp f₁ (MulEquiv.toMonoidHom (φ g)) = MonoidHom.comp (MulEquiv.toMonoidHom (φ₁ (f₂ g))) f₁
n : N
⊢ (map f₁ f₂ h) (inl n) = inl (f₁ n)

Next tactic:
simp [map]
@[simp]
theorem map_comp_inl : (map f₁ f₂ h).comp inl = inl.comp f₁ := by 

Proof state:
N : Type u_1
G : Type u_2
H : Type u_3
inst✝⁴ : Group N
inst✝³ : Group G
inst✝² : Group H
φ : G →* MulAut N
N₁ : Type u_4
G₁ : Type u_5
inst✝¹ : Group N₁
inst✝ : Group G₁
φ₁ : G₁ →* MulAut N₁
f₁ : N →* N₁
f₂ : G →* G₁
h : ∀ (g : G), MonoidHom.comp f₁ (MulEquiv.toMonoidHom (φ g)) = MonoidHom.comp (MulEquiv.toMonoidHom (φ₁ (f₂ g))) f₁
⊢ MonoidHom.comp (map f₁ f₂ h) inl = MonoidHom.comp inl f₁

Next tactic:
ext
@[simp]
theorem map_comp_inl : (map f₁ f₂ h).comp inl = inl.comp f₁ := by ext <;> 

Proof state:
case h.left
N : Type u_1
G : Type u_2
H : Type u_3
inst✝⁴ : Group N
inst✝³ : Group G
inst✝² : Group H
φ : G →* MulAut N
N₁ : Type u_4
G₁ : Type u_5
inst✝¹ : Group N₁
inst✝ : Group G₁
φ₁ : G₁ →* MulAut N₁
f₁ : N →* N₁
f₂ : G →* G₁
h : ∀ (g : G), MonoidHom.comp f₁ (MulEquiv.toMonoidHom (φ g)) = MonoidHom.comp (MulEquiv.toMonoidHom (φ₁ (f₂ g))) f₁
x✝ : N
⊢ ((MonoidHom.comp (map f₁ f₂ h) inl) x✝).left = ((MonoidHom.comp inl f₁) x✝).left

Next tactic:
simp
@[simp]
theorem map_comp_inl : (map f₁ f₂ h).comp inl = inl.comp f₁ := by ext <;> 

Proof state:
case h.right
N : Type u_1
G : Type u_2
H : Type u_3
inst✝⁴ : Group N
inst✝³ : Group G
inst✝² : Group H
φ : G →* MulAut N
N₁ : Type u_4
G₁ : Type u_5
inst✝¹ : Group N₁
inst✝ : Group G₁
φ₁ : G₁ →* MulAut N₁
f₁ : N →* N₁
f₂ : G →* G₁
h : ∀ (g : G), MonoidHom.comp f₁ (MulEquiv.toMonoidHom (φ g)) = MonoidHom.comp (MulEquiv.toMonoidHom (φ₁ (f₂ g))) f₁
x✝ : N
⊢ ((MonoidHom.comp (map f₁ f₂ h) inl) x✝).right = ((MonoidHom.comp inl f₁) x✝).right

Next tactic:
simp
@[simp]
theorem map_inr (g : G) : map f₁ f₂ h (inr g) = inr (f₂ g) := by 

Proof state:
N : Type u_1
G : Type u_2
H : Type u_3
inst✝⁴ : Group N
inst✝³ : Group G
inst✝² : Group H
φ : G →* MulAut N
N₁ : Type u_4
G₁ : Type u_5
inst✝¹ : Group N₁
inst✝ : Group G₁
φ₁ : G₁ →* MulAut N₁
f₁ : N →* N₁
f₂ : G →* G₁
h : ∀ (g : G), MonoidHom.comp f₁ (MulEquiv.toMonoidHom (φ g)) = MonoidHom.comp (MulEquiv.toMonoidHom (φ₁ (f₂ g))) f₁
g : G
⊢ (map f₁ f₂ h) (inr g) = inr (f₂ g)

Next tactic:
simp [map]
@[simp]
theorem map_comp_inr : (map f₁ f₂ h).comp inr = inr.comp f₂ := by 

Proof state:
N : Type u_1
G : Type u_2
H : Type u_3
inst✝⁴ : Group N
inst✝³ : Group G
inst✝² : Group H
φ : G →* MulAut N
N₁ : Type u_4
G₁ : Type u_5
inst✝¹ : Group N₁
inst✝ : Group G₁
φ₁ : G₁ →* MulAut N₁
f₁ : N →* N₁
f₂ : G →* G₁
h : ∀ (g : G), MonoidHom.comp f₁ (MulEquiv.toMonoidHom (φ g)) = MonoidHom.comp (MulEquiv.toMonoidHom (φ₁ (f₂ g))) f₁
⊢ MonoidHom.comp (map f₁ f₂ h) inr = MonoidHom.comp inr f₂

Next tactic:
ext
@[simp]
theorem map_comp_inr : (map f₁ f₂ h).comp inr = inr.comp f₂ := by ext <;> 

Proof state:
case h.left
N : Type u_1
G : Type u_2
H : Type u_3
inst✝⁴ : Group N
inst✝³ : Group G
inst✝² : Group H
φ : G →* MulAut N
N₁ : Type u_4
G₁ : Type u_5
inst✝¹ : Group N₁
inst✝ : Group G₁
φ₁ : G₁ →* MulAut N₁
f₁ : N →* N₁
f₂ : G →* G₁
h : ∀ (g : G), MonoidHom.comp f₁ (MulEquiv.toMonoidHom (φ g)) = MonoidHom.comp (MulEquiv.toMonoidHom (φ₁ (f₂ g))) f₁
x✝ : G
⊢ ((MonoidHom.comp (map f₁ f₂ h) inr) x✝).left = ((MonoidHom.comp inr f₂) x✝).left

Next tactic:
simp [map]
@[simp]
theorem map_comp_inr : (map f₁ f₂ h).comp inr = inr.comp f₂ := by ext <;> 

Proof state:
case h.right
N : Type u_1
G : Type u_2
H : Type u_3
inst✝⁴ : Group N
inst✝³ : Group G
inst✝² : Group H
φ : G →* MulAut N
N₁ : Type u_4
G₁ : Type u_5
inst✝¹ : Group N₁
inst✝ : Group G₁
φ₁ : G₁ →* MulAut N₁
f₁ : N →* N₁
f₂ : G →* G₁
h : ∀ (g : G), MonoidHom.comp f₁ (MulEquiv.toMonoidHom (φ g)) = MonoidHom.comp (MulEquiv.toMonoidHom (φ₁ (f₂ g))) f₁
x✝ : G
⊢ ((MonoidHom.comp (map f₁ f₂ h) inr) x✝).right = ((MonoidHom.comp inr f₂) x✝).right

Next tactic:
simp [map]
theorem nonzero_of_invertible [MulZeroOneClass α] (a : α) [Nontrivial α] [Invertible a] : a ≠ 0 :=
  fun ha =>
  zero_ne_one <|
    calc
      0 = ⅟ a * a := by 

Proof state:
α : Type u
inst✝² : MulZeroOneClass α
a : α
inst✝¹ : Nontrivial α
inst✝ : Invertible a
ha : a = 0
⊢ 0 = ⅟a * a

Next tactic:
simp [ha]
/-- `a` is the inverse of `a⁻¹` -/
def invertibleInv {a : α} [Invertible a] : Invertible a⁻¹ :=
  ⟨a, by 

Proof state:
α : Type u
inst✝¹ : GroupWithZero α
a : α
inst✝ : Invertible a
⊢ a * a⁻¹ = 1

Next tactic:
simp
/-- `a` is the inverse of `a⁻¹` -/
def invertibleInv {a : α} [Invertible a] : Invertible a⁻¹ :=
  ⟨a, by simp, by 

Proof state:
α : Type u
inst✝¹ : GroupWithZero α
a : α
inst✝ : Invertible a
⊢ a⁻¹ * a = 1

Next tactic:
simp
instance : Inhabited CpltSepUniformSpace :=
  haveI : SeparatedSpace Empty := separated_iff_t2.mpr (by 

Proof state:
⊢ T2Space Empty

Next tactic:
infer_instance
@[simp]
theorem extension_comp_coe {X : UniformSpaceCat} {Y : CpltSepUniformSpace}
    (f : toUniformSpace (CpltSepUniformSpace.of (Completion X)) ⟶ toUniformSpace Y) :
    extensionHom (completionHom X ≫ f) = f := by
  

Proof state:
X : UniformSpaceCat
Y : CpltSepUniformSpace
f : toUniformSpace (CpltSepUniformSpace.of (Completion ↑X)) ⟶ toUniformSpace Y
⊢ extensionHom (completionHom X ≫ f) = f

Next tactic:
apply Subtype.eq
@[simp]
theorem extension_comp_coe {X : UniformSpaceCat} {Y : CpltSepUniformSpace}
    (f : toUniformSpace (CpltSepUniformSpace.of (Completion X)) ⟶ toUniformSpace Y) :
    extensionHom (completionHom X ≫ f) = f := by
  apply Subtype.eq
  

Proof state:
case a
X : UniformSpaceCat
Y : CpltSepUniformSpace
f : toUniformSpace (CpltSepUniformSpace.of (Completion ↑X)) ⟶ toUniformSpace Y
⊢ ↑(extensionHom (completionHom X ≫ f)) = ↑f

Next tactic:
funext x
@[simp]
theorem extension_comp_coe {X : UniformSpaceCat} {Y : CpltSepUniformSpace}
    (f : toUniformSpace (CpltSepUniformSpace.of (Completion X)) ⟶ toUniformSpace Y) :
    extensionHom (completionHom X ≫ f) = f := by
  apply Subtype.eq
  funext x
  

Proof state:
case a.h
X : UniformSpaceCat
Y : CpltSepUniformSpace
f : toUniformSpace (CpltSepUniformSpace.of (Completion ↑X)) ⟶ toUniformSpace Y
x : ↑(toUniformSpace (completionFunctor.obj X))
⊢ ↑(extensionHom (completionHom X ≫ f)) x = ↑f x

Next tactic:
exact congr_fun (Completion.extension_comp_coe f.property) x
/-- The completion functor is left adjoint to the forgetful functor. -/
noncomputable def adj : completionFunctor ⊣ forget₂ CpltSepUniformSpace UniformSpaceCat :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun X Y =>
        { toFun := fun f => completionHom X ≫ f
          invFun := fun f => extensionHom f
          left_inv := fun f => by 

Proof state:
X : UniformSpaceCat
Y : CpltSepUniformSpace
f : completionFunctor.obj X ⟶ Y
⊢ (fun f => extensionHom f) ((fun f => completionHom X ≫ f) f) = f

Next tactic:
dsimp
/-- The completion functor is left adjoint to the forgetful functor. -/
noncomputable def adj : completionFunctor ⊣ forget₂ CpltSepUniformSpace UniformSpaceCat :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun X Y =>
        { toFun := fun f => completionHom X ≫ f
          invFun := fun f => extensionHom f
          left_inv := fun f => by dsimp; 

Proof state:
X : UniformSpaceCat
Y : CpltSepUniformSpace
f : completionFunctor.obj X ⟶ Y
⊢ extensionHom (completionHom X ≫ f) = f

Next tactic:
erw [extension_comp_coe]
/-- The completion functor is left adjoint to the forgetful functor. -/
noncomputable def adj : completionFunctor ⊣ forget₂ CpltSepUniformSpace UniformSpaceCat :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun X Y =>
        { toFun := fun f => completionHom X ≫ f
          invFun := fun f => extensionHom f
          left_inv := fun f => by dsimp; erw [extension_comp_coe]
          right_inv := fun f => by
            

Proof state:
X : UniformSpaceCat
Y : CpltSepUniformSpace
f : X ⟶ (forget₂ CpltSepUniformSpace UniformSpaceCat).obj Y
⊢ (fun f => completionHom X ≫ f) ((fun f => extensionHom f) f) = f

Next tactic:
apply Subtype.eq
/-- The completion functor is left adjoint to the forgetful functor. -/
noncomputable def adj : completionFunctor ⊣ forget₂ CpltSepUniformSpace UniformSpaceCat :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun X Y =>
        { toFun := fun f => completionHom X ≫ f
          invFun := fun f => extensionHom f
          left_inv := fun f => by dsimp; erw [extension_comp_coe]
          right_inv := fun f => by
            apply Subtype.eq; 

Proof state:
case a
X : UniformSpaceCat
Y : CpltSepUniformSpace
f : X ⟶ (forget₂ CpltSepUniformSpace UniformSpaceCat).obj Y
⊢ ↑((fun f => completionHom X ≫ f) ((fun f => extensionHom f) f)) = ↑f

Next tactic:
funext x
/-- The completion functor is left adjoint to the forgetful functor. -/
noncomputable def adj : completionFunctor ⊣ forget₂ CpltSepUniformSpace UniformSpaceCat :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun X Y =>
        { toFun := fun f => completionHom X ≫ f
          invFun := fun f => extensionHom f
          left_inv := fun f => by dsimp; erw [extension_comp_coe]
          right_inv := fun f => by
            apply Subtype.eq; funext x; 

Proof state:
case a.h
X : UniformSpaceCat
Y : CpltSepUniformSpace
f : X ⟶ (forget₂ CpltSepUniformSpace UniformSpaceCat).obj Y
x : ↑X
⊢ ↑((fun f => completionHom X ≫ f) ((fun f => extensionHom f) f)) x = ↑f x

Next tactic:
cases f
/-- The completion functor is left adjoint to the forgetful functor. -/
noncomputable def adj : completionFunctor ⊣ forget₂ CpltSepUniformSpace UniformSpaceCat :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun X Y =>
        { toFun := fun f => completionHom X ≫ f
          invFun := fun f => extensionHom f
          left_inv := fun f => by dsimp; erw [extension_comp_coe]
          right_inv := fun f => by
            apply Subtype.eq; funext x; cases f
            

Proof state:
case a.h.mk
X : UniformSpaceCat
Y : CpltSepUniformSpace
x : ↑X
val✝ : ↑X → ↑((forget₂ CpltSepUniformSpace UniformSpaceCat).obj Y)
property✝ : UniformContinuous val✝
⊢ ↑((fun f => completionHom X ≫ f) ((fun f => extensionHom f) { val := val✝, property := property✝ })) x =
    ↑{ val := val✝, property := property✝ } x

Next tactic:
exact @Completion.extension_coe _ _ _ _ _ (CpltSepUniformSpace.separatedSpace _)
              ‹_› _
/-- The completion functor is left adjoint to the forgetful functor. -/
noncomputable def adj : completionFunctor ⊣ forget₂ CpltSepUniformSpace UniformSpaceCat :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun X Y =>
        { toFun := fun f => completionHom X ≫ f
          invFun := fun f => extensionHom f
          left_inv := fun f => by dsimp; erw [extension_comp_coe]
          right_inv := fun f => by
            apply Subtype.eq; funext x; cases f
            exact @Completion.extension_coe _ _ _ _ _ (CpltSepUniformSpace.separatedSpace _)
              ‹_› _ }
      homEquiv_naturality_left_symm := fun {X' X Y} f g => by
        

Proof state:
X' X : UniformSpaceCat
Y : CpltSepUniformSpace
f : X' ⟶ X
g : X ⟶ (forget₂ CpltSepUniformSpace UniformSpaceCat).obj Y
⊢ ((fun X Y =>
            { toFun := fun f => completionHom X ≫ f, invFun := fun f => extensionHom f,
              left_inv :=
                (_ :
                  ∀ (f : completionFunctor.obj X ⟶ Y),
                    (fun f => extensionHom f) ((fun f => completionHom X ≫ f) f) = f),
              right_inv :=
                (_ :
                  ∀ (f : X ⟶ (forget₂ CpltSepUniformSpace UniformSpaceCat).obj Y),
                    (fun f => completionHom X ≫ f) ((fun f => extensionHom f) f) = f) })
          X' Y).symm
      (f ≫ g) =
    completionFunctor.map f ≫
      ((fun X Y =>
              { toFun := fun f => completionHom X ≫ f, invFun := fun f => extensionHom f,
                left_inv :=
                  (_ :
                    ∀ (f : completionFunctor.obj X ⟶ Y),
                      (fun f => extensionHom f) ((fun f => completionHom X ≫ f) f) = f),
                right_inv :=
                  (_ :
                    ∀ (f : X ⟶ (forget₂ CpltSepUniformSpace UniformSpaceCat).obj Y),
                      (fun f => completionHom X ≫ f) ((fun f => extensionHom f) f) = f) })
            X Y).symm
        g

Next tactic:
apply hom_ext
/-- The completion functor is left adjoint to the forgetful functor. -/
noncomputable def adj : completionFunctor ⊣ forget₂ CpltSepUniformSpace UniformSpaceCat :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun X Y =>
        { toFun := fun f => completionHom X ≫ f
          invFun := fun f => extensionHom f
          left_inv := fun f => by dsimp; erw [extension_comp_coe]
          right_inv := fun f => by
            apply Subtype.eq; funext x; cases f
            exact @Completion.extension_coe _ _ _ _ _ (CpltSepUniformSpace.separatedSpace _)
              ‹_› _ }
      homEquiv_naturality_left_symm := fun {X' X Y} f g => by
        apply hom_ext; 

Proof state:
case a
X' X : UniformSpaceCat
Y : CpltSepUniformSpace
f : X' ⟶ X
g : X ⟶ (forget₂ CpltSepUniformSpace UniformSpaceCat).obj Y
⊢ (forget UniformSpaceCat).map
      (((fun X Y =>
              { toFun := fun f => completionHom X ≫ f, invFun := fun f => extensionHom f,
                left_inv :=
                  (_ :
                    ∀ (f : completionFunctor.obj X ⟶ Y),
                      (fun f => extensionHom f) ((fun f => completionHom X ≫ f) f) = f),
                right_inv :=
                  (_ :
                    ∀ (f : X ⟶ (forget₂ CpltSepUniformSpace UniformSpaceCat).obj Y),
                      (fun f => completionHom X ≫ f) ((fun f => extensionHom f) f) = f) })
            X' Y).symm
        (f ≫ g)) =
    (forget UniformSpaceCat).map
      (completionFunctor.map f ≫
        ((fun X Y =>
                { toFun := fun f => completionHom X ≫ f, invFun := fun f => extensionHom f,
                  left_inv :=
                    (_ :
                      ∀ (f : completionFunctor.obj X ⟶ Y),
                        (fun f => extensionHom f) ((fun f => completionHom X ≫ f) f) = f),
                  right_inv :=
                    (_ :
                      ∀ (f : X ⟶ (forget₂ CpltSepUniformSpace UniformSpaceCat).obj Y),
                        (fun f => completionHom X ≫ f) ((fun f => extensionHom f) f) = f) })
              X Y).symm
          g)

Next tactic:
funext x
/-- The completion functor is left adjoint to the forgetful functor. -/
noncomputable def adj : completionFunctor ⊣ forget₂ CpltSepUniformSpace UniformSpaceCat :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun X Y =>
        { toFun := fun f => completionHom X ≫ f
          invFun := fun f => extensionHom f
          left_inv := fun f => by dsimp; erw [extension_comp_coe]
          right_inv := fun f => by
            apply Subtype.eq; funext x; cases f
            exact @Completion.extension_coe _ _ _ _ _ (CpltSepUniformSpace.separatedSpace _)
              ‹_› _ }
      homEquiv_naturality_left_symm := fun {X' X Y} f g => by
        apply hom_ext; funext x; 

Proof state:
case a.h
X' X : UniformSpaceCat
Y : CpltSepUniformSpace
f : X' ⟶ X
g : X ⟶ (forget₂ CpltSepUniformSpace UniformSpaceCat).obj Y
x : (forget UniformSpaceCat).obj (toUniformSpace (completionFunctor.obj X'))
⊢ (forget UniformSpaceCat).map
      (((fun X Y =>
              { toFun := fun f => completionHom X ≫ f, invFun := fun f => extensionHom f,
                left_inv :=
                  (_ :
                    ∀ (f : completionFunctor.obj X ⟶ Y),
                      (fun f => extensionHom f) ((fun f => completionHom X ≫ f) f) = f),
                right_inv :=
                  (_ :
                    ∀ (f : X ⟶ (forget₂ CpltSepUniformSpace UniformSpaceCat).obj Y),
                      (fun f => completionHom X ≫ f) ((fun f => extensionHom f) f) = f) })
            X' Y).symm
        (f ≫ g))
      x =
    (forget UniformSpaceCat).map
      (completionFunctor.map f ≫
        ((fun X Y =>
                { toFun := fun f => completionHom X ≫ f, invFun := fun f => extensionHom f,
                  left_inv :=
                    (_ :
                      ∀ (f : completionFunctor.obj X ⟶ Y),
                        (fun f => extensionHom f) ((fun f => completionHom X ≫ f) f) = f),
                  right_inv :=
                    (_ :
                      ∀ (f : X ⟶ (forget₂ CpltSepUniformSpace UniformSpaceCat).obj Y),
                        (fun f => completionHom X ≫ f) ((fun f => extensionHom f) f) = f) })
              X Y).symm
          g)
      x

Next tactic:
dsimp