├── .clang-format ├── .clangd ├── .github └── workflows │ ├── auto-draft-release.yml │ ├── ci.yml │ └── cibuildwheel.yml ├── .gitignore ├── AUTHORS ├── CMakeLists.txt ├── CONTRIBUTING.md ├── DEVELOPERS.md ├── LICENSE ├── README.md ├── THANKS ├── VERSION ├── bitwuzla ├── CMakeLists.txt ├── include │ ├── bitwuzla_solver.h │ ├── bitwuzla_sort.h │ └── bitwuzla_term.h └── src │ ├── bitwuzla_factory.cpp │ ├── bitwuzla_solver.cpp │ ├── bitwuzla_sort.cpp │ └── bitwuzla_term.cpp ├── btor ├── CMakeLists.txt ├── include │ ├── boolector_extensions.h │ ├── boolector_solver.h │ ├── boolector_sort.h │ └── boolector_term.h └── src │ ├── boolector_extensions.cpp │ ├── boolector_factory.cpp │ ├── boolector_solver.cpp │ ├── boolector_sort.cpp │ └── boolector_term.cpp ├── ci-scripts ├── cibw-build-before.sh ├── cibw-build-deps.sh ├── setup-bitwuzla.sh ├── setup-btor.sh ├── setup-cvc5.sh ├── setup-msat.sh ├── setup-yices2.sh ├── setup-z3.sh └── travis-setup-osx-python.sh ├── cmake ├── CheckPythonModule.cmake ├── FindCython.cmake ├── FindGMP.cmake └── FindPythonVirtualEnv.cmake ├── cmake_uninstall.cmake.in ├── configure.sh ├── contrib ├── cmake-steps.sh ├── common-setup.sh ├── make-steps.sh ├── memstream-0.1 │ ├── Makefile │ ├── README │ ├── memstream.c │ ├── memstream.h │ └── test.c ├── meson-steps.sh ├── msat_instructions.txt ├── setup-bison.sh ├── setup-bitwuzla.sh ├── setup-boolector.sh ├── setup-btor2tools.sh ├── setup-cadical.sh ├── setup-cvc5.sh ├── setup-flex.sh ├── setup-z3.sh └── yices2_instructions.txt ├── cvc5 ├── CMakeLists.txt ├── include │ ├── cvc5_datatype.h │ ├── cvc5_solver.h │ ├── cvc5_sort.h │ └── cvc5_term.h └── src │ ├── cvc5_datatype.cpp │ ├── cvc5_factory.cpp │ ├── cvc5_solver.cpp │ ├── cvc5_sort.cpp │ └── cvc5_term.cpp ├── examples ├── Makefile ├── README.md ├── btor_qf_ufbv.cpp ├── build.sh ├── cvc5_qf_ufbv.cpp └── python_qf_ufbv.py ├── include ├── bitwuzla_factory.h ├── boolector_factory.h ├── cvc5_factory.h ├── datatype.h ├── exceptions.h ├── generic_datatype.h ├── generic_solver.h ├── generic_sort.h ├── generic_term.h ├── identity_walker.h ├── logging_solver.h ├── logging_sort.h ├── logging_term.h ├── msat_factory.h ├── ops.h ├── portfolio_solver.h ├── printing_solver.h ├── result.h ├── smt.h ├── smt_defs.h ├── smtlib_reader.h ├── smtlib_utils.h ├── smtlibparser_maps.h ├── solver.h ├── solver_enums.h ├── solver_utils.h ├── sort.h ├── sort_inference.h ├── sorting_network.h ├── substitution_walker.h ├── term.h ├── term_hashtable.h ├── term_translator.h ├── tree_walker.h ├── utils.h ├── yices2_factory.h └── z3_factory.h ├── issues.md ├── msat ├── CMakeLists.txt ├── include │ ├── msat_extensions.h │ ├── msat_solver.h │ ├── msat_sort.h │ └── msat_term.h └── src │ ├── msat_extensions.cpp │ ├── msat_factory.cpp │ ├── msat_solver.cpp │ ├── msat_sort.cpp │ └── msat_term.cpp ├── python ├── CMakeLists.txt ├── gen-smt-solver-declarations.py ├── pyproject.toml ├── setup.py.in └── smt_switch │ ├── CMakeLists.txt │ ├── __init__.pxd │ ├── __init__.py.in │ ├── api.pxd │ ├── api.pyx │ ├── cppapi.pxd │ ├── cppenums.pxd │ ├── cpputils.pxd │ ├── enums.pxd │ ├── enums.pyx │ ├── primops.pyx │ ├── pysmt_frontend │ ├── __init__.py │ └── pysmt_solver.py │ ├── solverattr.pyx │ ├── solverenums.pyx │ └── sortkinds.pyx ├── rep.sed ├── scripts └── repack-static-lib.sh ├── src ├── datatype.cpp ├── generic_datatype.cpp ├── generic_solver.cpp ├── generic_sort.cpp ├── generic_term.cpp ├── identity_walker.cpp ├── logging_solver.cpp ├── logging_sort.cpp ├── logging_term.cpp ├── ops.cpp ├── portfolio_solver.cpp ├── printing_solver.cpp ├── result.cpp ├── smtlib_reader.cpp ├── smtlibparser.yy ├── smtlibscanner.l ├── solver.cpp ├── solver_enums.cpp ├── solver_utils.cpp ├── sort.cpp ├── sort_inference.cpp ├── sorting_network.cpp ├── substitution_walker.cpp ├── term.cpp ├── term_hashtable.cpp ├── term_translator.cpp ├── tree_walker.cpp └── utils.cpp ├── tests ├── CMakeLists.txt ├── CMakeLists.txt.in ├── available_solvers.cpp ├── available_solvers.h ├── btor │ ├── CMakeLists.txt │ ├── README.md │ ├── btor-array-empty-assignment.cpp │ ├── btor-array-models.cpp │ ├── btor-arrays.cpp │ ├── btor-const-arrays.cpp │ ├── btor-data-structures.cpp │ ├── btor-exceptions.cpp │ ├── btor-incremental.cpp │ ├── btor-indexed-op-tests.cpp │ ├── btor-neg-numbers.cpp │ ├── btor-negation.cpp │ ├── btor-opts.cpp │ ├── btor-printing.cpp │ ├── btor-simple.cpp │ ├── btor-substitute.cpp │ ├── btor-tests.cpp │ └── btor-transfer.cpp ├── cvc5 │ ├── CMakeLists.txt │ ├── README.md │ ├── cvc5-arrays.cpp │ ├── cvc5-data-structures.cpp │ ├── cvc5-incremental.cpp │ ├── cvc5-indexed-op-tests.cpp │ ├── cvc5-int-arithmetic.cpp │ ├── cvc5-interpolants-api.cpp │ ├── cvc5-interpolants.cpp │ ├── cvc5-neg-numbers.cpp │ ├── cvc5-printing.cpp │ ├── cvc5-str.cpp │ ├── cvc5-term-iter.cpp │ ├── cvc5-tests.cpp │ ├── cvc5-transfer.cpp │ └── cvc5_test.cpp ├── msat │ ├── CMakeLists.txt │ ├── msat-array-models.cpp │ ├── msat-arrays.cpp │ ├── msat-arrays2.cpp │ ├── msat-const-arrays.cpp │ ├── msat-data-structures.cpp │ ├── msat-ext-ops.cpp │ ├── msat-incremental.cpp │ ├── msat-indexed-op-tests.cpp │ ├── msat-int-arithmetic.cpp │ ├── msat-interpolants.cpp │ ├── msat-ite-test.cpp │ ├── msat-neg-numbers.cpp │ ├── msat-printing.cpp │ ├── msat-seq-interpolants.cpp │ ├── msat-substitute.cpp │ ├── msat-tests.cpp │ ├── msat-transfer.cpp │ └── msat-traversal.cpp ├── portfolio │ ├── CMakeLists.txt │ └── test-portfolio-solver.cpp ├── python │ ├── available_solvers.py │ ├── test_arrays.py │ ├── test_bv.py │ ├── test_enums.py │ ├── test_itp.py │ ├── test_lia.py │ ├── test_pysmt.py │ ├── test_reals.py │ ├── test_sorting_network.py │ ├── test_unit.py │ ├── test_unit_vals.py │ ├── test_unsat_core.py │ └── test_visitor.py ├── smt2 │ ├── qf_alia │ │ └── test-array.smt2 │ ├── qf_s │ │ ├── test-ops-SLIA.smt2 │ │ └── test-ops.smt2 │ ├── qf_uf │ │ ├── test-uninterp-sort-nonzero-arity.smt2 │ │ └── test-uninterp-sort-zero-arity.smt2 │ ├── qf_ufbv │ │ ├── test-attr.smt2 │ │ ├── test-define-sort-edge-case.smt2 │ │ └── test-define-sort.smt2 │ └── qf_uflia │ │ ├── test-symbols.smt2 │ │ └── test-uf.smt2 ├── smtlib_reader_test_inputs.h ├── test-array.cpp ├── test-bv.cpp ├── test-disjointset.cpp ├── test-dt.cpp ├── test-generic-solver.cpp ├── test-generic-sort.cpp ├── test-generic-term.cpp ├── test-int.cpp ├── test-itp.cpp ├── test-logging-solver.cpp ├── test-smtlib-reader.cpp ├── test-sorting-network.cpp ├── test-str.cpp ├── test-term-translation.cpp ├── test-time-limit.cpp ├── test-unsat-core-reducer.cpp ├── test-unsat-core.cpp ├── test-utils.cpp ├── test-utils.h ├── test-variadic-ops.cpp ├── unit │ ├── CMakeLists.txt │ ├── Makefile │ ├── unit-arrays.cpp │ ├── unit-exceptions.cpp │ ├── unit-fun.cpp │ ├── unit-incremental.cpp │ ├── unit-op.cpp │ ├── unit-printing.cpp │ ├── unit-quantifiers.cpp │ ├── unit-reset-assertions.cpp │ ├── unit-solver-enums.cpp │ ├── unit-solving-interface.cpp │ ├── unit-sort-inference.cpp │ ├── unit-sort.cpp │ ├── unit-substitute.cpp │ ├── unit-symbol.cpp │ ├── unit-term-hashtable.cpp │ ├── unit-term-id.cpp │ ├── unit-term.cpp │ ├── unit-termiter.cpp │ ├── unit-transfer.cpp │ ├── unit-util.cpp │ └── unit-walker.cpp ├── yices2 │ ├── CMakeLists.txt │ ├── yices2-array-models.cpp │ ├── yices2-arrays.cpp │ ├── yices2-arrays2.cpp │ ├── yices2-ext-ops.cpp │ ├── yices2-gtest.cpp │ ├── yices2-incremental.cpp │ ├── yices2-indexed-op-tests.cpp │ ├── yices2-ite-test.cpp │ ├── yices2-neg-numbers.cpp │ ├── yices2-polynomial.cpp │ └── yices2-tests.cpp └── z3 │ ├── CMakeLists.txt │ ├── z3_full.cpp │ └── z3_test.cpp ├── yices2 ├── CMakeLists.txt ├── include │ ├── yices2_extensions.h │ ├── yices2_solver.h │ ├── yices2_sort.h │ └── yices2_term.h └── src │ ├── yices2_extensions.cpp │ ├── yices2_factory.cpp │ ├── yices2_solver.cpp │ ├── yices2_sort.cpp │ └── yices2_term.cpp └── z3 ├── CMakeLists.txt ├── include ├── z3_datatype.h ├── z3_solver.h ├── z3_sort.h └── z3_term.h └── src ├── z3_datatype.cpp ├── z3_factory.cpp ├── z3_solver.cpp ├── z3_sort.cpp └── z3_term.cpp /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | Language: Cpp 3 | BasedOnStyle: Google 4 | AlignTrailingComments: true 5 | AllowShortCaseLabelsOnASingleLine: true 6 | BinPackArguments: false 7 | BinPackParameters: false 8 | BraceWrapping: 9 | AfterClass: true 10 | AfterControlStatement: true 11 | AfterEnum: true 12 | AfterFunction: true 13 | AfterStruct: true 14 | AfterUnion: true 15 | BeforeCatch: true 16 | BeforeElse: true 17 | BreakBeforeBinaryOperators: NonAssignment 18 | BreakBeforeBraces: Custom 19 | BreakConstructorInitializers: BeforeColon 20 | Cpp11BracedListStyle: false 21 | DerivePointerAlignment: false 22 | PointerAlignment: Middle 23 | ... 24 | -------------------------------------------------------------------------------- /.clangd: -------------------------------------------------------------------------------- 1 | CompileFlags: 2 | CompilationDatabase: build/ 3 | -------------------------------------------------------------------------------- /.github/workflows/auto-draft-release.yml: -------------------------------------------------------------------------------- 1 | name: Automatically Draft a Release on Version Bump 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | create-tag: 10 | runs-on: ubuntu-latest 11 | permissions: 12 | contents: write # Needed to create tags 13 | 14 | steps: 15 | # Check out the repository 16 | - name: Checkout code 17 | uses: actions/checkout@v4 18 | with: 19 | fetch-depth: 0 # Fetch all history to ensure we can check if tag exists 20 | 21 | - name: Read VERSION file 22 | id: version 23 | run: | 24 | # Use grep to filter out comment lines, then take the first non-comment line 25 | VERSION_VALUE=$(grep -v '^#' VERSION | head -n 1 | tr -d '[:space:]') 26 | echo "Detected version: $VERSION_VALUE" 27 | echo "version=$VERSION_VALUE" >> $GITHUB_OUTPUT 28 | 29 | - name: Check if tag exists 30 | id: check_tag 31 | run: | 32 | if git tag -l "v${{ steps.version.outputs.version }}" | grep -q .; then 33 | echo "tag_exists=true" >> $GITHUB_OUTPUT 34 | else 35 | echo "tag_exists=false" >> $GITHUB_OUTPUT 36 | fi 37 | 38 | # Create and push the tag if it doesn't already exist 39 | - name: Create and push tag 40 | if: steps.check_tag.outputs.tag_exists == 'false' 41 | run: | 42 | git config user.name "github-actions[bot]" 43 | git config user.email "41898282+github-actions[bot]@users.noreply.github.com" 44 | git tag -a v${{ steps.version.outputs.version }} -m "Version ${{ steps.version.outputs.version }}" 45 | git push origin "v${{ steps.version.outputs.version }}" 46 | 47 | - name: Create draft GitHub Release 48 | if: steps.check_tag.outputs.tag_exists == 'false' 49 | uses: softprops/action-gh-release@v2 50 | with: 51 | tag_name: v${{ steps.version.outputs.version }} 52 | name: Release v${{ steps.version.outputs.version }} 53 | draft: true 54 | prerelease: true 55 | generate_release_notes: true 56 | env: 57 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 58 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__/ 2 | build/ 3 | deps/ 4 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | The authors, designers, and main contributors to smt-switch are listed 2 | below. smt-switch's copyright is held by these individuals and the 3 | affiliated institutions at the time of their contributions. See the 4 | file LICENSE for details on the copyright and licensing of smt-switch. 5 | 6 | The core designers and authors of smt-switch are: 7 | 8 | Makai Mann, Stanford University 9 | Amalee Wilson, Stanford University 10 | Yoni Zohar, Stanford University 11 | Lindsey Stuntz, Stanford University 12 | Cesare Tinelli, The University of Iowa 13 | Clark Barrett, Stanford University 14 | 15 | Alumni: 16 | Ahmed Irfan, Stanford University -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | External contributions to smt-switch may be proposed via a pull request. All 4 | external contributions are subject to the following terms: 5 | * Pull requests must be squashed into a single commit before being submitted and 6 | must be signed using `git commit -s` 7 | * By submitting a signed contribution, you agree to all the terms of the 8 | 3-clause BSD license (see [LICENSE](./LICENSE)) 9 | * But submitting a signed contribution, you agree that the [Developer 10 | Certificate of Origin](https://developercertificate.org/) (reproduced below) 11 | applies to your contribution. 12 | 13 | ``` 14 | Developer Certificate of Origin 15 | Version 1.1 16 | 17 | Copyright (C) 2004, 2006 The Linux Foundation and its contributors. 18 | 1 Letterman Drive 19 | Suite D4700 20 | San Francisco, CA, 94129 21 | 22 | Everyone is permitted to copy and distribute verbatim copies of this 23 | license document, but changing it is not allowed. 24 | 25 | 26 | Developer's Certificate of Origin 1.1 27 | 28 | By making a contribution to this project, I certify that: 29 | 30 | (a) The contribution was created in whole or in part by me and I 31 | have the right to submit it under the open source license 32 | indicated in the file; or 33 | 34 | (b) The contribution is based upon previous work that, to the best 35 | of my knowledge, is covered under an appropriate open source 36 | license and I have the right under that license to submit that 37 | work with modifications, whether created in whole or in part 38 | by me, under the same open source license (unless I am 39 | permitted to submit under a different license), as indicated 40 | in the file; or 41 | 42 | (c) The contribution was provided directly to me by some other 43 | person who certified (a), (b) or (c) and I have not modified 44 | it. 45 | 46 | (d) I understand and agree that this project and the contribution 47 | are public and that a record of the contribution (including all 48 | personal information I submit with it, including my sign-off) is 49 | maintained indefinitely and may be redistributed consistent with 50 | this project or the open source license(s) involved. 51 | ``` 52 | -------------------------------------------------------------------------------- /THANKS: -------------------------------------------------------------------------------- 1 | Thanks to: 2 | 3 | * Keyi Zhang of Stanford University for adding the Python wheels distribution 4 | and PyPi upload infrastructure. 5 | 6 | * Hongce Zhang of Princeton University for the addition of an unsat core 7 | reduction function. 8 | 9 | * Bart van Helvert of JetBrains for an improvement to the handling of the 10 | distinct operator in the Yices2 backend. 11 | 12 | * Andrew V. Jones of VECTOR Informatik for a clarification in the README 13 | regarding BSD compliant underlying solvers. 14 | 15 | * Kristopher Brown of Stanford University for adding Datatypes support to the 16 | cvc5 backend. 17 | 18 | * Allison Guman of Columbia University for adding a TreeWalker. 19 | 20 | * Thomas Kiley for a code quality improvement. 21 | 22 | * Caleb Donovick of Stanford University for adding a PySMT translation module 23 | and improvements to the Python bindings setup.py infrastructure. -------------------------------------------------------------------------------- /VERSION: -------------------------------------------------------------------------------- 1 | # Update this version and commit to main to trigger a GitHub Action to create a new tag and draft release 2 | 1.0.1 3 | -------------------------------------------------------------------------------- /bitwuzla/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(CMAKE_POSITION_INDEPENDENT_CODE ON) 2 | 3 | # Find Bitwuzla installation 4 | list(PREPEND CMAKE_PREFIX_PATH "${BITWUZLA_DIR}") 5 | find_package(PkgConfig REQUIRED) 6 | pkg_check_modules(BITWUZLA REQUIRED bitwuzla) 7 | 8 | add_library(smt-switch-bitwuzla "${SMT_SWITCH_LIB_TYPE}" 9 | "${CMAKE_CURRENT_SOURCE_DIR}/src/bitwuzla_factory.cpp" 10 | "${CMAKE_CURRENT_SOURCE_DIR}/src/bitwuzla_solver.cpp" 11 | "${CMAKE_CURRENT_SOURCE_DIR}/src/bitwuzla_sort.cpp" 12 | "${CMAKE_CURRENT_SOURCE_DIR}/src/bitwuzla_term.cpp" 13 | ) 14 | 15 | target_include_directories (smt-switch-bitwuzla PUBLIC "${PROJECT_SOURCE_DIR}/include") 16 | target_include_directories (smt-switch-bitwuzla PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include") 17 | target_include_directories (smt-switch-bitwuzla PUBLIC ${BITWUZLA_INCLUDE_DIRS}) 18 | 19 | target_link_libraries(smt-switch-bitwuzla smt-switch) 20 | target_link_libraries(smt-switch-bitwuzla ${BITWUZLA_LDFLAGS}) 21 | 22 | install(TARGETS smt-switch-bitwuzla DESTINATION lib) 23 | # install headers -- for expert use only 24 | install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/" 25 | DESTINATION include/smt-switch 26 | FILES_MATCHING PATTERN "*.h") 27 | -------------------------------------------------------------------------------- /bitwuzla/include/bitwuzla_sort.h: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file bitwuzla_sort.h 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief Bitwuzla implementation of AbsSort 13 | ** 14 | ** 15 | **/ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include "bitwuzla/cpp/bitwuzla.h" 24 | #include "smt.h" 25 | 26 | namespace smt { 27 | 28 | // forward declaration 29 | class BzlaSolver; 30 | 31 | class BzlaSort : public AbsSort 32 | { 33 | public: 34 | BzlaSort(const bitwuzla::Sort s) : sort(s){}; 35 | virtual ~BzlaSort(); 36 | std::size_t hash() const override; 37 | std::uint64_t get_width() const override; 38 | Sort get_indexsort() const override; 39 | Sort get_elemsort() const override; 40 | SortVec get_domain_sorts() const override; 41 | Sort get_codomain_sort() const override; 42 | std::string get_uninterpreted_name() const override; 43 | std::size_t get_arity() const override; 44 | SortVec get_uninterpreted_param_sorts() const override; 45 | Datatype get_datatype() const override; 46 | bool compare(const Sort & s) const override; 47 | SortKind get_sort_kind() const override; 48 | 49 | // getters for solver-specific objects 50 | // for interacting with third-party Bitwuzla-specific software 51 | 52 | const bitwuzla::Sort get_bitwuzla_sort() const { return sort; }; 53 | 54 | protected: 55 | // objects from Bitwuzla API 56 | const bitwuzla::Sort sort; 57 | 58 | friend class BzlaSolver; 59 | }; 60 | 61 | } // namespace smt 62 | -------------------------------------------------------------------------------- /bitwuzla/src/bitwuzla_factory.cpp: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file bitwuzla_factory.cpp 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief Factory for creating a Bitwuzla SmtSolver 13 | ** 14 | ** 15 | **/ 16 | 17 | #include "bitwuzla_factory.h" 18 | 19 | #include 20 | 21 | #include "bitwuzla_solver.h" 22 | #include "logging_solver.h" 23 | #include "smt_defs.h" 24 | 25 | namespace smt { 26 | 27 | /* BitwuzlaSolverFactory implementation */ 28 | SmtSolver BitwuzlaSolverFactory::create(bool logging) 29 | { 30 | SmtSolver solver = std::make_shared(); 31 | if (logging) 32 | { 33 | solver = std::make_shared(solver); 34 | } 35 | return solver; 36 | } 37 | 38 | /* end BitwuzlaSolverFactory implementation */ 39 | 40 | } // namespace smt 41 | -------------------------------------------------------------------------------- /btor/include/boolector_extensions.h: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file boolector_extensions.h 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief Helper functions for certain operations in Boolector C API 13 | ** 14 | ** 15 | **/ 16 | 17 | #pragma once 18 | 19 | #include "boolector.h" 20 | 21 | namespace smt { 22 | BoolectorNode * custom_boolector_rotate_left(Btor * btor, 23 | BoolectorNode * node, 24 | uint32_t n); 25 | 26 | BoolectorNode * custom_boolector_rotate_right(Btor * btor, 27 | BoolectorNode * node, 28 | uint32_t n); 29 | } // namespace smt 30 | 31 | -------------------------------------------------------------------------------- /btor/src/boolector_extensions.cpp: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file boolector_extensions.cpp 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief Helper functions for certain operations in Boolector C API 13 | ** 14 | ** 15 | **/ 16 | 17 | #include "math.h" 18 | 19 | #include "boolector_extensions.h" 20 | 21 | namespace smt { 22 | BoolectorNode * custom_boolector_rotate_left(Btor * btor, 23 | BoolectorNode * node, 24 | uint32_t n) 25 | { 26 | uint32_t width = boolector_get_width(btor, node); 27 | if ((n == 0) || (width == 1)) 28 | { 29 | return boolector_uext(btor, node, 0); 30 | } 31 | 32 | // compute directly with extracts 33 | BoolectorNode * top_slice = boolector_slice(btor, node, width - 1, width - n); 34 | BoolectorNode * bot_slice = boolector_slice(btor, node, width - n - 1, 0); 35 | BoolectorNode * res = boolector_concat(btor, bot_slice, top_slice); 36 | boolector_release(btor, top_slice); 37 | boolector_release(btor, bot_slice); 38 | return res; 39 | } 40 | 41 | BoolectorNode * custom_boolector_rotate_right(Btor * btor, 42 | BoolectorNode * node, 43 | uint32_t n) 44 | { 45 | uint32_t width = boolector_get_width(btor, node); 46 | if ((n == 0) || (width == 1)) 47 | { 48 | return boolector_uext(btor, node, 0); 49 | } 50 | 51 | // compute directly with extracts 52 | BoolectorNode * top_slice = boolector_slice(btor, node, width - 1, n); 53 | BoolectorNode * bot_slice = boolector_slice(btor, node, n - 1, 0); 54 | BoolectorNode * res = boolector_concat(btor, bot_slice, top_slice); 55 | boolector_release(btor, top_slice); 56 | boolector_release(btor, bot_slice); 57 | return res; 58 | } 59 | } // namespace smt 60 | -------------------------------------------------------------------------------- /btor/src/boolector_factory.cpp: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file boolector_factory.cpp 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief Factory for creating a Boolector SmtSolver 13 | ** 14 | ** 15 | **/ 16 | 17 | #include "boolector_factory.h" 18 | #include "boolector_solver.h" 19 | #include "logging_solver.h" 20 | 21 | namespace smt { 22 | 23 | /* BoolectorSolverFactory implementation */ 24 | SmtSolver BoolectorSolverFactory::create(bool logging) 25 | { 26 | SmtSolver solver = std::make_shared(); 27 | if (logging) 28 | { 29 | solver = std::make_shared(solver); 30 | } 31 | return solver; 32 | } 33 | 34 | /* end BoolectorSolverFactory implementation */ 35 | 36 | } // namespace smt 37 | -------------------------------------------------------------------------------- /ci-scripts/cibw-build-before.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | ############################################################################### 3 | # Top contributors (to current version): 4 | # Makai Mann 5 | # 6 | # This file is part of the smt-switch project. 7 | # 8 | # Copyright (c) 2025 by the authors listed in the file AUTHORS 9 | # in the top-level source directory) and their institutional affiliations. 10 | # All rights reserved. See the file LICENSE in the top-level source 11 | # directory for licensing information.\endverbatim 12 | ############################################################################### 13 | # 14 | # This script builds the smt-switch C++ libraries for the PyPi upload 15 | # It is meant to be run after cibw-build-deps.sh 16 | # cibuildwheel (abbreviated cibw) will take care of building and packaging the Python wheel 17 | 18 | set -e 19 | 20 | # Find the Python root directory for the current Python version 21 | # This is important for the manylinux infrastructure, which is in 22 | # a nonstandard location that CMake has trouble finding 23 | PYTHON_EXECUTABLE=$(which python3) 24 | echo "Using Python_EXECUTABLE: ${PYTHON_EXECUTABLE}" 25 | 26 | # configure for all solvers with permissive licenses (BSD, MIT, etc..) 27 | ./configure.sh --bitwuzla --cvc5 --z3 --python --python-executable=${PYTHON_EXECUTABLE} 28 | cd build 29 | make -j 30 | -------------------------------------------------------------------------------- /ci-scripts/cibw-build-deps.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | ############################################################################### 3 | # Top contributors (to current version): 4 | # Makai Mann 5 | # 6 | # This file is part of the smt-switch project. 7 | # 8 | # Copyright (c) 2025 by the authors listed in the file AUTHORS 9 | # in the top-level source directory) and their institutional affiliations. 10 | # All rights reserved. See the file LICENSE in the top-level source 11 | # directory for licensing information.\endverbatim 12 | ############################################################################### 13 | # 14 | # This script builds all the permissive-license solvers that can be included 15 | # in the PyPi release. 16 | 17 | set -e 18 | 19 | python3 -m venv ./build-deps-env 20 | source ./build-deps-env/bin/activate 21 | python3 -m pip install meson pyparsing tomli 22 | 23 | ./contrib/setup-bitwuzla.sh 24 | # the version of ld.gold is too old in manylinux_2_28, remove it so cvc5 falls back on bfd 25 | rm -f /usr/bin/ld.gold 26 | source ./build-deps-env/bin/activate 27 | ./contrib/setup-cvc5.sh 28 | ./contrib/setup-z3.sh 29 | -------------------------------------------------------------------------------- /ci-scripts/setup-bitwuzla.sh: -------------------------------------------------------------------------------- 1 | ../contrib/setup-bitwuzla.sh -------------------------------------------------------------------------------- /ci-scripts/setup-btor.sh: -------------------------------------------------------------------------------- 1 | ../contrib/setup-boolector.sh -------------------------------------------------------------------------------- /ci-scripts/setup-cvc5.sh: -------------------------------------------------------------------------------- 1 | ../contrib/setup-cvc5.sh -------------------------------------------------------------------------------- /ci-scripts/setup-yices2.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # requires autoconf, gperf 4 | 5 | YICES2_VERSION=98fa2d882d83d32a07d3b8b2c562819e0e0babd0 6 | 7 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" 8 | DEPS=$DIR/../deps 9 | 10 | mkdir -p $DEPS 11 | 12 | if [ "$(uname)" == "Darwin" ]; then 13 | NUM_CORES=$(sysctl -n hw.logicalcpu) 14 | elif [ "$(expr substr $(uname -s) 1 5)" == "Linux" ]; then 15 | NUM_CORES=$(nproc) 16 | else 17 | NUM_CORES=1 18 | fi 19 | 20 | if [ ! -d "$DEPS/yices2" ]; then 21 | cd $DEPS 22 | git clone https://github.com/SRI-CSL/yices2.git 23 | chmod -R 777 yices2 24 | cd yices2 25 | git checkout -f $YICES2_VERSION 26 | autoconf 27 | ./configure --enable-thread-safety 28 | make build_dir=build BUILD=build -j$NUM_CORES 29 | cd $DIR 30 | else 31 | echo "$DEPS/yices2 already exists. If you want to rebuild, please remove it manually." 32 | fi 33 | 34 | if [ -f $DEPS/yices2/build/lib/libyices.a ] ; then \ 35 | echo "It appears yices2 was setup successfully into $DEPS/yices2." 36 | echo "You may now install it with make ./configure.sh --yices2 && cd build && make" 37 | else 38 | echo "Building yices2 failed." 39 | echo "You might be missing some dependencies." 40 | echo "Please see their github page for installation instructions: https://github.com/SRI-CSL/yices2" 41 | exit 1 42 | fi 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /ci-scripts/setup-z3.sh: -------------------------------------------------------------------------------- 1 | ../contrib/setup-z3.sh -------------------------------------------------------------------------------- /ci-scripts/travis-setup-osx-python.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ "$TRAVIS_OS_NAME" == "osx" ]; then 4 | ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" 5 | export PATH=/usr/local/bin:/usr/local/sbin:$PATH 6 | brew upgrade python 7 | else 8 | echo "NOT in OSX -- nothing to do" 9 | fi 10 | -------------------------------------------------------------------------------- /cmake/FindGMP.cmake: -------------------------------------------------------------------------------- 1 | # Find GMP 2 | # GMP_FOUND - system has GMP lib 3 | # GMP_INCLUDE_DIR - the GMP include directory 4 | # GMP_LIBRARIES - Libraries needed to use GMP 5 | 6 | find_path(GMP_INCLUDE_DIR NAMES gmp.h gmpxx.h) 7 | find_library(GMP_LIBRARIES NAMES gmp) 8 | find_library(GMPXX_LIBRARIES NAMES gmpxx) 9 | 10 | include(FindPackageHandleStandardArgs) 11 | find_package_handle_standard_args(GMP DEFAULT_MSG GMP_INCLUDE_DIR GMP_LIBRARIES) 12 | 13 | mark_as_advanced(GMP_INCLUDE_DIR GMP_LIBRARIES) 14 | if(GMP_LIBRARIES) 15 | message(STATUS "Found GMP libs: ${GMP_LIBRARIES}") 16 | endif() 17 | if (GMPXX_LIBRARIES) 18 | message(STATUS "Found GMPXX libs: ${GMPXX_LIBRARIES}") 19 | endif() 20 | -------------------------------------------------------------------------------- /cmake_uninstall.cmake.in: -------------------------------------------------------------------------------- 1 | if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt") 2 | message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt") 3 | endif(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt") 4 | 5 | file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files) 6 | string(REGEX REPLACE "\n" ";" files "${files}") 7 | foreach(file ${files}) 8 | message(STATUS "Uninstalling $ENV{DESTDIR}${file}") 9 | if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") 10 | exec_program( 11 | "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" 12 | OUTPUT_VARIABLE rm_out 13 | RETURN_VALUE rm_retval 14 | ) 15 | if(NOT "${rm_retval}" STREQUAL 0) 16 | message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") 17 | endif(NOT "${rm_retval}" STREQUAL 0) 18 | else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") 19 | message(STATUS "File $ENV{DESTDIR}${file} does not exist.") 20 | endif(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") 21 | endforeach(file) 22 | -------------------------------------------------------------------------------- /contrib/cmake-steps.sh: -------------------------------------------------------------------------------- 1 | #!/bin/echo Script should be sourced from contrib/setup-xxx.sh, not executed directly: 2 | declare -a cmake_options 3 | 4 | configure_step() { 5 | cmake_options+=( 6 | -DBUILD_SHARED_LIBS=OFF 7 | -DCMAKE_INSTALL_LIBDIR=lib # makes sure libraries go into deps/install/lib 8 | -DCMAKE_INSTALL_PREFIX="$install_dir" 9 | -DCMAKE_POLICY_VERSION_MINIMUM=3.5 # CMake 4.0 and later require 3.5 at minimum 10 | -DCMAKE_POSITION_INDEPENDENT_CODE=ON 11 | -DCMAKE_PREFIX_PATH="$install_dir" 12 | ) 13 | cmake -S . -B build "${cmake_options[@]}" 14 | } 15 | 16 | build_step() { 17 | cmake --build build -j$num_cores 18 | } 19 | 20 | install_step() { 21 | cmake --install build 22 | } 23 | -------------------------------------------------------------------------------- /contrib/make-steps.sh: -------------------------------------------------------------------------------- 1 | #!/bin/echo Script should be sourced from contrib/setup-xxx.sh, not executed directly: 2 | # Can be overridden for projects that don't use GNU autotools. 3 | if ! declare -F configure_step >/dev/null; then 4 | configure_step() { 5 | ./configure --prefix "$install_dir" 6 | } 7 | fi 8 | 9 | build_step() { 10 | make -j$num_cores 11 | } 12 | 13 | # Can be overridden for projects without an install target. 14 | if ! declare -F install_step >/dev/null; then 15 | install_step() { 16 | make install 17 | } 18 | fi 19 | -------------------------------------------------------------------------------- /contrib/memstream-0.1/Makefile: -------------------------------------------------------------------------------- 1 | all : test 2 | 3 | test : test.c memstream.o memstream.h 4 | cc -Wall -g -o $@ $< memstream.o 5 | 6 | memstream.o : memstream.c memstream.h 7 | cc -Wall -g -c memstream.c 8 | 9 | clean : .FORCE 10 | rm -rf *~ *.o test *.dSYM 11 | 12 | .FORCE : 13 | -------------------------------------------------------------------------------- /contrib/memstream-0.1/README: -------------------------------------------------------------------------------- 1 | Downloaded from: https://www.piumarta.com/software/memstream/ 2 | 3 | Serves as an open_memstream definition for Free BSD / Darwin systems that don't support it natively -------------------------------------------------------------------------------- /contrib/memstream-0.1/memstream.h: -------------------------------------------------------------------------------- 1 | #if defined(__linux__) 2 | # include 3 | #endif 4 | 5 | #include 6 | 7 | #if _POSIX_C_SOURCE < 200809L 8 | 9 | FILE *open_memstream(char **ptr, size_t *sizeloc); 10 | 11 | #endif /* _POSIX_C_SOURCE < 200809L */ 12 | -------------------------------------------------------------------------------- /contrib/memstream-0.1/test.c: -------------------------------------------------------------------------------- 1 | #include "memstream.h" 2 | 3 | #include 4 | #include 5 | 6 | int main() 7 | { 8 | char *buffer= 0; 9 | size_t size= 0; 10 | FILE *fp= open_memstream(&buffer, &size); 11 | int i; 12 | for (i= 0; i < 10240; ++i) { 13 | static char c= 42; 14 | fflush(fp); assert(size == i); 15 | fwrite(&c, 1, 1, fp); 16 | } 17 | fclose(fp); assert(size == 10240); 18 | free(buffer); 19 | fp= open_memstream(&buffer, &size); 20 | fprintf(fp, "This is a test of memstream, from main at %p.\n", main); 21 | fclose(fp); 22 | fputs(buffer, stdout); 23 | free(buffer); 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /contrib/meson-steps.sh: -------------------------------------------------------------------------------- 1 | #!/bin/echo Script should be sourced from contrib/setup-xxx.sh, not executed directly: 2 | declare -a meson_setup_options meson_compile_options 3 | 4 | configure_step() { 5 | meson_setup_options+=( 6 | -Dlibdir=lib # makes sure libraries go into deps/install/lib 7 | -Dprefix="$install_dir" 8 | ) 9 | meson setup build "${meson_setup_options[@]}" 10 | } 11 | 12 | build_step() { 13 | meson compile -C build ${meson_compile_options[@]+"${meson_compile_options[@]}"} 14 | } 15 | 16 | install_step() { 17 | meson install -C build 18 | } 19 | -------------------------------------------------------------------------------- /contrib/msat_instructions.txt: -------------------------------------------------------------------------------- 1 | MathSAT5 is covered under a custom license. Linking smt-switch against the MathSAT5 2 | library alters the license of smt-switch. 3 | 4 | If you choose to link against MathSAT5, you must obtain the MathSAT5 library yourself 5 | and ensure you meet all the license requirements. 6 | 7 | To link against the MathSAT5 library, download mathsat from 8 | https://mathsat.fbk.eu/download.html. Place the compressed files in ./deps and unpack 9 | it. Then rename the toplevel directory to mathsat. smt-switch will look for the files 10 | in ./deps/mathsat. 11 | 12 | Now you should be able to build smt-switch with MathSAT5 as a backend solver by 13 | configuring smt-switch with the --msat flag. 14 | -------------------------------------------------------------------------------- /contrib/setup-bison.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | version=3.8.2 3 | url=https://ftpmirror.gnu.org/gnu/bison/bison-$version.tar.gz 4 | 5 | source "$(dirname "$0")/make-steps.sh" 6 | source "$(dirname "$0")/common-setup.sh" 7 | -------------------------------------------------------------------------------- /contrib/setup-bitwuzla.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | git_commit=532ca9729136969008960481167ab55696a9cc52 3 | 4 | prepare_step() { 5 | "$contrib_dir/setup-cadical.sh" 6 | } 7 | 8 | source "$(dirname "$(realpath "$0")")/meson-steps.sh" 9 | source "$(dirname "$(realpath "$0")")/common-setup.sh" 10 | -------------------------------------------------------------------------------- /contrib/setup-boolector.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | git_tag=3.2.4 3 | cmake_options=(-DUSE_CADICAL=ON) 4 | 5 | prepare_step() { 6 | "$contrib_dir/setup-cadical.sh" 7 | "$contrib_dir/setup-btor2tools.sh" 8 | } 9 | 10 | source "$(dirname "$(realpath "$0")")/cmake-steps.sh" 11 | source "$(dirname "$(realpath "$0")")/common-setup.sh" 12 | -------------------------------------------------------------------------------- /contrib/setup-btor2tools.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | git_commit=fb69ee3b95e8baa5f0a9a6b0b19ee8beaad52932 3 | github_owner=hwmcc 4 | 5 | source "$(dirname "$(realpath "$0")")/cmake-steps.sh" 6 | source "$(dirname "$(realpath "$0")")/common-setup.sh" 7 | -------------------------------------------------------------------------------- /contrib/setup-cadical.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | git_tag=rel-2.1.3 3 | github_owner=arminbiere 4 | 5 | configure_step() { 6 | ./configure CXXFLAGS="-fPIC" 7 | } 8 | 9 | install_step() { 10 | install -m644 build/libcadical.a "$install_libdir" 11 | install -m644 src/ccadical.h "$install_includedir" 12 | install -m644 src/cadical.hpp "$install_includedir" 13 | install -m644 src/tracer.hpp "$install_includedir" 14 | } 15 | 16 | source "$(dirname "$0")/make-steps.sh" 17 | source "$(dirname "$0")/common-setup.sh" 18 | -------------------------------------------------------------------------------- /contrib/setup-cvc5.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | git_commit=befcee5dd12f2183b6a16a5b3d0b0d87fa2edd87 3 | cmake_options=(-DENABLE_AUTO_DOWNLOAD=ON -DUSE_POLY=ON) 4 | 5 | prepare_step() { 6 | "$contrib_dir/setup-cadical.sh" 7 | } 8 | 9 | source "$(dirname "$(realpath "$0")")/cmake-steps.sh" 10 | source "$(dirname "$(realpath "$0")")/common-setup.sh" 11 | -------------------------------------------------------------------------------- /contrib/setup-flex.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | version=2.6.4 3 | url=https://github.com/westes/flex/releases/download/v$version/flex-$version.tar.gz 4 | 5 | source "$(dirname "$0")/make-steps.sh" 6 | source "$(dirname "$0")/common-setup.sh" 7 | -------------------------------------------------------------------------------- /contrib/setup-z3.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | git_tag=z3-4.14.1 3 | github_owner=Z3Prover 4 | cmake_options=(-DZ3_BUILD_LIBZ3_SHARED=Off) 5 | 6 | source "$(dirname "$(realpath "$0")")/cmake-steps.sh" 7 | source "$(dirname "$(realpath "$0")")/common-setup.sh" 8 | -------------------------------------------------------------------------------- /contrib/yices2_instructions.txt: -------------------------------------------------------------------------------- 1 | Yices2 is covered under the GPLv3 license. Linking smt-switch against the Yices2 library 2 | alters the license of smt-switch. 3 | 4 | If you choose to link against Yices2, you must obtain the Yices2 library yourself and 5 | ensure you meet all the license requirements. 6 | 7 | To link against the Yices2 library, download Yices2 from 8 | https://github.com/SRI-CSL/yices2 and place the directory in ./deps. 9 | 10 | Then, build the yices2 library: 11 | cd deps/yices2 12 | autoconf 13 | ./configure --enable-thread-safety 14 | make build_dir=build BUILD=build 15 | 16 | Now you should be able to build smt-switch with Yices2 as a backend solver by configuring 17 | smt-switch with the --yices2 flag. 18 | -------------------------------------------------------------------------------- /cvc5/include/cvc5_datatype.h: -------------------------------------------------------------------------------- 1 | 2 | /********************* */ 3 | /*! \file cvc5_datatype.h 4 | ** \verbatim 5 | ** Top contributors (to current version): 6 | ** Kristopher Brown 7 | ** This file is part of the smt-switch project. 8 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 9 | ** in the top-level source directory) and their institutional affiliations. 10 | ** All rights reserved. See the file LICENSE in the top-level source 11 | ** directory for licensing information.\endverbatim 12 | ** 13 | ** \brief Thin wrapper for cvc5 Datatype-related classes. 14 | **/ 15 | 16 | #pragma once 17 | 18 | #include "cvc5/cvc5.h" 19 | #include "datatype.h" 20 | #include "exceptions.h" 21 | 22 | namespace smt { 23 | 24 | class Cvc5DatatypeDecl : public AbsDatatypeDecl 25 | { 26 | public: 27 | Cvc5DatatypeDecl(cvc5::DatatypeDecl t) : datatypedecl(t){}; 28 | 29 | protected: 30 | cvc5::DatatypeDecl datatypedecl; 31 | 32 | friend class Cvc5Solver; 33 | }; 34 | 35 | class Cvc5DatatypeConstructorDecl : public AbsDatatypeConstructorDecl 36 | { 37 | public: 38 | Cvc5DatatypeConstructorDecl(cvc5::DatatypeConstructorDecl t) 39 | : datatypeconstructordecl(t){}; 40 | bool compare(const DatatypeConstructorDecl &) const override; 41 | 42 | protected: 43 | cvc5::DatatypeConstructorDecl datatypeconstructordecl; 44 | 45 | friend class Cvc5Solver; 46 | }; 47 | 48 | class Cvc5Datatype : public AbsDatatype 49 | { 50 | public: 51 | Cvc5Datatype(cvc5::Datatype t) : datatype(t){}; 52 | std::string get_name() const override { return datatype.getName(); } 53 | int get_num_constructors() const override 54 | { 55 | return datatype.getNumConstructors(); 56 | } 57 | int get_num_selectors(std::string cons) const override 58 | { 59 | for (int i = 0; i != datatype.getNumConstructors(); i++) 60 | { 61 | cvc5::DatatypeConstructor ct = datatype[i]; 62 | if (ct.getName() == cons) 63 | { 64 | return ct.getNumSelectors(); 65 | } 66 | } 67 | throw InternalSolverException(datatype.getName() + "." + cons 68 | + " not found"); 69 | } 70 | 71 | protected: 72 | cvc5::Datatype datatype; 73 | 74 | friend class Cvc5Solver; 75 | }; 76 | 77 | } // namespace smt 78 | -------------------------------------------------------------------------------- /cvc5/include/cvc5_sort.h: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file cvc5_sort.h 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief cvc5 implementation of AbsSort 13 | ** 14 | ** 15 | **/ 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | #include "cvc5/cvc5.h" 22 | #include "cvc5/cvc5_kind.h" 23 | #include "sort.h" 24 | 25 | namespace smt { 26 | 27 | // forward declaration 28 | class Cvc5Solver; 29 | 30 | class Cvc5Sort : public AbsSort 31 | { 32 | public: 33 | Cvc5Sort(::cvc5::Sort s) : sort(s){}; 34 | ~Cvc5Sort() = default; 35 | std::string to_string() const override; 36 | std::size_t hash() const override; 37 | uint64_t get_width() const override; 38 | Sort get_indexsort() const override; 39 | Sort get_elemsort() const override; 40 | SortVec get_domain_sorts() const override; 41 | Sort get_codomain_sort() const override; 42 | std::string get_uninterpreted_name() const override; 43 | size_t get_arity() const override; 44 | SortVec get_uninterpreted_param_sorts() const override; 45 | Datatype get_datatype() const override; 46 | bool compare(const Sort &) const override; 47 | SortKind get_sort_kind() const override; 48 | 49 | // getters for solver-specific objects 50 | // for interacting with third-party cvc5-specific software 51 | ::cvc5::Sort get_cvc5_sort() const { return sort; }; 52 | 53 | protected: 54 | ::cvc5::Sort sort; 55 | 56 | friend class Cvc5Solver; 57 | }; 58 | 59 | } // namespace smt 60 | -------------------------------------------------------------------------------- /cvc5/src/cvc5_datatype.cpp: -------------------------------------------------------------------------------- 1 | #include "cvc5_datatype.h" 2 | namespace smt { 3 | 4 | bool Cvc5DatatypeConstructorDecl::compare( 5 | const DatatypeConstructorDecl & d) const 6 | { 7 | std::shared_ptr cd = 8 | std::static_pointer_cast(d); 9 | return datatypeconstructordecl.toString() 10 | == cd->datatypeconstructordecl.toString(); 11 | } 12 | 13 | } // namespace smt 14 | -------------------------------------------------------------------------------- /cvc5/src/cvc5_factory.cpp: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file cvc5_factory.cpp 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief Factory for creating a cvc5 SmtSolver 13 | ** 14 | ** 15 | **/ 16 | 17 | #include "cvc5_factory.h" 18 | 19 | #include "cvc5_solver.h" 20 | #include "logging_solver.h" 21 | 22 | namespace smt { 23 | 24 | /* Cvc5SolverFactory implementation */ 25 | SmtSolver Cvc5SolverFactory::create(bool logging) 26 | { 27 | SmtSolver solver = std::make_shared(); 28 | if (logging) 29 | { 30 | solver = std::make_shared(solver); 31 | } 32 | return solver; 33 | } 34 | 35 | SmtSolver Cvc5SolverFactory::create_interpolating_solver() 36 | { 37 | SmtSolver solver = std::make_shared(); 38 | /* 39 | * Enable interpolant generation. 40 | * */ 41 | solver->set_opt("produce-interpolants", "true"); 42 | solver->set_opt("incremental", "false"); 43 | return solver; 44 | } 45 | /* end Cvc5SolverFactory implementation */ 46 | 47 | } // namespace smt 48 | -------------------------------------------------------------------------------- /examples/Makefile: -------------------------------------------------------------------------------- 1 | all: cvc5_qf_ufbv btor_qf_ufbv 2 | 3 | # Note: assumes smt-switch has been installed in a directory called 4 | # example-install in this directory, which is automated by build.sh 5 | 6 | cvc5_qf_ufbv: cvc5_qf_ufbv.cpp 7 | $(CXX) -std=c++11 -I./example-install/include -L./example-install/lib -Wl,-rpath,./example-install/lib cvc5_qf_ufbv.cpp -o cvc5_qf_ufbv.out -lsmt-switch-cvc5 -lsmt-switch 8 | 9 | btor_qf_ufbv: btor_qf_ufbv.cpp 10 | $(CXX) -std=c++11 -I./example-install/include -L./example-install/lib -Wl,-rpath,./example-install/lib btor_qf_ufbv.cpp -o btor_qf_ufbv.out -lsmt-switch-btor -lsmt-switch 11 | 12 | clean: 13 | rm -rf cvc5_qf_ufbv.out btor_qf_ufbv.out 14 | 15 | clean-all: clean 16 | rm -rf ./example-build ./example-install 17 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | # Examples 2 | 3 | This directory contains example usage of smt-switch. 4 | 5 | ## QF_UFBV 6 | `QF_UFBV` stands for quantifier-free uninterpreted functions and bit-vectors. 7 | The files [cvc5_qf_ufbv.cpp](cvc5_qf_ufbv.cpp) and 8 | [btor_qf_ufbv.cpp](btor_qf_ufbv.cpp) demonstrate some common usage of the API 9 | with this logic. 10 | 11 | The `build.sh` script will setup and install smt-switch in this directory and 12 | then build the examples. The script has comments explaining each step for 13 | building smt-switch. The script assumes you already have dependencies installed 14 | and that boolector and cvc5 have been built in the top-level repository under 15 | `deps/cvc5` and `deps/boolector`. You can use the helper scripts 16 | [setup-cvc5.sh](../contrib/setup-cvc5.sh) and 17 | [setup-btor.sh](../contrib/setup-btor.sh) to automate this. If the build script 18 | fails and you haven't recently installed the solvers, you might have an old 19 | version. You can try deleting them from `deps` and rebuilding them. 20 | 21 | You can look at the `Makefile` to understand how to link smt-switch to a binary. 22 | If the script succeeds in building everything, you can run each of the files 23 | with `./cvc5_qf_ufbv.out` and `./btor_qf_ufbv.out`, respectively. Note that 24 | there may be a delay for looking up the shared libraries on some systems the 25 | first time they are run. Importantly, notice that the files differ by only two 26 | lines of code (excluding comments), demonstrating that changing the solver is 27 | straightforward. 28 | 29 | To explore the API, you can change either of those files and run `make` again. 30 | To remove the built binaries, run `make clean`. To clean up all the build and 31 | install files for `smt-switch` in this directory, run `make clean-all`. 32 | 33 | ## Python bindings 34 | You can also run the same example through the Python bindings with the file, 35 | [python_qf_ufbv.py](python_qf_ufbv.py). This requires building the Python 36 | bindings, which can be done by running `./build.sh --python`. If you have 37 | already built without Python bindings, please run `make clean-all` before 38 | rebuilding. `Python3` along with the modules `Cython` and `pytest` are required 39 | for building the bindings and running the example. It is recommended to use a 40 | `Python3` [virtual environment](https://docs.python.org/3/library/venv.html). 41 | -------------------------------------------------------------------------------- /examples/btor_qf_ufbv.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "smt-switch/boolector_factory.h" 3 | #include "smt-switch/smt.h" 4 | using namespace smt; 5 | using namespace std; 6 | int main() 7 | { 8 | // Boolector aliases booleans and bitvectors of size one 9 | // and also performs on-the-fly rewriting 10 | // if you'd like to maintain the term structure, you can 11 | // enable logging by passing true 12 | SmtSolver s = BoolectorSolverFactory::create(false); 13 | 14 | s->set_logic("QF_UFBV"); 15 | s->set_opt("incremental", "true"); 16 | s->set_opt("produce-models", "true"); 17 | s->set_opt("produce-unsat-assumptions", 18 | "true"); 19 | Sort bvs = s->make_sort(BV, 32); 20 | Sort funs = 21 | s->make_sort(FUNCTION, {bvs, bvs}); 22 | 23 | Term x = s->make_symbol("x", bvs); 24 | Term y = s->make_symbol("y", bvs); 25 | Term f = s->make_symbol("f", funs); 26 | 27 | Op ext = Op(Extract, 15, 0); 28 | Term x0 = s->make_term(ext, x); 29 | Term y0 = s->make_term(ext, y); 30 | 31 | Term fx = s->make_term(Apply, f, x); 32 | Term fy = s->make_term(Apply, f, y); 33 | s->assert_formula( 34 | s->make_term(Distinct, fx, fy)); 35 | 36 | s->push(1); 37 | s->assert_formula( 38 | s->make_term(Equal, x0, y0)); 39 | cout << s->check_sat() << endl; 40 | 41 | cout << s->get_value(x) << endl; 42 | s->pop(1); 43 | 44 | Term xy = s->make_term(BVAnd, x, y); 45 | Term a1 = s->make_term(BVUge, x0, y0); 46 | Term a2 = s->make_term(BVUge, xy, x); 47 | Term a3 = s->make_term(BVUge, xy, y); 48 | cout << 49 | s->check_sat_assuming({a1, a2, a3}) 50 | << endl; 51 | UnorderedTermSet ua; 52 | s->get_unsat_assumptions(ua); 53 | for (Term t : ua) { cout << t << endl; } 54 | } 55 | -------------------------------------------------------------------------------- /examples/build.sh: -------------------------------------------------------------------------------- 1 | # get the absolute path to this directory 2 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" 3 | 4 | set -e 5 | 6 | help_message() 7 | { 8 | echo "usage: $0 [--python]" 9 | echo "this script builds smt-switch and the C++ examples" 10 | echo "it also builds and installs the python bindings if run with --python" 11 | exit 0 12 | } 13 | 14 | if [[ "$1" == "--help" ]]; then 15 | help_message 16 | fi 17 | 18 | if [ $# -gt 2 ]; then 19 | help_message 20 | elif [[ $# -eq 1 && "$1" != "--python" ]]; then 21 | help_message 22 | fi 23 | 24 | 25 | # go to main repo directory 26 | cd $DIR/.. 27 | 28 | # configure and build smt-switch with boolector and cvc5 backends 29 | # set it up to be installed in a directory called example-install in the examples directory 30 | # also use a build directory in the examples directory 31 | ./configure.sh --btor --cvc5 --prefix=./examples/example-install --build-dir=$DIR/example-build $1 32 | cd $DIR/example-build 33 | make 34 | make test 35 | make install 36 | 37 | cd $DIR 38 | # now make the examples 39 | make 40 | 41 | # install python bindings with pip 42 | # this line might need to be adjusted depending on your current python environment 43 | python3 -m pip install -e $DIR/example-build/python 44 | -------------------------------------------------------------------------------- /examples/cvc5_qf_ufbv.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "smt-switch/cvc5_factory.h" 4 | #include "smt-switch/smt.h" 5 | using namespace smt; 6 | using namespace std; 7 | int main() 8 | { 9 | // cvc5 does not alias sorts or do on-the-fly rewriting 10 | // Thus there shouldn't be a reason to enable logging 11 | // so the parameter to create is false 12 | SmtSolver s = Cvc5SolverFactory::create(false); 13 | 14 | s->set_logic("QF_UFBV"); 15 | s->set_opt("incremental", "true"); 16 | s->set_opt("produce-models", "true"); 17 | s->set_opt("produce-unsat-assumptions", "true"); 18 | Sort bvs = s->make_sort(BV, 32); 19 | Sort funs = s->make_sort(FUNCTION, { bvs, bvs }); 20 | 21 | Term x = s->make_symbol("x", bvs); 22 | Term y = s->make_symbol("y", bvs); 23 | Term f = s->make_symbol("f", funs); 24 | 25 | Op ext = Op(Extract, 15, 0); 26 | Term x0 = s->make_term(ext, x); 27 | Term y0 = s->make_term(ext, y); 28 | 29 | Term fx = s->make_term(Apply, f, x); 30 | Term fy = s->make_term(Apply, f, y); 31 | s->assert_formula(s->make_term(Distinct, fx, fy)); 32 | 33 | s->push(1); 34 | s->assert_formula(s->make_term(Equal, x0, y0)); 35 | cout << s->check_sat() << endl; 36 | 37 | cout << s->get_value(x) << endl; 38 | s->pop(1); 39 | 40 | Term xy = s->make_term(BVAnd, x, y); 41 | Term a1 = s->make_term(BVUge, x0, y0); 42 | Term a2 = s->make_term(BVUge, xy, x); 43 | Term a3 = s->make_term(BVUge, xy, y); 44 | cout << s->check_sat_assuming({ a1, a2, a3 }) << endl; 45 | UnorderedTermSet ua; 46 | s->get_unsat_assumptions(ua); 47 | for (Term t : ua) 48 | { 49 | cout << t << endl; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /examples/python_qf_ufbv.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import smt_switch as ss 3 | from smt_switch.primops import Apply, Distinct, Equal, Extract, BVAnd, BVUge 4 | 5 | if __name__ == "__main__": 6 | s = ss.create_btor_solver(True) 7 | s.set_logic('QF_UFBV') 8 | s.set_opt('incremental', 'true') 9 | s.set_opt('produce-models', 'true') 10 | s.set_opt('produce-unsat-assumptions', 'true') 11 | bvs = s.make_sort(ss.sortkinds.BV, 32) 12 | funs = s.make_sort(ss.sortkinds.FUNCTION, [bvs, bvs]) 13 | 14 | x = s.make_symbol('x', bvs) 15 | y = s.make_symbol('y', bvs) 16 | f = s.make_symbol('f', funs) 17 | 18 | ext = ss.Op(Extract, 15, 0) 19 | x0 = s.make_term(ext, x) 20 | y0 = s.make_term(ext, y) 21 | 22 | fx = s.make_term(Apply, f, x) 23 | fy = s.make_term(Apply, f, y) 24 | s.assert_formula(s.make_term(Distinct, fx, fy)) 25 | 26 | s.push(1) 27 | s.assert_formula(s.make_term(Equal, x0, y0)) 28 | print(s.check_sat()) 29 | print(s.get_value(x)) 30 | s.pop(1) 31 | 32 | xy = s.make_term(BVAnd, x, y) 33 | a1 = s.make_term(BVUge, xy, x); 34 | a2 = s.make_term(BVUge, xy, y); 35 | a3 = s.make_term(BVUge, x0, y0); 36 | print(s.check_sat_assuming([a1,a2,a3])) 37 | print(s.get_unsat_assumptions()) 38 | -------------------------------------------------------------------------------- /include/bitwuzla_factory.h: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file bitwuzla_factory.h 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief Factory for creating a Bitwuzla SmtSolver 13 | ** 14 | ** 15 | **/ 16 | 17 | #pragma once 18 | 19 | #include "smt_defs.h" 20 | 21 | namespace smt { 22 | class BitwuzlaSolverFactory 23 | { 24 | public: 25 | /** Create a bitwuzla SmtSolver 26 | * @param logging if true creates a LoggingSolver wrapper 27 | * around the solver that keeps a shadow DAG at 28 | * the smt-switch level. 29 | * For bitwuzla, this is not required but will 30 | * but makes it easier to transfer terms to other 31 | * solvers because it avoids the bool / width one 32 | * bitvector sort aliasing 33 | * @return a Bitwuzla SmtSolver 34 | */ 35 | static SmtSolver create(bool logging); 36 | }; 37 | } // namespace smt 38 | -------------------------------------------------------------------------------- /include/boolector_factory.h: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file boolector_factory.h 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief Factory for creating a Boolector SmtSolver 13 | ** 14 | ** 15 | **/ 16 | 17 | #pragma once 18 | 19 | #include "smt_defs.h" 20 | 21 | namespace smt { 22 | class BoolectorSolverFactory 23 | { 24 | public: 25 | /** Create a boolector SmtSolver 26 | * @param logging if true creates a LoggingSolver wrapper 27 | * around the solver that keeps a shadow DAG at 28 | * the smt-switch level. 29 | * For boolector, this is not required but will 30 | * but makes it easier to transfer terms to other 31 | * solvers because it avoids the bool / width one 32 | * bitvector sort aliasing 33 | * @return a Boolector SmtSolver 34 | */ 35 | static SmtSolver create(bool logging); 36 | }; 37 | } // namespace smt 38 | -------------------------------------------------------------------------------- /include/cvc5_factory.h: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file cvc5_factory.h 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief Factory for creating a cvc5 SmtSolver 13 | ** 14 | ** 15 | **/ 16 | 17 | #pragma once 18 | 19 | #include "smt_defs.h" 20 | 21 | namespace smt { 22 | class Cvc5SolverFactory 23 | { 24 | public: 25 | /** Create a cvc5 SmtSolver 26 | * @param logging if true creates a LoggingSolver wrapper 27 | * around the solver that keeps a shadow DAG at 28 | * the smt-switch level. 29 | * For cvc5 this should never be necessary because 30 | * the cvc5 API does not alias any sorts or 31 | * perform on-the-fly rewriting. 32 | * @return a cvc5 SmtSolver 33 | */ 34 | static SmtSolver create(bool logging); 35 | 36 | /** Create an interpolating cvc5 SmtSolver 37 | * @return an interpolating cvc5 SmtSolver 38 | */ 39 | static SmtSolver create_interpolating_solver(); 40 | }; 41 | } // namespace smt 42 | -------------------------------------------------------------------------------- /include/datatype.h: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file datatype.h 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Kristopher Brown 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief Abstract interface for SMT datatypes. 13 | ** 14 | ** 15 | **/ 16 | 17 | #pragma once 18 | 19 | #include "smt_defs.h" 20 | 21 | 22 | namespace smt { 23 | 24 | class AbsDatatypeDecl { 25 | 26 | public: 27 | AbsDatatypeDecl(){}; 28 | virtual ~AbsDatatypeDecl(){}; 29 | 30 | }; 31 | 32 | 33 | class AbsDatatypeConstructorDecl { 34 | 35 | public: 36 | AbsDatatypeConstructorDecl(){}; 37 | virtual ~AbsDatatypeConstructorDecl(){}; 38 | virtual bool compare(const DatatypeConstructorDecl & d) const = 0; 39 | }; 40 | 41 | 42 | class AbsDatatype { 43 | 44 | public: 45 | AbsDatatype(){}; 46 | virtual ~AbsDatatype(){}; 47 | virtual std::string get_name() const=0; 48 | virtual int get_num_selectors(std::string cons) const=0; 49 | virtual int get_num_constructors() const=0; 50 | }; 51 | // Overloaded equivalence operators for two datatype constructor declarations 52 | bool operator==(const DatatypeConstructorDecl & d1, 53 | const DatatypeConstructorDecl & d2); 54 | bool operator!=(const DatatypeConstructorDecl & d1, 55 | const DatatypeConstructorDecl & d2); 56 | } 57 | -------------------------------------------------------------------------------- /include/msat_factory.h: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file msat_factory.h 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief Factory for creating a MathSAT SmtSolver 13 | ** 14 | ** 15 | **/ 16 | 17 | #pragma once 18 | 19 | #include "smt_defs.h" 20 | 21 | namespace smt { 22 | class MsatSolverFactory 23 | { 24 | public: 25 | /** Create a MathSAT SmtSolver 26 | * @param logging if true creates a LoggingSolver wrapper 27 | * around the solver that keeps a shadow DAG at 28 | * the smt-switch level. 29 | * For MathSAT this should not be needed because 30 | * it does not alias sorts. However, it does 31 | * do some light rewriting on-the-fly, so if 32 | * you want to guarantee that you get the exact 33 | * term you created back from term traversal, 34 | * please enable logging. 35 | * @return a MathSAT SmtSolver 36 | */ 37 | static SmtSolver create(bool logging); 38 | 39 | /** Create an interpolating MathSAT SmtSolver 40 | * @return an interpolating MathSAT SmtSolver 41 | */ 42 | static SmtSolver create_interpolating_solver(); 43 | }; 44 | } // namespace smt 45 | -------------------------------------------------------------------------------- /include/portfolio_solver.h: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file portfolio_solver.h 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Amalee Wilson 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2021 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief Header for a portfolio solving function that takes a vector 13 | ** of solvers and a term, and returns check_sat from the first solver 14 | ** that finishes. 15 | **/ 16 | #pragma once 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | #include "smt.h" 23 | 24 | namespace smt { 25 | 26 | class PortfolioSolver 27 | { 28 | public: 29 | PortfolioSolver(std::vector slvrs, Term trm); 30 | 31 | /** Launch many solvers and return whether the term is satisfiable when one of 32 | * them has finished. 33 | * @param solvers The solvers to run. 34 | * @param t The term to be checked. 35 | */ 36 | smt::Result portfolio_solve(); 37 | 38 | private: 39 | smt::Result result; 40 | std::vector solvers; 41 | Term portfolio_term; 42 | // Once a solver is done, result has been set, 43 | // and the main thread can terminate the others. 44 | bool a_solver_is_done = false; 45 | 46 | // Used for synchronization. 47 | std::mutex m; 48 | std::condition_variable cv; 49 | 50 | /** Translate the term t to the solver s, and check_sat. 51 | * @param s The solver to translate the term t to. 52 | * @param t The term being translated to solver s. 53 | */ 54 | void run_solver(SmtSolver s); 55 | }; 56 | } // namespace smt 57 | -------------------------------------------------------------------------------- /include/result.h: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file result.h 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann, Clark Barrett 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief The result of a call to check-sat or check-sat-assuming. 13 | ** 14 | ** 15 | **/ 16 | 17 | #pragma once 18 | 19 | namespace smt 20 | { 21 | enum ResultType 22 | { 23 | SAT = 0, 24 | UNSAT, 25 | UNKNOWN, 26 | /** IMPORTANT: This must stay at the bottom. 27 | It's only use is for sizing the result2str array 28 | */ 29 | NUM_RESULTS 30 | }; 31 | 32 | struct Result 33 | { 34 | Result() : result(NUM_RESULTS), explanation("null") {} 35 | Result(ResultType rt, std::string explanation = "no explanation") 36 | : result(rt), explanation(explanation) 37 | { 38 | } 39 | bool is_sat() const { return result == SAT; }; 40 | bool is_unsat() const { return result == UNSAT; }; 41 | bool is_unknown() const { return result == UNKNOWN; }; 42 | bool is_null() const { return result == NUM_RESULTS; }; 43 | std::string get_explanation() const; 44 | std::string to_string() const; 45 | ResultType result; 46 | std::string explanation; 47 | }; 48 | 49 | std::ostream & operator<<(std::ostream & output, const Result r); 50 | bool operator==(const Result & r1, const Result & r2); 51 | } // namespace smt 52 | -------------------------------------------------------------------------------- /include/smt.h: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file smt.h 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann, Clark Barrett 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief The main include file for the smt-switch abstract interface. 13 | ** 14 | ** 15 | **/ 16 | 17 | #pragma once 18 | 19 | // Exceptions used by SMT API. 20 | #include "exceptions.h" // IWYU pragma: export 21 | 22 | // Class and smart pointer definitions. 23 | #include "smt_defs.h" // IWYU pragma: export 24 | 25 | // SMT-LIB Sort and Function operators. 26 | #include "ops.h" // IWYU pragma: export 27 | 28 | // Abstract sort interface. 29 | #include "sort.h" // IWYU pragma: export 30 | 31 | // Abstract term interface. 32 | #include "term.h" // IWYU pragma: export 33 | 34 | // Transfer terms between solvers. 35 | #include "term_translator.h" // IWYU pragma: export 36 | 37 | // Main solver interface. 38 | #include "solver.h" // IWYU pragma: export 39 | 40 | // Solver enums for identifying solver 41 | #include "solver_enums.h" // IWYU pragma: export 42 | -------------------------------------------------------------------------------- /include/smt_defs.h: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file smt_defs.h 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann, Clark Barrett 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief Type definitions for pointers to main abstract objects. 13 | ** 14 | ** 15 | **/ 16 | 17 | // IWYU pragma: private, include "smt.h" 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | namespace smt { 24 | 25 | struct Op; 26 | 27 | class AbsSort; 28 | using Sort = std::shared_ptr; 29 | 30 | class AbsTerm; 31 | using Term = std::shared_ptr; 32 | 33 | class AbsSmtSolver; 34 | using SmtSolver = std::shared_ptr; 35 | 36 | // Datatype theory related 37 | class AbsDatatypeDecl; 38 | using DatatypeDecl = std::shared_ptr; 39 | 40 | class AbsDatatypeConstructorDecl; 41 | using DatatypeConstructorDecl = std::shared_ptr; 42 | 43 | class AbsDatatype; 44 | using Datatype = std::shared_ptr; 45 | 46 | } // namespace smt 47 | -------------------------------------------------------------------------------- /include/smtlib_utils.h: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file smtlib_utils.h 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Yoni Zohar 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief SMT-LIB Utility functions. 13 | ** 14 | ** 15 | **/ 16 | 17 | #pragma once 18 | 19 | /* string constants for the SMT-LIB commands */ 20 | const std::string SET_OPTION_STR = "set-option"; 21 | const std::string SET_LOGIC_STR = "set-logic"; 22 | const std::string DECLARE_FUN_STR = "declare-fun"; 23 | const std::string DEFINE_FUN_STR = "define-fun"; 24 | const std::string DECLARE_SORT_STR = "declare-sort"; 25 | const std::string DEFINE_SORT_STR = "define-sort"; 26 | const std::string ASSERT_STR = "assert"; 27 | const std::string CHECK_SAT_STR = "check-sat"; 28 | const std::string CHECK_SAT_ASSUMING_STR = "check-sat-assuming"; 29 | const std::string GET_VALUE_STR = "get-value"; 30 | const std::string GET_UNSAT_ASSUMPTIONS_STR = "get-unsat-assumptions"; 31 | const std::string PUSH_STR = "push"; 32 | const std::string POP_STR = "pop"; 33 | const std::string RESET_ASSERTIONS_STR = "reset-assertions"; 34 | const std::string RESET_STR = "reset"; 35 | const std::string INTERPOLATION_GROUP_STR = "interpolation-group"; 36 | const std::string MSAT_GET_INTERPOLANT_STR = "get-interpolant"; 37 | const std::string CVC5_GET_INTERPOLANT_STR = "get-interpolant"; 38 | const std::string DECLARE_DATATYPE_STR = "declare-datatypes"; 39 | -------------------------------------------------------------------------------- /include/solver_utils.h: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file solver_utils.h 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief Utility functions for solver implementations. Meant for internal 13 | ** use only, not from the API. 14 | ** 15 | **/ 16 | #pragma once 17 | 18 | #include "smt.h" 19 | 20 | namespace smt { 21 | 22 | /** Create distinctness constraint for each unique pair 23 | * @param terms the vector of terms to make distinct 24 | * @return the distinctness constraint 25 | */ 26 | smt::Term make_distinct(const smt::AbsSmtSolver * solver, 27 | const smt::TermVec & terms); 28 | 29 | } // namespace smt 30 | -------------------------------------------------------------------------------- /include/substitution_walker.h: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file substitution_walker.h 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief Substitution walker for doing substitutions with a persistent cache 13 | ** 14 | **/ 15 | 16 | #pragma once 17 | 18 | #include "identity_walker.h" 19 | 20 | namespace smt { 21 | // class for doing substitutions 22 | // can more efficient than SmtSolver::substitute if it 23 | // is called repeatedly since it has a persistent cache 24 | // NOTE: don't even need to override visit_term 25 | // just need to prepulate the cache 26 | class SubstitutionWalker : public IdentityWalker 27 | { 28 | public: 29 | SubstitutionWalker(const smt::SmtSolver & solver, 30 | const smt::UnorderedTermMap & smap); 31 | }; 32 | } // namespace smt 33 | -------------------------------------------------------------------------------- /include/term_hashtable.h: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file term_hashtable.h 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief A simple hash table for terms -- used for hash-consing in 13 | ** LoggingSolver 14 | ** 15 | ** 16 | **/ 17 | 18 | #pragma once 19 | 20 | #include 21 | 22 | #include "smt_defs.h" 23 | #include "term.h" 24 | 25 | namespace smt { 26 | 27 | /** \class TermHashTable 28 | * A very straightforward implementation of a Term hash table 29 | * using a std::unordered_map and UnorderedTermSet 30 | * The primary use of this is for hash-consing in LoggingSolver 31 | */ 32 | class TermHashTable 33 | { 34 | public: 35 | TermHashTable(); 36 | ~TermHashTable(); 37 | void insert(const Term & t); 38 | /** check if a term is in the table 39 | * @param the term to check 40 | * @return true iff the term is already in the table 41 | */ 42 | bool contains(const Term & t) const; 43 | /** lookup a term and modify pointer in place 44 | * @param t the term to look up and modify 45 | * @return true iff the term was found in the hash table 46 | */ 47 | bool lookup(Term & t); 48 | void erase(const Term & t); 49 | void clear(); 50 | 51 | protected: 52 | std::unordered_map table; 53 | }; 54 | 55 | } // namespace smt 56 | -------------------------------------------------------------------------------- /include/yices2_factory.h: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file yices2_factory.h 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Amalee Wilson 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief Factory for creating a Yices2 SmtSolver 13 | ** 14 | ** 15 | **/ 16 | 17 | #pragma once 18 | 19 | #include "smt_defs.h" 20 | 21 | namespace smt { 22 | class Yices2SolverFactory 23 | { 24 | public: 25 | /** Create a Yices2 SmtSolver 26 | * @param logging if true creates a LoggingSolver wrapper 27 | * around the solver that keeps a shadow DAG at 28 | * the smt-switch level. 29 | * For yices2, logging is *required* if you want 30 | * to traverse terms. 31 | * @return a Yices2 SmtSolver 32 | */ 33 | static SmtSolver create(bool logging); 34 | }; 35 | } // namespace smt 36 | -------------------------------------------------------------------------------- /include/z3_factory.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "smt_defs.h" 4 | 5 | namespace smt { 6 | class Z3SolverFactory 7 | { 8 | public: 9 | /** Create a Z3 SmtSolver 10 | * @param logging if true creates a LoggingSolver wrapper 11 | * around the solver that keeps a shadow DAG at 12 | * the smt-switch level. 13 | * For yices2, logging is *required* if you want 14 | * to traverse terms. 15 | * @return a Z3 SmtSolver 16 | */ 17 | static SmtSolver create(bool logging); 18 | }; 19 | } // namespace smt 20 | -------------------------------------------------------------------------------- /issues.md: -------------------------------------------------------------------------------- 1 | # Issues to Consider 2 | 3 | ## Hashing 4 | * If we rely on the solver to traverse terms and wrap the resulting terms, we need to rely on the equality operator for the underlying objects 5 | * If everything is a shared_ptr, this might be counterintuitive, because you can use == but it won't do quite what you think 6 | * it sounds like it does compare the underlying data, but even that might not be good enough 7 | * Imagine you have two versions of an AbsTerm implementation, one from when it was created and one that was supplied by the solver when traversing 8 | * There's no way to tell if they're the same or different, without comparing the underlying solver term that is pointed to 9 | 10 | ## Models 11 | * in Boolector, assignments are returned as strings. 12 | * We can then turn these back into bit-vectors, but there's no way to recover the value once it's a node again 13 | * Additionally, for arrays, there's no boolector structure for this. We'll need to have a representation for this 14 | * cvc5 has it's stores on a constant array structure, but maybe we should have a common representation for all solvers 15 | * a map with a default value would be most convenient 16 | 17 | ## Sorts 18 | * It would be useful to be able to query the sort from boolector - two options 19 | * reconstruct a sort object using calls to boolector functions <-- I think this one is better 20 | * but, whenever possible, don't reconstruct a sort object 21 | * for example, in get_value, can do everything with raw BoolectorSorts 22 | * store it explicitly -- this would require knowing what sort an op produces 23 | -------------------------------------------------------------------------------- /msat/include/msat_sort.h: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file msat_sort.h 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief MathSAT implementation of AbsSort 13 | ** 14 | ** 15 | **/ 16 | 17 | #pragma once 18 | 19 | #include "sort.h" 20 | 21 | #include "mathsat.h" 22 | 23 | namespace smt { 24 | // forward declaration 25 | class MsatSolver; 26 | 27 | class MsatSort : public AbsSort 28 | { 29 | public: 30 | MsatSort(msat_env e, msat_type t) : env(e), type(t), is_uf_type(false) {}; 31 | MsatSort(msat_env e, msat_type t, msat_decl d) : env(e), type(t), uf_decl(d), is_uf_type(true) {}; 32 | ~MsatSort() = default; 33 | std::size_t hash() const override; 34 | uint64_t get_width() const override; 35 | Sort get_indexsort() const override; 36 | Sort get_elemsort() const override; 37 | SortVec get_domain_sorts() const override; 38 | Sort get_codomain_sort() const override; 39 | std::string get_uninterpreted_name() const override; 40 | size_t get_arity() const override; 41 | SortVec get_uninterpreted_param_sorts() const override; 42 | Datatype get_datatype() const override; 43 | bool compare(const Sort &) const override; 44 | SortKind get_sort_kind() const override; 45 | 46 | // getters for solver-specific objects 47 | // for interacting with third-party MathSAT-specific software 48 | msat_type get_msat_type() const { return type; } 49 | 50 | protected: 51 | msat_env env; 52 | msat_type type; 53 | msat_decl uf_decl; 54 | bool is_uf_type; 55 | 56 | friend class MsatSolver; 57 | }; 58 | 59 | } // namespace smt 60 | 61 | -------------------------------------------------------------------------------- /msat/src/msat_factory.cpp: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file msat_factory.cpp 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief Factory for creating a MathSAT SmtSolver 13 | ** 14 | ** 15 | **/ 16 | 17 | #include "msat_factory.h" 18 | #include "msat_solver.h" 19 | 20 | #include "logging_solver.h" 21 | 22 | namespace smt { 23 | 24 | /* MsatSolverFactory implementation */ 25 | 26 | SmtSolver MsatSolverFactory::create(bool logging) 27 | { 28 | MsatSolver * ms = new MsatSolver(); 29 | SmtSolver solver(ms); 30 | if (logging) 31 | { 32 | solver = std::make_shared(solver); 33 | } 34 | return solver; 35 | } 36 | 37 | SmtSolver MsatSolverFactory::create_interpolating_solver() 38 | { 39 | MsatInterpolatingSolver * mis = new MsatInterpolatingSolver(); 40 | std::shared_ptr s(mis); 41 | return s; 42 | } 43 | 44 | /* end MsatSolverFactory implementation */ 45 | 46 | } // namespace smt 47 | -------------------------------------------------------------------------------- /python/pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = [ 3 | "setuptools>=61.0.0", 4 | "Cython>=3.0.0" 5 | ] 6 | build-backend = "setuptools.build_meta" 7 | 8 | [project] 9 | name = "smt-switch" 10 | description = "Python bindings for the smt-switch C++ SMT solving library" 11 | readme = {file = "README.md", content-type = "text/markdown"} 12 | requires-python = ">=3.9" 13 | license = "BSD-3-Clause" 14 | dynamic = ["version"] 15 | authors = [ 16 | {name = "Yoni Zohar", email = "yoni.zohar@biu.ac.il"}, 17 | {name = "Áron Ricardo Perez-Lopez", email = "arpl@cs.stanford.edu"}, 18 | {name = "Makai Mann", email = "makaim@cs.stanford.edu"}, 19 | {name = "Clark Barrett", email = "barrett@cs.stanford.edu"} 20 | ] 21 | dependencies = [] 22 | 23 | [project.optional-dependencies] 24 | pysmt = ["pysmt"] 25 | test = ["pytest"] 26 | 27 | [project.urls] 28 | Homepage = "https://github.com/stanford-centaur/smt-switch" 29 | Repository = "https://github.com/stanford-centaur/smt-switch.git" 30 | Issues = "https://github.com/stanford-centaur/smt-switch/issues" 31 | 32 | [tool.setuptools] 33 | include-package-data = true 34 | 35 | # Use find namespace directive to automatically discover packages 36 | # This will only find directories that contain __init__.py files 37 | [tool.setuptools.packages.find] 38 | include = ["smt_switch*"] 39 | 40 | # This tells setuptools to include all .dylib/.so files found in any package 41 | [tool.setuptools.package-data] 42 | "*" = ["*.dylib", "*.so", "*.pxd"] 43 | 44 | [tool.setuptools.dynamic] 45 | version = {attr = "smt_switch.__version__"} 46 | -------------------------------------------------------------------------------- /python/smt_switch/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Configure __init__.py 2 | configure_file( 3 | "${CMAKE_CURRENT_SOURCE_DIR}/__init__.py.in" 4 | "${CMAKE_CURRENT_BINARY_DIR}/__init__.py" 5 | @ONLY 6 | ) 7 | # Copy necessary Cython source files to the build directory 8 | file(GLOB CYTHON_SOURCE_FILES 9 | "${CMAKE_CURRENT_SOURCE_DIR}/*.pyx" 10 | "${CMAKE_CURRENT_SOURCE_DIR}/*.pxd" 11 | "${CMAKE_CURRENT_SOURCE_DIR}/*.pxi" 12 | ) 13 | 14 | # Cache the list of files 15 | set(CYTHON_SOURCE_FILES ${CYTHON_SOURCE_FILES} CACHE INTERNAL "") 16 | 17 | # Force CMake to rerun if any of these files change 18 | foreach(CYTHON_FILE ${CYTHON_SOURCE_FILES}) 19 | get_filename_component(FILE_NAME "${CYTHON_FILE}" NAME) 20 | configure_file( 21 | ${CYTHON_FILE} 22 | "${CMAKE_CURRENT_BINARY_DIR}/${FILE_NAME}" 23 | COPYONLY 24 | ) 25 | endforeach() 26 | 27 | # Copy PySmt frontend subpackage. 28 | file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/pysmt_frontend" 29 | DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/") 30 | -------------------------------------------------------------------------------- /python/smt_switch/__init__.pxd: -------------------------------------------------------------------------------- 1 | from .api cimport Op, Result, SmtSolver, Sort, SortingNetwork, Term 2 | from .cppapi cimport ( 3 | c_Op, 4 | c_Result, 5 | c_SmtSolver, 6 | c_Sort, 7 | c_SortingNetwork, 8 | c_SortVec, 9 | c_Term, 10 | c_TermIter, 11 | c_TermVec, 12 | c_UnorderedTermMap, 13 | c_UnorderedTermSet, 14 | ) 15 | from .cppenums cimport c_PrimOp, c_ResultType, c_SolverAttribute, c_SolverEnum, c_SortKind 16 | from .cpputils cimport ( 17 | conjunctive_partition, 18 | get_free_symbolic_consts, 19 | get_free_symbols, 20 | op_partition, 21 | ) 22 | from .enums cimport PrimOp, SolverAttribute, SolverEnum, SortKind 23 | from .smt_solvers cimport * 24 | -------------------------------------------------------------------------------- /python/smt_switch/__init__.py.in: -------------------------------------------------------------------------------- 1 | from .api import ( 2 | IdentityVisitor, 3 | Op, 4 | Result, 5 | SmtSolver, 6 | Sort, 7 | SortingNetwork, 8 | Term, 9 | TermDagVisitor, 10 | conjunctive_partition, 11 | get_free_symbolic_consts, 12 | get_free_symbols, 13 | op_partition, 14 | ) 15 | from .enums import PrimOp, SolverAttribute, SolverEnum, SortKind 16 | from .smt_solvers import * 17 | 18 | __version__ = "@PROJECT_VERSION@" 19 | -------------------------------------------------------------------------------- /python/smt_switch/api.pxd: -------------------------------------------------------------------------------- 1 | from .cppapi cimport c_Op, c_Result, c_SmtSolver, c_Sort, c_SortingNetwork, c_Term 2 | 3 | cdef class Op: 4 | cdef c_Op op 5 | 6 | 7 | cdef class Result: 8 | cdef c_Result cr 9 | 10 | 11 | cdef class SmtSolver: 12 | cdef c_SmtSolver css 13 | 14 | 15 | cdef class Sort: 16 | cdef c_Sort cs 17 | cdef SmtSolver _solver 18 | 19 | 20 | cdef class SortingNetwork: 21 | cdef c_SortingNetwork * csn 22 | cdef SmtSolver _solver 23 | 24 | 25 | cdef class Term: 26 | cdef c_Term ct 27 | cdef SmtSolver _solver 28 | -------------------------------------------------------------------------------- /python/smt_switch/cpputils.pxd: -------------------------------------------------------------------------------- 1 | from .cppapi cimport c_Term, c_TermVec, c_UnorderedTermSet 2 | from .cppenums cimport c_PrimOp 3 | 4 | 5 | cdef extern from "utils.h" namespace "smt": 6 | void get_free_symbolic_consts(const c_Term & term, c_UnorderedTermSet & out) except + 7 | void get_free_symbols(const c_Term & term, c_UnorderedTermSet & out) except + 8 | void op_partition(c_PrimOp po, const c_Term & term, c_TermVec & out) except + 9 | void conjunctive_partition(const c_Term & term, c_TermVec & out, bint include_bvand) except + 10 | -------------------------------------------------------------------------------- /python/smt_switch/enums.pxd: -------------------------------------------------------------------------------- 1 | from .cppenums cimport c_PrimOp, c_SolverAttribute, c_SolverEnum, c_SortKind 2 | 3 | cdef class PrimOp: 4 | cdef c_PrimOp po 5 | 6 | 7 | cdef class SolverAttribute: 8 | cdef c_SolverAttribute sa 9 | 10 | 11 | cdef class SolverEnum: 12 | cdef c_SolverEnum se 13 | 14 | 15 | cdef class SortKind: 16 | cdef c_SortKind sk 17 | -------------------------------------------------------------------------------- /python/smt_switch/enums.pyx: -------------------------------------------------------------------------------- 1 | from .cppenums cimport to_string 2 | 3 | 4 | cdef class SortKind: 5 | def __eq__(self, SortKind other): 6 | return ( self.sk) == ( other.sk) 7 | 8 | def __ne__(self, SortKind other): 9 | return ( self.sk) != ( other.sk) 10 | 11 | def __hash__(self): 12 | return hash( self.sk) 13 | 14 | def __str__(self): 15 | return to_string(self.sk).decode() 16 | 17 | def __repr__(self): 18 | return to_string(self.sk).decode() 19 | 20 | def as_int(self): 21 | return self.sk 22 | 23 | 24 | cdef class SolverEnum: 25 | def __eq__(self, SolverEnum other): 26 | return ( self.se) == ( other.se) 27 | 28 | def __ne__(self, SolverEnum other): 29 | return ( self.se) != ( other.se) 30 | 31 | def __hash__(self): 32 | return hash(( self.se, self.name)) 33 | 34 | def __str__(self): 35 | return to_string(self.se).decode() 36 | 37 | def __repr__(self): 38 | return to_string(self.se).decode() 39 | 40 | def as_int(self): 41 | return self.se 42 | 43 | 44 | cdef class SolverAttribute: 45 | def __eq__(self, SolverAttribute other): 46 | return ( self.sa) == ( other.sa) 47 | 48 | def __ne__(self, SolverAttribute other): 49 | return ( self.sa) != ( other.sa) 50 | 51 | def __hash__(self): 52 | return hash(( self.sa, self.name)) 53 | 54 | def __str__(self): 55 | return to_string(self.sa).decode() 56 | 57 | def __repr__(self): 58 | return to_string(self.sa).decode() 59 | 60 | def as_int(self): 61 | return self.sa 62 | 63 | 64 | cdef class PrimOp: 65 | def __eq__(self, PrimOp other): 66 | return ( self.po) == ( other.po) 67 | 68 | def __ne__(self, PrimOp other): 69 | return ( self.po) != ( other.po) 70 | 71 | def __hash__(self): 72 | return ( self.po) 73 | 74 | def __str__(self): 75 | return to_string(self.po).decode() 76 | 77 | def __repr__(self): 78 | return to_string(self.po).decode() 79 | 80 | def as_int(self): 81 | return self.po 82 | -------------------------------------------------------------------------------- /python/smt_switch/pysmt_frontend/__init__.py: -------------------------------------------------------------------------------- 1 | import typing as tp 2 | 3 | from pysmt import logics 4 | from pysmt.solvers.solver import Solver as SolverT 5 | from pysmt.exceptions import NoSolverAvailableError, NoLogicAvailableError 6 | from pysmt.environment import get_env 7 | 8 | from .pysmt_solver import SWITCH_SOLVERS 9 | 10 | __ALL__ = ['SWITCH_SOLVERS', 'Solver'] 11 | 12 | 13 | try: 14 | from .pysmt_solver import SwitchBtor 15 | __ALL__.append('SwitchBtor') 16 | except ImportError: 17 | pass 18 | 19 | try: 20 | from .pysmt_solver import SwitchCvc5 21 | __ALL__.append('SwitchCvc5') 22 | except ImportError: 23 | pass 24 | 25 | try: 26 | from .pysmt_solver import SwitchMsat 27 | __ALL__.append('SwitchMsat') 28 | except ImportError: 29 | pass 30 | 31 | def Solver(name: str, logic: tp.Optional[logics.Logic]=None) -> SolverT: 32 | ''' 33 | Convience function for building a pysmt solver object with a switch backend. 34 | Similar to `pysmt.shortcuts.Solver`. 35 | ''' 36 | try: 37 | cls = SWITCH_SOLVERS[name] 38 | except KeyError: 39 | raise NoSolverAvailableError(f"Solver '{name}' is not available") from None 40 | 41 | if isinstance(logic, str): 42 | logic = logics.convert_logic_from_string(logic) 43 | elif logic is None: 44 | # Try to use the most general logic supported 45 | try: 46 | logic = logics.most_generic_logic(cls.LOGICS) 47 | except NoLogicAvailableError: 48 | # supported logics do not have a single "upper bound" 49 | # Check for some reasonable ones 50 | if logics.QF_UFLIRA in cls.LOGICS: 51 | logic = logics.QF_UFLIRA 52 | elif logics.QF_AUFBV in cls.LOGICS: 53 | logic = logics.QF_AUFBV 54 | else: 55 | # use the first one 56 | logic = cls.LOGICS[0] 57 | 58 | return cls(environment=get_env(), logic=logic) 59 | -------------------------------------------------------------------------------- /python/smt_switch/solverattr.pyx: -------------------------------------------------------------------------------- 1 | from .cppenums cimport ( 2 | c_TERMITER, 3 | c_THEORY_INT, 4 | c_THEORY_REAL, 5 | c_ARRAY_MODELS, 6 | c_CONSTARR, 7 | c_FULL_TRANSFER, 8 | c_ARRAY_FUN_BOOLS, 9 | c_UNSAT_CORE, 10 | c_THEORY_DATATYPE, 11 | c_QUANTIFIERS, 12 | c_BOOL_BV1_ALIASING, 13 | c_TIMELIMIT, 14 | ) 15 | from .enums cimport SolverAttribute 16 | 17 | 18 | cdef SolverAttribute TERMITER = SolverAttribute() 19 | TERMITER.sa = c_TERMITER 20 | globals()["TERMITER"] = TERMITER 21 | 22 | cdef SolverAttribute THEORY_INT = SolverAttribute() 23 | THEORY_INT.sa = c_THEORY_INT 24 | globals()["THEORY_INT"] = THEORY_INT 25 | 26 | cdef SolverAttribute THEORY_REAL = SolverAttribute() 27 | THEORY_REAL.sa = c_THEORY_REAL 28 | globals()["THEORY_REAL"] = THEORY_REAL 29 | 30 | cdef SolverAttribute ARRAY_MODELS = SolverAttribute() 31 | ARRAY_MODELS.sa = c_ARRAY_MODELS 32 | globals()["ARRAY_MODELS"] = ARRAY_MODELS 33 | 34 | cdef SolverAttribute CONSTARR = SolverAttribute() 35 | CONSTARR.sa = c_CONSTARR 36 | globals()["CONSTARR"] = CONSTARR 37 | 38 | cdef SolverAttribute FULL_TRANSFER = SolverAttribute() 39 | FULL_TRANSFER.sa = c_FULL_TRANSFER 40 | globals()["FULL_TRANSFER"] = FULL_TRANSFER 41 | 42 | cdef SolverAttribute ARRAY_FUN_BOOLS = SolverAttribute() 43 | ARRAY_FUN_BOOLS.sa = c_ARRAY_FUN_BOOLS 44 | globals()["ARRAY_FUN_BOOLS"] = ARRAY_FUN_BOOLS 45 | 46 | cdef SolverAttribute UNSAT_CORE = SolverAttribute() 47 | UNSAT_CORE.sa = c_UNSAT_CORE 48 | globals()["UNSAT_CORE"] = UNSAT_CORE 49 | 50 | cdef SolverAttribute THEORY_DATATYPE = SolverAttribute() 51 | THEORY_DATATYPE.sa = c_THEORY_DATATYPE 52 | globals()["THEORY_DATATYPE"] = THEORY_DATATYPE 53 | 54 | cdef SolverAttribute QUANTIFIERS = SolverAttribute() 55 | QUANTIFIERS.sa = c_QUANTIFIERS 56 | globals()["QUANTIFIERS"] = QUANTIFIERS 57 | 58 | cdef SolverAttribute BOOL_BV1_ALIASING = SolverAttribute() 59 | BOOL_BV1_ALIASING.sa = c_BOOL_BV1_ALIASING 60 | globals()["BOOL_BV1_ALIASING"] = BOOL_BV1_ALIASING 61 | 62 | cdef SolverAttribute TIMELIMIT = SolverAttribute() 63 | TIMELIMIT.sa = c_TIMELIMIT 64 | globals()["TIMELIMIT"] = TIMELIMIT 65 | -------------------------------------------------------------------------------- /python/smt_switch/solverenums.pyx: -------------------------------------------------------------------------------- 1 | from .cppenums cimport ( 2 | c_BTOR, 3 | c_CVC5, 4 | c_MSAT, 5 | c_YICES2, 6 | c_MSAT_INTERPOLATOR, 7 | c_CVC5_INTERPOLATOR, 8 | c_GENERIC_SOLVER, 9 | ) 10 | from .enums cimport SolverEnum 11 | 12 | 13 | cdef SolverEnum BTOR = SolverEnum() 14 | BTOR.se = c_BTOR 15 | globals()["BTOR"] = BTOR 16 | 17 | cdef SolverEnum CVC5 = SolverEnum() 18 | CVC5.se = c_CVC5 19 | globals()["CVC5"] = CVC5 20 | 21 | cdef SolverEnum MSAT = SolverEnum() 22 | MSAT.se = c_MSAT 23 | globals()["MSAT"] = MSAT 24 | 25 | cdef SolverEnum YICES2 = SolverEnum() 26 | YICES2.se = c_YICES2 27 | globals()["YICES2"] = YICES2 28 | 29 | cdef SolverEnum MSAT_INTERPOLATOR = SolverEnum() 30 | MSAT_INTERPOLATOR.se = c_MSAT_INTERPOLATOR 31 | globals()["MSAT_INTERPOLATOR"] = MSAT_INTERPOLATOR 32 | 33 | cdef SolverEnum CVC5_INTERPOLATOR = SolverEnum() 34 | CVC5_INTERPOLATOR.se = c_CVC5_INTERPOLATOR 35 | globals()["CVC5_INTERPOLATOR"] = CVC5_INTERPOLATOR 36 | 37 | cdef SolverEnum GENERIC_SOLVER = SolverEnum() 38 | GENERIC_SOLVER.se = c_GENERIC_SOLVER 39 | globals()["GENERIC_SOLVER"] = GENERIC_SOLVER 40 | -------------------------------------------------------------------------------- /python/smt_switch/sortkinds.pyx: -------------------------------------------------------------------------------- 1 | from .cppenums cimport ( 2 | c_ARRAY, 3 | c_BOOL, 4 | c_BV, 5 | c_INT, 6 | c_REAL, 7 | c_FUNCTION, 8 | ) 9 | from .enums cimport SortKind 10 | 11 | cdef SortKind ARRAY = SortKind() 12 | ARRAY.sk = c_ARRAY 13 | globals()["ARRAY"] = ARRAY 14 | 15 | cdef SortKind BOOL = SortKind() 16 | BOOL.sk = c_BOOL 17 | globals()["BOOL"] = BOOL 18 | 19 | cdef SortKind BV = SortKind() 20 | BV.sk = c_BV 21 | globals()["BV"] = BV 22 | 23 | cdef SortKind INT = SortKind() 24 | INT.sk = c_INT 25 | globals()["INT"] = INT 26 | 27 | cdef SortKind REAL = SortKind() 28 | REAL.sk = c_REAL 29 | globals()["REAL"] = REAL 30 | 31 | cdef SortKind FUNCTION = SortKind() 32 | FUNCTION.sk = c_FUNCTION 33 | globals()["FUNCTION"] = FUNCTION 34 | 35 | 36 | attrs = {attr: pysk for attr, pysk in globals().items() if not attr.startswith("_")} 37 | int2sortkind = dict() 38 | for attr, pysk in attrs.items(): 39 | int2sortkind[( ( pysk).sk)] = pysk 40 | -------------------------------------------------------------------------------- /rep.sed: -------------------------------------------------------------------------------- 1 | s/class \(.*\) : public /GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(\1);\nclass \1 : public /g 2 | -------------------------------------------------------------------------------- /scripts/repack-static-lib.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ $# -lt 2 ]; then 4 | echo "usage: $0 [...libs to combine]" 5 | exit 1 6 | fi 7 | 8 | if [[ "$OSTYPE" == linux* || "$OSTYPE" == cygwin* ]]; then 9 | # use a GNU ar MRI script on Linux-like systems 10 | if ! command -v ar &> /dev/null 11 | then 12 | echo "ar could not be found" 13 | echo "required for repacking static libraries on Linux" 14 | exit 15 | fi 16 | 17 | TARGET=$1 18 | MRI_COMMAND="create $TARGET" 19 | for lib in "${@:2}"; do 20 | MRI_COMMAND="${MRI_COMMAND}\naddlib $lib" 21 | done 22 | 23 | MRI_COMMAND="${MRI_COMMAND}\nsave\nend" 24 | echo -e "$MRI_COMMAND" | ar -M 25 | 26 | if [ ! -f "${TARGET}" ]; then 27 | echo "It appears ar failed to create ${TARGET}" 28 | exit 1 29 | fi 30 | elif [[ "$OSTYPE" == darwin* ]]; then 31 | # use libtool (note: not the same as GNU libtool) on OSX 32 | if ! command -v libtool &> /dev/null 33 | then 34 | echo "libtool could not be found" 35 | echo "required for repacking static libraries on Mac" 36 | exit 37 | fi 38 | 39 | libtool -static -o $@ 40 | elif [[ "$OSTYPE" == msys* ]]; then 41 | echo "$0 does not support repacking static libs on Windows yet" 42 | else 43 | echo "Unrecognized OSTYPE=$OSTYPE" 44 | exit 1 45 | fi 46 | 47 | -------------------------------------------------------------------------------- /src/datatype.cpp: -------------------------------------------------------------------------------- 1 | #include "datatype.h" 2 | 3 | namespace smt { 4 | // Overloaded operators simply call the constructors' comparison functions 5 | bool operator==(const DatatypeConstructorDecl & d1, 6 | const DatatypeConstructorDecl & d2) 7 | { 8 | return d1->compare(d2); 9 | } 10 | bool operator!=(const DatatypeConstructorDecl & d1, 11 | const DatatypeConstructorDecl & d2) 12 | { 13 | return !d1->compare(d2); 14 | } 15 | 16 | } // namespace smt 17 | -------------------------------------------------------------------------------- /src/result.cpp: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file result.cpp 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann, Clark Barrett 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief The result of a call to check-sat or check-sat-assuming. 13 | ** 14 | ** 15 | **/ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | #include "exceptions.h" 22 | #include "result.h" 23 | 24 | namespace std 25 | { 26 | // specialize the hash template 27 | template<> 28 | struct hash 29 | { 30 | size_t operator()(const smt::ResultType r) const 31 | { 32 | return static_cast(r); 33 | } 34 | }; 35 | } 36 | 37 | 38 | namespace smt { 39 | 40 | const std::unordered_map result2str( 41 | { { SAT, "sat" }, { UNSAT, "unsat" }, { UNKNOWN, "unknown" } }); 42 | 43 | std::string Result::get_explanation() const 44 | { 45 | if (result != UNKNOWN) 46 | { 47 | throw IncorrectUsageException( 48 | "Result was not unknown. Cannot get explanation"); 49 | } 50 | else 51 | { 52 | return explanation; 53 | } 54 | } 55 | 56 | std::string Result::to_string() const { return result2str.at(result); } 57 | 58 | std::ostream & operator<<(std::ostream & output, const Result r) 59 | { 60 | output << result2str.at(r.result); 61 | return output; 62 | } 63 | 64 | bool operator==(const Result & r1, const Result & r2) 65 | { 66 | return r1.result == r2.result; 67 | } 68 | 69 | } // namespace smt 70 | -------------------------------------------------------------------------------- /src/solver_utils.cpp: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file solver_utils.cpp 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief Utility functions for solver implementations. Meant for internal 13 | ** use only, not from the API. 14 | ** 15 | **/ 16 | 17 | #include "assert.h" 18 | 19 | #include "solver_utils.h" 20 | 21 | namespace smt { 22 | 23 | Term make_distinct(const AbsSmtSolver * solver, const TermVec & terms) 24 | { 25 | size_t size = terms.size(); 26 | assert(size); 27 | 28 | TermVec pairs; 29 | for (size_t i = 0; i < terms.size(); ++i) 30 | { 31 | for (size_t j = 0; j < terms.size(); ++j) 32 | { 33 | if (i != j) 34 | { 35 | // trivially false if same term shows up twice 36 | assert(terms[i] != terms[j]); 37 | pairs.push_back(solver->make_term(Distinct, terms[i], terms[j])); 38 | } 39 | } 40 | } 41 | 42 | Term res = solver->make_term(And, pairs); 43 | return res; 44 | } 45 | 46 | } // namespace smt 47 | -------------------------------------------------------------------------------- /src/substitution_walker.cpp: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file substitution_walker.h 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief Substitution walker for doing substitutions with a persistent cache 13 | ** 14 | **/ 15 | 16 | #include "substitution_walker.h" 17 | 18 | namespace smt { 19 | 20 | SubstitutionWalker::SubstitutionWalker( 21 | const smt::SmtSolver & solver, 22 | const smt::UnorderedTermMap & substitution_map) 23 | : IdentityWalker(solver, false) 24 | { 25 | // pre-populate the cache with substitutions 26 | for (auto elem : substitution_map) 27 | { 28 | if (elem.first->get_sort() != elem.second->get_sort()) 29 | { 30 | throw IncorrectUsageException("Got mismatch in sorts for substitution: " 31 | + elem.first->to_string() + ":" 32 | + elem.first->get_sort()->to_string() + " " 33 | + elem.second->to_string() + ":" 34 | + elem.second->get_sort()->to_string()); 35 | } 36 | save_in_cache(elem.first, elem.second); 37 | } 38 | } 39 | } // namespace smt 40 | -------------------------------------------------------------------------------- /src/term.cpp: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file term.cpp 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann, Clark Barrett 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief Abstract interface for SMT terms. 13 | ** 14 | ** 15 | **/ 16 | 17 | #include "term.h" 18 | 19 | namespace smt { 20 | 21 | std::ostream & operator<<(std::ostream & output, const Term t) 22 | { 23 | output << t->to_string(); 24 | return output; 25 | } 26 | 27 | /* TermIterBase implementation */ 28 | const Term TermIterBase::operator*() 29 | { 30 | std::shared_ptr s; 31 | return s; 32 | } 33 | 34 | bool TermIterBase::operator==(const TermIterBase & other) const 35 | { 36 | return (typeid(*this) == typeid(other)) && equal(other); 37 | } 38 | /* end TermIterBase implementation */ 39 | 40 | /* TermIter implementation */ 41 | TermIter & TermIter::operator=(const TermIter & other) 42 | { 43 | delete iter_; 44 | iter_ = other.iter_->clone(); 45 | return *this; 46 | } 47 | 48 | TermIter & TermIter::operator++() 49 | { 50 | ++(*iter_); 51 | return *this; 52 | } 53 | 54 | TermIter TermIter::operator++(int) 55 | { 56 | TermIter it = *this; 57 | ++(*iter_); 58 | return it; 59 | } 60 | 61 | bool TermIter::operator==(const TermIter & other) const 62 | { 63 | return (iter_ == other.iter_) || (*iter_ == *other.iter_); 64 | } 65 | 66 | bool TermIter::operator!=(const TermIter & other) const 67 | { 68 | return !(*this == other); 69 | } 70 | /* end TermIter implementation */ 71 | } // namespace smt 72 | -------------------------------------------------------------------------------- /src/term_hashtable.cpp: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file term_hashtable.cpp 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief A simple hash table for terms -- used for hash-consing in 13 | ** LoggingSolver 14 | ** 15 | ** 16 | **/ 17 | 18 | #include "term_hashtable.h" 19 | 20 | using namespace std; 21 | 22 | namespace smt { 23 | 24 | /* TermHashTable */ 25 | 26 | TermHashTable::TermHashTable() {} 27 | 28 | TermHashTable::~TermHashTable() {} 29 | 30 | void TermHashTable::insert(const Term & t) { table[t->hash()].insert(t); } 31 | 32 | bool TermHashTable::contains(const Term & t) const 33 | { 34 | size_t hashval = t->hash(); 35 | return (table.find(hashval) != table.end() 36 | && table.at(hashval).find(t) != table.at(hashval).end()); 37 | } 38 | 39 | bool TermHashTable::lookup(Term & t) 40 | { 41 | if (contains(t)) 42 | { 43 | // reassign t 44 | // should destroy the previous Term 45 | // when reference counter goes to zero 46 | t = *(table[t->hash()].find(t)); 47 | return true; 48 | } 49 | return false; 50 | } 51 | 52 | void TermHashTable::erase(const Term & t) 53 | { 54 | size_t hashval = t->hash(); 55 | if (table.find(hashval) != table.end() 56 | && table[hashval].find(t) != table[hashval].end()) 57 | { 58 | table[hashval].erase(t); 59 | } 60 | } 61 | 62 | void TermHashTable::clear() { table.clear(); } 63 | 64 | } // namespace smt 65 | -------------------------------------------------------------------------------- /tests/CMakeLists.txt.in: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | 3 | project(googletest-download NONE) 4 | 5 | include(ExternalProject) 6 | ExternalProject_Add(googletest 7 | GIT_REPOSITORY https://github.com/google/googletest.git 8 | # Temporary: to avoid https://github.com/google/googletest/issues/2711 9 | GIT_TAG release-1.12.1 10 | SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-src" 11 | BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-build" 12 | CONFIGURE_COMMAND "" 13 | BUILD_COMMAND "" 14 | INSTALL_COMMAND "" 15 | TEST_COMMAND "" 16 | ) 17 | -------------------------------------------------------------------------------- /tests/btor/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | macro(switch_add_btor_test name) 2 | add_executable(${name} "${PROJECT_SOURCE_DIR}/tests/btor/${name}.cpp") 3 | target_link_libraries(${name} gtest gtest_main) 4 | target_link_libraries(${name} test-deps) 5 | add_test(NAME ${name}_test COMMAND ${name}) 6 | endmacro() 7 | 8 | # these tests don't use GoogleTest yet 9 | # TODO move old tests to Google Test infrastructure 10 | switch_add_btor_test(btor-arrays) 11 | switch_add_btor_test(btor-data-structures) 12 | switch_add_btor_test(btor-exceptions) 13 | switch_add_btor_test(btor-indexed-op-tests) 14 | switch_add_btor_test(btor-tests) 15 | switch_add_btor_test(btor-incremental) 16 | switch_add_btor_test(btor-transfer) 17 | switch_add_btor_test(btor-negation) 18 | switch_add_btor_test(btor-const-arrays) 19 | switch_add_btor_test(btor-substitute) 20 | switch_add_btor_test(btor-simple) 21 | switch_add_btor_test(btor-array-models) 22 | switch_add_btor_test(btor-array-empty-assignment) 23 | switch_add_btor_test(btor-neg-numbers) 24 | 25 | # Google Test 26 | 27 | switch_add_btor_test(btor-opts) 28 | switch_add_btor_test(btor-printing) 29 | -------------------------------------------------------------------------------- /tests/btor/README.md: -------------------------------------------------------------------------------- 1 | # Tests Using the Boolector Solver 2 | 3 | These tests demonstrate the usage of the API and test your installation of Boolector. These are meant to be run after an installation of `smt-switch`. 4 | 5 | To install `smt-switch` with `boolector`, you would run the following from the top-level directory: 6 | `sudo make install install-btor` 7 | 8 | # Dependencies 9 | 10 | We have tried to automate dependency installations for unusual packages, but we have not installed all the boolector dependencies that you can rely on a package manager for. If your build is not working, please see the installation instructions on the boolector [github](https://github.com/Boolector/boolector). 11 | -------------------------------------------------------------------------------- /tests/btor/btor-array-empty-assignment.cpp: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file btor-array-empty-assignment.cpp 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief 13 | ** 14 | ** 15 | **/ 16 | 17 | #include 18 | #include 19 | #include 20 | #include "assert.h" 21 | 22 | #include "boolector_factory.h" 23 | #include "smt.h" 24 | // after a full installation 25 | // #include "smt-switch/boolector_factory.h" 26 | // #include "smt-switch/smt.h" 27 | 28 | using namespace smt; 29 | using namespace std; 30 | 31 | int main() 32 | { 33 | // This simple test checks that memory is freed correctly 34 | // even if the array model has no stores 35 | 36 | SmtSolver s = BoolectorSolverFactory::create(false); 37 | s->set_opt("produce-models", "true"); 38 | Sort bvsort32 = s->make_sort(BV, 32); 39 | Sort array32_32 = s->make_sort(ARRAY, bvsort32, bvsort32); 40 | Term arr = s->make_symbol("arr", array32_32); 41 | 42 | Result r = s->check_sat(); 43 | assert(r.is_sat()); 44 | 45 | Term out_const_base; 46 | UnorderedTermMap arr_ass = s->get_array_values(arr, out_const_base); 47 | assert(arr_ass.size() == 0); 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /tests/btor/btor-array-models.cpp: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file btor-array-models.cpp 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief 13 | ** 14 | ** 15 | **/ 16 | 17 | #include 18 | #include 19 | #include 20 | #include "assert.h" 21 | 22 | #include "boolector_factory.h" 23 | #include "smt.h" 24 | // after a full installation 25 | // #include "smt-switch/boolector_factory.h" 26 | // #include "smt-switch/smt.h" 27 | 28 | using namespace smt; 29 | using namespace std; 30 | 31 | int main() 32 | { 33 | SmtSolver s = BoolectorSolverFactory::create(false); 34 | s->set_opt("produce-models", "true"); 35 | Sort bvsort32 = s->make_sort(BV, 32); 36 | Sort array32_32 = s->make_sort(ARRAY, bvsort32, bvsort32); 37 | Term x0 = s->make_symbol("x0", bvsort32); 38 | Term x1 = s->make_symbol("x1", bvsort32); 39 | Term y = s->make_symbol("y", bvsort32); 40 | Term arr = s->make_symbol("arr", array32_32); 41 | 42 | Term constraint = s->make_term(Equal, s->make_term(Select, arr, x0), x1); 43 | constraint = s->make_term( 44 | And, constraint, s->make_term(Equal, s->make_term(Select, arr, x1), y)); 45 | constraint = s->make_term(And, constraint, s->make_term(Distinct, x1, y)); 46 | s->assert_formula(constraint); 47 | Result r = s->check_sat(); 48 | 49 | assert(r.is_sat()); 50 | 51 | Term out_const_base; 52 | UnorderedTermMap arr_map = s->get_array_values(arr, out_const_base); 53 | 54 | for (auto elem : arr_map) 55 | { 56 | cout << elem.first << ": " << elem.second << endl; 57 | } 58 | 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /tests/btor/btor-arrays.cpp: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file btor-arrays.cpp 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief 13 | ** 14 | ** 15 | **/ 16 | 17 | #include 18 | #include 19 | #include 20 | #include "assert.h" 21 | 22 | #include "boolector_factory.h" 23 | #include "smt.h" 24 | // after a full installation 25 | // #include "smt-switch/boolector_factory.h" 26 | // #include "smt-switch/smt.h" 27 | 28 | using namespace smt; 29 | using namespace std; 30 | 31 | int main() 32 | { 33 | SmtSolver s = BoolectorSolverFactory::create(false); 34 | s->set_opt("produce-models", "true"); 35 | Sort bvsort32 = s->make_sort(BV, 32); 36 | Sort array32_32 = s->make_sort(ARRAY, bvsort32, bvsort32); 37 | Term x = s->make_symbol("x", bvsort32); 38 | Term y = s->make_symbol("y", bvsort32); 39 | Term arr = s->make_symbol("arr", array32_32); 40 | 41 | cout << "Sorts:" << endl; 42 | cout << "\tbvsort32 : " << bvsort32 << endl; 43 | cout << "\tarray32_32 : " << array32_32 << endl; 44 | s->assert_formula( 45 | s->make_term(Not, 46 | s->make_term(Implies, 47 | s->make_term(Equal, x, y), 48 | s->make_term(Equal, 49 | s->make_term(Select, arr, x), 50 | s->make_term(Select, arr, y))))); 51 | assert(!s->check_sat().is_sat()); 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /tests/btor/btor-exceptions.cpp: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file btor-exceptions.cpp 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief 13 | ** 14 | ** 15 | **/ 16 | 17 | #include 18 | #include 19 | #include 20 | #include "assert.h" 21 | 22 | #include "boolector_factory.h" 23 | #include "smt.h" 24 | // after a full installation 25 | // #include "smt-switch/boolector_factory.h" 26 | // #include "smt-switch/smt.h" 27 | 28 | using namespace smt; 29 | using namespace std; 30 | 31 | int main() 32 | { 33 | SmtSolver s = BoolectorSolverFactory::create(false); 34 | s->set_opt("produce-models", "true"); 35 | 36 | try 37 | { 38 | s->set_logic("QF_NIA"); 39 | } 40 | catch (SmtException & e) 41 | { 42 | cout << e.what() << endl; 43 | } 44 | 45 | try 46 | { 47 | Sort intsort = s->make_sort(INT); 48 | } 49 | catch (SmtException & e) 50 | { 51 | cout << e.what() << endl; 52 | } 53 | 54 | Sort bvsort4 = s->make_sort(BV, 4); 55 | Term x = s->make_symbol("x", bvsort4); 56 | Term y = s->make_symbol("y", bvsort4); 57 | 58 | try 59 | { 60 | s->assert_formula(s->make_term(Ge, x, y)); 61 | } 62 | catch (SmtException & e) 63 | { 64 | cout << e.what() << endl; 65 | } 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /tests/btor/btor-indexed-op-tests.cpp: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file btor-indexed-op-tests.cpp 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief 13 | ** 14 | ** 15 | **/ 16 | 17 | #include 18 | #include 19 | #include 20 | #include "assert.h" 21 | 22 | #include "boolector_factory.h" 23 | #include "smt.h" 24 | // after a full installation 25 | // #include "smt-switch/boolector_factory.h" 26 | // #include "smt-switch/smt.h" 27 | 28 | using namespace smt; 29 | using namespace std; 30 | 31 | int main() 32 | { 33 | SmtSolver s = BoolectorSolverFactory::create(false); 34 | s->set_opt("produce-models", "true"); 35 | Sort bvsort9 = s->make_sort(BV, 9); 36 | Term x = s->make_symbol("x", bvsort9); 37 | Term y = s->make_symbol("y", bvsort9); 38 | Term onebit = s->make_symbol("onebit", s->make_sort(BV, 1)); 39 | 40 | Term unnecessary_rotation = s->make_term(Op(Rotate_Right, 1), onebit); 41 | 42 | Op ext74 = Op(Extract, 7, 4); 43 | Term x_upper = s->make_term(ext74, x); 44 | 45 | Op op = x_upper->get_op(); 46 | cout << "Op: " << op << endl; 47 | 48 | Term y_ror = s->make_term(Op(Rotate_Right, 2), y); 49 | Term y_rol = s->make_term(Op(Rotate_Left, 2), y); 50 | 51 | s->assert_formula(s->make_term(Equal, y_ror, y_rol)); 52 | s->assert_formula(s->make_term(Distinct, y, s->make_term(0, bvsort9))); 53 | s->assert_formula(s->make_term( 54 | Equal, x, s->make_term(Op(Repeat, 9), unnecessary_rotation))); 55 | 56 | Result r = s->check_sat(); 57 | assert(r.is_sat()); 58 | 59 | Term xc = s->get_value(x); 60 | Term x_upperc = s->get_value(x_upper); 61 | Term yc = s->get_value(y); 62 | 63 | cout << "Results:" << endl; 64 | cout << x << ": " << xc->to_int() << endl; 65 | cout << x_upper << ": " << x_upperc->to_int() << endl; 66 | cout << y << ": " << yc->to_int() << endl; 67 | return 0; 68 | } 69 | -------------------------------------------------------------------------------- /tests/btor/btor-neg-numbers.cpp: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file btor-neg-numbers.cpp 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief 13 | ** 14 | ** 15 | **/ 16 | 17 | #include 18 | #include 19 | #include 20 | #include "assert.h" 21 | 22 | #include "boolector_factory.h" 23 | #include "smt.h" 24 | // after a full installation 25 | // #include "smt-switch/boolector_factory.h" 26 | // #include "smt-switch/smt.h" 27 | 28 | using namespace smt; 29 | using namespace std; 30 | 31 | int main() 32 | { 33 | SmtSolver s = BoolectorSolverFactory::create(false); 34 | 35 | Sort bvsort8 = s->make_sort(BV, 8); 36 | 37 | Term four = s->make_term(4, bvsort8); 38 | Term neg_four = s->make_term(-4, bvsort8); 39 | 40 | assert(neg_four == s->make_term("-4", bvsort8)); 41 | 42 | try 43 | { 44 | Term impossible = s->make_term("-129", bvsort8); 45 | assert(false); 46 | } 47 | catch (IncorrectUsageException & e) 48 | { 49 | cout << e.what() << endl; 50 | } 51 | 52 | s->assert_formula( 53 | s->make_term(Not, 54 | s->make_term(Equal, 55 | s->make_term(BVAdd, four, neg_four), 56 | s->make_term(0, bvsort8)))); 57 | Result r = s->check_sat(); 58 | assert(r.is_unsat()); 59 | 60 | return 0; 61 | } 62 | -------------------------------------------------------------------------------- /tests/btor/btor-opts.cpp: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file btor-opts.cpp 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief Tests for setting options through boolector. 13 | ** 14 | ** 15 | **/ 16 | 17 | #include 18 | #include 19 | #include 20 | #include "assert.h" 21 | 22 | #include "gtest/gtest.h" 23 | 24 | #include "boolector_factory.h" 25 | #include "smt.h" 26 | 27 | using namespace smt; 28 | using namespace std; 29 | 30 | TEST(BtorOptTest1, Incremental) 31 | { 32 | SmtSolver s = BoolectorSolverFactory::create(false); 33 | EXPECT_NO_THROW(s->set_opt("incremental", "true")); 34 | s->assert_formula(s->make_term(false)); 35 | s->check_sat(); 36 | EXPECT_NO_THROW(s->check_sat()); 37 | } 38 | 39 | TEST(BtorOptTest2, ProduceModels) 40 | { 41 | SmtSolver s = BoolectorSolverFactory::create(false); 42 | EXPECT_NO_THROW(s->set_opt("produce-models", "true")); 43 | Sort boolsort = s->make_sort(BOOL); 44 | Term b = s->make_symbol("b", boolsort); 45 | s->assert_formula(b); 46 | Result r = s->check_sat(); 47 | ASSERT_TRUE(r.is_sat()); 48 | EXPECT_NO_THROW(s->get_value(b)); 49 | } 50 | 51 | TEST(BtorOptTest3, NonStandardOpt) 52 | { 53 | // tests an option that's boolector specific 54 | SmtSolver s = BoolectorSolverFactory::create(false); 55 | EXPECT_NO_THROW(s->set_opt("nondestr-subst", "true")); 56 | } 57 | 58 | TEST(BtorOptTest4, IncorrectOption) 59 | { 60 | // tests an option that shouldn't exist 61 | SmtSolver s = BoolectorSolverFactory::create(false); 62 | EXPECT_THROW(s->set_opt("totally-made-up-option", "true"), 63 | NotImplementedException); 64 | } 65 | -------------------------------------------------------------------------------- /tests/btor/btor-printing.cpp: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file btor-printing.cpp 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Áron Ricardo Perez-Lopez 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2025 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief Test that PrintingSolver behaves correctly for Boolector. 13 | ** 14 | ** Note: this file depends on the CMake build infrastructure, specifically on 15 | ** defined macros. It cannot be compiled outside of the build. 16 | **/ 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include "gtest/gtest.h" 24 | 25 | #include "boolector_factory.h" 26 | #include "smt.h" 27 | #include "printing_solver.h" 28 | #include "test-utils.h" 29 | 30 | using namespace smt; 31 | 32 | TEST(BtorPrintingTest, SymbolName) 33 | { 34 | std::string smt_filename = "btor-printing-test.smt2"; 35 | std::ofstream smt_file(smt_filename, std::ios::trunc); 36 | SmtSolver solver = BoolectorSolverFactory::create(false); 37 | solver = create_printing_solver(solver, &smt_file, PrintingStyleEnum::DEFAULT_STYLE); 38 | solver->set_logic("QF_BV"); 39 | solver->set_opt("incremental", "true"); 40 | Sort sort = solver->make_sort(SortKind::BOOL); 41 | solver->push(); 42 | Term term = solver->make_symbol("x", sort); 43 | solver->assert_formula(term); 44 | Result result = solver->check_sat(); 45 | smt_file.close(); 46 | EXPECT_TRUE(result.is_sat()); 47 | 48 | std::string witness_filename = "btor-printing-test.witness"; 49 | std::string command = STRFY(BTOR_HOME); 50 | command += "/build/bin/boolector "; 51 | command += smt_filename; 52 | command += " >"; 53 | command += witness_filename; 54 | command += " 2>&1"; 55 | std::system(command.c_str()); 56 | std::remove(smt_filename.c_str()); 57 | std::ifstream witness_file(witness_filename); 58 | std::stringstream output; 59 | witness_file >> output.rdbuf(); 60 | witness_file.close(); 61 | std::remove(witness_filename.c_str()); 62 | std::string expected_output = "sat\n"; 63 | EXPECT_EQ(output.str(), expected_output); 64 | } 65 | -------------------------------------------------------------------------------- /tests/btor/btor-simple.cpp: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file btor-simple.cpp 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief 13 | ** 14 | ** 15 | **/ 16 | 17 | #include 18 | #include 19 | #include 20 | #include "assert.h" 21 | 22 | #include "boolector_factory.h" 23 | #include "smt.h" 24 | // after a full installation 25 | // #include "smt-switch/boolector_factory.h" 26 | // #include "smt-switch/smt.h" 27 | 28 | using namespace smt; 29 | using namespace std; 30 | 31 | int main() 32 | { 33 | SmtSolver s = BoolectorSolverFactory::create(false); 34 | s->set_logic("QF_ABV"); 35 | s->set_opt("produce-models", "true"); 36 | Sort bvsort8 = s->make_sort(BV, 8); 37 | Term x = s->make_symbol("x", bvsort8); 38 | Term y = s->make_symbol("y", bvsort8); 39 | Term xpy = s->make_term(BVAdd, x, y); 40 | 41 | for (auto c : xpy) 42 | { 43 | assert(c == x || c == y); 44 | } 45 | 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /tests/btor/btor-transfer.cpp: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file btor-transfer.cpp 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief 13 | ** 14 | ** 15 | **/ 16 | 17 | #include 18 | #include 19 | #include 20 | #include "assert.h" 21 | 22 | #include "boolector_factory.h" 23 | #include "smt.h" 24 | // after a full installation 25 | // #include "smt-switch/boolector_factory.h" 26 | // #include "smt-switch/smt.h" 27 | 28 | using namespace smt; 29 | using namespace std; 30 | 31 | int main() 32 | { 33 | SmtSolver s = BoolectorSolverFactory::create(false); 34 | s->set_logic("QF_ABV"); 35 | s->set_opt("produce-models", "true"); 36 | Sort bvsort8 = s->make_sort(BV, 8); 37 | Term x = s->make_symbol("x", bvsort8); 38 | Term y = s->make_symbol("y", bvsort8); 39 | Term z = s->make_symbol("z", bvsort8); 40 | Term T = s->make_term(true); 41 | 42 | Term constraint = s->make_term(Equal, z, s->make_term(BVAdd, x, y)); 43 | s->assert_formula(constraint); 44 | 45 | SmtSolver s2 = BoolectorSolverFactory::create(false); 46 | s2->set_logic("QF_ABV"); 47 | s2->set_opt("produce-models", "true"); 48 | s2->set_opt("incremental", "true"); 49 | 50 | TermTranslator tt(s2); 51 | 52 | Term constraint2 = tt.transfer_term(constraint); 53 | Term T2 = tt.transfer_term(T); 54 | // ensure it can handle transfering again (even though it already built the 55 | // node) 56 | tt.transfer_term(constraint); 57 | s2->assert_formula(constraint2); 58 | 59 | cout << "term from solver 1: " << constraint << endl; 60 | cout << "term from solver 2: " << constraint2 << endl; 61 | 62 | assert(s->check_sat().is_sat()); 63 | assert(s2->check_sat().is_sat()); 64 | 65 | return 0; 66 | } 67 | -------------------------------------------------------------------------------- /tests/cvc5/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | macro(switch_add_cvc5_test name) 2 | add_executable(${name} "${PROJECT_SOURCE_DIR}/tests/cvc5/${name}.cpp") 3 | target_link_libraries(${name} gtest gtest_main) 4 | target_link_libraries(${name} test-deps) 5 | add_test(NAME ${name}_test COMMAND ${name}) 6 | endmacro() 7 | 8 | # these tests don't use GoogleTest yet 9 | # TODO move old tests to Google Test infrastructure 10 | switch_add_cvc5_test(cvc5-arrays) 11 | switch_add_cvc5_test(cvc5-data-structures) 12 | switch_add_cvc5_test(cvc5-indexed-op-tests) 13 | switch_add_cvc5_test(cvc5-int-arithmetic) 14 | switch_add_cvc5_test(cvc5_test) 15 | switch_add_cvc5_test(cvc5-tests) 16 | switch_add_cvc5_test(cvc5-incremental) 17 | switch_add_cvc5_test(cvc5-interpolants) 18 | switch_add_cvc5_test(cvc5-interpolants-api) 19 | switch_add_cvc5_test(cvc5-transfer) 20 | switch_add_cvc5_test(cvc5-neg-numbers) 21 | switch_add_cvc5_test(cvc5-printing) 22 | switch_add_cvc5_test(cvc5-str) 23 | 24 | # Google Test 25 | switch_add_cvc5_test(cvc5-term-iter) 26 | -------------------------------------------------------------------------------- /tests/cvc5/README.md: -------------------------------------------------------------------------------- 1 | # Tests Using the cvc5 Solver 2 | 3 | These tests demonstrate the usage of the API and test your installation of `cvc5`. These are meant to be run after an installation of `smt-switch`. 4 | 5 | To install `smt-switch` with `cvc5`, you would run the following from the top-level directory: 6 | `sudo make install install-cvc5` 7 | 8 | # Dependencies 9 | 10 | We have tried to automate dependency installations for unusual packages, but we have not installed all the `cvc5` dependencies that you can rely on a package manager for. If your build is not working, please see the installation instructions on the `cvc5` [github](https://github.com/cvc5/cvc5/). 11 | -------------------------------------------------------------------------------- /tests/cvc5/cvc5-arrays.cpp: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file cvc5-arrays.cpp 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief 13 | ** 14 | ** 15 | **/ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | #include "assert.h" 22 | #include "cvc5_factory.h" 23 | #include "smt.h" 24 | // after full installation 25 | // #include "smt-switch/cvc5_factory.h" 26 | // #include "smt-switch/smt.h" 27 | 28 | using namespace smt; 29 | using namespace std; 30 | 31 | int main() 32 | { 33 | SmtSolver s = Cvc5SolverFactory::create(false); 34 | s->set_opt("produce-models", "true"); 35 | Sort bvsort32 = s->make_sort(BV, 32); 36 | Sort array32_32 = s->make_sort(ARRAY, bvsort32, bvsort32); 37 | Term x = s->make_symbol("x", bvsort32); 38 | Term y = s->make_symbol("y", bvsort32); 39 | Term arr = s->make_symbol("arr", array32_32); 40 | 41 | cout << "Sorts:" << endl; 42 | cout << "\tbvsort32 : " << bvsort32 << endl; 43 | cout << "\tarray32_32 : " << array32_32 << endl; 44 | s->assert_formula( 45 | s->make_term(Not, 46 | s->make_term(Implies, 47 | s->make_term(Equal, x, y), 48 | s->make_term(Equal, 49 | s->make_term(Select, arr, x), 50 | s->make_term(Select, arr, y))))); 51 | assert(!s->check_sat().is_sat()); 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /tests/cvc5/cvc5-indexed-op-tests.cpp: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file cvc5-indexed-op-tests.cpp 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief 13 | ** 14 | ** 15 | **/ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | #include "assert.h" 22 | #include "cvc5_factory.h" 23 | #include "smt.h" 24 | // after full installation 25 | // #include "smt-switch/cvc5_factory.h" 26 | // #include "smt-switch/smt.h" 27 | 28 | using namespace smt; 29 | using namespace std; 30 | 31 | int main() 32 | { 33 | SmtSolver s = Cvc5SolverFactory::create(false); 34 | s->set_opt("produce-models", "true"); 35 | Sort bvsort9 = s->make_sort(BV, 9); 36 | Term x = s->make_symbol("x", bvsort9); 37 | Term y = s->make_symbol("y", bvsort9); 38 | Term onebit = s->make_symbol("onebit", s->make_sort(BV, 1)); 39 | 40 | Term unnecessary_rotation = s->make_term(Op(Rotate_Right, 1), onebit); 41 | 42 | Op ext74 = Op(Extract, 7, 4); 43 | Term x_upper = s->make_term(ext74, x); 44 | 45 | Term y_ror = s->make_term(Op(Rotate_Right, 2), y); 46 | Term y_rol = s->make_term(Op(Rotate_Left, 2), y); 47 | 48 | s->assert_formula(s->make_term(Equal, y_ror, y_rol)); 49 | s->assert_formula(s->make_term(Distinct, y, s->make_term(0, bvsort9))); 50 | s->assert_formula(s->make_term( 51 | Equal, x, s->make_term(Op(Repeat, 9), unnecessary_rotation))); 52 | 53 | Result r = s->check_sat(); 54 | assert(r.is_sat()); 55 | 56 | Term xc = s->get_value(x); 57 | Term x_upperc = s->get_value(x_upper); 58 | Term yc = s->get_value(y); 59 | 60 | cout << "Results:" << endl; 61 | cout << "\tx = " << xc->to_int() << endl; 62 | cout << "\tx[7:4] = " << x_upperc->to_int() << endl; 63 | cout << "\ty = " << yc->to_int() << endl; 64 | return 0; 65 | } 66 | -------------------------------------------------------------------------------- /tests/cvc5/cvc5-int-arithmetic.cpp: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file cvc5-int-arithmetic.cpp 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief 13 | ** 14 | ** 15 | **/ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | #include "assert.h" 22 | #include "cvc5_factory.h" 23 | #include "smt.h" 24 | // after full installation 25 | // #include "smt-switch/cvc5_factory.h" 26 | // #include "smt-switch/smt.h" 27 | 28 | using namespace smt; 29 | using namespace std; 30 | 31 | int main() 32 | { 33 | SmtSolver s = Cvc5SolverFactory::create(false); 34 | s->set_opt("produce-models", "true"); 35 | s->set_logic("QF_NIA"); 36 | Sort intsort = s->make_sort(INT); 37 | Term x = s->make_symbol("x", intsort); 38 | Term y = s->make_symbol("y", intsort); 39 | Term z = s->make_symbol("z", intsort); 40 | 41 | s->assert_formula(s->make_term(Ge, x, y)); 42 | s->assert_formula(s->make_term(Le, z, s->make_term(Plus, x, y))); 43 | s->assert_formula( 44 | s->make_term(Lt, s->make_term(Negate, z), s->make_term(Minus, x, y))); 45 | s->assert_formula( 46 | s->make_term(Gt, s->make_term(Minus, x, y), s->make_term(Mult, x, y))); 47 | 48 | Result r = s->check_sat(); 49 | assert(r.is_sat()); 50 | 51 | cout << "Model Values:" << endl; 52 | for (auto t : TermVec({ x, y, z })) 53 | { 54 | cout << "\t" << t << " = " << s->get_value(t) << endl; 55 | } 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /tests/cvc5/cvc5-interpolants-api.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "cvc5/cvc5.h" 5 | 6 | using namespace std; 7 | using namespace cvc5; 8 | 9 | int main() 10 | { 11 | TermManager tm; 12 | Sort boolsort = tm.getBooleanSort(); 13 | Term b1 = tm.mkConst(boolsort, "b1"); 14 | Term b2 = tm.mkConst(boolsort, "b2"); 15 | 16 | cout << (b2.getKind() == Kind::CONSTANT) << std::endl; 17 | 18 | if (b2.getKind() != Kind::CONSTANT) 19 | { 20 | throw std::exception(); 21 | } 22 | 23 | Solver s(tm); 24 | s.setOption("produce-interpolants", "true"); 25 | s.setOption("incremental", "false"); 26 | s.assertFormula(tm.mkTerm(Kind::AND, { b1, b2 })); 27 | Term I = s.getInterpolant(b2); 28 | 29 | if (!I.isNull()) 30 | { 31 | cout << "got an interpolant: " << I << endl; 32 | } 33 | 34 | cout << (I == b2) << endl; 35 | 36 | if (I.getKind() != Kind::CONSTANT) 37 | { 38 | cout << "ERROR The interpolant should have kind CONSTANT but has kind: " 39 | << to_string(I.getKind()) << endl; 40 | } 41 | 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /tests/cvc5/cvc5-neg-numbers.cpp: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file cvc5-neg-numbers.cpp 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief 13 | ** 14 | ** 15 | **/ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | #include "assert.h" 22 | #include "cvc5_factory.h" 23 | #include "smt.h" 24 | // after a full installation 25 | // #include "smt-switch/cvc5_factory.h" 26 | // #include "smt-switch/smt.h" 27 | 28 | using namespace smt; 29 | using namespace std; 30 | 31 | int main() 32 | { 33 | SmtSolver s = Cvc5SolverFactory::create(false); 34 | 35 | // BitVector cases 36 | Sort bvsort8 = s->make_sort(BV, 8); 37 | 38 | Term four = s->make_term(4, bvsort8); 39 | Term neg_four = s->make_term(-4, bvsort8); 40 | 41 | assert(neg_four == s->make_term("-4", bvsort8)); 42 | 43 | try 44 | { 45 | Term impossible = s->make_term("-129", bvsort8); 46 | assert(false); 47 | } 48 | catch (IncorrectUsageException & e) 49 | { 50 | cout << e.what() << endl; 51 | } 52 | 53 | s->push(); 54 | s->assert_formula( 55 | s->make_term(Not, 56 | s->make_term(Equal, 57 | s->make_term(BVAdd, four, neg_four), 58 | s->make_term(0, bvsort8)))); 59 | Result r = s->check_sat(); 60 | assert(r.is_unsat()); 61 | s->pop(); 62 | 63 | r = s->check_sat(); 64 | assert(r.is_sat()); 65 | 66 | // Integer cases 67 | Sort intsort = s->make_sort(INT); 68 | Term five = s->make_term(5, intsort); 69 | Term neg_five = s->make_term(-5, intsort); 70 | 71 | assert(neg_five == s->make_term("-5", intsort)); 72 | 73 | s->push(); 74 | s->assert_formula( 75 | s->make_term(Not, 76 | s->make_term(Equal, 77 | s->make_term(Plus, five, neg_five), 78 | s->make_term("0", intsort)))); 79 | r = s->check_sat(); 80 | assert(r.is_unsat()); 81 | s->pop(); 82 | 83 | return 0; 84 | } 85 | -------------------------------------------------------------------------------- /tests/cvc5/cvc5-term-iter.cpp: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file cvc5-term-iter.cpp 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief 13 | ** 14 | ** 15 | **/ 16 | 17 | #include 18 | 19 | #include "cvc5/cvc5.h" 20 | #include "assert.h" 21 | #include "cvc5_term.h" 22 | #include "gtest/gtest.h" 23 | 24 | using namespace smt; 25 | using namespace std; 26 | 27 | TEST(Cvc5TermIterTest, Copy) 28 | { 29 | ::cvc5::TermManager term_manager; 30 | ::cvc5::Sort bvsort4 = term_manager.mkBitVectorSort(4); 31 | ::cvc5::Sort funsort = term_manager.mkFunctionSort({ bvsort4 }, bvsort4); 32 | 33 | ::cvc5::Term x = term_manager.mkConst(bvsort4, "x"); 34 | ::cvc5::Term v = term_manager.mkConst(bvsort4, "v"); 35 | ::cvc5::Term f = term_manager.mkConst(funsort, "f"); 36 | 37 | ::cvc5::Term fx = term_manager.mkTerm(cvc5::Kind::APPLY_UF, { f, x }); 38 | ::cvc5::Term fv = term_manager.mkTerm(cvc5::Kind::APPLY_UF, { f, v }); 39 | 40 | Cvc5TermIter it1(fx, 0); 41 | Cvc5TermIter it2(fx, 0); 42 | 43 | // NOTE: can't use _EQ and _NE macros because 44 | // it takes a const argument 45 | EXPECT_TRUE(it1 == it2); 46 | 47 | ++it2; 48 | EXPECT_TRUE(it1 != it2); 49 | 50 | Cvc5TermIter it3(fv, 0); 51 | EXPECT_TRUE(it1 != it3); 52 | 53 | Cvc5TermIter it4(it3); 54 | EXPECT_TRUE(it3 == it4); 55 | EXPECT_TRUE(it1 != it4); 56 | } 57 | -------------------------------------------------------------------------------- /tests/cvc5/cvc5-transfer.cpp: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file cvc5-transfer.cpp 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief 13 | ** 14 | ** 15 | **/ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | #include "assert.h" 22 | #include "cvc5_factory.h" 23 | #include "smt.h" 24 | // after a full installation 25 | // #include "smt-switch/cvc5_factory.h" 26 | // #include "smt-switch/smt.h" 27 | 28 | using namespace smt; 29 | using namespace std; 30 | 31 | int main() 32 | { 33 | SmtSolver s = Cvc5SolverFactory::create(false); 34 | s->set_opt("produce-models", "true"); 35 | Sort bvsort8 = s->make_sort(BV, 8); 36 | Term x = s->make_symbol("x", bvsort8); 37 | Term y = s->make_symbol("y", bvsort8); 38 | Term z = s->make_symbol("z", bvsort8); 39 | 40 | Term a = s->make_symbol("a", s->make_sort(INT)); 41 | Term b = s->make_symbol("b", s->make_sort(INT)); 42 | 43 | Term constraint = s->make_term(Equal, z, s->make_term(BVAdd, x, y)); 44 | constraint = s->make_term(And, constraint, s->make_term(Lt, a, b)); 45 | s->assert_formula(constraint); 46 | 47 | SmtSolver s2 = Cvc5SolverFactory::create(false); 48 | s2->set_opt("produce-models", "true"); 49 | s2->set_opt("incremental", "true"); 50 | 51 | TermTranslator tt(s2); 52 | 53 | Term constraint2 = tt.transfer_term(constraint); 54 | // ensure it can handle transfering again (even though it already built the 55 | // node) 56 | constraint2 = tt.transfer_term(constraint); 57 | s2->assert_formula(constraint2); 58 | 59 | cout << "term from solver 1: " << constraint << endl; 60 | cout << "term from solver 2: " << constraint2 << endl; 61 | 62 | assert(s->check_sat().is_sat()); 63 | assert(s2->check_sat().is_sat()); 64 | 65 | return 0; 66 | } 67 | -------------------------------------------------------------------------------- /tests/msat/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | macro(switch_add_msat_test name) 2 | add_executable(${name} "${PROJECT_SOURCE_DIR}/tests/msat/${name}.cpp") 3 | target_link_libraries(${name} gtest gtest_main) 4 | target_link_libraries(${name} test-deps) 5 | add_test(NAME ${name}_test COMMAND ${name}) 6 | endmacro() 7 | 8 | # these tests don't use GoogleTest yet 9 | # TODO move old tests to Google Test infrastructure 10 | switch_add_msat_test(msat-tests) 11 | switch_add_msat_test(msat-arrays) 12 | switch_add_msat_test(msat-arrays2) 13 | switch_add_msat_test(msat-data-structures) 14 | switch_add_msat_test(msat-incremental) 15 | switch_add_msat_test(msat-traversal) 16 | switch_add_msat_test(msat-int-arithmetic) 17 | switch_add_msat_test(msat-transfer) 18 | switch_add_msat_test(msat-substitute) 19 | switch_add_msat_test(msat-indexed-op-tests) 20 | switch_add_msat_test(msat-array-models) 21 | switch_add_msat_test(msat-ext-ops) 22 | switch_add_msat_test(msat-interpolants) 23 | switch_add_msat_test(msat-seq-interpolants) 24 | switch_add_msat_test(msat-const-arrays) 25 | switch_add_msat_test(msat-ite-test) 26 | switch_add_msat_test(msat-neg-numbers) 27 | switch_add_msat_test(msat-printing) 28 | -------------------------------------------------------------------------------- /tests/msat/msat-array-models.cpp: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file msat-array-models.cpp 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief 13 | ** 14 | ** 15 | **/ 16 | 17 | #include 18 | #include 19 | #include 20 | #include "assert.h" 21 | 22 | #include "msat_factory.h" 23 | #include "smt.h" 24 | // after a full installation 25 | // #include "smt-switch/msat_factory.h" 26 | // #include "smt-switch/smt.h" 27 | 28 | using namespace smt; 29 | using namespace std; 30 | 31 | int main() 32 | { 33 | SmtSolver s = MsatSolverFactory::create(false); 34 | s->set_opt("produce-models", "true"); 35 | Sort bvsort32 = s->make_sort(BV, 32); 36 | Sort array32_32 = s->make_sort(ARRAY, bvsort32, bvsort32); 37 | Term x0 = s->make_symbol("x0", bvsort32); 38 | Term x1 = s->make_symbol("x1", bvsort32); 39 | Term y = s->make_symbol("y", bvsort32); 40 | Term arr = s->make_symbol("arr", array32_32); 41 | 42 | Term constraint = s->make_term(Equal, s->make_term(Select, arr, x0), x1); 43 | constraint = s->make_term( 44 | And, constraint, s->make_term(Equal, s->make_term(Select, arr, x1), y)); 45 | constraint = s->make_term(And, constraint, s->make_term(Distinct, x1, y)); 46 | s->assert_formula(constraint); 47 | Result r = s->check_sat(); 48 | 49 | assert(r.is_sat()); 50 | 51 | Term arr_val = s->get_value(arr); 52 | 53 | cout << arr_val << endl; 54 | 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /tests/msat/msat-arrays.cpp: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file msat-arrays.cpp 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief 13 | ** 14 | ** 15 | **/ 16 | 17 | #include 18 | #include 19 | #include 20 | #include "assert.h" 21 | 22 | #include "msat_factory.h" 23 | #include "smt.h" 24 | // after a full installation 25 | // #include "smt-switch/msat_factory.h" 26 | // #include "smt-switch/smt.h" 27 | 28 | using namespace smt; 29 | using namespace std; 30 | 31 | int main() 32 | { 33 | SmtSolver s = MsatSolverFactory::create(false); 34 | s->set_opt("produce-models", "true"); 35 | Sort bvsort32 = s->make_sort(BV, 32); 36 | Sort array32_32 = s->make_sort(ARRAY, bvsort32, bvsort32); 37 | Term x = s->make_symbol("x", bvsort32); 38 | Term y = s->make_symbol("y", bvsort32); 39 | Term arr = s->make_symbol("arr", array32_32); 40 | 41 | cout << "Sorts:" << endl; 42 | cout << "\tbvsort32 : " << bvsort32 << endl; 43 | cout << "\tarray32_32 : " << array32_32 << endl; 44 | s->assert_formula( 45 | s->make_term(Not, 46 | s->make_term(Implies, 47 | s->make_term(Equal, x, y), 48 | s->make_term(Equal, 49 | s->make_term(Select, arr, x), 50 | s->make_term(Select, arr, y))))); 51 | assert(!s->check_sat().is_sat()); 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /tests/msat/msat-arrays2.cpp: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file msat-arrays2.cpp 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief 13 | ** 14 | ** 15 | **/ 16 | 17 | #include 18 | #include 19 | #include 20 | #include "assert.h" 21 | 22 | #include "msat_factory.h" 23 | #include "smt.h" 24 | // after a full installation 25 | // #include "smt-switch/msat_factory.h" 26 | // #include "smt-switch/smt.h" 27 | 28 | using namespace smt; 29 | using namespace std; 30 | 31 | int main() 32 | { 33 | SmtSolver s = MsatSolverFactory::create(false); 34 | s->set_opt("produce-models", "true"); 35 | Sort bvsort4 = s->make_sort(BV, 4); 36 | Sort bvsort8 = s->make_sort(BV, 8); 37 | Sort array4_8 = s->make_sort(ARRAY, bvsort4, bvsort8); 38 | Term x = s->make_symbol("x", bvsort4); 39 | Term elem = s->make_symbol("elem", bvsort8); 40 | Term mem = s->make_symbol("mem", array4_8); 41 | 42 | Term new_array = s->make_term(Store, mem, x, elem); 43 | assert(new_array->get_op() == Store); 44 | 45 | for (auto c : new_array) 46 | { 47 | cout << c << endl; 48 | } 49 | 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /tests/msat/msat-indexed-op-tests.cpp: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file msat-indexed-op-tests.cpp 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief 13 | ** 14 | ** 15 | **/ 16 | 17 | #include 18 | #include 19 | #include 20 | #include "assert.h" 21 | 22 | #include "msat_factory.h" 23 | #include "smt.h" 24 | // after a full installation 25 | // #include "smt-switch/msat_factory.h" 26 | // #include "smt-switch/smt.h" 27 | 28 | using namespace smt; 29 | using namespace std; 30 | 31 | int main() 32 | { 33 | SmtSolver s = MsatSolverFactory::create(false); 34 | s->set_opt("produce-models", "true"); 35 | Sort bvsort9 = s->make_sort(BV, 9); 36 | Term x = s->make_symbol("x", bvsort9); 37 | Term y = s->make_symbol("y", bvsort9); 38 | Term onebit = s->make_symbol("onebit", s->make_sort(BV, 1)); 39 | 40 | Term unnecessary_rotation = s->make_term(Op(Rotate_Right, 1), onebit); 41 | 42 | Op ext74 = Op(Extract, 7, 4); 43 | Term x_upper = s->make_term(ext74, x); 44 | 45 | Op op = x_upper->get_op(); 46 | cout << "Op: " << op << endl; 47 | 48 | Term y_ror = s->make_term(Op(Rotate_Right, 2), y); 49 | Term y_rol = s->make_term(Op(Rotate_Left, 2), y); 50 | 51 | assert(y_ror->to_string() == "((_ rotate_right 2) y)"); 52 | assert(y_rol->to_string() == "((_ rotate_left 2) y)"); 53 | 54 | s->assert_formula(s->make_term(Equal, y_ror, y_rol)); 55 | s->assert_formula(s->make_term(Distinct, y, s->make_term(0, bvsort9))); 56 | s->assert_formula(s->make_term( 57 | Equal, x, s->make_term(Op(Repeat, 9), unnecessary_rotation))); 58 | 59 | Result r = s->check_sat(); 60 | assert(r.is_sat()); 61 | 62 | Term xc = s->get_value(x); 63 | Term x_upperc = s->get_value(x_upper); 64 | Term yc = s->get_value(y); 65 | 66 | cout << "Results:" << endl; 67 | cout << x << ": " << xc->to_int() << endl; 68 | cout << x_upper << ": " << x_upperc->to_int() << endl; 69 | cout << y << ": " << yc->to_int() << endl; 70 | return 0; 71 | } 72 | -------------------------------------------------------------------------------- /tests/msat/msat-int-arithmetic.cpp: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file msat-int-arithmetic.cpp 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief 13 | ** 14 | ** 15 | **/ 16 | 17 | #include 18 | #include 19 | #include 20 | #include "assert.h" 21 | 22 | #include "msat_factory.h" 23 | #include "smt.h" 24 | // after full installation 25 | // #include "smt-switch/msat_factory.h" 26 | // #include "smt-switch/smt.h" 27 | 28 | using namespace smt; 29 | using namespace std; 30 | 31 | int main() 32 | { 33 | SmtSolver s = MsatSolverFactory::create(false); 34 | s->set_opt("produce-models", "true"); 35 | s->set_logic("QF_NIA"); 36 | Sort intsort = s->make_sort(INT); 37 | Term x = s->make_symbol("x", intsort); 38 | Term y = s->make_symbol("y", intsort); 39 | Term z = s->make_symbol("z", intsort); 40 | 41 | s->assert_formula(s->make_term(Ge, x, y)); 42 | s->assert_formula(s->make_term(Le, z, s->make_term(Plus, x, y))); 43 | s->assert_formula( 44 | s->make_term(Lt, s->make_term(Negate, z), s->make_term(Minus, x, y))); 45 | s->assert_formula( 46 | s->make_term(Gt, s->make_term(Minus, x, y), s->make_term(Mult, x, y))); 47 | 48 | Result r = s->check_sat(); 49 | assert(r.is_sat()); 50 | 51 | cout << "Model Values:" << endl; 52 | for (auto t : TermVec({ x, y, z })) 53 | { 54 | cout << "\t" << t << " = " << s->get_value(t) << endl; 55 | } 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /tests/msat/msat-interpolants.cpp: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file msat-interpolants.cpp 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief 13 | ** 14 | ** 15 | **/ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | #include "assert.h" 22 | #include "msat_factory.h" 23 | #include "smt.h" 24 | // after a full installation 25 | // #include "smt-switch/msat_factory.h" 26 | // #include "smt-switch/smt.h" 27 | 28 | using namespace smt; 29 | using namespace std; 30 | 31 | int main() 32 | { 33 | SmtSolver s = MsatSolverFactory::create_interpolating_solver(); 34 | Sort intsort = s->make_sort(INT); 35 | 36 | Term x = s->make_symbol("x", intsort); 37 | Term y = s->make_symbol("y", intsort); 38 | Term z = s->make_symbol("z", intsort); 39 | 40 | try 41 | { 42 | s->assert_formula(s->make_term(Equal, x, s->make_term(0, intsort))); 43 | } 44 | catch (IncorrectUsageException & e) 45 | { 46 | cout << e.what() << endl; 47 | } 48 | 49 | Term A = s->make_term(And, s->make_term(Lt, x, y), s->make_term(Lt, y, z)); 50 | Term B = s->make_term(Gt, x, z); 51 | Term I; 52 | Result r = s->get_interpolant(A, B, I); 53 | 54 | if (r.is_unsat()) 55 | { 56 | cout << "Found interpolant: " << I << endl; 57 | } 58 | else 59 | { 60 | cout << "Didn't find an interpolant..." << endl; 61 | assert(false); 62 | } 63 | 64 | s->reset_assertions(); 65 | 66 | // try getting a second interpolant with different A and B 67 | A = s->make_term(And, s->make_term(Gt, x, y), s->make_term(Gt, y, z)); 68 | B = s->make_term(Lt, x, z); 69 | r = s->get_interpolant(A, B, I); 70 | 71 | if (r.is_unsat()) 72 | { 73 | cout << "Found interpolant: " << I << endl; 74 | } 75 | else 76 | { 77 | cout << "Didn't find an interpolant..." << endl; 78 | assert(false); 79 | } 80 | 81 | // now try a satisfiable formula 82 | r = s->get_interpolant(A, s->make_term(Gt, x, z), I); 83 | assert(r.is_sat()); 84 | 85 | return 0; 86 | } 87 | -------------------------------------------------------------------------------- /tests/msat/msat-ite-test.cpp: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file msat-ite-test.cpp 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief 13 | ** 14 | ** 15 | **/ 16 | 17 | #include 18 | #include 19 | #include 20 | #include "assert.h" 21 | 22 | #include "msat_factory.h" 23 | #include "smt.h" 24 | // after a full installation 25 | // #include "smt-switch/boolector_factory.h" 26 | // #include "smt-switch/smt.h" 27 | 28 | using namespace smt; 29 | using namespace std; 30 | 31 | int main() 32 | { 33 | SmtSolver s = MsatSolverFactory::create(false); 34 | s->set_logic("QF_ABV"); 35 | s->set_opt("produce-models", "true"); 36 | Sort boolsort = s->make_sort(BOOL); 37 | Term a = s->make_symbol("a", boolsort); 38 | Term b = s->make_symbol("b", boolsort); 39 | Term c = s->make_symbol("c", boolsort); 40 | 41 | Sort intsort = s->make_sort(INT); 42 | Term x = s->make_symbol("x", intsort); 43 | Term y = s->make_symbol("y", intsort); 44 | 45 | Term ite_bool = s->make_term(Ite, a, b, c); 46 | Term ite_axiom = s->make_term( 47 | And, 48 | s->make_term(Implies, a, s->make_term(Equal, ite_bool, b)), 49 | s->make_term( 50 | Implies, s->make_term(Not, a), s->make_term(Equal, ite_bool, c))); 51 | 52 | s->push(); 53 | s->assert_formula(s->make_term(Not, ite_axiom)); 54 | Result r = s->check_sat(); 55 | assert(r.is_unsat()); 56 | s->pop(); 57 | 58 | r = s->check_sat(); 59 | assert(r.is_sat()); 60 | 61 | Term ite_int = s->make_term(Ite, a, x, y); 62 | Term ite_axiom_int = s->make_term( 63 | And, 64 | s->make_term(Implies, a, s->make_term(Equal, ite_int, x)), 65 | s->make_term( 66 | Implies, s->make_term(Not, a), s->make_term(Equal, ite_int, y))); 67 | 68 | s->push(); 69 | s->assert_formula(s->make_term(Not, ite_axiom_int)); 70 | r = s->check_sat(); 71 | assert(r.is_unsat()); 72 | s->pop(); 73 | 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /tests/portfolio/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | macro(switch_add_portfolio_test name) 2 | add_executable(${name} "${PROJECT_SOURCE_DIR}/tests/portfolio/${name}.cpp") 3 | target_link_libraries(${name} gtest gtest_main) 4 | target_link_libraries(${name} test-deps) 5 | add_test(NAME ${name}_test COMMAND ${name}) 6 | endmacro() 7 | 8 | switch_add_portfolio_test(test-portfolio-solver) 9 | 10 | -------------------------------------------------------------------------------- /tests/python/available_solvers.py: -------------------------------------------------------------------------------- 1 | ############################################################### 2 | # \file available_solvers.py 3 | # \verbatim 4 | # Top contributors (to current version): 5 | # Makai Mann 6 | # This file is part of the smt-switch project. 7 | # Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | # in the top-level source directory) and their institutional affiliations. 9 | # All rights reserved. See the file LICENSE in the top-level source 10 | # directory for licensing information.\endverbatim 11 | # 12 | # \brief 13 | # 14 | # 15 | # 16 | 17 | import smt_switch as ss 18 | 19 | 20 | termiter_support_solvers = {k:v for k, v in ss.solvers.items() if k != 'yices2'} 21 | int_support_solvers = {k:v for k, v in ss.solvers.items() if k != 'btor' and k != 'bitwuzla'} 22 | -------------------------------------------------------------------------------- /tests/python/test_enums.py: -------------------------------------------------------------------------------- 1 | ############################################################### 2 | # \file test_enums.py 3 | # \verbatim 4 | # Top contributors (to current version): 5 | # Makai Mann 6 | # This file is part of the smt-switch project. 7 | # Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | # in the top-level source directory) and their institutional affiliations. 9 | # All rights reserved. See the file LICENSE in the top-level source 10 | # directory for licensing information.\endverbatim 11 | # 12 | # \brief Test getters for enums (SortKind and PrimOp) 13 | # 14 | # 15 | 16 | import pytest 17 | import smt_switch as ss 18 | 19 | from available_solvers import int_support_solvers 20 | 21 | 22 | @pytest.mark.parametrize("create_solver", [f for name, f in int_support_solvers.items()]) 23 | def test_sortkind(create_solver): 24 | solver = create_solver(False) 25 | bvsort = solver.make_sort(ss.sortkinds.BV, 8) 26 | x = solver.make_symbol("x", bvsort) 27 | sk = x.get_sort().get_sort_kind() 28 | assert hash(ss.sortkinds.BV) == hash(sk) 29 | assert sk == ss.sortkinds.BV 30 | assert sk is ss.sortkinds.BV 31 | 32 | 33 | @pytest.mark.parametrize("create_solver", [f for name, f in int_support_solvers.items()]) 34 | def test_primop(create_solver): 35 | solver = create_solver(False) 36 | bvsort = solver.make_sort(ss.sortkinds.BV, 8) 37 | x = solver.make_symbol("x", bvsort) 38 | y = solver.make_symbol("y", bvsort) 39 | xpy = solver.make_term(ss.primops.BVAdd, x, y) 40 | op = xpy.get_op() 41 | 42 | assert hash(ss.primops.BVAdd) == hash(op.prim_op) 43 | assert op.prim_op == ss.primops.BVAdd 44 | assert op.prim_op is ss.primops.BVAdd 45 | -------------------------------------------------------------------------------- /tests/python/test_lia.py: -------------------------------------------------------------------------------- 1 | ############################################################### 2 | # \file test_lia.py 3 | # \verbatim 4 | # Top contributors (to current version): 5 | # Makai Mann 6 | # This file is part of the smt-switch project. 7 | # Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | # in the top-level source directory) and their institutional affiliations. 9 | # All rights reserved. See the file LICENSE in the top-level source 10 | # directory for licensing information.\endverbatim 11 | # 12 | # \brief 13 | # 14 | # 15 | # 16 | 17 | import pytest 18 | import smt_switch as ss 19 | 20 | from available_solvers import int_support_solvers 21 | 22 | @pytest.mark.parametrize("create_solver", [f for name, f in int_support_solvers.items()]) 23 | def test_simple(create_solver): 24 | solver = create_solver(False) 25 | solver.set_opt('produce-models', 'true') 26 | solver.set_logic('QF_LIA') 27 | 28 | intsort = solver.make_sort(ss.sortkinds.INT) 29 | x = solver.make_symbol('x', intsort) 30 | y = solver.make_symbol('y', intsort) 31 | z = solver.make_symbol('z', intsort) 32 | 33 | two = solver.make_term(2, intsort) 34 | three = solver.make_term(3, intsort) 35 | five = solver.make_term(5, intsort) 36 | 37 | t1 = solver.make_term(ss.primops.Plus, 38 | solver.make_term(ss.primops.Mult, two, x), 39 | solver.make_term(ss.primops.Mult, three, y)) 40 | t2 = solver.make_term(ss.primops.Minus, 41 | solver.make_term(ss.primops.Mult, five, y), 42 | solver.make_term(ss.primops.Mult, three, z)) 43 | 44 | f1 = solver.make_term(ss.primops.Lt, t1, five) 45 | f2 = solver.make_term(ss.primops.Ge, t2, two) 46 | 47 | solver.assert_formula(f1) 48 | solver.assert_formula(f2) 49 | 50 | r = solver.check_sat() 51 | assert r.is_sat() 52 | 53 | xv = int(solver.get_value(x)) 54 | yv = int(solver.get_value(y)) 55 | zv = int(solver.get_value(z)) 56 | 57 | assert 2*xv + 3*yv < 5 58 | assert 5*yv - 3*zv >= 2 59 | -------------------------------------------------------------------------------- /tests/python/test_pysmt.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | import smt_switch as ss 3 | 4 | pysmt = pytest.importorskip("pysmt") 5 | from pysmt import shortcuts as sc 6 | from pysmt import typing as st 7 | from pysmt import logics as sl 8 | import smt_switch.pysmt_frontend as fe 9 | 10 | @pytest.mark.parametrize('solver_str', fe.SWITCH_SOLVERS.keys()) 11 | @pytest.mark.parametrize(('T', 'logic'), [ 12 | (st.BV8, sl.QF_BV), 13 | (st.INT, sl.QF_LIA), 14 | (st.REAL, sl.QF_LRA), 15 | ]) 16 | @pytest.mark.parametrize('implicit', [True, False]) 17 | def test_basic(solver_str, T, logic, implicit): 18 | x = sc.FreshSymbol(T) 19 | problem = sc.And(x < 2, x > 0) 20 | x_val = None 21 | if implicit: 22 | args = () 23 | else: 24 | args = (logic,) 25 | 26 | 27 | if logic not in fe.SWITCH_SOLVERS[solver_str].LOGICS: 28 | with pytest.raises(RuntimeError): 29 | with fe.Solver(solver_str, *args) as solver: 30 | solver.add_assertion(problem) 31 | else: 32 | with fe.Solver(solver_str, *args) as solver: 33 | solver.add_assertion(problem) 34 | assert solver.solve() 35 | if T is not st.REAL: 36 | x_val = solver.get_py_value(x) 37 | assert x_val == 1 38 | else: 39 | x_val = solver.get_value(problem) 40 | assert x_val is not None 41 | -------------------------------------------------------------------------------- /tests/python/test_sorting_network.py: -------------------------------------------------------------------------------- 1 | ############################################################### 2 | # \file test_sorting_network.py 3 | # \verbatim 4 | # Top contributors (to current version): 5 | # Makai Mann 6 | # This file is part of the smt-switch project. 7 | # Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | # in the top-level source directory) and their institutional affiliations. 9 | # All rights reserved. See the file LICENSE in the top-level source 10 | # directory for licensing information.\endverbatim 11 | # 12 | # \brief Test SortingNetwork through Python bindings 13 | # see include/sorting_network.h for more information on the 14 | # SortingNetwork class 15 | # 16 | 17 | from itertools import product 18 | import pytest 19 | 20 | import smt_switch as ss 21 | 22 | @pytest.mark.parametrize("create_solver,num_vars", 23 | product(ss.solvers.values(), [3, 6, 8])) 24 | def test_sorting_network(create_solver, num_vars): 25 | solver = create_solver(False) 26 | solver.set_opt('produce-models', 'true') 27 | solver.set_opt('incremental', 'true') 28 | 29 | boolsort = solver.make_sort(ss.sortkinds.BOOL) 30 | boollist = [] 31 | for i in range(num_vars): 32 | boollist.append(solver.make_symbol('b' + str(i), boolsort)) 33 | 34 | sn = ss.SortingNetwork(solver) 35 | sortedlist = sn.sorting_network(boollist) 36 | 37 | # Test each possible return value 38 | for num_true in range(num_vars+1): 39 | solver.push() 40 | if num_true: 41 | # ensure there are at least num_true set to true 42 | solver.assert_formula(sortedlist[num_true-1]) 43 | if num_true < num_vars: 44 | # ensure there aren't more than num_true set to true 45 | solver.assert_formula(solver.make_term(ss.primops.Not, sortedlist[num_true])) 46 | res = solver.check_sat() 47 | assert res.is_sat() 48 | 49 | true_ = solver.make_term(True) 50 | counted_true = 0 51 | for bb in boollist: 52 | val = solver.get_value(bb) 53 | if val == true_: 54 | counted_true += 1 55 | assert counted_true == num_true 56 | solver.pop() 57 | -------------------------------------------------------------------------------- /tests/python/test_unit_vals.py: -------------------------------------------------------------------------------- 1 | ############################################################### 2 | # \file test_unit_vals.py 3 | # \verbatim 4 | # Top contributors (to current version): 5 | # Makai Mann 6 | # This file is part of the smt-switch project. 7 | # Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | # in the top-level source directory) and their institutional affiliations. 9 | # All rights reserved. See the file LICENSE in the top-level source 10 | # directory for licensing information.\endverbatim 11 | # 12 | # \brief 13 | # 14 | # 15 | # 16 | 17 | import pytest 18 | import smt_switch as ss 19 | from smt_switch.primops import Distinct, Equal, Select, Store 20 | import available_solvers 21 | 22 | termiter_and_int_keys = available_solvers.termiter_support_solvers.keys() & available_solvers.int_support_solvers.keys() 23 | termiter_and_int_solvers = [f for f in {ss.solvers[n] for n in termiter_and_int_keys}] 24 | 25 | 26 | @pytest.mark.parametrize("create_solver", termiter_and_int_solvers) 27 | def test_unit_bigint(create_solver): 28 | solver = create_solver(False) 29 | intsort = solver.make_sort(ss.sortkinds.INT) 30 | 31 | bigint = solver.make_term(2**200, intsort) 32 | maxsint_64 = solver.make_term(int("0x7FFFFFFFFFFFFFFF", 16), intsort) 33 | 34 | solver.assert_formula(solver.make_term(ss.primops.Gt, bigint, maxsint_64)) 35 | assert solver.check_sat().is_sat(), "Expecting to represent a large integer without overflow" 36 | -------------------------------------------------------------------------------- /tests/python/test_unsat_core.py: -------------------------------------------------------------------------------- 1 | ############################################################### 2 | # \file test_unsat_core.py 3 | # \verbatim 4 | # Top contributors (to current version): 5 | # Makai Mann 6 | # This file is part of the smt-switch project. 7 | # Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | # in the top-level source directory) and their institutional affiliations. 9 | # All rights reserved. See the file LICENSE in the top-level source 10 | # directory for licensing information.\endverbatim 11 | # 12 | # \brief 13 | # 14 | # 15 | # 16 | 17 | import pytest 18 | import smt_switch as ss 19 | 20 | @pytest.mark.parametrize("create_solver", ss.solvers.values()) 21 | def test_unsat_assumptions_simple(create_solver): 22 | solver = create_solver(False) 23 | solver.set_opt("produce-unsat-assumptions", "true") 24 | 25 | boolsort = solver.make_sort(ss.sortkinds.BOOL) 26 | a = solver.make_symbol("a", boolsort) 27 | b = solver.make_symbol("b", boolsort) 28 | notB = solver.make_term(ss.primops.Not, b) 29 | r = solver.check_sat_assuming([a, b, notB]); 30 | core = solver.get_unsat_assumptions() 31 | assert b in core, "expecting b to be in core" 32 | assert notB in core, "expecting (not b) to be in core" 33 | -------------------------------------------------------------------------------- /tests/python/test_visitor.py: -------------------------------------------------------------------------------- 1 | ############################################################### 2 | # \file test_visitor.py 3 | # \verbatim 4 | # Top contributors (to current version): 5 | # Makai Mann 6 | # This file is part of the smt-switch project. 7 | # Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | # in the top-level source directory) and their institutional affiliations. 9 | # All rights reserved. See the file LICENSE in the top-level source 10 | # directory for licensing information.\endverbatim 11 | # 12 | # \brief Small test of identity visiting 13 | # 14 | 15 | import pytest 16 | import smt_switch as ss 17 | from smt_switch.primops import Ite, Equal, BVOr, BVUlt 18 | 19 | @pytest.mark.parametrize("create_solver", [f for name, f in ss.solvers.items() if name != 'yices2']) 20 | def test_identity_visit_basic(create_solver): 21 | solver = create_solver(False) 22 | 23 | bv32 = solver.make_sort(ss.sortkinds.BV, 32) 24 | 25 | x = solver.make_symbol('x', bv32) 26 | y = solver.make_symbol('y', bv32) 27 | a = solver.make_symbol('a', bv32) 28 | b = solver.make_symbol('b', bv32) 29 | 30 | y_assignment = solver.make_term(Ite, 31 | solver.make_term(BVUlt, x, y), 32 | solver.make_term(BVOr, x, a), 33 | solver.make_term(BVOr, x, b)) 34 | 35 | idvisitor = ss.IdentityVisitor(solver) 36 | rebuilt_y_assignment = idvisitor.walk_dag(y_assignment) 37 | assert y_assignment == rebuilt_y_assignment 38 | -------------------------------------------------------------------------------- /tests/smt2/qf_alia/test-array.smt2: -------------------------------------------------------------------------------- 1 | (set-logic QF_ALIA) 2 | (declare-const x Int) 3 | (declare-const y Int) 4 | (declare-const arr (Array Int Int)) 5 | (declare-const all0 (Array Int Int)) 6 | (assert (= y (select arr x))) 7 | (assert (= all0 8 | ((as const (Array Int Int)) 0) 9 | )) 10 | (assert (= y (select all0 x))) 11 | (assert (distinct y 0)) 12 | (check-sat) -------------------------------------------------------------------------------- /tests/smt2/qf_s/test-ops-SLIA.smt2: -------------------------------------------------------------------------------- 1 | (set-logic QF_SLIA) 2 | 3 | (declare-const x String) 4 | (declare-const y String) 5 | (declare-const z String) 6 | (declare-const substryx String) 7 | (declare-const empty String) 8 | (declare-const lenx Int) 9 | (declare-const leny Int) 10 | (declare-const lenz Int) 11 | 12 | (assert (= lenx (str.len x))) 13 | (assert (= leny (str.len y))) 14 | (assert (= lenz (str.len z))) 15 | 16 | (declare-const xx String) 17 | (declare-const xy String) 18 | (declare-const yx String) 19 | (declare-const xxx String) 20 | (declare-const xyy String) 21 | 22 | (assert (= xx (str.++ x x))) 23 | (assert (= xy (str.++ x y))) 24 | (assert (= yx (str.++ y x))) 25 | (assert (= xxx (str.++ xx x))) 26 | (assert (= xyy (str.++ xy y))) 27 | 28 | (assert (= substryx (str.substr yx leny lenx))) 29 | (assert (= empty "")) 30 | 31 | ;StrLt 32 | (assert (str.< x y)) 33 | (assert (str.< yx xy)) 34 | ;StrLeq StrConcat 35 | (assert (str.<= z xy)) 36 | ;StrLen 37 | (assert (< 0 lenz)) 38 | ;StrConcat 39 | (assert (not (= xy yx))) 40 | ;StrSubstr 41 | (assert (= x substryx)) 42 | (assert (not (= y substryx))) 43 | (assert (= empty (str.substr x lenx lenx))) 44 | (assert (= empty (str.substr x (- 1) lenx))) 45 | ;StrAt 46 | (assert (= (str.len (str.at y 0)) 1)) 47 | (assert (= empty (str.at x lenx))) 48 | (assert (= empty (str.at x (- 1)))) 49 | ;StrContains 50 | (assert (not (str.contains x y))) 51 | (assert (str.contains xy y)) 52 | ;StrIndexof 53 | (assert (= lenx (str.indexof xyy y (- lenx 1)))) 54 | (assert (= 0 (str.indexof xy empty 0))) 55 | (assert (= (- 1) (str.indexof xy x (- 1)))) 56 | (assert (= (- 1) (str.indexof x y lenx))) 57 | (assert (= (- 1) (str.indexof x y 0))) 58 | ;StrReplace 59 | (assert (= xx (str.replace xy y x))) 60 | (assert (= xy (str.replace y empty x))) 61 | ;StrReplaceAll 62 | (assert (= xxx (str.replace_all xyy y x))) 63 | (assert (= xyy (str.replace_all xyy empty x))) 64 | ;StrPrefixof 65 | (assert (str.prefixof x xyy)) 66 | (assert (not (str.prefixof "1" "A"))) 67 | ;StrSuffixof 68 | (assert (str.suffixof y xyy)) 69 | (assert (not (str.suffixof "1" "A"))) 70 | ;StrIsDigit 71 | (assert (str.is_digit "1")) 72 | (assert (not (str.is_digit "A"))) 73 | (assert (not (str.is_digit "10"))) 74 | 75 | (check-sat) 76 | -------------------------------------------------------------------------------- /tests/smt2/qf_s/test-ops.smt2: -------------------------------------------------------------------------------- 1 | (set-logic QF_S) 2 | 3 | (declare-const x String) 4 | (declare-const y String) 5 | (declare-const z String) 6 | (declare-const substryx String) 7 | (declare-const empty String) 8 | 9 | (declare-const xx String) 10 | (declare-const xy String) 11 | (declare-const yx String) 12 | (declare-const xxx String) 13 | (declare-const xyy String) 14 | 15 | (assert (= xx (str.++ x x))) 16 | (assert (= xy (str.++ x y))) 17 | (assert (= yx (str.++ y x))) 18 | (assert (= xxx (str.++ xx x))) 19 | (assert (= xyy (str.++ xy y))) 20 | 21 | (assert (= substryx (str.substr yx (str.len y) (str.len x)))) 22 | (assert (= empty "")) 23 | 24 | ;StrLt 25 | (assert (str.< x y)) 26 | (assert (str.< yx xy)) 27 | ;StrLeq StrConcat 28 | (assert (str.<= z xy)) 29 | ;StrLen 30 | (assert (str.< empty z)) 31 | ;StrConcat 32 | (assert (not (= xy yx))) 33 | ;StrSubstr 34 | (assert (= x substryx)) 35 | (assert (not (= y substryx))) 36 | (assert (= empty (str.substr x (str.len x) (str.len x)))) 37 | ;StrAt 38 | (assert (= (str.len (str.at y 0)) 1)) 39 | (assert (= empty (str.at x (str.len x)))) 40 | ;StrContains 41 | (assert (not (str.contains x y))) 42 | (assert (str.contains xy y)) 43 | ;StrIndexof 44 | (assert (= (str.len x) (str.indexof xyy y 0))) 45 | (assert (= 0 (str.indexof xy empty 0))) 46 | ;StrReplace 47 | (assert (= xx (str.replace xy y x))) 48 | (assert (= xy (str.replace y empty x))) 49 | ;StrReplaceAll 50 | (assert (= xxx (str.replace_all xyy y x))) 51 | (assert (= xyy (str.replace_all xyy empty x))) 52 | ;StrPrefixof 53 | (assert (str.prefixof x xyy)) 54 | (assert (not (str.prefixof "1" "A"))) 55 | ;StrSuffixof 56 | (assert (str.suffixof y xyy)) 57 | (assert (not (str.suffixof "1" "A"))) 58 | ;StrIsDigit 59 | (assert (str.is_digit "1")) 60 | (assert (not (str.is_digit "A"))) 61 | (assert (not (str.is_digit "10"))) 62 | 63 | (check-sat) 64 | -------------------------------------------------------------------------------- /tests/smt2/qf_uf/test-uninterp-sort-nonzero-arity.smt2: -------------------------------------------------------------------------------- 1 | (set-logic QF_UFLIA) 2 | (declare-sort Mem 2) 3 | (declare-const m0 (Mem Int Int)) 4 | (declare-const m1 (Mem Int Int)) 5 | (declare-const m2 (Mem Int Int)) 6 | (assert (= m0 m1)) 7 | (assert (= m1 m2)) 8 | (declare-fun pred ((Mem Int Int)) Bool) 9 | (assert (pred m0)) 10 | (assert (not (pred m2))) 11 | (check-sat) -------------------------------------------------------------------------------- /tests/smt2/qf_uf/test-uninterp-sort-zero-arity.smt2: -------------------------------------------------------------------------------- 1 | (set-logic QF_UF) 2 | (declare-sort color 0) 3 | (declare-const red color) 4 | (declare-const green color) 5 | (declare-const blue color) 6 | 7 | (assert (distinct red green blue)) 8 | 9 | (define-fun rgb ((c color)) Bool (or (= c red) (= c green) (= c blue))) 10 | 11 | (declare-const c0 color) 12 | (declare-const c1 color) 13 | (declare-const c2 color) 14 | 15 | (assert (rgb c0)) 16 | (assert (rgb c1)) 17 | (assert (rgb c2)) 18 | 19 | (check-sat) -------------------------------------------------------------------------------- /tests/smt2/qf_ufbv/test-attr.smt2: -------------------------------------------------------------------------------- 1 | (set-logic QF_UFBV) 2 | (set-option :produce-models true) 3 | (set-option :incremental true) 4 | (declare-const x (_ BitVec 8)) 5 | (declare-const y (_ BitVec 8)) 6 | (define-fun xlow () (_ BitVec 4) ((_ extract 3 0) x)) 7 | (define-fun ylow () (_ BitVec 4) ((_ extract 3 0) y)) 8 | (define-fun xhigh () (_ BitVec 4) ((_ extract 7 4) x)) 9 | (define-fun yhigh () (_ BitVec 4) ((_ extract 7 4) y)) 10 | (declare-fun f ((_ BitVec 8)) (_ BitVec 8)) 11 | (assert (! (distinct (f x) (f y)) :name diff)) 12 | (assert (! (= xlow ylow) :name equal-low)) 13 | (check-sat) 14 | (assert (! (= xhigh yhigh) :name equal-high)) 15 | (check-sat) 16 | (exit) 17 | -------------------------------------------------------------------------------- /tests/smt2/qf_ufbv/test-define-sort-edge-case.smt2: -------------------------------------------------------------------------------- 1 | ;; this file tests an edge case 2 | ;; SMT-LIB allows using sort symbols as 3 | ;; the name of defined sort as long as 4 | ;; it's not included in the current logic 5 | ;; (i.e. the name Int is available if there 6 | ;; are no integers in the logic's signature) 7 | (set-logic QF_UFBV) 8 | (define-sort Int () (_ BitVec 32)) 9 | (declare-const x Int) 10 | (declare-const y Int) 11 | (assert (= ((_ extract 31 31) x) #b1)) 12 | (assert (= ((_ extract 31 31) y) #b0)) 13 | (assert (bvult x y)) 14 | (check-sat) 15 | 16 | -------------------------------------------------------------------------------- /tests/smt2/qf_ufbv/test-define-sort.smt2: -------------------------------------------------------------------------------- 1 | (set-logic QF_UFBV) 2 | (define-sort Word () (_ BitVec 32)) 3 | (declare-const x Word) 4 | (declare-const y Word) 5 | (assert (= ((_ extract 31 31) x) #b1)) 6 | (assert (= ((_ extract 31 31) y) #b0)) 7 | (assert (bvult x y)) 8 | (check-sat) 9 | 10 | -------------------------------------------------------------------------------- /tests/smt2/qf_uflia/test-symbols.smt2: -------------------------------------------------------------------------------- 1 | (set-logic QF_UFLIA) 2 | (set-option :incremental true) 3 | (set-option :produce-models true) 4 | (declare-const x Int) 5 | (declare-const y Int) 6 | (declare-const z Int) 7 | (declare-fun bvadd (Int Int) Int) 8 | (assert (and (<= y (+ x 1)) 9 | (> y x))) 10 | (assert (< (bvadd x y) y)) 11 | (assert (= z (ite (< x y) x y))) 12 | (check-sat) 13 | (push) 14 | (check-sat-assuming (false)) 15 | (pop) 16 | (check-sat) 17 | (get-value (x y z)) -------------------------------------------------------------------------------- /tests/smt2/qf_uflia/test-uf.smt2: -------------------------------------------------------------------------------- 1 | (set-logic QF_UFLIA) 2 | (set-option :incremental true) 3 | (set-option :produce-models true) 4 | (declare-const x Int) 5 | (declare-const y Int) 6 | (declare-const z Int) 7 | (declare-fun f (Int Int) Int) 8 | (assert (and (<= y (+ x 1)) 9 | (> y x))) 10 | (assert (< (f x y) y)) 11 | (assert (= z (ite (< x y) x y))) 12 | (check-sat) 13 | (push) 14 | (check-sat-assuming (false)) 15 | (pop) 16 | (check-sat) 17 | (get-value (x y z)) -------------------------------------------------------------------------------- /tests/smtlib_reader_test_inputs.h: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file smtlib_reader_test_inputs.h 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief List test inputs for SmtLibReader 13 | ** 14 | ** 15 | **/ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | 22 | #include "smt.h" 23 | 24 | // maps tests to their expected results 25 | const std::unordered_map> qf_uflia_tests({ 26 | { "test-uf.smt2", 27 | { smt::Result(smt::SAT), 28 | smt::Result(smt::UNSAT), 29 | smt::Result(smt::SAT) } }, 30 | { "test-symbols.smt2", 31 | { smt::Result(smt::SAT), 32 | smt::Result(smt::UNSAT), 33 | smt::Result(smt::SAT) } }, 34 | }); 35 | 36 | const std::unordered_map> qf_s_tests({ 37 | { "test-ops.smt2", { smt::Result(smt::SAT)} }, 38 | { "test-ops-SLIA.smt2", { smt::Result(smt::SAT)} }, 39 | }); 40 | 41 | const std::unordered_map> qf_ufbv_tests( 42 | { { "test-attr.smt2", 43 | { smt::Result(smt::SAT), smt::Result(smt::UNSAT) } }, 44 | { "test-define-sort.smt2", { smt::Result(smt::UNSAT) } }, 45 | { "test-define-sort-edge-case.smt2", { smt::Result(smt::UNSAT) } } }); 46 | 47 | const std::unordered_map> qf_alia_tests({ 48 | { "test-array.smt2", { smt::Result(smt::UNSAT) } }, 49 | }); 50 | 51 | const std::unordered_map> qf_uf_tests( 52 | { { "test-uninterp-sort-zero-arity.smt2", { smt::Result(smt::SAT) } } }); 53 | 54 | const std::unordered_map> 55 | qf_uf_param_sorts_tests({ { "test-uninterp-sort-nonzero-arity.smt2", 56 | { smt::Result(smt::UNSAT) } } }); 57 | -------------------------------------------------------------------------------- /tests/test-bv.cpp: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file test-bv.cpp 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Yoni Zohar 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief Tests for theory of bit-vectors. 13 | ** 14 | ** 15 | **/ 16 | 17 | #include 18 | #include 19 | 20 | #include "available_solvers.h" 21 | #include "gtest/gtest.h" 22 | #include "smt.h" 23 | 24 | using namespace smt; 25 | using namespace std; 26 | 27 | namespace smt_tests { 28 | 29 | GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BVTests); 30 | class BVTests : public ::testing::Test, 31 | public ::testing::WithParamInterface 32 | { 33 | protected: 34 | void SetUp() override 35 | { 36 | s = create_solver(GetParam()); 37 | s->set_opt("produce-models", "true"); 38 | s->set_opt("incremental", "true"); 39 | } 40 | SmtSolver s; 41 | }; 42 | 43 | // based on issue #308 44 | TEST_P(BVTests, to_int) 45 | { 46 | Sort sort1 = s->make_sort(BV, 1); 47 | Sort sort2 = s->make_sort(BV, 2); 48 | Term x1 = s->make_symbol("x1", sort1); 49 | Term x2 = s->make_symbol("x2", sort2); 50 | s->check_sat(); 51 | uint64_t i1 = s->get_value(x1)->to_int(); 52 | uint64_t i2 = s->get_value(x2)->to_int(); 53 | ASSERT_TRUE(0 <= i1 && i1 <= 1); 54 | ASSERT_TRUE(0 <= i2 && i2 <= 3); 55 | 56 | Sort bv3 = s->make_sort(BV, 3); 57 | Term minus_one = s->make_term(-1, bv3); 58 | Term one = s->make_term(1, bv3); 59 | Term x = s->make_symbol("x", bv3); 60 | s->assert_formula(s->make_term(BVSlt, minus_one, x)); 61 | s->assert_formula(s->make_term(BVSlt, x, one)); 62 | s->check_sat(); 63 | EXPECT_EQ(s->get_value(x)->to_int(), 0); 64 | } 65 | 66 | INSTANTIATE_TEST_SUITE_P( 67 | ParameterizedSolverBVTests, 68 | BVTests, 69 | testing::ValuesIn(filter_solver_configurations({ THEORY_BV }))); 70 | 71 | } // namespace smt_tests 72 | -------------------------------------------------------------------------------- /tests/test-disjointset.cpp: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file test-disjointset.cpp 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Ahmed Irfan, Makai Mann 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief Tests for disjoint-set. 13 | ** 14 | ** 15 | **/ 16 | 17 | #include 18 | #include 19 | 20 | #include "available_solvers.h" 21 | #include "gtest/gtest.h" 22 | #include "smt.h" 23 | #include "utils.h" 24 | 25 | using namespace smt; 26 | using namespace std; 27 | 28 | namespace smt_tests { 29 | 30 | class DisjointSetTests 31 | : public ::testing::Test, 32 | public ::testing::WithParamInterface 33 | { 34 | protected: 35 | void SetUp() override 36 | { 37 | s = create_solver(GetParam()); 38 | bvsort = s->make_sort(BV, 8); 39 | x = s->make_symbol("x", bvsort); 40 | y = s->make_symbol("y", bvsort); 41 | z = s->make_symbol("z", bvsort); 42 | w = s->make_symbol("w", bvsort); 43 | } 44 | SmtSolver s; 45 | Sort bvsort; 46 | Term x, y, z, w; 47 | }; 48 | 49 | static bool disjoint_set_rank(const Term & t1, const Term & t2) 50 | { 51 | if (!t1->is_value() && !t2->is_value()) 52 | { 53 | return t1 < t2; 54 | } 55 | return !t1->is_value(); 56 | } 57 | 58 | TEST_P(DisjointSetTests, TestDisjointSet) 59 | { 60 | Term t1, t2, t3, t4; 61 | DisjointSet ds(disjoint_set_rank); 62 | 63 | ds.add(z, y); 64 | t1 = ds.find(y); 65 | t2 = ds.find(z); 66 | EXPECT_TRUE(t1 == t2); 67 | 68 | ds.add(x, y); 69 | t3 = ds.find(x); 70 | EXPECT_TRUE(t1 == t3); 71 | 72 | ds.add(w, z); 73 | t4 = ds.find(w); 74 | EXPECT_TRUE(t1 == t4); 75 | } 76 | 77 | INSTANTIATE_TEST_SUITE_P(ParameterizedSolverDisjointSetTests, 78 | DisjointSetTests, 79 | testing::ValuesIn(available_solver_configurations())); 80 | 81 | } // namespace smt_tests 82 | -------------------------------------------------------------------------------- /tests/test-generic-term.cpp: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file test-generic-term.cpp 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Yoni Zohar 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief 13 | ** 14 | ** 15 | **/ 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include "assert.h" 27 | 28 | // note: this file depends on the CMake build infrastructure 29 | // specifically defined macros 30 | // it cannot be compiled outside of the build 31 | #include "cvc5_factory.h" 32 | #include "generic_sort.h" 33 | #include "generic_term.h" 34 | #include "gtest/gtest.h" 35 | #include "smt.h" 36 | #include "test-utils.h" 37 | 38 | using namespace smt; 39 | using namespace std; 40 | 41 | int main() { 42 | cout << "Testing an integer constant" << endl; 43 | Sort int_sort = make_generic_sort(INT); 44 | GenericTerm one(int_sort, Op(), {}, "1"); 45 | GenericTerm one_prime(int_sort, Op(), {}, "1"); 46 | assert(one.get_id() == one_prime.get_id()); 47 | assert(one.hash() == one_prime.hash()); 48 | assert(!one.is_symbol()); 49 | assert(!one.is_param()); 50 | assert(!one.is_symbolic_const()); 51 | 52 | cout << "Testing an integer variable" << endl; 53 | GenericTerm x(int_sort, Op(), {}, "x", true); 54 | GenericTerm x_prime(int_sort, Op(), {}, "x", true); 55 | assert(x.get_id() == x_prime.get_id()); 56 | assert(x.hash() == x_prime.hash()); 57 | assert(x.is_symbol()); 58 | assert(!x.is_param()); 59 | assert(x.is_symbolic_const()); 60 | } 61 | -------------------------------------------------------------------------------- /tests/test-utils.cpp: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file test-utils.cpp 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief Convenience functions for testing. 13 | ** 14 | ** 15 | **/ 16 | 17 | #include "test-utils.h" 18 | 19 | using namespace std; 20 | using namespace smt; 21 | 22 | namespace smt_tests { 23 | 24 | UnorderedTermSet get_free_symbols(Term & t) 25 | { 26 | UnorderedTermSet free_symbols; 27 | TermVec to_visit({ t }); 28 | UnorderedTermSet visited; 29 | 30 | Term n; 31 | while (to_visit.size()) 32 | { 33 | n = to_visit.back(); 34 | to_visit.pop_back(); 35 | 36 | if (visited.find(n) == visited.end()) 37 | { 38 | visited.insert(n); 39 | for (auto nn : n) 40 | { 41 | to_visit.push_back(nn); 42 | } 43 | 44 | if (n->is_symbolic_const()) 45 | { 46 | free_symbols.insert(n); 47 | } 48 | } 49 | } 50 | 51 | return free_symbols; 52 | } 53 | 54 | } // namespace smt_tests 55 | -------------------------------------------------------------------------------- /tests/test-utils.h: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file test-utils.h 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief Convenience functions for testing. 13 | ** 14 | ** 15 | **/ 16 | 17 | #pragma once 18 | 19 | #include "smt.h" 20 | 21 | // macros for getting string value of another macro 22 | // i.e. STRFY(FOO) := "FOO" 23 | #define STRHELPER(A) #A 24 | #define STRFY(A) STRHELPER(A) 25 | 26 | namespace smt_tests { 27 | 28 | smt::UnorderedTermSet get_free_symbols(smt::Term & t); 29 | } 30 | -------------------------------------------------------------------------------- /tests/unit/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | macro(switch_add_unit_test name) 2 | add_executable(${name} "${PROJECT_SOURCE_DIR}/tests/unit/${name}.cpp") 3 | target_link_libraries(${name} gtest gtest_main) 4 | target_link_libraries(${name} test-deps) 5 | add_test(NAME ${name}_test COMMAND ${name}) 6 | endmacro() 7 | 8 | switch_add_unit_test(unit-arrays) 9 | switch_add_unit_test(unit-incremental) 10 | switch_add_unit_test(unit-op) 11 | switch_add_unit_test(unit-printing) 12 | switch_add_unit_test(unit-quantifiers) 13 | switch_add_unit_test(unit-reset-assertions) 14 | switch_add_unit_test(unit-solver-enums) 15 | switch_add_unit_test(unit-solving-interface) 16 | switch_add_unit_test(unit-sort) 17 | switch_add_unit_test(unit-sort-inference) 18 | switch_add_unit_test(unit-substitute) 19 | switch_add_unit_test(unit-symbol) 20 | switch_add_unit_test(unit-term) 21 | switch_add_unit_test(unit-term-hashtable) 22 | switch_add_unit_test(unit-term-id) 23 | switch_add_unit_test(unit-termiter) 24 | switch_add_unit_test(unit-transfer) 25 | switch_add_unit_test(unit-util) 26 | switch_add_unit_test(unit-walker) 27 | -------------------------------------------------------------------------------- /tests/unit/Makefile: -------------------------------------------------------------------------------- 1 | CXX=clang++ 2 | CXXFLAGS="" 3 | SOURCE=../../src/sort.cpp ../../src/ops.cpp ../../src/term.cpp 4 | 5 | all: unit-sort.out unit-exception.out unit-fun.out unit-util.out 6 | debug: all 7 | debug: DEBUG=-g -D_DEBUG 8 | 9 | main: sorts 10 | 11 | unit-sort.out: unit-sort.cpp 12 | $(CXX) $(CXXFLAGS) $(DEBUG) -std=c++17 -I../../include/ -I../../src/ unit-sort.cpp $(SOURCE) -o unit-sort.out 13 | 14 | unit-exception.out: unit-exceptions.cpp 15 | $(CXX) $(CXXFLAGS) $(DEBUG) -std=c++17 -I../../include/ -I../../src/ unit-exceptions.cpp $(SOURCE) -o unit-exception.out 16 | 17 | unit-fun.out: unit-fun.cpp 18 | $(CXX) $(CXXFLAGS) $(DEBUG) -std=c++17 -I../../include/ -I../../src/ unit-fun.cpp $(SOURCE) -o unit-fun.out 19 | 20 | unit-util.out: unit-util.cpp 21 | $(CXX) $(CXXFLAGS) $(DEBUG) -std=c++17 -I../../include/ -I../../src/ unit-util.cpp $(SOURCE) -o unit-util.out 22 | 23 | clean: 24 | rm -rf *.o *.out 25 | -------------------------------------------------------------------------------- /tests/unit/unit-exceptions.cpp: -------------------------------------------------------------------------------- 1 | #include "exceptions.h" 2 | 3 | #include "assert.h" 4 | 5 | int throw_exception() { throw SmtException("test"); } 6 | 7 | bool catch_exception() 8 | { 9 | try 10 | { 11 | throw_exception(); 12 | return false; 13 | } 14 | catch (SmtException& e) 15 | { 16 | return true; 17 | } 18 | catch (...) 19 | { 20 | return false; 21 | } 22 | } 23 | 24 | int main() { assert(catch_exception()); } 25 | -------------------------------------------------------------------------------- /tests/unit/unit-fun.cpp: -------------------------------------------------------------------------------- 1 | #include "assert.h" 2 | 3 | #include "fun.h" 4 | #include "ops.h" 5 | 6 | using namespace smt; 7 | using namespace std; 8 | 9 | int main() 10 | { 11 | Op f1(And); 12 | assert(f1.num_idx == 0); 13 | assert(f1.prim_op == And); 14 | Op f2(And); 15 | Op f3(Or); 16 | assert(f1 == f2); 17 | assert(f1 != f3); 18 | 19 | Op zext(Zero_Extend, 4); 20 | Op zext2(Zero_Extend, 4); 21 | Op zext3(Zero_Extend, 5); 22 | assert(zext == zext2); 23 | assert(zext != zext3); 24 | 25 | Op ext(Extract, 3, 0); 26 | Op ext2(Extract, 3, 0); 27 | Op ext3(Extract, 3, 1); 28 | assert(ext == ext2); 29 | assert(ext != ext3); 30 | } 31 | -------------------------------------------------------------------------------- /tests/unit/unit-solver-enums.cpp: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file unit-solver-enums.cpp 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief Unit tests for theory of arrays. 13 | ** 14 | ** 15 | **/ 16 | 17 | #include 18 | #include 19 | 20 | #include "available_solvers.h" 21 | #include "gtest/gtest.h" 22 | #include "smt.h" 23 | 24 | using namespace smt; 25 | using namespace std; 26 | 27 | namespace smt_tests { 28 | 29 | GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(UnitSolverEnumTests); 30 | class UnitSolverEnumTests : public ::testing::Test, 31 | public ::testing::WithParamInterface 32 | { 33 | protected: 34 | void SetUp() override { s = create_solver(GetParam()); } 35 | SmtSolver s; 36 | }; 37 | 38 | TEST_P(UnitSolverEnumTests, SolverEnumMatch) 39 | { 40 | SolverConfiguration sc = GetParam(); 41 | SolverEnum se = sc.solver_enum; 42 | ASSERT_EQ(se, s->get_solver_enum()); 43 | } 44 | 45 | INSTANTIATE_TEST_SUITE_P(ParameterizedUnitSolverEnum, 46 | UnitSolverEnumTests, 47 | testing::ValuesIn(available_solver_configurations())); 48 | 49 | } // namespace smt_tests 50 | -------------------------------------------------------------------------------- /tests/unit/unit-term.cpp: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file unit-term.cpp 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Makai Mann 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief Unit tests for terms. 13 | ** 14 | ** 15 | **/ 16 | 17 | #include 18 | #include 19 | 20 | #include "available_solvers.h" 21 | #include "gtest/gtest.h" 22 | #include "smt.h" 23 | 24 | using namespace smt; 25 | using namespace std; 26 | 27 | namespace smt_tests { 28 | 29 | GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(UnitTermTests); 30 | class UnitTermTests : public ::testing::Test, 31 | public testing::WithParamInterface 32 | { 33 | protected: 34 | void SetUp() override 35 | { 36 | s = create_solver(GetParam()); 37 | 38 | boolsort = s->make_sort(BOOL); 39 | bvsort = s->make_sort(BV, 4); 40 | funsort = s->make_sort(FUNCTION, SortVec{ bvsort, bvsort }); 41 | arrsort = s->make_sort(ARRAY, bvsort, bvsort); 42 | } 43 | SmtSolver s; 44 | Sort boolsort, bvsort, funsort, arrsort; 45 | }; 46 | 47 | TEST_P(UnitTermTests, FunOp) 48 | { 49 | Term x = s->make_symbol("x", bvsort); 50 | Term f = s->make_symbol("f", funsort); 51 | Term fx = s->make_term(Apply, f, x); 52 | 53 | ASSERT_TRUE(x->is_symbol()); 54 | ASSERT_TRUE(x->is_symbolic_const()); 55 | ASSERT_TRUE(f->is_symbol()); 56 | ASSERT_FALSE(f->is_symbolic_const()); 57 | } 58 | 59 | TEST_P(UnitTermTests, Array) 60 | { 61 | SolverConfiguration sc = GetParam(); 62 | Term arr = s->make_symbol("arr", arrsort); 63 | ASSERT_TRUE(arr->is_symbol()); 64 | ASSERT_TRUE(arr->is_symbolic_const()); 65 | } 66 | 67 | INSTANTIATE_TEST_SUITE_P(ParameterizedSolverUnitTerm, 68 | UnitTermTests, 69 | testing::ValuesIn(available_solver_configurations())); 70 | 71 | } // namespace smt_tests 72 | -------------------------------------------------------------------------------- /tests/yices2/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | macro(switch_add_yices2_test name) 2 | add_executable(${name} "${PROJECT_SOURCE_DIR}/tests/yices2/${name}.cpp") 3 | target_link_libraries(${name} gtest gtest_main) 4 | target_link_libraries(${name} test-deps) 5 | add_test(NAME ${name}_test COMMAND ${name}) 6 | endmacro() 7 | 8 | # these tests don't use GoogleTest yet 9 | # TODO move old tests to Google Test infrastructure 10 | 11 | switch_add_yices2_test(yices2-tests) 12 | switch_add_yices2_test(yices2-arrays) 13 | switch_add_yices2_test(yices2-arrays2) 14 | switch_add_yices2_test(yices2-incremental) 15 | switch_add_yices2_test(yices2-indexed-op-tests) 16 | switch_add_yices2_test(yices2-ext-ops) 17 | switch_add_yices2_test(yices2-ite-test) 18 | switch_add_yices2_test(yices2-neg-numbers) 19 | switch_add_yices2_test(yices2-polynomial) 20 | 21 | -------------------------------------------------------------------------------- /tests/yices2/yices2-array-models.cpp: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file yices2-array-models.cpp 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Amalee Wilson 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief 13 | ** 14 | ** 15 | **/ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | #include "assert.h" 22 | #include "smt.h" 23 | #include "yices2_factory.h" 24 | // after a full installation 25 | // #include "smt-switch/yices2_factory.h" 26 | // #include "smt-switch/smt.h" 27 | 28 | using namespace smt; 29 | using namespace std; 30 | 31 | int main() 32 | { 33 | SmtSolver s = Yices2SolverFactory::create(true); 34 | s->set_opt("produce-models", "true"); 35 | Sort bvsort32 = s->make_sort(BV, 32); 36 | Sort array32_32 = s->make_sort(ARRAY, bvsort32, bvsort32); 37 | Term x0 = s->make_symbol("x0", bvsort32); 38 | Term x1 = s->make_symbol("x1", bvsort32); 39 | Term y = s->make_symbol("y", bvsort32); 40 | Term arr = s->make_symbol("arr", array32_32); 41 | 42 | Term constraint = s->make_term(Equal, s->make_term(Select, arr, x0), x1); 43 | constraint = s->make_term( 44 | And, constraint, s->make_term(Equal, s->make_term(Select, arr, x1), y)); 45 | constraint = s->make_term(And, constraint, s->make_term(Distinct, x1, y)); 46 | s->assert_formula(constraint); 47 | Result r = s->check_sat(); 48 | 49 | assert(r.is_sat()); 50 | 51 | Term arr_val = s->get_value(arr); 52 | 53 | cout << arr_val << endl; 54 | 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /tests/yices2/yices2-arrays.cpp: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file yices2-arrays.cpp 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Amalee Wilson 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief 13 | ** 14 | ** 15 | **/ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | #include "assert.h" 22 | #include "smt.h" 23 | #include "yices2_factory.h" 24 | // after a full installation 25 | // #include "smt-switch/yices2_factory.h" 26 | // #include "smt-switch/smt.h" 27 | 28 | using namespace smt; 29 | using namespace std; 30 | 31 | int main() 32 | { 33 | SmtSolver s = Yices2SolverFactory::create(true); 34 | s->set_opt("produce-models", "true"); 35 | Sort bvsort32 = s->make_sort(BV, 32); 36 | Sort array32_32 = s->make_sort(ARRAY, bvsort32, bvsort32); 37 | Term x = s->make_symbol("x", bvsort32); 38 | Term y = s->make_symbol("y", bvsort32); 39 | Term arr = s->make_symbol("arr", array32_32); 40 | 41 | cout << "Sorts:" << endl; 42 | cout << "\tbvsort32 : " << bvsort32 << endl; 43 | cout << "\tarray32_32 : " << array32_32 << endl; 44 | s->assert_formula( 45 | s->make_term(Not, 46 | s->make_term(Implies, 47 | s->make_term(Equal, x, y), 48 | s->make_term(Equal, 49 | s->make_term(Select, arr, x), 50 | s->make_term(Select, arr, y))))); 51 | assert(!s->check_sat().is_sat()); 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /tests/yices2/yices2-arrays2.cpp: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file yices2-arrays2.cpp 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Amalee Wilson 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief 13 | ** 14 | ** 15 | **/ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | #include "assert.h" 22 | #include "smt.h" 23 | #include "yices2_factory.h" 24 | // after a full installation 25 | // #include "smt-switch/yices2_factory.h" 26 | // #include "smt-switch/smt.h" 27 | 28 | using namespace smt; 29 | using namespace std; 30 | 31 | int main() 32 | { 33 | SmtSolver s = Yices2SolverFactory::create(true); 34 | s->set_opt("produce-models", "true"); 35 | Sort bvsort4 = s->make_sort(BV, 4); 36 | Sort bvsort8 = s->make_sort(BV, 8); 37 | Sort array4_8 = s->make_sort(ARRAY, bvsort4, bvsort8); 38 | Term x = s->make_symbol("x", bvsort4); 39 | Term elem = s->make_symbol("elem", bvsort8); 40 | Term mem = s->make_symbol("mem", array4_8); 41 | 42 | Term new_array = s->make_term(Store, mem, x, elem); 43 | // assert(new_array->get_op() == Store); 44 | 45 | // for (auto c : new_array) 46 | // { 47 | // cout << c << endl; 48 | // } 49 | 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /tests/yices2/yices2-indexed-op-tests.cpp: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file yices2-indexed-op-tests.cpp 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Amalee Wilson 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief 13 | ** 14 | ** 15 | **/ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | #include "assert.h" 22 | #include "smt.h" 23 | #include "yices2_factory.h" 24 | // after a full installation 25 | // #include "smt-switch/yices2_factory.h" 26 | // #include "smt-switch/smt.h" 27 | 28 | using namespace smt; 29 | using namespace std; 30 | 31 | int main() 32 | { 33 | SmtSolver s = Yices2SolverFactory::create(true); 34 | s->set_opt("produce-models", "true"); 35 | Sort bvsort9 = s->make_sort(BV, 9); 36 | Term x = s->make_symbol("x", bvsort9); 37 | Term y = s->make_symbol("y", bvsort9); 38 | Term onebit = s->make_symbol("onebit", s->make_sort(BV, 1)); 39 | 40 | Term unnecessary_rotation = s->make_term(Op(Rotate_Right, 1), onebit); 41 | 42 | Op ext74 = Op(Extract, 7, 4); 43 | Term x_upper = s->make_term(ext74, x); 44 | 45 | Op op = x_upper->get_op(); 46 | cout << "Op: " << op << endl; 47 | 48 | Term y_ror = s->make_term(Op(Rotate_Right, 2), y); 49 | Term y_rol = s->make_term(Op(Rotate_Left, 2), y); 50 | 51 | // assert(y_ror->to_string() == "((_ rotate_right 2) y)"); 52 | // assert(y_rol->to_string() == "((_ rotate_left 2) y)"); 53 | 54 | s->assert_formula(s->make_term(Equal, y_ror, y_rol)); 55 | s->assert_formula(s->make_term(Distinct, y, s->make_term(0, bvsort9))); 56 | s->assert_formula(s->make_term( 57 | Equal, x, s->make_term(Op(Repeat, 9), unnecessary_rotation))); 58 | 59 | Result r = s->check_sat(); 60 | assert(r.is_sat()); 61 | 62 | Term xc = s->get_value(x); 63 | Term x_upperc = s->get_value(x_upper); 64 | Term yc = s->get_value(y); 65 | 66 | cout << "Results:" << endl; 67 | cout << x << ": " << xc->to_int() << endl; 68 | cout << x_upper << ": " << x_upperc->to_int() << endl; 69 | cout << y << ": " << yc->to_int() << endl; 70 | return 0; 71 | } 72 | -------------------------------------------------------------------------------- /tests/yices2/yices2-ite-test.cpp: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file yices2-ite-test.cpp 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Amalee Wilson 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief 13 | ** 14 | ** 15 | **/ 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | #include "assert.h" 22 | #include "smt.h" 23 | #include "yices2_factory.h" 24 | // after a full installation 25 | // #include "smt-switch/boolector_factory.h" 26 | // #include "smt-switch/smt.h" 27 | 28 | using namespace smt; 29 | using namespace std; 30 | 31 | int main() 32 | { 33 | SmtSolver s = Yices2SolverFactory::create(true); 34 | s->set_logic("QF_ABV"); 35 | s->set_opt("produce-models", "true"); 36 | Sort boolsort = s->make_sort(BOOL); 37 | Term a = s->make_symbol("a", boolsort); 38 | Term b = s->make_symbol("b", boolsort); 39 | Term c = s->make_symbol("c", boolsort); 40 | 41 | Sort intsort = s->make_sort(INT); 42 | Term x = s->make_symbol("x", intsort); 43 | Term y = s->make_symbol("y", intsort); 44 | 45 | Term ite_bool = s->make_term(Ite, a, b, c); 46 | Term ite_axiom = s->make_term( 47 | And, 48 | s->make_term(Implies, a, s->make_term(Equal, ite_bool, b)), 49 | s->make_term( 50 | Implies, s->make_term(Not, a), s->make_term(Equal, ite_bool, c))); 51 | 52 | s->push(); 53 | s->assert_formula(s->make_term(Not, ite_axiom)); 54 | Result r = s->check_sat(); 55 | assert(r.is_unsat()); 56 | s->pop(); 57 | 58 | r = s->check_sat(); 59 | assert(r.is_sat()); 60 | 61 | Term ite_int = s->make_term(Ite, a, x, y); 62 | Term ite_axiom_int = s->make_term( 63 | And, 64 | s->make_term(Implies, a, s->make_term(Equal, ite_int, x)), 65 | s->make_term( 66 | Implies, s->make_term(Not, a), s->make_term(Equal, ite_int, y))); 67 | 68 | s->push(); 69 | s->assert_formula(s->make_term(Not, ite_axiom_int)); 70 | r = s->check_sat(); 71 | assert(r.is_unsat()); 72 | s->pop(); 73 | 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /tests/z3/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | macro(switch_add_z3_test name) 2 | add_executable(${name} "${PROJECT_SOURCE_DIR}/tests/z3/${name}.cpp") 3 | target_link_libraries(${name} gtest gtest_main) 4 | target_link_libraries(${name} test-deps) 5 | add_test(NAME ${name}_test COMMAND ${name}) 6 | endmacro() 7 | 8 | # these tests don't use GoogleTest yet 9 | # TODO move old tests to Google Test infrastructure 10 | switch_add_z3_test(z3_test) 11 | switch_add_z3_test(z3_full) 12 | -------------------------------------------------------------------------------- /tests/z3/z3_full.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "assert.h" 4 | #include "smt.h" 5 | #include "z3_factory.h" 6 | #include "z3_sort.h" 7 | 8 | using namespace smt; 9 | using namespace std; 10 | // using namespace z3; 11 | 12 | int main() 13 | { 14 | SmtSolver s = Z3SolverFactory::create(false); 15 | 16 | cout << ":)" << endl; 17 | 18 | Sort intsort = s->make_sort(INT); 19 | Term x = s->make_symbol("x", intsort); 20 | Term y = s->make_symbol("y", intsort); 21 | Term val1 = s->make_term(1, intsort); 22 | Term val3 = s->make_term(3, intsort); 23 | 24 | cout << x << endl << y << endl << val1 << endl << val3 << endl; 25 | 26 | Term xge = s->make_term(Op(Ge), x, val1); 27 | Term xplus = s->make_term(Op(Plus), x, val3); 28 | Term ylt = s->make_term(Op(Lt), y, xplus); 29 | 30 | cout << xge << endl << xplus << endl << ylt << endl; 31 | 32 | s->assert_formula(xge); 33 | s->assert_formula(ylt); 34 | 35 | Result r = s->check_sat(); 36 | cout << r << endl; 37 | 38 | 39 | Term xlt = s->make_term(Op(Lt), x, val1); 40 | s->assert_formula(xlt); 41 | r = s->check_sat(); 42 | cout << r << endl; 43 | 44 | Sort bvsort = s->make_sort(BV, 7); 45 | cout << "bv val " << s->make_term("0000010", bvsort, 2) << endl; 46 | cout << "bv val " << s->make_term("0F", bvsort, 16) << endl; 47 | 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /yices2/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(smt-switch-yices2 "${SMT_SWITCH_LIB_TYPE}" 2 | "${CMAKE_CURRENT_SOURCE_DIR}/src/yices2_extensions.cpp" 3 | "${CMAKE_CURRENT_SOURCE_DIR}/src/yices2_factory.cpp" 4 | "${CMAKE_CURRENT_SOURCE_DIR}/src/yices2_solver.cpp" 5 | "${CMAKE_CURRENT_SOURCE_DIR}/src/yices2_sort.cpp" 6 | "${CMAKE_CURRENT_SOURCE_DIR}/src/yices2_term.cpp" 7 | ) 8 | 9 | target_include_directories (smt-switch-yices2 PUBLIC "${PROJECT_SOURCE_DIR}/include") 10 | target_include_directories (smt-switch-yices2 PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include") 11 | target_include_directories (smt-switch-yices2 PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/yices2/include") 12 | target_include_directories (smt-switch-yices2 PUBLIC "${YICES2_HOME}/src/include") 13 | target_include_directories (smt-switch-yices2 PUBLIC "${GMP_INCLUDE_DIR}") 14 | target_link_libraries(smt-switch-yices2 "${GMP_LIBRARIES}") 15 | target_link_libraries(smt-switch-yices2 "${YICES2_HOME}/build/lib/libyices.a") 16 | target_link_libraries(smt-switch-yices2 smt-switch) 17 | target_link_libraries(smt-switch-yices2 pthread) 18 | 19 | 20 | if (SMT_SWITCH_LIB_TYPE STREQUAL STATIC) 21 | # we want the static library to include the yices2 source 22 | # we need to unpack and repack the libraries 23 | add_custom_target(repack-yices2-static-lib 24 | ALL 25 | COMMAND 26 | mkdir smt-switch-yices2 && cd smt-switch-yices2 && ar -x "../$" && cd ../ && 27 | mkdir yices2 && cd yices2 && ar -x "${YICES2_HOME}/build/lib/libyices.a" && cd ../ && 28 | ar -qc "$" ./yices2/*.o ./smt-switch-yices2/*.o && 29 | # now clean up 30 | rm -rf smt-switch-yices2 yices2 31 | DEPENDS 32 | smt-switch-yices2 33 | ) 34 | endif() 35 | 36 | install(TARGETS smt-switch-yices2 DESTINATION lib) 37 | # install headers -- for expert use only 38 | install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/" 39 | DESTINATION include/smt-switch 40 | FILES_MATCHING PATTERN "*.h") 41 | -------------------------------------------------------------------------------- /yices2/include/yices2_extensions.h: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file yices2_extensions.h 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Amalee Wilson 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief Helper functions for certain operations in the Yices C API 13 | ** 14 | ** 15 | **/ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include "yices.h" 21 | 22 | namespace smt { 23 | 24 | term_t ext_yices_select(term_t arr, term_t idx); 25 | term_t ext_yices_store(term_t arr, term_t idx, term_t nu); 26 | term_t ext_yices_make_bv_number(const char * val, size_t size, int base); 27 | term_t ext_yices_bvcomp(term_t t0, term_t t1); 28 | 29 | } // namespace smt 30 | 31 | -------------------------------------------------------------------------------- /yices2/include/yices2_sort.h: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file yices2_sort.h 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Amalee Wilson 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief Yices2 implementation of AbsSort 13 | ** 14 | ** 15 | **/ 16 | 17 | #pragma once 18 | 19 | #include "exceptions.h" 20 | #include "sort.h" 21 | #include "utils.h" 22 | 23 | #include "yices.h" 24 | 25 | namespace smt { 26 | 27 | // forward declaration 28 | class Yices2Solver; 29 | 30 | class Yices2Sort : public AbsSort 31 | { 32 | public: 33 | // Non-functions 34 | Yices2Sort(type_t y_type) : type(y_type), is_function(false){}; 35 | 36 | // Functions 37 | Yices2Sort(type_t y_type, bool is_fun) : type(y_type), is_function(is_fun){}; 38 | 39 | ~Yices2Sort() = default; 40 | std::size_t hash() const override; 41 | uint64_t get_width() const override; 42 | Sort get_indexsort() const override; 43 | Sort get_elemsort() const override; 44 | SortVec get_domain_sorts() const override; 45 | Sort get_codomain_sort() const override; 46 | std::string get_uninterpreted_name() const override; 47 | size_t get_arity() const override; 48 | SortVec get_uninterpreted_param_sorts() const override; 49 | Datatype get_datatype() const override; 50 | bool compare(const Sort & s) const override; 51 | SortKind get_sort_kind() const override; 52 | type_t get_ytype() { return type; }; 53 | 54 | protected: 55 | type_t type; 56 | bool is_function; 57 | 58 | friend class Yices2Solver; 59 | }; 60 | 61 | } // namespace smt 62 | 63 | -------------------------------------------------------------------------------- /yices2/src/yices2_factory.cpp: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file yices2_factory.cpp 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Amalee Wilson 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief Factory for creating a Yices2 SmtSolver 13 | ** 14 | ** 15 | **/ 16 | 17 | #include "yices2_factory.h" 18 | 19 | #include "yices2_solver.h" 20 | 21 | #include "logging_solver.h" 22 | 23 | namespace smt { 24 | 25 | bool initialized = false; 26 | 27 | /* Yices2SolverFactory implementation with logging */ 28 | SmtSolver Yices2SolverFactory::create(bool logging) 29 | { 30 | // Must initialize only once, even if planning to 31 | // create multiple contexts. 32 | // Different instances of the solver will have 33 | // different contexts. Yices2 must be configured 34 | // with --enable-thread-safety in order for 35 | // multiple threads to manipulate different contexts. 36 | // https://github.com/SRI-CSL/yices2#support-for-thread-safety 37 | if (!initialized) 38 | { 39 | yices_init(); 40 | initialized = true; 41 | } 42 | 43 | SmtSolver solver = std::make_shared(); 44 | if (logging) 45 | { 46 | solver = std::make_shared(solver); 47 | } 48 | return solver; 49 | } 50 | /* end Yices2SolverFactory logging implementation */ 51 | 52 | } // namespace smt 53 | -------------------------------------------------------------------------------- /z3/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Find Z3 installation 2 | if(DEFINED Z3_INSTALL_DIR) 3 | list(PREPEND CMAKE_PREFIX_PATH "${Z3_INSTALL_DIR}") 4 | endif() 5 | find_package(Z3 REQUIRED) 6 | 7 | # Variables needed in setup.py 8 | # TODO: move all compilation commands into CMake 9 | get_target_property(Z3_CONFIGURATIONS z3::libz3 IMPORTED_CONFIGURATIONS) 10 | list(GET Z3_CONFIGURATIONS 0 Z3_DEFAULT_CONFIGURATION) 11 | get_target_property(Z3_LIBRARY_LOCATION z3::libz3 IMPORTED_LOCATION_${Z3_DEFAULT_CONFIGURATION}) 12 | set(Z3_LIBRARY_LOCATION "${Z3_LIBRARY_LOCATION}" PARENT_SCOPE) 13 | 14 | add_library(smt-switch-z3 "${SMT_SWITCH_LIB_TYPE}" 15 | "${CMAKE_CURRENT_SOURCE_DIR}/src/z3_datatype.cpp" 16 | "${CMAKE_CURRENT_SOURCE_DIR}/src/z3_factory.cpp" 17 | "${CMAKE_CURRENT_SOURCE_DIR}/src/z3_solver.cpp" 18 | "${CMAKE_CURRENT_SOURCE_DIR}/src/z3_sort.cpp" 19 | "${CMAKE_CURRENT_SOURCE_DIR}/src/z3_term.cpp" 20 | ) 21 | 22 | target_include_directories(smt-switch-z3 PUBLIC "${PROJECT_SOURCE_DIR}/include") 23 | target_include_directories(smt-switch-z3 PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include") 24 | target_include_directories(smt-switch-z3 PRIVATE ${GMP_INCLUDE_DIR}) 25 | target_link_libraries(smt-switch-z3 PUBLIC smt-switch) 26 | target_link_libraries(smt-switch-z3 PUBLIC z3::libz3) 27 | target_link_libraries(smt-switch-z3 PRIVATE ${GMP_LIBRARIES}) 28 | target_link_libraries(smt-switch-z3 PRIVATE ${GMPXX_LIBRARIES}) 29 | 30 | install(TARGETS smt-switch-z3 DESTINATION lib) 31 | # install headers -- for expert use only 32 | install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/" 33 | DESTINATION include/smt-switch 34 | FILES_MATCHING PATTERN "*.h") 35 | -------------------------------------------------------------------------------- /z3/include/z3_datatype.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "z3++.h" 3 | #include "datatype.h" 4 | #include "exceptions.h" 5 | 6 | namespace smt { 7 | 8 | class Z3DatatypeDecl : public AbsDatatypeDecl 9 | { 10 | public: 11 | Z3DatatypeDecl(std::string name) : name(name){}; 12 | 13 | protected: 14 | friend class Z3Solver; 15 | std::string name; 16 | std::vector consvec {}; 17 | }; 18 | 19 | class Z3DatatypeConstructorDecl : public AbsDatatypeConstructorDecl 20 | { 21 | public: 22 | Z3DatatypeConstructorDecl(z3::context & c, std::string name) 23 | : c(c), constructorname(name){}; 24 | bool compare(const DatatypeConstructorDecl &) const override; 25 | 26 | protected: 27 | friend class Z3Solver; 28 | 29 | z3::context & c; 30 | std::string constructorname, datatypename; 31 | std::vector fieldnames {}; 32 | std::vector sorts {}; 33 | }; 34 | 35 | class Z3Datatype : public AbsDatatype 36 | { 37 | public: 38 | Z3Datatype(z3::context & c, z3::sort s) : c(c), datatype(s) {} 39 | std::string get_name() const override { return datatype.name().str(); } 40 | int get_num_constructors() const override 41 | { 42 | return Z3_get_datatype_sort_num_constructors(c, datatype); 43 | } 44 | int get_num_selectors(std::string name) const override 45 | { 46 | for (size_t i = 0; i < get_num_constructors(); i++) 47 | { 48 | z3::func_decl cons{ c, Z3_get_datatype_sort_constructor(c, datatype, i) }; 49 | if (cons.name().str() == name) return cons.arity(); 50 | } 51 | throw InternalSolverException(datatype.name().str() + "." + name 52 | + " not found"); 53 | } 54 | 55 | private: 56 | z3::context & c; 57 | 58 | z3::sort datatype; 59 | friend class Z3Solver; 60 | }; 61 | 62 | } // namespace smt 63 | -------------------------------------------------------------------------------- /z3/include/z3_sort.h: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file z3_sort.h 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Lindsey Stuntz 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief Z3 implementation of AbsSort 13 | ** 14 | ** 15 | **/ 16 | 17 | #pragma once 18 | 19 | #include "exceptions.h" 20 | #include "sort.h" 21 | #include "utils.h" 22 | #include "z3++.h" 23 | 24 | using namespace z3; 25 | namespace smt { 26 | 27 | // forward declaration 28 | class Z3Solver; 29 | 30 | class Z3Sort : public AbsSort 31 | { 32 | public: 33 | // Non-functions 34 | Z3Sort(z3::sort z3sort, context & c) 35 | : type(z3sort), is_function(false), z_func(c) 36 | { 37 | ctx = &c; 38 | }; 39 | 40 | // Functions 41 | Z3Sort(func_decl zfunc, context & c) 42 | : type(c), is_function(true), z_func(zfunc){}; 43 | 44 | ~Z3Sort() = default; 45 | std::size_t hash() const override; 46 | uint64_t get_width() const override; 47 | Sort get_indexsort() const override; 48 | Sort get_elemsort() const override; 49 | SortVec get_domain_sorts() const override; 50 | Sort get_codomain_sort() const override; 51 | std::string get_uninterpreted_name() const override; 52 | size_t get_arity() const override; 53 | SortVec get_uninterpreted_param_sorts() const override; 54 | Datatype get_datatype() const override; 55 | bool compare(const Sort &) const override; 56 | SortKind get_sort_kind() const override; 57 | 58 | // getters for solver-specific objects (EXPERTS only) 59 | z3::sort get_z3_type() 60 | { 61 | if (is_function) 62 | { 63 | throw IncorrectUsageException("Cannot get Z3 type from function term."); 64 | } 65 | return type; 66 | } 67 | 68 | protected: 69 | z3::sort type; 70 | func_decl z_func; 71 | bool is_function; 72 | context * ctx; 73 | 74 | friend class Z3Solver; 75 | }; 76 | 77 | } // namespace smt 78 | -------------------------------------------------------------------------------- /z3/src/z3_datatype.cpp: -------------------------------------------------------------------------------- 1 | #include "z3_datatype.h" 2 | 3 | namespace z3 { 4 | const bool operator==(const z3::sort & lhs, const z3::sort & rhs) 5 | { 6 | return z3::eq(lhs, rhs); 7 | } 8 | const bool operator==(const z3::symbol & lhs, const z3::symbol & rhs) 9 | { 10 | return lhs.str() == rhs.str(); 11 | } 12 | } // namespace z3 13 | 14 | namespace smt { 15 | bool Z3DatatypeConstructorDecl::compare( 16 | const DatatypeConstructorDecl & other) const 17 | { 18 | auto cast = std::static_pointer_cast(other); 19 | return std::tie(constructorname, fieldnames, sorts) 20 | == std::tie(cast->constructorname, cast->fieldnames, cast->sorts); 21 | } 22 | 23 | } // namespace smt 24 | -------------------------------------------------------------------------------- /z3/src/z3_factory.cpp: -------------------------------------------------------------------------------- 1 | /********************* */ 2 | /*! \file z3_factory.cpp 3 | ** \verbatim 4 | ** Top contributors (to current version): 5 | ** Lindsey Stuntz 6 | ** This file is part of the smt-switch project. 7 | ** Copyright (c) 2020 by the authors listed in the file AUTHORS 8 | ** in the top-level source directory) and their institutional affiliations. 9 | ** All rights reserved. See the file LICENSE in the top-level source 10 | ** directory for licensing information.\endverbatim 11 | ** 12 | ** \brief Factory for creating a Z3 SmtSolver 13 | ** 14 | ** 15 | **/ 16 | 17 | #include "z3_factory.h" 18 | 19 | #include "logging_solver.h" 20 | #include "z3_solver.h" 21 | 22 | namespace smt { 23 | 24 | /* Z3SolverFactory implementation with logging */ 25 | SmtSolver Z3SolverFactory::create(bool logging) 26 | { 27 | SmtSolver solver = std::make_shared(); 28 | if (logging) 29 | { 30 | solver = std::make_shared(solver); 31 | } 32 | return solver; 33 | } 34 | /* end Z3SolverFactory implementation */ 35 | 36 | } // namespace smt --------------------------------------------------------------------------------