l3lab/ntp-mathlib huggingface dataset:
/-- 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 := by
  rcases w with ⟨w, head, h3⟩
  convert h_base head ⟨w, 1, h3⟩ rfl ?_
  · simp [base_smul_def]
  · induction w using Word.consRecOn with
    | h_empty => exact h_empty
    | h_cons i g w h1 hg1 ih =>
      convert h_cons i g ⟨w, 1, fun _ _ h => h3 _ _ (List.mem_cons_of_mem _ h)⟩
        h1 (h3 _ _ (List.mem_cons_self _ _)) ?_ rfl
        (ih ?_)
      · ext
        simp only [Word.cons, Option.mem_def, cons, map_one, mul_one,
          (equiv_snd_eq_self_iff_mem (d.compl i) (one_mem _)).2
          (h3 _ _ (List.mem_cons_self _ _))]
      · apply d.injective i
        

Proof state:
case h.e'_1.h.e'_9.a
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝⁴ : Monoid K
inst✝³ : (i : ι) → Group (G i)
inst✝² : Group H
φ : (i : ι) → H →* G i
d : Transversal φ
inst✝¹ : DecidableEq ι
inst✝ : (i : ι) → DecidableEq (G i)
motive : NormalWord d → Sort ?u.1720143
h_empty : motive empty
h_cons :
  (i : ι) →
    (g : G i) →
      (w : NormalWord d) →
        (hmw : Word.fstIdx w.toWord ≠ some i) →
          g ∈ Transversal.set d i →
            (hgr : g ∉ MonoidHom.range (φ i)) → 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)
head : H
i : ι
g : G i
w : Word fun i => G i
h1 : Word.fstIdx w ≠ some i
hg1 : g ≠ 1
ih :
  (h3 : ∀ (i : ι) (g : G i), { fst := i, snd := g } ∈ w.toList → g ∈ Transversal.set d i) →
    motive { toWord := w, head := 1, normalized := h3 }
h3 : ∀ (i_1 : ι) (g_1 : G i_1), { fst := i_1, snd := g_1 } ∈ (Word.cons g w h1 hg1).toList → g_1 ∈ Transversal.set d i_1
⊢ (φ i) 1 =
    (φ i)
      (cons g
          { toWord := w, head := 1,
            normalized := (_ : ∀ (x : ι) (x_1 : G x), { fst := x, snd := x_1 } ∈ w.toList → x_1 ∈ Transversal.set d x) }
          h1 ?mk.h_cons).head

Next tactic:
simp only [cons, equiv_fst_eq_mul_inv, MonoidHom.apply_ofInjective_symm,
          map_one, mul_one, mul_right_inv, (equiv_snd_eq_self_iff_mem (d.compl i) (one_mem _)).2
          (h3 _ _ (List.mem_cons_self _ _))]
/-- 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 := by
  rcases w with ⟨w, head, h3⟩
  convert h_base head ⟨w, 1, h3⟩ rfl ?_
  · simp [base_smul_def]
  · induction w using Word.consRecOn with
    | h_empty => exact h_empty
    | h_cons i g w h1 hg1 ih =>
      convert h_cons i g ⟨w, 1, fun _ _ h => h3 _ _ (List.mem_cons_of_mem _ h)⟩
        h1 (h3 _ _ (List.mem_cons_self _ _)) ?_ rfl
        (ih ?_)
      · ext
        simp only [Word.cons, Option.mem_def, cons, map_one, mul_one,
          (equiv_snd_eq_self_iff_mem (d.compl i) (one_mem _)).2
          (h3 _ _ (List.mem_cons_self _ _))]
      · apply d.injective i
        simp only [cons, equiv_fst_eq_mul_inv, MonoidHom.apply_ofInjective_symm,
          map_one, mul_one, mul_right_inv, (equiv_snd_eq_self_iff_mem (d.compl i) (one_mem _)).2
          (h3 _ _ (List.mem_cons_self _ _))]
      · 

