metaSMT git
|
00001 #pragma once 00002 00003 #include "tags/QF_BV.hpp" 00004 #include "result_wrapper.hpp" 00005 00006 #include <boost/mpl/vector.hpp> 00007 #include <boost/proto/core.hpp> 00008 #include <boost/variant.hpp> 00009 #include <boost/any.hpp> 00010 00011 #include <iostream> 00012 00013 namespace metaSMT { 00014 namespace proto = boost::proto; 00015 namespace bvtags = ::metaSMT::logic::QF_BV::tag; 00016 namespace predtags = ::metaSMT::logic::tag; 00017 00018 00019 template <typename PredicateSolver> 00020 struct BitBlast { 00021 00022 typedef typename PredicateSolver::result_type result_base; 00023 typedef std::vector< result_base > bv_result; 00024 00025 typedef typename boost::mpl::vector2< 00026 result_base, bv_result 00027 >::type result_types_vec; 00028 00029 typedef typename boost::make_variant_over< result_types_vec >::type 00030 result_type; 00031 00032 00033 void assertion( result_type e ) { 00034 _solver.assertion( boost::get<result_base>(e) ); 00035 } 00036 00037 void assumption( result_type e ) { 00038 _solver.assumption( boost::get<result_base>(e) ); 00039 } 00040 00041 bool solve() { 00042 return _solver.solve(); 00043 } 00044 00045 result_type operator() (bvtags::var_tag var, boost::any arg ) { 00046 //printf("bitvec\n"); 00047 bv_result ret(var.width); 00048 for (unsigned i = 0; i < var.width; ++i) { 00049 ret[i]= _solver(predtags::var_tag(), arg); 00050 } 00051 return ret; 00052 } 00053 00054 result_type operator() ( bvtags::bvand_tag , result_type arg1, result_type arg2 ) 00055 { 00056 //printf("bvand\n"); 00057 bv_result a = boost::get<bv_result>(arg1); 00058 bv_result b = boost::get<bv_result>(arg2); 00059 assert(a.size()==b.size()); 00060 bv_result ret(a.size()); 00061 predtags::and_tag and_; 00062 00063 for (unsigned i = 0; i < a.size(); ++i) { 00064 ret[i]= _solver(and_, a[i], b[i]); 00065 } 00066 return ret; 00067 } 00068 00069 00070 result_type operator() ( bvtags::bvnand_tag , result_type arg1, result_type arg2 ) 00071 { 00072 //printf("bvnand\n"); 00073 bv_result a = boost::get<bv_result>(arg1); 00074 bv_result b = boost::get<bv_result>(arg2); 00075 assert(a.size()==b.size()); 00076 bv_result ret(a.size()); 00077 predtags::nand_tag nand_; 00078 00079 for (unsigned i = 0; i < a.size(); ++i) { 00080 ret[i]= _solver(nand_, a[i], b[i]); 00081 } 00082 return ret; 00083 } 00084 00085 result_type operator() ( bvtags::bvor_tag , result_type arg1, result_type arg2 ) 00086 { 00087 //printf("bvor\n"); 00088 bv_result a = boost::get<bv_result>(arg1); 00089 bv_result b = boost::get<bv_result>(arg2); 00090 assert(a.size()==b.size()); 00091 bv_result ret(a.size()); 00092 predtags::or_tag or_; 00093 00094 for (unsigned i = 0; i < a.size(); ++i) { 00095 ret[i]= _solver(or_, a[i], b[i]); 00096 } 00097 return ret; 00098 } 00099 00100 result_type operator() ( bvtags::bvnor_tag , result_type arg1, result_type arg2 ) 00101 { 00102 //printf("bvnor\n"); 00103 bv_result a = boost::get<bv_result>(arg1); 00104 bv_result b = boost::get<bv_result>(arg2); 00105 assert(a.size()==b.size()); 00106 bv_result ret(a.size()); 00107 predtags::nor_tag tag_; 00108 00109 for (unsigned i = 0; i < a.size(); ++i) { 00110 ret[i]= _solver(tag_, a[i], b[i]); 00111 } 00112 return ret; 00113 } 00114 00115 result_type operator() ( bvtags::bvnot_tag , result_type arg1 ) 00116 { 00117 //printf("bvnot\n"); 00118 bv_result a = boost::get<bv_result>(arg1); 00119 bv_result ret(a.size()); 00120 predtags::not_tag not_; 00121 00122 for (unsigned i = 0; i < a.size(); ++i) { 00123 ret[i] = _solver(not_,a[i]); 00124 } 00125 return ret; 00126 } 00127 00128 00129 result_type operator() ( bvtags::bvxor_tag , result_type arg1, result_type arg2 ) 00130 { 00131 //printf("bvxor\n"); 00132 bv_result a = boost::get<bv_result>(arg1); 00133 bv_result b = boost::get<bv_result>(arg2); 00134 assert(a.size()==b.size()); 00135 bv_result ret(a.size()); 00136 predtags::xor_tag xor_; 00137 00138 for (unsigned i = 0; i < a.size(); ++i) { 00139 ret[i]= _solver(xor_, a[i], b[i]); 00140 } 00141 return ret; 00142 } 00143 00144 result_type operator() ( bvtags::bvxnor_tag , result_type arg1, result_type arg2 ) 00145 { 00146 //printf("bvxnor\n"); 00147 bv_result a = boost::get<bv_result>(arg1); 00148 bv_result b = boost::get<bv_result>(arg2); 00149 assert(a.size()==b.size()); 00150 bv_result ret(a.size()); 00151 predtags::xnor_tag xnor_; 00152 00153 for (unsigned i = 0; i < a.size(); ++i) { 00154 ret[i]= _solver(xnor_, a[i], b[i]); 00155 } 00156 return ret; 00157 } 00158 00159 00160 result_type operator() (bvtags::bvult_tag, result_type arg1, result_type arg2) 00161 { 00162 bv_result a = boost::get<bv_result>(arg1); 00163 bv_result b = boost::get<bv_result>(arg2); 00164 assert(a.size()==b.size()); 00165 assert(a.size()>0); 00166 00167 typename bv_result::reverse_iterator ai, bi, end; 00168 ai = a.rbegin(); 00169 bi = b.rbegin(); 00170 end= a.rend(); 00171 00172 00173 result_base not_a = _solver(predtags::not_tag(), *ai); 00174 result_base ret = _solver(predtags::and_tag(),not_a, *bi); 00175 result_base equal = _solver(predtags::xnor_tag(), *ai, *bi); 00176 00177 00178 for (++ai, ++bi ; ai != end; ++ai, ++bi) 00179 { 00180 not_a = _solver(predtags::not_tag(), *ai); 00181 result_base now_less = _solver(predtags::and_tag(),not_a, *bi); 00182 result_base now = _solver(predtags::and_tag(), equal, now_less); 00183 00184 result_base now_equal = _solver(predtags::xnor_tag(), *ai, *bi); 00185 equal = _solver(predtags::and_tag(), now_equal, equal); 00186 00187 ret = _solver(predtags::or_tag(), ret, now); 00188 } 00189 return ret; 00190 } 00191 00192 result_type operator() (bvtags::bvugt_tag, result_type arg1, result_type arg2) 00193 { 00194 bv_result a = boost::get<bv_result>(arg1); 00195 bv_result b = boost::get<bv_result>(arg2); 00196 assert(a.size()==b.size()); 00197 assert(a.size()>0); 00198 00199 typename bv_result::reverse_iterator ai, bi, end; 00200 ai = a.rbegin(); 00201 bi = b.rbegin(); 00202 end= a.rend(); 00203 00204 00205 result_base not_b = _solver(predtags::not_tag(), *bi); 00206 result_base ret = _solver(predtags::and_tag(), *ai, not_b); 00207 result_base equal = _solver(predtags::xnor_tag(), *ai, *bi); 00208 00209 00210 for (++ai, ++bi ; ai != end; ++ai, ++bi) 00211 { 00212 not_b = _solver(predtags::not_tag(), *bi); 00213 result_base now_great = _solver(predtags::and_tag(),*ai, not_b); 00214 result_base now = _solver(predtags::and_tag(), equal, now_great); 00215 00216 result_base now_equal = _solver(predtags::xnor_tag(), *ai, *bi); 00217 equal = _solver(predtags::and_tag(), now_equal, equal); 00218 00219 ret = _solver(predtags::or_tag(), ret, now); 00220 } 00221 return ret; 00222 } 00223 00224 result_type operator() (bvtags::bvsgt_tag, result_type arg1, result_type arg2) 00225 { 00226 bv_result a = boost::get<bv_result>(arg1); 00227 bv_result b = boost::get<bv_result>(arg2); 00228 assert(a.size()==b.size()); 00229 assert(a.size()>0); 00230 00231 typename bv_result::reverse_iterator ai, bi, end; 00232 ai = a.rbegin(); 00233 bi = b.rbegin(); 00234 end= a.rend(); 00235 00236 result_base not_a = _solver(predtags::not_tag(), *ai); 00237 result_base not_b = _solver(predtags::not_tag(), *bi); 00238 result_base ret = _solver(predtags::and_tag(), not_a, *bi); 00239 result_base equal = _solver(predtags::xnor_tag(), *ai, *bi); 00240 00241 00242 for (++ai, ++bi ; ai != end; ++ai, ++bi) 00243 { 00244 not_b = _solver(predtags::not_tag(), *bi); 00245 00246 result_base now_great = _solver(predtags::and_tag(),*ai, not_b); 00247 result_base now = _solver(predtags::and_tag(), equal, now_great); 00248 00249 result_base now_equal = _solver(predtags::xnor_tag(), *ai, *bi); 00250 equal = _solver(predtags::and_tag(), now_equal, equal); 00251 00252 ret = _solver(predtags::or_tag(), ret, now); 00253 } 00254 return ret; 00255 } 00256 00257 00258 result_type operator() (bvtags::bvslt_tag, result_type arg1, result_type arg2) 00259 { 00260 bv_result a = boost::get<bv_result>(arg1); 00261 bv_result b = boost::get<bv_result>(arg2); 00262 assert(a.size()==b.size()); 00263 assert(a.size()>0); 00264 00265 typename bv_result::reverse_iterator ai, bi, end; 00266 ai = a.rbegin(); 00267 bi = b.rbegin(); 00268 end= a.rend(); 00269 00270 result_base not_a = _solver(predtags::not_tag(), *ai); 00271 result_base not_b = _solver(predtags::not_tag(), *bi); 00272 result_base ret = _solver(predtags::and_tag(), *ai, not_b); 00273 result_base equal = _solver(predtags::xnor_tag(), *ai, *bi); 00274 00275 00276 for (++ai, ++bi ; ai != end; ++ai, ++bi) 00277 { 00278 not_a = _solver(predtags::not_tag(), *ai); 00279 result_base now_less = _solver(predtags::and_tag(),not_a, *bi); 00280 result_base now = _solver(predtags::and_tag(), equal, now_less); 00281 00282 result_base now_equal = _solver(predtags::xnor_tag(), *ai, *bi); 00283 equal = _solver(predtags::and_tag(), now_equal, equal); 00284 00285 ret = _solver(predtags::or_tag(), ret, now); 00286 } 00287 return ret; 00288 } 00289 00290 00291 result_type operator() (bvtags::bvule_tag, result_type arg1, result_type arg2) 00292 { 00293 bv_result a = boost::get<bv_result>(arg1); 00294 bv_result b = boost::get<bv_result>(arg2); 00295 assert(a.size()==b.size()); 00296 assert(a.size()>0); 00297 00298 typename bv_result::reverse_iterator ai, bi, end; 00299 ai = a.rbegin(); 00300 bi = b.rbegin(); 00301 end= a.rend(); 00302 00303 result_base not_a = _solver(predtags::not_tag(), *ai); 00304 // result_base not_b = _solver(predtags::not_tag(), *bi); 00305 result_base less = _solver(predtags::and_tag(), not_a, *bi); 00306 result_base equal = _solver(predtags::xnor_tag(), *ai, *bi); 00307 result_base ret = less; 00308 00309 00310 00311 for (++ai, ++bi ; ai != end; ++ai, ++bi) 00312 { 00313 not_a = _solver(predtags::not_tag(), *ai); 00314 result_base now_less = _solver(predtags::and_tag(),not_a, *bi); 00315 result_base now = _solver(predtags::and_tag(), equal, now_less); 00316 00317 result_base now_equal = _solver(predtags::xnor_tag(), *ai, *bi); 00318 equal = _solver(predtags::and_tag(), now_equal, equal); 00319 00320 ret = _solver(predtags::or_tag(), ret, now); 00321 } 00322 ret = _solver(predtags::or_tag(), ret, equal); 00323 return ret; 00324 } 00325 00326 00327 00328 00329 result_type operator() (bvtags::bvuge_tag, result_type arg1, result_type arg2) 00330 { 00331 bv_result a = boost::get<bv_result>(arg1); 00332 bv_result b = boost::get<bv_result>(arg2); 00333 assert(a.size()==b.size()); 00334 assert(a.size()>0); 00335 00336 typename bv_result::reverse_iterator ai, bi, end; 00337 ai = a.rbegin(); 00338 bi = b.rbegin(); 00339 end= a.rend(); 00340 00341 result_base not_b = _solver(predtags::not_tag(), *bi); 00342 // result_base not_b = _solver(predtags::not_tag(), *bi); 00343 result_base great = _solver(predtags::and_tag(), *ai, not_b); 00344 result_base equal = _solver(predtags::xnor_tag(), *ai, *bi); 00345 result_base ret = great; 00346 00347 00348 for (++ai, ++bi ; ai != end; ++ai, ++bi) 00349 { 00350 not_b = _solver(predtags::not_tag(), *bi); 00351 result_base now_great = _solver(predtags::and_tag(),*ai, not_b); 00352 result_base now = _solver(predtags::and_tag(), equal, now_great); 00353 00354 result_base now_equal = _solver(predtags::xnor_tag(), *ai, *bi); 00355 equal = _solver(predtags::and_tag(), now_equal, equal); 00356 00357 ret = _solver(predtags::or_tag(), ret, now); 00358 } 00359 ret = _solver(predtags::or_tag(), ret, equal); 00360 return ret; 00361 } 00362 00363 result_type operator() (bvtags::bvsge_tag, result_type arg1, result_type arg2) 00364 { 00365 bv_result a = boost::get<bv_result>(arg1); 00366 bv_result b = boost::get<bv_result>(arg2); 00367 assert(a.size()==b.size()); 00368 assert(a.size()>0); 00369 00370 typename bv_result::reverse_iterator ai, bi, end; 00371 ai = a.rbegin(); 00372 bi = b.rbegin(); 00373 end= a.rend(); 00374 00375 result_base not_a = _solver(predtags::not_tag(), *ai); 00376 result_base not_b = _solver(predtags::not_tag(), *bi); 00377 result_base great = _solver(predtags::and_tag(), not_a, *bi); 00378 result_base equal = _solver(predtags::xnor_tag(), *ai, *bi); 00379 result_base ret = great; 00380 00381 for (++ai, ++bi ; ai != end; ++ai, ++bi) 00382 { 00383 not_b = _solver(predtags::not_tag(), *bi); 00384 result_base now_great = _solver(predtags::and_tag(),*ai, not_b); 00385 result_base now = _solver(predtags::and_tag(), equal, now_great); 00386 00387 result_base now_equal = _solver(predtags::xnor_tag(), *ai, *bi); 00388 equal = _solver(predtags::and_tag(), now_equal, equal); 00389 00390 ret = _solver(predtags::or_tag(), ret, now); 00391 } 00392 ret = _solver(predtags::or_tag(), ret, equal); 00393 return ret; 00394 } 00395 00396 00397 result_type operator() (bvtags::bvsle_tag, result_type arg1, result_type arg2) 00398 { 00399 bv_result a = boost::get<bv_result>(arg1); 00400 bv_result b = boost::get<bv_result>(arg2); 00401 assert(a.size()==b.size()); 00402 assert(a.size()>0); 00403 00404 typename bv_result::reverse_iterator ai, bi, end; 00405 ai = a.rbegin(); 00406 bi = b.rbegin(); 00407 end= a.rend(); 00408 00409 result_base not_b = _solver(predtags::not_tag(), *bi); 00410 result_base less = _solver(predtags::and_tag(), *ai, not_b); 00411 result_base equal = _solver(predtags::xnor_tag(), *ai, *bi); 00412 result_base ret = less; 00413 00414 for (++ai, ++bi ; ai != end; ++ai, ++bi) 00415 { 00416 result_base not_a = _solver(predtags::not_tag(), *ai); 00417 result_base now_less = _solver(predtags::and_tag(),not_a, *bi); 00418 result_base now = _solver(predtags::and_tag(), equal, now_less); 00419 00420 result_base now_equal = _solver(predtags::xnor_tag(), *ai, *bi); 00421 equal = _solver(predtags::and_tag(), now_equal, equal); 00422 00423 ret = _solver(predtags::or_tag(), ret, now); 00424 } 00425 ret = _solver(predtags::or_tag(), ret, equal); 00426 return ret; 00427 } 00428 00429 result_type operator() (bvtags::bvadd_tag, result_type arg1, result_type arg2) 00430 { 00431 bv_result a = boost::get<bv_result>(arg1); 00432 bv_result b = boost::get<bv_result>(arg2); 00433 assert(a.size()==b.size()); 00434 00435 bv_result ret(a.size()); 00436 00437 result_base carry = _solver(predtags::false_tag(), boost::any()); 00438 00439 result_base xor1, or1, and1, and2; 00440 00441 for (unsigned i = 0; i < a.size(); ++i) { 00442 00443 xor1 = _solver(predtags::xor_tag(), a[i], b[i]); 00444 ret[i] = _solver(predtags::xor_tag(), xor1, carry); 00445 00446 // a&b | c&(a|b) 00447 and1 = _solver(predtags::and_tag(), a[i], b[i]); 00448 or1 = _solver(predtags::or_tag(),a[i],b[i]); 00449 and2 = _solver(predtags::and_tag(),carry, or1); 00450 carry = _solver(predtags::or_tag(), and1, and2); 00451 00452 } 00453 return ret; 00454 } 00455 00456 result_type operator() (bvtags::bvmul_tag, result_type arg1, result_type arg2) 00457 { 00458 bv_result a = boost::get<bv_result>(arg1); 00459 bv_result b = boost::get<bv_result>(arg2); 00460 result_type ret = bv_result (a.size(), _solver( predtags::false_tag(), boost::any() ) ); 00461 result_type tmp1; 00462 00463 for(unsigned i = 0 ; i < a.size() ; ++i) 00464 { 00465 tmp1 = (*this)(bvtags::sign_extend_tag(),a.size()-1,bv_result(1,a[i])); 00466 tmp1 = (*this)(bvtags::bvand_tag(),arg2,tmp1); 00467 tmp1 = shiftL( boost::get<bv_result>(tmp1),i); 00468 00469 ret = (*this)(bvtags::bvadd_tag(),ret,tmp1); 00470 } 00471 return ret; 00472 } 00473 00474 result_type operator() ( bvtags::bvneg_tag, result_type arg1 ) 00475 { 00476 00477 bv_result a = boost::get<bv_result>(arg1); 00478 00479 bv_result tmp1(a.size(),_solver(predtags::false_tag(),boost::any())); 00480 tmp1.front()= _solver(predtags::true_tag(), boost::any()); 00481 result_type tmp2 = (*this)(bvtags::bvnot_tag(), arg1); 00482 00483 return (*this)(bvtags::bvadd_tag(),tmp2,tmp1); 00484 } 00485 00486 result_type operator() ( bvtags::bvudiv_tag, result_type arg1, result_type arg2 ) 00487 { 00488 return uDivRem(arg1,arg2,true); 00489 } 00490 00491 result_type operator() ( bvtags::bvsdiv_tag, result_type arg1, result_type arg2 ) 00492 { 00493 return sDivRem(arg1,arg2,true); 00494 } 00495 00496 result_type operator() ( bvtags::bvsrem_tag, result_type arg1, result_type arg2 ) 00497 { 00498 return sDivRem(arg1,arg2,false); 00499 } 00500 00501 result_type operator() ( bvtags::bvhex_tag , boost::any arg ) 00502 { 00503 std::string str = boost::any_cast<std::string>(arg); 00504 result_base _0 = _solver(predtags::false_tag(),boost::any()); 00505 result_base _1 = _solver(predtags::true_tag(),boost::any()); 00506 bv_result ret(str.size()*4,_0); 00507 typename bv_result::iterator iter = ret.begin(); 00508 00509 BOOST_REVERSE_FOREACH( const char c, str) { 00510 switch ( c ) { 00511 case '0': 00512 *(iter++) = _0; 00513 *(iter++) = _0; 00514 *(iter++) = _0; 00515 *(iter++) = _0; 00516 break; 00517 case '1': 00518 *(iter++) = _1; 00519 *(iter++) = _0; 00520 *(iter++) = _0; 00521 *(iter++) = _0; 00522 break; 00523 case '2': 00524 *(iter++) = _0; 00525 *(iter++) = _1; 00526 *(iter++) = _0; 00527 *(iter++) = _0; 00528 break; 00529 case '3': 00530 *(iter++) = _1; 00531 *(iter++) = _1; 00532 *(iter++) = _0; 00533 *(iter++) = _0; 00534 break; 00535 case '4': 00536 *(iter++) = _0; 00537 *(iter++) = _0; 00538 *(iter++) = _1; 00539 *(iter++) = _0; 00540 break; 00541 case '5': 00542 *(iter++) = _1; 00543 *(iter++) = _0; 00544 *(iter++) = _1; 00545 *(iter++) = _0; 00546 break; 00547 case '6': 00548 *(iter++) = _0; 00549 *(iter++) = _1; 00550 *(iter++) = _1; 00551 *(iter++) = _0; 00552 break; 00553 case '7': 00554 *(iter++) = _1; 00555 *(iter++) = _1; 00556 *(iter++) = _1; 00557 *(iter++) = _0; 00558 break; 00559 case '8': 00560 *(iter++) = _0; 00561 *(iter++) = _0; 00562 *(iter++) = _0; 00563 *(iter++) = _1; 00564 break; 00565 case '9': 00566 *(iter++) = _1; 00567 *(iter++) = _0; 00568 *(iter++) = _0; 00569 *(iter++) = _1; 00570 break; 00571 case 'A': 00572 *(iter++) = _0; 00573 *(iter++) = _1; 00574 *(iter++) = _0; 00575 *(iter++) = _1; 00576 break; 00577 case 'B': 00578 *(iter++) = _1; 00579 *(iter++) = _1; 00580 *(iter++) = _0; 00581 *(iter++) = _1; 00582 break; 00583 case 'C': 00584 *(iter++) = _0; 00585 *(iter++) = _0; 00586 *(iter++) = _1; 00587 *(iter++) = _1; 00588 break; 00589 case 'D': 00590 *(iter++) = _1; 00591 *(iter++) = _0; 00592 *(iter++) = _1; 00593 *(iter++) = _1; 00594 break; 00595 case 'E': 00596 *(iter++) = _0; 00597 *(iter++) = _1; 00598 *(iter++) = _1; 00599 *(iter++) = _1; 00600 break; 00601 case 'F': 00602 *(iter++) = _1; 00603 *(iter++) = _1; 00604 *(iter++) = _1; 00605 *(iter++) = _1; 00606 break; 00607 } 00608 } 00609 00610 return ret; 00611 00612 } 00613 00614 result_type operator() ( bvtags::bvurem_tag, result_type arg1, result_type arg2 ) 00615 { 00616 return uDivRem(arg1,arg2, false); 00617 } 00618 00619 result_type operator() ( bvtags::bvsub_tag, result_type arg1, result_type arg2 ) 00620 { 00621 result_type tmp ((*this)(bvtags::bvneg_tag(), arg2)); 00622 00623 return (*this)(bvtags::bvadd_tag(), arg1,tmp); 00624 } 00625 00626 result_type operator() ( bvtags::bvcomp_tag, result_type arg1, result_type arg2 ) 00627 { 00628 result_type tmp = (*this)(predtags::equal_tag(), arg1,arg2); 00629 00630 result_base ret = boost::get<result_base>(tmp); 00631 00632 return bv_result(1,ret); 00633 } 00634 00635 result_type operator() ( bvtags::zero_extend_tag, unsigned width, result_type arg1 ) 00636 { 00637 bv_result a = boost::get<bv_result>(arg1); 00638 bv_result tmp(a.size()+width,_solver(predtags::false_tag(),boost::any())); 00639 00640 std::copy(a.begin(), a.end(), tmp.begin()); 00641 return tmp; 00642 } 00643 00644 result_type operator() ( bvtags::sign_extend_tag, unsigned width, result_type arg1 ) 00645 { 00646 bv_result a = boost::get<bv_result>(arg1); 00647 assert(!a.empty()); 00648 bv_result tmp(a.size()+width, a.back()); 00649 00650 std::copy(a.begin(), a.end(), tmp.begin()); 00651 return tmp; 00652 } 00653 00654 00655 result_type operator() ( predtags::equal_tag eq, result_type arg1, result_type arg2 ) 00656 { 00657 result_base ret; 00658 //printf("try to compare bv\n"); 00659 try { 00660 //printf("read arg1\n"); 00661 bv_result a = boost::get<bv_result>(arg1); 00662 //printf("read arg2\n"); 00663 bv_result b = boost::get<bv_result>(arg2); 00664 assert(a.size()==b.size()); 00665 ret = _solver(predtags::true_tag(), boost::any()); 00666 for (unsigned i = 0; i < a.size(); ++i) { 00667 result_base cur = _solver(eq, a[i], b[i]); 00668 ret = _solver(predtags::and_tag(), cur, ret); 00669 } 00670 } catch (boost::bad_get) { 00671 //printf("try to compare bool\n"); 00672 //printf("read arg1\n"); 00673 result_base a = boost::get<result_base>(arg1); 00674 //printf("read arg2\n"); 00675 result_base b = boost::get<result_base>(arg2); 00676 ret = _solver(eq, a, b); 00677 } 00678 //printf("compare done\n"); 00679 return ret; 00680 } 00681 00682 result_type operator() ( predtags::nequal_tag neq, result_type arg1, result_type arg2 ) 00683 { 00684 result_base ret; 00685 //printf("try to compare bv\n"); 00686 try { 00687 //printf("read arg1\n"); 00688 bv_result a = boost::get<bv_result>(arg1); 00689 //printf("read arg2\n"); 00690 bv_result b = boost::get<bv_result>(arg2); 00691 assert(a.size()==b.size()); 00692 ret = _solver(predtags::false_tag(), boost::any()); 00693 for (unsigned i = 0; i < a.size(); ++i) { 00694 result_base cur = _solver(neq, a[i], b[i]); 00695 ret = _solver(predtags::or_tag(), cur, ret); 00696 } 00697 } catch (boost::bad_get) { 00698 //printf("try to compare bool\n"); 00699 //printf("read arg1\n"); 00700 result_base a = boost::get<result_base>(arg1); 00701 //printf("read arg2\n"); 00702 result_base b = boost::get<result_base>(arg2); 00703 ret = _solver(neq, a, b); 00704 } 00705 //printf("compare done\n"); 00706 return ret; 00707 } 00708 00709 00710 result_type operator() (bvtags::bvbin_tag , boost::any arg ) { 00711 //printf("bvbin\n"); 00712 std::string value = boost::any_cast<std::string>(arg); 00713 bv_result ret (value.size()); 00714 result_base one = _solver(predtags::true_tag (), boost::any()); 00715 result_base zero = _solver(predtags::false_tag(), boost::any()); 00716 for (unsigned i = 0; i < value.size(); ++i) { 00717 ret[i] = value[i]=='1' ? one : zero; 00718 } 00719 return ret; 00720 } 00721 00722 result_type operator() (bvtags::bvuint_tag , boost::any arg ) { 00723 typedef boost::tuple<unsigned long, unsigned long> P; 00724 P p = boost::any_cast<P>(arg); 00725 //std::cout << "bvuint "<< p << std::endl; 00726 unsigned value = boost::get<0>(p); 00727 unsigned width = boost::get<1>(p); 00728 00729 bv_result ret (width); 00730 result_base one = _solver(predtags::true_tag (), boost::any()); 00731 result_base zero = _solver(predtags::false_tag(), boost::any()); 00732 for (unsigned i = 0; i < width; ++i) { 00733 ret[i] = (value & (1ul << i )) ? one : zero; 00734 } 00735 return ret; 00736 } 00737 00738 result_type operator() (bvtags::bvsint_tag , boost::any arg ) { 00739 typedef boost::tuple< long, unsigned long> P; 00740 P p = boost::any_cast<P>(arg); 00741 signed value = boost::get<0>(p); 00742 unsigned width = boost::get<1>(p); 00743 00744 bv_result ret (width); 00745 result_base one = _solver(predtags::true_tag (), boost::any()); 00746 result_base zero = _solver(predtags::false_tag(), boost::any()); 00747 for (unsigned i = 0; i < width; ++i) { 00748 ret[i] = (value & (1l << i )) ? one : zero; 00749 } 00750 return ret; 00751 } 00752 00753 00754 result_type operator() (bvtags::bit0_tag , boost::any arg ) { 00755 //printf("bit0\n"); 00756 return bv_result(1,_solver(predtags::false_tag(), arg)); 00757 } 00758 00759 result_type operator() (bvtags::bit1_tag , boost::any arg ) { 00760 //printf("bit1\n"); 00761 return bv_result(1,_solver(predtags::true_tag(), arg)); 00762 } 00763 00764 result_type operator() (bvtags::bvshr_tag, result_type arg1, result_type value) { 00765 bv_result a = boost::get<bv_result>(arg1); 00766 00767 result_base zero = _solver(predtags::false_tag(),boost::any()); 00768 result_type ret = bv_result(a.size(), zero); 00769 predtags:: ite_tag ite; 00770 00771 for(unsigned i = 0; i < a.size(); ++i) 00772 { 00773 result_type index = (*this)(bvtags::bvuint_tag() 00774 ,boost::any(boost::tuple<unsigned long, unsigned long>(i,a.size()))); 00775 ret = (*this)(ite, 00776 (*this)(predtags::equal_tag(), value, index) 00777 , shiftR(a, i, zero) 00778 , ret 00779 ); 00780 } 00781 00782 return ret; 00783 } 00784 00785 result_type operator() (bvtags::bvshl_tag, result_type arg1, result_type value ) { 00786 00787 bv_result a = boost::get<bv_result>(arg1); 00788 00789 result_type ret = bv_result(a.size(), _solver(predtags::false_tag(), boost::any())); 00790 predtags:: ite_tag ite; 00791 00792 for(unsigned i = 0; i < a.size(); ++i) 00793 { 00794 result_type index = (*this)(bvtags::bvuint_tag() 00795 ,boost::any(boost::tuple<unsigned long, unsigned long>(i,a.size()))); 00796 ret = (*this)(ite, 00797 (*this)(predtags::equal_tag(), value, index) 00798 , shiftL(a, i) 00799 , ret 00800 ); 00801 } 00802 return ret; 00803 } 00804 00805 result_type operator() (bvtags::bvashr_tag, result_type arg1, result_type value ) { 00806 bv_result a = boost::get<bv_result>(arg1); 00807 00808 00809 result_type ret = bv_result(a.size(), a.back()); 00810 predtags:: ite_tag ite; 00811 00812 for(unsigned i = 0; i < a.size(); ++i) 00813 { 00814 result_type index = (*this)(bvtags::bvuint_tag() 00815 ,boost::any(boost::tuple<unsigned long, unsigned long>(i,a.size()))); 00816 ret = (*this)(ite, 00817 (*this)(predtags::equal_tag(), value, index) 00818 , shiftR(a, i, a.back()) 00819 , ret 00820 ); 00821 } 00822 00823 return ret; 00824 } 00825 00826 00827 result_type operator() (predtags::ite_tag, result_type arg1, result_type arg2, result_type arg3 ) { 00828 00829 result_base c = boost::get<result_base>(arg1); 00830 predtags::ite_tag ite; 00831 00832 try { 00833 bv_result a = boost::get<bv_result>(arg2); 00834 bv_result b = boost::get<bv_result>(arg3); 00835 bv_result ret(a.size()); 00836 assert(a.size()==b.size()); 00837 00838 for (unsigned i = 0; i < a.size(); ++i) { 00839 ret[i]= _solver(ite,c,a[i],b[i]); 00840 } 00841 00842 return ret; 00843 } 00844 catch (boost::bad_get) { 00845 result_base a = boost::get<result_base>(arg2); 00846 result_base b = boost::get<result_base>(arg3); 00847 return _solver(ite,c,a,b); 00848 } 00849 00850 00851 } 00852 00853 00854 result_type operator() (bvtags::extract_tag const & 00855 , unsigned long upper, unsigned long lower 00856 , result_type e 00857 ) { 00858 bv_result ret(upper-lower+1); 00859 bv_result const & bv = get<bv_result>(e); 00860 std::copy(bv.begin()+lower, bv.begin()+upper+1, ret.begin()); 00861 return ret; 00862 } 00863 00864 result_type operator() (bvtags::concat_tag const & 00865 , result_type e1, result_type e2 00866 ) { 00867 bv_result const & bv1 = get<bv_result>(e1); 00868 bv_result const & bv2 = get<bv_result>(e2); 00869 bv_result ret(bv1.size()+bv2.size()); 00870 typename bv_result::iterator iter = ret.begin(); 00871 std::copy(bv1.begin(), bv1.end(), iter); 00872 std::copy(bv2.begin(), bv2.end(), ret.begin() + bv1.size() ); 00873 return ret; 00874 } 00875 00876 result_wrapper read_value(result_type var) 00877 { 00878 try { 00879 return read_value(boost::get<result_base>(var)); 00880 } catch ( boost::bad_get ) { 00881 return read_value(boost::get<bv_result>(var)); 00882 } 00883 } 00884 00885 result_wrapper read_value(result_base var) 00886 { 00887 return _solver.read_value(var); 00888 } 00889 00890 result_wrapper read_value(bv_result const & vars) 00891 { 00892 std::vector<boost::logic::tribool> ret(vars.size()); 00893 std::vector<boost::logic::tribool>::iterator it 00894 = ret.begin(); 00895 00896 for (unsigned i = 0; i < vars.size(); ++i, ++it) { 00897 *it = _solver.read_value( vars[i] ); 00898 } 00899 00900 return result_wrapper(ret); 00901 } 00902 00904 // Fallback operators // 00906 00907 template <typename TagT, typename Any> 00908 //boost::disable_if< boost::is_same(Any, bv_result)::type, result_type >::type 00909 result_type 00910 operator() (TagT tag, Any args ) { 00911 try { 00912 // std::cout << "operator " << tag << std::endl; 00913 return _solver(tag, args); 00914 } catch (boost::bad_get) { 00915 std::cout << "Error bad_get in operator " << tag << std::endl; 00916 throw; 00917 } 00918 } 00919 00920 template <typename TagT> 00921 result_type operator() (TagT tag, result_type a ) { 00922 return _solver( tag 00923 , boost::get<result_base>(a) 00924 ); 00925 } 00926 00927 template <typename TagT> 00928 result_type operator() (TagT tag, result_type a, result_type b) { 00929 try { 00930 return _solver( tag 00931 , boost::get<result_base>(a) 00932 , boost::get<result_base>(b) 00933 ); 00934 } catch (boost::bad_get) { 00935 std::cout << "Error bad_get in operator " << tag << std::endl; 00936 throw; 00937 } 00938 } 00939 00940 template <typename TagT> 00941 result_type operator() (TagT tag, result_type a, result_type b, result_type c) { 00942 try { 00943 return _solver( tag 00944 , boost::get<result_base>(a) 00945 , boost::get<result_base>(b) 00946 , boost::get<result_base>(c) 00947 ); 00948 } catch (boost::bad_get) { 00949 std::cout << "Error bad_get in operator " << tag << std::endl; 00950 throw; 00951 } 00952 } 00953 00954 /* pseudo command */ 00955 void command ( BitBlast<PredicateSolver> const & ) { }; 00956 00957 private: 00958 result_type sDivRem (result_type arg1, result_type arg2, bool value) { 00959 00960 bv_result a = boost::get<bv_result>(arg1); 00961 bv_result b = boost::get<bv_result>(arg2); 00962 00963 predtags:: ite_tag ite; 00964 predtags:: xor_tag xor_; 00965 bvtags:: bvneg_tag neg; 00966 00967 result_type tmp1 = (*this)(neg,arg1); 00968 result_type tmp2 = (*this)(neg,arg2); 00969 00970 00971 result_type aneg = (*this)(ite, a.back(), (*this)(neg,arg1),arg1); 00972 result_type bneg = (*this)(ite, b.back(), (*this)(neg,arg2),arg2); 00973 00974 00975 result_type test = uDivRem(aneg,bneg,value); 00976 00977 test = (*this)(ite, _solver(xor_, a.back(), b.back()), (*this)(neg,test),test); 00978 00979 return test; 00980 } 00981 00982 private: 00983 result_type uDivRem (result_type arg1, result_type arg2, bool value) { 00984 00985 bv_result a = boost::get<bv_result>(arg1); 00986 bv_result b = boost::get<bv_result>(arg2); 00987 00988 result_type divisor = arg2 ; 00989 00990 result_base zero = _solver(predtags::false_tag(), boost::any()); 00991 result_base one = _solver(predtags::true_tag(), boost::any()); 00992 00993 bv_result ret(a.size(),zero); 00994 result_type checker = zero; 00995 predtags::ite_tag ite; 00996 /* 00997 00998 bvtags:: bvand_tag and_; 00999 bvtags:: bvneg_tag neg; 01000 01001 result_type ret1 = (*this)(bvtags::bvuge_tag(), a, ret); 01002 result_type ret2 = (*this)(bvtags::bvuge_tag(), b, ret); 01003 result_type ret3 = (*this)(bvtags::bvslt_tag(), a, ret); 01004 result_type ret4 = (*this)(bvtags::bvslt_tag(), b, ret); 01005 01006 result_type bneg = (*this)(ite, _solver(and_, ret1, ret4), (*this)(bvtags::bvneg_tag(),arg2),b); 01007 b = boost::get<bv_result>(bneg); 01008 01009 result_type aneg = (*this)(ite, _solver(and_, ret3, ret2), (*this)(bvtags::bvneg_tag(),arg1),a); 01010 a = boost::get<bv_result>(aneg); 01011 01012 result_type aeg = (*this)(ite, _solver(and_, ret3, ret4), (*this)(bvtags::bvneg_tag(),arg1),a); 01013 a = boost::get<bv_result>(aeg); 01014 01015 result_type args1 = a; 01016 result_type args2 = b; 01017 */ 01018 for(unsigned i = 0; i < a.size(); ++i) 01019 { 01020 result_type tmp = b.back(); 01021 divisor = (*this)(ite,tmp, divisor, shiftL(b,1)); 01022 b = boost::get<bv_result>(divisor); 01023 } 01024 01025 for(unsigned i = 1; i <=a.size(); ++i) 01026 { 01027 result_type bef_dev = divisor; 01028 result_type do_devide = (*this)(bvtags::bvuge_tag(), arg1, divisor); 01029 result_type eq = (*this)(predtags::equal_tag(),bef_dev,arg2); 01030 01031 arg1 = (*this)(ite, do_devide, (*this)(bvtags::bvsub_tag(), arg1, divisor),arg1); 01032 01033 01034 divisor = (*this)(ite, eq, divisor, shiftR(boost::get<bv_result>(divisor), 1, zero)); 01035 01036 do_devide = (*this)(ite,checker,zero, do_devide); 01037 ret[a.size()-i] = boost::get<result_base>(do_devide); 01038 01039 result_type bo = (*this)(ite,checker,shiftR(ret,1, zero),ret); 01040 01041 ret = boost::get<bv_result>(bo); 01042 01043 01044 checker = (*this)(ite, eq , one, checker); 01045 } 01046 01047 if(value) 01048 { 01049 return ret; 01050 } 01051 01052 return arg1; 01053 } 01054 01055 01056 01057 01058 private: 01059 result_type shiftR (bv_result a, unsigned value, result_base & x) { 01060 01061 //bv_result a = boost::get<bv_result>(arg); 01062 bv_result ret(a.size()); 01063 01064 if(value == 0) 01065 { 01066 return a; 01067 } 01068 01069 for(unsigned i= 0; i < a.size(); ++value,++i) 01070 { 01071 if(value < a.size()) 01072 { 01073 ret[i] = a[value]; 01074 } else 01075 ret[i] = x; 01076 } 01077 return ret; 01078 } 01079 01080 private: 01081 result_type shiftL (bv_result a, unsigned value) { 01082 01083 //bv_result a = boost::get<bv_result>(arg); 01084 bv_result ret(a.size()); 01085 01086 if(value == 0) 01087 { 01088 return a; 01089 } 01090 01091 for(unsigned i= 0; i < a.size(); ++i) 01092 { 01093 if( i < value) 01094 { 01095 ret[i] = _solver(predtags::false_tag(),boost::any()); 01096 } else 01097 ret[i] = a[i-value]; 01098 } 01099 return ret; 01100 } 01101 01102 private: 01103 PredicateSolver _solver; 01104 01105 }; 01106 01107 } // namespace metaSMT 01108 01109 // vim: ft=cpp:ts=2:sw=2:expandtab