我对解决此问题的“正确” 方法一无所知,因为可能应该首先定义“正确”。
但是,您可以通过多种方式将其编码为 smt2 公式。
示例 0。
通过简单地强制 index 进入域 [0, 4],你可以让 ite 做你想做的事不需要任何幻数。
(declare-const x Int)
(declare-const index Int)
(assert (= x
(ite (= index 0)
0
(ite (= index 1)
-1
(ite (= index 2)
1
(ite (= index 3)
8
43))))))
(assert (and (<= 0 index) (<= index 4)))
(assert (= x 8))
(check-sat)
(get-model)
返回你想要的模型:
~$ z3 example_00.smt2
sat
(model
(define-fun index () Int
3)
(define-fun x () Int
8)
)
示例 1.
(declare-const x Int)
(declare-const index Int)
(assert (ite (= index 0) (= x 0) true))
(assert (ite (= index 1) (= x (- 1)) true))
(assert (ite (= index 2) (= x 1) true))
(assert (ite (= index 3) (= x 8) true))
(assert (ite (= index 4) (= x 43) true))
(assert (and (<= 0 index) (<= index 4)))
(assert (= x 8))
(check-sat)
(get-model)
返回你想要的模型:
~$ z3 example_01.smt2
sat
(model
(define-fun index () Int
3)
(define-fun x () Int
8)
)
示例 2。
(declare-const x Int)
(declare-const index Int)
(assert (or (not (= index 0)) (= x 0))) ;; (= index 0) -> (= x 0)
(assert (or (not (= index 1)) (= x (- 1))))
(assert (or (not (= index 2)) (= x 1)))
(assert (or (not (= index 3)) (= x 8)))
(assert (or (not (= index 4)) (= x 43)))
(assert (and (<= 0 index) (<= index 4)))
(assert (= x 8))
(check-sat)
(get-model)
返回你想要的模型:
~$ z3 example_02.smt2
sat
(model
(define-fun index () Int
3)
(define-fun x () Int
8)
)
示例 3。
使用数组理论
(declare-fun x () Int)
(declare-fun index () Int)
(declare-const ar (Array Int Int))
; array's locations initialization
(assert (= (store ar 0 0) ar))
(assert (= (store ar 1 (- 1)) ar))
(assert (= (store ar 2 1) ar))
(assert (= (store ar 3 8) ar))
(assert (= (store ar 4 43) ar))
; x = ar[index]
(assert (= (select ar index) x))
; bound index to fall within specified locations
(assert (and (<= 0 index) (<= index 4)))
; x = 8
(assert (= x 8))
; check
(check-sat)
(get-model)
返回你想要的模型:
~$ z3 example_03.smt2
sat
(model
(define-fun x () Int
8)
(define-fun ar () (Array Int Int)
(_ as-array k!0))
(define-fun index () Int
3)
(define-fun k!0 ((x!0 Int)) Int
(ite (= x!0 2) 1
(ite (= x!0 3) 8
(ite (= x!0 1) (- 1)
(ite (= x!0 0) 0
(ite (= x!0 4) 43
5))))))
)
其他示例也是可能的。
理想情况下,人们会选择 z3 在求解公式时具有最佳性能的编码。在这方面我无法帮助您,因为我通常与其他 SMT 求解器打交道。
一般来说,使用更复杂的理论(例如数组理论)会导致运行时执行更昂贵的例程,因此人们可能认为最好避免它。但是,我会说,根据我的经验,这不是一般的经验法则,因为即使编码的微小变化也会导致显着的性能差异并且非常差或naive 编码可能会执行得非常糟糕。因此,最好对各种候选编码执行广泛的基准测试。