ProCGroups.ReidemeisterSchreier.Discrete.OpenSubgroups.PrefixTree

10 Theorems | 5 Lemmas | 3 Definitions | 1 Instance

This module constructs the Schreier prefix tree from a right transversal, proves its positive and negative edge criteria, and relates its complement edges to the nontrivial Schreier generators.

imports
Imported by

Declarations

theorem prefixParentEdge_mem_transversal {X : Type u} [DecidableEq X]
    {L : Subgroup (FreeGroup X)} {T : Set (FreeGroup X)}
    (hT : IsRightSchreierTransversal (X := X) L T)
    (t : T) (ht1 : (t : FreeGroup X) ≠ 1) :
    (FreeGroup.prefixParentEdgeOfNeOne (X := X) (t := (t : FreeGroup X)) ht1).parent ∈ T

The parent vertex of a nontrivial prefix-parent edge of a Schreier transversal again lies in the transversal.

Show Lean proof
theorem exists_inverseBasis_edge_of_ne_one {X : Type u} [DecidableEq X]
    {L : Subgroup (FreeGroup X)} {T : Set (FreeGroup X)}
    (hT : IsRightSchreierTransversal (X := X) L T)
    (t : T) (ht1 : (t : FreeGroup X) ≠ 1) :
    ∃ x : X,
      letI := schreierTransversalRightCosetAction (X := X) hT
      (FreeGroup.inverseBasis X x •
          (⟨FreeGroup.prefixParent (t : FreeGroup X),
            prefixParent_mem_of_mem (X := X) hT t.property⟩ : T) = t) ∨
      (FreeGroup.inverseBasis X x • t =
          (⟨FreeGroup.prefixParent (t : FreeGroup X),
            prefixParent_mem_of_mem (X := X) hT t.property⟩ : T))

Every nonidentity transversal representative is reached from its prefix parent by an inverse-basis edge.

Show Lean proof
noncomputable def schreierPrefixTree {X : Type u} [DecidableEq X]
    {L : Subgroup (FreeGroup X)} {T : Set (FreeGroup X)}
    (hT : IsRightSchreierTransversal (X := X) L T) :
    letI := schreierTransversalRightCosetAction (X := X) hT
    letI : IsFreeGroupoid (ActionCategory (FreeGroup X) T) :=
      FreeGroupBasis.actionGroupoidIsFree (FreeGroup.inverseBasis X)
    WideSubquiver
      (Quiver.Symmetrify <| IsFreeGroupoid.Generators (ActionCategory (FreeGroup X) T)) := by
  letI := schreierTransversalRightCosetAction (X := X) hT
  letI : IsFreeGroupoid (ActionCategory (FreeGroup X) T) :=
    FreeGroupBasis.actionGroupoidIsFree (FreeGroup.inverseBasis X)
  exact fun a b =>
    { e |
        ∃ hw : FreeGroup.toWord (((show ActionCategory (FreeGroup X) T from b).back : T) :
            FreeGroup X) ≠ [],
          let tb : T := (show ActionCategory (FreeGroup X) T from b).back
          let pb : T := ⟨FreeGroup.prefixParent (tb : FreeGroup X),
            prefixParent_mem_of_mem (X := X) hT tb.property⟩
          (show ActionCategory (FreeGroup X) T from a).back = pb ∧
            match e with
            | Sum.inl g => (FreeGroup.toWord (tb : FreeGroup X)).getLast hw = (g.1, true)
            | Sum.inr g => (FreeGroup.toWord (tb : FreeGroup X)).getLast hw = (g.1, false) }

The canonical prefix tree on the Schreier transversal. Its unique incoming edge for a non-root vertex is determined by the last letter of the reduced word of that vertex.

