【问题标题】:Invoking no-arg constructors of custom data types with type parameters in CVC4在 CVC4 中使用类型参数调用自定义数据类型的无参数构造函数
【发布时间】:2020-07-27 00:09:05
【问题描述】:

我正在尝试使用 Java API 在 CVC4 中定义参数化数据类型 option

 DATATYPE option[T] =
        None
      | Some(elem: T)
 END;

我的问题是我不知道如何调用None 构造函数。 我尝试了以下代码:

class Cvc4Test3 {

    public static void main(String... args) {
        Cvc4Solver.loadLibrary();
        ExprManager em = new ExprManager();
        SmtEngine smt = new SmtEngine(em);

        DatatypeType dt = createOptionDatatype(em);
        // instantiate to int
        DatatypeType dtInt = dt.instantiate(vector(em.integerType()));

        // x is an integer variable
        Expr x = em.mkVar("x", em.integerType());

        // create equation: None::option[INT] = Some(x)
        Expr l = em.mkExpr(Kind.APPLY_CONSTRUCTOR, dtInt.getConstructor("None"));
        Expr la = em.mkExpr(Kind.APPLY_TYPE_ASCRIPTION, em.mkConst(new AscriptionType(dtInt)), l);
        Expr r = em.mkExpr(Kind.APPLY_CONSTRUCTOR, dtInt.getConstructor("Some"), x);
        Expr eq = em.mkExpr(Kind.EQUAL, la, r);

        // Try to solve equation:
        smt.setOption("produce-models", new SExpr(true));
        smt.assertFormula(eq);
        Result res = smt.checkSat();
        System.out.println("res = " + res);
    }

    /**
     * DATATYPE option[T] =
     * None
     * | Some(elem: T)
     * END;
     */
    private static DatatypeType createOptionDatatype(ExprManager em) {
        Type t = em.mkSort("T");
        vectorType types = vector(t);
        Datatype dt = new Datatype("option", types);
        DatatypeConstructor cNone = new DatatypeConstructor("None");
        dt.addConstructor(cNone);
        DatatypeConstructor cSome = new DatatypeConstructor("Some");
        cSome.addArg("elem", t);
        dt.addConstructor(cSome);
        return em.mkDatatypeType(dt);
    }

    private static vectorType vector(Type... types) {
        vectorType res = new vectorType();
        for (Type t : types) {
            res.add(t);
        }
        return res;
    }
}

这会导致以下错误:

Exception in thread "main" java.lang.RuntimeException: matching failed for type ascription argument of parameterized datatype: matching failed for type ascription argument of parameterized datatype
    at edu.nyu.acsys.CVC4.CVC4JNI.SmtEngine_assertFormula__SWIG_1(Native Method)
    at edu.nyu.acsys.CVC4.SmtEngine.assertFormula(SmtEngine.java:149)

当我删除类型归属行时,它不会推断出正确的类型,所以我认为类型归属是必要的。这是我得到的没有类型归属的错误:

Exception in thread "main" java.lang.RuntimeException: Subexpressions must have a common base type:
Equation: None = Some(x)
Type 1: option[T]
Type 2: option[INT]
: Subexpressions must have a common base type:
Equation: None = Some(x)
Type 1: option[T]
Type 2: option[INT]

    at edu.nyu.acsys.CVC4.CVC4JNI.SmtEngine_assertFormula__SWIG_1(Native Method)
    at edu.nyu.acsys.CVC4.SmtEngine.assertFormula(SmtEngine.java:149)

如何使用 Java API 正确创建此数据类型和公式?

【问题讨论】:

  • 我不确定 Java 层,但如果您在 SMTLib 中编写此代码,则需要说明。类似:(as None (Option Int))。这就是 Java 版本试图编码的内容吗?
  • 是的,这就是我希望我的代码执行的操作。但是,我想我错误地使用了 API。
  • 我建议直接在 CVC4 问题页面询问。您将获得更快的答案:github.com/CVC4/CVC4/issues 请在此处发布您找到的答案。

标签: java cvc4


【解决方案1】:

在 CVC4 邮件列表上从 Andrew Reynolds 那里得到了答复:

首先,请注意我们已更新到新的 API (https://github.com/CVC4/CVC4/blob/master/src/api/cvc4cpp.h)。
巧合的是,我刚刚提交了一个PR,添加了接口 在新 API 中获取所需的构造函数: https://github.com/CVC4/CVC4/pull/4817

如果您对旧 API 感兴趣,您的代码几乎是正确的, 但是,我们期望的演员阵容存在细微差别。

特别是,在 SMT-LIB 中,强制转换应用于构造函数运算符, 不是条款(您可能对此讨论感兴趣 https://github.com/Z3Prover/z3/issues/2135)。这意味着 AST CVC4 中的 nil 项是:(APPLY_CONSTRUCTOR (APPLY_TYPE_ASCRIPTION 无 T)) 不是 (APPLY_TYPE_ASCRIPTION (APPLY_CONSTRUCTOR None) option[Int]) 不幸的是,有一个 旧 API 中关于 T 是什么的复杂性。它不是“选项[Int]”, 相反,它是“option[Int] 类型的构造函数的类型”,或者什么 我们称之为“构造函数类型”。

这是创建表达式的更正代码:

    // create equation: None::option[INT] = Some(x)
    Type noneInt = dtInt.getDatatype().get("None").getSpecializedConstructorType(dtInt);
    Expr la = em.mkExpr(Kind.APPLY_TYPE_ASCRIPTION, em.mkConst(new AscriptionType(noneInt)), dtInt.getConstructor("None"));
    Expr l = em.mkExpr(Kind.APPLY_CONSTRUCTOR, la);
    Expr r = em.mkExpr(Kind.APPLY_CONSTRUCTOR, dtInt.getConstructor("Some"), x);
    Expr eq = em.mkExpr(Kind.EQUAL, l, r);
  1. 类型选项[INT] 和构造函数类型选项[INT] 之间存在差异。类型归属需要使用构造函数类型。
  2. 归属必须在构造函数上,而不是在应用的构造函数上。

【讨论】:

    猜你喜欢
    • 2021-08-17
    • 1970-01-01
    • 2015-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多