.. _program_listing_file_src_VALfiles_instantiation.h: Program Listing for File instantiation.h ======================================== |exhale_lsh| :ref:`Return to documentation for file ` (``src/VALfiles/instantiation.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 . * ************************************************************************/ #ifndef __INSTANTIATION #define __INSTANTIATION #include #include #include "FastEnvironment.h" #include #include #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 definitive; static bool initDefinitive; public: static index * purify(const index *); }; template class FlexiblePrint { private: const char * before; const char * after; ostream_iterator os; public: FlexiblePrint(ostream & o, const char * b, const char * a) : before(b), after(a), os(ostream_iterator(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(func->getFunction()),pl); }; return realisation; }; struct PNEParametersOutput : unary_function { 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(o," ",""), PNEParametersOutput(*env)); o << ")"; }; const VAL::func_symbol * getHead() const { return func->getFunction(); }; const VAL::func_term * getFunc() const { return func; }; VAL::LiteralParameterIterator begin() {return makeIterator(env,func->getArgs()->begin());}; VAL::LiteralParameterIterator end() {return makeIterator(env,func->getArgs()->end());}; const VAL::parameter_symbol * operator[](int n) { VAL::LiteralParameterIterator 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(o," ",""),LiteralParametersOutput(*env)); o << ")"; }; const VAL::pred_symbol * getHead() const { return prop->head; }; const VAL::proposition * getProp() const { return prop; }; VAL::LiteralParameterIterator begin() {return makeIterator(env,prop->args->begin());}; VAL::LiteralParameterIterator end() {return makeIterator(env,prop->args->end());}; VAL::parameter_symbol * operator[](int n) { VAL::LiteralParameterIterator 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 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 { const pred_symbol * operator()(const pred_symbol * p) { return current_analysis->pred_tab.symbol_get(p->getName()); }; }; template<> struct Purifier { const instantiatedDrvUtils::index * operator()(const instantiatedDrvUtils::index * p) { return instantiatedDrvUtils::purify(p); }; }; template<> struct Purifier { const func_symbol * operator()(const func_symbol * f) { return current_analysis->func_tab.symbol_get(f->getName()); }; }; template class GenStore { private: typedef map > PredMap; PredMap literals; deque allLits; Purifier purify; bool locked; public: GenStore() : locked(false) { } void preventFurtherModification() { locked = true; } void write(ostream & o) const { for(typename deque::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 allContents(const S * p) { set slits; for(typename CascadeMap::iterator i = literals[purify(p)].begin(); i != literals[purify(p)].end();++i) { slits.insert(*i); }; slits.erase((V*)0); return slits; }; typedef typename deque::iterator iterator; typedef typename deque::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 V * get(S * s,TI b,TI e) { return literals[purify(s)].get(b,e); }; template 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 LiteralStore; typedef GenStore PNEStore; class instantiatedOp; class instantiatedDrv; typedef GenStore OpStore; typedef GenStore 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 { private: LiteralStore & literals; public: PrimitiveEvaluatorConstructor(LiteralStore & lits) : literals(lits) {}; PrimitiveEvaluator * operator()(bool & v,bool & u,bool & w,bool & x) { return new LitStoreEvaluator(v,u,w,x,literals); } }; typedef PrimitiveEvaluatorConstructor LSE; class instantiatedOp { private: int id; const VAL::operator_ * op; VAL::FastEnvironment * env; static OpStore instOps; static map > & 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 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(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 > & 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 static instantiatedOp * getInstOp(const VAL::operator_ * op,TI sp,TI ep) { return getInstOp(op->name,sp,ep); }; template static instantiatedOp * getInstOp(VAL::operator_symbol * osym,TI sp,TI ep) { return instOps.get(osym,sp,ep); }; template 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 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 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 allPNEs(const VAL::func_symbol * f) { return pnes.allContents(f); }; friend class Collector; class PropEffectsIterator { private: instantiatedOp * inst; bool isPos; VAL::pc_list::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::iterator effs; VAL::pc_list::iterator effsend; VAL::pc_list::iterator effts; VAL::pc_list::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 > & 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(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 static instantiatedDrv * getInstDrv(const VAL::derivation_rule * op,TI sp,TI ep) { return getInstDrv(op->get_head()->head->getName(),sp,ep); }; template static instantiatedOp * getInstDrv(VAL::pred_symbol * osym,TI sp,TI ep) { return instDrvs.get(osym,sp,ep); }; template 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 struct FType { typedef typename std::iterator_traits::value_type VT; typedef V(*FnType)(VT); }; template::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