File: Mathlib/Topology/Homotopy/HomotopyGroup.lean

full_name: Topology.«_aux_Mathlib_Topology_Homotopy_HomotopyGroup___macroRules_Topology_termI^__1»
code: scoped[Topology] notation "I^" N => N → I
goal: Lean.Macro

full_name: Cube.boundary
code: /-- The points in a cube with at least one projection equal to 0 or 1. -/
def boundary (N : Type*) : Set (I^N) 
goal: Set (N → ↑I)

full_name: Cube.splitAt
code: /-- The forward direction of the homeomorphism
  between the cube $I^N$ and $I × I^{N\setminus\{j\}}$. -/
abbrev splitAt (i : N) : (I^N) ≃ₜ I × I^{ j // j ≠ i } 
goal: (N → ↑I) ≃ₜ ↑I × ({ j // j ≠ i } → ↑I)

full_name: Cube.insertAt
code: /-- The backward direction of the homeomorphism
  between the cube $I^N$ and $I × I^{N\setminus\{j\}}$. -/
abbrev insertAt (i : N) : (I × I^{ j // j ≠ i }) ≃ₜ I^N 
goal: ↑I × ({ j // j ≠ i } → ↑I) ≃ₜ (N → ↑I)

full_name: Cube.insertAt_boundary
code: theorem insertAt_boundary (i : N) {t₀ : I} {t}
    (H : (t₀ = 0 ∨ t₀ = 1) ∨ t ∈ boundary { j // j ≠ i }) : insertAt i ⟨t₀, t⟩ ∈ boundary N 
goal: (Cube.insertAt i) (t₀, t) ∈ Cube.boundary N

full_name: LoopSpace
code: /-- The space of paths with both endpoints equal to a specified point `x : X`. -/
abbrev LoopSpace 
goal: Type u_2

full_name: Topology.Homotopy._aux_Mathlib_Topology_Homotopy_HomotopyGroup___unexpand_LoopSpace_1
code: scoped[Topology.Homotopy] notation "Ω" => LoopSpace
goal: Lean.PrettyPrinter.Unexpander

full_name: Topology.Homotopy._aux_Mathlib_Topology_Homotopy_HomotopyGroup___macroRules_Topology_Homotopy_termΩ_1
code: scoped[Topology.Homotopy] notation "Ω" => LoopSpace
goal: Lean.Macro

full_name: LoopSpace.inhabited
code: instance LoopSpace.inhabited : Inhabited (Path x x) 
goal: Inhabited (Path x x)

full_name: GenLoop
code: /-- The `n`-dimensional generalized loops based at `x` in a space `X` are
  continuous functions `I^n → X` that sends the boundary to `x`.
  We allow an arbitrary indexing type `N` in place of `Fin n` here. -/
def GenLoop : Set C(I^N, X) 
goal: Set C(N → ↑I, X)

full_name: Topology.Homotopy.«_aux_Mathlib_Topology_Homotopy_HomotopyGroup___macroRules_Topology_Homotopy_termΩ^_1»
code: @[inherit_doc] scoped[Topology.Homotopy] notation "Ω^" => GenLoop
goal: Lean.Macro

full_name: Topology.Homotopy._aux_Mathlib_Topology_Homotopy_HomotopyGroup___unexpand_GenLoop_1
code: @[inherit_doc] scoped[Topology.Homotopy] notation "Ω^" => GenLoop
goal: Lean.PrettyPrinter.Unexpander

full_name: GenLoop.instFunLike
code: instance instFunLike : FunLike (Ω^ N X x) (I^N) X 
goal: FunLike (↑(Ω^ N X x)) (N → ↑I) X

full_name: GenLoop.ext
code: @[ext]
theorem ext (f g : Ω^ N X x) (H : ∀ y, f y = g y) : f = g 
goal: f = g

full_name: GenLoop.mk_apply
code: @[simp]
theorem mk_apply (f : C(I^N, X)) (H y) : (⟨f, H⟩ : Ω^ N X x) y = f y 
goal: ⟨f, H⟩ y = f y

full_name: GenLoop.copy
code: /-- Copy of a `GenLoop` with a new map from the unit cube equal to the old one.
  Useful to fix definitional equalities. -/
def copy (f : Ω^ N X x) (g : (I^N) → X) (h : g = f) : Ω^ N X x 
goal: ↑(Ω^ N X x)

full_name: GenLoop.coe_copy
code: theorem coe_copy (f : Ω^ N X x) {g : (I^N) → X} (h : g = f) : ⇑(copy f g h) = g 
goal: ⇑(GenLoop.copy f g h) = g

full_name: GenLoop.copy_eq
code: theorem copy_eq (f : Ω^ N X x) {g : (I^N) → X} (h : g = f) : copy f g h = f 
goal: GenLoop.copy f g h = f

full_name: GenLoop.boundary
code: theorem boundary (f : Ω^ N X x) : ∀ y ∈ Cube.boundary N, f y = x 
goal: y ∈ Cube.boundary N → f y = x

full_name: GenLoop.const
code: /-- The constant `GenLoop` at `x`. -/
def const : Ω^ N X x 
goal: ↑(Ω^ N X x)

full_name: GenLoop.const_apply
code: @[simp]
theorem const_apply {t} : (@const N X _ x) t = x 
goal: GenLoop.const t = x

full_name: GenLoop.inhabited
code: instance inhabited : Inhabited (Ω^ N X x) 
goal: Inhabited ↑(Ω^ N X x)

full_name: GenLoop.Homotopic
code: /-- The "homotopic relative to boundary" relation between `GenLoop`s. -/
def Homotopic (f g : Ω^ N X x) : Prop 
goal: Prop

full_name: GenLoop.Homotopic.refl
code: @[refl]
theorem refl (f : Ω^ N X x) : Homotopic f f 
goal: GenLoop.Homotopic f f

full_name: GenLoop.Homotopic.symm
code: @[symm]
nonrec theorem symm (H : Homotopic f g) : Homotopic g f 
goal: GenLoop.Homotopic g f

full_name: GenLoop.Homotopic.trans
code: @[trans]
nonrec theorem trans (H0 : Homotopic f g) (H1 : Homotopic g h) : Homotopic f h 
goal: GenLoop.Homotopic f h

full_name: GenLoop.Homotopic.equiv
code: theorem equiv : Equivalence (@Homotopic N X _ x) 
goal: Equivalence GenLoop.Homotopic

full_name: GenLoop.Homotopic.setoid
code: instance setoid (N) (x : X) : Setoid (Ω^ N X x) 
goal: Setoid ↑(Ω^ N X x)

full_name: GenLoop.toLoop
code: /-- Loop from a generalized loop by currying $I^N → X$ into $I → (I^{N\setminus\{j\}} → X)$. -/
@[simps]
def toLoop (i : N) (p : Ω^ N X x) : Ω (Ω^ { j // j ≠ i } X x) const 
goal: Ω (↑(Ω^ { j // j ≠ i } X x)) GenLoop.const

full_name: GenLoop.toLoop_apply_coe
code: /-- Loop from a generalized loop by currying $I^N → X$ into $I → (I^{N\setminus\{j\}} → X)$. -/
@[simps]
def toLoop (i : N) (p : Ω^ N X x) : Ω (Ω^ { j // j ≠ i } X x) const 
goal: ↑((GenLoop.toLoop i p) t) = ((↑p).comp (Cube.insertAt i).toContinuousMap).curry t

full_name: GenLoop.continuous_toLoop
code: theorem continuous_toLoop (i : N) : Continuous (@toLoop N X _ x _ i) 
goal: Continuous (GenLoop.toLoop i)

full_name: GenLoop.fromLoop_coe
code: /-- Generalized loop from a loop by uncurrying $I → (I^{N\setminus\{j\}} → X)$ into $I^N → X$. -/
@[simps]
def fromLoop (i : N) (p : Ω (Ω^ { j // j ≠ i } X x) const) : Ω^ N X x 
goal: ↑(GenLoop.fromLoop i p) =
  ({ toFun := Subtype.val, continuous_toFun := ⋯ }.comp p.toContinuousMap).uncurry.comp (Cube.splitAt i).toContinuousMap

full_name: GenLoop.fromLoop
code: /-- Generalized loop from a loop by uncurrying $I → (I^{N\setminus\{j\}} → X)$ into $I^N → X$. -/
@[simps]
def fromLoop (i : N) (p : Ω (Ω^ { j // j ≠ i } X x) const) : Ω^ N X x 
goal: ↑(Ω^ N X x)

full_name: GenLoop.continuous_fromLoop
code: theorem continuous_fromLoop (i : N) : Continuous (@fromLoop N X _ x _ i) 
goal: Continuous (GenLoop.fromLoop i)

full_name: GenLoop.to_from
code: theorem to_from (i : N) (p : Ω (Ω^ { j // j ≠ i } X x) const) : toLoop i (fromLoop i p) = p 
goal: GenLoop.toLoop i (GenLoop.fromLoop i p) = p

full_name: GenLoop.loopHomeo_apply
code: /-- The `n+1`-dimensional loops are in bijection with the loops in the space of
  `n`-dimensional loops with base point `const`.
  We allow an arbitrary indexing type `N` in place of `Fin n` here. -/
@[simps]
def loopHomeo (i : N) : Ω^ N X x ≃ₜ Ω (Ω^ { j // j ≠ i } X x) const 
goal: (GenLoop.loopHomeo i) p = GenLoop.toLoop i p

full_name: GenLoop.loopHomeo_symm_apply
code: /-- The `n+1`-dimensional loops are in bijection with the loops in the space of
  `n`-dimensional loops with base point `const`.
  We allow an arbitrary indexing type `N` in place of `Fin n` here. -/
@[simps]
def loopHomeo (i : N) : Ω^ N X x ≃ₜ Ω (Ω^ { j // j ≠ i } X x) const 
goal: (GenLoop.loopHomeo i).symm p = GenLoop.fromLoop i p

full_name: GenLoop.loopHomeo
code: /-- The `n+1`-dimensional loops are in bijection with the loops in the space of
  `n`-dimensional loops with base point `const`.
  We allow an arbitrary indexing type `N` in place of `Fin n` here. -/
@[simps]
def loopHomeo (i : N) : Ω^ N X x ≃ₜ Ω (Ω^ { j // j ≠ i } X x) const 
goal: ↑(Ω^ N X x) ≃ₜ Ω (↑(Ω^ { j // j ≠ i } X x)) GenLoop.const

full_name: GenLoop.toLoop_apply
code: theorem toLoop_apply (i : N) {p : Ω^ N X x} {t} {tn} :
    toLoop i p t tn = p (Cube.insertAt i ⟨t, tn⟩) 
goal: ((GenLoop.toLoop i p) t) tn = p ((Cube.insertAt i) (t, tn))

full_name: GenLoop.fromLoop_apply
code: theorem fromLoop_apply (i : N) {p : Ω (Ω^ { j // j ≠ i } X x) const} {t : I^N} :
    fromLoop i p t = p (t i) (Cube.splitAt i t).snd 
goal: (GenLoop.fromLoop i p) t = (p (t i)) ((Cube.splitAt i) t).2

full_name: GenLoop.cCompInsert
code: /-- Composition with `Cube.insertAt` as a continuous map. -/
abbrev cCompInsert (i : N) : C(C(I^N, X), C(I × I^{ j // j ≠ i }, X)) 
goal: C(C(N → ↑I, X), C(↑I × ({ j // j ≠ i } → ↑I), X))

full_name: GenLoop.homotopyTo
code: /-- A homotopy between `n+1`-dimensional loops `p` and `q` constant on the boundary
  seen as a homotopy between two paths in the space of `n`-dimensional paths. -/
def homotopyTo (i : N) {p q : Ω^ N X x} (H : p.1.HomotopyRel q.1 (Cube.boundary N)) :
    C(I × I, C(I^{ j // j ≠ i }, X)) 
goal: C(↑I × ↑I, C({ j // j ≠ i } → ↑I, X))

full_name: GenLoop.homotopyTo_apply
code: theorem homotopyTo_apply (i : N) {p q : Ω^ N X x} (H : p.1.HomotopyRel q.1 <| Cube.boundary N)
    (t : I × I) (tₙ : I^{ j // j ≠ i }) :
    homotopyTo i H t tₙ = H (t.fst, Cube.insertAt i (t.snd, tₙ)) 
goal: ((GenLoop.homotopyTo i H) t) tₙ = H (t.1, (Cube.insertAt i) (t.2, tₙ))

full_name: GenLoop.homotopicTo
code: theorem homotopicTo (i : N) {p q : Ω^ N X x} :
    Homotopic p q → (toLoop i p).Homotopic (toLoop i q) 
goal: GenLoop.Homotopic p q → Path.Homotopic (GenLoop.toLoop i p) (GenLoop.toLoop i q)

full_name: GenLoop.homotopyFrom_apply
code: /-- The converse to `GenLoop.homotopyTo`: a homotopy between two loops in the space of
  `n`-dimensional loops can be seen as a homotopy between two `n+1`-dimensional paths. -/
@[simps!] def homotopyFrom (i : N) {p q : Ω^ N X x} (H : (toLoop i p).Homotopy (toLoop i q)) :
    C(I × I^N, X) 
goal: ∀ (a : ↑I × (N → ↑I)),
  (GenLoop.homotopyFrom i H) a =
    Function.uncurry (fun x_1 y => Function.uncurry (fun x_2 y => ↑(H (x_1, x_2)) y) y)
      (Prod.map id (⇑(Cube.splitAt i).toContinuousMap) a)

full_name: GenLoop.homotopyFrom
code: /-- The converse to `GenLoop.homotopyTo`: a homotopy between two loops in the space of
  `n`-dimensional loops can be seen as a homotopy between two `n+1`-dimensional paths. -/
@[simps!] def homotopyFrom (i : N) {p q : Ω^ N X x} (H : (toLoop i p).Homotopy (toLoop i q)) :
    C(I × I^N, X) 
goal: C(↑I × (N → ↑I), X)

full_name: GenLoop.homotopicFrom
code: theorem homotopicFrom (i : N) {p q : Ω^ N X x} :
    (toLoop i p).Homotopic (toLoop i q) → Homotopic p q 
goal: Path.Homotopic (GenLoop.toLoop i p) (GenLoop.toLoop i q) → GenLoop.Homotopic p q

full_name: GenLoop.transAt
code: /-- Concatenation of two `GenLoop`s along the `i`th coordinate. -/
def transAt (i : N) (f g : Ω^ N X x) : Ω^ N X x 
goal: ↑(Ω^ N X x)

full_name: GenLoop.symmAt
code: /-- Reversal of a `GenLoop` along the `i`th coordinate. -/
def symmAt (i : N) (f : Ω^ N X x) : Ω^ N X x 
goal: ↑(Ω^ N X x)

full_name: GenLoop.transAt_distrib
code: theorem transAt_distrib {i j : N} (h : i ≠ j) (a b c d : Ω^ N X x) :
    transAt i (transAt j a b) (transAt j c d) = transAt j (transAt i a c) (transAt i b d) 
goal: GenLoop.transAt i (GenLoop.transAt j a b) (GenLoop.transAt j c d) =
  GenLoop.transAt j (GenLoop.transAt i a c) (GenLoop.transAt i b d)

full_name: GenLoop.fromLoop_trans_toLoop
code: theorem fromLoop_trans_toLoop {i : N} {p q : Ω^ N X x} :
    fromLoop i ((toLoop i p).trans <| toLoop i q) = transAt i p q 
goal: GenLoop.fromLoop i (Path.trans (GenLoop.toLoop i p) (GenLoop.toLoop i q)) = GenLoop.transAt i p q

full_name: GenLoop.fromLoop_symm_toLoop
code: theorem fromLoop_symm_toLoop {i : N} {p : Ω^ N X x} : fromLoop i (toLoop i p).symm = symmAt i p 
goal: GenLoop.fromLoop i (Path.symm (GenLoop.toLoop i p)) = GenLoop.symmAt i p

full_name: HomotopyGroup
code: /-- The `n`th homotopy group at `x` defined as the quotient of `Ω^n x` by the
  `GenLoop.Homotopic` relation. -/
def HomotopyGroup (N X : Type*) [TopologicalSpace X] (x : X) : Type _ 
goal: Type (max u_3 u_4)

full_name: instInhabitedHomotopyGroup
code: instance : Inhabited (HomotopyGroup N X x) 
goal: Inhabited (HomotopyGroup N X x)

full_name: homotopyGroupEquivFundamentalGroup
code: /-- Equivalence between the homotopy group of X and the fundamental group of
  `Ω^{j // j ≠ i} x`. -/
def homotopyGroupEquivFundamentalGroup (i : N) :
    HomotopyGroup N X x ≃ FundamentalGroup (Ω^ { j // j ≠ i } X x) const 
goal: HomotopyGroup N X x ≃ FundamentalGroup (↑(Ω^ { j // j ≠ i } X x)) GenLoop.const

full_name: HomotopyGroup.Pi
code: /-- Homotopy group of finite index. -/
abbrev HomotopyGroup.Pi (n) (X : Type*) [TopologicalSpace X] (x : X) 
goal: Type u_3

full_name: Topology._aux_Mathlib_Topology_Homotopy_HomotopyGroup___unexpand_HomotopyGroup_Pi_1
code: scoped[Topology] notation "π_" => HomotopyGroup.Pi
goal: Lean.PrettyPrinter.Unexpander

full_name: Topology._aux_Mathlib_Topology_Homotopy_HomotopyGroup___macroRules_Topology_termπ__1
code: scoped[Topology] notation "π_" => HomotopyGroup.Pi
goal: Lean.Macro

full_name: genLoopHomeoOfIsEmpty
code: /-- The 0-dimensional generalized loops based at `x` are in bijection with `X`. -/
def genLoopHomeoOfIsEmpty (N x) [IsEmpty N] : Ω^ N X x ≃ₜ X 
goal: ↑(Ω^ N X x) ≃ₜ X

full_name: homotopyGroupEquivZerothHomotopyOfIsEmpty
code: /-- The homotopy "group" indexed by an empty type is in bijection with
  the path components of `X`, aka the `ZerothHomotopy`. -/
def homotopyGroupEquivZerothHomotopyOfIsEmpty (N x) [IsEmpty N] :
    HomotopyGroup N X x ≃ ZerothHomotopy X 
goal: HomotopyGroup N X x ≃ ZerothHomotopy X

full_name: HomotopyGroup.pi0EquivZerothHomotopy
code: /-- The 0th homotopy "group" is in bijection with `ZerothHomotopy`. -/
def HomotopyGroup.pi0EquivZerothHomotopy : π_ 0 X x ≃ ZerothHomotopy X 
goal: π_ 0 X x ≃ ZerothHomotopy X

full_name: genLoopEquivOfUnique
code: /-- The 1-dimensional generalized loops based at `x` are in bijection with loops at `x`. -/
def genLoopEquivOfUnique (N) [Unique N] : Ω^ N X x ≃ Ω X x 
goal: ↑(Ω^ N X x) ≃ Ω X x

full_name: homotopyGroupEquivFundamentalGroupOfUnique
code: /-- The homotopy group at `x` indexed by a singleton is in bijection with the fundamental group,
  i.e. the loops based at `x` up to homotopy. -/
def homotopyGroupEquivFundamentalGroupOfUnique (N) [Unique N] :
    HomotopyGroup N X x ≃ FundamentalGroup X x 
goal: HomotopyGroup N X x ≃ FundamentalGroup X x

full_name: HomotopyGroup.pi1EquivFundamentalGroup
code: /-- The first homotopy group at `x` is in bijection with the fundamental group. -/
def HomotopyGroup.pi1EquivFundamentalGroup : π_ 1 X x ≃ FundamentalGroup X x 
goal: π_ 1 X x ≃ FundamentalGroup X x

full_name: HomotopyGroup.group
code: /-- Group structure on `HomotopyGroup N X x` for nonempty `N` (in particular `π_(n+1) X x`). -/
instance group (N) [DecidableEq N] [Nonempty N] : Group (HomotopyGroup N X x) 
goal: Group (HomotopyGroup N X x)

full_name: HomotopyGroup.auxGroup
code: /-- Group structure on `HomotopyGroup` obtained by pulling back path composition along the
  `i`th direction. The group structures for two different `i j : N` distribute over each
  other, and therefore are equal by the Eckmann-Hilton argument. -/
abbrev auxGroup (i : N) : Group (HomotopyGroup N X x) 
goal: Group (HomotopyGroup N X x)

full_name: HomotopyGroup.isUnital_auxGroup
code: theorem isUnital_auxGroup (i : N) :
    EckmannHilton.IsUnital (auxGroup i).mul (⟦const⟧ : HomotopyGroup N X x) 
goal: EckmannHilton.IsUnital Mul.mul ⟦GenLoop.const⟧

full_name: HomotopyGroup.auxGroup_indep
code: theorem auxGroup_indep (i j : N) : (auxGroup i : Group (HomotopyGroup N X x)) = auxGroup j 
goal: HomotopyGroup.auxGroup i = HomotopyGroup.auxGroup j

full_name: HomotopyGroup.transAt_indep
code: theorem transAt_indep {i} (j) (f g : Ω^ N X x) :
    (⟦transAt i f g⟧ : HomotopyGroup N X x) = ⟦transAt j f g⟧ 
goal: ⟦GenLoop.transAt i f g⟧ = ⟦GenLoop.transAt j f g⟧

full_name: HomotopyGroup.symmAt_indep
code: theorem symmAt_indep {i} (j) (f : Ω^ N X x) :
    (⟦symmAt i f⟧ : HomotopyGroup N X x) = ⟦symmAt j f⟧ 
goal: ⟦GenLoop.symmAt i f⟧ = ⟦GenLoop.symmAt j f⟧

full_name: HomotopyGroup.one_def
code: /-- Characterization of multiplicative identity -/
theorem one_def [Nonempty N] : (1 : HomotopyGroup N X x) = ⟦const⟧ 
goal: 1 = ⟦GenLoop.const⟧

full_name: HomotopyGroup.mul_spec
code: /-- Characterization of multiplication -/
theorem mul_spec [Nonempty N] {i} {p q : Ω^ N X x} :
    -- Porting note (#11215): TODO: introduce `HomotopyGroup.mk` and remove defeq abuse.
    ((· * ·) : _ → _ → HomotopyGroup N X x) ⟦p⟧ ⟦q⟧ = ⟦transAt i q p⟧ 
goal: (fun x_1 x_2 => x_1 * x_2) ⟦p⟧ ⟦q⟧ = ⟦GenLoop.transAt i q p⟧

full_name: HomotopyGroup.inv_spec
code: /-- Characterization of multiplicative inverse -/
theorem inv_spec [Nonempty N] {i} {p : Ω^ N X x} :
    ((⟦p⟧)⁻¹ : HomotopyGroup N X x) = ⟦symmAt i p⟧ 
goal: (⟦p⟧)⁻¹ = ⟦GenLoop.symmAt i p⟧

full_name: HomotopyGroup.commGroup
code: /-- Multiplication on `HomotopyGroup N X x` is commutative for nontrivial `N`.
  In particular, multiplication on `π_(n+2)` is commutative. -/
instance commGroup [Nontrivial N] : CommGroup (HomotopyGroup N X x) 
goal: CommGroup (HomotopyGroup N X x)