SatProblem.cpp

Go to the documentation of this file.
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

Generated on Wed Nov 5 22:30:22 2008 for Fast SAT Solver by  doxygen 1.5.4