Z3: Java API 用于量化公式

Z3: Java API for quantified formulas

我正在尝试使用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)))))

我发现在

行发生了错误 "let ((a!1"
    body1 = ctx.mkImplies(andNode, eqX)

我错过了什么吗?谢谢

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