Z3中的量词和数组

时间:2016-12-20 17:19:29

标签: arrays z3 quantifiers

Z3回答"未知"当使用数组上的量词给出这段代码时:

(declare-const ia Int)
(declare-const ib Int)
(declare-const la Int)
(declare-const lb Int)
(declare-const A (Array Int Int))
(declare-const a (Array Int Int))
(declare-const b (Array Int Int))

(assert 
    (exists 
        ((ia_1 Int) (ia_2 Int) (ib_1 Int) (la_0 Int) (lb_0 Int) (A_0 (Array Int Int)) (a_0 (Array Int Int)) (b_0 (Array Int Int)))
        (and (= ia ia_2) (= ib ib_1) (= la la_0) (= lb lb_0) (= A A_0) (= a a_0) (= b b_0) (= ia_1 0) (= ib_1 0) (< ia_1 la_0) (< ib_1 lb_0) (< (select a_0 ia_1) (select b_0 ib_1)) (= ia_2 (+ ia_1 1)))))

(assert 
    (not 
        (exists 
            ((ia_1 Int) (ib_1 Int) (la_0 Int) (lb_0 Int) (A_0 (Array Int Int)) (a_0 (Array Int Int)) (b_0 (Array Int Int)))
            (and (= ia ia_1) (= ib ib_1) (= la la_0) (= lb lb_0) (= A A_0) (= a a_0) (= b b_0) (= ib_1 0)))))

(check-sat)

在这种情况下,有没有办法获得正确答案(&#34;不满&#34;)?

编辑:Z3正确回答&#34; sat&#34;例如,如果将约束(= ia_1 0)添加到第二个连词。

1 个答案:

答案 0 :(得分:0)

在这里,&#34;未知&#34;是一个正确的&#34;回答。通常,数组上的量词不可判定(至少不在进一步的假设下)。 Z3放弃了这个例子,因为它的默认量词实例化启发式方法没有找到正确的实例化模式。有关详细信息,请参阅quantifiers in the Z3 tutorial部分。

我们可以指定我们自己的实例化模式来帮助Z3,或者我们至少可以重述问题,以便启发式自动找到正确的模式。在这种情况下,我通过重写第二个量词就成功了:

(assert 
    (forall ((la_0 Int) (lb_0 Int) (A_0 (Array Int Int)))
            (and 
                (= A A_0) 
                (= la la_0) 
                (= lb lb_0)
                (forall ((b_0 (Array Int Int)) (ib_1 Int))
                    (and 
                        (= b b_0)
                        (= ib ib_1)
                        (= ib_1 0)
                        (forall ((a_0 (Array Int Int)) (ia_1 Int))
                            (not (and (= ia ia_1) (= a a_0))))                       
                        )))))

每个子量词的参数越少,它就越有可能获得有用的东西(我认为),但这当然并不总是足够的。