昨日の日記 の続き。 id:koji8y さんから、トラックバックで
じゃあ,昨日のスタート Alloy の演習中に僕らが表現したかったこと,
sig A { r: B -> C }で,各 A の各 r が one to one の関係 (functional かつ injective な関係) となること*1を表現するにはどう記述したらいいでしょうね?
(略)sig A { r: B -> C }{ // functional (left-unique) all b: B, c1, c2: C { (b->c1 in r and b->c2 in r) => c1 = c2 } // injective (right-unique) all b1, b2: B, c: C { (b1->c in r and b2->c in r) => b1 = b2 } }とすると,表示したインスタンスは求めている形になっていそう.
でももっと簡単に記述できるるのではないかと...
と追加質問いただいたんですが…これって
sig A { r: B lone -> lone C }
では?シグネチャファクト中の
all b: B, c1, c2: C { (b->c1 in r and b->c2 in r) => c1 = c2 }
って制約は
all b: B { lone b.r }
と同じ意味に読めます。
実際、下記のように書いたアサーションで反例は(スコープをいくつにしても)出ないです。
(アサーションを記述するため、シグネチャファクトや宣言制約を述語内に書き下しています)
sig A { r: B -> C } sig B, C {} pred p1 { all a: A { // functional (left-unique) all b: B, c1, c2: C { (b->c1 in a.r and b->c2 in a.r) => c1 = c2 } // injective (right-unique) all b1, b2: B, c: C { (b1->c in a.r and b2->c in a.r) => b1 = b2 } } } pred p2 { all a: A | a.r in B lone -> lone C } assert equivalence { p1 <=> p2 } check equivalence for 6