複雑なパターンと高度な機能

このチュートリアルは上級ユーザ向けである.

表記法パッケージの内部の動作が複雑であるため,Wolfram言語フロントエンドのより高度な機能と構造のいくつかについてと,それが表記法パッケージにどのように関わってくるかの概要を知っておくと役立つ.以下のセクションでは,タグボックス,パッケージが使う特定のタグ,およびタグボックスオプションSyntaxFormの機能についての概要を述べる.

ここでは「式のテキスト形入出力」のコンセプトを理解しており,さらに「式の拡張テキスト形式」「テキスト記述の式の解釈」「ボックス形テキスト表記」「ボックスの文字列表記」「文字列,ボックス,式の間の変換」「低レベル入出力の規則」についてよく知っていることを前提としている.

タグボックス

TagBoxRowBoxSubscriptBoxGridBoxと同様のボックス構造である.これは基底のレベルにおいて式の構造を変更したり,グループ化や部分式の解釈を示したりするのに使われる.タグボックスを理解するために,まずTagBoxが埋め込まれた次の入力を考える.

Wolfram言語入出力は低レベルではすべてボックス構造で構成されている.Wolfram言語が入力を受け取ると,これらのボックス式は解析されて内部式になる.これは完全形の式と考えることができる.その後内部評価が行われ,最後に内部構造はWolfram言語フロントエンドでの表示のためにボックス構造に戻される.Wolfram言語がどのように低レベルの入力を見るかはセルメニューにあるセルを式で表示を選ぶと分かる.

以下は上記の式の基底にあるボックスを使った表現である.これはセルメニューのセルを式で表示メニュー項目で表示できる.

上式は部分式TagBox[SuperscriptBox["x","2"],foo]]を含んでいる.このボックス式は,TagBoxが埋め込まれていてもWolfram言語で通常見えるようにx2と表示されることに注目されたい.タグに含まれている情報はユーザから見えないのである.TagBoxを含んでいる式がWolfram言語に入力されると,解析された部分式の周りのTagBox名(この場合はx^2の周りの foo)が,TagBoxで囲まれた部分式のデフォルトの解釈で囲まれる.

埋め込まれたTagBoxタグfooには特別な解析のための動作は関連付けられていない.

しかし,特定のタグボックスが構文解析される方法で独自の規則を定義することもできる.例えば,低レベル関数MakeExpressionを使うと,Wolfram言語がタグボックスを含む式を解析する方法を変更することができる.

MakeExpressionについての新しい規則を定義すると,Wolfram言語がタグliteralBoxesを持つTagBoxを含む式をどのように構文解析するかが変更できる.
これで,ボックスだけを返すという特別な解析動作が,埋め込まれたTagBoxタグliteralBoxesに関連付けられた.

このような特別な動作が特定のタグに設定できることを知っていると,表記法パッケージで定義されているタグの詳細がわかる.表記法パッケージでは,特別な動作を持つ3つのタグ,NotationTemplateTagNotationPatternTag,およびNotationMadeBoxesTagが定義されている.これらはすべて2つの理由で文字列タグである.1つ目は,文字列タグを使うことにより,パッケージの内容と再定義に関連した潜在的な問題を回避することができるということである.そして2つ目は,Wolfram言語ではTagBoxが文字列タグを持ち,スタイルシートパスに文字列タグと同じ名前の名前付きスタイルが存在する場合,TagBoxはそのスタイルで表示されると言うことである.これにより,TagBoxBaseStyleオプションを省略することができ,その結果,ボックス構造はより小さく,読みやすくなる.

タグNotationTemplateTag

NotationTemplateTagはボックス構造をWolfram言語が構文解析する前に捉えるために,表記法パッケージで使われる文字列タグである.実際,NotationTemplateTagはむしろ上で定義したタグliteralBoxesのように動作する.表記法パレットにあるNotationSymbolizeInfixNotationテンプレートはすべてNotationTemplateTagが文字列タグNotationTemplateTagを持つ埋め込まれたタグボックスを含んでいる.埋め込まれたTagBoxにより,表記法パッケージが正しい解析情報を得て,適切な書式とグループ分け情報が維持できるようになる.この埋め込まれたタグはボックス構造を捉えるために使われ,捉えたボックス構造はParsedBoxWrapperで囲まれる.

埋め込まれたNotationTemplateTagタグを含む式.
ボックス構造コードをParsedBoxWrapperで囲むと,表記法テンプレートを使わないでも行える.

複雑なパターンとタグNotationPatternTag

