I essentially have something of the form

pm[1, 2] pm[3, 4] pm[5, 6] c[{1, 2, 5, 6}, "+"] c[{3, 4}, "-"]

I want to add next to each pm a corresponding plus or minus; so I want to have an expression that looks like

pm[1, 2]["+"] pm[3, 4]["-"] pm[5, 6]["+"] c[{1, 2, 5, 6}, "+"] c[{3, 4}, "-"]

Does anybody know a simple way to do this? My problem is that I'm not sure how to access the indices in the "c" and match them up with my list entries for each pm;

Edit: so here's a bit of an explanation of what is going on. I need to code the multiplication of two diagrams which looks like this:


So the first cycle will have the representation in code of


while the second will look like


So the "pp"s represent that matchings on top while the "pm"s represent the matchings on bottom. Each "c" tells me I have a cycle, as well as which vertices are in the cycle and if the cycle has been assigned a plus or minus.

So here's how the multiplication works; the bottom of the first and the top of the second get ignored, and I just get back the top of the first combined with the bottom of the second, with some replacement rules for the plus/minuses. Specifically,

$$(+,+)\to+$$ $$(+,-)\to -$$ $$(-,+)\to -$$ $$(-,-)\to 0$$

So the reason we get a minus out, is that between vertices 1 and 2 we get $(+,+)\to+$ and between 3 and 4 we get $(+,-)\to -$ and then overall we are left with $(+,-)\to-$ for the single cycle. So the way to get the "pp/pm" structure of the result is simple; I just ignore what I don't need. I need the "c" structures to tell me where my plus and minuses are. So what I'd ideally like my code to do is take our two inputs from the picture, and give me


which I can then use to do some combining and give me a final result of


Yes I know this is long and convoluted. I'm also pretty new to Mathematica so if you think my whole approach is awful don't be afraid to tell me.

NOTE: I forgot to mention there may be an arbitrary (but always even) number of vertices. I just used four vertices in my example because it was simplest.

  • 2
    $\begingroup$ Quite a strange requirement. Do you mind explaining why do you want to do this ? Perhaps there is a more standard way ... $\endgroup$ Commented Oct 15, 2015 at 21:09
  • $\begingroup$ ...Right: does it never happen that there exists a pm[a, b] where a is in c[... "+"] and b is in c[... "-"]? If that's not the case, I suspect that there's way to simplify your "data structure". $\endgroup$
    – march
    Commented Oct 15, 2015 at 21:12
  • $\begingroup$ @march no, that'll never happen by the nature of this program. $\endgroup$ Commented Oct 15, 2015 at 21:14
  • 1
    $\begingroup$ I posted an answer, but I recommend delaying accepting it until other answerers chime in with better answers and/or until you update your post with the explanation so that we can figure out the best way of going about doing things. $\endgroup$
    – march
    Commented Oct 15, 2015 at 21:22
  • 1
    $\begingroup$ Please beware that Times is Orderless, so your expression could get reordered automagically $\endgroup$ Commented Oct 16, 2015 at 3:09

1 Answer 1


Here's one solution, taking into account the fact that p[a, b] where a corresponds to "+" and b corresponds to "=" (for instance) never happens:

rules = Flatten@Cases[expr, c[a_, b_] :> Thread[a -> b], Infinity]
expr /. pm[a_, b_] :> pm[a, b][a /. rules]
  • $\begingroup$ I went ahead and edited my post. $\endgroup$ Commented Oct 15, 2015 at 21:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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