l3lab/ntp-mathlib huggingface dataset:
/-- 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)
  refine Function.Injective.of_comp
    (f := ((. • .) : PushoutI φ → NormalWord d → NormalWord 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 φ
x✝¹ : DecidableEq ι := Classical.decEq ι
x✝ : (i : ι) → DecidableEq (G i) := fun i => Classical.decEq (G i)
⊢ Injective ((fun x x_1 => x • x_1) ∘ ⇑(of i))

Next tactic:
intros _ _ h
/-- 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)
  refine Function.Injective.of_comp
    (f := ((. • .) : PushoutI φ → NormalWord d → NormalWord d)) ?_
  intros _ _ h
  

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)
a₁✝ a₂✝ : G i
h : ((fun x x_1 => x • x_1) ∘ ⇑(of i)) a₁✝ = ((fun x x_1 => x • x_1) ∘ ⇑(of i)) a₂✝
⊢ a₁✝ = a₂✝

Next tactic:
exact eq_of_smul_eq_smul (fun w : NormalWord d =>
    by simp_all [Function.funext_iff, of_smul_eq_smul])
/-- 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)
  refine Function.Injective.of_comp
    (f := ((. • .) : PushoutI φ → NormalWord d → NormalWord d)) ?_
  intros _ _ h
  exact eq_of_smul_eq_smul (fun w : 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
hφ : ∀ (i : ι), Injective ⇑(φ i)
i : ι
d : Transversal φ
x✝¹ : DecidableEq ι := Classical.decEq ι
x✝ : (i : ι) → DecidableEq (G i) := fun i => Classical.decEq (G i)
a₁✝ a₂✝ : G i
h : ((fun x x_1 => x • x_1) ∘ ⇑(of i)) a₁✝ = ((fun x x_1 => x • x_1) ∘ ⇑(of i)) a₂✝
w : NormalWord d
⊢ a₁✝ • w = a₂✝ • w

Next tactic:
simp_all [Function.funext_iff, of_smul_eq_smul]
theorem base_injective (hφ : ∀ i, Function.Injective (φ i)) :
    Function.Injective (base φ) := 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)
⊢ Injective ⇑(base φ)

Next tactic:
rcases transversal_nonempty φ hφ with ⟨d⟩
theorem base_injective (hφ : ∀ i, Function.Injective (φ i)) :
    Function.Injective (base φ) := 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)
d : Transversal φ
⊢ Injective ⇑(base φ)

Next tactic:
let _ := Classical.decEq ι
theorem base_injective (hφ : ∀ i, Function.Injective (φ i)) :
    Function.Injective (base φ) := 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)
d : Transversal φ
x✝ : DecidableEq ι := Classical.decEq ι
⊢ Injective ⇑(base φ)

Next tactic:
let _ := fun i => Classical.decEq (G i)
theorem base_injective (hφ : ∀ i, Function.Injective (φ i)) :
    Function.Injective (base φ) := 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)
d : Transversal φ
x✝¹ : DecidableEq ι := Classical.decEq ι
x✝ : (i : ι) → DecidableEq (G i) := fun i => Classical.decEq (G i)
⊢ Injective ⇑(base φ)

Next tactic:
refine Function.Injective.of_comp
    (f := ((. • .) : PushoutI φ → NormalWord d → NormalWord d)) ?_
