|
2.5.10 異なるシンボルへの定義式の関連付け
f[args] = rhsや f[args] := rhsの形で割当て式を定義すると,式がオブジェクト f に関連付けられる.例えば, ?fと入力すると,表示にはこの定義が現れる.一般に,シンボル f を頭部とする式の定義は, f の下向きの値と呼ばれる.
Mathematicaでは,その逆の考えに基づいた上向きの値も使えるようになっている.上向きの値は,直接的な頭部ではないシンボルに定義を関連させるために使われる.
例として, Exp[g[x_]] := rhsを考える.1つの可能性として,この定義はシンボル Expに関連付けることができるため,それを Expの下向きの値としてとらえることができる.しかし,このとらえ方は,式の構成や計算の効率を考えると最良の見方であるとはいえないだろう.
それよりは, Exp[g[x_]] := rhsを gの上向きの値としてとらえ,それを gに関係付けた方がよい.

違うシンボルへの定義式の関連付け
これは,fに対する下向きの値を定義するものとする.
In[1]:= f[g[x_]] := fg[x]
fに関して情報を得ると,この定義を確認することができる.
In[2]:= ?f


次に, gに関する上向きの値を定義する.
In[3]:= Exp[g[x_]] ^:= expg[x]
定義が gに関連したものとして認識されている.
In[4]:= ?g


Expには関連付けされていない.
In[5]:= ??Exp


この式の評価にはこの定義が使われている.
In[6]:= Exp[g[5]]
Out[6]= 
単純なケースでは, f[g[x]]に対する定義を, fの下向きの値,または, gの上向きの値として与えても,計算される結果は変わらない.それでも,2つのとらえ方の内で,どちらか片方が他方に比べてより自然で,また,効率的になることがよくある.
どちらを取るかを判断する目安として, f[g[x]]の定義は,関数 f が gよりも使用頻度が高ければ gの上向きの値としてとらえる.これに従うと, Exp[g[x]]では, Expは Mathematicaの組込み関数であり, gはユーザ定義の関数であろう.そのような場合は,Exp[g[x]]に対する定義は, gにより満たされる関係を与えるものと通常とらえるだろう.つまり,定義を Expの下向きの値ととらえるよりは, gの上向きの値としてとらえた方がより自然である.
gの上向きの値として定義を与える.
In[7]:= g/: g[x_] + g[y_] := gplus[x, y]
これまでに gに関連付けられた定義を確認する.
In[8]:= ?g


gの加法用定義が使われる.
In[9]:= g[5] + g[7]
Out[9]= 
g[x_] + g[y_]は,完全形で Plus[g[x_], g[y_]]であるから,このパターンに対する定義は, Plusに対する下向きの値として与えることができる.それでも,ほとんどどんな場合でも,定義はgの上向きの値として与えた方がよい.
ある特定の関数が参照されるとき, Mathematicaは,その関数に関連付けられた全定義を試す. g[x_] + g[y_]用の定義を Plusに関する下向きの値として作ると, Plusが現れるたびに, Mathematicaはこの定義を使ってしまう.これは,式の加法が行われるたびにこの定義が判定されるため,非常に一般的な演算操作を遅くしてしまうことになる.
しかし, g[x_] + g[y_]用の定義を gの上向きの値として与えておけば,定義を gに関連付けることになる.この場合, Mathematicaは, Plusのような関数で gが現れるときにこの定義だけを試す. gが Plusに比べてあまり使用されないとすると,この手順の方がより効率的になる.

上向きの値を定義するための短縮形
上向きの値は,特定のオブジェクトの特性に関する「データベース」を構築するのによく使われる.上向きの値を使えば,作成する定義を,指定される特性にではなくこの定義にかかわるオブジェクトに関連付けることができる.
面積を求めるための正方形に関する上向きの値を定義する.
In[10]:= area[square] ^= 1
Out[10]= 
周辺の長さ(perimeter)に関する定義を加える.
In[11]:= perimeter[square] ^= 4
Out[11]= 
両方の定義は,オブジェクト squareに正しく関連付けられている.
In[12]:= ?square


十分高いレベルに位置するシンボルであれば,それが何であっても,式に関する定義をそれに関連させることができる.f[args]形の式があるとき,あるシンボル g自体または gを頭部とするオブジェクトが argsに現れるのであれば, gに関する上向きの値は定義することができる.しかし,もし gが式の低レベルに現れるならば,それに定義を関連付けることはできない.
gは引数の頭部としてあるため,それに対して定義を関連付けることができる.
In[13]:= g/: h[w[x_], g[y_]] := hwg[x, y]
ここでは, gは深すぎる位置に現れるので,定義を関連付けることができない.
In[14]:= g/: h[w[g[x_]], y_] := hw[x, y]

Out[14]= 

定義における可能なシンボルの位置
2.1.2で説明したように,シンボルを「タグ」として使うことで式の「型」を指定することができる.例えば,複素数は Mathematica内部で Complex[x, y]と表されるが,シンボル Complex[x, y]は,該当オブジェクトが複素数であることを指定するためのタグとして働いている.
上向きの値を使うと,タグにより型を特定化されたオブジェクトに対して働く操作を指定することが簡便になる.例えば,型を quatとした抽象的な数学オブジェクトからなる1つのオブジェクトクラスを導入したいとする.このとき,型が quatのオブジェクトは, quat[data]という形式の Mathematica式で表すことができる.
quatオブジェクトに,足し算や掛け算等の四則演算に関連した特別な性質を持たせたいときがある.このような性質は, quatに関する上向きの値を Plusや Timesに対して定義することで設定することができる.
quatの上向きの値を Plusに対して定義 する.
In[15]:= quat[x_] + quat[y_] ^:= quat[x + y]
定義した上向きの値が使われ,この式は簡約される.
In[16]:= quat[a] + quat[b] + quat[c]
Out[16]= 
quatの上向きの値を Plusのような演算に対して定義するとき,それは実効的に quatオブジェクトを包含させるべく Plusの定義域を拡張することに相当する.これは,加算される数が quat型のオブジェクトである場合には,加法に特殊則を使うように Mathematicaに指示することになる.
quatオブジェクトを対象にした加法を定義する際,適当な下向きの値を割り当てた特殊な加法操作 (例えば, quatPlus)を使うことも考えられる.しかし,普通は,標準の組込み関数 Plusを使い加法を表せるが,quat型のオブジェクトがあるときに限り特殊な動作を指定することで加法操作に「過負荷」をかけた方がより簡便になる.
上向きの値は,いわゆるオブジェクト指向のプログラミング手法を,部分的だが実現するのに使える.quat等のシンボルは特定型のオブジェクトを表すので,quatに関した各種の上向きの値は「メソッド」を指定するために使える.メソッドとは,特定の操作が施されるときや,特定の「メッセージ」が受け取られるときに,quatオブジェクトがどう動作すべきかを定義するものを指す.
|