SatSolver.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 <time.h>
00021 #include <iostream>
00022 #include <iomanip>
00023 #include <list>
00024 #include <vector>
00025 #include <set>
00026 #include "fssIO.h"
00027 #include "SatProblem.h"
00028 #include "SatSolver.h"
00029 
00030 namespace FastSatSolver {
00031 
00032   // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
00033   // AbstractSubject implementation
00034   struct AbstractSubject::Private {
00035     typedef std::list<IObserver *> TContainer;
00036     TContainer container;
00037   };
00038   AbstractSubject::AbstractSubject():
00039     d(new Private)
00040   {
00041   }
00042   AbstractSubject::~AbstractSubject() {
00043     // ATTENTION: Observers are not deleted on object destruction
00044     delete d;
00045   }
00046   void AbstractSubject::addObserver(IObserver *observer) {
00047     d->container.push_back(observer);
00048   }
00049   void AbstractSubject::notify() {
00050     Private::TContainer::iterator iter;
00051     for(iter=d->container.begin(); iter!=d->container.end(); iter++) {
00052       IObserver *observer = *iter;
00053       observer->notify();
00054     }
00055   }
00056 
00057   // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
00058   // AbstractProcess implementation
00059   struct AbstractProcess::Private {
00060     bool running;
00061     int steps;
00062   };
00063   AbstractProcess::AbstractProcess():
00064     d(new Private)
00065   {
00066     d->running = false;
00067     d->steps = 0;
00068   }
00069   AbstractProcess::~AbstractProcess() {
00070     delete d;
00071   }
00072   void AbstractProcess::start() {
00073     for(d->running=true; d->running; d->steps++) {
00074       this->doStep();
00075       this->notify();
00076     }
00077   }
00078   void AbstractProcess::stop() {
00079     d->running = false;
00080   }
00081   void AbstractProcess::reset() {
00082     d->running = false;
00083     d->steps = 0;
00084     this->initialize();
00085   }
00086   int AbstractProcess::getStepsCount() {
00087     return d->steps;
00088   }
00089 
00090   // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
00091   // AbstractProcessWatched implementation
00092   struct AbstractProcessWatched::Private {
00093     static const long RATIO = CLOCKS_PER_SEC/1000L;
00094     clock_t start;
00095     long total;
00096     bool running;
00097     long currentElapsed() {
00098       clock_t diff = clock() - start;
00099       return diff/RATIO;
00100     }
00101   };
00102   AbstractProcessWatched::AbstractProcessWatched():
00103     d(new Private)
00104   {
00105     d->total = 0;
00106     d->running = false;
00107   }
00108   AbstractProcessWatched::~AbstractProcessWatched() {
00109     delete d;
00110   }
00111   void AbstractProcessWatched::start() {
00112     d->start = clock();
00113     d->running = true;
00114     // Delegate to base
00115     AbstractProcess::start();
00116   }
00117   void AbstractProcessWatched::stop() {
00118     if (d->running) {
00119       d->running = false;
00120       d->total += d->currentElapsed();
00121     }
00122     // Delegate to base
00123     AbstractProcess::stop();
00124   }
00125   void AbstractProcessWatched::reset() {
00126     d->running = false;
00127     d->total = 0;
00128     // Delegate to base
00129     AbstractProcess::reset();
00130   }
00131   long AbstractProcessWatched::getTimeElapsed() {
00132     /*if (!d->running) {
00133       std::cerr << "AbstractProcessWatched::getTimeElapsed()" << std::endl;
00134       std::cerr << "  running: false" << std::endl;
00135       std::cerr << "    total: " << d->total << std::endl;
00136       std::cerr << "  current: " << d->currentElapsed() << std::endl;
00137     }*/
00138     long total = d->total;
00139     if (d->running)
00140       total+= d->currentElapsed();
00141     return total;
00142   }
00143 
00144   // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
00145   // AbstractSatSolver implementation
00146   AbstractSatSolver::AbstractSatSolver() { }
00147   AbstractSatSolver::~AbstractSatSolver() { }
00148 
00149 
00150   // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
00151   // SatItemVector implementation
00152   struct SatItemVector::Private {
00153     typedef std::vector<ISatItem *> TVector;
00154     TVector vect;
00155 
00156     Private(unsigned size=0): vect(size) { }
00157   };
00158   SatItemVector::SatItemVector():
00159     d(new Private)
00160   {
00161   }
00162   SatItemVector::SatItemVector(const SatItemVector &other):
00163     d(new Private(other.getLength()))
00164   {
00165     const int length= other.getLength();
00166     for(int i=0; i<length; i++)
00167       d->vect[i] = other.getItem(i)->clone();
00168   }
00169   SatItemVector::~SatItemVector() {
00170     this->clear();
00171     delete d;
00172   }
00173   int SatItemVector::getLength() const {
00174     return d->vect.size();
00175   }
00176   ISatItem* SatItemVector::getItem(int index) const {
00177     return d->vect[index];
00178   }
00179   void SatItemVector::addItem(ISatItem *item) {
00180     d->vect.push_back(item);
00181   }
00182   void SatItemVector::writeOut(SatProblem *problem, std::ostream &stream) const {
00183     const int nForms= this->getLength();
00184     const int nVars= problem->getVarsCount();
00185     for(int f=0; f<nForms; f++) {
00186       stream << std::setw(5) << f+1 << ". ";
00187       ISatItem *item= getItem(f);
00188       for(int v=0; v<nVars; v++) {
00189         stream << problem->getVarName(v) << "=" << item->getBit(v);
00190         if (v==nVars-1)
00191           stream << std::endl;
00192         else
00193           stream << ", ";
00194       }
00195     }
00196   }
00197   void SatItemVector::clear() {
00198     Private::TVector::iterator iter;
00199     for(iter=d->vect.begin(); iter!=d->vect.end(); iter++)
00200       delete *iter;
00201     d->vect.clear();
00202   }
00203 
00204 
00205   // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
00206   // SatItemSet implementation
00207   struct SatItemSet::Private {
00208     class SatItemHashDecorator: public ISatItem {
00209       public:
00210         SatItemHashDecorator(ISatItem *item):
00211           item_(item)
00212         {
00213         }
00214         void dispose() {
00215           delete item_;
00216         }
00217         virtual int getLength() const {
00218           return item_->getLength();
00219         }
00220         virtual bool getBit(int index) const {
00221           return item_->getBit(index);
00222         }
00223         virtual ISatItem* clone() const {
00224           return item_->clone();
00225         }
00226         bool operator< (const SatItemHashDecorator &other) const {
00227           for(int i=0; i<getLength(); i++) {
00228             if (!getBit(i) && other.getBit(i))
00229               return true;
00230             else if (getBit(i) && !other.getBit(i))
00231               return false;
00232           }
00233           return false;
00234         }
00235       private:
00236         ISatItem *item_;
00237     };
00238     typedef std::set<SatItemHashDecorator> TSet;
00239     TSet set;
00240 
00241     void addItem(ISatItem *item) {
00242       SatItemHashDecorator hashableItem(item);
00243       if (set.end()==set.find(hashableItem))
00244         set.insert(hashableItem);
00245       else
00246         hashableItem.dispose();
00247     }
00248   };
00249   SatItemSet::SatItemSet():
00250     d(new Private)
00251   {
00252   }
00253   SatItemSet::~SatItemSet() {
00254     this->clear();
00255     delete d;
00256   }
00257   int SatItemSet::getLength() {
00258     return d->set.size();
00259   }
00260   void SatItemSet::addItem(ISatItem *item) {
00261     d->addItem(item);
00262   }
00263   SatItemVector* SatItemSet::createVector() {
00264     SatItemVector *vect= new SatItemVector;
00265     Private::TSet::iterator iter;
00266     for(iter=d->set.begin(); iter!=d->set.end(); iter++) {
00267       const Private::SatItemHashDecorator &satItemHasable= *iter;
00268       ISatItem *itemClone= satItemHasable.clone();
00269       vect->addItem(itemClone);
00270     }
00271     return vect;
00272   }
00273   void SatItemSet::clear() {
00274     Private::TSet::iterator iter;
00275     for(iter=d->set.begin(); iter!=d->set.end(); iter++) {
00276       Private::SatItemHashDecorator &i= 
00277         const_cast<Private::SatItemHashDecorator &>(*iter);
00278       i.dispose();
00279     }
00280     d->set.clear();
00281   }
00282 
00283 } // namespace FastSatSolver
00284 

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