4 Equality and the Equality Test Operator

私達はこれまで同等性評価文の単純な例を見てきました。例えば

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つの変数 XY では、操作 X = Y はそれぞれのノードの 併合(merge) を試みます。今、私達は併合操作 X = Y のために、漸増的告知(incremental tell)または単一化(unification)操作として知られる適切なアカウントを与えるべき立場にいます。

一般的に、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 に束縛しようとするでしょう、しかしまた、ab を同等性評価しようとした時にシステムにキャッチされる例外を発生させるでしょう。

4.1同等性テスト演算子(equality test operator) ==

基本的手続き {Value.'==' X Y R}XY が等しいかそうでないかのテストを試み、結果を R に返します。

もし手続きが一時停止すると、スレッド全体が一時停止するという事を覚えておいて下さい!これはあまり有用に見えません。しかしながら、後で見るように、これは複数のスレッドがお互いにやり取りをする時には非常に有用な操作になります。

同等性テストは普通、文としてよりも関数の式(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


1. これは他にもたくさんやり方があります。一つはノード XY を指すようにし、X を参照ノードにする事です。参照ノードのチェインは、どんな単一化操作が行われる前にも常に走査されます(traversed)。

Seif Haridi and Nils Franz�n
Version 1.4.0 (20080704)