# Define an operator with the distributive property

I would like to define the ⊕ operator with distributive, associative, and commutative properties - so that Mathematica can symbolically simplify expressions I use it in. For example:

in := Simplify[a b ⊕ a c]
out := a (b ⊕ c)


I've already given the ⊕ operator the Flat and Orderless attributes, giving the operator the other two properties I would like, but I can't figure distribution out.

Specifically, what I'm trying to do is define an operator which has the symbolic properties of Plus, but which does not evaluate against numbers, e.g

in := 2⊕2
out := 2⊕2


is a fully simplified expression.

• What should be the output of Simplify[2 a b\[CirclePlus]a c\[CirclePlus]a d] or Simplify[2 + a b\[CirclePlus]a c\[CirclePlus]a d]? – Karsten 7. Sep 15 '15 at 23:21

This would perhaps do what you want:

CirclePlus /:
Simplify[CirclePlus[pre___, a_ b_, mid___, a_ c_, post___]] :=
Simplify@Apply[CirclePlus,
Simplify /@ {pre, mid, a Simplify[CirclePlus[b, c]], post}]


Since Distribute by default only works with Plus, I associate the distributive property with CirclePlus manually when Simplify is applied. I then allow Simplify to be applied recursively to the result.

Edit

Thanks to Karsten 7 for pointing out that the special case of CirclePlus with a single argument should also be handled. The Flat attribute by itself doesn't do that because it only kicks in at the pattern recognition stage and not as a simplification rule. So you could add the following:

CirclePlus[x : Except[_CirclePlus]] := x

Simplify[a b⊕a c]

(* ==> a (b⊕c) *)


I added the Except condition in case you already gave CirclePlus the Flat attribute of Plus.

• Wow I didn't think their was a way. – William Sep 15 '15 at 23:20
• I get CirclePlus[a (b\[CirclePlus]c)] as the output for Simplify[a b\[CirclePlus]a c] using your code. – Karsten 7. Sep 15 '15 at 23:22
• @Karsten7. Yes, that's what I intended. It's consistent with the operator precedence rules. – Jens Sep 15 '15 at 23:25
• But that is not the expected output shown in the example. Are you assuming CirclePlus[x_] := x? Also one should not give CirclePlus the attribute Flat as the OP did. – Karsten 7. Sep 15 '15 at 23:50
• @Karsten7. Indeed, I forgot about that. Now it should be fixed. – Jens Sep 16 '15 at 2:46