Theorem: LightProfinite.mono_iff_injective
File: Mathlib/Topology/Category/LightProfinite/Basic.lean

tactic: constructor
state_before: X✝ Y✝ : LightProfinite
f✝ : X✝ ⟶ Y✝
X Y : LightProfinite
f : X ⟶ Y
⊢ Mono f ↔ Function.Injective ⇑f
state_after: case mp
X✝ Y✝ : LightProfinite
f✝ : X✝ ⟶ Y✝
X Y : LightProfinite
f : X ⟶ Y
⊢ Mono f → Function.Injective ⇑f

case mpr
X✝ Y✝ : LightProfinite
f✝ : X✝ ⟶ Y✝
X Y : LightProfinite
f : X ⟶ Y
⊢ Function.Injective ⇑f → Mono f

tactic: intro hf x₁ x₂ h
state_before: case mp
X✝ Y✝ : LightProfinite
f✝ : X✝ ⟶ Y✝
X Y : LightProfinite
f : X ⟶ Y
⊢ Mono f → Function.Injective ⇑f
state_after: case mp
X✝ Y✝ : LightProfinite
f✝ : X✝ ⟶ Y✝
X Y : LightProfinite
f : X ⟶ Y
hf : Mono f
x₁ x₂ : (forget LightProfinite).obj X
h : f x₁ = f x₂
⊢ x₁ = x₂

tactic: let g₁ : of PUnit.{u+1} ⟶ X := ⟨fun _ => x₁, continuous_const⟩
state_before: case mp
X✝ Y✝ : LightProfinite
f✝ : X✝ ⟶ Y✝
X Y : LightProfinite
f : X ⟶ Y
hf : Mono f
x₁ x₂ : (forget LightProfinite).obj X
h : f x₁ = f x₂
⊢ x₁ = x₂
state_after: case mp
X✝ Y✝ : LightProfinite
f✝ : X✝ ⟶ Y✝
X Y : LightProfinite
f : X ⟶ Y
hf : Mono f
x₁ x₂ : (forget LightProfinite).obj X
h : f x₁ = f x₂
g₁ : of PUnit.{u + 1} ⟶ X := { toFun := fun x => x₁, continuous_toFun := ⋯ }
⊢ x₁ = x₂

tactic: let g₂ : of PUnit.{u+1} ⟶ X := ⟨fun _ => x₂, continuous_const⟩
state_before: case mp
X✝ Y✝ : LightProfinite
f✝ : X✝ ⟶ Y✝
X Y : LightProfinite
f : X ⟶ Y
hf : Mono f
x₁ x₂ : (forget LightProfinite).obj X
h : f x₁ = f x₂
g₁ : of PUnit.{u + 1} ⟶ X := { toFun := fun x => x₁, continuous_toFun := ⋯ }
⊢ x₁ = x₂
state_after: case mp
X✝ Y✝ : LightProfinite
f✝ : X✝ ⟶ Y✝
X Y : LightProfinite
f : X ⟶ Y
hf : Mono f
x₁ x₂ : (forget LightProfinite).obj X
h : f x₁ = f x₂
g₁ : of PUnit.{u + 1} ⟶ X := { toFun := fun x => x₁, continuous_toFun := ⋯ }
g₂ : of PUnit.{u + 1} ⟶ X := { toFun := fun x => x₂, continuous_toFun := ⋯ }
⊢ x₁ = x₂

tactic: have : g₁ ≫ f = g₂ ≫ f := by
  ext
  exact h
state_before: case mp
X✝ Y✝ : LightProfinite
f✝ : X✝ ⟶ Y✝
X Y : LightProfinite
f : X ⟶ Y
hf : Mono f
x₁ x₂ : (forget LightProfinite).obj X
h : f x₁ = f x₂
g₁ : of PUnit.{u + 1} ⟶ X := { toFun := fun x => x₁, continuous_toFun := ⋯ }
g₂ : of PUnit.{u + 1} ⟶ X := { toFun := fun x => x₂, continuous_toFun := ⋯ }
⊢ x₁ = x₂
state_after: case mp
X✝ Y✝ : LightProfinite
f✝ : X✝ ⟶ Y✝
X Y : LightProfinite
f : X ⟶ Y
hf : Mono f
x₁ x₂ : (forget LightProfinite).obj X
h : f x₁ = f x₂
g₁ : of PUnit.{u + 1} ⟶ X := { toFun := fun x => x₁, continuous_toFun := ⋯ }
g₂ : of PUnit.{u + 1} ⟶ X := { toFun := fun x => x₂, continuous_toFun := ⋯ }
this : g₁ ≫ f = g₂ ≫ f
⊢ x₁ = x₂

tactic: rw [cancel_mono] at this
state_before: case mp
X✝ Y✝ : LightProfinite
f✝ : X✝ ⟶ Y✝
X Y : LightProfinite
f : X ⟶ Y
hf : Mono f
x₁ x₂ : (forget LightProfinite).obj X
h : f x₁ = f x₂
g₁ : of PUnit.{u + 1} ⟶ X := { toFun := fun x => x₁, continuous_toFun := ⋯ }
g₂ : of PUnit.{u + 1} ⟶ X := { toFun := fun x => x₂, continuous_toFun := ⋯ }
this : g₁ ≫ f = g₂ ≫ f
⊢ x₁ = x₂
state_after: case mp
X✝ Y✝ : LightProfinite
f✝ : X✝ ⟶ Y✝
X Y : LightProfinite
f : X ⟶ Y
hf : Mono f
x₁ x₂ : (forget LightProfinite).obj X
h : f x₁ = f x₂
g₁ : of PUnit.{u + 1} ⟶ X := { toFun := fun x => x₁, continuous_toFun := ⋯ }
g₂ : of PUnit.{u + 1} ⟶ X := { toFun := fun x => x₂, continuous_toFun := ⋯ }
this : g₁ = g₂
⊢ x₁ = x₂

