00001 #include "continual_planning_executive/symbolicState.h"
00002 #include <sstream>
00003 #include <ros/ros.h>
00004
00005 bool Predicate::operator<(const Predicate & p) const
00006 {
00007 #if 0
00008 if(name < p.name)
00009 return true;
00010 else if(name > p.name)
00011 return false;
00012 if(parameters.size() < p.parameters.size())
00013 return true;
00014 else if(parameters.size() > p.parameters.size())
00015 return false;
00016 for(unsigned int i = 0; i < parameters.size(); i++) {
00017 if(parameters[i] < p.parameters[i])
00018 return true;
00019 else if(parameters[i] > p.parameters[i])
00020 return false;
00021 }
00022
00023 return false;
00024 #endif
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 if(parameters.empty() && !p.parameters.empty())
00038 return true;
00039 if(!parameters.empty() && p.parameters.empty())
00040 return false;
00041
00042 if(parameters.empty() && p.parameters.empty())
00043 return name < p.name;
00044
00045
00046
00047 if(parameters[0] < p.parameters[0])
00048 return true;
00049 if(parameters[0] > p.parameters[0])
00050 return false;
00051
00052 if(name < p.name)
00053 return true;
00054 else if(name > p.name)
00055 return false;
00056
00057 if(parameters.size() < p.parameters.size())
00058 return true;
00059 else if(parameters.size() > p.parameters.size())
00060 return false;
00061 for(unsigned int i = 1; i < parameters.size(); i++) {
00062 if(parameters[i] < p.parameters[i])
00063 return true;
00064 else if(parameters[i] > p.parameters[i])
00065 return false;
00066 }
00067
00068 return false;
00069 }
00070
00071 std::ostream & operator<<(std::ostream & os, const Predicate & p)
00072 {
00073 os << "(" << p.name;
00074 forEach(const string & s, p.parameters) {
00075 os << " " << s;
00076 }
00077 os << ")";
00078 return os;
00079 }
00080
00081
00082 SymbolicState::SymbolicState()
00083 {
00084 }
00085
00086 SymbolicState::~SymbolicState()
00087 {
00088 }
00089
00090 void SymbolicState::addObject(string obj, string type)
00091 {
00092 typedef pair< multimap<string,string>::iterator, multimap<string,string>::iterator > StringMapRange;
00093 multimap<string,string>::iterator mapIt;
00094
00095
00096 StringMapRange ret = _superTypes.equal_range(type);
00097 for(mapIt = ret.first; mapIt != ret.second; mapIt++) {
00098 string st = mapIt->second;
00099
00100
00101 StringMapRange objRange = _typedObjects.equal_range(st);
00102 bool alreadyIn = false;
00103 for(multimap<string,string>::iterator it = objRange.first; it != objRange.second; it++) {
00104 if(it->second == obj) {
00105 alreadyIn = true;
00106 break;
00107 }
00108 }
00109 if(!alreadyIn) {
00110 _typedObjects.insert(make_pair(st, obj));
00111 }
00112 }
00113
00114
00115
00116
00117
00118 ret = _typedObjects.equal_range(type);
00119
00120 for(multimap<string,string>::iterator it = ret.first; it != ret.second; it++) {
00121 if(it->second == obj)
00122 return;
00123 }
00124
00125
00126 _typedObjects.insert(std::make_pair(type, obj));
00127 }
00128
00129 void SymbolicState::addSuperType(string type, string supertype)
00130 {
00131
00132 multimap<string,string>::iterator mapIt;
00133 pair< multimap<string,string>::iterator, multimap<string,string>::iterator > ret;
00134
00135 deque<pair<string, string> > queue;
00136 queue.push_back(make_pair(type, supertype));
00137 queue.push_back(make_pair(type, type));
00138 queue.push_back(make_pair(supertype, supertype));
00139
00140
00141
00142
00143 while(!queue.empty()) {
00144 pair<string, string> stp = queue.front();
00145 queue.pop_front();
00146
00147
00148 ret = _superTypes.equal_range(stp.first);
00149 bool alreadyIn = false;
00150 for(mapIt = ret.first; mapIt != ret.second; mapIt++) {
00151 string st = mapIt->second;
00152 if(stp.second == st) {
00153 alreadyIn = true;
00154 break;
00155 }
00156 }
00157 if(alreadyIn)
00158 continue;
00159
00160
00161 _superTypes.insert(stp);
00162
00163
00164
00165
00166 for(mapIt = _superTypes.begin(); mapIt != _superTypes.end(); mapIt++) {
00167
00168 if(stp.second == mapIt->first)
00169 queue.push_back(make_pair(stp.first, mapIt->second));
00170 if(stp.first == mapIt->second)
00171 queue.push_back(make_pair(mapIt->first, stp.second));
00172 }
00173 }
00174 }
00175
00176 bool SymbolicState::isMostSpecificType(string obj, string type) const
00177 {
00178
00179
00180 multimap<string,string>::const_iterator mapIt;
00181 for(mapIt = _superTypes.begin(); mapIt != _superTypes.end(); mapIt++) {
00182
00183 if(type == mapIt->second && mapIt->first != mapIt->second) {
00184 string t = mapIt->first;
00185
00186 pair< multimap<string,string>::const_iterator, multimap<string,string>::const_iterator > ret;
00187 ret = _typedObjects.equal_range(t);
00188
00189 multimap<string,string>::const_iterator objectIt;
00190 for(objectIt = ret.first; objectIt != ret.second; objectIt++) {
00191 if(objectIt->second == obj) {
00192 return false;
00193 }
00194 }
00195 }
00196 }
00197
00198
00199
00200 return true;
00201 }
00202
00203 void SymbolicState::printSuperTypes() const
00204 {
00205 printf("Type Hierarchy:\n");
00206
00207
00208
00209
00210 string currentType;
00211 multimap<string,string>::const_iterator mapIt;
00212 for(mapIt = _superTypes.begin(); mapIt != _superTypes.end(); mapIt++) {
00213
00214 if(mapIt->first != currentType) {
00215 if(!currentType.empty()) {
00216 printf(")\n");
00217 }
00218 currentType = mapIt->first;
00219 printf("%s is a (object", currentType.c_str());
00220 }
00221 printf(", %s", mapIt->second.c_str());
00222 }
00223 if(!_superTypes.empty())
00224 printf(")\n");
00225 }
00226
00227 void SymbolicState::removeObject(string obj, bool removePredicates)
00228 {
00229 for(multimap<string,string>::iterator it = _typedObjects.begin(); it != _typedObjects.end(); ) {
00230 multimap<string, string>::iterator current = it;
00231 it++;
00232 if(current->second == obj) {
00233 _typedObjects.erase(current);
00234 }
00235 }
00236
00237 if(!removePredicates)
00238 return;
00239
00240 bool removedSomething = true;
00241
00242
00243 while(removedSomething) {
00244 removedSomething = false;
00245 for(map<Predicate, bool>::iterator it = _booleanPredicates.begin(); it != _booleanPredicates.end(); it++) {
00246 bool foundObj = false;
00247 for(vector<string>::const_iterator paramIt = it->first.parameters.begin();
00248 paramIt != it->first.parameters.end(); paramIt++) {
00249 if(obj == *paramIt) {
00250 foundObj = true;
00251 break;
00252 }
00253 }
00254 if(foundObj) {
00255 _booleanPredicates.erase(it);
00256 removedSomething = true;
00257 break;
00258 }
00259 }
00260 }
00261
00262 removedSomething = true;
00263 while(removedSomething) {
00264 removedSomething = false;
00265 for(map<Predicate, double>::iterator it = _numericalFluents.begin(); it != _numericalFluents.end(); it++) {
00266 bool foundObj = false;
00267 for(vector<string>::const_iterator paramIt = it->first.parameters.begin();
00268 paramIt != it->first.parameters.end(); paramIt++) {
00269 if(obj == *paramIt) {
00270 foundObj = true;
00271 break;
00272 }
00273 }
00274 if(foundObj) {
00275 _numericalFluents.erase(it);
00276 removedSomething = true;
00277 break;
00278 }
00279 }
00280 }
00281 }
00282
00283 void SymbolicState::setBooleanPredicate(string name, vector<string> parameters, bool value)
00284 {
00285 Predicate bp;
00286 bp.name = name;
00287 bp.parameters = parameters;
00288
00289 _booleanPredicates[bp] = value;
00290 }
00291
00292 void SymbolicState::setBooleanPredicate(string name, string parameters, bool value)
00293 {
00294 vector<string> params = buildParameterList(parameters);
00295 setBooleanPredicate(name, params, value);
00296 }
00297
00298 void SymbolicState::setAllBooleanPredicates(string name, bool value)
00299 {
00300 forEach(SymbolicState::BooleanPredicateEntry & bp, _booleanPredicates) {
00301 if(bp.first.name == name)
00302 bp.second = value;
00303 }
00304 }
00305
00306 void SymbolicState::setNumericalFluent(string name, vector<string> parameters, double value)
00307 {
00308 Predicate bp;
00309 bp.name = name;
00310 bp.parameters = parameters;
00311
00312 _numericalFluents[bp] = value;
00313 }
00314
00315 void SymbolicState::setNumericalFluent(string name, string parameters, double value)
00316 {
00317 vector<string> params = buildParameterList(parameters);
00318 setNumericalFluent(name, params, value);
00319 }
00320
00321 void SymbolicState::setAllNumericalFluents(string name, double value)
00322 {
00323 forEach(SymbolicState::NumericalFluentEntry & nf, _numericalFluents) {
00324 if(nf.first.name == name)
00325 nf.second = value;
00326 }
00327 }
00328
00329 void SymbolicState::setObjectFluent(string name, vector<string> parameters, string value)
00330 {
00331 Predicate bp;
00332 bp.name = name;
00333 bp.parameters = parameters;
00334
00335 _objectFluents[bp] = value;
00336 }
00337
00338 void SymbolicState::setObjectFluent(string name, string parameters, string value)
00339 {
00340 vector<string> params = buildParameterList(parameters);
00341 setObjectFluent(name, params, value);
00342 }
00343
00344 void SymbolicState::setAllObjectFluents(string name, string value)
00345 {
00346 forEach(SymbolicState::ObjectFluentEntry & of, _objectFluents) {
00347 if(of.first.name == name)
00348 of.second = value;
00349 }
00350 }
00351
00352 void SymbolicState::setForEachGoalStatement(string objectType, string predicateName, bool value)
00353 {
00354 _forEachGoalStatements.insert(pair<string, pair<string, bool> >(objectType, pair<string, bool>(predicateName, value)));
00355 }
00356
00357 bool SymbolicState::hasBooleanPredicate(const Predicate & p, bool* value) const
00358 {
00359 map<Predicate, bool>::const_iterator it = _booleanPredicates.find(p);
00360 if(it == _booleanPredicates.end())
00361 return false;
00362 if(value != NULL)
00363 *value = it->second;
00364 return true;
00365 }
00366
00367 bool SymbolicState::hasNumericalFluent(const Predicate & p, double* value) const
00368 {
00369 map<Predicate, double>::const_iterator it = _numericalFluents.find(p);
00370 if(it == _numericalFluents.end())
00371 return false;
00372 if(value != NULL)
00373 *value = it->second;
00374 return true;
00375 }
00376
00377 bool SymbolicState::hasObjectFluent(const Predicate & p, string* value) const
00378 {
00379 map<Predicate, string>::const_iterator it = _objectFluents.find(p);
00380 if(it == _objectFluents.end())
00381 return false;
00382 if(value != NULL)
00383 *value = it->second;
00384 return true;
00385 }
00386
00387
00388 bool SymbolicState::isFulfilledBy(const SymbolicState & state) const
00389 {
00390 forEach(const BooleanPredicateEntry & bp, _booleanPredicates) {
00391 bool value;
00392
00393 if(!state.hasBooleanPredicate(bp.first, &value))
00394 return false;
00395
00396 if(value != bp.second)
00397 return false;
00398 }
00399
00400 forEach(const NumericalFluentEntry & nf, _numericalFluents) {
00401 double value;
00402
00403 if(!state.hasNumericalFluent(nf.first, &value))
00404 return false;
00405
00406 if(!double_equals(value, nf.second))
00407 return false;
00408 }
00409
00410 forEach(const ObjectFluentEntry & of, _objectFluents) {
00411 string value;
00412
00413 if(!state.hasObjectFluent(of.first, &value))
00414 return false;
00415
00416 if(value != of.second)
00417 return false;
00418 }
00419
00420
00421 forEach(const ForEachGoalStatements::value_type & fobp, _forEachGoalStatements) {
00422 string objectType = fobp.first;
00423
00424 pair< multimap<string,string>::const_iterator, multimap<string,string>::const_iterator > ret;
00425 ret = _typedObjects.equal_range(objectType);
00426 for(multimap<string,string>::const_iterator objectIt = ret.first; objectIt != ret.second; objectIt++)
00427 {
00428 Predicate bp;
00429 bp.name = fobp.second.first;
00430 bp.parameters = buildParameterList(objectIt->second);
00431 bool value;
00432
00433 if(!state.hasBooleanPredicate(bp, &value))
00434 return false;
00435
00436 if(value != fobp.second.second)
00437 return false;
00438 }
00439 }
00440
00441 return true;
00442 }
00443
00444 bool SymbolicState::booleanEquals(const SymbolicState & other) const
00445 {
00446
00447
00448 forEach(const BooleanPredicateEntry & bp, _booleanPredicates) {
00449 bool value;
00450
00451 if(!other.hasBooleanPredicate(bp.first, &value))
00452 return false;
00453
00454 if(value != bp.second)
00455 return false;
00456 }
00457
00458 forEach(const BooleanPredicateEntry & bp, other._booleanPredicates) {
00459 bool value;
00460
00461 if(!hasBooleanPredicate(bp.first, &value))
00462 return false;
00463
00464 if(value != bp.second)
00465 return false;
00466 }
00467 return true;
00468 }
00469
00470 bool SymbolicState::numericalEquals(const SymbolicState & other) const
00471 {
00472 forEach(const NumericalFluentEntry & nf, _numericalFluents) {
00473 double value;
00474
00475 if(!other.hasNumericalFluent(nf.first, &value))
00476 return false;
00477
00478 if(!double_equals(value, nf.second))
00479 return false;
00480 }
00481
00482 forEach(const NumericalFluentEntry & nf, other._numericalFluents) {
00483 double value;
00484
00485 if(!hasNumericalFluent(nf.first, &value))
00486 return false;
00487
00488 if(!double_equals(value, nf.second))
00489 return false;
00490 }
00491 return true;
00492 }
00493
00494 bool SymbolicState::objectFluentsEquals(const SymbolicState & other) const
00495 {
00496 forEach(const ObjectFluentEntry & of, _objectFluents) {
00497 string value;
00498
00499 if(!other.hasObjectFluent(of.first, &value))
00500 return false;
00501
00502 if(value != of.second)
00503 return false;
00504 }
00505
00506 forEach(const ObjectFluentEntry & of, other._objectFluents) {
00507 string value;
00508
00509 if(!hasObjectFluent(of.first, &value))
00510 return false;
00511
00512 if(value != of.second)
00513 return false;
00514 }
00515 return true;
00516 }
00517
00518 bool SymbolicState::equals(const SymbolicState & other) const
00519 {
00520 return booleanEquals(other) && numericalEquals(other) && objectFluentsEquals(other);
00521 }
00522
00523
00524 void SymbolicState::toPDDLProblem(std::ostream & os) const
00525 {
00526 os << " (:objects" << std::endl << " ";
00527 string lastType = "";
00528 for(multimap<string,string>::const_iterator it = _typedObjects.begin(); it != _typedObjects.end(); it++) {
00529 if(!isMostSpecificType(it->second, it->first))
00530 continue;
00531
00532 if(lastType != "" && it->first != lastType) {
00533 os << "- " << lastType << std::endl << " ";
00534 }
00535 lastType = it->first;
00536 os << it->second << " ";
00537 }
00538 if(lastType != "")
00539 os << "- " << lastType;
00540 os << std::endl << " )" << std::endl;
00541 os << " (:init" << std::endl;
00542 forEach(const BooleanPredicateEntry & p, _booleanPredicates) {
00543 if(p.second)
00544 os << " " << p.first << std::endl;
00545 }
00546 forEach(const NumericalFluentEntry & nf, _numericalFluents) {
00547 os << " (= " << nf.first << " " << nf.second << ")" << std::endl;
00548 }
00549 forEach(const ObjectFluentEntry & of, _objectFluents) {
00550 if(of.second.empty()) {
00551 ROS_ERROR_STREAM(__func__ << ": ObjectFluentEntry for " << of.first << " is empty.");
00552 }
00553 os << " (= " << of.first << " " << of.second << ")" << std::endl;
00554 }
00555 os << " )" << std::endl;
00556 }
00557
00558 void SymbolicState::toPDDLGoal(std::ostream & os) const
00559 {
00560
00561 if(_booleanPredicates.empty() && _numericalFluents.empty() && _forEachGoalStatements.empty()) {
00562 os << " (:goal " << std::endl;
00563 os << " )" << std::endl;
00564 return;
00565 }
00566
00567 os << " (:goal (and" << std::endl;
00568 forEach(const BooleanPredicateEntry & p, _booleanPredicates) {
00569 if(p.second)
00570 os << " " << p.first << std::endl;
00571 else
00572 os << " (not " << p.first << ")" << std::endl;
00573 }
00574 forEach(const NumericalFluentEntry & nf, _numericalFluents) {
00575 os << " (= " << nf.first << " " << nf.second << ")" << std::endl;
00576 }
00577 forEach(const ObjectFluentEntry & of, _objectFluents) {
00578 if(of.second.empty()) {
00579 ROS_ERROR_STREAM(__func__ << ": ObjectFluentEntry for " << of.first << " is empty.");
00580 }
00581 os << " (= " << of.first << " " << of.second << ")" << std::endl;
00582 }
00583
00584
00585
00586
00587 forEach(const ForEachGoalStatements::value_type & p, _forEachGoalStatements) {
00588 os << " (forall (?o - " << p.first << ") (";
00589 if(p.second.second)
00590 os << p.second.first << " ?o))" << std::endl;
00591 else
00592 os << "not (" << p.second.first << " ?o)))" << std::endl;
00593 }
00594 os << " ))" << std::endl;
00595 }
00596
00597
00598 vector<string> SymbolicState::buildParameterList(string params) const
00599 {
00600 vector<string> ret;
00601
00602 while(params.size() > 0) {
00603
00604 while(params.size() > 0 && params[0] == ' ') {
00605 params = params.substr(1);
00606 }
00607
00608 if(params.size() > 0) {
00609 size_t ind = params.find_first_of(" ");
00610 ret.push_back(params.substr(0, ind));
00611 if(ind == string::npos) {
00612 params = "";
00613 } else {
00614 params = params.substr(ind);
00615 }
00616 }
00617 }
00618
00619 return ret;
00620 }
00621
00622 unsigned int getShellWidth()
00623 {
00624 string cmd = "stty size";
00625
00626 FILE* p = popen(cmd.c_str(), "r");
00627 if(p == NULL)
00628 return 80;
00629 char buf[1024];
00630 if(fgets(buf, 1024, p) == NULL)
00631 return 80;
00632 pclose(p);
00633
00634
00635 string s(buf);
00636 size_t pos = s.find_first_of(" ");
00637 if(pos == string::npos)
00638 return 80;
00639 s = s.substr(pos + 1);
00640 long w = strtol(s.c_str(), NULL, 10);
00641 if(w <= 0)
00642 return 80;
00643 return w;
00644 }
00645
00646 bool SymbolicState::OStreamMode::forceNewlines = false;
00647
00648 std::ostream & operator<<(std::ostream & os, const SymbolicState & ss) {
00649 os << "Objects:" << std::endl;
00650 string lastType = "";
00651 for(multimap<string,string>::const_iterator it = ss._typedObjects.begin(); it != ss._typedObjects.end(); it++) {
00652 if(!ss.isMostSpecificType(it->second, it->first))
00653 continue;
00654
00655 if(lastType != "" && it->first != lastType) {
00656 os << "- " << lastType << " ";
00657 if(SymbolicState::OStreamMode::forceNewlines) os << std::endl;
00658 }
00659 lastType = it->first;
00660 os << it->second << " ";
00661 }
00662 if(lastType != "")
00663 os << "- " << lastType;
00664
00665 os << std::endl;
00666 if(SymbolicState::OStreamMode::forceNewlines) os << std::endl;
00667 os << "True Predicates:" << std::endl;
00668 forEach(const SymbolicState::BooleanPredicateEntry & bp, ss._booleanPredicates) {
00669 if(bp.second) {
00670 os << bp.first << " ";
00671 if(SymbolicState::OStreamMode::forceNewlines) os << std::endl;
00672 }
00673 }
00674 os << std::endl;
00675 os << "False Predicates:" << std::endl;
00676 forEach(const SymbolicState::BooleanPredicateEntry & bp, ss._booleanPredicates) {
00677 if(!bp.second) {
00678 os << bp.first << " ";
00679 if(SymbolicState::OStreamMode::forceNewlines) os << std::endl;
00680 }
00681 }
00682 os << std::endl;
00683
00684 unsigned int sw = getShellWidth();
00685 int maxEntriesPerLine = 0;
00686 if(SymbolicState::OStreamMode::forceNewlines)
00687 maxEntriesPerLine = 1;
00688 os << "Numerical Fluents:" << std::endl;
00689 int count = 0;
00690 std::stringstream ssLine;
00691 forEach(const SymbolicState::NumericalFluentEntry & nf, ss._numericalFluents) {
00692 std::stringstream ssBuf;
00693 ssBuf << nf.first << " = " << nf.second << " ";
00694
00695 if(maxEntriesPerLine > 0) {
00696 os << ssBuf.str();
00697 } else {
00698 if(ssLine.str().length() + ssBuf.str().length() > sw) {
00699 os << ssLine.str() << std::endl;
00700 ssLine.str("");
00701 }
00702 ssLine << ssBuf.str();
00703 }
00704
00705
00706 count++;
00707 if(maxEntriesPerLine > 0 && count >= maxEntriesPerLine) {
00708 count = 0;
00709 os << std::endl;
00710 }
00711 }
00712 if(!ssLine.str().empty())
00713 os << ssLine.str() << std::endl;
00714 os << std::endl;
00715 os << "Object Fluents:" << std::endl;
00716 count = 0;
00717 ssLine.str("");
00718 forEach(const SymbolicState::ObjectFluentEntry & nf, ss._objectFluents) {
00719 std::stringstream ssBuf;
00720 ssBuf << nf.first << " = " << nf.second << " ";
00721
00722 if(maxEntriesPerLine > 0) {
00723 os << ssBuf.str();
00724 } else {
00725 if(ssLine.str().length() + ssBuf.str().length() > sw) {
00726 os << ssLine.str() << std::endl;
00727 ssLine.str("");
00728 }
00729 ssLine << ssBuf.str();
00730 }
00731
00732
00733 count++;
00734 if(maxEntriesPerLine > 0 && count >= maxEntriesPerLine) {
00735 count = 0;
00736 os << std::endl;
00737 }
00738 }
00739 if(!ssLine.str().empty())
00740 os << ssLine.str() << std::endl;
00741 os << std::endl;
00742
00743 if(!ss._forEachGoalStatements.empty()) {
00744 os << "ForEachGoalStatements:" << std::endl;
00745
00746
00747
00748 forEach(const SymbolicState::ForEachGoalStatements::value_type & p, ss._forEachGoalStatements) {
00749 os << " (forall (?o - " << p.first << ") (";
00750 if(p.second.second)
00751 os << p.second.first << " ?o))" << std::endl;
00752 else
00753 os << "not (" << p.second.first << " ?o)))" << std::endl;
00754 }
00755 }
00756
00757 return os;
00758 }
00759