利用z3中的位向量避免非线性

利用z3中的位向量避免非线性,z3,smt,nonlinear-functions,sat,Z3,Smt,Nonlinear Functions,Sat,我正在尝试求解包含数千个变量的公式。这些公式的主要部分是线性的,从我的观点来看,z3正在以难以置信的速度咀嚼它们。然而,很少有约束会引入一些非线性。然后,计算时间从几分钟增加到几天后无法得到解 我认为尝试使用位向量会很有趣,但仅仅是对于那些在过程中失去一些精度的非线性约束,但这不是我试图解决的问题。所以或多或少,我想通过在需要时切换到数字的位表示来使用小型SAT问题。我在另一个例子中看到,int2bv和bv2int被视为未解释的函数,因此似乎无法使用这些函数。然而,我仍然不确定他们为什么不感到惊

我正在尝试求解包含数千个变量的公式。这些公式的主要部分是线性的,从我的观点来看,z3正在以难以置信的速度咀嚼它们。然而,很少有约束会引入一些非线性。然后,计算时间从几分钟增加到几天后无法得到解

我认为尝试使用位向量会很有趣,但仅仅是对于那些在过程中失去一些精度的非线性约束,但这不是我试图解决的问题。所以或多或少,我想通过在需要时切换到数字的位表示来使用小型SAT问题。我在另一个例子中看到,int2bv和bv2int被视为未解释的函数,因此似乎无法使用这些函数。然而,我仍然不确定他们为什么不感到惊讶。是否存在任何理论问题或是出于性能原因

我还看到z3的最后一个稳定版本可以处理浮点()。然而,从FP到Reals似乎引入了非线性。因此,仅对非线性约束使用浮点运算,并用实数和整数求解其余约束,似乎也是不可能的。我还没有尝试过,但我假设对所有变量使用浮点不能适应我遇到的问题。 我提出了非常幼稚的函数,相当于int2bv和bv2int。显然,即使对于非线性的小例子,它也是非常缓慢的。下面是SMT2中用于正整数的8位向量的实现

(define-fun BitVecToInt ((x (_ BitVec 8))) Int
    (+
        (ite (= #b1 ((_ extract 0 0) x)) 1 0)
        (ite (= #b1 ((_ extract 1 1) x)) 2 0)
        (ite (= #b1 ((_ extract 2 2) x)) 4 0)
        (ite (= #b1 ((_ extract 3 3) x)) 8 0)
        (ite (= #b1 ((_ extract 4 4) x)) 16 0)
        (ite (= #b1 ((_ extract 5 5) x)) 32 0)
        (ite (= #b1 ((_ extract 6 6) x)) 64 0)
        (ite (= #b1 ((_ extract 7 7) x)) 128 0)
    )
)
(define-fun IntToBitVec ((x Int)) (_ BitVec 8)
    (bvor
        #b00000000
        (ite (> (rem x 2) 0) #b00000001 #b00000000)
        (ite (>= (rem x 4) 2) #b00000010 #b00000000)
        (ite (>= (rem x 8) 4) #b00000100 #b00000000)
        (ite (>= (rem x 16) 8) #b00001000 #b00000000)
        (ite (>= (rem x 32) 16) #b00010000 #b00000000)
        (ite (>= (rem x 64) 32) #b00100000 #b00000000)
        (ite (>= (rem x 128) 64) #b01000000 #b00000000)
        (ite (>= x 128) #b10000000 #b00000000)
    )
)

有没有关于解决这个问题的最佳方法的想法,或者z3中有没有我错过的、可以让我的生活更轻松的东西?

您的
BitVecToInt
函数隐式假设所表示的数字是一个无符号的量。当然,这可能很好;虽然如果您使用
(\ubitvec 8)
类型作为2的补码,那么您必须明确考虑这一点。因此,也许您需要
UBitVec8ToInt
SBitVec8ToInt
变体;要弄清楚这一点

我认为,
int2bv
bv2int
之所以没有得到解释,正是因为性能的影响:想象一下将一个整数转换为一个数千位长的非常大的位向量。公式将非常大,并且会带来性能损失。对于较小的目标尺寸,我认为问题相当容易处理;就像这里的8位

我在Z3中使用float的(有限的)经验是,如果您不进行与real的转换,那么支持是相当好的。你一到那里,问题就变得棘手了。这里有一些来自Z3开发者关于这个问题的评论: