diff options
author | makaimann <makaim@stanford.edu> | 2019-08-11 09:07:31 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-08-11 09:07:31 -0700 |
commit | 942f66a8b9dd92cb7c1ba72e6a521e86a1a7e341 (patch) | |
tree | adb50522a04454c1112169331c3edce6d8e66cb6 /src/api | |
parent | 03a99a427eaa8c679ede508e11561467a2291334 (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.cpp | 162 | ||||
-rw-r--r-- | src/api/cvc4cpp.h | 14 |
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 |