theorem mem_schreierPrefixTree_inl_iff {X : Type u} [DecidableEq X]
    {L : Subgroup (FreeGroup X)} {T : Set (FreeGroup X)}
    {hT : IsRightSchreierTransversal (X := X) L T} :
    letI := schreierTransversalRightCosetAction (X := X) hT
    letI : IsFreeGroupoid (ActionCategory (FreeGroup X) T) :=
      FreeGroupBasis.actionGroupoidIsFree (FreeGroup.inverseBasis X)
    ∀ {a b : IsFreeGroupoid.Generators (ActionCategory (FreeGroup X) T)}
      {g : a ⟶ b},
      (Sum.inl g :
          @Quiver.Hom
            (Quiver.Symmetrify (IsFreeGroupoid.Generators (ActionCategory (FreeGroup X) T)))
            inferInstance a b) ∈
          schreierPrefixTree (X := X) hT a b ↔
        ∃ hw : FreeGroup.toWord ((((show ActionCategory (FreeGroup X) T from b).back : T)) :
            FreeGroup X) ≠ [],
          let tb : T := (show ActionCategory (FreeGroup X) T from b).back
          let pb : T := ⟨FreeGroup.prefixParent (tb : FreeGroup X),
            prefixParent_mem_of_mem (X := X) hT tb.property⟩
          (show ActionCategory (FreeGroup X) T from a).back = pb ∧
            (FreeGroup.toWord (tb : FreeGroup X)).getLast hw = (g.1, true)

Membership in the left branch of the Schreier prefix tree is equivalent to the displayed prefix condition.

Show Lean proof
theorem mem_schreierPrefixTree_inr_iff {X : Type u} [DecidableEq X]
    {L : Subgroup (FreeGroup X)} {T : Set (FreeGroup X)}
    {hT : IsRightSchreierTransversal (X := X) L T} :
    letI := schreierTransversalRightCosetAction (X := X) hT
    letI : IsFreeGroupoid (ActionCategory (FreeGroup X) T) :=
      FreeGroupBasis.actionGroupoidIsFree (FreeGroup.inverseBasis X)
    ∀ {a b : IsFreeGroupoid.Generators (ActionCategory (FreeGroup X) T)}
      {g : b ⟶ a},
      (Sum.inr g :
          @Quiver.Hom
            (Quiver.Symmetrify (IsFreeGroupoid.Generators (ActionCategory (FreeGroup X) T)))
            inferInstance a b) ∈
          schreierPrefixTree (X := X) hT a b ↔
        ∃ hw : FreeGroup.toWord ((((show ActionCategory (FreeGroup X) T from b).back : T)) :
            FreeGroup X) ≠ [],
          let tb : T := (show ActionCategory (FreeGroup X) T from b).back
          let pb : T := ⟨FreeGroup.prefixParent (tb : FreeGroup X),
            prefixParent_mem_of_mem (X := X) hT tb.property⟩
          (show ActionCategory (FreeGroup X) T from a).back = pb ∧
            (FreeGroup.toWord (tb : FreeGroup X)).getLast hw = (g.1, false)

Membership in the right branch of the Schreier prefix tree is equivalent to the displayed prefix condition.

Show Lean proof
theorem schreierPrefixTree_edge_of_last_pos {X : Type u} [DecidableEq X]
    {L : Subgroup (FreeGroup X)} {T : Set (FreeGroup X)}
    (hT : IsRightSchreierTransversal (X := X) L T)
    (t : T) {x : X} (hw : FreeGroup.toWord (t : FreeGroup X) ≠ [])
    (hlast : (FreeGroup.toWord (t : FreeGroup X)).getLast hw = (x, true)) :
    letI := schreierTransversalRightCosetAction (X := X) hT
    letI : IsFreeGroupoid (ActionCategory (FreeGroup X) T) :=
      FreeGroupBasis.actionGroupoidIsFree (FreeGroup.inverseBasis X)
    let p : T := ⟨FreeGroup.prefixParent (t : FreeGroup X),
      prefixParent_mem_of_mem (X := X) hT t.property⟩
    let pA : IsFreeGroupoid.Generators (ActionCategory (FreeGroup X) T) :=
      show IsFreeGroupoid.Generators (ActionCategory (FreeGroup X) T) from
        ((p : T) : ActionCategory (FreeGroup X) T)
    let tA : IsFreeGroupoid.Generators (ActionCategory (FreeGroup X) T) :=
      show IsFreeGroupoid.Generators (ActionCategory (FreeGroup X) T) from
        ((t : T) : ActionCategory (FreeGroup X) T)
    ∃ e : @Quiver.Hom
        (Quiver.Symmetrify (IsFreeGroupoid.Generators (ActionCategory (FreeGroup X) T)))
        inferInstance pA tA,
      e ∈ schreierPrefixTree (X := X) hT pA tA

A positive final letter determines the forward edge from the prefix parent in the Schreier tree.

