File: Mathlib/CategoryTheory/Limits/Shapes/StrictInitial.lean

full_name: CategoryTheory.Limits.HasStrictInitialObjects
code: /-- We say `C` has strict initial objects if every initial object is strict, ie given any morphism
`f : A ⟶ I` where `I` is initial, then `f` is an isomorphism.

Strictly speaking, this says that *any* initial object must be strict, rather than that strict
initial objects exist.
-/
class HasStrictInitialObjects : Prop where
  out : ∀ {I A : C} (f : A ⟶ I), IsInitial I → IsIso f
goal: Prop

full_name: CategoryTheory.Limits.HasStrictInitialObjects.out
code: /-- We say `C` has strict initial objects if every initial object is strict, ie given any morphism
`f : A ⟶ I` where `I` is initial, then `f` is an isomorphism.

Strictly speaking, this says that *any* initial object must be strict, rather than that strict
initial objects exist.
-/
class HasStrictInitialObjects : Prop where
  out : ∀ {I A : C} (f : A ⟶ I), IsInitial I → IsIso f
goal: CategoryTheory.Limits.IsInitial I → CategoryTheory.IsIso f

full_name: CategoryTheory.Limits.IsInitial.isIso_to
code: theorem IsInitial.isIso_to (hI : IsInitial I) {A : C} (f : A ⟶ I) : IsIso f 
goal: CategoryTheory.IsIso f

full_name: CategoryTheory.Limits.IsInitial.strict_hom_ext
code: theorem IsInitial.strict_hom_ext (hI : IsInitial I) {A : C} (f g : A ⟶ I) : f = g 
goal: f = g

full_name: CategoryTheory.Limits.IsInitial.subsingleton_to
code: theorem IsInitial.subsingleton_to (hI : IsInitial I) {A : C} : Subsingleton (A ⟶ I) 
goal: Subsingleton (A ⟶ I)

full_name: CategoryTheory.Limits.IsInitial.ofStrict
code: /-- If `X ⟶ Y` with `Y` being a strict initial object, then `X` is also an initial object. -/
noncomputable
def IsInitial.ofStrict {X Y : C} (f : X ⟶ Y)
    (hY : IsInitial Y) : IsInitial X 
goal: CategoryTheory.Limits.IsInitial X

full_name: CategoryTheory.Limits.initial_mono_of_strict_initial_objects
code: instance (priority := 100) initial_mono_of_strict_initial_objects : InitialMonoClass C 
goal: CategoryTheory.Limits.InitialMonoClass C

full_name: CategoryTheory.Limits.mulIsInitial
code: /-- If `I` is initial, then `X ⨯ I` is isomorphic to it. -/
@[simps! hom]
noncomputable def mulIsInitial (X : C) [HasBinaryProduct X I] (hI : IsInitial I) : X ⨯ I ≅ I 
goal: X ⨯ I ≅ I

full_name: CategoryTheory.Limits.mulIsInitial_hom
code: /-- If `I` is initial, then `X ⨯ I` is isomorphic to it. -/
@[simps! hom]
noncomputable def mulIsInitial (X : C) [HasBinaryProduct X I] (hI : IsInitial I) : X ⨯ I ≅ I 
goal: (CategoryTheory.Limits.mulIsInitial X hI).hom = CategoryTheory.Limits.prod.snd

full_name: CategoryTheory.Limits.mulIsInitial_inv
code: @[simp]
theorem mulIsInitial_inv (X : C) [HasBinaryProduct X I] (hI : IsInitial I) :
    (mulIsInitial X hI).inv = hI.to _ 
goal: (CategoryTheory.Limits.mulIsInitial X hI).inv = hI.to (X ⨯ I)

full_name: CategoryTheory.Limits.isInitialMul
code: /-- If `I` is initial, then `I ⨯ X` is isomorphic to it. -/
@[simps! hom]
noncomputable def isInitialMul (X : C) [HasBinaryProduct I X] (hI : IsInitial I) : I ⨯ X ≅ I 
goal: I ⨯ X ≅ I

full_name: CategoryTheory.Limits.isInitialMul_hom
code: /-- If `I` is initial, then `I ⨯ X` is isomorphic to it. -/
@[simps! hom]
noncomputable def isInitialMul (X : C) [HasBinaryProduct I X] (hI : IsInitial I) : I ⨯ X ≅ I 
goal: (CategoryTheory.Limits.isInitialMul X hI).hom = CategoryTheory.Limits.prod.fst

full_name: CategoryTheory.Limits.isInitialMul_inv
code: @[simp]
theorem isInitialMul_inv (X : C) [HasBinaryProduct I X] (hI : IsInitial I) :
    (isInitialMul X hI).inv = hI.to _ 
goal: (CategoryTheory.Limits.isInitialMul X hI).inv = hI.to (I ⨯ X)

full_name: CategoryTheory.Limits.initial_isIso_to
code: instance initial_isIso_to {A : C} (f : A ⟶ ⊥_ C) : IsIso f 
goal: CategoryTheory.IsIso f

full_name: CategoryTheory.Limits.initial.strict_hom_ext
code: @[ext]
theorem initial.strict_hom_ext {A : C} (f g : A ⟶ ⊥_ C) : f = g 
goal: f = g

full_name: CategoryTheory.Limits.initial.subsingleton_to
code: theorem initial.subsingleton_to {A : C} : Subsingleton (A ⟶ ⊥_ C) 
goal: Subsingleton (A ⟶ ⊥_ C)

full_name: CategoryTheory.Limits.mulInitial
code: /-- The product of `X` with an initial object in a category with strict initial objects is itself
initial.
This is the generalisation of the fact that `X × Empty ≃ Empty` for types (or `n * 0 = 0`).
-/
@[simps! hom]
noncomputable def mulInitial (X : C) [HasBinaryProduct X (⊥_ C)] : X ⨯ ⊥_ C ≅ ⊥_ C 
goal: X ⨯ ⊥_ C ≅ ⊥_ C

full_name: CategoryTheory.Limits.mulInitial_hom
code: /-- The product of `X` with an initial object in a category with strict initial objects is itself
initial.
This is the generalisation of the fact that `X × Empty ≃ Empty` for types (or `n * 0 = 0`).
-/
@[simps! hom]
noncomputable def mulInitial (X : C) [HasBinaryProduct X (⊥_ C)] : X ⨯ ⊥_ C ≅ ⊥_ C 
goal: (CategoryTheory.Limits.mulInitial X).hom = CategoryTheory.Limits.prod.snd

full_name: CategoryTheory.Limits.mulInitial_inv
code: @[simp]
theorem mulInitial_inv (X : C) [HasBinaryProduct X (⊥_ C)] : (mulInitial X).inv = initial.to _ 
goal: (CategoryTheory.Limits.mulInitial X).inv = CategoryTheory.Limits.initial.to (X ⨯ ⊥_ C)

full_name: CategoryTheory.Limits.initialMul_hom
code: /-- The product of `X` with an initial object in a category with strict initial objects is itself
initial.
This is the generalisation of the fact that `Empty × X ≃ Empty` for types (or `0 * n = 0`).
-/
@[simps! hom]
noncomputable def initialMul (X : C) [HasBinaryProduct (⊥_ C) X] : (⊥_ C) ⨯ X ≅ ⊥_ C 
goal: (CategoryTheory.Limits.initialMul X).hom = CategoryTheory.Limits.prod.fst

full_name: CategoryTheory.Limits.initialMul
code: /-- The product of `X` with an initial object in a category with strict initial objects is itself
initial.
This is the generalisation of the fact that `Empty × X ≃ Empty` for types (or `0 * n = 0`).
-/
@[simps! hom]
noncomputable def initialMul (X : C) [HasBinaryProduct (⊥_ C) X] : (⊥_ C) ⨯ X ≅ ⊥_ C 
goal: (⊥_ C) ⨯ X ≅ ⊥_ C

full_name: CategoryTheory.Limits.initialMul_inv
code: @[simp]
theorem initialMul_inv (X : C) [HasBinaryProduct (⊥_ C) X] : (initialMul X).inv = initial.to _ 
goal: (CategoryTheory.Limits.initialMul X).inv = CategoryTheory.Limits.initial.to ((⊥_ C) ⨯ X)

full_name: CategoryTheory.Limits.hasStrictInitialObjects_of_initial_is_strict
code: /-- If `C` has an initial object such that every morphism *to* it is an isomorphism, then `C`
has strict initial objects. -/
theorem hasStrictInitialObjects_of_initial_is_strict [HasInitial C]
    (h : ∀ (A) (f : A ⟶ ⊥_ C), IsIso f) : HasStrictInitialObjects C 
