Z3:使用Java API简化断言

时间:2014-02-07 08:25:36

标签: java z3 smt

我在Windows 7以及64位Java 7上使用Z3版本4.3.2的Java-API。

我正在尝试使用简化,以便在我的断言集中获得有关冗余信息的知识。

我的第一个尝试是简化布尔表达式并像这样评估结果

Expr e = ctx.mkImplies(ctx.mkBoolConst("A"),ctx.mkBoolConst("B")).simplify();

在我的例子中

(=> A B)            
(=> (not B) C)
(=> A B)
(=> B A)
(=> D E)
(=> B F)
(=> G D)
(=> H I)
(=> I (not D))
(=> (not D) I)
(=> C (not B))
C)

这导致简化的公式

(and 
    (or (not A) B)
    or B C)
    or (not B) A)
    (or (not D) E)
    (or (not B) F)
    (or (not G) D)
    (or (not H) I)
    (or (not I) (not D))
    (or D I)
    (or (not C) (not B))
    C
)

我之前将其包含在AND表达式中,以便将它们简化为一个表达式。

这个结果还不是我想要的。取出原始代码第3行中的重复规则(很好)。 但如果C为真(示例的最后一行),则B必须为假((=> C (not B)))。 如果B为假,则A必须为假((=> A B))。 等等...

我所执行的更像是以下内容(我手动执行此操作,因此转换可能会出错)

(and 
    (or (not A) B)       ; transformed to (not A)
    or B C)              ; transformed to C
    or (not B) A)        ; deleted
    (or (not D) E)       ; left unchanged
    (or (not B) F)       ; deleted
    (or (not G) D)       ; left unchanged
    (or (not H) I)       ; left unchanged
    (or (not I) (not D)) ; left unchanged
    (or D I)             ; left unchanged
    (or (not C) (not B)) ; transformed to (not B)
    C                    ; C
)

接下来,我尝试使用以下

之类的策略
Tactic simplifyTactic = ctx.mkTactic("ctx-solver-simplify");
Tactic smtTactic = ctx.mkTactic("smt");
Tactic then = ctx.then(simplifyTactic, smtTactic, new Tactic[] {});
Solver solver = ctx.mkSolver(then);
solver.add(bel2.toArray(new BoolExpr[0])); // bel2 is List<BoolExpr>
Status status = solver.check();

这样做会导致模型而不是简化。 另外,让我完全按照简化策略工作有点困难。 结果通常是未知的,原因是“不完整”。

我上面描述的预期结果是否可以用Z3计算?怎么办呢?

我已经在这个论坛中环顾四周,但我的观点并没有真正得到回答......

1 个答案:

答案 0 :(得分:1)

作为一种策略,smt不会导致你试图实现的断言的任何转换或简化,这是可满足性的策略,所以对于某些断言,它会返回sat,不饱和,未知,或可能超时。

简化策略的使用更符合您的要求,但您可能需要应用不同的策略来实现您想要的转换。但是,当我以SMT-LIB格式编码您的问题并在您尝试时使用ctx-solver-simplify策略时,它会返回我认为您正在寻找的内容(rise4fun link:http://rise4fun.com/Z3/r2id):< / p>

(declare-fun A () Bool)
(declare-fun B () Bool)
(declare-fun C () Bool)
(declare-fun D () Bool)
(declare-fun E () Bool)
(declare-fun F () Bool)
(declare-fun G () Bool)
(declare-fun H () Bool)
(declare-fun I () Bool)

(assert (and (=> A B)            
(=> (not B) C)
(=> A B)
(=> B A)
(=> D E)
(=> B F)
(=> G D)
(=> H I)
(=> I (not D))
(=> (not D) I)
(=> C (not B))
C))

(apply ctx-solver-simplify)
; result: 
; (goals
; (goal
;  (=> A B)
;  (or (not D) E)
;  (or (not G) D)
;  (or (not H) I)
;  (or (not I) (not D))
;  (or D I)
;  (not B)
;  C
;  :precision precise :depth 1)
;)

对于您的实验,您可能需要查看策略(http://rise4fun.com/z3/tutorialcontent/strategies#h21)并在使用API​​之前在SMT-LIB界面中尝试一些,因为您可能会更快地进行实验。此外,正如您所看到的,这会返回一个目标。在Java API中,尝试更改为以下内容并查看ApplyResult对象的Subgoals字段(这是Goal个对象的集合),以查看它是否具有您想要的内容:

Tactic simplifyTactic = ctx.mkTactic("ctx-solver-simplify");
Goal g = ctx.mkGoal();
g.Assert(bel2.toArray(new BoolExpr[0]));
ApplyResult a = simplifyTactic.Apply(g);
// look at a.Subgoals

这是基于我对.NET API的经验,它可能与Java略有不同,但您可以在此处查看Goal Java文档: https://z3.codeplex.com/SourceControl/changeset/view/8bfbdf1e680d#src/api/java/Goal.java