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
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;
}
void testGetKind();
void testGetSort();
void testIsNull();
+ void testGetIndicesString();
+ void testGetIndicesKind();
+ void testGetIndicesUint();
+ void testGetIndicesPairUint();
private:
Solver d_solver;
x = d_solver.mkOpTerm(BITVECTOR_EXTRACT_OP, 31, 1);
TS_ASSERT(!x.isNull());
}
+
+void OpTermBlack::testGetIndicesString()
+{
+ OpTerm x;
+ TS_ASSERT_THROWS(x.getIndices<std::string>(), CVC4ApiException&);
+
+ OpTerm divisible_ot = d_solver.mkOpTerm(DIVISIBLE_OP, 4);
+ std::string divisible_idx = divisible_ot.getIndices<std::string>();
+ TS_ASSERT(divisible_idx == "4");
+
+ OpTerm record_update_ot = d_solver.mkOpTerm(RECORD_UPDATE_OP, "test");
+ std::string record_update_idx = record_update_ot.getIndices<std::string>();
+ TS_ASSERT(record_update_idx == "test");
+ TS_ASSERT_THROWS(record_update_ot.getIndices<uint32_t>(), CVC4ApiException&);
+}
+
+void OpTermBlack::testGetIndicesKind()
+{
+ OpTerm chain_ot = d_solver.mkOpTerm(CHAIN_OP, AND);
+ Kind chain_idx = chain_ot.getIndices<Kind>();
+ TS_ASSERT(chain_idx == AND);
+}
+
+void OpTermBlack::testGetIndicesUint()
+{
+ OpTerm bitvector_repeat_ot = d_solver.mkOpTerm(BITVECTOR_REPEAT_OP, 5);
+ uint32_t bitvector_repeat_idx = bitvector_repeat_ot.getIndices<uint32_t>();
+ TS_ASSERT(bitvector_repeat_idx == 5);
+ TS_ASSERT_THROWS(
+ (bitvector_repeat_ot.getIndices<std::pair<uint32_t, uint32_t>>()),
+ CVC4ApiException&);
+
+ OpTerm bitvector_zero_extend_ot =
+ d_solver.mkOpTerm(BITVECTOR_ZERO_EXTEND_OP, 6);
+ uint32_t bitvector_zero_extend_idx =
+ bitvector_zero_extend_ot.getIndices<uint32_t>();
+ TS_ASSERT(bitvector_zero_extend_idx == 6);
+
+ OpTerm bitvector_sign_extend_ot =
+ d_solver.mkOpTerm(BITVECTOR_SIGN_EXTEND_OP, 7);
+ uint32_t bitvector_sign_extend_idx =
+ bitvector_sign_extend_ot.getIndices<uint32_t>();
+ TS_ASSERT(bitvector_sign_extend_idx == 7);
+
+ OpTerm bitvector_rotate_left_ot =
+ d_solver.mkOpTerm(BITVECTOR_ROTATE_LEFT_OP, 8);
+ uint32_t bitvector_rotate_left_idx =
+ bitvector_rotate_left_ot.getIndices<uint32_t>();
+ TS_ASSERT(bitvector_rotate_left_idx == 8);
+
+ OpTerm bitvector_rotate_right_ot =
+ d_solver.mkOpTerm(BITVECTOR_ROTATE_RIGHT_OP, 9);
+ uint32_t bitvector_rotate_right_idx =
+ bitvector_rotate_right_ot.getIndices<uint32_t>();
+ TS_ASSERT(bitvector_rotate_right_idx == 9);
+
+ OpTerm int_to_bitvector_ot = d_solver.mkOpTerm(INT_TO_BITVECTOR_OP, 10);
+ uint32_t int_to_bitvector_idx = int_to_bitvector_ot.getIndices<uint32_t>();
+ TS_ASSERT(int_to_bitvector_idx == 10);
+
+ OpTerm floatingpoint_to_ubv_ot =
+ d_solver.mkOpTerm(FLOATINGPOINT_TO_UBV_OP, 11);
+ uint32_t floatingpoint_to_ubv_idx =
+ floatingpoint_to_ubv_ot.getIndices<uint32_t>();
+ TS_ASSERT(floatingpoint_to_ubv_idx == 11);
+
+ OpTerm floatingpoint_to_ubv_total_ot =
+ d_solver.mkOpTerm(FLOATINGPOINT_TO_UBV_TOTAL_OP, 12);
+ uint32_t floatingpoint_to_ubv_total_idx =
+ floatingpoint_to_ubv_total_ot.getIndices<uint32_t>();
+ TS_ASSERT(floatingpoint_to_ubv_total_idx == 12);
+
+ OpTerm floatingpoint_to_sbv_ot =
+ d_solver.mkOpTerm(FLOATINGPOINT_TO_SBV_OP, 13);
+ uint32_t floatingpoint_to_sbv_idx =
+ floatingpoint_to_sbv_ot.getIndices<uint32_t>();
+ TS_ASSERT(floatingpoint_to_sbv_idx == 13);
+
+ OpTerm floatingpoint_to_sbv_total_ot =
+ d_solver.mkOpTerm(FLOATINGPOINT_TO_SBV_TOTAL_OP, 14);
+ uint32_t floatingpoint_to_sbv_total_idx =
+ floatingpoint_to_sbv_total_ot.getIndices<uint32_t>();
+ TS_ASSERT(floatingpoint_to_sbv_total_idx == 14);
+
+ OpTerm tuple_update_ot = d_solver.mkOpTerm(TUPLE_UPDATE_OP, 5);
+ uint32_t tuple_update_idx = tuple_update_ot.getIndices<uint32_t>();
+ TS_ASSERT(tuple_update_idx == 5);
+ TS_ASSERT_THROWS(tuple_update_ot.getIndices<std::string>(),
+ CVC4ApiException&);
+}
+
+void OpTermBlack::testGetIndicesPairUint()
+{
+ OpTerm bitvector_extract_ot = d_solver.mkOpTerm(BITVECTOR_EXTRACT_OP, 4, 0);
+ std::pair<uint32_t, uint32_t> bitvector_extract_indices =
+ bitvector_extract_ot.getIndices<std::pair<uint32_t, uint32_t>>();
+ TS_ASSERT((bitvector_extract_indices == std::pair<uint32_t, uint32_t>{4, 0}));
+
+ OpTerm floatingpoint_to_fp_ieee_bitvector_ot =
+ d_solver.mkOpTerm(FLOATINGPOINT_TO_FP_IEEE_BITVECTOR_OP, 4, 25);
+ std::pair<uint32_t, uint32_t> floatingpoint_to_fp_ieee_bitvector_indices =
+ floatingpoint_to_fp_ieee_bitvector_ot
+ .getIndices<std::pair<uint32_t, uint32_t>>();
+ TS_ASSERT((floatingpoint_to_fp_ieee_bitvector_indices
+ == std::pair<uint32_t, uint32_t>{4, 25}));
+
+ OpTerm floatingpoint_to_fp_floatingpoint_ot =
+ d_solver.mkOpTerm(FLOATINGPOINT_TO_FP_FLOATINGPOINT_OP, 4, 25);
+ std::pair<uint32_t, uint32_t> floatingpoint_to_fp_floatingpoint_indices =
+ floatingpoint_to_fp_floatingpoint_ot
+ .getIndices<std::pair<uint32_t, uint32_t>>();
+ TS_ASSERT((floatingpoint_to_fp_floatingpoint_indices
+ == std::pair<uint32_t, uint32_t>{4, 25}));
+
+ OpTerm floatingpoint_to_fp_real_ot =
+ d_solver.mkOpTerm(FLOATINGPOINT_TO_FP_REAL_OP, 4, 25);
+ std::pair<uint32_t, uint32_t> floatingpoint_to_fp_real_indices =
+ floatingpoint_to_fp_real_ot.getIndices<std::pair<uint32_t, uint32_t>>();
+ TS_ASSERT((floatingpoint_to_fp_real_indices
+ == std::pair<uint32_t, uint32_t>{4, 25}));
+
+ OpTerm floatingpoint_to_fp_signed_bitvector_ot =
+ d_solver.mkOpTerm(FLOATINGPOINT_TO_FP_SIGNED_BITVECTOR_OP, 4, 25);
+ std::pair<uint32_t, uint32_t> floatingpoint_to_fp_signed_bitvector_indices =
+ floatingpoint_to_fp_signed_bitvector_ot
+ .getIndices<std::pair<uint32_t, uint32_t>>();
+ TS_ASSERT((floatingpoint_to_fp_signed_bitvector_indices
+ == std::pair<uint32_t, uint32_t>{4, 25}));
+
+ OpTerm floatingpoint_to_fp_unsigned_bitvector_ot =
+ d_solver.mkOpTerm(FLOATINGPOINT_TO_FP_UNSIGNED_BITVECTOR_OP, 4, 25);
+ std::pair<uint32_t, uint32_t> floatingpoint_to_fp_unsigned_bitvector_indices =
+ floatingpoint_to_fp_unsigned_bitvector_ot
+ .getIndices<std::pair<uint32_t, uint32_t>>();
+ TS_ASSERT((floatingpoint_to_fp_unsigned_bitvector_indices
+ == std::pair<uint32_t, uint32_t>{4, 25}));
+
+ OpTerm floatingpoint_to_fp_generic_ot =
+ d_solver.mkOpTerm(FLOATINGPOINT_TO_FP_GENERIC_OP, 4, 25);
+ std::pair<uint32_t, uint32_t> floatingpoint_to_fp_generic_indices =
+ floatingpoint_to_fp_generic_ot
+ .getIndices<std::pair<uint32_t, uint32_t>>();
+ TS_ASSERT((floatingpoint_to_fp_generic_indices
+ == std::pair<uint32_t, uint32_t>{4, 25}));
+ TS_ASSERT_THROWS(floatingpoint_to_fp_generic_ot.getIndices<std::string>(),
+ CVC4ApiException&);
+}