00001 00002 // 00003 // Copyright (c) 2004 Model-based Embedded and Robotic Systems Group 00004 // All Rights Reserved Massachusetts Institute of Technology 00005 // 00006 // This software is provided as is. Model-based Embedded and Robotic Systems 00007 // (MERS) group does not assume any responsibility. 00008 // 00009 // Organization: Model-based Embedded and Robotic Systems Group 00010 // Massachusetts Institute of Technology 00011 // 00013 //# CHECKED MJP 08-07-2002 00014 00015 //============================================ 00016 // BFIGAssignment IMPLEMENTATION 00017 //============================================ 00018 00019 #ifdef _MSC_VER 00020 #pragma warning( disable : 4786 ) 00021 #endif 00022 00023 #include "BFIGAssignment.h" 00024 00025 #include <cassert> 00026 #include <iomanip> 00027 #include "BFIGVariable.h" 00028 #include "BFIGConstraint.h" 00029 #include <Mers/Models/Base/BaseModelSentence.h> 00030 #include <Mers/Models/Base/BaseModelDomain.h> 00031 00032 using namespace std; 00033 using namespace Mers::Generators::BFIG; 00034 using Mers::Models::Base::BaseModelValue; 00035 using Mers::Utils::Lang::String; 00036 using Mers::Utils::Containers::IntegerArray; 00037 00038 bool BFIGAssignment::terse = false; 00039 00040 //---------------------------------------- 00041 // CONSTRUCTOR 00042 //---------------------------------------- 00043 BFIGAssignment::BFIGAssignment(BFIGVariable const * sourceVariable_p, 00044 BaseModelValue const * assignmentValue, double assignmentCost) 00045 : BaseModelAssignment(sourceVariable_p->getBMVariable(), assignmentValue) 00046 { 00047 assert(sourceVariable_p); 00048 debug = false; 00049 sourceVariable = sourceVariable_p; 00050 trueCost = assignmentCost; 00051 cost = trueCost; 00052 mEnabled = true; 00053 assertThis = new BFIGConstraint(this, true); 00054 assertNotThis = new BFIGConstraint(this, false); 00055 } 00056 00057 /* 00058 BFIGAssignment::BFIGAssignment(BFIGVariable const * sourceVariable_p, 00059 BaseModelValue * assignmentValue, vector<double> const & assignmentCosts, 00060 IntegerArray const & dependentValues) 00061 : BaseModelAssignment(sourceVariable_p->getBMVariable(), assignmentValue) 00062 { 00063 assert(sourceVariable_p); 00064 assert(!assignmentCosts.empty()); 00065 assert(!dependentValues.isEmpty()); 00066 assert(assignmentCosts.size() == dependentValues.getLength()); 00067 debug = false; 00068 sourceVariable = sourceVariable_p; 00069 trueCostList = assignmentCosts; 00070 trueCostValues = dependentValues; 00071 //# trueCost = trueCostList.front(); // hack - not meaningful. 00072 trueCost = 0.0; 00073 cost = trueCost; 00074 isDefaultVal = false; 00075 mEnabled = true; 00076 assertThis = new BFIGConstraint(this, true); 00077 assertNotThis = new BFIGConstraint(this, false); 00078 } 00079 00080 00081 BFIGAssignment::BFIGAssignment(BFIGVariable const * sourceVariable_p, unsigned int assignmentValue, 00082 vector<double> const & assignmentCosts, 00083 IntegerArray const & dependentValues, 00084 DynamicArrayTemplate<BaseModelSentence const> const & guards) 00085 : value(assignmentValue), transitionGuardsClauses(false) 00086 { 00087 assert(sourceVariable_p); 00088 assert(!assignmentCosts.empty()); 00089 assert(!dependentValues.isEmpty()); 00090 assert(assignmentCosts.size() == dependentValues.getLength()); 00091 assert(assignmentCosts.size() == guards.getLength()); 00092 debug = false; 00093 sourceVariable = sourceVariable_p; 00094 trueCostList = assignmentCosts; 00095 trueCostValues = dependentValues; 00096 trueCost = 0.0; 00097 transitionGuardsClauses = guards; // should be gotten rid of - not elegant or efficient. 00098 cost = trueCost; 00099 isDefaultVal = false; 00100 mEnabled = true; 00101 00103 //if (getName() == 0) 00104 //{ 00105 // cout << endl << " Var " << getName() << " : [" << value << "] : {" ; 00106 // IntegerArray::const_iterator vIter; 00107 // vector<BaseModelSentence const *>::const_iterator cIter; 00108 // for (vIter = trueCostValues.begin(), cIter = transitionGuardsClauses.begin(); 00109 // vIter != trueCostValues.end(); vIter++, cIter++) 00110 // { 00111 // if (vIter != trueCostValues.begin()) 00112 // cout << ", "; 00113 // cout << (*vIter) << ":" << (*(*cIter)); 00114 // } 00115 // cout << "}" << " (" << guards.size() << " guards)" << endl << endl; 00116 //} 00117 / 00118 00119 assertThis = new BFIGConstraint(this, true); 00120 assertNotThis = new BFIGConstraint(this, false); 00121 } 00122 */ 00123 00124 BFIGAssignment::~BFIGAssignment() 00125 { 00126 //vector<BFIGConstraint *>::iterator cIter; 00127 //for (cIter = transitionGuards.begin(); cIter != transitionGuards.end(); cIter++) 00128 //{ 00129 // delete (*cIter); 00130 //} 00131 if (assertThis) 00132 delete assertThis; 00133 if (assertNotThis) 00134 delete assertNotThis; 00135 } 00136 00137 //---------------------------------------- 00138 // OVERLOADED OPERATORS 00139 //---------------------------------------- 00140 bool 00141 BFIGAssignment::operator ==(BFIGAssignment const * a) const 00142 { 00143 if (a == NULL) 00144 return false; 00145 00146 return (getVariable()->getName() == a->getVariable()->getName()) && 00147 (getValue() == a->getValue()); 00148 } 00149 00150 bool 00151 BFIGAssignment::operator ==(BFIGAssignment const & a) const 00152 { 00153 return (getVariable()->getName() == a.getVariable()->getName()) && 00154 (getValue() == a.getValue()); 00155 } 00156 00157 00158 bool 00159 BFIGAssignment::operator <(BFIGAssignment const & a) const 00160 { 00161 if (getName() < a.getName()) 00162 return true; 00163 if (getName() > a.getName()) 00164 return false; 00165 return (getValue() < a.getValue()); 00166 } 00167 00168 00169 //---------------------------------------- 00170 // PUBLIC FUNCTION METHODS 00171 //---------------------------------------- 00172 00173 void 00174 BFIGAssignment::setDebug(bool debugState) 00175 { 00176 debug = debugState; 00177 } 00178 00179 00180 unsigned int 00181 BFIGAssignment::getValue() const 00182 { 00183 return getValueInt(); 00184 } 00185 00186 00187 String 00188 BFIGAssignment::getValueString() const 00189 { 00190 return BaseModelAssignment::getValue()->getName(); 00191 } 00192 00193 00194 unsigned int 00195 BFIGAssignment::getValueInt() const 00196 { 00197 return BaseModelAssignment::getValue()->getUID(); 00198 } 00199 00200 00201 Mers::Generators::BFIG::BFIGVariable const * 00202 BFIGAssignment::getVariable() const 00203 { 00204 return sourceVariable; 00205 } 00206 00207 00208 unsigned int 00209 BFIGAssignment::getName() const 00210 { 00211 return getVariable()->getName(); 00212 } 00213 00214 00215 String 00216 BFIGAssignment::getNameString() const 00217 { 00218 return getVariable()->getNameString(); 00219 } 00220 00221 00222 unsigned int 00223 BFIGAssignment::getNameInt() const 00224 { 00225 return getVariable()->getNameInt(); 00226 } 00227 00228 00229 /*# 00230 void 00231 BFIGAssignment::setValue(BFIGVariable::Value newValue) 00232 { 00233 value = newValue; 00234 } 00235 */ 00236 00237 double 00238 BFIGAssignment::getCost() const 00239 { 00240 return cost; 00241 } 00242 00243 double 00244 BFIGAssignment::getTrueCost() const 00245 { 00246 return trueCost; 00247 } 00248 00249 00250 void 00251 BFIGAssignment::setCost(double assignmentCost) 00252 { 00253 cost = assignmentCost; 00254 if ( cost == -0.0 ) // fix for -0.0... 00255 cost = 0.0; 00256 ((BFIGVariable *)sourceVariable)->isSorted = false; 00257 ((BFIGVariable *)sourceVariable)->bestAssignment = NULL; 00258 } 00259 00260 void 00261 BFIGAssignment::setTrueCost(double assignmentCost) 00262 { 00263 trueCost = assignmentCost; 00264 /*# better than nothing? */ 00265 setCost(trueCost); 00266 } 00267 00268 00269 bool 00270 BFIGAssignment::isEnabled() const 00271 { 00272 return mEnabled; 00273 } 00274 00275 00276 void 00277 BFIGAssignment::setEnabled(bool enabled) 00278 { 00279 mEnabled = enabled; 00280 ((BFIGVariable *)sourceVariable)->bestAssignment = NULL; 00281 } 00282 00283 /* 00284 bool 00285 BFIGAssignment::isCurrent() const 00286 { 00287 return (this == getVariable()->getCurrentAssignment()); 00288 } 00289 00290 00291 void 00292 BFIGAssignment::setAsCurrent() const 00293 { 00294 ((BFIGVariable *)getVariable())->setCurrent(this); 00295 } 00296 00297 00298 bool 00299 BFIGAssignment::isNext() const 00300 { 00301 return (this == getVariable()->getNextAssignment()); 00302 } 00303 00304 00305 void 00306 BFIGAssignment::setAsNext() const 00307 { 00308 ((BFIGVariable *)getVariable())->setNext(this); 00309 } 00310 */ 00311 00312 Mers::Generators::BFIG::BFIGConstraint const * 00313 BFIGAssignment::getConstraint() const 00314 { 00315 return assertThis; 00316 } 00317 00318 00319 Mers::Generators::BFIG::BFIGConstraint const * 00320 BFIGAssignment::getNegativeConstraint() const 00321 { 00322 return assertNotThis; 00323 } 00324 00325 /* 00326 void 00327 BFIGAssignment::convertGuards(ModelConvertorInterface const * mc) 00328 { 00329 assert(transitionGuards.empty()); 00330 DynamicArrayTemplate<BaseModelSentence const>::ConstantIterator cIter; 00331 for (cIter = transitionGuardsClauses.begin(); 00332 cIter != transitionGuardsClauses.end(); cIter++) 00333 { 00334 BaseModelSentence const &guard = (*cIter); 00335 //if (guard->type() == BaseModelSentence::DISJUNCTIVE) 00336 //{ 00337 // cerr << "Error: BFIGAssignment.convertGuards cannot handle disjunctions! " 00338 // << "in guard clause: " << (*guard) << endl; 00339 //} 00340 if(&guard && guard.getLength() > 0 && guard[0] != NULL) 00341 transitionGuards.push_back(mc->clauseToConstraint(guard[0], true)); 00342 } 00343 transitionGuardsClauses.makeEmpty(); 00344 } 00345 00346 00347 void 00348 BFIGAssignment::enableByGuard(AssignmentTesterInterface * currentSat, unsigned int priorVal) 00349 { 00350 setEnabled(true); 00351 if (transitionGuards.empty()) 00352 return; // assume enabled if no guards. 00353 00354 IntegerArray::const_iterator vIter; 00355 vector<BFIGConstraint *>::const_iterator cIter; 00356 for (vIter = trueCostValues.begin(), cIter = transitionGuards.begin(); 00357 vIter != trueCostValues.end(); vIter++, cIter++) 00358 { 00359 if ((unsigned int)(*vIter) == priorVal) 00360 { 00361 // found the right guard... 00362 BFIGConstraint * guard = (*cIter); 00363 // should check for its entailment now... 00364 //if (debug) 00365 //{ 00366 cout << "Found guard: BFIGAssignment: " << (*this) 00367 << " (" << priorVal << "," << getVariable()->getCurrentAssignment()->getValue() << ")" 00368 << ", guard: " << (*guard) 00369 << endl; 00370 //} 00371 if (guard->empty()) // && guard->type() == BaseModelSentence::CONJUNCTIVE 00372 { 00373 return; // trivially satisfied - leave enabled. 00374 } 00375 // perform the check: 00376 / *# 00377 //Implicant imp; // can we use this? 00380 //BFIGConstraint guardConstraint; 00381 //BaseModelSentence::const_iterator gcIter; 00382 //for (gcIter = guard->begin(); gcIter != guard->end(); gcIter++) 00383 //{ 00384 // literal lit = (*gcIter); 00385 // bool litType = (lit.type() == literal::POSITIVE); 00386 // BFIGAssignment const * litAssignment = NULL; 00387 // BFIGAssignment const a = (*litIter).proposition(); 00388 // //// *** need to convert the literal to the BFIGAssignment!!! 00389 // if (litAssignment) 00390 // guardConstraint.addUnit(ConstraintUnit(litAssignment, litType)); 00391 //} 00392 //if (currentSat.tryAssignment(imp, true, useDPLL).empty()) // guard is entailed 00393 00394 //currentSat.addTemporaryConstraint(guardConstraint.toisatClause(¤tSat)); 00395 //if (currentSat.consistent(true)) 00396 / 00397 BaseModelAssignmentArray conflict(false); 00398 BaseModelAssignmentArray bmGuard(true); 00399 list<BFIGConstraintUnit> bfigCUnits = guard->getConstraintUnits(); 00400 list<BFIGConstraintUnit>::iterator iter; 00401 for(iter = bfigCUnits.begin(); iter != bfigCUnits.end(); iter++){ 00402 BaseModelVariable * bmVar = iter->getVariable()->getBMVariable(); 00403 BaseModelAssignment * bmAsg = 00404 new BaseModelAssignment(bmVar, bmVar->getDomain()->getValue(iter->getValueInt()), 00405 (iter->getParity() ? BaseModelAssignment::Positive : BaseModelAssignment::Negative)); 00406 bmGuard.pushBack(bmAsg); 00407 } 00408 00409 AssignmentTesterInterface::SolutionType solution = 00410 currentSat->tryAssignment(&bmGuard, 0, true, conflict); 00411 //if (!isCorrect) // guard is entailed 00412 if(solution == AssignmentTesterInterface::Unsatisfiable) 00413 { 00414 if (debug) 00415 cout << " " << "guard is entailed." << endl; 00416 setEnabled(true); 00417 } else 00418 { 00419 if (debug) 00420 cout << " " << "guard is NOT entailed." << endl; 00421 setEnabled(false); 00422 } 00423 return; 00424 } 00425 } 00426 cerr << "Error: BFIGAssignment " << (*this) << " could not find value " 00427 << "in enableByGuard()!" << endl; 00428 } 00429 00430 00431 void 00432 BFIGAssignment::enableByGuard(unsigned int priorVal) 00433 { 00434 setEnabled(true); 00435 if (transitionGuards.empty()) 00436 return; // assume enabled if no guards. 00437 00438 IntegerArray::const_iterator vIter; 00439 vector<BFIGConstraint *>::const_iterator cIter; 00440 00441 if (debug) 00442 { 00443 cout << "Source modes for BFIGAssignment: " << (*this) << endl; 00444 for (vIter = trueCostValues.begin(), cIter = transitionGuards.begin(); 00445 vIter != trueCostValues.end(); vIter++, cIter++) 00446 { 00447 cout << getVariable()->getAssignmentByValue(*vIter)->getValueString() 00448 << " guard: " << *(*cIter) << endl; 00449 } 00450 cout << endl; 00451 } 00452 00453 for (vIter = trueCostValues.begin(), cIter = transitionGuards.begin(); 00454 vIter != trueCostValues.end(); vIter++, cIter++) 00455 { 00456 if ((unsigned int)(*vIter) == priorVal) 00457 { 00458 // found the right guard... 00459 BFIGConstraint * guard = (*cIter); 00460 // check for its entailment now... without sat engine... 00461 if (debug) 00462 { 00463 cout << "Found guard: BFIGAssignment: " << (*this) 00464 << " (" << priorVal << "," << getVariable()->getCurrentAssignment()->getValue() << ")" 00465 << ", guard: " << (*guard) 00466 << endl; 00467 } 00468 setEnabled(guard->isSatisfiedCurrent(true)); 00469 return; 00470 } 00471 } 00472 cerr << "Error: BFIGAssignment " << (*this) << " could not find value " 00473 << "in enableByGuard()!" << endl; 00474 } 00475 */ 00476 00477 /* 00478 void 00479 BFIGAssignment::setTrueCostByValue(unsigned int priorVal) 00480 { 00481 if (trueCostList.empty()) 00482 { 00483 //cerr << "Error: cannot set BFIGAssignment " << (*this) << " cost using prior " 00484 // << priorVal << " without cost vector!" << endl; 00485 return; 00486 } 00487 IntegerArray::const_iterator vIter; 00488 vector<double>::const_iterator cIter; 00489 for (vIter = trueCostValues.begin(), cIter = trueCostList.begin(); 00490 vIter != trueCostValues.end(); vIter++, cIter++) 00491 { 00492 if ((unsigned int)(*vIter) == priorVal) 00493 { 00494 setTrueCost((*cIter)); 00495 return; 00496 } 00497 } 00498 cerr << "Error: BFIGAssignment " << (*this) << " could not find value " 00499 << "in setCostByValue()!" << endl; 00500 } 00501 */ 00502 00503 bool 00504 BFIGAssignment::compatible(BFIGAssignment const *a) const 00505 { 00506 return (getName() != a->getName() || getValue() == a->getValue()); 00507 } 00508 00509 00510 bool 00511 BFIGAssignment::compatible(vector<BFIGAssignment const *> const & a) const 00512 { 00513 vector<BFIGAssignment const *>::const_iterator assignmentIter; 00514 for (assignmentIter = a.begin(); assignmentIter != a.end(); assignmentIter++) 00515 { 00516 if (!compatible(*assignmentIter)) 00517 return false; 00518 } 00519 return true; 00520 } 00521 00522 00523 IntegerArray 00524 BFIGAssignment::alternateValues() const 00525 // ******************************* 00526 // This function will generate all of the alternate assignments that this 00527 // particular BFIGAssignment points to. 00528 // This is generated by searching through the vector for the BFIGAssignment and then 00529 // removing it. 00530 // ******************************* 00531 { 00532 IntegerArray reducedDomain; 00533 00534 IntegerArray variableDomain = sourceVariable->getDomain(); 00535 00536 for (unsigned int x = 0; x < variableDomain.getLength(); x++) { 00537 if (value->getUID() != (unsigned int) variableDomain[x]) 00538 reducedDomain.pushBack(variableDomain[x]); 00539 } 00540 00541 return reducedDomain; 00542 } 00543 00544 00545 list<BFIGAssignment const *> 00546 BFIGAssignment::alternateAssignments() const 00547 // ******************************* 00548 // This function will generate all of the alternate assignments that this 00549 // particular assignment points to. 00550 // This is generated by searching through the vector for the assignment and then 00551 // removing it. 00552 // ******************************* 00553 { 00554 list<BFIGAssignment const *> others; 00555 00556 vector<BFIGAssignment const *> assignmentSet = sourceVariable->getAssignments(); 00557 00558 for (unsigned int x = 0; x < assignmentSet.size(); x++) { 00559 if (value->getUID() != assignmentSet[x]->getValue() && 00560 assignmentSet[x]->isEnabled()) 00561 others.push_back(assignmentSet[x]); 00562 } 00563 00564 return others; 00565 } 00566 00567 00568 vector<BFIGAssignment const *> 00569 BFIGAssignment::alternateAssignmentsTotal() const 00570 { 00571 vector<BFIGAssignment const *> others; 00572 00573 vector<BFIGAssignment const *> assignmentSet = sourceVariable->getAssignments(); 00574 00575 for (unsigned int x = 0; x < assignmentSet.size(); x++) { 00576 if (value->getUID() != assignmentSet[x]->getValue()) 00577 others.push_back(assignmentSet[x]); 00578 } 00579 return others; 00580 } 00581 00582 00583 String 00584 BFIGAssignment::toString() const 00585 { 00586 String res = ""; 00587 res += "( " ; 00588 res += sourceVariable->getNameString() ; 00589 res += " = " ; 00590 res += getValueString() ; 00591 res += " )" ; 00592 //res += "\n" ; 00593 return res; 00594 } 00595 00596 namespace Mers { 00597 namespace Generators { 00598 namespace BFIG { 00599 00600 ostream& 00601 operator<<(ostream& os, BFIGAssignment const & a) 00602 { 00603 //# Apparently, MSVC does not understand the concept of "friends" very well. 00604 if (a.terse) 00605 { 00606 os << a.getName() << "=" << a.getValue(); 00607 } else 00608 { 00609 int p = os.precision(); 00610 os << "(" << a.getVariable()->getNameString() << "[" << a.getName() << "]" << " = " ; 00611 os << a.getValueString() << "[" << a.getValue() << "]" << ":" 00612 << setprecision(2) << a.getCost() << setprecision(p) << ")" ; 00613 } 00614 00615 return os; 00616 } 00617 } 00618 } 00619 } 00620 00621 //---------------------------------------- 00622 // PRIVATE FUNCTION METHODS 00623 //---------------------------------------- 00624 00625 00626 00627 00628 00629 00630
1.5.0