Z3 中带有量词的函数

function with quantifier in Z3

我对量词有疑问。

设 a(0) = 0,a(n+1) 将是 a(n)+1 或 a(n)+2,具体取决于 x(n) 的值。我们可能期望对于任何类型的 x(.) 和所有 n,a(n) <= n*2.

这是 Z3 的代码:

(declare-fun a (Int) Int)
(declare-fun x (Int) Int)
(declare-fun N () Int)
(assert (forall 
    ((n Int))
    (=> (>= n 0)
        (= (a (+ n 1))
            (ite (> (x n) 0)
            (+ (a n) 1)
            (+ (a n) 2)
            )
        )
    )
))
(assert (= (a 0) 0))
(assert (> (a N) (+ N N)))

(check-sat)
(get-model)

我希望Z3可以return"unsat",而它总是"timeout"。 不知道Z3能不能处理这种量词,有没有大佬给点建议。

谢谢。

公式为SAT,对于N < 0,a的图形未指定。 但是默认量词实例化引擎无法确定这一点。您可以利用您正在定义递归函数来执行不同的引擎。

;(declare-fun a (Int) Int)
 (declare-fun x (Int) Int)
 (declare-fun y (Int) Int)
 (declare-fun N () Int)
 (define-fun-rec a ((n Int)) Int
   (if (> n 0) (if (> (x (- n 1)) 0) (+ (a (- n 1)) 1) (+ (a (- n 1)) 2)) (y n)))
(assert (= (a 0) 0))
(assert (> (a N) (+ N N)))

(check-sat)
(get-model)

正如 Malte 所写,不支持对此类公式进行归纳,因此不要指望 Z3 会产生归纳证明。它确实在 Horn 子句公式的 class 上找到归纳不变量,但它需要转换才能将任意公式转换为这种格式。

谢谢,Malte 和 Nikolaj。 变量 N 应该是有界的:

(assert (> N 0))
(assert (< N 10000))

我替换

(assert (> (a N) (+ N N)))

(assert (and
 (not (> (a N) (+ N N)))
 (> (a (+ N 1)) (+ (+ N 1) (+ N 1)))
))

并且它适用于 a(n) 的两个定义。 这是不是你说的那种归纳证明?

这是两个代码块,它们都是 return "unsat":

(declare-fun a (Int) Int)
(declare-fun x (Int) Int)
(declare-fun N () Int)
(assert (forall 
  ((n Int))
    (=> (>= n 0)
        (= (a (+ n 1))
        (ite (> (x n) 0)
        (+ (a n) 1)
        (+ (a n) 2)
        )
    ))
))
(assert (= (a 0) 0))

(assert (> N 0))
(assert (< N 10000))
;(assert (> (a N) (+ N N)))
(assert (and
  (not (> (a N) (+ N N)))
  (> (a (+ N 1)) (+ (+ N 1) (+ N 1)))
))
(check-sat)
;(get-model)

(declare-fun x (Int) Int)
(declare-fun y (Int) Int)
(declare-fun N () Int)

(define-fun-rec a ((n Int)) Int
  (if (> n 0) 
  (if (> (x (- n 1)) 0) (+ (a (- n 1)) 1) (+ (a (- n 1)) 2)) (y n)))
(assert (= (a 0) 0))

(assert (> N 0))
(assert (< N 10000))
;(assert (> (a N) (+ N N)))
(assert (and
  (not (> (a N) (+ N N)))
  (> (a (+ N 1)) (+ (+ N 1) (+ N 1)))
))
(check-sat)
;(get-model)