モデルの出力 (私の場合は sat と unsat のみ) を別のモデルで使用したいと考えています。ここで、モデルとは、一連の論理式 (この場合は Z3 式) に含まれる定数への満足のいく代入です。私の目的は、次のように簡単に説明できます。
私の問題は、次のように詳細に説明できます。形式化された問題 P、つまり、いくつかの制約 (C) に対応する一連の論理式 (式) があります。そのうちの 1 つ (例: Ai > 0) が目的です。モデル/形式化 P を実行すると、すべての制約が満たされる場合、sat が返されます。Ai = 0 は常に可能であることに注意してください。ここで、特定の変数セットへの代入セットが、Ai > 0 (任意の i について) が不可能であることを保証する制約 (C) に対応することを見つけたいと考えています。現在、制約 (つまり、制約値) の DFS ベースの検索アルゴリズムを開発し、P を実行して "push/pop "。検索を改善しようとしましたが、あまり役に立ちません。問題のサイズが大きい場合、これは非常に非効率的です。このような満足できるセットを検索するために、P を使用する別の SMT プログラム (モデル) を作成できれば素晴らしいと思います。
問題 P (元の問題の短い SMT LIB 2 バージョン) の現在の形式化は次のとおりです。
(declare-fun th1 () Real)
(declare-fun th2 () Real)
(declare-fun th3 () Real)
(declare-fun th4 () Real)
(declare-fun th5 () Real)
(declare-fun l1 () Real)
(declare-fun l2 () Real)
(declare-fun l3 () Real)
(declare-fun l4 () Real)
(declare-fun l5 () Real)
(declare-fun l6 () Real)
(declare-fun l7 () Real)
(declare-fun p1 () Real)
(declare-fun p2 () Real)
(declare-fun p3 () Real)
(declare-fun p4 () Real)
(declare-fun p5 () Real)
(declare-fun sl1 () Int)
(declare-fun sl2 () Int)
(declare-fun sl3 () Int)
(declare-fun sl4 () Int)
(declare-fun sl5 () Int)
(declare-fun sl6 () Int)
(declare-fun sl7 () Int)
(declare-fun sp1 () Int)
(declare-fun sp2 () Int)
(declare-fun sp3 () Int)
(declare-fun sp4 () Int)
(declare-fun sp5 () Int)
(declare-fun a1 () Int)
(declare-fun a2 () Int)
(declare-fun a3 () Int)
(declare-fun a4 () Int)
(declare-fun a5 () Int)
(declare-fun na () Int)
(declare-fun ns () Int)
(declare-fun attack () Bool)
;;;; System
(assert (and (= l1 (* (- th2 th1) 17.0))
(= l2 (* (- th5 th1) 4.5))
(= l3 (* (- th3 th2) 5.05))
(= l4 (* (- th4 th2) 5.65))
(= l5 (* (- th5 th2) 5.75))
(= l6 (* (- th4 th3) 5.85))
(= l7 (* (- th5 th4) 23.75))
(= p1 (+ l1 l2))
(= p2 (+ l1 l3 l4 l5))
(= p3 (+ l3 l6))
(= p4 (+ l4 l6 l7))
(= p5 (+ l2 l5 l7))
)
)
;;;; Secured measurements
(assert (and (or (= sl1 0) (= sl1 1))
(or (= sl2 0) (= sl2 1))
(or (= sl3 0) (= sl3 1))
(or (= sl4 0) (= sl4 1))
(or (= sl5 0) (= sl5 1))
(or (= sl6 0) (= sl6 1))
(or (= sl7 0) (= sl7 1))
(or (= sp1 0) (= sp1 1))
(or (= sp2 0) (= sp2 1))
(or (= sp3 0) (= sp3 1))
(or (= sp4 0) (= sp4 1))
(or (= sp5 0) (= sp5 1))
)
)
(assert (and (=> (not (= l1 0.0)) (= sl1 0))
(=> (not (= l2 0.0)) (= sl2 0))
(=> (not (= l3 0.0)) (= sl3 0))
(=> (not (= l4 0.0)) (= sl4 0))
(=> (not (= l5 0.0)) (= sl5 0))
(=> (not (= l6 0.0)) (= sl6 0))
(=> (not (= l7 0.0)) (= sl7 0))
(=> (not (= p1 0.0)) (= sp1 0))
(=> (not (= p2 0.0)) (= sp2 0))
(=> (not (= p3 0.0)) (= sp3 0))
(=> (not (= p4 0.0)) (= sp4 0))
(=> (not (= p5 0.0)) (= sp5 0))
)
)
(assert (and (= sl1 1) (= sl2 1)))
;;;; Attacks
(assert (and (or (= a1 0) (= a1 1))
(or (= a2 0) (= a2 1))
(or (= a3 0) (= a3 1))
(or (= a4 0) (= a4 1))
(or (= a5 0) (= a5 1))
)
)
(assert (and
(= (not (= th1 0.0)) (= a1 1))
(= (not (= th2 0.0)) (= a2 1))
(= (not (= th3 0.0)) (= a3 1))
(= (not (= th4 0.0)) (= a4 1))
(= (not (= th5 0.0)) (= a5 1))
)
)
(assert (= th1 0.0)) // Base condition
(assert (= na (+ a1 a2 a3 a4 a5)))
(assert (=> attack (> na 1)))
;;;; Check for satisfiable model
(assert attack)
(check-sat)
(get-model)
(exit)
たとえば、次のように、制約が与えられた場合に攻撃が発生しないように (つまり、na が 0 になるように)、セキュリティ測定値を合成します (つまり、「sl」および「sp」項の割り当てを見つけます)。
(assert (= ns (+ sl1 sl2 sl3 sl4 sl5 sl6 sl7 sp1 sp2 sp3 sp4 sp5)))
(assert (<= ns 4))
この場合、アサーション (すなわち、'(assert (and (= sl1 1) (= sl2 1)))' ) はコメント化されます。現在、'sl' と 'sp' の割り当てを受け取り、(assert (and (= sl1 1) (= sl2 1) ...))' のようにアサートし、指定されたプログラムを実行する C# プログラムを開発しました。可能な攻撃があるかどうかを確認します。プログラムが unsat を返したら完了です (つまり、na > 1 はあり得ません)。SMT (Z3) のみを使用して問題を解決する方法はありますか?