指导 z3 的证明搜索
Guiding z3's proof search
我正在尝试让 z3 工作(大部分时间)来解决非常简单的非线性整数算术问题。不幸的是,我在求幂方面遇到了一些困难。我希望能够处理像 x^{a+b+2} = (x * x * x^{a} * x{b}) 这样的问题。我只需要处理非负指数。
我尝试将求幂重新定义为递归函数(这样它就可以 return 1 用于任何非正指数)并使用一种模式来促进 z3 推断 x^{a+b} = x^{a} * x^{b},但它似乎不起作用 - 我还在超时。
(define-fun-rec pow ((x!1 Int) (x!2 Int)) Int
(if (<= x!2 0) 1 (* x!1 (pow x!1 (- x!2 1)))))
; split +
(assert (forall ((a Int) (b Int) (c Int))
(! (=>
(and (>= b 0) (>= c 0))
(= (pow a (+ b c)) (* (pow a c) (pow a b))))
:pattern ((pow a (+ b c))))))
; small cases
(assert (forall ((a Int)) (= 1 (pow a 0))))
(assert (forall ((a Int)) (= a (pow a 1))))
(assert (forall ((a Int)) (= (* a a) (pow a 2))))
(assert (forall ((a Int)) (= (* a a a) (pow a 3))))
; Our problem
(declare-const x Int)
(declare-const i Int)
(assert (>= i 0))
; This should be provably unsat, by splitting and the small case for 2
(assert (not (= (* (* x x) (pow x i)) (pow x (+ i 2)))))
(check-sat) ;times out
我是否错误地使用了模式,有没有办法为证明搜索提供更强的提示,或者有更简单的方法来实现我想要的?
模式(也称为触发器)只能包含未解释的函数。由于 +
是一个解释函数,您实际上提供了一个无效模式,在这种情况下几乎任何事情都可能发生。
作为第一步,我禁用了 Z3 的自动配置功能以及基于 MBQI 的量词实例化:
(set-option :auto_config false)
(set-option :smt.mbqi false)
接下来,我引入了一个未解释的plus
功能,并将+
的每个应用程序替换为plus
。这足以使您的断言得到验证(即 yield unsat
)。您当然也可以根据 +
公理化 plus
,即
(declare-fun plus (Int Int) Int)
(assert (forall ((a Int) (b Int))
(! (= (plus a b) (+ a b))
:pattern ((plus a b)))))
但是您的断言已经在没有 plus
.
的定义公理的情况下得到验证
我正在尝试让 z3 工作(大部分时间)来解决非常简单的非线性整数算术问题。不幸的是,我在求幂方面遇到了一些困难。我希望能够处理像 x^{a+b+2} = (x * x * x^{a} * x{b}) 这样的问题。我只需要处理非负指数。
我尝试将求幂重新定义为递归函数(这样它就可以 return 1 用于任何非正指数)并使用一种模式来促进 z3 推断 x^{a+b} = x^{a} * x^{b},但它似乎不起作用 - 我还在超时。
(define-fun-rec pow ((x!1 Int) (x!2 Int)) Int
(if (<= x!2 0) 1 (* x!1 (pow x!1 (- x!2 1)))))
; split +
(assert (forall ((a Int) (b Int) (c Int))
(! (=>
(and (>= b 0) (>= c 0))
(= (pow a (+ b c)) (* (pow a c) (pow a b))))
:pattern ((pow a (+ b c))))))
; small cases
(assert (forall ((a Int)) (= 1 (pow a 0))))
(assert (forall ((a Int)) (= a (pow a 1))))
(assert (forall ((a Int)) (= (* a a) (pow a 2))))
(assert (forall ((a Int)) (= (* a a a) (pow a 3))))
; Our problem
(declare-const x Int)
(declare-const i Int)
(assert (>= i 0))
; This should be provably unsat, by splitting and the small case for 2
(assert (not (= (* (* x x) (pow x i)) (pow x (+ i 2)))))
(check-sat) ;times out
我是否错误地使用了模式,有没有办法为证明搜索提供更强的提示,或者有更简单的方法来实现我想要的?
模式(也称为触发器)只能包含未解释的函数。由于 +
是一个解释函数,您实际上提供了一个无效模式,在这种情况下几乎任何事情都可能发生。
作为第一步,我禁用了 Z3 的自动配置功能以及基于 MBQI 的量词实例化:
(set-option :auto_config false)
(set-option :smt.mbqi false)
接下来,我引入了一个未解释的plus
功能,并将+
的每个应用程序替换为plus
。这足以使您的断言得到验证(即 yield unsat
)。您当然也可以根据 +
公理化 plus
,即
(declare-fun plus (Int Int) Int)
(assert (forall ((a Int) (b Int))
(! (= (plus a b) (+ a b))
:pattern ((plus a b)))))
但是您的断言已经在没有 plus
.