Z3 - 正式化阵列模式匹配

时间:2013-06-26 08:16:02

标签: arrays design-patterns z3

我尝试形式化一个函数,该函数将数组和数组列表作为参数,并返回列表中数组的索引。我尝试过非常不同的方法并从Z3获得“未知”。

这是我试过的一些代码,其中第一个和第二个公理都不起作用(还有其他一些我没有在这里包含):

(declare-fun SameArray ((Array Int Real) (Array Int Real)) Bool)
(declare-fun Match ((Array Int Real) (Array Int (Array Int Real))) Int)

(assert (forall ((array1 (Array Int Real)) (array2 (Array Int Real)))
    (= 
      (SameArray array1 array2)
      (ite (forall ((i Int)) (= (select array1 i) (select array2 i) )) true false)
    )
  ) 
)

;(assert (forall ((pattern (Array Int Real)) (list (Array Int (Array Int Real))) )
;  (or
;    (exists ((index Int))
;      (and
;        (= (SameArray pattern (select list index)) true)
;        (forall ((j Int)) (or (= (SameArray pattern (select list j)) false) (>= j index)))
;        (= (Match pattern list) index)
;      )
;    )
;    (= (Match pattern list) (- 1))
;  )
;))

(assert (forall ((pattern (Array Int Real)) (list (Array Int (Array Int Real))) )
  (exists ((index Int))
    (and
      (= (Match pattern list) index)
      (or
        (and
          (= (SameArray pattern (select list index)) true)
          (forall ((j Int)) (or (= (SameArray pattern (select list j)) false) (>= j index)))
        )
        (= index (- 1))
      )
    )
  )
))

; Testing - SameArray

(declare-const a1 (Array Int Real))
(declare-const a2 (Array Int Real))

(assert (= (store a1 1 1.1) a1))
(assert (= (store a1 2 1.2) a1))
(assert (= (store a1 3 1.3) a1))

(assert (= (store a2 1 2.1) a2))
(assert (= (store a2 2 2.2) a2))
(assert (= (store a2 3 2.3) a2))

(assert (= (SameArray a1 a1) true))
(assert (= (SameArray a1 a2) false))

(check-sat)

; Testing - Match

(declare-const aAll (Array Int (Array Int Real)) )

(assert (= (store aAll 1 a2) aAll))
(assert (= (store aAll 2 a1) aAll))

(assert (= (Match a1 aAll) 2))

(check-sat)

编辑: 即使是一个非常简单的虚拟版本也行不通。 我有模式(P => Q)和(不是P => Q')。我不知道为什么Z3给了我一个unknwon。

(assert (forall ((pattern (Array Int Real)) (list (Array Int (Array Int Real))) )
  (=>
    (forall ((j Int)) (= (SameArray pattern (select list j)) false))
    (= (Match pattern list) (- 1))
  )
))

(assert (forall ((pattern (Array Int Real)) (list (Array Int (Array Int Real))) )
  (=>
    (not (forall ((j Int)) (= (SameArray pattern (select list j)) false)))
    (= (Match pattern list) 1)
  )
))

2 个答案:

答案 0 :(得分:0)

我感觉您已停用MBQIAUTO_CONFIG,就像代码this variant中所做的那样。在那里,第一个unknown获得check-sat,第二个获得unsat。如果您同时对set-option进行评论,则会获得satunsat

unsat是预期的,因为push / pop范围内的断言与您的第一个公理相矛盾。

关于unknown vs sat,我必须推测一下。根据我的理解,MBQI试图找到所有未解释符号的解释,也就是说,它试图找到一个模型,这样就可以满足给定的断言。

如果没有MBQI,Z3依赖于E匹配,也就是说,它不会尝试为未解释的符号找到解释。 Z3确实试图找到一个矛盾,但是第一个check-sat所做的断言并不相互矛盾。由于该问题不包含可导出的矛盾,但是Z3知道太少的未解释符号,所有Z3都可以报告unsat

答案 1 :(得分:0)

问题可以解决。主要问题是函数Match刚刚声明并且没有定义,Z3有问题来处理额外的公理。虽然这对SameArray函数没有问题,但Match函数失败了。正确的定义如下:

(define-fun SameArray ((array1 (Array Int Real)) (array2 (Array Int Real))) Bool
  (ite (forall ((i Int)) (= (select array1 i) (select array2 i) )) true false)
)


(define-fun Match ((pattern (Array Int Real)) (list (Array Int (Array Int Real))) ) Int
  (ite 
    (exists ((index Int))
      (and
        (= (SameArray pattern (select list index)) true)
        (forall ((j Int)) (or (= (SameArray pattern (select list j)) false) (>= j index)))
      )
    )
    1 0)
)