Simple problem with pattern matching in Mathematica

460 Views Asked by At

I'm having trouble setting a pattern for simplifying a complex expression. I've distilled the question down to the simplest case where Mathematica seems to fail.

I set up a simple rule based on a pattern:

simpRule = a b v___ - c d v___ -> e v

which works on the direct case

a b - c d /. simpRule
e

but fails if I simply add a minus sign.

-a b + c d /. simpRule
-a b + c d

How do I go about writing a more robust rule? Or perhaps there's a better way to go about performing simplifications of this sort?

Thanks, Keith

3

There are 3 best solutions below

0
On BEST ANSWER

Eventually I posted the same question on MathGroup and received an answer which I think is superior to the one I posted before. I thought I should add it here.

As before, this is not strictly a replacement rule, instead it uses Mathematica's PolynomialReduce[], but it seems to be quite robust and if people come across this question they should be aware of this solution.

simpMeth[expr_] := Module[{pExpr},
  pExpr = PolynomialReduce[expr, a b - c d, {b, d}];
  pExpr[[1, 1]] e + pExpr[[2]]
 ]
2
On

Here's the best solution I've come up with so far. (Yes, I'm answering my own question, but I thought it would be nice to have some resolution to this question.)

simp[expr_] := Module[{fab,fcd,fabmcd,f0},
  {fab,fcd} = {Coefficient[expr, a b], Coefficient[expr, c d]};
  fabmcd = (1/2)(fab - fcd);
  f0 = Simplify[expr - fabmcd (a b - c d)];
  f0 + fabmcd e
]

Here's how it works:

simp[a b - c d] produces e,

simp[-a b + c d] produces -e and

simp[a b - c d + c] produces e + c.

My original intention was to make a more robust pattern rule, however I haven't figured out how to do that. Instead the solution I'm presenting here is based on using Mathematica's Coefficient[] function. In my experience, Coefficient[] and CoefficientList[] can be used to do quite sophisticated expression rearrangement. None the less, someday I'd like figure how to do sophisticated pattern matching.

3
On

You need to be aware of the FullForm of the expressions you are working with to correctly use replacement rules. Consider the FullForm of the two expressions you use ReplaceAll (/.) on:

 a b - c d // FullForm
-a b + c d // FullForm
(* Out *) Plus[Times[a, b], Times[-1, c, d]]
(* Out *) Plus[Times[-1, a, b], Times[c, d]]

From this you can see how the negation is internally represented as multiplication by -1, and therefore, why your rule matches differently. One way to allow for the alternative pattern is this:

rule = (-1 a b v___ | a b v___) + (-1 c d v___ | c d v___) -> e v;

This makes use of Alternatives.

Another, somewhat more opaque way is:

rule = (-1 ...) a b v___ + (-1 ...) c d v___ -> e v;

Which makes use of RepeatedNull.