Z3 Java API - 获得不满核心

时间:2015-09-15 21:17:52

标签: z3 smt theorem-proving

我试图弄清楚如何使用Java API for Z3获得不饱和核心。我们的场景如下(代码在下面,在rise4fun中工作):

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

    我猜我错误地使用了API ...但不太确定如何/为什么。

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

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

    谢谢!

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

2 个答案:

答案 0 :(得分:1)

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

unsat
(x1 x3)

如果目的是稍后将Java API用于其他事项,请参阅Java API unsat core example

答案 1 :(得分:0)

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

虽然以下方法会产生一个空的 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。