File: Mathlib/GroupTheory/PushoutI.lean

full_name: Monoid.PushoutI.con
code: /-- The relation we quotient by to form the pushout -/
def PushoutI.con [∀ i, Monoid (G i)] [Monoid H] (φ : ∀ i, H →* G i) :
    Con (Coprod (CoprodI G) H) 
goal: Con (Monoid.Coprod (Monoid.CoprodI G) H)

full_name: Monoid.PushoutI
code: /-- The indexed pushout of monoids, which is the pushout in the category of monoids,
or the category of groups. -/
def PushoutI [∀ i, Monoid (G i)] [Monoid H] (φ : ∀ i, H →* G i) : Type _ 
goal: Type (max (max u_1 u_2) u_3)

full_name: Monoid.PushoutI.mul
code: protected instance mul : Mul (PushoutI φ) 
goal: Mul (Monoid.PushoutI φ)

full_name: Monoid.PushoutI.one
code: protected instance one : One (PushoutI φ) 
goal: One (Monoid.PushoutI φ)

full_name: Monoid.PushoutI.monoid
code: instance monoid : Monoid (PushoutI φ) 
goal: Monoid (Monoid.PushoutI φ)

full_name: Monoid.PushoutI.of
code: /-- The map from each indexing group into the pushout -/
def of (i : ι) : G i →* PushoutI φ 
goal: G i →* Monoid.PushoutI φ

full_name: Monoid.PushoutI.base
code: /-- The map from the base monoid into the pushout -/
def base : H →* PushoutI φ 
goal: H →* Monoid.PushoutI φ

full_name: Monoid.PushoutI.of_comp_eq_base
code: theorem of_comp_eq_base (i : ι) : (of i).comp (φ i) = (base φ) 
goal: (Monoid.PushoutI.of i).comp (φ i) = Monoid.PushoutI.base φ

full_name: Monoid.PushoutI.of_apply_eq_base
code: theorem of_apply_eq_base (i : ι) (x : H) : of i (φ i x) = base φ x 
goal: (Monoid.PushoutI.of i) ((φ i) x) = (Monoid.PushoutI.base φ) x

full_name: Monoid.PushoutI.lift
code: /-- Define a homomorphism out of the pushout of monoids be defining it on each object in the
diagram -/
def lift (f : ∀ i, G i →* K) (k : H →* K)
    (hf : ∀ i, (f i).comp (φ i) = k) :
    PushoutI φ →* K 
goal: Monoid.PushoutI φ →* K

full_name: Monoid.PushoutI.lift_of
code: @[simp]
theorem lift_of (f : ∀ i, G i →* K) (k : H →* K)
    (hf : ∀ i, (f i).comp (φ i) = k)
    {i : ι} (g : G i) : (lift f k hf) (of i g : PushoutI φ) = f i g 
goal: (Monoid.PushoutI.lift f k hf) ((Monoid.PushoutI.of i) g) = (f i) g

full_name: Monoid.PushoutI.lift_base
code: @[simp]
theorem lift_base (f : ∀ i, G i →* K) (k : H →* K)
    (hf : ∀ i, (f i).comp (φ i) = k)
    (g : H) : (lift f k hf) (base φ g : PushoutI φ) = k g 
goal: (Monoid.PushoutI.lift f k hf) ((Monoid.PushoutI.base φ) g) = k g

full_name: Monoid.PushoutI.hom_ext
code: @[ext 1199]
theorem hom_ext {f g : PushoutI φ →* K}
    (h : ∀ i, f.comp (of i : G i →* _) = g.comp (of i : G i →* _))
    (hbase : f.comp (base φ) = g.comp (base φ)) : f = g 
goal: f = g

full_name: Monoid.PushoutI.hom_ext_nonempty
code: @[ext high]
theorem hom_ext_nonempty [hn : Nonempty ι]
    {f g : PushoutI φ →* K}
    (h : ∀ i, f.comp (of i : G i →* _) = g.comp (of i : G i →* _)) : f = g 
goal: f = g

