<< Prev | - Up - | Next >> |
私達はこれまで同等性評価文の単純な例を見てきました。例えば
W = tree(I Y LT LR)
これらは何が起こっているかを直観的に理解するのに十分な程に単純でした。しかし、2つの未束縛の変数が X = Y
の様に同等性評価されたり、2つの大きなデータ構造が同等性評価されたりする時、何が起こるでしょうか。短い説明をします。私達はストア(store)を ノード(node) と呼ばれるメモリ単位(memory words)の動的に拡張可能な配列と考える事が出来ます。各ノードは論理変数を使ってラベル付けされます。変数 X
がストアに新しく作られたノードに導入される時、X
とラベル付けされ、値 unknown を持ちます。この時点では、いかなる実際の値も持ちません; それはコンテナとしては後で埋められるかもしれない空っぽのものです。
ノードにラベリングする時にその値が unknown である変数は 未束縛(unbound) の変数です。ノードは任意の Oz の値を格納するのに十分な柔軟性があります。次の操作
W = tree(1:I 2:Y 3:LT 4:LR)
はレコード構造を W
によって紐付けられたノードにストアします。私達は正にグラフ構造を得たという事に注目して下さい。このノードは4つのフィールドを持つレコードを含みます。フィールドはそれぞれ I
,Y
,LT
, LR
とラベル付けられたノードを指し示す弧(arc)を持ちます。それぞれの弧は順々にレコードの対応するフィールド名によってラベル付けされます。与えられた2つの変数 X
と Y
では、操作 X = Y
はそれぞれのノードの 併合(merge) を試みます。今、私達は併合操作 X = Y
のために、漸増的告知(incremental tell)または単一化(unification)操作として知られる適切なアカウントを与えるべき立場にいます。
X と Y が同じノードをラベル付けするなら、操作は成功のうちに完了です。
X (あるいは Y) が未束縛ならば X (あるいは Y) のノードは Y (あるいは X) のノードへと併合されます。併合は、ノード X への全ての参照を Y1 へと置き換える事を意味します。概念的には元々の X のノードは破棄された事になります。
X と Y がそれぞれ Rx と Ry というレコードを含んでいる異なるノードをラベル付けしているなら:
Rx と Ry は異なるラベル、引数、またはそのどちらもを持ちます: 操作は完了し、例外が発生します。
そうでなければ、Rx と Ry の同じフィールド名の引数は任意の順序でペアとして併合されます。
一般的に、2つのグラフがマージされると、循環を持つことがあります。しかしながらどの適正な併合操作の実装も以前にマージを試みたノードのペアを記憶しており、操作は正しく行われると考えられます。漸増的告知のより形式的な記述は [Har98] に見られます。
変数がアクセス可能でなくなると、ガベージコレクション(garbage collection)がノードを回収します。
ここに、正しい同等性評価操作のいくつかの例を示します:
local X Y Z in
f(1:X 2:b) = f(a Y)
f(Z a) = Z
{Browse [X Y Z]}
end
上は browser に [a b R14=f(R14 a)]
を表示するでしょう。R14=f(R14 a)
は循環グラフの外部表現です。
注意: Z の有限表現を見るには、Browser を Minimal Graph 表示モードに切り替えなければなりません。Option メニュー、Representation フィールドを選択し、Minimal Graph をクリックします。
注意: Browser は ``The Oz Browser'' に記述されています。
以下の例は整合性の無い値が同等性評価された時に何が起こるかを示しています。
declare X Y Z in
X = f(c a)
Y = f(Z b)
X = Y
X = Y
の漸増的告知は Z
を値 c
に束縛しようとするでしょう、しかしまた、a
と b
を同等性評価しようとした時にシステムにキャッチされる例外を発生させるでしょう。
==
基本的手続き {Value.'==' X Y R}
は X
と Y
が等しいかそうでないかのテストを試み、結果を R
に返します。
グラフがX
から始まり Y
も同じ構造を持っていてそれぞれ対応するペアが同一の Oz の値を持っているか同じノードであるならば、ブール値 true
が返ってきます。
グラフが異なる構造かそれぞれ対応するペアが異なる値を持っているならば、ブール値 false
が返ってきます。
対応するペアのノードが異なっていて、しかし少なくともその一方が未束縛である場合は、一時停止します。
もし手続きが一時停止すると、スレッド全体が一時停止するという事を覚えておいて下さい!これはあまり有用に見えません。しかしながら、後で見るように、これは複数のスレッドがお互いにやり取りをする時には非常に有用な操作になります。
同等性テストは普通、文としてよりも関数の式(expression)として使われます。{Value.'==' X Y R}
は 中置の ==
演算子を使って R = X==Y
とも書けます。さらなる例を下に示します:
% リストはただのレコードのタプルである事を見ましょう
local L1 L2 L3 Head Tail in
L1 = Head|Tail
Head = 1
Tail = 2|nil
L2 = [1 2]
{Browse L1==L2}
L3 = '|'(1:1 2:'|'(2 nil))
{Browse L1==L3}
end
<< Prev | - Up - | Next >> |