在Z3中,或在传递到Z3之前,是否可能检测到不一致的方程式?
我在使用z3时使用了以下示例在Z3中,或在传递到Z3之前,是否可能检测到不一致的方程式?,z3,solver,smt,divide-by-zero,Z3,Solver,Smt,Divide By Zero,我在使用z3时使用了以下示例 f=Function('f',IntSort(),IntSort()) n=Int('n') c=Int('c') s=Solver() s.add(c>=0) s.add(f(0)==0) s.add(ForAll([n],Implies(n>=0, f(n+1)==f(n)+10/(n-c)))) 最后一个等式不一致(因为n=c将使其不确定)。但是,Z3无法检测到这种不一致性。有没有什么方法可以让Z3检测到它,或者任何其他工具可以检测到它?据我所知
f=Function('f',IntSort(),IntSort())
n=Int('n')
c=Int('c')
s=Solver()
s.add(c>=0)
s.add(f(0)==0)
s.add(ForAll([n],Implies(n>=0, f(n+1)==f(n)+10/(n-c))))
最后一个等式不一致(因为n=c
将使其不确定)。但是,Z3无法检测到这种不一致性。有没有什么方法可以让Z3检测到它,或者任何其他工具可以检测到它?据我所知,您关于最后一个等式不一致的断言与SMT-LIB标准的文档不匹配。页面上写着:
因为在SMT-LIB逻辑中,所有功能符号都被解释
作为总函数,(/t0)
形式的术语在
Reals的每一个实例。然而,该声明没有规定
对其价值的限制。这特别意味着
- 对于每一个例子,理论T和
- 对于每个值
(定义见:values属性)和 闭项v
为实数t
(=v(/t0))
类似地,该页面说:
请参阅Reals理论声明中关于表单术语的注释
(/t0)
同样的观察结果也适用于(div t 0)
和
(mod t 0)
因此,有理由相信SMT-LIB兼容工具不会为给定公式打印
unsat
。Z3不会检查是否被零除,因为正如Patrick Trentin所提到的,根据SMT-LIB被零除的语义是它返回未知值
您可以手动要求Z3检查零除法,以确保您永远不会依赖零除法。(例如,如果您正在建模一种语言,其中除零的语义与SMT-LIB不同,那么这一点很重要。)
对于您的示例,如下所示:
(declare-fun f (Int) Int)
(declare-const c Int)
(assert (>= c 0))
(assert (= (f 0) 0))
; check for division by zero
(push)
(declare-const n Int)
(assert (>= n 0))
(assert (= (- n c) 0))
(check-sat) ; reports sat, meaning division by zero is possible
(get-model) ; an example model where division by zero would occur
(pop)
;; Supposing the check had passed (returned unsat) instead, we could
;; continue, safely knowing that division by zero could not happen in
;; the following.
(assert (forall ((n Int))
(=> (>= n 0)
(= (f (+ n 1))
(+ (f n) (/ 10 (- n c)))))))
您是否在寻求一种方法,让工具报告可能的除法为零?或者你是想让它检测整个设置是否不正确?我想要一个工具,它可以报告FOL AXIOM中存在的按零划分的不一致性。我不知道有这样的事情。一种方法是首先要求解算器证明不存在被零除的情况。你愿意接受吗?是的,那将是非常有用的,为什么我没有想到添加这个部分是我无法理解的。很好的建议:)+1