/****************************************************************************** * Top contributors (to current version): * Aina Niemetz, Andrew Reynolds, Mathias Preiner * * This file is part of the cvc5 project. * * Copyright (c) 2009-2022 by the authors listed in the file AUTHORS * 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. * **************************************************************************** * * Black box testing of the Solver class of the C++ API. */ #include #include #include "base/output.h" #include "test_api.h" namespace cvc5::internal { namespace test { class TestApiBlackSolver : public TestApi { }; TEST_F(TestApiBlackSolver, proj_issue416) { Solver slv; slv.setOption("solve-bv-as-int", "sum"); slv.setOption("strings-exp", "true"); Sort s1 = slv.getStringSort(); Term t27 = slv.mkConst(s1, "_x50"); Term t333 = slv.mkRegexpAll(); Term t1243 = slv.mkTerm(Kind::STRING_REPLACE_RE_ALL, {t27, t333, t27}); Term t1291 = slv.mkTerm(Kind::EQUAL, {t1243, t27}); slv.assertFormula(t1291); slv.checkSat(); } TEST_F(TestApiBlackSolver, proj_issue435) { Solver slv; slv.setOption("strings-exp", "true"); Sort s1 = slv.mkUninterpretedSort("_u0"); Sort s3 = slv.getBooleanSort(); Sort _p7 = slv.mkParamSort("_p7"); DatatypeDecl _dt5 = slv.mkDatatypeDecl("_dt5", {_p7}); DatatypeConstructorDecl _cons33 = slv.mkDatatypeConstructorDecl("_cons33"); _cons33.addSelector("_sel31", s1); _cons33.addSelector("_sel32", _p7); _dt5.addConstructor(_cons33); std::vector _s6 = slv.mkDatatypeSorts({_dt5}); Sort s6 = _s6[0]; Sort s21 = s6.instantiate({s3}); Sort s42 = slv.mkSequenceSort(s21); Term t40 = slv.mkConst(s42, "_x64"); Term t75 = slv.mkTerm(Kind::SEQ_REV, {t40}); Term t91 = slv.mkTerm(Kind::SEQ_PREFIX, {t75, t40}); slv.checkSatAssuming({t91}); } TEST_F(TestApiBlackSolver, pow2Large1) { // Based on https://github.com/cvc5/cvc5-projects/issues/371 Sort s1 = d_solver.getStringSort(); Sort s2 = d_solver.getIntegerSort(); Sort s4 = d_solver.mkArraySort(s1, s2); Sort s7 = d_solver.mkArraySort(s2, s1); Term t10 = d_solver.mkInteger("68038927088685865242724985643"); Term t74 = d_solver.mkInteger("8416288636405"); std::vector ctors; ctors.push_back(d_solver.mkDatatypeConstructorDecl("_x109")); ctors.back().addSelector("_x108", s7); ctors.push_back(d_solver.mkDatatypeConstructorDecl("_x113")); ctors.back().addSelector("_x110", s4); ctors.back().addSelector("_x111", s2); ctors.back().addSelector("_x112", s7); Sort s11 = d_solver.declareDatatype("_x107", ctors); Term t82 = d_solver.mkConst(s11, "_x114"); Term t180 = d_solver.mkTerm(POW2, {t10}); Term t258 = d_solver.mkTerm(GEQ, {t74, t180}); d_solver.assertFormula(t258); ASSERT_THROW(d_solver.simplify(t82), CVC5ApiException); } TEST_F(TestApiBlackSolver, pow2Large2) { // Based on https://github.com/cvc5/cvc5-projects/issues/333 Term t1 = d_solver.mkBitVector(63, ~(((uint64_t)1) << 62)); Term t2 = d_solver.mkTerm(Kind::BITVECTOR_TO_NAT, {t1}); Term t3 = d_solver.mkTerm(Kind::POW2, {t2}); Term t4 = d_solver.mkTerm(Kind::DISTINCT, {t3, t2}); ASSERT_THROW(d_solver.checkSatAssuming({t4}), CVC5ApiException); } TEST_F(TestApiBlackSolver, pow2Large3) { // Based on https://github.com/cvc5/cvc5-projects/issues/339 Sort s4 = d_solver.getIntegerSort(); Term t203 = d_solver.mkInteger("6135470354240554220207"); Term t262 = d_solver.mkTerm(POW2, {t203}); Term t536 = d_solver.mkTerm(d_solver.mkOp(INT_TO_BITVECTOR, {49}), {t262}); ASSERT_THROW(d_solver.simplify(t536), CVC5ApiException); } TEST_F(TestApiBlackSolver, recoverableException) { d_solver.setOption("produce-models", "true"); Term x = d_solver.mkConst(d_solver.getBooleanSort(), "x"); d_solver.assertFormula(x.eqTerm(x).notTerm()); ASSERT_THROW(d_solver.getValue(x), CVC5ApiRecoverableException); try { d_solver.getValue(x); } catch (const CVC5ApiRecoverableException& e) { ASSERT_NO_THROW(e.what()); ASSERT_NO_THROW(e.getMessage()); } } TEST_F(TestApiBlackSolver, supportsFloatingPoint) { ASSERT_NO_THROW(d_solver.mkRoundingMode(ROUND_NEAREST_TIES_TO_EVEN)); } TEST_F(TestApiBlackSolver, getBooleanSort) { ASSERT_NO_THROW(d_solver.getBooleanSort()); } TEST_F(TestApiBlackSolver, getIntegerSort) { ASSERT_NO_THROW(d_solver.getIntegerSort()); } TEST_F(TestApiBlackSolver, getRealSort) { ASSERT_NO_THROW(d_solver.getRealSort()); } TEST_F(TestApiBlackSolver, getRegExpSort) { ASSERT_NO_THROW(d_solver.getRegExpSort()); } TEST_F(TestApiBlackSolver, getStringSort) { ASSERT_NO_THROW(d_solver.getStringSort()); } TEST_F(TestApiBlackSolver, getRoundingModeSort) { ASSERT_NO_THROW(d_solver.getRoundingModeSort()); } TEST_F(TestApiBlackSolver, mkArraySort) { Sort boolSort = d_solver.getBooleanSort(); Sort intSort = d_solver.getIntegerSort(); Sort realSort = d_solver.getRealSort(); Sort bvSort = d_solver.mkBitVectorSort(32); ASSERT_NO_THROW(d_solver.mkArraySort(boolSort, boolSort)); ASSERT_NO_THROW(d_solver.mkArraySort(intSort, intSort)); ASSERT_NO_THROW(d_solver.mkArraySort(realSort, realSort)); ASSERT_NO_THROW(d_solver.mkArraySort(bvSort, bvSort)); ASSERT_NO_THROW(d_solver.mkArraySort(boolSort, intSort)); ASSERT_NO_THROW(d_solver.mkArraySort(realSort, bvSort)); Sort fpSort = d_solver.mkFloatingPointSort(3, 5); ASSERT_NO_THROW(d_solver.mkArraySort(fpSort, fpSort)); ASSERT_NO_THROW(d_solver.mkArraySort(bvSort, fpSort)); Solver slv; ASSERT_NO_THROW(slv.mkArraySort(boolSort, boolSort)); } TEST_F(TestApiBlackSolver, mkBitVectorSort) { ASSERT_NO_THROW(d_solver.mkBitVectorSort(32)); ASSERT_THROW(d_solver.mkBitVectorSort(0), CVC5ApiException); } TEST_F(TestApiBlackSolver, mkFiniteFieldSort) { ASSERT_NO_THROW(d_solver.mkFiniteFieldSort("31")); ASSERT_THROW(d_solver.mkFiniteFieldSort("6"), CVC5ApiException); } TEST_F(TestApiBlackSolver, mkFloatingPointSort) { ASSERT_NO_THROW(d_solver.mkFloatingPointSort(4, 8)); ASSERT_THROW(d_solver.mkFloatingPointSort(0, 8), CVC5ApiException); ASSERT_THROW(d_solver.mkFloatingPointSort(4, 0), CVC5ApiException); ASSERT_THROW(d_solver.mkFloatingPointSort(1, 8), CVC5ApiException); ASSERT_THROW(d_solver.mkFloatingPointSort(4, 1), CVC5ApiException); } TEST_F(TestApiBlackSolver, mkDatatypeSort) { DatatypeDecl dtypeSpec = d_solver.mkDatatypeDecl("list"); DatatypeConstructorDecl cons = d_solver.mkDatatypeConstructorDecl("cons"); cons.addSelector("head", d_solver.getIntegerSort()); dtypeSpec.addConstructor(cons); DatatypeConstructorDecl nil = d_solver.mkDatatypeConstructorDecl("nil"); dtypeSpec.addConstructor(nil); ASSERT_NO_THROW(d_solver.mkDatatypeSort(dtypeSpec)); ASSERT_THROW(d_solver.mkDatatypeSort(dtypeSpec), CVC5ApiException); Solver slv; ASSERT_THROW(slv.mkDatatypeSort(dtypeSpec), CVC5ApiException); DatatypeDecl throwsDtypeSpec = d_solver.mkDatatypeDecl("list"); ASSERT_THROW(d_solver.mkDatatypeSort(throwsDtypeSpec), CVC5ApiException); } TEST_F(TestApiBlackSolver, mkDatatypeSorts) { Solver slv; DatatypeDecl dtypeSpec1 = d_solver.mkDatatypeDecl("list1"); DatatypeConstructorDecl cons1 = d_solver.mkDatatypeConstructorDecl("cons1"); cons1.addSelector("head1", d_solver.getIntegerSort()); dtypeSpec1.addConstructor(cons1); DatatypeConstructorDecl nil1 = d_solver.mkDatatypeConstructorDecl("nil1"); dtypeSpec1.addConstructor(nil1); DatatypeDecl dtypeSpec2 = d_solver.mkDatatypeDecl("list2"); DatatypeConstructorDecl cons2 = d_solver.mkDatatypeConstructorDecl("cons2"); cons2.addSelector("head2", d_solver.getIntegerSort()); dtypeSpec2.addConstructor(cons2); DatatypeConstructorDecl nil2 = d_solver.mkDatatypeConstructorDecl("nil2"); dtypeSpec2.addConstructor(nil2); std::vector decls = {dtypeSpec1, dtypeSpec2}; ASSERT_NO_THROW(d_solver.mkDatatypeSorts(decls)); ASSERT_THROW(d_solver.mkDatatypeSorts(decls), CVC5ApiException); ASSERT_THROW(slv.mkDatatypeSorts(decls), CVC5ApiException); DatatypeDecl throwsDtypeSpec = d_solver.mkDatatypeDecl("list"); std::vector throwsDecls = {throwsDtypeSpec}; ASSERT_THROW(d_solver.mkDatatypeSorts(throwsDecls), CVC5ApiException); /* with unresolved sorts */ Sort unresList = d_solver.mkUnresolvedDatatypeSort("ulist"); DatatypeDecl ulist = d_solver.mkDatatypeDecl("ulist"); DatatypeConstructorDecl ucons = d_solver.mkDatatypeConstructorDecl("ucons"); ucons.addSelector("car", unresList); ucons.addSelector("cdr", unresList); ulist.addConstructor(ucons); DatatypeConstructorDecl unil = d_solver.mkDatatypeConstructorDecl("unil"); ulist.addConstructor(unil); std::vector udecls = {ulist}; ASSERT_NO_THROW(d_solver.mkDatatypeSorts(udecls)); ASSERT_THROW(d_solver.mkDatatypeSorts(udecls), CVC5ApiException); ASSERT_THROW(slv.mkDatatypeSorts(udecls), CVC5ApiException); /* mutually recursive with unresolved parameterized sorts */ Sort p0 = d_solver.mkParamSort("p0"); Sort p1 = d_solver.mkParamSort("p1"); Sort u0 = d_solver.mkUnresolvedDatatypeSort("dt0", 1); Sort u1 = d_solver.mkUnresolvedDatatypeSort("dt1", 1); DatatypeDecl dtdecl0 = d_solver.mkDatatypeDecl("dt0", {p0}); DatatypeDecl dtdecl1 = d_solver.mkDatatypeDecl("dt1", {p1}); DatatypeConstructorDecl ctordecl0 = d_solver.mkDatatypeConstructorDecl("c0"); ctordecl0.addSelector("s0", u1.instantiate({p0})); DatatypeConstructorDecl ctordecl1 = d_solver.mkDatatypeConstructorDecl("c1"); ctordecl1.addSelector("s1", u0.instantiate({p1})); dtdecl0.addConstructor(ctordecl0); dtdecl1.addConstructor(ctordecl1); dtdecl1.addConstructor(d_solver.mkDatatypeConstructorDecl("nil")); std::vector dt_sorts = d_solver.mkDatatypeSorts({dtdecl0, dtdecl1}); Sort isort1 = dt_sorts[1].instantiate({d_solver.getBooleanSort()}); Term t1 = d_solver.mkConst(isort1, "t"); Term t0 = d_solver.mkTerm( APPLY_SELECTOR, {t1.getSort().getDatatype().getSelector("s1").getTerm(), t1}); ASSERT_EQ(dt_sorts[0].instantiate({d_solver.getBooleanSort()}), t0.getSort()); /* Note: More tests are in datatype_api_black. */ } TEST_F(TestApiBlackSolver, mkFunctionSort) { ASSERT_NO_THROW(d_solver.mkFunctionSort({d_solver.mkUninterpretedSort("u")}, d_solver.getIntegerSort())); Sort funSort = d_solver.mkFunctionSort({d_solver.mkUninterpretedSort("u")}, d_solver.getIntegerSort()); // function arguments are allowed ASSERT_NO_THROW( d_solver.mkFunctionSort({funSort}, d_solver.getIntegerSort())); // non-first-class arguments are not allowed Sort reSort = d_solver.getRegExpSort(); ASSERT_THROW(d_solver.mkFunctionSort({reSort}, d_solver.getIntegerSort()), CVC5ApiException); ASSERT_THROW(d_solver.mkFunctionSort({d_solver.getIntegerSort()}, funSort), CVC5ApiException); ASSERT_NO_THROW(d_solver.mkFunctionSort( {d_solver.mkUninterpretedSort("u"), d_solver.getIntegerSort()}, d_solver.getIntegerSort())); Sort funSort2 = d_solver.mkFunctionSort({d_solver.mkUninterpretedSort("u")}, d_solver.getIntegerSort()); // function arguments are allowed ASSERT_NO_THROW( d_solver.mkFunctionSort({funSort2, d_solver.mkUninterpretedSort("u")}, d_solver.getIntegerSort())); ASSERT_THROW(d_solver.mkFunctionSort({d_solver.getIntegerSort(), d_solver.mkUninterpretedSort("u")}, funSort2), CVC5ApiException); Solver slv; ASSERT_NO_THROW(slv.mkFunctionSort({d_solver.mkUninterpretedSort("u")}, d_solver.getIntegerSort())); ASSERT_NO_THROW(slv.mkFunctionSort({slv.mkUninterpretedSort("u")}, d_solver.getIntegerSort())); std::vector sorts1 = {d_solver.getBooleanSort(), slv.getIntegerSort(), d_solver.getIntegerSort()}; std::vector sorts2 = {slv.getBooleanSort(), slv.getIntegerSort()}; ASSERT_NO_THROW(slv.mkFunctionSort(sorts2, slv.getIntegerSort())); ASSERT_NO_THROW(slv.mkFunctionSort(sorts1, slv.getIntegerSort())); ASSERT_NO_THROW(slv.mkFunctionSort(sorts2, d_solver.getIntegerSort())); } TEST_F(TestApiBlackSolver, mkParamSort) { ASSERT_NO_THROW(d_solver.mkParamSort("T")); ASSERT_NO_THROW(d_solver.mkParamSort("")); } TEST_F(TestApiBlackSolver, mkPredicateSort) { ASSERT_NO_THROW(d_solver.mkPredicateSort({d_solver.getIntegerSort()})); ASSERT_THROW(d_solver.mkPredicateSort({}), CVC5ApiException); Sort funSort = d_solver.mkFunctionSort({d_solver.mkUninterpretedSort("u")}, d_solver.getIntegerSort()); // functions as arguments are allowed ASSERT_NO_THROW( d_solver.mkPredicateSort({d_solver.getIntegerSort(), funSort})); Solver slv; ASSERT_NO_THROW(slv.mkPredicateSort({d_solver.getIntegerSort()})); } TEST_F(TestApiBlackSolver, mkRecordSort) { std::vector> fields = { std::make_pair("b", d_solver.getBooleanSort()), std::make_pair("bv", d_solver.mkBitVectorSort(8)), std::make_pair("i", d_solver.getIntegerSort())}; std::vector> empty; ASSERT_NO_THROW(d_solver.mkRecordSort(fields)); ASSERT_NO_THROW(d_solver.mkRecordSort(empty)); Sort recSort = d_solver.mkRecordSort(fields); ASSERT_NO_THROW(recSort.getDatatype()); Solver slv; ASSERT_NO_THROW(slv.mkRecordSort(fields)); } TEST_F(TestApiBlackSolver, mkSetSort) { ASSERT_NO_THROW(d_solver.mkSetSort(d_solver.getBooleanSort())); ASSERT_NO_THROW(d_solver.mkSetSort(d_solver.getIntegerSort())); ASSERT_NO_THROW(d_solver.mkSetSort(d_solver.mkBitVectorSort(4))); Solver slv; ASSERT_NO_THROW(slv.mkSetSort(d_solver.mkBitVectorSort(4))); } TEST_F(TestApiBlackSolver, mkBagSort) { ASSERT_NO_THROW(d_solver.mkBagSort(d_solver.getBooleanSort())); ASSERT_NO_THROW(d_solver.mkBagSort(d_solver.getIntegerSort())); ASSERT_NO_THROW(d_solver.mkBagSort(d_solver.mkBitVectorSort(4))); Solver slv; ASSERT_NO_THROW(slv.mkBagSort(d_solver.mkBitVectorSort(4))); } TEST_F(TestApiBlackSolver, mkSequenceSort) { ASSERT_NO_THROW(d_solver.mkSequenceSort(d_solver.getBooleanSort())); ASSERT_NO_THROW(d_solver.mkSequenceSort( d_solver.mkSequenceSort(d_solver.getIntegerSort()))); Solver slv; ASSERT_NO_THROW(slv.mkSequenceSort(d_solver.getIntegerSort())); } TEST_F(TestApiBlackSolver, mkAbstractSort) { ASSERT_NO_THROW(d_solver.mkAbstractSort(ARRAY_SORT)); ASSERT_NO_THROW(d_solver.mkAbstractSort(BITVECTOR_SORT)); ASSERT_NO_THROW(d_solver.mkAbstractSort(TUPLE_SORT)); ASSERT_NO_THROW(d_solver.mkAbstractSort(SET_SORT)); ASSERT_THROW(d_solver.mkAbstractSort(BOOLEAN_SORT), CVC5ApiException); } TEST_F(TestApiBlackSolver, mkUninterpretedSort) { ASSERT_NO_THROW(d_solver.mkUninterpretedSort("u")); ASSERT_NO_THROW(d_solver.mkUninterpretedSort("")); } TEST_F(TestApiBlackSolver, mkUnresolvedDatatypeSort) { ASSERT_NO_THROW(d_solver.mkUnresolvedDatatypeSort("u")); ASSERT_NO_THROW(d_solver.mkUnresolvedDatatypeSort("u", 1)); ASSERT_NO_THROW(d_solver.mkUnresolvedDatatypeSort("")); ASSERT_NO_THROW(d_solver.mkUnresolvedDatatypeSort("", 1)); } TEST_F(TestApiBlackSolver, mkUninterpretedSortConstructorSort) { ASSERT_NO_THROW(d_solver.mkUninterpretedSortConstructorSort(2, "s")); ASSERT_NO_THROW(d_solver.mkUninterpretedSortConstructorSort(2, "")); ASSERT_THROW(d_solver.mkUninterpretedSortConstructorSort(0), CVC5ApiException); } TEST_F(TestApiBlackSolver, mkTupleSort) { ASSERT_NO_THROW(d_solver.mkTupleSort({d_solver.getIntegerSort()})); Sort funSort = d_solver.mkFunctionSort({d_solver.mkUninterpretedSort("u")}, d_solver.getIntegerSort()); ASSERT_NO_THROW(d_solver.mkTupleSort({d_solver.getIntegerSort(), funSort})); Solver slv; ASSERT_NO_THROW(slv.mkTupleSort({d_solver.getIntegerSort()})); } TEST_F(TestApiBlackSolver, mkBitVector) { ASSERT_NO_THROW(d_solver.mkBitVector(8, 2)); ASSERT_NO_THROW(d_solver.mkBitVector(32, 2)); ASSERT_NO_THROW(d_solver.mkBitVector(8, "-1111111", 2)); ASSERT_NO_THROW(d_solver.mkBitVector(8, "0101", 2)); ASSERT_NO_THROW(d_solver.mkBitVector(8, "00000101", 2)); ASSERT_NO_THROW(d_solver.mkBitVector(8, "-127", 10)); ASSERT_NO_THROW(d_solver.mkBitVector(8, "255", 10)); ASSERT_NO_THROW(d_solver.mkBitVector(8, "-7f", 16)); ASSERT_NO_THROW(d_solver.mkBitVector(8, "a0", 16)); ASSERT_THROW(d_solver.mkBitVector(0, 2), CVC5ApiException); ASSERT_THROW(d_solver.mkBitVector(0, "-127", 10), CVC5ApiException); ASSERT_THROW(d_solver.mkBitVector(0, "a0", 16), CVC5ApiException); ASSERT_THROW(d_solver.mkBitVector(8, "", 2), CVC5ApiException); ASSERT_THROW(d_solver.mkBitVector(8, "101", 5), CVC5ApiException); ASSERT_THROW(d_solver.mkBitVector(8, "128", 11), CVC5ApiException); ASSERT_THROW(d_solver.mkBitVector(8, "a0", 21), CVC5ApiException); ASSERT_THROW(d_solver.mkBitVector(8, "-11111111", 2), CVC5ApiException); ASSERT_THROW(d_solver.mkBitVector(8, "101010101", 2), CVC5ApiException); ASSERT_THROW(d_solver.mkBitVector(8, "-256", 10), CVC5ApiException); ASSERT_THROW(d_solver.mkBitVector(8, "257", 10), CVC5ApiException); ASSERT_THROW(d_solver.mkBitVector(8, "-a0", 16), CVC5ApiException); ASSERT_THROW(d_solver.mkBitVector(8, "fffff", 16), CVC5ApiException); ASSERT_THROW(d_solver.mkBitVector(8, "10201010", 2), CVC5ApiException); ASSERT_THROW(d_solver.mkBitVector(8, "-25x", 10), CVC5ApiException); ASSERT_THROW(d_solver.mkBitVector(8, "2x7", 10), CVC5ApiException); ASSERT_THROW(d_solver.mkBitVector(8, "fzff", 16), CVC5ApiException); ASSERT_EQ(d_solver.mkBitVector(8, "0101", 2), d_solver.mkBitVector(8, "00000101", 2)); ASSERT_EQ(d_solver.mkBitVector(4, "-1", 2), d_solver.mkBitVector(4, "1111", 2)); ASSERT_EQ(d_solver.mkBitVector(4, "-1", 16), d_solver.mkBitVector(4, "1111", 2)); ASSERT_EQ(d_solver.mkBitVector(4, "-1", 10), d_solver.mkBitVector(4, "1111", 2)); ASSERT_EQ(d_solver.mkBitVector(8, "01010101", 2).toString(), "#b01010101"); ASSERT_EQ(d_solver.mkBitVector(8, "F", 16).toString(), "#b00001111"); ASSERT_EQ(d_solver.mkBitVector(8, "-1", 10), d_solver.mkBitVector(8, "FF", 16)); } TEST_F(TestApiBlackSolver, mkFiniteFieldElem) { Sort f = d_solver.mkFiniteFieldSort("7"); Sort bv = d_solver.mkBitVectorSort(4); ASSERT_NO_THROW(d_solver.mkFiniteFieldElem("0", f)); ASSERT_NO_THROW(d_solver.mkFiniteFieldElem("1", f)); ASSERT_NO_THROW(d_solver.mkFiniteFieldElem("6", f)); ASSERT_NO_THROW(d_solver.mkFiniteFieldElem("8", f)); ASSERT_NO_THROW(d_solver.mkFiniteFieldElem("-1", f)); ASSERT_THROW(d_solver.mkFiniteFieldElem("-1", bv), CVC5ApiException); ASSERT_EQ(d_solver.mkFiniteFieldElem("-1", f), d_solver.mkFiniteFieldElem("6", f)); ASSERT_EQ(d_solver.mkFiniteFieldElem("1", f), d_solver.mkFiniteFieldElem("8", f)); } TEST_F(TestApiBlackSolver, mkVar) { Sort boolSort = d_solver.getBooleanSort(); Sort intSort = d_solver.getIntegerSort(); Sort funSort = d_solver.mkFunctionSort({intSort}, boolSort); ASSERT_NO_THROW(d_solver.mkVar(boolSort)); ASSERT_NO_THROW(d_solver.mkVar(funSort)); ASSERT_NO_THROW(d_solver.mkVar(boolSort, std::string("b"))); ASSERT_NO_THROW(d_solver.mkVar(funSort, "")); ASSERT_THROW(d_solver.mkVar(Sort()), CVC5ApiException); ASSERT_THROW(d_solver.mkVar(Sort(), "a"), CVC5ApiException); Solver slv; ASSERT_NO_THROW(slv.mkVar(boolSort, "x")); } TEST_F(TestApiBlackSolver, mkBoolean) { ASSERT_NO_THROW(d_solver.mkBoolean(true)); ASSERT_NO_THROW(d_solver.mkBoolean(false)); } TEST_F(TestApiBlackSolver, mkRoundingMode) { ASSERT_EQ(d_solver.mkRoundingMode(RoundingMode::ROUND_NEAREST_TIES_TO_EVEN) .toString(), "roundNearestTiesToEven"); ASSERT_EQ( d_solver.mkRoundingMode(RoundingMode::ROUND_TOWARD_POSITIVE).toString(), "roundTowardPositive"); ASSERT_EQ( d_solver.mkRoundingMode(RoundingMode::ROUND_TOWARD_NEGATIVE).toString(), "roundTowardNegative"); ASSERT_EQ(d_solver.mkRoundingMode(RoundingMode::ROUND_TOWARD_ZERO).toString(), "roundTowardZero"); ASSERT_EQ(d_solver.mkRoundingMode(RoundingMode::ROUND_NEAREST_TIES_TO_AWAY) .toString(), "roundNearestTiesToAway"); } TEST_F(TestApiBlackSolver, mkFloatingPoint) { Term t1 = d_solver.mkBitVector(8); Term t2 = d_solver.mkBitVector(4); Term t3 = d_solver.mkInteger(2); ASSERT_NO_THROW(d_solver.mkFloatingPoint(3, 5, t1)); ASSERT_THROW(d_solver.mkFloatingPoint(0, 5, Term()), CVC5ApiException); ASSERT_THROW(d_solver.mkFloatingPoint(0, 5, t1), CVC5ApiException); ASSERT_THROW(d_solver.mkFloatingPoint(3, 0, t1), CVC5ApiException); ASSERT_THROW(d_solver.mkFloatingPoint(3, 5, t2), CVC5ApiException); ASSERT_THROW(d_solver.mkFloatingPoint(3, 5, t2), CVC5ApiException); Solver slv; ASSERT_NO_THROW(slv.mkFloatingPoint(3, 5, t1)); } TEST_F(TestApiBlackSolver, mkCardinalityConstraint) { Sort su = d_solver.mkUninterpretedSort("u"); Sort si = d_solver.getIntegerSort(); ASSERT_NO_THROW(d_solver.mkCardinalityConstraint(su, 3)); ASSERT_THROW(d_solver.mkCardinalityConstraint(si, 3), CVC5ApiException); ASSERT_THROW(d_solver.mkCardinalityConstraint(su, 0), CVC5ApiException); Solver slv; ASSERT_NO_THROW(slv.mkCardinalityConstraint(su, 3)); } TEST_F(TestApiBlackSolver, mkEmptySet) { Sort s = d_solver.mkSetSort(d_solver.getBooleanSort()); ASSERT_THROW(d_solver.mkEmptySet(Sort()), CVC5ApiException); ASSERT_NO_THROW(d_solver.mkEmptySet(s)); ASSERT_THROW(d_solver.mkEmptySet(d_solver.getBooleanSort()), CVC5ApiException); Solver slv; ASSERT_NO_THROW(slv.mkEmptySet(s)); } TEST_F(TestApiBlackSolver, mkEmptyBag) { Sort s = d_solver.mkBagSort(d_solver.getBooleanSort()); ASSERT_THROW(d_solver.mkEmptyBag(Sort()), CVC5ApiException); ASSERT_NO_THROW(d_solver.mkEmptyBag(s)); ASSERT_THROW(d_solver.mkEmptyBag(d_solver.getBooleanSort()), CVC5ApiException); Solver slv; ASSERT_NO_THROW(slv.mkEmptyBag(s)); } TEST_F(TestApiBlackSolver, mkEmptySequence) { Sort s = d_solver.mkSequenceSort(d_solver.getBooleanSort()); ASSERT_NO_THROW(d_solver.mkEmptySequence(s)); ASSERT_NO_THROW(d_solver.mkEmptySequence(d_solver.getBooleanSort())); Solver slv; ASSERT_NO_THROW(slv.mkEmptySequence(s)); } TEST_F(TestApiBlackSolver, mkFalse) { ASSERT_NO_THROW(d_solver.mkFalse()); ASSERT_NO_THROW(d_solver.mkFalse()); } TEST_F(TestApiBlackSolver, mkFloatingPointNaN) { ASSERT_NO_THROW(d_solver.mkFloatingPointNaN(3, 5)); } TEST_F(TestApiBlackSolver, mkFloatingPointNegZero) { ASSERT_NO_THROW(d_solver.mkFloatingPointNegZero(3, 5)); } TEST_F(TestApiBlackSolver, mkFloatingPointNegInf) { ASSERT_NO_THROW(d_solver.mkFloatingPointNegInf(3, 5)); } TEST_F(TestApiBlackSolver, mkFloatingPointPosInf) { ASSERT_NO_THROW(d_solver.mkFloatingPointPosInf(3, 5)); } TEST_F(TestApiBlackSolver, mkFloatingPointPosZero) { ASSERT_NO_THROW(d_solver.mkFloatingPointPosZero(3, 5)); } TEST_F(TestApiBlackSolver, mkOp) { // mkOp(Kind kind, const std::string& arg) ASSERT_NO_THROW(d_solver.mkOp(DIVISIBLE, "2147483648")); ASSERT_THROW(d_solver.mkOp(BITVECTOR_EXTRACT, "asdf"), CVC5ApiException); // mkOp(Kind kind, std::vector args) ASSERT_NO_THROW(d_solver.mkOp(DIVISIBLE, {1})); ASSERT_NO_THROW(d_solver.mkOp(BITVECTOR_ROTATE_LEFT, {1})); ASSERT_NO_THROW(d_solver.mkOp(BITVECTOR_ROTATE_RIGHT, {1})); ASSERT_THROW(d_solver.mkOp(BITVECTOR_EXTRACT, {1}), CVC5ApiException); ASSERT_NO_THROW(d_solver.mkOp(BITVECTOR_EXTRACT, {1, 1})); ASSERT_THROW(d_solver.mkOp(DIVISIBLE, {1, 2}), CVC5ApiException); ASSERT_NO_THROW(d_solver.mkOp(TUPLE_PROJECT, {1, 2, 2})); } TEST_F(TestApiBlackSolver, mkPi) { ASSERT_NO_THROW(d_solver.mkPi()); } TEST_F(TestApiBlackSolver, mkInteger) { ASSERT_NO_THROW(d_solver.mkInteger("123")); ASSERT_THROW(d_solver.mkInteger("1.23"), CVC5ApiException); ASSERT_THROW(d_solver.mkInteger("1/23"), CVC5ApiException); ASSERT_THROW(d_solver.mkInteger("12/3"), CVC5ApiException); ASSERT_THROW(d_solver.mkInteger(".2"), CVC5ApiException); ASSERT_THROW(d_solver.mkInteger("2."), CVC5ApiException); ASSERT_THROW(d_solver.mkInteger(""), CVC5ApiException); ASSERT_THROW(d_solver.mkInteger("asdf"), CVC5ApiException); ASSERT_THROW(d_solver.mkInteger("1.2/3"), CVC5ApiException); ASSERT_THROW(d_solver.mkInteger("."), CVC5ApiException); ASSERT_THROW(d_solver.mkInteger("/"), CVC5ApiException); ASSERT_THROW(d_solver.mkInteger("2/"), CVC5ApiException); ASSERT_THROW(d_solver.mkInteger("/2"), CVC5ApiException); ASSERT_NO_THROW(d_solver.mkReal(std::string("123"))); ASSERT_THROW(d_solver.mkInteger(std::string("1.23")), CVC5ApiException); ASSERT_THROW(d_solver.mkInteger(std::string("1/23")), CVC5ApiException); ASSERT_THROW(d_solver.mkInteger(std::string("12/3")), CVC5ApiException); ASSERT_THROW(d_solver.mkInteger(std::string(".2")), CVC5ApiException); ASSERT_THROW(d_solver.mkInteger(std::string("2.")), CVC5ApiException); ASSERT_THROW(d_solver.mkInteger(std::string("")), CVC5ApiException); ASSERT_THROW(d_solver.mkInteger(std::string("asdf")), CVC5ApiException); ASSERT_THROW(d_solver.mkInteger(std::string("1.2/3")), CVC5ApiException); ASSERT_THROW(d_solver.mkInteger(std::string(".")), CVC5ApiException); ASSERT_THROW(d_solver.mkInteger(std::string("/")), CVC5ApiException); ASSERT_THROW(d_solver.mkInteger(std::string("2/")), CVC5ApiException); ASSERT_THROW(d_solver.mkInteger(std::string("/2")), CVC5ApiException); int32_t val1 = 1; int64_t val2 = -1; uint32_t val3 = 1; uint64_t val4 = -1; ASSERT_NO_THROW(d_solver.mkInteger(val1)); ASSERT_NO_THROW(d_solver.mkInteger(val2)); ASSERT_NO_THROW(d_solver.mkInteger(val3)); ASSERT_NO_THROW(d_solver.mkInteger(val4)); ASSERT_NO_THROW(d_solver.mkInteger(val4)); } TEST_F(TestApiBlackSolver, mkReal) { ASSERT_NO_THROW(d_solver.mkReal("123")); ASSERT_NO_THROW(d_solver.mkReal("1.23")); ASSERT_NO_THROW(d_solver.mkReal("1/23")); ASSERT_NO_THROW(d_solver.mkReal("12/3")); ASSERT_NO_THROW(d_solver.mkReal(".2")); ASSERT_NO_THROW(d_solver.mkReal("2.")); ASSERT_THROW(d_solver.mkReal(""), CVC5ApiException); ASSERT_THROW(d_solver.mkReal("asdf"), CVC5ApiException); ASSERT_THROW(d_solver.mkReal("1.2/3"), CVC5ApiException); ASSERT_THROW(d_solver.mkReal("."), CVC5ApiException); ASSERT_THROW(d_solver.mkReal("/"), CVC5ApiException); ASSERT_THROW(d_solver.mkReal("2/"), CVC5ApiException); ASSERT_THROW(d_solver.mkReal("/2"), CVC5ApiException); ASSERT_NO_THROW(d_solver.mkReal(std::string("123"))); ASSERT_NO_THROW(d_solver.mkReal(std::string("1.23"))); ASSERT_NO_THROW(d_solver.mkReal(std::string("1/23"))); ASSERT_NO_THROW(d_solver.mkReal(std::string("12/3"))); ASSERT_NO_THROW(d_solver.mkReal(std::string(".2"))); ASSERT_NO_THROW(d_solver.mkReal(std::string("2."))); ASSERT_THROW(d_solver.mkReal(std::string("")), CVC5ApiException); ASSERT_THROW(d_solver.mkReal(std::string("asdf")), CVC5ApiException); ASSERT_THROW(d_solver.mkReal(std::string("1.2/3")), CVC5ApiException); ASSERT_THROW(d_solver.mkReal(std::string(".")), CVC5ApiException); ASSERT_THROW(d_solver.mkReal(std::string("/")), CVC5ApiException); ASSERT_THROW(d_solver.mkReal(std::string("2/")), CVC5ApiException); ASSERT_THROW(d_solver.mkReal(std::string("/2")), CVC5ApiException); int32_t val1 = 1; int64_t val2 = -1; uint32_t val3 = 1; uint64_t val4 = -1; ASSERT_NO_THROW(d_solver.mkReal(val1)); ASSERT_NO_THROW(d_solver.mkReal(val2)); ASSERT_NO_THROW(d_solver.mkReal(val3)); ASSERT_NO_THROW(d_solver.mkReal(val4)); ASSERT_NO_THROW(d_solver.mkReal(val4)); ASSERT_NO_THROW(d_solver.mkReal(val1, val1)); ASSERT_NO_THROW(d_solver.mkReal(val2, val2)); ASSERT_NO_THROW(d_solver.mkReal(val3, val3)); ASSERT_NO_THROW(d_solver.mkReal(val4, val4)); ASSERT_NO_THROW(d_solver.mkReal("-1/-1")); ASSERT_NO_THROW(d_solver.mkReal("1/-1")); ASSERT_NO_THROW(d_solver.mkReal("-1/1")); ASSERT_NO_THROW(d_solver.mkReal("1/1")); ASSERT_THROW(d_solver.mkReal("/-5"), CVC5ApiException); } TEST_F(TestApiBlackSolver, mkRegexpAll) { Sort strSort = d_solver.getStringSort(); Term s = d_solver.mkConst(strSort, "s"); ASSERT_NO_THROW( d_solver.mkTerm(STRING_IN_REGEXP, {s, d_solver.mkRegexpAll()})); } TEST_F(TestApiBlackSolver, mkRegexpAllchar) { Sort strSort = d_solver.getStringSort(); Term s = d_solver.mkConst(strSort, "s"); ASSERT_NO_THROW( d_solver.mkTerm(STRING_IN_REGEXP, {s, d_solver.mkRegexpAllchar()})); } TEST_F(TestApiBlackSolver, mkRegexpNone) { Sort strSort = d_solver.getStringSort(); Term s = d_solver.mkConst(strSort, "s"); ASSERT_NO_THROW( d_solver.mkTerm(STRING_IN_REGEXP, {s, d_solver.mkRegexpNone()})); } TEST_F(TestApiBlackSolver, mkSepEmp) { ASSERT_NO_THROW(d_solver.mkSepEmp()); } TEST_F(TestApiBlackSolver, mkSepNil) { ASSERT_NO_THROW(d_solver.mkSepNil(d_solver.getBooleanSort())); ASSERT_THROW(d_solver.mkSepNil(Sort()), CVC5ApiException); Solver slv; ASSERT_NO_THROW(slv.mkSepNil(d_solver.getIntegerSort())); } TEST_F(TestApiBlackSolver, mkString) { ASSERT_NO_THROW(d_solver.mkString("")); ASSERT_NO_THROW(d_solver.mkString("asdfasdf")); ASSERT_EQ(d_solver.mkString("asdf\\nasdf").toString(), "\"asdf\\u{5c}nasdf\""); ASSERT_EQ(d_solver.mkString("asdf\\u{005c}nasdf", true).toString(), "\"asdf\\u{5c}nasdf\""); std::wstring s; ASSERT_EQ(d_solver.mkString(s).getStringValue(), s); } TEST_F(TestApiBlackSolver, mkTerm) { Sort bv32 = d_solver.mkBitVectorSort(32); Term a = d_solver.mkConst(bv32, "a"); Term b = d_solver.mkConst(bv32, "b"); std::vector v1 = {a, b}; std::vector v2 = {a, Term()}; std::vector v3 = {a, d_solver.mkTrue()}; std::vector v4 = {d_solver.mkInteger(1), d_solver.mkInteger(2)}; std::vector v5 = {d_solver.mkInteger(1), Term()}; std::vector v6 = {}; Solver slv; // mkTerm(Kind kind) const ASSERT_NO_THROW(d_solver.mkTerm(PI)); ASSERT_NO_THROW(d_solver.mkTerm(PI, {v6})); ASSERT_NO_THROW(d_solver.mkTerm(d_solver.mkOp(PI))); ASSERT_NO_THROW(d_solver.mkTerm(d_solver.mkOp(PI), {v6})); ASSERT_NO_THROW(d_solver.mkTerm(REGEXP_NONE)); ASSERT_NO_THROW(d_solver.mkTerm(REGEXP_NONE, {v6})); ASSERT_NO_THROW(d_solver.mkTerm(d_solver.mkOp(REGEXP_NONE))); ASSERT_NO_THROW(d_solver.mkTerm(d_solver.mkOp(REGEXP_NONE), {v6})); ASSERT_NO_THROW(d_solver.mkTerm(REGEXP_ALLCHAR)); ASSERT_NO_THROW(d_solver.mkTerm(REGEXP_ALLCHAR, {v6})); ASSERT_NO_THROW(d_solver.mkTerm(d_solver.mkOp(REGEXP_ALLCHAR))); ASSERT_NO_THROW(d_solver.mkTerm(d_solver.mkOp(REGEXP_ALLCHAR), {v6})); ASSERT_NO_THROW(d_solver.mkTerm(SEP_EMP)); ASSERT_NO_THROW(d_solver.mkTerm(SEP_EMP, {v6})); ASSERT_NO_THROW(d_solver.mkTerm(d_solver.mkOp(SEP_EMP))); ASSERT_NO_THROW(d_solver.mkTerm(d_solver.mkOp(SEP_EMP), {v6})); ASSERT_THROW(d_solver.mkTerm(CONST_BITVECTOR), CVC5ApiException); // mkTerm(Kind kind, Term child) const ASSERT_NO_THROW(d_solver.mkTerm(NOT, {d_solver.mkTrue()})); ASSERT_NO_THROW( d_solver.mkTerm(BAG_MAKE, {d_solver.mkTrue(), d_solver.mkInteger(1)})); ASSERT_THROW(d_solver.mkTerm(NOT, {Term()}), CVC5ApiException); ASSERT_THROW(d_solver.mkTerm(NOT, {a}), CVC5ApiException); ASSERT_NO_THROW(slv.mkTerm(NOT, {d_solver.mkTrue()})); // mkTerm(Kind kind, Term child1, Term child2) const ASSERT_NO_THROW(d_solver.mkTerm(EQUAL, {a, b})); ASSERT_THROW(d_solver.mkTerm(EQUAL, {Term(), b}), CVC5ApiException); ASSERT_THROW(d_solver.mkTerm(EQUAL, {a, Term()}), CVC5ApiException); ASSERT_THROW(d_solver.mkTerm(EQUAL, {a, d_solver.mkTrue()}), CVC5ApiException); ASSERT_NO_THROW(slv.mkTerm(EQUAL, {a, b})); // mkTerm(Kind kind, Term child1, Term child2, Term child3) const ASSERT_NO_THROW(d_solver.mkTerm( ITE, {d_solver.mkTrue(), d_solver.mkTrue(), d_solver.mkTrue()})); ASSERT_THROW( d_solver.mkTerm(ITE, {Term(), d_solver.mkTrue(), d_solver.mkTrue()}), CVC5ApiException); ASSERT_THROW( d_solver.mkTerm(ITE, {d_solver.mkTrue(), Term(), d_solver.mkTrue()}), CVC5ApiException); ASSERT_THROW( d_solver.mkTerm(ITE, {d_solver.mkTrue(), d_solver.mkTrue(), Term()}), CVC5ApiException); ASSERT_THROW(d_solver.mkTerm(ITE, {d_solver.mkTrue(), d_solver.mkTrue(), b}), CVC5ApiException); ASSERT_NO_THROW(slv.mkTerm( ITE, {d_solver.mkTrue(), d_solver.mkTrue(), d_solver.mkTrue()})); // mkTerm(Kind kind, const std::vector& children) const ASSERT_NO_THROW(d_solver.mkTerm(EQUAL, {v1})); ASSERT_THROW(d_solver.mkTerm(EQUAL, {v2}), CVC5ApiException); ASSERT_THROW(d_solver.mkTerm(EQUAL, {v3}), CVC5ApiException); ASSERT_THROW(d_solver.mkTerm(DISTINCT, {v6}), CVC5ApiException); // Test cases that are nary via the API but have arity = 2 internally Sort s_bool = d_solver.getBooleanSort(); Term t_bool = d_solver.mkConst(s_bool, "t_bool"); ASSERT_NO_THROW(d_solver.mkTerm(IMPLIES, {t_bool, t_bool, t_bool})); ASSERT_NO_THROW( d_solver.mkTerm(d_solver.mkOp(IMPLIES), {t_bool, t_bool, t_bool})); ASSERT_NO_THROW(d_solver.mkTerm(XOR, {t_bool, t_bool, t_bool})); ASSERT_NO_THROW( d_solver.mkTerm(d_solver.mkOp(XOR), {t_bool, t_bool, t_bool})); Term t_int = d_solver.mkConst(d_solver.getIntegerSort(), "t_int"); ASSERT_NO_THROW(d_solver.mkTerm(DIVISION, {t_int, t_int, t_int})); ASSERT_NO_THROW( d_solver.mkTerm(d_solver.mkOp(DIVISION), {t_int, t_int, t_int})); ASSERT_NO_THROW(d_solver.mkTerm(INTS_DIVISION, {t_int, t_int, t_int})); ASSERT_NO_THROW( d_solver.mkTerm(d_solver.mkOp(INTS_DIVISION), {t_int, t_int, t_int})); ASSERT_NO_THROW(d_solver.mkTerm(SUB, {t_int, t_int, t_int})); ASSERT_NO_THROW(d_solver.mkTerm(d_solver.mkOp(SUB), {t_int, t_int, t_int})); ASSERT_NO_THROW(d_solver.mkTerm(EQUAL, {t_int, t_int, t_int})); ASSERT_NO_THROW(d_solver.mkTerm(d_solver.mkOp(EQUAL), {t_int, t_int, t_int})); ASSERT_NO_THROW(d_solver.mkTerm(LT, {t_int, t_int, t_int})); ASSERT_NO_THROW(d_solver.mkTerm(d_solver.mkOp(LT), {t_int, t_int, t_int})); ASSERT_NO_THROW(d_solver.mkTerm(GT, {t_int, t_int, t_int})); ASSERT_NO_THROW(d_solver.mkTerm(d_solver.mkOp(GT), {t_int, t_int, t_int})); ASSERT_NO_THROW(d_solver.mkTerm(LEQ, {t_int, t_int, t_int})); ASSERT_NO_THROW(d_solver.mkTerm(d_solver.mkOp(LEQ), {t_int, t_int, t_int})); ASSERT_NO_THROW(d_solver.mkTerm(GEQ, {t_int, t_int, t_int})); ASSERT_NO_THROW(d_solver.mkTerm(d_solver.mkOp(GEQ), {t_int, t_int, t_int})); Term t_reg = d_solver.mkConst(d_solver.getRegExpSort(), "t_reg"); ASSERT_NO_THROW(d_solver.mkTerm(REGEXP_DIFF, {t_reg, t_reg, t_reg})); ASSERT_NO_THROW( d_solver.mkTerm(d_solver.mkOp(REGEXP_DIFF), {t_reg, t_reg, t_reg})); Term t_fun = d_solver.mkConst( d_solver.mkFunctionSort({s_bool, s_bool, s_bool}, s_bool)); ASSERT_NO_THROW(d_solver.mkTerm(HO_APPLY, {t_fun, t_bool, t_bool, t_bool})); ASSERT_NO_THROW(d_solver.mkTerm(d_solver.mkOp(HO_APPLY), {t_fun, t_bool, t_bool, t_bool})); } TEST_F(TestApiBlackSolver, mkTermFromOp) { Sort bv32 = d_solver.mkBitVectorSort(32); Term a = d_solver.mkConst(bv32, "a"); Term b = d_solver.mkConst(bv32, "b"); std::vector v1 = {d_solver.mkInteger(1), d_solver.mkInteger(2)}; std::vector v2 = {d_solver.mkInteger(1), Term()}; std::vector v3 = {}; std::vector v4 = {d_solver.mkInteger(5)}; Solver slv; // simple operator terms Op opterm1 = d_solver.mkOp(BITVECTOR_EXTRACT, {2, 1}); Op opterm2 = d_solver.mkOp(DIVISIBLE, {1}); // list datatype Sort sort = d_solver.mkParamSort("T"); DatatypeDecl listDecl = d_solver.mkDatatypeDecl("paramlist", {sort}); DatatypeConstructorDecl cons = d_solver.mkDatatypeConstructorDecl("cons"); DatatypeConstructorDecl nil = d_solver.mkDatatypeConstructorDecl("nil"); cons.addSelector("head", sort); cons.addSelectorSelf("tail"); listDecl.addConstructor(cons); listDecl.addConstructor(nil); Sort listSort = d_solver.mkDatatypeSort(listDecl); Sort intListSort = listSort.instantiate(std::vector{d_solver.getIntegerSort()}); Term c = d_solver.mkConst(intListSort, "c"); Datatype list = listSort.getDatatype(); // list datatype constructor and selector operator terms Term consTerm = list.getConstructor("cons").getTerm(); Term nilTerm = list.getConstructor("nil").getTerm(); Term headTerm = list["cons"].getSelector("head").getTerm(); Term tailTerm = list["cons"]["tail"].getTerm(); // mkTerm(Op op, Term term) const ASSERT_NO_THROW(d_solver.mkTerm(APPLY_CONSTRUCTOR, {nilTerm})); ASSERT_THROW(d_solver.mkTerm(APPLY_SELECTOR, {nilTerm}), CVC5ApiException); ASSERT_THROW(d_solver.mkTerm(APPLY_SELECTOR, {consTerm}), CVC5ApiException); ASSERT_THROW(d_solver.mkTerm(APPLY_CONSTRUCTOR, {consTerm}), CVC5ApiException); ASSERT_THROW(d_solver.mkTerm(opterm1), CVC5ApiException); ASSERT_THROW(d_solver.mkTerm(APPLY_SELECTOR, {headTerm}), CVC5ApiException); ASSERT_THROW(d_solver.mkTerm(opterm1), CVC5ApiException); ASSERT_NO_THROW(slv.mkTerm(APPLY_CONSTRUCTOR, {nilTerm})); // mkTerm(Op op, Term child) const ASSERT_NO_THROW(d_solver.mkTerm(opterm1, {a})); ASSERT_NO_THROW(d_solver.mkTerm(opterm2, {d_solver.mkInteger(1)})); ASSERT_NO_THROW(d_solver.mkTerm(APPLY_SELECTOR, {headTerm, c})); ASSERT_NO_THROW(d_solver.mkTerm(APPLY_SELECTOR, {tailTerm, c})); ASSERT_THROW(d_solver.mkTerm(opterm2, {a}), CVC5ApiException); ASSERT_THROW(d_solver.mkTerm(opterm1, {Term()}), CVC5ApiException); ASSERT_THROW( d_solver.mkTerm(APPLY_CONSTRUCTOR, {consTerm, d_solver.mkInteger(0)}), CVC5ApiException); ASSERT_NO_THROW(slv.mkTerm(opterm1, {a})); // mkTerm(Op op, Term child1, Term child2) const ASSERT_NO_THROW( d_solver.mkTerm(APPLY_CONSTRUCTOR, {consTerm, d_solver.mkInteger(0), d_solver.mkTerm(APPLY_CONSTRUCTOR, {nilTerm})})); ASSERT_THROW( d_solver.mkTerm(opterm2, {d_solver.mkInteger(1), d_solver.mkInteger(2)}), CVC5ApiException); ASSERT_THROW(d_solver.mkTerm(opterm1, {a, b}), CVC5ApiException); ASSERT_THROW(d_solver.mkTerm(opterm2, {d_solver.mkInteger(1), Term()}), CVC5ApiException); ASSERT_THROW(d_solver.mkTerm(opterm2, {Term(), d_solver.mkInteger(1)}), CVC5ApiException); ASSERT_NO_THROW(slv.mkTerm(APPLY_CONSTRUCTOR, {consTerm, d_solver.mkInteger(0), d_solver.mkTerm(APPLY_CONSTRUCTOR, {nilTerm})})); // mkTerm(Op op, Term child1, Term child2, Term child3) const ASSERT_THROW(d_solver.mkTerm(opterm1, {a, b, a}), CVC5ApiException); ASSERT_THROW( d_solver.mkTerm(opterm2, {d_solver.mkInteger(1), d_solver.mkInteger(1), Term()}), CVC5ApiException); // mkTerm(Op op, const std::vector& children) const ASSERT_NO_THROW(d_solver.mkTerm(opterm2, {v4})); ASSERT_THROW(d_solver.mkTerm(opterm2, {v1}), CVC5ApiException); ASSERT_THROW(d_solver.mkTerm(opterm2, {v2}), CVC5ApiException); ASSERT_THROW(d_solver.mkTerm(opterm2, {v3}), CVC5ApiException); ASSERT_NO_THROW(slv.mkTerm(opterm2, {v4})); } TEST_F(TestApiBlackSolver, mkTrue) { ASSERT_NO_THROW(d_solver.mkTrue()); ASSERT_NO_THROW(d_solver.mkTrue()); } TEST_F(TestApiBlackSolver, mkTuple) { ASSERT_NO_THROW(d_solver.mkTuple({d_solver.mkBitVectorSort(3)}, {d_solver.mkBitVector(3, "101", 2)})); ASSERT_THROW( d_solver.mkTuple({d_solver.getRealSort()}, {d_solver.mkInteger("5")}), CVC5ApiException); ASSERT_THROW(d_solver.mkTuple({}, {d_solver.mkBitVector(3, "101", 2)}), CVC5ApiException); ASSERT_THROW(d_solver.mkTuple({d_solver.mkBitVectorSort(4)}, {d_solver.mkBitVector(3, "101", 2)}), CVC5ApiException); ASSERT_THROW( d_solver.mkTuple({d_solver.getIntegerSort()}, {d_solver.mkReal("5.3")}), CVC5ApiException); Solver slv; ASSERT_NO_THROW(slv.mkTuple({d_solver.mkBitVectorSort(3)}, {slv.mkBitVector(3, "101", 2)})); ASSERT_NO_THROW(slv.mkTuple({slv.mkBitVectorSort(3)}, {d_solver.mkBitVector(3, "101", 2)})); } TEST_F(TestApiBlackSolver, mkUniverseSet) { ASSERT_NO_THROW(d_solver.mkUniverseSet(d_solver.getBooleanSort())); ASSERT_THROW(d_solver.mkUniverseSet(Sort()), CVC5ApiException); Solver slv; ASSERT_NO_THROW(slv.mkUniverseSet(d_solver.getBooleanSort())); } TEST_F(TestApiBlackSolver, mkConst) { Sort boolSort = d_solver.getBooleanSort(); Sort intSort = d_solver.getIntegerSort(); Sort funSort = d_solver.mkFunctionSort({intSort}, boolSort); ASSERT_NO_THROW(d_solver.mkConst(boolSort)); ASSERT_NO_THROW(d_solver.mkConst(funSort)); ASSERT_NO_THROW(d_solver.mkConst(boolSort, std::string("b"))); ASSERT_NO_THROW(d_solver.mkConst(intSort, std::string("i"))); ASSERT_NO_THROW(d_solver.mkConst(funSort, "f")); ASSERT_NO_THROW(d_solver.mkConst(funSort, "")); ASSERT_THROW(d_solver.mkConst(Sort()), CVC5ApiException); ASSERT_THROW(d_solver.mkConst(Sort(), "a"), CVC5ApiException); Solver slv; ASSERT_NO_THROW(slv.mkConst(boolSort)); } TEST_F(TestApiBlackSolver, mkConstArray) { Sort intSort = d_solver.getIntegerSort(); Sort arrSort = d_solver.mkArraySort(intSort, intSort); Term zero = d_solver.mkInteger(0); Term constArr = d_solver.mkConstArray(arrSort, zero); ASSERT_NO_THROW(d_solver.mkConstArray(arrSort, zero)); ASSERT_THROW(d_solver.mkConstArray(Sort(), zero), CVC5ApiException); ASSERT_THROW(d_solver.mkConstArray(arrSort, Term()), CVC5ApiException); ASSERT_THROW(d_solver.mkConstArray(arrSort, d_solver.mkBitVector(1, 1)), CVC5ApiException); ASSERT_THROW(d_solver.mkConstArray(intSort, zero), CVC5ApiException); Solver slv; Term zero2 = slv.mkInteger(0); Sort arrSort2 = slv.mkArraySort(slv.getIntegerSort(), slv.getIntegerSort()); ASSERT_NO_THROW(slv.mkConstArray(arrSort2, zero)); ASSERT_NO_THROW(slv.mkConstArray(arrSort, zero2)); } TEST_F(TestApiBlackSolver, declareDatatype) { DatatypeConstructorDecl lin = d_solver.mkDatatypeConstructorDecl("lin"); std::vector ctors0 = {lin}; ASSERT_NO_THROW(d_solver.declareDatatype(std::string(""), ctors0)); DatatypeConstructorDecl nil = d_solver.mkDatatypeConstructorDecl("nil"); std::vector ctors1 = {nil}; ASSERT_NO_THROW(d_solver.declareDatatype(std::string("a"), ctors1)); DatatypeConstructorDecl cons = d_solver.mkDatatypeConstructorDecl("cons"); DatatypeConstructorDecl nil2 = d_solver.mkDatatypeConstructorDecl("nil"); std::vector ctors2 = {cons, nil2}; ASSERT_NO_THROW(d_solver.declareDatatype(std::string("b"), ctors2)); DatatypeConstructorDecl cons2 = d_solver.mkDatatypeConstructorDecl("cons"); DatatypeConstructorDecl nil3 = d_solver.mkDatatypeConstructorDecl("nil"); std::vector ctors3 = {cons2, nil3}; ASSERT_NO_THROW(d_solver.declareDatatype(std::string(""), ctors3)); // must have at least one constructor std::vector ctors4; ASSERT_THROW(d_solver.declareDatatype(std::string("c"), ctors4), CVC5ApiException); // constructors may not be reused DatatypeConstructorDecl ctor1 = d_solver.mkDatatypeConstructorDecl("_x21"); DatatypeConstructorDecl ctor2 = d_solver.mkDatatypeConstructorDecl("_x31"); Sort s3 = d_solver.declareDatatype(std::string("_x17"), {ctor1, ctor2}); ASSERT_THROW(d_solver.declareDatatype(std::string("_x86"), {ctor1, ctor2}), CVC5ApiException); Solver slv; ASSERT_THROW(slv.declareDatatype(std::string("a"), ctors1), CVC5ApiException); } TEST_F(TestApiBlackSolver, declareFun) { Sort bvSort = d_solver.mkBitVectorSort(32); Sort funSort = d_solver.mkFunctionSort({d_solver.mkUninterpretedSort("u")}, d_solver.getIntegerSort()); ASSERT_NO_THROW(d_solver.declareFun("f1", {}, bvSort)); ASSERT_NO_THROW( d_solver.declareFun("f3", {bvSort, d_solver.getIntegerSort()}, bvSort)); ASSERT_THROW(d_solver.declareFun("f2", {}, funSort), CVC5ApiException); // functions as arguments is allowed ASSERT_NO_THROW(d_solver.declareFun("f4", {bvSort, funSort}, bvSort)); ASSERT_THROW(d_solver.declareFun("f5", {bvSort, bvSort}, funSort), CVC5ApiException); Solver slv; ASSERT_NO_THROW(slv.declareFun("f1", {}, bvSort)); } TEST_F(TestApiBlackSolver, declareSort) { ASSERT_NO_THROW(d_solver.declareSort("s", 0)); ASSERT_NO_THROW(d_solver.declareSort("s", 2)); ASSERT_NO_THROW(d_solver.declareSort("", 2)); } TEST_F(TestApiBlackSolver, defineSort) { Sort sortVar0 = d_solver.mkParamSort("T0"); Sort sortVar1 = d_solver.mkParamSort("T1"); Sort intSort = d_solver.getIntegerSort(); Sort realSort = d_solver.getRealSort(); Sort arraySort0 = d_solver.mkArraySort(sortVar0, sortVar0); Sort arraySort1 = d_solver.mkArraySort(sortVar0, sortVar1); // Now create instantiations of the defined sorts ASSERT_NO_THROW(arraySort0.substitute(sortVar0, intSort)); ASSERT_NO_THROW( arraySort1.substitute({sortVar0, sortVar1}, {intSort, realSort})); } TEST_F(TestApiBlackSolver, defineFun) { Sort bvSort = d_solver.mkBitVectorSort(32); Sort funSort = d_solver.mkFunctionSort({d_solver.mkUninterpretedSort("u")}, d_solver.getIntegerSort()); Term b1 = d_solver.mkVar(bvSort, "b1"); Term b2 = d_solver.mkVar(d_solver.getIntegerSort(), "b2"); Term b3 = d_solver.mkVar(funSort, "b3"); Term v1 = d_solver.mkConst(bvSort, "v1"); Term v2 = d_solver.mkConst(funSort, "v2"); ASSERT_NO_THROW(d_solver.defineFun("f", {}, bvSort, v1)); ASSERT_NO_THROW(d_solver.defineFun("ff", {b1, b2}, bvSort, v1)); ASSERT_THROW(d_solver.defineFun("ff", {v1, b2}, bvSort, v1), CVC5ApiException); ASSERT_THROW(d_solver.defineFun("fff", {b1}, bvSort, v2), CVC5ApiException); ASSERT_THROW(d_solver.defineFun("ffff", {b1}, funSort, v2), CVC5ApiException); // b3 has function sort, which is allowed as an argument ASSERT_NO_THROW(d_solver.defineFun("fffff", {b1, b3}, bvSort, v1)); Solver slv; Sort bvSort2 = slv.mkBitVectorSort(32); Term v12 = slv.mkConst(bvSort2, "v1"); Term b12 = slv.mkVar(bvSort2, "b1"); Term b22 = slv.mkVar(slv.getIntegerSort(), "b2"); ASSERT_NO_THROW(slv.defineFun("f", {}, bvSort, v12)); ASSERT_NO_THROW(slv.defineFun("f", {}, bvSort2, v1)); ASSERT_NO_THROW(slv.defineFun("ff", {b1, b22}, bvSort2, v12)); ASSERT_NO_THROW(slv.defineFun("ff", {b12, b2}, bvSort2, v12)); ASSERT_NO_THROW(slv.defineFun("ff", {b12, b22}, bvSort, v12)); ASSERT_NO_THROW(slv.defineFun("ff", {b12, b22}, bvSort2, v1)); } TEST_F(TestApiBlackSolver, defineFunGlobal) { Sort bSort = d_solver.getBooleanSort(); Term bTrue = d_solver.mkBoolean(true); // (define-fun f () Bool true) Term f = d_solver.defineFun("f", {}, bSort, bTrue, true); Term b = d_solver.mkVar(bSort, "b"); // (define-fun g (b Bool) Bool b) Term g = d_solver.defineFun("g", {b}, bSort, b, true); // (assert (or (not f) (not (g true)))) d_solver.assertFormula(d_solver.mkTerm( OR, {f.notTerm(), d_solver.mkTerm(APPLY_UF, {g, bTrue}).notTerm()})); ASSERT_TRUE(d_solver.checkSat().isUnsat()); d_solver.resetAssertions(); // (assert (or (not f) (not (g true)))) d_solver.assertFormula(d_solver.mkTerm( OR, {f.notTerm(), d_solver.mkTerm(APPLY_UF, {g, bTrue}).notTerm()})); ASSERT_TRUE(d_solver.checkSat().isUnsat()); } TEST_F(TestApiBlackSolver, defineFunRec) { Sort bvSort = d_solver.mkBitVectorSort(32); Sort funSort1 = d_solver.mkFunctionSort({bvSort, bvSort}, bvSort); Sort funSort2 = d_solver.mkFunctionSort({d_solver.mkUninterpretedSort("u")}, d_solver.getIntegerSort()); Term b1 = d_solver.mkVar(bvSort, "b1"); Term b11 = d_solver.mkVar(bvSort, "b1"); Term b2 = d_solver.mkVar(d_solver.getIntegerSort(), "b2"); Term b3 = d_solver.mkVar(funSort2, "b3"); Term v1 = d_solver.mkConst(bvSort, "v1"); Term v2 = d_solver.mkConst(d_solver.getIntegerSort(), "v2"); Term v3 = d_solver.mkConst(funSort2, "v3"); Term f1 = d_solver.mkConst(funSort1, "f1"); Term f2 = d_solver.mkConst(funSort2, "f2"); Term f3 = d_solver.mkConst(bvSort, "f3"); ASSERT_NO_THROW(d_solver.defineFunRec("f", {}, bvSort, v1)); ASSERT_NO_THROW(d_solver.defineFunRec("ff", {b1, b2}, bvSort, v1)); ASSERT_NO_THROW(d_solver.defineFunRec(f1, {b1, b11}, v1)); ASSERT_THROW(d_solver.defineFunRec("fff", {b1}, bvSort, v3), CVC5ApiException); ASSERT_THROW(d_solver.defineFunRec("ff", {b1, v2}, bvSort, v1), CVC5ApiException); ASSERT_THROW(d_solver.defineFunRec("ffff", {b1}, funSort2, v3), CVC5ApiException); // b3 has function sort, which is allowed as an argument ASSERT_NO_THROW(d_solver.defineFunRec("fffff", {b1, b3}, bvSort, v1)); ASSERT_THROW(d_solver.defineFunRec(f1, {b1}, v1), CVC5ApiException); ASSERT_THROW(d_solver.defineFunRec(f1, {b1, b11}, v2), CVC5ApiException); ASSERT_THROW(d_solver.defineFunRec(f1, {b1, b11}, v3), CVC5ApiException); ASSERT_THROW(d_solver.defineFunRec(f2, {b1}, v2), CVC5ApiException); ASSERT_THROW(d_solver.defineFunRec(f3, {b1}, v1), CVC5ApiException); Solver slv; Sort bvSort2 = slv.mkBitVectorSort(32); Term v12 = slv.mkConst(bvSort2, "v1"); Term b12 = slv.mkVar(bvSort2, "b1"); Term b22 = slv.mkVar(slv.getIntegerSort(), "b2"); ASSERT_NO_THROW(slv.defineFunRec("f", {}, bvSort2, v12)); ASSERT_NO_THROW(slv.defineFunRec("ff", {b12, b22}, bvSort2, v12)); ASSERT_NO_THROW(slv.defineFunRec("f", {}, bvSort, v12)); ASSERT_NO_THROW(slv.defineFunRec("f", {}, bvSort2, v1)); ASSERT_NO_THROW(slv.defineFunRec("ff", {b1, b22}, bvSort2, v12)); ASSERT_NO_THROW(slv.defineFunRec("ff", {b12, b2}, bvSort2, v12)); ASSERT_NO_THROW(slv.defineFunRec("ff", {b12, b22}, bvSort, v12)); ASSERT_NO_THROW(slv.defineFunRec("ff", {b12, b22}, bvSort2, v1)); } TEST_F(TestApiBlackSolver, defineFunRecWrongLogic) { d_solver.setLogic("QF_BV"); Sort bvSort = d_solver.mkBitVectorSort(32); Sort funSort = d_solver.mkFunctionSort({bvSort, bvSort}, bvSort); Term b = d_solver.mkVar(bvSort, "b"); Term v = d_solver.mkConst(bvSort, "v"); Term f = d_solver.mkConst(funSort, "f"); ASSERT_THROW(d_solver.defineFunRec("f", {}, bvSort, v), CVC5ApiException); ASSERT_THROW(d_solver.defineFunRec(f, {b, b}, v), CVC5ApiException); } TEST_F(TestApiBlackSolver, defineFunRecGlobal) { Sort bSort = d_solver.getBooleanSort(); Sort fSort = d_solver.mkFunctionSort({bSort}, bSort); d_solver.push(); Term bTrue = d_solver.mkBoolean(true); // (define-fun f () Bool true) Term f = d_solver.defineFunRec("f", {}, bSort, bTrue, true); Term b = d_solver.mkVar(bSort, "b"); Term gSym = d_solver.mkConst(fSort, "g"); // (define-fun g (b Bool) Bool b) Term g = d_solver.defineFunRec(gSym, {b}, b, true); // (assert (or (not f) (not (g true)))) d_solver.assertFormula(d_solver.mkTerm( OR, {f.notTerm(), d_solver.mkTerm(APPLY_UF, {g, bTrue}).notTerm()})); ASSERT_TRUE(d_solver.checkSat().isUnsat()); d_solver.pop(); // (assert (or (not f) (not (g true)))) d_solver.assertFormula(d_solver.mkTerm( OR, {f.notTerm(), d_solver.mkTerm(APPLY_UF, {g, bTrue}).notTerm()})); ASSERT_TRUE(d_solver.checkSat().isUnsat()); } TEST_F(TestApiBlackSolver, defineFunsRec) { Sort uSort = d_solver.mkUninterpretedSort("u"); Sort bvSort = d_solver.mkBitVectorSort(32); Sort funSort1 = d_solver.mkFunctionSort({bvSort, bvSort}, bvSort); Sort funSort2 = d_solver.mkFunctionSort({uSort}, d_solver.getIntegerSort()); Term b1 = d_solver.mkVar(bvSort, "b1"); Term b11 = d_solver.mkVar(bvSort, "b1"); Term b2 = d_solver.mkVar(d_solver.getIntegerSort(), "b2"); Term b3 = d_solver.mkVar(funSort2, "b3"); Term b4 = d_solver.mkVar(uSort, "b4"); Term v1 = d_solver.mkConst(bvSort, "v1"); Term v2 = d_solver.mkConst(d_solver.getIntegerSort(), "v2"); Term v3 = d_solver.mkConst(funSort2, "v3"); Term v4 = d_solver.mkConst(uSort, "v4"); Term f1 = d_solver.mkConst(funSort1, "f1"); Term f2 = d_solver.mkConst(funSort2, "f2"); Term f3 = d_solver.mkConst(bvSort, "f3"); ASSERT_NO_THROW( d_solver.defineFunsRec({f1, f2}, {{b1, b11}, {b4}}, {v1, v2})); ASSERT_THROW(d_solver.defineFunsRec({f1, f2}, {{v1, b11}, {b4}}, {v1, v2}), CVC5ApiException); ASSERT_THROW(d_solver.defineFunsRec({f1, f3}, {{b1, b11}, {b4}}, {v1, v2}), CVC5ApiException); ASSERT_THROW(d_solver.defineFunsRec({f1, f2}, {{b1}, {b4}}, {v1, v2}), CVC5ApiException); ASSERT_THROW(d_solver.defineFunsRec({f1, f2}, {{b1, b2}, {b4}}, {v1, v2}), CVC5ApiException); ASSERT_THROW(d_solver.defineFunsRec({f1, f2}, {{b1, b11}, {b4}}, {v1, v4}), CVC5ApiException); Solver slv; Sort uSort2 = slv.mkUninterpretedSort("u"); Sort bvSort2 = slv.mkBitVectorSort(32); Sort funSort12 = slv.mkFunctionSort({bvSort2, bvSort2}, bvSort2); Sort funSort22 = slv.mkFunctionSort({uSort2}, slv.getIntegerSort()); Term b12 = slv.mkVar(bvSort2, "b1"); Term b112 = slv.mkVar(bvSort2, "b1"); Term b42 = slv.mkVar(uSort2, "b4"); Term v12 = slv.mkConst(bvSort2, "v1"); Term v22 = slv.mkConst(slv.getIntegerSort(), "v2"); Term f12 = slv.mkConst(funSort12, "f1"); Term f22 = slv.mkConst(funSort22, "f2"); ASSERT_NO_THROW( slv.defineFunsRec({f12, f22}, {{b12, b112}, {b42}}, {v12, v22})); ASSERT_NO_THROW( slv.defineFunsRec({f1, f22}, {{b12, b112}, {b42}}, {v12, v22})); ASSERT_THROW(slv.defineFunsRec({f12, f2}, {{b12, b112}, {b42}}, {v12, v22}), CVC5ApiException); ASSERT_NO_THROW( slv.defineFunsRec({f12, f22}, {{b1, b112}, {b42}}, {v12, v22})); ASSERT_NO_THROW( slv.defineFunsRec({f12, f22}, {{b12, b11}, {b42}}, {v12, v22})); ASSERT_THROW(slv.defineFunsRec({f12, f22}, {{b12, b112}, {b4}}, {v12, v22}), CVC5ApiException); ASSERT_NO_THROW( slv.defineFunsRec({f12, f22}, {{b12, b112}, {b42}}, {v1, v22})); ASSERT_NO_THROW( slv.defineFunsRec({f12, f22}, {{b12, b112}, {b42}}, {v12, v2})); } TEST_F(TestApiBlackSolver, defineFunsRecWrongLogic) { d_solver.setLogic("QF_BV"); Sort uSort = d_solver.mkUninterpretedSort("u"); Sort bvSort = d_solver.mkBitVectorSort(32); Sort funSort1 = d_solver.mkFunctionSort({bvSort, bvSort}, bvSort); Sort funSort2 = d_solver.mkFunctionSort({uSort}, d_solver.getIntegerSort()); Term b = d_solver.mkVar(bvSort, "b"); Term u = d_solver.mkVar(uSort, "u"); Term v1 = d_solver.mkConst(bvSort, "v1"); Term v2 = d_solver.mkConst(d_solver.getIntegerSort(), "v2"); Term f1 = d_solver.mkConst(funSort1, "f1"); Term f2 = d_solver.mkConst(funSort2, "f2"); ASSERT_THROW(d_solver.defineFunsRec({f1, f2}, {{b, b}, {u}}, {v1, v2}), CVC5ApiException); } TEST_F(TestApiBlackSolver, defineFunsRecGlobal) { Sort bSort = d_solver.getBooleanSort(); Sort fSort = d_solver.mkFunctionSort({bSort}, bSort); d_solver.push(); Term bTrue = d_solver.mkBoolean(true); Term b = d_solver.mkVar(bSort, "b"); Term gSym = d_solver.mkConst(fSort, "g"); // (define-funs-rec ((g ((b Bool)) Bool)) (b)) d_solver.defineFunsRec({gSym}, {{b}}, {b}, true); // (assert (not (g true))) d_solver.assertFormula(d_solver.mkTerm(APPLY_UF, {gSym, bTrue}).notTerm()); ASSERT_TRUE(d_solver.checkSat().isUnsat()); d_solver.pop(); // (assert (not (g true))) d_solver.assertFormula(d_solver.mkTerm(APPLY_UF, {gSym, bTrue}).notTerm()); ASSERT_TRUE(d_solver.checkSat().isUnsat()); } TEST_F(TestApiBlackSolver, uFIteration) { Sort intSort = d_solver.getIntegerSort(); Sort funSort = d_solver.mkFunctionSort({intSort, intSort}, intSort); Term x = d_solver.mkConst(intSort, "x"); Term y = d_solver.mkConst(intSort, "y"); Term f = d_solver.mkConst(funSort, "f"); Term fxy = d_solver.mkTerm(APPLY_UF, {f, x, y}); // Expecting the uninterpreted function to be one of the children Term expected_children[3] = {f, x, y}; uint32_t idx = 0; for (auto c : fxy) { ASSERT_LT(idx, 3); ASSERT_EQ(c, expected_children[idx]); idx++; } } TEST_F(TestApiBlackSolver, getAssertions) { Term a = d_solver.mkConst(d_solver.getBooleanSort(), "a"); Term b = d_solver.mkConst(d_solver.getBooleanSort(), "b"); d_solver.assertFormula(a); d_solver.assertFormula(b); std::vector asserts{a, b}; ASSERT_EQ(d_solver.getAssertions(), asserts); } TEST_F(TestApiBlackSolver, getInfo) { ASSERT_NO_THROW(d_solver.getInfo("name")); ASSERT_THROW(d_solver.getInfo("asdf"), CVC5ApiException); } TEST_F(TestApiBlackSolver, getAbduct) { d_solver.setLogic("QF_LIA"); d_solver.setOption("produce-abducts", "true"); d_solver.setOption("incremental", "false"); Sort intSort = d_solver.getIntegerSort(); Term zero = d_solver.mkInteger(0); Term x = d_solver.mkConst(intSort, "x"); Term y = d_solver.mkConst(intSort, "y"); // Assumptions for abduction: x > 0 d_solver.assertFormula(d_solver.mkTerm(GT, {x, zero})); // Conjecture for abduction: y > 0 Term conj = d_solver.mkTerm(GT, {y, zero}); // Call the abduction api, while the resulting abduct is the output Term output = d_solver.getAbduct(conj); // We expect the resulting output to be a boolean formula ASSERT_TRUE(!output.isNull() && output.getSort().isBoolean()); // try with a grammar, a simple grammar admitting true Sort boolean = d_solver.getBooleanSort(); Term truen = d_solver.mkBoolean(true); Term start = d_solver.mkVar(boolean); Term output2; Grammar g = d_solver.mkGrammar({}, {start}); Term conj2 = d_solver.mkTerm(GT, {x, zero}); ASSERT_NO_THROW(g.addRule(start, truen)); // Call the abduction api, while the resulting abduct is the output output2 = d_solver.getAbduct(conj2, g); // abduct must be true ASSERT_EQ(output2, truen); } TEST_F(TestApiBlackSolver, getAbduct2) { d_solver.setLogic("QF_LIA"); d_solver.setOption("incremental", "false"); Sort intSort = d_solver.getIntegerSort(); Term zero = d_solver.mkInteger(0); Term x = d_solver.mkConst(intSort, "x"); Term y = d_solver.mkConst(intSort, "y"); // Assumptions for abduction: x > 0 d_solver.assertFormula(d_solver.mkTerm(GT, {x, zero})); // Conjecture for abduction: y > 0 Term conj = d_solver.mkTerm(GT, {y, zero}); // Fails due to option not set ASSERT_THROW(d_solver.getAbduct(conj), CVC5ApiException); } TEST_F(TestApiBlackSolver, getAbductNext) { d_solver.setLogic("QF_LIA"); d_solver.setOption("produce-abducts", "true"); d_solver.setOption("incremental", "true"); Sort intSort = d_solver.getIntegerSort(); Term zero = d_solver.mkInteger(0); Term x = d_solver.mkConst(intSort, "x"); Term y = d_solver.mkConst(intSort, "y"); // Assumptions for abduction: x > 0 d_solver.assertFormula(d_solver.mkTerm(GT, {x, zero})); // Conjecture for abduction: y > 0 Term conj = d_solver.mkTerm(GT, {y, zero}); // Call the abduction api, while the resulting abduct is the output Term output = d_solver.getAbduct(conj); Term output2 = d_solver.getAbductNext(); // should produce a different output ASSERT_TRUE(output != output2); } TEST_F(TestApiBlackSolver, getInterpolant) { d_solver.setLogic("QF_LIA"); d_solver.setOption("produce-interpolants", "true"); d_solver.setOption("incremental", "false"); Sort intSort = d_solver.getIntegerSort(); Term zero = d_solver.mkInteger(0); Term x = d_solver.mkConst(intSort, "x"); Term y = d_solver.mkConst(intSort, "y"); Term z = d_solver.mkConst(intSort, "z"); // Assumptions for interpolation: x + y > 0 /\ x < 0 d_solver.assertFormula( d_solver.mkTerm(GT, {d_solver.mkTerm(ADD, {x, y}), zero})); d_solver.assertFormula(d_solver.mkTerm(LT, {x, zero})); // Conjecture for interpolation: y + z > 0 \/ z < 0 Term conj = d_solver.mkTerm( OR, {d_solver.mkTerm(GT, {d_solver.mkTerm(ADD, {y, z}), zero}), d_solver.mkTerm(LT, {z, zero})}); // Call the interpolation api, while the resulting interpolant is the output Term output = d_solver.getInterpolant(conj); // We expect the resulting output to be a boolean formula ASSERT_TRUE(output.getSort().isBoolean()); // try with a grammar, a simple grammar admitting true Sort boolean = d_solver.getBooleanSort(); Term truen = d_solver.mkBoolean(true); Term start = d_solver.mkVar(boolean); Grammar g = d_solver.mkGrammar({}, {start}); Term conj2 = d_solver.mkTerm(EQUAL, {zero, zero}); ASSERT_NO_THROW(g.addRule(start, truen)); // Call the interpolation api, while the resulting interpolant is the output Term output2 = d_solver.getInterpolant(conj2, g); // interpolant must be true ASSERT_EQ(output2, truen); } TEST_F(TestApiBlackSolver, getInterpolantNext) { d_solver.setLogic("QF_LIA"); d_solver.setOption("produce-interpolants", "true"); d_solver.setOption("incremental", "true"); Sort intSort = d_solver.getIntegerSort(); Term zero = d_solver.mkInteger(0); Term x = d_solver.mkConst(intSort, "x"); Term y = d_solver.mkConst(intSort, "y"); Term z = d_solver.mkConst(intSort, "z"); // Assumptions for interpolation: x + y > 0 /\ x < 0 d_solver.assertFormula( d_solver.mkTerm(GT, {d_solver.mkTerm(ADD, {x, y}), zero})); d_solver.assertFormula(d_solver.mkTerm(LT, {x, zero})); // Conjecture for interpolation: y + z > 0 \/ z < 0 Term conj = d_solver.mkTerm( OR, {d_solver.mkTerm(GT, {d_solver.mkTerm(ADD, {y, z}), zero}), d_solver.mkTerm(LT, {z, zero})}); Term output = d_solver.getInterpolant(conj); Term output2 = d_solver.getInterpolantNext(); // We expect the next output to be distinct ASSERT_TRUE(output != output2); } TEST_F(TestApiBlackSolver, declarePool) { Sort intSort = d_solver.getIntegerSort(); Sort setSort = d_solver.mkSetSort(intSort); Term zero = d_solver.mkInteger(0); Term x = d_solver.mkConst(intSort, "x"); Term y = d_solver.mkConst(intSort, "y"); // declare a pool with initial value { 0, x, y } Term p = d_solver.declarePool("p", intSort, {zero, x, y}); // pool should have the same sort ASSERT_TRUE(p.getSort() == setSort); // cannot pass null sort Sort nullSort; ASSERT_THROW(d_solver.declarePool("i", nullSort, {}), CVC5ApiException); } TEST_F(TestApiBlackSolver, getOp) { Sort bv32 = d_solver.mkBitVectorSort(32); Term a = d_solver.mkConst(bv32, "a"); Op ext = d_solver.mkOp(BITVECTOR_EXTRACT, {2, 1}); Term exta = d_solver.mkTerm(ext, {a}); ASSERT_FALSE(a.hasOp()); ASSERT_THROW(a.getOp(), CVC5ApiException); ASSERT_TRUE(exta.hasOp()); ASSERT_EQ(exta.getOp(), ext); // Test Datatypes -- more complicated DatatypeDecl consListSpec = d_solver.mkDatatypeDecl("list"); DatatypeConstructorDecl cons = d_solver.mkDatatypeConstructorDecl("cons"); cons.addSelector("head", d_solver.getIntegerSort()); cons.addSelectorSelf("tail"); consListSpec.addConstructor(cons); DatatypeConstructorDecl nil = d_solver.mkDatatypeConstructorDecl("nil"); consListSpec.addConstructor(nil); Sort consListSort = d_solver.mkDatatypeSort(consListSpec); Datatype consList = consListSort.getDatatype(); Term consTerm = consList.getConstructor("cons").getTerm(); Term nilTerm = consList.getConstructor("nil").getTerm(); Term headTerm = consList["cons"].getSelector("head").getTerm(); Term listnil = d_solver.mkTerm(APPLY_CONSTRUCTOR, {nilTerm}); Term listcons1 = d_solver.mkTerm(APPLY_CONSTRUCTOR, {consTerm, d_solver.mkInteger(1), listnil}); Term listhead = d_solver.mkTerm(APPLY_SELECTOR, {headTerm, listcons1}); ASSERT_TRUE(listnil.hasOp()); ASSERT_TRUE(listcons1.hasOp()); ASSERT_TRUE(listhead.hasOp()); } TEST_F(TestApiBlackSolver, getOption) { ASSERT_NO_THROW(d_solver.getOption("incremental")); ASSERT_THROW(d_solver.getOption("asdf"), CVC5ApiException); } TEST_F(TestApiBlackSolver, getOptionNames) { std::vector names = d_solver.getOptionNames(); ASSERT_TRUE(names.size() > 100); ASSERT_NE(std::find(names.begin(), names.end(), "verbose"), names.end()); ASSERT_EQ(std::find(names.begin(), names.end(), "foobar"), names.end()); } TEST_F(TestApiBlackSolver, getOptionInfo) { { ASSERT_THROW(d_solver.getOptionInfo("asdf-invalid"), CVC5ApiException); } { cvc5::OptionInfo info = d_solver.getOptionInfo("verbose"); ASSERT_EQ("verbose", info.name); ASSERT_EQ(std::vector{}, info.aliases); ASSERT_TRUE(std::holds_alternative(info.valueInfo)); std::stringstream ss; ss << info; ASSERT_EQ(ss.str(), "OptionInfo{ verbose | void }"); } { // bool type with default cvc5::OptionInfo info = d_solver.getOptionInfo("print-success"); ASSERT_EQ("print-success", info.name); ASSERT_EQ(std::vector{}, info.aliases); ASSERT_TRUE( std::holds_alternative>(info.valueInfo)); auto valInfo = std::get>(info.valueInfo); ASSERT_EQ(false, valInfo.defaultValue); ASSERT_EQ(false, valInfo.currentValue); ASSERT_EQ(info.boolValue(), false); std::stringstream ss; ss << info; ASSERT_EQ(ss.str(), "OptionInfo{ print-success | bool | false | default false }"); } { // int64 type with default cvc5::OptionInfo info = d_solver.getOptionInfo("verbosity"); ASSERT_EQ("verbosity", info.name); ASSERT_EQ(std::vector{}, info.aliases); ASSERT_TRUE(std::holds_alternative>( info.valueInfo)); auto numInfo = std::get>(info.valueInfo); ASSERT_EQ(0, numInfo.defaultValue); ASSERT_EQ(0, numInfo.currentValue); ASSERT_FALSE(numInfo.minimum || numInfo.maximum); ASSERT_EQ(info.intValue(), 0); std::stringstream ss; ss << info; ASSERT_EQ(ss.str(), "OptionInfo{ verbosity | int64_t | 0 | default 0 }"); } { // uint64 type with default cvc5::OptionInfo info = d_solver.getOptionInfo("rlimit"); ASSERT_EQ("rlimit", info.name); ASSERT_EQ(std::vector{}, info.aliases); ASSERT_TRUE(std::holds_alternative>( info.valueInfo)); auto numInfo = std::get>(info.valueInfo); ASSERT_EQ(0, numInfo.defaultValue); ASSERT_EQ(0, numInfo.currentValue); ASSERT_FALSE(numInfo.minimum || numInfo.maximum); ASSERT_EQ(info.uintValue(), 0); std::stringstream ss; ss << info; ASSERT_EQ(ss.str(), "OptionInfo{ rlimit | uint64_t | 0 | default 0 }"); } { auto info = d_solver.getOptionInfo("random-freq"); ASSERT_EQ(info.name, "random-freq"); ASSERT_EQ(info.aliases, std::vector{"random-frequency"}); ASSERT_TRUE(std::holds_alternative>( info.valueInfo)); auto ni = std::get>(info.valueInfo); ASSERT_EQ(ni.currentValue, 0.0); ASSERT_EQ(ni.defaultValue, 0.0); ASSERT_TRUE(ni.minimum && ni.maximum); ASSERT_EQ(*ni.minimum, 0.0); ASSERT_EQ(*ni.maximum, 1.0); ASSERT_EQ(info.doubleValue(), 0.0); std::stringstream ss; ss << info; ASSERT_EQ(ss.str(), "OptionInfo{ random-freq, random-frequency | double | 0 | " "default 0 | 0 <= x <= 1 }"); } { // string type with default cvc5::OptionInfo info = d_solver.getOptionInfo("force-logic"); ASSERT_EQ("force-logic", info.name); ASSERT_EQ(std::vector{}, info.aliases); ASSERT_TRUE(std::holds_alternative>( info.valueInfo)); auto valInfo = std::get>(info.valueInfo); ASSERT_EQ("", valInfo.defaultValue); ASSERT_EQ("", valInfo.currentValue); ASSERT_EQ(info.stringValue(), ""); std::stringstream ss; ss << info; ASSERT_EQ(ss.str(), "OptionInfo{ force-logic | string | \"\" | default \"\" }"); } { // mode option cvc5::OptionInfo info = d_solver.getOptionInfo("simplification"); ASSERT_EQ("simplification", info.name); ASSERT_EQ(std::vector{"simplification-mode"}, info.aliases); ASSERT_TRUE(std::holds_alternative(info.valueInfo)); auto modeInfo = std::get(info.valueInfo); ASSERT_EQ("batch", modeInfo.defaultValue); ASSERT_EQ("batch", modeInfo.currentValue); ASSERT_EQ(2, modeInfo.modes.size()); ASSERT_TRUE(std::find(modeInfo.modes.begin(), modeInfo.modes.end(), "batch") != modeInfo.modes.end()); ASSERT_TRUE(std::find(modeInfo.modes.begin(), modeInfo.modes.end(), "none") != modeInfo.modes.end()); std::stringstream ss; ss << info; ASSERT_EQ(ss.str(), "OptionInfo{ simplification, simplification-mode | mode | batch " "| default batch | modes: batch, none }"); } } TEST_F(TestApiBlackSolver, getDriverOptions) { auto dopts = d_solver.getDriverOptions(); ASSERT_EQ(dopts.err().rdbuf(), std::cerr.rdbuf()); ASSERT_EQ(dopts.in().rdbuf(), std::cin.rdbuf()); ASSERT_EQ(dopts.out().rdbuf(), std::cout.rdbuf()); } TEST_F(TestApiBlackSolver, getStatistics) { ASSERT_NO_THROW(cvc5::Stat()); // do some array reasoning to make sure we have a double statistics { Sort s1 = d_solver.getIntegerSort(); Sort s2 = d_solver.mkArraySort(s1, s1); Term t1 = d_solver.mkConst(s1, "i"); Term t2 = d_solver.mkVar(s2, "a"); Term t3 = d_solver.mkTerm(Kind::SELECT, {t2, t1}); d_solver.checkSat(); } cvc5::Statistics stats = d_solver.getStatistics(); { std::stringstream ss; ss << stats; } { auto s = stats.get("global::totalTime"); ASSERT_FALSE(s.isInternal()); ASSERT_FALSE(s.isDefault()); ASSERT_TRUE(s.isString()); std::string time = s.getString(); ASSERT_TRUE(time.rfind("ms") == time.size() - 2); // ends with "ms" ASSERT_FALSE(s.isDouble()); s = stats.get("resource::resourceUnitsUsed"); ASSERT_TRUE(s.isInternal()); ASSERT_FALSE(s.isDefault()); ASSERT_TRUE(s.isInt()); ASSERT_TRUE(s.getInt() >= 0); } for (const auto& s: stats) { ASSERT_FALSE(s.first.empty()); } for (auto it = stats.begin(true, true); it != stats.end(); ++it) { { auto tmp1 = it, tmp2 = it; ++tmp1; tmp2++; ASSERT_EQ(tmp1, tmp2); --tmp1; tmp2--; ASSERT_EQ(tmp1, tmp2); ASSERT_EQ(tmp1, it); ASSERT_EQ(it, tmp2); } const auto& s = *it; // check some basic utility methods ASSERT_TRUE(!(it == stats.end())); ASSERT_EQ(s.first, it->first); if (s.first == "cvc5::CONSTANT") { ASSERT_FALSE(s.second.isInternal()); ASSERT_FALSE(s.second.isDefault()); ASSERT_TRUE(s.second.isHistogram()); auto hist = s.second.getHistogram(); ASSERT_FALSE(hist.empty()); std::stringstream ss; ss << s.second; ASSERT_EQ(ss.str(), "{ integer type: 1 }"); } else if (s.first == "theory::arrays::avgIndexListLength") { ASSERT_TRUE(s.second.isInternal()); ASSERT_TRUE(s.second.isDouble()); ASSERT_TRUE(std::isnan(s.second.getDouble())); } } } TEST_F(TestApiBlackSolver, printStatisticsSafe) { testing::internal::CaptureStdout(); d_solver.printStatisticsSafe(STDOUT_FILENO); testing::internal::GetCapturedStdout(); } TEST_F(TestApiBlackSolver, getUnsatAssumptions1) { d_solver.setOption("incremental", "false"); d_solver.checkSatAssuming(d_solver.mkFalse()); ASSERT_THROW(d_solver.getUnsatAssumptions(), CVC5ApiException); } TEST_F(TestApiBlackSolver, getUnsatAssumptions2) { d_solver.setOption("incremental", "true"); d_solver.setOption("produce-unsat-assumptions", "false"); d_solver.checkSatAssuming(d_solver.mkFalse()); ASSERT_THROW(d_solver.getUnsatAssumptions(), CVC5ApiException); } TEST_F(TestApiBlackSolver, getUnsatAssumptions3) { d_solver.setOption("incremental", "true"); d_solver.setOption("produce-unsat-assumptions", "true"); d_solver.checkSatAssuming(d_solver.mkFalse()); ASSERT_NO_THROW(d_solver.getUnsatAssumptions()); d_solver.checkSatAssuming(d_solver.mkTrue()); ASSERT_THROW(d_solver.getUnsatAssumptions(), CVC5ApiException); } TEST_F(TestApiBlackSolver, getUnsatCore1) { d_solver.setOption("incremental", "false"); d_solver.assertFormula(d_solver.mkFalse()); d_solver.checkSat(); ASSERT_THROW(d_solver.getUnsatCore(), CVC5ApiException); } TEST_F(TestApiBlackSolver, getUnsatCore2) { d_solver.setOption("incremental", "false"); d_solver.setOption("produce-unsat-cores", "false"); d_solver.assertFormula(d_solver.mkFalse()); d_solver.checkSat(); ASSERT_THROW(d_solver.getUnsatCore(), CVC5ApiException); } TEST_F(TestApiBlackSolver, getUnsatCoreAndProof) { d_solver.setOption("incremental", "true"); d_solver.setOption("produce-unsat-cores", "true"); d_solver.setOption("produce-proofs", "true"); Sort uSort = d_solver.mkUninterpretedSort("u"); Sort intSort = d_solver.getIntegerSort(); Sort boolSort = d_solver.getBooleanSort(); Sort uToIntSort = d_solver.mkFunctionSort({uSort}, intSort); Sort intPredSort = d_solver.mkFunctionSort({intSort}, boolSort); std::vector uc; Term x = d_solver.mkConst(uSort, "x"); Term y = d_solver.mkConst(uSort, "y"); Term f = d_solver.mkConst(uToIntSort, "f"); Term p = d_solver.mkConst(intPredSort, "p"); Term zero = d_solver.mkInteger(0); Term one = d_solver.mkInteger(1); Term f_x = d_solver.mkTerm(APPLY_UF, {f, x}); Term f_y = d_solver.mkTerm(APPLY_UF, {f, y}); Term sum = d_solver.mkTerm(ADD, {f_x, f_y}); Term p_0 = d_solver.mkTerm(APPLY_UF, {p, zero}); Term p_f_y = d_solver.mkTerm(APPLY_UF, {p, f_y}); d_solver.assertFormula(d_solver.mkTerm(GT, {zero, f_x})); d_solver.assertFormula(d_solver.mkTerm(GT, {zero, f_y})); d_solver.assertFormula(d_solver.mkTerm(GT, {sum, one})); d_solver.assertFormula(p_0); d_solver.assertFormula(p_f_y.notTerm()); ASSERT_TRUE(d_solver.checkSat().isUnsat()); ASSERT_NO_THROW(uc = d_solver.getUnsatCore()); ASSERT_FALSE(uc.empty()); ASSERT_NO_THROW(d_solver.getProof()); ASSERT_NO_THROW(d_solver.getProof(modes::PROOF_COMPONENT_SAT)); d_solver.resetAssertions(); for (const auto& t : uc) { d_solver.assertFormula(t); } cvc5::Result res = d_solver.checkSat(); ASSERT_TRUE(res.isUnsat()); ASSERT_NO_THROW(d_solver.getProof()); } TEST_F(TestApiBlackSolver, getDifficulty) { d_solver.setOption("produce-difficulty", "true"); // cannot ask before a check sat ASSERT_THROW(d_solver.getDifficulty(), CVC5ApiException); d_solver.checkSat(); ASSERT_NO_THROW(d_solver.getDifficulty()); } TEST_F(TestApiBlackSolver, getDifficulty2) { d_solver.checkSat(); // option is not set ASSERT_THROW(d_solver.getDifficulty(), CVC5ApiException); } TEST_F(TestApiBlackSolver, getDifficulty3) { d_solver.setOption("produce-difficulty", "true"); Sort intSort = d_solver.getIntegerSort(); Term x = d_solver.mkConst(intSort, "x"); Term zero = d_solver.mkInteger(0); Term ten = d_solver.mkInteger(10); Term f0 = d_solver.mkTerm(GEQ, {x, ten}); Term f1 = d_solver.mkTerm(GEQ, {zero, x}); d_solver.assertFormula(f0); d_solver.assertFormula(f1); d_solver.checkSat(); std::map dmap; ASSERT_NO_THROW(dmap = d_solver.getDifficulty()); // difficulty should map assertions to integer values for (const std::pair& t : dmap) { ASSERT_TRUE(t.first == f0 || t.first == f1); ASSERT_TRUE(t.second.getKind() == CONST_INTEGER); } } TEST_F(TestApiBlackSolver, getLearnedLiterals) { d_solver.setOption("produce-learned-literals", "true"); // cannot ask before a check sat ASSERT_THROW(d_solver.getLearnedLiterals(), CVC5ApiException); d_solver.checkSat(); ASSERT_NO_THROW(d_solver.getLearnedLiterals()); ASSERT_NO_THROW(d_solver.getLearnedLiterals(modes::LEARNED_LIT_PREPROCESS)); } TEST_F(TestApiBlackSolver, getLearnedLiterals2) { d_solver.setOption("produce-learned-literals", "true"); Sort intSort = d_solver.getIntegerSort(); Term x = d_solver.mkConst(intSort, "x"); Term y = d_solver.mkConst(intSort, "y"); Term zero = d_solver.mkInteger(0); Term ten = d_solver.mkInteger(10); Term f0 = d_solver.mkTerm(GEQ, {x, ten}); Term f1 = d_solver.mkTerm( OR, {d_solver.mkTerm(GEQ, {zero, x}), d_solver.mkTerm(GEQ, {y, zero})}); d_solver.assertFormula(f0); d_solver.assertFormula(f1); d_solver.checkSat(); ASSERT_NO_THROW(d_solver.getLearnedLiterals()); } TEST_F(TestApiBlackSolver, getValue1) { d_solver.setOption("produce-models", "false"); Term t = d_solver.mkTrue(); d_solver.assertFormula(t); d_solver.checkSat(); ASSERT_THROW(d_solver.getValue(t), CVC5ApiException); } TEST_F(TestApiBlackSolver, getValue2) { d_solver.setOption("produce-models", "true"); Term t = d_solver.mkFalse(); d_solver.assertFormula(t); d_solver.checkSat(); ASSERT_THROW(d_solver.getValue(t), CVC5ApiException); } TEST_F(TestApiBlackSolver, getValue3) { d_solver.setOption("produce-models", "true"); Sort uSort = d_solver.mkUninterpretedSort("u"); Sort intSort = d_solver.getIntegerSort(); Sort boolSort = d_solver.getBooleanSort(); Sort uToIntSort = d_solver.mkFunctionSort({uSort}, intSort); Sort intPredSort = d_solver.mkFunctionSort({intSort}, boolSort); std::vector unsat_core; Term x = d_solver.mkConst(uSort, "x"); Term y = d_solver.mkConst(uSort, "y"); Term z = d_solver.mkConst(uSort, "z"); Term f = d_solver.mkConst(uToIntSort, "f"); Term p = d_solver.mkConst(intPredSort, "p"); Term zero = d_solver.mkInteger(0); Term one = d_solver.mkInteger(1); Term f_x = d_solver.mkTerm(APPLY_UF, {f, x}); Term f_y = d_solver.mkTerm(APPLY_UF, {f, y}); Term sum = d_solver.mkTerm(ADD, {f_x, f_y}); Term p_0 = d_solver.mkTerm(APPLY_UF, {p, zero}); Term p_f_y = d_solver.mkTerm(APPLY_UF, {p, f_y}); d_solver.assertFormula(d_solver.mkTerm(LEQ, {zero, f_x})); d_solver.assertFormula(d_solver.mkTerm(LEQ, {zero, f_y})); d_solver.assertFormula(d_solver.mkTerm(LEQ, {sum, one})); d_solver.assertFormula(p_0.notTerm()); d_solver.assertFormula(p_f_y); ASSERT_TRUE(d_solver.checkSat().isSat()); ASSERT_NO_THROW(d_solver.getValue(x)); ASSERT_NO_THROW(d_solver.getValue(y)); ASSERT_NO_THROW(d_solver.getValue(z)); ASSERT_NO_THROW(d_solver.getValue(sum)); ASSERT_NO_THROW(d_solver.getValue(p_f_y)); std::vector a; ASSERT_NO_THROW(a.emplace_back(d_solver.getValue(x))); ASSERT_NO_THROW(a.emplace_back(d_solver.getValue(y))); ASSERT_NO_THROW(a.emplace_back(d_solver.getValue(z))); std::vector b; ASSERT_NO_THROW(b = d_solver.getValue({x,y,z})); ASSERT_EQ(a,b); Solver slv; ASSERT_THROW(slv.getValue(x), CVC5ApiException); } TEST_F(TestApiBlackSolver, getModelDomainElements) { d_solver.setOption("produce-models", "true"); Sort uSort = d_solver.mkUninterpretedSort("u"); Sort intSort = d_solver.getIntegerSort(); Term x = d_solver.mkConst(uSort, "x"); Term y = d_solver.mkConst(uSort, "y"); Term z = d_solver.mkConst(uSort, "z"); Term f = d_solver.mkTerm(DISTINCT, {x, y, z}); d_solver.assertFormula(f); d_solver.checkSat(); ASSERT_NO_THROW(d_solver.getModelDomainElements(uSort)); ASSERT_TRUE(d_solver.getModelDomainElements(uSort).size() >= 3); ASSERT_THROW(d_solver.getModelDomainElements(intSort), CVC5ApiException); } TEST_F(TestApiBlackSolver, getModelDomainElements2) { d_solver.setOption("produce-models", "true"); d_solver.setOption("finite-model-find", "true"); Sort uSort = d_solver.mkUninterpretedSort("u"); Term x = d_solver.mkVar(uSort, "x"); Term y = d_solver.mkVar(uSort, "y"); Term eq = d_solver.mkTerm(EQUAL, {x, y}); Term bvl = d_solver.mkTerm(VARIABLE_LIST, {x, y}); Term f = d_solver.mkTerm(FORALL, {bvl, eq}); d_solver.assertFormula(f); d_solver.checkSat(); ASSERT_NO_THROW(d_solver.getModelDomainElements(uSort)); // a model for the above must interpret u as size 1 ASSERT_TRUE(d_solver.getModelDomainElements(uSort).size() == 1); } TEST_F(TestApiBlackSolver, isModelCoreSymbol) { d_solver.setOption("produce-models", "true"); d_solver.setOption("model-cores", "simple"); Sort uSort = d_solver.mkUninterpretedSort("u"); Term x = d_solver.mkConst(uSort, "x"); Term y = d_solver.mkConst(uSort, "y"); Term z = d_solver.mkConst(uSort, "z"); Term zero = d_solver.mkInteger(0); Term f = d_solver.mkTerm(NOT, {d_solver.mkTerm(EQUAL, {x, y})}); d_solver.assertFormula(f); d_solver.checkSat(); ASSERT_TRUE(d_solver.isModelCoreSymbol(x)); ASSERT_TRUE(d_solver.isModelCoreSymbol(y)); ASSERT_FALSE(d_solver.isModelCoreSymbol(z)); ASSERT_THROW(d_solver.isModelCoreSymbol(zero), CVC5ApiException); } TEST_F(TestApiBlackSolver, getModel) { d_solver.setOption("produce-models", "true"); Sort uSort = d_solver.mkUninterpretedSort("u"); Term x = d_solver.mkConst(uSort, "x"); Term y = d_solver.mkConst(uSort, "y"); Term z = d_solver.mkConst(uSort, "z"); Term f = d_solver.mkTerm(NOT, {d_solver.mkTerm(EQUAL, {x, y})}); d_solver.assertFormula(f); d_solver.checkSat(); std::vector sorts; sorts.push_back(uSort); std::vector terms; terms.push_back(x); terms.push_back(y); ASSERT_NO_THROW(d_solver.getModel(sorts, terms)); Term null; terms.push_back(null); ASSERT_THROW(d_solver.getModel(sorts, terms), CVC5ApiException); } TEST_F(TestApiBlackSolver, getModel2) { d_solver.setOption("produce-models", "true"); std::vector sorts; std::vector terms; ASSERT_THROW(d_solver.getModel(sorts, terms), CVC5ApiException); } TEST_F(TestApiBlackSolver, getModel3) { d_solver.setOption("produce-models", "true"); std::vector sorts; std::vector terms; d_solver.checkSat(); ASSERT_NO_THROW(d_solver.getModel(sorts, terms)); Sort integer = d_solver.getIntegerSort(); sorts.push_back(integer); ASSERT_THROW(d_solver.getModel(sorts, terms), CVC5ApiException); } TEST_F(TestApiBlackSolver, getQuantifierElimination) { Term x = d_solver.mkVar(d_solver.getBooleanSort(), "x"); Term forall = d_solver.mkTerm(FORALL, {d_solver.mkTerm(VARIABLE_LIST, {x}), d_solver.mkTerm(OR, {x, d_solver.mkTerm(NOT, {x})})}); ASSERT_THROW(d_solver.getQuantifierElimination(Term()), CVC5ApiException); ASSERT_THROW(d_solver.getQuantifierElimination(Solver().mkBoolean(false)), CVC5ApiException); ASSERT_NO_THROW(d_solver.getQuantifierElimination(forall)); } TEST_F(TestApiBlackSolver, getQuantifierEliminationDisjunct) { Term x = d_solver.mkVar(d_solver.getBooleanSort(), "x"); Term forall = d_solver.mkTerm(FORALL, {d_solver.mkTerm(VARIABLE_LIST, {x}), d_solver.mkTerm(OR, {x, d_solver.mkTerm(NOT, {x})})}); ASSERT_THROW(d_solver.getQuantifierEliminationDisjunct(Term()), CVC5ApiException); ASSERT_THROW( d_solver.getQuantifierEliminationDisjunct(Solver().mkBoolean(false)), CVC5ApiException); ASSERT_NO_THROW(d_solver.getQuantifierEliminationDisjunct(forall)); } TEST_F(TestApiBlackSolver, declareSepHeap) { d_solver.setLogic("ALL"); d_solver.setOption("incremental", "false"); Sort integer = d_solver.getIntegerSort(); ASSERT_NO_THROW(d_solver.declareSepHeap(integer, integer)); // cannot declare separation logic heap more than once ASSERT_THROW(d_solver.declareSepHeap(integer, integer), CVC5ApiException); } namespace { /** * Helper function for testGetSeparation{Heap,Nil}TermX. Asserts and checks * some simple separation logic constraints. */ void checkSimpleSeparationConstraints(Solver* solver) { Sort integer = solver->getIntegerSort(); // declare the separation heap solver->declareSepHeap(integer, integer); Term x = solver->mkConst(integer, "x"); Term p = solver->mkConst(integer, "p"); Term heap = solver->mkTerm(cvc5::Kind::SEP_PTO, {p, x}); solver->assertFormula(heap); Term nil = solver->mkSepNil(integer); solver->assertFormula(nil.eqTerm(solver->mkInteger(5))); solver->checkSat(); } } // namespace TEST_F(TestApiBlackSolver, getValueSepHeap1) { d_solver.setLogic("QF_BV"); d_solver.setOption("incremental", "false"); d_solver.setOption("produce-models", "true"); Term t = d_solver.mkTrue(); d_solver.assertFormula(t); ASSERT_THROW(d_solver.getValueSepHeap(), CVC5ApiException); } TEST_F(TestApiBlackSolver, getValueSepHeap2) { d_solver.setLogic("ALL"); d_solver.setOption("incremental", "false"); d_solver.setOption("produce-models", "false"); checkSimpleSeparationConstraints(&d_solver); ASSERT_THROW(d_solver.getValueSepHeap(), CVC5ApiException); } TEST_F(TestApiBlackSolver, getValueSepHeap3) { d_solver.setLogic("ALL"); d_solver.setOption("incremental", "false"); d_solver.setOption("produce-models", "true"); Term t = d_solver.mkFalse(); d_solver.assertFormula(t); d_solver.checkSat(); ASSERT_THROW(d_solver.getValueSepHeap(), CVC5ApiException); } TEST_F(TestApiBlackSolver, getValueSepHeap4) { d_solver.setLogic("ALL"); d_solver.setOption("incremental", "false"); d_solver.setOption("produce-models", "true"); Term t = d_solver.mkTrue(); d_solver.assertFormula(t); d_solver.checkSat(); ASSERT_THROW(d_solver.getValueSepHeap(), CVC5ApiException); } TEST_F(TestApiBlackSolver, getValueSepHeap5) { d_solver.setLogic("ALL"); d_solver.setOption("incremental", "false"); d_solver.setOption("produce-models", "true"); checkSimpleSeparationConstraints(&d_solver); ASSERT_NO_THROW(d_solver.getValueSepHeap()); } TEST_F(TestApiBlackSolver, getValueSepNil1) { d_solver.setLogic("QF_BV"); d_solver.setOption("incremental", "false"); d_solver.setOption("produce-models", "true"); Term t = d_solver.mkTrue(); d_solver.assertFormula(t); ASSERT_THROW(d_solver.getValueSepNil(), CVC5ApiException); } TEST_F(TestApiBlackSolver, getValueSepNil2) { d_solver.setLogic("ALL"); d_solver.setOption("incremental", "false"); d_solver.setOption("produce-models", "false"); checkSimpleSeparationConstraints(&d_solver); ASSERT_THROW(d_solver.getValueSepNil(), CVC5ApiException); } TEST_F(TestApiBlackSolver, getValueSepNil3) { d_solver.setLogic("ALL"); d_solver.setOption("incremental", "false"); d_solver.setOption("produce-models", "true"); Term t = d_solver.mkFalse(); d_solver.assertFormula(t); d_solver.checkSat(); ASSERT_THROW(d_solver.getValueSepNil(), CVC5ApiException); } TEST_F(TestApiBlackSolver, getValueSepNil4) { d_solver.setLogic("ALL"); d_solver.setOption("incremental", "false"); d_solver.setOption("produce-models", "true"); Term t = d_solver.mkTrue(); d_solver.assertFormula(t); d_solver.checkSat(); ASSERT_THROW(d_solver.getValueSepNil(), CVC5ApiException); } TEST_F(TestApiBlackSolver, getValueSepNil5) { d_solver.setLogic("ALL"); d_solver.setOption("incremental", "false"); d_solver.setOption("produce-models", "true"); checkSimpleSeparationConstraints(&d_solver); ASSERT_NO_THROW(d_solver.getValueSepNil()); } TEST_F(TestApiBlackSolver, push1) { d_solver.setOption("incremental", "true"); ASSERT_NO_THROW(d_solver.push(1)); ASSERT_THROW(d_solver.setOption("incremental", "false"), CVC5ApiException); ASSERT_THROW(d_solver.setOption("incremental", "true"), CVC5ApiException); } TEST_F(TestApiBlackSolver, push2) { d_solver.setOption("incremental", "false"); ASSERT_THROW(d_solver.push(1), CVC5ApiException); } TEST_F(TestApiBlackSolver, pop1) { d_solver.setOption("incremental", "false"); ASSERT_THROW(d_solver.pop(1), CVC5ApiException); } TEST_F(TestApiBlackSolver, pop2) { d_solver.setOption("incremental", "true"); ASSERT_THROW(d_solver.pop(1), CVC5ApiException); } TEST_F(TestApiBlackSolver, pop3) { d_solver.setOption("incremental", "true"); ASSERT_NO_THROW(d_solver.push(1)); ASSERT_NO_THROW(d_solver.pop(1)); ASSERT_THROW(d_solver.pop(1), CVC5ApiException); } TEST_F(TestApiBlackSolver, blockModel1) { Term x = d_solver.mkConst(d_solver.getBooleanSort(), "x"); d_solver.assertFormula(x.eqTerm(x)); d_solver.checkSat(); ASSERT_THROW(d_solver.blockModel(modes::BlockModelsMode::LITERALS), CVC5ApiException); } TEST_F(TestApiBlackSolver, blockModel2) { d_solver.setOption("produce-models", "true"); Term x = d_solver.mkConst(d_solver.getBooleanSort(), "x"); d_solver.assertFormula(x.eqTerm(x)); ASSERT_THROW(d_solver.blockModel(modes::BlockModelsMode::LITERALS), CVC5ApiException); } TEST_F(TestApiBlackSolver, blockModel3) { d_solver.setOption("produce-models", "true"); Term x = d_solver.mkConst(d_solver.getBooleanSort(), "x"); d_solver.assertFormula(x.eqTerm(x)); d_solver.checkSat(); ASSERT_NO_THROW(d_solver.blockModel(modes::BlockModelsMode::LITERALS)); } TEST_F(TestApiBlackSolver, blockModelValues1) { d_solver.setOption("produce-models", "true"); Term x = d_solver.mkConst(d_solver.getBooleanSort(), "x"); d_solver.assertFormula(x.eqTerm(x)); d_solver.checkSat(); ASSERT_THROW(d_solver.blockModelValues({}), CVC5ApiException); ASSERT_THROW(d_solver.blockModelValues({Term()}), CVC5ApiException); ASSERT_NO_THROW(d_solver.blockModelValues({Solver().mkBoolean(false)})); } TEST_F(TestApiBlackSolver, blockModelValues2) { d_solver.setOption("produce-models", "true"); Term x = d_solver.mkConst(d_solver.getBooleanSort(), "x"); d_solver.assertFormula(x.eqTerm(x)); d_solver.checkSat(); ASSERT_NO_THROW(d_solver.blockModelValues({x})); } TEST_F(TestApiBlackSolver, blockModelValues3) { Term x = d_solver.mkConst(d_solver.getBooleanSort(), "x"); d_solver.assertFormula(x.eqTerm(x)); d_solver.checkSat(); ASSERT_THROW(d_solver.blockModelValues({x}), CVC5ApiException); } TEST_F(TestApiBlackSolver, blockModelValues4) { d_solver.setOption("produce-models", "true"); Term x = d_solver.mkConst(d_solver.getBooleanSort(), "x"); d_solver.assertFormula(x.eqTerm(x)); ASSERT_THROW(d_solver.blockModelValues({x}), CVC5ApiException); } TEST_F(TestApiBlackSolver, blockModelValues5) { d_solver.setOption("produce-models", "true"); Term x = d_solver.mkConst(d_solver.getBooleanSort(), "x"); d_solver.assertFormula(x.eqTerm(x)); d_solver.checkSat(); ASSERT_NO_THROW(d_solver.blockModelValues({x})); } TEST_F(TestApiBlackSolver, getInstantiations) { Sort iSort = d_solver.getIntegerSort(); Sort boolSort = d_solver.getBooleanSort(); Term p = d_solver.declareFun("p", {iSort}, boolSort); Term x = d_solver.mkVar(iSort, "x"); Term bvl = d_solver.mkTerm(VARIABLE_LIST, {x}); Term app = d_solver.mkTerm(APPLY_UF, {p, x}); Term q = d_solver.mkTerm(FORALL, {bvl, app}); d_solver.assertFormula(q); Term five = d_solver.mkInteger(5); Term app2 = d_solver.mkTerm(NOT, {d_solver.mkTerm(APPLY_UF, {p, five})}); d_solver.assertFormula(app2); ASSERT_THROW(d_solver.getInstantiations(), CVC5ApiException); d_solver.checkSat(); ASSERT_NO_THROW(d_solver.getInstantiations()); } TEST_F(TestApiBlackSolver, setInfo) { ASSERT_THROW(d_solver.setInfo("cvc5-lagic", "QF_BV"), CVC5ApiException); ASSERT_THROW(d_solver.setInfo("cvc2-logic", "QF_BV"), CVC5ApiException); ASSERT_THROW(d_solver.setInfo("cvc5-logic", "asdf"), CVC5ApiException); ASSERT_NO_THROW(d_solver.setInfo("source", "asdf")); ASSERT_NO_THROW(d_solver.setInfo("category", "asdf")); ASSERT_NO_THROW(d_solver.setInfo("difficulty", "asdf")); ASSERT_NO_THROW(d_solver.setInfo("filename", "asdf")); ASSERT_NO_THROW(d_solver.setInfo("license", "asdf")); ASSERT_NO_THROW(d_solver.setInfo("name", "asdf")); ASSERT_NO_THROW(d_solver.setInfo("notes", "asdf")); ASSERT_NO_THROW(d_solver.setInfo("smt-lib-version", "2")); ASSERT_NO_THROW(d_solver.setInfo("smt-lib-version", "2.0")); ASSERT_NO_THROW(d_solver.setInfo("smt-lib-version", "2.5")); ASSERT_NO_THROW(d_solver.setInfo("smt-lib-version", "2.6")); ASSERT_THROW(d_solver.setInfo("smt-lib-version", ".0"), CVC5ApiException); ASSERT_NO_THROW(d_solver.setInfo("status", "sat")); ASSERT_NO_THROW(d_solver.setInfo("status", "unsat")); ASSERT_NO_THROW(d_solver.setInfo("status", "unknown")); ASSERT_THROW(d_solver.setInfo("status", "asdf"), CVC5ApiException); } TEST_F(TestApiBlackSolver, simplify) { ASSERT_THROW(d_solver.simplify(Term()), CVC5ApiException); Sort bvSort = d_solver.mkBitVectorSort(32); Sort uSort = d_solver.mkUninterpretedSort("u"); Sort funSort1 = d_solver.mkFunctionSort({bvSort, bvSort}, bvSort); Sort funSort2 = d_solver.mkFunctionSort({uSort}, d_solver.getIntegerSort()); DatatypeDecl consListSpec = d_solver.mkDatatypeDecl("list"); DatatypeConstructorDecl cons = d_solver.mkDatatypeConstructorDecl("cons"); cons.addSelector("head", d_solver.getIntegerSort()); cons.addSelectorSelf("tail"); consListSpec.addConstructor(cons); DatatypeConstructorDecl nil = d_solver.mkDatatypeConstructorDecl("nil"); consListSpec.addConstructor(nil); Sort consListSort = d_solver.mkDatatypeSort(consListSpec); Term x = d_solver.mkConst(bvSort, "x"); ASSERT_NO_THROW(d_solver.simplify(x)); Term a = d_solver.mkConst(bvSort, "a"); ASSERT_NO_THROW(d_solver.simplify(a)); Term b = d_solver.mkConst(bvSort, "b"); ASSERT_NO_THROW(d_solver.simplify(b)); Term x_eq_x = d_solver.mkTerm(EQUAL, {x, x}); ASSERT_NO_THROW(d_solver.simplify(x_eq_x)); ASSERT_NE(d_solver.mkTrue(), x_eq_x); ASSERT_EQ(d_solver.mkTrue(), d_solver.simplify(x_eq_x)); Term x_eq_b = d_solver.mkTerm(EQUAL, {x, b}); ASSERT_NO_THROW(d_solver.simplify(x_eq_b)); ASSERT_NE(d_solver.mkTrue(), x_eq_b); ASSERT_NE(d_solver.mkTrue(), d_solver.simplify(x_eq_b)); Solver slv; ASSERT_NO_THROW(slv.simplify(x)); Term i1 = d_solver.mkConst(d_solver.getIntegerSort(), "i1"); ASSERT_NO_THROW(d_solver.simplify(i1)); Term i2 = d_solver.mkTerm(MULT, {i1, d_solver.mkInteger("23")}); ASSERT_NO_THROW(d_solver.simplify(i2)); ASSERT_NE(i1, i2); ASSERT_NE(i1, d_solver.simplify(i2)); Term i3 = d_solver.mkTerm(ADD, {i1, d_solver.mkInteger(0)}); ASSERT_NO_THROW(d_solver.simplify(i3)); ASSERT_NE(i1, i3); ASSERT_EQ(i1, d_solver.simplify(i3)); Datatype consList = consListSort.getDatatype(); Term dt1 = d_solver.mkTerm( APPLY_CONSTRUCTOR, {consList.getConstructor("cons").getTerm(), d_solver.mkInteger(0), d_solver.mkTerm(APPLY_CONSTRUCTOR, {consList.getConstructor("nil").getTerm()})}); ASSERT_NO_THROW(d_solver.simplify(dt1)); Term dt2 = d_solver.mkTerm( APPLY_SELECTOR, {consList["cons"].getSelector("head").getTerm(), dt1}); ASSERT_NO_THROW(d_solver.simplify(dt2)); Term b1 = d_solver.mkVar(bvSort, "b1"); ASSERT_NO_THROW(d_solver.simplify(b1)); Term b2 = d_solver.mkVar(bvSort, "b1"); ASSERT_NO_THROW(d_solver.simplify(b2)); Term b3 = d_solver.mkVar(uSort, "b3"); ASSERT_NO_THROW(d_solver.simplify(b3)); Term v1 = d_solver.mkConst(bvSort, "v1"); ASSERT_NO_THROW(d_solver.simplify(v1)); Term v2 = d_solver.mkConst(d_solver.getIntegerSort(), "v2"); ASSERT_NO_THROW(d_solver.simplify(v2)); Term f1 = d_solver.mkConst(funSort1, "f1"); ASSERT_NO_THROW(d_solver.simplify(f1)); Term f2 = d_solver.mkConst(funSort2, "f2"); ASSERT_NO_THROW(d_solver.simplify(f2)); d_solver.defineFunsRec({f1, f2}, {{b1, b2}, {b3}}, {v1, v2}); ASSERT_NO_THROW(d_solver.simplify(f1)); ASSERT_NO_THROW(d_solver.simplify(f2)); } TEST_F(TestApiBlackSolver, assertFormula) { ASSERT_NO_THROW(d_solver.assertFormula(d_solver.mkTrue())); ASSERT_THROW(d_solver.assertFormula(Term()), CVC5ApiException); Solver slv; ASSERT_NO_THROW(slv.assertFormula(d_solver.mkTrue())); } TEST_F(TestApiBlackSolver, checkSat) { d_solver.setOption("incremental", "false"); ASSERT_NO_THROW(d_solver.checkSat()); ASSERT_THROW(d_solver.checkSat(), CVC5ApiException); } TEST_F(TestApiBlackSolver, checkSatAssuming) { d_solver.setOption("incremental", "false"); ASSERT_NO_THROW(d_solver.checkSatAssuming(d_solver.mkTrue())); ASSERT_THROW(d_solver.checkSatAssuming(d_solver.mkTrue()), CVC5ApiException); Solver slv; ASSERT_NO_THROW(slv.checkSatAssuming(d_solver.mkTrue())); } TEST_F(TestApiBlackSolver, checkSatAssuming1) { Sort boolSort = d_solver.getBooleanSort(); Term x = d_solver.mkConst(boolSort, "x"); Term y = d_solver.mkConst(boolSort, "y"); Term z = d_solver.mkTerm(AND, {x, y}); d_solver.setOption("incremental", "true"); ASSERT_NO_THROW(d_solver.checkSatAssuming(d_solver.mkTrue())); ASSERT_THROW(d_solver.checkSatAssuming(Term()), CVC5ApiException); ASSERT_NO_THROW(d_solver.checkSatAssuming(d_solver.mkTrue())); ASSERT_NO_THROW(d_solver.checkSatAssuming(z)); Solver slv; ASSERT_NO_THROW(slv.checkSatAssuming(d_solver.mkTrue())); } TEST_F(TestApiBlackSolver, checkSatAssuming2) { d_solver.setOption("incremental", "true"); Sort uSort = d_solver.mkUninterpretedSort("u"); Sort intSort = d_solver.getIntegerSort(); Sort boolSort = d_solver.getBooleanSort(); Sort uToIntSort = d_solver.mkFunctionSort({uSort}, intSort); Sort intPredSort = d_solver.mkFunctionSort({intSort}, boolSort); Term n = Term(); // Constants Term x = d_solver.mkConst(uSort, "x"); Term y = d_solver.mkConst(uSort, "y"); // Functions Term f = d_solver.mkConst(uToIntSort, "f"); Term p = d_solver.mkConst(intPredSort, "p"); // Values Term zero = d_solver.mkInteger(0); Term one = d_solver.mkInteger(1); // Terms Term f_x = d_solver.mkTerm(APPLY_UF, {f, x}); Term f_y = d_solver.mkTerm(APPLY_UF, {f, y}); Term sum = d_solver.mkTerm(ADD, {f_x, f_y}); Term p_0 = d_solver.mkTerm(APPLY_UF, {p, zero}); Term p_f_y = d_solver.mkTerm(APPLY_UF, {p, f_y}); // Assertions Term assertions = d_solver.mkTerm(AND, { d_solver.mkTerm(LEQ, {zero, f_x}), // 0 <= f(x) d_solver.mkTerm(LEQ, {zero, f_y}), // 0 <= f(y) d_solver.mkTerm(LEQ, {sum, one}), // f(x) + f(y) <= 1 p_0.notTerm(), // not p(0) p_f_y // p(f(y)) }); ASSERT_NO_THROW(d_solver.checkSatAssuming(d_solver.mkTrue())); d_solver.assertFormula(assertions); ASSERT_NO_THROW(d_solver.checkSatAssuming(d_solver.mkTerm(DISTINCT, {x, y}))); ASSERT_NO_THROW(d_solver.checkSatAssuming( {d_solver.mkFalse(), d_solver.mkTerm(DISTINCT, {x, y})})); ASSERT_THROW(d_solver.checkSatAssuming(n), CVC5ApiException); ASSERT_THROW( d_solver.checkSatAssuming({n, d_solver.mkTerm(DISTINCT, {x, y})}), CVC5ApiException); Solver slv; ASSERT_NO_THROW(slv.checkSatAssuming(d_solver.mkTrue())); } TEST_F(TestApiBlackSolver, setLogic) { ASSERT_NO_THROW(d_solver.setLogic("AUFLIRA")); ASSERT_THROW(d_solver.setLogic("AF_BV"), CVC5ApiException); d_solver.assertFormula(d_solver.mkTrue()); ASSERT_THROW(d_solver.setLogic("AUFLIRA"), CVC5ApiException); } TEST_F(TestApiBlackSolver, setOption) { ASSERT_NO_THROW(d_solver.setOption("bv-sat-solver", "minisat")); ASSERT_THROW(d_solver.setOption("bv-sat-solver", "1"), CVC5ApiException); d_solver.assertFormula(d_solver.mkTrue()); ASSERT_THROW(d_solver.setOption("bv-sat-solver", "minisat"), CVC5ApiException); } TEST_F(TestApiBlackSolver, resetAssertions) { d_solver.setOption("incremental", "true"); Sort bvSort = d_solver.mkBitVectorSort(4); Term one = d_solver.mkBitVector(4, 1); Term x = d_solver.mkConst(bvSort, "x"); Term ule = d_solver.mkTerm(BITVECTOR_ULE, {x, one}); Term srem = d_solver.mkTerm(BITVECTOR_SREM, {one, x}); d_solver.push(4); Term slt = d_solver.mkTerm(BITVECTOR_SLT, {srem, one}); d_solver.resetAssertions(); d_solver.checkSatAssuming({slt, ule}); } TEST_F(TestApiBlackSolver, declareSygusVar) { d_solver.setOption("sygus", "true"); Sort boolSort = d_solver.getBooleanSort(); Sort intSort = d_solver.getIntegerSort(); Sort funSort = d_solver.mkFunctionSort({intSort}, boolSort); ASSERT_NO_THROW(d_solver.declareSygusVar("", boolSort)); ASSERT_NO_THROW(d_solver.declareSygusVar("", funSort)); ASSERT_NO_THROW(d_solver.declareSygusVar(std::string("b"), boolSort)); ASSERT_THROW(d_solver.declareSygusVar("", Sort()), CVC5ApiException); ASSERT_THROW(d_solver.declareSygusVar("a", Sort()), CVC5ApiException); Solver slv; ASSERT_THROW(slv.declareSygusVar("", boolSort), CVC5ApiException); } TEST_F(TestApiBlackSolver, mkGrammar) { Term nullTerm; Term boolTerm = d_solver.mkBoolean(true); Term boolVar = d_solver.mkVar(d_solver.getBooleanSort()); Term intVar = d_solver.mkVar(d_solver.getIntegerSort()); ASSERT_NO_THROW(d_solver.mkGrammar({}, {intVar})); ASSERT_NO_THROW(d_solver.mkGrammar({boolVar}, {intVar})); ASSERT_THROW(d_solver.mkGrammar({}, {}), CVC5ApiException); ASSERT_THROW(d_solver.mkGrammar({}, {nullTerm}), CVC5ApiException); ASSERT_THROW(d_solver.mkGrammar({}, {boolTerm}), CVC5ApiException); ASSERT_THROW(d_solver.mkGrammar({boolTerm}, {intVar}), CVC5ApiException); Solver slv; Term boolVar2 = slv.mkVar(slv.getBooleanSort()); Term intVar2 = slv.mkVar(slv.getIntegerSort()); ASSERT_NO_THROW(slv.mkGrammar({boolVar2}, {intVar2})); ASSERT_NO_THROW(slv.mkGrammar({boolVar}, {intVar2})); ASSERT_NO_THROW(slv.mkGrammar({boolVar2}, {intVar})); } TEST_F(TestApiBlackSolver, synthFun) { d_solver.setOption("sygus", "true"); Sort null; Sort boolean = d_solver.getBooleanSort(); Sort integer = d_solver.getIntegerSort(); Term nullTerm; Term x = d_solver.mkVar(boolean); Term start1 = d_solver.mkVar(boolean); Term start2 = d_solver.mkVar(integer); Grammar g1 = d_solver.mkGrammar({x}, {start1}); g1.addRule(start1, d_solver.mkBoolean(false)); Grammar g2 = d_solver.mkGrammar({x}, {start2}); g2.addRule(start2, d_solver.mkInteger(0)); ASSERT_NO_THROW(d_solver.synthFun("", {}, boolean)); ASSERT_NO_THROW(d_solver.synthFun("f1", {x}, boolean)); ASSERT_NO_THROW(d_solver.synthFun("f2", {x}, boolean, g1)); ASSERT_THROW(d_solver.synthFun("f3", {nullTerm}, boolean), CVC5ApiException); ASSERT_THROW(d_solver.synthFun("f4", {}, null), CVC5ApiException); ASSERT_THROW(d_solver.synthFun("f6", {x}, boolean, g2), CVC5ApiException); Solver slv; slv.setOption("sygus", "true"); Term x2 = slv.mkVar(slv.getBooleanSort()); ASSERT_NO_THROW(slv.synthFun("f1", {x2}, slv.getBooleanSort())); ASSERT_NO_THROW(slv.synthFun("", {}, d_solver.getBooleanSort())); ASSERT_NO_THROW(slv.synthFun("f1", {x}, d_solver.getBooleanSort())); } TEST_F(TestApiBlackSolver, synthInv) { d_solver.setOption("sygus", "true"); Sort boolean = d_solver.getBooleanSort(); Sort integer = d_solver.getIntegerSort(); Term nullTerm; Term x = d_solver.mkVar(boolean); Term start1 = d_solver.mkVar(boolean); Term start2 = d_solver.mkVar(integer); Grammar g1 = d_solver.mkGrammar({x}, {start1}); g1.addRule(start1, d_solver.mkBoolean(false)); Grammar g2 = d_solver.mkGrammar({x}, {start2}); g2.addRule(start2, d_solver.mkInteger(0)); ASSERT_NO_THROW(d_solver.synthInv("", {})); ASSERT_NO_THROW(d_solver.synthInv("i1", {x})); ASSERT_NO_THROW(d_solver.synthInv("i2", {x}, g1)); ASSERT_THROW(d_solver.synthInv("i3", {nullTerm}), CVC5ApiException); ASSERT_THROW(d_solver.synthInv("i4", {x}, g2), CVC5ApiException); } TEST_F(TestApiBlackSolver, addSygusConstraint) { d_solver.setOption("sygus", "true"); Term nullTerm; Term boolTerm = d_solver.mkBoolean(true); Term intTerm = d_solver.mkInteger(1); ASSERT_NO_THROW(d_solver.addSygusConstraint(boolTerm)); ASSERT_THROW(d_solver.addSygusConstraint(nullTerm), CVC5ApiException); ASSERT_THROW(d_solver.addSygusConstraint(intTerm), CVC5ApiException); Solver slv; slv.setOption("sygus", "true"); ASSERT_NO_THROW(slv.addSygusConstraint(boolTerm)); } TEST_F(TestApiBlackSolver, getSygusConstraints) { d_solver.setOption("sygus", "true"); Term trueTerm = d_solver.mkBoolean(true); Term falseTerm = d_solver.mkBoolean(false); d_solver.addSygusConstraint(trueTerm); d_solver.addSygusConstraint(falseTerm); std::vector constraints{trueTerm, falseTerm}; ASSERT_EQ(d_solver.getSygusConstraints(), constraints); } TEST_F(TestApiBlackSolver, addSygusAssume) { d_solver.setOption("sygus", "true"); Term nullTerm; Term boolTerm = d_solver.mkBoolean(false); Term intTerm = d_solver.mkInteger(1); ASSERT_NO_THROW(d_solver.addSygusAssume(boolTerm)); ASSERT_THROW(d_solver.addSygusAssume(nullTerm), CVC5ApiException); ASSERT_THROW(d_solver.addSygusAssume(intTerm), CVC5ApiException); Solver slv; slv.setOption("sygus", "true"); ASSERT_NO_THROW(slv.addSygusAssume(boolTerm)); } TEST_F(TestApiBlackSolver, getSygusAssumptions) { d_solver.setOption("sygus", "true"); Term trueTerm = d_solver.mkBoolean(true); Term falseTerm = d_solver.mkBoolean(false); d_solver.addSygusAssume(trueTerm); d_solver.addSygusAssume(falseTerm); std::vector assumptions{trueTerm, falseTerm}; ASSERT_EQ(d_solver.getSygusAssumptions(), assumptions); } TEST_F(TestApiBlackSolver, addSygusInvConstraint) { d_solver.setOption("sygus", "true"); Sort boolean = d_solver.getBooleanSort(); Sort real = d_solver.getRealSort(); Term nullTerm; Term intTerm = d_solver.mkInteger(1); Term inv = d_solver.declareFun("inv", {real}, boolean); Term pre = d_solver.declareFun("pre", {real}, boolean); Term trans = d_solver.declareFun("trans", {real, real}, boolean); Term post = d_solver.declareFun("post", {real}, boolean); Term inv1 = d_solver.declareFun("inv1", {real}, real); Term trans1 = d_solver.declareFun("trans1", {boolean, real}, boolean); Term trans2 = d_solver.declareFun("trans2", {real, boolean}, boolean); Term trans3 = d_solver.declareFun("trans3", {real, real}, real); ASSERT_NO_THROW(d_solver.addSygusInvConstraint(inv, pre, trans, post)); ASSERT_THROW(d_solver.addSygusInvConstraint(nullTerm, pre, trans, post), CVC5ApiException); ASSERT_THROW(d_solver.addSygusInvConstraint(inv, nullTerm, trans, post), CVC5ApiException); ASSERT_THROW(d_solver.addSygusInvConstraint(inv, pre, nullTerm, post), CVC5ApiException); ASSERT_THROW(d_solver.addSygusInvConstraint(inv, pre, trans, nullTerm), CVC5ApiException); ASSERT_THROW(d_solver.addSygusInvConstraint(intTerm, pre, trans, post), CVC5ApiException); ASSERT_THROW(d_solver.addSygusInvConstraint(inv1, pre, trans, post), CVC5ApiException); ASSERT_THROW(d_solver.addSygusInvConstraint(inv, trans, trans, post), CVC5ApiException); ASSERT_THROW(d_solver.addSygusInvConstraint(inv, pre, intTerm, post), CVC5ApiException); ASSERT_THROW(d_solver.addSygusInvConstraint(inv, pre, pre, post), CVC5ApiException); ASSERT_THROW(d_solver.addSygusInvConstraint(inv, pre, trans1, post), CVC5ApiException); ASSERT_THROW(d_solver.addSygusInvConstraint(inv, pre, trans2, post), CVC5ApiException); ASSERT_THROW(d_solver.addSygusInvConstraint(inv, pre, trans3, post), CVC5ApiException); ASSERT_THROW(d_solver.addSygusInvConstraint(inv, pre, trans, trans), CVC5ApiException); Solver slv; slv.setOption("sygus", "true"); Sort boolean2 = slv.getBooleanSort(); Sort real2 = slv.getRealSort(); Term inv22 = slv.declareFun("inv", {real2}, boolean2); Term pre22 = slv.declareFun("pre", {real2}, boolean2); Term trans22 = slv.declareFun("trans", {real2, real2}, boolean2); Term post22 = slv.declareFun("post", {real2}, boolean2); ASSERT_NO_THROW(slv.addSygusInvConstraint(inv22, pre22, trans22, post22)); ASSERT_NO_THROW(slv.addSygusInvConstraint(inv, pre22, trans22, post22)); ASSERT_NO_THROW(slv.addSygusInvConstraint(inv22, pre, trans22, post22)); ASSERT_NO_THROW(slv.addSygusInvConstraint(inv22, pre22, trans, post22)); ASSERT_NO_THROW(slv.addSygusInvConstraint(inv22, pre22, trans22, post)); } TEST_F(TestApiBlackSolver, checkSynth) { // requires option to be set ASSERT_THROW(d_solver.checkSynth(), CVC5ApiException); d_solver.setOption("sygus", "true"); ASSERT_NO_THROW(d_solver.checkSynth()); } TEST_F(TestApiBlackSolver, getSynthSolution) { d_solver.setOption("sygus", "true"); d_solver.setOption("incremental", "false"); Term nullTerm; Term x = d_solver.mkBoolean(false); Term f = d_solver.synthFun("f", {}, d_solver.getBooleanSort()); ASSERT_THROW(d_solver.getSynthSolution(f), CVC5ApiException); cvc5::SynthResult sr = d_solver.checkSynth(); ASSERT_EQ(sr.hasSolution(), true); ASSERT_NO_THROW(d_solver.getSynthSolution(f)); ASSERT_NO_THROW(d_solver.getSynthSolution(f)); ASSERT_THROW(d_solver.getSynthSolution(nullTerm), CVC5ApiException); ASSERT_THROW(d_solver.getSynthSolution(x), CVC5ApiException); Solver slv; ASSERT_THROW(slv.getSynthSolution(f), CVC5ApiException); } TEST_F(TestApiBlackSolver, getSynthSolutions) { d_solver.setOption("sygus", "true"); d_solver.setOption("incremental", "false"); Term nullTerm; Term x = d_solver.mkBoolean(false); Term f = d_solver.synthFun("f", {}, d_solver.getBooleanSort()); ASSERT_THROW(d_solver.getSynthSolutions({}), CVC5ApiException); ASSERT_THROW(d_solver.getSynthSolutions({f}), CVC5ApiException); d_solver.checkSynth(); ASSERT_NO_THROW(d_solver.getSynthSolutions({f})); ASSERT_NO_THROW(d_solver.getSynthSolutions({f, f})); ASSERT_THROW(d_solver.getSynthSolutions({}), CVC5ApiException); ASSERT_THROW(d_solver.getSynthSolutions({nullTerm}), CVC5ApiException); ASSERT_THROW(d_solver.getSynthSolutions({x}), CVC5ApiException); Solver slv; ASSERT_THROW(slv.getSynthSolutions({x}), CVC5ApiException); } TEST_F(TestApiBlackSolver, checkSynthNext) { d_solver.setOption("sygus", "true"); d_solver.setOption("incremental", "true"); Term f = d_solver.synthFun("f", {}, d_solver.getBooleanSort()); cvc5::SynthResult sr = d_solver.checkSynth(); ASSERT_EQ(sr.hasSolution(), true); ASSERT_NO_THROW(d_solver.getSynthSolutions({f})); sr = d_solver.checkSynthNext(); ASSERT_EQ(sr.hasSolution(), true); ASSERT_NO_THROW(d_solver.getSynthSolutions({f})); } TEST_F(TestApiBlackSolver, checkSynthNext2) { d_solver.setOption("sygus", "true"); d_solver.setOption("incremental", "false"); Term f = d_solver.synthFun("f", {}, d_solver.getBooleanSort()); d_solver.checkSynth(); ASSERT_THROW(d_solver.checkSynthNext(), CVC5ApiException); } TEST_F(TestApiBlackSolver, checkSynthNext3) { d_solver.setOption("sygus", "true"); d_solver.setOption("incremental", "true"); Term f = d_solver.synthFun("f", {}, d_solver.getBooleanSort()); ASSERT_THROW(d_solver.checkSynthNext(), CVC5ApiException); } TEST_F(TestApiBlackSolver, tupleProject) { std::vector sorts = {d_solver.getBooleanSort(), d_solver.getIntegerSort(), d_solver.getStringSort(), d_solver.mkSetSort(d_solver.getStringSort())}; std::vector elements = { d_solver.mkBoolean(true), d_solver.mkInteger(3), d_solver.mkString("C"), d_solver.mkTerm(SET_SINGLETON, {d_solver.mkString("Z")})}; Term tuple = d_solver.mkTuple(sorts, elements); std::vector indices1 = {}; std::vector indices2 = {0}; std::vector indices3 = {0, 1}; std::vector indices4 = {0, 0, 2, 2, 3, 3, 0}; std::vector indices5 = {4}; std::vector indices6 = {0, 4}; ASSERT_NO_THROW( d_solver.mkTerm(d_solver.mkOp(TUPLE_PROJECT, indices1), {tuple})); ASSERT_NO_THROW( d_solver.mkTerm(d_solver.mkOp(TUPLE_PROJECT, indices2), {tuple})); ASSERT_NO_THROW( d_solver.mkTerm(d_solver.mkOp(TUPLE_PROJECT, indices3), {tuple})); ASSERT_NO_THROW( d_solver.mkTerm(d_solver.mkOp(TUPLE_PROJECT, indices4), {tuple})); ASSERT_THROW(d_solver.mkTerm(d_solver.mkOp(TUPLE_PROJECT, indices5), {tuple}), CVC5ApiException); ASSERT_THROW(d_solver.mkTerm(d_solver.mkOp(TUPLE_PROJECT, indices6), {tuple}), CVC5ApiException); std::vector indices = {0, 3, 2, 0, 1, 2}; Op op = d_solver.mkOp(TUPLE_PROJECT, indices); Term projection = d_solver.mkTerm(op, {tuple}); Datatype datatype = tuple.getSort().getDatatype(); DatatypeConstructor constructor = datatype[0]; for (size_t i = 0; i < indices.size(); i++) { Term selectorTerm = constructor[indices[i]].getTerm(); Term selectedTerm = d_solver.mkTerm(APPLY_SELECTOR, {selectorTerm, tuple}); Term simplifiedTerm = d_solver.simplify(selectedTerm); ASSERT_EQ(elements[indices[i]], simplifiedTerm); } ASSERT_EQ( "((_ tuple.project 0 3 2 0 1 2) (tuple true 3 \"C\" (set.singleton " "\"Z\")))", projection.toString()); } TEST_F(TestApiBlackSolver, Output) { ASSERT_THROW(d_solver.isOutputOn("foo-invalid"), CVC5ApiException); ASSERT_THROW(d_solver.getOutput("foo-invalid"), CVC5ApiException); ASSERT_FALSE(d_solver.isOutputOn("inst")); ASSERT_EQ(null_os.rdbuf(), d_solver.getOutput("inst").rdbuf()); d_solver.setOption("output", "inst"); ASSERT_TRUE(d_solver.isOutputOn("inst")); ASSERT_NE(null_os.rdbuf(), d_solver.getOutput("inst").rdbuf()); } TEST_F(TestApiBlackSolver, issue7000) { Sort s1 = d_solver.getIntegerSort(); Sort s2 = d_solver.mkFunctionSort({s1}, s1); Sort s3 = d_solver.getRealSort(); Term t4 = d_solver.mkPi(); Term t7 = d_solver.mkConst(s3, "_x5"); Term t37 = d_solver.mkConst(s2, "_x32"); Term t59 = d_solver.mkConst(s2, "_x51"); Term t72 = d_solver.mkTerm(EQUAL, {t37, t59}); Term t74 = d_solver.mkTerm(GT, {t4, t7}); Term query = d_solver.mkTerm(AND, {t72, t74, t72, t72}); // throws logic exception since logic is not higher order by default ASSERT_THROW(d_solver.checkSatAssuming(query.notTerm()), CVC5ApiException); } TEST_F(TestApiBlackSolver, issue5893) { Solver slv; Sort bvsort4 = d_solver.mkBitVectorSort(4); Sort bvsort8 = d_solver.mkBitVectorSort(8); Sort arrsort = d_solver.mkArraySort(bvsort4, bvsort8); Term arr = d_solver.mkConst(arrsort, "arr"); Term idx = d_solver.mkConst(bvsort4, "idx"); Term ten = d_solver.mkBitVector(8, "10", 10); Term sel = d_solver.mkTerm(SELECT, {arr, idx}); Term distinct = d_solver.mkTerm(DISTINCT, {sel, ten}); ASSERT_NO_FATAL_FAILURE(distinct.getOp()); } TEST_F(TestApiBlackSolver, proj_issue308) { Solver slv; slv.setOption("check-proofs", "true"); Sort s1 = slv.getBooleanSort(); Term t1 = slv.mkConst(s1, "_x0"); Term t2 = slv.mkTerm(Kind::XOR, {t1, t1}); slv.checkSatAssuming({t2}); auto unsat_core = slv.getUnsatCore(); ASSERT_FALSE(unsat_core.empty()); } TEST_F(TestApiBlackSolver, proj_issue373) { Sort s1 = d_solver.getRealSort(); DatatypeConstructorDecl ctor13 = d_solver.mkDatatypeConstructorDecl("_x115"); ctor13.addSelector("_x109", s1); Sort s4 = d_solver.declareDatatype("_x86", {ctor13}); Term t452 = d_solver.mkVar(s1, "_x281"); Term bvl = d_solver.mkTerm(d_solver.mkOp(VARIABLE_LIST), {t452}); Term acons = d_solver.mkTerm( d_solver.mkOp(APPLY_CONSTRUCTOR), {s4.getDatatype().getConstructor("_x115").getTerm(), t452}); // type exception ASSERT_THROW( d_solver.mkTerm(d_solver.mkOp(APPLY_CONSTRUCTOR), {bvl, acons, t452}), CVC5ApiException); } TEST_F(TestApiBlackSolver, proj_issue378) { DatatypeDecl dtdecl; DatatypeConstructorDecl cdecl; Sort s1 = d_solver.getBooleanSort(); dtdecl = d_solver.mkDatatypeDecl("_x0"); cdecl = d_solver.mkDatatypeConstructorDecl("_x6"); cdecl.addSelector("_x1", s1); dtdecl.addConstructor(cdecl); Sort s2 = d_solver.mkDatatypeSort(dtdecl); dtdecl = d_solver.mkDatatypeDecl("_x36"); cdecl = d_solver.mkDatatypeConstructorDecl("_x42"); cdecl.addSelector("_x37", s1); dtdecl.addConstructor(cdecl); Sort s4 = d_solver.mkDatatypeSort(dtdecl); Term t1 = d_solver.mkConst(s1, "_x53"); Term t4 = d_solver.mkConst(s4, "_x56"); Term t7 = d_solver.mkConst(s2, "_x58"); Sort sp = d_solver.mkParamSort("_x178"); dtdecl = d_solver.mkDatatypeDecl("_x176", {sp}); cdecl = d_solver.mkDatatypeConstructorDecl("_x184"); cdecl.addSelector("_x180", s2); dtdecl.addConstructor(cdecl); cdecl = d_solver.mkDatatypeConstructorDecl("_x186"); cdecl.addSelector("_x185", sp); dtdecl.addConstructor(cdecl); Sort s7 = d_solver.mkDatatypeSort(dtdecl); Sort s9 = s7.instantiate({s2}); Term t1507 = d_solver.mkTerm(APPLY_CONSTRUCTOR, {s9.getDatatype().getConstructor("_x184").getTerm(), t7}); ASSERT_NO_THROW(d_solver.mkTerm( APPLY_UPDATER, {s9.getDatatype().getConstructor("_x186").getSelector("_x185").getTerm(), t1507, t7})); } TEST_F(TestApiBlackSolver, proj_issue379) { Sort bsort = d_solver.getBooleanSort(); Sort psort = d_solver.mkParamSort("_x1"); DatatypeConstructorDecl cdecl; DatatypeDecl dtdecl = d_solver.mkDatatypeDecl("x_0", {psort}); cdecl = d_solver.mkDatatypeConstructorDecl("_x8"); cdecl.addSelector("_x7", bsort); dtdecl.addConstructor(cdecl); cdecl = d_solver.mkDatatypeConstructorDecl("_x6"); cdecl.addSelector("_x2", psort); cdecl.addSelectorSelf("_x3"); cdecl.addSelector("_x4", psort); cdecl.addSelector("_x5", bsort); Sort s2 = d_solver.mkDatatypeSort(dtdecl); Sort s6 = s2.instantiate({bsort}); Term t317 = d_solver.mkConst(bsort, "_x345"); Term t843 = d_solver.mkConst(s6, "_x346"); Term t879 = d_solver.mkTerm(APPLY_UPDATER, {t843.getSort() .getDatatype() .getConstructor("_x8") .getSelector("_x7") .getUpdaterTerm(), t843, t317}); ASSERT_EQ(t879.getSort(), s6); } TEST_F(TestApiBlackSolver, getDatatypeArity) { DatatypeConstructorDecl ctor1 = d_solver.mkDatatypeConstructorDecl("_x21"); DatatypeConstructorDecl ctor2 = d_solver.mkDatatypeConstructorDecl("_x31"); Sort s3 = d_solver.declareDatatype(std::string("_x17"), {ctor1, ctor2}); ASSERT_EQ(s3.getDatatypeArity(), 0); } TEST_F(TestApiBlackSolver, proj_issue381) { Sort s1 = d_solver.getBooleanSort(); Sort psort = d_solver.mkParamSort("_x9"); DatatypeDecl dtdecl = d_solver.mkDatatypeDecl("_x8", {psort}); DatatypeConstructorDecl ctor = d_solver.mkDatatypeConstructorDecl("_x22"); ctor.addSelector("_x19", s1); dtdecl.addConstructor(ctor); Sort s3 = d_solver.mkDatatypeSort(dtdecl); Sort s6 = s3.instantiate({s1}); Term t26 = d_solver.mkConst(s6, "_x63"); Term t5 = d_solver.mkTrue(); Term t187 = d_solver.mkTerm(APPLY_UPDATER, {t26.getSort() .getDatatype() .getConstructor("_x22") .getSelector("_x19") .getUpdaterTerm(), t26, t5}); ASSERT_NO_THROW(d_solver.simplify(t187)); } TEST_F(TestApiBlackSolver, proj_issue382) { Sort s1 = d_solver.getBooleanSort(); Sort psort = d_solver.mkParamSort("_x1"); DatatypeConstructorDecl ctor = d_solver.mkDatatypeConstructorDecl("_x20"); ctor.addSelector("_x19", psort); DatatypeDecl dtdecl = d_solver.mkDatatypeDecl("_x0", {psort}); dtdecl.addConstructor(ctor); Sort s2 = d_solver.mkDatatypeSort(dtdecl); Sort s6 = s2.instantiate({s1}); Term t13 = d_solver.mkVar(s6, "_x58"); Term t18 = d_solver.mkConst(s6, "_x63"); Term t52 = d_solver.mkVar(s6, "_x70"); Term t53 = d_solver.mkTerm(MATCH_BIND_CASE, {d_solver.mkTerm(VARIABLE_LIST, {t52}), t52, t18}); Term t73 = d_solver.mkVar(s1, "_x78"); Term t81 = d_solver.mkTerm( MATCH_BIND_CASE, {d_solver.mkTerm(VARIABLE_LIST, {t73}), d_solver.mkTerm( APPLY_CONSTRUCTOR, {s6.getDatatype().getConstructor("_x20").getInstantiatedTerm(s6), t73}), t18}); Term t82 = d_solver.mkTerm(MATCH, {t13, t53, t53, t53, t81}); Term t325 = d_solver.mkTerm( APPLY_SELECTOR, {t82.getSort().getDatatype().getSelector("_x19").getTerm(), t82}); ASSERT_NO_THROW(d_solver.simplify(t325)); } TEST_F(TestApiBlackSolver, proj_issue383) { d_solver.setOption("produce-models", "true"); Sort s1 = d_solver.getBooleanSort(); DatatypeConstructorDecl ctordecl = d_solver.mkDatatypeConstructorDecl("_x5"); DatatypeDecl dtdecl = d_solver.mkDatatypeDecl("_x0"); dtdecl.addConstructor(ctordecl); Sort s2 = d_solver.mkDatatypeSort(dtdecl); ctordecl = d_solver.mkDatatypeConstructorDecl("_x23"); ctordecl.addSelectorSelf("_x21"); dtdecl = d_solver.mkDatatypeDecl("_x12"); dtdecl.addConstructor(ctordecl); ASSERT_THROW(d_solver.mkDatatypeSort(dtdecl), CVC5ApiException); } TEST_F(TestApiBlackSolver, proj_issue386) { Sort s1 = d_solver.getBooleanSort(); Sort p1 = d_solver.mkParamSort("_p1"); Sort p2 = d_solver.mkParamSort("_p2"); DatatypeDecl dtdecl = d_solver.mkDatatypeDecl("_x0", {p1, p2}); DatatypeConstructorDecl ctordecl = d_solver.mkDatatypeConstructorDecl("_x1"); ctordecl.addSelector("_x2", p1); dtdecl.addConstructor(ctordecl); Sort s2 = d_solver.mkDatatypeSort(dtdecl); ASSERT_THROW(s2.instantiate({s1}), CVC5ApiException); } TEST_F(TestApiBlackSolver, proj_issue414) { Solver slv; Sort s2 = slv.getRealSort(); Term t1 = slv.mkConst(s2, "_x0"); Term t16 = slv.mkTerm(Kind::PI); Term t53 = slv.mkTerm(Kind::SUB, {t1, t16}); Term t54 = slv.mkTerm(Kind::SECANT, {t53}); ASSERT_NO_THROW(slv.simplify(t54)); } TEST_F(TestApiBlackSolver, proj_issue420) { Solver slv; slv.setOption("strings-exp", "true"); slv.setOption("produce-models", "true"); slv.setOption("produce-unsat-cores", "true"); Sort s2 = slv.getRealSort(); Sort s3 = slv.mkUninterpretedSort("_u0"); DatatypeDecl _dt1 = slv.mkDatatypeDecl("_dt1", {}); DatatypeConstructorDecl _cons16 = slv.mkDatatypeConstructorDecl("_cons16"); _cons16.addSelector("_sel13", s3); _dt1.addConstructor(_cons16); std::vector _s4 = slv.mkDatatypeSorts({_dt1}); Sort s4 = _s4[0]; Sort s5 = slv.mkSequenceSort(s2); Term t3 = slv.mkConst(s5, "_x18"); Term t7 = slv.mkConst(s4, "_x22"); // was initially a dt size application Term t13 = slv.mkConst(slv.getIntegerSort(), "t13"); Term t53 = slv.mkTerm(Kind::SEQ_NTH, {t3, t13}); ASSERT_NO_THROW(slv.checkSat()); ASSERT_NO_THROW(slv.blockModelValues({t53, t7})); ASSERT_NO_THROW(slv.checkSat()); } TEST_F(TestApiBlackSolver, proj_issue440) { Solver slv; slv.setLogic("QF_ALL"); slv.setOption("global-negate", "true"); slv.setOption("produce-unsat-cores", "true"); Sort s1 = slv.getBooleanSort(); Term t9 = slv.mkBoolean(true); Term t109 = slv.mkTerm(Kind::NOT, {t9}); // should throw an option exception ASSERT_THROW(slv.checkSatAssuming({t109}), CVC5ApiException); } TEST_F(TestApiBlackSolver, proj_issue434) { Solver slv; slv.setOption("dump-difficulty", "true"); slv.setOption("debug-check-models", "true"); Sort s1 = slv.mkUninterpretedSort("_u0"); Sort s2 = slv.mkUninterpretedSort("_u1"); Sort s3 = slv.mkUninterpretedSort("_u2"); Sort s4 = slv.getBooleanSort(); Term t1 = slv.mkConst(s1, "_x3"); Term t3 = slv.mkConst(s3, "_x5"); Term t15 = slv.mkConst(s1, "_x17"); Term t26 = slv.mkBoolean(false); Term t60 = slv.mkVar(s4, "_f29_1"); Term t73 = slv.defineFun("_f29", {t60}, t60.getSort(), t60); Term t123 = slv.mkVar(s4, "_f31_0"); Term t135 = slv.defineFun("_f31", {t123}, t123.getSort(), t123); Term t506 = slv.mkVar(s1, "_f37_0"); Term t507 = slv.mkVar(s4, "_f37_1"); Term t510 = slv.mkTerm(Kind::APPLY_UF, {t73, t507}); Term t530 = slv.defineFun("_f37", {t507}, t510.getSort(), t510); Term t559 = slv.mkTerm(Kind::DISTINCT, {t15, t1}); Term t631 = slv.mkTerm(Kind::XOR, {t559, t26}); Term t632 = slv.mkTerm(Kind::APPLY_UF, {t135, t631}); Term t715 = slv.mkVar(s4, "_f40_0"); Term t721 = slv.mkTerm(Kind::APPLY_UF, {t530, t715}); Term t722 = slv.mkTerm(Kind::APPLY_UF, {t530, t721}); Term t731 = slv.defineFun("_f40", {t715}, t722.getSort(), t722); Term t1014 = slv.mkVar(s4, "_f45_0"); Term t1034 = slv.mkTerm(Kind::DISTINCT, {t510, t510}); Term t1035 = slv.mkTerm(Kind::XOR, {t1034, t632}); Term t1037 = slv.mkTerm(Kind::APPLY_UF, {t135, t1035}); Term t1039 = slv.mkTerm(Kind::APPLY_UF, {t731, t1037}); Term t1040 = slv.defineFun("_f45", {t1014}, t1039.getSort(), t1039); Term t1072 = slv.mkTerm(Kind::APPLY_UF, {t1040, t510}); Term t1073 = slv.mkTerm(Kind::APPLY_UF, {t73, t1072}); // the query has free variables, and should throw an exception ASSERT_THROW(slv.checkSatAssuming({t1073, t510}), CVC5ApiException); } TEST_F(TestApiBlackSolver, proj_issue436) { Solver slv; slv.setOption("produce-abducts", "true"); slv.setOption("solve-bv-as-int", "sum"); Sort s8 = slv.mkBitVectorSort(68); Term t17 = slv.mkConst(s8, "_x6"); Term t23; { uint32_t bw = s8.getBitVectorSize(); t23 = slv.mkBitVector(bw, 1); } Term t33 = slv.mkTerm(Kind::BITVECTOR_ULT, {t17, t23}); // solve-bv-as-int is incompatible with get-abduct ASSERT_THROW(slv.getAbduct(t33), CVC5ApiException); } TEST_F(TestApiBlackSolver, proj_issue431) { Solver slv; slv.setOption("produce-models", "true"); slv.setOption("produce-unsat-assumptions", "true"); slv.setOption("produce-assertions", "true"); Sort s1 = slv.getStringSort(); Sort s3 = slv.getIntegerSort(); Sort s7 = slv.mkArraySort(s1, s3); Term t3 = slv.mkConst(s1, "_x2"); Term t57 = slv.mkVar(s7, "_x38"); Term t103 = slv.mkTerm(Kind::SELECT, {t57, t3}); slv.checkSat(); ASSERT_THROW(slv.blockModelValues({t103}), CVC5ApiException); } TEST_F(TestApiBlackSolver, proj_issue426) { Solver slv; slv.setLogic("ALL"); slv.setOption("strings-exp", "true"); slv.setOption("produce-models", "true"); slv.setOption("produce-assertions", "true"); Sort s1 = slv.getRealSort(); Sort s2 = slv.getRoundingModeSort(); Sort s4 = slv.mkSequenceSort(s1); Sort s5 = slv.mkArraySort(s4, s4); Term t4 = slv.mkConst(s1, "_x3"); Term t5 = slv.mkReal("9192/832927743"); Term t19 = slv.mkConst(s2, "_x42"); Term t24 = slv.mkConst(s5, "_x44"); Term t37 = slv.mkRoundingMode(RoundingMode::ROUND_TOWARD_POSITIVE); slv.checkSat(); slv.blockModelValues({t24, t19, t4, t37}); slv.checkSat(); ASSERT_NO_THROW(slv.getValue({t5})); } TEST_F(TestApiBlackSolver, proj_issue429) { Solver slv; Sort s1 = slv.getRealSort(); Term t6 = slv.mkConst(s1, "_x5"); Term t16 = slv.mkReal(std::stoll("1696223.9473797265702297792792306581323741")); Term t111 = slv.mkTerm(Kind::SEQ_UNIT, {t16}); Term t119 = slv.mkTerm(slv.mkOp(Kind::SEQ_UNIT), {t6}); Term t126 = slv.mkTerm(Kind::SEQ_PREFIX, {t111, t119}); slv.checkSatAssuming({t126.notTerm()}); } TEST_F(TestApiBlackSolver, proj_issue422) { Solver slv; slv.setOption("sygus-rr-synth-input", "true"); slv.setOption("strings-exp", "true"); slv.setOption("sygus-abort-size", "1"); Sort s1 = slv.mkBitVectorSort(36); Sort s2 = slv.getStringSort(); Term t1 = slv.mkConst(s2, "_x0"); Term t2 = slv.mkConst(s1, "_x1"); Term t11; { uint32_t bw = s1.getBitVectorSize(); std::string val(bw, '1'); val[0] = '0'; t11 = slv.mkBitVector(bw, val, 2); } Term t60 = slv.mkTerm(Kind::SET_SINGLETON, {t1}); Term t66 = slv.mkTerm(Kind::BITVECTOR_COMP, {t2, t11}); Term t92 = slv.mkRegexpAll(); Term t96 = slv.mkTerm(slv.mkOp(Kind::BITVECTOR_ZERO_EXTEND, {51}), {t66}); Term t105 = slv.mkTerm(Kind::BITVECTOR_ADD, {t96, t96}); Term t113 = slv.mkTerm(Kind::BITVECTOR_SUB, {t105, t105}); Term t137 = slv.mkTerm(Kind::BITVECTOR_XOR, {t113, t105}); Term t211 = slv.mkTerm(Kind::BITVECTOR_SLTBV, {t137, t137}); Term t212 = slv.mkTerm(Kind::SET_MINUS, {t60, t60}); Term t234 = slv.mkTerm(Kind::SET_CHOOSE, {t212}); Term t250 = slv.mkTerm(Kind::STRING_REPLACE_RE_ALL, {t1, t92, t1}); Term t259 = slv.mkTerm(Kind::STRING_REPLACE_ALL, {t234, t234, t250}); Term t263 = slv.mkTerm(Kind::STRING_TO_LOWER, {t259}); Term t272 = slv.mkTerm(Kind::BITVECTOR_SDIV, {t211, t66}); Term t276 = slv.mkTerm(slv.mkOp(Kind::BITVECTOR_ZERO_EXTEND, {71}), {t272}); Term t288 = slv.mkTerm(Kind::EQUAL, {t263, t1}); Term t300 = slv.mkTerm(Kind::BITVECTOR_SLT, {t276, t276}); Term t301 = slv.mkTerm(Kind::EQUAL, {t288, t300}); slv.assertFormula({t301}); // should terminate with an exception indicating we are done enumerating // rewrite rules. ASSERT_THROW(slv.push(4), CVC5ApiException); } TEST_F(TestApiBlackSolver, proj_issue423) { Solver slv; slv.setOption("produce-models", "true"); slv.setOption("produce-difficulty", "true"); Sort s2 = slv.getRealSort(); Sort s3 = slv.mkSequenceSort(s2); Term t2; { t2 = slv.mkEmptySequence(s3.getSequenceElementSort()); } Term t22 = slv.mkReal("119605652059157009"); Term t32 = slv.mkTerm(Kind::SEQ_UNIT, {t22}); Term t43 = slv.mkTerm(Kind::SEQ_CONCAT, {t2, t32}); Term t51 = slv.mkTerm(Kind::DISTINCT, {t32, t32}); slv.checkSat(); slv.blockModelValues({t51, t43}); } TEST_F(TestApiBlackSolver, projIssue431) { Solver slv; slv.setOption("produce-abducts", "true"); Sort s2 = slv.mkBitVectorSort(22); Sort s4 = slv.mkSetSort(s2); Sort s5 = slv.getBooleanSort(); Sort s6 = slv.getRealSort(); Sort s7 = slv.mkFunctionSort({s6}, s5); DatatypeDecl _dt46 = slv.mkDatatypeDecl("_dt46", {}); DatatypeConstructorDecl _cons64 = slv.mkDatatypeConstructorDecl("_cons64"); _cons64.addSelector("_sel62", s6); _cons64.addSelector("_sel63", s4); _dt46.addConstructor(_cons64); Sort s14 = slv.mkDatatypeSorts({_dt46})[0]; Term t31 = slv.mkConst(s7, "_x100"); Term t47 = slv.mkConst(s14, "_x112"); Term sel = t47.getSort() .getDatatype() .getConstructor("_cons64") .getSelector("_sel62") .getTerm(); Term t274 = slv.mkTerm(APPLY_SELECTOR, {sel, t47}); Term t488 = slv.mkTerm(Kind::APPLY_UF, {t31, t274}); slv.assertFormula({t488}); Term abduct; abduct = slv.getAbduct(t488); } TEST_F(TestApiBlackSolver, projIssue337) { Term t = d_solver.mkTerm(SEQ_UNIT, {d_solver.mkReal("3416574625719121610379268")}); Term tt = d_solver.simplify(t); ASSERT_EQ(t.getSort(), tt.getSort()); } TEST_F(TestApiBlackSolver, declareOracleFunError) { Sort iSort = d_solver.getIntegerSort(); // cannot declare without option ASSERT_THROW(d_solver.declareOracleFun( "f", {iSort}, iSort, [&](const std::vector& input) { return d_solver.mkInteger(0); }); , CVC5ApiException); d_solver.setOption("oracles", "true"); Sort nullSort; // bad sort ASSERT_THROW(d_solver.declareOracleFun( "f", {nullSort}, iSort, [&](const std::vector& input) { return d_solver.mkInteger(0); }); , CVC5ApiException); } TEST_F(TestApiBlackSolver, declareOracleFunUnsat) { d_solver.setOption("oracles", "true"); Sort iSort = d_solver.getIntegerSort(); // f is the function implementing (lambda ((x Int)) (+ x 1)) Term f = d_solver.declareOracleFun( "f", {iSort}, iSort, [&](const std::vector& input) { if (input[0].isUInt32Value()) { return d_solver.mkInteger(input[0].getUInt32Value() + 1); } return d_solver.mkInteger(0); }); Term three = d_solver.mkInteger(3); Term five = d_solver.mkInteger(5); Term eq = d_solver.mkTerm(EQUAL, {d_solver.mkTerm(APPLY_UF, {f, three}), five}); d_solver.assertFormula(eq); // (f 3) = 5 ASSERT_TRUE(d_solver.checkSat().isUnsat()); } TEST_F(TestApiBlackSolver, declareOracleFunSat) { d_solver.setOption("oracles", "true"); d_solver.setOption("produce-models", "true"); Sort iSort = d_solver.getIntegerSort(); // f is the function implementing (lambda ((x Int)) (% x 10)) Term f = d_solver.declareOracleFun( "f", {iSort}, iSort, [&](const std::vector& input) { if (input[0].isUInt32Value()) { return d_solver.mkInteger(input[0].getUInt32Value() % 10); } return d_solver.mkInteger(0); }); Term seven = d_solver.mkInteger(7); Term x = d_solver.mkConst(iSort, "x"); Term lb = d_solver.mkTerm(GEQ, {x, d_solver.mkInteger(0)}); d_solver.assertFormula(lb); Term ub = d_solver.mkTerm(LEQ, {x, d_solver.mkInteger(100)}); d_solver.assertFormula(ub); Term eq = d_solver.mkTerm(EQUAL, {d_solver.mkTerm(APPLY_UF, {f, x}), seven}); d_solver.assertFormula(eq); // x >= 0 ^ x <= 100 ^ (f x) = 7 ASSERT_TRUE(d_solver.checkSat().isSat()); Term xval = d_solver.getValue(x); ASSERT_TRUE(xval.isUInt32Value()); ASSERT_TRUE(xval.getUInt32Value() % 10 == 7); } TEST_F(TestApiBlackSolver, declareOracleFunSat2) { d_solver.setOption("oracles", "true"); d_solver.setOption("produce-models", "true"); Sort iSort = d_solver.getIntegerSort(); Sort bSort = d_solver.getBooleanSort(); // f is the function implementing (lambda ((x Int) (y Int)) (= x y)) Term eq = d_solver.declareOracleFun( "eq", {iSort, iSort}, bSort, [&](const std::vector& input) { return d_solver.mkBoolean(input[0] == input[1]); }); Term x = d_solver.mkConst(iSort, "x"); Term y = d_solver.mkConst(iSort, "y"); Term neq = d_solver.mkTerm(NOT, {d_solver.mkTerm(APPLY_UF, {eq, x, y})}); d_solver.assertFormula(neq); // (not (eq x y)) ASSERT_TRUE(d_solver.checkSat().isSat()); Term xval = d_solver.getValue(x); Term yval = d_solver.getValue(y); ASSERT_TRUE(xval != yval); } TEST_F(TestApiBlackSolver, verticalBars) { Term a = d_solver.declareFun("|a |", {}, d_solver.getRealSort()); ASSERT_EQ("|a |", a.toString()); } TEST_F(TestApiBlackSolver, getVersion) { std::cout << d_solver.getVersion() << std::endl; } TEST_F(TestApiBlackSolver, multipleSolvers) { Term function1, function2, value1, value2, definedFunction; Sort integerSort; Term zero; { Solver s1; s1.setLogic("ALL"); s1.setOption("produce-models", "true"); integerSort = s1.getIntegerSort(); function1 = s1.declareFun("f1", {}, s1.getIntegerSort()); Term x = s1.mkVar(integerSort, "x"); zero = s1.mkInteger(0); definedFunction = s1.defineFun("f", {x}, integerSort, zero); s1.assertFormula(function1.eqTerm(zero)); s1.checkSat(); value1 = s1.getValue(function1); } ASSERT_EQ(zero, value1); { Solver s2; s2.setLogic("ALL"); s2.setOption("produce-models", "true"); function2 = s2.declareFun("function2", {}, integerSort); s2.assertFormula(function2.eqTerm(value1)); s2.checkSat(); value2 = s2.getValue(function2); } ASSERT_EQ(value1, value2); { Solver s3; s3.setLogic("ALL"); s3.setOption("produce-models", "true"); function2 = s3.declareFun("function3", {}, integerSort); Term apply = s3.mkTerm(APPLY_UF, {definedFunction, zero}); s3.assertFormula(function2.eqTerm(apply)); s3.checkSat(); Term value3 = s3.getValue(function2); ASSERT_EQ(value1, value3); } } } // namespace test } // namespace cvc5::internal