/Users/fpy/titan-1-5-MBARI/Mers/Generators/BFIG/BFIGCommonDriver.cpp

00001 
00002 //
00003 // Copyright (c) 2004           Model-based Embedded and Robotic Systems Group
00004 // All Rights Reserved          Massachusetts Institute of Technology
00005 //
00006 // This software is provided as is. Model-based Embedded and Robotic Systems
00007 // (MERS) group does not assume any responsibility.
00008 //
00009 // Organization:        Model-based Embedded and Robotic Systems Group
00010 //                                      Massachusetts Institute of Technology
00011 //
00013 
00014 #ifdef _MSC_VER
00015 #pragma warning( disable : 4786 )
00016 #endif
00017 
00018 #include <cstdlib>
00019 #include <cstdio>
00020 #include <iostream>
00021 #include <fstream>
00022 #include <string>
00023 //#include <time.h>
00024 #include <list>
00025 #include <sstream>
00026 
00027 #include "BFIGImplicant.h"
00028 #include "BFIGVariable.h"
00029 #include "BFIGConstraint.h"
00030 #include "BFIGAssignment.h"
00031 
00032 #include "BFIGGenerator.h"
00033 
00034 #include <Mers/Models/Base/BaseModelVariableArray.h>
00035 #include <Mers/Models/Base/BaseModelAssignmentArray.h>
00036 #include <Mers/Models/Base/BaseModelDomain.h>
00037 #include <Mers/Utils/Containers/IntegerArray.h>
00038 //#include <Mers/Solvers/SAT/GATSAT/OpSAT/Opsat.h>
00039 
00040 #include "BFIGFactory.h"
00041 
00042 using Mers::Models::Base::BaseModelVariableArray;
00043 using Mers::Models::Base::BaseModelVariable;
00044 using Mers::Models::Base::BaseModelAssignmentArray;
00045 using Mers::Models::Base::BaseModelAssignment;
00046 using Mers::Models::Base::BaseModelValue;
00047 using Mers::Models::Base::BaseModelDomain;
00048 using Mers::Utils::Containers::IntegerArray;
00049 
00053 namespace Mers {
00054         namespace Generators {
00055                 namespace BFIG {
00056                         BFIGFactory * getBFIGFactory();
00057                 }
00058         }
00059 }
00060 
00061 using namespace std;
00062 using Mers::Generators::BFIG::BFIG;
00063 using Mers::Generators::BFIG::BFIGGenerator;
00064 using Mers::Generators::BFIG::BFIGFactory;
00065 using Mers::Generators::BFIG::getBFIGFactory;
00066 
00067 bool
00068 file_exist(char const * filename)
00069 {
00070         FILE *file;
00071         if ( (file = fopen(filename,"r")) == NULL )
00072                 return false;
00073         fclose(file);
00074         return true;
00075 }
00076 
00077 
00078 BFIGGenerator *
00079 readVariables(char const * filename, BaseModelVariableArray ** variableSet, bool useProb)
00080 {
00081   bool ownsVars = true;
00082         BaseModelVariableArray * vars = new BaseModelVariableArray(ownsVars);
00083         vector<double> costs;
00084         IntegerArray valueMap;
00085         int position = 0;
00086         unsigned int UID = 0;
00087         valueMap.pushBack(position);
00088         char next;
00089         char tmp[400];
00090 
00091         if (!file_exist(filename))
00092         {
00093                 cerr << "File " << filename << " does not exist." << endl;
00094                 exit(-1);
00095         }
00096 
00097         ifstream in(filename);
00098 
00099         // skip comment lines
00100         while (!in.eof() && (next=in.peek()) == '#')
00101                 in.getline(tmp,400);
00102 
00103         if (in.eof())
00104         {
00105                 cout << "Data file contains no variables. " << endl;
00106                 return NULL;
00107         }
00108 
00109         in >> ws;
00110         while (!in.eof())
00111         {
00112                 in.getline(tmp,399);  // read variable
00113                 in >> ws;
00114                 if (strlen(tmp) == 0)
00115                         continue;
00116                 istringstream line(tmp);
00117                 char varname[400];
00118                 line >> varname;
00119                 line >> ws;
00120                 bool ownsVals = true;
00121                 BaseModelValue * value;
00122                 BaseModelDomain * domain = new BaseModelDomain(varname, ownsVals);
00123                 cout << "Domain name: " << domain->getName() << endl;
00124                 while (!line.eof())
00125                 {
00126                         char val[400];
00127                         double p;
00128 
00129                         line >> val;
00130                         cout << "   val: " << val << ", " ;
00131                         line >> p;
00132                         cout << "cost: " << p << endl;
00133                         line >> ws;
00134                         value = new BaseModelValue(val);
00135                         domain->pushBack(value);
00136                         costs.push_back(p);
00137                 }
00138                 position = position + domain->getLength();
00139                 valueMap.pushBack(position);
00140                 BaseModelVariable * var = new BaseModelVariable(varname, domain);
00141                 var->setUID(UID);
00142                 UID++;
00143                 //cout << "Read variable: " << *var << endl ;
00144                 //::cout << "(num values: " << values.size() << ")" << endl;
00145                 vars->pushBack(var);
00147         }
00148         // We put one too many positions in valueMap
00149         valueMap.popBack();
00150 
00151         in.close();
00152 
00153         *variableSet = vars;
00154         cout << "Length of variable array: " << vars->getLength() << endl;
00155         cout << "Variables: " << *variableSet << endl;
00156         cout << "ValueMap: " << valueMap << endl;
00157         cout << "Costs: ";
00158         for (vector<double>::const_iterator p = costs.begin();
00159              p!=costs.end(); p++) {
00160           cout << *p << " ";
00161         }
00162         cout << endl;
00163         BFIGFactory * factory = getBFIGFactory();
00164         BFIGGenerator * gen =
00165                 new BFIGGenerator(*factory, *vars, *vars, valueMap, costs, 1e10, useProb);
00166         delete factory;
00167         return gen;
00168 
00169         //cout << "Read file with " << (res.size()) << " variables." << endl;
00170         //cout << endl;
00171 
00172 }
00173 
00174 
00175 const vector<BaseModelAssignmentArray *> *
00176 readConflicts(char const * filename, BaseModelVariableArray * variableSet)
00177 {
00178 
00179         vector<BaseModelAssignmentArray *> * conflicts = 
00180                 new vector<BaseModelAssignmentArray *>();
00181         BaseModelAssignmentArray * conflict = NULL;
00182 
00183         char next;
00184         char tmp[400];
00185 
00186         if (!file_exist(filename))
00187         {
00188                 cerr << "File " << filename << " does not exist." << endl;
00189                 exit(-1);
00190         }
00191 
00192         ifstream in(filename);
00193 
00194         // skip comment lines
00195         while (!in.eof() && (next=in.peek()) == '#')
00196                 in.getline(tmp,400);
00197 
00198         in >> ws;
00199         if (in.eof())
00200         {
00201                 cout << "Data file contains no conflicts." << endl;
00202                 return conflicts;  // try anyway, for testing...
00203         }
00204 
00205         while (!in.eof())
00206         {
00207                 in.getline(tmp,399);  // read conflict
00208                 in >> ws;
00209                 if (strlen(tmp) == 0)
00210                         continue;
00211                 istringstream line(tmp);
00212                 bool bracketOpened = false;
00213                 bool lastVarInConflict = false;
00214                 while (!line.eof())
00215                 {
00216                   char var[400];
00217                   //char var2[399];
00218                         char val[400];
00219                         char tmpChar, tmpChar2;
00220 
00221                         line >> tmpChar;
00222                         if (tmpChar == '[')
00223                           {
00224                             bracketOpened = true;
00225                                         //The original BaseModelVariableArray owns the variables
00226                             bool ownsVars = false;
00227                             conflict = new BaseModelAssignmentArray(ownsVars);
00228                             line >> var;
00229                           }
00230                         else if (tmpChar == ']') // End of a conflict
00231                           {
00232                             bracketOpened = false;
00233                             if (conflict != NULL && conflict->getLength() > 0)
00234                                 conflicts->push_back(conflict);
00235                             line >> ws;
00236                             if (line.eof())
00237                               break;
00238                             line >> var;
00239                           }
00240                         else
00241                         {
00242                           var[0] = tmpChar;
00243                                 // Get the rest of the variable name up to the next space.
00244                           for (int i = 1; i < 400; i++) {
00245                             tmpChar2 = line.get();
00246                             if (tmpChar2 == ' ') break;
00247                             var[i] = tmpChar2;
00248                           }
00249                         }
00250                         line >> val;
00251                         line >> ws;
00252 
00253                         // There was no space between value and ]
00254                         if (val[strlen(val) - 1] == ']')
00255                         {
00256                                 val[strlen(val) - 1] = '\0';
00257                                 lastVarInConflict = true;
00258                         }
00259 
00260                         const BaseModelVariable * variable = variableSet->find(var);
00261                         const BaseModelValue * value;
00262                         if (variable == NULL) {
00263                                 cout << "Error: could not find conflict assignment "
00264                                        << var << ", " << val << endl;
00265                         }
00266                         else {
00267                           value = variable->getValue(val);
00268                           if (value == NULL) {
00269                             cout << "Error: could not find conflict assignment "
00270                                        << var << ", " << val << endl;
00271                           }
00272                           else if (!bracketOpened)
00273                             cerr << "Error: must start conflicts with a '['" << endl;
00274                           else {
00275                             conflict->pushBack(new BaseModelAssignment(variable, value));
00276                             if (lastVarInConflict) {
00277                               bracketOpened = false;
00278                               lastVarInConflict = false;
00279                               if (conflict != NULL && conflict->getLength() > 0)
00280                                 conflicts->push_back(conflict);
00281                             }
00282                           }
00283                         }
00284                 }
00285         }
00286 
00287         in.close();
00288         cout << "Finished reading conflicts: " << endl;
00289         int counter = 0;
00290         vector<BaseModelAssignmentArray *>::const_iterator p = conflicts->begin();
00291         for (; p != conflicts->end(); p++) {
00292           cout << "Conflict " << counter << endl;
00293           cout << **p << endl;
00294           counter++;
00295         }
00296         return conflicts;
00297 }
00298 
00299 
00300 int
00301 main(int argc, char** argv)
00302 {
00303         argc--;
00304         argv++;
00305 
00306         bool useProb = false;
00307         bool useDebug = false;
00308         int numResults = 1;
00309         char const * logConfigFileName = NULL;
00310 
00311         for (; argc > 0 && argv[argc-1][0] == '-'; argc--)
00312         {
00313                 if (argv[argc-1][1] == 'b' || argv[argc-1][1] == 'B')
00314                 {
00315                         cout << "Showing debug info." << endl;
00316                         useDebug = true;
00317                 } /*else
00318                 if (argv[argc-1][1] == 'e' || argv[argc-1][1] == 'E')
00319                 {
00320                         cout << "Using non-Conflict-Directed search." << endl;
00321                         useCD = false;
00322                         cout << "Using entropy to sort variables." << endl;
00323                         orderType = Opsat::ENTROPY;
00324                 } else
00325                 if (argv[argc-1][1] == 'r' || argv[argc-1][1] == 'R')
00326                 {
00327                         cout << "Using non-Conflict-Directed search." << endl;
00328                         useCD = false;
00329                         cout << "Using random sorting of variables." << endl;
00330                         orderType = Opsat::RANDOM;
00331                         } */else
00332                 if (argv[argc-1][1] == 'p' || argv[argc-1][1] == 'P')
00333                 {
00334                         cout << "Treating costs as probabilities." << endl;
00335                         useProb = true;
00336                 } else
00337                 if (argv[argc-1][1] == 'n' || argv[argc-1][1] == 'N')
00338                 {
00339                         char * numStr = argv[argc-1]+2;
00340                         numResults = atoi(numStr);
00341                         cout << "Searching for best " << numResults << " results." << endl;
00342                 } else if (argv[argc-1][1] == 'l') {
00343                         logConfigFileName = argv[argc-1] + 2;
00344                         cout << "Using log4cplus config file " << logConfigFileName;
00345                 } else {
00346                         cout << "Ignoring unrecognized option '" << argv[argc-1] << "'." << endl;
00347                 }
00348         }
00349         if (argc != 2)
00350         {
00351                 cout << "Arguments should be:" << endl << endl;
00352                 cout << "   <variable_file> <conflict_file> "
00353                      << "[-c][-e][-p][-r][-b][-y][-n#]" << endl;
00354                 cout << endl;
00355                 cout << "-e   uses an entropy-directed search method (with -c)." << endl;
00356                 cout << "-r   uses a random sorting of the variables (with -c)." << endl;
00357                 cout << "-b   show debug info." << endl;
00358                 cout << "-p   treats costs as probabilities." << endl;
00359                 cout << "-n#  specifies the number to find (default is 1)." << endl;
00360                 cout << "-l<log4cplus config file>: Specifies a config file to "
00361                         "load," << endl << "which is used to configure the log4cplus "
00362                         "logger output." << endl << "By default, log4cplus is "
00363                         "configured to print to standard out." << endl;
00364                 cout << endl;
00365                 exit(-1);
00366         }
00367         cout << endl;
00368 
00369         // load our config file
00370         if(logConfigFileName == NULL) {
00371                 log4cplus::BasicConfigurator::doConfigure();
00372         } else {
00373                 log4cplus::PropertyConfigurator::doConfigure(logConfigFileName);
00374         }
00375 
00376         char const * variableFile = argv[0];
00377         char const * conflictFile = argv[1];
00378 
00379         BaseModelVariableArray * variables;
00380         BFIGGenerator * bfig = readVariables(variableFile, &variables, useProb);
00381         const vector<BaseModelAssignmentArray *> * conflicts = readConflicts(conflictFile, variables);
00382 
00383         //float cutoff = 0.9F;
00384         int maxStatesTime = 20000;
00385         int maxStatesSize = 15000;
00386 
00387         bfig->setDebug(useDebug);
00388 
00389         vector<BaseModelAssignmentArray *>::const_iterator p = conflicts->begin();
00390         for (; p != conflicts->end(); p++) {
00391           bfig->addConflict(*p);
00392         }
00393         cout << "Added conflicts" << endl;
00394         
00395         /*      for (int i = 0; i < variables.getLength(); i++) {
00396           cout << *(bfig->findVariable(i)) << endl;
00397           }*/
00398         const BaseModelAssignmentArray * imp = bfig->generateBestImplicant(maxStatesTime, maxStatesSize);
00399         cout << endl;
00400         cout << "Implicant generated: " << *imp << endl;
00401         //      cout << "    true cost: " << (imp->getTrueCost()) << endl;
00402         cout << endl;
00403 
00404         bfig->printStatistics();
00405         //cout << "printed statistics." << endl;
00406         delete variables;
00407         delete bfig;
00408         //list<BFIGConstraint const *>::iterator cIter;
00409         //for (cIter = conflicts.begin(); cIter != conflicts.end(); cIter++)
00410         //{
00411         //      delete (*cIter);
00412         //}
00413         exit(0);
00414         return 0; //# to make MSVC happy - yes, it's that stupid.
00415 }

Generated on Mon Dec 4 14:16:50 2006 for Mers by  doxygen 1.5.0