有没有办法使用Z3来获取涉及集合的约束的模型?

时间:2013-09-16 12:07:29

标签: set z3

我正在尝试在Z3中对模型进行建模,以便我能够找到模型 涉及集合的约束。

我目前使用数组表示一组。元素属于集合 如果数组中的相应条目为true。然后我有一些公理 我在约束中使用它。

以下是SMT 2.0中的一个示例。

(define-sort Set (T) (Array T Bool))

(declare-fun |Set#Card| ((Set Int)) Int)
(assert (forall ((s (Set Int)))
      (!
        (<= 0 (|Set#Card| s))
          :pattern ((|Set#Card| s)))))

(declare-fun |Set#Singleton| (Int) (Set Int))
(assert (forall ((r Int))
      (!
        (select (|Set#Singleton| r) r)
       :pattern ((|Set#Singleton| r)))))
(assert (forall ((r Int) (o Int))
      (iff (select (|Set#Singleton| r) o) (= r o))))
(assert (forall ((r Int)) (= (|Set#Card| (|Set#Singleton| r)) 1)))

(declare-fun s () (Set Int))
(assert (= 1 (|Set#Card| s)))
;(assert (= 1 (|Set#Card| (|Set#Singleton| 1))))
;(assert (not (= 1 (|Set#Card| (|Set#Singleton| 1)))))
(check-sat)
(get-info :reason-unknown)
(get-model)

我的问题是我得到了unknown,因此在大多数情况下都没有模型。 我认为我的公理化太弱了。在上面的例子中我会 喜欢获得包含一个元素的集合s的模型。

有谁知道如何使用Z3来获取约束模型 涉及集?

每个答案都有帮助。也就是说,也许我误解了Z3能做什么 而且做不到。关于如何处理这个问题的想法值得欢迎 (其他工具建议......)。

1 个答案:

答案 0 :(得分:1)

问题是Z3将无法构建满足断言的模型,例如:

(assert (forall ((r Int) (o Int))
      (iff (select (|Set#Singleton| r) o) (= r o))))

一种可能的解决方法是定义|Set#Singleton|而不是公理化它。 我们可以使用const数组运算符和store来定义它。这是一个可能的定义:

(define-fun |Set#Singleton| ((r Int)) (Set Int)
            (store ((as const (Set Int)) false) r true))

Here是带有此定义的修改示例的链接。在使用定义后,Z3返回sat和模型。

在文本界面中,我们必须使用as构造来指定我们想要的常量数组的类型。 请注意,我们可以使用Z3中提供的扩展阵列理论对多个集合操作进行编码。 This paper有其他详细信息。但是,这种方法无法对|Set#Card|函数进行编码。

另一种选择是使用&#34;候选模型&#34;对于unknown结果。这不是理想的解决方案,但有几个用户会这样做。