metaSMT git
|
00001 #pragma once 00002 00003 #include "../tags/QF_BV.hpp" 00004 #include "../result_wrapper.hpp" 00005 00006 #include <mathsat.h> 00007 00008 #include <iostream> 00009 #include <boost/mpl/map.hpp> 00010 #include <boost/tuple/tuple_io.hpp> 00011 #include <boost/lexical_cast.hpp> 00012 00013 00014 namespace metaSMT { 00015 namespace solver { 00016 00017 namespace predtags = ::metaSMT::logic::tag; 00018 namespace bvtags = ::metaSMT::logic::QF_BV::tag; 00019 00020 class mathsat_Context { 00021 00022 public: 00023 typedef msat_term result_type; 00024 00025 mathsat_Context () 00026 : env_( msat_create_env() ) 00027 , assumptions_( msat_make_true(env_) ) 00028 { 00029 msat_add_theory(env_, MSAT_WORD); 00030 } 00031 00032 ~mathsat_Context() { 00033 msat_destroy_env(env_); 00034 } 00035 00036 void assertion( result_type e ) { 00037 //char * p = msat_to_msat(env_, e); 00038 //printf(p); 00039 //free(p); 00040 msat_assert_formula(env_, e); 00041 } 00042 00043 void assumption( result_type e ) { 00044 //char * p = msat_to_msat(env_, assumptions_); 00045 //printf(p); 00046 //free(p); 00047 assumptions_ = msat_make_and(env_, e, assumptions_); 00048 } 00049 00050 bool solve() { 00051 msat_pop_backtrack_point(env_); 00052 msat_push_backtrack_point(env_); 00053 msat_assert_formula(env_, assumptions_); 00054 bool ret = msat_solve(env_) == MSAT_SAT; 00055 assumptions_ = msat_make_true(env_); 00056 return ret; 00057 } 00058 00059 result_wrapper read_value(result_type var) 00060 { 00061 result_wrapper ret("X"); 00062 msat_term t = msat_get_model_value(env_, var); 00063 char* value = msat_to_msat(env_, t); 00064 if( strcmp(value, "FORMULA true\n" ) == 0 ) { 00065 //printf("formular true\n"); 00066 return result_wrapper(true); 00067 } else if( strcmp(value, "FORMULA false\n" ) == 0 ) { 00068 //printf("formular false\n"); 00069 return result_wrapper(false); 00070 } else if( strncmp(value, "FORMULA (0d", 11) == 0 ) { 00071 //printf("formular d\n"); 00072 char* beg = value+11; 00073 while (*beg && *beg != '_') ++beg; 00074 std::string widths (value+11, beg); 00075 ++beg; 00076 assert(*beg); 00077 char* end = beg+1; 00078 while (*end && *end != ')') ++end; 00079 assert(*end); 00080 std::string nums(beg, end); 00081 long width = boost::lexical_cast<long>(widths); 00082 long num = boost::lexical_cast<long>(nums); 00083 00084 std::vector<bool> v (width); 00085 std::vector<bool>::iterator ite =v.begin(); 00086 while (num !=0 ) { 00087 *ite = (num & 1); 00088 num>>=1; 00089 ++ite; 00090 } 00091 ret = result_wrapper(v); 00092 00093 //printf("<%s> %s %s\n", value, widths.c_str(), nums.c_str()); 00094 } 00095 //std::cout << value << ": " << ret << std::endl; 00096 free(value); 00097 return ret; 00098 } 00099 00100 result_type operator() (predtags::var_tag const & var, boost::any args ) 00101 { 00102 char buf[1024]; 00103 sprintf(buf, "var%d", var.id); 00104 00105 msat_decl decl = msat_declare_variable( env_, buf, MSAT_BOOL); 00106 return msat_make_variable(env_, decl); 00107 } 00108 00109 result_type operator() (predtags::false_tag , boost::any arg ) { 00110 return msat_make_false(env_); 00111 } 00112 00113 result_type operator() (predtags::true_tag , boost::any arg ) { 00114 return msat_make_true(env_); 00115 } 00116 00117 result_type operator() (predtags::not_tag , result_type a) { 00118 return msat_make_not(env_, a) ; 00119 } 00120 00121 00122 result_type operator() (predtags::equal_tag , result_type a, result_type b) { 00123 return msat_make_equal(env_, a, b) ; 00124 } 00125 00126 result_type operator() (predtags::nequal_tag , result_type a, result_type b) { 00127 return msat_make_not(env_, msat_make_equal(env_, a, b) ) ; 00128 } 00129 00130 result_type operator() (predtags::and_tag , result_type a, result_type b) { 00131 return msat_make_and(env_, a, b ) ; 00132 } 00133 00134 result_type operator() (predtags::xor_tag , result_type a, result_type b) { 00135 return msat_make_xor(env_, a, b ) ; 00136 } 00137 00138 result_type operator() (predtags::implies_tag , result_type a, result_type b) { 00139 return msat_make_implies(env_, a, b ) ; 00140 } 00141 00142 result_type operator() (predtags::or_tag , result_type a, result_type b) { 00143 return msat_make_or(env_, a, b ) ; 00144 } 00145 00146 result_type operator() (bvtags::var_tag const & var, boost::any args ) 00147 { 00148 char buf[1024]; 00149 sprintf(buf, "var%d", var.id); 00150 00151 msat_decl decl = msat_declare_variable( env_, buf, MSAT_BV+var.width); 00152 return msat_make_variable(env_, decl); 00153 } 00154 00155 result_type operator() (bvtags::bit0_tag , boost::any arg ) { 00156 return msat_make_number(env_, "0d1_0"); 00157 } 00158 00159 result_type operator() (bvtags::bit1_tag , boost::any arg ) { 00160 return msat_make_number(env_, "0d1_1"); 00161 } 00162 result_type operator() (bvtags::bvhex_tag , boost::any arg ) { 00163 std::string hex = boost::any_cast<std::string>(arg); 00164 char buf[4096]; 00165 sprintf(buf, "0h%u_%s", (unsigned)hex.size()*4, hex.c_str()); 00166 return msat_make_number(env_, buf); 00167 } 00168 00169 result_type operator() (bvtags::bvbin_tag , boost::any arg ) { 00170 std::string bin = boost::any_cast<std::string>(arg); 00171 char buf[4096]; 00172 sprintf(buf, "0b%u_%s", (unsigned)bin.size(), bin.c_str()); 00173 return msat_make_number(env_, buf); 00174 } 00175 result_type operator() (bvtags::bvuint_tag , boost::any arg ) { 00176 typedef boost::tuple<unsigned long, unsigned long> P; 00177 P p = boost::any_cast<P>(arg); 00178 //std::cout << "bvuint "<< p << std::endl; 00179 unsigned value = boost::get<0>(p); 00180 unsigned width = boost::get<1>(p); 00181 char buf[4096]; 00182 sprintf(buf, "0d%u_%u", width, value); 00183 return msat_make_number(env_, buf); 00184 } 00185 00186 00187 //result_type operator() (bvtags::bvsint_tag , boost::any arg ) { 00188 // typedef boost::tuple<long, unsigned long> P; 00189 // P p = boost::any_cast<P>(arg); 00190 // return boolector_int(_btor, boost::get<0>(p), boost::get<1>(p)); 00191 //} 00192 00193 result_type operator() (bvtags::bvnot_tag , result_type a ) { 00194 return msat_make_bv_not(env_, a); 00195 } 00196 00197 result_type operator() (bvtags::bvneg_tag , result_type a ) { 00198 return msat_make_bv_neg(env_, a); 00199 } 00200 00202 // Fallback operators // 00204 00205 template <typename TagT> 00206 result_type operator() (TagT tag, boost::any args ) { 00207 return msat_make_false(env_); 00208 } 00209 00210 00211 template <typename TagT> 00212 result_type operator() (TagT tag, result_type a ) { 00213 return msat_make_false(env_); 00214 } 00215 00216 template< result_type (*FN) (msat_env, result_type, result_type) > 00217 struct F2 { 00218 static result_type exec(msat_env e , result_type x, result_type y) 00219 { return (*FN)(e,x,y);} 00220 }; 00221 00222 result_type operator() (bvtags::bvnor_tag , result_type a, result_type b) { 00223 return msat_make_bv_not(env_, msat_make_bv_or(env_,a,b)); 00224 } 00225 00226 result_type operator() (bvtags::bvnand_tag , result_type a, result_type b) { 00227 return msat_make_bv_not(env_, msat_make_bv_and(env_,a,b)); 00228 } 00229 00230 result_type operator() (bvtags::bvxnor_tag , result_type a, result_type b) { 00231 return msat_make_bv_not(env_, msat_make_bv_xor(env_,a,b)); 00232 } 00233 00234 result_type operator() (bvtags::bvcomp_tag , result_type a, result_type b) { 00235 return msat_make_ite(env_, 00236 msat_make_equal(env_,a,b) 00237 , msat_make_number(env_, "0b1_1") 00238 , msat_make_number(env_, "0b1_0") 00239 ); 00240 } 00241 00242 template <typename TagT> 00243 result_type operator() (TagT tag, result_type a, result_type b) { 00244 using namespace boost::mpl; 00245 00246 typedef map< 00247 pair<bvtags::bvand_tag, F2<&msat_make_bv_and> > 00248 , pair<bvtags::bvor_tag, F2<&msat_make_bv_or > > 00249 , pair<bvtags::bvxor_tag, F2<&msat_make_bv_xor> > 00250 , pair<bvtags::bvadd_tag, F2<&msat_make_bv_plus> > 00251 , pair<bvtags::bvsub_tag, F2<&msat_make_bv_minus> > 00252 , pair<bvtags::bvmul_tag, F2<&msat_make_bv_times> > 00253 , pair<bvtags::bvslt_tag, F2<&msat_make_bv_slt> > 00254 > Opcode_Map; 00255 00256 typedef 00257 typename has_key< Opcode_Map, TagT >::type 00258 _has_key; 00259 00260 if (_has_key::value ) { 00261 typedef typename eval_if< 00262 _has_key 00263 , at< Opcode_Map, TagT > 00264 , identity< F2<msat_make_and> > 00265 >::type opcode; 00266 return opcode::exec(env_, a, b); 00267 } else { 00268 std::cout << "unknown operator: " << tag << std::endl; 00269 00270 assert(false && "unknown operator"); 00271 return msat_make_false(env_); 00272 } 00273 } 00274 00275 00276 template <typename TagT> 00277 result_type operator() (TagT tag, result_type a, result_type b, result_type c) { 00278 return msat_make_false(env_); 00279 } 00280 00281 private: 00282 msat_env env_; 00283 msat_term assumptions_; 00284 }; 00285 00286 } // namespace solver 00287 } // namespace metaSMT 00288 00289 // vim: ft=cpp:ts=2:sw=2:expandtab