Z3:Z3 C API中的未知结果

Z3:Z3 C API中的未知结果,z3,Z3,在当前Z3上下文中,assert tryX,i,j=X[i][j]==i*j已经存在。X的类型是Array Int Array Int。tryX,i,j是一个函数,返回类型是bool。以下是Z3上下文: (kernel (forall ((Y (Array Int (Array Int Int))) (i Int) (j Int)) (let ((a!1 (= (+ (select (select Y i) j) (* (- 1) j i)) 0)))

在当前Z3上下文中,assert tryX,i,j=X[i][j]==i*j已经存在。X的类型是Array Int Array Int。tryX,i,j是一个函数,返回类型是bool。以下是Z3上下文:

 (kernel
      (forall ((Y (Array Int (Array Int Int))) (i Int) (j Int))
        (let ((a!1 (= (+ (select (select Y i) j) (* (- 1) j i)) 0)))
          (= (try Y i j) a!1))))
我要证明Z3 ast:

 forall i[0..99],j[0..199]. try(X,i,j) 
    =>
       (forall i[0..49],j[0..199]. try(X,i,j) 
    &&  forall i[50..99],j[0..199]. try(X,i,j))
forall i[0..99],j[0..199]. (X[i][j] == i*j)
=>
  (forall i[0..49],j[0..199]. (X[i][j] == i*j)
&& forall i[50..99],j[0..199]. (X[i][j] == i*j))
换句话说,我检查的不是这个断言的是sat。 Z3检查结果未知。 但当我证明Z3 ast时:

 forall i[0..99],j[0..199]. try(X,i,j) 
    =>
       (forall i[0..49],j[0..199]. try(X,i,j) 
    &&  forall i[50..99],j[0..199]. try(X,i,j))
forall i[0..99],j[0..199]. (X[i][j] == i*j)
=>
  (forall i[0..49],j[0..199]. (X[i][j] == i*j)
&& forall i[50..99],j[0..199]. (X[i][j] == i*j))

Z3证明结果是有效的,换句话说,不是这个断言不成立。

我不确定我是否理解这个问题,但一般来说,我们不能指望Z3用量词来解决所有公式。在这种特殊情况下,启用宏查找器可能会有所帮助,它可以像

(forall ... (= (try ...) def )))

它将所有出现的try替换为def。该选项的名称为smt.macro\u finder。

谢谢您的帮助。是的,你的理解是对的。我想用try的定义替换所有出现的try。启用宏查找器后,Z3会给我一个有效的答案。但是现在,还有一个问题,我想改变参数,例如,def:tryX,I,j=X[I][j]==ij,当我遇到X[j][k]==jk时,我想用Z3替换tryX,j,k。所以我使用了一个新的定义:forall X,I,j.tryX,I,j=X[I][j]==ij。但是当我证明:X[j][k]==jk=>tryX,j,k时,Z3返回未知。期待您的好评!这实际上取决于您使用的解决方案和/或策略。整数上的i*j不是线性的,所以许多线性算术的解算器很快就会放弃。也许nlsat的策略可以做到这一点?有关如何使用策略,请参见此处:如果您只是想用其他内容替换X[i][j],您可以尝试使用try等新函数定义数组,以便宏查找器也可以执行此任务。