Implemented parsing of PDDL constants.
This commit is contained in:
parent
3c97ced486
commit
25cf7c8ae8
60
include/plasp/pddl/Constant.h
Normal file
60
include/plasp/pddl/Constant.h
Normal file
@ -0,0 +1,60 @@
|
||||
#ifndef __PLASP__PDDL__CONSTANT_H
|
||||
#define __PLASP__PDDL__CONSTANT_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <plasp/pddl/Type.h>
|
||||
#include <plasp/utils/Parser.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Constant
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Context;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Constant
|
||||
{
|
||||
public:
|
||||
static Constant &parse(utils::Parser &parser, Context &context);
|
||||
static Constant &parseDeclaration(utils::Parser &parser, Context &context);
|
||||
|
||||
public:
|
||||
const std::string &name() const;
|
||||
const PrimitiveType *type() const;
|
||||
|
||||
bool isDeclared() const;
|
||||
|
||||
private:
|
||||
Constant(std::string name);
|
||||
|
||||
void setDirty(bool isDirty = true);
|
||||
bool isDirty() const;
|
||||
|
||||
void setDeclared();
|
||||
|
||||
void setType(const PrimitiveType *parentType);
|
||||
|
||||
bool m_isDirty;
|
||||
bool m_isDeclared;
|
||||
|
||||
std::string m_name;
|
||||
|
||||
const PrimitiveType *m_type;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -5,6 +5,7 @@
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include <plasp/pddl/Constant.h>
|
||||
#include <plasp/pddl/Predicate.h>
|
||||
#include <plasp/pddl/Type.h>
|
||||
|
||||
@ -27,6 +28,9 @@ class Context
|
||||
|
||||
std::vector<std::unique_ptr<EitherType>> eitherTypes;
|
||||
|
||||
std::vector<std::unique_ptr<Constant>> constants;
|
||||
std::unordered_map<std::string, Constant *> constantsHashMap;
|
||||
|
||||
std::vector<std::unique_ptr<Predicate>> predicates;
|
||||
std::unordered_map<PredicateHashMapKey, Predicate *> predicatesHashMap;
|
||||
};
|
||||
|
@ -29,6 +29,7 @@ class Domain
|
||||
const std::string &name() const;
|
||||
const Requirements &requirements() const;
|
||||
const std::vector<std::unique_ptr<PrimitiveType>> &types() const;
|
||||
const std::vector<std::unique_ptr<Constant>> &constants() const;
|
||||
const std::vector<std::unique_ptr<Predicate>> &predicates() const;
|
||||
|
||||
private:
|
||||
@ -42,6 +43,8 @@ class Domain
|
||||
|
||||
void parseTypeSection(utils::Parser &parser);
|
||||
|
||||
void parseConstantSection(utils::Parser &parser);
|
||||
|
||||
void parsePredicateSection(utils::Parser &parser);
|
||||
|
||||
void checkConsistency();
|
||||
|
@ -41,7 +41,7 @@ class PrimitiveType
|
||||
|
||||
void setDeclared();
|
||||
|
||||
void addParentType(const PrimitiveType &parentType);
|
||||
void addParentType(const PrimitiveType *parentType);
|
||||
|
||||
bool m_isDirty;
|
||||
bool m_isDeclared;
|
||||
|
146
src/plasp/pddl/Constant.cpp
Normal file
146
src/plasp/pddl/Constant.cpp
Normal file
@ -0,0 +1,146 @@
|
||||
#include <plasp/pddl/Constant.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <plasp/pddl/Context.h>
|
||||
#include <plasp/pddl/Identifier.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Constant
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Constant::Constant(std::string name)
|
||||
: m_isDirty{false},
|
||||
m_isDeclared{false},
|
||||
m_name(name),
|
||||
m_type{nullptr}
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Constant &Constant::parse(utils::Parser &parser, Context &context)
|
||||
{
|
||||
parser.skipWhiteSpace();
|
||||
|
||||
const auto constantName = parser.parseIdentifier(isIdentifier);
|
||||
const auto match = context.constantsHashMap.find(constantName);
|
||||
const auto constantExists = (match != context.constantsHashMap.cend());
|
||||
|
||||
// Return existing primitive types
|
||||
if (constantExists)
|
||||
{
|
||||
auto &constant = *match->second;
|
||||
|
||||
constant.setDirty();
|
||||
|
||||
return constant;
|
||||
}
|
||||
|
||||
// Store new primitive type
|
||||
context.constants.emplace_back(std::make_unique<Constant>(Constant(constantName)));
|
||||
|
||||
auto &constant = *context.constants.back();
|
||||
|
||||
// Add a pointer to the primitive type to the hash map
|
||||
context.constantsHashMap.emplace(std::make_pair(constantName, &constant));
|
||||
|
||||
// Flag type for potentially upcoming parent type declaration
|
||||
constant.setDirty();
|
||||
|
||||
return constant;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Constant &Constant::parseDeclaration(utils::Parser &parser, Context &context)
|
||||
{
|
||||
// Parse and store constant
|
||||
auto &constant = parse(parser, context);
|
||||
|
||||
// Flag constant as correctly declared in the types section
|
||||
constant.setDeclared();
|
||||
|
||||
parser.skipWhiteSpace();
|
||||
|
||||
// Check for typing information
|
||||
if (!parser.advanceIf('-'))
|
||||
return constant;
|
||||
|
||||
// If existing, parse and store parent type
|
||||
auto &type = PrimitiveType::parse(parser, context);
|
||||
|
||||
// Assign parent type to all types that were previously flagged
|
||||
std::for_each(context.constants.begin(), context.constants.end(),
|
||||
[&](auto &constant)
|
||||
{
|
||||
if (!constant->isDirty())
|
||||
return;
|
||||
|
||||
constant->setType(&type);
|
||||
constant->setDirty(false);
|
||||
});
|
||||
|
||||
return constant;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Constant::setDirty(bool isDirty)
|
||||
{
|
||||
m_isDirty = isDirty;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool Constant::isDirty() const
|
||||
{
|
||||
return m_isDirty;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Constant::setDeclared()
|
||||
{
|
||||
m_isDeclared = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool Constant::isDeclared() const
|
||||
{
|
||||
return m_isDeclared;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::string &Constant::name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Constant::setType(const PrimitiveType *type)
|
||||
{
|
||||
m_type = type;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const PrimitiveType *Constant::type() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
@ -74,6 +74,13 @@ const std::vector<std::unique_ptr<PrimitiveType>> &Domain::types() const
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::vector<std::unique_ptr<Constant>> &Domain::constants() const
|
||||
{
|
||||
return m_context.constants;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::vector<std::unique_ptr<Predicate>> &Domain::predicates() const
|
||||
{
|
||||
return m_context.predicates;
|
||||
@ -116,7 +123,7 @@ void Domain::parseSection(utils::Parser &parser)
|
||||
else if (sectionIdentifier == "types")
|
||||
parseTypeSection(parser);
|
||||
else if (sectionIdentifier == "constants")
|
||||
skipSection();
|
||||
parseConstantSection(parser);
|
||||
else if (sectionIdentifier == "predicates")
|
||||
parsePredicateSection(parser);
|
||||
else if (sectionIdentifier == "functions")
|
||||
@ -125,6 +132,10 @@ void Domain::parseSection(utils::Parser &parser)
|
||||
skipSection();
|
||||
else if (sectionIdentifier == "action")
|
||||
skipSection();
|
||||
else if (sectionIdentifier == "durative-action")
|
||||
skipSection();
|
||||
else if (sectionIdentifier == "derived")
|
||||
skipSection();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -228,6 +239,23 @@ void Domain::parseTypeSection(utils::Parser &parser)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Domain::parseConstantSection(utils::Parser &parser)
|
||||
{
|
||||
parser.skipWhiteSpace();
|
||||
|
||||
// Store constants
|
||||
while (parser.currentCharacter() != ')')
|
||||
{
|
||||
Constant::parseDeclaration(parser, m_context);
|
||||
|
||||
parser.skipWhiteSpace();
|
||||
}
|
||||
|
||||
parser.expect<std::string>(")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Domain::parsePredicateSection(utils::Parser &parser)
|
||||
{
|
||||
parser.skipWhiteSpace();
|
||||
@ -263,6 +291,17 @@ void Domain::checkConsistency()
|
||||
throw ConsistencyException("Type \"" + type->name() + "\" used but never declared");
|
||||
});
|
||||
|
||||
// Verify that all used constants have been declared
|
||||
std::for_each(m_context.constants.cbegin(), m_context.constants.cend(),
|
||||
[&](const auto &constant)
|
||||
{
|
||||
if (!constant->isDeclared())
|
||||
throw ConsistencyException("Constant \"" + constant->name() + "\" used but never declared");
|
||||
|
||||
if (constant->type() == nullptr)
|
||||
throw ConsistencyException("Constant \"" + constant->name() + "\" has an undeclared type");
|
||||
});
|
||||
|
||||
// Verify that all used predicates have been declared
|
||||
std::for_each(m_context.predicates.cbegin(), m_context.predicates.cend(),
|
||||
[&](const auto &predicate)
|
||||
|
@ -89,7 +89,7 @@ PrimitiveType &PrimitiveType::parseDeclaration(utils::Parser &parser, Context &c
|
||||
if (!childType->isDirty())
|
||||
return;
|
||||
|
||||
childType->addParentType(parentType);
|
||||
childType->addParentType(&parentType);
|
||||
childType->setDirty(false);
|
||||
});
|
||||
|
||||
@ -133,9 +133,9 @@ const std::string &PrimitiveType::name() const
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void PrimitiveType::addParentType(const PrimitiveType &parentType)
|
||||
void PrimitiveType::addParentType(const PrimitiveType *parentType)
|
||||
{
|
||||
m_parentTypes.emplace_back(&parentType);
|
||||
m_parentTypes.push_back(parentType);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -14,7 +14,8 @@ class PDDLParserTests : public ::testing::Test
|
||||
protected:
|
||||
PDDLParserTests()
|
||||
: m_blocksworldDomainFile(readFile("data/blocksworld-domain.pddl")),
|
||||
m_storageDomainFile(readFile("data/storage-domain.pddl"))
|
||||
m_storageDomainFile(readFile("data/storage-domain.pddl")),
|
||||
m_woodworkingDomainFile(readFile("data/woodworking-domain.pddl"))
|
||||
{
|
||||
}
|
||||
|
||||
@ -34,6 +35,7 @@ class PDDLParserTests : public ::testing::Test
|
||||
|
||||
std::stringstream m_blocksworldDomainFile;
|
||||
std::stringstream m_storageDomainFile;
|
||||
std::stringstream m_woodworkingDomainFile;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -155,3 +157,37 @@ TEST_F(PDDLParserTests, ParseStorageDomain)
|
||||
FAIL() << e.what();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TEST_F(PDDLParserTests, ParseConstants)
|
||||
{
|
||||
try
|
||||
{
|
||||
const auto description = plasp::pddl::Description::fromStream(m_woodworkingDomainFile);
|
||||
|
||||
ASSERT_NO_THROW(description.domain());
|
||||
|
||||
const auto &domain = description.domain();
|
||||
|
||||
// Name
|
||||
ASSERT_EQ(domain.name(), "woodworking");
|
||||
|
||||
// Types
|
||||
const auto &acolour = *domain.types()[0];
|
||||
const auto &surface = *domain.types()[4];
|
||||
const auto &treatmentstatus = *domain.types()[5];
|
||||
|
||||
// Constants
|
||||
ASSERT_EQ(domain.constants().size(), 8u);
|
||||
ASSERT_EQ(domain.constants()[0]->type(), &surface);
|
||||
ASSERT_EQ(domain.constants()[2]->type(), &surface);
|
||||
ASSERT_EQ(domain.constants()[3]->type(), &treatmentstatus);
|
||||
ASSERT_EQ(domain.constants()[6]->type(), &treatmentstatus);
|
||||
ASSERT_EQ(domain.constants()[7]->type(), &acolour);
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
FAIL() << e.what();
|
||||
}
|
||||
}
|
||||
|
215
tests/data/woodworking-domain.pddl
Normal file
215
tests/data/woodworking-domain.pddl
Normal file
@ -0,0 +1,215 @@
|
||||
(define (domain woodworking)
|
||||
(:requirements :typing :durative-actions :numeric-fluents)
|
||||
(:types
|
||||
acolour awood woodobj machine
|
||||
surface treatmentstatus - object
|
||||
highspeed-saw glazer grinder immersion-varnisher
|
||||
planer saw spray-varnisher - machine
|
||||
board part - woodobj)
|
||||
|
||||
(:constants
|
||||
verysmooth smooth rough - surface
|
||||
varnished glazed untreated colourfragments - treatmentstatus
|
||||
natural - acolour)
|
||||
|
||||
(:predicates
|
||||
(idle ?machine - machine)
|
||||
(unused ?obj - part)
|
||||
(available ?obj - woodobj)
|
||||
|
||||
(surface-condition ?obj - woodobj ?surface - surface)
|
||||
(treatment ?obj - part ?treatment - treatmentstatus)
|
||||
(colour ?obj - part ?colour - acolour)
|
||||
(wood ?obj - woodobj ?wood - awood)
|
||||
|
||||
(in-highspeed-saw ?b - board ?m - highspeed-saw)
|
||||
(empty ?m - highspeed-saw)
|
||||
(has-colour ?machine - machine ?colour - acolour)
|
||||
(grind-treatment-change ?old ?new - treatmentstatus)
|
||||
(is-smooth ?surface - surface))
|
||||
|
||||
(:functions
|
||||
(board-size ?board - board)
|
||||
(goal-size ?obj - part))
|
||||
|
||||
(:durative-action do-immersion-varnish
|
||||
:parameters (?x - part ?m - immersion-varnisher
|
||||
?newcolour - acolour ?surface - surface)
|
||||
:duration (= ?duration 10)
|
||||
:condition (and
|
||||
(at start (idle ?m))
|
||||
(at start (available ?x))
|
||||
(at start (surface-condition ?x ?surface))
|
||||
(at start (is-smooth ?surface))
|
||||
(at start (has-colour ?m ?newcolour))
|
||||
(at start (treatment ?x untreated)))
|
||||
:effect (and
|
||||
(at start (not (idle ?m)))
|
||||
(at start (not (available ?x)))
|
||||
(at start (not (treatment ?x untreated)))
|
||||
(at start (not (colour ?x natural)))
|
||||
(at end (idle ?m))
|
||||
(at end (available ?x))
|
||||
(at end (treatment ?x varnished))
|
||||
(at end (colour ?x ?newcolour))))
|
||||
|
||||
(:durative-action do-spray-varnish
|
||||
:parameters (?x - part ?m - spray-varnisher
|
||||
?newcolour - acolour ?surface - surface)
|
||||
:duration (= ?duration (goal-size ?x))
|
||||
:condition (and
|
||||
(at start (idle ?m))
|
||||
(at start (available ?x))
|
||||
(at start (surface-condition ?x ?surface))
|
||||
(at start (is-smooth ?surface))
|
||||
(at start (has-colour ?m ?newcolour))
|
||||
(at start (treatment ?x untreated)))
|
||||
:effect (and
|
||||
(at start (not (idle ?m)))
|
||||
(at start (not (available ?x)))
|
||||
(at start (not (treatment ?x untreated)))
|
||||
(at start (not (colour ?x natural)))
|
||||
(at end (idle ?m))
|
||||
(at end (available ?x))
|
||||
(at end (treatment ?x varnished))
|
||||
(at end (colour ?x ?newcolour))))
|
||||
|
||||
(:durative-action do-glaze
|
||||
:parameters (?x - part ?m - glazer
|
||||
?newcolour - acolour)
|
||||
:duration (= ?duration (+ (goal-size ?x) 5))
|
||||
:condition (and
|
||||
(at start (idle ?m))
|
||||
(at start (available ?x))
|
||||
(at start (has-colour ?m ?newcolour))
|
||||
(at start (treatment ?x untreated)))
|
||||
:effect (and
|
||||
(at start (not (idle ?m)))
|
||||
(at start (not (available ?x)))
|
||||
(at start (not (treatment ?x untreated)))
|
||||
(at start (not (colour ?x natural)))
|
||||
(at end (idle ?m))
|
||||
(at end (available ?x))
|
||||
(at end (treatment ?x glazed))
|
||||
(at end (colour ?x ?newcolour))))
|
||||
|
||||
(:durative-action do-grind
|
||||
:parameters (?x - part ?m - grinder ?oldsurface - surface
|
||||
?oldcolour - acolour
|
||||
?oldtreatment ?newtreatment - treatmentstatus)
|
||||
:duration (= ?duration (* 3 (goal-size ?x)))
|
||||
:condition (and
|
||||
(at start (idle ?m))
|
||||
(at start (available ?x))
|
||||
(at start (surface-condition ?x ?oldsurface))
|
||||
(at start (is-smooth ?oldsurface))
|
||||
(at start (colour ?x ?oldcolour))
|
||||
(at start (treatment ?x ?oldtreatment))
|
||||
(at start (grind-treatment-change ?oldtreatment ?newtreatment)))
|
||||
:effect (and
|
||||
(at start (not (idle ?m)))
|
||||
(at start (not (available ?x)))
|
||||
(at start (not (surface-condition ?x ?oldsurface)))
|
||||
(at start (not (treatment ?x ?oldtreatment)))
|
||||
(at start (not (colour ?x ?oldcolour)))
|
||||
(at end (idle ?m))
|
||||
(at end (available ?x))
|
||||
(at end (surface-condition ?x verysmooth))
|
||||
(at end (treatment ?x ?newtreatment))
|
||||
(at end (colour ?x natural))))
|
||||
|
||||
(:durative-action do-plane
|
||||
:parameters (?x - part ?m - planer ?oldsurface - surface
|
||||
?oldcolour - acolour ?oldtreatment - treatmentstatus)
|
||||
:duration (= ?duration (* 2 (goal-size ?x)))
|
||||
:condition (and
|
||||
(at start (idle ?m))
|
||||
(at start (available ?x))
|
||||
(at start (surface-condition ?x ?oldsurface))
|
||||
(at start (treatment ?x ?oldtreatment))
|
||||
(at start (colour ?x ?oldcolour)))
|
||||
:effect (and
|
||||
(at start (not (idle ?m)))
|
||||
(at start (not (available ?x)))
|
||||
(at start (not (surface-condition ?x ?oldsurface)))
|
||||
(at start (not (treatment ?x ?oldtreatment)))
|
||||
(at start (not (colour ?x ?oldcolour)))
|
||||
(at end (idle ?m))
|
||||
(at end (available ?x))
|
||||
(at end (surface-condition ?x smooth))
|
||||
(at end (treatment ?x untreated))
|
||||
(at end (colour ?x natural))))
|
||||
|
||||
(:durative-action load-highspeed-saw
|
||||
:parameters (?b - board ?m - highspeed-saw)
|
||||
:duration (= ?duration 30)
|
||||
:condition (and
|
||||
(at start (idle ?m))
|
||||
(at start (empty ?m))
|
||||
(at start (available ?b)))
|
||||
:effect (and
|
||||
(at start (not (idle ?m)))
|
||||
(at start (not (available ?b)))
|
||||
(at start (not (empty ?m)))
|
||||
(at end (idle ?m))
|
||||
(at end (in-highspeed-saw ?b ?m))))
|
||||
|
||||
(:durative-action unload-highspeed-saw
|
||||
:parameters (?b - board ?m - highspeed-saw)
|
||||
:duration (= ?duration 10)
|
||||
:condition (and
|
||||
(at start (idle ?m))
|
||||
(at start (in-highspeed-saw ?b ?m)))
|
||||
:effect (and
|
||||
(at start (not (idle ?m)))
|
||||
(at end (available ?b))
|
||||
(at end (not (in-highspeed-saw ?b ?m)))
|
||||
(at end (empty ?m))
|
||||
(at end (idle ?m))))
|
||||
|
||||
(:durative-action cut-board
|
||||
:parameters (?b - board ?p - part ?m - highspeed-saw ?w - awood
|
||||
?surface - surface)
|
||||
:duration (= ?duration 10)
|
||||
:condition (and
|
||||
(at start (idle ?m))
|
||||
(at start (unused ?p))
|
||||
(at start (in-highspeed-saw ?b ?m))
|
||||
(at start (wood ?b ?w))
|
||||
(at start (surface-condition ?b ?surface))
|
||||
(at start (>= (board-size ?b) (goal-size ?p))))
|
||||
:effect (and
|
||||
(at start (not (idle ?m)))
|
||||
(at start (not (unused ?p)))
|
||||
(at start (decrease (board-size ?b) (goal-size ?p)))
|
||||
(at end (idle ?m))
|
||||
(at end (available ?p))
|
||||
(at end (wood ?p ?w))
|
||||
(at end (surface-condition ?p ?surface))
|
||||
(at end (colour ?p natural))
|
||||
(at end (treatment ?p untreated))))
|
||||
|
||||
(:durative-action do-saw
|
||||
:parameters (?b - board ?p - part ?m - saw ?w - awood
|
||||
?surface - surface)
|
||||
:duration (= ?duration 30)
|
||||
:condition (and
|
||||
(at start (idle ?m))
|
||||
(at start (unused ?p))
|
||||
(at start (available ?b))
|
||||
(at start (wood ?b ?w))
|
||||
(at start (surface-condition ?b ?surface))
|
||||
(at start (>= (board-size ?b) (goal-size ?p))))
|
||||
:effect (and
|
||||
(at start (not (idle ?m)))
|
||||
(at start (not (unused ?p)))
|
||||
(at start (not (available ?b)))
|
||||
(at end (decrease (board-size ?b) (goal-size ?p)))
|
||||
(at end (idle ?m))
|
||||
(at end (available ?p))
|
||||
(at end (available ?b))
|
||||
(at end (wood ?p ?w))
|
||||
(at end (surface-condition ?p ?surface))
|
||||
(at end (colour ?p natural))
|
||||
(at end (treatment ?p untreated))))
|
||||
)
|
Reference in New Issue
Block a user