- Main Page
- Namespaces
- Classes
- Files
- Related Pages

# /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 }