.. _program_listing_file_src_VALfiles_Plan.h: Program Listing for File Plan.h =============================== |exhale_lsh| :ref:`Return to documentation for file ` (``src/VALfiles/Plan.h``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp /************************************************************************ * Copyright 2008, Strathclyde Planning Group, * Department of Computer and Information Sciences, * University of Strathclyde, Glasgow, UK * http://planning.cis.strath.ac.uk/ * * Maria Fox, Richard Howey and Derek Long - VAL * Stephen Cresswell - PDDL Parser * * This file is part of VAL, the PDDL validator. * * VAL is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * VAL is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with VAL. If not, see . * ************************************************************************/ /*----------------------------------------------------------------------------- VAL - The Automatic Plan Validator for PDDL+ $Date: 2010-07-15 15:13:44 $ $Revision: 1.4 $ Maria Fox, Richard Howey and Derek Long - PDDL+ and VAL Stephen Cresswell - PDDL Parser maria.fox@cis.strath.ac.uk derek.long@cis.strath.ac.uk stephen.cresswell@cis.strath.ac.uk richard.howey@cis.strath.ac.uk By releasing this code we imply no warranty as to its reliability and its use is entirely at your own risk. Strathclyde Planning Group http://planning.cis.strath.ac.uk ----------------------------------------------------------------------------*/ #include #include #include #include #include #include "ptree.h" #include "Exceptions.h" #include "main.h" #include "Ownership.h" #include "Polynomial.h" #include "State.h" #ifndef __PLAN #define __PLAN // Use the following switch if your compiler/STL doesn't use std. // #define NO_STD_NAMESPACE //#define vector std::vector namespace VAL { class State; class Proposition; class FuncExp; class FuncExpFactory; class Action; class InvariantAction; class CtsEffectAction; class CondCommunicationAction; class ExecutionContext; class Update { private: const FuncExp * fe; assign_op aop; FEScalar value; public: Update(const FuncExp * f,assign_op ao,FEScalar v) : fe(f), aop(ao), value(v) {}; void update(State * s) const; void updateChange(State * s) const; }; class EffectsRecord { private: vector adds; vector dels; vector updates; public: void pushAdd(const SimpleProposition * p) { adds.push_back(p); }; void pushDel(const SimpleProposition * p) { dels.push_back(p); }; void addFEffect(const FuncExp * fe,assign_op aop,FEScalar value) { updates.push_back(Update(fe,aop,value)); }; void enact(State * s) const; }; class Happening { private: Validator * vld; double time; vector actions; Happening(Validator * v) : vld(v), time(0.0), actions(), eventHappening(false),realHappening(false), afterPlan(false) {}; bool eventHappening; bool realHappening; bool afterPlan; public: friend class ExecutionContext; friend class ActiveCtsEffects; private: template struct select2nd { typename X::second_type operator()(X p){return p.second;}; }; public: Happening(Validator * v,const vector > & as,double timeEndPlan); Happening(Validator * v,double timeToExecute,const vector > & as); Happening(Validator * v,vector acts,bool event = false); //for creating event happenings Happening(Validator * v, vector acts,double t,bool event =false); ~Happening(); void adjustContext(ExecutionContext &) const; void adjustContextInvariants(ExecutionContext &) const; //invariant interval is ( , ] or ( , ) ? void adjustActiveCtsEffects(ActiveCtsEffects &) const; double getTime() const {return time;}; int getNoActions() const {return actions.size();}; const vector * getActions() const {return &actions;}; void clearActions() {actions.clear();}; bool canHappen(const State * s) const; bool applyTo(State * s) const; void write(ostream & o) const; bool isAfterPlan() const {return afterPlan;}; bool isRegularHappening() const {return realHappening;}; void inject(Action * a) {actions.push_back(a);}; }; struct ExecutionContext { Happening invariants; // Also includes the temporal conditional effects monitors. ExecutionContext(Validator * v); void addInvariant(const InvariantAction * a); void removeInvariant(const InvariantAction * a); void addCondAction(const CondCommunicationAction * ca); bool removeCondAction(const CondCommunicationAction * ca); void setTime(double t); void setActiveCtsEffects(ActiveCtsEffects * ace); const Happening * getInvariants() const {return &invariants;}; bool hasInvariants() const; ~ExecutionContext(); }; typedef pair, const Environment *> ExprnPair; //bool is true if increasing struct ActiveFE { const FuncExp * fe; vector parentFEs; //an active FE that this FE depends on, there may be 0 or many int colour; //for topological sort vector exprns; const CtsFunction * ctsFtn; //cts fn defining FEs values on interval it is changing on FEScalar evaluate(double time) const; //time since start of active interval; bool isLinear() const; ActiveFE(const FuncExp * f) : fe(f),ctsFtn(0) {}; void addParentFE(const ActiveFE * a); void removeParentFE(const ActiveFE * a); void addParentFEs(const ActiveCtsEffects * ace,const expression * e,const Environment * bs); bool appearsInEprsn(const ActiveCtsEffects * ace,const expression * e,const Environment * bs) const; bool canResolveToExp(const map activeFEs,Validator *) const; ~ActiveFE(); }; bool isConstLinearChangeExpr(const ExprnPair & exp,const map activeFEs,Validator * vld); bool isConstant(const expression * exp,const Environment * env,const map activeFEs,Validator * vld); const expression* getRateExpression(const expression* aExpression); //the following class contains all the active cts effects that are to be updated before each regular happening at //the same point in time struct ActiveCtsEffects { Happening ctsEffects; // contains all the active cts effects, length of time is given from the last happening map activeFEs; // contains all the active FEs and their dependencies on other FEs, also how to update the FEs bool ctsEffectsProcessed; mutable Happening ctsUpdateHappening; Validator * vld; double localUpdateTime; //time since last happening double eventTime; ActiveCtsEffects(Validator * v); void addCtsEffect(const CtsEffectAction * a); void removeCtsEffect(const CtsEffectAction * a); void setTime(double t); void setEventTime(double t) {eventTime =t;}; double getEventTime() const {return eventTime;}; void setLocalUpdateTime(double ht); void addActiveFEs(bool reCalc = false); void addActiveFE(assignment * e,const Environment & bs); void buildAFECtsFtns(); void visitActiveFE(ActiveFE * afe,vector & topSAFEs); //for topological sort const Polynomial * buildPoly(const ActiveFE * afe); const CtsFunction * buildExp(const ActiveFE * afe); const CtsFunction * buildNumericalSoln(const ActiveFE * afe); const Happening * getCtsEffects() const {return &ctsEffects;}; const Happening * getCtsEffectUpdate() const; bool hasCtsEffects() const; void clearCtsEffects(); bool areCtsEffectsLinear() const; bool isFEactive(const FuncExp * fe) const; ~ActiveCtsEffects(); }; struct after { double time; double tolerance; after(double t,double tol) : time(t), tolerance(tol) {}; bool operator()(const pair p) const { return p.first > time + tolerance/10; }; }; struct sameTime { double time; sameTime(double t) : time(t) {}; bool operator()(const pair p) const { return p.first > time; }; }; class Plan { public: typedef vector > timedActionSeq; // Using a list allows us to add Happenings to the end of the plan without // invalidating the iterators. typedef list HappeningSeq; private: HappeningSeq happenings; Validator * vld; double timeToProduce; struct planBuilder { Validator * vld; timedActionSeq & tas; const operator_list * ops; double defaultTime; timedActionSeq extras; planBuilder(Validator * v,timedActionSeq & ps, const operator_list * os) : vld(v), tas(ps), ops(os), defaultTime(1), extras() {}; void handleDurativeAction(const durative_action *,const const_symbol_list *,double,double,const plan_step * ps); void operator()(const plan_step * ps); }; public: Validator* getValidator() const {return vld;}; HappeningSeq::const_iterator getFirstHappening() const {return happenings.begin();}; HappeningSeq::const_iterator getEndHappening() const {return happenings.end();}; Plan(Validator* v,const operator_list * ops,const plan * p); ~Plan() { for(HappeningSeq::const_iterator i = happenings.begin(); i != happenings.end();++i) { delete (*i); }; }; Happening * lastHappening() const { if(happenings.size()==0) return 0; return happenings.back(); }; class const_iterator; friend class const_iterator; class const_iterator : public #ifndef OLDCOMPILER std::iterator #endif #ifdef OLDCOMPILER std::forward_iterator #endif { private: int pos; const Plan * myPlan; double currenttime; // currenttime will always be the time of the state prevailing. //(Last distinct time! May be different type of happening happenings with same time) ExecutionContext ec; // Records invariant checks. ActiveCtsEffects ace; //Records all the active cts effects enum HappeningType {INVARIANT, CTS, REGULAR, END }; //The different types of happening to be executed in that order //at each regular happening timestamp if invariants and cts effects exist HappeningType executeHappening; HappeningSeq::const_iterator i; // The iterator always points at the next happening to be considered // (if there is one), ignoring possible invariant checks. public: const_iterator(const Plan * p) : pos(0), myPlan(p), currenttime(0.0), ec(p->getValidator()), ace(p->getValidator()), executeHappening(REGULAR), i(p->getFirstHappening()) { if(i != p->getEndHappening()) { (*i)->adjustContext(ec); (*i)->adjustActiveCtsEffects(ace); }; }; int operator-(const const_iterator & x) { return pos - x.pos; }; double getTime() { if(executeHappening == REGULAR) return (*i)->getTime(); else { HappeningSeq::const_iterator j = i; ++j; return (*j)->getTime(); }; }; void deleteActiveFEs() { for(map::iterator j = ace.activeFEs.begin(); j != ace.activeFEs.end(); ++j) { //cout << " deleting"<< *(j->second->fe) <<"\n"; delete j->second; }; ace.activeFEs.clear(); }; bool isRegular() const { return (executeHappening == REGULAR); }; ActiveCtsEffects * getActiveCtsEffects() {return &ace;}; ExecutionContext * getExecutionContext() {return &ec;}; const ActiveCtsEffects * getActiveCtsEffects() const {return &ace;}; const ExecutionContext * getExecutionContext() const {return &ec;}; bool isInvariant() const { return (executeHappening == INVARIANT); }; void toEnd() { i = myPlan->getEndHappening(); currenttime = 0; executeHappening = END; }; bool operator ==(const const_iterator & c) const { return currenttime == c.currenttime && executeHappening == c.executeHappening; }; bool operator !=(const const_iterator & c) const { return !(operator==(c)); }; const Happening * operator*() const { switch(executeHappening) { case INVARIANT: return ec.getInvariants(); break; case CTS: return ace.getCtsEffectUpdate(); break; case REGULAR: if(i != myPlan->getEndHappening()) return *i; default: break; } return 0; }; const_iterator & operator++() { HappeningSeq::const_iterator j = i; ++j; if((j) == myPlan->getEndHappening()) { ++i; ++pos; currenttime = 0; executeHappening = END; //set value so we know the plan has finished return *this; }; currenttime = (*(j))->getTime();// //value of executeHappening represents the last type of happening to be executed switch(executeHappening) { case INVARIANT: if(ace.hasCtsEffects()) { handleCtsHappening(); return *this; }; executeHappening = REGULAR; break; case CTS: executeHappening = REGULAR; break; case REGULAR: if(ec.hasInvariants()) { handleInvHappening(); (*i)->adjustContextInvariants(ec); (*(j))->adjustContextInvariants(ec); return *this; } else if(ace.hasCtsEffects()) { handleCtsHappening(); return *this; }; default: break; };//end of happening type switch //deal with regular happenings here ++i; (*i)->adjustContext(ec); (*i)->adjustActiveCtsEffects(ace); return *this; }; void handleInvHappening() { executeHappening = INVARIANT; ec.setActiveCtsEffects(&ace); //cout << "inv current time = "< (*i)->getTime()) ace.setLocalUpdateTime(currenttime - ace.getEventTime()); else ace.setLocalUpdateTime(currenttime - (*i)->getTime()); }; void handleCtsHappening() { executeHappening = CTS; ace.setTime(currenttime); //same time as next regular happening ace.setLocalUpdateTime(currenttime - (*i)->getTime()); //set value of LocalUpdateTime - time since last regular happening if(ace.getEventTime() > (*i)->getTime()) ace.setLocalUpdateTime(currenttime - ace.getEventTime()); else ace.setLocalUpdateTime(currenttime - (*i)->getTime()); //set value of LocalUpdateTime - time since last regular happening }; const_iterator operator++(int) { const_iterator ii = *this; ++(*this); return ii; }; }; const_iterator begin() const { return const_iterator(this); }; const_iterator end() const { const_iterator c(this); c.toEnd(); return c; }; void display() const; int length() const; double getTime() const {return timeToProduce;}; double timeOf(const Action * a) const; void show(ostream & o) const; void addHappening(Happening * h); }; ostream & operator <<(ostream & o,const Plan & p); ostream & operator <<(ostream & o,const Happening * h); inline ostream & operator <<(ostream & o,const Happening & h) { h.write(o); return o; }; void insert_effects(effect_lists * el,effect_lists * more); Polynomial getPoly(const expression * e,const ActiveCtsEffects * ace,const Environment & bs,CoScalar endInt = 0); Polynomial getPoly(const expression * e,const ActiveCtsEffects * ace,const Environment * bs,CoScalar endInt = 0); Polynomial getPoly(const expression * e,bool inc,const ActiveCtsEffects * ace,const Environment & bs,CoScalar endInt = 0); Polynomial getPoly(const expression * e,bool inc,const ActiveCtsEffects * ace,const Environment * bs,CoScalar endInt = 0); }; #endif