I'm guessing a bit at what you're doing here, so I do hope some of this is relevant. Trying to define your own version of multiplication is essentially trying to implement a group structure in mathematics. Here's how I would implement the dihedral group using NonCommutativeMultiply
. At the end, you'll notice that I do need to deal with expressions like NonCommutativeMultiply[a]
.
The dihedral group of order $2n$ has presentation
$$\langle a,b : a^2=b^2=(ab)^n=1 \rangle.$$
Given a finite string of $a$s and $b$s representing an element of the dihedral group, there is a standard procedure to place that string into one of the following four canonical forms: $(ab)^m$, $(ab)^m b$, $(ba)^m$, or ($ba)^m a$, where $m$ is an integer such that $0\leq m<n$. To do so, simply remove each consecutive pair of identical symbols and then reduce the exponent of $ab$ or $ba$ modulo $n$. This solves the so called Word Problem for the dihedral group.
To implement this in Mathematica, first associate UpValues
with a
and b
representing the order of those elements.
a /: a ** a = 1;
b /: b ** b = 1;
a /: a ** 1 = a;
b /: b ** 1 = b;
a /: 1 ** a = a;
b /: 1 ** b = b;
Now, let's generate a long product of $a$s and $b$s.
SeedRandom[1];
w = NonCommutativeMultiply @@ RandomChoice[{a, b}, 100]
a ** b ** a ** b ** a ** b ** a ** b ** a ** b ** a ** b ** a ** b ** a ** b
The result is much shorter than 100 because cancellation has already occurred. Now let's put it in it's final form. Assuming you're working in $D_6$, you can do the following:
n = 3;
finalForm[w : NonCommutativeMultiply[a, ___, b]] :=
(a ** b)^Mod[Length[w]/2, n];
finalForm[w : NonCommutativeMultiply[a, ___, a]] :=
(a ** b)^Mod[(Length[w] - 1)/2, n] ** a;
finalForm[w : NonCommutativeMultiply[b, ___, a]] :=
(b ** a)^Mod[Length[w]/2, n];
finalForm[w : NonCommutativeMultiply[b, ___, b]] :=
(b ** a)^Mod[(Length[w] - 1)/2, n] ** b;
finalForm[w]
(a ** b)^2
Well, that's cool but what about this example:
finalForm[a ** a ** a]
finalForm[a]
We've run into exactly the problem you've described. To fix it, simply associate DownValues
with finalForm
.
finalForm[a] = a;
finalForm[b] = b;
finalForm[a ** a ** a]
a
More generally, you might define a function simplify
with the property that
simplify[NonCommutativeMultiply[a_]] := a
NonCommutativeMultiply
. The very purpose of this function is to allow the user to set up their own version of multiplication. It already has the attributeOneIdentity
. $\endgroup$ – Mark McClure May 3 '12 at 16:38MatchQ[b, otimes[a_]]
yields the same asMatchQ[b, Times[a_]]
. So could you state more clearly what the problem is that gives infinite recursion? $\endgroup$ – Jens May 3 '12 at 17:16