Program Listing for File graphconstruct.h
↰ Return to documentation for file (src/VALfiles/misc/graphconstruct.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/>.
*
************************************************************************/
#ifndef __GRAPHCONSTRUCT
#define __GRAPHCONSTRUCT
#include "instantiation.h"
#include <vector>
#include <iostream>
using std::vector;
using std::ostream;
namespace VAL {
class State;
class Validator;
};
namespace Inst {
class SpikeEntry {
private:
int layerEntered;
public:
void addAt(int l) {layerEntered = l;};
virtual ~SpikeEntry(){};
virtual void write(ostream & o) const {};
int getWhen() const {return layerEntered;};
virtual void lateEntry() {};
};
inline ostream & operator<<(ostream & o,const SpikeEntry & s)
{
s.write(o);
return o;
};
template<typename T>
class Spike {
private:
vector<T *> spk;
vector<int> levelheads;
public:
typedef typename vector<T *>::iterator SpikeIterator;
int size() const {return spk.size();};
Spike(){};
T * addEntry(T * spe){
spk.push_back(spe);
spe->addAt(levelheads.size());
return spe;
}
void finishedLevel(){
levelheads.push_back(spk.size());
}
int numLevels() const {
return levelheads.size();
};
void write(ostream & o) const
{
for(int i = 0;i < numLevels();++i)
{
o << "Level " << i << " (";
for(int j = 0;j < levelheads[i];++j)
{
spk[j]->write(o);
o << ",";
};
o << ")\n\n";
};
};
int & lastLevelHead()
{
return levelheads[numLevels()-1];
};
const int & lastLevelHead() const
{
return levelheads[numLevels()-1];
};
void insertAbsentee(T * t)
{
// This inserts t at the previous level, where it was meant to have been added earlier.
cout << "Adding absentee to level " << lastLevelHead() << "\n";
int idx = lastLevelHead();
spk.push_back(spk[idx]);
spk[idx] = t;
t->lateEntry();
++lastLevelHead();
};
template<typename U>
T * find(const U * u) const
{
int j = 0;
for(typename vector<T *>::const_iterator i = spk.begin();j != lastLevelHead();++i,++j)
{
if((*i)->represents(u))
{
return *i;
};
};
return 0;
};
template<typename U>
T * findInAll(const U * u) const
{
for(typename vector<T *>::const_iterator i = spk.begin();i != spk.end();++i)
{
if((*i)->represents(u))
{
return *i;
};
};
return 0;
};
SpikeIterator begin() {return spk.begin();};
SpikeIterator end() {return spk.end();};
// This is the address of the first element *not* in level i
SpikeIterator toLevel(int i) {return spk.begin()+levelheads[i];};
};
class ActEntry;
class FluentEntry;
class PlanGraph;
class PropEntry : public SpikeEntry {
private:
static int counter;
const int myID;
Literal * theprop;
bool initiallyTrue;
vector<ActEntry *> achievers;
vector<ActEntry *> deleters;
public:
PropEntry(Literal * p) : myID(counter++), theprop(p), initiallyTrue(true) {};
int getID() const {return myID;};
void write(ostream & o) const
{
if(!initiallyTrue) o << "*";
theprop->write(o);
};
bool represents(const Literal * lit) const {return theprop==lit;};
void setInitiallyFalse() {initiallyTrue = false;};
void addAchievedBy(ActEntry * ae)
{
achievers.push_back(ae);
};
void addDeletedBy(ActEntry * ae)
{
deleters.push_back(ae);
};
bool gotAchievers() const
{
return !achievers.empty() || initiallyTrue;
};
bool gotDeleters() const
{
return !deleters.empty() || !initiallyTrue;
};
void lateEntry()
{
initiallyTrue = false;
};
};
enum ActType {START,END,INV,ATOMIC};
class DurationConstraint;
class DurationHolder {
private:
map<string,vector<int> > relevantArgs;
map<string,DurationConstraint *> dursFor;
public:
void readDurations(const string & nm);
DurationConstraint * lookUp(const string & nm,instantiatedOp * op);
};
class ActEntry : public SpikeEntry {
private:
instantiatedOp * theact;
vector<PropEntry *> achieves;
vector<PropEntry *> deletes;
vector<FluentEntry *> updates;
vector<PropEntry *> supports;
vector<PropEntry *> negSupports;
// This flag is used for identifying those actions that must be repeatedly applied
// because they have relative metric effects.
bool iterating;
// If this is part of a durative action structure we want to know about it
ActType atype;
DurationConstraint * dur;
static DurationHolder dursFor;
public:
static void readDurations(const string & nm)
{
dursFor.readDurations(nm);
};
bool isActivated(const vector<bool> & actives) const;
bool isActivated(VAL::Validator * v,const VAL::State *) const;
bool isRelevant(VAL::Validator * v,const VAL::State *) const;
ActEntry(instantiatedOp * io);
instantiatedOp * getIO() {return theact;};
bool isEvent() const
{
const VAL::event * e = dynamic_cast<const VAL::event *>(theact->forOp());
return (e != 0);
};
bool represents(const instantiatedOp * op) const {return op==theact;};
void addUpdates(FluentEntry * fe)
{
updates.push_back(fe);
};
void addAchieves(PropEntry * pe)
{
achieves.push_back(pe);
};
void addDeletes(PropEntry * pe)
{
deletes.push_back(pe);
};
void addSupportedBy(PropEntry * pe)
{
supports.push_back(pe);
};
void addSupportedByNeg(PropEntry * pe)
{
negSupports.push_back(pe);
};
void write(ostream & o) const;
bool isIterating() const {return iterating;};
};
class BoundedValue;
class Constraint {
protected:
BoundedValue * bval;
public:
Constraint(BoundedValue * b) : bval(b) {};
virtual ~Constraint();
virtual void write(ostream & o) const;
};
class DurationConstraint : public Constraint {
private:
ActEntry * start;
ActEntry * inv;
ActEntry * end;
public:
DurationConstraint(BoundedValue * b) :
Constraint(b), start(0), inv(0), end(0) {};
void setStart(ActEntry * s) {start = s;};
void setEnd(ActEntry * e) {end = e;};
void setInv(ActEntry * i) {inv = i;};
virtual void write(ostream & o) const;
};
class InitialValue : public Constraint {
public:
InitialValue(BoundedValue * b) : Constraint(b) {};
void write(ostream & o) const;
};
class UpdateValue : public Constraint {
private:
ActEntry * updater;
const VAL::expression * exp;
const VAL::assign_op op;
public:
UpdateValue(ActEntry * ae,const VAL::expression * e,const VAL::assign_op o,BoundedValue * b) :
Constraint(b), updater(ae), exp(e), op(o)
{};
void write(ostream & o) const;
};
class BoundedValue {
public:
virtual ~BoundedValue() {};
virtual void write(ostream & ) const {};
virtual BoundedValue * operator+=(const BoundedValue *) = 0;
virtual BoundedValue * operator-=(const BoundedValue *) = 0;
virtual BoundedValue * operator*=(const BoundedValue *) = 0;
virtual BoundedValue * operator/=(const BoundedValue *) = 0;
virtual void negate() {};
virtual bool gotLB() const {return true;};
virtual bool gotUB() const {return true;};
virtual double getLB() const = 0;
virtual double getUB() const = 0;
virtual BoundedValue * accum(const BoundedValue * bv) = 0;
virtual bool contains(double d) const {return false;};
virtual BoundedValue * infUpper() =0;
virtual BoundedValue * infLower() =0;
virtual BoundedValue * copy() const = 0;
};
class BoundedInterval : public BoundedValue {
private:
bool finitelbnd;
double lbnd;
bool finiteubnd;
double ubnd;
public:
BoundedInterval(double l,double u) : finitelbnd(true), lbnd(l),
finiteubnd(true), ubnd(u) {};
BoundedValue * infUpper() {finiteubnd = false; return this;};
BoundedValue * infLower() {finitelbnd = false; return this;};
void negate()
{
bool x = finitelbnd;
finitelbnd = finiteubnd;
finiteubnd = x;
double y = lbnd;
lbnd = -ubnd;
ubnd = -y;
};
BoundedValue * accum(const BoundedValue * bv)
{
if(!finitelbnd || !bv->gotLB())
{
finitelbnd = false;
}
else
{
lbnd = min(lbnd,bv->getLB());
};
if(!finiteubnd || !bv->gotUB())
{
finiteubnd = false;
}
else
{
ubnd = max(ubnd,bv->getUB());
};
return this;
};
void write(ostream & o) const
{
if(finitelbnd)
{
o << "[" << lbnd << ",";
}
else
{
o << "(-INF,";
};
if(finiteubnd)
{
o << ubnd << "]";
}
else
{
o << "INF)";
};
};
virtual BoundedValue * operator+=(const BoundedValue *);
virtual BoundedValue * operator-=(const BoundedValue *);
virtual BoundedValue * operator*=(const BoundedValue *);
virtual BoundedValue * operator/=(const BoundedValue *);
bool gotLB() const {return finitelbnd;};
bool gotUB() const {return finiteubnd;};
double getLB() const {return lbnd;};
double getUB() const {return ubnd;};
bool contains(double d) const
{
return (!finitelbnd || lbnd <= d) && (!finiteubnd || ubnd >= d);
};
BoundedInterval * copy() const
{
return new BoundedInterval(*this);
};
};
class PointValue : public BoundedValue {
private:
double val;
public:
PointValue(double v) : val(v) {};
void write(ostream & o) const
{
o << "[" << val << "]";
};
virtual BoundedValue * operator+=(const BoundedValue *);
virtual BoundedValue * operator-=(const BoundedValue *);
virtual BoundedValue * operator*=(const BoundedValue *);
virtual BoundedValue * operator/=(const BoundedValue *);
BoundedValue * infUpper()
{
BoundedInterval * bi = new BoundedInterval(val,val);
bi->infUpper();
return bi;
};
BoundedValue * infLower()
{
BoundedInterval * bi = new BoundedInterval(val,val);
bi->infLower();
return bi;
};
void negate() {val = -val;};
double getLB() const {return val;};
double getUB() const {return val;};
BoundedValue * accum(const BoundedValue * bv);
bool contains(double d) const
{
return val == d;
};
PointValue * copy() const
{
return new PointValue(*this);
};
};
class Undefined : public BoundedValue {
public:
void write(ostream & o) const
{
o << "UNDEF";
};
virtual BoundedValue * operator+=(const BoundedValue *) {return this;};
virtual BoundedValue * operator-=(const BoundedValue *) {return this;};
virtual BoundedValue * operator*=(const BoundedValue *) {return this;};
virtual BoundedValue * operator/=(const BoundedValue *) {return this;};
BoundedValue * infUpper() {return this;};
BoundedValue * infLower() {return this;};
double getLB() const {return 0;};
double getUB() const {return 0;};
BoundedValue * accum(const BoundedValue * bv) {return bv->copy();};
Undefined * copy() const {return new Undefined(*this);};
};
inline ostream & operator<<(ostream & o,const BoundedValue & b)
{
b.write(o);
return o;
};
inline ostream & operator<<(ostream & o,const Constraint & b)
{
b.write(o);
return o;
};
class FluentEntry : public SpikeEntry {
private:
vector<Constraint *> constrs;
PNE * thefluent;
BoundedValue * bval;
BoundedValue * tmpaccum;
public:
FluentEntry(PNE * pne) : thefluent(pne), bval(new Undefined()), tmpaccum(0) {};
void addInitial(double d)
{
delete bval;
bval = new PointValue(d);
constrs.push_back(new InitialValue(bval->copy()));
};
void addUpdatedBy(ActEntry * ae,const VAL::expression * expr,const VAL::assign_op op,PlanGraph * pg);
void write(ostream & o) const;
BoundedValue * getBV() const {return bval;};
bool represents(const PNE * pne) const {return pne==thefluent;};
~FluentEntry() {delete bval;};
void transferValue();
};
class GraphFactory {
public:
virtual PropEntry * makePropEntry(Literal * l){return new PropEntry(l);};
virtual ActEntry * makeActEntry(instantiatedOp * io){return new ActEntry(io);};
virtual FluentEntry * makeFluentEntry(PNE * pne){return new FluentEntry(pne);};
virtual ~GraphFactory() {};
};
class PlanGraph {
private:
GraphFactory * myFac;
Spike<PropEntry> props;
Spike<ActEntry> acts;
Spike<FluentEntry> fluents;
// Use a list of candidates and filter them
list<instantiatedOp *> inactive;
typedef list<instantiatedOp *> InstOps;
vector<ActEntry *> iteratingActs;
public:
class BVEvaluator;
friend class BVEvaluator;
PlanGraph(GraphFactory * gf); // Constructor can set up initial state.
~PlanGraph() {delete myFac;};
bool extendPlanGraph(); // Extends the graph by one level.
void extendToGoals();
void write(ostream & o) const;
bool activated(instantiatedOp *);
void activateEntry(ActEntry *);
void iterateEntry(ActEntry *);
BoundedValue * update(BoundedValue * bv,const VAL::expression * exp,const VAL::assign_op op,VAL::FastEnvironment * fenv);
vector<ActEntry *> applicableActions(VAL::Validator * v,const VAL::State * s);
vector<ActEntry *> relevantActions(VAL::Validator * v,const VAL::State * s);
};
inline ostream & operator<<(ostream & o,const PlanGraph & pg)
{
pg.write(o);
return o;
};
};
#endif