metaSMT git

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 
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines