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[]}
?
ReplaceAll
tries to match some subsequence of the expression andf[a,f[b,c]|{},d]
doesn't matchf[a,b,c,d]
because it wouldn't evaluate to it? $\endgroup$Alternatives
itself theFlat
attribute, in which case your example still wouldn't evaluate tof[a,b,c,d]
. $\endgroup$f[f[a, b] | f[c, d]]
as the pattern? $\endgroup$Alternatives
is corrected/extended for your example it will still need//.
? $\endgroup$