Z3中具有解释函数的奇异行为E-匹配

Z3中具有解释函数的奇异行为E-匹配,z3,Z3,给出以下Z3序言(SMT2格式): unsat可以在几毫秒内从以下两个目标(单独)推断出来: (assert (not (= (+ z (* (exp x) (exp y))) (+ z (exp (+ x y)))))) (

给出以下Z3序言(SMT2格式):

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
包装,或者如果
+z
替换为
条形z
,该模式的行为会有什么不同


这是怎么回事?谢谢。

我不确定您的情况,但您可以尝试向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))))
(声明常量为实)
(断言(>EULER_E 2.718281828459045))
(断言(

添加上述任何一项都会使Z3回到您的示例中。

我不确定您的情况下发生了什么,但您可以尝试向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))))
(声明常量为实)
(断言(>EULER_E 2.718281828459045))
(断言(
添加上述任何一项都会使Z3回到您的示例中
unsat