Show Lean proof
theorem schreierPrefixTree_edge_of_last_neg {X : Type u} [DecidableEq X]
    {L : Subgroup (FreeGroup X)} {T : Set (FreeGroup X)}
    (hT : IsRightSchreierTransversal (X := X) L T)
    (t : T) {x : X} (hw : FreeGroup.toWord (t : FreeGroup X) ≠ [])
    (hlast : (FreeGroup.toWord (t : FreeGroup X)).getLast hw = (x, false)) :
    letI := schreierTransversalRightCosetAction (X := X) hT
    letI : IsFreeGroupoid (ActionCategory (FreeGroup X) T) :=
      FreeGroupBasis.actionGroupoidIsFree (FreeGroup.inverseBasis X)
    let p : T := ⟨FreeGroup.prefixParent (t : FreeGroup X),
      prefixParent_mem_of_mem (X := X) hT t.property⟩
    let pA : IsFreeGroupoid.Generators (ActionCategory (FreeGroup X) T) :=
      show IsFreeGroupoid.Generators (ActionCategory (FreeGroup X) T) from
        ((p : T) : ActionCategory (FreeGroup X) T)
    let tA : IsFreeGroupoid.Generators (ActionCategory (FreeGroup X) T) :=
      show IsFreeGroupoid.Generators (ActionCategory (FreeGroup X) T) from
        ((t : T) : ActionCategory (FreeGroup X) T)
    ∃ e : @Quiver.Hom
        (Quiver.Symmetrify (IsFreeGroupoid.Generators (ActionCategory (FreeGroup X) T)))
        inferInstance pA tA,
      e ∈ schreierPrefixTree (X := X) hT pA tA

A negative final letter determines the oppositely oriented edge from the prefix parent.

Show Lean proof
theorem schreierPrefixTree_parent_edge_of_ne_one {X : Type u} [DecidableEq X]
    {L : Subgroup (FreeGroup X)} {T : Set (FreeGroup X)}
    (hT : IsRightSchreierTransversal (X := X) L T)
    (t : T) (ht1 : (t : FreeGroup X) ≠ 1) :
    letI := schreierTransversalRightCosetAction (X := X) hT
    letI : IsFreeGroupoid (ActionCategory (FreeGroup X) T) :=
      FreeGroupBasis.actionGroupoidIsFree (FreeGroup.inverseBasis X)
    let p : T := ⟨FreeGroup.prefixParent (t : FreeGroup X),
      prefixParent_mem_of_mem (X := X) hT t.property⟩
    let pA : IsFreeGroupoid.Generators (ActionCategory (FreeGroup X) T) :=
      show IsFreeGroupoid.Generators (ActionCategory (FreeGroup X) T) from
        ((p : T) : ActionCategory (FreeGroup X) T)
    let tA : IsFreeGroupoid.Generators (ActionCategory (FreeGroup X) T) :=
      show IsFreeGroupoid.Generators (ActionCategory (FreeGroup X) T) from
        ((t : T) : ActionCategory (FreeGroup X) T)
    ∃ e : @Quiver.Hom
        (Quiver.Symmetrify (IsFreeGroupoid.Generators (ActionCategory (FreeGroup X) T)))
        inferInstance pA tA,
      e ∈ schreierPrefixTree (X := X) hT pA tA

Every nonroot vertex has a Schreier-tree edge from its canonical prefix parent.

Show Lean proof
lemma schreierPrefixTree_root_or_arrow {X : Type u} [DecidableEq X]
    {L : Subgroup (FreeGroup X)} {T : Set (FreeGroup X)}
    (hT : IsRightSchreierTransversal (X := X) L T) :
    letI := schreierTransversalRightCosetAction (X := X) hT
    letI : IsFreeGroupoid (ActionCategory (FreeGroup X) T) :=
      FreeGroupBasis.actionGroupoidIsFree (FreeGroup.inverseBasis X)
    ∀ b : schreierPrefixTree (X := X) hT,
      b = ((((⟨(1 : FreeGroup X), hT.2.1⟩ : T) : ActionCategory (FreeGroup X) T) :
        schreierPrefixTree (X := X) hT)) ∨
      ∃ a, Nonempty (a ⟶ b)

Every Schreier-tree vertex is either the identity root or the target of an incoming edge.

Show Lean proof
lemma schreierPrefixTree_unique_arrow {X : Type u} [DecidableEq X]
    {L : Subgroup (FreeGroup X)} {T : Set (FreeGroup X)}
    (hT : IsRightSchreierTransversal (X := X) L T) :
    letI := schreierTransversalRightCosetAction (X := X) hT
    letI : IsFreeGroupoid (ActionCategory (FreeGroup X) T) :=
      FreeGroupBasis.actionGroupoidIsFree (FreeGroup.inverseBasis X)
    ∀ ⦃a b c : schreierPrefixTree (X := X) hT⦄ (e : a ⟶ c) (f : b ⟶ c), a = b ∧ e ≍ f

Two Schreier-tree arrows with the same target have equal sources and agree as quiver edges.

Show Lean proof
lemma schreierPrefixTree_height_lt {X : Type u} [DecidableEq X]
    {L : Subgroup (FreeGroup X)} {T : Set (FreeGroup X)}
    (hT : IsRightSchreierTransversal (X := X) L T) :
    letI := schreierTransversalRightCosetAction (X := X) hT
    letI : IsFreeGroupoid (ActionCategory (FreeGroup X) T) :=
      FreeGroupBasis.actionGroupoidIsFree (FreeGroup.inverseBasis X)
    ∀ ⦃a b : schreierPrefixTree (X := X) hT⦄ (_ : a ⟶ b),
      (FreeGroup.toWord (((show ActionCategory (FreeGroup X) T from a).back : T) :
        FreeGroup X)).length <
      (FreeGroup.toWord (((show ActionCategory (FreeGroup X) T from b).back : T) :
        FreeGroup X)).length

The reduced-word length strictly increases along every oriented Schreier-tree edge.

Show Lean proof
noncomputable instance schreierPrefixTree_arborescence {X : Type u} [DecidableEq X]
    {L : Subgroup (FreeGroup X)} {T : Set (FreeGroup X)}
    (hT : IsRightSchreierTransversal (X := X) L T) :
    letI := schreierTransversalRightCosetAction (X := X) hT
    letI : IsFreeGroupoid (ActionCategory (FreeGroup X) T) :=
      FreeGroupBasis.actionGroupoidIsFree (FreeGroup.inverseBasis X)
    Quiver.Arborescence (schreierPrefixTree (X := X) hT) := by
  letI := schreierTransversalRightCosetAction (X := X) hT
  letI : IsFreeGroupoid (ActionCategory (FreeGroup X) T) :=
    FreeGroupBasis.actionGroupoidIsFree (FreeGroup.inverseBasis X)
  refine Quiver.arborescenceMk
    ((((⟨(1 : FreeGroup X), hT.2.1⟩ : T) : ActionCategory (FreeGroup X) T) :
      schreierPrefixTree (X := X) hT))
    (fun a =>
      (FreeGroup.toWord (((show ActionCategory (FreeGroup X) T from a).back : T) :
        FreeGroup X)).length)
    ?_ ?_ ?_
  · intro a b e
    exact schreierPrefixTree_height_lt (X := X) hT e
  · intro a b c e f
    exact schreierPrefixTree_unique_arrow (X := X) hT e f
  · intro b
    exact schreierPrefixTree_root_or_arrow (X := X) hT b

The prefix-closed Schreier quiver is an arborescence rooted at the identity representative.

theorem closure_schreierGeneratorSet_eq_top {X : Type u} [DecidableEq X]
    {L : Subgroup (FreeGroup X)} {T : Set (FreeGroup X)}
    (hT : IsRightSchreierTransversal (X := X) L T) :
    Subgroup.closure (schreierGeneratorSet (X := X) hT : Set L) = ⊤

The classical Schreier generators attached to a right Schreier transversal algebraically generate the subgroup.

