Satisfiability solver The Deduction algorithm

Satisfiability solver
The Deduction algorithm
Deductionとは
• 探索木の先を見る。
• Decisionの変数割り当ての結果を返す事が目的。
• 戻り値は3種類
– SATISFIABLE
– CONFLICT
– UNKNOWN
• UNKNOWNが出る限り、Decisionを繰り返す。
Unit Clause Rule(1)
• Deduction mechanismの一つ。
• 最も効率的だと言われている。
• SATのほとんどでこの手法が使われている。
Unit Clause Rule(2)
定義
Clause内のLiteralに関して、1つのLiteralを除く全
てのLiteralがFalseの場合、残りのLiteralはTrueと
割り当てる事が出来る。
具体例
(¬A ∨ B ∨ C ∨ ¬D)
前提:A = True , B = False , C = False
結果:Unit Clause Ruleより、D = Falseとなる。
BCP mechanism
• Boolean Constraint Propagation
• Decisionの後に、Unit ClauseやConflictを
検知するために使う。
• ソルバのデータ構造や振舞いを定義する。
– Counter-Based BCP
– Head/Tail List
– 2-Literal Watching
Counter-Based BCP(1)
• 全てのClauseにカウンタを用意する方法。
• 昔は数多くのソルバで適用されていた。
• Counter-Based BCPの一例
– 各Clauseは2つのカウンタを所有する。
• それぞれTrue/FalseなLiteralの数をカウント
– 各変数は2つのリストを持っている
• それぞれ正/負Literalが出現するClauseを保持
Counter-Based BCP(2)
• 変数割り当てがあると、Clauseのカウンタが更新
される。
– ClauseのFalseカウンタがLiteralの数と等しくなった場
合、CONFLICTである。
– ClauseのFalseカウンタがLiteralの数より1少なくなった
場合、Unit Clauseである。
• コストが高い特徴がある
– m個のClause 変数がn種類 各Clauseが平均l個の
Literalを持つ場合、コストはlm/nとなる。
Head/Tail List(1)
• 各Clauseは2つのポインタを所有。
– それぞれ、HeadポインタとTailポインタと呼ぶ
• Clauseは全てのLiteralを配列で保持する。
– 最初は、HeadポインタはClauseの先頭Literalを、Tailポインタは
末尾Literalを指す
• 各変数は4つのLinked Listを保持する。それぞれ
Head/Tailにポイントされているというフラグを表す。
–
–
–
–
Clause_of_pos_head(v)
Clause_of_neg_head(v)
Clause_of_pos_tail(v)
Clause_of_neg_tail(v)
Head/Tail List(2)
• 例えばClause_of_neg_head(v)は、¬vが
Headポインタに指されているClauseを保持
するリストである。
Head/Tail List 例題(1)
例えば変数vがTrueを割り当てられた時の
事を考えてみよう。まず、矛盾やUnit
Clauseを探すには関係のない
Clause_of_pos_head(v)と
Clause_of_pos_tail(v)は無視される。その
ため、neg_head(v)を考えてみる。
neg_head(v)内のClauseに関して探索を行
う。
Head/Tail List 例題(2)
探索プロセスにおけるケース
1. 探索を始めて、TrueになってるLiteralを発見した場
合、Clauseは充足しているので何もしない。
2. 探索を始めて、最初に自由変数wを見つけた場合、
neg_head(v)よりこのClauseを削除し、head(w)にこの
Clauseを追加する。
3. もし2つのポインタ間のLiteralが全てFalseに割り当
てられていて、tail Literalが割り当てられていなけれ
ば、これはUnit Clauseである。
4. もし2つのポインタ間のLiteralが全てFalseに割り当
てられていて、Tail Literalが0に割り当てられていた
ら、ClauseはCONFLICTである。
Head/Tail List(3)
• Head/Tail ListはCounter-Basedよりも速い。
– 例えば変数がTrueと割り当てられた時、
Head/Tailが正LiteralなClauseには訪問しない。
– ポインタ操作のコストはm/nである。(m:Clause
の数、n:Literalの種類数)
• Counter-BaseとHead/TailはBacktrackに弱
い性質を持つ
– 変数割当のUndoが複雑
2-Literal Watching(1)
• 各Clauseは2つのポインタを所有
– Watching Literal(監視リテラル)と呼ぶ。
• 各変数は2つのリストを所有する。それぞ
れの変数が出現するClauseを保持する。
– Pos_Watched(v)
– Neg_Watched(v)
• 実行開始時のポインタ位置はどこでも良い。
• ポインタの移動方向も特に定めない。
2-Literal Watching 例題(1)
変数vがTrueを割り当てられた時の事を考
えてみる。Head/Tailと同様、Posのリストは
無視する事になる。そこで、Neg(v)に入っ
ているClauseを考える。まず、Clause内の
FalseでないLiteral L を探す。この探索中に
は4つのケースが起きる可能性がある。
2-Literal Watching 例題(2)
Negに割当があったケースの分岐
1. もう一方の監視Literalに監視されていないLが存在
したら、Neg(v)よりこのClauseを削除し、Lの正/負に
そったリストにこのClauseを追加する。この操作をポ
インタの移動と呼ぶ。
2. もう一方の監視LiteralしかLが存在しなく、さらにLが
自由変数ならば、Unit Clauseである。
3. もう一方の監視LiteralしかLが存在しなく、さらにLが
Trueな時、何もしなくて良い。
4. もし全てのClauseがFalseに割り当てられ、Lが存在
しない場合、CONFLICTである。
2-Literal Watching(2)
• Literal Countingフェーズにおいて、Head/Tailと同
等の性能を持つ。
• バックトラックにおいて、変数割当のUndoは一定
の時間しかかからない。なぜなら2つの監視
LiteralはFalseになった最後のLiteralだからであ
る。
– バックトラック時、監視Literalは共に割当無しになるか、
Trueとなる。
– つまりポインタを移動する必要がない。