| 充足可能性問題について |
| SATソルバって何。 |
| a3 | a2 | a1 | ||
| × | b2 | b1 | ||
| (a3∧b1) | (a2∧b1) | (a1∧b1) | ||
| (a3∧b2) | (a2∧b2) | (a1∧b2) | ||
| + | c2 | c1 | ||
| 0 | 1 | 0 | 1 | |
| 式 | CNF式 |
|---|---|
| X = 1 | X |
| X = 0 | X |
| Y = X | (X∨Y) ∧ (X∨Y) |
| Y = X | (X∨Y) ∧ (X∨Y) |
| Z = X ∧ Y | (X∨Z) ∧ (Y∨Z) ∧ (X∨Y∨Z) |
| Z = X ∨ Y | (X∨Z) ∧ (Y∨Z) ∧ (X∨Y∨Z) |
| Z = X ⊕ Y | (X∨Y∨Z) ∧ (X∨Y∨Z) ∧ (X∨Y∨Z) ∧ (X∨Y∨Z) |
| SATソルバの作り方。 手法1 - バックトラック |
def doit():
for a in [0, 1]:
for b in [0, 1]:
for c in [0, 1]:
for d in [0, 1]:
for e in [0, 1]:
if f(a,b,c,d,e):
return SAT
return UNSAT
decisions = [] # 決めた値 implications = [] # 推論した値 while 未定義の変数がある: decide() # ひとつ決める bcp() # 推論する if 失敗: undo() # もとに戻す flip() # 別の選択肢を試す if 失敗: return UNSAT # もう試すものがない return SAT
decide)。
bcp)。
bcp)。
decide)。
decide)。
bcp)。
bcp 失敗)。
undo)。
flip)。
decide)。
decide()
# 未定義の変数の値をひとつ決める
def decide():
for v in 各変数:
if v == 未定義:
decisions.append((v, 1))
break
decisions に記録される。
bcp()# 推論して値を決める def bcp(): for C in 各CNF節: if Cはすでに充足している: continue # Cはまだ充足していない。 U = [ C中の変数で、未定義なもの ] if len(U) == 0: # 変更の余地なし return 失敗 elif len(U) == 1: # テンパってる implications.append((v, 0または1)) return 成功
while level < N: # level = 現在の段階 decide(level) # ひとつ決める bcp(level) # 推論する if 成功: level += 1 # 次の段階へ else: level = まだ選択肢がある段階 undo(level) # その状態に戻す flip(level) # 別の選択肢を試す if 失敗: return UNSAT return SAT
bcp() が遅い。
def bcp():for C in 各CNF節: # ループ1 if Cはすでに充足している: continue U = [ C中の変数で、未定義なもの ] # ループ2...
| SATソルバの作り方。 手法2 - Resolution |
| SATソルバの作り方。 手法3 - 学習する |
# Conflict Driven Clause Learning 法 decisions = [] # 決めた値 implications = [] # 推論した値 while 未定義の変数がある: decide() # ひとつ決める bcp() # 推論する if 失敗:learn(decisions) # 失敗から学ぶundo() # もとに戻す flip() # 別の選択肢を試す if 失敗: return UNSAT # もう試すものがない return SAT
decide) とする。
decide() する
順番をより賢く決める (a la DPLL法)。
| SATソルバとSMTソルバ。 |
| a1 | a2 | a3 |
| a4 | a5 | a6 |
| a7 | a8 | a9 |
(declare-const a1 Int) ; a1は整数型。 ... (assert (<= 1 a1 9)) ; 1 <= a1 <= 9 ... (assert (distinct a1 a2 ... a9)) ; a1...a9は異なる。 ... (assert (= (+ a1 a2 a3) ... (+ a3 a5 a7))) (check-sat) ; 制約充足可能性をチェック。 (get-model) ; 可能なときの値を表示。
| まとめ。 |
cdcl.py