すべては式
Wolfram言語では数式,リスト,グラフィックス等各種のオブジェクトを扱うことができる.見掛けはずいぶんと違うが,Wolfram言語では,すべてが統一的に表現される.つまり,すべては「式」として表される.
典型的なWolfram言語の式にf[x,y]がある.f[x,y]を使い数学の関数 を表すことができる.この関数は,名前がfで,xyの2つの引数を取る.
式の記述に,いつも f[x,y,]の書式を使う必要はない.例えば,足し算式なら,x+yと書いてもよい.しかし,一旦,Wolfram言語にx+yと入力されたなら,この式は,Plus[x,y]とされ,違った形に変換される.また,表示されるときは,再び,x+yの形式に逆変換される.
同様な表記変換は,ベキ乗(^; Power)や除算(/; Divide)等の演算子にも行われる.
事実,Wolfram言語に入力されるすべての式は完全形の式に変換される.
x+y+zPlus[x,y,z]
xyzTimes[x,y,z]
x^nPower[x,n]
{a,b,c}List[a,b,c]
a->bRule[a,b]
a=bSet[a,b]
Wolfram言語式の例
式の完全形を確認するには,FullForm[expr]と入力する.
式を入力する:
完全形を得る:
別の式を入力する:
完全形では,ネストしている部分がある:
f[x,y,]においてオブジェクト f は式の「頭部」と呼ばれる.これは,先頭に位置するのでそう呼ばれる.式の頭部が何か調べるにはHead[expr]の機能を使う.計算プログラムを作る際に,式がどんなものか知る必要がよくあるが,そのようなときにこの機能を使い頭部を調べるとよい.
Headは,「関数名」fを返す:
ここでは,Headは「演算子」の名前を返す:
どんなものにでも頭部はある:
数にも頭部はある:
頭部を参照することで,数がどんな型のものか調べることができる:
Head[expr]
式の頭部を抽出する(例えば,f[x,y]f
FullForm[expr]
Wolfram言語内部で使われる完全形に式を変換する
式の表記に関する操作
式の意味
式の概念は,Wolframシステムにおいて中核的で統一的な原理である.Wolframシステムの扱うすべてのオブジェクトは同じ基本構造を持つという事実が,Wolframシステムを限られた数の基本操作だけで多くの領域に対応することができるものとしている.
すべての式は同じ構造を持つが,式の使われ方は式によりいろいろ違う.式の各部分がどのような意味を持つか簡単な例で見てみる.
f の意味
x,y, の意味
Function(関数)
引数,パラメータ
Sin[x]
,
f[x,y]
コマンド
引数,パラメータ
Expand[(x+1)^2]
演算子
演算数
x+y
,
a=b
Head(頭部)
要素
{a,b,c}
オブジェクトの型
内容
RGBColor[r,g,b]
式の各部分の持つ意味
多くの式は,行いたい操作を指示する目的で使われる.例えば,2+3とタイプすると,23を加える操作を指示することになるし,Factor[x^6-1]と入力すれば,因数分解の操作を指示することになる.
さらに,重要な式の使い方として,他の関数を適用させることができる構造体の保持がある.例えば,式{a,b,c}は演算操作を保持するのではなく,3成分からなるリスト形式の構造体の構築を保持するために使われる.この構造体には,ReverseDot等の他の関数を作用させることができる.
{a,b,c}は,完全形ではList[a,b,c]になる.頭部Listは何の操作も行わない.その代り,構造体の「型」を指定するための「タグ」としての働きを持つ.
完全形の式を使うことで任意の構造体を構築することができる.例として,3つの座標で決定される,3D空間の点を表した構造体を考える.点は英語でポイントというので,point[x,y,z]で表すことにする.リストと同じように,このpoint構造体も何も操作は行わない.単に,3座標をまとめて保持し,その結果としてのオブジェクトにラベルpointを付けたに過ぎない.
point[x,y,z]等の式は,特定の頭部が名札として付けられた「データの集合体」ととらえることもできる.すべての式は同じ構造を持つが,式の「型」は,違った頭部が与えられるとき当然変わり得る.このため,式の取る型に応じて式を違った方法で扱う変換規則やプログラムを設定することができる.
式の特殊な入力法
Wolfram言語では,多くの慣用的な演算子に対して特別な表記を使えるようになっている.例えば,二項の加算は,Wolframシステム内部ではPlus[x,y]と表されるが,その入力は,慣用的な形を使い x+y とすればよい.
Wolfram言語には特定の文法が備わっており,入力はそれに従って内部表記へ変換される.文法の規則に入力成分のまとめ方に関するものがある.例えば,この規則によると,a+b^cと入力された式は,a+(b^c)に等しいとされるが,(a+b)^cには等しくない.これは,ベキ乗(^)は加算(+)より優先順位が高いとする標準的な数学表記法に基づいた規則である.一般的に,優先順位が高ければ高いほど,その演算項は先にまとめられる.
Wolfram言語で使われるすべての特殊入力形には特定の優先順位が割り当てられている.このことは,慣用数学の演算子に限らず,例えば,「->」や「:=」の入力形や,Wolfram言語プログラムにおける複文形式の式と式の間を区切るセミコロンにもいえる.
「演算子の入力形」の表に,Wolfram言語で使えるすべての演算子の優先順位を高い順に掲載した.順位の決定は数学の標準的な使い方が基本になっており,丸カッコをなるべく使わなくて済むように考えられている.
<のような式の左右の関係を表した演算子は,+ 等の演算子に比べて順位が低い.これは,x+y>7等の式を記述するときに丸カッコを使わずに済むようにするためである.
それでも,カッコを使わなければいけない場合は結構ある.例えば,セミコロン(;)はイコール(=)より順位が低い.したがって,x=(a;b)には,丸カッコを入れておく必要がある.もし式をx=a;bとしたなら,(x=a);bと解釈されてしまう.一般論として,丸カッコを付けすぎるということはない.その逆に,付け惜しむと,予期しなかった順序で式の項が読み取られてしまい,計算に思わぬ間違いが生じてしまうことがある.
f[x,y]
f[x,y]の標準形
f@x
f[x]の前置形(接頭辞)
x//f
f[x]の後置形(接尾辞)
x~f~y
f[x,y]の中置形(接合辞)
関数の4つの表記形
演算子は上記の表記形のどれかを取る.例えば,式 x+y のプラス記号+は「中置」演算子であり,「-p」におけるマイナス記号-は「前置」演算子である.さらに,f[x,y,]等の式を入力するときは,それを,中置,前置,後置形式で記述することもできる.
この「後置形」は,f[x+y]に完全に等しい:
「結果的」に,N等の関数を後置的に加えることも可能である:
この例のように,式によっては中置的に表現した方が分かりやすくなる:
気が付かれたかもしれないが,二重スラッシュ記号(//)には非常に低い優先順位が割り当てられている.このため,//f と,式の末尾に関数の頭部を加えると,式が四則演算でも論理演算の式であっても,頭部 f は式全体にかかってしまう.つまり,x+y//fとすると,f[x+y]と解釈される.x+f[y]とはならない.
前置形演算子@には高い優先順位が与えられている.このため,f@x+yは,f[x+y]ではなく,f[x]+yと解釈される.f[x+y]に等しい式を記述するには,前置形式を使いf@(x+y)とし,引数を丸カッコでくくる.
式の部分抽出
リストが単に式の一形態であることはすでに説明した通りだが,その逆に,一般的な式もリストと同様に使えたとしても驚かないだろう.リストの各成分を個別に参照できるように,一般的な式の部分もまた個別に参照することができる.
こうすると,リスト{a,b,c}から第2要素を1つだけ取り出すことができる:
加算式x+y+zから第2要素を取り出すのにも同じ方法が使える:
マイナスを指定値に付けると末尾から数えた位置を指定することができる.ここでは最後尾の要素が抽出される:
0要素は頭部である:
ネストしたリストの部分抽出を行うときと同じ方法で,f[g[a],g[b]]等の一般式からある部分を抽出することができる.
1部分が抽出される:
{1,1}番の部分が抽出される:
1+x^2{2,1}番の部分が抽出される:
完全形で式を表示させ,{2,1}番の部分が何か確認する:
添数の式の部分への割当ては,FullFormによるWolfram言語内部の表記形に従って行われる.これらの表記形は,必ずしも表示に現れる順番に対応しない.このことは,標準内部表記が使われるが,特別な形で表示される代数式に対して特に当てはまる.
x/yの内部表記形を見てみる:
部分指定は,内部表記形に従い解釈される:
リストの部分と同じように式の部分を操作することができる.
a+b+c+dの第3部分をx^2に置き換える.和の構成順が自動調整されることに注意:
別の式を入力する:
tの完全形で見てみる:
tの一部分を変更する:
tの表記形が変わったかどうかを確認する:
Part[expr,n]
または
expr[[n]]
expr の第 部分を抽出する
Part[expr,{n1,n2,}]
または
expr[[{n1,n2,}]]
複数部分の抽出
Part[expr,n1;;n2]
式の部分 から
ReplacePart[expr,n->elem]
expr の第 要素を elem で置換する
式の部分操作を行う関数
「リスト要素の操作」において,添数のリストを作り,それをもとにリストから複数の要素を一括抽出する方法を説明した.それと全く同じやり方で,一般式の複数の部分も一括抽出することができる.
リストから第2,第4の要素を抽出する.抽出した要素は新たなリストとして返される:
加法式から第2,第4部分を抽出する.結果は抽出した要素の和sum として返される:
ある式のある部分は,別のある関数の引数として見ることができる.添数のリストを与えることで複数の部分を抽出するとき,抽出される部分は,抽出元の関数によりまとめられる.
リストの部分2から4までを選ぶ:
式のリスト的操作
「リスト」で説明したリストの操作機能は,一般式にも同様に使える.それらの機能を使い式の構造をどのようにでも操作することができる.
すべての項を足し合せる式を入力する:
あたかもtがリストであるかのように,Take[t,2]で,tから最初の2項を取り出すことができる:
Lengthを使い,式tにいくつ要素があるか調べる:
FreeQ[expr,form]を使うと,式 expr に形 form が現れるかどうかを検査することができる:
txが現れる位置を列挙する:
式の構造を操作するすべての関数は,式の内部表記形に対して働く.これらの形は,FullForm[expr]を使うことで見ることができる.内部表記形は,必ずしも表示される式の形ではない.
4引数の関数を入力する:
Appendを使うと,引数を追加することができる:
引数の並び順を反転することもできる:
上記の他にも式の部分操作を行うための関数がいくつかある.詳しくは,「構造操作」を参照のこと.
式の木構造
完全形で式の構成を見る:
TreeFormを使うと,式の「木」構造を表示させることができる:
すべてのWolfram言語の式は木と考えることができる.例えば,上記の式を例に取ると,ノードの頂点はPlus項であり,頂点から「枝分かれ」する2つの枝は,x^3(1+x)^2である.ノードx^3からは,さらに2つの枝,x3が伸びる.これらは,木構造の「葉」と見ることができる.
この行列は,2つのレベルからなる簡単な木構造を持つ:
より複雑な式を見てみる:
この式の木は,いくつもの階層を持つ:
式の各部分に付けられた添数は,木構造によって簡単に解釈することができる.各添数は,頂点のノードから下向きに数え,到達したい部分に至るために取る枝を示す.
式におけるレベル
関数Partを使えばWolfram言語式の特定部分だけを参照することができる.しかし,式の構造がほとんど一様ならば,複数部分に一括で参照することができた方が通常便利になる.
式の複数部分をまとめて指定するには,レベル指定に基づいた,一般化された方法を使う.多くの Wolfram言語関数では,それらを式の特定部分に作用させるとき,作用対象になるレベル位置を指定することができるようになっている.
簡単な式を入力して,木表示させる:
tのレベル1にあるxを探させる.1つだけ見付かる:
今度は,レベル2まで探させる.レベル1,2の両方にあるxが探し当てられる:
こうすると,検索をレベル2だけに絞ることができる.xは1つだけ見付かる:
Position[expr,form,n]
expr においてレベル n までに形 form が現れる位置を返す
Position[expr,form,{n}]
厳密にレベル n での位置を返す
レベルを使ったPositionの制御
ある式における部分のレベルは,単にこの部分が現れる位置までの,木構造の頂点からの距離ととらえることもできる.このとき,木の頂点はレベル0とする.
これは,レベル n にある部分は,n 個の添数からなる列で完全に指定することができる,ということに相当する.
n
レベル1〜n
Infinity
レベル0を除く全レベル
{n}
レベル n のみ
{n1,n2}
レベル n1n2
Heads->True
頭部を含む
Heads->False
頭部を含まない
レベルの指定
式を入力し,木形式で表示させる:
レベル2から下層方向にaを探させる:
こうすると,式の頭部以外でfの現れる位置を得ることができる:
今度は,頭部でのfの出現も検索対象に含める:
Level[expr,lev]
expr のレベル lev で指定されたレベルにある部分のリスト
Depth[expr]
expr のレベル総数を返す
レベルの判定と抽出
最上位からレベル2までの,uのすべての部分を列挙させる:
レベル2に限って,部分を列挙させる:
普通のレベルの使い方が分かってきたところで,今度は,負のレベルの使い方を見てみる.レベルに負の値を指定すると,木構造の最下位から数えた部分を指すことができる.例えば,レベル-1には,木の葉の部分に当たるすべてのシンボルや数のオブジェクトが含まれる.
uのレベル-1にあるすべての部分を列挙させる:
TreeFormで示されるように,式は「深さ」を持つものと考えられる.一般に,ある式においてレベル-n は,深さを n とした要素式から構成されると定義される.
g[a]の深さは2である:
レベル-2にあるuの部分は,深さがちょうど2の部分である: