在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检测到它,或者任何其他工具可以检测到它?据我所知

我在使用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和
  • 对于每个值
    v
    (定义见:values属性)和 闭项
    t
    为实数
有一个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