metaSMT 2
metaSMT/BitBlast.hpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines