File: Mathlib/CategoryTheory/IsConnected.lean

full_name: CategoryTheory.IsPreconnected
code: /-- A possibly empty category for which every functor to a discrete category is constant.
-/
class IsPreconnected (J : Type u₁) [Category.{v₁} J] : Prop where
  iso_constant :
    ∀ {α : Type u₁} (F : J ⥤ Discrete α) (j : J), Nonempty (F ≅ (Functor.const J).obj (F.obj j))
goal: Prop

full_name: CategoryTheory.IsPreconnected.iso_constant
code: /-- A possibly empty category for which every functor to a discrete category is constant.
-/
class IsPreconnected (J : Type u₁) [Category.{v₁} J] : Prop where
  iso_constant :
    ∀ {α : Type u₁} (F : J ⥤ Discrete α) (j : J), Nonempty (F ≅ (Functor.const J).obj (F.obj j))
goal: Nonempty (F ≅ (CategoryTheory.Functor.const J).obj (F.obj j))

full_name: CategoryTheory.IsConnected
code: /-- We define a connected category as a _nonempty_ category for which every
functor to a discrete category is constant.

NB. Some authors include the empty category as connected, we do not.
We instead are interested in categories with exactly one 'connected
component'.

This allows us to show that the functor X ⨯ - preserves connected limits.

See <https://stacks.math.columbia.edu/tag/002S>
-/
class IsConnected (J : Type u₁) [Category.{v₁} J] extends IsPreconnected J : Prop where
  [is_nonempty : Nonempty J]
goal: Prop

full_name: CategoryTheory.IsConnected.is_nonempty
code: /-- We define a connected category as a _nonempty_ category for which every
functor to a discrete category is constant.

NB. Some authors include the empty category as connected, we do not.
We instead are interested in categories with exactly one 'connected
component'.

This allows us to show that the functor X ⨯ - preserves connected limits.

See <https://stacks.math.columbia.edu/tag/002S>
-/
class IsConnected (J : Type u₁) [Category.{v₁} J] extends IsPreconnected J : Prop where
  [is_nonempty : Nonempty J]
goal: Nonempty J

full_name: _private.Mathlib.CategoryTheory.IsConnected.0.CategoryTheory.IsPreconnected.IsoConstantAux.liftToDiscrete
code: /-- Implementation detail of `isoConstant`. -/
private def liftToDiscrete {α : Type u₂} (F : J ⥤ Discrete α) : J ⥤ Discrete J 
goal: CategoryTheory.Functor J (CategoryTheory.Discrete J)

full_name: _private.Mathlib.CategoryTheory.IsConnected.0.CategoryTheory.IsPreconnected.IsoConstantAux.factorThroughDiscrete
code: /-- Implementation detail of `isoConstant`. -/
private def factorThroughDiscrete {α : Type u₂} (F : J ⥤ Discrete α) :
    liftToDiscrete F ⋙ Discrete.functor F.obj ≅ F 
goal: (CategoryTheory.IsPreconnected.IsoConstantAux.liftToDiscrete F).comp (CategoryTheory.Discrete.functor F.obj) ≅ F

full_name: CategoryTheory.isoConstant
code: /-- If `J` is connected, any functor `F : J ⥤ Discrete α` is isomorphic to
the constant functor with value `F.obj j` (for any choice of `j`).
-/
def isoConstant [IsPreconnected J] {α : Type u₂} (F : J ⥤ Discrete α) (j : J) :
    F ≅ (Functor.const J).obj (F.obj j) 
goal: F ≅ (CategoryTheory.Functor.const J).obj (F.obj j)

full_name: CategoryTheory.any_functor_const_on_obj
code: /-- If `J` is connected, any functor to a discrete category is constant on objects.
The converse is given in `IsConnected.of_any_functor_const_on_obj`.
-/
theorem any_functor_const_on_obj [IsPreconnected J] {α : Type u₂} (F : J ⥤ Discrete α) (j j' : J) :
    F.obj j = F.obj j' 
goal: F.obj j = F.obj j'

full_name: CategoryTheory.IsPreconnected.of_any_functor_const_on_obj
code: /-- If any functor to a discrete category is constant on objects, J is connected.
The converse of `any_functor_const_on_obj`.
-/
theorem IsPreconnected.of_any_functor_const_on_obj
    (h : ∀ {α : Type u₁} (F : J ⥤ Discrete α), ∀ j j' : J, F.obj j = F.obj j') :
    IsPreconnected J 
goal: CategoryTheory.IsPreconnected J

full_name: CategoryTheory.IsConnected.of_any_functor_const_on_obj
code: /-- If any functor to a discrete category is constant on objects, J is connected.
The converse of `any_functor_const_on_obj`.
-/
theorem IsConnected.of_any_functor_const_on_obj [Nonempty J]
    (h : ∀ {α : Type u₁} (F : J ⥤ Discrete α), ∀ j j' : J, F.obj j = F.obj j') : IsConnected J 
goal: CategoryTheory.IsConnected J

full_name: CategoryTheory.constant_of_preserves_morphisms
code: /-- If `J` is connected, then given any function `F` such that the presence of a
morphism `j₁ ⟶ j₂` implies `F j₁ = F j₂`, we have that `F` is constant.
This can be thought of as a local-to-global property.

The converse is shown in `IsConnected.of_constant_of_preserves_morphisms`
-/
theorem constant_of_preserves_morphisms [IsPreconnected J] {α : Type u₂} (F : J → α)
    (h : ∀ (j₁ j₂ : J) (_ : j₁ ⟶ j₂), F j₁ = F j₂) (j j' : J) : F j = F j' 
goal: F j = F j'

full_name: CategoryTheory.IsPreconnected.of_constant_of_preserves_morphisms
code: /-- `J` is connected if: given any function `F : J → α` which is constant for any
`j₁, j₂` for which there is a morphism `j₁ ⟶ j₂`, then `F` is constant.
This can be thought of as a local-to-global property.

The converse of `constant_of_preserves_morphisms`.
-/
theorem IsPreconnected.of_constant_of_preserves_morphisms
    (h : ∀ {α : Type u₁} (F : J → α),
      (∀ {j₁ j₂ : J} (_ : j₁ ⟶ j₂), F j₁ = F j₂) → ∀ j j' : J, F j = F j') :
    IsPreconnected J 
goal: CategoryTheory.IsPreconnected J

full_name: CategoryTheory.IsConnected.of_constant_of_preserves_morphisms
code: /-- `J` is connected if: given any function `F : J → α` which is constant for any
`j₁, j₂` for which there is a morphism `j₁ ⟶ j₂`, then `F` is constant.
This can be thought of as a local-to-global property.

The converse of `constant_of_preserves_morphisms`.
-/
theorem IsConnected.of_constant_of_preserves_morphisms [Nonempty J]
    (h : ∀ {α : Type u₁} (F : J → α),
      (∀ {j₁ j₂ : J} (_ : j₁ ⟶ j₂), F j₁ = F j₂) → ∀ j j' : J, F j = F j') :
    IsConnected J 
goal: CategoryTheory.IsConnected J

full_name: CategoryTheory.induct_on_objects
code: /-- An inductive-like property for the objects of a connected category.
If the set `p` is nonempty, and `p` is closed under morphisms of `J`,
then `p` contains all of `J`.

The converse is given in `IsConnected.of_induct`.
-/
theorem induct_on_objects [IsPreconnected J] (p : Set J) {j₀ : J} (h0 : j₀ ∈ p)
    (h1 : ∀ {j₁ j₂ : J} (_ : j₁ ⟶ j₂), j₁ ∈ p ↔ j₂ ∈ p) (j : J) : j ∈ p 
goal: j ∈ p

full_name: CategoryTheory.IsConnected.of_induct
code: /--
If any maximal connected component containing some element j₀ of J is all of J, then J is connected.

The converse of `induct_on_objects`.
-/
theorem IsConnected.of_induct {j₀ : J}
    (h : ∀ p : Set J, j₀ ∈ p → (∀ {j₁ j₂ : J} (_ : j₁ ⟶ j₂), j₁ ∈ p ↔ j₂ ∈ p) → ∀ j : J, j ∈ p) :
    IsConnected J 
goal: CategoryTheory.IsConnected J

full_name: CategoryTheory.instIsConnectedULiftHomULift
code: /-- Lifting the universe level of morphisms and objects preserves connectedness. -/
instance [hc : IsConnected J] : IsConnected (ULiftHom.{v₂} (ULift.{u₂} J)) 
goal: CategoryTheory.IsConnected (CategoryTheory.ULiftHom (ULift.{u₂, u₁} J))

full_name: CategoryTheory.isPreconnected_induction
code: /-- Another induction principle for `IsPreconnected J`:
given a type family `Z : J → Sort*` and
a rule for transporting in *both* directions along a morphism in `J`,
we can transport an `x : Z j₀` to a point in `Z j` for any `j`.
-/
theorem isPreconnected_induction [IsPreconnected J] (Z : J → Sort*)
    (h₁ : ∀ {j₁ j₂ : J} (_ : j₁ ⟶ j₂), Z j₁ → Z j₂) (h₂ : ∀ {j₁ j₂ : J} (_ : j₁ ⟶ j₂), Z j₂ → Z j₁)
    {j₀ : J} (x : Z j₀) (j : J) : Nonempty (Z j) 
goal: Nonempty (Z j)

full_name: CategoryTheory.isPreconnected_of_equivalent
code: /-- If `J` and `K` are equivalent, then if `J` is preconnected then `K` is as well. -/
theorem isPreconnected_of_equivalent {K : Type u₂} [Category.{v₂} K] [IsPreconnected J]
    (e : J ≌ K) : IsPreconnected K 
goal: CategoryTheory.IsPreconnected K

full_name: CategoryTheory.isPreconnected_iff_of_equivalence
code: lemma isPreconnected_iff_of_equivalence {K : Type u₂} [Category.{v₂} K] (e : J ≌ K) :
    IsPreconnected J ↔ IsPreconnected K 
goal: CategoryTheory.IsPreconnected J ↔ CategoryTheory.IsPreconnected K

full_name: CategoryTheory.isConnected_of_equivalent
code: /-- If `J` and `K` are equivalent, then if `J` is connected then `K` is as well. -/
theorem isConnected_of_equivalent {K : Type u₂} [Category.{v₂} K] (e : J ≌ K) [IsConnected J] :
    IsConnected K 
goal: CategoryTheory.IsConnected K

full_name: CategoryTheory.isConnected_iff_of_equivalence
code: lemma isConnected_iff_of_equivalence {K : Type u₂} [Category.{v₂} K] (e : J ≌ K) :
    IsConnected J ↔ IsConnected K 
goal: CategoryTheory.IsConnected J ↔ CategoryTheory.IsConnected K

full_name: CategoryTheory.isPreconnected_op
code: /-- If `J` is preconnected, then `Jᵒᵖ` is preconnected as well. -/
instance isPreconnected_op [IsPreconnected J] : IsPreconnected Jᵒᵖ 
goal: CategoryTheory.IsPreconnected Jᵒᵖ

full_name: CategoryTheory.isConnected_op
code: /-- If `J` is connected, then `Jᵒᵖ` is connected as well. -/
instance isConnected_op [IsConnected J] : IsConnected Jᵒᵖ 
goal: CategoryTheory.IsConnected Jᵒᵖ

full_name: CategoryTheory.isPreconnected_of_isPreconnected_op
code: theorem isPreconnected_of_isPreconnected_op [IsPreconnected Jᵒᵖ] : IsPreconnected J 
goal: CategoryTheory.IsPreconnected J

full_name: CategoryTheory.isConnected_of_isConnected_op
code: theorem isConnected_of_isConnected_op [IsConnected Jᵒᵖ] : IsConnected J 
goal: CategoryTheory.IsConnected J

full_name: CategoryTheory.Zag
code: /-- j₁ and j₂ are related by `Zag` if there is a morphism between them. -/
def Zag (j₁ j₂ : J) : Prop 
goal: Prop

full_name: CategoryTheory.Zag.refl
code: theorem Zag.refl (X : J) : Zag X X 
goal: CategoryTheory.Zag X X

full_name: CategoryTheory.zag_symmetric
code: theorem zag_symmetric : Symmetric (@Zag J _) 
goal: Symmetric CategoryTheory.Zag

full_name: CategoryTheory.Zag.symm
code: theorem Zag.symm {j₁ j₂ : J} (h : Zag j₁ j₂) : Zag j₂ j₁ 
goal: CategoryTheory.Zag j₂ j₁

full_name: CategoryTheory.Zag.of_hom
code: theorem Zag.of_hom {j₁ j₂ : J} (f : j₁ ⟶ j₂) : Zag j₁ j₂ 
goal: CategoryTheory.Zag j₁ j₂

full_name: CategoryTheory.Zag.of_inv
code: theorem Zag.of_inv {j₁ j₂ : J} (f : j₂ ⟶ j₁) : Zag j₁ j₂ 
goal: CategoryTheory.Zag j₁ j₂

full_name: CategoryTheory.Zigzag
code: /-- `j₁` and `j₂` are related by `Zigzag` if there is a chain of
morphisms from `j₁` to `j₂`, with backward morphisms allowed.
-/
def Zigzag : J → J → Prop 
goal: J → J → Prop

full_name: CategoryTheory.zigzag_symmetric
code: theorem zigzag_symmetric : Symmetric (@Zigzag J _) 
goal: Symmetric CategoryTheory.Zigzag

full_name: CategoryTheory.zigzag_equivalence
code: theorem zigzag_equivalence : _root_.Equivalence (@Zigzag J _) 
goal: Equivalence CategoryTheory.Zigzag

full_name: CategoryTheory.Zigzag.refl
code: theorem Zigzag.refl (X : J) : Zigzag X X 
goal: CategoryTheory.Zigzag X X

full_name: CategoryTheory.Zigzag.symm
code: theorem Zigzag.symm {j₁ j₂ : J} (h : Zigzag j₁ j₂) : Zigzag j₂ j₁ 
goal: CategoryTheory.Zigzag j₂ j₁

full_name: CategoryTheory.Zigzag.trans
code: theorem Zigzag.trans {j₁ j₂ j₃ : J} (h₁ : Zigzag j₁ j₂) (h₂ : Zigzag j₂ j₃) : Zigzag j₁ j₃ 
goal: CategoryTheory.Zigzag j₁ j₃

full_name: CategoryTheory.Zigzag.of_zag
code: theorem Zigzag.of_zag {j₁ j₂ : J} (h : Zag j₁ j₂) : Zigzag j₁ j₂ 
goal: CategoryTheory.Zigzag j₁ j₂

full_name: CategoryTheory.Zigzag.of_hom
code: theorem Zigzag.of_hom {j₁ j₂ : J} (f : j₁ ⟶ j₂) : Zigzag j₁ j₂ 
goal: CategoryTheory.Zigzag j₁ j₂

full_name: CategoryTheory.Zigzag.of_inv
code: theorem Zigzag.of_inv {j₁ j₂ : J} (f : j₂ ⟶ j₁) : Zigzag j₁ j₂ 
goal: CategoryTheory.Zigzag j₁ j₂

full_name: CategoryTheory.Zigzag.of_zag_trans
code: theorem Zigzag.of_zag_trans {j₁ j₂ j₃ : J} (h₁ : Zag j₁ j₂) (h₂ : Zag j₂ j₃) : Zigzag j₁ j₃ 
goal: CategoryTheory.Zigzag j₁ j₃

full_name: CategoryTheory.Zigzag.of_hom_hom
code: theorem Zigzag.of_hom_hom {j₁ j₂ j₃ : J} (f₁₂ : j₁ ⟶ j₂) (f₂₃ : j₂ ⟶ j₃) : Zigzag j₁ j₃ 
goal: CategoryTheory.Zigzag j₁ j₃

full_name: CategoryTheory.Zigzag.of_hom_inv
code: theorem Zigzag.of_hom_inv {j₁ j₂ j₃ : J} (f₁₂ : j₁ ⟶ j₂) (f₃₂ : j₃ ⟶ j₂) : Zigzag j₁ j₃ 
goal: CategoryTheory.Zigzag j₁ j₃

full_name: CategoryTheory.Zigzag.of_inv_hom
code: theorem Zigzag.of_inv_hom {j₁ j₂ j₃ : J} (f₂₁ : j₂ ⟶ j₁) (f₂₃ : j₂ ⟶ j₃) : Zigzag j₁ j₃ 
goal: CategoryTheory.Zigzag j₁ j₃

full_name: CategoryTheory.Zigzag.of_inv_inv
code: theorem Zigzag.of_inv_inv {j₁ j₂ j₃ : J} (f₂₁ : j₂ ⟶ j₁) (f₃₂ : j₃ ⟶ j₂) : Zigzag j₁ j₃ 
goal: CategoryTheory.Zigzag j₁ j₃

full_name: CategoryTheory.Zigzag.setoid
code: /-- The setoid given by the equivalence relation `Zigzag`. A quotient for this
setoid is a connected component of the category.
-/
def Zigzag.setoid (J : Type u₂) [Category.{v₁} J] : Setoid J 
goal: Setoid J

full_name: CategoryTheory.zigzag_obj_of_zigzag
code: /-- If there is a zigzag from `j₁` to `j₂`, then there is a zigzag from `F j₁` to
`F j₂` as long as `F` is a functor.
-/
theorem zigzag_obj_of_zigzag (F : J ⥤ K) {j₁ j₂ : J} (h : Zigzag j₁ j₂) :
    Zigzag (F.obj j₁) (F.obj j₂) 
goal: CategoryTheory.Zigzag (F.obj j₁) (F.obj j₂)

full_name: CategoryTheory.zag_of_zag_obj
code: theorem zag_of_zag_obj (F : J ⥤ K) [F.Full] {j₁ j₂ : J} (h : Zag (F.obj j₁) (F.obj j₂)) :
    Zag j₁ j₂ 
goal: CategoryTheory.Zag j₁ j₂

full_name: CategoryTheory.equiv_relation
code: /-- Any equivalence relation containing (⟶) holds for all pairs of a connected category. -/
theorem equiv_relation [IsPreconnected J] (r : J → J → Prop) (hr : _root_.Equivalence r)
    (h : ∀ {j₁ j₂ : J} (_ : j₁ ⟶ j₂), r j₁ j₂) : ∀ j₁ j₂ : J, r j₁ j₂ 
goal: r j₁ j₂

full_name: CategoryTheory.isPreconnected_zigzag
code: /-- In a connected category, any two objects are related by `Zigzag`. -/
theorem isPreconnected_zigzag [IsPreconnected J] (j₁ j₂ : J) : Zigzag j₁ j₂ 
goal: CategoryTheory.Zigzag j₁ j₂

full_name: CategoryTheory.zigzag_isPreconnected
code: theorem zigzag_isPreconnected (h : ∀ j₁ j₂ : J, Zigzag j₁ j₂) : IsPreconnected J 
goal: CategoryTheory.IsPreconnected J

full_name: CategoryTheory.zigzag_isConnected
code: /-- If any two objects in a nonempty category are related by `Zigzag`, the category is connected.
-/
theorem zigzag_isConnected [Nonempty J] (h : ∀ j₁ j₂ : J, Zigzag j₁ j₂) : IsConnected J 
goal: CategoryTheory.IsConnected J

full_name: CategoryTheory.exists_zigzag'
code: theorem exists_zigzag' [IsConnected J] (j₁ j₂ : J) :
    ∃ l, List.Chain Zag j₁ l ∧ List.getLast (j₁ :: l) (List.cons_ne_nil _ _) = j₂ 
goal: ∃ l, List.Chain CategoryTheory.Zag j₁ l ∧ (j₁ :: l).getLast ⋯ = j₂

full_name: CategoryTheory.isPreconnected_of_zigzag
code: /-- If any two objects in a nonempty category are linked by a sequence of (potentially reversed)
morphisms, then J is connected.

The converse of `exists_zigzag'`.
-/
theorem isPreconnected_of_zigzag (h : ∀ j₁ j₂ : J, ∃ l,
    List.Chain Zag j₁ l ∧ List.getLast (j₁ :: l) (List.cons_ne_nil _ _) = j₂) :
    IsPreconnected J 
goal: CategoryTheory.IsPreconnected J

full_name: CategoryTheory.isConnected_of_zigzag
code: /-- If any two objects in a nonempty category are linked by a sequence of (potentially reversed)
morphisms, then J is connected.

The converse of `exists_zigzag'`.
-/
theorem isConnected_of_zigzag [Nonempty J] (h : ∀ j₁ j₂ : J, ∃ l,
    List.Chain Zag j₁ l ∧ List.getLast (j₁ :: l) (List.cons_ne_nil _ _) = j₂) :
    IsConnected J 
goal: CategoryTheory.IsConnected J

full_name: CategoryTheory.discreteIsConnectedEquivPUnit
code: /-- If `Discrete α` is connected, then `α` is (type-)equivalent to `PUnit`. -/
def discreteIsConnectedEquivPUnit {α : Type u₁} [IsConnected (Discrete α)] : α ≃ PUnit 
goal: α ≃ PUnit.{u₁ + 1}

full_name: CategoryTheory.nat_trans_from_is_connected
code: /-- For objects `X Y : C`, any natural transformation `α : const X ⟶ const Y` from a connected
category must be constant.
This is the key property of connected categories which we use to establish properties about limits.
-/
theorem nat_trans_from_is_connected [IsPreconnected J] {X Y : C}
    (α : (Functor.const J).obj X ⟶ (Functor.const J).obj Y) :
    ∀ j j' : J, α.app j = (α.app j' : X ⟶ Y) 
goal: α.app j = α.app j'

full_name: CategoryTheory.instFullFunctorConstOfIsConnected
code: instance [IsConnected J] : (Functor.const J : C ⥤ J ⥤ C).Full 
goal: (CategoryTheory.Functor.const J).Full

full_name: CategoryTheory.nonempty_hom_of_preconnected_groupoid
code: theorem nonempty_hom_of_preconnected_groupoid {G} [Groupoid G] [IsPreconnected G] :
    ∀ x y : G, Nonempty (x ⟶ y) 
goal: Nonempty (x ⟶ y)