Proof state:
case mk.h_cons
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝⁴ : Monoid K
inst✝³ : (i : ι) → Group (G i)
inst✝² : Group H
φ : (i : ι) → H →* G i
d : Transversal φ
inst✝¹ : DecidableEq ι
inst✝ : (i : ι) → DecidableEq (G i)
motive : NormalWord d → Sort ?u.1720143
h_empty : motive empty
h_cons :
  (i : ι) →
    (g : G i) →
      (w : NormalWord d) →
        (hmw : Word.fstIdx w.toWord ≠ some i) →
          g ∈ Transversal.set d i →
            (hgr : g ∉ MonoidHom.range (φ i)) → 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)
head : H
i : ι
g : G i
w : Word fun i => G i
h1 : Word.fstIdx w ≠ some i
hg1 : g ≠ 1
ih :
  (h3 : ∀ (i : ι) (g : G i), { fst := i, snd := g } ∈ w.toList → g ∈ Transversal.set d i) →
    motive { toWord := w, head := 1, normalized := h3 }
h3 : ∀ (i_1 : ι) (g_1 : G i_1), { fst := i_1, snd := g_1 } ∈ (Word.cons g w h1 hg1).toList → g_1 ∈ Transversal.set d i_1
⊢ g ∉ MonoidHom.range (φ i)

Next tactic:
rwa [← SetLike.mem_coe,
          ← coe_equiv_snd_eq_one_iff_mem (d.compl i) (d.one_mem _),
          (equiv_snd_eq_self_iff_mem (d.compl i) (one_mem _)).2
          (h3 _ _ (List.mem_cons_self _ _))]
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 := by
  

Proof state:
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝⁴ : Monoid K
inst✝³ : (i : ι) → Group (G i)
inst✝² : Group H
φ : (i : ι) → H →* G i
d : Transversal φ
inst✝¹ : DecidableEq ι
inst✝ : (i : ι) → DecidableEq (G i)
i : ι
g : G i
w : NormalWord d
hmw : Word.fstIdx w.toWord ≠ some i
hgr : g ∉ MonoidHom.range (φ i)
⊢ cons g w hmw hgr = (of i) g • w

Next tactic:
apply ext_smul i
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 := by
  apply ext_smul i
  

Proof state:
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝⁴ : Monoid K
inst✝³ : (i : ι) → Group (G i)
inst✝² : Group H
φ : (i : ι) → H →* G i
d : Transversal φ
inst✝¹ : DecidableEq ι
inst✝ : (i : ι) → DecidableEq (G i)
i : ι
g : G i
w : NormalWord d
hmw : Word.fstIdx w.toWord ≠ some i
hgr : g ∉ MonoidHom.range (φ i)
⊢ CoprodI.of ((φ i) (cons g w hmw hgr).head) • (cons g w hmw hgr).toWord =
    CoprodI.of ((φ i) ((of i) g • w).head) • ((of i) g • w).toWord

Next tactic:
simp only [cons, ne_eq, Word.cons_eq_smul, MonoidHom.apply_ofInjective_symm,
    equiv_fst_eq_mul_inv, mul_assoc, map_mul, map_inv, mul_smul, inv_smul_smul, summand_smul_def,
    equivPair, rcons, Word.equivPair_symm, Word.rcons_eq_smul, Equiv.coe_fn_mk,
    Word.equivPair_tail_eq_inv_smul, Equiv.coe_fn_symm_mk, smul_inv_smul]
@[simp]
theorem prod_summand_smul {i : ι} (g : G i) (w : NormalWord d) :
    (g • w).prod = of i g * w.prod := by
  

Proof state:
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝⁴ : Monoid K
inst✝³ : (i : ι) → Group (G i)
inst✝² : Group H
φ : (i : ι) → H →* G i
d : Transversal φ
inst✝¹ : DecidableEq ι
inst✝ : (i : ι) → DecidableEq (G i)
i : ι
g : G i
w : NormalWord d
⊢ prod (g • w) = (of i) g * prod w

Next tactic:
simp only [prod, summand_smul_def', equivPair, rcons, Word.equivPair_symm,
    Equiv.coe_fn_mk, Equiv.coe_fn_symm_mk, Word.equivPair_smul_same,
    Word.equivPair_tail_eq_inv_smul, Word.rcons_eq_smul, ← of_apply_eq_base φ i,
    MonoidHom.apply_ofInjective_symm, equiv_fst_eq_mul_inv, mul_assoc, map_mul, map_inv,
    Word.prod_smul, ofCoprodI_of, inv_mul_cancel_left, mul_inv_cancel_left]
