在 CVC4 中使用类型参数调用自定义数据类型的无参数构造函数
Invoking no-arg constructors of custom data types with type parameters in CVC4
我正在尝试使用 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 正确创建此数据类型和公式?
在 CVC4 邮件列表上得到了 Andrew Reynolds 的答复:
First, notice that we have updated to a new API
(https://github.com/CVC4/CVC4/blob/master/src/api/cvc4cpp.h).
Coincidentally, I just submitted a PR that adds the interface for
getting the required constructor you are looking for, in the new API:
https://github.com/CVC4/CVC4/pull/4817
If you are interested in the old API, your code is almost correct,
however, there is a subtle difference in what we expect to be cast.
In particular, in SMT-LIB casts are applied to constructor operators,
not terms (you may be interested in this discussion
https://github.com/Z3Prover/z3/issues/2135). This means that the AST
of a casted nil term in CVC4 is: (APPLY_CONSTRUCTOR
(APPLY_TYPE_ASCRIPTION None T)) not (APPLY_TYPE_ASCRIPTION
(APPLY_CONSTRUCTOR None) option[Int]) Unfortunately, there is a
complication in the old API about what T is. It is not "option[Int]",
instead it is "the type of constructors of type option[Int]", or what
we call a "constructor type".
这是创建表达式的更正代码:
// 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);
- 类型选项[INT] 和构造函数类型选项[INT] 之间存在差异。类型归属需使用构造函数类型
- 归属必须在构造函数上进行,而不是在应用的构造函数上进行。
我正在尝试使用 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 正确创建此数据类型和公式?
在 CVC4 邮件列表上得到了 Andrew Reynolds 的答复:
First, notice that we have updated to a new API (https://github.com/CVC4/CVC4/blob/master/src/api/cvc4cpp.h).
Coincidentally, I just submitted a PR that adds the interface for getting the required constructor you are looking for, in the new API: https://github.com/CVC4/CVC4/pull/4817If you are interested in the old API, your code is almost correct, however, there is a subtle difference in what we expect to be cast.
In particular, in SMT-LIB casts are applied to constructor operators, not terms (you may be interested in this discussion https://github.com/Z3Prover/z3/issues/2135). This means that the AST of a casted nil term in CVC4 is: (APPLY_CONSTRUCTOR (APPLY_TYPE_ASCRIPTION None T)) not (APPLY_TYPE_ASCRIPTION (APPLY_CONSTRUCTOR None) option[Int]) Unfortunately, there is a complication in the old API about what T is. It is not "option[Int]", instead it is "the type of constructors of type option[Int]", or what we call a "constructor type".
这是创建表达式的更正代码:
// 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);
- 类型选项[INT] 和构造函数类型选项[INT] 之间存在差异。类型归属需使用构造函数类型
- 归属必须在构造函数上进行,而不是在应用的构造函数上进行。