【问题标题】:BitVector in Z3 - functions for different bitsZ3 中的 BitVector - 不同位的函数
【发布时间】:2013-07-08 10:51:39
【问题描述】:

我有这段代码来检查其他元素是否包含在集合中。

;; All is encoding the set that contains {0, 1, 2, 3, 4, 5}
(define-const All (_ BitVec 6) #b111111)
;; Empty is encoding the empty set
(define-const Empty (_ BitVec 6) #b000000)

(define-fun LT_l ((S (_ BitVec 6)) (l (_ BitVec 6))) Bool
    ;; True if for all x in S x < l
    (= (bvand (bvshl All l) S) Empty))

(define-fun GT_l ((l (_ BitVec 6)) (S (_ BitVec 6))) Bool
    ;; True if for all x in S l < x
    (= (bvand (bvnot (bvshl All l)) S) Empty))

(define-fun is_in ((e (_ BitVec 6)) (S (_ BitVec 6))) Bool
   ;; True if e is an element of the "set" S.
   (not (= (bvand (bvshl (_ bv1 6) e) S) Empty)))

(define-fun is_minimal ((e (_ BitVec 6)) (S (_ BitVec 6))) Bool
    (and (is_in e S)
         (= (bvand (bvsub (bvshl (_ bv1 6) e) (_ bv1 6)) S) Empty)))

(define-fun LT ((L0 (_ BitVec 6)) (L1 (_ BitVec 6))) Bool
    ; True if forall x in L0 and forall y in L1, x < y
    (or (= L0 Empty)
        (= L1 Empty)
        (exists ((min (_ BitVec 6))) (and (is_minimal min L1) (LT_l L0 min)))))


(declare-const consoleLock (_ BitVec 6))
(declare-const l1 (_ BitVec 6))
(declare-const l2 (_ BitVec 6)) 

( assert (distinct consoleLock l1 l2 ) )

( assert (or (= l1 (_ bv0 6)) (= l1 (_ bv1 6)) (= l1 (_ bv2 6)) (= l1 (_ bv4 6)) ))
( assert (or (= l2 (_ bv0 6)) (= l2 (_ bv1 6)) (= l2 (_ bv2 6)) (= l2 (_ bv4 6)) ))
( assert (or (= consoleLock (_ bv0 6)) (= consoleLock (_ bv1 6)) (= consoleLock (_ bv2 6)) (= consoleLock (_ bv4 6)) ))


(declare-const L4 (_ BitVec 6))
(declare-const L1 (_ BitVec 6))
(declare-const L0 (_ BitVec 6))
(declare-const L5 (_ BitVec 6))


(assert (LT_l L0 l1))
(assert (LT L0 L1))
(assert (GT_l L1 l1))

(assert (LT_l L4 l2))
(assert (LT L4 L5))
(assert (GT_l L5 l2))

(declare-const T1 (_ BitVec 6))
(assert (= T1 l1))
(assert (LT_l T1 l2))

(declare-const T2 (_ BitVec 6))
(assert (= T2 l2))
(assert (LT_l T2 l1))

(check-sat)
(get-model)

我的问题是您想将此代码也用于具有 8 位和 16 位的向量,但它不起作用。

例如,如果我将所有 (_BitVec 6) 替换为 (_BitVec 8),上面的代码就不能正常工作,因为结果应该是 unsat 但它是 sat。

好像 6 位向量效果很好。

如何使它适用于不同大小的位向量?

【问题讨论】:

    标签: z3 smt


    【解决方案1】:

    我们还要调整例子中出现的常数:#b111111#b000000(_ bv1 6)等。话虽如此,SMT-LIB 2.0格式对于写参数问题不是很方便。我认为编程 API 更容易用于编码参数问题。 这是使用 Z3 Python API 编码的相同示例。也可在线获取here。我们可以通过将SZ = 6 替换为SZ = 8SZ = 16 来更改位向量的大小。

    def All(sz):
        return BitVecVal(2**sz - 1, sz)
    
    def Empty(sz):
        return BitVecVal(0, sz)
    
    def LT_l(S, l):
        sz = S.size()
        return (All(sz) << l) & S == Empty(sz)
    
    def GT_l(l, S):
        sz = S.size()
        return (~(All(sz) << l)) & S == Empty(sz)    
    
    def is_in(e, S):
        sz = S.size()
        one = BitVecVal(1, sz)
        return (1 << e) & S != Empty(sz)
    
    def is_minimal(e, S):
        sz = S.size()
        return And(is_in(e, S), ((1 << e) - 1) & S == Empty(sz))
    
    def LT(L0, L1):
        sz = L0.size()
        min = BitVec('min', sz)
        return Or(L0 == Empty(sz), L1 == Empty(sz), Exists([min], And(is_minimal(min, L1), LT_l(L0, min))))
    
    SZ=6
    consoleLock = BitVec('consoleLock', SZ)
    l1 = BitVec('l1', SZ)
    l2 = BitVec('l2', SZ)    
    
    s = Solver()
    s.add(Distinct(consoleLock, l1, l2))
    s.add(Or(l1 == 0, l1 == 1, l1 == 2, l1 == 4))
    s.add(Or(l2 == 0, l2 == 1, l2 == 2, l2 == 4))
    s.add(Or(consoleLock == 0, consoleLock == 1, consoleLock == 2, consoleLock == 4))
    
    L4 = BitVec('L4', SZ)
    L1 = BitVec('L1', SZ)
    L0 = BitVec('L0', SZ)
    L5 = BitVec('L5', SZ)
    
    s.add(LT_l(L0, l1))
    s.add(LT(L0, L1))
    s.add(GT_l(L1, l1))
    s.add(LT_l(L4, l2))
    s.add(LT(L4, L5))
    s.add(GT_l(L5, l2))
    
    T1 = BitVec('T1', SZ)
    s.add(T1 == l1)
    s.add(LT_l(T1, l2))
    
    T2 = BitVec('T2', SZ)
    s.add(T2 == l2)
    s.add(LT_l(T2, l1))
    
    print s.check()
    

    【讨论】:

    • 谢谢。 SMT-LIB 2.0 格式写参数问题不是很方便但是没有phyton 也可以,只有SMT-LIB 2.0 格式?如果可以,我该怎么办?
    • 我们不能在 SMT-LIB 2.0 中做到这一点。请注意,Z3 绑定了其他编程语言(例如 C、C++、Java、C# 等)。因此,您可以将 python 代码移植到这些编程语言中的任何一种。另一种选择是编写一个生成 SMT-LIB 2.0 文件的程序。给定输入 N,程序将为大小为 N 的位向量生成一个 SMT 文件。
    • 好吧,我试图做第二个选项,但我上面发布的 Z3 代码不适用于所有尺寸,即使只是将 (_ BitVec 6) 更改为 (_ BitVec 8),#b111111由#b11111111 和#b000000 由#b00000000 提供。即使这样也不可能?
    • 它应该可以工作。出了什么问题?您能否提供一个为大小为 8 的位向量生成的文件的链接?
    • 例如对于 16-bit 是不行的。也可在线获取here。因为结果应该是不满意的。
    猜你喜欢
    • 1970-01-01
    • 2020-04-29
    • 1970-01-01
    • 1970-01-01
    • 2012-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-23
    相关资源
    最近更新 更多