goal: CategoryTheory.Limits.HasStrictInitialObjects C

full_name: CategoryTheory.Limits.HasStrictTerminalObjects.out
code: /-- We say `C` has strict terminal objects if every terminal object is strict, ie given any morphism
`f : I ⟶ A` where `I` is terminal, then `f` is an isomorphism.

Strictly speaking, this says that *any* terminal object must be strict, rather than that strict
terminal objects exist.
-/
class HasStrictTerminalObjects : Prop where
  out : ∀ {I A : C} (f : I ⟶ A), IsTerminal I → IsIso f
goal: CategoryTheory.Limits.IsTerminal I → CategoryTheory.IsIso f

full_name: CategoryTheory.Limits.HasStrictTerminalObjects
code: /-- We say `C` has strict terminal objects if every terminal object is strict, ie given any morphism
`f : I ⟶ A` where `I` is terminal, then `f` is an isomorphism.

Strictly speaking, this says that *any* terminal object must be strict, rather than that strict
terminal objects exist.
-/
class HasStrictTerminalObjects : Prop where
  out : ∀ {I A : C} (f : I ⟶ A), IsTerminal I → IsIso f
goal: Prop

full_name: CategoryTheory.Limits.IsTerminal.isIso_from
code: theorem IsTerminal.isIso_from (hI : IsTerminal I) {A : C} (f : I ⟶ A) : IsIso f 
goal: CategoryTheory.IsIso f

full_name: CategoryTheory.Limits.IsTerminal.strict_hom_ext
code: theorem IsTerminal.strict_hom_ext (hI : IsTerminal I) {A : C} (f g : I ⟶ A) : f = g 
goal: f = g

full_name: CategoryTheory.Limits.IsTerminal.ofStrict
code: /-- If `X ⟶ Y` with `Y` being a strict terminal object, then `X` is also an terminal object. -/
noncomputable
def IsTerminal.ofStrict {X Y : C} (f : X ⟶ Y)
    (hY : IsTerminal X) : IsTerminal Y 
goal: CategoryTheory.Limits.IsTerminal Y

full_name: CategoryTheory.Limits.IsTerminal.subsingleton_to
code: theorem IsTerminal.subsingleton_to (hI : IsTerminal I) {A : C} : Subsingleton (I ⟶ A) 
goal: Subsingleton (I ⟶ A)

full_name: CategoryTheory.Limits.limit_π_isIso_of_is_strict_terminal
code: /-- If all but one object in a diagram is strict terminal, then the limit is isomorphic to the
said object via `limit.π`. -/
theorem limit_π_isIso_of_is_strict_terminal (F : J ⥤ C) [HasLimit F] (i : J)
    (H : ∀ (j) (_ : j ≠ i), IsTerminal (F.obj j)) [Subsingleton (i ⟶ i)] : IsIso (limit.π F i) 
goal: CategoryTheory.IsIso (CategoryTheory.Limits.limit.π F i)

full_name: CategoryTheory.Limits.terminal_isIso_from
code: instance terminal_isIso_from {A : C} (f : ⊤_ C ⟶ A) : IsIso f 
goal: CategoryTheory.IsIso f

full_name: CategoryTheory.Limits.terminal.strict_hom_ext
code: @[ext]
theorem terminal.strict_hom_ext {A : C} (f g : ⊤_ C ⟶ A) : f = g 
goal: f = g

full_name: CategoryTheory.Limits.terminal.subsingleton_to
code: theorem terminal.subsingleton_to {A : C} : Subsingleton (⊤_ C ⟶ A) 
goal: Subsingleton (⊤_ C ⟶ A)

full_name: CategoryTheory.Limits.hasStrictTerminalObjects_of_terminal_is_strict
code: /-- If `C` has an object such that every morphism *from* it is an isomorphism, then `C`
has strict terminal objects. -/
theorem hasStrictTerminalObjects_of_terminal_is_strict (I : C) (h : ∀ (A) (f : I ⟶ A), IsIso f) :
    HasStrictTerminalObjects C 
goal: CategoryTheory.Limits.HasStrictTerminalObjects C