summaryrefslogtreecommitdiff
path: root/src/api/cvc4cpp.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/api/cvc4cpp.cpp')
-rw-r--r--src/api/cvc4cpp.cpp2035
1 files changed, 1281 insertions, 754 deletions
diff --git a/src/api/cvc4cpp.cpp b/src/api/cvc4cpp.cpp
index fa995a00a..9b79b5c45 100644
--- a/src/api/cvc4cpp.cpp
+++ b/src/api/cvc4cpp.cpp
@@ -2,10 +2,10 @@
/*! \file cvc4cpp.cpp
** \verbatim
** Top contributors (to current version):
- ** Aina Niemetz, Makai Mann, Andrew Reynolds
+ ** Aina Niemetz, Andrew Reynolds, Andres Noetzli
** This file is part of the CVC4 project.
** Copyright (c) 2009-2020 by the authors listed in the file AUTHORS
- ** in the top-level source directory) and their institutional affiliations.
+ ** in the top-level source directory and their institutional affiliations.
** All rights reserved. See the file COPYING in the top-level source
** directory for licensing information.\endverbatim
**
@@ -34,23 +34,29 @@
#include "api/cvc4cpp.h"
#include <cstring>
+#include <regex>
#include <sstream>
#include "base/check.h"
#include "base/configuration.h"
+#include "expr/dtype.h"
#include "expr/expr.h"
#include "expr/expr_manager.h"
#include "expr/expr_manager_scope.h"
#include "expr/kind.h"
#include "expr/metakind.h"
+#include "expr/node.h"
#include "expr/node_manager.h"
#include "expr/sequence.h"
#include "expr/type.h"
+#include "expr/type_node.h"
#include "options/main_options.h"
#include "options/options.h"
#include "options/smt_options.h"
+#include "proof/unsat_core.h"
#include "smt/model.h"
#include "smt/smt_engine.h"
+#include "smt/smt_mode.h"
#include "theory/logic_info.h"
#include "theory/theory_model.h"
#include "util/random.h"
@@ -76,6 +82,7 @@ const static std::unordered_map<Kind, CVC4::Kind, KindHashFunction> s_kinds{
{DISTINCT, CVC4::Kind::DISTINCT},
{CONSTANT, CVC4::Kind::VARIABLE},
{VARIABLE, CVC4::Kind::BOUND_VARIABLE},
+ {SEXPR, CVC4::Kind::SEXPR},
{LAMBDA, CVC4::Kind::LAMBDA},
{WITNESS, CVC4::Kind::WITNESS},
/* Boolean ------------------------------------------------------------- */
@@ -250,6 +257,23 @@ const static std::unordered_map<Kind, CVC4::Kind, KindHashFunction> s_kinds{
{IDEN, CVC4::Kind::IDEN},
{COMPREHENSION, CVC4::Kind::COMPREHENSION},
{CHOOSE, CVC4::Kind::CHOOSE},
+ {IS_SINGLETON, CVC4::Kind::IS_SINGLETON},
+ /* Bags ---------------------------------------------------------------- */
+ {UNION_MAX, CVC4::Kind::UNION_MAX},
+ {UNION_DISJOINT, CVC4::Kind::UNION_DISJOINT},
+ {INTERSECTION_MIN, CVC4::Kind::INTERSECTION_MIN},
+ {DIFFERENCE_SUBTRACT, CVC4::Kind::DIFFERENCE_SUBTRACT},
+ {DIFFERENCE_REMOVE, CVC4::Kind::DIFFERENCE_REMOVE},
+ {SUBBAG, CVC4::Kind::SUBBAG},
+ {BAG_COUNT, CVC4::Kind::BAG_COUNT},
+ {DUPLICATE_REMOVAL, CVC4::Kind::DUPLICATE_REMOVAL},
+ {MK_BAG, CVC4::Kind::MK_BAG},
+ {EMPTYBAG, CVC4::Kind::EMPTYBAG},
+ {BAG_CARD, CVC4::Kind::BAG_CARD},
+ {BAG_CHOOSE, CVC4::Kind::BAG_CHOOSE},
+ {BAG_IS_SINGLETON, CVC4::Kind::BAG_IS_SINGLETON},
+ {BAG_FROM_SET, CVC4::Kind::BAG_FROM_SET},
+ {BAG_TO_SET, CVC4::Kind::BAG_TO_SET},
/* Strings ------------------------------------------------------------- */
{STRING_CONCAT, CVC4::Kind::STRING_CONCAT},
{STRING_IN_REGEXP, CVC4::Kind::STRING_IN_REGEXP},
@@ -305,6 +329,7 @@ const static std::unordered_map<Kind, CVC4::Kind, KindHashFunction> s_kinds{
{SEQ_SUFFIX, CVC4::Kind::STRING_SUFFIX},
{CONST_SEQUENCE, CVC4::Kind::CONST_SEQUENCE},
{SEQ_UNIT, CVC4::Kind::SEQ_UNIT},
+ {SEQ_NTH, CVC4::Kind::SEQ_NTH},
/* Quantifiers --------------------------------------------------------- */
{FORALL, CVC4::Kind::FORALL},
{EXISTS, CVC4::Kind::EXISTS},
@@ -538,6 +563,23 @@ const static std::unordered_map<CVC4::Kind, Kind, CVC4::kind::KindHashFunction>
{CVC4::Kind::IDEN, IDEN},
{CVC4::Kind::COMPREHENSION, COMPREHENSION},
{CVC4::Kind::CHOOSE, CHOOSE},
+ {CVC4::Kind::IS_SINGLETON, IS_SINGLETON},
+ /* Bags ------------------------------------------------------------ */
+ {CVC4::Kind::UNION_MAX, UNION_MAX},
+ {CVC4::Kind::UNION_DISJOINT, UNION_DISJOINT},
+ {CVC4::Kind::INTERSECTION_MIN, INTERSECTION_MIN},
+ {CVC4::Kind::DIFFERENCE_SUBTRACT, DIFFERENCE_SUBTRACT},
+ {CVC4::Kind::DIFFERENCE_REMOVE, DIFFERENCE_REMOVE},
+ {CVC4::Kind::SUBBAG, SUBBAG},
+ {CVC4::Kind::BAG_COUNT, BAG_COUNT},
+ {CVC4::Kind::DUPLICATE_REMOVAL, DUPLICATE_REMOVAL},
+ {CVC4::Kind::MK_BAG, MK_BAG},
+ {CVC4::Kind::EMPTYBAG, EMPTYBAG},
+ {CVC4::Kind::BAG_CARD, BAG_CARD},
+ {CVC4::Kind::BAG_CHOOSE, BAG_CHOOSE},
+ {CVC4::Kind::BAG_IS_SINGLETON, BAG_IS_SINGLETON},
+ {CVC4::Kind::BAG_FROM_SET, BAG_FROM_SET},
+ {CVC4::Kind::BAG_TO_SET, BAG_TO_SET},
/* Strings --------------------------------------------------------- */
{CVC4::Kind::STRING_CONCAT, STRING_CONCAT},
{CVC4::Kind::STRING_IN_REGEXP, STRING_IN_REGEXP},
@@ -574,12 +616,15 @@ const static std::unordered_map<CVC4::Kind, Kind, CVC4::kind::KindHashFunction>
{CVC4::Kind::REGEXP_OPT, REGEXP_OPT},
{CVC4::Kind::REGEXP_RANGE, REGEXP_RANGE},
{CVC4::Kind::REGEXP_REPEAT, REGEXP_REPEAT},
+ {CVC4::Kind::REGEXP_REPEAT_OP, REGEXP_REPEAT},
{CVC4::Kind::REGEXP_LOOP, REGEXP_LOOP},
+ {CVC4::Kind::REGEXP_LOOP_OP, REGEXP_LOOP},
{CVC4::Kind::REGEXP_EMPTY, REGEXP_EMPTY},
{CVC4::Kind::REGEXP_SIGMA, REGEXP_SIGMA},
{CVC4::Kind::REGEXP_COMPLEMENT, REGEXP_COMPLEMENT},
{CVC4::Kind::CONST_SEQUENCE, CONST_SEQUENCE},
{CVC4::Kind::SEQ_UNIT, SEQ_UNIT},
+ {CVC4::Kind::SEQ_NTH, SEQ_NTH},
/* Quantifiers ----------------------------------------------------- */
{CVC4::Kind::FORALL, FORALL},
{CVC4::Kind::EXISTS, EXISTS},
@@ -642,7 +687,15 @@ uint32_t minArity(Kind k)
{
Assert(isDefinedKind(k));
Assert(isDefinedIntKind(extToIntKind(k)));
- return CVC4::ExprManager::minArity(extToIntKind(k));
+ uint32_t min = CVC4::ExprManager::minArity(extToIntKind(k));
+
+ // At the API level, we treat functions/constructors/selectors/testers as
+ // normal terms instead of making them part of the operator
+ if (isApplyKind(extToIntKind(k)))
+ {
+ min++;
+ }
+ return min;
}
uint32_t maxArity(Kind k)
@@ -651,9 +704,8 @@ uint32_t maxArity(Kind k)
Assert(isDefinedIntKind(extToIntKind(k)));
uint32_t max = CVC4::ExprManager::maxArity(extToIntKind(k));
- // special cases for API level
- // higher-order logic perspective at API
- // functions/constructors/selectors/testers are terms
+ // At the API level, we treat functions/constructors/selectors/testers as
+ // normal terms instead of making them part of the operator
if (isApplyKind(extToIntKind(k))
&& max != std::numeric_limits<uint32_t>::max()) // be careful not to
// overflow
@@ -710,10 +762,35 @@ class CVC4ApiExceptionStream
std::stringstream d_stream;
};
+class CVC4ApiRecoverableExceptionStream
+{
+ public:
+ CVC4ApiRecoverableExceptionStream() {}
+ /* Note: This needs to be explicitly set to 'noexcept(false)' since it is
+ * a destructor that throws an exception and in C++11 all destructors
+ * default to noexcept(true) (else this triggers a call to std::terminate). */
+ ~CVC4ApiRecoverableExceptionStream() noexcept(false)
+ {
+ if (!std::uncaught_exception())
+ {
+ throw CVC4ApiRecoverableException(d_stream.str());
+ }
+ }
+
+ std::ostream& ostream() { return d_stream; }
+
+ private:
+ std::stringstream d_stream;
+};
+
#define CVC4_API_CHECK(cond) \
CVC4_PREDICT_TRUE(cond) \
? (void)0 : OstreamVoider() & CVC4ApiExceptionStream().ostream()
+#define CVC4_API_RECOVERABLE_CHECK(cond) \
+ CVC4_PREDICT_TRUE(cond) \
+ ? (void)0 : OstreamVoider() & CVC4ApiRecoverableExceptionStream().ostream()
+
#define CVC4_API_CHECK_NOT_NULL \
CVC4_API_CHECK(!isNullHelper()) \
<< "Invalid call to '" << __PRETTY_FUNCTION__ \
@@ -765,6 +842,10 @@ class CVC4ApiExceptionStream
{
#define CVC4_API_SOLVER_TRY_CATCH_END \
} \
+ catch (const CVC4::RecoverableModalException& e) \
+ { \
+ throw CVC4ApiRecoverableException(e.getMessage()); \
+ } \
catch (const CVC4::Exception& e) { throw CVC4ApiException(e.getMessage()); } \
catch (const std::invalid_argument& e) { throw CVC4ApiException(e.what()); }
@@ -865,13 +946,26 @@ std::ostream& operator<<(std::ostream& out, const Result& r)
/* -------------------------------------------------------------------------- */
Sort::Sort(const Solver* slv, const CVC4::Type& t)
- : d_solver(slv), d_type(new CVC4::Type(t))
+ : d_solver(slv), d_type(new CVC4::TypeNode(TypeNode::fromType(t)))
+{
+}
+Sort::Sort(const Solver* slv, const CVC4::TypeNode& t)
+ : d_solver(slv), d_type(new CVC4::TypeNode(t))
{
}
-Sort::Sort() : d_solver(nullptr), d_type(new CVC4::Type()) {}
+Sort::Sort() : d_solver(nullptr), d_type(new CVC4::TypeNode()) {}
-Sort::~Sort() {}
+Sort::~Sort()
+{
+ if (d_solver != nullptr)
+ {
+ // Ensure that the correct node manager is in scope when the node is
+ // destroyed.
+ NodeManagerScope scope(d_solver->getNodeManager());
+ d_type.reset();
+ }
+}
/* Helpers */
/* -------------------------------------------------------------------------- */
@@ -916,7 +1010,7 @@ bool Sort::isDatatype() const { return d_type->isDatatype(); }
bool Sort::isParametricDatatype() const
{
if (!d_type->isDatatype()) return false;
- return DatatypeType(*d_type).isParametric();
+ return d_type->isParametricDatatype();
}
bool Sort::isConstructor() const { return d_type->isConstructor(); }
@@ -935,6 +1029,8 @@ bool Sort::isArray() const { return d_type->isArray(); }
bool Sort::isSet() const { return d_type->isSet(); }
+bool Sort::isBag() const { return d_type->isBag(); }
+
bool Sort::isSequence() const { return d_type->isSequence(); }
bool Sort::isUninterpretedSort() const { return d_type->isSort(); }
@@ -954,52 +1050,91 @@ bool Sort::isComparableTo(Sort s) const
Datatype Sort::getDatatype() const
{
+ NodeManagerScope scope(d_solver->getNodeManager());
CVC4_API_CHECK(isDatatype()) << "Expected datatype sort.";
- return Datatype(d_solver, DatatypeType(*d_type).getDatatype());
+ return Datatype(d_solver, d_type->getDType());
}
Sort Sort::instantiate(const std::vector<Sort>& params) const
{
+ NodeManagerScope scope(d_solver->getNodeManager());
CVC4_API_CHECK(isParametricDatatype() || isSortConstructor())
<< "Expected parametric datatype or sort constructor sort.";
- std::vector<Type> tparams;
- for (const Sort& s : params)
- {
- tparams.push_back(*s.d_type.get());
- }
+ std::vector<CVC4::TypeNode> tparams = sortVectorToTypeNodes(params);
if (d_type->isDatatype())
{
- return Sort(d_solver, DatatypeType(*d_type).instantiate(tparams));
+ return Sort(d_solver, d_type->instantiateParametricDatatype(tparams));
}
Assert(d_type->isSortConstructor());
- return Sort(d_solver, SortConstructorType(*d_type).instantiate(tparams));
+ return Sort(d_solver, d_solver->getNodeManager()->mkSort(*d_type, tparams));
}
-std::string Sort::toString() const { return d_type->toString(); }
+std::string Sort::toString() const
+{
+ if (d_solver != nullptr)
+ {
+ NodeManagerScope scope(d_solver->getNodeManager());
+ return d_type->toString();
+ }
+ return d_type->toString();
+}
// !!! This is only temporarily available until the parser is fully migrated
// to the new API. !!!
-CVC4::Type Sort::getType(void) const { return *d_type; }
+CVC4::Type Sort::getType(void) const
+{
+ if (d_type->isNull()) return Type();
+ NodeManagerScope scope(d_solver->getNodeManager());
+ return d_type->toType();
+}
+const CVC4::TypeNode& Sort::getTypeNode(void) const { return *d_type; }
/* Constructor sort ------------------------------------------------------- */
size_t Sort::getConstructorArity() const
{
- CVC4_API_CHECK(isConstructor()) << "Not a function sort: " << (*this);
- return ConstructorType(*d_type).getArity();
+ CVC4_API_CHECK(isConstructor()) << "Not a constructor sort: " << (*this);
+ return d_type->getNumChildren() - 1;
}
std::vector<Sort> Sort::getConstructorDomainSorts() const
{
- CVC4_API_CHECK(isConstructor()) << "Not a function sort: " << (*this);
- std::vector<CVC4::Type> types = ConstructorType(*d_type).getArgTypes();
- return typeVectorToSorts(d_solver, types);
+ CVC4_API_CHECK(isConstructor()) << "Not a constructor sort: " << (*this);
+ return typeNodeVectorToSorts(d_solver, d_type->getArgTypes());
}
Sort Sort::getConstructorCodomainSort() const
{
- CVC4_API_CHECK(isConstructor()) << "Not a function sort: " << (*this);
- return Sort(d_solver, ConstructorType(*d_type).getRangeType());
+ CVC4_API_CHECK(isConstructor()) << "Not a constructor sort: " << (*this);
+ return Sort(d_solver, d_type->getConstructorRangeType());
+}
+
+/* Selector sort ------------------------------------------------------- */
+
+Sort Sort::getSelectorDomainSort() const
+{
+ CVC4_API_CHECK(isSelector()) << "Not a selector sort: " << (*this);
+ return Sort(d_solver, d_type->getSelectorDomainType());
+}
+
+Sort Sort::getSelectorCodomainSort() const
+{
+ CVC4_API_CHECK(isSelector()) << "Not a selector sort: " << (*this);
+ return Sort(d_solver, d_type->getSelectorRangeType());
+}
+
+/* Tester sort ------------------------------------------------------- */
+
+Sort Sort::getTesterDomainSort() const
+{
+ CVC4_API_CHECK(isTester()) << "Not a tester sort: " << (*this);
+ return Sort(d_solver, d_type->getTesterDomainType());
+}
+
+Sort Sort::getTesterCodomainSort() const
+{
+ CVC4_API_CHECK(isTester()) << "Not a tester sort: " << (*this);
+ return d_solver->getBooleanSort();
}
/* Function sort ------------------------------------------------------- */
@@ -1007,20 +1142,19 @@ Sort Sort::getConstructorCodomainSort() const
size_t Sort::getFunctionArity() const
{
CVC4_API_CHECK(isFunction()) << "Not a function sort: " << (*this);
- return FunctionType(*d_type).getArity();
+ return d_type->getNumChildren() - 1;
}
std::vector<Sort> Sort::getFunctionDomainSorts() const
{
CVC4_API_CHECK(isFunction()) << "Not a function sort: " << (*this);
- std::vector<CVC4::Type> types = FunctionType(*d_type).getArgTypes();
- return typeVectorToSorts(d_solver, types);
+ return typeNodeVectorToSorts(d_solver, d_type->getArgTypes());
}
Sort Sort::getFunctionCodomainSort() const
{
CVC4_API_CHECK(isFunction()) << "Not a function sort" << (*this);
- return Sort(d_solver, FunctionType(*d_type).getRangeType());
+ return Sort(d_solver, d_type->getRangeType());
}
/* Array sort ---------------------------------------------------------- */
@@ -1028,13 +1162,13 @@ Sort Sort::getFunctionCodomainSort() const
Sort Sort::getArrayIndexSort() const
{
CVC4_API_CHECK(isArray()) << "Not an array sort.";
- return Sort(d_solver, ArrayType(*d_type).getIndexType());
+ return Sort(d_solver, d_type->getArrayIndexType());
}
Sort Sort::getArrayElementSort() const
{
CVC4_API_CHECK(isArray()) << "Not an array sort.";
- return Sort(d_solver, ArrayType(*d_type).getConstituentType());
+ return Sort(d_solver, d_type->getArrayConstituentType());
}
/* Set sort ------------------------------------------------------------ */
@@ -1042,15 +1176,23 @@ Sort Sort::getArrayElementSort() const
Sort Sort::getSetElementSort() const
{
CVC4_API_CHECK(isSet()) << "Not a set sort.";
- return Sort(d_solver, SetType(*d_type).getElementType());
+ return Sort(d_solver, d_type->getSetElementType());
}
-/* Set sort ------------------------------------------------------------ */
+/* Bag sort ------------------------------------------------------------ */
+
+Sort Sort::getBagElementSort() const
+{
+ CVC4_API_CHECK(isBag()) << "Not a bag sort.";
+ return Sort(d_solver, d_type->getBagElementType());
+}
+
+/* Sequence sort ------------------------------------------------------- */
Sort Sort::getSequenceElementSort() const
{
CVC4_API_CHECK(isSequence()) << "Not a sequence sort.";
- return Sort(d_solver, SequenceType(*d_type).getElementType());
+ return Sort(d_solver, d_type->getSequenceElementType());
}
/* Uninterpreted sort -------------------------------------------------- */
@@ -1058,20 +1200,28 @@ Sort Sort::getSequenceElementSort() const
std::string Sort::getUninterpretedSortName() const
{
CVC4_API_CHECK(isUninterpretedSort()) << "Not an uninterpreted sort.";
- return SortType(*d_type).getName();
+ return d_type->getName();
}
bool Sort::isUninterpretedSortParameterized() const
{
CVC4_API_CHECK(isUninterpretedSort()) << "Not an uninterpreted sort.";
- return SortType(*d_type).isParameterized();
+ // This method is not implemented in the NodeManager, since whether a
+ // uninterpreted sort is parametrized is irrelevant for solving.
+ return d_type->getNumChildren() > 0;
}
std::vector<Sort> Sort::getUninterpretedSortParamSorts() const
{
CVC4_API_CHECK(isUninterpretedSort()) << "Not an uninterpreted sort.";
- std::vector<CVC4::Type> types = SortType(*d_type).getParamTypes();
- return typeVectorToSorts(d_solver, types);
+ // This method is not implemented in the NodeManager, since whether a
+ // uninterpreted sort is parametrized is irrelevant for solving.
+ std::vector<TypeNode> params;
+ for (size_t i = 0, nchildren = d_type->getNumChildren(); i < nchildren; i++)
+ {
+ params.push_back((*d_type)[i]);
+ }
+ return typeNodeVectorToSorts(d_solver, params);
}
/* Sort constructor sort ----------------------------------------------- */
@@ -1079,13 +1229,13 @@ std::vector<Sort> Sort::getUninterpretedSortParamSorts() const
std::string Sort::getSortConstructorName() const
{
CVC4_API_CHECK(isSortConstructor()) << "Not a sort constructor sort.";
- return SortConstructorType(*d_type).getName();
+ return d_type->getName();
}
size_t Sort::getSortConstructorArity() const
{
CVC4_API_CHECK(isSortConstructor()) << "Not a sort constructor sort.";
- return SortConstructorType(*d_type).getArity();
+ return d_type->getSortConstructorArity();
}
/* Bit-vector sort ----------------------------------------------------- */
@@ -1093,7 +1243,7 @@ size_t Sort::getSortConstructorArity() const
uint32_t Sort::getBVSize() const
{
CVC4_API_CHECK(isBitVector()) << "Not a bit-vector sort.";
- return BitVectorType(*d_type).getSize();
+ return d_type->getBitVectorSize();
}
/* Floating-point sort ------------------------------------------------- */
@@ -1101,13 +1251,13 @@ uint32_t Sort::getBVSize() const
uint32_t Sort::getFPExponentSize() const
{
CVC4_API_CHECK(isFloatingPoint()) << "Not a floating-point sort.";
- return FloatingPointType(*d_type).getExponentSize();
+ return d_type->getFloatingPointExponentSize();
}
uint32_t Sort::getFPSignificandSize() const
{
CVC4_API_CHECK(isFloatingPoint()) << "Not a floating-point sort.";
- return FloatingPointType(*d_type).getSignificandSize();
+ return d_type->getFloatingPointSignificandSize();
}
/* Datatype sort ------------------------------------------------------- */
@@ -1115,14 +1265,14 @@ uint32_t Sort::getFPSignificandSize() const
std::vector<Sort> Sort::getDatatypeParamSorts() const
{
CVC4_API_CHECK(isParametricDatatype()) << "Not a parametric datatype sort.";
- std::vector<CVC4::Type> types = DatatypeType(*d_type).getParamTypes();
- return typeVectorToSorts(d_solver, types);
+ std::vector<CVC4::TypeNode> typeNodes = d_type->getParamTypes();
+ return typeNodeVectorToSorts(d_solver, typeNodes);
}
size_t Sort::getDatatypeArity() const
{
CVC4_API_CHECK(isDatatype()) << "Not a datatype sort.";
- return DatatypeType(*d_type).getArity();
+ return d_type->getNumChildren() - 1;
}
/* Tuple sort ---------------------------------------------------------- */
@@ -1130,14 +1280,14 @@ size_t Sort::getDatatypeArity() const
size_t Sort::getTupleLength() const
{
CVC4_API_CHECK(isTuple()) << "Not a tuple sort.";
- return DatatypeType(*d_type).getTupleLength();
+ return d_type->getTupleLength();
}
std::vector<Sort> Sort::getTupleSorts() const
{
CVC4_API_CHECK(isTuple()) << "Not a tuple sort.";
- std::vector<CVC4::Type> types = DatatypeType(*d_type).getTupleTypes();
- return typeVectorToSorts(d_solver, types);
+ std::vector<CVC4::TypeNode> typeNodes = d_type->getTupleTypes();
+ return typeNodeVectorToSorts(d_solver, typeNodes);
}
/* --------------------------------------------------------------------- */
@@ -1150,26 +1300,40 @@ std::ostream& operator<<(std::ostream& out, const Sort& s)
size_t SortHashFunction::operator()(const Sort& s) const
{
- return TypeHashFunction()(*s.d_type);
+ return TypeNodeHashFunction()(*s.d_type);
}
/* -------------------------------------------------------------------------- */
/* Op */
/* -------------------------------------------------------------------------- */
-Op::Op() : d_solver(nullptr), d_kind(NULL_EXPR), d_expr(new CVC4::Expr()) {}
+Op::Op() : d_solver(nullptr), d_kind(NULL_EXPR), d_node(new CVC4::Node()) {}
Op::Op(const Solver* slv, const Kind k)
- : d_solver(slv), d_kind(k), d_expr(new CVC4::Expr())
+ : d_solver(slv), d_kind(k), d_node(new CVC4::Node())
{
}
Op::Op(const Solver* slv, const Kind k, const CVC4::Expr& e)
- : d_solver(slv), d_kind(k), d_expr(new CVC4::Expr(e))
+ : d_solver(slv), d_kind(k), d_node(new CVC4::Node(Node::fromExpr(e)))
{
}
-Op::~Op() {}
+Op::Op(const Solver* slv, const Kind k, const CVC4::Node& n)
+ : d_solver(slv), d_kind(k), d_node(new CVC4::Node(n))
+{
+}
+
+Op::~Op()
+{
+ if (d_solver != nullptr)
+ {
+ // Ensure that the correct node manager is in scope when the type node is
+ // destroyed.
+ NodeManagerScope scope(d_solver->getNodeManager());
+ d_node.reset();
+ }
+}
/* Helpers */
/* -------------------------------------------------------------------------- */
@@ -1179,23 +1343,23 @@ Op::~Op() {}
bool Op::isNullHelper() const
{
- return (d_expr->isNull() && (d_kind == NULL_EXPR));
+ return (d_node->isNull() && (d_kind == NULL_EXPR));
}
-bool Op::isIndexedHelper() const { return !d_expr->isNull(); }
+bool Op::isIndexedHelper() const { return !d_node->isNull(); }
/* Public methods */
bool Op::operator==(const Op& t) const
{
- if (d_expr->isNull() && t.d_expr->isNull())
+ if (d_node->isNull() && t.d_node->isNull())
{
return (d_kind == t.d_kind);
}
- else if (d_expr->isNull() || t.d_expr->isNull())
+ else if (d_node->isNull() || t.d_node->isNull())
{
return false;
}
- return (d_kind == t.d_kind) && (*d_expr == *t.d_expr);
+ return (d_kind == t.d_kind) && (*d_node == *t.d_node);
}
bool Op::operator!=(const Op& t) const { return !(*this == t); }
@@ -1214,22 +1378,22 @@ template <>
std::string Op::getIndices() const
{
CVC4_API_CHECK_NOT_NULL;
- CVC4_API_CHECK(!d_expr->isNull())
+ CVC4_API_CHECK(!d_node->isNull())
<< "Expecting a non-null internal expression. This Op is not indexed.";
std::string i;
- Kind k = intToExtKind(d_expr->getKind());
+ Kind k = intToExtKind(d_node->getKind());
if (k == DIVISIBLE)
{
// DIVISIBLE returns a string index to support
// arbitrary precision integers
- CVC4::Integer _int = d_expr->getConst<Divisible>().k;
+ CVC4::Integer _int = d_node->getConst<Divisible>().k;
i = _int.toString();
}
else if (k == RECORD_UPDATE)
{
- i = d_expr->getConst<RecordUpdate>().getField();
+ i = d_node->getConst<RecordUpdate>().getField();
}
else
{
@@ -1244,37 +1408,40 @@ template <>
uint32_t Op::getIndices() const
{
CVC4_API_CHECK_NOT_NULL;
- CVC4_API_CHECK(!d_expr->isNull())
+ CVC4_API_CHECK(!d_node->isNull())
<< "Expecting a non-null internal expression. This Op is not indexed.";
uint32_t i = 0;
- Kind k = intToExtKind(d_expr->getKind());
+ Kind k = intToExtKind(d_node->getKind());
switch (k)
{
case BITVECTOR_REPEAT:
- i = d_expr->getConst<BitVectorRepeat>().d_repeatAmount;
+ i = d_node->getConst<BitVectorRepeat>().d_repeatAmount;
break;
case BITVECTOR_ZERO_EXTEND:
- i = d_expr->getConst<BitVectorZeroExtend>().d_zeroExtendAmount;
+ i = d_node->getConst<BitVectorZeroExtend>().d_zeroExtendAmount;
break;
case BITVECTOR_SIGN_EXTEND:
- i = d_expr->getConst<BitVectorSignExtend>().d_signExtendAmount;
+ i = d_node->getConst<BitVectorSignExtend>().d_signExtendAmount;
break;
case BITVECTOR_ROTATE_LEFT:
- i = d_expr->getConst<BitVectorRotateLeft>().d_rotateLeftAmount;
+ i = d_node->getConst<BitVectorRotateLeft>().d_rotateLeftAmount;
break;
case BITVECTOR_ROTATE_RIGHT:
- i = d_expr->getConst<BitVectorRotateRight>().d_rotateRightAmount;
+ i = d_node->getConst<BitVectorRotateRight>().d_rotateRightAmount;
break;
- case INT_TO_BITVECTOR: i = d_expr->getConst<IntToBitVector>().d_size; break;
- case IAND: i = d_expr->getConst<IntAnd>().d_size; break;
+ case INT_TO_BITVECTOR: i = d_node->getConst<IntToBitVector>().d_size; break;
+ case IAND: i = d_node->getConst<IntAnd>().d_size; break;
case FLOATINGPOINT_TO_UBV:
- i = d_expr->getConst<FloatingPointToUBV>().bvs.d_size;
+ i = d_node->getConst<FloatingPointToUBV>().d_bv_size.d_size;
break;
case FLOATINGPOINT_TO_SBV:
- i = d_expr->getConst<FloatingPointToSBV>().bvs.d_size;
+ i = d_node->getConst<FloatingPointToSBV>().d_bv_size.d_size;
+ break;
+ case TUPLE_UPDATE: i = d_node->getConst<TupleUpdate>().getIndex(); break;
+ case REGEXP_REPEAT:
+ i = d_node->getConst<RegExpRepeat>().d_repeatAmount;
break;
- case TUPLE_UPDATE: i = d_expr->getConst<TupleUpdate>().getIndex(); break;
default:
CVC4ApiExceptionStream().ostream() << "Can't get uint32_t index from"
<< " kind " << kindToString(k);
@@ -1286,52 +1453,63 @@ template <>
std::pair<uint32_t, uint32_t> Op::getIndices() const
{
CVC4_API_CHECK_NOT_NULL;
- CVC4_API_CHECK(!d_expr->isNull())
+ CVC4_API_CHECK(!d_node->isNull())
<< "Expecting a non-null internal expression. This Op is not indexed.";
std::pair<uint32_t, uint32_t> indices;
- Kind k = intToExtKind(d_expr->getKind());
+ Kind k = intToExtKind(d_node->getKind());
// using if/else instead of case statement because want local variables
if (k == BITVECTOR_EXTRACT)
{
- CVC4::BitVectorExtract ext = d_expr->getConst<BitVectorExtract>();
+ CVC4::BitVectorExtract ext = d_node->getConst<BitVectorExtract>();
indices = std::make_pair(ext.d_high, ext.d_low);
}
else if (k == FLOATINGPOINT_TO_FP_IEEE_BITVECTOR)
{
CVC4::FloatingPointToFPIEEEBitVector ext =
- d_expr->getConst<FloatingPointToFPIEEEBitVector>();
- indices = std::make_pair(ext.t.exponent(), ext.t.significand());
+ d_node->getConst<FloatingPointToFPIEEEBitVector>();
+ indices = std::make_pair(ext.d_fp_size.exponentWidth(),
+ ext.d_fp_size.significandWidth());
}
else if (k == FLOATINGPOINT_TO_FP_FLOATINGPOINT)
{
CVC4::FloatingPointToFPFloatingPoint ext =
- d_expr->getConst<FloatingPointToFPFloatingPoint>();
- indices = std::make_pair(ext.t.exponent(), ext.t.significand());
+ d_node->getConst<FloatingPointToFPFloatingPoint>();
+ indices = std::make_pair(ext.d_fp_size.exponentWidth(),
+ ext.d_fp_size.significandWidth());
}
else if (k == FLOATINGPOINT_TO_FP_REAL)
{
- CVC4::FloatingPointToFPReal ext = d_expr->getConst<FloatingPointToFPReal>();
- indices = std::make_pair(ext.t.exponent(), ext.t.significand());
+ CVC4::FloatingPointToFPReal ext = d_node->getConst<FloatingPointToFPReal>();
+ indices = std::make_pair(ext.d_fp_size.exponentWidth(),
+ ext.d_fp_size.significandWidth());
}
else if (k == FLOATINGPOINT_TO_FP_SIGNED_BITVECTOR)
{
CVC4::FloatingPointToFPSignedBitVector ext =
- d_expr->getConst<FloatingPointToFPSignedBitVector>();
- indices = std::make_pair(ext.t.exponent(), ext.t.significand());
+ d_node->getConst<FloatingPointToFPSignedBitVector>();
+ indices = std::make_pair(ext.d_fp_size.exponentWidth(),
+ ext.d_fp_size.significandWidth());
}
else if (k == FLOATINGPOINT_TO_FP_UNSIGNED_BITVECTOR)
{
CVC4::FloatingPointToFPUnsignedBitVector ext =
- d_expr->getConst<FloatingPointToFPUnsignedBitVector>();
- indices = std::make_pair(ext.t.exponent(), ext.t.significand());
+ d_node->getConst<FloatingPointToFPUnsignedBitVector>();
+ indices = std::make_pair(ext.d_fp_size.exponentWidth(),
+ ext.d_fp_size.significandWidth());
}
else if (k == FLOATINGPOINT_TO_FP_GENERIC)
{
CVC4::FloatingPointToFPGeneric ext =
- d_expr->getConst<FloatingPointToFPGeneric>();
- indices = std::make_pair(ext.t.exponent(), ext.t.significand());
+ d_node->getConst<FloatingPointToFPGeneric>();
+ indices = std::make_pair(ext.d_fp_size.exponentWidth(),
+ ext.d_fp_size.significandWidth());
+ }
+ else if (k == REGEXP_LOOP)
+ {
+ CVC4::RegExpLoop ext = d_node->getConst<RegExpLoop>();
+ indices = std::make_pair(ext.d_loopMinOcc, ext.d_loopMaxOcc);
}
else
{
@@ -1344,21 +1522,31 @@ std::pair<uint32_t, uint32_t> Op::getIndices() const
std::string Op::toString() const
{
CVC4_API_CHECK_NOT_NULL;
- if (d_expr->isNull())
+ if (d_node->isNull())
{
return kindToString(d_kind);
}
else
{
- CVC4_API_CHECK(!d_expr->isNull())
+ CVC4_API_CHECK(!d_node->isNull())
<< "Expecting a non-null internal expression";
- return d_expr->toString();
+ if (d_solver != nullptr)
+ {
+ NodeManagerScope scope(d_solver->getNodeManager());
+ return d_node->toString();
+ }
+ return d_node->toString();
}
}
// !!! This is only temporarily available until the parser is fully migrated
// to the new API. !!!
-CVC4::Expr Op::getExpr(void) const { return *d_expr; }
+CVC4::Expr Op::getExpr(void) const
+{
+ if (d_node->isNull()) return Expr();
+ NodeManagerScope scope(d_solver->getNodeManager());
+ return d_node->toExpr();
+}
std::ostream& operator<<(std::ostream& out, const Op& t)
{
@@ -1370,7 +1558,7 @@ size_t OpHashFunction::operator()(const Op& t) const
{
if (t.isIndexedHelper())
{
- return ExprHashFunction()(*t.d_expr);
+ return ExprHashFunction()(t.d_node->toExpr());
}
else
{
@@ -1382,19 +1570,37 @@ size_t OpHashFunction::operator()(const Op& t) const
/* Term */
/* -------------------------------------------------------------------------- */
-Term::Term() : d_solver(nullptr), d_expr(new CVC4::Expr()) {}
+Term::Term() : d_solver(nullptr), d_node(new CVC4::Node()) {}
-Term::Term(const Solver* slv, const CVC4::Expr& e)
- : d_solver(slv), d_expr(new CVC4::Expr(e))
+Term::Term(const Solver* slv, const CVC4::Expr& e) : d_solver(slv)
{
+ // Ensure that we create the node in the correct node manager.
+ NodeManagerScope scope(d_solver->getNodeManager());
+ d_node.reset(new CVC4::Node(e));
}
-Term::~Term() {}
+Term::Term(const Solver* slv, const CVC4::Node& n) : d_solver(slv)
+{
+ // Ensure that we create the node in the correct node manager.
+ NodeManagerScope scope(d_solver->getNodeManager());
+ d_node.reset(new CVC4::Node(n));
+}
+
+Term::~Term()
+{
+ if (d_solver != nullptr)
+ {
+ // Ensure that the correct node manager is in scope when the node is
+ // destroyed.
+ NodeManagerScope scope(d_solver->getNodeManager());
+ d_node.reset();
+ }
+}
bool Term::isNullHelper() const
{
/* Split out to avoid nested API calls (problematic with API tracing). */
- return d_expr->isNull();
+ return d_node->isNull();
}
Kind Term::getKindHelper() const
@@ -1403,9 +1609,9 @@ Kind Term::getKindHelper() const
// (string) versions back to sequence. All operators where this is
// necessary are such that their first child is of sequence type, which
// we check here.
- if (getNumChildren() > 0 && (*this)[0].getSort().isSequence())
+ if (d_node->getNumChildren() > 0 && (*d_node)[0].getType().isSequence())
{
- switch (d_expr->getKind())
+ switch (d_node->getKind())
{
case CVC4::Kind::STRING_CONCAT: return SEQ_CONCAT;
case CVC4::Kind::STRING_LENGTH: return SEQ_LENGTH;
@@ -1424,56 +1630,78 @@ Kind Term::getKindHelper() const
break;
}
}
+ // Notice that kinds like APPLY_TYPE_ASCRIPTION will be converted to
+ // INTERNAL_KIND.
+ if(isCastedReal())
+ {
+ return CONST_RATIONAL;
+ }
+ return intToExtKind(d_node->getKind());
+}
- return intToExtKind(d_expr->getKind());
+bool Term::isCastedReal() const
+{
+ if(d_node->getKind() == kind::CAST_TO_REAL)
+ {
+ return (*d_node)[0].isConst() && (*d_node)[0].getType().isInteger();
+ }
+ return false;
}
-bool Term::operator==(const Term& t) const { return *d_expr == *t.d_expr; }
+bool Term::operator==(const Term& t) const { return *d_node == *t.d_node; }
-bool Term::operator!=(const Term& t) const { return *d_expr != *t.d_expr; }
+bool Term::operator!=(const Term& t) const { return *d_node != *t.d_node; }
-bool Term::operator<(const Term& t) const { return *d_expr < *t.d_expr; }
+bool Term::operator<(const Term& t) const { return *d_node < *t.d_node; }
-bool Term::operator>(const Term& t) const { return *d_expr > *t.d_expr; }
+bool Term::operator>(const Term& t) const { return *d_node > *t.d_node; }
-bool Term::operator<=(const Term& t) const { return *d_expr <= *t.d_expr; }
+bool Term::operator<=(const Term& t) const { return *d_node <= *t.d_node; }
-bool Term::operator>=(const Term& t) const { return *d_expr >= *t.d_expr; }
+bool Term::operator>=(const Term& t) const { return *d_node >= *t.d_node; }
size_t Term::getNumChildren() const
{
CVC4_API_CHECK_NOT_NULL;
// special case for apply kinds
- if (isApplyKind(d_expr->getKind()))
+ if (isApplyKind(d_node->getKind()))
+ {
+ return d_node->getNumChildren() + 1;
+ }
+ if(isCastedReal())
{
- return d_expr->getNumChildren() + 1;
+ return 0;
}
- return d_expr->getNumChildren();
+ return d_node->getNumChildren();
}
Term Term::operator[](size_t index) const
{
CVC4_API_CHECK_NOT_NULL;
+
+ // check the index within the number of children
+ CVC4_API_CHECK(index < getNumChildren()) << "index out of bound";
+
// special cases for apply kinds
- if (isApplyKind(d_expr->getKind()))
+ if (isApplyKind(d_node->getKind()))
{
- CVC4_API_CHECK(d_expr->hasOperator())
+ CVC4_API_CHECK(d_node->hasOperator())
<< "Expected apply kind to have operator when accessing child of Term";
if (index == 0)
{
// return the operator
- return Term(d_solver, d_expr->getOperator());
+ return Term(d_solver, d_node->getOperator().toExpr());
}
// otherwise we are looking up child at (index-1)
index--;
}
- return Term(d_solver, (*d_expr)[index]);
+ return Term(d_solver, (*d_node)[index].toExpr());
}
uint64_t Term::getId() const
{
CVC4_API_CHECK_NOT_NULL;
- return d_expr->getId();
+ return d_node->getId();
}
Kind Term::getKind() const
@@ -1485,7 +1713,8 @@ Kind Term::getKind() const
Sort Term::getSort() const
{
CVC4_API_CHECK_NOT_NULL;
- return Sort(d_solver, d_expr->getType());
+ NodeManagerScope scope(d_solver->getNodeManager());
+ return Sort(d_solver, d_node->getType());
}
Term Term::substitute(Term e, Term replacement) const
@@ -1497,7 +1726,8 @@ Term Term::substitute(Term e, Term replacement) const
<< "Expected non-null term as replacement in substitute";
CVC4_API_CHECK(e.getSort().isComparableTo(replacement.getSort()))
<< "Expecting terms of comparable sort in substitute";
- return Term(d_solver, d_expr->substitute(e.getExpr(), replacement.getExpr()));
+ return Term(d_solver,
+ d_node->substitute(TNode(*e.d_node), TNode(*replacement.d_node)));
}
Term Term::substitute(const std::vector<Term> es,
@@ -1515,21 +1745,26 @@ Term Term::substitute(const std::vector<Term> es,
CVC4_API_CHECK(es[i].getSort().isComparableTo(replacements[i].getSort()))
<< "Expecting terms of comparable sort in substitute";
}
+
+ std::vector<Node> nodes = termVectorToNodes(es);
+ std::vector<Node> nodeReplacements = termVectorToNodes(replacements);
return Term(d_solver,
- d_expr->substitute(termVectorToExprs(es),
- termVectorToExprs(replacements)));
+ d_node->substitute(nodes.begin(),
+ nodes.end(),
+ nodeReplacements.begin(),
+ nodeReplacements.end()));
}
bool Term::hasOp() const
{
CVC4_API_CHECK_NOT_NULL;
- return d_expr->hasOperator();
+ return d_node->hasOperator();
}
Op Term::getOp() const
{
CVC4_API_CHECK_NOT_NULL;
- CVC4_API_CHECK(d_expr->hasOperator())
+ CVC4_API_CHECK(d_node->hasOperator())
<< "Expecting Term to have an Op when calling getOp()";
// special cases for parameterized operators that are not indexed operators
@@ -1537,51 +1772,45 @@ Op Term::getOp() const
// indexed operators are stored in Ops
// whereas functions and datatype operators are terms, and the Op
// is one of the APPLY_* kinds
- if (isApplyKind(d_expr->getKind()))
+ if (isApplyKind(d_node->getKind()))
{
- return Op(d_solver, intToExtKind(d_expr->getKind()));
+ return Op(d_solver, intToExtKind(d_node->getKind()));
}
- else if (d_expr->isParameterized())
+ else if (d_node->getMetaKind() == kind::metakind::PARAMETERIZED)
{
// it's an indexed operator
// so we should return the indexed op
- CVC4::Expr op = d_expr->getOperator();
- return Op(d_solver, intToExtKind(d_expr->getKind()), op);
+ CVC4::Node op = d_node->getOperator();
+ return Op(d_solver, intToExtKind(d_node->getKind()), op);
}
// Notice this is the only case where getKindHelper is used, since the
- // cases above do have special cases for intToExtKind.
+ // cases above do not have special cases for intToExtKind.
return Op(d_solver, getKindHelper());
}
bool Term::isNull() const { return isNullHelper(); }
-bool Term::isConst() const
-{
- CVC4_API_CHECK_NOT_NULL;
- return d_expr->isConst();
-}
-
Term Term::getConstArrayBase() const
{
CVC4::ExprManagerScope exmgrs(*(d_solver->getExprManager()));
CVC4_API_CHECK_NOT_NULL;
// CONST_ARRAY kind maps to STORE_ALL internal kind
- CVC4_API_CHECK(d_expr->getKind() == CVC4::Kind::STORE_ALL)
+ CVC4_API_CHECK(d_node->getKind() == CVC4::Kind::STORE_ALL)
<< "Expecting a CONST_ARRAY Term when calling getConstArrayBase()";
- return Term(d_solver, d_expr->getConst<ArrayStoreAll>().getValue().toExpr());
+ return Term(d_solver, d_node->getConst<ArrayStoreAll>().getValue());
}
std::vector<Term> Term::getConstSequenceElements() const
{
CVC4_API_CHECK_NOT_NULL;
- CVC4_API_CHECK(d_expr->getKind() == CVC4::Kind::CONST_SEQUENCE)
+ CVC4_API_CHECK(d_node->getKind() == CVC4::Kind::CONST_SEQUENCE)
<< "Expecting a CONST_SEQUENCE Term when calling "
"getConstSequenceElements()";
- const std::vector<Node>& elems = d_expr->getConst<Sequence>().getVec();
+ const std::vector<Node>& elems = d_node->getConst<Sequence>().getVec();
std::vector<Term> terms;
for (const Node& t : elems)
{
- terms.push_back(Term(d_solver, t.toExpr()));
+ terms.push_back(Term(d_solver, t));
}
return terms;
}
@@ -1591,11 +1820,11 @@ Term Term::notTerm() const
CVC4_API_CHECK_NOT_NULL;
try
{
- Expr res = d_expr->notExpr();
+ Node res = d_node->notNode();
(void)res.getType(true); /* kick off type checking */
return Term(d_solver, res);
}
- catch (const CVC4::TypeCheckingException& e)
+ catch (const CVC4::TypeCheckingExceptionPrivate& e)
{
throw CVC4ApiException(e.getMessage());
}
@@ -1607,11 +1836,11 @@ Term Term::andTerm(const Term& t) const
CVC4_API_ARG_CHECK_NOT_NULL(t);
try
{
- Expr res = d_expr->andExpr(*t.d_expr);
+ Node res = d_node->andNode(*t.d_node);
(void)res.getType(true); /* kick off type checking */
return Term(d_solver, res);
}
- catch (const CVC4::TypeCheckingException& e)
+ catch (const CVC4::TypeCheckingExceptionPrivate& e)
{
throw CVC4ApiException(e.getMessage());
}
@@ -1623,11 +1852,11 @@ Term Term::orTerm(const Term& t) const
CVC4_API_ARG_CHECK_NOT_NULL(t);
try
{
- Expr res = d_expr->orExpr(*t.d_expr);
+ Node res = d_node->orNode(*t.d_node);
(void)res.getType(true); /* kick off type checking */
return Term(d_solver, res);
}
- catch (const CVC4::TypeCheckingException& e)
+ catch (const CVC4::TypeCheckingExceptionPrivate& e)
{
throw CVC4ApiException(e.getMessage());
}
@@ -1639,11 +1868,11 @@ Term Term::xorTerm(const Term& t) const
CVC4_API_ARG_CHECK_NOT_NULL(t);
try
{
- Expr res = d_expr->xorExpr(*t.d_expr);
+ Node res = d_node->xorNode(*t.d_node);
(void)res.getType(true); /* kick off type checking */
return Term(d_solver, res);
}
- catch (const CVC4::TypeCheckingException& e)
+ catch (const CVC4::TypeCheckingExceptionPrivate& e)
{
throw CVC4ApiException(e.getMessage());
}
@@ -1655,11 +1884,11 @@ Term Term::eqTerm(const Term& t) const
CVC4_API_ARG_CHECK_NOT_NULL(t);
try
{
- Expr res = d_expr->eqExpr(*t.d_expr);
+ Node res = d_node->eqNode(*t.d_node);
(void)res.getType(true); /* kick off type checking */
return Term(d_solver, res);
}
- catch (const CVC4::TypeCheckingException& e)
+ catch (const CVC4::TypeCheckingExceptionPrivate& e)
{
throw CVC4ApiException(e.getMessage());
}
@@ -1671,11 +1900,11 @@ Term Term::impTerm(const Term& t) const
CVC4_API_ARG_CHECK_NOT_NULL(t);
try
{
- Expr res = d_expr->impExpr(*t.d_expr);
+ Node res = d_node->impNode(*t.d_node);
(void)res.getType(true); /* kick off type checking */
return Term(d_solver, res);
}
- catch (const CVC4::TypeCheckingException& e)
+ catch (const CVC4::TypeCheckingExceptionPrivate& e)
{
throw CVC4ApiException(e.getMessage());
}
@@ -1688,37 +1917,45 @@ Term Term::iteTerm(const Term& then_t, const Term& else_t) const
CVC4_API_ARG_CHECK_NOT_NULL(else_t);
try
{
- Expr res = d_expr->iteExpr(*then_t.d_expr, *else_t.d_expr);
+ Node res = d_node->iteNode(*then_t.d_node, *else_t.d_node);
(void)res.getType(true); /* kick off type checking */
return Term(d_solver, res);
}
- catch (const CVC4::TypeCheckingException& e)
+ catch (const CVC4::TypeCheckingExceptionPrivate& e)
{
throw CVC4ApiException(e.getMessage());
}
}
-std::string Term::toString() const { return d_expr->toString(); }
+std::string Term::toString() const
+{
+ if (d_solver != nullptr)
+ {
+ NodeManagerScope scope(d_solver->getNodeManager());
+ return d_node->toString();
+ }
+ return d_node->toString();
+}
Term::const_iterator::const_iterator()
- : d_solver(nullptr), d_orig_expr(nullptr), d_pos(0)
+ : d_solver(nullptr), d_origNode(nullptr), d_pos(0)
{
}
Term::const_iterator::const_iterator(const Solver* slv,
- const std::shared_ptr<CVC4::Expr>& e,
+ const std::shared_ptr<CVC4::Node>& n,
uint32_t p)
- : d_solver(slv), d_orig_expr(e), d_pos(p)
+ : d_solver(slv), d_origNode(n), d_pos(p)
{
}
Term::const_iterator::const_iterator(const const_iterator& it)
- : d_solver(nullptr), d_orig_expr(nullptr)
+ : d_solver(nullptr), d_origNode(nullptr)
{
- if (it.d_orig_expr != nullptr)
+ if (it.d_origNode != nullptr)
{
d_solver = it.d_solver;
- d_orig_expr = it.d_orig_expr;
+ d_origNode = it.d_origNode;
d_pos = it.d_pos;
}
}
@@ -1726,18 +1963,18 @@ Term::const_iterator::const_iterator(const const_iterator& it)
Term::const_iterator& Term::const_iterator::operator=(const const_iterator& it)
{
d_solver = it.d_solver;
- d_orig_expr = it.d_orig_expr;
+ d_origNode = it.d_origNode;
d_pos = it.d_pos;
return *this;
}
bool Term::const_iterator::operator==(const const_iterator& it) const
{
- if (d_orig_expr == nullptr || it.d_orig_expr == nullptr)
+ if (d_origNode == nullptr || it.d_origNode == nullptr)
{
return false;
}
- return (d_solver == it.d_solver && *d_orig_expr == *it.d_orig_expr)
+ return (d_solver == it.d_solver && *d_origNode == *it.d_origNode)
&& (d_pos == it.d_pos);
}
@@ -1748,14 +1985,14 @@ bool Term::const_iterator::operator!=(const const_iterator& it) const
Term::const_iterator& Term::const_iterator::operator++()
{
- Assert(d_orig_expr != nullptr);
+ Assert(d_origNode != nullptr);
++d_pos;
return *this;
}
Term::const_iterator Term::const_iterator::operator++(int)
{
- Assert(d_orig_expr != nullptr);
+ Assert(d_origNode != nullptr);
const_iterator it = *this;
++d_pos;
return it;
@@ -1763,14 +2000,14 @@ Term::const_iterator Term::const_iterator::operator++(int)
Term Term::const_iterator::operator*() const
{
- Assert(d_orig_expr != nullptr);
+ Assert(d_origNode != nullptr);
// this term has an extra child (mismatch between API and internal structure)
// the extra child will be the first child
- bool extra_child = isApplyKind(d_orig_expr->getKind());
+ bool extra_child = isApplyKind(d_origNode->getKind());
if (!d_pos && extra_child)
{
- return Term(d_solver, d_orig_expr->getOperator());
+ return Term(d_solver, d_origNode->getOperator());
}
else
{
@@ -1781,35 +2018,47 @@ Term Term::const_iterator::operator*() const
--idx;
}
Assert(idx >= 0);
- return Term(d_solver, (*d_orig_expr)[idx]);
+ return Term(d_solver, (*d_origNode)[idx]);
}
}
Term::const_iterator Term::begin() const
{
- return Term::const_iterator(d_solver, d_expr, 0);
+ return Term::const_iterator(d_solver, d_node, 0);
}
Term::const_iterator Term::end() const
{
- int endpos = d_expr->getNumChildren();
+ int endpos = d_node->getNumChildren();
// special cases for APPLY_*
// the API differs from the internal structure
// the API takes a "higher-order" perspective and the applied
// function or datatype constructor/selector/tester is a Term
// which means it needs to be one of the children, even though
// internally it is not
- if (isApplyKind(d_expr->getKind()))
+ if (isApplyKind(d_node->getKind()))
{
// one more child if this is a UF application (count the UF as a child)
++endpos;
}
- return Term::const_iterator(d_solver, d_expr, endpos);
+ return Term::const_iterator(d_solver, d_node, endpos);
+}
+
+// !!! This is only temporarily available until the parser is fully migrated
+// to the new API. !!!
+CVC4::Expr Term::getExpr(void) const
+{
+ if (d_node->isNull())
+ {
+ return Expr();
+ }
+ NodeManagerScope scope(d_solver->getNodeManager());
+ return d_node->toExpr();
}
// !!! This is only temporarily available until the parser is fully migrated
// to the new API. !!!
-CVC4::Expr Term::getExpr(void) const { return *d_expr; }
+const CVC4::Node& Term::getNode(void) const { return *d_node; }
std::ostream& operator<<(std::ostream& out, const Term& t)
{
@@ -1855,7 +2104,7 @@ std::ostream& operator<<(
size_t TermHashFunction::operator()(const Term& t) const
{
- return ExprHashFunction()(*t.d_expr);
+ return NodeHashFunction()(*t.d_node);
}
/* -------------------------------------------------------------------------- */
@@ -1871,12 +2120,22 @@ DatatypeConstructorDecl::DatatypeConstructorDecl()
DatatypeConstructorDecl::DatatypeConstructorDecl(const Solver* slv,
const std::string& name)
- : d_solver(slv), d_ctor(new CVC4::DatatypeConstructor(name))
+ : d_solver(slv), d_ctor(new CVC4::DTypeConstructor(name))
{
}
+DatatypeConstructorDecl::~DatatypeConstructorDecl()
+{
+ if (d_ctor != nullptr)
+ {
+ // ensure proper node manager is in scope
+ NodeManagerScope scope(d_solver->getNodeManager());
+ d_ctor.reset();
+ }
+}
void DatatypeConstructorDecl::addSelector(const std::string& name, Sort sort)
{
+ NodeManagerScope scope(d_solver->getNodeManager());
CVC4_API_ARG_CHECK_EXPECTED(!sort.isNull(), sort)
<< "non-null range sort for selector";
d_ctor->addArg(name, *sort.d_type);
@@ -1884,7 +2143,8 @@ void DatatypeConstructorDecl::addSelector(const std::string& name, Sort sort)
void DatatypeConstructorDecl::addSelectorSelf(const std::string& name)
{
- d_ctor->addArg(name, DatatypeSelfType());
+ NodeManagerScope scope(d_solver->getNodeManager());
+ d_ctor->addArgSelf(name);
}
std::string DatatypeConstructorDecl::toString() const
@@ -1896,8 +2156,8 @@ std::string DatatypeConstructorDecl::toString() const
// !!! This is only temporarily available until the parser is fully migrated
// to the new API. !!!
-const CVC4::DatatypeConstructor&
-DatatypeConstructorDecl::getDatatypeConstructor(void) const
+const CVC4::DTypeConstructor& DatatypeConstructorDecl::getDatatypeConstructor(
+ void) const
{
return *d_ctor;
}
@@ -1923,8 +2183,7 @@ DatatypeDecl::DatatypeDecl() : d_solver(nullptr), d_dtype(nullptr) {}
DatatypeDecl::DatatypeDecl(const Solver* slv,
const std::string& name,
bool isCoDatatype)
- : d_solver(slv),
- d_dtype(new CVC4::Datatype(slv->getExprManager(), name, isCoDatatype))
+ : d_solver(slv), d_dtype(new CVC4::DType(name, isCoDatatype))
{
}
@@ -1933,10 +2192,8 @@ DatatypeDecl::DatatypeDecl(const Solver* slv,
Sort param,
bool isCoDatatype)
: d_solver(slv),
- d_dtype(new CVC4::Datatype(slv->getExprManager(),
- name,
- std::vector<Type>{*param.d_type},
- isCoDatatype))
+ d_dtype(new CVC4::DType(
+ name, std::vector<TypeNode>{*param.d_type}, isCoDatatype))
{
}
@@ -1946,23 +2203,28 @@ DatatypeDecl::DatatypeDecl(const Solver* slv,
bool isCoDatatype)
: d_solver(slv)
{
- std::vector<Type> tparams;
- for (const Sort& p : params)
- {
- tparams.push_back(*p.d_type);
- }
- d_dtype = std::shared_ptr<CVC4::Datatype>(
- new CVC4::Datatype(slv->getExprManager(), name, tparams, isCoDatatype));
+ std::vector<TypeNode> tparams = sortVectorToTypeNodes(params);
+ d_dtype = std::shared_ptr<CVC4::DType>(
+ new CVC4::DType(name, tparams, isCoDatatype));
}
bool DatatypeDecl::isNullHelper() const { return !d_dtype; }
-DatatypeDecl::~DatatypeDecl() {}
+DatatypeDecl::~DatatypeDecl()
+{
+ if (d_dtype != nullptr)
+ {
+ // ensure proper node manager is in scope
+ NodeManagerScope scope(d_solver->getNodeManager());
+ d_dtype.reset();
+ }
+}
void DatatypeDecl::addConstructor(const DatatypeConstructorDecl& ctor)
{
+ NodeManagerScope scope(d_solver->getNodeManager());
CVC4_API_CHECK_NOT_NULL;
- d_dtype->addConstructor(*ctor.d_ctor);
+ d_dtype->addConstructor(ctor.d_ctor);
}
size_t DatatypeDecl::getNumConstructors() const
@@ -1995,7 +2257,7 @@ bool DatatypeDecl::isNull() const { return isNullHelper(); }
// !!! This is only temporarily available until the parser is fully migrated
// to the new API. !!!
-CVC4::Datatype& DatatypeDecl::getDatatype(void) const { return *d_dtype; }
+CVC4::DType& DatatypeDecl::getDatatype(void) const { return *d_dtype; }
std::ostream& operator<<(std::ostream& out, const DatatypeDecl& dtdecl)
{
@@ -2008,13 +2270,21 @@ std::ostream& operator<<(std::ostream& out, const DatatypeDecl& dtdecl)
DatatypeSelector::DatatypeSelector() : d_solver(nullptr), d_stor(nullptr) {}
DatatypeSelector::DatatypeSelector(const Solver* slv,
- const CVC4::DatatypeConstructorArg& stor)
- : d_solver(slv), d_stor(new CVC4::DatatypeConstructorArg(stor))
+ const CVC4::DTypeSelector& stor)
+ : d_solver(slv), d_stor(new CVC4::DTypeSelector(stor))
{
CVC4_API_CHECK(d_stor->isResolved()) << "Expected resolved datatype selector";
}
-DatatypeSelector::~DatatypeSelector() {}
+DatatypeSelector::~DatatypeSelector()
+{
+ if (d_stor != nullptr)
+ {
+ // ensure proper node manager is in scope
+ NodeManagerScope scope(d_solver->getNodeManager());
+ d_stor.reset();
+ }
+}
std::string DatatypeSelector::getName() const { return d_stor->getName(); }
@@ -2038,8 +2308,7 @@ std::string DatatypeSelector::toString() const
// !!! This is only temporarily available until the parser is fully migrated
// to the new API. !!!
-CVC4::DatatypeConstructorArg DatatypeSelector::getDatatypeConstructorArg(
- void) const
+CVC4::DTypeSelector DatatypeSelector::getDatatypeConstructorArg(void) const
{
return *d_stor;
}
@@ -2057,14 +2326,22 @@ DatatypeConstructor::DatatypeConstructor() : d_solver(nullptr), d_ctor(nullptr)
}
DatatypeConstructor::DatatypeConstructor(const Solver* slv,
- const CVC4::DatatypeConstructor& ctor)
- : d_solver(slv), d_ctor(new CVC4::DatatypeConstructor(ctor))
+ const CVC4::DTypeConstructor& ctor)
+ : d_solver(slv), d_ctor(new CVC4::DTypeConstructor(ctor))
{
CVC4_API_CHECK(d_ctor->isResolved())
<< "Expected resolved datatype constructor";
}
-DatatypeConstructor::~DatatypeConstructor() {}
+DatatypeConstructor::~DatatypeConstructor()
+{
+ if (d_ctor != nullptr)
+ {
+ // ensure proper node manager is in scope
+ NodeManagerScope scope(d_solver->getNodeManager());
+ d_ctor.reset();
+ }
+}
std::string DatatypeConstructor::getName() const { return d_ctor->getName(); }
@@ -2074,6 +2351,30 @@ Term DatatypeConstructor::getConstructorTerm() const
return ctor;
}
+Term DatatypeConstructor::getSpecializedConstructorTerm(Sort retSort) const
+{
+ NodeManagerScope scope(d_solver->getNodeManager());
+ CVC4_API_CHECK(d_ctor->isResolved())
+ << "Expected resolved datatype constructor";
+ CVC4_API_CHECK(retSort.isDatatype())
+ << "Cannot get specialized constructor type for non-datatype type "
+ << retSort;
+ CVC4_API_SOLVER_TRY_CATCH_BEGIN;
+
+ NodeManager* nm = d_solver->getNodeManager();
+ Node ret =
+ nm->mkNode(kind::APPLY_TYPE_ASCRIPTION,
+ nm->mkConst(AscriptionType(
+ d_ctor->getSpecializedConstructorType(*retSort.d_type))),
+ d_ctor->getConstructor());
+ (void)ret.getType(true); /* kick off type checking */
+ // apply type ascription to the operator
+ Term sctor = api::Term(d_solver, ret);
+ return sctor;
+
+ CVC4_API_SOLVER_TRY_CATCH_END;
+}
+
Term DatatypeConstructor::getTesterTerm() const
{
Term tst = Term(d_solver, d_ctor->getTester());
@@ -2117,20 +2418,19 @@ DatatypeConstructor::const_iterator DatatypeConstructor::end() const
}
DatatypeConstructor::const_iterator::const_iterator(
- const Solver* slv, const CVC4::DatatypeConstructor& ctor, bool begin)
+ const Solver* slv, const CVC4::DTypeConstructor& ctor, bool begin)
{
d_solver = slv;
- d_int_stors = ctor.getArgs();
+ d_int_stors = &ctor.getArgs();
- const std::vector<CVC4::DatatypeConstructorArg>* sels =
- static_cast<const std::vector<CVC4::DatatypeConstructorArg>*>(
- d_int_stors);
- for (const auto& s : *sels)
+ const std::vector<std::shared_ptr<CVC4::DTypeSelector>>& sels =
+ ctor.getArgs();
+ for (const std::shared_ptr<CVC4::DTypeSelector>& s : sels)
{
/* Can not use emplace_back here since constructor is private. */
- d_stors.push_back(DatatypeSelector(d_solver, s));
+ d_stors.push_back(DatatypeSelector(d_solver, *s.get()));
}
- d_idx = begin ? 0 : sels->size();
+ d_idx = begin ? 0 : sels.size();
}
DatatypeConstructor::const_iterator::const_iterator()
@@ -2195,7 +2495,7 @@ std::string DatatypeConstructor::toString() const
// !!! This is only temporarily available until the parser is fully migrated
// to the new API. !!!
-const CVC4::DatatypeConstructor& DatatypeConstructor::getDatatypeConstructor(
+const CVC4::DTypeConstructor& DatatypeConstructor::getDatatypeConstructor(
void) const
{
return *d_ctor;
@@ -2215,8 +2515,18 @@ DatatypeSelector DatatypeConstructor::getSelectorForName(
break;
}
}
- CVC4_API_CHECK(foundSel) << "No selector " << name << " for constructor "
- << getName() << " exists";
+ if (!foundSel)
+ {
+ std::stringstream snames;
+ snames << "{ ";
+ for (size_t i = 0, ncons = getNumSelectors(); i < ncons; i++)
+ {
+ snames << (*d_ctor)[i].getName() << " ";
+ }
+ snames << "} ";
+ CVC4_API_CHECK(foundSel) << "No selector " << name << " for constructor "
+ << getName() << " exists among " << snames.str();
+ }
return DatatypeSelector(d_solver, (*d_ctor)[index]);
}
@@ -2228,15 +2538,23 @@ std::ostream& operator<<(std::ostream& out, const DatatypeConstructor& ctor)
/* Datatype ----------------------------------------------------------------- */
-Datatype::Datatype(const Solver* slv, const CVC4::Datatype& dtype)
- : d_solver(slv), d_dtype(new CVC4::Datatype(dtype))
+Datatype::Datatype(const Solver* slv, const CVC4::DType& dtype)
+ : d_solver(slv), d_dtype(new CVC4::DType(dtype))
{
CVC4_API_CHECK(d_dtype->isResolved()) << "Expected resolved datatype";
}
Datatype::Datatype() : d_solver(nullptr), d_dtype(nullptr) {}
-Datatype::~Datatype() {}
+Datatype::~Datatype()
+{
+ if (d_dtype != nullptr)
+ {
+ // ensure proper node manager is in scope
+ NodeManagerScope scope(d_solver->getNodeManager());
+ d_dtype.reset();
+ }
+}
DatatypeConstructor Datatype::operator[](size_t idx) const
{
@@ -2295,7 +2613,7 @@ Datatype::const_iterator Datatype::end() const
// !!! This is only temporarily available until the parser is fully migrated
// to the new API. !!!
-const CVC4::Datatype& Datatype::getDatatype(void) const { return *d_dtype; }
+const CVC4::DType& Datatype::getDatatype(void) const { return *d_dtype; }
DatatypeConstructor Datatype::getConstructorForName(
const std::string& name) const
@@ -2311,24 +2629,34 @@ DatatypeConstructor Datatype::getConstructorForName(
break;
}
}
- CVC4_API_CHECK(foundCons) << "No constructor " << name << " for datatype "
- << getName() << " exists";
+ if (!foundCons)
+ {
+ std::stringstream snames;
+ snames << "{ ";
+ for (size_t i = 0, ncons = getNumConstructors(); i < ncons; i++)
+ {
+ snames << (*d_dtype)[i].getName() << " ";
+ }
+ snames << "}";
+ CVC4_API_CHECK(foundCons) << "No constructor " << name << " for datatype "
+ << getName() << " exists, among " << snames.str();
+ }
return DatatypeConstructor(d_solver, (*d_dtype)[index]);
}
Datatype::const_iterator::const_iterator(const Solver* slv,
- const CVC4::Datatype& dtype,
+ const CVC4::DType& dtype,
bool begin)
- : d_solver(slv), d_int_ctors(dtype.getConstructors())
+ : d_solver(slv), d_int_ctors(&dtype.getConstructors())
{
- const std::vector<CVC4::DatatypeConstructor>* cons =
- static_cast<const std::vector<CVC4::DatatypeConstructor>*>(d_int_ctors);
- for (const auto& c : *cons)
+ const std::vector<std::shared_ptr<DTypeConstructor>>& cons =
+ dtype.getConstructors();
+ for (const std::shared_ptr<DTypeConstructor>& c : cons)
{
/* Can not use emplace_back here since constructor is private. */
- d_ctors.push_back(DatatypeConstructor(d_solver, c));
+ d_ctors.push_back(DatatypeConstructor(d_solver, *c.get()));
}
- d_idx = begin ? 0 : cons->size();
+ d_idx = begin ? 0 : cons.size();
}
Datatype::const_iterator::const_iterator()
@@ -2384,6 +2712,18 @@ bool Datatype::const_iterator::operator!=(
/* -------------------------------------------------------------------------- */
/* Grammar */
/* -------------------------------------------------------------------------- */
+
+Grammar::Grammar()
+ : d_solver(nullptr),
+ d_sygusVars(),
+ d_ntSyms(),
+ d_ntsToTerms(0),
+ d_allowConst(),
+ d_allowVars(),
+ d_isResolved(false)
+{
+}
+
Grammar::Grammar(const Solver* slv,
const std::vector<Term>& sygusVars,
const std::vector<Term>& ntSymbols)
@@ -2411,7 +2751,7 @@ void Grammar::addRule(Term ntSymbol, Term rule)
d_ntsToTerms.find(ntSymbol) != d_ntsToTerms.cend(), ntSymbol)
<< "ntSymbol to be one of the non-terminal symbols given in the "
"predeclaration";
- CVC4_API_CHECK(ntSymbol.d_expr->getType() == rule.d_expr->getType())
+ CVC4_API_CHECK(ntSymbol.d_node->getType() == rule.d_node->getType())
<< "Expected ntSymbol and rule to have the same sort";
d_ntsToTerms[ntSymbol].push_back(rule);
@@ -2432,7 +2772,7 @@ void Grammar::addRules(Term ntSymbol, std::vector<Term> rules)
CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
!rules[i].isNull(), "parameter rule", rules[i], i)
<< "non-null term";
- CVC4_API_CHECK(ntSymbol.d_expr->getType() == rules[i].d_expr->getType())
+ CVC4_API_CHECK(ntSymbol.d_node->getType() == rules[i].d_node->getType())
<< "Expected ntSymbol and rule at index " << i
<< " to have the same sort";
}
@@ -2467,6 +2807,78 @@ void Grammar::addAnyVariable(Term ntSymbol)
d_allowVars.insert(ntSymbol);
}
+/**
+ * this function concatinates the outputs of calling f on each element between
+ * first and last, seperated by sep.
+ * @param first the beginning of the range
+ * @param last the end of the range
+ * @param f the function to call on each element in the range, its output must
+ * be overloaded for operator<<
+ * @param sep the string to add between successive calls to f
+ */
+template <typename Iterator, typename Function>
+std::string join(Iterator first, Iterator last, Function f, std::string sep)
+{
+ std::stringstream ss;
+ Iterator i = first;
+
+ if (i != last)
+ {
+ ss << f(*i);
+ ++i;
+ }
+
+ while (i != last)
+ {
+ ss << sep << f(*i);
+ ++i;
+ }
+
+ return ss.str();
+}
+
+std::string Grammar::toString() const
+{
+ std::stringstream ss;
+ ss << " (" // pre-declaration
+ << join(
+ d_ntSyms.cbegin(),
+ d_ntSyms.cend(),
+ [](const Term& t) {
+ std::stringstream s;
+ s << '(' << t << ' ' << t.getSort() << ')';
+ return s.str();
+ },
+ " ")
+ << ")\n (" // grouped rule listing
+ << join(
+ d_ntSyms.cbegin(),
+ d_ntSyms.cend(),
+ [this](const Term& t) {
+ bool allowConst = d_allowConst.find(t) != d_allowConst.cend(),
+ allowVars = d_allowVars.find(t) != d_allowVars.cend();
+ const std::vector<Term>& rules = d_ntsToTerms.at(t);
+ std::stringstream s;
+ s << '(' << t << ' ' << t.getSort() << " ("
+ << (allowConst ? "(Constant " + t.getSort().toString() + ")"
+ : "")
+ << (allowConst && allowVars ? " " : "")
+ << (allowVars ? "(Var " + t.getSort().toString() + ")" : "")
+ << ((allowConst || allowVars) && !rules.empty() ? " " : "")
+ << join(
+ rules.cbegin(),
+ rules.cend(),
+ [](const Term& rule) { return rule.toString(); },
+ " ")
+ << "))";
+ return s.str();
+ },
+ "\n ")
+ << ')';
+
+ return ss.str();
+}
+
Sort Grammar::resolve()
{
d_isResolved = true;
@@ -2487,11 +2899,11 @@ Sort Grammar::resolve()
// make the unresolved type, used for referencing the final version of
// the ntsymbol's datatype
ntsToUnres[ntsymbol] =
- Sort(d_solver, d_solver->getExprManager()->mkSort(ntsymbol.toString()));
+ Sort(d_solver, d_solver->getNodeManager()->mkSort(ntsymbol.toString()));
}
- std::vector<CVC4::Datatype> datatypes;
- std::set<Type> unresTypes;
+ std::vector<CVC4::DType> datatypes;
+ std::set<TypeNode> unresTypes;
datatypes.reserve(d_ntSyms.size());
@@ -2508,12 +2920,12 @@ Sort Grammar::resolve()
if (d_allowVars.find(ntSym) != d_allowVars.cend())
{
addSygusConstructorVariables(dtDecl,
- Sort(d_solver, ntSym.d_expr->getType()));
+ Sort(d_solver, ntSym.d_node->getType()));
}
bool aci = d_allowConst.find(ntSym) != d_allowConst.end();
- Type btt = ntSym.d_expr->getType();
- dtDecl.d_dtype->setSygus(btt, *bvl.d_expr, aci, false);
+ TypeNode btt = ntSym.d_node->getType();
+ dtDecl.d_dtype->setSygus(btt, *bvl.d_node, aci, false);
// We can be in a case where the only rule specified was (Variable T)
// and there are no variables of type T, in which case this is a bogus
@@ -2526,9 +2938,9 @@ Sort Grammar::resolve()
unresTypes.insert(*ntsToUnres[ntSym].d_type);
}
- std::vector<DatatypeType> datatypeTypes =
- d_solver->getExprManager()->mkMutualDatatypeTypes(
- datatypes, unresTypes, ExprManager::DATATYPE_FLAG_PLACEHOLDER);
+ std::vector<TypeNode> datatypeTypes =
+ d_solver->getNodeManager()->mkMutualDatatypeTypes(
+ datatypes, unresTypes, NodeManager::DATATYPE_FLAG_PLACEHOLDER);
// return is the first datatype
return Sort(d_solver, datatypeTypes[0]);
@@ -2558,12 +2970,13 @@ void Grammar::addSygusConstructorTerm(
d_solver->getExprManager()->mkExpr(
CVC4::kind::BOUND_VAR_LIST, termVectorToExprs(args)));
// its operator is a lambda
- op = Term(d_solver,
- d_solver->getExprManager()->mkExpr(CVC4::kind::LAMBDA,
- {*lbvl.d_expr, *op.d_expr}));
+ op = Term(
+ d_solver,
+ d_solver->getExprManager()->mkExpr(
+ CVC4::kind::LAMBDA, {lbvl.d_node->toExpr(), op.d_node->toExpr()}));
}
- dt.d_dtype->addSygusConstructor(
- *op.d_expr, ssCName.str(), sortVectorToTypes(cargs));
+ std::vector<TypeNode> cargst = sortVectorToTypeNodes(cargs);
+ dt.d_dtype->addSygusConstructor(*op.d_node, ssCName.str(), cargst);
}
Term Grammar::purifySygusGTerm(
@@ -2578,38 +2991,40 @@ Term Grammar::purifySygusGTerm(
{
Term ret =
Term(d_solver,
- d_solver->getExprManager()->mkBoundVar(term.d_expr->getType()));
+ d_solver->getNodeManager()->mkBoundVar(term.d_node->getType()));
args.push_back(ret);
cargs.push_back(itn->second);
return ret;
}
std::vector<Term> pchildren;
bool childChanged = false;
- for (unsigned i = 0, nchild = term.d_expr->getNumChildren(); i < nchild; i++)
+ for (unsigned i = 0, nchild = term.d_node->getNumChildren(); i < nchild; i++)
{
Term ptermc = purifySygusGTerm(
- Term(d_solver, (*term.d_expr)[i]), args, cargs, ntsToUnres);
+ Term(d_solver, (*term.d_node)[i]), args, cargs, ntsToUnres);
pchildren.push_back(ptermc);
- childChanged = childChanged || *ptermc.d_expr != (*term.d_expr)[i];
+ childChanged =
+ childChanged || ptermc.d_node->toExpr() != (term.d_node->toExpr())[i];
}
if (!childChanged)
{
return term;
}
- Expr nret;
+ Node nret;
- if (term.d_expr->isParameterized())
+ if (term.d_node->getMetaKind() == kind::metakind::PARAMETERIZED)
{
// it's an indexed operator so we should provide the op
- nret = d_solver->getExprManager()->mkExpr(term.d_expr->getKind(),
- term.d_expr->getOperator(),
- termVectorToExprs(pchildren));
+ NodeBuilder<> nb(term.d_node->getKind());
+ nb << term.d_node->getOperator();
+ nb.append(termVectorToNodes(pchildren));
+ nret = nb.constructNode();
}
else
{
- nret = d_solver->getExprManager()->mkExpr(term.d_expr->getKind(),
- termVectorToExprs(pchildren));
+ nret = d_solver->getNodeManager()->mkNode(term.d_node->getKind(),
+ termVectorToNodes(pchildren));
}
return Term(d_solver, nret);
@@ -2622,17 +3037,21 @@ void Grammar::addSygusConstructorVariables(DatatypeDecl& dt, Sort sort) const
for (unsigned i = 0, size = d_sygusVars.size(); i < size; i++)
{
Term v = d_sygusVars[i];
- if (v.d_expr->getType() == *sort.d_type)
+ if (v.d_node->getType() == *sort.d_type)
{
std::stringstream ss;
ss << v;
- std::vector<Sort> cargs;
- dt.d_dtype->addSygusConstructor(
- *v.d_expr, ss.str(), sortVectorToTypes(cargs));
+ std::vector<TypeNode> cargs;
+ dt.d_dtype->addSygusConstructor(*v.d_node, ss.str(), cargs);
}
}
}
+std::ostream& operator<<(std::ostream& out, const Grammar& g)
+{
+ return out << g.toString();
+}
+
/* -------------------------------------------------------------------------- */
/* Rounding Mode for Floating Points */
/* -------------------------------------------------------------------------- */
@@ -2641,24 +3060,24 @@ const static std::
unordered_map<RoundingMode, CVC4::RoundingMode, RoundingModeHashFunction>
s_rmodes{
{ROUND_NEAREST_TIES_TO_EVEN,
- CVC4::RoundingMode::roundNearestTiesToEven},
- {ROUND_TOWARD_POSITIVE, CVC4::RoundingMode::roundTowardPositive},
- {ROUND_TOWARD_NEGATIVE, CVC4::RoundingMode::roundTowardNegative},
- {ROUND_TOWARD_ZERO, CVC4::RoundingMode::roundTowardZero},
+ CVC4::RoundingMode::ROUND_NEAREST_TIES_TO_EVEN},
+ {ROUND_TOWARD_POSITIVE, CVC4::RoundingMode::ROUND_TOWARD_POSITIVE},
+ {ROUND_TOWARD_NEGATIVE, CVC4::RoundingMode::ROUND_TOWARD_POSITIVE},
+ {ROUND_TOWARD_ZERO, CVC4::RoundingMode::ROUND_TOWARD_ZERO},
{ROUND_NEAREST_TIES_TO_AWAY,
- CVC4::RoundingMode::roundNearestTiesToAway},
+ CVC4::RoundingMode::ROUND_NEAREST_TIES_TO_AWAY},
};
const static std::unordered_map<CVC4::RoundingMode,
RoundingMode,
CVC4::RoundingModeHashFunction>
s_rmodes_internal{
- {CVC4::RoundingMode::roundNearestTiesToEven,
+ {CVC4::RoundingMode::ROUND_NEAREST_TIES_TO_EVEN,
ROUND_NEAREST_TIES_TO_EVEN},
- {CVC4::RoundingMode::roundTowardPositive, ROUND_TOWARD_POSITIVE},
- {CVC4::RoundingMode::roundTowardNegative, ROUND_TOWARD_NEGATIVE},
- {CVC4::RoundingMode::roundTowardZero, ROUND_TOWARD_ZERO},
- {CVC4::RoundingMode::roundNearestTiesToAway,
+ {CVC4::RoundingMode::ROUND_TOWARD_POSITIVE, ROUND_TOWARD_POSITIVE},
+ {CVC4::RoundingMode::ROUND_TOWARD_POSITIVE, ROUND_TOWARD_NEGATIVE},
+ {CVC4::RoundingMode::ROUND_TOWARD_ZERO, ROUND_TOWARD_ZERO},
+ {CVC4::RoundingMode::ROUND_NEAREST_TIES_TO_AWAY,
ROUND_NEAREST_TIES_TO_AWAY},
};
@@ -2691,23 +3110,28 @@ Solver::~Solver() {}
template <typename T>
Term Solver::mkValHelper(T t) const
{
- Expr res = d_exprMgr->mkConst(t);
+ NodeManagerScope scope(getNodeManager());
+ Node res = getNodeManager()->mkConst(t);
(void)res.getType(true); /* kick off type checking */
return Term(this, res);
}
Term Solver::mkRealFromStrHelper(const std::string& s) const
{
- /* CLN and GMP handle this case differently, CLN interprets it as 0, GMP
- * throws an std::invalid_argument exception. For consistency, we treat it
- * as invalid. */
- CVC4_API_ARG_CHECK_EXPECTED(s != ".", s)
- << "a string representing an integer, real or rational value.";
-
- CVC4::Rational r = s.find('/') != std::string::npos
- ? CVC4::Rational(s)
- : CVC4::Rational::fromDecimal(s);
- return mkValHelper<CVC4::Rational>(r);
+ try
+ {
+ CVC4::Rational r = s.find('/') != std::string::npos
+ ? CVC4::Rational(s)
+ : CVC4::Rational::fromDecimal(s);
+ return mkValHelper<CVC4::Rational>(r);
+ }
+ catch (const std::invalid_argument& e)
+ {
+ std::stringstream message;
+ message << "Cannot construct Real or Int from string argument '" << s << "'"
+ << std::endl;
+ throw std::invalid_argument(message.str());
+ }
}
Term Solver::mkBVFromIntHelper(uint32_t size, uint64_t val) const
@@ -2760,15 +3184,28 @@ Term Solver::mkCharFromStrHelper(const std::string& s) const
CVC4_API_CHECK(s.find_first_not_of("0123456789abcdefABCDEF", 0)
== std::string::npos
&& s.size() <= 5 && s.size() > 0)
- << "Unexpected string for hexidecimal character " << s;
+ << "Unexpected string for hexadecimal character " << s;
uint32_t val = static_cast<uint32_t>(std::stoul(s, 0, 16));
CVC4_API_CHECK(val < String::num_codes())
- << "Not a valid code point for hexidecimal character " << s;
+ << "Not a valid code point for hexadecimal character " << s;
std::vector<unsigned> cpts;
cpts.push_back(val);
return mkValHelper<CVC4::String>(CVC4::String(cpts));
}
+Term Solver::getValueHelper(Term term) const
+{
+ Node value = d_smtEngine->getValue(*term.d_node);
+ Term res = Term(this, value);
+ // May need to wrap in real cast so that user know this is a real.
+ TypeNode tn = (*term.d_node).getType();
+ if (!tn.isInteger() && value.getType().isInteger())
+ {
+ return ensureRealSort(res);
+ }
+ return res;
+}
+
Term Solver::mkTermFromKind(Kind kind) const
{
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
@@ -2796,6 +3233,7 @@ Term Solver::mkTermFromKind(Kind kind) const
Term Solver::mkTermHelper(Kind kind, const std::vector<Term>& children) const
{
+ NodeManagerScope scope(getNodeManager());
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
for (size_t i = 0, size = children.size(); i < size; ++i)
{
@@ -2816,7 +3254,7 @@ Term Solver::mkTermHelper(Kind kind, const std::vector<Term>& children) const
if (echildren.size() > 2)
{
if (kind == INTS_DIVISION || kind == XOR || kind == MINUS
- || kind == DIVISION || kind == BITVECTOR_XNOR || kind == HO_APPLY)
+ || kind == DIVISION || kind == HO_APPLY || kind == REGEXP_DIFF)
{
// left-associative, but CVC4 internally only supports 2 args
res = d_exprMgr->mkLeftAssociative(k, echildren);
@@ -2854,7 +3292,23 @@ Term Solver::mkTermHelper(Kind kind, const std::vector<Term>& children) const
{
// default case, same as above
checkMkTerm(kind, children.size());
- res = d_exprMgr->mkExpr(k, echildren);
+ if (kind == api::SINGLETON)
+ {
+ // the type of the term is the same as the type of the internal node
+ // see Term::getSort()
+ TypeNode type = children[0].d_node->getType();
+ // Internally NodeManager::mkSingleton needs a type argument
+ // to construct a singleton, since there is no difference between
+ // integers and reals (both are Rationals).
+ // At the API, mkReal and mkInteger are different and therefore the
+ // element type can be used safely here.
+ Node singleton = getNodeManager()->mkSingleton(type, *children[0].d_node);
+ res = Term(this, singleton).getExpr();
+ }
+ else
+ {
+ res = d_exprMgr->mkExpr(k, echildren);
+ }
}
(void)res.getType(true); /* kick off type checking */
@@ -2863,12 +3317,13 @@ Term Solver::mkTermHelper(Kind kind, const std::vector<Term>& children) const
}
std::vector<Sort> Solver::mkDatatypeSortsInternal(
- std::vector<DatatypeDecl>& dtypedecls,
- std::set<Sort>& unresolvedSorts) const
+ const std::vector<DatatypeDecl>& dtypedecls,
+ const std::set<Sort>& unresolvedSorts) const
{
+ NodeManagerScope scope(getNodeManager());
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
- std::vector<CVC4::Datatype> datatypes;
+ std::vector<CVC4::DType> datatypes;
for (size_t i = 0, ndts = dtypedecls.size(); i < ndts; ++i)
{
CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(this == dtypedecls[i].d_solver,
@@ -2887,14 +3342,11 @@ std::vector<Sort> Solver::mkDatatypeSortsInternal(
{
CVC4_API_SOLVER_CHECK_SORT(sort);
}
- std::set<Type> utypes = sortSetToTypes(unresolvedSorts);
- std::vector<CVC4::DatatypeType> dtypes =
- d_exprMgr->mkMutualDatatypeTypes(datatypes, utypes);
- std::vector<Sort> retTypes;
- for (CVC4::DatatypeType t : dtypes)
- {
- retTypes.push_back(Sort(this, t));
- }
+
+ std::set<TypeNode> utypes = sortSetToTypeNodes(unresolvedSorts);
+ std::vector<CVC4::TypeNode> dtypes =
+ getNodeManager()->mkMutualDatatypeTypes(datatypes, utypes);
+ std::vector<Sort> retTypes = typeNodeVectorToSorts(this, dtypes);
return retTypes;
CVC4_API_SOLVER_TRY_CATCH_END;
@@ -2910,7 +3362,7 @@ std::vector<Type> Solver::sortVectorToTypes(
for (const Sort& s : sorts)
{
CVC4_API_SOLVER_CHECK_SORT(s);
- res.push_back(*s.d_type);
+ res.push_back(s.d_type->toType());
}
return res;
}
@@ -2922,7 +3374,7 @@ std::vector<Expr> Solver::termVectorToExprs(
for (const Term& t : terms)
{
CVC4_API_SOLVER_CHECK_TERM(t);
- res.push_back(*t.d_expr);
+ res.push_back(t.d_node->toExpr());
}
return res;
}
@@ -2949,55 +3401,71 @@ void Solver::checkMkTerm(Kind kind, uint32_t nchildren) const
<< " children (the one under construction has " << nchildren << ")";
}
+/* Solver Configuration */
+/* -------------------------------------------------------------------------- */
+
+bool Solver::supportsFloatingPoint() const
+{
+ return Configuration::isBuiltWithSymFPU();
+}
+
/* Sorts Handling */
/* -------------------------------------------------------------------------- */
Sort Solver::getNullSort(void) const
{
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
- return Sort(this, Type());
+ return Sort(this, TypeNode());
CVC4_API_SOLVER_TRY_CATCH_END;
}
Sort Solver::getBooleanSort(void) const
{
+ NodeManagerScope scope(getNodeManager());
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
- return Sort(this, d_exprMgr->booleanType());
+ return Sort(this, getNodeManager()->booleanType());
CVC4_API_SOLVER_TRY_CATCH_END;
}
Sort Solver::getIntegerSort(void) const
{
+ NodeManagerScope scope(getNodeManager());
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
- return Sort(this, d_exprMgr->integerType());
+ return Sort(this, getNodeManager()->integerType());
CVC4_API_SOLVER_TRY_CATCH_END;
}
Sort Solver::getRealSort(void) const
{
+ NodeManagerScope scope(getNodeManager());
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
- return Sort(this, d_exprMgr->realType());
+ return Sort(this, getNodeManager()->realType());
CVC4_API_SOLVER_TRY_CATCH_END;
}
Sort Solver::getRegExpSort(void) const
{
+ NodeManagerScope scope(getNodeManager());
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
- return Sort(this, d_exprMgr->regExpType());
+ return Sort(this, getNodeManager()->regExpType());
CVC4_API_SOLVER_TRY_CATCH_END;
}
Sort Solver::getStringSort(void) const
{
+ NodeManagerScope scope(getNodeManager());
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
- return Sort(this, d_exprMgr->stringType());
+ return Sort(this, getNodeManager()->stringType());
CVC4_API_SOLVER_TRY_CATCH_END;
}
-Sort Solver::getRoundingmodeSort(void) const
+Sort Solver::getRoundingModeSort(void) const
{
+ NodeManagerScope scope(getNodeManager());
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
- return Sort(this, d_exprMgr->roundingModeType());
+ CVC4_API_CHECK(Configuration::isBuiltWithSymFPU())
+ << "Expected CVC4 to be compiled with SymFPU support";
+ return Sort(this, getNodeManager()->roundingModeType());
CVC4_API_SOLVER_TRY_CATCH_END;
}
@@ -3005,6 +3473,7 @@ Sort Solver::getRoundingmodeSort(void) const
Sort Solver::mkArraySort(Sort indexSort, Sort elemSort) const
{
+ NodeManagerScope scope(getNodeManager());
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
CVC4_API_ARG_CHECK_EXPECTED(!indexSort.isNull(), indexSort)
<< "non-null index sort";
@@ -3013,42 +3482,47 @@ Sort Solver::mkArraySort(Sort indexSort, Sort elemSort) const
CVC4_API_SOLVER_CHECK_SORT(indexSort);
CVC4_API_SOLVER_CHECK_SORT(elemSort);
- return Sort(this,
- d_exprMgr->mkArrayType(*indexSort.d_type, *elemSort.d_type));
+ return Sort(
+ this, getNodeManager()->mkArrayType(*indexSort.d_type, *elemSort.d_type));
CVC4_API_SOLVER_TRY_CATCH_END;
}
Sort Solver::mkBitVectorSort(uint32_t size) const
{
+ NodeManagerScope scope(getNodeManager());
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
CVC4_API_ARG_CHECK_EXPECTED(size > 0, size) << "size > 0";
- return Sort(this, d_exprMgr->mkBitVectorType(size));
+ return Sort(this, getNodeManager()->mkBitVectorType(size));
CVC4_API_SOLVER_TRY_CATCH_END;
}
Sort Solver::mkFloatingPointSort(uint32_t exp, uint32_t sig) const
{
+ NodeManagerScope scope(getNodeManager());
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
+ CVC4_API_CHECK(Configuration::isBuiltWithSymFPU())
+ << "Expected CVC4 to be compiled with SymFPU support";
CVC4_API_ARG_CHECK_EXPECTED(exp > 0, exp) << "exponent size > 0";
CVC4_API_ARG_CHECK_EXPECTED(sig > 0, sig) << "significand size > 0";
- return Sort(this, d_exprMgr->mkFloatingPointType(exp, sig));
+ return Sort(this, getNodeManager()->mkFloatingPointType(exp, sig));
CVC4_API_SOLVER_TRY_CATCH_END;
}
Sort Solver::mkDatatypeSort(DatatypeDecl dtypedecl) const
{
+ NodeManagerScope scope(getNodeManager());
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
CVC4_API_CHECK(this == dtypedecl.d_solver)
<< "Given datatype declaration is not associated with this solver";
CVC4_API_ARG_CHECK_EXPECTED(dtypedecl.getNumConstructors() > 0, dtypedecl)
<< "a datatype declaration with at least one constructor";
- return Sort(this, d_exprMgr->mkDatatypeType(*dtypedecl.d_dtype));
+ return Sort(this, getNodeManager()->mkDatatypeType(*dtypedecl.d_dtype));
CVC4_API_SOLVER_TRY_CATCH_END;
}
@@ -3056,18 +3530,24 @@ Sort Solver::mkDatatypeSort(DatatypeDecl dtypedecl) const
std::vector<Sort> Solver::mkDatatypeSorts(
std::vector<DatatypeDecl>& dtypedecls) const
{
+ CVC4_API_SOLVER_TRY_CATCH_BEGIN;
std::set<Sort> unresolvedSorts;
return mkDatatypeSortsInternal(dtypedecls, unresolvedSorts);
+ CVC4_API_SOLVER_TRY_CATCH_END;
}
-std::vector<Sort> Solver::mkDatatypeSorts(std::vector<DatatypeDecl>& dtypedecls,
- std::set<Sort>& unresolvedSorts) const
+std::vector<Sort> Solver::mkDatatypeSorts(
+ const std::vector<DatatypeDecl>& dtypedecls,
+ const std::set<Sort>& unresolvedSorts) const
{
+ CVC4_API_SOLVER_TRY_CATCH_BEGIN;
return mkDatatypeSortsInternal(dtypedecls, unresolvedSorts);
+ CVC4_API_SOLVER_TRY_CATCH_END;
}
Sort Solver::mkFunctionSort(Sort domain, Sort codomain) const
{
+ NodeManagerScope scope(getNodeManager());
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
CVC4_API_ARG_CHECK_EXPECTED(!codomain.isNull(), codomain)
<< "non-null codomain sort";
@@ -3079,14 +3559,15 @@ Sort Solver::mkFunctionSort(Sort domain, Sort codomain) const
<< "first-class sort as codomain sort for function sort";
Assert(!codomain.isFunction()); /* A function sort is not first-class. */
- return Sort(this,
- d_exprMgr->mkFunctionType(*domain.d_type, *codomain.d_type));
+ return Sort(
+ this, getNodeManager()->mkFunctionType(*domain.d_type, *codomain.d_type));
CVC4_API_SOLVER_TRY_CATCH_END;
}
Sort Solver::mkFunctionSort(const std::vector<Sort>& sorts, Sort codomain) const
{
+ NodeManagerScope scope(getNodeManager());
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
CVC4_API_ARG_SIZE_CHECK_EXPECTED(sorts.size() >= 1, sorts)
<< "at least one parameter sort for function sort";
@@ -3109,22 +3590,26 @@ Sort Solver::mkFunctionSort(const std::vector<Sort>& sorts, Sort codomain) const
<< "first-class sort as codomain sort for function sort";
Assert(!codomain.isFunction()); /* A function sort is not first-class. */
- std::vector<Type> argTypes = sortVectorToTypes(sorts);
- return Sort(this, d_exprMgr->mkFunctionType(argTypes, *codomain.d_type));
+ std::vector<TypeNode> argTypes = sortVectorToTypeNodes(sorts);
+ return Sort(this,
+ getNodeManager()->mkFunctionType(argTypes, *codomain.d_type));
CVC4_API_SOLVER_TRY_CATCH_END;
}
Sort Solver::mkParamSort(const std::string& symbol) const
{
+ NodeManagerScope scope(getNodeManager());
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
- return Sort(this,
- d_exprMgr->mkSort(symbol, ExprManager::SORT_FLAG_PLACEHOLDER));
+ return Sort(
+ this,
+ getNodeManager()->mkSort(symbol, ExprManager::SORT_FLAG_PLACEHOLDER));
CVC4_API_SOLVER_TRY_CATCH_END;
}
Sort Solver::mkPredicateSort(const std::vector<Sort>& sorts) const
{
+ NodeManagerScope scope(getNodeManager());
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
CVC4_API_ARG_SIZE_CHECK_EXPECTED(sorts.size() >= 1, sorts)
<< "at least one parameter sort for predicate sort";
@@ -3140,9 +3625,9 @@ Sort Solver::mkPredicateSort(const std::vector<Sort>& sorts) const
sorts[i].isFirstClass(), "parameter sort", sorts[i], i)
<< "first-class sort as parameter sort for predicate sort";
}
- std::vector<Type> types = sortVectorToTypes(sorts);
+ std::vector<TypeNode> types = sortVectorToTypeNodes(sorts);
- return Sort(this, d_exprMgr->mkPredicateType(types));
+ return Sort(this, getNodeManager()->mkPredicateType(types));
CVC4_API_SOLVER_TRY_CATCH_END;
}
@@ -3150,6 +3635,7 @@ Sort Solver::mkPredicateSort(const std::vector<Sort>& sorts) const
Sort Solver::mkRecordSort(
const std::vector<std::pair<std::string, Sort>>& fields) const
{
+ NodeManagerScope scope(getNodeManager());
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
std::vector<std::pair<std::string, Type>> f;
size_t i = 0;
@@ -3162,58 +3648,76 @@ Sort Solver::mkRecordSort(
this == p.second.d_solver, "parameter sort", p.second, i)
<< "sort associated to this solver object";
i += 1;
- f.emplace_back(p.first, *p.second.d_type);
+ f.emplace_back(p.first, p.second.d_type->toType());
}
- return Sort(this, d_exprMgr->mkRecordType(Record(f)));
+ return Sort(this, getNodeManager()->mkRecordType(Record(f)));
CVC4_API_SOLVER_TRY_CATCH_END;
}
Sort Solver::mkSetSort(Sort elemSort) const
{
+ NodeManagerScope scope(getNodeManager());
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
CVC4_API_ARG_CHECK_EXPECTED(!elemSort.isNull(), elemSort)
<< "non-null element sort";
CVC4_API_SOLVER_CHECK_SORT(elemSort);
- return Sort(this, d_exprMgr->mkSetType(*elemSort.d_type));
+ return Sort(this, getNodeManager()->mkSetType(*elemSort.d_type));
+
+ CVC4_API_SOLVER_TRY_CATCH_END;
+}
+
+Sort Solver::mkBagSort(Sort elemSort) const
+{
+ NodeManagerScope scope(getNodeManager());
+ CVC4_API_SOLVER_TRY_CATCH_BEGIN;
+ CVC4_API_ARG_CHECK_EXPECTED(!elemSort.isNull(), elemSort)
+ << "non-null element sort";
+ CVC4_API_SOLVER_CHECK_SORT(elemSort);
+
+ return Sort(this, getNodeManager()->mkBagType(*elemSort.d_type));
CVC4_API_SOLVER_TRY_CATCH_END;
}
Sort Solver::mkSequenceSort(Sort elemSort) const
{
+ NodeManagerScope scope(getNodeManager());
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
CVC4_API_ARG_CHECK_EXPECTED(!elemSort.isNull(), elemSort)
<< "non-null element sort";
CVC4_API_SOLVER_CHECK_SORT(elemSort);
- return Sort(this, d_exprMgr->mkSequenceType(*elemSort.d_type));
+ return Sort(this, getNodeManager()->mkSequenceType(*elemSort.d_type));
CVC4_API_SOLVER_TRY_CATCH_END;
}
Sort Solver::mkUninterpretedSort(const std::string& symbol) const
{
+ NodeManagerScope scope(getNodeManager());
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
- return Sort(this, d_exprMgr->mkSort(symbol));
+ return Sort(this, getNodeManager()->mkSort(symbol));
CVC4_API_SOLVER_TRY_CATCH_END;
}
Sort Solver::mkSortConstructorSort(const std::string& symbol,
size_t arity) const
{
+ NodeManagerScope scope(getNodeManager());
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
CVC4_API_ARG_CHECK_EXPECTED(arity > 0, arity) << "an arity > 0";
- return Sort(this, d_exprMgr->mkSortConstructor(symbol, arity));
+ return Sort(this, getNodeManager()->mkSortConstructor(symbol, arity));
CVC4_API_SOLVER_TRY_CATCH_END;
}
Sort Solver::mkTupleSort(const std::vector<Sort>& sorts) const
{
+ NodeManagerScope scope(getNodeManager());
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
for (size_t i = 0, size = sorts.size(); i < size; ++i)
{
@@ -3227,9 +3731,8 @@ Sort Solver::mkTupleSort(const std::vector<Sort>& sorts) const
!sorts[i].isFunctionLike(), "parameter sort", sorts[i], i)
<< "non-function-like sort as parameter sort for tuple sort";
}
- std::vector<Type> types = sortVectorToTypes(sorts);
-
- return Sort(this, d_exprMgr->mkTupleType(types));
+ std::vector<TypeNode> typeNodes = sortVectorToTypeNodes(sorts);
+ return Sort(this, getNodeManager()->mkTupleType(typeNodes));
CVC4_API_SOLVER_TRY_CATCH_END;
}
@@ -3270,76 +3773,66 @@ Term Solver::mkPi() const
CVC4_API_SOLVER_TRY_CATCH_END;
}
-Term Solver::mkReal(const char* s) const
-{
- CVC4_API_SOLVER_TRY_CATCH_BEGIN;
- CVC4_API_ARG_CHECK_NOT_NULLPTR(s);
-
- return mkRealFromStrHelper(std::string(s));
-
- CVC4_API_SOLVER_TRY_CATCH_END;
-}
-
-Term Solver::mkReal(const std::string& s) const
+Term Solver::mkInteger(const std::string& s) const
{
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
- return mkRealFromStrHelper(s);
+ CVC4_API_ARG_CHECK_EXPECTED(std::regex_match(s, std::regex("-?\\d+")), s)
+ << " an integer ";
+ Term integer = mkRealFromStrHelper(s);
+ CVC4_API_ARG_CHECK_EXPECTED(integer.getSort() == getIntegerSort(), s)
+ << " an integer";
+ return integer;
CVC4_API_SOLVER_TRY_CATCH_END;
}
-Term Solver::mkReal(int32_t val) const
+Term Solver::mkInteger(int64_t val) const
{
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
- return mkValHelper<CVC4::Rational>(CVC4::Rational(val));
+ Term integer = mkValHelper<CVC4::Rational>(CVC4::Rational(val));
+ Assert(integer.getSort() == getIntegerSort());
+ return integer;
CVC4_API_SOLVER_TRY_CATCH_END;
}
-Term Solver::mkReal(int64_t val) const
-{
- CVC4_API_SOLVER_TRY_CATCH_BEGIN;
- return mkValHelper<CVC4::Rational>(CVC4::Rational(val));
- CVC4_API_SOLVER_TRY_CATCH_END;
-}
-
-Term Solver::mkReal(uint32_t val) const
+Term Solver::mkReal(const std::string& s) const
{
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
- return mkValHelper<CVC4::Rational>(CVC4::Rational(val));
+ /* CLN and GMP handle this case differently, CLN interprets it as 0, GMP
+ * throws an std::invalid_argument exception. For consistency, we treat it
+ * as invalid. */
+ CVC4_API_ARG_CHECK_EXPECTED(s != ".", s)
+ << "a string representing a real or rational value.";
+ Term rational = mkRealFromStrHelper(s);
+ return ensureRealSort(rational);
CVC4_API_SOLVER_TRY_CATCH_END;
}
-Term Solver::mkReal(uint64_t val) const
+Term Solver::ensureRealSort(const Term t) const
{
- CVC4_API_SOLVER_TRY_CATCH_BEGIN;
- return mkValHelper<CVC4::Rational>(CVC4::Rational(val));
- CVC4_API_SOLVER_TRY_CATCH_END;
+ CVC4_API_ARG_CHECK_EXPECTED(
+ t.getSort() == getIntegerSort() || t.getSort() == getRealSort(),
+ " an integer or real term");
+ if (t.getSort() == getIntegerSort())
+ {
+ Node n = getNodeManager()->mkNode(kind::CAST_TO_REAL, *t.d_node);
+ return Term(this, n);
+ }
+ return t;
}
-Term Solver::mkReal(int32_t num, int32_t den) const
+Term Solver::mkReal(int64_t val) const
{
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
- return mkValHelper<CVC4::Rational>(CVC4::Rational(num, den));
+ Term rational = mkValHelper<CVC4::Rational>(CVC4::Rational(val));
+ return ensureRealSort(rational);
CVC4_API_SOLVER_TRY_CATCH_END;
}
Term Solver::mkReal(int64_t num, int64_t den) const
{
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
- return mkValHelper<CVC4::Rational>(CVC4::Rational(num, den));
- CVC4_API_SOLVER_TRY_CATCH_END;
-}
-
-Term Solver::mkReal(uint32_t num, uint32_t den) const
-{
- CVC4_API_SOLVER_TRY_CATCH_BEGIN;
- return mkValHelper<CVC4::Rational>(CVC4::Rational(num, den));
- CVC4_API_SOLVER_TRY_CATCH_END;
-}
-
-Term Solver::mkReal(uint64_t num, uint64_t den) const
-{
- CVC4_API_SOLVER_TRY_CATCH_BEGIN;
- return mkValHelper<CVC4::Rational>(CVC4::Rational(num, den));
+ Term rational = mkValHelper<CVC4::Rational>(CVC4::Rational(num, den));
+ return ensureRealSort(rational);
CVC4_API_SOLVER_TRY_CATCH_END;
}
@@ -3375,29 +3868,36 @@ Term Solver::mkEmptySet(Sort s) const
CVC4_API_ARG_CHECK_EXPECTED(s.isNull() || this == s.d_solver, s)
<< "set sort associated to this solver object";
- return mkValHelper<CVC4::EmptySet>(
- CVC4::EmptySet(TypeNode::fromType(*s.d_type)));
+ return mkValHelper<CVC4::EmptySet>(CVC4::EmptySet(*s.d_type));
CVC4_API_SOLVER_TRY_CATCH_END;
}
-Term Solver::mkSepNil(Sort sort) const
+Term Solver::mkEmptyBag(Sort s) const
{
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
- CVC4_API_ARG_CHECK_EXPECTED(!sort.isNull(), sort) << "non-null sort";
- CVC4_API_SOLVER_CHECK_SORT(sort);
+ CVC4_API_ARG_CHECK_EXPECTED(s.isNull() || s.isBag(), s)
+ << "null sort or bag sort";
- Expr res = d_exprMgr->mkNullaryOperator(*sort.d_type, CVC4::kind::SEP_NIL);
- (void)res.getType(true); /* kick off type checking */
- return Term(this, res);
+ CVC4_API_ARG_CHECK_EXPECTED(s.isNull() || this == s.d_solver, s)
+ << "bag sort associated to this solver object";
+
+ return mkValHelper<CVC4::EmptyBag>(CVC4::EmptyBag(*s.d_type));
CVC4_API_SOLVER_TRY_CATCH_END;
}
-Term Solver::mkString(const char* s, bool useEscSequences) const
+Term Solver::mkSepNil(Sort sort) const
{
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
- return mkValHelper<CVC4::String>(CVC4::String(s, useEscSequences));
+ CVC4_API_ARG_CHECK_EXPECTED(!sort.isNull(), sort) << "non-null sort";
+ CVC4_API_SOLVER_CHECK_SORT(sort);
+
+ Node res =
+ getNodeManager()->mkNullaryOperator(*sort.d_type, CVC4::kind::SEP_NIL);
+ (void)res.getType(true); /* kick off type checking */
+ return Term(this, res);
+
CVC4_API_SOLVER_TRY_CATCH_END;
}
@@ -3429,14 +3929,6 @@ Term Solver::mkChar(const std::string& s) const
CVC4_API_SOLVER_TRY_CATCH_END;
}
-Term Solver::mkChar(const char* s) const
-{
- CVC4_API_SOLVER_TRY_CATCH_BEGIN;
- CVC4_API_ARG_CHECK_NOT_NULLPTR(s);
- return mkCharFromStrHelper(std::string(s));
- CVC4_API_SOLVER_TRY_CATCH_END;
-}
-
Term Solver::mkEmptySequence(Sort sort) const
{
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
@@ -3444,8 +3936,7 @@ Term Solver::mkEmptySequence(Sort sort) const
CVC4_API_SOLVER_CHECK_SORT(sort);
std::vector<Node> seq;
- Expr res =
- d_exprMgr->mkConst(Sequence(TypeNode::fromType(*sort.d_type), seq));
+ Expr res = d_exprMgr->mkConst(Sequence(*sort.d_type, seq));
return Term(this, res);
CVC4_API_SOLVER_TRY_CATCH_END;
@@ -3457,8 +3948,8 @@ Term Solver::mkUniverseSet(Sort sort) const
CVC4_API_ARG_CHECK_EXPECTED(!sort.isNull(), sort) << "non-null sort";
CVC4_API_SOLVER_CHECK_SORT(sort);
- Expr res =
- d_exprMgr->mkNullaryOperator(*sort.d_type, CVC4::kind::UNIVERSE_SET);
+ Node res = getNodeManager()->mkNullaryOperator(*sort.d_type,
+ CVC4::kind::UNIVERSE_SET);
// TODO(#2771): Reenable?
// (void)res->getType(true); /* kick off type checking */
return Term(this, res);
@@ -3473,16 +3964,6 @@ Term Solver::mkBitVector(uint32_t size, uint64_t val) const
CVC4_API_SOLVER_TRY_CATCH_END;
}
-Term Solver::mkBitVector(const char* s, uint32_t base) const
-{
- CVC4_API_SOLVER_TRY_CATCH_BEGIN;
- CVC4_API_ARG_CHECK_NOT_NULLPTR(s);
-
- return mkBVFromStrHelper(std::string(s), base);
-
- CVC4_API_SOLVER_TRY_CATCH_END;
-}
-
Term Solver::mkBitVector(const std::string& s, uint32_t base) const
{
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
@@ -3490,15 +3971,9 @@ Term Solver::mkBitVector(const std::string& s, uint32_t base) const
CVC4_API_SOLVER_TRY_CATCH_END;
}
-Term Solver::mkBitVector(uint32_t size, const char* s, uint32_t base) const
-{
- CVC4_API_SOLVER_TRY_CATCH_BEGIN;
- CVC4_API_ARG_CHECK_NOT_NULLPTR(s);
- return mkBVFromStrHelper(size, s, base);
- CVC4_API_SOLVER_TRY_CATCH_END;
-}
-
-Term Solver::mkBitVector(uint32_t size, std::string& s, uint32_t base) const
+Term Solver::mkBitVector(uint32_t size,
+ const std::string& s,
+ uint32_t base) const
{
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
return mkBVFromStrHelper(size, s, base);
@@ -3514,10 +3989,17 @@ Term Solver::mkConstArray(Sort sort, Term val) const
CVC4_API_SOLVER_CHECK_SORT(sort);
CVC4_API_SOLVER_CHECK_TERM(val);
CVC4_API_CHECK(sort.isArray()) << "Not an array sort.";
- CVC4_API_CHECK(sort.getArrayElementSort().isComparableTo(val.getSort()))
+ CVC4_API_CHECK(val.getSort().isSubsortOf(sort.getArrayElementSort()))
<< "Value does not match element sort.";
- Term res = mkValHelper<CVC4::ArrayStoreAll>(CVC4::ArrayStoreAll(
- TypeNode::fromType(*sort.d_type), Node::fromExpr(*val.d_expr)));
+ // handle the special case of (CAST_TO_REAL n) where n is an integer
+ Node n = *val.d_node;
+ if (val.isCastedReal())
+ {
+ // this is safe because the constant array stores its type
+ n = n[0];
+ }
+ Term res = mkValHelper<CVC4::ArrayStoreAll>(
+ CVC4::ArrayStoreAll(*sort.d_type, n));
return res;
CVC4_API_SOLVER_TRY_CATCH_END;
}
@@ -3585,6 +4067,8 @@ Term Solver::mkNegZero(uint32_t exp, uint32_t sig) const
Term Solver::mkRoundingMode(RoundingMode rm) const
{
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
+ CVC4_API_CHECK(Configuration::isBuiltWithSymFPU())
+ << "Expected CVC4 to be compiled with SymFPU support";
return mkValHelper<CVC4::RoundingMode>(s_rmodes.at(rm));
CVC4_API_SOLVER_TRY_CATCH_END;
}
@@ -3596,7 +4080,7 @@ Term Solver::mkUninterpretedConst(Sort sort, int32_t index) const
CVC4_API_SOLVER_CHECK_SORT(sort);
return mkValHelper<CVC4::UninterpretedConstant>(
- CVC4::UninterpretedConstant(TypeNode::fromType(*sort.d_type), index));
+ CVC4::UninterpretedConstant(*sort.d_type, index));
CVC4_API_SOLVER_TRY_CATCH_END;
}
@@ -3609,7 +4093,7 @@ Term Solver::mkAbstractValue(const std::string& index) const
CVC4::Integer idx(index, 10);
CVC4_API_ARG_CHECK_EXPECTED(idx > 0, index)
<< "a string representing an integer > 0";
- return Term(this, d_exprMgr->mkConst(CVC4::AbstractValue(idx)));
+ return Term(this, getNodeManager()->mkConst(CVC4::AbstractValue(idx)));
// do not call getType(), for abstract values, type can not be computed
// until it is substituted away
CVC4_API_SOLVER_TRY_CATCH_END;
@@ -3620,7 +4104,8 @@ Term Solver::mkAbstractValue(uint64_t index) const
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
CVC4_API_ARG_CHECK_EXPECTED(index > 0, index) << "an integer > 0";
- return Term(this, d_exprMgr->mkConst(CVC4::AbstractValue(Integer(index))));
+ return Term(this,
+ getNodeManager()->mkConst(CVC4::AbstractValue(Integer(index))));
// do not call getType(), for abstract values, type can not be computed
// until it is substituted away
CVC4_API_SOLVER_TRY_CATCH_END;
@@ -3639,11 +4124,11 @@ Term Solver::mkFloatingPoint(uint32_t exp, uint32_t sig, Term val) const
CVC4_API_ARG_CHECK_EXPECTED(!val.isNull(), val) << "non-null term";
CVC4_API_SOLVER_CHECK_TERM(val);
CVC4_API_ARG_CHECK_EXPECTED(
- val.getSort().isBitVector() && val.d_expr->isConst(), val)
+ val.getSort().isBitVector() && val.d_node->isConst(), val)
<< "bit-vector constant";
return mkValHelper<CVC4::FloatingPoint>(
- CVC4::FloatingPoint(exp, sig, val.d_expr->getConst<BitVector>()));
+ CVC4::FloatingPoint(exp, sig, val.d_node->getConst<BitVector>()));
CVC4_API_SOLVER_TRY_CATCH_END;
}
@@ -3653,12 +4138,26 @@ Term Solver::mkFloatingPoint(uint32_t exp, uint32_t sig, Term val) const
Term Solver::mkConst(Sort sort, const std::string& symbol) const
{
+ NodeManagerScope scope(getNodeManager());
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
CVC4_API_ARG_CHECK_EXPECTED(!sort.isNull(), sort) << "non-null sort";
CVC4_API_SOLVER_CHECK_SORT(sort);
- Expr res = symbol.empty() ? d_exprMgr->mkVar(*sort.d_type)
- : d_exprMgr->mkVar(symbol, *sort.d_type);
+ Expr res = d_exprMgr->mkVar(symbol, sort.d_type->toType());
+ (void)res.getType(true); /* kick off type checking */
+ return Term(this, res);
+
+ CVC4_API_SOLVER_TRY_CATCH_END;
+}
+
+Term Solver::mkConst(Sort sort) const
+{
+ NodeManagerScope scope(getNodeManager());
+ CVC4_API_SOLVER_TRY_CATCH_BEGIN;
+ CVC4_API_ARG_CHECK_EXPECTED(!sort.isNull(), sort) << "non-null sort";
+ CVC4_API_SOLVER_CHECK_SORT(sort);
+
+ Expr res = d_exprMgr->mkVar(sort.d_type->toType());
(void)res.getType(true); /* kick off type checking */
return Term(this, res);
@@ -3674,8 +4173,9 @@ Term Solver::mkVar(Sort sort, const std::string& symbol) const
CVC4_API_ARG_CHECK_EXPECTED(!sort.isNull(), sort) << "non-null sort";
CVC4_API_SOLVER_CHECK_SORT(sort);
- Expr res = symbol.empty() ? d_exprMgr->mkBoundVar(*sort.d_type)
- : d_exprMgr->mkBoundVar(symbol, *sort.d_type);
+ Expr res = symbol.empty()
+ ? d_exprMgr->mkBoundVar(sort.d_type->toType())
+ : d_exprMgr->mkBoundVar(symbol, sort.d_type->toType());
(void)res.getType(true); /* kick off type checking */
return Term(this, res);
@@ -3688,6 +4188,7 @@ Term Solver::mkVar(Sort sort, const std::string& symbol) const
DatatypeConstructorDecl Solver::mkDatatypeConstructorDecl(
const std::string& name)
{
+ NodeManagerScope scope(getNodeManager());
return DatatypeConstructorDecl(this, name);
}
@@ -3696,6 +4197,7 @@ DatatypeConstructorDecl Solver::mkDatatypeConstructorDecl(
DatatypeDecl Solver::mkDatatypeDecl(const std::string& name, bool isCoDatatype)
{
+ NodeManagerScope scope(getNodeManager());
return DatatypeDecl(this, name, isCoDatatype);
}
@@ -3703,6 +4205,7 @@ DatatypeDecl Solver::mkDatatypeDecl(const std::string& name,
Sort param,
bool isCoDatatype)
{
+ NodeManagerScope scope(getNodeManager());
return DatatypeDecl(this, name, param, isCoDatatype);
}
@@ -3710,6 +4213,7 @@ DatatypeDecl Solver::mkDatatypeDecl(const std::string& name,
const std::vector<Sort>& params,
bool isCoDatatype)
{
+ NodeManagerScope scope(getNodeManager());
return DatatypeDecl(this, name, params, isCoDatatype);
}
@@ -3725,33 +4229,12 @@ Term Solver::mkTerm(Kind kind) const
Term Solver::mkTerm(Kind kind, Term child) const
{
- CVC4_API_SOLVER_TRY_CATCH_BEGIN;
- CVC4_API_ARG_CHECK_EXPECTED(!child.isNull(), child) << "non-null term";
- CVC4_API_SOLVER_CHECK_TERM(child);
- checkMkTerm(kind, 1);
-
- Expr res = d_exprMgr->mkExpr(extToIntKind(kind), *child.d_expr);
- (void)res.getType(true); /* kick off type checking */
- return Term(this, res);
-
- CVC4_API_SOLVER_TRY_CATCH_END;
+ return mkTermHelper(kind, std::vector<Term>{child});
}
Term Solver::mkTerm(Kind kind, Term child1, Term child2) const
{
- CVC4_API_SOLVER_TRY_CATCH_BEGIN;
- CVC4_API_ARG_CHECK_EXPECTED(!child1.isNull(), child1) << "non-null term";
- CVC4_API_ARG_CHECK_EXPECTED(!child2.isNull(), child2) << "non-null term";
- CVC4_API_SOLVER_CHECK_TERM(child1);
- CVC4_API_SOLVER_CHECK_TERM(child2);
- checkMkTerm(kind, 2);
-
- Expr res =
- d_exprMgr->mkExpr(extToIntKind(kind), *child1.d_expr, *child2.d_expr);
- (void)res.getType(true); /* kick off type checking */
- return Term(this, res);
-
- CVC4_API_SOLVER_TRY_CATCH_END;
+ return mkTermHelper(kind, std::vector<Term>{child1, child2});
}
Term Solver::mkTerm(Kind kind, Term child1, Term child2, Term child3) const
@@ -3767,21 +4250,20 @@ Term Solver::mkTerm(Kind kind, const std::vector<Term>& children) const
Term Solver::mkTerm(Op op) const
{
+ NodeManagerScope scope(getNodeManager());
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
CVC4_API_SOLVER_CHECK_OP(op);
+ checkMkTerm(op.d_kind, 0);
- Term res;
- if (op.isIndexedHelper())
+ if (!op.isIndexedHelper())
{
- const CVC4::Kind int_kind = extToIntKind(op.d_kind);
- res = Term(this, d_exprMgr->mkExpr(int_kind, *op.d_expr));
- }
- else
- {
- res = mkTermFromKind(op.d_kind);
+ return mkTermFromKind(op.d_kind);
}
- (void)res.d_expr->getType(true); /* kick off type checking */
+ const CVC4::Kind int_kind = extToIntKind(op.d_kind);
+ Term res = Term(this, getNodeManager()->mkNode(int_kind, *op.d_node));
+
+ (void)res.d_node->getType(true); /* kick off type checking */
return res;
CVC4_API_SOLVER_TRY_CATCH_END;
@@ -3789,88 +4271,35 @@ Term Solver::mkTerm(Op op) const
Term Solver::mkTerm(Op op, Term child) const
{
- CVC4_API_SOLVER_TRY_CATCH_BEGIN;
- CVC4_API_SOLVER_CHECK_OP(op);
- CVC4_API_ARG_CHECK_EXPECTED(!child.isNull(), child) << "non-null term";
- CVC4_API_SOLVER_CHECK_TERM(child);
-
- const CVC4::Kind int_kind = extToIntKind(op.d_kind);
- Expr res;
- if (op.isIndexedHelper())
- {
- res = d_exprMgr->mkExpr(int_kind, *op.d_expr, *child.d_expr);
- }
- else
- {
- res = d_exprMgr->mkExpr(int_kind, *child.d_expr);
- }
-
- (void)res.getType(true); /* kick off type checking */
- return Term(this, res);
-
- CVC4_API_SOLVER_TRY_CATCH_END;
+ return mkTermHelper(op, std::vector<Term>{child});
}
Term Solver::mkTerm(Op op, Term child1, Term child2) const
{
- CVC4_API_SOLVER_TRY_CATCH_BEGIN;
- CVC4_API_SOLVER_CHECK_OP(op);
- CVC4_API_ARG_CHECK_EXPECTED(!child1.isNull(), child1) << "non-null term";
- CVC4_API_ARG_CHECK_EXPECTED(!child2.isNull(), child2) << "non-null term";
- CVC4_API_SOLVER_CHECK_TERM(child1);
- CVC4_API_SOLVER_CHECK_TERM(child2);
-
- const CVC4::Kind int_kind = extToIntKind(op.d_kind);
- Expr res;
- if (op.isIndexedHelper())
- {
- res =
- d_exprMgr->mkExpr(int_kind, *op.d_expr, *child1.d_expr, *child2.d_expr);
- }
- else
- {
- res = d_exprMgr->mkExpr(int_kind, *child1.d_expr, *child2.d_expr);
- }
-
- (void)res.getType(true); /* kick off type checking */
- return Term(this, res);
- CVC4_API_SOLVER_TRY_CATCH_END;
+ return mkTermHelper(op, std::vector<Term>{child1, child2});
}
Term Solver::mkTerm(Op op, Term child1, Term child2, Term child3) const
{
- CVC4_API_SOLVER_TRY_CATCH_BEGIN;
- CVC4_API_SOLVER_CHECK_OP(op);
- 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";
- CVC4_API_SOLVER_CHECK_TERM(child1);
- CVC4_API_SOLVER_CHECK_TERM(child2);
- CVC4_API_SOLVER_CHECK_TERM(child3);
-
- const CVC4::Kind int_kind = extToIntKind(op.d_kind);
- Expr res;
- if (op.isIndexedHelper())
- {
- res = d_exprMgr->mkExpr(
- int_kind, *op.d_expr, *child1.d_expr, *child2.d_expr, *child3.d_expr);
- }
- else
- {
- res = d_exprMgr->mkExpr(
- int_kind, *child1.d_expr, *child2.d_expr, *child3.d_expr);
- }
-
- (void)res.getType(true); /* kick off type checking */
- return Term(this, res);
-
- CVC4_API_SOLVER_TRY_CATCH_END;
+ return mkTermHelper(op, std::vector<Term>{child1, child2, child3});
}
Term Solver::mkTerm(Op op, const std::vector<Term>& children) const
{
+ return mkTermHelper(op, children);
+}
+
+Term Solver::mkTermHelper(const Op& op, const std::vector<Term>& children) const
+{
+ if (!op.isIndexedHelper())
+ {
+ return mkTermHelper(op.d_kind, children);
+ }
+
+ NodeManagerScope scope(getNodeManager());
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
CVC4_API_SOLVER_CHECK_OP(op);
+ checkMkTerm(op.d_kind, children.size());
for (size_t i = 0, size = children.size(); i < size; ++i)
{
CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
@@ -3882,16 +4311,12 @@ Term Solver::mkTerm(Op op, const std::vector<Term>& children) const
}
const CVC4::Kind int_kind = extToIntKind(op.d_kind);
- std::vector<Expr> echildren = termVectorToExprs(children);
- Expr res;
- if (op.isIndexedHelper())
- {
- res = d_exprMgr->mkExpr(int_kind, *op.d_expr, echildren);
- }
- else
- {
- res = d_exprMgr->mkExpr(int_kind, echildren);
- }
+ std::vector<Node> echildren = termVectorToNodes(children);
+
+ NodeBuilder<> nb(int_kind);
+ nb << *op.d_node;
+ nb.append(echildren);
+ Node res = nb.constructNode();
(void)res.getType(true); /* kick off type checking */
return Term(this, res);
@@ -3902,10 +4327,11 @@ Term Solver::mkTerm(Op op, const std::vector<Term>& children) const
Term Solver::mkTuple(const std::vector<Sort>& sorts,
const std::vector<Term>& terms) const
{
+ NodeManagerScope scope(getNodeManager());
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
CVC4_API_CHECK(sorts.size() == terms.size())
<< "Expected the same number of sorts and elements";
- std::vector<CVC4::Expr> args;
+ std::vector<CVC4::Node> args;
for (size_t i = 0, size = sorts.size(); i < size; i++)
{
CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
@@ -3914,14 +4340,15 @@ Term Solver::mkTuple(const std::vector<Sort>& sorts,
CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
this == sorts[i].d_solver, "child sort", sorts[i], i)
<< "child sort associated to this solver object";
- args.push_back(*(ensureTermSort(terms[i], sorts[i])).d_expr);
+ args.push_back(*(ensureTermSort(terms[i], sorts[i])).d_node);
}
Sort s = mkTupleSort(sorts);
Datatype dt = s.getDatatype();
- Expr res = d_exprMgr->mkExpr(extToIntKind(APPLY_CONSTRUCTOR),
- *dt[0].getConstructorTerm().d_expr,
- args);
+ NodeBuilder<> nb(extToIntKind(APPLY_CONSTRUCTOR));
+ nb << *dt[0].getConstructorTerm().d_node;
+ nb.append(args);
+ Node res = nb.constructNode();
(void)res.getType(true); /* kick off type checking */
return Term(this, res);
@@ -3949,10 +4376,9 @@ Op Solver::mkOp(Kind kind, const std::string& arg) const
Op res;
if (kind == RECORD_UPDATE)
{
- res = Op(
- this,
- kind,
- *mkValHelper<CVC4::RecordUpdate>(CVC4::RecordUpdate(arg)).d_expr.get());
+ res = Op(this,
+ kind,
+ *mkValHelper<CVC4::RecordUpdate>(CVC4::RecordUpdate(arg)).d_node);
}
else
{
@@ -3964,7 +4390,7 @@ Op Solver::mkOp(Kind kind, const std::string& arg) const
res = Op(this,
kind,
*mkValHelper<CVC4::Divisible>(CVC4::Divisible(CVC4::Integer(arg)))
- .d_expr.get());
+ .d_node);
}
return res;
@@ -3980,81 +4406,78 @@ Op Solver::mkOp(Kind kind, uint32_t arg) const
switch (kind)
{
case DIVISIBLE:
- res =
- Op(this,
- kind,
- *mkValHelper<CVC4::Divisible>(CVC4::Divisible(arg)).d_expr.get());
+ res = Op(this,
+ kind,
+ *mkValHelper<CVC4::Divisible>(CVC4::Divisible(arg)).d_node);
break;
case BITVECTOR_REPEAT:
res = Op(this,
kind,
- *mkValHelper<CVC4::BitVectorRepeat>(CVC4::BitVectorRepeat(arg))
- .d_expr.get());
+ mkValHelper<CVC4::BitVectorRepeat>(CVC4::BitVectorRepeat(arg))
+ .d_node->toExpr());
break;
case BITVECTOR_ZERO_EXTEND:
res = Op(this,
kind,
*mkValHelper<CVC4::BitVectorZeroExtend>(
CVC4::BitVectorZeroExtend(arg))
- .d_expr.get());
+ .d_node);
break;
case BITVECTOR_SIGN_EXTEND:
res = Op(this,
kind,
*mkValHelper<CVC4::BitVectorSignExtend>(
CVC4::BitVectorSignExtend(arg))
- .d_expr.get());
+ .d_node);
break;
case BITVECTOR_ROTATE_LEFT:
res = Op(this,
kind,
*mkValHelper<CVC4::BitVectorRotateLeft>(
CVC4::BitVectorRotateLeft(arg))
- .d_expr.get());
+ .d_node);
break;
case BITVECTOR_ROTATE_RIGHT:
res = Op(this,
kind,
*mkValHelper<CVC4::BitVectorRotateRight>(
CVC4::BitVectorRotateRight(arg))
- .d_expr.get());
+ .d_node);
break;
case INT_TO_BITVECTOR:
- res = Op(this,
- kind,
- *mkValHelper<CVC4::IntToBitVector>(CVC4::IntToBitVector(arg))
- .d_expr.get());
+ res = Op(
+ this,
+ kind,
+ *mkValHelper<CVC4::IntToBitVector>(CVC4::IntToBitVector(arg)).d_node);
break;
case IAND:
- res = Op(this,
- kind,
- *mkValHelper<CVC4::IntAnd>(CVC4::IntAnd(arg)).d_expr.get());
+ res =
+ Op(this, kind, *mkValHelper<CVC4::IntAnd>(CVC4::IntAnd(arg)).d_node);
break;
case FLOATINGPOINT_TO_UBV:
res = Op(
this,
kind,
*mkValHelper<CVC4::FloatingPointToUBV>(CVC4::FloatingPointToUBV(arg))
- .d_expr.get());
+ .d_node);
break;
case FLOATINGPOINT_TO_SBV:
res = Op(
this,
kind,
*mkValHelper<CVC4::FloatingPointToSBV>(CVC4::FloatingPointToSBV(arg))
- .d_expr.get());
+ .d_node);
break;
case TUPLE_UPDATE:
- res = Op(
- this,
- kind,
- *mkValHelper<CVC4::TupleUpdate>(CVC4::TupleUpdate(arg)).d_expr.get());
- break;
- case REGEXP_REPEAT:
res = Op(this,
kind,
- *mkValHelper<CVC4::RegExpRepeat>(CVC4::RegExpRepeat(arg))
- .d_expr.get());
+ *mkValHelper<CVC4::TupleUpdate>(CVC4::TupleUpdate(arg)).d_node);
+ break;
+ case REGEXP_REPEAT:
+ res =
+ Op(this,
+ kind,
+ *mkValHelper<CVC4::RegExpRepeat>(CVC4::RegExpRepeat(arg)).d_node);
break;
default:
CVC4_API_KIND_CHECK_EXPECTED(false, kind)
@@ -4079,55 +4502,55 @@ Op Solver::mkOp(Kind kind, uint32_t arg1, uint32_t arg2) const
kind,
*mkValHelper<CVC4::BitVectorExtract>(
CVC4::BitVectorExtract(arg1, arg2))
- .d_expr.get());
+ .d_node);
break;
case FLOATINGPOINT_TO_FP_IEEE_BITVECTOR:
res = Op(this,
kind,
*mkValHelper<CVC4::FloatingPointToFPIEEEBitVector>(
CVC4::FloatingPointToFPIEEEBitVector(arg1, arg2))
- .d_expr.get());
+ .d_node);
break;
case FLOATINGPOINT_TO_FP_FLOATINGPOINT:
res = Op(this,
kind,
*mkValHelper<CVC4::FloatingPointToFPFloatingPoint>(
CVC4::FloatingPointToFPFloatingPoint(arg1, arg2))
- .d_expr.get());
+ .d_node);
break;
case FLOATINGPOINT_TO_FP_REAL:
res = Op(this,
kind,
*mkValHelper<CVC4::FloatingPointToFPReal>(
CVC4::FloatingPointToFPReal(arg1, arg2))
- .d_expr.get());
+ .d_node);
break;
case FLOATINGPOINT_TO_FP_SIGNED_BITVECTOR:
res = Op(this,
kind,
*mkValHelper<CVC4::FloatingPointToFPSignedBitVector>(
CVC4::FloatingPointToFPSignedBitVector(arg1, arg2))
- .d_expr.get());
+ .d_node);
break;
case FLOATINGPOINT_TO_FP_UNSIGNED_BITVECTOR:
res = Op(this,
kind,
*mkValHelper<CVC4::FloatingPointToFPUnsignedBitVector>(
CVC4::FloatingPointToFPUnsignedBitVector(arg1, arg2))
- .d_expr.get());
+ .d_node);
break;
case FLOATINGPOINT_TO_FP_GENERIC:
res = Op(this,
kind,
*mkValHelper<CVC4::FloatingPointToFPGeneric>(
CVC4::FloatingPointToFPGeneric(arg1, arg2))
- .d_expr.get());
+ .d_node);
break;
case REGEXP_LOOP:
- res = Op(this,
- kind,
- *mkValHelper<CVC4::RegExpLoop>(CVC4::RegExpLoop(arg1, arg2))
- .d_expr.get());
+ res = Op(
+ this,
+ kind,
+ *mkValHelper<CVC4::RegExpLoop>(CVC4::RegExpLoop(arg1, arg2)).d_node);
break;
default:
CVC4_API_KIND_CHECK_EXPECTED(false, kind)
@@ -4145,10 +4568,11 @@ Op Solver::mkOp(Kind kind, uint32_t arg1, uint32_t arg2) const
Term Solver::simplify(const Term& term)
{
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
+ CVC4::ExprManagerScope exmgrs(*(d_exprMgr.get()));
CVC4_API_ARG_CHECK_NOT_NULL(term);
CVC4_API_SOLVER_CHECK_TERM(term);
- return Term(this, d_smtEngine->simplify(*term.d_expr));
+ return Term(this, d_smtEngine->simplify(term.d_node->toExpr()));
CVC4_API_SOLVER_TRY_CATCH_END;
}
@@ -4164,7 +4588,7 @@ Result Solver::checkEntailed(Term term) const
CVC4_API_ARG_CHECK_NOT_NULL(term);
CVC4_API_SOLVER_CHECK_TERM(term);
- CVC4::Result r = d_smtEngine->checkEntailed(*term.d_expr);
+ CVC4::Result r = d_smtEngine->checkEntailed(*term.d_node);
return Result(r);
CVC4_API_SOLVER_TRY_CATCH_END;
@@ -4184,7 +4608,7 @@ Result Solver::checkEntailed(const std::vector<Term>& terms) const
CVC4_API_ARG_CHECK_NOT_NULL(term);
}
- std::vector<Expr> exprs = termVectorToExprs(terms);
+ std::vector<Node> exprs = termVectorToNodes(terms);
CVC4::Result r = d_smtEngine->checkEntailed(exprs);
return Result(r);
@@ -4202,7 +4626,7 @@ void Solver::assertFormula(Term term) const
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
CVC4_API_SOLVER_CHECK_TERM(term);
CVC4_API_ARG_CHECK_NOT_NULL(term);
- d_smtEngine->assertFormula(Node::fromExpr(*term.d_expr));
+ d_smtEngine->assertFormula(*term.d_node);
CVC4_API_SOLVER_TRY_CATCH_END;
}
@@ -4234,7 +4658,7 @@ Result Solver::checkSatAssuming(Term assumption) const
<< "Cannot make multiple queries unless incremental solving is enabled "
"(try --incremental)";
CVC4_API_SOLVER_CHECK_TERM(assumption);
- CVC4::Result r = d_smtEngine->checkSat(*assumption.d_expr);
+ CVC4::Result r = d_smtEngine->checkSat(*assumption.d_node);
return Result(r);
CVC4_API_SOLVER_TRY_CATCH_END;
}
@@ -4255,7 +4679,7 @@ Result Solver::checkSatAssuming(const std::vector<Term>& assumptions) const
CVC4_API_SOLVER_CHECK_TERM(term);
CVC4_API_ARG_CHECK_NOT_NULL(term);
}
- std::vector<Expr> eassumptions = termVectorToExprs(assumptions);
+ std::vector<Node> eassumptions = termVectorToNodes(assumptions);
CVC4::Result r = d_smtEngine->checkSat(eassumptions);
return Result(r);
CVC4_API_SOLVER_TRY_CATCH_END;
@@ -4281,7 +4705,7 @@ Sort Solver::declareDatatype(
<< "datatype constructor declaration associated to this solver object";
dtdecl.addConstructor(ctors[i]);
}
- return Sort(this, d_exprMgr->mkDatatypeType(*dtdecl.d_dtype));
+ return Sort(this, getNodeManager()->mkDatatypeType(*dtdecl.d_dtype));
CVC4_API_SOLVER_TRY_CATCH_END;
}
@@ -4306,13 +4730,13 @@ Term Solver::declareFun(const std::string& symbol,
<< "first-class sort as function codomain sort";
CVC4_API_SOLVER_CHECK_SORT(sort);
Assert(!sort.isFunction()); /* A function sort is not first-class. */
- Type type = *sort.d_type;
+ TypeNode type = *sort.d_type;
if (!sorts.empty())
{
- std::vector<Type> types = sortVectorToTypes(sorts);
- type = d_exprMgr->mkFunctionType(types, type);
+ std::vector<TypeNode> types = sortVectorToTypeNodes(sorts);
+ type = getNodeManager()->mkFunctionType(types, type);
}
- return Term(this, d_exprMgr->mkVar(symbol, type));
+ return Term(this, d_exprMgr->mkVar(symbol, type.toType()));
CVC4_API_SOLVER_TRY_CATCH_END;
}
@@ -4322,8 +4746,11 @@ Term Solver::declareFun(const std::string& symbol,
Sort Solver::declareSort(const std::string& symbol, uint32_t arity) const
{
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
- if (arity == 0) return Sort(this, d_exprMgr->mkSort(symbol));
- return Sort(this, d_exprMgr->mkSortConstructor(symbol, arity));
+ if (arity == 0)
+ {
+ return Sort(this, getNodeManager()->mkSort(symbol));
+ }
+ return Sort(this, getNodeManager()->mkSortConstructor(symbol, arity));
CVC4_API_SOLVER_TRY_CATCH_END;
}
@@ -4339,19 +4766,19 @@ Term Solver::defineFun(const std::string& symbol,
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
CVC4_API_ARG_CHECK_EXPECTED(sort.isFirstClass(), sort)
<< "first-class sort as codomain sort for function sort";
- std::vector<Type> domain_types;
+ std::vector<TypeNode> domain_types;
for (size_t i = 0, size = bound_vars.size(); i < size; ++i)
{
CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
this == bound_vars[i].d_solver, "bound variable", bound_vars[i], i)
<< "bound variable associated to this solver object";
CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
- bound_vars[i].d_expr->getKind() == CVC4::Kind::BOUND_VARIABLE,
+ bound_vars[i].d_node->getKind() == CVC4::Kind::BOUND_VARIABLE,
"bound variable",
bound_vars[i],
i)
<< "a bound variable";
- CVC4::Type t = bound_vars[i].d_expr->getType();
+ CVC4::TypeNode t = bound_vars[i].d_node->getType();
CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
t.isFirstClass(), "sort of parameter", bound_vars[i], i)
<< "first-class sort of parameter of defined function";
@@ -4361,14 +4788,15 @@ Term Solver::defineFun(const std::string& symbol,
CVC4_API_CHECK(sort == term.getSort())
<< "Invalid sort of function body '" << term << "', expected '" << sort
<< "'";
- Type type = *sort.d_type;
+ NodeManager* nm = getNodeManager();
+ TypeNode type = *sort.d_type;
if (!domain_types.empty())
{
- type = d_exprMgr->mkFunctionType(domain_types, type);
+ type = nm->mkFunctionType(domain_types, type);
}
- Expr fun = d_exprMgr->mkVar(symbol, type);
- std::vector<Expr> ebound_vars = termVectorToExprs(bound_vars);
- d_smtEngine->defineFunction(fun, ebound_vars, *term.d_expr, global);
+ Node fun = Node::fromExpr(d_exprMgr->mkVar(symbol, type.toType()));
+ std::vector<Node> ebound_vars = termVectorToNodes(bound_vars);
+ d_smtEngine->defineFunction(fun, ebound_vars, *term.d_node, global);
return Term(this, fun);
CVC4_API_SOLVER_TRY_CATCH_END;
}
@@ -4392,7 +4820,7 @@ Term Solver::defineFun(Term fun,
this == bound_vars[i].d_solver, "bound variable", bound_vars[i], i)
<< "bound variable associated to this solver object";
CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
- bound_vars[i].d_expr->getKind() == CVC4::Kind::BOUND_VARIABLE,
+ bound_vars[i].d_node->getKind() == CVC4::Kind::BOUND_VARIABLE,
"bound variable",
bound_vars[i],
i)
@@ -4417,8 +4845,8 @@ Term Solver::defineFun(Term fun,
CVC4_API_SOLVER_CHECK_TERM(term);
- std::vector<Expr> ebound_vars = termVectorToExprs(bound_vars);
- d_smtEngine->defineFunction(*fun.d_expr, ebound_vars, *term.d_expr, global);
+ std::vector<Node> ebound_vars = termVectorToNodes(bound_vars);
+ d_smtEngine->defineFunction(*fun.d_node, ebound_vars, *term.d_node, global);
return fun;
CVC4_API_SOLVER_TRY_CATCH_END;
}
@@ -4432,6 +4860,7 @@ Term Solver::defineFunRec(const std::string& symbol,
Term term,
bool global) const
{
+ NodeManagerScope scope(getNodeManager());
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
CVC4_API_CHECK(d_smtEngine->getUserLogicInfo().isQuantified())
@@ -4444,19 +4873,19 @@ Term Solver::defineFunRec(const std::string& symbol,
CVC4_API_ARG_CHECK_EXPECTED(sort.isFirstClass(), sort)
<< "first-class sort as function codomain sort";
Assert(!sort.isFunction()); /* A function sort is not first-class. */
- std::vector<Type> domain_types;
+ std::vector<TypeNode> domain_types;
for (size_t i = 0, size = bound_vars.size(); i < size; ++i)
{
CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
this == bound_vars[i].d_solver, "bound variable", bound_vars[i], i)
<< "bound variable associated to this solver object";
CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
- bound_vars[i].d_expr->getKind() == CVC4::Kind::BOUND_VARIABLE,
+ bound_vars[i].d_node->getKind() == CVC4::Kind::BOUND_VARIABLE,
"bound variable",
bound_vars[i],
i)
<< "a bound variable";
- CVC4::Type t = bound_vars[i].d_expr->getType();
+ CVC4::TypeNode t = bound_vars[i].d_node->getType();
CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
t.isFirstClass(), "sort of parameter", bound_vars[i], i)
<< "first-class sort of parameter of defined function";
@@ -4467,14 +4896,16 @@ Term Solver::defineFunRec(const std::string& symbol,
<< "Invalid sort of function body '" << term << "', expected '" << sort
<< "'";
CVC4_API_SOLVER_CHECK_TERM(term);
- Type type = *sort.d_type;
+ NodeManager* nm = getNodeManager();
+ TypeNode type = *sort.d_type;
if (!domain_types.empty())
{
- type = d_exprMgr->mkFunctionType(domain_types, type);
+ type = nm->mkFunctionType(domain_types, type);
}
- Expr fun = d_exprMgr->mkVar(symbol, type);
- std::vector<Expr> ebound_vars = termVectorToExprs(bound_vars);
- d_smtEngine->defineFunctionRec(fun, ebound_vars, *term.d_expr, global);
+ Node fun = Node::fromExpr(d_exprMgr->mkVar(symbol, type.toType()));
+ std::vector<Node> ebound_vars = termVectorToNodes(bound_vars);
+ d_smtEngine->defineFunctionRec(
+ fun, ebound_vars, term.d_node->toExpr(), global);
return Term(this, fun);
CVC4_API_SOLVER_TRY_CATCH_END;
}
@@ -4484,6 +4915,7 @@ Term Solver::defineFunRec(Term fun,
Term term,
bool global) const
{
+ NodeManagerScope scope(getNodeManager());
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
CVC4_API_CHECK(d_smtEngine->getUserLogicInfo().isQuantified())
@@ -4505,7 +4937,7 @@ Term Solver::defineFunRec(Term fun,
this == bound_vars[i].d_solver, "bound variable", bound_vars[i], i)
<< "bound variable associated to this solver object";
CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
- bound_vars[i].d_expr->getKind() == CVC4::Kind::BOUND_VARIABLE,
+ bound_vars[i].d_node->getKind() == CVC4::Kind::BOUND_VARIABLE,
"bound variable",
bound_vars[i],
i)
@@ -4529,9 +4961,9 @@ Term Solver::defineFunRec(Term fun,
}
CVC4_API_SOLVER_CHECK_TERM(term);
- std::vector<Expr> ebound_vars = termVectorToExprs(bound_vars);
+ std::vector<Node> ebound_vars = termVectorToNodes(bound_vars);
d_smtEngine->defineFunctionRec(
- *fun.d_expr, ebound_vars, *term.d_expr, global);
+ *fun.d_node, ebound_vars, *term.d_node, global);
return fun;
CVC4_API_SOLVER_TRY_CATCH_END;
}
@@ -4544,6 +4976,7 @@ void Solver::defineFunsRec(const std::vector<Term>& funs,
const std::vector<Term>& terms,
bool global) const
{
+ NodeManagerScope scope(getNodeManager());
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
CVC4_API_CHECK(d_smtEngine->getUserLogicInfo().isQuantified())
@@ -4581,7 +5014,7 @@ void Solver::defineFunsRec(const std::vector<Term>& funs,
this == bvars[k].d_solver, "bound variable", bvars[k], k)
<< "bound variable associated to this solver object";
CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
- bvars[k].d_expr->getKind() == CVC4::Kind::BOUND_VARIABLE,
+ bvars[k].d_node->getKind() == CVC4::Kind::BOUND_VARIABLE,
"bound variable",
bvars[k],
k)
@@ -4606,13 +5039,13 @@ void Solver::defineFunsRec(const std::vector<Term>& funs,
<< "function or nullary symbol";
}
}
- std::vector<Expr> efuns = termVectorToExprs(funs);
- std::vector<std::vector<Expr>> ebound_vars;
+ std::vector<Node> efuns = termVectorToNodes(funs);
+ std::vector<std::vector<Node>> ebound_vars;
for (const auto& v : bound_vars)
{
- ebound_vars.push_back(termVectorToExprs(v));
+ ebound_vars.push_back(termVectorToNodes(v));
}
- std::vector<Expr> exprs = termVectorToExprs(terms);
+ std::vector<Node> exprs = termVectorToNodes(terms);
d_smtEngine->defineFunctionsRec(efuns, ebound_vars, exprs, global);
CVC4_API_SOLVER_TRY_CATCH_END;
}
@@ -4631,12 +5064,12 @@ void Solver::echo(std::ostream& out, const std::string& str) const
std::vector<Term> Solver::getAssertions(void) const
{
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
- std::vector<Expr> assertions = d_smtEngine->getAssertions();
+ std::vector<Node> assertions = d_smtEngine->getAssertions();
/* Can not use
* return std::vector<Term>(assertions.begin(), assertions.end());
* here since constructor is private */
std::vector<Term> res;
- for (const Expr& e : assertions)
+ for (const Node& e : assertions)
{
res.push_back(Term(this, e));
}
@@ -4645,26 +5078,6 @@ std::vector<Term> Solver::getAssertions(void) const
}
/**
- * ( get-assignment )
- */
-std::vector<std::pair<Term, Term>> Solver::getAssignment(void) const
-{
- CVC4_API_SOLVER_TRY_CATCH_BEGIN;
- CVC4::ExprManagerScope exmgrs(*(d_exprMgr.get()));
- CVC4_API_CHECK(d_smtEngine->getOptions()[options::produceAssignments])
- << "Cannot get assignment unless assignment generation is enabled "
- "(try --produce-assignments)";
- std::vector<std::pair<Expr, Expr>> assignment = d_smtEngine->getAssignment();
- std::vector<std::pair<Term, Term>> res;
- for (const auto& p : assignment)
- {
- res.emplace_back(Term(this, p.first), Term(this, p.second));
- }
- return res;
- CVC4_API_SOLVER_TRY_CATCH_END;
-}
-
-/**
* ( get-info <info_flag> )
*/
std::string Solver::getInfo(const std::string& flag) const
@@ -4701,18 +5114,17 @@ std::vector<Term> Solver::getUnsatAssumptions(void) const
CVC4_API_CHECK(d_smtEngine->getOptions()[options::unsatAssumptions])
<< "Cannot get unsat assumptions unless explicitly enabled "
"(try --produce-unsat-assumptions)";
- CVC4_API_CHECK(d_smtEngine->getSmtMode()
- == SmtEngine::SmtMode::SMT_MODE_UNSAT)
+ CVC4_API_CHECK(d_smtEngine->getSmtMode() == SmtMode::UNSAT)
<< "Cannot get unsat assumptions unless in unsat mode.";
- std::vector<Expr> uassumptions = d_smtEngine->getUnsatAssumptions();
+ std::vector<Node> uassumptions = d_smtEngine->getUnsatAssumptions();
/* Can not use
* return std::vector<Term>(uassumptions.begin(), uassumptions.end());
* here since constructor is private */
std::vector<Term> res;
- for (const Expr& e : uassumptions)
+ for (const Node& e : uassumptions)
{
- res.push_back(Term(this, e));
+ res.push_back(Term(this, e.toExpr()));
}
return res;
CVC4_API_SOLVER_TRY_CATCH_END;
@@ -4728,15 +5140,14 @@ std::vector<Term> Solver::getUnsatCore(void) const
CVC4_API_CHECK(d_smtEngine->getOptions()[options::unsatCores])
<< "Cannot get unsat core unless explicitly enabled "
"(try --produce-unsat-cores)";
- CVC4_API_CHECK(d_smtEngine->getSmtMode()
- == SmtEngine::SmtMode::SMT_MODE_UNSAT)
+ CVC4_API_RECOVERABLE_CHECK(d_smtEngine->getSmtMode() == SmtMode::UNSAT)
<< "Cannot get unsat core unless in unsat mode.";
UnsatCore core = d_smtEngine->getUnsatCore();
/* Can not use
* return std::vector<Term>(core.begin(), core.end());
* here since constructor is private */
std::vector<Term> res;
- for (const Expr& e : core)
+ for (const Node& e : core)
{
res.push_back(Term(this, e));
}
@@ -4751,7 +5162,7 @@ Term Solver::getValue(Term term) const
{
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
CVC4_API_SOLVER_CHECK_TERM(term);
- return Term(this, d_smtEngine->getValue(*term.d_expr));
+ return getValueHelper(term);
CVC4_API_SOLVER_TRY_CATCH_END;
}
@@ -4762,12 +5173,11 @@ std::vector<Term> Solver::getValue(const std::vector<Term>& terms) const
{
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
CVC4::ExprManagerScope exmgrs(*(d_exprMgr.get()));
- CVC4_API_CHECK(d_smtEngine->getOptions()[options::produceModels])
+ CVC4_API_RECOVERABLE_CHECK(d_smtEngine->getOptions()[options::produceModels])
<< "Cannot get value unless model generation is enabled "
"(try --produce-models)";
- CVC4_API_CHECK(d_smtEngine->getSmtMode()
- != SmtEngine::SmtMode::SMT_MODE_UNSAT)
- << "Cannot get value when in unsat mode.";
+ CVC4_API_RECOVERABLE_CHECK(d_smtEngine->isSmtModeSat())
+ << "Cannot get value unless after a SAT or unknown response.";
std::vector<Term> res;
for (size_t i = 0, n = terms.size(); i < n; ++i)
{
@@ -4775,12 +5185,45 @@ std::vector<Term> Solver::getValue(const std::vector<Term>& terms) const
this == terms[i].d_solver, "term", terms[i], i)
<< "term associated to this solver object";
/* Can not use emplace_back here since constructor is private. */
- res.push_back(Term(this, d_smtEngine->getValue(*terms[i].d_expr)));
+ res.push_back(getValueHelper(terms[i]));
}
return res;
CVC4_API_SOLVER_TRY_CATCH_END;
}
+Term Solver::getQuantifierElimination(api::Term q) const
+{
+ CVC4_API_SOLVER_TRY_CATCH_BEGIN;
+ CVC4_API_ARG_CHECK_NOT_NULL(q);
+ CVC4_API_SOLVER_CHECK_TERM(q);
+ CVC4::ExprManagerScope exmgrs(*(d_exprMgr.get()));
+ return Term(this,
+ d_smtEngine->getQuantifierElimination(q.getNode(), true, true));
+ CVC4_API_SOLVER_TRY_CATCH_END;
+}
+
+Term Solver::getQuantifierEliminationDisjunct(api::Term q) const
+{
+ CVC4_API_SOLVER_TRY_CATCH_BEGIN;
+ CVC4_API_ARG_CHECK_NOT_NULL(q);
+ CVC4_API_SOLVER_CHECK_TERM(q);
+ CVC4::ExprManagerScope exmgrs(*(d_exprMgr.get()));
+ return Term(
+ this, d_smtEngine->getQuantifierElimination(q.getNode(), false, true));
+ CVC4_API_SOLVER_TRY_CATCH_END;
+}
+
+void Solver::declareSeparationHeap(api::Sort locSort, api::Sort dataSort) const
+{
+ CVC4_API_SOLVER_TRY_CATCH_BEGIN;
+ CVC4_API_CHECK(
+ d_smtEngine->getLogicInfo().isTheoryEnabled(theory::THEORY_SEP))
+ << "Cannot obtain separation logic expressions if not using the "
+ "separation logic theory.";
+ d_smtEngine->declareSepHeap(locSort.getTypeNode(), dataSort.getTypeNode());
+ CVC4_API_SOLVER_TRY_CATCH_END;
+}
+
Term Solver::getSeparationHeap() const
{
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
@@ -4792,16 +5235,8 @@ Term Solver::getSeparationHeap() const
CVC4_API_CHECK(d_smtEngine->getOptions()[options::produceModels])
<< "Cannot get separation heap term unless model generation is enabled "
"(try --produce-models)";
- CVC4_API_CHECK(d_smtEngine->getSmtMode()
- != SmtEngine::SmtMode::SMT_MODE_UNSAT)
- << "Cannot get separtion heap term when in unsat mode.";
-
- theory::TheoryModel* m =
- d_smtEngine->getAvailableModel("get separation logic heap and nil");
- Expr heap, nil;
- bool hasHeapModel = m->getHeapModel(heap, nil);
- CVC4_API_CHECK(hasHeapModel)
- << "Failed to obtain heap term from theory model.";
+ CVC4_API_RECOVERABLE_CHECK(d_smtEngine->isSmtModeSat())
+ << "Can only get separtion heap term after sat or unknown response.";
return Term(this, d_smtEngine->getSepHeapExpr());
CVC4_API_SOLVER_TRY_CATCH_END;
}
@@ -4817,17 +5252,9 @@ Term Solver::getSeparationNilTerm() const
CVC4_API_CHECK(d_smtEngine->getOptions()[options::produceModels])
<< "Cannot get separation nil term unless model generation is enabled "
"(try --produce-models)";
- CVC4_API_CHECK(d_smtEngine->getSmtMode()
- != SmtEngine::SmtMode::SMT_MODE_UNSAT)
- << "Cannot get separtion nil term when in unsat mode.";
-
- theory::TheoryModel* m =
- d_smtEngine->getAvailableModel("get separation logic heap and nil");
- Expr heap, nil;
- bool hasHeapModel = m->getHeapModel(heap, nil);
- CVC4_API_CHECK(hasHeapModel)
- << "Failed to obtain nil term from theory model.";
- return Term(this, nil);
+ CVC4_API_RECOVERABLE_CHECK(d_smtEngine->isSmtModeSat())
+ << "Can only get separtion nil term after sat or unknown response.";
+ return Term(this, d_smtEngine->getSepNilExpr());
CVC4_API_SOLVER_TRY_CATCH_END;
}
@@ -4854,39 +5281,103 @@ void Solver::pop(uint32_t nscopes) const
bool Solver::getInterpolant(Term conj, Term& output) const
{
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
- Expr result;
- bool success = d_smtEngine->getInterpol(*conj.d_expr, result);
- if (success) {
- output = Term(output.d_solver, result);
+ CVC4::ExprManagerScope exmgrs(*(d_exprMgr.get()));
+ Node result;
+ bool success = d_smtEngine->getInterpol(*conj.d_node, result);
+ if (success)
+ {
+ output = Term(this, result);
+ }
+ return success;
+ CVC4_API_SOLVER_TRY_CATCH_END;
+}
+
+bool Solver::getInterpolant(Term conj, Grammar& g, Term& output) const
+{
+ CVC4_API_SOLVER_TRY_CATCH_BEGIN;
+ CVC4::ExprManagerScope exmgrs(*(d_exprMgr.get()));
+ Node result;
+ bool success =
+ d_smtEngine->getInterpol(*conj.d_node, *g.resolve().d_type, result);
+ if (success)
+ {
+ output = Term(this, result);
+ }
+ return success;
+ CVC4_API_SOLVER_TRY_CATCH_END;
+}
+
+bool Solver::getAbduct(Term conj, Term& output) const
+{
+ CVC4_API_SOLVER_TRY_CATCH_BEGIN;
+ CVC4::ExprManagerScope exmgrs(*(d_exprMgr.get()));
+ Node result;
+ bool success = d_smtEngine->getAbduct(*conj.d_node, result);
+ if (success)
+ {
+ output = Term(this, result);
}
return success;
CVC4_API_SOLVER_TRY_CATCH_END;
}
-bool Solver::getInterpolant(Term conj, const Type& gtype, Term& output) const
+bool Solver::getAbduct(Term conj, Grammar& g, Term& output) const
{
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
- Expr result;
- bool success = d_smtEngine->getInterpol(*conj.d_expr, gtype, result);
+ CVC4::ExprManagerScope exmgrs(*(d_exprMgr.get()));
+ Node result;
+ bool success =
+ d_smtEngine->getAbduct(*conj.d_node, *g.resolve().d_type, result);
if (success)
{
- output = Term(output.d_solver, result);
+ output = Term(this, result);
}
return success;
CVC4_API_SOLVER_TRY_CATCH_END;
}
-void Solver::printModel(std::ostream& out) const
+void Solver::blockModel() const
{
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
CVC4::ExprManagerScope exmgrs(*(d_exprMgr.get()));
CVC4_API_CHECK(d_smtEngine->getOptions()[options::produceModels])
<< "Cannot get value unless model generation is enabled "
"(try --produce-models)";
- CVC4_API_CHECK(d_smtEngine->getSmtMode()
- != SmtEngine::SmtMode::SMT_MODE_UNSAT)
- << "Cannot get value when in unsat mode.";
- out << *d_smtEngine->getModel();
+ CVC4_API_RECOVERABLE_CHECK(d_smtEngine->isSmtModeSat())
+ << "Can only block model after sat or unknown response.";
+ d_smtEngine->blockModel();
+ CVC4_API_SOLVER_TRY_CATCH_END;
+}
+
+void Solver::blockModelValues(const std::vector<Term>& terms) const
+{
+ CVC4_API_SOLVER_TRY_CATCH_BEGIN;
+ CVC4_API_CHECK(d_smtEngine->getOptions()[options::produceModels])
+ << "Cannot get value unless model generation is enabled "
+ "(try --produce-models)";
+ CVC4_API_RECOVERABLE_CHECK(d_smtEngine->isSmtModeSat())
+ << "Can only block model values after sat or unknown response.";
+ CVC4_API_ARG_SIZE_CHECK_EXPECTED(!terms.empty(), terms)
+ << "a non-empty set of terms";
+ for (size_t i = 0, tsize = terms.size(); i < tsize; ++i)
+ {
+ CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
+ !terms[i].isNull(), "term", terms[i], i)
+ << "a non-null term";
+ CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
+ this == terms[i].d_solver, "term", terms[i], i)
+ << "a term associated to this solver object";
+ }
+ CVC4::ExprManagerScope exmgrs(*(d_exprMgr.get()));
+ d_smtEngine->blockModelValues(termVectorToNodes(terms));
+ CVC4_API_SOLVER_TRY_CATCH_END;
+}
+
+void Solver::printInstantiations(std::ostream& out) const
+{
+ CVC4_API_SOLVER_TRY_CATCH_BEGIN;
+ CVC4::ExprManagerScope exmgrs(*(d_exprMgr.get()));
+ d_smtEngine->printInstantiations(out);
CVC4_API_SOLVER_TRY_CATCH_END;
}
@@ -4995,7 +5486,7 @@ Term Solver::ensureTermSort(const Term& term, const Sort& sort) const
// in the theory.
res = Term(this,
d_exprMgr->mkExpr(extToIntKind(DIVISION),
- *res.d_expr,
+ res.d_node->toExpr(),
d_exprMgr->mkConst(CVC4::Rational(1))));
}
Assert(res.getSort() == sort);
@@ -5008,7 +5499,7 @@ Term Solver::mkSygusVar(Sort sort, const std::string& symbol) const
CVC4_API_ARG_CHECK_NOT_NULL(sort);
CVC4_API_SOLVER_CHECK_SORT(sort);
- Expr res = d_exprMgr->mkBoundVar(symbol, *sort.d_type);
+ Node res = getNodeManager()->mkBoundVar(symbol, *sort.d_type);
(void)res.getType(true); /* kick off type checking */
d_smtEngine->declareSygusVar(symbol, res, *sort.d_type);
@@ -5023,7 +5514,7 @@ Grammar Solver::mkSygusGrammar(const std::vector<Term>& boundVars,
{
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
CVC4_API_ARG_SIZE_CHECK_EXPECTED(!ntSymbols.empty(), ntSymbols)
- << "non-empty vector";
+ << "a non-empty vector";
for (size_t i = 0, n = boundVars.size(); i < n; ++i)
{
@@ -5031,30 +5522,30 @@ Grammar Solver::mkSygusGrammar(const std::vector<Term>& boundVars,
this == boundVars[i].d_solver, "bound variable", boundVars[i], i)
<< "bound variable associated to this solver object";
CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
- boundVars[i].d_expr->getKind() == CVC4::Kind::BOUND_VARIABLE,
+ !boundVars[i].isNull(), "bound variable", boundVars[i], i)
+ << "a non-null term";
+ CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
+ boundVars[i].d_node->getKind() == CVC4::Kind::BOUND_VARIABLE,
"bound variable",
boundVars[i],
i)
<< "a bound variable";
- CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
- !boundVars[i].isNull(), "parameter term", boundVars[i], i)
- << "non-null term";
}
for (size_t i = 0, n = ntSymbols.size(); i < n; ++i)
{
CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
- this == ntSymbols[i].d_solver, "term", ntSymbols[i], i)
+ this == ntSymbols[i].d_solver, "non-terminal", ntSymbols[i], i)
<< "term associated to this solver object";
CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
- ntSymbols[i].d_expr->getKind() == CVC4::Kind::BOUND_VARIABLE,
- "bound variable",
+ !ntSymbols[i].isNull(), "non-terminal", ntSymbols[i], i)
+ << "a non-null term";
+ CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
+ ntSymbols[i].d_node->getKind() == CVC4::Kind::BOUND_VARIABLE,
+ "non-terminal",
ntSymbols[i],
i)
<< "a bound variable";
- CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
- !ntSymbols[i].isNull(), "parameter term", ntSymbols[i], i)
- << "non-null term";
}
return Grammar(this, boundVars, ntSymbols);
@@ -5080,7 +5571,7 @@ Term Solver::synthInv(const std::string& symbol,
const std::vector<Term>& boundVars) const
{
return synthFunHelper(
- symbol, boundVars, Sort(this, d_exprMgr->booleanType()), true);
+ symbol, boundVars, Sort(this, getNodeManager()->booleanType()), true);
}
Term Solver::synthInv(const std::string& symbol,
@@ -5088,7 +5579,7 @@ Term Solver::synthInv(const std::string& symbol,
Grammar& g) const
{
return synthFunHelper(
- symbol, boundVars, Sort(this, d_exprMgr->booleanType()), true, &g);
+ symbol, boundVars, Sort(this, getNodeManager()->booleanType()), true, &g);
}
Term Solver::synthFunHelper(const std::string& symbol,
@@ -5100,47 +5591,43 @@ Term Solver::synthFunHelper(const std::string& symbol,
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
CVC4_API_ARG_CHECK_NOT_NULL(sort);
- CVC4_API_ARG_CHECK_EXPECTED(sort.d_type->isFirstClass(), sort)
- << "first-class sort as codomain sort for function sort";
-
- std::vector<Type> varTypes;
+ std::vector<TypeNode> varTypes;
for (size_t i = 0, n = boundVars.size(); i < n; ++i)
{
CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
this == boundVars[i].d_solver, "bound variable", boundVars[i], i)
<< "bound variable associated to this solver object";
CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
- boundVars[i].d_expr->getKind() == CVC4::Kind::BOUND_VARIABLE,
+ !boundVars[i].isNull(), "bound variable", boundVars[i], i)
+ << "a non-null term";
+ CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
+ boundVars[i].d_node->getKind() == CVC4::Kind::BOUND_VARIABLE,
"bound variable",
boundVars[i],
i)
<< "a bound variable";
- CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
- !boundVars[i].isNull(), "parameter term", boundVars[i], i)
- << "non-null term";
- varTypes.push_back(boundVars[i].d_expr->getType());
+ varTypes.push_back(boundVars[i].d_node->getType());
}
CVC4_API_SOLVER_CHECK_SORT(sort);
if (g != nullptr)
{
- CVC4_API_CHECK(g->d_ntSyms[0].d_expr->getType() == *sort.d_type)
+ CVC4_API_CHECK(g->d_ntSyms[0].d_node->getType() == *sort.d_type)
<< "Invalid Start symbol for Grammar g, Expected Start's sort to be "
- << *sort.d_type;
+ << *sort.d_type << " but found " << g->d_ntSyms[0].d_node->getType();
}
- Type funType = varTypes.empty()
- ? *sort.d_type
- : d_exprMgr->mkFunctionType(varTypes, *sort.d_type);
+ TypeNode funType = varTypes.empty() ? *sort.d_type
+ : getNodeManager()->mkFunctionType(
+ varTypes, *sort.d_type);
- Expr fun = d_exprMgr->mkBoundVar(symbol, funType);
+ Node fun = getNodeManager()->mkBoundVar(symbol, funType);
(void)fun.getType(true); /* kick off type checking */
- d_smtEngine->declareSynthFun(symbol,
- fun,
- g == nullptr ? funType : *g->resolve().d_type,
- isInv,
- termVectorToExprs(boundVars));
+ std::vector<Node> bvns = termVectorToNodes(boundVars);
+
+ d_smtEngine->declareSynthFun(
+ symbol, fun, g == nullptr ? funType : *g->resolve().d_type, isInv, bvns);
return Term(this, fun);
@@ -5150,13 +5637,14 @@ Term Solver::synthFunHelper(const std::string& symbol,
void Solver::addSygusConstraint(Term term) const
{
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
+ NodeManagerScope scope(getNodeManager());
CVC4_API_ARG_CHECK_NOT_NULL(term);
CVC4_API_SOLVER_CHECK_TERM(term);
CVC4_API_ARG_CHECK_EXPECTED(
- term.d_expr->getType() == d_exprMgr->booleanType(), term)
+ term.d_node->getType() == getNodeManager()->booleanType(), term)
<< "boolean term";
- d_smtEngine->assertSygusConstraint(*term.d_expr);
+ d_smtEngine->assertSygusConstraint(*term.d_node);
CVC4_API_SOLVER_TRY_CATCH_END;
}
@@ -5175,24 +5663,24 @@ void Solver::addSygusInvConstraint(Term inv,
CVC4_API_ARG_CHECK_NOT_NULL(post);
CVC4_API_SOLVER_CHECK_TERM(post);
- CVC4_API_ARG_CHECK_EXPECTED(inv.d_expr->getType().isFunction(), inv)
+ CVC4_API_ARG_CHECK_EXPECTED(inv.d_node->getType().isFunction(), inv)
<< "a function";
- FunctionType invType = inv.d_expr->getType();
+ TypeNode invType = inv.d_node->getType();
CVC4_API_ARG_CHECK_EXPECTED(invType.getRangeType().isBoolean(), inv)
<< "boolean range";
- CVC4_API_CHECK(pre.d_expr->getType() == invType)
+ CVC4_API_CHECK(pre.d_node->getType() == invType)
<< "Expected inv and pre to have the same sort";
- CVC4_API_CHECK(post.d_expr->getType() == invType)
+ CVC4_API_CHECK(post.d_node->getType() == invType)
<< "Expected inv and post to have the same sort";
- const std::vector<Type>& invArgTypes = invType.getArgTypes();
+ const std::vector<TypeNode>& invArgTypes = invType.getArgTypes();
- std::vector<Type> expectedTypes;
- expectedTypes.reserve(2 * invType.getArity() + 1);
+ std::vector<TypeNode> expectedTypes;
+ expectedTypes.reserve(2 * invArgTypes.size() + 1);
for (size_t i = 0, n = invArgTypes.size(); i < 2 * n; i += 2)
{
@@ -5201,13 +5689,13 @@ void Solver::addSygusInvConstraint(Term inv,
}
expectedTypes.push_back(invType.getRangeType());
- FunctionType expectedTransType = d_exprMgr->mkFunctionType(expectedTypes);
+ TypeNode expectedTransType = getNodeManager()->mkFunctionType(expectedTypes);
- CVC4_API_CHECK(trans.d_expr->getType() == expectedTransType)
+ CVC4_API_CHECK(trans.d_node->getType() == expectedTransType)
<< "Expected trans's sort to be " << invType;
d_smtEngine->assertSygusInvConstraint(
- *inv.d_expr, *pre.d_expr, *trans.d_expr, *post.d_expr);
+ *inv.d_node, *pre.d_node, *trans.d_node, *post.d_node);
CVC4_API_SOLVER_TRY_CATCH_END;
}
@@ -5224,12 +5712,12 @@ Term Solver::getSynthSolution(Term term) const
CVC4_API_ARG_CHECK_NOT_NULL(term);
CVC4_API_SOLVER_CHECK_TERM(term);
- std::map<CVC4::Expr, CVC4::Expr> map;
+ std::map<CVC4::Node, CVC4::Node> map;
CVC4_API_CHECK(d_smtEngine->getSynthSolutions(map))
- << "The solver is not in a state immediately preceeded by a "
+ << "The solver is not in a state immediately preceded by a "
"successful call to checkSynth";
- std::map<CVC4::Expr, CVC4::Expr>::const_iterator it = map.find(*term.d_expr);
+ std::map<CVC4::Node, CVC4::Node>::const_iterator it = map.find(*term.d_node);
CVC4_API_CHECK(it != map.cend()) << "Synth solution not found for given term";
@@ -5253,9 +5741,9 @@ std::vector<Term> Solver::getSynthSolutions(
<< "non-null term";
}
- std::map<CVC4::Expr, CVC4::Expr> map;
+ std::map<CVC4::Node, CVC4::Node> map;
CVC4_API_CHECK(d_smtEngine->getSynthSolutions(map))
- << "The solver is not in a state immediately preceeded by a "
+ << "The solver is not in a state immediately preceded by a "
"successful call to checkSynth";
std::vector<Term> synthSolution;
@@ -5263,8 +5751,8 @@ std::vector<Term> Solver::getSynthSolutions(
for (size_t i = 0, n = terms.size(); i < n; ++i)
{
- std::map<CVC4::Expr, CVC4::Expr>::const_iterator it =
- map.find(*terms[i].d_expr);
+ std::map<CVC4::Node, CVC4::Node>::const_iterator it =
+ map.find(*terms[i].d_node);
CVC4_API_CHECK(it != map.cend())
<< "Synth solution not found for term at index " << i;
@@ -5293,6 +5781,15 @@ ExprManager* Solver::getExprManager(void) const { return d_exprMgr.get(); }
* !!! This is only temporarily available until the parser is fully migrated to
* the new API. !!!
*/
+NodeManager* Solver::getNodeManager(void) const
+{
+ return d_exprMgr->getNodeManager();
+}
+
+/**
+ * !!! This is only temporarily available until the parser is fully migrated to
+ * the new API. !!!
+ */
SmtEngine* Solver::getSmtEngine(void) const { return d_smtEngine.get(); }
/**
@@ -5315,22 +5812,42 @@ std::vector<Expr> termVectorToExprs(const std::vector<Term>& terms)
return exprs;
}
+std::vector<Node> termVectorToNodes(const std::vector<Term>& terms)
+{
+ std::vector<Node> res;
+ for (const Term& t : terms)
+ {
+ res.push_back(t.getNode());
+ }
+ return res;
+}
+
std::vector<Type> sortVectorToTypes(const std::vector<Sort>& sorts)
{
std::vector<Type> types;
for (size_t i = 0, ssize = sorts.size(); i < ssize; i++)
{
- types.push_back(sorts[i].getType());
+ types.push_back(sorts[i].getTypeNode().toType());
}
return types;
}
-std::set<Type> sortSetToTypes(const std::set<Sort>& sorts)
+std::vector<TypeNode> sortVectorToTypeNodes(const std::vector<Sort>& sorts)
{
- std::set<Type> types;
+ std::vector<TypeNode> typeNodes;
+ for (const Sort& sort : sorts)
+ {
+ typeNodes.push_back(sort.getTypeNode());
+ }
+ return typeNodes;
+}
+
+std::set<TypeNode> sortSetToTypeNodes(const std::set<Sort>& sorts)
+{
+ std::set<TypeNode> types;
for (const Sort& s : sorts)
{
- types.insert(s.getType());
+ types.insert(s.getTypeNode());
}
return types;
}
@@ -5352,6 +5869,16 @@ std::vector<Sort> typeVectorToSorts(const Solver* slv,
std::vector<Sort> sorts;
for (size_t i = 0, tsize = types.size(); i < tsize; i++)
{
+ sorts.push_back(Sort(slv, TypeNode::fromType(types[i])));
+ }
+ return sorts;
+}
+std::vector<Sort> typeNodeVectorToSorts(const Solver* slv,
+ const std::vector<TypeNode>& types)
+{
+ std::vector<Sort> sorts;
+ for (size_t i = 0, tsize = types.size(); i < tsize; i++)
+ {
sorts.push_back(Sort(slv, types[i]));
}
return sorts;
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback