P:=PolynomialRing(IntegerRing()); P; //FOR THE DESCRIPTION OF ALL PROGRAMS, PLEASE SEE THE LAST ANNEXE OF OUR ARTICLE. // Zeta Polynomial for loose trees function PolTree(G) V:=Vertices(G); Q:=0; if #(V) eq 0 then return Q; else for i in [1..#(V)] do if Degree(V[i]) eq 1 then Q:=Q + 1; else Q:=Q + x^(Degree(V[i])) - x + 1; end if; end for; Q:=Q + x - 1; return Q; end if; end function; //Given a loose graph G, create a spanning tree breaking a cycle in each step function LooseSPTree(G) L:=[* G *]; if IsTree(G) then return L; else G1:=SpanningTree(G); V1:=Vertices(G1); V:=Vertices(G); G2:=G; t:=#(V); t1:=#(V1); for i in [1 .. t] do A:=Neighbors(V[i]); A1:=Neighbors(V1[i]); for c in [i+1 .. t1] do if V[c] in A then if V1[c] notin A1 then R:=G2 + 2; t2:=#(Vertices(R)); R:=AddEdge(R, Vertices(R)[i], Vertices(R)[t2-1]); R:= R - { {Vertices(R)[i], Vertices(R)[c]} }; G2:=AddEdge(R, Vertices(R)[c], Vertices(R)[t2]); L:=Append(L, G2); end if; end if; end for; end for; return L; end if; end function; //Given a graph, compute its Loose Spanning Tree function PolLSPTree(G) B:=LooseSPTree(G); n:=#(B); A:=PolTree(B[n]); return A; end function; //Computing the graph G^L function GL(A,B) V1:=Vertices(A); V2:=Vertices(B); t1:=#(V1); t2:=#(V2); L:=[* *]; for i in [1 .. t2] do N2:=Neighbors(V2[i]); for c in [i+1 .. t2] do if V2[c] adj V2[i] then if V1[c] notadj V1[i] then H1:= Exclude(Neighbors(V2[c]), V2[i]); H2:= Exclude(Neighbors(V2[i]), V2[c]); H:= H1 meet H2; H3:= H1 sdiff H2; if IsEmpty(H) then L:=Append(L, NullGraph()); else G3:=sub; T:=Components(G3); lT:=#(T); for i in [1..lT] do G4:=sub; V4:=Vertices(G4); lV4:=#(V4); if #(H3) ge 1 then G5:=G4; VG5:=Vertices(G5); for j in [1..#(H3)] do V5:={@ v : v in VG5 | (Vertices(B) ! v) adj SetToIndexedSet(H3)[j] @}; if IsEmpty(V5) then else G5:= G5 + 1; lG5:=#(Vertices(G5)); if IsSubgraph(G5,G4) then V6:={@ (VertexSet(G5) ! V5[s]) : s in [1..#(V5)] @}; G5:= G5 + {{V6[s], Vertices(G5)[lG5]} : s in [1..#(V6)]}; end if; end if; end for; L:=Append(L,G5); else L:=[* sub : i in [1..lT] *]; end if; end for; end if; return L; end if; end if; end for; end for; end function; //Computing the graph C(G^L, xy) function GL2(A,B) V1:=Vertices(A); V2:=Vertices(B); t1:=#(V1); t2:=#(V2); for i in [1 .. t2] do N2:=Neighbors(V2[i]); for c in [i+1 .. t2] do if V2[c] adj V2[i] then if V1[c] notadj V1[i] then H1:= Exclude(Neighbors(V2[c]), V2[i]); H2:= Exclude(Neighbors(V2[i]), V2[c]); H:= H1 meet H2; H5:=Include(Include(H, V2[c]), V2[i]); H3:= H1 sdiff H2; G2:=sub; G3:=sub; if IsEmpty(H) then L:=[* G2 *]; else T:=Components(G3); lT:=#(T); G5:=G2; for i in [1..lT] do G4:=sub; V4:=Vertices(G4); lV4:=#(V4); if #(H3) ge 1 then for j in [1..#(H3)] do if IsSubgraph (G2,G4) then V5:={@ (VertexSet(B) ! (VertexSet(G3) ! v)) : v in V4 | (VertexSet(B) ! (VertexSet(G3) ! v)) adj SetToIndexedSet(H3)[j] @}; if not IsEmpty(V5) then G5:=G5 + 1; lG5:=#(Vertices(G5)); if IsSubgraph (G5,G2) then V6:={@ (VertexSet(G5) ! (VertexSet(G2) ! V5[s])) : s in [1..#(V5)] @}; G5:= G5 + {{V6[s], Vertices(G5)[lG5]} : s in [1..#(V6)]}; end if; end if; end if; end for; end if; end for; L:=[* G5 *]; end if; return L; end if; end if; end for; end for; end function; //Computing the graph G^L_x function GLx(A,B) V1:=Vertices(A); V2:=Vertices(B); t1:=#(V1); t2:=#(V2); L:=[* *]; for i in [1 .. t2] do N2:=Neighbors(V2[i]); for c in [i+1 .. t2] do if V2[c] adj V2[i] then if V1[c] notadj V1[i] then H1:= Exclude(Neighbors(V2[c]), V2[i]); H2:= Exclude(Neighbors(V2[i]), V2[c]); H:= H1 meet H2; H3:= H1 diff H2; if IsEmpty(H) then L:=Append(L, NullGraph()); else G3:=sub; T:=Components(G3); lT:=#(T); for i in [1..lT] do G4:=sub; V4:=Vertices(G4); lV4:=#(V4); if #(H3) ge 1 then G5:=G4; VG5:=Vertices(G5); for j in [1..#(H3)] do V5:={@ v : v in VG5 | (Vertices(B) ! v) adj SetToIndexedSet(H3)[j] @}; if IsEmpty(V5) then else G5:= G5 + 1; lG5:=#(Vertices(G5)); if IsSubgraph(G5,G4) then V6:={@ (VertexSet(G5) ! V5[s]) : s in [1..#(V5)] @}; G5:= G5 + {{V6[s], Vertices(G5)[lG5]} : s in [1..#(V6)]}; end if; end if; end for; L:=Append(L,G5); else L:=[* sub : i in [1..lT] *]; end if; end for; end if; return L; end if; end if; end for; end for; end function; //Computing the graph C(G^L_x, xy) function GL2x(A,B) V1:=Vertices(A); V2:=Vertices(B); t1:=#(V1); t2:=#(V2); for i in [1 .. t2] do N2:=Neighbors(V2[i]); for c in [i+1 .. t2] do if V2[c] adj V2[i] then if V1[c] notadj V1[i] then H1:= Exclude(Neighbors(V2[c]), V2[i]); H2:= Exclude(Neighbors(V2[i]), V2[c]); H:= H1 meet H2; H5:=Include(Include(H, V2[c]), V2[i]); H3:= H1 diff H2; G2:=sub; G3:=sub; if IsEmpty(H) then L:=[* G2 *]; else T:=Components(G3); lT:=#(T); G5:=G2; for i in [1..lT] do G4:=sub; V4:=Vertices(G4); lV4:=#(V4); if #(H3) ge 1 then for j in [1..#(H3)] do if IsSubgraph (G2,G4) then V5:={@ (VertexSet(B) ! (VertexSet(G3) ! v)) : v in V4 | (VertexSet(B) ! (VertexSet(G3) ! v)) adj SetToIndexedSet(H3)[j] @}; if not IsEmpty(V5) then G5:=G5 + 1; lG5:=#(Vertices(G5)); if IsSubgraph (G5,G2) then V6:={@ (VertexSet(G5) ! (VertexSet(G2) ! V5[s])) : s in [1..#(V5)] @}; G5:= G5 + {{V6[s], Vertices(G5)[lG5]} : s in [1..#(V6)]}; end if; end if; end if; end for; end if; end for; L:=[* G5 *]; end if; return L; end if; end if; end for; end for; end function; //Computing the graph C(G^L_x, y) function GL3x(A,B) V1:=Vertices(A); V2:=Vertices(B); t1:=#(V1); t2:=#(V2); for i in [1 .. t2] do N2:=Neighbors(V2[i]); for c in [i+1 .. t2] do if V2[c] adj V2[i] then if V1[c] notadj V1[i] then H1:= Exclude(Neighbors(V2[c]), V2[i]); H2:= Exclude(Neighbors(V2[i]), V2[c]); H:= H1 meet H2; H5:=Include(H, V2[i]); H3:= H1 diff H2; G2:=sub; G3:=sub; if IsEmpty(H) then L:=[* G2 *]; else T:=Components(G3); lT:=#(T); G5:=G2; for i in [1..lT] do G4:=sub; V4:=Vertices(G4); lV4:=#(V4); if #(H3) ge 1 then for j in [1..#(H3)] do if IsSubgraph (G2,G4) then V5:={@ (VertexSet(B) ! (VertexSet(G3) ! v)) : v in V4 | (VertexSet(B) ! (VertexSet(G3) ! v)) adj SetToIndexedSet(H3)[j] @}; if not IsEmpty(V5) then G5:=G5 + 1; lG5:=#(Vertices(G5)); if IsSubgraph (G5,G2) then V6:={@ (VertexSet(G5) ! (VertexSet(G2) ! V5[s])) : s in [1..#(V5)] @}; G5:= G5 + {{V6[s], Vertices(G5)[lG5]} : s in [1..#(V6)]}; end if; end if; end if; end for; end if; end for; L:=[* G5 *]; end if; return L; end if; end if; end for; end for; end function; //Computing the graph G^L_y function GLy(A,B) V1:=Vertices(A); V2:=Vertices(B); t1:=#(V1); t2:=#(V2); L:=[* *]; for i in [1 .. t2] do N2:=Neighbors(V2[i]); for c in [i+1 .. t2] do if V2[c] adj V2[i] then if V1[c] notadj V1[i] then H1:= Exclude(Neighbors(V2[c]), V2[i]); H2:= Exclude(Neighbors(V2[i]), V2[c]); H:= H1 meet H2; H4:= H2 diff H1; if IsEmpty(H) then L:=Append(L, NullGraph()); else G3:=sub; T:=Components(G3); lT:=#(T); for i in [1..lT] do G4:=sub; V4:=Vertices(G4); lV4:=#(V4); if #(H4) ge 1 then G5:=G4; VG5:=Vertices(G5); for j in [1..#(H4)] do V5:={@ v : v in VG5 | (Vertices(B) ! v) adj SetToIndexedSet(H4)[j] @}; if IsEmpty(V5) then else G5:= G5 + 1; lG5:=#(Vertices(G5)); if IsSubgraph(G5,G4) then V6:={@ (VertexSet(G5) ! V5[s]) : s in [1..#(V5)] @}; G5:= G5 + {{V6[s], Vertices(G5)[lG5]} : s in [1..#(V6)]}; end if; end if; end for; L:=Append(L,G5); else L:=[* sub : i in [1..lT] *]; end if; end for; end if; return L; end if; end if; end for; end for; end function; //Computing the graph C(G^L_y, xy) function GL2y(A,B) V1:=Vertices(A); V2:=Vertices(B); t1:=#(V1); t2:=#(V2); for i in [1 .. t2] do N2:=Neighbors(V2[i]); for c in [i+1 .. t2] do if V2[c] adj V2[i] then if V1[c] notadj V1[i] then H1:= Exclude(Neighbors(V2[c]), V2[i]); H2:= Exclude(Neighbors(V2[i]), V2[c]); H:= H1 meet H2; H5:=Include(Include(H, V2[c]), V2[i]); H3:= H2 diff H1; G2:=sub; G3:=sub; if IsEmpty(H) then L:=[* G2 *]; else T:=Components(G3); lT:=#(T); G5:=G2; for i in [1..lT] do G4:=sub; V4:=Vertices(G4); lV4:=#(V4); if #(H3) ge 1 then for j in [1..#(H3)] do if IsSubgraph (G2,G4) then V5:={@ (VertexSet(B) ! (VertexSet(G3) ! v)) : v in V4 | (VertexSet(B) ! (VertexSet(G3) ! v)) adj SetToIndexedSet(H3)[j] @}; if not IsEmpty(V5) then G5:=G5 + 1; lG5:=#(Vertices(G5)); if IsSubgraph (G5,G2) then V6:={@ (VertexSet(G5) ! (VertexSet(G2) ! V5[s])) : s in [1..#(V5)] @}; G5:= G5 + {{V6[s], Vertices(G5)[lG5]} : s in [1..#(V6)]}; end if; end if; end if; end for; end if; end for; L:=[* G5 *]; end if; return L; end if; end if; end for; end for; end function; //Computing the graph C(G^L_y, x) function GL3y(A,B) V1:=Vertices(A); V2:=Vertices(B); t1:=#(V1); t2:=#(V2); for i in [1 .. t2] do N2:=Neighbors(V2[i]); for c in [i+1 .. t2] do if V2[c] adj V2[i] then if V1[c] notadj V1[i] then H1:= Exclude(Neighbors(V2[c]), V2[i]); H2:= Exclude(Neighbors(V2[i]), V2[c]); H:= H1 meet H2; H5:=Include(H, V2[c]); H3:= H2 diff H1; G2:=sub; G3:=sub; if IsEmpty(H) then L:=[* G2 *]; else T:=Components(G3); lT:=#(T); G5:=G2; for i in [1..lT] do G4:=sub; V4:=Vertices(G4); lV4:=#(V4); if #(H3) ge 1 then for j in [1..#(H3)] do if IsSubgraph (G2,G4) then V5:={@ (VertexSet(B) ! (VertexSet(G3) ! v)) : v in V4 | (VertexSet(B) ! (VertexSet(G3) ! v)) adj SetToIndexedSet(H3)[j] @}; if not IsEmpty(V5) then G5:=G5 + 1; lG5:=#(Vertices(G5)); if IsSubgraph (G5,G2) then V6:={@ (VertexSet(G5) ! (VertexSet(G2) ! V5[s])) : s in [1..#(V5)] @}; G5:= G5 + {{V6[s], Vertices(G5)[lG5]} : s in [1..#(V6)]}; end if; end if; end if; end for; end if; end for; L:=[* G5 *]; end if; return L; end if; end if; end for; end for; end function; //Create all list with all different graph from the whole surgery process function ListGL (L) tL:=#(L); L1:=[* *]; for i in [1..(tL-1)] do L1:=L1 cat GL(L[tL - i +1], L[tL - i]); end for; return L1; end function; function ListGLx (L) tL:=#(L); L1:=[* *]; for i in [1..(tL-1)] do L1:=L1 cat GLx(L[tL - i +1], L[tL - i]); end for; return L1; end function; function ListGLy (L) tL:=#(L); L1:=[* *]; for i in [1..(tL-1)] do L1:=L1 cat GLy(L[tL - i +1], L[tL - i]); end for; return L1; end function; function ListGL2 (L) tL:=#(L); L1:=[* *]; for i in [1..(tL-1)] do L1:=L1 cat GL2(L[tL - i +1], L[tL - i]); end for; return L1; end function; function ListGL2x (L) tL:=#(L); L1:=[* *]; for i in [1..(tL-1)] do L1:=L1 cat GL2x(L[tL - i +1], L[tL - i]); end for; return L1; end function; function ListGL2y (L) tL:=#(L); L1:=[* *]; for i in [1..(tL-1)] do L1:=L1 cat GL2y(L[tL - i +1], L[tL - i]); end for; return L1; end function; function ListGL3x (L) tL:=#(L); L1:=[* *]; for i in [1..(tL-1)] do L1:=L1 cat GL3x(L[tL - i +1], L[tL - i]); end for; return L1; end function; function ListGL3y (L) tL:=#(L); L1:=[* *]; for i in [1..(tL-1)] do L1:=L1 cat GL3y(L[tL - i +1], L[tL - i]); end for; return L1; end function; //Keeping track of all vertices added in the surgery process function mL (A,B) V1:=Vertices(A); V2:=Vertices(B); t1:=#(V1); t2:=#(V2); t:=0; for i in [1 .. t2] do N2:=Neighbors(V2[i]); for c in [i+1 .. t2] do if V2[c] adj V2[i] then if V1[c] notadj V1[i] then H1:= Exclude(Neighbors(V2[c]), V2[i]); H2:= Exclude(Neighbors(V2[i]), V2[c]); H:= H1 meet H2; L:=GL(A,B); for i in [1..#(L)] do t:= t + #(Vertices(L[i])); end for; t:= t - #(H); end if; end if; end for; end for; return t; end function; function ListmL(L) tL:=#(L); L2:=[mL(L[tL - i +1], L[tL - i]) : i in [1..(tL-1)]]; return L2; end function; function mLx (A,B) V1:=Vertices(A); V2:=Vertices(B); t1:=#(V1); t2:=#(V2); t:=0; for i in [1 .. t2] do N2:=Neighbors(V2[i]); for c in [i+1 .. t2] do if V2[c] adj V2[i] then if V1[c] notadj V1[i] then H1:= Exclude(Neighbors(V2[c]), V2[i]); H2:= Exclude(Neighbors(V2[i]), V2[c]); H:= H1 meet H2; L:=GLx(A,B); for i in [1..#(L)] do t:= t + #(Vertices(L[i])); end for; t:= t - #(H); end if; end if; end for; end for; return t; end function; function ListmLx(L) tL:=#(L); L2:=[mLx(L[tL - i +1], L[tL - i]) : i in [1..(tL-1)]]; return L2; end function; function mLy (A,B) V1:=Vertices(A); V2:=Vertices(B); t1:=#(V1); t2:=#(V2); t:=0; for i in [1 .. t2] do N2:=Neighbors(V2[i]); for c in [i+1 .. t2] do if V2[c] adj V2[i] then if V1[c] notadj V1[i] then H1:= Exclude(Neighbors(V2[c]), V2[i]); H2:= Exclude(Neighbors(V2[i]), V2[c]); H:= H1 meet H2; L:=GLy(A,B); for i in [1..#(L)] do t:= t + #(Vertices(L[i])); end for; t:= t - #(H); end if; end if; end for; end for; return t; end function; function ListmLy(L) tL:=#(L); L2:=[mLy(L[tL - i +1], L[tL - i]) : i in [1..(tL-1)]]; return L2; end function; //Compute zeta polynomial for a graph function PolynGraph1(G) Q:=0; if IsNull(G) then return Q; else if IsTree(G) then return Q + PolTree(G); else V:=Vertices(G); D:=SetToIndexedSet(Alldeg(G, #(V) -1)); if IsEmpty(D) then L:=LooseSPTree(G); tL:=#(L); Q:=Q + PolLSPTree(L[tL]) - 2*(tL - 1); L1:=ListGL(L); L2:=ListGLx(L); L3:=ListGLy(L); L4:=ListGL2(L); L5:=ListGL2x(L); L6:=ListGL2y(L); L7:=ListGL3x(L); L8:=ListGL3y(L); L9:=ListmL(L); L10:=ListmLx(L); L11:=ListmLy(L); for i in [1..#(L1)] do Q:= Q - x^2*PolynGraph1(L1[i]); end for; for i in [1..#(L2)] do Q:= Q + (x-1)*PolynGraph1(L2[i]); end for; for i in [1..#(L3)] do Q:= Q + (x-1)*PolynGraph1(L3[i]); end for; for i in [1..#(L9)] do Q:= Q + (x^2-1)*L9[i]; end for; for i in [1..#(L10)] do Q:= Q - (x-1)*L10[i]; end for; for i in [1..#(L11)] do Q:= Q - (x-1)*L11[i]; end for; for i in [1..#(L4)] do Q:= Q + PolynGraph1(L4[i]); end for; for i in [1..#(L5)] do Q:= Q - PolynGraph1(L5[i]); end for; for i in [1..#(L6)] do Q:= Q - PolynGraph1(L6[i]); end for; for i in [1..#(L7)] do Q:= Q + PolynGraph1(L7[i]); end for; for i in [1..#(L8)] do Q:= Q + PolynGraph1(L8[i]); end for; else G1:= G - D[1]; G2:= Components(G1); Q:=Q + x^(Degree(D[1])); for i in [1..#(G2)] do Q:= Q + PolynGraph1(sub); end for; end if; return Q; end if; end if; end function; //Compute the zeta polynomial for a loose graph function PolynGraph(G,m) Q:= PolynGraph1(G) - m; return Q; end function; //EXAMPLES OF GRAPHS A:= Graph< 6 | {1,2}, {1,3}, {1,4}, {1,5}, {2,3}, {3,4}, {3,5}, {3,6}, {4,5}, {5,6}>; B:=Graph< 5 | {1,2}, {2,3}, {2,4}, {3,4}, {4,5}>; C:=Graph<5 | {1,2}, {1,3}, {1,4}, {1,5}, {2,3}, {2,4}, {2,5}, {3,4}, {3,5}, {4,5}>; D:= Graph< 7 | {1,2}, {1,3}, {1,4}, {1,5}, {2,3}, {3,4}, {3,5}, {3,6}, {4,5}, {5,6}, {1,7}, {7,3}>; E:=Graph <5 | {5,2}, {5,3}, {5,4}, {1,5}, {2,3}, {3,4}, {4,1}, {1,2}>; F:= Graph <6 | {1,2}, {1,3}, {1,4}, {1,5}, {2,3}, {3,4}, {4,5}, {5,2}, {6,2} >; G:=Graph<6 | {1,2}, {1,3}, {1,4}, {1,5}, {2,3}, {3,4}, {4,5}, {5,2}, {6,2}, {6,3}, {6,4}, {6,5}>; H:=Graph<7 | {1,2}, {1,3}, {1,4}, {1,5}, {1,6}, {2,5}, {2,6}, {2,7}, {3,6}, {3,5}, {4,5}, {6,7}>; I:=Graph<7 | {1,2}, {1,3}, {1,4}, {1,5}, {1,6}, {2,5}, {2,6}, {2,7}, {3,6}, {3,5}, {4,5}, {6,7}, {5,6}>; J:=Graph<8 | {1,2}, {1,3}, {1,8}, {2,6}, {2,7}, {3,4}, {3,6}, {4,5}, {4,8}, {5,6}, {5,7}, {7,8}>;