tactic: apply_fun fun e => e PUnit.unit at this
state_before: case mp
X✝ Y✝ : LightProfinite
f✝ : X✝ ⟶ Y✝
X Y : LightProfinite
f : X ⟶ Y
hf : Mono f
x₁ x₂ : (forget LightProfinite).obj X
h : f x₁ = f x₂
g₁ : of PUnit.{u + 1} ⟶ X := { toFun := fun x => x₁, continuous_toFun := ⋯ }
g₂ : of PUnit.{u + 1} ⟶ X := { toFun := fun x => x₂, continuous_toFun := ⋯ }
this : g₁ = g₂
⊢ x₁ = x₂
state_after: case mp
X✝ Y✝ : LightProfinite
f✝ : X✝ ⟶ Y✝
X Y : LightProfinite
f : X ⟶ Y
hf : Mono f
x₁ x₂ : (forget LightProfinite).obj X
h : f x₁ = f x₂
g₁ : of PUnit.{u + 1} ⟶ X := { toFun := fun x => x₁, continuous_toFun := ⋯ }
g₂ : of PUnit.{u + 1} ⟶ X := { toFun := fun x => x₂, continuous_toFun := ⋯ }
this : g₁ PUnit.unit = g₂ PUnit.unit
⊢ x₁ = x₂

tactic: exact this
state_before: case mp
X✝ Y✝ : LightProfinite
f✝ : X✝ ⟶ Y✝
X Y : LightProfinite
f : X ⟶ Y
hf : Mono f
x₁ x₂ : (forget LightProfinite).obj X
h : f x₁ = f x₂
g₁ : of PUnit.{u + 1} ⟶ X := { toFun := fun x => x₁, continuous_toFun := ⋯ }
g₂ : of PUnit.{u + 1} ⟶ X := { toFun := fun x => x₂, continuous_toFun := ⋯ }
this : g₁ PUnit.unit = g₂ PUnit.unit
⊢ x₁ = x₂
state_after: no goals

tactic: ext
state_before: X✝ Y✝ : LightProfinite
f✝ : X✝ ⟶ Y✝
X Y : LightProfinite
f : X ⟶ Y
hf : Mono f
x₁ x₂ : (forget LightProfinite).obj X
h : f x₁ = f x₂
g₁ : of PUnit.{u + 1} ⟶ X := { toFun := fun x => x₁, continuous_toFun := ⋯ }
g₂ : of PUnit.{u + 1} ⟶ X := { toFun := fun x => x₂, continuous_toFun := ⋯ }
⊢ g₁ ≫ f = g₂ ≫ f
state_after: case w
X✝ Y✝ : LightProfinite
f✝ : X✝ ⟶ Y✝
X Y : LightProfinite
f : X ⟶ Y
hf : Mono f
x₁ x₂ : (forget LightProfinite).obj X
h : f x₁ = f x₂
g₁ : of PUnit.{u + 1} ⟶ X := { toFun := fun x => x₁, continuous_toFun := ⋯ }
g₂ : of PUnit.{u + 1} ⟶ X := { toFun := fun x => x₂, continuous_toFun := ⋯ }
x✝ : (forget LightProfinite).obj (of PUnit.{u + 1})
⊢ (g₁ ≫ f) x✝ = (g₂ ≫ f) x✝

tactic: exact h
state_before: case w
X✝ Y✝ : LightProfinite
f✝ : X✝ ⟶ Y✝
X Y : LightProfinite
f : X ⟶ Y
hf : Mono f
x₁ x₂ : (forget LightProfinite).obj X
h : f x₁ = f x₂
g₁ : of PUnit.{u + 1} ⟶ X := { toFun := fun x => x₁, continuous_toFun := ⋯ }
g₂ : of PUnit.{u + 1} ⟶ X := { toFun := fun x => x₂, continuous_toFun := ⋯ }
x✝ : (forget LightProfinite).obj (of PUnit.{u + 1})
⊢ (g₁ ≫ f) x✝ = (g₂ ≫ f) x✝
state_after: no goals

tactic: rw [← CategoryTheory.mono_iff_injective]
state_before: case mpr
X✝ Y✝ : LightProfinite
f✝ : X✝ ⟶ Y✝
X Y : LightProfinite
f : X ⟶ Y
⊢ Function.Injective ⇑f → Mono f
state_after: case mpr
X✝ Y✝ : LightProfinite
f✝ : X✝ ⟶ Y✝
X Y : LightProfinite
f : X ⟶ Y
⊢ Mono ⇑f → Mono f

tactic: apply (forget LightProfinite).mono_of_mono_map
state_before: case mpr
X✝ Y✝ : LightProfinite
f✝ : X✝ ⟶ Y✝
X Y : LightProfinite
f : X ⟶ Y
⊢ Mono ⇑f → Mono f
state_after: no goals