Program Listing for File Action.h

Return to documentation for file (src/VALfiles/Action.h)

/************************************************************************
 * 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 <http://www.gnu.org/licenses/>.
 *
 ************************************************************************/

/*-----------------------------------------------------------------------------
  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 "ptree.h"
#include "Proposition.h"
#include "main.h"
#include <iostream>
#include <algorithm>
#include <iterator>
#include <string>
#include <set>

using std::ostream_iterator;
using std::set;

#ifndef __ACTION
#define __ACTION

namespace VAL {

class State;
class Ownership;
class EffectsRecord;
class Validator;
class ExecutionContext;
class ActiveCtsEffects;
class StartAction;
class EndAction;

struct safeaction : public action {

    safeaction(operator_symbol* nm,
        var_symbol_list* ps,
        goal* pre,
        effect_lists* effs,
        var_symbol_table* st) : action(nm,ps,pre,effs,st) {};

    ~safeaction()
    {
        conj_goal * cg = dynamic_cast<conj_goal*>(precondition);
        if(cg) const_cast<goal_list *>(cg->getGoals())->clear();
                        // Mustn't delete the preconditions.
        symtab = 0;     // Mustn't delete the symbol table either.
        parameters = 0; // Or the parameters.
                        // Finally, we don't own the effects, so mustn't
                        // clobber those either.
        effects->add_effects.clear();
        effects->del_effects.clear();
        effects->forall_effects.clear();
        effects->cond_effects.clear();
        effects->assign_effects.clear();
    };
};


class Action {
protected:
        const operator_ * act;
        Environment bindings;

        bool timedInitialLiteral;

        Validator * vld;

        const Proposition * pre;
    string actionName;
    const plan_step * planStep;

    bool handleEffects(Ownership & o,EffectsRecord & e,
                            const State * s,const effect_lists * effs,const Environment & env,bool markPreCons) const;
    bool handleEffects(Ownership & o,EffectsRecord & e,
                            const State * s,const effect_lists * effs,bool markPreCons) const;

        struct ActionParametersOutput {

            const Environment & bindings;

            ActionParametersOutput(const Environment & bs) : bindings(bs) {};
            string operator()(const var_symbol * v) const
            {
                return bindings.find(v)->second->getName();
            };
        };

    friend class FAEhandler;
    friend class ActiveCtsEffects;

public:
    Action(Validator * v,const operator_ * a,const const_symbol_list* bs);
    Action(Validator * v,const operator_ * a,Environment * bs);
    Action(Validator * v,const operator_ * a,const vector<const_symbol *> & vs);
  Action(Validator * v,const operator_ * a,const const_symbol_list* bs,const plan_step * ps);

    virtual ~Action();

    const effect_lists * getEffects() const {return act->effects;};
    const Environment & getBindings() const {return bindings;};
    const operator_ * getAction() const {return act;};
  const plan_step * getPlanStep() const {return planStep;};
    const Proposition * getPrecondition() const {return pre;};
    string getName() const;
    string getName0() const;
    virtual void displayDurationAdvice(const State * s) const {};
    virtual void displayEventInfomation() const;
    virtual bool confirmPrecondition(const State * s) const;
   virtual void addErrorRecord(double t,const State * s) const;
    virtual void markOwnedPreconditions(Ownership & o) const;
    virtual bool constructEffects(Ownership & o,EffectsRecord & e,const State * s,bool markPreCons) const;
    virtual void adjustContext(ExecutionContext &) const;
    virtual void adjustContextInvariants(ExecutionContext &) const;
    virtual void adjustActiveCtsEffects(ActiveCtsEffects &) const;
    virtual void addTriggeredEvents(vector<const Action *> & triggeredEvents,vector<const Action *> & oldTriggeredEvents, vector<const StartAction *> & triggeredStartProcesses, vector<const EndAction *> & triggeredEndProcesses) const;
    virtual void write(ostream & o) const
    {
        o << getName();
    };

    bool isRealAction() const {return !timedInitialLiteral;};
    bool isRegAction() const {return true;};

    bool operator==(const plan_step & ps) const;
};

class InvariantAction : public Action {
private:
    ActiveCtsEffects * ace;
    StartAction * start;
    mutable bool rhsIntervalOpen;//only open for last interval that invariant is checked on
public:
    InvariantAction(Validator * v,StartAction * sa,const action * a,const const_symbol_list* bs,const plan_step * ps = 0) :
        Action(v,a,bs,ps), start(sa), rhsIntervalOpen(false)
    {};

    ~InvariantAction();
    bool confirmPrecondition(const State * s) const;
   void addErrorRecord(double t,const State * s) const;
    void setActiveCtsEffects(ActiveCtsEffects * a) {ace = a;};
    void setRhsIntervalOpen(bool rhs) const {rhsIntervalOpen = rhs;};
    bool isRealAction() const {return false;};
    bool isRegAction() const {return false;};

    void write(ostream & o) const
    {
        if(LaTeX)
        {
            o << "\\actioninv{";
            Action::write(o);
            o << "}";
        }
        else
        {
            o << "Invariant for ";
            Action::write(o);
        };
    };

    const Action * partner() const;
};







class CondCommunicationAction : public Action {
private:
    mutable bool status;
    ActiveCtsEffects * ace;
    mutable bool rhsIntervalOpen;
    StartAction * start;

    conj_goal * gls;
    const Proposition * initPre;
    conj_goal * gli;
    const Proposition * invPre;
    goal * gle;         // Will actually be a conj_goal *, but it's not important.

    effect_lists * els;
    effect_lists * ele;

    Environment * vars;

public:
    CondCommunicationAction(Validator * v,const durative_action * a,const const_symbol_list * bs,
        goal_list * gs,goal_list * gi,goal_list * ge,
        effect_lists * es,effect_lists * el);
    CondCommunicationAction(Validator * v,const durative_action * a,const const_symbol_list * bs,
        goal_list * gs,goal_list * gi,goal_list * ge,
        effect_lists * es,effect_lists * el,Environment * vs);
    ~CondCommunicationAction();

    void write(ostream & o) const

    {

        if(LaTeX)
        {
            o << "\\condeffmon{";
            Action::write(o);
            o << "}";
        }
        else
        {
            Action::write(o);
            o << " - conditional effect monitor";
        };

    };

    void markInitialPreconditions(Ownership & o) const;


    void markOwnedPreconditions(Ownership & o) const;
    bool confirmPrecondition(const State * s) const;
    bool constructEffects(Ownership & o,EffectsRecord & e,const State * s,bool markPreCons) const;
    void setActiveCtsEffects(ActiveCtsEffects * a) {ace = a;};
    void setRhsIntervalOpen(bool rhs) const {rhsIntervalOpen = rhs;};
    bool confirmInitialPrecondition(const State * s) const;
    bool constructFinalEffects(Ownership & o,EffectsRecord & e,const State * s) const;
    bool isActive() const {return status;};
   bool isRealAction() const {return false;};
    bool isRegAction() const {return false;};
    const Action * partner() const;
};

void buildForAllCondActions(Validator * vld,const durative_action * da,
    const const_symbol_list * params,goal_list * gls,
        goal_list * gli,goal_list * gle,effect_lists * locels,
        effect_lists * locele,const var_symbol_list * vars,
        var_symbol_list::const_iterator i,
        vector<const CondCommunicationAction *> & condActions,
        Environment * env);

class CtsEffectAction : public Action {
private:
    ActiveCtsEffects * ace;
    StartAction * start;
public:
    CtsEffectAction(Validator * v,const action * a,const const_symbol_list* bs,const vector<const CondCommunicationAction*> & cas) :
        Action(v,a,bs), condActions(cas)
    {};

    ~CtsEffectAction();

    const vector<const CondCommunicationAction *> condActions;

    bool constructEffects(Ownership & o,EffectsRecord & e,const State * s,bool markPreCons) const;
    void setHasht(double ht);
    void setActiveCtsEffects(ActiveCtsEffects * a) {ace = a;};
    void displayCtsFtns() const;
    bool isRealAction() const {return false;};
    bool isRegAction() const {return false;};

    void write(ostream & o) const
    {

        if(LaTeX)
        {

            o << "\\updatectspne";
        }
        else
            o << "Update of continuously changing Primitive Numerical Expressions";
    };
    const Action * partner() const;
};

class DurativeActionElement : public Action {
protected:
    double duration;
    const goal_list * durs;

    const InvariantAction * invariant;
    const CtsEffectAction * ctsEffects;

    const vector<const CondCommunicationAction *> condActions;

public:
    DurativeActionElement(Validator * v,const action * a,const const_symbol_list* bs,
                    double d,const goal_list * ds,const InvariantAction * inv,
                            const CtsEffectAction * ctsEff,
                    const vector<const CondCommunicationAction *> & cas,const plan_step * ps = 0) :
        Action(v,a,bs,ps),
        duration(d), durs(ds), invariant(inv), ctsEffects(ctsEff), condActions(cas)
    {
        bindings.duration = duration;
    };
    virtual ~DurativeActionElement();

    void markOwnedPreconditions(Ownership &) const;
    bool confirmPrecondition(const State * s) const;
    double getDuration() const {return duration;};
    bool isRegAction() const {return true;};

};

class EndAction;

class StartAction : public DurativeActionElement {
private:
    mutable EndAction * otherEnd;
public:
    friend class EndAction;

    StartAction(Validator * v,const action * a,const const_symbol_list* bs,
                    const conj_goal * inv, effect_lists * elc, double d,const goal_list * ds,
                    const vector<const CondCommunicationAction*> & cas,
                    const vector<const CondCommunicationAction*> & ccas,const plan_step * ps = 0) :
           DurativeActionElement(v,
                                 a,
                                 bs,
                                 d,
                                 ds,
                                 (inv->getGoals()->empty())?0:  //do not create invariant action if no invariants to check!
                                 new InvariantAction(v,this,
                                                     new safeaction(a->name,
                                                                    a->parameters,
                                                                    const_cast<conj_goal *>(inv),
                                                                    new effect_lists(),
                                                                    a->symtab),
                                                     bs,ps),
                                (elc->assign_effects.empty() && elc->forall_effects.empty() && ccas.empty() )?0: //similarly do not create cts effect action if no cts effects!
                                new CtsEffectAction(v,
                                                    new safeaction(a->name,
                                                                   a->parameters,
                                                                   new conj_goal(new goal_list()), //no preconditions
                                                                   elc,
                                                                   a->symtab),
                                                    bs,
                                                    ccas),
                                cas,ps)
    {
   if(inv->getGoals()->empty()) delete inv;
   if(elc->assign_effects.empty() && elc->forall_effects.empty() && ccas.empty()) delete elc;
  };


    ~StartAction()
    {
        delete invariant;
        delete ctsEffects;
    };

    void adjustContext(ExecutionContext &) const;
    void adjustContextInvariants(ExecutionContext &) const;
    void adjustActiveCtsEffects(ActiveCtsEffects &) const;
    void markOwnedPreconditions(Ownership & o) const;
    bool confirmPrecondition(const State *) const;
    void displayDurationAdvice(const State * s) const;
    void addTriggeredEvents(vector<const Action *> & triggeredEvents,vector<const Action *> & oldTriggeredEvents, vector<const StartAction *> & triggeredStartProcesses, vector<const EndAction *> & triggeredEndProcesses) const;
  void displayEventInfomation() const;
    void write(ostream & o) const
    {

        if(LaTeX)
        {
            o << "\\actionstart{";
            Action::write(o);
            o << "}";
        }
        else
        {
            Action::write(o);
            o << " - start";
        };
    };
    const Action * partner() const;
    const Action * starter() const {return this;};
};

class EndAction : public DurativeActionElement {
private:
    const StartAction * otherEnd;
public:
    EndAction(Validator * v,const action * a,const const_symbol_list* bs,
                const StartAction * sa,double d, const goal_list * ds,const plan_step * ps = 0) :
        DurativeActionElement(v,a,bs,d,ds,sa->invariant,sa->ctsEffects, sa->condActions,ps),
        otherEnd(sa)
    {
        sa->otherEnd = this;
    };
    ~EndAction()
    {};

    void adjustContext(ExecutionContext &) const;

    void adjustContextInvariants(ExecutionContext &) const;
    void adjustActiveCtsEffects(ActiveCtsEffects &) const;
    bool constructEffects(Ownership & o,EffectsRecord & e,const State * s,bool markPreCons) const;
    const Action * partner() const {return otherEnd;};
    void addTriggeredEvents(vector<const Action *> & triggeredEvents,vector<const Action *> & oldTriggeredEvents,
  vector<const StartAction *> & triggeredStartProcesses, vector<const EndAction *> & triggeredEndProcesses) const;
  void displayEventInfomation() const;
    void write(ostream & o) const
    {
        if(LaTeX)
        {
            o << "\\actionend{";
            Action::write(o);
            o << "}";
        }
        else
        {
            Action::write(o);
            o << " - end";
        };
    };

};


ostream & operator <<(ostream & o,const Action & a);
ostream & operator << (ostream & o, const Action * const a);

template<typename T>
const Environment buildBindings(const operator_ * a,const T & bs)
{
    Environment bindings;
    typename T::const_iterator j = bs.begin();
    for(var_symbol_list::iterator i = a->parameters->begin();
            i != a->parameters->end();++i,++j)
    {
        bindings[*i] = *j;
    };
    return bindings;
};


};

#endif