I thought that Mathematica would be smart enough to know that f[t]^2 should match a_ * b_ with a and b both taking the value f[t], but it doesn't.

I'm writing some rules for identities involving products. It's mainly finding different ways of doing integration by parts. Am I forced to write separate rules for handling powers, or can Mathematica be persuaded to matchf[t]^2 as a_ * b_?

I would like to handle arbitrarily large natural powers, so f[t]^3 should match a_ * b_ with a as f[t] and b as f[t]^2, or vice versa. f[t]^4 should match as both f[t] * f[t]^3 and f[t]^2 * f[t]^2. I'm using ReplaceList, so the order is unimportant. I want the behaviour to be identical to if the powers were represented as f[t] * f[t] * f[t] ....

If not, is there a nice single pattern I can use to match all cases? I've been looking at Alternatives, but I don't know how to capture the a and b values properly when dealing with the powers forms.

  • 1
    $\begingroup$ The former has a head Power while the latter Times. Seen from this single fact, they two do not match of course. It is not a matter of being smart or not. Pattern matching is performed based on the form of an expression, not its (mathematical) meaning. Using jargon, pattern matching is performed syntactically, not semantically. $\endgroup$ – Αλέξανδρος Ζεγγ Feb 23 '20 at 11:32
  • $\begingroup$ @ΑλέξανδροςΖεγγ I understand that. There are attributes like Flat that allow semantic matching that deviates from those strict rules and I assumed that there would be similar special handling for Power, although I realise now that there isn't. That's quite inconvenient, because when I have an expression featuring a * b, and a happens to equal b at some point, MMA automatically transforms it into a power, then all of my rules stop working. Do you know of any concise pattern that is able to match either form interchangably while giving the a and b values? $\endgroup$ – Sam Feb 23 '20 at 11:41
  • $\begingroup$ Two suggestions. You can try to use functions like Hold, Unevaluated, etc. to stop MMA from evaluations before matchings; because MMA "thinks" Power is simpler than Times when multiplying factors are the same. Or why do you not just using Power to construct the matching rules? $\endgroup$ – Αλέξανδρος Ζεγγ Feb 23 '20 at 11:52
  • $\begingroup$ @ΑλέξανδροςΖεγγ I can write matching rules directly using Power, but they would be duplicates of ones I've already written that use Times. Although I'm not sure how to get the exact functionality I need. I'm using ReplaceList to get every possible match with a_ * b_, but I don't know how to write a rule for Power that gives all of the different forms of f[t]^4 like f[t] * f[t]^3 and f[t]^2 * f[t]^2. The best idea I have is to do this in two stages, first transforming all Times and Power into a new head myTimes then doing my matching against that. That feels like a hack. $\endgroup$ – Sam Feb 23 '20 at 12:03
  • $\begingroup$ @ΑλέξανδροςΖεγγ I don't think I can easily use Hold etc, because I'm passing these expressions through other functions that transform them too. I'll have another read of the docs in case I'm missing something that I could do there. $\endgroup$ – Sam Feb 23 '20 at 12:05

By replacing multiplication with NonCommutativeMultiply, which is an associative but noncommutative symbol with no built-in meaning, you can preprocess your expressions in the desired explicit form:

expr = a^3 + b c (1 + c + c^2);

A = Expand[expr] /. {Times -> NonCommutativeMultiply,
                     x_^n_Integer :> NonCommutativeMultiply @@ ConstantArray[x, n]}

(*    b ** c + a ** a ** a + b ** c ** c + b ** c ** c ** c    *)

From here you can continue applying your rules by pattern-matching, for example

A /. {x_ ** y_ ** z_ ** w_ :> func4[x, y, z, w],
      x_ ** y_ ** z_ :> func3[x, y, z],
      x_ ** y_ :> func2[x, y]}

(*    func2[b, c] + func3[a, a, a] + func3[b, c, c] + func4[b, c, c, c]    *)
  • $\begingroup$ Thanks! I've marked this as the answer because it does get me what I need. It's similar to the method I already mentioned in the comments, and I had hoped for something more concise that didn't involve multiple steps and transforming the expression before matching against it. If somebody is able to provide a better answer I'll probably switch to accepting that, but I think this is probably about as good as it gets. It feels like an oversight that MMA doesn't have an attribute similar to Flat and Orderless to support this automatically out of the box. $\endgroup$ – Sam Feb 23 '20 at 20:47

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.