@[simp]
theorem prod_base_smul (h : H) (w : NormalWord d) :
    (h • w).prod = base φ h * w.prod := by
  

Proof state:
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝⁴ : Monoid K
inst✝³ : (i : ι) → Group (G i)
inst✝² : Group H
φ : (i : ι) → H →* G i
d : Transversal φ
inst✝¹ : DecidableEq ι
inst✝ : (i : ι) → DecidableEq (G i)
h : H
w : NormalWord d
⊢ prod (h • w) = (base φ) h * prod w

Next tactic:
simp only [base_smul_def', prod, map_mul, mul_assoc]
@[simp]
theorem prod_smul (g : PushoutI φ) (w : NormalWord d) :
    (g • w).prod = g * w.prod := by
  

Proof state:
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝⁴ : Monoid K
inst✝³ : (i : ι) → Group (G i)
inst✝² : Group H
φ : (i : ι) → H →* G i
d : Transversal φ
inst✝¹ : DecidableEq ι
inst✝ : (i : ι) → DecidableEq (G i)
g : PushoutI φ
w : NormalWord d
⊢ prod (g • w) = g * prod w

Next tactic:
induction g using PushoutI.induction_on generalizing w with
  | of i g => rw [of_smul_eq_smul, prod_summand_smul]
  | base h => rw [base_smul_eq_smul, prod_base_smul]
  | mul x y ihx ihy => rw [mul_smul, ihx, ihy, mul_assoc]
@[simp]
theorem prod_smul (g : PushoutI φ) (w : NormalWord d) :
    (g • w).prod = g * w.prod := by
  induction g using PushoutI.induction_on generalizing w with
  

Proof state:
case of
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝⁴ : Monoid K
inst✝³ : (i : ι) → Group (G i)
inst✝² : Group H
φ : (i : ι) → H →* G i
d : Transversal φ
inst✝¹ : DecidableEq ι
inst✝ : (i : ι) → DecidableEq (G i)
i : ι
g : G i
w : NormalWord d
⊢ prod ((of i) g • w) = (of i) g * prod w

Next tactic:
| of i g => rw [of_smul_eq_smul, prod_summand_smul]
@[simp]
theorem prod_smul (g : PushoutI φ) (w : NormalWord d) :
    (g • w).prod = g * w.prod := by
  induction g using PushoutI.induction_on generalizing w with
  | of i g => 

Proof state:
case of
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝⁴ : Monoid K
inst✝³ : (i : ι) → Group (G i)
inst✝² : Group H
φ : (i : ι) → H →* G i
d : Transversal φ
inst✝¹ : DecidableEq ι
inst✝ : (i : ι) → DecidableEq (G i)
i : ι
g : G i
w : NormalWord d
⊢ prod ((of i) g • w) = (of i) g * prod w

Next tactic:
rw [of_smul_eq_smul, prod_summand_smul]
@[simp]
theorem prod_smul (g : PushoutI φ) (w : NormalWord d) :
    (g • w).prod = g * w.prod := by
  induction g using PushoutI.induction_on generalizing w with
  | of i g => rw [of_smul_eq_smul, prod_summand_smul]
  

Proof state:
case base
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝⁴ : Monoid K
inst✝³ : (i : ι) → Group (G i)
inst✝² : Group H
φ : (i : ι) → H →* G i
d : Transversal φ
inst✝¹ : DecidableEq ι
inst✝ : (i : ι) → DecidableEq (G i)
h : H
w : NormalWord d
⊢ prod ((base φ) h • w) = (base φ) h * prod w

Next tactic:
| base h => rw [base_smul_eq_smul, prod_base_smul]
@[simp]
theorem prod_smul (g : PushoutI φ) (w : NormalWord d) :
    (g • w).prod = g * w.prod := by
  induction g using PushoutI.induction_on generalizing w with
  | of i g => rw [of_smul_eq_smul, prod_summand_smul]
  | base h => 

Proof state:
case base
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝⁴ : Monoid K
inst✝³ : (i : ι) → Group (G i)
inst✝² : Group H
φ : (i : ι) → H →* G i
d : Transversal φ
inst✝¹ : DecidableEq ι
inst✝ : (i : ι) → DecidableEq (G i)
h : H
w : NormalWord d
⊢ prod ((base φ) h • w) = (base φ) h * prod w

Next tactic:
rw [base_smul_eq_smul, prod_base_smul]
@[simp]
theorem prod_smul (g : PushoutI φ) (w : NormalWord d) :
    (g • w).prod = g * w.prod := by
  induction g using PushoutI.induction_on generalizing w with
  | of i g => rw [of_smul_eq_smul, prod_summand_smul]
  | base h => rw [base_smul_eq_smul, prod_base_smul]
  

Proof state:
case mul
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝⁴ : Monoid K
inst✝³ : (i : ι) → Group (G i)
inst✝² : Group H
φ : (i : ι) → H →* G i
d : Transversal φ
inst✝¹ : DecidableEq ι
inst✝ : (i : ι) → DecidableEq (G i)
x y : PushoutI φ
ihx : ∀ (w : NormalWord d), prod (x • w) = x * prod w
ihy : ∀ (w : NormalWord d), prod (y • w) = y * prod w
w : NormalWord d
⊢ prod ((x * y) • w) = x * y * prod w

Next tactic:
| mul x y ihx ihy => rw [mul_smul, ihx, ihy, mul_assoc]
@[simp]
theorem prod_smul (g : PushoutI φ) (w : NormalWord d) :
    (g • w).prod = g * w.prod := by
  induction g using PushoutI.induction_on generalizing w with
  | of i g => rw [of_smul_eq_smul, prod_summand_smul]
  | base h => rw [base_smul_eq_smul, prod_base_smul]
  | mul x y ihx ihy => 

Proof state:
case mul
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝⁴ : Monoid K
inst✝³ : (i : ι) → Group (G i)
inst✝² : Group H
φ : (i : ι) → H →* G i
d : Transversal φ
inst✝¹ : DecidableEq ι
inst✝ : (i : ι) → DecidableEq (G i)
x y : PushoutI φ
ihx : ∀ (w : NormalWord d), prod (x • w) = x * prod w
ihy : ∀ (w : NormalWord d), prod (y • w) = y * prod w
w : NormalWord d
⊢ prod ((x * y) • w) = x * y * prod w

Next tactic:
rw [mul_smul, ihx, ihy, mul_assoc]
@[simp]
theorem prod_empty : (empty : NormalWord d).prod = 1 := by
  

Proof state:
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝⁴ : Monoid K
inst✝³ : (i : ι) → Group (G i)
inst✝² : Group H
φ : (i : ι) → H →* G i
d : Transversal φ
inst✝¹ : DecidableEq ι
inst✝ : (i : ι) → DecidableEq (G i)
⊢ prod empty = 1

Next tactic:
simp [prod, empty]
@[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 := by
  

Proof state:
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝⁴ : Monoid K
inst✝³ : (i : ι) → Group (G i)
inst✝² : Group H
φ : (i : ι) → H →* G i
d : Transversal φ
inst✝¹ : DecidableEq ι
inst✝ : (i : ι) → DecidableEq (G i)
i : ι
g : G i
w : NormalWord d
hmw : Word.fstIdx w.toWord ≠ some i
hgr : g ∉ MonoidHom.range (φ i)
⊢ prod (cons g w hmw hgr) = (of i) g * prod w

Next tactic:
simp only [prod, cons, Word.prod, List.map, ← of_apply_eq_base φ i, equiv_fst_eq_mul_inv,
    mul_assoc, MonoidHom.apply_ofInjective_symm, List.prod_cons, map_mul, map_inv,
    ofCoprodI_of, inv_mul_cancel_left]
theorem prod_smul_empty (w : NormalWord d) : w.prod • empty = w := by
  

Proof state:
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝⁴ : Monoid K
inst✝³ : (i : ι) → Group (G i)
inst✝² : Group H
φ : (i : ι) → H →* G i
d : Transversal φ
inst✝¹ : DecidableEq ι
inst✝ : (i : ι) → DecidableEq (G i)
w : NormalWord d
⊢ prod w • empty = w

Next tactic:
induction w using consRecOn with
  | h_empty => simp
  | h_cons i g w _ _ _ _ ih =>
    rw [prod_cons, mul_smul, ih, cons_eq_smul]
  | h_base h w _ ih =>
    rw [prod_smul, mul_smul, ih]
theorem prod_smul_empty (w : NormalWord d) : w.prod • empty = w := by
  induction w using consRecOn with
  

Proof state:
case h_empty
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝⁴ : Monoid K
inst✝³ : (i : ι) → Group (G i)
inst✝² : Group H
φ : (i : ι) → H →* G i
d : Transversal φ
inst✝¹ : DecidableEq ι
inst✝ : (i : ι) → DecidableEq (G i)
⊢ prod empty • empty = empty

Next tactic:
| h_empty => simp
theorem prod_smul_empty (w : NormalWord d) : w.prod • empty = w := by
  induction w using consRecOn with
  | h_empty => 

Proof state:
case h_empty
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝⁴ : Monoid K
inst✝³ : (i : ι) → Group (G i)
inst✝² : Group H
φ : (i : ι) → H →* G i
d : Transversal φ
inst✝¹ : DecidableEq ι
inst✝ : (i : ι) → DecidableEq (G i)
⊢ prod empty • empty = empty

Next tactic:
simp
theorem prod_smul_empty (w : NormalWord d) : w.prod • empty = w := by
  induction w using consRecOn with
  | h_empty => simp
  

Proof state:
case h_cons
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝⁴ : Monoid K
inst✝³ : (i : ι) → Group (G i)
inst✝² : Group H
φ : (i : ι) → H →* G i
d : Transversal φ
inst✝¹ : DecidableEq ι
inst✝ : (i : ι) → DecidableEq (G i)
i : ι
g : G i
w : NormalWord d
hmw✝ : Word.fstIdx w.toWord ≠ some i
_hgn✝ : g ∈ Transversal.set d i
hgr✝ : g ∉ MonoidHom.range (φ i)
_hw1✝ : w.head = 1
ih : prod w • empty = w
⊢ prod (cons g w hmw✝ hgr✝) • empty = cons g w hmw✝ hgr✝

Next tactic:
| h_cons i g w _ _ _ _ ih =>
    rw [prod_cons, mul_smul, ih, cons_eq_smul]
theorem prod_smul_empty (w : NormalWord d) : w.prod • empty = w := by
  induction w using consRecOn with
  | h_empty => simp
  | h_cons i g w _ _ _ _ ih =>
    

Proof state:
case h_cons
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝⁴ : Monoid K
inst✝³ : (i : ι) → Group (G i)
inst✝² : Group H
φ : (i : ι) → H →* G i
d : Transversal φ
inst✝¹ : DecidableEq ι
inst✝ : (i : ι) → DecidableEq (G i)
i : ι
g : G i
w : NormalWord d
hmw✝ : Word.fstIdx w.toWord ≠ some i
_hgn✝ : g ∈ Transversal.set d i
hgr✝ : g ∉ MonoidHom.range (φ i)
_hw1✝ : w.head = 1
ih : prod w • empty = w
⊢ prod (cons g w hmw✝ hgr✝) • empty = cons g w hmw✝ hgr✝

Next tactic:
rw [prod_cons, mul_smul, ih, cons_eq_smul]
theorem prod_smul_empty (w : NormalWord d) : w.prod • empty = w := by
  induction w using consRecOn with
  | h_empty => simp
  | h_cons i g w _ _ _ _ ih =>
    rw [prod_cons, mul_smul, ih, cons_eq_smul]
  

Proof state:
case h_base
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝⁴ : Monoid K
inst✝³ : (i : ι) → Group (G i)
inst✝² : Group H
φ : (i : ι) → H →* G i
d : Transversal φ
inst✝¹ : DecidableEq ι
inst✝ : (i : ι) → DecidableEq (G i)
h : H
w : NormalWord d
a✝ : w.head = 1
ih : prod w • empty = w
⊢ prod ((base φ) h • w) • empty = (base φ) h • w

Next tactic:
| h_base h w _ ih =>
    rw [prod_smul, mul_smul, ih]
theorem prod_smul_empty (w : NormalWord d) : w.prod • empty = w := by
  induction w using consRecOn with
  | h_empty => simp
  | h_cons i g w _ _ _ _ ih =>
    rw [prod_cons, mul_smul, ih, cons_eq_smul]
  | h_base h w _ ih =>
    

Proof state:
case h_base
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝⁴ : Monoid K
inst✝³ : (i : ι) → Group (G i)
inst✝² : Group H
φ : (i : ι) → H →* G i
d : Transversal φ
inst✝¹ : DecidableEq ι
inst✝ : (i : ι) → DecidableEq (G i)
h : H
w : NormalWord d
a✝ : w.head = 1
ih : prod w • empty = w
⊢ prod ((base φ) h • w) • empty = (base φ) h • w

Next tactic:
rw [prod_smul, mul_smul, ih]
/-- The equivalence between normal forms and elements of the pushout -/
noncomputable def equiv : PushoutI φ ≃ NormalWord d :=
  { toFun := fun g => g • .empty
    invFun := fun w => w.prod
    left_inv := fun g => by
      

Proof state:
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝⁴ : Monoid K
inst✝³ : (i : ι) → Group (G i)
inst✝² : Group H
φ : (i : ι) → H →* G i
d : Transversal φ
inst✝¹ : DecidableEq ι
inst✝ : (i : ι) → DecidableEq (G i)
g : PushoutI φ
⊢ (fun w => prod w) ((fun g => g • empty) g) = g

Next tactic:
simp only [prod_smul, prod_empty, mul_one]
theorem prod_injective : Function.Injective (prod : NormalWord d → PushoutI φ) := by
  

Proof state:
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝⁴ : Monoid K
inst✝³ : (i : ι) → Group (G i)
inst✝² : Group H
φ : (i : ι) → H →* G i
d : Transversal φ
inst✝¹ : DecidableEq ι
inst✝ : (i : ι) → DecidableEq (G i)
⊢ Injective prod

Next tactic:
letI := Classical.decEq ι
theorem prod_injective : Function.Injective (prod : NormalWord d → PushoutI φ) := by
  letI := Classical.decEq ι
  

Proof state:
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝⁴ : Monoid K
inst✝³ : (i : ι) → Group (G i)
inst✝² : Group H
φ : (i : ι) → H →* G i
d : Transversal φ
inst✝¹ : DecidableEq ι
inst✝ : (i : ι) → DecidableEq (G i)
this : DecidableEq ι := Classical.decEq ι
⊢ Injective prod

Next tactic:
letI := fun i => Classical.decEq (G i)
theorem prod_injective : Function.Injective (prod : NormalWord d → PushoutI φ) := by
  letI := Classical.decEq ι
  letI := fun i => Classical.decEq (G i)
  

Proof state:
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝⁴ : Monoid K
inst✝³ : (i : ι) → Group (G i)
inst✝² : Group H
φ : (i : ι) → H →* G i
d : Transversal φ
inst✝¹ : DecidableEq ι
inst✝ : (i : ι) → DecidableEq (G i)
this✝ : DecidableEq ι := Classical.decEq ι
this : (i : ι) → DecidableEq (G i) := fun i => Classical.decEq (G i)
⊢ Injective prod

Next tactic:
classical exact equiv.symm.injective
theorem prod_injective : Function.Injective (prod : NormalWord d → PushoutI φ) := by
  letI := Classical.decEq ι
  letI := fun i => Classical.decEq (G i)
  classical 

Proof state:
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝⁴ : Monoid K
inst✝³ : (i : ι) → Group (G i)
inst✝² : Group H
φ : (i : ι) → H →* G i
d : Transversal φ
inst✝¹ : DecidableEq ι
inst✝ : (i : ι) → DecidableEq (G i)
this✝ : DecidableEq ι := Classical.decEq ι
this : (i : ι) → DecidableEq (G i) := fun i => Classical.decEq (G i)
⊢ Injective prod

Next tactic:
exact equiv.symm.injective
instance : FaithfulSMul (PushoutI φ) (NormalWord d) :=
  ⟨fun h => by 

Proof state:
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝⁴ : Monoid K
inst✝³ : (i : ι) → Group (G i)
inst✝² : Group H
φ : (i : ι) → H →* G i
d : Transversal φ
inst✝¹ : DecidableEq ι
inst✝ : (i : ι) → DecidableEq (G i)
m₁✝ m₂✝ : PushoutI φ
h : ∀ (a : NormalWord d), m₁✝ • a = m₂✝ • a
⊢ m₁✝ = m₂✝

Next tactic:
simpa using congr_arg prod (h empty)
instance (i : ι) : FaithfulSMul (G i) (NormalWord d) :=
  ⟨by 

Proof state:
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝⁴ : Monoid K
inst✝³ : (i : ι) → Group (G i)
inst✝² : Group H
φ : (i : ι) → H →* G i
d : Transversal φ
inst✝¹ : DecidableEq ι
inst✝ : (i : ι) → DecidableEq (G i)
i : ι
⊢ ∀ {m₁ m₂ : G i}, (∀ (a : NormalWord d), m₁ • a = m₂ • a) → m₁ = m₂

Next tactic:
simp [summand_smul_def']
instance : FaithfulSMul H (NormalWord d) :=
  ⟨by 

Proof state:
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝⁴ : Monoid K
inst✝³ : (i : ι) → Group (G i)
inst✝² : Group H
φ : (i : ι) → H →* G i
d : Transversal φ
inst✝¹ : DecidableEq ι
inst✝ : (i : ι) → DecidableEq (G i)
⊢ ∀ {m₁ m₂ : H}, (∀ (a : NormalWord d), m₁ • a = m₂ • a) → m₁ = m₂

Next tactic:
simp [base_smul_def']
/-- 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) := by
  

Proof state:
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝² : Monoid K
inst✝¹ : (i : ι) → Group (G i)
inst✝ : Group H
φ : (i : ι) → H →* G i
hφ : ∀ (i : ι), Injective ⇑(φ i)
i : ι
⊢ Injective ⇑(of i)

Next tactic:
rcases transversal_nonempty φ hφ with ⟨d⟩
/-- 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) := by
  rcases transversal_nonempty φ hφ with ⟨d⟩
  

Proof state:
case intro
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝² : Monoid K
inst✝¹ : (i : ι) → Group (G i)
inst✝ : Group H
φ : (i : ι) → H →* G i
hφ : ∀ (i : ι), Injective ⇑(φ i)
i : ι
d : Transversal φ
⊢ Injective ⇑(of i)

Next tactic:
let _ := Classical.decEq ι
/-- 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) := by
  rcases transversal_nonempty φ hφ with ⟨d⟩
  let _ := Classical.decEq ι
  

Proof state:
case intro
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝² : Monoid K
inst✝¹ : (i : ι) → Group (G i)
inst✝ : Group H
φ : (i : ι) → H →* G i
hφ : ∀ (i : ι), Injective ⇑(φ i)
i : ι
d : Transversal φ
x✝ : DecidableEq ι := Classical.decEq ι
⊢ Injective ⇑(of i)

Next tactic:
let _ := fun i => Classical.decEq (G i)
/-- 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) := by
  rcases transversal_nonempty φ hφ with ⟨d⟩
  let _ := Classical.decEq ι
  let _ := fun i => Classical.decEq (G i)
  

Proof state:
case intro
ι : Type u_1
G : ι → Type u_2
H : Type u_3
K : Type u_4
inst✝² : Monoid K
inst✝¹ : (i : ι) → Group (G i)
inst✝ : Group H
φ : (i : ι) → H →* G i
hφ : ∀ (i : ι), Injective ⇑(φ i)
i : ι
d : Transversal φ
x✝¹ : DecidableEq ι := Classical.decEq ι
x✝ : (i : ι) → DecidableEq (G i) := fun i => Classical.decEq (G i)
⊢ Injective ⇑(of i)

Next tactic:
refine Function.Injective.of_comp
    (f := ((. • .) : PushoutI φ → NormalWord d → NormalWord d)) ?_