summaryrefslogtreecommitdiff
path: root/src/api
diff options
context:
space:
mode:
authormakaimann <makaim@stanford.edu>2019-08-11 09:07:31 -0700
committerGitHub <noreply@github.com>2019-08-11 09:07:31 -0700
commit942f66a8b9dd92cb7c1ba72e6a521e86a1a7e341 (patch)
treeadb50522a04454c1112169331c3edce6d8e66cb6 /src/api
parent03a99a427eaa8c679ede508e11561467a2291334 (diff)
New C++ API: Add templated getIndices method for OpTerm (#3073)
* Implement templated getIndices method for OpTerm * Add getIndices unit tests * Update src/api/cvc4cpp.cpp Co-Authored-By: Aina Niemetz <aina.niemetz@gmail.com> * Update src/api/cvc4cpp.cpp Co-Authored-By: Aina Niemetz <aina.niemetz@gmail.com> * Add comment about DIVISIBLE_OP * Update test/unit/api/opterm_black.h Co-Authored-By: Aina Niemetz <aina.niemetz@gmail.com> * Update test/unit/api/opterm_black.h Co-Authored-By: Aina Niemetz <aina.niemetz@gmail.com> * Update test/unit/api/opterm_black.h Co-Authored-By: Aina Niemetz <aina.niemetz@gmail.com> * Update test/unit/api/opterm_black.h Co-Authored-By: Aina Niemetz <aina.niemetz@gmail.com> * Add exception checks to other unit tests (instead of having its own function) * Fix unit test names in opterm_black.h * Add description to docstring for getIndices * Formatting * Clang format older commits * Use '-' in docstring list to match other docstrings * Support creating DIVISIBLE_OP with a string (for arbitrary precision integers) * Move mkOpTerm(DIVISIBLE_OP, <str>) test to solver_black.h * Fix pointer access * Replace switch statement with if statement * Guard string input for CVC4::Integer in mkOpTerm for consistency on GMP/CLN back-end
Diffstat (limited to 'src/api')
-rw-r--r--src/api/cvc4cpp.cpp162
-rw-r--r--src/api/cvc4cpp.h14
2 files changed, 172 insertions, 4 deletions
diff --git a/src/api/cvc4cpp.cpp b/src/api/cvc4cpp.cpp
index bdb5f2f59..942235e9c 100644
--- a/src/api/cvc4cpp.cpp
+++ b/src/api/cvc4cpp.cpp
@@ -1288,6 +1288,144 @@ Sort OpTerm::getSort() const
bool OpTerm::isNull() const { return d_expr->isNull(); }
+template <>
+std::string OpTerm::getIndices() const
+{
+ CVC4_API_CHECK_NOT_NULL;
+ std::string i;
+ Kind k = intToExtKind(d_expr->getKind());
+
+ if (k == DIVISIBLE_OP)
+ {
+ // DIVISIBLE_OP returns a string index to support
+ // arbitrary precision integers
+ CVC4::Integer _int = d_expr->getConst<Divisible>().k;
+ i = _int.toString();
+ }
+ else if (k == RECORD_UPDATE_OP)
+ {
+ i = d_expr->getConst<RecordUpdate>().getField();
+ }
+ else
+ {
+ CVC4_API_CHECK(false) << "Can't get string index from"
+ << " kind " << kindToString(k);
+ }
+
+ return i;
+}
+
+template <>
+Kind OpTerm::getIndices() const
+{
+ CVC4_API_CHECK_NOT_NULL;
+ Kind kind = intToExtKind(d_expr->getKind());
+ CVC4_API_KIND_CHECK_EXPECTED(kind == CHAIN_OP, kind) << "CHAIN_OP";
+ return intToExtKind(d_expr->getConst<Chain>().getOperator());
+}
+
+template <>
+uint32_t OpTerm::getIndices() const
+{
+ CVC4_API_CHECK_NOT_NULL;
+ uint32_t i;
+ Kind k = intToExtKind(d_expr->getKind());
+ switch (k)
+ {
+ case BITVECTOR_REPEAT_OP:
+ i = d_expr->getConst<BitVectorRepeat>().repeatAmount;
+ break;
+ case BITVECTOR_ZERO_EXTEND_OP:
+ i = d_expr->getConst<BitVectorZeroExtend>().zeroExtendAmount;
+ break;
+ case BITVECTOR_SIGN_EXTEND_OP:
+ i = d_expr->getConst<BitVectorSignExtend>().signExtendAmount;
+ break;
+ case BITVECTOR_ROTATE_LEFT_OP:
+ i = d_expr->getConst<BitVectorRotateLeft>().rotateLeftAmount;
+ break;
+ case BITVECTOR_ROTATE_RIGHT_OP:
+ i = d_expr->getConst<BitVectorRotateRight>().rotateRightAmount;
+ break;
+ case INT_TO_BITVECTOR_OP:
+ i = d_expr->getConst<IntToBitVector>().size;
+ break;
+ case FLOATINGPOINT_TO_UBV_OP:
+ i = d_expr->getConst<FloatingPointToUBV>().bvs.size;
+ break;
+ case FLOATINGPOINT_TO_UBV_TOTAL_OP:
+ i = d_expr->getConst<FloatingPointToUBVTotal>().bvs.size;
+ break;
+ case FLOATINGPOINT_TO_SBV_OP:
+ i = d_expr->getConst<FloatingPointToSBV>().bvs.size;
+ break;
+ case FLOATINGPOINT_TO_SBV_TOTAL_OP:
+ i = d_expr->getConst<FloatingPointToSBVTotal>().bvs.size;
+ break;
+ case TUPLE_UPDATE_OP: i = d_expr->getConst<TupleUpdate>().getIndex(); break;
+ default:
+ CVC4ApiExceptionStream().ostream() << "Can't get uint32_t index from"
+ << " kind " << kindToString(k);
+ }
+ return i;
+}
+
+template <>
+std::pair<uint32_t, uint32_t> OpTerm::getIndices() const
+{
+ CVC4_API_CHECK_NOT_NULL;
+ std::pair<uint32_t, uint32_t> indices;
+ Kind k = intToExtKind(d_expr->getKind());
+
+ // using if/else instead of case statement because want local variables
+ if (k == BITVECTOR_EXTRACT_OP)
+ {
+ CVC4::BitVectorExtract ext = d_expr->getConst<BitVectorExtract>();
+ indices = std::make_pair(ext.high, ext.low);
+ }
+ else if (k == FLOATINGPOINT_TO_FP_IEEE_BITVECTOR_OP)
+ {
+ CVC4::FloatingPointToFPIEEEBitVector ext =
+ d_expr->getConst<FloatingPointToFPIEEEBitVector>();
+ indices = std::make_pair(ext.t.exponent(), ext.t.significand());
+ }
+ else if (k == FLOATINGPOINT_TO_FP_FLOATINGPOINT_OP)
+ {
+ CVC4::FloatingPointToFPFloatingPoint ext =
+ d_expr->getConst<FloatingPointToFPFloatingPoint>();
+ indices = std::make_pair(ext.t.exponent(), ext.t.significand());
+ }
+ else if (k == FLOATINGPOINT_TO_FP_REAL_OP)
+ {
+ CVC4::FloatingPointToFPReal ext = d_expr->getConst<FloatingPointToFPReal>();
+ indices = std::make_pair(ext.t.exponent(), ext.t.significand());
+ }
+ else if (k == FLOATINGPOINT_TO_FP_SIGNED_BITVECTOR_OP)
+ {
+ CVC4::FloatingPointToFPSignedBitVector ext =
+ d_expr->getConst<FloatingPointToFPSignedBitVector>();
+ indices = std::make_pair(ext.t.exponent(), ext.t.significand());
+ }
+ else if (k == FLOATINGPOINT_TO_FP_UNSIGNED_BITVECTOR_OP)
+ {
+ CVC4::FloatingPointToFPUnsignedBitVector ext =
+ d_expr->getConst<FloatingPointToFPUnsignedBitVector>();
+ indices = std::make_pair(ext.t.exponent(), ext.t.significand());
+ }
+ else if (k == FLOATINGPOINT_TO_FP_GENERIC_OP)
+ {
+ CVC4::FloatingPointToFPGeneric ext =
+ d_expr->getConst<FloatingPointToFPGeneric>();
+ indices = std::make_pair(ext.t.exponent(), ext.t.significand());
+ }
+ else
+ {
+ CVC4_API_CHECK(false) << "Can't get pair<uint32_t, uint32_t> indices from"
+ << " kind " << kindToString(k);
+ }
+ return indices;
+}
+
std::string OpTerm::toString() const { return d_expr->toString(); }
// !!! This is only temporarily available until the parser is fully migrated
@@ -2724,10 +2862,26 @@ OpTerm Solver::mkOpTerm(Kind kind, Kind k) const
OpTerm Solver::mkOpTerm(Kind kind, const std::string& arg) const
{
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
- CVC4_API_KIND_CHECK_EXPECTED(kind == RECORD_UPDATE_OP, kind)
- << "RECORD_UPDATE_OP";
-
- return *mkValHelper<CVC4::RecordUpdate>(CVC4::RecordUpdate(arg)).d_expr.get();
+ CVC4_API_KIND_CHECK_EXPECTED(
+ (kind == RECORD_UPDATE_OP) || (kind == DIVISIBLE_OP), kind)
+ << "RECORD_UPDATE_OP or DIVISIBLE_OP";
+ OpTerm res;
+ if (kind == RECORD_UPDATE_OP)
+ {
+ res =
+ *mkValHelper<CVC4::RecordUpdate>(CVC4::RecordUpdate(arg)).d_expr.get();
+ }
+ else
+ {
+ /* 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(arg != ".", arg)
+ << "a string representing an integer, real or rational value.";
+ res = *mkValHelper<CVC4::Divisible>(CVC4::Divisible(CVC4::Integer(arg)))
+ .d_expr.get();
+ }
+ return res;
CVC4_API_SOLVER_TRY_CATCH_END;
}
diff --git a/src/api/cvc4cpp.h b/src/api/cvc4cpp.h
index 2ff1cb91d..67e8bb6e7 100644
--- a/src/api/cvc4cpp.h
+++ b/src/api/cvc4cpp.h
@@ -873,6 +873,19 @@ class CVC4_PUBLIC OpTerm
bool isNull() const;
/**
+ * Get the indices used to create this OpTerm.
+ * Supports the following template arguments:
+ * - string
+ * - Kind
+ * - uint32_t
+ * - pair<uint32_t, uint32_t>
+ * Check the OpTerm Kind with getKind() to determine which argument to use.
+ * @return the indices used to create this OpTerm
+ */
+ template <typename T>
+ T getIndices() const;
+
+ /**
* @return a string representation of this operator term
*/
std::string toString() const;
@@ -1818,6 +1831,7 @@ class CVC4_PUBLIC Solver
/**
* Create operator of kind:
* - RECORD_UPDATE_OP
+ * - DIVISIBLE_OP (to support arbitrary precision integers)
* See enum Kind for a description of the parameters.
* @param kind the kind of the operator
* @param arg the string argument to this operator
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback