我在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计算?怎么办呢?
我已经在这个论坛中环顾四周,但我的观点并没有真正得到回答......
答案 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