Show Lean proof
noncomputable def schreierRootEndMulEquiv {X : Type u} [DecidableEq X]
    {L : Subgroup (FreeGroup X)} {T : Set (FreeGroup X)}
    (hT : IsRightSchreierTransversal (X := X) L T) :
    letI := schreierTransversalRightCosetAction (X := X) hT
    CategoryTheory.End
      (show ActionCategory (FreeGroup X) T from ((⟨(1 : FreeGroup X), hT.2.1⟩ : T) :
        ActionCategory (FreeGroup X) T)) ≃* L := by
  letI := schreierTransversalRightCosetAction (X := X) hT
  let rootT : T := ⟨(1 : FreeGroup X), hT.2.1⟩
  let eStab : MulAction.stabilizer (FreeGroup X) rootT ≃* L := by
    refine MulEquiv.subgroupCongr ?_
    ext g
    constructor
    · intro hg
      have hfix : g • rootT = rootT := hg
      have hrep : schreierRepresentative (X := X) hT (g⁻¹) = rootT := by
        simpa [rootT] using (schreierTransversalRightCosetAction_smul (X := X) hT g
            rootT).symm.trans hfix
      have hmemInv : g⁻¹ ∈ L := by
        have hm : g⁻¹ *
            (((schreierRepresentative (X := X) hT (g⁻¹) : T) : FreeGroup X))⁻¹ ∈ L :=
          hT.1.mul_inv_toRightFun_mem (g⁻¹)
        simpa [hrep, rootT] using hm
      simpa using L.inv_mem hmemInv
    · intro hg
      change g • rootT = rootT
      rw [schreierTransversalRightCosetAction_smul (X := X) hT g rootT]
      simpa [rootT] using schreierRepresentative_eq_one_of_mem (X := X) hT (L.inv_mem hg)
  let eSubmonoid : MulAction.stabilizerSubmonoid (FreeGroup X) rootT ≃* L :=
    { toFun := fun g => eStab ⟨g.1, g.2⟩
      invFun := fun l => ⟨(eStab.symm l).1, (eStab.symm l).2⟩
      left_inv := by intro g; rfl
      right_inv := by intro l; rfl
      map_mul' := by intro g h; rfl }
  exact (CategoryTheory.ActionCategory.stabilizerIsoEnd (FreeGroup X) rootT).symm.trans eSubmonoid

The root vertex group in the Schreier action groupoid is canonically the subgroup L, via the action label of an endomorphism.

noncomputable def schreierLabelFunctor {X : Type u} [DecidableEq X]
    {L : Subgroup (FreeGroup X)} {T : Set (FreeGroup X)}
    (hT : IsRightSchreierTransversal (X := X) L T) :
    letI := schreierTransversalRightCosetAction (X := X) hT
    ActionCategory (FreeGroup X) T ⥤ CategoryTheory.SingleObj L := by
  letI := schreierTransversalRightCosetAction (X := X) hT
  refine
    { obj := fun _ => ()
      map := fun {a b} p => ?_
      map_id := ?_
      map_comp := ?_ }
  · let g : FreeGroup X := p.1
    refine ⟨((b.back : T) : FreeGroup X) * g * (((a.back : T) : FreeGroup X))⁻¹, ?_⟩
    have hp : schreierRepresentative (X := X) hT
        ((((a.back : T) : FreeGroup X)) * g⁻¹) = b.back := by
      rw [← schreierTransversalRightCosetAction_smul (X := X) hT g a.back]
      exact p.2
    have hmem : (((a.back : T) : FreeGroup X)) * g⁻¹ *
        (((b.back : T) : FreeGroup X))⁻¹ ∈ L := by
      have hmem0 : (((a.back : T) : FreeGroup X)) * g⁻¹ *
          (((schreierRepresentative (X := X) hT
            ((((a.back : T) : FreeGroup X)) * g⁻¹) : T) : FreeGroup X))⁻¹ ∈ L := by
        simpa [schreierRepresentative] using
          hT.1.mul_inv_toRightFun_mem ((((a.back : T) : FreeGroup X)) * g⁻¹)
      rw [hp] at hmem0
      exact hmem0
    simpa [mul_assoc] using L.inv_mem hmem
  · intro a
    apply Subtype.ext
    change (((a.back : T) : FreeGroup X) * (1 : FreeGroup X) *
        (((a.back : T) : FreeGroup X))⁻¹) = 1
    simp only [mul_one, mul_inv_cancel]
  · intro a b c p q
    let gp : FreeGroup X := p.1
    let gq : FreeGroup X := q.1
    apply Subtype.ext
    change (((c.back : T) : FreeGroup X) * (gq * gp) *
        (((a.back : T) : FreeGroup X))⁻¹) =
        ((((c.back : T) : FreeGroup X) * gq * (((b.back : T) : FreeGroup X))⁻¹) *
          (((b.back : T) : FreeGroup X) * gp * (((a.back : T) : FreeGroup X))⁻¹))
    simp only [mul_assoc, inv_mul_cancel_left]

The cocycle functor on the Schreier action groupoid. It sends a morphism \(a\to b\) labelled by \(g\) to the subgroup element \(b g a^{-1}\), the inverse of the corresponding classical Schreier generator.

@[simp 900] theorem schreierLabelFunctor_map_of {X : Type u} [DecidableEq X]
    {L : Subgroup (FreeGroup X)} {T : Set (FreeGroup X)}
    (hT : IsRightSchreierTransversal (X := X) L T) :
    letI := schreierTransversalRightCosetAction (X := X) hT
    letI : IsFreeGroupoid (ActionCategory (FreeGroup X) T) :=
      FreeGroupBasis.actionGroupoidIsFree (FreeGroup.inverseBasis X)
    ∀ {a b : ActionCategory (FreeGroup X) T}
      (e : ((show IsFreeGroupoid.Generators (ActionCategory (FreeGroup X) T) from a) ⟶ b)),
      ((schreierLabelFunctor (X := X) hT).map (IsFreeGroupoid.of e) : L) =
        (schreierGenerator (X := X) hT (((a.back : T) : FreeGroup X)) e.1)⁻¹

The Schreier label functor respects the corresponding map of generators.

Show Lean proof
lemma schreierLabelFunctor_map_of_eq_one_of_mem_tree {X : Type u} [DecidableEq X]
    {L : Subgroup (FreeGroup X)} {T : Set (FreeGroup X)}
    (hT : IsRightSchreierTransversal (X := X) L T) :
    letI := schreierTransversalRightCosetAction (X := X) hT
    letI : IsFreeGroupoid (ActionCategory (FreeGroup X) T) :=
      FreeGroupBasis.actionGroupoidIsFree (FreeGroup.inverseBasis X)
    ∀ {a b : ActionCategory (FreeGroup X) T}
      (e : ((show IsFreeGroupoid.Generators (ActionCategory (FreeGroup X) T) from a) ⟶ b)),
      e ∈ Quiver.wideSubquiverSymmetrify (schreierPrefixTree (X := X) hT) a b →
        (schreierLabelFunctor (X := X) hT).map (IsFreeGroupoid.of e) = (1 : L)

The corresponding Schreier representative satisfies the stated membership criterion.

Show Lean proof
lemma schreierGenerator_eq_one_implies_mem_prefixTree {X : Type u} [DecidableEq X]
    {L : Subgroup (FreeGroup X)} {T : Set (FreeGroup X)}
    (hT : IsRightSchreierTransversal (X := X) L T) :
    letI := schreierTransversalRightCosetAction (X := X) hT
    letI : IsFreeGroupoid (CategoryTheory.ActionCategory (FreeGroup X) T) :=
      FreeGroupBasis.actionGroupoidIsFree (FreeGroup.inverseBasis X)
    ∀ {a b : CategoryTheory.ActionCategory (FreeGroup X) T}
      (e :
        (show IsFreeGroupoid.Generators (CategoryTheory.ActionCategory (FreeGroup X) T) from
          a) ⟶ b),
      schreierGenerator (X := X) hT (a.back : FreeGroup X) e.1 = 1 →
        e ∈ Quiver.wideSubquiverSymmetrify (schreierPrefixTree (X := X) hT) a b

The Schreier generator is trivial exactly in the corresponding subgroup-membership case.

Show Lean proof
theorem schreierGenerator_eq_one_iff_mem_prefixTree {X : Type u} [DecidableEq X]
    {L : Subgroup (FreeGroup X)} {T : Set (FreeGroup X)}
    {hT : IsRightSchreierTransversal (X := X) L T} :
    letI := schreierTransversalRightCosetAction (X := X) hT
    letI : IsFreeGroupoid (CategoryTheory.ActionCategory (FreeGroup X) T) :=
      FreeGroupBasis.actionGroupoidIsFree (FreeGroup.inverseBasis X)
    ∀ {a b : CategoryTheory.ActionCategory (FreeGroup X) T}
      {e :
        (show IsFreeGroupoid.Generators (CategoryTheory.ActionCategory (FreeGroup X) T) from
          a) ⟶ b},
      schreierGenerator (X := X) hT (a.back : FreeGroup X) e.1 = 1 ↔
        e ∈ Quiver.wideSubquiverSymmetrify (schreierPrefixTree (X := X) hT) a b

A generator edge lies in the symmetrized prefix tree exactly when the associated Schreier generator is trivial.

Show Lean proof