奇怪的行为与Z3中的解释函数进行E匹配

时间:2016-03-14 21:56:33

标签: z3

给出以下Z3前导码(采用SMT2格式):

(set-option :smt.auto-config false)
(set-option :smt.mbqi false)

(declare-fun exp (Real) Real)
(declare-fun foo (Real) Real)
(declare-fun bar (Real Real) Real)

(assert (forall ((x Real) (y Real)) (= (* (exp x) (exp y)) (exp (+ x y)))))

(declare-const x Real)
(declare-const y Real)
(declare-const z Real)

unsat可以在几毫秒内从以下两个目标中推断出来:

(assert (not (= (+ z (* (exp x) (exp y))) (+ z (exp (+ x y))))))                                                                                                                                         
(assert (not (= (foo (bar z (* (exp x) (exp y)))) (foo (bar z (exp (+ x y)))))))

然而,Z3在给出目标时超时:

(assert (not (= (foo (+ z (* (exp x) (exp y)))) (foo (+ z (exp (+ x y)))))))

可以看作是在foo包裹第一个目标的两边,或者在第二个目标中用bar替换+

如果我们使用以下两种模式中的任何一种来引用引理,就可以证明这个目标:

(assert (forall ((x Real) (y Real)) (! (= (* (exp x) (exp y)) (exp (+ x y))) :pattern (* (exp x) (exp y)))))                              
(assert (forall ((x Real) (y Real)) (! (= (* (exp x) (exp y)) (exp (+ x y))) :pattern (exp (+ x y))))) 

因此,我假设默认情况下会生成多模式((exp x) (exp y)),但我不确定如果双方都包含在foo中,或者{{{}},这种模式的行为会有所不同1}}替换为+ z

这里发生了什么?感谢。

1 个答案:

答案 0 :(得分:0)

我不确定您的情况发生了什么,但您可能会尝试向Z3提供有关exp功能的其他信息。一种选择是:

(assert (exists ((EULER_E Real)) (forall ((x Real)) (= (exp x) (^ EULER_E x)))))

我非常确定这些内容写得正确,但我还没有在SMT-LIB中使用嵌套量词,所以请小心。另一个更明确的选择是:

(declare-const EULER_E Real)
(assert (> EULER_E 2.718281828459045))
(assert (< EULER_E 2.718281828459046))
(assert (forall ((x Real)) (= (exp x) (^ EULER_E x))))

添加上述任一项会使Z3返回unsat作为您的示例。