00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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
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
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
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);
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
00144
00145 vars->pushBack(var);
00147 }
00148
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
00170
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
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;
00203 }
00204
00205 while (!in.eof())
00206 {
00207 in.getline(tmp,399);
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
00218 char val[400];
00219 char tmpChar, tmpChar2;
00220
00221 line >> tmpChar;
00222 if (tmpChar == '[')
00223 {
00224 bracketOpened = true;
00225
00226 bool ownsVars = false;
00227 conflict = new BaseModelAssignmentArray(ownsVars);
00228 line >> var;
00229 }
00230 else if (tmpChar == ']')
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
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
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 }
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
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
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
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
00396
00397
00398 const BaseModelAssignmentArray * imp = bfig->generateBestImplicant(maxStatesTime, maxStatesSize);
00399 cout << endl;
00400 cout << "Implicant generated: " << *imp << endl;
00401
00402 cout << endl;
00403
00404 bfig->printStatistics();
00405
00406 delete variables;
00407 delete bfig;
00408
00409
00410
00411
00412
00413 exit(0);
00414 return 0;
00415 }