theorem base_injective (hφ : ∀ i, Function.Injective (φ i)) :
    Function.Injective (base φ) := by
  rcases transversal_nonempty φ hφ with ⟨d⟩
  let _ := Classical.decEq ι
  let _ := fun i => Classical.decEq (G i)
  refine Function.Injective.of_comp
    (f := ((. • .) : PushoutI φ → NormalWord d → NormalWord 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)
d : Transversal φ
x✝¹ : DecidableEq ι := Classical.decEq ι
x✝ : (i : ι) → DecidableEq (G i) := fun i => Classical.decEq (G i)
⊢ Injective ((fun x x_1 => x • x_1) ∘ ⇑(base φ))

Next tactic:
intros _ _ h
theorem base_injective (hφ : ∀ i, Function.Injective (φ i)) :
    Function.Injective (base φ) := by
  rcases transversal_nonempty φ hφ with ⟨d⟩
  let _ := Classical.decEq ι
  let _ := fun i => Classical.decEq (G i)
  refine Function.Injective.of_comp
    (f := ((. • .) : PushoutI φ → NormalWord d → NormalWord d)) ?_
  intros _ _ h
  

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)
d : Transversal φ
x✝¹ : DecidableEq ι := Classical.decEq ι
x✝ : (i : ι) → DecidableEq (G i) := fun i => Classical.decEq (G i)
a₁✝ a₂✝ : H
h : ((fun x x_1 => x • x_1) ∘ ⇑(base φ)) a₁✝ = ((fun x x_1 => x • x_1) ∘ ⇑(base φ)) a₂✝
⊢ a₁✝ = a₂✝

Next tactic:
exact eq_of_smul_eq_smul (fun w : NormalWord d =>
    by simp_all [Function.funext_iff, base_smul_eq_smul])
