`type/graphsymbol` := proc(s) local x; if type(s,symbol) then # Classic GUI x := [attributes(s)]; type(s,symbol) and length(s)>6 and substring(s,1..6)='`Graph `' and type(x,'list'(`=`)) and hasoption(x,'GRAPHLN'); elif type(s,function) then # Standard GUI return evalb( op(0,s)=GRAPHLN ); # Don't use type(s,GRAPHLN) because s has been print preprocessed else false fi; end: `type/undirectedgraphsymbol` := proc(s) type(s,graphsymbol) and ( type(s,symbol) and searchtext("undirected",s) > 0 # classic GUI or type(s,function) and op(1,s)=undirected # java GUI ) end: `type/weightedgraphsymbol` := proc(s) type(s,graphsymbol) and ( type(s,symbol) and searchtext("unweighted",s) = 0 # classic GUI or type(s,function) and op(2,s)=weighted # java GUI ) end: `type/simplegraph` := proc(s) type(s,undirectedgraphsymbol) and ( type(s,symbol) and searchtext("unweighted",s) > 0 # classic GUI or type(s,function) and op(2,s)=unweighted # java GUI ) end: `type/unweightedgraph` := proc(s) type(s,graphsymbol) and ( type(s,symbol) and searchtext("unweighted",s) > 0 # classic GUI or type(s,function) and op(2,s)=unweighted # java GUI ) end: `type/nonsimplegraph` := proc(s) not type(s,simplegraph) end: `type/digraphsymbol` := proc(s) type(s,graphsymbol) and ( type(s,symbol) and searchtext(" directed",s) > 0 or type(s,function) and op(1,s)=directed ) end: `type/acyclicdigraphsymbol` := proc(s) type(s,digraphsymbol) and GraphTheory:-IsAcyclic( preprograph(s) ); end: `type/networksymbol` := proc(s) local S,T; if not type(s,digraphsymbol) then return false; fi; S,T := GraphTheory:-IsNetwork( preprograph(s) ); S <> {} and T <> {}; end: `type/weightednetworksymbol` := proc(s) type(s,networksymbol) and ( type(s,symbol) and searchtext("unweighted",s) = 0 # classic GUI or type(s,function) and op(2,s)=weighted # java GUI ) end: preprograph := proc(g) local A,M,GUI; GUI := interface(version); if substring(GUI,1..7)='`Classic`' then return ExtractGraph(g); fi; if substring(GUI,1..8)='`Standard`' and #type(g,'GRAPHLN'(symbol,symbol,list,'Array'(anything=integer),symbol,{0,'Matrix'(anything=integer)})) then #The above doesn't work because type/Array and type/Matrix are special types type(g,'GRAPHLN'(symbol,symbol,list,specfunc(identical(`%id`)=integer,'Array'),symbol,{0,function})) then # In the java GUI, g looks like this # GRAPHLN(directed,weighted,[...],Array(`%id`=NNN),`GRAPHLN/table/nnn`,Matrix(`%id`=MMM)) # where NNN and MMM are handles to the actual objects. A := pointto(op(2,op(1,op(4,g)))); if op(6,g)=0 then M := 0; else M := pointto(op(2,op(1,op(6,g)))); fi; return subsop(4=A,6=M,g); fi; error "not implemented for this version: %1", GUI; end: ExtractGraph := proc(g) local G; # For a Maple command which outputs a graph, e.g., # > Graph([1,2,3],{{1,2},{2,3}}); # outputs the following symbol from print/GRAPHLN # `Graph 1: an undirected and unweighted graph with 3 vertices and 2 edge(s)` # In the classic GUI, g is this symbol, with the graph attached as an attribute. # In the java GUI, g will be the actual graph. # However, for a Maple command which assigns a graph to a variable, e.g., # > G := Graph([1,2,3],{{1,2},{2,3}}); # `Graph 2: an undirected and unweighted graph with 3 vertices and 2 edge(s)` # In this case, for both classic and java GUIs, g will be the graph # printf("EXT=%a: %a\n",type(g,GRAPHLN),g); if type(g,GRAPHLN) then return g fi; if not type(g,symbol) then error "bad graph" fi; G := subs([attributes(g)],GRAPHLN); if G=GRAPHLN then error "bad graph" else G fi; end: use ContextMenu in CM := New(); CM[EntryGenerators][Add]( "GraphTheoryExportList", proc(G) local n, i, f, s, H; H := preprograph(G); n := `GRAPHLN/number`(H); # n should be the unique print number for this graph if not type(n,posint) then return []; fi; # this should not happen but if it does .... n := cat("Graph",n); # this is the file name prefix if op(1,H)=undirected and op(2,H)=unweighted then f := ["combinatorica","dimacs","metapost"]; s := ["combinatorica","col","mp"]; else f := ["metapost"]; s := ["mp"]; fi; [seq( [f[i],[cat(n,".",s[i]),f[i]]], i=1..nops(f) )]; end ); CM[Entries][Add]( "DrawGraph", "GraphTheory:-DrawGraph(ExtractGraph(%EXPR))", graphsymbol, 'autoassign'=false ); CM[Entries][Add]( "ExportGraph", "GraphTheory:-ExportGraph(ExtractGraph(%EXPR),%ARG1,%ARG2)", graphsymbol, entry_generator = "GraphTheoryExportList", 'autoassign'=false ); CM[Entries][AddMultiple]( ["DrawGraph (spring)", "GraphTheory:-DrawGraph(ExtractGraph(%EXPR),style=spring)", graphsymbol, 'autoassign'=false], ["DrawGraph (3D)", "GraphTheory:-DrawGraph(ExtractGraph(%EXPR),style=spring,dimension=3)", graphsymbol, 'autoassign'=false], ["DrawNetwork", "GraphTheory:-DrawNetwork(ExtractGraph(%EXPR))", networksymbol, 'autoassign'=false], submenu=["Graph drawing"]); CM[EntryGenerators][Add]( "GraphTheoryPolynomialVariableList", proc(G) local v,X; X := remove(assigned,'[x,y,lambda,p,q]'); [seq([convert(v,string),[v]], v=X)]; end); CM[Entries][AddMultiple]( ["AcyclicPolynomial", "GraphTheory:-AcyclicPolynomial(ExtractGraph(%EXPR),%ARG1)", simplegraph, entry_generator = "GraphTheoryPolynomialVariableList"], ["CharacteristicPolynomial", "GraphTheory:-CharacteristicPolynomial(ExtractGraph(%EXPR),%ARG1)", graphsymbol, entry_generator = "GraphTheoryPolynomialVariableList"], ["ChromaticPolynomial", "GraphTheory:-ChromaticPolynomial(ExtractGraph(%EXPR),%ARG1)", simplegraph, entry_generator = "GraphTheoryPolynomialVariableList"], ["FlowPolynomial", "GraphTheory:-FlowPolynomial(ExtractGraph(%EXPR),%ARG1)", simplegraph, entry_generator = "GraphTheoryPolynomialVariableList"], ["SpanningPolynomial", "GraphTheory:-SpanningPolynomial(ExtractGraph(%EXPR),%ARG1)", simplegraph, entry_generator = "GraphTheoryPolynomialVariableList"], submenu=["Graph polynomials"]); CM[Entries][AddMultiple]( ["AdjacencyMatrix", "GraphTheory:-AdjacencyMatrix(ExtractGraph(%EXPR))", graphsymbol], ["AllPairsDistance", "GraphTheory:-AllPairsDistance(ExtractGraph(%EXPR))", graphsymbol], ["ArticulationPoints", "GraphTheory:-ArticulationPoints(ExtractGraph(%EXPR))", undirectedgraphsymbol], ["BiconnectedComponents", "GraphTheory:-BiconnectedComponents(ExtractGraph(%EXPR))", graphsymbol], ["BipartiteMatching", "GraphTheory:-BipartiteMatching(ExtractGraph(%EXPR))", undirectedgraphsymbol], ["ConnectedComponents", "GraphTheory:-ConnectedComponents(ExtractGraph(%EXPR))", undirectedgraphsymbol], ["CycleBasis", "GraphTheory:-CycleBasis(ExtractGraph(%EXPR))", undirectedgraphsymbol], ["Edges", "GraphTheory:-Edges(ExtractGraph(%EXPR))", graphsymbol], ["GraphComplement", "GraphTheory:-GraphComplement(ExtractGraph(%EXPR))", graphsymbol], ["GraphPower", "GraphTheory:-GraphPower(ExtractGraph(%EXPR),%ARG1)", unweightedgraph, entry_generator=proc() [["2",[2]],["3",[3]],["4",[4]]] end], ["GraphSpectrum", "GraphTheory:-GraphSpectrum(ExtractGraph(%EXPR))", graphsymbol], ["IndicenceMatrix", "GraphTheory:-IncidenceMatrix(ExtractGraph(%EXPR))", graphsymbol], ["LineGraph", "GraphTheory:-LineGraph(ExtractGraph(%EXPR))", undirectedgraphsymbol], ["MaximumClique", "GraphTheory:-MaximumClique(ExtractGraph(%EXPR))", graphsymbol], ["MaxFlow", "GraphTheory:-MaxFlow(ExtractGraph(%EXPR),%ARG1,%ARG2)", weightednetworksymbol, entry_generator=proc(G) local N, sources,sinks, i,j, m,n; N := preprograph(G); sources,sinks := GraphTheory:-IsNetwork(N); # sources and sinks are non-empty sets (m,n) := (nops(sources),nops(sinks)); while m*n > 12 do if m>n then m := m-1; else n := n-1 fi; od; (sources,sinks) := (sources[1..m], sinks[1..n]); [seq( seq( [sprintf("source(%d), sink(%d)",i,j), [i,j]], i=sources ), j=sinks )]; end], ["MinimalSpanningTree", "GraphTheory:-MinimalSpanningTree(ExtractGraph(%EXPR))", undirectedgraphsymbol], ["Mycielski", "GraphTheory:-Mycielski(ExtractGraph(%EXPR))", simplegraph], ["Neighbors", "GraphTheory:-Neighbors(ExtractGraph(%EXPR))", graphsymbol], ["OptimalEdgeColoring", "GraphTheory:-OptimalEdgeColoring(ExtractGraph(%EXPR))", undirectedgraphsymbol], ["OptimalVertexColoring", "GraphTheory:-OptimalVertexColoring(ExtractGraph(%EXPR))", undirectedgraphsymbol], ["SeidelSpectrum", "GraphTheory:-SeidelSpectrum(ExtractGraph(%EXPR))", graphsymbol], ["SpanningTree", "GraphTheory:-SpanningTree(ExtractGraph(%EXPR))", undirectedgraphsymbol], ["StronglyConnectedComponents", "GraphTheory:-StronglyConnectedComponents(ExtractGraph(%EXPR))", digraphsymbol], ["TopologicSort", "GraphTheory:-TopologicSort(ExtractGraph(%EXPR))", acyclicdigraphsymbol], ["TravelingSalesman", "GraphTheory:-TravelingSalesman(ExtractGraph(%EXPR))", graphsymbol], ["UnderlyingGraph", "GraphTheory:-UnderlyingGraph(ExtractGraph(%EXPR))", digraphsymbol], ["VertexConnectivity", "GraphTheory:-VertexConnectivity(ExtractGraph(%EXPR))", graphsymbol], ["Vertices", "GraphTheory:-Vertices(ExtractGraph(%EXPR))", graphsymbol], ["WeightMatrix", "GraphTheory:-WeightMatrix(ExtractGraph(%EXPR))", weightedgraphsymbol], submenu=["Graph commands"]); CM[Entries][AddMultiple]( ["ChromaticIndex", "GraphTheory:-ChromaticIndex(ExtractGraph(%EXPR))", simplegraph], ["ChromaticNumber", "GraphTheory:-ChromaticNumber(ExtractGraph(%EXPR))", simplegraph], ["CliqueNumber", "GraphTheory:-CliqueNumber(ExtractGraph(%EXPR))", simplegraph], ["Diameter", "GraphTheory:-Diameter(ExtractGraph(%EXPR))", graphsymbol], ["EdgeChromaticNumber", "GraphTheory:-EdgeChromaticNumber(ExtractGraph(%EXPR))", simplegraph], ["EdgeConnectivity", "GraphTheory:-EdgeConnectivity(ExtractGraph(%EXPR))", simplegraph], ["Girth", "GraphTheory:-Girth(ExtractGraph(%EXPR))", undirectedgraphsymbol], ["GraphRank", "GraphTheory:-GraphRank(ExtractGraph(%EXPR))", undirectedgraphsymbol], ["IndependenceNumber", "GraphTheory:-IndependenceNumber(ExtractGraph(%EXPR))", simplegraph], ["IsAcyclic", "GraphTheory:-IsAcyclic(ExtractGraph(%EXPR))", digraphsymbol, 'autoassign'=false], ["IsBiconnected", "GraphTheory:-IsBiconnected(ExtractGraph(%EXPR))", simplegraph, 'autoassign'=false], ["IsBipartite", "GraphTheory:-IsBipartite(ExtractGraph(%EXPR))", graphsymbol, 'autoassign'=false], ["IsClique", "GraphTheory:-IsClique(ExtractGraph(%EXPR))", undirectedgraphsymbol, 'autoassign'=false], ["IsConnected", "GraphTheory:-IsConnected(ExtractGraph(%EXPR))", undirectedgraphsymbol, 'autoassign'=false], ["IsDirected", "GraphTheory:-IsDirected(ExtractGraph(%EXPR))", graphsymbol, 'autoassign'=false], ["IsEulerian", "GraphTheory:-IsEulerian(ExtractGraph(%EXPR))", graphsymbol, 'autoassign'=false], ["IsForest", "GraphTheory:-IsForest(ExtractGraph(%EXPR))", undirectedgraphsymbol, 'autoassign'=false], ["IsVertexColorable", "GraphTheory:-IsVertexColorable(%EXPR,%ARG1)", graphsymbol, entry_generator=proc() [["2",[2]],["3",[3]],["4",[4]],["5",[5]],["6",[6]]] end], ["IsEdgeColorable", "GraphTheory:-IsEdgeColorable(%EXPR,%ARG1)", undirectedgraphsymbol, entry_generator=proc() [["2",[2]],["3",[3]],["4",[4]],["5",[5]],["6",[6]]] end], ["IsNetwork", "[GraphTheory:-IsNetwork(ExtractGraph(%EXPR))]", digraphsymbol, 'autoassign'=false], ["IsHamiltonian", "GraphTheory:-IsHamiltonian(ExtractGraph(%EXPR))", graphsymbol, 'autoassign'=false], ["IsPlanar", "GraphTheory:-IsPlanar(ExtractGraph(%EXPR))", graphsymbol, 'autoassign'=false], ["IsRegular", "GraphTheory:-IsRegular(ExtractGraph(%EXPR))", graphsymbol, 'autoassign'=false], ["IsStronglyConnected", "GraphTheory:-IsStronglyConnected(ExtractGraph(%EXPR))", digraphsymbol, 'autoassign'=false], ["IsTree", "GraphTheory:-IsTree(ExtractGraph(%EXPR))", undirectedgraphsymbol, 'autoassign'=false], ["IsTwoEdgeConnected", "GraphTheory:-IsTwoEdgeConnected(ExtractGraph(%EXPR))", undirectedgraphsymbol, 'autoassign'=false], ["IsWeighted", "GraphTheory:-IsWeighted(ExtractGraph(%EXPR))", graphsymbol, 'autoassign'=false], ["MaximumDegree", "GraphTheory:-MaximumDegree(ExtractGraph(%EXPR))", undirectedgraphsymbol], ["MinimumDegree", "GraphTheory:-MinimumDegree(ExtractGraph(%EXPR))", undirectedgraphsymbol], submenu=["Graph properties"]); CM[Entries][AddMultiple]( ["AntiPrism", "SpecialGraphs:-AntiPrismGraph(%ARG1,1)", graphsymbol, entry_generator=proc() [["4",[4]],["5",[5]],["6",[6]],["7",[7]]] end], ["Clique", "CompleteGraph(%ARG1)", graphsymbol, entry_generator=proc() [["3",[3]],["4",[4]],["5",[5]],["6",[6]]] end], ["Cube", "SpecialGraphs:-HypercubeGraph(3)", graphsymbol], ["Cycle", "CycleGraph(%ARG1)", graphsymbol, entry_generator=proc() [["3",[3]],["4",[4]],["5",[5]],["6",[6]],["7",[7]]] end], ["Dodecahedron", "SpecialGraphs:-DodecahedronGraph()", graphsymbol], ["Grid", "SpecialGraphs:-GridGraph(%ARG1,%ARG2)", graphsymbol, entry_generator=proc() [["3 by 3",[3,3]],["3 by 4",[4,3]],["4 by 4",[4,4]], ["2 by 3",[3,2]],["2 by 4",[4,2]],["2 by 5",[5,2]], ["5 by 3",[3,5]],["5 by 4",[4,5]],["5 by 5",[5,5]]] end], ["Hypercube", "SpecialGraphs:-HypercubeGraph(%ARG1)", graphsymbol, entry_generator=proc() [["2",[2]],["3",[3]],["4",[4]],["5",[5]],["6",[6]]] end], ["Icosahedron", "SpecialGraphs:-IcosahedronGraph()", graphsymbol], ["Octahedron", "SpecialGraphs:-OctahedronGraph()", graphsymbol], ["Prism", "SpecialGraphs:-PrismGraph(%ARG1,1)", graphsymbol, entry_generator=proc() [["3",[3]],["4",[4]],["5",[5]],["6",[6]],["7",[7]]] end], ["Soccer ball", "SpecialGraphs:-SoccerBallGraph()", graphsymbol], ["Tetrahedron", "SpecialGraphs:-TetrahedronGraph()", graphsymbol], ["Torus grid", "SpecialGraphs:-TorusGridGraph(%ARG1,%ARG2)", graphsymbol, entry_generator=proc() [["3 by 3",[3,3]],["4 by 3",[4,3]],["5 by 3",[5,3]],["6 by 3",[6,3]]] end], ["Spider web", "SpecialGraphs:-WebGraph(8,3)", graphsymbol], ["Wheel", "SpecialGraphs:-WheelGraph(%ARG1)", graphsymbol, entry_generator=proc() [["4",[4]],["5",[5]],["6",[6]],["7",[7]],["8",[8]]] end], submenu=["Standard graphs"]); CM[Entries][AddMultiple]( ["Clebsch graph", "SpecialGraphs:-ClebschGraph()", graphsymbol], ["Complete binary tree", "SpecialGraphs:-CompleteBinaryTree(%ARG1)", graphsymbol, entry_generator=proc() [["2",[2]],["3",[3]],["4",[4]],["5",[5]]] end], ["Complete k-ary tree", "SpecialGraphs:-CompleteKaryTree(3,3)", graphsymbol], ["Complete graph", "CompleteGraph(%ARG1)", graphsymbol, entry_generator=proc() [["3",[3]],["4",[4]],["5",[5]],["6",[6]]] end], ["Desargues graph", "SpecialGraphs:-DesarguesGraph()", graphsymbol], ["Double star snark", "SpecialGraphs:-DoubleStarSnark()", graphsymbol], ["Dyck graph", "SpecialGraphs:-DyckGraph()", graphsymbol], ["Flower snark", "SpecialGraphs:-FlowerSnark(%ARG1)", graphsymbol, entry_generator=proc() [["3",[3]],["5",[5]],["7",[7]],["9",[9]]] end], ["Foster graph", "SpecialGraphs:-FosterGraph()", graphsymbol], ["Goldberg snark", "SpecialGraphs:-GoldbergSnark(%ARG1)", graphsymbol, entry_generator=proc() [["3",[3]],["5",[5]],["7",[7]]] end], ["Grinberg graph", "SpecialGraphs:-GrinbergGraph()", graphsymbol], ["Grotzsch graph", "SpecialGraphs:-GrotzschGraph()", graphsymbol], ["Heawood graph", "SpecialGraphs:-HeawoodGraph()", graphsymbol], ["Herschel graph", "SpecialGraphs:-HerschelGraph()", graphsymbol], ["Kneser graph", "SpecialGraphs:-KneserGraph(5,2)", graphsymbol], ["Levi graph", "SpecialGraphs:-LeviGraph()", graphsymbol], ["Mobius Kantor graph", "SpecialGraphs:-MobiusKantorGraph()", graphsymbol], ["Pappus graph", "SpecialGraphs:-PappusGraph()", graphsymbol], ["Petersen graph", "SpecialGraphs:-PetersenGraph()", graphsymbol], ["Shrikhande graph", "SpecialGraphs:-ShrikhandeGraph()", graphsymbol], ["Szekeres snark", "SpecialGraphs:-SzekeresSnark()", graphsymbol], submenu=["Special graphs"]); Install(CM); end use: