<2012年1月3日 大幅に修正,加筆>
近代的なプログラミング言語ではもはやnull(あるいはnil)は不可欠の定数であり,組み込み定数として用意されている.しかし,その扱いはかなり恣意的で,プログラマを戸惑わせ,ときにバグのもとになる.
nullは「確定しない(与えられていない,定義されていない,未知の、不明の)」なにかを示すものとされる.nullは,まるで中観派仏教のいう「空」のように,否定型でしか表現されない.非常にわかりにくいが,計算モデルの基幹をなす概念である.
素朴なモデルでは,集合圏
Set において,nullをどの対象(集合)も持つ特別な要素と見なし,あらゆる写像でnullはnullに写像されるとして,圏
1/Set を構成する.つまり,不明なものはどんな処理を受けても結果は不明だと考える."Garbage in, garbage out"である(E.W.Lawvere and S.H.Schanuel : "Conceptual Mathematics - A first introduction to categories, Cambridge University Press, 1995, p.296参照).しかし,この圏は,始対象 0と終対象1が同型になり,応用がきわめて限られてしまう.
次に,部分射(集合圏では部分写像あるいは部分関数と呼ばれる)によるモデル化の方法がある(Robert Goldbratt著 "
Topoi" Dover 1984, p268参照).
集合圏
Set において,写像(射)は定義域の全要素に適用されるが,部分写像はその部分集合にしか適用されない.この部分写像
f を拡張した写像
f を設定し,その定義域
D は
f の定義域
D を含むとする,拡張された写像
f は,集合
D に 対し(1)
f の定義域にはいる要素
x については,{
f(x)}を値とし,(2) それ以外の要素については, 0(空集合)を値とする,というものである.この一般化写像
f は
f と圏論的に等価であり,その意味で同等であると見なせる.部分写像
f は定義域の要素に対し(1)の場合は「確定」,(2)の場合は「未確定」ということにする.圏の対象の要素とは終対象
1 からその対象への射であるので,その部分射を部分要素と呼び,「不確定」な場合,その値をnullと呼ぶことにする.これが部分射によるnullのモデルである.
しかし,これは「定義されていない(定義域にない)」ゆえの値の不明を示しているものであって,nullのもう一面である値そのものが「未知,未定」のため不明であることを示していない.また,仕組みがかなり作為的である.そこで,より自然で一般的な可変集合の圏をモデルにする考え方を以下に述べる.
2段階の変化を取り入れた「可変集合」を対象とする圏を考える(前掲書Sets For Mathematics p.114参照.この本を以降は略してSFMということにする).SFMでは,段階を「以前previous」と「現在present」と呼んでいる.われわれの場合は,「認識前」と「認識後」の段階を考える.この2段階を対象(Uと1とする)とする圏を
2 とする.
2 から集合圏
Set への反変関手(contravariant functor)を対象として構成する関手圏を
Set↑2↑opとする.この対象である可変集合
X は,認識後の段階の集合
X1 から認識前の段階の集合
XU への射である.
XU と
X1 は,それぞれ「所与」と「所識」としても良いし,ノエシスによって切り出された対象領域とそれによって得られるノエマとしてもよいだろう.
X1 から
XU への射
ξx は認識されたものが認識対象領域のもののどれに対応するのか,それを与える.すると,
xU を
XU のある要素とすると,
(1)
xU =
ξx(
x1)なる
x1 がある.つまり,
xU は認識されている
(2)そういう
x1 はない.つまり,
xU は認識されていない.
の二通りがある.
可変集合として,集合1から集合1への射は,
Set↑2↑op の終対象
1 であり,
1 から可変集合
X への射は
X の「要素」である.
X1 の要素
x1 に対し
ξx (
x1) は
XU の要素になるから
,任意のx1に対応するもの,つまり,認識されたものはいずれも
X の「要素」である.
また,可変集合として,0から0への射は,
Set↑2↑op の始対象
0 である.ここへの
1 からの射はないので,「要素」を持たない.
では,0から1への射 である
U はどうか,この
U 自体は始対象
0 と同様「要素」を持たない.しかし,
U から
X への射は,
X1 の要素の如何に拘わらず,
XU の要素を与える.これは前述の(2)にあたり,認識対象のなにかはあるのにそれが認識されたもののなにかとして得られない(未知),逆に,認識されたものの集合(
X1 )の要素(0からの射で決まる.つまり,特定できない)がなんであろうと,認識対象の集合(
XU )のいずれかの要素が指定されるため,認識結果の要素が認識対象の要素のいずれに対応するのかが特定できず,その意味で不確定である.
対象
X の要素
x が
X の「部分(part)」
A のメンバーであるかどうかを判定するものを特性関数(characteristic function)といい,その値は「真理値」と呼ばれる.通常の集合圏では,この値は 0と1で,0への射をfalse, 1への射をtrueというのが慣わしである.
Set↑2↑op では,真理値は 認識前の段階では 0,
1の2値,認識後の段階では 0, 1に加え,U がある(SFM p.117参照).認識後の段階でU になるのは,x1 が A1 の要素ではないのにX1の要素であり,それが変換された xUがAUの要素である場合である.つまり,x はAに入るメンバーなのかどうかなんとも言えないことを示す.この場合,真理値をnullということにする.真理値がtrueの場合,A のメンバーであるとするのに対し,nullの場合を「nullメンバー」であると言うことにする.
可変集合圏での属性について考える.
X の属性
p を
Y への射とする.
x を
X の要素とすると,
Y の「部分」である
p(
X ) に対し,p(x)がそのメンバーであるかどうかを特性関数で見る .すると,値がtrueならばp(x)が属性値だが,nullならば,属性値は不明であると言うことになる.一方,
p の定義域
X がある対象
Xの「部分」であるかどうかを見るxの真理値がtrueならば対象
Xを定義域とする属性
p の適用対象となるが,nullならば,
p が
xに適用可能かどうかが不明となり,その意味で属性値は不明,ないし不確定と見なされる.
Rubyの組み込みクラスにNilClassがある.これは特異な可変集合
U に相当する.インスタンス(「要素」)はないものの,インスタンス属性は与えることが出来る.属性
p を
U から
X への射 としたとき,
p は(前述のように
X1 の要素に関わりなく)
XU の要素を値とする.NilClassの属性として便利なのは型変換である.たとえば.to_s(文字列に変換)など.この属性 to_s を
X1 = 0,
XU = {""} なる
X への射とすれば,xの値をnull(つまり,部分要素)としたとき,x.to_s は ""(長さ0の文字列)となる.R3ではコーディングの便宜を図るため,NilClassにto_a, to_hash, to_s,などのインスタンス属性(メソッド)を追加しているが,このモデル化のなかでは体系としての一貫性を壊さない.Railsでは実際,Viewの作成時にnullを "" に変換している.
クラスの属性の「継承」についてどう考えるか.OOPのクラスはノエシスによる対象領域の切り出し(関心の的となる領域)と認識対象とするものの集まり(ノエマ)の2重構造を持つと考えるならば,圏
Set↑2↑op の「対象」に対応付けすることが出来る.上位クラス(に相当する対象)の認識後段階の集合を
X10 ,認識前段階の集合を
XU0 + Σ
XUi (
i = 1...
n),下位クラス(に相当する対象)の認識後段階の集合を
X10+
X1i(
i = 1...
n),認識前段階の集合を
XU0+
XUi(
i = 1...
n) とする.(Σは集合の総直和を,+ は直和を示す).上位,下位クラス全体を包摂する拡大対象
X として,
X1 = Σ
X1i (
i = 0..
n),
XU =
XUi(
i = 0..
n)とする.各クラス(対象)の属性はいずれもその定義域を拡大対象
X とみなす.各クラス(に相当する対象)いずれも
X の部分であるから,
X1 の部分の真メンバーならばそのクラスに定義された属性は適用可能であるが,nullメンバーならば,(上述のように)その属性値は不明ないし不確定とされる.ただし,上乗り(overriding)した属性は上位クラスの属性とは別物とみなす.このように考えれば,上位クラスが複数の場合も,また,階層が多段の場合も同じである.
これまではインスタンス属性の扱いについて述べてきたが,クラス属性(メソッド)についてはどう考えるのか.Rubyの場合,各クラスは,Classという名のクラスのインスタンスである.したがって,クラス属性はClassの属性の一つであり,ただし,そのクラス(Classのインスタンス)についてのみ適用可能で,他のクラスには適用不能である.一般的にあるクラスのあるひとつのインスタンスのみに定義される属性(メソッド)をRubyではsingleton属性(メソッド)と呼び,クラス属性は,各クラスをクラスClassのインスタンスとして,その一種である.要するに,認識後段階の集合がひとつの要素からなる拡大クラスの「部分」に対して定義された属性である,とみなせる.
以上のような議論は,素朴な集合の上では十分に進めることが出来ない.圏
Set↑2↑op は比較的簡単なトポスであるが,
- 真理値は二つではない
- 選択公理(axiom of choice)を満たさない
という通常の集合とは大分異なる性質を持つ.
R3の体系では,このような可変集合の圏によるモデル化によってnullを解釈する.これから述べるように,このモデル化の利点はほかにも多い.
0 件のコメント:
コメントを投稿