您在消息中描述的操作(contains S1 S2)
是子集关系。如果我们将整数集编码为从 Int 到 Boolean 的函数(例如 in: max value in set z3),那么S1
和S2
被声明为:
(declare-fun S1 (Int) Bool)
(declare-fun S2 (Int) Bool)
然后,我们可以说这S1
是S2
通过断言
(assert (forall ((x Int)) (=> (S1 x) (S2 x))))
我们只是说 in 中的任何元素S1
也是 的元素S2
。
编辑
我们可以使用表达式(exists ((x Int)) (and (S1 x) (S2 x)))
来检查集合是否S1
有S2
共同的元素
结束编辑
集合的最小元素可以像我们在集合 z3 中的最大值中那样进行编码。例如,假设 的最小元素S1
是min_S1
。
; Now, let min_S1 be the min value in S1
(declare-const min_S1 Int)
; Then, we now that min_S1 is an element of S1, that is
(assert (S1 min_S1))
; All elements in S1 are bigger than or equal to min_S1
(assert (forall ((x Int)) (=> (S1 x) (not (<= x (- min_S1 1))))))
如果您正在编码的集合的最小值在“编码时”是已知的(并且很小)。我们可以使用另一种基于位向量的编码。在这种编码中,一个集合是一个位向量。如果集合只包含 0 到 5 之间的值,那么我们可以使用大小为 6 的位向量。想法是:如果位i
为真,当且仅当i
是集合的一个元素。
以下是主要操作的示例:
(declare-const S1 (_ BitVec 6))
(declare-const S2 (_ BitVec 6))
(declare-const S3 (_ BitVec 6))
; set equality is just bit-vector equality
(assert (= S1 S2))
; set intersection, union, and complement are encoded using bit-wise operations
; S3 is S1 union S2
(assert (= S3 (bvor S1 S2)))
; S3 is S1 intersection of S2
(assert (= S3 (bvand S1 S2)))
; S3 is the complement of S1
(assert (= S3 (bvnot S1)))
; S1 is a subset of S2 if S1 = (S1 intersection S2), that is
(assert (= S1 (bvand S1 S2)))
; S1 is the empty set if it is the 0 bit-vector
(assert (= S1 #b000000))
; To build a set that contains only i we can use the left shift
; Here, we assume that i is also a bit-vector
(declare-const i (_ BitVec 6))
; S1 is the set that contains only i
; We are also assuming that i is a value in [0, 5]
(assert (= S1 (bvshl #b000001 i)))