Alloyガール6

ここまでの話はこちら: Alloy

ドットは結合

僕: ひさしぶり
Alloy: ひさしぶり
僕: で、どういう話だっけ
Alloy: もう忘れたの?あなたがドット演算子JavaScriptのメンバアクセス演算子と混同してた話よ。
僕: いちいち言い方がキツイなぁ。まあ、そういう話だったね。今日は「ドットは結合だ」ってのを詳しく教えてもらおう。
Alloy: そうね、まず説明のためにもっとシンプルな関係を作ってみましょう

run {
	some rel: Int -> Int {
		rel = (1 -> 2) + (2 -> 3) + (3 -> 4)
	}
}

JS: 1増えるのね?
僕: なるほど。someで選ばれた対象はEvaluatorから名前でアクセスできるってのを使うわけか。
Alloy: そういうこと。さあEvaluatorを開いて確認してみましょう。
僕: JSちゃん、Evaluatorに$relって入力してごらん?

JS: $rel、っと。うん、それっぽいのが表示されたよ。
Alloy: じゃあその関係をドットで結合した $rel . $rel を計算してみて。
JS: 「関係ドット関係」なんてのができるの?
僕: ドットは「関係の結合演算」なんだよね。お休みのうちに実は勉強したんだ。
JS: $rel . $relっと。あ、{1 -> 3, 2 -> 4}って出たよ。2増えるようになった?なんで?
Alloy: (2 -> 7)とかと結合してみたらわかりやすいんじゃない?
JS: 今度は{1 -> 7}になった!
Alloy: つまり$relの中の(1 -> 2)と(2 -> 7)が結合して(1 -> 7)になったわけよ。
JS: だから結合演算子って言うのかー☆

プロパティアクセス風

JS: 結合演算子はわかったけど、プロパティアクセスは?
Alloy: え、まだ分からないの?アリティが1の関係のシングルトンと結合演算をすればプロパティアクセスに見えるでしょ?
JS: ????
僕: 1 . $rel を計算してごらん。
JS: {2}って返ってきたよ
僕: 要するに、さっき(1 -> x)と(x -> 7)が結合して(1 -> 7)になったように、(x)と(x -> 2)が結合したら(2)になるんだよ。
JS: あー、それでプロパティアクセス風になるのか☆
Alloy: プロパティアクセスだっていう理解の仕方は足元をすくわれそうな気がするわね。たとえばこういう例を考えてみましょう。

run {
	some rel: Int -> Int {
		rel = (1 -> 2) + (2 -> 3) + (2 -> 4)
	}
}

JS: (3 -> 4)の代わりに(2 -> 4)になったのね。
Alloy: この状態で1.$rel、2.$rel、3.$relはそれぞれ何になるでしょう
僕: 3.$rel とか そもそも$relの定義域に入ってないね
Alloy: 関係の場合は定義域じゃなくて始集合という方が一般的かしら。
JS: 3の時は簡単だね!
僕: え、そう?
JS: undefinedが返るんでしょ?
僕: そんなわけないじゃん…
JS: えー、でも3からrelをたどった先なんて定義されていないよ?
僕: 定義されていないんじゃなくて、存在しないんでしょ?
JS: あ、そうか、じゃあ空リスト?
僕: 空集合
JS: そっかー

Int型というよりIntの集合型

Alloy: じゃあ 2.$rel は?
JS: (2 -> 3) と (2 -> 4) とあるから…どっちかなぁ。あとので上書きかなぁ?だから4?
僕: これは集合{3, 4}だよね。
Alloy: そのとおり。
JS: なんだー、じゃあInt->Intって書いてあっても、Intを取ってIntを返すって言うよりは、Intの集合を返すと考えたほうがいいのね。
Alloy: うーん、なんだかやっぱり他の言語の発想に囚われてる感じがするわね。(1 + 2).$relとか$rel.4とか試してみたら?

僕: そうか、単に結合するだけだから左辺がスカラーじゃなくて集合でもいいし、関係を左辺に持ってきてもいいわけか。
Alloy: そうね。そもそもあなたが集合と呼んでいるものはアリティが1の関係だし、スカラーって呼んでいるのはアリティが1の関係で位数が1のものね。
僕: なるほど、何もかも関係なのか。
Alloy: だから関係演算が言語の基本構成ブロックになるわけよ。