用Z3证明归纳事实

用Z3证明归纳事实,z3,smt,Z3,Smt,我试图在Z3中证明一个归纳的事实,Z3是微软的SMT解决方案。我知道Z3一般不提供这种功能,如(第8节:数据类型)中所解释的,但当我们约束我们想要证明事实的域时,这似乎是可能的。考虑下面的例子: (declare-fun p (Int) Bool) (assert (p 0)) (assert (forall ((x Int)) (=> (and (> x 0) (<= x 20)) (= (p (- x 1)) (p x) )))) (asser

我试图在Z3中证明一个归纳的事实,Z3是微软的SMT解决方案。我知道Z3一般不提供这种功能,如(第8节:数据类型)中所解释的,但当我们约束我们想要证明事实的域时,这似乎是可能的。考虑下面的例子:

(declare-fun p (Int) Bool)
(assert (p 0))

(assert (forall ((x Int)) 
    (=> 
    (and (> x 0) (<= x 20))
    (= (p (- x 1)) (p x) ))))
(assert (not (p 20)))

(check-sat)

这似乎效果更好,但现在上限是40。这是否意味着我最好不要使用Z3来证明这些事实,或者我的问题表述不正确?

Z3使用许多启发式方法来控制量词实例化。其中一个是基于“实例化深度”。Z3用“depth”属性标记每个表达式。所有用户提供的断言都标记为深度0。实例化量词时,新表达式的深度会受到影响。Z3不会使用标记深度大于预定义阈值的表达式实例化量词。在您的问题中,已达到阈值:
(p40)
是深度0,
(p39)
是深度1,
(p38)
是深度2,等等

要增加阈值,应使用以下选项:

(set-option :qi-eager-threshold 100)
以下是具有此选项的示例:

当然,使用此设置,Z3将超时,例如,对于
(p 110)

未来,Z3将更好地支持“有界量化”。在大多数情况下,处理此类量词的最佳方法是扩展它。 通过编程API,我们可以在将表达式发送到Z3之前轻松地“实例化”表达式。 下面是Python()中的一个示例:


最后,在Z3中,包含算术符号的模式不是非常有效。问题是Z3在求解之前对公式进行了预处理。然后,大多数包含算术符号的模式将永远不会匹配。有关如何有效使用模式/触发器的更多信息,请参阅。作者还提供了一个。

谢谢,非常有用!是否有一些资源可以提供更多关于所有可设置选项的信息?我知道,但这相当简洁,我希望可能会有更详细的解释。不幸的是,我们没有详细描述选项的文档/页面。我正在尝试将Z3移动到一个新的参数设置框架,其中每个组件都有自己的参数和文档。待办事项列表中的另一项是从评论中引用的列表中删除过时的选项。指向文章和幻灯片组的链接已断开
(set-option :qi-eager-threshold 100)
p = Function('p', IntSort(), BoolSort())

s = Solver()

s.add(p(0))
s.add([ p(x+1) == p(x) for x in range(40)])
s.add(Not(p(40)))

print s.check()