ZTL中的SMTLIB阵列理论奇怪

时间:2012-02-24 13:43:41

标签: arrays z3 smt

在使用SMTLIB阵列时,我注意到Z3对该理论的理解与我的理解之间存在差异。我使用的是SMTLIB阵列理论[0],可以在官方网站上找到[1]。

我认为用一个简单的例子可以很好地说明我的问题。

(store (store (store ((as const (Array Int Int)) 0) 0 1) 1 2) 0 0)
       (store (store ((as const (Array Int Int)) 0) 0 1) 1 2)

第一个数组应该在索引1处返回2,对于所有其他索引应该返回0,第二个数组应该在索引0处返回1,在索引1处返回2,对于所有其他索引应该返回0。在索引0处调用select似乎证实了这一点:

(assert
    (=
        (select (store (store (store ((as const (Array Int Int)) 0) 0 1) 1 2) 0 0) 0)
        0
    )
)
(assert
    (=
        1
        (select        (store (store ((as const (Array Int Int)) 0) 0 1) 1 2)      0)
    )
)

Z3为两者返回sat

(assert
    (=
        (select (store (store (store ((as const (Array Int Int)) 0) 0 1) 1 2) 0 0) 0)
        (select        (store (store ((as const (Array Int Int)) 0) 0 1) 1 2)      0)
    )
)

正如预期的那样,在这种情况下,Z3(如果重要,我在linux-amd64上使用的是3.2版本)会回复unsat。接下来,让我们比较这两个数组:

(assert
    (=
        (store (store (store ((as const (Array Int Int)) 0) 0 1) 1 2) 0 0)
               (store (store ((as const (Array Int Int)) 0) 0 1) 1 2)
    )
)

Z3告诉我sat,我将其解释为“这两个数组比较相等”。但是,我希望这些数组不要相等。我的基础是SMTLIB阵列理论,它说:

- (forall ((a (Array s1 s2)) (b (Array s1 s2)))
    (=> (forall ((i s1)) (= (select a i) (select b i)))
            (= a b)))

所以,用简单的英语来说,这意味着“两个数组应该相等,如果,并且只有它们对所有指数都相等”。任何人都可以向我解释一下吗?我错过了什么或误解了理论吗?对于你在这个问题上的任何想法,我将不胜感激。

祝你好运, 利昂

[0] http://goedel.cs.uiowa.edu/smtlib/theories/ArraysEx.smt2 [1] http://smtlib.org

1 个答案:

答案 0 :(得分:3)

感谢您报告此问题。这是数组预处理器中的一个错误。预处理器在调用实际解算器之前简化了数组表达式。该错误仅影响使用常量数组的问题(例如,((as const (Array Int Int)) 0))。您可以通过不使用常量数组来解决该错误。我修复了错误,修复程序将在下一个版本中提供。