【发布时间】:2016-09-09 03:58:39
【问题描述】:
我很困惑,很难理解 Z3 定点引擎的两种不同输入格式之间的关系。简短的例子:假设我想证明负数的存在。我声明了一个函数,它为非负数返回 1,为负数返回 0,然后如果有参数返回 0,则要求求解器失败。但有一个限制:我希望求解器在存在时响应 sat如果所有数字都是非负数,则至少有一个负数和unsat。
使用declare-rel 和query 格式很简单:
(declare-rel f (Int Int))
(declare-rel fail ())
(declare-var n Int)
(declare-var m Int)
(rule (=> (< n 0) (f n 0)))
(rule (=> (>= n 0) (f n 1)))
(rule (=> (and (f n m) (= m 0)) fail))
(query fail)
但是使用纯 SMT-LIB2 格式(使用forall)时会变得很棘手。例如,直截了当
(set-logic HORN)
(declare-fun f (Int Int) Bool)
(declare-fun fail () Bool)
(assert (forall ((n Int))
(=> (< n 0) (f n 0))))
(assert (forall ((n Int))
(=> (>= n 0) (f n 1))))
(assert (forall ((n Int) (m Int))
(=> (and (f n m) (= m 0)) fail)))
(assert (not fail))
(check-sat)
返回unsat。毫不奇怪,将(= m 0) 更改为(= m 1) 的结果相同。我们只能从(= m 2) 得到sat 暗示fail。问题是我无法理解,如何使用这种格式询问求解器。
我现在是如何理解它的,在使用forall-form 时,我们可以要求仅找到 ∀-解决方案,即答案 sat 意味着求解器设法找到满足所有断言的解释(或不变量)对于 all 值,unsat 表示没有此类功能。换句话说,它试图证明,将“证明”(不变量)放入模型中(显然,当sat 时)。
相反,当querydeclare-rel 格式的解法求解器在解法中搜索一些变量时,就像约束在∃-量词下一样。换句话说,它给出了反例。它只能在unsat的情况下打印不变量。
我有几个问题:
- 我理解正确吗?我觉得我错过了一些关键的想法。例如,关于如何用
(assert (forall ...))表达(query ...)的一般概念将非常有帮助(并且会自动回答问题 2)。 - 有没有办法用纯SMT-LIB2格式解决这种∃约束(找到反例时输出
sat)?如果是,那怎么办?
【问题讨论】: