metaSMT 2
|
00001 #pragma once 00002 00003 #include "../tags/SAT.hpp" 00004 #include "../result_wrapper.hpp" 00005 00006 00007 #include <vector> 00008 #include <iostream> 00009 00010 #include <boost/fusion/sequence/intrinsic.hpp> 00011 #include <boost/fusion/support/is_sequence.hpp> 00012 #include <boost/variant.hpp> 00013 #include <boost/any.hpp> 00014 #include <boost/foreach.hpp> 00015 00016 #include <minisat/core/Solver.h> 00017 00018 00019 namespace metaSMT { 00020 namespace solver { 00021 00022 class MiniSAT { 00023 00024 public: 00025 Minisat::Lit toLit ( SAT::tag::lit_tag lit ) 00026 { 00027 while ( solver_.nVars() <= abs ( lit.id ) ) 00028 solver_.newVar(); 00029 00030 return Minisat::mkLit ( abs ( lit.id ), lit.id < 0 ); 00031 } 00032 00033 void clause ( std::vector < SAT::tag::lit_tag > const& clause) 00034 { 00035 const size_t s = clause.size(); 00036 00037 // BOOST_FOREACH ( SAT::tag::lit_tag const& lit, clause ) 00038 // std::cout << lit.id << " "; 00039 // std::cout << "0" << std::endl; 00040 00041 switch ( s ) 00042 { 00043 case 1: 00044 solver_.addClause ( toLit ( clause[0] ) ); 00045 break; 00046 00047 case 2: 00048 solver_.addClause ( toLit ( clause[0] ), toLit ( clause[1] ) ); 00049 break; 00050 00051 case 3: 00052 solver_.addClause ( toLit ( clause[0] ) 00053 , toLit ( clause[1] ) 00054 , toLit ( clause[2] ) ); 00055 break; 00056 00057 default: 00058 { 00059 Minisat::vec<Minisat::Lit> v; 00060 for (unsigned i = 0; i < s; ++i) 00061 { 00062 v.push ( toLit ( clause[i] ) ); 00063 } 00064 solver_.addClause ( v ); 00065 break; 00066 } 00067 } 00068 } 00069 00070 00071 void assertion ( SAT::tag::lit_tag lit ) 00072 { 00073 solver_.addClause ( toLit ( lit ) ); 00074 } 00075 00076 void assumption ( SAT::tag::lit_tag lit ) 00077 { 00078 assumption_.push ( toLit ( lit ) ); 00079 } 00080 00081 00082 bool solve ( ) 00083 { 00084 if ( !solver_.okay()) { std::cout << "Okay? failed." << std::endl; return false; } 00085 00086 bool r = solver_.solve ( assumption_ ); 00087 00088 assumption_.clear (); 00089 return r; 00090 } 00091 00092 result_wrapper read_value ( SAT::tag::lit_tag lit ) 00093 { 00094 using namespace Minisat; 00095 00096 lbool val = solver_.modelValue (toLit(lit)); 00097 00098 if ( val == l_True ) 00099 return result_wrapper ( '1' ); 00100 else if ( val == l_False ) 00101 return result_wrapper ( '0' ); 00102 00103 return result_wrapper ('X'); 00104 } 00105 00106 00107 private: 00108 Minisat::Solver solver_; 00109 Minisat::vec<Minisat::Lit> assumption_; 00110 }; 00111 } /* solver */ 00112 } /* metaSMT */ 00113 // vim: ts=2 sw=2 et