1 | initial version |
The type of solution i had in mind, while typing the comment, was of the following shape:
F.<a,b,c> = FreeGroup()
H.<s,t,u> = FreeGroup()
h2f_DIC = { 1: a*b , # s "is" a*b :: map s -> a*b
2: b , # t "is" b :: map t -> b
3: b*c , # u "is" b*c :: map u -> b*c
}
f2h_DIC = { 1: s*t^(-1),
2: t ,
3: t^(-1)*u, }
for dic in h2f_DIC, f2h_DIC:
for key, val in dic.items():
dic[-key] = val^(-1)
def h2f( d ):
"""d is an element of F.<a,b,c>, map it to H by using f2h_DIC
"""
return prod( [ f2h_DIC[j] for j in d.Tietze() ] )
def f2h( w ):
"""w is an element of H.<s,t,u>, map it to F by using h2f_DIC
"""
return prod( [ h2f_DIC[j] for j in w.Tietze() ] )
d = a * b * a * b^-1 * c * a^2 * c^3 * b * c^-3
print "d = %s" % d
print "d.Tietze() = %s" % str( d.Tietze() )
w = h2f( d )
print "w = %s" % w
print "w.Tietze() = %s" % str( w.Tietze() )
print "f2h( h2f( d ) ) == d is %s" % bool( f2h( h2f( d ) ) == d )
which delivers:
d = a*b*a*b^-1*c*a^2*c^3*b*c^-3
d.Tietze() = (1, 2, 1, -2, 3, 1, 1, 3, 3, 3, 2, -3, -3, -3)
w = s^2*t^-3*u*(s*t^-1)^2*(t^-1*u)^3*(t*u^-1)^3*t
w.Tietze() = (1, 1, -2, -2, -2, 3, 1, -2, 1, -2, -2, 3, -2, 3, -2, 3, 2, -3, 2, -3, 2, -3, 2)
f2h( h2f( d ) ) == d is True
However not in this ugly, unstructural way do define morphisms by hand, well, i hoped for us, that something like F.hom( ... )
would work. No chance... The above is the best i can deliver in time...
Anyway, the above is the best structural solution i could see, that works without too much pain in both directions, $F\to H$, and $H\to F$. The composition $F\to H\to F$ was tested above to be the identity, at least when applied on some random element $d$.
(We really need the usual structural morphisms. As seen above, there should be not so complicated to implement them somehow, even also not optimal for a first approach...)