summaryrefslogtreecommitdiff
path: root/src/api
diff options
context:
space:
mode:
authorAina Niemetz <aina.niemetz@gmail.com>2019-01-29 11:47:04 -0800
committerGitHub <noreply@github.com>2019-01-29 11:47:04 -0800
commitd4870775e67c7878c32c17f10b1217c14dc5869b (patch)
tree8e2bcd1a731eab54041724bb9310e1c7aaaf3e4c /src/api
parent1eaf6cf987fa1452528dc0598ca7235be735ba3b (diff)
New C++ API: Fix checks for mkTerm. (#2820)
This required fixing the OpTerm handling for mkTerm functions in the API.
Diffstat (limited to 'src/api')
-rw-r--r--src/api/cvc4cpp.cpp173
-rw-r--r--src/api/cvc4cpp.h51
-rw-r--r--src/api/cvc4cppkind.h26
3 files changed, 164 insertions, 86 deletions
diff --git a/src/api/cvc4cpp.cpp b/src/api/cvc4cpp.cpp
index 123613797..ddb17c3a7 100644
--- a/src/api/cvc4cpp.cpp
+++ b/src/api/cvc4cpp.cpp
@@ -1444,6 +1444,14 @@ DatatypeSelector::DatatypeSelector(const CVC4::DatatypeConstructorArg& stor)
DatatypeSelector::~DatatypeSelector() {}
+bool DatatypeSelector::isResolved() const { return d_stor->isResolved(); }
+
+OpTerm DatatypeSelector::getSelectorTerm() const
+{
+ CVC4_API_CHECK(isResolved()) << "Expected resolved datatype selector.";
+ return d_stor->getSelector();
+}
+
std::string DatatypeSelector::toString() const
{
std::stringstream ss;
@@ -1478,10 +1486,10 @@ DatatypeConstructor::~DatatypeConstructor() {}
bool DatatypeConstructor::isResolved() const { return d_ctor->isResolved(); }
-Term DatatypeConstructor::getConstructorTerm() const
+OpTerm DatatypeConstructor::getConstructorTerm() const
{
CVC4_API_CHECK(isResolved()) << "Expected resolved datatype constructor.";
- return Term(d_ctor->getConstructor());
+ return OpTerm(d_ctor->getConstructor());
}
DatatypeSelector DatatypeConstructor::operator[](const std::string& name) const
@@ -1498,7 +1506,7 @@ DatatypeSelector DatatypeConstructor::getSelector(const std::string& name) const
return (*d_ctor)[name];
}
-Term DatatypeConstructor::getSelectorTerm(const std::string& name) const
+OpTerm DatatypeConstructor::getSelectorTerm(const std::string& name) const
{
// CHECK: cons with name exists?
// CHECK: is resolved?
@@ -1627,7 +1635,7 @@ DatatypeConstructor Datatype::getConstructor(const std::string& name) const
return (*d_dtype)[name];
}
-Term Datatype::getConstructorTerm(const std::string& name) const
+OpTerm Datatype::getConstructorTerm(const std::string& name) const
{
// CHECK: cons with name exists?
// CHECK: is resolved?
@@ -2451,40 +2459,41 @@ void Solver::checkMkTerm(Kind kind, uint32_t nchildren) const
<< "Only operator-style terms are created with mkTerm(), "
"to create variables and constants see mkVar(), mkBoundVar(), "
"and mkConst().";
- if (nchildren)
- {
- const uint32_t n =
- nchildren - (mk == CVC4::kind::metakind::PARAMETERIZED ? 1 : 0);
- CVC4_API_KIND_CHECK_EXPECTED(n >= minArity(kind) && n <= maxArity(kind),
- kind)
- << "Terms with kind " << kindToString(kind) << " must have at least "
- << minArity(kind) << " children and at most " << maxArity(kind)
- << " children (the one under construction has " << n << ")";
- }
+ CVC4_API_KIND_CHECK_EXPECTED(
+ nchildren >= minArity(kind) && nchildren <= maxArity(kind), kind)
+ << "Terms with kind " << kindToString(kind) << " must have at least "
+ << minArity(kind) << " children and at most " << maxArity(kind)
+ << " children (the one under construction has " << nchildren << ")";
}
-void Solver::checkMkOpTerm(OpTerm opTerm, uint32_t nchildren) const
+void Solver::checkMkOpTerm(Kind kind, OpTerm opTerm, uint32_t nchildren) const
{
- const Kind kind = opTerm.getKind();
Assert(isDefinedIntKind(extToIntKind(kind)));
const CVC4::Kind int_kind = extToIntKind(kind);
- const CVC4::Kind int_op_kind =
+ const CVC4::Kind int_op_kind = opTerm.d_expr->getKind();
+ const CVC4::Kind int_op_to_kind =
NodeManager::operatorToKind(opTerm.d_expr->getNode());
- CVC4_API_ARG_CHECK_EXPECTED(int_kind == kind::BUILTIN
- || CVC4::kind::metaKindOf(int_op_kind)
- == kind::metakind::PARAMETERIZED,
- opTerm)
+ CVC4_API_ARG_CHECK_EXPECTED(
+ int_kind == int_op_to_kind
+ || (kind == APPLY_CONSTRUCTOR
+ && int_op_to_kind == CVC4::Kind::UNDEFINED_KIND)
+ || (kind == APPLY_SELECTOR
+ && int_op_to_kind == CVC4::Kind::UNDEFINED_KIND)
+ || (kind == APPLY_UF && int_op_to_kind == CVC4::Kind::UNDEFINED_KIND),
+ kind)
+ << "kind that matches kind associated with given operator term";
+ CVC4_API_ARG_CHECK_EXPECTED(
+ int_op_kind == CVC4::kind::BUILTIN
+ || CVC4::kind::metaKindOf(int_kind) == kind::metakind::PARAMETERIZED,
+ opTerm)
<< "This term constructor is for parameterized kinds only";
- if (nchildren)
- {
- uint32_t min_arity = ExprManager::minArity(int_op_kind);
- uint32_t max_arity = ExprManager::maxArity(int_op_kind);
- CVC4_API_KIND_CHECK_EXPECTED(
- nchildren >= min_arity && nchildren <= max_arity, kind)
- << "Terms with kind " << kindToString(kind) << " must have at least "
- << min_arity << " children and at most " << max_arity
- << " children (the one under construction has " << nchildren << ")";
- }
+ uint32_t min_arity = ExprManager::minArity(int_kind);
+ uint32_t max_arity = ExprManager::maxArity(int_kind);
+ CVC4_API_KIND_CHECK_EXPECTED(nchildren >= min_arity && nchildren <= max_arity,
+ kind)
+ << "Terms with kind " << kindToString(kind) << " must have at least "
+ << min_arity << " children and at most " << max_arity
+ << " children (the one under construction has " << nchildren << ")";
}
Term Solver::mkTerm(Kind kind) const
@@ -2611,13 +2620,30 @@ Term Solver::mkTerm(Kind kind, const std::vector<Term>& children) const
}
}
-Term Solver::mkTerm(OpTerm opTerm, Term child) const
+Term Solver::mkTerm(Kind kind, OpTerm opTerm) const
+{
+ try
+ {
+ checkMkOpTerm(kind, opTerm, 0);
+ const CVC4::Kind int_kind = extToIntKind(kind);
+ Term res = d_exprMgr->mkExpr(int_kind, *opTerm.d_expr);
+ (void)res.d_expr->getType(true); /* kick off type checking */
+ return res;
+ }
+ catch (const CVC4::TypeCheckingException& e)
+ {
+ throw CVC4ApiException(e.getMessage());
+ }
+}
+
+Term Solver::mkTerm(Kind kind, OpTerm opTerm, Term child) const
{
try
{
CVC4_API_ARG_CHECK_EXPECTED(!child.isNull(), child) << "non-null term";
- checkMkOpTerm(opTerm, 1);
- Term res = d_exprMgr->mkExpr(*opTerm.d_expr, *child.d_expr);
+ checkMkOpTerm(kind, opTerm, 1);
+ const CVC4::Kind int_kind = extToIntKind(kind);
+ Term res = d_exprMgr->mkExpr(int_kind, *opTerm.d_expr, *child.d_expr);
(void)res.d_expr->getType(true); /* kick off type checking */
return res;
}
@@ -2627,15 +2653,16 @@ Term Solver::mkTerm(OpTerm opTerm, Term child) const
}
}
-Term Solver::mkTerm(OpTerm opTerm, Term child1, Term child2) const
+Term Solver::mkTerm(Kind kind, OpTerm opTerm, Term child1, Term child2) const
{
try
{
CVC4_API_ARG_CHECK_EXPECTED(!child1.isNull(), child1) << "non-null term";
CVC4_API_ARG_CHECK_EXPECTED(!child2.isNull(), child2) << "non-null term";
- checkMkOpTerm(opTerm, 2);
- Term res =
- d_exprMgr->mkExpr(*opTerm.d_expr, *child1.d_expr, *child2.d_expr);
+ checkMkOpTerm(kind, opTerm, 2);
+ const CVC4::Kind int_kind = extToIntKind(kind);
+ Term res = d_exprMgr->mkExpr(
+ int_kind, *opTerm.d_expr, *child1.d_expr, *child2.d_expr);
(void)res.d_expr->getType(true); /* kick off type checking */
return res;
}
@@ -2645,16 +2672,21 @@ Term Solver::mkTerm(OpTerm opTerm, Term child1, Term child2) const
}
}
-Term Solver::mkTerm(OpTerm opTerm, Term child1, Term child2, Term child3) const
+Term Solver::mkTerm(
+ Kind kind, OpTerm opTerm, Term child1, Term child2, Term child3) const
{
try
{
CVC4_API_ARG_CHECK_EXPECTED(!child1.isNull(), child1) << "non-null term";
CVC4_API_ARG_CHECK_EXPECTED(!child2.isNull(), child2) << "non-null term";
CVC4_API_ARG_CHECK_EXPECTED(!child3.isNull(), child3) << "non-null term";
- checkMkOpTerm(opTerm, 3);
- Term res = d_exprMgr->mkExpr(
- *opTerm.d_expr, *child1.d_expr, *child2.d_expr, *child3.d_expr);
+ checkMkOpTerm(kind, opTerm, 3);
+ const CVC4::Kind int_kind = extToIntKind(kind);
+ Term res = d_exprMgr->mkExpr(int_kind,
+ *opTerm.d_expr,
+ *child1.d_expr,
+ *child2.d_expr,
+ *child3.d_expr);
(void)res.d_expr->getType(true); /* kick off type checking */
return res;
}
@@ -2664,7 +2696,9 @@ Term Solver::mkTerm(OpTerm opTerm, Term child1, Term child2, Term child3) const
}
}
-Term Solver::mkTerm(OpTerm opTerm, const std::vector<Term>& children) const
+Term Solver::mkTerm(Kind kind,
+ OpTerm opTerm,
+ const std::vector<Term>& children) const
{
try
{
@@ -2674,9 +2708,10 @@ Term Solver::mkTerm(OpTerm opTerm, const std::vector<Term>& children) const
!children[i].isNull(), "parameter term", children[i], i)
<< "non-null term";
}
- checkMkOpTerm(opTerm, children.size());
+ checkMkOpTerm(kind, opTerm, children.size());
+ const CVC4::Kind int_kind = extToIntKind(kind);
std::vector<Expr> echildren = termVectorToExprs(children);
- Term res = d_exprMgr->mkExpr(*opTerm.d_expr, echildren);
+ Term res = d_exprMgr->mkExpr(int_kind, *opTerm.d_expr, echildren);
(void)res.d_expr->getType(true); /* kick off type checking */
return res;
}
@@ -2691,16 +2726,26 @@ Term Solver::mkTuple(const std::vector<Sort>& sorts,
{
CVC4_API_CHECK(sorts.size() == terms.size())
<< "Expected the same number of sorts and elements";
- std::vector<Term> args;
- for (size_t i = 0, size = sorts.size(); i < size; i++)
+ try
{
- args.push_back(ensureTermSort(terms[i], sorts[i]));
- }
+ std::vector<CVC4::Expr> args;
+ for (size_t i = 0, size = sorts.size(); i < size; i++)
+ {
+ args.push_back(*(ensureTermSort(terms[i], sorts[i])).d_expr);
+ }
- Sort s = mkTupleSort(sorts);
- Datatype dt = s.getDatatype();
- args.insert(args.begin(), dt[0].getConstructorTerm());
- return mkTerm(APPLY_CONSTRUCTOR, args);
+ Sort s = mkTupleSort(sorts);
+ Datatype dt = s.getDatatype();
+ Term res = d_exprMgr->mkExpr(extToIntKind(APPLY_CONSTRUCTOR),
+ *dt[0].getConstructorTerm().d_expr,
+ args);
+ (void)res.d_expr->getType(true); /* kick off type checking */
+ return res;
+ }
+ catch (const CVC4::TypeCheckingException& e)
+ {
+ throw CVC4ApiException(e.getMessage());
+ }
}
std::vector<Expr> Solver::termVectorToExprs(
@@ -3458,28 +3503,32 @@ void Solver::setOption(const std::string& option,
}
}
-Term Solver::ensureTermSort(const Term& t, const Sort& s) const
+Term Solver::ensureTermSort(const Term& term, const Sort& sort) const
{
- CVC4_API_CHECK(t.getSort() == s || (t.getSort().isInteger() && s.isReal()))
+ CVC4_API_CHECK(term.getSort() == sort
+ || (term.getSort().isInteger() && sort.isReal()))
<< "Expected conversion from Int to Real";
- if (t.getSort() == s)
+ Sort t = term.getSort();
+ if (term.getSort() == sort)
{
- return t;
+ return term;
}
// Integers are reals, too
- Assert(t.getSort().isReal());
- Term res = t;
- if (t.getSort().isInteger())
+ Assert(t.isReal());
+ Term res = term;
+ if (t.isInteger())
{
// Must cast to Real to ensure correct type is passed to parametric type
// constructors. We do this cast using division with 1. This has the
// advantage wrt using TO_REAL since (constant) division is always included
// in the theory.
- res = mkTerm(DIVISION, *t.d_expr, mkReal(1));
+ res = Term(d_exprMgr->mkExpr(extToIntKind(DIVISION),
+ *res.d_expr,
+ d_exprMgr->mkConst(CVC4::Rational(1))));
}
- Assert(res.getSort() == s);
+ Assert(res.getSort() == sort);
return res;
}
diff --git a/src/api/cvc4cpp.h b/src/api/cvc4cpp.h
index a06f2e415..b8da070fc 100644
--- a/src/api/cvc4cpp.h
+++ b/src/api/cvc4cpp.h
@@ -1100,6 +1100,17 @@ class CVC4_PUBLIC DatatypeSelector
~DatatypeSelector();
/**
+ * @return true if this datatype selector has been resolved.
+ */
+ bool isResolved() const;
+
+ /**
+ * Get the selector operator of this datatype selector.
+ * @return the selector operator
+ */
+ OpTerm getSelectorTerm() const;
+
+ /**
* @return a string representation of this datatype selector
*/
std::string toString() const;
@@ -1154,7 +1165,7 @@ class CVC4_PUBLIC DatatypeConstructor
* Get the constructor operator of this datatype constructor.
* @return the constructor operator
*/
- Term getConstructorTerm() const;
+ OpTerm getConstructorTerm() const;
/**
* Get the datatype selector with the given name.
@@ -1173,7 +1184,7 @@ class CVC4_PUBLIC DatatypeConstructor
* @param name the name of the datatype selector
* @return a term representing the datatype selector with the given name
*/
- Term getSelectorTerm(const std::string& name) const;
+ OpTerm getSelectorTerm(const std::string& name) const;
/**
* @return a string representation of this datatype constructor
@@ -1320,7 +1331,7 @@ class CVC4_PUBLIC Datatype
* similarly-named constructors, the
* first is returned.
*/
- Term getConstructorTerm(const std::string& name) const;
+ OpTerm getConstructorTerm(const std::string& name) const;
/** Get the number of constructors for this Datatype. */
size_t getNumConstructors() const;
@@ -1725,43 +1736,59 @@ class CVC4_PUBLIC Solver
Term mkTerm(Kind kind, const std::vector<Term>& children) const;
/**
- * Create unary term from a given operator term.
+ * Create nullary term of given kind from a given operator term.
+ * Create operator terms with mkOpTerm().
+ * @param kind the kind of the term
+ * @param the operator term
+ * @return the Term
+ */
+ Term mkTerm(Kind kind, OpTerm opTerm) const;
+
+ /**
+ * Create unary term of given kind from a given operator term.
* Create operator terms with mkOpTerm().
+ * @param kind the kind of the term
* @param the operator term
* @child the child of the term
* @return the Term
*/
- Term mkTerm(OpTerm opTerm, Term child) const;
+ Term mkTerm(Kind kind, OpTerm opTerm, Term child) const;
/**
- * Create binary term from a given operator term.
+ * Create binary term of given kind from a given operator term.
+ * @param kind the kind of the term
* Create operator terms with mkOpTerm().
* @param the operator term
* @child1 the first child of the term
* @child2 the second child of the term
* @return the Term
*/
- Term mkTerm(OpTerm opTerm, Term child1, Term child2) const;
+ Term mkTerm(Kind kind, OpTerm opTerm, Term child1, Term child2) const;
/**
- * Create ternary term from a given operator term.
+ * Create ternary term of given kind from a given operator term.
* Create operator terms with mkOpTerm().
+ * @param kind the kind of the term
* @param the operator term
* @child1 the first child of the term
* @child2 the second child of the term
* @child3 the third child of the term
* @return the Term
*/
- Term mkTerm(OpTerm opTerm, Term child1, Term child2, Term child3) const;
+ Term mkTerm(
+ Kind kind, OpTerm opTerm, Term child1, Term child2, Term child3) const;
/**
- * Create n-ary term from a given operator term.
+ * Create n-ary term of given kind from a given operator term.
* Create operator terms with mkOpTerm().
+ * @param kind the kind of the term
* @param the operator term
* @children the children of the term
* @return the Term
*/
- Term mkTerm(OpTerm opTerm, const std::vector<Term>& children) const;
+ Term mkTerm(Kind kind,
+ OpTerm opTerm,
+ const std::vector<Term>& children) const;
/**
* Create a tuple term. Terms are automatically converted if sorts are
@@ -2485,7 +2512,7 @@ class CVC4_PUBLIC Solver
/* Helper to convert a vector of sorts to internal types. */
std::vector<Expr> termVectorToExprs(const std::vector<Term>& vector) const;
/* Helper to check for API misuse in mkTerm functions. */
- void checkMkOpTerm(OpTerm opTerm, uint32_t nchildren) const;
+ void checkMkOpTerm(Kind kind, OpTerm opTerm, uint32_t nchildren) const;
/* Helper to check for API misuse in mkOpTerm functions. */
void checkMkTerm(Kind kind, uint32_t nchildren) const;
/* Helper for mk-functions that call d_exprMgr->mkConst(). */
diff --git a/src/api/cvc4cppkind.h b/src/api/cvc4cppkind.h
index a7f6926bb..4e69ddfe1 100644
--- a/src/api/cvc4cppkind.h
+++ b/src/api/cvc4cppkind.h
@@ -1649,30 +1649,32 @@ enum CVC4_PUBLIC Kind : int32_t
/**
* Constructor application.
* Paramters: n > 0
- * -[1]: Constructor
+ * -[1]: Constructor (operator term)
* -[2]..[n]: Parameters to the constructor
* Create with:
- * mkTerm(Kind kind)
- * mkTerm(Kind kind, Term child)
- * mkTerm(Kind kind, Term child1, Term child2)
- * mkTerm(Kind kind, Term child1, Term child2, Term child3)
- * mkTerm(Kind kind, const std::vector<Term>& children)
+ * mkTerm(Kind kind, OpTerm opTerm)
+ * mkTerm(Kind kind, OpTerm opTerm, Term child)
+ * mkTerm(Kind kind, OpTerm opTerm, Term child1, Term child2)
+ * mkTerm(Kind kind, OpTerm opTerm, Term child1, Term child2, Term child3)
+ * mkTerm(Kind kind, OpTerm opTerm, const std::vector<Term>& children)
*/
- APPLY_SELECTOR,
+ APPLY_CONSTRUCTOR,
/**
* Datatype selector application.
* Parameters: 1
- * -[1]: Datatype term (undefined if mis-applied)
+ * -[1]: Selector (operator term)
+ * -[2]: Datatype term (undefined if mis-applied)
* Create with:
- * mkTerm(Kind kind, Term child)
+ * mkTerm(Kind kind, OpTerm opTerm, Term child)
*/
- APPLY_CONSTRUCTOR,
+ APPLY_SELECTOR,
/**
* Datatype selector application.
* Parameters: 1
- * -[1]: Datatype term (defined rigidly if mis-applied)
+ * -[1]: Selector (operator term)
+ * -[2]: Datatype term (defined rigidly if mis-applied)
* Create with:
- * mkTerm(Kind kind, Term child)
+ * mkTerm(Kind kind, OpTerm opTerm, Term child)
*/
APPLY_SELECTOR_TOTAL,
/**
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback