使用Z3 QFNRA策略与数据类型:交互或内联

时间:2014-11-19 05:07:14

标签: z3 smt nonlinear-functions

Non-linear arithmetic and uninterpreted functions中,莱昂纳多·德莫拉表示,qfnra-nlsat策略尚未与Z3的其余部分完全整合。我认为情况在两年内发生了变化,但显然整合还不是很完整。

在下面的示例中,我使用的数据类型纯粹用于"软件工程"用途:将我的数据整理成记录。即使没有未解释的功能,Z3仍然无法给我一个解决方案:

(declare-datatypes () (
    (Point (point (point-x Real) (point-y Real)))
    (Line (line (line-a Real) (line-b Real) (line-c Real)))))

(define-fun point-line-subst ((p Point) (l Line)) Real
    (+ (* (line-a l) (point-x p)) (* (line-b l) (point-y p)) (line-c l)))

(declare-const p Point)
(declare-const l Line)

(assert (> (point-y p) 20.0))
(assert (= 0.0 (point-line-subst p l)))

(check-sat-using qfnra-nlsat)
(get-model)

> unknown
(model 
)

但是,如果我手动内联所有功能,Z3会立即找到一个模型:

(declare-const x Real)
(declare-const y Real)
(declare-const a Real)
(declare-const b Real)
(declare-const c Real)

(assert (> y 20.0))
(assert (= 0.0 (+ (* a x) (* b y) c)))

(check-sat-using qfnra-nlsat)
(get-model)

> sat
(model 
  (define-fun y () Real
    21.0)
  (define-fun a () Real
    0.0)
  (define-fun x () Real
    0.0)
  (define-fun b () Real
    0.0)
  (define-fun c () Real
    0.0)
)

我的问题是,有没有办法自动执行这样的内联?我对这些工作流程中的任何一个都很好:

  1. 启动Z3的策略是"先内联,然后应用qfnra-nlsat。我还没有找到办法,但也许我看起来不够好。
  2. 使用某个版本的simplify启动Z3进行内联。在第一次调用的结果(内联版本)上第二次启动Z3。
  3. 换句话说,如何使qfnra-nlsat与元组一起工作?

    谢谢!

1 个答案:

答案 0 :(得分:3)

没错,NLSAT解算器仍未与其他理论相结合。目前,如果我们在运行之前消除所有数据类型(或其他理论的元素),我们只能使用它。我相信目前Z3内部没有任何有用的战术,所以这必须事先做好。一般来说,编写策略并不难,例如:

(check-sat-using (and-then simplify qfnra-nlsat))

但是,简化程序不够强大,无法消除此问题中的数据类型常量。 (相应的实施文件为datatype_rewriter.cppdatatype_simplifier_plugin.cpp。)