From: Aina Niemetz Date: Wed, 10 Nov 2021 00:08:29 +0000 (-0800) Subject: Reorganize test/unit/api directory. (#7612) X-Git-Tag: cvc5-1.0.0~841 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=eea329d3e061e1e0e98585f8b68c8db851b46513;p=cvc5.git Reorganize test/unit/api directory. (#7612) This moves .cpp files to directory test/unit/api/cpp and python files in test/python/unit/api to test/unit/api/python. --- diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index d3ff709ca..5f96d2b9b 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -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 index 5b681ca36..000000000 --- a/test/python/CMakeLists.txt +++ /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 index e69de29bb..000000000 diff --git a/test/python/unit/api/test_datatype_api.py b/test/python/unit/api/test_datatype_api.py deleted file mode 100644 index d8a4c26f7..000000000 --- a/test/python/unit/api/test_datatype_api.py +++ /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 index db567a6ba..000000000 --- a/test/python/unit/api/test_grammar.py +++ /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 index 5126a481d..000000000 --- a/test/python/unit/api/test_op.py +++ /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 index bd97646f9..000000000 --- a/test/python/unit/api/test_result.py +++ /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 index 71ab17465..000000000 --- a/test/python/unit/api/test_solver.py +++ /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 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& 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& 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 index 98cf76d76..000000000 --- a/test/python/unit/api/test_sort.py +++ /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 index 34a79d597..000000000 --- a/test/python/unit/api/test_term.py +++ /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 index bb30fae8f..000000000 --- a/test/python/unit/api/test_to_python_obj.py +++ /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") diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index 11c2e8514..9be9dcefa 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -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") diff --git a/test/unit/api/CMakeLists.txt b/test/unit/api/CMakeLists.txt index ae6db51ef..0701c3ca6 100644 --- a/test/unit/api/CMakeLists.txt +++ b/test/unit/api/CMakeLists.txt @@ -13,17 +13,10 @@ # 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 index 000000000..e99732ca4 --- /dev/null +++ b/test/unit/api/cpp/CMakeLists.txt @@ -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 index 000000000..745abc17c --- /dev/null +++ b/test/unit/api/cpp/datatype_api_black.cpp @@ -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 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 dtdecls; + dtdecls.push_back(tree); + dtdecls.push_back(list); + std::vector 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 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> 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 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 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 dtdecls; + dtdecls.push_back(wlist); + dtdecls.push_back(list); + dtdecls.push_back(ns); + // this is well-founded and has no nested recursion + std::vector 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 v; + Sort x = d_solver.mkParamSort("X"); + v.push_back(x); + DatatypeDecl list5 = d_solver.mkDatatypeDecl("list5", v); + + std::vector 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 unresTypes; + Sort unresList = d_solver.mkSortConstructorSort("plist", 1); + unresTypes.insert(unresList); + + std::vector v; + Sort x = d_solver.mkParamSort("X"); + v.push_back(x); + DatatypeDecl plist = d_solver.mkDatatypeDecl("plist", v); + + std::vector 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 dtdecls; + dtdecls.push_back(plist); + + std::vector 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 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 index 000000000..7b7556539 --- /dev/null +++ b/test/unit/api/cpp/grammar_black.cpp @@ -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 index 000000000..fd45b1c22 --- /dev/null +++ b/test/unit/api/cpp/op_black.cpp @@ -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(), CVC5ApiException); + + Op divisible_ot = d_solver.mkOp(DIVISIBLE, 4); + ASSERT_TRUE(divisible_ot.isIndexed()); + std::string divisible_idx = divisible_ot.getIndices(); + 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(); + ASSERT_EQ(bitvector_repeat_idx, 5); + ASSERT_THROW( + (bitvector_repeat_ot.getIndices>()), + CVC5ApiException); + + Op bitvector_zero_extend_ot = d_solver.mkOp(BITVECTOR_ZERO_EXTEND, 6); + uint32_t bitvector_zero_extend_idx = + bitvector_zero_extend_ot.getIndices(); + 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(); + 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(); + 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(); + 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(); + 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(); + 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(); + 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 bitvector_extract_indices = + bitvector_extract_ot.getIndices>(); + ASSERT_TRUE( + (bitvector_extract_indices == std::pair{4, 0})); + + Op floatingpoint_to_fp_ieee_bitvector_ot = + d_solver.mkOp(FLOATINGPOINT_TO_FP_IEEE_BITVECTOR, 4, 25); + std::pair floatingpoint_to_fp_ieee_bitvector_indices = + floatingpoint_to_fp_ieee_bitvector_ot + .getIndices>(); + ASSERT_TRUE((floatingpoint_to_fp_ieee_bitvector_indices + == std::pair{4, 25})); + + Op floatingpoint_to_fp_floatingpoint_ot = + d_solver.mkOp(FLOATINGPOINT_TO_FP_FLOATINGPOINT, 4, 25); + std::pair floatingpoint_to_fp_floatingpoint_indices = + floatingpoint_to_fp_floatingpoint_ot + .getIndices>(); + ASSERT_TRUE((floatingpoint_to_fp_floatingpoint_indices + == std::pair{4, 25})); + + Op floatingpoint_to_fp_real_ot = + d_solver.mkOp(FLOATINGPOINT_TO_FP_REAL, 4, 25); + std::pair floatingpoint_to_fp_real_indices = + floatingpoint_to_fp_real_ot.getIndices>(); + ASSERT_TRUE((floatingpoint_to_fp_real_indices + == std::pair{4, 25})); + + Op floatingpoint_to_fp_signed_bitvector_ot = + d_solver.mkOp(FLOATINGPOINT_TO_FP_SIGNED_BITVECTOR, 4, 25); + std::pair floatingpoint_to_fp_signed_bitvector_indices = + floatingpoint_to_fp_signed_bitvector_ot + .getIndices>(); + ASSERT_TRUE((floatingpoint_to_fp_signed_bitvector_indices + == std::pair{4, 25})); + + Op floatingpoint_to_fp_unsigned_bitvector_ot = + d_solver.mkOp(FLOATINGPOINT_TO_FP_UNSIGNED_BITVECTOR, 4, 25); + std::pair floatingpoint_to_fp_unsigned_bitvector_indices = + floatingpoint_to_fp_unsigned_bitvector_ot + .getIndices>(); + ASSERT_TRUE((floatingpoint_to_fp_unsigned_bitvector_indices + == std::pair{4, 25})); + + Op floatingpoint_to_fp_generic_ot = + d_solver.mkOp(FLOATINGPOINT_TO_FP_GENERIC, 4, 25); + std::pair floatingpoint_to_fp_generic_indices = + floatingpoint_to_fp_generic_ot + .getIndices>(); + ASSERT_TRUE((floatingpoint_to_fp_generic_indices + == std::pair{4, 25})); + ASSERT_THROW(floatingpoint_to_fp_generic_ot.getIndices(), + CVC5ApiException); +} + +TEST_F(TestApiBlackOp, getIndicesVector) +{ + std::vector 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 tuple_project_extract_indices = + tuple_project_op.getIndices>(); + ASSERT_THROW(tuple_project_op.getIndices(), 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 index 000000000..39952739b --- /dev/null +++ b/test/unit/api/cpp/op_white.cpp @@ -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(), 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 index 000000000..9bf6b8491 --- /dev/null +++ b/test/unit/api/cpp/result_black.cpp @@ -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 index 000000000..37aed63be --- /dev/null +++ b/test/unit/api/cpp/solver_black.cpp @@ -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 + +#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 decls = {dtypeSpec1, dtypeSpec2}; + ASSERT_NO_THROW(d_solver.mkDatatypeSorts(decls)); + + ASSERT_THROW(slv.mkDatatypeSorts(decls), CVC5ApiException); + + DatatypeDecl throwsDtypeSpec = d_solver.mkDatatypeDecl("list"); + std::vector throwsDecls = {throwsDtypeSpec}; + ASSERT_THROW(d_solver.mkDatatypeSorts(throwsDecls), CVC5ApiException); + + /* with unresolved sorts */ + Sort unresList = d_solver.mkUninterpretedSort("ulist"); + std::set 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 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 sorts1 = {d_solver.getBooleanSort(), + slv.getIntegerSort(), + d_solver.getIntegerSort()}; + std::vector sorts2 = {slv.getBooleanSort(), slv.getIntegerSort()}; + ASSERT_NO_THROW(slv.mkFunctionSort(sorts2, slv.getIntegerSort())); + ASSERT_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> fields = { + std::make_pair("b", d_solver.getBooleanSort()), + std::make_pair("bv", d_solver.mkBitVectorSort(8)), + std::make_pair("i", d_solver.getIntegerSort())}; + std::vector> empty; + ASSERT_NO_THROW(d_solver.mkRecordSort(fields)); + ASSERT_NO_THROW(d_solver.mkRecordSort(empty)); + Sort recSort = d_solver.mkRecordSort(fields); + ASSERT_NO_THROW(recSort.getDatatype()); + + Solver slv; + ASSERT_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 args) + std::vector 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 v1 = {a, b}; + std::vector v2 = {a, Term()}; + std::vector v3 = {a, d_solver.mkTrue()}; + std::vector v4 = {d_solver.mkInteger(1), d_solver.mkInteger(2)}; + std::vector v5 = {d_solver.mkInteger(1), Term()}; + std::vector v6 = {}; + Solver slv; + + // mkTerm(Kind kind) const + ASSERT_NO_THROW(d_solver.mkTerm(PI)); + ASSERT_NO_THROW(d_solver.mkTerm(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& 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 v1 = {d_solver.mkInteger(1), d_solver.mkInteger(2)}; + std::vector v2 = {d_solver.mkInteger(1), Term()}; + std::vector v3 = {}; + std::vector v4 = {d_solver.mkInteger(5)}; + Solver slv; + + // simple operator terms + Op opterm1 = d_solver.mkOp(BITVECTOR_EXTRACT, 2, 1); + Op opterm2 = d_solver.mkOp(DIVISIBLE, 1); + + // list datatype + Sort sort = d_solver.mkParamSort("T"); + DatatypeDecl listDecl = d_solver.mkDatatypeDecl("paramlist", sort); + DatatypeConstructorDecl cons = d_solver.mkDatatypeConstructorDecl("cons"); + DatatypeConstructorDecl nil = d_solver.mkDatatypeConstructorDecl("nil"); + cons.addSelector("head", sort); + cons.addSelectorSelf("tail"); + listDecl.addConstructor(cons); + listDecl.addConstructor(nil); + Sort listSort = d_solver.mkDatatypeSort(listDecl); + Sort intListSort = + listSort.instantiate(std::vector{d_solver.getIntegerSort()}); + Term c = d_solver.mkConst(intListSort, "c"); + Datatype list = listSort.getDatatype(); + + // list datatype constructor and selector operator terms + Term 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& 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 ctors1 = {nil}; + ASSERT_NO_THROW(d_solver.declareDatatype(std::string("a"), ctors1)); + DatatypeConstructorDecl cons = d_solver.mkDatatypeConstructorDecl("cons"); + DatatypeConstructorDecl nil2 = d_solver.mkDatatypeConstructorDecl("nil"); + std::vector ctors2 = {cons, nil2}; + ASSERT_NO_THROW(d_solver.declareDatatype(std::string("b"), ctors2)); + DatatypeConstructorDecl cons2 = d_solver.mkDatatypeConstructorDecl("cons"); + DatatypeConstructorDecl nil3 = d_solver.mkDatatypeConstructorDecl("nil"); + std::vector ctors3 = {cons2, nil3}; + ASSERT_NO_THROW(d_solver.declareDatatype(std::string(""), ctors3)); + std::vector 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 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{}, info.aliases); + EXPECT_TRUE(std::holds_alternative(info.valueInfo)); + } + { + // int64 type with default + api::OptionInfo info = d_solver.getOptionInfo("verbosity"); + EXPECT_EQ("verbosity", info.name); + EXPECT_EQ(std::vector{}, info.aliases); + EXPECT_TRUE(std::holds_alternative>( + info.valueInfo)); + auto numInfo = std::get>(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{"random-frequency"}); + ASSERT_TRUE(std::holds_alternative>( + info.valueInfo)); + auto ni = std::get>(info.valueInfo); + ASSERT_EQ(ni.currentValue, 0.0); + ASSERT_EQ(ni.defaultValue, 0.0); + ASSERT_TRUE(ni.minimum && ni.maximum); + ASSERT_EQ(*ni.minimum, 0.0); + ASSERT_EQ(*ni.maximum, 1.0); + ASSERT_EQ(info.doubleValue(), 0.0); + } + { + // mode option + api::OptionInfo info = d_solver.getOptionInfo("output"); + EXPECT_EQ("output", info.name); + EXPECT_EQ(std::vector{}, info.aliases); + EXPECT_TRUE(std::holds_alternative(info.valueInfo)); + auto modeInfo = std::get(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 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 dmap; + ASSERT_NO_THROW(dmap = d_solver.getDifficulty()); + // difficulty should map assertions to integer values + for (const std::pair& t : dmap) + { + ASSERT_TRUE(t.first == f0 || t.first == f1); + ASSERT_TRUE(t.second.getKind() == CONST_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 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 sorts; + sorts.push_back(uSort); + std::vector terms; + terms.push_back(x); + terms.push_back(y); + ASSERT_NO_THROW(d_solver.getModel(sorts, terms)); + Term null; + terms.push_back(null); + ASSERT_THROW(d_solver.getModel(sorts, terms), CVC5ApiException); +} + +TEST_F(TestApiBlackSolver, getModel2) +{ + d_solver.setOption("produce-models", "true"); + std::vector sorts; + std::vector terms; + ASSERT_THROW(d_solver.getModel(sorts, terms), CVC5ApiException); +} + +TEST_F(TestApiBlackSolver, getModel3) +{ + d_solver.setOption("produce-models", "true"); + std::vector sorts; + std::vector terms; + d_solver.checkSat(); + ASSERT_NO_THROW(d_solver.getModel(sorts, terms)); + Sort integer = d_solver.getIntegerSort(); + sorts.push_back(integer); + ASSERT_THROW(d_solver.getModel(sorts, terms), CVC5ApiException); +} + +TEST_F(TestApiBlackSolver, getQuantifierElimination) +{ + Term x = d_solver.mkVar(d_solver.getBooleanSort(), "x"); + Term forall = + d_solver.mkTerm(FORALL, + d_solver.mkTerm(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{ + 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{ + 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 sorts = {d_solver.getBooleanSort(), + d_solver.getIntegerSort(), + d_solver.getStringSort(), + d_solver.mkSetSort(d_solver.getStringSort())}; + std::vector elements = { + d_solver.mkBoolean(true), + d_solver.mkInteger(3), + d_solver.mkString("C"), + d_solver.mkTerm(SET_SINGLETON, d_solver.mkString("Z"))}; + + Term tuple = d_solver.mkTuple(sorts, elements); + + std::vector indices1 = {}; + std::vector indices2 = {0}; + std::vector indices3 = {0, 1}; + std::vector indices4 = {0, 0, 2, 2, 3, 3, 0}; + std::vector indices5 = {4}; + std::vector indices6 = {0, 4}; + + ASSERT_NO_THROW( + d_solver.mkTerm(d_solver.mkOp(TUPLE_PROJECT, indices1), tuple)); + ASSERT_NO_THROW( + d_solver.mkTerm(d_solver.mkOp(TUPLE_PROJECT, indices2), tuple)); + ASSERT_NO_THROW( + d_solver.mkTerm(d_solver.mkOp(TUPLE_PROJECT, indices3), tuple)); + ASSERT_NO_THROW( + d_solver.mkTerm(d_solver.mkOp(TUPLE_PROJECT, indices4), tuple)); + + ASSERT_THROW(d_solver.mkTerm(d_solver.mkOp(TUPLE_PROJECT, indices5), tuple), + CVC5ApiException); + ASSERT_THROW(d_solver.mkTerm(d_solver.mkOp(TUPLE_PROJECT, indices6), tuple), + CVC5ApiException); + + std::vector indices = {0, 3, 2, 0, 1, 2}; + + Op op = d_solver.mkOp(TUPLE_PROJECT, indices); + Term projection = d_solver.mkTerm(op, tuple); + + Datatype datatype = tuple.getSort().getDatatype(); + DatatypeConstructor constructor = datatype[0]; + + for (size_t i = 0; i < indices.size(); i++) + { + Term selectorTerm = constructor[indices[i]].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 index 000000000..5d7b9eacf --- /dev/null +++ b/test/unit/api/cpp/solver_white.cpp @@ -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 index 000000000..d0c755cf7 --- /dev/null +++ b/test/unit/api/cpp/sort_black.cpp @@ -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 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{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{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 index 000000000..f4180aa34 --- /dev/null +++ b/test/unit/api/cpp/term_black.cpp @@ -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 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{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(0, 1)), real1.getReal32Value()); + ASSERT_EQ((std::pair(0, 1)), real1.getReal64Value()); + ASSERT_EQ("0/1", real1.getRealValue()); + + ASSERT_EQ((std::pair(0, 1)), real2.getReal32Value()); + ASSERT_EQ((std::pair(0, 1)), real2.getReal64Value()); + ASSERT_EQ("0/1", real2.getRealValue()); + + ASSERT_EQ((std::pair(-17, 1)), real3.getReal32Value()); + ASSERT_EQ((std::pair(-17, 1)), real3.getReal64Value()); + ASSERT_EQ("-17/1", real3.getRealValue()); + + ASSERT_EQ((std::pair(-3, 5)), real4.getReal32Value()); + ASSERT_EQ((std::pair(-3, 5)), real4.getReal64Value()); + ASSERT_EQ("-3/5", real4.getRealValue()); + + ASSERT_EQ((std::pair(127, 10)), real5.getReal32Value()); + ASSERT_EQ((std::pair(127, 10)), real5.getReal64Value()); + ASSERT_EQ("127/10", real5.getRealValue()); + + ASSERT_EQ((std::pair(1, 4294967297)), + real6.getReal64Value()); + ASSERT_EQ("1/4294967297", real6.getRealValue()); + + ASSERT_EQ((std::pair(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({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({}), s1.getSetValue()); + ASSERT_EQ(std::set({i1}), s2.getSetValue()); + ASSERT_EQ(std::set({i1}), s3.getSetValue()); + ASSERT_EQ(std::set({i2}), s4.getSetValue()); + ASSERT_EQ(std::set({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({}), s1.getSequenceValue()); + ASSERT_EQ(std::vector({i1}), s2.getSequenceValue()); + ASSERT_EQ(std::vector({i1}), s3.getSequenceValue()); + ASSERT_EQ(std::vector({i2}), s4.getSequenceValue()); + ASSERT_EQ(std::vector({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 es; + std::vector 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 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 index 000000000..ace5645dc --- /dev/null +++ b/test/unit/api/cpp/term_white.cpp @@ -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{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 index 745abc17c..000000000 --- a/test/unit/api/datatype_api_black.cpp +++ /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 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 dtdecls; - dtdecls.push_back(tree); - dtdecls.push_back(list); - std::vector 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 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> 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 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 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 dtdecls; - dtdecls.push_back(wlist); - dtdecls.push_back(list); - dtdecls.push_back(ns); - // this is well-founded and has no nested recursion - std::vector 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 v; - Sort x = d_solver.mkParamSort("X"); - v.push_back(x); - DatatypeDecl list5 = d_solver.mkDatatypeDecl("list5", v); - - std::vector 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 unresTypes; - Sort unresList = d_solver.mkSortConstructorSort("plist", 1); - unresTypes.insert(unresList); - - std::vector v; - Sort x = d_solver.mkParamSort("X"); - v.push_back(x); - DatatypeDecl plist = d_solver.mkDatatypeDecl("plist", v); - - std::vector 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 dtdecls; - dtdecls.push_back(plist); - - std::vector 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 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 index 7b7556539..000000000 --- a/test/unit/api/grammar_black.cpp +++ /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 index fd45b1c22..000000000 --- a/test/unit/api/op_black.cpp +++ /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(), CVC5ApiException); - - Op divisible_ot = d_solver.mkOp(DIVISIBLE, 4); - ASSERT_TRUE(divisible_ot.isIndexed()); - std::string divisible_idx = divisible_ot.getIndices(); - 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(); - ASSERT_EQ(bitvector_repeat_idx, 5); - ASSERT_THROW( - (bitvector_repeat_ot.getIndices>()), - CVC5ApiException); - - Op bitvector_zero_extend_ot = d_solver.mkOp(BITVECTOR_ZERO_EXTEND, 6); - uint32_t bitvector_zero_extend_idx = - bitvector_zero_extend_ot.getIndices(); - 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(); - 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(); - 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(); - 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(); - 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(); - 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(); - 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 bitvector_extract_indices = - bitvector_extract_ot.getIndices>(); - ASSERT_TRUE( - (bitvector_extract_indices == std::pair{4, 0})); - - Op floatingpoint_to_fp_ieee_bitvector_ot = - d_solver.mkOp(FLOATINGPOINT_TO_FP_IEEE_BITVECTOR, 4, 25); - std::pair floatingpoint_to_fp_ieee_bitvector_indices = - floatingpoint_to_fp_ieee_bitvector_ot - .getIndices>(); - ASSERT_TRUE((floatingpoint_to_fp_ieee_bitvector_indices - == std::pair{4, 25})); - - Op floatingpoint_to_fp_floatingpoint_ot = - d_solver.mkOp(FLOATINGPOINT_TO_FP_FLOATINGPOINT, 4, 25); - std::pair floatingpoint_to_fp_floatingpoint_indices = - floatingpoint_to_fp_floatingpoint_ot - .getIndices>(); - ASSERT_TRUE((floatingpoint_to_fp_floatingpoint_indices - == std::pair{4, 25})); - - Op floatingpoint_to_fp_real_ot = - d_solver.mkOp(FLOATINGPOINT_TO_FP_REAL, 4, 25); - std::pair floatingpoint_to_fp_real_indices = - floatingpoint_to_fp_real_ot.getIndices>(); - ASSERT_TRUE((floatingpoint_to_fp_real_indices - == std::pair{4, 25})); - - Op floatingpoint_to_fp_signed_bitvector_ot = - d_solver.mkOp(FLOATINGPOINT_TO_FP_SIGNED_BITVECTOR, 4, 25); - std::pair floatingpoint_to_fp_signed_bitvector_indices = - floatingpoint_to_fp_signed_bitvector_ot - .getIndices>(); - ASSERT_TRUE((floatingpoint_to_fp_signed_bitvector_indices - == std::pair{4, 25})); - - Op floatingpoint_to_fp_unsigned_bitvector_ot = - d_solver.mkOp(FLOATINGPOINT_TO_FP_UNSIGNED_BITVECTOR, 4, 25); - std::pair floatingpoint_to_fp_unsigned_bitvector_indices = - floatingpoint_to_fp_unsigned_bitvector_ot - .getIndices>(); - ASSERT_TRUE((floatingpoint_to_fp_unsigned_bitvector_indices - == std::pair{4, 25})); - - Op floatingpoint_to_fp_generic_ot = - d_solver.mkOp(FLOATINGPOINT_TO_FP_GENERIC, 4, 25); - std::pair floatingpoint_to_fp_generic_indices = - floatingpoint_to_fp_generic_ot - .getIndices>(); - ASSERT_TRUE((floatingpoint_to_fp_generic_indices - == std::pair{4, 25})); - ASSERT_THROW(floatingpoint_to_fp_generic_ot.getIndices(), - CVC5ApiException); -} - -TEST_F(TestApiBlackOp, getIndicesVector) -{ - std::vector 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 tuple_project_extract_indices = - tuple_project_op.getIndices>(); - ASSERT_THROW(tuple_project_op.getIndices(), 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 index 39952739b..000000000 --- a/test/unit/api/op_white.cpp +++ /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(), 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 index 000000000..cbf9629ce --- /dev/null +++ b/test/unit/api/python/CMakeLists.txt @@ -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 index 000000000..e69de29bb diff --git a/test/unit/api/python/test_datatype_api.py b/test/unit/api/python/test_datatype_api.py new file mode 100644 index 000000000..d8a4c26f7 --- /dev/null +++ b/test/unit/api/python/test_datatype_api.py @@ -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 index 000000000..db567a6ba --- /dev/null +++ b/test/unit/api/python/test_grammar.py @@ -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 index 000000000..5126a481d --- /dev/null +++ b/test/unit/api/python/test_op.py @@ -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 index 000000000..bd97646f9 --- /dev/null +++ b/test/unit/api/python/test_result.py @@ -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 index 000000000..71ab17465 --- /dev/null +++ b/test/unit/api/python/test_solver.py @@ -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 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& 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& 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 index 000000000..98cf76d76 --- /dev/null +++ b/test/unit/api/python/test_sort.py @@ -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 index 000000000..34a79d597 --- /dev/null +++ b/test/unit/api/python/test_term.py @@ -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 index 000000000..bb30fae8f --- /dev/null +++ b/test/unit/api/python/test_to_python_obj.py @@ -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 index 9bf6b8491..000000000 --- a/test/unit/api/result_black.cpp +++ /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 index 79a4aa63e..000000000 --- a/test/unit/api/solver_black.cpp +++ /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 - -#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 decls = {dtypeSpec1, dtypeSpec2}; - ASSERT_NO_THROW(d_solver.mkDatatypeSorts(decls)); - - ASSERT_THROW(slv.mkDatatypeSorts(decls), CVC5ApiException); - - DatatypeDecl throwsDtypeSpec = d_solver.mkDatatypeDecl("list"); - std::vector throwsDecls = {throwsDtypeSpec}; - ASSERT_THROW(d_solver.mkDatatypeSorts(throwsDecls), CVC5ApiException); - - /* with unresolved sorts */ - Sort unresList = d_solver.mkUninterpretedSort("ulist"); - std::set 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 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 sorts1 = {d_solver.getBooleanSort(), - slv.getIntegerSort(), - d_solver.getIntegerSort()}; - std::vector sorts2 = {slv.getBooleanSort(), slv.getIntegerSort()}; - ASSERT_NO_THROW(slv.mkFunctionSort(sorts2, slv.getIntegerSort())); - ASSERT_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> fields = { - std::make_pair("b", d_solver.getBooleanSort()), - std::make_pair("bv", d_solver.mkBitVectorSort(8)), - std::make_pair("i", d_solver.getIntegerSort())}; - std::vector> empty; - ASSERT_NO_THROW(d_solver.mkRecordSort(fields)); - ASSERT_NO_THROW(d_solver.mkRecordSort(empty)); - Sort recSort = d_solver.mkRecordSort(fields); - ASSERT_NO_THROW(recSort.getDatatype()); - - Solver slv; - ASSERT_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 args) - std::vector 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 v1 = {a, b}; - std::vector v2 = {a, Term()}; - std::vector v3 = {a, d_solver.mkTrue()}; - std::vector v4 = {d_solver.mkInteger(1), d_solver.mkInteger(2)}; - std::vector v5 = {d_solver.mkInteger(1), Term()}; - std::vector v6 = {}; - Solver slv; - - // mkTerm(Kind kind) const - ASSERT_NO_THROW(d_solver.mkTerm(PI)); - ASSERT_NO_THROW(d_solver.mkTerm(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& 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 v1 = {d_solver.mkInteger(1), d_solver.mkInteger(2)}; - std::vector v2 = {d_solver.mkInteger(1), Term()}; - std::vector v3 = {}; - std::vector v4 = {d_solver.mkInteger(5)}; - Solver slv; - - // simple operator terms - Op opterm1 = d_solver.mkOp(BITVECTOR_EXTRACT, 2, 1); - Op opterm2 = d_solver.mkOp(DIVISIBLE, 1); - - // list datatype - Sort sort = d_solver.mkParamSort("T"); - DatatypeDecl listDecl = d_solver.mkDatatypeDecl("paramlist", sort); - DatatypeConstructorDecl cons = d_solver.mkDatatypeConstructorDecl("cons"); - DatatypeConstructorDecl nil = d_solver.mkDatatypeConstructorDecl("nil"); - cons.addSelector("head", sort); - cons.addSelectorSelf("tail"); - listDecl.addConstructor(cons); - listDecl.addConstructor(nil); - Sort listSort = d_solver.mkDatatypeSort(listDecl); - Sort intListSort = - listSort.instantiate(std::vector{d_solver.getIntegerSort()}); - Term c = d_solver.mkConst(intListSort, "c"); - Datatype list = listSort.getDatatype(); - - // list datatype constructor and selector operator terms - Term 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& 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 ctors1 = {nil}; - ASSERT_NO_THROW(d_solver.declareDatatype(std::string("a"), ctors1)); - DatatypeConstructorDecl cons = d_solver.mkDatatypeConstructorDecl("cons"); - DatatypeConstructorDecl nil2 = d_solver.mkDatatypeConstructorDecl("nil"); - std::vector ctors2 = {cons, nil2}; - ASSERT_NO_THROW(d_solver.declareDatatype(std::string("b"), ctors2)); - DatatypeConstructorDecl cons2 = d_solver.mkDatatypeConstructorDecl("cons"); - DatatypeConstructorDecl nil3 = d_solver.mkDatatypeConstructorDecl("nil"); - std::vector ctors3 = {cons2, nil3}; - ASSERT_NO_THROW(d_solver.declareDatatype(std::string(""), ctors3)); - std::vector 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 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{}, info.aliases); - EXPECT_TRUE(std::holds_alternative(info.valueInfo)); - } - { - // int64 type with default - api::OptionInfo info = d_solver.getOptionInfo("verbosity"); - EXPECT_EQ("verbosity", info.name); - EXPECT_EQ(std::vector{}, info.aliases); - EXPECT_TRUE(std::holds_alternative>(info.valueInfo)); - auto numInfo = std::get>(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{"random-frequency"}); - ASSERT_TRUE(std::holds_alternative>(info.valueInfo)); - auto ni = std::get>(info.valueInfo); - ASSERT_EQ(ni.currentValue, 0.0); - ASSERT_EQ(ni.defaultValue, 0.0); - ASSERT_TRUE(ni.minimum && ni.maximum); - ASSERT_EQ(*ni.minimum, 0.0); - ASSERT_EQ(*ni.maximum, 1.0); - ASSERT_EQ(info.doubleValue(), 0.0); - } - { - // mode option - api::OptionInfo info = d_solver.getOptionInfo("output"); - EXPECT_EQ("output", info.name); - EXPECT_EQ(std::vector{}, info.aliases); - EXPECT_TRUE(std::holds_alternative(info.valueInfo)); - auto modeInfo = std::get(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 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 dmap; - ASSERT_NO_THROW(dmap = d_solver.getDifficulty()); - // difficulty should map assertions to integer values - for (const std::pair& t : dmap) - { - ASSERT_TRUE(t.first == f0 || t.first == f1); - ASSERT_TRUE(t.second.getKind() == CONST_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 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 sorts; - sorts.push_back(uSort); - std::vector terms; - terms.push_back(x); - terms.push_back(y); - ASSERT_NO_THROW(d_solver.getModel(sorts, terms)); - Term null; - terms.push_back(null); - ASSERT_THROW(d_solver.getModel(sorts, terms), CVC5ApiException); -} - -TEST_F(TestApiBlackSolver, getModel2) -{ - d_solver.setOption("produce-models", "true"); - std::vector sorts; - std::vector terms; - ASSERT_THROW(d_solver.getModel(sorts, terms), CVC5ApiException); -} - -TEST_F(TestApiBlackSolver, getModel3) -{ - d_solver.setOption("produce-models", "true"); - std::vector sorts; - std::vector terms; - d_solver.checkSat(); - ASSERT_NO_THROW(d_solver.getModel(sorts, terms)); - Sort integer = d_solver.getIntegerSort(); - sorts.push_back(integer); - ASSERT_THROW(d_solver.getModel(sorts, terms), CVC5ApiException); -} - -TEST_F(TestApiBlackSolver, getQuantifierElimination) -{ - Term x = d_solver.mkVar(d_solver.getBooleanSort(), "x"); - Term forall = - d_solver.mkTerm(FORALL, - d_solver.mkTerm(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{ - 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{ - 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 sorts = {d_solver.getBooleanSort(), - d_solver.getIntegerSort(), - d_solver.getStringSort(), - d_solver.mkSetSort(d_solver.getStringSort())}; - std::vector elements = { - d_solver.mkBoolean(true), - d_solver.mkInteger(3), - d_solver.mkString("C"), - d_solver.mkTerm(SET_SINGLETON, d_solver.mkString("Z"))}; - - Term tuple = d_solver.mkTuple(sorts, elements); - - std::vector indices1 = {}; - std::vector indices2 = {0}; - std::vector indices3 = {0, 1}; - std::vector indices4 = {0, 0, 2, 2, 3, 3, 0}; - std::vector indices5 = {4}; - std::vector indices6 = {0, 4}; - - ASSERT_NO_THROW( - d_solver.mkTerm(d_solver.mkOp(TUPLE_PROJECT, indices1), tuple)); - ASSERT_NO_THROW( - d_solver.mkTerm(d_solver.mkOp(TUPLE_PROJECT, indices2), tuple)); - ASSERT_NO_THROW( - d_solver.mkTerm(d_solver.mkOp(TUPLE_PROJECT, indices3), tuple)); - ASSERT_NO_THROW( - d_solver.mkTerm(d_solver.mkOp(TUPLE_PROJECT, indices4), tuple)); - - ASSERT_THROW(d_solver.mkTerm(d_solver.mkOp(TUPLE_PROJECT, indices5), tuple), - CVC5ApiException); - ASSERT_THROW(d_solver.mkTerm(d_solver.mkOp(TUPLE_PROJECT, indices6), tuple), - CVC5ApiException); - - std::vector indices = {0, 3, 2, 0, 1, 2}; - - Op op = d_solver.mkOp(TUPLE_PROJECT, indices); - Term projection = d_solver.mkTerm(op, tuple); - - Datatype datatype = tuple.getSort().getDatatype(); - DatatypeConstructor constructor = datatype[0]; - - for (size_t i = 0; i < indices.size(); i++) - { - Term selectorTerm = constructor[indices[i]].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 index 5d7b9eacf..000000000 --- a/test/unit/api/solver_white.cpp +++ /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 index d0c755cf7..000000000 --- a/test/unit/api/sort_black.cpp +++ /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 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{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{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 index 9e52174b4..000000000 --- a/test/unit/api/term_black.cpp +++ /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 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{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(0, 1)), real1.getReal32Value()); - ASSERT_EQ((std::pair(0, 1)), real1.getReal64Value()); - ASSERT_EQ("0/1", real1.getRealValue()); - - ASSERT_EQ((std::pair(0, 1)), real2.getReal32Value()); - ASSERT_EQ((std::pair(0, 1)), real2.getReal64Value()); - ASSERT_EQ("0/1", real2.getRealValue()); - - ASSERT_EQ((std::pair(-17, 1)), real3.getReal32Value()); - ASSERT_EQ((std::pair(-17, 1)), real3.getReal64Value()); - ASSERT_EQ("-17/1", real3.getRealValue()); - - ASSERT_EQ((std::pair(-3, 5)), real4.getReal32Value()); - ASSERT_EQ((std::pair(-3, 5)), real4.getReal64Value()); - ASSERT_EQ("-3/5", real4.getRealValue()); - - ASSERT_EQ((std::pair(127, 10)), real5.getReal32Value()); - ASSERT_EQ((std::pair(127, 10)), real5.getReal64Value()); - ASSERT_EQ("127/10", real5.getRealValue()); - - ASSERT_EQ((std::pair(1, 4294967297)), real6.getReal64Value()); - ASSERT_EQ("1/4294967297", real6.getRealValue()); - - ASSERT_EQ((std::pair(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({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({}), s1.getSetValue()); - ASSERT_EQ(std::set({i1}), s2.getSetValue()); - ASSERT_EQ(std::set({i1}), s3.getSetValue()); - ASSERT_EQ(std::set({i2}), s4.getSetValue()); - ASSERT_EQ(std::set({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({}), s1.getSequenceValue()); - ASSERT_EQ(std::vector({i1}), s2.getSequenceValue()); - ASSERT_EQ(std::vector({i1}), s3.getSequenceValue()); - ASSERT_EQ(std::vector({i2}), s4.getSequenceValue()); - ASSERT_EQ(std::vector({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 es; - std::vector 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 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 index ace5645dc..000000000 --- a/test/unit/api/term_white.cpp +++ /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{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