【问题标题】:Z3 support for exponentialsZ3 对指数的支持
【发布时间】:2018-03-22 13:52:10
【问题描述】:

我是 Z3 的新手,我正在尝试了解它的工作原理,以及它能做什么和不能做什么。我知道 Z3 至少 一些 通过幂 (^) 运算符支持指数(请参阅 Z3py returns unknown for equation using pow() functionHow to represent logarithmic formula in z3pyUse Z3 and SMT-LIB to define sqrt function with a real number)。我不清楚的是这种支持有多广泛,以及 z3 可以对指数做出什么样的推论。

这是一个涉及指数的简单示例,z3 可以分析。我们定义一个指数函数,然后要求它验证 exp(0) == 1:

(define-fun exp ((x Real)) Real
  (^ 2.718281828459045 x))
(declare-fun x1 () Real)
(declare-fun y1 () Real)
(assert (= y1 (exp x1)))
(assert (not (=> (= x1 0.0) (= y1 1.0))))
(check-sat)
(exit)

Z3 按预期返回 unsat。另一方面,这是一个 Z3 无法分析的简单示例:

(define-fun exp ((x Real)) Real
  (^ 2.718281828459045 x))
(declare-fun x1 () Real)
(declare-fun y1 () Real)
(assert (= y1 (exp x1)))
(assert (not (< y1 0.0)))
(check-sat)
(exit)

这应该是可以满足的,因为从字面上看,x1 的任何值都会给出 y1 > 0。但是,Z3 返回未知。天真的我可能期望 Z3 能够分析这个,因为它可以分析第一个示例。

我意识到这个问题有点宽泛,但是:谁能给我任何关于 Z3 如何处理指数的见解,以及(更具体地说)为什么它可以解决我给出的第一个示例但不能解决第二个示例?

【问题讨论】:

  • 有时 (check-sat-using (or-else default qfnra-nlsat)) 使用非线性 sat 引擎提供更好的结果。 (尽管它不适用于您的第二个示例。)根据我的经验,一旦您有非线性项,就很难说什么时候有效,什么时候无效。

标签: z3 smt


【解决方案1】:

一般来说很难说,因为非线性求解具有挑战性,但你提出的案例实际上并不那么神秘。你写道:

(assert (= y (exp x)))
(assert (not (=> (= x 0) (= y 1))))

Z3 将简化第二个断言,产生:

(assert (= y (exp x)))
(assert (= x 0))
(assert (not (= y 1)))

然后它将传播第一个相等,产生:

(assert (= y (exp 0)))
(assert (not (= y 1)))

现在当exp 展开时,你有一个常量^常量的情况,Z3 可以处理(对于整数指数等)。

对于第二种情况,您要问的是一个关于变量指数的非常基本的问题,Z3 会立即出错。这并不太奇怪,因为关于变量指数的许多问题要么已知不可计算,要么未知但很难。

【讨论】:

  • 谢谢!这非常有帮助(回想起来很明显,真的)。只是添加到它以供将来参考:从那以后我一直在处理 Z3 中的指数,我发现它有时(但并非总是)以这种方式传播等式并确定它正在评估常量^常量.对于更复杂的表达式,我发现它对你给出的断言的确切表述相当敏感。一种公式将立即返回未知,而另一种稍有不同(但在逻辑上等效)的公式将立即返回 unsat。
  • 是的,它会非常敏感,因为您依靠简化器将方程按摩成可判定的形式。手动简化它通常是必要的,因为简化器不是很聪明。通常,您会很快得到“未知”,因为它通常是语法检查。我认为您很快就会“不满意”,这只是您发送的断言的一个事实。顺便说一句,如果我的回答是正确的,我会很感激你“接受”它。
猜你喜欢
  • 2012-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多