# Can you explain this substitution rule?

This rule behaves as I expect:

b . c + a . b . c /. (b . c) -> x
(* x + a . x *)


I would expect the same result with this:

b . c + a . b . c /. (b . c | c . b) -> x
(* x + a . b . c *)


Can you explain why I am wrong? (I know the brackets are redundant, but they make it a little easier to read)

EDIT

As @Syed suggests, there are simple ways of fixing the problem e.g.

b . c + a . b . c /. y___ . b . c :> y . x
(* x + a . x *)


However, to avoid difficulties in debugging complex sets of replacement rules, it's better to avoid these problems, rather than fix them afterwards. How should I have known that my rule wouldn't work?

FURTHER EDIT

This effect is not specific to Dot, but appears to apply generally to functions with the attribute Flat. For example, with

SetAttributes[g, Flat]


a simple pattern matches:

g[b, c] + g[a, b, c, d] /. g[b, c] -> x
(* x + g[a, x, d] *)


while alternatives do not:

g[b, c] + g[a, b, c, d] /. g[b, c] | g[c, b] -> x
(* x + g[a, b, c, d] *)


Is this behaviour documented anywhere?

• b . c + a . b . c /. y___ . b . c -> y . x ?
– Syed
Commented Dec 1, 2023 at 14:25
• I do not know what the alternative does not work. It looks like a bug to me. But you can replace the alternative by 2 Re[placeAll like: a1 . b . c + a2 . c . b /. b . c -> x /. c . b -> x This results in: a1 . x + a2 . x Commented Dec 1, 2023 at 16:26
• So why does (a . b . c /. (b . c ) -> x) replace, whereas (a . b . c /. (b . c | c . b) -> x) doesn't, and neither does Replace[ a . b . c, (b . c -> x),{1}] ( nor Replace[ a . b . c, (b . c | c . b) -> x,{1}])? Commented Dec 2, 2023 at 10:36
• Using Dispatch may be another alternative: b . c + a . b . c + d . c . b /. Dispatch[{b . c | c . b -> x}] gives (* x + a . x + d . x *) Commented Dec 2, 2023 at 23:21
• This is a long-standing weakness. I looked into it a couple of times and came to the conclusion that we should document it under Possible Issues for both Alternatives and Flat. Commented May 2 at 20:26

Its simply so, that Alternatives are not identified a subsequences

     Position[b . c + a . b . c, (b . c | c . b), \[Infinity]]

{{1}}

Position[ b . c + a . b . c, (b . c | c . b | ___ . b . c . ___),
\[Infinity]]

{{1}, {2}}


The reason for this behaviour: sequences are not considered as expressions. Even in this simple case its a complex task to identify the position of a pair inside an argument sequence.

The logical decision for this behaviour is to avoid, generally, modifications to the right of inner leafs of a tree and to limit the search tree depth in normal cases, where only algebraic parts of an expression are renamed.

Reorganizing argument sequences is not a branch of mathematics but a kind of string manipulation, the reason why natural languages are more powerful but slightly less logical than mathematics.

• This doesn't answer the question. What's matched here is not sequence. Please read the first example in the question carefully. Dot (.) behaves like this because it owns the attribute Flat. Commented Dec 3, 2023 at 6:59
• No, try $$a\cdot b\cdot c\text{/.}\, b\cdot c|c\cdot b\to x$$ with no attributes. Subsequence not identified. Commented Dec 3, 2023 at 9:17
• Once again, please check the behavior of first example i.e. b . c + a . b . c /. (b . c) -> x (* returns x + a . x *) carefully. With · (\[CenterDot]), the first example won't "work", either: b·c + a·b·c /. b·c -> x (*returns x + a·b·c *) Commented Dec 3, 2023 at 9:23
• If you're not familiar with the attribute Flat, check e.g. verbeia.com/mathematica/tips/Tricks.html (The notebook version is here: library.wolfram.com/infocenter/MathSource/4557 ) Commented Dec 3, 2023 at 9:25
• I am familiar with anything since the first attemtps of Wolfram, sorry. The Replace actions were always full of surprises, bomb shells and shutdowns and students in despair. This is not very different from the methods used by mathematicians and physicists with pencil and paper. Its not worth the work to identify the rules, that are not documented and not constant over versions, Use clear Patterns and nothing open to interpretation. Commented Dec 3, 2023 at 9:48