我正在尝试在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能做什么 而且做不到。关于如何处理这个问题的想法值得欢迎 (其他工具建议......)。
答案 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
结果。这不是理想的解决方案,但有几个用户会这样做。