theorem base_injective (hφ : ∀ i, Function.Injective (φ i)) :
    Function.Injective (base φ) := by
  rcases transversal_nonempty φ hφ with ⟨d⟩
  let _ := Classical.decEq ι
  let _ := fun i => Classical.decEq (G i)
  refine Function.Injective.of_comp
    (f := ((. • .) : PushoutI φ → NormalWord d → NormalWord d)) ?_
  intros _ _ h
  exact eq_of_smul_eq_smul (fun w : 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
hφ : ∀ (i : ι), Injective ⇑(φ i)
d : Transversal φ
x✝¹ : DecidableEq ι := Classical.decEq ι
x✝ : (i : ι) → DecidableEq (G i) := fun i => Classical.decEq (G i)
a₁✝ a₂✝ : H
h : ((fun x x_1 => x • x_1) ∘ ⇑(base φ)) a₁✝ = ((fun x x_1 => x • x_1) ∘ ⇑(base φ)) a₂✝
w : NormalWord d
⊢ a₁✝ • w = a₂✝ • w

Next tactic:
simp_all [Function.funext_iff, base_smul_eq_smul]
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 := 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 φ
w : Word G
hw : Reduced φ w
⊢ ∃ w', NormalWord.prod w' = ofCoprodI (Word.prod w) ∧ List.map Sigma.fst w'.toList = List.map Sigma.fst w.toList

Next tactic:
classical
  induction w using Word.consRecOn with
  | h_empty => exact ⟨empty, by simp, rfl⟩
  | h_cons i g w hIdx hg1 ih =>
    rcases ih (fun _ hg => hw _ (List.mem_cons_of_mem _ hg)) with
      ⟨w', hw'prod, hw'map⟩
    refine ⟨cons g w' ?_ ?_, ?_⟩
    · rwa [Word.fstIdx, ← List.head?_map, hw'map, List.head?_map]
    · exact hw _ (List.mem_cons_self _ _)
    · simp [hw'prod, hw'map]
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 := by
  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 φ
w : Word G
hw : Reduced φ w
⊢ ∃ w', NormalWord.prod w' = ofCoprodI (Word.prod w) ∧ List.map Sigma.fst w'.toList = List.map Sigma.fst w.toList

Next tactic:
induction w using Word.consRecOn with
  | h_empty => exact ⟨empty, by simp, rfl⟩
  | h_cons i g w hIdx hg1 ih =>
    rcases ih (fun _ hg => hw _ (List.mem_cons_of_mem _ hg)) with
      ⟨w', hw'prod, hw'map⟩
    refine ⟨cons g w' ?_ ?_, ?_⟩
    · rwa [Word.fstIdx, ← List.head?_map, hw'map, List.head?_map]
    · exact hw _ (List.mem_cons_self _ _)
    · simp [hw'prod, hw'map]
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 := by
  classical
  induction w using Word.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 φ
hw : Reduced φ Word.empty
⊢ ∃ w',
    NormalWord.prod w' = ofCoprodI (Word.prod Word.empty) ∧
      List.map Sigma.fst w'.toList = List.map Sigma.fst Word.empty.toList

Next tactic:
| h_empty => exact ⟨empty, by simp, rfl⟩
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 := by
  classical
  induction w using Word.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 φ
hw : Reduced φ Word.empty
⊢ ∃ w',
    NormalWord.prod w' = ofCoprodI (Word.prod Word.empty) ∧
      List.map Sigma.fst w'.toList = List.map Sigma.fst Word.empty.toList

Next tactic:
exact ⟨empty, by simp, rfl⟩
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 := by
  classical
  induction w using Word.consRecOn with
  | h_empty => exact ⟨empty, 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 φ
hw : Reduced φ Word.empty
⊢ NormalWord.prod empty = ofCoprodI (Word.prod Word.empty)

Next tactic:
simp
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 := by
  classical
  induction w using Word.consRecOn with
  | h_empty => exact ⟨empty, by simp, rfl⟩
  

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 φ
i : ι
g : G i
w : Word G
hIdx : Word.fstIdx w ≠ some i
hg1 : g ≠ 1
ih :
  Reduced φ w →
    ∃ w', NormalWord.prod w' = ofCoprodI (Word.prod w) ∧ List.map Sigma.fst w'.toList = List.map Sigma.fst w.toList
hw : Reduced φ (Word.cons g w hIdx hg1)
⊢ ∃ w',
    NormalWord.prod w' = ofCoprodI (Word.prod (Word.cons g w hIdx hg1)) ∧
      List.map Sigma.fst w'.toList = List.map Sigma.fst (Word.cons g w hIdx hg1).toList

Next tactic:
| h_cons i g w hIdx hg1 ih =>
    rcases ih (fun _ hg => hw _ (List.mem_cons_of_mem _ hg)) with
      ⟨w', hw'prod, hw'map⟩
    refine ⟨cons g w' ?_ ?_, ?_⟩
    · rwa [Word.fstIdx, ← List.head?_map, hw'map, List.head?_map]
    · exact hw _ (List.mem_cons_self _ _)
    · simp [hw'prod, hw'map]
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 := by
  classical
  induction w using Word.consRecOn with
  | h_empty => exact ⟨empty, by simp, rfl⟩
  | h_cons i g w hIdx hg1 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 φ
i : ι
g : G i
w : Word G
hIdx : Word.fstIdx w ≠ some i
hg1 : g ≠ 1
ih :
  Reduced φ w →
    ∃ w', NormalWord.prod w' = ofCoprodI (Word.prod w) ∧ List.map Sigma.fst w'.toList = List.map Sigma.fst w.toList
hw : Reduced φ (Word.cons g w hIdx hg1)
⊢ ∃ w',
    NormalWord.prod w' = ofCoprodI (Word.prod (Word.cons g w hIdx hg1)) ∧
      List.map Sigma.fst w'.toList = List.map Sigma.fst (Word.cons g w hIdx hg1).toList

Next tactic:
rcases ih (fun _ hg => hw _ (List.mem_cons_of_mem _ hg)) with
      ⟨w', hw'prod, hw'map⟩
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 := by
  classical
  induction w using Word.consRecOn with
  | h_empty => exact ⟨empty, by simp, rfl⟩
  | h_cons i g w hIdx hg1 ih =>
    rcases ih (fun _ hg => hw _ (List.mem_cons_of_mem _ hg)) with
      ⟨w', hw'prod, hw'map⟩
    

Proof state:
case h_cons.intro.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
d : Transversal φ
i : ι
g : G i
w : Word G
hIdx : Word.fstIdx w ≠ some i
hg1 : g ≠ 1
ih :
  Reduced φ w →
    ∃ w', NormalWord.prod w' = ofCoprodI (Word.prod w) ∧ List.map Sigma.fst w'.toList = List.map Sigma.fst w.toList
hw : Reduced φ (Word.cons g w hIdx hg1)
w' : NormalWord d
hw'prod : NormalWord.prod w' = ofCoprodI (Word.prod w)
hw'map : List.map Sigma.fst w'.toList = List.map Sigma.fst w.toList
⊢ ∃ w',
    NormalWord.prod w' = ofCoprodI (Word.prod (Word.cons g w hIdx hg1)) ∧
      List.map Sigma.fst w'.toList = List.map Sigma.fst (Word.cons g w hIdx hg1).toList

Next tactic:
refine ⟨cons g w' ?_ ?_, ?_⟩
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 := by
  classical
  induction w using Word.consRecOn with
  | h_empty => exact ⟨empty, by simp, rfl⟩
  | h_cons i g w hIdx hg1 ih =>
    rcases ih (fun _ hg => hw _ (List.mem_cons_of_mem _ hg)) with
      ⟨w', hw'prod, hw'map⟩
    refine ⟨cons g w' ?_ ?_, ?_⟩
    · 

Proof state:
case h_cons.intro.intro.refine_1
ι : 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 φ
i : ι
g : G i
w : Word G
hIdx : Word.fstIdx w ≠ some i
hg1 : g ≠ 1
ih :
  Reduced φ w →
    ∃ w', NormalWord.prod w' = ofCoprodI (Word.prod w) ∧ List.map Sigma.fst w'.toList = List.map Sigma.fst w.toList
hw : Reduced φ (Word.cons g w hIdx hg1)
w' : NormalWord d
hw'prod : NormalWord.prod w' = ofCoprodI (Word.prod w)
hw'map : List.map Sigma.fst w'.toList = List.map Sigma.fst w.toList
⊢ Word.fstIdx w'.toWord ≠ some i

Next tactic:
rwa [Word.fstIdx, ← List.head?_map, hw'map, List.head?_map]
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 := by
  classical
  induction w using Word.consRecOn with
  | h_empty => exact ⟨empty, by simp, rfl⟩
  | h_cons i g w hIdx hg1 ih =>
    rcases ih (fun _ hg => hw _ (List.mem_cons_of_mem _ hg)) with
      ⟨w', hw'prod, hw'map⟩
    refine ⟨cons g w' ?_ ?_, ?_⟩
    · rwa [Word.fstIdx, ← List.head?_map, hw'map, List.head?_map]
    · 

Proof state:
case h_cons.intro.intro.refine_2
ι : 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 φ
i : ι
g : G i
w : Word G
hIdx : Word.fstIdx w ≠ some i
hg1 : g ≠ 1
ih :
  Reduced φ w →
    ∃ w', NormalWord.prod w' = ofCoprodI (Word.prod w) ∧ List.map Sigma.fst w'.toList = List.map Sigma.fst w.toList
hw : Reduced φ (Word.cons g w hIdx hg1)
w' : NormalWord d
hw'prod : NormalWord.prod w' = ofCoprodI (Word.prod w)
hw'map : List.map Sigma.fst w'.toList = List.map Sigma.fst w.toList
⊢ g ∉ MonoidHom.range (φ i)

Next tactic:
exact hw _ (List.mem_cons_self _ _)
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 := by
  classical
  induction w using Word.consRecOn with
  | h_empty => exact ⟨empty, by simp, rfl⟩
  | h_cons i g w hIdx hg1 ih =>
    rcases ih (fun _ hg => hw _ (List.mem_cons_of_mem _ hg)) with
      ⟨w', hw'prod, hw'map⟩
    refine ⟨cons g w' ?_ ?_, ?_⟩
    · rwa [Word.fstIdx, ← List.head?_map, hw'map, List.head?_map]
    · exact hw _ (List.mem_cons_self _ _)
    · 

Proof state:
case h_cons.intro.intro.refine_3
ι : 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 φ
i : ι
g : G i
w : Word G
hIdx : Word.fstIdx w ≠ some i
hg1 : g ≠ 1
ih :
  Reduced φ w →
    ∃ w', NormalWord.prod w' = ofCoprodI (Word.prod w) ∧ List.map Sigma.fst w'.toList = List.map Sigma.fst w.toList
hw : Reduced φ (Word.cons g w hIdx hg1)
w' : NormalWord d
hw'prod : NormalWord.prod w' = ofCoprodI (Word.prod w)
hw'map : List.map Sigma.fst w'.toList = List.map Sigma.fst w.toList
⊢ NormalWord.prod
        (NormalWord.cons g w' (_ : Word.fstIdx w'.toWord ≠ some i)
          (_ : { fst := i, snd := g }.snd ∉ MonoidHom.range (φ { fst := i, snd := g }.fst))) =
      ofCoprodI (Word.prod (Word.cons g w hIdx hg1)) ∧
    List.map Sigma.fst
        (NormalWord.cons g w' (_ : Word.fstIdx w'.toWord ≠ some i)
              (_ : { fst := i, snd := g }.snd ∉ MonoidHom.range (φ { fst := i, snd := g }.fst))).toWord.toList =
      List.map Sigma.fst (Word.cons g w hIdx hg1).toList

Next tactic:
simp [hw'prod, hw'map]
/-- 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 := 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)
w : Word G
hw : Reduced φ w
h : ofCoprodI (Word.prod w) ∈ MonoidHom.range (base φ)
⊢ w = Word.empty

Next tactic:
rcases transversal_nonempty φ hφ with ⟨d⟩
/-- 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 := 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)
w : Word G
hw : Reduced φ w
h : ofCoprodI (Word.prod w) ∈ MonoidHom.range (base φ)
d : Transversal φ
⊢ w = Word.empty

Next tactic:
rcases hw.exists_normalWord_prod_eq d with ⟨w', hw'prod, hw'map⟩
/-- 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 := by
  rcases transversal_nonempty φ hφ with ⟨d⟩
  rcases hw.exists_normalWord_prod_eq d with ⟨w', hw'prod, hw'map⟩
  

Proof state:
case intro.intro.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)
w : Word G
hw : Reduced φ w
h : ofCoprodI (Word.prod w) ∈ MonoidHom.range (base φ)
d : Transversal φ
w' : NormalWord d
hw'prod : NormalWord.prod w' = ofCoprodI (Word.prod w)
hw'map : List.map Sigma.fst w'.toList = List.map Sigma.fst w.toList
⊢ w = Word.empty

Next tactic:
rcases h with ⟨h, heq⟩
/-- 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 := by
  rcases transversal_nonempty φ hφ with ⟨d⟩
  rcases hw.exists_normalWord_prod_eq d with ⟨w', hw'prod, hw'map⟩
  rcases h with ⟨h, heq⟩
  

Proof state:
case intro.intro.intro.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)
w : Word G
hw : Reduced φ w
d : Transversal φ
w' : NormalWord d
hw'prod : NormalWord.prod w' = ofCoprodI (Word.prod w)
hw'map : List.map Sigma.fst w'.toList = List.map Sigma.fst w.toList
h : H
heq : (base φ) h = ofCoprodI (Word.prod w)
⊢ w = Word.empty

Next tactic:
have : (NormalWord.prod (d := d) ⟨.empty, h, by simp⟩) = base φ h := by
    simp [NormalWord.prod]
/-- 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 := by
  rcases transversal_nonempty φ hφ with ⟨d⟩
  rcases hw.exists_normalWord_prod_eq d with ⟨w', hw'prod, hw'map⟩
  rcases h with ⟨h, heq⟩
  have : (NormalWord.prod (d := d) ⟨.empty, 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
hφ : ∀ (i : ι), Injective ⇑(φ i)
w : Word G
hw : Reduced φ w
d : Transversal φ
w' : NormalWord d
hw'prod : NormalWord.prod w' = ofCoprodI (Word.prod w)
hw'map : List.map Sigma.fst w'.toList = List.map Sigma.fst w.toList
h : H
heq : (base φ) h = ofCoprodI (Word.prod w)
⊢ ∀ (i : ι) (g : G i), { fst := i, snd := g } ∈ Word.empty.toList → g ∈ Transversal.set d i

Next tactic:
simp