首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在CVC4中使用类型参数调用自定义数据类型的no构造函数

在CVC4中使用类型参数调用自定义数据类型的no构造函数
EN

Stack Overflow用户
提问于 2020-07-27 00:09:05
回答 1查看 42关注 0票数 1

我试图使用Java在option中定义参数化数据类型CVC4。

代码语言:javascript
复制
 DATATYPE option[T] =
        None
      | Some(elem: T)
 END;

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

代码语言:javascript
复制
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;
    }
}

这将导致以下错误:

代码语言:javascript
复制
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)

当我移除类型归属行时,它不会推断正确的类型,因此我假设类型归属是必要的。在这里,我得到了没有类型归属的错误:

代码语言:javascript
复制
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正确创建此数据类型和公式?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-08-01 11:57:04

安德鲁·雷诺兹()在CVC4邮件列表上给出了答案:

首先,请注意,我们已经更新为一个新的

(https://github.com/CVC4/CVC4/blob/master/src/api/cvc4cpp.h)。

巧合的是,我刚刚提交了一个PR,它在新API:https://github.com/CVC4/CVC4/pull/4817中添加了获取所需构造函数的接口。

如果您对旧API感兴趣,那么您的代码几乎是正确的,但是,我们所期望的转换有一个细微的差别。

特别是,在SMT转换中,构造器运算符不适用于术语(您可能对本讨论https://github.com/Z3Prover/z3/issues/2135感兴趣)。这意味着在CVC4中,铸零项的AST是:(APPLY_CONSTRUCTOR (APPLY_TYPE_ASCRIPTION None T)) not (APPLY_TYPE_ASCRIPTION (APPLY_CONSTRUCTOR None) optionInt)不幸的是,旧API中有一个关于T是什么的复杂问题。它不是"optionInt",而是“optionInt类型的构造函数类型”,或者我们所说的“构造函数类型”。

下面是用于创建表达式的更正代码:

代码语言:javascript
复制
    // 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. 类型optionINT和构造函数类型optionINT之间存在差异。类型归属需要使用构造函数类型。
  2. 分配必须在构造函数上进行,而不是在应用的
  3. 上。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63107078

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档