繁体   English   中英

Z3 Java API - 获得 unsat 核心

[英]Z3 Java API - get unsat core

我试图弄清楚如何使用 Z3 的 Java API 获得 unsat 核心。 我们的场景如下(代码在下面,在rise4fun中有效):

  1. 我们以编程方式创建 SMT2 输入
  2. 输入包含函数定义、数据类型声明和断言
  3. 我们使用 parseSMTLIB2String API 解析它
  4. 我们确保上下文和求解器具有 unsat_core -> true
  5. Z3 为提供的输入返回 UNSAT,这是正确的
  6. 但是,UNSAT 核心始终是空的。
  7. 相同的输入在rise4fun (x1 x3) 上正确生成 UNSAT 核心

我猜我以某种方式滥用了 API ......但不太确定如何/为什么。

我注意到我无法在传递给 parseSMTLIB2String 的 SMT 字符串中设置 unsat 核心选项,因为这是不允许的。 我猜这是预期的。

有人可以指出我正确的方向吗?

谢谢!!

(set-option :smt.macro-finder true)

;; The following is only for rise4fun, i cannot get it 
;; to work with the parse SMT Java API
(set-option :produce-unsat-cores true)

(define-sort Ref () Int)

(declare-datatypes (T1 T2) ((Tuple2 (mk-Tuple2 (_1 T1)(_2 T2)))))
(declare-datatypes (T1 T2 T3) ((Tuple3 (mk-Tuple3 (_1 T1)(_2 T2)(_3 T3)))))

(define-sort Set (T) (Array T Bool))
(define-sort Bag (T) (Array T Int))

(declare-const emptySetOf_Int (Set Int))
(assert (!(forall ((x Int)) (= (select emptySetOf_Int x) false)) :named AXIOM1))

(declare-sort TopLevelDeclarations) (declare-const mk-TopLevelDeclarations TopLevelDeclarations)
(declare-datatypes () ((A (mk-A (x Int)(y Int)))))

(declare-datatypes () ((Any
  (lift-TopLevelDeclarations (sel-TopLevelDeclarations TopLevelDeclarations))
  (lift-A (sel-A A))
  null))
)

(declare-const heap (Array Ref Any))

(define-fun deref ((ref Ref)) Any
  (select heap ref)
)

(define-fun deref-is-TopLevelDeclarations ((this Ref)) Bool
  (is-lift-TopLevelDeclarations (deref this))
)

(define-fun deref-TopLevelDeclarations ((this Ref)) TopLevelDeclarations
  (sel-TopLevelDeclarations (deref this))
)

(define-fun deref-is-A ((this Ref)) Bool
  (is-lift-A (deref this))
)

(define-fun deref-A ((this Ref)) A
  (sel-A (deref this))
)

(define-fun deref-isa-TopLevelDeclarations ((this Ref)) Bool
  (deref-is-TopLevelDeclarations this)
)

(define-fun deref-isa-A ((this Ref)) Bool
  (deref-is-A this)
)

(define-fun A!x ((this Ref)) Int
  (x (deref-A this))
)

(define-fun A!y ((this Ref)) Int
  (y (deref-A this))
)

(define-fun TopLevelDeclarations.inv ((this Ref)) Bool
  true
)

(assert (! (forall ((this Ref))
  (=> (deref-is-TopLevelDeclarations this) (TopLevelDeclarations.inv this))
) :named x0))

(define-fun A.inv ((this Ref)) Bool
  (and
    (> (A!x this)  0)
    (> (A!y this)  0)
    (< (A!x this)  0)
  )
)

(assert (! (forall ((this Ref))
  (=> (deref-is-A this) (A.inv this))
) :named x1))

(assert (!(deref-is-TopLevelDeclarations 0) :named TOP))
(assert (!(exists ((instanceOfA Ref)) (deref-is-A instanceOfA)) :named x3))

(check-sat)
(get-unsat-core)

除了对parseSMTLIB2String的调用之外,您没有使用 Java API。 此函数不执行任何 SMT 命令,并且没有任何函数可以为您执行此操作。 parseSMTLIB2String专门用于解析断言,它将忽略其他所有内容。 对于这个特定问题,我建议简单地将问题文件作为命令行参数或通过 stdin(使用-in选项)传递给z3.exe 这产生

unsat
(x1 x3)

如果打算稍后将 Java API 用于其他用途,请参阅Java API unsat core 示例

我刚刚遇到了同样的问题,发现这取决于您如何将解析的输入传递给求解器。

虽然以下方法会产生一个空的 unsat-core...:

BoolExpr[] program = context.parseSMTLIB2File(input_file, null, null, null, null);
solver.add(program);
solver.check();
solver.getUnsatCore();

...如果您将解析的输入文件提供给求解器,则会正确生成 unsat-core,如下所示:

BoolExpr[] program = context.parseSMTLIB2File(input_file, null, null, null, null);
solver.check(program);
solver.getUnsatCore();

因此,我假设通过solver.add()传递的所有内容都属于假设,因此根据 Z3 可能不属于 unsat-core。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM