# Image of finitely generated group through an injective homomorphism

I'm doing some work with knot theory, and as a part of it, I'm taking an injection of a finitely generated group into the braid group. I want to do some computations on the image of the group, but I'm having trouble actually computing the image in Sage. This is what I have so far:

```
# Explicitly name generators; rho_i, sigma_i, tau_i
G.<p1, p2, p3, s1, s2, s3, t1, t2, t3, t4> = FreeGroup()
rho = [0, p1, p2, p3] # Zero padding so that rho[i] = rho_i
sigma = [0, s1, s2, s3]
tau = [0, t1, t2, t3, t4]
relations = []
# Lots of relations that aren't actually important for this
for i in range(1, 5):
for j in range(i, 5):
if i != j:
relations.append(tau[i]^-1 * tau[j]^-1 * tau[i] * tau[j])
if abs(i - j) > 1 and i < 4 and j < 4:
relations.append(rho[i]^-1 * rho[j]^-1 * rho[i] * rho[j])
relations.append(sigma[i]^-1 * sigma[j]^-1 * sigma[i] * sigma[j])
relations.append(rho[i]^-1 * sigma[j]^-1 * rho[i] * sigma[j])
# Now relations on neighboring rho_i, sigma_i, tau_i
for i in range(1, 3):
relations.append(rho[i] * rho[i+1] * rho[i] * rho[i+1]^-1 * rho[i]^-1 * rho[i]^-1)
relations.append(sigma[i] * sigma[i+1] * sigma[i] * sigma[i+1]^-1 * sigma[i]^-1 * sigma[i+1]^-1)
relations.append(rho[i] * sigma[i+1] * sigma[i] * rho[i+1]^-1 * sigma[i]^-1 * sigma[i+1]^-1)
relations.append(sigma[i] * sigma[i+1] * rho[i] * sigma[i+1]^-1 * sigma[i]^-1 * rho[i+1]^-1)
relations.append(sigma[i] * rho[i+1] * rho[i] * sigma[i+1]^-1 * rho[i]^-1 * rho[i+1]^-1)
for eta in [1, -1]:
for nu in [1, -1]:
relations.append(tau[i]^eta * sigma[i]^nu * tau[i+1]^(-eta) * sigma[i]^(-nu))
relations.append(tau[i+1]^eta * sigma[i]^nu * tau[i]^(-eta) * sigma[i]^(-nu))
relations.append(tau[i]^eta * rho[i] * tau[i+1]^(-eta) * rho[i]^-1)
relations.append(tau[i+1]^eta * rho[i] * tau[i]^(-eta) * sigma[i]^(-eta) * rho[i] * sigma[i]^eta)
relations.append(tau[i]^eta * rho[i]^-1 * tau[i+1]^(-eta) * sigma[i]^(-eta) * rho[i]^-1 * sigma[i]^eta)
relations.append(tau[i+1]^eta * rho[i]^-1 * tau[i]^(-eta) * rho[i])
# The group I want is F = G / relations
# Now inject into braid group
B = BraidGroup(8, 'b')
b = B.gens()
gen_images = []
for i in range(3):
j = 2 * i
gen_images.append(b[j]) # Image of tau_i
gen_images.append(b[j+1] * b[j+2] * b[j] * b[j+1]) # sigma_i
gen_images.append(b[j+1] * b[j+2]^-1 * b[j] * b[j+1]^-1) # rho_i
gen_images.append(b[6]) # Image of tau_4
f = G.hom(gen_images)
print(f)
for gen in G.gens():
print(f(gen))
```

The actual relations that I haven't aren't too important, the point is that I have the free group `G`

generated by the three sets of generators, and I know what the image of each of those generators should be in the braid group. What I want to do is compute the subgroup of `B`

of `f(G / relations)`

, which I think is generated by the images of the original generators

```
b0, b1*b2*b0*b1, b1*b2^-1*b0*b1^-1, b2, b3*b4*b2*b3, b3*b4^-1*b2*b3^-1, b4, b5*b6*b4*b5, b5*b6^-1*b4*b5^-1, b6
```

then modded out by the image of each of the original relations, but I don't see a way to have a generator of a free group be, for example, `b1*b2*b0*b1`

, e.g. something non-trivial. Is there a way of doing that, or some other way of computing the subgroup that I want?