Reorganize test/unit/api directory. (#7612)
authorAina Niemetz <aina.niemetz@gmail.com>
Wed, 10 Nov 2021 00:08:29 +0000 (16:08 -0800)
committerGitHub <noreply@github.com>
Wed, 10 Nov 2021 00:08:29 +0000 (00:08 +0000)
This moves .cpp files to directory test/unit/api/cpp and python files in
test/python/unit/api to test/unit/api/python.

44 files changed:
test/CMakeLists.txt
test/python/CMakeLists.txt [deleted file]
test/python/unit/api/__init__.py [deleted file]
test/python/unit/api/test_datatype_api.py [deleted file]
test/python/unit/api/test_grammar.py [deleted file]
test/python/unit/api/test_op.py [deleted file]
test/python/unit/api/test_result.py [deleted file]
test/python/unit/api/test_solver.py [deleted file]
test/python/unit/api/test_sort.py [deleted file]
test/python/unit/api/test_term.py [deleted file]
test/python/unit/api/test_to_python_obj.py [deleted file]
test/unit/CMakeLists.txt
test/unit/api/CMakeLists.txt
test/unit/api/cpp/CMakeLists.txt [new file with mode: 0644]
test/unit/api/cpp/datatype_api_black.cpp [new file with mode: 0644]
test/unit/api/cpp/grammar_black.cpp [new file with mode: 0644]
test/unit/api/cpp/op_black.cpp [new file with mode: 0644]
test/unit/api/cpp/op_white.cpp [new file with mode: 0644]
test/unit/api/cpp/result_black.cpp [new file with mode: 0644]
test/unit/api/cpp/solver_black.cpp [new file with mode: 0644]
test/unit/api/cpp/solver_white.cpp [new file with mode: 0644]
test/unit/api/cpp/sort_black.cpp [new file with mode: 0644]
test/unit/api/cpp/term_black.cpp [new file with mode: 0644]
test/unit/api/cpp/term_white.cpp [new file with mode: 0644]
test/unit/api/datatype_api_black.cpp [deleted file]
test/unit/api/grammar_black.cpp [deleted file]
test/unit/api/op_black.cpp [deleted file]
test/unit/api/op_white.cpp [deleted file]
test/unit/api/python/CMakeLists.txt [new file with mode: 0644]
test/unit/api/python/__init__.py [new file with mode: 0644]
test/unit/api/python/test_datatype_api.py [new file with mode: 0644]
test/unit/api/python/test_grammar.py [new file with mode: 0644]
test/unit/api/python/test_op.py [new file with mode: 0644]
test/unit/api/python/test_result.py [new file with mode: 0644]
test/unit/api/python/test_solver.py [new file with mode: 0644]
test/unit/api/python/test_sort.py [new file with mode: 0644]
test/unit/api/python/test_term.py [new file with mode: 0644]
test/unit/api/python/test_to_python_obj.py [new file with mode: 0644]
test/unit/api/result_black.cpp [deleted file]
test/unit/api/solver_black.cpp [deleted file]
test/unit/api/solver_white.cpp [deleted file]
test/unit/api/sort_black.cpp [deleted file]
test/unit/api/term_black.cpp [deleted file]
test/unit/api/term_white.cpp [deleted file]

index d3ff709ca30f63025436e3be137bad8415899ea5..5f96d2b9bef007015eb506a301a805141388b91b 100644 (file)
@@ -41,8 +41,3 @@ add_subdirectory(api EXCLUDE_FROM_ALL)
 if(ENABLE_UNIT_TESTING)
   add_subdirectory(unit EXCLUDE_FROM_ALL)
 endif()
-
-# add Python bindings tests if building with Python bindings
-if (BUILD_BINDINGS_PYTHON)
-  add_subdirectory(python)
-endif()
diff --git a/test/python/CMakeLists.txt b/test/python/CMakeLists.txt
deleted file mode 100644 (file)
index 5b681ca..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-###############################################################################
-# Top contributors (to current version):
-#   Yoni Zohar, Aina Niemetz, Mathias Preiner
-#
-# This file is part of the cvc5 project.
-#
-# Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
-# in the top-level source directory and their institutional affiliations.
-# All rights reserved.  See the file COPYING in the top-level source
-# directory for licensing information.
-# #############################################################################
-#
-# The build system configuration.
-##
-
-# Check if the pytest Python module is installed.
-check_python_module("pytest")
-
-# Add Python bindings API tests.
-macro(cvc5_add_python_api_test name filename)
-# We create test target 'python/unit/api/myapitest' and run it with
-# 'ctest -R "python/unit/api/myapitest"'.
-add_test (NAME python/unit/api/${name}
-  COMMAND ${PYTHON_EXECUTABLE} -m pytest ${CMAKE_CURRENT_SOURCE_DIR}/${filename}
-  # directory for importing the python bindings
-  WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/src/api/python)
-endmacro()
-
-# add specific test files
-cvc5_add_python_api_test(pytest_solver unit/api/test_solver.py)
-cvc5_add_python_api_test(pytest_sort unit/api/test_sort.py)
-cvc5_add_python_api_test(pytest_term unit/api/test_term.py)
-cvc5_add_python_api_test(pytest_datatype_api unit/api/test_datatype_api.py)
-cvc5_add_python_api_test(pytest_grammar unit/api/test_grammar.py)
-cvc5_add_python_api_test(pytest_to_python_obj unit/api/test_to_python_obj.py)
-cvc5_add_python_api_test(pytest_op unit/api/test_op.py)
-cvc5_add_python_api_test(pytest_result unit/api/test_result.py)
diff --git a/test/python/unit/api/__init__.py b/test/python/unit/api/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/test/python/unit/api/test_datatype_api.py b/test/python/unit/api/test_datatype_api.py
deleted file mode 100644 (file)
index d8a4c26..0000000
+++ /dev/null
@@ -1,566 +0,0 @@
-###############################################################################
-# Top contributors (to current version):
-#   Yoni Zohar
-#
-# This file is part of the cvc5 project.
-#
-# Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
-# in the top-level source directory and their institutional affiliations.
-# All rights reserved.  See the file COPYING in the top-level source
-# directory for licensing information.
-# #############################################################################
-##
-
-import pytest
-import pycvc5
-from pycvc5 import kinds
-from pycvc5 import Sort, Term 
-from pycvc5 import DatatypeDecl
-from pycvc5 import Datatype
-from pycvc5 import DatatypeConstructorDecl
-from pycvc5 import DatatypeConstructor
-from pycvc5 import DatatypeSelector
-
-
-@pytest.fixture
-def solver():
-    return pycvc5.Solver()
-
-
-def test_mk_datatype_sort(solver):
-    dtypeSpec = solver.mkDatatypeDecl("list")
-    cons = solver.mkDatatypeConstructorDecl("cons")
-    cons.addSelector("head", solver.getIntegerSort())
-    dtypeSpec.addConstructor(cons)
-    nil = solver.mkDatatypeConstructorDecl("nil")
-    dtypeSpec.addConstructor(nil)
-    listSort = solver.mkDatatypeSort(dtypeSpec)
-    d = listSort.getDatatype()
-    consConstr = d[0]
-    nilConstr = d[1]
-    with pytest.raises(RuntimeError):
-        d[2]
-    consConstr.getConstructorTerm()
-    nilConstr.getConstructorTerm()
-
-def test_is_null(solver):
-  # creating empty (null) objects.
-  dtypeSpec = DatatypeDecl(solver)
-  cons = DatatypeConstructorDecl(solver)
-  d = Datatype(solver)
-  consConstr = DatatypeConstructor(solver)
-  sel = DatatypeSelector(solver)
-
-  # verifying that the objects are considered null.
-  assert dtypeSpec.isNull()
-  assert cons.isNull()
-  assert d.isNull()
-  assert consConstr.isNull()
-  assert sel.isNull()
-
-  # changing the objects to be non-null
-  dtypeSpec = solver.mkDatatypeDecl("list");
-  cons = solver.mkDatatypeConstructorDecl("cons");
-  cons.addSelector("head", solver.getIntegerSort());
-  dtypeSpec.addConstructor(cons);
-  listSort = solver.mkDatatypeSort(dtypeSpec)
-  d = listSort.getDatatype();
-  consConstr = d[0];
-  sel = consConstr[0];
-
-  # verifying that the new objects are non-null
-  assert not dtypeSpec.isNull()
-  assert not cons.isNull()
-  assert not d.isNull()
-  assert not consConstr.isNull()
-  assert not sel.isNull()
-
-def test_mk_datatype_sorts(solver):
-    # Create two mutual datatypes corresponding to this definition
-    # block:
-    #
-    #   DATATYPE
-    #     tree = node(left: tree, right: tree) | leaf(data: list),
-    #     list = cons(car: tree, cdr: list) | nil
-    #   END
-    #
-
-    #Make unresolved types as placeholders
-    unresTypes = set([])
-    unresTree = solver.mkUninterpretedSort("tree")
-    unresList = solver.mkUninterpretedSort("list")
-    unresTypes.add(unresTree)
-    unresTypes.add(unresList)
-
-    tree = solver.mkDatatypeDecl("tree")
-    node = solver.mkDatatypeConstructorDecl("node")
-    node.addSelector("left", unresTree)
-    node.addSelector("right", unresTree)
-    tree.addConstructor(node)
-
-    leaf = solver.mkDatatypeConstructorDecl("leaf")
-    leaf.addSelector("data", unresList)
-    tree.addConstructor(leaf)
-
-    llist = solver.mkDatatypeDecl("list")
-    cons = solver.mkDatatypeConstructorDecl("cons")
-    cons.addSelector("car", unresTree)
-    cons.addSelector("cdr", unresTree)
-    llist.addConstructor(cons)
-
-    nil = solver.mkDatatypeConstructorDecl("nil")
-    llist.addConstructor(nil)
-
-    dtdecls = []
-    dtdecls.append(tree)
-    dtdecls.append(llist)
-    dtsorts = []
-    dtsorts = solver.mkDatatypeSorts(dtdecls, unresTypes)
-    assert len(dtsorts) == len(dtdecls)
-    for i in range(0, len(dtdecls)):
-        assert dtsorts[i].isDatatype()
-        assert not dtsorts[i].getDatatype().isFinite()
-        assert dtsorts[i].getDatatype().getName() == dtdecls[i].getName()
-    # verify the resolution was correct
-    dtTree = dtsorts[0].getDatatype()
-    dtcTreeNode = dtTree[0]
-    assert dtcTreeNode.getName() == "node"
-    dtsTreeNodeLeft = dtcTreeNode[0]
-    assert dtsTreeNodeLeft.getName() == "left"
-    # argument type should have resolved to be recursive
-    assert dtsTreeNodeLeft.getRangeSort().isDatatype()
-    assert dtsTreeNodeLeft.getRangeSort() == dtsorts[0]
-
-    # fails due to empty datatype
-    dtdeclsBad = []
-    emptyD = solver.mkDatatypeDecl("emptyD")
-    dtdeclsBad.append(emptyD)
-    with pytest.raises(RuntimeError):
-        solver.mkDatatypeSorts(dtdeclsBad)
-
-
-def test_datatype_structs(solver):
-    intSort = solver.getIntegerSort()
-    boolSort = solver.getBooleanSort()
-
-    # create datatype sort to test
-    dtypeSpec = solver.mkDatatypeDecl("list")
-    cons = solver.mkDatatypeConstructorDecl("cons")
-    cons.addSelector("head", intSort)
-    cons.addSelectorSelf("tail")
-    nullSort = Sort(solver)
-    with pytest.raises(RuntimeError):
-        cons.addSelector("null", nullSort)
-    dtypeSpec.addConstructor(cons)
-    nil = solver.mkDatatypeConstructorDecl("nil")
-    dtypeSpec.addConstructor(nil)
-    dtypeSort = solver.mkDatatypeSort(dtypeSpec)
-    dt = dtypeSort.getDatatype()
-    assert not dt.isCodatatype()
-    assert not dt.isTuple()
-    assert not dt.isRecord()
-    assert not dt.isFinite()
-    assert dt.isWellFounded()
-    # get constructor
-    dcons = dt[0]
-    consTerm = dcons.getConstructorTerm()
-    assert dcons.getNumSelectors() == 2
-
-    # create datatype sort to test
-    dtypeSpecEnum = solver.mkDatatypeDecl("enum")
-    ca = solver.mkDatatypeConstructorDecl("A")
-    dtypeSpecEnum.addConstructor(ca)
-    cb = solver.mkDatatypeConstructorDecl("B")
-    dtypeSpecEnum.addConstructor(cb)
-    cc = solver.mkDatatypeConstructorDecl("C")
-    dtypeSpecEnum.addConstructor(cc)
-    dtypeSortEnum = solver.mkDatatypeSort(dtypeSpecEnum)
-    dtEnum = dtypeSortEnum.getDatatype()
-    assert not dtEnum.isTuple()
-    assert dtEnum.isFinite()
-
-    # create codatatype
-    dtypeSpecStream = solver.mkDatatypeDecl("stream", True)
-    consStream = solver.mkDatatypeConstructorDecl("cons")
-    consStream.addSelector("head", intSort)
-    consStream.addSelectorSelf("tail")
-    dtypeSpecStream.addConstructor(consStream)
-    dtypeSortStream = solver.mkDatatypeSort(dtypeSpecStream)
-    dtStream = dtypeSortStream.getDatatype()
-    assert dtStream.isCodatatype()
-    assert not dtStream.isFinite()
-    # codatatypes may be well-founded
-    assert dtStream.isWellFounded()
-
-    # create tuple
-    tupSort = solver.mkTupleSort([boolSort])
-    dtTuple = tupSort.getDatatype()
-    assert dtTuple.isTuple()
-    assert not dtTuple.isRecord()
-    assert dtTuple.isFinite()
-    assert dtTuple.isWellFounded()
-
-    # create record
-    fields = [("b", boolSort), ("i", intSort)]
-    recSort = solver.mkRecordSort(fields)
-    assert recSort.isDatatype()
-    dtRecord = recSort.getDatatype()
-    assert not dtRecord.isTuple()
-    assert dtRecord.isRecord()
-    assert not dtRecord.isFinite()
-    assert dtRecord.isWellFounded()
-
-
-def test_datatype_names(solver):
-    intSort = solver.getIntegerSort()
-
-    # create datatype sort to test
-    dtypeSpec = solver.mkDatatypeDecl("list")
-    dtypeSpec.getName()
-    assert dtypeSpec.getName() == "list"
-    cons = solver.mkDatatypeConstructorDecl("cons")
-    cons.addSelector("head", intSort)
-    cons.addSelectorSelf("tail")
-    dtypeSpec.addConstructor(cons)
-    nil = solver.mkDatatypeConstructorDecl("nil")
-    dtypeSpec.addConstructor(nil)
-    dtypeSort = solver.mkDatatypeSort(dtypeSpec)
-    dt = dtypeSort.getDatatype()
-    assert dt.getName() == "list"
-    dt.getConstructor("nil")
-    dt["cons"]
-    with pytest.raises(RuntimeError):
-        dt.getConstructor("head")
-    with pytest.raises(RuntimeError):
-        dt.getConstructor("")
-
-    dcons = dt[0]
-    assert dcons.getName() == "cons"
-    dcons.getSelector("head")
-    dcons["tail"]
-    with pytest.raises(RuntimeError):
-        dcons.getSelector("cons")
-
-    # get selector
-    dselTail = dcons[1]
-    assert dselTail.getName() == "tail"
-    assert dselTail.getRangeSort() == dtypeSort
-
-    # get selector from datatype
-    dt.getSelector("head")
-    with pytest.raises(RuntimeError):
-        dt.getSelector("cons")
-
-    # possible to construct null datatype declarations if not using mkDatatypeDecl
-    with pytest.raises(RuntimeError):
-        DatatypeDecl(solver).getName()
-
-
-def test_parametric_datatype(solver):
-    v = []
-    t1 = solver.mkParamSort("T1")
-    t2 = solver.mkParamSort("T2")
-    v.append(t1)
-    v.append(t2)
-    pairSpec = solver.mkDatatypeDecl("pair", v)
-
-    mkpair = solver.mkDatatypeConstructorDecl("mk-pair")
-    mkpair.addSelector("first", t1)
-    mkpair.addSelector("second", t2)
-    pairSpec.addConstructor(mkpair)
-
-    pairType = solver.mkDatatypeSort(pairSpec)
-
-    assert pairType.getDatatype().isParametric()
-
-    v.clear()
-    v.append(solver.getIntegerSort())
-    v.append(solver.getIntegerSort())
-    pairIntInt = pairType.instantiate(v)
-    v.clear()
-    v.append(solver.getRealSort())
-    v.append(solver.getRealSort())
-    pairRealReal = pairType.instantiate(v)
-    v.clear()
-    v.append(solver.getRealSort())
-    v.append(solver.getIntegerSort())
-    pairRealInt = pairType.instantiate(v)
-    v.clear()
-    v.append(solver.getIntegerSort())
-    v.append(solver.getRealSort())
-    pairIntReal = pairType.instantiate(v)
-
-    assert pairIntInt != pairRealReal
-    assert pairIntReal != pairRealReal
-    assert pairRealInt != pairRealReal
-    assert pairIntInt != pairIntReal
-    assert pairIntInt != pairRealInt
-    assert pairIntReal != pairRealInt
-
-    assert pairRealReal.isComparableTo(pairRealReal)
-    assert not pairIntReal.isComparableTo(pairRealReal)
-    assert not pairRealInt.isComparableTo(pairRealReal)
-    assert not pairIntInt.isComparableTo(pairRealReal)
-    assert not pairRealReal.isComparableTo(pairRealInt)
-    assert not pairIntReal.isComparableTo(pairRealInt)
-    assert pairRealInt.isComparableTo(pairRealInt)
-    assert not pairIntInt.isComparableTo(pairRealInt)
-    assert not pairRealReal.isComparableTo(pairIntReal)
-    assert pairIntReal.isComparableTo(pairIntReal)
-    assert not pairRealInt.isComparableTo(pairIntReal)
-    assert not pairIntInt.isComparableTo(pairIntReal)
-    assert not pairRealReal.isComparableTo(pairIntInt)
-    assert not pairIntReal.isComparableTo(pairIntInt)
-    assert not pairRealInt.isComparableTo(pairIntInt)
-    assert pairIntInt.isComparableTo(pairIntInt)
-
-    assert pairRealReal.isSubsortOf(pairRealReal)
-    assert not pairIntReal.isSubsortOf(pairRealReal)
-    assert not pairRealInt.isSubsortOf(pairRealReal)
-    assert not pairIntInt.isSubsortOf(pairRealReal)
-    assert not pairRealReal.isSubsortOf(pairRealInt)
-    assert not pairIntReal.isSubsortOf(pairRealInt)
-    assert pairRealInt.isSubsortOf(pairRealInt)
-    assert not pairIntInt.isSubsortOf(pairRealInt)
-    assert not pairRealReal.isSubsortOf(pairIntReal)
-    assert pairIntReal.isSubsortOf(pairIntReal)
-    assert not pairRealInt.isSubsortOf(pairIntReal)
-    assert not pairIntInt.isSubsortOf(pairIntReal)
-    assert not pairRealReal.isSubsortOf(pairIntInt)
-    assert not pairIntReal.isSubsortOf(pairIntInt)
-    assert not pairRealInt.isSubsortOf(pairIntInt)
-    assert pairIntInt.isSubsortOf(pairIntInt)
-
-
-def test_datatype_simply_rec(solver):
-    # Create mutual datatypes corresponding to this definition block:
-    #
-    #   DATATYPE
-    #     wlist = leaf(data: list),
-    #     list = cons(car: wlist, cdr: list) | nil,
-    #     ns = elem(ndata: set(wlist)) | elemArray(ndata2: array(list, list))
-    #   END
-
-    # Make unresolved types as placeholders
-    unresTypes = set([])
-    unresWList = solver.mkUninterpretedSort("wlist")
-    unresList = solver.mkUninterpretedSort("list")
-    unresNs = solver.mkUninterpretedSort("ns")
-    unresTypes.add(unresWList)
-    unresTypes.add(unresList)
-    unresTypes.add(unresNs)
-
-    wlist = solver.mkDatatypeDecl("wlist")
-    leaf = solver.mkDatatypeConstructorDecl("leaf")
-    leaf.addSelector("data", unresList)
-    wlist.addConstructor(leaf)
-
-    llist = solver.mkDatatypeDecl("list")
-    cons = solver.mkDatatypeConstructorDecl("cons")
-    cons.addSelector("car", unresWList)
-    cons.addSelector("cdr", unresList)
-    llist.addConstructor(cons)
-    nil = solver.mkDatatypeConstructorDecl("nil")
-    llist.addConstructor(nil)
-
-    ns = solver.mkDatatypeDecl("ns")
-    elem = solver.mkDatatypeConstructorDecl("elem")
-    elem.addSelector("ndata", solver.mkSetSort(unresWList))
-    ns.addConstructor(elem)
-    elemArray = solver.mkDatatypeConstructorDecl("elemArray")
-    elemArray.addSelector("ndata", solver.mkArraySort(unresList, unresList))
-    ns.addConstructor(elemArray)
-
-    dtdecls = [wlist, llist, ns]
-    # this is well-founded and has no nested recursion
-    dtsorts = solver.mkDatatypeSorts(dtdecls, unresTypes)
-    assert len(dtsorts) == 3
-    assert dtsorts[0].getDatatype().isWellFounded()
-    assert dtsorts[1].getDatatype().isWellFounded()
-    assert dtsorts[2].getDatatype().isWellFounded()
-    assert not dtsorts[0].getDatatype().hasNestedRecursion()
-    assert not dtsorts[1].getDatatype().hasNestedRecursion()
-    assert not dtsorts[2].getDatatype().hasNestedRecursion()
-
-    # Create mutual datatypes corresponding to this definition block:
-    #   DATATYPE
-    #     ns2 = elem2(ndata: array(int,ns2)) | nil2
-    #   END
-
-    unresTypes.clear()
-    unresNs2 = solver.mkUninterpretedSort("ns2")
-    unresTypes.add(unresNs2)
-
-    ns2 = solver.mkDatatypeDecl("ns2")
-    elem2 = solver.mkDatatypeConstructorDecl("elem2")
-    elem2.addSelector("ndata",
-                      solver.mkArraySort(solver.getIntegerSort(), unresNs2))
-    ns2.addConstructor(elem2)
-    nil2 = solver.mkDatatypeConstructorDecl("nil2")
-    ns2.addConstructor(nil2)
-
-    dtdecls.clear()
-    dtdecls.append(ns2)
-
-    # this is not well-founded due to non-simple recursion
-    dtsorts = solver.mkDatatypeSorts(dtdecls, unresTypes)
-    assert len(dtsorts) == 1
-    assert dtsorts[0].getDatatype()[0][0].getRangeSort().isArray()
-    assert dtsorts[0].getDatatype()[0][0].getRangeSort().getArrayElementSort() \
-        == dtsorts[0]
-    assert dtsorts[0].getDatatype().isWellFounded()
-    assert dtsorts[0].getDatatype().hasNestedRecursion()
-
-    # Create mutual datatypes corresponding to this definition block:
-    #   DATATYPE
-    #     list3 = cons3(car: ns3, cdr: list3) | nil3,
-    #     ns3 = elem3(ndata: set(list3))
-    #   END
-
-    unresTypes.clear()
-    unresNs3 = solver.mkUninterpretedSort("ns3")
-    unresTypes.add(unresNs3)
-    unresList3 = solver.mkUninterpretedSort("list3")
-    unresTypes.add(unresList3)
-
-    list3 = solver.mkDatatypeDecl("list3")
-    cons3 = solver.mkDatatypeConstructorDecl("cons3")
-    cons3.addSelector("car", unresNs3)
-    cons3.addSelector("cdr", unresList3)
-    list3.addConstructor(cons3)
-    nil3 = solver.mkDatatypeConstructorDecl("nil3")
-    list3.addConstructor(nil3)
-
-    ns3 = solver.mkDatatypeDecl("ns3")
-    elem3 = solver.mkDatatypeConstructorDecl("elem3")
-    elem3.addSelector("ndata", solver.mkSetSort(unresList3))
-    ns3.addConstructor(elem3)
-
-    dtdecls.clear()
-    dtdecls.append(list3)
-    dtdecls.append(ns3)
-
-    # both are well-founded and have nested recursion
-    dtsorts = solver.mkDatatypeSorts(dtdecls, unresTypes)
-    assert len(dtsorts) == 2
-    assert dtsorts[0].getDatatype().isWellFounded()
-    assert dtsorts[1].getDatatype().isWellFounded()
-    assert dtsorts[0].getDatatype().hasNestedRecursion()
-    assert dtsorts[1].getDatatype().hasNestedRecursion()
-
-    # Create mutual datatypes corresponding to this definition block:
-    #   DATATYPE
-    #     list4 = cons(car: set(ns4), cdr: list4) | nil,
-    #     ns4 = elem(ndata: list4)
-    #   END
-    unresTypes.clear()
-    unresNs4 = solver.mkUninterpretedSort("ns4")
-    unresTypes.add(unresNs4)
-    unresList4 = solver.mkUninterpretedSort("list4")
-    unresTypes.add(unresList4)
-
-    list4 = solver.mkDatatypeDecl("list4")
-    cons4 = solver.mkDatatypeConstructorDecl("cons4")
-    cons4.addSelector("car", solver.mkSetSort(unresNs4))
-    cons4.addSelector("cdr", unresList4)
-    list4.addConstructor(cons4)
-    nil4 = solver.mkDatatypeConstructorDecl("nil4")
-    list4.addConstructor(nil4)
-
-    ns4 = solver.mkDatatypeDecl("ns4")
-    elem4 = solver.mkDatatypeConstructorDecl("elem3")
-    elem4.addSelector("ndata", unresList4)
-    ns4.addConstructor(elem4)
-
-    dtdecls.clear()
-    dtdecls.append(list4)
-    dtdecls.append(ns4)
-
-    # both are well-founded and have nested recursion
-    dtsorts = solver.mkDatatypeSorts(dtdecls, unresTypes)
-    assert len(dtsorts) == 2
-    assert dtsorts[0].getDatatype().isWellFounded()
-    assert dtsorts[1].getDatatype().isWellFounded()
-    assert dtsorts[0].getDatatype().hasNestedRecursion()
-    assert dtsorts[1].getDatatype().hasNestedRecursion()
-
-    # Create mutual datatypes corresponding to this definition block:
-    #   DATATYPE
-    #     list5[X] = cons(car: X, cdr: list5[list5[X]]) | nil
-    #   END
-    unresTypes.clear()
-    unresList5 = solver.mkSortConstructorSort("list5", 1)
-    unresTypes.add(unresList5)
-
-    v = []
-    x = solver.mkParamSort("X")
-    v.append(x)
-    list5 = solver.mkDatatypeDecl("list5", v)
-
-    args = [x]
-    urListX = unresList5.instantiate(args)
-    args[0] = urListX
-    urListListX = unresList5.instantiate(args)
-
-    cons5 = solver.mkDatatypeConstructorDecl("cons5")
-    cons5.addSelector("car", x)
-    cons5.addSelector("cdr", urListListX)
-    list5.addConstructor(cons5)
-    nil5 = solver.mkDatatypeConstructorDecl("nil5")
-    list5.addConstructor(nil5)
-
-    dtdecls.clear()
-    dtdecls.append(list5)
-
-    # well-founded and has nested recursion
-    dtsorts = solver.mkDatatypeSorts(dtdecls, unresTypes)
-    assert len(dtsorts) == 1
-    assert dtsorts[0].getDatatype().isWellFounded()
-    assert dtsorts[0].getDatatype().hasNestedRecursion()
-
-
-def test_datatype_specialized_cons(solver):
-    # Create mutual datatypes corresponding to this definition block:
-    #   DATATYPE
-    #     plist[X] = pcons(car: X, cdr: plist[X]) | pnil
-    #   END
-
-    # Make unresolved types as placeholders
-    unresTypes = set([])
-    unresList = solver.mkSortConstructorSort("plist", 1)
-    unresTypes.add(unresList)
-
-    v = []
-    x = solver.mkParamSort("X")
-    v.append(x)
-    plist = solver.mkDatatypeDecl("plist", v)
-
-    args = [x]
-    urListX = unresList.instantiate(args)
-
-    pcons = solver.mkDatatypeConstructorDecl("pcons")
-    pcons.addSelector("car", x)
-    pcons.addSelector("cdr", urListX)
-    plist.addConstructor(pcons)
-    nil5 = solver.mkDatatypeConstructorDecl("pnil")
-    plist.addConstructor(nil5)
-
-    dtdecls = [plist]
-
-    # make the datatype sorts
-    dtsorts = solver.mkDatatypeSorts(dtdecls, unresTypes)
-    assert len(dtsorts) == 1
-    d = dtsorts[0].getDatatype()
-    nilc = d[0]
-
-    isort = solver.getIntegerSort()
-    iargs = [isort]
-    listInt = dtsorts[0].instantiate(iargs)
-
-    testConsTerm = Term(solver)
-    # get the specialized constructor term for list[Int]
-    testConsTerm = nilc.getSpecializedConstructorTerm(listInt)
-    assert testConsTerm != nilc.getConstructorTerm()
-    # error to get the specialized constructor term for Int
-    with pytest.raises(RuntimeError):
-        nilc.getSpecializedConstructorTerm(isort)
diff --git a/test/python/unit/api/test_grammar.py b/test/python/unit/api/test_grammar.py
deleted file mode 100644 (file)
index db567a6..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-###############################################################################
-# Top contributors (to current version):
-#   Yoni Zohar, Makai Mann, Mudathir Mohamed
-#
-# This file is part of the cvc5 project.
-#
-# Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
-# in the top-level source directory and their institutional affiliations.
-# All rights reserved.  See the file COPYING in the top-level source
-# directory for licensing information.
-# #############################################################################
-#
-# Translated from test/unit/api/grammar_black.h
-##
-
-import pytest
-
-import pycvc5
-from pycvc5 import kinds, Term
-
-
-@pytest.fixture
-def solver():
-    return pycvc5.Solver()
-
-
-def test_add_rule(solver):
-    boolean = solver.getBooleanSort()
-    integer = solver.getIntegerSort()
-
-    null_term = Term(solver)
-    start = solver.mkVar(boolean)
-    nts = solver.mkVar(boolean)
-
-    # expecting no error
-    g = solver.mkSygusGrammar([], [start])
-
-    g.addRule(start, solver.mkBoolean(False))
-
-    # expecting errors
-    with pytest.raises(RuntimeError):
-        g.addRule(null_term, solver.mkBoolean(False))
-    with pytest.raises(RuntimeError):
-        g.addRule(start, null_term)
-    with pytest.raises(RuntimeError):
-        g.addRule(nts, solver.mkBoolean(False))
-    with pytest.raises(RuntimeError):
-        g.addRule(start, solver.mkInteger(0))
-    with pytest.raises(RuntimeError):
-        g.addRule(start, nts)
-
-    # expecting no errors
-    solver.synthFun("f", {}, boolean, g)
-
-    # expecting an error
-    with pytest.raises(RuntimeError):
-        g.addRule(start, solver.mkBoolean(False))
-
-
-def test_add_rules(solver):
-    boolean = solver.getBooleanSort()
-    integer = solver.getIntegerSort()
-
-    null_term = Term(solver)
-    start = solver.mkVar(boolean)
-    nts = solver.mkVar(boolean)
-
-    g = solver.mkSygusGrammar([], [start])
-
-    g.addRules(start, {solver.mkBoolean(False)})
-
-    #Expecting errors
-    with pytest.raises(RuntimeError):
-        g.addRules(null_term, [solver.mkBoolean(False)])
-    with pytest.raises(RuntimeError):
-        g.addRules(start, [null_term])
-    with pytest.raises(RuntimeError):
-        g.addRules(nts, [solver.mkBoolean(False)])
-    with pytest.raises(RuntimeError):
-        g.addRules(start, [solver.mkInteger(0)])
-    with pytest.raises(RuntimeError):
-        g.addRules(start, [nts])
-    #Expecting no errors
-    solver.synthFun("f", {}, boolean, g)
-
-    #Expecting an error
-    with pytest.raises(RuntimeError):
-        g.addRules(start, solver.mkBoolean(False))
-
-
-def test_add_any_constant(solver):
-    boolean = solver.getBooleanSort()
-
-    null_term = Term(solver)
-    start = solver.mkVar(boolean)
-    nts = solver.mkVar(boolean)
-
-    g = solver.mkSygusGrammar({}, {start})
-
-    g.addAnyConstant(start)
-    g.addAnyConstant(start)
-
-    with pytest.raises(RuntimeError):
-        g.addAnyConstant(null_term)
-    with pytest.raises(RuntimeError):
-        g.addAnyConstant(nts)
-
-    solver.synthFun("f", {}, boolean, g)
-
-    with pytest.raises(RuntimeError):
-        g.addAnyConstant(start)
-
-
-def test_add_any_variable(solver):
-    boolean = solver.getBooleanSort()
-
-    null_term = Term(solver)
-    x = solver.mkVar(boolean)
-    start = solver.mkVar(boolean)
-    nts = solver.mkVar(boolean)
-
-    g1 = solver.mkSygusGrammar({x}, {start})
-    g2 = solver.mkSygusGrammar({}, {start})
-
-    g1.addAnyVariable(start)
-    g1.addAnyVariable(start)
-    g2.addAnyVariable(start)
-
-    with pytest.raises(RuntimeError):
-        g1.addAnyVariable(null_term)
-    with pytest.raises(RuntimeError):
-        g1.addAnyVariable(nts)
-
-    solver.synthFun("f", {}, boolean, g1)
-
-    with pytest.raises(RuntimeError):
-        g1.addAnyVariable(start)
diff --git a/test/python/unit/api/test_op.py b/test/python/unit/api/test_op.py
deleted file mode 100644 (file)
index 5126a48..0000000
+++ /dev/null
@@ -1,181 +0,0 @@
-###############################################################################
-# Top contributors (to current version):
-#   Yoni Zohar
-#
-# This file is part of the cvc5 project.
-#
-# Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
-# in the top-level source directory and their institutional affiliations.
-# All rights reserved.  See the file COPYING in the top-level source
-# directory for licensing information.
-# #############################################################################
-#
-# Unit tests for op API.
-#
-# Obtained by translating test/unit/api/op_black.cpp
-##
-
-import pytest
-import pycvc5
-from pycvc5 import kinds
-from pycvc5 import Sort
-from pycvc5 import Op
-
-
-@pytest.fixture
-def solver():
-    return pycvc5.Solver()
-
-
-def test_get_kind(solver):
-    x = solver.mkOp(kinds.BVExtract, 31, 1)
-    x.getKind()
-
-
-def test_is_null(solver):
-    x = Op(solver)
-    assert x.isNull()
-    x = solver.mkOp(kinds.BVExtract, 31, 1)
-    assert not x.isNull()
-
-
-def test_op_from_kind(solver):
-    solver.mkOp(kinds.Plus)
-    with pytest.raises(RuntimeError):
-        solver.mkOp(kinds.BVExtract)
-
-
-def test_get_num_indices(solver):
-    plus = solver.mkOp(kinds.Plus)
-    divisible = solver.mkOp(kinds.Divisible, 4)
-    bitvector_repeat = solver.mkOp(kinds.BVRepeat, 5)
-    bitvector_zero_extend = solver.mkOp(kinds.BVZeroExtend, 6)
-    bitvector_sign_extend = solver.mkOp(kinds.BVSignExtend, 7)
-    bitvector_rotate_left = solver.mkOp(kinds.BVRotateLeft, 8)
-    bitvector_rotate_right = solver.mkOp(kinds.BVRotateRight, 9)
-    int_to_bitvector = solver.mkOp(kinds.IntToBV, 10)
-    iand = solver.mkOp(kinds.Iand, 3)
-    floatingpoint_to_ubv = solver.mkOp(kinds.FPToUbv, 11)
-    floatingopint_to_sbv = solver.mkOp(kinds.FPToSbv, 13)
-    floatingpoint_to_fp_ieee_bitvector = solver.mkOp(kinds.FPToFpIeeeBV, 4, 25)
-    floatingpoint_to_fp_floatingpoint = solver.mkOp(kinds.FPToFpFP, 4, 25)
-    floatingpoint_to_fp_real = solver.mkOp(kinds.FPToFpReal, 4, 25)
-    floatingpoint_to_fp_signed_bitvector = solver.mkOp(kinds.FPToFpSignedBV, 4,
-                                                       25)
-    floatingpoint_to_fp_unsigned_bitvector = solver.mkOp(
-        kinds.FPToFpUnsignedBV, 4, 25)
-    floatingpoint_to_fp_generic = solver.mkOp(kinds.FPToFpGeneric, 4, 25)
-    regexp_loop = solver.mkOp(kinds.RegexpLoop, 2, 3)
-
-    assert 0 == plus.getNumIndices()
-    assert 1 == divisible.getNumIndices()
-    assert 1 == bitvector_repeat.getNumIndices()
-    assert 1 == bitvector_zero_extend.getNumIndices()
-    assert 1 == bitvector_sign_extend.getNumIndices()
-    assert 1 == bitvector_rotate_left.getNumIndices()
-    assert 1 == bitvector_rotate_right.getNumIndices()
-    assert 1 == int_to_bitvector.getNumIndices()
-    assert 1 == iand.getNumIndices()
-    assert 1 == floatingpoint_to_ubv.getNumIndices()
-    assert 1 == floatingopint_to_sbv.getNumIndices()
-    assert 2 == floatingpoint_to_fp_ieee_bitvector.getNumIndices()
-    assert 2 == floatingpoint_to_fp_floatingpoint.getNumIndices()
-    assert 2 == floatingpoint_to_fp_real.getNumIndices()
-    assert 2 == floatingpoint_to_fp_signed_bitvector.getNumIndices()
-    assert 2 == floatingpoint_to_fp_unsigned_bitvector.getNumIndices()
-    assert 2 == floatingpoint_to_fp_generic.getNumIndices()
-    assert 2 == regexp_loop.getNumIndices()
-
-def test_op_indices_list(solver):
-    with_list = solver.mkOp(kinds.TupleProject, [4, 25])
-    assert 2 == with_list.getNumIndices()
-
-def test_get_indices_string(solver):
-    x = Op(solver)
-    with pytest.raises(RuntimeError):
-        x.getIndices()
-
-    divisible_ot = solver.mkOp(kinds.Divisible, 4)
-    assert divisible_ot.isIndexed()
-    divisible_idx = divisible_ot.getIndices()
-    assert divisible_idx == "4"
-
-
-def test_get_indices_uint(solver):
-    bitvector_repeat_ot = solver.mkOp(kinds.BVRepeat, 5)
-    assert bitvector_repeat_ot.isIndexed()
-    bitvector_repeat_idx = bitvector_repeat_ot.getIndices()
-    assert bitvector_repeat_idx == 5
-
-    bitvector_zero_extend_ot = solver.mkOp(kinds.BVZeroExtend, 6)
-    bitvector_zero_extend_idx = bitvector_zero_extend_ot.getIndices()
-    assert bitvector_zero_extend_idx == 6
-
-    bitvector_sign_extend_ot = solver.mkOp(kinds.BVSignExtend, 7)
-    bitvector_sign_extend_idx = bitvector_sign_extend_ot.getIndices()
-    assert bitvector_sign_extend_idx == 7
-
-    bitvector_rotate_left_ot = solver.mkOp(kinds.BVRotateLeft, 8)
-    bitvector_rotate_left_idx = bitvector_rotate_left_ot.getIndices()
-    assert bitvector_rotate_left_idx == 8
-
-    bitvector_rotate_right_ot = solver.mkOp(kinds.BVRotateRight, 9)
-    bitvector_rotate_right_idx = bitvector_rotate_right_ot.getIndices()
-    assert bitvector_rotate_right_idx == 9
-
-    int_to_bitvector_ot = solver.mkOp(kinds.IntToBV, 10)
-    int_to_bitvector_idx = int_to_bitvector_ot.getIndices()
-    assert int_to_bitvector_idx == 10
-
-    floatingpoint_to_ubv_ot = solver.mkOp(kinds.FPToUbv, 11)
-    floatingpoint_to_ubv_idx = floatingpoint_to_ubv_ot.getIndices()
-    assert floatingpoint_to_ubv_idx == 11
-
-    floatingpoint_to_sbv_ot = solver.mkOp(kinds.FPToSbv, 13)
-    floatingpoint_to_sbv_idx = floatingpoint_to_sbv_ot.getIndices()
-    assert floatingpoint_to_sbv_idx == 13
-
-
-def test_get_indices_pair_uint(solver):
-    bitvector_extract_ot = solver.mkOp(kinds.BVExtract, 4, 0)
-    assert bitvector_extract_ot.isIndexed()
-    bitvector_extract_indices = bitvector_extract_ot.getIndices()
-    assert bitvector_extract_indices == (4, 0)
-
-    floatingpoint_to_fp_ieee_bitvector_ot = solver.mkOp(
-        kinds.FPToFpIeeeBV, 4, 25)
-    floatingpoint_to_fp_ieee_bitvector_indices = floatingpoint_to_fp_ieee_bitvector_ot.getIndices(
-    )
-    assert floatingpoint_to_fp_ieee_bitvector_indices == (4, 25)
-
-    floatingpoint_to_fp_floatingpoint_ot = solver.mkOp(kinds.FPToFpFP, 4, 25)
-    floatingpoint_to_fp_floatingpoint_indices = floatingpoint_to_fp_floatingpoint_ot.getIndices(
-    )
-    assert floatingpoint_to_fp_floatingpoint_indices == (4, 25)
-
-    floatingpoint_to_fp_real_ot = solver.mkOp(kinds.FPToFpReal, 4, 25)
-    floatingpoint_to_fp_real_indices = floatingpoint_to_fp_real_ot.getIndices()
-    assert floatingpoint_to_fp_real_indices == (4, 25)
-
-    floatingpoint_to_fp_signed_bitvector_ot = solver.mkOp(
-        kinds.FPToFpSignedBV, 4, 25)
-    floatingpoint_to_fp_signed_bitvector_indices = floatingpoint_to_fp_signed_bitvector_ot.getIndices(
-    )
-    assert floatingpoint_to_fp_signed_bitvector_indices == (4, 25)
-
-    floatingpoint_to_fp_unsigned_bitvector_ot = solver.mkOp(
-        kinds.FPToFpUnsignedBV, 4, 25)
-    floatingpoint_to_fp_unsigned_bitvector_indices = floatingpoint_to_fp_unsigned_bitvector_ot.getIndices(
-    )
-    assert floatingpoint_to_fp_unsigned_bitvector_indices == (4, 25)
-
-    floatingpoint_to_fp_generic_ot = solver.mkOp(kinds.FPToFpGeneric, 4, 25)
-    floatingpoint_to_fp_generic_indices = floatingpoint_to_fp_generic_ot.getIndices(
-    )
-    assert floatingpoint_to_fp_generic_indices == (4, 25)
-
-
-def test_op_scoping_to_string(solver):
-    bitvector_repeat_ot = solver.mkOp(kinds.BVRepeat, 5)
-    op_repr = str(bitvector_repeat_ot)
-    assert str(bitvector_repeat_ot) == op_repr
diff --git a/test/python/unit/api/test_result.py b/test/python/unit/api/test_result.py
deleted file mode 100644 (file)
index bd97646..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-###############################################################################
-# Top contributors (to current version):
-#   Yoni Zohar
-#
-# This file is part of the cvc5 project.
-#
-# Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
-# in the top-level source directory and their institutional affiliations.
-# All rights reserved.  See the file COPYING in the top-level source
-# directory for licensing information.
-# #############################################################################
-#
-# Unit tests for result API.
-#
-# Obtained by translating test/unit/api/result_black.cpp
-##
-
-import pytest
-import pycvc5
-from pycvc5 import kinds
-from pycvc5 import Result
-from pycvc5 import UnknownExplanation
-
-
-@pytest.fixture
-def solver():
-    return pycvc5.Solver()
-
-
-def test_is_null(solver):
-    res_null = Result(solver)
-    assert res_null.isNull()
-    assert not res_null.isSat()
-    assert not res_null.isUnsat()
-    assert not res_null.isSatUnknown()
-    assert not res_null.isEntailed()
-    assert not res_null.isNotEntailed()
-    assert not res_null.isEntailmentUnknown()
-    u_sort = solver.mkUninterpretedSort("u")
-    x = solver.mkVar(u_sort, "x")
-    solver.assertFormula(x.eqTerm(x))
-    res = solver.checkSat()
-    assert not res.isNull()
-
-
-def test_eq(solver):
-    u_sort = solver.mkUninterpretedSort("u")
-    x = solver.mkVar(u_sort, "x")
-    solver.assertFormula(x.eqTerm(x))
-    res2 = solver.checkSat()
-    res3 = solver.checkSat()
-    res = res2
-    assert res == res2
-    assert res3 == res2
-
-
-def test_is_sat(solver):
-    u_sort = solver.mkUninterpretedSort("u")
-    x = solver.mkVar(u_sort, "x")
-    solver.assertFormula(x.eqTerm(x))
-    res = solver.checkSat()
-    assert res.isSat()
-    assert not res.isSatUnknown()
-
-
-def test_is_unsat(solver):
-    u_sort = solver.mkUninterpretedSort("u")
-    x = solver.mkVar(u_sort, "x")
-    solver.assertFormula(x.eqTerm(x).notTerm())
-    res = solver.checkSat()
-    assert res.isUnsat()
-    assert not res.isSatUnknown()
-
-
-def test_is_sat_unknown(solver):
-    solver.setLogic("QF_NIA")
-    solver.setOption("incremental", "false")
-    solver.setOption("solve-int-as-bv", "32")
-    int_sort = solver.getIntegerSort()
-    x = solver.mkVar(int_sort, "x")
-    solver.assertFormula(x.eqTerm(x).notTerm())
-    res = solver.checkSat()
-    assert not res.isSat()
-    assert res.isSatUnknown()
-
-
-def test_is_entailed(solver):
-    solver.setOption("incremental", "true")
-    u_sort = solver.mkUninterpretedSort("u")
-    x = solver.mkConst(u_sort, "x")
-    y = solver.mkConst(u_sort, "y")
-    a = x.eqTerm(y).notTerm()
-    b = x.eqTerm(y)
-    solver.assertFormula(a)
-    entailed = solver.checkEntailed(a)
-    assert entailed.isEntailed()
-    assert not entailed.isEntailmentUnknown()
-    not_entailed = solver.checkEntailed(b)
-    assert not_entailed.isNotEntailed()
-    assert not not_entailed.isEntailmentUnknown()
-
-
-def test_is_entailment_unknown(solver):
-    solver.setLogic("QF_NIA")
-    solver.setOption("incremental", "false")
-    solver.setOption("solve-int-as-bv", "32")
-    int_sort = solver.getIntegerSort()
-    x = solver.mkVar(int_sort, "x")
-    solver.assertFormula(x.eqTerm(x).notTerm())
-    res = solver.checkEntailed(x.eqTerm(x))
-    assert not res.isEntailed()
-    assert res.isEntailmentUnknown()
-    print(type(pycvc5.RoundTowardZero))
-    print(type(pycvc5.UnknownReason))
-    assert res.getUnknownExplanation() == pycvc5.UnknownReason
diff --git a/test/python/unit/api/test_solver.py b/test/python/unit/api/test_solver.py
deleted file mode 100644 (file)
index 71ab174..0000000
+++ /dev/null
@@ -1,1884 +0,0 @@
-###############################################################################
-# Top contributors (to current version):
-#   Yoni Zohar, Ying Sheng
-#
-# This file is part of the cvc5 project.
-#
-# Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
-# in the top-level source directory and their institutional affiliations.
-# All rights reserved.  See the file COPYING in the top-level source
-# directory for licensing information.
-# #############################################################################
-##
-
-import pytest
-import pycvc5
-import sys
-
-from pycvc5 import kinds
-
-
-@pytest.fixture
-def solver():
-    return pycvc5.Solver()
-
-
-def test_recoverable_exception(solver):
-    solver.setOption("produce-models", "true")
-    x = solver.mkConst(solver.getBooleanSort(), "x")
-    solver.assertFormula(x.eqTerm(x).notTerm())
-    with pytest.raises(RuntimeError):
-        c = solver.getValue(x)
-
-
-def test_supports_floating_point(solver):
-    solver.mkRoundingMode(pycvc5.RoundNearestTiesToEven)
-
-
-def test_get_boolean_sort(solver):
-    solver.getBooleanSort()
-
-
-def test_get_integer_sort(solver):
-    solver.getIntegerSort()
-
-
-def test_get_null_sort(solver):
-    solver.getNullSort()
-
-
-def test_get_real_sort(solver):
-    solver.getRealSort()
-
-
-def test_get_reg_exp_sort(solver):
-    solver.getRegExpSort()
-
-
-def test_get_string_sort(solver):
-    solver.getStringSort()
-
-
-def test_get_rounding_mode_sort(solver):
-    solver.getRoundingModeSort()
-
-
-def test_mk_array_sort(solver):
-    boolSort = solver.getBooleanSort()
-    intSort = solver.getIntegerSort()
-    realSort = solver.getRealSort()
-    bvSort = solver.mkBitVectorSort(32)
-    solver.mkArraySort(boolSort, boolSort)
-    solver.mkArraySort(intSort, intSort)
-    solver.mkArraySort(realSort, realSort)
-    solver.mkArraySort(bvSort, bvSort)
-    solver.mkArraySort(boolSort, intSort)
-    solver.mkArraySort(realSort, bvSort)
-
-    fpSort = solver.mkFloatingPointSort(3, 5)
-    solver.mkArraySort(fpSort, fpSort)
-    solver.mkArraySort(bvSort, fpSort)
-
-    slv = pycvc5.Solver()
-    with pytest.raises(RuntimeError):
-        slv.mkArraySort(boolSort, boolSort)
-
-
-def test_mk_bit_vector_sort(solver):
-    solver.mkBitVectorSort(32)
-    with pytest.raises(RuntimeError):
-        solver.mkBitVectorSort(0)
-
-
-def test_mk_floating_point_sort(solver):
-    solver.mkFloatingPointSort(4, 8)
-    with pytest.raises(RuntimeError):
-        solver.mkFloatingPointSort(0, 8)
-    with pytest.raises(RuntimeError):
-        solver.mkFloatingPointSort(4, 0)
-
-
-def test_mk_datatype_sort(solver):
-    dtypeSpec = solver.mkDatatypeDecl("list")
-    cons = solver.mkDatatypeConstructorDecl("cons")
-    cons.addSelector("head", solver.getIntegerSort())
-    dtypeSpec.addConstructor(cons)
-    nil = solver.mkDatatypeConstructorDecl("nil")
-    dtypeSpec.addConstructor(nil)
-    solver.mkDatatypeSort(dtypeSpec)
-
-    slv = pycvc5.Solver()
-    with pytest.raises(RuntimeError):
-        slv.mkDatatypeSort(dtypeSpec)
-
-    throwsDtypeSpec = solver.mkDatatypeDecl("list")
-    with pytest.raises(RuntimeError):
-        solver.mkDatatypeSort(throwsDtypeSpec)
-
-
-def test_mk_datatype_sorts(solver):
-    slv = pycvc5.Solver()
-
-    dtypeSpec1 = solver.mkDatatypeDecl("list1")
-    cons1 = solver.mkDatatypeConstructorDecl("cons1")
-    cons1.addSelector("head1", solver.getIntegerSort())
-    dtypeSpec1.addConstructor(cons1)
-    nil1 = solver.mkDatatypeConstructorDecl("nil1")
-    dtypeSpec1.addConstructor(nil1)
-
-    dtypeSpec2 = solver.mkDatatypeDecl("list2")
-    cons2 = solver.mkDatatypeConstructorDecl("cons2")
-    cons2.addSelector("head2", solver.getIntegerSort())
-    dtypeSpec2.addConstructor(cons2)
-    nil2 = solver.mkDatatypeConstructorDecl("nil2")
-    dtypeSpec2.addConstructor(nil2)
-
-    decls = [dtypeSpec1, dtypeSpec2]
-    solver.mkDatatypeSorts(decls, set([]))
-
-    with pytest.raises(RuntimeError):
-        slv.mkDatatypeSorts(decls, set([]))
-
-    throwsDtypeSpec = solver.mkDatatypeDecl("list")
-    throwsDecls = [throwsDtypeSpec]
-    with pytest.raises(RuntimeError):
-        solver.mkDatatypeSorts(throwsDecls, set([]))
-
-    # with unresolved sorts
-    unresList = solver.mkUninterpretedSort("ulist")
-    unresSorts = set([unresList])
-    ulist = solver.mkDatatypeDecl("ulist")
-    ucons = solver.mkDatatypeConstructorDecl("ucons")
-    ucons.addSelector("car", unresList)
-    ucons.addSelector("cdr", unresList)
-    ulist.addConstructor(ucons)
-    unil = solver.mkDatatypeConstructorDecl("unil")
-    ulist.addConstructor(unil)
-    udecls = [ulist]
-
-    solver.mkDatatypeSorts(udecls, unresSorts)
-    with pytest.raises(RuntimeError):
-        slv.mkDatatypeSorts(udecls, unresSorts)
-
-
-def test_mk_function_sort(solver):
-    funSort = solver.mkFunctionSort(solver.mkUninterpretedSort("u"),\
-            solver.getIntegerSort())
-
-    # function arguments are allowed
-    solver.mkFunctionSort(funSort, solver.getIntegerSort())
-
-    # non-first-class arguments are not allowed
-    reSort = solver.getRegExpSort()
-    with pytest.raises(RuntimeError):
-        solver.mkFunctionSort(reSort, solver.getIntegerSort())
-    with pytest.raises(RuntimeError):
-        solver.mkFunctionSort(solver.getIntegerSort(), funSort)
-
-    solver.mkFunctionSort([solver.mkUninterpretedSort("u"),\
-            solver.getIntegerSort()],\
-            solver.getIntegerSort())
-    funSort2 = solver.mkFunctionSort(solver.mkUninterpretedSort("u"),\
-            solver.getIntegerSort())
-
-    # function arguments are allowed
-    solver.mkFunctionSort([funSort2, solver.mkUninterpretedSort("u")],\
-            solver.getIntegerSort())
-
-    with pytest.raises(RuntimeError):
-        solver.mkFunctionSort([solver.getIntegerSort(),\
-                solver.mkUninterpretedSort("u")],\
-                funSort2)
-
-    slv = pycvc5.Solver()
-    with pytest.raises(RuntimeError):
-        slv.mkFunctionSort(solver.mkUninterpretedSort("u"),\
-                solver.getIntegerSort())
-    with pytest.raises(RuntimeError):
-        slv.mkFunctionSort(slv.mkUninterpretedSort("u"),\
-                solver.getIntegerSort())
-    sorts1 = [solver.getBooleanSort(),\
-            slv.getIntegerSort(),\
-            solver.getIntegerSort()]
-    sorts2 = [slv.getBooleanSort(), slv.getIntegerSort()]
-    slv.mkFunctionSort(sorts2, slv.getIntegerSort())
-    with pytest.raises(RuntimeError):
-        slv.mkFunctionSort(sorts1, slv.getIntegerSort())
-    with pytest.raises(RuntimeError):
-        slv.mkFunctionSort(sorts2, solver.getIntegerSort())
-
-
-def test_mk_param_sort(solver):
-    solver.mkParamSort("T")
-    solver.mkParamSort("")
-
-
-def test_mk_predicate_sort(solver):
-    solver.mkPredicateSort([solver.getIntegerSort()])
-    with pytest.raises(RuntimeError):
-        solver.mkPredicateSort([])
-
-    funSort = solver.mkFunctionSort(solver.mkUninterpretedSort("u"),\
-            solver.getIntegerSort())
-    # functions as arguments are allowed
-    solver.mkPredicateSort([solver.getIntegerSort(), funSort])
-
-    slv = pycvc5.Solver()
-    with pytest.raises(RuntimeError):
-        slv.mkPredicateSort([solver.getIntegerSort()])
-
-
-def test_mk_record_sort(solver):
-    fields = [("b", solver.getBooleanSort()),\
-              ("bv", solver.mkBitVectorSort(8)),\
-              ("i", solver.getIntegerSort())]
-    empty = []
-    solver.mkRecordSort(fields)
-    solver.mkRecordSort(empty)
-    recSort = solver.mkRecordSort(fields)
-    recSort.getDatatype()
-
-
-def test_mk_set_sort(solver):
-    solver.mkSetSort(solver.getBooleanSort())
-    solver.mkSetSort(solver.getIntegerSort())
-    solver.mkSetSort(solver.mkBitVectorSort(4))
-    slv = pycvc5.Solver()
-    with pytest.raises(RuntimeError):
-        slv.mkSetSort(solver.mkBitVectorSort(4))
-
-
-def test_mk_bag_sort(solver):
-    solver.mkBagSort(solver.getBooleanSort())
-    solver.mkBagSort(solver.getIntegerSort())
-    solver.mkBagSort(solver.mkBitVectorSort(4))
-    slv = pycvc5.Solver()
-    with pytest.raises(RuntimeError):
-        slv.mkBagSort(solver.mkBitVectorSort(4))
-
-
-def test_mk_sequence_sort(solver):
-    solver.mkSequenceSort(solver.getBooleanSort())
-    solver.mkSequenceSort(\
-            solver.mkSequenceSort(solver.getIntegerSort()))
-    slv = pycvc5.Solver()
-    with pytest.raises(RuntimeError):
-        slv.mkSequenceSort(solver.getIntegerSort())
-
-
-def test_mk_uninterpreted_sort(solver):
-    solver.mkUninterpretedSort("u")
-    solver.mkUninterpretedSort("")
-
-
-def test_mk_sortConstructor_sort(solver):
-    solver.mkSortConstructorSort("s", 2)
-    solver.mkSortConstructorSort("", 2)
-    with pytest.raises(RuntimeError):
-        solver.mkSortConstructorSort("", 0)
-
-
-def test_mk_tuple_sort(solver):
-    solver.mkTupleSort([solver.getIntegerSort()])
-    funSort = solver.mkFunctionSort(solver.mkUninterpretedSort("u"),\
-                                    solver.getIntegerSort())
-    with pytest.raises(RuntimeError):
-        solver.mkTupleSort([solver.getIntegerSort(), funSort])
-
-    slv = pycvc5.Solver()
-    with pytest.raises(RuntimeError):
-        slv.mkTupleSort([solver.getIntegerSort()])
-
-
-def test_mk_bit_vector(solver):
-    solver.mkBitVector(8, 2)
-    solver.mkBitVector(32, 2)
-
-    solver.mkBitVector(4, "1010", 2)
-    solver.mkBitVector(8, "0101", 2)
-    solver.mkBitVector(8, "-1111111", 2)
-    solver.mkBitVector(8, "00000101", 2)
-    solver.mkBitVector(8, "-127", 10)
-    solver.mkBitVector(8, "255", 10)
-    solver.mkBitVector(10, "1010", 10)
-    solver.mkBitVector(11, "1234", 10)
-    solver.mkBitVector(8, "-7f", 16)
-    solver.mkBitVector(8, "a0", 16)
-    solver.mkBitVector(16, "1010", 16)
-    solver.mkBitVector(16, "a09f", 16)
-
-    with pytest.raises(RuntimeError):
-        solver.mkBitVector(0, 2)
-    with pytest.raises(RuntimeError):
-        solver.mkBitVector(0, "-127", 10)
-    with pytest.raises(RuntimeError):
-        solver.mkBitVector(0, "a0", 16)
-
-    with pytest.raises(RuntimeError):
-        solver.mkBitVector(2, "", 2)
-
-    with pytest.raises(RuntimeError):
-        solver.mkBitVector(8, "101", 5)
-    with pytest.raises(RuntimeError):
-        solver.mkBitVector(8, "127", 11)
-    with pytest.raises(RuntimeError):
-        solver.mkBitVector(8, "a0", 21)
-
-    with pytest.raises(RuntimeError):
-        solver.mkBitVector(8, "101010101", 2)
-    with pytest.raises(RuntimeError):
-        solver.mkBitVector(8, "-11111111", 2)
-    with pytest.raises(RuntimeError):
-        solver.mkBitVector(8, "-256", 10)
-    with pytest.raises(RuntimeError):
-        solver.mkBitVector(8, "257", 10)
-    with pytest.raises(RuntimeError):
-        solver.mkBitVector(8, "-a0", 16)
-    with pytest.raises(RuntimeError):
-        solver.mkBitVector(8, "fffff", 16)
-
-    with pytest.raises(RuntimeError):
-        solver.mkBitVector(8, "10201010", 2)
-    with pytest.raises(RuntimeError):
-        solver.mkBitVector(8, "-25x", 10)
-    with pytest.raises(RuntimeError):
-        solver.mkBitVector(8, "2x7", 10)
-    with pytest.raises(RuntimeError):
-        solver.mkBitVector(8, "fzff", 16)
-
-    assert solver.mkBitVector(8, "0101", 2) == solver.mkBitVector(8, "00000101", 2)
-    assert solver.mkBitVector(4, "1010", 2) == solver.mkBitVector(4, "10", 10)
-    assert solver.mkBitVector(4, "1010", 2) == solver.mkBitVector(4, "a", 16)
-    assert str(solver.mkBitVector(8, "01010101", 2)) == "#b01010101"
-    assert str(solver.mkBitVector(8, "F", 16)) == "#b00001111"
-    assert solver.mkBitVector(8, "-1", 10) ==\
-            solver.mkBitVector(8, "FF", 16)
-
-
-def test_mk_var(solver):
-    boolSort = solver.getBooleanSort()
-    intSort = solver.getIntegerSort()
-    funSort = solver.mkFunctionSort(intSort, boolSort)
-    solver.mkVar(boolSort)
-    solver.mkVar(funSort)
-    solver.mkVar(boolSort, "b")
-    solver.mkVar(funSort, "")
-    with pytest.raises(RuntimeError):
-        solver.mkVar(pycvc5.Sort(solver))
-    with pytest.raises(RuntimeError):
-        solver.mkVar(pycvc5.Sort(solver), "a")
-    slv = pycvc5.Solver()
-    with pytest.raises(RuntimeError):
-        slv.mkVar(boolSort, "x")
-
-
-def test_mk_boolean(solver):
-    solver.mkBoolean(True)
-    solver.mkBoolean(False)
-
-
-def test_mk_rounding_mode(solver):
-    solver.mkRoundingMode(pycvc5.RoundTowardZero)
-
-
-def test_mk_abstract_value(solver):
-    solver.mkAbstractValue("1")
-    with pytest.raises(ValueError):
-        solver.mkAbstractValue("0")
-    with pytest.raises(ValueError):
-        solver.mkAbstractValue("-1")
-    with pytest.raises(ValueError):
-        solver.mkAbstractValue("1.2")
-    with pytest.raises(ValueError):
-        solver.mkAbstractValue("1/2")
-    with pytest.raises(ValueError):
-        solver.mkAbstractValue("asdf")
-
-    solver.mkAbstractValue(1)
-    with pytest.raises(ValueError):
-        solver.mkAbstractValue(-1)
-    with pytest.raises(ValueError):
-        solver.mkAbstractValue(0)
-
-
-def test_mk_floating_point(solver):
-    t1 = solver.mkBitVector(8)
-    t2 = solver.mkBitVector(4)
-    t3 = solver.mkInteger(2)
-    solver.mkFloatingPoint(3, 5, t1)
-
-    with pytest.raises(RuntimeError):
-        solver.mkFloatingPoint(0, 5, pycvc5.Term(solver))
-    with pytest.raises(RuntimeError):
-        solver.mkFloatingPoint(0, 5, t1)
-    with pytest.raises(RuntimeError):
-        solver.mkFloatingPoint(3, 0, t1)
-    with pytest.raises(RuntimeError):
-        solver.mkFloatingPoint(3, 5, t2)
-    with pytest.raises(RuntimeError):
-        solver.mkFloatingPoint(3, 5, t2)
-
-    slv = pycvc5.Solver()
-    with pytest.raises(RuntimeError):
-        slv.mkFloatingPoint(3, 5, t1)
-
-def test_mk_cardinality_constraint(solver):
-    su = solver.mkUninterpretedSort("u")
-    si = solver.getIntegerSort()
-    solver.mkCardinalityConstraint(su, 3)
-    with pytest.raises(RuntimeError):
-        solver.mkEmptySet(solver.mkCardinalityConstraint(si, 3))
-    with pytest.raises(RuntimeError):
-        solver.mkEmptySet(solver.mkCardinalityConstraint(su, 0))
-    slv = pycvc5.Solver()
-    with pytest.raises(RuntimeError):
-        slv.mkCardinalityConstraint(su, 3)
-
-def test_mk_empty_set(solver):
-    slv = pycvc5.Solver()
-    s = solver.mkSetSort(solver.getBooleanSort())
-    solver.mkEmptySet(pycvc5.Sort(solver))
-    solver.mkEmptySet(s)
-    with pytest.raises(RuntimeError):
-        solver.mkEmptySet(solver.getBooleanSort())
-    with pytest.raises(RuntimeError):
-        slv.mkEmptySet(s)
-
-
-def test_mk_empty_bag(solver):
-    slv = pycvc5.Solver()
-    s = solver.mkBagSort(solver.getBooleanSort())
-    solver.mkEmptyBag(pycvc5.Sort(solver))
-    solver.mkEmptyBag(s)
-    with pytest.raises(RuntimeError):
-        solver.mkEmptyBag(solver.getBooleanSort())
-    with pytest.raises(RuntimeError):
-        slv.mkEmptyBag(s)
-
-
-def test_mk_empty_sequence(solver):
-    slv = pycvc5.Solver()
-    s = solver.mkSequenceSort(solver.getBooleanSort())
-    solver.mkEmptySequence(s)
-    solver.mkEmptySequence(solver.getBooleanSort())
-    with pytest.raises(RuntimeError):
-        slv.mkEmptySequence(s)
-
-
-def test_mk_false(solver):
-    solver.mkFalse()
-    solver.mkFalse()
-
-
-def test_mk_nan(solver):
-    solver.mkNaN(3, 5)
-
-
-def test_mk_neg_zero(solver):
-    solver.mkNegZero(3, 5)
-
-
-def test_mk_neg_inf(solver):
-    solver.mkNegInf(3, 5)
-
-
-def test_mk_pos_inf(solver):
-    solver.mkPosInf(3, 5)
-
-
-def test_mk_pos_zero(solver):
-    solver.mkPosZero(3, 5)
-
-
-def test_mk_op(solver):
-    # mkOp(Kind kind, Kind k)
-    with pytest.raises(ValueError):
-        solver.mkOp(kinds.BVExtract, kinds.Equal)
-
-    # mkOp(Kind kind, const std::string& arg)
-    solver.mkOp(kinds.Divisible, "2147483648")
-    with pytest.raises(RuntimeError):
-        solver.mkOp(kinds.BVExtract, "asdf")
-
-    # mkOp(Kind kind, uint32_t arg)
-    solver.mkOp(kinds.Divisible, 1)
-    solver.mkOp(kinds.BVRotateLeft, 1)
-    solver.mkOp(kinds.BVRotateRight, 1)
-    with pytest.raises(RuntimeError):
-        solver.mkOp(kinds.BVExtract, 1)
-
-    # mkOp(Kind kind, uint32_t arg1, uint32_t arg2)
-    solver.mkOp(kinds.BVExtract, 1, 1)
-    with pytest.raises(RuntimeError):
-        solver.mkOp(kinds.Divisible, 1, 2)
-
-    # mkOp(Kind kind, std::vector<uint32_t> args)
-    args = [1, 2, 2]
-    solver.mkOp(kinds.TupleProject, args)
-
-
-def test_mk_pi(solver):
-    solver.mkPi()
-
-
-def test_mk_integer(solver):
-    solver.mkInteger("123")
-    with pytest.raises(RuntimeError):
-        solver.mkInteger("1.23")
-    with pytest.raises(RuntimeError):
-        solver.mkInteger("1/23")
-    with pytest.raises(RuntimeError):
-        solver.mkInteger("12/3")
-    with pytest.raises(RuntimeError):
-        solver.mkInteger(".2")
-    with pytest.raises(RuntimeError):
-        solver.mkInteger("2.")
-    with pytest.raises(RuntimeError):
-        solver.mkInteger("")
-    with pytest.raises(RuntimeError):
-        solver.mkInteger("asdf")
-    with pytest.raises(RuntimeError):
-        solver.mkInteger("1.2/3")
-    with pytest.raises(RuntimeError):
-        solver.mkInteger(".")
-    with pytest.raises(RuntimeError):
-        solver.mkInteger("/")
-    with pytest.raises(RuntimeError):
-        solver.mkInteger("2/")
-    with pytest.raises(RuntimeError):
-        solver.mkInteger("/2")
-
-    solver.mkReal("123")
-    with pytest.raises(RuntimeError):
-        solver.mkInteger("1.23")
-    with pytest.raises(RuntimeError):
-        solver.mkInteger("1/23")
-    with pytest.raises(RuntimeError):
-        solver.mkInteger("12/3")
-    with pytest.raises(RuntimeError):
-        solver.mkInteger(".2")
-    with pytest.raises(RuntimeError):
-        solver.mkInteger("2.")
-    with pytest.raises(RuntimeError):
-        solver.mkInteger("")
-    with pytest.raises(RuntimeError):
-        solver.mkInteger("asdf")
-    with pytest.raises(RuntimeError):
-        solver.mkInteger("1.2/3")
-    with pytest.raises(RuntimeError):
-        solver.mkInteger(".")
-    with pytest.raises(RuntimeError):
-        solver.mkInteger("/")
-    with pytest.raises(RuntimeError):
-        solver.mkInteger("2/")
-    with pytest.raises(RuntimeError):
-        solver.mkInteger("/2")
-
-    val1 = 1
-    val2 = -1
-    val3 = 1
-    val4 = -1
-    solver.mkInteger(val1)
-    solver.mkInteger(val2)
-    solver.mkInteger(val3)
-    solver.mkInteger(val4)
-    solver.mkInteger(val4)
-
-
-def test_mk_real(solver):
-    solver.mkReal("123")
-    solver.mkReal("1.23")
-    solver.mkReal("1/23")
-    solver.mkReal("12/3")
-    solver.mkReal(".2")
-    solver.mkReal("2.")
-    with pytest.raises(RuntimeError):
-        solver.mkReal("")
-    with pytest.raises(RuntimeError):
-        solver.mkReal("asdf")
-    with pytest.raises(RuntimeError):
-        solver.mkReal("1.2/3")
-    with pytest.raises(RuntimeError):
-        solver.mkReal(".")
-    with pytest.raises(RuntimeError):
-        solver.mkReal("/")
-    with pytest.raises(RuntimeError):
-        solver.mkReal("2/")
-    with pytest.raises(RuntimeError):
-        solver.mkReal("/2")
-
-    solver.mkReal("123")
-    solver.mkReal("1.23")
-    solver.mkReal("1/23")
-    solver.mkReal("12/3")
-    solver.mkReal(".2")
-    solver.mkReal("2.")
-    with pytest.raises(RuntimeError):
-        solver.mkReal("")
-    with pytest.raises(RuntimeError):
-        solver.mkReal("asdf")
-    with pytest.raises(RuntimeError):
-        solver.mkReal("1.2/3")
-    with pytest.raises(RuntimeError):
-        solver.mkReal(".")
-    with pytest.raises(RuntimeError):
-        solver.mkReal("/")
-    with pytest.raises(RuntimeError):
-        solver.mkReal("2/")
-    with pytest.raises(RuntimeError):
-        solver.mkReal("/2")
-
-    val1 = 1
-    val2 = -1
-    val3 = 1
-    val4 = -1
-    solver.mkReal(val1)
-    solver.mkReal(val2)
-    solver.mkReal(val3)
-    solver.mkReal(val4)
-    solver.mkReal(val4)
-    solver.mkReal(val1, val1)
-    solver.mkReal(val2, val2)
-    solver.mkReal(val3, val3)
-    solver.mkReal(val4, val4)
-
-
-def test_mk_regexp_empty(solver):
-    strSort = solver.getStringSort()
-    s = solver.mkConst(strSort, "s")
-    solver.mkTerm(kinds.StringInRegexp, s, solver.mkRegexpNone())
-
-
-def test_mk_regexp_sigma(solver):
-    strSort = solver.getStringSort()
-    s = solver.mkConst(strSort, "s")
-    solver.mkTerm(kinds.StringInRegexp, s, solver.mkRegexpAllchar())
-
-
-def test_mk_sep_emp(solver):
-    solver.mkSepEmp();
-
-
-def test_mk_sep_nil(solver):
-    solver.mkSepNil(solver.getBooleanSort())
-    with pytest.raises(RuntimeError):
-        solver.mkSepNil(pycvc5.Sort(solver))
-    slv = pycvc5.Solver()
-    with pytest.raises(RuntimeError):
-        slv.mkSepNil(solver.getIntegerSort())
-
-
-def test_mk_string(solver):
-    solver.mkString("")
-    solver.mkString("asdfasdf")
-    str(solver.mkString("asdf\\nasdf")) == "\"asdf\\u{5c}nasdf\""
-    str(solver.mkString("asdf\\u{005c}nasdf", True)) ==\
-            "\"asdf\\u{5c}nasdf\""
-
-
-def test_mk_term(solver):
-    bv32 = solver.mkBitVectorSort(32)
-    a = solver.mkConst(bv32, "a")
-    b = solver.mkConst(bv32, "b")
-    v1 = [a, b]
-    v2 = [a, pycvc5.Term(solver)]
-    v3 = [a, solver.mkTrue()]
-    v4 = [solver.mkInteger(1), solver.mkInteger(2)]
-    v5 = [solver.mkInteger(1), pycvc5.Term(solver)]
-    v6 = []
-    slv = pycvc5.Solver()
-
-    # mkTerm(Kind kind) const
-    solver.mkPi()
-    solver.mkTerm(kinds.RegexpNone)
-    solver.mkTerm(kinds.RegexpAllchar)
-    with pytest.raises(RuntimeError):
-        solver.mkTerm(kinds.ConstBV)
-
-    # mkTerm(Kind kind, Term child) const
-    solver.mkTerm(kinds.Not, solver.mkTrue())
-    with pytest.raises(RuntimeError):
-        solver.mkTerm(kinds.Not, pycvc5.Term(solver))
-    with pytest.raises(RuntimeError):
-        solver.mkTerm(kinds.Not, a)
-    with pytest.raises(RuntimeError):
-        slv.mkTerm(kinds.Not, solver.mkTrue())
-
-    # mkTerm(Kind kind, Term child1, Term child2) const
-    solver.mkTerm(kinds.Equal, a, b)
-    with pytest.raises(RuntimeError):
-        solver.mkTerm(kinds.Equal, pycvc5.Term(solver), b)
-    with pytest.raises(RuntimeError):
-        solver.mkTerm(kinds.Equal, a, pycvc5.Term(solver))
-    with pytest.raises(RuntimeError):
-        solver.mkTerm(kinds.Equal, a, solver.mkTrue())
-    with pytest.raises(RuntimeError):
-        slv.mkTerm(kinds.Equal, a, b)
-
-    # mkTerm(Kind kind, Term child1, Term child2, Term child3) const
-    solver.mkTerm(kinds.Ite, solver.mkTrue(), solver.mkTrue(), solver.mkTrue())
-    with pytest.raises(RuntimeError):
-        solver.mkTerm(kinds.Ite, pycvc5.Term(solver), solver.mkTrue(),
-                      solver.mkTrue())
-    with pytest.raises(RuntimeError):
-        solver.mkTerm(kinds.Ite, solver.mkTrue(), pycvc5.Term(solver),
-                      solver.mkTrue())
-    with pytest.raises(RuntimeError):
-        solver.mkTerm(kinds.Ite, solver.mkTrue(), solver.mkTrue(),
-                      pycvc5.Term(solver))
-    with pytest.raises(RuntimeError):
-        solver.mkTerm(kinds.Ite, solver.mkTrue(), solver.mkTrue(), b)
-    with pytest.raises(RuntimeError):
-        slv.mkTerm(kinds.Ite, solver.mkTrue(), solver.mkTrue(),
-                   solver.mkTrue())
-
-    # mkTerm(Kind kind, const std::vector<Term>& children) const
-    solver.mkTerm(kinds.Equal, v1)
-    with pytest.raises(RuntimeError):
-        solver.mkTerm(kinds.Equal, v2)
-    with pytest.raises(RuntimeError):
-        solver.mkTerm(kinds.Equal, v3)
-    with pytest.raises(RuntimeError):
-        solver.mkTerm(kinds.Distinct, v6)
-
-
-def test_mk_term_from_op(solver):
-    bv32 = solver.mkBitVectorSort(32)
-    a = solver.mkConst(bv32, "a")
-    b = solver.mkConst(bv32, "b")
-    v1 = [solver.mkInteger(1), solver.mkInteger(2)]
-    v2 = [solver.mkInteger(1), pycvc5.Term(solver)]
-    v3 = []
-    v4 = [solver.mkInteger(5)]
-    slv = pycvc5.Solver()
-
-    # simple operator terms
-    opterm1 = solver.mkOp(kinds.BVExtract, 2, 1)
-    opterm2 = solver.mkOp(kinds.Divisible, 1)
-
-    # list datatype
-    sort = solver.mkParamSort("T")
-    listDecl = solver.mkDatatypeDecl("paramlist", sort)
-    cons = solver.mkDatatypeConstructorDecl("cons")
-    nil = solver.mkDatatypeConstructorDecl("nil")
-    cons.addSelector("head", sort)
-    cons.addSelectorSelf("tail")
-    listDecl.addConstructor(cons)
-    listDecl.addConstructor(nil)
-    listSort = solver.mkDatatypeSort(listDecl)
-    intListSort =\
-        listSort.instantiate([solver.getIntegerSort()])
-    c = solver.mkConst(intListSort, "c")
-    lis = listSort.getDatatype()
-
-    # list datatype constructor and selector operator terms
-    consTerm1 = lis.getConstructorTerm("cons")
-    consTerm2 = lis.getConstructor("cons").getConstructorTerm()
-    nilTerm1 = lis.getConstructorTerm("nil")
-    nilTerm2 = lis.getConstructor("nil").getConstructorTerm()
-    headTerm1 = lis["cons"].getSelectorTerm("head")
-    headTerm2 = lis["cons"].getSelector("head").getSelectorTerm()
-    tailTerm1 = lis["cons"].getSelectorTerm("tail")
-    tailTerm2 = lis["cons"]["tail"].getSelectorTerm()
-
-    # mkTerm(Op op, Term term) const
-    solver.mkTerm(kinds.ApplyConstructor, nilTerm1)
-    solver.mkTerm(kinds.ApplyConstructor, nilTerm2)
-    with pytest.raises(RuntimeError):
-        solver.mkTerm(kinds.ApplySelector, nilTerm1)
-    with pytest.raises(RuntimeError):
-        solver.mkTerm(kinds.ApplySelector, consTerm1)
-    with pytest.raises(RuntimeError):
-        solver.mkTerm(kinds.ApplyConstructor, consTerm2)
-    with pytest.raises(RuntimeError):
-        solver.mkTerm(opterm1)
-    with pytest.raises(RuntimeError):
-        solver.mkTerm(kinds.ApplySelector, headTerm1)
-    with pytest.raises(RuntimeError):
-        solver.mkTerm(opterm1)
-    with pytest.raises(RuntimeError):
-        slv.mkTerm(kinds.ApplyConstructor, nilTerm1)
-
-    # mkTerm(Op op, Term child) const
-    solver.mkTerm(opterm1, a)
-    solver.mkTerm(opterm2, solver.mkInteger(1))
-    solver.mkTerm(kinds.ApplySelector, headTerm1, c)
-    solver.mkTerm(kinds.ApplySelector, tailTerm2, c)
-    with pytest.raises(RuntimeError):
-        solver.mkTerm(opterm2, a)
-    with pytest.raises(RuntimeError):
-        solver.mkTerm(opterm1, pycvc5.Term(solver))
-    with pytest.raises(RuntimeError):
-        solver.mkTerm(kinds.ApplyConstructor, consTerm1, solver.mkInteger(0))
-    with pytest.raises(RuntimeError):
-        slv.mkTerm(opterm1, a)
-
-    # mkTerm(Op op, Term child1, Term child2) const
-    solver.mkTerm(kinds.ApplyConstructor, consTerm1, solver.mkInteger(0),
-                  solver.mkTerm(kinds.ApplyConstructor, nilTerm1))
-    with pytest.raises(RuntimeError):
-        solver.mkTerm(opterm2, solver.mkInteger(1), solver.mkInteger(2))
-    with pytest.raises(RuntimeError):
-        solver.mkTerm(opterm1, a, b)
-    with pytest.raises(RuntimeError):
-        solver.mkTerm(opterm2, solver.mkInteger(1), pycvc5.Term(solver))
-    with pytest.raises(RuntimeError):
-        solver.mkTerm(opterm2, pycvc5.Term(solver), solver.mkInteger(1))
-    with pytest.raises(RuntimeError):
-        slv.mkTerm(kinds.ApplyConstructor,\
-                        consTerm1,\
-                        solver.mkInteger(0),\
-                        solver.mkTerm(kinds.ApplyConstructor, nilTerm1))
-
-    # mkTerm(Op op, Term child1, Term child2, Term child3) const
-    with pytest.raises(RuntimeError):
-        solver.mkTerm(opterm1, a, b, a)
-    with pytest.raises(RuntimeError):
-        solver.mkTerm(opterm2, solver.mkInteger(1), solver.mkInteger(1),
-                      pycvc5.Term(solver))
-
-    # mkTerm(Op op, const std::vector<Term>& children) const
-    solver.mkTerm(opterm2, v4)
-    with pytest.raises(RuntimeError):
-        solver.mkTerm(opterm2, v1)
-    with pytest.raises(RuntimeError):
-        solver.mkTerm(opterm2, v2)
-    with pytest.raises(RuntimeError):
-        solver.mkTerm(opterm2, v3)
-    with pytest.raises(RuntimeError):
-        slv.mkTerm(opterm2, v4)
-
-
-def test_mk_true(solver):
-    solver.mkTrue()
-    solver.mkTrue()
-
-
-def test_mk_tuple(solver):
-    solver.mkTuple([solver.mkBitVectorSort(3)], [solver.mkBitVector(3, "101", 2)])
-    solver.mkTuple([solver.getRealSort()], [solver.mkInteger("5")])
-
-    with pytest.raises(RuntimeError):
-        solver.mkTuple([], [solver.mkBitVector(3, "101", 2)])
-    with pytest.raises(RuntimeError):
-        solver.mkTuple([solver.mkBitVectorSort(4)],
-                       [solver.mkBitVector(3, "101", 2)])
-    with pytest.raises(RuntimeError):
-        solver.mkTuple([solver.getIntegerSort()], [solver.mkReal("5.3")])
-    slv = pycvc5.Solver()
-    with pytest.raises(RuntimeError):
-        slv.mkTuple([solver.mkBitVectorSort(3)], [slv.mkBitVector(3, "101", 2)])
-    with pytest.raises(RuntimeError):
-        slv.mkTuple([slv.mkBitVectorSort(3)], [solver.mkBitVector(3, "101", 2)])
-
-
-def test_mk_universe_set(solver):
-    solver.mkUniverseSet(solver.getBooleanSort())
-    with pytest.raises(RuntimeError):
-        solver.mkUniverseSet(pycvc5.Sort(solver))
-    slv = pycvc5.Solver()
-    with pytest.raises(RuntimeError):
-        slv.mkUniverseSet(solver.getBooleanSort())
-
-
-def test_mk_const(solver):
-    boolSort = solver.getBooleanSort()
-    intSort = solver.getIntegerSort()
-    funSort = solver.mkFunctionSort(intSort, boolSort)
-    solver.mkConst(boolSort)
-    solver.mkConst(funSort)
-    solver.mkConst(boolSort, "b")
-    solver.mkConst(intSort, "i")
-    solver.mkConst(funSort, "f")
-    solver.mkConst(funSort, "")
-    with pytest.raises(RuntimeError):
-        solver.mkConst(pycvc5.Sort(solver))
-    with pytest.raises(RuntimeError):
-        solver.mkConst(pycvc5.Sort(solver), "a")
-
-    slv = pycvc5.Solver()
-    with pytest.raises(RuntimeError):
-        slv.mkConst(boolSort)
-
-
-def test_mk_const_array(solver):
-    intSort = solver.getIntegerSort()
-    arrSort = solver.mkArraySort(intSort, intSort)
-    zero = solver.mkInteger(0)
-    constArr = solver.mkConstArray(arrSort, zero)
-
-    solver.mkConstArray(arrSort, zero)
-    with pytest.raises(RuntimeError):
-        solver.mkConstArray(pycvc5.Sort(solver), zero)
-    with pytest.raises(RuntimeError):
-        solver.mkConstArray(arrSort, pycvc5.Term(solver))
-    with pytest.raises(RuntimeError):
-        solver.mkConstArray(arrSort, solver.mkBitVector(1, 1))
-    with pytest.raises(RuntimeError):
-        solver.mkConstArray(intSort, zero)
-    slv = pycvc5.Solver()
-    zero2 = slv.mkInteger(0)
-    arrSort2 = slv.mkArraySort(slv.getIntegerSort(), slv.getIntegerSort())
-    with pytest.raises(RuntimeError):
-        slv.mkConstArray(arrSort2, zero)
-    with pytest.raises(RuntimeError):
-        slv.mkConstArray(arrSort, zero2)
-
-
-def test_declare_fun(solver):
-    bvSort = solver.mkBitVectorSort(32)
-    funSort = solver.mkFunctionSort(solver.mkUninterpretedSort("u"),\
-                                    solver.getIntegerSort())
-    solver.declareFun("f1", [], bvSort)
-    solver.declareFun("f3", [bvSort, solver.getIntegerSort()], bvSort)
-    with pytest.raises(RuntimeError):
-        solver.declareFun("f2", [], funSort)
-    # functions as arguments is allowed
-    solver.declareFun("f4", [bvSort, funSort], bvSort)
-    with pytest.raises(RuntimeError):
-        solver.declareFun("f5", [bvSort, bvSort], funSort)
-    slv = pycvc5.Solver()
-    with pytest.raises(RuntimeError):
-        slv.declareFun("f1", [], bvSort)
-
-
-def test_declare_sort(solver):
-    solver.declareSort("s", 0)
-    solver.declareSort("s", 2)
-    solver.declareSort("", 2)
-
-
-def test_define_fun(solver):
-    bvSort = solver.mkBitVectorSort(32)
-    funSort = solver.mkFunctionSort(solver.mkUninterpretedSort("u"),
-                                    solver.getIntegerSort())
-    b1 = solver.mkVar(bvSort, "b1")
-    b2 = solver.mkVar(solver.getIntegerSort(), "b2")
-    b3 = solver.mkVar(funSort, "b3")
-    v1 = solver.mkConst(bvSort, "v1")
-    v2 = solver.mkConst(funSort, "v2")
-    solver.defineFun("f", [], bvSort, v1)
-    solver.defineFun("ff", [b1, b2], bvSort, v1)
-    with pytest.raises(RuntimeError):
-        solver.defineFun("ff", [v1, b2], bvSort, v1)
-    with pytest.raises(RuntimeError):
-        solver.defineFun("fff", [b1], bvSort, v2)
-    with pytest.raises(RuntimeError):
-        solver.defineFun("ffff", [b1], funSort, v2)
-    # b3 has function sort, which is allowed as an argument
-    solver.defineFun("fffff", [b1, b3], bvSort, v1)
-
-    slv = pycvc5.Solver()
-    bvSort2 = slv.mkBitVectorSort(32)
-    v12 = slv.mkConst(bvSort2, "v1")
-    b12 = slv.mkVar(bvSort2, "b1")
-    b22 = slv.mkVar(slv.getIntegerSort(), "b2")
-    with pytest.raises(RuntimeError):
-        slv.defineFun("f", [], bvSort, v12)
-    with pytest.raises(RuntimeError):
-        slv.defineFun("f", [], bvSort2, v1)
-    with pytest.raises(RuntimeError):
-        slv.defineFun("ff", [b1, b22], bvSort2, v12)
-    with pytest.raises(RuntimeError):
-        slv.defineFun("ff", [b12, b2], bvSort2, v12)
-    with pytest.raises(RuntimeError):
-        slv.defineFun("ff", [b12, b22], bvSort, v12)
-    with pytest.raises(RuntimeError):
-        slv.defineFun("ff", [b12, b22], bvSort2, v1)
-
-
-def test_define_fun_rec(solver):
-    bvSort = solver.mkBitVectorSort(32)
-    funSort1 = solver.mkFunctionSort([bvSort, bvSort], bvSort)
-    funSort2 = solver.mkFunctionSort(solver.mkUninterpretedSort("u"),\
-                                     solver.getIntegerSort())
-    b1 = solver.mkVar(bvSort, "b1")
-    b11 = solver.mkVar(bvSort, "b1")
-    b2 = solver.mkVar(solver.getIntegerSort(), "b2")
-    b3 = solver.mkVar(funSort2, "b3")
-    v1 = solver.mkConst(bvSort, "v1")
-    v2 = solver.mkConst(solver.getIntegerSort(), "v2")
-    v3 = solver.mkConst(funSort2, "v3")
-    f1 = solver.mkConst(funSort1, "f1")
-    f2 = solver.mkConst(funSort2, "f2")
-    f3 = solver.mkConst(bvSort, "f3")
-    solver.defineFunRec("f", [], bvSort, v1)
-    solver.defineFunRec("ff", [b1, b2], bvSort, v1)
-    solver.defineFunRec(f1, [b1, b11], v1)
-    with pytest.raises(RuntimeError):
-        solver.defineFunRec("fff", [b1], bvSort, v3)
-    with pytest.raises(RuntimeError):
-        solver.defineFunRec("ff", [b1, v2], bvSort, v1)
-    with pytest.raises(RuntimeError):
-        solver.defineFunRec("ffff", [b1], funSort2, v3)
-    # b3 has function sort, which is allowed as an argument
-    solver.defineFunRec("fffff", [b1, b3], bvSort, v1)
-    with pytest.raises(RuntimeError):
-        solver.defineFunRec(f1, [b1], v1)
-    with pytest.raises(RuntimeError):
-        solver.defineFunRec(f1, [b1, b11], v2)
-    with pytest.raises(RuntimeError):
-        solver.defineFunRec(f1, [b1, b11], v3)
-    with pytest.raises(RuntimeError):
-        solver.defineFunRec(f2, [b1], v2)
-    with pytest.raises(RuntimeError):
-        solver.defineFunRec(f3, [b1], v1)
-
-    slv = pycvc5.Solver()
-    bvSort2 = slv.mkBitVectorSort(32)
-    v12 = slv.mkConst(bvSort2, "v1")
-    b12 = slv.mkVar(bvSort2, "b1")
-    b22 = slv.mkVar(slv.getIntegerSort(), "b2")
-    slv.defineFunRec("f", [], bvSort2, v12)
-    slv.defineFunRec("ff", [b12, b22], bvSort2, v12)
-    with pytest.raises(RuntimeError):
-        slv.defineFunRec("f", [], bvSort, v12)
-    with pytest.raises(RuntimeError):
-        slv.defineFunRec("f", [], bvSort2, v1)
-    with pytest.raises(RuntimeError):
-        slv.defineFunRec("ff", [b1, b22], bvSort2, v12)
-    with pytest.raises(RuntimeError):
-        slv.defineFunRec("ff", [b12, b2], bvSort2, v12)
-    with pytest.raises(RuntimeError):
-        slv.defineFunRec("ff", [b12, b22], bvSort, v12)
-    with pytest.raises(RuntimeError):
-        slv.defineFunRec("ff", [b12, b22], bvSort2, v1)
-
-
-def test_define_fun_rec_wrong_logic(solver):
-    solver.setLogic("QF_BV")
-    bvSort = solver.mkBitVectorSort(32)
-    funSort = solver.mkFunctionSort([bvSort, bvSort], bvSort)
-    b = solver.mkVar(bvSort, "b")
-    v = solver.mkConst(bvSort, "v")
-    f = solver.mkConst(funSort, "f")
-    with pytest.raises(RuntimeError):
-        solver.defineFunRec("f", [], bvSort, v)
-    with pytest.raises(RuntimeError):
-        solver.defineFunRec(f, [b, b], v)
-
-
-def test_uf_iteration(solver):
-    intSort = solver.getIntegerSort()
-    funSort = solver.mkFunctionSort([intSort, intSort], intSort)
-    x = solver.mkConst(intSort, "x")
-    y = solver.mkConst(intSort, "y")
-    f = solver.mkConst(funSort, "f")
-    fxy = solver.mkTerm(kinds.ApplyUf, f, x, y)
-
-    # Expecting the uninterpreted function to be one of the children
-    expected_children = [f, x, y]
-    idx = 0
-    for c in fxy:
-        assert idx < 3
-        assert c == expected_children[idx]
-        idx = idx + 1
-
-
-def test_get_info(solver):
-    solver.getInfo("name")
-    with pytest.raises(RuntimeError):
-        solver.getInfo("asdf")
-
-
-def test_get_op(solver):
-    bv32 = solver.mkBitVectorSort(32)
-    a = solver.mkConst(bv32, "a")
-    ext = solver.mkOp(kinds.BVExtract, 2, 1)
-    exta = solver.mkTerm(ext, a)
-
-    assert not a.hasOp()
-    with pytest.raises(RuntimeError):
-        a.getOp()
-    assert exta.hasOp()
-    assert exta.getOp() == ext
-
-    # Test Datatypes -- more complicated
-    consListSpec = solver.mkDatatypeDecl("list")
-    cons = solver.mkDatatypeConstructorDecl("cons")
-    cons.addSelector("head", solver.getIntegerSort())
-    cons.addSelectorSelf("tail")
-    consListSpec.addConstructor(cons)
-    nil = solver.mkDatatypeConstructorDecl("nil")
-    consListSpec.addConstructor(nil)
-    consListSort = solver.mkDatatypeSort(consListSpec)
-    consList = consListSort.getDatatype()
-
-    consTerm = consList.getConstructorTerm("cons")
-    nilTerm = consList.getConstructorTerm("nil")
-    headTerm = consList["cons"].getSelectorTerm("head")
-
-    listnil = solver.mkTerm(kinds.ApplyConstructor, nilTerm)
-    listcons1 = solver.mkTerm(kinds.ApplyConstructor, consTerm,
-                              solver.mkInteger(1), listnil)
-    listhead = solver.mkTerm(kinds.ApplySelector, headTerm, listcons1)
-
-    assert listnil.hasOp()
-    assert listcons1.hasOp()
-    assert listhead.hasOp()
-
-
-def test_get_option(solver):
-    solver.getOption("incremental")
-    with pytest.raises(RuntimeError):
-        solver.getOption("asdf")
-
-
-def test_get_unsat_assumptions1(solver):
-    solver.setOption("incremental", "false")
-    solver.checkSatAssuming(solver.mkFalse())
-    with pytest.raises(RuntimeError):
-        solver.getUnsatAssumptions()
-
-
-def test_get_unsat_assumptions2(solver):
-    solver.setOption("incremental", "true")
-    solver.setOption("produce-unsat-assumptions", "false")
-    solver.checkSatAssuming(solver.mkFalse())
-    with pytest.raises(RuntimeError):
-        solver.getUnsatAssumptions()
-
-
-def test_get_unsat_assumptions3(solver):
-    solver.setOption("incremental", "true")
-    solver.setOption("produce-unsat-assumptions", "true")
-    solver.checkSatAssuming(solver.mkFalse())
-    solver.getUnsatAssumptions()
-    solver.checkSatAssuming(solver.mkTrue())
-    with pytest.raises(RuntimeError):
-        solver.getUnsatAssumptions()
-
-
-def test_get_unsat_core1(solver):
-    solver.setOption("incremental", "false")
-    solver.assertFormula(solver.mkFalse())
-    solver.checkSat()
-    with pytest.raises(RuntimeError):
-        solver.getUnsatCore()
-
-
-def test_get_unsat_core2(solver):
-    solver.setOption("incremental", "false")
-    solver.setOption("produce-unsat-cores", "false")
-    solver.assertFormula(solver.mkFalse())
-    solver.checkSat()
-    with pytest.raises(RuntimeError):
-        solver.getUnsatCore()
-
-
-def test_get_unsat_core3(solver):
-    solver.setOption("incremental", "true")
-    solver.setOption("produce-unsat-cores", "true")
-
-    uSort = solver.mkUninterpretedSort("u")
-    intSort = solver.getIntegerSort()
-    boolSort = solver.getBooleanSort()
-    uToIntSort = solver.mkFunctionSort(uSort, intSort)
-    intPredSort = solver.mkFunctionSort(intSort, boolSort)
-
-    x = solver.mkConst(uSort, "x")
-    y = solver.mkConst(uSort, "y")
-    f = solver.mkConst(uToIntSort, "f")
-    p = solver.mkConst(intPredSort, "p")
-    zero = solver.mkInteger(0)
-    one = solver.mkInteger(1)
-    f_x = solver.mkTerm(kinds.ApplyUf, f, x)
-    f_y = solver.mkTerm(kinds.ApplyUf, f, y)
-    summ = solver.mkTerm(kinds.Plus, f_x, f_y)
-    p_0 = solver.mkTerm(kinds.ApplyUf, p, zero)
-    p_f_y = solver.mkTerm(kinds.ApplyUf, p, f_y)
-    solver.assertFormula(solver.mkTerm(kinds.Gt, zero, f_x))
-    solver.assertFormula(solver.mkTerm(kinds.Gt, zero, f_y))
-    solver.assertFormula(solver.mkTerm(kinds.Gt, summ, one))
-    solver.assertFormula(p_0)
-    solver.assertFormula(p_f_y.notTerm())
-    assert solver.checkSat().isUnsat()
-
-    unsat_core = solver.getUnsatCore()
-
-    solver.resetAssertions()
-    for t in unsat_core:
-        solver.assertFormula(t)
-    res = solver.checkSat()
-    assert res.isUnsat()
-
-
-def test_get_value1(solver):
-    solver.setOption("produce-models", "false")
-    t = solver.mkTrue()
-    solver.assertFormula(t)
-    solver.checkSat()
-    with pytest.raises(RuntimeError):
-        solver.getValue(t)
-
-
-def test_get_value2(solver):
-    solver.setOption("produce-models", "true")
-    t = solver.mkFalse()
-    solver.assertFormula(t)
-    solver.checkSat()
-    with pytest.raises(RuntimeError):
-        solver.getValue(t)
-
-
-def test_get_value3(solver):
-    solver.setOption("produce-models", "true")
-    uSort = solver.mkUninterpretedSort("u")
-    intSort = solver.getIntegerSort()
-    boolSort = solver.getBooleanSort()
-    uToIntSort = solver.mkFunctionSort(uSort, intSort)
-    intPredSort = solver.mkFunctionSort(intSort, boolSort)
-
-    x = solver.mkConst(uSort, "x")
-    y = solver.mkConst(uSort, "y")
-    z = solver.mkConst(uSort, "z")
-    f = solver.mkConst(uToIntSort, "f")
-    p = solver.mkConst(intPredSort, "p")
-    zero = solver.mkInteger(0)
-    one = solver.mkInteger(1)
-    f_x = solver.mkTerm(kinds.ApplyUf, f, x)
-    f_y = solver.mkTerm(kinds.ApplyUf, f, y)
-    summ = solver.mkTerm(kinds.Plus, f_x, f_y)
-    p_0 = solver.mkTerm(kinds.ApplyUf, p, zero)
-    p_f_y = solver.mkTerm(kinds.ApplyUf, p, f_y)
-
-    solver.assertFormula(solver.mkTerm(kinds.Leq, zero, f_x))
-    solver.assertFormula(solver.mkTerm(kinds.Leq, zero, f_y))
-    solver.assertFormula(solver.mkTerm(kinds.Leq, summ, one))
-    solver.assertFormula(p_0.notTerm())
-    solver.assertFormula(p_f_y)
-    assert solver.checkSat().isSat()
-    solver.getValue(x)
-    solver.getValue(y)
-    solver.getValue(z)
-    solver.getValue(summ)
-    solver.getValue(p_f_y)
-
-    slv = pycvc5.Solver()
-    with pytest.raises(RuntimeError):
-        slv.getValue(x)
-
-
-def test_declare_separation_heap(solver):
-    solver.setLogic("ALL")
-    integer = solver.getIntegerSort()
-    solver.declareSepHeap(integer, integer)
-    # cannot declare separation logic heap more than once
-    with pytest.raises(RuntimeError):
-        solver.declareSepHeap(integer, integer)
-
-
-# Helper function for test_get_separation_{heap,nil}_termX. Asserts and checks
-# some simple separation logic constraints.
-def checkSimpleSeparationConstraints(slv):
-    integer = slv.getIntegerSort()
-    # declare the separation heap
-    slv.declareSepHeap(integer, integer)
-    x = slv.mkConst(integer, "x")
-    p = slv.mkConst(integer, "p")
-    heap = slv.mkTerm(kinds.SepPto, p, x)
-    slv.assertFormula(heap)
-    nil = slv.mkSepNil(integer)
-    slv.assertFormula(nil.eqTerm(slv.mkReal(5)))
-    slv.checkSat()
-
-
-def test_get_separation_heap_term1(solver):
-    solver.setLogic("QF_BV")
-    solver.setOption("incremental", "false")
-    solver.setOption("produce-models", "true")
-    t = solver.mkTrue()
-    solver.assertFormula(t)
-    with pytest.raises(RuntimeError):
-        solver.getValueSepHeap()
-
-
-def test_get_separation_heap_term2(solver):
-    solver.setLogic("ALL")
-    solver.setOption("incremental", "false")
-    solver.setOption("produce-models", "false")
-    checkSimpleSeparationConstraints(solver)
-    with pytest.raises(RuntimeError):
-        solver.getValueSepHeap()
-
-
-def test_get_separation_heap_term3(solver):
-    solver.setLogic("ALL")
-    solver.setOption("incremental", "false")
-    solver.setOption("produce-models", "true")
-    t = solver.mkFalse()
-    solver.assertFormula(t)
-    solver.checkSat()
-    with pytest.raises(RuntimeError):
-        solver.getValueSepHeap()
-
-
-def test_get_separation_heap_term4(solver):
-    solver.setLogic("ALL")
-    solver.setOption("incremental", "false")
-    solver.setOption("produce-models", "true")
-    t = solver.mkTrue()
-    solver.assertFormula(t)
-    solver.checkSat()
-    with pytest.raises(RuntimeError):
-        solver.getValueSepHeap()
-
-
-def test_get_separation_heap_term5(solver):
-    solver.setLogic("ALL")
-    solver.setOption("incremental", "false")
-    solver.setOption("produce-models", "true")
-    checkSimpleSeparationConstraints(solver)
-    solver.getValueSepHeap()
-
-
-def test_get_separation_nil_term1(solver):
-    solver.setLogic("QF_BV")
-    solver.setOption("incremental", "false")
-    solver.setOption("produce-models", "true")
-    t = solver.mkTrue()
-    solver.assertFormula(t)
-    with pytest.raises(RuntimeError):
-        solver.getValueSepNil()
-
-
-def test_get_separation_nil_term2(solver):
-    solver.setLogic("ALL")
-    solver.setOption("incremental", "false")
-    solver.setOption("produce-models", "false")
-    checkSimpleSeparationConstraints(solver)
-    with pytest.raises(RuntimeError):
-        solver.getValueSepNil()
-
-
-def test_get_separation_nil_term3(solver):
-    solver.setLogic("ALL")
-    solver.setOption("incremental", "false")
-    solver.setOption("produce-models", "true")
-    t = solver.mkFalse()
-    solver.assertFormula(t)
-    solver.checkSat()
-    with pytest.raises(RuntimeError):
-        solver.getValueSepNil()
-
-
-def test_get_separation_nil_term4(solver):
-    solver.setLogic("ALL")
-    solver.setOption("incremental", "false")
-    solver.setOption("produce-models", "true")
-    t = solver.mkTrue()
-    solver.assertFormula(t)
-    solver.checkSat()
-    with pytest.raises(RuntimeError):
-        solver.getValueSepNil()
-
-
-def test_get_separation_nil_term5(solver):
-    solver.setLogic("ALL")
-    solver.setOption("incremental", "false")
-    solver.setOption("produce-models", "true")
-    checkSimpleSeparationConstraints(solver)
-    solver.getValueSepNil()
-
-
-def test_push1(solver):
-    solver.setOption("incremental", "true")
-    solver.push(1)
-    with pytest.raises(RuntimeError):
-        solver.setOption("incremental", "false")
-    with pytest.raises(RuntimeError):
-        solver.setOption("incremental", "true")
-
-
-def test_push2(solver):
-    solver.setOption("incremental", "false")
-    with pytest.raises(RuntimeError):
-        solver.push(1)
-
-
-def test_pop1(solver):
-    solver.setOption("incremental", "false")
-    with pytest.raises(RuntimeError):
-        solver.pop(1)
-
-
-def test_pop2(solver):
-    solver.setOption("incremental", "true")
-    with pytest.raises(RuntimeError):
-        solver.pop(1)
-
-
-def test_pop3(solver):
-    solver.setOption("incremental", "true")
-    solver.push(1)
-    solver.pop(1)
-    with pytest.raises(RuntimeError):
-        solver.pop(1)
-
-
-def test_setInfo(solver):
-    with pytest.raises(RuntimeError):
-        solver.setInfo("cvc5-lagic", "QF_BV")
-    with pytest.raises(RuntimeError):
-        solver.setInfo("cvc2-logic", "QF_BV")
-    with pytest.raises(RuntimeError):
-        solver.setInfo("cvc5-logic", "asdf")
-
-    solver.setInfo("source", "asdf")
-    solver.setInfo("category", "asdf")
-    solver.setInfo("difficulty", "asdf")
-    solver.setInfo("filename", "asdf")
-    solver.setInfo("license", "asdf")
-    solver.setInfo("name", "asdf")
-    solver.setInfo("notes", "asdf")
-
-    solver.setInfo("smt-lib-version", "2")
-    solver.setInfo("smt-lib-version", "2.0")
-    solver.setInfo("smt-lib-version", "2.5")
-    solver.setInfo("smt-lib-version", "2.6")
-    with pytest.raises(RuntimeError):
-        solver.setInfo("smt-lib-version", ".0")
-
-    solver.setInfo("status", "sat")
-    solver.setInfo("status", "unsat")
-    solver.setInfo("status", "unknown")
-    with pytest.raises(RuntimeError):
-        solver.setInfo("status", "asdf")
-
-
-def test_simplify(solver):
-    with pytest.raises(RuntimeError):
-        solver.simplify(pycvc5.Term(solver))
-
-    bvSort = solver.mkBitVectorSort(32)
-    uSort = solver.mkUninterpretedSort("u")
-    funSort1 = solver.mkFunctionSort([bvSort, bvSort], bvSort)
-    funSort2 = solver.mkFunctionSort(uSort, solver.getIntegerSort())
-    consListSpec = solver.mkDatatypeDecl("list")
-    cons = solver.mkDatatypeConstructorDecl("cons")
-    cons.addSelector("head", solver.getIntegerSort())
-    cons.addSelectorSelf("tail")
-    consListSpec.addConstructor(cons)
-    nil = solver.mkDatatypeConstructorDecl("nil")
-    consListSpec.addConstructor(nil)
-    consListSort = solver.mkDatatypeSort(consListSpec)
-
-    x = solver.mkConst(bvSort, "x")
-    solver.simplify(x)
-    a = solver.mkConst(bvSort, "a")
-    solver.simplify(a)
-    b = solver.mkConst(bvSort, "b")
-    solver.simplify(b)
-    x_eq_x = solver.mkTerm(kinds.Equal, x, x)
-    solver.simplify(x_eq_x)
-    assert solver.mkTrue() != x_eq_x
-    assert solver.mkTrue() == solver.simplify(x_eq_x)
-    x_eq_b = solver.mkTerm(kinds.Equal, x, b)
-    solver.simplify(x_eq_b)
-    assert solver.mkTrue() != x_eq_b
-    assert solver.mkTrue() != solver.simplify(x_eq_b)
-    slv = pycvc5.Solver()
-    with pytest.raises(RuntimeError):
-        slv.simplify(x)
-
-    i1 = solver.mkConst(solver.getIntegerSort(), "i1")
-    solver.simplify(i1)
-    i2 = solver.mkTerm(kinds.Mult, i1, solver.mkInteger("23"))
-    solver.simplify(i2)
-    assert i1 != i2
-    assert i1 != solver.simplify(i2)
-    i3 = solver.mkTerm(kinds.Plus, i1, solver.mkInteger(0))
-    solver.simplify(i3)
-    assert i1 != i3
-    assert i1 == solver.simplify(i3)
-
-    consList = consListSort.getDatatype()
-    dt1 = solver.mkTerm(\
-        kinds.ApplyConstructor,\
-        consList.getConstructorTerm("cons"),\
-        solver.mkInteger(0),\
-        solver.mkTerm(kinds.ApplyConstructor, consList.getConstructorTerm("nil")))
-    solver.simplify(dt1)
-    dt2 = solver.mkTerm(\
-      kinds.ApplySelector, consList["cons"].getSelectorTerm("head"), dt1)
-    solver.simplify(dt2)
-
-    b1 = solver.mkVar(bvSort, "b1")
-    solver.simplify(b1)
-    b2 = solver.mkVar(bvSort, "b1")
-    solver.simplify(b2)
-    b3 = solver.mkVar(uSort, "b3")
-    solver.simplify(b3)
-    v1 = solver.mkConst(bvSort, "v1")
-    solver.simplify(v1)
-    v2 = solver.mkConst(solver.getIntegerSort(), "v2")
-    solver.simplify(v2)
-    f1 = solver.mkConst(funSort1, "f1")
-    solver.simplify(f1)
-    f2 = solver.mkConst(funSort2, "f2")
-    solver.simplify(f2)
-    solver.defineFunsRec([f1, f2], [[b1, b2], [b3]], [v1, v2])
-    solver.simplify(f1)
-    solver.simplify(f2)
-
-
-def test_assert_formula(solver):
-    solver.assertFormula(solver.mkTrue())
-    with pytest.raises(RuntimeError):
-        solver.assertFormula(pycvc5.Term(solver))
-    slv = pycvc5.Solver()
-    with pytest.raises(RuntimeError):
-        slv.assertFormula(solver.mkTrue())
-
-
-def test_check_entailed(solver):
-    solver.setOption("incremental", "false")
-    solver.checkEntailed(solver.mkTrue())
-    with pytest.raises(RuntimeError):
-        solver.checkEntailed(solver.mkTrue())
-    slv = pycvc5.Solver()
-    with pytest.raises(RuntimeError):
-        slv.checkEntailed(solver.mkTrue())
-
-
-def test_check_entailed1(solver):
-    boolSort = solver.getBooleanSort()
-    x = solver.mkConst(boolSort, "x")
-    y = solver.mkConst(boolSort, "y")
-    z = solver.mkTerm(kinds.And, x, y)
-    solver.setOption("incremental", "true")
-    solver.checkEntailed(solver.mkTrue())
-    with pytest.raises(RuntimeError):
-        solver.checkEntailed(pycvc5.Term(solver))
-    solver.checkEntailed(solver.mkTrue())
-    solver.checkEntailed(z)
-    slv = pycvc5.Solver()
-    with pytest.raises(RuntimeError):
-        slv.checkEntailed(solver.mkTrue())
-
-
-def test_check_entailed2(solver):
-    solver.setOption("incremental", "true")
-
-    uSort = solver.mkUninterpretedSort("u")
-    intSort = solver.getIntegerSort()
-    boolSort = solver.getBooleanSort()
-    uToIntSort = solver.mkFunctionSort(uSort, intSort)
-    intPredSort = solver.mkFunctionSort(intSort, boolSort)
-
-    n = pycvc5.Term(solver)
-    # Constants
-    x = solver.mkConst(uSort, "x")
-    y = solver.mkConst(uSort, "y")
-    # Functions
-    f = solver.mkConst(uToIntSort, "f")
-    p = solver.mkConst(intPredSort, "p")
-    # Values
-    zero = solver.mkInteger(0)
-    one = solver.mkInteger(1)
-    # Terms
-    f_x = solver.mkTerm(kinds.ApplyUf, f, x)
-    f_y = solver.mkTerm(kinds.ApplyUf, f, y)
-    summ = solver.mkTerm(kinds.Plus, f_x, f_y)
-    p_0 = solver.mkTerm(kinds.ApplyUf, p, zero)
-    p_f_y = solver.mkTerm(kinds.ApplyUf, p, f_y)
-    # Assertions
-    assertions =\
-        solver.mkTerm(kinds.And,\
-                      [solver.mkTerm(kinds.Leq, zero, f_x),  # 0 <= f(x)
-                       solver.mkTerm(kinds.Leq, zero, f_y),  # 0 <= f(y)
-                       solver.mkTerm(kinds.Leq, summ, one),  # f(x) + f(y) <= 1
-                       p_0.notTerm(),                        # not p(0)
-                       p_f_y                                 # p(f(y))
-                      ])
-
-    solver.checkEntailed(solver.mkTrue())
-    solver.assertFormula(assertions)
-    solver.checkEntailed(solver.mkTerm(kinds.Distinct, x, y))
-    solver.checkEntailed(\
-        [solver.mkFalse(), solver.mkTerm(kinds.Distinct, x, y)])
-    with pytest.raises(RuntimeError):
-        solver.checkEntailed(n)
-    with pytest.raises(RuntimeError):
-        solver.checkEntailed([n, solver.mkTerm(kinds.Distinct, x, y)])
-    slv = pycvc5.Solver()
-    with pytest.raises(RuntimeError):
-        slv.checkEntailed(solver.mkTrue())
-
-
-def test_check_sat(solver):
-    solver.setOption("incremental", "false")
-    solver.checkSat()
-    with pytest.raises(RuntimeError):
-        solver.checkSat()
-
-
-def test_check_sat_assuming(solver):
-    solver.setOption("incremental", "false")
-    solver.checkSatAssuming(solver.mkTrue())
-    with pytest.raises(RuntimeError):
-        solver.checkSatAssuming(solver.mkTrue())
-    slv = pycvc5.Solver()
-    with pytest.raises(RuntimeError):
-        slv.checkSatAssuming(solver.mkTrue())
-
-
-def test_check_sat_assuming1(solver):
-    boolSort = solver.getBooleanSort()
-    x = solver.mkConst(boolSort, "x")
-    y = solver.mkConst(boolSort, "y")
-    z = solver.mkTerm(kinds.And, x, y)
-    solver.setOption("incremental", "true")
-    solver.checkSatAssuming(solver.mkTrue())
-    with pytest.raises(RuntimeError):
-        solver.checkSatAssuming(pycvc5.Term(solver))
-    solver.checkSatAssuming(solver.mkTrue())
-    solver.checkSatAssuming(z)
-    slv = pycvc5.Solver()
-    with pytest.raises(RuntimeError):
-        slv.checkSatAssuming(solver.mkTrue())
-
-
-def test_check_sat_assuming2(solver):
-    solver.setOption("incremental", "true")
-
-    uSort = solver.mkUninterpretedSort("u")
-    intSort = solver.getIntegerSort()
-    boolSort = solver.getBooleanSort()
-    uToIntSort = solver.mkFunctionSort(uSort, intSort)
-    intPredSort = solver.mkFunctionSort(intSort, boolSort)
-
-    n = pycvc5.Term(solver)
-    # Constants
-    x = solver.mkConst(uSort, "x")
-    y = solver.mkConst(uSort, "y")
-    # Functions
-    f = solver.mkConst(uToIntSort, "f")
-    p = solver.mkConst(intPredSort, "p")
-    # Values
-    zero = solver.mkInteger(0)
-    one = solver.mkInteger(1)
-    # Terms
-    f_x = solver.mkTerm(kinds.ApplyUf, f, x)
-    f_y = solver.mkTerm(kinds.ApplyUf, f, y)
-    summ = solver.mkTerm(kinds.Plus, f_x, f_y)
-    p_0 = solver.mkTerm(kinds.ApplyUf, p, zero)
-    p_f_y = solver.mkTerm(kinds.ApplyUf, p, f_y)
-    # Assertions
-    assertions =\
-        solver.mkTerm(kinds.And,\
-                      [solver.mkTerm(kinds.Leq, zero, f_x),  # 0 <= f(x)
-                       solver.mkTerm(kinds.Leq, zero, f_y),  # 0 <= f(y)
-                       solver.mkTerm(kinds.Leq, summ, one),  # f(x) + f(y) <= 1
-                       p_0.notTerm(),                        # not p(0)
-                       p_f_y                                 # p(f(y))
-                      ])
-
-    solver.checkSatAssuming(solver.mkTrue())
-    solver.assertFormula(assertions)
-    solver.checkSatAssuming(solver.mkTerm(kinds.Distinct, x, y))
-    solver.checkSatAssuming(
-        [solver.mkFalse(),
-         solver.mkTerm(kinds.Distinct, x, y)])
-    with pytest.raises(RuntimeError):
-        solver.checkSatAssuming(n)
-    with pytest.raises(RuntimeError):
-        solver.checkSatAssuming([n, solver.mkTerm(kinds.Distinct, x, y)])
-    slv = pycvc5.Solver()
-    with pytest.raises(RuntimeError):
-        slv.checkSatAssuming(solver.mkTrue())
-
-
-def test_set_logic(solver):
-    solver.setLogic("AUFLIRA")
-    with pytest.raises(RuntimeError):
-        solver.setLogic("AF_BV")
-    solver.assertFormula(solver.mkTrue())
-    with pytest.raises(RuntimeError):
-        solver.setLogic("AUFLIRA")
-
-
-def test_set_option(solver):
-    solver.setOption("bv-sat-solver", "minisat")
-    with pytest.raises(RuntimeError):
-        solver.setOption("bv-sat-solver", "1")
-    solver.assertFormula(solver.mkTrue())
-    with pytest.raises(RuntimeError):
-        solver.setOption("bv-sat-solver", "minisat")
-
-
-def test_reset_assertions(solver):
-    solver.setOption("incremental", "true")
-
-    bvSort = solver.mkBitVectorSort(4)
-    one = solver.mkBitVector(4, 1)
-    x = solver.mkConst(bvSort, "x")
-    ule = solver.mkTerm(kinds.BVUle, x, one)
-    srem = solver.mkTerm(kinds.BVSrem, one, x)
-    solver.push(4)
-    slt = solver.mkTerm(kinds.BVSlt, srem, one)
-    solver.resetAssertions()
-    solver.checkSatAssuming([slt, ule])
-
-
-def test_mk_sygus_grammar(solver):
-    nullTerm = pycvc5.Term(solver)
-    boolTerm = solver.mkBoolean(True)
-    boolVar = solver.mkVar(solver.getBooleanSort())
-    intVar = solver.mkVar(solver.getIntegerSort())
-
-    solver.mkSygusGrammar([], [intVar])
-    solver.mkSygusGrammar([boolVar], [intVar])
-    with pytest.raises(RuntimeError):
-        solver.mkSygusGrammar([], [])
-    with pytest.raises(RuntimeError):
-        solver.mkSygusGrammar([], [nullTerm])
-    with pytest.raises(RuntimeError):
-        solver.mkSygusGrammar([], [boolTerm])
-    with pytest.raises(RuntimeError):
-        solver.mkSygusGrammar([boolTerm], [intVar])
-    slv = pycvc5.Solver()
-    boolVar2 = slv.mkVar(slv.getBooleanSort())
-    intVar2 = slv.mkVar(slv.getIntegerSort())
-    slv.mkSygusGrammar([boolVar2], [intVar2])
-    with pytest.raises(RuntimeError):
-        slv.mkSygusGrammar([boolVar], [intVar2])
-    with pytest.raises(RuntimeError):
-        slv.mkSygusGrammar([boolVar2], [intVar])
-
-
-def test_synth_inv(solver):
-    boolean = solver.getBooleanSort()
-    integer = solver.getIntegerSort()
-
-    nullTerm = pycvc5.Term(solver)
-    x = solver.mkVar(boolean)
-
-    start1 = solver.mkVar(boolean)
-    start2 = solver.mkVar(integer)
-
-    g1 = solver.mkSygusGrammar([x], [start1])
-    g1.addRule(start1, solver.mkBoolean(False))
-
-    g2 = solver.mkSygusGrammar([x], [start2])
-    g2.addRule(start2, solver.mkInteger(0))
-
-    solver.synthInv("", [])
-    solver.synthInv("i1", [x])
-    solver.synthInv("i2", [x], g1)
-
-    with pytest.raises(RuntimeError):
-        solver.synthInv("i3", [nullTerm])
-    with pytest.raises(RuntimeError):
-        solver.synthInv("i4", [x], g2)
-
-
-def test_add_sygus_constraint(solver):
-    nullTerm = pycvc5.Term(solver)
-    boolTerm = solver.mkBoolean(True)
-    intTerm = solver.mkInteger(1)
-
-    solver.addSygusConstraint(boolTerm)
-    with pytest.raises(RuntimeError):
-        solver.addSygusConstraint(nullTerm)
-    with pytest.raises(RuntimeError):
-        solver.addSygusConstraint(intTerm)
-
-    slv = pycvc5.Solver()
-    with pytest.raises(RuntimeError):
-        slv.addSygusConstraint(boolTerm)
-
-
-def test_add_sygus_inv_constraint(solver):
-    boolean = solver.getBooleanSort()
-    real = solver.getRealSort()
-
-    nullTerm = pycvc5.Term(solver)
-    intTerm = solver.mkInteger(1)
-
-    inv = solver.declareFun("inv", [real], boolean)
-    pre = solver.declareFun("pre", [real], boolean)
-    trans = solver.declareFun("trans", [real, real], boolean)
-    post = solver.declareFun("post", [real], boolean)
-
-    inv1 = solver.declareFun("inv1", [real], real)
-
-    trans1 = solver.declareFun("trans1", [boolean, real], boolean)
-    trans2 = solver.declareFun("trans2", [real, boolean], boolean)
-    trans3 = solver.declareFun("trans3", [real, real], real)
-
-    solver.addSygusInvConstraint(inv, pre, trans, post)
-
-    with pytest.raises(RuntimeError):
-        solver.addSygusInvConstraint(nullTerm, pre, trans, post)
-    with pytest.raises(RuntimeError):
-        solver.addSygusInvConstraint(inv, nullTerm, trans, post)
-    with pytest.raises(RuntimeError):
-        solver.addSygusInvConstraint(inv, pre, nullTerm, post)
-    with pytest.raises(RuntimeError):
-        solver.addSygusInvConstraint(inv, pre, trans, nullTerm)
-
-    with pytest.raises(RuntimeError):
-        solver.addSygusInvConstraint(intTerm, pre, trans, post)
-
-    with pytest.raises(RuntimeError):
-        solver.addSygusInvConstraint(inv1, pre, trans, post)
-
-    with pytest.raises(RuntimeError):
-        solver.addSygusInvConstraint(inv, trans, trans, post)
-
-    with pytest.raises(RuntimeError):
-        solver.addSygusInvConstraint(inv, pre, intTerm, post)
-    with pytest.raises(RuntimeError):
-        solver.addSygusInvConstraint(inv, pre, pre, post)
-    with pytest.raises(RuntimeError):
-        solver.addSygusInvConstraint(inv, pre, trans1, post)
-    with pytest.raises(RuntimeError):
-        solver.addSygusInvConstraint(inv, pre, trans2, post)
-    with pytest.raises(RuntimeError):
-        solver.addSygusInvConstraint(inv, pre, trans3, post)
-
-    with pytest.raises(RuntimeError):
-        solver.addSygusInvConstraint(inv, pre, trans, trans)
-    slv = pycvc5.Solver()
-    boolean2 = slv.getBooleanSort()
-    real2 = slv.getRealSort()
-    inv22 = slv.declareFun("inv", [real2], boolean2)
-    pre22 = slv.declareFun("pre", [real2], boolean2)
-    trans22 = slv.declareFun("trans", [real2, real2], boolean2)
-    post22 = slv.declareFun("post", [real2], boolean2)
-    slv.addSygusInvConstraint(inv22, pre22, trans22, post22)
-    with pytest.raises(RuntimeError):
-        slv.addSygusInvConstraint(inv, pre22, trans22, post22)
-    with pytest.raises(RuntimeError):
-        slv.addSygusInvConstraint(inv22, pre, trans22, post22)
-    with pytest.raises(RuntimeError):
-        slv.addSygusInvConstraint(inv22, pre22, trans, post22)
-    with pytest.raises(RuntimeError):
-        slv.addSygusInvConstraint(inv22, pre22, trans22, post)
-
-
-def test_get_synth_solution(solver):
-    solver.setOption("lang", "sygus2")
-    solver.setOption("incremental", "false")
-
-    nullTerm = pycvc5.Term(solver)
-    x = solver.mkBoolean(False)
-    f = solver.synthFun("f", [], solver.getBooleanSort())
-
-    with pytest.raises(RuntimeError):
-        solver.getSynthSolution(f)
-
-    solver.checkSynth()
-
-    solver.getSynthSolution(f)
-    solver.getSynthSolution(f)
-
-    with pytest.raises(RuntimeError):
-        solver.getSynthSolution(nullTerm)
-    with pytest.raises(RuntimeError):
-        solver.getSynthSolution(x)
-
-    slv = pycvc5.Solver()
-    with pytest.raises(RuntimeError):
-        slv.getSynthSolution(f)
diff --git a/test/python/unit/api/test_sort.py b/test/python/unit/api/test_sort.py
deleted file mode 100644 (file)
index 98cf76d..0000000
+++ /dev/null
@@ -1,575 +0,0 @@
-###############################################################################
-# Top contributors (to current version):
-#   Yoni Zohar, Makai Mann
-#
-# This file is part of the cvc5 project.
-#
-# Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
-# in the top-level source directory and their institutional affiliations.
-# All rights reserved.  See the file COPYING in the top-level source
-# directory for licensing information.
-# #############################################################################
-#
-# Unit tests for sort API.
-#
-# Obtained by translating test/unit/api/sort_black.cpp
-##
-
-import pytest
-import pycvc5
-from pycvc5 import kinds
-from pycvc5 import Sort
-
-
-@pytest.fixture
-def solver():
-    return pycvc5.Solver()
-
-
-def create_datatype_sort(solver):
-    intSort = solver.getIntegerSort()
-    # create datatype sort to test
-    dtypeSpec = solver.mkDatatypeDecl("list")
-    cons = solver.mkDatatypeConstructorDecl("cons")
-    cons.addSelector("head", intSort)
-    cons.addSelectorSelf("tail")
-    dtypeSpec.addConstructor(cons)
-    nil = solver.mkDatatypeConstructorDecl("nil")
-    dtypeSpec.addConstructor(nil)
-    dtypeSort = solver.mkDatatypeSort(dtypeSpec)
-    return dtypeSort
-
-
-def create_param_datatype_sort(solver):
-    sort = solver.mkParamSort("T")
-    paramDtypeSpec = solver.mkDatatypeDecl("paramlist", sort)
-    paramCons = solver.mkDatatypeConstructorDecl("cons")
-    paramNil = solver.mkDatatypeConstructorDecl("nil")
-    paramCons.addSelector("head", sort)
-    paramDtypeSpec.addConstructor(paramCons)
-    paramDtypeSpec.addConstructor(paramNil)
-    paramDtypeSort = solver.mkDatatypeSort(paramDtypeSpec)
-    return paramDtypeSort
-
-
-def test_operators_comparison(solver):
-    solver.getIntegerSort() == Sort(solver)
-    solver.getIntegerSort() != Sort(solver)
-    solver.getIntegerSort() < Sort(solver)
-    solver.getIntegerSort() <= Sort(solver)
-    solver.getIntegerSort() > Sort(solver)
-    solver.getIntegerSort() >= Sort(solver)
-
-def test_is_null(solver):
-   x = Sort(solver)
-   assert x.isNull()
-   x = solver.getBooleanSort()
-   assert not x.isNull()
-
-def test_is_boolean(solver):
-    assert solver.getBooleanSort().isBoolean()
-    Sort(solver).isBoolean()
-
-
-def test_is_integer(solver):
-    assert solver.getIntegerSort().isInteger()
-    assert not solver.getRealSort().isInteger()
-    Sort(solver).isInteger()
-
-
-def test_is_real(solver):
-    assert solver.getRealSort().isReal()
-    assert not solver.getIntegerSort().isReal()
-    Sort(solver).isReal()
-
-
-def test_is_string(solver):
-    assert solver.getStringSort().isString()
-    Sort(solver).isString()
-
-
-def test_is_reg_exp(solver):
-    assert solver.getRegExpSort().isRegExp()
-    Sort(solver).isRegExp()
-
-
-def test_is_rounding_mode(solver):
-    assert solver.getRoundingModeSort().isRoundingMode()
-    Sort(solver).isRoundingMode()
-
-
-def test_is_bit_vector(solver):
-    assert solver.mkBitVectorSort(8).isBitVector()
-    Sort(solver).isBitVector()
-
-
-def test_is_floating_point(solver):
-    assert solver.mkFloatingPointSort(8, 24).isFloatingPoint()
-    Sort(solver).isFloatingPoint()
-
-
-def test_is_datatype(solver):
-    dt_sort = create_datatype_sort(solver)
-    assert dt_sort.isDatatype()
-    Sort(solver).isDatatype()
-
-
-def test_is_parametric_datatype(solver):
-    param_dt_sort = create_param_datatype_sort(solver)
-    assert param_dt_sort.isParametricDatatype()
-    Sort(solver).isParametricDatatype()
-
-
-def test_is_constructor(solver):
-    dt_sort = create_datatype_sort(solver)
-    dt = dt_sort.getDatatype()
-    cons_sort = dt[0].getConstructorTerm().getSort()
-    assert cons_sort.isConstructor()
-    Sort(solver).isConstructor()
-
-
-def test_is_selector(solver):
-    dt_sort = create_datatype_sort(solver)
-    dt = dt_sort.getDatatype()
-    dt0 = dt[0]
-    dt01 = dt0[1]
-    cons_sort = dt01.getSelectorTerm().getSort()
-    assert cons_sort.isSelector()
-    Sort(solver).isSelector()
-
-
-def test_is_tester(solver):
-    dt_sort = create_datatype_sort(solver)
-    dt = dt_sort.getDatatype()
-    cons_sort = dt[0].getTesterTerm().getSort()
-    assert cons_sort.isTester()
-    Sort(solver).isTester()
-
-def test_is_updater(solver):
-  dt_sort = create_datatype_sort(solver)
-  dt = dt_sort.getDatatype()
-  updater_sort = dt[0][0].getUpdaterTerm().getSort()
-  assert updater_sort.isUpdater()
-  Sort(solver).isUpdater()
-
-def test_is_function(solver):
-    fun_sort = solver.mkFunctionSort(solver.getRealSort(),
-                                     solver.getIntegerSort())
-    assert fun_sort.isFunction()
-    Sort(solver).isFunction()
-
-
-def test_is_predicate(solver):
-    pred_sort = solver.mkPredicateSort(solver.getRealSort())
-    assert pred_sort.isPredicate()
-    Sort(solver).isPredicate()
-
-
-def test_is_tuple(solver):
-    tup_sort = solver.mkTupleSort(solver.getRealSort())
-    assert tup_sort.isTuple()
-    Sort(solver).isTuple()
-
-
-def test_is_record(solver):
-    rec_sort = solver.mkRecordSort([("asdf", solver.getRealSort())])
-    assert rec_sort.isRecord()
-    Sort(solver).isRecord()
-
-
-def test_is_array(solver):
-    arr_sort = solver.mkArraySort(solver.getRealSort(),
-                                  solver.getIntegerSort())
-    assert arr_sort.isArray()
-    Sort(solver).isArray()
-
-
-def test_is_set(solver):
-    set_sort = solver.mkSetSort(solver.getRealSort())
-    assert set_sort.isSet()
-    Sort(solver).isSet()
-
-
-def test_is_bag(solver):
-    bag_sort = solver.mkBagSort(solver.getRealSort())
-    assert bag_sort.isBag()
-    Sort(solver).isBag()
-
-
-def test_is_sequence(solver):
-    seq_sort = solver.mkSequenceSort(solver.getRealSort())
-    assert seq_sort.isSequence()
-    Sort(solver).isSequence()
-
-
-def test_is_uninterpreted(solver):
-    un_sort = solver.mkUninterpretedSort("asdf")
-    assert un_sort.isUninterpretedSort()
-    Sort(solver).isUninterpretedSort()
-
-
-def test_is_sort_constructor(solver):
-    sc_sort = solver.mkSortConstructorSort("asdf", 1)
-    assert sc_sort.isSortConstructor()
-    Sort(solver).isSortConstructor()
-
-
-def test_is_first_class(solver):
-    fun_sort = solver.mkFunctionSort(solver.getRealSort(),
-                                     solver.getIntegerSort())
-    assert solver.getIntegerSort().isFirstClass()
-    assert fun_sort.isFirstClass()
-    reSort = solver.getRegExpSort()
-    assert not reSort.isFirstClass()
-    Sort(solver).isFirstClass()
-
-
-def test_is_function_like(solver):
-    fun_sort = solver.mkFunctionSort(solver.getRealSort(),
-                                     solver.getIntegerSort())
-    assert not solver.getIntegerSort().isFunctionLike()
-    assert fun_sort.isFunctionLike()
-
-    dt_sort = create_datatype_sort(solver)
-    dt = dt_sort.getDatatype()
-    cons_sort = dt[0][1].getSelectorTerm().getSort()
-    assert cons_sort.isFunctionLike()
-
-    Sort(solver).isFunctionLike()
-
-
-def test_is_subsort_of(solver):
-    assert solver.getIntegerSort().isSubsortOf(solver.getIntegerSort())
-    assert solver.getIntegerSort().isSubsortOf(solver.getRealSort())
-    assert not solver.getIntegerSort().isSubsortOf(solver.getBooleanSort())
-    Sort(solver).isSubsortOf(Sort(solver))
-
-
-def test_is_comparable_to(solver):
-    assert solver.getIntegerSort().isComparableTo(solver.getIntegerSort())
-    assert solver.getIntegerSort().isComparableTo(solver.getRealSort())
-    assert not solver.getIntegerSort().isComparableTo(solver.getBooleanSort())
-    Sort(solver).isComparableTo(Sort(solver))
-
-
-def test_get_datatype(solver):
-    dtypeSort = create_datatype_sort(solver)
-    dtypeSort.getDatatype()
-    # create bv sort, check should fail
-    bvSort = solver.mkBitVectorSort(32)
-    with pytest.raises(RuntimeError):
-        bvSort.getDatatype()
-
-
-def test_datatype_sorts(solver):
-    intSort = solver.getIntegerSort()
-    dtypeSort = create_datatype_sort(solver)
-    dt = dtypeSort.getDatatype()
-    assert not dtypeSort.isConstructor()
-    with pytest.raises(RuntimeError):
-        dtypeSort.getConstructorCodomainSort()
-    with pytest.raises(RuntimeError):
-        dtypeSort.getConstructorDomainSorts()
-    with pytest.raises(RuntimeError):
-        dtypeSort.getConstructorArity()
-
-    # get constructor
-    dcons = dt[0]
-    consTerm = dcons.getConstructorTerm()
-    consSort = consTerm.getSort()
-    assert consSort.isConstructor()
-    assert not consSort.isTester()
-    assert not consSort.isSelector()
-    assert consSort.getConstructorArity() == 2
-    consDomSorts = consSort.getConstructorDomainSorts()
-    assert consDomSorts[0] == intSort
-    assert consDomSorts[1] == dtypeSort
-    assert consSort.getConstructorCodomainSort() == dtypeSort
-
-    # get tester
-    isConsTerm = dcons.getTesterTerm()
-    assert isConsTerm.getSort().isTester()
-    booleanSort = solver.getBooleanSort()
-
-    assert isConsTerm.getSort().getTesterDomainSort() == dtypeSort
-    assert isConsTerm.getSort().getTesterCodomainSort() == booleanSort
-    with pytest.raises(RuntimeError):
-        booleanSort.getTesterDomainSort()
-    with pytest.raises(RuntimeError):
-        booleanSort.getTesterCodomainSort()
-
-    # get selector
-    dselTail = dcons[1]
-    tailTerm = dselTail.getSelectorTerm()
-    assert tailTerm.getSort().isSelector()
-    assert tailTerm.getSort().getSelectorDomainSort() == dtypeSort
-    assert tailTerm.getSort().getSelectorCodomainSort() == dtypeSort
-    with pytest.raises(RuntimeError):
-        booleanSort.getSelectorDomainSort()
-    with pytest.raises(RuntimeError):
-        booleanSort.getSelectorCodomainSort()
-
-
-def test_instantiate(solver):
-    # instantiate parametric datatype, check should not fail
-    paramDtypeSort = create_param_datatype_sort(solver)
-    paramDtypeSort.instantiate([solver.getIntegerSort()])
-    # instantiate non-parametric datatype sort, check should fail
-    dtypeSpec = solver.mkDatatypeDecl("list")
-    cons = solver.mkDatatypeConstructorDecl("cons")
-    cons.addSelector("head", solver.getIntegerSort())
-    dtypeSpec.addConstructor(cons)
-    nil = solver.mkDatatypeConstructorDecl("nil")
-    dtypeSpec.addConstructor(nil)
-    dtypeSort = solver.mkDatatypeSort(dtypeSpec)
-    with pytest.raises(RuntimeError):
-        dtypeSort.instantiate([solver.getIntegerSort()])
-
-
-def test_get_function_arity(solver):
-    funSort = solver.mkFunctionSort(solver.mkUninterpretedSort("u"),
-                                    solver.getIntegerSort())
-    funSort.getFunctionArity()
-    bvSort = solver.mkBitVectorSort(32)
-    with pytest.raises(RuntimeError):
-        bvSort.getFunctionArity()
-
-
-def test_get_function_domain_sorts(solver):
-    funSort = solver.mkFunctionSort(solver.mkUninterpretedSort("u"),
-                                    solver.getIntegerSort())
-    funSort.getFunctionDomainSorts()
-    bvSort = solver.mkBitVectorSort(32)
-    with pytest.raises(RuntimeError):
-        bvSort.getFunctionDomainSorts()
-
-
-def test_get_function_codomain_sort(solver):
-    funSort = solver.mkFunctionSort(solver.mkUninterpretedSort("u"),
-                                    solver.getIntegerSort())
-    funSort.getFunctionCodomainSort()
-    bvSort = solver.mkBitVectorSort(32)
-    with pytest.raises(RuntimeError):
-        bvSort.getFunctionCodomainSort()
-
-
-def test_get_array_index_sort(solver):
-    elementSort = solver.mkBitVectorSort(32)
-    indexSort = solver.mkBitVectorSort(32)
-    arraySort = solver.mkArraySort(indexSort, elementSort)
-    arraySort.getArrayIndexSort()
-    with pytest.raises(RuntimeError):
-        indexSort.getArrayIndexSort()
-
-
-def test_get_array_element_sort(solver):
-    elementSort = solver.mkBitVectorSort(32)
-    indexSort = solver.mkBitVectorSort(32)
-    arraySort = solver.mkArraySort(indexSort, elementSort)
-    arraySort.getArrayElementSort()
-    with pytest.raises(RuntimeError):
-        indexSort.getArrayElementSort()
-
-
-def test_get_set_element_sort(solver):
-    setSort = solver.mkSetSort(solver.getIntegerSort())
-    setSort.getSetElementSort()
-    elementSort = setSort.getSetElementSort()
-    assert elementSort == solver.getIntegerSort()
-    bvSort = solver.mkBitVectorSort(32)
-    with pytest.raises(RuntimeError):
-        bvSort.getSetElementSort()
-
-
-def test_get_bag_element_sort(solver):
-    bagSort = solver.mkBagSort(solver.getIntegerSort())
-    bagSort.getBagElementSort()
-    elementSort = bagSort.getBagElementSort()
-    assert elementSort == solver.getIntegerSort()
-    bvSort = solver.mkBitVectorSort(32)
-    with pytest.raises(RuntimeError):
-        bvSort.getBagElementSort()
-
-
-def test_get_sequence_element_sort(solver):
-    seqSort = solver.mkSequenceSort(solver.getIntegerSort())
-    assert seqSort.isSequence()
-    seqSort.getSequenceElementSort()
-    bvSort = solver.mkBitVectorSort(32)
-    assert not bvSort.isSequence()
-    with pytest.raises(RuntimeError):
-        bvSort.getSequenceElementSort()
-
-
-def test_get_uninterpreted_sort_name(solver):
-    uSort = solver.mkUninterpretedSort("u")
-    uSort.getUninterpretedSortName()
-    bvSort = solver.mkBitVectorSort(32)
-    with pytest.raises(RuntimeError):
-        bvSort.getUninterpretedSortName()
-
-
-def test_is_uninterpreted_sort_parameterized(solver):
-    uSort = solver.mkUninterpretedSort("u")
-    assert not uSort.isUninterpretedSortParameterized()
-    sSort = solver.mkSortConstructorSort("s", 1)
-    siSort = sSort.instantiate([uSort])
-    assert siSort.isUninterpretedSortParameterized()
-    bvSort = solver.mkBitVectorSort(32)
-    with pytest.raises(RuntimeError):
-        bvSort.isUninterpretedSortParameterized()
-
-
-def test_get_uninterpreted_sort_paramsorts(solver):
-    uSort = solver.mkUninterpretedSort("u")
-    uSort.getUninterpretedSortParamSorts()
-    sSort = solver.mkSortConstructorSort("s", 2)
-    siSort = sSort.instantiate([uSort, uSort])
-    assert len(siSort.getUninterpretedSortParamSorts()) == 2
-    bvSort = solver.mkBitVectorSort(32)
-    with pytest.raises(RuntimeError):
-        bvSort.getUninterpretedSortParamSorts()
-
-
-def test_get_uninterpreted_sort_constructor_name(solver):
-    sSort = solver.mkSortConstructorSort("s", 2)
-    sSort.getSortConstructorName()
-    bvSort = solver.mkBitVectorSort(32)
-    with pytest.raises(RuntimeError):
-        bvSort.getSortConstructorName()
-
-
-def test_get_uninterpreted_sort_constructor_arity(solver):
-    sSort = solver.mkSortConstructorSort("s", 2)
-    sSort.getSortConstructorArity()
-    bvSort = solver.mkBitVectorSort(32)
-    with pytest.raises(RuntimeError):
-        bvSort.getSortConstructorArity()
-
-
-def test_get_bv_size(solver):
-    bvSort = solver.mkBitVectorSort(32)
-    bvSort.getBitVectorSize()
-    setSort = solver.mkSetSort(solver.getIntegerSort())
-    with pytest.raises(RuntimeError):
-        setSort.getBitVectorSize()
-
-
-def test_get_fp_exponent_size(solver):
-    fpSort = solver.mkFloatingPointSort(4, 8)
-    fpSort.getFloatingPointExponentSize()
-    setSort = solver.mkSetSort(solver.getIntegerSort())
-    with pytest.raises(RuntimeError):
-        setSort.getFloatingPointExponentSize()
-
-
-def test_get_fp_significand_size(solver):
-    fpSort = solver.mkFloatingPointSort(4, 8)
-    fpSort.getFloatingPointSignificandSize()
-    setSort = solver.mkSetSort(solver.getIntegerSort())
-    with pytest.raises(RuntimeError):
-        setSort.getFloatingPointSignificandSize()
-
-
-def test_get_datatype_paramsorts(solver):
-    # create parametric datatype, check should not fail
-    sort = solver.mkParamSort("T")
-    paramDtypeSpec = solver.mkDatatypeDecl("paramlist", sort)
-    paramCons = solver.mkDatatypeConstructorDecl("cons")
-    paramNil = solver.mkDatatypeConstructorDecl("nil")
-    paramCons.addSelector("head", sort)
-    paramDtypeSpec.addConstructor(paramCons)
-    paramDtypeSpec.addConstructor(paramNil)
-    paramDtypeSort = solver.mkDatatypeSort(paramDtypeSpec)
-    paramDtypeSort.getDatatypeParamSorts()
-    # create non-parametric datatype sort, check should fail
-    dtypeSpec = solver.mkDatatypeDecl("list")
-    cons = solver.mkDatatypeConstructorDecl("cons")
-    cons.addSelector("head", solver.getIntegerSort())
-    dtypeSpec.addConstructor(cons)
-    nil = solver.mkDatatypeConstructorDecl("nil")
-    dtypeSpec.addConstructor(nil)
-    dtypeSort = solver.mkDatatypeSort(dtypeSpec)
-    with pytest.raises(RuntimeError):
-        dtypeSort.getDatatypeParamSorts()
-
-
-def test_get_datatype_arity(solver):
-    # create datatype sort, check should not fail
-    dtypeSpec = solver.mkDatatypeDecl("list")
-    cons = solver.mkDatatypeConstructorDecl("cons")
-    cons.addSelector("head", solver.getIntegerSort())
-    dtypeSpec.addConstructor(cons)
-    nil = solver.mkDatatypeConstructorDecl("nil")
-    dtypeSpec.addConstructor(nil)
-    dtypeSort = solver.mkDatatypeSort(dtypeSpec)
-    dtypeSort.getDatatypeArity()
-    # create bv sort, check should fail
-    bvSort = solver.mkBitVectorSort(32)
-    with pytest.raises(RuntimeError):
-        bvSort.getDatatypeArity()
-
-
-def test_get_tuple_length(solver):
-    tupleSort = solver.mkTupleSort(
-        [solver.getIntegerSort(),
-         solver.getIntegerSort()])
-    tupleSort.getTupleLength()
-    bvSort = solver.mkBitVectorSort(32)
-    with pytest.raises(RuntimeError):
-        bvSort.getTupleLength()
-
-
-def test_get_tuple_sorts(solver):
-    tupleSort = solver.mkTupleSort(
-        [solver.getIntegerSort(),
-         solver.getIntegerSort()])
-    tupleSort.getTupleSorts()
-    bvSort = solver.mkBitVectorSort(32)
-    with pytest.raises(RuntimeError):
-        bvSort.getTupleSorts()
-
-
-def test_sort_compare(solver):
-    boolSort = solver.getBooleanSort()
-    intSort = solver.getIntegerSort()
-    bvSort = solver.mkBitVectorSort(32)
-    bvSort2 = solver.mkBitVectorSort(32)
-    assert bvSort >= bvSort2
-    assert bvSort <= bvSort2
-    assert (intSort > boolSort) != (intSort < boolSort)
-    assert (intSort > bvSort or intSort == bvSort) == (intSort >= bvSort)
-
-
-def test_sort_subtyping(solver):
-    intSort = solver.getIntegerSort()
-    realSort = solver.getRealSort()
-    assert intSort.isSubsortOf(realSort)
-    assert not realSort.isSubsortOf(intSort)
-    assert intSort.isComparableTo(realSort)
-    assert realSort.isComparableTo(intSort)
-
-    arraySortII = solver.mkArraySort(intSort, intSort)
-    arraySortIR = solver.mkArraySort(intSort, realSort)
-    assert not arraySortII.isComparableTo(intSort)
-    # we do not support subtyping for arrays
-    assert not arraySortII.isComparableTo(arraySortIR)
-
-    setSortI = solver.mkSetSort(intSort)
-    setSortR = solver.mkSetSort(realSort)
-    # we don't support subtyping for sets
-    assert not setSortI.isComparableTo(setSortR)
-    assert not setSortI.isSubsortOf(setSortR)
-    assert not setSortR.isComparableTo(setSortI)
-    assert not setSortR.isSubsortOf(setSortI)
-
-
-def test_sort_scoped_tostring(solver):
-    name = "uninterp-sort"
-    bvsort8 = solver.mkBitVectorSort(8)
-    uninterp_sort = solver.mkUninterpretedSort(name)
-    assert str(bvsort8) == "(_ BitVec 8)"
-    assert str(uninterp_sort) == name
-    solver2 = pycvc5.Solver()
-    assert str(bvsort8) == "(_ BitVec 8)"
-    assert str(uninterp_sort) == name
diff --git a/test/python/unit/api/test_term.py b/test/python/unit/api/test_term.py
deleted file mode 100644 (file)
index 34a79d5..0000000
+++ /dev/null
@@ -1,1267 +0,0 @@
-###############################################################################
-# Top contributors (to current version):
-#   Yoni Zohar, Makai Mann, Andres Noetzli
-#
-# This file is part of the cvc5 project.
-#
-# Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
-# in the top-level source directory and their institutional affiliations.
-# All rights reserved.  See the file COPYING in the top-level source
-# directory for licensing information.
-# #############################################################################
-##
-
-import pytest
-import pycvc5
-from pycvc5 import kinds
-from pycvc5 import Sort, Term
-from fractions import Fraction
-
-
-@pytest.fixture
-def solver():
-    return pycvc5.Solver()
-
-
-def test_eq(solver):
-    uSort = solver.mkUninterpretedSort("u")
-    x = solver.mkVar(uSort, "x")
-    y = solver.mkVar(uSort, "y")
-    z = Term(solver)
-
-    assert x == x
-    assert not x != x
-    assert not x == y
-    assert x != y
-    assert not (x == z)
-    assert x != z
-
-
-def test_get_id(solver):
-    n = Term(solver)
-    with pytest.raises(RuntimeError):
-        n.getId()
-    x = solver.mkVar(solver.getIntegerSort(), "x")
-    x.getId()
-    y = x
-    assert x.getId() == y.getId()
-
-    z = solver.mkVar(solver.getIntegerSort(), "z")
-    assert x.getId() != z.getId()
-
-
-def test_get_kind(solver):
-    uSort = solver.mkUninterpretedSort("u")
-    intSort = solver.getIntegerSort()
-    boolSort = solver.getBooleanSort()
-    funSort1 = solver.mkFunctionSort(uSort, intSort)
-    funSort2 = solver.mkFunctionSort(intSort, boolSort)
-
-    n = Term(solver)
-    with pytest.raises(RuntimeError):
-        n.getKind()
-    x = solver.mkVar(uSort, "x")
-    x.getKind()
-    y = solver.mkVar(uSort, "y")
-    y.getKind()
-
-    f = solver.mkVar(funSort1, "f")
-    f.getKind()
-    p = solver.mkVar(funSort2, "p")
-    p.getKind()
-
-    zero = solver.mkInteger(0)
-    zero.getKind()
-
-    f_x = solver.mkTerm(kinds.ApplyUf, f, x)
-    f_x.getKind()
-    f_y = solver.mkTerm(kinds.ApplyUf, f, y)
-    f_y.getKind()
-    sum = solver.mkTerm(kinds.Plus, f_x, f_y)
-    sum.getKind()
-    p_0 = solver.mkTerm(kinds.ApplyUf, p, zero)
-    p_0.getKind()
-    p_f_y = solver.mkTerm(kinds.ApplyUf, p, f_y)
-    p_f_y.getKind()
-
-    # Sequence kinds do not exist internally, test that the API properly
-    # converts them back.
-    seqSort = solver.mkSequenceSort(intSort)
-    s = solver.mkConst(seqSort, "s")
-    ss = solver.mkTerm(kinds.SeqConcat, s, s)
-    assert ss.getKind() == kinds.SeqConcat
-
-
-def test_get_sort(solver):
-    bvSort = solver.mkBitVectorSort(8)
-    intSort = solver.getIntegerSort()
-    boolSort = solver.getBooleanSort()
-    funSort1 = solver.mkFunctionSort(bvSort, intSort)
-    funSort2 = solver.mkFunctionSort(intSort, boolSort)
-
-    n = Term(solver)
-    with pytest.raises(RuntimeError):
-        n.getSort()
-    x = solver.mkVar(bvSort, "x")
-    x.getSort()
-    assert x.getSort() == bvSort
-    y = solver.mkVar(bvSort, "y")
-    y.getSort()
-    assert y.getSort() == bvSort
-
-    f = solver.mkVar(funSort1, "f")
-    f.getSort()
-    assert f.getSort() == funSort1
-    p = solver.mkVar(funSort2, "p")
-    p.getSort()
-    assert p.getSort() == funSort2
-
-    zero = solver.mkInteger(0)
-    zero.getSort()
-    assert zero.getSort() == intSort
-
-    f_x = solver.mkTerm(kinds.ApplyUf, f, x)
-    f_x.getSort()
-    assert f_x.getSort() == intSort
-    f_y = solver.mkTerm(kinds.ApplyUf, f, y)
-    f_y.getSort()
-    assert f_y.getSort() == intSort
-    sum = solver.mkTerm(kinds.Plus, f_x, f_y)
-    sum.getSort()
-    assert sum.getSort() == intSort
-    p_0 = solver.mkTerm(kinds.ApplyUf, p, zero)
-    p_0.getSort()
-    assert p_0.getSort() == boolSort
-    p_f_y = solver.mkTerm(kinds.ApplyUf, p, f_y)
-    p_f_y.getSort()
-    assert p_f_y.getSort() == boolSort
-
-
-def test_get_op(solver):
-    intsort = solver.getIntegerSort()
-    bvsort = solver.mkBitVectorSort(8)
-    arrsort = solver.mkArraySort(bvsort, intsort)
-    funsort = solver.mkFunctionSort(intsort, bvsort)
-
-    x = solver.mkConst(intsort, "x")
-    a = solver.mkConst(arrsort, "a")
-    b = solver.mkConst(bvsort, "b")
-
-    assert not x.hasOp()
-    with pytest.raises(RuntimeError):
-        x.getOp()
-
-    ab = solver.mkTerm(kinds.Select, a, b)
-    ext = solver.mkOp(kinds.BVExtract, 4, 0)
-    extb = solver.mkTerm(ext, b)
-
-    assert ab.hasOp()
-    assert not ab.getOp().isIndexed()
-    # can compare directly to a Kind (will invoke constructor)
-    assert extb.hasOp()
-    assert extb.getOp().isIndexed()
-    assert extb.getOp() == ext
-
-    f = solver.mkConst(funsort, "f")
-    fx = solver.mkTerm(kinds.ApplyUf, f, x)
-
-    assert not f.hasOp()
-    with pytest.raises(RuntimeError):
-        f.getOp()
-    assert fx.hasOp()
-    children = [c for c in fx]
-    # testing rebuild from op and children
-    assert fx == solver.mkTerm(fx.getOp(), children)
-
-    # Test Datatypes Ops
-    sort = solver.mkParamSort("T")
-    listDecl = solver.mkDatatypeDecl("paramlist", sort)
-    cons = solver.mkDatatypeConstructorDecl("cons")
-    nil = solver.mkDatatypeConstructorDecl("nil")
-    cons.addSelector("head", sort)
-    cons.addSelectorSelf("tail")
-    listDecl.addConstructor(cons)
-    listDecl.addConstructor(nil)
-    listSort = solver.mkDatatypeSort(listDecl)
-    intListSort = listSort.instantiate([solver.getIntegerSort()])
-    c = solver.mkConst(intListSort, "c")
-    list1 = listSort.getDatatype()
-    # list datatype constructor and selector operator terms
-    consOpTerm = list1.getConstructorTerm("cons")
-    nilOpTerm = list1.getConstructorTerm("nil")
-    headOpTerm = list1["cons"].getSelectorTerm("head")
-    tailOpTerm = list1["cons"].getSelectorTerm("tail")
-
-    nilTerm = solver.mkTerm(kinds.ApplyConstructor, nilOpTerm)
-    consTerm = solver.mkTerm(kinds.ApplyConstructor, consOpTerm,
-                             solver.mkInteger(0), nilTerm)
-    headTerm = solver.mkTerm(kinds.ApplySelector, headOpTerm, consTerm)
-    tailTerm = solver.mkTerm(kinds.ApplySelector, tailOpTerm, consTerm)
-
-    assert nilTerm.hasOp()
-    assert consTerm.hasOp()
-    assert headTerm.hasOp()
-    assert tailTerm.hasOp()
-
-    # Test rebuilding
-    children = [c for c in headTerm]
-    assert headTerm == solver.mkTerm(headTerm.getOp(), children)
-
-
-def test_is_null(solver):
-    x = Term(solver)
-    assert x.isNull()
-    x = solver.mkVar(solver.mkBitVectorSort(4), "x")
-    assert not x.isNull()
-
-
-def test_not_term(solver):
-    bvSort = solver.mkBitVectorSort(8)
-    intSort = solver.getIntegerSort()
-    boolSort = solver.getBooleanSort()
-    funSort1 = solver.mkFunctionSort(bvSort, intSort)
-    funSort2 = solver.mkFunctionSort(intSort, boolSort)
-
-    with pytest.raises(RuntimeError):
-        Term(solver).notTerm()
-    b = solver.mkTrue()
-    b.notTerm()
-    x = solver.mkVar(solver.mkBitVectorSort(8), "x")
-    with pytest.raises(RuntimeError):
-        x.notTerm()
-    f = solver.mkVar(funSort1, "f")
-    with pytest.raises(RuntimeError):
-        f.notTerm()
-    p = solver.mkVar(funSort2, "p")
-    with pytest.raises(RuntimeError):
-        p.notTerm()
-    zero = solver.mkInteger(0)
-    with pytest.raises(RuntimeError):
-        zero.notTerm()
-    f_x = solver.mkTerm(kinds.ApplyUf, f, x)
-    with pytest.raises(RuntimeError):
-        f_x.notTerm()
-    sum = solver.mkTerm(kinds.Plus, f_x, f_x)
-    with pytest.raises(RuntimeError):
-        sum.notTerm()
-    p_0 = solver.mkTerm(kinds.ApplyUf, p, zero)
-    p_0.notTerm()
-    p_f_x = solver.mkTerm(kinds.ApplyUf, p, f_x)
-    p_f_x.notTerm()
-
-
-def test_and_term(solver):
-    bvSort = solver.mkBitVectorSort(8)
-    intSort = solver.getIntegerSort()
-    boolSort = solver.getBooleanSort()
-    funSort1 = solver.mkFunctionSort(bvSort, intSort)
-    funSort2 = solver.mkFunctionSort(intSort, boolSort)
-
-    b = solver.mkTrue()
-    with pytest.raises(RuntimeError):
-        Term(solver).andTerm(b)
-    with pytest.raises(RuntimeError):
-        b.andTerm(Term(solver))
-    b.andTerm(b)
-    x = solver.mkVar(solver.mkBitVectorSort(8), "x")
-    with pytest.raises(RuntimeError):
-        x.andTerm(b)
-    with pytest.raises(RuntimeError):
-        x.andTerm(x)
-    f = solver.mkVar(funSort1, "f")
-    with pytest.raises(RuntimeError):
-        f.andTerm(b)
-    with pytest.raises(RuntimeError):
-        f.andTerm(x)
-    with pytest.raises(RuntimeError):
-        f.andTerm(f)
-    p = solver.mkVar(funSort2, "p")
-    with pytest.raises(RuntimeError):
-        p.andTerm(b)
-    with pytest.raises(RuntimeError):
-        p.andTerm(x)
-    with pytest.raises(RuntimeError):
-        p.andTerm(f)
-    with pytest.raises(RuntimeError):
-        p.andTerm(p)
-    zero = solver.mkInteger(0)
-    with pytest.raises(RuntimeError):
-        zero.andTerm(b)
-    with pytest.raises(RuntimeError):
-        zero.andTerm(x)
-    with pytest.raises(RuntimeError):
-        zero.andTerm(f)
-    with pytest.raises(RuntimeError):
-        zero.andTerm(p)
-    with pytest.raises(RuntimeError):
-        zero.andTerm(zero)
-    f_x = solver.mkTerm(kinds.ApplyUf, f, x)
-    with pytest.raises(RuntimeError):
-        f_x.andTerm(b)
-    with pytest.raises(RuntimeError):
-        f_x.andTerm(x)
-    with pytest.raises(RuntimeError):
-        f_x.andTerm(f)
-    with pytest.raises(RuntimeError):
-        f_x.andTerm(p)
-    with pytest.raises(RuntimeError):
-        f_x.andTerm(zero)
-    with pytest.raises(RuntimeError):
-        f_x.andTerm(f_x)
-    sum = solver.mkTerm(kinds.Plus, f_x, f_x)
-    with pytest.raises(RuntimeError):
-        sum.andTerm(b)
-    with pytest.raises(RuntimeError):
-        sum.andTerm(x)
-    with pytest.raises(RuntimeError):
-        sum.andTerm(f)
-    with pytest.raises(RuntimeError):
-        sum.andTerm(p)
-    with pytest.raises(RuntimeError):
-        sum.andTerm(zero)
-    with pytest.raises(RuntimeError):
-        sum.andTerm(f_x)
-    with pytest.raises(RuntimeError):
-        sum.andTerm(sum)
-    p_0 = solver.mkTerm(kinds.ApplyUf, p, zero)
-    p_0.andTerm(b)
-    with pytest.raises(RuntimeError):
-        p_0.andTerm(x)
-    with pytest.raises(RuntimeError):
-        p_0.andTerm(f)
-    with pytest.raises(RuntimeError):
-        p_0.andTerm(p)
-    with pytest.raises(RuntimeError):
-        p_0.andTerm(zero)
-    with pytest.raises(RuntimeError):
-        p_0.andTerm(f_x)
-    with pytest.raises(RuntimeError):
-        p_0.andTerm(sum)
-    p_0.andTerm(p_0)
-    p_f_x = solver.mkTerm(kinds.ApplyUf, p, f_x)
-    p_f_x.andTerm(b)
-    with pytest.raises(RuntimeError):
-        p_f_x.andTerm(x)
-    with pytest.raises(RuntimeError):
-        p_f_x.andTerm(f)
-    with pytest.raises(RuntimeError):
-        p_f_x.andTerm(p)
-    with pytest.raises(RuntimeError):
-        p_f_x.andTerm(zero)
-    with pytest.raises(RuntimeError):
-        p_f_x.andTerm(f_x)
-    with pytest.raises(RuntimeError):
-        p_f_x.andTerm(sum)
-    p_f_x.andTerm(p_0)
-    p_f_x.andTerm(p_f_x)
-
-
-def test_or_term(solver):
-    bvSort = solver.mkBitVectorSort(8)
-    intSort = solver.getIntegerSort()
-    boolSort = solver.getBooleanSort()
-    funSort1 = solver.mkFunctionSort(bvSort, intSort)
-    funSort2 = solver.mkFunctionSort(intSort, boolSort)
-
-    b = solver.mkTrue()
-    with pytest.raises(RuntimeError):
-        Term(solver).orTerm(b)
-    with pytest.raises(RuntimeError):
-        b.orTerm(Term(solver))
-    b.orTerm(b)
-    x = solver.mkVar(solver.mkBitVectorSort(8), "x")
-    with pytest.raises(RuntimeError):
-        x.orTerm(b)
-    with pytest.raises(RuntimeError):
-        x.orTerm(x)
-    f = solver.mkVar(funSort1, "f")
-    with pytest.raises(RuntimeError):
-        f.orTerm(b)
-    with pytest.raises(RuntimeError):
-        f.orTerm(x)
-    with pytest.raises(RuntimeError):
-        f.orTerm(f)
-    p = solver.mkVar(funSort2, "p")
-    with pytest.raises(RuntimeError):
-        p.orTerm(b)
-    with pytest.raises(RuntimeError):
-        p.orTerm(x)
-    with pytest.raises(RuntimeError):
-        p.orTerm(f)
-    with pytest.raises(RuntimeError):
-        p.orTerm(p)
-    zero = solver.mkInteger(0)
-    with pytest.raises(RuntimeError):
-        zero.orTerm(b)
-    with pytest.raises(RuntimeError):
-        zero.orTerm(x)
-    with pytest.raises(RuntimeError):
-        zero.orTerm(f)
-    with pytest.raises(RuntimeError):
-        zero.orTerm(p)
-    with pytest.raises(RuntimeError):
-        zero.orTerm(zero)
-    f_x = solver.mkTerm(kinds.ApplyUf, f, x)
-    with pytest.raises(RuntimeError):
-        f_x.orTerm(b)
-    with pytest.raises(RuntimeError):
-        f_x.orTerm(x)
-    with pytest.raises(RuntimeError):
-        f_x.orTerm(f)
-    with pytest.raises(RuntimeError):
-        f_x.orTerm(p)
-    with pytest.raises(RuntimeError):
-        f_x.orTerm(zero)
-    with pytest.raises(RuntimeError):
-        f_x.orTerm(f_x)
-    sum = solver.mkTerm(kinds.Plus, f_x, f_x)
-    with pytest.raises(RuntimeError):
-        sum.orTerm(b)
-    with pytest.raises(RuntimeError):
-        sum.orTerm(x)
-    with pytest.raises(RuntimeError):
-        sum.orTerm(f)
-    with pytest.raises(RuntimeError):
-        sum.orTerm(p)
-    with pytest.raises(RuntimeError):
-        sum.orTerm(zero)
-    with pytest.raises(RuntimeError):
-        sum.orTerm(f_x)
-    with pytest.raises(RuntimeError):
-        sum.orTerm(sum)
-    p_0 = solver.mkTerm(kinds.ApplyUf, p, zero)
-    p_0.orTerm(b)
-    with pytest.raises(RuntimeError):
-        p_0.orTerm(x)
-    with pytest.raises(RuntimeError):
-        p_0.orTerm(f)
-    with pytest.raises(RuntimeError):
-        p_0.orTerm(p)
-    with pytest.raises(RuntimeError):
-        p_0.orTerm(zero)
-    with pytest.raises(RuntimeError):
-        p_0.orTerm(f_x)
-    with pytest.raises(RuntimeError):
-        p_0.orTerm(sum)
-    p_0.orTerm(p_0)
-    p_f_x = solver.mkTerm(kinds.ApplyUf, p, f_x)
-    p_f_x.orTerm(b)
-    with pytest.raises(RuntimeError):
-        p_f_x.orTerm(x)
-    with pytest.raises(RuntimeError):
-        p_f_x.orTerm(f)
-    with pytest.raises(RuntimeError):
-        p_f_x.orTerm(p)
-    with pytest.raises(RuntimeError):
-        p_f_x.orTerm(zero)
-    with pytest.raises(RuntimeError):
-        p_f_x.orTerm(f_x)
-    with pytest.raises(RuntimeError):
-        p_f_x.orTerm(sum)
-    p_f_x.orTerm(p_0)
-    p_f_x.orTerm(p_f_x)
-
-
-def test_xor_term(solver):
-    bvSort = solver.mkBitVectorSort(8)
-    intSort = solver.getIntegerSort()
-    boolSort = solver.getBooleanSort()
-    funSort1 = solver.mkFunctionSort(bvSort, intSort)
-    funSort2 = solver.mkFunctionSort(intSort, boolSort)
-
-    b = solver.mkTrue()
-    with pytest.raises(RuntimeError):
-        Term(solver).xorTerm(b)
-    with pytest.raises(RuntimeError):
-        b.xorTerm(Term(solver))
-    b.xorTerm(b)
-    x = solver.mkVar(solver.mkBitVectorSort(8), "x")
-    with pytest.raises(RuntimeError):
-        x.xorTerm(b)
-    with pytest.raises(RuntimeError):
-        x.xorTerm(x)
-    f = solver.mkVar(funSort1, "f")
-    with pytest.raises(RuntimeError):
-        f.xorTerm(b)
-    with pytest.raises(RuntimeError):
-        f.xorTerm(x)
-    with pytest.raises(RuntimeError):
-        f.xorTerm(f)
-    p = solver.mkVar(funSort2, "p")
-    with pytest.raises(RuntimeError):
-        p.xorTerm(b)
-    with pytest.raises(RuntimeError):
-        p.xorTerm(x)
-    with pytest.raises(RuntimeError):
-        p.xorTerm(f)
-    with pytest.raises(RuntimeError):
-        p.xorTerm(p)
-    zero = solver.mkInteger(0)
-    with pytest.raises(RuntimeError):
-        zero.xorTerm(b)
-    with pytest.raises(RuntimeError):
-        zero.xorTerm(x)
-    with pytest.raises(RuntimeError):
-        zero.xorTerm(f)
-    with pytest.raises(RuntimeError):
-        zero.xorTerm(p)
-    with pytest.raises(RuntimeError):
-        zero.xorTerm(zero)
-    f_x = solver.mkTerm(kinds.ApplyUf, f, x)
-    with pytest.raises(RuntimeError):
-        f_x.xorTerm(b)
-    with pytest.raises(RuntimeError):
-        f_x.xorTerm(x)
-    with pytest.raises(RuntimeError):
-        f_x.xorTerm(f)
-    with pytest.raises(RuntimeError):
-        f_x.xorTerm(p)
-    with pytest.raises(RuntimeError):
-        f_x.xorTerm(zero)
-    with pytest.raises(RuntimeError):
-        f_x.xorTerm(f_x)
-    sum = solver.mkTerm(kinds.Plus, f_x, f_x)
-    with pytest.raises(RuntimeError):
-        sum.xorTerm(b)
-    with pytest.raises(RuntimeError):
-        sum.xorTerm(x)
-    with pytest.raises(RuntimeError):
-        sum.xorTerm(f)
-    with pytest.raises(RuntimeError):
-        sum.xorTerm(p)
-    with pytest.raises(RuntimeError):
-        sum.xorTerm(zero)
-    with pytest.raises(RuntimeError):
-        sum.xorTerm(f_x)
-    with pytest.raises(RuntimeError):
-        sum.xorTerm(sum)
-    p_0 = solver.mkTerm(kinds.ApplyUf, p, zero)
-    p_0.xorTerm(b)
-    with pytest.raises(RuntimeError):
-        p_0.xorTerm(x)
-    with pytest.raises(RuntimeError):
-        p_0.xorTerm(f)
-    with pytest.raises(RuntimeError):
-        p_0.xorTerm(p)
-    with pytest.raises(RuntimeError):
-        p_0.xorTerm(zero)
-    with pytest.raises(RuntimeError):
-        p_0.xorTerm(f_x)
-    with pytest.raises(RuntimeError):
-        p_0.xorTerm(sum)
-    p_0.xorTerm(p_0)
-    p_f_x = solver.mkTerm(kinds.ApplyUf, p, f_x)
-    p_f_x.xorTerm(b)
-    with pytest.raises(RuntimeError):
-        p_f_x.xorTerm(x)
-    with pytest.raises(RuntimeError):
-        p_f_x.xorTerm(f)
-    with pytest.raises(RuntimeError):
-        p_f_x.xorTerm(p)
-    with pytest.raises(RuntimeError):
-        p_f_x.xorTerm(zero)
-    with pytest.raises(RuntimeError):
-        p_f_x.xorTerm(f_x)
-    with pytest.raises(RuntimeError):
-        p_f_x.xorTerm(sum)
-    p_f_x.xorTerm(p_0)
-    p_f_x.xorTerm(p_f_x)
-
-
-def test_eq_term(solver):
-    bvSort = solver.mkBitVectorSort(8)
-    intSort = solver.getIntegerSort()
-    boolSort = solver.getBooleanSort()
-    funSort1 = solver.mkFunctionSort(bvSort, intSort)
-    funSort2 = solver.mkFunctionSort(intSort, boolSort)
-
-    b = solver.mkTrue()
-    with pytest.raises(RuntimeError):
-        Term(solver).eqTerm(b)
-    with pytest.raises(RuntimeError):
-        b.eqTerm(Term(solver))
-    b.eqTerm(b)
-    x = solver.mkVar(solver.mkBitVectorSort(8), "x")
-    with pytest.raises(RuntimeError):
-        x.eqTerm(b)
-    x.eqTerm(x)
-    f = solver.mkVar(funSort1, "f")
-    with pytest.raises(RuntimeError):
-        f.eqTerm(b)
-    with pytest.raises(RuntimeError):
-        f.eqTerm(x)
-    f.eqTerm(f)
-    p = solver.mkVar(funSort2, "p")
-    with pytest.raises(RuntimeError):
-        p.eqTerm(b)
-    with pytest.raises(RuntimeError):
-        p.eqTerm(x)
-    with pytest.raises(RuntimeError):
-        p.eqTerm(f)
-    p.eqTerm(p)
-    zero = solver.mkInteger(0)
-    with pytest.raises(RuntimeError):
-        zero.eqTerm(b)
-    with pytest.raises(RuntimeError):
-        zero.eqTerm(x)
-    with pytest.raises(RuntimeError):
-        zero.eqTerm(f)
-    with pytest.raises(RuntimeError):
-        zero.eqTerm(p)
-    zero.eqTerm(zero)
-    f_x = solver.mkTerm(kinds.ApplyUf, f, x)
-    with pytest.raises(RuntimeError):
-        f_x.eqTerm(b)
-    with pytest.raises(RuntimeError):
-        f_x.eqTerm(x)
-    with pytest.raises(RuntimeError):
-        f_x.eqTerm(f)
-    with pytest.raises(RuntimeError):
-        f_x.eqTerm(p)
-    f_x.eqTerm(zero)
-    f_x.eqTerm(f_x)
-    sum = solver.mkTerm(kinds.Plus, f_x, f_x)
-    with pytest.raises(RuntimeError):
-        sum.eqTerm(b)
-    with pytest.raises(RuntimeError):
-        sum.eqTerm(x)
-    with pytest.raises(RuntimeError):
-        sum.eqTerm(f)
-    with pytest.raises(RuntimeError):
-        sum.eqTerm(p)
-    sum.eqTerm(zero)
-    sum.eqTerm(f_x)
-    sum.eqTerm(sum)
-    p_0 = solver.mkTerm(kinds.ApplyUf, p, zero)
-    p_0.eqTerm(b)
-    with pytest.raises(RuntimeError):
-        p_0.eqTerm(x)
-    with pytest.raises(RuntimeError):
-        p_0.eqTerm(f)
-    with pytest.raises(RuntimeError):
-        p_0.eqTerm(p)
-    with pytest.raises(RuntimeError):
-        p_0.eqTerm(zero)
-    with pytest.raises(RuntimeError):
-        p_0.eqTerm(f_x)
-    with pytest.raises(RuntimeError):
-        p_0.eqTerm(sum)
-    p_0.eqTerm(p_0)
-    p_f_x = solver.mkTerm(kinds.ApplyUf, p, f_x)
-    p_f_x.eqTerm(b)
-    with pytest.raises(RuntimeError):
-        p_f_x.eqTerm(x)
-    with pytest.raises(RuntimeError):
-        p_f_x.eqTerm(f)
-    with pytest.raises(RuntimeError):
-        p_f_x.eqTerm(p)
-    with pytest.raises(RuntimeError):
-        p_f_x.eqTerm(zero)
-    with pytest.raises(RuntimeError):
-        p_f_x.eqTerm(f_x)
-    with pytest.raises(RuntimeError):
-        p_f_x.eqTerm(sum)
-    p_f_x.eqTerm(p_0)
-    p_f_x.eqTerm(p_f_x)
-
-
-def test_imp_term(solver):
-    bvSort = solver.mkBitVectorSort(8)
-    intSort = solver.getIntegerSort()
-    boolSort = solver.getBooleanSort()
-    funSort1 = solver.mkFunctionSort(bvSort, intSort)
-    funSort2 = solver.mkFunctionSort(intSort, boolSort)
-
-    b = solver.mkTrue()
-    with pytest.raises(RuntimeError):
-        Term(solver).impTerm(b)
-    with pytest.raises(RuntimeError):
-        b.impTerm(Term(solver))
-    b.impTerm(b)
-    x = solver.mkVar(solver.mkBitVectorSort(8), "x")
-    with pytest.raises(RuntimeError):
-        x.impTerm(b)
-    with pytest.raises(RuntimeError):
-        x.impTerm(x)
-    f = solver.mkVar(funSort1, "f")
-    with pytest.raises(RuntimeError):
-        f.impTerm(b)
-    with pytest.raises(RuntimeError):
-        f.impTerm(x)
-    with pytest.raises(RuntimeError):
-        f.impTerm(f)
-    p = solver.mkVar(funSort2, "p")
-    with pytest.raises(RuntimeError):
-        p.impTerm(b)
-    with pytest.raises(RuntimeError):
-        p.impTerm(x)
-    with pytest.raises(RuntimeError):
-        p.impTerm(f)
-    with pytest.raises(RuntimeError):
-        p.impTerm(p)
-    zero = solver.mkInteger(0)
-    with pytest.raises(RuntimeError):
-        zero.impTerm(b)
-    with pytest.raises(RuntimeError):
-        zero.impTerm(x)
-    with pytest.raises(RuntimeError):
-        zero.impTerm(f)
-    with pytest.raises(RuntimeError):
-        zero.impTerm(p)
-    with pytest.raises(RuntimeError):
-        zero.impTerm(zero)
-    f_x = solver.mkTerm(kinds.ApplyUf, f, x)
-    with pytest.raises(RuntimeError):
-        f_x.impTerm(b)
-    with pytest.raises(RuntimeError):
-        f_x.impTerm(x)
-    with pytest.raises(RuntimeError):
-        f_x.impTerm(f)
-    with pytest.raises(RuntimeError):
-        f_x.impTerm(p)
-    with pytest.raises(RuntimeError):
-        f_x.impTerm(zero)
-    with pytest.raises(RuntimeError):
-        f_x.impTerm(f_x)
-    sum = solver.mkTerm(kinds.Plus, f_x, f_x)
-    with pytest.raises(RuntimeError):
-        sum.impTerm(b)
-    with pytest.raises(RuntimeError):
-        sum.impTerm(x)
-    with pytest.raises(RuntimeError):
-        sum.impTerm(f)
-    with pytest.raises(RuntimeError):
-        sum.impTerm(p)
-    with pytest.raises(RuntimeError):
-        sum.impTerm(zero)
-    with pytest.raises(RuntimeError):
-        sum.impTerm(f_x)
-    with pytest.raises(RuntimeError):
-        sum.impTerm(sum)
-    p_0 = solver.mkTerm(kinds.ApplyUf, p, zero)
-    p_0.impTerm(b)
-    with pytest.raises(RuntimeError):
-        p_0.impTerm(x)
-    with pytest.raises(RuntimeError):
-        p_0.impTerm(f)
-    with pytest.raises(RuntimeError):
-        p_0.impTerm(p)
-    with pytest.raises(RuntimeError):
-        p_0.impTerm(zero)
-    with pytest.raises(RuntimeError):
-        p_0.impTerm(f_x)
-    with pytest.raises(RuntimeError):
-        p_0.impTerm(sum)
-    p_0.impTerm(p_0)
-    p_f_x = solver.mkTerm(kinds.ApplyUf, p, f_x)
-    p_f_x.impTerm(b)
-    with pytest.raises(RuntimeError):
-        p_f_x.impTerm(x)
-    with pytest.raises(RuntimeError):
-        p_f_x.impTerm(f)
-    with pytest.raises(RuntimeError):
-        p_f_x.impTerm(p)
-    with pytest.raises(RuntimeError):
-        p_f_x.impTerm(zero)
-    with pytest.raises(RuntimeError):
-        p_f_x.impTerm(f_x)
-    with pytest.raises(RuntimeError):
-        p_f_x.impTerm(sum)
-    p_f_x.impTerm(p_0)
-    p_f_x.impTerm(p_f_x)
-
-
-def test_ite_term(solver):
-    bvSort = solver.mkBitVectorSort(8)
-    intSort = solver.getIntegerSort()
-    boolSort = solver.getBooleanSort()
-    funSort1 = solver.mkFunctionSort(bvSort, intSort)
-    funSort2 = solver.mkFunctionSort(intSort, boolSort)
-
-    b = solver.mkTrue()
-    with pytest.raises(RuntimeError):
-        Term(solver).iteTerm(b, b)
-    with pytest.raises(RuntimeError):
-        b.iteTerm(Term(solver), b)
-    with pytest.raises(RuntimeError):
-        b.iteTerm(b, Term(solver))
-    b.iteTerm(b, b)
-    x = solver.mkVar(solver.mkBitVectorSort(8), "x")
-    b.iteTerm(x, x)
-    b.iteTerm(b, b)
-    with pytest.raises(RuntimeError):
-        b.iteTerm(x, b)
-    with pytest.raises(RuntimeError):
-        x.iteTerm(x, x)
-    with pytest.raises(RuntimeError):
-        x.iteTerm(x, b)
-    f = solver.mkVar(funSort1, "f")
-    with pytest.raises(RuntimeError):
-        f.iteTerm(b, b)
-    with pytest.raises(RuntimeError):
-        x.iteTerm(b, x)
-    p = solver.mkVar(funSort2, "p")
-    with pytest.raises(RuntimeError):
-        p.iteTerm(b, b)
-    with pytest.raises(RuntimeError):
-        p.iteTerm(x, b)
-    zero = solver.mkInteger(0)
-    with pytest.raises(RuntimeError):
-        zero.iteTerm(x, x)
-    with pytest.raises(RuntimeError):
-        zero.iteTerm(x, b)
-    f_x = solver.mkTerm(kinds.ApplyUf, f, x)
-    with pytest.raises(RuntimeError):
-        f_x.iteTerm(b, b)
-    with pytest.raises(RuntimeError):
-        f_x.iteTerm(b, x)
-    sum = solver.mkTerm(kinds.Plus, f_x, f_x)
-    with pytest.raises(RuntimeError):
-        sum.iteTerm(x, x)
-    with pytest.raises(RuntimeError):
-        sum.iteTerm(b, x)
-    p_0 = solver.mkTerm(kinds.ApplyUf, p, zero)
-    p_0.iteTerm(b, b)
-    p_0.iteTerm(x, x)
-    with pytest.raises(RuntimeError):
-        p_0.iteTerm(x, b)
-    p_f_x = solver.mkTerm(kinds.ApplyUf, p, f_x)
-    p_f_x.iteTerm(b, b)
-    p_f_x.iteTerm(x, x)
-    with pytest.raises(RuntimeError):
-        p_f_x.iteTerm(x, b)
-
-
-def test_term_assignment(solver):
-    t1 = solver.mkInteger(1)
-    t2 = t1
-    t2 = solver.mkInteger(2)
-    assert t1 == solver.mkInteger(1)
-
-
-def test_substitute(solver):
-    x = solver.mkConst(solver.getIntegerSort(), "x")
-    one = solver.mkInteger(1)
-    ttrue = solver.mkTrue()
-    xpx = solver.mkTerm(kinds.Plus, x, x)
-    onepone = solver.mkTerm(kinds.Plus, one, one)
-
-    assert xpx.substitute(x, one) == onepone
-    assert onepone.substitute(one, x) == xpx
-    # incorrect due to type
-    with pytest.raises(RuntimeError):
-        xpx.substitute(one, ttrue)
-
-    # simultaneous substitution
-    y = solver.mkConst(solver.getIntegerSort(), "y")
-    xpy = solver.mkTerm(kinds.Plus, x, y)
-    xpone = solver.mkTerm(kinds.Plus, y, one)
-    es = []
-    rs = []
-    es.append(x)
-    rs.append(y)
-    es.append(y)
-    rs.append(one)
-    assert xpy.substitute(es, rs) == xpone
-
-    # incorrect substitution due to arity
-    rs.pop()
-    with pytest.raises(RuntimeError):
-        xpy.substitute(es, rs)
-
-    # incorrect substitution due to types
-    rs.append(ttrue)
-    with pytest.raises(RuntimeError):
-        xpy.substitute(es, rs)
-
-    # null cannot substitute
-    tnull = Term(solver)
-    with pytest.raises(RuntimeError):
-        tnull.substitute(one, x)
-    with pytest.raises(RuntimeError):
-        xpx.substitute(tnull, x)
-    with pytest.raises(RuntimeError):
-        xpx.substitute(x, tnull)
-    rs.pop()
-    rs.append(tnull)
-    with pytest.raises(RuntimeError):
-        xpy.substitute(es, rs)
-    es.clear()
-    rs.clear()
-    es.append(x)
-    rs.append(y)
-    with pytest.raises(RuntimeError):
-        tnull.substitute(es, rs)
-    es.append(tnull)
-    rs.append(one)
-    with pytest.raises(RuntimeError):
-        xpx.substitute(es, rs)
-
-
-def test_term_compare(solver):
-    t1 = solver.mkInteger(1)
-    t2 = solver.mkTerm(kinds.Plus, solver.mkInteger(2), solver.mkInteger(2))
-    t3 = solver.mkTerm(kinds.Plus, solver.mkInteger(2), solver.mkInteger(2))
-    assert t2 >= t3
-    assert t2 <= t3
-    assert (t1 > t2) != (t1 < t2)
-    assert (t1 > t2 or t1 == t2) == (t1 >= t2)
-
-
-def test_term_children(solver):
-    # simple term 2+3
-    two = solver.mkInteger(2)
-    t1 = solver.mkTerm(kinds.Plus, two, solver.mkInteger(3))
-    assert t1[0] == two
-    assert t1.getNumChildren() == 2
-    tnull = Term(solver)
-    with pytest.raises(RuntimeError):
-        tnull.getNumChildren()
-
-    # apply term f(2)
-    intSort = solver.getIntegerSort()
-    fsort = solver.mkFunctionSort(intSort, intSort)
-    f = solver.mkConst(fsort, "f")
-    t2 = solver.mkTerm(kinds.ApplyUf, f, two)
-    # due to our higher-order view of terms, we treat f as a child of kinds.ApplyUf
-    assert t2.getNumChildren() == 2
-    assert t2[0] == f
-    assert t2[1] == two
-    with pytest.raises(RuntimeError):
-        tnull[0]
-
-
-def test_get_const_array_base(solver):
-    intsort = solver.getIntegerSort()
-    arrsort = solver.mkArraySort(intsort, intsort)
-    one = solver.mkInteger(1)
-    constarr = solver.mkConstArray(arrsort, one)
-
-    assert constarr.isConstArray()
-    assert one == constarr.getConstArrayBase()
-
-
-def test_get_abstract_value(solver):
-    v1 = solver.mkAbstractValue(1)
-    v2 = solver.mkAbstractValue("15")
-    v3 = solver.mkAbstractValue("18446744073709551617")
-
-    assert v1.isAbstractValue()
-    assert v2.isAbstractValue()
-    assert v3.isAbstractValue()
-    assert "1" == v1.getAbstractValue()
-    assert "15" == v2.getAbstractValue()
-    assert "18446744073709551617" == v3.getAbstractValue()
-
-
-def test_get_tuple(solver):
-    s1 = solver.getIntegerSort()
-    s2 = solver.getRealSort()
-    s3 = solver.getStringSort()
-
-    t1 = solver.mkInteger(15)
-    t2 = solver.mkReal(17, 25)
-    t3 = solver.mkString("abc")
-
-    tup = solver.mkTuple([s1, s2, s3], [t1, t2, t3])
-
-    assert tup.isTupleValue()
-    assert [t1, t2, t3] == tup.getTupleValue()
-
-
-def test_get_set(solver):
-    s = solver.mkSetSort(solver.getIntegerSort())
-
-    i1 = solver.mkInteger(5)
-    i2 = solver.mkInteger(7)
-
-    s1 = solver.mkEmptySet(s)
-    s2 = solver.mkTerm(kinds.SetSingleton, i1)
-    s3 = solver.mkTerm(kinds.SetSingleton, i1)
-    s4 = solver.mkTerm(kinds.SetSingleton, i2)
-    s5 = solver.mkTerm(
-            kinds.SetUnion, s2, solver.mkTerm(kinds.SetUnion, s3, s4))
-
-    assert s1.isSetValue()
-    assert s2.isSetValue()
-    assert s3.isSetValue()
-    assert s4.isSetValue()
-    assert not s5.isSetValue()
-    s5 = solver.simplify(s5)
-    assert s5.isSetValue()
-
-    assert set([]) == s1.getSetValue()
-    assert set([i1]) == s2.getSetValue()
-    assert set([i1]) == s3.getSetValue()
-    assert set([i2]) == s4.getSetValue()
-    assert set([i1, i2]) == s5.getSetValue()
-
-
-def test_get_sequence(solver):
-    s = solver.mkSequenceSort(solver.getIntegerSort())
-
-    i1 = solver.mkInteger(5)
-    i2 = solver.mkInteger(7)
-
-    s1 = solver.mkEmptySequence(s)
-    s2 = solver.mkTerm(kinds.SeqUnit, i1)
-    s3 = solver.mkTerm(kinds.SeqUnit, i1)
-    s4 = solver.mkTerm(kinds.SeqUnit, i2)
-    s5 = solver.mkTerm(kinds.SeqConcat, s2,
-                       solver.mkTerm(kinds.SeqConcat, s3, s4))
-
-    assert s1.isSequenceValue()
-    assert not s2.isSequenceValue()
-    assert not s3.isSequenceValue()
-    assert not s4.isSequenceValue()
-    assert not s5.isSequenceValue()
-
-    s2 = solver.simplify(s2)
-    s3 = solver.simplify(s3)
-    s4 = solver.simplify(s4)
-    s5 = solver.simplify(s5)
-
-    assert [] == s1.getSequenceValue()
-    assert [i1] == s2.getSequenceValue()
-    assert [i1] == s3.getSequenceValue()
-    assert [i2] == s4.getSequenceValue()
-    assert [i1, i1, i2] == s5.getSequenceValue()
-
-
-def test_get_uninterpreted_const(solver):
-    s = solver.mkUninterpretedSort("test")
-    t1 = solver.mkUninterpretedConst(s, 3)
-    t2 = solver.mkUninterpretedConst(s, 5)
-
-    assert t1.isUninterpretedValue()
-    assert t2.isUninterpretedValue()
-
-    assert (s, 3) == t1.getUninterpretedValue()
-    assert (s, 5) == t2.getUninterpretedValue()
-
-
-def test_get_floating_point(solver):
-    bvval = solver.mkBitVector(16, "0000110000000011", 2)
-    fp = solver.mkFloatingPoint(5, 11, bvval)
-
-    assert fp.isFloatingPointValue()
-    assert not fp.isFloatingPointPosZero()
-    assert not fp.isFloatingPointNegZero()
-    assert not fp.isFloatingPointPosInf()
-    assert not fp.isFloatingPointNegInf()
-    assert not fp.isFloatingPointNaN()
-    assert (5, 11, bvval) == fp.getFloatingPointValue()
-
-    assert solver.mkPosZero(5, 11).isFloatingPointPosZero()
-    assert solver.mkNegZero(5, 11).isFloatingPointNegZero()
-    assert solver.mkPosInf(5, 11).isFloatingPointPosInf()
-    assert solver.mkNegInf(5, 11).isFloatingPointNegInf()
-    assert solver.mkNaN(5, 11).isFloatingPointNaN()
-
-
-def test_is_integer(solver):
-    int1 = solver.mkInteger("-18446744073709551616")
-    int2 = solver.mkInteger("-18446744073709551615")
-    int3 = solver.mkInteger("-4294967296")
-    int4 = solver.mkInteger("-4294967295")
-    int5 = solver.mkInteger("-10")
-    int6 = solver.mkInteger("0")
-    int7 = solver.mkInteger("10")
-    int8 = solver.mkInteger("4294967295")
-    int9 = solver.mkInteger("4294967296")
-    int10 = solver.mkInteger("18446744073709551615")
-    int11 = solver.mkInteger("18446744073709551616")
-    int12 = solver.mkInteger("-0")
-
-    with pytest.raises(RuntimeError):
-        solver.mkInteger("")
-    with pytest.raises(RuntimeError):
-        solver.mkInteger("-")
-    with pytest.raises(RuntimeError):
-        solver.mkInteger("-1-")
-    with pytest.raises(RuntimeError):
-        solver.mkInteger("0.0")
-    with pytest.raises(RuntimeError):
-        solver.mkInteger("-0.1")
-    with pytest.raises(RuntimeError):
-        solver.mkInteger("012")
-    with pytest.raises(RuntimeError):
-        solver.mkInteger("0000")
-    with pytest.raises(RuntimeError):
-        solver.mkInteger("-01")
-    with pytest.raises(RuntimeError):
-        solver.mkInteger("-00")
-
-    assert int1.isIntegerValue()
-    assert int2.isIntegerValue()
-    assert int3.isIntegerValue()
-    assert int4.isIntegerValue()
-    assert int5.isIntegerValue()
-    assert int6.isIntegerValue()
-    assert int7.isIntegerValue()
-    assert int8.isIntegerValue()
-    assert int9.isIntegerValue()
-    assert int10.isIntegerValue()
-    assert int11.isIntegerValue()
-
-    assert int1.getIntegerValue() == -18446744073709551616
-    assert int2.getIntegerValue() == -18446744073709551615
-    assert int3.getIntegerValue() == -4294967296
-    assert int4.getIntegerValue() == -4294967295
-    assert int5.getIntegerValue() == -10
-    assert int6.getIntegerValue() == 0
-    assert int7.getIntegerValue() == 10
-    assert int8.getIntegerValue() == 4294967295
-    assert int9.getIntegerValue() == 4294967296
-    assert int10.getIntegerValue() == 18446744073709551615
-    assert int11.getIntegerValue() == 18446744073709551616
-
-
-def test_get_string(solver):
-    s1 = solver.mkString("abcde")
-    assert s1.isStringValue()
-    assert s1.getStringValue() == str("abcde")
-
-
-def test_get_real(solver):
-    real1 = solver.mkReal("0")
-    real2 = solver.mkReal(".0")
-    real3 = solver.mkReal("-17")
-    real4 = solver.mkReal("-3/5")
-    real5 = solver.mkReal("12.7")
-    real6 = solver.mkReal("1/4294967297")
-    real7 = solver.mkReal("4294967297")
-    real8 = solver.mkReal("1/18446744073709551617")
-    real9 = solver.mkReal("18446744073709551617")
-
-    assert real1.isRealValue()
-    assert real2.isRealValue()
-    assert real3.isRealValue()
-    assert real4.isRealValue()
-    assert real5.isRealValue()
-    assert real6.isRealValue()
-    assert real7.isRealValue()
-    assert real8.isRealValue()
-    assert real9.isRealValue()
-
-    assert 0 == real1.getRealValue()
-    assert 0 == real2.getRealValue()
-    assert -17 == real3.getRealValue()
-    assert Fraction(-3, 5) == real4.getRealValue()
-    assert Fraction(127, 10) == real5.getRealValue()
-    assert Fraction(1, 4294967297) == real6.getRealValue()
-    assert 4294967297 == real7.getRealValue()
-    assert Fraction(1, 18446744073709551617) == real8.getRealValue()
-    assert Fraction(18446744073709551617, 1) == real9.getRealValue()
-
-    # Check denominator too large for float
-    num = 1
-    den = 2 ** 64 + 1
-    real_big = solver.mkReal(num, den)
-    assert real_big.isRealValue()
-    assert Fraction(num, den) == real_big.getRealValue()
-
-    # Check that we're treating floats as decimal aproximations rather than
-    # IEEE-754-specified values.
-    real_decimal = solver.mkReal(0.3)
-    assert real_decimal.isRealValue()
-    assert Fraction("0.3") == real_decimal.getRealValue()
-    assert Fraction(0.3) == Fraction(5404319552844595, 18014398509481984)
-    assert Fraction(0.3) != real_decimal.getRealValue()
-
-
-def test_get_boolean(solver):
-    b1 = solver.mkBoolean(True)
-    b2 = solver.mkBoolean(False)
-
-    assert b1.isBooleanValue()
-    assert b2.isBooleanValue()
-    assert b1.getBooleanValue()
-    assert not b2.getBooleanValue()
-
-
-def test_get_bit_vector(solver):
-    b1 = solver.mkBitVector(8, 15)
-    b2 = solver.mkBitVector(8, "00001111", 2)
-    b3 = solver.mkBitVector(8, "15", 10)
-    b4 = solver.mkBitVector(8, "0f", 16)
-    b5 = solver.mkBitVector(9, "00001111", 2);
-    b6 = solver.mkBitVector(9, "15", 10);
-    b7 = solver.mkBitVector(9, "0f", 16);
-
-    assert b1.isBitVectorValue()
-    assert b2.isBitVectorValue()
-    assert b3.isBitVectorValue()
-    assert b4.isBitVectorValue()
-    assert b5.isBitVectorValue()
-    assert b6.isBitVectorValue()
-    assert b7.isBitVectorValue()
-
-    assert "00001111" == b1.getBitVectorValue(2)
-    assert "15" == b1.getBitVectorValue(10)
-    assert "f" == b1.getBitVectorValue(16)
-    assert "00001111" == b2.getBitVectorValue(2)
-    assert "15" == b2.getBitVectorValue(10)
-    assert "f" == b2.getBitVectorValue(16)
-    assert "00001111" == b3.getBitVectorValue(2)
-    assert "15" == b3.getBitVectorValue(10)
-    assert "f" == b3.getBitVectorValue(16)
-    assert "00001111" == b4.getBitVectorValue(2)
-    assert "15" == b4.getBitVectorValue(10)
-    assert "f" == b4.getBitVectorValue(16)
-    assert "000001111" == b5.getBitVectorValue(2)
-    assert "15" == b5.getBitVectorValue(10)
-    assert "f" == b5.getBitVectorValue(16)
-    assert "000001111" == b6.getBitVectorValue(2)
-    assert "15" == b6.getBitVectorValue(10)
-    assert "f" == b6.getBitVectorValue(16)
-    assert "000001111" == b7.getBitVectorValue(2)
-    assert "15" == b7.getBitVectorValue(10)
-    assert "f" == b7.getBitVectorValue(16)
-
-
-def test_const_array(solver):
-    intsort = solver.getIntegerSort()
-    arrsort = solver.mkArraySort(intsort, intsort)
-    a = solver.mkConst(arrsort, "a")
-    one = solver.mkInteger(1)
-    constarr = solver.mkConstArray(arrsort, one)
-
-    assert constarr.getKind() == kinds.ConstArray
-    assert constarr.getConstArrayBase() == one
-    with pytest.raises(RuntimeError):
-        a.getConstArrayBase()
-
-    arrsort = solver.mkArraySort(solver.getRealSort(), solver.getRealSort())
-    zero_array = solver.mkConstArray(arrsort, solver.mkReal(0))
-    stores = solver.mkTerm(kinds.Store, zero_array, solver.mkReal(1),
-                           solver.mkReal(2))
-    stores = solver.mkTerm(kinds.Store, stores, solver.mkReal(2),
-                           solver.mkReal(3))
-    stores = solver.mkTerm(kinds.Store, stores, solver.mkReal(4),
-                           solver.mkReal(5))
-
-
-def test_const_sequence_elements(solver):
-    realsort = solver.getRealSort()
-    seqsort = solver.mkSequenceSort(realsort)
-    s = solver.mkEmptySequence(seqsort)
-
-    assert s.getKind() == kinds.ConstSequence
-    # empty sequence has zero elements
-    cs = s.getSequenceValue()
-    assert len(cs) == 0
-
-    # A seq.unit app is not a constant sequence (regardless of whether it is
-    # applied to a constant).
-    su = solver.mkTerm(kinds.SeqUnit, solver.mkReal(1))
-    with pytest.raises(RuntimeError):
-        su.getSequenceValue()
-
-
-def test_term_scoped_to_string(solver):
-    intsort = solver.getIntegerSort()
-    x = solver.mkConst(intsort, "x")
-    assert str(x) == "x"
-    solver2 = pycvc5.Solver()
-    assert str(x) == "x"
diff --git a/test/python/unit/api/test_to_python_obj.py b/test/python/unit/api/test_to_python_obj.py
deleted file mode 100644 (file)
index bb30fae..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-###############################################################################
-# Top contributors (to current version):
-#   Makai Mann, Andres Noetzli, Mudathir Mohamed
-#
-# This file is part of the cvc5 project.
-#
-# Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
-# in the top-level source directory and their institutional affiliations.
-# All rights reserved.  See the file COPYING in the top-level source
-# directory for licensing information.
-# #############################################################################
-##
-
-from fractions import Fraction
-import pytest
-
-import pycvc5
-from pycvc5 import kinds
-
-
-def testGetBool():
-    solver = pycvc5.Solver()
-    t = solver.mkTrue()
-    f = solver.mkFalse()
-    assert t.toPythonObj() is True
-    assert f.toPythonObj() is False
-
-
-def testGetInt():
-    solver = pycvc5.Solver()
-    two = solver.mkInteger(2)
-    assert two.toPythonObj() == 2
-
-
-def testGetReal():
-    solver = pycvc5.Solver()
-    half = solver.mkReal("1/2")
-    assert half.toPythonObj() == Fraction(1, 2)
-
-    neg34 = solver.mkReal("-3/4")
-    assert neg34.toPythonObj() == Fraction(-3, 4)
-
-    neg1 = solver.mkInteger("-1")
-    assert neg1.toPythonObj() == -1
-
-
-def testGetBV():
-    solver = pycvc5.Solver()
-    three = solver.mkBitVector(8, 3)
-    assert three.toPythonObj() == 3
-
-
-def testGetArray():
-    solver = pycvc5.Solver()
-    arrsort = solver.mkArraySort(solver.getRealSort(), solver.getRealSort())
-    zero_array = solver.mkConstArray(arrsort, solver.mkInteger(0))
-    stores = solver.mkTerm(kinds.Store, zero_array, solver.mkInteger(1), solver.mkInteger(2))
-    stores = solver.mkTerm(kinds.Store, stores, solver.mkInteger(2), solver.mkInteger(3))
-    stores = solver.mkTerm(kinds.Store, stores, solver.mkInteger(4), solver.mkInteger(5))
-
-    array_dict = stores.toPythonObj()
-
-    assert array_dict[1] == 2
-    assert array_dict[2] == 3
-    assert array_dict[4] == 5
-    # an index that wasn't stored at should give zero
-    assert array_dict[8] == 0
-
-
-def testGetSymbol():
-    solver = pycvc5.Solver()
-    solver.mkConst(solver.getBooleanSort(), "x")
-
-
-def testGetString():
-    solver = pycvc5.Solver()
-
-    s1 = '"test\n"😃\\u{a}'
-    t1 = solver.mkString(s1)
-    assert s1 == t1.toPythonObj()
-
-    s2 = '❤️cvc5❤️'
-    t2 = solver.mkString(s2)
-    assert s2 == t2.toPythonObj()
-
-
-def testGetValueInt():
-    solver = pycvc5.Solver()
-    solver.setOption("produce-models", "true")
-
-    intsort = solver.getIntegerSort()
-    x = solver.mkConst(intsort, "x")
-    solver.assertFormula(solver.mkTerm(kinds.Equal, x, solver.mkInteger(6)))
-
-    r = solver.checkSat()
-    assert r.isSat()
-
-    xval = solver.getValue(x)
-    assert xval.toPythonObj() == 6
-
-
-def testGetValueReal():
-    solver = pycvc5.Solver()
-    solver.setOption("produce-models", "true")
-
-    realsort = solver.getRealSort()
-    x = solver.mkConst(realsort, "x")
-    y = solver.mkConst(realsort, "y")
-    solver.assertFormula(solver.mkTerm(kinds.Equal, x, solver.mkReal("6")))
-    solver.assertFormula(solver.mkTerm(kinds.Equal, y, solver.mkReal("8.33")))
-
-    r = solver.checkSat()
-    assert r.isSat()
-
-    xval = solver.getValue(x)
-    yval = solver.getValue(y)
-    assert xval.toPythonObj() == Fraction("6")
-    assert yval.toPythonObj() == Fraction("8.33")
index 11c2e8514d8bcc10c827aa22e990beea4e4c67fe..9be9dcefa8cb75757762c5bead9838fe68e8652a 100644 (file)
@@ -70,7 +70,11 @@ macro(cvc5_add_unit_test is_white name output_dir)
   if("${output_dir}" STREQUAL "")
     set(test_name unit/${name})
   else()
-    set(test_name unit/${output_dir}/${name})
+    if("${output_dir}" STREQUAL "api")
+      set(test_name unit/${output_dir}/cpp/${name})
+    else()
+      set(test_name unit/${output_dir}/${name})
+    endif()
   endif()
   add_test(${test_name} ${test_bin_dir}/${name})
   set_tests_properties(${test_name} PROPERTIES LABELS "unit")
index ae6db51ef1f686d900523350714476b1e738bea6..0701c3ca62bd0a58576c156db6dcb5fa39451826 100644 (file)
 # The build system configuration.
 ##
 
-# Add unit tests.
-cvc5_add_unit_test_black(datatype_api_black api)
-cvc5_add_unit_test_black(grammar_black api)
-cvc5_add_unit_test_black(op_black api)
-cvc5_add_unit_test_white(op_white api)
-cvc5_add_unit_test_black(result_black api)
-cvc5_add_unit_test_black(solver_black api)
-cvc5_add_unit_test_white(solver_white api)
-cvc5_add_unit_test_black(sort_black api)
-cvc5_add_unit_test_black(term_black api)
-cvc5_add_unit_test_white(term_white api)
+add_subdirectory(cpp)
+if (BUILD_BINDINGS_PYTHON)
+  add_subdirectory(python)
+endif()
 if (BUILD_BINDINGS_JAVA)
   add_subdirectory(java)
 endif()
diff --git a/test/unit/api/cpp/CMakeLists.txt b/test/unit/api/cpp/CMakeLists.txt
new file mode 100644 (file)
index 0000000..e99732c
--- /dev/null
@@ -0,0 +1,24 @@
+###############################################################################
+# Top contributors (to current version):
+#   Aina Niemetz
+#
+# This file is part of the cvc5 project.
+#
+# Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
+# in the top-level source directory and their institutional affiliations.
+# All rights reserved.  See the file COPYING in the top-level source
+# directory for licensing information.
+# #############################################################################
+#
+# The build system configuration.
+##
+cvc5_add_unit_test_black(datatype_api_black api)
+cvc5_add_unit_test_black(grammar_black api)
+cvc5_add_unit_test_black(op_black api)
+cvc5_add_unit_test_white(op_white api)
+cvc5_add_unit_test_black(result_black api)
+cvc5_add_unit_test_black(solver_black api)
+cvc5_add_unit_test_white(solver_white api)
+cvc5_add_unit_test_black(sort_black api)
+cvc5_add_unit_test_black(term_black api)
+cvc5_add_unit_test_white(term_white api)
diff --git a/test/unit/api/cpp/datatype_api_black.cpp b/test/unit/api/cpp/datatype_api_black.cpp
new file mode 100644 (file)
index 0000000..745abc1
--- /dev/null
@@ -0,0 +1,587 @@
+/******************************************************************************
+ * Top contributors (to current version):
+ *   Andrew Reynolds, Aina Niemetz, Andres Noetzli
+ *
+ * This file is part of the cvc5 project.
+ *
+ * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
+ * in the top-level source directory and their institutional affiliations.
+ * All rights reserved.  See the file COPYING in the top-level source
+ * directory for licensing information.
+ * ****************************************************************************
+ *
+ * Black box testing of the datatype classes of the C++ API.
+ */
+
+#include "test_api.h"
+
+namespace cvc5 {
+
+using namespace api;
+
+namespace test {
+
+class TestApiBlackDatatype : public TestApi
+{
+};
+
+TEST_F(TestApiBlackDatatype, mkDatatypeSort)
+{
+  DatatypeDecl dtypeSpec = d_solver.mkDatatypeDecl("list");
+  DatatypeConstructorDecl cons = d_solver.mkDatatypeConstructorDecl("cons");
+  cons.addSelector("head", d_solver.getIntegerSort());
+  dtypeSpec.addConstructor(cons);
+  DatatypeConstructorDecl nil = d_solver.mkDatatypeConstructorDecl("nil");
+  dtypeSpec.addConstructor(nil);
+  Sort listSort = d_solver.mkDatatypeSort(dtypeSpec);
+  Datatype d = listSort.getDatatype();
+  DatatypeConstructor consConstr = d[0];
+  DatatypeConstructor nilConstr = d[1];
+  ASSERT_THROW(d[2], CVC5ApiException);
+  ASSERT_NO_THROW(consConstr.getConstructorTerm());
+  ASSERT_NO_THROW(nilConstr.getConstructorTerm());
+}
+
+TEST_F(TestApiBlackDatatype, isNull)
+{
+  // creating empty (null) objects.
+  DatatypeDecl dtypeSpec;
+  DatatypeConstructorDecl cons;
+  Datatype d;
+  DatatypeConstructor consConstr;
+  DatatypeSelector sel;
+
+  // verifying that the objects are considered null.
+  ASSERT_TRUE(dtypeSpec.isNull());
+  ASSERT_TRUE(cons.isNull());
+  ASSERT_TRUE(d.isNull());
+  ASSERT_TRUE(consConstr.isNull());
+  ASSERT_TRUE(sel.isNull());
+
+  // changing the objects to be non-null
+  dtypeSpec = d_solver.mkDatatypeDecl("list");
+  cons = d_solver.mkDatatypeConstructorDecl("cons");
+  cons.addSelector("head", d_solver.getIntegerSort());
+  dtypeSpec.addConstructor(cons);
+  Sort listSort = d_solver.mkDatatypeSort(dtypeSpec);
+  d = listSort.getDatatype();
+  consConstr = d[0];
+  sel = consConstr[0];
+
+  // verifying that the new objects are non-null
+  ASSERT_FALSE(dtypeSpec.isNull());
+  ASSERT_FALSE(cons.isNull());
+  ASSERT_FALSE(d.isNull());
+  ASSERT_FALSE(consConstr.isNull());
+  ASSERT_FALSE(sel.isNull());
+}
+
+TEST_F(TestApiBlackDatatype, mkDatatypeSorts)
+{
+  /* Create two mutual datatypes corresponding to this definition
+   * block:
+   *
+   *   DATATYPE
+   *     tree = node(left: tree, right: tree) | leaf(data: list),
+   *     list = cons(car: tree, cdr: list) | nil
+   *   END;
+   */
+  // Make unresolved types as placeholders
+  std::set<Sort> unresTypes;
+  Sort unresTree = d_solver.mkUninterpretedSort("tree");
+  Sort unresList = d_solver.mkUninterpretedSort("list");
+  unresTypes.insert(unresTree);
+  unresTypes.insert(unresList);
+
+  DatatypeDecl tree = d_solver.mkDatatypeDecl("tree");
+  DatatypeConstructorDecl node = d_solver.mkDatatypeConstructorDecl("node");
+  node.addSelector("left", unresTree);
+  node.addSelector("right", unresTree);
+  tree.addConstructor(node);
+
+  DatatypeConstructorDecl leaf = d_solver.mkDatatypeConstructorDecl("leaf");
+  leaf.addSelector("data", unresList);
+  tree.addConstructor(leaf);
+
+  DatatypeDecl list = d_solver.mkDatatypeDecl("list");
+  DatatypeConstructorDecl cons = d_solver.mkDatatypeConstructorDecl("cons");
+  cons.addSelector("car", unresTree);
+  cons.addSelector("cdr", unresTree);
+  list.addConstructor(cons);
+
+  DatatypeConstructorDecl nil = d_solver.mkDatatypeConstructorDecl("nil");
+  list.addConstructor(nil);
+
+  std::vector<DatatypeDecl> dtdecls;
+  dtdecls.push_back(tree);
+  dtdecls.push_back(list);
+  std::vector<Sort> dtsorts;
+  ASSERT_NO_THROW(dtsorts = d_solver.mkDatatypeSorts(dtdecls, unresTypes));
+  ASSERT_EQ(dtsorts.size(), dtdecls.size());
+  for (size_t i = 0, ndecl = dtdecls.size(); i < ndecl; i++)
+  {
+    ASSERT_TRUE(dtsorts[i].isDatatype());
+    ASSERT_FALSE(dtsorts[i].getDatatype().isFinite());
+    ASSERT_EQ(dtsorts[i].getDatatype().getName(), dtdecls[i].getName());
+  }
+  // verify the resolution was correct
+  Datatype dtTree = dtsorts[0].getDatatype();
+  DatatypeConstructor dtcTreeNode = dtTree[0];
+  ASSERT_EQ(dtcTreeNode.getName(), "node");
+  DatatypeSelector dtsTreeNodeLeft = dtcTreeNode[0];
+  ASSERT_EQ(dtsTreeNodeLeft.getName(), "left");
+  // argument type should have resolved to be recursive
+  ASSERT_TRUE(dtsTreeNodeLeft.getRangeSort().isDatatype());
+  ASSERT_EQ(dtsTreeNodeLeft.getRangeSort(), dtsorts[0]);
+
+  // fails due to empty datatype
+  std::vector<DatatypeDecl> dtdeclsBad;
+  DatatypeDecl emptyD = d_solver.mkDatatypeDecl("emptyD");
+  dtdeclsBad.push_back(emptyD);
+  ASSERT_THROW(d_solver.mkDatatypeSorts(dtdeclsBad), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackDatatype, datatypeStructs)
+{
+  Sort intSort = d_solver.getIntegerSort();
+  Sort boolSort = d_solver.getBooleanSort();
+
+  // create datatype sort to test
+  DatatypeDecl dtypeSpec = d_solver.mkDatatypeDecl("list");
+  DatatypeConstructorDecl cons = d_solver.mkDatatypeConstructorDecl("cons");
+  cons.addSelector("head", intSort);
+  cons.addSelectorSelf("tail");
+  Sort nullSort;
+  ASSERT_THROW(cons.addSelector("null", nullSort), CVC5ApiException);
+  dtypeSpec.addConstructor(cons);
+  DatatypeConstructorDecl nil = d_solver.mkDatatypeConstructorDecl("nil");
+  dtypeSpec.addConstructor(nil);
+  Sort dtypeSort = d_solver.mkDatatypeSort(dtypeSpec);
+  Datatype dt = dtypeSort.getDatatype();
+  ASSERT_FALSE(dt.isCodatatype());
+  ASSERT_FALSE(dt.isTuple());
+  ASSERT_FALSE(dt.isRecord());
+  ASSERT_FALSE(dt.isFinite());
+  ASSERT_TRUE(dt.isWellFounded());
+  // get constructor
+  DatatypeConstructor dcons = dt[0];
+  Term consTerm = dcons.getConstructorTerm();
+  ASSERT_EQ(dcons.getNumSelectors(), 2);
+
+  // create datatype sort to test
+  DatatypeDecl dtypeSpecEnum = d_solver.mkDatatypeDecl("enum");
+  DatatypeConstructorDecl ca = d_solver.mkDatatypeConstructorDecl("A");
+  dtypeSpecEnum.addConstructor(ca);
+  DatatypeConstructorDecl cb = d_solver.mkDatatypeConstructorDecl("B");
+  dtypeSpecEnum.addConstructor(cb);
+  DatatypeConstructorDecl cc = d_solver.mkDatatypeConstructorDecl("C");
+  dtypeSpecEnum.addConstructor(cc);
+  Sort dtypeSortEnum = d_solver.mkDatatypeSort(dtypeSpecEnum);
+  Datatype dtEnum = dtypeSortEnum.getDatatype();
+  ASSERT_FALSE(dtEnum.isTuple());
+  ASSERT_TRUE(dtEnum.isFinite());
+
+  // create codatatype
+  DatatypeDecl dtypeSpecStream = d_solver.mkDatatypeDecl("stream", true);
+  DatatypeConstructorDecl consStream =
+      d_solver.mkDatatypeConstructorDecl("cons");
+  consStream.addSelector("head", intSort);
+  consStream.addSelectorSelf("tail");
+  dtypeSpecStream.addConstructor(consStream);
+  Sort dtypeSortStream = d_solver.mkDatatypeSort(dtypeSpecStream);
+  Datatype dtStream = dtypeSortStream.getDatatype();
+  ASSERT_TRUE(dtStream.isCodatatype());
+  ASSERT_FALSE(dtStream.isFinite());
+  // codatatypes may be well-founded
+  ASSERT_TRUE(dtStream.isWellFounded());
+
+  // create tuple
+  Sort tupSort = d_solver.mkTupleSort({boolSort});
+  Datatype dtTuple = tupSort.getDatatype();
+  ASSERT_TRUE(dtTuple.isTuple());
+  ASSERT_FALSE(dtTuple.isRecord());
+  ASSERT_TRUE(dtTuple.isFinite());
+  ASSERT_TRUE(dtTuple.isWellFounded());
+
+  // create record
+  std::vector<std::pair<std::string, Sort>> fields = {
+      std::make_pair("b", boolSort), std::make_pair("i", intSort)};
+  Sort recSort = d_solver.mkRecordSort(fields);
+  ASSERT_TRUE(recSort.isDatatype());
+  Datatype dtRecord = recSort.getDatatype();
+  ASSERT_FALSE(dtRecord.isTuple());
+  ASSERT_TRUE(dtRecord.isRecord());
+  ASSERT_FALSE(dtRecord.isFinite());
+  ASSERT_TRUE(dtRecord.isWellFounded());
+}
+
+TEST_F(TestApiBlackDatatype, datatypeNames)
+{
+  Sort intSort = d_solver.getIntegerSort();
+
+  // create datatype sort to test
+  DatatypeDecl dtypeSpec = d_solver.mkDatatypeDecl("list");
+  ASSERT_NO_THROW(dtypeSpec.getName());
+  ASSERT_EQ(dtypeSpec.getName(), std::string("list"));
+  DatatypeConstructorDecl cons = d_solver.mkDatatypeConstructorDecl("cons");
+  cons.addSelector("head", intSort);
+  cons.addSelectorSelf("tail");
+  dtypeSpec.addConstructor(cons);
+  DatatypeConstructorDecl nil = d_solver.mkDatatypeConstructorDecl("nil");
+  dtypeSpec.addConstructor(nil);
+  Sort dtypeSort = d_solver.mkDatatypeSort(dtypeSpec);
+  Datatype dt = dtypeSort.getDatatype();
+  ASSERT_EQ(dt.getName(), std::string("list"));
+  ASSERT_NO_THROW(dt.getConstructor("nil"));
+  ASSERT_NO_THROW(dt["cons"]);
+  ASSERT_THROW(dt.getConstructor("head"), CVC5ApiException);
+  ASSERT_THROW(dt.getConstructor(""), CVC5ApiException);
+
+  DatatypeConstructor dcons = dt[0];
+  ASSERT_EQ(dcons.getName(), std::string("cons"));
+  ASSERT_NO_THROW(dcons.getSelector("head"));
+  ASSERT_NO_THROW(dcons["tail"]);
+  ASSERT_THROW(dcons.getSelector("cons"), CVC5ApiException);
+
+  // get selector
+  DatatypeSelector dselTail = dcons[1];
+  ASSERT_EQ(dselTail.getName(), std::string("tail"));
+  ASSERT_EQ(dselTail.getRangeSort(), dtypeSort);
+
+  // get selector from datatype
+  ASSERT_NO_THROW(dt.getSelector("head"));
+  ASSERT_THROW(dt.getSelector("cons"), CVC5ApiException);
+
+  // possible to construct null datatype declarations if not using solver
+  ASSERT_THROW(DatatypeDecl().getName(), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackDatatype, parametricDatatype)
+{
+  std::vector<Sort> v;
+  Sort t1 = d_solver.mkParamSort("T1");
+  Sort t2 = d_solver.mkParamSort("T2");
+  v.push_back(t1);
+  v.push_back(t2);
+  DatatypeDecl pairSpec = d_solver.mkDatatypeDecl("pair", v);
+
+  DatatypeConstructorDecl mkpair =
+      d_solver.mkDatatypeConstructorDecl("mk-pair");
+  mkpair.addSelector("first", t1);
+  mkpair.addSelector("second", t2);
+  pairSpec.addConstructor(mkpair);
+
+  Sort pairType = d_solver.mkDatatypeSort(pairSpec);
+
+  ASSERT_TRUE(pairType.getDatatype().isParametric());
+
+  v.clear();
+  v.push_back(d_solver.getIntegerSort());
+  v.push_back(d_solver.getIntegerSort());
+  Sort pairIntInt = pairType.instantiate(v);
+  v.clear();
+  v.push_back(d_solver.getRealSort());
+  v.push_back(d_solver.getRealSort());
+  Sort pairRealReal = pairType.instantiate(v);
+  v.clear();
+  v.push_back(d_solver.getRealSort());
+  v.push_back(d_solver.getIntegerSort());
+  Sort pairRealInt = pairType.instantiate(v);
+  v.clear();
+  v.push_back(d_solver.getIntegerSort());
+  v.push_back(d_solver.getRealSort());
+  Sort pairIntReal = pairType.instantiate(v);
+
+  ASSERT_NE(pairIntInt, pairRealReal);
+  ASSERT_NE(pairIntReal, pairRealReal);
+  ASSERT_NE(pairRealInt, pairRealReal);
+  ASSERT_NE(pairIntInt, pairIntReal);
+  ASSERT_NE(pairIntInt, pairRealInt);
+  ASSERT_NE(pairIntReal, pairRealInt);
+
+  ASSERT_TRUE(pairRealReal.isComparableTo(pairRealReal));
+  ASSERT_FALSE(pairIntReal.isComparableTo(pairRealReal));
+  ASSERT_FALSE(pairRealInt.isComparableTo(pairRealReal));
+  ASSERT_FALSE(pairIntInt.isComparableTo(pairRealReal));
+  ASSERT_FALSE(pairRealReal.isComparableTo(pairRealInt));
+  ASSERT_FALSE(pairIntReal.isComparableTo(pairRealInt));
+  ASSERT_TRUE(pairRealInt.isComparableTo(pairRealInt));
+  ASSERT_FALSE(pairIntInt.isComparableTo(pairRealInt));
+  ASSERT_FALSE(pairRealReal.isComparableTo(pairIntReal));
+  ASSERT_TRUE(pairIntReal.isComparableTo(pairIntReal));
+  ASSERT_FALSE(pairRealInt.isComparableTo(pairIntReal));
+  ASSERT_FALSE(pairIntInt.isComparableTo(pairIntReal));
+  ASSERT_FALSE(pairRealReal.isComparableTo(pairIntInt));
+  ASSERT_FALSE(pairIntReal.isComparableTo(pairIntInt));
+  ASSERT_FALSE(pairRealInt.isComparableTo(pairIntInt));
+  ASSERT_TRUE(pairIntInt.isComparableTo(pairIntInt));
+
+  ASSERT_TRUE(pairRealReal.isSubsortOf(pairRealReal));
+  ASSERT_FALSE(pairIntReal.isSubsortOf(pairRealReal));
+  ASSERT_FALSE(pairRealInt.isSubsortOf(pairRealReal));
+  ASSERT_FALSE(pairIntInt.isSubsortOf(pairRealReal));
+  ASSERT_FALSE(pairRealReal.isSubsortOf(pairRealInt));
+  ASSERT_FALSE(pairIntReal.isSubsortOf(pairRealInt));
+  ASSERT_TRUE(pairRealInt.isSubsortOf(pairRealInt));
+  ASSERT_FALSE(pairIntInt.isSubsortOf(pairRealInt));
+  ASSERT_FALSE(pairRealReal.isSubsortOf(pairIntReal));
+  ASSERT_TRUE(pairIntReal.isSubsortOf(pairIntReal));
+  ASSERT_FALSE(pairRealInt.isSubsortOf(pairIntReal));
+  ASSERT_FALSE(pairIntInt.isSubsortOf(pairIntReal));
+  ASSERT_FALSE(pairRealReal.isSubsortOf(pairIntInt));
+  ASSERT_FALSE(pairIntReal.isSubsortOf(pairIntInt));
+  ASSERT_FALSE(pairRealInt.isSubsortOf(pairIntInt));
+  ASSERT_TRUE(pairIntInt.isSubsortOf(pairIntInt));
+}
+
+TEST_F(TestApiBlackDatatype, datatypeSimplyRec)
+{
+  /* Create mutual datatypes corresponding to this definition block:
+   *
+   *   DATATYPE
+   *     wlist = leaf(data: list),
+   *     list = cons(car: wlist, cdr: list) | nil,
+   *     ns = elem(ndata: set(wlist)) | elemArray(ndata2: array(list, list))
+   *   END;
+   */
+  // Make unresolved types as placeholders
+  std::set<Sort> unresTypes;
+  Sort unresWList = d_solver.mkUninterpretedSort("wlist");
+  Sort unresList = d_solver.mkUninterpretedSort("list");
+  Sort unresNs = d_solver.mkUninterpretedSort("ns");
+  unresTypes.insert(unresWList);
+  unresTypes.insert(unresList);
+  unresTypes.insert(unresNs);
+
+  DatatypeDecl wlist = d_solver.mkDatatypeDecl("wlist");
+  DatatypeConstructorDecl leaf = d_solver.mkDatatypeConstructorDecl("leaf");
+  leaf.addSelector("data", unresList);
+  wlist.addConstructor(leaf);
+
+  DatatypeDecl list = d_solver.mkDatatypeDecl("list");
+  DatatypeConstructorDecl cons = d_solver.mkDatatypeConstructorDecl("cons");
+  cons.addSelector("car", unresWList);
+  cons.addSelector("cdr", unresList);
+  list.addConstructor(cons);
+  DatatypeConstructorDecl nil = d_solver.mkDatatypeConstructorDecl("nil");
+  list.addConstructor(nil);
+
+  DatatypeDecl ns = d_solver.mkDatatypeDecl("ns");
+  DatatypeConstructorDecl elem = d_solver.mkDatatypeConstructorDecl("elem");
+  elem.addSelector("ndata", d_solver.mkSetSort(unresWList));
+  ns.addConstructor(elem);
+  DatatypeConstructorDecl elemArray =
+      d_solver.mkDatatypeConstructorDecl("elemArray");
+  elemArray.addSelector("ndata", d_solver.mkArraySort(unresList, unresList));
+  ns.addConstructor(elemArray);
+
+  std::vector<DatatypeDecl> dtdecls;
+  dtdecls.push_back(wlist);
+  dtdecls.push_back(list);
+  dtdecls.push_back(ns);
+  // this is well-founded and has no nested recursion
+  std::vector<Sort> dtsorts;
+  ASSERT_NO_THROW(dtsorts = d_solver.mkDatatypeSorts(dtdecls, unresTypes));
+  ASSERT_EQ(dtsorts.size(), 3);
+  ASSERT_TRUE(dtsorts[0].getDatatype().isWellFounded());
+  ASSERT_TRUE(dtsorts[1].getDatatype().isWellFounded());
+  ASSERT_TRUE(dtsorts[2].getDatatype().isWellFounded());
+  ASSERT_FALSE(dtsorts[0].getDatatype().hasNestedRecursion());
+  ASSERT_FALSE(dtsorts[1].getDatatype().hasNestedRecursion());
+  ASSERT_FALSE(dtsorts[2].getDatatype().hasNestedRecursion());
+
+  /* Create mutual datatypes corresponding to this definition block:
+   *   DATATYPE
+   *     ns2 = elem2(ndata: array(int,ns2)) | nil2
+   *   END;
+   */
+  unresTypes.clear();
+  Sort unresNs2 = d_solver.mkUninterpretedSort("ns2");
+  unresTypes.insert(unresNs2);
+
+  DatatypeDecl ns2 = d_solver.mkDatatypeDecl("ns2");
+  DatatypeConstructorDecl elem2 = d_solver.mkDatatypeConstructorDecl("elem2");
+  elem2.addSelector("ndata",
+                    d_solver.mkArraySort(d_solver.getIntegerSort(), unresNs2));
+  ns2.addConstructor(elem2);
+  DatatypeConstructorDecl nil2 = d_solver.mkDatatypeConstructorDecl("nil2");
+  ns2.addConstructor(nil2);
+
+  dtdecls.clear();
+  dtdecls.push_back(ns2);
+
+  dtsorts.clear();
+  // this is not well-founded due to non-simple recursion
+  ASSERT_NO_THROW(dtsorts = d_solver.mkDatatypeSorts(dtdecls, unresTypes));
+  ASSERT_EQ(dtsorts.size(), 1);
+  ASSERT_TRUE(dtsorts[0].getDatatype()[0][0].getRangeSort().isArray());
+  ASSERT_EQ(dtsorts[0].getDatatype()[0][0].getRangeSort().getArrayElementSort(),
+            dtsorts[0]);
+  ASSERT_TRUE(dtsorts[0].getDatatype().isWellFounded());
+  ASSERT_TRUE(dtsorts[0].getDatatype().hasNestedRecursion());
+
+  /* Create mutual datatypes corresponding to this definition block:
+   *   DATATYPE
+   *     list3 = cons3(car: ns3, cdr: list3) | nil3,
+   *     ns3 = elem3(ndata: set(list3))
+   *   END;
+   */
+  unresTypes.clear();
+  Sort unresNs3 = d_solver.mkUninterpretedSort("ns3");
+  unresTypes.insert(unresNs3);
+  Sort unresList3 = d_solver.mkUninterpretedSort("list3");
+  unresTypes.insert(unresList3);
+
+  DatatypeDecl list3 = d_solver.mkDatatypeDecl("list3");
+  DatatypeConstructorDecl cons3 = d_solver.mkDatatypeConstructorDecl("cons3");
+  cons3.addSelector("car", unresNs3);
+  cons3.addSelector("cdr", unresList3);
+  list3.addConstructor(cons3);
+  DatatypeConstructorDecl nil3 = d_solver.mkDatatypeConstructorDecl("nil3");
+  list3.addConstructor(nil3);
+
+  DatatypeDecl ns3 = d_solver.mkDatatypeDecl("ns3");
+  DatatypeConstructorDecl elem3 = d_solver.mkDatatypeConstructorDecl("elem3");
+  elem3.addSelector("ndata", d_solver.mkSetSort(unresList3));
+  ns3.addConstructor(elem3);
+
+  dtdecls.clear();
+  dtdecls.push_back(list3);
+  dtdecls.push_back(ns3);
+
+  dtsorts.clear();
+  // both are well-founded and have nested recursion
+  ASSERT_NO_THROW(dtsorts = d_solver.mkDatatypeSorts(dtdecls, unresTypes));
+  ASSERT_EQ(dtsorts.size(), 2);
+  ASSERT_TRUE(dtsorts[0].getDatatype().isWellFounded());
+  ASSERT_TRUE(dtsorts[1].getDatatype().isWellFounded());
+  ASSERT_TRUE(dtsorts[0].getDatatype().hasNestedRecursion());
+  ASSERT_TRUE(dtsorts[1].getDatatype().hasNestedRecursion());
+
+  /* Create mutual datatypes corresponding to this definition block:
+   *   DATATYPE
+   *     list4 = cons(car: set(ns4), cdr: list4) | nil,
+   *     ns4 = elem(ndata: list4)
+   *   END;
+   */
+  unresTypes.clear();
+  Sort unresNs4 = d_solver.mkUninterpretedSort("ns4");
+  unresTypes.insert(unresNs4);
+  Sort unresList4 = d_solver.mkUninterpretedSort("list4");
+  unresTypes.insert(unresList4);
+
+  DatatypeDecl list4 = d_solver.mkDatatypeDecl("list4");
+  DatatypeConstructorDecl cons4 = d_solver.mkDatatypeConstructorDecl("cons4");
+  cons4.addSelector("car", d_solver.mkSetSort(unresNs4));
+  cons4.addSelector("cdr", unresList4);
+  list4.addConstructor(cons4);
+  DatatypeConstructorDecl nil4 = d_solver.mkDatatypeConstructorDecl("nil4");
+  list4.addConstructor(nil4);
+
+  DatatypeDecl ns4 = d_solver.mkDatatypeDecl("ns4");
+  DatatypeConstructorDecl elem4 = d_solver.mkDatatypeConstructorDecl("elem3");
+  elem4.addSelector("ndata", unresList4);
+  ns4.addConstructor(elem4);
+
+  dtdecls.clear();
+  dtdecls.push_back(list4);
+  dtdecls.push_back(ns4);
+
+  dtsorts.clear();
+  // both are well-founded and have nested recursion
+  ASSERT_NO_THROW(dtsorts = d_solver.mkDatatypeSorts(dtdecls, unresTypes));
+  ASSERT_EQ(dtsorts.size(), 2);
+  ASSERT_TRUE(dtsorts[0].getDatatype().isWellFounded());
+  ASSERT_TRUE(dtsorts[1].getDatatype().isWellFounded());
+  ASSERT_TRUE(dtsorts[0].getDatatype().hasNestedRecursion());
+  ASSERT_TRUE(dtsorts[1].getDatatype().hasNestedRecursion());
+
+  /* Create mutual datatypes corresponding to this definition block:
+   *   DATATYPE
+   *     list5[X] = cons(car: X, cdr: list5[list5[X]]) | nil
+   *   END;
+   */
+  unresTypes.clear();
+  Sort unresList5 = d_solver.mkSortConstructorSort("list5", 1);
+  unresTypes.insert(unresList5);
+
+  std::vector<Sort> v;
+  Sort x = d_solver.mkParamSort("X");
+  v.push_back(x);
+  DatatypeDecl list5 = d_solver.mkDatatypeDecl("list5", v);
+
+  std::vector<Sort> args;
+  args.push_back(x);
+  Sort urListX = unresList5.instantiate(args);
+  args[0] = urListX;
+  Sort urListListX = unresList5.instantiate(args);
+
+  DatatypeConstructorDecl cons5 = d_solver.mkDatatypeConstructorDecl("cons5");
+  cons5.addSelector("car", x);
+  cons5.addSelector("cdr", urListListX);
+  list5.addConstructor(cons5);
+  DatatypeConstructorDecl nil5 = d_solver.mkDatatypeConstructorDecl("nil5");
+  list5.addConstructor(nil5);
+
+  dtdecls.clear();
+  dtdecls.push_back(list5);
+
+  // well-founded and has nested recursion
+  ASSERT_NO_THROW(dtsorts = d_solver.mkDatatypeSorts(dtdecls, unresTypes));
+  ASSERT_EQ(dtsorts.size(), 1);
+  ASSERT_TRUE(dtsorts[0].getDatatype().isWellFounded());
+  ASSERT_TRUE(dtsorts[0].getDatatype().hasNestedRecursion());
+}
+
+TEST_F(TestApiBlackDatatype, datatypeSpecializedCons)
+{
+  /* Create mutual datatypes corresponding to this definition block:
+   *   DATATYPE
+   *     plist[X] = pcons(car: X, cdr: plist[X]) | pnil
+   *   END;
+   */
+  // Make unresolved types as placeholders
+  std::set<Sort> unresTypes;
+  Sort unresList = d_solver.mkSortConstructorSort("plist", 1);
+  unresTypes.insert(unresList);
+
+  std::vector<Sort> v;
+  Sort x = d_solver.mkParamSort("X");
+  v.push_back(x);
+  DatatypeDecl plist = d_solver.mkDatatypeDecl("plist", v);
+
+  std::vector<Sort> args;
+  args.push_back(x);
+  Sort urListX = unresList.instantiate(args);
+
+  DatatypeConstructorDecl pcons = d_solver.mkDatatypeConstructorDecl("pcons");
+  pcons.addSelector("car", x);
+  pcons.addSelector("cdr", urListX);
+  plist.addConstructor(pcons);
+  DatatypeConstructorDecl nil5 = d_solver.mkDatatypeConstructorDecl("pnil");
+  plist.addConstructor(nil5);
+
+  std::vector<DatatypeDecl> dtdecls;
+  dtdecls.push_back(plist);
+
+  std::vector<Sort> dtsorts;
+  // make the datatype sorts
+  ASSERT_NO_THROW(dtsorts = d_solver.mkDatatypeSorts(dtdecls, unresTypes));
+  ASSERT_EQ(dtsorts.size(), 1);
+  Datatype d = dtsorts[0].getDatatype();
+  DatatypeConstructor nilc = d[0];
+
+  Sort isort = d_solver.getIntegerSort();
+  std::vector<Sort> iargs;
+  iargs.push_back(isort);
+  Sort listInt = dtsorts[0].instantiate(iargs);
+
+  Term testConsTerm;
+  // get the specialized constructor term for list[Int]
+  ASSERT_NO_THROW(testConsTerm = nilc.getSpecializedConstructorTerm(listInt));
+  ASSERT_NE(testConsTerm, nilc.getConstructorTerm());
+  // error to get the specialized constructor term for Int
+  ASSERT_THROW(nilc.getSpecializedConstructorTerm(isort), CVC5ApiException);
+}
+}  // namespace test
+}  // namespace cvc5
diff --git a/test/unit/api/cpp/grammar_black.cpp b/test/unit/api/cpp/grammar_black.cpp
new file mode 100644 (file)
index 0000000..7b75565
--- /dev/null
@@ -0,0 +1,124 @@
+/******************************************************************************
+ * Top contributors (to current version):
+ *   Aina Niemetz, Abdalrhman Mohamed
+ *
+ * This file is part of the cvc5 project.
+ *
+ * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
+ * in the top-level source directory and their institutional affiliations.
+ * All rights reserved.  See the file COPYING in the top-level source
+ * directory for licensing information.
+ * ****************************************************************************
+ *
+ * Black box testing of the guards of the C++ API functions.
+ */
+
+#include "test_api.h"
+
+namespace cvc5 {
+
+using namespace api;
+
+namespace test {
+
+class TestApiBlackGrammar : public TestApi
+{
+};
+
+TEST_F(TestApiBlackGrammar, addRule)
+{
+  Sort boolean = d_solver.getBooleanSort();
+  Sort integer = d_solver.getIntegerSort();
+
+  Term nullTerm;
+  Term start = d_solver.mkVar(boolean);
+  Term nts = d_solver.mkVar(boolean);
+
+  Grammar g = d_solver.mkSygusGrammar({}, {start});
+
+  ASSERT_NO_THROW(g.addRule(start, d_solver.mkBoolean(false)));
+
+  ASSERT_THROW(g.addRule(nullTerm, d_solver.mkBoolean(false)),
+               CVC5ApiException);
+  ASSERT_THROW(g.addRule(start, nullTerm), CVC5ApiException);
+  ASSERT_THROW(g.addRule(nts, d_solver.mkBoolean(false)), CVC5ApiException);
+  ASSERT_THROW(g.addRule(start, d_solver.mkInteger(0)), CVC5ApiException);
+  ASSERT_THROW(g.addRule(start, nts), CVC5ApiException);
+
+  d_solver.synthFun("f", {}, boolean, g);
+
+  ASSERT_THROW(g.addRule(start, d_solver.mkBoolean(false)), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackGrammar, addRules)
+{
+  Sort boolean = d_solver.getBooleanSort();
+  Sort integer = d_solver.getIntegerSort();
+
+  Term nullTerm;
+  Term start = d_solver.mkVar(boolean);
+  Term nts = d_solver.mkVar(boolean);
+
+  Grammar g = d_solver.mkSygusGrammar({}, {start});
+
+  ASSERT_NO_THROW(g.addRules(start, {d_solver.mkBoolean(false)}));
+
+  ASSERT_THROW(g.addRules(nullTerm, {d_solver.mkBoolean(false)}),
+               CVC5ApiException);
+  ASSERT_THROW(g.addRules(start, {nullTerm}), CVC5ApiException);
+  ASSERT_THROW(g.addRules(nts, {d_solver.mkBoolean(false)}), CVC5ApiException);
+  ASSERT_THROW(g.addRules(start, {d_solver.mkInteger(0)}), CVC5ApiException);
+  ASSERT_THROW(g.addRules(start, {nts}), CVC5ApiException);
+
+  d_solver.synthFun("f", {}, boolean, g);
+
+  ASSERT_THROW(g.addRules(start, {d_solver.mkBoolean(false)}),
+               CVC5ApiException);
+}
+
+TEST_F(TestApiBlackGrammar, addAnyConstant)
+{
+  Sort boolean = d_solver.getBooleanSort();
+
+  Term nullTerm;
+  Term start = d_solver.mkVar(boolean);
+  Term nts = d_solver.mkVar(boolean);
+
+  Grammar g = d_solver.mkSygusGrammar({}, {start});
+
+  ASSERT_NO_THROW(g.addAnyConstant(start));
+  ASSERT_NO_THROW(g.addAnyConstant(start));
+
+  ASSERT_THROW(g.addAnyConstant(nullTerm), CVC5ApiException);
+  ASSERT_THROW(g.addAnyConstant(nts), CVC5ApiException);
+
+  d_solver.synthFun("f", {}, boolean, g);
+
+  ASSERT_THROW(g.addAnyConstant(start), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackGrammar, addAnyVariable)
+{
+  Sort boolean = d_solver.getBooleanSort();
+
+  Term nullTerm;
+  Term x = d_solver.mkVar(boolean);
+  Term start = d_solver.mkVar(boolean);
+  Term nts = d_solver.mkVar(boolean);
+
+  Grammar g1 = d_solver.mkSygusGrammar({x}, {start});
+  Grammar g2 = d_solver.mkSygusGrammar({}, {start});
+
+  ASSERT_NO_THROW(g1.addAnyVariable(start));
+  ASSERT_NO_THROW(g1.addAnyVariable(start));
+  ASSERT_NO_THROW(g2.addAnyVariable(start));
+
+  ASSERT_THROW(g1.addAnyVariable(nullTerm), CVC5ApiException);
+  ASSERT_THROW(g1.addAnyVariable(nts), CVC5ApiException);
+
+  d_solver.synthFun("f", {}, boolean, g1);
+
+  ASSERT_THROW(g1.addAnyVariable(start), CVC5ApiException);
+}
+}  // namespace test
+}  // namespace cvc5
diff --git a/test/unit/api/cpp/op_black.cpp b/test/unit/api/cpp/op_black.cpp
new file mode 100644 (file)
index 0000000..fd45b1c
--- /dev/null
@@ -0,0 +1,280 @@
+/******************************************************************************
+ * Top contributors (to current version):
+ *   Makai Mann, Aina Niemetz
+ *
+ * This file is part of the cvc5 project.
+ *
+ * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
+ * in the top-level source directory and their institutional affiliations.
+ * All rights reserved.  See the file COPYING in the top-level source
+ * directory for licensing information.
+ * ****************************************************************************
+ *
+ * Black box testing of the Op class.
+ */
+
+#include "test_api.h"
+
+namespace cvc5 {
+
+using namespace api;
+
+namespace test {
+
+class TestApiBlackOp : public TestApi
+{
+};
+
+TEST_F(TestApiBlackOp, getKind)
+{
+  Op x;
+  x = d_solver.mkOp(BITVECTOR_EXTRACT, 31, 1);
+  ASSERT_NO_THROW(x.getKind());
+}
+
+TEST_F(TestApiBlackOp, isNull)
+{
+  Op x;
+  ASSERT_TRUE(x.isNull());
+  x = d_solver.mkOp(BITVECTOR_EXTRACT, 31, 1);
+  ASSERT_FALSE(x.isNull());
+}
+
+TEST_F(TestApiBlackOp, opFromKind)
+{
+  ASSERT_NO_THROW(d_solver.mkOp(PLUS));
+  ASSERT_THROW(d_solver.mkOp(BITVECTOR_EXTRACT), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackOp, getNumIndices)
+{
+  Op plus = d_solver.mkOp(PLUS);
+  Op divisible = d_solver.mkOp(DIVISIBLE, 4);
+  Op bitvector_repeat = d_solver.mkOp(BITVECTOR_REPEAT, 5);
+  Op bitvector_zero_extend = d_solver.mkOp(BITVECTOR_ZERO_EXTEND, 6);
+  Op bitvector_sign_extend = d_solver.mkOp(BITVECTOR_SIGN_EXTEND, 7);
+  Op bitvector_rotate_left = d_solver.mkOp(BITVECTOR_ROTATE_LEFT, 8);
+  Op bitvector_rotate_right = d_solver.mkOp(BITVECTOR_ROTATE_RIGHT, 9);
+  Op int_to_bitvector = d_solver.mkOp(INT_TO_BITVECTOR, 10);
+  Op iand = d_solver.mkOp(IAND, 3);
+  Op floatingpoint_to_ubv = d_solver.mkOp(FLOATINGPOINT_TO_UBV, 11);
+  Op floatingopint_to_sbv = d_solver.mkOp(FLOATINGPOINT_TO_SBV, 13);
+  Op floatingpoint_to_fp_ieee_bitvector =
+      d_solver.mkOp(FLOATINGPOINT_TO_FP_IEEE_BITVECTOR, 4, 25);
+  Op floatingpoint_to_fp_floatingpoint =
+      d_solver.mkOp(FLOATINGPOINT_TO_FP_FLOATINGPOINT, 4, 25);
+  Op floatingpoint_to_fp_real = d_solver.mkOp(FLOATINGPOINT_TO_FP_REAL, 4, 25);
+  Op floatingpoint_to_fp_signed_bitvector =
+      d_solver.mkOp(FLOATINGPOINT_TO_FP_SIGNED_BITVECTOR, 4, 25);
+  Op floatingpoint_to_fp_unsigned_bitvector =
+      d_solver.mkOp(FLOATINGPOINT_TO_FP_UNSIGNED_BITVECTOR, 4, 25);
+  Op floatingpoint_to_fp_generic =
+      d_solver.mkOp(FLOATINGPOINT_TO_FP_GENERIC, 4, 25);
+  Op regexp_loop = d_solver.mkOp(REGEXP_LOOP, 2, 3);
+
+  ASSERT_EQ(0, plus.getNumIndices());
+  ASSERT_EQ(1, divisible.getNumIndices());
+  ASSERT_EQ(1, bitvector_repeat.getNumIndices());
+  ASSERT_EQ(1, bitvector_zero_extend.getNumIndices());
+  ASSERT_EQ(1, bitvector_sign_extend.getNumIndices());
+  ASSERT_EQ(1, bitvector_rotate_left.getNumIndices());
+  ASSERT_EQ(1, bitvector_rotate_right.getNumIndices());
+  ASSERT_EQ(1, int_to_bitvector.getNumIndices());
+  ASSERT_EQ(1, iand.getNumIndices());
+  ASSERT_EQ(1, floatingpoint_to_ubv.getNumIndices());
+  ASSERT_EQ(1, floatingopint_to_sbv.getNumIndices());
+  ASSERT_EQ(2, floatingpoint_to_fp_ieee_bitvector.getNumIndices());
+  ASSERT_EQ(2, floatingpoint_to_fp_floatingpoint.getNumIndices());
+  ASSERT_EQ(2, floatingpoint_to_fp_real.getNumIndices());
+  ASSERT_EQ(2, floatingpoint_to_fp_signed_bitvector.getNumIndices());
+  ASSERT_EQ(2, floatingpoint_to_fp_unsigned_bitvector.getNumIndices());
+  ASSERT_EQ(2, floatingpoint_to_fp_generic.getNumIndices());
+  ASSERT_EQ(2, regexp_loop.getNumIndices());
+}
+
+TEST_F(TestApiBlackOp, subscriptOperator)
+{
+  Op plus = d_solver.mkOp(PLUS);
+  Op divisible = d_solver.mkOp(DIVISIBLE, 4);
+  Op bitvector_repeat = d_solver.mkOp(BITVECTOR_REPEAT, 4);
+  Op bitvector_zero_extend = d_solver.mkOp(BITVECTOR_ZERO_EXTEND, 4);
+  Op bitvector_sign_extend = d_solver.mkOp(BITVECTOR_SIGN_EXTEND, 4);
+  Op bitvector_rotate_left = d_solver.mkOp(BITVECTOR_ROTATE_LEFT, 4);
+  Op bitvector_rotate_right = d_solver.mkOp(BITVECTOR_ROTATE_RIGHT, 4);
+  Op int_to_bitvector = d_solver.mkOp(INT_TO_BITVECTOR, 4);
+  Op iand = d_solver.mkOp(IAND, 4);
+  Op floatingpoint_to_ubv = d_solver.mkOp(FLOATINGPOINT_TO_UBV, 4);
+  Op floatingopint_to_sbv = d_solver.mkOp(FLOATINGPOINT_TO_SBV, 4);
+  Op floatingpoint_to_fp_ieee_bitvector =
+      d_solver.mkOp(FLOATINGPOINT_TO_FP_IEEE_BITVECTOR, 4, 5);
+  Op floatingpoint_to_fp_floatingpoint =
+      d_solver.mkOp(FLOATINGPOINT_TO_FP_FLOATINGPOINT, 4, 5);
+  Op floatingpoint_to_fp_real = d_solver.mkOp(FLOATINGPOINT_TO_FP_REAL, 4, 5);
+  Op floatingpoint_to_fp_signed_bitvector =
+      d_solver.mkOp(FLOATINGPOINT_TO_FP_SIGNED_BITVECTOR, 4, 5);
+  Op floatingpoint_to_fp_unsigned_bitvector =
+      d_solver.mkOp(FLOATINGPOINT_TO_FP_UNSIGNED_BITVECTOR, 4, 5);
+  Op floatingpoint_to_fp_generic =
+      d_solver.mkOp(FLOATINGPOINT_TO_FP_GENERIC, 4, 5);
+  Op regexp_loop = d_solver.mkOp(REGEXP_LOOP, 4, 5);
+
+  ASSERT_THROW(plus[0], CVC5ApiException);
+  ASSERT_EQ(4, divisible[0].getUInt32Value());
+  ASSERT_EQ(4, bitvector_repeat[0].getUInt32Value());
+  ASSERT_EQ(4, bitvector_zero_extend[0].getUInt32Value());
+  ASSERT_EQ(4, bitvector_sign_extend[0].getUInt32Value());
+  ASSERT_EQ(4, bitvector_rotate_left[0].getUInt32Value());
+  ASSERT_EQ(4, bitvector_rotate_right[0].getUInt32Value());
+  ASSERT_EQ(4, int_to_bitvector[0].getUInt32Value());
+  ASSERT_EQ(4, iand[0].getUInt32Value());
+  ASSERT_EQ(4, floatingpoint_to_ubv[0].getUInt32Value());
+  ASSERT_EQ(4, floatingopint_to_sbv[0].getUInt32Value());
+  ASSERT_EQ(4, floatingpoint_to_fp_ieee_bitvector[0].getUInt32Value());
+  ASSERT_EQ(4, floatingpoint_to_fp_floatingpoint[0].getUInt32Value());
+  ASSERT_EQ(4, floatingpoint_to_fp_real[0].getUInt32Value());
+  ASSERT_EQ(4, floatingpoint_to_fp_signed_bitvector[0].getUInt32Value());
+  ASSERT_EQ(4, floatingpoint_to_fp_unsigned_bitvector[0].getUInt32Value());
+  ASSERT_EQ(4, floatingpoint_to_fp_generic[0].getUInt32Value());
+  ASSERT_EQ(4, regexp_loop[0].getUInt32Value());
+}
+
+TEST_F(TestApiBlackOp, getIndicesString)
+{
+  Op x;
+  ASSERT_THROW(x.getIndices<std::string>(), CVC5ApiException);
+
+  Op divisible_ot = d_solver.mkOp(DIVISIBLE, 4);
+  ASSERT_TRUE(divisible_ot.isIndexed());
+  std::string divisible_idx = divisible_ot.getIndices<std::string>();
+  ASSERT_EQ(divisible_idx, "4");
+}
+
+TEST_F(TestApiBlackOp, getIndicesUint)
+{
+  Op bitvector_repeat_ot = d_solver.mkOp(BITVECTOR_REPEAT, 5);
+  ASSERT_TRUE(bitvector_repeat_ot.isIndexed());
+  uint32_t bitvector_repeat_idx = bitvector_repeat_ot.getIndices<uint32_t>();
+  ASSERT_EQ(bitvector_repeat_idx, 5);
+  ASSERT_THROW(
+      (bitvector_repeat_ot.getIndices<std::pair<uint32_t, uint32_t>>()),
+      CVC5ApiException);
+
+  Op bitvector_zero_extend_ot = d_solver.mkOp(BITVECTOR_ZERO_EXTEND, 6);
+  uint32_t bitvector_zero_extend_idx =
+      bitvector_zero_extend_ot.getIndices<uint32_t>();
+  ASSERT_EQ(bitvector_zero_extend_idx, 6);
+
+  Op bitvector_sign_extend_ot = d_solver.mkOp(BITVECTOR_SIGN_EXTEND, 7);
+  uint32_t bitvector_sign_extend_idx =
+      bitvector_sign_extend_ot.getIndices<uint32_t>();
+  ASSERT_EQ(bitvector_sign_extend_idx, 7);
+
+  Op bitvector_rotate_left_ot = d_solver.mkOp(BITVECTOR_ROTATE_LEFT, 8);
+  uint32_t bitvector_rotate_left_idx =
+      bitvector_rotate_left_ot.getIndices<uint32_t>();
+  ASSERT_EQ(bitvector_rotate_left_idx, 8);
+
+  Op bitvector_rotate_right_ot = d_solver.mkOp(BITVECTOR_ROTATE_RIGHT, 9);
+  uint32_t bitvector_rotate_right_idx =
+      bitvector_rotate_right_ot.getIndices<uint32_t>();
+  ASSERT_EQ(bitvector_rotate_right_idx, 9);
+
+  Op int_to_bitvector_ot = d_solver.mkOp(INT_TO_BITVECTOR, 10);
+  uint32_t int_to_bitvector_idx = int_to_bitvector_ot.getIndices<uint32_t>();
+  ASSERT_EQ(int_to_bitvector_idx, 10);
+
+  Op floatingpoint_to_ubv_ot = d_solver.mkOp(FLOATINGPOINT_TO_UBV, 11);
+  uint32_t floatingpoint_to_ubv_idx =
+      floatingpoint_to_ubv_ot.getIndices<uint32_t>();
+  ASSERT_EQ(floatingpoint_to_ubv_idx, 11);
+
+  Op floatingpoint_to_sbv_ot = d_solver.mkOp(FLOATINGPOINT_TO_SBV, 13);
+  uint32_t floatingpoint_to_sbv_idx =
+      floatingpoint_to_sbv_ot.getIndices<uint32_t>();
+  ASSERT_EQ(floatingpoint_to_sbv_idx, 13);
+}
+
+TEST_F(TestApiBlackOp, getIndicesPairUint)
+{
+  Op bitvector_extract_ot = d_solver.mkOp(BITVECTOR_EXTRACT, 4, 0);
+  ASSERT_TRUE(bitvector_extract_ot.isIndexed());
+  std::pair<uint32_t, uint32_t> bitvector_extract_indices =
+      bitvector_extract_ot.getIndices<std::pair<uint32_t, uint32_t>>();
+  ASSERT_TRUE(
+      (bitvector_extract_indices == std::pair<uint32_t, uint32_t>{4, 0}));
+
+  Op floatingpoint_to_fp_ieee_bitvector_ot =
+      d_solver.mkOp(FLOATINGPOINT_TO_FP_IEEE_BITVECTOR, 4, 25);
+  std::pair<uint32_t, uint32_t> floatingpoint_to_fp_ieee_bitvector_indices =
+      floatingpoint_to_fp_ieee_bitvector_ot
+          .getIndices<std::pair<uint32_t, uint32_t>>();
+  ASSERT_TRUE((floatingpoint_to_fp_ieee_bitvector_indices
+               == std::pair<uint32_t, uint32_t>{4, 25}));
+
+  Op floatingpoint_to_fp_floatingpoint_ot =
+      d_solver.mkOp(FLOATINGPOINT_TO_FP_FLOATINGPOINT, 4, 25);
+  std::pair<uint32_t, uint32_t> floatingpoint_to_fp_floatingpoint_indices =
+      floatingpoint_to_fp_floatingpoint_ot
+          .getIndices<std::pair<uint32_t, uint32_t>>();
+  ASSERT_TRUE((floatingpoint_to_fp_floatingpoint_indices
+               == std::pair<uint32_t, uint32_t>{4, 25}));
+
+  Op floatingpoint_to_fp_real_ot =
+      d_solver.mkOp(FLOATINGPOINT_TO_FP_REAL, 4, 25);
+  std::pair<uint32_t, uint32_t> floatingpoint_to_fp_real_indices =
+      floatingpoint_to_fp_real_ot.getIndices<std::pair<uint32_t, uint32_t>>();
+  ASSERT_TRUE((floatingpoint_to_fp_real_indices
+               == std::pair<uint32_t, uint32_t>{4, 25}));
+
+  Op floatingpoint_to_fp_signed_bitvector_ot =
+      d_solver.mkOp(FLOATINGPOINT_TO_FP_SIGNED_BITVECTOR, 4, 25);
+  std::pair<uint32_t, uint32_t> floatingpoint_to_fp_signed_bitvector_indices =
+      floatingpoint_to_fp_signed_bitvector_ot
+          .getIndices<std::pair<uint32_t, uint32_t>>();
+  ASSERT_TRUE((floatingpoint_to_fp_signed_bitvector_indices
+               == std::pair<uint32_t, uint32_t>{4, 25}));
+
+  Op floatingpoint_to_fp_unsigned_bitvector_ot =
+      d_solver.mkOp(FLOATINGPOINT_TO_FP_UNSIGNED_BITVECTOR, 4, 25);
+  std::pair<uint32_t, uint32_t> floatingpoint_to_fp_unsigned_bitvector_indices =
+      floatingpoint_to_fp_unsigned_bitvector_ot
+          .getIndices<std::pair<uint32_t, uint32_t>>();
+  ASSERT_TRUE((floatingpoint_to_fp_unsigned_bitvector_indices
+               == std::pair<uint32_t, uint32_t>{4, 25}));
+
+  Op floatingpoint_to_fp_generic_ot =
+      d_solver.mkOp(FLOATINGPOINT_TO_FP_GENERIC, 4, 25);
+  std::pair<uint32_t, uint32_t> floatingpoint_to_fp_generic_indices =
+      floatingpoint_to_fp_generic_ot
+          .getIndices<std::pair<uint32_t, uint32_t>>();
+  ASSERT_TRUE((floatingpoint_to_fp_generic_indices
+               == std::pair<uint32_t, uint32_t>{4, 25}));
+  ASSERT_THROW(floatingpoint_to_fp_generic_ot.getIndices<std::string>(),
+               CVC5ApiException);
+}
+
+TEST_F(TestApiBlackOp, getIndicesVector)
+{
+  std::vector<uint32_t> indices = {0, 3, 2, 0, 1, 2};
+  Op tuple_project_op = d_solver.mkOp(TUPLE_PROJECT, indices);
+
+  ASSERT_TRUE(tuple_project_op.isIndexed());
+  std::vector<Term> tuple_project_extract_indices =
+      tuple_project_op.getIndices<std::vector<Term>>();
+  ASSERT_THROW(tuple_project_op.getIndices<std::string>(), CVC5ApiException);
+  for (size_t i = 0; i < indices.size(); i++)
+  {
+    ASSERT_EQ(indices[i], tuple_project_extract_indices[i].getUInt32Value());
+    ASSERT_EQ(indices[i], tuple_project_op[i].getUInt32Value());
+  }
+}
+
+TEST_F(TestApiBlackOp, opScopingToString)
+{
+  Op bitvector_repeat_ot = d_solver.mkOp(BITVECTOR_REPEAT, 5);
+  std::string op_repr = bitvector_repeat_ot.toString();
+  Solver solver2;
+  ASSERT_EQ(bitvector_repeat_ot.toString(), op_repr);
+}
+}  // namespace test
+}  // namespace cvc5
diff --git a/test/unit/api/cpp/op_white.cpp b/test/unit/api/cpp/op_white.cpp
new file mode 100644 (file)
index 0000000..3995273
--- /dev/null
@@ -0,0 +1,36 @@
+/******************************************************************************
+ * Top contributors (to current version):
+ *   Aina Niemetz, Makai Mann
+ *
+ * This file is part of the cvc5 project.
+ *
+ * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
+ * in the top-level source directory and their institutional affiliations.
+ * All rights reserved.  See the file COPYING in the top-level source
+ * directory for licensing information.
+ * ****************************************************************************
+ *
+ * White box testing of the Op class.
+ */
+
+#include "test_api.h"
+
+namespace cvc5 {
+
+using namespace api;
+
+namespace test {
+
+class TestApiWhiteOp : public TestApi
+{
+};
+
+TEST_F(TestApiWhiteOp, opFromKind)
+{
+  Op plus(&d_solver, PLUS);
+  ASSERT_FALSE(plus.isIndexed());
+  ASSERT_THROW(plus.getIndices<uint32_t>(), CVC5ApiException);
+  ASSERT_EQ(plus, d_solver.mkOp(PLUS));
+}
+}  // namespace test
+}  // namespace cvc5
diff --git a/test/unit/api/cpp/result_black.cpp b/test/unit/api/cpp/result_black.cpp
new file mode 100644 (file)
index 0000000..9bf6b84
--- /dev/null
@@ -0,0 +1,122 @@
+/******************************************************************************
+ * Top contributors (to current version):
+ *   Aina Niemetz
+ *
+ * This file is part of the cvc5 project.
+ *
+ * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
+ * in the top-level source directory and their institutional affiliations.
+ * All rights reserved.  See the file COPYING in the top-level source
+ * directory for licensing information.
+ * ****************************************************************************
+ *
+ * Black box testing of the Result class
+ */
+
+#include "test_api.h"
+
+namespace cvc5 {
+
+using namespace api;
+
+namespace test {
+
+class TestApiBlackResult : public TestApi
+{
+};
+
+TEST_F(TestApiBlackResult, isNull)
+{
+  cvc5::api::Result res_null;
+  ASSERT_TRUE(res_null.isNull());
+  ASSERT_FALSE(res_null.isSat());
+  ASSERT_FALSE(res_null.isUnsat());
+  ASSERT_FALSE(res_null.isSatUnknown());
+  ASSERT_FALSE(res_null.isEntailed());
+  ASSERT_FALSE(res_null.isNotEntailed());
+  ASSERT_FALSE(res_null.isEntailmentUnknown());
+  Sort u_sort = d_solver.mkUninterpretedSort("u");
+  Term x = d_solver.mkVar(u_sort, "x");
+  d_solver.assertFormula(x.eqTerm(x));
+  cvc5::api::Result res = d_solver.checkSat();
+  ASSERT_FALSE(res.isNull());
+}
+
+TEST_F(TestApiBlackResult, eq)
+{
+  Sort u_sort = d_solver.mkUninterpretedSort("u");
+  Term x = d_solver.mkVar(u_sort, "x");
+  d_solver.assertFormula(x.eqTerm(x));
+  cvc5::api::Result res;
+  cvc5::api::Result res2 = d_solver.checkSat();
+  cvc5::api::Result res3 = d_solver.checkSat();
+  res = res2;
+  ASSERT_EQ(res, res2);
+  ASSERT_EQ(res3, res2);
+}
+
+TEST_F(TestApiBlackResult, isSat)
+{
+  Sort u_sort = d_solver.mkUninterpretedSort("u");
+  Term x = d_solver.mkVar(u_sort, "x");
+  d_solver.assertFormula(x.eqTerm(x));
+  cvc5::api::Result res = d_solver.checkSat();
+  ASSERT_TRUE(res.isSat());
+  ASSERT_FALSE(res.isSatUnknown());
+}
+
+TEST_F(TestApiBlackResult, isUnsat)
+{
+  Sort u_sort = d_solver.mkUninterpretedSort("u");
+  Term x = d_solver.mkVar(u_sort, "x");
+  d_solver.assertFormula(x.eqTerm(x).notTerm());
+  cvc5::api::Result res = d_solver.checkSat();
+  ASSERT_TRUE(res.isUnsat());
+  ASSERT_FALSE(res.isSatUnknown());
+}
+
+TEST_F(TestApiBlackResult, isSatUnknown)
+{
+  d_solver.setLogic("QF_NIA");
+  d_solver.setOption("incremental", "false");
+  d_solver.setOption("solve-int-as-bv", "32");
+  Sort int_sort = d_solver.getIntegerSort();
+  Term x = d_solver.mkVar(int_sort, "x");
+  d_solver.assertFormula(x.eqTerm(x).notTerm());
+  cvc5::api::Result res = d_solver.checkSat();
+  ASSERT_FALSE(res.isSat());
+  ASSERT_TRUE(res.isSatUnknown());
+}
+
+TEST_F(TestApiBlackResult, isEntailed)
+{
+  d_solver.setOption("incremental", "true");
+  Sort u_sort = d_solver.mkUninterpretedSort("u");
+  Term x = d_solver.mkConst(u_sort, "x");
+  Term y = d_solver.mkConst(u_sort, "y");
+  Term a = x.eqTerm(y).notTerm();
+  Term b = x.eqTerm(y);
+  d_solver.assertFormula(a);
+  cvc5::api::Result entailed = d_solver.checkEntailed(a);
+  ASSERT_TRUE(entailed.isEntailed());
+  ASSERT_FALSE(entailed.isEntailmentUnknown());
+  cvc5::api::Result not_entailed = d_solver.checkEntailed(b);
+  ASSERT_TRUE(not_entailed.isNotEntailed());
+  ASSERT_FALSE(not_entailed.isEntailmentUnknown());
+}
+
+TEST_F(TestApiBlackResult, isEntailmentUnknown)
+{
+  d_solver.setLogic("QF_NIA");
+  d_solver.setOption("incremental", "false");
+  d_solver.setOption("solve-int-as-bv", "32");
+  Sort int_sort = d_solver.getIntegerSort();
+  Term x = d_solver.mkVar(int_sort, "x");
+  d_solver.assertFormula(x.eqTerm(x).notTerm());
+  cvc5::api::Result res = d_solver.checkEntailed(x.eqTerm(x));
+  ASSERT_FALSE(res.isEntailed());
+  ASSERT_TRUE(res.isEntailmentUnknown());
+  ASSERT_EQ(res.getUnknownExplanation(), api::Result::UNKNOWN_REASON);
+}
+}  // namespace test
+}  // namespace cvc5
diff --git a/test/unit/api/cpp/solver_black.cpp b/test/unit/api/cpp/solver_black.cpp
new file mode 100644 (file)
index 0000000..37aed63
--- /dev/null
@@ -0,0 +1,2578 @@
+/******************************************************************************
+ * Top contributors (to current version):
+ *   Aina Niemetz, Mudathir Mohamed, Andrew Reynolds
+ *
+ * This file is part of the cvc5 project.
+ *
+ * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
+ * in the top-level source directory and their institutional affiliations.
+ * All rights reserved.  See the file COPYING in the top-level source
+ * directory for licensing information.
+ * ****************************************************************************
+ *
+ * Black box testing of the Solver class of the  C++ API.
+ */
+
+#include <algorithm>
+
+#include "base/output.h"
+#include "test_api.h"
+
+namespace cvc5 {
+
+using namespace api;
+
+namespace test {
+
+class TestApiBlackSolver : public TestApi
+{
+};
+
+TEST_F(TestApiBlackSolver, recoverableException)
+{
+  d_solver.setOption("produce-models", "true");
+  Term x = d_solver.mkConst(d_solver.getBooleanSort(), "x");
+  d_solver.assertFormula(x.eqTerm(x).notTerm());
+  ASSERT_THROW(d_solver.getValue(x), CVC5ApiRecoverableException);
+}
+
+TEST_F(TestApiBlackSolver, supportsFloatingPoint)
+{
+  ASSERT_NO_THROW(d_solver.mkRoundingMode(ROUND_NEAREST_TIES_TO_EVEN));
+}
+
+TEST_F(TestApiBlackSolver, getBooleanSort)
+{
+  ASSERT_NO_THROW(d_solver.getBooleanSort());
+}
+
+TEST_F(TestApiBlackSolver, getIntegerSort)
+{
+  ASSERT_NO_THROW(d_solver.getIntegerSort());
+}
+
+TEST_F(TestApiBlackSolver, getNullSort)
+{
+  ASSERT_NO_THROW(d_solver.getNullSort());
+}
+
+TEST_F(TestApiBlackSolver, getRealSort)
+{
+  ASSERT_NO_THROW(d_solver.getRealSort());
+}
+
+TEST_F(TestApiBlackSolver, getRegExpSort)
+{
+  ASSERT_NO_THROW(d_solver.getRegExpSort());
+}
+
+TEST_F(TestApiBlackSolver, getStringSort)
+{
+  ASSERT_NO_THROW(d_solver.getStringSort());
+}
+
+TEST_F(TestApiBlackSolver, getRoundingModeSort)
+{
+  ASSERT_NO_THROW(d_solver.getRoundingModeSort());
+}
+
+TEST_F(TestApiBlackSolver, mkArraySort)
+{
+  Sort boolSort = d_solver.getBooleanSort();
+  Sort intSort = d_solver.getIntegerSort();
+  Sort realSort = d_solver.getRealSort();
+  Sort bvSort = d_solver.mkBitVectorSort(32);
+  ASSERT_NO_THROW(d_solver.mkArraySort(boolSort, boolSort));
+  ASSERT_NO_THROW(d_solver.mkArraySort(intSort, intSort));
+  ASSERT_NO_THROW(d_solver.mkArraySort(realSort, realSort));
+  ASSERT_NO_THROW(d_solver.mkArraySort(bvSort, bvSort));
+  ASSERT_NO_THROW(d_solver.mkArraySort(boolSort, intSort));
+  ASSERT_NO_THROW(d_solver.mkArraySort(realSort, bvSort));
+
+  Sort fpSort = d_solver.mkFloatingPointSort(3, 5);
+  ASSERT_NO_THROW(d_solver.mkArraySort(fpSort, fpSort));
+  ASSERT_NO_THROW(d_solver.mkArraySort(bvSort, fpSort));
+
+  Solver slv;
+  ASSERT_THROW(slv.mkArraySort(boolSort, boolSort), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, mkBitVectorSort)
+{
+  ASSERT_NO_THROW(d_solver.mkBitVectorSort(32));
+  ASSERT_THROW(d_solver.mkBitVectorSort(0), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, mkFloatingPointSort)
+{
+  ASSERT_NO_THROW(d_solver.mkFloatingPointSort(4, 8));
+  ASSERT_THROW(d_solver.mkFloatingPointSort(0, 8), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkFloatingPointSort(4, 0), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, mkDatatypeSort)
+{
+  DatatypeDecl dtypeSpec = d_solver.mkDatatypeDecl("list");
+  DatatypeConstructorDecl cons = d_solver.mkDatatypeConstructorDecl("cons");
+  cons.addSelector("head", d_solver.getIntegerSort());
+  dtypeSpec.addConstructor(cons);
+  DatatypeConstructorDecl nil = d_solver.mkDatatypeConstructorDecl("nil");
+  dtypeSpec.addConstructor(nil);
+  ASSERT_NO_THROW(d_solver.mkDatatypeSort(dtypeSpec));
+
+  Solver slv;
+  ASSERT_THROW(slv.mkDatatypeSort(dtypeSpec), CVC5ApiException);
+
+  DatatypeDecl throwsDtypeSpec = d_solver.mkDatatypeDecl("list");
+  ASSERT_THROW(d_solver.mkDatatypeSort(throwsDtypeSpec), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, mkDatatypeSorts)
+{
+  Solver slv;
+
+  DatatypeDecl dtypeSpec1 = d_solver.mkDatatypeDecl("list1");
+  DatatypeConstructorDecl cons1 = d_solver.mkDatatypeConstructorDecl("cons1");
+  cons1.addSelector("head1", d_solver.getIntegerSort());
+  dtypeSpec1.addConstructor(cons1);
+  DatatypeConstructorDecl nil1 = d_solver.mkDatatypeConstructorDecl("nil1");
+  dtypeSpec1.addConstructor(nil1);
+  DatatypeDecl dtypeSpec2 = d_solver.mkDatatypeDecl("list2");
+  DatatypeConstructorDecl cons2 = d_solver.mkDatatypeConstructorDecl("cons2");
+  cons2.addSelector("head2", d_solver.getIntegerSort());
+  dtypeSpec2.addConstructor(cons2);
+  DatatypeConstructorDecl nil2 = d_solver.mkDatatypeConstructorDecl("nil2");
+  dtypeSpec2.addConstructor(nil2);
+  std::vector<DatatypeDecl> decls = {dtypeSpec1, dtypeSpec2};
+  ASSERT_NO_THROW(d_solver.mkDatatypeSorts(decls));
+
+  ASSERT_THROW(slv.mkDatatypeSorts(decls), CVC5ApiException);
+
+  DatatypeDecl throwsDtypeSpec = d_solver.mkDatatypeDecl("list");
+  std::vector<DatatypeDecl> throwsDecls = {throwsDtypeSpec};
+  ASSERT_THROW(d_solver.mkDatatypeSorts(throwsDecls), CVC5ApiException);
+
+  /* with unresolved sorts */
+  Sort unresList = d_solver.mkUninterpretedSort("ulist");
+  std::set<Sort> unresSorts = {unresList};
+  DatatypeDecl ulist = d_solver.mkDatatypeDecl("ulist");
+  DatatypeConstructorDecl ucons = d_solver.mkDatatypeConstructorDecl("ucons");
+  ucons.addSelector("car", unresList);
+  ucons.addSelector("cdr", unresList);
+  ulist.addConstructor(ucons);
+  DatatypeConstructorDecl unil = d_solver.mkDatatypeConstructorDecl("unil");
+  ulist.addConstructor(unil);
+  std::vector<DatatypeDecl> udecls = {ulist};
+  ASSERT_NO_THROW(d_solver.mkDatatypeSorts(udecls, unresSorts));
+
+  ASSERT_THROW(slv.mkDatatypeSorts(udecls, unresSorts), CVC5ApiException);
+
+  /* Note: More tests are in datatype_api_black. */
+}
+
+TEST_F(TestApiBlackSolver, mkFunctionSort)
+{
+  ASSERT_NO_THROW(d_solver.mkFunctionSort(d_solver.mkUninterpretedSort("u"),
+                                          d_solver.getIntegerSort()));
+  Sort funSort = d_solver.mkFunctionSort(d_solver.mkUninterpretedSort("u"),
+                                         d_solver.getIntegerSort());
+  // function arguments are allowed
+  ASSERT_NO_THROW(d_solver.mkFunctionSort(funSort, d_solver.getIntegerSort()));
+  // non-first-class arguments are not allowed
+  Sort reSort = d_solver.getRegExpSort();
+  ASSERT_THROW(d_solver.mkFunctionSort(reSort, d_solver.getIntegerSort()),
+               CVC5ApiException);
+  ASSERT_THROW(d_solver.mkFunctionSort(d_solver.getIntegerSort(), funSort),
+               CVC5ApiException);
+  ASSERT_NO_THROW(d_solver.mkFunctionSort(
+      {d_solver.mkUninterpretedSort("u"), d_solver.getIntegerSort()},
+      d_solver.getIntegerSort()));
+  Sort funSort2 = d_solver.mkFunctionSort(d_solver.mkUninterpretedSort("u"),
+                                          d_solver.getIntegerSort());
+  // function arguments are allowed
+  ASSERT_NO_THROW(
+      d_solver.mkFunctionSort({funSort2, d_solver.mkUninterpretedSort("u")},
+                              d_solver.getIntegerSort()));
+  ASSERT_THROW(d_solver.mkFunctionSort({d_solver.getIntegerSort(),
+                                        d_solver.mkUninterpretedSort("u")},
+                                       funSort2),
+               CVC5ApiException);
+
+  Solver slv;
+  ASSERT_THROW(slv.mkFunctionSort(d_solver.mkUninterpretedSort("u"),
+                                  d_solver.getIntegerSort()),
+               CVC5ApiException);
+  ASSERT_THROW(slv.mkFunctionSort(slv.mkUninterpretedSort("u"),
+                                  d_solver.getIntegerSort()),
+               CVC5ApiException);
+  std::vector<Sort> sorts1 = {d_solver.getBooleanSort(),
+                              slv.getIntegerSort(),
+                              d_solver.getIntegerSort()};
+  std::vector<Sort> sorts2 = {slv.getBooleanSort(), slv.getIntegerSort()};
+  ASSERT_NO_THROW(slv.mkFunctionSort(sorts2, slv.getIntegerSort()));
+  ASSERT_THROW(slv.mkFunctionSort(sorts1, slv.getIntegerSort()),
+               CVC5ApiException);
+  ASSERT_THROW(slv.mkFunctionSort(sorts2, d_solver.getIntegerSort()),
+               CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, mkParamSort)
+{
+  ASSERT_NO_THROW(d_solver.mkParamSort("T"));
+  ASSERT_NO_THROW(d_solver.mkParamSort(""));
+}
+
+TEST_F(TestApiBlackSolver, mkPredicateSort)
+{
+  ASSERT_NO_THROW(d_solver.mkPredicateSort({d_solver.getIntegerSort()}));
+  ASSERT_THROW(d_solver.mkPredicateSort({}), CVC5ApiException);
+  Sort funSort = d_solver.mkFunctionSort(d_solver.mkUninterpretedSort("u"),
+                                         d_solver.getIntegerSort());
+  // functions as arguments are allowed
+  ASSERT_NO_THROW(
+      d_solver.mkPredicateSort({d_solver.getIntegerSort(), funSort}));
+
+  Solver slv;
+  ASSERT_THROW(slv.mkPredicateSort({d_solver.getIntegerSort()}),
+               CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, mkRecordSort)
+{
+  std::vector<std::pair<std::string, Sort>> fields = {
+      std::make_pair("b", d_solver.getBooleanSort()),
+      std::make_pair("bv", d_solver.mkBitVectorSort(8)),
+      std::make_pair("i", d_solver.getIntegerSort())};
+  std::vector<std::pair<std::string, Sort>> empty;
+  ASSERT_NO_THROW(d_solver.mkRecordSort(fields));
+  ASSERT_NO_THROW(d_solver.mkRecordSort(empty));
+  Sort recSort = d_solver.mkRecordSort(fields);
+  ASSERT_NO_THROW(recSort.getDatatype());
+
+  Solver slv;
+  ASSERT_THROW(slv.mkRecordSort(fields), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, mkSetSort)
+{
+  ASSERT_NO_THROW(d_solver.mkSetSort(d_solver.getBooleanSort()));
+  ASSERT_NO_THROW(d_solver.mkSetSort(d_solver.getIntegerSort()));
+  ASSERT_NO_THROW(d_solver.mkSetSort(d_solver.mkBitVectorSort(4)));
+  Solver slv;
+  ASSERT_THROW(slv.mkSetSort(d_solver.mkBitVectorSort(4)), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, mkBagSort)
+{
+  ASSERT_NO_THROW(d_solver.mkBagSort(d_solver.getBooleanSort()));
+  ASSERT_NO_THROW(d_solver.mkBagSort(d_solver.getIntegerSort()));
+  ASSERT_NO_THROW(d_solver.mkBagSort(d_solver.mkBitVectorSort(4)));
+  Solver slv;
+  ASSERT_THROW(slv.mkBagSort(d_solver.mkBitVectorSort(4)), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, mkSequenceSort)
+{
+  ASSERT_NO_THROW(d_solver.mkSequenceSort(d_solver.getBooleanSort()));
+  ASSERT_NO_THROW(d_solver.mkSequenceSort(
+      d_solver.mkSequenceSort(d_solver.getIntegerSort())));
+  Solver slv;
+  ASSERT_THROW(slv.mkSequenceSort(d_solver.getIntegerSort()), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, mkUninterpretedSort)
+{
+  ASSERT_NO_THROW(d_solver.mkUninterpretedSort("u"));
+  ASSERT_NO_THROW(d_solver.mkUninterpretedSort(""));
+}
+
+TEST_F(TestApiBlackSolver, mkSortConstructorSort)
+{
+  ASSERT_NO_THROW(d_solver.mkSortConstructorSort("s", 2));
+  ASSERT_NO_THROW(d_solver.mkSortConstructorSort("", 2));
+  ASSERT_THROW(d_solver.mkSortConstructorSort("", 0), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, mkTupleSort)
+{
+  ASSERT_NO_THROW(d_solver.mkTupleSort({d_solver.getIntegerSort()}));
+  Sort funSort = d_solver.mkFunctionSort(d_solver.mkUninterpretedSort("u"),
+                                         d_solver.getIntegerSort());
+  ASSERT_THROW(d_solver.mkTupleSort({d_solver.getIntegerSort(), funSort}),
+               CVC5ApiException);
+
+  Solver slv;
+  ASSERT_THROW(slv.mkTupleSort({d_solver.getIntegerSort()}), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, mkBitVector)
+{
+  ASSERT_NO_THROW(d_solver.mkBitVector(8, 2));
+  ASSERT_NO_THROW(d_solver.mkBitVector(32, 2));
+  ASSERT_NO_THROW(d_solver.mkBitVector(8, "-1111111", 2));
+  ASSERT_NO_THROW(d_solver.mkBitVector(8, "0101", 2));
+  ASSERT_NO_THROW(d_solver.mkBitVector(8, "00000101", 2));
+  ASSERT_NO_THROW(d_solver.mkBitVector(8, "-127", 10));
+  ASSERT_NO_THROW(d_solver.mkBitVector(8, "255", 10));
+  ASSERT_NO_THROW(d_solver.mkBitVector(8, "-7f", 16));
+  ASSERT_NO_THROW(d_solver.mkBitVector(8, "a0", 16));
+
+  ASSERT_THROW(d_solver.mkBitVector(0, 2), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkBitVector(0, "-127", 10), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkBitVector(0, "a0", 16), CVC5ApiException);
+
+  ASSERT_THROW(d_solver.mkBitVector(8, "", 2), CVC5ApiException);
+
+  ASSERT_THROW(d_solver.mkBitVector(8, "101", 5), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkBitVector(8, "128", 11), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkBitVector(8, "a0", 21), CVC5ApiException);
+
+  ASSERT_THROW(d_solver.mkBitVector(8, "-11111111", 2), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkBitVector(8, "101010101", 2), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkBitVector(8, "-256", 10), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkBitVector(8, "257", 10), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkBitVector(8, "-a0", 16), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkBitVector(8, "fffff", 16), CVC5ApiException);
+
+  ASSERT_THROW(d_solver.mkBitVector(8, "10201010", 2), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkBitVector(8, "-25x", 10), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkBitVector(8, "2x7", 10), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkBitVector(8, "fzff", 16), CVC5ApiException);
+
+  ASSERT_EQ(d_solver.mkBitVector(8, "0101", 2),
+            d_solver.mkBitVector(8, "00000101", 2));
+  ASSERT_EQ(d_solver.mkBitVector(4, "-1", 2),
+            d_solver.mkBitVector(4, "1111", 2));
+  ASSERT_EQ(d_solver.mkBitVector(4, "-1", 16),
+            d_solver.mkBitVector(4, "1111", 2));
+  ASSERT_EQ(d_solver.mkBitVector(4, "-1", 10),
+            d_solver.mkBitVector(4, "1111", 2));
+  ASSERT_EQ(d_solver.mkBitVector(8, "01010101", 2).toString(), "#b01010101");
+  ASSERT_EQ(d_solver.mkBitVector(8, "F", 16).toString(), "#b00001111");
+  ASSERT_EQ(d_solver.mkBitVector(8, "-1", 10),
+            d_solver.mkBitVector(8, "FF", 16));
+}
+
+TEST_F(TestApiBlackSolver, mkVar)
+{
+  Sort boolSort = d_solver.getBooleanSort();
+  Sort intSort = d_solver.getIntegerSort();
+  Sort funSort = d_solver.mkFunctionSort(intSort, boolSort);
+  ASSERT_NO_THROW(d_solver.mkVar(boolSort));
+  ASSERT_NO_THROW(d_solver.mkVar(funSort));
+  ASSERT_NO_THROW(d_solver.mkVar(boolSort, std::string("b")));
+  ASSERT_NO_THROW(d_solver.mkVar(funSort, ""));
+  ASSERT_THROW(d_solver.mkVar(Sort()), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkVar(Sort(), "a"), CVC5ApiException);
+  Solver slv;
+  ASSERT_THROW(slv.mkVar(boolSort, "x"), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, mkBoolean)
+{
+  ASSERT_NO_THROW(d_solver.mkBoolean(true));
+  ASSERT_NO_THROW(d_solver.mkBoolean(false));
+}
+
+TEST_F(TestApiBlackSolver, mkRoundingMode)
+{
+  ASSERT_NO_THROW(d_solver.mkRoundingMode(RoundingMode::ROUND_TOWARD_ZERO));
+}
+
+TEST_F(TestApiBlackSolver, mkAbstractValue)
+{
+  ASSERT_NO_THROW(d_solver.mkAbstractValue(std::string("1")));
+  ASSERT_THROW(d_solver.mkAbstractValue(std::string("0")), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkAbstractValue(std::string("-1")), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkAbstractValue(std::string("1.2")), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkAbstractValue("1/2"), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkAbstractValue("asdf"), CVC5ApiException);
+
+  ASSERT_NO_THROW(d_solver.mkAbstractValue((uint32_t)1));
+  ASSERT_NO_THROW(d_solver.mkAbstractValue((int32_t)1));
+  ASSERT_NO_THROW(d_solver.mkAbstractValue((uint64_t)1));
+  ASSERT_NO_THROW(d_solver.mkAbstractValue((int64_t)1));
+  ASSERT_NO_THROW(d_solver.mkAbstractValue((int32_t)-1));
+  ASSERT_NO_THROW(d_solver.mkAbstractValue((int64_t)-1));
+  ASSERT_THROW(d_solver.mkAbstractValue(0), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, mkFloatingPoint)
+{
+  Term t1 = d_solver.mkBitVector(8);
+  Term t2 = d_solver.mkBitVector(4);
+  Term t3 = d_solver.mkInteger(2);
+  ASSERT_NO_THROW(d_solver.mkFloatingPoint(3, 5, t1));
+  ASSERT_THROW(d_solver.mkFloatingPoint(0, 5, Term()), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkFloatingPoint(0, 5, t1), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkFloatingPoint(3, 0, t1), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkFloatingPoint(3, 5, t2), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkFloatingPoint(3, 5, t2), CVC5ApiException);
+
+  Solver slv;
+  ASSERT_THROW(slv.mkFloatingPoint(3, 5, t1), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, mkCardinalityConstraint)
+{
+  Sort su = d_solver.mkUninterpretedSort("u");
+  Sort si = d_solver.getIntegerSort();
+  ASSERT_NO_THROW(d_solver.mkCardinalityConstraint(su, 3));
+  ASSERT_THROW(d_solver.mkCardinalityConstraint(si, 3), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkCardinalityConstraint(su, 0), CVC5ApiException);
+  Solver slv;
+  ASSERT_THROW(slv.mkCardinalityConstraint(su, 3), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, mkEmptySet)
+{
+  Solver slv;
+  Sort s = d_solver.mkSetSort(d_solver.getBooleanSort());
+  ASSERT_NO_THROW(d_solver.mkEmptySet(Sort()));
+  ASSERT_NO_THROW(d_solver.mkEmptySet(s));
+  ASSERT_THROW(d_solver.mkEmptySet(d_solver.getBooleanSort()),
+               CVC5ApiException);
+  ASSERT_THROW(slv.mkEmptySet(s), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, mkEmptyBag)
+{
+  Solver slv;
+  Sort s = d_solver.mkBagSort(d_solver.getBooleanSort());
+  ASSERT_NO_THROW(d_solver.mkEmptyBag(Sort()));
+  ASSERT_NO_THROW(d_solver.mkEmptyBag(s));
+  ASSERT_THROW(d_solver.mkEmptyBag(d_solver.getBooleanSort()),
+               CVC5ApiException);
+  ASSERT_THROW(slv.mkEmptyBag(s), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, mkEmptySequence)
+{
+  Solver slv;
+  Sort s = d_solver.mkSequenceSort(d_solver.getBooleanSort());
+  ASSERT_NO_THROW(d_solver.mkEmptySequence(s));
+  ASSERT_NO_THROW(d_solver.mkEmptySequence(d_solver.getBooleanSort()));
+  ASSERT_THROW(slv.mkEmptySequence(s), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, mkFalse)
+{
+  ASSERT_NO_THROW(d_solver.mkFalse());
+  ASSERT_NO_THROW(d_solver.mkFalse());
+}
+
+TEST_F(TestApiBlackSolver, mkNaN) { ASSERT_NO_THROW(d_solver.mkNaN(3, 5)); }
+
+TEST_F(TestApiBlackSolver, mkNegZero)
+{
+  ASSERT_NO_THROW(d_solver.mkNegZero(3, 5));
+}
+
+TEST_F(TestApiBlackSolver, mkNegInf)
+{
+  ASSERT_NO_THROW(d_solver.mkNegInf(3, 5));
+}
+
+TEST_F(TestApiBlackSolver, mkPosInf)
+{
+  ASSERT_NO_THROW(d_solver.mkPosInf(3, 5));
+}
+
+TEST_F(TestApiBlackSolver, mkPosZero)
+{
+  ASSERT_NO_THROW(d_solver.mkPosZero(3, 5));
+}
+
+TEST_F(TestApiBlackSolver, mkOp)
+{
+  // mkOp(Kind kind, Kind k)
+  ASSERT_THROW(d_solver.mkOp(BITVECTOR_EXTRACT, EQUAL), CVC5ApiException);
+
+  // mkOp(Kind kind, const std::string& arg)
+  ASSERT_NO_THROW(d_solver.mkOp(DIVISIBLE, "2147483648"));
+  ASSERT_THROW(d_solver.mkOp(BITVECTOR_EXTRACT, "asdf"), CVC5ApiException);
+
+  // mkOp(Kind kind, uint32_t arg)
+  ASSERT_NO_THROW(d_solver.mkOp(DIVISIBLE, 1));
+  ASSERT_NO_THROW(d_solver.mkOp(BITVECTOR_ROTATE_LEFT, 1));
+  ASSERT_NO_THROW(d_solver.mkOp(BITVECTOR_ROTATE_RIGHT, 1));
+  ASSERT_THROW(d_solver.mkOp(BITVECTOR_EXTRACT, 1), CVC5ApiException);
+
+  // mkOp(Kind kind, uint32_t arg1, uint32_t arg2)
+  ASSERT_NO_THROW(d_solver.mkOp(BITVECTOR_EXTRACT, 1, 1));
+  ASSERT_THROW(d_solver.mkOp(DIVISIBLE, 1, 2), CVC5ApiException);
+
+  // mkOp(Kind kind, std::vector<uint32_t> args)
+  std::vector<uint32_t> args = {1, 2, 2};
+  ASSERT_NO_THROW(d_solver.mkOp(TUPLE_PROJECT, args));
+}
+
+TEST_F(TestApiBlackSolver, mkPi) { ASSERT_NO_THROW(d_solver.mkPi()); }
+
+TEST_F(TestApiBlackSolver, mkInteger)
+{
+  ASSERT_NO_THROW(d_solver.mkInteger("123"));
+  ASSERT_THROW(d_solver.mkInteger("1.23"), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkInteger("1/23"), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkInteger("12/3"), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkInteger(".2"), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkInteger("2."), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkInteger(""), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkInteger("asdf"), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkInteger("1.2/3"), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkInteger("."), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkInteger("/"), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkInteger("2/"), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkInteger("/2"), CVC5ApiException);
+
+  ASSERT_NO_THROW(d_solver.mkReal(std::string("123")));
+  ASSERT_THROW(d_solver.mkInteger(std::string("1.23")), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkInteger(std::string("1/23")), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkInteger(std::string("12/3")), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkInteger(std::string(".2")), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkInteger(std::string("2.")), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkInteger(std::string("")), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkInteger(std::string("asdf")), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkInteger(std::string("1.2/3")), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkInteger(std::string(".")), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkInteger(std::string("/")), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkInteger(std::string("2/")), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkInteger(std::string("/2")), CVC5ApiException);
+
+  int32_t val1 = 1;
+  int64_t val2 = -1;
+  uint32_t val3 = 1;
+  uint64_t val4 = -1;
+  ASSERT_NO_THROW(d_solver.mkInteger(val1));
+  ASSERT_NO_THROW(d_solver.mkInteger(val2));
+  ASSERT_NO_THROW(d_solver.mkInteger(val3));
+  ASSERT_NO_THROW(d_solver.mkInteger(val4));
+  ASSERT_NO_THROW(d_solver.mkInteger(val4));
+}
+
+TEST_F(TestApiBlackSolver, mkReal)
+{
+  ASSERT_NO_THROW(d_solver.mkReal("123"));
+  ASSERT_NO_THROW(d_solver.mkReal("1.23"));
+  ASSERT_NO_THROW(d_solver.mkReal("1/23"));
+  ASSERT_NO_THROW(d_solver.mkReal("12/3"));
+  ASSERT_NO_THROW(d_solver.mkReal(".2"));
+  ASSERT_NO_THROW(d_solver.mkReal("2."));
+  ASSERT_THROW(d_solver.mkReal(""), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkReal("asdf"), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkReal("1.2/3"), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkReal("."), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkReal("/"), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkReal("2/"), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkReal("/2"), CVC5ApiException);
+
+  ASSERT_NO_THROW(d_solver.mkReal(std::string("123")));
+  ASSERT_NO_THROW(d_solver.mkReal(std::string("1.23")));
+  ASSERT_NO_THROW(d_solver.mkReal(std::string("1/23")));
+  ASSERT_NO_THROW(d_solver.mkReal(std::string("12/3")));
+  ASSERT_NO_THROW(d_solver.mkReal(std::string(".2")));
+  ASSERT_NO_THROW(d_solver.mkReal(std::string("2.")));
+  ASSERT_THROW(d_solver.mkReal(std::string("")), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkReal(std::string("asdf")), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkReal(std::string("1.2/3")), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkReal(std::string(".")), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkReal(std::string("/")), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkReal(std::string("2/")), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkReal(std::string("/2")), CVC5ApiException);
+
+  int32_t val1 = 1;
+  int64_t val2 = -1;
+  uint32_t val3 = 1;
+  uint64_t val4 = -1;
+  ASSERT_NO_THROW(d_solver.mkReal(val1));
+  ASSERT_NO_THROW(d_solver.mkReal(val2));
+  ASSERT_NO_THROW(d_solver.mkReal(val3));
+  ASSERT_NO_THROW(d_solver.mkReal(val4));
+  ASSERT_NO_THROW(d_solver.mkReal(val4));
+  ASSERT_NO_THROW(d_solver.mkReal(val1, val1));
+  ASSERT_NO_THROW(d_solver.mkReal(val2, val2));
+  ASSERT_NO_THROW(d_solver.mkReal(val3, val3));
+  ASSERT_NO_THROW(d_solver.mkReal(val4, val4));
+}
+
+TEST_F(TestApiBlackSolver, mkRegexpNone)
+{
+  Sort strSort = d_solver.getStringSort();
+  Term s = d_solver.mkConst(strSort, "s");
+  ASSERT_NO_THROW(
+      d_solver.mkTerm(STRING_IN_REGEXP, s, d_solver.mkRegexpNone()));
+}
+
+TEST_F(TestApiBlackSolver, mkRegexpAllchar)
+{
+  Sort strSort = d_solver.getStringSort();
+  Term s = d_solver.mkConst(strSort, "s");
+  ASSERT_NO_THROW(
+      d_solver.mkTerm(STRING_IN_REGEXP, s, d_solver.mkRegexpAllchar()));
+}
+
+TEST_F(TestApiBlackSolver, mkSepEmp) { ASSERT_NO_THROW(d_solver.mkSepEmp()); }
+
+TEST_F(TestApiBlackSolver, mkSepNil)
+{
+  ASSERT_NO_THROW(d_solver.mkSepNil(d_solver.getBooleanSort()));
+  ASSERT_THROW(d_solver.mkSepNil(Sort()), CVC5ApiException);
+  Solver slv;
+  ASSERT_THROW(slv.mkSepNil(d_solver.getIntegerSort()), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, mkString)
+{
+  ASSERT_NO_THROW(d_solver.mkString(""));
+  ASSERT_NO_THROW(d_solver.mkString("asdfasdf"));
+  ASSERT_EQ(d_solver.mkString("asdf\\nasdf").toString(),
+            "\"asdf\\u{5c}nasdf\"");
+  ASSERT_EQ(d_solver.mkString("asdf\\u{005c}nasdf", true).toString(),
+            "\"asdf\\u{5c}nasdf\"");
+}
+
+TEST_F(TestApiBlackSolver, mkTerm)
+{
+  Sort bv32 = d_solver.mkBitVectorSort(32);
+  Term a = d_solver.mkConst(bv32, "a");
+  Term b = d_solver.mkConst(bv32, "b");
+  std::vector<Term> v1 = {a, b};
+  std::vector<Term> v2 = {a, Term()};
+  std::vector<Term> v3 = {a, d_solver.mkTrue()};
+  std::vector<Term> v4 = {d_solver.mkInteger(1), d_solver.mkInteger(2)};
+  std::vector<Term> v5 = {d_solver.mkInteger(1), Term()};
+  std::vector<Term> v6 = {};
+  Solver slv;
+
+  // mkTerm(Kind kind) const
+  ASSERT_NO_THROW(d_solver.mkTerm(PI));
+  ASSERT_NO_THROW(d_solver.mkTerm(REGEXP_NONE));
+  ASSERT_NO_THROW(d_solver.mkTerm(REGEXP_ALLCHAR));
+  ASSERT_THROW(d_solver.mkTerm(CONST_BITVECTOR), CVC5ApiException);
+
+  // mkTerm(Kind kind, Term child) const
+  ASSERT_NO_THROW(d_solver.mkTerm(NOT, d_solver.mkTrue()));
+  ASSERT_THROW(d_solver.mkTerm(NOT, Term()), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkTerm(NOT, a), CVC5ApiException);
+  ASSERT_THROW(slv.mkTerm(NOT, d_solver.mkTrue()), CVC5ApiException);
+
+  // mkTerm(Kind kind, Term child1, Term child2) const
+  ASSERT_NO_THROW(d_solver.mkTerm(EQUAL, a, b));
+  ASSERT_THROW(d_solver.mkTerm(EQUAL, Term(), b), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkTerm(EQUAL, a, Term()), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkTerm(EQUAL, a, d_solver.mkTrue()), CVC5ApiException);
+  ASSERT_THROW(slv.mkTerm(EQUAL, a, b), CVC5ApiException);
+
+  // mkTerm(Kind kind, Term child1, Term child2, Term child3) const
+  ASSERT_NO_THROW(d_solver.mkTerm(
+      ITE, d_solver.mkTrue(), d_solver.mkTrue(), d_solver.mkTrue()));
+  ASSERT_THROW(
+      d_solver.mkTerm(ITE, Term(), d_solver.mkTrue(), d_solver.mkTrue()),
+      CVC5ApiException);
+  ASSERT_THROW(
+      d_solver.mkTerm(ITE, d_solver.mkTrue(), Term(), d_solver.mkTrue()),
+      CVC5ApiException);
+  ASSERT_THROW(
+      d_solver.mkTerm(ITE, d_solver.mkTrue(), d_solver.mkTrue(), Term()),
+      CVC5ApiException);
+  ASSERT_THROW(d_solver.mkTerm(ITE, d_solver.mkTrue(), d_solver.mkTrue(), b),
+               CVC5ApiException);
+  ASSERT_THROW(
+      slv.mkTerm(ITE, d_solver.mkTrue(), d_solver.mkTrue(), d_solver.mkTrue()),
+      CVC5ApiException);
+
+  // mkTerm(Kind kind, const std::vector<Term>& children) const
+  ASSERT_NO_THROW(d_solver.mkTerm(EQUAL, v1));
+  ASSERT_THROW(d_solver.mkTerm(EQUAL, v2), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkTerm(EQUAL, v3), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkTerm(DISTINCT, v6), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, mkTermFromOp)
+{
+  Sort bv32 = d_solver.mkBitVectorSort(32);
+  Term a = d_solver.mkConst(bv32, "a");
+  Term b = d_solver.mkConst(bv32, "b");
+  std::vector<Term> v1 = {d_solver.mkInteger(1), d_solver.mkInteger(2)};
+  std::vector<Term> v2 = {d_solver.mkInteger(1), Term()};
+  std::vector<Term> v3 = {};
+  std::vector<Term> v4 = {d_solver.mkInteger(5)};
+  Solver slv;
+
+  // simple operator terms
+  Op opterm1 = d_solver.mkOp(BITVECTOR_EXTRACT, 2, 1);
+  Op opterm2 = d_solver.mkOp(DIVISIBLE, 1);
+
+  // list datatype
+  Sort sort = d_solver.mkParamSort("T");
+  DatatypeDecl listDecl = d_solver.mkDatatypeDecl("paramlist", sort);
+  DatatypeConstructorDecl cons = d_solver.mkDatatypeConstructorDecl("cons");
+  DatatypeConstructorDecl nil = d_solver.mkDatatypeConstructorDecl("nil");
+  cons.addSelector("head", sort);
+  cons.addSelectorSelf("tail");
+  listDecl.addConstructor(cons);
+  listDecl.addConstructor(nil);
+  Sort listSort = d_solver.mkDatatypeSort(listDecl);
+  Sort intListSort =
+      listSort.instantiate(std::vector<Sort>{d_solver.getIntegerSort()});
+  Term c = d_solver.mkConst(intListSort, "c");
+  Datatype list = listSort.getDatatype();
+
+  // list datatype constructor and selector operator terms
+  Term consTerm1 = list.getConstructorTerm("cons");
+  Term consTerm2 = list.getConstructor("cons").getConstructorTerm();
+  Term nilTerm1 = list.getConstructorTerm("nil");
+  Term nilTerm2 = list.getConstructor("nil").getConstructorTerm();
+  Term headTerm1 = list["cons"].getSelectorTerm("head");
+  Term headTerm2 = list["cons"].getSelector("head").getSelectorTerm();
+  Term tailTerm1 = list["cons"].getSelectorTerm("tail");
+  Term tailTerm2 = list["cons"]["tail"].getSelectorTerm();
+
+  // mkTerm(Op op, Term term) const
+  ASSERT_NO_THROW(d_solver.mkTerm(APPLY_CONSTRUCTOR, nilTerm1));
+  ASSERT_NO_THROW(d_solver.mkTerm(APPLY_CONSTRUCTOR, nilTerm2));
+  ASSERT_THROW(d_solver.mkTerm(APPLY_SELECTOR, nilTerm1), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkTerm(APPLY_SELECTOR, consTerm1), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkTerm(APPLY_CONSTRUCTOR, consTerm2), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkTerm(opterm1), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkTerm(APPLY_SELECTOR, headTerm1), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkTerm(opterm1), CVC5ApiException);
+  ASSERT_THROW(slv.mkTerm(APPLY_CONSTRUCTOR, nilTerm1), CVC5ApiException);
+
+  // mkTerm(Op op, Term child) const
+  ASSERT_NO_THROW(d_solver.mkTerm(opterm1, a));
+  ASSERT_NO_THROW(d_solver.mkTerm(opterm2, d_solver.mkInteger(1)));
+  ASSERT_NO_THROW(d_solver.mkTerm(APPLY_SELECTOR, headTerm1, c));
+  ASSERT_NO_THROW(d_solver.mkTerm(APPLY_SELECTOR, tailTerm2, c));
+  ASSERT_THROW(d_solver.mkTerm(opterm2, a), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkTerm(opterm1, Term()), CVC5ApiException);
+  ASSERT_THROW(
+      d_solver.mkTerm(APPLY_CONSTRUCTOR, consTerm1, d_solver.mkInteger(0)),
+      CVC5ApiException);
+  ASSERT_THROW(slv.mkTerm(opterm1, a), CVC5ApiException);
+
+  // mkTerm(Op op, Term child1, Term child2) const
+  ASSERT_NO_THROW(
+      d_solver.mkTerm(APPLY_CONSTRUCTOR,
+                      consTerm1,
+                      d_solver.mkInteger(0),
+                      d_solver.mkTerm(APPLY_CONSTRUCTOR, nilTerm1)));
+  ASSERT_THROW(
+      d_solver.mkTerm(opterm2, d_solver.mkInteger(1), d_solver.mkInteger(2)),
+      CVC5ApiException);
+  ASSERT_THROW(d_solver.mkTerm(opterm1, a, b), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkTerm(opterm2, d_solver.mkInteger(1), Term()),
+               CVC5ApiException);
+  ASSERT_THROW(d_solver.mkTerm(opterm2, Term(), d_solver.mkInteger(1)),
+               CVC5ApiException);
+  ASSERT_THROW(slv.mkTerm(APPLY_CONSTRUCTOR,
+                          consTerm1,
+                          d_solver.mkInteger(0),
+                          d_solver.mkTerm(APPLY_CONSTRUCTOR, nilTerm1)),
+               CVC5ApiException);
+
+  // mkTerm(Op op, Term child1, Term child2, Term child3) const
+  ASSERT_THROW(d_solver.mkTerm(opterm1, a, b, a), CVC5ApiException);
+  ASSERT_THROW(
+      d_solver.mkTerm(
+          opterm2, d_solver.mkInteger(1), d_solver.mkInteger(1), Term()),
+      CVC5ApiException);
+
+  // mkTerm(Op op, const std::vector<Term>& children) const
+  ASSERT_NO_THROW(d_solver.mkTerm(opterm2, v4));
+  ASSERT_THROW(d_solver.mkTerm(opterm2, v1), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkTerm(opterm2, v2), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkTerm(opterm2, v3), CVC5ApiException);
+  ASSERT_THROW(slv.mkTerm(opterm2, v4), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, mkTrue)
+{
+  ASSERT_NO_THROW(d_solver.mkTrue());
+  ASSERT_NO_THROW(d_solver.mkTrue());
+}
+
+TEST_F(TestApiBlackSolver, mkTuple)
+{
+  ASSERT_NO_THROW(d_solver.mkTuple({d_solver.mkBitVectorSort(3)},
+                                   {d_solver.mkBitVector(3, "101", 2)}));
+  ASSERT_NO_THROW(
+      d_solver.mkTuple({d_solver.getRealSort()}, {d_solver.mkInteger("5")}));
+
+  ASSERT_THROW(d_solver.mkTuple({}, {d_solver.mkBitVector(3, "101", 2)}),
+               CVC5ApiException);
+  ASSERT_THROW(d_solver.mkTuple({d_solver.mkBitVectorSort(4)},
+                                {d_solver.mkBitVector(3, "101", 2)}),
+               CVC5ApiException);
+  ASSERT_THROW(
+      d_solver.mkTuple({d_solver.getIntegerSort()}, {d_solver.mkReal("5.3")}),
+      CVC5ApiException);
+  Solver slv;
+  ASSERT_THROW(slv.mkTuple({d_solver.mkBitVectorSort(3)},
+                           {slv.mkBitVector(3, "101", 2)}),
+               CVC5ApiException);
+  ASSERT_THROW(slv.mkTuple({slv.mkBitVectorSort(3)},
+                           {d_solver.mkBitVector(3, "101", 2)}),
+               CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, mkUniverseSet)
+{
+  ASSERT_NO_THROW(d_solver.mkUniverseSet(d_solver.getBooleanSort()));
+  ASSERT_THROW(d_solver.mkUniverseSet(Sort()), CVC5ApiException);
+  Solver slv;
+  ASSERT_THROW(slv.mkUniverseSet(d_solver.getBooleanSort()), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, mkConst)
+{
+  Sort boolSort = d_solver.getBooleanSort();
+  Sort intSort = d_solver.getIntegerSort();
+  Sort funSort = d_solver.mkFunctionSort(intSort, boolSort);
+  ASSERT_NO_THROW(d_solver.mkConst(boolSort));
+  ASSERT_NO_THROW(d_solver.mkConst(funSort));
+  ASSERT_NO_THROW(d_solver.mkConst(boolSort, std::string("b")));
+  ASSERT_NO_THROW(d_solver.mkConst(intSort, std::string("i")));
+  ASSERT_NO_THROW(d_solver.mkConst(funSort, "f"));
+  ASSERT_NO_THROW(d_solver.mkConst(funSort, ""));
+  ASSERT_THROW(d_solver.mkConst(Sort()), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkConst(Sort(), "a"), CVC5ApiException);
+
+  Solver slv;
+  ASSERT_THROW(slv.mkConst(boolSort), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, mkConstArray)
+{
+  Sort intSort = d_solver.getIntegerSort();
+  Sort arrSort = d_solver.mkArraySort(intSort, intSort);
+  Term zero = d_solver.mkInteger(0);
+  Term constArr = d_solver.mkConstArray(arrSort, zero);
+
+  ASSERT_NO_THROW(d_solver.mkConstArray(arrSort, zero));
+  ASSERT_THROW(d_solver.mkConstArray(Sort(), zero), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkConstArray(arrSort, Term()), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkConstArray(arrSort, d_solver.mkBitVector(1, 1)),
+               CVC5ApiException);
+  ASSERT_THROW(d_solver.mkConstArray(intSort, zero), CVC5ApiException);
+  Solver slv;
+  Term zero2 = slv.mkInteger(0);
+  Sort arrSort2 = slv.mkArraySort(slv.getIntegerSort(), slv.getIntegerSort());
+  ASSERT_THROW(slv.mkConstArray(arrSort2, zero), CVC5ApiException);
+  ASSERT_THROW(slv.mkConstArray(arrSort, zero2), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, declareDatatype)
+{
+  DatatypeConstructorDecl nil = d_solver.mkDatatypeConstructorDecl("nil");
+  std::vector<DatatypeConstructorDecl> ctors1 = {nil};
+  ASSERT_NO_THROW(d_solver.declareDatatype(std::string("a"), ctors1));
+  DatatypeConstructorDecl cons = d_solver.mkDatatypeConstructorDecl("cons");
+  DatatypeConstructorDecl nil2 = d_solver.mkDatatypeConstructorDecl("nil");
+  std::vector<DatatypeConstructorDecl> ctors2 = {cons, nil2};
+  ASSERT_NO_THROW(d_solver.declareDatatype(std::string("b"), ctors2));
+  DatatypeConstructorDecl cons2 = d_solver.mkDatatypeConstructorDecl("cons");
+  DatatypeConstructorDecl nil3 = d_solver.mkDatatypeConstructorDecl("nil");
+  std::vector<DatatypeConstructorDecl> ctors3 = {cons2, nil3};
+  ASSERT_NO_THROW(d_solver.declareDatatype(std::string(""), ctors3));
+  std::vector<DatatypeConstructorDecl> ctors4;
+  ASSERT_THROW(d_solver.declareDatatype(std::string("c"), ctors4),
+               CVC5ApiException);
+  ASSERT_THROW(d_solver.declareDatatype(std::string(""), ctors4),
+               CVC5ApiException);
+  Solver slv;
+  ASSERT_THROW(slv.declareDatatype(std::string("a"), ctors1), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, declareFun)
+{
+  Sort bvSort = d_solver.mkBitVectorSort(32);
+  Sort funSort = d_solver.mkFunctionSort(d_solver.mkUninterpretedSort("u"),
+                                         d_solver.getIntegerSort());
+  ASSERT_NO_THROW(d_solver.declareFun("f1", {}, bvSort));
+  ASSERT_NO_THROW(
+      d_solver.declareFun("f3", {bvSort, d_solver.getIntegerSort()}, bvSort));
+  ASSERT_THROW(d_solver.declareFun("f2", {}, funSort), CVC5ApiException);
+  // functions as arguments is allowed
+  ASSERT_NO_THROW(d_solver.declareFun("f4", {bvSort, funSort}, bvSort));
+  ASSERT_THROW(d_solver.declareFun("f5", {bvSort, bvSort}, funSort),
+               CVC5ApiException);
+  Solver slv;
+  ASSERT_THROW(slv.declareFun("f1", {}, bvSort), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, declareSort)
+{
+  ASSERT_NO_THROW(d_solver.declareSort("s", 0));
+  ASSERT_NO_THROW(d_solver.declareSort("s", 2));
+  ASSERT_NO_THROW(d_solver.declareSort("", 2));
+}
+
+TEST_F(TestApiBlackSolver, defineSort)
+{
+  Sort sortVar0 = d_solver.mkParamSort("T0");
+  Sort sortVar1 = d_solver.mkParamSort("T1");
+  Sort intSort = d_solver.getIntegerSort();
+  Sort realSort = d_solver.getRealSort();
+  Sort arraySort0 = d_solver.mkArraySort(sortVar0, sortVar0);
+  Sort arraySort1 = d_solver.mkArraySort(sortVar0, sortVar1);
+  // Now create instantiations of the defined sorts
+  ASSERT_NO_THROW(arraySort0.substitute(sortVar0, intSort));
+  ASSERT_NO_THROW(
+      arraySort1.substitute({sortVar0, sortVar1}, {intSort, realSort}));
+}
+
+TEST_F(TestApiBlackSolver, defineFun)
+{
+  Sort bvSort = d_solver.mkBitVectorSort(32);
+  Sort funSort = d_solver.mkFunctionSort(d_solver.mkUninterpretedSort("u"),
+                                         d_solver.getIntegerSort());
+  Term b1 = d_solver.mkVar(bvSort, "b1");
+  Term b2 = d_solver.mkVar(d_solver.getIntegerSort(), "b2");
+  Term b3 = d_solver.mkVar(funSort, "b3");
+  Term v1 = d_solver.mkConst(bvSort, "v1");
+  Term v2 = d_solver.mkConst(funSort, "v2");
+  ASSERT_NO_THROW(d_solver.defineFun("f", {}, bvSort, v1));
+  ASSERT_NO_THROW(d_solver.defineFun("ff", {b1, b2}, bvSort, v1));
+  ASSERT_THROW(d_solver.defineFun("ff", {v1, b2}, bvSort, v1),
+               CVC5ApiException);
+  ASSERT_THROW(d_solver.defineFun("fff", {b1}, bvSort, v2), CVC5ApiException);
+  ASSERT_THROW(d_solver.defineFun("ffff", {b1}, funSort, v2), CVC5ApiException);
+  // b3 has function sort, which is allowed as an argument
+  ASSERT_NO_THROW(d_solver.defineFun("fffff", {b1, b3}, bvSort, v1));
+
+  Solver slv;
+  Sort bvSort2 = slv.mkBitVectorSort(32);
+  Term v12 = slv.mkConst(bvSort2, "v1");
+  Term b12 = slv.mkVar(bvSort2, "b1");
+  Term b22 = slv.mkVar(slv.getIntegerSort(), "b2");
+  ASSERT_THROW(slv.defineFun("f", {}, bvSort, v12), CVC5ApiException);
+  ASSERT_THROW(slv.defineFun("f", {}, bvSort2, v1), CVC5ApiException);
+  ASSERT_THROW(slv.defineFun("ff", {b1, b22}, bvSort2, v12), CVC5ApiException);
+  ASSERT_THROW(slv.defineFun("ff", {b12, b2}, bvSort2, v12), CVC5ApiException);
+  ASSERT_THROW(slv.defineFun("ff", {b12, b22}, bvSort, v12), CVC5ApiException);
+  ASSERT_THROW(slv.defineFun("ff", {b12, b22}, bvSort2, v1), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, defineFunGlobal)
+{
+  Sort bSort = d_solver.getBooleanSort();
+
+  Term bTrue = d_solver.mkBoolean(true);
+  // (define-fun f () Bool true)
+  Term f = d_solver.defineFun("f", {}, bSort, bTrue, true);
+  Term b = d_solver.mkVar(bSort, "b");
+  // (define-fun g (b Bool) Bool b)
+  Term g = d_solver.defineFun("g", {b}, bSort, b, true);
+
+  // (assert (or (not f) (not (g true))))
+  d_solver.assertFormula(d_solver.mkTerm(
+      OR, f.notTerm(), d_solver.mkTerm(APPLY_UF, g, bTrue).notTerm()));
+  ASSERT_TRUE(d_solver.checkSat().isUnsat());
+  d_solver.resetAssertions();
+  // (assert (or (not f) (not (g true))))
+  d_solver.assertFormula(d_solver.mkTerm(
+      OR, f.notTerm(), d_solver.mkTerm(APPLY_UF, g, bTrue).notTerm()));
+  ASSERT_TRUE(d_solver.checkSat().isUnsat());
+}
+
+TEST_F(TestApiBlackSolver, defineFunRec)
+{
+  Sort bvSort = d_solver.mkBitVectorSort(32);
+  Sort funSort1 = d_solver.mkFunctionSort({bvSort, bvSort}, bvSort);
+  Sort funSort2 = d_solver.mkFunctionSort(d_solver.mkUninterpretedSort("u"),
+                                          d_solver.getIntegerSort());
+  Term b1 = d_solver.mkVar(bvSort, "b1");
+  Term b11 = d_solver.mkVar(bvSort, "b1");
+  Term b2 = d_solver.mkVar(d_solver.getIntegerSort(), "b2");
+  Term b3 = d_solver.mkVar(funSort2, "b3");
+  Term v1 = d_solver.mkConst(bvSort, "v1");
+  Term v2 = d_solver.mkConst(d_solver.getIntegerSort(), "v2");
+  Term v3 = d_solver.mkConst(funSort2, "v3");
+  Term f1 = d_solver.mkConst(funSort1, "f1");
+  Term f2 = d_solver.mkConst(funSort2, "f2");
+  Term f3 = d_solver.mkConst(bvSort, "f3");
+  ASSERT_NO_THROW(d_solver.defineFunRec("f", {}, bvSort, v1));
+  ASSERT_NO_THROW(d_solver.defineFunRec("ff", {b1, b2}, bvSort, v1));
+  ASSERT_NO_THROW(d_solver.defineFunRec(f1, {b1, b11}, v1));
+  ASSERT_THROW(d_solver.defineFunRec("fff", {b1}, bvSort, v3),
+               CVC5ApiException);
+  ASSERT_THROW(d_solver.defineFunRec("ff", {b1, v2}, bvSort, v1),
+               CVC5ApiException);
+  ASSERT_THROW(d_solver.defineFunRec("ffff", {b1}, funSort2, v3),
+               CVC5ApiException);
+  // b3 has function sort, which is allowed as an argument
+  ASSERT_NO_THROW(d_solver.defineFunRec("fffff", {b1, b3}, bvSort, v1));
+  ASSERT_THROW(d_solver.defineFunRec(f1, {b1}, v1), CVC5ApiException);
+  ASSERT_THROW(d_solver.defineFunRec(f1, {b1, b11}, v2), CVC5ApiException);
+  ASSERT_THROW(d_solver.defineFunRec(f1, {b1, b11}, v3), CVC5ApiException);
+  ASSERT_THROW(d_solver.defineFunRec(f2, {b1}, v2), CVC5ApiException);
+  ASSERT_THROW(d_solver.defineFunRec(f3, {b1}, v1), CVC5ApiException);
+
+  Solver slv;
+  Sort bvSort2 = slv.mkBitVectorSort(32);
+  Term v12 = slv.mkConst(bvSort2, "v1");
+  Term b12 = slv.mkVar(bvSort2, "b1");
+  Term b22 = slv.mkVar(slv.getIntegerSort(), "b2");
+  ASSERT_NO_THROW(slv.defineFunRec("f", {}, bvSort2, v12));
+  ASSERT_NO_THROW(slv.defineFunRec("ff", {b12, b22}, bvSort2, v12));
+  ASSERT_THROW(slv.defineFunRec("f", {}, bvSort, v12), CVC5ApiException);
+  ASSERT_THROW(slv.defineFunRec("f", {}, bvSort2, v1), CVC5ApiException);
+  ASSERT_THROW(slv.defineFunRec("ff", {b1, b22}, bvSort2, v12),
+               CVC5ApiException);
+  ASSERT_THROW(slv.defineFunRec("ff", {b12, b2}, bvSort2, v12),
+               CVC5ApiException);
+  ASSERT_THROW(slv.defineFunRec("ff", {b12, b22}, bvSort, v12),
+               CVC5ApiException);
+  ASSERT_THROW(slv.defineFunRec("ff", {b12, b22}, bvSort2, v1),
+               CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, defineFunRecWrongLogic)
+{
+  d_solver.setLogic("QF_BV");
+  Sort bvSort = d_solver.mkBitVectorSort(32);
+  Sort funSort = d_solver.mkFunctionSort({bvSort, bvSort}, bvSort);
+  Term b = d_solver.mkVar(bvSort, "b");
+  Term v = d_solver.mkConst(bvSort, "v");
+  Term f = d_solver.mkConst(funSort, "f");
+  ASSERT_THROW(d_solver.defineFunRec("f", {}, bvSort, v), CVC5ApiException);
+  ASSERT_THROW(d_solver.defineFunRec(f, {b, b}, v), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, defineFunRecGlobal)
+{
+  Sort bSort = d_solver.getBooleanSort();
+  Sort fSort = d_solver.mkFunctionSort(bSort, bSort);
+
+  d_solver.push();
+  Term bTrue = d_solver.mkBoolean(true);
+  // (define-fun f () Bool true)
+  Term f = d_solver.defineFunRec("f", {}, bSort, bTrue, true);
+  Term b = d_solver.mkVar(bSort, "b");
+  Term gSym = d_solver.mkConst(fSort, "g");
+  // (define-fun g (b Bool) Bool b)
+  Term g = d_solver.defineFunRec(gSym, {b}, b, true);
+
+  // (assert (or (not f) (not (g true))))
+  d_solver.assertFormula(d_solver.mkTerm(
+      OR, f.notTerm(), d_solver.mkTerm(APPLY_UF, g, bTrue).notTerm()));
+  ASSERT_TRUE(d_solver.checkSat().isUnsat());
+  d_solver.pop();
+  // (assert (or (not f) (not (g true))))
+  d_solver.assertFormula(d_solver.mkTerm(
+      OR, f.notTerm(), d_solver.mkTerm(APPLY_UF, g, bTrue).notTerm()));
+  ASSERT_TRUE(d_solver.checkSat().isUnsat());
+}
+
+TEST_F(TestApiBlackSolver, defineFunsRec)
+{
+  Sort uSort = d_solver.mkUninterpretedSort("u");
+  Sort bvSort = d_solver.mkBitVectorSort(32);
+  Sort funSort1 = d_solver.mkFunctionSort({bvSort, bvSort}, bvSort);
+  Sort funSort2 = d_solver.mkFunctionSort(uSort, d_solver.getIntegerSort());
+  Term b1 = d_solver.mkVar(bvSort, "b1");
+  Term b11 = d_solver.mkVar(bvSort, "b1");
+  Term b2 = d_solver.mkVar(d_solver.getIntegerSort(), "b2");
+  Term b3 = d_solver.mkVar(funSort2, "b3");
+  Term b4 = d_solver.mkVar(uSort, "b4");
+  Term v1 = d_solver.mkConst(bvSort, "v1");
+  Term v2 = d_solver.mkConst(d_solver.getIntegerSort(), "v2");
+  Term v3 = d_solver.mkConst(funSort2, "v3");
+  Term v4 = d_solver.mkConst(uSort, "v4");
+  Term f1 = d_solver.mkConst(funSort1, "f1");
+  Term f2 = d_solver.mkConst(funSort2, "f2");
+  Term f3 = d_solver.mkConst(bvSort, "f3");
+  ASSERT_NO_THROW(
+      d_solver.defineFunsRec({f1, f2}, {{b1, b11}, {b4}}, {v1, v2}));
+  ASSERT_THROW(d_solver.defineFunsRec({f1, f2}, {{v1, b11}, {b4}}, {v1, v2}),
+               CVC5ApiException);
+  ASSERT_THROW(d_solver.defineFunsRec({f1, f3}, {{b1, b11}, {b4}}, {v1, v2}),
+               CVC5ApiException);
+  ASSERT_THROW(d_solver.defineFunsRec({f1, f2}, {{b1}, {b4}}, {v1, v2}),
+               CVC5ApiException);
+  ASSERT_THROW(d_solver.defineFunsRec({f1, f2}, {{b1, b2}, {b4}}, {v1, v2}),
+               CVC5ApiException);
+  ASSERT_THROW(d_solver.defineFunsRec({f1, f2}, {{b1, b11}, {b4}}, {v1, v4}),
+               CVC5ApiException);
+
+  Solver slv;
+  Sort uSort2 = slv.mkUninterpretedSort("u");
+  Sort bvSort2 = slv.mkBitVectorSort(32);
+  Sort funSort12 = slv.mkFunctionSort({bvSort2, bvSort2}, bvSort2);
+  Sort funSort22 = slv.mkFunctionSort(uSort2, slv.getIntegerSort());
+  Term b12 = slv.mkVar(bvSort2, "b1");
+  Term b112 = slv.mkVar(bvSort2, "b1");
+  Term b42 = slv.mkVar(uSort2, "b4");
+  Term v12 = slv.mkConst(bvSort2, "v1");
+  Term v22 = slv.mkConst(slv.getIntegerSort(), "v2");
+  Term f12 = slv.mkConst(funSort12, "f1");
+  Term f22 = slv.mkConst(funSort22, "f2");
+  ASSERT_NO_THROW(
+      slv.defineFunsRec({f12, f22}, {{b12, b112}, {b42}}, {v12, v22}));
+  ASSERT_THROW(slv.defineFunsRec({f1, f22}, {{b12, b112}, {b42}}, {v12, v22}),
+               CVC5ApiException);
+  ASSERT_THROW(slv.defineFunsRec({f12, f2}, {{b12, b112}, {b42}}, {v12, v22}),
+               CVC5ApiException);
+  ASSERT_THROW(slv.defineFunsRec({f12, f22}, {{b1, b112}, {b42}}, {v12, v22}),
+               CVC5ApiException);
+  ASSERT_THROW(slv.defineFunsRec({f12, f22}, {{b12, b11}, {b42}}, {v12, v22}),
+               CVC5ApiException);
+  ASSERT_THROW(slv.defineFunsRec({f12, f22}, {{b12, b112}, {b4}}, {v12, v22}),
+               CVC5ApiException);
+  ASSERT_THROW(slv.defineFunsRec({f12, f22}, {{b12, b112}, {b42}}, {v1, v22}),
+               CVC5ApiException);
+  ASSERT_THROW(slv.defineFunsRec({f12, f22}, {{b12, b112}, {b42}}, {v12, v2}),
+               CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, defineFunsRecWrongLogic)
+{
+  d_solver.setLogic("QF_BV");
+  Sort uSort = d_solver.mkUninterpretedSort("u");
+  Sort bvSort = d_solver.mkBitVectorSort(32);
+  Sort funSort1 = d_solver.mkFunctionSort({bvSort, bvSort}, bvSort);
+  Sort funSort2 = d_solver.mkFunctionSort(uSort, d_solver.getIntegerSort());
+  Term b = d_solver.mkVar(bvSort, "b");
+  Term u = d_solver.mkVar(uSort, "u");
+  Term v1 = d_solver.mkConst(bvSort, "v1");
+  Term v2 = d_solver.mkConst(d_solver.getIntegerSort(), "v2");
+  Term f1 = d_solver.mkConst(funSort1, "f1");
+  Term f2 = d_solver.mkConst(funSort2, "f2");
+  ASSERT_THROW(d_solver.defineFunsRec({f1, f2}, {{b, b}, {u}}, {v1, v2}),
+               CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, defineFunsRecGlobal)
+{
+  Sort bSort = d_solver.getBooleanSort();
+  Sort fSort = d_solver.mkFunctionSort(bSort, bSort);
+
+  d_solver.push();
+  Term bTrue = d_solver.mkBoolean(true);
+  Term b = d_solver.mkVar(bSort, "b");
+  Term gSym = d_solver.mkConst(fSort, "g");
+  // (define-funs-rec ((g ((b Bool)) Bool)) (b))
+  d_solver.defineFunsRec({gSym}, {{b}}, {b}, true);
+
+  // (assert (not (g true)))
+  d_solver.assertFormula(d_solver.mkTerm(APPLY_UF, gSym, bTrue).notTerm());
+  ASSERT_TRUE(d_solver.checkSat().isUnsat());
+  d_solver.pop();
+  // (assert (not (g true)))
+  d_solver.assertFormula(d_solver.mkTerm(APPLY_UF, gSym, bTrue).notTerm());
+  ASSERT_TRUE(d_solver.checkSat().isUnsat());
+}
+
+TEST_F(TestApiBlackSolver, uFIteration)
+{
+  Sort intSort = d_solver.getIntegerSort();
+  Sort funSort = d_solver.mkFunctionSort({intSort, intSort}, intSort);
+  Term x = d_solver.mkConst(intSort, "x");
+  Term y = d_solver.mkConst(intSort, "y");
+  Term f = d_solver.mkConst(funSort, "f");
+  Term fxy = d_solver.mkTerm(APPLY_UF, f, x, y);
+
+  // Expecting the uninterpreted function to be one of the children
+  Term expected_children[3] = {f, x, y};
+  uint32_t idx = 0;
+  for (auto c : fxy)
+  {
+    ASSERT_LT(idx, 3);
+    ASSERT_EQ(c, expected_children[idx]);
+    idx++;
+  }
+}
+
+TEST_F(TestApiBlackSolver, getInfo)
+{
+  ASSERT_NO_THROW(d_solver.getInfo("name"));
+  ASSERT_THROW(d_solver.getInfo("asdf"), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, getAbduct)
+{
+  d_solver.setLogic("QF_LIA");
+  d_solver.setOption("produce-abducts", "true");
+  d_solver.setOption("incremental", "false");
+
+  Sort intSort = d_solver.getIntegerSort();
+  Term zero = d_solver.mkInteger(0);
+  Term x = d_solver.mkConst(intSort, "x");
+  Term y = d_solver.mkConst(intSort, "y");
+
+  // Assumptions for abduction: x > 0
+  d_solver.assertFormula(d_solver.mkTerm(GT, x, zero));
+  // Conjecture for abduction: y > 0
+  Term conj = d_solver.mkTerm(GT, y, zero);
+  Term output;
+  // Call the abduction api, while the resulting abduct is the output
+  ASSERT_TRUE(d_solver.getAbduct(conj, output));
+  // We expect the resulting output to be a boolean formula
+  ASSERT_TRUE(!output.isNull() && output.getSort().isBoolean());
+
+  // try with a grammar, a simple grammar admitting true
+  Sort boolean = d_solver.getBooleanSort();
+  Term truen = d_solver.mkBoolean(true);
+  Term start = d_solver.mkVar(boolean);
+  Term output2;
+  Grammar g = d_solver.mkSygusGrammar({}, {start});
+  Term conj2 = d_solver.mkTerm(GT, x, zero);
+  ASSERT_NO_THROW(g.addRule(start, truen));
+  // Call the abduction api, while the resulting abduct is the output
+  ASSERT_TRUE(d_solver.getAbduct(conj2, g, output2));
+  // abduct must be true
+  ASSERT_EQ(output2, truen);
+}
+
+TEST_F(TestApiBlackSolver, getAbduct2)
+{
+  d_solver.setLogic("QF_LIA");
+  d_solver.setOption("incremental", "false");
+  Sort intSort = d_solver.getIntegerSort();
+  Term zero = d_solver.mkInteger(0);
+  Term x = d_solver.mkConst(intSort, "x");
+  Term y = d_solver.mkConst(intSort, "y");
+  // Assumptions for abduction: x > 0
+  d_solver.assertFormula(d_solver.mkTerm(GT, x, zero));
+  // Conjecture for abduction: y > 0
+  Term conj = d_solver.mkTerm(GT, y, zero);
+  Term output;
+  // Fails due to option not set
+  ASSERT_THROW(d_solver.getAbduct(conj, output), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, getInterpolant)
+{
+  d_solver.setLogic("QF_LIA");
+  d_solver.setOption("produce-interpols", "default");
+  d_solver.setOption("incremental", "false");
+
+  Sort intSort = d_solver.getIntegerSort();
+  Term zero = d_solver.mkInteger(0);
+  Term x = d_solver.mkConst(intSort, "x");
+  Term y = d_solver.mkConst(intSort, "y");
+  Term z = d_solver.mkConst(intSort, "z");
+
+  // Assumptions for interpolation: x + y > 0 /\ x < 0
+  d_solver.assertFormula(
+      d_solver.mkTerm(GT, d_solver.mkTerm(PLUS, x, y), zero));
+  d_solver.assertFormula(d_solver.mkTerm(LT, x, zero));
+  // Conjecture for interpolation: y + z > 0 \/ z < 0
+  Term conj =
+      d_solver.mkTerm(OR,
+                      d_solver.mkTerm(GT, d_solver.mkTerm(PLUS, y, z), zero),
+                      d_solver.mkTerm(LT, z, zero));
+  Term output;
+  // Call the interpolation api, while the resulting interpolant is the output
+  d_solver.getInterpolant(conj, output);
+
+  // We expect the resulting output to be a boolean formula
+  ASSERT_TRUE(output.getSort().isBoolean());
+}
+
+TEST_F(TestApiBlackSolver, declarePool)
+{
+  Sort intSort = d_solver.getIntegerSort();
+  Sort setSort = d_solver.mkSetSort(intSort);
+  Term zero = d_solver.mkInteger(0);
+  Term x = d_solver.mkConst(intSort, "x");
+  Term y = d_solver.mkConst(intSort, "y");
+  // declare a pool with initial value { 0, x, y }
+  Term p = d_solver.declarePool("p", intSort, {zero, x, y});
+  // pool should have the same sort
+  ASSERT_TRUE(p.getSort() == setSort);
+  // cannot pass null sort
+  Sort nullSort;
+  ASSERT_THROW(d_solver.declarePool("i", nullSort, {}), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, getOp)
+{
+  Sort bv32 = d_solver.mkBitVectorSort(32);
+  Term a = d_solver.mkConst(bv32, "a");
+  Op ext = d_solver.mkOp(BITVECTOR_EXTRACT, 2, 1);
+  Term exta = d_solver.mkTerm(ext, a);
+
+  ASSERT_FALSE(a.hasOp());
+  ASSERT_THROW(a.getOp(), CVC5ApiException);
+  ASSERT_TRUE(exta.hasOp());
+  ASSERT_EQ(exta.getOp(), ext);
+
+  // Test Datatypes -- more complicated
+  DatatypeDecl consListSpec = d_solver.mkDatatypeDecl("list");
+  DatatypeConstructorDecl cons = d_solver.mkDatatypeConstructorDecl("cons");
+  cons.addSelector("head", d_solver.getIntegerSort());
+  cons.addSelectorSelf("tail");
+  consListSpec.addConstructor(cons);
+  DatatypeConstructorDecl nil = d_solver.mkDatatypeConstructorDecl("nil");
+  consListSpec.addConstructor(nil);
+  Sort consListSort = d_solver.mkDatatypeSort(consListSpec);
+  Datatype consList = consListSort.getDatatype();
+
+  Term consTerm = consList.getConstructorTerm("cons");
+  Term nilTerm = consList.getConstructorTerm("nil");
+  Term headTerm = consList["cons"].getSelectorTerm("head");
+
+  Term listnil = d_solver.mkTerm(APPLY_CONSTRUCTOR, nilTerm);
+  Term listcons1 = d_solver.mkTerm(
+      APPLY_CONSTRUCTOR, consTerm, d_solver.mkInteger(1), listnil);
+  Term listhead = d_solver.mkTerm(APPLY_SELECTOR, headTerm, listcons1);
+
+  ASSERT_TRUE(listnil.hasOp());
+  ASSERT_TRUE(listcons1.hasOp());
+  ASSERT_TRUE(listhead.hasOp());
+}
+
+TEST_F(TestApiBlackSolver, getOption)
+{
+  ASSERT_NO_THROW(d_solver.getOption("incremental"));
+  ASSERT_THROW(d_solver.getOption("asdf"), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, getOptionNames)
+{
+  std::vector<std::string> names = d_solver.getOptionNames();
+  ASSERT_TRUE(names.size() > 100);
+  ASSERT_NE(std::find(names.begin(), names.end(), "verbose"), names.end());
+  ASSERT_EQ(std::find(names.begin(), names.end(), "foobar"), names.end());
+}
+
+TEST_F(TestApiBlackSolver, getOptionInfo)
+{
+  {
+    EXPECT_THROW(d_solver.getOptionInfo("asdf-invalid"), CVC5ApiException);
+  }
+  {
+    api::OptionInfo info = d_solver.getOptionInfo("verbose");
+    EXPECT_EQ("verbose", info.name);
+    EXPECT_EQ(std::vector<std::string>{}, info.aliases);
+    EXPECT_TRUE(std::holds_alternative<OptionInfo::VoidInfo>(info.valueInfo));
+  }
+  {
+    // int64 type with default
+    api::OptionInfo info = d_solver.getOptionInfo("verbosity");
+    EXPECT_EQ("verbosity", info.name);
+    EXPECT_EQ(std::vector<std::string>{}, info.aliases);
+    EXPECT_TRUE(std::holds_alternative<OptionInfo::NumberInfo<int64_t>>(
+        info.valueInfo));
+    auto numInfo = std::get<OptionInfo::NumberInfo<int64_t>>(info.valueInfo);
+    EXPECT_EQ(0, numInfo.defaultValue);
+    EXPECT_EQ(0, numInfo.currentValue);
+    EXPECT_FALSE(numInfo.minimum || numInfo.maximum);
+    ASSERT_EQ(info.intValue(), 0);
+  }
+  {
+    auto info = d_solver.getOptionInfo("random-freq");
+    ASSERT_EQ(info.name, "random-freq");
+    ASSERT_EQ(info.aliases, std::vector<std::string>{"random-frequency"});
+    ASSERT_TRUE(std::holds_alternative<api::OptionInfo::NumberInfo<double>>(
+        info.valueInfo));
+    auto ni = std::get<api::OptionInfo::NumberInfo<double>>(info.valueInfo);
+    ASSERT_EQ(ni.currentValue, 0.0);
+    ASSERT_EQ(ni.defaultValue, 0.0);
+    ASSERT_TRUE(ni.minimum && ni.maximum);
+    ASSERT_EQ(*ni.minimum, 0.0);
+    ASSERT_EQ(*ni.maximum, 1.0);
+    ASSERT_EQ(info.doubleValue(), 0.0);
+  }
+  {
+    // mode option
+    api::OptionInfo info = d_solver.getOptionInfo("output");
+    EXPECT_EQ("output", info.name);
+    EXPECT_EQ(std::vector<std::string>{}, info.aliases);
+    EXPECT_TRUE(std::holds_alternative<OptionInfo::ModeInfo>(info.valueInfo));
+    auto modeInfo = std::get<OptionInfo::ModeInfo>(info.valueInfo);
+    EXPECT_EQ("NONE", modeInfo.defaultValue);
+    EXPECT_EQ("none", modeInfo.currentValue);
+    EXPECT_TRUE(std::find(modeInfo.modes.begin(), modeInfo.modes.end(), "NONE")
+                != modeInfo.modes.end());
+  }
+}
+
+TEST_F(TestApiBlackSolver, getUnsatAssumptions1)
+{
+  d_solver.setOption("incremental", "false");
+  d_solver.checkSatAssuming(d_solver.mkFalse());
+  ASSERT_THROW(d_solver.getUnsatAssumptions(), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, getUnsatAssumptions2)
+{
+  d_solver.setOption("incremental", "true");
+  d_solver.setOption("produce-unsat-assumptions", "false");
+  d_solver.checkSatAssuming(d_solver.mkFalse());
+  ASSERT_THROW(d_solver.getUnsatAssumptions(), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, getUnsatAssumptions3)
+{
+  d_solver.setOption("incremental", "true");
+  d_solver.setOption("produce-unsat-assumptions", "true");
+  d_solver.checkSatAssuming(d_solver.mkFalse());
+  ASSERT_NO_THROW(d_solver.getUnsatAssumptions());
+  d_solver.checkSatAssuming(d_solver.mkTrue());
+  ASSERT_THROW(d_solver.getUnsatAssumptions(), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, getUnsatCore1)
+{
+  d_solver.setOption("incremental", "false");
+  d_solver.assertFormula(d_solver.mkFalse());
+  d_solver.checkSat();
+  ASSERT_THROW(d_solver.getUnsatCore(), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, getUnsatCore2)
+{
+  d_solver.setOption("incremental", "false");
+  d_solver.setOption("produce-unsat-cores", "false");
+  d_solver.assertFormula(d_solver.mkFalse());
+  d_solver.checkSat();
+  ASSERT_THROW(d_solver.getUnsatCore(), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, getUnsatCoreAndProof)
+{
+  d_solver.setOption("incremental", "true");
+  d_solver.setOption("produce-unsat-cores", "true");
+  d_solver.setOption("produce-proofs", "true");
+
+  Sort uSort = d_solver.mkUninterpretedSort("u");
+  Sort intSort = d_solver.getIntegerSort();
+  Sort boolSort = d_solver.getBooleanSort();
+  Sort uToIntSort = d_solver.mkFunctionSort(uSort, intSort);
+  Sort intPredSort = d_solver.mkFunctionSort(intSort, boolSort);
+  std::vector<Term> unsat_core;
+
+  Term x = d_solver.mkConst(uSort, "x");
+  Term y = d_solver.mkConst(uSort, "y");
+  Term f = d_solver.mkConst(uToIntSort, "f");
+  Term p = d_solver.mkConst(intPredSort, "p");
+  Term zero = d_solver.mkInteger(0);
+  Term one = d_solver.mkInteger(1);
+  Term f_x = d_solver.mkTerm(APPLY_UF, f, x);
+  Term f_y = d_solver.mkTerm(APPLY_UF, f, y);
+  Term sum = d_solver.mkTerm(PLUS, f_x, f_y);
+  Term p_0 = d_solver.mkTerm(APPLY_UF, p, zero);
+  Term p_f_y = d_solver.mkTerm(APPLY_UF, p, f_y);
+  d_solver.assertFormula(d_solver.mkTerm(GT, zero, f_x));
+  d_solver.assertFormula(d_solver.mkTerm(GT, zero, f_y));
+  d_solver.assertFormula(d_solver.mkTerm(GT, sum, one));
+  d_solver.assertFormula(p_0);
+  d_solver.assertFormula(p_f_y.notTerm());
+  ASSERT_TRUE(d_solver.checkSat().isUnsat());
+
+  ASSERT_NO_THROW(unsat_core = d_solver.getUnsatCore());
+
+  ASSERT_NO_THROW(d_solver.getProof());
+
+  d_solver.resetAssertions();
+  for (const auto& t : unsat_core)
+  {
+    d_solver.assertFormula(t);
+  }
+  cvc5::api::Result res = d_solver.checkSat();
+  ASSERT_TRUE(res.isUnsat());
+  ASSERT_NO_THROW(d_solver.getProof());
+}
+
+TEST_F(TestApiBlackSolver, getDifficulty)
+{
+  d_solver.setOption("produce-difficulty", "true");
+  // cannot ask before a check sat
+  ASSERT_THROW(d_solver.getDifficulty(), CVC5ApiException);
+  d_solver.checkSat();
+  ASSERT_NO_THROW(d_solver.getDifficulty());
+}
+
+TEST_F(TestApiBlackSolver, getDifficulty2)
+{
+  d_solver.checkSat();
+  // option is not set
+  ASSERT_THROW(d_solver.getDifficulty(), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, getDifficulty3)
+{
+  d_solver.setOption("produce-difficulty", "true");
+  Sort intSort = d_solver.getIntegerSort();
+  Term x = d_solver.mkConst(intSort, "x");
+  Term zero = d_solver.mkInteger(0);
+  Term ten = d_solver.mkInteger(10);
+  Term f0 = d_solver.mkTerm(GEQ, x, ten);
+  Term f1 = d_solver.mkTerm(GEQ, zero, x);
+  d_solver.checkSat();
+  std::map<Term, Term> dmap;
+  ASSERT_NO_THROW(dmap = d_solver.getDifficulty());
+  // difficulty should map assertions to integer values
+  for (const std::pair<const Term, Term>& t : dmap)
+  {
+    ASSERT_TRUE(t.first == f0 || t.first == f1);
+    ASSERT_TRUE(t.second.getKind() == CONST_RATIONAL);
+  }
+}
+
+TEST_F(TestApiBlackSolver, getValue1)
+{
+  d_solver.setOption("produce-models", "false");
+  Term t = d_solver.mkTrue();
+  d_solver.assertFormula(t);
+  d_solver.checkSat();
+  ASSERT_THROW(d_solver.getValue(t), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, getValue2)
+{
+  d_solver.setOption("produce-models", "true");
+  Term t = d_solver.mkFalse();
+  d_solver.assertFormula(t);
+  d_solver.checkSat();
+  ASSERT_THROW(d_solver.getValue(t), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, getValue3)
+{
+  d_solver.setOption("produce-models", "true");
+  Sort uSort = d_solver.mkUninterpretedSort("u");
+  Sort intSort = d_solver.getIntegerSort();
+  Sort boolSort = d_solver.getBooleanSort();
+  Sort uToIntSort = d_solver.mkFunctionSort(uSort, intSort);
+  Sort intPredSort = d_solver.mkFunctionSort(intSort, boolSort);
+  std::vector<Term> unsat_core;
+
+  Term x = d_solver.mkConst(uSort, "x");
+  Term y = d_solver.mkConst(uSort, "y");
+  Term z = d_solver.mkConst(uSort, "z");
+  Term f = d_solver.mkConst(uToIntSort, "f");
+  Term p = d_solver.mkConst(intPredSort, "p");
+  Term zero = d_solver.mkInteger(0);
+  Term one = d_solver.mkInteger(1);
+  Term f_x = d_solver.mkTerm(APPLY_UF, f, x);
+  Term f_y = d_solver.mkTerm(APPLY_UF, f, y);
+  Term sum = d_solver.mkTerm(PLUS, f_x, f_y);
+  Term p_0 = d_solver.mkTerm(APPLY_UF, p, zero);
+  Term p_f_y = d_solver.mkTerm(APPLY_UF, p, f_y);
+
+  d_solver.assertFormula(d_solver.mkTerm(LEQ, zero, f_x));
+  d_solver.assertFormula(d_solver.mkTerm(LEQ, zero, f_y));
+  d_solver.assertFormula(d_solver.mkTerm(LEQ, sum, one));
+  d_solver.assertFormula(p_0.notTerm());
+  d_solver.assertFormula(p_f_y);
+  ASSERT_TRUE(d_solver.checkSat().isSat());
+  ASSERT_NO_THROW(d_solver.getValue(x));
+  ASSERT_NO_THROW(d_solver.getValue(y));
+  ASSERT_NO_THROW(d_solver.getValue(z));
+  ASSERT_NO_THROW(d_solver.getValue(sum));
+  ASSERT_NO_THROW(d_solver.getValue(p_f_y));
+
+  Solver slv;
+  ASSERT_THROW(slv.getValue(x), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, getModelDomainElements)
+{
+  d_solver.setOption("produce-models", "true");
+  Sort uSort = d_solver.mkUninterpretedSort("u");
+  Sort intSort = d_solver.getIntegerSort();
+  Term x = d_solver.mkConst(uSort, "x");
+  Term y = d_solver.mkConst(uSort, "y");
+  Term z = d_solver.mkConst(uSort, "z");
+  Term f = d_solver.mkTerm(DISTINCT, x, y, z);
+  d_solver.assertFormula(f);
+  d_solver.checkSat();
+  ASSERT_NO_THROW(d_solver.getModelDomainElements(uSort));
+  ASSERT_TRUE(d_solver.getModelDomainElements(uSort).size() >= 3);
+  ASSERT_THROW(d_solver.getModelDomainElements(intSort), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, getModelDomainElements2)
+{
+  d_solver.setOption("produce-models", "true");
+  d_solver.setOption("finite-model-find", "true");
+  Sort uSort = d_solver.mkUninterpretedSort("u");
+  Term x = d_solver.mkVar(uSort, "x");
+  Term y = d_solver.mkVar(uSort, "y");
+  Term eq = d_solver.mkTerm(EQUAL, x, y);
+  Term bvl = d_solver.mkTerm(BOUND_VAR_LIST, x, y);
+  Term f = d_solver.mkTerm(FORALL, bvl, eq);
+  d_solver.assertFormula(f);
+  d_solver.checkSat();
+  ASSERT_NO_THROW(d_solver.getModelDomainElements(uSort));
+  // a model for the above must interpret u as size 1
+  ASSERT_TRUE(d_solver.getModelDomainElements(uSort).size() == 1);
+}
+
+TEST_F(TestApiBlackSolver, isModelCoreSymbol)
+{
+  d_solver.setOption("produce-models", "true");
+  d_solver.setOption("model-cores", "simple");
+  Sort uSort = d_solver.mkUninterpretedSort("u");
+  Term x = d_solver.mkConst(uSort, "x");
+  Term y = d_solver.mkConst(uSort, "y");
+  Term z = d_solver.mkConst(uSort, "z");
+  Term zero = d_solver.mkInteger(0);
+  Term f = d_solver.mkTerm(NOT, d_solver.mkTerm(EQUAL, x, y));
+  d_solver.assertFormula(f);
+  d_solver.checkSat();
+  ASSERT_TRUE(d_solver.isModelCoreSymbol(x));
+  ASSERT_TRUE(d_solver.isModelCoreSymbol(y));
+  ASSERT_FALSE(d_solver.isModelCoreSymbol(z));
+  ASSERT_THROW(d_solver.isModelCoreSymbol(zero), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, getModel)
+{
+  d_solver.setOption("produce-models", "true");
+  Sort uSort = d_solver.mkUninterpretedSort("u");
+  Term x = d_solver.mkConst(uSort, "x");
+  Term y = d_solver.mkConst(uSort, "y");
+  Term z = d_solver.mkConst(uSort, "z");
+  Term f = d_solver.mkTerm(NOT, d_solver.mkTerm(EQUAL, x, y));
+  d_solver.assertFormula(f);
+  d_solver.checkSat();
+  std::vector<Sort> sorts;
+  sorts.push_back(uSort);
+  std::vector<Term> terms;
+  terms.push_back(x);
+  terms.push_back(y);
+  ASSERT_NO_THROW(d_solver.getModel(sorts, terms));
+  Term null;
+  terms.push_back(null);
+  ASSERT_THROW(d_solver.getModel(sorts, terms), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, getModel2)
+{
+  d_solver.setOption("produce-models", "true");
+  std::vector<Sort> sorts;
+  std::vector<Term> terms;
+  ASSERT_THROW(d_solver.getModel(sorts, terms), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, getModel3)
+{
+  d_solver.setOption("produce-models", "true");
+  std::vector<Sort> sorts;
+  std::vector<Term> terms;
+  d_solver.checkSat();
+  ASSERT_NO_THROW(d_solver.getModel(sorts, terms));
+  Sort integer = d_solver.getIntegerSort();
+  sorts.push_back(integer);
+  ASSERT_THROW(d_solver.getModel(sorts, terms), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, getQuantifierElimination)
+{
+  Term x = d_solver.mkVar(d_solver.getBooleanSort(), "x");
+  Term forall =
+      d_solver.mkTerm(FORALL,
+                      d_solver.mkTerm(BOUND_VAR_LIST, x),
+                      d_solver.mkTerm(OR, x, d_solver.mkTerm(NOT, x)));
+  ASSERT_THROW(d_solver.getQuantifierElimination(Term()), CVC5ApiException);
+  ASSERT_THROW(d_solver.getQuantifierElimination(Solver().mkBoolean(false)),
+               CVC5ApiException);
+  ASSERT_NO_THROW(d_solver.getQuantifierElimination(forall));
+}
+
+TEST_F(TestApiBlackSolver, getQuantifierEliminationDisjunct)
+{
+  Term x = d_solver.mkVar(d_solver.getBooleanSort(), "x");
+  Term forall =
+      d_solver.mkTerm(FORALL,
+                      d_solver.mkTerm(BOUND_VAR_LIST, x),
+                      d_solver.mkTerm(OR, x, d_solver.mkTerm(NOT, x)));
+  ASSERT_THROW(d_solver.getQuantifierEliminationDisjunct(Term()),
+               CVC5ApiException);
+  ASSERT_THROW(
+      d_solver.getQuantifierEliminationDisjunct(Solver().mkBoolean(false)),
+      CVC5ApiException);
+  ASSERT_NO_THROW(d_solver.getQuantifierEliminationDisjunct(forall));
+}
+
+TEST_F(TestApiBlackSolver, declareSepHeap)
+{
+  d_solver.setLogic("ALL");
+  Sort integer = d_solver.getIntegerSort();
+  ASSERT_NO_THROW(d_solver.declareSepHeap(integer, integer));
+  // cannot declare separation logic heap more than once
+  ASSERT_THROW(d_solver.declareSepHeap(integer, integer), CVC5ApiException);
+}
+
+namespace {
+/**
+ * Helper function for testGetSeparation{Heap,Nil}TermX. Asserts and checks
+ * some simple separation logic constraints.
+ */
+void checkSimpleSeparationConstraints(Solver* solver)
+{
+  Sort integer = solver->getIntegerSort();
+  // declare the separation heap
+  solver->declareSepHeap(integer, integer);
+  Term x = solver->mkConst(integer, "x");
+  Term p = solver->mkConst(integer, "p");
+  Term heap = solver->mkTerm(cvc5::api::Kind::SEP_PTO, p, x);
+  solver->assertFormula(heap);
+  Term nil = solver->mkSepNil(integer);
+  solver->assertFormula(nil.eqTerm(solver->mkReal(5)));
+  solver->checkSat();
+}
+}  // namespace
+
+TEST_F(TestApiBlackSolver, getValueSepHeap1)
+{
+  d_solver.setLogic("QF_BV");
+  d_solver.setOption("incremental", "false");
+  d_solver.setOption("produce-models", "true");
+  Term t = d_solver.mkTrue();
+  d_solver.assertFormula(t);
+  ASSERT_THROW(d_solver.getValueSepHeap(), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, getValueSepHeap2)
+{
+  d_solver.setLogic("ALL");
+  d_solver.setOption("incremental", "false");
+  d_solver.setOption("produce-models", "false");
+  checkSimpleSeparationConstraints(&d_solver);
+  ASSERT_THROW(d_solver.getValueSepHeap(), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, getValueSepHeap3)
+{
+  d_solver.setLogic("ALL");
+  d_solver.setOption("incremental", "false");
+  d_solver.setOption("produce-models", "true");
+  Term t = d_solver.mkFalse();
+  d_solver.assertFormula(t);
+  d_solver.checkSat();
+  ASSERT_THROW(d_solver.getValueSepHeap(), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, getValueSepHeap4)
+{
+  d_solver.setLogic("ALL");
+  d_solver.setOption("incremental", "false");
+  d_solver.setOption("produce-models", "true");
+  Term t = d_solver.mkTrue();
+  d_solver.assertFormula(t);
+  d_solver.checkSat();
+  ASSERT_THROW(d_solver.getValueSepHeap(), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, getValueSepHeap5)
+{
+  d_solver.setLogic("ALL");
+  d_solver.setOption("incremental", "false");
+  d_solver.setOption("produce-models", "true");
+  checkSimpleSeparationConstraints(&d_solver);
+  ASSERT_NO_THROW(d_solver.getValueSepHeap());
+}
+
+TEST_F(TestApiBlackSolver, getValueSepNil1)
+{
+  d_solver.setLogic("QF_BV");
+  d_solver.setOption("incremental", "false");
+  d_solver.setOption("produce-models", "true");
+  Term t = d_solver.mkTrue();
+  d_solver.assertFormula(t);
+  ASSERT_THROW(d_solver.getValueSepNil(), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, getValueSepNil2)
+{
+  d_solver.setLogic("ALL");
+  d_solver.setOption("incremental", "false");
+  d_solver.setOption("produce-models", "false");
+  checkSimpleSeparationConstraints(&d_solver);
+  ASSERT_THROW(d_solver.getValueSepNil(), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, getValueSepNil3)
+{
+  d_solver.setLogic("ALL");
+  d_solver.setOption("incremental", "false");
+  d_solver.setOption("produce-models", "true");
+  Term t = d_solver.mkFalse();
+  d_solver.assertFormula(t);
+  d_solver.checkSat();
+  ASSERT_THROW(d_solver.getValueSepNil(), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, getValueSepNil4)
+{
+  d_solver.setLogic("ALL");
+  d_solver.setOption("incremental", "false");
+  d_solver.setOption("produce-models", "true");
+  Term t = d_solver.mkTrue();
+  d_solver.assertFormula(t);
+  d_solver.checkSat();
+  ASSERT_THROW(d_solver.getValueSepNil(), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, getValueSepNil5)
+{
+  d_solver.setLogic("ALL");
+  d_solver.setOption("incremental", "false");
+  d_solver.setOption("produce-models", "true");
+  checkSimpleSeparationConstraints(&d_solver);
+  ASSERT_NO_THROW(d_solver.getValueSepNil());
+}
+
+TEST_F(TestApiBlackSolver, push1)
+{
+  d_solver.setOption("incremental", "true");
+  ASSERT_NO_THROW(d_solver.push(1));
+  ASSERT_THROW(d_solver.setOption("incremental", "false"), CVC5ApiException);
+  ASSERT_THROW(d_solver.setOption("incremental", "true"), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, push2)
+{
+  d_solver.setOption("incremental", "false");
+  ASSERT_THROW(d_solver.push(1), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, pop1)
+{
+  d_solver.setOption("incremental", "false");
+  ASSERT_THROW(d_solver.pop(1), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, pop2)
+{
+  d_solver.setOption("incremental", "true");
+  ASSERT_THROW(d_solver.pop(1), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, pop3)
+{
+  d_solver.setOption("incremental", "true");
+  ASSERT_NO_THROW(d_solver.push(1));
+  ASSERT_NO_THROW(d_solver.pop(1));
+  ASSERT_THROW(d_solver.pop(1), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, blockModel1)
+{
+  d_solver.setOption("produce-models", "true");
+  Term x = d_solver.mkConst(d_solver.getBooleanSort(), "x");
+  d_solver.assertFormula(x.eqTerm(x));
+  d_solver.checkSat();
+  ASSERT_THROW(d_solver.blockModel(), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, blockModel2)
+{
+  d_solver.setOption("block-models", "literals");
+  Term x = d_solver.mkConst(d_solver.getBooleanSort(), "x");
+  d_solver.assertFormula(x.eqTerm(x));
+  d_solver.checkSat();
+  ASSERT_THROW(d_solver.blockModel(), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, blockModel3)
+{
+  d_solver.setOption("produce-models", "true");
+  d_solver.setOption("block-models", "literals");
+  Term x = d_solver.mkConst(d_solver.getBooleanSort(), "x");
+  d_solver.assertFormula(x.eqTerm(x));
+  ASSERT_THROW(d_solver.blockModel(), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, blockModel4)
+{
+  d_solver.setOption("produce-models", "true");
+  d_solver.setOption("block-models", "literals");
+  Term x = d_solver.mkConst(d_solver.getBooleanSort(), "x");
+  d_solver.assertFormula(x.eqTerm(x));
+  d_solver.checkSat();
+  ASSERT_NO_THROW(d_solver.blockModel());
+}
+
+TEST_F(TestApiBlackSolver, blockModelValues1)
+{
+  d_solver.setOption("produce-models", "true");
+  d_solver.setOption("block-models", "literals");
+  Term x = d_solver.mkConst(d_solver.getBooleanSort(), "x");
+  d_solver.assertFormula(x.eqTerm(x));
+  d_solver.checkSat();
+  ASSERT_THROW(d_solver.blockModelValues({}), CVC5ApiException);
+  ASSERT_THROW(d_solver.blockModelValues({Term()}), CVC5ApiException);
+  ASSERT_THROW(d_solver.blockModelValues({Solver().mkBoolean(false)}),
+               CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, blockModelValues2)
+{
+  d_solver.setOption("produce-models", "true");
+  Term x = d_solver.mkConst(d_solver.getBooleanSort(), "x");
+  d_solver.assertFormula(x.eqTerm(x));
+  d_solver.checkSat();
+  ASSERT_THROW(d_solver.blockModelValues({x}), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, blockModelValues3)
+{
+  d_solver.setOption("block-models", "literals");
+  Term x = d_solver.mkConst(d_solver.getBooleanSort(), "x");
+  d_solver.assertFormula(x.eqTerm(x));
+  d_solver.checkSat();
+  ASSERT_THROW(d_solver.blockModelValues({x}), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, blockModelValues4)
+{
+  d_solver.setOption("produce-models", "true");
+  d_solver.setOption("block-models", "literals");
+  Term x = d_solver.mkConst(d_solver.getBooleanSort(), "x");
+  d_solver.assertFormula(x.eqTerm(x));
+  ASSERT_THROW(d_solver.blockModelValues({x}), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, blockModelValues5)
+{
+  d_solver.setOption("produce-models", "true");
+  d_solver.setOption("block-models", "literals");
+  Term x = d_solver.mkConst(d_solver.getBooleanSort(), "x");
+  d_solver.assertFormula(x.eqTerm(x));
+  d_solver.checkSat();
+  ASSERT_NO_THROW(d_solver.blockModelValues({x}));
+}
+
+TEST_F(TestApiBlackSolver, setInfo)
+{
+  ASSERT_THROW(d_solver.setInfo("cvc5-lagic", "QF_BV"), CVC5ApiException);
+  ASSERT_THROW(d_solver.setInfo("cvc2-logic", "QF_BV"), CVC5ApiException);
+  ASSERT_THROW(d_solver.setInfo("cvc5-logic", "asdf"), CVC5ApiException);
+
+  ASSERT_NO_THROW(d_solver.setInfo("source", "asdf"));
+  ASSERT_NO_THROW(d_solver.setInfo("category", "asdf"));
+  ASSERT_NO_THROW(d_solver.setInfo("difficulty", "asdf"));
+  ASSERT_NO_THROW(d_solver.setInfo("filename", "asdf"));
+  ASSERT_NO_THROW(d_solver.setInfo("license", "asdf"));
+  ASSERT_NO_THROW(d_solver.setInfo("name", "asdf"));
+  ASSERT_NO_THROW(d_solver.setInfo("notes", "asdf"));
+
+  ASSERT_NO_THROW(d_solver.setInfo("smt-lib-version", "2"));
+  ASSERT_NO_THROW(d_solver.setInfo("smt-lib-version", "2.0"));
+  ASSERT_NO_THROW(d_solver.setInfo("smt-lib-version", "2.5"));
+  ASSERT_NO_THROW(d_solver.setInfo("smt-lib-version", "2.6"));
+  ASSERT_THROW(d_solver.setInfo("smt-lib-version", ".0"), CVC5ApiException);
+
+  ASSERT_NO_THROW(d_solver.setInfo("status", "sat"));
+  ASSERT_NO_THROW(d_solver.setInfo("status", "unsat"));
+  ASSERT_NO_THROW(d_solver.setInfo("status", "unknown"));
+  ASSERT_THROW(d_solver.setInfo("status", "asdf"), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, simplify)
+{
+  ASSERT_THROW(d_solver.simplify(Term()), CVC5ApiException);
+
+  Sort bvSort = d_solver.mkBitVectorSort(32);
+  Sort uSort = d_solver.mkUninterpretedSort("u");
+  Sort funSort1 = d_solver.mkFunctionSort({bvSort, bvSort}, bvSort);
+  Sort funSort2 = d_solver.mkFunctionSort(uSort, d_solver.getIntegerSort());
+  DatatypeDecl consListSpec = d_solver.mkDatatypeDecl("list");
+  DatatypeConstructorDecl cons = d_solver.mkDatatypeConstructorDecl("cons");
+  cons.addSelector("head", d_solver.getIntegerSort());
+  cons.addSelectorSelf("tail");
+  consListSpec.addConstructor(cons);
+  DatatypeConstructorDecl nil = d_solver.mkDatatypeConstructorDecl("nil");
+  consListSpec.addConstructor(nil);
+  Sort consListSort = d_solver.mkDatatypeSort(consListSpec);
+
+  Term x = d_solver.mkConst(bvSort, "x");
+  ASSERT_NO_THROW(d_solver.simplify(x));
+  Term a = d_solver.mkConst(bvSort, "a");
+  ASSERT_NO_THROW(d_solver.simplify(a));
+  Term b = d_solver.mkConst(bvSort, "b");
+  ASSERT_NO_THROW(d_solver.simplify(b));
+  Term x_eq_x = d_solver.mkTerm(EQUAL, x, x);
+  ASSERT_NO_THROW(d_solver.simplify(x_eq_x));
+  ASSERT_NE(d_solver.mkTrue(), x_eq_x);
+  ASSERT_EQ(d_solver.mkTrue(), d_solver.simplify(x_eq_x));
+  Term x_eq_b = d_solver.mkTerm(EQUAL, x, b);
+  ASSERT_NO_THROW(d_solver.simplify(x_eq_b));
+  ASSERT_NE(d_solver.mkTrue(), x_eq_b);
+  ASSERT_NE(d_solver.mkTrue(), d_solver.simplify(x_eq_b));
+  Solver slv;
+  ASSERT_THROW(slv.simplify(x), CVC5ApiException);
+
+  Term i1 = d_solver.mkConst(d_solver.getIntegerSort(), "i1");
+  ASSERT_NO_THROW(d_solver.simplify(i1));
+  Term i2 = d_solver.mkTerm(MULT, i1, d_solver.mkInteger("23"));
+  ASSERT_NO_THROW(d_solver.simplify(i2));
+  ASSERT_NE(i1, i2);
+  ASSERT_NE(i1, d_solver.simplify(i2));
+  Term i3 = d_solver.mkTerm(PLUS, i1, d_solver.mkInteger(0));
+  ASSERT_NO_THROW(d_solver.simplify(i3));
+  ASSERT_NE(i1, i3);
+  ASSERT_EQ(i1, d_solver.simplify(i3));
+
+  Datatype consList = consListSort.getDatatype();
+  Term dt1 = d_solver.mkTerm(
+      APPLY_CONSTRUCTOR,
+      consList.getConstructorTerm("cons"),
+      d_solver.mkInteger(0),
+      d_solver.mkTerm(APPLY_CONSTRUCTOR, consList.getConstructorTerm("nil")));
+  ASSERT_NO_THROW(d_solver.simplify(dt1));
+  Term dt2 = d_solver.mkTerm(
+      APPLY_SELECTOR, consList["cons"].getSelectorTerm("head"), dt1);
+  ASSERT_NO_THROW(d_solver.simplify(dt2));
+
+  Term b1 = d_solver.mkVar(bvSort, "b1");
+  ASSERT_NO_THROW(d_solver.simplify(b1));
+  Term b2 = d_solver.mkVar(bvSort, "b1");
+  ASSERT_NO_THROW(d_solver.simplify(b2));
+  Term b3 = d_solver.mkVar(uSort, "b3");
+  ASSERT_NO_THROW(d_solver.simplify(b3));
+  Term v1 = d_solver.mkConst(bvSort, "v1");
+  ASSERT_NO_THROW(d_solver.simplify(v1));
+  Term v2 = d_solver.mkConst(d_solver.getIntegerSort(), "v2");
+  ASSERT_NO_THROW(d_solver.simplify(v2));
+  Term f1 = d_solver.mkConst(funSort1, "f1");
+  ASSERT_NO_THROW(d_solver.simplify(f1));
+  Term f2 = d_solver.mkConst(funSort2, "f2");
+  ASSERT_NO_THROW(d_solver.simplify(f2));
+  d_solver.defineFunsRec({f1, f2}, {{b1, b2}, {b3}}, {v1, v2});
+  ASSERT_NO_THROW(d_solver.simplify(f1));
+  ASSERT_NO_THROW(d_solver.simplify(f2));
+}
+
+TEST_F(TestApiBlackSolver, assertFormula)
+{
+  ASSERT_NO_THROW(d_solver.assertFormula(d_solver.mkTrue()));
+  ASSERT_THROW(d_solver.assertFormula(Term()), CVC5ApiException);
+  Solver slv;
+  ASSERT_THROW(slv.assertFormula(d_solver.mkTrue()), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, checkEntailed)
+{
+  d_solver.setOption("incremental", "false");
+  ASSERT_NO_THROW(d_solver.checkEntailed(d_solver.mkTrue()));
+  ASSERT_THROW(d_solver.checkEntailed(d_solver.mkTrue()), CVC5ApiException);
+  Solver slv;
+  ASSERT_THROW(slv.checkEntailed(d_solver.mkTrue()), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, checkEntailed1)
+{
+  Sort boolSort = d_solver.getBooleanSort();
+  Term x = d_solver.mkConst(boolSort, "x");
+  Term y = d_solver.mkConst(boolSort, "y");
+  Term z = d_solver.mkTerm(AND, x, y);
+  d_solver.setOption("incremental", "true");
+  ASSERT_NO_THROW(d_solver.checkEntailed(d_solver.mkTrue()));
+  ASSERT_THROW(d_solver.checkEntailed(Term()), CVC5ApiException);
+  ASSERT_NO_THROW(d_solver.checkEntailed(d_solver.mkTrue()));
+  ASSERT_NO_THROW(d_solver.checkEntailed(z));
+  Solver slv;
+  ASSERT_THROW(slv.checkEntailed(d_solver.mkTrue()), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, checkEntailed2)
+{
+  d_solver.setOption("incremental", "true");
+
+  Sort uSort = d_solver.mkUninterpretedSort("u");
+  Sort intSort = d_solver.getIntegerSort();
+  Sort boolSort = d_solver.getBooleanSort();
+  Sort uToIntSort = d_solver.mkFunctionSort(uSort, intSort);
+  Sort intPredSort = d_solver.mkFunctionSort(intSort, boolSort);
+
+  Term n = Term();
+  // Constants
+  Term x = d_solver.mkConst(uSort, "x");
+  Term y = d_solver.mkConst(uSort, "y");
+  // Functions
+  Term f = d_solver.mkConst(uToIntSort, "f");
+  Term p = d_solver.mkConst(intPredSort, "p");
+  // Values
+  Term zero = d_solver.mkInteger(0);
+  Term one = d_solver.mkInteger(1);
+  // Terms
+  Term f_x = d_solver.mkTerm(APPLY_UF, f, x);
+  Term f_y = d_solver.mkTerm(APPLY_UF, f, y);
+  Term sum = d_solver.mkTerm(PLUS, f_x, f_y);
+  Term p_0 = d_solver.mkTerm(APPLY_UF, p, zero);
+  Term p_f_y = d_solver.mkTerm(APPLY_UF, p, f_y);
+  // Assertions
+  Term assertions =
+      d_solver.mkTerm(AND,
+                      std::vector<Term>{
+                          d_solver.mkTerm(LEQ, zero, f_x),  // 0 <= f(x)
+                          d_solver.mkTerm(LEQ, zero, f_y),  // 0 <= f(y)
+                          d_solver.mkTerm(LEQ, sum, one),   // f(x) + f(y) <= 1
+                          p_0.notTerm(),                    // not p(0)
+                          p_f_y                             // p(f(y))
+                      });
+
+  ASSERT_NO_THROW(d_solver.checkEntailed(d_solver.mkTrue()));
+  d_solver.assertFormula(assertions);
+  ASSERT_NO_THROW(d_solver.checkEntailed(d_solver.mkTerm(DISTINCT, x, y)));
+  ASSERT_NO_THROW(d_solver.checkEntailed(
+      {d_solver.mkFalse(), d_solver.mkTerm(DISTINCT, x, y)}));
+  ASSERT_THROW(d_solver.checkEntailed(n), CVC5ApiException);
+  ASSERT_THROW(d_solver.checkEntailed({n, d_solver.mkTerm(DISTINCT, x, y)}),
+               CVC5ApiException);
+  Solver slv;
+  ASSERT_THROW(slv.checkEntailed(d_solver.mkTrue()), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, checkSat)
+{
+  d_solver.setOption("incremental", "false");
+  ASSERT_NO_THROW(d_solver.checkSat());
+  ASSERT_THROW(d_solver.checkSat(), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, checkSatAssuming)
+{
+  d_solver.setOption("incremental", "false");
+  ASSERT_NO_THROW(d_solver.checkSatAssuming(d_solver.mkTrue()));
+  ASSERT_THROW(d_solver.checkSatAssuming(d_solver.mkTrue()), CVC5ApiException);
+  Solver slv;
+  ASSERT_THROW(slv.checkSatAssuming(d_solver.mkTrue()), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, checkSatAssuming1)
+{
+  Sort boolSort = d_solver.getBooleanSort();
+  Term x = d_solver.mkConst(boolSort, "x");
+  Term y = d_solver.mkConst(boolSort, "y");
+  Term z = d_solver.mkTerm(AND, x, y);
+  d_solver.setOption("incremental", "true");
+  ASSERT_NO_THROW(d_solver.checkSatAssuming(d_solver.mkTrue()));
+  ASSERT_THROW(d_solver.checkSatAssuming(Term()), CVC5ApiException);
+  ASSERT_NO_THROW(d_solver.checkSatAssuming(d_solver.mkTrue()));
+  ASSERT_NO_THROW(d_solver.checkSatAssuming(z));
+  Solver slv;
+  ASSERT_THROW(slv.checkSatAssuming(d_solver.mkTrue()), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, checkSatAssuming2)
+{
+  d_solver.setOption("incremental", "true");
+
+  Sort uSort = d_solver.mkUninterpretedSort("u");
+  Sort intSort = d_solver.getIntegerSort();
+  Sort boolSort = d_solver.getBooleanSort();
+  Sort uToIntSort = d_solver.mkFunctionSort(uSort, intSort);
+  Sort intPredSort = d_solver.mkFunctionSort(intSort, boolSort);
+
+  Term n = Term();
+  // Constants
+  Term x = d_solver.mkConst(uSort, "x");
+  Term y = d_solver.mkConst(uSort, "y");
+  // Functions
+  Term f = d_solver.mkConst(uToIntSort, "f");
+  Term p = d_solver.mkConst(intPredSort, "p");
+  // Values
+  Term zero = d_solver.mkInteger(0);
+  Term one = d_solver.mkInteger(1);
+  // Terms
+  Term f_x = d_solver.mkTerm(APPLY_UF, f, x);
+  Term f_y = d_solver.mkTerm(APPLY_UF, f, y);
+  Term sum = d_solver.mkTerm(PLUS, f_x, f_y);
+  Term p_0 = d_solver.mkTerm(APPLY_UF, p, zero);
+  Term p_f_y = d_solver.mkTerm(APPLY_UF, p, f_y);
+  // Assertions
+  Term assertions =
+      d_solver.mkTerm(AND,
+                      std::vector<Term>{
+                          d_solver.mkTerm(LEQ, zero, f_x),  // 0 <= f(x)
+                          d_solver.mkTerm(LEQ, zero, f_y),  // 0 <= f(y)
+                          d_solver.mkTerm(LEQ, sum, one),   // f(x) + f(y) <= 1
+                          p_0.notTerm(),                    // not p(0)
+                          p_f_y                             // p(f(y))
+                      });
+
+  ASSERT_NO_THROW(d_solver.checkSatAssuming(d_solver.mkTrue()));
+  d_solver.assertFormula(assertions);
+  ASSERT_NO_THROW(d_solver.checkSatAssuming(d_solver.mkTerm(DISTINCT, x, y)));
+  ASSERT_NO_THROW(d_solver.checkSatAssuming(
+      {d_solver.mkFalse(), d_solver.mkTerm(DISTINCT, x, y)}));
+  ASSERT_THROW(d_solver.checkSatAssuming(n), CVC5ApiException);
+  ASSERT_THROW(d_solver.checkSatAssuming({n, d_solver.mkTerm(DISTINCT, x, y)}),
+               CVC5ApiException);
+  Solver slv;
+  ASSERT_THROW(slv.checkSatAssuming(d_solver.mkTrue()), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, setLogic)
+{
+  ASSERT_NO_THROW(d_solver.setLogic("AUFLIRA"));
+  ASSERT_THROW(d_solver.setLogic("AF_BV"), CVC5ApiException);
+  d_solver.assertFormula(d_solver.mkTrue());
+  ASSERT_THROW(d_solver.setLogic("AUFLIRA"), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, setOption)
+{
+  ASSERT_NO_THROW(d_solver.setOption("bv-sat-solver", "minisat"));
+  ASSERT_THROW(d_solver.setOption("bv-sat-solver", "1"), CVC5ApiException);
+  d_solver.assertFormula(d_solver.mkTrue());
+  ASSERT_THROW(d_solver.setOption("bv-sat-solver", "minisat"),
+               CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, resetAssertions)
+{
+  d_solver.setOption("incremental", "true");
+
+  Sort bvSort = d_solver.mkBitVectorSort(4);
+  Term one = d_solver.mkBitVector(4, 1);
+  Term x = d_solver.mkConst(bvSort, "x");
+  Term ule = d_solver.mkTerm(BITVECTOR_ULE, x, one);
+  Term srem = d_solver.mkTerm(BITVECTOR_SREM, one, x);
+  d_solver.push(4);
+  Term slt = d_solver.mkTerm(BITVECTOR_SLT, srem, one);
+  d_solver.resetAssertions();
+  d_solver.checkSatAssuming({slt, ule});
+}
+
+TEST_F(TestApiBlackSolver, mkSygusVar)
+{
+  Sort boolSort = d_solver.getBooleanSort();
+  Sort intSort = d_solver.getIntegerSort();
+  Sort funSort = d_solver.mkFunctionSort(intSort, boolSort);
+
+  ASSERT_NO_THROW(d_solver.mkSygusVar(boolSort));
+  ASSERT_NO_THROW(d_solver.mkSygusVar(funSort));
+  ASSERT_NO_THROW(d_solver.mkSygusVar(boolSort, std::string("b")));
+  ASSERT_NO_THROW(d_solver.mkSygusVar(funSort, ""));
+  ASSERT_THROW(d_solver.mkSygusVar(Sort()), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkSygusVar(d_solver.getNullSort(), "a"),
+               CVC5ApiException);
+  Solver slv;
+  ASSERT_THROW(slv.mkSygusVar(boolSort), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, mkSygusGrammar)
+{
+  Term nullTerm;
+  Term boolTerm = d_solver.mkBoolean(true);
+  Term boolVar = d_solver.mkVar(d_solver.getBooleanSort());
+  Term intVar = d_solver.mkVar(d_solver.getIntegerSort());
+
+  ASSERT_NO_THROW(d_solver.mkSygusGrammar({}, {intVar}));
+  ASSERT_NO_THROW(d_solver.mkSygusGrammar({boolVar}, {intVar}));
+  ASSERT_THROW(d_solver.mkSygusGrammar({}, {}), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkSygusGrammar({}, {nullTerm}), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkSygusGrammar({}, {boolTerm}), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkSygusGrammar({boolTerm}, {intVar}), CVC5ApiException);
+  Solver slv;
+  Term boolVar2 = slv.mkVar(slv.getBooleanSort());
+  Term intVar2 = slv.mkVar(slv.getIntegerSort());
+  ASSERT_NO_THROW(slv.mkSygusGrammar({boolVar2}, {intVar2}));
+  ASSERT_THROW(slv.mkSygusGrammar({boolVar}, {intVar2}), CVC5ApiException);
+  ASSERT_THROW(slv.mkSygusGrammar({boolVar2}, {intVar}), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, synthFun)
+{
+  Sort null = d_solver.getNullSort();
+  Sort boolean = d_solver.getBooleanSort();
+  Sort integer = d_solver.getIntegerSort();
+
+  Term nullTerm;
+  Term x = d_solver.mkVar(boolean);
+
+  Term start1 = d_solver.mkVar(boolean);
+  Term start2 = d_solver.mkVar(integer);
+
+  Grammar g1 = d_solver.mkSygusGrammar({x}, {start1});
+  g1.addRule(start1, d_solver.mkBoolean(false));
+
+  Grammar g2 = d_solver.mkSygusGrammar({x}, {start2});
+  g2.addRule(start2, d_solver.mkInteger(0));
+
+  ASSERT_NO_THROW(d_solver.synthFun("", {}, boolean));
+  ASSERT_NO_THROW(d_solver.synthFun("f1", {x}, boolean));
+  ASSERT_NO_THROW(d_solver.synthFun("f2", {x}, boolean, g1));
+
+  ASSERT_THROW(d_solver.synthFun("f3", {nullTerm}, boolean), CVC5ApiException);
+  ASSERT_THROW(d_solver.synthFun("f4", {}, null), CVC5ApiException);
+  ASSERT_THROW(d_solver.synthFun("f6", {x}, boolean, g2), CVC5ApiException);
+  Solver slv;
+  Term x2 = slv.mkVar(slv.getBooleanSort());
+  ASSERT_NO_THROW(slv.synthFun("f1", {x2}, slv.getBooleanSort()));
+  ASSERT_THROW(slv.synthFun("", {}, d_solver.getBooleanSort()),
+               CVC5ApiException);
+  ASSERT_THROW(slv.synthFun("f1", {x}, d_solver.getBooleanSort()),
+               CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, synthInv)
+{
+  Sort boolean = d_solver.getBooleanSort();
+  Sort integer = d_solver.getIntegerSort();
+
+  Term nullTerm;
+  Term x = d_solver.mkVar(boolean);
+
+  Term start1 = d_solver.mkVar(boolean);
+  Term start2 = d_solver.mkVar(integer);
+
+  Grammar g1 = d_solver.mkSygusGrammar({x}, {start1});
+  g1.addRule(start1, d_solver.mkBoolean(false));
+
+  Grammar g2 = d_solver.mkSygusGrammar({x}, {start2});
+  g2.addRule(start2, d_solver.mkInteger(0));
+
+  ASSERT_NO_THROW(d_solver.synthInv("", {}));
+  ASSERT_NO_THROW(d_solver.synthInv("i1", {x}));
+  ASSERT_NO_THROW(d_solver.synthInv("i2", {x}, g1));
+
+  ASSERT_THROW(d_solver.synthInv("i3", {nullTerm}), CVC5ApiException);
+  ASSERT_THROW(d_solver.synthInv("i4", {x}, g2), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, addSygusConstraint)
+{
+  Term nullTerm;
+  Term boolTerm = d_solver.mkBoolean(true);
+  Term intTerm = d_solver.mkInteger(1);
+
+  ASSERT_NO_THROW(d_solver.addSygusConstraint(boolTerm));
+  ASSERT_THROW(d_solver.addSygusConstraint(nullTerm), CVC5ApiException);
+  ASSERT_THROW(d_solver.addSygusConstraint(intTerm), CVC5ApiException);
+
+  Solver slv;
+  ASSERT_THROW(slv.addSygusConstraint(boolTerm), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, addSygusAssume)
+{
+  Term nullTerm;
+  Term boolTerm = d_solver.mkBoolean(false);
+  Term intTerm = d_solver.mkInteger(1);
+
+  ASSERT_NO_THROW(d_solver.addSygusAssume(boolTerm));
+  ASSERT_THROW(d_solver.addSygusAssume(nullTerm), CVC5ApiException);
+  ASSERT_THROW(d_solver.addSygusAssume(intTerm), CVC5ApiException);
+
+  Solver slv;
+  ASSERT_THROW(slv.addSygusAssume(boolTerm), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, addSygusInvConstraint)
+{
+  Sort boolean = d_solver.getBooleanSort();
+  Sort real = d_solver.getRealSort();
+
+  Term nullTerm;
+  Term intTerm = d_solver.mkInteger(1);
+
+  Term inv = d_solver.declareFun("inv", {real}, boolean);
+  Term pre = d_solver.declareFun("pre", {real}, boolean);
+  Term trans = d_solver.declareFun("trans", {real, real}, boolean);
+  Term post = d_solver.declareFun("post", {real}, boolean);
+
+  Term inv1 = d_solver.declareFun("inv1", {real}, real);
+
+  Term trans1 = d_solver.declareFun("trans1", {boolean, real}, boolean);
+  Term trans2 = d_solver.declareFun("trans2", {real, boolean}, boolean);
+  Term trans3 = d_solver.declareFun("trans3", {real, real}, real);
+
+  ASSERT_NO_THROW(d_solver.addSygusInvConstraint(inv, pre, trans, post));
+
+  ASSERT_THROW(d_solver.addSygusInvConstraint(nullTerm, pre, trans, post),
+               CVC5ApiException);
+  ASSERT_THROW(d_solver.addSygusInvConstraint(inv, nullTerm, trans, post),
+               CVC5ApiException);
+  ASSERT_THROW(d_solver.addSygusInvConstraint(inv, pre, nullTerm, post),
+               CVC5ApiException);
+  ASSERT_THROW(d_solver.addSygusInvConstraint(inv, pre, trans, nullTerm),
+               CVC5ApiException);
+
+  ASSERT_THROW(d_solver.addSygusInvConstraint(intTerm, pre, trans, post),
+               CVC5ApiException);
+
+  ASSERT_THROW(d_solver.addSygusInvConstraint(inv1, pre, trans, post),
+               CVC5ApiException);
+
+  ASSERT_THROW(d_solver.addSygusInvConstraint(inv, trans, trans, post),
+               CVC5ApiException);
+
+  ASSERT_THROW(d_solver.addSygusInvConstraint(inv, pre, intTerm, post),
+               CVC5ApiException);
+  ASSERT_THROW(d_solver.addSygusInvConstraint(inv, pre, pre, post),
+               CVC5ApiException);
+  ASSERT_THROW(d_solver.addSygusInvConstraint(inv, pre, trans1, post),
+               CVC5ApiException);
+  ASSERT_THROW(d_solver.addSygusInvConstraint(inv, pre, trans2, post),
+               CVC5ApiException);
+  ASSERT_THROW(d_solver.addSygusInvConstraint(inv, pre, trans3, post),
+               CVC5ApiException);
+
+  ASSERT_THROW(d_solver.addSygusInvConstraint(inv, pre, trans, trans),
+               CVC5ApiException);
+  Solver slv;
+  Sort boolean2 = slv.getBooleanSort();
+  Sort real2 = slv.getRealSort();
+  Term inv22 = slv.declareFun("inv", {real2}, boolean2);
+  Term pre22 = slv.declareFun("pre", {real2}, boolean2);
+  Term trans22 = slv.declareFun("trans", {real2, real2}, boolean2);
+  Term post22 = slv.declareFun("post", {real2}, boolean2);
+  ASSERT_NO_THROW(slv.addSygusInvConstraint(inv22, pre22, trans22, post22));
+  ASSERT_THROW(slv.addSygusInvConstraint(inv, pre22, trans22, post22),
+               CVC5ApiException);
+  ASSERT_THROW(slv.addSygusInvConstraint(inv22, pre, trans22, post22),
+               CVC5ApiException);
+  ASSERT_THROW(slv.addSygusInvConstraint(inv22, pre22, trans, post22),
+               CVC5ApiException);
+  ASSERT_THROW(slv.addSygusInvConstraint(inv22, pre22, trans22, post),
+               CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, getSynthSolution)
+{
+  d_solver.setOption("lang", "sygus2");
+  d_solver.setOption("incremental", "false");
+
+  Term nullTerm;
+  Term x = d_solver.mkBoolean(false);
+  Term f = d_solver.synthFun("f", {}, d_solver.getBooleanSort());
+
+  ASSERT_THROW(d_solver.getSynthSolution(f), CVC5ApiException);
+
+  d_solver.checkSynth();
+
+  ASSERT_NO_THROW(d_solver.getSynthSolution(f));
+  ASSERT_NO_THROW(d_solver.getSynthSolution(f));
+
+  ASSERT_THROW(d_solver.getSynthSolution(nullTerm), CVC5ApiException);
+  ASSERT_THROW(d_solver.getSynthSolution(x), CVC5ApiException);
+
+  Solver slv;
+  ASSERT_THROW(slv.getSynthSolution(f), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, getSynthSolutions)
+{
+  d_solver.setOption("lang", "sygus2");
+  d_solver.setOption("incremental", "false");
+
+  Term nullTerm;
+  Term x = d_solver.mkBoolean(false);
+  Term f = d_solver.synthFun("f", {}, d_solver.getBooleanSort());
+
+  ASSERT_THROW(d_solver.getSynthSolutions({}), CVC5ApiException);
+  ASSERT_THROW(d_solver.getSynthSolutions({f}), CVC5ApiException);
+
+  d_solver.checkSynth();
+
+  ASSERT_NO_THROW(d_solver.getSynthSolutions({f}));
+  ASSERT_NO_THROW(d_solver.getSynthSolutions({f, f}));
+
+  ASSERT_THROW(d_solver.getSynthSolutions({}), CVC5ApiException);
+  ASSERT_THROW(d_solver.getSynthSolutions({nullTerm}), CVC5ApiException);
+  ASSERT_THROW(d_solver.getSynthSolutions({x}), CVC5ApiException);
+
+  Solver slv;
+  ASSERT_THROW(slv.getSynthSolutions({x}), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, tupleProject)
+{
+  std::vector<Sort> sorts = {d_solver.getBooleanSort(),
+                             d_solver.getIntegerSort(),
+                             d_solver.getStringSort(),
+                             d_solver.mkSetSort(d_solver.getStringSort())};
+  std::vector<Term> elements = {
+      d_solver.mkBoolean(true),
+      d_solver.mkInteger(3),
+      d_solver.mkString("C"),
+      d_solver.mkTerm(SET_SINGLETON, d_solver.mkString("Z"))};
+
+  Term tuple = d_solver.mkTuple(sorts, elements);
+
+  std::vector<uint32_t> indices1 = {};
+  std::vector<uint32_t> indices2 = {0};
+  std::vector<uint32_t> indices3 = {0, 1};
+  std::vector<uint32_t> indices4 = {0, 0, 2, 2, 3, 3, 0};
+  std::vector<uint32_t> indices5 = {4};
+  std::vector<uint32_t> indices6 = {0, 4};
+
+  ASSERT_NO_THROW(
+      d_solver.mkTerm(d_solver.mkOp(TUPLE_PROJECT, indices1), tuple));
+  ASSERT_NO_THROW(
+      d_solver.mkTerm(d_solver.mkOp(TUPLE_PROJECT, indices2), tuple));
+  ASSERT_NO_THROW(
+      d_solver.mkTerm(d_solver.mkOp(TUPLE_PROJECT, indices3), tuple));
+  ASSERT_NO_THROW(
+      d_solver.mkTerm(d_solver.mkOp(TUPLE_PROJECT, indices4), tuple));
+
+  ASSERT_THROW(d_solver.mkTerm(d_solver.mkOp(TUPLE_PROJECT, indices5), tuple),
+               CVC5ApiException);
+  ASSERT_THROW(d_solver.mkTerm(d_solver.mkOp(TUPLE_PROJECT, indices6), tuple),
+               CVC5ApiException);
+
+  std::vector<uint32_t> indices = {0, 3, 2, 0, 1, 2};
+
+  Op op = d_solver.mkOp(TUPLE_PROJECT, indices);
+  Term projection = d_solver.mkTerm(op, tuple);
+
+  Datatype datatype = tuple.getSort().getDatatype();
+  DatatypeConstructor constructor = datatype[0];
+
+  for (size_t i = 0; i < indices.size(); i++)
+  {
+    Term selectorTerm = constructor[indices[i]].getSelectorTerm();
+    Term selectedTerm = d_solver.mkTerm(APPLY_SELECTOR, selectorTerm, tuple);
+    Term simplifiedTerm = d_solver.simplify(selectedTerm);
+    ASSERT_EQ(elements[indices[i]], simplifiedTerm);
+  }
+
+  ASSERT_EQ(
+      "((_ tuple_project 0 3 2 0 1 2) (tuple true 3 \"C\" (set.singleton "
+      "\"Z\")))",
+      projection.toString());
+}
+
+TEST_F(TestApiBlackSolver, Output)
+{
+  ASSERT_THROW(d_solver.isOutputOn("foo-invalid"), CVC5ApiException);
+  ASSERT_THROW(d_solver.getOutput("foo-invalid"), CVC5ApiException);
+  ASSERT_FALSE(d_solver.isOutputOn("inst"));
+  ASSERT_EQ(cvc5::null_os.rdbuf(), d_solver.getOutput("inst").rdbuf());
+  d_solver.setOption("output", "inst");
+  ASSERT_TRUE(d_solver.isOutputOn("inst"));
+  ASSERT_NE(cvc5::null_os.rdbuf(), d_solver.getOutput("inst").rdbuf());
+}
+
+TEST_F(TestApiBlackSolver, issue7000)
+{
+  Sort s1 = d_solver.getIntegerSort();
+  Sort s2 = d_solver.mkFunctionSort(s1, s1);
+  Sort s3 = d_solver.getRealSort();
+  Term t4 = d_solver.mkPi();
+  Term t7 = d_solver.mkConst(s3, "_x5");
+  Term t37 = d_solver.mkConst(s2, "_x32");
+  Term t59 = d_solver.mkConst(s2, "_x51");
+  Term t72 = d_solver.mkTerm(EQUAL, t37, t59);
+  Term t74 = d_solver.mkTerm(GT, t4, t7);
+  // throws logic exception since logic is not higher order by default
+  ASSERT_THROW(d_solver.checkEntailed({t72, t74, t72, t72}), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSolver, issue5893)
+{
+  Solver slv;
+  Sort bvsort4 = d_solver.mkBitVectorSort(4);
+  Sort bvsort8 = d_solver.mkBitVectorSort(8);
+  Sort arrsort = d_solver.mkArraySort(bvsort4, bvsort8);
+  Term arr = d_solver.mkConst(arrsort, "arr");
+  Term idx = d_solver.mkConst(bvsort4, "idx");
+  Term ten = d_solver.mkBitVector(8, "10", 10);
+  Term sel = d_solver.mkTerm(SELECT, arr, idx);
+  Term distinct = d_solver.mkTerm(DISTINCT, sel, ten);
+  ASSERT_NO_FATAL_FAILURE(distinct.getOp());
+}
+
+}  // namespace test
+}  // namespace cvc5
diff --git a/test/unit/api/cpp/solver_white.cpp b/test/unit/api/cpp/solver_white.cpp
new file mode 100644 (file)
index 0000000..5d7b9ea
--- /dev/null
@@ -0,0 +1,56 @@
+/******************************************************************************
+ * Top contributors (to current version):
+ *   Aina Niemetz, Makai Mann, Andrew Reynolds
+ *
+ * This file is part of the cvc5 project.
+ *
+ * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
+ * in the top-level source directory and their institutional affiliations.
+ * All rights reserved.  See the file COPYING in the top-level source
+ * directory for licensing information.
+ * ****************************************************************************
+ *
+ * Black box testing of the Solver class of the  C++ API.
+ */
+
+#include "base/configuration.h"
+#include "test_api.h"
+
+namespace cvc5 {
+
+using namespace api;
+
+namespace test {
+
+class TestApiWhiteSolver : public TestApi
+{
+};
+
+TEST_F(TestApiWhiteSolver, getOp)
+{
+  DatatypeDecl consListSpec = d_solver.mkDatatypeDecl("list");
+  DatatypeConstructorDecl cons = d_solver.mkDatatypeConstructorDecl("cons");
+  cons.addSelector("head", d_solver.getIntegerSort());
+  cons.addSelectorSelf("tail");
+  consListSpec.addConstructor(cons);
+  DatatypeConstructorDecl nil = d_solver.mkDatatypeConstructorDecl("nil");
+  consListSpec.addConstructor(nil);
+  Sort consListSort = d_solver.mkDatatypeSort(consListSpec);
+  Datatype consList = consListSort.getDatatype();
+
+  Term nilTerm = consList.getConstructorTerm("nil");
+  Term consTerm = consList.getConstructorTerm("cons");
+  Term headTerm = consList["cons"].getSelectorTerm("head");
+
+  Term listnil = d_solver.mkTerm(APPLY_CONSTRUCTOR, nilTerm);
+  Term listcons1 = d_solver.mkTerm(
+      APPLY_CONSTRUCTOR, consTerm, d_solver.mkInteger(1), listnil);
+  Term listhead = d_solver.mkTerm(APPLY_SELECTOR, headTerm, listcons1);
+
+  ASSERT_EQ(listnil.getOp(), Op(&d_solver, APPLY_CONSTRUCTOR));
+  ASSERT_EQ(listcons1.getOp(), Op(&d_solver, APPLY_CONSTRUCTOR));
+  ASSERT_EQ(listhead.getOp(), Op(&d_solver, APPLY_SELECTOR));
+}
+
+}  // namespace test
+}  // namespace cvc5
diff --git a/test/unit/api/cpp/sort_black.cpp b/test/unit/api/cpp/sort_black.cpp
new file mode 100644 (file)
index 0000000..d0c755c
--- /dev/null
@@ -0,0 +1,612 @@
+/******************************************************************************
+ * Top contributors (to current version):
+ *   Aina Niemetz, Andrew Reynolds, Mathias Preiner
+ *
+ * This file is part of the cvc5 project.
+ *
+ * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
+ * in the top-level source directory and their institutional affiliations.
+ * All rights reserved.  See the file COPYING in the top-level source
+ * directory for licensing information.
+ * ****************************************************************************
+ *
+ * Black box testing of the guards of the C++ API functions.
+ */
+
+#include "test_api.h"
+
+namespace cvc5 {
+
+using namespace api;
+
+namespace test {
+
+class TestApiBlackSort : public TestApi
+{
+ protected:
+  Sort create_datatype_sort()
+  {
+    DatatypeDecl dtypeSpec = d_solver.mkDatatypeDecl("list");
+    DatatypeConstructorDecl cons = d_solver.mkDatatypeConstructorDecl("cons");
+    cons.addSelector("head", d_solver.getIntegerSort());
+    cons.addSelectorSelf("tail");
+    dtypeSpec.addConstructor(cons);
+    DatatypeConstructorDecl nil = d_solver.mkDatatypeConstructorDecl("nil");
+    dtypeSpec.addConstructor(nil);
+    return d_solver.mkDatatypeSort(dtypeSpec);
+  }
+
+  Sort create_param_datatype_sort()
+  {
+    Sort sort = d_solver.mkParamSort("T");
+    DatatypeDecl paramDtypeSpec = d_solver.mkDatatypeDecl("paramlist", sort);
+    DatatypeConstructorDecl paramCons =
+        d_solver.mkDatatypeConstructorDecl("cons");
+    DatatypeConstructorDecl paramNil =
+        d_solver.mkDatatypeConstructorDecl("nil");
+    paramCons.addSelector("head", sort);
+    paramDtypeSpec.addConstructor(paramCons);
+    paramDtypeSpec.addConstructor(paramNil);
+    return d_solver.mkDatatypeSort(paramDtypeSpec);
+  }
+};
+
+TEST_F(TestApiBlackSort, operators_comparison)
+{
+  ASSERT_NO_THROW(d_solver.getIntegerSort() == Sort());
+  ASSERT_NO_THROW(d_solver.getIntegerSort() != Sort());
+  ASSERT_NO_THROW(d_solver.getIntegerSort() < Sort());
+  ASSERT_NO_THROW(d_solver.getIntegerSort() <= Sort());
+  ASSERT_NO_THROW(d_solver.getIntegerSort() > Sort());
+  ASSERT_NO_THROW(d_solver.getIntegerSort() >= Sort());
+}
+
+TEST_F(TestApiBlackSort, isNull)
+{
+  Sort x;
+  ASSERT_TRUE(x.isNull());
+  x = d_solver.getBooleanSort();
+  ASSERT_FALSE(x.isNull());
+}
+
+TEST_F(TestApiBlackSort, isBoolean)
+{
+  ASSERT_TRUE(d_solver.getBooleanSort().isBoolean());
+  ASSERT_NO_THROW(Sort().isBoolean());
+}
+
+TEST_F(TestApiBlackSort, isInteger)
+{
+  ASSERT_TRUE(d_solver.getIntegerSort().isInteger());
+  ASSERT_TRUE(!d_solver.getRealSort().isInteger());
+  ASSERT_NO_THROW(Sort().isInteger());
+}
+
+TEST_F(TestApiBlackSort, isReal)
+{
+  ASSERT_TRUE(d_solver.getRealSort().isReal());
+  ASSERT_TRUE(!d_solver.getIntegerSort().isReal());
+  ASSERT_NO_THROW(Sort().isReal());
+}
+
+TEST_F(TestApiBlackSort, isString)
+{
+  ASSERT_TRUE(d_solver.getStringSort().isString());
+  ASSERT_NO_THROW(Sort().isString());
+}
+
+TEST_F(TestApiBlackSort, isRegExp)
+{
+  ASSERT_TRUE(d_solver.getRegExpSort().isRegExp());
+  ASSERT_NO_THROW(Sort().isRegExp());
+}
+
+TEST_F(TestApiBlackSort, isRoundingMode)
+{
+  ASSERT_TRUE(d_solver.getRoundingModeSort().isRoundingMode());
+  ASSERT_NO_THROW(Sort().isRoundingMode());
+}
+
+TEST_F(TestApiBlackSort, isBitVector)
+{
+  ASSERT_TRUE(d_solver.mkBitVectorSort(8).isBitVector());
+  ASSERT_NO_THROW(Sort().isBitVector());
+}
+
+TEST_F(TestApiBlackSort, isFloatingPoint)
+{
+  ASSERT_TRUE(d_solver.mkFloatingPointSort(8, 24).isFloatingPoint());
+  ASSERT_NO_THROW(Sort().isFloatingPoint());
+}
+
+TEST_F(TestApiBlackSort, isDatatype)
+{
+  Sort dt_sort = create_datatype_sort();
+  ASSERT_TRUE(dt_sort.isDatatype());
+  ASSERT_NO_THROW(Sort().isDatatype());
+}
+
+TEST_F(TestApiBlackSort, isParametricDatatype)
+{
+  Sort param_dt_sort = create_param_datatype_sort();
+  ASSERT_TRUE(param_dt_sort.isParametricDatatype());
+  ASSERT_NO_THROW(Sort().isParametricDatatype());
+}
+
+TEST_F(TestApiBlackSort, isConstructor)
+{
+  Sort dt_sort = create_datatype_sort();
+  Datatype dt = dt_sort.getDatatype();
+  Sort cons_sort = dt[0].getConstructorTerm().getSort();
+  ASSERT_TRUE(cons_sort.isConstructor());
+  ASSERT_NO_THROW(Sort().isConstructor());
+}
+
+TEST_F(TestApiBlackSort, isSelector)
+{
+  Sort dt_sort = create_datatype_sort();
+  Datatype dt = dt_sort.getDatatype();
+  Sort cons_sort = dt[0][1].getSelectorTerm().getSort();
+  ASSERT_TRUE(cons_sort.isSelector());
+  ASSERT_NO_THROW(Sort().isSelector());
+}
+
+TEST_F(TestApiBlackSort, isTester)
+{
+  Sort dt_sort = create_datatype_sort();
+  Datatype dt = dt_sort.getDatatype();
+  Sort testerSort = dt[0].getTesterTerm().getSort();
+  ASSERT_TRUE(testerSort.isTester());
+  ASSERT_NO_THROW(Sort().isTester());
+}
+
+TEST_F(TestApiBlackSort, isUpdater)
+{
+  Sort dt_sort = create_datatype_sort();
+  Datatype dt = dt_sort.getDatatype();
+  Sort updaterSort = dt[0][0].getUpdaterTerm().getSort();
+  ASSERT_TRUE(updaterSort.isUpdater());
+  ASSERT_NO_THROW(Sort().isUpdater());
+}
+
+TEST_F(TestApiBlackSort, isFunction)
+{
+  Sort fun_sort = d_solver.mkFunctionSort(d_solver.getRealSort(),
+                                          d_solver.getIntegerSort());
+  ASSERT_TRUE(fun_sort.isFunction());
+  ASSERT_NO_THROW(Sort().isFunction());
+}
+
+TEST_F(TestApiBlackSort, isPredicate)
+{
+  Sort pred_sort = d_solver.mkPredicateSort({d_solver.getRealSort()});
+  ASSERT_TRUE(pred_sort.isPredicate());
+  ASSERT_NO_THROW(Sort().isPredicate());
+}
+
+TEST_F(TestApiBlackSort, isTuple)
+{
+  Sort tup_sort = d_solver.mkTupleSort({d_solver.getRealSort()});
+  ASSERT_TRUE(tup_sort.isTuple());
+  ASSERT_NO_THROW(Sort().isTuple());
+}
+
+TEST_F(TestApiBlackSort, isRecord)
+{
+  Sort rec_sort =
+      d_solver.mkRecordSort({std::make_pair("asdf", d_solver.getRealSort())});
+  ASSERT_TRUE(rec_sort.isRecord());
+  ASSERT_NO_THROW(Sort().isRecord());
+}
+
+TEST_F(TestApiBlackSort, isArray)
+{
+  Sort arr_sort =
+      d_solver.mkArraySort(d_solver.getRealSort(), d_solver.getIntegerSort());
+  ASSERT_TRUE(arr_sort.isArray());
+  ASSERT_NO_THROW(Sort().isArray());
+}
+
+TEST_F(TestApiBlackSort, isSet)
+{
+  Sort set_sort = d_solver.mkSetSort(d_solver.getRealSort());
+  ASSERT_TRUE(set_sort.isSet());
+  ASSERT_NO_THROW(Sort().isSet());
+}
+
+TEST_F(TestApiBlackSort, isBag)
+{
+  Sort bag_sort = d_solver.mkBagSort(d_solver.getRealSort());
+  ASSERT_TRUE(bag_sort.isBag());
+  ASSERT_NO_THROW(Sort().isBag());
+}
+
+TEST_F(TestApiBlackSort, isSequence)
+{
+  Sort seq_sort = d_solver.mkSequenceSort(d_solver.getRealSort());
+  ASSERT_TRUE(seq_sort.isSequence());
+  ASSERT_NO_THROW(Sort().isSequence());
+}
+
+TEST_F(TestApiBlackSort, isUninterpreted)
+{
+  Sort un_sort = d_solver.mkUninterpretedSort("asdf");
+  ASSERT_TRUE(un_sort.isUninterpretedSort());
+  ASSERT_NO_THROW(Sort().isUninterpretedSort());
+}
+
+TEST_F(TestApiBlackSort, isSortConstructor)
+{
+  Sort sc_sort = d_solver.mkSortConstructorSort("asdf", 1);
+  ASSERT_TRUE(sc_sort.isSortConstructor());
+  ASSERT_NO_THROW(Sort().isSortConstructor());
+}
+
+TEST_F(TestApiBlackSort, isFirstClass)
+{
+  Sort fun_sort = d_solver.mkFunctionSort(d_solver.getRealSort(),
+                                          d_solver.getIntegerSort());
+  ASSERT_TRUE(d_solver.getIntegerSort().isFirstClass());
+  ASSERT_TRUE(fun_sort.isFirstClass());
+  Sort reSort = d_solver.getRegExpSort();
+  ASSERT_FALSE(reSort.isFirstClass());
+  ASSERT_NO_THROW(Sort().isFirstClass());
+}
+
+TEST_F(TestApiBlackSort, isFunctionLike)
+{
+  Sort fun_sort = d_solver.mkFunctionSort(d_solver.getRealSort(),
+                                          d_solver.getIntegerSort());
+  ASSERT_FALSE(d_solver.getIntegerSort().isFunctionLike());
+  ASSERT_TRUE(fun_sort.isFunctionLike());
+
+  Sort dt_sort = create_datatype_sort();
+  Datatype dt = dt_sort.getDatatype();
+  Sort cons_sort = dt[0][1].getSelectorTerm().getSort();
+  ASSERT_TRUE(cons_sort.isFunctionLike());
+
+  ASSERT_NO_THROW(Sort().isFunctionLike());
+}
+
+TEST_F(TestApiBlackSort, isSubsortOf)
+{
+  ASSERT_TRUE(d_solver.getIntegerSort().isSubsortOf(d_solver.getIntegerSort()));
+  ASSERT_TRUE(d_solver.getIntegerSort().isSubsortOf(d_solver.getRealSort()));
+  ASSERT_FALSE(
+      d_solver.getIntegerSort().isSubsortOf(d_solver.getBooleanSort()));
+  ASSERT_NO_THROW(Sort().isSubsortOf(Sort()));
+}
+
+TEST_F(TestApiBlackSort, isComparableTo)
+{
+  ASSERT_TRUE(
+      d_solver.getIntegerSort().isComparableTo(d_solver.getIntegerSort()));
+  ASSERT_TRUE(d_solver.getIntegerSort().isComparableTo(d_solver.getRealSort()));
+  ASSERT_FALSE(
+      d_solver.getIntegerSort().isComparableTo(d_solver.getBooleanSort()));
+  ASSERT_NO_THROW(Sort().isComparableTo(Sort()));
+}
+
+TEST_F(TestApiBlackSort, getDatatype)
+{
+  Sort dtypeSort = create_datatype_sort();
+  ASSERT_NO_THROW(dtypeSort.getDatatype());
+  // create bv sort, check should fail
+  Sort bvSort = d_solver.mkBitVectorSort(32);
+  ASSERT_THROW(bvSort.getDatatype(), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSort, datatypeSorts)
+{
+  Sort intSort = d_solver.getIntegerSort();
+  Sort dtypeSort = create_datatype_sort();
+  Datatype dt = dtypeSort.getDatatype();
+  ASSERT_FALSE(dtypeSort.isConstructor());
+  ASSERT_THROW(dtypeSort.getConstructorCodomainSort(), CVC5ApiException);
+  ASSERT_THROW(dtypeSort.getConstructorDomainSorts(), CVC5ApiException);
+  ASSERT_THROW(dtypeSort.getConstructorArity(), CVC5ApiException);
+
+  // get constructor
+  DatatypeConstructor dcons = dt[0];
+  Term consTerm = dcons.getConstructorTerm();
+  Sort consSort = consTerm.getSort();
+  ASSERT_TRUE(consSort.isConstructor());
+  ASSERT_FALSE(consSort.isTester());
+  ASSERT_FALSE(consSort.isSelector());
+  ASSERT_EQ(consSort.getConstructorArity(), 2);
+  std::vector<Sort> consDomSorts = consSort.getConstructorDomainSorts();
+  ASSERT_EQ(consDomSorts[0], intSort);
+  ASSERT_EQ(consDomSorts[1], dtypeSort);
+  ASSERT_EQ(consSort.getConstructorCodomainSort(), dtypeSort);
+
+  // get tester
+  Term isConsTerm = dcons.getTesterTerm();
+  ASSERT_TRUE(isConsTerm.getSort().isTester());
+  ASSERT_EQ(isConsTerm.getSort().getTesterDomainSort(), dtypeSort);
+  Sort booleanSort = d_solver.getBooleanSort();
+  ASSERT_EQ(isConsTerm.getSort().getTesterCodomainSort(), booleanSort);
+  ASSERT_THROW(booleanSort.getTesterDomainSort(), CVC5ApiException);
+  ASSERT_THROW(booleanSort.getTesterCodomainSort(), CVC5ApiException);
+
+  // get selector
+  DatatypeSelector dselTail = dcons[1];
+  Term tailTerm = dselTail.getSelectorTerm();
+  ASSERT_TRUE(tailTerm.getSort().isSelector());
+  ASSERT_EQ(tailTerm.getSort().getSelectorDomainSort(), dtypeSort);
+  ASSERT_EQ(tailTerm.getSort().getSelectorCodomainSort(), dtypeSort);
+  ASSERT_THROW(booleanSort.getSelectorDomainSort(), CVC5ApiException);
+  ASSERT_THROW(booleanSort.getSelectorCodomainSort(), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSort, instantiate)
+{
+  // instantiate parametric datatype, check should not fail
+  Sort paramDtypeSort = create_param_datatype_sort();
+  ASSERT_NO_THROW(
+      paramDtypeSort.instantiate(std::vector<Sort>{d_solver.getIntegerSort()}));
+  // instantiate non-parametric datatype sort, check should fail
+  DatatypeDecl dtypeSpec = d_solver.mkDatatypeDecl("list");
+  DatatypeConstructorDecl cons = d_solver.mkDatatypeConstructorDecl("cons");
+  cons.addSelector("head", d_solver.getIntegerSort());
+  dtypeSpec.addConstructor(cons);
+  DatatypeConstructorDecl nil = d_solver.mkDatatypeConstructorDecl("nil");
+  dtypeSpec.addConstructor(nil);
+  Sort dtypeSort = d_solver.mkDatatypeSort(dtypeSpec);
+  ASSERT_THROW(
+      dtypeSort.instantiate(std::vector<Sort>{d_solver.getIntegerSort()}),
+      CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSort, getFunctionArity)
+{
+  Sort funSort = d_solver.mkFunctionSort(d_solver.mkUninterpretedSort("u"),
+                                         d_solver.getIntegerSort());
+  ASSERT_NO_THROW(funSort.getFunctionArity());
+  Sort bvSort = d_solver.mkBitVectorSort(32);
+  ASSERT_THROW(bvSort.getFunctionArity(), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSort, getFunctionDomainSorts)
+{
+  Sort funSort = d_solver.mkFunctionSort(d_solver.mkUninterpretedSort("u"),
+                                         d_solver.getIntegerSort());
+  ASSERT_NO_THROW(funSort.getFunctionDomainSorts());
+  Sort bvSort = d_solver.mkBitVectorSort(32);
+  ASSERT_THROW(bvSort.getFunctionDomainSorts(), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSort, getFunctionCodomainSort)
+{
+  Sort funSort = d_solver.mkFunctionSort(d_solver.mkUninterpretedSort("u"),
+                                         d_solver.getIntegerSort());
+  ASSERT_NO_THROW(funSort.getFunctionCodomainSort());
+  Sort bvSort = d_solver.mkBitVectorSort(32);
+  ASSERT_THROW(bvSort.getFunctionCodomainSort(), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSort, getArrayIndexSort)
+{
+  Sort elementSort = d_solver.mkBitVectorSort(32);
+  Sort indexSort = d_solver.mkBitVectorSort(32);
+  Sort arraySort = d_solver.mkArraySort(indexSort, elementSort);
+  ASSERT_NO_THROW(arraySort.getArrayIndexSort());
+  ASSERT_THROW(indexSort.getArrayIndexSort(), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSort, getArrayElementSort)
+{
+  Sort elementSort = d_solver.mkBitVectorSort(32);
+  Sort indexSort = d_solver.mkBitVectorSort(32);
+  Sort arraySort = d_solver.mkArraySort(indexSort, elementSort);
+  ASSERT_NO_THROW(arraySort.getArrayElementSort());
+  ASSERT_THROW(indexSort.getArrayElementSort(), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSort, getSetElementSort)
+{
+  Sort setSort = d_solver.mkSetSort(d_solver.getIntegerSort());
+  ASSERT_NO_THROW(setSort.getSetElementSort());
+  Sort elementSort = setSort.getSetElementSort();
+  ASSERT_EQ(elementSort, d_solver.getIntegerSort());
+  Sort bvSort = d_solver.mkBitVectorSort(32);
+  ASSERT_THROW(bvSort.getSetElementSort(), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSort, getBagElementSort)
+{
+  Sort bagSort = d_solver.mkBagSort(d_solver.getIntegerSort());
+  ASSERT_NO_THROW(bagSort.getBagElementSort());
+  Sort elementSort = bagSort.getBagElementSort();
+  ASSERT_EQ(elementSort, d_solver.getIntegerSort());
+  Sort bvSort = d_solver.mkBitVectorSort(32);
+  ASSERT_THROW(bvSort.getBagElementSort(), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSort, getSequenceElementSort)
+{
+  Sort seqSort = d_solver.mkSequenceSort(d_solver.getIntegerSort());
+  ASSERT_TRUE(seqSort.isSequence());
+  ASSERT_NO_THROW(seqSort.getSequenceElementSort());
+  Sort bvSort = d_solver.mkBitVectorSort(32);
+  ASSERT_FALSE(bvSort.isSequence());
+  ASSERT_THROW(bvSort.getSequenceElementSort(), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSort, getUninterpretedSortName)
+{
+  Sort uSort = d_solver.mkUninterpretedSort("u");
+  ASSERT_NO_THROW(uSort.getUninterpretedSortName());
+  Sort bvSort = d_solver.mkBitVectorSort(32);
+  ASSERT_THROW(bvSort.getUninterpretedSortName(), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSort, isUninterpretedSortParameterized)
+{
+  Sort uSort = d_solver.mkUninterpretedSort("u");
+  ASSERT_FALSE(uSort.isUninterpretedSortParameterized());
+  Sort sSort = d_solver.mkSortConstructorSort("s", 1);
+  Sort siSort = sSort.instantiate({uSort});
+  ASSERT_TRUE(siSort.isUninterpretedSortParameterized());
+  Sort bvSort = d_solver.mkBitVectorSort(32);
+  ASSERT_THROW(bvSort.isUninterpretedSortParameterized(), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSort, getUninterpretedSortParamSorts)
+{
+  Sort uSort = d_solver.mkUninterpretedSort("u");
+  ASSERT_NO_THROW(uSort.getUninterpretedSortParamSorts());
+  Sort sSort = d_solver.mkSortConstructorSort("s", 2);
+  Sort siSort = sSort.instantiate({uSort, uSort});
+  ASSERT_EQ(siSort.getUninterpretedSortParamSorts().size(), 2);
+  Sort bvSort = d_solver.mkBitVectorSort(32);
+  ASSERT_THROW(bvSort.getUninterpretedSortParamSorts(), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSort, getUninterpretedSortConstructorName)
+{
+  Sort sSort = d_solver.mkSortConstructorSort("s", 2);
+  ASSERT_NO_THROW(sSort.getSortConstructorName());
+  Sort bvSort = d_solver.mkBitVectorSort(32);
+  ASSERT_THROW(bvSort.getSortConstructorName(), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSort, getUninterpretedSortConstructorArity)
+{
+  Sort sSort = d_solver.mkSortConstructorSort("s", 2);
+  ASSERT_NO_THROW(sSort.getSortConstructorArity());
+  Sort bvSort = d_solver.mkBitVectorSort(32);
+  ASSERT_THROW(bvSort.getSortConstructorArity(), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSort, getBitVectorSize)
+{
+  Sort bvSort = d_solver.mkBitVectorSort(32);
+  ASSERT_NO_THROW(bvSort.getBitVectorSize());
+  Sort setSort = d_solver.mkSetSort(d_solver.getIntegerSort());
+  ASSERT_THROW(setSort.getBitVectorSize(), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSort, getFloatingPointExponentSize)
+{
+  Sort fpSort = d_solver.mkFloatingPointSort(4, 8);
+  ASSERT_NO_THROW(fpSort.getFloatingPointExponentSize());
+  Sort setSort = d_solver.mkSetSort(d_solver.getIntegerSort());
+  ASSERT_THROW(setSort.getFloatingPointExponentSize(), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSort, getFloatingPointSignificandSize)
+{
+  Sort fpSort = d_solver.mkFloatingPointSort(4, 8);
+  ASSERT_NO_THROW(fpSort.getFloatingPointSignificandSize());
+  Sort setSort = d_solver.mkSetSort(d_solver.getIntegerSort());
+  ASSERT_THROW(setSort.getFloatingPointSignificandSize(), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSort, getDatatypeParamSorts)
+{
+  // create parametric datatype, check should not fail
+  Sort sort = d_solver.mkParamSort("T");
+  DatatypeDecl paramDtypeSpec = d_solver.mkDatatypeDecl("paramlist", sort);
+  DatatypeConstructorDecl paramCons =
+      d_solver.mkDatatypeConstructorDecl("cons");
+  DatatypeConstructorDecl paramNil = d_solver.mkDatatypeConstructorDecl("nil");
+  paramCons.addSelector("head", sort);
+  paramDtypeSpec.addConstructor(paramCons);
+  paramDtypeSpec.addConstructor(paramNil);
+  Sort paramDtypeSort = d_solver.mkDatatypeSort(paramDtypeSpec);
+  ASSERT_NO_THROW(paramDtypeSort.getDatatypeParamSorts());
+  // create non-parametric datatype sort, check should fail
+  DatatypeDecl dtypeSpec = d_solver.mkDatatypeDecl("list");
+  DatatypeConstructorDecl cons = d_solver.mkDatatypeConstructorDecl("cons");
+  cons.addSelector("head", d_solver.getIntegerSort());
+  dtypeSpec.addConstructor(cons);
+  DatatypeConstructorDecl nil = d_solver.mkDatatypeConstructorDecl("nil");
+  dtypeSpec.addConstructor(nil);
+  Sort dtypeSort = d_solver.mkDatatypeSort(dtypeSpec);
+  ASSERT_THROW(dtypeSort.getDatatypeParamSorts(), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSort, getDatatypeArity)
+{
+  // create datatype sort, check should not fail
+  DatatypeDecl dtypeSpec = d_solver.mkDatatypeDecl("list");
+  DatatypeConstructorDecl cons = d_solver.mkDatatypeConstructorDecl("cons");
+  cons.addSelector("head", d_solver.getIntegerSort());
+  dtypeSpec.addConstructor(cons);
+  DatatypeConstructorDecl nil = d_solver.mkDatatypeConstructorDecl("nil");
+  dtypeSpec.addConstructor(nil);
+  Sort dtypeSort = d_solver.mkDatatypeSort(dtypeSpec);
+  ASSERT_NO_THROW(dtypeSort.getDatatypeArity());
+  // create bv sort, check should fail
+  Sort bvSort = d_solver.mkBitVectorSort(32);
+  ASSERT_THROW(bvSort.getDatatypeArity(), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSort, getTupleLength)
+{
+  Sort tupleSort = d_solver.mkTupleSort(
+      {d_solver.getIntegerSort(), d_solver.getIntegerSort()});
+  ASSERT_NO_THROW(tupleSort.getTupleLength());
+  Sort bvSort = d_solver.mkBitVectorSort(32);
+  ASSERT_THROW(bvSort.getTupleLength(), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSort, getTupleSorts)
+{
+  Sort tupleSort = d_solver.mkTupleSort(
+      {d_solver.getIntegerSort(), d_solver.getIntegerSort()});
+  ASSERT_NO_THROW(tupleSort.getTupleSorts());
+  Sort bvSort = d_solver.mkBitVectorSort(32);
+  ASSERT_THROW(bvSort.getTupleSorts(), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackSort, sortCompare)
+{
+  Sort boolSort = d_solver.getBooleanSort();
+  Sort intSort = d_solver.getIntegerSort();
+  Sort bvSort = d_solver.mkBitVectorSort(32);
+  Sort bvSort2 = d_solver.mkBitVectorSort(32);
+  ASSERT_TRUE(bvSort >= bvSort2);
+  ASSERT_TRUE(bvSort <= bvSort2);
+  ASSERT_TRUE((intSort > boolSort) != (intSort < boolSort));
+  ASSERT_TRUE((intSort > bvSort || intSort == bvSort) == (intSort >= bvSort));
+}
+
+TEST_F(TestApiBlackSort, sortSubtyping)
+{
+  Sort intSort = d_solver.getIntegerSort();
+  Sort realSort = d_solver.getRealSort();
+  ASSERT_TRUE(intSort.isSubsortOf(realSort));
+  ASSERT_FALSE(realSort.isSubsortOf(intSort));
+  ASSERT_TRUE(intSort.isComparableTo(realSort));
+  ASSERT_TRUE(realSort.isComparableTo(intSort));
+
+  Sort arraySortII = d_solver.mkArraySort(intSort, intSort);
+  Sort arraySortIR = d_solver.mkArraySort(intSort, realSort);
+  ASSERT_FALSE(arraySortII.isComparableTo(intSort));
+  // we do not support subtyping for arrays
+  ASSERT_FALSE(arraySortII.isComparableTo(arraySortIR));
+
+  Sort setSortI = d_solver.mkSetSort(intSort);
+  Sort setSortR = d_solver.mkSetSort(realSort);
+  // we don't support subtyping for sets
+  ASSERT_FALSE(setSortI.isComparableTo(setSortR));
+  ASSERT_FALSE(setSortI.isSubsortOf(setSortR));
+  ASSERT_FALSE(setSortR.isComparableTo(setSortI));
+  ASSERT_FALSE(setSortR.isSubsortOf(setSortI));
+}
+
+TEST_F(TestApiBlackSort, sortScopedToString)
+{
+  std::string name = "uninterp-sort";
+  Sort bvsort8 = d_solver.mkBitVectorSort(8);
+  Sort uninterp_sort = d_solver.mkUninterpretedSort(name);
+  ASSERT_EQ(bvsort8.toString(), "(_ BitVec 8)");
+  ASSERT_EQ(uninterp_sort.toString(), name);
+  Solver solver2;
+  ASSERT_EQ(bvsort8.toString(), "(_ BitVec 8)");
+  ASSERT_EQ(uninterp_sort.toString(), name);
+}
+
+}  // namespace test
+}  // namespace cvc5
diff --git a/test/unit/api/cpp/term_black.cpp b/test/unit/api/cpp/term_black.cpp
new file mode 100644 (file)
index 0000000..f4180aa
--- /dev/null
@@ -0,0 +1,1112 @@
+/******************************************************************************
+ * Top contributors (to current version):
+ *   Aina Niemetz, Makai Mann, Andrew Reynolds
+ *
+ * This file is part of the cvc5 project.
+ *
+ * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
+ * in the top-level source directory and their institutional affiliations.
+ * All rights reserved.  See the file COPYING in the top-level source
+ * directory for licensing information.
+ * ****************************************************************************
+ *
+ * Black box testing of the Term class.
+ */
+
+#include "test_api.h"
+
+namespace cvc5 {
+
+using namespace api;
+
+namespace test {
+
+class TestApiBlackTerm : public TestApi
+{
+};
+
+TEST_F(TestApiBlackTerm, eq)
+{
+  Sort uSort = d_solver.mkUninterpretedSort("u");
+  Term x = d_solver.mkVar(uSort, "x");
+  Term y = d_solver.mkVar(uSort, "y");
+  Term z;
+
+  ASSERT_TRUE(x == x);
+  ASSERT_FALSE(x != x);
+  ASSERT_FALSE(x == y);
+  ASSERT_TRUE(x != y);
+  ASSERT_FALSE((x == z));
+  ASSERT_TRUE(x != z);
+}
+
+TEST_F(TestApiBlackTerm, getId)
+{
+  Term n;
+  ASSERT_THROW(n.getId(), CVC5ApiException);
+  Term x = d_solver.mkVar(d_solver.getIntegerSort(), "x");
+  ASSERT_NO_THROW(x.getId());
+  Term y = x;
+  ASSERT_EQ(x.getId(), y.getId());
+
+  Term z = d_solver.mkVar(d_solver.getIntegerSort(), "z");
+  ASSERT_NE(x.getId(), z.getId());
+}
+
+TEST_F(TestApiBlackTerm, getKind)
+{
+  Sort uSort = d_solver.mkUninterpretedSort("u");
+  Sort intSort = d_solver.getIntegerSort();
+  Sort boolSort = d_solver.getBooleanSort();
+  Sort funSort1 = d_solver.mkFunctionSort(uSort, intSort);
+  Sort funSort2 = d_solver.mkFunctionSort(intSort, boolSort);
+
+  Term n;
+  ASSERT_THROW(n.getKind(), CVC5ApiException);
+  Term x = d_solver.mkVar(uSort, "x");
+  ASSERT_NO_THROW(x.getKind());
+  Term y = d_solver.mkVar(uSort, "y");
+  ASSERT_NO_THROW(y.getKind());
+
+  Term f = d_solver.mkVar(funSort1, "f");
+  ASSERT_NO_THROW(f.getKind());
+  Term p = d_solver.mkVar(funSort2, "p");
+  ASSERT_NO_THROW(p.getKind());
+
+  Term zero = d_solver.mkInteger(0);
+  ASSERT_NO_THROW(zero.getKind());
+
+  Term f_x = d_solver.mkTerm(APPLY_UF, f, x);
+  ASSERT_NO_THROW(f_x.getKind());
+  Term f_y = d_solver.mkTerm(APPLY_UF, f, y);
+  ASSERT_NO_THROW(f_y.getKind());
+  Term sum = d_solver.mkTerm(PLUS, f_x, f_y);
+  ASSERT_NO_THROW(sum.getKind());
+  Term p_0 = d_solver.mkTerm(APPLY_UF, p, zero);
+  ASSERT_NO_THROW(p_0.getKind());
+  Term p_f_y = d_solver.mkTerm(APPLY_UF, p, f_y);
+  ASSERT_NO_THROW(p_f_y.getKind());
+
+  // Sequence kinds do not exist internally, test that the API properly
+  // converts them back.
+  Sort seqSort = d_solver.mkSequenceSort(intSort);
+  Term s = d_solver.mkConst(seqSort, "s");
+  Term ss = d_solver.mkTerm(SEQ_CONCAT, s, s);
+  ASSERT_EQ(ss.getKind(), SEQ_CONCAT);
+}
+
+TEST_F(TestApiBlackTerm, getSort)
+{
+  Sort bvSort = d_solver.mkBitVectorSort(8);
+  Sort intSort = d_solver.getIntegerSort();
+  Sort boolSort = d_solver.getBooleanSort();
+  Sort funSort1 = d_solver.mkFunctionSort(bvSort, intSort);
+  Sort funSort2 = d_solver.mkFunctionSort(intSort, boolSort);
+
+  Term n;
+  ASSERT_THROW(n.getSort(), CVC5ApiException);
+  Term x = d_solver.mkVar(bvSort, "x");
+  ASSERT_NO_THROW(x.getSort());
+  ASSERT_EQ(x.getSort(), bvSort);
+  Term y = d_solver.mkVar(bvSort, "y");
+  ASSERT_NO_THROW(y.getSort());
+  ASSERT_EQ(y.getSort(), bvSort);
+
+  Term f = d_solver.mkVar(funSort1, "f");
+  ASSERT_NO_THROW(f.getSort());
+  ASSERT_EQ(f.getSort(), funSort1);
+  Term p = d_solver.mkVar(funSort2, "p");
+  ASSERT_NO_THROW(p.getSort());
+  ASSERT_EQ(p.getSort(), funSort2);
+
+  Term zero = d_solver.mkInteger(0);
+  ASSERT_NO_THROW(zero.getSort());
+  ASSERT_EQ(zero.getSort(), intSort);
+
+  Term f_x = d_solver.mkTerm(APPLY_UF, f, x);
+  ASSERT_NO_THROW(f_x.getSort());
+  ASSERT_EQ(f_x.getSort(), intSort);
+  Term f_y = d_solver.mkTerm(APPLY_UF, f, y);
+  ASSERT_NO_THROW(f_y.getSort());
+  ASSERT_EQ(f_y.getSort(), intSort);
+  Term sum = d_solver.mkTerm(PLUS, f_x, f_y);
+  ASSERT_NO_THROW(sum.getSort());
+  ASSERT_EQ(sum.getSort(), intSort);
+  Term p_0 = d_solver.mkTerm(APPLY_UF, p, zero);
+  ASSERT_NO_THROW(p_0.getSort());
+  ASSERT_EQ(p_0.getSort(), boolSort);
+  Term p_f_y = d_solver.mkTerm(APPLY_UF, p, f_y);
+  ASSERT_NO_THROW(p_f_y.getSort());
+  ASSERT_EQ(p_f_y.getSort(), boolSort);
+}
+
+TEST_F(TestApiBlackTerm, getOp)
+{
+  Sort intsort = d_solver.getIntegerSort();
+  Sort bvsort = d_solver.mkBitVectorSort(8);
+  Sort arrsort = d_solver.mkArraySort(bvsort, intsort);
+  Sort funsort = d_solver.mkFunctionSort(intsort, bvsort);
+
+  Term x = d_solver.mkConst(intsort, "x");
+  Term a = d_solver.mkConst(arrsort, "a");
+  Term b = d_solver.mkConst(bvsort, "b");
+
+  ASSERT_FALSE(x.hasOp());
+  ASSERT_THROW(x.getOp(), CVC5ApiException);
+
+  Term ab = d_solver.mkTerm(SELECT, a, b);
+  Op ext = d_solver.mkOp(BITVECTOR_EXTRACT, 4, 0);
+  Term extb = d_solver.mkTerm(ext, b);
+
+  ASSERT_TRUE(ab.hasOp());
+  ASSERT_FALSE(ab.getOp().isIndexed());
+  // can compare directly to a Kind (will invoke Op constructor)
+  ASSERT_TRUE(extb.hasOp());
+  ASSERT_TRUE(extb.getOp().isIndexed());
+  ASSERT_EQ(extb.getOp(), ext);
+
+  Term f = d_solver.mkConst(funsort, "f");
+  Term fx = d_solver.mkTerm(APPLY_UF, f, x);
+
+  ASSERT_FALSE(f.hasOp());
+  ASSERT_THROW(f.getOp(), CVC5ApiException);
+  ASSERT_TRUE(fx.hasOp());
+  std::vector<Term> children(fx.begin(), fx.end());
+  // testing rebuild from op and children
+  ASSERT_EQ(fx, d_solver.mkTerm(fx.getOp(), children));
+
+  // Test Datatypes Ops
+  Sort sort = d_solver.mkParamSort("T");
+  DatatypeDecl listDecl = d_solver.mkDatatypeDecl("paramlist", sort);
+  DatatypeConstructorDecl cons = d_solver.mkDatatypeConstructorDecl("cons");
+  DatatypeConstructorDecl nil = d_solver.mkDatatypeConstructorDecl("nil");
+  cons.addSelector("head", sort);
+  cons.addSelectorSelf("tail");
+  listDecl.addConstructor(cons);
+  listDecl.addConstructor(nil);
+  Sort listSort = d_solver.mkDatatypeSort(listDecl);
+  Sort intListSort =
+      listSort.instantiate(std::vector<Sort>{d_solver.getIntegerSort()});
+  Term c = d_solver.mkConst(intListSort, "c");
+  Datatype list = listSort.getDatatype();
+  // list datatype constructor and selector operator terms
+  Term consOpTerm = list.getConstructorTerm("cons");
+  Term nilOpTerm = list.getConstructorTerm("nil");
+  Term headOpTerm = list["cons"].getSelectorTerm("head");
+  Term tailOpTerm = list["cons"].getSelectorTerm("tail");
+
+  Term nilTerm = d_solver.mkTerm(APPLY_CONSTRUCTOR, nilOpTerm);
+  Term consTerm = d_solver.mkTerm(
+      APPLY_CONSTRUCTOR, consOpTerm, d_solver.mkInteger(0), nilTerm);
+  Term headTerm = d_solver.mkTerm(APPLY_SELECTOR, headOpTerm, consTerm);
+  Term tailTerm = d_solver.mkTerm(APPLY_SELECTOR, tailOpTerm, consTerm);
+
+  ASSERT_TRUE(nilTerm.hasOp());
+  ASSERT_TRUE(consTerm.hasOp());
+  ASSERT_TRUE(headTerm.hasOp());
+  ASSERT_TRUE(tailTerm.hasOp());
+
+  // Test rebuilding
+  children.clear();
+  children.insert(children.begin(), headTerm.begin(), headTerm.end());
+  ASSERT_EQ(headTerm, d_solver.mkTerm(headTerm.getOp(), children));
+}
+
+TEST_F(TestApiBlackTerm, isNull)
+{
+  Term x;
+  ASSERT_TRUE(x.isNull());
+  x = d_solver.mkVar(d_solver.mkBitVectorSort(4), "x");
+  ASSERT_FALSE(x.isNull());
+}
+
+TEST_F(TestApiBlackTerm, notTerm)
+{
+  Sort bvSort = d_solver.mkBitVectorSort(8);
+  Sort intSort = d_solver.getIntegerSort();
+  Sort boolSort = d_solver.getBooleanSort();
+  Sort funSort1 = d_solver.mkFunctionSort(bvSort, intSort);
+  Sort funSort2 = d_solver.mkFunctionSort(intSort, boolSort);
+
+  ASSERT_THROW(Term().notTerm(), CVC5ApiException);
+  Term b = d_solver.mkTrue();
+  ASSERT_NO_THROW(b.notTerm());
+  Term x = d_solver.mkVar(d_solver.mkBitVectorSort(8), "x");
+  ASSERT_THROW(x.notTerm(), CVC5ApiException);
+  Term f = d_solver.mkVar(funSort1, "f");
+  ASSERT_THROW(f.notTerm(), CVC5ApiException);
+  Term p = d_solver.mkVar(funSort2, "p");
+  ASSERT_THROW(p.notTerm(), CVC5ApiException);
+  Term zero = d_solver.mkInteger(0);
+  ASSERT_THROW(zero.notTerm(), CVC5ApiException);
+  Term f_x = d_solver.mkTerm(APPLY_UF, f, x);
+  ASSERT_THROW(f_x.notTerm(), CVC5ApiException);
+  Term sum = d_solver.mkTerm(PLUS, f_x, f_x);
+  ASSERT_THROW(sum.notTerm(), CVC5ApiException);
+  Term p_0 = d_solver.mkTerm(APPLY_UF, p, zero);
+  ASSERT_NO_THROW(p_0.notTerm());
+  Term p_f_x = d_solver.mkTerm(APPLY_UF, p, f_x);
+  ASSERT_NO_THROW(p_f_x.notTerm());
+}
+
+TEST_F(TestApiBlackTerm, andTerm)
+{
+  Sort bvSort = d_solver.mkBitVectorSort(8);
+  Sort intSort = d_solver.getIntegerSort();
+  Sort boolSort = d_solver.getBooleanSort();
+  Sort funSort1 = d_solver.mkFunctionSort(bvSort, intSort);
+  Sort funSort2 = d_solver.mkFunctionSort(intSort, boolSort);
+
+  Term b = d_solver.mkTrue();
+  ASSERT_THROW(Term().andTerm(b), CVC5ApiException);
+  ASSERT_THROW(b.andTerm(Term()), CVC5ApiException);
+  ASSERT_NO_THROW(b.andTerm(b));
+  Term x = d_solver.mkVar(d_solver.mkBitVectorSort(8), "x");
+  ASSERT_THROW(x.andTerm(b), CVC5ApiException);
+  ASSERT_THROW(x.andTerm(x), CVC5ApiException);
+  Term f = d_solver.mkVar(funSort1, "f");
+  ASSERT_THROW(f.andTerm(b), CVC5ApiException);
+  ASSERT_THROW(f.andTerm(x), CVC5ApiException);
+  ASSERT_THROW(f.andTerm(f), CVC5ApiException);
+  Term p = d_solver.mkVar(funSort2, "p");
+  ASSERT_THROW(p.andTerm(b), CVC5ApiException);
+  ASSERT_THROW(p.andTerm(x), CVC5ApiException);
+  ASSERT_THROW(p.andTerm(f), CVC5ApiException);
+  ASSERT_THROW(p.andTerm(p), CVC5ApiException);
+  Term zero = d_solver.mkInteger(0);
+  ASSERT_THROW(zero.andTerm(b), CVC5ApiException);
+  ASSERT_THROW(zero.andTerm(x), CVC5ApiException);
+  ASSERT_THROW(zero.andTerm(f), CVC5ApiException);
+  ASSERT_THROW(zero.andTerm(p), CVC5ApiException);
+  ASSERT_THROW(zero.andTerm(zero), CVC5ApiException);
+  Term f_x = d_solver.mkTerm(APPLY_UF, f, x);
+  ASSERT_THROW(f_x.andTerm(b), CVC5ApiException);
+  ASSERT_THROW(f_x.andTerm(x), CVC5ApiException);
+  ASSERT_THROW(f_x.andTerm(f), CVC5ApiException);
+  ASSERT_THROW(f_x.andTerm(p), CVC5ApiException);
+  ASSERT_THROW(f_x.andTerm(zero), CVC5ApiException);
+  ASSERT_THROW(f_x.andTerm(f_x), CVC5ApiException);
+  Term sum = d_solver.mkTerm(PLUS, f_x, f_x);
+  ASSERT_THROW(sum.andTerm(b), CVC5ApiException);
+  ASSERT_THROW(sum.andTerm(x), CVC5ApiException);
+  ASSERT_THROW(sum.andTerm(f), CVC5ApiException);
+  ASSERT_THROW(sum.andTerm(p), CVC5ApiException);
+  ASSERT_THROW(sum.andTerm(zero), CVC5ApiException);
+  ASSERT_THROW(sum.andTerm(f_x), CVC5ApiException);
+  ASSERT_THROW(sum.andTerm(sum), CVC5ApiException);
+  Term p_0 = d_solver.mkTerm(APPLY_UF, p, zero);
+  ASSERT_NO_THROW(p_0.andTerm(b));
+  ASSERT_THROW(p_0.andTerm(x), CVC5ApiException);
+  ASSERT_THROW(p_0.andTerm(f), CVC5ApiException);
+  ASSERT_THROW(p_0.andTerm(p), CVC5ApiException);
+  ASSERT_THROW(p_0.andTerm(zero), CVC5ApiException);
+  ASSERT_THROW(p_0.andTerm(f_x), CVC5ApiException);
+  ASSERT_THROW(p_0.andTerm(sum), CVC5ApiException);
+  ASSERT_NO_THROW(p_0.andTerm(p_0));
+  Term p_f_x = d_solver.mkTerm(APPLY_UF, p, f_x);
+  ASSERT_NO_THROW(p_f_x.andTerm(b));
+  ASSERT_THROW(p_f_x.andTerm(x), CVC5ApiException);
+  ASSERT_THROW(p_f_x.andTerm(f), CVC5ApiException);
+  ASSERT_THROW(p_f_x.andTerm(p), CVC5ApiException);
+  ASSERT_THROW(p_f_x.andTerm(zero), CVC5ApiException);
+  ASSERT_THROW(p_f_x.andTerm(f_x), CVC5ApiException);
+  ASSERT_THROW(p_f_x.andTerm(sum), CVC5ApiException);
+  ASSERT_NO_THROW(p_f_x.andTerm(p_0));
+  ASSERT_NO_THROW(p_f_x.andTerm(p_f_x));
+}
+
+TEST_F(TestApiBlackTerm, orTerm)
+{
+  Sort bvSort = d_solver.mkBitVectorSort(8);
+  Sort intSort = d_solver.getIntegerSort();
+  Sort boolSort = d_solver.getBooleanSort();
+  Sort funSort1 = d_solver.mkFunctionSort(bvSort, intSort);
+  Sort funSort2 = d_solver.mkFunctionSort(intSort, boolSort);
+
+  Term b = d_solver.mkTrue();
+  ASSERT_THROW(Term().orTerm(b), CVC5ApiException);
+  ASSERT_THROW(b.orTerm(Term()), CVC5ApiException);
+  ASSERT_NO_THROW(b.orTerm(b));
+  Term x = d_solver.mkVar(d_solver.mkBitVectorSort(8), "x");
+  ASSERT_THROW(x.orTerm(b), CVC5ApiException);
+  ASSERT_THROW(x.orTerm(x), CVC5ApiException);
+  Term f = d_solver.mkVar(funSort1, "f");
+  ASSERT_THROW(f.orTerm(b), CVC5ApiException);
+  ASSERT_THROW(f.orTerm(x), CVC5ApiException);
+  ASSERT_THROW(f.orTerm(f), CVC5ApiException);
+  Term p = d_solver.mkVar(funSort2, "p");
+  ASSERT_THROW(p.orTerm(b), CVC5ApiException);
+  ASSERT_THROW(p.orTerm(x), CVC5ApiException);
+  ASSERT_THROW(p.orTerm(f), CVC5ApiException);
+  ASSERT_THROW(p.orTerm(p), CVC5ApiException);
+  Term zero = d_solver.mkInteger(0);
+  ASSERT_THROW(zero.orTerm(b), CVC5ApiException);
+  ASSERT_THROW(zero.orTerm(x), CVC5ApiException);
+  ASSERT_THROW(zero.orTerm(f), CVC5ApiException);
+  ASSERT_THROW(zero.orTerm(p), CVC5ApiException);
+  ASSERT_THROW(zero.orTerm(zero), CVC5ApiException);
+  Term f_x = d_solver.mkTerm(APPLY_UF, f, x);
+  ASSERT_THROW(f_x.orTerm(b), CVC5ApiException);
+  ASSERT_THROW(f_x.orTerm(x), CVC5ApiException);
+  ASSERT_THROW(f_x.orTerm(f), CVC5ApiException);
+  ASSERT_THROW(f_x.orTerm(p), CVC5ApiException);
+  ASSERT_THROW(f_x.orTerm(zero), CVC5ApiException);
+  ASSERT_THROW(f_x.orTerm(f_x), CVC5ApiException);
+  Term sum = d_solver.mkTerm(PLUS, f_x, f_x);
+  ASSERT_THROW(sum.orTerm(b), CVC5ApiException);
+  ASSERT_THROW(sum.orTerm(x), CVC5ApiException);
+  ASSERT_THROW(sum.orTerm(f), CVC5ApiException);
+  ASSERT_THROW(sum.orTerm(p), CVC5ApiException);
+  ASSERT_THROW(sum.orTerm(zero), CVC5ApiException);
+  ASSERT_THROW(sum.orTerm(f_x), CVC5ApiException);
+  ASSERT_THROW(sum.orTerm(sum), CVC5ApiException);
+  Term p_0 = d_solver.mkTerm(APPLY_UF, p, zero);
+  ASSERT_NO_THROW(p_0.orTerm(b));
+  ASSERT_THROW(p_0.orTerm(x), CVC5ApiException);
+  ASSERT_THROW(p_0.orTerm(f), CVC5ApiException);
+  ASSERT_THROW(p_0.orTerm(p), CVC5ApiException);
+  ASSERT_THROW(p_0.orTerm(zero), CVC5ApiException);
+  ASSERT_THROW(p_0.orTerm(f_x), CVC5ApiException);
+  ASSERT_THROW(p_0.orTerm(sum), CVC5ApiException);
+  ASSERT_NO_THROW(p_0.orTerm(p_0));
+  Term p_f_x = d_solver.mkTerm(APPLY_UF, p, f_x);
+  ASSERT_NO_THROW(p_f_x.orTerm(b));
+  ASSERT_THROW(p_f_x.orTerm(x), CVC5ApiException);
+  ASSERT_THROW(p_f_x.orTerm(f), CVC5ApiException);
+  ASSERT_THROW(p_f_x.orTerm(p), CVC5ApiException);
+  ASSERT_THROW(p_f_x.orTerm(zero), CVC5ApiException);
+  ASSERT_THROW(p_f_x.orTerm(f_x), CVC5ApiException);
+  ASSERT_THROW(p_f_x.orTerm(sum), CVC5ApiException);
+  ASSERT_NO_THROW(p_f_x.orTerm(p_0));
+  ASSERT_NO_THROW(p_f_x.orTerm(p_f_x));
+}
+
+TEST_F(TestApiBlackTerm, xorTerm)
+{
+  Sort bvSort = d_solver.mkBitVectorSort(8);
+  Sort intSort = d_solver.getIntegerSort();
+  Sort boolSort = d_solver.getBooleanSort();
+  Sort funSort1 = d_solver.mkFunctionSort(bvSort, intSort);
+  Sort funSort2 = d_solver.mkFunctionSort(intSort, boolSort);
+
+  Term b = d_solver.mkTrue();
+  ASSERT_THROW(Term().xorTerm(b), CVC5ApiException);
+  ASSERT_THROW(b.xorTerm(Term()), CVC5ApiException);
+  ASSERT_NO_THROW(b.xorTerm(b));
+  Term x = d_solver.mkVar(d_solver.mkBitVectorSort(8), "x");
+  ASSERT_THROW(x.xorTerm(b), CVC5ApiException);
+  ASSERT_THROW(x.xorTerm(x), CVC5ApiException);
+  Term f = d_solver.mkVar(funSort1, "f");
+  ASSERT_THROW(f.xorTerm(b), CVC5ApiException);
+  ASSERT_THROW(f.xorTerm(x), CVC5ApiException);
+  ASSERT_THROW(f.xorTerm(f), CVC5ApiException);
+  Term p = d_solver.mkVar(funSort2, "p");
+  ASSERT_THROW(p.xorTerm(b), CVC5ApiException);
+  ASSERT_THROW(p.xorTerm(x), CVC5ApiException);
+  ASSERT_THROW(p.xorTerm(f), CVC5ApiException);
+  ASSERT_THROW(p.xorTerm(p), CVC5ApiException);
+  Term zero = d_solver.mkInteger(0);
+  ASSERT_THROW(zero.xorTerm(b), CVC5ApiException);
+  ASSERT_THROW(zero.xorTerm(x), CVC5ApiException);
+  ASSERT_THROW(zero.xorTerm(f), CVC5ApiException);
+  ASSERT_THROW(zero.xorTerm(p), CVC5ApiException);
+  ASSERT_THROW(zero.xorTerm(zero), CVC5ApiException);
+  Term f_x = d_solver.mkTerm(APPLY_UF, f, x);
+  ASSERT_THROW(f_x.xorTerm(b), CVC5ApiException);
+  ASSERT_THROW(f_x.xorTerm(x), CVC5ApiException);
+  ASSERT_THROW(f_x.xorTerm(f), CVC5ApiException);
+  ASSERT_THROW(f_x.xorTerm(p), CVC5ApiException);
+  ASSERT_THROW(f_x.xorTerm(zero), CVC5ApiException);
+  ASSERT_THROW(f_x.xorTerm(f_x), CVC5ApiException);
+  Term sum = d_solver.mkTerm(PLUS, f_x, f_x);
+  ASSERT_THROW(sum.xorTerm(b), CVC5ApiException);
+  ASSERT_THROW(sum.xorTerm(x), CVC5ApiException);
+  ASSERT_THROW(sum.xorTerm(f), CVC5ApiException);
+  ASSERT_THROW(sum.xorTerm(p), CVC5ApiException);
+  ASSERT_THROW(sum.xorTerm(zero), CVC5ApiException);
+  ASSERT_THROW(sum.xorTerm(f_x), CVC5ApiException);
+  ASSERT_THROW(sum.xorTerm(sum), CVC5ApiException);
+  Term p_0 = d_solver.mkTerm(APPLY_UF, p, zero);
+  ASSERT_NO_THROW(p_0.xorTerm(b));
+  ASSERT_THROW(p_0.xorTerm(x), CVC5ApiException);
+  ASSERT_THROW(p_0.xorTerm(f), CVC5ApiException);
+  ASSERT_THROW(p_0.xorTerm(p), CVC5ApiException);
+  ASSERT_THROW(p_0.xorTerm(zero), CVC5ApiException);
+  ASSERT_THROW(p_0.xorTerm(f_x), CVC5ApiException);
+  ASSERT_THROW(p_0.xorTerm(sum), CVC5ApiException);
+  ASSERT_NO_THROW(p_0.xorTerm(p_0));
+  Term p_f_x = d_solver.mkTerm(APPLY_UF, p, f_x);
+  ASSERT_NO_THROW(p_f_x.xorTerm(b));
+  ASSERT_THROW(p_f_x.xorTerm(x), CVC5ApiException);
+  ASSERT_THROW(p_f_x.xorTerm(f), CVC5ApiException);
+  ASSERT_THROW(p_f_x.xorTerm(p), CVC5ApiException);
+  ASSERT_THROW(p_f_x.xorTerm(zero), CVC5ApiException);
+  ASSERT_THROW(p_f_x.xorTerm(f_x), CVC5ApiException);
+  ASSERT_THROW(p_f_x.xorTerm(sum), CVC5ApiException);
+  ASSERT_NO_THROW(p_f_x.xorTerm(p_0));
+  ASSERT_NO_THROW(p_f_x.xorTerm(p_f_x));
+}
+
+TEST_F(TestApiBlackTerm, eqTerm)
+{
+  Sort bvSort = d_solver.mkBitVectorSort(8);
+  Sort intSort = d_solver.getIntegerSort();
+  Sort boolSort = d_solver.getBooleanSort();
+  Sort funSort1 = d_solver.mkFunctionSort(bvSort, intSort);
+  Sort funSort2 = d_solver.mkFunctionSort(intSort, boolSort);
+
+  Term b = d_solver.mkTrue();
+  ASSERT_THROW(Term().eqTerm(b), CVC5ApiException);
+  ASSERT_THROW(b.eqTerm(Term()), CVC5ApiException);
+  ASSERT_NO_THROW(b.eqTerm(b));
+  Term x = d_solver.mkVar(d_solver.mkBitVectorSort(8), "x");
+  ASSERT_THROW(x.eqTerm(b), CVC5ApiException);
+  ASSERT_NO_THROW(x.eqTerm(x));
+  Term f = d_solver.mkVar(funSort1, "f");
+  ASSERT_THROW(f.eqTerm(b), CVC5ApiException);
+  ASSERT_THROW(f.eqTerm(x), CVC5ApiException);
+  ASSERT_NO_THROW(f.eqTerm(f));
+  Term p = d_solver.mkVar(funSort2, "p");
+  ASSERT_THROW(p.eqTerm(b), CVC5ApiException);
+  ASSERT_THROW(p.eqTerm(x), CVC5ApiException);
+  ASSERT_THROW(p.eqTerm(f), CVC5ApiException);
+  ASSERT_NO_THROW(p.eqTerm(p));
+  Term zero = d_solver.mkInteger(0);
+  ASSERT_THROW(zero.eqTerm(b), CVC5ApiException);
+  ASSERT_THROW(zero.eqTerm(x), CVC5ApiException);
+  ASSERT_THROW(zero.eqTerm(f), CVC5ApiException);
+  ASSERT_THROW(zero.eqTerm(p), CVC5ApiException);
+  ASSERT_NO_THROW(zero.eqTerm(zero));
+  Term f_x = d_solver.mkTerm(APPLY_UF, f, x);
+  ASSERT_THROW(f_x.eqTerm(b), CVC5ApiException);
+  ASSERT_THROW(f_x.eqTerm(x), CVC5ApiException);
+  ASSERT_THROW(f_x.eqTerm(f), CVC5ApiException);
+  ASSERT_THROW(f_x.eqTerm(p), CVC5ApiException);
+  ASSERT_NO_THROW(f_x.eqTerm(zero));
+  ASSERT_NO_THROW(f_x.eqTerm(f_x));
+  Term sum = d_solver.mkTerm(PLUS, f_x, f_x);
+  ASSERT_THROW(sum.eqTerm(b), CVC5ApiException);
+  ASSERT_THROW(sum.eqTerm(x), CVC5ApiException);
+  ASSERT_THROW(sum.eqTerm(f), CVC5ApiException);
+  ASSERT_THROW(sum.eqTerm(p), CVC5ApiException);
+  ASSERT_NO_THROW(sum.eqTerm(zero));
+  ASSERT_NO_THROW(sum.eqTerm(f_x));
+  ASSERT_NO_THROW(sum.eqTerm(sum));
+  Term p_0 = d_solver.mkTerm(APPLY_UF, p, zero);
+  ASSERT_NO_THROW(p_0.eqTerm(b));
+  ASSERT_THROW(p_0.eqTerm(x), CVC5ApiException);
+  ASSERT_THROW(p_0.eqTerm(f), CVC5ApiException);
+  ASSERT_THROW(p_0.eqTerm(p), CVC5ApiException);
+  ASSERT_THROW(p_0.eqTerm(zero), CVC5ApiException);
+  ASSERT_THROW(p_0.eqTerm(f_x), CVC5ApiException);
+  ASSERT_THROW(p_0.eqTerm(sum), CVC5ApiException);
+  ASSERT_NO_THROW(p_0.eqTerm(p_0));
+  Term p_f_x = d_solver.mkTerm(APPLY_UF, p, f_x);
+  ASSERT_NO_THROW(p_f_x.eqTerm(b));
+  ASSERT_THROW(p_f_x.eqTerm(x), CVC5ApiException);
+  ASSERT_THROW(p_f_x.eqTerm(f), CVC5ApiException);
+  ASSERT_THROW(p_f_x.eqTerm(p), CVC5ApiException);
+  ASSERT_THROW(p_f_x.eqTerm(zero), CVC5ApiException);
+  ASSERT_THROW(p_f_x.eqTerm(f_x), CVC5ApiException);
+  ASSERT_THROW(p_f_x.eqTerm(sum), CVC5ApiException);
+  ASSERT_NO_THROW(p_f_x.eqTerm(p_0));
+  ASSERT_NO_THROW(p_f_x.eqTerm(p_f_x));
+}
+
+TEST_F(TestApiBlackTerm, impTerm)
+{
+  Sort bvSort = d_solver.mkBitVectorSort(8);
+  Sort intSort = d_solver.getIntegerSort();
+  Sort boolSort = d_solver.getBooleanSort();
+  Sort funSort1 = d_solver.mkFunctionSort(bvSort, intSort);
+  Sort funSort2 = d_solver.mkFunctionSort(intSort, boolSort);
+
+  Term b = d_solver.mkTrue();
+  ASSERT_THROW(Term().impTerm(b), CVC5ApiException);
+  ASSERT_THROW(b.impTerm(Term()), CVC5ApiException);
+  ASSERT_NO_THROW(b.impTerm(b));
+  Term x = d_solver.mkVar(d_solver.mkBitVectorSort(8), "x");
+  ASSERT_THROW(x.impTerm(b), CVC5ApiException);
+  ASSERT_THROW(x.impTerm(x), CVC5ApiException);
+  Term f = d_solver.mkVar(funSort1, "f");
+  ASSERT_THROW(f.impTerm(b), CVC5ApiException);
+  ASSERT_THROW(f.impTerm(x), CVC5ApiException);
+  ASSERT_THROW(f.impTerm(f), CVC5ApiException);
+  Term p = d_solver.mkVar(funSort2, "p");
+  ASSERT_THROW(p.impTerm(b), CVC5ApiException);
+  ASSERT_THROW(p.impTerm(x), CVC5ApiException);
+  ASSERT_THROW(p.impTerm(f), CVC5ApiException);
+  ASSERT_THROW(p.impTerm(p), CVC5ApiException);
+  Term zero = d_solver.mkInteger(0);
+  ASSERT_THROW(zero.impTerm(b), CVC5ApiException);
+  ASSERT_THROW(zero.impTerm(x), CVC5ApiException);
+  ASSERT_THROW(zero.impTerm(f), CVC5ApiException);
+  ASSERT_THROW(zero.impTerm(p), CVC5ApiException);
+  ASSERT_THROW(zero.impTerm(zero), CVC5ApiException);
+  Term f_x = d_solver.mkTerm(APPLY_UF, f, x);
+  ASSERT_THROW(f_x.impTerm(b), CVC5ApiException);
+  ASSERT_THROW(f_x.impTerm(x), CVC5ApiException);
+  ASSERT_THROW(f_x.impTerm(f), CVC5ApiException);
+  ASSERT_THROW(f_x.impTerm(p), CVC5ApiException);
+  ASSERT_THROW(f_x.impTerm(zero), CVC5ApiException);
+  ASSERT_THROW(f_x.impTerm(f_x), CVC5ApiException);
+  Term sum = d_solver.mkTerm(PLUS, f_x, f_x);
+  ASSERT_THROW(sum.impTerm(b), CVC5ApiException);
+  ASSERT_THROW(sum.impTerm(x), CVC5ApiException);
+  ASSERT_THROW(sum.impTerm(f), CVC5ApiException);
+  ASSERT_THROW(sum.impTerm(p), CVC5ApiException);
+  ASSERT_THROW(sum.impTerm(zero), CVC5ApiException);
+  ASSERT_THROW(sum.impTerm(f_x), CVC5ApiException);
+  ASSERT_THROW(sum.impTerm(sum), CVC5ApiException);
+  Term p_0 = d_solver.mkTerm(APPLY_UF, p, zero);
+  ASSERT_NO_THROW(p_0.impTerm(b));
+  ASSERT_THROW(p_0.impTerm(x), CVC5ApiException);
+  ASSERT_THROW(p_0.impTerm(f), CVC5ApiException);
+  ASSERT_THROW(p_0.impTerm(p), CVC5ApiException);
+  ASSERT_THROW(p_0.impTerm(zero), CVC5ApiException);
+  ASSERT_THROW(p_0.impTerm(f_x), CVC5ApiException);
+  ASSERT_THROW(p_0.impTerm(sum), CVC5ApiException);
+  ASSERT_NO_THROW(p_0.impTerm(p_0));
+  Term p_f_x = d_solver.mkTerm(APPLY_UF, p, f_x);
+  ASSERT_NO_THROW(p_f_x.impTerm(b));
+  ASSERT_THROW(p_f_x.impTerm(x), CVC5ApiException);
+  ASSERT_THROW(p_f_x.impTerm(f), CVC5ApiException);
+  ASSERT_THROW(p_f_x.impTerm(p), CVC5ApiException);
+  ASSERT_THROW(p_f_x.impTerm(zero), CVC5ApiException);
+  ASSERT_THROW(p_f_x.impTerm(f_x), CVC5ApiException);
+  ASSERT_THROW(p_f_x.impTerm(sum), CVC5ApiException);
+  ASSERT_NO_THROW(p_f_x.impTerm(p_0));
+  ASSERT_NO_THROW(p_f_x.impTerm(p_f_x));
+}
+
+TEST_F(TestApiBlackTerm, iteTerm)
+{
+  Sort bvSort = d_solver.mkBitVectorSort(8);
+  Sort intSort = d_solver.getIntegerSort();
+  Sort boolSort = d_solver.getBooleanSort();
+  Sort funSort1 = d_solver.mkFunctionSort(bvSort, intSort);
+  Sort funSort2 = d_solver.mkFunctionSort(intSort, boolSort);
+
+  Term b = d_solver.mkTrue();
+  ASSERT_THROW(Term().iteTerm(b, b), CVC5ApiException);
+  ASSERT_THROW(b.iteTerm(Term(), b), CVC5ApiException);
+  ASSERT_THROW(b.iteTerm(b, Term()), CVC5ApiException);
+  ASSERT_NO_THROW(b.iteTerm(b, b));
+  Term x = d_solver.mkVar(d_solver.mkBitVectorSort(8), "x");
+  ASSERT_NO_THROW(b.iteTerm(x, x));
+  ASSERT_NO_THROW(b.iteTerm(b, b));
+  ASSERT_THROW(b.iteTerm(x, b), CVC5ApiException);
+  ASSERT_THROW(x.iteTerm(x, x), CVC5ApiException);
+  ASSERT_THROW(x.iteTerm(x, b), CVC5ApiException);
+  Term f = d_solver.mkVar(funSort1, "f");
+  ASSERT_THROW(f.iteTerm(b, b), CVC5ApiException);
+  ASSERT_THROW(x.iteTerm(b, x), CVC5ApiException);
+  Term p = d_solver.mkVar(funSort2, "p");
+  ASSERT_THROW(p.iteTerm(b, b), CVC5ApiException);
+  ASSERT_THROW(p.iteTerm(x, b), CVC5ApiException);
+  Term zero = d_solver.mkInteger(0);
+  ASSERT_THROW(zero.iteTerm(x, x), CVC5ApiException);
+  ASSERT_THROW(zero.iteTerm(x, b), CVC5ApiException);
+  Term f_x = d_solver.mkTerm(APPLY_UF, f, x);
+  ASSERT_THROW(f_x.iteTerm(b, b), CVC5ApiException);
+  ASSERT_THROW(f_x.iteTerm(b, x), CVC5ApiException);
+  Term sum = d_solver.mkTerm(PLUS, f_x, f_x);
+  ASSERT_THROW(sum.iteTerm(x, x), CVC5ApiException);
+  ASSERT_THROW(sum.iteTerm(b, x), CVC5ApiException);
+  Term p_0 = d_solver.mkTerm(APPLY_UF, p, zero);
+  ASSERT_NO_THROW(p_0.iteTerm(b, b));
+  ASSERT_NO_THROW(p_0.iteTerm(x, x));
+  ASSERT_THROW(p_0.iteTerm(x, b), CVC5ApiException);
+  Term p_f_x = d_solver.mkTerm(APPLY_UF, p, f_x);
+  ASSERT_NO_THROW(p_f_x.iteTerm(b, b));
+  ASSERT_NO_THROW(p_f_x.iteTerm(x, x));
+  ASSERT_THROW(p_f_x.iteTerm(x, b), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackTerm, termAssignment)
+{
+  Term t1 = d_solver.mkInteger(1);
+  Term t2 = t1;
+  t2 = d_solver.mkInteger(2);
+  ASSERT_EQ(t1, d_solver.mkInteger(1));
+}
+
+TEST_F(TestApiBlackTerm, termCompare)
+{
+  Term t1 = d_solver.mkInteger(1);
+  Term t2 = d_solver.mkTerm(PLUS, d_solver.mkInteger(2), d_solver.mkInteger(2));
+  Term t3 = d_solver.mkTerm(PLUS, d_solver.mkInteger(2), d_solver.mkInteger(2));
+  ASSERT_TRUE(t2 >= t3);
+  ASSERT_TRUE(t2 <= t3);
+  ASSERT_TRUE((t1 > t2) != (t1 < t2));
+  ASSERT_TRUE((t1 > t2 || t1 == t2) == (t1 >= t2));
+}
+
+TEST_F(TestApiBlackTerm, termChildren)
+{
+  // simple term 2+3
+  Term two = d_solver.mkInteger(2);
+  Term t1 = d_solver.mkTerm(PLUS, two, d_solver.mkInteger(3));
+  ASSERT_EQ(t1[0], two);
+  ASSERT_EQ(t1.getNumChildren(), 2);
+  Term tnull;
+  ASSERT_THROW(tnull.getNumChildren(), CVC5ApiException);
+
+  // apply term f(2)
+  Sort intSort = d_solver.getIntegerSort();
+  Sort fsort = d_solver.mkFunctionSort(intSort, intSort);
+  Term f = d_solver.mkConst(fsort, "f");
+  Term t2 = d_solver.mkTerm(APPLY_UF, f, two);
+  // due to our higher-order view of terms, we treat f as a child of APPLY_UF
+  ASSERT_EQ(t2.getNumChildren(), 2);
+  ASSERT_EQ(t2[0], f);
+  ASSERT_EQ(t2[1], two);
+  ASSERT_THROW(tnull[0], CVC5ApiException);
+}
+
+TEST_F(TestApiBlackTerm, getInteger)
+{
+  Term int1 = d_solver.mkInteger("-18446744073709551616");
+  Term int2 = d_solver.mkInteger("-18446744073709551615");
+  Term int3 = d_solver.mkInteger("-4294967296");
+  Term int4 = d_solver.mkInteger("-4294967295");
+  Term int5 = d_solver.mkInteger("-10");
+  Term int6 = d_solver.mkInteger("0");
+  Term int7 = d_solver.mkInteger("10");
+  Term int8 = d_solver.mkInteger("4294967295");
+  Term int9 = d_solver.mkInteger("4294967296");
+  Term int10 = d_solver.mkInteger("18446744073709551615");
+  Term int11 = d_solver.mkInteger("18446744073709551616");
+  Term int12 = d_solver.mkInteger("-0");
+
+  ASSERT_THROW(d_solver.mkInteger(""), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkInteger("-"), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkInteger("-1-"), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkInteger("0.0"), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkInteger("-0.1"), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkInteger("012"), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkInteger("0000"), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkInteger("-01"), CVC5ApiException);
+  ASSERT_THROW(d_solver.mkInteger("-00"), CVC5ApiException);
+
+  ASSERT_TRUE(!int1.isInt32Value() && !int1.isUInt32Value()
+              && !int1.isInt64Value() && !int1.isUInt64Value()
+              && int1.isIntegerValue());
+  ASSERT_EQ(int1.getIntegerValue(), "-18446744073709551616");
+  ASSERT_TRUE(!int2.isInt32Value() && !int2.isUInt32Value()
+              && !int2.isInt64Value() && !int2.isUInt64Value()
+              && int2.isIntegerValue());
+  ASSERT_EQ(int2.getIntegerValue(), "-18446744073709551615");
+  ASSERT_TRUE(!int3.isInt32Value() && !int3.isUInt32Value()
+              && int3.isInt64Value() && !int3.isUInt64Value()
+              && int3.isIntegerValue());
+  ASSERT_EQ(int3.getInt64Value(), -4294967296);
+  ASSERT_EQ(int3.getIntegerValue(), "-4294967296");
+  ASSERT_TRUE(!int4.isInt32Value() && !int4.isUInt32Value()
+              && int4.isInt64Value() && !int4.isUInt64Value()
+              && int4.isIntegerValue());
+  ASSERT_EQ(int4.getInt64Value(), -4294967295);
+  ASSERT_EQ(int4.getIntegerValue(), "-4294967295");
+  ASSERT_TRUE(int5.isInt32Value() && !int5.isUInt32Value()
+              && int5.isInt64Value() && !int5.isUInt64Value()
+              && int5.isIntegerValue());
+  ASSERT_EQ(int5.getInt32Value(), -10);
+  ASSERT_EQ(int5.getInt64Value(), -10);
+  ASSERT_EQ(int5.getIntegerValue(), "-10");
+  ASSERT_TRUE(int6.isInt32Value() && int6.isUInt32Value() && int6.isInt64Value()
+              && int6.isUInt64Value() && int6.isIntegerValue());
+  ASSERT_EQ(int6.getInt32Value(), 0);
+  ASSERT_EQ(int6.getUInt32Value(), 0);
+  ASSERT_EQ(int6.getInt64Value(), 0);
+  ASSERT_EQ(int6.getUInt64Value(), 0);
+  ASSERT_EQ(int6.getIntegerValue(), "0");
+  ASSERT_TRUE(int7.isInt32Value() && int7.isUInt32Value() && int7.isInt64Value()
+              && int7.isUInt64Value() && int7.isIntegerValue());
+  ASSERT_EQ(int7.getInt32Value(), 10);
+  ASSERT_EQ(int7.getUInt32Value(), 10);
+  ASSERT_EQ(int7.getInt64Value(), 10);
+  ASSERT_EQ(int7.getUInt64Value(), 10);
+  ASSERT_EQ(int7.getIntegerValue(), "10");
+  ASSERT_TRUE(!int8.isInt32Value() && int8.isUInt32Value()
+              && int8.isInt64Value() && int8.isUInt64Value()
+              && int8.isIntegerValue());
+  ASSERT_EQ(int8.getUInt32Value(), 4294967295);
+  ASSERT_EQ(int8.getInt64Value(), 4294967295);
+  ASSERT_EQ(int8.getUInt64Value(), 4294967295);
+  ASSERT_EQ(int8.getIntegerValue(), "4294967295");
+  ASSERT_TRUE(!int9.isInt32Value() && !int9.isUInt32Value()
+              && int9.isInt64Value() && int9.isUInt64Value()
+              && int9.isIntegerValue());
+  ASSERT_EQ(int9.getInt64Value(), 4294967296);
+  ASSERT_EQ(int9.getUInt64Value(), 4294967296);
+  ASSERT_EQ(int9.getIntegerValue(), "4294967296");
+  ASSERT_TRUE(!int10.isInt32Value() && !int10.isUInt32Value()
+              && !int10.isInt64Value() && int10.isUInt64Value()
+              && int10.isIntegerValue());
+  ASSERT_EQ(int10.getUInt64Value(), 18446744073709551615ull);
+  ASSERT_EQ(int10.getIntegerValue(), "18446744073709551615");
+  ASSERT_TRUE(!int11.isInt32Value() && !int11.isUInt32Value()
+              && !int11.isInt64Value() && !int11.isUInt64Value()
+              && int11.isIntegerValue());
+  ASSERT_EQ(int11.getIntegerValue(), "18446744073709551616");
+}
+
+TEST_F(TestApiBlackTerm, getString)
+{
+  Term s1 = d_solver.mkString("abcde");
+  ASSERT_TRUE(s1.isStringValue());
+  ASSERT_EQ(s1.getStringValue(), L"abcde");
+}
+
+TEST_F(TestApiBlackTerm, getReal)
+{
+  Term real1 = d_solver.mkReal("0");
+  Term real2 = d_solver.mkReal(".0");
+  Term real3 = d_solver.mkReal("-17");
+  Term real4 = d_solver.mkReal("-3/5");
+  Term real5 = d_solver.mkReal("12.7");
+  Term real6 = d_solver.mkReal("1/4294967297");
+  Term real7 = d_solver.mkReal("4294967297");
+  Term real8 = d_solver.mkReal("1/18446744073709551617");
+  Term real9 = d_solver.mkReal("18446744073709551617");
+  Term real10 = d_solver.mkReal("2343.2343");
+
+  ASSERT_TRUE(real1.isRealValue() && real1.isReal64Value()
+              && real1.isReal32Value());
+  ASSERT_TRUE(real2.isRealValue() && real2.isReal64Value()
+              && real2.isReal32Value());
+  ASSERT_TRUE(real3.isRealValue() && real3.isReal64Value()
+              && real3.isReal32Value());
+  ASSERT_TRUE(real4.isRealValue() && real4.isReal64Value()
+              && real4.isReal32Value());
+  ASSERT_TRUE(real5.isRealValue() && real5.isReal64Value()
+              && real5.isReal32Value());
+  ASSERT_TRUE(real6.isRealValue() && real6.isReal64Value());
+  ASSERT_TRUE(real7.isRealValue() && real7.isReal64Value());
+  ASSERT_TRUE(real8.isRealValue());
+  ASSERT_TRUE(real9.isRealValue());
+  ASSERT_TRUE(real10.isRealValue());
+
+  ASSERT_EQ((std::pair<int32_t, uint32_t>(0, 1)), real1.getReal32Value());
+  ASSERT_EQ((std::pair<int64_t, uint64_t>(0, 1)), real1.getReal64Value());
+  ASSERT_EQ("0/1", real1.getRealValue());
+
+  ASSERT_EQ((std::pair<int32_t, uint32_t>(0, 1)), real2.getReal32Value());
+  ASSERT_EQ((std::pair<int64_t, uint64_t>(0, 1)), real2.getReal64Value());
+  ASSERT_EQ("0/1", real2.getRealValue());
+
+  ASSERT_EQ((std::pair<int32_t, uint32_t>(-17, 1)), real3.getReal32Value());
+  ASSERT_EQ((std::pair<int64_t, uint64_t>(-17, 1)), real3.getReal64Value());
+  ASSERT_EQ("-17/1", real3.getRealValue());
+
+  ASSERT_EQ((std::pair<int32_t, uint32_t>(-3, 5)), real4.getReal32Value());
+  ASSERT_EQ((std::pair<int64_t, uint64_t>(-3, 5)), real4.getReal64Value());
+  ASSERT_EQ("-3/5", real4.getRealValue());
+
+  ASSERT_EQ((std::pair<int32_t, uint32_t>(127, 10)), real5.getReal32Value());
+  ASSERT_EQ((std::pair<int64_t, uint64_t>(127, 10)), real5.getReal64Value());
+  ASSERT_EQ("127/10", real5.getRealValue());
+
+  ASSERT_EQ((std::pair<int64_t, uint64_t>(1, 4294967297)),
+            real6.getReal64Value());
+  ASSERT_EQ("1/4294967297", real6.getRealValue());
+
+  ASSERT_EQ((std::pair<int64_t, uint64_t>(4294967297, 1)),
+            real7.getReal64Value());
+  ASSERT_EQ("4294967297/1", real7.getRealValue());
+
+  ASSERT_EQ("1/18446744073709551617", real8.getRealValue());
+
+  ASSERT_EQ("18446744073709551617/1", real9.getRealValue());
+
+  ASSERT_EQ("23432343/10000", real10.getRealValue());
+}
+
+TEST_F(TestApiBlackTerm, getConstArrayBase)
+{
+  Sort intsort = d_solver.getIntegerSort();
+  Sort arrsort = d_solver.mkArraySort(intsort, intsort);
+  Term one = d_solver.mkInteger(1);
+  Term constarr = d_solver.mkConstArray(arrsort, one);
+
+  ASSERT_TRUE(constarr.isConstArray());
+  ASSERT_EQ(one, constarr.getConstArrayBase());
+}
+
+TEST_F(TestApiBlackTerm, getBoolean)
+{
+  Term b1 = d_solver.mkBoolean(true);
+  Term b2 = d_solver.mkBoolean(false);
+
+  ASSERT_TRUE(b1.isBooleanValue());
+  ASSERT_TRUE(b2.isBooleanValue());
+  ASSERT_TRUE(b1.getBooleanValue());
+  ASSERT_FALSE(b2.getBooleanValue());
+}
+
+TEST_F(TestApiBlackTerm, getBitVector)
+{
+  Term b1 = d_solver.mkBitVector(8, 15);
+  Term b2 = d_solver.mkBitVector(8, "00001111", 2);
+  Term b3 = d_solver.mkBitVector(8, "15", 10);
+  Term b4 = d_solver.mkBitVector(8, "0f", 16);
+  Term b5 = d_solver.mkBitVector(9, "00001111", 2);
+  Term b6 = d_solver.mkBitVector(9, "15", 10);
+  Term b7 = d_solver.mkBitVector(9, "0f", 16);
+
+  ASSERT_TRUE(b1.isBitVectorValue());
+  ASSERT_TRUE(b2.isBitVectorValue());
+  ASSERT_TRUE(b3.isBitVectorValue());
+  ASSERT_TRUE(b4.isBitVectorValue());
+  ASSERT_TRUE(b5.isBitVectorValue());
+  ASSERT_TRUE(b6.isBitVectorValue());
+  ASSERT_TRUE(b7.isBitVectorValue());
+
+  ASSERT_EQ("00001111", b1.getBitVectorValue(2));
+  ASSERT_EQ("15", b1.getBitVectorValue(10));
+  ASSERT_EQ("f", b1.getBitVectorValue(16));
+  ASSERT_EQ("00001111", b2.getBitVectorValue(2));
+  ASSERT_EQ("15", b2.getBitVectorValue(10));
+  ASSERT_EQ("f", b2.getBitVectorValue(16));
+  ASSERT_EQ("00001111", b3.getBitVectorValue(2));
+  ASSERT_EQ("15", b3.getBitVectorValue(10));
+  ASSERT_EQ("f", b3.getBitVectorValue(16));
+  ASSERT_EQ("00001111", b4.getBitVectorValue(2));
+  ASSERT_EQ("15", b4.getBitVectorValue(10));
+  ASSERT_EQ("f", b4.getBitVectorValue(16));
+  ASSERT_EQ("000001111", b5.getBitVectorValue(2));
+  ASSERT_EQ("15", b5.getBitVectorValue(10));
+  ASSERT_EQ("f", b5.getBitVectorValue(16));
+  ASSERT_EQ("000001111", b6.getBitVectorValue(2));
+  ASSERT_EQ("15", b6.getBitVectorValue(10));
+  ASSERT_EQ("f", b6.getBitVectorValue(16));
+  ASSERT_EQ("000001111", b7.getBitVectorValue(2));
+  ASSERT_EQ("15", b7.getBitVectorValue(10));
+  ASSERT_EQ("f", b7.getBitVectorValue(16));
+}
+
+TEST_F(TestApiBlackTerm, getAbstractValue)
+{
+  Term v1 = d_solver.mkAbstractValue(1);
+  Term v2 = d_solver.mkAbstractValue("15");
+  Term v3 = d_solver.mkAbstractValue("18446744073709551617");
+
+  ASSERT_TRUE(v1.isAbstractValue());
+  ASSERT_TRUE(v2.isAbstractValue());
+  ASSERT_TRUE(v3.isAbstractValue());
+  ASSERT_EQ("1", v1.getAbstractValue());
+  ASSERT_EQ("15", v2.getAbstractValue());
+  ASSERT_EQ("18446744073709551617", v3.getAbstractValue());
+}
+
+TEST_F(TestApiBlackTerm, getTuple)
+{
+  Sort s1 = d_solver.getIntegerSort();
+  Sort s2 = d_solver.getRealSort();
+  Sort s3 = d_solver.getStringSort();
+
+  Term t1 = d_solver.mkInteger(15);
+  Term t2 = d_solver.mkReal(17, 25);
+  Term t3 = d_solver.mkString("abc");
+
+  Term tup = d_solver.mkTuple({s1, s2, s3}, {t1, t2, t3});
+
+  ASSERT_TRUE(tup.isTupleValue());
+  ASSERT_EQ(std::vector<Term>({t1, t2, t3}), tup.getTupleValue());
+}
+
+TEST_F(TestApiBlackTerm, getFloatingPoint)
+{
+  Term bvval = d_solver.mkBitVector(16, "0000110000000011", 2);
+  Term fp = d_solver.mkFloatingPoint(5, 11, bvval);
+
+  ASSERT_TRUE(fp.isFloatingPointValue());
+  ASSERT_FALSE(fp.isFloatingPointPosZero());
+  ASSERT_FALSE(fp.isFloatingPointNegZero());
+  ASSERT_FALSE(fp.isFloatingPointPosInf());
+  ASSERT_FALSE(fp.isFloatingPointNegInf());
+  ASSERT_FALSE(fp.isFloatingPointNaN());
+  ASSERT_EQ(std::make_tuple(5u, 11u, bvval), fp.getFloatingPointValue());
+
+  ASSERT_TRUE(d_solver.mkPosZero(5, 11).isFloatingPointPosZero());
+  ASSERT_TRUE(d_solver.mkNegZero(5, 11).isFloatingPointNegZero());
+  ASSERT_TRUE(d_solver.mkPosInf(5, 11).isFloatingPointPosInf());
+  ASSERT_TRUE(d_solver.mkNegInf(5, 11).isFloatingPointNegInf());
+  ASSERT_TRUE(d_solver.mkNaN(5, 11).isFloatingPointNaN());
+}
+
+TEST_F(TestApiBlackTerm, getSet)
+{
+  Sort s = d_solver.mkSetSort(d_solver.getIntegerSort());
+
+  Term i1 = d_solver.mkInteger(5);
+  Term i2 = d_solver.mkInteger(7);
+
+  Term s1 = d_solver.mkEmptySet(s);
+  Term s2 = d_solver.mkTerm(Kind::SET_SINGLETON, i1);
+  Term s3 = d_solver.mkTerm(Kind::SET_SINGLETON, i1);
+  Term s4 = d_solver.mkTerm(Kind::SET_SINGLETON, i2);
+  Term s5 = d_solver.mkTerm(
+      Kind::SET_UNION, s2, d_solver.mkTerm(Kind::SET_UNION, s3, s4));
+
+  ASSERT_TRUE(s1.isSetValue());
+  ASSERT_TRUE(s2.isSetValue());
+  ASSERT_TRUE(s3.isSetValue());
+  ASSERT_TRUE(s4.isSetValue());
+  ASSERT_FALSE(s5.isSetValue());
+  s5 = d_solver.simplify(s5);
+  ASSERT_TRUE(s5.isSetValue());
+
+  ASSERT_EQ(std::set<Term>({}), s1.getSetValue());
+  ASSERT_EQ(std::set<Term>({i1}), s2.getSetValue());
+  ASSERT_EQ(std::set<Term>({i1}), s3.getSetValue());
+  ASSERT_EQ(std::set<Term>({i2}), s4.getSetValue());
+  ASSERT_EQ(std::set<Term>({i1, i2}), s5.getSetValue());
+}
+
+TEST_F(TestApiBlackTerm, getSequence)
+{
+  Sort s = d_solver.mkSequenceSort(d_solver.getIntegerSort());
+
+  Term i1 = d_solver.mkInteger(5);
+  Term i2 = d_solver.mkInteger(7);
+
+  Term s1 = d_solver.mkEmptySequence(s);
+  Term s2 = d_solver.mkTerm(Kind::SEQ_UNIT, i1);
+  Term s3 = d_solver.mkTerm(Kind::SEQ_UNIT, i1);
+  Term s4 = d_solver.mkTerm(Kind::SEQ_UNIT, i2);
+  Term s5 = d_solver.mkTerm(
+      Kind::SEQ_CONCAT, s2, d_solver.mkTerm(Kind::SEQ_CONCAT, s3, s4));
+
+  ASSERT_TRUE(s1.isSequenceValue());
+  ASSERT_TRUE(!s2.isSequenceValue());
+  ASSERT_TRUE(!s3.isSequenceValue());
+  ASSERT_TRUE(!s4.isSequenceValue());
+  ASSERT_TRUE(!s5.isSequenceValue());
+
+  s2 = d_solver.simplify(s2);
+  s3 = d_solver.simplify(s3);
+  s4 = d_solver.simplify(s4);
+  s5 = d_solver.simplify(s5);
+
+  ASSERT_EQ(std::vector<Term>({}), s1.getSequenceValue());
+  ASSERT_EQ(std::vector<Term>({i1}), s2.getSequenceValue());
+  ASSERT_EQ(std::vector<Term>({i1}), s3.getSequenceValue());
+  ASSERT_EQ(std::vector<Term>({i2}), s4.getSequenceValue());
+  ASSERT_EQ(std::vector<Term>({i1, i1, i2}), s5.getSequenceValue());
+}
+
+TEST_F(TestApiBlackTerm, getUninterpretedConst)
+{
+  Sort s = d_solver.mkUninterpretedSort("test");
+  Term t1 = d_solver.mkUninterpretedConst(s, 3);
+  Term t2 = d_solver.mkUninterpretedConst(s, 5);
+
+  ASSERT_TRUE(t1.isUninterpretedValue());
+  ASSERT_TRUE(t2.isUninterpretedValue());
+
+  ASSERT_EQ(std::make_pair(s, 3), t1.getUninterpretedValue());
+  ASSERT_EQ(std::make_pair(s, 5), t2.getUninterpretedValue());
+}
+
+TEST_F(TestApiBlackTerm, substitute)
+{
+  Term x = d_solver.mkConst(d_solver.getIntegerSort(), "x");
+  Term one = d_solver.mkInteger(1);
+  Term ttrue = d_solver.mkTrue();
+  Term xpx = d_solver.mkTerm(PLUS, x, x);
+  Term onepone = d_solver.mkTerm(PLUS, one, one);
+
+  ASSERT_EQ(xpx.substitute(x, one), onepone);
+  ASSERT_EQ(onepone.substitute(one, x), xpx);
+  // incorrect due to type
+  ASSERT_THROW(xpx.substitute(one, ttrue), CVC5ApiException);
+
+  // simultaneous substitution
+  Term y = d_solver.mkConst(d_solver.getIntegerSort(), "y");
+  Term xpy = d_solver.mkTerm(PLUS, x, y);
+  Term xpone = d_solver.mkTerm(PLUS, y, one);
+  std::vector<Term> es;
+  std::vector<Term> rs;
+  es.push_back(x);
+  rs.push_back(y);
+  es.push_back(y);
+  rs.push_back(one);
+  ASSERT_EQ(xpy.substitute(es, rs), xpone);
+
+  // incorrect substitution due to arity
+  rs.pop_back();
+  ASSERT_THROW(xpy.substitute(es, rs), CVC5ApiException);
+
+  // incorrect substitution due to types
+  rs.push_back(ttrue);
+  ASSERT_THROW(xpy.substitute(es, rs), CVC5ApiException);
+
+  // null cannot substitute
+  Term tnull;
+  ASSERT_THROW(tnull.substitute(one, x), CVC5ApiException);
+  ASSERT_THROW(xpx.substitute(tnull, x), CVC5ApiException);
+  ASSERT_THROW(xpx.substitute(x, tnull), CVC5ApiException);
+  rs.pop_back();
+  rs.push_back(tnull);
+  ASSERT_THROW(xpy.substitute(es, rs), CVC5ApiException);
+  es.clear();
+  rs.clear();
+  es.push_back(x);
+  rs.push_back(y);
+  ASSERT_THROW(tnull.substitute(es, rs), CVC5ApiException);
+  es.push_back(tnull);
+  rs.push_back(one);
+  ASSERT_THROW(xpx.substitute(es, rs), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackTerm, constArray)
+{
+  Sort intsort = d_solver.getIntegerSort();
+  Sort arrsort = d_solver.mkArraySort(intsort, intsort);
+  Term a = d_solver.mkConst(arrsort, "a");
+  Term one = d_solver.mkInteger(1);
+  Term constarr = d_solver.mkConstArray(arrsort, one);
+
+  ASSERT_EQ(constarr.getKind(), CONST_ARRAY);
+  ASSERT_EQ(constarr.getConstArrayBase(), one);
+  ASSERT_THROW(a.getConstArrayBase(), CVC5ApiException);
+
+  arrsort =
+      d_solver.mkArraySort(d_solver.getRealSort(), d_solver.getRealSort());
+  Term zero_array = d_solver.mkConstArray(arrsort, d_solver.mkReal(0));
+  Term stores = d_solver.mkTerm(
+      STORE, zero_array, d_solver.mkReal(1), d_solver.mkReal(2));
+  stores =
+      d_solver.mkTerm(STORE, stores, d_solver.mkReal(2), d_solver.mkReal(3));
+  stores =
+      d_solver.mkTerm(STORE, stores, d_solver.mkReal(4), d_solver.mkReal(5));
+}
+
+TEST_F(TestApiBlackTerm, getSequenceValue)
+{
+  Sort realsort = d_solver.getRealSort();
+  Sort seqsort = d_solver.mkSequenceSort(realsort);
+  Term s = d_solver.mkEmptySequence(seqsort);
+
+  ASSERT_EQ(s.getKind(), CONST_SEQUENCE);
+  // empty sequence has zero elements
+  std::vector<Term> cs = s.getSequenceValue();
+  ASSERT_TRUE(cs.empty());
+
+  // A seq.unit app is not a constant sequence (regardless of whether it is
+  // applied to a constant).
+  Term su = d_solver.mkTerm(SEQ_UNIT, d_solver.mkReal(1));
+  ASSERT_THROW(su.getSequenceValue(), CVC5ApiException);
+}
+
+TEST_F(TestApiBlackTerm, termScopedToString)
+{
+  Sort intsort = d_solver.getIntegerSort();
+  Term x = d_solver.mkConst(intsort, "x");
+  ASSERT_EQ(x.toString(), "x");
+  Solver solver2;
+  ASSERT_EQ(x.toString(), "x");
+}
+}  // namespace test
+}  // namespace cvc5
diff --git a/test/unit/api/cpp/term_white.cpp b/test/unit/api/cpp/term_white.cpp
new file mode 100644 (file)
index 0000000..ace5645
--- /dev/null
@@ -0,0 +1,85 @@
+/******************************************************************************
+ * Top contributors (to current version):
+ *   Makai Mann, Aina Niemetz, Andrew Reynolds
+ *
+ * This file is part of the cvc5 project.
+ *
+ * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
+ * in the top-level source directory and their institutional affiliations.
+ * All rights reserved.  See the file COPYING in the top-level source
+ * directory for licensing information.
+ * ****************************************************************************
+ *
+ * White box testing of the Term class.
+ */
+
+#include "test_api.h"
+
+namespace cvc5 {
+
+using namespace api;
+
+namespace test {
+
+class TestApiWhiteTerm : public TestApi
+{
+};
+
+TEST_F(TestApiWhiteTerm, getOp)
+{
+  Sort intsort = d_solver.getIntegerSort();
+  Sort bvsort = d_solver.mkBitVectorSort(8);
+  Sort arrsort = d_solver.mkArraySort(bvsort, intsort);
+  Sort funsort = d_solver.mkFunctionSort(intsort, bvsort);
+
+  Term x = d_solver.mkConst(intsort, "x");
+  Term a = d_solver.mkConst(arrsort, "a");
+  Term b = d_solver.mkConst(bvsort, "b");
+
+  Term ab = d_solver.mkTerm(SELECT, a, b);
+  Op ext = d_solver.mkOp(BITVECTOR_EXTRACT, 4, 0);
+  Term extb = d_solver.mkTerm(ext, b);
+
+  ASSERT_EQ(ab.getOp(), Op(&d_solver, SELECT));
+  // can compare directly to a Kind (will invoke Op constructor)
+  ASSERT_EQ(ab.getOp(), Op(&d_solver, SELECT));
+
+  Term f = d_solver.mkConst(funsort, "f");
+  Term fx = d_solver.mkTerm(APPLY_UF, f, x);
+
+  ASSERT_EQ(fx.getOp(), Op(&d_solver, APPLY_UF));
+  // testing rebuild from op and children
+
+  // Test Datatypes Ops
+  Sort sort = d_solver.mkParamSort("T");
+  DatatypeDecl listDecl = d_solver.mkDatatypeDecl("paramlist", sort);
+  DatatypeConstructorDecl cons = d_solver.mkDatatypeConstructorDecl("cons");
+  DatatypeConstructorDecl nil = d_solver.mkDatatypeConstructorDecl("nil");
+  cons.addSelector("head", sort);
+  cons.addSelectorSelf("tail");
+  listDecl.addConstructor(cons);
+  listDecl.addConstructor(nil);
+  Sort listSort = d_solver.mkDatatypeSort(listDecl);
+  Sort intListSort =
+      listSort.instantiate(std::vector<Sort>{d_solver.getIntegerSort()});
+  Term c = d_solver.mkConst(intListSort, "c");
+  Datatype list = listSort.getDatatype();
+  // list datatype constructor and selector operator terms
+  Term consOpTerm = list.getConstructorTerm("cons");
+  Term nilOpTerm = list.getConstructorTerm("nil");
+  Term headOpTerm = list["cons"].getSelectorTerm("head");
+  Term tailOpTerm = list["cons"].getSelectorTerm("tail");
+
+  Term nilTerm = d_solver.mkTerm(APPLY_CONSTRUCTOR, nilOpTerm);
+  Term consTerm = d_solver.mkTerm(
+      APPLY_CONSTRUCTOR, consOpTerm, d_solver.mkInteger(0), nilTerm);
+  Term headTerm = d_solver.mkTerm(APPLY_SELECTOR, headOpTerm, consTerm);
+  Term tailTerm = d_solver.mkTerm(APPLY_SELECTOR, tailOpTerm, consTerm);
+
+  ASSERT_EQ(nilTerm.getOp(), Op(&d_solver, APPLY_CONSTRUCTOR));
+  ASSERT_EQ(consTerm.getOp(), Op(&d_solver, APPLY_CONSTRUCTOR));
+  ASSERT_EQ(headTerm.getOp(), Op(&d_solver, APPLY_SELECTOR));
+  ASSERT_EQ(tailTerm.getOp(), Op(&d_solver, APPLY_SELECTOR));
+}
+}  // namespace test
+}  // namespace cvc5
diff --git a/test/unit/api/datatype_api_black.cpp b/test/unit/api/datatype_api_black.cpp
deleted file mode 100644 (file)
index 745abc1..0000000
+++ /dev/null
@@ -1,587 +0,0 @@
-/******************************************************************************
- * Top contributors (to current version):
- *   Andrew Reynolds, Aina Niemetz, Andres Noetzli
- *
- * This file is part of the cvc5 project.
- *
- * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
- * in the top-level source directory and their institutional affiliations.
- * All rights reserved.  See the file COPYING in the top-level source
- * directory for licensing information.
- * ****************************************************************************
- *
- * Black box testing of the datatype classes of the C++ API.
- */
-
-#include "test_api.h"
-
-namespace cvc5 {
-
-using namespace api;
-
-namespace test {
-
-class TestApiBlackDatatype : public TestApi
-{
-};
-
-TEST_F(TestApiBlackDatatype, mkDatatypeSort)
-{
-  DatatypeDecl dtypeSpec = d_solver.mkDatatypeDecl("list");
-  DatatypeConstructorDecl cons = d_solver.mkDatatypeConstructorDecl("cons");
-  cons.addSelector("head", d_solver.getIntegerSort());
-  dtypeSpec.addConstructor(cons);
-  DatatypeConstructorDecl nil = d_solver.mkDatatypeConstructorDecl("nil");
-  dtypeSpec.addConstructor(nil);
-  Sort listSort = d_solver.mkDatatypeSort(dtypeSpec);
-  Datatype d = listSort.getDatatype();
-  DatatypeConstructor consConstr = d[0];
-  DatatypeConstructor nilConstr = d[1];
-  ASSERT_THROW(d[2], CVC5ApiException);
-  ASSERT_NO_THROW(consConstr.getConstructorTerm());
-  ASSERT_NO_THROW(nilConstr.getConstructorTerm());
-}
-
-TEST_F(TestApiBlackDatatype, isNull)
-{
-  // creating empty (null) objects.
-  DatatypeDecl dtypeSpec;
-  DatatypeConstructorDecl cons;
-  Datatype d;
-  DatatypeConstructor consConstr;
-  DatatypeSelector sel;
-
-  // verifying that the objects are considered null.
-  ASSERT_TRUE(dtypeSpec.isNull());
-  ASSERT_TRUE(cons.isNull());
-  ASSERT_TRUE(d.isNull());
-  ASSERT_TRUE(consConstr.isNull());
-  ASSERT_TRUE(sel.isNull());
-
-  // changing the objects to be non-null
-  dtypeSpec = d_solver.mkDatatypeDecl("list");
-  cons = d_solver.mkDatatypeConstructorDecl("cons");
-  cons.addSelector("head", d_solver.getIntegerSort());
-  dtypeSpec.addConstructor(cons);
-  Sort listSort = d_solver.mkDatatypeSort(dtypeSpec);
-  d = listSort.getDatatype();
-  consConstr = d[0];
-  sel = consConstr[0];
-
-  // verifying that the new objects are non-null
-  ASSERT_FALSE(dtypeSpec.isNull());
-  ASSERT_FALSE(cons.isNull());
-  ASSERT_FALSE(d.isNull());
-  ASSERT_FALSE(consConstr.isNull());
-  ASSERT_FALSE(sel.isNull());
-}
-
-TEST_F(TestApiBlackDatatype, mkDatatypeSorts)
-{
-  /* Create two mutual datatypes corresponding to this definition
-   * block:
-   *
-   *   DATATYPE
-   *     tree = node(left: tree, right: tree) | leaf(data: list),
-   *     list = cons(car: tree, cdr: list) | nil
-   *   END;
-   */
-  // Make unresolved types as placeholders
-  std::set<Sort> unresTypes;
-  Sort unresTree = d_solver.mkUninterpretedSort("tree");
-  Sort unresList = d_solver.mkUninterpretedSort("list");
-  unresTypes.insert(unresTree);
-  unresTypes.insert(unresList);
-
-  DatatypeDecl tree = d_solver.mkDatatypeDecl("tree");
-  DatatypeConstructorDecl node = d_solver.mkDatatypeConstructorDecl("node");
-  node.addSelector("left", unresTree);
-  node.addSelector("right", unresTree);
-  tree.addConstructor(node);
-
-  DatatypeConstructorDecl leaf = d_solver.mkDatatypeConstructorDecl("leaf");
-  leaf.addSelector("data", unresList);
-  tree.addConstructor(leaf);
-
-  DatatypeDecl list = d_solver.mkDatatypeDecl("list");
-  DatatypeConstructorDecl cons = d_solver.mkDatatypeConstructorDecl("cons");
-  cons.addSelector("car", unresTree);
-  cons.addSelector("cdr", unresTree);
-  list.addConstructor(cons);
-
-  DatatypeConstructorDecl nil = d_solver.mkDatatypeConstructorDecl("nil");
-  list.addConstructor(nil);
-
-  std::vector<DatatypeDecl> dtdecls;
-  dtdecls.push_back(tree);
-  dtdecls.push_back(list);
-  std::vector<Sort> dtsorts;
-  ASSERT_NO_THROW(dtsorts = d_solver.mkDatatypeSorts(dtdecls, unresTypes));
-  ASSERT_EQ(dtsorts.size(), dtdecls.size());
-  for (size_t i = 0, ndecl = dtdecls.size(); i < ndecl; i++)
-  {
-    ASSERT_TRUE(dtsorts[i].isDatatype());
-    ASSERT_FALSE(dtsorts[i].getDatatype().isFinite());
-    ASSERT_EQ(dtsorts[i].getDatatype().getName(), dtdecls[i].getName());
-  }
-  // verify the resolution was correct
-  Datatype dtTree = dtsorts[0].getDatatype();
-  DatatypeConstructor dtcTreeNode = dtTree[0];
-  ASSERT_EQ(dtcTreeNode.getName(), "node");
-  DatatypeSelector dtsTreeNodeLeft = dtcTreeNode[0];
-  ASSERT_EQ(dtsTreeNodeLeft.getName(), "left");
-  // argument type should have resolved to be recursive
-  ASSERT_TRUE(dtsTreeNodeLeft.getRangeSort().isDatatype());
-  ASSERT_EQ(dtsTreeNodeLeft.getRangeSort(), dtsorts[0]);
-
-  // fails due to empty datatype
-  std::vector<DatatypeDecl> dtdeclsBad;
-  DatatypeDecl emptyD = d_solver.mkDatatypeDecl("emptyD");
-  dtdeclsBad.push_back(emptyD);
-  ASSERT_THROW(d_solver.mkDatatypeSorts(dtdeclsBad), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackDatatype, datatypeStructs)
-{
-  Sort intSort = d_solver.getIntegerSort();
-  Sort boolSort = d_solver.getBooleanSort();
-
-  // create datatype sort to test
-  DatatypeDecl dtypeSpec = d_solver.mkDatatypeDecl("list");
-  DatatypeConstructorDecl cons = d_solver.mkDatatypeConstructorDecl("cons");
-  cons.addSelector("head", intSort);
-  cons.addSelectorSelf("tail");
-  Sort nullSort;
-  ASSERT_THROW(cons.addSelector("null", nullSort), CVC5ApiException);
-  dtypeSpec.addConstructor(cons);
-  DatatypeConstructorDecl nil = d_solver.mkDatatypeConstructorDecl("nil");
-  dtypeSpec.addConstructor(nil);
-  Sort dtypeSort = d_solver.mkDatatypeSort(dtypeSpec);
-  Datatype dt = dtypeSort.getDatatype();
-  ASSERT_FALSE(dt.isCodatatype());
-  ASSERT_FALSE(dt.isTuple());
-  ASSERT_FALSE(dt.isRecord());
-  ASSERT_FALSE(dt.isFinite());
-  ASSERT_TRUE(dt.isWellFounded());
-  // get constructor
-  DatatypeConstructor dcons = dt[0];
-  Term consTerm = dcons.getConstructorTerm();
-  ASSERT_EQ(dcons.getNumSelectors(), 2);
-
-  // create datatype sort to test
-  DatatypeDecl dtypeSpecEnum = d_solver.mkDatatypeDecl("enum");
-  DatatypeConstructorDecl ca = d_solver.mkDatatypeConstructorDecl("A");
-  dtypeSpecEnum.addConstructor(ca);
-  DatatypeConstructorDecl cb = d_solver.mkDatatypeConstructorDecl("B");
-  dtypeSpecEnum.addConstructor(cb);
-  DatatypeConstructorDecl cc = d_solver.mkDatatypeConstructorDecl("C");
-  dtypeSpecEnum.addConstructor(cc);
-  Sort dtypeSortEnum = d_solver.mkDatatypeSort(dtypeSpecEnum);
-  Datatype dtEnum = dtypeSortEnum.getDatatype();
-  ASSERT_FALSE(dtEnum.isTuple());
-  ASSERT_TRUE(dtEnum.isFinite());
-
-  // create codatatype
-  DatatypeDecl dtypeSpecStream = d_solver.mkDatatypeDecl("stream", true);
-  DatatypeConstructorDecl consStream =
-      d_solver.mkDatatypeConstructorDecl("cons");
-  consStream.addSelector("head", intSort);
-  consStream.addSelectorSelf("tail");
-  dtypeSpecStream.addConstructor(consStream);
-  Sort dtypeSortStream = d_solver.mkDatatypeSort(dtypeSpecStream);
-  Datatype dtStream = dtypeSortStream.getDatatype();
-  ASSERT_TRUE(dtStream.isCodatatype());
-  ASSERT_FALSE(dtStream.isFinite());
-  // codatatypes may be well-founded
-  ASSERT_TRUE(dtStream.isWellFounded());
-
-  // create tuple
-  Sort tupSort = d_solver.mkTupleSort({boolSort});
-  Datatype dtTuple = tupSort.getDatatype();
-  ASSERT_TRUE(dtTuple.isTuple());
-  ASSERT_FALSE(dtTuple.isRecord());
-  ASSERT_TRUE(dtTuple.isFinite());
-  ASSERT_TRUE(dtTuple.isWellFounded());
-
-  // create record
-  std::vector<std::pair<std::string, Sort>> fields = {
-      std::make_pair("b", boolSort), std::make_pair("i", intSort)};
-  Sort recSort = d_solver.mkRecordSort(fields);
-  ASSERT_TRUE(recSort.isDatatype());
-  Datatype dtRecord = recSort.getDatatype();
-  ASSERT_FALSE(dtRecord.isTuple());
-  ASSERT_TRUE(dtRecord.isRecord());
-  ASSERT_FALSE(dtRecord.isFinite());
-  ASSERT_TRUE(dtRecord.isWellFounded());
-}
-
-TEST_F(TestApiBlackDatatype, datatypeNames)
-{
-  Sort intSort = d_solver.getIntegerSort();
-
-  // create datatype sort to test
-  DatatypeDecl dtypeSpec = d_solver.mkDatatypeDecl("list");
-  ASSERT_NO_THROW(dtypeSpec.getName());
-  ASSERT_EQ(dtypeSpec.getName(), std::string("list"));
-  DatatypeConstructorDecl cons = d_solver.mkDatatypeConstructorDecl("cons");
-  cons.addSelector("head", intSort);
-  cons.addSelectorSelf("tail");
-  dtypeSpec.addConstructor(cons);
-  DatatypeConstructorDecl nil = d_solver.mkDatatypeConstructorDecl("nil");
-  dtypeSpec.addConstructor(nil);
-  Sort dtypeSort = d_solver.mkDatatypeSort(dtypeSpec);
-  Datatype dt = dtypeSort.getDatatype();
-  ASSERT_EQ(dt.getName(), std::string("list"));
-  ASSERT_NO_THROW(dt.getConstructor("nil"));
-  ASSERT_NO_THROW(dt["cons"]);
-  ASSERT_THROW(dt.getConstructor("head"), CVC5ApiException);
-  ASSERT_THROW(dt.getConstructor(""), CVC5ApiException);
-
-  DatatypeConstructor dcons = dt[0];
-  ASSERT_EQ(dcons.getName(), std::string("cons"));
-  ASSERT_NO_THROW(dcons.getSelector("head"));
-  ASSERT_NO_THROW(dcons["tail"]);
-  ASSERT_THROW(dcons.getSelector("cons"), CVC5ApiException);
-
-  // get selector
-  DatatypeSelector dselTail = dcons[1];
-  ASSERT_EQ(dselTail.getName(), std::string("tail"));
-  ASSERT_EQ(dselTail.getRangeSort(), dtypeSort);
-
-  // get selector from datatype
-  ASSERT_NO_THROW(dt.getSelector("head"));
-  ASSERT_THROW(dt.getSelector("cons"), CVC5ApiException);
-
-  // possible to construct null datatype declarations if not using solver
-  ASSERT_THROW(DatatypeDecl().getName(), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackDatatype, parametricDatatype)
-{
-  std::vector<Sort> v;
-  Sort t1 = d_solver.mkParamSort("T1");
-  Sort t2 = d_solver.mkParamSort("T2");
-  v.push_back(t1);
-  v.push_back(t2);
-  DatatypeDecl pairSpec = d_solver.mkDatatypeDecl("pair", v);
-
-  DatatypeConstructorDecl mkpair =
-      d_solver.mkDatatypeConstructorDecl("mk-pair");
-  mkpair.addSelector("first", t1);
-  mkpair.addSelector("second", t2);
-  pairSpec.addConstructor(mkpair);
-
-  Sort pairType = d_solver.mkDatatypeSort(pairSpec);
-
-  ASSERT_TRUE(pairType.getDatatype().isParametric());
-
-  v.clear();
-  v.push_back(d_solver.getIntegerSort());
-  v.push_back(d_solver.getIntegerSort());
-  Sort pairIntInt = pairType.instantiate(v);
-  v.clear();
-  v.push_back(d_solver.getRealSort());
-  v.push_back(d_solver.getRealSort());
-  Sort pairRealReal = pairType.instantiate(v);
-  v.clear();
-  v.push_back(d_solver.getRealSort());
-  v.push_back(d_solver.getIntegerSort());
-  Sort pairRealInt = pairType.instantiate(v);
-  v.clear();
-  v.push_back(d_solver.getIntegerSort());
-  v.push_back(d_solver.getRealSort());
-  Sort pairIntReal = pairType.instantiate(v);
-
-  ASSERT_NE(pairIntInt, pairRealReal);
-  ASSERT_NE(pairIntReal, pairRealReal);
-  ASSERT_NE(pairRealInt, pairRealReal);
-  ASSERT_NE(pairIntInt, pairIntReal);
-  ASSERT_NE(pairIntInt, pairRealInt);
-  ASSERT_NE(pairIntReal, pairRealInt);
-
-  ASSERT_TRUE(pairRealReal.isComparableTo(pairRealReal));
-  ASSERT_FALSE(pairIntReal.isComparableTo(pairRealReal));
-  ASSERT_FALSE(pairRealInt.isComparableTo(pairRealReal));
-  ASSERT_FALSE(pairIntInt.isComparableTo(pairRealReal));
-  ASSERT_FALSE(pairRealReal.isComparableTo(pairRealInt));
-  ASSERT_FALSE(pairIntReal.isComparableTo(pairRealInt));
-  ASSERT_TRUE(pairRealInt.isComparableTo(pairRealInt));
-  ASSERT_FALSE(pairIntInt.isComparableTo(pairRealInt));
-  ASSERT_FALSE(pairRealReal.isComparableTo(pairIntReal));
-  ASSERT_TRUE(pairIntReal.isComparableTo(pairIntReal));
-  ASSERT_FALSE(pairRealInt.isComparableTo(pairIntReal));
-  ASSERT_FALSE(pairIntInt.isComparableTo(pairIntReal));
-  ASSERT_FALSE(pairRealReal.isComparableTo(pairIntInt));
-  ASSERT_FALSE(pairIntReal.isComparableTo(pairIntInt));
-  ASSERT_FALSE(pairRealInt.isComparableTo(pairIntInt));
-  ASSERT_TRUE(pairIntInt.isComparableTo(pairIntInt));
-
-  ASSERT_TRUE(pairRealReal.isSubsortOf(pairRealReal));
-  ASSERT_FALSE(pairIntReal.isSubsortOf(pairRealReal));
-  ASSERT_FALSE(pairRealInt.isSubsortOf(pairRealReal));
-  ASSERT_FALSE(pairIntInt.isSubsortOf(pairRealReal));
-  ASSERT_FALSE(pairRealReal.isSubsortOf(pairRealInt));
-  ASSERT_FALSE(pairIntReal.isSubsortOf(pairRealInt));
-  ASSERT_TRUE(pairRealInt.isSubsortOf(pairRealInt));
-  ASSERT_FALSE(pairIntInt.isSubsortOf(pairRealInt));
-  ASSERT_FALSE(pairRealReal.isSubsortOf(pairIntReal));
-  ASSERT_TRUE(pairIntReal.isSubsortOf(pairIntReal));
-  ASSERT_FALSE(pairRealInt.isSubsortOf(pairIntReal));
-  ASSERT_FALSE(pairIntInt.isSubsortOf(pairIntReal));
-  ASSERT_FALSE(pairRealReal.isSubsortOf(pairIntInt));
-  ASSERT_FALSE(pairIntReal.isSubsortOf(pairIntInt));
-  ASSERT_FALSE(pairRealInt.isSubsortOf(pairIntInt));
-  ASSERT_TRUE(pairIntInt.isSubsortOf(pairIntInt));
-}
-
-TEST_F(TestApiBlackDatatype, datatypeSimplyRec)
-{
-  /* Create mutual datatypes corresponding to this definition block:
-   *
-   *   DATATYPE
-   *     wlist = leaf(data: list),
-   *     list = cons(car: wlist, cdr: list) | nil,
-   *     ns = elem(ndata: set(wlist)) | elemArray(ndata2: array(list, list))
-   *   END;
-   */
-  // Make unresolved types as placeholders
-  std::set<Sort> unresTypes;
-  Sort unresWList = d_solver.mkUninterpretedSort("wlist");
-  Sort unresList = d_solver.mkUninterpretedSort("list");
-  Sort unresNs = d_solver.mkUninterpretedSort("ns");
-  unresTypes.insert(unresWList);
-  unresTypes.insert(unresList);
-  unresTypes.insert(unresNs);
-
-  DatatypeDecl wlist = d_solver.mkDatatypeDecl("wlist");
-  DatatypeConstructorDecl leaf = d_solver.mkDatatypeConstructorDecl("leaf");
-  leaf.addSelector("data", unresList);
-  wlist.addConstructor(leaf);
-
-  DatatypeDecl list = d_solver.mkDatatypeDecl("list");
-  DatatypeConstructorDecl cons = d_solver.mkDatatypeConstructorDecl("cons");
-  cons.addSelector("car", unresWList);
-  cons.addSelector("cdr", unresList);
-  list.addConstructor(cons);
-  DatatypeConstructorDecl nil = d_solver.mkDatatypeConstructorDecl("nil");
-  list.addConstructor(nil);
-
-  DatatypeDecl ns = d_solver.mkDatatypeDecl("ns");
-  DatatypeConstructorDecl elem = d_solver.mkDatatypeConstructorDecl("elem");
-  elem.addSelector("ndata", d_solver.mkSetSort(unresWList));
-  ns.addConstructor(elem);
-  DatatypeConstructorDecl elemArray =
-      d_solver.mkDatatypeConstructorDecl("elemArray");
-  elemArray.addSelector("ndata", d_solver.mkArraySort(unresList, unresList));
-  ns.addConstructor(elemArray);
-
-  std::vector<DatatypeDecl> dtdecls;
-  dtdecls.push_back(wlist);
-  dtdecls.push_back(list);
-  dtdecls.push_back(ns);
-  // this is well-founded and has no nested recursion
-  std::vector<Sort> dtsorts;
-  ASSERT_NO_THROW(dtsorts = d_solver.mkDatatypeSorts(dtdecls, unresTypes));
-  ASSERT_EQ(dtsorts.size(), 3);
-  ASSERT_TRUE(dtsorts[0].getDatatype().isWellFounded());
-  ASSERT_TRUE(dtsorts[1].getDatatype().isWellFounded());
-  ASSERT_TRUE(dtsorts[2].getDatatype().isWellFounded());
-  ASSERT_FALSE(dtsorts[0].getDatatype().hasNestedRecursion());
-  ASSERT_FALSE(dtsorts[1].getDatatype().hasNestedRecursion());
-  ASSERT_FALSE(dtsorts[2].getDatatype().hasNestedRecursion());
-
-  /* Create mutual datatypes corresponding to this definition block:
-   *   DATATYPE
-   *     ns2 = elem2(ndata: array(int,ns2)) | nil2
-   *   END;
-   */
-  unresTypes.clear();
-  Sort unresNs2 = d_solver.mkUninterpretedSort("ns2");
-  unresTypes.insert(unresNs2);
-
-  DatatypeDecl ns2 = d_solver.mkDatatypeDecl("ns2");
-  DatatypeConstructorDecl elem2 = d_solver.mkDatatypeConstructorDecl("elem2");
-  elem2.addSelector("ndata",
-                    d_solver.mkArraySort(d_solver.getIntegerSort(), unresNs2));
-  ns2.addConstructor(elem2);
-  DatatypeConstructorDecl nil2 = d_solver.mkDatatypeConstructorDecl("nil2");
-  ns2.addConstructor(nil2);
-
-  dtdecls.clear();
-  dtdecls.push_back(ns2);
-
-  dtsorts.clear();
-  // this is not well-founded due to non-simple recursion
-  ASSERT_NO_THROW(dtsorts = d_solver.mkDatatypeSorts(dtdecls, unresTypes));
-  ASSERT_EQ(dtsorts.size(), 1);
-  ASSERT_TRUE(dtsorts[0].getDatatype()[0][0].getRangeSort().isArray());
-  ASSERT_EQ(dtsorts[0].getDatatype()[0][0].getRangeSort().getArrayElementSort(),
-            dtsorts[0]);
-  ASSERT_TRUE(dtsorts[0].getDatatype().isWellFounded());
-  ASSERT_TRUE(dtsorts[0].getDatatype().hasNestedRecursion());
-
-  /* Create mutual datatypes corresponding to this definition block:
-   *   DATATYPE
-   *     list3 = cons3(car: ns3, cdr: list3) | nil3,
-   *     ns3 = elem3(ndata: set(list3))
-   *   END;
-   */
-  unresTypes.clear();
-  Sort unresNs3 = d_solver.mkUninterpretedSort("ns3");
-  unresTypes.insert(unresNs3);
-  Sort unresList3 = d_solver.mkUninterpretedSort("list3");
-  unresTypes.insert(unresList3);
-
-  DatatypeDecl list3 = d_solver.mkDatatypeDecl("list3");
-  DatatypeConstructorDecl cons3 = d_solver.mkDatatypeConstructorDecl("cons3");
-  cons3.addSelector("car", unresNs3);
-  cons3.addSelector("cdr", unresList3);
-  list3.addConstructor(cons3);
-  DatatypeConstructorDecl nil3 = d_solver.mkDatatypeConstructorDecl("nil3");
-  list3.addConstructor(nil3);
-
-  DatatypeDecl ns3 = d_solver.mkDatatypeDecl("ns3");
-  DatatypeConstructorDecl elem3 = d_solver.mkDatatypeConstructorDecl("elem3");
-  elem3.addSelector("ndata", d_solver.mkSetSort(unresList3));
-  ns3.addConstructor(elem3);
-
-  dtdecls.clear();
-  dtdecls.push_back(list3);
-  dtdecls.push_back(ns3);
-
-  dtsorts.clear();
-  // both are well-founded and have nested recursion
-  ASSERT_NO_THROW(dtsorts = d_solver.mkDatatypeSorts(dtdecls, unresTypes));
-  ASSERT_EQ(dtsorts.size(), 2);
-  ASSERT_TRUE(dtsorts[0].getDatatype().isWellFounded());
-  ASSERT_TRUE(dtsorts[1].getDatatype().isWellFounded());
-  ASSERT_TRUE(dtsorts[0].getDatatype().hasNestedRecursion());
-  ASSERT_TRUE(dtsorts[1].getDatatype().hasNestedRecursion());
-
-  /* Create mutual datatypes corresponding to this definition block:
-   *   DATATYPE
-   *     list4 = cons(car: set(ns4), cdr: list4) | nil,
-   *     ns4 = elem(ndata: list4)
-   *   END;
-   */
-  unresTypes.clear();
-  Sort unresNs4 = d_solver.mkUninterpretedSort("ns4");
-  unresTypes.insert(unresNs4);
-  Sort unresList4 = d_solver.mkUninterpretedSort("list4");
-  unresTypes.insert(unresList4);
-
-  DatatypeDecl list4 = d_solver.mkDatatypeDecl("list4");
-  DatatypeConstructorDecl cons4 = d_solver.mkDatatypeConstructorDecl("cons4");
-  cons4.addSelector("car", d_solver.mkSetSort(unresNs4));
-  cons4.addSelector("cdr", unresList4);
-  list4.addConstructor(cons4);
-  DatatypeConstructorDecl nil4 = d_solver.mkDatatypeConstructorDecl("nil4");
-  list4.addConstructor(nil4);
-
-  DatatypeDecl ns4 = d_solver.mkDatatypeDecl("ns4");
-  DatatypeConstructorDecl elem4 = d_solver.mkDatatypeConstructorDecl("elem3");
-  elem4.addSelector("ndata", unresList4);
-  ns4.addConstructor(elem4);
-
-  dtdecls.clear();
-  dtdecls.push_back(list4);
-  dtdecls.push_back(ns4);
-
-  dtsorts.clear();
-  // both are well-founded and have nested recursion
-  ASSERT_NO_THROW(dtsorts = d_solver.mkDatatypeSorts(dtdecls, unresTypes));
-  ASSERT_EQ(dtsorts.size(), 2);
-  ASSERT_TRUE(dtsorts[0].getDatatype().isWellFounded());
-  ASSERT_TRUE(dtsorts[1].getDatatype().isWellFounded());
-  ASSERT_TRUE(dtsorts[0].getDatatype().hasNestedRecursion());
-  ASSERT_TRUE(dtsorts[1].getDatatype().hasNestedRecursion());
-
-  /* Create mutual datatypes corresponding to this definition block:
-   *   DATATYPE
-   *     list5[X] = cons(car: X, cdr: list5[list5[X]]) | nil
-   *   END;
-   */
-  unresTypes.clear();
-  Sort unresList5 = d_solver.mkSortConstructorSort("list5", 1);
-  unresTypes.insert(unresList5);
-
-  std::vector<Sort> v;
-  Sort x = d_solver.mkParamSort("X");
-  v.push_back(x);
-  DatatypeDecl list5 = d_solver.mkDatatypeDecl("list5", v);
-
-  std::vector<Sort> args;
-  args.push_back(x);
-  Sort urListX = unresList5.instantiate(args);
-  args[0] = urListX;
-  Sort urListListX = unresList5.instantiate(args);
-
-  DatatypeConstructorDecl cons5 = d_solver.mkDatatypeConstructorDecl("cons5");
-  cons5.addSelector("car", x);
-  cons5.addSelector("cdr", urListListX);
-  list5.addConstructor(cons5);
-  DatatypeConstructorDecl nil5 = d_solver.mkDatatypeConstructorDecl("nil5");
-  list5.addConstructor(nil5);
-
-  dtdecls.clear();
-  dtdecls.push_back(list5);
-
-  // well-founded and has nested recursion
-  ASSERT_NO_THROW(dtsorts = d_solver.mkDatatypeSorts(dtdecls, unresTypes));
-  ASSERT_EQ(dtsorts.size(), 1);
-  ASSERT_TRUE(dtsorts[0].getDatatype().isWellFounded());
-  ASSERT_TRUE(dtsorts[0].getDatatype().hasNestedRecursion());
-}
-
-TEST_F(TestApiBlackDatatype, datatypeSpecializedCons)
-{
-  /* Create mutual datatypes corresponding to this definition block:
-   *   DATATYPE
-   *     plist[X] = pcons(car: X, cdr: plist[X]) | pnil
-   *   END;
-   */
-  // Make unresolved types as placeholders
-  std::set<Sort> unresTypes;
-  Sort unresList = d_solver.mkSortConstructorSort("plist", 1);
-  unresTypes.insert(unresList);
-
-  std::vector<Sort> v;
-  Sort x = d_solver.mkParamSort("X");
-  v.push_back(x);
-  DatatypeDecl plist = d_solver.mkDatatypeDecl("plist", v);
-
-  std::vector<Sort> args;
-  args.push_back(x);
-  Sort urListX = unresList.instantiate(args);
-
-  DatatypeConstructorDecl pcons = d_solver.mkDatatypeConstructorDecl("pcons");
-  pcons.addSelector("car", x);
-  pcons.addSelector("cdr", urListX);
-  plist.addConstructor(pcons);
-  DatatypeConstructorDecl nil5 = d_solver.mkDatatypeConstructorDecl("pnil");
-  plist.addConstructor(nil5);
-
-  std::vector<DatatypeDecl> dtdecls;
-  dtdecls.push_back(plist);
-
-  std::vector<Sort> dtsorts;
-  // make the datatype sorts
-  ASSERT_NO_THROW(dtsorts = d_solver.mkDatatypeSorts(dtdecls, unresTypes));
-  ASSERT_EQ(dtsorts.size(), 1);
-  Datatype d = dtsorts[0].getDatatype();
-  DatatypeConstructor nilc = d[0];
-
-  Sort isort = d_solver.getIntegerSort();
-  std::vector<Sort> iargs;
-  iargs.push_back(isort);
-  Sort listInt = dtsorts[0].instantiate(iargs);
-
-  Term testConsTerm;
-  // get the specialized constructor term for list[Int]
-  ASSERT_NO_THROW(testConsTerm = nilc.getSpecializedConstructorTerm(listInt));
-  ASSERT_NE(testConsTerm, nilc.getConstructorTerm());
-  // error to get the specialized constructor term for Int
-  ASSERT_THROW(nilc.getSpecializedConstructorTerm(isort), CVC5ApiException);
-}
-}  // namespace test
-}  // namespace cvc5
diff --git a/test/unit/api/grammar_black.cpp b/test/unit/api/grammar_black.cpp
deleted file mode 100644 (file)
index 7b75565..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-/******************************************************************************
- * Top contributors (to current version):
- *   Aina Niemetz, Abdalrhman Mohamed
- *
- * This file is part of the cvc5 project.
- *
- * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
- * in the top-level source directory and their institutional affiliations.
- * All rights reserved.  See the file COPYING in the top-level source
- * directory for licensing information.
- * ****************************************************************************
- *
- * Black box testing of the guards of the C++ API functions.
- */
-
-#include "test_api.h"
-
-namespace cvc5 {
-
-using namespace api;
-
-namespace test {
-
-class TestApiBlackGrammar : public TestApi
-{
-};
-
-TEST_F(TestApiBlackGrammar, addRule)
-{
-  Sort boolean = d_solver.getBooleanSort();
-  Sort integer = d_solver.getIntegerSort();
-
-  Term nullTerm;
-  Term start = d_solver.mkVar(boolean);
-  Term nts = d_solver.mkVar(boolean);
-
-  Grammar g = d_solver.mkSygusGrammar({}, {start});
-
-  ASSERT_NO_THROW(g.addRule(start, d_solver.mkBoolean(false)));
-
-  ASSERT_THROW(g.addRule(nullTerm, d_solver.mkBoolean(false)),
-               CVC5ApiException);
-  ASSERT_THROW(g.addRule(start, nullTerm), CVC5ApiException);
-  ASSERT_THROW(g.addRule(nts, d_solver.mkBoolean(false)), CVC5ApiException);
-  ASSERT_THROW(g.addRule(start, d_solver.mkInteger(0)), CVC5ApiException);
-  ASSERT_THROW(g.addRule(start, nts), CVC5ApiException);
-
-  d_solver.synthFun("f", {}, boolean, g);
-
-  ASSERT_THROW(g.addRule(start, d_solver.mkBoolean(false)), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackGrammar, addRules)
-{
-  Sort boolean = d_solver.getBooleanSort();
-  Sort integer = d_solver.getIntegerSort();
-
-  Term nullTerm;
-  Term start = d_solver.mkVar(boolean);
-  Term nts = d_solver.mkVar(boolean);
-
-  Grammar g = d_solver.mkSygusGrammar({}, {start});
-
-  ASSERT_NO_THROW(g.addRules(start, {d_solver.mkBoolean(false)}));
-
-  ASSERT_THROW(g.addRules(nullTerm, {d_solver.mkBoolean(false)}),
-               CVC5ApiException);
-  ASSERT_THROW(g.addRules(start, {nullTerm}), CVC5ApiException);
-  ASSERT_THROW(g.addRules(nts, {d_solver.mkBoolean(false)}), CVC5ApiException);
-  ASSERT_THROW(g.addRules(start, {d_solver.mkInteger(0)}), CVC5ApiException);
-  ASSERT_THROW(g.addRules(start, {nts}), CVC5ApiException);
-
-  d_solver.synthFun("f", {}, boolean, g);
-
-  ASSERT_THROW(g.addRules(start, {d_solver.mkBoolean(false)}),
-               CVC5ApiException);
-}
-
-TEST_F(TestApiBlackGrammar, addAnyConstant)
-{
-  Sort boolean = d_solver.getBooleanSort();
-
-  Term nullTerm;
-  Term start = d_solver.mkVar(boolean);
-  Term nts = d_solver.mkVar(boolean);
-
-  Grammar g = d_solver.mkSygusGrammar({}, {start});
-
-  ASSERT_NO_THROW(g.addAnyConstant(start));
-  ASSERT_NO_THROW(g.addAnyConstant(start));
-
-  ASSERT_THROW(g.addAnyConstant(nullTerm), CVC5ApiException);
-  ASSERT_THROW(g.addAnyConstant(nts), CVC5ApiException);
-
-  d_solver.synthFun("f", {}, boolean, g);
-
-  ASSERT_THROW(g.addAnyConstant(start), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackGrammar, addAnyVariable)
-{
-  Sort boolean = d_solver.getBooleanSort();
-
-  Term nullTerm;
-  Term x = d_solver.mkVar(boolean);
-  Term start = d_solver.mkVar(boolean);
-  Term nts = d_solver.mkVar(boolean);
-
-  Grammar g1 = d_solver.mkSygusGrammar({x}, {start});
-  Grammar g2 = d_solver.mkSygusGrammar({}, {start});
-
-  ASSERT_NO_THROW(g1.addAnyVariable(start));
-  ASSERT_NO_THROW(g1.addAnyVariable(start));
-  ASSERT_NO_THROW(g2.addAnyVariable(start));
-
-  ASSERT_THROW(g1.addAnyVariable(nullTerm), CVC5ApiException);
-  ASSERT_THROW(g1.addAnyVariable(nts), CVC5ApiException);
-
-  d_solver.synthFun("f", {}, boolean, g1);
-
-  ASSERT_THROW(g1.addAnyVariable(start), CVC5ApiException);
-}
-}  // namespace test
-}  // namespace cvc5
diff --git a/test/unit/api/op_black.cpp b/test/unit/api/op_black.cpp
deleted file mode 100644 (file)
index fd45b1c..0000000
+++ /dev/null
@@ -1,280 +0,0 @@
-/******************************************************************************
- * Top contributors (to current version):
- *   Makai Mann, Aina Niemetz
- *
- * This file is part of the cvc5 project.
- *
- * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
- * in the top-level source directory and their institutional affiliations.
- * All rights reserved.  See the file COPYING in the top-level source
- * directory for licensing information.
- * ****************************************************************************
- *
- * Black box testing of the Op class.
- */
-
-#include "test_api.h"
-
-namespace cvc5 {
-
-using namespace api;
-
-namespace test {
-
-class TestApiBlackOp : public TestApi
-{
-};
-
-TEST_F(TestApiBlackOp, getKind)
-{
-  Op x;
-  x = d_solver.mkOp(BITVECTOR_EXTRACT, 31, 1);
-  ASSERT_NO_THROW(x.getKind());
-}
-
-TEST_F(TestApiBlackOp, isNull)
-{
-  Op x;
-  ASSERT_TRUE(x.isNull());
-  x = d_solver.mkOp(BITVECTOR_EXTRACT, 31, 1);
-  ASSERT_FALSE(x.isNull());
-}
-
-TEST_F(TestApiBlackOp, opFromKind)
-{
-  ASSERT_NO_THROW(d_solver.mkOp(PLUS));
-  ASSERT_THROW(d_solver.mkOp(BITVECTOR_EXTRACT), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackOp, getNumIndices)
-{
-  Op plus = d_solver.mkOp(PLUS);
-  Op divisible = d_solver.mkOp(DIVISIBLE, 4);
-  Op bitvector_repeat = d_solver.mkOp(BITVECTOR_REPEAT, 5);
-  Op bitvector_zero_extend = d_solver.mkOp(BITVECTOR_ZERO_EXTEND, 6);
-  Op bitvector_sign_extend = d_solver.mkOp(BITVECTOR_SIGN_EXTEND, 7);
-  Op bitvector_rotate_left = d_solver.mkOp(BITVECTOR_ROTATE_LEFT, 8);
-  Op bitvector_rotate_right = d_solver.mkOp(BITVECTOR_ROTATE_RIGHT, 9);
-  Op int_to_bitvector = d_solver.mkOp(INT_TO_BITVECTOR, 10);
-  Op iand = d_solver.mkOp(IAND, 3);
-  Op floatingpoint_to_ubv = d_solver.mkOp(FLOATINGPOINT_TO_UBV, 11);
-  Op floatingopint_to_sbv = d_solver.mkOp(FLOATINGPOINT_TO_SBV, 13);
-  Op floatingpoint_to_fp_ieee_bitvector =
-      d_solver.mkOp(FLOATINGPOINT_TO_FP_IEEE_BITVECTOR, 4, 25);
-  Op floatingpoint_to_fp_floatingpoint =
-      d_solver.mkOp(FLOATINGPOINT_TO_FP_FLOATINGPOINT, 4, 25);
-  Op floatingpoint_to_fp_real = d_solver.mkOp(FLOATINGPOINT_TO_FP_REAL, 4, 25);
-  Op floatingpoint_to_fp_signed_bitvector =
-      d_solver.mkOp(FLOATINGPOINT_TO_FP_SIGNED_BITVECTOR, 4, 25);
-  Op floatingpoint_to_fp_unsigned_bitvector =
-      d_solver.mkOp(FLOATINGPOINT_TO_FP_UNSIGNED_BITVECTOR, 4, 25);
-  Op floatingpoint_to_fp_generic =
-      d_solver.mkOp(FLOATINGPOINT_TO_FP_GENERIC, 4, 25);
-  Op regexp_loop = d_solver.mkOp(REGEXP_LOOP, 2, 3);
-
-  ASSERT_EQ(0, plus.getNumIndices());
-  ASSERT_EQ(1, divisible.getNumIndices());
-  ASSERT_EQ(1, bitvector_repeat.getNumIndices());
-  ASSERT_EQ(1, bitvector_zero_extend.getNumIndices());
-  ASSERT_EQ(1, bitvector_sign_extend.getNumIndices());
-  ASSERT_EQ(1, bitvector_rotate_left.getNumIndices());
-  ASSERT_EQ(1, bitvector_rotate_right.getNumIndices());
-  ASSERT_EQ(1, int_to_bitvector.getNumIndices());
-  ASSERT_EQ(1, iand.getNumIndices());
-  ASSERT_EQ(1, floatingpoint_to_ubv.getNumIndices());
-  ASSERT_EQ(1, floatingopint_to_sbv.getNumIndices());
-  ASSERT_EQ(2, floatingpoint_to_fp_ieee_bitvector.getNumIndices());
-  ASSERT_EQ(2, floatingpoint_to_fp_floatingpoint.getNumIndices());
-  ASSERT_EQ(2, floatingpoint_to_fp_real.getNumIndices());
-  ASSERT_EQ(2, floatingpoint_to_fp_signed_bitvector.getNumIndices());
-  ASSERT_EQ(2, floatingpoint_to_fp_unsigned_bitvector.getNumIndices());
-  ASSERT_EQ(2, floatingpoint_to_fp_generic.getNumIndices());
-  ASSERT_EQ(2, regexp_loop.getNumIndices());
-}
-
-TEST_F(TestApiBlackOp, subscriptOperator)
-{
-  Op plus = d_solver.mkOp(PLUS);
-  Op divisible = d_solver.mkOp(DIVISIBLE, 4);
-  Op bitvector_repeat = d_solver.mkOp(BITVECTOR_REPEAT, 4);
-  Op bitvector_zero_extend = d_solver.mkOp(BITVECTOR_ZERO_EXTEND, 4);
-  Op bitvector_sign_extend = d_solver.mkOp(BITVECTOR_SIGN_EXTEND, 4);
-  Op bitvector_rotate_left = d_solver.mkOp(BITVECTOR_ROTATE_LEFT, 4);
-  Op bitvector_rotate_right = d_solver.mkOp(BITVECTOR_ROTATE_RIGHT, 4);
-  Op int_to_bitvector = d_solver.mkOp(INT_TO_BITVECTOR, 4);
-  Op iand = d_solver.mkOp(IAND, 4);
-  Op floatingpoint_to_ubv = d_solver.mkOp(FLOATINGPOINT_TO_UBV, 4);
-  Op floatingopint_to_sbv = d_solver.mkOp(FLOATINGPOINT_TO_SBV, 4);
-  Op floatingpoint_to_fp_ieee_bitvector =
-      d_solver.mkOp(FLOATINGPOINT_TO_FP_IEEE_BITVECTOR, 4, 5);
-  Op floatingpoint_to_fp_floatingpoint =
-      d_solver.mkOp(FLOATINGPOINT_TO_FP_FLOATINGPOINT, 4, 5);
-  Op floatingpoint_to_fp_real = d_solver.mkOp(FLOATINGPOINT_TO_FP_REAL, 4, 5);
-  Op floatingpoint_to_fp_signed_bitvector =
-      d_solver.mkOp(FLOATINGPOINT_TO_FP_SIGNED_BITVECTOR, 4, 5);
-  Op floatingpoint_to_fp_unsigned_bitvector =
-      d_solver.mkOp(FLOATINGPOINT_TO_FP_UNSIGNED_BITVECTOR, 4, 5);
-  Op floatingpoint_to_fp_generic =
-      d_solver.mkOp(FLOATINGPOINT_TO_FP_GENERIC, 4, 5);
-  Op regexp_loop = d_solver.mkOp(REGEXP_LOOP, 4, 5);
-
-  ASSERT_THROW(plus[0], CVC5ApiException);
-  ASSERT_EQ(4, divisible[0].getUInt32Value());
-  ASSERT_EQ(4, bitvector_repeat[0].getUInt32Value());
-  ASSERT_EQ(4, bitvector_zero_extend[0].getUInt32Value());
-  ASSERT_EQ(4, bitvector_sign_extend[0].getUInt32Value());
-  ASSERT_EQ(4, bitvector_rotate_left[0].getUInt32Value());
-  ASSERT_EQ(4, bitvector_rotate_right[0].getUInt32Value());
-  ASSERT_EQ(4, int_to_bitvector[0].getUInt32Value());
-  ASSERT_EQ(4, iand[0].getUInt32Value());
-  ASSERT_EQ(4, floatingpoint_to_ubv[0].getUInt32Value());
-  ASSERT_EQ(4, floatingopint_to_sbv[0].getUInt32Value());
-  ASSERT_EQ(4, floatingpoint_to_fp_ieee_bitvector[0].getUInt32Value());
-  ASSERT_EQ(4, floatingpoint_to_fp_floatingpoint[0].getUInt32Value());
-  ASSERT_EQ(4, floatingpoint_to_fp_real[0].getUInt32Value());
-  ASSERT_EQ(4, floatingpoint_to_fp_signed_bitvector[0].getUInt32Value());
-  ASSERT_EQ(4, floatingpoint_to_fp_unsigned_bitvector[0].getUInt32Value());
-  ASSERT_EQ(4, floatingpoint_to_fp_generic[0].getUInt32Value());
-  ASSERT_EQ(4, regexp_loop[0].getUInt32Value());
-}
-
-TEST_F(TestApiBlackOp, getIndicesString)
-{
-  Op x;
-  ASSERT_THROW(x.getIndices<std::string>(), CVC5ApiException);
-
-  Op divisible_ot = d_solver.mkOp(DIVISIBLE, 4);
-  ASSERT_TRUE(divisible_ot.isIndexed());
-  std::string divisible_idx = divisible_ot.getIndices<std::string>();
-  ASSERT_EQ(divisible_idx, "4");
-}
-
-TEST_F(TestApiBlackOp, getIndicesUint)
-{
-  Op bitvector_repeat_ot = d_solver.mkOp(BITVECTOR_REPEAT, 5);
-  ASSERT_TRUE(bitvector_repeat_ot.isIndexed());
-  uint32_t bitvector_repeat_idx = bitvector_repeat_ot.getIndices<uint32_t>();
-  ASSERT_EQ(bitvector_repeat_idx, 5);
-  ASSERT_THROW(
-      (bitvector_repeat_ot.getIndices<std::pair<uint32_t, uint32_t>>()),
-      CVC5ApiException);
-
-  Op bitvector_zero_extend_ot = d_solver.mkOp(BITVECTOR_ZERO_EXTEND, 6);
-  uint32_t bitvector_zero_extend_idx =
-      bitvector_zero_extend_ot.getIndices<uint32_t>();
-  ASSERT_EQ(bitvector_zero_extend_idx, 6);
-
-  Op bitvector_sign_extend_ot = d_solver.mkOp(BITVECTOR_SIGN_EXTEND, 7);
-  uint32_t bitvector_sign_extend_idx =
-      bitvector_sign_extend_ot.getIndices<uint32_t>();
-  ASSERT_EQ(bitvector_sign_extend_idx, 7);
-
-  Op bitvector_rotate_left_ot = d_solver.mkOp(BITVECTOR_ROTATE_LEFT, 8);
-  uint32_t bitvector_rotate_left_idx =
-      bitvector_rotate_left_ot.getIndices<uint32_t>();
-  ASSERT_EQ(bitvector_rotate_left_idx, 8);
-
-  Op bitvector_rotate_right_ot = d_solver.mkOp(BITVECTOR_ROTATE_RIGHT, 9);
-  uint32_t bitvector_rotate_right_idx =
-      bitvector_rotate_right_ot.getIndices<uint32_t>();
-  ASSERT_EQ(bitvector_rotate_right_idx, 9);
-
-  Op int_to_bitvector_ot = d_solver.mkOp(INT_TO_BITVECTOR, 10);
-  uint32_t int_to_bitvector_idx = int_to_bitvector_ot.getIndices<uint32_t>();
-  ASSERT_EQ(int_to_bitvector_idx, 10);
-
-  Op floatingpoint_to_ubv_ot = d_solver.mkOp(FLOATINGPOINT_TO_UBV, 11);
-  uint32_t floatingpoint_to_ubv_idx =
-      floatingpoint_to_ubv_ot.getIndices<uint32_t>();
-  ASSERT_EQ(floatingpoint_to_ubv_idx, 11);
-
-  Op floatingpoint_to_sbv_ot = d_solver.mkOp(FLOATINGPOINT_TO_SBV, 13);
-  uint32_t floatingpoint_to_sbv_idx =
-      floatingpoint_to_sbv_ot.getIndices<uint32_t>();
-  ASSERT_EQ(floatingpoint_to_sbv_idx, 13);
-}
-
-TEST_F(TestApiBlackOp, getIndicesPairUint)
-{
-  Op bitvector_extract_ot = d_solver.mkOp(BITVECTOR_EXTRACT, 4, 0);
-  ASSERT_TRUE(bitvector_extract_ot.isIndexed());
-  std::pair<uint32_t, uint32_t> bitvector_extract_indices =
-      bitvector_extract_ot.getIndices<std::pair<uint32_t, uint32_t>>();
-  ASSERT_TRUE(
-      (bitvector_extract_indices == std::pair<uint32_t, uint32_t>{4, 0}));
-
-  Op floatingpoint_to_fp_ieee_bitvector_ot =
-      d_solver.mkOp(FLOATINGPOINT_TO_FP_IEEE_BITVECTOR, 4, 25);
-  std::pair<uint32_t, uint32_t> floatingpoint_to_fp_ieee_bitvector_indices =
-      floatingpoint_to_fp_ieee_bitvector_ot
-          .getIndices<std::pair<uint32_t, uint32_t>>();
-  ASSERT_TRUE((floatingpoint_to_fp_ieee_bitvector_indices
-               == std::pair<uint32_t, uint32_t>{4, 25}));
-
-  Op floatingpoint_to_fp_floatingpoint_ot =
-      d_solver.mkOp(FLOATINGPOINT_TO_FP_FLOATINGPOINT, 4, 25);
-  std::pair<uint32_t, uint32_t> floatingpoint_to_fp_floatingpoint_indices =
-      floatingpoint_to_fp_floatingpoint_ot
-          .getIndices<std::pair<uint32_t, uint32_t>>();
-  ASSERT_TRUE((floatingpoint_to_fp_floatingpoint_indices
-               == std::pair<uint32_t, uint32_t>{4, 25}));
-
-  Op floatingpoint_to_fp_real_ot =
-      d_solver.mkOp(FLOATINGPOINT_TO_FP_REAL, 4, 25);
-  std::pair<uint32_t, uint32_t> floatingpoint_to_fp_real_indices =
-      floatingpoint_to_fp_real_ot.getIndices<std::pair<uint32_t, uint32_t>>();
-  ASSERT_TRUE((floatingpoint_to_fp_real_indices
-               == std::pair<uint32_t, uint32_t>{4, 25}));
-
-  Op floatingpoint_to_fp_signed_bitvector_ot =
-      d_solver.mkOp(FLOATINGPOINT_TO_FP_SIGNED_BITVECTOR, 4, 25);
-  std::pair<uint32_t, uint32_t> floatingpoint_to_fp_signed_bitvector_indices =
-      floatingpoint_to_fp_signed_bitvector_ot
-          .getIndices<std::pair<uint32_t, uint32_t>>();
-  ASSERT_TRUE((floatingpoint_to_fp_signed_bitvector_indices
-               == std::pair<uint32_t, uint32_t>{4, 25}));
-
-  Op floatingpoint_to_fp_unsigned_bitvector_ot =
-      d_solver.mkOp(FLOATINGPOINT_TO_FP_UNSIGNED_BITVECTOR, 4, 25);
-  std::pair<uint32_t, uint32_t> floatingpoint_to_fp_unsigned_bitvector_indices =
-      floatingpoint_to_fp_unsigned_bitvector_ot
-          .getIndices<std::pair<uint32_t, uint32_t>>();
-  ASSERT_TRUE((floatingpoint_to_fp_unsigned_bitvector_indices
-               == std::pair<uint32_t, uint32_t>{4, 25}));
-
-  Op floatingpoint_to_fp_generic_ot =
-      d_solver.mkOp(FLOATINGPOINT_TO_FP_GENERIC, 4, 25);
-  std::pair<uint32_t, uint32_t> floatingpoint_to_fp_generic_indices =
-      floatingpoint_to_fp_generic_ot
-          .getIndices<std::pair<uint32_t, uint32_t>>();
-  ASSERT_TRUE((floatingpoint_to_fp_generic_indices
-               == std::pair<uint32_t, uint32_t>{4, 25}));
-  ASSERT_THROW(floatingpoint_to_fp_generic_ot.getIndices<std::string>(),
-               CVC5ApiException);
-}
-
-TEST_F(TestApiBlackOp, getIndicesVector)
-{
-  std::vector<uint32_t> indices = {0, 3, 2, 0, 1, 2};
-  Op tuple_project_op = d_solver.mkOp(TUPLE_PROJECT, indices);
-
-  ASSERT_TRUE(tuple_project_op.isIndexed());
-  std::vector<Term> tuple_project_extract_indices =
-      tuple_project_op.getIndices<std::vector<Term>>();
-  ASSERT_THROW(tuple_project_op.getIndices<std::string>(), CVC5ApiException);
-  for (size_t i = 0; i < indices.size(); i++)
-  {
-    ASSERT_EQ(indices[i], tuple_project_extract_indices[i].getUInt32Value());
-    ASSERT_EQ(indices[i], tuple_project_op[i].getUInt32Value());
-  }
-}
-
-TEST_F(TestApiBlackOp, opScopingToString)
-{
-  Op bitvector_repeat_ot = d_solver.mkOp(BITVECTOR_REPEAT, 5);
-  std::string op_repr = bitvector_repeat_ot.toString();
-  Solver solver2;
-  ASSERT_EQ(bitvector_repeat_ot.toString(), op_repr);
-}
-}  // namespace test
-}  // namespace cvc5
diff --git a/test/unit/api/op_white.cpp b/test/unit/api/op_white.cpp
deleted file mode 100644 (file)
index 3995273..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/******************************************************************************
- * Top contributors (to current version):
- *   Aina Niemetz, Makai Mann
- *
- * This file is part of the cvc5 project.
- *
- * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
- * in the top-level source directory and their institutional affiliations.
- * All rights reserved.  See the file COPYING in the top-level source
- * directory for licensing information.
- * ****************************************************************************
- *
- * White box testing of the Op class.
- */
-
-#include "test_api.h"
-
-namespace cvc5 {
-
-using namespace api;
-
-namespace test {
-
-class TestApiWhiteOp : public TestApi
-{
-};
-
-TEST_F(TestApiWhiteOp, opFromKind)
-{
-  Op plus(&d_solver, PLUS);
-  ASSERT_FALSE(plus.isIndexed());
-  ASSERT_THROW(plus.getIndices<uint32_t>(), CVC5ApiException);
-  ASSERT_EQ(plus, d_solver.mkOp(PLUS));
-}
-}  // namespace test
-}  // namespace cvc5
diff --git a/test/unit/api/python/CMakeLists.txt b/test/unit/api/python/CMakeLists.txt
new file mode 100644 (file)
index 0000000..cbf9629
--- /dev/null
@@ -0,0 +1,40 @@
+###############################################################################
+# Top contributors (to current version):
+#   Yoni Zohar, Aina Niemetz, Mathias Preiner
+#
+# This file is part of the cvc5 project.
+#
+# Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
+# in the top-level source directory and their institutional affiliations.
+# All rights reserved.  See the file COPYING in the top-level source
+# directory for licensing information.
+# #############################################################################
+#
+# The build system configuration.
+##
+
+# Check if the pytest Python module is installed.
+check_python_module("pytest")
+
+# Add Python bindings API tests.
+macro(cvc5_add_python_api_unit_test name filename)
+# We create test target 'python/unit/api/myapitest' and run it with
+# 'ctest -R "python/unit/api/myapitest"'.
+  set(test_name unit/api/python/${name})
+  add_test (NAME ${test_name}
+    COMMAND ${PYTHON_EXECUTABLE}
+            -m pytest ${CMAKE_CURRENT_SOURCE_DIR}/${filename}
+    # directory for importing the python bindings
+    WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/src/api/python)
+    set_tests_properties(${test_name} PROPERTIES LABELS "unit")
+endmacro()
+
+# add specific test files
+cvc5_add_python_api_unit_test(pytest_solver test_solver.py)
+cvc5_add_python_api_unit_test(pytest_sort test_sort.py)
+cvc5_add_python_api_unit_test(pytest_term test_term.py)
+cvc5_add_python_api_unit_test(pytest_datatype_api test_datatype_api.py)
+cvc5_add_python_api_unit_test(pytest_grammar test_grammar.py)
+cvc5_add_python_api_unit_test(pytest_to_python_obj test_to_python_obj.py)
+cvc5_add_python_api_unit_test(pytest_op test_op.py)
+cvc5_add_python_api_unit_test(pytest_result test_result.py)
diff --git a/test/unit/api/python/__init__.py b/test/unit/api/python/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/test/unit/api/python/test_datatype_api.py b/test/unit/api/python/test_datatype_api.py
new file mode 100644 (file)
index 0000000..d8a4c26
--- /dev/null
@@ -0,0 +1,566 @@
+###############################################################################
+# Top contributors (to current version):
+#   Yoni Zohar
+#
+# This file is part of the cvc5 project.
+#
+# Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
+# in the top-level source directory and their institutional affiliations.
+# All rights reserved.  See the file COPYING in the top-level source
+# directory for licensing information.
+# #############################################################################
+##
+
+import pytest
+import pycvc5
+from pycvc5 import kinds
+from pycvc5 import Sort, Term 
+from pycvc5 import DatatypeDecl
+from pycvc5 import Datatype
+from pycvc5 import DatatypeConstructorDecl
+from pycvc5 import DatatypeConstructor
+from pycvc5 import DatatypeSelector
+
+
+@pytest.fixture
+def solver():
+    return pycvc5.Solver()
+
+
+def test_mk_datatype_sort(solver):
+    dtypeSpec = solver.mkDatatypeDecl("list")
+    cons = solver.mkDatatypeConstructorDecl("cons")
+    cons.addSelector("head", solver.getIntegerSort())
+    dtypeSpec.addConstructor(cons)
+    nil = solver.mkDatatypeConstructorDecl("nil")
+    dtypeSpec.addConstructor(nil)
+    listSort = solver.mkDatatypeSort(dtypeSpec)
+    d = listSort.getDatatype()
+    consConstr = d[0]
+    nilConstr = d[1]
+    with pytest.raises(RuntimeError):
+        d[2]
+    consConstr.getConstructorTerm()
+    nilConstr.getConstructorTerm()
+
+def test_is_null(solver):
+  # creating empty (null) objects.
+  dtypeSpec = DatatypeDecl(solver)
+  cons = DatatypeConstructorDecl(solver)
+  d = Datatype(solver)
+  consConstr = DatatypeConstructor(solver)
+  sel = DatatypeSelector(solver)
+
+  # verifying that the objects are considered null.
+  assert dtypeSpec.isNull()
+  assert cons.isNull()
+  assert d.isNull()
+  assert consConstr.isNull()
+  assert sel.isNull()
+
+  # changing the objects to be non-null
+  dtypeSpec = solver.mkDatatypeDecl("list");
+  cons = solver.mkDatatypeConstructorDecl("cons");
+  cons.addSelector("head", solver.getIntegerSort());
+  dtypeSpec.addConstructor(cons);
+  listSort = solver.mkDatatypeSort(dtypeSpec)
+  d = listSort.getDatatype();
+  consConstr = d[0];
+  sel = consConstr[0];
+
+  # verifying that the new objects are non-null
+  assert not dtypeSpec.isNull()
+  assert not cons.isNull()
+  assert not d.isNull()
+  assert not consConstr.isNull()
+  assert not sel.isNull()
+
+def test_mk_datatype_sorts(solver):
+    # Create two mutual datatypes corresponding to this definition
+    # block:
+    #
+    #   DATATYPE
+    #     tree = node(left: tree, right: tree) | leaf(data: list),
+    #     list = cons(car: tree, cdr: list) | nil
+    #   END
+    #
+
+    #Make unresolved types as placeholders
+    unresTypes = set([])
+    unresTree = solver.mkUninterpretedSort("tree")
+    unresList = solver.mkUninterpretedSort("list")
+    unresTypes.add(unresTree)
+    unresTypes.add(unresList)
+
+    tree = solver.mkDatatypeDecl("tree")
+    node = solver.mkDatatypeConstructorDecl("node")
+    node.addSelector("left", unresTree)
+    node.addSelector("right", unresTree)
+    tree.addConstructor(node)
+
+    leaf = solver.mkDatatypeConstructorDecl("leaf")
+    leaf.addSelector("data", unresList)
+    tree.addConstructor(leaf)
+
+    llist = solver.mkDatatypeDecl("list")
+    cons = solver.mkDatatypeConstructorDecl("cons")
+    cons.addSelector("car", unresTree)
+    cons.addSelector("cdr", unresTree)
+    llist.addConstructor(cons)
+
+    nil = solver.mkDatatypeConstructorDecl("nil")
+    llist.addConstructor(nil)
+
+    dtdecls = []
+    dtdecls.append(tree)
+    dtdecls.append(llist)
+    dtsorts = []
+    dtsorts = solver.mkDatatypeSorts(dtdecls, unresTypes)
+    assert len(dtsorts) == len(dtdecls)
+    for i in range(0, len(dtdecls)):
+        assert dtsorts[i].isDatatype()
+        assert not dtsorts[i].getDatatype().isFinite()
+        assert dtsorts[i].getDatatype().getName() == dtdecls[i].getName()
+    # verify the resolution was correct
+    dtTree = dtsorts[0].getDatatype()
+    dtcTreeNode = dtTree[0]
+    assert dtcTreeNode.getName() == "node"
+    dtsTreeNodeLeft = dtcTreeNode[0]
+    assert dtsTreeNodeLeft.getName() == "left"
+    # argument type should have resolved to be recursive
+    assert dtsTreeNodeLeft.getRangeSort().isDatatype()
+    assert dtsTreeNodeLeft.getRangeSort() == dtsorts[0]
+
+    # fails due to empty datatype
+    dtdeclsBad = []
+    emptyD = solver.mkDatatypeDecl("emptyD")
+    dtdeclsBad.append(emptyD)
+    with pytest.raises(RuntimeError):
+        solver.mkDatatypeSorts(dtdeclsBad)
+
+
+def test_datatype_structs(solver):
+    intSort = solver.getIntegerSort()
+    boolSort = solver.getBooleanSort()
+
+    # create datatype sort to test
+    dtypeSpec = solver.mkDatatypeDecl("list")
+    cons = solver.mkDatatypeConstructorDecl("cons")
+    cons.addSelector("head", intSort)
+    cons.addSelectorSelf("tail")
+    nullSort = Sort(solver)
+    with pytest.raises(RuntimeError):
+        cons.addSelector("null", nullSort)
+    dtypeSpec.addConstructor(cons)
+    nil = solver.mkDatatypeConstructorDecl("nil")
+    dtypeSpec.addConstructor(nil)
+    dtypeSort = solver.mkDatatypeSort(dtypeSpec)
+    dt = dtypeSort.getDatatype()
+    assert not dt.isCodatatype()
+    assert not dt.isTuple()
+    assert not dt.isRecord()
+    assert not dt.isFinite()
+    assert dt.isWellFounded()
+    # get constructor
+    dcons = dt[0]
+    consTerm = dcons.getConstructorTerm()
+    assert dcons.getNumSelectors() == 2
+
+    # create datatype sort to test
+    dtypeSpecEnum = solver.mkDatatypeDecl("enum")
+    ca = solver.mkDatatypeConstructorDecl("A")
+    dtypeSpecEnum.addConstructor(ca)
+    cb = solver.mkDatatypeConstructorDecl("B")
+    dtypeSpecEnum.addConstructor(cb)
+    cc = solver.mkDatatypeConstructorDecl("C")
+    dtypeSpecEnum.addConstructor(cc)
+    dtypeSortEnum = solver.mkDatatypeSort(dtypeSpecEnum)
+    dtEnum = dtypeSortEnum.getDatatype()
+    assert not dtEnum.isTuple()
+    assert dtEnum.isFinite()
+
+    # create codatatype
+    dtypeSpecStream = solver.mkDatatypeDecl("stream", True)
+    consStream = solver.mkDatatypeConstructorDecl("cons")
+    consStream.addSelector("head", intSort)
+    consStream.addSelectorSelf("tail")
+    dtypeSpecStream.addConstructor(consStream)
+    dtypeSortStream = solver.mkDatatypeSort(dtypeSpecStream)
+    dtStream = dtypeSortStream.getDatatype()
+    assert dtStream.isCodatatype()
+    assert not dtStream.isFinite()
+    # codatatypes may be well-founded
+    assert dtStream.isWellFounded()
+
+    # create tuple
+    tupSort = solver.mkTupleSort([boolSort])
+    dtTuple = tupSort.getDatatype()
+    assert dtTuple.isTuple()
+    assert not dtTuple.isRecord()
+    assert dtTuple.isFinite()
+    assert dtTuple.isWellFounded()
+
+    # create record
+    fields = [("b", boolSort), ("i", intSort)]
+    recSort = solver.mkRecordSort(fields)
+    assert recSort.isDatatype()
+    dtRecord = recSort.getDatatype()
+    assert not dtRecord.isTuple()
+    assert dtRecord.isRecord()
+    assert not dtRecord.isFinite()
+    assert dtRecord.isWellFounded()
+
+
+def test_datatype_names(solver):
+    intSort = solver.getIntegerSort()
+
+    # create datatype sort to test
+    dtypeSpec = solver.mkDatatypeDecl("list")
+    dtypeSpec.getName()
+    assert dtypeSpec.getName() == "list"
+    cons = solver.mkDatatypeConstructorDecl("cons")
+    cons.addSelector("head", intSort)
+    cons.addSelectorSelf("tail")
+    dtypeSpec.addConstructor(cons)
+    nil = solver.mkDatatypeConstructorDecl("nil")
+    dtypeSpec.addConstructor(nil)
+    dtypeSort = solver.mkDatatypeSort(dtypeSpec)
+    dt = dtypeSort.getDatatype()
+    assert dt.getName() == "list"
+    dt.getConstructor("nil")
+    dt["cons"]
+    with pytest.raises(RuntimeError):
+        dt.getConstructor("head")
+    with pytest.raises(RuntimeError):
+        dt.getConstructor("")
+
+    dcons = dt[0]
+    assert dcons.getName() == "cons"
+    dcons.getSelector("head")
+    dcons["tail"]
+    with pytest.raises(RuntimeError):
+        dcons.getSelector("cons")
+
+    # get selector
+    dselTail = dcons[1]
+    assert dselTail.getName() == "tail"
+    assert dselTail.getRangeSort() == dtypeSort
+
+    # get selector from datatype
+    dt.getSelector("head")
+    with pytest.raises(RuntimeError):
+        dt.getSelector("cons")
+
+    # possible to construct null datatype declarations if not using mkDatatypeDecl
+    with pytest.raises(RuntimeError):
+        DatatypeDecl(solver).getName()
+
+
+def test_parametric_datatype(solver):
+    v = []
+    t1 = solver.mkParamSort("T1")
+    t2 = solver.mkParamSort("T2")
+    v.append(t1)
+    v.append(t2)
+    pairSpec = solver.mkDatatypeDecl("pair", v)
+
+    mkpair = solver.mkDatatypeConstructorDecl("mk-pair")
+    mkpair.addSelector("first", t1)
+    mkpair.addSelector("second", t2)
+    pairSpec.addConstructor(mkpair)
+
+    pairType = solver.mkDatatypeSort(pairSpec)
+
+    assert pairType.getDatatype().isParametric()
+
+    v.clear()
+    v.append(solver.getIntegerSort())
+    v.append(solver.getIntegerSort())
+    pairIntInt = pairType.instantiate(v)
+    v.clear()
+    v.append(solver.getRealSort())
+    v.append(solver.getRealSort())
+    pairRealReal = pairType.instantiate(v)
+    v.clear()
+    v.append(solver.getRealSort())
+    v.append(solver.getIntegerSort())
+    pairRealInt = pairType.instantiate(v)
+    v.clear()
+    v.append(solver.getIntegerSort())
+    v.append(solver.getRealSort())
+    pairIntReal = pairType.instantiate(v)
+
+    assert pairIntInt != pairRealReal
+    assert pairIntReal != pairRealReal
+    assert pairRealInt != pairRealReal
+    assert pairIntInt != pairIntReal
+    assert pairIntInt != pairRealInt
+    assert pairIntReal != pairRealInt
+
+    assert pairRealReal.isComparableTo(pairRealReal)
+    assert not pairIntReal.isComparableTo(pairRealReal)
+    assert not pairRealInt.isComparableTo(pairRealReal)
+    assert not pairIntInt.isComparableTo(pairRealReal)
+    assert not pairRealReal.isComparableTo(pairRealInt)
+    assert not pairIntReal.isComparableTo(pairRealInt)
+    assert pairRealInt.isComparableTo(pairRealInt)
+    assert not pairIntInt.isComparableTo(pairRealInt)
+    assert not pairRealReal.isComparableTo(pairIntReal)
+    assert pairIntReal.isComparableTo(pairIntReal)
+    assert not pairRealInt.isComparableTo(pairIntReal)
+    assert not pairIntInt.isComparableTo(pairIntReal)
+    assert not pairRealReal.isComparableTo(pairIntInt)
+    assert not pairIntReal.isComparableTo(pairIntInt)
+    assert not pairRealInt.isComparableTo(pairIntInt)
+    assert pairIntInt.isComparableTo(pairIntInt)
+
+    assert pairRealReal.isSubsortOf(pairRealReal)
+    assert not pairIntReal.isSubsortOf(pairRealReal)
+    assert not pairRealInt.isSubsortOf(pairRealReal)
+    assert not pairIntInt.isSubsortOf(pairRealReal)
+    assert not pairRealReal.isSubsortOf(pairRealInt)
+    assert not pairIntReal.isSubsortOf(pairRealInt)
+    assert pairRealInt.isSubsortOf(pairRealInt)
+    assert not pairIntInt.isSubsortOf(pairRealInt)
+    assert not pairRealReal.isSubsortOf(pairIntReal)
+    assert pairIntReal.isSubsortOf(pairIntReal)
+    assert not pairRealInt.isSubsortOf(pairIntReal)
+    assert not pairIntInt.isSubsortOf(pairIntReal)
+    assert not pairRealReal.isSubsortOf(pairIntInt)
+    assert not pairIntReal.isSubsortOf(pairIntInt)
+    assert not pairRealInt.isSubsortOf(pairIntInt)
+    assert pairIntInt.isSubsortOf(pairIntInt)
+
+
+def test_datatype_simply_rec(solver):
+    # Create mutual datatypes corresponding to this definition block:
+    #
+    #   DATATYPE
+    #     wlist = leaf(data: list),
+    #     list = cons(car: wlist, cdr: list) | nil,
+    #     ns = elem(ndata: set(wlist)) | elemArray(ndata2: array(list, list))
+    #   END
+
+    # Make unresolved types as placeholders
+    unresTypes = set([])
+    unresWList = solver.mkUninterpretedSort("wlist")
+    unresList = solver.mkUninterpretedSort("list")
+    unresNs = solver.mkUninterpretedSort("ns")
+    unresTypes.add(unresWList)
+    unresTypes.add(unresList)
+    unresTypes.add(unresNs)
+
+    wlist = solver.mkDatatypeDecl("wlist")
+    leaf = solver.mkDatatypeConstructorDecl("leaf")
+    leaf.addSelector("data", unresList)
+    wlist.addConstructor(leaf)
+
+    llist = solver.mkDatatypeDecl("list")
+    cons = solver.mkDatatypeConstructorDecl("cons")
+    cons.addSelector("car", unresWList)
+    cons.addSelector("cdr", unresList)
+    llist.addConstructor(cons)
+    nil = solver.mkDatatypeConstructorDecl("nil")
+    llist.addConstructor(nil)
+
+    ns = solver.mkDatatypeDecl("ns")
+    elem = solver.mkDatatypeConstructorDecl("elem")
+    elem.addSelector("ndata", solver.mkSetSort(unresWList))
+    ns.addConstructor(elem)
+    elemArray = solver.mkDatatypeConstructorDecl("elemArray")
+    elemArray.addSelector("ndata", solver.mkArraySort(unresList, unresList))
+    ns.addConstructor(elemArray)
+
+    dtdecls = [wlist, llist, ns]
+    # this is well-founded and has no nested recursion
+    dtsorts = solver.mkDatatypeSorts(dtdecls, unresTypes)
+    assert len(dtsorts) == 3
+    assert dtsorts[0].getDatatype().isWellFounded()
+    assert dtsorts[1].getDatatype().isWellFounded()
+    assert dtsorts[2].getDatatype().isWellFounded()
+    assert not dtsorts[0].getDatatype().hasNestedRecursion()
+    assert not dtsorts[1].getDatatype().hasNestedRecursion()
+    assert not dtsorts[2].getDatatype().hasNestedRecursion()
+
+    # Create mutual datatypes corresponding to this definition block:
+    #   DATATYPE
+    #     ns2 = elem2(ndata: array(int,ns2)) | nil2
+    #   END
+
+    unresTypes.clear()
+    unresNs2 = solver.mkUninterpretedSort("ns2")
+    unresTypes.add(unresNs2)
+
+    ns2 = solver.mkDatatypeDecl("ns2")
+    elem2 = solver.mkDatatypeConstructorDecl("elem2")
+    elem2.addSelector("ndata",
+                      solver.mkArraySort(solver.getIntegerSort(), unresNs2))
+    ns2.addConstructor(elem2)
+    nil2 = solver.mkDatatypeConstructorDecl("nil2")
+    ns2.addConstructor(nil2)
+
+    dtdecls.clear()
+    dtdecls.append(ns2)
+
+    # this is not well-founded due to non-simple recursion
+    dtsorts = solver.mkDatatypeSorts(dtdecls, unresTypes)
+    assert len(dtsorts) == 1
+    assert dtsorts[0].getDatatype()[0][0].getRangeSort().isArray()
+    assert dtsorts[0].getDatatype()[0][0].getRangeSort().getArrayElementSort() \
+        == dtsorts[0]
+    assert dtsorts[0].getDatatype().isWellFounded()
+    assert dtsorts[0].getDatatype().hasNestedRecursion()
+
+    # Create mutual datatypes corresponding to this definition block:
+    #   DATATYPE
+    #     list3 = cons3(car: ns3, cdr: list3) | nil3,
+    #     ns3 = elem3(ndata: set(list3))
+    #   END
+
+    unresTypes.clear()
+    unresNs3 = solver.mkUninterpretedSort("ns3")
+    unresTypes.add(unresNs3)
+    unresList3 = solver.mkUninterpretedSort("list3")
+    unresTypes.add(unresList3)
+
+    list3 = solver.mkDatatypeDecl("list3")
+    cons3 = solver.mkDatatypeConstructorDecl("cons3")
+    cons3.addSelector("car", unresNs3)
+    cons3.addSelector("cdr", unresList3)
+    list3.addConstructor(cons3)
+    nil3 = solver.mkDatatypeConstructorDecl("nil3")
+    list3.addConstructor(nil3)
+
+    ns3 = solver.mkDatatypeDecl("ns3")
+    elem3 = solver.mkDatatypeConstructorDecl("elem3")
+    elem3.addSelector("ndata", solver.mkSetSort(unresList3))
+    ns3.addConstructor(elem3)
+
+    dtdecls.clear()
+    dtdecls.append(list3)
+    dtdecls.append(ns3)
+
+    # both are well-founded and have nested recursion
+    dtsorts = solver.mkDatatypeSorts(dtdecls, unresTypes)
+    assert len(dtsorts) == 2
+    assert dtsorts[0].getDatatype().isWellFounded()
+    assert dtsorts[1].getDatatype().isWellFounded()
+    assert dtsorts[0].getDatatype().hasNestedRecursion()
+    assert dtsorts[1].getDatatype().hasNestedRecursion()
+
+    # Create mutual datatypes corresponding to this definition block:
+    #   DATATYPE
+    #     list4 = cons(car: set(ns4), cdr: list4) | nil,
+    #     ns4 = elem(ndata: list4)
+    #   END
+    unresTypes.clear()
+    unresNs4 = solver.mkUninterpretedSort("ns4")
+    unresTypes.add(unresNs4)
+    unresList4 = solver.mkUninterpretedSort("list4")
+    unresTypes.add(unresList4)
+
+    list4 = solver.mkDatatypeDecl("list4")
+    cons4 = solver.mkDatatypeConstructorDecl("cons4")
+    cons4.addSelector("car", solver.mkSetSort(unresNs4))
+    cons4.addSelector("cdr", unresList4)
+    list4.addConstructor(cons4)
+    nil4 = solver.mkDatatypeConstructorDecl("nil4")
+    list4.addConstructor(nil4)
+
+    ns4 = solver.mkDatatypeDecl("ns4")
+    elem4 = solver.mkDatatypeConstructorDecl("elem3")
+    elem4.addSelector("ndata", unresList4)
+    ns4.addConstructor(elem4)
+
+    dtdecls.clear()
+    dtdecls.append(list4)
+    dtdecls.append(ns4)
+
+    # both are well-founded and have nested recursion
+    dtsorts = solver.mkDatatypeSorts(dtdecls, unresTypes)
+    assert len(dtsorts) == 2
+    assert dtsorts[0].getDatatype().isWellFounded()
+    assert dtsorts[1].getDatatype().isWellFounded()
+    assert dtsorts[0].getDatatype().hasNestedRecursion()
+    assert dtsorts[1].getDatatype().hasNestedRecursion()
+
+    # Create mutual datatypes corresponding to this definition block:
+    #   DATATYPE
+    #     list5[X] = cons(car: X, cdr: list5[list5[X]]) | nil
+    #   END
+    unresTypes.clear()
+    unresList5 = solver.mkSortConstructorSort("list5", 1)
+    unresTypes.add(unresList5)
+
+    v = []
+    x = solver.mkParamSort("X")
+    v.append(x)
+    list5 = solver.mkDatatypeDecl("list5", v)
+
+    args = [x]
+    urListX = unresList5.instantiate(args)
+    args[0] = urListX
+    urListListX = unresList5.instantiate(args)
+
+    cons5 = solver.mkDatatypeConstructorDecl("cons5")
+    cons5.addSelector("car", x)
+    cons5.addSelector("cdr", urListListX)
+    list5.addConstructor(cons5)
+    nil5 = solver.mkDatatypeConstructorDecl("nil5")
+    list5.addConstructor(nil5)
+
+    dtdecls.clear()
+    dtdecls.append(list5)
+
+    # well-founded and has nested recursion
+    dtsorts = solver.mkDatatypeSorts(dtdecls, unresTypes)
+    assert len(dtsorts) == 1
+    assert dtsorts[0].getDatatype().isWellFounded()
+    assert dtsorts[0].getDatatype().hasNestedRecursion()
+
+
+def test_datatype_specialized_cons(solver):
+    # Create mutual datatypes corresponding to this definition block:
+    #   DATATYPE
+    #     plist[X] = pcons(car: X, cdr: plist[X]) | pnil
+    #   END
+
+    # Make unresolved types as placeholders
+    unresTypes = set([])
+    unresList = solver.mkSortConstructorSort("plist", 1)
+    unresTypes.add(unresList)
+
+    v = []
+    x = solver.mkParamSort("X")
+    v.append(x)
+    plist = solver.mkDatatypeDecl("plist", v)
+
+    args = [x]
+    urListX = unresList.instantiate(args)
+
+    pcons = solver.mkDatatypeConstructorDecl("pcons")
+    pcons.addSelector("car", x)
+    pcons.addSelector("cdr", urListX)
+    plist.addConstructor(pcons)
+    nil5 = solver.mkDatatypeConstructorDecl("pnil")
+    plist.addConstructor(nil5)
+
+    dtdecls = [plist]
+
+    # make the datatype sorts
+    dtsorts = solver.mkDatatypeSorts(dtdecls, unresTypes)
+    assert len(dtsorts) == 1
+    d = dtsorts[0].getDatatype()
+    nilc = d[0]
+
+    isort = solver.getIntegerSort()
+    iargs = [isort]
+    listInt = dtsorts[0].instantiate(iargs)
+
+    testConsTerm = Term(solver)
+    # get the specialized constructor term for list[Int]
+    testConsTerm = nilc.getSpecializedConstructorTerm(listInt)
+    assert testConsTerm != nilc.getConstructorTerm()
+    # error to get the specialized constructor term for Int
+    with pytest.raises(RuntimeError):
+        nilc.getSpecializedConstructorTerm(isort)
diff --git a/test/unit/api/python/test_grammar.py b/test/unit/api/python/test_grammar.py
new file mode 100644 (file)
index 0000000..db567a6
--- /dev/null
@@ -0,0 +1,137 @@
+###############################################################################
+# Top contributors (to current version):
+#   Yoni Zohar, Makai Mann, Mudathir Mohamed
+#
+# This file is part of the cvc5 project.
+#
+# Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
+# in the top-level source directory and their institutional affiliations.
+# All rights reserved.  See the file COPYING in the top-level source
+# directory for licensing information.
+# #############################################################################
+#
+# Translated from test/unit/api/grammar_black.h
+##
+
+import pytest
+
+import pycvc5
+from pycvc5 import kinds, Term
+
+
+@pytest.fixture
+def solver():
+    return pycvc5.Solver()
+
+
+def test_add_rule(solver):
+    boolean = solver.getBooleanSort()
+    integer = solver.getIntegerSort()
+
+    null_term = Term(solver)
+    start = solver.mkVar(boolean)
+    nts = solver.mkVar(boolean)
+
+    # expecting no error
+    g = solver.mkSygusGrammar([], [start])
+
+    g.addRule(start, solver.mkBoolean(False))
+
+    # expecting errors
+    with pytest.raises(RuntimeError):
+        g.addRule(null_term, solver.mkBoolean(False))
+    with pytest.raises(RuntimeError):
+        g.addRule(start, null_term)
+    with pytest.raises(RuntimeError):
+        g.addRule(nts, solver.mkBoolean(False))
+    with pytest.raises(RuntimeError):
+        g.addRule(start, solver.mkInteger(0))
+    with pytest.raises(RuntimeError):
+        g.addRule(start, nts)
+
+    # expecting no errors
+    solver.synthFun("f", {}, boolean, g)
+
+    # expecting an error
+    with pytest.raises(RuntimeError):
+        g.addRule(start, solver.mkBoolean(False))
+
+
+def test_add_rules(solver):
+    boolean = solver.getBooleanSort()
+    integer = solver.getIntegerSort()
+
+    null_term = Term(solver)
+    start = solver.mkVar(boolean)
+    nts = solver.mkVar(boolean)
+
+    g = solver.mkSygusGrammar([], [start])
+
+    g.addRules(start, {solver.mkBoolean(False)})
+
+    #Expecting errors
+    with pytest.raises(RuntimeError):
+        g.addRules(null_term, [solver.mkBoolean(False)])
+    with pytest.raises(RuntimeError):
+        g.addRules(start, [null_term])
+    with pytest.raises(RuntimeError):
+        g.addRules(nts, [solver.mkBoolean(False)])
+    with pytest.raises(RuntimeError):
+        g.addRules(start, [solver.mkInteger(0)])
+    with pytest.raises(RuntimeError):
+        g.addRules(start, [nts])
+    #Expecting no errors
+    solver.synthFun("f", {}, boolean, g)
+
+    #Expecting an error
+    with pytest.raises(RuntimeError):
+        g.addRules(start, solver.mkBoolean(False))
+
+
+def test_add_any_constant(solver):
+    boolean = solver.getBooleanSort()
+
+    null_term = Term(solver)
+    start = solver.mkVar(boolean)
+    nts = solver.mkVar(boolean)
+
+    g = solver.mkSygusGrammar({}, {start})
+
+    g.addAnyConstant(start)
+    g.addAnyConstant(start)
+
+    with pytest.raises(RuntimeError):
+        g.addAnyConstant(null_term)
+    with pytest.raises(RuntimeError):
+        g.addAnyConstant(nts)
+
+    solver.synthFun("f", {}, boolean, g)
+
+    with pytest.raises(RuntimeError):
+        g.addAnyConstant(start)
+
+
+def test_add_any_variable(solver):
+    boolean = solver.getBooleanSort()
+
+    null_term = Term(solver)
+    x = solver.mkVar(boolean)
+    start = solver.mkVar(boolean)
+    nts = solver.mkVar(boolean)
+
+    g1 = solver.mkSygusGrammar({x}, {start})
+    g2 = solver.mkSygusGrammar({}, {start})
+
+    g1.addAnyVariable(start)
+    g1.addAnyVariable(start)
+    g2.addAnyVariable(start)
+
+    with pytest.raises(RuntimeError):
+        g1.addAnyVariable(null_term)
+    with pytest.raises(RuntimeError):
+        g1.addAnyVariable(nts)
+
+    solver.synthFun("f", {}, boolean, g1)
+
+    with pytest.raises(RuntimeError):
+        g1.addAnyVariable(start)
diff --git a/test/unit/api/python/test_op.py b/test/unit/api/python/test_op.py
new file mode 100644 (file)
index 0000000..5126a48
--- /dev/null
@@ -0,0 +1,181 @@
+###############################################################################
+# Top contributors (to current version):
+#   Yoni Zohar
+#
+# This file is part of the cvc5 project.
+#
+# Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
+# in the top-level source directory and their institutional affiliations.
+# All rights reserved.  See the file COPYING in the top-level source
+# directory for licensing information.
+# #############################################################################
+#
+# Unit tests for op API.
+#
+# Obtained by translating test/unit/api/op_black.cpp
+##
+
+import pytest
+import pycvc5
+from pycvc5 import kinds
+from pycvc5 import Sort
+from pycvc5 import Op
+
+
+@pytest.fixture
+def solver():
+    return pycvc5.Solver()
+
+
+def test_get_kind(solver):
+    x = solver.mkOp(kinds.BVExtract, 31, 1)
+    x.getKind()
+
+
+def test_is_null(solver):
+    x = Op(solver)
+    assert x.isNull()
+    x = solver.mkOp(kinds.BVExtract, 31, 1)
+    assert not x.isNull()
+
+
+def test_op_from_kind(solver):
+    solver.mkOp(kinds.Plus)
+    with pytest.raises(RuntimeError):
+        solver.mkOp(kinds.BVExtract)
+
+
+def test_get_num_indices(solver):
+    plus = solver.mkOp(kinds.Plus)
+    divisible = solver.mkOp(kinds.Divisible, 4)
+    bitvector_repeat = solver.mkOp(kinds.BVRepeat, 5)
+    bitvector_zero_extend = solver.mkOp(kinds.BVZeroExtend, 6)
+    bitvector_sign_extend = solver.mkOp(kinds.BVSignExtend, 7)
+    bitvector_rotate_left = solver.mkOp(kinds.BVRotateLeft, 8)
+    bitvector_rotate_right = solver.mkOp(kinds.BVRotateRight, 9)
+    int_to_bitvector = solver.mkOp(kinds.IntToBV, 10)
+    iand = solver.mkOp(kinds.Iand, 3)
+    floatingpoint_to_ubv = solver.mkOp(kinds.FPToUbv, 11)
+    floatingopint_to_sbv = solver.mkOp(kinds.FPToSbv, 13)
+    floatingpoint_to_fp_ieee_bitvector = solver.mkOp(kinds.FPToFpIeeeBV, 4, 25)
+    floatingpoint_to_fp_floatingpoint = solver.mkOp(kinds.FPToFpFP, 4, 25)
+    floatingpoint_to_fp_real = solver.mkOp(kinds.FPToFpReal, 4, 25)
+    floatingpoint_to_fp_signed_bitvector = solver.mkOp(kinds.FPToFpSignedBV, 4,
+                                                       25)
+    floatingpoint_to_fp_unsigned_bitvector = solver.mkOp(
+        kinds.FPToFpUnsignedBV, 4, 25)
+    floatingpoint_to_fp_generic = solver.mkOp(kinds.FPToFpGeneric, 4, 25)
+    regexp_loop = solver.mkOp(kinds.RegexpLoop, 2, 3)
+
+    assert 0 == plus.getNumIndices()
+    assert 1 == divisible.getNumIndices()
+    assert 1 == bitvector_repeat.getNumIndices()
+    assert 1 == bitvector_zero_extend.getNumIndices()
+    assert 1 == bitvector_sign_extend.getNumIndices()
+    assert 1 == bitvector_rotate_left.getNumIndices()
+    assert 1 == bitvector_rotate_right.getNumIndices()
+    assert 1 == int_to_bitvector.getNumIndices()
+    assert 1 == iand.getNumIndices()
+    assert 1 == floatingpoint_to_ubv.getNumIndices()
+    assert 1 == floatingopint_to_sbv.getNumIndices()
+    assert 2 == floatingpoint_to_fp_ieee_bitvector.getNumIndices()
+    assert 2 == floatingpoint_to_fp_floatingpoint.getNumIndices()
+    assert 2 == floatingpoint_to_fp_real.getNumIndices()
+    assert 2 == floatingpoint_to_fp_signed_bitvector.getNumIndices()
+    assert 2 == floatingpoint_to_fp_unsigned_bitvector.getNumIndices()
+    assert 2 == floatingpoint_to_fp_generic.getNumIndices()
+    assert 2 == regexp_loop.getNumIndices()
+
+def test_op_indices_list(solver):
+    with_list = solver.mkOp(kinds.TupleProject, [4, 25])
+    assert 2 == with_list.getNumIndices()
+
+def test_get_indices_string(solver):
+    x = Op(solver)
+    with pytest.raises(RuntimeError):
+        x.getIndices()
+
+    divisible_ot = solver.mkOp(kinds.Divisible, 4)
+    assert divisible_ot.isIndexed()
+    divisible_idx = divisible_ot.getIndices()
+    assert divisible_idx == "4"
+
+
+def test_get_indices_uint(solver):
+    bitvector_repeat_ot = solver.mkOp(kinds.BVRepeat, 5)
+    assert bitvector_repeat_ot.isIndexed()
+    bitvector_repeat_idx = bitvector_repeat_ot.getIndices()
+    assert bitvector_repeat_idx == 5
+
+    bitvector_zero_extend_ot = solver.mkOp(kinds.BVZeroExtend, 6)
+    bitvector_zero_extend_idx = bitvector_zero_extend_ot.getIndices()
+    assert bitvector_zero_extend_idx == 6
+
+    bitvector_sign_extend_ot = solver.mkOp(kinds.BVSignExtend, 7)
+    bitvector_sign_extend_idx = bitvector_sign_extend_ot.getIndices()
+    assert bitvector_sign_extend_idx == 7
+
+    bitvector_rotate_left_ot = solver.mkOp(kinds.BVRotateLeft, 8)
+    bitvector_rotate_left_idx = bitvector_rotate_left_ot.getIndices()
+    assert bitvector_rotate_left_idx == 8
+
+    bitvector_rotate_right_ot = solver.mkOp(kinds.BVRotateRight, 9)
+    bitvector_rotate_right_idx = bitvector_rotate_right_ot.getIndices()
+    assert bitvector_rotate_right_idx == 9
+
+    int_to_bitvector_ot = solver.mkOp(kinds.IntToBV, 10)
+    int_to_bitvector_idx = int_to_bitvector_ot.getIndices()
+    assert int_to_bitvector_idx == 10
+
+    floatingpoint_to_ubv_ot = solver.mkOp(kinds.FPToUbv, 11)
+    floatingpoint_to_ubv_idx = floatingpoint_to_ubv_ot.getIndices()
+    assert floatingpoint_to_ubv_idx == 11
+
+    floatingpoint_to_sbv_ot = solver.mkOp(kinds.FPToSbv, 13)
+    floatingpoint_to_sbv_idx = floatingpoint_to_sbv_ot.getIndices()
+    assert floatingpoint_to_sbv_idx == 13
+
+
+def test_get_indices_pair_uint(solver):
+    bitvector_extract_ot = solver.mkOp(kinds.BVExtract, 4, 0)
+    assert bitvector_extract_ot.isIndexed()
+    bitvector_extract_indices = bitvector_extract_ot.getIndices()
+    assert bitvector_extract_indices == (4, 0)
+
+    floatingpoint_to_fp_ieee_bitvector_ot = solver.mkOp(
+        kinds.FPToFpIeeeBV, 4, 25)
+    floatingpoint_to_fp_ieee_bitvector_indices = floatingpoint_to_fp_ieee_bitvector_ot.getIndices(
+    )
+    assert floatingpoint_to_fp_ieee_bitvector_indices == (4, 25)
+
+    floatingpoint_to_fp_floatingpoint_ot = solver.mkOp(kinds.FPToFpFP, 4, 25)
+    floatingpoint_to_fp_floatingpoint_indices = floatingpoint_to_fp_floatingpoint_ot.getIndices(
+    )
+    assert floatingpoint_to_fp_floatingpoint_indices == (4, 25)
+
+    floatingpoint_to_fp_real_ot = solver.mkOp(kinds.FPToFpReal, 4, 25)
+    floatingpoint_to_fp_real_indices = floatingpoint_to_fp_real_ot.getIndices()
+    assert floatingpoint_to_fp_real_indices == (4, 25)
+
+    floatingpoint_to_fp_signed_bitvector_ot = solver.mkOp(
+        kinds.FPToFpSignedBV, 4, 25)
+    floatingpoint_to_fp_signed_bitvector_indices = floatingpoint_to_fp_signed_bitvector_ot.getIndices(
+    )
+    assert floatingpoint_to_fp_signed_bitvector_indices == (4, 25)
+
+    floatingpoint_to_fp_unsigned_bitvector_ot = solver.mkOp(
+        kinds.FPToFpUnsignedBV, 4, 25)
+    floatingpoint_to_fp_unsigned_bitvector_indices = floatingpoint_to_fp_unsigned_bitvector_ot.getIndices(
+    )
+    assert floatingpoint_to_fp_unsigned_bitvector_indices == (4, 25)
+
+    floatingpoint_to_fp_generic_ot = solver.mkOp(kinds.FPToFpGeneric, 4, 25)
+    floatingpoint_to_fp_generic_indices = floatingpoint_to_fp_generic_ot.getIndices(
+    )
+    assert floatingpoint_to_fp_generic_indices == (4, 25)
+
+
+def test_op_scoping_to_string(solver):
+    bitvector_repeat_ot = solver.mkOp(kinds.BVRepeat, 5)
+    op_repr = str(bitvector_repeat_ot)
+    assert str(bitvector_repeat_ot) == op_repr
diff --git a/test/unit/api/python/test_result.py b/test/unit/api/python/test_result.py
new file mode 100644 (file)
index 0000000..bd97646
--- /dev/null
@@ -0,0 +1,115 @@
+###############################################################################
+# Top contributors (to current version):
+#   Yoni Zohar
+#
+# This file is part of the cvc5 project.
+#
+# Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
+# in the top-level source directory and their institutional affiliations.
+# All rights reserved.  See the file COPYING in the top-level source
+# directory for licensing information.
+# #############################################################################
+#
+# Unit tests for result API.
+#
+# Obtained by translating test/unit/api/result_black.cpp
+##
+
+import pytest
+import pycvc5
+from pycvc5 import kinds
+from pycvc5 import Result
+from pycvc5 import UnknownExplanation
+
+
+@pytest.fixture
+def solver():
+    return pycvc5.Solver()
+
+
+def test_is_null(solver):
+    res_null = Result(solver)
+    assert res_null.isNull()
+    assert not res_null.isSat()
+    assert not res_null.isUnsat()
+    assert not res_null.isSatUnknown()
+    assert not res_null.isEntailed()
+    assert not res_null.isNotEntailed()
+    assert not res_null.isEntailmentUnknown()
+    u_sort = solver.mkUninterpretedSort("u")
+    x = solver.mkVar(u_sort, "x")
+    solver.assertFormula(x.eqTerm(x))
+    res = solver.checkSat()
+    assert not res.isNull()
+
+
+def test_eq(solver):
+    u_sort = solver.mkUninterpretedSort("u")
+    x = solver.mkVar(u_sort, "x")
+    solver.assertFormula(x.eqTerm(x))
+    res2 = solver.checkSat()
+    res3 = solver.checkSat()
+    res = res2
+    assert res == res2
+    assert res3 == res2
+
+
+def test_is_sat(solver):
+    u_sort = solver.mkUninterpretedSort("u")
+    x = solver.mkVar(u_sort, "x")
+    solver.assertFormula(x.eqTerm(x))
+    res = solver.checkSat()
+    assert res.isSat()
+    assert not res.isSatUnknown()
+
+
+def test_is_unsat(solver):
+    u_sort = solver.mkUninterpretedSort("u")
+    x = solver.mkVar(u_sort, "x")
+    solver.assertFormula(x.eqTerm(x).notTerm())
+    res = solver.checkSat()
+    assert res.isUnsat()
+    assert not res.isSatUnknown()
+
+
+def test_is_sat_unknown(solver):
+    solver.setLogic("QF_NIA")
+    solver.setOption("incremental", "false")
+    solver.setOption("solve-int-as-bv", "32")
+    int_sort = solver.getIntegerSort()
+    x = solver.mkVar(int_sort, "x")
+    solver.assertFormula(x.eqTerm(x).notTerm())
+    res = solver.checkSat()
+    assert not res.isSat()
+    assert res.isSatUnknown()
+
+
+def test_is_entailed(solver):
+    solver.setOption("incremental", "true")
+    u_sort = solver.mkUninterpretedSort("u")
+    x = solver.mkConst(u_sort, "x")
+    y = solver.mkConst(u_sort, "y")
+    a = x.eqTerm(y).notTerm()
+    b = x.eqTerm(y)
+    solver.assertFormula(a)
+    entailed = solver.checkEntailed(a)
+    assert entailed.isEntailed()
+    assert not entailed.isEntailmentUnknown()
+    not_entailed = solver.checkEntailed(b)
+    assert not_entailed.isNotEntailed()
+    assert not not_entailed.isEntailmentUnknown()
+
+
+def test_is_entailment_unknown(solver):
+    solver.setLogic("QF_NIA")
+    solver.setOption("incremental", "false")
+    solver.setOption("solve-int-as-bv", "32")
+    int_sort = solver.getIntegerSort()
+    x = solver.mkVar(int_sort, "x")
+    solver.assertFormula(x.eqTerm(x).notTerm())
+    res = solver.checkEntailed(x.eqTerm(x))
+    assert not res.isEntailed()
+    assert res.isEntailmentUnknown()
+    print(type(pycvc5.RoundTowardZero))
+    print(type(pycvc5.UnknownReason))
+    assert res.getUnknownExplanation() == pycvc5.UnknownReason
diff --git a/test/unit/api/python/test_solver.py b/test/unit/api/python/test_solver.py
new file mode 100644 (file)
index 0000000..71ab174
--- /dev/null
@@ -0,0 +1,1884 @@
+###############################################################################
+# Top contributors (to current version):
+#   Yoni Zohar, Ying Sheng
+#
+# This file is part of the cvc5 project.
+#
+# Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
+# in the top-level source directory and their institutional affiliations.
+# All rights reserved.  See the file COPYING in the top-level source
+# directory for licensing information.
+# #############################################################################
+##
+
+import pytest
+import pycvc5
+import sys
+
+from pycvc5 import kinds
+
+
+@pytest.fixture
+def solver():
+    return pycvc5.Solver()
+
+
+def test_recoverable_exception(solver):
+    solver.setOption("produce-models", "true")
+    x = solver.mkConst(solver.getBooleanSort(), "x")
+    solver.assertFormula(x.eqTerm(x).notTerm())
+    with pytest.raises(RuntimeError):
+        c = solver.getValue(x)
+
+
+def test_supports_floating_point(solver):
+    solver.mkRoundingMode(pycvc5.RoundNearestTiesToEven)
+
+
+def test_get_boolean_sort(solver):
+    solver.getBooleanSort()
+
+
+def test_get_integer_sort(solver):
+    solver.getIntegerSort()
+
+
+def test_get_null_sort(solver):
+    solver.getNullSort()
+
+
+def test_get_real_sort(solver):
+    solver.getRealSort()
+
+
+def test_get_reg_exp_sort(solver):
+    solver.getRegExpSort()
+
+
+def test_get_string_sort(solver):
+    solver.getStringSort()
+
+
+def test_get_rounding_mode_sort(solver):
+    solver.getRoundingModeSort()
+
+
+def test_mk_array_sort(solver):
+    boolSort = solver.getBooleanSort()
+    intSort = solver.getIntegerSort()
+    realSort = solver.getRealSort()
+    bvSort = solver.mkBitVectorSort(32)
+    solver.mkArraySort(boolSort, boolSort)
+    solver.mkArraySort(intSort, intSort)
+    solver.mkArraySort(realSort, realSort)
+    solver.mkArraySort(bvSort, bvSort)
+    solver.mkArraySort(boolSort, intSort)
+    solver.mkArraySort(realSort, bvSort)
+
+    fpSort = solver.mkFloatingPointSort(3, 5)
+    solver.mkArraySort(fpSort, fpSort)
+    solver.mkArraySort(bvSort, fpSort)
+
+    slv = pycvc5.Solver()
+    with pytest.raises(RuntimeError):
+        slv.mkArraySort(boolSort, boolSort)
+
+
+def test_mk_bit_vector_sort(solver):
+    solver.mkBitVectorSort(32)
+    with pytest.raises(RuntimeError):
+        solver.mkBitVectorSort(0)
+
+
+def test_mk_floating_point_sort(solver):
+    solver.mkFloatingPointSort(4, 8)
+    with pytest.raises(RuntimeError):
+        solver.mkFloatingPointSort(0, 8)
+    with pytest.raises(RuntimeError):
+        solver.mkFloatingPointSort(4, 0)
+
+
+def test_mk_datatype_sort(solver):
+    dtypeSpec = solver.mkDatatypeDecl("list")
+    cons = solver.mkDatatypeConstructorDecl("cons")
+    cons.addSelector("head", solver.getIntegerSort())
+    dtypeSpec.addConstructor(cons)
+    nil = solver.mkDatatypeConstructorDecl("nil")
+    dtypeSpec.addConstructor(nil)
+    solver.mkDatatypeSort(dtypeSpec)
+
+    slv = pycvc5.Solver()
+    with pytest.raises(RuntimeError):
+        slv.mkDatatypeSort(dtypeSpec)
+
+    throwsDtypeSpec = solver.mkDatatypeDecl("list")
+    with pytest.raises(RuntimeError):
+        solver.mkDatatypeSort(throwsDtypeSpec)
+
+
+def test_mk_datatype_sorts(solver):
+    slv = pycvc5.Solver()
+
+    dtypeSpec1 = solver.mkDatatypeDecl("list1")
+    cons1 = solver.mkDatatypeConstructorDecl("cons1")
+    cons1.addSelector("head1", solver.getIntegerSort())
+    dtypeSpec1.addConstructor(cons1)
+    nil1 = solver.mkDatatypeConstructorDecl("nil1")
+    dtypeSpec1.addConstructor(nil1)
+
+    dtypeSpec2 = solver.mkDatatypeDecl("list2")
+    cons2 = solver.mkDatatypeConstructorDecl("cons2")
+    cons2.addSelector("head2", solver.getIntegerSort())
+    dtypeSpec2.addConstructor(cons2)
+    nil2 = solver.mkDatatypeConstructorDecl("nil2")
+    dtypeSpec2.addConstructor(nil2)
+
+    decls = [dtypeSpec1, dtypeSpec2]
+    solver.mkDatatypeSorts(decls, set([]))
+
+    with pytest.raises(RuntimeError):
+        slv.mkDatatypeSorts(decls, set([]))
+
+    throwsDtypeSpec = solver.mkDatatypeDecl("list")
+    throwsDecls = [throwsDtypeSpec]
+    with pytest.raises(RuntimeError):
+        solver.mkDatatypeSorts(throwsDecls, set([]))
+
+    # with unresolved sorts
+    unresList = solver.mkUninterpretedSort("ulist")
+    unresSorts = set([unresList])
+    ulist = solver.mkDatatypeDecl("ulist")
+    ucons = solver.mkDatatypeConstructorDecl("ucons")
+    ucons.addSelector("car", unresList)
+    ucons.addSelector("cdr", unresList)
+    ulist.addConstructor(ucons)
+    unil = solver.mkDatatypeConstructorDecl("unil")
+    ulist.addConstructor(unil)
+    udecls = [ulist]
+
+    solver.mkDatatypeSorts(udecls, unresSorts)
+    with pytest.raises(RuntimeError):
+        slv.mkDatatypeSorts(udecls, unresSorts)
+
+
+def test_mk_function_sort(solver):
+    funSort = solver.mkFunctionSort(solver.mkUninterpretedSort("u"),\
+            solver.getIntegerSort())
+
+    # function arguments are allowed
+    solver.mkFunctionSort(funSort, solver.getIntegerSort())
+
+    # non-first-class arguments are not allowed
+    reSort = solver.getRegExpSort()
+    with pytest.raises(RuntimeError):
+        solver.mkFunctionSort(reSort, solver.getIntegerSort())
+    with pytest.raises(RuntimeError):
+        solver.mkFunctionSort(solver.getIntegerSort(), funSort)
+
+    solver.mkFunctionSort([solver.mkUninterpretedSort("u"),\
+            solver.getIntegerSort()],\
+            solver.getIntegerSort())
+    funSort2 = solver.mkFunctionSort(solver.mkUninterpretedSort("u"),\
+            solver.getIntegerSort())
+
+    # function arguments are allowed
+    solver.mkFunctionSort([funSort2, solver.mkUninterpretedSort("u")],\
+            solver.getIntegerSort())
+
+    with pytest.raises(RuntimeError):
+        solver.mkFunctionSort([solver.getIntegerSort(),\
+                solver.mkUninterpretedSort("u")],\
+                funSort2)
+
+    slv = pycvc5.Solver()
+    with pytest.raises(RuntimeError):
+        slv.mkFunctionSort(solver.mkUninterpretedSort("u"),\
+                solver.getIntegerSort())
+    with pytest.raises(RuntimeError):
+        slv.mkFunctionSort(slv.mkUninterpretedSort("u"),\
+                solver.getIntegerSort())
+    sorts1 = [solver.getBooleanSort(),\
+            slv.getIntegerSort(),\
+            solver.getIntegerSort()]
+    sorts2 = [slv.getBooleanSort(), slv.getIntegerSort()]
+    slv.mkFunctionSort(sorts2, slv.getIntegerSort())
+    with pytest.raises(RuntimeError):
+        slv.mkFunctionSort(sorts1, slv.getIntegerSort())
+    with pytest.raises(RuntimeError):
+        slv.mkFunctionSort(sorts2, solver.getIntegerSort())
+
+
+def test_mk_param_sort(solver):
+    solver.mkParamSort("T")
+    solver.mkParamSort("")
+
+
+def test_mk_predicate_sort(solver):
+    solver.mkPredicateSort([solver.getIntegerSort()])
+    with pytest.raises(RuntimeError):
+        solver.mkPredicateSort([])
+
+    funSort = solver.mkFunctionSort(solver.mkUninterpretedSort("u"),\
+            solver.getIntegerSort())
+    # functions as arguments are allowed
+    solver.mkPredicateSort([solver.getIntegerSort(), funSort])
+
+    slv = pycvc5.Solver()
+    with pytest.raises(RuntimeError):
+        slv.mkPredicateSort([solver.getIntegerSort()])
+
+
+def test_mk_record_sort(solver):
+    fields = [("b", solver.getBooleanSort()),\
+              ("bv", solver.mkBitVectorSort(8)),\
+              ("i", solver.getIntegerSort())]
+    empty = []
+    solver.mkRecordSort(fields)
+    solver.mkRecordSort(empty)
+    recSort = solver.mkRecordSort(fields)
+    recSort.getDatatype()
+
+
+def test_mk_set_sort(solver):
+    solver.mkSetSort(solver.getBooleanSort())
+    solver.mkSetSort(solver.getIntegerSort())
+    solver.mkSetSort(solver.mkBitVectorSort(4))
+    slv = pycvc5.Solver()
+    with pytest.raises(RuntimeError):
+        slv.mkSetSort(solver.mkBitVectorSort(4))
+
+
+def test_mk_bag_sort(solver):
+    solver.mkBagSort(solver.getBooleanSort())
+    solver.mkBagSort(solver.getIntegerSort())
+    solver.mkBagSort(solver.mkBitVectorSort(4))
+    slv = pycvc5.Solver()
+    with pytest.raises(RuntimeError):
+        slv.mkBagSort(solver.mkBitVectorSort(4))
+
+
+def test_mk_sequence_sort(solver):
+    solver.mkSequenceSort(solver.getBooleanSort())
+    solver.mkSequenceSort(\
+            solver.mkSequenceSort(solver.getIntegerSort()))
+    slv = pycvc5.Solver()
+    with pytest.raises(RuntimeError):
+        slv.mkSequenceSort(solver.getIntegerSort())
+
+
+def test_mk_uninterpreted_sort(solver):
+    solver.mkUninterpretedSort("u")
+    solver.mkUninterpretedSort("")
+
+
+def test_mk_sortConstructor_sort(solver):
+    solver.mkSortConstructorSort("s", 2)
+    solver.mkSortConstructorSort("", 2)
+    with pytest.raises(RuntimeError):
+        solver.mkSortConstructorSort("", 0)
+
+
+def test_mk_tuple_sort(solver):
+    solver.mkTupleSort([solver.getIntegerSort()])
+    funSort = solver.mkFunctionSort(solver.mkUninterpretedSort("u"),\
+                                    solver.getIntegerSort())
+    with pytest.raises(RuntimeError):
+        solver.mkTupleSort([solver.getIntegerSort(), funSort])
+
+    slv = pycvc5.Solver()
+    with pytest.raises(RuntimeError):
+        slv.mkTupleSort([solver.getIntegerSort()])
+
+
+def test_mk_bit_vector(solver):
+    solver.mkBitVector(8, 2)
+    solver.mkBitVector(32, 2)
+
+    solver.mkBitVector(4, "1010", 2)
+    solver.mkBitVector(8, "0101", 2)
+    solver.mkBitVector(8, "-1111111", 2)
+    solver.mkBitVector(8, "00000101", 2)
+    solver.mkBitVector(8, "-127", 10)
+    solver.mkBitVector(8, "255", 10)
+    solver.mkBitVector(10, "1010", 10)
+    solver.mkBitVector(11, "1234", 10)
+    solver.mkBitVector(8, "-7f", 16)
+    solver.mkBitVector(8, "a0", 16)
+    solver.mkBitVector(16, "1010", 16)
+    solver.mkBitVector(16, "a09f", 16)
+
+    with pytest.raises(RuntimeError):
+        solver.mkBitVector(0, 2)
+    with pytest.raises(RuntimeError):
+        solver.mkBitVector(0, "-127", 10)
+    with pytest.raises(RuntimeError):
+        solver.mkBitVector(0, "a0", 16)
+
+    with pytest.raises(RuntimeError):
+        solver.mkBitVector(2, "", 2)
+
+    with pytest.raises(RuntimeError):
+        solver.mkBitVector(8, "101", 5)
+    with pytest.raises(RuntimeError):
+        solver.mkBitVector(8, "127", 11)
+    with pytest.raises(RuntimeError):
+        solver.mkBitVector(8, "a0", 21)
+
+    with pytest.raises(RuntimeError):
+        solver.mkBitVector(8, "101010101", 2)
+    with pytest.raises(RuntimeError):
+        solver.mkBitVector(8, "-11111111", 2)
+    with pytest.raises(RuntimeError):
+        solver.mkBitVector(8, "-256", 10)
+    with pytest.raises(RuntimeError):
+        solver.mkBitVector(8, "257", 10)
+    with pytest.raises(RuntimeError):
+        solver.mkBitVector(8, "-a0", 16)
+    with pytest.raises(RuntimeError):
+        solver.mkBitVector(8, "fffff", 16)
+
+    with pytest.raises(RuntimeError):
+        solver.mkBitVector(8, "10201010", 2)
+    with pytest.raises(RuntimeError):
+        solver.mkBitVector(8, "-25x", 10)
+    with pytest.raises(RuntimeError):
+        solver.mkBitVector(8, "2x7", 10)
+    with pytest.raises(RuntimeError):
+        solver.mkBitVector(8, "fzff", 16)
+
+    assert solver.mkBitVector(8, "0101", 2) == solver.mkBitVector(8, "00000101", 2)
+    assert solver.mkBitVector(4, "1010", 2) == solver.mkBitVector(4, "10", 10)
+    assert solver.mkBitVector(4, "1010", 2) == solver.mkBitVector(4, "a", 16)
+    assert str(solver.mkBitVector(8, "01010101", 2)) == "#b01010101"
+    assert str(solver.mkBitVector(8, "F", 16)) == "#b00001111"
+    assert solver.mkBitVector(8, "-1", 10) ==\
+            solver.mkBitVector(8, "FF", 16)
+
+
+def test_mk_var(solver):
+    boolSort = solver.getBooleanSort()
+    intSort = solver.getIntegerSort()
+    funSort = solver.mkFunctionSort(intSort, boolSort)
+    solver.mkVar(boolSort)
+    solver.mkVar(funSort)
+    solver.mkVar(boolSort, "b")
+    solver.mkVar(funSort, "")
+    with pytest.raises(RuntimeError):
+        solver.mkVar(pycvc5.Sort(solver))
+    with pytest.raises(RuntimeError):
+        solver.mkVar(pycvc5.Sort(solver), "a")
+    slv = pycvc5.Solver()
+    with pytest.raises(RuntimeError):
+        slv.mkVar(boolSort, "x")
+
+
+def test_mk_boolean(solver):
+    solver.mkBoolean(True)
+    solver.mkBoolean(False)
+
+
+def test_mk_rounding_mode(solver):
+    solver.mkRoundingMode(pycvc5.RoundTowardZero)
+
+
+def test_mk_abstract_value(solver):
+    solver.mkAbstractValue("1")
+    with pytest.raises(ValueError):
+        solver.mkAbstractValue("0")
+    with pytest.raises(ValueError):
+        solver.mkAbstractValue("-1")
+    with pytest.raises(ValueError):
+        solver.mkAbstractValue("1.2")
+    with pytest.raises(ValueError):
+        solver.mkAbstractValue("1/2")
+    with pytest.raises(ValueError):
+        solver.mkAbstractValue("asdf")
+
+    solver.mkAbstractValue(1)
+    with pytest.raises(ValueError):
+        solver.mkAbstractValue(-1)
+    with pytest.raises(ValueError):
+        solver.mkAbstractValue(0)
+
+
+def test_mk_floating_point(solver):
+    t1 = solver.mkBitVector(8)
+    t2 = solver.mkBitVector(4)
+    t3 = solver.mkInteger(2)
+    solver.mkFloatingPoint(3, 5, t1)
+
+    with pytest.raises(RuntimeError):
+        solver.mkFloatingPoint(0, 5, pycvc5.Term(solver))
+    with pytest.raises(RuntimeError):
+        solver.mkFloatingPoint(0, 5, t1)
+    with pytest.raises(RuntimeError):
+        solver.mkFloatingPoint(3, 0, t1)
+    with pytest.raises(RuntimeError):
+        solver.mkFloatingPoint(3, 5, t2)
+    with pytest.raises(RuntimeError):
+        solver.mkFloatingPoint(3, 5, t2)
+
+    slv = pycvc5.Solver()
+    with pytest.raises(RuntimeError):
+        slv.mkFloatingPoint(3, 5, t1)
+
+def test_mk_cardinality_constraint(solver):
+    su = solver.mkUninterpretedSort("u")
+    si = solver.getIntegerSort()
+    solver.mkCardinalityConstraint(su, 3)
+    with pytest.raises(RuntimeError):
+        solver.mkEmptySet(solver.mkCardinalityConstraint(si, 3))
+    with pytest.raises(RuntimeError):
+        solver.mkEmptySet(solver.mkCardinalityConstraint(su, 0))
+    slv = pycvc5.Solver()
+    with pytest.raises(RuntimeError):
+        slv.mkCardinalityConstraint(su, 3)
+
+def test_mk_empty_set(solver):
+    slv = pycvc5.Solver()
+    s = solver.mkSetSort(solver.getBooleanSort())
+    solver.mkEmptySet(pycvc5.Sort(solver))
+    solver.mkEmptySet(s)
+    with pytest.raises(RuntimeError):
+        solver.mkEmptySet(solver.getBooleanSort())
+    with pytest.raises(RuntimeError):
+        slv.mkEmptySet(s)
+
+
+def test_mk_empty_bag(solver):
+    slv = pycvc5.Solver()
+    s = solver.mkBagSort(solver.getBooleanSort())
+    solver.mkEmptyBag(pycvc5.Sort(solver))
+    solver.mkEmptyBag(s)
+    with pytest.raises(RuntimeError):
+        solver.mkEmptyBag(solver.getBooleanSort())
+    with pytest.raises(RuntimeError):
+        slv.mkEmptyBag(s)
+
+
+def test_mk_empty_sequence(solver):
+    slv = pycvc5.Solver()
+    s = solver.mkSequenceSort(solver.getBooleanSort())
+    solver.mkEmptySequence(s)
+    solver.mkEmptySequence(solver.getBooleanSort())
+    with pytest.raises(RuntimeError):
+        slv.mkEmptySequence(s)
+
+
+def test_mk_false(solver):
+    solver.mkFalse()
+    solver.mkFalse()
+
+
+def test_mk_nan(solver):
+    solver.mkNaN(3, 5)
+
+
+def test_mk_neg_zero(solver):
+    solver.mkNegZero(3, 5)
+
+
+def test_mk_neg_inf(solver):
+    solver.mkNegInf(3, 5)
+
+
+def test_mk_pos_inf(solver):
+    solver.mkPosInf(3, 5)
+
+
+def test_mk_pos_zero(solver):
+    solver.mkPosZero(3, 5)
+
+
+def test_mk_op(solver):
+    # mkOp(Kind kind, Kind k)
+    with pytest.raises(ValueError):
+        solver.mkOp(kinds.BVExtract, kinds.Equal)
+
+    # mkOp(Kind kind, const std::string& arg)
+    solver.mkOp(kinds.Divisible, "2147483648")
+    with pytest.raises(RuntimeError):
+        solver.mkOp(kinds.BVExtract, "asdf")
+
+    # mkOp(Kind kind, uint32_t arg)
+    solver.mkOp(kinds.Divisible, 1)
+    solver.mkOp(kinds.BVRotateLeft, 1)
+    solver.mkOp(kinds.BVRotateRight, 1)
+    with pytest.raises(RuntimeError):
+        solver.mkOp(kinds.BVExtract, 1)
+
+    # mkOp(Kind kind, uint32_t arg1, uint32_t arg2)
+    solver.mkOp(kinds.BVExtract, 1, 1)
+    with pytest.raises(RuntimeError):
+        solver.mkOp(kinds.Divisible, 1, 2)
+
+    # mkOp(Kind kind, std::vector<uint32_t> args)
+    args = [1, 2, 2]
+    solver.mkOp(kinds.TupleProject, args)
+
+
+def test_mk_pi(solver):
+    solver.mkPi()
+
+
+def test_mk_integer(solver):
+    solver.mkInteger("123")
+    with pytest.raises(RuntimeError):
+        solver.mkInteger("1.23")
+    with pytest.raises(RuntimeError):
+        solver.mkInteger("1/23")
+    with pytest.raises(RuntimeError):
+        solver.mkInteger("12/3")
+    with pytest.raises(RuntimeError):
+        solver.mkInteger(".2")
+    with pytest.raises(RuntimeError):
+        solver.mkInteger("2.")
+    with pytest.raises(RuntimeError):
+        solver.mkInteger("")
+    with pytest.raises(RuntimeError):
+        solver.mkInteger("asdf")
+    with pytest.raises(RuntimeError):
+        solver.mkInteger("1.2/3")
+    with pytest.raises(RuntimeError):
+        solver.mkInteger(".")
+    with pytest.raises(RuntimeError):
+        solver.mkInteger("/")
+    with pytest.raises(RuntimeError):
+        solver.mkInteger("2/")
+    with pytest.raises(RuntimeError):
+        solver.mkInteger("/2")
+
+    solver.mkReal("123")
+    with pytest.raises(RuntimeError):
+        solver.mkInteger("1.23")
+    with pytest.raises(RuntimeError):
+        solver.mkInteger("1/23")
+    with pytest.raises(RuntimeError):
+        solver.mkInteger("12/3")
+    with pytest.raises(RuntimeError):
+        solver.mkInteger(".2")
+    with pytest.raises(RuntimeError):
+        solver.mkInteger("2.")
+    with pytest.raises(RuntimeError):
+        solver.mkInteger("")
+    with pytest.raises(RuntimeError):
+        solver.mkInteger("asdf")
+    with pytest.raises(RuntimeError):
+        solver.mkInteger("1.2/3")
+    with pytest.raises(RuntimeError):
+        solver.mkInteger(".")
+    with pytest.raises(RuntimeError):
+        solver.mkInteger("/")
+    with pytest.raises(RuntimeError):
+        solver.mkInteger("2/")
+    with pytest.raises(RuntimeError):
+        solver.mkInteger("/2")
+
+    val1 = 1
+    val2 = -1
+    val3 = 1
+    val4 = -1
+    solver.mkInteger(val1)
+    solver.mkInteger(val2)
+    solver.mkInteger(val3)
+    solver.mkInteger(val4)
+    solver.mkInteger(val4)
+
+
+def test_mk_real(solver):
+    solver.mkReal("123")
+    solver.mkReal("1.23")
+    solver.mkReal("1/23")
+    solver.mkReal("12/3")
+    solver.mkReal(".2")
+    solver.mkReal("2.")
+    with pytest.raises(RuntimeError):
+        solver.mkReal("")
+    with pytest.raises(RuntimeError):
+        solver.mkReal("asdf")
+    with pytest.raises(RuntimeError):
+        solver.mkReal("1.2/3")
+    with pytest.raises(RuntimeError):
+        solver.mkReal(".")
+    with pytest.raises(RuntimeError):
+        solver.mkReal("/")
+    with pytest.raises(RuntimeError):
+        solver.mkReal("2/")
+    with pytest.raises(RuntimeError):
+        solver.mkReal("/2")
+
+    solver.mkReal("123")
+    solver.mkReal("1.23")
+    solver.mkReal("1/23")
+    solver.mkReal("12/3")
+    solver.mkReal(".2")
+    solver.mkReal("2.")
+    with pytest.raises(RuntimeError):
+        solver.mkReal("")
+    with pytest.raises(RuntimeError):
+        solver.mkReal("asdf")
+    with pytest.raises(RuntimeError):
+        solver.mkReal("1.2/3")
+    with pytest.raises(RuntimeError):
+        solver.mkReal(".")
+    with pytest.raises(RuntimeError):
+        solver.mkReal("/")
+    with pytest.raises(RuntimeError):
+        solver.mkReal("2/")
+    with pytest.raises(RuntimeError):
+        solver.mkReal("/2")
+
+    val1 = 1
+    val2 = -1
+    val3 = 1
+    val4 = -1
+    solver.mkReal(val1)
+    solver.mkReal(val2)
+    solver.mkReal(val3)
+    solver.mkReal(val4)
+    solver.mkReal(val4)
+    solver.mkReal(val1, val1)
+    solver.mkReal(val2, val2)
+    solver.mkReal(val3, val3)
+    solver.mkReal(val4, val4)
+
+
+def test_mk_regexp_empty(solver):
+    strSort = solver.getStringSort()
+    s = solver.mkConst(strSort, "s")
+    solver.mkTerm(kinds.StringInRegexp, s, solver.mkRegexpNone())
+
+
+def test_mk_regexp_sigma(solver):
+    strSort = solver.getStringSort()
+    s = solver.mkConst(strSort, "s")
+    solver.mkTerm(kinds.StringInRegexp, s, solver.mkRegexpAllchar())
+
+
+def test_mk_sep_emp(solver):
+    solver.mkSepEmp();
+
+
+def test_mk_sep_nil(solver):
+    solver.mkSepNil(solver.getBooleanSort())
+    with pytest.raises(RuntimeError):
+        solver.mkSepNil(pycvc5.Sort(solver))
+    slv = pycvc5.Solver()
+    with pytest.raises(RuntimeError):
+        slv.mkSepNil(solver.getIntegerSort())
+
+
+def test_mk_string(solver):
+    solver.mkString("")
+    solver.mkString("asdfasdf")
+    str(solver.mkString("asdf\\nasdf")) == "\"asdf\\u{5c}nasdf\""
+    str(solver.mkString("asdf\\u{005c}nasdf", True)) ==\
+            "\"asdf\\u{5c}nasdf\""
+
+
+def test_mk_term(solver):
+    bv32 = solver.mkBitVectorSort(32)
+    a = solver.mkConst(bv32, "a")
+    b = solver.mkConst(bv32, "b")
+    v1 = [a, b]
+    v2 = [a, pycvc5.Term(solver)]
+    v3 = [a, solver.mkTrue()]
+    v4 = [solver.mkInteger(1), solver.mkInteger(2)]
+    v5 = [solver.mkInteger(1), pycvc5.Term(solver)]
+    v6 = []
+    slv = pycvc5.Solver()
+
+    # mkTerm(Kind kind) const
+    solver.mkPi()
+    solver.mkTerm(kinds.RegexpNone)
+    solver.mkTerm(kinds.RegexpAllchar)
+    with pytest.raises(RuntimeError):
+        solver.mkTerm(kinds.ConstBV)
+
+    # mkTerm(Kind kind, Term child) const
+    solver.mkTerm(kinds.Not, solver.mkTrue())
+    with pytest.raises(RuntimeError):
+        solver.mkTerm(kinds.Not, pycvc5.Term(solver))
+    with pytest.raises(RuntimeError):
+        solver.mkTerm(kinds.Not, a)
+    with pytest.raises(RuntimeError):
+        slv.mkTerm(kinds.Not, solver.mkTrue())
+
+    # mkTerm(Kind kind, Term child1, Term child2) const
+    solver.mkTerm(kinds.Equal, a, b)
+    with pytest.raises(RuntimeError):
+        solver.mkTerm(kinds.Equal, pycvc5.Term(solver), b)
+    with pytest.raises(RuntimeError):
+        solver.mkTerm(kinds.Equal, a, pycvc5.Term(solver))
+    with pytest.raises(RuntimeError):
+        solver.mkTerm(kinds.Equal, a, solver.mkTrue())
+    with pytest.raises(RuntimeError):
+        slv.mkTerm(kinds.Equal, a, b)
+
+    # mkTerm(Kind kind, Term child1, Term child2, Term child3) const
+    solver.mkTerm(kinds.Ite, solver.mkTrue(), solver.mkTrue(), solver.mkTrue())
+    with pytest.raises(RuntimeError):
+        solver.mkTerm(kinds.Ite, pycvc5.Term(solver), solver.mkTrue(),
+                      solver.mkTrue())
+    with pytest.raises(RuntimeError):
+        solver.mkTerm(kinds.Ite, solver.mkTrue(), pycvc5.Term(solver),
+                      solver.mkTrue())
+    with pytest.raises(RuntimeError):
+        solver.mkTerm(kinds.Ite, solver.mkTrue(), solver.mkTrue(),
+                      pycvc5.Term(solver))
+    with pytest.raises(RuntimeError):
+        solver.mkTerm(kinds.Ite, solver.mkTrue(), solver.mkTrue(), b)
+    with pytest.raises(RuntimeError):
+        slv.mkTerm(kinds.Ite, solver.mkTrue(), solver.mkTrue(),
+                   solver.mkTrue())
+
+    # mkTerm(Kind kind, const std::vector<Term>& children) const
+    solver.mkTerm(kinds.Equal, v1)
+    with pytest.raises(RuntimeError):
+        solver.mkTerm(kinds.Equal, v2)
+    with pytest.raises(RuntimeError):
+        solver.mkTerm(kinds.Equal, v3)
+    with pytest.raises(RuntimeError):
+        solver.mkTerm(kinds.Distinct, v6)
+
+
+def test_mk_term_from_op(solver):
+    bv32 = solver.mkBitVectorSort(32)
+    a = solver.mkConst(bv32, "a")
+    b = solver.mkConst(bv32, "b")
+    v1 = [solver.mkInteger(1), solver.mkInteger(2)]
+    v2 = [solver.mkInteger(1), pycvc5.Term(solver)]
+    v3 = []
+    v4 = [solver.mkInteger(5)]
+    slv = pycvc5.Solver()
+
+    # simple operator terms
+    opterm1 = solver.mkOp(kinds.BVExtract, 2, 1)
+    opterm2 = solver.mkOp(kinds.Divisible, 1)
+
+    # list datatype
+    sort = solver.mkParamSort("T")
+    listDecl = solver.mkDatatypeDecl("paramlist", sort)
+    cons = solver.mkDatatypeConstructorDecl("cons")
+    nil = solver.mkDatatypeConstructorDecl("nil")
+    cons.addSelector("head", sort)
+    cons.addSelectorSelf("tail")
+    listDecl.addConstructor(cons)
+    listDecl.addConstructor(nil)
+    listSort = solver.mkDatatypeSort(listDecl)
+    intListSort =\
+        listSort.instantiate([solver.getIntegerSort()])
+    c = solver.mkConst(intListSort, "c")
+    lis = listSort.getDatatype()
+
+    # list datatype constructor and selector operator terms
+    consTerm1 = lis.getConstructorTerm("cons")
+    consTerm2 = lis.getConstructor("cons").getConstructorTerm()
+    nilTerm1 = lis.getConstructorTerm("nil")
+    nilTerm2 = lis.getConstructor("nil").getConstructorTerm()
+    headTerm1 = lis["cons"].getSelectorTerm("head")
+    headTerm2 = lis["cons"].getSelector("head").getSelectorTerm()
+    tailTerm1 = lis["cons"].getSelectorTerm("tail")
+    tailTerm2 = lis["cons"]["tail"].getSelectorTerm()
+
+    # mkTerm(Op op, Term term) const
+    solver.mkTerm(kinds.ApplyConstructor, nilTerm1)
+    solver.mkTerm(kinds.ApplyConstructor, nilTerm2)
+    with pytest.raises(RuntimeError):
+        solver.mkTerm(kinds.ApplySelector, nilTerm1)
+    with pytest.raises(RuntimeError):
+        solver.mkTerm(kinds.ApplySelector, consTerm1)
+    with pytest.raises(RuntimeError):
+        solver.mkTerm(kinds.ApplyConstructor, consTerm2)
+    with pytest.raises(RuntimeError):
+        solver.mkTerm(opterm1)
+    with pytest.raises(RuntimeError):
+        solver.mkTerm(kinds.ApplySelector, headTerm1)
+    with pytest.raises(RuntimeError):
+        solver.mkTerm(opterm1)
+    with pytest.raises(RuntimeError):
+        slv.mkTerm(kinds.ApplyConstructor, nilTerm1)
+
+    # mkTerm(Op op, Term child) const
+    solver.mkTerm(opterm1, a)
+    solver.mkTerm(opterm2, solver.mkInteger(1))
+    solver.mkTerm(kinds.ApplySelector, headTerm1, c)
+    solver.mkTerm(kinds.ApplySelector, tailTerm2, c)
+    with pytest.raises(RuntimeError):
+        solver.mkTerm(opterm2, a)
+    with pytest.raises(RuntimeError):
+        solver.mkTerm(opterm1, pycvc5.Term(solver))
+    with pytest.raises(RuntimeError):
+        solver.mkTerm(kinds.ApplyConstructor, consTerm1, solver.mkInteger(0))
+    with pytest.raises(RuntimeError):
+        slv.mkTerm(opterm1, a)
+
+    # mkTerm(Op op, Term child1, Term child2) const
+    solver.mkTerm(kinds.ApplyConstructor, consTerm1, solver.mkInteger(0),
+                  solver.mkTerm(kinds.ApplyConstructor, nilTerm1))
+    with pytest.raises(RuntimeError):
+        solver.mkTerm(opterm2, solver.mkInteger(1), solver.mkInteger(2))
+    with pytest.raises(RuntimeError):
+        solver.mkTerm(opterm1, a, b)
+    with pytest.raises(RuntimeError):
+        solver.mkTerm(opterm2, solver.mkInteger(1), pycvc5.Term(solver))
+    with pytest.raises(RuntimeError):
+        solver.mkTerm(opterm2, pycvc5.Term(solver), solver.mkInteger(1))
+    with pytest.raises(RuntimeError):
+        slv.mkTerm(kinds.ApplyConstructor,\
+                        consTerm1,\
+                        solver.mkInteger(0),\
+                        solver.mkTerm(kinds.ApplyConstructor, nilTerm1))
+
+    # mkTerm(Op op, Term child1, Term child2, Term child3) const
+    with pytest.raises(RuntimeError):
+        solver.mkTerm(opterm1, a, b, a)
+    with pytest.raises(RuntimeError):
+        solver.mkTerm(opterm2, solver.mkInteger(1), solver.mkInteger(1),
+                      pycvc5.Term(solver))
+
+    # mkTerm(Op op, const std::vector<Term>& children) const
+    solver.mkTerm(opterm2, v4)
+    with pytest.raises(RuntimeError):
+        solver.mkTerm(opterm2, v1)
+    with pytest.raises(RuntimeError):
+        solver.mkTerm(opterm2, v2)
+    with pytest.raises(RuntimeError):
+        solver.mkTerm(opterm2, v3)
+    with pytest.raises(RuntimeError):
+        slv.mkTerm(opterm2, v4)
+
+
+def test_mk_true(solver):
+    solver.mkTrue()
+    solver.mkTrue()
+
+
+def test_mk_tuple(solver):
+    solver.mkTuple([solver.mkBitVectorSort(3)], [solver.mkBitVector(3, "101", 2)])
+    solver.mkTuple([solver.getRealSort()], [solver.mkInteger("5")])
+
+    with pytest.raises(RuntimeError):
+        solver.mkTuple([], [solver.mkBitVector(3, "101", 2)])
+    with pytest.raises(RuntimeError):
+        solver.mkTuple([solver.mkBitVectorSort(4)],
+                       [solver.mkBitVector(3, "101", 2)])
+    with pytest.raises(RuntimeError):
+        solver.mkTuple([solver.getIntegerSort()], [solver.mkReal("5.3")])
+    slv = pycvc5.Solver()
+    with pytest.raises(RuntimeError):
+        slv.mkTuple([solver.mkBitVectorSort(3)], [slv.mkBitVector(3, "101", 2)])
+    with pytest.raises(RuntimeError):
+        slv.mkTuple([slv.mkBitVectorSort(3)], [solver.mkBitVector(3, "101", 2)])
+
+
+def test_mk_universe_set(solver):
+    solver.mkUniverseSet(solver.getBooleanSort())
+    with pytest.raises(RuntimeError):
+        solver.mkUniverseSet(pycvc5.Sort(solver))
+    slv = pycvc5.Solver()
+    with pytest.raises(RuntimeError):
+        slv.mkUniverseSet(solver.getBooleanSort())
+
+
+def test_mk_const(solver):
+    boolSort = solver.getBooleanSort()
+    intSort = solver.getIntegerSort()
+    funSort = solver.mkFunctionSort(intSort, boolSort)
+    solver.mkConst(boolSort)
+    solver.mkConst(funSort)
+    solver.mkConst(boolSort, "b")
+    solver.mkConst(intSort, "i")
+    solver.mkConst(funSort, "f")
+    solver.mkConst(funSort, "")
+    with pytest.raises(RuntimeError):
+        solver.mkConst(pycvc5.Sort(solver))
+    with pytest.raises(RuntimeError):
+        solver.mkConst(pycvc5.Sort(solver), "a")
+
+    slv = pycvc5.Solver()
+    with pytest.raises(RuntimeError):
+        slv.mkConst(boolSort)
+
+
+def test_mk_const_array(solver):
+    intSort = solver.getIntegerSort()
+    arrSort = solver.mkArraySort(intSort, intSort)
+    zero = solver.mkInteger(0)
+    constArr = solver.mkConstArray(arrSort, zero)
+
+    solver.mkConstArray(arrSort, zero)
+    with pytest.raises(RuntimeError):
+        solver.mkConstArray(pycvc5.Sort(solver), zero)
+    with pytest.raises(RuntimeError):
+        solver.mkConstArray(arrSort, pycvc5.Term(solver))
+    with pytest.raises(RuntimeError):
+        solver.mkConstArray(arrSort, solver.mkBitVector(1, 1))
+    with pytest.raises(RuntimeError):
+        solver.mkConstArray(intSort, zero)
+    slv = pycvc5.Solver()
+    zero2 = slv.mkInteger(0)
+    arrSort2 = slv.mkArraySort(slv.getIntegerSort(), slv.getIntegerSort())
+    with pytest.raises(RuntimeError):
+        slv.mkConstArray(arrSort2, zero)
+    with pytest.raises(RuntimeError):
+        slv.mkConstArray(arrSort, zero2)
+
+
+def test_declare_fun(solver):
+    bvSort = solver.mkBitVectorSort(32)
+    funSort = solver.mkFunctionSort(solver.mkUninterpretedSort("u"),\
+                                    solver.getIntegerSort())
+    solver.declareFun("f1", [], bvSort)
+    solver.declareFun("f3", [bvSort, solver.getIntegerSort()], bvSort)
+    with pytest.raises(RuntimeError):
+        solver.declareFun("f2", [], funSort)
+    # functions as arguments is allowed
+    solver.declareFun("f4", [bvSort, funSort], bvSort)
+    with pytest.raises(RuntimeError):
+        solver.declareFun("f5", [bvSort, bvSort], funSort)
+    slv = pycvc5.Solver()
+    with pytest.raises(RuntimeError):
+        slv.declareFun("f1", [], bvSort)
+
+
+def test_declare_sort(solver):
+    solver.declareSort("s", 0)
+    solver.declareSort("s", 2)
+    solver.declareSort("", 2)
+
+
+def test_define_fun(solver):
+    bvSort = solver.mkBitVectorSort(32)
+    funSort = solver.mkFunctionSort(solver.mkUninterpretedSort("u"),
+                                    solver.getIntegerSort())
+    b1 = solver.mkVar(bvSort, "b1")
+    b2 = solver.mkVar(solver.getIntegerSort(), "b2")
+    b3 = solver.mkVar(funSort, "b3")
+    v1 = solver.mkConst(bvSort, "v1")
+    v2 = solver.mkConst(funSort, "v2")
+    solver.defineFun("f", [], bvSort, v1)
+    solver.defineFun("ff", [b1, b2], bvSort, v1)
+    with pytest.raises(RuntimeError):
+        solver.defineFun("ff", [v1, b2], bvSort, v1)
+    with pytest.raises(RuntimeError):
+        solver.defineFun("fff", [b1], bvSort, v2)
+    with pytest.raises(RuntimeError):
+        solver.defineFun("ffff", [b1], funSort, v2)
+    # b3 has function sort, which is allowed as an argument
+    solver.defineFun("fffff", [b1, b3], bvSort, v1)
+
+    slv = pycvc5.Solver()
+    bvSort2 = slv.mkBitVectorSort(32)
+    v12 = slv.mkConst(bvSort2, "v1")
+    b12 = slv.mkVar(bvSort2, "b1")
+    b22 = slv.mkVar(slv.getIntegerSort(), "b2")
+    with pytest.raises(RuntimeError):
+        slv.defineFun("f", [], bvSort, v12)
+    with pytest.raises(RuntimeError):
+        slv.defineFun("f", [], bvSort2, v1)
+    with pytest.raises(RuntimeError):
+        slv.defineFun("ff", [b1, b22], bvSort2, v12)
+    with pytest.raises(RuntimeError):
+        slv.defineFun("ff", [b12, b2], bvSort2, v12)
+    with pytest.raises(RuntimeError):
+        slv.defineFun("ff", [b12, b22], bvSort, v12)
+    with pytest.raises(RuntimeError):
+        slv.defineFun("ff", [b12, b22], bvSort2, v1)
+
+
+def test_define_fun_rec(solver):
+    bvSort = solver.mkBitVectorSort(32)
+    funSort1 = solver.mkFunctionSort([bvSort, bvSort], bvSort)
+    funSort2 = solver.mkFunctionSort(solver.mkUninterpretedSort("u"),\
+                                     solver.getIntegerSort())
+    b1 = solver.mkVar(bvSort, "b1")
+    b11 = solver.mkVar(bvSort, "b1")
+    b2 = solver.mkVar(solver.getIntegerSort(), "b2")
+    b3 = solver.mkVar(funSort2, "b3")
+    v1 = solver.mkConst(bvSort, "v1")
+    v2 = solver.mkConst(solver.getIntegerSort(), "v2")
+    v3 = solver.mkConst(funSort2, "v3")
+    f1 = solver.mkConst(funSort1, "f1")
+    f2 = solver.mkConst(funSort2, "f2")
+    f3 = solver.mkConst(bvSort, "f3")
+    solver.defineFunRec("f", [], bvSort, v1)
+    solver.defineFunRec("ff", [b1, b2], bvSort, v1)
+    solver.defineFunRec(f1, [b1, b11], v1)
+    with pytest.raises(RuntimeError):
+        solver.defineFunRec("fff", [b1], bvSort, v3)
+    with pytest.raises(RuntimeError):
+        solver.defineFunRec("ff", [b1, v2], bvSort, v1)
+    with pytest.raises(RuntimeError):
+        solver.defineFunRec("ffff", [b1], funSort2, v3)
+    # b3 has function sort, which is allowed as an argument
+    solver.defineFunRec("fffff", [b1, b3], bvSort, v1)
+    with pytest.raises(RuntimeError):
+        solver.defineFunRec(f1, [b1], v1)
+    with pytest.raises(RuntimeError):
+        solver.defineFunRec(f1, [b1, b11], v2)
+    with pytest.raises(RuntimeError):
+        solver.defineFunRec(f1, [b1, b11], v3)
+    with pytest.raises(RuntimeError):
+        solver.defineFunRec(f2, [b1], v2)
+    with pytest.raises(RuntimeError):
+        solver.defineFunRec(f3, [b1], v1)
+
+    slv = pycvc5.Solver()
+    bvSort2 = slv.mkBitVectorSort(32)
+    v12 = slv.mkConst(bvSort2, "v1")
+    b12 = slv.mkVar(bvSort2, "b1")
+    b22 = slv.mkVar(slv.getIntegerSort(), "b2")
+    slv.defineFunRec("f", [], bvSort2, v12)
+    slv.defineFunRec("ff", [b12, b22], bvSort2, v12)
+    with pytest.raises(RuntimeError):
+        slv.defineFunRec("f", [], bvSort, v12)
+    with pytest.raises(RuntimeError):
+        slv.defineFunRec("f", [], bvSort2, v1)
+    with pytest.raises(RuntimeError):
+        slv.defineFunRec("ff", [b1, b22], bvSort2, v12)
+    with pytest.raises(RuntimeError):
+        slv.defineFunRec("ff", [b12, b2], bvSort2, v12)
+    with pytest.raises(RuntimeError):
+        slv.defineFunRec("ff", [b12, b22], bvSort, v12)
+    with pytest.raises(RuntimeError):
+        slv.defineFunRec("ff", [b12, b22], bvSort2, v1)
+
+
+def test_define_fun_rec_wrong_logic(solver):
+    solver.setLogic("QF_BV")
+    bvSort = solver.mkBitVectorSort(32)
+    funSort = solver.mkFunctionSort([bvSort, bvSort], bvSort)
+    b = solver.mkVar(bvSort, "b")
+    v = solver.mkConst(bvSort, "v")
+    f = solver.mkConst(funSort, "f")
+    with pytest.raises(RuntimeError):
+        solver.defineFunRec("f", [], bvSort, v)
+    with pytest.raises(RuntimeError):
+        solver.defineFunRec(f, [b, b], v)
+
+
+def test_uf_iteration(solver):
+    intSort = solver.getIntegerSort()
+    funSort = solver.mkFunctionSort([intSort, intSort], intSort)
+    x = solver.mkConst(intSort, "x")
+    y = solver.mkConst(intSort, "y")
+    f = solver.mkConst(funSort, "f")
+    fxy = solver.mkTerm(kinds.ApplyUf, f, x, y)
+
+    # Expecting the uninterpreted function to be one of the children
+    expected_children = [f, x, y]
+    idx = 0
+    for c in fxy:
+        assert idx < 3
+        assert c == expected_children[idx]
+        idx = idx + 1
+
+
+def test_get_info(solver):
+    solver.getInfo("name")
+    with pytest.raises(RuntimeError):
+        solver.getInfo("asdf")
+
+
+def test_get_op(solver):
+    bv32 = solver.mkBitVectorSort(32)
+    a = solver.mkConst(bv32, "a")
+    ext = solver.mkOp(kinds.BVExtract, 2, 1)
+    exta = solver.mkTerm(ext, a)
+
+    assert not a.hasOp()
+    with pytest.raises(RuntimeError):
+        a.getOp()
+    assert exta.hasOp()
+    assert exta.getOp() == ext
+
+    # Test Datatypes -- more complicated
+    consListSpec = solver.mkDatatypeDecl("list")
+    cons = solver.mkDatatypeConstructorDecl("cons")
+    cons.addSelector("head", solver.getIntegerSort())
+    cons.addSelectorSelf("tail")
+    consListSpec.addConstructor(cons)
+    nil = solver.mkDatatypeConstructorDecl("nil")
+    consListSpec.addConstructor(nil)
+    consListSort = solver.mkDatatypeSort(consListSpec)
+    consList = consListSort.getDatatype()
+
+    consTerm = consList.getConstructorTerm("cons")
+    nilTerm = consList.getConstructorTerm("nil")
+    headTerm = consList["cons"].getSelectorTerm("head")
+
+    listnil = solver.mkTerm(kinds.ApplyConstructor, nilTerm)
+    listcons1 = solver.mkTerm(kinds.ApplyConstructor, consTerm,
+                              solver.mkInteger(1), listnil)
+    listhead = solver.mkTerm(kinds.ApplySelector, headTerm, listcons1)
+
+    assert listnil.hasOp()
+    assert listcons1.hasOp()
+    assert listhead.hasOp()
+
+
+def test_get_option(solver):
+    solver.getOption("incremental")
+    with pytest.raises(RuntimeError):
+        solver.getOption("asdf")
+
+
+def test_get_unsat_assumptions1(solver):
+    solver.setOption("incremental", "false")
+    solver.checkSatAssuming(solver.mkFalse())
+    with pytest.raises(RuntimeError):
+        solver.getUnsatAssumptions()
+
+
+def test_get_unsat_assumptions2(solver):
+    solver.setOption("incremental", "true")
+    solver.setOption("produce-unsat-assumptions", "false")
+    solver.checkSatAssuming(solver.mkFalse())
+    with pytest.raises(RuntimeError):
+        solver.getUnsatAssumptions()
+
+
+def test_get_unsat_assumptions3(solver):
+    solver.setOption("incremental", "true")
+    solver.setOption("produce-unsat-assumptions", "true")
+    solver.checkSatAssuming(solver.mkFalse())
+    solver.getUnsatAssumptions()
+    solver.checkSatAssuming(solver.mkTrue())
+    with pytest.raises(RuntimeError):
+        solver.getUnsatAssumptions()
+
+
+def test_get_unsat_core1(solver):
+    solver.setOption("incremental", "false")
+    solver.assertFormula(solver.mkFalse())
+    solver.checkSat()
+    with pytest.raises(RuntimeError):
+        solver.getUnsatCore()
+
+
+def test_get_unsat_core2(solver):
+    solver.setOption("incremental", "false")
+    solver.setOption("produce-unsat-cores", "false")
+    solver.assertFormula(solver.mkFalse())
+    solver.checkSat()
+    with pytest.raises(RuntimeError):
+        solver.getUnsatCore()
+
+
+def test_get_unsat_core3(solver):
+    solver.setOption("incremental", "true")
+    solver.setOption("produce-unsat-cores", "true")
+
+    uSort = solver.mkUninterpretedSort("u")
+    intSort = solver.getIntegerSort()
+    boolSort = solver.getBooleanSort()
+    uToIntSort = solver.mkFunctionSort(uSort, intSort)
+    intPredSort = solver.mkFunctionSort(intSort, boolSort)
+
+    x = solver.mkConst(uSort, "x")
+    y = solver.mkConst(uSort, "y")
+    f = solver.mkConst(uToIntSort, "f")
+    p = solver.mkConst(intPredSort, "p")
+    zero = solver.mkInteger(0)
+    one = solver.mkInteger(1)
+    f_x = solver.mkTerm(kinds.ApplyUf, f, x)
+    f_y = solver.mkTerm(kinds.ApplyUf, f, y)
+    summ = solver.mkTerm(kinds.Plus, f_x, f_y)
+    p_0 = solver.mkTerm(kinds.ApplyUf, p, zero)
+    p_f_y = solver.mkTerm(kinds.ApplyUf, p, f_y)
+    solver.assertFormula(solver.mkTerm(kinds.Gt, zero, f_x))
+    solver.assertFormula(solver.mkTerm(kinds.Gt, zero, f_y))
+    solver.assertFormula(solver.mkTerm(kinds.Gt, summ, one))
+    solver.assertFormula(p_0)
+    solver.assertFormula(p_f_y.notTerm())
+    assert solver.checkSat().isUnsat()
+
+    unsat_core = solver.getUnsatCore()
+
+    solver.resetAssertions()
+    for t in unsat_core:
+        solver.assertFormula(t)
+    res = solver.checkSat()
+    assert res.isUnsat()
+
+
+def test_get_value1(solver):
+    solver.setOption("produce-models", "false")
+    t = solver.mkTrue()
+    solver.assertFormula(t)
+    solver.checkSat()
+    with pytest.raises(RuntimeError):
+        solver.getValue(t)
+
+
+def test_get_value2(solver):
+    solver.setOption("produce-models", "true")
+    t = solver.mkFalse()
+    solver.assertFormula(t)
+    solver.checkSat()
+    with pytest.raises(RuntimeError):
+        solver.getValue(t)
+
+
+def test_get_value3(solver):
+    solver.setOption("produce-models", "true")
+    uSort = solver.mkUninterpretedSort("u")
+    intSort = solver.getIntegerSort()
+    boolSort = solver.getBooleanSort()
+    uToIntSort = solver.mkFunctionSort(uSort, intSort)
+    intPredSort = solver.mkFunctionSort(intSort, boolSort)
+
+    x = solver.mkConst(uSort, "x")
+    y = solver.mkConst(uSort, "y")
+    z = solver.mkConst(uSort, "z")
+    f = solver.mkConst(uToIntSort, "f")
+    p = solver.mkConst(intPredSort, "p")
+    zero = solver.mkInteger(0)
+    one = solver.mkInteger(1)
+    f_x = solver.mkTerm(kinds.ApplyUf, f, x)
+    f_y = solver.mkTerm(kinds.ApplyUf, f, y)
+    summ = solver.mkTerm(kinds.Plus, f_x, f_y)
+    p_0 = solver.mkTerm(kinds.ApplyUf, p, zero)
+    p_f_y = solver.mkTerm(kinds.ApplyUf, p, f_y)
+
+    solver.assertFormula(solver.mkTerm(kinds.Leq, zero, f_x))
+    solver.assertFormula(solver.mkTerm(kinds.Leq, zero, f_y))
+    solver.assertFormula(solver.mkTerm(kinds.Leq, summ, one))
+    solver.assertFormula(p_0.notTerm())
+    solver.assertFormula(p_f_y)
+    assert solver.checkSat().isSat()
+    solver.getValue(x)
+    solver.getValue(y)
+    solver.getValue(z)
+    solver.getValue(summ)
+    solver.getValue(p_f_y)
+
+    slv = pycvc5.Solver()
+    with pytest.raises(RuntimeError):
+        slv.getValue(x)
+
+
+def test_declare_separation_heap(solver):
+    solver.setLogic("ALL")
+    integer = solver.getIntegerSort()
+    solver.declareSepHeap(integer, integer)
+    # cannot declare separation logic heap more than once
+    with pytest.raises(RuntimeError):
+        solver.declareSepHeap(integer, integer)
+
+
+# Helper function for test_get_separation_{heap,nil}_termX. Asserts and checks
+# some simple separation logic constraints.
+def checkSimpleSeparationConstraints(slv):
+    integer = slv.getIntegerSort()
+    # declare the separation heap
+    slv.declareSepHeap(integer, integer)
+    x = slv.mkConst(integer, "x")
+    p = slv.mkConst(integer, "p")
+    heap = slv.mkTerm(kinds.SepPto, p, x)
+    slv.assertFormula(heap)
+    nil = slv.mkSepNil(integer)
+    slv.assertFormula(nil.eqTerm(slv.mkReal(5)))
+    slv.checkSat()
+
+
+def test_get_separation_heap_term1(solver):
+    solver.setLogic("QF_BV")
+    solver.setOption("incremental", "false")
+    solver.setOption("produce-models", "true")
+    t = solver.mkTrue()
+    solver.assertFormula(t)
+    with pytest.raises(RuntimeError):
+        solver.getValueSepHeap()
+
+
+def test_get_separation_heap_term2(solver):
+    solver.setLogic("ALL")
+    solver.setOption("incremental", "false")
+    solver.setOption("produce-models", "false")
+    checkSimpleSeparationConstraints(solver)
+    with pytest.raises(RuntimeError):
+        solver.getValueSepHeap()
+
+
+def test_get_separation_heap_term3(solver):
+    solver.setLogic("ALL")
+    solver.setOption("incremental", "false")
+    solver.setOption("produce-models", "true")
+    t = solver.mkFalse()
+    solver.assertFormula(t)
+    solver.checkSat()
+    with pytest.raises(RuntimeError):
+        solver.getValueSepHeap()
+
+
+def test_get_separation_heap_term4(solver):
+    solver.setLogic("ALL")
+    solver.setOption("incremental", "false")
+    solver.setOption("produce-models", "true")
+    t = solver.mkTrue()
+    solver.assertFormula(t)
+    solver.checkSat()
+    with pytest.raises(RuntimeError):
+        solver.getValueSepHeap()
+
+
+def test_get_separation_heap_term5(solver):
+    solver.setLogic("ALL")
+    solver.setOption("incremental", "false")
+    solver.setOption("produce-models", "true")
+    checkSimpleSeparationConstraints(solver)
+    solver.getValueSepHeap()
+
+
+def test_get_separation_nil_term1(solver):
+    solver.setLogic("QF_BV")
+    solver.setOption("incremental", "false")
+    solver.setOption("produce-models", "true")
+    t = solver.mkTrue()
+    solver.assertFormula(t)
+    with pytest.raises(RuntimeError):
+        solver.getValueSepNil()
+
+
+def test_get_separation_nil_term2(solver):
+    solver.setLogic("ALL")
+    solver.setOption("incremental", "false")
+    solver.setOption("produce-models", "false")
+    checkSimpleSeparationConstraints(solver)
+    with pytest.raises(RuntimeError):
+        solver.getValueSepNil()
+
+
+def test_get_separation_nil_term3(solver):
+    solver.setLogic("ALL")
+    solver.setOption("incremental", "false")
+    solver.setOption("produce-models", "true")
+    t = solver.mkFalse()
+    solver.assertFormula(t)
+    solver.checkSat()
+    with pytest.raises(RuntimeError):
+        solver.getValueSepNil()
+
+
+def test_get_separation_nil_term4(solver):
+    solver.setLogic("ALL")
+    solver.setOption("incremental", "false")
+    solver.setOption("produce-models", "true")
+    t = solver.mkTrue()
+    solver.assertFormula(t)
+    solver.checkSat()
+    with pytest.raises(RuntimeError):
+        solver.getValueSepNil()
+
+
+def test_get_separation_nil_term5(solver):
+    solver.setLogic("ALL")
+    solver.setOption("incremental", "false")
+    solver.setOption("produce-models", "true")
+    checkSimpleSeparationConstraints(solver)
+    solver.getValueSepNil()
+
+
+def test_push1(solver):
+    solver.setOption("incremental", "true")
+    solver.push(1)
+    with pytest.raises(RuntimeError):
+        solver.setOption("incremental", "false")
+    with pytest.raises(RuntimeError):
+        solver.setOption("incremental", "true")
+
+
+def test_push2(solver):
+    solver.setOption("incremental", "false")
+    with pytest.raises(RuntimeError):
+        solver.push(1)
+
+
+def test_pop1(solver):
+    solver.setOption("incremental", "false")
+    with pytest.raises(RuntimeError):
+        solver.pop(1)
+
+
+def test_pop2(solver):
+    solver.setOption("incremental", "true")
+    with pytest.raises(RuntimeError):
+        solver.pop(1)
+
+
+def test_pop3(solver):
+    solver.setOption("incremental", "true")
+    solver.push(1)
+    solver.pop(1)
+    with pytest.raises(RuntimeError):
+        solver.pop(1)
+
+
+def test_setInfo(solver):
+    with pytest.raises(RuntimeError):
+        solver.setInfo("cvc5-lagic", "QF_BV")
+    with pytest.raises(RuntimeError):
+        solver.setInfo("cvc2-logic", "QF_BV")
+    with pytest.raises(RuntimeError):
+        solver.setInfo("cvc5-logic", "asdf")
+
+    solver.setInfo("source", "asdf")
+    solver.setInfo("category", "asdf")
+    solver.setInfo("difficulty", "asdf")
+    solver.setInfo("filename", "asdf")
+    solver.setInfo("license", "asdf")
+    solver.setInfo("name", "asdf")
+    solver.setInfo("notes", "asdf")
+
+    solver.setInfo("smt-lib-version", "2")
+    solver.setInfo("smt-lib-version", "2.0")
+    solver.setInfo("smt-lib-version", "2.5")
+    solver.setInfo("smt-lib-version", "2.6")
+    with pytest.raises(RuntimeError):
+        solver.setInfo("smt-lib-version", ".0")
+
+    solver.setInfo("status", "sat")
+    solver.setInfo("status", "unsat")
+    solver.setInfo("status", "unknown")
+    with pytest.raises(RuntimeError):
+        solver.setInfo("status", "asdf")
+
+
+def test_simplify(solver):
+    with pytest.raises(RuntimeError):
+        solver.simplify(pycvc5.Term(solver))
+
+    bvSort = solver.mkBitVectorSort(32)
+    uSort = solver.mkUninterpretedSort("u")
+    funSort1 = solver.mkFunctionSort([bvSort, bvSort], bvSort)
+    funSort2 = solver.mkFunctionSort(uSort, solver.getIntegerSort())
+    consListSpec = solver.mkDatatypeDecl("list")
+    cons = solver.mkDatatypeConstructorDecl("cons")
+    cons.addSelector("head", solver.getIntegerSort())
+    cons.addSelectorSelf("tail")
+    consListSpec.addConstructor(cons)
+    nil = solver.mkDatatypeConstructorDecl("nil")
+    consListSpec.addConstructor(nil)
+    consListSort = solver.mkDatatypeSort(consListSpec)
+
+    x = solver.mkConst(bvSort, "x")
+    solver.simplify(x)
+    a = solver.mkConst(bvSort, "a")
+    solver.simplify(a)
+    b = solver.mkConst(bvSort, "b")
+    solver.simplify(b)
+    x_eq_x = solver.mkTerm(kinds.Equal, x, x)
+    solver.simplify(x_eq_x)
+    assert solver.mkTrue() != x_eq_x
+    assert solver.mkTrue() == solver.simplify(x_eq_x)
+    x_eq_b = solver.mkTerm(kinds.Equal, x, b)
+    solver.simplify(x_eq_b)
+    assert solver.mkTrue() != x_eq_b
+    assert solver.mkTrue() != solver.simplify(x_eq_b)
+    slv = pycvc5.Solver()
+    with pytest.raises(RuntimeError):
+        slv.simplify(x)
+
+    i1 = solver.mkConst(solver.getIntegerSort(), "i1")
+    solver.simplify(i1)
+    i2 = solver.mkTerm(kinds.Mult, i1, solver.mkInteger("23"))
+    solver.simplify(i2)
+    assert i1 != i2
+    assert i1 != solver.simplify(i2)
+    i3 = solver.mkTerm(kinds.Plus, i1, solver.mkInteger(0))
+    solver.simplify(i3)
+    assert i1 != i3
+    assert i1 == solver.simplify(i3)
+
+    consList = consListSort.getDatatype()
+    dt1 = solver.mkTerm(\
+        kinds.ApplyConstructor,\
+        consList.getConstructorTerm("cons"),\
+        solver.mkInteger(0),\
+        solver.mkTerm(kinds.ApplyConstructor, consList.getConstructorTerm("nil")))
+    solver.simplify(dt1)
+    dt2 = solver.mkTerm(\
+      kinds.ApplySelector, consList["cons"].getSelectorTerm("head"), dt1)
+    solver.simplify(dt2)
+
+    b1 = solver.mkVar(bvSort, "b1")
+    solver.simplify(b1)
+    b2 = solver.mkVar(bvSort, "b1")
+    solver.simplify(b2)
+    b3 = solver.mkVar(uSort, "b3")
+    solver.simplify(b3)
+    v1 = solver.mkConst(bvSort, "v1")
+    solver.simplify(v1)
+    v2 = solver.mkConst(solver.getIntegerSort(), "v2")
+    solver.simplify(v2)
+    f1 = solver.mkConst(funSort1, "f1")
+    solver.simplify(f1)
+    f2 = solver.mkConst(funSort2, "f2")
+    solver.simplify(f2)
+    solver.defineFunsRec([f1, f2], [[b1, b2], [b3]], [v1, v2])
+    solver.simplify(f1)
+    solver.simplify(f2)
+
+
+def test_assert_formula(solver):
+    solver.assertFormula(solver.mkTrue())
+    with pytest.raises(RuntimeError):
+        solver.assertFormula(pycvc5.Term(solver))
+    slv = pycvc5.Solver()
+    with pytest.raises(RuntimeError):
+        slv.assertFormula(solver.mkTrue())
+
+
+def test_check_entailed(solver):
+    solver.setOption("incremental", "false")
+    solver.checkEntailed(solver.mkTrue())
+    with pytest.raises(RuntimeError):
+        solver.checkEntailed(solver.mkTrue())
+    slv = pycvc5.Solver()
+    with pytest.raises(RuntimeError):
+        slv.checkEntailed(solver.mkTrue())
+
+
+def test_check_entailed1(solver):
+    boolSort = solver.getBooleanSort()
+    x = solver.mkConst(boolSort, "x")
+    y = solver.mkConst(boolSort, "y")
+    z = solver.mkTerm(kinds.And, x, y)
+    solver.setOption("incremental", "true")
+    solver.checkEntailed(solver.mkTrue())
+    with pytest.raises(RuntimeError):
+        solver.checkEntailed(pycvc5.Term(solver))
+    solver.checkEntailed(solver.mkTrue())
+    solver.checkEntailed(z)
+    slv = pycvc5.Solver()
+    with pytest.raises(RuntimeError):
+        slv.checkEntailed(solver.mkTrue())
+
+
+def test_check_entailed2(solver):
+    solver.setOption("incremental", "true")
+
+    uSort = solver.mkUninterpretedSort("u")
+    intSort = solver.getIntegerSort()
+    boolSort = solver.getBooleanSort()
+    uToIntSort = solver.mkFunctionSort(uSort, intSort)
+    intPredSort = solver.mkFunctionSort(intSort, boolSort)
+
+    n = pycvc5.Term(solver)
+    # Constants
+    x = solver.mkConst(uSort, "x")
+    y = solver.mkConst(uSort, "y")
+    # Functions
+    f = solver.mkConst(uToIntSort, "f")
+    p = solver.mkConst(intPredSort, "p")
+    # Values
+    zero = solver.mkInteger(0)
+    one = solver.mkInteger(1)
+    # Terms
+    f_x = solver.mkTerm(kinds.ApplyUf, f, x)
+    f_y = solver.mkTerm(kinds.ApplyUf, f, y)
+    summ = solver.mkTerm(kinds.Plus, f_x, f_y)
+    p_0 = solver.mkTerm(kinds.ApplyUf, p, zero)
+    p_f_y = solver.mkTerm(kinds.ApplyUf, p, f_y)
+    # Assertions
+    assertions =\
+        solver.mkTerm(kinds.And,\
+                      [solver.mkTerm(kinds.Leq, zero, f_x),  # 0 <= f(x)
+                       solver.mkTerm(kinds.Leq, zero, f_y),  # 0 <= f(y)
+                       solver.mkTerm(kinds.Leq, summ, one),  # f(x) + f(y) <= 1
+                       p_0.notTerm(),                        # not p(0)
+                       p_f_y                                 # p(f(y))
+                      ])
+
+    solver.checkEntailed(solver.mkTrue())
+    solver.assertFormula(assertions)
+    solver.checkEntailed(solver.mkTerm(kinds.Distinct, x, y))
+    solver.checkEntailed(\
+        [solver.mkFalse(), solver.mkTerm(kinds.Distinct, x, y)])
+    with pytest.raises(RuntimeError):
+        solver.checkEntailed(n)
+    with pytest.raises(RuntimeError):
+        solver.checkEntailed([n, solver.mkTerm(kinds.Distinct, x, y)])
+    slv = pycvc5.Solver()
+    with pytest.raises(RuntimeError):
+        slv.checkEntailed(solver.mkTrue())
+
+
+def test_check_sat(solver):
+    solver.setOption("incremental", "false")
+    solver.checkSat()
+    with pytest.raises(RuntimeError):
+        solver.checkSat()
+
+
+def test_check_sat_assuming(solver):
+    solver.setOption("incremental", "false")
+    solver.checkSatAssuming(solver.mkTrue())
+    with pytest.raises(RuntimeError):
+        solver.checkSatAssuming(solver.mkTrue())
+    slv = pycvc5.Solver()
+    with pytest.raises(RuntimeError):
+        slv.checkSatAssuming(solver.mkTrue())
+
+
+def test_check_sat_assuming1(solver):
+    boolSort = solver.getBooleanSort()
+    x = solver.mkConst(boolSort, "x")
+    y = solver.mkConst(boolSort, "y")
+    z = solver.mkTerm(kinds.And, x, y)
+    solver.setOption("incremental", "true")
+    solver.checkSatAssuming(solver.mkTrue())
+    with pytest.raises(RuntimeError):
+        solver.checkSatAssuming(pycvc5.Term(solver))
+    solver.checkSatAssuming(solver.mkTrue())
+    solver.checkSatAssuming(z)
+    slv = pycvc5.Solver()
+    with pytest.raises(RuntimeError):
+        slv.checkSatAssuming(solver.mkTrue())
+
+
+def test_check_sat_assuming2(solver):
+    solver.setOption("incremental", "true")
+
+    uSort = solver.mkUninterpretedSort("u")
+    intSort = solver.getIntegerSort()
+    boolSort = solver.getBooleanSort()
+    uToIntSort = solver.mkFunctionSort(uSort, intSort)
+    intPredSort = solver.mkFunctionSort(intSort, boolSort)
+
+    n = pycvc5.Term(solver)
+    # Constants
+    x = solver.mkConst(uSort, "x")
+    y = solver.mkConst(uSort, "y")
+    # Functions
+    f = solver.mkConst(uToIntSort, "f")
+    p = solver.mkConst(intPredSort, "p")
+    # Values
+    zero = solver.mkInteger(0)
+    one = solver.mkInteger(1)
+    # Terms
+    f_x = solver.mkTerm(kinds.ApplyUf, f, x)
+    f_y = solver.mkTerm(kinds.ApplyUf, f, y)
+    summ = solver.mkTerm(kinds.Plus, f_x, f_y)
+    p_0 = solver.mkTerm(kinds.ApplyUf, p, zero)
+    p_f_y = solver.mkTerm(kinds.ApplyUf, p, f_y)
+    # Assertions
+    assertions =\
+        solver.mkTerm(kinds.And,\
+                      [solver.mkTerm(kinds.Leq, zero, f_x),  # 0 <= f(x)
+                       solver.mkTerm(kinds.Leq, zero, f_y),  # 0 <= f(y)
+                       solver.mkTerm(kinds.Leq, summ, one),  # f(x) + f(y) <= 1
+                       p_0.notTerm(),                        # not p(0)
+                       p_f_y                                 # p(f(y))
+                      ])
+
+    solver.checkSatAssuming(solver.mkTrue())
+    solver.assertFormula(assertions)
+    solver.checkSatAssuming(solver.mkTerm(kinds.Distinct, x, y))
+    solver.checkSatAssuming(
+        [solver.mkFalse(),
+         solver.mkTerm(kinds.Distinct, x, y)])
+    with pytest.raises(RuntimeError):
+        solver.checkSatAssuming(n)
+    with pytest.raises(RuntimeError):
+        solver.checkSatAssuming([n, solver.mkTerm(kinds.Distinct, x, y)])
+    slv = pycvc5.Solver()
+    with pytest.raises(RuntimeError):
+        slv.checkSatAssuming(solver.mkTrue())
+
+
+def test_set_logic(solver):
+    solver.setLogic("AUFLIRA")
+    with pytest.raises(RuntimeError):
+        solver.setLogic("AF_BV")
+    solver.assertFormula(solver.mkTrue())
+    with pytest.raises(RuntimeError):
+        solver.setLogic("AUFLIRA")
+
+
+def test_set_option(solver):
+    solver.setOption("bv-sat-solver", "minisat")
+    with pytest.raises(RuntimeError):
+        solver.setOption("bv-sat-solver", "1")
+    solver.assertFormula(solver.mkTrue())
+    with pytest.raises(RuntimeError):
+        solver.setOption("bv-sat-solver", "minisat")
+
+
+def test_reset_assertions(solver):
+    solver.setOption("incremental", "true")
+
+    bvSort = solver.mkBitVectorSort(4)
+    one = solver.mkBitVector(4, 1)
+    x = solver.mkConst(bvSort, "x")
+    ule = solver.mkTerm(kinds.BVUle, x, one)
+    srem = solver.mkTerm(kinds.BVSrem, one, x)
+    solver.push(4)
+    slt = solver.mkTerm(kinds.BVSlt, srem, one)
+    solver.resetAssertions()
+    solver.checkSatAssuming([slt, ule])
+
+
+def test_mk_sygus_grammar(solver):
+    nullTerm = pycvc5.Term(solver)
+    boolTerm = solver.mkBoolean(True)
+    boolVar = solver.mkVar(solver.getBooleanSort())
+    intVar = solver.mkVar(solver.getIntegerSort())
+
+    solver.mkSygusGrammar([], [intVar])
+    solver.mkSygusGrammar([boolVar], [intVar])
+    with pytest.raises(RuntimeError):
+        solver.mkSygusGrammar([], [])
+    with pytest.raises(RuntimeError):
+        solver.mkSygusGrammar([], [nullTerm])
+    with pytest.raises(RuntimeError):
+        solver.mkSygusGrammar([], [boolTerm])
+    with pytest.raises(RuntimeError):
+        solver.mkSygusGrammar([boolTerm], [intVar])
+    slv = pycvc5.Solver()
+    boolVar2 = slv.mkVar(slv.getBooleanSort())
+    intVar2 = slv.mkVar(slv.getIntegerSort())
+    slv.mkSygusGrammar([boolVar2], [intVar2])
+    with pytest.raises(RuntimeError):
+        slv.mkSygusGrammar([boolVar], [intVar2])
+    with pytest.raises(RuntimeError):
+        slv.mkSygusGrammar([boolVar2], [intVar])
+
+
+def test_synth_inv(solver):
+    boolean = solver.getBooleanSort()
+    integer = solver.getIntegerSort()
+
+    nullTerm = pycvc5.Term(solver)
+    x = solver.mkVar(boolean)
+
+    start1 = solver.mkVar(boolean)
+    start2 = solver.mkVar(integer)
+
+    g1 = solver.mkSygusGrammar([x], [start1])
+    g1.addRule(start1, solver.mkBoolean(False))
+
+    g2 = solver.mkSygusGrammar([x], [start2])
+    g2.addRule(start2, solver.mkInteger(0))
+
+    solver.synthInv("", [])
+    solver.synthInv("i1", [x])
+    solver.synthInv("i2", [x], g1)
+
+    with pytest.raises(RuntimeError):
+        solver.synthInv("i3", [nullTerm])
+    with pytest.raises(RuntimeError):
+        solver.synthInv("i4", [x], g2)
+
+
+def test_add_sygus_constraint(solver):
+    nullTerm = pycvc5.Term(solver)
+    boolTerm = solver.mkBoolean(True)
+    intTerm = solver.mkInteger(1)
+
+    solver.addSygusConstraint(boolTerm)
+    with pytest.raises(RuntimeError):
+        solver.addSygusConstraint(nullTerm)
+    with pytest.raises(RuntimeError):
+        solver.addSygusConstraint(intTerm)
+
+    slv = pycvc5.Solver()
+    with pytest.raises(RuntimeError):
+        slv.addSygusConstraint(boolTerm)
+
+
+def test_add_sygus_inv_constraint(solver):
+    boolean = solver.getBooleanSort()
+    real = solver.getRealSort()
+
+    nullTerm = pycvc5.Term(solver)
+    intTerm = solver.mkInteger(1)
+
+    inv = solver.declareFun("inv", [real], boolean)
+    pre = solver.declareFun("pre", [real], boolean)
+    trans = solver.declareFun("trans", [real, real], boolean)
+    post = solver.declareFun("post", [real], boolean)
+
+    inv1 = solver.declareFun("inv1", [real], real)
+
+    trans1 = solver.declareFun("trans1", [boolean, real], boolean)
+    trans2 = solver.declareFun("trans2", [real, boolean], boolean)
+    trans3 = solver.declareFun("trans3", [real, real], real)
+
+    solver.addSygusInvConstraint(inv, pre, trans, post)
+
+    with pytest.raises(RuntimeError):
+        solver.addSygusInvConstraint(nullTerm, pre, trans, post)
+    with pytest.raises(RuntimeError):
+        solver.addSygusInvConstraint(inv, nullTerm, trans, post)
+    with pytest.raises(RuntimeError):
+        solver.addSygusInvConstraint(inv, pre, nullTerm, post)
+    with pytest.raises(RuntimeError):
+        solver.addSygusInvConstraint(inv, pre, trans, nullTerm)
+
+    with pytest.raises(RuntimeError):
+        solver.addSygusInvConstraint(intTerm, pre, trans, post)
+
+    with pytest.raises(RuntimeError):
+        solver.addSygusInvConstraint(inv1, pre, trans, post)
+
+    with pytest.raises(RuntimeError):
+        solver.addSygusInvConstraint(inv, trans, trans, post)
+
+    with pytest.raises(RuntimeError):
+        solver.addSygusInvConstraint(inv, pre, intTerm, post)
+    with pytest.raises(RuntimeError):
+        solver.addSygusInvConstraint(inv, pre, pre, post)
+    with pytest.raises(RuntimeError):
+        solver.addSygusInvConstraint(inv, pre, trans1, post)
+    with pytest.raises(RuntimeError):
+        solver.addSygusInvConstraint(inv, pre, trans2, post)
+    with pytest.raises(RuntimeError):
+        solver.addSygusInvConstraint(inv, pre, trans3, post)
+
+    with pytest.raises(RuntimeError):
+        solver.addSygusInvConstraint(inv, pre, trans, trans)
+    slv = pycvc5.Solver()
+    boolean2 = slv.getBooleanSort()
+    real2 = slv.getRealSort()
+    inv22 = slv.declareFun("inv", [real2], boolean2)
+    pre22 = slv.declareFun("pre", [real2], boolean2)
+    trans22 = slv.declareFun("trans", [real2, real2], boolean2)
+    post22 = slv.declareFun("post", [real2], boolean2)
+    slv.addSygusInvConstraint(inv22, pre22, trans22, post22)
+    with pytest.raises(RuntimeError):
+        slv.addSygusInvConstraint(inv, pre22, trans22, post22)
+    with pytest.raises(RuntimeError):
+        slv.addSygusInvConstraint(inv22, pre, trans22, post22)
+    with pytest.raises(RuntimeError):
+        slv.addSygusInvConstraint(inv22, pre22, trans, post22)
+    with pytest.raises(RuntimeError):
+        slv.addSygusInvConstraint(inv22, pre22, trans22, post)
+
+
+def test_get_synth_solution(solver):
+    solver.setOption("lang", "sygus2")
+    solver.setOption("incremental", "false")
+
+    nullTerm = pycvc5.Term(solver)
+    x = solver.mkBoolean(False)
+    f = solver.synthFun("f", [], solver.getBooleanSort())
+
+    with pytest.raises(RuntimeError):
+        solver.getSynthSolution(f)
+
+    solver.checkSynth()
+
+    solver.getSynthSolution(f)
+    solver.getSynthSolution(f)
+
+    with pytest.raises(RuntimeError):
+        solver.getSynthSolution(nullTerm)
+    with pytest.raises(RuntimeError):
+        solver.getSynthSolution(x)
+
+    slv = pycvc5.Solver()
+    with pytest.raises(RuntimeError):
+        slv.getSynthSolution(f)
diff --git a/test/unit/api/python/test_sort.py b/test/unit/api/python/test_sort.py
new file mode 100644 (file)
index 0000000..98cf76d
--- /dev/null
@@ -0,0 +1,575 @@
+###############################################################################
+# Top contributors (to current version):
+#   Yoni Zohar, Makai Mann
+#
+# This file is part of the cvc5 project.
+#
+# Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
+# in the top-level source directory and their institutional affiliations.
+# All rights reserved.  See the file COPYING in the top-level source
+# directory for licensing information.
+# #############################################################################
+#
+# Unit tests for sort API.
+#
+# Obtained by translating test/unit/api/sort_black.cpp
+##
+
+import pytest
+import pycvc5
+from pycvc5 import kinds
+from pycvc5 import Sort
+
+
+@pytest.fixture
+def solver():
+    return pycvc5.Solver()
+
+
+def create_datatype_sort(solver):
+    intSort = solver.getIntegerSort()
+    # create datatype sort to test
+    dtypeSpec = solver.mkDatatypeDecl("list")
+    cons = solver.mkDatatypeConstructorDecl("cons")
+    cons.addSelector("head", intSort)
+    cons.addSelectorSelf("tail")
+    dtypeSpec.addConstructor(cons)
+    nil = solver.mkDatatypeConstructorDecl("nil")
+    dtypeSpec.addConstructor(nil)
+    dtypeSort = solver.mkDatatypeSort(dtypeSpec)
+    return dtypeSort
+
+
+def create_param_datatype_sort(solver):
+    sort = solver.mkParamSort("T")
+    paramDtypeSpec = solver.mkDatatypeDecl("paramlist", sort)
+    paramCons = solver.mkDatatypeConstructorDecl("cons")
+    paramNil = solver.mkDatatypeConstructorDecl("nil")
+    paramCons.addSelector("head", sort)
+    paramDtypeSpec.addConstructor(paramCons)
+    paramDtypeSpec.addConstructor(paramNil)
+    paramDtypeSort = solver.mkDatatypeSort(paramDtypeSpec)
+    return paramDtypeSort
+
+
+def test_operators_comparison(solver):
+    solver.getIntegerSort() == Sort(solver)
+    solver.getIntegerSort() != Sort(solver)
+    solver.getIntegerSort() < Sort(solver)
+    solver.getIntegerSort() <= Sort(solver)
+    solver.getIntegerSort() > Sort(solver)
+    solver.getIntegerSort() >= Sort(solver)
+
+def test_is_null(solver):
+   x = Sort(solver)
+   assert x.isNull()
+   x = solver.getBooleanSort()
+   assert not x.isNull()
+
+def test_is_boolean(solver):
+    assert solver.getBooleanSort().isBoolean()
+    Sort(solver).isBoolean()
+
+
+def test_is_integer(solver):
+    assert solver.getIntegerSort().isInteger()
+    assert not solver.getRealSort().isInteger()
+    Sort(solver).isInteger()
+
+
+def test_is_real(solver):
+    assert solver.getRealSort().isReal()
+    assert not solver.getIntegerSort().isReal()
+    Sort(solver).isReal()
+
+
+def test_is_string(solver):
+    assert solver.getStringSort().isString()
+    Sort(solver).isString()
+
+
+def test_is_reg_exp(solver):
+    assert solver.getRegExpSort().isRegExp()
+    Sort(solver).isRegExp()
+
+
+def test_is_rounding_mode(solver):
+    assert solver.getRoundingModeSort().isRoundingMode()
+    Sort(solver).isRoundingMode()
+
+
+def test_is_bit_vector(solver):
+    assert solver.mkBitVectorSort(8).isBitVector()
+    Sort(solver).isBitVector()
+
+
+def test_is_floating_point(solver):
+    assert solver.mkFloatingPointSort(8, 24).isFloatingPoint()
+    Sort(solver).isFloatingPoint()
+
+
+def test_is_datatype(solver):
+    dt_sort = create_datatype_sort(solver)
+    assert dt_sort.isDatatype()
+    Sort(solver).isDatatype()
+
+
+def test_is_parametric_datatype(solver):
+    param_dt_sort = create_param_datatype_sort(solver)
+    assert param_dt_sort.isParametricDatatype()
+    Sort(solver).isParametricDatatype()
+
+
+def test_is_constructor(solver):
+    dt_sort = create_datatype_sort(solver)
+    dt = dt_sort.getDatatype()
+    cons_sort = dt[0].getConstructorTerm().getSort()
+    assert cons_sort.isConstructor()
+    Sort(solver).isConstructor()
+
+
+def test_is_selector(solver):
+    dt_sort = create_datatype_sort(solver)
+    dt = dt_sort.getDatatype()
+    dt0 = dt[0]
+    dt01 = dt0[1]
+    cons_sort = dt01.getSelectorTerm().getSort()
+    assert cons_sort.isSelector()
+    Sort(solver).isSelector()
+
+
+def test_is_tester(solver):
+    dt_sort = create_datatype_sort(solver)
+    dt = dt_sort.getDatatype()
+    cons_sort = dt[0].getTesterTerm().getSort()
+    assert cons_sort.isTester()
+    Sort(solver).isTester()
+
+def test_is_updater(solver):
+  dt_sort = create_datatype_sort(solver)
+  dt = dt_sort.getDatatype()
+  updater_sort = dt[0][0].getUpdaterTerm().getSort()
+  assert updater_sort.isUpdater()
+  Sort(solver).isUpdater()
+
+def test_is_function(solver):
+    fun_sort = solver.mkFunctionSort(solver.getRealSort(),
+                                     solver.getIntegerSort())
+    assert fun_sort.isFunction()
+    Sort(solver).isFunction()
+
+
+def test_is_predicate(solver):
+    pred_sort = solver.mkPredicateSort(solver.getRealSort())
+    assert pred_sort.isPredicate()
+    Sort(solver).isPredicate()
+
+
+def test_is_tuple(solver):
+    tup_sort = solver.mkTupleSort(solver.getRealSort())
+    assert tup_sort.isTuple()
+    Sort(solver).isTuple()
+
+
+def test_is_record(solver):
+    rec_sort = solver.mkRecordSort([("asdf", solver.getRealSort())])
+    assert rec_sort.isRecord()
+    Sort(solver).isRecord()
+
+
+def test_is_array(solver):
+    arr_sort = solver.mkArraySort(solver.getRealSort(),
+                                  solver.getIntegerSort())
+    assert arr_sort.isArray()
+    Sort(solver).isArray()
+
+
+def test_is_set(solver):
+    set_sort = solver.mkSetSort(solver.getRealSort())
+    assert set_sort.isSet()
+    Sort(solver).isSet()
+
+
+def test_is_bag(solver):
+    bag_sort = solver.mkBagSort(solver.getRealSort())
+    assert bag_sort.isBag()
+    Sort(solver).isBag()
+
+
+def test_is_sequence(solver):
+    seq_sort = solver.mkSequenceSort(solver.getRealSort())
+    assert seq_sort.isSequence()
+    Sort(solver).isSequence()
+
+
+def test_is_uninterpreted(solver):
+    un_sort = solver.mkUninterpretedSort("asdf")
+    assert un_sort.isUninterpretedSort()
+    Sort(solver).isUninterpretedSort()
+
+
+def test_is_sort_constructor(solver):
+    sc_sort = solver.mkSortConstructorSort("asdf", 1)
+    assert sc_sort.isSortConstructor()
+    Sort(solver).isSortConstructor()
+
+
+def test_is_first_class(solver):
+    fun_sort = solver.mkFunctionSort(solver.getRealSort(),
+                                     solver.getIntegerSort())
+    assert solver.getIntegerSort().isFirstClass()
+    assert fun_sort.isFirstClass()
+    reSort = solver.getRegExpSort()
+    assert not reSort.isFirstClass()
+    Sort(solver).isFirstClass()
+
+
+def test_is_function_like(solver):
+    fun_sort = solver.mkFunctionSort(solver.getRealSort(),
+                                     solver.getIntegerSort())
+    assert not solver.getIntegerSort().isFunctionLike()
+    assert fun_sort.isFunctionLike()
+
+    dt_sort = create_datatype_sort(solver)
+    dt = dt_sort.getDatatype()
+    cons_sort = dt[0][1].getSelectorTerm().getSort()
+    assert cons_sort.isFunctionLike()
+
+    Sort(solver).isFunctionLike()
+
+
+def test_is_subsort_of(solver):
+    assert solver.getIntegerSort().isSubsortOf(solver.getIntegerSort())
+    assert solver.getIntegerSort().isSubsortOf(solver.getRealSort())
+    assert not solver.getIntegerSort().isSubsortOf(solver.getBooleanSort())
+    Sort(solver).isSubsortOf(Sort(solver))
+
+
+def test_is_comparable_to(solver):
+    assert solver.getIntegerSort().isComparableTo(solver.getIntegerSort())
+    assert solver.getIntegerSort().isComparableTo(solver.getRealSort())
+    assert not solver.getIntegerSort().isComparableTo(solver.getBooleanSort())
+    Sort(solver).isComparableTo(Sort(solver))
+
+
+def test_get_datatype(solver):
+    dtypeSort = create_datatype_sort(solver)
+    dtypeSort.getDatatype()
+    # create bv sort, check should fail
+    bvSort = solver.mkBitVectorSort(32)
+    with pytest.raises(RuntimeError):
+        bvSort.getDatatype()
+
+
+def test_datatype_sorts(solver):
+    intSort = solver.getIntegerSort()
+    dtypeSort = create_datatype_sort(solver)
+    dt = dtypeSort.getDatatype()
+    assert not dtypeSort.isConstructor()
+    with pytest.raises(RuntimeError):
+        dtypeSort.getConstructorCodomainSort()
+    with pytest.raises(RuntimeError):
+        dtypeSort.getConstructorDomainSorts()
+    with pytest.raises(RuntimeError):
+        dtypeSort.getConstructorArity()
+
+    # get constructor
+    dcons = dt[0]
+    consTerm = dcons.getConstructorTerm()
+    consSort = consTerm.getSort()
+    assert consSort.isConstructor()
+    assert not consSort.isTester()
+    assert not consSort.isSelector()
+    assert consSort.getConstructorArity() == 2
+    consDomSorts = consSort.getConstructorDomainSorts()
+    assert consDomSorts[0] == intSort
+    assert consDomSorts[1] == dtypeSort
+    assert consSort.getConstructorCodomainSort() == dtypeSort
+
+    # get tester
+    isConsTerm = dcons.getTesterTerm()
+    assert isConsTerm.getSort().isTester()
+    booleanSort = solver.getBooleanSort()
+
+    assert isConsTerm.getSort().getTesterDomainSort() == dtypeSort
+    assert isConsTerm.getSort().getTesterCodomainSort() == booleanSort
+    with pytest.raises(RuntimeError):
+        booleanSort.getTesterDomainSort()
+    with pytest.raises(RuntimeError):
+        booleanSort.getTesterCodomainSort()
+
+    # get selector
+    dselTail = dcons[1]
+    tailTerm = dselTail.getSelectorTerm()
+    assert tailTerm.getSort().isSelector()
+    assert tailTerm.getSort().getSelectorDomainSort() == dtypeSort
+    assert tailTerm.getSort().getSelectorCodomainSort() == dtypeSort
+    with pytest.raises(RuntimeError):
+        booleanSort.getSelectorDomainSort()
+    with pytest.raises(RuntimeError):
+        booleanSort.getSelectorCodomainSort()
+
+
+def test_instantiate(solver):
+    # instantiate parametric datatype, check should not fail
+    paramDtypeSort = create_param_datatype_sort(solver)
+    paramDtypeSort.instantiate([solver.getIntegerSort()])
+    # instantiate non-parametric datatype sort, check should fail
+    dtypeSpec = solver.mkDatatypeDecl("list")
+    cons = solver.mkDatatypeConstructorDecl("cons")
+    cons.addSelector("head", solver.getIntegerSort())
+    dtypeSpec.addConstructor(cons)
+    nil = solver.mkDatatypeConstructorDecl("nil")
+    dtypeSpec.addConstructor(nil)
+    dtypeSort = solver.mkDatatypeSort(dtypeSpec)
+    with pytest.raises(RuntimeError):
+        dtypeSort.instantiate([solver.getIntegerSort()])
+
+
+def test_get_function_arity(solver):
+    funSort = solver.mkFunctionSort(solver.mkUninterpretedSort("u"),
+                                    solver.getIntegerSort())
+    funSort.getFunctionArity()
+    bvSort = solver.mkBitVectorSort(32)
+    with pytest.raises(RuntimeError):
+        bvSort.getFunctionArity()
+
+
+def test_get_function_domain_sorts(solver):
+    funSort = solver.mkFunctionSort(solver.mkUninterpretedSort("u"),
+                                    solver.getIntegerSort())
+    funSort.getFunctionDomainSorts()
+    bvSort = solver.mkBitVectorSort(32)
+    with pytest.raises(RuntimeError):
+        bvSort.getFunctionDomainSorts()
+
+
+def test_get_function_codomain_sort(solver):
+    funSort = solver.mkFunctionSort(solver.mkUninterpretedSort("u"),
+                                    solver.getIntegerSort())
+    funSort.getFunctionCodomainSort()
+    bvSort = solver.mkBitVectorSort(32)
+    with pytest.raises(RuntimeError):
+        bvSort.getFunctionCodomainSort()
+
+
+def test_get_array_index_sort(solver):
+    elementSort = solver.mkBitVectorSort(32)
+    indexSort = solver.mkBitVectorSort(32)
+    arraySort = solver.mkArraySort(indexSort, elementSort)
+    arraySort.getArrayIndexSort()
+    with pytest.raises(RuntimeError):
+        indexSort.getArrayIndexSort()
+
+
+def test_get_array_element_sort(solver):
+    elementSort = solver.mkBitVectorSort(32)
+    indexSort = solver.mkBitVectorSort(32)
+    arraySort = solver.mkArraySort(indexSort, elementSort)
+    arraySort.getArrayElementSort()
+    with pytest.raises(RuntimeError):
+        indexSort.getArrayElementSort()
+
+
+def test_get_set_element_sort(solver):
+    setSort = solver.mkSetSort(solver.getIntegerSort())
+    setSort.getSetElementSort()
+    elementSort = setSort.getSetElementSort()
+    assert elementSort == solver.getIntegerSort()
+    bvSort = solver.mkBitVectorSort(32)
+    with pytest.raises(RuntimeError):
+        bvSort.getSetElementSort()
+
+
+def test_get_bag_element_sort(solver):
+    bagSort = solver.mkBagSort(solver.getIntegerSort())
+    bagSort.getBagElementSort()
+    elementSort = bagSort.getBagElementSort()
+    assert elementSort == solver.getIntegerSort()
+    bvSort = solver.mkBitVectorSort(32)
+    with pytest.raises(RuntimeError):
+        bvSort.getBagElementSort()
+
+
+def test_get_sequence_element_sort(solver):
+    seqSort = solver.mkSequenceSort(solver.getIntegerSort())
+    assert seqSort.isSequence()
+    seqSort.getSequenceElementSort()
+    bvSort = solver.mkBitVectorSort(32)
+    assert not bvSort.isSequence()
+    with pytest.raises(RuntimeError):
+        bvSort.getSequenceElementSort()
+
+
+def test_get_uninterpreted_sort_name(solver):
+    uSort = solver.mkUninterpretedSort("u")
+    uSort.getUninterpretedSortName()
+    bvSort = solver.mkBitVectorSort(32)
+    with pytest.raises(RuntimeError):
+        bvSort.getUninterpretedSortName()
+
+
+def test_is_uninterpreted_sort_parameterized(solver):
+    uSort = solver.mkUninterpretedSort("u")
+    assert not uSort.isUninterpretedSortParameterized()
+    sSort = solver.mkSortConstructorSort("s", 1)
+    siSort = sSort.instantiate([uSort])
+    assert siSort.isUninterpretedSortParameterized()
+    bvSort = solver.mkBitVectorSort(32)
+    with pytest.raises(RuntimeError):
+        bvSort.isUninterpretedSortParameterized()
+
+
+def test_get_uninterpreted_sort_paramsorts(solver):
+    uSort = solver.mkUninterpretedSort("u")
+    uSort.getUninterpretedSortParamSorts()
+    sSort = solver.mkSortConstructorSort("s", 2)
+    siSort = sSort.instantiate([uSort, uSort])
+    assert len(siSort.getUninterpretedSortParamSorts()) == 2
+    bvSort = solver.mkBitVectorSort(32)
+    with pytest.raises(RuntimeError):
+        bvSort.getUninterpretedSortParamSorts()
+
+
+def test_get_uninterpreted_sort_constructor_name(solver):
+    sSort = solver.mkSortConstructorSort("s", 2)
+    sSort.getSortConstructorName()
+    bvSort = solver.mkBitVectorSort(32)
+    with pytest.raises(RuntimeError):
+        bvSort.getSortConstructorName()
+
+
+def test_get_uninterpreted_sort_constructor_arity(solver):
+    sSort = solver.mkSortConstructorSort("s", 2)
+    sSort.getSortConstructorArity()
+    bvSort = solver.mkBitVectorSort(32)
+    with pytest.raises(RuntimeError):
+        bvSort.getSortConstructorArity()
+
+
+def test_get_bv_size(solver):
+    bvSort = solver.mkBitVectorSort(32)
+    bvSort.getBitVectorSize()
+    setSort = solver.mkSetSort(solver.getIntegerSort())
+    with pytest.raises(RuntimeError):
+        setSort.getBitVectorSize()
+
+
+def test_get_fp_exponent_size(solver):
+    fpSort = solver.mkFloatingPointSort(4, 8)
+    fpSort.getFloatingPointExponentSize()
+    setSort = solver.mkSetSort(solver.getIntegerSort())
+    with pytest.raises(RuntimeError):
+        setSort.getFloatingPointExponentSize()
+
+
+def test_get_fp_significand_size(solver):
+    fpSort = solver.mkFloatingPointSort(4, 8)
+    fpSort.getFloatingPointSignificandSize()
+    setSort = solver.mkSetSort(solver.getIntegerSort())
+    with pytest.raises(RuntimeError):
+        setSort.getFloatingPointSignificandSize()
+
+
+def test_get_datatype_paramsorts(solver):
+    # create parametric datatype, check should not fail
+    sort = solver.mkParamSort("T")
+    paramDtypeSpec = solver.mkDatatypeDecl("paramlist", sort)
+    paramCons = solver.mkDatatypeConstructorDecl("cons")
+    paramNil = solver.mkDatatypeConstructorDecl("nil")
+    paramCons.addSelector("head", sort)
+    paramDtypeSpec.addConstructor(paramCons)
+    paramDtypeSpec.addConstructor(paramNil)
+    paramDtypeSort = solver.mkDatatypeSort(paramDtypeSpec)
+    paramDtypeSort.getDatatypeParamSorts()
+    # create non-parametric datatype sort, check should fail
+    dtypeSpec = solver.mkDatatypeDecl("list")
+    cons = solver.mkDatatypeConstructorDecl("cons")
+    cons.addSelector("head", solver.getIntegerSort())
+    dtypeSpec.addConstructor(cons)
+    nil = solver.mkDatatypeConstructorDecl("nil")
+    dtypeSpec.addConstructor(nil)
+    dtypeSort = solver.mkDatatypeSort(dtypeSpec)
+    with pytest.raises(RuntimeError):
+        dtypeSort.getDatatypeParamSorts()
+
+
+def test_get_datatype_arity(solver):
+    # create datatype sort, check should not fail
+    dtypeSpec = solver.mkDatatypeDecl("list")
+    cons = solver.mkDatatypeConstructorDecl("cons")
+    cons.addSelector("head", solver.getIntegerSort())
+    dtypeSpec.addConstructor(cons)
+    nil = solver.mkDatatypeConstructorDecl("nil")
+    dtypeSpec.addConstructor(nil)
+    dtypeSort = solver.mkDatatypeSort(dtypeSpec)
+    dtypeSort.getDatatypeArity()
+    # create bv sort, check should fail
+    bvSort = solver.mkBitVectorSort(32)
+    with pytest.raises(RuntimeError):
+        bvSort.getDatatypeArity()
+
+
+def test_get_tuple_length(solver):
+    tupleSort = solver.mkTupleSort(
+        [solver.getIntegerSort(),
+         solver.getIntegerSort()])
+    tupleSort.getTupleLength()
+    bvSort = solver.mkBitVectorSort(32)
+    with pytest.raises(RuntimeError):
+        bvSort.getTupleLength()
+
+
+def test_get_tuple_sorts(solver):
+    tupleSort = solver.mkTupleSort(
+        [solver.getIntegerSort(),
+         solver.getIntegerSort()])
+    tupleSort.getTupleSorts()
+    bvSort = solver.mkBitVectorSort(32)
+    with pytest.raises(RuntimeError):
+        bvSort.getTupleSorts()
+
+
+def test_sort_compare(solver):
+    boolSort = solver.getBooleanSort()
+    intSort = solver.getIntegerSort()
+    bvSort = solver.mkBitVectorSort(32)
+    bvSort2 = solver.mkBitVectorSort(32)
+    assert bvSort >= bvSort2
+    assert bvSort <= bvSort2
+    assert (intSort > boolSort) != (intSort < boolSort)
+    assert (intSort > bvSort or intSort == bvSort) == (intSort >= bvSort)
+
+
+def test_sort_subtyping(solver):
+    intSort = solver.getIntegerSort()
+    realSort = solver.getRealSort()
+    assert intSort.isSubsortOf(realSort)
+    assert not realSort.isSubsortOf(intSort)
+    assert intSort.isComparableTo(realSort)
+    assert realSort.isComparableTo(intSort)
+
+    arraySortII = solver.mkArraySort(intSort, intSort)
+    arraySortIR = solver.mkArraySort(intSort, realSort)
+    assert not arraySortII.isComparableTo(intSort)
+    # we do not support subtyping for arrays
+    assert not arraySortII.isComparableTo(arraySortIR)
+
+    setSortI = solver.mkSetSort(intSort)
+    setSortR = solver.mkSetSort(realSort)
+    # we don't support subtyping for sets
+    assert not setSortI.isComparableTo(setSortR)
+    assert not setSortI.isSubsortOf(setSortR)
+    assert not setSortR.isComparableTo(setSortI)
+    assert not setSortR.isSubsortOf(setSortI)
+
+
+def test_sort_scoped_tostring(solver):
+    name = "uninterp-sort"
+    bvsort8 = solver.mkBitVectorSort(8)
+    uninterp_sort = solver.mkUninterpretedSort(name)
+    assert str(bvsort8) == "(_ BitVec 8)"
+    assert str(uninterp_sort) == name
+    solver2 = pycvc5.Solver()
+    assert str(bvsort8) == "(_ BitVec 8)"
+    assert str(uninterp_sort) == name
diff --git a/test/unit/api/python/test_term.py b/test/unit/api/python/test_term.py
new file mode 100644 (file)
index 0000000..34a79d5
--- /dev/null
@@ -0,0 +1,1267 @@
+###############################################################################
+# Top contributors (to current version):
+#   Yoni Zohar, Makai Mann, Andres Noetzli
+#
+# This file is part of the cvc5 project.
+#
+# Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
+# in the top-level source directory and their institutional affiliations.
+# All rights reserved.  See the file COPYING in the top-level source
+# directory for licensing information.
+# #############################################################################
+##
+
+import pytest
+import pycvc5
+from pycvc5 import kinds
+from pycvc5 import Sort, Term
+from fractions import Fraction
+
+
+@pytest.fixture
+def solver():
+    return pycvc5.Solver()
+
+
+def test_eq(solver):
+    uSort = solver.mkUninterpretedSort("u")
+    x = solver.mkVar(uSort, "x")
+    y = solver.mkVar(uSort, "y")
+    z = Term(solver)
+
+    assert x == x
+    assert not x != x
+    assert not x == y
+    assert x != y
+    assert not (x == z)
+    assert x != z
+
+
+def test_get_id(solver):
+    n = Term(solver)
+    with pytest.raises(RuntimeError):
+        n.getId()
+    x = solver.mkVar(solver.getIntegerSort(), "x")
+    x.getId()
+    y = x
+    assert x.getId() == y.getId()
+
+    z = solver.mkVar(solver.getIntegerSort(), "z")
+    assert x.getId() != z.getId()
+
+
+def test_get_kind(solver):
+    uSort = solver.mkUninterpretedSort("u")
+    intSort = solver.getIntegerSort()
+    boolSort = solver.getBooleanSort()
+    funSort1 = solver.mkFunctionSort(uSort, intSort)
+    funSort2 = solver.mkFunctionSort(intSort, boolSort)
+
+    n = Term(solver)
+    with pytest.raises(RuntimeError):
+        n.getKind()
+    x = solver.mkVar(uSort, "x")
+    x.getKind()
+    y = solver.mkVar(uSort, "y")
+    y.getKind()
+
+    f = solver.mkVar(funSort1, "f")
+    f.getKind()
+    p = solver.mkVar(funSort2, "p")
+    p.getKind()
+
+    zero = solver.mkInteger(0)
+    zero.getKind()
+
+    f_x = solver.mkTerm(kinds.ApplyUf, f, x)
+    f_x.getKind()
+    f_y = solver.mkTerm(kinds.ApplyUf, f, y)
+    f_y.getKind()
+    sum = solver.mkTerm(kinds.Plus, f_x, f_y)
+    sum.getKind()
+    p_0 = solver.mkTerm(kinds.ApplyUf, p, zero)
+    p_0.getKind()
+    p_f_y = solver.mkTerm(kinds.ApplyUf, p, f_y)
+    p_f_y.getKind()
+
+    # Sequence kinds do not exist internally, test that the API properly
+    # converts them back.
+    seqSort = solver.mkSequenceSort(intSort)
+    s = solver.mkConst(seqSort, "s")
+    ss = solver.mkTerm(kinds.SeqConcat, s, s)
+    assert ss.getKind() == kinds.SeqConcat
+
+
+def test_get_sort(solver):
+    bvSort = solver.mkBitVectorSort(8)
+    intSort = solver.getIntegerSort()
+    boolSort = solver.getBooleanSort()
+    funSort1 = solver.mkFunctionSort(bvSort, intSort)
+    funSort2 = solver.mkFunctionSort(intSort, boolSort)
+
+    n = Term(solver)
+    with pytest.raises(RuntimeError):
+        n.getSort()
+    x = solver.mkVar(bvSort, "x")
+    x.getSort()
+    assert x.getSort() == bvSort
+    y = solver.mkVar(bvSort, "y")
+    y.getSort()
+    assert y.getSort() == bvSort
+
+    f = solver.mkVar(funSort1, "f")
+    f.getSort()
+    assert f.getSort() == funSort1
+    p = solver.mkVar(funSort2, "p")
+    p.getSort()
+    assert p.getSort() == funSort2
+
+    zero = solver.mkInteger(0)
+    zero.getSort()
+    assert zero.getSort() == intSort
+
+    f_x = solver.mkTerm(kinds.ApplyUf, f, x)
+    f_x.getSort()
+    assert f_x.getSort() == intSort
+    f_y = solver.mkTerm(kinds.ApplyUf, f, y)
+    f_y.getSort()
+    assert f_y.getSort() == intSort
+    sum = solver.mkTerm(kinds.Plus, f_x, f_y)
+    sum.getSort()
+    assert sum.getSort() == intSort
+    p_0 = solver.mkTerm(kinds.ApplyUf, p, zero)
+    p_0.getSort()
+    assert p_0.getSort() == boolSort
+    p_f_y = solver.mkTerm(kinds.ApplyUf, p, f_y)
+    p_f_y.getSort()
+    assert p_f_y.getSort() == boolSort
+
+
+def test_get_op(solver):
+    intsort = solver.getIntegerSort()
+    bvsort = solver.mkBitVectorSort(8)
+    arrsort = solver.mkArraySort(bvsort, intsort)
+    funsort = solver.mkFunctionSort(intsort, bvsort)
+
+    x = solver.mkConst(intsort, "x")
+    a = solver.mkConst(arrsort, "a")
+    b = solver.mkConst(bvsort, "b")
+
+    assert not x.hasOp()
+    with pytest.raises(RuntimeError):
+        x.getOp()
+
+    ab = solver.mkTerm(kinds.Select, a, b)
+    ext = solver.mkOp(kinds.BVExtract, 4, 0)
+    extb = solver.mkTerm(ext, b)
+
+    assert ab.hasOp()
+    assert not ab.getOp().isIndexed()
+    # can compare directly to a Kind (will invoke constructor)
+    assert extb.hasOp()
+    assert extb.getOp().isIndexed()
+    assert extb.getOp() == ext
+
+    f = solver.mkConst(funsort, "f")
+    fx = solver.mkTerm(kinds.ApplyUf, f, x)
+
+    assert not f.hasOp()
+    with pytest.raises(RuntimeError):
+        f.getOp()
+    assert fx.hasOp()
+    children = [c for c in fx]
+    # testing rebuild from op and children
+    assert fx == solver.mkTerm(fx.getOp(), children)
+
+    # Test Datatypes Ops
+    sort = solver.mkParamSort("T")
+    listDecl = solver.mkDatatypeDecl("paramlist", sort)
+    cons = solver.mkDatatypeConstructorDecl("cons")
+    nil = solver.mkDatatypeConstructorDecl("nil")
+    cons.addSelector("head", sort)
+    cons.addSelectorSelf("tail")
+    listDecl.addConstructor(cons)
+    listDecl.addConstructor(nil)
+    listSort = solver.mkDatatypeSort(listDecl)
+    intListSort = listSort.instantiate([solver.getIntegerSort()])
+    c = solver.mkConst(intListSort, "c")
+    list1 = listSort.getDatatype()
+    # list datatype constructor and selector operator terms
+    consOpTerm = list1.getConstructorTerm("cons")
+    nilOpTerm = list1.getConstructorTerm("nil")
+    headOpTerm = list1["cons"].getSelectorTerm("head")
+    tailOpTerm = list1["cons"].getSelectorTerm("tail")
+
+    nilTerm = solver.mkTerm(kinds.ApplyConstructor, nilOpTerm)
+    consTerm = solver.mkTerm(kinds.ApplyConstructor, consOpTerm,
+                             solver.mkInteger(0), nilTerm)
+    headTerm = solver.mkTerm(kinds.ApplySelector, headOpTerm, consTerm)
+    tailTerm = solver.mkTerm(kinds.ApplySelector, tailOpTerm, consTerm)
+
+    assert nilTerm.hasOp()
+    assert consTerm.hasOp()
+    assert headTerm.hasOp()
+    assert tailTerm.hasOp()
+
+    # Test rebuilding
+    children = [c for c in headTerm]
+    assert headTerm == solver.mkTerm(headTerm.getOp(), children)
+
+
+def test_is_null(solver):
+    x = Term(solver)
+    assert x.isNull()
+    x = solver.mkVar(solver.mkBitVectorSort(4), "x")
+    assert not x.isNull()
+
+
+def test_not_term(solver):
+    bvSort = solver.mkBitVectorSort(8)
+    intSort = solver.getIntegerSort()
+    boolSort = solver.getBooleanSort()
+    funSort1 = solver.mkFunctionSort(bvSort, intSort)
+    funSort2 = solver.mkFunctionSort(intSort, boolSort)
+
+    with pytest.raises(RuntimeError):
+        Term(solver).notTerm()
+    b = solver.mkTrue()
+    b.notTerm()
+    x = solver.mkVar(solver.mkBitVectorSort(8), "x")
+    with pytest.raises(RuntimeError):
+        x.notTerm()
+    f = solver.mkVar(funSort1, "f")
+    with pytest.raises(RuntimeError):
+        f.notTerm()
+    p = solver.mkVar(funSort2, "p")
+    with pytest.raises(RuntimeError):
+        p.notTerm()
+    zero = solver.mkInteger(0)
+    with pytest.raises(RuntimeError):
+        zero.notTerm()
+    f_x = solver.mkTerm(kinds.ApplyUf, f, x)
+    with pytest.raises(RuntimeError):
+        f_x.notTerm()
+    sum = solver.mkTerm(kinds.Plus, f_x, f_x)
+    with pytest.raises(RuntimeError):
+        sum.notTerm()
+    p_0 = solver.mkTerm(kinds.ApplyUf, p, zero)
+    p_0.notTerm()
+    p_f_x = solver.mkTerm(kinds.ApplyUf, p, f_x)
+    p_f_x.notTerm()
+
+
+def test_and_term(solver):
+    bvSort = solver.mkBitVectorSort(8)
+    intSort = solver.getIntegerSort()
+    boolSort = solver.getBooleanSort()
+    funSort1 = solver.mkFunctionSort(bvSort, intSort)
+    funSort2 = solver.mkFunctionSort(intSort, boolSort)
+
+    b = solver.mkTrue()
+    with pytest.raises(RuntimeError):
+        Term(solver).andTerm(b)
+    with pytest.raises(RuntimeError):
+        b.andTerm(Term(solver))
+    b.andTerm(b)
+    x = solver.mkVar(solver.mkBitVectorSort(8), "x")
+    with pytest.raises(RuntimeError):
+        x.andTerm(b)
+    with pytest.raises(RuntimeError):
+        x.andTerm(x)
+    f = solver.mkVar(funSort1, "f")
+    with pytest.raises(RuntimeError):
+        f.andTerm(b)
+    with pytest.raises(RuntimeError):
+        f.andTerm(x)
+    with pytest.raises(RuntimeError):
+        f.andTerm(f)
+    p = solver.mkVar(funSort2, "p")
+    with pytest.raises(RuntimeError):
+        p.andTerm(b)
+    with pytest.raises(RuntimeError):
+        p.andTerm(x)
+    with pytest.raises(RuntimeError):
+        p.andTerm(f)
+    with pytest.raises(RuntimeError):
+        p.andTerm(p)
+    zero = solver.mkInteger(0)
+    with pytest.raises(RuntimeError):
+        zero.andTerm(b)
+    with pytest.raises(RuntimeError):
+        zero.andTerm(x)
+    with pytest.raises(RuntimeError):
+        zero.andTerm(f)
+    with pytest.raises(RuntimeError):
+        zero.andTerm(p)
+    with pytest.raises(RuntimeError):
+        zero.andTerm(zero)
+    f_x = solver.mkTerm(kinds.ApplyUf, f, x)
+    with pytest.raises(RuntimeError):
+        f_x.andTerm(b)
+    with pytest.raises(RuntimeError):
+        f_x.andTerm(x)
+    with pytest.raises(RuntimeError):
+        f_x.andTerm(f)
+    with pytest.raises(RuntimeError):
+        f_x.andTerm(p)
+    with pytest.raises(RuntimeError):
+        f_x.andTerm(zero)
+    with pytest.raises(RuntimeError):
+        f_x.andTerm(f_x)
+    sum = solver.mkTerm(kinds.Plus, f_x, f_x)
+    with pytest.raises(RuntimeError):
+        sum.andTerm(b)
+    with pytest.raises(RuntimeError):
+        sum.andTerm(x)
+    with pytest.raises(RuntimeError):
+        sum.andTerm(f)
+    with pytest.raises(RuntimeError):
+        sum.andTerm(p)
+    with pytest.raises(RuntimeError):
+        sum.andTerm(zero)
+    with pytest.raises(RuntimeError):
+        sum.andTerm(f_x)
+    with pytest.raises(RuntimeError):
+        sum.andTerm(sum)
+    p_0 = solver.mkTerm(kinds.ApplyUf, p, zero)
+    p_0.andTerm(b)
+    with pytest.raises(RuntimeError):
+        p_0.andTerm(x)
+    with pytest.raises(RuntimeError):
+        p_0.andTerm(f)
+    with pytest.raises(RuntimeError):
+        p_0.andTerm(p)
+    with pytest.raises(RuntimeError):
+        p_0.andTerm(zero)
+    with pytest.raises(RuntimeError):
+        p_0.andTerm(f_x)
+    with pytest.raises(RuntimeError):
+        p_0.andTerm(sum)
+    p_0.andTerm(p_0)
+    p_f_x = solver.mkTerm(kinds.ApplyUf, p, f_x)
+    p_f_x.andTerm(b)
+    with pytest.raises(RuntimeError):
+        p_f_x.andTerm(x)
+    with pytest.raises(RuntimeError):
+        p_f_x.andTerm(f)
+    with pytest.raises(RuntimeError):
+        p_f_x.andTerm(p)
+    with pytest.raises(RuntimeError):
+        p_f_x.andTerm(zero)
+    with pytest.raises(RuntimeError):
+        p_f_x.andTerm(f_x)
+    with pytest.raises(RuntimeError):
+        p_f_x.andTerm(sum)
+    p_f_x.andTerm(p_0)
+    p_f_x.andTerm(p_f_x)
+
+
+def test_or_term(solver):
+    bvSort = solver.mkBitVectorSort(8)
+    intSort = solver.getIntegerSort()
+    boolSort = solver.getBooleanSort()
+    funSort1 = solver.mkFunctionSort(bvSort, intSort)
+    funSort2 = solver.mkFunctionSort(intSort, boolSort)
+
+    b = solver.mkTrue()
+    with pytest.raises(RuntimeError):
+        Term(solver).orTerm(b)
+    with pytest.raises(RuntimeError):
+        b.orTerm(Term(solver))
+    b.orTerm(b)
+    x = solver.mkVar(solver.mkBitVectorSort(8), "x")
+    with pytest.raises(RuntimeError):
+        x.orTerm(b)
+    with pytest.raises(RuntimeError):
+        x.orTerm(x)
+    f = solver.mkVar(funSort1, "f")
+    with pytest.raises(RuntimeError):
+        f.orTerm(b)
+    with pytest.raises(RuntimeError):
+        f.orTerm(x)
+    with pytest.raises(RuntimeError):
+        f.orTerm(f)
+    p = solver.mkVar(funSort2, "p")
+    with pytest.raises(RuntimeError):
+        p.orTerm(b)
+    with pytest.raises(RuntimeError):
+        p.orTerm(x)
+    with pytest.raises(RuntimeError):
+        p.orTerm(f)
+    with pytest.raises(RuntimeError):
+        p.orTerm(p)
+    zero = solver.mkInteger(0)
+    with pytest.raises(RuntimeError):
+        zero.orTerm(b)
+    with pytest.raises(RuntimeError):
+        zero.orTerm(x)
+    with pytest.raises(RuntimeError):
+        zero.orTerm(f)
+    with pytest.raises(RuntimeError):
+        zero.orTerm(p)
+    with pytest.raises(RuntimeError):
+        zero.orTerm(zero)
+    f_x = solver.mkTerm(kinds.ApplyUf, f, x)
+    with pytest.raises(RuntimeError):
+        f_x.orTerm(b)
+    with pytest.raises(RuntimeError):
+        f_x.orTerm(x)
+    with pytest.raises(RuntimeError):
+        f_x.orTerm(f)
+    with pytest.raises(RuntimeError):
+        f_x.orTerm(p)
+    with pytest.raises(RuntimeError):
+        f_x.orTerm(zero)
+    with pytest.raises(RuntimeError):
+        f_x.orTerm(f_x)
+    sum = solver.mkTerm(kinds.Plus, f_x, f_x)
+    with pytest.raises(RuntimeError):
+        sum.orTerm(b)
+    with pytest.raises(RuntimeError):
+        sum.orTerm(x)
+    with pytest.raises(RuntimeError):
+        sum.orTerm(f)
+    with pytest.raises(RuntimeError):
+        sum.orTerm(p)
+    with pytest.raises(RuntimeError):
+        sum.orTerm(zero)
+    with pytest.raises(RuntimeError):
+        sum.orTerm(f_x)
+    with pytest.raises(RuntimeError):
+        sum.orTerm(sum)
+    p_0 = solver.mkTerm(kinds.ApplyUf, p, zero)
+    p_0.orTerm(b)
+    with pytest.raises(RuntimeError):
+        p_0.orTerm(x)
+    with pytest.raises(RuntimeError):
+        p_0.orTerm(f)
+    with pytest.raises(RuntimeError):
+        p_0.orTerm(p)
+    with pytest.raises(RuntimeError):
+        p_0.orTerm(zero)
+    with pytest.raises(RuntimeError):
+        p_0.orTerm(f_x)
+    with pytest.raises(RuntimeError):
+        p_0.orTerm(sum)
+    p_0.orTerm(p_0)
+    p_f_x = solver.mkTerm(kinds.ApplyUf, p, f_x)
+    p_f_x.orTerm(b)
+    with pytest.raises(RuntimeError):
+        p_f_x.orTerm(x)
+    with pytest.raises(RuntimeError):
+        p_f_x.orTerm(f)
+    with pytest.raises(RuntimeError):
+        p_f_x.orTerm(p)
+    with pytest.raises(RuntimeError):
+        p_f_x.orTerm(zero)
+    with pytest.raises(RuntimeError):
+        p_f_x.orTerm(f_x)
+    with pytest.raises(RuntimeError):
+        p_f_x.orTerm(sum)
+    p_f_x.orTerm(p_0)
+    p_f_x.orTerm(p_f_x)
+
+
+def test_xor_term(solver):
+    bvSort = solver.mkBitVectorSort(8)
+    intSort = solver.getIntegerSort()
+    boolSort = solver.getBooleanSort()
+    funSort1 = solver.mkFunctionSort(bvSort, intSort)
+    funSort2 = solver.mkFunctionSort(intSort, boolSort)
+
+    b = solver.mkTrue()
+    with pytest.raises(RuntimeError):
+        Term(solver).xorTerm(b)
+    with pytest.raises(RuntimeError):
+        b.xorTerm(Term(solver))
+    b.xorTerm(b)
+    x = solver.mkVar(solver.mkBitVectorSort(8), "x")
+    with pytest.raises(RuntimeError):
+        x.xorTerm(b)
+    with pytest.raises(RuntimeError):
+        x.xorTerm(x)
+    f = solver.mkVar(funSort1, "f")
+    with pytest.raises(RuntimeError):
+        f.xorTerm(b)
+    with pytest.raises(RuntimeError):
+        f.xorTerm(x)
+    with pytest.raises(RuntimeError):
+        f.xorTerm(f)
+    p = solver.mkVar(funSort2, "p")
+    with pytest.raises(RuntimeError):
+        p.xorTerm(b)
+    with pytest.raises(RuntimeError):
+        p.xorTerm(x)
+    with pytest.raises(RuntimeError):
+        p.xorTerm(f)
+    with pytest.raises(RuntimeError):
+        p.xorTerm(p)
+    zero = solver.mkInteger(0)
+    with pytest.raises(RuntimeError):
+        zero.xorTerm(b)
+    with pytest.raises(RuntimeError):
+        zero.xorTerm(x)
+    with pytest.raises(RuntimeError):
+        zero.xorTerm(f)
+    with pytest.raises(RuntimeError):
+        zero.xorTerm(p)
+    with pytest.raises(RuntimeError):
+        zero.xorTerm(zero)
+    f_x = solver.mkTerm(kinds.ApplyUf, f, x)
+    with pytest.raises(RuntimeError):
+        f_x.xorTerm(b)
+    with pytest.raises(RuntimeError):
+        f_x.xorTerm(x)
+    with pytest.raises(RuntimeError):
+        f_x.xorTerm(f)
+    with pytest.raises(RuntimeError):
+        f_x.xorTerm(p)
+    with pytest.raises(RuntimeError):
+        f_x.xorTerm(zero)
+    with pytest.raises(RuntimeError):
+        f_x.xorTerm(f_x)
+    sum = solver.mkTerm(kinds.Plus, f_x, f_x)
+    with pytest.raises(RuntimeError):
+        sum.xorTerm(b)
+    with pytest.raises(RuntimeError):
+        sum.xorTerm(x)
+    with pytest.raises(RuntimeError):
+        sum.xorTerm(f)
+    with pytest.raises(RuntimeError):
+        sum.xorTerm(p)
+    with pytest.raises(RuntimeError):
+        sum.xorTerm(zero)
+    with pytest.raises(RuntimeError):
+        sum.xorTerm(f_x)
+    with pytest.raises(RuntimeError):
+        sum.xorTerm(sum)
+    p_0 = solver.mkTerm(kinds.ApplyUf, p, zero)
+    p_0.xorTerm(b)
+    with pytest.raises(RuntimeError):
+        p_0.xorTerm(x)
+    with pytest.raises(RuntimeError):
+        p_0.xorTerm(f)
+    with pytest.raises(RuntimeError):
+        p_0.xorTerm(p)
+    with pytest.raises(RuntimeError):
+        p_0.xorTerm(zero)
+    with pytest.raises(RuntimeError):
+        p_0.xorTerm(f_x)
+    with pytest.raises(RuntimeError):
+        p_0.xorTerm(sum)
+    p_0.xorTerm(p_0)
+    p_f_x = solver.mkTerm(kinds.ApplyUf, p, f_x)
+    p_f_x.xorTerm(b)
+    with pytest.raises(RuntimeError):
+        p_f_x.xorTerm(x)
+    with pytest.raises(RuntimeError):
+        p_f_x.xorTerm(f)
+    with pytest.raises(RuntimeError):
+        p_f_x.xorTerm(p)
+    with pytest.raises(RuntimeError):
+        p_f_x.xorTerm(zero)
+    with pytest.raises(RuntimeError):
+        p_f_x.xorTerm(f_x)
+    with pytest.raises(RuntimeError):
+        p_f_x.xorTerm(sum)
+    p_f_x.xorTerm(p_0)
+    p_f_x.xorTerm(p_f_x)
+
+
+def test_eq_term(solver):
+    bvSort = solver.mkBitVectorSort(8)
+    intSort = solver.getIntegerSort()
+    boolSort = solver.getBooleanSort()
+    funSort1 = solver.mkFunctionSort(bvSort, intSort)
+    funSort2 = solver.mkFunctionSort(intSort, boolSort)
+
+    b = solver.mkTrue()
+    with pytest.raises(RuntimeError):
+        Term(solver).eqTerm(b)
+    with pytest.raises(RuntimeError):
+        b.eqTerm(Term(solver))
+    b.eqTerm(b)
+    x = solver.mkVar(solver.mkBitVectorSort(8), "x")
+    with pytest.raises(RuntimeError):
+        x.eqTerm(b)
+    x.eqTerm(x)
+    f = solver.mkVar(funSort1, "f")
+    with pytest.raises(RuntimeError):
+        f.eqTerm(b)
+    with pytest.raises(RuntimeError):
+        f.eqTerm(x)
+    f.eqTerm(f)
+    p = solver.mkVar(funSort2, "p")
+    with pytest.raises(RuntimeError):
+        p.eqTerm(b)
+    with pytest.raises(RuntimeError):
+        p.eqTerm(x)
+    with pytest.raises(RuntimeError):
+        p.eqTerm(f)
+    p.eqTerm(p)
+    zero = solver.mkInteger(0)
+    with pytest.raises(RuntimeError):
+        zero.eqTerm(b)
+    with pytest.raises(RuntimeError):
+        zero.eqTerm(x)
+    with pytest.raises(RuntimeError):
+        zero.eqTerm(f)
+    with pytest.raises(RuntimeError):
+        zero.eqTerm(p)
+    zero.eqTerm(zero)
+    f_x = solver.mkTerm(kinds.ApplyUf, f, x)
+    with pytest.raises(RuntimeError):
+        f_x.eqTerm(b)
+    with pytest.raises(RuntimeError):
+        f_x.eqTerm(x)
+    with pytest.raises(RuntimeError):
+        f_x.eqTerm(f)
+    with pytest.raises(RuntimeError):
+        f_x.eqTerm(p)
+    f_x.eqTerm(zero)
+    f_x.eqTerm(f_x)
+    sum = solver.mkTerm(kinds.Plus, f_x, f_x)
+    with pytest.raises(RuntimeError):
+        sum.eqTerm(b)
+    with pytest.raises(RuntimeError):
+        sum.eqTerm(x)
+    with pytest.raises(RuntimeError):
+        sum.eqTerm(f)
+    with pytest.raises(RuntimeError):
+        sum.eqTerm(p)
+    sum.eqTerm(zero)
+    sum.eqTerm(f_x)
+    sum.eqTerm(sum)
+    p_0 = solver.mkTerm(kinds.ApplyUf, p, zero)
+    p_0.eqTerm(b)
+    with pytest.raises(RuntimeError):
+        p_0.eqTerm(x)
+    with pytest.raises(RuntimeError):
+        p_0.eqTerm(f)
+    with pytest.raises(RuntimeError):
+        p_0.eqTerm(p)
+    with pytest.raises(RuntimeError):
+        p_0.eqTerm(zero)
+    with pytest.raises(RuntimeError):
+        p_0.eqTerm(f_x)
+    with pytest.raises(RuntimeError):
+        p_0.eqTerm(sum)
+    p_0.eqTerm(p_0)
+    p_f_x = solver.mkTerm(kinds.ApplyUf, p, f_x)
+    p_f_x.eqTerm(b)
+    with pytest.raises(RuntimeError):
+        p_f_x.eqTerm(x)
+    with pytest.raises(RuntimeError):
+        p_f_x.eqTerm(f)
+    with pytest.raises(RuntimeError):
+        p_f_x.eqTerm(p)
+    with pytest.raises(RuntimeError):
+        p_f_x.eqTerm(zero)
+    with pytest.raises(RuntimeError):
+        p_f_x.eqTerm(f_x)
+    with pytest.raises(RuntimeError):
+        p_f_x.eqTerm(sum)
+    p_f_x.eqTerm(p_0)
+    p_f_x.eqTerm(p_f_x)
+
+
+def test_imp_term(solver):
+    bvSort = solver.mkBitVectorSort(8)
+    intSort = solver.getIntegerSort()
+    boolSort = solver.getBooleanSort()
+    funSort1 = solver.mkFunctionSort(bvSort, intSort)
+    funSort2 = solver.mkFunctionSort(intSort, boolSort)
+
+    b = solver.mkTrue()
+    with pytest.raises(RuntimeError):
+        Term(solver).impTerm(b)
+    with pytest.raises(RuntimeError):
+        b.impTerm(Term(solver))
+    b.impTerm(b)
+    x = solver.mkVar(solver.mkBitVectorSort(8), "x")
+    with pytest.raises(RuntimeError):
+        x.impTerm(b)
+    with pytest.raises(RuntimeError):
+        x.impTerm(x)
+    f = solver.mkVar(funSort1, "f")
+    with pytest.raises(RuntimeError):
+        f.impTerm(b)
+    with pytest.raises(RuntimeError):
+        f.impTerm(x)
+    with pytest.raises(RuntimeError):
+        f.impTerm(f)
+    p = solver.mkVar(funSort2, "p")
+    with pytest.raises(RuntimeError):
+        p.impTerm(b)
+    with pytest.raises(RuntimeError):
+        p.impTerm(x)
+    with pytest.raises(RuntimeError):
+        p.impTerm(f)
+    with pytest.raises(RuntimeError):
+        p.impTerm(p)
+    zero = solver.mkInteger(0)
+    with pytest.raises(RuntimeError):
+        zero.impTerm(b)
+    with pytest.raises(RuntimeError):
+        zero.impTerm(x)
+    with pytest.raises(RuntimeError):
+        zero.impTerm(f)
+    with pytest.raises(RuntimeError):
+        zero.impTerm(p)
+    with pytest.raises(RuntimeError):
+        zero.impTerm(zero)
+    f_x = solver.mkTerm(kinds.ApplyUf, f, x)
+    with pytest.raises(RuntimeError):
+        f_x.impTerm(b)
+    with pytest.raises(RuntimeError):
+        f_x.impTerm(x)
+    with pytest.raises(RuntimeError):
+        f_x.impTerm(f)
+    with pytest.raises(RuntimeError):
+        f_x.impTerm(p)
+    with pytest.raises(RuntimeError):
+        f_x.impTerm(zero)
+    with pytest.raises(RuntimeError):
+        f_x.impTerm(f_x)
+    sum = solver.mkTerm(kinds.Plus, f_x, f_x)
+    with pytest.raises(RuntimeError):
+        sum.impTerm(b)
+    with pytest.raises(RuntimeError):
+        sum.impTerm(x)
+    with pytest.raises(RuntimeError):
+        sum.impTerm(f)
+    with pytest.raises(RuntimeError):
+        sum.impTerm(p)
+    with pytest.raises(RuntimeError):
+        sum.impTerm(zero)
+    with pytest.raises(RuntimeError):
+        sum.impTerm(f_x)
+    with pytest.raises(RuntimeError):
+        sum.impTerm(sum)
+    p_0 = solver.mkTerm(kinds.ApplyUf, p, zero)
+    p_0.impTerm(b)
+    with pytest.raises(RuntimeError):
+        p_0.impTerm(x)
+    with pytest.raises(RuntimeError):
+        p_0.impTerm(f)
+    with pytest.raises(RuntimeError):
+        p_0.impTerm(p)
+    with pytest.raises(RuntimeError):
+        p_0.impTerm(zero)
+    with pytest.raises(RuntimeError):
+        p_0.impTerm(f_x)
+    with pytest.raises(RuntimeError):
+        p_0.impTerm(sum)
+    p_0.impTerm(p_0)
+    p_f_x = solver.mkTerm(kinds.ApplyUf, p, f_x)
+    p_f_x.impTerm(b)
+    with pytest.raises(RuntimeError):
+        p_f_x.impTerm(x)
+    with pytest.raises(RuntimeError):
+        p_f_x.impTerm(f)
+    with pytest.raises(RuntimeError):
+        p_f_x.impTerm(p)
+    with pytest.raises(RuntimeError):
+        p_f_x.impTerm(zero)
+    with pytest.raises(RuntimeError):
+        p_f_x.impTerm(f_x)
+    with pytest.raises(RuntimeError):
+        p_f_x.impTerm(sum)
+    p_f_x.impTerm(p_0)
+    p_f_x.impTerm(p_f_x)
+
+
+def test_ite_term(solver):
+    bvSort = solver.mkBitVectorSort(8)
+    intSort = solver.getIntegerSort()
+    boolSort = solver.getBooleanSort()
+    funSort1 = solver.mkFunctionSort(bvSort, intSort)
+    funSort2 = solver.mkFunctionSort(intSort, boolSort)
+
+    b = solver.mkTrue()
+    with pytest.raises(RuntimeError):
+        Term(solver).iteTerm(b, b)
+    with pytest.raises(RuntimeError):
+        b.iteTerm(Term(solver), b)
+    with pytest.raises(RuntimeError):
+        b.iteTerm(b, Term(solver))
+    b.iteTerm(b, b)
+    x = solver.mkVar(solver.mkBitVectorSort(8), "x")
+    b.iteTerm(x, x)
+    b.iteTerm(b, b)
+    with pytest.raises(RuntimeError):
+        b.iteTerm(x, b)
+    with pytest.raises(RuntimeError):
+        x.iteTerm(x, x)
+    with pytest.raises(RuntimeError):
+        x.iteTerm(x, b)
+    f = solver.mkVar(funSort1, "f")
+    with pytest.raises(RuntimeError):
+        f.iteTerm(b, b)
+    with pytest.raises(RuntimeError):
+        x.iteTerm(b, x)
+    p = solver.mkVar(funSort2, "p")
+    with pytest.raises(RuntimeError):
+        p.iteTerm(b, b)
+    with pytest.raises(RuntimeError):
+        p.iteTerm(x, b)
+    zero = solver.mkInteger(0)
+    with pytest.raises(RuntimeError):
+        zero.iteTerm(x, x)
+    with pytest.raises(RuntimeError):
+        zero.iteTerm(x, b)
+    f_x = solver.mkTerm(kinds.ApplyUf, f, x)
+    with pytest.raises(RuntimeError):
+        f_x.iteTerm(b, b)
+    with pytest.raises(RuntimeError):
+        f_x.iteTerm(b, x)
+    sum = solver.mkTerm(kinds.Plus, f_x, f_x)
+    with pytest.raises(RuntimeError):
+        sum.iteTerm(x, x)
+    with pytest.raises(RuntimeError):
+        sum.iteTerm(b, x)
+    p_0 = solver.mkTerm(kinds.ApplyUf, p, zero)
+    p_0.iteTerm(b, b)
+    p_0.iteTerm(x, x)
+    with pytest.raises(RuntimeError):
+        p_0.iteTerm(x, b)
+    p_f_x = solver.mkTerm(kinds.ApplyUf, p, f_x)
+    p_f_x.iteTerm(b, b)
+    p_f_x.iteTerm(x, x)
+    with pytest.raises(RuntimeError):
+        p_f_x.iteTerm(x, b)
+
+
+def test_term_assignment(solver):
+    t1 = solver.mkInteger(1)
+    t2 = t1
+    t2 = solver.mkInteger(2)
+    assert t1 == solver.mkInteger(1)
+
+
+def test_substitute(solver):
+    x = solver.mkConst(solver.getIntegerSort(), "x")
+    one = solver.mkInteger(1)
+    ttrue = solver.mkTrue()
+    xpx = solver.mkTerm(kinds.Plus, x, x)
+    onepone = solver.mkTerm(kinds.Plus, one, one)
+
+    assert xpx.substitute(x, one) == onepone
+    assert onepone.substitute(one, x) == xpx
+    # incorrect due to type
+    with pytest.raises(RuntimeError):
+        xpx.substitute(one, ttrue)
+
+    # simultaneous substitution
+    y = solver.mkConst(solver.getIntegerSort(), "y")
+    xpy = solver.mkTerm(kinds.Plus, x, y)
+    xpone = solver.mkTerm(kinds.Plus, y, one)
+    es = []
+    rs = []
+    es.append(x)
+    rs.append(y)
+    es.append(y)
+    rs.append(one)
+    assert xpy.substitute(es, rs) == xpone
+
+    # incorrect substitution due to arity
+    rs.pop()
+    with pytest.raises(RuntimeError):
+        xpy.substitute(es, rs)
+
+    # incorrect substitution due to types
+    rs.append(ttrue)
+    with pytest.raises(RuntimeError):
+        xpy.substitute(es, rs)
+
+    # null cannot substitute
+    tnull = Term(solver)
+    with pytest.raises(RuntimeError):
+        tnull.substitute(one, x)
+    with pytest.raises(RuntimeError):
+        xpx.substitute(tnull, x)
+    with pytest.raises(RuntimeError):
+        xpx.substitute(x, tnull)
+    rs.pop()
+    rs.append(tnull)
+    with pytest.raises(RuntimeError):
+        xpy.substitute(es, rs)
+    es.clear()
+    rs.clear()
+    es.append(x)
+    rs.append(y)
+    with pytest.raises(RuntimeError):
+        tnull.substitute(es, rs)
+    es.append(tnull)
+    rs.append(one)
+    with pytest.raises(RuntimeError):
+        xpx.substitute(es, rs)
+
+
+def test_term_compare(solver):
+    t1 = solver.mkInteger(1)
+    t2 = solver.mkTerm(kinds.Plus, solver.mkInteger(2), solver.mkInteger(2))
+    t3 = solver.mkTerm(kinds.Plus, solver.mkInteger(2), solver.mkInteger(2))
+    assert t2 >= t3
+    assert t2 <= t3
+    assert (t1 > t2) != (t1 < t2)
+    assert (t1 > t2 or t1 == t2) == (t1 >= t2)
+
+
+def test_term_children(solver):
+    # simple term 2+3
+    two = solver.mkInteger(2)
+    t1 = solver.mkTerm(kinds.Plus, two, solver.mkInteger(3))
+    assert t1[0] == two
+    assert t1.getNumChildren() == 2
+    tnull = Term(solver)
+    with pytest.raises(RuntimeError):
+        tnull.getNumChildren()
+
+    # apply term f(2)
+    intSort = solver.getIntegerSort()
+    fsort = solver.mkFunctionSort(intSort, intSort)
+    f = solver.mkConst(fsort, "f")
+    t2 = solver.mkTerm(kinds.ApplyUf, f, two)
+    # due to our higher-order view of terms, we treat f as a child of kinds.ApplyUf
+    assert t2.getNumChildren() == 2
+    assert t2[0] == f
+    assert t2[1] == two
+    with pytest.raises(RuntimeError):
+        tnull[0]
+
+
+def test_get_const_array_base(solver):
+    intsort = solver.getIntegerSort()
+    arrsort = solver.mkArraySort(intsort, intsort)
+    one = solver.mkInteger(1)
+    constarr = solver.mkConstArray(arrsort, one)
+
+    assert constarr.isConstArray()
+    assert one == constarr.getConstArrayBase()
+
+
+def test_get_abstract_value(solver):
+    v1 = solver.mkAbstractValue(1)
+    v2 = solver.mkAbstractValue("15")
+    v3 = solver.mkAbstractValue("18446744073709551617")
+
+    assert v1.isAbstractValue()
+    assert v2.isAbstractValue()
+    assert v3.isAbstractValue()
+    assert "1" == v1.getAbstractValue()
+    assert "15" == v2.getAbstractValue()
+    assert "18446744073709551617" == v3.getAbstractValue()
+
+
+def test_get_tuple(solver):
+    s1 = solver.getIntegerSort()
+    s2 = solver.getRealSort()
+    s3 = solver.getStringSort()
+
+    t1 = solver.mkInteger(15)
+    t2 = solver.mkReal(17, 25)
+    t3 = solver.mkString("abc")
+
+    tup = solver.mkTuple([s1, s2, s3], [t1, t2, t3])
+
+    assert tup.isTupleValue()
+    assert [t1, t2, t3] == tup.getTupleValue()
+
+
+def test_get_set(solver):
+    s = solver.mkSetSort(solver.getIntegerSort())
+
+    i1 = solver.mkInteger(5)
+    i2 = solver.mkInteger(7)
+
+    s1 = solver.mkEmptySet(s)
+    s2 = solver.mkTerm(kinds.SetSingleton, i1)
+    s3 = solver.mkTerm(kinds.SetSingleton, i1)
+    s4 = solver.mkTerm(kinds.SetSingleton, i2)
+    s5 = solver.mkTerm(
+            kinds.SetUnion, s2, solver.mkTerm(kinds.SetUnion, s3, s4))
+
+    assert s1.isSetValue()
+    assert s2.isSetValue()
+    assert s3.isSetValue()
+    assert s4.isSetValue()
+    assert not s5.isSetValue()
+    s5 = solver.simplify(s5)
+    assert s5.isSetValue()
+
+    assert set([]) == s1.getSetValue()
+    assert set([i1]) == s2.getSetValue()
+    assert set([i1]) == s3.getSetValue()
+    assert set([i2]) == s4.getSetValue()
+    assert set([i1, i2]) == s5.getSetValue()
+
+
+def test_get_sequence(solver):
+    s = solver.mkSequenceSort(solver.getIntegerSort())
+
+    i1 = solver.mkInteger(5)
+    i2 = solver.mkInteger(7)
+
+    s1 = solver.mkEmptySequence(s)
+    s2 = solver.mkTerm(kinds.SeqUnit, i1)
+    s3 = solver.mkTerm(kinds.SeqUnit, i1)
+    s4 = solver.mkTerm(kinds.SeqUnit, i2)
+    s5 = solver.mkTerm(kinds.SeqConcat, s2,
+                       solver.mkTerm(kinds.SeqConcat, s3, s4))
+
+    assert s1.isSequenceValue()
+    assert not s2.isSequenceValue()
+    assert not s3.isSequenceValue()
+    assert not s4.isSequenceValue()
+    assert not s5.isSequenceValue()
+
+    s2 = solver.simplify(s2)
+    s3 = solver.simplify(s3)
+    s4 = solver.simplify(s4)
+    s5 = solver.simplify(s5)
+
+    assert [] == s1.getSequenceValue()
+    assert [i1] == s2.getSequenceValue()
+    assert [i1] == s3.getSequenceValue()
+    assert [i2] == s4.getSequenceValue()
+    assert [i1, i1, i2] == s5.getSequenceValue()
+
+
+def test_get_uninterpreted_const(solver):
+    s = solver.mkUninterpretedSort("test")
+    t1 = solver.mkUninterpretedConst(s, 3)
+    t2 = solver.mkUninterpretedConst(s, 5)
+
+    assert t1.isUninterpretedValue()
+    assert t2.isUninterpretedValue()
+
+    assert (s, 3) == t1.getUninterpretedValue()
+    assert (s, 5) == t2.getUninterpretedValue()
+
+
+def test_get_floating_point(solver):
+    bvval = solver.mkBitVector(16, "0000110000000011", 2)
+    fp = solver.mkFloatingPoint(5, 11, bvval)
+
+    assert fp.isFloatingPointValue()
+    assert not fp.isFloatingPointPosZero()
+    assert not fp.isFloatingPointNegZero()
+    assert not fp.isFloatingPointPosInf()
+    assert not fp.isFloatingPointNegInf()
+    assert not fp.isFloatingPointNaN()
+    assert (5, 11, bvval) == fp.getFloatingPointValue()
+
+    assert solver.mkPosZero(5, 11).isFloatingPointPosZero()
+    assert solver.mkNegZero(5, 11).isFloatingPointNegZero()
+    assert solver.mkPosInf(5, 11).isFloatingPointPosInf()
+    assert solver.mkNegInf(5, 11).isFloatingPointNegInf()
+    assert solver.mkNaN(5, 11).isFloatingPointNaN()
+
+
+def test_is_integer(solver):
+    int1 = solver.mkInteger("-18446744073709551616")
+    int2 = solver.mkInteger("-18446744073709551615")
+    int3 = solver.mkInteger("-4294967296")
+    int4 = solver.mkInteger("-4294967295")
+    int5 = solver.mkInteger("-10")
+    int6 = solver.mkInteger("0")
+    int7 = solver.mkInteger("10")
+    int8 = solver.mkInteger("4294967295")
+    int9 = solver.mkInteger("4294967296")
+    int10 = solver.mkInteger("18446744073709551615")
+    int11 = solver.mkInteger("18446744073709551616")
+    int12 = solver.mkInteger("-0")
+
+    with pytest.raises(RuntimeError):
+        solver.mkInteger("")
+    with pytest.raises(RuntimeError):
+        solver.mkInteger("-")
+    with pytest.raises(RuntimeError):
+        solver.mkInteger("-1-")
+    with pytest.raises(RuntimeError):
+        solver.mkInteger("0.0")
+    with pytest.raises(RuntimeError):
+        solver.mkInteger("-0.1")
+    with pytest.raises(RuntimeError):
+        solver.mkInteger("012")
+    with pytest.raises(RuntimeError):
+        solver.mkInteger("0000")
+    with pytest.raises(RuntimeError):
+        solver.mkInteger("-01")
+    with pytest.raises(RuntimeError):
+        solver.mkInteger("-00")
+
+    assert int1.isIntegerValue()
+    assert int2.isIntegerValue()
+    assert int3.isIntegerValue()
+    assert int4.isIntegerValue()
+    assert int5.isIntegerValue()
+    assert int6.isIntegerValue()
+    assert int7.isIntegerValue()
+    assert int8.isIntegerValue()
+    assert int9.isIntegerValue()
+    assert int10.isIntegerValue()
+    assert int11.isIntegerValue()
+
+    assert int1.getIntegerValue() == -18446744073709551616
+    assert int2.getIntegerValue() == -18446744073709551615
+    assert int3.getIntegerValue() == -4294967296
+    assert int4.getIntegerValue() == -4294967295
+    assert int5.getIntegerValue() == -10
+    assert int6.getIntegerValue() == 0
+    assert int7.getIntegerValue() == 10
+    assert int8.getIntegerValue() == 4294967295
+    assert int9.getIntegerValue() == 4294967296
+    assert int10.getIntegerValue() == 18446744073709551615
+    assert int11.getIntegerValue() == 18446744073709551616
+
+
+def test_get_string(solver):
+    s1 = solver.mkString("abcde")
+    assert s1.isStringValue()
+    assert s1.getStringValue() == str("abcde")
+
+
+def test_get_real(solver):
+    real1 = solver.mkReal("0")
+    real2 = solver.mkReal(".0")
+    real3 = solver.mkReal("-17")
+    real4 = solver.mkReal("-3/5")
+    real5 = solver.mkReal("12.7")
+    real6 = solver.mkReal("1/4294967297")
+    real7 = solver.mkReal("4294967297")
+    real8 = solver.mkReal("1/18446744073709551617")
+    real9 = solver.mkReal("18446744073709551617")
+
+    assert real1.isRealValue()
+    assert real2.isRealValue()
+    assert real3.isRealValue()
+    assert real4.isRealValue()
+    assert real5.isRealValue()
+    assert real6.isRealValue()
+    assert real7.isRealValue()
+    assert real8.isRealValue()
+    assert real9.isRealValue()
+
+    assert 0 == real1.getRealValue()
+    assert 0 == real2.getRealValue()
+    assert -17 == real3.getRealValue()
+    assert Fraction(-3, 5) == real4.getRealValue()
+    assert Fraction(127, 10) == real5.getRealValue()
+    assert Fraction(1, 4294967297) == real6.getRealValue()
+    assert 4294967297 == real7.getRealValue()
+    assert Fraction(1, 18446744073709551617) == real8.getRealValue()
+    assert Fraction(18446744073709551617, 1) == real9.getRealValue()
+
+    # Check denominator too large for float
+    num = 1
+    den = 2 ** 64 + 1
+    real_big = solver.mkReal(num, den)
+    assert real_big.isRealValue()
+    assert Fraction(num, den) == real_big.getRealValue()
+
+    # Check that we're treating floats as decimal aproximations rather than
+    # IEEE-754-specified values.
+    real_decimal = solver.mkReal(0.3)
+    assert real_decimal.isRealValue()
+    assert Fraction("0.3") == real_decimal.getRealValue()
+    assert Fraction(0.3) == Fraction(5404319552844595, 18014398509481984)
+    assert Fraction(0.3) != real_decimal.getRealValue()
+
+
+def test_get_boolean(solver):
+    b1 = solver.mkBoolean(True)
+    b2 = solver.mkBoolean(False)
+
+    assert b1.isBooleanValue()
+    assert b2.isBooleanValue()
+    assert b1.getBooleanValue()
+    assert not b2.getBooleanValue()
+
+
+def test_get_bit_vector(solver):
+    b1 = solver.mkBitVector(8, 15)
+    b2 = solver.mkBitVector(8, "00001111", 2)
+    b3 = solver.mkBitVector(8, "15", 10)
+    b4 = solver.mkBitVector(8, "0f", 16)
+    b5 = solver.mkBitVector(9, "00001111", 2);
+    b6 = solver.mkBitVector(9, "15", 10);
+    b7 = solver.mkBitVector(9, "0f", 16);
+
+    assert b1.isBitVectorValue()
+    assert b2.isBitVectorValue()
+    assert b3.isBitVectorValue()
+    assert b4.isBitVectorValue()
+    assert b5.isBitVectorValue()
+    assert b6.isBitVectorValue()
+    assert b7.isBitVectorValue()
+
+    assert "00001111" == b1.getBitVectorValue(2)
+    assert "15" == b1.getBitVectorValue(10)
+    assert "f" == b1.getBitVectorValue(16)
+    assert "00001111" == b2.getBitVectorValue(2)
+    assert "15" == b2.getBitVectorValue(10)
+    assert "f" == b2.getBitVectorValue(16)
+    assert "00001111" == b3.getBitVectorValue(2)
+    assert "15" == b3.getBitVectorValue(10)
+    assert "f" == b3.getBitVectorValue(16)
+    assert "00001111" == b4.getBitVectorValue(2)
+    assert "15" == b4.getBitVectorValue(10)
+    assert "f" == b4.getBitVectorValue(16)
+    assert "000001111" == b5.getBitVectorValue(2)
+    assert "15" == b5.getBitVectorValue(10)
+    assert "f" == b5.getBitVectorValue(16)
+    assert "000001111" == b6.getBitVectorValue(2)
+    assert "15" == b6.getBitVectorValue(10)
+    assert "f" == b6.getBitVectorValue(16)
+    assert "000001111" == b7.getBitVectorValue(2)
+    assert "15" == b7.getBitVectorValue(10)
+    assert "f" == b7.getBitVectorValue(16)
+
+
+def test_const_array(solver):
+    intsort = solver.getIntegerSort()
+    arrsort = solver.mkArraySort(intsort, intsort)
+    a = solver.mkConst(arrsort, "a")
+    one = solver.mkInteger(1)
+    constarr = solver.mkConstArray(arrsort, one)
+
+    assert constarr.getKind() == kinds.ConstArray
+    assert constarr.getConstArrayBase() == one
+    with pytest.raises(RuntimeError):
+        a.getConstArrayBase()
+
+    arrsort = solver.mkArraySort(solver.getRealSort(), solver.getRealSort())
+    zero_array = solver.mkConstArray(arrsort, solver.mkReal(0))
+    stores = solver.mkTerm(kinds.Store, zero_array, solver.mkReal(1),
+                           solver.mkReal(2))
+    stores = solver.mkTerm(kinds.Store, stores, solver.mkReal(2),
+                           solver.mkReal(3))
+    stores = solver.mkTerm(kinds.Store, stores, solver.mkReal(4),
+                           solver.mkReal(5))
+
+
+def test_const_sequence_elements(solver):
+    realsort = solver.getRealSort()
+    seqsort = solver.mkSequenceSort(realsort)
+    s = solver.mkEmptySequence(seqsort)
+
+    assert s.getKind() == kinds.ConstSequence
+    # empty sequence has zero elements
+    cs = s.getSequenceValue()
+    assert len(cs) == 0
+
+    # A seq.unit app is not a constant sequence (regardless of whether it is
+    # applied to a constant).
+    su = solver.mkTerm(kinds.SeqUnit, solver.mkReal(1))
+    with pytest.raises(RuntimeError):
+        su.getSequenceValue()
+
+
+def test_term_scoped_to_string(solver):
+    intsort = solver.getIntegerSort()
+    x = solver.mkConst(intsort, "x")
+    assert str(x) == "x"
+    solver2 = pycvc5.Solver()
+    assert str(x) == "x"
diff --git a/test/unit/api/python/test_to_python_obj.py b/test/unit/api/python/test_to_python_obj.py
new file mode 100644 (file)
index 0000000..bb30fae
--- /dev/null
@@ -0,0 +1,118 @@
+###############################################################################
+# Top contributors (to current version):
+#   Makai Mann, Andres Noetzli, Mudathir Mohamed
+#
+# This file is part of the cvc5 project.
+#
+# Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
+# in the top-level source directory and their institutional affiliations.
+# All rights reserved.  See the file COPYING in the top-level source
+# directory for licensing information.
+# #############################################################################
+##
+
+from fractions import Fraction
+import pytest
+
+import pycvc5
+from pycvc5 import kinds
+
+
+def testGetBool():
+    solver = pycvc5.Solver()
+    t = solver.mkTrue()
+    f = solver.mkFalse()
+    assert t.toPythonObj() is True
+    assert f.toPythonObj() is False
+
+
+def testGetInt():
+    solver = pycvc5.Solver()
+    two = solver.mkInteger(2)
+    assert two.toPythonObj() == 2
+
+
+def testGetReal():
+    solver = pycvc5.Solver()
+    half = solver.mkReal("1/2")
+    assert half.toPythonObj() == Fraction(1, 2)
+
+    neg34 = solver.mkReal("-3/4")
+    assert neg34.toPythonObj() == Fraction(-3, 4)
+
+    neg1 = solver.mkInteger("-1")
+    assert neg1.toPythonObj() == -1
+
+
+def testGetBV():
+    solver = pycvc5.Solver()
+    three = solver.mkBitVector(8, 3)
+    assert three.toPythonObj() == 3
+
+
+def testGetArray():
+    solver = pycvc5.Solver()
+    arrsort = solver.mkArraySort(solver.getRealSort(), solver.getRealSort())
+    zero_array = solver.mkConstArray(arrsort, solver.mkInteger(0))
+    stores = solver.mkTerm(kinds.Store, zero_array, solver.mkInteger(1), solver.mkInteger(2))
+    stores = solver.mkTerm(kinds.Store, stores, solver.mkInteger(2), solver.mkInteger(3))
+    stores = solver.mkTerm(kinds.Store, stores, solver.mkInteger(4), solver.mkInteger(5))
+
+    array_dict = stores.toPythonObj()
+
+    assert array_dict[1] == 2
+    assert array_dict[2] == 3
+    assert array_dict[4] == 5
+    # an index that wasn't stored at should give zero
+    assert array_dict[8] == 0
+
+
+def testGetSymbol():
+    solver = pycvc5.Solver()
+    solver.mkConst(solver.getBooleanSort(), "x")
+
+
+def testGetString():
+    solver = pycvc5.Solver()
+
+    s1 = '"test\n"😃\\u{a}'
+    t1 = solver.mkString(s1)
+    assert s1 == t1.toPythonObj()
+
+    s2 = '❤️cvc5❤️'
+    t2 = solver.mkString(s2)
+    assert s2 == t2.toPythonObj()
+
+
+def testGetValueInt():
+    solver = pycvc5.Solver()
+    solver.setOption("produce-models", "true")
+
+    intsort = solver.getIntegerSort()
+    x = solver.mkConst(intsort, "x")
+    solver.assertFormula(solver.mkTerm(kinds.Equal, x, solver.mkInteger(6)))
+
+    r = solver.checkSat()
+    assert r.isSat()
+
+    xval = solver.getValue(x)
+    assert xval.toPythonObj() == 6
+
+
+def testGetValueReal():
+    solver = pycvc5.Solver()
+    solver.setOption("produce-models", "true")
+
+    realsort = solver.getRealSort()
+    x = solver.mkConst(realsort, "x")
+    y = solver.mkConst(realsort, "y")
+    solver.assertFormula(solver.mkTerm(kinds.Equal, x, solver.mkReal("6")))
+    solver.assertFormula(solver.mkTerm(kinds.Equal, y, solver.mkReal("8.33")))
+
+    r = solver.checkSat()
+    assert r.isSat()
+
+    xval = solver.getValue(x)
+    yval = solver.getValue(y)
+    assert xval.toPythonObj() == Fraction("6")
+    assert yval.toPythonObj() == Fraction("8.33")
diff --git a/test/unit/api/result_black.cpp b/test/unit/api/result_black.cpp
deleted file mode 100644 (file)
index 9bf6b84..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-/******************************************************************************
- * Top contributors (to current version):
- *   Aina Niemetz
- *
- * This file is part of the cvc5 project.
- *
- * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
- * in the top-level source directory and their institutional affiliations.
- * All rights reserved.  See the file COPYING in the top-level source
- * directory for licensing information.
- * ****************************************************************************
- *
- * Black box testing of the Result class
- */
-
-#include "test_api.h"
-
-namespace cvc5 {
-
-using namespace api;
-
-namespace test {
-
-class TestApiBlackResult : public TestApi
-{
-};
-
-TEST_F(TestApiBlackResult, isNull)
-{
-  cvc5::api::Result res_null;
-  ASSERT_TRUE(res_null.isNull());
-  ASSERT_FALSE(res_null.isSat());
-  ASSERT_FALSE(res_null.isUnsat());
-  ASSERT_FALSE(res_null.isSatUnknown());
-  ASSERT_FALSE(res_null.isEntailed());
-  ASSERT_FALSE(res_null.isNotEntailed());
-  ASSERT_FALSE(res_null.isEntailmentUnknown());
-  Sort u_sort = d_solver.mkUninterpretedSort("u");
-  Term x = d_solver.mkVar(u_sort, "x");
-  d_solver.assertFormula(x.eqTerm(x));
-  cvc5::api::Result res = d_solver.checkSat();
-  ASSERT_FALSE(res.isNull());
-}
-
-TEST_F(TestApiBlackResult, eq)
-{
-  Sort u_sort = d_solver.mkUninterpretedSort("u");
-  Term x = d_solver.mkVar(u_sort, "x");
-  d_solver.assertFormula(x.eqTerm(x));
-  cvc5::api::Result res;
-  cvc5::api::Result res2 = d_solver.checkSat();
-  cvc5::api::Result res3 = d_solver.checkSat();
-  res = res2;
-  ASSERT_EQ(res, res2);
-  ASSERT_EQ(res3, res2);
-}
-
-TEST_F(TestApiBlackResult, isSat)
-{
-  Sort u_sort = d_solver.mkUninterpretedSort("u");
-  Term x = d_solver.mkVar(u_sort, "x");
-  d_solver.assertFormula(x.eqTerm(x));
-  cvc5::api::Result res = d_solver.checkSat();
-  ASSERT_TRUE(res.isSat());
-  ASSERT_FALSE(res.isSatUnknown());
-}
-
-TEST_F(TestApiBlackResult, isUnsat)
-{
-  Sort u_sort = d_solver.mkUninterpretedSort("u");
-  Term x = d_solver.mkVar(u_sort, "x");
-  d_solver.assertFormula(x.eqTerm(x).notTerm());
-  cvc5::api::Result res = d_solver.checkSat();
-  ASSERT_TRUE(res.isUnsat());
-  ASSERT_FALSE(res.isSatUnknown());
-}
-
-TEST_F(TestApiBlackResult, isSatUnknown)
-{
-  d_solver.setLogic("QF_NIA");
-  d_solver.setOption("incremental", "false");
-  d_solver.setOption("solve-int-as-bv", "32");
-  Sort int_sort = d_solver.getIntegerSort();
-  Term x = d_solver.mkVar(int_sort, "x");
-  d_solver.assertFormula(x.eqTerm(x).notTerm());
-  cvc5::api::Result res = d_solver.checkSat();
-  ASSERT_FALSE(res.isSat());
-  ASSERT_TRUE(res.isSatUnknown());
-}
-
-TEST_F(TestApiBlackResult, isEntailed)
-{
-  d_solver.setOption("incremental", "true");
-  Sort u_sort = d_solver.mkUninterpretedSort("u");
-  Term x = d_solver.mkConst(u_sort, "x");
-  Term y = d_solver.mkConst(u_sort, "y");
-  Term a = x.eqTerm(y).notTerm();
-  Term b = x.eqTerm(y);
-  d_solver.assertFormula(a);
-  cvc5::api::Result entailed = d_solver.checkEntailed(a);
-  ASSERT_TRUE(entailed.isEntailed());
-  ASSERT_FALSE(entailed.isEntailmentUnknown());
-  cvc5::api::Result not_entailed = d_solver.checkEntailed(b);
-  ASSERT_TRUE(not_entailed.isNotEntailed());
-  ASSERT_FALSE(not_entailed.isEntailmentUnknown());
-}
-
-TEST_F(TestApiBlackResult, isEntailmentUnknown)
-{
-  d_solver.setLogic("QF_NIA");
-  d_solver.setOption("incremental", "false");
-  d_solver.setOption("solve-int-as-bv", "32");
-  Sort int_sort = d_solver.getIntegerSort();
-  Term x = d_solver.mkVar(int_sort, "x");
-  d_solver.assertFormula(x.eqTerm(x).notTerm());
-  cvc5::api::Result res = d_solver.checkEntailed(x.eqTerm(x));
-  ASSERT_FALSE(res.isEntailed());
-  ASSERT_TRUE(res.isEntailmentUnknown());
-  ASSERT_EQ(res.getUnknownExplanation(), api::Result::UNKNOWN_REASON);
-}
-}  // namespace test
-}  // namespace cvc5
diff --git a/test/unit/api/solver_black.cpp b/test/unit/api/solver_black.cpp
deleted file mode 100644 (file)
index 79a4aa6..0000000
+++ /dev/null
@@ -1,2574 +0,0 @@
-/******************************************************************************
- * Top contributors (to current version):
- *   Aina Niemetz, Mudathir Mohamed, Andrew Reynolds
- *
- * This file is part of the cvc5 project.
- *
- * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
- * in the top-level source directory and their institutional affiliations.
- * All rights reserved.  See the file COPYING in the top-level source
- * directory for licensing information.
- * ****************************************************************************
- *
- * Black box testing of the Solver class of the  C++ API.
- */
-
-#include <algorithm>
-
-#include "test_api.h"
-#include "base/output.h"
-
-namespace cvc5 {
-
-using namespace api;
-
-namespace test {
-
-class TestApiBlackSolver : public TestApi
-{
-};
-
-TEST_F(TestApiBlackSolver, recoverableException)
-{
-  d_solver.setOption("produce-models", "true");
-  Term x = d_solver.mkConst(d_solver.getBooleanSort(), "x");
-  d_solver.assertFormula(x.eqTerm(x).notTerm());
-  ASSERT_THROW(d_solver.getValue(x), CVC5ApiRecoverableException);
-}
-
-TEST_F(TestApiBlackSolver, supportsFloatingPoint)
-{
-  ASSERT_NO_THROW(d_solver.mkRoundingMode(ROUND_NEAREST_TIES_TO_EVEN));
-}
-
-TEST_F(TestApiBlackSolver, getBooleanSort)
-{
-  ASSERT_NO_THROW(d_solver.getBooleanSort());
-}
-
-TEST_F(TestApiBlackSolver, getIntegerSort)
-{
-  ASSERT_NO_THROW(d_solver.getIntegerSort());
-}
-
-TEST_F(TestApiBlackSolver, getNullSort)
-{
-  ASSERT_NO_THROW(d_solver.getNullSort());
-}
-
-TEST_F(TestApiBlackSolver, getRealSort)
-{
-  ASSERT_NO_THROW(d_solver.getRealSort());
-}
-
-TEST_F(TestApiBlackSolver, getRegExpSort)
-{
-  ASSERT_NO_THROW(d_solver.getRegExpSort());
-}
-
-TEST_F(TestApiBlackSolver, getStringSort)
-{
-  ASSERT_NO_THROW(d_solver.getStringSort());
-}
-
-TEST_F(TestApiBlackSolver, getRoundingModeSort)
-{
-  ASSERT_NO_THROW(d_solver.getRoundingModeSort());
-}
-
-TEST_F(TestApiBlackSolver, mkArraySort)
-{
-  Sort boolSort = d_solver.getBooleanSort();
-  Sort intSort = d_solver.getIntegerSort();
-  Sort realSort = d_solver.getRealSort();
-  Sort bvSort = d_solver.mkBitVectorSort(32);
-  ASSERT_NO_THROW(d_solver.mkArraySort(boolSort, boolSort));
-  ASSERT_NO_THROW(d_solver.mkArraySort(intSort, intSort));
-  ASSERT_NO_THROW(d_solver.mkArraySort(realSort, realSort));
-  ASSERT_NO_THROW(d_solver.mkArraySort(bvSort, bvSort));
-  ASSERT_NO_THROW(d_solver.mkArraySort(boolSort, intSort));
-  ASSERT_NO_THROW(d_solver.mkArraySort(realSort, bvSort));
-
-  Sort fpSort = d_solver.mkFloatingPointSort(3, 5);
-  ASSERT_NO_THROW(d_solver.mkArraySort(fpSort, fpSort));
-  ASSERT_NO_THROW(d_solver.mkArraySort(bvSort, fpSort));
-
-  Solver slv;
-  ASSERT_THROW(slv.mkArraySort(boolSort, boolSort), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, mkBitVectorSort)
-{
-  ASSERT_NO_THROW(d_solver.mkBitVectorSort(32));
-  ASSERT_THROW(d_solver.mkBitVectorSort(0), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, mkFloatingPointSort)
-{
-  ASSERT_NO_THROW(d_solver.mkFloatingPointSort(4, 8));
-  ASSERT_THROW(d_solver.mkFloatingPointSort(0, 8), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkFloatingPointSort(4, 0), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, mkDatatypeSort)
-{
-  DatatypeDecl dtypeSpec = d_solver.mkDatatypeDecl("list");
-  DatatypeConstructorDecl cons = d_solver.mkDatatypeConstructorDecl("cons");
-  cons.addSelector("head", d_solver.getIntegerSort());
-  dtypeSpec.addConstructor(cons);
-  DatatypeConstructorDecl nil = d_solver.mkDatatypeConstructorDecl("nil");
-  dtypeSpec.addConstructor(nil);
-  ASSERT_NO_THROW(d_solver.mkDatatypeSort(dtypeSpec));
-
-  Solver slv;
-  ASSERT_THROW(slv.mkDatatypeSort(dtypeSpec), CVC5ApiException);
-
-  DatatypeDecl throwsDtypeSpec = d_solver.mkDatatypeDecl("list");
-  ASSERT_THROW(d_solver.mkDatatypeSort(throwsDtypeSpec), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, mkDatatypeSorts)
-{
-  Solver slv;
-
-  DatatypeDecl dtypeSpec1 = d_solver.mkDatatypeDecl("list1");
-  DatatypeConstructorDecl cons1 = d_solver.mkDatatypeConstructorDecl("cons1");
-  cons1.addSelector("head1", d_solver.getIntegerSort());
-  dtypeSpec1.addConstructor(cons1);
-  DatatypeConstructorDecl nil1 = d_solver.mkDatatypeConstructorDecl("nil1");
-  dtypeSpec1.addConstructor(nil1);
-  DatatypeDecl dtypeSpec2 = d_solver.mkDatatypeDecl("list2");
-  DatatypeConstructorDecl cons2 = d_solver.mkDatatypeConstructorDecl("cons2");
-  cons2.addSelector("head2", d_solver.getIntegerSort());
-  dtypeSpec2.addConstructor(cons2);
-  DatatypeConstructorDecl nil2 = d_solver.mkDatatypeConstructorDecl("nil2");
-  dtypeSpec2.addConstructor(nil2);
-  std::vector<DatatypeDecl> decls = {dtypeSpec1, dtypeSpec2};
-  ASSERT_NO_THROW(d_solver.mkDatatypeSorts(decls));
-
-  ASSERT_THROW(slv.mkDatatypeSorts(decls), CVC5ApiException);
-
-  DatatypeDecl throwsDtypeSpec = d_solver.mkDatatypeDecl("list");
-  std::vector<DatatypeDecl> throwsDecls = {throwsDtypeSpec};
-  ASSERT_THROW(d_solver.mkDatatypeSorts(throwsDecls), CVC5ApiException);
-
-  /* with unresolved sorts */
-  Sort unresList = d_solver.mkUninterpretedSort("ulist");
-  std::set<Sort> unresSorts = {unresList};
-  DatatypeDecl ulist = d_solver.mkDatatypeDecl("ulist");
-  DatatypeConstructorDecl ucons = d_solver.mkDatatypeConstructorDecl("ucons");
-  ucons.addSelector("car", unresList);
-  ucons.addSelector("cdr", unresList);
-  ulist.addConstructor(ucons);
-  DatatypeConstructorDecl unil = d_solver.mkDatatypeConstructorDecl("unil");
-  ulist.addConstructor(unil);
-  std::vector<DatatypeDecl> udecls = {ulist};
-  ASSERT_NO_THROW(d_solver.mkDatatypeSorts(udecls, unresSorts));
-
-  ASSERT_THROW(slv.mkDatatypeSorts(udecls, unresSorts), CVC5ApiException);
-
-  /* Note: More tests are in datatype_api_black. */
-}
-
-TEST_F(TestApiBlackSolver, mkFunctionSort)
-{
-  ASSERT_NO_THROW(d_solver.mkFunctionSort(d_solver.mkUninterpretedSort("u"),
-                                          d_solver.getIntegerSort()));
-  Sort funSort = d_solver.mkFunctionSort(d_solver.mkUninterpretedSort("u"),
-                                         d_solver.getIntegerSort());
-  // function arguments are allowed
-  ASSERT_NO_THROW(d_solver.mkFunctionSort(funSort, d_solver.getIntegerSort()));
-  // non-first-class arguments are not allowed
-  Sort reSort = d_solver.getRegExpSort();
-  ASSERT_THROW(d_solver.mkFunctionSort(reSort, d_solver.getIntegerSort()),
-               CVC5ApiException);
-  ASSERT_THROW(d_solver.mkFunctionSort(d_solver.getIntegerSort(), funSort),
-               CVC5ApiException);
-  ASSERT_NO_THROW(d_solver.mkFunctionSort(
-      {d_solver.mkUninterpretedSort("u"), d_solver.getIntegerSort()},
-      d_solver.getIntegerSort()));
-  Sort funSort2 = d_solver.mkFunctionSort(d_solver.mkUninterpretedSort("u"),
-                                          d_solver.getIntegerSort());
-  // function arguments are allowed
-  ASSERT_NO_THROW(
-      d_solver.mkFunctionSort({funSort2, d_solver.mkUninterpretedSort("u")},
-                              d_solver.getIntegerSort()));
-  ASSERT_THROW(d_solver.mkFunctionSort({d_solver.getIntegerSort(),
-                                        d_solver.mkUninterpretedSort("u")},
-                                       funSort2),
-               CVC5ApiException);
-
-  Solver slv;
-  ASSERT_THROW(slv.mkFunctionSort(d_solver.mkUninterpretedSort("u"),
-                                  d_solver.getIntegerSort()),
-               CVC5ApiException);
-  ASSERT_THROW(slv.mkFunctionSort(slv.mkUninterpretedSort("u"),
-                                  d_solver.getIntegerSort()),
-               CVC5ApiException);
-  std::vector<Sort> sorts1 = {d_solver.getBooleanSort(),
-                              slv.getIntegerSort(),
-                              d_solver.getIntegerSort()};
-  std::vector<Sort> sorts2 = {slv.getBooleanSort(), slv.getIntegerSort()};
-  ASSERT_NO_THROW(slv.mkFunctionSort(sorts2, slv.getIntegerSort()));
-  ASSERT_THROW(slv.mkFunctionSort(sorts1, slv.getIntegerSort()),
-               CVC5ApiException);
-  ASSERT_THROW(slv.mkFunctionSort(sorts2, d_solver.getIntegerSort()),
-               CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, mkParamSort)
-{
-  ASSERT_NO_THROW(d_solver.mkParamSort("T"));
-  ASSERT_NO_THROW(d_solver.mkParamSort(""));
-}
-
-TEST_F(TestApiBlackSolver, mkPredicateSort)
-{
-  ASSERT_NO_THROW(d_solver.mkPredicateSort({d_solver.getIntegerSort()}));
-  ASSERT_THROW(d_solver.mkPredicateSort({}), CVC5ApiException);
-  Sort funSort = d_solver.mkFunctionSort(d_solver.mkUninterpretedSort("u"),
-                                         d_solver.getIntegerSort());
-  // functions as arguments are allowed
-  ASSERT_NO_THROW(
-      d_solver.mkPredicateSort({d_solver.getIntegerSort(), funSort}));
-
-  Solver slv;
-  ASSERT_THROW(slv.mkPredicateSort({d_solver.getIntegerSort()}),
-               CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, mkRecordSort)
-{
-  std::vector<std::pair<std::string, Sort>> fields = {
-      std::make_pair("b", d_solver.getBooleanSort()),
-      std::make_pair("bv", d_solver.mkBitVectorSort(8)),
-      std::make_pair("i", d_solver.getIntegerSort())};
-  std::vector<std::pair<std::string, Sort>> empty;
-  ASSERT_NO_THROW(d_solver.mkRecordSort(fields));
-  ASSERT_NO_THROW(d_solver.mkRecordSort(empty));
-  Sort recSort = d_solver.mkRecordSort(fields);
-  ASSERT_NO_THROW(recSort.getDatatype());
-
-  Solver slv;
-  ASSERT_THROW(slv.mkRecordSort(fields), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, mkSetSort)
-{
-  ASSERT_NO_THROW(d_solver.mkSetSort(d_solver.getBooleanSort()));
-  ASSERT_NO_THROW(d_solver.mkSetSort(d_solver.getIntegerSort()));
-  ASSERT_NO_THROW(d_solver.mkSetSort(d_solver.mkBitVectorSort(4)));
-  Solver slv;
-  ASSERT_THROW(slv.mkSetSort(d_solver.mkBitVectorSort(4)), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, mkBagSort)
-{
-  ASSERT_NO_THROW(d_solver.mkBagSort(d_solver.getBooleanSort()));
-  ASSERT_NO_THROW(d_solver.mkBagSort(d_solver.getIntegerSort()));
-  ASSERT_NO_THROW(d_solver.mkBagSort(d_solver.mkBitVectorSort(4)));
-  Solver slv;
-  ASSERT_THROW(slv.mkBagSort(d_solver.mkBitVectorSort(4)), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, mkSequenceSort)
-{
-  ASSERT_NO_THROW(d_solver.mkSequenceSort(d_solver.getBooleanSort()));
-  ASSERT_NO_THROW(d_solver.mkSequenceSort(
-      d_solver.mkSequenceSort(d_solver.getIntegerSort())));
-  Solver slv;
-  ASSERT_THROW(slv.mkSequenceSort(d_solver.getIntegerSort()), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, mkUninterpretedSort)
-{
-  ASSERT_NO_THROW(d_solver.mkUninterpretedSort("u"));
-  ASSERT_NO_THROW(d_solver.mkUninterpretedSort(""));
-}
-
-TEST_F(TestApiBlackSolver, mkSortConstructorSort)
-{
-  ASSERT_NO_THROW(d_solver.mkSortConstructorSort("s", 2));
-  ASSERT_NO_THROW(d_solver.mkSortConstructorSort("", 2));
-  ASSERT_THROW(d_solver.mkSortConstructorSort("", 0), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, mkTupleSort)
-{
-  ASSERT_NO_THROW(d_solver.mkTupleSort({d_solver.getIntegerSort()}));
-  Sort funSort = d_solver.mkFunctionSort(d_solver.mkUninterpretedSort("u"),
-                                         d_solver.getIntegerSort());
-  ASSERT_THROW(d_solver.mkTupleSort({d_solver.getIntegerSort(), funSort}),
-               CVC5ApiException);
-
-  Solver slv;
-  ASSERT_THROW(slv.mkTupleSort({d_solver.getIntegerSort()}), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, mkBitVector)
-{
-  ASSERT_NO_THROW(d_solver.mkBitVector(8, 2));
-  ASSERT_NO_THROW(d_solver.mkBitVector(32, 2));
-  ASSERT_NO_THROW(d_solver.mkBitVector(8, "-1111111", 2));
-  ASSERT_NO_THROW(d_solver.mkBitVector(8, "0101", 2));
-  ASSERT_NO_THROW(d_solver.mkBitVector(8, "00000101", 2));
-  ASSERT_NO_THROW(d_solver.mkBitVector(8, "-127", 10));
-  ASSERT_NO_THROW(d_solver.mkBitVector(8, "255", 10));
-  ASSERT_NO_THROW(d_solver.mkBitVector(8, "-7f", 16));
-  ASSERT_NO_THROW(d_solver.mkBitVector(8, "a0", 16));
-
-  ASSERT_THROW(d_solver.mkBitVector(0, 2), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkBitVector(0, "-127", 10), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkBitVector(0, "a0", 16), CVC5ApiException);
-
-  ASSERT_THROW(d_solver.mkBitVector(8, "", 2), CVC5ApiException);
-
-  ASSERT_THROW(d_solver.mkBitVector(8, "101", 5), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkBitVector(8, "128", 11), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkBitVector(8, "a0", 21), CVC5ApiException);
-
-  ASSERT_THROW(d_solver.mkBitVector(8, "-11111111", 2), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkBitVector(8, "101010101", 2), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkBitVector(8, "-256", 10), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkBitVector(8, "257", 10), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkBitVector(8, "-a0", 16), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkBitVector(8, "fffff", 16), CVC5ApiException);
-
-  ASSERT_THROW(d_solver.mkBitVector(8, "10201010", 2), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkBitVector(8, "-25x", 10), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkBitVector(8, "2x7", 10), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkBitVector(8, "fzff", 16), CVC5ApiException);
-
-  ASSERT_EQ(d_solver.mkBitVector(8, "0101", 2),
-            d_solver.mkBitVector(8, "00000101", 2));
-  ASSERT_EQ(d_solver.mkBitVector(4, "-1", 2), d_solver.mkBitVector(4, "1111", 2));
-  ASSERT_EQ(d_solver.mkBitVector(4, "-1", 16), d_solver.mkBitVector(4, "1111", 2));
-  ASSERT_EQ(d_solver.mkBitVector(4, "-1", 10), d_solver.mkBitVector(4, "1111", 2));
-  ASSERT_EQ(d_solver.mkBitVector(8, "01010101", 2).toString(), "#b01010101");
-  ASSERT_EQ(d_solver.mkBitVector(8, "F", 16).toString(), "#b00001111");
-  ASSERT_EQ(d_solver.mkBitVector(8, "-1", 10),
-            d_solver.mkBitVector(8, "FF", 16));
-}
-
-TEST_F(TestApiBlackSolver, mkVar)
-{
-  Sort boolSort = d_solver.getBooleanSort();
-  Sort intSort = d_solver.getIntegerSort();
-  Sort funSort = d_solver.mkFunctionSort(intSort, boolSort);
-  ASSERT_NO_THROW(d_solver.mkVar(boolSort));
-  ASSERT_NO_THROW(d_solver.mkVar(funSort));
-  ASSERT_NO_THROW(d_solver.mkVar(boolSort, std::string("b")));
-  ASSERT_NO_THROW(d_solver.mkVar(funSort, ""));
-  ASSERT_THROW(d_solver.mkVar(Sort()), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkVar(Sort(), "a"), CVC5ApiException);
-  Solver slv;
-  ASSERT_THROW(slv.mkVar(boolSort, "x"), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, mkBoolean)
-{
-  ASSERT_NO_THROW(d_solver.mkBoolean(true));
-  ASSERT_NO_THROW(d_solver.mkBoolean(false));
-}
-
-TEST_F(TestApiBlackSolver, mkRoundingMode)
-{
-  ASSERT_NO_THROW(d_solver.mkRoundingMode(RoundingMode::ROUND_TOWARD_ZERO));
-}
-
-TEST_F(TestApiBlackSolver, mkAbstractValue)
-{
-  ASSERT_NO_THROW(d_solver.mkAbstractValue(std::string("1")));
-  ASSERT_THROW(d_solver.mkAbstractValue(std::string("0")), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkAbstractValue(std::string("-1")), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkAbstractValue(std::string("1.2")), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkAbstractValue("1/2"), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkAbstractValue("asdf"), CVC5ApiException);
-
-  ASSERT_NO_THROW(d_solver.mkAbstractValue((uint32_t)1));
-  ASSERT_NO_THROW(d_solver.mkAbstractValue((int32_t)1));
-  ASSERT_NO_THROW(d_solver.mkAbstractValue((uint64_t)1));
-  ASSERT_NO_THROW(d_solver.mkAbstractValue((int64_t)1));
-  ASSERT_NO_THROW(d_solver.mkAbstractValue((int32_t)-1));
-  ASSERT_NO_THROW(d_solver.mkAbstractValue((int64_t)-1));
-  ASSERT_THROW(d_solver.mkAbstractValue(0), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, mkFloatingPoint)
-{
-  Term t1 = d_solver.mkBitVector(8);
-  Term t2 = d_solver.mkBitVector(4);
-  Term t3 = d_solver.mkInteger(2);
-  ASSERT_NO_THROW(d_solver.mkFloatingPoint(3, 5, t1));
-  ASSERT_THROW(d_solver.mkFloatingPoint(0, 5, Term()), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkFloatingPoint(0, 5, t1), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkFloatingPoint(3, 0, t1), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkFloatingPoint(3, 5, t2), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkFloatingPoint(3, 5, t2), CVC5ApiException);
-
-  Solver slv;
-  ASSERT_THROW(slv.mkFloatingPoint(3, 5, t1), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, mkCardinalityConstraint)
-{
-  Sort su = d_solver.mkUninterpretedSort("u");
-  Sort si = d_solver.getIntegerSort();
-  ASSERT_NO_THROW(d_solver.mkCardinalityConstraint(su, 3));
-  ASSERT_THROW(d_solver.mkCardinalityConstraint(si, 3), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkCardinalityConstraint(su, 0), CVC5ApiException);
-  Solver slv;
-  ASSERT_THROW(slv.mkCardinalityConstraint(su, 3), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, mkEmptySet)
-{
-  Solver slv;
-  Sort s = d_solver.mkSetSort(d_solver.getBooleanSort());
-  ASSERT_NO_THROW(d_solver.mkEmptySet(Sort()));
-  ASSERT_NO_THROW(d_solver.mkEmptySet(s));
-  ASSERT_THROW(d_solver.mkEmptySet(d_solver.getBooleanSort()),
-               CVC5ApiException);
-  ASSERT_THROW(slv.mkEmptySet(s), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, mkEmptyBag)
-{
-  Solver slv;
-  Sort s = d_solver.mkBagSort(d_solver.getBooleanSort());
-  ASSERT_NO_THROW(d_solver.mkEmptyBag(Sort()));
-  ASSERT_NO_THROW(d_solver.mkEmptyBag(s));
-  ASSERT_THROW(d_solver.mkEmptyBag(d_solver.getBooleanSort()),
-               CVC5ApiException);
-  ASSERT_THROW(slv.mkEmptyBag(s), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, mkEmptySequence)
-{
-  Solver slv;
-  Sort s = d_solver.mkSequenceSort(d_solver.getBooleanSort());
-  ASSERT_NO_THROW(d_solver.mkEmptySequence(s));
-  ASSERT_NO_THROW(d_solver.mkEmptySequence(d_solver.getBooleanSort()));
-  ASSERT_THROW(slv.mkEmptySequence(s), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, mkFalse)
-{
-  ASSERT_NO_THROW(d_solver.mkFalse());
-  ASSERT_NO_THROW(d_solver.mkFalse());
-}
-
-TEST_F(TestApiBlackSolver, mkNaN) { ASSERT_NO_THROW(d_solver.mkNaN(3, 5)); }
-
-TEST_F(TestApiBlackSolver, mkNegZero)
-{
-  ASSERT_NO_THROW(d_solver.mkNegZero(3, 5));
-}
-
-TEST_F(TestApiBlackSolver, mkNegInf)
-{
-  ASSERT_NO_THROW(d_solver.mkNegInf(3, 5));
-}
-
-TEST_F(TestApiBlackSolver, mkPosInf)
-{
-  ASSERT_NO_THROW(d_solver.mkPosInf(3, 5));
-}
-
-TEST_F(TestApiBlackSolver, mkPosZero)
-{
-  ASSERT_NO_THROW(d_solver.mkPosZero(3, 5));
-}
-
-TEST_F(TestApiBlackSolver, mkOp)
-{
-  // mkOp(Kind kind, Kind k)
-  ASSERT_THROW(d_solver.mkOp(BITVECTOR_EXTRACT, EQUAL), CVC5ApiException);
-
-  // mkOp(Kind kind, const std::string& arg)
-  ASSERT_NO_THROW(d_solver.mkOp(DIVISIBLE, "2147483648"));
-  ASSERT_THROW(d_solver.mkOp(BITVECTOR_EXTRACT, "asdf"), CVC5ApiException);
-
-  // mkOp(Kind kind, uint32_t arg)
-  ASSERT_NO_THROW(d_solver.mkOp(DIVISIBLE, 1));
-  ASSERT_NO_THROW(d_solver.mkOp(BITVECTOR_ROTATE_LEFT, 1));
-  ASSERT_NO_THROW(d_solver.mkOp(BITVECTOR_ROTATE_RIGHT, 1));
-  ASSERT_THROW(d_solver.mkOp(BITVECTOR_EXTRACT, 1), CVC5ApiException);
-
-  // mkOp(Kind kind, uint32_t arg1, uint32_t arg2)
-  ASSERT_NO_THROW(d_solver.mkOp(BITVECTOR_EXTRACT, 1, 1));
-  ASSERT_THROW(d_solver.mkOp(DIVISIBLE, 1, 2), CVC5ApiException);
-
-  // mkOp(Kind kind, std::vector<uint32_t> args)
-  std::vector<uint32_t> args = {1, 2, 2};
-  ASSERT_NO_THROW(d_solver.mkOp(TUPLE_PROJECT, args));
-}
-
-TEST_F(TestApiBlackSolver, mkPi) { ASSERT_NO_THROW(d_solver.mkPi()); }
-
-TEST_F(TestApiBlackSolver, mkInteger)
-{
-  ASSERT_NO_THROW(d_solver.mkInteger("123"));
-  ASSERT_THROW(d_solver.mkInteger("1.23"), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkInteger("1/23"), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkInteger("12/3"), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkInteger(".2"), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkInteger("2."), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkInteger(""), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkInteger("asdf"), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkInteger("1.2/3"), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkInteger("."), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkInteger("/"), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkInteger("2/"), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkInteger("/2"), CVC5ApiException);
-
-  ASSERT_NO_THROW(d_solver.mkReal(std::string("123")));
-  ASSERT_THROW(d_solver.mkInteger(std::string("1.23")), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkInteger(std::string("1/23")), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkInteger(std::string("12/3")), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkInteger(std::string(".2")), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkInteger(std::string("2.")), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkInteger(std::string("")), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkInteger(std::string("asdf")), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkInteger(std::string("1.2/3")), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkInteger(std::string(".")), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkInteger(std::string("/")), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkInteger(std::string("2/")), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkInteger(std::string("/2")), CVC5ApiException);
-
-  int32_t val1 = 1;
-  int64_t val2 = -1;
-  uint32_t val3 = 1;
-  uint64_t val4 = -1;
-  ASSERT_NO_THROW(d_solver.mkInteger(val1));
-  ASSERT_NO_THROW(d_solver.mkInteger(val2));
-  ASSERT_NO_THROW(d_solver.mkInteger(val3));
-  ASSERT_NO_THROW(d_solver.mkInteger(val4));
-  ASSERT_NO_THROW(d_solver.mkInteger(val4));
-}
-
-TEST_F(TestApiBlackSolver, mkReal)
-{
-  ASSERT_NO_THROW(d_solver.mkReal("123"));
-  ASSERT_NO_THROW(d_solver.mkReal("1.23"));
-  ASSERT_NO_THROW(d_solver.mkReal("1/23"));
-  ASSERT_NO_THROW(d_solver.mkReal("12/3"));
-  ASSERT_NO_THROW(d_solver.mkReal(".2"));
-  ASSERT_NO_THROW(d_solver.mkReal("2."));
-  ASSERT_THROW(d_solver.mkReal(""), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkReal("asdf"), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkReal("1.2/3"), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkReal("."), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkReal("/"), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkReal("2/"), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkReal("/2"), CVC5ApiException);
-
-  ASSERT_NO_THROW(d_solver.mkReal(std::string("123")));
-  ASSERT_NO_THROW(d_solver.mkReal(std::string("1.23")));
-  ASSERT_NO_THROW(d_solver.mkReal(std::string("1/23")));
-  ASSERT_NO_THROW(d_solver.mkReal(std::string("12/3")));
-  ASSERT_NO_THROW(d_solver.mkReal(std::string(".2")));
-  ASSERT_NO_THROW(d_solver.mkReal(std::string("2.")));
-  ASSERT_THROW(d_solver.mkReal(std::string("")), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkReal(std::string("asdf")), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkReal(std::string("1.2/3")), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkReal(std::string(".")), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkReal(std::string("/")), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkReal(std::string("2/")), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkReal(std::string("/2")), CVC5ApiException);
-
-  int32_t val1 = 1;
-  int64_t val2 = -1;
-  uint32_t val3 = 1;
-  uint64_t val4 = -1;
-  ASSERT_NO_THROW(d_solver.mkReal(val1));
-  ASSERT_NO_THROW(d_solver.mkReal(val2));
-  ASSERT_NO_THROW(d_solver.mkReal(val3));
-  ASSERT_NO_THROW(d_solver.mkReal(val4));
-  ASSERT_NO_THROW(d_solver.mkReal(val4));
-  ASSERT_NO_THROW(d_solver.mkReal(val1, val1));
-  ASSERT_NO_THROW(d_solver.mkReal(val2, val2));
-  ASSERT_NO_THROW(d_solver.mkReal(val3, val3));
-  ASSERT_NO_THROW(d_solver.mkReal(val4, val4));
-}
-
-TEST_F(TestApiBlackSolver, mkRegexpNone)
-{
-  Sort strSort = d_solver.getStringSort();
-  Term s = d_solver.mkConst(strSort, "s");
-  ASSERT_NO_THROW(
-      d_solver.mkTerm(STRING_IN_REGEXP, s, d_solver.mkRegexpNone()));
-}
-
-TEST_F(TestApiBlackSolver, mkRegexpAllchar)
-{
-  Sort strSort = d_solver.getStringSort();
-  Term s = d_solver.mkConst(strSort, "s");
-  ASSERT_NO_THROW(
-      d_solver.mkTerm(STRING_IN_REGEXP, s, d_solver.mkRegexpAllchar()));
-}
-
-TEST_F(TestApiBlackSolver, mkSepEmp) { ASSERT_NO_THROW(d_solver.mkSepEmp()); }
-
-TEST_F(TestApiBlackSolver, mkSepNil)
-{
-  ASSERT_NO_THROW(d_solver.mkSepNil(d_solver.getBooleanSort()));
-  ASSERT_THROW(d_solver.mkSepNil(Sort()), CVC5ApiException);
-  Solver slv;
-  ASSERT_THROW(slv.mkSepNil(d_solver.getIntegerSort()), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, mkString)
-{
-  ASSERT_NO_THROW(d_solver.mkString(""));
-  ASSERT_NO_THROW(d_solver.mkString("asdfasdf"));
-  ASSERT_EQ(d_solver.mkString("asdf\\nasdf").toString(),
-            "\"asdf\\u{5c}nasdf\"");
-  ASSERT_EQ(d_solver.mkString("asdf\\u{005c}nasdf", true).toString(),
-            "\"asdf\\u{5c}nasdf\"");
-}
-
-TEST_F(TestApiBlackSolver, mkTerm)
-{
-  Sort bv32 = d_solver.mkBitVectorSort(32);
-  Term a = d_solver.mkConst(bv32, "a");
-  Term b = d_solver.mkConst(bv32, "b");
-  std::vector<Term> v1 = {a, b};
-  std::vector<Term> v2 = {a, Term()};
-  std::vector<Term> v3 = {a, d_solver.mkTrue()};
-  std::vector<Term> v4 = {d_solver.mkInteger(1), d_solver.mkInteger(2)};
-  std::vector<Term> v5 = {d_solver.mkInteger(1), Term()};
-  std::vector<Term> v6 = {};
-  Solver slv;
-
-  // mkTerm(Kind kind) const
-  ASSERT_NO_THROW(d_solver.mkTerm(PI));
-  ASSERT_NO_THROW(d_solver.mkTerm(REGEXP_NONE));
-  ASSERT_NO_THROW(d_solver.mkTerm(REGEXP_ALLCHAR));
-  ASSERT_THROW(d_solver.mkTerm(CONST_BITVECTOR), CVC5ApiException);
-
-  // mkTerm(Kind kind, Term child) const
-  ASSERT_NO_THROW(d_solver.mkTerm(NOT, d_solver.mkTrue()));
-  ASSERT_THROW(d_solver.mkTerm(NOT, Term()), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkTerm(NOT, a), CVC5ApiException);
-  ASSERT_THROW(slv.mkTerm(NOT, d_solver.mkTrue()), CVC5ApiException);
-
-  // mkTerm(Kind kind, Term child1, Term child2) const
-  ASSERT_NO_THROW(d_solver.mkTerm(EQUAL, a, b));
-  ASSERT_THROW(d_solver.mkTerm(EQUAL, Term(), b), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkTerm(EQUAL, a, Term()), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkTerm(EQUAL, a, d_solver.mkTrue()), CVC5ApiException);
-  ASSERT_THROW(slv.mkTerm(EQUAL, a, b), CVC5ApiException);
-
-  // mkTerm(Kind kind, Term child1, Term child2, Term child3) const
-  ASSERT_NO_THROW(d_solver.mkTerm(
-      ITE, d_solver.mkTrue(), d_solver.mkTrue(), d_solver.mkTrue()));
-  ASSERT_THROW(
-      d_solver.mkTerm(ITE, Term(), d_solver.mkTrue(), d_solver.mkTrue()),
-      CVC5ApiException);
-  ASSERT_THROW(
-      d_solver.mkTerm(ITE, d_solver.mkTrue(), Term(), d_solver.mkTrue()),
-      CVC5ApiException);
-  ASSERT_THROW(
-      d_solver.mkTerm(ITE, d_solver.mkTrue(), d_solver.mkTrue(), Term()),
-      CVC5ApiException);
-  ASSERT_THROW(d_solver.mkTerm(ITE, d_solver.mkTrue(), d_solver.mkTrue(), b),
-               CVC5ApiException);
-  ASSERT_THROW(
-      slv.mkTerm(ITE, d_solver.mkTrue(), d_solver.mkTrue(), d_solver.mkTrue()),
-      CVC5ApiException);
-
-  // mkTerm(Kind kind, const std::vector<Term>& children) const
-  ASSERT_NO_THROW(d_solver.mkTerm(EQUAL, v1));
-  ASSERT_THROW(d_solver.mkTerm(EQUAL, v2), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkTerm(EQUAL, v3), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkTerm(DISTINCT, v6), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, mkTermFromOp)
-{
-  Sort bv32 = d_solver.mkBitVectorSort(32);
-  Term a = d_solver.mkConst(bv32, "a");
-  Term b = d_solver.mkConst(bv32, "b");
-  std::vector<Term> v1 = {d_solver.mkInteger(1), d_solver.mkInteger(2)};
-  std::vector<Term> v2 = {d_solver.mkInteger(1), Term()};
-  std::vector<Term> v3 = {};
-  std::vector<Term> v4 = {d_solver.mkInteger(5)};
-  Solver slv;
-
-  // simple operator terms
-  Op opterm1 = d_solver.mkOp(BITVECTOR_EXTRACT, 2, 1);
-  Op opterm2 = d_solver.mkOp(DIVISIBLE, 1);
-
-  // list datatype
-  Sort sort = d_solver.mkParamSort("T");
-  DatatypeDecl listDecl = d_solver.mkDatatypeDecl("paramlist", sort);
-  DatatypeConstructorDecl cons = d_solver.mkDatatypeConstructorDecl("cons");
-  DatatypeConstructorDecl nil = d_solver.mkDatatypeConstructorDecl("nil");
-  cons.addSelector("head", sort);
-  cons.addSelectorSelf("tail");
-  listDecl.addConstructor(cons);
-  listDecl.addConstructor(nil);
-  Sort listSort = d_solver.mkDatatypeSort(listDecl);
-  Sort intListSort =
-      listSort.instantiate(std::vector<Sort>{d_solver.getIntegerSort()});
-  Term c = d_solver.mkConst(intListSort, "c");
-  Datatype list = listSort.getDatatype();
-
-  // list datatype constructor and selector operator terms
-  Term consTerm1 = list.getConstructorTerm("cons");
-  Term consTerm2 = list.getConstructor("cons").getConstructorTerm();
-  Term nilTerm1 = list.getConstructorTerm("nil");
-  Term nilTerm2 = list.getConstructor("nil").getConstructorTerm();
-  Term headTerm1 = list["cons"].getSelectorTerm("head");
-  Term headTerm2 = list["cons"].getSelector("head").getSelectorTerm();
-  Term tailTerm1 = list["cons"].getSelectorTerm("tail");
-  Term tailTerm2 = list["cons"]["tail"].getSelectorTerm();
-
-  // mkTerm(Op op, Term term) const
-  ASSERT_NO_THROW(d_solver.mkTerm(APPLY_CONSTRUCTOR, nilTerm1));
-  ASSERT_NO_THROW(d_solver.mkTerm(APPLY_CONSTRUCTOR, nilTerm2));
-  ASSERT_THROW(d_solver.mkTerm(APPLY_SELECTOR, nilTerm1), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkTerm(APPLY_SELECTOR, consTerm1), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkTerm(APPLY_CONSTRUCTOR, consTerm2), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkTerm(opterm1), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkTerm(APPLY_SELECTOR, headTerm1), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkTerm(opterm1), CVC5ApiException);
-  ASSERT_THROW(slv.mkTerm(APPLY_CONSTRUCTOR, nilTerm1), CVC5ApiException);
-
-  // mkTerm(Op op, Term child) const
-  ASSERT_NO_THROW(d_solver.mkTerm(opterm1, a));
-  ASSERT_NO_THROW(d_solver.mkTerm(opterm2, d_solver.mkInteger(1)));
-  ASSERT_NO_THROW(d_solver.mkTerm(APPLY_SELECTOR, headTerm1, c));
-  ASSERT_NO_THROW(d_solver.mkTerm(APPLY_SELECTOR, tailTerm2, c));
-  ASSERT_THROW(d_solver.mkTerm(opterm2, a), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkTerm(opterm1, Term()), CVC5ApiException);
-  ASSERT_THROW(
-      d_solver.mkTerm(APPLY_CONSTRUCTOR, consTerm1, d_solver.mkInteger(0)),
-      CVC5ApiException);
-  ASSERT_THROW(slv.mkTerm(opterm1, a), CVC5ApiException);
-
-  // mkTerm(Op op, Term child1, Term child2) const
-  ASSERT_NO_THROW(
-      d_solver.mkTerm(APPLY_CONSTRUCTOR,
-                      consTerm1,
-                      d_solver.mkInteger(0),
-                      d_solver.mkTerm(APPLY_CONSTRUCTOR, nilTerm1)));
-  ASSERT_THROW(
-      d_solver.mkTerm(opterm2, d_solver.mkInteger(1), d_solver.mkInteger(2)),
-      CVC5ApiException);
-  ASSERT_THROW(d_solver.mkTerm(opterm1, a, b), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkTerm(opterm2, d_solver.mkInteger(1), Term()),
-               CVC5ApiException);
-  ASSERT_THROW(d_solver.mkTerm(opterm2, Term(), d_solver.mkInteger(1)),
-               CVC5ApiException);
-  ASSERT_THROW(slv.mkTerm(APPLY_CONSTRUCTOR,
-                          consTerm1,
-                          d_solver.mkInteger(0),
-                          d_solver.mkTerm(APPLY_CONSTRUCTOR, nilTerm1)),
-               CVC5ApiException);
-
-  // mkTerm(Op op, Term child1, Term child2, Term child3) const
-  ASSERT_THROW(d_solver.mkTerm(opterm1, a, b, a), CVC5ApiException);
-  ASSERT_THROW(
-      d_solver.mkTerm(
-          opterm2, d_solver.mkInteger(1), d_solver.mkInteger(1), Term()),
-      CVC5ApiException);
-
-  // mkTerm(Op op, const std::vector<Term>& children) const
-  ASSERT_NO_THROW(d_solver.mkTerm(opterm2, v4));
-  ASSERT_THROW(d_solver.mkTerm(opterm2, v1), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkTerm(opterm2, v2), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkTerm(opterm2, v3), CVC5ApiException);
-  ASSERT_THROW(slv.mkTerm(opterm2, v4), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, mkTrue)
-{
-  ASSERT_NO_THROW(d_solver.mkTrue());
-  ASSERT_NO_THROW(d_solver.mkTrue());
-}
-
-TEST_F(TestApiBlackSolver, mkTuple)
-{
-  ASSERT_NO_THROW(d_solver.mkTuple({d_solver.mkBitVectorSort(3)},
-                                   {d_solver.mkBitVector(3, "101", 2)}));
-  ASSERT_NO_THROW(
-      d_solver.mkTuple({d_solver.getRealSort()}, {d_solver.mkInteger("5")}));
-
-  ASSERT_THROW(d_solver.mkTuple({}, {d_solver.mkBitVector(3, "101", 2)}),
-               CVC5ApiException);
-  ASSERT_THROW(d_solver.mkTuple({d_solver.mkBitVectorSort(4)},
-                                {d_solver.mkBitVector(3, "101", 2)}),
-               CVC5ApiException);
-  ASSERT_THROW(
-      d_solver.mkTuple({d_solver.getIntegerSort()}, {d_solver.mkReal("5.3")}),
-      CVC5ApiException);
-  Solver slv;
-  ASSERT_THROW(slv.mkTuple({d_solver.mkBitVectorSort(3)},
-                           {slv.mkBitVector(3, "101", 2)}),
-               CVC5ApiException);
-  ASSERT_THROW(slv.mkTuple({slv.mkBitVectorSort(3)},
-                           {d_solver.mkBitVector(3, "101", 2)}),
-               CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, mkUniverseSet)
-{
-  ASSERT_NO_THROW(d_solver.mkUniverseSet(d_solver.getBooleanSort()));
-  ASSERT_THROW(d_solver.mkUniverseSet(Sort()), CVC5ApiException);
-  Solver slv;
-  ASSERT_THROW(slv.mkUniverseSet(d_solver.getBooleanSort()), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, mkConst)
-{
-  Sort boolSort = d_solver.getBooleanSort();
-  Sort intSort = d_solver.getIntegerSort();
-  Sort funSort = d_solver.mkFunctionSort(intSort, boolSort);
-  ASSERT_NO_THROW(d_solver.mkConst(boolSort));
-  ASSERT_NO_THROW(d_solver.mkConst(funSort));
-  ASSERT_NO_THROW(d_solver.mkConst(boolSort, std::string("b")));
-  ASSERT_NO_THROW(d_solver.mkConst(intSort, std::string("i")));
-  ASSERT_NO_THROW(d_solver.mkConst(funSort, "f"));
-  ASSERT_NO_THROW(d_solver.mkConst(funSort, ""));
-  ASSERT_THROW(d_solver.mkConst(Sort()), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkConst(Sort(), "a"), CVC5ApiException);
-
-  Solver slv;
-  ASSERT_THROW(slv.mkConst(boolSort), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, mkConstArray)
-{
-  Sort intSort = d_solver.getIntegerSort();
-  Sort arrSort = d_solver.mkArraySort(intSort, intSort);
-  Term zero = d_solver.mkInteger(0);
-  Term constArr = d_solver.mkConstArray(arrSort, zero);
-
-  ASSERT_NO_THROW(d_solver.mkConstArray(arrSort, zero));
-  ASSERT_THROW(d_solver.mkConstArray(Sort(), zero), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkConstArray(arrSort, Term()), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkConstArray(arrSort, d_solver.mkBitVector(1, 1)),
-               CVC5ApiException);
-  ASSERT_THROW(d_solver.mkConstArray(intSort, zero), CVC5ApiException);
-  Solver slv;
-  Term zero2 = slv.mkInteger(0);
-  Sort arrSort2 = slv.mkArraySort(slv.getIntegerSort(), slv.getIntegerSort());
-  ASSERT_THROW(slv.mkConstArray(arrSort2, zero), CVC5ApiException);
-  ASSERT_THROW(slv.mkConstArray(arrSort, zero2), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, declareDatatype)
-{
-  DatatypeConstructorDecl nil = d_solver.mkDatatypeConstructorDecl("nil");
-  std::vector<DatatypeConstructorDecl> ctors1 = {nil};
-  ASSERT_NO_THROW(d_solver.declareDatatype(std::string("a"), ctors1));
-  DatatypeConstructorDecl cons = d_solver.mkDatatypeConstructorDecl("cons");
-  DatatypeConstructorDecl nil2 = d_solver.mkDatatypeConstructorDecl("nil");
-  std::vector<DatatypeConstructorDecl> ctors2 = {cons, nil2};
-  ASSERT_NO_THROW(d_solver.declareDatatype(std::string("b"), ctors2));
-  DatatypeConstructorDecl cons2 = d_solver.mkDatatypeConstructorDecl("cons");
-  DatatypeConstructorDecl nil3 = d_solver.mkDatatypeConstructorDecl("nil");
-  std::vector<DatatypeConstructorDecl> ctors3 = {cons2, nil3};
-  ASSERT_NO_THROW(d_solver.declareDatatype(std::string(""), ctors3));
-  std::vector<DatatypeConstructorDecl> ctors4;
-  ASSERT_THROW(d_solver.declareDatatype(std::string("c"), ctors4),
-               CVC5ApiException);
-  ASSERT_THROW(d_solver.declareDatatype(std::string(""), ctors4),
-               CVC5ApiException);
-  Solver slv;
-  ASSERT_THROW(slv.declareDatatype(std::string("a"), ctors1), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, declareFun)
-{
-  Sort bvSort = d_solver.mkBitVectorSort(32);
-  Sort funSort = d_solver.mkFunctionSort(d_solver.mkUninterpretedSort("u"),
-                                         d_solver.getIntegerSort());
-  ASSERT_NO_THROW(d_solver.declareFun("f1", {}, bvSort));
-  ASSERT_NO_THROW(
-      d_solver.declareFun("f3", {bvSort, d_solver.getIntegerSort()}, bvSort));
-  ASSERT_THROW(d_solver.declareFun("f2", {}, funSort), CVC5ApiException);
-  // functions as arguments is allowed
-  ASSERT_NO_THROW(d_solver.declareFun("f4", {bvSort, funSort}, bvSort));
-  ASSERT_THROW(d_solver.declareFun("f5", {bvSort, bvSort}, funSort),
-               CVC5ApiException);
-  Solver slv;
-  ASSERT_THROW(slv.declareFun("f1", {}, bvSort), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, declareSort)
-{
-  ASSERT_NO_THROW(d_solver.declareSort("s", 0));
-  ASSERT_NO_THROW(d_solver.declareSort("s", 2));
-  ASSERT_NO_THROW(d_solver.declareSort("", 2));
-}
-
-TEST_F(TestApiBlackSolver, defineSort)
-{
-  Sort sortVar0 = d_solver.mkParamSort("T0");
-  Sort sortVar1 = d_solver.mkParamSort("T1");
-  Sort intSort = d_solver.getIntegerSort();
-  Sort realSort = d_solver.getRealSort();
-  Sort arraySort0 = d_solver.mkArraySort(sortVar0, sortVar0);
-  Sort arraySort1 = d_solver.mkArraySort(sortVar0, sortVar1);
-  // Now create instantiations of the defined sorts
-  ASSERT_NO_THROW(arraySort0.substitute(sortVar0, intSort));
-  ASSERT_NO_THROW(
-      arraySort1.substitute({sortVar0, sortVar1}, {intSort, realSort}));
-}
-
-TEST_F(TestApiBlackSolver, defineFun)
-{
-  Sort bvSort = d_solver.mkBitVectorSort(32);
-  Sort funSort = d_solver.mkFunctionSort(d_solver.mkUninterpretedSort("u"),
-                                         d_solver.getIntegerSort());
-  Term b1 = d_solver.mkVar(bvSort, "b1");
-  Term b2 = d_solver.mkVar(d_solver.getIntegerSort(), "b2");
-  Term b3 = d_solver.mkVar(funSort, "b3");
-  Term v1 = d_solver.mkConst(bvSort, "v1");
-  Term v2 = d_solver.mkConst(funSort, "v2");
-  ASSERT_NO_THROW(d_solver.defineFun("f", {}, bvSort, v1));
-  ASSERT_NO_THROW(d_solver.defineFun("ff", {b1, b2}, bvSort, v1));
-  ASSERT_THROW(d_solver.defineFun("ff", {v1, b2}, bvSort, v1),
-               CVC5ApiException);
-  ASSERT_THROW(d_solver.defineFun("fff", {b1}, bvSort, v2), CVC5ApiException);
-  ASSERT_THROW(d_solver.defineFun("ffff", {b1}, funSort, v2), CVC5ApiException);
-  // b3 has function sort, which is allowed as an argument
-  ASSERT_NO_THROW(d_solver.defineFun("fffff", {b1, b3}, bvSort, v1));
-
-  Solver slv;
-  Sort bvSort2 = slv.mkBitVectorSort(32);
-  Term v12 = slv.mkConst(bvSort2, "v1");
-  Term b12 = slv.mkVar(bvSort2, "b1");
-  Term b22 = slv.mkVar(slv.getIntegerSort(), "b2");
-  ASSERT_THROW(slv.defineFun("f", {}, bvSort, v12), CVC5ApiException);
-  ASSERT_THROW(slv.defineFun("f", {}, bvSort2, v1), CVC5ApiException);
-  ASSERT_THROW(slv.defineFun("ff", {b1, b22}, bvSort2, v12), CVC5ApiException);
-  ASSERT_THROW(slv.defineFun("ff", {b12, b2}, bvSort2, v12), CVC5ApiException);
-  ASSERT_THROW(slv.defineFun("ff", {b12, b22}, bvSort, v12), CVC5ApiException);
-  ASSERT_THROW(slv.defineFun("ff", {b12, b22}, bvSort2, v1), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, defineFunGlobal)
-{
-  Sort bSort = d_solver.getBooleanSort();
-
-  Term bTrue = d_solver.mkBoolean(true);
-  // (define-fun f () Bool true)
-  Term f = d_solver.defineFun("f", {}, bSort, bTrue, true);
-  Term b = d_solver.mkVar(bSort, "b");
-  // (define-fun g (b Bool) Bool b)
-  Term g = d_solver.defineFun("g", {b}, bSort, b, true);
-
-  // (assert (or (not f) (not (g true))))
-  d_solver.assertFormula(d_solver.mkTerm(
-      OR, f.notTerm(), d_solver.mkTerm(APPLY_UF, g, bTrue).notTerm()));
-  ASSERT_TRUE(d_solver.checkSat().isUnsat());
-  d_solver.resetAssertions();
-  // (assert (or (not f) (not (g true))))
-  d_solver.assertFormula(d_solver.mkTerm(
-      OR, f.notTerm(), d_solver.mkTerm(APPLY_UF, g, bTrue).notTerm()));
-  ASSERT_TRUE(d_solver.checkSat().isUnsat());
-}
-
-TEST_F(TestApiBlackSolver, defineFunRec)
-{
-  Sort bvSort = d_solver.mkBitVectorSort(32);
-  Sort funSort1 = d_solver.mkFunctionSort({bvSort, bvSort}, bvSort);
-  Sort funSort2 = d_solver.mkFunctionSort(d_solver.mkUninterpretedSort("u"),
-                                          d_solver.getIntegerSort());
-  Term b1 = d_solver.mkVar(bvSort, "b1");
-  Term b11 = d_solver.mkVar(bvSort, "b1");
-  Term b2 = d_solver.mkVar(d_solver.getIntegerSort(), "b2");
-  Term b3 = d_solver.mkVar(funSort2, "b3");
-  Term v1 = d_solver.mkConst(bvSort, "v1");
-  Term v2 = d_solver.mkConst(d_solver.getIntegerSort(), "v2");
-  Term v3 = d_solver.mkConst(funSort2, "v3");
-  Term f1 = d_solver.mkConst(funSort1, "f1");
-  Term f2 = d_solver.mkConst(funSort2, "f2");
-  Term f3 = d_solver.mkConst(bvSort, "f3");
-  ASSERT_NO_THROW(d_solver.defineFunRec("f", {}, bvSort, v1));
-  ASSERT_NO_THROW(d_solver.defineFunRec("ff", {b1, b2}, bvSort, v1));
-  ASSERT_NO_THROW(d_solver.defineFunRec(f1, {b1, b11}, v1));
-  ASSERT_THROW(d_solver.defineFunRec("fff", {b1}, bvSort, v3),
-               CVC5ApiException);
-  ASSERT_THROW(d_solver.defineFunRec("ff", {b1, v2}, bvSort, v1),
-               CVC5ApiException);
-  ASSERT_THROW(d_solver.defineFunRec("ffff", {b1}, funSort2, v3),
-               CVC5ApiException);
-  // b3 has function sort, which is allowed as an argument
-  ASSERT_NO_THROW(d_solver.defineFunRec("fffff", {b1, b3}, bvSort, v1));
-  ASSERT_THROW(d_solver.defineFunRec(f1, {b1}, v1), CVC5ApiException);
-  ASSERT_THROW(d_solver.defineFunRec(f1, {b1, b11}, v2), CVC5ApiException);
-  ASSERT_THROW(d_solver.defineFunRec(f1, {b1, b11}, v3), CVC5ApiException);
-  ASSERT_THROW(d_solver.defineFunRec(f2, {b1}, v2), CVC5ApiException);
-  ASSERT_THROW(d_solver.defineFunRec(f3, {b1}, v1), CVC5ApiException);
-
-  Solver slv;
-  Sort bvSort2 = slv.mkBitVectorSort(32);
-  Term v12 = slv.mkConst(bvSort2, "v1");
-  Term b12 = slv.mkVar(bvSort2, "b1");
-  Term b22 = slv.mkVar(slv.getIntegerSort(), "b2");
-  ASSERT_NO_THROW(slv.defineFunRec("f", {}, bvSort2, v12));
-  ASSERT_NO_THROW(slv.defineFunRec("ff", {b12, b22}, bvSort2, v12));
-  ASSERT_THROW(slv.defineFunRec("f", {}, bvSort, v12), CVC5ApiException);
-  ASSERT_THROW(slv.defineFunRec("f", {}, bvSort2, v1), CVC5ApiException);
-  ASSERT_THROW(slv.defineFunRec("ff", {b1, b22}, bvSort2, v12),
-               CVC5ApiException);
-  ASSERT_THROW(slv.defineFunRec("ff", {b12, b2}, bvSort2, v12),
-               CVC5ApiException);
-  ASSERT_THROW(slv.defineFunRec("ff", {b12, b22}, bvSort, v12),
-               CVC5ApiException);
-  ASSERT_THROW(slv.defineFunRec("ff", {b12, b22}, bvSort2, v1),
-               CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, defineFunRecWrongLogic)
-{
-  d_solver.setLogic("QF_BV");
-  Sort bvSort = d_solver.mkBitVectorSort(32);
-  Sort funSort = d_solver.mkFunctionSort({bvSort, bvSort}, bvSort);
-  Term b = d_solver.mkVar(bvSort, "b");
-  Term v = d_solver.mkConst(bvSort, "v");
-  Term f = d_solver.mkConst(funSort, "f");
-  ASSERT_THROW(d_solver.defineFunRec("f", {}, bvSort, v), CVC5ApiException);
-  ASSERT_THROW(d_solver.defineFunRec(f, {b, b}, v), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, defineFunRecGlobal)
-{
-  Sort bSort = d_solver.getBooleanSort();
-  Sort fSort = d_solver.mkFunctionSort(bSort, bSort);
-
-  d_solver.push();
-  Term bTrue = d_solver.mkBoolean(true);
-  // (define-fun f () Bool true)
-  Term f = d_solver.defineFunRec("f", {}, bSort, bTrue, true);
-  Term b = d_solver.mkVar(bSort, "b");
-  Term gSym = d_solver.mkConst(fSort, "g");
-  // (define-fun g (b Bool) Bool b)
-  Term g = d_solver.defineFunRec(gSym, {b}, b, true);
-
-  // (assert (or (not f) (not (g true))))
-  d_solver.assertFormula(d_solver.mkTerm(
-      OR, f.notTerm(), d_solver.mkTerm(APPLY_UF, g, bTrue).notTerm()));
-  ASSERT_TRUE(d_solver.checkSat().isUnsat());
-  d_solver.pop();
-  // (assert (or (not f) (not (g true))))
-  d_solver.assertFormula(d_solver.mkTerm(
-      OR, f.notTerm(), d_solver.mkTerm(APPLY_UF, g, bTrue).notTerm()));
-  ASSERT_TRUE(d_solver.checkSat().isUnsat());
-}
-
-TEST_F(TestApiBlackSolver, defineFunsRec)
-{
-  Sort uSort = d_solver.mkUninterpretedSort("u");
-  Sort bvSort = d_solver.mkBitVectorSort(32);
-  Sort funSort1 = d_solver.mkFunctionSort({bvSort, bvSort}, bvSort);
-  Sort funSort2 = d_solver.mkFunctionSort(uSort, d_solver.getIntegerSort());
-  Term b1 = d_solver.mkVar(bvSort, "b1");
-  Term b11 = d_solver.mkVar(bvSort, "b1");
-  Term b2 = d_solver.mkVar(d_solver.getIntegerSort(), "b2");
-  Term b3 = d_solver.mkVar(funSort2, "b3");
-  Term b4 = d_solver.mkVar(uSort, "b4");
-  Term v1 = d_solver.mkConst(bvSort, "v1");
-  Term v2 = d_solver.mkConst(d_solver.getIntegerSort(), "v2");
-  Term v3 = d_solver.mkConst(funSort2, "v3");
-  Term v4 = d_solver.mkConst(uSort, "v4");
-  Term f1 = d_solver.mkConst(funSort1, "f1");
-  Term f2 = d_solver.mkConst(funSort2, "f2");
-  Term f3 = d_solver.mkConst(bvSort, "f3");
-  ASSERT_NO_THROW(
-      d_solver.defineFunsRec({f1, f2}, {{b1, b11}, {b4}}, {v1, v2}));
-  ASSERT_THROW(d_solver.defineFunsRec({f1, f2}, {{v1, b11}, {b4}}, {v1, v2}),
-               CVC5ApiException);
-  ASSERT_THROW(d_solver.defineFunsRec({f1, f3}, {{b1, b11}, {b4}}, {v1, v2}),
-               CVC5ApiException);
-  ASSERT_THROW(d_solver.defineFunsRec({f1, f2}, {{b1}, {b4}}, {v1, v2}),
-               CVC5ApiException);
-  ASSERT_THROW(d_solver.defineFunsRec({f1, f2}, {{b1, b2}, {b4}}, {v1, v2}),
-               CVC5ApiException);
-  ASSERT_THROW(d_solver.defineFunsRec({f1, f2}, {{b1, b11}, {b4}}, {v1, v4}),
-               CVC5ApiException);
-
-  Solver slv;
-  Sort uSort2 = slv.mkUninterpretedSort("u");
-  Sort bvSort2 = slv.mkBitVectorSort(32);
-  Sort funSort12 = slv.mkFunctionSort({bvSort2, bvSort2}, bvSort2);
-  Sort funSort22 = slv.mkFunctionSort(uSort2, slv.getIntegerSort());
-  Term b12 = slv.mkVar(bvSort2, "b1");
-  Term b112 = slv.mkVar(bvSort2, "b1");
-  Term b42 = slv.mkVar(uSort2, "b4");
-  Term v12 = slv.mkConst(bvSort2, "v1");
-  Term v22 = slv.mkConst(slv.getIntegerSort(), "v2");
-  Term f12 = slv.mkConst(funSort12, "f1");
-  Term f22 = slv.mkConst(funSort22, "f2");
-  ASSERT_NO_THROW(
-      slv.defineFunsRec({f12, f22}, {{b12, b112}, {b42}}, {v12, v22}));
-  ASSERT_THROW(slv.defineFunsRec({f1, f22}, {{b12, b112}, {b42}}, {v12, v22}),
-               CVC5ApiException);
-  ASSERT_THROW(slv.defineFunsRec({f12, f2}, {{b12, b112}, {b42}}, {v12, v22}),
-               CVC5ApiException);
-  ASSERT_THROW(slv.defineFunsRec({f12, f22}, {{b1, b112}, {b42}}, {v12, v22}),
-               CVC5ApiException);
-  ASSERT_THROW(slv.defineFunsRec({f12, f22}, {{b12, b11}, {b42}}, {v12, v22}),
-               CVC5ApiException);
-  ASSERT_THROW(slv.defineFunsRec({f12, f22}, {{b12, b112}, {b4}}, {v12, v22}),
-               CVC5ApiException);
-  ASSERT_THROW(slv.defineFunsRec({f12, f22}, {{b12, b112}, {b42}}, {v1, v22}),
-               CVC5ApiException);
-  ASSERT_THROW(slv.defineFunsRec({f12, f22}, {{b12, b112}, {b42}}, {v12, v2}),
-               CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, defineFunsRecWrongLogic)
-{
-  d_solver.setLogic("QF_BV");
-  Sort uSort = d_solver.mkUninterpretedSort("u");
-  Sort bvSort = d_solver.mkBitVectorSort(32);
-  Sort funSort1 = d_solver.mkFunctionSort({bvSort, bvSort}, bvSort);
-  Sort funSort2 = d_solver.mkFunctionSort(uSort, d_solver.getIntegerSort());
-  Term b = d_solver.mkVar(bvSort, "b");
-  Term u = d_solver.mkVar(uSort, "u");
-  Term v1 = d_solver.mkConst(bvSort, "v1");
-  Term v2 = d_solver.mkConst(d_solver.getIntegerSort(), "v2");
-  Term f1 = d_solver.mkConst(funSort1, "f1");
-  Term f2 = d_solver.mkConst(funSort2, "f2");
-  ASSERT_THROW(d_solver.defineFunsRec({f1, f2}, {{b, b}, {u}}, {v1, v2}),
-               CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, defineFunsRecGlobal)
-{
-  Sort bSort = d_solver.getBooleanSort();
-  Sort fSort = d_solver.mkFunctionSort(bSort, bSort);
-
-  d_solver.push();
-  Term bTrue = d_solver.mkBoolean(true);
-  Term b = d_solver.mkVar(bSort, "b");
-  Term gSym = d_solver.mkConst(fSort, "g");
-  // (define-funs-rec ((g ((b Bool)) Bool)) (b))
-  d_solver.defineFunsRec({gSym}, {{b}}, {b}, true);
-
-  // (assert (not (g true)))
-  d_solver.assertFormula(d_solver.mkTerm(APPLY_UF, gSym, bTrue).notTerm());
-  ASSERT_TRUE(d_solver.checkSat().isUnsat());
-  d_solver.pop();
-  // (assert (not (g true)))
-  d_solver.assertFormula(d_solver.mkTerm(APPLY_UF, gSym, bTrue).notTerm());
-  ASSERT_TRUE(d_solver.checkSat().isUnsat());
-}
-
-TEST_F(TestApiBlackSolver, uFIteration)
-{
-  Sort intSort = d_solver.getIntegerSort();
-  Sort funSort = d_solver.mkFunctionSort({intSort, intSort}, intSort);
-  Term x = d_solver.mkConst(intSort, "x");
-  Term y = d_solver.mkConst(intSort, "y");
-  Term f = d_solver.mkConst(funSort, "f");
-  Term fxy = d_solver.mkTerm(APPLY_UF, f, x, y);
-
-  // Expecting the uninterpreted function to be one of the children
-  Term expected_children[3] = {f, x, y};
-  uint32_t idx = 0;
-  for (auto c : fxy)
-  {
-    ASSERT_LT(idx, 3);
-    ASSERT_EQ(c, expected_children[idx]);
-    idx++;
-  }
-}
-
-TEST_F(TestApiBlackSolver, getInfo)
-{
-  ASSERT_NO_THROW(d_solver.getInfo("name"));
-  ASSERT_THROW(d_solver.getInfo("asdf"), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, getAbduct)
-{
-  d_solver.setLogic("QF_LIA");
-  d_solver.setOption("produce-abducts", "true");
-  d_solver.setOption("incremental", "false");
-
-  Sort intSort = d_solver.getIntegerSort();
-  Term zero = d_solver.mkInteger(0);
-  Term x = d_solver.mkConst(intSort, "x");
-  Term y = d_solver.mkConst(intSort, "y");
-
-  // Assumptions for abduction: x > 0
-  d_solver.assertFormula(d_solver.mkTerm(GT, x, zero));
-  // Conjecture for abduction: y > 0
-  Term conj = d_solver.mkTerm(GT, y, zero);
-  Term output;
-  // Call the abduction api, while the resulting abduct is the output
-  ASSERT_TRUE(d_solver.getAbduct(conj, output));
-  // We expect the resulting output to be a boolean formula
-  ASSERT_TRUE(!output.isNull() && output.getSort().isBoolean());
-
-  // try with a grammar, a simple grammar admitting true
-  Sort boolean = d_solver.getBooleanSort();
-  Term truen = d_solver.mkBoolean(true);
-  Term start = d_solver.mkVar(boolean);
-  Term output2;
-  Grammar g = d_solver.mkSygusGrammar({}, {start});
-  Term conj2 = d_solver.mkTerm(GT, x, zero);
-  ASSERT_NO_THROW(g.addRule(start, truen));
-  // Call the abduction api, while the resulting abduct is the output
-  ASSERT_TRUE(d_solver.getAbduct(conj2, g, output2));
-  // abduct must be true
-  ASSERT_EQ(output2, truen);
-}
-
-TEST_F(TestApiBlackSolver, getAbduct2)
-{
-  d_solver.setLogic("QF_LIA");
-  d_solver.setOption("incremental", "false");
-  Sort intSort = d_solver.getIntegerSort();
-  Term zero = d_solver.mkInteger(0);
-  Term x = d_solver.mkConst(intSort, "x");
-  Term y = d_solver.mkConst(intSort, "y");
-  // Assumptions for abduction: x > 0
-  d_solver.assertFormula(d_solver.mkTerm(GT, x, zero));
-  // Conjecture for abduction: y > 0
-  Term conj = d_solver.mkTerm(GT, y, zero);
-  Term output;
-  // Fails due to option not set
-  ASSERT_THROW(d_solver.getAbduct(conj, output), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, getInterpolant)
-{
-  d_solver.setLogic("QF_LIA");
-  d_solver.setOption("produce-interpols", "default");
-  d_solver.setOption("incremental", "false");
-
-  Sort intSort = d_solver.getIntegerSort();
-  Term zero = d_solver.mkInteger(0);
-  Term x = d_solver.mkConst(intSort, "x");
-  Term y = d_solver.mkConst(intSort, "y");
-  Term z = d_solver.mkConst(intSort, "z");
-
-  // Assumptions for interpolation: x + y > 0 /\ x < 0
-  d_solver.assertFormula(
-      d_solver.mkTerm(GT, d_solver.mkTerm(PLUS, x, y), zero));
-  d_solver.assertFormula(d_solver.mkTerm(LT, x, zero));
-  // Conjecture for interpolation: y + z > 0 \/ z < 0
-  Term conj =
-      d_solver.mkTerm(OR,
-                      d_solver.mkTerm(GT, d_solver.mkTerm(PLUS, y, z), zero),
-                      d_solver.mkTerm(LT, z, zero));
-  Term output;
-  // Call the interpolation api, while the resulting interpolant is the output
-  d_solver.getInterpolant(conj, output);
-
-  // We expect the resulting output to be a boolean formula
-  ASSERT_TRUE(output.getSort().isBoolean());
-}
-
-TEST_F(TestApiBlackSolver, declarePool)
-{
-  Sort intSort = d_solver.getIntegerSort();
-  Sort setSort = d_solver.mkSetSort(intSort);
-  Term zero = d_solver.mkInteger(0);
-  Term x = d_solver.mkConst(intSort, "x");
-  Term y = d_solver.mkConst(intSort, "y");
-  // declare a pool with initial value { 0, x, y }
-  Term p = d_solver.declarePool("p", intSort, {zero, x, y});
-  // pool should have the same sort
-  ASSERT_TRUE(p.getSort() == setSort);
-  // cannot pass null sort
-  Sort nullSort;
-  ASSERT_THROW(d_solver.declarePool("i", nullSort, {}), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, getOp)
-{
-  Sort bv32 = d_solver.mkBitVectorSort(32);
-  Term a = d_solver.mkConst(bv32, "a");
-  Op ext = d_solver.mkOp(BITVECTOR_EXTRACT, 2, 1);
-  Term exta = d_solver.mkTerm(ext, a);
-
-  ASSERT_FALSE(a.hasOp());
-  ASSERT_THROW(a.getOp(), CVC5ApiException);
-  ASSERT_TRUE(exta.hasOp());
-  ASSERT_EQ(exta.getOp(), ext);
-
-  // Test Datatypes -- more complicated
-  DatatypeDecl consListSpec = d_solver.mkDatatypeDecl("list");
-  DatatypeConstructorDecl cons = d_solver.mkDatatypeConstructorDecl("cons");
-  cons.addSelector("head", d_solver.getIntegerSort());
-  cons.addSelectorSelf("tail");
-  consListSpec.addConstructor(cons);
-  DatatypeConstructorDecl nil = d_solver.mkDatatypeConstructorDecl("nil");
-  consListSpec.addConstructor(nil);
-  Sort consListSort = d_solver.mkDatatypeSort(consListSpec);
-  Datatype consList = consListSort.getDatatype();
-
-  Term consTerm = consList.getConstructorTerm("cons");
-  Term nilTerm = consList.getConstructorTerm("nil");
-  Term headTerm = consList["cons"].getSelectorTerm("head");
-
-  Term listnil = d_solver.mkTerm(APPLY_CONSTRUCTOR, nilTerm);
-  Term listcons1 = d_solver.mkTerm(
-      APPLY_CONSTRUCTOR, consTerm, d_solver.mkInteger(1), listnil);
-  Term listhead = d_solver.mkTerm(APPLY_SELECTOR, headTerm, listcons1);
-
-  ASSERT_TRUE(listnil.hasOp());
-  ASSERT_TRUE(listcons1.hasOp());
-  ASSERT_TRUE(listhead.hasOp());
-}
-
-TEST_F(TestApiBlackSolver, getOption)
-{
-  ASSERT_NO_THROW(d_solver.getOption("incremental"));
-  ASSERT_THROW(d_solver.getOption("asdf"), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, getOptionNames)
-{
-  std::vector<std::string> names = d_solver.getOptionNames();
-  ASSERT_TRUE(names.size() > 100);
-  ASSERT_NE(std::find(names.begin(), names.end(), "verbose"), names.end());
-  ASSERT_EQ(std::find(names.begin(), names.end(), "foobar"), names.end());
-}
-
-TEST_F(TestApiBlackSolver, getOptionInfo)
-{
-  {
-    EXPECT_THROW(d_solver.getOptionInfo("asdf-invalid"), CVC5ApiException);
-  }
-  {
-    api::OptionInfo info = d_solver.getOptionInfo("verbose");
-    EXPECT_EQ("verbose", info.name);
-    EXPECT_EQ(std::vector<std::string>{}, info.aliases);
-    EXPECT_TRUE(std::holds_alternative<OptionInfo::VoidInfo>(info.valueInfo));
-  }
-  {
-    // int64 type with default
-    api::OptionInfo info = d_solver.getOptionInfo("verbosity");
-    EXPECT_EQ("verbosity", info.name);
-    EXPECT_EQ(std::vector<std::string>{}, info.aliases);
-    EXPECT_TRUE(std::holds_alternative<OptionInfo::NumberInfo<int64_t>>(info.valueInfo));
-    auto numInfo = std::get<OptionInfo::NumberInfo<int64_t>>(info.valueInfo);
-    EXPECT_EQ(0, numInfo.defaultValue);
-    EXPECT_EQ(0, numInfo.currentValue);
-    EXPECT_FALSE(numInfo.minimum || numInfo.maximum);
-    ASSERT_EQ(info.intValue(), 0);
-  }
-  {
-    auto info = d_solver.getOptionInfo("random-freq");
-    ASSERT_EQ(info.name, "random-freq");
-    ASSERT_EQ(info.aliases, std::vector<std::string>{"random-frequency"});
-    ASSERT_TRUE(std::holds_alternative<api::OptionInfo::NumberInfo<double>>(info.valueInfo));
-    auto ni = std::get<api::OptionInfo::NumberInfo<double>>(info.valueInfo);
-    ASSERT_EQ(ni.currentValue, 0.0);
-    ASSERT_EQ(ni.defaultValue, 0.0);
-    ASSERT_TRUE(ni.minimum && ni.maximum);
-    ASSERT_EQ(*ni.minimum, 0.0);
-    ASSERT_EQ(*ni.maximum, 1.0);
-    ASSERT_EQ(info.doubleValue(), 0.0);
-  }
-  {
-    // mode option
-    api::OptionInfo info = d_solver.getOptionInfo("output");
-    EXPECT_EQ("output", info.name);
-    EXPECT_EQ(std::vector<std::string>{}, info.aliases);
-    EXPECT_TRUE(std::holds_alternative<OptionInfo::ModeInfo>(info.valueInfo));
-    auto modeInfo = std::get<OptionInfo::ModeInfo>(info.valueInfo);
-    EXPECT_EQ("NONE", modeInfo.defaultValue);
-    EXPECT_EQ("none", modeInfo.currentValue);
-    EXPECT_TRUE(std::find(modeInfo.modes.begin(), modeInfo.modes.end(), "NONE")
-                != modeInfo.modes.end());
-  }
-}
-
-TEST_F(TestApiBlackSolver, getUnsatAssumptions1)
-{
-  d_solver.setOption("incremental", "false");
-  d_solver.checkSatAssuming(d_solver.mkFalse());
-  ASSERT_THROW(d_solver.getUnsatAssumptions(), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, getUnsatAssumptions2)
-{
-  d_solver.setOption("incremental", "true");
-  d_solver.setOption("produce-unsat-assumptions", "false");
-  d_solver.checkSatAssuming(d_solver.mkFalse());
-  ASSERT_THROW(d_solver.getUnsatAssumptions(), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, getUnsatAssumptions3)
-{
-  d_solver.setOption("incremental", "true");
-  d_solver.setOption("produce-unsat-assumptions", "true");
-  d_solver.checkSatAssuming(d_solver.mkFalse());
-  ASSERT_NO_THROW(d_solver.getUnsatAssumptions());
-  d_solver.checkSatAssuming(d_solver.mkTrue());
-  ASSERT_THROW(d_solver.getUnsatAssumptions(), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, getUnsatCore1)
-{
-  d_solver.setOption("incremental", "false");
-  d_solver.assertFormula(d_solver.mkFalse());
-  d_solver.checkSat();
-  ASSERT_THROW(d_solver.getUnsatCore(), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, getUnsatCore2)
-{
-  d_solver.setOption("incremental", "false");
-  d_solver.setOption("produce-unsat-cores", "false");
-  d_solver.assertFormula(d_solver.mkFalse());
-  d_solver.checkSat();
-  ASSERT_THROW(d_solver.getUnsatCore(), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, getUnsatCoreAndProof)
-{
-  d_solver.setOption("incremental", "true");
-  d_solver.setOption("produce-unsat-cores", "true");
-  d_solver.setOption("produce-proofs", "true");
-
-  Sort uSort = d_solver.mkUninterpretedSort("u");
-  Sort intSort = d_solver.getIntegerSort();
-  Sort boolSort = d_solver.getBooleanSort();
-  Sort uToIntSort = d_solver.mkFunctionSort(uSort, intSort);
-  Sort intPredSort = d_solver.mkFunctionSort(intSort, boolSort);
-  std::vector<Term> unsat_core;
-
-  Term x = d_solver.mkConst(uSort, "x");
-  Term y = d_solver.mkConst(uSort, "y");
-  Term f = d_solver.mkConst(uToIntSort, "f");
-  Term p = d_solver.mkConst(intPredSort, "p");
-  Term zero = d_solver.mkInteger(0);
-  Term one = d_solver.mkInteger(1);
-  Term f_x = d_solver.mkTerm(APPLY_UF, f, x);
-  Term f_y = d_solver.mkTerm(APPLY_UF, f, y);
-  Term sum = d_solver.mkTerm(PLUS, f_x, f_y);
-  Term p_0 = d_solver.mkTerm(APPLY_UF, p, zero);
-  Term p_f_y = d_solver.mkTerm(APPLY_UF, p, f_y);
-  d_solver.assertFormula(d_solver.mkTerm(GT, zero, f_x));
-  d_solver.assertFormula(d_solver.mkTerm(GT, zero, f_y));
-  d_solver.assertFormula(d_solver.mkTerm(GT, sum, one));
-  d_solver.assertFormula(p_0);
-  d_solver.assertFormula(p_f_y.notTerm());
-  ASSERT_TRUE(d_solver.checkSat().isUnsat());
-
-  ASSERT_NO_THROW(unsat_core = d_solver.getUnsatCore());
-
-  ASSERT_NO_THROW(d_solver.getProof());
-
-  d_solver.resetAssertions();
-  for (const auto& t : unsat_core)
-  {
-    d_solver.assertFormula(t);
-  }
-  cvc5::api::Result res = d_solver.checkSat();
-  ASSERT_TRUE(res.isUnsat());
-  ASSERT_NO_THROW(d_solver.getProof());
-}
-
-TEST_F(TestApiBlackSolver, getDifficulty)
-{
-  d_solver.setOption("produce-difficulty", "true");
-  // cannot ask before a check sat
-  ASSERT_THROW(d_solver.getDifficulty(), CVC5ApiException);
-  d_solver.checkSat();
-  ASSERT_NO_THROW(d_solver.getDifficulty());
-}
-
-TEST_F(TestApiBlackSolver, getDifficulty2)
-{
-  d_solver.checkSat();
-  // option is not set
-  ASSERT_THROW(d_solver.getDifficulty(), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, getDifficulty3)
-{
-  d_solver.setOption("produce-difficulty", "true");
-  Sort intSort = d_solver.getIntegerSort();
-  Term x = d_solver.mkConst(intSort, "x");
-  Term zero = d_solver.mkInteger(0);
-  Term ten = d_solver.mkInteger(10);
-  Term f0 = d_solver.mkTerm(GEQ, x, ten);
-  Term f1 = d_solver.mkTerm(GEQ, zero, x);
-  d_solver.checkSat();
-  std::map<Term, Term> dmap;
-  ASSERT_NO_THROW(dmap = d_solver.getDifficulty());
-  // difficulty should map assertions to integer values
-  for (const std::pair<const Term, Term>& t : dmap)
-  {
-    ASSERT_TRUE(t.first == f0 || t.first == f1);
-    ASSERT_TRUE(t.second.getKind() == CONST_RATIONAL);
-  }
-}
-
-TEST_F(TestApiBlackSolver, getValue1)
-{
-  d_solver.setOption("produce-models", "false");
-  Term t = d_solver.mkTrue();
-  d_solver.assertFormula(t);
-  d_solver.checkSat();
-  ASSERT_THROW(d_solver.getValue(t), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, getValue2)
-{
-  d_solver.setOption("produce-models", "true");
-  Term t = d_solver.mkFalse();
-  d_solver.assertFormula(t);
-  d_solver.checkSat();
-  ASSERT_THROW(d_solver.getValue(t), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, getValue3)
-{
-  d_solver.setOption("produce-models", "true");
-  Sort uSort = d_solver.mkUninterpretedSort("u");
-  Sort intSort = d_solver.getIntegerSort();
-  Sort boolSort = d_solver.getBooleanSort();
-  Sort uToIntSort = d_solver.mkFunctionSort(uSort, intSort);
-  Sort intPredSort = d_solver.mkFunctionSort(intSort, boolSort);
-  std::vector<Term> unsat_core;
-
-  Term x = d_solver.mkConst(uSort, "x");
-  Term y = d_solver.mkConst(uSort, "y");
-  Term z = d_solver.mkConst(uSort, "z");
-  Term f = d_solver.mkConst(uToIntSort, "f");
-  Term p = d_solver.mkConst(intPredSort, "p");
-  Term zero = d_solver.mkInteger(0);
-  Term one = d_solver.mkInteger(1);
-  Term f_x = d_solver.mkTerm(APPLY_UF, f, x);
-  Term f_y = d_solver.mkTerm(APPLY_UF, f, y);
-  Term sum = d_solver.mkTerm(PLUS, f_x, f_y);
-  Term p_0 = d_solver.mkTerm(APPLY_UF, p, zero);
-  Term p_f_y = d_solver.mkTerm(APPLY_UF, p, f_y);
-
-  d_solver.assertFormula(d_solver.mkTerm(LEQ, zero, f_x));
-  d_solver.assertFormula(d_solver.mkTerm(LEQ, zero, f_y));
-  d_solver.assertFormula(d_solver.mkTerm(LEQ, sum, one));
-  d_solver.assertFormula(p_0.notTerm());
-  d_solver.assertFormula(p_f_y);
-  ASSERT_TRUE(d_solver.checkSat().isSat());
-  ASSERT_NO_THROW(d_solver.getValue(x));
-  ASSERT_NO_THROW(d_solver.getValue(y));
-  ASSERT_NO_THROW(d_solver.getValue(z));
-  ASSERT_NO_THROW(d_solver.getValue(sum));
-  ASSERT_NO_THROW(d_solver.getValue(p_f_y));
-
-  Solver slv;
-  ASSERT_THROW(slv.getValue(x), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, getModelDomainElements)
-{
-  d_solver.setOption("produce-models", "true");
-  Sort uSort = d_solver.mkUninterpretedSort("u");
-  Sort intSort = d_solver.getIntegerSort();
-  Term x = d_solver.mkConst(uSort, "x");
-  Term y = d_solver.mkConst(uSort, "y");
-  Term z = d_solver.mkConst(uSort, "z");
-  Term f = d_solver.mkTerm(DISTINCT, x, y, z);
-  d_solver.assertFormula(f);
-  d_solver.checkSat();
-  ASSERT_NO_THROW(d_solver.getModelDomainElements(uSort));
-  ASSERT_TRUE(d_solver.getModelDomainElements(uSort).size() >= 3);
-  ASSERT_THROW(d_solver.getModelDomainElements(intSort), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, getModelDomainElements2)
-{
-  d_solver.setOption("produce-models", "true");
-  d_solver.setOption("finite-model-find", "true");
-  Sort uSort = d_solver.mkUninterpretedSort("u");
-  Term x = d_solver.mkVar(uSort, "x");
-  Term y = d_solver.mkVar(uSort, "y");
-  Term eq = d_solver.mkTerm(EQUAL, x, y);
-  Term bvl = d_solver.mkTerm(BOUND_VAR_LIST, x, y);
-  Term f = d_solver.mkTerm(FORALL, bvl, eq);
-  d_solver.assertFormula(f);
-  d_solver.checkSat();
-  ASSERT_NO_THROW(d_solver.getModelDomainElements(uSort));
-  // a model for the above must interpret u as size 1
-  ASSERT_TRUE(d_solver.getModelDomainElements(uSort).size() == 1);
-}
-
-TEST_F(TestApiBlackSolver, isModelCoreSymbol)
-{
-  d_solver.setOption("produce-models", "true");
-  d_solver.setOption("model-cores", "simple");
-  Sort uSort = d_solver.mkUninterpretedSort("u");
-  Term x = d_solver.mkConst(uSort, "x");
-  Term y = d_solver.mkConst(uSort, "y");
-  Term z = d_solver.mkConst(uSort, "z");
-  Term zero = d_solver.mkInteger(0);
-  Term f = d_solver.mkTerm(NOT, d_solver.mkTerm(EQUAL, x, y));
-  d_solver.assertFormula(f);
-  d_solver.checkSat();
-  ASSERT_TRUE(d_solver.isModelCoreSymbol(x));
-  ASSERT_TRUE(d_solver.isModelCoreSymbol(y));
-  ASSERT_FALSE(d_solver.isModelCoreSymbol(z));
-  ASSERT_THROW(d_solver.isModelCoreSymbol(zero), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, getModel)
-{
-  d_solver.setOption("produce-models", "true");
-  Sort uSort = d_solver.mkUninterpretedSort("u");
-  Term x = d_solver.mkConst(uSort, "x");
-  Term y = d_solver.mkConst(uSort, "y");
-  Term z = d_solver.mkConst(uSort, "z");
-  Term f = d_solver.mkTerm(NOT, d_solver.mkTerm(EQUAL, x, y));
-  d_solver.assertFormula(f);
-  d_solver.checkSat();
-  std::vector<Sort> sorts;
-  sorts.push_back(uSort);
-  std::vector<Term> terms;
-  terms.push_back(x);
-  terms.push_back(y);
-  ASSERT_NO_THROW(d_solver.getModel(sorts, terms));
-  Term null;
-  terms.push_back(null);
-  ASSERT_THROW(d_solver.getModel(sorts, terms), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, getModel2)
-{
-  d_solver.setOption("produce-models", "true");
-  std::vector<Sort> sorts;
-  std::vector<Term> terms;
-  ASSERT_THROW(d_solver.getModel(sorts, terms), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, getModel3)
-{
-  d_solver.setOption("produce-models", "true");
-  std::vector<Sort> sorts;
-  std::vector<Term> terms;
-  d_solver.checkSat();
-  ASSERT_NO_THROW(d_solver.getModel(sorts, terms));
-  Sort integer = d_solver.getIntegerSort();
-  sorts.push_back(integer);
-  ASSERT_THROW(d_solver.getModel(sorts, terms), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, getQuantifierElimination)
-{
-  Term x = d_solver.mkVar(d_solver.getBooleanSort(), "x");
-  Term forall =
-      d_solver.mkTerm(FORALL,
-                      d_solver.mkTerm(BOUND_VAR_LIST, x),
-                      d_solver.mkTerm(OR, x, d_solver.mkTerm(NOT, x)));
-  ASSERT_THROW(d_solver.getQuantifierElimination(Term()), CVC5ApiException);
-  ASSERT_THROW(d_solver.getQuantifierElimination(Solver().mkBoolean(false)),
-               CVC5ApiException);
-  ASSERT_NO_THROW(d_solver.getQuantifierElimination(forall));
-}
-
-TEST_F(TestApiBlackSolver, getQuantifierEliminationDisjunct)
-{
-  Term x = d_solver.mkVar(d_solver.getBooleanSort(), "x");
-  Term forall =
-      d_solver.mkTerm(FORALL,
-                      d_solver.mkTerm(BOUND_VAR_LIST, x),
-                      d_solver.mkTerm(OR, x, d_solver.mkTerm(NOT, x)));
-  ASSERT_THROW(d_solver.getQuantifierEliminationDisjunct(Term()),
-               CVC5ApiException);
-  ASSERT_THROW(
-      d_solver.getQuantifierEliminationDisjunct(Solver().mkBoolean(false)),
-      CVC5ApiException);
-  ASSERT_NO_THROW(d_solver.getQuantifierEliminationDisjunct(forall));
-}
-
-TEST_F(TestApiBlackSolver, declareSepHeap)
-{
-  d_solver.setLogic("ALL");
-  Sort integer = d_solver.getIntegerSort();
-  ASSERT_NO_THROW(d_solver.declareSepHeap(integer, integer));
-  // cannot declare separation logic heap more than once
-  ASSERT_THROW(d_solver.declareSepHeap(integer, integer), CVC5ApiException);
-}
-
-namespace {
-/**
- * Helper function for testGetSeparation{Heap,Nil}TermX. Asserts and checks
- * some simple separation logic constraints.
- */
-void checkSimpleSeparationConstraints(Solver* solver)
-{
-  Sort integer = solver->getIntegerSort();
-  // declare the separation heap
-  solver->declareSepHeap(integer, integer);
-  Term x = solver->mkConst(integer, "x");
-  Term p = solver->mkConst(integer, "p");
-  Term heap = solver->mkTerm(cvc5::api::Kind::SEP_PTO, p, x);
-  solver->assertFormula(heap);
-  Term nil = solver->mkSepNil(integer);
-  solver->assertFormula(nil.eqTerm(solver->mkReal(5)));
-  solver->checkSat();
-}
-}  // namespace
-
-TEST_F(TestApiBlackSolver, getValueSepHeap1)
-{
-  d_solver.setLogic("QF_BV");
-  d_solver.setOption("incremental", "false");
-  d_solver.setOption("produce-models", "true");
-  Term t = d_solver.mkTrue();
-  d_solver.assertFormula(t);
-  ASSERT_THROW(d_solver.getValueSepHeap(), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, getValueSepHeap2)
-{
-  d_solver.setLogic("ALL");
-  d_solver.setOption("incremental", "false");
-  d_solver.setOption("produce-models", "false");
-  checkSimpleSeparationConstraints(&d_solver);
-  ASSERT_THROW(d_solver.getValueSepHeap(), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, getValueSepHeap3)
-{
-  d_solver.setLogic("ALL");
-  d_solver.setOption("incremental", "false");
-  d_solver.setOption("produce-models", "true");
-  Term t = d_solver.mkFalse();
-  d_solver.assertFormula(t);
-  d_solver.checkSat();
-  ASSERT_THROW(d_solver.getValueSepHeap(), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, getValueSepHeap4)
-{
-  d_solver.setLogic("ALL");
-  d_solver.setOption("incremental", "false");
-  d_solver.setOption("produce-models", "true");
-  Term t = d_solver.mkTrue();
-  d_solver.assertFormula(t);
-  d_solver.checkSat();
-  ASSERT_THROW(d_solver.getValueSepHeap(), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, getValueSepHeap5)
-{
-  d_solver.setLogic("ALL");
-  d_solver.setOption("incremental", "false");
-  d_solver.setOption("produce-models", "true");
-  checkSimpleSeparationConstraints(&d_solver);
-  ASSERT_NO_THROW(d_solver.getValueSepHeap());
-}
-
-TEST_F(TestApiBlackSolver, getValueSepNil1)
-{
-  d_solver.setLogic("QF_BV");
-  d_solver.setOption("incremental", "false");
-  d_solver.setOption("produce-models", "true");
-  Term t = d_solver.mkTrue();
-  d_solver.assertFormula(t);
-  ASSERT_THROW(d_solver.getValueSepNil(), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, getValueSepNil2)
-{
-  d_solver.setLogic("ALL");
-  d_solver.setOption("incremental", "false");
-  d_solver.setOption("produce-models", "false");
-  checkSimpleSeparationConstraints(&d_solver);
-  ASSERT_THROW(d_solver.getValueSepNil(), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, getValueSepNil3)
-{
-  d_solver.setLogic("ALL");
-  d_solver.setOption("incremental", "false");
-  d_solver.setOption("produce-models", "true");
-  Term t = d_solver.mkFalse();
-  d_solver.assertFormula(t);
-  d_solver.checkSat();
-  ASSERT_THROW(d_solver.getValueSepNil(), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, getValueSepNil4)
-{
-  d_solver.setLogic("ALL");
-  d_solver.setOption("incremental", "false");
-  d_solver.setOption("produce-models", "true");
-  Term t = d_solver.mkTrue();
-  d_solver.assertFormula(t);
-  d_solver.checkSat();
-  ASSERT_THROW(d_solver.getValueSepNil(), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, getValueSepNil5)
-{
-  d_solver.setLogic("ALL");
-  d_solver.setOption("incremental", "false");
-  d_solver.setOption("produce-models", "true");
-  checkSimpleSeparationConstraints(&d_solver);
-  ASSERT_NO_THROW(d_solver.getValueSepNil());
-}
-
-TEST_F(TestApiBlackSolver, push1)
-{
-  d_solver.setOption("incremental", "true");
-  ASSERT_NO_THROW(d_solver.push(1));
-  ASSERT_THROW(d_solver.setOption("incremental", "false"), CVC5ApiException);
-  ASSERT_THROW(d_solver.setOption("incremental", "true"), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, push2)
-{
-  d_solver.setOption("incremental", "false");
-  ASSERT_THROW(d_solver.push(1), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, pop1)
-{
-  d_solver.setOption("incremental", "false");
-  ASSERT_THROW(d_solver.pop(1), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, pop2)
-{
-  d_solver.setOption("incremental", "true");
-  ASSERT_THROW(d_solver.pop(1), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, pop3)
-{
-  d_solver.setOption("incremental", "true");
-  ASSERT_NO_THROW(d_solver.push(1));
-  ASSERT_NO_THROW(d_solver.pop(1));
-  ASSERT_THROW(d_solver.pop(1), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, blockModel1)
-{
-  d_solver.setOption("produce-models", "true");
-  Term x = d_solver.mkConst(d_solver.getBooleanSort(), "x");
-  d_solver.assertFormula(x.eqTerm(x));
-  d_solver.checkSat();
-  ASSERT_THROW(d_solver.blockModel(), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, blockModel2)
-{
-  d_solver.setOption("block-models", "literals");
-  Term x = d_solver.mkConst(d_solver.getBooleanSort(), "x");
-  d_solver.assertFormula(x.eqTerm(x));
-  d_solver.checkSat();
-  ASSERT_THROW(d_solver.blockModel(), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, blockModel3)
-{
-  d_solver.setOption("produce-models", "true");
-  d_solver.setOption("block-models", "literals");
-  Term x = d_solver.mkConst(d_solver.getBooleanSort(), "x");
-  d_solver.assertFormula(x.eqTerm(x));
-  ASSERT_THROW(d_solver.blockModel(), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, blockModel4)
-{
-  d_solver.setOption("produce-models", "true");
-  d_solver.setOption("block-models", "literals");
-  Term x = d_solver.mkConst(d_solver.getBooleanSort(), "x");
-  d_solver.assertFormula(x.eqTerm(x));
-  d_solver.checkSat();
-  ASSERT_NO_THROW(d_solver.blockModel());
-}
-
-TEST_F(TestApiBlackSolver, blockModelValues1)
-{
-  d_solver.setOption("produce-models", "true");
-  d_solver.setOption("block-models", "literals");
-  Term x = d_solver.mkConst(d_solver.getBooleanSort(), "x");
-  d_solver.assertFormula(x.eqTerm(x));
-  d_solver.checkSat();
-  ASSERT_THROW(d_solver.blockModelValues({}), CVC5ApiException);
-  ASSERT_THROW(d_solver.blockModelValues({Term()}), CVC5ApiException);
-  ASSERT_THROW(d_solver.blockModelValues({Solver().mkBoolean(false)}),
-               CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, blockModelValues2)
-{
-  d_solver.setOption("produce-models", "true");
-  Term x = d_solver.mkConst(d_solver.getBooleanSort(), "x");
-  d_solver.assertFormula(x.eqTerm(x));
-  d_solver.checkSat();
-  ASSERT_THROW(d_solver.blockModelValues({x}), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, blockModelValues3)
-{
-  d_solver.setOption("block-models", "literals");
-  Term x = d_solver.mkConst(d_solver.getBooleanSort(), "x");
-  d_solver.assertFormula(x.eqTerm(x));
-  d_solver.checkSat();
-  ASSERT_THROW(d_solver.blockModelValues({x}), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, blockModelValues4)
-{
-  d_solver.setOption("produce-models", "true");
-  d_solver.setOption("block-models", "literals");
-  Term x = d_solver.mkConst(d_solver.getBooleanSort(), "x");
-  d_solver.assertFormula(x.eqTerm(x));
-  ASSERT_THROW(d_solver.blockModelValues({x}), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, blockModelValues5)
-{
-  d_solver.setOption("produce-models", "true");
-  d_solver.setOption("block-models", "literals");
-  Term x = d_solver.mkConst(d_solver.getBooleanSort(), "x");
-  d_solver.assertFormula(x.eqTerm(x));
-  d_solver.checkSat();
-  ASSERT_NO_THROW(d_solver.blockModelValues({x}));
-}
-
-TEST_F(TestApiBlackSolver, setInfo)
-{
-  ASSERT_THROW(d_solver.setInfo("cvc5-lagic", "QF_BV"), CVC5ApiException);
-  ASSERT_THROW(d_solver.setInfo("cvc2-logic", "QF_BV"), CVC5ApiException);
-  ASSERT_THROW(d_solver.setInfo("cvc5-logic", "asdf"), CVC5ApiException);
-
-  ASSERT_NO_THROW(d_solver.setInfo("source", "asdf"));
-  ASSERT_NO_THROW(d_solver.setInfo("category", "asdf"));
-  ASSERT_NO_THROW(d_solver.setInfo("difficulty", "asdf"));
-  ASSERT_NO_THROW(d_solver.setInfo("filename", "asdf"));
-  ASSERT_NO_THROW(d_solver.setInfo("license", "asdf"));
-  ASSERT_NO_THROW(d_solver.setInfo("name", "asdf"));
-  ASSERT_NO_THROW(d_solver.setInfo("notes", "asdf"));
-
-  ASSERT_NO_THROW(d_solver.setInfo("smt-lib-version", "2"));
-  ASSERT_NO_THROW(d_solver.setInfo("smt-lib-version", "2.0"));
-  ASSERT_NO_THROW(d_solver.setInfo("smt-lib-version", "2.5"));
-  ASSERT_NO_THROW(d_solver.setInfo("smt-lib-version", "2.6"));
-  ASSERT_THROW(d_solver.setInfo("smt-lib-version", ".0"), CVC5ApiException);
-
-  ASSERT_NO_THROW(d_solver.setInfo("status", "sat"));
-  ASSERT_NO_THROW(d_solver.setInfo("status", "unsat"));
-  ASSERT_NO_THROW(d_solver.setInfo("status", "unknown"));
-  ASSERT_THROW(d_solver.setInfo("status", "asdf"), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, simplify)
-{
-  ASSERT_THROW(d_solver.simplify(Term()), CVC5ApiException);
-
-  Sort bvSort = d_solver.mkBitVectorSort(32);
-  Sort uSort = d_solver.mkUninterpretedSort("u");
-  Sort funSort1 = d_solver.mkFunctionSort({bvSort, bvSort}, bvSort);
-  Sort funSort2 = d_solver.mkFunctionSort(uSort, d_solver.getIntegerSort());
-  DatatypeDecl consListSpec = d_solver.mkDatatypeDecl("list");
-  DatatypeConstructorDecl cons = d_solver.mkDatatypeConstructorDecl("cons");
-  cons.addSelector("head", d_solver.getIntegerSort());
-  cons.addSelectorSelf("tail");
-  consListSpec.addConstructor(cons);
-  DatatypeConstructorDecl nil = d_solver.mkDatatypeConstructorDecl("nil");
-  consListSpec.addConstructor(nil);
-  Sort consListSort = d_solver.mkDatatypeSort(consListSpec);
-
-  Term x = d_solver.mkConst(bvSort, "x");
-  ASSERT_NO_THROW(d_solver.simplify(x));
-  Term a = d_solver.mkConst(bvSort, "a");
-  ASSERT_NO_THROW(d_solver.simplify(a));
-  Term b = d_solver.mkConst(bvSort, "b");
-  ASSERT_NO_THROW(d_solver.simplify(b));
-  Term x_eq_x = d_solver.mkTerm(EQUAL, x, x);
-  ASSERT_NO_THROW(d_solver.simplify(x_eq_x));
-  ASSERT_NE(d_solver.mkTrue(), x_eq_x);
-  ASSERT_EQ(d_solver.mkTrue(), d_solver.simplify(x_eq_x));
-  Term x_eq_b = d_solver.mkTerm(EQUAL, x, b);
-  ASSERT_NO_THROW(d_solver.simplify(x_eq_b));
-  ASSERT_NE(d_solver.mkTrue(), x_eq_b);
-  ASSERT_NE(d_solver.mkTrue(), d_solver.simplify(x_eq_b));
-  Solver slv;
-  ASSERT_THROW(slv.simplify(x), CVC5ApiException);
-
-  Term i1 = d_solver.mkConst(d_solver.getIntegerSort(), "i1");
-  ASSERT_NO_THROW(d_solver.simplify(i1));
-  Term i2 = d_solver.mkTerm(MULT, i1, d_solver.mkInteger("23"));
-  ASSERT_NO_THROW(d_solver.simplify(i2));
-  ASSERT_NE(i1, i2);
-  ASSERT_NE(i1, d_solver.simplify(i2));
-  Term i3 = d_solver.mkTerm(PLUS, i1, d_solver.mkInteger(0));
-  ASSERT_NO_THROW(d_solver.simplify(i3));
-  ASSERT_NE(i1, i3);
-  ASSERT_EQ(i1, d_solver.simplify(i3));
-
-  Datatype consList = consListSort.getDatatype();
-  Term dt1 = d_solver.mkTerm(
-      APPLY_CONSTRUCTOR,
-      consList.getConstructorTerm("cons"),
-      d_solver.mkInteger(0),
-      d_solver.mkTerm(APPLY_CONSTRUCTOR, consList.getConstructorTerm("nil")));
-  ASSERT_NO_THROW(d_solver.simplify(dt1));
-  Term dt2 = d_solver.mkTerm(
-      APPLY_SELECTOR, consList["cons"].getSelectorTerm("head"), dt1);
-  ASSERT_NO_THROW(d_solver.simplify(dt2));
-
-  Term b1 = d_solver.mkVar(bvSort, "b1");
-  ASSERT_NO_THROW(d_solver.simplify(b1));
-  Term b2 = d_solver.mkVar(bvSort, "b1");
-  ASSERT_NO_THROW(d_solver.simplify(b2));
-  Term b3 = d_solver.mkVar(uSort, "b3");
-  ASSERT_NO_THROW(d_solver.simplify(b3));
-  Term v1 = d_solver.mkConst(bvSort, "v1");
-  ASSERT_NO_THROW(d_solver.simplify(v1));
-  Term v2 = d_solver.mkConst(d_solver.getIntegerSort(), "v2");
-  ASSERT_NO_THROW(d_solver.simplify(v2));
-  Term f1 = d_solver.mkConst(funSort1, "f1");
-  ASSERT_NO_THROW(d_solver.simplify(f1));
-  Term f2 = d_solver.mkConst(funSort2, "f2");
-  ASSERT_NO_THROW(d_solver.simplify(f2));
-  d_solver.defineFunsRec({f1, f2}, {{b1, b2}, {b3}}, {v1, v2});
-  ASSERT_NO_THROW(d_solver.simplify(f1));
-  ASSERT_NO_THROW(d_solver.simplify(f2));
-}
-
-TEST_F(TestApiBlackSolver, assertFormula)
-{
-  ASSERT_NO_THROW(d_solver.assertFormula(d_solver.mkTrue()));
-  ASSERT_THROW(d_solver.assertFormula(Term()), CVC5ApiException);
-  Solver slv;
-  ASSERT_THROW(slv.assertFormula(d_solver.mkTrue()), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, checkEntailed)
-{
-  d_solver.setOption("incremental", "false");
-  ASSERT_NO_THROW(d_solver.checkEntailed(d_solver.mkTrue()));
-  ASSERT_THROW(d_solver.checkEntailed(d_solver.mkTrue()), CVC5ApiException);
-  Solver slv;
-  ASSERT_THROW(slv.checkEntailed(d_solver.mkTrue()), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, checkEntailed1)
-{
-  Sort boolSort = d_solver.getBooleanSort();
-  Term x = d_solver.mkConst(boolSort, "x");
-  Term y = d_solver.mkConst(boolSort, "y");
-  Term z = d_solver.mkTerm(AND, x, y);
-  d_solver.setOption("incremental", "true");
-  ASSERT_NO_THROW(d_solver.checkEntailed(d_solver.mkTrue()));
-  ASSERT_THROW(d_solver.checkEntailed(Term()), CVC5ApiException);
-  ASSERT_NO_THROW(d_solver.checkEntailed(d_solver.mkTrue()));
-  ASSERT_NO_THROW(d_solver.checkEntailed(z));
-  Solver slv;
-  ASSERT_THROW(slv.checkEntailed(d_solver.mkTrue()), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, checkEntailed2)
-{
-  d_solver.setOption("incremental", "true");
-
-  Sort uSort = d_solver.mkUninterpretedSort("u");
-  Sort intSort = d_solver.getIntegerSort();
-  Sort boolSort = d_solver.getBooleanSort();
-  Sort uToIntSort = d_solver.mkFunctionSort(uSort, intSort);
-  Sort intPredSort = d_solver.mkFunctionSort(intSort, boolSort);
-
-  Term n = Term();
-  // Constants
-  Term x = d_solver.mkConst(uSort, "x");
-  Term y = d_solver.mkConst(uSort, "y");
-  // Functions
-  Term f = d_solver.mkConst(uToIntSort, "f");
-  Term p = d_solver.mkConst(intPredSort, "p");
-  // Values
-  Term zero = d_solver.mkInteger(0);
-  Term one = d_solver.mkInteger(1);
-  // Terms
-  Term f_x = d_solver.mkTerm(APPLY_UF, f, x);
-  Term f_y = d_solver.mkTerm(APPLY_UF, f, y);
-  Term sum = d_solver.mkTerm(PLUS, f_x, f_y);
-  Term p_0 = d_solver.mkTerm(APPLY_UF, p, zero);
-  Term p_f_y = d_solver.mkTerm(APPLY_UF, p, f_y);
-  // Assertions
-  Term assertions =
-      d_solver.mkTerm(AND,
-                      std::vector<Term>{
-                          d_solver.mkTerm(LEQ, zero, f_x),  // 0 <= f(x)
-                          d_solver.mkTerm(LEQ, zero, f_y),  // 0 <= f(y)
-                          d_solver.mkTerm(LEQ, sum, one),   // f(x) + f(y) <= 1
-                          p_0.notTerm(),                    // not p(0)
-                          p_f_y                             // p(f(y))
-                      });
-
-  ASSERT_NO_THROW(d_solver.checkEntailed(d_solver.mkTrue()));
-  d_solver.assertFormula(assertions);
-  ASSERT_NO_THROW(d_solver.checkEntailed(d_solver.mkTerm(DISTINCT, x, y)));
-  ASSERT_NO_THROW(d_solver.checkEntailed(
-      {d_solver.mkFalse(), d_solver.mkTerm(DISTINCT, x, y)}));
-  ASSERT_THROW(d_solver.checkEntailed(n), CVC5ApiException);
-  ASSERT_THROW(d_solver.checkEntailed({n, d_solver.mkTerm(DISTINCT, x, y)}),
-               CVC5ApiException);
-  Solver slv;
-  ASSERT_THROW(slv.checkEntailed(d_solver.mkTrue()), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, checkSat)
-{
-  d_solver.setOption("incremental", "false");
-  ASSERT_NO_THROW(d_solver.checkSat());
-  ASSERT_THROW(d_solver.checkSat(), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, checkSatAssuming)
-{
-  d_solver.setOption("incremental", "false");
-  ASSERT_NO_THROW(d_solver.checkSatAssuming(d_solver.mkTrue()));
-  ASSERT_THROW(d_solver.checkSatAssuming(d_solver.mkTrue()), CVC5ApiException);
-  Solver slv;
-  ASSERT_THROW(slv.checkSatAssuming(d_solver.mkTrue()), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, checkSatAssuming1)
-{
-  Sort boolSort = d_solver.getBooleanSort();
-  Term x = d_solver.mkConst(boolSort, "x");
-  Term y = d_solver.mkConst(boolSort, "y");
-  Term z = d_solver.mkTerm(AND, x, y);
-  d_solver.setOption("incremental", "true");
-  ASSERT_NO_THROW(d_solver.checkSatAssuming(d_solver.mkTrue()));
-  ASSERT_THROW(d_solver.checkSatAssuming(Term()), CVC5ApiException);
-  ASSERT_NO_THROW(d_solver.checkSatAssuming(d_solver.mkTrue()));
-  ASSERT_NO_THROW(d_solver.checkSatAssuming(z));
-  Solver slv;
-  ASSERT_THROW(slv.checkSatAssuming(d_solver.mkTrue()), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, checkSatAssuming2)
-{
-  d_solver.setOption("incremental", "true");
-
-  Sort uSort = d_solver.mkUninterpretedSort("u");
-  Sort intSort = d_solver.getIntegerSort();
-  Sort boolSort = d_solver.getBooleanSort();
-  Sort uToIntSort = d_solver.mkFunctionSort(uSort, intSort);
-  Sort intPredSort = d_solver.mkFunctionSort(intSort, boolSort);
-
-  Term n = Term();
-  // Constants
-  Term x = d_solver.mkConst(uSort, "x");
-  Term y = d_solver.mkConst(uSort, "y");
-  // Functions
-  Term f = d_solver.mkConst(uToIntSort, "f");
-  Term p = d_solver.mkConst(intPredSort, "p");
-  // Values
-  Term zero = d_solver.mkInteger(0);
-  Term one = d_solver.mkInteger(1);
-  // Terms
-  Term f_x = d_solver.mkTerm(APPLY_UF, f, x);
-  Term f_y = d_solver.mkTerm(APPLY_UF, f, y);
-  Term sum = d_solver.mkTerm(PLUS, f_x, f_y);
-  Term p_0 = d_solver.mkTerm(APPLY_UF, p, zero);
-  Term p_f_y = d_solver.mkTerm(APPLY_UF, p, f_y);
-  // Assertions
-  Term assertions =
-      d_solver.mkTerm(AND,
-                      std::vector<Term>{
-                          d_solver.mkTerm(LEQ, zero, f_x),  // 0 <= f(x)
-                          d_solver.mkTerm(LEQ, zero, f_y),  // 0 <= f(y)
-                          d_solver.mkTerm(LEQ, sum, one),   // f(x) + f(y) <= 1
-                          p_0.notTerm(),                    // not p(0)
-                          p_f_y                             // p(f(y))
-                      });
-
-  ASSERT_NO_THROW(d_solver.checkSatAssuming(d_solver.mkTrue()));
-  d_solver.assertFormula(assertions);
-  ASSERT_NO_THROW(d_solver.checkSatAssuming(d_solver.mkTerm(DISTINCT, x, y)));
-  ASSERT_NO_THROW(d_solver.checkSatAssuming(
-      {d_solver.mkFalse(), d_solver.mkTerm(DISTINCT, x, y)}));
-  ASSERT_THROW(d_solver.checkSatAssuming(n), CVC5ApiException);
-  ASSERT_THROW(d_solver.checkSatAssuming({n, d_solver.mkTerm(DISTINCT, x, y)}),
-               CVC5ApiException);
-  Solver slv;
-  ASSERT_THROW(slv.checkSatAssuming(d_solver.mkTrue()), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, setLogic)
-{
-  ASSERT_NO_THROW(d_solver.setLogic("AUFLIRA"));
-  ASSERT_THROW(d_solver.setLogic("AF_BV"), CVC5ApiException);
-  d_solver.assertFormula(d_solver.mkTrue());
-  ASSERT_THROW(d_solver.setLogic("AUFLIRA"), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, setOption)
-{
-  ASSERT_NO_THROW(d_solver.setOption("bv-sat-solver", "minisat"));
-  ASSERT_THROW(d_solver.setOption("bv-sat-solver", "1"), CVC5ApiException);
-  d_solver.assertFormula(d_solver.mkTrue());
-  ASSERT_THROW(d_solver.setOption("bv-sat-solver", "minisat"),
-               CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, resetAssertions)
-{
-  d_solver.setOption("incremental", "true");
-
-  Sort bvSort = d_solver.mkBitVectorSort(4);
-  Term one = d_solver.mkBitVector(4, 1);
-  Term x = d_solver.mkConst(bvSort, "x");
-  Term ule = d_solver.mkTerm(BITVECTOR_ULE, x, one);
-  Term srem = d_solver.mkTerm(BITVECTOR_SREM, one, x);
-  d_solver.push(4);
-  Term slt = d_solver.mkTerm(BITVECTOR_SLT, srem, one);
-  d_solver.resetAssertions();
-  d_solver.checkSatAssuming({slt, ule});
-}
-
-TEST_F(TestApiBlackSolver, mkSygusVar)
-{
-  Sort boolSort = d_solver.getBooleanSort();
-  Sort intSort = d_solver.getIntegerSort();
-  Sort funSort = d_solver.mkFunctionSort(intSort, boolSort);
-
-  ASSERT_NO_THROW(d_solver.mkSygusVar(boolSort));
-  ASSERT_NO_THROW(d_solver.mkSygusVar(funSort));
-  ASSERT_NO_THROW(d_solver.mkSygusVar(boolSort, std::string("b")));
-  ASSERT_NO_THROW(d_solver.mkSygusVar(funSort, ""));
-  ASSERT_THROW(d_solver.mkSygusVar(Sort()), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkSygusVar(d_solver.getNullSort(), "a"),
-               CVC5ApiException);
-  Solver slv;
-  ASSERT_THROW(slv.mkSygusVar(boolSort), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, mkSygusGrammar)
-{
-  Term nullTerm;
-  Term boolTerm = d_solver.mkBoolean(true);
-  Term boolVar = d_solver.mkVar(d_solver.getBooleanSort());
-  Term intVar = d_solver.mkVar(d_solver.getIntegerSort());
-
-  ASSERT_NO_THROW(d_solver.mkSygusGrammar({}, {intVar}));
-  ASSERT_NO_THROW(d_solver.mkSygusGrammar({boolVar}, {intVar}));
-  ASSERT_THROW(d_solver.mkSygusGrammar({}, {}), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkSygusGrammar({}, {nullTerm}), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkSygusGrammar({}, {boolTerm}), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkSygusGrammar({boolTerm}, {intVar}), CVC5ApiException);
-  Solver slv;
-  Term boolVar2 = slv.mkVar(slv.getBooleanSort());
-  Term intVar2 = slv.mkVar(slv.getIntegerSort());
-  ASSERT_NO_THROW(slv.mkSygusGrammar({boolVar2}, {intVar2}));
-  ASSERT_THROW(slv.mkSygusGrammar({boolVar}, {intVar2}), CVC5ApiException);
-  ASSERT_THROW(slv.mkSygusGrammar({boolVar2}, {intVar}), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, synthFun)
-{
-  Sort null = d_solver.getNullSort();
-  Sort boolean = d_solver.getBooleanSort();
-  Sort integer = d_solver.getIntegerSort();
-
-  Term nullTerm;
-  Term x = d_solver.mkVar(boolean);
-
-  Term start1 = d_solver.mkVar(boolean);
-  Term start2 = d_solver.mkVar(integer);
-
-  Grammar g1 = d_solver.mkSygusGrammar({x}, {start1});
-  g1.addRule(start1, d_solver.mkBoolean(false));
-
-  Grammar g2 = d_solver.mkSygusGrammar({x}, {start2});
-  g2.addRule(start2, d_solver.mkInteger(0));
-
-  ASSERT_NO_THROW(d_solver.synthFun("", {}, boolean));
-  ASSERT_NO_THROW(d_solver.synthFun("f1", {x}, boolean));
-  ASSERT_NO_THROW(d_solver.synthFun("f2", {x}, boolean, g1));
-
-  ASSERT_THROW(d_solver.synthFun("f3", {nullTerm}, boolean), CVC5ApiException);
-  ASSERT_THROW(d_solver.synthFun("f4", {}, null), CVC5ApiException);
-  ASSERT_THROW(d_solver.synthFun("f6", {x}, boolean, g2), CVC5ApiException);
-  Solver slv;
-  Term x2 = slv.mkVar(slv.getBooleanSort());
-  ASSERT_NO_THROW(slv.synthFun("f1", {x2}, slv.getBooleanSort()));
-  ASSERT_THROW(slv.synthFun("", {}, d_solver.getBooleanSort()),
-               CVC5ApiException);
-  ASSERT_THROW(slv.synthFun("f1", {x}, d_solver.getBooleanSort()),
-               CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, synthInv)
-{
-  Sort boolean = d_solver.getBooleanSort();
-  Sort integer = d_solver.getIntegerSort();
-
-  Term nullTerm;
-  Term x = d_solver.mkVar(boolean);
-
-  Term start1 = d_solver.mkVar(boolean);
-  Term start2 = d_solver.mkVar(integer);
-
-  Grammar g1 = d_solver.mkSygusGrammar({x}, {start1});
-  g1.addRule(start1, d_solver.mkBoolean(false));
-
-  Grammar g2 = d_solver.mkSygusGrammar({x}, {start2});
-  g2.addRule(start2, d_solver.mkInteger(0));
-
-  ASSERT_NO_THROW(d_solver.synthInv("", {}));
-  ASSERT_NO_THROW(d_solver.synthInv("i1", {x}));
-  ASSERT_NO_THROW(d_solver.synthInv("i2", {x}, g1));
-
-  ASSERT_THROW(d_solver.synthInv("i3", {nullTerm}), CVC5ApiException);
-  ASSERT_THROW(d_solver.synthInv("i4", {x}, g2), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, addSygusConstraint)
-{
-  Term nullTerm;
-  Term boolTerm = d_solver.mkBoolean(true);
-  Term intTerm = d_solver.mkInteger(1);
-
-  ASSERT_NO_THROW(d_solver.addSygusConstraint(boolTerm));
-  ASSERT_THROW(d_solver.addSygusConstraint(nullTerm), CVC5ApiException);
-  ASSERT_THROW(d_solver.addSygusConstraint(intTerm), CVC5ApiException);
-
-  Solver slv;
-  ASSERT_THROW(slv.addSygusConstraint(boolTerm), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, addSygusAssume)
-{
-  Term nullTerm;
-  Term boolTerm = d_solver.mkBoolean(false);
-  Term intTerm = d_solver.mkInteger(1);
-
-  ASSERT_NO_THROW(d_solver.addSygusAssume(boolTerm));
-  ASSERT_THROW(d_solver.addSygusAssume(nullTerm), CVC5ApiException);
-  ASSERT_THROW(d_solver.addSygusAssume(intTerm), CVC5ApiException);
-
-  Solver slv;
-  ASSERT_THROW(slv.addSygusAssume(boolTerm), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, addSygusInvConstraint)
-{
-  Sort boolean = d_solver.getBooleanSort();
-  Sort real = d_solver.getRealSort();
-
-  Term nullTerm;
-  Term intTerm = d_solver.mkInteger(1);
-
-  Term inv = d_solver.declareFun("inv", {real}, boolean);
-  Term pre = d_solver.declareFun("pre", {real}, boolean);
-  Term trans = d_solver.declareFun("trans", {real, real}, boolean);
-  Term post = d_solver.declareFun("post", {real}, boolean);
-
-  Term inv1 = d_solver.declareFun("inv1", {real}, real);
-
-  Term trans1 = d_solver.declareFun("trans1", {boolean, real}, boolean);
-  Term trans2 = d_solver.declareFun("trans2", {real, boolean}, boolean);
-  Term trans3 = d_solver.declareFun("trans3", {real, real}, real);
-
-  ASSERT_NO_THROW(d_solver.addSygusInvConstraint(inv, pre, trans, post));
-
-  ASSERT_THROW(d_solver.addSygusInvConstraint(nullTerm, pre, trans, post),
-               CVC5ApiException);
-  ASSERT_THROW(d_solver.addSygusInvConstraint(inv, nullTerm, trans, post),
-               CVC5ApiException);
-  ASSERT_THROW(d_solver.addSygusInvConstraint(inv, pre, nullTerm, post),
-               CVC5ApiException);
-  ASSERT_THROW(d_solver.addSygusInvConstraint(inv, pre, trans, nullTerm),
-               CVC5ApiException);
-
-  ASSERT_THROW(d_solver.addSygusInvConstraint(intTerm, pre, trans, post),
-               CVC5ApiException);
-
-  ASSERT_THROW(d_solver.addSygusInvConstraint(inv1, pre, trans, post),
-               CVC5ApiException);
-
-  ASSERT_THROW(d_solver.addSygusInvConstraint(inv, trans, trans, post),
-               CVC5ApiException);
-
-  ASSERT_THROW(d_solver.addSygusInvConstraint(inv, pre, intTerm, post),
-               CVC5ApiException);
-  ASSERT_THROW(d_solver.addSygusInvConstraint(inv, pre, pre, post),
-               CVC5ApiException);
-  ASSERT_THROW(d_solver.addSygusInvConstraint(inv, pre, trans1, post),
-               CVC5ApiException);
-  ASSERT_THROW(d_solver.addSygusInvConstraint(inv, pre, trans2, post),
-               CVC5ApiException);
-  ASSERT_THROW(d_solver.addSygusInvConstraint(inv, pre, trans3, post),
-               CVC5ApiException);
-
-  ASSERT_THROW(d_solver.addSygusInvConstraint(inv, pre, trans, trans),
-               CVC5ApiException);
-  Solver slv;
-  Sort boolean2 = slv.getBooleanSort();
-  Sort real2 = slv.getRealSort();
-  Term inv22 = slv.declareFun("inv", {real2}, boolean2);
-  Term pre22 = slv.declareFun("pre", {real2}, boolean2);
-  Term trans22 = slv.declareFun("trans", {real2, real2}, boolean2);
-  Term post22 = slv.declareFun("post", {real2}, boolean2);
-  ASSERT_NO_THROW(slv.addSygusInvConstraint(inv22, pre22, trans22, post22));
-  ASSERT_THROW(slv.addSygusInvConstraint(inv, pre22, trans22, post22),
-               CVC5ApiException);
-  ASSERT_THROW(slv.addSygusInvConstraint(inv22, pre, trans22, post22),
-               CVC5ApiException);
-  ASSERT_THROW(slv.addSygusInvConstraint(inv22, pre22, trans, post22),
-               CVC5ApiException);
-  ASSERT_THROW(slv.addSygusInvConstraint(inv22, pre22, trans22, post),
-               CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, getSynthSolution)
-{
-  d_solver.setOption("lang", "sygus2");
-  d_solver.setOption("incremental", "false");
-
-  Term nullTerm;
-  Term x = d_solver.mkBoolean(false);
-  Term f = d_solver.synthFun("f", {}, d_solver.getBooleanSort());
-
-  ASSERT_THROW(d_solver.getSynthSolution(f), CVC5ApiException);
-
-  d_solver.checkSynth();
-
-  ASSERT_NO_THROW(d_solver.getSynthSolution(f));
-  ASSERT_NO_THROW(d_solver.getSynthSolution(f));
-
-  ASSERT_THROW(d_solver.getSynthSolution(nullTerm), CVC5ApiException);
-  ASSERT_THROW(d_solver.getSynthSolution(x), CVC5ApiException);
-
-  Solver slv;
-  ASSERT_THROW(slv.getSynthSolution(f), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, getSynthSolutions)
-{
-  d_solver.setOption("lang", "sygus2");
-  d_solver.setOption("incremental", "false");
-
-  Term nullTerm;
-  Term x = d_solver.mkBoolean(false);
-  Term f = d_solver.synthFun("f", {}, d_solver.getBooleanSort());
-
-  ASSERT_THROW(d_solver.getSynthSolutions({}), CVC5ApiException);
-  ASSERT_THROW(d_solver.getSynthSolutions({f}), CVC5ApiException);
-
-  d_solver.checkSynth();
-
-  ASSERT_NO_THROW(d_solver.getSynthSolutions({f}));
-  ASSERT_NO_THROW(d_solver.getSynthSolutions({f, f}));
-
-  ASSERT_THROW(d_solver.getSynthSolutions({}), CVC5ApiException);
-  ASSERT_THROW(d_solver.getSynthSolutions({nullTerm}), CVC5ApiException);
-  ASSERT_THROW(d_solver.getSynthSolutions({x}), CVC5ApiException);
-
-  Solver slv;
-  ASSERT_THROW(slv.getSynthSolutions({x}), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, tupleProject)
-{
-  std::vector<Sort> sorts = {d_solver.getBooleanSort(),
-                             d_solver.getIntegerSort(),
-                             d_solver.getStringSort(),
-                             d_solver.mkSetSort(d_solver.getStringSort())};
-  std::vector<Term> elements = {
-      d_solver.mkBoolean(true),
-      d_solver.mkInteger(3),
-      d_solver.mkString("C"),
-      d_solver.mkTerm(SET_SINGLETON, d_solver.mkString("Z"))};
-
-  Term tuple = d_solver.mkTuple(sorts, elements);
-
-  std::vector<uint32_t> indices1 = {};
-  std::vector<uint32_t> indices2 = {0};
-  std::vector<uint32_t> indices3 = {0, 1};
-  std::vector<uint32_t> indices4 = {0, 0, 2, 2, 3, 3, 0};
-  std::vector<uint32_t> indices5 = {4};
-  std::vector<uint32_t> indices6 = {0, 4};
-
-  ASSERT_NO_THROW(
-      d_solver.mkTerm(d_solver.mkOp(TUPLE_PROJECT, indices1), tuple));
-  ASSERT_NO_THROW(
-      d_solver.mkTerm(d_solver.mkOp(TUPLE_PROJECT, indices2), tuple));
-  ASSERT_NO_THROW(
-      d_solver.mkTerm(d_solver.mkOp(TUPLE_PROJECT, indices3), tuple));
-  ASSERT_NO_THROW(
-      d_solver.mkTerm(d_solver.mkOp(TUPLE_PROJECT, indices4), tuple));
-
-  ASSERT_THROW(d_solver.mkTerm(d_solver.mkOp(TUPLE_PROJECT, indices5), tuple),
-               CVC5ApiException);
-  ASSERT_THROW(d_solver.mkTerm(d_solver.mkOp(TUPLE_PROJECT, indices6), tuple),
-               CVC5ApiException);
-
-  std::vector<uint32_t> indices = {0, 3, 2, 0, 1, 2};
-
-  Op op = d_solver.mkOp(TUPLE_PROJECT, indices);
-  Term projection = d_solver.mkTerm(op, tuple);
-
-  Datatype datatype = tuple.getSort().getDatatype();
-  DatatypeConstructor constructor = datatype[0];
-
-  for (size_t i = 0; i < indices.size(); i++)
-  {
-    Term selectorTerm = constructor[indices[i]].getSelectorTerm();
-    Term selectedTerm = d_solver.mkTerm(APPLY_SELECTOR, selectorTerm, tuple);
-    Term simplifiedTerm = d_solver.simplify(selectedTerm);
-    ASSERT_EQ(elements[indices[i]], simplifiedTerm);
-  }
-
-  ASSERT_EQ(
-      "((_ tuple_project 0 3 2 0 1 2) (tuple true 3 \"C\" (set.singleton "
-      "\"Z\")))",
-      projection.toString());
-}
-
-TEST_F(TestApiBlackSolver, Output)
-{
-  ASSERT_THROW(d_solver.isOutputOn("foo-invalid"), CVC5ApiException);
-  ASSERT_THROW(d_solver.getOutput("foo-invalid"), CVC5ApiException);
-  ASSERT_FALSE(d_solver.isOutputOn("inst"));
-  ASSERT_EQ(cvc5::null_os.rdbuf(), d_solver.getOutput("inst").rdbuf());
-  d_solver.setOption("output", "inst");
-  ASSERT_TRUE(d_solver.isOutputOn("inst"));
-  ASSERT_NE(cvc5::null_os.rdbuf(), d_solver.getOutput("inst").rdbuf());
-}
-
-
-TEST_F(TestApiBlackSolver, issue7000)
-{
-  Sort s1 = d_solver.getIntegerSort();
-  Sort s2 = d_solver.mkFunctionSort(s1, s1);
-  Sort s3 = d_solver.getRealSort();
-  Term t4 = d_solver.mkPi();
-  Term t7 = d_solver.mkConst(s3, "_x5");
-  Term t37 = d_solver.mkConst(s2, "_x32");
-  Term t59 = d_solver.mkConst(s2, "_x51");
-  Term t72 = d_solver.mkTerm(EQUAL, t37, t59);
-  Term t74 = d_solver.mkTerm(GT, t4, t7);
-  // throws logic exception since logic is not higher order by default
-  ASSERT_THROW(d_solver.checkEntailed({t72, t74, t72, t72}), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSolver, issue5893)
-{
-  Solver slv;
-  Sort bvsort4 = d_solver.mkBitVectorSort(4);
-  Sort bvsort8 = d_solver.mkBitVectorSort(8);
-  Sort arrsort = d_solver.mkArraySort(bvsort4, bvsort8);
-  Term arr = d_solver.mkConst(arrsort, "arr");
-  Term idx = d_solver.mkConst(bvsort4, "idx");
-  Term ten = d_solver.mkBitVector(8, "10", 10);
-  Term sel = d_solver.mkTerm(SELECT, arr, idx);
-  Term distinct = d_solver.mkTerm(DISTINCT, sel, ten);
-  ASSERT_NO_FATAL_FAILURE(distinct.getOp());
-}
-
-}  // namespace test
-}  // namespace cvc5
diff --git a/test/unit/api/solver_white.cpp b/test/unit/api/solver_white.cpp
deleted file mode 100644 (file)
index 5d7b9ea..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/******************************************************************************
- * Top contributors (to current version):
- *   Aina Niemetz, Makai Mann, Andrew Reynolds
- *
- * This file is part of the cvc5 project.
- *
- * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
- * in the top-level source directory and their institutional affiliations.
- * All rights reserved.  See the file COPYING in the top-level source
- * directory for licensing information.
- * ****************************************************************************
- *
- * Black box testing of the Solver class of the  C++ API.
- */
-
-#include "base/configuration.h"
-#include "test_api.h"
-
-namespace cvc5 {
-
-using namespace api;
-
-namespace test {
-
-class TestApiWhiteSolver : public TestApi
-{
-};
-
-TEST_F(TestApiWhiteSolver, getOp)
-{
-  DatatypeDecl consListSpec = d_solver.mkDatatypeDecl("list");
-  DatatypeConstructorDecl cons = d_solver.mkDatatypeConstructorDecl("cons");
-  cons.addSelector("head", d_solver.getIntegerSort());
-  cons.addSelectorSelf("tail");
-  consListSpec.addConstructor(cons);
-  DatatypeConstructorDecl nil = d_solver.mkDatatypeConstructorDecl("nil");
-  consListSpec.addConstructor(nil);
-  Sort consListSort = d_solver.mkDatatypeSort(consListSpec);
-  Datatype consList = consListSort.getDatatype();
-
-  Term nilTerm = consList.getConstructorTerm("nil");
-  Term consTerm = consList.getConstructorTerm("cons");
-  Term headTerm = consList["cons"].getSelectorTerm("head");
-
-  Term listnil = d_solver.mkTerm(APPLY_CONSTRUCTOR, nilTerm);
-  Term listcons1 = d_solver.mkTerm(
-      APPLY_CONSTRUCTOR, consTerm, d_solver.mkInteger(1), listnil);
-  Term listhead = d_solver.mkTerm(APPLY_SELECTOR, headTerm, listcons1);
-
-  ASSERT_EQ(listnil.getOp(), Op(&d_solver, APPLY_CONSTRUCTOR));
-  ASSERT_EQ(listcons1.getOp(), Op(&d_solver, APPLY_CONSTRUCTOR));
-  ASSERT_EQ(listhead.getOp(), Op(&d_solver, APPLY_SELECTOR));
-}
-
-}  // namespace test
-}  // namespace cvc5
diff --git a/test/unit/api/sort_black.cpp b/test/unit/api/sort_black.cpp
deleted file mode 100644 (file)
index d0c755c..0000000
+++ /dev/null
@@ -1,612 +0,0 @@
-/******************************************************************************
- * Top contributors (to current version):
- *   Aina Niemetz, Andrew Reynolds, Mathias Preiner
- *
- * This file is part of the cvc5 project.
- *
- * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
- * in the top-level source directory and their institutional affiliations.
- * All rights reserved.  See the file COPYING in the top-level source
- * directory for licensing information.
- * ****************************************************************************
- *
- * Black box testing of the guards of the C++ API functions.
- */
-
-#include "test_api.h"
-
-namespace cvc5 {
-
-using namespace api;
-
-namespace test {
-
-class TestApiBlackSort : public TestApi
-{
- protected:
-  Sort create_datatype_sort()
-  {
-    DatatypeDecl dtypeSpec = d_solver.mkDatatypeDecl("list");
-    DatatypeConstructorDecl cons = d_solver.mkDatatypeConstructorDecl("cons");
-    cons.addSelector("head", d_solver.getIntegerSort());
-    cons.addSelectorSelf("tail");
-    dtypeSpec.addConstructor(cons);
-    DatatypeConstructorDecl nil = d_solver.mkDatatypeConstructorDecl("nil");
-    dtypeSpec.addConstructor(nil);
-    return d_solver.mkDatatypeSort(dtypeSpec);
-  }
-
-  Sort create_param_datatype_sort()
-  {
-    Sort sort = d_solver.mkParamSort("T");
-    DatatypeDecl paramDtypeSpec = d_solver.mkDatatypeDecl("paramlist", sort);
-    DatatypeConstructorDecl paramCons =
-        d_solver.mkDatatypeConstructorDecl("cons");
-    DatatypeConstructorDecl paramNil =
-        d_solver.mkDatatypeConstructorDecl("nil");
-    paramCons.addSelector("head", sort);
-    paramDtypeSpec.addConstructor(paramCons);
-    paramDtypeSpec.addConstructor(paramNil);
-    return d_solver.mkDatatypeSort(paramDtypeSpec);
-  }
-};
-
-TEST_F(TestApiBlackSort, operators_comparison)
-{
-  ASSERT_NO_THROW(d_solver.getIntegerSort() == Sort());
-  ASSERT_NO_THROW(d_solver.getIntegerSort() != Sort());
-  ASSERT_NO_THROW(d_solver.getIntegerSort() < Sort());
-  ASSERT_NO_THROW(d_solver.getIntegerSort() <= Sort());
-  ASSERT_NO_THROW(d_solver.getIntegerSort() > Sort());
-  ASSERT_NO_THROW(d_solver.getIntegerSort() >= Sort());
-}
-
-TEST_F(TestApiBlackSort, isNull)
-{
-  Sort x;
-  ASSERT_TRUE(x.isNull());
-  x = d_solver.getBooleanSort();
-  ASSERT_FALSE(x.isNull());
-}
-
-TEST_F(TestApiBlackSort, isBoolean)
-{
-  ASSERT_TRUE(d_solver.getBooleanSort().isBoolean());
-  ASSERT_NO_THROW(Sort().isBoolean());
-}
-
-TEST_F(TestApiBlackSort, isInteger)
-{
-  ASSERT_TRUE(d_solver.getIntegerSort().isInteger());
-  ASSERT_TRUE(!d_solver.getRealSort().isInteger());
-  ASSERT_NO_THROW(Sort().isInteger());
-}
-
-TEST_F(TestApiBlackSort, isReal)
-{
-  ASSERT_TRUE(d_solver.getRealSort().isReal());
-  ASSERT_TRUE(!d_solver.getIntegerSort().isReal());
-  ASSERT_NO_THROW(Sort().isReal());
-}
-
-TEST_F(TestApiBlackSort, isString)
-{
-  ASSERT_TRUE(d_solver.getStringSort().isString());
-  ASSERT_NO_THROW(Sort().isString());
-}
-
-TEST_F(TestApiBlackSort, isRegExp)
-{
-  ASSERT_TRUE(d_solver.getRegExpSort().isRegExp());
-  ASSERT_NO_THROW(Sort().isRegExp());
-}
-
-TEST_F(TestApiBlackSort, isRoundingMode)
-{
-  ASSERT_TRUE(d_solver.getRoundingModeSort().isRoundingMode());
-  ASSERT_NO_THROW(Sort().isRoundingMode());
-}
-
-TEST_F(TestApiBlackSort, isBitVector)
-{
-  ASSERT_TRUE(d_solver.mkBitVectorSort(8).isBitVector());
-  ASSERT_NO_THROW(Sort().isBitVector());
-}
-
-TEST_F(TestApiBlackSort, isFloatingPoint)
-{
-  ASSERT_TRUE(d_solver.mkFloatingPointSort(8, 24).isFloatingPoint());
-  ASSERT_NO_THROW(Sort().isFloatingPoint());
-}
-
-TEST_F(TestApiBlackSort, isDatatype)
-{
-  Sort dt_sort = create_datatype_sort();
-  ASSERT_TRUE(dt_sort.isDatatype());
-  ASSERT_NO_THROW(Sort().isDatatype());
-}
-
-TEST_F(TestApiBlackSort, isParametricDatatype)
-{
-  Sort param_dt_sort = create_param_datatype_sort();
-  ASSERT_TRUE(param_dt_sort.isParametricDatatype());
-  ASSERT_NO_THROW(Sort().isParametricDatatype());
-}
-
-TEST_F(TestApiBlackSort, isConstructor)
-{
-  Sort dt_sort = create_datatype_sort();
-  Datatype dt = dt_sort.getDatatype();
-  Sort cons_sort = dt[0].getConstructorTerm().getSort();
-  ASSERT_TRUE(cons_sort.isConstructor());
-  ASSERT_NO_THROW(Sort().isConstructor());
-}
-
-TEST_F(TestApiBlackSort, isSelector)
-{
-  Sort dt_sort = create_datatype_sort();
-  Datatype dt = dt_sort.getDatatype();
-  Sort cons_sort = dt[0][1].getSelectorTerm().getSort();
-  ASSERT_TRUE(cons_sort.isSelector());
-  ASSERT_NO_THROW(Sort().isSelector());
-}
-
-TEST_F(TestApiBlackSort, isTester)
-{
-  Sort dt_sort = create_datatype_sort();
-  Datatype dt = dt_sort.getDatatype();
-  Sort testerSort = dt[0].getTesterTerm().getSort();
-  ASSERT_TRUE(testerSort.isTester());
-  ASSERT_NO_THROW(Sort().isTester());
-}
-
-TEST_F(TestApiBlackSort, isUpdater)
-{
-  Sort dt_sort = create_datatype_sort();
-  Datatype dt = dt_sort.getDatatype();
-  Sort updaterSort = dt[0][0].getUpdaterTerm().getSort();
-  ASSERT_TRUE(updaterSort.isUpdater());
-  ASSERT_NO_THROW(Sort().isUpdater());
-}
-
-TEST_F(TestApiBlackSort, isFunction)
-{
-  Sort fun_sort = d_solver.mkFunctionSort(d_solver.getRealSort(),
-                                          d_solver.getIntegerSort());
-  ASSERT_TRUE(fun_sort.isFunction());
-  ASSERT_NO_THROW(Sort().isFunction());
-}
-
-TEST_F(TestApiBlackSort, isPredicate)
-{
-  Sort pred_sort = d_solver.mkPredicateSort({d_solver.getRealSort()});
-  ASSERT_TRUE(pred_sort.isPredicate());
-  ASSERT_NO_THROW(Sort().isPredicate());
-}
-
-TEST_F(TestApiBlackSort, isTuple)
-{
-  Sort tup_sort = d_solver.mkTupleSort({d_solver.getRealSort()});
-  ASSERT_TRUE(tup_sort.isTuple());
-  ASSERT_NO_THROW(Sort().isTuple());
-}
-
-TEST_F(TestApiBlackSort, isRecord)
-{
-  Sort rec_sort =
-      d_solver.mkRecordSort({std::make_pair("asdf", d_solver.getRealSort())});
-  ASSERT_TRUE(rec_sort.isRecord());
-  ASSERT_NO_THROW(Sort().isRecord());
-}
-
-TEST_F(TestApiBlackSort, isArray)
-{
-  Sort arr_sort =
-      d_solver.mkArraySort(d_solver.getRealSort(), d_solver.getIntegerSort());
-  ASSERT_TRUE(arr_sort.isArray());
-  ASSERT_NO_THROW(Sort().isArray());
-}
-
-TEST_F(TestApiBlackSort, isSet)
-{
-  Sort set_sort = d_solver.mkSetSort(d_solver.getRealSort());
-  ASSERT_TRUE(set_sort.isSet());
-  ASSERT_NO_THROW(Sort().isSet());
-}
-
-TEST_F(TestApiBlackSort, isBag)
-{
-  Sort bag_sort = d_solver.mkBagSort(d_solver.getRealSort());
-  ASSERT_TRUE(bag_sort.isBag());
-  ASSERT_NO_THROW(Sort().isBag());
-}
-
-TEST_F(TestApiBlackSort, isSequence)
-{
-  Sort seq_sort = d_solver.mkSequenceSort(d_solver.getRealSort());
-  ASSERT_TRUE(seq_sort.isSequence());
-  ASSERT_NO_THROW(Sort().isSequence());
-}
-
-TEST_F(TestApiBlackSort, isUninterpreted)
-{
-  Sort un_sort = d_solver.mkUninterpretedSort("asdf");
-  ASSERT_TRUE(un_sort.isUninterpretedSort());
-  ASSERT_NO_THROW(Sort().isUninterpretedSort());
-}
-
-TEST_F(TestApiBlackSort, isSortConstructor)
-{
-  Sort sc_sort = d_solver.mkSortConstructorSort("asdf", 1);
-  ASSERT_TRUE(sc_sort.isSortConstructor());
-  ASSERT_NO_THROW(Sort().isSortConstructor());
-}
-
-TEST_F(TestApiBlackSort, isFirstClass)
-{
-  Sort fun_sort = d_solver.mkFunctionSort(d_solver.getRealSort(),
-                                          d_solver.getIntegerSort());
-  ASSERT_TRUE(d_solver.getIntegerSort().isFirstClass());
-  ASSERT_TRUE(fun_sort.isFirstClass());
-  Sort reSort = d_solver.getRegExpSort();
-  ASSERT_FALSE(reSort.isFirstClass());
-  ASSERT_NO_THROW(Sort().isFirstClass());
-}
-
-TEST_F(TestApiBlackSort, isFunctionLike)
-{
-  Sort fun_sort = d_solver.mkFunctionSort(d_solver.getRealSort(),
-                                          d_solver.getIntegerSort());
-  ASSERT_FALSE(d_solver.getIntegerSort().isFunctionLike());
-  ASSERT_TRUE(fun_sort.isFunctionLike());
-
-  Sort dt_sort = create_datatype_sort();
-  Datatype dt = dt_sort.getDatatype();
-  Sort cons_sort = dt[0][1].getSelectorTerm().getSort();
-  ASSERT_TRUE(cons_sort.isFunctionLike());
-
-  ASSERT_NO_THROW(Sort().isFunctionLike());
-}
-
-TEST_F(TestApiBlackSort, isSubsortOf)
-{
-  ASSERT_TRUE(d_solver.getIntegerSort().isSubsortOf(d_solver.getIntegerSort()));
-  ASSERT_TRUE(d_solver.getIntegerSort().isSubsortOf(d_solver.getRealSort()));
-  ASSERT_FALSE(
-      d_solver.getIntegerSort().isSubsortOf(d_solver.getBooleanSort()));
-  ASSERT_NO_THROW(Sort().isSubsortOf(Sort()));
-}
-
-TEST_F(TestApiBlackSort, isComparableTo)
-{
-  ASSERT_TRUE(
-      d_solver.getIntegerSort().isComparableTo(d_solver.getIntegerSort()));
-  ASSERT_TRUE(d_solver.getIntegerSort().isComparableTo(d_solver.getRealSort()));
-  ASSERT_FALSE(
-      d_solver.getIntegerSort().isComparableTo(d_solver.getBooleanSort()));
-  ASSERT_NO_THROW(Sort().isComparableTo(Sort()));
-}
-
-TEST_F(TestApiBlackSort, getDatatype)
-{
-  Sort dtypeSort = create_datatype_sort();
-  ASSERT_NO_THROW(dtypeSort.getDatatype());
-  // create bv sort, check should fail
-  Sort bvSort = d_solver.mkBitVectorSort(32);
-  ASSERT_THROW(bvSort.getDatatype(), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSort, datatypeSorts)
-{
-  Sort intSort = d_solver.getIntegerSort();
-  Sort dtypeSort = create_datatype_sort();
-  Datatype dt = dtypeSort.getDatatype();
-  ASSERT_FALSE(dtypeSort.isConstructor());
-  ASSERT_THROW(dtypeSort.getConstructorCodomainSort(), CVC5ApiException);
-  ASSERT_THROW(dtypeSort.getConstructorDomainSorts(), CVC5ApiException);
-  ASSERT_THROW(dtypeSort.getConstructorArity(), CVC5ApiException);
-
-  // get constructor
-  DatatypeConstructor dcons = dt[0];
-  Term consTerm = dcons.getConstructorTerm();
-  Sort consSort = consTerm.getSort();
-  ASSERT_TRUE(consSort.isConstructor());
-  ASSERT_FALSE(consSort.isTester());
-  ASSERT_FALSE(consSort.isSelector());
-  ASSERT_EQ(consSort.getConstructorArity(), 2);
-  std::vector<Sort> consDomSorts = consSort.getConstructorDomainSorts();
-  ASSERT_EQ(consDomSorts[0], intSort);
-  ASSERT_EQ(consDomSorts[1], dtypeSort);
-  ASSERT_EQ(consSort.getConstructorCodomainSort(), dtypeSort);
-
-  // get tester
-  Term isConsTerm = dcons.getTesterTerm();
-  ASSERT_TRUE(isConsTerm.getSort().isTester());
-  ASSERT_EQ(isConsTerm.getSort().getTesterDomainSort(), dtypeSort);
-  Sort booleanSort = d_solver.getBooleanSort();
-  ASSERT_EQ(isConsTerm.getSort().getTesterCodomainSort(), booleanSort);
-  ASSERT_THROW(booleanSort.getTesterDomainSort(), CVC5ApiException);
-  ASSERT_THROW(booleanSort.getTesterCodomainSort(), CVC5ApiException);
-
-  // get selector
-  DatatypeSelector dselTail = dcons[1];
-  Term tailTerm = dselTail.getSelectorTerm();
-  ASSERT_TRUE(tailTerm.getSort().isSelector());
-  ASSERT_EQ(tailTerm.getSort().getSelectorDomainSort(), dtypeSort);
-  ASSERT_EQ(tailTerm.getSort().getSelectorCodomainSort(), dtypeSort);
-  ASSERT_THROW(booleanSort.getSelectorDomainSort(), CVC5ApiException);
-  ASSERT_THROW(booleanSort.getSelectorCodomainSort(), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSort, instantiate)
-{
-  // instantiate parametric datatype, check should not fail
-  Sort paramDtypeSort = create_param_datatype_sort();
-  ASSERT_NO_THROW(
-      paramDtypeSort.instantiate(std::vector<Sort>{d_solver.getIntegerSort()}));
-  // instantiate non-parametric datatype sort, check should fail
-  DatatypeDecl dtypeSpec = d_solver.mkDatatypeDecl("list");
-  DatatypeConstructorDecl cons = d_solver.mkDatatypeConstructorDecl("cons");
-  cons.addSelector("head", d_solver.getIntegerSort());
-  dtypeSpec.addConstructor(cons);
-  DatatypeConstructorDecl nil = d_solver.mkDatatypeConstructorDecl("nil");
-  dtypeSpec.addConstructor(nil);
-  Sort dtypeSort = d_solver.mkDatatypeSort(dtypeSpec);
-  ASSERT_THROW(
-      dtypeSort.instantiate(std::vector<Sort>{d_solver.getIntegerSort()}),
-      CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSort, getFunctionArity)
-{
-  Sort funSort = d_solver.mkFunctionSort(d_solver.mkUninterpretedSort("u"),
-                                         d_solver.getIntegerSort());
-  ASSERT_NO_THROW(funSort.getFunctionArity());
-  Sort bvSort = d_solver.mkBitVectorSort(32);
-  ASSERT_THROW(bvSort.getFunctionArity(), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSort, getFunctionDomainSorts)
-{
-  Sort funSort = d_solver.mkFunctionSort(d_solver.mkUninterpretedSort("u"),
-                                         d_solver.getIntegerSort());
-  ASSERT_NO_THROW(funSort.getFunctionDomainSorts());
-  Sort bvSort = d_solver.mkBitVectorSort(32);
-  ASSERT_THROW(bvSort.getFunctionDomainSorts(), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSort, getFunctionCodomainSort)
-{
-  Sort funSort = d_solver.mkFunctionSort(d_solver.mkUninterpretedSort("u"),
-                                         d_solver.getIntegerSort());
-  ASSERT_NO_THROW(funSort.getFunctionCodomainSort());
-  Sort bvSort = d_solver.mkBitVectorSort(32);
-  ASSERT_THROW(bvSort.getFunctionCodomainSort(), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSort, getArrayIndexSort)
-{
-  Sort elementSort = d_solver.mkBitVectorSort(32);
-  Sort indexSort = d_solver.mkBitVectorSort(32);
-  Sort arraySort = d_solver.mkArraySort(indexSort, elementSort);
-  ASSERT_NO_THROW(arraySort.getArrayIndexSort());
-  ASSERT_THROW(indexSort.getArrayIndexSort(), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSort, getArrayElementSort)
-{
-  Sort elementSort = d_solver.mkBitVectorSort(32);
-  Sort indexSort = d_solver.mkBitVectorSort(32);
-  Sort arraySort = d_solver.mkArraySort(indexSort, elementSort);
-  ASSERT_NO_THROW(arraySort.getArrayElementSort());
-  ASSERT_THROW(indexSort.getArrayElementSort(), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSort, getSetElementSort)
-{
-  Sort setSort = d_solver.mkSetSort(d_solver.getIntegerSort());
-  ASSERT_NO_THROW(setSort.getSetElementSort());
-  Sort elementSort = setSort.getSetElementSort();
-  ASSERT_EQ(elementSort, d_solver.getIntegerSort());
-  Sort bvSort = d_solver.mkBitVectorSort(32);
-  ASSERT_THROW(bvSort.getSetElementSort(), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSort, getBagElementSort)
-{
-  Sort bagSort = d_solver.mkBagSort(d_solver.getIntegerSort());
-  ASSERT_NO_THROW(bagSort.getBagElementSort());
-  Sort elementSort = bagSort.getBagElementSort();
-  ASSERT_EQ(elementSort, d_solver.getIntegerSort());
-  Sort bvSort = d_solver.mkBitVectorSort(32);
-  ASSERT_THROW(bvSort.getBagElementSort(), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSort, getSequenceElementSort)
-{
-  Sort seqSort = d_solver.mkSequenceSort(d_solver.getIntegerSort());
-  ASSERT_TRUE(seqSort.isSequence());
-  ASSERT_NO_THROW(seqSort.getSequenceElementSort());
-  Sort bvSort = d_solver.mkBitVectorSort(32);
-  ASSERT_FALSE(bvSort.isSequence());
-  ASSERT_THROW(bvSort.getSequenceElementSort(), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSort, getUninterpretedSortName)
-{
-  Sort uSort = d_solver.mkUninterpretedSort("u");
-  ASSERT_NO_THROW(uSort.getUninterpretedSortName());
-  Sort bvSort = d_solver.mkBitVectorSort(32);
-  ASSERT_THROW(bvSort.getUninterpretedSortName(), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSort, isUninterpretedSortParameterized)
-{
-  Sort uSort = d_solver.mkUninterpretedSort("u");
-  ASSERT_FALSE(uSort.isUninterpretedSortParameterized());
-  Sort sSort = d_solver.mkSortConstructorSort("s", 1);
-  Sort siSort = sSort.instantiate({uSort});
-  ASSERT_TRUE(siSort.isUninterpretedSortParameterized());
-  Sort bvSort = d_solver.mkBitVectorSort(32);
-  ASSERT_THROW(bvSort.isUninterpretedSortParameterized(), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSort, getUninterpretedSortParamSorts)
-{
-  Sort uSort = d_solver.mkUninterpretedSort("u");
-  ASSERT_NO_THROW(uSort.getUninterpretedSortParamSorts());
-  Sort sSort = d_solver.mkSortConstructorSort("s", 2);
-  Sort siSort = sSort.instantiate({uSort, uSort});
-  ASSERT_EQ(siSort.getUninterpretedSortParamSorts().size(), 2);
-  Sort bvSort = d_solver.mkBitVectorSort(32);
-  ASSERT_THROW(bvSort.getUninterpretedSortParamSorts(), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSort, getUninterpretedSortConstructorName)
-{
-  Sort sSort = d_solver.mkSortConstructorSort("s", 2);
-  ASSERT_NO_THROW(sSort.getSortConstructorName());
-  Sort bvSort = d_solver.mkBitVectorSort(32);
-  ASSERT_THROW(bvSort.getSortConstructorName(), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSort, getUninterpretedSortConstructorArity)
-{
-  Sort sSort = d_solver.mkSortConstructorSort("s", 2);
-  ASSERT_NO_THROW(sSort.getSortConstructorArity());
-  Sort bvSort = d_solver.mkBitVectorSort(32);
-  ASSERT_THROW(bvSort.getSortConstructorArity(), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSort, getBitVectorSize)
-{
-  Sort bvSort = d_solver.mkBitVectorSort(32);
-  ASSERT_NO_THROW(bvSort.getBitVectorSize());
-  Sort setSort = d_solver.mkSetSort(d_solver.getIntegerSort());
-  ASSERT_THROW(setSort.getBitVectorSize(), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSort, getFloatingPointExponentSize)
-{
-  Sort fpSort = d_solver.mkFloatingPointSort(4, 8);
-  ASSERT_NO_THROW(fpSort.getFloatingPointExponentSize());
-  Sort setSort = d_solver.mkSetSort(d_solver.getIntegerSort());
-  ASSERT_THROW(setSort.getFloatingPointExponentSize(), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSort, getFloatingPointSignificandSize)
-{
-  Sort fpSort = d_solver.mkFloatingPointSort(4, 8);
-  ASSERT_NO_THROW(fpSort.getFloatingPointSignificandSize());
-  Sort setSort = d_solver.mkSetSort(d_solver.getIntegerSort());
-  ASSERT_THROW(setSort.getFloatingPointSignificandSize(), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSort, getDatatypeParamSorts)
-{
-  // create parametric datatype, check should not fail
-  Sort sort = d_solver.mkParamSort("T");
-  DatatypeDecl paramDtypeSpec = d_solver.mkDatatypeDecl("paramlist", sort);
-  DatatypeConstructorDecl paramCons =
-      d_solver.mkDatatypeConstructorDecl("cons");
-  DatatypeConstructorDecl paramNil = d_solver.mkDatatypeConstructorDecl("nil");
-  paramCons.addSelector("head", sort);
-  paramDtypeSpec.addConstructor(paramCons);
-  paramDtypeSpec.addConstructor(paramNil);
-  Sort paramDtypeSort = d_solver.mkDatatypeSort(paramDtypeSpec);
-  ASSERT_NO_THROW(paramDtypeSort.getDatatypeParamSorts());
-  // create non-parametric datatype sort, check should fail
-  DatatypeDecl dtypeSpec = d_solver.mkDatatypeDecl("list");
-  DatatypeConstructorDecl cons = d_solver.mkDatatypeConstructorDecl("cons");
-  cons.addSelector("head", d_solver.getIntegerSort());
-  dtypeSpec.addConstructor(cons);
-  DatatypeConstructorDecl nil = d_solver.mkDatatypeConstructorDecl("nil");
-  dtypeSpec.addConstructor(nil);
-  Sort dtypeSort = d_solver.mkDatatypeSort(dtypeSpec);
-  ASSERT_THROW(dtypeSort.getDatatypeParamSorts(), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSort, getDatatypeArity)
-{
-  // create datatype sort, check should not fail
-  DatatypeDecl dtypeSpec = d_solver.mkDatatypeDecl("list");
-  DatatypeConstructorDecl cons = d_solver.mkDatatypeConstructorDecl("cons");
-  cons.addSelector("head", d_solver.getIntegerSort());
-  dtypeSpec.addConstructor(cons);
-  DatatypeConstructorDecl nil = d_solver.mkDatatypeConstructorDecl("nil");
-  dtypeSpec.addConstructor(nil);
-  Sort dtypeSort = d_solver.mkDatatypeSort(dtypeSpec);
-  ASSERT_NO_THROW(dtypeSort.getDatatypeArity());
-  // create bv sort, check should fail
-  Sort bvSort = d_solver.mkBitVectorSort(32);
-  ASSERT_THROW(bvSort.getDatatypeArity(), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSort, getTupleLength)
-{
-  Sort tupleSort = d_solver.mkTupleSort(
-      {d_solver.getIntegerSort(), d_solver.getIntegerSort()});
-  ASSERT_NO_THROW(tupleSort.getTupleLength());
-  Sort bvSort = d_solver.mkBitVectorSort(32);
-  ASSERT_THROW(bvSort.getTupleLength(), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSort, getTupleSorts)
-{
-  Sort tupleSort = d_solver.mkTupleSort(
-      {d_solver.getIntegerSort(), d_solver.getIntegerSort()});
-  ASSERT_NO_THROW(tupleSort.getTupleSorts());
-  Sort bvSort = d_solver.mkBitVectorSort(32);
-  ASSERT_THROW(bvSort.getTupleSorts(), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackSort, sortCompare)
-{
-  Sort boolSort = d_solver.getBooleanSort();
-  Sort intSort = d_solver.getIntegerSort();
-  Sort bvSort = d_solver.mkBitVectorSort(32);
-  Sort bvSort2 = d_solver.mkBitVectorSort(32);
-  ASSERT_TRUE(bvSort >= bvSort2);
-  ASSERT_TRUE(bvSort <= bvSort2);
-  ASSERT_TRUE((intSort > boolSort) != (intSort < boolSort));
-  ASSERT_TRUE((intSort > bvSort || intSort == bvSort) == (intSort >= bvSort));
-}
-
-TEST_F(TestApiBlackSort, sortSubtyping)
-{
-  Sort intSort = d_solver.getIntegerSort();
-  Sort realSort = d_solver.getRealSort();
-  ASSERT_TRUE(intSort.isSubsortOf(realSort));
-  ASSERT_FALSE(realSort.isSubsortOf(intSort));
-  ASSERT_TRUE(intSort.isComparableTo(realSort));
-  ASSERT_TRUE(realSort.isComparableTo(intSort));
-
-  Sort arraySortII = d_solver.mkArraySort(intSort, intSort);
-  Sort arraySortIR = d_solver.mkArraySort(intSort, realSort);
-  ASSERT_FALSE(arraySortII.isComparableTo(intSort));
-  // we do not support subtyping for arrays
-  ASSERT_FALSE(arraySortII.isComparableTo(arraySortIR));
-
-  Sort setSortI = d_solver.mkSetSort(intSort);
-  Sort setSortR = d_solver.mkSetSort(realSort);
-  // we don't support subtyping for sets
-  ASSERT_FALSE(setSortI.isComparableTo(setSortR));
-  ASSERT_FALSE(setSortI.isSubsortOf(setSortR));
-  ASSERT_FALSE(setSortR.isComparableTo(setSortI));
-  ASSERT_FALSE(setSortR.isSubsortOf(setSortI));
-}
-
-TEST_F(TestApiBlackSort, sortScopedToString)
-{
-  std::string name = "uninterp-sort";
-  Sort bvsort8 = d_solver.mkBitVectorSort(8);
-  Sort uninterp_sort = d_solver.mkUninterpretedSort(name);
-  ASSERT_EQ(bvsort8.toString(), "(_ BitVec 8)");
-  ASSERT_EQ(uninterp_sort.toString(), name);
-  Solver solver2;
-  ASSERT_EQ(bvsort8.toString(), "(_ BitVec 8)");
-  ASSERT_EQ(uninterp_sort.toString(), name);
-}
-
-}  // namespace test
-}  // namespace cvc5
diff --git a/test/unit/api/term_black.cpp b/test/unit/api/term_black.cpp
deleted file mode 100644 (file)
index 9e52174..0000000
+++ /dev/null
@@ -1,1110 +0,0 @@
-/******************************************************************************
- * Top contributors (to current version):
- *   Aina Niemetz, Makai Mann, Andrew Reynolds
- *
- * This file is part of the cvc5 project.
- *
- * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
- * in the top-level source directory and their institutional affiliations.
- * All rights reserved.  See the file COPYING in the top-level source
- * directory for licensing information.
- * ****************************************************************************
- *
- * Black box testing of the Term class.
- */
-
-#include "test_api.h"
-
-namespace cvc5 {
-
-using namespace api;
-
-namespace test {
-
-class TestApiBlackTerm : public TestApi
-{
-};
-
-TEST_F(TestApiBlackTerm, eq)
-{
-  Sort uSort = d_solver.mkUninterpretedSort("u");
-  Term x = d_solver.mkVar(uSort, "x");
-  Term y = d_solver.mkVar(uSort, "y");
-  Term z;
-
-  ASSERT_TRUE(x == x);
-  ASSERT_FALSE(x != x);
-  ASSERT_FALSE(x == y);
-  ASSERT_TRUE(x != y);
-  ASSERT_FALSE((x == z));
-  ASSERT_TRUE(x != z);
-}
-
-TEST_F(TestApiBlackTerm, getId)
-{
-  Term n;
-  ASSERT_THROW(n.getId(), CVC5ApiException);
-  Term x = d_solver.mkVar(d_solver.getIntegerSort(), "x");
-  ASSERT_NO_THROW(x.getId());
-  Term y = x;
-  ASSERT_EQ(x.getId(), y.getId());
-
-  Term z = d_solver.mkVar(d_solver.getIntegerSort(), "z");
-  ASSERT_NE(x.getId(), z.getId());
-}
-
-TEST_F(TestApiBlackTerm, getKind)
-{
-  Sort uSort = d_solver.mkUninterpretedSort("u");
-  Sort intSort = d_solver.getIntegerSort();
-  Sort boolSort = d_solver.getBooleanSort();
-  Sort funSort1 = d_solver.mkFunctionSort(uSort, intSort);
-  Sort funSort2 = d_solver.mkFunctionSort(intSort, boolSort);
-
-  Term n;
-  ASSERT_THROW(n.getKind(), CVC5ApiException);
-  Term x = d_solver.mkVar(uSort, "x");
-  ASSERT_NO_THROW(x.getKind());
-  Term y = d_solver.mkVar(uSort, "y");
-  ASSERT_NO_THROW(y.getKind());
-
-  Term f = d_solver.mkVar(funSort1, "f");
-  ASSERT_NO_THROW(f.getKind());
-  Term p = d_solver.mkVar(funSort2, "p");
-  ASSERT_NO_THROW(p.getKind());
-
-  Term zero = d_solver.mkInteger(0);
-  ASSERT_NO_THROW(zero.getKind());
-
-  Term f_x = d_solver.mkTerm(APPLY_UF, f, x);
-  ASSERT_NO_THROW(f_x.getKind());
-  Term f_y = d_solver.mkTerm(APPLY_UF, f, y);
-  ASSERT_NO_THROW(f_y.getKind());
-  Term sum = d_solver.mkTerm(PLUS, f_x, f_y);
-  ASSERT_NO_THROW(sum.getKind());
-  Term p_0 = d_solver.mkTerm(APPLY_UF, p, zero);
-  ASSERT_NO_THROW(p_0.getKind());
-  Term p_f_y = d_solver.mkTerm(APPLY_UF, p, f_y);
-  ASSERT_NO_THROW(p_f_y.getKind());
-
-  // Sequence kinds do not exist internally, test that the API properly
-  // converts them back.
-  Sort seqSort = d_solver.mkSequenceSort(intSort);
-  Term s = d_solver.mkConst(seqSort, "s");
-  Term ss = d_solver.mkTerm(SEQ_CONCAT, s, s);
-  ASSERT_EQ(ss.getKind(), SEQ_CONCAT);
-}
-
-TEST_F(TestApiBlackTerm, getSort)
-{
-  Sort bvSort = d_solver.mkBitVectorSort(8);
-  Sort intSort = d_solver.getIntegerSort();
-  Sort boolSort = d_solver.getBooleanSort();
-  Sort funSort1 = d_solver.mkFunctionSort(bvSort, intSort);
-  Sort funSort2 = d_solver.mkFunctionSort(intSort, boolSort);
-
-  Term n;
-  ASSERT_THROW(n.getSort(), CVC5ApiException);
-  Term x = d_solver.mkVar(bvSort, "x");
-  ASSERT_NO_THROW(x.getSort());
-  ASSERT_EQ(x.getSort(), bvSort);
-  Term y = d_solver.mkVar(bvSort, "y");
-  ASSERT_NO_THROW(y.getSort());
-  ASSERT_EQ(y.getSort(), bvSort);
-
-  Term f = d_solver.mkVar(funSort1, "f");
-  ASSERT_NO_THROW(f.getSort());
-  ASSERT_EQ(f.getSort(), funSort1);
-  Term p = d_solver.mkVar(funSort2, "p");
-  ASSERT_NO_THROW(p.getSort());
-  ASSERT_EQ(p.getSort(), funSort2);
-
-  Term zero = d_solver.mkInteger(0);
-  ASSERT_NO_THROW(zero.getSort());
-  ASSERT_EQ(zero.getSort(), intSort);
-
-  Term f_x = d_solver.mkTerm(APPLY_UF, f, x);
-  ASSERT_NO_THROW(f_x.getSort());
-  ASSERT_EQ(f_x.getSort(), intSort);
-  Term f_y = d_solver.mkTerm(APPLY_UF, f, y);
-  ASSERT_NO_THROW(f_y.getSort());
-  ASSERT_EQ(f_y.getSort(), intSort);
-  Term sum = d_solver.mkTerm(PLUS, f_x, f_y);
-  ASSERT_NO_THROW(sum.getSort());
-  ASSERT_EQ(sum.getSort(), intSort);
-  Term p_0 = d_solver.mkTerm(APPLY_UF, p, zero);
-  ASSERT_NO_THROW(p_0.getSort());
-  ASSERT_EQ(p_0.getSort(), boolSort);
-  Term p_f_y = d_solver.mkTerm(APPLY_UF, p, f_y);
-  ASSERT_NO_THROW(p_f_y.getSort());
-  ASSERT_EQ(p_f_y.getSort(), boolSort);
-}
-
-TEST_F(TestApiBlackTerm, getOp)
-{
-  Sort intsort = d_solver.getIntegerSort();
-  Sort bvsort = d_solver.mkBitVectorSort(8);
-  Sort arrsort = d_solver.mkArraySort(bvsort, intsort);
-  Sort funsort = d_solver.mkFunctionSort(intsort, bvsort);
-
-  Term x = d_solver.mkConst(intsort, "x");
-  Term a = d_solver.mkConst(arrsort, "a");
-  Term b = d_solver.mkConst(bvsort, "b");
-
-  ASSERT_FALSE(x.hasOp());
-  ASSERT_THROW(x.getOp(), CVC5ApiException);
-
-  Term ab = d_solver.mkTerm(SELECT, a, b);
-  Op ext = d_solver.mkOp(BITVECTOR_EXTRACT, 4, 0);
-  Term extb = d_solver.mkTerm(ext, b);
-
-  ASSERT_TRUE(ab.hasOp());
-  ASSERT_FALSE(ab.getOp().isIndexed());
-  // can compare directly to a Kind (will invoke Op constructor)
-  ASSERT_TRUE(extb.hasOp());
-  ASSERT_TRUE(extb.getOp().isIndexed());
-  ASSERT_EQ(extb.getOp(), ext);
-
-  Term f = d_solver.mkConst(funsort, "f");
-  Term fx = d_solver.mkTerm(APPLY_UF, f, x);
-
-  ASSERT_FALSE(f.hasOp());
-  ASSERT_THROW(f.getOp(), CVC5ApiException);
-  ASSERT_TRUE(fx.hasOp());
-  std::vector<Term> children(fx.begin(), fx.end());
-  // testing rebuild from op and children
-  ASSERT_EQ(fx, d_solver.mkTerm(fx.getOp(), children));
-
-  // Test Datatypes Ops
-  Sort sort = d_solver.mkParamSort("T");
-  DatatypeDecl listDecl = d_solver.mkDatatypeDecl("paramlist", sort);
-  DatatypeConstructorDecl cons = d_solver.mkDatatypeConstructorDecl("cons");
-  DatatypeConstructorDecl nil = d_solver.mkDatatypeConstructorDecl("nil");
-  cons.addSelector("head", sort);
-  cons.addSelectorSelf("tail");
-  listDecl.addConstructor(cons);
-  listDecl.addConstructor(nil);
-  Sort listSort = d_solver.mkDatatypeSort(listDecl);
-  Sort intListSort =
-      listSort.instantiate(std::vector<Sort>{d_solver.getIntegerSort()});
-  Term c = d_solver.mkConst(intListSort, "c");
-  Datatype list = listSort.getDatatype();
-  // list datatype constructor and selector operator terms
-  Term consOpTerm = list.getConstructorTerm("cons");
-  Term nilOpTerm = list.getConstructorTerm("nil");
-  Term headOpTerm = list["cons"].getSelectorTerm("head");
-  Term tailOpTerm = list["cons"].getSelectorTerm("tail");
-
-  Term nilTerm = d_solver.mkTerm(APPLY_CONSTRUCTOR, nilOpTerm);
-  Term consTerm = d_solver.mkTerm(
-      APPLY_CONSTRUCTOR, consOpTerm, d_solver.mkInteger(0), nilTerm);
-  Term headTerm = d_solver.mkTerm(APPLY_SELECTOR, headOpTerm, consTerm);
-  Term tailTerm = d_solver.mkTerm(APPLY_SELECTOR, tailOpTerm, consTerm);
-
-  ASSERT_TRUE(nilTerm.hasOp());
-  ASSERT_TRUE(consTerm.hasOp());
-  ASSERT_TRUE(headTerm.hasOp());
-  ASSERT_TRUE(tailTerm.hasOp());
-
-  // Test rebuilding
-  children.clear();
-  children.insert(children.begin(), headTerm.begin(), headTerm.end());
-  ASSERT_EQ(headTerm, d_solver.mkTerm(headTerm.getOp(), children));
-}
-
-TEST_F(TestApiBlackTerm, isNull)
-{
-  Term x;
-  ASSERT_TRUE(x.isNull());
-  x = d_solver.mkVar(d_solver.mkBitVectorSort(4), "x");
-  ASSERT_FALSE(x.isNull());
-}
-
-TEST_F(TestApiBlackTerm, notTerm)
-{
-  Sort bvSort = d_solver.mkBitVectorSort(8);
-  Sort intSort = d_solver.getIntegerSort();
-  Sort boolSort = d_solver.getBooleanSort();
-  Sort funSort1 = d_solver.mkFunctionSort(bvSort, intSort);
-  Sort funSort2 = d_solver.mkFunctionSort(intSort, boolSort);
-
-  ASSERT_THROW(Term().notTerm(), CVC5ApiException);
-  Term b = d_solver.mkTrue();
-  ASSERT_NO_THROW(b.notTerm());
-  Term x = d_solver.mkVar(d_solver.mkBitVectorSort(8), "x");
-  ASSERT_THROW(x.notTerm(), CVC5ApiException);
-  Term f = d_solver.mkVar(funSort1, "f");
-  ASSERT_THROW(f.notTerm(), CVC5ApiException);
-  Term p = d_solver.mkVar(funSort2, "p");
-  ASSERT_THROW(p.notTerm(), CVC5ApiException);
-  Term zero = d_solver.mkInteger(0);
-  ASSERT_THROW(zero.notTerm(), CVC5ApiException);
-  Term f_x = d_solver.mkTerm(APPLY_UF, f, x);
-  ASSERT_THROW(f_x.notTerm(), CVC5ApiException);
-  Term sum = d_solver.mkTerm(PLUS, f_x, f_x);
-  ASSERT_THROW(sum.notTerm(), CVC5ApiException);
-  Term p_0 = d_solver.mkTerm(APPLY_UF, p, zero);
-  ASSERT_NO_THROW(p_0.notTerm());
-  Term p_f_x = d_solver.mkTerm(APPLY_UF, p, f_x);
-  ASSERT_NO_THROW(p_f_x.notTerm());
-}
-
-TEST_F(TestApiBlackTerm, andTerm)
-{
-  Sort bvSort = d_solver.mkBitVectorSort(8);
-  Sort intSort = d_solver.getIntegerSort();
-  Sort boolSort = d_solver.getBooleanSort();
-  Sort funSort1 = d_solver.mkFunctionSort(bvSort, intSort);
-  Sort funSort2 = d_solver.mkFunctionSort(intSort, boolSort);
-
-  Term b = d_solver.mkTrue();
-  ASSERT_THROW(Term().andTerm(b), CVC5ApiException);
-  ASSERT_THROW(b.andTerm(Term()), CVC5ApiException);
-  ASSERT_NO_THROW(b.andTerm(b));
-  Term x = d_solver.mkVar(d_solver.mkBitVectorSort(8), "x");
-  ASSERT_THROW(x.andTerm(b), CVC5ApiException);
-  ASSERT_THROW(x.andTerm(x), CVC5ApiException);
-  Term f = d_solver.mkVar(funSort1, "f");
-  ASSERT_THROW(f.andTerm(b), CVC5ApiException);
-  ASSERT_THROW(f.andTerm(x), CVC5ApiException);
-  ASSERT_THROW(f.andTerm(f), CVC5ApiException);
-  Term p = d_solver.mkVar(funSort2, "p");
-  ASSERT_THROW(p.andTerm(b), CVC5ApiException);
-  ASSERT_THROW(p.andTerm(x), CVC5ApiException);
-  ASSERT_THROW(p.andTerm(f), CVC5ApiException);
-  ASSERT_THROW(p.andTerm(p), CVC5ApiException);
-  Term zero = d_solver.mkInteger(0);
-  ASSERT_THROW(zero.andTerm(b), CVC5ApiException);
-  ASSERT_THROW(zero.andTerm(x), CVC5ApiException);
-  ASSERT_THROW(zero.andTerm(f), CVC5ApiException);
-  ASSERT_THROW(zero.andTerm(p), CVC5ApiException);
-  ASSERT_THROW(zero.andTerm(zero), CVC5ApiException);
-  Term f_x = d_solver.mkTerm(APPLY_UF, f, x);
-  ASSERT_THROW(f_x.andTerm(b), CVC5ApiException);
-  ASSERT_THROW(f_x.andTerm(x), CVC5ApiException);
-  ASSERT_THROW(f_x.andTerm(f), CVC5ApiException);
-  ASSERT_THROW(f_x.andTerm(p), CVC5ApiException);
-  ASSERT_THROW(f_x.andTerm(zero), CVC5ApiException);
-  ASSERT_THROW(f_x.andTerm(f_x), CVC5ApiException);
-  Term sum = d_solver.mkTerm(PLUS, f_x, f_x);
-  ASSERT_THROW(sum.andTerm(b), CVC5ApiException);
-  ASSERT_THROW(sum.andTerm(x), CVC5ApiException);
-  ASSERT_THROW(sum.andTerm(f), CVC5ApiException);
-  ASSERT_THROW(sum.andTerm(p), CVC5ApiException);
-  ASSERT_THROW(sum.andTerm(zero), CVC5ApiException);
-  ASSERT_THROW(sum.andTerm(f_x), CVC5ApiException);
-  ASSERT_THROW(sum.andTerm(sum), CVC5ApiException);
-  Term p_0 = d_solver.mkTerm(APPLY_UF, p, zero);
-  ASSERT_NO_THROW(p_0.andTerm(b));
-  ASSERT_THROW(p_0.andTerm(x), CVC5ApiException);
-  ASSERT_THROW(p_0.andTerm(f), CVC5ApiException);
-  ASSERT_THROW(p_0.andTerm(p), CVC5ApiException);
-  ASSERT_THROW(p_0.andTerm(zero), CVC5ApiException);
-  ASSERT_THROW(p_0.andTerm(f_x), CVC5ApiException);
-  ASSERT_THROW(p_0.andTerm(sum), CVC5ApiException);
-  ASSERT_NO_THROW(p_0.andTerm(p_0));
-  Term p_f_x = d_solver.mkTerm(APPLY_UF, p, f_x);
-  ASSERT_NO_THROW(p_f_x.andTerm(b));
-  ASSERT_THROW(p_f_x.andTerm(x), CVC5ApiException);
-  ASSERT_THROW(p_f_x.andTerm(f), CVC5ApiException);
-  ASSERT_THROW(p_f_x.andTerm(p), CVC5ApiException);
-  ASSERT_THROW(p_f_x.andTerm(zero), CVC5ApiException);
-  ASSERT_THROW(p_f_x.andTerm(f_x), CVC5ApiException);
-  ASSERT_THROW(p_f_x.andTerm(sum), CVC5ApiException);
-  ASSERT_NO_THROW(p_f_x.andTerm(p_0));
-  ASSERT_NO_THROW(p_f_x.andTerm(p_f_x));
-}
-
-TEST_F(TestApiBlackTerm, orTerm)
-{
-  Sort bvSort = d_solver.mkBitVectorSort(8);
-  Sort intSort = d_solver.getIntegerSort();
-  Sort boolSort = d_solver.getBooleanSort();
-  Sort funSort1 = d_solver.mkFunctionSort(bvSort, intSort);
-  Sort funSort2 = d_solver.mkFunctionSort(intSort, boolSort);
-
-  Term b = d_solver.mkTrue();
-  ASSERT_THROW(Term().orTerm(b), CVC5ApiException);
-  ASSERT_THROW(b.orTerm(Term()), CVC5ApiException);
-  ASSERT_NO_THROW(b.orTerm(b));
-  Term x = d_solver.mkVar(d_solver.mkBitVectorSort(8), "x");
-  ASSERT_THROW(x.orTerm(b), CVC5ApiException);
-  ASSERT_THROW(x.orTerm(x), CVC5ApiException);
-  Term f = d_solver.mkVar(funSort1, "f");
-  ASSERT_THROW(f.orTerm(b), CVC5ApiException);
-  ASSERT_THROW(f.orTerm(x), CVC5ApiException);
-  ASSERT_THROW(f.orTerm(f), CVC5ApiException);
-  Term p = d_solver.mkVar(funSort2, "p");
-  ASSERT_THROW(p.orTerm(b), CVC5ApiException);
-  ASSERT_THROW(p.orTerm(x), CVC5ApiException);
-  ASSERT_THROW(p.orTerm(f), CVC5ApiException);
-  ASSERT_THROW(p.orTerm(p), CVC5ApiException);
-  Term zero = d_solver.mkInteger(0);
-  ASSERT_THROW(zero.orTerm(b), CVC5ApiException);
-  ASSERT_THROW(zero.orTerm(x), CVC5ApiException);
-  ASSERT_THROW(zero.orTerm(f), CVC5ApiException);
-  ASSERT_THROW(zero.orTerm(p), CVC5ApiException);
-  ASSERT_THROW(zero.orTerm(zero), CVC5ApiException);
-  Term f_x = d_solver.mkTerm(APPLY_UF, f, x);
-  ASSERT_THROW(f_x.orTerm(b), CVC5ApiException);
-  ASSERT_THROW(f_x.orTerm(x), CVC5ApiException);
-  ASSERT_THROW(f_x.orTerm(f), CVC5ApiException);
-  ASSERT_THROW(f_x.orTerm(p), CVC5ApiException);
-  ASSERT_THROW(f_x.orTerm(zero), CVC5ApiException);
-  ASSERT_THROW(f_x.orTerm(f_x), CVC5ApiException);
-  Term sum = d_solver.mkTerm(PLUS, f_x, f_x);
-  ASSERT_THROW(sum.orTerm(b), CVC5ApiException);
-  ASSERT_THROW(sum.orTerm(x), CVC5ApiException);
-  ASSERT_THROW(sum.orTerm(f), CVC5ApiException);
-  ASSERT_THROW(sum.orTerm(p), CVC5ApiException);
-  ASSERT_THROW(sum.orTerm(zero), CVC5ApiException);
-  ASSERT_THROW(sum.orTerm(f_x), CVC5ApiException);
-  ASSERT_THROW(sum.orTerm(sum), CVC5ApiException);
-  Term p_0 = d_solver.mkTerm(APPLY_UF, p, zero);
-  ASSERT_NO_THROW(p_0.orTerm(b));
-  ASSERT_THROW(p_0.orTerm(x), CVC5ApiException);
-  ASSERT_THROW(p_0.orTerm(f), CVC5ApiException);
-  ASSERT_THROW(p_0.orTerm(p), CVC5ApiException);
-  ASSERT_THROW(p_0.orTerm(zero), CVC5ApiException);
-  ASSERT_THROW(p_0.orTerm(f_x), CVC5ApiException);
-  ASSERT_THROW(p_0.orTerm(sum), CVC5ApiException);
-  ASSERT_NO_THROW(p_0.orTerm(p_0));
-  Term p_f_x = d_solver.mkTerm(APPLY_UF, p, f_x);
-  ASSERT_NO_THROW(p_f_x.orTerm(b));
-  ASSERT_THROW(p_f_x.orTerm(x), CVC5ApiException);
-  ASSERT_THROW(p_f_x.orTerm(f), CVC5ApiException);
-  ASSERT_THROW(p_f_x.orTerm(p), CVC5ApiException);
-  ASSERT_THROW(p_f_x.orTerm(zero), CVC5ApiException);
-  ASSERT_THROW(p_f_x.orTerm(f_x), CVC5ApiException);
-  ASSERT_THROW(p_f_x.orTerm(sum), CVC5ApiException);
-  ASSERT_NO_THROW(p_f_x.orTerm(p_0));
-  ASSERT_NO_THROW(p_f_x.orTerm(p_f_x));
-}
-
-TEST_F(TestApiBlackTerm, xorTerm)
-{
-  Sort bvSort = d_solver.mkBitVectorSort(8);
-  Sort intSort = d_solver.getIntegerSort();
-  Sort boolSort = d_solver.getBooleanSort();
-  Sort funSort1 = d_solver.mkFunctionSort(bvSort, intSort);
-  Sort funSort2 = d_solver.mkFunctionSort(intSort, boolSort);
-
-  Term b = d_solver.mkTrue();
-  ASSERT_THROW(Term().xorTerm(b), CVC5ApiException);
-  ASSERT_THROW(b.xorTerm(Term()), CVC5ApiException);
-  ASSERT_NO_THROW(b.xorTerm(b));
-  Term x = d_solver.mkVar(d_solver.mkBitVectorSort(8), "x");
-  ASSERT_THROW(x.xorTerm(b), CVC5ApiException);
-  ASSERT_THROW(x.xorTerm(x), CVC5ApiException);
-  Term f = d_solver.mkVar(funSort1, "f");
-  ASSERT_THROW(f.xorTerm(b), CVC5ApiException);
-  ASSERT_THROW(f.xorTerm(x), CVC5ApiException);
-  ASSERT_THROW(f.xorTerm(f), CVC5ApiException);
-  Term p = d_solver.mkVar(funSort2, "p");
-  ASSERT_THROW(p.xorTerm(b), CVC5ApiException);
-  ASSERT_THROW(p.xorTerm(x), CVC5ApiException);
-  ASSERT_THROW(p.xorTerm(f), CVC5ApiException);
-  ASSERT_THROW(p.xorTerm(p), CVC5ApiException);
-  Term zero = d_solver.mkInteger(0);
-  ASSERT_THROW(zero.xorTerm(b), CVC5ApiException);
-  ASSERT_THROW(zero.xorTerm(x), CVC5ApiException);
-  ASSERT_THROW(zero.xorTerm(f), CVC5ApiException);
-  ASSERT_THROW(zero.xorTerm(p), CVC5ApiException);
-  ASSERT_THROW(zero.xorTerm(zero), CVC5ApiException);
-  Term f_x = d_solver.mkTerm(APPLY_UF, f, x);
-  ASSERT_THROW(f_x.xorTerm(b), CVC5ApiException);
-  ASSERT_THROW(f_x.xorTerm(x), CVC5ApiException);
-  ASSERT_THROW(f_x.xorTerm(f), CVC5ApiException);
-  ASSERT_THROW(f_x.xorTerm(p), CVC5ApiException);
-  ASSERT_THROW(f_x.xorTerm(zero), CVC5ApiException);
-  ASSERT_THROW(f_x.xorTerm(f_x), CVC5ApiException);
-  Term sum = d_solver.mkTerm(PLUS, f_x, f_x);
-  ASSERT_THROW(sum.xorTerm(b), CVC5ApiException);
-  ASSERT_THROW(sum.xorTerm(x), CVC5ApiException);
-  ASSERT_THROW(sum.xorTerm(f), CVC5ApiException);
-  ASSERT_THROW(sum.xorTerm(p), CVC5ApiException);
-  ASSERT_THROW(sum.xorTerm(zero), CVC5ApiException);
-  ASSERT_THROW(sum.xorTerm(f_x), CVC5ApiException);
-  ASSERT_THROW(sum.xorTerm(sum), CVC5ApiException);
-  Term p_0 = d_solver.mkTerm(APPLY_UF, p, zero);
-  ASSERT_NO_THROW(p_0.xorTerm(b));
-  ASSERT_THROW(p_0.xorTerm(x), CVC5ApiException);
-  ASSERT_THROW(p_0.xorTerm(f), CVC5ApiException);
-  ASSERT_THROW(p_0.xorTerm(p), CVC5ApiException);
-  ASSERT_THROW(p_0.xorTerm(zero), CVC5ApiException);
-  ASSERT_THROW(p_0.xorTerm(f_x), CVC5ApiException);
-  ASSERT_THROW(p_0.xorTerm(sum), CVC5ApiException);
-  ASSERT_NO_THROW(p_0.xorTerm(p_0));
-  Term p_f_x = d_solver.mkTerm(APPLY_UF, p, f_x);
-  ASSERT_NO_THROW(p_f_x.xorTerm(b));
-  ASSERT_THROW(p_f_x.xorTerm(x), CVC5ApiException);
-  ASSERT_THROW(p_f_x.xorTerm(f), CVC5ApiException);
-  ASSERT_THROW(p_f_x.xorTerm(p), CVC5ApiException);
-  ASSERT_THROW(p_f_x.xorTerm(zero), CVC5ApiException);
-  ASSERT_THROW(p_f_x.xorTerm(f_x), CVC5ApiException);
-  ASSERT_THROW(p_f_x.xorTerm(sum), CVC5ApiException);
-  ASSERT_NO_THROW(p_f_x.xorTerm(p_0));
-  ASSERT_NO_THROW(p_f_x.xorTerm(p_f_x));
-}
-
-TEST_F(TestApiBlackTerm, eqTerm)
-{
-  Sort bvSort = d_solver.mkBitVectorSort(8);
-  Sort intSort = d_solver.getIntegerSort();
-  Sort boolSort = d_solver.getBooleanSort();
-  Sort funSort1 = d_solver.mkFunctionSort(bvSort, intSort);
-  Sort funSort2 = d_solver.mkFunctionSort(intSort, boolSort);
-
-  Term b = d_solver.mkTrue();
-  ASSERT_THROW(Term().eqTerm(b), CVC5ApiException);
-  ASSERT_THROW(b.eqTerm(Term()), CVC5ApiException);
-  ASSERT_NO_THROW(b.eqTerm(b));
-  Term x = d_solver.mkVar(d_solver.mkBitVectorSort(8), "x");
-  ASSERT_THROW(x.eqTerm(b), CVC5ApiException);
-  ASSERT_NO_THROW(x.eqTerm(x));
-  Term f = d_solver.mkVar(funSort1, "f");
-  ASSERT_THROW(f.eqTerm(b), CVC5ApiException);
-  ASSERT_THROW(f.eqTerm(x), CVC5ApiException);
-  ASSERT_NO_THROW(f.eqTerm(f));
-  Term p = d_solver.mkVar(funSort2, "p");
-  ASSERT_THROW(p.eqTerm(b), CVC5ApiException);
-  ASSERT_THROW(p.eqTerm(x), CVC5ApiException);
-  ASSERT_THROW(p.eqTerm(f), CVC5ApiException);
-  ASSERT_NO_THROW(p.eqTerm(p));
-  Term zero = d_solver.mkInteger(0);
-  ASSERT_THROW(zero.eqTerm(b), CVC5ApiException);
-  ASSERT_THROW(zero.eqTerm(x), CVC5ApiException);
-  ASSERT_THROW(zero.eqTerm(f), CVC5ApiException);
-  ASSERT_THROW(zero.eqTerm(p), CVC5ApiException);
-  ASSERT_NO_THROW(zero.eqTerm(zero));
-  Term f_x = d_solver.mkTerm(APPLY_UF, f, x);
-  ASSERT_THROW(f_x.eqTerm(b), CVC5ApiException);
-  ASSERT_THROW(f_x.eqTerm(x), CVC5ApiException);
-  ASSERT_THROW(f_x.eqTerm(f), CVC5ApiException);
-  ASSERT_THROW(f_x.eqTerm(p), CVC5ApiException);
-  ASSERT_NO_THROW(f_x.eqTerm(zero));
-  ASSERT_NO_THROW(f_x.eqTerm(f_x));
-  Term sum = d_solver.mkTerm(PLUS, f_x, f_x);
-  ASSERT_THROW(sum.eqTerm(b), CVC5ApiException);
-  ASSERT_THROW(sum.eqTerm(x), CVC5ApiException);
-  ASSERT_THROW(sum.eqTerm(f), CVC5ApiException);
-  ASSERT_THROW(sum.eqTerm(p), CVC5ApiException);
-  ASSERT_NO_THROW(sum.eqTerm(zero));
-  ASSERT_NO_THROW(sum.eqTerm(f_x));
-  ASSERT_NO_THROW(sum.eqTerm(sum));
-  Term p_0 = d_solver.mkTerm(APPLY_UF, p, zero);
-  ASSERT_NO_THROW(p_0.eqTerm(b));
-  ASSERT_THROW(p_0.eqTerm(x), CVC5ApiException);
-  ASSERT_THROW(p_0.eqTerm(f), CVC5ApiException);
-  ASSERT_THROW(p_0.eqTerm(p), CVC5ApiException);
-  ASSERT_THROW(p_0.eqTerm(zero), CVC5ApiException);
-  ASSERT_THROW(p_0.eqTerm(f_x), CVC5ApiException);
-  ASSERT_THROW(p_0.eqTerm(sum), CVC5ApiException);
-  ASSERT_NO_THROW(p_0.eqTerm(p_0));
-  Term p_f_x = d_solver.mkTerm(APPLY_UF, p, f_x);
-  ASSERT_NO_THROW(p_f_x.eqTerm(b));
-  ASSERT_THROW(p_f_x.eqTerm(x), CVC5ApiException);
-  ASSERT_THROW(p_f_x.eqTerm(f), CVC5ApiException);
-  ASSERT_THROW(p_f_x.eqTerm(p), CVC5ApiException);
-  ASSERT_THROW(p_f_x.eqTerm(zero), CVC5ApiException);
-  ASSERT_THROW(p_f_x.eqTerm(f_x), CVC5ApiException);
-  ASSERT_THROW(p_f_x.eqTerm(sum), CVC5ApiException);
-  ASSERT_NO_THROW(p_f_x.eqTerm(p_0));
-  ASSERT_NO_THROW(p_f_x.eqTerm(p_f_x));
-}
-
-TEST_F(TestApiBlackTerm, impTerm)
-{
-  Sort bvSort = d_solver.mkBitVectorSort(8);
-  Sort intSort = d_solver.getIntegerSort();
-  Sort boolSort = d_solver.getBooleanSort();
-  Sort funSort1 = d_solver.mkFunctionSort(bvSort, intSort);
-  Sort funSort2 = d_solver.mkFunctionSort(intSort, boolSort);
-
-  Term b = d_solver.mkTrue();
-  ASSERT_THROW(Term().impTerm(b), CVC5ApiException);
-  ASSERT_THROW(b.impTerm(Term()), CVC5ApiException);
-  ASSERT_NO_THROW(b.impTerm(b));
-  Term x = d_solver.mkVar(d_solver.mkBitVectorSort(8), "x");
-  ASSERT_THROW(x.impTerm(b), CVC5ApiException);
-  ASSERT_THROW(x.impTerm(x), CVC5ApiException);
-  Term f = d_solver.mkVar(funSort1, "f");
-  ASSERT_THROW(f.impTerm(b), CVC5ApiException);
-  ASSERT_THROW(f.impTerm(x), CVC5ApiException);
-  ASSERT_THROW(f.impTerm(f), CVC5ApiException);
-  Term p = d_solver.mkVar(funSort2, "p");
-  ASSERT_THROW(p.impTerm(b), CVC5ApiException);
-  ASSERT_THROW(p.impTerm(x), CVC5ApiException);
-  ASSERT_THROW(p.impTerm(f), CVC5ApiException);
-  ASSERT_THROW(p.impTerm(p), CVC5ApiException);
-  Term zero = d_solver.mkInteger(0);
-  ASSERT_THROW(zero.impTerm(b), CVC5ApiException);
-  ASSERT_THROW(zero.impTerm(x), CVC5ApiException);
-  ASSERT_THROW(zero.impTerm(f), CVC5ApiException);
-  ASSERT_THROW(zero.impTerm(p), CVC5ApiException);
-  ASSERT_THROW(zero.impTerm(zero), CVC5ApiException);
-  Term f_x = d_solver.mkTerm(APPLY_UF, f, x);
-  ASSERT_THROW(f_x.impTerm(b), CVC5ApiException);
-  ASSERT_THROW(f_x.impTerm(x), CVC5ApiException);
-  ASSERT_THROW(f_x.impTerm(f), CVC5ApiException);
-  ASSERT_THROW(f_x.impTerm(p), CVC5ApiException);
-  ASSERT_THROW(f_x.impTerm(zero), CVC5ApiException);
-  ASSERT_THROW(f_x.impTerm(f_x), CVC5ApiException);
-  Term sum = d_solver.mkTerm(PLUS, f_x, f_x);
-  ASSERT_THROW(sum.impTerm(b), CVC5ApiException);
-  ASSERT_THROW(sum.impTerm(x), CVC5ApiException);
-  ASSERT_THROW(sum.impTerm(f), CVC5ApiException);
-  ASSERT_THROW(sum.impTerm(p), CVC5ApiException);
-  ASSERT_THROW(sum.impTerm(zero), CVC5ApiException);
-  ASSERT_THROW(sum.impTerm(f_x), CVC5ApiException);
-  ASSERT_THROW(sum.impTerm(sum), CVC5ApiException);
-  Term p_0 = d_solver.mkTerm(APPLY_UF, p, zero);
-  ASSERT_NO_THROW(p_0.impTerm(b));
-  ASSERT_THROW(p_0.impTerm(x), CVC5ApiException);
-  ASSERT_THROW(p_0.impTerm(f), CVC5ApiException);
-  ASSERT_THROW(p_0.impTerm(p), CVC5ApiException);
-  ASSERT_THROW(p_0.impTerm(zero), CVC5ApiException);
-  ASSERT_THROW(p_0.impTerm(f_x), CVC5ApiException);
-  ASSERT_THROW(p_0.impTerm(sum), CVC5ApiException);
-  ASSERT_NO_THROW(p_0.impTerm(p_0));
-  Term p_f_x = d_solver.mkTerm(APPLY_UF, p, f_x);
-  ASSERT_NO_THROW(p_f_x.impTerm(b));
-  ASSERT_THROW(p_f_x.impTerm(x), CVC5ApiException);
-  ASSERT_THROW(p_f_x.impTerm(f), CVC5ApiException);
-  ASSERT_THROW(p_f_x.impTerm(p), CVC5ApiException);
-  ASSERT_THROW(p_f_x.impTerm(zero), CVC5ApiException);
-  ASSERT_THROW(p_f_x.impTerm(f_x), CVC5ApiException);
-  ASSERT_THROW(p_f_x.impTerm(sum), CVC5ApiException);
-  ASSERT_NO_THROW(p_f_x.impTerm(p_0));
-  ASSERT_NO_THROW(p_f_x.impTerm(p_f_x));
-}
-
-TEST_F(TestApiBlackTerm, iteTerm)
-{
-  Sort bvSort = d_solver.mkBitVectorSort(8);
-  Sort intSort = d_solver.getIntegerSort();
-  Sort boolSort = d_solver.getBooleanSort();
-  Sort funSort1 = d_solver.mkFunctionSort(bvSort, intSort);
-  Sort funSort2 = d_solver.mkFunctionSort(intSort, boolSort);
-
-  Term b = d_solver.mkTrue();
-  ASSERT_THROW(Term().iteTerm(b, b), CVC5ApiException);
-  ASSERT_THROW(b.iteTerm(Term(), b), CVC5ApiException);
-  ASSERT_THROW(b.iteTerm(b, Term()), CVC5ApiException);
-  ASSERT_NO_THROW(b.iteTerm(b, b));
-  Term x = d_solver.mkVar(d_solver.mkBitVectorSort(8), "x");
-  ASSERT_NO_THROW(b.iteTerm(x, x));
-  ASSERT_NO_THROW(b.iteTerm(b, b));
-  ASSERT_THROW(b.iteTerm(x, b), CVC5ApiException);
-  ASSERT_THROW(x.iteTerm(x, x), CVC5ApiException);
-  ASSERT_THROW(x.iteTerm(x, b), CVC5ApiException);
-  Term f = d_solver.mkVar(funSort1, "f");
-  ASSERT_THROW(f.iteTerm(b, b), CVC5ApiException);
-  ASSERT_THROW(x.iteTerm(b, x), CVC5ApiException);
-  Term p = d_solver.mkVar(funSort2, "p");
-  ASSERT_THROW(p.iteTerm(b, b), CVC5ApiException);
-  ASSERT_THROW(p.iteTerm(x, b), CVC5ApiException);
-  Term zero = d_solver.mkInteger(0);
-  ASSERT_THROW(zero.iteTerm(x, x), CVC5ApiException);
-  ASSERT_THROW(zero.iteTerm(x, b), CVC5ApiException);
-  Term f_x = d_solver.mkTerm(APPLY_UF, f, x);
-  ASSERT_THROW(f_x.iteTerm(b, b), CVC5ApiException);
-  ASSERT_THROW(f_x.iteTerm(b, x), CVC5ApiException);
-  Term sum = d_solver.mkTerm(PLUS, f_x, f_x);
-  ASSERT_THROW(sum.iteTerm(x, x), CVC5ApiException);
-  ASSERT_THROW(sum.iteTerm(b, x), CVC5ApiException);
-  Term p_0 = d_solver.mkTerm(APPLY_UF, p, zero);
-  ASSERT_NO_THROW(p_0.iteTerm(b, b));
-  ASSERT_NO_THROW(p_0.iteTerm(x, x));
-  ASSERT_THROW(p_0.iteTerm(x, b), CVC5ApiException);
-  Term p_f_x = d_solver.mkTerm(APPLY_UF, p, f_x);
-  ASSERT_NO_THROW(p_f_x.iteTerm(b, b));
-  ASSERT_NO_THROW(p_f_x.iteTerm(x, x));
-  ASSERT_THROW(p_f_x.iteTerm(x, b), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackTerm, termAssignment)
-{
-  Term t1 = d_solver.mkInteger(1);
-  Term t2 = t1;
-  t2 = d_solver.mkInteger(2);
-  ASSERT_EQ(t1, d_solver.mkInteger(1));
-}
-
-TEST_F(TestApiBlackTerm, termCompare)
-{
-  Term t1 = d_solver.mkInteger(1);
-  Term t2 = d_solver.mkTerm(PLUS, d_solver.mkInteger(2), d_solver.mkInteger(2));
-  Term t3 = d_solver.mkTerm(PLUS, d_solver.mkInteger(2), d_solver.mkInteger(2));
-  ASSERT_TRUE(t2 >= t3);
-  ASSERT_TRUE(t2 <= t3);
-  ASSERT_TRUE((t1 > t2) != (t1 < t2));
-  ASSERT_TRUE((t1 > t2 || t1 == t2) == (t1 >= t2));
-}
-
-TEST_F(TestApiBlackTerm, termChildren)
-{
-  // simple term 2+3
-  Term two = d_solver.mkInteger(2);
-  Term t1 = d_solver.mkTerm(PLUS, two, d_solver.mkInteger(3));
-  ASSERT_EQ(t1[0], two);
-  ASSERT_EQ(t1.getNumChildren(), 2);
-  Term tnull;
-  ASSERT_THROW(tnull.getNumChildren(), CVC5ApiException);
-
-  // apply term f(2)
-  Sort intSort = d_solver.getIntegerSort();
-  Sort fsort = d_solver.mkFunctionSort(intSort, intSort);
-  Term f = d_solver.mkConst(fsort, "f");
-  Term t2 = d_solver.mkTerm(APPLY_UF, f, two);
-  // due to our higher-order view of terms, we treat f as a child of APPLY_UF
-  ASSERT_EQ(t2.getNumChildren(), 2);
-  ASSERT_EQ(t2[0], f);
-  ASSERT_EQ(t2[1], two);
-  ASSERT_THROW(tnull[0], CVC5ApiException);
-}
-
-TEST_F(TestApiBlackTerm, getInteger)
-{
-  Term int1 = d_solver.mkInteger("-18446744073709551616");
-  Term int2 = d_solver.mkInteger("-18446744073709551615");
-  Term int3 = d_solver.mkInteger("-4294967296");
-  Term int4 = d_solver.mkInteger("-4294967295");
-  Term int5 = d_solver.mkInteger("-10");
-  Term int6 = d_solver.mkInteger("0");
-  Term int7 = d_solver.mkInteger("10");
-  Term int8 = d_solver.mkInteger("4294967295");
-  Term int9 = d_solver.mkInteger("4294967296");
-  Term int10 = d_solver.mkInteger("18446744073709551615");
-  Term int11 = d_solver.mkInteger("18446744073709551616");
-  Term int12 = d_solver.mkInteger("-0");
-
-  ASSERT_THROW(d_solver.mkInteger(""), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkInteger("-"), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkInteger("-1-"), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkInteger("0.0"), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkInteger("-0.1"), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkInteger("012"), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkInteger("0000"), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkInteger("-01"), CVC5ApiException);
-  ASSERT_THROW(d_solver.mkInteger("-00"), CVC5ApiException);
-
-  ASSERT_TRUE(!int1.isInt32Value() && !int1.isUInt32Value()
-              && !int1.isInt64Value() && !int1.isUInt64Value()
-              && int1.isIntegerValue());
-  ASSERT_EQ(int1.getIntegerValue(), "-18446744073709551616");
-  ASSERT_TRUE(!int2.isInt32Value() && !int2.isUInt32Value()
-              && !int2.isInt64Value() && !int2.isUInt64Value()
-              && int2.isIntegerValue());
-  ASSERT_EQ(int2.getIntegerValue(), "-18446744073709551615");
-  ASSERT_TRUE(!int3.isInt32Value() && !int3.isUInt32Value()
-              && int3.isInt64Value() && !int3.isUInt64Value()
-              && int3.isIntegerValue());
-  ASSERT_EQ(int3.getInt64Value(), -4294967296);
-  ASSERT_EQ(int3.getIntegerValue(), "-4294967296");
-  ASSERT_TRUE(!int4.isInt32Value() && !int4.isUInt32Value()
-              && int4.isInt64Value() && !int4.isUInt64Value()
-              && int4.isIntegerValue());
-  ASSERT_EQ(int4.getInt64Value(), -4294967295);
-  ASSERT_EQ(int4.getIntegerValue(), "-4294967295");
-  ASSERT_TRUE(int5.isInt32Value() && !int5.isUInt32Value()
-              && int5.isInt64Value() && !int5.isUInt64Value()
-              && int5.isIntegerValue());
-  ASSERT_EQ(int5.getInt32Value(), -10);
-  ASSERT_EQ(int5.getInt64Value(), -10);
-  ASSERT_EQ(int5.getIntegerValue(), "-10");
-  ASSERT_TRUE(int6.isInt32Value() && int6.isUInt32Value() && int6.isInt64Value()
-              && int6.isUInt64Value() && int6.isIntegerValue());
-  ASSERT_EQ(int6.getInt32Value(), 0);
-  ASSERT_EQ(int6.getUInt32Value(), 0);
-  ASSERT_EQ(int6.getInt64Value(), 0);
-  ASSERT_EQ(int6.getUInt64Value(), 0);
-  ASSERT_EQ(int6.getIntegerValue(), "0");
-  ASSERT_TRUE(int7.isInt32Value() && int7.isUInt32Value() && int7.isInt64Value()
-              && int7.isUInt64Value() && int7.isIntegerValue());
-  ASSERT_EQ(int7.getInt32Value(), 10);
-  ASSERT_EQ(int7.getUInt32Value(), 10);
-  ASSERT_EQ(int7.getInt64Value(), 10);
-  ASSERT_EQ(int7.getUInt64Value(), 10);
-  ASSERT_EQ(int7.getIntegerValue(), "10");
-  ASSERT_TRUE(!int8.isInt32Value() && int8.isUInt32Value()
-              && int8.isInt64Value() && int8.isUInt64Value()
-              && int8.isIntegerValue());
-  ASSERT_EQ(int8.getUInt32Value(), 4294967295);
-  ASSERT_EQ(int8.getInt64Value(), 4294967295);
-  ASSERT_EQ(int8.getUInt64Value(), 4294967295);
-  ASSERT_EQ(int8.getIntegerValue(), "4294967295");
-  ASSERT_TRUE(!int9.isInt32Value() && !int9.isUInt32Value()
-              && int9.isInt64Value() && int9.isUInt64Value()
-              && int9.isIntegerValue());
-  ASSERT_EQ(int9.getInt64Value(), 4294967296);
-  ASSERT_EQ(int9.getUInt64Value(), 4294967296);
-  ASSERT_EQ(int9.getIntegerValue(), "4294967296");
-  ASSERT_TRUE(!int10.isInt32Value() && !int10.isUInt32Value()
-              && !int10.isInt64Value() && int10.isUInt64Value()
-              && int10.isIntegerValue());
-  ASSERT_EQ(int10.getUInt64Value(), 18446744073709551615ull);
-  ASSERT_EQ(int10.getIntegerValue(), "18446744073709551615");
-  ASSERT_TRUE(!int11.isInt32Value() && !int11.isUInt32Value()
-              && !int11.isInt64Value() && !int11.isUInt64Value()
-              && int11.isIntegerValue());
-  ASSERT_EQ(int11.getIntegerValue(), "18446744073709551616");
-}
-
-TEST_F(TestApiBlackTerm, getString)
-{
-  Term s1 = d_solver.mkString("abcde");
-  ASSERT_TRUE(s1.isStringValue());
-  ASSERT_EQ(s1.getStringValue(), L"abcde");
-}
-
-TEST_F(TestApiBlackTerm, getReal)
-{
-  Term real1 = d_solver.mkReal("0");
-  Term real2 = d_solver.mkReal(".0");
-  Term real3 = d_solver.mkReal("-17");
-  Term real4 = d_solver.mkReal("-3/5");
-  Term real5 = d_solver.mkReal("12.7");
-  Term real6 = d_solver.mkReal("1/4294967297");
-  Term real7 = d_solver.mkReal("4294967297");
-  Term real8 = d_solver.mkReal("1/18446744073709551617");
-  Term real9 = d_solver.mkReal("18446744073709551617");
-  Term real10 = d_solver.mkReal("2343.2343");
-
-  ASSERT_TRUE(real1.isRealValue() && real1.isReal64Value()
-              && real1.isReal32Value());
-  ASSERT_TRUE(real2.isRealValue() && real2.isReal64Value()
-              && real2.isReal32Value());
-  ASSERT_TRUE(real3.isRealValue() && real3.isReal64Value()
-              && real3.isReal32Value());
-  ASSERT_TRUE(real4.isRealValue() && real4.isReal64Value()
-              && real4.isReal32Value());
-  ASSERT_TRUE(real5.isRealValue() && real5.isReal64Value()
-              && real5.isReal32Value());
-  ASSERT_TRUE(real6.isRealValue() && real6.isReal64Value());
-  ASSERT_TRUE(real7.isRealValue() && real7.isReal64Value());
-  ASSERT_TRUE(real8.isRealValue());
-  ASSERT_TRUE(real9.isRealValue());
-  ASSERT_TRUE(real10.isRealValue());
-
-  ASSERT_EQ((std::pair<int32_t, uint32_t>(0, 1)), real1.getReal32Value());
-  ASSERT_EQ((std::pair<int64_t, uint64_t>(0, 1)), real1.getReal64Value());
-  ASSERT_EQ("0/1", real1.getRealValue());
-
-  ASSERT_EQ((std::pair<int32_t, uint32_t>(0, 1)), real2.getReal32Value());
-  ASSERT_EQ((std::pair<int64_t, uint64_t>(0, 1)), real2.getReal64Value());
-  ASSERT_EQ("0/1", real2.getRealValue());
-
-  ASSERT_EQ((std::pair<int32_t, uint32_t>(-17, 1)), real3.getReal32Value());
-  ASSERT_EQ((std::pair<int64_t, uint64_t>(-17, 1)), real3.getReal64Value());
-  ASSERT_EQ("-17/1", real3.getRealValue());
-
-  ASSERT_EQ((std::pair<int32_t, uint32_t>(-3, 5)), real4.getReal32Value());
-  ASSERT_EQ((std::pair<int64_t, uint64_t>(-3, 5)), real4.getReal64Value());
-  ASSERT_EQ("-3/5", real4.getRealValue());
-
-  ASSERT_EQ((std::pair<int32_t, uint32_t>(127, 10)), real5.getReal32Value());
-  ASSERT_EQ((std::pair<int64_t, uint64_t>(127, 10)), real5.getReal64Value());
-  ASSERT_EQ("127/10", real5.getRealValue());
-
-  ASSERT_EQ((std::pair<int64_t, uint64_t>(1, 4294967297)), real6.getReal64Value());
-  ASSERT_EQ("1/4294967297", real6.getRealValue());
-
-  ASSERT_EQ((std::pair<int64_t, uint64_t>(4294967297, 1)), real7.getReal64Value());
-  ASSERT_EQ("4294967297/1", real7.getRealValue());
-
-  ASSERT_EQ("1/18446744073709551617", real8.getRealValue());
-
-  ASSERT_EQ("18446744073709551617/1", real9.getRealValue());
-
-  ASSERT_EQ("23432343/10000", real10.getRealValue());
-}
-
-TEST_F(TestApiBlackTerm, getConstArrayBase)
-{
-  Sort intsort = d_solver.getIntegerSort();
-  Sort arrsort = d_solver.mkArraySort(intsort, intsort);
-  Term one = d_solver.mkInteger(1);
-  Term constarr = d_solver.mkConstArray(arrsort, one);
-
-  ASSERT_TRUE(constarr.isConstArray());
-  ASSERT_EQ(one, constarr.getConstArrayBase());
-}
-
-TEST_F(TestApiBlackTerm, getBoolean)
-{
-  Term b1 = d_solver.mkBoolean(true);
-  Term b2 = d_solver.mkBoolean(false);
-
-  ASSERT_TRUE(b1.isBooleanValue());
-  ASSERT_TRUE(b2.isBooleanValue());
-  ASSERT_TRUE(b1.getBooleanValue());
-  ASSERT_FALSE(b2.getBooleanValue());
-}
-
-TEST_F(TestApiBlackTerm, getBitVector)
-{
-  Term b1 = d_solver.mkBitVector(8, 15);
-  Term b2 = d_solver.mkBitVector(8, "00001111", 2);
-  Term b3 = d_solver.mkBitVector(8, "15", 10);
-  Term b4 = d_solver.mkBitVector(8, "0f", 16);
-  Term b5 = d_solver.mkBitVector(9, "00001111", 2);
-  Term b6 = d_solver.mkBitVector(9, "15", 10);
-  Term b7 = d_solver.mkBitVector(9, "0f", 16);
-
-  ASSERT_TRUE(b1.isBitVectorValue());
-  ASSERT_TRUE(b2.isBitVectorValue());
-  ASSERT_TRUE(b3.isBitVectorValue());
-  ASSERT_TRUE(b4.isBitVectorValue());
-  ASSERT_TRUE(b5.isBitVectorValue());
-  ASSERT_TRUE(b6.isBitVectorValue());
-  ASSERT_TRUE(b7.isBitVectorValue());
-
-  ASSERT_EQ("00001111", b1.getBitVectorValue(2));
-  ASSERT_EQ("15", b1.getBitVectorValue(10));
-  ASSERT_EQ("f", b1.getBitVectorValue(16));
-  ASSERT_EQ("00001111", b2.getBitVectorValue(2));
-  ASSERT_EQ("15", b2.getBitVectorValue(10));
-  ASSERT_EQ("f", b2.getBitVectorValue(16));
-  ASSERT_EQ("00001111", b3.getBitVectorValue(2));
-  ASSERT_EQ("15", b3.getBitVectorValue(10));
-  ASSERT_EQ("f", b3.getBitVectorValue(16));
-  ASSERT_EQ("00001111", b4.getBitVectorValue(2));
-  ASSERT_EQ("15", b4.getBitVectorValue(10));
-  ASSERT_EQ("f", b4.getBitVectorValue(16));
-  ASSERT_EQ("000001111", b5.getBitVectorValue(2));
-  ASSERT_EQ("15", b5.getBitVectorValue(10));
-  ASSERT_EQ("f", b5.getBitVectorValue(16));
-  ASSERT_EQ("000001111", b6.getBitVectorValue(2));
-  ASSERT_EQ("15", b6.getBitVectorValue(10));
-  ASSERT_EQ("f", b6.getBitVectorValue(16));
-  ASSERT_EQ("000001111", b7.getBitVectorValue(2));
-  ASSERT_EQ("15", b7.getBitVectorValue(10));
-  ASSERT_EQ("f", b7.getBitVectorValue(16));
-}
-
-TEST_F(TestApiBlackTerm, getAbstractValue)
-{
-  Term v1 = d_solver.mkAbstractValue(1);
-  Term v2 = d_solver.mkAbstractValue("15");
-  Term v3 = d_solver.mkAbstractValue("18446744073709551617");
-
-  ASSERT_TRUE(v1.isAbstractValue());
-  ASSERT_TRUE(v2.isAbstractValue());
-  ASSERT_TRUE(v3.isAbstractValue());
-  ASSERT_EQ("1", v1.getAbstractValue());
-  ASSERT_EQ("15", v2.getAbstractValue());
-  ASSERT_EQ("18446744073709551617", v3.getAbstractValue());
-}
-
-TEST_F(TestApiBlackTerm, getTuple)
-{
-  Sort s1 = d_solver.getIntegerSort();
-  Sort s2 = d_solver.getRealSort();
-  Sort s3 = d_solver.getStringSort();
-
-  Term t1 = d_solver.mkInteger(15);
-  Term t2 = d_solver.mkReal(17, 25);
-  Term t3 = d_solver.mkString("abc");
-
-  Term tup = d_solver.mkTuple({s1, s2, s3}, {t1, t2, t3});
-
-  ASSERT_TRUE(tup.isTupleValue());
-  ASSERT_EQ(std::vector<Term>({t1, t2, t3}), tup.getTupleValue());
-}
-
-TEST_F(TestApiBlackTerm, getFloatingPoint)
-{
-  Term bvval = d_solver.mkBitVector(16, "0000110000000011", 2);
-  Term fp = d_solver.mkFloatingPoint(5, 11, bvval);
-
-  ASSERT_TRUE(fp.isFloatingPointValue());
-  ASSERT_FALSE(fp.isFloatingPointPosZero());
-  ASSERT_FALSE(fp.isFloatingPointNegZero());
-  ASSERT_FALSE(fp.isFloatingPointPosInf());
-  ASSERT_FALSE(fp.isFloatingPointNegInf());
-  ASSERT_FALSE(fp.isFloatingPointNaN());
-  ASSERT_EQ(std::make_tuple(5u, 11u, bvval), fp.getFloatingPointValue());
-
-  ASSERT_TRUE(d_solver.mkPosZero(5, 11).isFloatingPointPosZero());
-  ASSERT_TRUE(d_solver.mkNegZero(5, 11).isFloatingPointNegZero());
-  ASSERT_TRUE(d_solver.mkPosInf(5, 11).isFloatingPointPosInf());
-  ASSERT_TRUE(d_solver.mkNegInf(5, 11).isFloatingPointNegInf());
-  ASSERT_TRUE(d_solver.mkNaN(5, 11).isFloatingPointNaN());
-}
-
-TEST_F(TestApiBlackTerm, getSet)
-{
-  Sort s = d_solver.mkSetSort(d_solver.getIntegerSort());
-
-  Term i1 = d_solver.mkInteger(5);
-  Term i2 = d_solver.mkInteger(7);
-
-  Term s1 = d_solver.mkEmptySet(s);
-  Term s2 = d_solver.mkTerm(Kind::SET_SINGLETON, i1);
-  Term s3 = d_solver.mkTerm(Kind::SET_SINGLETON, i1);
-  Term s4 = d_solver.mkTerm(Kind::SET_SINGLETON, i2);
-  Term s5 = d_solver.mkTerm(
-      Kind::SET_UNION, s2, d_solver.mkTerm(Kind::SET_UNION, s3, s4));
-
-  ASSERT_TRUE(s1.isSetValue());
-  ASSERT_TRUE(s2.isSetValue());
-  ASSERT_TRUE(s3.isSetValue());
-  ASSERT_TRUE(s4.isSetValue());
-  ASSERT_FALSE(s5.isSetValue());
-  s5 = d_solver.simplify(s5);
-  ASSERT_TRUE(s5.isSetValue());
-
-  ASSERT_EQ(std::set<Term>({}), s1.getSetValue());
-  ASSERT_EQ(std::set<Term>({i1}), s2.getSetValue());
-  ASSERT_EQ(std::set<Term>({i1}), s3.getSetValue());
-  ASSERT_EQ(std::set<Term>({i2}), s4.getSetValue());
-  ASSERT_EQ(std::set<Term>({i1, i2}), s5.getSetValue());
-}
-
-TEST_F(TestApiBlackTerm, getSequence)
-{
-  Sort s = d_solver.mkSequenceSort(d_solver.getIntegerSort());
-
-  Term i1 = d_solver.mkInteger(5);
-  Term i2 = d_solver.mkInteger(7);
-
-  Term s1 = d_solver.mkEmptySequence(s);
-  Term s2 = d_solver.mkTerm(Kind::SEQ_UNIT, i1);
-  Term s3 = d_solver.mkTerm(Kind::SEQ_UNIT, i1);
-  Term s4 = d_solver.mkTerm(Kind::SEQ_UNIT, i2);
-  Term s5 = d_solver.mkTerm(
-      Kind::SEQ_CONCAT, s2, d_solver.mkTerm(Kind::SEQ_CONCAT, s3, s4));
-
-  ASSERT_TRUE(s1.isSequenceValue());
-  ASSERT_TRUE(!s2.isSequenceValue());
-  ASSERT_TRUE(!s3.isSequenceValue());
-  ASSERT_TRUE(!s4.isSequenceValue());
-  ASSERT_TRUE(!s5.isSequenceValue());
-
-  s2 = d_solver.simplify(s2);
-  s3 = d_solver.simplify(s3);
-  s4 = d_solver.simplify(s4);
-  s5 = d_solver.simplify(s5);
-
-  ASSERT_EQ(std::vector<Term>({}), s1.getSequenceValue());
-  ASSERT_EQ(std::vector<Term>({i1}), s2.getSequenceValue());
-  ASSERT_EQ(std::vector<Term>({i1}), s3.getSequenceValue());
-  ASSERT_EQ(std::vector<Term>({i2}), s4.getSequenceValue());
-  ASSERT_EQ(std::vector<Term>({i1, i1, i2}), s5.getSequenceValue());
-}
-
-TEST_F(TestApiBlackTerm, getUninterpretedConst)
-{
-  Sort s = d_solver.mkUninterpretedSort("test");
-  Term t1 = d_solver.mkUninterpretedConst(s, 3);
-  Term t2 = d_solver.mkUninterpretedConst(s, 5);
-
-  ASSERT_TRUE(t1.isUninterpretedValue());
-  ASSERT_TRUE(t2.isUninterpretedValue());
-
-  ASSERT_EQ(std::make_pair(s, 3), t1.getUninterpretedValue());
-  ASSERT_EQ(std::make_pair(s, 5), t2.getUninterpretedValue());
-}
-
-TEST_F(TestApiBlackTerm, substitute)
-{
-  Term x = d_solver.mkConst(d_solver.getIntegerSort(), "x");
-  Term one = d_solver.mkInteger(1);
-  Term ttrue = d_solver.mkTrue();
-  Term xpx = d_solver.mkTerm(PLUS, x, x);
-  Term onepone = d_solver.mkTerm(PLUS, one, one);
-
-  ASSERT_EQ(xpx.substitute(x, one), onepone);
-  ASSERT_EQ(onepone.substitute(one, x), xpx);
-  // incorrect due to type
-  ASSERT_THROW(xpx.substitute(one, ttrue), CVC5ApiException);
-
-  // simultaneous substitution
-  Term y = d_solver.mkConst(d_solver.getIntegerSort(), "y");
-  Term xpy = d_solver.mkTerm(PLUS, x, y);
-  Term xpone = d_solver.mkTerm(PLUS, y, one);
-  std::vector<Term> es;
-  std::vector<Term> rs;
-  es.push_back(x);
-  rs.push_back(y);
-  es.push_back(y);
-  rs.push_back(one);
-  ASSERT_EQ(xpy.substitute(es, rs), xpone);
-
-  // incorrect substitution due to arity
-  rs.pop_back();
-  ASSERT_THROW(xpy.substitute(es, rs), CVC5ApiException);
-
-  // incorrect substitution due to types
-  rs.push_back(ttrue);
-  ASSERT_THROW(xpy.substitute(es, rs), CVC5ApiException);
-
-  // null cannot substitute
-  Term tnull;
-  ASSERT_THROW(tnull.substitute(one, x), CVC5ApiException);
-  ASSERT_THROW(xpx.substitute(tnull, x), CVC5ApiException);
-  ASSERT_THROW(xpx.substitute(x, tnull), CVC5ApiException);
-  rs.pop_back();
-  rs.push_back(tnull);
-  ASSERT_THROW(xpy.substitute(es, rs), CVC5ApiException);
-  es.clear();
-  rs.clear();
-  es.push_back(x);
-  rs.push_back(y);
-  ASSERT_THROW(tnull.substitute(es, rs), CVC5ApiException);
-  es.push_back(tnull);
-  rs.push_back(one);
-  ASSERT_THROW(xpx.substitute(es, rs), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackTerm, constArray)
-{
-  Sort intsort = d_solver.getIntegerSort();
-  Sort arrsort = d_solver.mkArraySort(intsort, intsort);
-  Term a = d_solver.mkConst(arrsort, "a");
-  Term one = d_solver.mkInteger(1);
-  Term constarr = d_solver.mkConstArray(arrsort, one);
-
-  ASSERT_EQ(constarr.getKind(), CONST_ARRAY);
-  ASSERT_EQ(constarr.getConstArrayBase(), one);
-  ASSERT_THROW(a.getConstArrayBase(), CVC5ApiException);
-
-  arrsort =
-      d_solver.mkArraySort(d_solver.getRealSort(), d_solver.getRealSort());
-  Term zero_array = d_solver.mkConstArray(arrsort, d_solver.mkReal(0));
-  Term stores = d_solver.mkTerm(
-      STORE, zero_array, d_solver.mkReal(1), d_solver.mkReal(2));
-  stores =
-      d_solver.mkTerm(STORE, stores, d_solver.mkReal(2), d_solver.mkReal(3));
-  stores =
-      d_solver.mkTerm(STORE, stores, d_solver.mkReal(4), d_solver.mkReal(5));
-}
-
-TEST_F(TestApiBlackTerm, getSequenceValue)
-{
-  Sort realsort = d_solver.getRealSort();
-  Sort seqsort = d_solver.mkSequenceSort(realsort);
-  Term s = d_solver.mkEmptySequence(seqsort);
-
-  ASSERT_EQ(s.getKind(), CONST_SEQUENCE);
-  // empty sequence has zero elements
-  std::vector<Term> cs = s.getSequenceValue();
-  ASSERT_TRUE(cs.empty());
-
-  // A seq.unit app is not a constant sequence (regardless of whether it is
-  // applied to a constant).
-  Term su = d_solver.mkTerm(SEQ_UNIT, d_solver.mkReal(1));
-  ASSERT_THROW(su.getSequenceValue(), CVC5ApiException);
-}
-
-TEST_F(TestApiBlackTerm, termScopedToString)
-{
-  Sort intsort = d_solver.getIntegerSort();
-  Term x = d_solver.mkConst(intsort, "x");
-  ASSERT_EQ(x.toString(), "x");
-  Solver solver2;
-  ASSERT_EQ(x.toString(), "x");
-}
-}  // namespace test
-}  // namespace cvc5
diff --git a/test/unit/api/term_white.cpp b/test/unit/api/term_white.cpp
deleted file mode 100644 (file)
index ace5645..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/******************************************************************************
- * Top contributors (to current version):
- *   Makai Mann, Aina Niemetz, Andrew Reynolds
- *
- * This file is part of the cvc5 project.
- *
- * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
- * in the top-level source directory and their institutional affiliations.
- * All rights reserved.  See the file COPYING in the top-level source
- * directory for licensing information.
- * ****************************************************************************
- *
- * White box testing of the Term class.
- */
-
-#include "test_api.h"
-
-namespace cvc5 {
-
-using namespace api;
-
-namespace test {
-
-class TestApiWhiteTerm : public TestApi
-{
-};
-
-TEST_F(TestApiWhiteTerm, getOp)
-{
-  Sort intsort = d_solver.getIntegerSort();
-  Sort bvsort = d_solver.mkBitVectorSort(8);
-  Sort arrsort = d_solver.mkArraySort(bvsort, intsort);
-  Sort funsort = d_solver.mkFunctionSort(intsort, bvsort);
-
-  Term x = d_solver.mkConst(intsort, "x");
-  Term a = d_solver.mkConst(arrsort, "a");
-  Term b = d_solver.mkConst(bvsort, "b");
-
-  Term ab = d_solver.mkTerm(SELECT, a, b);
-  Op ext = d_solver.mkOp(BITVECTOR_EXTRACT, 4, 0);
-  Term extb = d_solver.mkTerm(ext, b);
-
-  ASSERT_EQ(ab.getOp(), Op(&d_solver, SELECT));
-  // can compare directly to a Kind (will invoke Op constructor)
-  ASSERT_EQ(ab.getOp(), Op(&d_solver, SELECT));
-
-  Term f = d_solver.mkConst(funsort, "f");
-  Term fx = d_solver.mkTerm(APPLY_UF, f, x);
-
-  ASSERT_EQ(fx.getOp(), Op(&d_solver, APPLY_UF));
-  // testing rebuild from op and children
-
-  // Test Datatypes Ops
-  Sort sort = d_solver.mkParamSort("T");
-  DatatypeDecl listDecl = d_solver.mkDatatypeDecl("paramlist", sort);
-  DatatypeConstructorDecl cons = d_solver.mkDatatypeConstructorDecl("cons");
-  DatatypeConstructorDecl nil = d_solver.mkDatatypeConstructorDecl("nil");
-  cons.addSelector("head", sort);
-  cons.addSelectorSelf("tail");
-  listDecl.addConstructor(cons);
-  listDecl.addConstructor(nil);
-  Sort listSort = d_solver.mkDatatypeSort(listDecl);
-  Sort intListSort =
-      listSort.instantiate(std::vector<Sort>{d_solver.getIntegerSort()});
-  Term c = d_solver.mkConst(intListSort, "c");
-  Datatype list = listSort.getDatatype();
-  // list datatype constructor and selector operator terms
-  Term consOpTerm = list.getConstructorTerm("cons");
-  Term nilOpTerm = list.getConstructorTerm("nil");
-  Term headOpTerm = list["cons"].getSelectorTerm("head");
-  Term tailOpTerm = list["cons"].getSelectorTerm("tail");
-
-  Term nilTerm = d_solver.mkTerm(APPLY_CONSTRUCTOR, nilOpTerm);
-  Term consTerm = d_solver.mkTerm(
-      APPLY_CONSTRUCTOR, consOpTerm, d_solver.mkInteger(0), nilTerm);
-  Term headTerm = d_solver.mkTerm(APPLY_SELECTOR, headOpTerm, consTerm);
-  Term tailTerm = d_solver.mkTerm(APPLY_SELECTOR, tailOpTerm, consTerm);
-
-  ASSERT_EQ(nilTerm.getOp(), Op(&d_solver, APPLY_CONSTRUCTOR));
-  ASSERT_EQ(consTerm.getOp(), Op(&d_solver, APPLY_CONSTRUCTOR));
-  ASSERT_EQ(headTerm.getOp(), Op(&d_solver, APPLY_SELECTOR));
-  ASSERT_EQ(tailTerm.getOp(), Op(&d_solver, APPLY_SELECTOR));
-}
-}  // namespace test
-}  // namespace cvc5