Clingo.cpp
Go to the documentation of this file.
00001 #include <actasp/reasoners/Clingo.h>
00002 
00003 #include "IsNotLocallyOptimal.h"
00004 #include "LexComparator.h"
00005 
00006 #include <actasp/AnswerSet.h>
00007 #include <actasp/action_utils.h>
00008 #include <actasp/Action.h>
00009 
00010 #include <ctime>
00011 
00012 #include <sstream>
00013 #include <ostream>
00014 #include <iterator>
00015 #include <algorithm>
00016 #include <fstream>
00017 #include <cmath> //for floor
00018 
00019 #include <iostream>
00020 #include <ctime>
00021 
00022 #define CURRENT_FILE_HOME std::string("/tmp/")
00023 #define CURRENT_STATE_FILE std::string("current.asp")
00024 
00025 using namespace std;
00026 
00027 namespace actasp {
00028 
00029 
00030 
00031 //own the actions in the map
00032 Clingo::Clingo(unsigned int max_n,
00033                const std::string& incrementalVar,
00034                const std::string& queryDir,
00035                const std::string& domainDir,
00036                const ActionSet& actions,
00037                unsigned int max_time
00038               ) throw() :
00039   max_n(max_n),
00040   incrementalVar(incrementalVar),
00041   max_time(max_time),
00042   queryDir(queryDir),
00043   domainDir(domainDir),
00044   allActions(actions),
00045   actionFilter() {
00046 
00047   if (max_time > 0 && !system("timeout 2>/dev/null")) //make sure timeout is available
00048     max_time = 0;
00049 
00050   //make sure directory ends with '/'
00051 
00052   if (this->queryDir.find_last_of("/") != (this->queryDir.length() -1))
00053     this->queryDir += "/";
00054 
00055   if ((this->domainDir.find_last_of("/")) != (this->domainDir.length() -1))
00056     this->domainDir += "/";
00057 
00058   //TODO test the existance of the directories
00059 
00060   stringstream filterStream;
00061   filterStream << "#hide." << endl;
00062 
00063   std::set<AspFluent>::const_iterator actIt = allActions.begin();
00064   for (; actIt != allActions.end(); ++actIt) {
00065     filterStream << "#show " << actIt->getName() << "/" << actIt->arity() << "." << endl;
00066   }
00067 
00068   actionFilter = filterStream.str();
00069 }
00070 
00071 struct RuleToString {
00072   RuleToString(unsigned int timeStepNum) {
00073     stringstream ss;
00074     ss << timeStepNum;
00075     timeStep = ss.str();
00076   }
00077 
00078   RuleToString(const string& timeStepVar) : timeStep(timeStepVar) {}
00079 
00080   std::string operator()(const AspRule& rule) {
00081 
00082     stringstream ruleStream;
00083 
00084     //iterate over head
00085     for (int i =0, size = rule.head.size(); i <size; ++i) {
00086       ruleStream << rule.head[i].toString(timeStep);
00087       if (i < (size-1))
00088         ruleStream << ", ";
00089     }
00090 
00091     if (!(rule.body.empty()))
00092       ruleStream << ":- ";
00093 
00094     //iterate over body
00095     for (int i =0, size = rule.body.size(); i <size; ++i) {
00096       ruleStream << rule.body[i].toString(timeStep);
00097       if (i < (size-1))
00098         ruleStream << ", ";
00099     }
00100 
00101     if (!(rule.head.empty() && rule.body.empty()))
00102       ruleStream << "." << std::endl;
00103 
00104     return ruleStream.str();
00105   }
00106 
00107   string timeStep;
00108 };
00109 
00110 
00111 static string aspString(const std::vector<actasp::AspRule>& query, const string& timeStepVar) {
00112 
00113   stringstream aspStream;
00114   transform(query.begin(),query.end(),ostream_iterator<std::string>(aspStream),RuleToString(timeStepVar));
00115   return aspStream.str();
00116 }
00117 
00118 static string aspString(const std::vector<actasp::AspRule>& query, unsigned int timeStep) {
00119 
00120   stringstream vs;
00121   vs << timeStep;
00122 
00123   return aspString(query,vs.str());
00124 }
00125 
00126 static std::list<AspFluent> parseAnswerSet(const std::string& answerSetContent) {
00127 
00128   stringstream predicateLine(answerSetContent);
00129 
00130   list<AspFluent> predicates;
00131 
00132   //split the line based on spaces
00133   copy(istream_iterator<string>(predicateLine),
00134             istream_iterator<string>(),
00135             back_inserter(predicates));
00136 
00137   return predicates;
00138 }
00139 
00140 
00141 static std::list<actasp::AnswerSet> readAnswerSets(const std::string& filePath) {
00142 
00143   ifstream file(filePath.c_str());
00144 
00145   list<AnswerSet> allSets;
00146   bool answerFound = false;
00147 
00148   string line;
00149   while(file) {
00150 
00151     getline(file,line);
00152 
00153     if(answerFound && line == "UNSATISFIABLE")
00154       return list<AnswerSet>();
00155 
00156     if(line.find("Answer") != string::npos) {
00157       getline(file,line);
00158         try {
00159           list<AspFluent> fluents = parseAnswerSet(line);
00160           allSets.push_back(AnswerSet(fluents.begin(), fluents.end()));
00161         } catch (std::invalid_argument& arg) {
00162           //swollow it and skip this answer set.
00163         }
00164     }
00165   }
00166 
00167  return allSets;
00168 }
00169 
00170 std::list<actasp::AnswerSet> Clingo::krQuery(const std::string& query,
00171     unsigned int initialTimeStep,
00172     unsigned int finalTimeStep,
00173     const std::string& fileName,
00174     unsigned int answerSetsNumber = 1) const throw() {
00175 
00176 
00177   //this depends on our way of representing stuff.
00178   //iclingo starts from 1, while we needed the initial state and first action to be at time step 0
00179   initialTimeStep++;
00180   finalTimeStep++;
00181 
00182   string queryPath = queryDir + fileName;
00183 
00184   ofstream queryFile(queryPath.c_str());
00185   queryFile << query << endl;
00186   queryFile.close();
00187 
00188   stringstream commandLine;
00189 
00190   const string outputFilePath = queryDir + "query_output.txt";
00191 
00192   if (max_time > 0) {
00193     commandLine << "timeout " << max_time << " ";
00194   }
00195 
00196   stringstream iterations;
00197   iterations << "--imin=" << initialTimeStep << " --imax=" << finalTimeStep;
00198 
00199   commandLine << "iclingo " << iterations.str() << " " << queryPath << " " << domainDir << "*.asp " << (CURRENT_FILE_HOME + CURRENT_STATE_FILE) << " > " << outputFilePath << " " << answerSetsNumber;
00200 
00201 
00202   if (!system(commandLine.str().c_str())) {
00203     //maybe do something here, or just kill the warning about the return value not being used.
00204   }
00205 
00206   return readAnswerSets(outputFilePath);
00207 
00208 }
00209 
00210 string Clingo::generatePlanQuery(const std::vector<actasp::AspRule>& goalRules,
00211                                  bool filterActions = true) const throw() {
00212   stringstream goal;
00213   goal << "#volatile " << incrementalVar << "." << endl;
00214   //I don't like this -1 too much, but it makes up for the incremental variable starting at 1
00215   goal << aspString(goalRules,incrementalVar+"-1") << endl;
00216 
00217   if (filterActions)
00218     goal << actionFilter;
00219 
00220 
00221   return goal.str();
00222 }
00223 
00224 
00225 
00226 ActionSet Clingo::availableActions() const throw() {
00227   list<AnswerSet> actions = krQuery(generatePlanQuery(vector<AspRule>(), true),1,1,"planQuery.asp",0);
00228 
00229   ActionSet computed;
00230 
00231   //the first answer set contains the current state and no actions
00232   list<AnswerSet>::iterator act = ++actions.begin();
00233   for (; act != actions.end(); ++act) {
00234     computed.insert(act->getFluents().begin(), act->getFluents().end());
00235   }
00236 
00237   return computed;
00238 }
00239 
00240 
00241 AnswerSet Clingo::computePlan(const std::vector<actasp::AspRule>& goal) const throw() {
00242 
00243   list<AnswerSet> answerSets;
00244 
00245   string query = generatePlanQuery(goal);
00246 
00247   answerSets = krQuery(query,0,max_n,"planQuery.asp");
00248 
00249 
00250   if (answerSets.empty())
00251     return AnswerSet();
00252 
00253   return  *(answerSets.begin());
00254 }
00255 
00256 struct PolicyMerger {
00257 
00258   PolicyMerger(MultiPolicy & policy) :
00259     policy(policy) {}
00260 
00261   void operator()(const AnswerSet& set) {
00262     policy.merge(set);
00263   }
00264 
00265   MultiPolicy &policy;
00266 };
00267 
00268 //substituted with the check on sub-sequences
00269 
00270 // static set<AspFluent> reducePlan(const list<AspFluent> &plan, int begin, int length) {
00271 //
00272 //   set<AspFluent> newPlan;
00273 //
00274 //   list<AspFluent>::const_iterator actionIt = plan.begin();
00275 //
00276 //   for (int timeStep = 0; actionIt != plan.end(); ++timeStep, ++actionIt) {
00277 //     if (timeStep < begin) {
00278 //       newPlan.insert(*actionIt);
00279 //     } else if (timeStep >= begin + length) {
00280 //       AspFluent fluentCopy(*actionIt);
00281 //       fluentCopy.setTimeStep(timeStep - length);
00282 //       newPlan.insert(fluentCopy);
00283 //     }
00284 //   }
00285 //
00286 //   return newPlan;
00287 // }
00288 //
00289 // struct IsNotLocallyOptimal {
00290 //
00291 //   IsNotLocallyOptimal(const Clingo *reasoner,
00292 //                       const std::vector<actasp::AspRule>& goal,
00293 //                       const ActionSet &allActions ) : reasoner(reasoner), goal(goal), allActions(allActions) {}
00294 //
00295 //   bool operator()(const AnswerSet& plan) const {
00296 //
00297 //     list<AspFluent> actionsOnly;
00298 //
00299 //     remove_copy_if(plan.getFluents().begin(), plan.getFluents().end(),
00300 //                      back_inserter(actionsOnly),not1(IsAnAction(allActions)));
00301 //
00302 //     for (int length = 1; length < actionsOnly.size(); ++length) {
00303 //
00304 //       for (int begin = 0; begin <= actionsOnly.size() - length; ++begin) {
00305 //
00306 //         //remove length actions from begin
00307 //         set<AspFluent> reduced = reducePlan(actionsOnly,begin,length);
00308 //
00309 //         if (reasoner->isPlanValid(AnswerSet(true,reduced),goal))
00310 //           return true;
00311 //
00312 //       }
00313 //     }
00314 //
00315 //     return false;
00316 //   }
00317 //
00318 //   const Clingo *reasoner;
00319 //   const vector<actasp::AspRule>& goal;
00320 //   const ActionSet &allActions;
00321 // };
00322 
00323 
00324 //checks wheter the shorter plan occurs in the longer one. For instance: ABCDEF and ABCDXYEF removing XY
00325 
00326 struct IsSubSequence {
00327 
00328   IsSubSequence(const list< AspFluent> &myPlan) : longerPlan(myPlan) {};
00329 
00330   bool operator()(const list<AspFluent> &shorterPlan) const {
00331 
00332     pair< list< AspFluent>::const_iterator, list< AspFluent>::const_iterator>
00333     start = mismatch(shorterPlan.begin(),shorterPlan.end(),longerPlan.begin(), ActionEquality());
00334 
00335     size_t remaining = distance(start.first, shorterPlan.end());
00336     list< AspFluent>::const_iterator secondStart = longerPlan.end();
00337     advance(secondStart, -remaining);
00338 
00339     return equal(start.first, shorterPlan.end(), secondStart, ActionEquality());
00340 
00341   }
00342 
00343   const list< AspFluent> &longerPlan;
00344 
00345 };
00346 
00347 struct IsNotLocallyOptimalSubPlanCheck {
00348 
00349   IsNotLocallyOptimalSubPlanCheck(const set< list< AspFluent>,LexComparator > &allPlans, const ActionSet &allActions) :
00350     allPlans(allPlans), allActions(allActions) {}
00351 
00352   bool operator()(const AnswerSet& plan) const {
00353     list<AspFluent> actionsOnly;
00354 
00355     remove_copy_if(plan.getFluents().begin(), plan.getFluents().end(),
00356                    back_inserter(actionsOnly),not1(IsAnAction(allActions)));
00357 
00358     set< list< AspFluent>, LexComparator >::const_iterator sub = find_if(allPlans.begin(),allPlans.end(),IsSubSequence(actionsOnly));
00359 
00360     return sub != allPlans.end();
00361   }
00362 
00363   const set< list< AspFluent>, LexComparator > &allPlans;
00364   const ActionSet &allActions;
00365 };
00366 
00367 struct CleanPlan {
00368 
00369   CleanPlan(const ActionSet &allActions) : allActions(allActions) {}
00370 
00371   list<AspFluentRef> operator()(const AnswerSet &planWithStates) const {
00372     list<AspFluentRef> actionsOnly;
00373 
00374     remove_copy_if(planWithStates.getFluents().begin(), planWithStates.getFluents().end(),
00375                    back_inserter(actionsOnly),not1(IsAnAction(allActions)));
00376 
00377     return actionsOnly;
00378 
00379   }
00380 
00381   const ActionSet &allActions;
00382 
00383 };
00384 
00385 struct PlanLongerThan {
00386 
00387   PlanLongerThan(unsigned int length) : length(length) {}
00388 
00389   bool operator()(const AnswerSet& plan) const {
00390     return plan.maxTimeStep() > length;
00391   }
00392 
00393   unsigned int length;
00394 };
00395 
00396 struct AnswerSetRef {
00397   AnswerSetRef(const AnswerSet& aset) : aset(&aset) {}
00398 
00399   operator const AnswerSet&() const {
00400     return *aset;
00401   }
00402 
00403   const AnswerSet *aset;
00404 };
00405 
00406 
00407 
00408 MultiPolicy Clingo::computePolicy(const std::vector<actasp::AspRule>& goal, double suboptimality) const throw (std::logic_error) {
00409 
00410   if (suboptimality < 1) {
00411     stringstream num;
00412     num << suboptimality;
00413     throw logic_error("Clingo: suboptimality value cannot be less then one, found: " + num.str());
00414   }
00415 
00416   string query = generatePlanQuery(goal,false);
00417 
00418   clock_t kr1_begin = clock();
00419   list<AnswerSet> firstAnswerSets = krQuery(query,1,max_n,"planQuery.asp",0);
00420   clock_t kr1_end = clock();
00421   cout << "The first kr call took " << (double(kr1_end - kr1_begin) / CLOCKS_PER_SEC) << " seconds" << endl;
00422 
00423   MultiPolicy policy(allActions);
00424 
00425   if (firstAnswerSets.empty())
00426     return policy;
00427 
00428   unsigned int shortestLength = firstAnswerSets.begin()->maxTimeStep();
00429 
00430   for_each(firstAnswerSets.begin(),firstAnswerSets.end(),PolicyMerger(policy));
00431 
00432   int maxLength = floor(suboptimality * shortestLength);
00433 
00434   if (maxLength == shortestLength)
00435     return policy;
00436 
00437   //all accepted plans sorted lexicographically
00438   set< list <AspFluentRef>, LexComparator > goodPlans;
00439 
00440   //remove the states from the plans
00441   transform(firstAnswerSets.begin(),firstAnswerSets.end(),inserter(goodPlans,goodPlans.begin()), CleanPlan(allActions));
00442 
00443   query = generatePlanQuery(goal,false);
00444 
00445   clock_t kr2_begin = clock();
00446   list<AnswerSet> answerSets = krQuery(query,maxLength,maxLength,"planQuery.asp",0);
00447   clock_t kr2_end = clock();
00448   cout << "The second kr call took " << (double(kr2_end - kr2_begin) / CLOCKS_PER_SEC) << " seconds" << endl;
00449 
00450   //skip the minimial plans
00451   list<AnswerSet>::iterator currentFirst = find_if(answerSets.begin(),answerSets.end(),PlanLongerThan(answerSets.begin()->maxTimeStep()));
00452 
00453   set< list <AspFluentRef>, LexComparator > badPlans;
00454   //this object remembers the set of bad plans, cannot be created inside the loop
00455   IsNotLocallyOptimal isNotLocallyOptimal(&goodPlans,&badPlans, allActions, shortestLength,false);
00456 
00457   clock_t filter_begin = clock();
00458   while (currentFirst != answerSets.end()) {
00459 
00460     //process the plans in groups of increasing length
00461 
00462     list<AnswerSet>::iterator currentLast = find_if(currentFirst,answerSets.end(),PlanLongerThan(currentFirst->maxTimeStep()));
00463 
00464     list<AnswerSetRef> goodPointers;
00465     remove_copy_if(currentFirst,currentLast,back_inserter(goodPointers),isNotLocallyOptimal);
00466 
00467     for_each(goodPointers.begin(),goodPointers.end(),PolicyMerger(policy));
00468 
00469     transform(goodPointers.begin(),goodPointers.end(),inserter(goodPlans, goodPlans.begin()), CleanPlan(allActions));
00470 
00471     currentFirst = currentLast;
00472 
00473   }
00474   clock_t filter_end = clock();
00475 
00476   set< list <AspFluentRef>, LexComparator >::const_iterator printIt = goodPlans.begin();
00477   for (; printIt != goodPlans.end(); ++printIt) {
00478     copy(printIt->begin(),printIt->end(),ostream_iterator<string>(cout, " "));
00479     cout << endl;
00480   }
00481 
00482   cout << "filtering took " << (double(filter_end - filter_begin) / CLOCKS_PER_SEC) << " seconds" << endl;
00483 
00484 
00485   return policy;
00486 
00487 }
00488 
00489 struct AnswerSetToList {
00490   list <AspFluentRef> operator()(const AnswerSet& aset) const {
00491 
00492     return list <AspFluentRef>(aset.getFluents().begin(), aset.getFluents().end());
00493 
00494   }
00495 };
00496 
00497 struct ListToAnswerSet {
00498   AnswerSet operator()(const list<AspFluent>& plan) {
00499     return AnswerSet(plan.begin(), plan.end());
00500   }
00501 
00502 };
00503 
00504 
00505 std::vector< AnswerSet > Clingo::computeAllPlans(const std::vector<actasp::AspRule>& goal,
00506     double suboptimality) const throw () {
00507 
00508   if (suboptimality < 1) {
00509     stringstream num;
00510     num << suboptimality;
00511     throw logic_error("Clingo: suboptimality value cannot be less then one, found: " + num.str());
00512   }
00513 
00514   string query = generatePlanQuery(goal,true);
00515   list<AnswerSet> firstAnswerSets = krQuery(query,0,max_n,"planQuery.asp",0);
00516 
00517   if (firstAnswerSets.empty())
00518     return vector<AnswerSet>();
00519 
00520   //when actions are filtered and there are not state fluents,
00521   //the last time step is of the last action, and actions start at
00522   //zero, so we need +1
00523   unsigned int shortestLength = firstAnswerSets.begin()->maxTimeStep()+1;
00524 
00525   int maxLength = floor(suboptimality * shortestLength);
00526 
00527   if (maxLength == shortestLength)
00528     return vector<AnswerSet>(firstAnswerSets.begin(), firstAnswerSets.end());
00529 
00530   set< list <AspFluentRef>, LexComparator > goodPlans;
00531   transform(firstAnswerSets.begin(), firstAnswerSets.end(),inserter(goodPlans,goodPlans.begin()),AnswerSetToList());
00532 
00533   query = generatePlanQuery(goal,true);
00534   list<AnswerSet> moreAnswerSets = krQuery(query,maxLength,maxLength,"planQuery.asp",0);
00535 
00536 
00537   list<AnswerSet>::iterator currentFirst = find_if(moreAnswerSets.begin(),moreAnswerSets.end(),PlanLongerThan(moreAnswerSets.begin()->maxTimeStep()));
00538 
00539   set< list<AspFluentRef>, LexComparator > badPlans;
00540   //this object remembers the set of bad plans, cannot be created inside the loop
00541 
00542   IsNotLocallyOptimal isNotLocallyOptimal(&goodPlans, &badPlans,allActions,shortestLength,true);
00543 
00544   list<AnswerSetRef> goodPointers(firstAnswerSets.begin(),firstAnswerSets.end());
00545   while (currentFirst != moreAnswerSets.end()) {
00546 
00547     //process the plans in groups of increasing length
00548 
00549     list<AnswerSet>::iterator currentLast = find_if(currentFirst,moreAnswerSets.end(),PlanLongerThan(currentFirst->maxTimeStep()));
00550 
00551     size_t size_pre_copy = goodPointers.size();
00552 
00553     remove_copy_if(currentFirst,currentLast,back_inserter(goodPointers),isNotLocallyOptimal);
00554 
00555     list<AnswerSetRef>::iterator from = goodPointers.begin();
00556     advance(from,size_pre_copy);
00557     transform(from, goodPointers.end(),inserter(goodPlans,goodPlans.begin()),AnswerSetToList());
00558 
00559     currentFirst = currentLast;
00560   }
00561 
00562   vector<AnswerSet> finalVector(goodPointers.begin(),goodPointers.end());
00563 
00564   cout << "  ---  good plans ---" << endl;
00565   vector< AnswerSet>::const_iterator printIt = finalVector.begin();
00566   for (; printIt != finalVector.end(); ++printIt) {
00567     copy(printIt->getFluents().begin(),printIt->getFluents().end(),ostream_iterator<string>(cout, " "));
00568     cout << endl;
00569   }
00570   cout << " ---- " << endl;
00571 
00572   return finalVector;
00573 
00574 
00575 }
00576 
00577 
00578 bool Clingo::isPlanValid(const AnswerSet& plan, const std::vector<actasp::AspRule>& goal)  const throw() {
00579 
00580 
00581   string planQuery = generatePlanQuery(goal);
00582 
00583   stringstream monitorQuery(planQuery, ios_base::app | ios_base::out);
00584 
00585   const AnswerSet::FluentSet &allActions = plan.getFluents();
00586   AnswerSet::FluentSet::const_iterator actionIt = allActions.begin();
00587 
00588   for (int i=0; actionIt != allActions.end(); ++actionIt, ++i)
00589     monitorQuery << actionIt->toString(i) << "." << endl;
00590 
00591   return !(krQuery(monitorQuery.str(),plan.getFluents().size(),plan.getFluents().size(),"monitorQuery.asp").empty());
00592 }
00593 
00594 AnswerSet Clingo::currentStateQuery(const std::vector<actasp::AspRule>& query) const throw() {
00595 
00596   list<AnswerSet> sets = krQuery(aspString(query,0),0,0,"stateQuery.asp");
00597 
00598   return (sets.empty())? AnswerSet() : *(sets.begin());
00599 }
00600 
00601 static AspRule fluent2Rule(const AspFluent& fluent) {
00602   AspRule rule;
00603   rule.head.push_back(fluent);
00604   return rule;
00605 }
00606 
00607 bool Clingo::updateFluents(const std::vector<actasp::AspFluent> &observations) throw() {
00608 
00609   //copy the observations in the heads of rules
00610   vector<AspRule> obsRules;
00611   obsRules.reserve(observations.size());
00612   transform(observations.begin(),observations.end(),back_inserter(obsRules),fluent2Rule);
00613   //add the rule for the noop action
00614 
00615   stringstream queryStream(aspString(obsRules,1), ios_base::app | ios_base::out);
00616 
00617   queryStream << "noop(0)." << endl;
00618   queryStream << "#hide noop/1." << endl;
00619 
00620   list<AnswerSet> currentState = krQuery(queryStream.str(),1,1,"observationQuery.asp");
00621 
00622   if (currentState.empty())
00623     return false; //the observations are incompatible with the current state and are discarded
00624 
00625   vector<AspRule> newStateRules;
00626   //iclingo generates all answer sets up to the last iteration, so we need the last one here
00627   set<AspFluent> newStateFluents = currentState.rbegin()->getFluentsAtTime(1);
00628   newStateRules.reserve(newStateFluents.size());
00629   transform(newStateFluents.begin(),newStateFluents.end(),back_inserter(newStateRules),fluent2Rule);
00630 
00631   //copy the current state in a file
00632   ofstream currentFile((CURRENT_FILE_HOME + CURRENT_STATE_FILE).c_str());
00633 
00634   currentFile << aspString(newStateRules,0);
00635   currentFile.close();
00636 
00637   return true;
00638 }
00639 
00640 
00641 //this is almost brutally copied from krquery
00642 std::list< std::list<AspAtom> > Clingo::query(const std::string &queryString, unsigned int initialTimeStep,
00643                                    unsigned int finalTimeStep) const throw() {
00644 
00645   //this depends on our way of representing stuff.
00646   //iclingo starts from 1, while we needed the initial state and first action to be at time step 0
00647   initialTimeStep++;
00648   finalTimeStep++;
00649 
00650   string queryPath = queryDir + "generic_query.asp";
00651 
00652   ofstream queryFile(queryPath.c_str());
00653   queryFile << queryString << endl;
00654   queryFile.close();
00655 
00656   stringstream commandLine;
00657 
00658   const string outputFilePath = queryDir + "query_output.txt";
00659 
00660   if (max_time > 0) {
00661     commandLine << "timeout " << max_time << " ";
00662   }
00663 
00664   stringstream iterations;
00665   iterations << "--imin=" << initialTimeStep << " --imax=" << finalTimeStep;
00666 
00667 
00668   commandLine << "iclingo " << iterations.str() << " " << domainDir <<  "*.asp " << " " << (CURRENT_FILE_HOME + CURRENT_STATE_FILE) << " " << queryPath <<  " > " << outputFilePath << " 0";
00669 
00670 
00671   if (!system(commandLine.str().c_str())) {
00672     //maybe do something here, or just kill the warning about the return value not being used.
00673   }
00674 
00675   ifstream file(outputFilePath.c_str());
00676 
00677   list<list <AspAtom> > allSets;
00678   bool answerFound = false;
00679 
00680   string line;
00681   while(file) {
00682 
00683     getline(file,line);
00684 
00685     if(answerFound && line == "UNSATISFIABLE")
00686       return list<list <AspAtom> >();
00687 
00688     if(line.find("Answer") != string::npos) {
00689       getline(file,line);
00690         try {
00691             stringstream predicateLine(line);
00692 
00693             list<AspAtom> atoms;
00694 
00695             //split the line based on spaces
00696             copy(istream_iterator<string>(predicateLine),
00697                   istream_iterator<string>(),
00698                   back_inserter(atoms));
00699 
00700           allSets.push_back(atoms);
00701         } catch (std::invalid_argument& arg) {
00702           //swollow it and skip this answer set.
00703         }
00704     }
00705   }
00706 
00707  return allSets;
00708 
00709 }
00710 
00711 void Clingo::reset() throw() {
00712   ofstream current((CURRENT_FILE_HOME + CURRENT_STATE_FILE).c_str());
00713   current << "";
00714   current.close();
00715 }
00716 
00717 }


bwi_kr_execution
Author(s): Matteo Leonetti, Piyush Khandelwal
autogenerated on Fri Aug 28 2015 10:14:46