When a head has the attribute Flat then the pattern matcher is able to pick out a sublist of its arguments, even though the structure doesn't match:

SetAttributes[f, Flat];
f[a, b, c, d] /. f[a, b] -> Sequence[]
(* f[c, d] *)
f[a, b, c, d] /. f[c, d] -> Sequence[]
(* f[a, b] *)

This makes sense because the Flat attribute asserts that f[a, b, c, d] is among other things equivalent to f[f[a, b], c, d].

However, as soon as I put the shorter sublist inside Alternatives, the pattern matcher no longer seems to look for this restructuring:

f[a, b, c, d] /. f[a, b] | f[c, d] -> Sequence[]
(* f[a, b, c, d] *)

It doesn't matter here that the f[c, d] is trying to do the same thing. If I use f[a, b] | {} it doesn't match anything either.

I have tested this with Mathematica 11.0.0.

The docs of Alternatives don't seem to give away a reason why this would be the case. I found this related question but I can no longer reproduce the behaviour described there in 11.0.0.

Is this a bug or the intended behaviour? And either way, is there a better workaround than {f[a, b] -> Sequence[], f[c, d] -> Sequence[]}?

  • $\begingroup$ Is it because ReplaceAll tries to match some subsequence of the expression and f[a,f[b,c]|{},d] doesn't match f[a,b,c,d] because it wouldn't evaluate to it? $\endgroup$
    – swish
    Commented Jan 25, 2017 at 11:17
  • 1
    $\begingroup$ @swish I'm not sure. Rolf Mertig found out that it does work if you give Alternatives itself the Flat attribute, in which case your example still wouldn't evaluate to f[a,b,c,d]. $\endgroup$ Commented Jan 25, 2017 at 13:27
  • 1
    $\begingroup$ As a workaround could you use f[f[a, b] | f[c, d]] as the pattern? $\endgroup$ Commented Jan 25, 2017 at 21:09
  • $\begingroup$ @SimonWoods That doesn't work for me (I'm currently on 10.4 though, will have to test 11.0 tomorrow). $\endgroup$ Commented Jan 25, 2017 at 22:08
  • 1
    $\begingroup$ Re: Simon's workaround I think one would only expect it to remove one match? I mean even if Alternatives is corrected/extended for your example it will still need //.? $\endgroup$
    – Mr.Wizard
    Commented Jan 30, 2017 at 10:05


Your Answer

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