commit 3ddf942a12721ea2e26b91c0884d830748152425 Author: Patrick Lühne Date: Fri May 20 15:29:24 2016 +0200 Initial commit. diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..52daab4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.gitignore +build/* diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..0a50346 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,15 @@ +cmake_minimum_required(VERSION 2.6) +project(plasp CXX) + +find_package(Boost 1.55.0 COMPONENTS program_options iostreams system filesystem REQUIRED) + +set(CMAKE_CXX_FLAGS "-Wall -Wpedantic") +set(CMAKE_CXX_FLAGS_DEBUG "-g") +add_definitions(-std=c++14) + +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) + +add_subdirectory(src) +add_subdirectory(apps) diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..ebdc5b6 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Patrick Lühne + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..5333230 --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +# plasp—Translate PDDL to ASP + +`plasp` is in early development and not intended for productive use. + +## Contributors + +* [Patrick Lühne](https://www.luehne.de) diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt new file mode 100644 index 0000000..f30b3d4 --- /dev/null +++ b/apps/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(plasp-app) diff --git a/apps/plasp-app/CMakeLists.txt b/apps/plasp-app/CMakeLists.txt new file mode 100644 index 0000000..b6a4ca9 --- /dev/null +++ b/apps/plasp-app/CMakeLists.txt @@ -0,0 +1,23 @@ +set(target plasp_app) + +file(GLOB core_sources "*.cpp") +file(GLOB core_headers "*.h") + +include_directories( + ${Boost_INCLUDE_DIRS} + ${PROJECT_SOURCE_DIR}/include +) + +set(sources + ${core_sources} + ${core_headers} +) + +set(libraries + ${Boost_LIBRARIES} + plasp +) + +add_executable(${target} ${sources}) +target_link_libraries(${target} ${libraries}) +set_target_properties(plasp_app PROPERTIES OUTPUT_NAME plasp) diff --git a/apps/plasp-app/main.cpp b/apps/plasp-app/main.cpp new file mode 100644 index 0000000..0373303 --- /dev/null +++ b/apps/plasp-app/main.cpp @@ -0,0 +1,44 @@ +#include + +#include + +#include + +int main(int argc, char **argv) +{ + namespace po = boost::program_options; + + po::options_description description("Allowed options"); + description.add_options() + ("help,h", "display this help message") + ("input,i", po::value(), "SAS input file"); + + po::positional_options_description positionalOptionsDescription; + positionalOptionsDescription.add("input", -1); + + po::variables_map variablesMap; + po::store(po::command_line_parser(argc, argv) + .options(description) + .positional(positionalOptionsDescription) + .run(), + variablesMap); + po::notify(variablesMap); + + if (variablesMap.count("help")) + { + std::cout << description; + return EXIT_SUCCESS; + } + + if (!variablesMap.count("input")) + { + std::cerr << "Error: No input file specified" << std::endl; + std::cout << description; + return EXIT_FAILURE; + } + + const auto sasDescription = plasp::sas::Description::fromFile(variablesMap["input"].as()); + sasDescription.print(std::cout); + + return EXIT_SUCCESS; +} diff --git a/include/plasp/sas/AxiomRule.h b/include/plasp/sas/AxiomRule.h new file mode 100644 index 0000000..3929bfb --- /dev/null +++ b/include/plasp/sas/AxiomRule.h @@ -0,0 +1,33 @@ +#ifndef __SAS__AXIOM_RULE_H +#define __SAS__AXIOM_RULE_H + +#include + +#include + +namespace plasp +{ +namespace sas +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// AxiomRule +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +struct AxiomRule +{ + using Condition = AssignedVariable; + using Conditions = std::vector; + + Conditions conditions; + Condition postcondition; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} + +#endif diff --git a/include/plasp/sas/Description.h b/include/plasp/sas/Description.h new file mode 100644 index 0000000..261bbde --- /dev/null +++ b/include/plasp/sas/Description.h @@ -0,0 +1,66 @@ +#ifndef __SAS__DESCRIPTION_H +#define __SAS__DESCRIPTION_H + +#include + +#include + +#include +#include +#include +#include + +namespace plasp +{ +namespace sas +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Description +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +class Description +{ + public: + static Description fromFile(const boost::filesystem::path &path); + + public: + Description(); + + void print(std::ostream &ostream) const; + + private: + void parseSectionIdentifier(std::istream &istream, const std::string &expectedSectionIdentifier) const; + size_t parseNumber(std::istream &istream) const; + const Variable &parseVariable(std::istream &istream) const; + const Value &parseVariableValue(std::istream &istream, const Variable &variable) const; + AssignedVariable parseAssignedVariable(std::istream &istream) const; + VariableTransition parseVariableTransition(std::istream &istream) const; + + void parseVersionSection(std::istream &istream) const; + void parseMetricSection(std::istream &istream); + void parseVariablesSection(std::istream &istream); + void parseMutexSection(std::istream &istream); + void parseInitialStateSection(std::istream &istream); + void parseGoalSection(std::istream &istream); + void parseOperatorSection(std::istream &istream); + void parseAxiomSection(std::istream &istream); + + bool m_usesActionCosts; + + std::vector m_variables; + std::vector m_mutexGroups; + std::vector m_initialStateFacts; + std::vector m_goalFacts; + std::vector m_operators; + std::vector m_axiomRules; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} + +#endif diff --git a/include/plasp/sas/Effect.h b/include/plasp/sas/Effect.h new file mode 100644 index 0000000..f97db59 --- /dev/null +++ b/include/plasp/sas/Effect.h @@ -0,0 +1,33 @@ +#ifndef __SAS__EFFECT_H +#define __SAS__EFFECT_H + +#include + +#include + +namespace plasp +{ +namespace sas +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Effect +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +struct Effect +{ + using Condition = AssignedVariable; + using Conditions = std::vector; + + Conditions conditions; + Condition postcondition; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} + +#endif diff --git a/include/plasp/sas/MutexGroup.h b/include/plasp/sas/MutexGroup.h new file mode 100644 index 0000000..3fa5267 --- /dev/null +++ b/include/plasp/sas/MutexGroup.h @@ -0,0 +1,30 @@ +#ifndef __SAS__MUTEX_GROUP_H +#define __SAS__MUTEX_GROUP_H + +#include + +namespace plasp +{ +namespace sas +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// MutexGroup +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +struct MutexGroup +{ + using Fact = AssignedVariable; + using Facts = std::vector; + + Facts facts; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} + +#endif diff --git a/include/plasp/sas/Operator.h b/include/plasp/sas/Operator.h new file mode 100644 index 0000000..1b6b0fb --- /dev/null +++ b/include/plasp/sas/Operator.h @@ -0,0 +1,38 @@ +#ifndef __SAS__OPERATOR_H +#define __SAS__OPERATOR_H + +#include +#include + +#include +#include + +namespace plasp +{ +namespace sas +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Operator +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +struct Operator +{ + using Condition = AssignedVariable; + using Conditions = std::vector; + using Effects = std::vector; + + std::string name; + Conditions preconditions; + Effects effects; + size_t costs; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} + +#endif diff --git a/include/plasp/sas/ParserException.h b/include/plasp/sas/ParserException.h new file mode 100644 index 0000000..6ba04a6 --- /dev/null +++ b/include/plasp/sas/ParserException.h @@ -0,0 +1,56 @@ +#ifndef __SAS__PARSER_EXCEPTION_H +#define __SAS__PARSER_EXCEPTION_H + +#include +#include + +namespace plasp +{ +namespace sas +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// ParserException +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +class ParserException: public std::exception +{ + public: + explicit ParserException() + { + } + + explicit ParserException(const char *message) + : m_message(message) + { + } + + explicit ParserException(const std::string &message) + : m_message(message) + { + } + + ~ParserException() throw() + { + } + + const char *what() const throw() + { + if (m_message.empty()) + return "Unspecified error while parsing SAS description file"; + + return m_message.c_str(); + } + + private: + std::string m_message; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} + +#endif diff --git a/include/plasp/sas/Value.h b/include/plasp/sas/Value.h new file mode 100644 index 0000000..dbbcd7a --- /dev/null +++ b/include/plasp/sas/Value.h @@ -0,0 +1,29 @@ +#ifndef __SAS__VALUE_H +#define __SAS__VALUE_H + +#include + +namespace plasp +{ +namespace sas +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Value +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +struct Value +{ + static const Value Any; + + std::string name; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} + +#endif diff --git a/include/plasp/sas/Variable.h b/include/plasp/sas/Variable.h new file mode 100644 index 0000000..09049ce --- /dev/null +++ b/include/plasp/sas/Variable.h @@ -0,0 +1,51 @@ +#ifndef __SAS__VARIABLE_H +#define __SAS__VARIABLE_H + +#include +#include + +#include + +namespace plasp +{ +namespace sas +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Variable +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +struct Variable +{ + using Values = std::vector; + + std::string name; + int axiomLayer; + Values values; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +struct AssignedVariable +{ + const Variable &variable; + const Value &value; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +struct VariableTransition +{ + const Variable &variable; + const Value &valueBefore; + const Value &valueAfter; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} + +#endif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..be5d1e2 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,31 @@ +set(target plasp) + +file(GLOB core_sources "plasp/*.cpp") +file(GLOB core_headers "../include/plasp/*.h") + +file(GLOB sas_sources "plasp/sas/*.cpp") +file(GLOB sas_headers "../include/plasp/sas/*.h") + +include_directories( + ${Boost_INCLUDE_DIRS} +) + +include_directories( + ${PROJECT_SOURCE_DIR}/include +) + +set(sources + ${core_sources} + ${core_headers} + + ${sas_sources} + ${sas_headers} +) + +set(libraries + ${Boost_LIBRARIES} + pthread +) + +add_library(${target} ${sources}) +target_link_libraries(${target} ${libraries}) diff --git a/src/plasp/sas/Description.cpp b/src/plasp/sas/Description.cpp new file mode 100644 index 0000000..4a153d1 --- /dev/null +++ b/src/plasp/sas/Description.cpp @@ -0,0 +1,470 @@ +#include + +#include + +#include + +#include + +namespace plasp +{ +namespace sas +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Description +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +Description::Description() +: m_usesActionCosts{false} +{ +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +Description Description::fromFile(const boost::filesystem::path &path) +{ + Description description; + + setlocale(LC_NUMERIC, "C"); + + if (!boost::filesystem::is_regular_file(path)) + { + std::cerr << "Error: File does not exist: " << path.string() << std::endl; + return description; + } + + try + { + std::ifstream fileStream(path.string(), std::ios::in); + fileStream.exceptions(std::ifstream::failbit | std::ifstream::badbit); + + description.parseVersionSection(fileStream); + description.parseMetricSection(fileStream); + description.parseVariablesSection(fileStream); + description.parseMutexSection(fileStream); + description.parseInitialStateSection(fileStream); + description.parseGoalSection(fileStream); + description.parseOperatorSection(fileStream); + description.parseAxiomSection(fileStream); + } + catch (std::exception &exception) + { + std::cerr << "Error: " << exception.what() << std::endl; + return description; + } + + return description; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void Description::print(std::ostream &ostream) const +{ + // Metric section + ostream << "uses action costs: " << (m_usesActionCosts ? "yes" : "no") << std::endl; + + // Variable section + ostream << "variables: " << m_variables.size() << std::endl; + + std::for_each(m_variables.cbegin(), m_variables.cend(), + [&](const auto &variable) + { + ostream << "\t" << variable.name << std::endl; + ostream << "\t\tvalues: " << variable.values.size() << std::endl; + + std::for_each(variable.values.cbegin(), variable.values.cend(), + [&](const auto &value) + { + ostream << "\t\t\t" << value.name << std::endl; + }); + + ostream << "\t\taxiom layer: " << variable.axiomLayer << std::endl; + }); + + // Mutex section + ostream << "mutex groups: " << m_mutexGroups.size() << std::endl; + + std::for_each(m_mutexGroups.cbegin(), m_mutexGroups.cend(), + [&](const auto &mutexGroup) + { + ostream << "\tmutex group:" << std::endl; + + std::for_each(mutexGroup.facts.cbegin(), mutexGroup.facts.cend(), + [&](const auto &fact) + { + ostream << "\t\t" << fact.variable.name << " = " << fact.value.name << std::endl; + }); + }); + + // Initial state section + ostream << "initial state:" << std::endl; + + std::for_each(m_initialStateFacts.cbegin(), m_initialStateFacts.cend(), + [&](const auto &initialStateFact) + { + ostream << "\t" << initialStateFact.variable.name << " = " << initialStateFact.value.name << std::endl; + }); + + // Goal section + ostream << "goal:" << std::endl; + + std::for_each(m_goalFacts.cbegin(), m_goalFacts.cend(), + [&](const auto &goalFact) + { + ostream << "\t" << goalFact.variable.name << " = " << goalFact.value.name << std::endl; + }); + + // Operator section + ostream << "operators: " << m_operators.size() << std::endl; + + std::for_each(m_operators.cbegin(), m_operators.cend(), + [&](const auto &operator_) + { + ostream << "\t" << operator_.name << std::endl; + ostream << "\t\tpreconditions: " << operator_.preconditions.size() << std::endl; + + std::for_each(operator_.preconditions.cbegin(), operator_.preconditions.cend(), + [&](const auto &precondition) + { + std::cout << "\t\t\t" << precondition.variable.name << " = " << precondition.value.name << std::endl; + }); + + ostream << "\t\teffects: " << operator_.effects.size() << std::endl; + + std::for_each(operator_.effects.cbegin(), operator_.effects.cend(), + [&](const auto &effect) + { + ostream << "\t\t\teffect:" << std::endl; + ostream << "\t\t\t\tconditions: " << effect.conditions.size() << std::endl; + + std::for_each(effect.conditions.cbegin(), effect.conditions.cend(), + [&](const auto &condition) + { + ostream << "\t\t\t\t\t" << condition.variable.name << " = " << condition.value.name << std::endl; + }); + + ostream << "\t\t\t\tpostcondition:" << std::endl; + ostream << "\t\t\t\t\t" << effect.postcondition.variable.name << " = " << effect.postcondition.value.name << std::endl; + }); + + ostream << "\t\tcosts: " << operator_.costs << std::endl; + }); + + // Axiom section + ostream << "axiom rules: " << m_axiomRules.size() << std::endl; + + std::for_each(m_axiomRules.cbegin(), m_axiomRules.cend(), + [&](const auto &axiomRule) + { + ostream << "\taxiom rule:" << std::endl; + ostream << "\t\tconditions: " << axiomRule.conditions.size() << std::endl; + + std::for_each(axiomRule.conditions.cbegin(), axiomRule.conditions.cend(), + [&](const auto &condition) + { + ostream << "\t\t\t" << condition.variable.name << " = " << condition.value.name << std::endl; + }); + + ostream << "\t\tpostcondition:" << std::endl; + ostream << "\t\t\t" << axiomRule.postcondition.variable.name << " = " << axiomRule.postcondition.value.name << std::endl; + }); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void Description::parseSectionIdentifier(std::istream &istream, const std::string &expectedSectionIdentifier) const +{ + std::string sectionIdentifier; + + istream >> sectionIdentifier; + + if (sectionIdentifier != expectedSectionIdentifier) + throw ParserException("Invalid format, expected " + expectedSectionIdentifier + ", got " + sectionIdentifier); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +size_t Description::parseNumber(std::istream &istream) const +{ + auto number = std::numeric_limits::max(); + istream >> number; + + if (number == std::numeric_limits::max()) + throw ParserException("Invalid number"); + + return number; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +const Variable &Description::parseVariable(std::istream &istream) const +{ + auto variableID = std::numeric_limits::max(); + istream >> variableID; + + if (variableID >= m_variables.size()) + throw ParserException("Variable index out of range (index " + std::to_string(variableID) + ")"); + + return m_variables[variableID]; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +const Value &Description::parseVariableValue(std::istream &istream, const Variable &variable) const +{ + auto valueID = std::numeric_limits::max(); + istream >> valueID; + + if (valueID == -1) + return Value::Any; + + if (valueID < 0 || static_cast(valueID) >= variable.values.size()) + throw ParserException("Value index out of range (variable " + variable.name + ", index " + std::to_string(valueID) + ")"); + + return variable.values[valueID]; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +AssignedVariable Description::parseAssignedVariable(std::istream &istream) const +{ + const auto &variable = parseVariable(istream); + const auto &value = parseVariableValue(istream, variable); + + return {variable, value}; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +VariableTransition Description::parseVariableTransition(std::istream &istream) const +{ + const auto &variable = parseVariable(istream); + const auto &valueBefore = parseVariableValue(istream, variable); + const auto &valueAfter = parseVariableValue(istream, variable); + + return {variable, valueBefore, valueAfter}; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void Description::parseVersionSection(std::istream &istream) const +{ + // Version section + parseSectionIdentifier(istream, "begin_version"); + + const auto formatVersion = parseNumber(istream); + + if (formatVersion != 3) + throw ParserException("Unsupported SAS format version (" + std::to_string(formatVersion) + ")"); + + std::cout << "SAS format version: " << formatVersion << std::endl; + + parseSectionIdentifier(istream, "end_version"); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void Description::parseMetricSection(std::istream &istream) +{ + parseSectionIdentifier(istream, "begin_metric"); + + istream >> m_usesActionCosts; + + parseSectionIdentifier(istream, "end_metric"); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void Description::parseVariablesSection(std::istream &istream) +{ + const auto numberOfVariables = parseNumber(istream); + m_variables.resize(numberOfVariables); + + for (size_t i = 0; i < numberOfVariables; i++) + { + auto &variable = m_variables[i]; + + parseSectionIdentifier(istream, "begin_variable"); + + istream >> variable.name; + istream >> variable.axiomLayer; + + const auto numberOfValues = parseNumber(istream); + variable.values.resize(numberOfValues); + + istream.ignore(std::numeric_limits::max(), '\n'); + + for (size_t j = 0; j < numberOfValues; j++) + { + auto &value = variable.values[j]; + std::getline(istream, value.name); + } + + parseSectionIdentifier(istream, "end_variable"); + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void Description::parseMutexSection(std::istream &istream) +{ + const auto numberOfMutexGroups = parseNumber(istream); + m_mutexGroups.resize(numberOfMutexGroups); + + for (size_t i = 0; i < numberOfMutexGroups; i++) + { + parseSectionIdentifier(istream, "begin_mutex_group"); + + auto &mutexGroup = m_mutexGroups[i]; + + const auto numberOfFacts = parseNumber(istream); + mutexGroup.facts.reserve(numberOfFacts); + + for (size_t j = 0; j < numberOfFacts; j++) + { + const auto fact = parseAssignedVariable(istream); + mutexGroup.facts.push_back(std::move(fact)); + } + + parseSectionIdentifier(istream, "end_mutex_group"); + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void Description::parseInitialStateSection(std::istream &istream) +{ + parseSectionIdentifier(istream, "begin_state"); + + m_initialStateFacts.reserve(m_variables.size()); + + for (size_t i = 0; i < m_variables.size(); i++) + { + const auto &variable = m_variables[i]; + const auto &value = parseVariableValue(istream, variable); + + m_initialStateFacts.push_back({variable, value}); + } + + parseSectionIdentifier(istream, "end_state"); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void Description::parseGoalSection(std::istream &istream) +{ + parseSectionIdentifier(istream, "begin_goal"); + + const auto numberOfGoalFacts = parseNumber(istream); + m_goalFacts.reserve(numberOfGoalFacts); + + for (size_t i = 0; i < numberOfGoalFacts; i++) + { + const auto goalFact = parseAssignedVariable(istream); + m_goalFacts.push_back(std::move(goalFact)); + } + + parseSectionIdentifier(istream, "end_goal"); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void Description::parseOperatorSection(std::istream &istream) +{ + const auto numberOfOperators = parseNumber(istream); + m_operators.resize(numberOfOperators); + + for (size_t i = 0; i < numberOfOperators; i++) + { + parseSectionIdentifier(istream, "begin_operator"); + + istream.ignore(std::numeric_limits::max(), '\n'); + + auto &operator_ = m_operators[i]; + std::getline(istream, operator_.name); + + const auto numberOfPrevailConditions = parseNumber(istream); + operator_.preconditions.reserve(numberOfPrevailConditions); + + for (size_t j = 0; j < numberOfPrevailConditions; j++) + { + const auto precondition = parseAssignedVariable(istream); + operator_.preconditions.push_back(std::move(precondition)); + } + + const auto numberOfEffects = parseNumber(istream); + operator_.effects.reserve(numberOfEffects); + + for (size_t j = 0; j < numberOfEffects; j++) + { + Effect::Conditions conditions; + + const auto numberOfEffectConditions = parseNumber(istream); + conditions.reserve(numberOfEffectConditions); + + for (size_t k = 0; k < numberOfEffectConditions; k++) + { + const auto condition = parseAssignedVariable(istream); + conditions.push_back(std::move(condition)); + } + + const auto variableTransition = parseVariableTransition(istream); + + if (&variableTransition.valueBefore != &Value::Any) + operator_.preconditions.push_back({variableTransition.variable, variableTransition.valueBefore}); + + const Effect::Condition postcondition = {variableTransition.variable, variableTransition.valueAfter}; + const Effect effect = {std::move(conditions), std::move(postcondition)}; + operator_.effects.push_back(std::move(effect)); + } + + operator_.costs = parseNumber(istream); + + parseSectionIdentifier(istream, "end_operator"); + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void Description::parseAxiomSection(std::istream &istream) +{ + const auto numberOfAxiomRules = parseNumber(istream); + m_axiomRules.reserve(numberOfAxiomRules); + + std::cout << "Axiom rules: " << numberOfAxiomRules << std::endl; + + for (size_t i = 0; i < numberOfAxiomRules; i++) + { + parseSectionIdentifier(istream, "begin_rule"); + + const auto numberOfConditions = parseNumber(istream); + + AxiomRule::Conditions conditions; + conditions.reserve(numberOfConditions); + + for (size_t j = 0; j < numberOfConditions; j++) + { + const auto condition = parseAssignedVariable(istream); + conditions.push_back(std::move(condition)); + } + + const auto variableTransition = parseVariableTransition(istream); + + if (&variableTransition.valueBefore != &Value::Any) + conditions.push_back({variableTransition.variable, variableTransition.valueBefore}); + + const AxiomRule::Condition postcondition = {variableTransition.variable, variableTransition.valueAfter}; + const AxiomRule axiomRule = {std::move(conditions), std::move(postcondition)}; + m_axiomRules.push_back(std::move(axiomRule)); + + parseSectionIdentifier(istream, "end_rule"); + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} diff --git a/src/plasp/sas/Value.cpp b/src/plasp/sas/Value.cpp new file mode 100644 index 0000000..532ed77 --- /dev/null +++ b/src/plasp/sas/Value.cpp @@ -0,0 +1,19 @@ +#include + +namespace plasp +{ +namespace sas +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Value +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +const Value Value::Any = {"(any)"}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +}