∃-queries 和 ∀-queries with Z3 fixedpoint engine

∃-queries and ∀-queries with Z3 fixedpoint engine

我很困惑并且很难理解 Z3 定点引擎的两种不同输入格式是如何相关的。简短示例:假设我想证明负数的存在。我声明一个函数,returns 1 表示非负数,0 表示负数,然后如果有函数 returns 0 的参数,则要求求解器失败。但是有一个限制:我希望求解器如果存在至少一个负数,则响应 sat,如果所有数字均为非负数,则响应 unsat

使用 declare-relquery 格式很简单:

(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)

returnsunsat。毫不奇怪,将 (= m 0) 更改为 (= m 1) 结果相同。我们可以从 (= m 2) 得到 sat 仅暗示 fail。问题是我无法理解,如何使用这种格式询问求解器

我目前的理解方式是,在使用 forall-形式时,我们可以要求仅找到∀-解,即答案 sat 意味着解算器设法找到了解释(或不变的)满足 all 值的所有断言,而 unsat 意味着没有这样的函数。换句话说,它试图证明,将'proof'(不变量)放入模型中(显然,当sat)。

相反,当 query 求解 declare-rel 格式的解时,求解器搜索 一些 变量的解,就像约束条件下一样∃-量词。换句话说,它给出了反例。它只能在 unsat.

的情况下打印不变量

我有几个问题:

  1. 我的理解正确吗?我觉得我错过了一些关键的想法。例如,关于如何用 (assert (forall ...)) 表达 (query ...) 的一般想法将非常有帮助(并且会自动回答问题 2)。
  2. 有没有办法用纯SMT-LIB2格式解决这样的∃约束(找到反例时输出sat)?如果是那么怎么办?

首先,使用"declare-rel"、"declare-var"、"rule"和"query"的格式是SMT-LIB2的自定义扩展。 "declare-var" 特性便于从多个规则中省略绑定变量。它还允许使用分层否定来制定 Datalog 规则,而这正是您应该从分层否定中得到的语义。按照惯例,它使用 "sat" 表示查询有派生,而 "unsat" 表示查询不存在派生。

事实证明,标准的SMT-LIB2 几乎可以表达你想要的东西 没有否定的 Horn 从句。规则成为含义,查询成为以下形式的含义:(=> query false),或如您所写(不是查询)。 自定义格式的推导对应于空子句的证明(例如,证明 "query",然后证明 "false")。所以推导的存在意味着 SMT-LIB2 断言是 "unsat"。相反,如果 Horn 子句有一个解释(模型),那么这样的模型就证明没有推导。这些子句是 "sat"。

换句话说:

 "sat" for datalog extension   <=> "unsat" for SMT-LIB2 formulation
 "unsat" for datalog extension <=> "sat" for SMT-LIB2 formulation

在适用时使用纯 SMT-LIB2 格式的优点是 没有特殊的语法扩展。这些是普通的 SMT 公式和 其他想解决这个 class 公式的人不必写特殊的 扩展,他们只需要确保调整到的求解器 Horn 从句识别适当的 class 公式。 (Z3 的实现 HORN 片段的一部分确实允许在写下 Horn 子句时有一定的灵活性。 你可以在身体中有分离,你可以有 Curried 含义)。

使用 SMT-LIB2 格式有一个缺点,rule-based 格式有助于:当有查询的派生时,rule-based 格式有打印元素的编译指示一个元组。请注意,通常查询关系可以带参数。此功能对于有限域关系很有用。 您上面的示例使用整数,因此关系不是有限域,但 online-tutorial 中的示例包含有限域实例。 现在查询的推导也对应于解析证明。您可以从 SMT-LIB2 案例中提取分辨率证明,但我不得不说它是 令人费解,我还没有找到有效使用它的方法。 Horn 子句的 "duality" 引擎以比 Z3 的默认证明格式。无论哪种方式,如果用户 运行 尝试使用证明证书,他们很可能会遇到障碍,因为它们很少被使用。 rule-based 格式确实有另一个功能,它可以将一组谓词与对应于派生轨迹的实例组合在一起。更容易观察此输出。