4
$\begingroup$

The question concerns the Notation package. I want to define notation for the function very similar to the built-in Power[a,b] function. I am trying to do it in the following way:

Needs["Notation`"];
Notation[ParsedBoxWrapper[SuperscriptBox["A_","B_"]]  \[DoubleLongLeftArrow] ParsedBoxWrapper[RowBox[{"MyPower", "[","A_", ",", "B_", "]"}]]]

It works fine with MyPower[a,c], displaying a^c. However if the case of MyPower[a+b,c], the result is a+b^c.

The question is how to make Mathematica to put parenthesis automatically, so I can get a^c in the first case and (a+b)^c in the second case.

I believe that the answer is about setting the precedence order using TagBox function with SyntaxForm argument. However, this function is rather ill-documented and I couldn't get it work.

P.S. I would like to note that automatic parenthesis placement works fine for binary operations:

Needs["Notation`"];
Notation[ParsedBoxWrapper[RowBox[{"A_", " ", "plus"  , " ", "B_"}]] \[DoubleLongLeftRightArrow] ParsedBoxWrapper[RowBox[{"MyPlus", "[", RowBox[{"A_", ",", "B_"}], "]"}]]]
Notation[ParsedBoxWrapper[RowBox[{"A_", " ", "times" , " ", "B_"}]] \[DoubleLongLeftRightArrow] ParsedBoxWrapper[RowBox[{"MyMult", "[", RowBox[{"A_", ",", "B_"}], "]"}]]]
MyPlus[a, MyMult[b, c]] (* Returns a plus (b times c) *)
MyMult[MyPlus[a, b], c] (* Returns (a plus b) times c *)

Notation[ParsedBoxWrapper[RowBox[{"A_", " ", TagBox["plus", "", SyntaxForm -> "+"], " ", "B_"}]]\[DoubleLongLeftRightArrow]ParsedBoxWrapper[RowBox[{"MyPlus", "[", RowBox[{"A_", ",", "B_"}], "]"}]]]
Notation[ParsedBoxWrapper[RowBox[{"A_", " ", TagBox["times", "", SyntaxForm -> "a"], " ", "B_"}]]\[DoubleLongLeftRightArrow]ParsedBoxWrapper[RowBox[{"MyMult", "[", RowBox[{"A_", ",", "B_"}], "]"}]]]
MyPlus[a, MyMult[b, c]] (* Returns a plus b times c *)
MyMult[MyPlus[a, b], c] (* Returns (a plus b) times c *)
$\endgroup$

3 Answers 3

3
$\begingroup$

If your custom notation is identical to that of Power, I would do it the lazy way:

MakeBoxes[ myPower[base_, exp_], form_ ] :=
  TagBox[ MakeBoxes[ base^exp, form], myPower] ;

myPower @@@ {{x, y}, {x + y, z}, {x y, z}, {myPower[x, y], z}, {f[x, y], z}}

{ xy, (x+y)z, (x y)z, (xy)z, f[x, y]z }

% // InputForm

{myPower[x, y], myPower[x + y, z], myPower[x*y, z], myPower[myPower[x, y], z], myPower[f[x, y], z]}

$\endgroup$
4
+50
$\begingroup$

Using

\((a + b ) \^ c \)

where \^ is short form for SuperscriptBox within \( ...\), gives

SuperscriptBox[RowBox[{"(", RowBox[{"a", "+", "b"}], ")"}], "c"]

as pointed out by @jkuczm, you can then solve by using RowBox.

So I tried to do for the cases it didn't work and for others, like $(\frac{a}{b})^c$

I played a bit with the pattern matching in Notation but found it a bit confusing and inconsistent, maybe someone more familiar can do better. If you use the option PrintNotationRules you can see the function used to set the notation which is NotationMakeBoxes, here the pattern matching is more like what I am familiar with (not that I know much)

so using 2 separate cases:

NotationMakeBoxes[MyPower[A_?AtomQ, B_], StandardForm] := 
      SuperscriptBox[MakeBoxes[A, StandardForm], MakeBoxes[B, StandardForm]]

NotationMakeBoxes[MyPower[A_, B_], StandardForm] := 
      SuperscriptBox[RowBox[{"(", MakeBoxes[A, StandardForm], ")"}], 
      MakeBoxes[B, StandardForm]]

Using the examples in the other answer

MyPower[x, y]

$x^y$

MyPower[x + y, z]

$\left(x+y \right)^z$

MyPower[x y, z]

$\left(x y \right)^z$

MyPower[x^y, z]

$\left(x^y \right)^z$

MyPower[x, y^z]

$ x^{y^{z}}$

MyPower[f[x, y], z]

$(f[x,y])^z$

It wraps the last function in parentheses but that's because I only matched for Atoms, you can now modify to have all the patterns you want.

$\endgroup$
2
$\begingroup$

As a workaround you can wrap base of MyPower with additional RowBox:

Notation[
    ParsedBoxWrapper[SuperscriptBox[RowBox[{"A_", ""}],"B_"]]
    \[DoubleLongLeftArrow]
    ParsedBoxWrapper[RowBox[{"MyPower", "[", "A_", ",", "B_", "]"}]]
]

It works with Plus, Times, nested MyPower and custom functions:

MyPower[x, y]
MyPower[x + y, z]
MyPower[x y, z]
MyPower[MyPower2[x, y], z]
MyPower2[x, MyPower2[y, z]]
MyPower[f[x, y], z]

xy

(x + y)z

(x y)z

(xy)z

xyz

f[x, y]y

Unfortunately it doesn't work as I would expect in combination with ordinary Power:

MyPower[x^y, z]

xy z

Honestly, I don't know why it works as it does. I hope someone will give a better answer.

$\endgroup$
1
  • 1
    $\begingroup$ It doesn't work with noncommutative multiply: MyPower[x ** y, z]. The same problem with cross operator MyPower[x\[Cross]y, z]. $\endgroup$
    – bcp
    Jul 7, 2014 at 9:45

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.