00001 /* 00002 * Copyright (C) 2008 Kamil Dudka <xdudka00@stud.fit.vutbr.cz> 00003 * 00004 * This file is part of fss (Fast SAT Solver). 00005 * 00006 * fss is free software: you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation, either version 3 of the License, or 00009 * any later version. 00010 * 00011 * fss is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with fss. If not, see <http://www.gnu.org/licenses/>. 00018 */ 00019 00020 #include <stdio.h> 00021 #include <assert.h> 00022 #include <iostream> 00023 #include <string> 00024 #include <vector> 00025 #include <list> 00026 #include <map> 00027 #include "fssIO.h" 00028 #include "SatSolver.h" 00029 #include "Scanner.h" 00030 #include "Formula.h" 00031 #include "SatProblem.h" 00032 00033 using std::string; 00034 00035 namespace FastSatSolver { 00036 00037 // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 00038 // SatProblem implementation 00039 struct SatProblem::Private { 00040 bool hasError; 00041 VariableContainer vc; 00042 FormulaContainer fc; 00043 std::string fileName; 00044 00045 void parseFile(FILE *); 00046 void parserLoop(IScanner *); 00047 void printError(Token); 00048 }; 00049 SatProblem::SatProblem(): 00050 d(new Private) 00051 { 00052 d->hasError = false; 00053 } 00054 SatProblem::~SatProblem() { 00055 delete d; 00056 } 00057 void SatProblem::loadFromFile (std::string fileName ) { 00058 d->fileName = fileName; 00059 00060 // OpenedFile RAII 00061 class OpenedFileRAII { 00062 public: 00063 OpenedFileRAII(string fileName) { 00064 fd_ = fopen(fileName.c_str(), "r"); 00065 if (0== fd_) { 00066 string error("Could not open file: "); 00067 throw GenericException(error + fileName); 00068 } 00069 } 00070 ~OpenedFileRAII() { fclose(fd_); } 00071 FILE* getFd() { return fd_; } 00072 private: 00073 FILE* fd_; 00074 } openedFile(fileName); 00075 d->parseFile(openedFile.getFd()); 00076 } 00077 00078 00081 void SatProblem::loadFromInput ( ) { 00082 d->fileName = "-"; 00083 d->parseFile(stdin); 00084 } 00085 00086 00087 // @private 00088 void SatProblem::Private::parseFile(FILE *fd) { 00089 // RawScanner RAII 00090 class RawScanRAII { 00091 public: 00092 RawScanRAII(FILE *fd) { ptr_ = new RawScanner(fd); } 00093 ~RawScanRAII() { delete ptr_; } 00094 RawScanner* instance() { return ptr_; } 00095 private: 00096 RawScanner *ptr_; 00097 } rawScan(fd); 00098 00099 // ScannerStringHandler RAII 00100 class StringScanRAII { 00101 public: 00102 StringScanRAII(IScanner *scan, VariableContainer *vc) { 00103 ptr_ = new ScannerStringHandler(scan, vc); 00104 } 00105 ~StringScanRAII() { delete ptr_; } 00106 ScannerStringHandler* instance() { return ptr_; } 00107 private: 00108 ScannerStringHandler *ptr_; 00109 } stringScan(rawScan.instance(), &vc); 00110 00111 // ScannerFormulaHandler RAII 00112 class FormulaScanRAII { 00113 public: 00114 FormulaScanRAII(IScanner *scan, FormulaContainer *fc) { 00115 ptr_ = new ScannerFormulaHandler(scan, fc); 00116 } 00117 ~FormulaScanRAII() { delete ptr_; } 00118 ScannerFormulaHandler* instance() { return ptr_; } 00119 private: 00120 ScannerFormulaHandler *ptr_; 00121 } formulaScan(stringScan.instance(), &fc); 00122 00123 this->parserLoop(formulaScan.instance()); 00124 if (0==fc.getLength() || 0==vc.getLength()) 00125 hasError = true; 00126 } 00127 00128 00129 // @private 00130 void SatProblem::Private::parserLoop(IScanner *scanner) { 00131 Token token; 00132 while (0== scanner->readNext(&token) && T_EOF!=token.m_token) { 00133 switch (token.m_token) { 00134 case T_ERR_LEX: 00135 case T_ERR_EXPR: 00136 case T_ERR_PARSE: 00137 this->printError(token); 00138 break; 00139 00140 default: 00141 throw GenericException("Unhandled token in SatProblemImp::parserLoop"); 00142 } 00143 } 00144 } 00145 00146 00147 // @private 00148 void SatProblem::Private::printError(Token token) { 00149 this->hasError = true; 00150 std::cerr << fileName << ":" << token.m_line << ": error: "; 00151 switch (token.m_token) { 00152 case T_ERR_LEX: std::cerr << "lexical error"; break; 00153 case T_ERR_EXPR: std::cerr << "expression error"; break; 00154 case T_ERR_PARSE: std::cerr << "syntax error"; break; 00155 default: 00156 throw GenericException("Unhandled error in SatProblemImp::printError"); 00157 } 00158 std::cerr << std::endl; 00159 } 00160 00161 00165 int SatProblem::getVarsCount ( ) { 00166 return d->vc.getLength(); 00167 } 00168 00169 00174 string SatProblem::getVarName (int index ) { 00175 return d->vc.getVarName(index); 00176 } 00177 00178 00182 int SatProblem::getFormulasCount() { 00183 return d->fc.getLength(); 00184 } 00185 00186 00191 int SatProblem::getSatsCount (ISatItem *data ) { 00192 return d->fc.evalAll(data); 00193 } 00194 00195 00199 bool SatProblem::hasError ( ) { 00200 return d->hasError; 00201 } 00202 00203 // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 00204 // VariableContainer implementation 00205 struct VariableContainer::Private { 00206 typedef std::string TVarName; 00207 typedef std::vector<TVarName> TIndexToName; 00208 typedef std::map<TVarName, int> TNameToIndex; 00209 TIndexToName indexToName; 00210 TNameToIndex nameToIndex; 00211 int currentIndex; 00212 }; 00213 VariableContainer::VariableContainer(): 00214 d(new Private) 00215 { 00216 d->currentIndex = 0; 00217 } 00218 VariableContainer::~VariableContainer() { 00219 delete d; 00220 } 00221 int VariableContainer::getLength ( ) { 00222 return d->currentIndex; 00223 } 00224 string VariableContainer::getVarName (int index ) { 00225 assert(index < d->currentIndex); 00226 return d->indexToName[index]; 00227 } 00228 int VariableContainer::addVariable (std::string name ) { 00229 if (d->nameToIndex.end() != d->nameToIndex.find(name)) 00230 // Variable already exists 00231 return d->nameToIndex[name]; 00232 00233 // Add new variable 00234 d->nameToIndex[name] = d->currentIndex; 00235 d->indexToName.push_back(name); 00236 return (d->currentIndex)++; 00237 } 00238 00239 // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 00240 // FormulaContainer implementation 00241 struct FormulaContainer::Private { 00242 typedef std::list<IFormulaEvaluator *> TContainer; 00243 TContainer container; 00244 }; 00245 FormulaContainer::FormulaContainer(): 00246 d(new Private) 00247 { 00248 } 00249 FormulaContainer::~FormulaContainer() { 00250 Private::TContainer::iterator iter; 00251 for(iter=d->container.begin(); iter!=d->container.end(); iter++) 00252 delete *iter; 00253 delete d; 00254 } 00255 00256 00260 int FormulaContainer::getLength ( ) { 00261 return d->container.size(); 00262 } 00263 00264 00269 int FormulaContainer::evalAll (ISatItem *data ) { 00270 int counter = 0; 00271 00272 Private::TContainer::iterator iter; 00273 for(iter=d->container.begin(); iter!=d->container.end(); iter++) { 00274 IFormulaEvaluator *fe = *iter; 00275 counter += fe->eval(data); 00276 } 00277 00278 return counter; 00279 } 00280 00284 void FormulaContainer::addFormula (IFormulaEvaluator *formula ) { 00285 d->container.push_back(formula); 00286 } 00287 00288 } // namespace FastSatSolver
1.5.4