Alloy Analyzer のこと
-
Upload
hiromi-ishii -
Category
Technology
-
view
4.874 -
download
1
description
Transcript of Alloy Analyzer のこと
Alloy Analyzer のこと石井 大海
2011年9月23日金曜日
自己紹介• 石井 大海 (id:mr_konn / @mr_konn)
• 早稲田大学数学科二年
• 集合論や論理学、圏論に興味
• Haskell Lover
• 2010 Summer Intern から PFI でバイト中
2011年9月23日金曜日
• Alloy を用いた軽量形式手法の入門本
• 原書よりも最新の情報に準拠!
• Alloy Analyzer 入手先:http://alloy.mit.edu/alloy4/
本日のネタ本
2011年9月23日金曜日
Alloy Analyzer とは?• 有界モデル発見器
• 仕様を記述→満たす/満たさないモデルを検査
• 抽象化・設計段階で用いる
• “軽量”形式手法
2011年9月23日金曜日
形式手法
• 形式手法……お高いんでしょう?
• 従来のモデル検査:定理証明
• 仕様が性質を満たすことを証明する
• 手間と利益が中々バランスしない
2011年9月23日金曜日
“軽量”形式手法• Alloyの基礎:SAT ソルバ
• 反例を簡単に発見できる
• 完全ではないが、莫大な空間を探索できる(10
億以上)のでテストよりかなりの高カバレッジ
• モデルをわかりやすい図で確認出来る
• 小スコープ仮説
• バグを産む様なパターンは大きさに依らない
2011年9月23日金曜日
例
2011年9月23日金曜日
例:騎士と奇人の島パズル
• 住人は騎士か奇人かのいずれか。
• 騎士は常に真実, 奇人は常に嘘を云う
• 島の夫婦にそれぞれの種類を訊いた。夫が答えて曰く「私が騎士なら妻も騎士だ」二人はそれぞれ騎士か奇人か?
── 『スマリヤンの決定不能の論理パズル』より
2011年9月23日金曜日
正答• 夫が騎士だとする。• 夫の云うことは正しいから、妻も騎士• つまり、夫が騎士なら妻も騎士
• これは夫が云ったことそのもの• よって夫は騎士で、従って妻も騎士
2011年9月23日金曜日
Alloy で解くenum 真理値 {真, 偽}enum 騎士か奇人 {騎士, 奇人}abstract sig 命題 {真偽: one 真理値}
abstract sig 人間 { 発言: lone 命題, 種族: 騎士か奇人} { some 発言 => (種族 = 騎士 <=> 発言.真偽 = 真)}
• 真偽値、種別、命題、人間を抽象化
• フィールドとファクトの定義2011年9月23日金曜日
Alloy で解く (2)one sig 夫 extends 人間 {} { 夫が騎士なら妻も騎士 in 発言}one sig 妻 extends 人間 {} { no 発言 }
one sig 夫が騎士なら妻も騎士 extends 命題 {} { 真偽 = 真 <=> (夫.種族 = 騎士 => 妻.種族 = 騎士)}
pred show {}run show
• 先程の定義を使って問題をエンコード• run : pred で定義した述語を満たすモデルを探索
2011年9月23日金曜日
実行結果
• この一つだけが該当
• 夫も妻も騎士である、ということがわかった!
2011年9月23日金曜日
例:金星人と火星人のパズル
• 宇宙人の集まるバー
• 金星人の女性は常に真実、男性は常に嘘を喋り、火星人はその逆
• 男女を見分けられる、Yes/No で答えられる質問は何か?
2011年9月23日金曜日
Alloy で記述 (1)module marsandvenus
enum 惑星 {火星, 金星}enum 男か女 {男, 女}enum 真理値 {真, 偽}
sig 質問 {! 評価: 人間 -> one 真理値}
abstract sig 人間 { 性別: 男か女, 出身: 惑星, 回答: 質問 -> one 真理値} { all q : 質問 | ((性別 = 男 and 出身 = 金星) or (性別 = 女 and 出身 = 火星)) <=> 回答[q] = q.評価[this]}
• 宇宙人と質問の定義
• シグネチャファクトで性別/出身と回答の制約を記述
2011年9月23日金曜日
Alloy で記述 (2)
one sig 金星人の男 extends 人間 {} { 性別 in 男 and 出身 in 金星}
• 金星人の男、火星人の男……を表現
• これもシグネチャファクトで表現• 火星人の男、金星人の女、火星人の女……も同様に定義
2011年9月23日金曜日
質問を見付ける
• 「女だけが Yes と答える質問」を探す述語
• run すれば以上の制約から該当する質問を探し出してくれる
pred 女性発見器(何か: 質問) { all 誰か: 人間 | 誰か.性別 in 女 <=> (誰か.回答[何か] = 真)}fact { one 質問 }run 女性発見器
2011年9月23日金曜日
実行結果
• この一つだけが該当
• この図を基に条件を列挙してみる。
2011年9月23日金曜日
真理表出身 性別 評価 回答火星 男 ○ No火星 女 ○ Yes金星 男 × No金星 女 × Yes
• 「あなたは火星人ですか?」と訊いて
YES と答えれば女性!
2011年9月23日金曜日
業務っぽい例
2011年9月23日金曜日
例:ファイルシステム• 構成要素
• ディレクトリ……ルートが存在
• ファイル
• エイリアス
• エイリアスはディレクトリ or ファイルを参照
2011年9月23日金曜日
こんな感じmodule tour/filesystem
abstract sig Object {}sig Directory extends Object {contents: set Object}
one sig Root extends Directory {}sig File extends Object {}sig Alias extends File {to: Object}
pred show {}run show
2011年9月23日金曜日
実行すると……
• 早速変な例が見付かる
1. どこにもはいっていない子(File)がいる!
2. ディレクトリが循環してしまっている
3. ルートが要素になってしまっている
2011年9月23日金曜日
以下の行を追加fact FileBelongsSomewhere { all f : File | one d : Directory |
f in d.contents}
fact NoRecursiveDirs {! no d : Directory | d in d.contents}
fact RootHasNoSuperDir { no d: Directory | Root in d.contents}
• fact : 常に成り立つ制約を記述
• 直感的に読み易い!
• 実はもっと短く書けます(後述)
2011年9月23日金曜日
再びモデル探索
• 今度は何処にも属さない Directory が
• FileBelongsSomewhere を以下で書き換えfact ObjBelongsSomewhere { all o : Object | one d : Directory | o in d.contents}
2011年9月23日金曜日
すると……
• インスタンスがみつからない!
• RootHasNoSuperDir と
ObjBelongsSomewhere が矛盾!
• all o : Object を all o : Object - Root
にすると良い
2011年9月23日金曜日
今度は
• 相互参照するディレクトリが!
• エイリアスも同様の問題が起きそう• 循環を取り除くにはどうすれば……?
2011年9月23日金曜日
Alloy の仕組み• Alloy では全てが集合であり関係である
• Object = Directory ⊔ File, Alias ⊆ File
• クラス継承関係みたいなもの
• アトム(値)は一点集合で表現
• Root は one 限量子によって一点集合として宣言
• contents : Directory と Object 間の二項関係
• n項関係は、n要素タプルの集合と思えばよい
• 実際には集合は 1 項関係で表現している
2011年9月23日金曜日
集合演算• A + B : A と B の和集合
• A & B : AとB の共通部分
• A - B : A と B の差集合
• A in B : A は B の部分集合 (A ⊆ B)
• アトムは一点集合:所属(A∈B)の意味でも使える
• A = B : A と B は等価
2011年9月23日金曜日
関係演算• P → Q : 直積(P, Qのタプル全体)
• A.B : タプルの結合
• Aの末尾とBの先頭の要素で合致するものを結合して返す
• 例:{(1)} . {1→A, 1→B, 3→B} = {(A), (B)}
例:{1→A, 1→B, 3→B} . {(B)} = {(1), (3)}
• 関数適用みたいなものと思えばいい
2011年9月23日金曜日
関係演算• A[B] : B. A と同じ意味
• 結合性が違うa.b [c] = c.(a.b)
• 関数適用っぽく書くことが出来る
• ~a : 関係 a の転置(タプルの順を逆転)
• ^a, *a : 推移閉包、反射推移閉包
• ^{1→2, 2→3} = {1→2, 2→3, 1→3}
• *{1→2, 2→3} = {1→2, 2→3, 1→3, 1→1, 2→2, 3→3}
2011年9月23日金曜日
組み込み定数• none : 空集合
• 要素のない集合• univ : 全体集合(宇宙、普遍集合)
• 全てのアトムの集まり• iden : 恒等関係
• a.iden = a , iden.a = a (forall a)
2011年9月23日金曜日
限量子• all x : e | F = 全てのeを満たすx で F
• some x : e | F = ある x で F
• no x : e | F = どんな x も F でない
• lone x : e | F = 高々一つの x で F
• one x : e | F = 唯一つの x で F
• 集合の修飾子にも使える
2011年9月23日金曜日
以上を踏まえて…
• 相互参照するディレクトリ/エイリアスを排除するには?
• 推移閉包が使えそう!
2011年9月23日金曜日
修正・追加fact NoRecursiveDirs {! no d : Directory | d in d.^contents}
fact NoRecursiveAliases {! no a : Alias | a in a.^to}
• これで変な関係は取り除けた!
• インスタンス捲っていっても変なのは見えない
2011年9月23日金曜日
ところで
• 出て来るオブジェクトが高々三つしかない?
2011年9月23日金曜日
run コマンド
• run hoge : 述語 hoge が成り立つインスタンスを探索せよ!
• 例では show は空命題だったので、単に与えられた制約を満たす物を探索
• 探索する対象の上限(スコープ)を指定可
pred show {}run show
2011年9月23日金曜日
スコープの指定
• for n で合計 n 個の対象について探査
• デフォルトでは n = 3
• 細かい指定も出来る
• for 4 but 2 Alias, exactly 1 Directory
• 4 つ中最大 2 つの Alias, 正確に1つの Dir
• スコープを上げれば別の不具合が見付かったりする
pred show {} for 4run show
2011年9月23日金曜日
ところで
• 全ての Object が Root から辿れるか?
• 条件から成り立つように思うが…?
• チェックしよう!
2011年9月23日金曜日
assert
• 成り立って欲しい表明(アサーション)を書く
• check hoge で hoge の反例がないか探索
• run と同様スコープ指定可能(default: 3)
assert TrackableFromRoot { all o : Object | o in Root.^contents}
check TrackableFromRoot
2011年9月23日金曜日
実行してみる• 反例がある……!?
• Root から Root へは行けない
• Object - Root としてもよいが、反射推移閉包を使い Root.*contents とすればいい!
2011年9月23日金曜日
修正assert TrackableFromRoot { all o : Object | o in Root.*contents}
check TrackableFromRoot
• 今度は反例が見付からない
• スコープを上げてもなし!
2011年9月23日金曜日
Alloy の柔軟性
• より簡潔な表現が出来る!fact NoRecursiveDirsOrAlias {! no iden & (^contents + ^to)}fact RootHasNoSuperDir {no contents.Root}fact AllObjBelongSomewhere {all o : Object - Root | some contents.o}
assert TrackableFromRoot {Object in Root.*contents
}
2011年9月23日金曜日
まとめ• Alloy は十分軽量で、表現力豊か
• 完璧な仕様・抽象化は難しい
• 仕様の穴は案外ぼろぼろ出て来る• Alloy を使って仕様のバグを見付けよう
• パズルのようで楽しい!
2011年9月23日金曜日
Any Questions?
2011年9月23日金曜日
御清聴ありがとうございました
2011年9月23日金曜日