Program Listing for File Instance.h
↰ Return to documentation for file (/tmp/ws/src/ros2_planning_system/plansys2_pddl_parser/include/plansys2_pddl_parser/Instance.h
)
#pragma once
#include "plansys2_pddl_parser/Domain.h"
namespace parser { namespace pddl {
class Instance {
public:
Domain &d;
std::string name;
GroundVec init, goal; // initial and goal states
bool metric;
Instance( Domain & dom ) : d( dom ), metric( false ) {}
Instance( Domain & dom, const std::string & s ) : Instance(dom)
{
parse(s);
}
virtual ~Instance() {
for ( unsigned i = 0; i < init.size(); ++i )
delete init[i];
for ( unsigned i = 0; i < goal.size(); ++i )
delete goal[i];
}
void parse( const std::string &s) {
Stringreader f( s );
name = f.parseName( "problem" );
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 ( t == "domain" ) parseDomain( f );
else if ( t == "objects" ) parseObjects( f );
else if ( t == "init" ) parseInit( f );
else if ( t == "goal" ) parseGoal( f );
else if ( t == "metric" ) parseMetric( f );
else f.tokenExit( t );
}
}
std::string getDomainName( const std::string &s) {
std::string domain_name = "";
Stringreader f( s );
f.parseName( "problem" );
for ( ; f.getChar() != ')'; f.next() ) {
f.assert_token( "(" );
f.assert_token( ":" );
std::string t = f.getToken();
if ( t == "domain" ) {
f.next();
domain_name = f.getToken();
break;
}
}
return domain_name;
}
void parseDomain( Stringreader & f ) {
f.next();
f.assert_token( d.name );
f.assert_token( ")" );
}
void parseObjects( Stringreader & f ) {
TokenStruct< std::string > ts = f.parseTypedList( true, d.types );
for ( unsigned i = 0; i < ts.size(); ++i ) {
Type * type = d.getType( ts.types[i] );
std::pair< bool, unsigned > pair = type->parseObject( ts[i] );
if ( pair.first == false )
type->objects.insert( ts[i] );
}
for ( unsigned i = 0; DOMAIN_DEBUG && i < d.types.size(); ++i ) {
std::cout << " ";
if ( d.typed ) std::cout << " " << d.types[i] << ":";
for ( unsigned j = 0; j < d.types[i]->objects.size(); ++j )
std::cout << " " << d.types[i]->objects[j];
std::cout << "\n";
}
}
virtual void parseGround( Stringreader & f, GroundVec & v ) {
TypeGround * c = 0;
if ( f.getChar() == '=') {
f.assert_token( "=" );
f.assert_token( "(" );
std::string s = f.getToken();
int i = d.funcs.index( s );
if ( i < 0 ) f.tokenExit( s );
if ( d.funcs[i]->returnType < 0 ) c = new GroundFunc< double >( d.funcs[i] );
else c = new GroundFunc< int >( d.funcs[i] );
}
else c = new TypeGround( d.preds.get( f.getToken( d.preds ) ) );
c->parse( f, d.types[0]->constants, d );
v.push_back( c );
}
void parseInit( Stringreader & f ) {
for ( f.next(); f.getChar() != ')'; f.next() ) {
f.assert_token( "(" );
parseGround( f, init );
}
++f.c;
for ( unsigned i = 0; DOMAIN_DEBUG && i < init.size(); ++i )
std::cout << " " << init[i];
}
virtual void parseGoal( Stringreader & f ) {
f.next();
f.assert_token( "(" );
std::string s = f.getToken();
if ( s == "and" ) {
for ( f.next(); f.getChar() != ')'; f.next() ) {
f.assert_token( "(" );
parseGround( f, goal );
}
++f.c;
f.next();
}
else {
f.c -= s.size();
parseGround( f, goal );
}
f.assert_token( ")" );
for ( unsigned i = 0; DOMAIN_DEBUG && i < goal.size(); ++i ) std::cout << " " << goal[i];
}
// for the moment only parse total-cost/total-time
void parseMetric( Stringreader & f ) {
if ( !d.temp && !d.costs ) {
std::cerr << "metric only defined for temporal actions or actions with costs!\n";
std::exit( 1 );
}
metric = true;
f.next();
f.assert_token( "minimize" );
f.assert_token( "(" );
if ( d.temp ) f.assert_token( "total-time" );
else f.assert_token( "total-cost" );
f.assert_token( ")" );
f.assert_token( ")" );
}
// add an object of a certain type
void addObject( const std::string & name, const std::string & type ) {
d.getType( type )->objects.insert( name );
}
// add a predicate fluent to the initial state
void addInit( const std::string & name, const StringVec & v = StringVec() ) {
TypeGround * tg = new TypeGround( d.preds.get( name ) );
tg->insert( d, v );
init.push_back( tg );
}
// add a function value to the initial state
void addInit( const std::string & name, int value, const StringVec & v = StringVec() ) {
GroundFunc< int > * gf = new GroundFunc< int >( d.funcs.get( name ), value );
gf->insert( d, v );
init.push_back( gf );
}
// add a function value to the initial state
void addInit( const std::string & name, double value, const StringVec & v = StringVec() ) {
GroundFunc< double > * gf = new GroundFunc< double >( d.funcs.get( name ), value );
gf->insert( d, v );
init.push_back( gf );
}
// add a fluent (predicate or function) to the initial state
void addInit( TypeGround * g, const StringVec & v = StringVec() ) {
TypeGround * tg = 0;
GroundFunc< int > * f1 = dynamic_cast< GroundFunc< int > * >( g );
GroundFunc< double > * f2 = dynamic_cast< GroundFunc< double > * >( g );
if ( f1 ) tg = new GroundFunc< int >( d.funcs.get( g->name ), f1->value );
else if ( f2 ) tg = new GroundFunc< double >( d.funcs.get( g->name ), f2->value );
else tg = new TypeGround( d.preds.get( g->name ) );
tg->insert( d, v );
init.push_back( tg );
}
// add a fluent to the goal state
void addGoal( const std::string & name, const StringVec & v = StringVec() ) {
TypeGround * tg = new TypeGround( d.preds.get( name ) );
tg->insert( d, v );
goal.push_back( tg );
}
friend std::ostream& operator<<(std::ostream &os, const Instance& o) { return o.print(os); }
virtual std::ostream& print(std::ostream& stream) const {
stream << "( define ( problem " << name << " )\n";
stream << "( :domain " << d.name << " )\n";
stream << "( :objects\n";
for ( unsigned i = 0; i < d.types.size(); ++i )
if ( d.types[i]->objects.size() ) {
stream << "\t";
for ( unsigned j = 0; j < d.types[i]->objects.size(); ++j )
stream << d.types[i]->objects[j] << " ";
if ( d.typed ) stream << "- " << d.types[i]->name;
stream << "\n";
}
stream << ")\n";
stream << "( :init\n";
for ( unsigned i = 0; i < init.size(); ++i ) {
( (TypeGround*)init[i])->PDDLPrint( stream, 1, TokenStruct< std::string >(), d );
stream << "\n";
}
stream << ")\n";
stream << "( :goal\n";
stream << "\t( and\n";
for ( unsigned i = 0; i < goal.size(); ++i ) {
( (TypeGround*)goal[i])->PDDLPrint( stream, 2, TokenStruct< std::string >(), d );
stream << "\n";
}
stream << "\t)\n";
stream << ")\n";
if ( metric ) {
stream << "( :metric minimize ( total-";
if ( d.temp ) stream << "time";
else stream << "cost";
stream << " ) )\n";
}
stream << ")\n";
return stream;
}
};
} } // namespaces