LCOV - code coverage report
Current view: top level - buildbot/coverage/build/test/unit/api/cpp - api_solver_black.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1985 1988 99.8 %
Date: 2026-05-08 10:22:53 Functions: 536 542 98.9 %
Branches: 1350 2934 46.0 %

           Branch data     Line data    Source code
       1                 :            : /******************************************************************************
       2                 :            :  * This file is part of the cvc5 project.
       3                 :            :  *
       4                 :            :  * Copyright (c) 2009-2026 by the authors listed in the file AUTHORS
       5                 :            :  * in the top-level source directory and their institutional affiliations.
       6                 :            :  * All rights reserved.  See the file COPYING in the top-level source
       7                 :            :  * directory for licensing information.
       8                 :            :  * ****************************************************************************
       9                 :            :  *
      10                 :            :  * Black box testing of the Solver class of the  C++ API.
      11                 :            :  */
      12                 :            : 
      13                 :            : #include <cvc5/cvc5_types.h>
      14                 :            : #include <gtest/gtest.h>
      15                 :            : 
      16                 :            : #include <algorithm>
      17                 :            : #include <cmath>
      18                 :            : 
      19                 :            : #include "base/output.h"
      20                 :            : #include "test_api.h"
      21                 :            : 
      22                 :            : namespace cvc5::internal {
      23                 :            : 
      24                 :            : namespace test {
      25                 :            : 
      26                 :            : class TestApiBlackSolver : public TestApi
      27                 :            : {
      28                 :            : };
      29                 :            : 
      30                 :          4 : TEST_F(TestApiBlackSolver, pow2Large1)
      31                 :            : {
      32                 :            :   // Based on https://github.com/cvc5/cvc5-projects/issues/371
      33                 :          1 :   Sort s4 = d_tm.mkArraySort(d_string, d_int);
      34                 :          1 :   Sort s7 = d_tm.mkArraySort(d_int, d_string);
      35                 :          2 :   Term t10 = d_tm.mkInteger("68038927088685865242724985643");
      36                 :          2 :   Term t74 = d_tm.mkInteger("8416288636405");
      37                 :          1 :   std::vector<DatatypeConstructorDecl> ctors;
      38                 :          1 :   ctors.push_back(d_tm.mkDatatypeConstructorDecl("_x109"));
      39                 :          1 :   ctors.back().addSelector("_x108", s7);
      40                 :          1 :   ctors.push_back(d_tm.mkDatatypeConstructorDecl("_x113"));
      41                 :          1 :   ctors.back().addSelector("_x110", s4);
      42                 :          1 :   ctors.back().addSelector("_x111", d_int);
      43                 :          1 :   ctors.back().addSelector("_x112", s7);
      44                 :          2 :   Sort s11 = d_solver->declareDatatype("_x107", ctors);
      45                 :          1 :   Term t82 = d_tm.mkConst(s11, "_x114");
      46                 :          3 :   Term t180 = d_tm.mkTerm(Kind::POW2, {t10});
      47                 :          4 :   Term t258 = d_tm.mkTerm(Kind::GEQ, {t74, t180});
      48                 :          1 :   d_solver->assertFormula(t258);
      49                 :          1 :   ASSERT_THROW(d_solver->simplify(t82, true), CVC5ApiException);
      50 [ +  - ][ +  - ]:          1 : }
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
      51                 :            : 
      52                 :          4 : TEST_F(TestApiBlackSolver, pow2Large2)
      53                 :            : {
      54                 :            :   // Based on https://github.com/cvc5/cvc5-projects/issues/333
      55                 :          1 :   Term t1 = d_tm.mkBitVector(63, ~(((uint64_t)1) << 62));
      56                 :          3 :   Term t2 = d_tm.mkTerm(Kind::BITVECTOR_UBV_TO_INT, {t1});
      57                 :          3 :   Term t3 = d_tm.mkTerm(Kind::POW2, {t2});
      58                 :          4 :   Term t4 = d_tm.mkTerm(Kind::DISTINCT, {t3, t2});
      59                 :          1 :   ASSERT_THROW(d_solver->checkSatAssuming({t4}), CVC5ApiException);
      60 [ +  - ][ +  - ]:          1 : }
         [ +  - ][ +  - ]
      61                 :            : 
      62                 :          4 : TEST_F(TestApiBlackSolver, pow2Large3)
      63                 :            : {
      64                 :            :   // Based on https://github.com/cvc5/cvc5-projects/issues/339
      65                 :          2 :   Term t203 = d_tm.mkInteger("6135470354240554220207");
      66                 :          3 :   Term t262 = d_tm.mkTerm(Kind::POW2, {t203});
      67                 :          3 :   Term t536 = d_tm.mkTerm(d_tm.mkOp(Kind::INT_TO_BITVECTOR, {49}), {t262});
      68                 :            :   // should not throw an exception, will not simplify.
      69 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->simplify(t536));
         [ +  - ][ -  - ]
      70 [ +  - ][ +  - ]:          1 : }
                 [ +  - ]
      71                 :            : 
      72                 :          4 : TEST_F(TestApiBlackSolver, recoverableException)
      73                 :            : {
      74                 :          1 :   d_solver->setOption("produce-models", "true");
      75                 :          1 :   Term x = d_tm.mkConst(d_bool, "x");
      76                 :          1 :   d_solver->assertFormula(x.eqTerm(x).notTerm());
      77                 :          1 :   ASSERT_THROW(d_solver->getValue(x), CVC5ApiRecoverableException);
      78                 :            : 
      79                 :            :   try
      80                 :            :   {
      81                 :          1 :     d_solver->getValue(x);
      82                 :            :   }
      83         [ -  + ]:          1 :   catch (const CVC5ApiRecoverableException& e)
      84                 :            :   {
      85 [ +  - ][ +  - ]:          1 :     ASSERT_NO_THROW(e.what());
         [ +  - ][ -  - ]
      86 [ +  - ][ +  - ]:          1 :     ASSERT_NO_THROW(e.getMessage());
         [ +  - ][ -  - ]
      87         [ +  - ]:          1 :   }
      88         [ +  - ]:          1 : }
      89                 :            : 
      90                 :          4 : TEST_F(TestApiBlackSolver, simplify)
      91                 :            : {
      92                 :          2 :   ASSERT_THROW(d_solver->simplify(Term()), CVC5ApiException);
      93                 :            : 
      94                 :          1 :   Sort bvSort = d_tm.mkBitVectorSort(32);
      95                 :          4 :   Sort funSort1 = d_tm.mkFunctionSort({bvSort, bvSort}, bvSort);
      96                 :          3 :   Sort funSort2 = d_tm.mkFunctionSort({d_uninterpreted}, d_int);
      97                 :          2 :   DatatypeDecl consListSpec = d_tm.mkDatatypeDecl("list");
      98                 :          2 :   DatatypeConstructorDecl cons = d_tm.mkDatatypeConstructorDecl("cons");
      99                 :          1 :   cons.addSelector("head", d_int);
     100                 :          1 :   cons.addSelectorSelf("tail");
     101                 :          1 :   consListSpec.addConstructor(cons);
     102                 :          2 :   DatatypeConstructorDecl nil = d_tm.mkDatatypeConstructorDecl("nil");
     103                 :          1 :   consListSpec.addConstructor(nil);
     104                 :          1 :   Sort consListSort = d_tm.mkDatatypeSort(consListSpec);
     105                 :            : 
     106                 :          1 :   Term x = d_tm.mkConst(bvSort, "x");
     107 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->simplify(x));
         [ +  - ][ -  - ]
     108                 :          1 :   Term a = d_tm.mkConst(bvSort, "a");
     109 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->simplify(a));
         [ +  - ][ -  - ]
     110                 :          1 :   Term b = d_tm.mkConst(bvSort, "b");
     111 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->simplify(b));
         [ +  - ][ -  - ]
     112                 :          4 :   Term x_eq_x = d_tm.mkTerm(Kind::EQUAL, {x, x});
     113 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->simplify(x_eq_x));
         [ +  - ][ -  - ]
     114 [ -  + ][ +  - ]:          2 :   ASSERT_NE(d_tm.mkTrue(), x_eq_x);
     115 [ -  + ][ +  - ]:          2 :   ASSERT_EQ(d_tm.mkTrue(), d_solver->simplify(x_eq_x));
     116                 :          4 :   Term x_eq_b = d_tm.mkTerm(Kind::EQUAL, {x, b});
     117 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->simplify(x_eq_b));
         [ +  - ][ -  - ]
     118 [ -  + ][ +  - ]:          2 :   ASSERT_NE(d_tm.mkTrue(), x_eq_b);
     119 [ -  + ][ +  - ]:          2 :   ASSERT_NE(d_tm.mkTrue(), d_solver->simplify(x_eq_b));
     120                 :            : 
     121                 :          1 :   Term i1 = d_tm.mkConst(d_int, "i1");
     122 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->simplify(i1));
         [ +  - ][ -  - ]
     123                 :          5 :   Term i2 = d_tm.mkTerm(Kind::MULT, {i1, d_tm.mkInteger("23")});
     124 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->simplify(i2));
         [ +  - ][ -  - ]
     125 [ -  + ][ +  - ]:          1 :   ASSERT_NE(i1, i2);
     126 [ -  + ][ +  - ]:          2 :   ASSERT_NE(i1, d_solver->simplify(i2));
     127                 :          4 :   Term i3 = d_tm.mkTerm(Kind::ADD, {i1, d_tm.mkInteger(0)});
     128 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->simplify(i3));
         [ +  - ][ -  - ]
     129 [ -  + ][ +  - ]:          1 :   ASSERT_NE(i1, i3);
     130 [ -  + ][ +  - ]:          2 :   ASSERT_EQ(i1, d_solver->simplify(i3));
     131                 :            : 
     132                 :          1 :   Datatype consList = consListSort.getDatatype();
     133                 :            :   Term dt1 =
     134                 :          3 :       d_tm.mkTerm(Kind::APPLY_CONSTRUCTOR,
     135                 :          2 :                   {consList.getConstructor("cons").getTerm(),
     136                 :            :                    d_tm.mkInteger(0),
     137                 :          1 :                    d_tm.mkTerm(Kind::APPLY_CONSTRUCTOR,
     138                 :          5 :                                {consList.getConstructor("nil").getTerm()})});
     139 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->simplify(dt1));
         [ +  - ][ -  - ]
     140                 :          2 :   Term dt2 = d_tm.mkTerm(Kind::APPLY_SELECTOR,
     141                 :          3 :                          {consList["cons"].getSelector("head").getTerm(), dt1});
     142 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->simplify(dt2));
         [ +  - ][ -  - ]
     143                 :            : 
     144                 :          1 :   Term b1 = d_tm.mkVar(bvSort, "b1");
     145 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->simplify(b1));
         [ +  - ][ -  - ]
     146                 :          1 :   Term b2 = d_tm.mkVar(bvSort, "b1");
     147 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->simplify(b2));
         [ +  - ][ -  - ]
     148                 :          1 :   Term b3 = d_tm.mkVar(d_uninterpreted, "b3");
     149 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->simplify(b3));
         [ +  - ][ -  - ]
     150                 :          1 :   Term v1 = d_tm.mkConst(bvSort, "v1");
     151 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->simplify(v1));
         [ +  - ][ -  - ]
     152                 :          1 :   Term v2 = d_tm.mkConst(d_int, "v2");
     153 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->simplify(v2));
         [ +  - ][ -  - ]
     154                 :          1 :   Term f1 = d_tm.mkConst(funSort1, "f1");
     155 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->simplify(f1));
         [ +  - ][ -  - ]
     156                 :          1 :   Term f2 = d_tm.mkConst(funSort2, "f2");
     157 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->simplify(f2));
         [ +  - ][ -  - ]
     158                 :         10 :   d_solver->defineFunsRec({f1, f2}, {{b1, b2}, {b3}}, {v1, v2});
     159 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->simplify(f1));
         [ +  - ][ -  - ]
     160 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->simplify(f2));
         [ +  - ][ -  - ]
     161                 :            : 
     162                 :          1 :   TermManager tm;
     163                 :          1 :   Solver slv(tm);
     164                 :          1 :   ASSERT_THROW(slv.simplify(x), CVC5ApiException);
     165                 :            : }
     166                 :            : 
     167                 :          4 : TEST_F(TestApiBlackSolver, simplifyApplySubs)
     168                 :            : {
     169                 :          1 :   d_solver->setOption("incremental", "true");
     170                 :          1 :   Term x = d_tm.mkConst(d_int, "x");
     171                 :          1 :   Term zero = d_tm.mkInteger(0);
     172                 :          4 :   Term eq = d_tm.mkTerm(Kind::EQUAL, {x, zero});
     173                 :          1 :   d_solver->assertFormula(eq);
     174 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->checkSat());
         [ +  - ][ -  - ]
     175                 :            : 
     176 [ -  + ][ +  - ]:          2 :   ASSERT_EQ(d_solver->simplify(x, false), x);
     177 [ -  + ][ +  - ]:          2 :   ASSERT_EQ(d_solver->simplify(x, true), zero);
     178 [ +  - ][ +  - ]:          1 : }
                 [ +  - ]
     179                 :            : 
     180                 :          4 : TEST_F(TestApiBlackSolver, assertFormula)
     181                 :            : {
     182 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->assertFormula(d_tm.mkTrue()));
         [ +  - ][ -  - ]
     183                 :          2 :   ASSERT_THROW(d_solver->assertFormula(Term()), CVC5ApiException);
     184                 :          1 :   TermManager tm;
     185                 :          1 :   Solver slv(tm);
     186                 :          2 :   ASSERT_THROW(slv.assertFormula(d_tm.mkTrue()), CVC5ApiException);
     187                 :            : }
     188                 :            : 
     189                 :          4 : TEST_F(TestApiBlackSolver, checkSat)
     190                 :            : {
     191                 :          1 :   d_solver->setOption("incremental", "false");
     192 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->checkSat());
         [ +  - ][ -  - ]
     193                 :          1 :   ASSERT_THROW(d_solver->checkSat(), CVC5ApiException);
     194                 :            : }
     195                 :            : 
     196                 :          4 : TEST_F(TestApiBlackSolver, checkSatAssuming)
     197                 :            : {
     198                 :          1 :   d_solver->setOption("incremental", "false");
     199 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->checkSatAssuming(d_tm.mkTrue()));
         [ +  - ][ -  - ]
     200                 :          2 :   ASSERT_THROW(d_solver->checkSatAssuming(d_tm.mkTrue()), CVC5ApiException);
     201                 :          1 :   TermManager tm;
     202                 :          1 :   Solver slv(tm);
     203                 :          2 :   ASSERT_THROW(slv.checkSatAssuming(d_tm.mkTrue()), CVC5ApiException);
     204                 :            : }
     205                 :            : 
     206                 :          4 : TEST_F(TestApiBlackSolver, checkSatAssuming1)
     207                 :            : {
     208                 :          1 :   Term x = d_tm.mkConst(d_bool, "x");
     209                 :          1 :   Term y = d_tm.mkConst(d_bool, "y");
     210                 :          4 :   Term z = d_tm.mkTerm(Kind::AND, {x, y});
     211                 :          1 :   d_solver->setOption("incremental", "true");
     212 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->checkSatAssuming(d_tm.mkTrue()));
         [ +  - ][ -  - ]
     213                 :          2 :   ASSERT_THROW(d_solver->checkSatAssuming(Term()), CVC5ApiException);
     214 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->checkSatAssuming(d_tm.mkTrue()));
         [ +  - ][ -  - ]
     215 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->checkSatAssuming(z));
         [ +  - ][ -  - ]
     216 [ +  - ][ +  - ]:          1 : }
                 [ +  - ]
     217                 :            : 
     218                 :          4 : TEST_F(TestApiBlackSolver, checkSatAssuming2)
     219                 :            : {
     220                 :          1 :   d_solver->setOption("incremental", "true");
     221                 :            : 
     222                 :          3 :   Sort uToIntSort = d_tm.mkFunctionSort({d_uninterpreted}, d_int);
     223                 :          3 :   Sort intPredSort = d_tm.mkFunctionSort({d_int}, d_bool);
     224                 :            : 
     225                 :          1 :   Term n = Term();
     226                 :            :   // Constants
     227                 :          1 :   Term x = d_tm.mkConst(d_uninterpreted, "x");
     228                 :          1 :   Term y = d_tm.mkConst(d_uninterpreted, "y");
     229                 :            :   // Functions
     230                 :          1 :   Term f = d_tm.mkConst(uToIntSort, "f");
     231                 :          1 :   Term p = d_tm.mkConst(intPredSort, "p");
     232                 :            :   // Values
     233                 :          1 :   Term zero = d_tm.mkInteger(0);
     234                 :          1 :   Term one = d_tm.mkInteger(1);
     235                 :            :   // Terms
     236                 :          4 :   Term f_x = d_tm.mkTerm(Kind::APPLY_UF, {f, x});
     237                 :          4 :   Term f_y = d_tm.mkTerm(Kind::APPLY_UF, {f, y});
     238                 :          4 :   Term sum = d_tm.mkTerm(Kind::ADD, {f_x, f_y});
     239                 :          4 :   Term p_0 = d_tm.mkTerm(Kind::APPLY_UF, {p, zero});
     240                 :          4 :   Term p_f_y = d_tm.mkTerm(Kind::APPLY_UF, {p, f_y});
     241                 :            :   // Assertions
     242                 :            :   Term assertions =
     243                 :          5 :       d_tm.mkTerm(Kind::AND,
     244                 :            :                   {
     245                 :          2 :                       d_tm.mkTerm(Kind::LEQ, {zero, f_x}),  // 0 <= f(x)
     246                 :          2 :                       d_tm.mkTerm(Kind::LEQ, {zero, f_y}),  // 0 <= f(y)
     247                 :          2 :                       d_tm.mkTerm(Kind::LEQ, {sum, one}),   // f(x) + f(y) <= 1
     248                 :            :                       p_0.notTerm(),                        // not p(0)
     249                 :            :                       p_f_y                                 // p(f(y))
     250                 :          5 :                   });
     251                 :            : 
     252 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->checkSatAssuming(d_tm.mkTrue()));
         [ +  - ][ -  - ]
     253                 :          1 :   d_solver->assertFormula(assertions);
     254                 :          3 :   ASSERT_NO_THROW(
     255         [ +  - ]:          1 :       d_solver->checkSatAssuming(d_tm.mkTerm(Kind::DISTINCT, {x, y})));
     256                 :          5 :   ASSERT_NO_THROW(d_solver->checkSatAssuming(
     257         [ +  - ]:          1 :       {d_tm.mkFalse(), d_tm.mkTerm(Kind::DISTINCT, {x, y})}));
     258                 :          1 :   ASSERT_THROW(d_solver->checkSatAssuming(n), CVC5ApiException);
     259                 :         11 :   ASSERT_THROW(
     260                 :            :       d_solver->checkSatAssuming({n, d_tm.mkTerm(Kind::DISTINCT, {x, y})}),
     261         [ +  - ]:          1 :       CVC5ApiException);
     262 [ +  - ][ +  - ]:          1 : }
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
     263                 :            : 
     264                 :          4 : TEST_F(TestApiBlackSolver, declareFunFresh)
     265                 :            : {
     266                 :          2 :   Term t1 = d_solver->declareFun(std::string("b"), {}, d_bool, true);
     267                 :          2 :   Term t2 = d_solver->declareFun(std::string("b"), {}, d_bool, false);
     268                 :          2 :   Term t3 = d_solver->declareFun(std::string("b"), {}, d_bool, false);
     269 [ -  + ][ +  - ]:          1 :   ASSERT_FALSE(t1 == t2);
     270 [ -  + ][ +  - ]:          1 :   ASSERT_FALSE(t1 == t3);
     271 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(t2 == t3);
     272                 :          2 :   Term t4 = d_solver->declareFun(std::string("c"), {}, d_bool, false);
     273 [ -  + ][ +  - ]:          1 :   ASSERT_FALSE(t2 == t4);
     274                 :          2 :   Term t5 = d_solver->declareFun(std::string("b"), {}, d_int, false);
     275 [ -  + ][ +  - ]:          1 :   ASSERT_FALSE(t2 == t5);
     276                 :            : 
     277                 :          1 :   TermManager tm;
     278                 :          1 :   Solver slv(tm);
     279                 :          4 :   ASSERT_THROW(slv.declareFun(std::string("b"), {}, d_int, false),
     280         [ +  - ]:          1 :                CVC5ApiException);
     281 [ +  - ][ +  - ]:          1 : }
                 [ +  - ]
     282                 :            : 
     283                 :          4 : TEST_F(TestApiBlackSolver, declareDatatype)
     284                 :            : {
     285                 :          2 :   DatatypeConstructorDecl lin = d_tm.mkDatatypeConstructorDecl("lin");
     286                 :          3 :   std::vector<DatatypeConstructorDecl> ctors0 = {lin};
     287 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->declareDatatype(std::string(""), ctors0));
         [ +  - ][ -  - ]
     288                 :            : 
     289                 :          2 :   DatatypeConstructorDecl nil = d_tm.mkDatatypeConstructorDecl("nil");
     290                 :          3 :   std::vector<DatatypeConstructorDecl> ctors1 = {nil};
     291 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->declareDatatype(std::string("a"), ctors1));
         [ +  - ][ -  - ]
     292                 :            : 
     293                 :          2 :   DatatypeConstructorDecl cons = d_tm.mkDatatypeConstructorDecl("cons");
     294                 :          2 :   DatatypeConstructorDecl nil2 = d_tm.mkDatatypeConstructorDecl("nil");
     295                 :          4 :   std::vector<DatatypeConstructorDecl> ctors2 = {cons, nil2};
     296 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->declareDatatype(std::string("b"), ctors2));
         [ +  - ][ -  - ]
     297                 :            : 
     298                 :          2 :   DatatypeConstructorDecl cons2 = d_tm.mkDatatypeConstructorDecl("cons");
     299                 :          2 :   DatatypeConstructorDecl nil3 = d_tm.mkDatatypeConstructorDecl("nil");
     300                 :          4 :   std::vector<DatatypeConstructorDecl> ctors3 = {cons2, nil3};
     301 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->declareDatatype(std::string(""), ctors3));
         [ +  - ][ -  - ]
     302                 :            : 
     303                 :            :   // must have at least one constructor
     304                 :          1 :   std::vector<DatatypeConstructorDecl> ctors4;
     305                 :          3 :   ASSERT_THROW(d_solver->declareDatatype(std::string("c"), ctors4),
     306         [ +  - ]:          1 :                CVC5ApiException);
     307                 :            :   // constructors may not be reused
     308                 :          2 :   DatatypeConstructorDecl ctor1 = d_tm.mkDatatypeConstructorDecl("_x21");
     309                 :          2 :   DatatypeConstructorDecl ctor2 = d_tm.mkDatatypeConstructorDecl("_x31");
     310 [ +  + ][ -  - ]:          3 :   d_solver->declareDatatype(std::string("_x17"), {ctor1, ctor2});
     311                 :          8 :   ASSERT_THROW(d_solver->declareDatatype(std::string("_x86"), {ctor1, ctor2}),
     312         [ +  - ]:          1 :                CVC5ApiException);
     313                 :            : 
     314                 :          1 :   TermManager tm;
     315                 :          1 :   Solver slv(tm);
     316                 :          2 :   DatatypeConstructorDecl nnil = d_tm.mkDatatypeConstructorDecl("nil");
     317                 :          7 :   ASSERT_THROW(slv.declareDatatype(std::string("a"), {nnil}), CVC5ApiException);
     318 [ +  - ][ +  - ]:          1 : }
     319                 :            : 
     320                 :          4 : TEST_F(TestApiBlackSolver, declareFun)
     321                 :            : {
     322                 :          1 :   Sort bvSort = d_tm.mkBitVectorSort(32);
     323                 :          3 :   Sort funSort = d_tm.mkFunctionSort({d_uninterpreted}, d_int);
     324 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->declareFun("f1", {}, bvSort));
         [ +  - ][ -  - ]
     325                 :          3 :   ASSERT_NO_THROW(d_solver->declareFun("f3", {bvSort, d_int}, bvSort));
     326                 :          4 :   ASSERT_THROW(d_solver->declareFun("f2", {}, funSort), CVC5ApiException);
     327                 :            :   // functions as arguments is allowed
     328                 :          3 :   ASSERT_NO_THROW(d_solver->declareFun("f4", {bvSort, funSort}, bvSort));
     329                 :          8 :   ASSERT_THROW(d_solver->declareFun("f5", {bvSort, bvSort}, funSort),
     330         [ +  - ]:          1 :                CVC5ApiException);
     331                 :            : 
     332                 :          1 :   TermManager tm;
     333                 :          1 :   Solver slv(tm);
     334                 :          4 :   ASSERT_THROW(slv.declareFun("f1", {}, bvSort), CVC5ApiException);
     335 [ +  - ][ +  - ]:          1 : }
     336                 :            : 
     337                 :          4 : TEST_F(TestApiBlackSolver, declareSort)
     338                 :            : {
     339 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->declareSort("s", 0));
         [ +  - ][ -  - ]
     340 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->declareSort("s", 2));
         [ +  - ][ -  - ]
     341 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->declareSort("", 2));
         [ +  - ][ -  - ]
     342                 :            : }
     343                 :            : 
     344                 :          4 : TEST_F(TestApiBlackSolver, declareSortFresh)
     345                 :            : {
     346                 :          2 :   Sort t1 = d_solver->declareSort(std::string("b"), 0, true);
     347                 :          2 :   Sort t2 = d_solver->declareSort(std::string("b"), 0, false);
     348                 :          2 :   Sort t3 = d_solver->declareSort(std::string("b"), 0, false);
     349 [ -  + ][ +  - ]:          1 :   ASSERT_FALSE(t1 == t2);
     350 [ -  + ][ +  - ]:          1 :   ASSERT_FALSE(t1 == t3);
     351 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(t2 == t3);
     352                 :          2 :   Sort t4 = d_solver->declareSort(std::string("c"), 0, false);
     353 [ -  + ][ +  - ]:          1 :   ASSERT_FALSE(t2 == t4);
     354                 :          2 :   Sort t5 = d_solver->declareSort(std::string("b"), 1, false);
     355 [ -  + ][ +  - ]:          1 :   ASSERT_FALSE(t2 == t5);
     356 [ +  - ][ +  - ]:          1 : }
                 [ +  - ]
     357                 :            : 
     358                 :          4 : TEST_F(TestApiBlackSolver, defineFun)
     359                 :            : {
     360                 :          1 :   Sort bvSort = d_tm.mkBitVectorSort(32);
     361                 :          3 :   Sort funSort = d_tm.mkFunctionSort({d_uninterpreted}, d_int);
     362                 :          1 :   Term b1 = d_tm.mkVar(bvSort, "b1");
     363                 :          1 :   Term b2 = d_tm.mkVar(d_int, "b2");
     364                 :          1 :   Term b3 = d_tm.mkVar(funSort, "b3");
     365                 :          1 :   Term v1 = d_tm.mkConst(bvSort, "v1");
     366                 :          1 :   Term v2 = d_tm.mkConst(funSort, "v2");
     367 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->defineFun("f", {}, bvSort, v1));
         [ +  - ][ -  - ]
     368                 :          3 :   ASSERT_NO_THROW(d_solver->defineFun("ff", {b1, b2}, bvSort, v1));
     369                 :          8 :   ASSERT_THROW(d_solver->defineFun("ff", {v1, b2}, bvSort, v1),
     370         [ +  - ]:          1 :                CVC5ApiException);
     371                 :          7 :   ASSERT_THROW(d_solver->defineFun("fff", {b1}, bvSort, v2), CVC5ApiException);
     372                 :          7 :   ASSERT_THROW(d_solver->defineFun("ffff", {b1}, funSort, v2),
     373         [ +  - ]:          1 :                CVC5ApiException);
     374                 :            :   // b3 has function sort, which is allowed as an argument
     375                 :          3 :   ASSERT_NO_THROW(d_solver->defineFun("fffff", {b1, b3}, bvSort, v1));
     376                 :            : 
     377                 :          1 :   TermManager tm;
     378                 :          1 :   Solver slv(tm);
     379                 :          1 :   Sort bvSort2 = tm.mkBitVectorSort(32);
     380                 :          1 :   Term v12 = tm.mkConst(bvSort2, "v1");
     381                 :          1 :   Term b12 = tm.mkVar(bvSort2, "b1");
     382                 :          2 :   Term b22 = tm.mkVar(tm.getIntegerSort(), "b2");
     383                 :          4 :   ASSERT_THROW(slv.defineFun("f", {}, bvSort, v12), CVC5ApiException);
     384                 :          4 :   ASSERT_THROW(slv.defineFun("f", {}, bvSort2, v1), CVC5ApiException);
     385                 :          8 :   ASSERT_THROW(slv.defineFun("ff", {b1, b22}, bvSort2, v12), CVC5ApiException);
     386                 :          8 :   ASSERT_THROW(slv.defineFun("ff", {b12, b2}, bvSort2, v12), CVC5ApiException);
     387                 :          8 :   ASSERT_THROW(slv.defineFun("ff", {b12, b22}, bvSort, v12), CVC5ApiException);
     388                 :          8 :   ASSERT_THROW(slv.defineFun("ff", {b12, b22}, bvSort2, v1), CVC5ApiException);
     389 [ +  - ][ +  - ]:          1 : }
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
     390                 :            : 
     391                 :          4 : TEST_F(TestApiBlackSolver, defineFunGlobal)
     392                 :            : {
     393                 :          1 :   Term bTrue = d_tm.mkBoolean(true);
     394                 :            :   // (define-fun f () Bool true)
     395                 :          2 :   Term f = d_solver->defineFun("f", {}, d_bool, bTrue, true);
     396                 :          1 :   Term b = d_tm.mkVar(d_bool, "b");
     397                 :            :   // (define-fun g (b Bool) Bool b)
     398                 :          3 :   Term g = d_solver->defineFun("g", {b}, d_bool, b, true);
     399                 :            : 
     400                 :            :   // (assert (or (not f) (not (g true))))
     401 [ +  + ][ -  - ]:          4 :   d_solver->assertFormula(d_tm.mkTerm(
     402                 :            :       Kind::OR,
     403 [ +  + ][ -  - ]:          4 :       {f.notTerm(), d_tm.mkTerm(Kind::APPLY_UF, {g, bTrue}).notTerm()}));
     404 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(d_solver->checkSat().isUnsat());
     405                 :          1 :   d_solver->resetAssertions();
     406                 :            :   // (assert (or (not f) (not (g true))))
     407 [ +  + ][ -  - ]:          4 :   d_solver->assertFormula(d_tm.mkTerm(
     408                 :            :       Kind::OR,
     409 [ +  + ][ -  - ]:          4 :       {f.notTerm(), d_tm.mkTerm(Kind::APPLY_UF, {g, bTrue}).notTerm()}));
     410 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(d_solver->checkSat().isUnsat());
     411                 :            : 
     412                 :          1 :   TermManager tm;
     413                 :          1 :   Solver slv(tm);
     414                 :          4 :   ASSERT_THROW(slv.defineFun("f", {}, d_bool, bTrue, true), CVC5ApiException);
     415 [ +  - ][ +  - ]:          1 : }
         [ +  - ][ +  - ]
     416                 :            : 
     417                 :          4 : TEST_F(TestApiBlackSolver, defineFunRec)
     418                 :            : {
     419                 :          1 :   Sort bvSort = d_tm.mkBitVectorSort(32);
     420                 :          4 :   Sort funSort1 = d_tm.mkFunctionSort({bvSort, bvSort}, bvSort);
     421                 :          3 :   Sort funSort2 = d_tm.mkFunctionSort({d_uninterpreted}, d_int);
     422                 :          1 :   Term b1 = d_tm.mkVar(bvSort, "b1");
     423                 :          1 :   Term b11 = d_tm.mkVar(bvSort, "b1");
     424                 :          1 :   Term b2 = d_tm.mkVar(d_int, "b2");
     425                 :          1 :   Term b3 = d_tm.mkVar(funSort2, "b3");
     426                 :          1 :   Term v1 = d_tm.mkConst(bvSort, "v1");
     427                 :          1 :   Term v2 = d_tm.mkConst(d_int, "v2");
     428                 :          1 :   Term v3 = d_tm.mkConst(funSort2, "v3");
     429                 :          1 :   Term f1 = d_tm.mkConst(funSort1, "f1");
     430                 :          1 :   Term f2 = d_tm.mkConst(funSort2, "f2");
     431                 :          1 :   Term f3 = d_tm.mkConst(bvSort, "f3");
     432 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->defineFunRec("f", {}, bvSort, v1));
         [ +  - ][ -  - ]
     433                 :          3 :   ASSERT_NO_THROW(d_solver->defineFunRec("ff", {b1, b2}, bvSort, v1));
     434                 :          3 :   ASSERT_NO_THROW(d_solver->defineFunRec(f1, {b1, b11}, v1));
     435                 :          7 :   ASSERT_THROW(d_solver->defineFunRec("fff", {b1}, bvSort, v3),
     436         [ +  - ]:          1 :                CVC5ApiException);
     437                 :          8 :   ASSERT_THROW(d_solver->defineFunRec("ff", {b1, v2}, bvSort, v1),
     438         [ +  - ]:          1 :                CVC5ApiException);
     439                 :          7 :   ASSERT_THROW(d_solver->defineFunRec("ffff", {b1}, funSort2, v3),
     440         [ +  - ]:          1 :                CVC5ApiException);
     441                 :            :   // b3 has function sort, which is allowed as an argument
     442                 :          3 :   ASSERT_NO_THROW(d_solver->defineFunRec("fffff", {b1, b3}, bvSort, v1));
     443                 :          5 :   ASSERT_THROW(d_solver->defineFunRec(f1, {b1}, v1), CVC5ApiException);
     444                 :          6 :   ASSERT_THROW(d_solver->defineFunRec(f1, {b1, b11}, v2), CVC5ApiException);
     445                 :          6 :   ASSERT_THROW(d_solver->defineFunRec(f1, {b1, b11}, v3), CVC5ApiException);
     446                 :          5 :   ASSERT_THROW(d_solver->defineFunRec(f2, {b1}, v2), CVC5ApiException);
     447                 :          5 :   ASSERT_THROW(d_solver->defineFunRec(f3, {b1}, v1), CVC5ApiException);
     448                 :            : 
     449                 :          1 :   TermManager tm;
     450                 :          1 :   Solver slv(tm);
     451                 :          1 :   Sort bvSort2 = tm.mkBitVectorSort(32);
     452                 :          1 :   Term v12 = tm.mkConst(bvSort2, "v1");
     453                 :          1 :   Term b12 = tm.mkVar(bvSort2, "b1");
     454                 :          2 :   Term b22 = tm.mkVar(tm.getIntegerSort(), "b2");
     455 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(slv.defineFunRec("f", {}, bvSort2, v12));
         [ +  - ][ -  - ]
     456                 :          3 :   ASSERT_NO_THROW(slv.defineFunRec("ff", {b12, b22}, bvSort2, v12));
     457                 :          4 :   ASSERT_THROW(slv.defineFunRec("f", {}, bvSort, v12), CVC5ApiException);
     458                 :          4 :   ASSERT_THROW(slv.defineFunRec("f", {}, bvSort2, v1), CVC5ApiException);
     459                 :          8 :   ASSERT_THROW(slv.defineFunRec("ff", {b1, b22}, bvSort2, v12),
     460         [ +  - ]:          1 :                CVC5ApiException);
     461                 :          8 :   ASSERT_THROW(slv.defineFunRec("ff", {b12, b2}, bvSort2, v12),
     462         [ +  - ]:          1 :                CVC5ApiException);
     463                 :          8 :   ASSERT_THROW(slv.defineFunRec("ff", {b12, b22}, bvSort, v12),
     464         [ +  - ]:          1 :                CVC5ApiException);
     465                 :          8 :   ASSERT_THROW(slv.defineFunRec("ff", {b12, b22}, bvSort2, v1),
     466         [ +  - ]:          1 :                CVC5ApiException);
     467 [ +  - ][ +  - ]:          1 : }
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
     468                 :            : 
     469                 :          4 : TEST_F(TestApiBlackSolver, defineFunRecWrongLogic)
     470                 :            : {
     471                 :          1 :   d_solver->setLogic("QF_BV");
     472                 :          1 :   Sort bvSort = d_tm.mkBitVectorSort(32);
     473                 :          4 :   Sort funSort = d_tm.mkFunctionSort({bvSort, bvSort}, bvSort);
     474                 :          1 :   Term b = d_tm.mkVar(bvSort, "b");
     475                 :          1 :   Term v = d_tm.mkConst(bvSort, "v");
     476                 :          1 :   Term f = d_tm.mkConst(funSort, "f");
     477                 :          4 :   ASSERT_THROW(d_solver->defineFunRec("f", {}, bvSort, v), CVC5ApiException);
     478                 :          6 :   ASSERT_THROW(d_solver->defineFunRec(f, {b, b}, v), CVC5ApiException);
     479 [ +  - ][ +  - ]:          1 : }
         [ +  - ][ +  - ]
                 [ +  - ]
     480                 :            : 
     481                 :          4 : TEST_F(TestApiBlackSolver, defineFunRecGlobal)
     482                 :            : {
     483                 :          1 :   d_solver->push();
     484                 :          1 :   Term bTrue = d_tm.mkBoolean(true);
     485                 :            :   // (define-fun f () Bool true)
     486                 :          2 :   Term f = d_solver->defineFunRec("f", {}, d_bool, bTrue, true);
     487                 :          1 :   Term b = d_tm.mkVar(d_bool, "b");
     488                 :            :   // (define-fun g (b Bool) Bool b)
     489                 :          1 :   Term g = d_solver->defineFunRec(
     490                 :          4 :       d_tm.mkConst(d_tm.mkFunctionSort({d_bool}, d_bool), "g"), {b}, b, true);
     491                 :            : 
     492                 :            :   // (assert (or (not f) (not (g true))))
     493 [ +  + ][ -  - ]:          4 :   d_solver->assertFormula(d_tm.mkTerm(
     494                 :            :       Kind::OR,
     495 [ +  + ][ -  - ]:          4 :       {f.notTerm(), d_tm.mkTerm(Kind::APPLY_UF, {g, bTrue}).notTerm()}));
     496 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(d_solver->checkSat().isUnsat());
     497                 :          1 :   d_solver->pop();
     498                 :            :   // (assert (or (not f) (not (g true))))
     499 [ +  + ][ -  - ]:          4 :   d_solver->assertFormula(d_tm.mkTerm(
     500                 :            :       Kind::OR,
     501 [ +  + ][ -  - ]:          4 :       {f.notTerm(), d_tm.mkTerm(Kind::APPLY_UF, {g, bTrue}).notTerm()}));
     502 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(d_solver->checkSat().isUnsat());
     503                 :            : 
     504                 :          1 :   TermManager tm;
     505                 :          1 :   Solver slv(tm);
     506                 :          2 :   Term bb = tm.mkVar(tm.getBooleanSort(), "b");
     507                 :         12 :   ASSERT_THROW(
     508                 :            :       slv.defineFunRec(d_tm.mkConst(d_tm.mkFunctionSort({d_bool}, d_bool), "g"),
     509                 :            :                        {bb},
     510                 :            :                        bb,
     511                 :            :                        true),
     512         [ +  - ]:          1 :       CVC5ApiException);
     513                 :         10 :   ASSERT_THROW(
     514                 :            :       slv.defineFunRec(
     515                 :            :           tm.mkConst(tm.mkFunctionSort({d_bool}, d_bool), "g"), {b}, b, true),
     516         [ +  - ]:          1 :       CVC5ApiException);
     517 [ +  - ][ +  - ]:          1 : }
         [ +  - ][ +  - ]
     518                 :            : 
     519                 :          4 : TEST_F(TestApiBlackSolver, defineFunsRec)
     520                 :            : {
     521                 :          1 :   Sort bvSort = d_tm.mkBitVectorSort(32);
     522                 :          4 :   Sort funSort1 = d_tm.mkFunctionSort({bvSort, bvSort}, bvSort);
     523                 :          3 :   Sort funSort2 = d_tm.mkFunctionSort({d_uninterpreted}, d_int);
     524                 :          1 :   Term b1 = d_tm.mkVar(bvSort, "b1");
     525                 :          1 :   Term b11 = d_tm.mkVar(bvSort, "b1");
     526                 :          1 :   Term b2 = d_tm.mkVar(d_int, "b2");
     527                 :          1 :   Term b4 = d_tm.mkVar(d_uninterpreted, "b4");
     528                 :          1 :   Term v1 = d_tm.mkConst(bvSort, "v1");
     529                 :          1 :   Term v2 = d_tm.mkConst(d_int, "v2");
     530                 :          1 :   Term v4 = d_tm.mkConst(d_uninterpreted, "v4");
     531                 :          1 :   Term f1 = d_tm.mkConst(funSort1, "f1");
     532                 :          1 :   Term f2 = d_tm.mkConst(funSort2, "f2");
     533                 :          1 :   Term f3 = d_tm.mkConst(bvSort, "f3");
     534                 :         10 :   ASSERT_NO_THROW(
     535         [ +  - ]:          1 :       d_solver->defineFunsRec({f1, f2}, {{b1, b11}, {b4}}, {v1, v2}));
     536                 :         23 :   ASSERT_THROW(d_solver->defineFunsRec({f1, f2}, {{v1, b11}, {b4}}, {v1, v2}),
     537         [ +  - ]:          1 :                CVC5ApiException);
     538                 :         23 :   ASSERT_THROW(d_solver->defineFunsRec({f1, f3}, {{b1, b11}, {b4}}, {v1, v2}),
     539         [ +  - ]:          1 :                CVC5ApiException);
     540                 :         22 :   ASSERT_THROW(d_solver->defineFunsRec({f1, f2}, {{b1}, {b4}}, {v1, v2}),
     541         [ +  - ]:          1 :                CVC5ApiException);
     542                 :         23 :   ASSERT_THROW(d_solver->defineFunsRec({f1, f2}, {{b1, b2}, {b4}}, {v1, v2}),
     543         [ +  - ]:          1 :                CVC5ApiException);
     544                 :         23 :   ASSERT_THROW(d_solver->defineFunsRec({f1, f2}, {{b1, b11}, {b4}}, {v1, v4}),
     545         [ +  - ]:          1 :                CVC5ApiException);
     546                 :            : 
     547                 :          1 :   TermManager tm;
     548                 :          1 :   Solver slv(tm);
     549                 :          1 :   Sort uSort2 = tm.mkUninterpretedSort("u");
     550                 :          1 :   Sort bvSort2 = tm.mkBitVectorSort(32);
     551                 :          4 :   Sort funSort12 = tm.mkFunctionSort({bvSort2, bvSort2}, bvSort2);
     552                 :          4 :   Sort funSort22 = tm.mkFunctionSort({uSort2}, tm.getIntegerSort());
     553                 :          1 :   Term b12 = tm.mkVar(bvSort2, "b1");
     554                 :          1 :   Term b112 = tm.mkVar(bvSort2, "b1");
     555                 :          1 :   Term b42 = tm.mkVar(uSort2, "b4");
     556                 :          1 :   Term v12 = tm.mkConst(bvSort2, "v1");
     557                 :          2 :   Term v22 = tm.mkConst(tm.getIntegerSort(), "v2");
     558                 :          1 :   Term f12 = tm.mkConst(funSort12, "f1");
     559                 :          1 :   Term f22 = tm.mkConst(funSort22, "f2");
     560                 :         10 :   ASSERT_NO_THROW(
     561         [ +  - ]:          1 :       slv.defineFunsRec({f12, f22}, {{b12, b112}, {b42}}, {v12, v22}));
     562                 :         23 :   ASSERT_THROW(slv.defineFunsRec({f1, f22}, {{b12, b112}, {b42}}, {v12, v22}),
     563         [ +  - ]:          1 :                CVC5ApiException);
     564                 :         23 :   ASSERT_THROW(slv.defineFunsRec({f12, f2}, {{b12, b112}, {b42}}, {v12, v22}),
     565         [ +  - ]:          1 :                CVC5ApiException);
     566                 :         23 :   ASSERT_THROW(slv.defineFunsRec({f12, f22}, {{b1, b112}, {b42}}, {v12, v22}),
     567         [ +  - ]:          1 :                CVC5ApiException);
     568                 :         23 :   ASSERT_THROW(slv.defineFunsRec({f12, f22}, {{b12, b11}, {b42}}, {v12, v22}),
     569         [ +  - ]:          1 :                CVC5ApiException);
     570                 :         23 :   ASSERT_THROW(slv.defineFunsRec({f12, f22}, {{b12, b112}, {b4}}, {v12, v22}),
     571         [ +  - ]:          1 :                CVC5ApiException);
     572                 :         23 :   ASSERT_THROW(slv.defineFunsRec({f12, f22}, {{b12, b112}, {b42}}, {v1, v22}),
     573         [ +  - ]:          1 :                CVC5ApiException);
     574                 :         23 :   ASSERT_THROW(slv.defineFunsRec({f12, f22}, {{b12, b112}, {b42}}, {v12, v2}),
     575         [ +  - ]:          1 :                CVC5ApiException);
     576 [ +  - ][ +  - ]:          1 : }
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
     577                 :            : 
     578                 :          4 : TEST_F(TestApiBlackSolver, defineFunsRecWrongLogic)
     579                 :            : {
     580                 :          1 :   d_solver->setLogic("QF_BV");
     581                 :          1 :   Sort bvSort = d_tm.mkBitVectorSort(32);
     582                 :          4 :   Sort funSort1 = d_tm.mkFunctionSort({bvSort, bvSort}, bvSort);
     583                 :          3 :   Sort funSort2 = d_tm.mkFunctionSort({d_uninterpreted}, d_int);
     584                 :          1 :   Term b = d_tm.mkVar(bvSort, "b");
     585                 :          1 :   Term u = d_tm.mkVar(d_uninterpreted, "u");
     586                 :          1 :   Term v1 = d_tm.mkConst(bvSort, "v1");
     587                 :          1 :   Term v2 = d_tm.mkConst(d_int, "v2");
     588                 :          1 :   Term f1 = d_tm.mkConst(funSort1, "f1");
     589                 :          1 :   Term f2 = d_tm.mkConst(funSort2, "f2");
     590                 :         23 :   ASSERT_THROW(d_solver->defineFunsRec({f1, f2}, {{b, b}, {u}}, {v1, v2}),
     591         [ +  - ]:          1 :                CVC5ApiException);
     592 [ +  - ][ +  - ]:          1 : }
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
     593                 :            : 
     594                 :          4 : TEST_F(TestApiBlackSolver, defineFunsRecGlobal)
     595                 :            : {
     596                 :          3 :   Sort fSort = d_tm.mkFunctionSort({d_bool}, d_bool);
     597                 :            : 
     598                 :          1 :   d_solver->push();
     599                 :          1 :   Term bTrue = d_tm.mkBoolean(true);
     600                 :          1 :   Term b = d_tm.mkVar(d_bool, "b");
     601                 :          1 :   Term gSym = d_tm.mkConst(fSort, "g");
     602                 :            :   // (define-funs-rec ((g ((b Bool)) Bool)) (b))
     603                 :          5 :   d_solver->defineFunsRec({gSym}, {{b}}, {b}, true);
     604                 :            : 
     605                 :            :   // (assert (not (g true)))
     606 [ +  + ][ -  - ]:          3 :   d_solver->assertFormula(d_tm.mkTerm(Kind::APPLY_UF, {gSym, bTrue}).notTerm());
     607 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(d_solver->checkSat().isUnsat());
     608                 :          1 :   d_solver->pop();
     609                 :            :   // (assert (not (g true)))
     610 [ +  + ][ -  - ]:          3 :   d_solver->assertFormula(d_tm.mkTerm(Kind::APPLY_UF, {gSym, bTrue}).notTerm());
     611 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(d_solver->checkSat().isUnsat());
     612 [ +  - ][ +  - ]:          1 : }
         [ +  - ][ +  - ]
     613                 :            : 
     614                 :          4 : TEST_F(TestApiBlackSolver, getAssertions)
     615                 :            : {
     616                 :          1 :   Term a = d_tm.mkConst(d_bool, "a");
     617                 :          1 :   Term b = d_tm.mkConst(d_bool, "b");
     618                 :          1 :   d_solver->assertFormula(a);
     619                 :          1 :   d_solver->assertFormula(b);
     620                 :          4 :   std::vector<Term> asserts{a, b};
     621 [ -  + ][ +  - ]:          2 :   ASSERT_EQ(d_solver->getAssertions(), asserts);
     622 [ +  - ][ +  - ]:          1 : }
                 [ +  - ]
     623                 :            : 
     624                 :          4 : TEST_F(TestApiBlackSolver, getInfo)
     625                 :            : {
     626 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->getInfo("name"));
         [ +  - ][ -  - ]
     627                 :          3 :   ASSERT_THROW(d_solver->getInfo("asdf"), CVC5ApiException);
     628                 :            : }
     629                 :            : 
     630                 :          4 : TEST_F(TestApiBlackSolver, getOption)
     631                 :            : {
     632 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->getOption("incremental"));
         [ +  - ][ -  - ]
     633                 :          3 :   ASSERT_THROW(d_solver->getOption("asdf"), CVC5ApiException);
     634                 :            : }
     635                 :            : 
     636                 :          4 : TEST_F(TestApiBlackSolver, getOptionNames)
     637                 :            : {
     638                 :          1 :   std::vector<std::string> names = d_solver->getOptionNames();
     639 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(names.size() > 100);
     640 [ -  + ][ +  - ]:          1 :   ASSERT_NE(std::find(names.begin(), names.end(), "verbose"), names.end());
     641 [ -  + ][ +  - ]:          1 :   ASSERT_EQ(std::find(names.begin(), names.end(), "foobar"), names.end());
     642         [ +  - ]:          1 : }
     643                 :            : 
     644                 :          4 : TEST_F(TestApiBlackSolver, getOptionInfo)
     645                 :            : {
     646                 :          1 :   d_solver->setOption("verbosity", "2");
     647                 :            : 
     648                 :            :   {
     649                 :          3 :     ASSERT_THROW(d_solver->getOptionInfo("asdf-invalid"), CVC5ApiException);
     650                 :            :   }
     651                 :            :   {
     652                 :          2 :     cvc5::OptionInfo info = d_solver->getOptionInfo("verbose");
     653 [ -  + ][ +  - ]:          1 :     ASSERT_EQ("verbose", info.name);
     654 [ -  + ][ +  - ]:          2 :     ASSERT_EQ(std::vector<std::string>{}, info.aliases);
     655 [ -  + ][ +  - ]:          1 :     ASSERT_EQ(info.category, cvc5::modes::OptionCategory::COMMON);
     656 [ -  + ][ +  - ]:          1 :     ASSERT_FALSE(info.setByUser);
     657 [ -  + ][ +  - ]:          1 :     ASSERT_TRUE(std::holds_alternative<OptionInfo::VoidInfo>(info.valueInfo));
     658                 :          1 :     std::stringstream ss;
     659                 :          1 :     ss << info;
     660 [ -  + ][ +  - ]:          2 :     ASSERT_EQ(ss.str(), "OptionInfo{ verbose | void }");
     661         [ +  - ]:          1 :   }
     662                 :            :   {
     663                 :            :     // bool type with default
     664                 :          2 :     cvc5::OptionInfo info = d_solver->getOptionInfo("print-success");
     665 [ -  + ][ +  - ]:          1 :     ASSERT_EQ("print-success", info.name);
     666 [ -  + ][ +  - ]:          2 :     ASSERT_EQ(std::vector<std::string>{}, info.aliases);
     667 [ -  + ][ +  - ]:          1 :     ASSERT_EQ(info.category, cvc5::modes::OptionCategory::COMMON);
     668 [ -  + ][ +  - ]:          1 :     ASSERT_FALSE(info.setByUser);
     669         [ -  + ]:          1 :     ASSERT_TRUE(
     670         [ +  - ]:          1 :         std::holds_alternative<OptionInfo::ValueInfo<bool>>(info.valueInfo));
     671                 :          1 :     auto valInfo = std::get<OptionInfo::ValueInfo<bool>>(info.valueInfo);
     672 [ -  + ][ +  - ]:          1 :     ASSERT_EQ(false, valInfo.defaultValue);
     673 [ -  + ][ +  - ]:          1 :     ASSERT_EQ(false, valInfo.currentValue);
     674 [ -  + ][ +  - ]:          1 :     ASSERT_EQ(info.boolValue(), false);
     675                 :          1 :     std::stringstream ss;
     676                 :          1 :     ss << info;
     677         [ -  + ]:          2 :     ASSERT_EQ(ss.str(),
     678         [ +  - ]:          1 :               "OptionInfo{ print-success | bool | false | default false }");
     679         [ +  - ]:          1 :   }
     680                 :            :   {
     681                 :            :     // int64 type with default
     682                 :          2 :     cvc5::OptionInfo info = d_solver->getOptionInfo("verbosity");
     683 [ -  + ][ +  - ]:          1 :     ASSERT_EQ("verbosity", info.name);
     684 [ -  + ][ +  - ]:          2 :     ASSERT_EQ(std::vector<std::string>{}, info.aliases);
     685 [ -  + ][ +  - ]:          1 :     ASSERT_EQ(info.category, cvc5::modes::OptionCategory::COMMON);
     686 [ -  + ][ +  - ]:          1 :     ASSERT_TRUE(info.setByUser);
     687         [ -  + ]:          1 :     ASSERT_TRUE(std::holds_alternative<OptionInfo::NumberInfo<int64_t>>(
     688         [ +  - ]:          1 :         info.valueInfo));
     689                 :          1 :     auto numInfo = std::get<OptionInfo::NumberInfo<int64_t>>(info.valueInfo);
     690 [ -  + ][ +  - ]:          1 :     ASSERT_EQ(0, numInfo.defaultValue);
     691 [ -  + ][ +  - ]:          1 :     ASSERT_EQ(2, numInfo.currentValue);
     692 [ +  - ][ +  - ]:          1 :     ASSERT_FALSE(numInfo.minimum || numInfo.maximum);
         [ -  + ][ +  - ]
     693 [ -  + ][ +  - ]:          1 :     ASSERT_EQ(info.intValue(), 2);
     694                 :          1 :     std::stringstream ss;
     695                 :          1 :     ss << info;
     696         [ -  + ]:          2 :     ASSERT_EQ(
     697                 :            :         ss.str(),
     698         [ +  - ]:          1 :         "OptionInfo{ verbosity | set by user | int64_t | 2 | default 0 }");
     699         [ +  - ]:          1 :   }
     700                 :            :   {
     701                 :            :     // uint64 type with default
     702                 :          2 :     cvc5::OptionInfo info = d_solver->getOptionInfo("rlimit");
     703 [ -  + ][ +  - ]:          1 :     ASSERT_EQ("rlimit", info.name);
     704 [ -  + ][ +  - ]:          2 :     ASSERT_EQ(std::vector<std::string>{}, info.aliases);
     705 [ -  + ][ +  - ]:          1 :     ASSERT_EQ(info.category, cvc5::modes::OptionCategory::COMMON);
     706 [ -  + ][ +  - ]:          1 :     ASSERT_FALSE(info.setByUser);
     707         [ -  + ]:          1 :     ASSERT_TRUE(std::holds_alternative<OptionInfo::NumberInfo<uint64_t>>(
     708         [ +  - ]:          1 :         info.valueInfo));
     709                 :          1 :     auto numInfo = std::get<OptionInfo::NumberInfo<uint64_t>>(info.valueInfo);
     710 [ -  + ][ +  - ]:          1 :     ASSERT_EQ(0, numInfo.defaultValue);
     711 [ -  + ][ +  - ]:          1 :     ASSERT_EQ(0, numInfo.currentValue);
     712 [ +  - ][ +  - ]:          1 :     ASSERT_FALSE(numInfo.minimum || numInfo.maximum);
         [ -  + ][ +  - ]
     713 [ -  + ][ +  - ]:          1 :     ASSERT_EQ(info.uintValue(), 0);
     714                 :          1 :     std::stringstream ss;
     715                 :          1 :     ss << info;
     716 [ -  + ][ +  - ]:          2 :     ASSERT_EQ(ss.str(), "OptionInfo{ rlimit | uint64_t | 0 | default 0 }");
     717         [ +  - ]:          1 :   }
     718                 :            :   // string type
     719                 :            :   {
     720                 :          2 :     auto info = d_solver->getOptionInfo("random-freq");
     721 [ -  + ][ +  - ]:          1 :     ASSERT_EQ(info.name, "random-freq");
     722 [ -  + ][ +  - ]:          4 :     ASSERT_EQ(info.aliases, std::vector<std::string>{"random-frequency"});
     723 [ -  + ][ +  - ]:          1 :     ASSERT_EQ(info.category, cvc5::modes::OptionCategory::EXPERT);
     724 [ -  + ][ +  - ]:          1 :     ASSERT_FALSE(info.setByUser);
     725         [ -  + ]:          1 :     ASSERT_TRUE(std::holds_alternative<cvc5::OptionInfo::NumberInfo<double>>(
     726         [ +  - ]:          1 :         info.valueInfo));
     727                 :          1 :     auto ni = std::get<cvc5::OptionInfo::NumberInfo<double>>(info.valueInfo);
     728 [ -  + ][ +  - ]:          1 :     ASSERT_EQ(ni.currentValue, 0.0);
     729 [ -  + ][ +  - ]:          1 :     ASSERT_EQ(ni.defaultValue, 0.0);
     730 [ +  - ][ +  - ]:          1 :     ASSERT_TRUE(ni.minimum && ni.maximum);
         [ -  + ][ +  - ]
     731 [ -  + ][ +  - ]:          1 :     ASSERT_EQ(*ni.minimum, 0.0);
     732 [ -  + ][ +  - ]:          1 :     ASSERT_EQ(*ni.maximum, 1.0);
     733 [ -  + ][ +  - ]:          1 :     ASSERT_EQ(info.doubleValue(), 0.0);
     734                 :          1 :     std::stringstream ss;
     735                 :          1 :     ss << info;
     736         [ -  + ]:          2 :     ASSERT_EQ(ss.str(),
     737                 :            :               "OptionInfo{ random-freq, random-frequency | double | 0 | "
     738         [ +  - ]:          1 :               "default 0 | 0 <= x <= 1 }");
     739         [ +  - ]:          1 :   }
     740                 :            :   {
     741                 :            :     // string type with default
     742                 :          2 :     cvc5::OptionInfo info = d_solver->getOptionInfo("force-logic");
     743 [ -  + ][ +  - ]:          1 :     ASSERT_EQ("force-logic", info.name);
     744 [ -  + ][ +  - ]:          2 :     ASSERT_EQ(std::vector<std::string>{}, info.aliases);
     745 [ -  + ][ +  - ]:          1 :     ASSERT_EQ(info.category, cvc5::modes::OptionCategory::COMMON);
     746 [ -  + ][ +  - ]:          1 :     ASSERT_FALSE(info.setByUser);
     747         [ -  + ]:          1 :     ASSERT_TRUE(std::holds_alternative<OptionInfo::ValueInfo<std::string>>(
     748         [ +  - ]:          1 :         info.valueInfo));
     749                 :          1 :     auto valInfo = std::get<OptionInfo::ValueInfo<std::string>>(info.valueInfo);
     750 [ -  + ][ +  - ]:          1 :     ASSERT_EQ("", valInfo.defaultValue);
     751 [ -  + ][ +  - ]:          1 :     ASSERT_EQ("", valInfo.currentValue);
     752 [ -  + ][ +  - ]:          2 :     ASSERT_EQ(info.stringValue(), "");
     753                 :          1 :     std::stringstream ss;
     754                 :          1 :     ss << info;
     755         [ -  + ]:          2 :     ASSERT_EQ(ss.str(),
     756         [ +  - ]:          1 :               "OptionInfo{ force-logic | string | \"\" | default \"\" }");
     757 [ +  - ][ +  - ]:          1 :   }
     758                 :            :   {
     759                 :            :     // mode option
     760                 :          2 :     cvc5::OptionInfo info = d_solver->getOptionInfo("simplification");
     761 [ -  + ][ +  - ]:          1 :     ASSERT_EQ("simplification", info.name);
     762 [ -  + ][ +  - ]:          4 :     ASSERT_EQ(std::vector<std::string>{"simplification-mode"}, info.aliases);
     763 [ -  + ][ +  - ]:          1 :     ASSERT_EQ(info.category, cvc5::modes::OptionCategory::REGULAR);
     764 [ -  + ][ +  - ]:          1 :     ASSERT_FALSE(info.setByUser);
     765 [ -  + ][ +  - ]:          1 :     ASSERT_TRUE(std::holds_alternative<OptionInfo::ModeInfo>(info.valueInfo));
     766                 :          1 :     auto modeInfo = std::get<OptionInfo::ModeInfo>(info.valueInfo);
     767 [ -  + ][ +  - ]:          1 :     ASSERT_EQ("batch", modeInfo.defaultValue);
     768 [ -  + ][ +  - ]:          1 :     ASSERT_EQ("batch", modeInfo.currentValue);
     769 [ -  + ][ +  - ]:          1 :     ASSERT_EQ(2, modeInfo.modes.size());
     770         [ -  + ]:          1 :     ASSERT_TRUE(std::find(modeInfo.modes.begin(), modeInfo.modes.end(), "batch")
     771         [ +  - ]:          1 :                 != modeInfo.modes.end());
     772         [ -  + ]:          1 :     ASSERT_TRUE(std::find(modeInfo.modes.begin(), modeInfo.modes.end(), "none")
     773         [ +  - ]:          1 :                 != modeInfo.modes.end());
     774                 :          1 :     std::stringstream ss;
     775                 :          1 :     ss << info;
     776         [ -  + ]:          2 :     ASSERT_EQ(ss.str(),
     777                 :            :               "OptionInfo{ simplification, simplification-mode | mode | batch "
     778         [ +  - ]:          1 :               "| default batch | modes: batch, none }");
     779 [ +  - ][ +  - ]:          1 :   }
     780                 :            : }
     781                 :            : 
     782                 :          4 : TEST_F(TestApiBlackSolver, getUnsatAssumptions1)
     783                 :            : {
     784                 :          1 :   d_solver->setOption("incremental", "false");
     785                 :          1 :   d_solver->checkSatAssuming(d_tm.mkFalse());
     786                 :          1 :   ASSERT_THROW(d_solver->getUnsatAssumptions(), CVC5ApiException);
     787                 :            : }
     788                 :            : 
     789                 :          4 : TEST_F(TestApiBlackSolver, getUnsatAssumptions2)
     790                 :            : {
     791                 :          1 :   d_solver->setOption("incremental", "true");
     792                 :          1 :   d_solver->setOption("produce-unsat-assumptions", "false");
     793                 :          1 :   d_solver->checkSatAssuming(d_tm.mkFalse());
     794                 :          1 :   ASSERT_THROW(d_solver->getUnsatAssumptions(), CVC5ApiException);
     795                 :            : }
     796                 :            : 
     797                 :          4 : TEST_F(TestApiBlackSolver, getUnsatAssumptions3)
     798                 :            : {
     799                 :          1 :   d_solver->setOption("incremental", "true");
     800                 :          1 :   d_solver->setOption("produce-unsat-assumptions", "true");
     801                 :          1 :   d_solver->checkSatAssuming(d_tm.mkFalse());
     802 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->getUnsatAssumptions());
         [ +  - ][ -  - ]
     803                 :          1 :   d_solver->checkSatAssuming(d_tm.mkTrue());
     804                 :          1 :   ASSERT_THROW(d_solver->getUnsatAssumptions(), CVC5ApiException);
     805                 :            : }
     806                 :            : 
     807                 :          4 : TEST_F(TestApiBlackSolver, getUnsatCore1)
     808                 :            : {
     809                 :          1 :   d_solver->setOption("incremental", "false");
     810                 :          1 :   d_solver->assertFormula(d_tm.mkFalse());
     811                 :          1 :   d_solver->checkSat();
     812                 :          1 :   ASSERT_THROW(d_solver->getUnsatCore(), CVC5ApiException);
     813                 :            : }
     814                 :            : 
     815                 :          4 : TEST_F(TestApiBlackSolver, getUnsatCore2)
     816                 :            : {
     817                 :          1 :   d_solver->setOption("incremental", "false");
     818                 :          1 :   d_solver->setOption("produce-unsat-cores", "false");
     819                 :          1 :   d_solver->assertFormula(d_tm.mkFalse());
     820                 :          1 :   d_solver->checkSat();
     821                 :          1 :   ASSERT_THROW(d_solver->getUnsatCore(), CVC5ApiException);
     822                 :            : }
     823                 :            : 
     824                 :          4 : TEST_F(TestApiBlackSolver, getUnsatCoreAndProof)
     825                 :            : {
     826                 :          1 :   d_solver->setOption("incremental", "true");
     827                 :          1 :   d_solver->setOption("produce-unsat-cores", "true");
     828                 :          1 :   d_solver->setOption("produce-proofs", "true");
     829                 :            : 
     830                 :          3 :   Sort uToIntSort = d_tm.mkFunctionSort({d_uninterpreted}, d_int);
     831                 :          3 :   Sort intPredSort = d_tm.mkFunctionSort({d_int}, d_bool);
     832                 :          1 :   std::vector<Term> uc;
     833                 :            : 
     834                 :          1 :   Term x = d_tm.mkConst(d_uninterpreted, "x");
     835                 :          1 :   Term y = d_tm.mkConst(d_uninterpreted, "y");
     836                 :          1 :   Term f = d_tm.mkConst(uToIntSort, "f");
     837                 :          1 :   Term p = d_tm.mkConst(intPredSort, "p");
     838                 :          1 :   Term zero = d_tm.mkInteger(0);
     839                 :          1 :   Term one = d_tm.mkInteger(1);
     840                 :          4 :   Term f_x = d_tm.mkTerm(Kind::APPLY_UF, {f, x});
     841                 :          4 :   Term f_y = d_tm.mkTerm(Kind::APPLY_UF, {f, y});
     842                 :          4 :   Term sum = d_tm.mkTerm(Kind::ADD, {f_x, f_y});
     843                 :          4 :   Term p_0 = d_tm.mkTerm(Kind::APPLY_UF, {p, zero});
     844                 :          4 :   Term p_f_y = d_tm.mkTerm(Kind::APPLY_UF, {p, f_y});
     845 [ +  + ][ -  - ]:          3 :   d_solver->assertFormula(d_tm.mkTerm(Kind::GT, {zero, f_x}));
     846 [ +  + ][ -  - ]:          3 :   d_solver->assertFormula(d_tm.mkTerm(Kind::GT, {zero, f_y}));
     847 [ +  + ][ -  - ]:          3 :   d_solver->assertFormula(d_tm.mkTerm(Kind::GT, {sum, one}));
     848                 :          1 :   d_solver->assertFormula(p_0);
     849                 :          1 :   d_solver->assertFormula(p_f_y.notTerm());
     850 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(d_solver->checkSat().isUnsat());
     851                 :            : 
     852 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(uc = d_solver->getUnsatCore());
         [ +  - ][ -  - ]
     853 [ -  + ][ +  - ]:          1 :   ASSERT_FALSE(uc.empty());
     854                 :            : 
     855 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->getProof());
         [ +  - ][ -  - ]
     856 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->getProof(modes::ProofComponent::SAT));
         [ +  - ][ -  - ]
     857                 :            : 
     858                 :          1 :   d_solver->resetAssertions();
     859         [ +  + ]:          4 :   for (const auto& t : uc)
     860                 :            :   {
     861                 :          3 :     d_solver->assertFormula(t);
     862                 :            :   }
     863                 :          1 :   cvc5::Result res = d_solver->checkSat();
     864 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(res.isUnsat());
     865 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->getProof());
         [ +  - ][ -  - ]
     866 [ +  - ][ +  - ]:          1 : }
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     867                 :            : 
     868                 :          4 : TEST_F(TestApiBlackSolver, getUnsatCoreLemmas1)
     869                 :            : {
     870                 :          1 :   d_solver->setOption("produce-unsat-cores", "true");
     871                 :          1 :   d_solver->setOption("unsat-cores-mode", "sat-proof");
     872                 :            :   // cannot ask before a check sat
     873                 :          1 :   ASSERT_THROW(d_solver->getUnsatCoreLemmas(), CVC5ApiException);
     874                 :            : 
     875                 :          1 :   d_solver->assertFormula(d_tm.mkFalse());
     876 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(d_solver->checkSat().isUnsat());
     877 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->getUnsatCoreLemmas());
         [ +  - ][ -  - ]
     878                 :            : }
     879                 :            : 
     880                 :          4 : TEST_F(TestApiBlackSolver, getUnsatCoreLemmas2)
     881                 :            : {
     882                 :          1 :   d_solver->setOption("incremental", "true");
     883                 :          1 :   d_solver->setOption("produce-unsat-cores", "true");
     884                 :          1 :   d_solver->setOption("produce-proofs", "true");
     885                 :            : 
     886                 :          3 :   Sort uToIntSort = d_tm.mkFunctionSort({d_uninterpreted}, d_int);
     887                 :          3 :   Sort intPredSort = d_tm.mkFunctionSort({d_int}, d_bool);
     888                 :            : 
     889                 :          1 :   Term x = d_tm.mkConst(d_uninterpreted, "x");
     890                 :          1 :   Term y = d_tm.mkConst(d_uninterpreted, "y");
     891                 :          1 :   Term f = d_tm.mkConst(uToIntSort, "f");
     892                 :          1 :   Term p = d_tm.mkConst(intPredSort, "p");
     893                 :          1 :   Term zero = d_tm.mkInteger(0);
     894                 :          1 :   Term one = d_tm.mkInteger(1);
     895                 :          4 :   Term f_x = d_tm.mkTerm(Kind::APPLY_UF, {f, x});
     896                 :          4 :   Term f_y = d_tm.mkTerm(Kind::APPLY_UF, {f, y});
     897                 :          4 :   Term sum = d_tm.mkTerm(Kind::ADD, {f_x, f_y});
     898                 :          4 :   Term p_0 = d_tm.mkTerm(Kind::APPLY_UF, {p, zero});
     899                 :          4 :   Term p_f_y = d_tm.mkTerm(Kind::APPLY_UF, {p, f_y});
     900 [ +  + ][ -  - ]:          3 :   d_solver->assertFormula(d_tm.mkTerm(Kind::GT, {zero, f_x}));
     901 [ +  + ][ -  - ]:          3 :   d_solver->assertFormula(d_tm.mkTerm(Kind::GT, {zero, f_y}));
     902 [ +  + ][ -  - ]:          3 :   d_solver->assertFormula(d_tm.mkTerm(Kind::GT, {sum, one}));
     903                 :          1 :   d_solver->assertFormula(p_0);
     904                 :          1 :   d_solver->assertFormula(p_f_y.notTerm());
     905 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(d_solver->checkSat().isUnsat());
     906                 :            : 
     907 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->getUnsatCoreLemmas());
         [ +  - ][ -  - ]
     908 [ +  - ][ +  - ]:          1 : }
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
     909                 :            : 
     910                 :          4 : TEST_F(TestApiBlackSolver, getAbduct)
     911                 :            : {
     912                 :          1 :   d_solver->setLogic("QF_LIA");
     913                 :          1 :   d_solver->setOption("produce-abducts", "true");
     914                 :          1 :   d_solver->setOption("incremental", "false");
     915                 :            : 
     916                 :          1 :   Term zero = d_tm.mkInteger(0);
     917                 :          1 :   Term x = d_tm.mkConst(d_int, "x");
     918                 :          1 :   Term y = d_tm.mkConst(d_int, "y");
     919                 :            : 
     920                 :            :   // Assumptions for abduction: x > 0
     921 [ +  + ][ -  - ]:          3 :   d_solver->assertFormula(d_tm.mkTerm(Kind::GT, {x, zero}));
     922                 :            :   // Conjecture for abduction: y > 0
     923                 :          4 :   Term conj = d_tm.mkTerm(Kind::GT, {y, zero});
     924                 :            :   // Call the abduction api, while the resulting abduct is the output
     925                 :          1 :   Term output = d_solver->getAbduct(conj);
     926                 :            :   // We expect the resulting output to be a boolean formula
     927 [ +  - ][ +  - ]:          2 :   ASSERT_TRUE(!output.isNull() && output.getSort().isBoolean());
         [ +  - ][ -  + ]
         [ +  - ][ -  - ]
     928                 :            : 
     929                 :            :   // try with a grammar, a simple grammar admitting true
     930                 :          1 :   Term truen = d_tm.mkBoolean(true);
     931                 :          1 :   Term start = d_tm.mkVar(d_bool);
     932                 :          3 :   Grammar g = d_solver->mkGrammar({}, {start});
     933                 :          4 :   Term conj2 = d_tm.mkTerm(Kind::GT, {x, zero});
     934                 :          1 :   ASSERT_THROW(d_solver->getAbduct(conj2, g), CVC5ApiException);
     935 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(g.addRule(start, truen));
         [ +  - ][ -  - ]
     936                 :            :   // Call the abduction api, while the resulting abduct is the output
     937                 :          1 :   Term output2 = d_solver->getAbduct(conj2, g);
     938                 :            :   // abduct must be true
     939 [ -  + ][ +  - ]:          1 :   ASSERT_EQ(output2, truen);
     940                 :            : 
     941                 :          1 :   TermManager tm;
     942                 :          1 :   Solver slv(tm);
     943                 :          1 :   slv.setOption("produce-abducts", "true");
     944                 :          1 :   Sort intSort2 = tm.getIntegerSort();
     945                 :          1 :   Term xx = tm.mkConst(intSort2, "x");
     946                 :          1 :   Term yy = tm.mkConst(intSort2, "y");
     947                 :          1 :   Term zzero = tm.mkInteger(0);
     948                 :          2 :   Term sstart = tm.mkVar(tm.getBooleanSort());
     949                 :          1 :   slv.assertFormula(
     950                 :          6 :       tm.mkTerm(Kind::GT, {tm.mkTerm(Kind::ADD, {xx, yy}), zzero}));
     951                 :          3 :   Grammar gg = slv.mkGrammar({}, {sstart});
     952                 :          1 :   gg.addRule(sstart, tm.mkTrue());
     953                 :          4 :   Term cconj2 = tm.mkTerm(Kind::EQUAL, {zzero, zzero});
     954 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(slv.getAbduct(cconj2, gg));
         [ +  - ][ -  - ]
     955                 :          1 :   ASSERT_THROW(slv.getAbduct(conj2), CVC5ApiException);
     956                 :          1 :   ASSERT_THROW(slv.getAbduct(conj2, gg), CVC5ApiException);
     957                 :          1 :   ASSERT_THROW(slv.getAbduct(cconj2, g), CVC5ApiException);
     958 [ +  - ][ +  - ]:          1 : }
         [ +  - ][ +  - ]
                 [ +  - ]
     959                 :            : 
     960                 :          4 : TEST_F(TestApiBlackSolver, getAbduct2)
     961                 :            : {
     962                 :          1 :   d_solver->setLogic("QF_LIA");
     963                 :          1 :   d_solver->setOption("incremental", "false");
     964                 :          1 :   Term zero = d_tm.mkInteger(0);
     965                 :          1 :   Term x = d_tm.mkConst(d_int, "x");
     966                 :          1 :   Term y = d_tm.mkConst(d_int, "y");
     967                 :            :   // Assumptions for abduction: x > 0
     968 [ +  + ][ -  - ]:          3 :   d_solver->assertFormula(d_tm.mkTerm(Kind::GT, {x, zero}));
     969                 :            :   // Conjecture for abduction: y > 0
     970                 :          4 :   Term conj = d_tm.mkTerm(Kind::GT, {y, zero});
     971                 :            :   // Fails due to option not set
     972                 :          1 :   ASSERT_THROW(d_solver->getAbduct(conj), CVC5ApiException);
     973 [ +  - ][ +  - ]:          1 : }
         [ +  - ][ +  - ]
     974                 :            : 
     975                 :          4 : TEST_F(TestApiBlackSolver, getAbductNext)
     976                 :            : {
     977                 :          1 :   d_solver->setLogic("QF_LIA");
     978                 :          1 :   d_solver->setOption("produce-abducts", "true");
     979                 :          1 :   d_solver->setOption("incremental", "true");
     980                 :            : 
     981                 :          1 :   Term zero = d_tm.mkInteger(0);
     982                 :          1 :   Term x = d_tm.mkConst(d_int, "x");
     983                 :          1 :   Term y = d_tm.mkConst(d_int, "y");
     984                 :            : 
     985                 :            :   // Assumptions for abduction: x > 0
     986 [ +  + ][ -  - ]:          3 :   d_solver->assertFormula(d_tm.mkTerm(Kind::GT, {x, zero}));
     987                 :            :   // Conjecture for abduction: y > 0
     988                 :          4 :   Term conj = d_tm.mkTerm(Kind::GT, {y, zero});
     989                 :            :   // Call the abduction api, while the resulting abduct is the output
     990                 :          1 :   Term output = d_solver->getAbduct(conj);
     991                 :          1 :   Term output2 = d_solver->getAbductNext();
     992                 :            :   // should produce a different output
     993 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(output != output2);
     994 [ +  - ][ +  - ]:          1 : }
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     995                 :            : 
     996                 :          4 : TEST_F(TestApiBlackSolver, getInterpolant)
     997                 :            : {
     998                 :          1 :   d_solver->setLogic("QF_LIA");
     999                 :          1 :   d_solver->setOption("produce-interpolants", "true");
    1000                 :          1 :   d_solver->setOption("incremental", "false");
    1001                 :            : 
    1002                 :          1 :   Term zero = d_tm.mkInteger(0);
    1003                 :          1 :   Term x = d_tm.mkConst(d_int, "x");
    1004                 :          1 :   Term y = d_tm.mkConst(d_int, "y");
    1005                 :          1 :   Term z = d_tm.mkConst(d_int, "z");
    1006                 :            : 
    1007                 :            :   // Assumptions for interpolation: x + y > 0 /\ x < 0
    1008                 :          2 :   d_solver->assertFormula(
    1009                 :          6 :       d_tm.mkTerm(Kind::GT, {d_tm.mkTerm(Kind::ADD, {x, y}), zero}));
    1010 [ +  + ][ -  - ]:          3 :   d_solver->assertFormula(d_tm.mkTerm(Kind::LT, {x, zero}));
    1011                 :            :   // Conjecture for interpolation: y + z > 0 \/ z < 0
    1012                 :          2 :   Term conj = d_tm.mkTerm(
    1013                 :            :       Kind::OR,
    1014                 :          4 :       {d_tm.mkTerm(Kind::GT, {d_tm.mkTerm(Kind::ADD, {y, z}), zero}),
    1015                 :          7 :        d_tm.mkTerm(Kind::LT, {z, zero})});
    1016                 :            :   // Call the interpolation api, while the resulting interpolant is the output
    1017                 :          1 :   Term output = d_solver->getInterpolant(conj);
    1018                 :            :   // We expect the resulting output to be a boolean formula
    1019 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(output.getSort().isBoolean());
    1020                 :            : 
    1021                 :            :   // try with a grammar, a simple grammar admitting true
    1022                 :          1 :   Term truen = d_tm.mkBoolean(true);
    1023                 :          1 :   Term start = d_tm.mkVar(d_bool);
    1024                 :          3 :   Grammar g = d_solver->mkGrammar({}, {start});
    1025                 :          4 :   Term conj2 = d_tm.mkTerm(Kind::EQUAL, {zero, zero});
    1026                 :          1 :   ASSERT_THROW(d_solver->getInterpolant(conj2, g), CVC5ApiException);
    1027 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(g.addRule(start, truen));
         [ +  - ][ -  - ]
    1028                 :            :   // Call the interpolation api, while the resulting interpolant is the output
    1029                 :          1 :   Term output2 = d_solver->getInterpolant(conj2, g);
    1030                 :            :   // interpolant must be true
    1031 [ -  + ][ +  - ]:          1 :   ASSERT_EQ(output2, truen);
    1032                 :            : 
    1033                 :          1 :   TermManager tm;
    1034                 :          1 :   Solver slv(tm);
    1035                 :          1 :   slv.setOption("produce-interpolants", "true");
    1036                 :          1 :   Term zzero = tm.mkInteger(0);
    1037                 :          2 :   Term sstart = tm.mkVar(tm.getBooleanSort());
    1038                 :          3 :   Grammar gg = slv.mkGrammar({}, {sstart});
    1039                 :          1 :   gg.addRule(sstart, tm.mkTrue());
    1040                 :          4 :   Term cconj2 = tm.mkTerm(Kind::EQUAL, {zzero, zzero});
    1041 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(slv.getInterpolant(cconj2, gg));
         [ +  - ][ -  - ]
    1042                 :          1 :   ASSERT_THROW(slv.getInterpolant(conj2), CVC5ApiException);
    1043                 :          1 :   ASSERT_THROW(slv.getInterpolant(conj2, gg), CVC5ApiException);
    1044                 :          1 :   ASSERT_THROW(slv.getInterpolant(cconj2, g), CVC5ApiException);
    1045 [ +  - ][ +  - ]:          1 : }
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
    1046                 :            : 
    1047                 :          4 : TEST_F(TestApiBlackSolver, getInterpolantNext)
    1048                 :            : {
    1049                 :          1 :   d_solver->setLogic("QF_LIA");
    1050                 :          1 :   d_solver->setOption("produce-interpolants", "true");
    1051                 :          1 :   d_solver->setOption("incremental", "true");
    1052                 :            : 
    1053                 :          1 :   Term zero = d_tm.mkInteger(0);
    1054                 :          1 :   Term x = d_tm.mkConst(d_int, "x");
    1055                 :          1 :   Term y = d_tm.mkConst(d_int, "y");
    1056                 :          1 :   Term z = d_tm.mkConst(d_int, "z");
    1057                 :            :   // Assumptions for interpolation: x + y > 0 /\ x < 0
    1058                 :          2 :   d_solver->assertFormula(
    1059                 :          6 :       d_tm.mkTerm(Kind::GT, {d_tm.mkTerm(Kind::ADD, {x, y}), zero}));
    1060 [ +  + ][ -  - ]:          3 :   d_solver->assertFormula(d_tm.mkTerm(Kind::LT, {x, zero}));
    1061                 :            :   // Conjecture for interpolation: y + z > 0 \/ z < 0
    1062                 :          2 :   Term conj = d_tm.mkTerm(
    1063                 :            :       Kind::OR,
    1064                 :          4 :       {d_tm.mkTerm(Kind::GT, {d_tm.mkTerm(Kind::ADD, {y, z}), zero}),
    1065                 :          7 :        d_tm.mkTerm(Kind::LT, {z, zero})});
    1066                 :          1 :   Term output = d_solver->getInterpolant(conj);
    1067                 :          1 :   Term output2 = d_solver->getInterpolantNext();
    1068                 :            : 
    1069                 :            :   // We expect the next output to be distinct
    1070 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(output != output2);
    1071 [ +  - ][ +  - ]:          1 : }
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
    1072                 :            : 
    1073                 :          4 : TEST_F(TestApiBlackSolver, declarePool)
    1074                 :            : {
    1075                 :          1 :   Sort setSort = d_tm.mkSetSort(d_int);
    1076                 :          1 :   Term zero = d_tm.mkInteger(0);
    1077                 :          1 :   Term x = d_tm.mkConst(d_int, "x");
    1078                 :          1 :   Term y = d_tm.mkConst(d_int, "y");
    1079                 :            :   // declare a pool with initial value { 0, x, y }
    1080                 :          5 :   Term p = d_solver->declarePool("p", d_int, {zero, x, y});
    1081                 :            :   // pool should have the same sort
    1082 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(p.getSort() == setSort);
    1083                 :            :   // cannot pass null sort
    1084                 :          1 :   Sort nullSort;
    1085                 :          4 :   ASSERT_THROW(d_solver->declarePool("i", nullSort, {}), CVC5ApiException);
    1086                 :            : 
    1087                 :          1 :   TermManager tm;
    1088                 :          1 :   Solver slv(tm);
    1089                 :          1 :   Sort tm_int = tm.getIntegerSort();
    1090                 :          1 :   Term tm_zero = tm.mkInteger(0);
    1091                 :          1 :   Term tm_x = tm.mkConst(tm_int, "x");
    1092                 :          1 :   Term tm_y = tm.mkConst(tm_int, "y");
    1093                 :          9 :   ASSERT_THROW(slv.declarePool("p", d_int, {tm_zero, tm_x, tm_y}),
    1094         [ +  - ]:          1 :                CVC5ApiException);
    1095                 :          9 :   ASSERT_THROW(slv.declarePool("p", tm_int, {zero, tm_x, tm_y}),
    1096         [ +  - ]:          1 :                CVC5ApiException);
    1097                 :          9 :   ASSERT_THROW(slv.declarePool("p", tm_int, {tm_zero, x, tm_y}),
    1098         [ +  - ]:          1 :                CVC5ApiException);
    1099                 :          9 :   ASSERT_THROW(slv.declarePool("p", tm_int, {tm_zero, tm_x, y}),
    1100         [ +  - ]:          1 :                CVC5ApiException);
    1101 [ +  - ][ +  - ]:          1 : }
         [ +  - ][ +  - ]
                 [ +  - ]
    1102                 :            : 
    1103                 :          4 : TEST_F(TestApiBlackSolver, getDriverOptions)
    1104                 :            : {
    1105                 :          1 :   auto dopts = d_solver->getDriverOptions();
    1106 [ -  + ][ +  - ]:          1 :   ASSERT_EQ(dopts.err().rdbuf(), std::cerr.rdbuf());
    1107 [ -  + ][ +  - ]:          1 :   ASSERT_EQ(dopts.in().rdbuf(), std::cin.rdbuf());
    1108 [ -  + ][ +  - ]:          1 :   ASSERT_EQ(dopts.out().rdbuf(), std::cout.rdbuf());
    1109                 :            : }
    1110                 :            : 
    1111                 :          4 : TEST_F(TestApiBlackSolver, getStatistics)
    1112                 :            : {
    1113 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(cvc5::Stat());
         [ +  - ][ -  - ]
    1114                 :            :   // do some array reasoning to make sure we have statistics
    1115                 :            :   {
    1116                 :          1 :     Sort s2 = d_tm.mkArraySort(d_int, d_int);
    1117                 :          1 :     Term t1 = d_tm.mkConst(d_int, "i");
    1118                 :          1 :     Term t2 = d_tm.mkConst(s2, "a");
    1119                 :          4 :     Term t3 = d_tm.mkTerm(Kind::SELECT, {t2, t1});
    1120                 :          1 :     d_solver->assertFormula(t3.eqTerm(t1));
    1121                 :          1 :     d_solver->checkSat();
    1122                 :          1 :   }
    1123                 :          1 :   cvc5::Statistics stats = d_solver->getStatistics();
    1124                 :          1 :   std::stringstream ss;
    1125                 :          1 :   ss << stats;
    1126                 :            :   {
    1127                 :          2 :     auto s = stats.get("global::totalTime");
    1128 [ -  + ][ +  - ]:          1 :     ASSERT_FALSE(s.isInternal());
    1129 [ -  + ][ +  - ]:          1 :     ASSERT_FALSE(s.isDefault());
    1130 [ -  + ][ +  - ]:          1 :     ASSERT_TRUE(s.isString());
    1131                 :          1 :     std::string time = s.getString();
    1132 [ -  + ][ +  - ]:          1 :     ASSERT_TRUE(time.rfind("ms") == time.size() - 2);  // ends with "ms"
    1133 [ -  + ][ +  - ]:          1 :     ASSERT_FALSE(s.isDouble());
    1134                 :          1 :     ss << s << s.toString();
    1135                 :          1 :     s = stats.get("resource::resourceUnitsUsed");
    1136 [ -  + ][ +  - ]:          1 :     ASSERT_TRUE(s.isInternal());
    1137 [ -  + ][ +  - ]:          1 :     ASSERT_FALSE(s.isDefault());
    1138 [ -  + ][ +  - ]:          1 :     ASSERT_TRUE(s.isInt());
    1139 [ -  + ][ +  - ]:          1 :     ASSERT_TRUE(s.getInt() >= 0);
    1140                 :          1 :     ss << s << s.toString();
    1141         [ +  - ]:          1 :   }
    1142                 :          1 :   bool hasstats = false;
    1143         [ +  + ]:        517 :   for (const auto& s : stats)
    1144                 :            :   {
    1145                 :        516 :     hasstats = true;
    1146 [ -  + ][ +  - ]:        516 :     ASSERT_FALSE(s.first.empty());
    1147                 :            :   }
    1148 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(hasstats);
    1149                 :          1 :   hasstats = false;
    1150         [ +  + ]:        517 :   for (auto it = stats.begin(true, true); it != stats.end(); ++it)
    1151                 :            :   {
    1152                 :        516 :     hasstats = true;
    1153                 :            :     {
    1154                 :        516 :       auto tmp1 = it, tmp2 = it;
    1155                 :        516 :       ++tmp1;
    1156                 :        516 :       tmp2++;
    1157 [ -  + ][ +  - ]:        516 :       ASSERT_EQ(tmp1, tmp2);
    1158                 :        516 :       --tmp1;
    1159                 :        516 :       tmp2--;
    1160 [ -  + ][ +  - ]:        516 :       ASSERT_EQ(tmp1, tmp2);
    1161 [ -  + ][ +  - ]:        516 :       ASSERT_EQ(tmp1, it);
    1162 [ -  + ][ +  - ]:        516 :       ASSERT_EQ(it, tmp2);
    1163                 :            :     }
    1164                 :        516 :     const auto& s = *it;
    1165                 :            :     // check some basic utility methods
    1166 [ -  + ][ +  - ]:        516 :     ASSERT_TRUE(!(it == stats.end()));
    1167 [ -  + ][ +  - ]:        516 :     ASSERT_EQ(s.first, it->first);
    1168         [ +  + ]:        516 :     if (s.first == "theory::arrays::avgIndexListLength")
    1169                 :            :     {
    1170 [ -  + ][ +  - ]:          1 :       ASSERT_TRUE(s.second.isInternal());
    1171 [ -  + ][ +  - ]:          1 :       ASSERT_TRUE(s.second.isDouble());
    1172 [ -  + ][ +  - ]:          1 :       ASSERT_TRUE(std::isnan(s.second.getDouble()));
    1173                 :            :     }
    1174                 :            :   }
    1175 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(hasstats);
    1176                 :            : }
    1177                 :            : 
    1178                 :          4 : TEST_F(TestApiBlackSolver, printStatisticsSafe)
    1179                 :            : {
    1180                 :            :   // do some array reasoning to make sure we have statistics
    1181                 :            :   {
    1182                 :          1 :     Sort s2 = d_tm.mkArraySort(d_int, d_int);
    1183                 :          1 :     Term t1 = d_tm.mkConst(d_int, "i");
    1184                 :          1 :     Term t2 = d_tm.mkConst(s2, "a");
    1185                 :          4 :     Term t3 = d_tm.mkTerm(Kind::SELECT, {t2, t1});
    1186                 :          1 :     d_solver->assertFormula(t3.eqTerm(t1));
    1187                 :          1 :     d_solver->checkSat();
    1188                 :          1 :   }
    1189                 :          1 :   testing::internal::CaptureStdout();
    1190                 :          1 :   d_solver->printStatisticsSafe(STDOUT_FILENO);
    1191                 :          1 :   testing::internal::GetCapturedStdout();
    1192                 :          1 : }
    1193                 :            : 
    1194                 :          4 : TEST_F(TestApiBlackSolver, getProofAndProofToString)
    1195                 :            : {
    1196                 :          1 :   d_solver->setOption("produce-proofs", "true");
    1197                 :            : 
    1198                 :          3 :   Sort uToIntSort = d_tm.mkFunctionSort({d_uninterpreted}, d_int);
    1199                 :          3 :   Sort intPredSort = d_tm.mkFunctionSort({d_int}, d_bool);
    1200                 :          1 :   std::vector<Proof> proofs;
    1201                 :            : 
    1202                 :          1 :   Term x = d_tm.mkConst(d_uninterpreted, "x");
    1203                 :          1 :   Term y = d_tm.mkConst(d_uninterpreted, "y");
    1204                 :          1 :   Term f = d_tm.mkConst(uToIntSort, "f");
    1205                 :          1 :   Term p = d_tm.mkConst(intPredSort, "p");
    1206                 :          1 :   Term zero = d_tm.mkInteger(0);
    1207                 :          1 :   Term one = d_tm.mkInteger(1);
    1208                 :          4 :   Term f_x = d_tm.mkTerm(Kind::APPLY_UF, {f, x});
    1209                 :          4 :   Term f_y = d_tm.mkTerm(Kind::APPLY_UF, {f, y});
    1210                 :          4 :   Term sum = d_tm.mkTerm(Kind::ADD, {f_x, f_y});
    1211                 :          4 :   Term p_0 = d_tm.mkTerm(Kind::APPLY_UF, {p, zero});
    1212                 :          4 :   Term p_f_y = d_tm.mkTerm(Kind::APPLY_UF, {p, f_y});
    1213 [ +  + ][ -  - ]:          3 :   d_solver->assertFormula(d_tm.mkTerm(Kind::GT, {zero, f_x}));
    1214 [ +  + ][ -  - ]:          3 :   d_solver->assertFormula(d_tm.mkTerm(Kind::GT, {zero, f_y}));
    1215 [ +  + ][ -  - ]:          3 :   d_solver->assertFormula(d_tm.mkTerm(Kind::GT, {sum, one}));
    1216                 :          1 :   d_solver->assertFormula(p_0);
    1217                 :          1 :   d_solver->assertFormula(p_f_y.notTerm());
    1218 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(d_solver->checkSat().isUnsat());
    1219                 :            : 
    1220                 :          1 :   std::string printedProof;
    1221 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(proofs = d_solver->getProof());
         [ +  - ][ -  - ]
    1222 [ -  + ][ +  - ]:          1 :   ASSERT_FALSE(proofs.empty());
    1223 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(printedProof = d_solver->proofToString(proofs[0]));
         [ +  - ][ -  - ]
    1224 [ -  + ][ +  - ]:          1 :   ASSERT_FALSE(printedProof.empty());
    1225 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(printedProof = d_solver->proofToString(
                 [ -  - ]
    1226         [ +  - ]:          1 :                       proofs[0], modes::ProofFormat::ALETHE));
    1227 [ -  + ][ +  - ]:          1 :   ASSERT_FALSE(printedProof.empty());
    1228 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(proofs = d_solver->getProof(modes::ProofComponent::SAT));
         [ +  - ][ -  - ]
    1229 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(printedProof = d_solver->proofToString(
                 [ -  - ]
    1230         [ +  - ]:          1 :                       proofs[0], modes::ProofFormat::NONE));
    1231 [ -  + ][ +  - ]:          1 :   ASSERT_FALSE(printedProof.empty());
    1232 [ +  - ][ +  - ]:          1 : }
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
    1233                 :            : 
    1234                 :          4 : TEST_F(TestApiBlackSolver, proofToStringAssertionNames)
    1235                 :            : {
    1236                 :          1 :   d_solver->setOption("produce-proofs", "true");
    1237                 :            : 
    1238                 :          1 :   std::vector<Proof> proofs;
    1239                 :            : 
    1240                 :          1 :   Term x = d_tm.mkConst(d_uninterpreted, "x");
    1241                 :          1 :   Term y = d_tm.mkConst(d_uninterpreted, "y");
    1242                 :            : 
    1243                 :          4 :   Term x_eq_y = d_tm.mkTerm(Kind::EQUAL, {x, y});
    1244                 :          3 :   Term not_x_eq_y = d_tm.mkTerm(Kind::NOT, {x_eq_y});
    1245                 :            : 
    1246                 :          1 :   std::map<cvc5::Term, std::string> assertionNames;
    1247                 :          1 :   assertionNames.emplace(x_eq_y, "as1");
    1248                 :          1 :   assertionNames.emplace(not_x_eq_y, "as2");
    1249                 :            : 
    1250                 :          1 :   d_solver->assertFormula(x_eq_y);
    1251                 :          1 :   d_solver->assertFormula(not_x_eq_y);
    1252                 :            : 
    1253 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(d_solver->checkSat().isUnsat());
    1254                 :            : 
    1255                 :          1 :   std::string printedProof;
    1256 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(proofs = d_solver->getProof());
         [ +  - ][ -  - ]
    1257 [ -  + ][ +  - ]:          1 :   ASSERT_FALSE(proofs.empty());
    1258 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(printedProof = d_solver->proofToString(
                 [ -  - ]
    1259         [ +  - ]:          1 :                       proofs[0], modes::ProofFormat::ALETHE, assertionNames));
    1260 [ -  + ][ +  - ]:          1 :   ASSERT_FALSE(printedProof.empty());
    1261 [ -  + ][ +  - ]:          1 :   ASSERT_LT(printedProof.find("as1"), std::string::npos);
    1262 [ -  + ][ +  - ]:          1 :   ASSERT_LT(printedProof.find("as2"), std::string::npos);
    1263 [ +  - ][ +  - ]:          1 : }
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
    1264                 :            : 
    1265                 :          4 : TEST_F(TestApiBlackSolver, getDifficulty)
    1266                 :            : {
    1267                 :          1 :   d_solver->setOption("produce-difficulty", "true");
    1268                 :            :   // cannot ask before a check sat
    1269                 :          1 :   ASSERT_THROW(d_solver->getDifficulty(), CVC5ApiException);
    1270                 :          1 :   d_solver->checkSat();
    1271 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->getDifficulty());
         [ +  - ][ -  - ]
    1272                 :            : }
    1273                 :            : 
    1274                 :          4 : TEST_F(TestApiBlackSolver, getDifficulty2)
    1275                 :            : {
    1276                 :          1 :   d_solver->checkSat();
    1277                 :            :   // option is not set
    1278                 :          1 :   ASSERT_THROW(d_solver->getDifficulty(), CVC5ApiException);
    1279                 :            : }
    1280                 :            : 
    1281                 :          4 : TEST_F(TestApiBlackSolver, getDifficulty3)
    1282                 :            : {
    1283                 :          1 :   d_solver->setOption("produce-difficulty", "true");
    1284                 :          1 :   Term x = d_tm.mkConst(d_int, "x");
    1285                 :          1 :   Term zero = d_tm.mkInteger(0);
    1286                 :          1 :   Term ten = d_tm.mkInteger(10);
    1287                 :          4 :   Term f0 = d_tm.mkTerm(Kind::GEQ, {x, ten});
    1288                 :          4 :   Term f1 = d_tm.mkTerm(Kind::GEQ, {zero, x});
    1289                 :          1 :   d_solver->assertFormula(f0);
    1290                 :          1 :   d_solver->assertFormula(f1);
    1291                 :          1 :   d_solver->checkSat();
    1292                 :          1 :   std::map<Term, Term> dmap;
    1293 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(dmap = d_solver->getDifficulty());
         [ +  - ][ -  - ]
    1294                 :            :   // difficulty should map assertions to integer values
    1295         [ +  + ]:          3 :   for (const std::pair<const Term, Term>& t : dmap)
    1296                 :            :   {
    1297 [ +  + ][ +  - ]:          2 :     ASSERT_TRUE(t.first == f0 || t.first == f1);
         [ -  + ][ +  - ]
    1298 [ -  + ][ +  - ]:          2 :     ASSERT_TRUE(t.second.getKind() == Kind::CONST_INTEGER);
    1299                 :            :   }
    1300 [ +  - ][ +  - ]:          1 : }
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
    1301                 :            : 
    1302                 :          4 : TEST_F(TestApiBlackSolver, getLearnedLiterals)
    1303                 :            : {
    1304                 :          1 :   d_solver->setOption("produce-learned-literals", "true");
    1305                 :            :   // cannot ask before a check sat
    1306                 :          1 :   ASSERT_THROW(d_solver->getLearnedLiterals(), CVC5ApiException);
    1307                 :          1 :   d_solver->checkSat();
    1308 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->getLearnedLiterals());
         [ +  - ][ -  - ]
    1309 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(
                 [ -  - ]
    1310         [ +  - ]:          1 :       d_solver->getLearnedLiterals(modes::LearnedLitType::PREPROCESS));
    1311                 :            : }
    1312                 :            : 
    1313                 :          4 : TEST_F(TestApiBlackSolver, getLearnedLiterals2)
    1314                 :            : {
    1315                 :          1 :   d_solver->setOption("produce-learned-literals", "true");
    1316                 :          1 :   Term x = d_tm.mkConst(d_int, "x");
    1317                 :          1 :   Term y = d_tm.mkConst(d_int, "y");
    1318                 :          1 :   Term zero = d_tm.mkInteger(0);
    1319                 :          1 :   Term ten = d_tm.mkInteger(10);
    1320                 :          4 :   Term f0 = d_tm.mkTerm(Kind::GEQ, {x, ten});
    1321                 :          2 :   Term f1 = d_tm.mkTerm(
    1322                 :            :       Kind::OR,
    1323                 :          8 :       {d_tm.mkTerm(Kind::GEQ, {zero, x}), d_tm.mkTerm(Kind::GEQ, {y, zero})});
    1324                 :          1 :   d_solver->assertFormula(f0);
    1325                 :          1 :   d_solver->assertFormula(f1);
    1326                 :          1 :   d_solver->checkSat();
    1327 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->getLearnedLiterals());
         [ +  - ][ -  - ]
    1328 [ +  - ][ +  - ]:          1 : }
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
    1329                 :            : 
    1330                 :          4 : TEST_F(TestApiBlackSolver, getTimeoutCore)
    1331                 :            : {
    1332                 :          1 :   d_solver->setOption("timeout-core-timeout", "100");
    1333                 :          1 :   d_solver->setOption("produce-unsat-cores", "true");
    1334                 :          1 :   Term x = d_tm.mkConst(d_int, "x");
    1335                 :          1 :   Term tt = d_tm.mkBoolean(true);
    1336                 :            :   Term hard =
    1337                 :          2 :       d_tm.mkTerm(Kind::EQUAL,
    1338                 :          2 :                   {d_tm.mkTerm(Kind::MULT, {x, x}),
    1339                 :          3 :                    d_tm.mkInteger("501240912901901249014210220059591")});
    1340                 :          1 :   d_solver->assertFormula(tt);
    1341                 :          1 :   d_solver->assertFormula(hard);
    1342                 :          1 :   std::pair<cvc5::Result, std::vector<Term>> res = d_solver->getTimeoutCore();
    1343 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(res.first.isUnknown());
    1344 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(res.second.size() == 1);
    1345 [ -  + ][ +  - ]:          1 :   ASSERT_EQ(res.second[0], hard);
    1346 [ +  - ][ +  - ]:          1 : }
         [ +  - ][ +  - ]
    1347                 :            : 
    1348                 :          4 : TEST_F(TestApiBlackSolver, getTimeoutCoreUnsat)
    1349                 :            : {
    1350                 :          1 :   d_solver->setOption("produce-unsat-cores", "true");
    1351                 :          1 :   Term ff = d_tm.mkBoolean(false);
    1352                 :          1 :   Term tt = d_tm.mkBoolean(true);
    1353                 :          1 :   d_solver->assertFormula(tt);
    1354                 :          1 :   d_solver->assertFormula(ff);
    1355                 :          1 :   d_solver->assertFormula(tt);
    1356                 :          1 :   std::pair<cvc5::Result, std::vector<Term>> res = d_solver->getTimeoutCore();
    1357 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(res.first.isUnsat());
    1358 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(res.second.size() == 1);
    1359 [ -  + ][ +  - ]:          1 :   ASSERT_EQ(res.second[0], ff);
    1360 [ +  - ][ +  - ]:          1 : }
                 [ +  - ]
    1361                 :            : 
    1362                 :          4 : TEST_F(TestApiBlackSolver, getTimeoutCoreAssuming)
    1363                 :            : {
    1364                 :          1 :   d_solver->setOption("produce-unsat-cores", "true");
    1365                 :          1 :   Term ff = d_tm.mkBoolean(false);
    1366                 :          1 :   Term tt = d_tm.mkBoolean(true);
    1367                 :          1 :   d_solver->assertFormula(tt);
    1368                 :            :   std::pair<cvc5::Result, std::vector<Term>> res =
    1369                 :          4 :       d_solver->getTimeoutCoreAssuming({ff, tt});
    1370 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(res.first.isUnsat());
    1371 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(res.second.size() == 1);
    1372 [ -  + ][ +  - ]:          1 :   ASSERT_EQ(res.second[0], ff);
    1373 [ +  - ][ +  - ]:          1 : }
                 [ +  - ]
    1374                 :            : 
    1375                 :          4 : TEST_F(TestApiBlackSolver, getTimeoutCoreAssumingEmpty)
    1376                 :            : {
    1377                 :          1 :   d_solver->setOption("produce-unsat-cores", "true");
    1378                 :          2 :   ASSERT_THROW(d_solver->getTimeoutCoreAssuming({}), CVC5ApiException);
    1379                 :            : }
    1380                 :            : 
    1381                 :          4 : TEST_F(TestApiBlackSolver, getValue1)
    1382                 :            : {
    1383                 :          1 :   d_solver->setOption("produce-models", "false");
    1384                 :          1 :   Term t = d_tm.mkTrue();
    1385                 :          1 :   d_solver->assertFormula(t);
    1386                 :          1 :   d_solver->checkSat();
    1387                 :          1 :   ASSERT_THROW(d_solver->getValue(t), CVC5ApiException);
    1388         [ +  - ]:          1 : }
    1389                 :            : 
    1390                 :          4 : TEST_F(TestApiBlackSolver, getValue2)
    1391                 :            : {
    1392                 :          1 :   d_solver->setOption("produce-models", "true");
    1393                 :          1 :   Term t = d_tm.mkFalse();
    1394                 :          1 :   d_solver->assertFormula(t);
    1395                 :          1 :   d_solver->checkSat();
    1396                 :          1 :   ASSERT_THROW(d_solver->getValue(t), CVC5ApiException);
    1397         [ +  - ]:          1 : }
    1398                 :            : 
    1399                 :          4 : TEST_F(TestApiBlackSolver, getValue3)
    1400                 :            : {
    1401                 :          1 :   d_solver->setOption("produce-models", "true");
    1402                 :          3 :   Sort uToIntSort = d_tm.mkFunctionSort({d_uninterpreted}, d_int);
    1403                 :          3 :   Sort intPredSort = d_tm.mkFunctionSort({d_int}, d_bool);
    1404                 :          1 :   std::vector<Term> unsat_core;
    1405                 :            : 
    1406                 :          1 :   Term x = d_tm.mkConst(d_uninterpreted, "x");
    1407                 :          1 :   Term y = d_tm.mkConst(d_uninterpreted, "y");
    1408                 :          1 :   Term z = d_tm.mkConst(d_uninterpreted, "z");
    1409                 :          1 :   Term f = d_tm.mkConst(uToIntSort, "f");
    1410                 :          1 :   Term p = d_tm.mkConst(intPredSort, "p");
    1411                 :          1 :   Term zero = d_tm.mkInteger(0);
    1412                 :          1 :   Term one = d_tm.mkInteger(1);
    1413                 :          4 :   Term f_x = d_tm.mkTerm(Kind::APPLY_UF, {f, x});
    1414                 :          4 :   Term f_y = d_tm.mkTerm(Kind::APPLY_UF, {f, y});
    1415                 :          4 :   Term sum = d_tm.mkTerm(Kind::ADD, {f_x, f_y});
    1416                 :          4 :   Term p_0 = d_tm.mkTerm(Kind::APPLY_UF, {p, zero});
    1417                 :          4 :   Term p_f_y = d_tm.mkTerm(Kind::APPLY_UF, {p, f_y});
    1418                 :            : 
    1419 [ +  + ][ -  - ]:          3 :   d_solver->assertFormula(d_tm.mkTerm(Kind::LEQ, {zero, f_x}));
    1420 [ +  + ][ -  - ]:          3 :   d_solver->assertFormula(d_tm.mkTerm(Kind::LEQ, {zero, f_y}));
    1421 [ +  + ][ -  - ]:          3 :   d_solver->assertFormula(d_tm.mkTerm(Kind::LEQ, {sum, one}));
    1422                 :          1 :   d_solver->assertFormula(p_0.notTerm());
    1423                 :          1 :   d_solver->assertFormula(p_f_y);
    1424 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(d_solver->checkSat().isSat());
    1425 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->getValue(x));
         [ +  - ][ -  - ]
    1426 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->getValue(y));
         [ +  - ][ -  - ]
    1427 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->getValue(z));
         [ +  - ][ -  - ]
    1428 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->getValue(sum));
         [ +  - ][ -  - ]
    1429 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->getValue(p_f_y));
         [ +  - ][ -  - ]
    1430                 :            : 
    1431                 :          1 :   std::vector<Term> a;
    1432 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(a.emplace_back(d_solver->getValue(x)));
         [ +  - ][ -  - ]
    1433 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(a.emplace_back(d_solver->getValue(y)));
         [ +  - ][ -  - ]
    1434 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(a.emplace_back(d_solver->getValue(z)));
         [ +  - ][ -  - ]
    1435                 :          1 :   std::vector<Term> b;
    1436                 :          4 :   ASSERT_NO_THROW(b = d_solver->getValue({x, y, z}));
    1437 [ -  + ][ +  - ]:          1 :   ASSERT_EQ(a, b);
    1438                 :            : 
    1439                 :          2 :   ASSERT_THROW(Solver(d_tm).getValue(x), CVC5ApiException);
    1440                 :            :   {
    1441                 :          1 :     Solver slv(d_tm);
    1442                 :          1 :     slv.setOption("produce-models", "true");
    1443                 :          1 :     ASSERT_THROW(slv.getValue(x), CVC5ApiException);
    1444         [ +  - ]:          1 :   }
    1445                 :            :   {
    1446                 :          1 :     Solver slv(d_tm);
    1447                 :          1 :     slv.setOption("produce-models", "true");
    1448                 :          1 :     slv.checkSat();
    1449 [ +  - ][ +  - ]:          1 :     ASSERT_NO_THROW(slv.getValue(x));
         [ +  - ][ -  - ]
    1450         [ +  - ]:          1 :   }
    1451                 :            : 
    1452                 :          1 :   TermManager tm;
    1453                 :          1 :   Solver slv(tm);
    1454                 :          1 :   slv.setOption("produce-models", "true");
    1455                 :          1 :   slv.checkSat();
    1456                 :          3 :   ASSERT_THROW(slv.getValue(d_tm.mkConst(d_bool, "x")), CVC5ApiException);
    1457 [ +  - ][ +  - ]:          1 : }
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
    1458                 :            : 
    1459                 :          4 : TEST_F(TestApiBlackSolver, getModelDomainElements)
    1460                 :            : {
    1461                 :          1 :   d_solver->setOption("produce-models", "true");
    1462                 :          1 :   Term x = d_tm.mkConst(d_uninterpreted, "x");
    1463                 :          1 :   Term y = d_tm.mkConst(d_uninterpreted, "y");
    1464                 :          1 :   Term z = d_tm.mkConst(d_uninterpreted, "z");
    1465                 :          5 :   Term f = d_tm.mkTerm(Kind::DISTINCT, {x, y, z});
    1466                 :          1 :   d_solver->assertFormula(f);
    1467                 :          1 :   d_solver->checkSat();
    1468                 :          1 :   auto elems = d_solver->getModelDomainElements(d_uninterpreted);
    1469 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(elems.size() >= 3);
    1470                 :          1 :   ASSERT_THROW(d_solver->getModelDomainElements(d_int), CVC5ApiException);
    1471                 :            : 
    1472                 :          1 :   TermManager tm;
    1473                 :          1 :   Solver slv(tm);
    1474                 :          1 :   slv.setOption("produce-models", "true");
    1475                 :          1 :   slv.checkSat();
    1476                 :          1 :   ASSERT_THROW(slv.getModelDomainElements(d_uninterpreted), CVC5ApiException);
    1477 [ +  - ][ +  - ]:          1 : }
         [ +  - ][ +  - ]
                 [ +  - ]
    1478                 :            : 
    1479                 :          4 : TEST_F(TestApiBlackSolver, getModelDomainElements2)
    1480                 :            : {
    1481                 :          1 :   d_solver->setOption("produce-models", "true");
    1482                 :          1 :   d_solver->setOption("finite-model-find", "true");
    1483                 :          1 :   Term x = d_tm.mkVar(d_uninterpreted, "x");
    1484                 :          1 :   Term y = d_tm.mkVar(d_uninterpreted, "y");
    1485                 :          4 :   Term eq = d_tm.mkTerm(Kind::EQUAL, {x, y});
    1486                 :          4 :   Term bvl = d_tm.mkTerm(Kind::VARIABLE_LIST, {x, y});
    1487                 :          4 :   Term f = d_tm.mkTerm(Kind::FORALL, {bvl, eq});
    1488                 :          1 :   d_solver->assertFormula(f);
    1489                 :          1 :   d_solver->checkSat();
    1490                 :          1 :   auto elems = d_solver->getModelDomainElements(d_uninterpreted);
    1491                 :            :   // a model for the above must interpret u as size 1
    1492 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(elems.size() == 1);
    1493 [ +  - ][ +  - ]:          1 : }
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
    1494                 :            : 
    1495                 :          4 : TEST_F(TestApiBlackSolver, isModelCoreSymbol)
    1496                 :            : {
    1497                 :          1 :   d_solver->setOption("produce-models", "true");
    1498                 :          1 :   d_solver->setOption("model-cores", "simple");
    1499                 :          1 :   Term x = d_tm.mkConst(d_uninterpreted, "x");
    1500                 :          1 :   Term y = d_tm.mkConst(d_uninterpreted, "y");
    1501                 :          1 :   Term z = d_tm.mkConst(d_uninterpreted, "z");
    1502                 :          1 :   Term zero = d_tm.mkInteger(0);
    1503                 :          6 :   Term f = d_tm.mkTerm(Kind::NOT, {d_tm.mkTerm(Kind::EQUAL, {x, y})});
    1504                 :          1 :   d_solver->assertFormula(f);
    1505                 :          1 :   d_solver->checkSat();
    1506 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(d_solver->isModelCoreSymbol(x));
    1507 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(d_solver->isModelCoreSymbol(y));
    1508 [ -  + ][ +  - ]:          1 :   ASSERT_FALSE(d_solver->isModelCoreSymbol(z));
    1509                 :          1 :   ASSERT_THROW(d_solver->isModelCoreSymbol(zero), CVC5ApiException);
    1510                 :            : 
    1511                 :          1 :   TermManager tm;
    1512                 :          1 :   Solver slv(tm);
    1513                 :          1 :   slv.setOption("produce-models", "true");
    1514                 :          1 :   slv.checkSat();
    1515                 :          3 :   ASSERT_THROW(slv.isModelCoreSymbol(d_tm.mkConst(d_uninterpreted, "x")),
    1516         [ +  - ]:          1 :                CVC5ApiException);
    1517 [ +  - ][ +  - ]:          1 : }
         [ +  - ][ +  - ]
                 [ +  - ]
    1518                 :            : 
    1519                 :          4 : TEST_F(TestApiBlackSolver, getModel)
    1520                 :            : {
    1521                 :          1 :   d_solver->setOption("produce-models", "true");
    1522                 :          1 :   Term x = d_tm.mkConst(d_uninterpreted, "x");
    1523                 :          1 :   Term y = d_tm.mkConst(d_uninterpreted, "y");
    1524                 :          1 :   Term z = d_tm.mkConst(d_uninterpreted, "z");
    1525                 :          6 :   Term f = d_tm.mkTerm(Kind::NOT, {d_tm.mkTerm(Kind::EQUAL, {x, y})});
    1526                 :          1 :   d_solver->assertFormula(f);
    1527                 :          1 :   d_solver->checkSat();
    1528                 :          3 :   std::vector<Sort> sorts{d_uninterpreted};
    1529                 :          4 :   std::vector<Term> terms{x, y};
    1530 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->getModel(sorts, terms));
         [ +  - ][ -  - ]
    1531                 :          1 :   Term null;
    1532                 :          1 :   terms.push_back(null);
    1533                 :          1 :   ASSERT_THROW(d_solver->getModel(sorts, terms), CVC5ApiException);
    1534 [ +  - ][ +  - ]:          1 : }
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
    1535                 :            : 
    1536                 :          4 : TEST_F(TestApiBlackSolver, getModel2)
    1537                 :            : {
    1538                 :          1 :   d_solver->setOption("produce-models", "true");
    1539                 :          1 :   std::vector<Sort> sorts;
    1540                 :          1 :   std::vector<Term> terms;
    1541                 :          1 :   ASSERT_THROW(d_solver->getModel(sorts, terms), CVC5ApiException);
    1542 [ +  - ][ +  - ]:          1 : }
    1543                 :            : 
    1544                 :          4 : TEST_F(TestApiBlackSolver, getModel3)
    1545                 :            : {
    1546                 :          1 :   d_solver->setOption("produce-models", "true");
    1547                 :          1 :   std::vector<Sort> sorts;
    1548                 :          1 :   std::vector<Term> terms;
    1549                 :          1 :   d_solver->checkSat();
    1550 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->getModel(sorts, terms));
         [ +  - ][ -  - ]
    1551                 :          1 :   sorts.push_back(d_int);
    1552                 :          1 :   ASSERT_THROW(d_solver->getModel(sorts, terms), CVC5ApiException);
    1553 [ +  - ][ +  - ]:          1 : }
    1554                 :            : 
    1555                 :          4 : TEST_F(TestApiBlackSolver, getQuantifierElimination)
    1556                 :            : {
    1557                 :          1 :   Term x = d_tm.mkVar(d_bool, "x");
    1558                 :            :   Term forall =
    1559                 :          2 :       d_tm.mkTerm(Kind::FORALL,
    1560                 :          1 :                   {d_tm.mkTerm(Kind::VARIABLE_LIST, {x}),
    1561                 :          8 :                    d_tm.mkTerm(Kind::OR, {x, d_tm.mkTerm(Kind::NOT, {x})})});
    1562                 :          2 :   ASSERT_THROW(d_solver->getQuantifierElimination(Term()), CVC5ApiException);
    1563                 :          2 :   ASSERT_THROW(d_solver->getQuantifierElimination(d_tm.mkBoolean(false)),
    1564         [ +  - ]:          1 :                CVC5ApiException);
    1565 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->getQuantifierElimination(forall));
         [ +  - ][ -  - ]
    1566                 :            : 
    1567                 :          1 :   TermManager tm;
    1568                 :          1 :   Solver slv(tm);
    1569                 :          1 :   slv.checkSat();
    1570                 :          1 :   ASSERT_THROW(slv.getQuantifierElimination(forall), CVC5ApiException);
    1571 [ +  - ][ +  - ]:          1 : }
    1572                 :            : 
    1573                 :          4 : TEST_F(TestApiBlackSolver, getQuantifierEliminationDisjunct)
    1574                 :            : {
    1575                 :          1 :   Term x = d_tm.mkVar(d_bool, "x");
    1576                 :            :   Term forall =
    1577                 :          2 :       d_tm.mkTerm(Kind::FORALL,
    1578                 :          1 :                   {d_tm.mkTerm(Kind::VARIABLE_LIST, {x}),
    1579                 :          8 :                    d_tm.mkTerm(Kind::OR, {x, d_tm.mkTerm(Kind::NOT, {x})})});
    1580                 :          2 :   ASSERT_THROW(d_solver->getQuantifierEliminationDisjunct(Term()),
    1581         [ +  - ]:          1 :                CVC5ApiException);
    1582                 :          2 :   ASSERT_THROW(
    1583                 :            :       d_solver->getQuantifierEliminationDisjunct(d_tm.mkBoolean(false)),
    1584         [ +  - ]:          1 :       CVC5ApiException);
    1585 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->getQuantifierEliminationDisjunct(forall));
         [ +  - ][ -  - ]
    1586                 :            : 
    1587                 :          1 :   TermManager tm;
    1588                 :          1 :   Solver slv(tm);
    1589                 :          1 :   slv.checkSat();
    1590                 :          1 :   ASSERT_THROW(slv.getQuantifierEliminationDisjunct(forall), CVC5ApiException);
    1591 [ +  - ][ +  - ]:          1 : }
    1592                 :            : 
    1593                 :          4 : TEST_F(TestApiBlackSolver, declareSepHeap)
    1594                 :            : {
    1595                 :          1 :   d_solver->setLogic("ALL");
    1596                 :          1 :   d_solver->setOption("incremental", "false");
    1597 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->declareSepHeap(d_int, d_int));
         [ +  - ][ -  - ]
    1598                 :            :   // cannot declare separation logic heap more than once
    1599                 :          1 :   ASSERT_THROW(d_solver->declareSepHeap(d_int, d_int), CVC5ApiException);
    1600                 :            : 
    1601                 :          1 :   TermManager tm;
    1602                 :            :   {
    1603                 :          1 :     Solver slv(tm);
    1604                 :            :     // no logic set yet
    1605                 :          3 :     ASSERT_THROW(slv.declareSepHeap(tm.getIntegerSort(), tm.getIntegerSort()),
    1606         [ +  - ]:          1 :                  CVC5ApiException);
    1607         [ +  - ]:          1 :   }
    1608                 :            :   {
    1609                 :          1 :     Solver slv(tm);
    1610                 :          1 :     slv.setLogic("ALL");
    1611                 :          2 :     ASSERT_THROW(slv.declareSepHeap(d_int, tm.getRealSort()), CVC5ApiException);
    1612         [ +  - ]:          1 :   }
    1613                 :            :   {
    1614                 :          1 :     Solver slv(tm);
    1615                 :          1 :     slv.setLogic("ALL");
    1616                 :          2 :     ASSERT_THROW(slv.declareSepHeap(tm.getBooleanSort(), d_int),
    1617         [ +  - ]:          1 :                  CVC5ApiException);
    1618         [ +  - ]:          1 :   }
    1619                 :            : }
    1620                 :            : 
    1621                 :            : namespace {
    1622                 :            : /**
    1623                 :            :  * Helper function for testGetSeparation{Heap,Nil}TermX. Asserts and checks
    1624                 :            :  * some simple separation logic constraints.
    1625                 :            :  */
    1626                 :          4 : void checkSimpleSeparationConstraints(Solver* solver)
    1627                 :            : {
    1628                 :          4 :   TermManager& tm = solver->getTermManager();
    1629                 :          4 :   Sort integer = tm.getIntegerSort();
    1630                 :            :   // declare the separation heap
    1631                 :          4 :   solver->declareSepHeap(integer, integer);
    1632                 :          4 :   Term x = tm.mkConst(integer, "x");
    1633                 :          4 :   Term p = tm.mkConst(integer, "p");
    1634                 :         16 :   Term heap = tm.mkTerm(cvc5::Kind::SEP_PTO, {p, x});
    1635                 :          4 :   solver->assertFormula(heap);
    1636                 :          4 :   Term nil = tm.mkSepNil(integer);
    1637                 :          4 :   solver->assertFormula(nil.eqTerm(tm.mkInteger(5)));
    1638                 :          4 :   solver->checkSat();
    1639                 :          4 : }
    1640                 :            : }  // namespace
    1641                 :            : 
    1642                 :          4 : TEST_F(TestApiBlackSolver, getValueSepHeap1)
    1643                 :            : {
    1644                 :          1 :   d_solver->setLogic("QF_BV");
    1645                 :          1 :   d_solver->setOption("incremental", "false");
    1646                 :          1 :   d_solver->setOption("produce-models", "true");
    1647                 :          1 :   Term t = d_tm.mkTrue();
    1648                 :          1 :   d_solver->assertFormula(t);
    1649                 :          1 :   ASSERT_THROW(d_solver->getValueSepHeap(), CVC5ApiException);
    1650         [ +  - ]:          1 : }
    1651                 :            : 
    1652                 :          4 : TEST_F(TestApiBlackSolver, getValueSepHeap2)
    1653                 :            : {
    1654                 :          1 :   d_solver->setLogic("ALL");
    1655                 :          1 :   d_solver->setOption("incremental", "false");
    1656                 :          1 :   d_solver->setOption("produce-models", "false");
    1657                 :          1 :   checkSimpleSeparationConstraints(d_solver.get());
    1658                 :          1 :   ASSERT_THROW(d_solver->getValueSepHeap(), CVC5ApiException);
    1659                 :            : }
    1660                 :            : 
    1661                 :          4 : TEST_F(TestApiBlackSolver, getValueSepHeap3)
    1662                 :            : {
    1663                 :          1 :   d_solver->setLogic("ALL");
    1664                 :          1 :   d_solver->setOption("incremental", "false");
    1665                 :          1 :   d_solver->setOption("produce-models", "true");
    1666                 :          1 :   Term t = d_tm.mkFalse();
    1667                 :          1 :   d_solver->assertFormula(t);
    1668                 :          1 :   d_solver->checkSat();
    1669                 :          1 :   ASSERT_THROW(d_solver->getValueSepHeap(), CVC5ApiException);
    1670         [ +  - ]:          1 : }
    1671                 :            : 
    1672                 :          4 : TEST_F(TestApiBlackSolver, getValueSepHeap4)
    1673                 :            : {
    1674                 :          1 :   d_solver->setLogic("ALL");
    1675                 :          1 :   d_solver->setOption("incremental", "false");
    1676                 :          1 :   d_solver->setOption("produce-models", "true");
    1677                 :          1 :   Term t = d_tm.mkTrue();
    1678                 :          1 :   d_solver->assertFormula(t);
    1679                 :          1 :   d_solver->checkSat();
    1680                 :          1 :   ASSERT_THROW(d_solver->getValueSepHeap(), CVC5ApiException);
    1681         [ +  - ]:          1 : }
    1682                 :            : 
    1683                 :          4 : TEST_F(TestApiBlackSolver, getValueSepHeap5)
    1684                 :            : {
    1685                 :          1 :   d_solver->setLogic("ALL");
    1686                 :          1 :   d_solver->setOption("incremental", "false");
    1687                 :          1 :   d_solver->setOption("produce-models", "true");
    1688                 :          1 :   checkSimpleSeparationConstraints(d_solver.get());
    1689 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->getValueSepHeap());
         [ +  - ][ -  - ]
    1690                 :            : }
    1691                 :            : 
    1692                 :          4 : TEST_F(TestApiBlackSolver, getValueSepNil1)
    1693                 :            : {
    1694                 :          1 :   d_solver->setLogic("QF_BV");
    1695                 :          1 :   d_solver->setOption("incremental", "false");
    1696                 :          1 :   d_solver->setOption("produce-models", "true");
    1697                 :          1 :   Term t = d_tm.mkTrue();
    1698                 :          1 :   d_solver->assertFormula(t);
    1699                 :          1 :   ASSERT_THROW(d_solver->getValueSepNil(), CVC5ApiException);
    1700         [ +  - ]:          1 : }
    1701                 :            : 
    1702                 :          4 : TEST_F(TestApiBlackSolver, getValueSepNil2)
    1703                 :            : {
    1704                 :          1 :   d_solver->setLogic("ALL");
    1705                 :          1 :   d_solver->setOption("incremental", "false");
    1706                 :          1 :   d_solver->setOption("produce-models", "false");
    1707                 :          1 :   checkSimpleSeparationConstraints(d_solver.get());
    1708                 :          1 :   ASSERT_THROW(d_solver->getValueSepNil(), CVC5ApiException);
    1709                 :            : }
    1710                 :            : 
    1711                 :          4 : TEST_F(TestApiBlackSolver, getValueSepNil3)
    1712                 :            : {
    1713                 :          1 :   d_solver->setLogic("ALL");
    1714                 :          1 :   d_solver->setOption("incremental", "false");
    1715                 :          1 :   d_solver->setOption("produce-models", "true");
    1716                 :          1 :   Term t = d_tm.mkFalse();
    1717                 :          1 :   d_solver->assertFormula(t);
    1718                 :          1 :   d_solver->checkSat();
    1719                 :          1 :   ASSERT_THROW(d_solver->getValueSepNil(), CVC5ApiException);
    1720         [ +  - ]:          1 : }
    1721                 :            : 
    1722                 :          4 : TEST_F(TestApiBlackSolver, getValueSepNil4)
    1723                 :            : {
    1724                 :          1 :   d_solver->setLogic("ALL");
    1725                 :          1 :   d_solver->setOption("incremental", "false");
    1726                 :          1 :   d_solver->setOption("produce-models", "true");
    1727                 :          1 :   Term t = d_tm.mkTrue();
    1728                 :          1 :   d_solver->assertFormula(t);
    1729                 :          1 :   d_solver->checkSat();
    1730                 :          1 :   ASSERT_THROW(d_solver->getValueSepNil(), CVC5ApiException);
    1731         [ +  - ]:          1 : }
    1732                 :            : 
    1733                 :          4 : TEST_F(TestApiBlackSolver, getValueSepNil5)
    1734                 :            : {
    1735                 :          1 :   d_solver->setLogic("ALL");
    1736                 :          1 :   d_solver->setOption("incremental", "false");
    1737                 :          1 :   d_solver->setOption("produce-models", "true");
    1738                 :          1 :   checkSimpleSeparationConstraints(d_solver.get());
    1739 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->getValueSepNil());
         [ +  - ][ -  - ]
    1740                 :            : }
    1741                 :            : 
    1742                 :          4 : TEST_F(TestApiBlackSolver, push1)
    1743                 :            : {
    1744                 :          1 :   d_solver->setOption("incremental", "true");
    1745 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->push(1));
         [ +  - ][ -  - ]
    1746                 :          5 :   ASSERT_THROW(d_solver->setOption("incremental", "false"), CVC5ApiException);
    1747                 :          5 :   ASSERT_THROW(d_solver->setOption("incremental", "true"), CVC5ApiException);
    1748                 :            : }
    1749                 :            : 
    1750                 :          4 : TEST_F(TestApiBlackSolver, push2)
    1751                 :            : {
    1752                 :          1 :   d_solver->setOption("incremental", "false");
    1753                 :          1 :   ASSERT_THROW(d_solver->push(1), CVC5ApiException);
    1754                 :            : }
    1755                 :            : 
    1756                 :          4 : TEST_F(TestApiBlackSolver, pop1)
    1757                 :            : {
    1758                 :          1 :   d_solver->setOption("incremental", "false");
    1759                 :          1 :   ASSERT_THROW(d_solver->pop(1), CVC5ApiException);
    1760                 :            : }
    1761                 :            : 
    1762                 :          4 : TEST_F(TestApiBlackSolver, pop2)
    1763                 :            : {
    1764                 :          1 :   d_solver->setOption("incremental", "true");
    1765                 :          1 :   ASSERT_THROW(d_solver->pop(1), CVC5ApiException);
    1766                 :            : }
    1767                 :            : 
    1768                 :          4 : TEST_F(TestApiBlackSolver, pop3)
    1769                 :            : {
    1770                 :          1 :   d_solver->setOption("incremental", "true");
    1771 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->push(1));
         [ +  - ][ -  - ]
    1772 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->pop(1));
         [ +  - ][ -  - ]
    1773                 :          1 :   ASSERT_THROW(d_solver->pop(1), CVC5ApiException);
    1774                 :            : }
    1775                 :            : 
    1776                 :          4 : TEST_F(TestApiBlackSolver, blockModel1)
    1777                 :            : {
    1778                 :          1 :   Term x = d_tm.mkConst(d_bool, "x");
    1779                 :          1 :   d_solver->assertFormula(x.eqTerm(x));
    1780                 :          1 :   d_solver->checkSat();
    1781                 :          1 :   ASSERT_THROW(d_solver->blockModel(modes::BlockModelsMode::LITERALS),
    1782         [ +  - ]:          1 :                CVC5ApiException);
    1783         [ +  - ]:          1 : }
    1784                 :            : 
    1785                 :          4 : TEST_F(TestApiBlackSolver, blockModel2)
    1786                 :            : {
    1787                 :          1 :   d_solver->setOption("produce-models", "true");
    1788                 :          1 :   Term x = d_tm.mkConst(d_bool, "x");
    1789                 :          1 :   d_solver->assertFormula(x.eqTerm(x));
    1790                 :          1 :   ASSERT_THROW(d_solver->blockModel(modes::BlockModelsMode::LITERALS),
    1791         [ +  - ]:          1 :                CVC5ApiException);
    1792         [ +  - ]:          1 : }
    1793                 :            : 
    1794                 :          4 : TEST_F(TestApiBlackSolver, blockModel3)
    1795                 :            : {
    1796                 :          1 :   d_solver->setOption("produce-models", "true");
    1797                 :          1 :   Term x = d_tm.mkConst(d_bool, "x");
    1798                 :          1 :   d_solver->assertFormula(x.eqTerm(x));
    1799                 :          1 :   d_solver->checkSat();
    1800 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->blockModel(modes::BlockModelsMode::LITERALS));
         [ +  - ][ -  - ]
    1801         [ +  - ]:          1 : }
    1802                 :            : 
    1803                 :          4 : TEST_F(TestApiBlackSolver, blockModelValues1)
    1804                 :            : {
    1805                 :          1 :   d_solver->setOption("produce-models", "true");
    1806                 :          1 :   Term x = d_tm.mkConst(d_bool, "x");
    1807                 :          1 :   d_solver->assertFormula(x.eqTerm(x));
    1808                 :          1 :   d_solver->checkSat();
    1809                 :          2 :   ASSERT_THROW(d_solver->blockModelValues({}), CVC5ApiException);
    1810                 :          5 :   ASSERT_THROW(d_solver->blockModelValues({Term()}), CVC5ApiException);
    1811                 :          2 :   ASSERT_NO_THROW(d_solver->blockModelValues({d_tm.mkBoolean(false)}));
    1812                 :            : 
    1813                 :          1 :   TermManager tm;
    1814                 :          1 :   Solver slv(tm);
    1815                 :          1 :   slv.setOption("produce-models", "true");
    1816                 :          1 :   slv.checkSat();
    1817                 :          5 :   ASSERT_THROW(slv.blockModelValues({d_tm.mkFalse()}), CVC5ApiException);
    1818         [ +  - ]:          1 : }
    1819                 :            : 
    1820                 :          4 : TEST_F(TestApiBlackSolver, blockModelValues2)
    1821                 :            : {
    1822                 :          1 :   d_solver->setOption("produce-models", "true");
    1823                 :          1 :   Term x = d_tm.mkConst(d_bool, "x");
    1824                 :          1 :   d_solver->assertFormula(x.eqTerm(x));
    1825                 :          1 :   d_solver->checkSat();
    1826                 :          2 :   ASSERT_NO_THROW(d_solver->blockModelValues({x}));
    1827         [ +  - ]:          1 : }
    1828                 :            : 
    1829                 :          4 : TEST_F(TestApiBlackSolver, blockModelValues3)
    1830                 :            : {
    1831                 :          1 :   Term x = d_tm.mkConst(d_bool, "x");
    1832                 :          1 :   d_solver->assertFormula(x.eqTerm(x));
    1833                 :          1 :   d_solver->checkSat();
    1834                 :          5 :   ASSERT_THROW(d_solver->blockModelValues({x}), CVC5ApiException);
    1835         [ +  - ]:          1 : }
    1836                 :            : 
    1837                 :          4 : TEST_F(TestApiBlackSolver, blockModelValues4)
    1838                 :            : {
    1839                 :          1 :   d_solver->setOption("produce-models", "true");
    1840                 :          1 :   Term x = d_tm.mkConst(d_bool, "x");
    1841                 :          1 :   d_solver->assertFormula(x.eqTerm(x));
    1842                 :          5 :   ASSERT_THROW(d_solver->blockModelValues({x}), CVC5ApiException);
    1843         [ +  - ]:          1 : }
    1844                 :            : 
    1845                 :          4 : TEST_F(TestApiBlackSolver, blockModelValues5)
    1846                 :            : {
    1847                 :          1 :   d_solver->setOption("produce-models", "true");
    1848                 :          1 :   Term x = d_tm.mkConst(d_bool, "x");
    1849                 :          1 :   d_solver->assertFormula(x.eqTerm(x));
    1850                 :          1 :   d_solver->checkSat();
    1851                 :          2 :   ASSERT_NO_THROW(d_solver->blockModelValues({x}));
    1852         [ +  - ]:          1 : }
    1853                 :            : 
    1854                 :          4 : TEST_F(TestApiBlackSolver, getInstantiations)
    1855                 :            : {
    1856                 :          3 :   Term p = d_solver->declareFun("p", {d_int}, d_bool);
    1857                 :          1 :   Term x = d_tm.mkVar(d_int, "x");
    1858                 :          3 :   Term bvl = d_tm.mkTerm(Kind::VARIABLE_LIST, {x});
    1859                 :          4 :   Term app = d_tm.mkTerm(Kind::APPLY_UF, {p, x});
    1860                 :          4 :   Term q = d_tm.mkTerm(Kind::FORALL, {bvl, app});
    1861                 :          1 :   d_solver->assertFormula(q);
    1862                 :          1 :   Term five = d_tm.mkInteger(5);
    1863                 :          6 :   Term app2 = d_tm.mkTerm(Kind::NOT, {d_tm.mkTerm(Kind::APPLY_UF, {p, five})});
    1864                 :          1 :   d_solver->assertFormula(app2);
    1865                 :          1 :   ASSERT_THROW(d_solver->getInstantiations(), CVC5ApiException);
    1866                 :          1 :   d_solver->checkSat();
    1867 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->getInstantiations());
         [ +  - ][ -  - ]
    1868 [ +  - ][ +  - ]:          1 : }
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
    1869                 :            : 
    1870                 :          4 : TEST_F(TestApiBlackSolver, setInfo)
    1871                 :            : {
    1872                 :          5 :   ASSERT_THROW(d_solver->setInfo("cvc5-lagic", "QF_BV"), CVC5ApiException);
    1873                 :          5 :   ASSERT_THROW(d_solver->setInfo("cvc2-logic", "QF_BV"), CVC5ApiException);
    1874                 :          5 :   ASSERT_THROW(d_solver->setInfo("cvc5-logic", "asdf"), CVC5ApiException);
    1875                 :            : 
    1876 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->setInfo("source", "asdf"));
         [ +  - ][ -  - ]
    1877 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->setInfo("category", "asdf"));
         [ +  - ][ -  - ]
    1878 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->setInfo("difficulty", "asdf"));
         [ +  - ][ -  - ]
    1879 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->setInfo("filename", "asdf"));
         [ +  - ][ -  - ]
    1880 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->setInfo("license", "asdf"));
         [ +  - ][ -  - ]
    1881 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->setInfo("name", "asdf"));
         [ +  - ][ -  - ]
    1882 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->setInfo("notes", "asdf"));
         [ +  - ][ -  - ]
    1883                 :            : 
    1884 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->setInfo("smt-lib-version", "2"));
         [ +  - ][ -  - ]
    1885 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->setInfo("smt-lib-version", "2.0"));
         [ +  - ][ -  - ]
    1886 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->setInfo("smt-lib-version", "2.5"));
         [ +  - ][ -  - ]
    1887 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->setInfo("smt-lib-version", "2.6"));
         [ +  - ][ -  - ]
    1888                 :          5 :   ASSERT_THROW(d_solver->setInfo("smt-lib-version", ".0"), CVC5ApiException);
    1889                 :            : 
    1890 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->setInfo("status", "sat"));
         [ +  - ][ -  - ]
    1891 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->setInfo("status", "unsat"));
         [ +  - ][ -  - ]
    1892 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->setInfo("status", "unknown"));
         [ +  - ][ -  - ]
    1893                 :          5 :   ASSERT_THROW(d_solver->setInfo("status", "asdf"), CVC5ApiException);
    1894                 :            : }
    1895                 :            : 
    1896                 :          4 : TEST_F(TestApiBlackSolver, setLogic)
    1897                 :            : {
    1898 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->setLogic("AUFLIRA"));
         [ +  - ][ -  - ]
    1899                 :          3 :   ASSERT_THROW(d_solver->setLogic("AF_BV"), CVC5ApiException);
    1900                 :          1 :   d_solver->assertFormula(d_tm.mkTrue());
    1901                 :          3 :   ASSERT_THROW(d_solver->setLogic("AUFLIRA"), CVC5ApiException);
    1902                 :            : }
    1903                 :            : 
    1904                 :          4 : TEST_F(TestApiBlackSolver, isLogicSet)
    1905                 :            : {
    1906 [ -  + ][ +  - ]:          1 :   ASSERT_FALSE(d_solver->isLogicSet());
    1907 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->setLogic("QF_BV"));
         [ +  - ][ -  - ]
    1908 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(d_solver->isLogicSet());
    1909                 :            : }
    1910                 :            : 
    1911                 :          4 : TEST_F(TestApiBlackSolver, getLogic)
    1912                 :            : {
    1913                 :          1 :   ASSERT_THROW(d_solver->getLogic(), CVC5ApiException);
    1914 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->setLogic("QF_BV"));
         [ +  - ][ -  - ]
    1915 [ -  + ][ +  - ]:          2 :   ASSERT_EQ(d_solver->getLogic(), "QF_BV");
    1916                 :            : }
    1917                 :            : 
    1918                 :          4 : TEST_F(TestApiBlackSolver, setOption)
    1919                 :            : {
    1920 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->setOption("bv-sat-solver", "cadical"));
         [ +  - ][ -  - ]
    1921                 :          5 :   ASSERT_THROW(d_solver->setOption("bv-sat-solver", "1"), CVC5ApiException);
    1922                 :          1 :   d_solver->assertFormula(d_tm.mkTrue());
    1923                 :          5 :   ASSERT_THROW(d_solver->setOption("bv-sat-solver", "cadical"),
    1924         [ +  - ]:          1 :                CVC5ApiException);
    1925                 :            : }
    1926                 :            : 
    1927                 :          4 : TEST_F(TestApiBlackSolver, resetAssertions)
    1928                 :            : {
    1929                 :          1 :   d_solver->setOption("incremental", "true");
    1930                 :            : 
    1931                 :          1 :   Sort bvSort = d_tm.mkBitVectorSort(4);
    1932                 :          1 :   Term one = d_tm.mkBitVector(4, 1);
    1933                 :          1 :   Term x = d_tm.mkConst(bvSort, "x");
    1934                 :          4 :   Term ule = d_tm.mkTerm(Kind::BITVECTOR_ULE, {x, one});
    1935                 :          4 :   Term srem = d_tm.mkTerm(Kind::BITVECTOR_SREM, {one, x});
    1936                 :          1 :   d_solver->push(4);
    1937                 :          4 :   Term slt = d_tm.mkTerm(Kind::BITVECTOR_SLT, {srem, one});
    1938                 :          1 :   d_solver->resetAssertions();
    1939 [ +  + ][ -  - ]:          3 :   d_solver->checkSatAssuming({slt, ule});
    1940                 :          1 : }
    1941                 :            : 
    1942                 :          4 : TEST_F(TestApiBlackSolver, declareSygusVar)
    1943                 :            : {
    1944                 :          1 :   d_solver->setOption("sygus", "true");
    1945                 :          3 :   Sort funSort = d_tm.mkFunctionSort({d_int}, d_bool);
    1946                 :            : 
    1947 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->declareSygusVar("", d_bool));
         [ +  - ][ -  - ]
    1948 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->declareSygusVar("", funSort));
         [ +  - ][ -  - ]
    1949 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->declareSygusVar(std::string("b"), d_bool));
         [ +  - ][ -  - ]
    1950                 :          4 :   ASSERT_THROW(d_solver->declareSygusVar("", Sort()), CVC5ApiException);
    1951                 :          4 :   ASSERT_THROW(d_solver->declareSygusVar("a", Sort()), CVC5ApiException);
    1952                 :            : 
    1953                 :          4 :   ASSERT_THROW(Solver(d_tm).declareSygusVar("", d_bool), CVC5ApiException);
    1954                 :            : 
    1955                 :          1 :   TermManager tm;
    1956                 :          1 :   Solver slv(tm);
    1957                 :          1 :   slv.setOption("sygus", "true");
    1958                 :          3 :   ASSERT_THROW(slv.declareSygusVar("", d_bool), CVC5ApiException);
    1959         [ +  - ]:          1 : }
    1960                 :            : 
    1961                 :          4 : TEST_F(TestApiBlackSolver, mkGrammar)
    1962                 :            : {
    1963                 :          1 :   Term nullTerm;
    1964                 :          1 :   Term boolTerm = d_tm.mkBoolean(true);
    1965                 :          1 :   Term boolVar = d_tm.mkVar(d_bool);
    1966                 :          1 :   Term intVar = d_tm.mkVar(d_int);
    1967                 :            : 
    1968                 :          2 :   ASSERT_NO_THROW(d_solver->mkGrammar({}, {intVar}));
    1969                 :          3 :   ASSERT_NO_THROW(d_solver->mkGrammar({boolVar}, {intVar}));
    1970                 :          3 :   ASSERT_THROW(d_solver->mkGrammar({}, {}), CVC5ApiException);
    1971                 :          6 :   ASSERT_THROW(d_solver->mkGrammar({}, {nullTerm}), CVC5ApiException);
    1972                 :          6 :   ASSERT_THROW(d_solver->mkGrammar({}, {boolTerm}), CVC5ApiException);
    1973                 :          9 :   ASSERT_THROW(d_solver->mkGrammar({boolTerm}, {intVar}), CVC5ApiException);
    1974                 :            : 
    1975                 :          1 :   TermManager tm;
    1976                 :          1 :   Solver slv(tm);
    1977                 :          2 :   Term boolVar2 = tm.mkVar(tm.getBooleanSort());
    1978                 :          2 :   Term intVar2 = tm.mkVar(tm.getIntegerSort());
    1979                 :          3 :   ASSERT_NO_THROW(slv.mkGrammar({boolVar2}, {intVar2}));
    1980                 :          9 :   ASSERT_THROW(slv.mkGrammar({boolVar}, {intVar2}), CVC5ApiException);
    1981                 :          9 :   ASSERT_THROW(slv.mkGrammar({boolVar2}, {intVar}), CVC5ApiException);
    1982 [ +  - ][ +  - ]:          1 : }
         [ +  - ][ +  - ]
    1983                 :            : 
    1984                 :          4 : TEST_F(TestApiBlackSolver, synthFun)
    1985                 :            : {
    1986                 :          1 :   d_solver->setOption("sygus", "true");
    1987                 :          1 :   Sort null;
    1988                 :            : 
    1989                 :          1 :   Term nullTerm;
    1990                 :          1 :   Term x = d_tm.mkVar(d_bool);
    1991                 :            : 
    1992                 :          1 :   Term start1 = d_tm.mkVar(d_bool);
    1993                 :          1 :   Term start2 = d_tm.mkVar(d_int);
    1994                 :            : 
    1995                 :          5 :   Grammar g1 = d_solver->mkGrammar({x}, {start1});
    1996 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->synthFun("", {}, d_bool));
         [ +  - ][ -  - ]
    1997                 :          2 :   ASSERT_NO_THROW(d_solver->synthFun("f1", {x}, d_bool));
    1998                 :          8 :   ASSERT_THROW(d_solver->synthFun("f2", {x}, d_bool, g1), CVC5ApiException);
    1999                 :          1 :   g1.addRule(start1, d_tm.mkBoolean(false));
    2000                 :            : 
    2001                 :          5 :   Grammar g2 = d_solver->mkGrammar({x}, {start2});
    2002                 :          1 :   g2.addRule(start2, d_tm.mkInteger(0));
    2003                 :            : 
    2004 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->synthFun("", {}, d_bool));
         [ +  - ][ -  - ]
    2005                 :          2 :   ASSERT_NO_THROW(d_solver->synthFun("f1", {x}, d_bool));
    2006                 :          2 :   ASSERT_NO_THROW(d_solver->synthFun("f2", {x}, d_bool, g1));
    2007                 :            : 
    2008                 :          7 :   ASSERT_THROW(d_solver->synthFun("f3", {nullTerm}, d_bool), CVC5ApiException);
    2009                 :          4 :   ASSERT_THROW(d_solver->synthFun("f4", {}, null), CVC5ApiException);
    2010                 :          8 :   ASSERT_THROW(d_solver->synthFun("f6", {x}, d_bool, g2), CVC5ApiException);
    2011                 :            : 
    2012                 :          1 :   TermManager tm;
    2013                 :          1 :   Solver slv(tm);
    2014                 :          1 :   slv.setOption("sygus", "true");
    2015                 :          2 :   Term x2 = tm.mkVar(tm.getBooleanSort());
    2016                 :          7 :   ASSERT_THROW(slv.synthFun("f1", {x2}, d_bool), CVC5ApiException);
    2017                 :          4 :   ASSERT_THROW(slv.synthFun("", {}, d_bool), CVC5ApiException);
    2018                 :          8 :   ASSERT_THROW(slv.synthFun("f1", {x}, tm.getBooleanSort()), CVC5ApiException);
    2019 [ +  - ][ +  - ]:          1 : }
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
    2020                 :            : 
    2021                 :          4 : TEST_F(TestApiBlackSolver, addSygusConstraint)
    2022                 :            : {
    2023                 :          1 :   d_solver->setOption("sygus", "true");
    2024                 :          1 :   Term nullTerm;
    2025                 :          1 :   Term boolTerm = d_tm.mkBoolean(true);
    2026                 :          1 :   Term intTerm = d_tm.mkInteger(1);
    2027                 :            : 
    2028 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->addSygusConstraint(boolTerm));
         [ +  - ][ -  - ]
    2029                 :          1 :   ASSERT_THROW(d_solver->addSygusConstraint(nullTerm), CVC5ApiException);
    2030                 :          1 :   ASSERT_THROW(d_solver->addSygusConstraint(intTerm), CVC5ApiException);
    2031                 :            : 
    2032                 :          1 :   TermManager tm;
    2033                 :          1 :   Solver slv(tm);
    2034                 :          1 :   slv.setOption("sygus", "true");
    2035                 :          1 :   ASSERT_THROW(slv.addSygusConstraint(boolTerm), CVC5ApiException);
    2036 [ +  - ][ +  - ]:          1 : }
                 [ +  - ]
    2037                 :            : 
    2038                 :          4 : TEST_F(TestApiBlackSolver, getSygusConstraints)
    2039                 :            : {
    2040                 :          1 :   d_solver->setOption("sygus", "true");
    2041                 :          1 :   Term trueTerm = d_tm.mkBoolean(true);
    2042                 :          1 :   Term falseTerm = d_tm.mkBoolean(false);
    2043                 :          1 :   d_solver->addSygusConstraint(trueTerm);
    2044                 :          1 :   d_solver->addSygusConstraint(falseTerm);
    2045                 :          4 :   std::vector<Term> constraints{trueTerm, falseTerm};
    2046 [ -  + ][ +  - ]:          2 :   ASSERT_EQ(d_solver->getSygusConstraints(), constraints);
    2047 [ +  - ][ +  - ]:          1 : }
                 [ +  - ]
    2048                 :            : 
    2049                 :          4 : TEST_F(TestApiBlackSolver, addSygusAssume)
    2050                 :            : {
    2051                 :          1 :   d_solver->setOption("sygus", "true");
    2052                 :          1 :   Term nullTerm;
    2053                 :          1 :   Term boolTerm = d_tm.mkBoolean(false);
    2054                 :          1 :   Term intTerm = d_tm.mkInteger(1);
    2055                 :            : 
    2056 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->addSygusAssume(boolTerm));
         [ +  - ][ -  - ]
    2057                 :          1 :   ASSERT_THROW(d_solver->addSygusAssume(nullTerm), CVC5ApiException);
    2058                 :          1 :   ASSERT_THROW(d_solver->addSygusAssume(intTerm), CVC5ApiException);
    2059                 :            : 
    2060                 :          1 :   TermManager tm;
    2061                 :          1 :   Solver slv(tm);
    2062                 :          1 :   slv.setOption("sygus", "true");
    2063                 :          1 :   ASSERT_THROW(slv.addSygusAssume(boolTerm), CVC5ApiException);
    2064 [ +  - ][ +  - ]:          1 : }
                 [ +  - ]
    2065                 :            : 
    2066                 :          4 : TEST_F(TestApiBlackSolver, getSygusAssumptions)
    2067                 :            : {
    2068                 :          1 :   d_solver->setOption("sygus", "true");
    2069                 :          1 :   Term trueTerm = d_tm.mkBoolean(true);
    2070                 :          1 :   Term falseTerm = d_tm.mkBoolean(false);
    2071                 :          1 :   d_solver->addSygusAssume(trueTerm);
    2072                 :          1 :   d_solver->addSygusAssume(falseTerm);
    2073                 :          4 :   std::vector<Term> assumptions{trueTerm, falseTerm};
    2074 [ -  + ][ +  - ]:          2 :   ASSERT_EQ(d_solver->getSygusAssumptions(), assumptions);
    2075 [ +  - ][ +  - ]:          1 : }
                 [ +  - ]
    2076                 :            : 
    2077                 :          4 : TEST_F(TestApiBlackSolver, addSygusInvConstraint)
    2078                 :            : {
    2079                 :          1 :   d_solver->setOption("sygus", "true");
    2080                 :            : 
    2081                 :          1 :   Term nullTerm;
    2082                 :          1 :   Term intTerm = d_tm.mkInteger(1);
    2083                 :            : 
    2084                 :          3 :   Term inv = d_solver->declareFun("inv", {d_real}, d_bool);
    2085                 :          3 :   Term pre = d_solver->declareFun("pre", {d_real}, d_bool);
    2086                 :          4 :   Term trans = d_solver->declareFun("trans", {d_real, d_real}, d_bool);
    2087                 :          3 :   Term post = d_solver->declareFun("post", {d_real}, d_bool);
    2088                 :            : 
    2089                 :          3 :   Term inv1 = d_solver->declareFun("inv1", {d_real}, d_real);
    2090                 :            : 
    2091                 :          4 :   Term trans1 = d_solver->declareFun("trans1", {d_bool, d_real}, d_bool);
    2092                 :          4 :   Term trans2 = d_solver->declareFun("trans2", {d_real, d_bool}, d_bool);
    2093                 :          4 :   Term trans3 = d_solver->declareFun("trans3", {d_real, d_real}, d_real);
    2094                 :            : 
    2095 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->addSygusInvConstraint(inv, pre, trans, post));
         [ +  - ][ -  - ]
    2096                 :            : 
    2097                 :          1 :   ASSERT_THROW(d_solver->addSygusInvConstraint(nullTerm, pre, trans, post),
    2098         [ +  - ]:          1 :                CVC5ApiException);
    2099                 :          1 :   ASSERT_THROW(d_solver->addSygusInvConstraint(inv, nullTerm, trans, post),
    2100         [ +  - ]:          1 :                CVC5ApiException);
    2101                 :          1 :   ASSERT_THROW(d_solver->addSygusInvConstraint(inv, pre, nullTerm, post),
    2102         [ +  - ]:          1 :                CVC5ApiException);
    2103                 :          1 :   ASSERT_THROW(d_solver->addSygusInvConstraint(inv, pre, trans, nullTerm),
    2104         [ +  - ]:          1 :                CVC5ApiException);
    2105                 :            : 
    2106                 :          1 :   ASSERT_THROW(d_solver->addSygusInvConstraint(intTerm, pre, trans, post),
    2107         [ +  - ]:          1 :                CVC5ApiException);
    2108                 :            : 
    2109                 :          1 :   ASSERT_THROW(d_solver->addSygusInvConstraint(inv1, pre, trans, post),
    2110         [ +  - ]:          1 :                CVC5ApiException);
    2111                 :            : 
    2112                 :          1 :   ASSERT_THROW(d_solver->addSygusInvConstraint(inv, trans, trans, post),
    2113         [ +  - ]:          1 :                CVC5ApiException);
    2114                 :            : 
    2115                 :          1 :   ASSERT_THROW(d_solver->addSygusInvConstraint(inv, pre, intTerm, post),
    2116         [ +  - ]:          1 :                CVC5ApiException);
    2117                 :          1 :   ASSERT_THROW(d_solver->addSygusInvConstraint(inv, pre, pre, post),
    2118         [ +  - ]:          1 :                CVC5ApiException);
    2119                 :          1 :   ASSERT_THROW(d_solver->addSygusInvConstraint(inv, pre, trans1, post),
    2120         [ +  - ]:          1 :                CVC5ApiException);
    2121                 :          1 :   ASSERT_THROW(d_solver->addSygusInvConstraint(inv, pre, trans2, post),
    2122         [ +  - ]:          1 :                CVC5ApiException);
    2123                 :          1 :   ASSERT_THROW(d_solver->addSygusInvConstraint(inv, pre, trans3, post),
    2124         [ +  - ]:          1 :                CVC5ApiException);
    2125                 :            : 
    2126                 :          1 :   ASSERT_THROW(d_solver->addSygusInvConstraint(inv, pre, trans, trans),
    2127         [ +  - ]:          1 :                CVC5ApiException);
    2128                 :            : 
    2129                 :          1 :   TermManager tm;
    2130                 :          1 :   Solver slv(tm);
    2131                 :          1 :   slv.setOption("sygus", "true");
    2132                 :          1 :   Sort boolean2 = tm.getBooleanSort();
    2133                 :          1 :   Sort real2 = tm.getRealSort();
    2134                 :          3 :   Term inv22 = slv.declareFun("inv", {real2}, boolean2);
    2135                 :          3 :   Term pre22 = slv.declareFun("pre", {real2}, boolean2);
    2136                 :          4 :   Term trans22 = slv.declareFun("trans", {real2, real2}, boolean2);
    2137                 :          3 :   Term post22 = slv.declareFun("post", {real2}, boolean2);
    2138 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(slv.addSygusInvConstraint(inv22, pre22, trans22, post22));
         [ +  - ][ -  - ]
    2139                 :          1 :   ASSERT_THROW(slv.addSygusInvConstraint(inv, pre22, trans22, post22),
    2140         [ +  - ]:          1 :                CVC5ApiException);
    2141                 :          1 :   ASSERT_THROW(slv.addSygusInvConstraint(inv22, pre, trans22, post22),
    2142         [ +  - ]:          1 :                CVC5ApiException);
    2143                 :          1 :   ASSERT_THROW(slv.addSygusInvConstraint(inv22, pre22, trans, post22),
    2144         [ +  - ]:          1 :                CVC5ApiException);
    2145                 :          1 :   ASSERT_THROW(slv.addSygusInvConstraint(inv22, pre22, trans22, post),
    2146         [ +  - ]:          1 :                CVC5ApiException);
    2147 [ +  - ][ +  - ]:          1 : }
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
    2148                 :            : 
    2149                 :          4 : TEST_F(TestApiBlackSolver, checkSynth)
    2150                 :            : {
    2151                 :            :   // requires option to be set
    2152                 :          1 :   ASSERT_THROW(d_solver->checkSynth(), CVC5ApiException);
    2153                 :          1 :   d_solver->setOption("sygus", "true");
    2154 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->checkSynth());
         [ +  - ][ -  - ]
    2155                 :            : }
    2156                 :            : 
    2157                 :          4 : TEST_F(TestApiBlackSolver, getSynthSolution)
    2158                 :            : {
    2159                 :          1 :   d_solver->setOption("sygus", "true");
    2160                 :          1 :   d_solver->setOption("incremental", "false");
    2161                 :            : 
    2162                 :          1 :   Term nullTerm;
    2163                 :          1 :   Term x = d_tm.mkBoolean(false);
    2164                 :          2 :   Term f = d_solver->synthFun("f", {}, d_bool);
    2165                 :            : 
    2166                 :          1 :   ASSERT_THROW(d_solver->getSynthSolution(f), CVC5ApiException);
    2167                 :            : 
    2168                 :          1 :   cvc5::SynthResult sr = d_solver->checkSynth();
    2169 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(sr.hasSolution());
    2170                 :            : 
    2171 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->getSynthSolution(f));
         [ +  - ][ -  - ]
    2172 [ +  - ][ +  - ]:          1 :   ASSERT_NO_THROW(d_solver->getSynthSolution(f));
         [ +  - ][ -  - ]
    2173                 :            : 
    2174                 :          1 :   ASSERT_THROW(d_solver->getSynthSolution(nullTerm), CVC5ApiException);
    2175                 :          1 :   ASSERT_THROW(d_solver->getSynthSolution(x), CVC5ApiException);
    2176                 :            : 
    2177                 :          2 :   ASSERT_THROW(Solver(d_tm).getSynthSolution(f), CVC5ApiException);
    2178 [ +  - ][ +  - ]:          1 : }
                 [ +  - ]
    2179                 :            : 
    2180                 :          4 : TEST_F(TestApiBlackSolver, getSynthSolutions)
    2181                 :            : {
    2182                 :          1 :   d_solver->setOption("sygus", "true");
    2183                 :          1 :   d_solver->setOption("incremental", "false");
    2184                 :            : 
    2185                 :          1 :   Term nullTerm;
    2186                 :          1 :   Term x = d_tm.mkBoolean(false);
    2187                 :          2 :   Term f = d_solver->synthFun("f", {}, d_bool);
    2188                 :            : 
    2189                 :          2 :   ASSERT_THROW(d_solver->getSynthSolutions({}), CVC5ApiException);
    2190                 :          5 :   ASSERT_THROW(d_solver->getSynthSolutions({f}), CVC5ApiException);
    2191                 :            : 
    2192                 :          1 :   d_solver->checkSynth();
    2193                 :            : 
    2194                 :          2 :   ASSERT_NO_THROW(d_solver->getSynthSolutions({f}));
    2195                 :          3 :   ASSERT_NO_THROW(d_solver->getSynthSolutions({f, f}));
    2196                 :            : 
    2197                 :          2 :   ASSERT_THROW(d_solver->getSynthSolutions({}), CVC5ApiException);
    2198                 :          5 :   ASSERT_THROW(d_solver->getSynthSolutions({nullTerm}), CVC5ApiException);
    2199                 :          5 :   ASSERT_THROW(d_solver->getSynthSolutions({x}), CVC5ApiException);
    2200                 :            : 
    2201                 :          6 :   ASSERT_THROW(Solver(d_tm).getSynthSolutions({x}), CVC5ApiException);
    2202 [ +  - ][ +  - ]:          1 : }
                 [ +  - ]
    2203                 :            : 
    2204                 :          4 : TEST_F(TestApiBlackSolver, checkSynthNext)
    2205                 :            : {
    2206                 :          1 :   d_solver->setOption("sygus", "true");
    2207                 :          1 :   d_solver->setOption("incremental", "true");
    2208                 :          2 :   Term f = d_solver->synthFun("f", {}, d_bool);
    2209                 :            : 
    2210                 :          1 :   cvc5::SynthResult sr = d_solver->checkSynth();
    2211 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(sr.hasSolution());
    2212                 :          2 :   ASSERT_NO_THROW(d_solver->getSynthSolutions({f}));
    2213                 :          1 :   sr = d_solver->checkSynthNext();
    2214 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(sr.hasSolution());
    2215                 :          2 :   ASSERT_NO_THROW(d_solver->getSynthSolutions({f}));
    2216 [ +  - ][ +  - ]:          1 : }
    2217                 :            : 
    2218                 :          4 : TEST_F(TestApiBlackSolver, checkSynthNext2)
    2219                 :            : {
    2220                 :          1 :   d_solver->setOption("sygus", "true");
    2221                 :          1 :   d_solver->setOption("incremental", "false");
    2222                 :          1 :   (void)d_solver->synthFun("f", {}, d_bool);
    2223                 :          1 :   d_solver->checkSynth();
    2224                 :          1 :   ASSERT_THROW(d_solver->checkSynthNext(), CVC5ApiException);
    2225                 :            : }
    2226                 :            : 
    2227                 :          4 : TEST_F(TestApiBlackSolver, checkSynthNext3)
    2228                 :            : {
    2229                 :          1 :   d_solver->setOption("sygus", "true");
    2230                 :          1 :   d_solver->setOption("incremental", "true");
    2231                 :          1 :   (void)d_solver->synthFun("f", {}, d_bool);
    2232                 :          1 :   ASSERT_THROW(d_solver->checkSynthNext(), CVC5ApiException);
    2233                 :            : }
    2234                 :            : 
    2235                 :          4 : TEST_F(TestApiBlackSolver, findSynth)
    2236                 :            : {
    2237                 :          1 :   d_solver->setOption("sygus", "true");
    2238                 :          1 :   Term start = d_tm.mkVar(d_bool);
    2239                 :          3 :   Grammar g = d_solver->mkGrammar({}, {start});
    2240                 :          5 :   ASSERT_THROW(d_solver->synthFun("f", {}, d_bool, g), CVC5ApiException);
    2241                 :            : 
    2242                 :          1 :   Term truen = d_tm.mkBoolean(true);
    2243                 :          1 :   Term falsen = d_tm.mkBoolean(false);
    2244                 :          1 :   g.addRule(start, truen);
    2245                 :          1 :   g.addRule(start, falsen);
    2246                 :          1 :   (void)d_solver->synthFun("f", {}, d_bool, g);
    2247                 :            : 
    2248                 :            :   // should enumerate based on the grammar of the function to synthesize above
    2249                 :          1 :   cvc5::Term t = d_solver->findSynth(modes::FindSynthTarget::ENUM);
    2250 [ +  - ][ +  - ]:          2 :   ASSERT_TRUE(!t.isNull() && t.getSort().isBoolean());
         [ +  - ][ -  + ]
         [ +  - ][ -  - ]
    2251 [ +  - ][ +  - ]:          1 : }
    2252                 :            : 
    2253                 :          4 : TEST_F(TestApiBlackSolver, findSynth2)
    2254                 :            : {
    2255                 :          1 :   d_solver->setOption("sygus", "true");
    2256                 :          1 :   d_solver->setOption("incremental", "true");
    2257                 :          1 :   Term start = d_tm.mkVar(d_bool);
    2258                 :          3 :   Grammar g = d_solver->mkGrammar({}, {start});
    2259                 :          1 :   Term truen = d_tm.mkBoolean(true);
    2260                 :          1 :   Term falsen = d_tm.mkBoolean(false);
    2261                 :          1 :   g.addRule(start, truen);
    2262                 :          1 :   g.addRule(start, falsen);
    2263                 :            : 
    2264                 :            :   // should enumerate true/false
    2265                 :          1 :   cvc5::Term t = d_solver->findSynth(modes::FindSynthTarget::ENUM, g);
    2266 [ +  - ][ +  - ]:          2 :   ASSERT_TRUE(!t.isNull() && t.getSort().isBoolean());
         [ +  - ][ -  + ]
         [ +  - ][ -  - ]
    2267                 :          1 :   t = d_solver->findSynthNext();
    2268 [ +  - ][ +  - ]:          2 :   ASSERT_TRUE(!t.isNull() && t.getSort().isBoolean());
         [ +  - ][ -  + ]
         [ +  - ][ -  - ]
    2269 [ +  - ][ +  - ]:          1 : }
         [ +  - ][ +  - ]
                 [ +  - ]
    2270                 :            : 
    2271                 :          4 : TEST_F(TestApiBlackSolver, tupleProject)
    2272                 :            : {
    2273                 :            :   std::vector<Term> elements = {
    2274                 :            :       d_tm.mkBoolean(true),
    2275                 :            :       d_tm.mkInteger(3),
    2276                 :            :       d_tm.mkString("C"),
    2277                 :          9 :       d_tm.mkTerm(Kind::SET_SINGLETON, {d_tm.mkString("Z")})};
    2278                 :            : 
    2279                 :          1 :   Term tuple = d_tm.mkTuple(elements);
    2280                 :            : 
    2281                 :          1 :   std::vector<uint32_t> indices1 = {};
    2282                 :          1 :   std::vector<uint32_t> indices2 = {0};
    2283                 :          1 :   std::vector<uint32_t> indices3 = {0, 1};
    2284                 :          1 :   std::vector<uint32_t> indices4 = {0, 0, 2, 2, 3, 3, 0};
    2285                 :          1 :   std::vector<uint32_t> indices5 = {4};
    2286                 :          1 :   std::vector<uint32_t> indices6 = {0, 4};
    2287                 :            : 
    2288                 :          2 :   ASSERT_NO_THROW(
    2289         [ +  - ]:          1 :       d_tm.mkTerm(d_tm.mkOp(Kind::TUPLE_PROJECT, indices1), {tuple}));
    2290                 :          2 :   ASSERT_NO_THROW(
    2291         [ +  - ]:          1 :       d_tm.mkTerm(d_tm.mkOp(Kind::TUPLE_PROJECT, indices2), {tuple}));
    2292                 :          2 :   ASSERT_NO_THROW(
    2293         [ +  - ]:          1 :       d_tm.mkTerm(d_tm.mkOp(Kind::TUPLE_PROJECT, indices3), {tuple}));
    2294                 :          2 :   ASSERT_NO_THROW(
    2295         [ +  - ]:          1 :       d_tm.mkTerm(d_tm.mkOp(Kind::TUPLE_PROJECT, indices4), {tuple}));
    2296                 :            : 
    2297                 :          6 :   ASSERT_THROW(d_tm.mkTerm(d_tm.mkOp(Kind::TUPLE_PROJECT, indices5), {tuple}),
    2298         [ +  - ]:          1 :                CVC5ApiException);
    2299                 :          6 :   ASSERT_THROW(d_tm.mkTerm(d_tm.mkOp(Kind::TUPLE_PROJECT, indices6), {tuple}),
    2300         [ +  - ]:          1 :                CVC5ApiException);
    2301                 :            : 
    2302                 :          1 :   std::vector<uint32_t> indices = {0, 3, 2, 0, 1, 2};
    2303                 :            : 
    2304                 :          1 :   Op op = d_tm.mkOp(Kind::TUPLE_PROJECT, indices);
    2305                 :          3 :   Term projection = d_tm.mkTerm(op, {tuple});
    2306                 :            : 
    2307                 :          1 :   Datatype datatype = tuple.getSort().getDatatype();
    2308                 :          1 :   DatatypeConstructor constructor = datatype[0];
    2309                 :            : 
    2310         [ +  + ]:          7 :   for (size_t i = 0; i < indices.size(); i++)
    2311                 :            :   {
    2312                 :          6 :     Term selectorTerm = constructor[indices[i]].getTerm();
    2313                 :            :     Term selectedTerm =
    2314                 :         24 :         d_tm.mkTerm(Kind::APPLY_SELECTOR, {selectorTerm, tuple});
    2315                 :          6 :     Term simplifiedTerm = d_solver->simplify(selectedTerm);
    2316 [ -  + ][ +  - ]:          6 :     ASSERT_EQ(elements[indices[i]], simplifiedTerm);
    2317 [ +  - ][ +  - ]:          6 :   }
                 [ +  - ]
    2318                 :            : 
    2319         [ -  + ]:          2 :   ASSERT_EQ(
    2320                 :            :       "((_ tuple.project 0 3 2 0 1 2) (tuple true 3 \"C\" (set.singleton "
    2321                 :            :       "\"Z\")))",
    2322         [ +  - ]:          1 :       projection.toString());
    2323 [ +  - ][ +  - ]:          1 : }
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
    2324                 :            : 
    2325                 :          4 : TEST_F(TestApiBlackSolver, output)
    2326                 :            : {
    2327                 :          3 :   ASSERT_THROW(d_solver->isOutputOn("foo-invalid"), CVC5ApiException);
    2328                 :          3 :   ASSERT_THROW(d_solver->getOutput("foo-invalid"), CVC5ApiException);
    2329 [ -  + ][ +  - ]:          1 :   ASSERT_FALSE(d_solver->isOutputOn("inst"));
    2330 [ -  + ][ +  - ]:          1 :   ASSERT_EQ(null_os.rdbuf(), d_solver->getOutput("inst").rdbuf());
    2331                 :          1 :   d_solver->setOption("output", "inst");
    2332 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(d_solver->isOutputOn("inst"));
    2333 [ -  + ][ +  - ]:          1 :   ASSERT_NE(null_os.rdbuf(), d_solver->getOutput("inst").rdbuf());
    2334                 :            : }
    2335                 :            : 
    2336                 :          4 : TEST_F(TestApiBlackSolver, getDatatypeArity)
    2337                 :            : {
    2338                 :          2 :   DatatypeConstructorDecl ctor1 = d_tm.mkDatatypeConstructorDecl("_x21");
    2339                 :          2 :   DatatypeConstructorDecl ctor2 = d_tm.mkDatatypeConstructorDecl("_x31");
    2340                 :          4 :   Sort s3 = d_solver->declareDatatype(std::string("_x17"), {ctor1, ctor2});
    2341 [ -  + ][ +  - ]:          1 :   ASSERT_EQ(s3.getDatatypeArity(), 0);
    2342 [ +  - ][ +  - ]:          1 : }
                 [ +  - ]
    2343                 :            : 
    2344                 :          4 : TEST_F(TestApiBlackSolver, declareOracleFunError)
    2345                 :            : {
    2346                 :            :   // cannot declare without option
    2347                 :          8 :   ASSERT_THROW(d_solver->declareOracleFun(
    2348                 :            :       "f",
    2349                 :            :       {d_int},
    2350                 :            :       d_int,
    2351                 :            :       [&](const std::vector<Term>&) { return d_tm.mkInteger(0); });
    2352         [ +  - ]:          1 :                , CVC5ApiException);
    2353                 :          1 :   d_solver->setOption("oracles", "true");
    2354                 :          1 :   Sort nullSort;
    2355                 :            :   // bad sort
    2356                 :          8 :   ASSERT_THROW(d_solver->declareOracleFun(
    2357                 :            :       "f",
    2358                 :            :       {nullSort},
    2359                 :            :       d_int,
    2360                 :            :       [&](const std::vector<Term>&) { return d_tm.mkInteger(0); });
    2361         [ +  - ]:          1 :                , CVC5ApiException);
    2362                 :            : }
    2363                 :            : 
    2364                 :          4 : TEST_F(TestApiBlackSolver, declareOracleFunUnsat)
    2365                 :            : {
    2366                 :          1 :   d_solver->setOption("oracles", "true");
    2367                 :            :   // f is the function implementing (lambda ((x Int)) (+ x 1))
    2368                 :          1 :   Term f = d_solver->declareOracleFun(
    2369                 :          2 :       "f", {d_int}, d_int, [&](const std::vector<Term>& input) {
    2370         [ +  - ]:          1 :         if (input[0].isUInt32Value())
    2371                 :            :         {
    2372                 :          1 :           return d_tm.mkInteger(input[0].getUInt32Value() + 1);
    2373                 :            :         }
    2374                 :          0 :         return d_tm.mkInteger(0);
    2375                 :          3 :       });
    2376                 :          1 :   Term three = d_tm.mkInteger(3);
    2377                 :          1 :   Term five = d_tm.mkInteger(5);
    2378                 :            :   Term eq =
    2379                 :          7 :       d_tm.mkTerm(Kind::EQUAL, {d_tm.mkTerm(Kind::APPLY_UF, {f, three}), five});
    2380                 :          1 :   d_solver->assertFormula(eq);
    2381                 :            :   // (f 3) = 5
    2382 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(d_solver->checkSat().isUnsat());
    2383                 :            : 
    2384                 :          1 :   TermManager tm;
    2385                 :          1 :   Solver slv(tm);
    2386                 :          1 :   slv.setOption("oracles", "true");
    2387                 :          1 :   Sort iiSort = tm.getIntegerSort();
    2388         [ -  - ]:          8 :   ASSERT_THROW(slv.declareOracleFun("f",
    2389                 :            :                                     {iiSort},
    2390                 :            :                                     d_int,
    2391                 :            :                                     [&](const std::vector<Term>& input) {
    2392                 :            :                                       if (input[0].isUInt32Value())
    2393                 :            :                                       {
    2394                 :            :                                         return tm.mkInteger(
    2395                 :            :                                             input[0].getUInt32Value() + 1);
    2396                 :            :                                       }
    2397                 :            :                                       return tm.mkInteger(0);
    2398                 :            :                                     }),
    2399         [ +  - ]:          1 :                CVC5ApiException);
    2400         [ -  - ]:          8 :   ASSERT_THROW(slv.declareOracleFun("f",
    2401                 :            :                                     {d_int},
    2402                 :            :                                     iiSort,
    2403                 :            :                                     [&](const std::vector<Term>& input) {
    2404                 :            :                                       if (input[0].isUInt32Value())
    2405                 :            :                                       {
    2406                 :            :                                         return tm.mkInteger(
    2407                 :            :                                             input[0].getUInt32Value() + 1);
    2408                 :            :                                       }
    2409                 :            :                                       return tm.mkInteger(0);
    2410                 :            :                                     }),
    2411         [ +  - ]:          1 :                CVC5ApiException);
    2412                 :            :   // this cannot be caught during declaration, is caught during check-sat
    2413                 :          1 :   Term f2 = slv.declareOracleFun(
    2414                 :          1 :       "f2", {iiSort}, iiSort, [&](const std::vector<Term>& input) {
    2415         [ +  - ]:          1 :         if (input[0].isUInt32Value())
    2416                 :            :         {
    2417                 :          1 :           return d_tm.mkInteger(input[0].getUInt32Value() + 1);
    2418                 :            :         }
    2419                 :          0 :         return d_tm.mkInteger(0);
    2420                 :          3 :       });
    2421                 :          2 :   Term eq2 = tm.mkTerm(
    2422                 :            :       Kind::EQUAL,
    2423                 :          5 :       {tm.mkTerm(Kind::APPLY_UF, {f2, tm.mkInteger(3)}), tm.mkInteger(5)});
    2424                 :          1 :   slv.assertFormula(eq2);
    2425                 :          1 :   ASSERT_THROW(slv.checkSat(), CVC5ApiException);
    2426 [ +  - ][ +  - ]:          1 : }
         [ +  - ][ +  - ]
    2427                 :            : 
    2428                 :          4 : TEST_F(TestApiBlackSolver, declareOracleFunSat)
    2429                 :            : {
    2430                 :          1 :   d_solver->setOption("oracles", "true");
    2431                 :          1 :   d_solver->setOption("produce-models", "true");
    2432                 :            :   // f is the function implementing (lambda ((x Int)) (% x 10))
    2433                 :          1 :   Term f = d_solver->declareOracleFun(
    2434                 :          9 :       "f", {d_int}, d_int, [&](const std::vector<Term>& input) {
    2435         [ +  - ]:          8 :         if (input[0].isUInt32Value())
    2436                 :            :         {
    2437                 :          8 :           return d_tm.mkInteger(input[0].getUInt32Value() % 10);
    2438                 :            :         }
    2439                 :          0 :         return d_tm.mkInteger(0);
    2440                 :          3 :       });
    2441                 :          1 :   Term seven = d_tm.mkInteger(7);
    2442                 :          1 :   Term x = d_tm.mkConst(d_int, "x");
    2443                 :          4 :   Term lb = d_tm.mkTerm(Kind::GEQ, {x, d_tm.mkInteger(0)});
    2444                 :          1 :   d_solver->assertFormula(lb);
    2445                 :          4 :   Term ub = d_tm.mkTerm(Kind::LEQ, {x, d_tm.mkInteger(100)});
    2446                 :          1 :   d_solver->assertFormula(ub);
    2447                 :            :   Term eq =
    2448                 :          7 :       d_tm.mkTerm(Kind::EQUAL, {d_tm.mkTerm(Kind::APPLY_UF, {f, x}), seven});
    2449                 :          1 :   d_solver->assertFormula(eq);
    2450                 :            :   // x >= 0 ^ x <= 100 ^ (f x) = 7
    2451 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(d_solver->checkSat().isSat());
    2452                 :          1 :   Term xval = d_solver->getValue(x);
    2453 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(xval.isUInt32Value());
    2454 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(xval.getUInt32Value() % 10 == 7);
    2455 [ +  - ][ +  - ]:          1 : }
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
    2456                 :            : 
    2457                 :          4 : TEST_F(TestApiBlackSolver, declareOracleFunSat2)
    2458                 :            : {
    2459                 :          1 :   d_solver->setOption("oracles", "true");
    2460                 :          1 :   d_solver->setOption("produce-models", "true");
    2461                 :            :   // f is the function implementing (lambda ((x Int) (y Int)) (= x y))
    2462                 :          2 :   Term eq = d_solver->declareOracleFun(
    2463                 :          4 :       "eq", {d_int, d_int}, d_bool, [&](const std::vector<Term>& input) {
    2464                 :          2 :         return d_tm.mkBoolean(input[0] == input[1]);
    2465                 :          3 :       });
    2466                 :          1 :   Term x = d_tm.mkConst(d_int, "x");
    2467                 :          1 :   Term y = d_tm.mkConst(d_int, "y");
    2468                 :          7 :   Term neq = d_tm.mkTerm(Kind::NOT, {d_tm.mkTerm(Kind::APPLY_UF, {eq, x, y})});
    2469                 :          1 :   d_solver->assertFormula(neq);
    2470                 :            :   // (not (eq x y))
    2471 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(d_solver->checkSat().isSat());
    2472                 :          1 :   Term xval = d_solver->getValue(x);
    2473                 :          1 :   Term yval = d_solver->getValue(y);
    2474 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(xval != yval);
    2475 [ +  - ][ +  - ]:          1 : }
         [ +  - ][ +  - ]
    2476                 :            : 
    2477                 :            : class PluginUnsat : public Plugin
    2478                 :            : {
    2479                 :            :  public:
    2480                 :          1 :   PluginUnsat(TermManager& tm) : Plugin(tm), d_tm(tm) {}
    2481                 :          1 :   virtual ~PluginUnsat() {}
    2482                 :          1 :   std::vector<Term> check() override
    2483                 :            :   {
    2484                 :          1 :     std::vector<Term> lemmas;
    2485                 :            :     // add the "false" lemma.
    2486                 :          1 :     Term flem = d_tm.mkBoolean(false);
    2487                 :          1 :     lemmas.push_back(flem);
    2488                 :          2 :     return lemmas;
    2489                 :          1 :   }
    2490                 :          2 :   std::string getName() override { return "PluginUnsat"; }
    2491                 :            : 
    2492                 :            :  private:
    2493                 :            :   /** Reference to the term manager */
    2494                 :            :   TermManager& d_tm;
    2495                 :            : };
    2496                 :            : 
    2497                 :          4 : TEST_F(TestApiBlackSolver, pluginUnsat)
    2498                 :            : {
    2499                 :          1 :   PluginUnsat pu(d_tm);
    2500                 :          1 :   d_solver->addPlugin(pu);
    2501 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(pu.getName() == "PluginUnsat");
    2502                 :            :   // should be unsat since the plugin above asserts "false" as a lemma
    2503 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(d_solver->checkSat().isUnsat());
    2504         [ +  - ]:          1 : }
    2505                 :            : 
    2506                 :            : class PluginListen : public Plugin
    2507                 :            : {
    2508                 :            :  public:
    2509                 :          2 :   PluginListen(TermManager& tm)
    2510                 :          2 :       : Plugin(tm), d_hasSeenTheoryLemma(false), d_hasSeenSatClause(false)
    2511                 :            :   {
    2512                 :          2 :   }
    2513                 :          2 :   virtual ~PluginListen() {}
    2514                 :          4 :   void notifySatClause(const Term& cl) override
    2515                 :            :   {
    2516                 :          4 :     Plugin::notifySatClause(cl);  // Cover default implementation
    2517                 :          4 :     d_hasSeenSatClause = true;
    2518                 :          4 :   }
    2519                 :          2 :   bool hasSeenSatClause() const { return d_hasSeenSatClause; }
    2520                 :         10 :   void notifyTheoryLemma(const Term& lem) override
    2521                 :            :   {
    2522                 :         10 :     Plugin::notifyTheoryLemma(lem);  // Cover default implementation
    2523                 :         10 :     d_hasSeenTheoryLemma = true;
    2524                 :         10 :   }
    2525                 :          2 :   bool hasSeenTheoryLemma() const { return d_hasSeenTheoryLemma; }
    2526                 :          2 :   std::string getName() override { return "PluginListen"; }
    2527                 :            : 
    2528                 :            :  private:
    2529                 :            :   /** have we seen a theory lemma? */
    2530                 :            :   bool d_hasSeenTheoryLemma;
    2531                 :            :   /** have we seen a SAT clause? */
    2532                 :            :   bool d_hasSeenSatClause;
    2533                 :            : };
    2534                 :            : 
    2535                 :          4 : TEST_F(TestApiBlackSolver, pluginListen)
    2536                 :            : {
    2537                 :            :   // NOTE: this shouldn't be necessary but ensures notifySatClause is called
    2538                 :            :   // here.
    2539                 :          1 :   d_solver->setOption("plugin-notify-sat-clause-in-solve", "false");
    2540                 :          1 :   PluginListen pl(d_tm);
    2541                 :          1 :   d_solver->addPlugin(pl);
    2542                 :          1 :   Term x = d_tm.mkConst(d_string, "x");
    2543                 :          1 :   Term y = d_tm.mkConst(d_string, "y");
    2544                 :          4 :   Term ctn1 = d_tm.mkTerm(Kind::STRING_CONTAINS, {x, y});
    2545                 :          4 :   Term ctn2 = d_tm.mkTerm(Kind::STRING_CONTAINS, {y, x});
    2546 [ +  + ][ -  - ]:          3 :   d_solver->assertFormula(d_tm.mkTerm(Kind::OR, {ctn1, ctn2}));
    2547                 :          3 :   Term lx = d_tm.mkTerm(Kind::STRING_LENGTH, {x});
    2548                 :          3 :   Term ly = d_tm.mkTerm(Kind::STRING_LENGTH, {y});
    2549                 :          4 :   Term lc = d_tm.mkTerm(Kind::GT, {lx, ly});
    2550                 :          1 :   d_solver->assertFormula(lc);
    2551 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(d_solver->checkSat().isSat());
    2552                 :            :   // above input formulas should induce a theory lemma and SAT clause learning
    2553 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(pl.hasSeenTheoryLemma());
    2554 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(pl.hasSeenSatClause());
    2555 [ +  - ][ +  - ]:          1 : }
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
    2556                 :            : 
    2557                 :          4 : TEST_F(TestApiBlackSolver, pluginListenCadical)
    2558                 :            : {
    2559                 :          1 :   cvc5::Solver solver(d_tm);
    2560                 :          1 :   solver.setOption("sat-solver", "cadical");
    2561                 :          1 :   solver.setOption("plugin-notify-sat-clause-in-solve", "true");
    2562                 :          1 :   PluginListen pl(d_tm);
    2563                 :          1 :   solver.addPlugin(pl);
    2564                 :          1 :   Sort bv1 = d_tm.mkBitVectorSort(8);
    2565                 :          1 :   Sort bv16 = d_tm.mkBitVectorSort(8);
    2566                 :          1 :   Term x = d_tm.mkConst(d_bool, "x");
    2567                 :          1 :   Term z16 = d_tm.mkBitVector(16, 0);
    2568                 :          1 :   Term o16 = d_tm.mkBitVector(16, 1);
    2569                 :          1 :   Term z1 = d_tm.mkBitVector(1, 0);
    2570                 :          1 :   Term o1 = d_tm.mkBitVector(1, 1);
    2571                 :            : 
    2572                 :          5 :   Term ite1 = d_tm.mkTerm(Kind::ITE, {x, z16, o16});
    2573                 :          4 :   Term add = d_tm.mkTerm(Kind::BITVECTOR_ADD, {o16, ite1});
    2574                 :          4 :   Term eq1 = d_tm.mkTerm(Kind::EQUAL, {z16, add});
    2575                 :          5 :   Term ite2 = d_tm.mkTerm(Kind::ITE, {eq1, o1, z1});
    2576                 :            :   Term eq2 =
    2577                 :          6 :       d_tm.mkTerm(Kind::EQUAL, {z1, d_tm.mkTerm(Kind::BITVECTOR_NOT, {ite2})});
    2578                 :          1 :   solver.assertFormula(eq2);
    2579 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(solver.checkSat().isUnsat());
    2580                 :            :   // above input formulas should induce a theory lemma and SAT clause learning
    2581 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(pl.hasSeenTheoryLemma());
    2582 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(pl.hasSeenSatClause());
    2583 [ +  - ][ +  - ]:          1 : }
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
    2584                 :            : 
    2585                 :          4 : TEST_F(TestApiBlackSolver, verticalBars)
    2586                 :            : {
    2587                 :          2 :   Term a = d_solver->declareFun("|a |", {}, d_real);
    2588 [ -  + ][ +  - ]:          2 :   ASSERT_EQ("|a |", a.toString());
    2589         [ +  - ]:          1 : }
    2590                 :            : 
    2591                 :          4 : TEST_F(TestApiBlackSolver, getVersion)
    2592                 :            : {
    2593                 :          1 :   std::cout << d_solver->getVersion() << std::endl;
    2594                 :          1 : }
    2595                 :            : 
    2596                 :          4 : TEST_F(TestApiBlackSolver, multipleSolvers)
    2597                 :            : {
    2598                 :          1 :   Term function1, function2, value1, value2, definedFunction;
    2599                 :          1 :   Term zero;
    2600                 :            :   {
    2601                 :          1 :     Solver s1(d_tm);
    2602                 :          1 :     s1.setLogic("ALL");
    2603                 :          1 :     s1.setOption("produce-models", "true");
    2604                 :          1 :     function1 = s1.declareFun("f1", {}, d_int);
    2605                 :          1 :     Term x = d_tm.mkVar(d_int, "x");
    2606                 :          1 :     zero = d_tm.mkInteger(0);
    2607                 :          2 :     definedFunction = s1.defineFun("f", {x}, d_int, zero);
    2608                 :          1 :     s1.assertFormula(function1.eqTerm(zero));
    2609                 :          1 :     s1.checkSat();
    2610                 :          1 :     value1 = s1.getValue(function1);
    2611                 :          1 :   }
    2612 [ -  + ][ +  - ]:          1 :   ASSERT_EQ(zero, value1);
    2613                 :            :   {
    2614                 :          1 :     Solver s2(d_tm);
    2615                 :          1 :     s2.setLogic("ALL");
    2616                 :          1 :     s2.setOption("produce-models", "true");
    2617                 :          1 :     function2 = s2.declareFun("function2", {}, d_int);
    2618                 :          1 :     s2.assertFormula(function2.eqTerm(value1));
    2619                 :          1 :     s2.checkSat();
    2620                 :          1 :     value2 = s2.getValue(function2);
    2621                 :          1 :   }
    2622 [ -  + ][ +  - ]:          1 :   ASSERT_EQ(value1, value2);
    2623                 :            :   {
    2624                 :          1 :     Solver s3(d_tm);
    2625                 :          1 :     s3.setLogic("ALL");
    2626                 :          1 :     s3.setOption("produce-models", "true");
    2627                 :          1 :     function2 = s3.declareFun("function3", {}, d_int);
    2628                 :          4 :     Term apply = d_tm.mkTerm(Kind::APPLY_UF, {definedFunction, zero});
    2629                 :          1 :     s3.assertFormula(function2.eqTerm(apply));
    2630                 :          1 :     s3.checkSat();
    2631                 :          1 :     Term value3 = s3.getValue(function2);
    2632 [ -  + ][ +  - ]:          1 :     ASSERT_EQ(value1, value3);
    2633 [ +  - ][ +  - ]:          1 :   }
                 [ +  - ]
    2634 [ +  - ][ +  - ]:          1 : }
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
    2635                 :            : 
    2636                 :            : #ifdef CVC5_USE_COCOA
    2637                 :            : 
    2638                 :          4 : TEST_F(TestApiBlackSolver, basicFiniteField)
    2639                 :            : {
    2640                 :          1 :   d_solver->setOption("produce-models", "true");
    2641                 :            : 
    2642                 :          2 :   Sort F = d_tm.mkFiniteFieldSort("5");
    2643                 :          1 :   Term a = d_tm.mkConst(F, "a");
    2644                 :          1 :   Term b = d_tm.mkConst(F, "b");
    2645 [ -  + ][ +  - ]:          2 :   ASSERT_EQ("5", F.getFiniteFieldSize());
    2646                 :            : 
    2647                 :          2 :   Term inv = d_tm.mkTerm(Kind::EQUAL,
    2648                 :          2 :                          {d_tm.mkTerm(Kind::FINITE_FIELD_MULT, {a, b}),
    2649                 :          3 :                           d_tm.mkFiniteFieldElem("1", F)});
    2650                 :          5 :   Term aIsTwo = d_tm.mkTerm(Kind::EQUAL, {a, d_tm.mkFiniteFieldElem("2", F)});
    2651                 :            : 
    2652                 :          1 :   d_solver->assertFormula(inv);
    2653                 :          1 :   d_solver->assertFormula(aIsTwo);
    2654 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(d_solver->checkSat().isSat());
    2655 [ -  + ][ +  - ]:          2 :   ASSERT_EQ(d_solver->getValue(a).getFiniteFieldValue(), "2");
    2656 [ -  + ][ +  - ]:          2 :   ASSERT_EQ(d_solver->getValue(b).getFiniteFieldValue(), "-2");
    2657                 :            : 
    2658                 :          5 :   Term bIsTwo = d_tm.mkTerm(Kind::EQUAL, {b, d_tm.mkFiniteFieldElem("2", F)});
    2659                 :          1 :   d_solver->assertFormula(bIsTwo);
    2660 [ -  + ][ +  - ]:          1 :   ASSERT_FALSE(d_solver->checkSat().isSat());
    2661 [ +  - ][ +  - ]:          1 : }
                 [ +  - ]
    2662                 :            : 
    2663                 :          4 : TEST_F(TestApiBlackSolver, basicFiniteFieldBase)
    2664                 :            : {
    2665                 :          1 :   d_solver->setOption("produce-models", "true");
    2666                 :            : 
    2667                 :          2 :   Sort F = d_tm.mkFiniteFieldSort("101", 2);
    2668                 :          1 :   Term a = d_tm.mkConst(F, "a");
    2669                 :          1 :   Term b = d_tm.mkConst(F, "b");
    2670 [ -  + ][ +  - ]:          2 :   ASSERT_EQ("5", F.getFiniteFieldSize());
    2671                 :            : 
    2672                 :          2 :   Term inv = d_tm.mkTerm(Kind::EQUAL,
    2673                 :          2 :                          {d_tm.mkTerm(Kind::FINITE_FIELD_MULT, {a, b}),
    2674                 :          3 :                           d_tm.mkFiniteFieldElem("1", F, 3)});
    2675                 :            :   Term aIsTwo =
    2676                 :          5 :       d_tm.mkTerm(Kind::EQUAL, {a, d_tm.mkFiniteFieldElem("10", F, 2)});
    2677                 :            : 
    2678                 :          1 :   d_solver->assertFormula(inv);
    2679                 :          1 :   d_solver->assertFormula(aIsTwo);
    2680 [ -  + ][ +  - ]:          1 :   ASSERT_TRUE(d_solver->checkSat().isSat());
    2681 [ -  + ][ +  - ]:          2 :   ASSERT_EQ(d_solver->getValue(a).getFiniteFieldValue(), "2");
    2682 [ -  + ][ +  - ]:          2 :   ASSERT_EQ(d_solver->getValue(b).getFiniteFieldValue(), "-2");
    2683                 :            : 
    2684                 :          5 :   Term bIsTwo = d_tm.mkTerm(Kind::EQUAL, {b, d_tm.mkFiniteFieldElem("2", F)});
    2685                 :          1 :   d_solver->assertFormula(bIsTwo);
    2686 [ -  + ][ +  - ]:          1 :   ASSERT_FALSE(d_solver->checkSat().isSat());
    2687 [ +  - ][ +  - ]:          1 : }
                 [ +  - ]
    2688                 :            : 
    2689                 :            : #endif  // CVC5_USE_COCOA
    2690                 :            : 
    2691                 :            : }  // namespace test
    2692                 :            : }  // namespace cvc5::internal

Generated by: LCOV version 1.14