Z3 澄清SMT类型;变量截断中的错误?;允许Bool*Int
我有以下问题:Z3 澄清SMT类型;变量截断中的错误?;允许Bool*Int,z3,smt,z3py,Z3,Smt,Z3py,我有以下问题: A.如果我有一个变量x,我声明它(案例1)为Bool(案例2)为Int,断言x=0或x=1(案例3)为Int,断言0,我不能具体回答z3,但我想陈述我对A)点的看法 通常,约束x=0 v x=1被抽象为t1 v t2,其中t1是x=0,t2是x=1,在SAT发动机级别 因此,SAT引擎可能会在为输入公式构造可满足的真值分配期间尝试将t1和t2分配给true。需要注意的是,这是LAR理论中的一个矛盾,但是SAT引擎无法进行这种推理。因此,SAT引擎在做出此决定后可能会继续搜索一段时
A.如果我有一个变量x,我声明它(案例1)为Bool(案例2)为Int,断言x=0或x=1(案例3)为Int,断言0,我不能具体回答z3,但我想陈述我对A)点的看法 通常,约束
x=0 v x=1
被抽象为t1 v t2
,其中t1
是x=0
,t2
是x=1
,在SAT
发动机级别
因此,SAT
引擎可能会在为输入公式构造可满足的真值分配期间尝试将t1
和t2
分配给true
。需要注意的是,这是LAR
理论中的一个矛盾,但是SAT
引擎无法进行这种推理。因此,SAT
引擎在做出此决定后可能会继续搜索一段时间
当LAR
解算器最终被调用时,它将检测给定(可能部分)真值分配的LAR不可满足性。因此,它(应该)将子句not t1或not t2
作为学习子句交给SAT
引擎,以阻止再次生成的值的错误分配
如果存在许多此类错误赋值,则可能需要多次调用LAR
解算器,以便生成纠正SAT
真值赋值所需的所有阻塞子句,可能每个错误组合最多一个阻塞子句
在收到冲突子句后,SAT
引擎将不得不返回到它进行错误分配的位置,并做出正确的决定。显然,SAT
引擎所做的工作并不是都白费了,因为它导致了错误的值赋值:在此期间学习到的任何有用的子句都肯定会被重新使用。但是,这仍然会对某些公式造成明显的性能影响
将所有这些被浪费的来回计算与简单地将x
声明为Bool进行比较:现在SAT
引擎知道它只能为其分配两个值中的一个,并且永远不会同时分配x
和而不是x
在这种特定情况下,可以通过在输入公式中提供必要的阻塞子句来缓解此问题。但是,可以得出这样的结论:这始终是最佳实践:在某些情况下,显式列出所有已知的阻塞子句可能会导致公式大小的爆炸,并在实践中导致性能的更严重降级。最好的建议是在解决问题的任何特定编码之前,尝试不同的方法并进行实验评估
免责声明:一些
SMT
解算器可能比其他解算器更聪明,在解析公式时自动为0/1
变量生成适当的阻塞子句,或者通过其他方式完全避免这种情况(即afaik,基于模型的SMT解算器不应在同一问题中出现)关于
帕特里克对此做了很好的解释。实际上,你真的必须试着看看会发生什么。不同的问题可能会表现出不同的行为,这取决于启发式何时/如何开始。我认为这里没有一般的经验法则。我个人的偏好是将布尔值保持为布尔值,并根据需要进行转换,但这主要是从编程/维护的角度出发,而不是从效率的角度出发
关于B
您的“部门”被截断的问题很可能与此相同:
您可以显式地编写1.0/2.0
等。;或使用:
from __future__ import division
在你程序的顶端
关于C
SMTLib是一种强类型语言;你不能乘布尔。你必须先把它转换成一个数字。类似于(*(iteb10)x)
,其中b
是您的布尔值。或者您可以编写一个自定义函数来为您执行此操作,并调用它;比如:
(define-fun mul_bool_int ((b Bool) (i Int)) Int (ite b i 0))
(assert (= 0 (mul_bool_int false 5)))
(assert (= 5 (mul_bool_int true 5)))
最好一次只问一个问题,而不是把问题都堆在一起。请考虑把问题分成多个问题。我现在才看到!
from __future__ import division
(define-fun mul_bool_int ((b Bool) (i Int)) Int (ite b i 0))
(assert (= 0 (mul_bool_int false 5)))
(assert (= 5 (mul_bool_int true 5)))