00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <sstream>
00031 #include "variable.h"
00032 #include "search_rules.h"
00033 #include "memory_manager_chunks.h"
00034 #include "memory_manager_malloc.h"
00035
00036 using namespace std;
00037
00038 namespace CVCL {
00039
00040
00041
00042
00043
00044
00045 Variable::Variable(VariableManager* vm, const Expr& e)
00046 : d_val(vm->newVariableValue(e))
00047 {
00048 d_val->d_refcount++;
00049 }
00050
00051 Variable::Variable(const Variable& l): d_val(l.d_val) {
00052 if(!isNull()) d_val->d_refcount++;
00053 }
00054
00055
00056 Variable::~Variable() {
00057 if(!isNull()) {
00058 if(--(d_val->d_refcount) == 0)
00059 d_val->d_vm->gc(d_val);
00060 }
00061 }
00062
00063
00064 Variable&
00065 Variable::operator=(const Variable& l) {
00066 if(&l == this) return *this;
00067 if(!isNull()) {
00068 if(--(d_val->d_refcount) == 0) d_val->d_vm->gc(d_val);
00069 }
00070 d_val = l.d_val;
00071 if(!isNull()) d_val->d_refcount++;
00072 return *this;
00073 }
00074
00075 const Expr&
00076 Variable::getExpr() const {
00077 static Expr null;
00078 if(isNull()) return null;
00079 return d_val->getExpr();
00080 }
00081
00082 const Expr&
00083 Variable::getNegExpr() const {
00084 static Expr null;
00085 if(isNull()) return null;
00086 return d_val->getNegExpr();
00087 }
00088
00089
00090 int
00091 Variable::getValue() const {
00092 if(isNull()) return 0;
00093 return d_val->getValue();
00094 }
00095
00096
00097 int
00098 Variable::getScope() const {
00099 if(isNull()) return 0;
00100 return d_val->getScope();
00101 }
00102
00103 const Theorem&
00104 Variable::getTheorem() const {
00105 static Theorem null;
00106 if(isNull()) return null;
00107 return d_val->getTheorem();
00108 }
00109
00110 const Clause&
00111 Variable::getAntecedent() const {
00112 static Clause null;
00113 if(isNull()) return null;
00114 return d_val->getAntecedent();
00115 }
00116
00117 int
00118 Variable::getAntecedentIdx() const {
00119 if(isNull()) return 0;
00120 return d_val->getAntecedentIdx();
00121 }
00122
00123 const Theorem&
00124 Variable::getAssumpThm() const {
00125 static Theorem null;
00126 if(isNull()) return null;
00127 return d_val->getAssumpThm();
00128 }
00129
00130
00131
00132
00133 void
00134 Variable::setValue(int val, const Clause& c, int idx) {
00135 DebugAssert(!isNull(), "Variable::setValue(antecedent): var is NULL");
00136 d_val->setValue(val, c, idx);
00137 }
00138
00139
00140
00141 void
00142 Variable::setValue(const Theorem& thm) {
00143 DebugAssert(!isNull(), "Variable::setValue(Theorem): var is NULL");
00144 d_val->setValue(thm, thm.getScope());
00145 }
00146
00147 void
00148 Variable::setValue(const Theorem& thm, int scope) {
00149 DebugAssert(!isNull(), "Variable::setValue(Theorem,scope): var is NULL");
00150 d_val->setValue(thm, scope);
00151 }
00152
00153 void
00154 Variable::setAssumpThm(const Theorem& a, int scope) {
00155 DebugAssert(!isNull(), "Variable::setAssumpThm(): var is NULL");
00156 d_val->setAssumpThm(a, scope);
00157 }
00158
00159
00160
00161
00162
00163 Theorem
00164 Variable::deriveTheorem() const {
00165 return deriveThmRec(false);
00166 }
00167
00168
00169 Theorem
00170 Variable::deriveThmRec(bool checkAssump) const {
00171 DebugAssert(!isNull(), "Variable::deriveTheorem(): called on Null");
00172 DebugAssert(getValue() != 0, "Variable::deriveTheorem(): value is not set: "
00173 + toString());
00174 if(!getTheorem().isNull()) return getTheorem();
00175 if(checkAssump && !getAssumpThm().isNull()) return getAssumpThm();
00176
00177 Clause c(getAntecedent());
00178 int idx(getAntecedentIdx());
00179 const vector<Literal>& lits = c.getLiterals();
00180
00181 vector<Theorem> thms;
00182 int size(lits.size());
00183
00184 for(int i=0; i<size; ++i)
00185 if(i!=idx) thms.push_back(lits[i].getVar().deriveThmRec(true));
00186 Theorem thm;
00187 if(idx!=-1)
00188 thm = d_val->d_vm->getRules()->unitProp(thms, c.getTheorem(), idx);
00189 else
00190 thm = d_val->d_vm->getRules()->conflictRule(thms, c.getTheorem());
00191
00192 IF_DEBUG(Expr e(thm.getExpr()));
00193 DebugAssert(e == getExpr()
00194 || (e.isNot() && e[0] == getExpr()),
00195 "Variable::deriveTheorem: bad theorem derived: expr ="
00196 + toString() + ", thm = " + thm.toString());
00197
00198 d_val->setValue(thm, getScope());
00199 return thm;
00200 }
00201
00202 string
00203 Variable::toString() const {
00204 ostringstream ss;
00205 ss << *this;
00206 return ss.str();
00207 }
00208
00209
00210 ostream& operator<<(ostream& os, const Variable& l) {
00211 return os << (*l.d_val);
00212 }
00213
00214
00215
00216
00217
00218 string
00219 Literal::toString() const {
00220 ostringstream ss;
00221 ss << *this;
00222 return ss.str();
00223 }
00224
00225 ostream& operator<<(ostream& os, const Literal& l) {
00226 os << "Lit(" << (l.isNegative()? "!" : "")
00227 << l.getVar();
00228
00229 os << ", count=" << l.count() << ", score=" << l.score();
00230 return os << ")";
00231 }
00232
00233
00234
00235
00236
00237
00238 VariableValue::~VariableValue() {
00239 if(d_val!=NULL) { delete d_val; d_val = NULL; }
00240 if(d_scope!=NULL) { delete d_scope; d_scope = NULL; }
00241 if(d_thm!=NULL) { delete d_thm; d_thm = NULL; }
00242 if(d_ante!=NULL) { delete d_ante; d_ante = NULL; }
00243 if(d_anteIdx!=NULL) { delete d_anteIdx; d_anteIdx = NULL; }
00244 if(d_assump!=NULL) { delete d_assump; d_assump = NULL; }
00245 }
00246
00247
00248
00249 void
00250 VariableValue::setValue(int val, const Clause& c, int idx) {
00251 if(d_val==NULL) {
00252
00253 d_val = new CDO<int>(d_vm->getCM()->getCurrentContext(), 0, 0);
00254 IF_DEBUG(d_val->setName("CDO[VariableValue::d_val]"));
00255 }
00256 if(d_scope==NULL) {
00257 d_scope = new CDO<int>(d_vm->getCM()->getCurrentContext());
00258 IF_DEBUG(d_scope->setName("CDO[VariableValue::d_scope]"));
00259 }
00260 if(d_ante==NULL) {
00261 d_ante = new CDO<Clause>(d_vm->getCM()->getCurrentContext());
00262 IF_DEBUG(d_ante->setName("CDO[VariableValue::d_ante]"));
00263 }
00264 if(d_anteIdx==NULL) {
00265 d_anteIdx = new CDO<int>(d_vm->getCM()->getCurrentContext());
00266 IF_DEBUG(d_anteIdx->setName("CDO[VariableValue::d_anteIdx]"));
00267 }
00268
00269
00270
00271 int scope(c.getScope());
00272 for(int i=0, iend=c.size(); i!=iend; ++i) {
00273 if(i!=idx) {
00274 int s(c[i].getScope());
00275 if(s > scope) scope = s;
00276 DebugAssert(c[i].getValue() != 0,
00277 "VariableValue::setValue(ante): literal has no value: "
00278 "i="+int2string(i)+" in\n clause = "
00279 +c.toString());
00280 }
00281 }
00282
00283 d_val->set(val, scope);
00284 d_scope->set(scope, scope);
00285 d_ante->set(c, scope);
00286 d_anteIdx->set(idx, scope);
00287
00288 if(!getTheorem().isNull()) d_thm->set(Theorem(), scope);
00289
00290 IF_DEBUG(Expr l((idx == -1)? getExpr().getEM()->falseExpr()
00291 : c[idx].getExpr()));
00292 DebugAssert((val > 0 && l == getExpr())
00293 || (val < 0 && l.isNot() && l[0] == getExpr()),
00294 "VariableValue::setValue(val = " + int2string(val)
00295 + ", c = " + c.toString() + ", idx = " + int2string(idx)
00296 + "):\n expr = " + getExpr().toString()
00297 + "\n literal = " + l.toString());
00298 }
00299
00300
00301
00302 void
00303 VariableValue::setValue(const Theorem& thm, int scope) {
00304 if(d_val==NULL) {
00305
00306 d_val = new CDO<int>(d_vm->getCM()->getCurrentContext(),0,0);
00307 IF_DEBUG(d_val->setName("CDO[VariableValue::d_val]"));
00308 }
00309 if(d_scope==NULL) {
00310 d_scope = new CDO<int>(d_vm->getCM()->getCurrentContext());
00311 IF_DEBUG(d_scope->setName("CDO[VariableValue::d_scope]"));
00312 }
00313 if(d_thm==NULL) {
00314 d_thm = new CDO<Theorem>(d_vm->getCM()->getCurrentContext());
00315 IF_DEBUG(d_thm->setName("CDO[VariableValue::d_thm]"));
00316 }
00317
00318 Expr e(thm.getExpr());
00319 int val(0);
00320 if(e == d_expr) val = 1;
00321 else {
00322 DebugAssert(e.isNot() && e[0] == d_expr,
00323 "VariableValue::setValue(thm = "
00324 + thm.toString() + "): expr = " + d_expr.toString());
00325 val = -1;
00326 }
00327
00328 d_val->set(val, scope);
00329 d_scope->set(scope, scope);
00330 d_thm->set(thm, scope);
00331
00332 if(!getAntecedent().isNull()) d_ante->set(Clause(), scope);
00333 }
00334
00335 void
00336 VariableValue::setAssumpThm(const Theorem& thm, int scope) {
00337 if(d_assump==NULL) {
00338
00339 d_assump = new CDO<Theorem>(d_vm->getCM()->getCurrentContext());
00340 IF_DEBUG(d_val->setName("CDO[VariableValue::d_val]"));
00341 }
00342 d_assump->set(thm, scope);
00343 }
00344
00345 ostream& operator<<(ostream& os, const VariableValue& v) {
00346 os << "Var(" << v.getExpr() << " = " << v.getValue();
00347 if(v.getValue() != 0) {
00348 os << " @ " << v.getScope();
00349 if(!v.getTheorem().isNull())
00350 os << "; " << v.getTheorem();
00351 else if(!v.getAntecedent().isNull()) {
00352 os << "; #" << v.getAntecedentIdx()
00353 << " in " << CompactClause(v.getAntecedent());
00354 }
00355 }
00356 return os << ")";
00357 }
00358
00359
00360
00361
00362
00363
00364 VariableValue*
00365 VariableManager::newVariableValue(const Expr& e) {
00366 VariableValue vv(this, e);
00367 VariableValueSet::iterator i(d_varSet.find(&vv)), iend(d_varSet.end());
00368 if(i != iend) return (*i);
00369
00370 VariableValue* p_vv(new(d_mm) VariableValue(this, e));
00371 d_varSet.insert(p_vv);
00372 return p_vv;
00373 }
00374
00375
00376 VariableManager::VariableManager(ContextManager* cm, SearchEngineRules* rules,
00377 const string& mmFlag)
00378 : d_cm(cm), d_rules(rules), d_disableGC(false), d_postponeGC(false) {
00379 if(mmFlag == "chunks")
00380 d_mm = new MemoryManagerChunks(sizeof(VariableValue));
00381 else
00382 d_mm = new MemoryManagerMalloc();
00383
00384 d_notifyObj = new VariableManagerNotifyObj(this, d_cm->getCurrentContext());
00385 }
00386
00387
00388 VariableManager::~VariableManager() {
00389 delete d_notifyObj;
00390
00391 d_disableGC = true;
00392 vector<VariableValue*> vars;
00393 for(VariableValueSet::iterator i=d_varSet.begin(), iend=d_varSet.end();
00394 i!=iend; ++i) {
00395 vars.push_back(*i);
00396
00397
00398
00399 }
00400 d_varSet.clear();
00401 for(vector<VariableValue*>::iterator i=vars.begin(), iend=vars.end();
00402 i!=iend; ++i) delete *i;
00403 delete d_mm;
00404 }
00405
00406
00407 void
00408 VariableManager::gc(VariableValue* v) {
00409 if(!d_disableGC) {
00410 d_varSet.erase(v);
00411 if(d_postponeGC) d_deleted.push_back(v);
00412 else {
00413 delete v;
00414 d_mm->deleteData(v);
00415 }
00416 }
00417 }
00418
00419
00420 void
00421 VariableManager::resumeGC() {
00422 d_postponeGC = false;
00423 while(d_deleted.size() > 0) {
00424 VariableValue* v = d_deleted.back();
00425 d_deleted.pop_back();
00426 delete v;
00427 d_mm->deleteData(v);
00428 }
00429 }
00430
00431 }