full_name: Monoid.PushoutI.homEquiv
code: /-- The equivalence that is part of the universal property of the pushout. A hom out of
the pushout is just a morphism out of all groups in the pushout that satisfies a commutativity
condition. -/
@[simps]
def homEquiv :
    (PushoutI φ →* K) ≃ { f : (Π i, G i →* K) × (H →* K) // ∀ i, (f.1 i).comp (φ i) = f.2 } 
goal: (Monoid.PushoutI φ →* K) ≃ { f // ∀ (i : ι), (f.1 i).comp (φ i) = f.2 }

full_name: Monoid.PushoutI.homEquiv_symm_apply
code: /-- The equivalence that is part of the universal property of the pushout. A hom out of
the pushout is just a morphism out of all groups in the pushout that satisfies a commutativity
condition. -/
@[simps]
def homEquiv :
    (PushoutI φ →* K) ≃ { f : (Π i, G i →* K) × (H →* K) // ∀ i, (f.1 i).comp (φ i) = f.2 } 
goal: Monoid.PushoutI.homEquiv.symm f = Monoid.PushoutI.lift (↑f).1 (↑f).2 ⋯

full_name: Monoid.PushoutI.homEquiv_apply_coe
code: /-- The equivalence that is part of the universal property of the pushout. A hom out of
the pushout is just a morphism out of all groups in the pushout that satisfies a commutativity
condition. -/
@[simps]
def homEquiv :
    (PushoutI φ →* K) ≃ { f : (Π i, G i →* K) × (H →* K) // ∀ i, (f.1 i).comp (φ i) = f.2 } 
goal: ↑(Monoid.PushoutI.homEquiv f) = (fun i => f.comp (Monoid.PushoutI.of i), f.comp (Monoid.PushoutI.base φ))

full_name: Monoid.PushoutI.ofCoprodI
code: /-- The map from the coproduct into the pushout -/
def ofCoprodI : CoprodI G →* PushoutI φ 
goal: Monoid.CoprodI G →* Monoid.PushoutI φ

full_name: Monoid.PushoutI.ofCoprodI_of
code: @[simp]
theorem ofCoprodI_of (i : ι) (g : G i) :
    (ofCoprodI (CoprodI.of g) : PushoutI φ) = of i g 
goal: Monoid.PushoutI.ofCoprodI (Monoid.CoprodI.of g) = (Monoid.PushoutI.of i) g

full_name: Monoid.PushoutI.induction_on
code: theorem induction_on {motive : PushoutI φ → Prop}
    (x : PushoutI φ)
    (of : ∀ (i : ι) (g : G i), motive (of i g))
    (base : ∀ h, motive (base φ h))
    (mul : ∀ x y, motive x → motive y → motive (x * y)) : motive x 
goal: motive x

full_name: Monoid.PushoutI.instGroup
code: instance : Group (PushoutI φ) 
goal: Group (Monoid.PushoutI φ)

full_name: Monoid.PushoutI.NormalWord.Transversal.injective
code: /-- The data we need to pick a normal form for words in the pushout. We need to pick a
canonical element of each coset. We also need all the maps in the diagram to be injective  -/
structure Transversal : Type _ where
  /-- All maps in the diagram are injective -/
  injective : ∀ i, Injective (φ i)
  /-- The underlying set, containing exactly one element of each coset of the base group -/
  set : ∀ i, Set (G i)
  /-- The chosen element of the base group itself is the identity -/
  one_mem : ∀ i, 1 ∈ set i
  /-- We have exactly one element of each coset of the base group -/
  compl : ∀ i, IsComplement (φ i).range (set i)
goal: Function.Injective ⇑(φ i)

full_name: Monoid.PushoutI.NormalWord.Transversal
code: /-- The data we need to pick a normal form for words in the pushout. We need to pick a
canonical element of each coset. We also need all the maps in the diagram to be injective  -/
structure Transversal : Type _ where
  /-- All maps in the diagram are injective -/
  injective : ∀ i, Injective (φ i)
  /-- The underlying set, containing exactly one element of each coset of the base group -/
  set : ∀ i, Set (G i)
  /-- The chosen element of the base group itself is the identity -/
  one_mem : ∀ i, 1 ∈ set i
  /-- We have exactly one element of each coset of the base group -/
  compl : ∀ i, IsComplement (φ i).range (set i)
goal: Type (max u_1 u_2)

full_name: Monoid.PushoutI.NormalWord.Transversal.one_mem
code: /-- The data we need to pick a normal form for words in the pushout. We need to pick a
canonical element of each coset. We also need all the maps in the diagram to be injective  -/
structure Transversal : Type _ where
  /-- All maps in the diagram are injective -/
  injective : ∀ i, Injective (φ i)
  /-- The underlying set, containing exactly one element of each coset of the base group -/
  set : ∀ i, Set (G i)
  /-- The chosen element of the base group itself is the identity -/
  one_mem : ∀ i, 1 ∈ set i
  /-- We have exactly one element of each coset of the base group -/
  compl : ∀ i, IsComplement (φ i).range (set i)
goal: 1 ∈ self.set i

full_name: Monoid.PushoutI.NormalWord.Transversal.set
code: /-- The data we need to pick a normal form for words in the pushout. We need to pick a
canonical element of each coset. We also need all the maps in the diagram to be injective  -/
structure Transversal : Type _ where
  /-- All maps in the diagram are injective -/
  injective : ∀ i, Injective (φ i)
  /-- The underlying set, containing exactly one element of each coset of the base group -/
  set : ∀ i, Set (G i)
  /-- The chosen element of the base group itself is the identity -/
  one_mem : ∀ i, 1 ∈ set i
  /-- We have exactly one element of each coset of the base group -/
  compl : ∀ i, IsComplement (φ i).range (set i)
goal: Set (G i)

full_name: Monoid.PushoutI.NormalWord.Transversal.compl
code: /-- The data we need to pick a normal form for words in the pushout. We need to pick a
canonical element of each coset. We also need all the maps in the diagram to be injective  -/
structure Transversal : Type _ where
  /-- All maps in the diagram are injective -/
  injective : ∀ i, Injective (φ i)
  /-- The underlying set, containing exactly one element of each coset of the base group -/
  set : ∀ i, Set (G i)
  /-- The chosen element of the base group itself is the identity -/
  one_mem : ∀ i, 1 ∈ set i
  /-- We have exactly one element of each coset of the base group -/
  compl : ∀ i, IsComplement (φ i).range (set i)
goal: Subgroup.IsComplement (↑(φ i).range) (self.set i)

full_name: Monoid.PushoutI.NormalWord.transversal_nonempty
code: theorem transversal_nonempty (hφ : ∀ i, Injective (φ i)) : Nonempty (Transversal φ) 
goal: Nonempty (Monoid.PushoutI.NormalWord.Transversal φ)

full_name: Monoid.PushoutI.NormalWord.normalized
code: /-- The normal form for words in the pushout. Every element of the pushout is the product of an
element of the base group and a word made up of letters each of which is in the transversal. -/
structure _root_.Monoid.PushoutI.NormalWord (d : Transversal φ) extends CoprodI.Word G where
  /-- Every `NormalWord` is the product of an element of the base group and a word made up
  of letters each of which is in the transversal. `head` is that element of the base group. -/
  head : H
  /-- All letter in the word are in the transversal. -/
  normalized : ∀ i g, ⟨i, g⟩ ∈ toList → g ∈ d.set i
goal: ⟨i, g⟩ ∈ self.toList → g ∈ d.set i

full_name: Monoid.PushoutI.NormalWord.head
code: /-- The normal form for words in the pushout. Every element of the pushout is the product of an
element of the base group and a word made up of letters each of which is in the transversal. -/
structure _root_.Monoid.PushoutI.NormalWord (d : Transversal φ) extends CoprodI.Word G where
  /-- Every `NormalWord` is the product of an element of the base group and a word made up
  of letters each of which is in the transversal. `head` is that element of the base group. -/
  head : H
  /-- All letter in the word are in the transversal. -/
  normalized : ∀ i g, ⟨i, g⟩ ∈ toList → g ∈ d.set i
goal: H

full_name: Monoid.PushoutI.NormalWord
code: /-- The normal form for words in the pushout. Every element of the pushout is the product of an
element of the base group and a word made up of letters each of which is in the transversal. -/
structure _root_.Monoid.PushoutI.NormalWord (d : Transversal φ) extends CoprodI.Word G where
  /-- Every `NormalWord` is the product of an element of the base group and a word made up
  of letters each of which is in the transversal. `head` is that element of the base group. -/
  head : H
  /-- All letter in the word are in the transversal. -/
  normalized : ∀ i g, ⟨i, g⟩ ∈ toList → g ∈ d.set i
goal: Type (max (max u_1 u_2) u_3)

full_name: Monoid.PushoutI.NormalWord.Pair.normalized
code: /--
A `Pair d i` is a word in the coproduct, `Coprod G`, the `tail`, and an element of the group `G i`,
the `head`. The first letter of the `tail` must not be an element of `G i`.
Note that the `head` may be `1` Every letter in the `tail` must be in the transversal given by `d`.
Similar to `Monoid.CoprodI.Pair` except every letter must be in the transversal
(not including the head letter). -/
structure Pair (d : Transversal φ) (i : ι) extends CoprodI.Word.Pair G i where
  /-- All letters in the word are in the transversal. -/
  normalized : ∀ i g, ⟨i, g⟩ ∈ tail.toList → g ∈ d.set i
goal: ∀ (i_1 : ι) (g : G i_1), ⟨i_1, g⟩ ∈ self.tail.toList → g ∈ d.set i_1

full_name: Monoid.PushoutI.NormalWord.Pair
code: /--
A `Pair d i` is a word in the coproduct, `Coprod G`, the `tail`, and an element of the group `G i`,
the `head`. The first letter of the `tail` must not be an element of `G i`.
Note that the `head` may be `1` Every letter in the `tail` must be in the transversal given by `d`.
Similar to `Monoid.CoprodI.Pair` except every letter must be in the transversal
(not including the head letter). -/
structure Pair (d : Transversal φ) (i : ι) extends CoprodI.Word.Pair G i where
  /-- All letters in the word are in the transversal. -/
  normalized : ∀ i g, ⟨i, g⟩ ∈ tail.toList → g ∈ d.set i
goal: Type (max u_1 u_2)

full_name: Monoid.PushoutI.NormalWord.empty
code: /-- The empty normalized word, representing the identity element of the group. -/
@[simps!]
def empty : NormalWord d 
goal: Monoid.PushoutI.NormalWord d

full_name: Monoid.PushoutI.NormalWord.empty_head
code: /-- The empty normalized word, representing the identity element of the group. -/
@[simps!]
def empty : NormalWord d 
goal: Monoid.PushoutI.NormalWord.empty.head = 1

full_name: Monoid.PushoutI.NormalWord.empty_toList
code: /-- The empty normalized word, representing the identity element of the group. -/
@[simps!]
def empty : NormalWord d 
goal: Monoid.PushoutI.NormalWord.empty.toList = []

full_name: Monoid.PushoutI.NormalWord.instInhabited
code: instance : Inhabited (NormalWord d) 
goal: Inhabited (Monoid.PushoutI.NormalWord d)

full_name: Monoid.PushoutI.NormalWord.instInhabitedPair
code: instance (i : ι) : Inhabited (Pair d i) 
goal: Inhabited (Monoid.PushoutI.NormalWord.Pair d i)

full_name: Monoid.PushoutI.NormalWord.ext
code: @[ext]
theorem ext {w₁ w₂ : NormalWord d} (hhead : w₁.head = w₂.head)
    (hlist : w₁.toList = w₂.toList) : w₁ = w₂ 
goal: w₁ = w₂

full_name: Monoid.PushoutI.NormalWord.ext_iff
code: theorem ext_iff {w₁ w₂ : NormalWord d} : w₁ = w₂ ↔ w₁.head = w₂.head ∧ w₁.toList = w₂.toList 
goal: w₁ = w₂ ↔ w₁.head = w₂.head ∧ w₁.toList = w₂.toList

full_name: Monoid.PushoutI.NormalWord.eq_one_of_smul_normalized
code: /-- Given a word in `CoprodI`, if every letter is in the transversal and when
we multiply by an element of the base group it still has this property,
then the element of the base group we multiplied by was one.  -/
theorem eq_one_of_smul_normalized (w : CoprodI.Word G) {i : ι} (h : H)
    (hw : ∀ i g, ⟨i, g⟩ ∈ w.toList → g ∈ d.set i)
    (hφw : ∀ j g, ⟨j, g⟩ ∈ (CoprodI.of (φ i h) • w).toList → g ∈ d.set j) :
    h = 1 
goal: h = 1

full_name: Monoid.PushoutI.NormalWord.ext_smul
code: theorem ext_smul {w₁ w₂ : NormalWord d} (i : ι)
    (h : CoprodI.of (φ i w₁.head) • w₁.toWord =
         CoprodI.of (φ i w₂.head) • w₂.toWord) :
    w₁ = w₂ 
goal: w₁ = w₂

full_name: Monoid.PushoutI.NormalWord.cons_toList
code: /-- A constructor that multiplies a `NormalWord` by an element, with condition to make
sure the underlying list does get longer.  -/
@[simps!]
noncomputable def cons {i} (g : G i) (w : NormalWord d) (hmw : w.fstIdx ≠ some i)
    (hgr : g ∉ (φ i).range) : NormalWord d 
goal: (Monoid.PushoutI.NormalWord.cons g w hmw hgr).toList = ⟨i, ↑(⋯.equiv (g * (φ i) w.head)).2⟩ :: w.toList

full_name: Monoid.PushoutI.NormalWord.cons
code: /-- A constructor that multiplies a `NormalWord` by an element, with condition to make
sure the underlying list does get longer.  -/
@[simps!]
noncomputable def cons {i} (g : G i) (w : NormalWord d) (hmw : w.fstIdx ≠ some i)
    (hgr : g ∉ (φ i).range) : NormalWord d 
goal: Monoid.PushoutI.NormalWord d

full_name: Monoid.PushoutI.NormalWord.cons_head
code: /-- A constructor that multiplies a `NormalWord` by an element, with condition to make
sure the underlying list does get longer.  -/
@[simps!]
noncomputable def cons {i} (g : G i) (w : NormalWord d) (hmw : w.fstIdx ≠ some i)
    (hgr : g ∉ (φ i).range) : NormalWord d 
goal: (Monoid.PushoutI.NormalWord.cons g w hmw hgr).head = (MonoidHom.ofInjective ⋯).symm (⋯.equiv (g * (φ i) w.head)).1

full_name: Monoid.PushoutI.NormalWord.rcons
code: /-- Given a pair `(head, tail)`, we can form a word by prepending `head` to `tail`, but
putting head into normal form first, by making sure it is expressed as an element
of the base group multiplied by an element of the transversal. -/
noncomputable def rcons (i : ι) (p : Pair d i) : NormalWord d 
goal: Monoid.PushoutI.NormalWord d

full_name: Monoid.PushoutI.NormalWord.rcons_injective
code: theorem rcons_injective {i : ι} : Function.Injective (rcons (d := d) i) 
goal: Function.Injective (Monoid.PushoutI.NormalWord.rcons i)

full_name: Monoid.PushoutI.NormalWord.equivPair
code: /-- The equivalence between `NormalWord`s and pairs. We can turn a `NormalWord` into a
pair by taking the head of the `List` if it is in `G i` and multiplying it by the element of the
base group. -/
noncomputable def equivPair (i) : NormalWord d ≃ Pair d i 
goal: Monoid.PushoutI.NormalWord d ≃ Monoid.PushoutI.NormalWord.Pair d i

full_name: Monoid.PushoutI.NormalWord.summandAction
code: noncomputable instance summandAction (i : ι) : MulAction (G i) (NormalWord d) 
goal: MulAction (G i) (Monoid.PushoutI.NormalWord d)

full_name: Monoid.PushoutI.NormalWord.baseAction
code: instance baseAction : MulAction H (NormalWord d) 
goal: MulAction H (Monoid.PushoutI.NormalWord d)

full_name: Monoid.PushoutI.NormalWord.base_smul_def'
code: theorem base_smul_def' (h : H) (w : NormalWord d) :
    h • w = { w with head := h * w.head } 
goal: h • w = { toWord := w.toWord, head := h * w.head, normalized := ⋯ }

full_name: Monoid.PushoutI.NormalWord.summand_smul_def'
code: theorem summand_smul_def' {i : ι} (g : G i) (w : NormalWord d) :
    g • w = (equivPair i).symm
      { equivPair i w with
        head := g * (equivPair i w).head } 
goal: g • w =
  (Monoid.PushoutI.NormalWord.equivPair i).symm
    (let __src := (Monoid.PushoutI.NormalWord.equivPair i) w;
    { head := g * ((Monoid.PushoutI.NormalWord.equivPair i) w).head, tail := __src.tail, fstIdx_ne := ⋯,
      normalized := ⋯ })

full_name: Monoid.PushoutI.NormalWord.mulAction
code: noncomputable instance mulAction : MulAction (PushoutI φ) (NormalWord d) 
goal: MulAction (Monoid.PushoutI φ) (Monoid.PushoutI.NormalWord d)

full_name: Monoid.PushoutI.NormalWord.base_smul_def
code: theorem base_smul_def (h : H) (w : NormalWord d) :
    base φ h • w = { w with head := h * w.head } 
goal: (Monoid.PushoutI.base φ) h • w = { toWord := w.toWord, head := h * w.head, normalized := ⋯ }

full_name: Monoid.PushoutI.NormalWord.summand_smul_def
code: theorem summand_smul_def {i : ι} (g : G i) (w : NormalWord d) :
    of (φ := φ) i g • w = (equivPair i).symm
      { equivPair i w with
        head := g * (equivPair i w).head } 
goal: (Monoid.PushoutI.of i) g • w =
  (Monoid.PushoutI.NormalWord.equivPair i).symm
    (let __src := (Monoid.PushoutI.NormalWord.equivPair i) w;
    { head := g * ((Monoid.PushoutI.NormalWord.equivPair i) w).head, tail := __src.tail, fstIdx_ne := ⋯,
      normalized := ⋯ })

full_name: Monoid.PushoutI.NormalWord.of_smul_eq_smul
code: theorem of_smul_eq_smul {i : ι} (g : G i) (w : NormalWord d) :
    of (φ := φ) i g • w = g • w 
goal: (Monoid.PushoutI.of i) g • w = g • w

full_name: Monoid.PushoutI.NormalWord.base_smul_eq_smul
code: theorem base_smul_eq_smul (h : H) (w : NormalWord d) :
    base φ h • w = h • w 
goal: (Monoid.PushoutI.base φ) h • w = h • w

full_name: Monoid.PushoutI.NormalWord.consRecOn
code: /-- Induction principle for `NormalWord`, that corresponds closely to inducting on
the underlying list. -/
@[elab_as_elim]
noncomputable def consRecOn {motive : NormalWord d → Sort _} (w : NormalWord d)
    (h_empty : motive empty)
    (h_cons : ∀ (i : ι) (g : G i) (w : NormalWord d) (hmw : w.fstIdx ≠ some i)
      (_hgn : g ∈ d.set i) (hgr : g ∉ (φ i).range) (_hw1 : w.head = 1),
      motive w →  motive (cons g w hmw hgr))
    (h_base : ∀ (h : H) (w : NormalWord d), w.head = 1 → motive w → motive
      (base φ h • w)) : motive w 
goal: motive w

full_name: Monoid.PushoutI.NormalWord.prod
code: /-- Take the product of a normal word as an element of the `PushoutI`. We show that this is
bijective, in `NormalWord.equiv`. -/
def prod (w : NormalWord d) : PushoutI φ 
goal: Monoid.PushoutI φ

full_name: Monoid.PushoutI.NormalWord.cons_eq_smul
code: theorem cons_eq_smul {i : ι} (g : G i)
    (w : NormalWord d) (hmw : w.fstIdx ≠ some i)
    (hgr : g ∉ (φ i).range) : cons g w hmw hgr = of (φ := φ) i g  • w 
goal: Monoid.PushoutI.NormalWord.cons g w hmw hgr = (Monoid.PushoutI.of i) g • w

full_name: Monoid.PushoutI.NormalWord.prod_summand_smul
code: @[simp]
theorem prod_summand_smul {i : ι} (g : G i) (w : NormalWord d) :
    (g • w).prod = of i g * w.prod 
goal: (g • w).prod = (Monoid.PushoutI.of i) g * w.prod

full_name: Monoid.PushoutI.NormalWord.prod_base_smul
code: @[simp]
theorem prod_base_smul (h : H) (w : NormalWord d) :
    (h • w).prod = base φ h * w.prod 
goal: (h • w).prod = (Monoid.PushoutI.base φ) h * w.prod

full_name: Monoid.PushoutI.NormalWord.prod_smul
code: @[simp]
theorem prod_smul (g : PushoutI φ) (w : NormalWord d) :
    (g • w).prod = g * w.prod 
goal: (g • w).prod = g * w.prod

full_name: Monoid.PushoutI.NormalWord.prod_empty
code: @[simp]
theorem prod_empty : (empty : NormalWord d).prod = 1 
goal: Monoid.PushoutI.NormalWord.empty.prod = 1

full_name: Monoid.PushoutI.NormalWord.prod_cons
code: @[simp]
theorem prod_cons {i} (g : G i) (w : NormalWord d) (hmw : w.fstIdx ≠ some i)
    (hgr : g ∉ (φ i).range) : (cons g w hmw hgr).prod = of i g * w.prod 
goal: (Monoid.PushoutI.NormalWord.cons g w hmw hgr).prod = (Monoid.PushoutI.of i) g * w.prod

full_name: Monoid.PushoutI.NormalWord.prod_smul_empty
code: theorem prod_smul_empty (w : NormalWord d) : w.prod • empty = w 
goal: w.prod • Monoid.PushoutI.NormalWord.empty = w

full_name: Monoid.PushoutI.NormalWord.equiv
code: /-- The equivalence between normal forms and elements of the pushout -/
noncomputable def equiv : PushoutI φ ≃ NormalWord d 
goal: Monoid.PushoutI φ ≃ Monoid.PushoutI.NormalWord d

full_name: Monoid.PushoutI.NormalWord.prod_injective
code: theorem prod_injective : Function.Injective (prod : NormalWord d → PushoutI φ) 
goal: Function.Injective Monoid.PushoutI.NormalWord.prod

full_name: Monoid.PushoutI.NormalWord.instFaithfulSMul
code: instance : FaithfulSMul (PushoutI φ) (NormalWord d) 
goal: FaithfulSMul (Monoid.PushoutI φ) (Monoid.PushoutI.NormalWord d)

full_name: Monoid.PushoutI.NormalWord.instFaithfulSMul_1
code: instance (i : ι) : FaithfulSMul (G i) (NormalWord d) 
goal: FaithfulSMul (G i) (Monoid.PushoutI.NormalWord d)

full_name: Monoid.PushoutI.NormalWord.instFaithfulSMul_2
code: instance : FaithfulSMul H (NormalWord d) 
goal: FaithfulSMul H (Monoid.PushoutI.NormalWord d)

full_name: Monoid.PushoutI.of_injective
code: /-- All maps into the `PushoutI`, or amalgamated product of groups are injective,
provided all maps in the diagram are injective.

See also `base_injective` -/
theorem of_injective (hφ : ∀ i, Function.Injective (φ i)) (i : ι) :
    Function.Injective (of (φ := φ) i) 
goal: Function.Injective ⇑(Monoid.PushoutI.of i)

full_name: Monoid.PushoutI.base_injective
code: theorem base_injective (hφ : ∀ i, Function.Injective (φ i)) :
    Function.Injective (base φ) 
goal: Function.Injective ⇑(Monoid.PushoutI.base φ)

full_name: Monoid.PushoutI.Reduced
code: /-- A word in `CoprodI` is reduced if none of its letters are in the base group. -/
def Reduced (w : Word G) : Prop 
goal: Prop

full_name: Monoid.PushoutI.Reduced.exists_normalWord_prod_eq
code: theorem Reduced.exists_normalWord_prod_eq (d : Transversal φ) {w : Word G} (hw : Reduced φ w) :
    ∃ w' : NormalWord d, w'.prod = ofCoprodI w.prod ∧
      w'.toList.map Sigma.fst = w.toList.map Sigma.fst 
goal: ∃ w', w'.prod = Monoid.PushoutI.ofCoprodI w.prod ∧ List.map Sigma.fst w'.toList = List.map Sigma.fst w.toList

full_name: Monoid.PushoutI.Reduced.eq_empty_of_mem_range
code: /-- For any word `w` in the coproduct,
if `w` is reduced (i.e none its letters are in the image of the base monoid), and nonempty, then
`w` itself is not in the image of the base group. -/
theorem Reduced.eq_empty_of_mem_range (hφ : ∀ i, Injective (φ i))
    {w : Word G} (hw : Reduced φ w)
    (h : ofCoprodI w.prod ∈ (base φ).range) : w = .empty 
goal: w = Monoid.CoprodI.Word.empty

full_name: Monoid.PushoutI.inf_of_range_eq_base_range
code: /-- The intersection of the images of the maps from any two distinct groups in the diagram
into the amalgamated product is the image of the map from the base group in the diagram. -/
theorem inf_of_range_eq_base_range (hφ : ∀ i, Injective (φ i)) {i j : ι} (hij : i ≠ j) :
    (of i).range ⊓ (of j).range = (base φ).range 
goal: (Monoid.PushoutI.of i).range ⊓ (Monoid.PushoutI.of j).range = (Monoid.PushoutI.base φ).range