3
$\begingroup$

If I have

f0 = f[x,y,z]

and I am interested in the list of the arguments, what I do is

In[1]:= args = Apply[ List, f0 ]
Out[1]= {x, y, z}

Apparently this doesn't work with the function "Graph"

In[2]:= gr = CycleGraph[3];

In[3]:= gr // InputForm

Out[3]//InputForm= 
  Graph[{1, 2, 3}, 
  {UndirectedEdge[1, 2], UndirectedEdge[2, 3], UndirectedEdge[3, 1]}, 
  {VertexCoordinates -> {{0.8660254037844388, -0.4999999999999998},
  {-0.8660254037844384, -0.5000000000000004}, {-2.4492935982947064*^-16, 1.}}}]

When I try

args = Apply[ List, gr ]

what happens is that the graph is drawn and that's it. The following doesn't work either

args = Apply[ List, InputForm[gr] ]

Any explanation or workaround?

$\endgroup$
  • 1
    $\begingroup$ Since Graph[] is an atomic object (see this related thread), you cannot use things like Apply[] or Part[] on it. Instead, use VertexList[] and EdgeList[] to extract vertices and edges, respectively. Additionally, look up PropertyValue[]. Someone else might want to write an elaboration of this comment. $\endgroup$ – J. M.'s discontentment Feb 24 '16 at 14:13
  • $\begingroup$ Welcome to Mathematica.SE! 1) As you receive help, try to give it too, by answering questions in your area of expertise. 2) Take the tour and check the faqs! 3) When you see good questions and answers, vote them up by clicking the gray triangles, because the credibility of the system is based on the reputation gained by users sharing their knowledge. Also, please remember to accept the answer, if any, that solves your problem, by clicking the checkmark sign! $\endgroup$ – user9660 Feb 24 '16 at 14:47
3
$\begingroup$

Graph is an atomic expression. It is not a Mathematica expression made up of a head and multiple "arguments", even though sometimes it vaguely looks like one. Instead you should treat it as an indivisible unit.

Use VertexList, EdgeList, PropertyValue, etc. to extract information from it.


We should distinguish between a truly atomic Graph object, and a compound expression with head Graph. When you type Graph[{1,2,3},{1<->2}] in Mathematica, you are indeed writing a compound expression which can be manipulated like any other. For example:

g = Hold@Graph[{1, 2, 3}, {1 <-> 2}]
(* Hold[Graph[{1, 2, 3}, {1 <-> 2}]] *)

g[[1, 1]]
(* {1, 2, 3} *)

However, this compound expression immediately evaluates to an atomic Graph:

AtomQ@ReleaseHold[g]
(* True *)

After that it is no longer possible to access its parts (because it has no parts).

As you can see, not every expression with Head Graph is an atomic Graph object. To test if one is, use the GraphQ function. For example:

GraphQ@Graph[{1, 2, 3}, {2 <-> 3}]
(* True *)

GraphQ@Graph[asd]
(* False *)

Graph[asd] is not a valid way to construct a graph, so instead of evaluating to a true graph, it stays as a compound expression.


To make this answer complete, I should note that atomic Graph objects do in fact have a representation as a compound expression, but these are not meant to be used by end users. They are used internally for serialization, such as storing a graph in a notebook, sending it through MathLink, Compressing it, etc. See my two answers here on how to get to it.

Since these representations are not meant for end users, they are undocumented (meaning that you might easily encounter unexpected forms – don't assume that inspecting one graph tells you how others are represented) and may be different between different Mathematica versions.

| improve this answer | |
$\endgroup$
  • $\begingroup$ It's more or less clear now. It felt kind of funny that I could print, using InputForm, the argument list on the display of my PC and assign it to a variable using a mouse with cut and paste, but I could not do it programmatically... :-) $\endgroup$ – brian0 Feb 24 '16 at 14:51
  • $\begingroup$ @brian0 Well, you can do it programmatically with the tricks I linked to, but it's really not a good idea (other than looking at it for curiosity). I looked at Graph and as I remember I found at least three different representations. If you're interested in poking around in the internals, also check out GraphComputation`GraphRepresentation and GraphComputation`ToGraphRepresentation. I looked at these because I was desperate to find a faster way to transfer graphs to LibraryLink in some form for IGraph/M). But eventually I gave up on it ... $\endgroup$ – Szabolcs Feb 24 '16 at 14:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.