Z3 ForAll on Arrays

时间:2017-01-06 05:17:29

标签: arrays z3 first-order-logic

我已经设法使用Z3创建了一个记录数组,但现在我很难看到我需要在数组上执行$ \ forall $操作的语法...这里是一个SMT-LIB2代码的片段示例到目前为止。

(declare-datatypes () ((rec (mk-R5 (age Int) (area Int) (married Bool)))))
(declare-const recs (Array Int rec))
(declare-const r1 rec)
(assert(= (age r1) 15))
(assert(= (area r1) 10001))
(assert(= (married r1) true))
(declare-const r2 rec)
(assert(= (age r2) 35))
(assert(= (area r2) 2845))
(assert(= (married r2) true))
(declare-const x Int)
(declare-const y Int)
(assert (= recs (store recs x r1)))
(assert (= recs (store recs y r2)))
(assert(forall ((i rec)) (= (married i) true)))
(check-sat)
(get-model)

我猜第三行应该对数组有一些参考,但是我已经尝试了所有内容,但教程并没有帮我解决这个问题。

如何对我在这里的数组执行$ \ forall $操作?

1 个答案:

答案 0 :(得分:2)

看起来你正在尝试将两个记录放在一个数组中,然后对这些元素说些什么。不幸的是,你的编码并不意味着。

首先要注意的是以下行的含义:

   (declare-const recs (Array Int rec))

这表示recs是由所有整数索引的数组。也就是说,域是所有 Int 值的集合。这可能不是你的意思。

另外,行:

(assert (= recs (store recs x r1)))
(assert (= recs (store recs y r2)))

写得更好:

(assert (= (select recs x) r1))
(assert (= (select recs y) r2))

将其视为您对索引xy所了解的内容;而不是在您尝试编写时“修改”recs的一些命令性赋值语句。没有修改smt-lib中任何值的概念;你只需陈述你所知道你正在建造的模型的真实情况。

修复你的forall-assertion的一种方法就是这样写:

(assert (forall ((i Int)) 
                (implies (or (= i x) (= i y)) 
                         (= (married (select recs i)) true))))

我们对指数进行量化,并说如果索引是iy,则这些记录中有married个人。通过这些修改,Z3回应:

sat
(model
  (define-fun r2 () rec
    (mk-R5 35 2845 true))
  (define-fun recs () (Array Int rec)
    (_ as-array k!0))
  (define-fun y () Int
    1)
  (define-fun x () Int
    0)
  (define-fun r1 () rec
    (mk-R5 15 10001 true))
  (define-fun k!0!2 ((x!0 Int)) rec
    (ite (= x!0 1) (mk-R5 35 2845 true)
      (mk-R5 15 10001 true)))
  (define-fun k!1 ((x!0 Int)) Int
    (ite (= x!0 0) 0
      1))
  (define-fun k!0 ((x!0 Int)) rec
    (k!0!2 (k!1 x!0)))
)

这有点难以阅读,但它确实为您提供了您指定的模型。

然而,在我看来,这并不是你想要塑造的;但是你的问题很难说清楚。如果您描述了您尝试解决的实际问题,答案可能会更有帮助。