Set 有没有一种方法可以使用Z3来获取涉及集合的约束的模型?

Set 有没有一种方法可以使用Z3来获取涉及集合的约束的模型?,set,z3,Set,Z3,我试图在Z3中对集合进行建模,这样我就能够找到要创建的模型 涉及集合的约束 我当前使用数组表示一个集合。元素属于集合 如果数组中的对应项为true。我有一些公理 我在约束中使用它 下面是SMT2.0中的一个示例 (define-sort Set (T) (Array T Bool)) (declare-fun |Set#Card| ((Set Int)) Int) (assert (forall ((s (Set Int))) (! (<= 0 (|Set#C

我试图在Z3中对集合进行建模,这样我就能够找到要创建的模型 涉及集合的约束

我当前使用数组表示一个集合。元素属于集合 如果数组中的对应项为true。我有一些公理 我在约束中使用它

下面是SMT2.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)
(定义排序集(T)(数组T Bool))
(声明乐趣|集合#卡片|((集合Int))Int)
(assert(forall((s(Set Int)))
(!

(问题在于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))
是此定义的修改示例的链接。Z3在使用该定义后返回
sat
和模型

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


另一种选择是对
未知的
结果使用“候选模型”。这不是理想的解决方案,但有几个用户这样做。

谢谢。我试过“候选模型”但它们在很多情况下都不精确。稍后我还需要支持集合相等、相交、不相交等。你知道一种适用于这些情况的方法吗?扩展数组理论(在我引用的论文中描述)可用于对集合相等、交集等进行编码。基数是无法编码的主要操作。Z3教程有一个示例()。请参阅:阵列上的映射函数我现在正尝试使用.NET API(
MkMap
)为此。布尔函数是预定义的还是我需要自己定义?我现在使用未解释的函数,并根据特定布尔函数的要求进行断言。