如何处理Z3中的递归函数?

时间:2016-04-05 15:42:10

标签: z3 smt

(set-option :smt.mbqi true)
(declare-fun R(Int) Int)
(declare-const a Int)
(assert (= (R 0) 0))
(assert (forall ((n Int)) (=> (> n 0) (= (R n ) (+ (R (- n 1)) 1)))))
(assert (not (= a 5)))
(assert (not (= (R a) 5)))
(check-sat)

我在Z3上尝试了上面的代码,但是Z3无法回答。你能指导我在哪里弄错了吗?

1 个答案:

答案 0 :(得分:2)

作为一般模式,不要指望MBQI能够生产模型 涉及的功能 只有无限范围的不同值。 如果你真的必须,那么你可以使用define-fun-rec结构来定义 递归函数。 Z3目前信任该定义 格式良好(例如,对应于函数的等式) 定义是可以满足的。)

(set-option :smt.mbqi true)
(declare-fun F (Int) Int)
(define-fun-rec R ((n Int)) Int
   (if (= n 0) 0
       (if (> n 0) (+ (R (- n 1)) 1)
            (F n))))

(declare-const a Int)
(assert (not (= a 5)))
(assert (not (= (R a) 5)))
(check-sat)
(get-model)

Z3在搜索期间被动地使用递归定义的函数:无论何时 它有一个候选模型用于约束的地面部分 检查函数图是否在候选模型的值上得到充分定义。如果不是,则在所选值上实例化函数定义,直到在相关值上明确定义 对地面的限制。