metaSMT git

metaSMT/backend/CUDD_Distributed.hpp

Go to the documentation of this file.
00001 #include "CUDD_Context.hpp"
00002 #include <cstdlib>
00003 
00004 #include <boost/format.hpp>
00005 #include <boost/random/uniform_int.hpp>
00006 #include <boost/random/mersenne_twister.hpp>
00007 
00008 namespace metaSMT {
00009   namespace solver {
00010 
00011 class CUDD_Distributed : public CUDD_Context
00012 {
00013                         
00014 public: 
00015 
00016         CUDD_Distributed () {
00017         reset();
00018         }
00019 
00020         bool solve() {
00021                 BDD complete =_assertions & _assumptions;  
00022                 bool  ret =  complete != _manager.bddZero();
00023                 _assumptions = _manager.bddOne();
00024                 //printDD(complete.getNode(),"BDD.dot");
00025                 if(ret) {
00026                         store_solution( complete.getNode() );
00027                         reset();
00028                 }
00029                 return ret;
00030         }
00031 
00032 private:
00033         std::map<DdNode *, unsigned> map_0;
00034         std::map<DdNode *, unsigned> map_1;
00035         
00036         void reset() {
00037 
00038                 map_0.clear();
00039                 map_1.clear();
00040 
00041                 map_0 [_manager.bddZero().getNode()] = 1;
00042                 map_1 [_manager.bddZero().getNode()] = 0;
00043                 map_0 [_manager.bddOne().getNode()] = 0;
00044                 map_1 [_manager.bddOne().getNode()] = 1;
00045         }
00046         unsigned distance(DdNode *parent, DdNode *child) {
00047                 int i_1 = Cudd_ReadPerm(_manager.getManager(),Cudd_Regular(parent)->index);
00048                 int i_2 = (Cudd_IsConstant(child)) ? _manager.ReadSize() : Cudd_ReadPerm(_manager.getManager(), Cudd_Regular(child)->index);    
00049                 //std::cout << boost::format( "distance(v%d,v%d) = %d - %d = %d\n") 
00050                 //      % parent->index % child->index % i_2 % i_1 % (i_2 - i_1);
00051                 return i_2 - i_1;
00052         }
00053 
00054         unsigned skipped ( DdNode *parent, DdNode *child) {
00055                 unsigned t = distance (parent, child);
00056                 if(t > 0) return t-1;
00057                 else return 0;
00058         }
00059 
00060         unsigned count_0 (DdNode *root) {
00061                 if( Cudd_IsComplement(root)) {
00062                         DdNode * comp = Cudd_Regular(root);
00063                         //std::cout << boost::format("count_0(v%d)=count_1( ~v%d )\n") % root->index% comp->index;
00064                         return count_1(comp);
00065                 }
00066                 //std::cout << boost::format("count_0(v%d)\n") % root->index;
00067                 std::map<DdNode *, unsigned>::iterator iter = map_0.find(root); 
00068                 if(iter != map_0.end()) {
00069                         //std::cout << boost::format("count_0(v%d) = %d\n") % root->index % iter->second;
00070                         return iter->second;
00071                 } else {
00072                         
00073                         unsigned ret = count_0 ( Cudd_T( root ) )*( 1ull << skipped( root, Cudd_T(root) ) ) ;
00074                         //std::cout << "then count is " << ret << std::endl;
00075                         ret += count_0 (Cudd_E(root)) *  ( 1ull << skipped( root, Cudd_E( root ) ) );
00076                         //std::cout << "after else count is " << ret << std::endl;
00077                         map_0.insert( std::make_pair(root,ret) );
00078                         //std::cout << boost::format("count_0(v%d) = %d\n") % root->index % ret;
00079                         return ret;
00080                 }                       
00081         }
00082 
00083         unsigned count_1 (DdNode *root) {
00084                 if( Cudd_IsComplement(root)) {
00085                         DdNode * comp = Cudd_Regular(root);
00086                         //std::cout << boost::format("count_1(v%d)=count_0( ~v%d )\n") % root->index% comp->index;
00087                         return count_0(comp);
00088                 }
00089                 //std::cout << boost::format("count_1(v%d)\n") % root->index;
00090                 std::map<DdNode *, unsigned>::iterator iter = map_1.find(root); 
00091          
00092         if(iter != map_1.end()) {
00093                    //std::cout << boost::format("count_1(v%d) = %d\n") % root->index % iter->second;
00094                   return iter->second;
00095                 } else {
00096                         unsigned ret = count_1 ( Cudd_T( root ) )*( 1ull << skipped( root, Cudd_T(root) ) ) ;
00097                         //std::cout << "then count is " << ret << std::endl;
00098                         ret += count_1 (Cudd_E(root)) *  ( 1ull << skipped( root, Cudd_E( root ) ) );
00099                         //std::cout << "after else count is " << ret << std::endl;
00100 
00101                    map_1.insert( std::make_pair(root,ret) );
00102                    //std::cout << boost::format("count_1(v%d) = %d\n") % root->index % ret;
00103                    return ret;
00104                 
00105                  }
00106         }
00107 
00108 
00109         void store_solution ( DdNode * root) {
00110 
00111            // clear solution
00112             unsigned size = _manager.ReadSize();
00113             std::vector< boost::logic::tribool > (size, boost::logic::indeterminate).swap(_solution);
00114 
00115             bool negated = false;
00116            
00117             while( ! Cudd_IsConstant(root) ) {
00118                 
00119                 //std::cout << "chosing for v" << root->index << " (negated: " << negated << ")" << std::endl;
00120                 
00121                 unsigned cnt_r = 0;
00122                 unsigned cnt_t = 0;
00123                 negated ^= Cudd_IsComplement( root );
00124                 root = Cudd_Regular(root);
00125                 DdNode* child = Cudd_T(root);
00126                 if( negated ) {
00127                         cnt_r = count_0(root);
00128                         cnt_t = count_0(child) << skipped(root, child);
00129                 } else {
00130                         cnt_r = count_1(root);
00131                         cnt_t = count_1(child)<< skipped(root, child);
00132                 }
00133                 
00134                 //std::cout << "count: " << cnt_r << " " << cnt_t << std::endl;
00135 
00136                 boost::uniform_int<unsigned> rnd( 0, cnt_r-1);
00137                 unsigned select = rnd(gen);
00138                 //std::cout << boost::format("%u %u %u") %select%cnt_r%cnt_t << std::endl; 
00139                 if(select <  cnt_t )
00140                 {                       
00141                         //std::cout << "v" << root->index << " = 1" << std::endl;
00142                         _solution[root->index] = true;
00143                         root = Cudd_T( root );
00144                 }       
00145                 else
00146                 {
00147                         //std::cout << "v" << root->index << " = 0" << std::endl;
00148                         _solution[root->index] = false;
00149                         root = Cudd_E( root );  
00150                 }
00151             }
00152             assert( Cudd_V(root) == 1 );  
00153         }
00154         
00155         void printDD(DdNode *root, std::string fileName) {
00156 
00157 
00158 
00159            FILE *file = fopen(fileName.c_str(),"w");
00160         
00161            char **iname = (char**) malloc(sizeof(char *)*_manager.ReadSize());
00162            for(unsigned i = 0; i < _manager.ReadSize(); ++i)
00163            {
00164                 char *name = (char*) malloc(256);
00165                 sprintf(name,"v%d", _manager.bddVar(i).NodeReadIndex());
00166                 iname [i] = name;
00167            }
00168            //extern int Cudd_DumpDot (DdManager *dd, int n, DdNode **f, char **inames, char **onames, FILE *fp);
00169            Cudd_DumpDot (_manager.getManager(),1,&root,iname, NULL,file);
00170            fclose(file);        
00171 }
00172     private:
00173       boost::mt19937 gen;
00174     }; // class CUDD_Distribuded
00175 
00176   } //namespace metaSMT
00177 }//  namespace solver
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines