I am building a tool to manipulate Feynman diagrams and depict them using the Graph
functionality. A diagram might have the following syntax
f=diag[g[a,i[1]],g[b,i[2]],g[i[1],c],g[i[2],d],v[i[1],i[2]]]
This is just an example. Now we would like to represent it as a graph.
First way (using RuleDelayed
):
Clear[pic]
pic[diag[x__]]:=Module[{i},Graph[List[x]/.{g[i_,j_]:> DirectedEdge[j,i],v[j_,k_]:> UndirectedEdge[j,k]},VertexLabels->"Name",PlotTheme->"Business",ImageSize->300,ImagePadding->10,VertexLabelStyle->Directive[Black,11],GraphHighlight->Cases[List[x],v[i_,j_]:> UndirectedEdge[i,j]]]]
Using it
pic[f]
i=5;
pic[f]
produces
Thus we have an expected result and a result with wrong labels.
Second way (using Rule
)
Clear[i,g,v,f]
f=diag[g[a,i[1]],g[b,i[2]],g[i[1],c],g[i[2],d],v[i[1],i[2]]];
Clear[pic]
pic[diag[x__]]:=Module[{i,j,k},Graph[List[x]/.{g[i_,j_]->DirectedEdge[j,i],v[j_,k_]->UndirectedEdge[j,k]},VertexLabels->"Name",PlotTheme->"Business",ImageSize->300,ImagePadding->10,VertexLabelStyle->Directive[Black,11],GraphHighlight->Cases[List[x],v[i_,j_]->UndirectedEdge[i,j]]]]
Now using it
pic[f]
i=5;
pic[f]
Produces the correct picture only the first time, and does not work at all second time.
RuleDelayed
solves your problem in the second snippet. It is true thatRule
treats named pattern as local to the rule. However in the second snippet, the right-hand side gets evaluated toTimes[2, 5]
before any replacing takes place.RuleDelayed
first performs replacements, and then evaluates the expression on the right-hand side of the rule. I am still confused about the first snippet, though. $\endgroup$SetDelayed
is not relevant here. The confusing part is this:Clear[i, x]; i = n; Module[{i}, x /. {i_ -> i}] (*n*)
. To be honest, if this is expected behavior I have understood nothing aboutModule
. $\endgroup$Module
is this "Before evaluating expr, Module substitutes new symbols for each of the local variables that appear anywhere in expr except as local variables in scoping constructs." The issue now is thatRule
is also a scoping construct (with named patterns). ThereforeModule
does not replace thei
in theRule
. $\endgroup$RuleDelayed
. This would be the "canonical way" in my opinion. $\endgroup$Rule
instead ofRuleDelayed
. In the first the problem for the label is thatf
is defined usingi
. Of course, if you later seti
it will be used for the value off
. Mathematica usually evaluates expressions unless being told to hold them. $\endgroup$