Finitely generated subgroups of free groups
code-golf mathematics abstract-algebra decision-problem
Suppose you are given the free group \$F_n\$ on \$n\$ generators, a finite subset \$S\$ of \$F_n\$, and an element \$x \in F_n\$. Then there is an algorithm to determine whether \$x\$ is in the subgroup generated by \$S\$, as follows:
- Start with a directed graph with a single "base" vertex, and no edges.
- For each element of \$S\$, add a cycle to the graph according to the corresponding free group word. Start at the base vertex; for each generator \$g_n\$ in the word, add an arrow labelled by \$n\$; for each inverse of a generator \$g_n^{-1}\$ in the word, add an arrow in the opposite direction labelled by \$n\$; and end at the base vertex.
- If there is a pair of edges with the same label and with either the same source or the same destination, merge those two edges and the two vertices at the other end. (Except that merging two vertices is not necessary if the two edges have the same source and the same destination.)
- Iterate the previous step until there is no such pair of edges left.
- Now follow the graph from the base vertex, according to the reduced free group word corresponding to \$x\$. For each generator \$g_n\$ in the word, look for an edge with source at the current vertex and label \$n\$, and move to the destination of that edge. For each generator \$g_n^{-1}\$ in the word, look for an edge with target at the current vertex and label \$n\$, and move to the source of that edge.
- If at any point, you do not find such an edge, then \$x \notin \langle S \rangle\$.
- If at the end, you end up back at the base vertex, then \$x \in \langle S \rangle\$; otherwise, \$x \notin \langle S \rangle\$.
(I plan to give an example of the operation of this algorithm; but I do not have time at the moment to generate the required graph diagrams.)
Task
Your task is: given a finite subset \$S\$ of a free group \$F_n\$ and an element \$x \in F_n\$, determine whether \$x\$ is in the subgroup generated by \$S\$. (Note: we are not asking to determine whether \$x\$ is in the normal subgroup generated by \$S\$; that problem is undecidable in general.)
You are not required to use the above algorithm. On the other hand, your program or function must always terminate in finite time; so for example, that rules out a naive algorithm just taking all possible products of elements of \$S\$ and their inverses and determining whether you eventually find \$x\$ in the output.
Input
You will be given a list of free group elements, and a second input giving another free group element. Possible input formats for free group elements include:
- An element of a built-in free group type.
- A string in the form
abCbcA
where the generators are a
through z
and for example C
represents the inverse of the generator c
. You may assume the string is in reduced form, so for example it will not contain either Cc
or cC
.
If you like, you could also take a single list of free group elements, and use the first element as \$x\$ and the rest of the list as \$S\$.
Output
A truthy/falsey value according to whether or not \$x \in \langle S \rangle\$, where \$S\$ is the set of elements of the list for the first input and \$x\$ is the second input.
Examples
[], identity (empty string) -> True
[], abc -> False
[aa, ab], a -> False
[aa, ab], ba -> False
[aa, ab], Ba -> True
[aBc, bc], identity -> True
[aBc, bc], aBBCbA -> True
[aBc, bc], abc -> False
[identity, identity], a -> False
[aaaaa, aaa], a -> True
Score
This is code-golf: the shortest code in bytes for any given programming language wins.