diff --git a/include/plasp/pddl/Domain.h b/include/plasp/pddl/Domain.h index d9261ca..42bcc56 100644 --- a/include/plasp/pddl/Domain.h +++ b/include/plasp/pddl/Domain.h @@ -26,7 +26,8 @@ class Domain Domain(Context &context); public: - void readPDDL(); + void findSections(); + void parse(); void setName(std::string name); const std::string &name() const; @@ -66,10 +67,20 @@ class Domain Context &m_context; std::string m_name; + + utils::Parser::Position m_requirementsPosition; Requirements m_requirements; - expressions::PrimitiveTypes m_primitiveTypes; + + utils::Parser::Position m_typesPosition; + expressions::PrimitiveTypes m_types; + + utils::Parser::Position m_constantsPosition; expressions::Constants m_constants; - expressions::PredicateDeclarations m_predicateDeclarations; + + utils::Parser::Position m_predicatesPosition; + expressions::PredicateDeclarations m_predicates; + + std::vector m_actionPositions; std::vector> m_actions; }; diff --git a/include/plasp/pddl/expressions/InitialState.h b/include/plasp/pddl/InitialState.h similarity index 68% rename from include/plasp/pddl/expressions/InitialState.h rename to include/plasp/pddl/InitialState.h index ff94409..fbbd5f8 100644 --- a/include/plasp/pddl/expressions/InitialState.h +++ b/include/plasp/pddl/InitialState.h @@ -7,20 +7,27 @@ namespace plasp { namespace pddl { -namespace expressions + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// InitialState +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +class InitialState { + public: + static std::unique_ptr parseDeclaration(Context &context, const Problem &problem); -//////////////////////////////////////////////////////////////////////////////////////////////////// -// -// Type -// -//////////////////////////////////////////////////////////////////////////////////////////////////// + public: + const Expressions &facts() const; -ExpressionPointer parseInitialState(Context &context); + private: + Expressions m_facts; +}; //////////////////////////////////////////////////////////////////////////////////////////////////// -} } } diff --git a/include/plasp/pddl/Problem.h b/include/plasp/pddl/Problem.h index c360b5b..37bae97 100644 --- a/include/plasp/pddl/Problem.h +++ b/include/plasp/pddl/Problem.h @@ -3,6 +3,7 @@ #include #include +#include #include namespace plasp @@ -21,7 +22,7 @@ class Problem public: Problem(Context &context, Domain &domain); - void readPDDL(); + void parse(); bool isDeclared() const; @@ -37,6 +38,9 @@ class Problem expressions::Constants &objects(); const expressions::Constants &objects() const; + InitialState &initialState(); + const InitialState &initialState() const; + void checkConsistency(); private: @@ -49,6 +53,8 @@ class Problem void parseObjectSection(); + void parseInitialStateSection(); + Context &m_context; Domain &m_domain; bool m_isDeclared; @@ -57,6 +63,8 @@ class Problem Requirements m_requirements; expressions::Constants m_objects; + + std::unique_ptr m_initialState; }; //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/include/plasp/pddl/expressions/Constant.h b/include/plasp/pddl/expressions/Constant.h index 4051a03..bd642cc 100644 --- a/include/plasp/pddl/expressions/Constant.h +++ b/include/plasp/pddl/expressions/Constant.h @@ -27,7 +27,8 @@ class Constant: public Expression static void parseTypedDeclaration(Context &context, Problem &problem); static void parseTypedDeclarations(Context &context, Problem &problem); - static Constant *parseAndFind(Context &context, const ExpressionContext &expressionContext); + static Constant *parseAndFind(Context &context, const Domain &domain); + static Constant *parseAndFind(Context &context, const Problem &problem); public: void accept(ExpressionVisitor &expressionVisitor) const override; diff --git a/include/plasp/pddl/expressions/Predicate.h b/include/plasp/pddl/expressions/Predicate.h index c71e1d7..14dc971 100644 --- a/include/plasp/pddl/expressions/Predicate.h +++ b/include/plasp/pddl/expressions/Predicate.h @@ -21,6 +21,7 @@ class Predicate: public Expression public: static PredicatePointer parse(std::string name, Context &context, ExpressionContext &expressionContext); + static PredicatePointer parse(std::string name, Context &context, const Problem &problem); public: void accept(ExpressionVisitor &expressionVisitor) const override; diff --git a/src/plasp/pddl/Description.cpp b/src/plasp/pddl/Description.cpp index fd3f5fe..8566402 100644 --- a/src/plasp/pddl/Description.cpp +++ b/src/plasp/pddl/Description.cpp @@ -106,12 +106,12 @@ void Description::parseContent() throw ConsistencyException("No PDDL domain specified"); m_context.parser.seek(m_domainPosition); - m_domain->readPDDL(); + m_domain->parse(); if (m_problemPosition != -1) { m_context.parser.seek(m_problemPosition); - m_problem->readPDDL(); + m_problem->parse(); } } @@ -119,41 +119,45 @@ void Description::parseContent() void Description::findSections() { - while (true) + auto &parser = m_context.parser; + + parser.skipWhiteSpace(); + + while (!parser.atEndOfStream()) { - m_context.parser.skipWhiteSpace(); + const auto position = parser.position(); - if (m_context.parser.atEndOfStream()) - return; + parser.expect("("); + parser.expect("define"); + parser.expect("("); - const auto position = m_context.parser.position(); - - m_context.parser.expect("("); - m_context.parser.expect("define"); - m_context.parser.expect("("); - - if (m_context.parser.probe("domain")) + if (parser.probe("domain")) { if (m_domainPosition != -1) - throw utils::ParserException(m_context.parser, "PDDL description may not contain two domains"); + throw utils::ParserException(parser, "PDDL description may not contain two domains"); m_domainPosition = position; + + parser.seek(position); + m_domain->findSections(); } else if (m_context.parser.probe("problem")) { if (m_problemPosition != -1) - throw utils::ParserException(m_context.parser, "PDDL description may currently not contain two problems"); + throw utils::ParserException(parser, "PDDL description may currently not contain two problems"); m_problemPosition = position; + + skipSection(parser); + skipSection(parser); } else { - const auto sectionIdentifier = m_context.parser.parse(); - throw utils::ParserException(m_context.parser, "Unknown PDDL section \"" + sectionIdentifier + "\""); + const auto sectionIdentifier = parser.parse(); + throw utils::ParserException(parser, "Unknown PDDL section \"" + sectionIdentifier + "\""); } - skipSection(m_context.parser); - skipSection(m_context.parser); + m_context.parser.skipWhiteSpace(); } } diff --git a/src/plasp/pddl/Domain.cpp b/src/plasp/pddl/Domain.cpp index 9e0a50b..c0332ea 100644 --- a/src/plasp/pddl/Domain.cpp +++ b/src/plasp/pddl/Domain.cpp @@ -11,6 +11,7 @@ #include #include #include +#include namespace plasp { @@ -24,35 +25,129 @@ namespace pddl //////////////////////////////////////////////////////////////////////////////////////////////////// Domain::Domain(Context &context) -: m_context(context) +: m_context(context), + m_requirementsPosition{-1}, + m_typesPosition{-1}, + m_constantsPosition{-1}, + m_predicatesPosition{-1} { } //////////////////////////////////////////////////////////////////////////////////////////////////// -void Domain::readPDDL() +void Domain::findSections() { - m_context.parser.expect("("); - m_context.parser.expect("define"); - m_context.parser.expect("("); - m_context.parser.expect("domain"); + auto &parser = m_context.parser; + + parser.expect("("); + parser.expect("define"); + parser.expect("("); + parser.expect("domain"); m_name = m_context.parser.parseIdentifier(isIdentifier); + std::cout << "Found domain " << m_name << std::endl; + + parser.expect(")"); + + const auto setSectionPosition = + [&](const std::string §ionName, auto §ionPosition, const auto value, bool unique = false) + { + if (unique && sectionPosition != -1) + throw utils::ParserException(parser, "Only one \":" + sectionName + "\" section allowed"); + + sectionPosition = value; + }; + + parser.skipWhiteSpace(); + + // Find sections + while (parser.currentCharacter() != ')') + { + const auto position = parser.position(); + + parser.expect("("); + parser.expect(":"); + + // Save the parser position of the individual sections for later parsing + if (parser.probe("requirements")) + setSectionPosition("requirements", m_requirementsPosition, position, true); + else if (parser.probe("types")) + setSectionPosition("types", m_typesPosition, position, true); + else if (parser.probe("constants")) + setSectionPosition("constants", m_constantsPosition, position, true); + else if (parser.probe("predicates")) + setSectionPosition("predicates", m_predicatesPosition, position, true); + else if (parser.probe("action")) + { + m_actionPositions.emplace_back(-1); + setSectionPosition("action", m_actionPositions.back(), position); + } + else if (parser.probe("functions") + || parser.probe("constraints") + || parser.probe("durative-action") + || parser.probe("derived")) + { + parser.seek(position); + m_context.logger.parserWarning(parser, "Section type currently unsupported"); + parser.advance(); + } + else + { + const auto sectionIdentifier = parser.parseIdentifier(isIdentifier); + + parser.seek(position); + throw utils::ParserException(m_context.parser, "Unknown domain section \"" + sectionIdentifier + "\""); + } + + // Skip section for now and parse it later + skipSection(parser); + + parser.skipWhiteSpace(); + } + + parser.expect(")"); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void Domain::parse() +{ + auto &parser = m_context.parser; + std::cout << "Parsing domain " << m_name << std::endl; - m_context.parser.expect(")"); - - while (true) + if (m_requirementsPosition != -1) { - m_context.parser.skipWhiteSpace(); - - if (m_context.parser.probe(')')) - break; - - parseSection(); + parser.seek(m_requirementsPosition); + parseRequirementSection(); } + if (m_typesPosition != -1) + { + parser.seek(m_typesPosition); + parseTypeSection(); + } + + if (m_constantsPosition != -1) + { + parser.seek(m_constantsPosition); + parseConstantSection(); + } + + if (m_predicatesPosition != -1) + { + parser.seek(m_predicatesPosition); + parsePredicateSection(); + } + + for (size_t i = 0; i < m_actionPositions.size(); i++) + if (m_actionPositions[i] != -1) + { + parser.seek(m_actionPositions[i]); + parseActionSection(); + } + computeDerivedRequirements(); } @@ -81,14 +176,14 @@ const Requirements &Domain::requirements() const expressions::PrimitiveTypes &Domain::types() { - return m_primitiveTypes; + return m_types; } //////////////////////////////////////////////////////////////////////////////////////////////////// const expressions::PrimitiveTypes &Domain::types() const { - return m_primitiveTypes; + return m_types; } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -109,14 +204,14 @@ const expressions::Constants &Domain::constants() const expressions::PredicateDeclarations &Domain::predicates() { - return m_predicateDeclarations; + return m_predicates; } //////////////////////////////////////////////////////////////////////////////////////////////////// const expressions::PredicateDeclarations &Domain::predicates() const { - return m_predicateDeclarations; + return m_predicates; } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -135,52 +230,21 @@ const std::vector> &Domain::actions() const //////////////////////////////////////////////////////////////////////////////////////////////////// -void Domain::parseSection() +void Domain::parseRequirementSection() { auto &parser = m_context.parser; parser.expect("("); parser.expect(":"); + parser.expect("requirements"); - // TODO: check order of the sections - if (parser.probe("requirements")) - parseRequirementSection(); - else if (parser.probe("types")) - parseTypeSection(); - else if (parser.probe("constants")) - parseConstantSection(); - else if (parser.probe("predicates")) - parsePredicateSection(); - else if (parser.probe("action")) - parseActionSection(); - else if (parser.probe("functions") - || parser.probe("constraints") - || parser.probe("durative-action") - || parser.probe("derived")) + while (parser.currentCharacter() != ')') { - std::cout << "Skipping section" << std::endl; - skipSection(m_context.parser); - } - else - { - const auto sectionIdentifier = parser.parseIdentifier(isIdentifier); - throw utils::ParserException(m_context.parser, "Unknown domain section \"" + sectionIdentifier + "\""); - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void Domain::parseRequirementSection() -{ - m_context.parser.skipWhiteSpace(); - - while (m_context.parser.currentCharacter() != ')') - { - m_context.parser.expect(":"); + parser.expect(":"); m_requirements.emplace_back(Requirement::parse(m_context)); - m_context.parser.skipWhiteSpace(); + parser.skipWhiteSpace(); } // TODO: do this check only once the problem is parsed @@ -188,7 +252,7 @@ void Domain::parseRequirementSection() if (m_requirements.empty()) m_requirements.emplace_back(Requirement::Type::STRIPS); - m_context.parser.expect(")"); + parser.expect(")"); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -258,60 +322,82 @@ void Domain::computeDerivedRequirements() void Domain::parseTypeSection() { + auto &parser = m_context.parser; + + parser.expect("("); + parser.expect(":"); + parser.expect("types"); + checkRequirement(Requirement::Type::Typing); - m_context.parser.skipWhiteSpace(); + parser.skipWhiteSpace(); // Store types and their parent types - while (!m_context.parser.probe(')')) + while (parser.currentCharacter() != ')') { - if (m_context.parser.currentCharacter() == '(') - throw utils::ParserException(m_context.parser, "Only primitive types are allowed in type section"); + if (parser.currentCharacter() == '(') + throw utils::ParserException(parser, "Only primitive types are allowed in type section"); expressions::PrimitiveType::parseTypedDeclaration(m_context, *this); - m_context.parser.skipWhiteSpace(); + parser.skipWhiteSpace(); } + + parser.expect(")"); } //////////////////////////////////////////////////////////////////////////////////////////////////// void Domain::parseConstantSection() { - m_context.parser.skipWhiteSpace(); + auto &parser = m_context.parser; + + parser.expect("("); + parser.expect(":"); + parser.expect("constants"); // Store constants expressions::Constant::parseTypedDeclarations(m_context, *this); - m_context.parser.expect(")"); + parser.expect(")"); } //////////////////////////////////////////////////////////////////////////////////////////////////// void Domain::parsePredicateSection() { - m_context.parser.skipWhiteSpace(); + auto &parser = m_context.parser; + + parser.expect("("); + parser.expect(":"); + parser.expect("predicates"); + + parser.skipWhiteSpace(); // Store predicates and their arguments - while (m_context.parser.currentCharacter() != ')') + while (parser.currentCharacter() != ')') { expressions::PredicateDeclaration::parse(m_context, *this); - m_context.parser.skipWhiteSpace(); + parser.skipWhiteSpace(); } - m_context.parser.expect(")"); + parser.expect(")"); } //////////////////////////////////////////////////////////////////////////////////////////////////// void Domain::parseActionSection() { - m_context.parser.skipWhiteSpace(); + auto &parser = m_context.parser; + + parser.expect("("); + parser.expect(":"); + parser.expect("action"); Action::parseDeclaration(m_context, *this); - m_context.parser.expect(")"); + parser.expect(")"); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/plasp/pddl/Expression.cpp b/src/plasp/pddl/Expression.cpp index e5e88da..4014abe 100644 --- a/src/plasp/pddl/Expression.cpp +++ b/src/plasp/pddl/Expression.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -33,10 +34,10 @@ ExpressionPointer parsePredicate(Context &context, ExpressionContext &expression //////////////////////////////////////////////////////////////////////////////////////////////////// -[[noreturn]] void throwUnsupported(const utils::Parser &parser, - const std::string &expressionIdentifier) +inline void warnUnsupported(Context &context, const std::string &expressionIdentifier) { - throw utils::ParserException(parser, "Expression type \"" + expressionIdentifier + "\" currently unsupported in this context"); + context.logger.parserWarning(context.parser, "Expression type \"" + expressionIdentifier + "\" currently unsupported in this context"); + skipSection(context.parser); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -58,7 +59,9 @@ ExpressionPointer parsePreconditionExpression(Context &context, else if (expressionIdentifier == "forall" || expressionIdentifier == "preference") { - throwUnsupported(context.parser, expressionIdentifier); + warnUnsupported(context, expressionIdentifier); + + return nullptr; } else expression = parseExpressionContent(expressionIdentifier, context, expressionContext); @@ -116,7 +119,9 @@ ExpressionPointer parseExpressionContent(const std::string &expressionIdentifier || expressionIdentifier == ">=" || expressionIdentifier == "<=") { - throwUnsupported(context.parser, expressionIdentifier); + warnUnsupported(context, expressionIdentifier); + + return nullptr; } auto &predicateDeclarations = expressionContext.domain.predicates(); @@ -132,7 +137,7 @@ ExpressionPointer parseExpressionContent(const std::string &expressionIdentifier if (match != predicateDeclarations.cend()) return expressions::Predicate::parse(expressionIdentifier, context, expressionContext); - throw utils::ParserException(context.parser, "Expression \"" + expressionIdentifier + "\" not allowed in this context"); + throw utils::ParserException(context.parser, "Unknown expression \"" + expressionIdentifier + "\""); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -150,7 +155,9 @@ ExpressionPointer parseEffectExpression(Context &context, ExpressionContext &exp else if (expressionIdentifier == "forall" || expressionIdentifier == "when") { - throwUnsupported(context.parser, expressionIdentifier); + warnUnsupported(context, expressionIdentifier); + + return nullptr; } else expression = parseEffectBodyExpressionContent(expressionIdentifier, context, expressionContext); @@ -177,7 +184,9 @@ ExpressionPointer parseEffectBodyExpressionContent(const std::string &expression || expressionIdentifier == "increase" || expressionIdentifier == "decrease") { - throwUnsupported(context.parser, expressionIdentifier); + warnUnsupported(context, expressionIdentifier); + + return nullptr; } const auto &predicateDeclarations = expressionContext.domain.predicates(); diff --git a/src/plasp/pddl/InitialState.cpp b/src/plasp/pddl/InitialState.cpp new file mode 100644 index 0000000..680f7ea --- /dev/null +++ b/src/plasp/pddl/InitialState.cpp @@ -0,0 +1,63 @@ +#include + +#include +#include +#include +#include +#include + +namespace plasp +{ +namespace pddl +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// InitialState +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +inline void warnUnsupported(Context &context, const std::string &expressionIdentifier) +{ + context.logger.parserWarning(context.parser, "Expression type \"" + expressionIdentifier + "\" currently unsupported in this context"); + skipSection(context.parser); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +std::unique_ptr InitialState::parseDeclaration(Context &context, const Problem &problem) +{ + auto initialState = std::make_unique(InitialState()); + + while (context.parser.currentCharacter() != ')') + { + context.parser.expect("("); + + ExpressionPointer expression; + + const auto expressionIdentifier = context.parser.parseIdentifier(isIdentifier); + + if (expressionIdentifier == "at" + || expressionIdentifier == "=" + || expressionIdentifier == "not") + { + warnUnsupported(context, expressionIdentifier); + + continue; + } + + // If none of the above types apply, the content is a predicate over constants and objects + initialState->m_facts.emplace_back(expressions::Predicate::parse(expressionIdentifier, context, problem)); + + context.parser.expect(")"); + + context.parser.skipWhiteSpace(); + } + + return initialState; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} diff --git a/src/plasp/pddl/Problem.cpp b/src/plasp/pddl/Problem.cpp index a7835f8..35f7c14 100644 --- a/src/plasp/pddl/Problem.cpp +++ b/src/plasp/pddl/Problem.cpp @@ -29,7 +29,7 @@ Problem::Problem(Context &context, Domain &domain) //////////////////////////////////////////////////////////////////////////////////////////////////// -void Problem::readPDDL() +void Problem::parse() { m_context.parser.expect("("); m_context.parser.expect("define"); @@ -122,8 +122,9 @@ void Problem::parseSection() parseRequirementSection(); else if (parser.probe("objects")) parseObjectSection(); - else if (parser.probe("init") - || parser.probe("goal") + else if (parser.probe("init")) + parseInitialStateSection(); + else if (parser.probe("goal") || parser.probe("constraints") || parser.probe("metric") || parser.probe("length")) @@ -255,6 +256,33 @@ void Problem::parseObjectSection() //////////////////////////////////////////////////////////////////////////////////////////////////// +void Problem::parseInitialStateSection() +{ + m_initialState = InitialState::parseDeclaration(m_context, *this); + + m_context.parser.expect(")"); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +InitialState &Problem::initialState() +{ + BOOST_ASSERT(m_initialState); + + return *m_initialState; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +const InitialState &Problem::initialState() const +{ + BOOST_ASSERT(m_initialState); + + return *m_initialState; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + void Problem::checkConsistency() { } diff --git a/src/plasp/pddl/expressions/Constant.cpp b/src/plasp/pddl/expressions/Constant.cpp index a011713..9bfe0fc 100644 --- a/src/plasp/pddl/expressions/Constant.cpp +++ b/src/plasp/pddl/expressions/Constant.cpp @@ -134,24 +134,37 @@ void Constant::parseTypedDeclarations(Context &context, Problem &problem) //////////////////////////////////////////////////////////////////////////////////////////////////// -Constant *Constant::parseAndFind(Context &context, const ExpressionContext &expressionContext) +Constant *Constant::parseAndFind(Context &context, const Domain &domain) { context.parser.skipWhiteSpace(); const auto constantName = context.parser.parseIdentifier(isIdentifier); - auto *constant = parseAndFind(constantName, expressionContext.domain.constants()); + auto *constant = parseAndFind(constantName, domain.constants()); + + if (constant != nullptr) + return constant; + + throw utils::ParserException(context.parser, "Constant \"" + constantName + "\" used but never declared"); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +Constant *Constant::parseAndFind(Context &context, const Problem &problem) +{ + context.parser.skipWhiteSpace(); + + const auto constantName = context.parser.parseIdentifier(isIdentifier); + + auto *constant = parseAndFind(constantName, problem.domain().constants()); if (constant) return constant; - if (expressionContext.problem) - { - constant = parseAndFind(constantName, expressionContext.problem->objects()); + constant = parseAndFind(constantName, problem.objects()); - if (constant) - return constant; - } + if (constant) + return constant; throw utils::ParserException(context.parser, "Constant \"" + constantName + "\" used but never declared"); } diff --git a/src/plasp/pddl/expressions/InitialState.cpp b/src/plasp/pddl/expressions/InitialState.cpp deleted file mode 100644 index 3d85d3f..0000000 --- a/src/plasp/pddl/expressions/InitialState.cpp +++ /dev/null @@ -1,54 +0,0 @@ -#include - -#include -#include -#include -#include -#include - -namespace plasp -{ -namespace pddl -{ -namespace expressions -{ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// -// InitialState -// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void throwUnsupported(const utils::Parser &parser, const std::string &expressionIdentifier) -{ - throw utils::ParserException(parser, "Expression type \"" + expressionIdentifier + "\" currently unsupported in this context"); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -ExpressionPointer parseInitialState(Context &context) -{ - context.parser.expect("("); - - const auto expressionIdentifier = context.parser.parseIdentifier(isIdentifier); - - ExpressionPointer expression; - - if (expressionIdentifier == "at" - || expressionIdentifier == "=") - { - throwUnsupported(context.parser, expressionIdentifier); - } - - // TODO: implement predicate parsing - - context.parser.expect(")"); - - return expression; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -} -} -} diff --git a/src/plasp/pddl/expressions/Predicate.cpp b/src/plasp/pddl/expressions/Predicate.cpp index 73f9bdf..1e3c27a 100644 --- a/src/plasp/pddl/expressions/Predicate.cpp +++ b/src/plasp/pddl/expressions/Predicate.cpp @@ -51,7 +51,9 @@ PredicatePointer Predicate::parse(std::string name, Context &context, // Parse constants else { - const auto *constant = Constant::parseAndFind(context, expressionContext); + const auto *constant = (expressionContext.problem == nullptr) + ? Constant::parseAndFind(context, expressionContext.domain) + : Constant::parseAndFind(context, *expressionContext.problem); auto constantReference = std::make_unique>(constant); predicate->m_arguments.emplace_back(std::move(constantReference)); } @@ -66,6 +68,32 @@ PredicatePointer Predicate::parse(std::string name, Context &context, //////////////////////////////////////////////////////////////////////////////////////////////////// +PredicatePointer Predicate::parse(std::string name, Context &context, const Problem &problem) +{ + auto predicate = std::make_unique(Predicate()); + + predicate->m_name = name; + + context.parser.skipWhiteSpace(); + + while (context.parser.currentCharacter() != ')') + { + if (context.parser.currentCharacter() == '?') + throw utils::ParserException(context.parser, "Variables not allowed in this context"); + + // Parse objects and constants + const auto *constant = Constant::parseAndFind(context, problem); + auto constantReference = std::make_unique>(constant); + predicate->m_arguments.emplace_back(std::move(constantReference)); + } + + // TODO: check that signature matches one of the declared ones + + return predicate; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + void Predicate::accept(plasp::pddl::ExpressionVisitor &expressionVisitor) const { expressionVisitor.visit(*this);