Conflict between generators in different groups with the same name

asked 2022-03-10 05:26:31 +0200

cgodfrey gravatar image

updated 2022-03-10 18:47:38 +0200

I wrote a relatively simple implementation of the Seifert van Kampen theorem, and I have a commutative 'cube', so to speak, meaning I want to apply it twice successively. The implementation is

# This function computes the fundamental group of a topological space X using
# the Seifert-van Kampen theorem. We decompose X into the union of two open
# connected subsets, U and V, whose fundamental groups are the free group on
# some generators along with relations alpha and beta, respectively.
# Additionally, we have the fundamental group of U \cap V, which is the free
# group on the generators gamma_i. We then have the inclusion maps
# I: \pi(U\cap V) -> \pi(U) and J: \pi(U\cap V) -> \pi(V) which gives
# us the categorical coproduct of \pi(U) * \pi(V).
def seifert_van_kampen(U, alpha, V, beta, I, J, intersection):
    X = FreeGroup(U.gens() + V.gens())
    relations = []
    for generator in intersection.gens():
        relations.append(X(I(generator))*X(J(generator))^-1)
    relations = relations + alpha + beta
    return X / relations

And it seems to work properly in simple cases. My problem arises when trying to apply it twice successively. My diagram looks like this:

     A --- AB
  /     X    \
S -- B     AG -- X  
  \     X    /
     G --- BG

Where S is the pairwise intersection between any of A, B, and G, and the X in the middle of the diagram represents crossing arrows. Through one application of SVK, I can get the fundamental group for AB, AG, or BG, and the problem occurs with the second step to compute the fundamental group for X.

If I have the fundamental groups for A, B, and G generated by alpha_i, beta_i, and gamma_i respectively, then the fundamental group for AB is generated by the alpha_i and beta_i, and similar for AG and BG. But if I try to use the same logic, say using AB and BG to get X, the generators would be alpha_i, beta_i from AB, and beta_i and gamma_i from BG. But my understanding is that those generators should be considered distinct, and I don't quite see how to make that happen in Sage.

In particular, the additional relations when we compute the coproduct (in the AB/BG case) come from the inclusion map of the generators for B into each of AB and BG respectively, which is exactly those duplicate generators. That part is fine, but if I want to consider those words as elements of the free group on (alpha_i, beta_i, beta_i, gamma_i), I don't know how to make those words use the 'correct' generators.

EDIT: To give the specific way I'm trying to use this, I'm studying 2-knots, and have a particular decomposition into 3 1-knots. The fundamental group of each of the knot complements are A, B, and G above, and I'm trying to recover the fundamental group for the original 2-knot complement. There's a lot of boilerplate stuff to get the knot in a particular representation I can work with, but right now I use the above function like this:

def SVK_cube(braids, b):
    prefixes = ['x', 'y', 'z']
    intersect_maps = []
    groups = []

    intersect_group = FreeGroup(2 * b, 'a')

    # Boilerplate stuff
    graph, _ = make_graph(braids, b)
    graph = is_orientable(graph)
    signs = orientation_signs(graph, b)

    for i in range(3):
        # hom[i] is the element that the ith generator of fundamental group for
        # intersection gets sent to
        hom, group = wirtinger_relations(braids[i], signs, b, prefixes[i])
        print(group)
        print(hom)
        groups.append(group)
        intersect_maps.append(intersect_group.hom(hom))

    a_group, b_group, g_group = groups
    a_rels = [a_group.gen(2*i)*a_group.gen(2*i+1)^-1 for i in range(b)]
    b_rels = [b_group.gen(2*i)*b_group.gen(2*i+1)^-1 for i in range(b)]
    g_rels = [g_group.gen(2*i)*g_group.gen(2*i+1)^-1 for i in range(b)]

    ab = seifert_van_kampen(a_group, a_rels, b_group, b_rels, intersect_maps[0], intersect_maps[1], intersect_group)
    ag = seifert_van_kampen(a_group, a_rels, g_group, g_rels, intersect_maps[0], intersect_maps[2], intersect_group)
    bg = seifert_van_kampen(b_group, b_rels, g_group, g_rels, intersect_maps[1], intersect_maps[2], intersect_group)
    print(ab.simplified())
    print(ag.simplified())
    print(bg.simplified())


braids = [[4,5,6,7,2,3,4,5,6,7],[2,3,4,5,6,7], [2, 3, 4, 5, 6, 7, -7, -7, -7, 1, 1, 1, 3, -5, -4]]
SVK_cube(braids, 4)

And this gives the output:

Free Group on generators {x0, x1, x2, x3, x4, x5, x6, x7}
[x0, x1^-1*x2*x1, x1^-1*x3^-1*x4^-1*x3*x1, x1^-1*x3^-1*x5*x3*x1, x1^-1*x3^-1*x6^-1*x3*x1, x1^-1*x3^-1*x7*x3*x1, x1^-1*x3^-1*x1, x1^-1]
Free Group on generators {y0, y1, y2, y3, y4, y5, y6, y7}
[y0, y1^-1*y2*y1, y1^-1*y3^-1*y1, y1^-1*y4*y1, y1^-1*y5^-1*y1, y1^-1*y6*y1, y1^-1*y7^-1*y1, y1^-1]
Free Group on generators {z0, z1, z2, z3, z4, z5, z6, z7}
[(z0*z1^-1*z2*z1)^2*z0^-1*z1^-1*z2^-1*z1*z0^-1, z0*z1^-1*z2*z1*z0*z1^-1*z2^-1*z1*z0^-1, z1^-1*z3^-1*z4^-1*z3*z1, z1^-1*z6*z1, z1^-1*z6^-1*z3^-1*z6*z1, z1^-1*z6^-1*z5*z6*z1, z7*z1^-1*z7^-1, z7*z1*z7^-1*z1^-1*z7^-1]
Finitely presented group < x0, x2 |  >
Finitely presented group < x4, z0 |  >
Finitely presented group < y0, y2 |  >

I have the simplified group printed out for the sake of space, but the next step would be to take a pair of these groups and compute the coproduct again. I don't think I can use the simplified form because I need to know where the generators for b (for example) are sent to into ab and bg, which is lost in the simplified form.

edit retag flag offensive close merge delete

Comments

Could you add an example that uses your function, with a successful first step and an attempt at the second step? For me it would clarify the types of the objects involved.

rburing gravatar imagerburing ( 2022-03-10 15:48:25 +0200 )edit

@rburing I added an example, hopefully that helps clear up what I'm trying to do.

cgodfrey gravatar imagecgodfrey ( 2022-03-10 18:48:31 +0200 )edit