Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Here is a minimal example of the problem I am having.

f[a___, b_, c_, d___] /; Not@OrderedQ[{b, c}] := h[b,c]f[a, c, b, d]
f[b, a, B, c, A]
SetAttributes[g, Flat]
g[a___, b_, c_, d___] /; Not@OrderedQ[{b, c}] := h[b,c]g[a, c, b, d]
g[b, a, B, c, A]

The f function works great. The g function goes into an infinite loop. How can I work around this problem? Perhaps an alternative to the Flat attribute or some other way of defining the commutation relation?

By the way, I set the attribute Flat because G[b, a, B, c, A] is often built up as follows:

SetAttributes[G, Flat]
G[b, G[G[a, B, c], A]]

Thanks to @alephalpha for explaining what the problem is and suggesting the following fix. EDIT: Actually the implementation below still runs an infinite loop on the second test cases below, independent of the order of definitions. EDIT: found a fix for that loop.

(* Flatten g instead of declaring Flat attribute *)
(* The next line was a failed attempt and gets overwritten *)
g[a___, b_g, c___] := Flatten[g[a, b, c]]
(* This line works *)
g[a___, b_g, c___] := Module[{temp},
  temp = Flatten[Hold@g[a, b, c], \[Infinity], g] // Release]
g[a___, b_, c_, d___] /; Not@OrderedQ[{b, c}] := h[b, c] g[a, c, b, d]
g[b, a, B, c, A]
g[b, g[g[a, B, c], A]]

I am not sure how this will affect the pattern matching of other definitions, so I will leave the question open to see what others come up with and possibly get a discussion of the pros and cons of Flat vs Flatten.

share|improve this question

1 Answer 1

up vote 2 down vote accepted

This is a problem of pattern-matching.

When Mathematica evalutes the expression g[b, a, B, c, A], it attempts to apply any transformation rules for g. Here the transformation rule is:

g[a___, b_, c_, d___] /; Not@OrderedQ[{b, c}] :> h[b, c] g[a, c, b, d]

So Mathematica will find out the pattern that match g[a___, b_, c_, d___] /; Not@OrderedQ[{b, c}]. But g has the attribute Flat, so g[b, a, B, c, A] is the same as g[g[b], g[a], B, c, A]. So the first pattern Mathematica finds to match the pattern is g[g[b], g[a], B, c, A]. So it gets:

h[g[b], g[a]]g[g[a], g[b], B, c, A]

Of course, it is the same as:

h[g[b], g[a]] g[a, b, B, c, A]

Then Mathematica continues to evaluate g[a, b, B, c, A], which is the same as g[g[a, b], g[B], c, A]. OrderedQ[{g[a, b], g[B]}] returns False because g[a,b] has two arguments while g[B] has one. So it gets:

h[g[b], g[a]] h[g[a, b], g[B]] g[g[B], g[a, b], c, A]

which is the same as:

h[g[b], g[a]] h[g[a, b], g[B]] g[B, a, b, c, A]

Then Mathematica evaluates g[B, a, b, c, A] and gets:

h[g[b], g[a]] h[g[a, b], g[B]] h[g[a], g[B]] g[a, B, b, c, A]

But g[a, B, b, c, A] is the same as g[g[a, B], g[b], c, A]. So it gets:

h[g[b], g[a]] h[g[a, b], g[B]] h[g[a], g[B]] h[g[a, B], g[b]] g[b, a, B, c, A]

So it goes into an infinite loop.


You can use

Flatten[G[b, G[G[a, B, c], A]]] /. G -> f
share|improve this answer
    
I am not accustomed to Flatten anything other than List. Thanks for pointing it out. I updated the question to show my interpretation of your suggestion. Do you see any secondary effects coming from replacing the Flat attribute with the Flatten function? –  Timothy Wofford Oct 21 '13 at 7:40

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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