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
1.5.4