.. _program_listing_file__tmp_ws_src_ros2_planning_system_plansys2_pddl_parser_include_plansys2_pddl_parser_Domain.h: Program Listing for File Domain.h ================================= |exhale_lsh| :ref:`Return to documentation for file ` (``/tmp/ws/src/ros2_planning_system/plansys2_pddl_parser/include/plansys2_pddl_parser/Domain.h``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #pragma once #include "plansys2_pddl_parser/Task.h" #include "plansys2_pddl_parser/TemporalAction.h" #include "plansys2_pddl_parser/And.h" #include "plansys2_pddl_parser/Derived.h" #include "plansys2_pddl_parser/Exists.h" #include "plansys2_pddl_parser/Forall.h" #include "plansys2_pddl_parser/Function.h" #include "plansys2_pddl_parser/GroundFunc.h" #include "plansys2_pddl_parser/FunctionModifier.h" #include "plansys2_pddl_parser/Not.h" #include "plansys2_pddl_parser/Oneof.h" #include "plansys2_pddl_parser/Or.h" #include "plansys2_pddl_parser/EitherType.h" #include "plansys2_pddl_parser/When.h" #define DOMAIN_DEBUG false namespace parser { namespace pddl { class Domain { public: std::string name; // name of domain bool equality; // whether domain supports equality bool strips, adl, condeffects; // whether domain is strips, adl and/or has conditional effects bool typed, cons, costs; // whether domain is typed, has constants, has costs bool temp, nondet, neg, disj; // whether domain is temporal, is non-deterministic, has negative precons, has disjunctive preconditions bool universal; // whether domain has universal precons bool fluents; // whether domains contains fluents bool derivedpred; // whether domain contains derived predicates TokenStruct< Type * > types; // types TokenStruct< Lifted * > preds; // predicates TokenStruct< Function * > funcs; // functions TokenStruct< Action * > actions; // actions TokenStruct< Derived * > derived; // derived predicates TokenStruct< Task * > tasks; // tasks Domain() : equality( false ), strips( false ), adl( false ), condeffects( false ) , typed( false ), cons( false ), costs( false ), temp( false ) , nondet( false ), neg( false ), disj( false ), universal( false ) , fluents( false ), derivedpred( false ) { types.insert( new Type( "object" ) ); // Type 0 is always "object", whether the domain is typed or not } Domain( const std::string & s ) : Domain() { parse( s ); } virtual ~Domain() { for ( unsigned i = 0; i < types.size(); ++i ) delete types[i]; for ( unsigned i = 0; i < preds.size(); ++i ) delete preds[i]; for ( unsigned i = 0; i < funcs.size(); ++i ) delete funcs[i]; for ( unsigned i = 0; i < actions.size(); ++i ) delete actions[i]; for ( unsigned i = 0; i < derived.size(); ++i ) delete derived[i]; for ( unsigned i = 0; i < tasks.size(); ++i ) delete tasks[i]; } virtual void parse( const std::string & s ) { Stringreader f( s ); name = f.parseName( "domain" ); if ( DOMAIN_DEBUG ) std::cout << name << "\n"; for ( ; f.getChar() != ')'; f.next() ) { f.assert_token( "(" ); f.assert_token( ":" ); std::string t = f.getToken(); if ( DOMAIN_DEBUG ) std::cout << t << "\n"; if (!parseBlock(t, f)) { f.tokenExit( t ); } } } virtual bool parseBlock(const std::string& t, Stringreader& f) { if ( t == "requirements" ) parseRequirements( f ); else if ( t == "types" ) parseTypes( f ); else if ( t == "constants" ) parseConstants( f ); else if ( t == "predicates" ) parsePredicates( f ); else if ( t == "functions" ) parseFunctions( f ); else if ( t == "action" ) parseAction( f ); else if ( t == "durative-action" ) parseDurativeAction( f ); else if ( t == "derived" ) parseDerived( f ); // else if ( t == "axiom" ) parseAxiom( f ); else return false; // Unknown block type return true; } void parseRequirements( Stringreader & f ) { for ( f.next(); f.getChar() != ')'; f.next() ) { f.assert_token( ":" ); std::string s = f.getToken(); if ( DOMAIN_DEBUG ) std::cout << " " << s << "\n"; if (!parseRequirement(s)) { f.tokenExit( s ); } } ++f.c; } virtual bool parseRequirement( const std::string& s ) { if ( s == "strips" ) strips = true; else if ( s == "adl" ) adl = true; else if ( s == "negative-preconditions" ) neg = true; else if ( s == "conditional-effects" ) condeffects = true; else if ( s == "typing" ) typed = true; else if ( s == "action-cost" ) costs = true; else if ( s == "equality" ) equality = true; else if ( s == "durative-actions" ) temp = true; else if ( s == "non-deterministic" ) nondet = true; else if ( s == "universal-preconditions" ) universal = true; else if ( s == "fluents" ) fluents = true; else if ( s == "disjuntive-preconditions" ) disj = true; else if ( s == "derived-predicates" ) derivedpred = true; else return false; // Unknown requirement return true; } // get the type corresponding to a string Type * getType( std::string s ) { int i = types.index( s ); if ( i < 0 ) { if ( s[0] == '(' ) { i = types.insert( new EitherType( s ) ); for ( unsigned k = 9; s[k] != ')'; ) { unsigned e = s.find( ' ', k ); types[i]->subtypes.push_back( getType( s.substr( k, e - k ) ) ); k = e + 1; } } else i = types.insert( new Type( s ) ); } return types[i]; } // convert a vector of type names to integers IntVec convertTypes( const StringVec & v ) { IntVec out; for ( unsigned i = 0; i < v.size(); ++i ) out.push_back( types.index( getType( v[i] )->name ) ); return out; } void parseTypes( Stringreader & f ) { if ( !typed ) { std::cout << "Requirement :typing needed to define types\n"; exit( 1 ); } // if this makes it in, probably need to define new subclass of Type // if ( costs ) insert( new Type( "NUMBER" ), tmap, types ); // Parse the typed list TokenStruct< std::string > ts = f.parseTypedList( false ); // bit of a hack to avoid object being the supertype if ( ts.index( "object" ) >= 0 ) { types[0]->name = "supertype"; types.tokenMap.clear(); types.tokenMap["supertype"] = 0; } // Relate subtypes and supertypes for ( unsigned i = 0; i < ts.size(); ++i ) { if (std::find(types.types.begin(), types.types.end(), ts.types[i]) == types.types.end()) { if ( ts.types[i].size() ) getType( ts.types[i] )->insertSubtype( getType( ts[i] ) ); else getType( ts[i] ); } } // By default, the supertype of a type is "object" for ( unsigned i = 1; i < types.size(); ++i ) if ( types[i]->supertype == 0 ) types[0]->insertSubtype( types[i] ); for ( unsigned i = 0; DOMAIN_DEBUG && i < types.size(); ++i ) std::cout << " " << types[i]; } void parseConstants( Stringreader & f ) { if ( typed && !types.size() ) { std::cout << "Types needed before defining constants\n"; exit( 1 ); } cons = true; TokenStruct< std::string > ts = f.parseTypedList( true, types ); for ( unsigned i = 0; i < ts.size(); ++i ) getType( ts.types[i] )->constants.insert( ts[i] ); for ( unsigned i = 0; DOMAIN_DEBUG && i < types.size(); ++i ) { std::cout << " "; if ( typed ) std::cout << " " << types[i] << ":"; for ( unsigned j = 0; j < types[i]->constants.size(); ++j ) std::cout << " " << types[i]->constants[j]; std::cout << "\n"; } } void parsePredicates( Stringreader & f ) { if ( typed && !types.size() ) { std::cout << "Types needed before defining predicates\n"; exit(1); } for ( f.next(); f.getChar() != ')'; f.next() ) { f.assert_token( "(" ); if ( f.getChar() == ':' ) { // Needed to support MA-PDDL f.assert_token( ":private" ); f.parseTypedList( true, types, "(" ); // CURRENT HACK: TOTALLY IGNORE PRIVATE !!! --f.c; parsePredicates( f ); } else { Lifted * c = new Lifted( f.getToken() ); c->parse( f, types[0]->constants, *this ); if ( DOMAIN_DEBUG ) std::cout << " " << c; preds.insert( c ); } } ++f.c; } void parseFunctions( Stringreader & f ) { if ( typed && !types.size() ) { std::cout << "Types needed before defining functions\n"; exit(1); } for ( f.next(); f.getChar() != ')'; f.next() ) { f.assert_token( "(" ); Function * c = new Function( f.getToken() ); c->parse( f, types[0]->constants, *this ); if ( DOMAIN_DEBUG ) std::cout << " " << c; funcs.insert( c ); } ++f.c; } virtual void parseAction( Stringreader & f ) { if ( !preds.size() ) { std::cout << "Predicates needed before defining actions\n"; exit(1); } f.next(); Action * a = new Action( f.getToken() ); a->parse( f, types[0]->constants, *this ); if ( DOMAIN_DEBUG ) std::cout << a << "\n"; actions.insert( a ); } void parseDerived( Stringreader & f ) { if ( !preds.size() ) { std::cout << "Predicates needed before defining derived predicates\n"; exit(1); } f.next(); Derived * d = new Derived; d->parse( f, types[0]->constants, *this ); if ( DOMAIN_DEBUG ) std::cout << d << "\n"; derived.insert( d ); } void parseDurativeAction( Stringreader & f ) { if ( !preds.size() ) { std::cout << "Predicates needed before defining actions\n"; exit(1); } f.next(); Action * a = new TemporalAction( f.getToken() ); a->parse( f, types[0]->constants, *this ); if ( DOMAIN_DEBUG ) std::cout << a << "\n"; actions.insert( a ); } // Return a copy of the type structure, with newly allocated types // This will also copy all constants and objects! TokenStruct< Type * > copyTypes() { TokenStruct< Type * > out; for ( unsigned i = 0; i < types.size(); ++i ) out.insert( types[i]->copy() ); for ( unsigned i = 1; i < types.size(); ++i ) { if ( types[i]->supertype ) out[out.index( types[i]->supertype->name )]->insertSubtype( out[i] ); else out[i]->copySubtypes( types[i], out ); } return out; } // Set the types to "otherTypes" void setTypes( const TokenStruct< Type * > & otherTypes ) { for ( unsigned i = 0; i < types.size(); ++i ) delete types[i]; types = otherTypes; } // Create a type with a given supertype (default is "object") void createType( const std::string & name, const std::string & parent = "object" ) { Type * type = new Type( name ); types.insert( type ); types.get( parent )->insertSubtype( type ); } // Create a constant of a given type void createConstant( const std::string & name, const std::string & type ) { types.get( type )->constants.insert( name ); } // Create a predicate with the given name and parameter types Lifted * createPredicate( const std::string & name, const StringVec & params = StringVec() ) { Lifted * pred = new Lifted( name ); for ( unsigned i = 0; i < params.size(); ++i ) pred->params.push_back( types.index( params[i] ) ); preds.insert( pred ); return pred; } // Create a function with the given name and parameter types Lifted * createFunction( const std::string & name, int type, const StringVec & params = StringVec() ) { Function * func = new Function( name, type ); for ( unsigned i = 0; i < params.size(); ++i ) func->params.push_back( types.index( params[i] ) ); funcs.insert( func ); return func; } // Create an action with the given name and parameter types Action * createAction( const std::string & name, const StringVec & params = StringVec() ) { Action * action = new Action( name ); for ( unsigned i = 0; i < params.size(); ++i ) action->params.push_back( types.index( params[i] ) ); action->pre = new And; action->eff = new And; actions.insert( action ); return action; } // Set the precondition of an action to "cond", converting to "And" void setPre( const std::string & act, Condition * cond ) { Action * action = actions.get( act ); And * old = dynamic_cast< And * >( cond ); if ( old == 0 ) { action->pre = new And; if ( cond ) dynamic_cast< And * >( action->pre )->add( cond->copy( *this ) ); } else action->pre = old->copy( *this ); } // Add a precondition to the action with name "act" void addPre( bool neg, const std::string & act, const std::string & pred, const IntVec & params = IntVec() ) { Action * action = actions.get( act ); if ( action->pre == 0 ) action->pre = new And; And * a = dynamic_cast< And * >( action->pre ); if ( neg ) a->add( new Not( ground( pred, params ) ) ); else a->add( ground( pred, params ) ); } // Add an "or" precondition to the action with name "act" void addOrPre( const std::string & act, const std::string & pred1, const std::string & pred2, const IntVec & params1 = IntVec(), const IntVec & params2 = IntVec() ) { Or * o = new Or; o->first = ground( pred1, params1 ); o->second = ground( pred2, params2 ); Action * action = actions.get( act ); And * a = dynamic_cast< And * >( action->pre ); a->add( o ); } // Set the precondition of an action to "cond", converting to "And" void setEff( const std::string & act, Condition * cond ) { Action * action = actions.get( act ); And * old = dynamic_cast< And * >( cond ); if ( old == 0 ) { action->eff = new And; if ( cond ) dynamic_cast< And * >( action->eff )->add( cond->copy( *this ) ); } else action->eff = old->copy( *this ); } // Add an effect to the action with name "act" void addEff( bool neg, const std::string & act, const std::string & pred, const IntVec & params = IntVec() ) { Action * action = actions.get( act ); if ( action->eff == 0 ) action->eff = new And; And * a = dynamic_cast< And * >( action->eff ); if ( neg ) a->add( new Not( ground( pred, params ) ) ); else a->add( ground( pred, params ) ); } // Add a cost to the action with name "act", in the form of an integer void addCost( const std::string & act, int cost ) { Action * action = actions.get( act ); if ( action->eff == 0 ) action->eff = new And; And * a = dynamic_cast< And * >( action->eff ); a->add( new Increase( cost ) ); } // Add a cost to the action with name "act", in the form of a function void addCost( const std::string & act, const std::string & func, const IntVec & params = IntVec() ) { Action * action = actions.get( act ); if ( action->eff == 0 ) action->eff = new And; And * a = dynamic_cast< And * >( action->eff ); a->add( new Increase( funcs.get( func ), params ) ); } void addFunctionModifier( const std::string & act, FunctionModifier * fm ) { Action * action = actions.get( act ); if ( action->eff == 0 ) action->eff = new And; And * a = dynamic_cast< And * >( action->eff ); a->add( fm ); } // Create a ground condition with the given name Ground * ground( const std::string & name, const IntVec & params = IntVec() ) { if ( preds.index( name ) < 0 ) { std::cout << "Creating a ground condition " << name << params; std::cout << " failed since the predicate " << name << " does not exist!\n"; std::exit( 1 ); } return new Ground( preds[preds.index( name )], params ); } // Return the list of type names corresponding to a parameter list StringVec typeList( ParamCond * c ) { StringVec out; for ( unsigned i = 0; i < c->params.size(); ++i ) out.push_back( types[c->params[i]]->name ); return out; } // Return the list of object names corresponding to a ground fluent StringVec objectList( Ground * g ) { StringVec out; for ( unsigned i = 0; i < g->params.size(); ++i ) out.push_back( types[g->lifted->params[i]]->object( g->params[i] ).first ); return out; } // Add parameters to an action void addParams( const std::string & name, const StringVec & v ) { actions.get( name )->addParams( convertTypes( v ) ); } // Assert that one type is a subtype of another bool assertSubtype( int t1, int t2 ) { for ( Type * type = types[t1]; type != 0; type = type->supertype ) if ( type->name == types[t2]->name ) return 1; return 0; } // Check whether the given string represents a valid constant in the model bool isConstant( const std::string & name) { bool res = false; for (int t = 0; t < types.size() && !res; t++) { for (int c = 0; c < types[t]->constants.size() && !res; c++) { if (types[t]->constants[c] == name) res = true; } } return res; } IntPair constantTypeIdConstId(const std::string & name) { int t, c; bool found = false; for (t = 0; t < types.size() && !found; t++) { for (c = 0; c < types[t]->constants.size() && !found; c++) { if (name == types[t]->constants[c]) found = true; } } if (!found) return IntPair(-1,-1); return IntPair(c-1,t-1); } // return the index of a constant for a given type int constantIndex( const std::string & name, const std::string & type ) { return types.get( type )->parseConstant( name ).second; } friend std::ostream& operator<<(std::ostream &os, const Domain& o) { return o.print(os); } virtual std::ostream& print(std::ostream& os) const { os << "( define ( domain " << name << " )\n"; print_requirements(os); if ( typed ) { os << "( :types\n"; for ( unsigned i = 1; i < types.size(); ++i ) types[i]->PDDLPrint( os ); os << ")\n"; } if ( cons ) { os << "( :constants\n"; for ( unsigned i = 0; i < types.size(); ++i ) if ( types[i]->constants.size() ) { os << "\t"; for ( unsigned j = 0; j < types[i]->constants.size(); ++j ) os << types[i]->constants[j] << " "; if ( typed ) os << "- " << types[i]->name; os << "\n"; } os << ")\n"; } os << "( :predicates\n"; for ( unsigned i = 0; i < preds.size(); ++i ) { preds[i]->PDDLPrint( os, 1, TokenStruct< std::string >(), *this ); os << "\n"; } os << ")\n"; if ( funcs.size() ) { os << "( :functions\n"; for ( unsigned i = 0; i < funcs.size(); ++i ) { funcs[i]->PDDLPrint( os, 1, TokenStruct< std::string >(), *this ); os << "\n"; } os << ")\n"; } for ( unsigned i = 0; i < actions.size(); ++i ) actions[i]->PDDLPrint( os, 0, TokenStruct< std::string >(), *this ); for ( unsigned i = 0; i < derived.size(); ++i ) derived[i]->PDDLPrint( os, 0, TokenStruct< std::string >(), *this ); print_addtional_blocks(os); os << ")\n"; return os; } virtual std::ostream& print_requirements(std::ostream& os) const { os << "( :requirements"; if ( equality ) os << " :equality"; if ( strips ) os << " :strips"; if ( costs ) os << " :action-cost"; if ( adl ) os << " :adl"; if ( neg ) os << " :negative-preconditions"; if ( condeffects ) os << " :conditional-effects"; if ( typed ) os << " :typing"; if ( temp ) os << " :durative-actions"; if ( nondet ) os << " :non-deterministic"; if ( universal ) os << " :universal-preconditions"; if ( fluents ) os << " :fluents"; if ( disj ) os << " :disjuntive-preconditions"; if ( derivedpred ) os << " :derived-predicates"; os << " )\n"; return os; } virtual std::ostream& print_addtional_blocks(std::ostream& os) const { return os; } virtual Condition * createCondition( Stringreader & f ) { std::string s = f.getToken(); if ( s == "and" ) return new And; if ( s == "exists" ) return new Exists; if ( s == "forall" ) return new Forall; if ( s == "assign" ) return new Assign; if ( s == "increase" ) return new Increase; if ( s == "decrease" ) return new Decrease; if ( s == "not" ) return new Not; if ( s == "oneof" ) return new Oneof; if ( s == "or" ) return new Or; if ( s == "when" ) return new When; if ( s == "=" || s == ">=" || s == ">" || s == "<=" || s == "<" ) return new CompositeExpression( s ); int i = preds.index( s ); if ( i >= 0 ) return new Ground( preds[i] ); f.tokenExit( s ); return 0; } }; } } // namespaces