Program Listing for File instantiation.h
↰ Return to documentation for file (src/VALfiles/instantiation.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 __INSTANTIATION
#define __INSTANTIATION
#include <vector>
#include <map>
#include "FastEnvironment.h"
#include <algorithm>
#include <iterator>
#include "SimpleEval.h"
using std::ostream_iterator;
using std::insert_iterator;
using std::unary_function;
using std::for_each;
class operator_;
class problem;
class TypeChecker;
class pddl_type;
class const_symbol;
using std::vector;
using std::map;
using std::deque;
#include "TypedAnalyser.h"
namespace Inst {
bool varFree(const VAL::parameter_symbol_list * pl);
class instantiatedOp;
class instantiatedDrv;
class instantiatedDrvUtils {
public:
struct index {
VAL::pred_symbol* first;
const VAL::derivation_rule* second;
index(VAL::pred_symbol * a, const VAL::derivation_rule * b) : first(a), second(b) {};
};
private:
struct indexLT {
bool operator() (const index & a, const index & b) const {
VAL::pred_symbol * afirst = VAL::current_analysis->pred_tab.symbol_get(a.first->getName());
VAL::pred_symbol * bfirst = VAL::current_analysis->pred_tab.symbol_get(b.first->getName());
if (afirst < bfirst) return true;
if (afirst > bfirst) return false;
if (a.second < b.second) return true;
return false;
};
};
static set<index,indexLT> definitive;
static bool initDefinitive;
public:
static index * purify(const index *);
};
template<class T> class FlexiblePrint {
private:
const char * before;
const char * after;
ostream_iterator<T> os;
public:
FlexiblePrint(ostream & o, const char * b, const char * a) : before(b), after(a), os(ostream_iterator<T>(o)) {};
FlexiblePrint(const FlexiblePrint & f) : before(f.before), after(f.after),os(f.os) {};
virtual FlexiblePrint & operator=(const FlexiblePrint & f) {
os = f.os;
before = f.before;
after = f.after;
return *this;
}
virtual FlexiblePrint & operator=(const T & f) {
os = before;
os = f;
os = after;
return *this;
}
virtual FlexiblePrint & operator*() { return *this; };
virtual FlexiblePrint & operator++() {
os++;
return *this;
};
virtual FlexiblePrint & operator++(int) {
++os;
return *this;
};
};
class PNE {
private:
int id;
const VAL::func_term * func;
VAL::FastEnvironment * env;
const VAL::func_term * realisation;
public:
PNE(const VAL::func_term * f,VAL::FastEnvironment * e) :
id(0), func(f), env(e), realisation(0)
{
if(varFree(func->getArgs()))
{
realisation = func;
};
};
const VAL::func_term * toFuncTerm()
{
if(!realisation)
{
VAL::parameter_symbol_list * pl = new VAL::parameter_symbol_list();
for(VAL::parameter_symbol_list::const_iterator i = func->getArgs()->begin();i != func->getArgs()->end();++i)
{
pl->push_back((*env)[*i]);
};
realisation = new VAL::func_term(const_cast<VAL::func_symbol*>(func->getFunction()),pl);
};
return realisation;
};
struct PNEParametersOutput : unary_function<const VAL::parameter_symbol *,string> {
const VAL::FastEnvironment & bindings;
PNEParametersOutput(const VAL::FastEnvironment & bs) : bindings(bs) {};
string operator()(const VAL::parameter_symbol * v) const
{
return bindings[v]->getName();
};
};
void write(ostream & o) const
{
o << "(" << func->getFunction()->getName();
transform(func->getArgs()->begin(),func->getArgs()->end(),
FlexiblePrint<string>(o," ",""), PNEParametersOutput(*env));
o << ")";
};
const VAL::func_symbol * getHead() const
{
return func->getFunction();
};
const VAL::func_term * getFunc() const
{
return func;
};
VAL::LiteralParameterIterator<VAL::parameter_symbol_list::const_iterator> begin()
{return makeIterator(env,func->getArgs()->begin());};
VAL::LiteralParameterIterator<VAL::parameter_symbol_list::const_iterator> end()
{return makeIterator(env,func->getArgs()->end());};
const VAL::parameter_symbol * operator[](int n)
{
VAL::LiteralParameterIterator<VAL::parameter_symbol_list::const_iterator> i = begin();
for(;n > 0;--n,++i);
return *i;
};
int getID() const {return id;};
void setID(int x) {id = x;};
};
ostream & operator<<(ostream & o,const PNE & p);
class Literal {
protected:
int id;
const VAL::proposition * prop;
VAL::FastEnvironment * env;
const VAL::proposition * realisation;
public:
Literal(const VAL::proposition * p, VAL::FastEnvironment * e) :
id(0), prop(p), env(e), realisation(0)
{
if(varFree(prop->args))
{
realisation = prop;
};
};
VAL::FastEnvironment * getEnv() const
{
return env;
}
const VAL::proposition * toProposition()
{
if(!realisation)
{
VAL::parameter_symbol_list * pl = new VAL::parameter_symbol_list;
for(VAL::parameter_symbol_list::iterator i = prop->args->begin();i != prop->args->end();++i)
{
pl->push_back((*env)[*i]);
};
realisation = new VAL::proposition(prop->head,pl);
};
return realisation;
};
struct LiteralParametersOutput {
const VAL::FastEnvironment & bindings;
LiteralParametersOutput(const VAL::FastEnvironment & bs) : bindings(bs) {};
string operator()(const VAL::parameter_symbol * v) const
{
return bindings[v]->getName();
};
};
void write(ostream & o) const
{
o << "(" << prop->head->getName();
transform(prop->args->begin(),prop->args->end(),
FlexiblePrint<string>(o," ",""),LiteralParametersOutput(*env));
o << ")";
};
const VAL::pred_symbol * getHead() const
{
return prop->head;
};
const VAL::proposition * getProp() const
{
return prop;
};
VAL::LiteralParameterIterator<VAL::parameter_symbol_list::iterator> begin()
{return makeIterator(env,prop->args->begin());};
VAL::LiteralParameterIterator<VAL::parameter_symbol_list::iterator> end()
{return makeIterator(env,prop->args->end());};
VAL::parameter_symbol * operator[](int n)
{
VAL::LiteralParameterIterator<VAL::parameter_symbol_list::iterator> i = begin();
for(;n > 0;--n,++i);
return *i;
};
int getID() const {return id;};
void setID(int x) {id = x;};
virtual ~Literal() {};
};
struct CreatedLiteral : public Literal {
CreatedLiteral(const VAL::proposition * p, VAL::FastEnvironment * e) :
Literal(p,e)
{};
~CreatedLiteral()
{
delete env;
};
};
ostream & operator<<(ostream & o,const Literal & io);
template<typename S>
struct Purifier {
const S * operator()(const S * s)
{
return s;
};
};
using VAL::pred_symbol;
using VAL::func_symbol;
using VAL::current_analysis;
template<>
struct Purifier<pred_symbol> {
const pred_symbol * operator()(const pred_symbol * p)
{
return current_analysis->pred_tab.symbol_get(p->getName());
};
};
template<>
struct Purifier<instantiatedDrvUtils::index> {
const instantiatedDrvUtils::index * operator()(const instantiatedDrvUtils::index * p)
{
return instantiatedDrvUtils::purify(p);
};
};
template<>
struct Purifier<func_symbol> {
const func_symbol * operator()(const func_symbol * f)
{
return current_analysis->func_tab.symbol_get(f->getName());
};
};
template<typename S,typename V>
class GenStore {
private:
typedef map<const S *,CascadeMap<VAL::const_symbol *,V> > PredMap;
PredMap literals;
deque<V *> allLits;
Purifier<S> purify;
bool locked;
public:
GenStore()
: locked(false)
{
}
void preventFurtherModification()
{
locked = true;
}
void write(ostream & o) const
{
for(typename deque<V*>::const_iterator i = allLits.begin();i != allLits.end();++i)
{
if(*i) o << **i << "\n";
};
};
V * insert(V * lit)
{
assert(!locked);
V * & str = literals[purify(lit->getHead())].forceGet(lit->begin(),lit->end());
if(str == 0)
{
str = lit;
allLits.push_back(lit);
lit->setID(allLits.size()-1);
return 0;
}
return str;
};
V * find(V * lit)
{
V * & str = literals[purify(lit->getHead())].myGet(lit->begin(),lit->end());
return str;
};
set<V *> allContents(const S * p)
{
set<V *> slits;
for(typename CascadeMap<VAL::const_symbol *,V>::iterator i = literals[purify(p)].begin();
i != literals[purify(p)].end();++i)
{
slits.insert(*i);
};
slits.erase((V*)0);
return slits;
};
typedef typename deque<V *>::iterator iterator;
typedef typename deque<V *>::const_iterator const_iterator;
iterator begin() {return allLits.begin();};
iterator end() {return allLits.end();};
const_iterator begin() const {return allLits.begin();};
const_iterator end() const {return allLits.end();};
size_t size() const {return allLits.size();};
V * operator[](int x) const {return allLits[x];};
template<typename TI>
V * get(S * s,TI b,TI e)
{
return literals[purify(s)].get(b,e);
};
template<typename TI>
V * find(S * s,TI b,TI e)
{
return literals[purify(s)].myGet(b,e);
};
void erase(const V * v)
{
literals[purify(v->getHead())].myGet(v->begin(),v->end()) = 0;
allLits[v->getID()] = 0;
}
void clearUp()
{
allLits.erase(std::remove(allLits.begin(),allLits.end(),((V*)0)),allLits.end());
}
void clear()
{
iterator itr = begin();
const iterator itrEnd = end();
for (; itr != itrEnd; ++itr) delete *itr;
literals.clear();
allLits.clear();
}
};
typedef GenStore<VAL::pred_symbol,Literal> LiteralStore;
typedef GenStore<VAL::func_symbol,PNE> PNEStore;
class instantiatedOp;
class instantiatedDrv;
typedef GenStore<VAL::operator_symbol,instantiatedOp> OpStore;
typedef GenStore<instantiatedDrvUtils::index,instantiatedDrv> DrvStore;
class LitStoreEvaluator : public PrimitiveEvaluator {
private:
LiteralStore & literals;
public:
LitStoreEvaluator(bool & v,bool & u,bool & w,bool & x,LiteralStore & lits) :
PrimitiveEvaluator(v,u,w,x), literals(lits) {};
virtual void evaluateSimpleGoal(VAL::FastEnvironment * f,VAL::simple_goal * s);
};
template<>
class PrimitiveEvaluatorConstructor<LitStoreEvaluator> {
private:
LiteralStore & literals;
public:
PrimitiveEvaluatorConstructor<LitStoreEvaluator>(LiteralStore & lits) :
literals(lits) {};
PrimitiveEvaluator * operator()(bool & v,bool & u,bool & w,bool & x)
{
return new LitStoreEvaluator(v,u,w,x,literals);
}
};
typedef PrimitiveEvaluatorConstructor<LitStoreEvaluator> LSE;
class instantiatedOp {
private:
int id;
const VAL::operator_ * op;
VAL::FastEnvironment * env;
static OpStore instOps;
static map<VAL::pddl_type *,vector<VAL::const_symbol*> > & values;
struct ActionParametersOutput {
const VAL::FastEnvironment & bindings;
ActionParametersOutput(const VAL::FastEnvironment & bs) : bindings(bs) {};
string operator()(const VAL::var_symbol * v) const
{
return bindings[v]->getName();
};
};
static LiteralStore & literals;
static PNEStore & pnes;
public:
#ifndef NDEBUG
static const VAL::operator_ * insistOnOp;
static vector<VAL::const_symbol *> insistOnOpParameters;
static const instantiatedOp * opBeforeFiltering;
#endif
instantiatedOp(const VAL::operator_ * o,VAL::FastEnvironment * e) : id(0), op(o), env(e) {};
static void instantiate(const VAL::operator_ * op, const VAL::problem * p,VAL::TypeChecker & tc);
~instantiatedOp() {delete env;};
static void filterOps(VAL::TypeChecker * const);
static void opErase(const instantiatedOp * o)
{
instOps.erase(o);
}
void write(ostream & o) const
{
o << "(" << op->name->getName();
transform(op->parameters->begin(),op->parameters->end(),
FlexiblePrint<string>(o," ",""),ActionParametersOutput(*env));
o << ")";
};
int arity() const {return op->parameters->size();};
const VAL::const_symbol * getArg(int i) const
{
VAL::var_symbol_list::const_iterator a = op->parameters->begin();
for(;i > 0;--i,++a);
return (*env)[*a];
};
static void writeAll(ostream & o);
static int howMany() {return instOps.size();};
static int howManyLiterals() {return literals.size();};
static int howManyPNEs() {return pnes.size();};
static void createAllLiterals(VAL::problem * p,VAL::TypeChecker * tc);
void collectLiterals(VAL::TypeChecker * tc);
static void writeAllLiterals(ostream & o);
static void writeAllPNEs(ostream & o);
static OpStore::iterator opsBegin() {return instOps.begin();};
static OpStore::iterator opsEnd() {return instOps.end();};
static PNEStore::iterator pnesBegin() {return pnes.begin();};
static PNEStore::iterator pnesEnd() {return pnes.end();};
static LiteralStore::iterator literalsBegin() {return literals.begin();};
static LiteralStore::iterator literalsEnd() {return literals.end();};
static map<VAL::pddl_type *,vector<VAL::const_symbol*> > & getValues() { return values; };
typedef VAL::FastEnvironment::const_iterator const_iterator;
const_iterator begin() const {return env->begin();};
const_iterator end() const {return env->end();};
static instantiatedOp * getInstOp(int i) {return instOps[i];};
template<typename TI>
static instantiatedOp * getInstOp(const VAL::operator_ * op,TI sp,TI ep)
{
return getInstOp(op->name,sp,ep);
};
template<typename TI>
static instantiatedOp * getInstOp(VAL::operator_symbol * osym,TI sp,TI ep)
{
return instOps.get(osym,sp,ep);
};
template<typename TI>
static instantiatedOp * getInstOp(const string & opname,TI sp,TI ep)
{
VAL::operator_symbol * osym(VAL::current_analysis->op_tab.symbol_get(opname));
return getInstOp(osym,sp,ep);
};
template<typename TI>
static instantiatedOp * findInstOp(VAL::operator_symbol * osym,TI sp,TI ep)
{
return instOps.find(osym,sp,ep);
};
static OpStore::iterator from(int k) {return opsBegin()+k;};
const VAL::operator_ * forOp() const {return op;};
VAL::FastEnvironment * getEnv() {return env;};
static Literal * getLiteral(Literal * l) {return literals.insert(l);};
static Literal * findLiteral(Literal * l) {return literals.find(l);};
static void preventFurtherModificationOfLiterals()
{
literals.preventFurtherModification();
}
static PNE * getPNE(PNE * p) {return pnes.insert(p);};
static PNE * findPNE(PNE * p) {return pnes.find(p);};
static set<Literal *> allLiterals(const VAL::pred_symbol * p)
{
return literals.allContents(p);
};
const VAL::operator_symbol * getHead() const {return op->name;};
int getID() const {return id;};
void setID(int x) {id = x;};
//added by AMC to find PNEs which match a func_symbol
static set<PNE *> allPNEs(const VAL::func_symbol * f)
{
return pnes.allContents(f);
};
friend class Collector;
class PropEffectsIterator {
private:
instantiatedOp * inst;
bool isPos;
VAL::pc_list<VAL::simple_effect *>::iterator effs;
Literal * lit;
public:
PropEffectsIterator(instantiatedOp * io,bool pos) : inst(io), isPos(pos),
effs(pos?io->op->effects->add_effects.begin():io->op->effects->del_effects.begin()),
lit(0)
{};
void toEnd()
{
effs = isPos?inst->op->effects->add_effects.end():inst->op->effects->del_effects.end();
};
bool operator==(const PropEffectsIterator & i) const
{
return effs == i.effs;
};
bool operator!=(const PropEffectsIterator & i) const
{
return effs != i.effs;
};
PropEffectsIterator & operator++()
{
++effs;
lit = 0;
return *this;
};
Literal * operator*()
{
if(!lit)
{
Literal l((*effs)->prop,inst->getEnv());
lit = instantiatedOp::getLiteral(&l);
};
return lit;
};
};
class PNEEffectsIterator {
private:
instantiatedOp * inst;
VAL::pc_list<VAL::assignment *>::iterator effs;
VAL::pc_list<VAL::assignment *>::iterator effsend;
VAL::pc_list<VAL::timed_effect *>::iterator effts;
VAL::pc_list<VAL::timed_effect*>::iterator efftsend;
PNE * pne;
public:
PNEEffectsIterator(instantiatedOp * io) : inst(io),
effs(io->op->effects->assign_effects.begin()),
effsend(io->op->effects->assign_effects.end()),
effts(io->op->effects->timed_effects.begin()),
efftsend(io->op->effects->timed_effects.end()),
pne(0)
{
while(effts != efftsend &&
(*effts)->ts !=VAL:: E_CONTINUOUS) ++effts;
if(effs == effsend && effts != efftsend)
{
effs = (*effts)->effs->assign_effects.begin();
//cout << "GOT " << **effs << "\n";
effsend = (*effts)->effs->assign_effects.end();
++effts;
while(effts != efftsend &&
(*effts)->ts != VAL::E_CONTINUOUS) ++effts;
};
};
void toEnd()
{
effs = effsend;
effts = efftsend;
};
bool operator==(const PNEEffectsIterator & i) const
{
return effts == i.effts && (effs == i.effs ||
(effts == efftsend && effs == effsend && i.effs == i.effsend));
};
bool operator!=(const PNEEffectsIterator & i) const
{
return !(*this == i);
};
PNE * operator*()
{
if(!pne)
{
PNE p((*effs)->getFTerm(),inst->getEnv());
pne = instantiatedOp::getPNE(&p);
};
return pne;
};
PNEEffectsIterator & operator++()
{
++effs;
if(effs == effsend && effts != efftsend)
{
effs = (*effts)->effs->assign_effects.begin();
//cout << "GOT " << **effs << "\n";
effsend = (*effts)->effs->assign_effects.end();
++effts;
while(effts != efftsend &&
(*effts)->ts != VAL::E_CONTINUOUS) ++effts;
};
pne = 0;
return *this;
};
const VAL::expression * getUpdate()
{
return (*effs)->getExpr();
};
const VAL::assign_op getOp() const
{
return (*effs)->getOp();
};
};
PropEffectsIterator addEffectsBegin();
PropEffectsIterator addEffectsEnd();
PropEffectsIterator delEffectsBegin();
PropEffectsIterator delEffectsEnd();
PNEEffectsIterator PNEEffectsBegin();
PNEEffectsIterator PNEEffectsEnd();
//added by AMC to test whether a goal can be satisfied by an
//InstantiatedOp
bool isGoalMetByOp(const Literal * lit);
bool isGoalMetByEffect(const VAL::effect_lists * effs, const Literal * lit);
bool isGoalMetByEffect(VAL::simple_effect * seff, const Literal * lit);
bool isGoalMetByEffect(VAL::forall_effect * fleff, const Literal * lit);
bool isGoalMetByEffect(VAL::cond_effect * ceff, const Literal * lit);
bool isGoalMetByEffect(VAL::timed_effect * teff, const Literal * lit);
};
class instantiatedDrv {
private:
int id;
const VAL::derivation_rule * op;
VAL::FastEnvironment * env;
instantiatedDrvUtils::index localHead;
static DrvStore instDrvs;
static map<VAL::pddl_type *,vector<VAL::const_symbol*> > & values;
struct DerivationRuleParametersOutput {
const VAL::FastEnvironment & bindings;
DerivationRuleParametersOutput(const VAL::FastEnvironment & bs) : bindings(bs) {};
string operator()(const VAL::var_symbol * v) const
{
return bindings[v]->getName();
};
string operator()(const VAL::parameter_symbol * v) const
{
return bindings[v]->getName();
};
};
static LiteralStore & literals;
static PNEStore & pnes;
public:
instantiatedDrv(const VAL::derivation_rule * o,VAL::FastEnvironment * e) : id(0), op(o), env(e), localHead(o->get_head()->head,o) {};
static void instantiate(const VAL::derivation_rule * op, const VAL::problem * p,VAL::TypeChecker & tc);
~instantiatedDrv() {delete env;};
static void filterDrvs(VAL::TypeChecker * const);
static void drvErase(const instantiatedDrv * o)
{
instDrvs.erase(o);
}
void write(ostream & o) const
{
o << "(derive-" << op->get_head()->head->getName() << "-" << op;
transform(op->get_head()->args->begin(),op->get_head()->args->end(),
FlexiblePrint<string>(o," ",""),DerivationRuleParametersOutput(*env));
o << ")";
};
int arity() const {return op->get_head()->args->size();};
const VAL::const_symbol * getArg(int i) const
{
VAL::parameter_symbol_list::const_iterator a = op->get_head()->args->begin();
for(;i > 0;--i,++a);
return (*env)[*a];
};
static void writeAll(ostream & o);
static int howMany() {return instDrvs.size();};
static void createAllLiterals(VAL::problem * p,VAL::TypeChecker * tc);
void collectLiterals(VAL::TypeChecker * tc);
static DrvStore::iterator drvsBegin() {return instDrvs.begin();};
static DrvStore::iterator drvsEnd() {return instDrvs.end();};
typedef VAL::FastEnvironment::const_iterator const_iterator;
const_iterator begin() const {return env->begin();};
const_iterator end() const {return env->end();};
static instantiatedDrv * getInstDrv(int i) {return instDrvs[i];};
template<typename TI>
static instantiatedDrv * getInstDrv(const VAL::derivation_rule * op,TI sp,TI ep)
{
return getInstDrv(op->get_head()->head->getName(),sp,ep);
};
template<typename TI>
static instantiatedOp * getInstDrv(VAL::pred_symbol * osym,TI sp,TI ep)
{
return instDrvs.get(osym,sp,ep);
};
template<typename TI>
static instantiatedOp * getInstDrv(const string & opname,TI sp,TI ep)
{
VAL::pred_symbol * osym(VAL::current_analysis->pred_tab.symbol_get(opname));
return getInstDrv(osym,sp,ep);
};
static DrvStore::iterator from(int k) {return drvsBegin()+k;};
const VAL::derivation_rule * forDrv() const {return op;};
VAL::FastEnvironment * getEnv() {return env;};
//const VAL::pred_symbol * getHead() const {return op->get_head()->head;};
const instantiatedDrvUtils::index * getHead() const {return &localHead; };
int getID() const {return id;};
void setID(int x) {id = x;};
friend class Collector;
};
ostream & operator<<(ostream & o,const instantiatedOp & io);
ostream & operator<<(ostream & o,const instantiatedDrv & io);
VAL::const_symbol * const getConst(string name);
VAL::const_symbol * const getConst(char * name);
template<typename V,typename I>
struct FType {
typedef typename std::iterator_traits<I>::value_type VT;
typedef V(*FnType)(VT);
};
template<typename V,typename I,typename FType<V,I>::FnType f>
class Iterator {
private:
I myIt;
public:
Iterator(I i) : myIt(i) {};
Iterator & operator++()
{
++myIt;
return *this;
};
V operator*()
{
return f(*myIt);
};
bool operator==(const Iterator & i)
{
return myIt == i.myIt;
};
};
};
#endif