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