These cells are here with the correct cell tags so they can copied when the help browser loads just a subsection of the documentation. This means the titles can always be open.
Notation, Symbolize and InfixNotation
Notation
Symbolize
Infix Notation
Entering Notations
Precedence of Operators in Notations
How Precedence is determined
Parentheses in Notations
Changing Precedences in Notations
Options and Auxiliary Functions
The option Action
The option WorkingForm
The option AutoLoadNotationPalette
The function ClearNotations[]
Complex Patterns and Advanced Features
Note: This section is intended for advanced users.
Tag boxes
The tag NotationBoxTag
Complex Patterns and the tag NotationPatternTag
The tag NotationMadeBoxesTag
Changing precedences and the TagBox option SyntaxForm
Advice and Suggested Guidelines
Build up notations in stages
Don't alter too much
Follow existing conventions where possible
Parse without evaluation where possible
Internal and External representations which are structurally different
Updates and Expanded Documentation
Jason Harris, November 1997.
Utilities`Notation`
The Notation package allows you to extend Mathematica so it understands and functions correctly with new typeset notations. The package Notation.m consists of three main utility functions: Symbolize, Notation and InfixNotation. Symbolize forces Mathematica to treat composite box structures internally as single symbols. Notation forces Mathematica to treat classes of composite box structures internally as a class of fullform expressions. InfixNotation forces Mathematica to treat a composite expression as an infix operator.
Without the definitions provided in this package, it is necessary to define new notations by constructing explicit MakeExpression and MakeBoxes rules. These rules have to be written in terms of full box structures that are generally long and visually unintuitive. Also, in creating a new notation, there are several nontrivial programming issues that must be taken into consideration. Hence, in the interests of readability and ease of use, it is desirable to be able to introduce new notations easily, intuitively, and graphically. The Notation package provides this functionality.
You should be aware that in this version of the Notation package, unlike some previous versions, all notations must be entered through the notation palette or through input aliases. (See EnteringNotations.) Also this version of the Notation package automatically adds the new notation styles into the current style sheet, as well as generating an updated notebook if necessary.
Notation, Symbolize and InfixNotation
Notation
Syntax of notation declarations.
Notation takes both an external representation and an internal representation as arguments. Mathematica translates any input matching the external representation into the corresponding internal representation and, reciprocally, formats any expression matching the internal representation into the corresponding external representation. In this context, representation means a composite structure made up of boxes representing some "notation".
This loads the package.
In[1]:=
The following declares a new notation for gplus.
In[2]:=
Any input matching is now interpreted as gplus[x,y,n].
In[3]:=
Out[3]//FullForm=
Any gplus expression is now formatted in the new notation.
In[4]:=
Out[4]=
Notations defined using in their definition both parse and format expressions according to the given notation. However, you can restrict the notation to only parsing or only formatting by using or respectively, instead of in your notation statements.
This defines a notation for the parsing of a hypothetical DomainIntegral.
In[5]:=
DomainIntegrals are now parsable.
In[6]:=
Out[6]=
The following defines an output format for Derivative objects that looks more like that of traditional mathematics.
In[7]:=
Derivatives are now formatted according to the new derivative notation.
In[9]:=
Out[9]=
To allow the previous output to be used as input you can define an interpretation of partial derivatives.
In[10]:=
You can now use these new notations for derivatives.
In[12]:=
Out[12]=
You should define your notations in such a way that they both parse and format, since users will generally expect this functionality.
The following notation both formats and parses arrows overscripted by Apply.
In[13]:=
Simple rules like linearity can now be entered in a visually intuitive way.
In[14]:=
In[15]:=
Out[15]=
You may at first feel that having underscores on both sides of a Notation statement is somewhat unsettling. However, notational transformations usually work in both directions, therefore having underscores on both sides of a notation statement is natural, and soon becomes intuitive.
Symbolize
Syntax of symbolization declarations.
Symbolize is used to treat a class of composite boxes internally as symbols. It is sometimes necessary and desirable to be able to symbolize composite objects; for example, to be able to attach rules to a composite object, it must be treated as a symbol.
This declares that the composite object should be treated as a symbol.
In[16]:=
The package has created a FullForm name for the composite symbol .
In[17]:=
Out[17]//FullForm=
You can now attach rules to the composite symbol .
In[18]:=
The above rule for is now tried before the rules of DomainIntegrals.
In[19]:=
Out[19]=
Symbolize also symbolizes classes of expressions, for example, to symbolize all objects subscripted by Rule.
In[20]:=
Anything subscripted by Rule is now treated as a symbol.
In[21]:=
Out[21]//FullForm=
You can use symbolized box structures as pattern variables in definitions. This lets you create formulas in a more familiar notation. However, you must use pattern expressions of the form CompositePatternVariable : PatternContent otherwise Mathematica may interpret the pattern expression as CompositePatternVariable PatternContent.
This defines the transmission coefficient for an incident wave packet on a potential step under certain conditions.
In[22]:=
In[23]:=
Infix Notation
Syntax of infix notation declarations.
InfixNotation is used to treat a composite box structure as an infix operator. InfixNotation requires both a composite box object which will represent the infix operator and a symbol which will be the full form head of the expression. A simple parallel of this duality in Mathematica is that the infix notation + has the full form head Plus.
This declares that the composite object should act as the infix form of Join.
In[23]:=
In[24]:=
Out[24]=
The infix notation both parses input and formats output.
In[25]:=
Out[25]=
An advantage of using InfixNotation over that of using Notation to define an infix operator is that InfixNotation parses an expression into a flat internal form without evaluation. Although this is a subtle difference, it is an important one (see ring operations and parsing without evaluation.)
InfixNotation parses input to a flat expression.
In[26]:=
Out[26]//FullForm=
The function InfixNotation can be compared to using the infix form of functions ~~ (cf. The Mathematica Book 2.1.3)
Entering Notations
When defining your own notations it is critically important to use the notation templates. The notation templates are contained in the notation palette shown below.
The reason for this restriction is that the templates pasted into a notebook contain essential tag boxes embedded in the correct way. These embedded tag boxes allow Notation , Symbolize and InfixNotation to properly group and parse the new notation being defined. Further, they allow these functions to get the styling information of the new notation so that the output is formatted with the same spacing, sizes, adjustments, etc. as the input.
A blank notation template looks like the following.
Advanced note: You can circumvent using the notation palette by wrapping the corresponding literal box structures in a NotationBoxTag[].
In Mathematica it is possible to create input aliases for any notation or expression you want. The normal interface to these input aliases is rather cumbersome and so the notation package contains the function AddInputAlias to facilitate adding input aliases to the current notebook. Each of the common templates has an alias associated with it for easy entry. For instance typing notation in an input cell will enter the notation template .
Add an input alias for apply statements to the current notebook.
In[27]:=
Now that we have created this alias we can enter "apply" templates by simply typing apply.
Precedence of Operators in Notations
How Precedence is determined
The precedence of any new notation or operator is determined by examining the components from which it is constructed. For instance, is grouped according to the precedence of +, the operator is grouped according to the precedence of , and the mapping is grouped according to the precedence of . Generally the grouping behavior of positioning boxes is determined by the "base element". For instance, the expression SubscriptBox[symb, sub] is grouped according to symb. But for some other structural boxes the grouping behavior of surrounding elements is not affected by the behavior of the contents of the box. The precedence of compound objects is determined according to the following table
The standard boxes and their relationship to precedence.
The design decision of making the precedence of new compound operators correspond to their constituents makes intuitive sense and generally leads to notations that are consistent. For instance, consider a possible notation for addition and multiplication over a ring .
This defines a notation for ring addition and ring multiplication.
In[28]:=
Mathematica now can parse and format expressions containing ring additions and multiplications.
In[30]:=
Out[30]=
In[31]:=
Out[31]//FullForm=
The ring multiplication operator has a higher precedence than the ring addition operator because * has a higher precedence than + . Moreover, the notation is automatically set up to parenthesize the expression appropriately to maintain the correct structure.
The output has the correct formatting, styling, spacing, and parenthesization.
In[32]:=
Out[32]=
However the above notation for ring addition and ring multiplication is still somewhat limited.
In[33]:=
Out[33]=
The above Notation statement can be removed and an InfixNotation can be used instead.
In[34]:=
Now and act as true infix operators for RingPlus and RingTimes.
In[38]:=
Out[38]=
Parentheses in Notations
It is important to point out that bracketing expressions by using {},(), ,[], or other braces in a notation not only changes the grouping of the notation but requires the brackets to be literally present in the input expression.
The following defines a notation that uses parentheses.
In[39]:=
In[40]:=
Out[40]//FullForm=
Without parentheses input is not recognized as a Semantic wrapper.
In[41]:=
Out[41]//FullForm=
Changing Precedences in Notations
You can isolate the elements around an operator or expression by surrounding the operator or expression with a box structure that isolates its contents (cf. the table above). The box structure typically used to do this encapsulation / isolation is the TagBox. Furthermore it is possible to change the precedence of an operator through the use of the TagBox option SyntaxForm. More will be said on this later in the section Complex Patterns and Advanced Features.
The underlying box structure of has an embedded TagBox.
In[42]:=
Out[42]=
The embedded TagBox in is necessary for several reasons: to contain the StyleBox asserting ZeroWidthTimes, to suppress the natural prefix operator grouping of , and to allow the parsing and formatting rules to act on an encapsulated unit.
Options and Auxiliary Functions
Notation , Symbolize and InfixNotation have several options that modify their behavior. These notation functions all take the options WorkingForm and Action. In addition the Notation package has a local option AutoLoadNotationPalette which affects the loading of the palette. Finally, the Notation package has a function which clears all notations, symbolizations, and infix notations defined so far.
The option Action
The Action option and its possible values.
The Notation, Symbolize and InfixNotation option Action determines what a notation statement does with the rules it generates. The default value of the Action option is CreateNotationRules, which causes the generated notation rules to be entered into the system.
This creates a notation for pure functions more in keeping with that of traditional mathematics.
In[43]:=
Pure functions now use this new notation.
In[44]:=
Out[44]=
If the Action option is set to RemoveNotationRules, then the notation rules are removed from the system. Using the option value RemoveNotationRules in a notation statement is equivalent to using the appropriate RemoveNotation, RemoveSymbolize or RemoveInfixNotation statement.
This removes the above notation from the system.
In[45]:=
Now the special notation for functions is no longer defined.
In[46]:=
Out[46]=
By setting the option Action to PrintNotationRules, you can view the rules generated by a notation statement. Examining the MakeExpression and MakeBoxes rules is often useful to give you an idea of the underlying box structures that are used in your notation statement.
This prints the MakeExpression and MakeBoxes rules corresponding to the given Notation.
In[47]:=
The option WorkingForm
The WorkingForm option and some of its possible values.
The option WorkingForm specifies the form or environment the Notation, Symbolize or InfixNotation statement is generated in. The typical values of WorkingForm are StandardForm or TraditionalForm; any notations created would only apply in StandardForm or TraditionalForm (respectively). However, WorkingForm can be set to any form you define, for instance LogicForm, PhysicsForm etc.
When the option WorkingForm is set to Automatic the Notation, Symbolize or InfixNotation statement will be created in the DefaultOutputFormatType. This form is show in the menu item Default Output Format Type under the menu Cell.
This creates TraditionalForm notations for the vector calculus functions Div, Curl and the wrapper Vector.
In[48]:=
These notations behave as expected.
In[51]:=
Out[51]//TraditionalForm=
In[52]:=
Out[52]//FullForm=
In[53]:=
Out[53]=
The option AutoLoadNotationPalette
The option AutoLoadNotationPalette and its behavior.
If you are designing a package you may want to hide the notation palette when the user loads the Notation package so as not to confuse them. You can set the boolean variable AutoLoadNotationPalette inside your package to achieve this. If AutoLoadNotationPalette has been set to False then the notation palette will not be loaded when the Notation package is loaded. If the value is undefined or True, the notation palette will be loaded when the Notation package loads. In input form the statement would look like the following.
Statement forcing the notation palette not to load when the Notation package loads.
The function ClearNotations[]
Syntax of clear notations.
If you would like to reenter a set of notations or would like to make a "clean start" you can use the ClearNotations[] command to erase all notations, symbolizations and infix notations present in the system. Using ClearNotations[] should not affect other packages or definitions you have made to MakeExpression or MakeBoxes.
Wipe all notations, symbolizations and infix notations.
In[54]:=
Complex Patterns and Advanced Features
This section is intended for advanced users.
Due to the complex inner workings of the Notation package it is helpful to outline some of the more advanced features and structures of the Mathematica front end and how they relate to the Notation package. The following sections give a small overview of the functionality of tag boxes the specific tags used by the Notation package and the tag box option SyntaxForm.
The reader should be familiar with the concepts in section 2.9 Textual Input and Output and moreover understand the following sections: 2.9.3 The Representation of Textual Forms, 2.9.4 The Interpretation of Textual Forms, 2.9.10 Representing Textual Forms by Boxes, 2.9.12 String Representation of Boxes, 2.9.13 Converting between Strings, Boxes, and Expressions, and 2.9.17 Advanced Topic: LowLevel Input and Output Rules.
Tag boxes
A TagBox is a box structure just like, SubscriptBox, GridBox. It is used to change the structure of an expression or indicate a grouping or interpretation of a subexpression at an underlying level. To illustrate tag boxes consider the following input which contains an embedded TagBox.
All Mathematica input and output is made up of box structures at a low level. When Mathematica receives input, these box structures are parsed into internal expressions, which can be thought of as full form expressions. Internal evaluation then takes place, and finally the internal structures are transformed back into box structures for displaying in the Mathematica front end.We can reveal how Mathematica sees this input at a low level by using the Show Expression command under the Format menu.
Here is the underlying representation of the expression above in terms of boxes, displayed using the Show Expression menu item located under the Format menu.
The above expression contains a subexpression TagBox[SuperscriptBox["x", "2"],foo]]. It is important to note that this box expression as normally viewed in Mathematica looks visually like even though it has an embedded TagBox. Information contained in the tag is visually hidden from the user. When an expression containing a TagBox is input into Mathematica the default interpretation of the subexpression surrounded by the TagBox is to wrap the TagBox name around the parsed subexpression, in this case to wrap foo around x^2.
The embedded TagBox tag foo has no special parsing behavior associated with it.
In[55]:=
Out[55]=
However you can define your own rules for the way specific tag boxes are parsed. For instance by using the low level function MakeExpression we can change how Mathematica will parse expressions containing TagBoxes.
By defining a new rule for MakeExpression we can change how Mathematica will parse expressions containing a TagBox with the tag literalBoxes.
In[56]:=
The embedded TagBox tag literalBoxes now has the special parsing behavior associated with it to just return the boxes.
In[57]:=
Out[57]=
Knowing that special behaviors can be set up for specific tags we can now examine the tags defined by the Notation package. The Notation package defines three tags that have special behaviors: NotationBoxTag, NotationPatternTag, and NotationMadeBoxesTag.
The tag NotationBoxTag
NotationBoxTag is a tag used by the Notation package to grab box structures before they can be parsed by Mathematica. In fact NotationBoxTag acts rather like the tag literalBoxes defined above. All Notation , Symbolize and InfixNotation templates on the notation palette contain tag boxes with an embedded NotationBoxTag. The embedded TagBox ensures that the Notation package can obtain the correct parsing information and retain the proper styling and grouping information.
An expression containing an embedded NotationBoxTag tag.
In[58]:=
Out[58]//FullForm=
We can avoid using notation templates if we wrap raw box structures with a NotationBoxTag.
In[59]:=
In[60]:=
Out[60]//FullForm=
Complex Patterns and the tag NotationPatternTag
For normal purposes it is usually sufficient that the patterns present in Notation and Symbolize statements are simple patterns. However, it is sometimes necessary or desirable to use more complicated patterns in notations. For example, a notation might only be valid when a certain pattern is a number. To allow more complex patterns you can embed a NotationPatternTag tag box inside a notation statement. It is critical that any notation you define which uses a complex pattern has an embedded NotationPatternTag, otherwise the pattern will be treated as a verbatim expression and not function as a pattern. The notation palette has a button labeled InsertPatternWrapper which will embed a NotationPatternTag around the selection, as well as tint the background of the selection to indicate that a complex pattern is present.
This creates a TraditionalForm notation that only functions with numbers.
In[61]:=
It must also be pointed out that the pattern matching on the external representation is performed on the box structures, so usually you will have to make small transformations to convert box structures into normal expressions. Pattern matching on the internal representation follows conventional pattern matching.
This defines a function analogous to NumericQ that operates on box structures.
In[62]:=
Now only input which matches the above pattern will be interpreted as a foo object.
In[63]:=
Out[63]=
Reciprocally only foo objects with numerical arguments will be formatted using the notation.
In[64]:=
Out[64]//TraditionalForm=
You should be careful to avoid unwanted evaluation through testing functions when parsing expressions (see parsing without evaluation.)
We can examine the form of the rules created by using the option Action PrintNotationRules.
In[65]:=
We can see that the patterns a_?StringNumericQ and a_?NumericQ do not appear literally since they were surrounded by a NotationPatternTag in the notation statement.
The tag NotationMadeBoxesTag
The tag NotationMadeBoxesTag is intended for advanced users. It is used to indicate that box processing and formatting has already been done and that the Notation package should not perform any processing. Typically you would use this tag for surrounding your own functions that return expressions that have already been turned into boxes or parsed into expressions. To illustrate the tag NotationMadeBoxesTag we can examine a notation statement that might be part of a number of statements used to create a notation for Tensors.
An example notation for formatting tensors containing the tag NotationMadeBoxesTag.
In[66]:=
We can see from the internal definition returned that there is no further processing of the expression createGridBox[inds], i.e. it is not surrounded by a MakeBoxes[...,StandardForm].
Changing precedences and the TagBox option SyntaxForm
Using the option SyntaxForm you can change the precedence of an expression containing a TagBox. A tag box containing a SyntaxForm option will look like TagBox[ box structure, tag, SyntaxForm string], where string is a string indicating the operator on which the precedence of the tag box is modeled. The following examples illustrate the SyntaxForm option .
An expression which uses the arrow with standard precedences.
In[67]:=
Out[67]//FullForm=
We can define a new notation for a composite arrow surrounded by a TagBox that has the SyntaxForm option set to a low precedence.
In[68]:=
This new composite arrow has a low precedence.
In[69]:=
Out[69]//FullForm=
We can illustrate the underlying groupings of the expressions above in the following table.
A table illustrating the precedences and grouping of expressions with and without precedence changing tag boxes.
The SyntaxForm option value can be any operator string valid in Mathematica, that is, any operator contained in the UnicodeCharacters.tr file. The SyntaxForm value can also include symbols before and after the operator to indicate whether the precedence is that of a prefix operator, an infix operator, or a postfix operator. Some typical values for the SyntaxForm option are given in the table below.
Typical SyntaxForm values and their associated precedence behaviors.
Advice and Suggested Guidelines
The following are some issues and considerations to be aware of when using the Notation package and/or designing notations.
Build up notations in stages
It is intrinsically difficult to debug something you cannot see; therefore, it is best to build up notations, seeing if something works or where a mistake has been made. It is harder to find errors if you enter a whole complex notation before testing it. Many notational problems will usually be revealed by examining the full form of an expression or its internal structure via e.
Don't alter too much
You should try not to alter too much. For example, changing commas to vertical separators is strongly discouraged. The more notational oddities present in the system, the higher the chance that one notation will adversely interact with another giving unexpected results. Some parsers have mechanisms to detect conflicts in a given grammar but the Notation package does not.
Follow existing conventions where possible
Where possible, you should follow standard Mathematica conventions or follow the conventions of a given field. Inventing your own individual nonstandard notation is discouraged since such notations are necessarily unrecognizable to other users. Even if a notation has an historical origin and is not as intuitive as other possible notations the author could invent, it is usually better, where possible, to use the historical notation. Admittedly, however, it is sometimes difficult to resolve the inconsistencies present in a certain notation with the desire to have a uniform notation.
Parse without evaluation where possible
When designing notations it is desirable to be able to parse an expression to its correct full form without evaluation. This is not always possible for complex notations where there is no direct correspondence between an external form and an internal form. However, for the cases when it is possible there should be no side effects from evaluation.
The following notation does not depend on evaluation in order to behave correctly.
In[70]:=
In[71]:=
Out[71]//FullForm=
A common instance of unwanted evaluation comes from testing functions used in complex pattern matching. If possible you should design testing functions to hold their arguments.
The notation defined using the testing function StringNumericQ evaluates its arguments, which can lead to unpredictable results.
In[72]:=
Out[72]=
Internal and External representations which are structurally different
In cases when a conventional notation does not easily equate to an internal form in Mathematica, it is suggested that you have the notation take the conventional form to the internal Mathematica name appended by "Typeset". For example the MeijerG function should have the TraditionalForm
But the FullForm of the MeijerG function in Mathematica has the following form.
Therefore it is necessary to verify that the , , , are numbers having the right values before it is even possible to construct the internal form of the MeijerG function. It is not possible to convert from the conventional form to the internal form without evaluation.
Therefore, in this case, we should take the traditional MeijerG box structure to a MeijerGTypeset[{{,},{,}},{,...,},{,...,}}]. Then evaluation takes this to the internal MeijerG function once it is has been established that it is possible to construct it.
Another possible case of this is taking a tensor defined using a GridBox to the expression TensorTypeset. Then evaluation takes this to an internal form Tensor, provided that the structure is valid, that is, the tensor does not have a contravariant and covariant index in the same column, etc.
Jason Harris (jasonh@wolfram.com), April 2003.
