├── __init__.py ├── bindings ├── python │ ├── metasmt │ │ ├── __init__.py │ │ ├── smt2.py │ │ ├── operators.py │ │ └── support.py │ ├── generate_ctest_script.awk │ ├── pymetaSMT.in │ ├── python.cpp │ ├── python_config.hxx.in │ ├── examples │ │ ├── rect.py │ │ ├── prime_test.py │ │ ├── graph_coloring.py │ │ └── rect_qf_bv.py │ └── tests │ │ ├── __main__.py │ │ ├── support.py │ │ └── smt2.py └── CMakeLists.txt ├── tests ├── boost_test.cpp ├── direct_CVC4.cpp ├── direct_STP.cpp ├── graph_STP.cpp ├── direct_CUDD.cpp ├── graph_CUDD.cpp ├── graph_SWORD2.cpp ├── direct_BitBlast_CUDD.cpp ├── direct_ExprSolver_SMT2.cpp ├── graph_Z3.cpp ├── direct_PicoSAT.cpp ├── direct_ExprSolver_Z3.cpp ├── direct_Lingeling.cpp ├── graph_BitBlast_CUDD.cpp ├── direct_ExprSolver_Boolector.cpp ├── direct_Aiger_MiniSAT.cpp ├── direct_Aiger_PicoSAT.cpp ├── direct_SWORD2.cpp ├── graph_Aiger_MiniSAT.cpp ├── graph_SMT2.cpp ├── graph_MiniSAT.cpp ├── graph_Lingeling.cpp ├── direct_CW_MiniSat.cpp ├── direct_CW_PicoSAT.cpp ├── direct_CW_Glucoser.cpp ├── direct_CW_PrecoSAT.cpp ├── direct_CW_Plingeling.cpp ├── search_tests.awk ├── direct_MiniSAT.cpp ├── test_stack.cpp ├── direct_SMT2.cpp ├── direct_Z3.cpp ├── direct_Threaded_Z3.cpp ├── graph_Boolector.cpp ├── SMT2Parser_SMT2.cpp ├── SMT2Parser_STP.cpp ├── SMT2Parser_Boolector.cpp ├── SMT2Parser_Z3_Backend.cpp ├── test_group.cpp ├── direct_Boolector.cpp ├── direct_Threaded_SWORD.cpp ├── test_SAT.cpp ├── test_graph_copy.cpp ├── test_expression.cpp ├── test_evaluator.cpp ├── test_lazy.cpp ├── test_random_bits.cpp ├── test_aig.cpp └── test_QF_UF.cpp ├── cmake ├── metaSMT.cmake.in ├── metaSMT.pc.in ├── metaSMT.makefile.in ├── metaSMTConfig.cmake.in ├── default_compliler_flags.cmake ├── get_git_version.cmake ├── library_rpath.cmake └── build_type.cmake ├── toolbox ├── simple │ └── main.cpp ├── n-queens │ └── CMakeLists.txt ├── pretty-print │ ├── CMakeLists.txt │ └── pretty-print.cpp ├── smt2Input_evaluator │ ├── options.hpp │ ├── SMT2_main.cpp │ ├── Z3_Backend_main.cpp │ ├── STP_main.cpp │ ├── SWORD_Backend_main.cpp │ ├── Boolector_main.cpp │ ├── MiniSAT_main.cpp │ ├── PicoSAT_main.cpp │ ├── CMakeLists.txt │ └── main.cpp ├── factorization │ ├── CMakeLists.txt │ └── factorization.cpp ├── metaSMT-cnf-solver │ ├── CMakeLists.txt │ └── main.cpp ├── boolector_facorization │ └── CMakeLists.txt ├── guess_mastermind │ └── CMakeLists.txt ├── metaSMT-server │ ├── test-commands │ ├── CMakeLists.txt │ ├── main.cpp │ ├── Connection.hpp │ ├── SolverProcess.hpp │ ├── create_solver.hpp │ └── SolverProcess.cpp ├── sortnets │ ├── z3.cpp │ ├── stp.cpp │ ├── cvc4.cpp │ ├── sword.cpp │ ├── smt2.cpp │ ├── minisat.cpp │ ├── boolector.cpp │ ├── picosat.cpp │ ├── unsorted_6.txt │ ├── Main.hpp │ ├── unsorted_7.txt │ ├── CMakeLists.txt │ ├── SortNetSynth.hpp │ └── Level.hpp ├── sudoku │ ├── sudoku_examples.txt │ └── CMakeLists.txt ├── README └── CMakeLists.txt ├── src ├── metaSMT │ ├── support │ │ ├── optimization.hpp │ │ ├── default_visitation_unrolling_limit.hpp │ │ ├── cardinality.hpp │ │ ├── boost_mpl_map60.hpp │ │ ├── boost_mpl_vector60.hpp │ │ ├── DefaultSymbolTable.hpp │ │ ├── string_concat.hpp │ │ ├── enable_warnings.hpp │ │ ├── protofy.hpp │ │ ├── index │ │ │ └── Logics.hpp │ │ ├── optimization │ │ │ ├── detail.hpp │ │ │ ├── minimize.hpp │ │ │ └── maximize.hpp │ │ ├── find_executable.hpp │ │ ├── SimpleSymbolTable.hpp │ │ ├── cardinality │ │ │ ├── object.hpp │ │ │ └── deprecated_api.hpp │ │ ├── parser │ │ │ ├── UTreeToString.hpp │ │ │ ├── has_attribute.hpp │ │ │ └── get_index.hpp │ │ ├── GoTmp.hpp │ │ ├── disable_warnings.hpp │ │ ├── evaluate_string.hpp │ │ ├── SMT_Graph.hpp │ │ ├── SMT2_result_grammar.hpp │ │ ├── Options.hpp │ │ └── dot_SMT_Graph.hpp │ ├── impl │ │ └── _var_id.hpp │ ├── types │ │ ├── Types.hpp │ │ ├── Evaluator.hpp │ │ ├── Boolean.hpp │ │ ├── BitVector.hpp │ │ └── Array.hpp │ ├── expression │ │ └── print_expression.hpp │ ├── Features.hpp │ ├── API │ │ ├── BoolEvaluator.hpp │ │ ├── AddClause.hpp │ │ ├── Evaluator.hpp │ │ ├── Assertion.hpp │ │ ├── Assumption.hpp │ │ ├── Simplify.hpp │ │ ├── Options.hpp │ │ ├── Comment.hpp │ │ └── SymbolTable.hpp │ ├── tags │ │ ├── attribute.hpp │ │ ├── Cardinality.hpp │ │ ├── QF_UF.hpp │ │ ├── Logics.hpp │ │ ├── SAT.hpp │ │ ├── Array.hpp │ │ └── Logic.hpp │ ├── transform │ │ ├── rewrite.hpp │ │ └── satClause.hpp │ ├── Debug_Context.hpp │ ├── UnpackFuture_Context.hpp │ ├── concurrent │ │ ├── Threaded_Worker.hpp │ │ └── concurrent_queue.hpp │ ├── Instantiate.hpp │ ├── io │ │ ├── SMT2_ResultParser.hpp │ │ └── DimacsParser.hpp │ ├── backend │ │ └── SAT │ │ │ └── model_parser.hpp │ └── frontend │ │ └── SAT.hpp ├── CMakeLists.txt └── lib │ ├── simple_symbol_table.cpp │ ├── _var_id.cpp │ ├── CMakeLists.txt │ ├── expression_generator.cpp │ └── doxy.cpp ├── .gitignore ├── .travis.yml ├── doc └── CMakeLists.txt ├── ChangeLog ├── LICENSE └── TODO /__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /bindings/python/metasmt/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /tests/boost_test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | -------------------------------------------------------------------------------- /cmake/metaSMT.cmake.in: -------------------------------------------------------------------------------- 1 | set(metaSMT_INCLUDE_DIR @PROJECT_SOURCE_DIR@/src;@metaSMT_INCLUDES@) 2 | -------------------------------------------------------------------------------- /toolbox/simple/main.cpp: -------------------------------------------------------------------------------- 1 | int main(int argc, const char *argv[]) 2 | { 3 | return 0; 4 | } 5 | -------------------------------------------------------------------------------- /cmake/metaSMT.pc.in: -------------------------------------------------------------------------------- 1 | Name: metaSMT 2 | Description: SMT Solver library 3 | Cflags: -I@metaSMT_INCLUDES@ 4 | Libs: @metaSMT_MLIBS@ 5 | 6 | -------------------------------------------------------------------------------- /src/metaSMT/support/optimization.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "optimization/minimize.hpp" 4 | #include "optimization/maximize.hpp" 5 | -------------------------------------------------------------------------------- /toolbox/n-queens/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_tool_executable( n-queens 2 | SOURCES 3 | n-queens.cpp 4 | REQUIRES 5 | Boolector_FOUND 6 | ) 7 | 8 | -------------------------------------------------------------------------------- /cmake/metaSMT.makefile.in: -------------------------------------------------------------------------------- 1 | metaSMT_INCLUDES := @metaSMT_MINCLUDES@ 2 | metaSMT_LIBRARIES := @metaSMT_MLIBS@ 3 | metaSMT_CXXFLAGS := @metaSMT_CXXFLAGS@ 4 | -------------------------------------------------------------------------------- /toolbox/pretty-print/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_tool_executable( pretty-print 2 | SOURCES 3 | pretty-print.cpp 4 | REQUIRES 5 | Z3_FOUND 6 | ) 7 | 8 | -------------------------------------------------------------------------------- /toolbox/smt2Input_evaluator/options.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | typedef std::map OptionMap; 5 | -------------------------------------------------------------------------------- /src/metaSMT/impl/_var_id.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace metaSMT { 4 | namespace impl { 5 | unsigned new_var_id(); 6 | } /* impl */ 7 | } /* metaSMT */ 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.swp 3 | build* 4 | root* 5 | cmake/*.Config.cmake 6 | deps 7 | dependencies 8 | *.aux 9 | *.bbl 10 | *.blg 11 | *.d 12 | *.log 13 | *.tdo 14 | *.pyc 15 | -------------------------------------------------------------------------------- /toolbox/factorization/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_tool_executable( factorization 2 | SOURCES 3 | factorization.cpp 4 | REQUIRES 5 | Z3_FOUND 6 | SWORD_FOUND 7 | ) 8 | 9 | -------------------------------------------------------------------------------- /bindings/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if( Boost_PYTHON_FOUND ) 2 | add_subdirectory(python) 3 | else () 4 | message(STATUS "skipping python bindings because Boost Python is unavailable") 5 | endif() 6 | -------------------------------------------------------------------------------- /toolbox/metaSMT-cnf-solver/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_tool_executable( metaSMT-cnf-solver 2 | SOURCES 3 | main.cpp 4 | REQUIRES 5 | PicoSAT_FOUND 6 | Boost_ASIO_LIBRARY 7 | ) 8 | 9 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | add_subdirectory(lib) 3 | install(DIRECTORY metaSMT 4 | DESTINATION include/ 5 | FILES_MATCHING PATTERN "*.hpp" 6 | ) 7 | 8 | # vim: ft=cmake:ts=2:sw=2:expandtab 9 | -------------------------------------------------------------------------------- /toolbox/boolector_facorization/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_tool_executable( boolector_factorization 2 | SOURCES 3 | boolector_factorization.cpp 4 | REQUIRES 5 | Boolector_FOUND 6 | ) 7 | 8 | -------------------------------------------------------------------------------- /src/metaSMT/support/default_visitation_unrolling_limit.hpp: -------------------------------------------------------------------------------- 1 | // Default BOOST_VARIANT_VISITATION_UNROLLING_LIMIT required when 2 | // logic_expressions are used. 3 | #define BOOST_VARIANT_VISITATION_UNROLLING_LIMIT 60 4 | 5 | -------------------------------------------------------------------------------- /toolbox/guess_mastermind/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_tool_executable( guess_mastermind 2 | SOURCES 3 | guess.cpp 4 | REQUIRES 5 | Boolector_FOUND 6 | CUDD_FOUND 7 | MiniSat_FOUND 8 | PicoSAT_FOUND 9 | ) 10 | 11 | -------------------------------------------------------------------------------- /src/metaSMT/support/cardinality.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "cardinality/bdd_impl.hpp" 4 | #include "cardinality/adder_impl.hpp" 5 | #include "cardinality/object.hpp" 6 | #include "cardinality/Evaluator.hpp" 7 | #include "cardinality/deprecated_api.hpp" 8 | -------------------------------------------------------------------------------- /src/lib/simple_symbol_table.cpp: -------------------------------------------------------------------------------- 1 | #include "../metaSMT/support/SimpleSymbolTable.hpp" 2 | 3 | namespace metaSMT { 4 | namespace support { 5 | struct std::map metaSMT::support::simple_symbol_table::map_; 6 | } // support 7 | } // metaSMT 8 | -------------------------------------------------------------------------------- /src/metaSMT/support/boost_mpl_map60.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | namespace boost { namespace mpl { 4 | #define BOOST_PP_ITERATION_PARAMS_1 \ 5 | (3, (51, 60, "boost/mpl/map/aux_/numbered.hpp")) 6 | #include BOOST_PP_ITERATE() 7 | }} 8 | -------------------------------------------------------------------------------- /src/metaSMT/support/boost_mpl_vector60.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | namespace boost { namespace mpl { 4 | #define BOOST_PP_ITERATION_PARAMS_1 \ 5 | (3, (51, 60, "boost/mpl/vector/aux_/numbered.hpp")) 6 | #include BOOST_PP_ITERATE() 7 | }} 8 | -------------------------------------------------------------------------------- /bindings/python/generate_ctest_script.awk: -------------------------------------------------------------------------------- 1 | #!/usr/bin/awk 2 | BEGIN { 3 | } 4 | 5 | { 6 | test=$1 7 | gen_test(test) 8 | } 9 | 10 | function gen_test(name) { 11 | print "ADD_TEST(\"" name "\"\n cmake -E chdir " path " \"" pymetaSMT "\" \"tests\" \"" name "\")" 12 | } 13 | -------------------------------------------------------------------------------- /bindings/python/pymetaSMT.in: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | THIS="$(cd $(dirname $0); pwd)" 3 | if [ "$1" = "--gdb" ]; then 4 | GDB="gdb --args" 5 | shift 6 | fi 7 | if [ -x '${Z3_EXECUTABLE}' ]; then 8 | Z3_PATH="Z3_EXECUTABLE='${Z3_EXECUTABLE}'" 9 | fi 10 | exec /usr/bin/env PYTHONPATH=$THIS $Z3_PATH $GDB python $@ 11 | -------------------------------------------------------------------------------- /src/metaSMT/types/Types.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Boolean.hpp" 4 | #include "BitVector.hpp" 5 | #include "Array.hpp" 6 | #include 7 | 8 | namespace metaSMT { 9 | namespace type { 10 | typedef boost::variant any_type; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /toolbox/smt2Input_evaluator/SMT2_main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "options.hpp" 5 | typedef metaSMT::DirectSolver_Context< metaSMT::solver::SMT2 > ContextType; 6 | OptionMap options; 7 | #include "main.cpp" 8 | -------------------------------------------------------------------------------- /src/metaSMT/support/DefaultSymbolTable.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | namespace metaSMT { 6 | namespace support { 7 | inline std::string default_symbol_table(unsigned id) { 8 | char buf[64]; 9 | sprintf(buf, "var_%u", id); 10 | return buf; 11 | } 12 | } // support 13 | } // metaSMT 14 | 15 | -------------------------------------------------------------------------------- /tests/direct_CVC4.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_TEST_MODULE direct_CVC4 2 | #include 3 | #include 4 | 5 | using namespace metaSMT; 6 | struct Solver_Fixture { 7 | typedef DirectSolver_Context< metaSMT::solver::CVC4 > ContextType; 8 | ContextType ctx ; 9 | }; 10 | 11 | #include "test_solver.cpp" 12 | #include "test_QF_BV.cpp" 13 | #include "test_cardinality.cpp" 14 | -------------------------------------------------------------------------------- /src/metaSMT/expression/print_expression.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "expression.hpp" 3 | 4 | namespace metaSMT { 5 | namespace expression { 6 | bool print_expression_static( std::ostream_iterator &out_it, 7 | logic_expression const &expr, 8 | boost::function const &table ); 9 | } // expression 10 | } // metaSMT 11 | -------------------------------------------------------------------------------- /cmake/metaSMTConfig.cmake.in: -------------------------------------------------------------------------------- 1 | set(metaSMT_FOUND 1) 2 | 3 | @_metaSMT_EXTERNAL_FIND@ 4 | 5 | set(metaSMT_INCLUDE_DIR @metaSMT_INCLUDES@) 6 | set(metaSMT_INCLUDE_DIRS ${metaSMT_INCLUDE_DIR}) 7 | 8 | set(metaSMT_LIBRARIES @metaSMT_MLIBS@) 9 | 10 | get_filename_component(metaSMT_CONFIG_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) 11 | include("${metaSMT_CONFIG_DIR}/metaSMT.cmake" ) 12 | set(metaSMT_CXXFLAGS "@metaSMT_CXXFLAGS@") 13 | -------------------------------------------------------------------------------- /toolbox/metaSMT-server/test-commands: -------------------------------------------------------------------------------- 1 | 0 2 | new_bitvector x 5 3 | #assertion {"op":"!=", "lhs":{"op":"variable", "name":"x"}, "rhs":{"op":"integer", "value":"0", "width":"5"}} 4 | assertion {"op":"bvslt", "lhs":{"op":"variable", "name":"x"}, "rhs":{"op":"integer", "value":"-5", "width":"5"}} 5 | assertion {"op":"bvsgt", "lhs":{"op":"variable", "name":"x"}, "rhs":{"op":"integer", "value":"-15", "width":"5"}} 6 | solve 7 | modelvalue x 8 | -------------------------------------------------------------------------------- /src/metaSMT/support/string_concat.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | namespace metaSMT { 7 | template < typename str1, typename str2 > 8 | struct string_concat 9 | : boost::mpl::insert_range< 10 | str1 11 | , typename boost::mpl::end::type, str2 12 | > 13 | {}; // string_concat 14 | } // metaSMT 15 | -------------------------------------------------------------------------------- /src/metaSMT/types/Evaluator.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../API/Evaluator.hpp" 3 | 4 | namespace metaSMT { 5 | template < typename Ctx > 6 | struct Evaluator< type::TypedSymbol > : public boost::mpl::true_ { 7 | template < typename Context > 8 | static typename Context::result_type eval(Context &ctx, metaSMT::type::TypedSymbol s) { 9 | return s.eval(ctx); 10 | } 11 | }; // Evaluator 12 | } // metaSMT 13 | -------------------------------------------------------------------------------- /toolbox/metaSMT-server/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_tool_executable( metaSMT-server 2 | SOURCES 3 | main.cpp 4 | SolverProcess.cpp 5 | Connection.cpp 6 | REQUIRES 7 | Boost_FOUND 8 | Boolector_FOUND 9 | CUDD_FOUND 10 | MiniSat_FOUND 11 | PicoSAT_FOUND 12 | STP_FOUND 13 | SWORD_FOUND 14 | Z3_FOUND 15 | STP_FOUND 16 | LIBRARIES 17 | pthread 18 | ${Boost_SYSTEM_LIBRARY} 19 | ${Boost_THREAD_LIBRARY} 20 | ) 21 | -------------------------------------------------------------------------------- /src/lib/_var_id.cpp: -------------------------------------------------------------------------------- 1 | #include "../metaSMT/impl/_var_id.hpp" 2 | #include 3 | 4 | #if BOOST_VERSION >= 105500 5 | 6 | #include 7 | unsigned metaSMT::impl::new_var_id() 8 | { 9 | static boost::atomic_uint _id ( 0u ); 10 | ++_id; 11 | return _id; 12 | } 13 | 14 | #else 15 | 16 | unsigned metaSMT::impl::new_var_id() 17 | { 18 | static unsigned _id ( 0u ); 19 | ++_id; 20 | return _id; 21 | } 22 | 23 | #endif 24 | 25 | -------------------------------------------------------------------------------- /toolbox/smt2Input_evaluator/Z3_Backend_main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "options.hpp" 6 | typedef metaSMT::DirectSolver_Context< 7 | metaSMT::IgnoreSymbolTable< 8 | metaSMT::solver::Z3_Backend 9 | > 10 | > ContextType; 11 | OptionMap options; 12 | #include "main.cpp" 13 | -------------------------------------------------------------------------------- /toolbox/sortnets/z3.cpp: -------------------------------------------------------------------------------- 1 | #include "Main.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace metaSMT; 8 | 9 | typedef DirectSolver_Context< IgnoreComments > DirectZ3Context; 10 | 11 | 12 | int main(int argc, const char *argv[]) 13 | { 14 | Main m(argc, argv); 15 | 16 | return m.run(); 17 | } 18 | -------------------------------------------------------------------------------- /toolbox/sortnets/stp.cpp: -------------------------------------------------------------------------------- 1 | #include "Main.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace metaSMT; 8 | 9 | int main(int argc, const char *argv[]) 10 | { 11 | Main< 12 | DirectSolver_Context < IgnoreComments < solver::STP > >, 13 | DirectSolver_Context < IgnoreComments < solver::STP > > 14 | > m(argc, argv); 15 | 16 | return m.run(); 17 | } 18 | -------------------------------------------------------------------------------- /toolbox/sortnets/cvc4.cpp: -------------------------------------------------------------------------------- 1 | #include "Main.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace metaSMT; 8 | 9 | int main(int argc, const char *argv[]) 10 | { 11 | Main< 12 | DirectSolver_Context < IgnoreComments < solver::CVC4 > > 13 | , DirectSolver_Context < IgnoreComments < solver::CVC4 > > 14 | > m(argc, argv); 15 | 16 | return m.run(); 17 | } 18 | -------------------------------------------------------------------------------- /bindings/python/python.cpp: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include "solvers.hpp" 9 | #include 10 | 11 | void export_expressions(); 12 | 13 | BOOST_PYTHON_MODULE( metasmt_python ) 14 | { 15 | 16 | export_expressions(); 17 | export_solvers(); 18 | 19 | } 20 | -------------------------------------------------------------------------------- /toolbox/sortnets/sword.cpp: -------------------------------------------------------------------------------- 1 | #include "Main.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace metaSMT; 8 | 9 | typedef DirectSolver_Context< IgnoreComments > DirectSwordContext; 10 | 11 | 12 | int main(int argc, const char *argv[]) 13 | { 14 | Main m(argc, argv); 15 | 16 | return m.run(); 17 | } 18 | -------------------------------------------------------------------------------- /src/metaSMT/Features.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace metaSMT { 6 | namespace features { 7 | 8 | /** 9 | * This template provides a compile-time way 10 | * to check for supported features of specific contexts. 11 | * e.g. to declare native supported apis. 12 | * 13 | **/ 14 | template 15 | struct supports : boost::mpl::false_ {}; 16 | 17 | } /* features */ 18 | } /* metaSMT */ 19 | -------------------------------------------------------------------------------- /src/metaSMT/support/enable_warnings.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This header complements disable_warnings.hpp should only be used in combination with it 3 | */ 4 | #ifdef __GNUC__ 5 | # if __GNUC__ >= 4 and __GNUC_MINOR__ > 4 6 | // this makes gcc 4.4 corrupt executables and cause random segfaults 7 | #pragma GCC pop_options 8 | #undef _BACKWARD_BACKWARD_WARNING_H 9 | #endif 10 | #endif 11 | 12 | #ifdef __clang__ 13 | #pragma clang diagnostic pop 14 | #undef _BACKWARD_BACKWARD_WARNING_H 15 | #endif 16 | -------------------------------------------------------------------------------- /tests/direct_STP.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_TEST_MODULE direct_STP 2 | #include 3 | #include 4 | 5 | using namespace metaSMT::solver; 6 | using namespace metaSMT; 7 | struct Solver_Fixture { 8 | typedef DirectSolver_Context< STP > ContextType; 9 | ContextType ctx ; 10 | }; 11 | 12 | #include "test_solver.cpp" 13 | #include "test_QF_BV.cpp" 14 | #include "test_cardinality.cpp" 15 | #include "test_evaluator.cpp" 16 | #include "test_Array.cpp" 17 | -------------------------------------------------------------------------------- /toolbox/smt2Input_evaluator/STP_main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "options.hpp" 7 | typedef metaSMT::DirectSolver_Context< 8 | metaSMT::IgnoreSymbolTable< 9 | metaSMT::Stack 10 | > 11 | > ContextType; 12 | OptionMap options; 13 | #include "main.cpp" 14 | -------------------------------------------------------------------------------- /bindings/python/metasmt/smt2.py: -------------------------------------------------------------------------------- 1 | from metasmt.core import * 2 | 3 | def _solver_install_symbol_table( self ): 4 | assert hasattr( self, 'symbol_table' ) 5 | self.set_symbol_table( self.symbol_table ) 6 | 7 | def _solver_symbol( self, var, name ): 8 | if not hasattr( self, 'symbol_table' ): 9 | self.symbol_table = smt2_symbol_table() 10 | 11 | self.symbol_table.insert( var, name ) 12 | 13 | solver.install_symbol_table = _solver_install_symbol_table 14 | solver.symbol = _solver_symbol 15 | -------------------------------------------------------------------------------- /src/metaSMT/support/protofy.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace metaSMT { 5 | namespace detail { 6 | 7 | template 8 | typename boost::disable_if, proto::literal >::type 9 | protofy ( T e) { 10 | return proto::lit(e); 11 | } 12 | 13 | template 14 | typename boost::enable_if, T>::type 15 | protofy ( T e) { 16 | return e; 17 | } 18 | 19 | } 20 | } /* metaSMT */ 21 | -------------------------------------------------------------------------------- /src/lib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(metaSMT STATIC 2 | _var_id.cpp 3 | expression_generator.cpp 4 | simple_symbol_table.cpp 5 | ) 6 | target_link_libraries(metaSMT ${metaSMT_LIBS}) 7 | if( CMAKE_COMPILER_IS_GNUCC OR ("${CMAKE_CXX_COMPILER_ID}" MATCHES Clang)) 8 | set_target_properties(metaSMT PROPERTIES COMPILE_FLAGS "-fPIC -g0 -O3") 9 | endif() 10 | 11 | 12 | install(TARGETS metaSMT 13 | EXPORT metaSMT 14 | LIBRARY DESTINATION lib 15 | RUNTIME DESTINATION bin 16 | ARCHIVE DESTINATION lib 17 | ) 18 | -------------------------------------------------------------------------------- /src/metaSMT/support/index/Logics.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../../tags/Logics.hpp" 3 | #include 4 | 5 | namespace metaSMT { 6 | namespace logic { 7 | typedef int index; 8 | 9 | template < typename Tag > 10 | struct Index { 11 | typedef typename boost::mpl::find< 12 | _all_logic_tags::all_Tags 13 | , Tag 14 | >::type iterator; 15 | 16 | static const index value = iterator::pos::value; 17 | }; // Index 18 | } // logic 19 | } // metaSMT 20 | -------------------------------------------------------------------------------- /src/metaSMT/API/BoolEvaluator.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Evaluator.hpp" 3 | 4 | namespace metaSMT { 5 | template <> 6 | struct Evaluator : public boost::mpl::true_ { 7 | template < typename Context > 8 | static typename Context::result_type eval(Context &ctx, bool b) { 9 | if ( b ) { 10 | return evaluate(ctx, metaSMT::logic::True); 11 | } 12 | else { 13 | return evaluate(ctx, metaSMT::logic::False); 14 | } 15 | } 16 | }; // Evaluator 17 | } // metaSMT 18 | -------------------------------------------------------------------------------- /src/metaSMT/tags/attribute.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace metaSMT { 4 | namespace attr { 5 | struct ignore {}; 6 | 7 | struct constant {}; 8 | struct unary {}; 9 | struct binary {}; 10 | struct ternary {}; 11 | 12 | //@ nary attributes: see SMT-LIB2 Core theory 13 | struct right_assoc {}; 14 | struct left_assoc {}; 15 | struct chainable {}; 16 | struct pairwise {}; 17 | 18 | // special attribute for cardinality 19 | struct nary {}; 20 | } // attr 21 | } // metaSMT 22 | 23 | -------------------------------------------------------------------------------- /toolbox/smt2Input_evaluator/SWORD_Backend_main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "options.hpp" 7 | typedef metaSMT::DirectSolver_Context< 8 | metaSMT::IgnoreSymbolTable< 9 | metaSMT::Stack 10 | > 11 | > ContextType; 12 | OptionMap options; 13 | #include "main.cpp" 14 | -------------------------------------------------------------------------------- /toolbox/smt2Input_evaluator/Boolector_main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "options.hpp" 7 | typedef metaSMT::DirectSolver_Context< 8 | metaSMT::IgnoreSymbolTable< 9 | metaSMT::Stack< 10 | metaSMT::solver::Boolector 11 | > 12 | > 13 | > ContextType; 14 | OptionMap options; 15 | #include "main.cpp" 16 | -------------------------------------------------------------------------------- /toolbox/sortnets/smt2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "Main.hpp" 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace metaSMT; 9 | 10 | 11 | 12 | int main(int argc, const char *argv[]) 13 | { 14 | Main< 15 | DirectSolver_Context < IgnoreComments < solver::SMT2 > > 16 | , DirectSolver_Context < IgnoreComments < solver::SMT2 > > 17 | > m(argc, argv); 18 | 19 | return m.run(); 20 | } 21 | -------------------------------------------------------------------------------- /tests/graph_STP.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_TEST_MODULE graph_STP 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace metaSMT::solver; 7 | using namespace metaSMT; 8 | struct Solver_Fixture { 9 | typedef GraphSolver_Context< STP > ContextType; 10 | ContextType ctx ; 11 | }; 12 | 13 | #include "test_solver.cpp" 14 | #include "test_QF_BV.cpp" 15 | #include "test_graph_copy.cpp" 16 | #include "test_cardinality.cpp" 17 | #include "test_evaluator.cpp" 18 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: cpp 2 | 3 | sudo: false 4 | 5 | compiler: 6 | - gcc 7 | 8 | addons: 9 | apt: 10 | sources: 11 | - kalakris-cmake 12 | - ubuntu-toolchain-r-test 13 | packages: 14 | - cmake 15 | 16 | cache: 17 | directories: 18 | - deps 19 | 20 | before_install: 21 | - git clone https://github.com/agra-uni-bremen/dependencies.git 22 | - ./bootstrap.sh --deps deps/ --travis -m RELEASE build/ 23 | 24 | before_script: 25 | - cd build 26 | 27 | script: make 28 | 29 | after_success: 30 | - make test 31 | 32 | os: 33 | - linux 34 | -------------------------------------------------------------------------------- /cmake/default_compliler_flags.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Add default C/CXX flags to reduce memory consumption and compile time with gcc 3 | # 4 | 5 | if( CMAKE_COMPILER_IS_GNUCC AND NOT CMAKE_C_FLAGS) 6 | set( CMAKE_C_FLAGS "--param ggc-min-expand=30 --param ggc-min-heapsize=8192" CACHE STRING "Flags used by the compiler during all build types." FORCE ) 7 | endif() 8 | 9 | if( CMAKE_COMPILER_IS_GNUCXX AND NOT CMAKE_CXX_FLAGS) 10 | set( CMAKE_CXX_FLAGS "--param ggc-min-expand=30 --param ggc-min-heapsize=8192" CACHE STRING "Flags used by the compiler during all build types." FORCE ) 11 | endif() 12 | -------------------------------------------------------------------------------- /tests/direct_CUDD.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_TEST_MODULE direct_CUDD 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace metaSMT::solver; 7 | using namespace metaSMT; 8 | struct Solver_Fixture { 9 | typedef DirectSolver_Context< Group < CUDD_Context > > ContextType; 10 | ContextType ctx ; 11 | }; 12 | 13 | #include "test_solver.cpp" 14 | // #include "test_QF_BV.cpp" 15 | // #include "test_Array.cpp" 16 | #include "test_group.cpp" 17 | #include "test_unsat.cpp" 18 | #include "test_lazy.cpp" 19 | -------------------------------------------------------------------------------- /src/metaSMT/types/Boolean.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace metaSMT { 6 | namespace type { 7 | 8 | struct Boolean { 9 | template 10 | friend STREAM & operator<< (STREAM & out, Boolean const & self) \ 11 | { return (out << "Boolean"); } 12 | 13 | }; 14 | 15 | /** equality of Boolean Types **/ 16 | template 17 | bool operator== (Boolean const & a , T const & b) \ 18 | { return boost::is_same::value; } 19 | 20 | } /* type */ 21 | } /* metaSMT */ 22 | -------------------------------------------------------------------------------- /cmake/get_git_version.cmake: -------------------------------------------------------------------------------- 1 | find_package(Git QUIET) 2 | if( GIT_FOUND ) 3 | execute_process( 4 | COMMAND ${GIT_EXECUTABLE} describe --tags --match "metaSMT-*" HEAD 5 | OUTPUT_VARIABLE GIT_VERSION_DESCRIPTION 6 | OUTPUT_STRIP_TRAILING_WHITESPACE 7 | WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} 8 | ERROR_QUIET 9 | RESULT_VARIABLE GIT_DESCRIBE_RESULT 10 | ) 11 | 12 | if(GIT_DESCRIBE_RESULT EQUAL 0) 13 | string(REPLACE "metaSMT-" "" metaSMT_VERSION "${GIT_VERSION_DESCRIPTION}") 14 | endif() 15 | 16 | message(STATUS "metaSMT VERSION: ${metaSMT_VERSION}" ) 17 | endif() 18 | 19 | -------------------------------------------------------------------------------- /tests/graph_CUDD.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_TEST_MODULE graph_CUDD 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace metaSMT::solver; 7 | using namespace metaSMT; 8 | struct Solver_Fixture { 9 | typedef GraphSolver_Context ContextType; 10 | ContextType ctx; 11 | }; 12 | 13 | #include "test_solver.cpp" 14 | //#include "test_QF_BV.cpp" 15 | //#include "test_Array.hpp" 16 | #include "test_graph_copy.cpp" 17 | #include "test_unsat.cpp" 18 | #include "test_lazy.cpp" 19 | -------------------------------------------------------------------------------- /tests/graph_SWORD2.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_TEST_MODULE graph_SWORD 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace metaSMT::solver; 7 | using namespace metaSMT; 8 | struct Solver_Fixture { 9 | typedef GraphSolver_Context< SWORD_Backend > ContextType; 10 | ContextType ctx; 11 | }; 12 | 13 | #include "test_solver.cpp" 14 | #include "test_QF_BV.cpp" 15 | //#include "test_Array.cpp" 16 | #include "test_graph_copy.cpp" 17 | #include "test_unsat.cpp" 18 | #include "test_lazy.cpp" 19 | -------------------------------------------------------------------------------- /toolbox/sudoku/sudoku_examples.txt: -------------------------------------------------------------------------------- 1 | # Each line is one sudoku instance (Size 16*16, serialized by row) 2 | 3 | __________________________________________________i_____bg_______________h___________________________________________b____________g__________________f____________kn_______________c____________________________________________________________________________ 4 | 5 | n_gi_ldfbkc_eh_p_b_dmojnp_gfq_kilpf_ei_b_qn_m__jcm__g___j_e_f__b_kp___lcdb__jmhqm_b_f____ni__l_____fp_e___hcb_ngon_l_h_j__meif_k___po_f_n_l_g___fi_bh__p__d_oqjldg__kebqfc_jnimh_e_n__ilqob_dpc__qdc__piheo__gfmbf_____o_dklh___p_e_lbg_m_qn_ji_i___d_hec_jpkbq_ 6 | 7 | 8 | -------------------------------------------------------------------------------- /toolbox/sortnets/minisat.cpp: -------------------------------------------------------------------------------- 1 | #include "Main.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace metaSMT; 10 | 11 | 12 | 13 | int main(int argc, const char *argv[]) 14 | { 15 | Main< 16 | DirectSolver_Context < IgnoreComments < BitBlast < SAT_Aiger < solver::MiniSAT > > > > 17 | , DirectSolver_Context < IgnoreComments < BitBlast < SAT_Aiger < solver::MiniSAT > > > > 18 | > m(argc, argv); 19 | 20 | return m.run(); 21 | } 22 | -------------------------------------------------------------------------------- /toolbox/sortnets/boolector.cpp: -------------------------------------------------------------------------------- 1 | #include "Main.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | using namespace metaSMT; 11 | 12 | 13 | 14 | int main(int argc, const char *argv[]) 15 | { 16 | Main< 17 | DirectSolver_Context < IgnoreComments < solver::Boolector > > 18 | , DirectSolver_Context < IgnoreComments < BitBlast < SAT_Aiger < solver::MiniSAT > > > > 19 | > m(argc, argv); 20 | 21 | return m.run(); 22 | } 23 | -------------------------------------------------------------------------------- /src/lib/expression_generator.cpp: -------------------------------------------------------------------------------- 1 | #include "../metaSMT/support/default_visitation_unrolling_limit.hpp" 2 | #include "../metaSMT/expression/print_expression_generic.hpp" 3 | 4 | namespace metaSMT { 5 | namespace expression { 6 | bool print_expression_static( std::ostream_iterator &out_it, 7 | logic_expression const &expr, 8 | boost::function const &table ) { 9 | grammar< std::ostream_iterator > g(table); 10 | return boost::spirit::karma::generate_delimited(out_it, g, boost::spirit::ascii::space, expr); 11 | } 12 | } // expression 13 | } // metaSMT 14 | -------------------------------------------------------------------------------- /tests/direct_BitBlast_CUDD.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_TEST_MODULE direct_BitBlast_CUDD 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace metaSMT::solver; 8 | using namespace metaSMT; 9 | struct Solver_Fixture { 10 | typedef DirectSolver_Context< Group < BitBlast > > 11 | ContextType; 12 | ContextType ctx ; 13 | }; 14 | 15 | #include "test_solver.cpp" 16 | #include "test_QF_BV.cpp" 17 | // #include "test_Array.cpp" 18 | #include "test_group.cpp" 19 | #include "test_unsat.cpp" 20 | #include "test_lazy.cpp" 21 | 22 | -------------------------------------------------------------------------------- /tests/direct_ExprSolver_SMT2.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_TEST_MODULE direct_ExprSolver_SMT2 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace metaSMT::solver; 9 | using namespace metaSMT; 10 | struct Solver_Fixture { 11 | typedef DirectSolver_Context< Stack< ExpressionSolver< SMT2 > > > ContextType; 12 | ContextType ctx ; 13 | }; 14 | 15 | #include "test_solver.cpp" 16 | #include "test_QF_BV.cpp" 17 | #include "test_Array.cpp" 18 | #include "test_stack.cpp" 19 | -------------------------------------------------------------------------------- /tests/graph_Z3.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_TEST_MODULE graph_Z3 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace metaSMT::solver; 7 | using namespace metaSMT; 8 | struct Solver_Fixture { 9 | typedef GraphSolver_Context< Z3_Backend > ContextType; 10 | ContextType ctx ; 11 | }; 12 | 13 | #include "test_solver.cpp" 14 | #include "test_QF_BV.cpp" 15 | #include "test_Array.cpp" 16 | #include "test_graph_copy.cpp" 17 | #include "test_cardinality.cpp" 18 | #include "test_lazy.cpp" 19 | #include "test_stack.cpp" 20 | #include "test_evaluator.cpp" 21 | -------------------------------------------------------------------------------- /tests/direct_PicoSAT.cpp: -------------------------------------------------------------------------------- 1 | 2 | #define BOOST_TEST_MODULE direct_PicoSAT 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace metaSMT::solver; 10 | using namespace metaSMT; 11 | struct Solver_Fixture 12 | { 13 | typedef DirectSolver_Context< Group > > > ContextType; 14 | ContextType ctx ; 15 | }; 16 | 17 | #include "test_solver.cpp" 18 | #include "test_QF_BV.cpp" 19 | // #include "test_Array.cpp" 20 | #include "test_group.cpp" 21 | #include "test_unsat.cpp" 22 | -------------------------------------------------------------------------------- /toolbox/sortnets/picosat.cpp: -------------------------------------------------------------------------------- 1 | #include "Main.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | using namespace metaSMT; 11 | 12 | 13 | 14 | int main(int argc, const char *argv[]) 15 | { 16 | Main< 17 | DirectSolver_Context < IgnoreComments < BitBlast < SAT_Aiger < solver::PicoSAT > > > > 18 | , DirectSolver_Context < IgnoreComments < BitBlast < SAT_Aiger < solver::MiniSAT > > > > 19 | > m(argc, argv); 20 | 21 | return m.run(); 22 | } 23 | -------------------------------------------------------------------------------- /tests/direct_ExprSolver_Z3.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_TEST_MODULE direct_ExprSolver_Z3 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace metaSMT::solver; 9 | using namespace metaSMT; 10 | struct Solver_Fixture { 11 | typedef DirectSolver_Context< Stack< ExpressionSolver< Z3_Backend > > > ContextType; 12 | ContextType ctx ; 13 | }; 14 | 15 | #include "test_solver.cpp" 16 | #include "test_QF_BV.cpp" 17 | #include "test_Array.cpp" 18 | #include "test_stack.cpp" 19 | -------------------------------------------------------------------------------- /tests/direct_Lingeling.cpp: -------------------------------------------------------------------------------- 1 | 2 | #define BOOST_TEST_MODULE direct_Lingeling 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace metaSMT::solver; 10 | using namespace metaSMT; 11 | struct Solver_Fixture 12 | { 13 | typedef DirectSolver_Context< Group > > > ContextType; 14 | ContextType ctx ; 15 | }; 16 | 17 | #include "test_solver.cpp" 18 | #include "test_QF_BV.cpp" 19 | // #include "test_Array.cpp" 20 | #include "test_group.cpp" 21 | #include "test_unsat.cpp" 22 | -------------------------------------------------------------------------------- /tests/graph_BitBlast_CUDD.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_TEST_MODULE graph_BitBlast_CUDD 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace metaSMT::solver; 8 | using namespace metaSMT; 9 | struct Solver_Fixture { 10 | typedef GraphSolver_Context< BitBlast > 11 | ContextType; 12 | ContextType ctx; 13 | }; 14 | 15 | #include "test_solver.cpp" 16 | #include "test_QF_BV.cpp" 17 | // #include "test_Array.cpp" 18 | #include "test_graph_copy.cpp" 19 | #include "test_unsat.cpp" 20 | #include "test_lazy.cpp" 21 | -------------------------------------------------------------------------------- /tests/direct_ExprSolver_Boolector.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_TEST_MODULE direct_ExprSolver_Boolector 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace metaSMT::solver; 9 | using namespace metaSMT; 10 | struct Solver_Fixture { 11 | typedef DirectSolver_Context< Stack< ExpressionSolver< Boolector > > > ContextType; 12 | ContextType ctx ; 13 | }; 14 | 15 | #include "test_solver.cpp" 16 | #include "test_QF_BV.cpp" 17 | #include "test_Array.cpp" 18 | #include "test_stack.cpp" 19 | -------------------------------------------------------------------------------- /toolbox/sortnets/unsorted_6.txt: -------------------------------------------------------------------------------- 1 | 000010 2 | 000100 3 | 000101 4 | 000110 5 | 001000 6 | 001001 7 | 001010 8 | 001011 9 | 001100 10 | 001101 11 | 001110 12 | 010000 13 | 010001 14 | 010010 15 | 010011 16 | 010100 17 | 010101 18 | 010110 19 | 010111 20 | 011000 21 | 011001 22 | 011010 23 | 011011 24 | 011100 25 | 011101 26 | 011110 27 | 100000 28 | 100001 29 | 100010 30 | 100011 31 | 100100 32 | 100101 33 | 100110 34 | 100111 35 | 101000 36 | 101001 37 | 101010 38 | 101011 39 | 101100 40 | 101101 41 | 101110 42 | 101111 43 | 110000 44 | 110001 45 | 110010 46 | 110011 47 | 110100 48 | 110101 49 | 110110 50 | 110111 51 | 111000 52 | 111001 53 | 111010 54 | 111011 55 | 111100 56 | 111101 57 | 111110 58 | -------------------------------------------------------------------------------- /tests/direct_Aiger_MiniSAT.cpp: -------------------------------------------------------------------------------- 1 | 2 | #define BOOST_TEST_MODULE direct_MiniSAT 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace metaSMT::solver; 10 | using namespace metaSMT; 11 | struct Solver_Fixture 12 | { 13 | typedef DirectSolver_Context< Group< BitBlast < SAT_Aiger < MiniSAT > > > > ContextType; 14 | ContextType ctx ; 15 | }; 16 | 17 | #include "test_solver.cpp" 18 | #include "test_QF_BV.cpp" 19 | // #include "test_Array.cpp" 20 | #include "test_group.cpp" 21 | #include "test_unsat.cpp" 22 | #include "test_lazy.cpp" 23 | -------------------------------------------------------------------------------- /tests/direct_Aiger_PicoSAT.cpp: -------------------------------------------------------------------------------- 1 | 2 | #define BOOST_TEST_MODULE direct_PicoSAT 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace metaSMT::solver; 10 | using namespace metaSMT; 11 | struct Solver_Fixture 12 | { 13 | typedef DirectSolver_Context< Group< BitBlast < SAT_Aiger < PicoSAT > > > > ContextType; 14 | ContextType ctx ; 15 | }; 16 | 17 | #include "test_solver.cpp" 18 | #include "test_QF_BV.cpp" 19 | // #include "test_Array.cpp" 20 | #include "test_group.cpp" 21 | #include "test_unsat.cpp" 22 | #include "test_lazy.cpp" 23 | -------------------------------------------------------------------------------- /tests/direct_SWORD2.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_TEST_MODULE direct_SWORD 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace metaSMT::solver; 8 | using namespace metaSMT; 9 | struct Solver_Fixture { 10 | typedef DirectSolver_Context< Stack < Group < SWORD_Backend > > > ContextType; 11 | ContextType ctx ; 12 | }; 13 | 14 | #include "test_solver.cpp" 15 | #include "test_QF_BV.cpp" 16 | //#include "test_Array.cpp" 17 | #include "test_group.cpp" 18 | #include "test_unsat.cpp" 19 | #include "test_fmi.cpp" 20 | #include "test_cardinality.cpp" 21 | #include "test_optimization.cpp" 22 | -------------------------------------------------------------------------------- /tests/graph_Aiger_MiniSAT.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_TEST_MODULE graph_MiniSAT 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace metaSMT::solver; 9 | using namespace metaSMT; 10 | struct Solver_Fixture 11 | { 12 | typedef GraphSolver_Context< BitBlast < SAT_Aiger < MiniSAT > > > ContextType; 13 | ContextType ctx ; 14 | }; 15 | 16 | #include "test_solver.cpp" 17 | #include "test_QF_BV.cpp" 18 | // #include "test_Array.cpp" 19 | // #include "test_group.cpp" 20 | #include "test_unsat.cpp" 21 | #include "test_lazy.cpp" 22 | -------------------------------------------------------------------------------- /src/metaSMT/API/AddClause.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include "../tags/SAT.hpp" 5 | #include "../Features.hpp" 6 | 7 | #include 8 | 9 | namespace metaSMT 10 | { 11 | namespace features 12 | { 13 | struct addclause_api {}; 14 | } 15 | 16 | struct addclause_cmd { typedef void result_type; }; 17 | 18 | template 19 | void add_clause ( Context_& ctx, std::vector < SAT::tag::lit_tag > const& clause ) 20 | { 21 | BOOST_MPL_ASSERT_MSG( 22 | ( features::supports< Context_, features::addclause_api>::value), 23 | context_does_not_support_addclause_api, 24 | () 25 | ); 26 | 27 | ctx.command ( addclause_cmd(), clause ); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/metaSMT/transform/rewrite.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace metaSMT { 5 | namespace transform { 6 | 7 | template 8 | struct rewrite1 { 9 | template 10 | struct to 11 | : boost::proto::result_of::make_expr< Tag, Domain, Child> 12 | {}; 13 | }; 14 | 15 | template 16 | struct rewrite2 { 17 | template 18 | struct to 19 | : boost::proto::result_of::make_expr< Tag, Domain, Left, Right> 20 | {}; 21 | }; 22 | 23 | } /* transform */ 24 | } /* metaSMT */ 25 | 26 | 27 | // vim: tabstop=2 shiftwidth=2 expandtab 28 | -------------------------------------------------------------------------------- /tests/graph_SMT2.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_TEST_MODULE direct_SMT2 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace metaSMT::solver; 8 | using namespace metaSMT; 9 | struct Solver_Fixture 10 | { 11 | typedef GraphSolver_Context< SMT2 > ContextType; 12 | ContextType ctx ; 13 | }; 14 | 15 | #include "test_solver.cpp" 16 | #include "test_QF_BV.cpp" 17 | #include "test_annotate.cpp" 18 | // #include "test_Array.cpp" 19 | //#include "test_group.cpp" 20 | //#include "test_unsat.cpp" 21 | //#include "test_lazy.cpp" 22 | #include "test_cardinality.cpp" 23 | #include "test_evaluator.cpp" 24 | -------------------------------------------------------------------------------- /src/metaSMT/support/optimization/detail.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace metaSMT { 4 | namespace optimization { 5 | namespace detail { 6 | /* 7 | * Note that countOnes implicitly calls solve(.). 8 | */ 9 | template < typename Context, typename Boolean > 10 | unsigned countOnes( Context &ctx, std::vector const &ps ) { 11 | bool sat = solve(ctx); 12 | assert( sat && "The formula must not be unsatisfiable" ); 13 | unsigned num_ones = 0; 14 | for ( unsigned u = 0; u < ps.size(); ++u ) { 15 | num_ones += static_cast(read_value(ctx, ps[u])); 16 | } 17 | return num_ones; 18 | } 19 | } // detail 20 | } // optimization 21 | } // metaSMT 22 | -------------------------------------------------------------------------------- /tests/graph_MiniSAT.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_TEST_MODULE graph_MiniSAT 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace metaSMT::solver; 9 | using namespace metaSMT; 10 | struct Solver_Fixture 11 | { 12 | typedef GraphSolver_Context< BitBlast < SAT_Clause < MiniSAT > > > ContextType; 13 | ContextType ctx ; 14 | }; 15 | 16 | #include "test_solver.cpp" 17 | #include "test_QF_BV.cpp" 18 | // #include "test_Array.cpp" 19 | // #include "test_group.cpp" 20 | #include "test_unsat.cpp" 21 | #include "test_lazy.cpp" 22 | #include "test_evaluator.cpp" 23 | -------------------------------------------------------------------------------- /tests/graph_Lingeling.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_TEST_MODULE graph_Lingeling 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace metaSMT::solver; 9 | using namespace metaSMT; 10 | struct Solver_Fixture 11 | { 12 | typedef GraphSolver_Context< BitBlast < SAT_Clause < Lingeling > > > ContextType; 13 | ContextType ctx ; 14 | }; 15 | 16 | #include "test_solver.cpp" 17 | #include "test_QF_BV.cpp" 18 | // #include "test_Array.cpp" 19 | // #include "test_group.cpp" 20 | #include "test_unsat.cpp" 21 | #include "test_lazy.cpp" 22 | #include "test_evaluator.cpp" 23 | -------------------------------------------------------------------------------- /tests/direct_CW_MiniSat.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_TEST_MODULE direct_CW_PicoSAT 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace metaSMT::solver; 9 | using namespace metaSMT; 10 | struct Solver_Fixture 11 | { 12 | typedef DirectSolver_Context< Group > 14 | > > > > ContextType; 15 | ContextType ctx ; 16 | }; 17 | 18 | #include "test_solver.cpp" 19 | #include "test_QF_BV.cpp" 20 | // #include "test_Array.cpp" 21 | #include "test_group.cpp" 22 | #include "test_unsat.cpp" 23 | #include "test_lazy.cpp" 24 | -------------------------------------------------------------------------------- /tests/direct_CW_PicoSAT.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_TEST_MODULE direct_CW_PicoSAT 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace metaSMT::solver; 9 | using namespace metaSMT; 10 | struct Solver_Fixture 11 | { 12 | typedef DirectSolver_Context< Group > 14 | > > > > ContextType; 15 | ContextType ctx ; 16 | }; 17 | 18 | #include "test_solver.cpp" 19 | #include "test_QF_BV.cpp" 20 | // #include "test_Array.cpp" 21 | #include "test_group.cpp" 22 | #include "test_unsat.cpp" 23 | #include "test_lazy.cpp" 24 | -------------------------------------------------------------------------------- /toolbox/smt2Input_evaluator/MiniSAT_main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "options.hpp" 10 | typedef metaSMT::DirectSolver_Context< 11 | metaSMT::IgnoreSymbolTable< 12 | metaSMT::Group< 13 | metaSMT::BitBlast< 14 | metaSMT::SAT_Clause< 15 | metaSMT::Stack 16 | > 17 | > 18 | > 19 | > 20 | > ContextType; 21 | OptionMap options; 22 | #include "main.cpp" 23 | -------------------------------------------------------------------------------- /toolbox/smt2Input_evaluator/PicoSAT_main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "options.hpp" 10 | typedef 11 | metaSMT::DirectSolver_Context< 12 | metaSMT::IgnoreSymbolTable< 13 | metaSMT::Group< 14 | metaSMT::BitBlast< 15 | metaSMT::SAT_Clause< 16 | metaSMT::Stack 17 | > 18 | > 19 | > 20 | > 21 | > ContextType; 22 | OptionMap options; 23 | #include "main.cpp" 24 | -------------------------------------------------------------------------------- /toolbox/README: -------------------------------------------------------------------------------- 1 | == metaSMT toolbox == 2 | This folder is meant for small projects that use metaSMT. 3 | All subfolders are automatically compiled into executables with the current build configuration. 4 | 5 | == How to make a new project == 6 | 7 | # copy the example project 8 | cp -r simple new_project 9 | 10 | # or copy a project with custom CMakeLists.txt 11 | cp -r sudoku new_project 12 | # specify the correct dependencies 13 | edit new_project/CMakeLists.txt 14 | 15 | 16 | # and tell cmake to pick up new projects 17 | cd build 18 | make rebuild_cache 19 | 20 | 21 | == Reference and Guidance == 22 | The sudoku/ and guess_mastermind/ folders both show the basic usage of 23 | metaSMT. 24 | 25 | The use of all metaSMT expressions is also demonstrated in the tests folder of 26 | metaSMT. 27 | -------------------------------------------------------------------------------- /tests/direct_CW_Glucoser.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_TEST_MODULE direct_CW_PicoSAT 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace metaSMT::solver; 10 | using namespace metaSMT; 11 | struct Solver_Fixture 12 | { 13 | typedef DirectSolver_Context< Group > 15 | > > > > ContextType; 16 | ContextType ctx ; 17 | }; 18 | 19 | #include "test_solver.cpp" 20 | #include "test_QF_BV.cpp" 21 | // #include "test_Array.cpp" 22 | #include "test_group.cpp" 23 | #include "test_unsat.cpp" 24 | #include "test_lazy.cpp" 25 | -------------------------------------------------------------------------------- /tests/direct_CW_PrecoSAT.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_TEST_MODULE direct_CW_PicoSAT 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace metaSMT::solver; 10 | using namespace metaSMT; 11 | struct Solver_Fixture 12 | { 13 | typedef DirectSolver_Context< Group > 15 | > > > > ContextType; 16 | ContextType ctx ; 17 | }; 18 | 19 | #include "test_solver.cpp" 20 | #include "test_QF_BV.cpp" 21 | // #include "test_Array.cpp" 22 | #include "test_group.cpp" 23 | #include "test_unsat.cpp" 24 | #include "test_lazy.cpp" 25 | -------------------------------------------------------------------------------- /tests/direct_CW_Plingeling.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_TEST_MODULE direct_CW_PicoSAT 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace metaSMT::solver; 10 | using namespace metaSMT; 11 | struct Solver_Fixture 12 | { 13 | typedef DirectSolver_Context< Group > 15 | > > > > ContextType; 16 | ContextType ctx ; 17 | }; 18 | 19 | #include "test_solver.cpp" 20 | #include "test_QF_BV.cpp" 21 | // #include "test_Array.cpp" 22 | #include "test_group.cpp" 23 | #include "test_unsat.cpp" 24 | #include "test_lazy.cpp" 25 | -------------------------------------------------------------------------------- /tests/search_tests.awk: -------------------------------------------------------------------------------- 1 | BEGIN { 2 | PREFIX="" 3 | } 4 | 5 | $0 ~ "^ *BOOST_FIXTURE_TEST_SUITE.*\\(" { 6 | sub("^.*\\( *", ""); 7 | sub(" *\\,.*$", ""); 8 | PREFIX=$0; 9 | } 10 | 11 | $0 ~ "^ *BOOST_AUTO_TEST_SUITE_END *\\( *\\)" { 12 | PREFIX="" 13 | } 14 | 15 | $0 ~ "^ *BOOST_AUTO_TEST_CASE *\\(" { 16 | sub("^ *BOOST_AUTO_TEST_CASE *\\( *", "") 17 | sub(" *\\).*$", "") 18 | if ( PREFIX ) { 19 | printf "%s/%s\n", PREFIX, $0 20 | } else { 21 | printf "%s\n", $0 22 | } 23 | } 24 | 25 | $0 ~ "^ *#include *\"" { 26 | sub("^[^\"]*\" *", ""); 27 | sub(" *\".*$", ""); 28 | #print "#include", $0 29 | callfile($0) 30 | } 31 | 32 | END { 33 | } 34 | 35 | function callfile(f) { 36 | if (system("test -f " f) == 0) { 37 | ARGV[ARGC]=f 38 | ARGC++ 39 | } 40 | } 41 | 42 | # vim: ts=2 sw=2 et 43 | -------------------------------------------------------------------------------- /tests/direct_MiniSAT.cpp: -------------------------------------------------------------------------------- 1 | 2 | #define BOOST_TEST_MODULE direct_MiniSAT 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | using namespace metaSMT::solver; 11 | using namespace metaSMT; 12 | struct Solver_Fixture 13 | { 14 | typedef DirectSolver_Context< Stack< Group < BitBlast < SAT_Clause < MiniSAT > > > > > ContextType; 15 | ContextType ctx ; 16 | }; 17 | 18 | #include "test_solver.cpp" 19 | #include "test_QF_BV.cpp" 20 | // #include "test_Array.cpp" 21 | #include "test_group.cpp" 22 | #include "test_unsat.cpp" 23 | #include "test_cardinality.cpp" 24 | #include "test_optimization.cpp" 25 | #include "test_evaluator.cpp" 26 | -------------------------------------------------------------------------------- /src/metaSMT/support/find_executable.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | namespace metaSMT { 6 | namespace support { 7 | inline std::string find_executable( std::string const & progname 8 | , std::string const & envname) 9 | { 10 | char* env = getenv(envname.c_str()); 11 | if(env) return env; 12 | return progname; 13 | } 14 | 15 | inline int execvp(std::string const &file, 16 | std::vector const &args) { 17 | std::vector av; 18 | for ( std::vector::const_iterator it = args.begin(); 19 | it != args.end(); ++it ) 20 | av.push_back( it->c_str() ); 21 | av.push_back(0); 22 | return ::execvp(file.c_str(), const_cast(&av[0])); 23 | } 24 | } /* support */ 25 | } /* metaSMT */ 26 | 27 | -------------------------------------------------------------------------------- /tests/test_stack.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | using namespace metaSMT; 10 | using namespace metaSMT::solver; 11 | using namespace metaSMT::logic; 12 | namespace proto = boost::proto; 13 | using boost::dynamic_bitset; 14 | 15 | BOOST_FIXTURE_TEST_SUITE(stack_test, Solver_Fixture ) 16 | 17 | BOOST_AUTO_TEST_CASE( simple_sat ) 18 | { 19 | BOOST_REQUIRE( solve(ctx) ); 20 | // sat 21 | 22 | push( ctx ); 23 | 24 | assertion ( ctx, False ); 25 | BOOST_REQUIRE ( !solve(ctx) ); 26 | // unsat 27 | BOOST_REQUIRE ( !solve(ctx) ); 28 | // still unsat 29 | 30 | pop( ctx ); 31 | BOOST_REQUIRE ( solve(ctx) ); 32 | } 33 | 34 | 35 | BOOST_AUTO_TEST_SUITE_END() //Solver 36 | 37 | // vim: ft=cpp:ts=2:sw=2:expandtab 38 | -------------------------------------------------------------------------------- /tests/direct_SMT2.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_TEST_MODULE direct_SMT2 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace metaSMT::solver; 8 | using namespace metaSMT; 9 | struct Solver_Fixture 10 | { 11 | typedef DirectSolver_Context< SMT2 > ContextType; 12 | ContextType ctx ; 13 | }; 14 | 15 | #include "test_solver.cpp" 16 | #include "test_QF_BV.cpp" 17 | #include "test_QF_UF.cpp" 18 | #include "test_annotate.cpp" 19 | #include "test_stack.cpp" 20 | #include "test_Array.cpp" 21 | //#include "test_group.cpp" 22 | //#include "test_unsat.cpp" 23 | //#include "test_lazy.cpp" 24 | #include "test_Types.cpp" 25 | #include "test_cardinality.cpp" 26 | #include "test_optimization.cpp" 27 | #include "test_expression.cpp" 28 | #include "test_simplify.cpp" 29 | #include "test_evaluator.cpp" 30 | -------------------------------------------------------------------------------- /tests/direct_Z3.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_TEST_MODULE direct_Z3 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace metaSMT::solver; 9 | using namespace metaSMT; 10 | struct Solver_Fixture { 11 | typedef DirectSolver_Context< IgnoreSymbolTable< IgnoreComments< Group< Z3_Backend > > > > 12 | ContextType; 13 | ContextType ctx ; 14 | }; 15 | 16 | #include "test_solver.cpp" 17 | #include "test_QF_BV.cpp" 18 | #include "test_QF_UF.cpp" 19 | #include "test_Array.cpp" 20 | #include "test_group.cpp" 21 | #include "test_unsat.cpp" 22 | #include "test_cardinality.cpp" 23 | #include "test_annotate.cpp" 24 | #include "test_stack.cpp" 25 | #include "test_Types.cpp" 26 | #include "test_simplify.cpp" 27 | #include "test_optimization.cpp" 28 | #include "test_evaluator.cpp" 29 | -------------------------------------------------------------------------------- /src/metaSMT/API/Evaluator.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace metaSMT { 5 | /** 6 | * \brief Evaluator API 7 | * 8 | * \ingroup API 9 | * \defgroup Evaluator Evaluator 10 | * @{ 11 | */ 12 | 13 | /** 14 | * \brief generic mechanism to extend the metaSMT primitives 15 | * 16 | * Evaluator provides a mechanism to enrich metaSMT's list of 17 | * primitives with arbitary types. For each new type T a 18 | * specialization of metaSMT::Evaluator has to be implemened 19 | * which provides a static member function eval(.) to convert the 20 | * new type into a result_type. 21 | * 22 | * See BoolEvaluator.hpp for an example. 23 | * 24 | * WARNING: Note that specializations of Evaluator must be placed 25 | * into the namespace metaSMT. 26 | */ 27 | template < typename Tag > 28 | struct Evaluator : public boost::mpl::false_ 29 | {}; // evaluator 30 | /**@}*/ 31 | } // metaSMT 32 | -------------------------------------------------------------------------------- /tests/direct_Threaded_Z3.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_TEST_MODULE direct_Threaded_Z3 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | using namespace metaSMT::solver; 11 | using namespace metaSMT; 12 | struct Solver_Fixture { 13 | typedef DirectSolver_Context< IgnoreComments< Group < Stack < Z3 > > > > ContextType1; 14 | typedef Threaded_Context< ContextType1, ContextType1 > ContextType; 15 | ContextType ctx ; 16 | }; 17 | 18 | #include "test_solver.cpp" 19 | //#include "test_QF_BV.cpp" 20 | //#include "test_Array.cpp" 21 | //#include "test_group.cpp" 22 | //#include "test_stack.cpp" 23 | //#include "test_unsat.cpp" 24 | //#include "test_fmi.cpp" 25 | //#include "test_cardinality.cpp" 26 | //#include "test_lazy.cpp" 27 | //#include "test_annotate.cpp" 28 | -------------------------------------------------------------------------------- /tests/graph_Boolector.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_TEST_MODULE graph_Boolector 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | 11 | using namespace metaSMT::solver; 12 | using namespace metaSMT; 13 | struct Solver_Fixture { 14 | typedef GraphSolver_Context< IgnoreSymbolTable< IgnoreComments< Group < Stack < Boolector > > > > > ContextType; 15 | ContextType ctx ; 16 | }; 17 | 18 | #include "test_solver.cpp" 19 | #include "test_QF_BV.cpp" 20 | #include "test_Array.cpp" 21 | #include "test_graph_copy.cpp" 22 | #include "test_unsat.cpp" 23 | #include "test_cardinality.cpp" 24 | #include "test_lazy.cpp" 25 | #include "test_group.cpp" 26 | #include "test_stack.cpp" 27 | #include "test_annotate.cpp" 28 | #include "test_evaluator.cpp" 29 | -------------------------------------------------------------------------------- /src/metaSMT/support/SimpleSymbolTable.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | namespace metaSMT { 8 | namespace support { 9 | struct simple_symbol_table { 10 | static std::map map_; 11 | 12 | std::string operator()(unsigned id) const { 13 | std::map::const_iterator it = map_.find(id); 14 | if ( it == map_.end() ) { 15 | // assert( false && "Invalid read in symbol table" ); 16 | char buf[64]; 17 | sprintf(buf, "var_%u", id); 18 | return buf; 19 | } 20 | return it->second; 21 | } 22 | 23 | template < typename T > 24 | void insert(T const &t, std::string const &name) { 25 | map_.insert(std::make_pair(boost::proto::value(t).id, name)); 26 | } 27 | 28 | std::size_t size() const { 29 | return map_.size(); 30 | } 31 | }; // simple_symbol_table 32 | } // support 33 | } 34 | -------------------------------------------------------------------------------- /src/metaSMT/support/cardinality/object.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace metaSMT { 6 | namespace cardinality { 7 | 8 | template < typename Tag, typename Boolean > 9 | struct Cardinality { 10 | Cardinality( std::vector< Boolean > const &ps, 11 | unsigned const cardinality, 12 | std::string const encoding = "" ) 13 | : ps(ps) 14 | , cardinality(cardinality) 15 | , encoding(encoding) 16 | {} 17 | 18 | std::vector< Boolean > const &ps; 19 | unsigned const cardinality; 20 | std::string const encoding; 21 | }; // Cardinality 22 | 23 | template < typename Tag, typename Boolean > 24 | Cardinality cardinality( 25 | Tag const & 26 | , std::vector< Boolean > const &ps 27 | , unsigned const cardinality 28 | , std::string const encoding = "" ) 29 | { 30 | return Cardinality( ps, cardinality, encoding); 31 | } 32 | 33 | } // cardinality 34 | } // metaSMT 35 | -------------------------------------------------------------------------------- /src/metaSMT/types/BitVector.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace metaSMT { 7 | namespace type { 8 | 9 | struct BitVector { 10 | 11 | unsigned width; 12 | 13 | BitVector() {} 14 | 15 | BitVector(unsigned w) 16 | : width(w) 17 | {} 18 | 19 | template 20 | friend STREAM & operator<< (STREAM & out, BitVector const & self) \ 21 | { return (out << "BitVector [" << self.width <<"]"); } 22 | 23 | }; 24 | 25 | /** equality of BitVector Types **/ 26 | template 27 | typename boost::enable_if< boost::is_same, bool>::type 28 | operator== (BitVector const & a , T const & b) \ 29 | { return a.width==b.width; } 30 | 31 | template 32 | typename boost::disable_if< boost::is_same, bool>::type 33 | operator== (BitVector const & a , T const & b) \ 34 | { return false; } 35 | 36 | } /* type */ 37 | } /* metaSMT */ 38 | -------------------------------------------------------------------------------- /tests/SMT2Parser_SMT2.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_TEST_MODULE SMT2Parser_SMT2 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | using namespace metaSMT; 10 | using namespace metaSMT::solver; 11 | struct Solver_Fixture { 12 | public: 13 | typedef DirectSolver_Context< SMT2 > ContextType; 14 | Solver_Fixture() { 15 | set_option(ctx, "solver_executable", "smt2InputEvaluator_SMT2"); 16 | set_option(ctx, "solver_arguments", ""); 17 | } 18 | ContextType ctx; 19 | }; 20 | 21 | #include "test_solver.cpp" 22 | #include "test_QF_BV.cpp" 23 | //#include "test_QF_UF.cpp" 24 | //#include "test_annotate.cpp" 25 | //#include "test_stack.cpp" 26 | //#include "test_Array.cpp" 27 | //#include "test_Types.cpp" 28 | //#include "test_cardinality.cpp" 29 | //#include "test_optimization.cpp" 30 | //#include "test_expression.cpp" 31 | //#include "test_simplify.cpp" 32 | -------------------------------------------------------------------------------- /tests/SMT2Parser_STP.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_TEST_MODULE SMT2Parser_STP 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | using namespace metaSMT; 10 | using namespace metaSMT::solver; 11 | struct Solver_Fixture { 12 | public: 13 | typedef DirectSolver_Context< SMT2 > ContextType; 14 | Solver_Fixture() { 15 | set_option(ctx, "solver_executable", "smt2InputEvaluator_STP"); 16 | set_option(ctx, "solver_arguments", ""); 17 | } 18 | ContextType ctx; 19 | }; 20 | 21 | #include "test_solver.cpp" 22 | #include "test_QF_BV.cpp" 23 | //#include "test_QF_UF.cpp" 24 | //#include "test_annotate.cpp" 25 | //#include "test_stack.cpp" 26 | //#include "test_Array.cpp" 27 | //#include "test_Types.cpp" 28 | //#include "test_cardinality.cpp" 29 | //#include "test_optimization.cpp" 30 | //#include "test_expression.cpp" 31 | //#include "test_simplify.cpp" 32 | -------------------------------------------------------------------------------- /tests/SMT2Parser_Boolector.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_TEST_MODULE SMT2Parser_Boolector 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | using namespace metaSMT; 10 | using namespace metaSMT::solver; 11 | struct Solver_Fixture { 12 | public: 13 | typedef DirectSolver_Context< SMT2 > ContextType; 14 | Solver_Fixture() { 15 | set_option(ctx, "solver_executable", "smt2InputEvaluator_Boolector"); 16 | set_option(ctx, "solver_arguments", ""); 17 | } 18 | ContextType ctx; 19 | }; 20 | 21 | #include "test_solver.cpp" 22 | #include "test_QF_BV.cpp" 23 | //#include "test_QF_UF.cpp" 24 | //#include "test_annotate.cpp" 25 | //#include "test_stack.cpp" 26 | //#include "test_Array.cpp" 27 | //#include "test_Types.cpp" 28 | //#include "test_cardinality.cpp" 29 | //#include "test_optimization.cpp" 30 | //#include "test_expression.cpp" 31 | //#include "test_simplify.cpp" 32 | -------------------------------------------------------------------------------- /toolbox/smt2Input_evaluator/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_tool_executable( smt2InputEvaluator_Boolector 2 | SOURCES 3 | Boolector_main.cpp 4 | REQUIRES 5 | Boolector_FOUND 6 | ) 7 | 8 | add_tool_executable( smt2InputEvaluator_MiniSAT 9 | SOURCES 10 | MiniSAT_main.cpp 11 | REQUIRES 12 | MiniSat_FOUND 13 | ) 14 | 15 | add_tool_executable( smt2InputEvaluator_PicoSAT 16 | SOURCES 17 | PicoSAT_main.cpp 18 | REQUIRES 19 | PicoSAT_FOUND 20 | ) 21 | 22 | add_tool_executable( smt2InputEvaluator_SMT2 23 | SOURCES 24 | SMT2_main.cpp 25 | REQUIRES 26 | Z3_FOUND 27 | LIBRARIES 28 | ${Boost_IOSTREAMS_LIBRARY} 29 | ) 30 | 31 | add_tool_executable( smt2InputEvaluator_STP 32 | SOURCES 33 | STP_main.cpp 34 | REQUIRES 35 | STP_FOUND 36 | ) 37 | 38 | add_tool_executable( smt2InputEvaluator_SWORD_Backend 39 | SOURCES 40 | SWORD_Backend_main.cpp 41 | REQUIRES 42 | SWORD_FOUND 43 | ) 44 | 45 | add_tool_executable( smt2InputEvaluator_Z3_Backend 46 | SOURCES 47 | Z3_Backend_main.cpp 48 | REQUIRES 49 | Z3_FOUND 50 | ) 51 | -------------------------------------------------------------------------------- /doc/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include_directories(../src) 2 | 3 | include_directories(${metaSMT_INCLUDES}) 4 | 5 | if(DOXYGEN_FOUND) 6 | if(DOXYGEN_DOT_FOUND) 7 | set(DOXYGEN_HAVE_DOT YES) 8 | else(DOXYGEN_DOT_FOUND) 9 | set(DOXYGEN_HAVE_DOT NO) 10 | endif(DOXYGEN_DOT_FOUND) 11 | 12 | 13 | configure_file(Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile) 14 | add_custom_target(doxygen ALL 15 | ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile 16 | WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 17 | SOURCES ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile 18 | ) 19 | 20 | set(doc_name "metaSMT-docs-${metaSMT_VERSION}") 21 | 22 | add_custom_target(package_doxygen 23 | COMMAND ${CMAKE_COMMAND} -E copy_directory html "${doc_name}" 24 | COMMAND ${CMAKE_COMMAND} -E tar zcf "${PROJECT_BINARY_DIR}/${doc_name}.tar.gz" "${doc_name}" 25 | COMMAND ${CMAKE_COMMAND} -E tar jcf "${PROJECT_BINARY_DIR}/${doc_name}.tar.bz2" "${doc_name}" 26 | WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" 27 | DEPENDS doxygen 28 | ) 29 | endif(DOXYGEN_FOUND) 30 | 31 | -------------------------------------------------------------------------------- /tests/SMT2Parser_Z3_Backend.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_TEST_MODULE SMT2Parser_Z3_Backend 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | using namespace metaSMT; 10 | using namespace metaSMT::solver; 11 | struct Solver_Fixture { 12 | public: 13 | typedef DirectSolver_Context< SMT2 > ContextType; 14 | Solver_Fixture() { 15 | set_option(ctx, "solver_executable", "smt2InputEvaluator_Z3_Backend"); 16 | set_option(ctx, "solver_arguments", ""); 17 | } 18 | ContextType ctx; 19 | }; 20 | 21 | #include "test_solver.cpp" 22 | #include "test_QF_BV.cpp" 23 | //#include "test_QF_UF.cpp" 24 | //#include "test_annotate.cpp" 25 | //#include "test_stack.cpp" 26 | //#include "test_Array.cpp" 27 | //#include "test_Types.cpp" 28 | //#include "test_cardinality.cpp" 29 | //#include "test_optimization.cpp" 30 | //#include "test_expression.cpp" 31 | //#include "test_simplify.cpp" 32 | -------------------------------------------------------------------------------- /src/metaSMT/Debug_Context.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Features.hpp" 3 | #include "support/protofy.hpp" 4 | #include 5 | #include 6 | 7 | namespace metaSMT { 8 | 9 | template 10 | struct Debug_Context : Solver {}; 11 | 12 | template 13 | void assertion( Debug_Context & ctx, Expr const & e ) 14 | { 15 | std::printf("DEBUG assertion:\n"); 16 | boost::proto::display_expr(detail::protofy(e)); 17 | metaSMT::assertion( (Solver&) ctx, e ); 18 | } 19 | 20 | template 21 | void assumption( Debug_Context & ctx, Expr const & e ) 22 | { 23 | std::printf("DEBUG assumption:\n"); 24 | boost::proto::display_expr(detail::protofy(e)); 25 | metaSMT::assumption( (Solver&) ctx, e ); 26 | } 27 | 28 | namespace features { 29 | template 30 | struct supports< Debug_Context, Feature> 31 | : supports::type {}; 32 | } 33 | 34 | 35 | } /* metaSMT */ 36 | 37 | -------------------------------------------------------------------------------- /tests/test_group.cpp: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | using namespace std; 11 | using namespace metaSMT; 12 | using namespace metaSMT::solver; 13 | using namespace metaSMT::logic; 14 | namespace proto = boost::proto; 15 | using boost::dynamic_bitset; 16 | 17 | BOOST_FIXTURE_TEST_SUITE(group_, Solver_Fixture ) 18 | 19 | BOOST_AUTO_TEST_CASE( simple_sat ) 20 | { 21 | BOOST_REQUIRE( solve(ctx) ); 22 | // sat 23 | guard_type zero_group = current_group ( ctx ); 24 | 25 | 26 | guard_type main = create_group ( ctx ); 27 | assertion ( ctx, False ); 28 | BOOST_REQUIRE ( !solve(ctx) ); 29 | BOOST_REQUIRE ( !solve(ctx) ); 30 | 31 | change_group ( ctx, zero_group); 32 | delete_group ( ctx, main ); 33 | BOOST_REQUIRE ( solve(ctx) ); 34 | 35 | BOOST_REQUIRE ( current_group ( ctx ) == zero_group ); 36 | 37 | } 38 | 39 | 40 | 41 | 42 | BOOST_AUTO_TEST_SUITE_END() //Solver 43 | 44 | // vim: ft=cpp:ts=2:sw=2:expandtab 45 | -------------------------------------------------------------------------------- /toolbox/metaSMT-server/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "Connection.hpp" 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | namespace asio = boost::asio; 9 | using asio::ip::tcp; 10 | 11 | void server(asio::io_service &io_service) { 12 | int const port = 1313; 13 | tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), port)); 14 | std::cout << "metaSMT-server started" << std::endl; 15 | std::cout << "Listening on port " << port << std::endl; 16 | 17 | for (;;) { 18 | typedef boost::shared_ptr SocketPtr; 19 | SocketPtr sock(new tcp::socket(io_service)); 20 | acceptor.accept(*sock); 21 | boost::thread t(boost::bind(Connection::new_connection, sock)); 22 | } 23 | } 24 | 25 | int main(int argc, const char *argv[]) { 26 | try { 27 | asio::io_service io_service; 28 | server(io_service); 29 | } 30 | catch (std::exception &e) { 31 | std::cerr << e.what() << std::endl; 32 | } 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /src/metaSMT/API/Assertion.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../Features.hpp" 4 | 5 | namespace metaSMT { 6 | struct assertion_cmd { typedef void result_type; }; 7 | 8 | /** 9 | * \brief Assertion API 10 | * 11 | * 12 | * \code 13 | * DirectSolver_Context< Boolector > ctx; 14 | * 15 | * assertion(ctx, True); 16 | * solve(ctx) == true; 17 | * 18 | * assertion(ctx, equal(False, False)) 19 | * solve(ctx) == false; 20 | * \endcode 21 | * \ingroup API 22 | * \defgroup Assertion Assertion 23 | * @{ 24 | */ 25 | 26 | /** 27 | * \brief add an assumption to the current context 28 | * 29 | * \param ctx The metaSMT Context 30 | * \param e Any Boolean expression 31 | */ 32 | template 33 | void assertion( Context_ & ctx, Expr_ const & e ) 34 | { 35 | BOOST_MPL_ASSERT_MSG( 36 | ( features::supports< Context_, assertion_cmd>::value), 37 | context_does_not_support_assertion_api, 38 | () 39 | ); 40 | 41 | ctx.command(assertion_cmd(), evaluate(ctx, e) ); 42 | } 43 | /**@}*/ 44 | } /* metaSMT */ 45 | -------------------------------------------------------------------------------- /src/metaSMT/types/Array.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace metaSMT { 4 | namespace type { 5 | struct Array { 6 | Array() {} 7 | 8 | Array(unsigned elem_width, 9 | unsigned index_width) 10 | : elem_width(elem_width) 11 | , index_width(index_width) 12 | {} 13 | 14 | template 15 | friend STREAM & operator<<(STREAM & out, Array const &self) \ 16 | { return (out << "Array [" << self.elem_width << "," << self.index_width << "]"); } 17 | 18 | unsigned elem_width; 19 | unsigned index_width; 20 | }; 21 | 22 | // equality of Array types 23 | template 24 | typename boost::enable_if< boost::is_same, bool>::type 25 | operator== (type::Array const &a , T const &b) \ 26 | { return a.elem_width == b.elem_width && a.index_width == b.index_width; } 27 | 28 | template 29 | typename boost::disable_if< boost::is_same, bool>::type 30 | operator== (type::Array const &a , T const &b) \ 31 | { return false; } 32 | 33 | } // type 34 | } // metaSMT 35 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- 1 | ChangeLog 2 | =========== 3 | 4 | metaSMT 2 -> 3 5 | ---------------- 6 | 7 | * Better integration with CMake find_package 8 | * Extended API support 9 | * SymbolTable: Custom names for variables (SMT2 output) 10 | * AssignRandomBits: select a random subset of bits from BitVector 11 | variables and assign a random value 12 | * SAT API (add_clause): directly add clauses to the backend 13 | * Type Descriptors and TypedSymbols (Boolean, BitVector) 14 | * Preliminary support for QF_UF (only unary functions) 15 | * Portfolio and Priority Multi-Threaded solving 16 | * toolbox example N-Queens using cardinality constraints 17 | * toolbox contains a CNF solver 18 | 19 | 20 | metaSMT 1 -> 2 21 | ---------------- 22 | 23 | Bugfixes: 24 | 25 | * Fixed 2 bug in BitBlast constant handling (wrong bit order, overflow) 26 | * Fixed memory leak in Boolector backend 27 | * Disabled Copy Constructor of DirectSolver 28 | 29 | Other changes: 30 | 31 | * further work on the FMI frontend 32 | * Refactored assertion, assumption to use "command"-API, moved to separate 33 | headers 34 | * fixes and enhancements to the build system and bootstrap script 35 | 36 | -------------------------------------------------------------------------------- /src/lib/doxy.cpp: -------------------------------------------------------------------------------- 1 | // doxygen definition that do not fit outside 2 | // 3 | // 4 | 5 | /** 6 | * @defgroup Backend Backends 7 | * @brief metaSMT backends (solvers) 8 | */ 9 | 10 | /** 11 | * @defgroup API API 12 | * @brief metaSMT API functions and classes 13 | * 14 | * APIs provide mechanisms to access native backend features or 15 | * easy to use abstractions. 16 | * 17 | */ 18 | 19 | /** 20 | * @defgroup Support Support 21 | * @brief tools and helpers 22 | **/ 23 | 24 | /** 25 | * @defgroup Frontend Frontend 26 | * @brief metaSMT input languages 27 | **/ 28 | 29 | 30 | /** 31 | * \mainpage metaSMT 32 | * 33 | * \section Installation 34 | * 35 | * Please see the current README distributed with metaSMT for instructions 36 | * on how to build and install metaSMT. 37 | * 38 | * \section structure How metaSMT is structured 39 | * 40 | * metaSMT is structured in several basic components. An overview is given on 41 | * the Modules page. 42 | * 43 | * metaSMT leaves the control at the programmer, you can decide which features 44 | * and which backend (solver) to use. 45 | * 46 | **/ 47 | 48 | 49 | // vim: ts=2 sw=2 et tw=76 50 | -------------------------------------------------------------------------------- /tests/direct_Boolector.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_TEST_MODULE direct_Boolector 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | using namespace metaSMT::solver; 12 | using namespace metaSMT; 13 | struct Solver_Fixture { 14 | typedef DirectSolver_Context< AssignRandomBits< IgnoreSymbolTable< IgnoreComments< Group < Stack < Boolector > > > > > > ContextType; 15 | ContextType ctx ; 16 | }; 17 | 18 | #include "test_solver.cpp" 19 | #include "test_QF_BV.cpp" 20 | #include "test_Array.cpp" 21 | #include "test_group.cpp" 22 | #include "test_stack.cpp" 23 | #include "test_unsat.cpp" 24 | #include "test_fmi.cpp" 25 | #include "test_cardinality.cpp" 26 | #include "test_optimization.cpp" 27 | #include "test_lazy.cpp" 28 | #include "test_annotate.cpp" 29 | #include "test_Types.cpp" 30 | #include "test_random_bits.cpp" 31 | #include "test_simplify.cpp" 32 | #include "test_evaluator.cpp" 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011 The metaSMT developers 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /src/metaSMT/API/Assumption.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../Features.hpp" 4 | 5 | namespace metaSMT { 6 | struct assumption_cmd { typedef void result_type; }; 7 | 8 | /** 9 | * \brief Assumption API, one-time Assertions 10 | * 11 | * 12 | * \code 13 | * DirectSolver_Context< Boolector > ctx; 14 | * 15 | * assumption(ctx, False); 16 | * solve(ctx) == false; 17 | * // solve was called, assumption no longer valid 18 | * 19 | * solve(ctx) == true; 20 | * \endcode 21 | * \ingroup API 22 | * \defgroup Assumption Assumption 23 | * @{ 24 | */ 25 | 26 | /** 27 | * \brief add an assumption to the current context 28 | * 29 | * \param ctx The metaSMT Context 30 | * \param e Any Boolean expression 31 | */ 32 | template 33 | void assumption( Context_ & ctx, Expr_ const & e ) 34 | { 35 | BOOST_MPL_ASSERT_MSG( 36 | ( features::supports< Context_, assumption_cmd>::value), 37 | context_does_not_support_assumption_api, 38 | () 39 | ); 40 | 41 | ctx.command(assumption_cmd(), evaluate(ctx, e) ); 42 | } 43 | /**@}*/ 44 | } /* metaSMT */ 45 | -------------------------------------------------------------------------------- /bindings/python/python_config.hxx.in: -------------------------------------------------------------------------------- 1 | #ifndef PYTHON_CONFIG_HXX_H 2 | 3 | #define PYTHON_CONFIG_HXX_H 4 | 5 | #define ENABLE_SOLVER_SWORD ${ENABLE_SOLVER_SWORD} 6 | #define ENABLE_SOLVER_BOOLECTOR ${ENABLE_SOLVER_BOOLECTOR} 7 | 8 | #define ENABLE_SOLVER_Z3 ${ENABLE_SOLVER_Z3} 9 | 10 | // z3 2.18 needs to be available at runtime 11 | #define ENABLE_SOLVER_Z3_EXECUTABLE 1 12 | 13 | #define ENABLE_SOLVER_SMT2 ${ENABLE_SOLVER_SMT2} 14 | 15 | #define ENABLE_SOLVER_CUDD ${ENABLE_SOLVER_CUDD} 16 | #define ENABLE_SOLVER_MINISAT ${ENABLE_SOLVER_MINISAT} 17 | 18 | #define ENABLE_SOLVER_AIGER ${ENABLE_SOLVER_AIGER} 19 | 20 | #define ENABLE_SOLVER_PICOSAT ${ENABLE_SOLVER_PICOSAT} 21 | #define ENABLE_SOLVER_GLUCOSER ${ENABLE_SOLVER_GLUCOSER} 22 | #define ENABLE_SOLVER_MINISAT_EXECUTABLE ${ENABLE_SOLVER_MINISAT_EXECUTABLE} 23 | #define ENABLE_SOLVER_PICOSAT_EXECUTABLE ${ENABLE_SOLVER_PICOSAT_EXECUTABLE} 24 | #define ENABLE_SOLVER_PLINGELING_EXECUTABLE ${ENABLE_SOLVER_PLINGELING_EXECUTABLE} 25 | #define ENABLE_SOLVER_PRECOSAT_EXECUTABLE ${ENABLE_SOLVER_PRECOSAT_EXECUTABLE} 26 | 27 | #define ENABLE_SOLVER_CONSTRAINT ${ENABLE_SOLVER_CONSTRAINT} 28 | 29 | #endif /* end of include guard: PYTHON_CONFIG_HXX_H */ 30 | -------------------------------------------------------------------------------- /cmake/library_rpath.cmake: -------------------------------------------------------------------------------- 1 | 2 | # Generate an RPATH from all the libraries used by metaSMT. 3 | # If the library is a file use its directory, 4 | # if the library is a target use its location and recurse on 5 | # its dependencies. 6 | 7 | macro( _recursive_collect_rpath ) 8 | foreach( lib ${ARGN}) 9 | if(EXISTS ${lib}) 10 | get_filename_component(libdir ${lib} PATH) 11 | list(APPEND _rpath ${libdir}) 12 | elseif(TARGET ${lib}) 13 | get_target_property(libpath ${lib} LOCATION) 14 | get_filename_component(libdir ${libpath} PATH) 15 | list(APPEND _rpath ${libdir}) 16 | get_target_property(dependent ${lib} IMPORTED_LINK_INTERFACE_LIBRARIES) 17 | _recursive_collect_rpath(${dependent}) 18 | get_target_property(dependent ${lib} IMPORTED_LINK_INTERFACE_LIBRARIES_RELEASE) 19 | _recursive_collect_rpath(${dependent}) 20 | endif() 21 | endforeach() 22 | endmacro( ) 23 | 24 | function(add_dependent_libraries) 25 | set( _rpath "") 26 | 27 | _recursive_collect_rpath( ${ARGN} ) 28 | 29 | list( SORT _rpath ) 30 | list( REMOVE_DUPLICATES _rpath ) 31 | 32 | set( CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_RPATH} ${_rpath} PARENT_SCOPE) 33 | endfunction() 34 | 35 | -------------------------------------------------------------------------------- /src/metaSMT/API/Simplify.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../Features.hpp" 4 | 5 | namespace metaSMT { 6 | // Note that void is not a valid result_type, i.e., simplify will 7 | // fail when a graph solver is used. 8 | struct simplify_cmd { typedef void result_type; }; 9 | 10 | /** 11 | * \brief simplify function 12 | * \param ctx The context to work on 13 | * \param e expression to be simplified 14 | * \return simplified expression 15 | * 16 | */ 17 | template 18 | typename boost::enable_if< 19 | features::supports 20 | , typename Context::result_type 21 | >::type 22 | simplify( Context &ctx, Expr const &e ) { 23 | return ctx.command(simplify_cmd(), evaluate(ctx, e) ); 24 | } 25 | 26 | /** \cond */ 27 | // return the original expression if simplify is unsupported 28 | template 29 | typename boost::disable_if< 30 | features::supports 31 | , typename Context::result_type 32 | >::type 33 | simplify( Context &ctx, Expr const &e ) { 34 | return evaluate(ctx, e); 35 | } 36 | /** \endcond **/ 37 | 38 | /**@}*/ 39 | 40 | } /* metaSMT */ 41 | -------------------------------------------------------------------------------- /toolbox/metaSMT-server/Connection.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Solver.hpp" 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | class Connection { 10 | public: 11 | typedef boost::shared_ptr SocketPtr; 12 | typedef std::vector Solvers; 13 | 14 | public: 15 | static void new_connection(SocketPtr socket); 16 | 17 | public: 18 | Connection(SocketPtr socket); 19 | 20 | private: 21 | std::string getLine(); 22 | void write(std::string string); 23 | void terminateSolver(SolverProcess *solver); 24 | 25 | void setupSolvers(); 26 | bool createSolverProcesses(); 27 | SolverProcess *findFastestSolver(); 28 | std::string getValue(); 29 | std::string checkSat(); 30 | void processCommandsLoop(); 31 | void checkTimeout(); 32 | void skipAnswers(int level); 33 | bool wasSAT; 34 | 35 | private: 36 | SocketPtr socket; 37 | boost::asio::streambuf buffer; 38 | Solvers solvers; 39 | SolverProcess* preferredSolver; 40 | bool timeoutEnabled; 41 | int timeoutThreshold; 42 | timeval startTime; 43 | timeval checkSatStartTime; 44 | }; // Connection 45 | -------------------------------------------------------------------------------- /src/metaSMT/support/parser/UTreeToString.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | namespace metaSMT { 7 | namespace evaluator { 8 | inline std::string utreeToString(boost::spirit::utree const tree) { 9 | std::stringstream ss; 10 | ss << tree; 11 | std::string output = ss.str(); 12 | 13 | std::size_t found = output.find("\""); 14 | while (found != output.npos) { 15 | output.erase(found, 1); 16 | found = output.find("\""); 17 | } 18 | found = output.find(" "); 19 | while (found != output.npos) { 20 | output.erase(found, 1); 21 | found = output.find(" "); 22 | } 23 | 24 | if ( output == "(" || output == ")" ) { 25 | return output; 26 | } 27 | 28 | found = output.find("("); 29 | while (found != output.npos) { 30 | output.erase(found, 1); 31 | found = output.find("("); 32 | } 33 | found = output.find(")"); 34 | while (found != output.npos) { 35 | output.erase(found, 1); 36 | found = output.find(")"); 37 | } 38 | return output; 39 | } 40 | } // evaluator 41 | } // metaSMT 42 | -------------------------------------------------------------------------------- /toolbox/metaSMT-server/SolverProcess.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class SolverProcess; 5 | 6 | class SolverBase { 7 | public: 8 | virtual void start() = 0; 9 | virtual ~SolverBase() {}; 10 | 11 | static const std::string success; 12 | static const std::string unsupported; 13 | static const std::string error; 14 | 15 | static const std::string sat; 16 | static const std::string unsat; 17 | static const std::string unknown; 18 | // protected: 19 | SolverProcess *sp; 20 | }; // SolverBase 21 | 22 | class SolverProcess { 23 | public: 24 | SolverProcess(std::string const &solver_type); 25 | ~SolverProcess(); 26 | 27 | int initPipes(); 28 | 29 | std::string child_read_command(); 30 | void child_write_command(std::string s); 31 | 32 | bool parent_read_command_available(); 33 | std::string parent_read_command(); 34 | void parent_write_command(std::string s); 35 | 36 | SolverBase *sb; 37 | std::string solver_type; 38 | int num_answers; 39 | pid_t pid; 40 | 41 | public: // private: 42 | int fd_p2c[2]; 43 | int fd_c2p[2]; 44 | 45 | std::string p2c_read_command; 46 | 47 | std::string read_command(int fd); 48 | void write_command(int fd, std::string s); 49 | }; // SolverProcess 50 | -------------------------------------------------------------------------------- /toolbox/metaSMT-server/create_solver.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Solver_Name_Map.hpp" 3 | #include "SolverProcess.hpp" 4 | 5 | namespace detail { 6 | struct CreateSolverBase 7 | : public boost::static_visitor { 8 | public: 9 | CreateSolverBase(bool &found, 10 | SolverBase *&solver, 11 | std::string const &name) 12 | : found(found) 13 | , solver(solver) 14 | , name(name) 15 | {} 16 | 17 | template < typename Pair > 18 | void operator()( Pair const & ) { 19 | typedef typename Pair::first Name; 20 | typedef typename Pair::second BackendType; 21 | if ( !found && boost::mpl::c_str::value == name ) { 22 | solver = new Solver(); 23 | found = true; 24 | } 25 | } 26 | 27 | bool &found; 28 | SolverBase *&solver; 29 | std::string name; 30 | }; // CreateSolverBase 31 | } // detail 32 | 33 | static SolverBase *create_solver(std::string const &name) { 34 | bool found = false; 35 | SolverBase *solver = 0; 36 | detail::CreateSolverBase vis(found, solver, name); 37 | boost::mpl::for_each(vis); 38 | assert( found && "Undefined solver mapping" ); 39 | return solver; 40 | } 41 | -------------------------------------------------------------------------------- /toolbox/sortnets/Main.hpp: -------------------------------------------------------------------------------- 1 | #include "SortNetSynth.hpp" 2 | 3 | #include 4 | 5 | #include 6 | 7 | template 8 | class Main 9 | { 10 | public: 11 | Main(int argc, const char** argv) 12 | : argc(argc) 13 | , argv(argv) 14 | { 15 | } 16 | 17 | int run() 18 | { 19 | if (argc < 3) { 20 | return usage(); 21 | } 22 | 23 | unsigned min_depth = atoi ( argv[1] ); 24 | 25 | std::vector inits; 26 | for (int i = 2; i < argc; ++i) 27 | { 28 | inits.push_back(argv[i]); 29 | } 30 | 31 | SortNetSynth synth(min_depth, inits); 32 | 33 | synth(); 34 | 35 | std::cout 36 | << boost::format("Synthesis Time: %6.2fs\n") % synth.time_synth 37 | << boost::format("Verification Time: %6.2fs\n") % synth.time_verify; 38 | 39 | return 0; 40 | } 41 | 42 | private: 43 | int usage() 44 | { 45 | std::cout 46 | << "usage: "<< argv[0] 47 | << " [...]" 48 | << std::endl; 49 | return 1; 50 | } 51 | 52 | private: 53 | int argc; 54 | const char** argv; 55 | }; 56 | 57 | -------------------------------------------------------------------------------- /src/metaSMT/tags/Cardinality.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "attribute.hpp" 4 | #include 5 | #include 6 | 7 | namespace metaSMT { 8 | namespace logic { 9 | namespace cardinality { 10 | namespace tag { 11 | 12 | #define PRINT(Tag, body) template \ 13 | friend STREAM & operator<< (STREAM & out, Tag const & self) \ 14 | { out << body; return out; } 15 | #define TAG( NAME, ATTR ) struct NAME##_tag { \ 16 | typedef attr::ATTR attribute; \ 17 | bool operator<(NAME##_tag const &) const {return false;} \ 18 | PRINT(NAME##_tag, #NAME) \ 19 | }; 20 | 21 | TAG(lt, nary) 22 | TAG(le, nary) 23 | TAG(eq, nary) 24 | TAG(ge, nary) 25 | TAG(gt, nary) 26 | 27 | #undef PRINT 28 | #undef TAG 29 | 30 | // tag variant Cardinality_Tags 31 | typedef boost::mpl::vector< 32 | lt_tag 33 | , le_tag 34 | , eq_tag 35 | , ge_tag 36 | , gt_tag 37 | >::type Cardinality_Tags; 38 | 39 | typedef boost::make_variant_over< Cardinality_Tags >::type Cardinality_Tag; 40 | 41 | } // namespace cardinality 42 | } // namespace tag 43 | } // namespace logic 44 | } // namespace metaSMT 45 | 46 | // vim: ft=cpp:ts=2:sw=2:expandtab 47 | -------------------------------------------------------------------------------- /src/metaSMT/support/GoTmp.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | 6 | namespace metaSMT { 7 | 8 | struct GoTmp { 9 | GoTmp () 10 | : prevPath(boost::filesystem::current_path()) 11 | , path() 12 | { 13 | 14 | if ( tryDir("/dev/shm") ) { 15 | // we are done, use ramdisk 16 | } else if( tryDir( boost::filesystem::temp_directory_path()) ) { 17 | // done, use /tmp 18 | } else { 19 | // currend dir should always work 20 | tryDir( prevPath ); 21 | } 22 | boost::filesystem::current_path(path); 23 | 24 | } 25 | 26 | ~GoTmp() { 27 | boost::filesystem::current_path(prevPath); 28 | boost::filesystem::remove_all(path); 29 | } 30 | 31 | private: 32 | bool tryDir(boost::filesystem::path dir) { 33 | try { 34 | if (is_directory(dir)) { 35 | dir /= "metaSMT-%%%%%%"; 36 | boost::filesystem::create_directory(path); 37 | return true; 38 | } 39 | } catch (std::exception &) { 40 | // fallback to false 41 | } 42 | return false; 43 | } 44 | 45 | private: 46 | boost::filesystem::path prevPath; 47 | boost::filesystem::path path; 48 | }; 49 | 50 | } /* metaSMT */ 51 | -------------------------------------------------------------------------------- /cmake/build_type.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Add the build_type "Profiling", that 3 | # * enables gcov profiling 4 | # * enables -Wall (all warnings) 5 | # * disables optimizations 6 | # for GCC or compatible compilers 7 | # 8 | 9 | SET( CMAKE_CXX_FLAGS_PROFILING "-O0 -g -Wall -fprofile-arcs -ftest-coverage" CACHE STRING 10 | "Flags used by the C++ compiler during profiling builds." 11 | FORCE ) 12 | SET( CMAKE_C_FLAGS_PROFILING "-O0 -g -Wall -fprofile-arcs -ftest-coverage" CACHE STRING 13 | "Flags used by the C compiler during profiling builds." 14 | FORCE ) 15 | SET( CMAKE_EXE_LINKER_FLAGS_PROFILING 16 | "-fprofile-arcs -ftest-coverage" CACHE STRING 17 | "Flags used for linking binaries during profiling builds." 18 | FORCE ) 19 | SET( CMAKE_SHARED_LINKER_FLAGS_PROFILING 20 | "-fprofile-arcs -ftest-coverage" CACHE STRING 21 | "Flags used by the shared libraries linker during profiling builds." 22 | FORCE ) 23 | MARK_AS_ADVANCED( 24 | CMAKE_CXX_FLAGS_PROFILING 25 | CMAKE_C_FLAGS_PROFILING 26 | CMAKE_EXE_LINKER_FLAGS_PROFILING 27 | CMAKE_SHARED_LINKER_FLAGS_PROFILING ) 28 | # Update the documentation string of CMAKE_BUILD_TYPE for GUIs 29 | SET( CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}" CACHE STRING 30 | "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel Profiling." 31 | FORCE ) 32 | 33 | -------------------------------------------------------------------------------- /src/metaSMT/support/optimization/minimize.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "detail.hpp" 4 | #include "../cardinality.hpp" 5 | 6 | namespace metaSMT { 7 | namespace optimization { 8 | template < typename Context, typename Boolean > 9 | unsigned minimize( Context &ctx, std::vector const &ps, 10 | unsigned min, unsigned max ) { 11 | unsigned mid = max, last_mid = max; 12 | bool sat = false; 13 | while ( min <= max ) { 14 | mid = min + ((max - min) >> 1); 15 | assumption(ctx, cardinality_leq(ctx, ps, mid)); 16 | sat = solve(ctx); 17 | if ( sat ) { 18 | unsigned const witness = detail::countOnes(ctx, ps); 19 | if ( witness <= min ) return min; 20 | max = witness - 1; 21 | last_mid = witness; 22 | } 23 | else { 24 | min = mid + 1; 25 | } 26 | } 27 | return last_mid; 28 | } 29 | 30 | template < typename Context, typename Boolean > 31 | unsigned minimize( Context &ctx, std::vector const &ps, 32 | unsigned min = 0 ) { 33 | unsigned const upper_bound = detail::countOnes(ctx, ps); 34 | assert( upper_bound <= ps.size() ); 35 | return minimize(ctx, ps, min, upper_bound); 36 | } 37 | } // optimization 38 | } // metaSMT 39 | -------------------------------------------------------------------------------- /src/metaSMT/support/disable_warnings.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This header may be included before including system or library headers that 3 | * emits an warning. 4 | * 5 | * IMPORTANT: Do not forget to include enable_warnings.hpp after including the 6 | * external headers to re-enable warnings again. 7 | */ 8 | #ifdef __clang__ 9 | #define _BACKWARD_BACKWARD_WARNING_H 10 | #pragma clang diagnostic push 11 | #pragma clang diagnostic ignored "-Wstrict-aliasing" 12 | #pragma clang diagnostic ignored "-Wunused-variable" 13 | #pragma clang diagnostic ignored "-Wreturn-type" 14 | #pragma clang diagnostic ignored "-Wsign-compare" 15 | #pragma clang diagnostic ignored "-Wunknown-pragmas" 16 | #pragma clang diagnostic ignored "-Wdelete-non-virtual-dtor" 17 | #pragma clang diagnostic ignored "-Wparentheses-equality" 18 | #pragma clang diagnostic ignored "-Wlogical-op-parentheses" 19 | #endif 20 | 21 | 22 | #ifdef __GNUC__ 23 | # if __GNUC__ >= 4 and __GNUC_MINOR__ > 4 24 | // with this definitions gcc 4.4 creates executables with random segfaults 25 | #define _BACKWARD_BACKWARD_WARNING_H 26 | #pragma GCC push_options 27 | #pragma GCC diagnostic ignored "-Wstrict-aliasing" 28 | #pragma GCC diagnostic ignored "-Wunused-variable" 29 | #pragma GCC diagnostic ignored "-Wreturn-type" 30 | #pragma GCC diagnostic ignored "-Wsign-compare" 31 | #pragma GCC diagnostic ignored "-Wparentheses" 32 | #endif 33 | #endif 34 | 35 | -------------------------------------------------------------------------------- /bindings/python/examples/rect.py: -------------------------------------------------------------------------------- 1 | from metasmt.core import * 2 | from metasmt.operators import * 3 | 4 | class rectangle(object): 5 | def __init__(self, limit, bw): 6 | self.bw = bw 7 | self.limit = bv_uint(limit)[bw] 8 | self.xpos = new_bitvector(bw) 9 | self.ypos = new_bitvector(bw) 10 | self.xwid = new_bitvector(bw) 11 | self.yhei = new_bitvector(bw) 12 | 13 | def to_logic_expression(self): 14 | lim = self.limit 15 | return reduce(logic_and, ( 16 | self.xpos + self.xwid <= lim, 17 | self.ypos + self.yhei <= lim, 18 | self.xwid > bv_uint(0)[self.bw], 19 | self.yhei > bv_uint(0)[self.bw], 20 | )) 21 | 22 | def print_solution(self, solver): 23 | print ( 24 | solver[self.xpos], 25 | solver[self.ypos], 26 | solver[self.xwid], 27 | solver[self.yhei], 28 | ) 29 | 30 | 31 | def main(): 32 | for name, sc in available_solvers().items(): 33 | try: 34 | rect = rectangle(5,4) 35 | print "testing solver", name 36 | solver = sc() 37 | solver &= rect.to_logic_expression() 38 | for i in xrange(5): 39 | if solver.solve(): 40 | rect.print_solution(solver) 41 | else: 42 | print "no rect found" 43 | 44 | except Exception as e: 45 | print "error in solver", name 46 | print e 47 | 48 | if __name__ == '__main__': 49 | main() 50 | 51 | -------------------------------------------------------------------------------- /src/metaSMT/UnpackFuture_Context.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Features.hpp" 4 | 5 | #include "support/disable_warnings.hpp" 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "support/enable_warnings.hpp" 11 | 12 | namespace metaSMT { 13 | 14 | /** 15 | * @brief direct Solver integration 16 | * 17 | * DirectSolver_Context takes a SolverType and directly feeds all commands 18 | * to it. Variable expressions are cached and only evaluated once. 19 | **/ 20 | template 21 | struct UnpackFuture_Context 22 | : SolverContext 23 | { 24 | UnpackFuture_Context() {} 25 | 26 | /// The returned expression type is the result_type of the SolverContext 27 | typedef typename SolverContext::result_type result_type; 28 | 29 | result_type operator() (boost::shared_future e, boost::any const & any) { 30 | return e.get(); 31 | } 32 | 33 | using SolverContext::command; 34 | using SolverContext::operator(); 35 | 36 | }; 37 | 38 | namespace features { 39 | template 40 | struct supports< UnpackFuture_Context, Feature> 41 | : supports::type {}; 42 | } 43 | 44 | 45 | } // namespace metaSMT 46 | 47 | // vim: ft=cpp:ts=2:sw=2:expandtab 48 | -------------------------------------------------------------------------------- /src/metaSMT/API/Options.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../Features.hpp" 4 | 5 | namespace metaSMT { 6 | struct setup_option_map_cmd { typedef void result_type; }; 7 | struct get_option_cmd { typedef std::string result_type; }; 8 | struct set_option_cmd { typedef void result_type; }; 9 | 10 | template 11 | std::string get_option( Context_ &ctx, std::string const &key ) { 12 | BOOST_MPL_ASSERT_MSG( 13 | ( features::supports::value ) 14 | , context_does_not_support_get_option_api 15 | , () 16 | ); 17 | return ctx.command(get_option_cmd(), key ); 18 | } 19 | 20 | template 21 | std::string get_option( Context_ &ctx, std::string const &key, std::string const &default_value ) { 22 | BOOST_MPL_ASSERT_MSG( 23 | ( features::supports::value ) 24 | , context_does_not_support_get_option_api 25 | , () 26 | ); 27 | return ctx.command(get_option_cmd(), key, default_value ); 28 | } 29 | 30 | template 31 | void set_option( Context_ &ctx, std::string const &key, std::string const &value ) { 32 | BOOST_MPL_ASSERT_MSG( 33 | ( features::supports::value ) 34 | , context_does_not_support_set_option_api 35 | , () 36 | ); 37 | ctx.command(set_option_cmd(), key, value ); 38 | } 39 | } // metaSMT 40 | -------------------------------------------------------------------------------- /tests/direct_Threaded_SWORD.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_TEST_MODULE direct_Threaded_SWORD 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | using namespace metaSMT::solver; 11 | using namespace metaSMT; 12 | struct Solver_Fixture { 13 | typedef DirectSolver_Context< UnpackFuture_Context< Stack< SWORD_Backend > > > ContextType1; 14 | typedef Threaded_Context< ContextType1, ContextType1 > ContextType; 15 | ContextType ctx ; 16 | }; 17 | 18 | namespace std { 19 | //std::ostream & operator<< (std::ostream & o, Solver_Fixture::ContextType::result_type const & r) { 20 | // return (o << "(Threaded result_type " << &r << ")"); 21 | //} 22 | template 23 | std::ostream & operator<< (std::ostream & o, boost::shared_future const & f) { 24 | return (o << "(shared_future@" << &f << ")"); 25 | } 26 | } /* std */ 27 | 28 | #include "test_solver.cpp" 29 | #include "test_QF_BV.cpp" 30 | //#include "test_Array.cpp" 31 | //#include "test_group.cpp" 32 | #include "test_stack.cpp" 33 | #include "test_unsat.cpp" 34 | #include "test_fmi.cpp" 35 | //#include "test_cardinality.cpp" 36 | #include "test_lazy.cpp" 37 | //#include "test_annotate.cpp" 38 | -------------------------------------------------------------------------------- /toolbox/smt2Input_evaluator/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | using namespace metaSMT; 8 | using namespace metaSMT::solver; 9 | using namespace metaSMT::evaluator; 10 | using namespace metaSMT::smt2; 11 | 12 | int main(int argc, char **argv) { 13 | ContextType ctx; 14 | for ( OptionMap::const_iterator it = options.begin(), ie = options.end(); 15 | it != ie; ++it ) { 16 | set_option(ctx, it->first, it->second); 17 | } 18 | 19 | typedef UTreeEvaluator Evaluator; 20 | Evaluator evaluator(ctx); 21 | SMT2Parser parser(evaluator); 22 | 23 | stringstream *buf = new stringstream; 24 | string line; 25 | while( !cin.eof() ){ 26 | std::getline(std::cin, line); 27 | if ( std::cin.fail() ) { 28 | // stream end without exit or read error 29 | return 0; 30 | } 31 | 32 | // std::cerr << line << '\n'; 33 | *buf << line << endl; 34 | size_t found = line.find("(get-value"); 35 | if (line == "(check-sat)" || found != line.npos) { 36 | boost::spirit::utree::list_type ast; 37 | parser.parse(*buf, ast); 38 | evaluator.evaluateInstance(ast); 39 | delete buf; 40 | buf = new stringstream; 41 | } 42 | 43 | if ( line == "(exit)" ) { 44 | break; 45 | } 46 | } 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /toolbox/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file(GLOB toolbox_entries ${CMAKE_CURRENT_SOURCE_DIR}/*/) 2 | 3 | 4 | ## helper funtion to conditionally build a tool 5 | function (add_tool_executable name ) 6 | cmake_parse_arguments(_req "" "" "SOURCES;REQUIRES;PROPERTIES;ARGS;LIBRARIES;ENV" ${ARGN}) 7 | 8 | set(_req_all 1) 9 | 10 | foreach( _req ${_req_REQUIRES} ) 11 | if(NOT ${_req} ) 12 | set(_req_all 0) 13 | endif(NOT ${_req} ) 14 | endforeach( _req ) 15 | 16 | if(_req_all) 17 | add_executable(${name} ${_req_SOURCES}) 18 | target_link_libraries(${name} metaSMT) 19 | if(_req_LIBRARIES) 20 | target_link_libraries(${name} ${_req_LIBRARIES}) 21 | endif() 22 | if(_req_PROPERTIES) 23 | set_target_properties(${name} PROPERTIES ${_req_PROPERTIES}) 24 | endif() 25 | 26 | set(${name}_ENABLED TRUE PARENT_SCOPE) 27 | endif(_req_all) 28 | endfunction(add_tool_executable) 29 | 30 | include_directories(${metaSMT_SOURCE_DIR}/src ${metaSMT_INCLUDES}) 31 | add_definitions(${metaSMT_CXXFLAGS}) 32 | 33 | foreach(entry ${toolbox_entries}) 34 | if(IS_DIRECTORY ${entry}) 35 | get_filename_component(_name ${entry} NAME) 36 | if(EXISTS ${entry}/CMakeLists.txt) 37 | add_subdirectory(${entry}) 38 | else() 39 | file(GLOB _sources ${entry}/*.cc ${entry}/*.cpp) 40 | if( _sources ) 41 | add_tool_executable(${_name}.auto SOURCES ${_sources}) 42 | endif() 43 | endif() 44 | endif() 45 | endforeach(${entry}) 46 | -------------------------------------------------------------------------------- /tests/test_SAT.cpp: -------------------------------------------------------------------------------- 1 | #define BOOST_TEST_MODULE test_sat 2 | #include 3 | 4 | //internal includes 5 | #include 6 | #include 7 | #include 8 | 9 | //external includes 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | using namespace metaSMT; 16 | 17 | class sat_Fixture { 18 | protected: 19 | }; 20 | 21 | using SAT::variable; 22 | using SAT::new_variable; 23 | using boost::proto::display_expr; 24 | 25 | //template< typename Context, typename Expr > 26 | //typename boost::result_of< transform::satClause( Expr )>::type 27 | //evaluate ( Context const & , Expr const & ) { 28 | // return boost::result_of< transform::satClause( Expr )>::type::value; 29 | //} 30 | 31 | BOOST_FIXTURE_TEST_SUITE(sat_t, sat_Fixture ) 32 | 33 | BOOST_AUTO_TEST_CASE( syntax ) 34 | { 35 | SAT::variable x=new_variable(), y=new_variable(), z=new_variable(); 36 | 37 | display_expr( 38 | x + !y + !~z 39 | ); 40 | 41 | std::cout << transform::satClauseArity() ( 42 | x+!y+!~z 43 | ) << std::endl; 44 | 45 | 46 | display_expr( 47 | x+ y + (-z) 48 | ); 49 | 50 | std::cout << transform::satClause() ( 51 | x + y + -(-(-z)) 52 | ) << std::endl; 53 | 54 | } 55 | 56 | BOOST_AUTO_TEST_SUITE_END() //QF_BV 57 | 58 | // vim: ft=cpp:ts=2:sw=2:expandtab 59 | -------------------------------------------------------------------------------- /src/metaSMT/support/optimization/maximize.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "detail.hpp" 4 | #include "../cardinality.hpp" 5 | 6 | namespace metaSMT { 7 | namespace optimization { 8 | template < typename Context, typename Boolean > 9 | unsigned maximize( Context &ctx, std::vector const &ps, 10 | unsigned min, unsigned max ) { 11 | unsigned mid = min, last_mid = min; 12 | bool sat = false; 13 | while ( max >= min ) { 14 | mid = min + ((max - min) >> 1); 15 | assumption(ctx, cardinality_geq(ctx, ps, mid)); 16 | sat = solve(ctx); 17 | if ( sat ) { 18 | unsigned const witness = detail::countOnes(ctx, ps); 19 | min = witness + 1; 20 | last_mid = witness; 21 | } 22 | else { 23 | max = mid - 1; 24 | } 25 | } 26 | return last_mid; 27 | } 28 | 29 | template < typename Context, typename Boolean > 30 | unsigned maximize( Context &ctx, std::vector const &ps, 31 | unsigned max ) { 32 | unsigned const lower_bound = detail::countOnes(ctx, ps); 33 | assert( lower_bound >= 0 ); 34 | return maximize(ctx, ps, lower_bound, max); 35 | } 36 | 37 | template < typename Context, typename Boolean > 38 | unsigned maximize( Context &ctx, std::vector const &ps ) { 39 | return maximize(ctx, ps, ps.size()); 40 | } 41 | } // optimization 42 | } // metaSMT 43 | -------------------------------------------------------------------------------- /src/metaSMT/tags/QF_UF.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifndef HEADER_metaSMT_TAG_QF_UF_HPP 3 | #define HEADER_metaSMT_TAG_QF_UF_HPP 4 | 5 | #include "Logic.hpp" 6 | #include "../types/Types.hpp" 7 | 8 | #include 9 | #include 10 | 11 | namespace metaSMT { 12 | namespace logic { 13 | namespace QF_UF { 14 | namespace tag { 15 | 16 | #define PRINT(Tag, body) template \ 17 | friend STREAM & operator<< (STREAM & out, Tag const & self) \ 18 | { return (out << body); } 19 | 20 | // uninterpreted function variable tag 21 | struct function_var_tag { 22 | typedef attr::ignore attribute; 23 | 24 | unsigned id; 25 | type::any_type result_type; 26 | std::vector args; 27 | 28 | PRINT(function_var_tag, "function_var_tag[" << self.id << "]") 29 | bool operator< (function_var_tag const & other) const { 30 | return id < other.id; 31 | } 32 | }; 33 | 34 | #undef PRINT 35 | 36 | typedef boost::mpl::vector< 37 | nil 38 | , function_var_tag 39 | >::type QF_UF_Tags; 40 | 41 | typedef boost::make_variant_over::type QF_UF_Tag; 42 | 43 | } // namespace metaSMT::logic::QF_UF::tag 44 | } // namespace metaSMT::logic::QF_UF 45 | } // namespace metaSMT::logic 46 | } // namespace metaSMT 47 | #endif // HEADER_metaSMT_TAG_ARRAY_HPP 48 | // vim: ft=cpp:ts=2:sw=2:expandtab 49 | -------------------------------------------------------------------------------- /src/metaSMT/support/parser/has_attribute.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // lazily typed 4 | 5 | namespace metaSMT { 6 | namespace support { 7 | namespace detail { 8 | template < typename Attr > 9 | struct HasAttributeVisitor { 10 | HasAttributeVisitor(bool &found, 11 | bool &has_attribute, 12 | std::string const &name) 13 | : found(found) 14 | , has_attribute(has_attribute) 15 | , name(name) 16 | {} 17 | 18 | template < typename Pair > 19 | void operator()( Pair const & ) { 20 | typedef typename Pair::first Tag; 21 | typedef typename Pair::second Name; 22 | if ( !found && 23 | mpl::c_str::value == name ) { 24 | found = true; 25 | has_attribute = boost::is_same::value; 26 | } 27 | } 28 | 29 | bool &found; 30 | bool &has_attribute; 31 | std::string const name; 32 | }; // HasAttributeVisitor 33 | } // detail 34 | 35 | template < typename Attr > 36 | bool has_attribute( std::string const &name ) { 37 | bool found = false; 38 | bool has_attribute = false; 39 | detail::HasAttributeVisitor visitor(found, has_attribute, name); 40 | mpl::for_each< SMT_NameMap >( visitor ); 41 | assert( found ); 42 | return has_attribute; 43 | } 44 | } // support 45 | } // metaSMT 46 | -------------------------------------------------------------------------------- /src/metaSMT/concurrent/Threaded_Worker.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "concurrent_queue.hpp" 4 | 5 | #include 6 | #include 7 | 8 | namespace metaSMT { 9 | namespace concurrent { 10 | 11 | 12 | template 13 | struct ThreadedWorker { 14 | typedef boost::function0 task_type; 15 | typedef concurrent_queue< task_type > queue_type; 16 | 17 | boost::shared_ptr ctx; 18 | queue_type queue; 19 | 20 | ThreadedWorker( boost::shared_ptr ctx ) 21 | : ctx(ctx) 22 | , queue() 23 | {} 24 | 25 | void operator() () { 26 | task_type task = NULL; 27 | while(true) { 28 | queue.wait_and_pop(task); 29 | task(); 30 | } 31 | } 32 | }; 33 | 34 | /** 35 | * @brief Wrapper for ThreadedWork that is copyable 36 | **/ 37 | template 38 | struct ThreadedWorkerWrapper { 39 | typedef ThreadedWorker worker_type; 40 | boost::shared_ptr< worker_type > worker; 41 | 42 | ThreadedWorkerWrapper( boost::shared_ptr ctx ) 43 | : worker( new worker_type(ctx)) 44 | {} 45 | 46 | void operator() () { 47 | (*worker)(); 48 | } 49 | 50 | void push( typename worker_type::task_type const & task) { 51 | worker->queue.push(task); 52 | } 53 | }; 54 | 55 | } /* namespace concurrent */ 56 | } /* namespace metaSMT */ 57 | 58 | -------------------------------------------------------------------------------- /tests/test_graph_copy.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | using namespace std; 7 | using namespace metaSMT; 8 | using namespace metaSMT::solver; 9 | using namespace metaSMT::logic; 10 | 11 | BOOST_FIXTURE_TEST_SUITE(can_copy_graph, Solver_Fixture ) 12 | 13 | BOOST_AUTO_TEST_CASE( copy_false ) 14 | { 15 | BOOST_REQUIRE( solve(ctx) ); 16 | 17 | assertion( ctx, False ); 18 | 19 | ContextType ctx2(ctx); 20 | 21 | BOOST_REQUIRE( !solve(ctx) ); 22 | BOOST_REQUIRE( !solve(ctx2) ); 23 | } 24 | 25 | BOOST_AUTO_TEST_CASE( copy_independent ) 26 | { 27 | BOOST_REQUIRE( solve(ctx) ); 28 | 29 | ContextType ctx2(ctx); 30 | 31 | assertion( ctx, False ); 32 | 33 | BOOST_REQUIRE( !solve(ctx) ); 34 | BOOST_REQUIRE( solve(ctx2) ); 35 | } 36 | 37 | BOOST_AUTO_TEST_CASE( assume_after_copy ) 38 | { 39 | BOOST_REQUIRE( solve(ctx) ); 40 | 41 | ContextType ctx2(ctx); 42 | 43 | assumption( ctx, False ); 44 | assumption( ctx2, True ); 45 | 46 | BOOST_REQUIRE( !solve(ctx) ); 47 | BOOST_REQUIRE( solve(ctx2) ); 48 | } 49 | 50 | BOOST_AUTO_TEST_CASE( copy_assume ) 51 | { 52 | BOOST_REQUIRE( solve(ctx) ); 53 | 54 | assumption( ctx, False ); 55 | 56 | ContextType ctx2(ctx); 57 | 58 | BOOST_REQUIRE( !solve(ctx) ); 59 | BOOST_REQUIRE( !solve(ctx2) ); 60 | 61 | BOOST_REQUIRE( solve(ctx) ); 62 | BOOST_REQUIRE( solve(ctx2) ); 63 | } 64 | 65 | BOOST_AUTO_TEST_SUITE_END() //Solver 66 | 67 | // vim: ft=cpp:ts=2:sw=2:expandtab 68 | -------------------------------------------------------------------------------- /src/metaSMT/support/evaluate_string.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "parser/UTreeEvaluator.hpp" 3 | #include "parser/SMT2Parser.hpp" 4 | #include 5 | #include 6 | 7 | namespace metaSMT { 8 | template < typename Context > 9 | typename Context::result_type 10 | evaluate_string( Context &ctx, std::string const &formula) { 11 | typedef evaluator::UTreeEvaluator< Context > Evaluator; 12 | Evaluator evaluator(ctx); 13 | 14 | std::stringstream ss; 15 | ss << formula; 16 | 17 | boost::spirit::utree::list_type ast; 18 | smt2::SMT2Parser parser(evaluator); 19 | bool const success = parser.parse(ss, ast); 20 | assert( success && "Parsing failed" ); 21 | 22 | return evaluator.evaluateExpressions(ast); 23 | } 24 | 25 | template < typename Context > 26 | typename Context::result_type 27 | evaluate_string( Context &ctx, 28 | std::string const &formula, 29 | std::map > > &var_map) { 31 | typedef evaluator::UTreeEvaluator< Context > Evaluator; 32 | Evaluator evaluator(ctx, var_map); 33 | 34 | std::stringstream ss; 35 | ss << formula; 36 | 37 | boost::spirit::utree::list_type ast; 38 | smt2::SMT2Parser parser(evaluator); 39 | bool const success = parser.parse(ss, ast); 40 | assert( success && "Parsing failed" ); 41 | 42 | return evaluator.evaluateExpressions(ast); 43 | } 44 | } // metaSMT 45 | -------------------------------------------------------------------------------- /src/metaSMT/tags/Logics.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Logic.hpp" 4 | #include "QF_BV.hpp" 5 | #include "Array.hpp" 6 | #include "Cardinality.hpp" 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | namespace metaSMT { 13 | 14 | namespace _all_logic_tags { 15 | typedef boost::mpl::joint_view< 16 | logic::tag::Predicate_Tags 17 | , logic::QF_BV::tag::QF_BV_Tags 18 | >::type all_Tags1; 19 | 20 | typedef boost::mpl::joint_view< 21 | all_Tags1 22 | , logic::Array::tag::Array_Tags 23 | >::type all_Tags2; 24 | 25 | typedef boost::mpl::joint_view< 26 | all_Tags2 27 | , logic::cardinality::tag::Cardinality_Tags 28 | >::type all_Tags3; 29 | 30 | typedef boost::mpl::copy< 31 | all_Tags3 32 | , boost::mpl::back_inserter< boost::mpl::vector<> > 33 | >::type all_Tags; 34 | //BOOST_MPL_ASSERT_RELATION( boost::mpl::size::value, ==, 1 ); 35 | } 36 | 37 | #if BOOST_VARIANT_VISITATION_UNROLLING_LIMIT < 58 38 | #warning "BOOST_VARIANT_VISITATION_UNROLLING_LIMIT is too small!" 39 | #warning "Visiting metaSMT::Tag (e.g., via boost::put(.)) may unexpectedly fail." 40 | #warning "Try to include ." 41 | #endif // BOOST_VARIANT_VISITATION_UNROLLING_LIMIT 42 | 43 | typedef boost::make_variant_over< _all_logic_tags::all_Tags >::type Tag; 44 | 45 | } // namespace metaSMT 46 | 47 | // vim: ft=cpp:ts=2:sw=2:expandtab 48 | -------------------------------------------------------------------------------- /src/metaSMT/support/SMT_Graph.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../tags/Logics.hpp" 4 | 5 | #include "disable_warnings.hpp" 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "enable_warnings.hpp" 11 | 12 | namespace boost { 13 | enum edge_input_t { edge_input }; 14 | BOOST_INSTALL_PROPERTY (edge, input); 15 | 16 | enum vertex_tag_t { vertex_tag }; 17 | BOOST_INSTALL_PROPERTY (vertex, tag); 18 | 19 | enum vertex_arg_t { vertex_arg }; 20 | BOOST_INSTALL_PROPERTY (vertex, arg); 21 | } 22 | 23 | namespace metaSMT { 24 | 25 | /* define properties on edges */ 26 | typedef boost::property edge_input_property; 27 | typedef edge_input_property SMT_Edge_t; 28 | 29 | /* define properties on Vertices */ 30 | typedef boost::property vertex_arg_property; 31 | typedef boost::property vertex_tag_property; 32 | typedef vertex_tag_property SMT_Vertex_t; 33 | 34 | typedef boost::adjacency_list SMT_Graph ; 38 | 39 | typedef boost::graph_traits::vertex_descriptor SMT_Expression; 40 | typedef boost::graph_traits::edge_descriptor SMT_Edge; 41 | 42 | 43 | } /* namespace metaSMT */ 44 | 45 | // vim: ft=cpp:ts=2:sw=2:expandtab 46 | -------------------------------------------------------------------------------- /bindings/python/tests/__main__.py: -------------------------------------------------------------------------------- 1 | import os 2 | import re 3 | import sys 4 | import random 5 | import unittest 6 | 7 | test_str_re = re.compile(r'([^ ]+) \((.*)\)') 8 | 9 | def test_id(test): 10 | m = test_str_re.match(str(test)) 11 | if m is None: 12 | return None 13 | 14 | t, h = m.groups() 15 | 16 | return tuple(h.split('.')+[t]) 17 | 18 | def map_tests(fun, test): 19 | if isinstance(test, unittest.suite.TestSuite): 20 | map(lambda t: map_tests(fun, t), test) 21 | else: 22 | fun(test) 23 | 24 | def print_test(test): 25 | print '.'.join(test_id(str(test))) 26 | 27 | def collect_tests(dic): 28 | def fun(test): 29 | id = test_id(test) 30 | dic[id] = test 31 | return fun 32 | 33 | 34 | if __name__ == "__main__": 35 | tests = unittest.defaultTestLoader.discover(os.path.dirname(__file__), pattern='*.py') 36 | if len(sys.argv) == 2 and sys.argv[1] == '--discover': 37 | map_tests(print_test, tests) 38 | else: 39 | random.seed() 40 | if len(sys.argv) == 0: 41 | unittest.main() 42 | else: 43 | lookup = {} 44 | map_tests( collect_tests(lookup), tests) 45 | suite = unittest.TestSuite() 46 | success = True 47 | for t in sys.argv[1:]: 48 | tc = lookup[tuple(t.split('.'))] 49 | suite.addTest(tc) 50 | result = unittest.TextTestRunner(verbosity=2).run(suite) 51 | if len(result.errors) > 0 or len(result.failures) > 0: 52 | success = False 53 | 54 | if success: 55 | sys.exit(0) 56 | else: 57 | sys.exit(1) 58 | -------------------------------------------------------------------------------- /src/metaSMT/tags/SAT.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace metaSMT { 7 | 8 | namespace SAT { 9 | namespace tag { 10 | 11 | // sat literal tag 12 | // 0 is invalid 13 | // n is variable n 14 | // -m is variable n negated 15 | struct lit_tag { 16 | int id; 17 | template 18 | friend STREAM & operator<< (STREAM & out, lit_tag const & self) 19 | { out << "sat_lit[" << self.id << "]"; return out; } 20 | bool operator< (lit_tag const & other) const { return id < other.id; } 21 | lit_tag operator- () const { lit_tag l = { -id }; return l; } 22 | int var() const {return id >= 0 ? id: -id; } 23 | }; 24 | 25 | struct c_tag { 26 | template 27 | friend STREAM & operator<< (STREAM & out, c_tag const & self) 28 | { out << "or"; return out; } 29 | bool operator< (c_tag const & other) const { return false; } 30 | }; 31 | 32 | struct not_tag { 33 | template 34 | friend STREAM & operator<< (STREAM & out, not_tag const & self) 35 | { out << "not"; return out; } 36 | bool operator< (not_tag const & other) const { return false; } 37 | }; 38 | 39 | // tag variant SAT 40 | typedef boost::mpl::vector< 41 | lit_tag 42 | , c_tag 43 | >::type SAT_Tags; 44 | 45 | typedef boost::make_variant_over< SAT_Tags >::type SAT_Tag; 46 | 47 | } // namespace tag 48 | } // namespace SAT 49 | } // namespace metaSMT 50 | 51 | // vim: ft=cpp:ts=2:sw=2:expandtab 52 | -------------------------------------------------------------------------------- /toolbox/sortnets/unsorted_7.txt: -------------------------------------------------------------------------------- 1 | 0000010 2 | 0000100 3 | 0000101 4 | 0000110 5 | 0001000 6 | 0001001 7 | 0001010 8 | 0001011 9 | 0001100 10 | 0001101 11 | 0001110 12 | 0010000 13 | 0010001 14 | 0010010 15 | 0010011 16 | 0010100 17 | 0010101 18 | 0010110 19 | 0010111 20 | 0011000 21 | 0011001 22 | 0011010 23 | 0011011 24 | 0011100 25 | 0011101 26 | 0011110 27 | 0100000 28 | 0100001 29 | 0100010 30 | 0100011 31 | 0100100 32 | 0100101 33 | 0100110 34 | 0100111 35 | 0101000 36 | 0101001 37 | 0101010 38 | 0101011 39 | 0101100 40 | 0101101 41 | 0101110 42 | 0101111 43 | 0110000 44 | 0110001 45 | 0110010 46 | 0110011 47 | 0110100 48 | 0110101 49 | 0110110 50 | 0110111 51 | 0111000 52 | 0111001 53 | 0111010 54 | 0111011 55 | 0111100 56 | 0111101 57 | 0111110 58 | 1000000 59 | 1000001 60 | 1000010 61 | 1000011 62 | 1000100 63 | 1000101 64 | 1000110 65 | 1000111 66 | 1001000 67 | 1001001 68 | 1001010 69 | 1001011 70 | 1001100 71 | 1001101 72 | 1001110 73 | 1001111 74 | 1010000 75 | 1010001 76 | 1010010 77 | 1010011 78 | 1010100 79 | 1010101 80 | 1010110 81 | 1010111 82 | 1011000 83 | 1011001 84 | 1011010 85 | 1011011 86 | 1011100 87 | 1011101 88 | 1011110 89 | 1011111 90 | 1100000 91 | 1100001 92 | 1100010 93 | 1100011 94 | 1100100 95 | 1100101 96 | 1100110 97 | 1100111 98 | 1101000 99 | 1101001 100 | 1101010 101 | 1101011 102 | 1101100 103 | 1101101 104 | 1101110 105 | 1101111 106 | 1110000 107 | 1110001 108 | 1110010 109 | 1110011 110 | 1110100 111 | 1110101 112 | 1110110 113 | 1110111 114 | 1111000 115 | 1111001 116 | 1111010 117 | 1111011 118 | 1111100 119 | 1111101 120 | 1111110 121 | -------------------------------------------------------------------------------- /src/metaSMT/Instantiate.hpp: -------------------------------------------------------------------------------- 1 | #include "backend/Boolector.hpp" 2 | #include "DirectSolver_Context.hpp" 3 | #include "API/Group.hpp" 4 | 5 | #include "boost/mpl/list.hpp" 6 | #include "boost/mpl/eval_if.hpp" 7 | 8 | namespace metaSMT { 9 | 10 | struct boolector { 11 | template struct result; 12 | 13 | template 14 | struct result< This( Arg ) > { 15 | typedef solver::Boolector type; 16 | }; 17 | 18 | template 19 | DirectSolver_Context< Arg > 20 | operator() (Arg) { 21 | return solver::Boolector(); 22 | } 23 | }; 24 | 25 | struct group { 26 | template struct result; 27 | 28 | template 29 | struct result< This( Arg ) > { 30 | typedef Group< Arg > type; 31 | }; 32 | 33 | template 34 | Group< Arg > 35 | operator() (Arg) { 36 | return Group(); 37 | } 38 | }; 39 | 40 | 41 | struct direct { 42 | template struct result; 43 | 44 | template 45 | struct result< This( Arg ) > { 46 | typedef DirectSolver_Context< Arg > type; 47 | }; 48 | 49 | template 50 | DirectSolver_Context< Arg > 51 | operator() (Arg) { 52 | return DirectSolver_Context(); 53 | } 54 | }; 55 | 56 | template 57 | struct construct_helper 58 | : boost::result_of< A (B) > 59 | { }; 60 | 61 | template 62 | struct Instantiate 63 | : boost::mpl::reverse_fold 65 | > 66 | { 67 | }; 68 | 69 | } /* metaSMT */ 70 | -------------------------------------------------------------------------------- /src/metaSMT/support/parser/get_index.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../../support/index/Logics.hpp" 3 | #include "../../support/SMT_Tag_Mapping.hpp" 4 | #include 5 | #include 6 | 7 | namespace metaSMT { 8 | namespace support { 9 | namespace idx { 10 | namespace mpl = boost::mpl; 11 | 12 | namespace detail { 13 | struct IndexVisitor { 14 | IndexVisitor(bool &found, 15 | logic::index &idx, 16 | std::string const &name) 17 | : found(found) 18 | , idx(idx) 19 | , name(name) 20 | {} 21 | 22 | template < typename Pair > 23 | void operator()( Pair const & ) { 24 | typedef typename Pair::first Tag; 25 | typedef typename Pair::second Name; 26 | if ( !found && 27 | mpl::c_str::value == name ) { 28 | found = true; 29 | idx = logic::Index::value; 30 | } 31 | } 32 | 33 | bool &found; 34 | logic::index &idx; 35 | std::string const name; 36 | }; // IndexVisitor 37 | } // detail 38 | 39 | inline boost::optional< logic::index > 40 | get_index( std::string const &name ) { 41 | bool found = false; 42 | logic::index idx = 0; 43 | detail::IndexVisitor visitor(found, idx, name); 44 | mpl::for_each< SMT_NameMap >( visitor ); 45 | if ( found ) { 46 | return boost::optional< logic::index >(idx); 47 | } 48 | else { 49 | return boost::optional< logic::index >(); 50 | } 51 | } // get_index 52 | } // idx 53 | } // support 54 | } // metaSMT 55 | -------------------------------------------------------------------------------- /bindings/python/examples/prime_test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | from metasmt.core import * 3 | from metasmt.operators import * 4 | import random 5 | 6 | default_bitwidth = 24 7 | 8 | def prime_test(number, solver=boolector_solver(), bitwidth=default_bitwidth): 9 | a = new_bitvector( bitwidth ) 10 | b = new_bitvector( bitwidth ) 11 | 12 | ext = lambda x: zero_extend( bitwidth, x) 13 | 14 | ## a*b=c (avoiding overflows) 15 | solver.assertion( 16 | logic_equal( 17 | bv_mul( ext(a), ext(b)), 18 | bv_uint(number)[2*bitwidth] 19 | ) 20 | ) 21 | solver.assertion( logic_nequal( a, bv_uint(1)[bitwidth]) ) 22 | solver.assertion( logic_nequal( b, bv_uint(1)[bitwidth]) ) 23 | 24 | if solver.solve(): 25 | return ( 26 | solver.read_value(a), 27 | solver.read_value(b), 28 | ) 29 | else: 30 | return None 31 | 32 | def prime_test_operators(number, solver=boolector_solver(), bitwidth=default_bitwidth): 33 | a = new_bitvector( bitwidth ) 34 | b = new_bitvector( bitwidth ) 35 | 36 | ext = lambda x: zero_extend( bitwidth, x) 37 | 38 | ## a*b=c (avoiding overflows) 39 | solver &= ext(a) * ext(b) == bv_uint(number)[2*bitwidth] 40 | solver &= a != bv_uint(1)[bitwidth] 41 | solver &= b != bv_uint(1)[bitwidth] 42 | solver &= a <= b 43 | 44 | if solver.solve(): 45 | return ( solver[a], solver[b] ) 46 | else: 47 | return None 48 | 49 | 50 | def main(): 51 | while True: 52 | rand = random.randint(2, 2**default_bitwidth-1) 53 | print "%8d" % rand, 54 | result = prime_test_operators( rand ) 55 | if result is None: 56 | print "is prime" 57 | break; 58 | else: 59 | print "can be factorized into %8d * %8d" % result 60 | 61 | if __name__ == '__main__': 62 | main() 63 | -------------------------------------------------------------------------------- /src/metaSMT/tags/Array.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifndef HEADER_metaSMT_TAG_ARRAY_HPP 3 | #define HEADER_metaSMT_TAG_ARRAY_HPP 4 | 5 | #include "Logic.hpp" 6 | 7 | #include 8 | #include 9 | 10 | namespace metaSMT { 11 | namespace logic { 12 | namespace Array { 13 | namespace tag { 14 | 15 | #define PRINT(Tag, body) template \ 16 | friend STREAM & operator<< (STREAM & out, Tag const & self) \ 17 | { return (out << body); } 18 | #define TAG( NAME, ATTR ) struct NAME##_tag { \ 19 | typedef attr::ATTR attribute; \ 20 | bool operator<(NAME##_tag const &) const {return false;} \ 21 | PRINT(NAME##_tag, #NAME) \ 22 | }; 23 | 24 | // array variable tag 25 | struct array_var_tag { 26 | typedef attr::ignore attribute; 27 | 28 | unsigned id; 29 | unsigned elem_width; 30 | unsigned index_width; 31 | PRINT(array_var_tag, "array_var_tag[" << self.id << ',' << self.elem_width << ',' << self.index_width << "]") 32 | bool operator< (array_var_tag const & other) const { 33 | return id < other.id; 34 | } 35 | }; 36 | 37 | TAG(select, ignore) 38 | TAG(store, ignore) 39 | 40 | #undef PRINT 41 | #undef TAG 42 | 43 | typedef boost::mpl::vector< 44 | nil 45 | , select_tag 46 | , store_tag 47 | , array_var_tag 48 | >::type Array_Tags; 49 | 50 | typedef boost::make_variant_over::type Array_Tag; 51 | 52 | } // namespace metaSMT::logic::Array::tag 53 | } // namespace metaSMT::logic::Array 54 | } // namespace metaSMT::logic 55 | } // namespace metaSMT 56 | #endif // HEADER_metaSMT_TAG_ARRAY_HPP 57 | // vim: ft=cpp:ts=2:sw=2:expandtab 58 | -------------------------------------------------------------------------------- /src/metaSMT/concurrent/concurrent_queue.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../support/disable_warnings.hpp" 4 | #include 5 | #include 6 | #include "../support/enable_warnings.hpp" 7 | 8 | #include 9 | 10 | namespace metaSMT { 11 | namespace concurrent { 12 | 13 | /* taken from http://www.justsoftwaresolutions.co.uk/threading/implementing-a-thread-safe-queue-using-condition-variables.html */ 14 | 15 | template 16 | class concurrent_queue 17 | { 18 | private: 19 | std::queue the_queue; 20 | mutable boost::mutex the_mutex; 21 | boost::condition_variable the_condition_variable; 22 | public: 23 | void push(Data const& data) 24 | { 25 | boost::mutex::scoped_lock lock(the_mutex); 26 | the_queue.push(data); 27 | lock.unlock(); 28 | the_condition_variable.notify_one(); 29 | } 30 | 31 | bool empty() const 32 | { 33 | boost::mutex::scoped_lock lock(the_mutex); 34 | return the_queue.empty(); 35 | } 36 | 37 | bool try_pop(Data& popped_value) 38 | { 39 | boost::mutex::scoped_lock lock(the_mutex); 40 | if(the_queue.empty()) 41 | { 42 | return false; 43 | } 44 | 45 | popped_value=the_queue.front(); 46 | the_queue.pop(); 47 | return true; 48 | } 49 | 50 | void wait_and_pop(Data& popped_value) 51 | { 52 | boost::mutex::scoped_lock lock(the_mutex); 53 | while(the_queue.empty()) 54 | { 55 | the_condition_variable.wait(lock); 56 | } 57 | 58 | popped_value=the_queue.front(); 59 | the_queue.pop(); 60 | } 61 | 62 | }; 63 | 64 | } /* namespace concurrent */ 65 | } /* namespace metaSMT */ 66 | -------------------------------------------------------------------------------- /src/metaSMT/support/SMT2_result_grammar.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../result_wrapper.hpp" 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | namespace metaSMT { 12 | namespace smt2 { 13 | 14 | template< typename Iterator > 15 | struct smt2_result_grammar : boost::spirit::qi::grammar 16 | { 17 | smt2_result_grammar() : smt2_result_grammar::base_type(start) 18 | { 19 | using boost::spirit::qi::lit; 20 | using boost::spirit::qi::uint_; 21 | using boost::spirit::qi::eol; 22 | using boost::spirit::qi::attr; 23 | using boost::spirit::qi::labels::_1; 24 | using boost::spirit::qi::labels::_2; 25 | using boost::spirit::qi::labels::_val; 26 | 27 | start = boolean ;// | bitvector; 28 | ; 29 | 30 | boolean = 31 | lit("(true)") >> attr(result_wrapper(true)) 32 | | lit("(false)") >> attr(result_wrapper(false)) 33 | ; 34 | //bitvector = 35 | //(lit("((_ bv") << uint_ << " " << uint_ << "))")//[_val = construct(_1, _2)] 36 | ; 37 | 38 | 39 | 40 | //start.name("start"); 41 | //boolean.name("boolean"); 42 | //bitvector.name("bitvector"); 43 | 44 | //debug(start); 45 | //debug(boolean); 46 | //debug(bitvector); 47 | } 48 | 49 | boost::spirit::qi::rule start 50 | , boolean 51 | , bitvector 52 | ; 53 | boost::spirit::qi::rule()> bvint; 54 | 55 | }; 56 | } /* SMT2 */ 57 | } /* metaSMT */ 58 | 59 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | = TODO List = 2 | 3 | == features for metaSMT 4 (future release)== 4 | * Type save 5 | * Python Interface/bindings 6 | * SMT-Lib 2 7 | * Portfolio Solver (Any number of Solvers) 8 | * Parallel/Distributed/Clustered solving [network] 9 | * Typed Expression (automatic handling) 10 | * extend documentation of available commands (SMT expressions, other) 11 | 12 | == features for metaSMT 3 (next release)== 13 | * CNF-Parser /Solver Frontend [done] 14 | * extend documentation of available commands (SMT expressions, other) 15 | * Portfolio Solver (2 Threads) [done] 16 | * SMT-Lib 2 File output [done, for Z3 2.18] 17 | * Typed Expression -> TypedSymbol [done] 18 | * Explicit Features [partial] 19 | * API declaration an checking [done] 20 | 21 | == Future versions (maybe) == 22 | * Solver independent Syntax Trees 23 | * SMT-LIB 1 Parser 24 | * BitBlasting QF_BV to LIA (or other Logics) 25 | * Pseudo Boolean SAT/Solvers 26 | * Solver Checking (using a different Solver) 27 | * Fuzzing 28 | * eFMI ( easy Formal Methods Interface) 29 | 30 | == Finished Features == 31 | * support for Boolector (QF_BV, Core Logic) [done] 32 | * support for Z3 (QF_BV, Core Logic) [done] 33 | * support for MiniSAT (Core Logic) [done] 34 | * support for SWORD (QF_BV, Logic) [done] 35 | * support for Picosat (Logic) [done] 36 | * support for BitBlastig QF_BV to Logic [done] 37 | * compile time Solver selection (same api, different solvers) [done] 38 | 39 | * README for installation 40 | * install scripts for Solvers (s.a.) [done] 41 | * Example algorithm (Sudoku, Mastermind, etc) [done] 42 | * Tool Paper [done] 43 | * README/script to setup own projects [done] 44 | 45 | * Cardinality Constraints [ done ] 46 | * Constraint Groups [done] 47 | * Constraint Stack [done] 48 | * Array over Bitvector Theory [done] 49 | * lazy expressions [done] 50 | 51 | -------------------------------------------------------------------------------- /bindings/python/examples/graph_coloring.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | import random 3 | import sys 4 | 5 | sys.path.insert( 0, sys.path[0] + '/..' ) 6 | from metasmt.core import * 7 | from metasmt.operators import * 8 | from metasmt.support import * 9 | 10 | import matplotlib.pyplot as plt 11 | import networkx as nx 12 | 13 | # Graph Coloring 14 | def graph_coloring( G, num_colors, 15 | solver = boolector_solver(), 16 | colors = [ 'red', 'green', 'blue', 'yellow', 'orange', 'purple', 'orange', 'cyan', 'magenta' ]): 17 | 18 | # Bit-width of variables 19 | bw = bits_for_values( num_colors ) 20 | 21 | # Create variables for each vertex 22 | vmap = dict( [ ( n, new_bitvector( bw ) ) for n in G.nodes() ] ) 23 | 24 | # Color in range 25 | for b in vmap.values(): 26 | solver &= ( b <= bv_uint[bw]( num_colors ) ) 27 | 28 | # Different color for adjacent vertices 29 | for v, w in G.edges(): 30 | solver &= vmap[v] != vmap[w] 31 | 32 | r = solver.solve() 33 | print r, solver 34 | if r: 35 | for n, b in vmap.items(): 36 | G.node[n]['color'] = colors[solver[b]] 37 | return True 38 | else: 39 | return False 40 | 41 | def optimal_graph_coloring( G, start_from = 2 ): 42 | num_colors = start_from 43 | solver = z3_solver() 44 | while not graph_coloring( G, num_colors, solver ): 45 | print "try with %d" % num_colors 46 | num_colors += 1 47 | 48 | if num_colors == G.number_of_nodes(): 49 | exit( 1 ) 50 | 51 | solver = z3_solver() 52 | 53 | return num_colors 54 | 55 | 56 | 57 | 58 | # Main Program 59 | G = nx.dodecahedral_graph() 60 | 61 | optimal_graph_coloring( G ) 62 | 63 | nx.draw( G, node_color = [ p['color'] for _, p in G.nodes( data = True ) ] ) 64 | plt.draw() 65 | plt.show() 66 | -------------------------------------------------------------------------------- /src/metaSMT/io/SMT2_ResultParser.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | namespace metaSMT { 11 | 12 | namespace io { 13 | 14 | namespace qi = boost::spirit::qi; 15 | 16 | template< typename Iterator > 17 | struct smt2_response_grammar : qi::grammar { 18 | smt2_response_grammar() : smt2_response_grammar::base_type(start) { 19 | using qi::omit; 20 | using qi::lit; 21 | using qi::char_; 22 | using qi::int_; 23 | using qi::eol; 24 | using qi::attr; 25 | using qi::space; 26 | using qi::alnum; 27 | 28 | // See: SMT-LIB 2 - Section 3.1: Symbol 29 | quotted_symbol = 30 | omit[ lit('|') >> *( char_-lit('|') ) >> lit('|') ] 31 | ; 32 | 33 | simple_symbol = 34 | omit[ +(alnum | '~' | '!' | '@' | '$' | '%' | '^' | '&' | '*' | '_' | '-' | '+' | '=' | '<' | '>' | '.' | '?' | '/') ] 35 | ; 36 | 37 | symbol_name = 38 | omit[ quotted_symbol | simple_symbol ] 39 | ; 40 | 41 | select_expr = 42 | lit("(select") >> *( char_-lit(')') ) >> lit("))") 43 | ; 44 | 45 | start = 46 | lit("((") >> (symbol_name | select_expr) >> omit[ *space ] >> +( char_('#') | alnum ) >> lit("))") 47 | ; 48 | 49 | //start.name("start"); 50 | //debug(start); 51 | } 52 | 53 | qi::rule quotted_symbol; 54 | qi::rule simple_symbol; 55 | qi::rule symbol_name; 56 | qi::rule select_expr; 57 | qi::rule start; 58 | }; // smt2_response_grammar 59 | 60 | } // io 61 | 62 | } // metaSMT 63 | -------------------------------------------------------------------------------- /toolbox/sortnets/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | define_property( 3 | GLOBAL 4 | PROPERTY TOOLBOX_SORTNETS_BENCHMARKS 5 | BRIEF_DOCS "list of sortnet benchmarks" 6 | FULL_DOCS "list of sortnet benchmarks" 7 | ) 8 | 9 | 10 | function(add_sortnet name) 11 | add_tool_executable( sortnets_${name} 12 | SOURCES 13 | ${name}.cpp 14 | 15 | REQUIRES 16 | ${ARGN} 17 | ) 18 | 19 | add_sortnet_benchmark(sortnets_${name} 1 unsorted_6.txt) 20 | add_sortnet_benchmark(sortnets_${name} 5 unsorted_6.txt) 21 | add_sortnet_benchmark(sortnets_${name} 1 unsorted_7.txt) 22 | add_sortnet_benchmark(sortnets_${name} 6 unsorted_7.txt) 23 | add_sortnet_benchmark(sortnets_${name} 6 unsorted_8.txt) 24 | 25 | endfunction(add_sortnet) 26 | 27 | function(add_sortnet_benchmark target depth benchmark) 28 | if(TARGET ${target}) 29 | message(STATUS "add_sortnet_benchmark ${target} ${depth} ${benchmark}") 30 | set(datafile "${CMAKE_CURRENT_SOURCE_DIR}/${benchmark}") 31 | set(logfile "${CMAKE_CURRENT_BINARY_DIR}/${target}_${depth}_${benchmark}.log") 32 | add_custom_command( 33 | OUTPUT ${logfile} 34 | COMMAND cat ${datafile} | ${CMAKE_COMMAND} -E time xargs $ ${depth} &> ${logfile} 35 | DEPENDS ${datafile} ${target} 36 | ) 37 | 38 | set_property(GLOBAL APPEND PROPERTY TOOLBOX_SORTNETS_BENCHMARKS ${logfile}) 39 | endif() 40 | endfunction(add_sortnet_benchmark) 41 | 42 | add_sortnet(boolector Boolector_FOUND MiniSat_FOUND Aiger_FOUND) 43 | add_sortnet(cvc4 CVC4_FOUND) 44 | add_sortnet(minisat MiniSat_FOUND Aiger_FOUND) 45 | add_sortnet(picosat PicoSAT_FOUND MiniSat_FOUND Aiger_FOUND) 46 | add_sortnet(smt2) 47 | add_sortnet(stp STP_FOUND) 48 | add_sortnet(sword SWORD_FOUND) 49 | add_sortnet(z3 Z3_FOUND) 50 | 51 | get_property(benchmarks GLOBAL PROPERTY TOOLBOX_SORTNETS_BENCHMARKS) 52 | add_custom_target( 53 | benchmark_sortnets 54 | ${CMAKE_COMMAND} -E echo_append 55 | DEPENDS ${benchmarks} 56 | COMMENT "" 57 | ) 58 | -------------------------------------------------------------------------------- /tests/test_expression.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | using namespace std; 13 | using namespace metaSMT; 14 | using namespace metaSMT::solver; 15 | using namespace metaSMT::logic; 16 | using namespace metaSMT::logic::QF_BV; 17 | using namespace metaSMT::logic::QF_UF; 18 | using namespace metaSMT::expression; 19 | namespace proto = boost::proto; 20 | using boost::dynamic_bitset; 21 | 22 | BOOST_FIXTURE_TEST_SUITE(expression_t, Solver_Fixture ) 23 | 24 | BOOST_AUTO_TEST_CASE( expression_equality ) { 25 | logic_expression b0 = bit0_const(); 26 | logic_expression b1 = bit1_const(); 27 | BOOST_REQUIRE( b0 == b0 ); 28 | BOOST_REQUIRE( !(b0 == b1) ); 29 | BOOST_REQUIRE( b1 == b1 ); 30 | BOOST_REQUIRE( !(b1 == b0) ); 31 | 32 | logic_expression p = new_variable(); 33 | BOOST_REQUIRE( p == p ); 34 | 35 | logic_expression q = new_variable(); 36 | BOOST_REQUIRE( !(p == q) ); 37 | BOOST_REQUIRE( !(q == p) ); 38 | 39 | logic_expression bv_a = new_bitvector(); 40 | BOOST_REQUIRE( bv_a == bv_a ); 41 | BOOST_REQUIRE( !(p == bv_a) ); 42 | 43 | logic_expression bv_b = new_bitvector(); 44 | BOOST_REQUIRE( !(bv_a == bv_b) ); 45 | BOOST_REQUIRE( !(bv_b == bv_a) ); 46 | 47 | logic_expression and1_expr = evaluate(ctx, And(p, q)); 48 | logic_expression and2_expr = evaluate(ctx, And(p, q)); 49 | BOOST_REQUIRE( and1_expr == and2_expr ); 50 | 51 | logic_expression func1 = declare_function(Boolean())(BitVector(8)); 52 | logic_expression func2 = declare_function(Boolean())(BitVector(6)); 53 | BOOST_REQUIRE( func1 == func1 ); 54 | BOOST_REQUIRE( !(func1 == func2) ); 55 | } 56 | 57 | BOOST_AUTO_TEST_SUITE_END() //Solver 58 | 59 | // vim: ft=cpp:ts=2:sw=2:expandtab 60 | -------------------------------------------------------------------------------- /src/metaSMT/backend/SAT/model_parser.hpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | namespace metaSMT { 9 | namespace SAT { 10 | /** 11 | * first element is the result (SATISFIABLE) 12 | * second is the assignment. 13 | **/ 14 | typedef boost::tuple< std::string, std::vector< int > > result_tuple; 15 | 16 | // debug code 17 | //template< typename O> 18 | //O& operator<< (O& o, std::vector< int > const & v) { 19 | // BOOST_FOREACH(int i, v) { 20 | // o << i << ' '; 21 | // } 22 | // return o; 23 | //} 24 | 25 | template< typename Iterator > 26 | struct model_grammar : boost::spirit::qi::grammar 27 | { 28 | model_grammar() : model_grammar::base_type(start) 29 | { 30 | using boost::spirit::qi::lit; 31 | using boost::spirit::qi::char_; 32 | using boost::spirit::qi::int_; 33 | using boost::spirit::qi::eol; 34 | using boost::spirit::qi::attr; 35 | 36 | start = 37 | *comment 38 | >> result 39 | >> *comment 40 | >> -lit("v ") >> ( int_ % ((eol >> -lit("v ")) | lit(' ')) ) >> +eol 41 | >> *comment 42 | ; 43 | result = -lit("s ") >> *(char_ - (eol | ' ')) >> +eol; 44 | comment = -(lit('c') >> *(char_ - eol)) >> +eol; 45 | 46 | //start.name("start"); 47 | //comment.name("comment"); 48 | //result.name("result"); 49 | 50 | //debug(start); 51 | //debug(comment); 52 | //debug(result); 53 | } 54 | 55 | boost::spirit::qi::rule start; 56 | boost::spirit::qi::rule result; 57 | boost::spirit::qi::rule comment; 58 | 59 | }; 60 | } /* SA */ 61 | } /* metaSMT */ 62 | -------------------------------------------------------------------------------- /toolbox/metaSMT-cnf-solver/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | 19 | using namespace metaSMT; 20 | using namespace metaSMT::dimacs; 21 | using namespace metaSMT::solver; 22 | using namespace std; 23 | 24 | int main(int argc, const char *argv[]) 25 | { 26 | assert ( argc == 2 ); 27 | 28 | string filename ( argv[1] ); 29 | 30 | ifstream stream ( filename.c_str() ); 31 | assert ( stream.good() ); 32 | 33 | DirectSolver_Context < BitBlast < SAT_Clause < PicoSAT > > > picosat; 34 | 35 | boost::timer all_timer; 36 | 37 | std::set < unsigned > vars; 38 | bool r = parse_dimacs ( stream, picosat, vars ); 39 | 40 | if ( r ) 41 | { 42 | cout << boost::format ("c Parsed in %.2f seconds.") % all_timer.elapsed() << std::endl; 43 | } 44 | else 45 | { 46 | cerr << boost::format ("c Failure while parsing Dimacs file %s.") % filename << endl; 47 | return -1; 48 | } 49 | 50 | bool sat = solve ( picosat); 51 | 52 | if ( sat ) 53 | { 54 | std::cout << "s SATISFIABLE" << std::endl; 55 | unsigned num = 0; 56 | 57 | std::cout << "s "; 58 | foreach ( unsigned var, vars ) 59 | { 60 | SAT::tag::lit_tag Var; 61 | Var.id = var; 62 | 63 | if ( bool(read_value ( picosat, Var )) == true ) 64 | std::cout << var << " "; 65 | else 66 | std::cout << "-" << var << " "; 67 | 68 | num++; 69 | 70 | if ( num == 10 ) 71 | { 72 | std::cout << "\ns "; 73 | num = 0; 74 | } 75 | } 76 | } 77 | else 78 | std::cout << "s UNSATISFIABLE" << std::endl; 79 | 80 | return EXIT_SUCCESS; 81 | } 82 | -------------------------------------------------------------------------------- /src/metaSMT/transform/satClause.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../tags/SAT.hpp" 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | namespace metaSMT { 12 | namespace transform { 13 | namespace proto = boost::proto; 14 | 15 | struct satClauseArity 16 | : proto::or_< 17 | proto::when, boost::mpl::int_<1>()> 18 | , proto::otherwise(), boost::mpl::plus()> > 19 | > {}; 20 | 21 | 22 | struct satClause 23 | : proto::or_< 24 | proto::when< 25 | proto::terminal 26 | , boost::fusion::single_view< 27 | proto::_value 28 | > ( 29 | proto::_value 30 | ) 31 | > 32 | , proto::when< 33 | proto::plus 34 | , boost::fusion::joint_view< 35 | boost::add_const 36 | , boost::add_const 37 | >(satClause(proto::_left), satClause(proto::_right)) 38 | > 39 | , proto::when< 40 | proto::negate< proto::negate > 41 | , satClause(proto::_child(proto::_child)) 42 | > 43 | , proto::when< 44 | proto::negate< proto::terminal > 45 | , boost::fusion::single_view< 46 | proto::call >( 47 | proto::_value(proto::_child) 48 | ) 49 | > ( 50 | proto::call >( 51 | proto::_value(proto::_child) 52 | ) 53 | ) 54 | > 55 | > {}; 56 | 57 | 58 | } /* transform */ 59 | } /* metaSMT */ 60 | 61 | -------------------------------------------------------------------------------- /toolbox/sortnets/SortNetSynth.hpp: -------------------------------------------------------------------------------- 1 | #include "Level.hpp" 2 | #include "SynthNet.hpp" 3 | 4 | #include 5 | 6 | #include 7 | 8 | using metaSMT::logic::predicate; 9 | 10 | template 11 | struct SortNetSynth 12 | { 13 | typedef bool result_type; 14 | 15 | unsigned size; 16 | SynthNet syn_net; 17 | 18 | typedef std::list< Level > Net; 19 | Net ver_net; 20 | 21 | double time_synth; 22 | double time_verify; 23 | 24 | SortNetSynth ( unsigned min_depth, std::vector const & inits ) 25 | : size(inits[0].size()) 26 | , syn_net(size) 27 | { 28 | for (unsigned i = 0; i < min_depth; i++) { 29 | syn_net.add_level(); 30 | } 31 | BOOST_FOREACH (std::string const & init, inits) { 32 | syn_net.add_counterexample(init); 33 | } 34 | } 35 | 36 | void print_solution(std::ostream& out) { 37 | out << "found solution\n"; 38 | //syn_net.print_all(out); 39 | syn_net.print_one(out); 40 | } 41 | 42 | void print_counterexample(std::ostream& out) { 43 | } 44 | 45 | bool verify() { 46 | boost::timer timer; 47 | VerifyerContext ver; 48 | bool success = syn_net.verify_or_add_counterexample(ver); 49 | time_verify += timer.elapsed(); 50 | return success; 51 | } 52 | 53 | bool synth() 54 | { 55 | boost::timer timer; 56 | bool success = syn_net.synth(); 57 | time_synth += timer.elapsed(); 58 | return success; 59 | } 60 | 61 | result_type operator() () 62 | { 63 | while(true) { 64 | while( synth() ) { 65 | print_solution(std::cout); 66 | if( verify() ) { 67 | std::cout << "Found Solution." << std::endl; 68 | print_solution(std::cout); 69 | return result_type(); 70 | } else { 71 | print_counterexample(std::cout); 72 | } 73 | } 74 | std::cout << "add another level." << std::endl; 75 | syn_net.add_level(); 76 | } 77 | return result_type(); 78 | } 79 | 80 | }; 81 | -------------------------------------------------------------------------------- /bindings/python/tests/support.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | import sys 3 | import unittest 4 | 5 | sys.path.insert( 0, sys.path[0] + '/..' ) 6 | 7 | from metasmt.core import * 8 | from metasmt.operators import * 9 | from metasmt.support import * 10 | 11 | class SupportTest( object ): 12 | def testOneHot( self ): 13 | vars = new_variables( 10 ) 14 | bv = new_bitvector( 10 ) 15 | 16 | solver = self.solver() 17 | solver &= one_hot( vars ) 18 | solver &= one_hot( bv, 10 ) 19 | self.assertTrue( solver.solve() ) 20 | self.assertEqual( len( [ v for v in map( solver.read_value, vars ) if v ] ), 1 ) 21 | self.assertEqual( len( [ v for v in [ 2**i & solver.read_value( bv ) != 0 for i in range( 10 ) ] if v ] ), 1 ) 22 | 23 | def testCardinality( self ): 24 | vgeq = new_variables( 10 ) 25 | vlt = new_variables( 10 ) 26 | vleq = new_variables( 10 ) 27 | vgt = new_variables( 10 ) 28 | veq = new_variables( 10 ) 29 | 30 | solver = self.solver() 31 | solver &= cardinality_geq( vgeq, 5 ) 32 | solver &= cardinality_lt( vlt, 5 ) 33 | solver &= cardinality_leq( vleq, 5 ) 34 | solver &= cardinality_gt( vgt, 5 ) 35 | solver &= cardinality_eq( veq, 5 ) 36 | self.assertTrue( solver.solve() ) 37 | self.assertGreaterEqual( len( [ v for v in map( solver.read_value, vgeq ) if v ] ), 5 ) 38 | self.assertLess( len( [ v for v in map( solver.read_value, vlt ) if v ] ), 5 ) 39 | self.assertLessEqual( len( [ v for v in map( solver.read_value, vleq ) if v ] ), 5 ) 40 | self.assertGreater( len( [ v for v in map( solver.read_value, vgt ) if v ] ), 5 ) 41 | self.assertEqual( len( [ v for v in map( solver.read_value, veq ) if v ] ), 5 ) 42 | 43 | for name, solver in available_solvers().items(): 44 | test_name = 'SupportTest_'+name 45 | solver_fun = lambda self: solver() 46 | globals()[test_name] = type(test_name, (SupportTest, unittest.TestCase), dict(solver=solver_fun )) 47 | 48 | if __name__ == "__main__": 49 | unittest.main() 50 | 51 | -------------------------------------------------------------------------------- /toolbox/sortnets/Level.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | 7 | using namespace metaSMT::logic; 8 | 9 | struct Level { 10 | 11 | std::vector vars; 12 | 13 | Level(unsigned size) 14 | { 15 | for (unsigned i = 0; i < size; i++) { 16 | vars.push_back( new_variable() ); 17 | } 18 | } 19 | 20 | predicate & operator[] (unsigned i) { 21 | return vars[i]; 22 | } 23 | 24 | template 25 | typename Context::result_type 26 | is_sorted(Context & ctx) { 27 | //std::cout << "is_sorted called\n"; 28 | typename Context::result_type ret = evaluate(ctx, True); 29 | for (unsigned i = 1; i < vars.size(); i++) { 30 | ret = evaluate(ctx, And(ret, 31 | implies(vars[i-1], vars[i]) 32 | )); 33 | } 34 | return ret; 35 | } 36 | 37 | template 38 | typename Context::result_type 39 | equal_to(Context & ctx, std::string const & val) { 40 | typename Context::result_type ret = evaluate(ctx, True); 41 | for (unsigned i = 0; i < vars.size(); i++) { 42 | if(val[i] == '1') { 43 | ret = evaluate(ctx, And(ret, 44 | vars[i] 45 | )); 46 | } else { 47 | ret = evaluate(ctx, And(ret, 48 | Not(vars[i]) 49 | )); 50 | } 51 | } 52 | return ret; 53 | } 54 | 55 | template 56 | void print_assignment(std::ostream& out, Context & ctx) { 57 | for (unsigned i = 0; i < vars.size(); i++) { 58 | bool b = read_value(ctx, vars[i]); 59 | out << b; 60 | } 61 | out << '\n'; 62 | } 63 | 64 | template 65 | void print(std::ostream& out, Context & ctx) { 66 | print_assignment(out, ctx); 67 | } 68 | 69 | template 70 | std::string assignment(Context & ctx) { 71 | std::string ret(vars.size(), '-'); 72 | for (unsigned i = 0; i < vars.size(); i++) { 73 | bool b = read_value(ctx, vars[i]); 74 | ret[i] = b ? '1' : '0'; 75 | } 76 | return ret; 77 | } 78 | }; 79 | -------------------------------------------------------------------------------- /src/metaSMT/API/Comment.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../Features.hpp" 4 | 5 | #include 6 | 7 | namespace metaSMT { 8 | 9 | namespace features { 10 | struct comment_api {}; 11 | } /* features */ 12 | 13 | struct write_comment { typedef void result_type; }; 14 | 15 | /** 16 | * \brief Insert comments into the instance file 17 | * 18 | * 19 | * 20 | * \code 21 | * DirectSolver_Context< SMT2 > ctx; 22 | * 23 | * assertion(ctx, equal(True, False); 24 | * comment(ctx, "now call solve"); 25 | * 26 | * solve(ctx); 27 | * \endcode 28 | * \ingroup API 29 | * \defgroup Comment Comments API 30 | * @{ 31 | */ 32 | 33 | /** 34 | * \class IgnoreComments Comment.hpp metaSMT/Comment.hpp 35 | * \brief Ignore comment commands 36 | */ 37 | template 38 | struct IgnoreComments : Context { 39 | void command ( write_comment const &, std::string const & message) { 40 | /* ignored */ 41 | } 42 | 43 | using Context::command; 44 | }; 45 | 46 | namespace features { 47 | /* IgnoreComments supports comment api (by ignoring it) */ 48 | template 49 | struct supports< IgnoreComments, features::comment_api> 50 | : boost::mpl::true_ {}; 51 | 52 | /* Forward all other supported operations */ 53 | template 54 | struct supports< IgnoreComments, Feature> 55 | : supports::type {}; 56 | } 57 | 58 | 59 | /** 60 | * \brief write a comment 61 | * \param ctx The context to work on 62 | * \param message The comment 63 | * \return void 64 | * \throws Assertion at compile time if \c Context does not support comments 65 | * 66 | */ 67 | template 68 | void comment( Context & ctx, std::string const & message) { 69 | BOOST_MPL_ASSERT_MSG(( features::supports::value ), 70 | context_does_not_support_comment_api, (Context) ); 71 | ctx.command(write_comment(), message); 72 | } 73 | 74 | /**@}*/ 75 | 76 | } /* metaSMT */ 77 | 78 | -------------------------------------------------------------------------------- /src/metaSMT/frontend/SAT.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../tags/SAT.hpp" 3 | #include "../transform/rewrite.hpp" 4 | #include 5 | #include 6 | 7 | // debug includes 8 | #include 9 | #include 10 | #include 11 | 12 | namespace metaSMT { 13 | namespace SAT { 14 | namespace proto=boost::proto; 15 | 16 | /*** SAT/clase grammar ***/ 17 | struct SAT_Domain; 18 | 19 | struct Literal 20 | : proto::or_< 21 | proto::terminal< tag::lit_tag > 22 | , proto::unary_expr< tag::not_tag, Literal> 23 | , proto::complement< Literal > 24 | , proto::logical_not< Literal > 25 | > {}; 26 | 27 | 28 | struct SAT_Grammar 29 | : proto::or_< 30 | proto::_, 31 | Literal 32 | , proto::plus 33 | , proto::nary_expr > 34 | > {}; 35 | 36 | 37 | /*** SAT expression and Domain ***/ 38 | template 39 | struct SAT_Expr; 40 | 41 | struct SAT_Domain 42 | : proto::domain, SAT_Grammar> 43 | {}; 44 | 45 | template 46 | struct SAT_Expr 47 | : proto::extends, SAT_Domain > 48 | { 49 | typedef proto::extends, SAT_Domain > base_type; 50 | 51 | SAT_Expr(Expr expr ) 52 | : base_type(expr) 53 | { 54 | } 55 | SAT_Expr( ) 56 | : base_type(Expr()) 57 | { 58 | } 59 | }; 60 | 61 | 62 | 63 | 64 | typedef 65 | proto::result_of::make_expr< proto::tag::terminal, SAT_Domain 66 | , tag::lit_tag 67 | > ::type variable; 68 | 69 | variable new_variable() { 70 | static unsigned _id = 0; 71 | ++_id; 72 | tag::lit_tag tag; 73 | tag.id = _id; 74 | return proto::make_expr< proto::tag::terminal, SAT_Domain >( tag ); 75 | } 76 | 77 | struct clause { 78 | }; 79 | 80 | } /* SAT */ 81 | } /* metaSMT */ 82 | 83 | 84 | // vim: tabstop=2 shiftwidth=2 expandtab 85 | -------------------------------------------------------------------------------- /bindings/python/tests/smt2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | import os, sys 3 | import unittest 4 | 5 | pwd = sys.path[0] 6 | sys.path.insert( 0, pwd + '/..' ) 7 | 8 | #os.environ['PATH'] = "%s/../../../deps/Z3-2.19/bin:%s" % ( pwd, os.environ['PATH'] ) 9 | 10 | from metasmt.core import * 11 | from metasmt.operators import * 12 | from metasmt.smt2 import * 13 | 14 | def delete_tmp_files(): 15 | for f in [ 'meta.%s' % f for f in [ 'smt2', 'sol' ]]: 16 | if os.path.exists( f ): 17 | os.unlink( f ) 18 | 19 | def skipIfNoSMT2(obj): 20 | if 'smt2' in available_solvers(): 21 | return lambda func: func 22 | return unittest.skip("smt2 solver is unavailable") 23 | 24 | 25 | @skipIfNoSMT2 26 | class SMT2Test( unittest.TestCase ): 27 | def test_solver( self ): 28 | delete_tmp_files() 29 | 30 | a, b, c = new_bitvectors( 32, 3 ) 31 | 32 | s = smt2_solver() 33 | s &= ( a == ( b & c ) ) 34 | s.solve() 35 | 36 | delete_tmp_files() 37 | 38 | def test_symbol_table( self ): 39 | delete_tmp_files() 40 | 41 | a, b, c = new_bitvectors( 32, 3 ) 42 | 43 | s = smt2_solver() 44 | 45 | s.symbol( a, "a" ) 46 | s.symbol( b, "b" ) 47 | s.symbol( c, "c" ) 48 | s.install_symbol_table() 49 | 50 | s &= ( a == ( b & c ) ) 51 | s.solve() 52 | 53 | self.assertEqual( len( filter( lambda s: s == '(assert (= a (bvand b c)))', map( str.strip, open( 'meta.smt2', 'r' ).readlines() ) ) ), 1 ) 54 | 55 | delete_tmp_files() 56 | 57 | def test_symbol_table_with_vars( self ): 58 | delete_tmp_files() 59 | 60 | a, b, c = new_variables( 3 ) 61 | 62 | s = smt2_solver() 63 | 64 | s.symbol( a, "a" ) 65 | s.symbol( b, "b" ) 66 | s.symbol( c, "c" ) 67 | s.install_symbol_table() 68 | 69 | s &= ( a == ( b & c ) ) 70 | s.solve() 71 | 72 | self.assertEqual( len( filter( lambda s: s == '(assert (= a (and b c)))', map( str.strip, open( 'meta.smt2', 'r' ).readlines() ) ) ), 1 ) 73 | 74 | delete_tmp_files() 75 | 76 | if __name__ == "__main__": 77 | unittest.main() 78 | 79 | -------------------------------------------------------------------------------- /tests/test_evaluator.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace metaSMT; 9 | using namespace metaSMT::solver; 10 | using namespace metaSMT::logic; 11 | 12 | namespace metaSMT { 13 | template <> 14 | struct Evaluator : public boost::mpl::true_ { 15 | template < typename Context > 16 | static typename Context::result_type eval(Context &ctx, char const &c) { 17 | // assert( (c == '1' || c == '0' || c == 'X' || c == 'x') && 18 | // "has to be 0, 1, X, or x character" ); 19 | 20 | if ( c == '1' ) { 21 | return evaluate(ctx, True); 22 | } 23 | else if ( c == '0' ) { 24 | return evaluate(ctx, False); 25 | } 26 | else if ( c == 'X' || c == 'x' ) { 27 | // prefer false in case of a don't care 28 | return evaluate(ctx, False); 29 | } 30 | 31 | // error 32 | std::string message = "trying evaluate an unsupported character: "; 33 | message += c; 34 | throw std::runtime_error(message); 35 | } 36 | }; // Evaluator 37 | } // metaSMT 38 | 39 | BOOST_FIXTURE_TEST_SUITE(eval, Solver_Fixture ) 40 | 41 | BOOST_AUTO_TEST_CASE( char_evaluator ) 42 | { 43 | predicate x = new_variable(); 44 | assertion(ctx, logic::equal(x, x)); 45 | BOOST_REQUIRE( solve(ctx) ); 46 | 47 | bool xd; 48 | assumption(ctx, logic::equal(x, '1')); 49 | BOOST_REQUIRE( solve(ctx) ); 50 | xd = read_value(ctx, x); 51 | BOOST_CHECK_EQUAL(xd, true); 52 | 53 | assumption(ctx, logic::equal(x, '0')); 54 | BOOST_REQUIRE( solve(ctx) ); 55 | xd = read_value(ctx, x); 56 | BOOST_CHECK_EQUAL(xd, false); 57 | 58 | assumption(ctx, logic::equal(x, 'X')); 59 | BOOST_REQUIRE( solve(ctx) ); 60 | xd = read_value(ctx, x); 61 | BOOST_CHECK_EQUAL(xd, false); 62 | 63 | BOOST_CHECK_THROW( 64 | assertion(ctx, logic::equal(x, 'U')) 65 | , std::runtime_error 66 | ); 67 | } 68 | 69 | BOOST_AUTO_TEST_SUITE_END() // eval 70 | 71 | // vim: ft=cpp:ts=2:sw=2:expandtab 72 | -------------------------------------------------------------------------------- /tests/test_lazy.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | // lazy headers 11 | 12 | using namespace metaSMT; 13 | using namespace logic; 14 | using namespace logic::QF_BV; 15 | namespace proto = boost::proto; 16 | 17 | 18 | BOOST_FIXTURE_TEST_SUITE(lazy_t, Solver_Fixture ) 19 | 20 | BOOST_AUTO_TEST_CASE( andiN ) 21 | { 22 | typedef ContextType::result_type result_type; 23 | 24 | boost::function< result_type ( predicate const &, predicate const & ) > 25 | lazy_andiN = metaSMT::lazy( ctx, And( arg1, Not(arg2)) ) ; 26 | 27 | predicate x = new_variable(); 28 | predicate y = new_variable(); 29 | 30 | assumption( ctx, metaSMT::logic::equal(And(x, Not(y)), lazy_andiN(x,y)) ); 31 | BOOST_REQUIRE( solve(ctx) ); 32 | 33 | assumption( ctx, nequal(And(x, Not(y)), lazy_andiN(x,y)) ); 34 | BOOST_REQUIRE( !solve(ctx) ); 35 | } 36 | 37 | BOOST_AUTO_TEST_CASE( lazy_result_type ) 38 | { 39 | typedef ContextType::result_type result_type; 40 | 41 | boost::function< result_type ( predicate const &, result_type const & ) > 42 | lazy_Xor = metaSMT::lazy( ctx, Xor( arg1, arg2) ) ; 43 | 44 | predicate x = new_variable(); 45 | result_type y = evaluate(ctx, new_variable()); 46 | 47 | assumption(ctx, metaSMT::logic::equal( Xor(x,y), lazy_Xor(x,y)) ); 48 | BOOST_REQUIRE( solve(ctx) ); 49 | 50 | assumption(ctx, nequal( Xor(x,y), lazy_Xor(x,y)) ); 51 | BOOST_REQUIRE( !solve(ctx) ); 52 | } 53 | 54 | BOOST_AUTO_TEST_CASE( lazy_accumulate ) 55 | { 56 | unsigned count = 100; 57 | std::vector< predicate > preds; 58 | for (unsigned i = 0; i < count; ++i) { 59 | preds.push_back( new_variable() ); 60 | } 61 | 62 | ContextType::result_type initial = evaluate(ctx, False); 63 | 64 | metaSMT::assertion( ctx, std::accumulate(preds.begin(), preds.end(), initial, 65 | metaSMT::lazy(ctx, Xor(arg1, arg2) ) 66 | )); 67 | 68 | BOOST_REQUIRE( solve(ctx) ); 69 | } 70 | 71 | BOOST_AUTO_TEST_SUITE_END() //lazy_t 72 | 73 | // vim: ft=cpp:ts=2:sw=2:expandtab 74 | 75 | -------------------------------------------------------------------------------- /tests/test_random_bits.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | using namespace metaSMT; 9 | using namespace metaSMT::solver; 10 | using namespace metaSMT::logic; 11 | namespace proto = boost::proto; 12 | using boost::dynamic_bitset; 13 | 14 | BOOST_FIXTURE_TEST_SUITE(assign_random_bits_t, Solver_Fixture ) 15 | 16 | BOOST_AUTO_TEST_CASE( test_random_bits ) 17 | { 18 | bitvector x = new_bitvector(32); 19 | bitvector y = new_bitvector(32); 20 | bitvector z = new_bitvector(32); 21 | 22 | std::vector variables; 23 | variables.push_back(x); 24 | variables.push_back(y); 25 | variables.push_back(z); 26 | 27 | unsigned x1, y1, z1; 28 | unsigned x2, y2, z2; 29 | 30 | 31 | BOOST_REQUIRE( solve(ctx) ); 32 | assign_random_bits(ctx, variables); 33 | 34 | x1 = read_value(ctx,x); 35 | y1 = read_value(ctx,y); 36 | z1 = read_value(ctx,z); 37 | 38 | BOOST_REQUIRE ( solve(ctx) ); 39 | assign_random_bits(ctx, variables); 40 | 41 | x2 = read_value(ctx,x); 42 | y2 = read_value(ctx,y); 43 | z2 = read_value(ctx,z); 44 | 45 | BOOST_REQUIRE ( solve(ctx) ); 46 | 47 | BOOST_REQUIRE ( x1 != x2 || y1 != y2 || z1 != z2 ); 48 | 49 | } 50 | 51 | BOOST_AUTO_TEST_CASE( test_solve_random ) 52 | { 53 | bitvector x = new_bitvector(32); 54 | bitvector y = new_bitvector(32); 55 | bitvector z = new_bitvector(32); 56 | 57 | std::vector variables; 58 | variables.push_back(x); 59 | variables.push_back(y); 60 | variables.push_back(z); 61 | 62 | unsigned x1, y1, z1; 63 | unsigned x2, y2, z2; 64 | 65 | BOOST_REQUIRE( solve_with_random_bits(ctx, variables) ); 66 | 67 | x1 = read_value(ctx,x); 68 | y1 = read_value(ctx,y); 69 | z1 = read_value(ctx,z); 70 | 71 | BOOST_REQUIRE ( solve_with_random_bits(ctx,variables) ); 72 | x2 = read_value(ctx,x); 73 | y2 = read_value(ctx,y); 74 | z2 = read_value(ctx,z); 75 | 76 | BOOST_REQUIRE ( solve_with_random_bits(ctx,variables) ); 77 | 78 | BOOST_REQUIRE ( x1 != x2 || y1 != y2 || z1 != z2 ); 79 | 80 | } 81 | 82 | BOOST_AUTO_TEST_SUITE_END() //Solver 83 | 84 | // vim: ft=cpp:ts=2:sw=2:expandtab 85 | -------------------------------------------------------------------------------- /bindings/python/examples/rect_qf_bv.py: -------------------------------------------------------------------------------- 1 | 2 | from metasmt.core import * 3 | from metasmt.support import bits_for_values 4 | 5 | class rectangle(object): 6 | """a symbolic rectangle on a square field (limit x limit) """ 7 | def __init__(self, limit): 8 | 9 | ## how many bits are requred for limit 10 | self.bitwidth = bits_for_values( limit ) 11 | 12 | 13 | ## store the upper bound (already as metasmt Expression) 14 | self.limit = bv_uint(limit)[self.bitwidth] 15 | 16 | ## create the bounding box for the rectangle 17 | ## lower left corner, width, height 18 | self.xpos = new_bitvector(self.bitwidth) 19 | self.ypos = new_bitvector(self.bitwidth) 20 | self.xwid = new_bitvector(self.bitwidth) 21 | self.yhei = new_bitvector(self.bitwidth) 22 | 23 | def constraints(self): 24 | 25 | ## vvvv bit-vector unsigned less equal 26 | x_in_lim = bv_ule( 27 | bv_add( zero_extend(1, self.xpos), 28 | zero_extend(1, self.xwid)), 29 | zero_extend(1,self.limit) 30 | ) 31 | y_in_lim = bv_ule( bv_add( self.ypos, self.yhei), self.limit ) 32 | 33 | ## vvvv bit-vector unsigned greater than 34 | wid_gt_0 = bv_ugt( self.xwid, bv_uint(0)[self.bitwidth] ) 35 | hei_gt_0 = bv_ugt( self.yhei, bv_uint(0)[self.bitwidth] ) 36 | 37 | ## all these comparisons operate on bitvector and return boolean symbols 38 | 39 | return logic_and( 40 | logic_and( x_in_lim, y_in_lim), 41 | logic_and( wid_gt_0, hei_gt_0) 42 | ) 43 | 44 | def intersects(self): 45 | pass 46 | 47 | def print_solution(self, solver): 48 | print ( 49 | solver.read_value(self.xpos), 50 | solver.read_value(self.ypos), 51 | solver.read_value(self.xwid), 52 | solver.read_value(self.yhei), 53 | ) 54 | 55 | 56 | def main(): 57 | for name, sc in available_solvers().items(): 58 | try: 59 | rect = rectangle(5) 60 | print "testing solver", name 61 | solver = sc() 62 | solver.assertion( rect.constraints() ) 63 | for i in xrange(5): 64 | if solver.solve(): 65 | rect.print_solution(solver) 66 | else: 67 | print "no rect found" 68 | except: 69 | print "error in solver", name 70 | 71 | if __name__ == '__main__': 72 | main() 73 | 74 | -------------------------------------------------------------------------------- /src/metaSMT/tags/Logic.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "attribute.hpp" 4 | #include 5 | #include 6 | 7 | namespace metaSMT { 8 | struct nil { 9 | typedef attr::ignore attribute; 10 | 11 | bool operator< (nil const &) const { return false; }; 12 | template friend STREAM & 13 | operator<< (STREAM & out, nil const & ) { out << "nil"; return out; } 14 | }; 15 | 16 | namespace logic { 17 | namespace tag { 18 | 19 | #define PRINT(Tag, body) template \ 20 | friend STREAM & operator<< (STREAM & out, Tag const & self) \ 21 | { out << body; return out; } 22 | #define TAG( NAME, ATTR ) struct NAME##_tag { \ 23 | typedef attr::ATTR attribute; \ 24 | bool operator<(NAME##_tag const &) const {return false;} \ 25 | PRINT(NAME##_tag, #NAME) \ 26 | }; 27 | 28 | // variable tag 29 | struct var_tag { unsigned id; 30 | typedef attr::ignore attribute; 31 | 32 | PRINT(var_tag, "var_tag[" << self.id << "]") 33 | bool operator< (var_tag const & other) const { 34 | return id < other.id; 35 | } 36 | }; 37 | 38 | // constants 39 | TAG(true, constant) 40 | TAG(false, constant) 41 | TAG(bool, constant) 42 | 43 | // unary 44 | TAG(not, unary) 45 | 46 | // binary 47 | TAG(equal, binary) // chainable 48 | TAG(nequal, binary) 49 | TAG(distinct, binary) // pairwise 50 | TAG(implies, binary) // right_assoc 51 | 52 | TAG(and, left_assoc) 53 | TAG(nand, binary) 54 | TAG(or, left_assoc) 55 | TAG(nor, binary) 56 | TAG(xor, binary) // left_assoc 57 | TAG(xnor, binary) 58 | 59 | // ternary 60 | TAG(ite, ternary) 61 | 62 | #undef PRINT 63 | #undef TAG 64 | // 65 | // tag variant Predicate 66 | typedef boost::mpl::vector< 67 | false_tag 68 | , true_tag 69 | , not_tag 70 | , equal_tag 71 | , nequal_tag 72 | , distinct_tag 73 | , and_tag 74 | , nand_tag 75 | , or_tag 76 | , nor_tag 77 | , xor_tag 78 | , xnor_tag 79 | , implies_tag 80 | , ite_tag 81 | , var_tag 82 | >::type Predicate_Tags; 83 | 84 | typedef boost::make_variant_over< Predicate_Tags >::type Predicate_Tag; 85 | 86 | } // namespace tag 87 | } // namespace logic 88 | } // namespace metaSMT 89 | 90 | // vim: ft=cpp:ts=2:sw=2:expandtab 91 | -------------------------------------------------------------------------------- /src/metaSMT/support/cardinality/deprecated_api.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Evaluator.hpp" 4 | 5 | namespace metaSMT { 6 | 7 | namespace cardtags = metaSMT::logic::cardinality::tag; 8 | 9 | template 10 | typename Context::result_type 11 | one_hot(Context &ctx, std::vector const &ps) { 12 | assert(ps.size() > 0 && "One hot encoding requires at least one input variable"); 13 | 14 | if (ps.size() == 1) { 15 | return evaluate(ctx, logic::equal(ps[0], logic::True)); 16 | } 17 | 18 | typename Context::result_type zero_rail = evaluate(ctx, ps[0]); 19 | typename Context::result_type one_rail = evaluate(ctx, Not(ps[0])); 20 | 21 | for (unsigned u = 1; u < ps.size() - 1; ++u) { 22 | zero_rail = evaluate(ctx, Ite(ps[u], one_rail, zero_rail)); 23 | one_rail = evaluate(ctx, Ite(ps[u], logic::False, one_rail)); 24 | } 25 | 26 | return evaluate(ctx, Ite(ps[ps.size()-1], one_rail, zero_rail)); 27 | } 28 | 29 | template 30 | typename Context::result_type 31 | cardinality_eq(Context &ctx, std::vector const &ps, unsigned cardinality) { 32 | return evaluate(ctx, 33 | cardinality::cardinality(cardtags::eq_tag(), ps, cardinality) 34 | ); 35 | } 36 | 37 | template 38 | typename Context::result_type 39 | cardinality_geq(Context &ctx, std::vector const &ps, unsigned cardinality) { 40 | return evaluate(ctx, 41 | cardinality::cardinality(cardtags::ge_tag(), ps, cardinality) 42 | ); 43 | } 44 | 45 | template 46 | typename Context::result_type 47 | cardinality_leq(Context &ctx, std::vector const &ps, unsigned cardinality) { 48 | return evaluate(ctx, 49 | cardinality::cardinality(cardtags::le_tag(), ps, cardinality) 50 | ); 51 | } 52 | 53 | template 54 | typename Context::result_type 55 | cardinality_gt(Context &ctx, std::vector const &ps, unsigned cardinality) { 56 | return evaluate(ctx, 57 | cardinality::cardinality(cardtags::gt_tag(), ps, cardinality) 58 | ); 59 | } 60 | 61 | template 62 | typename Context::result_type 63 | cardinality_lt(Context &ctx, std::vector const &ps, unsigned cardinality) { 64 | return evaluate(ctx, 65 | cardinality::cardinality(cardtags::lt_tag(), ps, cardinality) 66 | ); 67 | } 68 | } // metaSMT 69 | -------------------------------------------------------------------------------- /toolbox/factorization/factorization.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | 11 | using namespace metaSMT; 12 | using namespace metaSMT::logic; 13 | using namespace metaSMT::logic::QF_BV; 14 | using namespace metaSMT::solver; 15 | using namespace std; 16 | 17 | 18 | template 19 | struct my_algo 20 | { 21 | typedef int result_type; 22 | 23 | my_algo ( unsigned width ) : 24 | width_ (width) {}; 25 | 26 | result_type operator()() 27 | { 28 | const unsigned width = width_; 29 | 30 | bitvector a = new_bitvector(width); 31 | bitvector b = new_bitvector(width); 32 | bitvector c = new_bitvector(2*width); 33 | 34 | bitvector zero = new_bitvector(width); 35 | assertion( ctx, equal(zero, bvuint(0,width)) ); 36 | assertion( ctx, nequal(a, bvuint(1,width)) ); 37 | assertion( ctx, nequal(b, bvuint(1,width)) ); 38 | 39 | assertion( ctx, equal(c, bvmul( concat(zero, a), concat(zero,b)) )); 40 | 41 | int valids = 0; 42 | for (unsigned i = 0; i < 10; i++) 43 | { 44 | unsigned r = (unsigned long long)rand()%(1ull< 69 | using namespace std; 70 | 71 | int main(int argc, const char *argv[]) 72 | { 73 | typedef mpl::vector2 < 74 | DirectSolver_Context< SWORD_Backend > 75 | , DirectSolver_Context< Z3_Backend > 76 | > SolverVec; 77 | 78 | if( argc < 3) { 79 | cout << "usage: example3 solver width\nsolver:\n\t0 - SWORD\n\t1 - Z3" << endl; 80 | exit(1); 81 | } 82 | 83 | 84 | unsigned solver = atoi ( argv[1] ); 85 | unsigned width = atoi ( argv[2] ); 86 | 87 | int val = run_algorithm ( solver, width ); 88 | 89 | cout << "Got " << val << endl; 90 | 91 | 92 | return 0; 93 | } 94 | -------------------------------------------------------------------------------- /tests/test_aig.cpp: -------------------------------------------------------------------------------- 1 | 2 | #define BOOST_TEST_MODULE test_aig 3 | #include 4 | 5 | //internal includes 6 | #include 7 | #include 8 | #include 9 | 10 | //external includes 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include 18 | 19 | using namespace metaSMT; 20 | 21 | struct clause_printer 22 | { 23 | void clause ( std::vector < SAT::tag::lit_tag > const& clause ) 24 | { 25 | BOOST_FOREACH ( SAT::tag::lit_tag const& lit, clause ) 26 | std::cout << lit.id << " "; 27 | std::cout << std::endl; 28 | } 29 | 30 | void assertion ( SAT::tag::lit_tag const& lit ) 31 | { 32 | std::cout << "Assertion: " << lit.id << std::endl; 33 | } 34 | void assumption ( SAT::tag::lit_tag const& lit ) 35 | { 36 | std::cout << "Assumption: " << lit.id << std::endl; 37 | } 38 | 39 | bool solve () 40 | { 41 | return false; 42 | } 43 | 44 | }; 45 | 46 | 47 | class aig_Fixture { 48 | public: 49 | protected: 50 | DirectSolver_Context < SAT_Aiger < clause_printer > > ctx; 51 | }; 52 | 53 | using boost::proto::display_expr; 54 | 55 | 56 | BOOST_FIXTURE_TEST_SUITE(aig_t, aig_Fixture ) 57 | 58 | BOOST_AUTO_TEST_CASE( syntax ) 59 | { 60 | using namespace logic; 61 | BOOST_REQUIRE_EQUAL( evaluate (ctx, False ), aiger_false); 62 | BOOST_REQUIRE_EQUAL( evaluate (ctx, True ), aiger_true); 63 | 64 | BOOST_REQUIRE_EQUAL( evaluate (ctx, Not(True) ), aiger_false); 65 | BOOST_REQUIRE_EQUAL( evaluate (ctx, Not(False) ), aiger_true); 66 | 67 | BOOST_REQUIRE_EQUAL( evaluate (ctx, Not(Not(True) )), aiger_true); 68 | BOOST_REQUIRE_EQUAL( evaluate (ctx, Not(Not(False)) ), aiger_false); 69 | 70 | predicate x = new_variable (); 71 | predicate y = new_variable (); 72 | assertion ( ctx, And ( x, y) ); 73 | 74 | bool r = solve ( ctx ); 75 | 76 | 77 | 78 | // BOOST_REQUIRE_EQUAL(to_aiger( True, aig )()(),aiger_true); 79 | // 80 | // display_expr( Not(False)); 81 | // BOOST_REQUIRE_EQUAL(to_aiger ( Not(False), aig)( )(), aiger_true); 82 | // BOOST_REQUIRE_EQUAL(to_aiger ( Not(True ), aig)(), aiger_false); 83 | // 84 | // BOOST_REQUIRE_EQUAL(to_aiger( Not(Not(False)), aig )(), aiger_false); 85 | // BOOST_REQUIRE_EQUAL(to_aiger( Not(Not(True)), aig )(), aiger_true); 86 | } 87 | 88 | BOOST_AUTO_TEST_SUITE_END() //QF_BV 89 | 90 | // vim: ft=cpp:ts=2:sw=2:expandtab 91 | -------------------------------------------------------------------------------- /src/metaSMT/support/Options.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../API/Options.hpp" 4 | 5 | #include 6 | 7 | #include 8 | 9 | namespace metaSMT { 10 | struct Options; 11 | 12 | namespace option { 13 | struct NOPCommand { 14 | template < typename SolverType, typename T1 > 15 | static void action( SolverType const &, T1 const & ) { 16 | /* ignore command */ 17 | } 18 | 19 | template < typename SolverType, typename T1, typename T2 > 20 | static void action( SolverType const &, T1 const &, T2 const & ) { 21 | /* ignore command */ 22 | } 23 | 24 | template < typename SolverType, typename T1, typename T2, typename T3 > 25 | static void action( SolverType const &, T1 const &, T2 const &, T3 const & ) { 26 | /* ignore command */ 27 | } 28 | }; // NOPCommand 29 | 30 | struct SetupOptionMapCommand { 31 | template < typename SolverType > 32 | static void action( SolverType &ctx, Options const &opt ) { 33 | ctx.command( setup_option_map_cmd(), opt ); 34 | } 35 | }; // SetupOptionMapCommand 36 | 37 | struct SetOptionCommand { 38 | template < typename SolverType > 39 | static void action( SolverType &ctx, Options const &opt, 40 | std::string const &key, std::string const &value ) { 41 | ctx.command( set_option_cmd(), opt, key, value ); 42 | } 43 | }; // SetOptionCommand 44 | } // option 45 | 46 | struct Options { 47 | typedef std::map< std::string, std::string > Map; 48 | typedef boost::shared_ptr< Map > SharedMap; 49 | 50 | Options() 51 | : map( new Map() ) 52 | {} 53 | 54 | Options(Map const &map) 55 | : map( new Map(map) ) 56 | {} 57 | 58 | void set(std::string const &key, std::string const &value) { 59 | assert( map != 0 ); 60 | (*map)[ key ] = value; 61 | } 62 | 63 | std::string get( std::string const &key ) const { 64 | assert( map != 0 ); 65 | Map::const_iterator it = map->find( key ); 66 | if ( it != map->end() ) { 67 | return it->second; 68 | } 69 | 70 | // Option has not been set. 71 | assert(false && "Could not determine value in map"); 72 | throw std::exception(); 73 | } 74 | 75 | std::string get( std::string const &key, std::string const &default_value ) const { 76 | assert( map != 0 ); 77 | Map::const_iterator it = map->find( key ); 78 | if ( it != map->end() ) { 79 | return it->second; 80 | } 81 | 82 | return default_value; 83 | } 84 | 85 | SharedMap map; 86 | }; // Options 87 | } 88 | -------------------------------------------------------------------------------- /src/metaSMT/API/SymbolTable.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../Features.hpp" 4 | 5 | #include 6 | #include 7 | 8 | namespace metaSMT { 9 | 10 | struct set_symbol_table_cmd { typedef void result_type; }; 11 | 12 | /** 13 | * \brief Use custom symbol table for variable naming 14 | * 15 | * 16 | * 17 | * \code 18 | * DirectSolver_Context< SMT2 > ctx; 19 | * 20 | * struct Lookup { 21 | * std::map &map_; 22 | * 23 | * Lookup(std::map &map) 24 | * : map_(map) {} 25 | * 26 | * std::string operator()(unsigned id) { 27 | * return map_[id]; 28 | * } 29 | * 30 | * void insert(predicate p, std::string const &name) { 31 | * map_.insert(std::make_pair(boost::proto::value(p).id, name)); 32 | * } 33 | * }; 34 | * 35 | * 36 | * std::map symbols; 37 | * Lookup lookup(symbols); 38 | * 39 | * predicate x = new_variable(); 40 | * lookup.insert(x, "x"); 41 | * set_symbol_table( ctx, lookup); 42 | * 43 | * \endcode 44 | * \ingroup API 45 | * \defgroup SymbolTable SymbolTable API 46 | * @{ 47 | */ 48 | 49 | /** 50 | * \class IgnoreSymbolTable SymbolTable.hpp metaSMT/SymbolTable.hpp 51 | * \brief Ignore symbol table commands 52 | */ 53 | template 54 | struct IgnoreSymbolTable : Context { 55 | void command ( set_symbol_table_cmd const &, boost::function table) { 56 | /* ignored */ 57 | } 58 | 59 | using Context::command; 60 | }; 61 | 62 | namespace features { 63 | /* IgnoreSymbolTable supports symbol table (by ignoring it) */ 64 | template 65 | struct supports< IgnoreSymbolTable, set_symbol_table_cmd> 66 | : boost::mpl::true_ {}; 67 | 68 | /* Forward all other supported operations */ 69 | template 70 | struct supports< IgnoreSymbolTable, Feature> 71 | : supports::type {}; 72 | } 73 | 74 | /** 75 | * \brief set symbol table 76 | * \param ctx The context to work on 77 | * \param table Symbol table used to name variables 78 | * \return void 79 | * \throws Assertion at compile time if \c Context does not support symbol tables 80 | * 81 | */ 82 | template 83 | void set_symbol_table( Context & ctx, boost::function table) { 84 | BOOST_MPL_ASSERT_MSG(( features::supports::value ), 85 | context_does_not_support_symbol_table, (Context) ); 86 | ctx.command(set_symbol_table_cmd(), table); 87 | } 88 | 89 | /**@}*/ 90 | 91 | } /* metaSMT */ 92 | 93 | -------------------------------------------------------------------------------- /toolbox/metaSMT-server/SolverProcess.cpp: -------------------------------------------------------------------------------- 1 | #include "SolverProcess.hpp" 2 | #include 3 | #include 4 | #include 5 | 6 | const std::string SolverBase::success = "success"; 7 | const std::string SolverBase::unsupported = "unsupported"; 8 | const std::string SolverBase::error = "error"; 9 | 10 | const std::string SolverBase::sat = "sat"; 11 | const std::string SolverBase::unsat = "unsat"; 12 | const std::string SolverBase::unknown = "unknown"; 13 | 14 | bool fd_block(int fd, bool block) { 15 | int flags = fcntl(fd, F_GETFL, 0); 16 | if (flags == -1) 17 | return 0; 18 | 19 | if (block) 20 | flags &= ~O_NONBLOCK; 21 | else 22 | flags |= O_NONBLOCK; 23 | return fcntl(fd, F_SETFL, flags) != -1; 24 | } 25 | 26 | SolverProcess::SolverProcess(std::string const &solver_type) 27 | : solver_type(solver_type) 28 | , sb(0) 29 | , num_answers(0) 30 | {} 31 | 32 | SolverProcess::~SolverProcess() { 33 | for (int n = 0; n < 2; ++n) { 34 | close(fd_c2p[n]); 35 | close(fd_p2c[n]); 36 | } 37 | 38 | if ( sb ) { 39 | delete sb; 40 | } 41 | } 42 | 43 | int SolverProcess::initPipes() { 44 | return pipe(fd_c2p) != -1 && pipe(fd_p2c) != -1; 45 | } 46 | 47 | std::string SolverProcess::child_read_command() { 48 | return read_command(fd_p2c[0]); 49 | } 50 | 51 | void SolverProcess::child_write_command(std::string s) { 52 | write_command(fd_c2p[1], s); 53 | } 54 | 55 | void SolverProcess::parent_write_command(std::string s) { 56 | write_command(fd_p2c[1], s); 57 | } 58 | 59 | std::string SolverProcess::parent_read_command() { 60 | std::string r; 61 | if (*p2c_read_command.rbegin() == '\n') { 62 | p2c_read_command.erase(p2c_read_command.find_last_not_of(" \n\r\t") + 1); 63 | r = p2c_read_command; 64 | } 65 | else { 66 | r = p2c_read_command + read_command(fd_c2p[0]); 67 | } 68 | p2c_read_command.clear(); 69 | ++num_answers; 70 | return r; 71 | } 72 | 73 | bool SolverProcess::parent_read_command_available() { 74 | fd_block(fd_c2p[0], false); 75 | char buf[1]; 76 | int len = read(fd_c2p[0], buf, 1); 77 | if (len > 0) 78 | p2c_read_command += buf[0]; 79 | bool r = len > 0 || !p2c_read_command.empty(); 80 | fd_block(fd_c2p[0], true); 81 | return r; 82 | } 83 | 84 | std::string SolverProcess::read_command(int fd) { 85 | std::string s; 86 | char buf[1]; 87 | do { 88 | int res = read(fd, buf, 1); 89 | assert( res > 0 ); 90 | s += buf[0]; 91 | } while (buf[0] != '\n'); 92 | s.erase(s.find_last_not_of("\n\r\t") + 1); 93 | return s; 94 | } 95 | 96 | void SolverProcess::write_command(int fd, std::string s) { 97 | s += '\n'; 98 | write(fd, s.c_str(), s.length()); 99 | } 100 | -------------------------------------------------------------------------------- /toolbox/pretty-print/pretty-print.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | using namespace metaSMT; 16 | using namespace metaSMT::solver; 17 | using namespace metaSMT::logic; 18 | using namespace metaSMT::logic::QF_BV; 19 | using namespace metaSMT::logic::Array; 20 | using namespace metaSMT::expression; 21 | 22 | struct Lookup { 23 | std::map map_; 24 | 25 | std::string operator()(unsigned id) { 26 | return map_[id]; 27 | } 28 | 29 | template < typename T > 30 | void insert(T const &v, std::string const &name) { 31 | map_.insert(std::make_pair(boost::proto::value(v).id, name)); 32 | } 33 | }; 34 | 35 | struct Printer { 36 | Printer(std::ostream &os, Lookup &table) 37 | : os(os) 38 | , table(table) 39 | {} 40 | 41 | template < typename T > 42 | std::ostream &operator<<(T expr); 43 | 44 | std::ostream &os; 45 | Lookup &table; 46 | }; // Printer 47 | 48 | template < typename T > 49 | std::ostream &Printer::operator<<(T expr) { 50 | return os; 51 | } 52 | 53 | template <> 54 | std::ostream &Printer::operator<<(logic_expression expr) { 55 | std::ostream_iterator out_it( os ); 56 | expression::print_expression_static( 57 | out_it, expr, table 58 | ); 59 | return os; 60 | } 61 | 62 | int main( int argc, char *argv[] ) { 63 | typedef DirectSolver_Context< 64 | ExpressionSolver< Z3_Backend > 65 | > ContextType; 66 | typedef ContextType::result_type result_type; 67 | 68 | ContextType ctx; 69 | Lookup lookup; 70 | 71 | Printer err(std::cerr, lookup); 72 | 73 | predicate x = new_variable(); 74 | lookup.insert(x, "x"); 75 | err << evaluate(ctx, x) << '\n'; 76 | 77 | predicate y = new_variable(); 78 | lookup.insert(y, "y"); 79 | result_type expr = evaluate(ctx, And(x, y)); 80 | err << expr << '\n'; 81 | 82 | unsigned const elem_width = 8; 83 | unsigned const index_width = 5; 84 | array a = new_array(elem_width, index_width); 85 | lookup.insert(a, "a"); 86 | err << evaluate(ctx, a) << '\n'; 87 | 88 | bitvector index = new_bitvector(index_width); 89 | lookup.insert(index, "index"); 90 | err << evaluate(ctx, store(a, index, new_bitvector(elem_width))) << '\n'; 91 | err << evaluate(ctx, select(a, index)) << '\n'; 92 | 93 | return 0; 94 | } 95 | -------------------------------------------------------------------------------- /src/metaSMT/support/dot_SMT_Graph.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "SMT_Graph.hpp" 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | namespace metaSMT { 10 | 11 | struct VertexDecorator 12 | { 13 | typedef void result_type; 14 | typedef boost::graph_traits::vertex_descriptor VertexT; 15 | 16 | VertexDecorator( const SMT_Graph & g, VertexT const & v , std::ostream & out) 17 | : _g(g), _v(v), out(out) {} 18 | 19 | void operator()(logic::QF_BV::tag::bvbin_tag const &) { 20 | using namespace boost; 21 | out << "[ label=\""; 22 | out << "bvbin(" << any_cast(get(vertex_arg, _g, _v)) << ")"; 23 | out << "\"]"; 24 | } 25 | 26 | void operator()(logic::QF_BV::tag::bvhex_tag const &) { 27 | using namespace boost; 28 | out << "[ label=\""; 29 | out << "bvhex(" << any_cast(get(vertex_arg, _g, _v)) << ")"; 30 | out << "\"]"; 31 | } 32 | 33 | void operator()(logic::QF_BV::tag::bvuint_tag const &) { 34 | using namespace boost; 35 | out << "[ label=\""; 36 | out << "bvuint" << any_cast >(get(vertex_arg, _g, _v)); 37 | out << "\"]"; 38 | } 39 | 40 | void operator()(logic::QF_BV::tag::bvsint_tag const &) { 41 | using namespace boost; 42 | out << "[ label=\""; 43 | out << "bvsint" << any_cast >(get(vertex_arg, _g, _v)); 44 | out << "\"]"; 45 | } 46 | 47 | template 48 | void operator()(Tag const & t ){ 49 | using namespace boost; 50 | out << "[ label=\"" << out << "\"]"; 51 | } 52 | 53 | private: 54 | const SMT_Graph & _g; 55 | const VertexT & _v; 56 | std::ostream & out; 57 | }; 58 | 59 | struct DotDecorator { 60 | DotDecorator(const SMT_Graph & g) 61 | : _g(g) { } 62 | 63 | typedef boost::graph_traits::vertex_descriptor VertexT; 64 | typedef boost::graph_traits::edge_descriptor EdgeT; 65 | 66 | void operator()(std::ostream & out, VertexT n ) { 67 | VertexDecorator vd(_g, n, out); 68 | boost::apply_visitor(vd, boost::get(boost::vertex_tag, _g, n) ); 69 | } 70 | 71 | void operator()(std::ostream & out, EdgeT e){ 72 | using namespace boost; 73 | out << "[ label=\""; 74 | out << "IN: " << get(edge_input, _g, e); 75 | out << "\"]"; 76 | } 77 | 78 | template 79 | void operator()(std::ostream & out, T2) const{ 80 | } 81 | 82 | private: 83 | SMT_Graph const & _g; 84 | }; 85 | 86 | 87 | inline void write_dot(std::ostream & out, SMT_Graph & g) { 88 | DotDecorator dotDecorator(g); 89 | write_graphviz(out, g, dotDecorator, dotDecorator); 90 | } 91 | 92 | } // namespace metaSMT 93 | // vim: ft=cpp:ts=2:sw=2:expandtab 94 | -------------------------------------------------------------------------------- /toolbox/sudoku/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_tool_executable( sudoku 2 | SOURCES 3 | sudoku.cpp 4 | REQUIRES 5 | Boolector_FOUND 6 | PicoSAT_FOUND 7 | MiniSat_FOUND 8 | Aiger_FOUND 9 | CUDD_FOUND 10 | ) 11 | 12 | ## run some sudokus as tests 13 | 14 | if(sudoku_ENABLED) 15 | set( _solvers boolector minisat picosat cudd graph_boolector graph_minisat graph_picosat graph_cudd) 16 | set( _valid_instances 17 | "n_gi_ldfbkc_eh_p_b_dmojnp_gfq_kilpf_ei_b_qn_m__jcm__g___j_e_f__b_kp___lcdb__jmhqm_b_f____ni__l_____fp_e___hcb_ngon_l_h_j__meif_k___po_f_n_l_g___fi_bh__p__d_oqjldg__kebqfc_jnimh_e_n__ilqob_dpc__qdc__piheo__gfmbf_____o_dklh___p_e_lbg_m_qn_ji_i___d_hec_jpkbq_" 18 | 19 | "n_gi_ld_bkc_eh_p_b_dmojnp_gfq_kilp__ei_b_qn_m__jcm__g___j_e_f__b_kp___lcdb__jmhqm_b______ni__l_____fp_e___hcb_ngon_l_h_j__mei__k___po_f_n_l_g____i_bh__p__d_oqjldg__kebqfc_jnimh_e_n__ilqob_dpc__qdc__piheo__g_mbf_____o_dklh___p_e_lbg_m_qn_ji_i___d_hec_jpkbq_" 20 | 21 | "____________eh_p_b_dmojnp_gfq_kilp__ei_b_q__m__jcm__g___j_e_f__b_kp____cdb__jmhqm_b______ni__l_____fp_e___hcb__gon___h_j____________________g____i_bh__p__d_oqj_dg__kebqfc_jnimh_e____il_________________eo__g_mbf_____o__________________qn_ji_i___d_hec_jpkbq_" 22 | 23 | "_jebflm__d_o__i___i_dqk_b__ehfo__q_____cp__n__j_g_of_j__qlimd_ke___j_h_f__bgp__cmbf_ocj__e______qp_____bj__cf_nokc_ni_qmo_fpld__fen_h___l___gb___d____leckm_i__nh_m__d_k__e__j_q______p__ng___l_eijmbnclk_d__p____lkq__jn__h_e_ip____i__e________fchgk_oi__lj__d" 24 | 25 | "___________o__i___i_dqk_b__ehfo__q_____cp__n____________qlimd_ke___j_h_f__bgp__cmbf_ocj__e______qp_____bj__cf_nokc_ni_qmo_fpld__fen_h___l___gb___d____leckm_i__nh_m__d_k__e__j_q______p__ng___l___________d__p____lkq__jn__h_e__________e________fchgk_oi__lj__d" 26 | 27 | "__________________________________________________i_____bg_______________h___________________________________________b____________g__________________f____________kn_______________c____________________________________________________________________________" 28 | ) 29 | set( _invalid_instances 30 | "n_gi_ldfbkc_eh_p_b_dmojnp_gfq_kilpf_ei_b_qn_m__jcm__g___j_e_f__b_kp___lcdb__jmhqm_b_f____ni__l_____fp_e___hcb_ngon_l_h_j__meif_k___po_f_n_l_g___fi_bh__p__d_oqjldg__kebqac_jnimh_e_n__ilqob_dpc__qdc__piheo__gfmbf_____o_dklh___p_e_lbg_m_qn_ji_i___d_hec_jpkbq_" 31 | ) 32 | 33 | set(sid 0) 34 | foreach(s ${_solvers}) 35 | set(iid 0) 36 | foreach(i ${_valid_instances}) 37 | set(_name sudoku_${s}_valid_${iid}) 38 | add_test(${_name} sudoku ${sid} ${i}) 39 | set_tests_properties (${_name} PROPERTIES TIMEOUT ${TIMEOUT}) 40 | math(EXPR iid "${iid} + 1") 41 | endforeach(i) 42 | set(iid 0) 43 | foreach(i ${_invalid_instances}) 44 | set(_name sudoku_${s}_invalid_${iid}) 45 | add_test(${_name} sudoku ${sid} ${i}) 46 | set_property(TEST ${_name} PROPERTY WILL_FAIL TRUE) 47 | set_tests_properties (${_name} PROPERTIES TIMEOUT ${TIMEOUT}) 48 | math(EXPR iid "${iid} + 1") 49 | endforeach(i) 50 | math(EXPR sid "${sid} + 1") 51 | endforeach() 52 | 53 | endif() 54 | -------------------------------------------------------------------------------- /src/metaSMT/io/DimacsParser.hpp: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include "../API/AddClause.hpp" 19 | 20 | #define foreach BOOST_FOREACH 21 | 22 | namespace metaSMT 23 | { 24 | namespace dimacs 25 | { 26 | template 27 | bool parse_dimacs_clause ( Iterator first, Iterator last, std::vector < int >& clause ) 28 | { 29 | namespace qi = boost::spirit::qi; 30 | namespace ascii = boost::spirit::ascii; 31 | namespace phoenix = boost::phoenix; 32 | 33 | using namespace boost::assign; 34 | using qi::int_; 35 | using qi::phrase_parse; 36 | using qi::_1; 37 | using ascii::space; 38 | using phoenix::push_back; 39 | using phoenix::ref; 40 | 41 | bool r = phrase_parse ( first, last, 42 | ( 43 | *( int_ [ push_back ( ref( clause ), _1 )] - int_(0) ) >> int_(0) 44 | ) 45 | , 46 | space ); 47 | 48 | if ( first != last ) 49 | return false; 50 | return true; 51 | 52 | } 53 | 54 | template 55 | void addclause_to_context ( Context& ctx, std::vector < int > read_clause ) 56 | { 57 | std::vector < SAT::tag::lit_tag > clause ( read_clause.size() ); 58 | 59 | for ( unsigned i = 0; i < read_clause.size(); i++ ) 60 | { 61 | clause[i].id = read_clause[i]; 62 | } 63 | 64 | add_clause ( ctx, clause ); 65 | } 66 | 67 | template 68 | static bool parse_dimacs ( std::ifstream& stream, Context& context, std::set < unsigned >& vars ) 69 | { 70 | std::string line; 71 | unsigned n = 1; 72 | while ( std::getline ( stream, line ) ) 73 | { 74 | boost::trim ( line ); 75 | 76 | if (line.empty() || line[0] == 'p' || line[0] == 'c' ) continue; 77 | 78 | std::vector < int > clause; 79 | bool r = parse_dimacs_clause ( line.begin(), line.end(), clause ); 80 | 81 | addclause_to_context ( context, clause ); 82 | 83 | foreach ( int lit, clause ) 84 | { 85 | vars.insert ( abs ( lit ) ); 86 | } 87 | 88 | if (!r) 89 | { 90 | std::cerr << "Invalid Dimacs file at line " << n << "." << std::endl; 91 | return false; 92 | } 93 | n++; 94 | } 95 | 96 | return true; 97 | } 98 | } 99 | } 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /bindings/python/metasmt/operators.py: -------------------------------------------------------------------------------- 1 | from metasmt.core import * 2 | 3 | import inspect 4 | 5 | 6 | # Expressions 7 | def install_operator( sym, types, functions ): 8 | # Process Types 9 | if types == '*': 10 | types = [ predicate, bitvector, logic_expression ] 11 | elif not isinstance( types, list ): 12 | types = [ types ] 13 | 14 | # Process Functions 15 | if not isinstance( functions, tuple ): 16 | functions = ( functions, functions ) 17 | 18 | # Install the operator 19 | n = len( inspect.getargspec( functions[0] ).args ) 20 | if n == 1: 21 | f = lambda a: functions[to_logic_expression( a ).type()]( a ) 22 | elif n == 2: 23 | f = lambda a, b: functions[to_logic_expression( a ).type()]( a, b ) 24 | elif n == 3: 25 | f = lambda a, b, c: functions[to_logic_expression( a ).type()]( a, b, c ) 26 | else: 27 | def fun(*a): 28 | return functions[to_logic_expression(a[0]).type()](*a) 29 | f = fun 30 | 31 | for t in types: 32 | setattr( t, sym, f ) 33 | 34 | def member_extract(self, x): 35 | if isinstance( x, tuple ): 36 | return extract( x[0], x[1], self ) 37 | else: 38 | return extract( x, x, self ) 39 | 40 | def install_extract( types ): 41 | # Process Types 42 | if types == '*': 43 | types = [ predicate, bitvector, logic_expression ] 44 | elif not isinstance( types, list ): 45 | types = [ types ] 46 | 47 | for t in types: 48 | setattr( t, '__getitem__', member_extract ) 49 | 50 | install_operator( '__neg__', '*', ( logic_not, bv_not ) ) 51 | install_operator( '__eq__', '*', logic_equal ) 52 | install_operator( '__ne__', '*', logic_nequal ) 53 | install_operator( '__and__', '*', ( logic_and, bv_and ) ) 54 | install_operator( '__or__', '*', ( logic_or, bv_or ) ) 55 | install_operator( '__xor__', '*', ( logic_xor, bv_xor ) ) 56 | install_operator( '__invert__', [ bitvector, logic_expression ], bv_neg ) 57 | install_operator( '__add__', [ bitvector, logic_expression ], bv_add ) 58 | install_operator( '__mul__', [ bitvector, logic_expression ], bv_mul ) 59 | install_operator( '__sub__', [ bitvector, logic_expression ], bv_sub ) 60 | install_operator( '__div__', [ bitvector, logic_expression ], bv_udiv ) 61 | install_operator( '__mod__', [ bitvector, logic_expression ], bv_urem ) 62 | install_operator( '__lshift__', [ bitvector, logic_expression ], bv_shl ) 63 | install_operator( '__rshift__', [ bitvector, logic_expression ], bv_shr ) 64 | install_operator( '__lt__', [ bitvector, logic_expression ], bv_ult ) 65 | install_operator( '__gt__', [ bitvector, logic_expression ], bv_ugt ) 66 | install_operator( '__le__', [ bitvector, logic_expression ], bv_ule ) 67 | install_operator( '__ge__', [ bitvector, logic_expression ], bv_uge ) 68 | install_operator( '__pow__', [ bitvector, logic_expression ], concat ) 69 | 70 | install_extract( [ bitvector, logic_expression ] ) 71 | 72 | # Solver 73 | def _solver_iand( self, clause ): 74 | self.assertion( clause ) 75 | return self 76 | solver.__iand__ = _solver_iand 77 | -------------------------------------------------------------------------------- /bindings/python/metasmt/support.py: -------------------------------------------------------------------------------- 1 | from metasmt.core import * 2 | from metasmt.operators import * 3 | 4 | import math 5 | 6 | def _adjust( ps, width ): 7 | if width == None: 8 | width = len( ps ) 9 | else: 10 | ps = [ as_boolean(ps[i]) == True for i in range( width ) ] 11 | assert( width > 0 ) 12 | return ( ps, width ) 13 | 14 | def one_hot( ps, width = None ): 15 | # Parameters 16 | ps, width = _adjust( ps, width ) 17 | 18 | # Encoding 19 | if width == 1: 20 | return ps[0] == True 21 | 22 | zero_rail = ps[0] 23 | one_rail = -ps[0] 24 | 25 | for u in range( 1, width - 1 ): 26 | zero_rail = logic_ite( ps[u], one_rail, zero_rail ) 27 | one_rail = logic_ite( ps[u], False, one_rail ) 28 | 29 | return logic_ite( ps[width - 1], one_rail, zero_rail ) 30 | 31 | def cardinality_geq( ps, k, width = None ): 32 | # Parameters 33 | ps, width = _adjust( ps, width ) 34 | 35 | # Encoding 36 | if width < k: 37 | return False 38 | elif width == k: 39 | return reduce( logic_and, ps ) 40 | elif k == 0: 41 | return True 42 | 43 | rails = [ [None] * k ] * 2 44 | 45 | for v in range( width - k + 1 ): 46 | for u in range( k ): 47 | if u == 0 and v == 0: 48 | rails[0][0] = ps[0] 49 | elif u == 0: 50 | rails[v % 2][0] = logic_ite( ps[v], True, rails[(v-1)%2][0] ) 51 | elif v == 0: 52 | rails[0][u] = logic_ite( ps[u], rails[0][u-1], False ) 53 | else: 54 | rails[v%2][u] = logic_ite( ps[u+v], rails[v%2][u-1], rails[(v-1)%2][u] ) 55 | return rails[(width - k) % 2][k - 1] 56 | 57 | def cardinality_lt( ps, k, width = None ): 58 | return logic_not( cardinality_geq( ps, k, width ) ) 59 | 60 | def cardinality_leq( ps, k, width = None ): 61 | return logic_not( cardinality_geq( ps, k + 1, width ) ) 62 | 63 | def cardinality_gt( ps, k, width = None ): 64 | return logic_not( cardinality_leq( ps, k, width ) ) 65 | 66 | def cardinality_eq( ps, k, width = None ): 67 | return cardinality_geq( ps, k, width ) & cardinality_leq( ps, k, width ) 68 | 69 | # Join a list of single bit expressions as vector 70 | def bv_join( l ): 71 | def to_bv( c ): 72 | if c.type() == 0: 73 | return logic_ite( c, bit1, bit0 ) 74 | else: 75 | return c 76 | return reduce( concat, reversed( map( to_bv, l ) ) ) 77 | 78 | # Counts the bits in a bit-vector in a very inefficient way 79 | def bv_count( bv, width ): 80 | return reduce( bv_add, [ zero_extend( width - 1, bv[i] ) for i in range( width ) ], bv_uint[width]( 0 ) ) 81 | 82 | 83 | # Get bit-width for values 84 | def bits_for_values( values ): 85 | return int( math.ceil( math.log( values ) / math.log( 2.0 ) ) ) 86 | 87 | def as_boolean( bool_or_bit ): 88 | """if the paramter is boolean, returns it. If it is 89 | a bitvector returns parameter != bit0. This only 90 | works for 1-bit bitvectors. 91 | """ 92 | 93 | if bool_or_bit.type() == 0: 94 | # boolean 95 | return bool_or_bit 96 | else: 97 | return logic_nequal(bool_or_bit, bit0) 98 | -------------------------------------------------------------------------------- /tests/test_QF_UF.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | using namespace metaSMT; 9 | using namespace metaSMT::logic; 10 | using namespace metaSMT::logic::QF_UF; 11 | using namespace metaSMT::logic::QF_BV; 12 | namespace proto = boost::proto; 13 | using boost::dynamic_bitset; 14 | 15 | 16 | BOOST_FIXTURE_TEST_SUITE(QF_UF, Solver_Fixture ) 17 | 18 | BOOST_AUTO_TEST_CASE( equal_bool ) { 19 | using namespace type; 20 | 21 | unsigned const w = 8; 22 | Uninterpreted_Function f = declare_function(Boolean())(BitVector(w)); 23 | bitvector x = new_bitvector(w); 24 | 25 | assertion(ctx, equal(f(x), f(x)) ); 26 | BOOST_REQUIRE( solve(ctx) ); 27 | 28 | assertion(ctx, nequal(f(x), f(x)) ); 29 | BOOST_REQUIRE( !solve(ctx) ); 30 | } 31 | 32 | BOOST_AUTO_TEST_CASE( equal_bitvector ) { 33 | using namespace type; 34 | unsigned const result_width = 4; 35 | unsigned const param_width = 8; 36 | Uninterpreted_Function f = declare_function(BitVector(result_width))(BitVector(param_width)); 37 | bitvector x = new_bitvector(param_width); 38 | 39 | assertion(ctx, equal(f(x), f(x)) ); 40 | BOOST_REQUIRE( solve(ctx) ); 41 | 42 | assertion(ctx, nequal(f(x), f(x)) ); 43 | BOOST_REQUIRE( !solve(ctx) ); 44 | } 45 | 46 | BOOST_AUTO_TEST_CASE( functional_consistency ) { 47 | using namespace type; 48 | 49 | unsigned const w = 8; 50 | Uninterpreted_Function f = declare_function(Boolean())(BitVector(w)); 51 | bitvector x = new_bitvector(w); 52 | bitvector y = new_bitvector(w); 53 | 54 | // functional consistency: 55 | // ( x == y ) --> ( f(x) == f(y) ) 56 | assertion(ctx, equal(x, y) ); 57 | 58 | assertion(ctx, equal(f(x), f(y)) ); 59 | BOOST_REQUIRE( solve(ctx) ); 60 | } 61 | 62 | BOOST_AUTO_TEST_CASE( two_arguments ) { 63 | using namespace type; 64 | unsigned const w = 8; 65 | 66 | Uninterpreted_Function f = declare_function(Boolean())(BitVector(w))(BitVector(w)); 67 | bitvector x = new_bitvector(w); 68 | 69 | assertion(ctx, equal(f(x,x), f(x,x))); 70 | BOOST_REQUIRE( solve(ctx) ); 71 | } 72 | 73 | BOOST_AUTO_TEST_CASE( three_arguments ) { 74 | using namespace type; 75 | unsigned const w = 8; 76 | 77 | Uninterpreted_Function f = declare_function(Boolean())(BitVector(w))(BitVector(w))(BitVector(w)); 78 | bitvector x = new_bitvector(w); 79 | 80 | assertion(ctx, equal(f(x,x,x), f(x,x,x))); 81 | BOOST_REQUIRE( solve(ctx) ); 82 | } 83 | 84 | BOOST_AUTO_TEST_CASE( variable_equality ) { 85 | using namespace type; 86 | 87 | unsigned const w = 8; 88 | Uninterpreted_Function f = declare_function(Boolean())(BitVector(w)); 89 | Uninterpreted_Function g = declare_function(Boolean())(BitVector(w)); 90 | bitvector x = new_bitvector(w); 91 | 92 | bool cmp = (f == f); 93 | BOOST_CHECK( cmp ); 94 | 95 | cmp = (g == f); 96 | BOOST_CHECK( !cmp ); 97 | 98 | cmp = (f == g); 99 | BOOST_CHECK( !cmp ); 100 | } 101 | 102 | BOOST_AUTO_TEST_SUITE_END() // QF_UF 103 | 104 | // vim: ft=cpp:ts=2:sw=2:expandtab 105 | --------------------------------------------------------------------------------