Z3:用于量化公式的Java API

时间:2016-01-25 19:14:36

标签: java z3 java-api

我正在尝试使用Z3的JAVA API来构建以下公式

    (assert (forall ((x_0 fcn_sort_2) (x_1 fcn_sort_2))
                    (=> (and (= (domain x_0) 
                                (domain x_1))
                             (forall ((y Int))
                                     (= (alpha x_0 y) 
                                        (alpha x_1 y))))))
                        (= x_0 x_1)))))

通过以下代码

Sort[] types1 = new Sort[2]; // for x_0 and x_1
Expr[] xs1 = new Expr[2];        
for (int j = 0; j < 2; j++) {
    types1[j] = this.getZ3Sort("fcn_sort_2");        
    xs1[j] = ctx.mkConst(ctx.mkSymbol("x_" + Integer.toString(j)), types1[j]);        
}    
Sort[] types2 = new Sort[1]; // for y
Expr[] xs2 = new Expr[1];    
types2[0] = ctx.mkIntSort();
xs2[0] = ctx.mkConst(ctx.mkSymbol("y"), types2[0]);
FuncDecl alpha_fcn = this.getFuncSymbol("alpha");
Expr[] arg0 = new Expr[] { xs1[0], xs2[0] };
Expr[] arg1 = new Expr[] { xs1[1], xs2[0] };
BoolExpr 
    // (= (alpha x_0 y) (alpha x_1 y))
    body2 = ctx.mkEq(ctx.mkApp(alpha_fcn, arg0), ctx.mkApp(alpha_fcn, arg1)), 
    // forall ((y Int)) ...
    bf2 = ctx.mkForall(xs2, body2, 1, null, null, null, null); 
FuncDecl domain_fcn = this.getFuncSymbol("domain");
BoolExpr
    // (= x_0 x_1)
    eqX = ctx.mkEq(xs1[0], xs1[1]), 
    // (= (domain x_0) (domain x_1))
    eqDo = ctx.mkEq(ctx.mkApp(domain_fcn, new Expr[] {xs1[0]}), ctx.mkApp(domain_fcn, new Expr[] {xs1[1]})), 
    // (and ...)
    andNode = ctx.mkAnd(eqDo, bf2),         
    // (=> ...)
    body1 = ctx.mkImplies(andNode, eqX),
    // (forall ((x_0 ...) (x_1 ...))
    bf1 = ctx.mkForall(xs1, body1, 1, null, null, null, null);  

其中getFuncSymbol是我自己的函数,用于获取之前声明的FuncDecl。

不幸的是,我使用“let”和“a!1”

得到了错误的结果
(assert (forall ((x_0 fcn_sort_2) (x_1 fcn_sort_2))
  (let ((a!1 (and (= (domain_fcn_sort_2 x_0) (domain_fcn_sort_2 x_1))
                  (forall ((y Int))
                    (= (alpha_fcn_sort_2 x_0 y) (alpha_fcn_sort_2 x_1 y))))))
    (=> a!1 (= x_0 x_1)))))

我发现有些不对劲,“让((a!1”)发生在

    body1 = ctx.mkImplies(andNode, eqX)

我错过了什么吗?谢谢

1 个答案:

答案 0 :(得分:0)

let-expressions在漂亮打印期间引入,试图使输出更简洁。在这里,它只是意味着只要输出中出现名称a!1,就可以将其替换为(and ...)。从语义上讲,这没有什么区别。