通常の目的では,Notation文とSymbolize文に含まれるパターンはシンプルなパターンで十分である.しかし,時にはより複雑なパターンが表記法で必要,または望ましいことがある.例えば,ある表記法が特定のパターンが数値のときだけ有効となる場合である.表記法の命令文にNotationPatternTagタグボックスを含めると,より複雑なパターンが可能になる.定義した複雑なパターンを使うどの表記法にも,NotationPatternTagが埋め込まれていることが重要である.埋め込まれていないとパターンが文字通りの式として扱われ,パターンとしては機能しなくなってしまう.これは,NotationTemplateTagと同様に文字列タグでなければならない.表記法パレットにはInsertPatternWrapperというボタンが含まれている.これは選択範囲の周りにNotationPatternTagを埋め込み,またその選択範囲が複雑なパターンを含んでいることを示すために背景に色を付ける(名前付きスタイルNotationPatternTagは文字列タグであるので,この色付けはその結果として生じる).

次の式は数値にのみ機能するTraditionalForm 表記法を作成する.

外部表現におけるパターンマッチングはボックス構造に施されるので,一般にボックス構造を通常の式に変換する際に多少の操作を要するということも特筆すべきことであろう.内部表現でのパターンマッチングは従来のパターンマッチングに従う.

次の式はボックス構造に作用するNumericQに似た関数を定義する.
これで,上記パターンにマッチする入力だけがfooオブジェクトとして解釈されるようになった.
反対に,引数が数値であるfooオブジェクトだけがこの表記法を使ってフォーマットされる.

式を解析する際,テスト関数によって必要のない評価を行ってしまうことのないように気を付ける必要がある(「可能な限り評価せずに構文解釈する」を参照のこと).

オプションAction->PrintNotationRulesを使って作成した規則の形式を調べることができる.

パターンa_?StringNumericQa_?NumericQは表記法の命令文においてNotationPatternTagで囲まれているため,その通りには現れないことが分かる.

タグNotationMadeBoxesTag

NotationMadeBoxesTagは上級ユーザ向けのタグで,これも文字列タグである.このタグはボックスの処理とフォーマットが既に終了しているため,Notation パッケージは何の処理も行う必要がないということを示すために使われる.このタグは一般に,既にボックスに変換されている式や解析されている式を持つユーザ定義関数を囲むときに使う.タグNotationMadeBoxesTagを理解するために,テンソルの表記法の作成に使われている多くの文の一部に使用できる表記法の命令文を調べてみる.

タグNotationMadeBoxesTagを含むテンソルのフォーマットのための表記法の例.

返された内部定義から,式createGridBox[inds]にはさらに行わなければならない処理は何もない,つまりMakeBoxes[,StandardForm]で囲まれていないということが分かる.

優先順位の変更とTagBoxオプションSyntaxForm

オプションSyntaxFormを使うと,TagBoxを含む式の優先順位が変更できる.SyntaxFormオプションを含んでいるタグボックスは,TagBox[box structure, tag, SyntaxForm -> string]のような形式となる.ここで,stringはタグボックスの優先順位がモデル化される演算子を表す文字列である.次の例でSyntaxFormオプションを説明する.

標準の優先順位の矢印を使う式.
優先順位が低く設定されているSyntaxFormオプションを持つTagBoxで囲まれた複合矢印の新しい表記法が定義できる.
新しく作った複合矢印の優先順位は低い.

上式の基底にあるグループ分けは次の表のようになっている.

式の外観
グループ化
式のボックス形式
a+bca+(b c)Cell[BoxData[RowBox[{"a","+", RowBox[{"b"," ","", " ","c"}]}]],"Input"]
a+bc(a+b) cCell[BoxData[RowBox[{RowBox[{"a","+","b"}], " ", TagBox["",Identity,SyntaxForm ->","], " ","c"}]], "Input"]

優先順位変更タグボックス付き/なしの式の優先順位とグループ分け

SyntaxFormオプションは,その値として,Wolfram言語で使えるどの演算子の文字列でも取ることができる.この演算子とは,UnicodeCharacters.trファイルに含まれている演算子のことである.SyntaxFormの値は,演算子の前後に,優先順位が前置・中置・後置演算子のいずれであるかを示すシンボルを含むこともできる.次の表に,いくつかの一般的なSyntaxFormオプションの値を示す.

SyntaxForm の値
優先順位
"*"乗算演算子としてグループ分けされる
"a"シンボルとしてグループ分けされる
"a+b"中置加算演算子としてグループ分けされる
""全称演算子としてグループ分けされる
""積分演算子としてグループ分けされる
" a"前置和集合演算子としてグループ分けされる
" "ホワイトスペースとしてグループ分けされる

一般的なSyntaxFormの値と,それに関連付けられている優先順位