Initial commit.

This commit is contained in:
Patrick Lühne 2016-05-20 15:29:24 +02:00
commit 3ddf942a12
18 changed files with 969 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
.gitignore
build/*

15
CMakeLists.txt Normal file
View File

@ -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)

21
LICENSE Normal file
View File

@ -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.

7
README.md Normal file
View File

@ -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)

1
apps/CMakeLists.txt Normal file
View File

@ -0,0 +1 @@
add_subdirectory(plasp-app)

View File

@ -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)

44
apps/plasp-app/main.cpp Normal file
View File

@ -0,0 +1,44 @@
#include <iostream>
#include <boost/program_options.hpp>
#include <plasp/sas/Description.h>
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<std::string>(), "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<std::string>());
sasDescription.print(std::cout);
return EXIT_SUCCESS;
}

View File

@ -0,0 +1,33 @@
#ifndef __SAS__AXIOM_RULE_H
#define __SAS__AXIOM_RULE_H
#include <vector>
#include <plasp/sas/Variable.h>
namespace plasp
{
namespace sas
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// AxiomRule
//
////////////////////////////////////////////////////////////////////////////////////////////////////
struct AxiomRule
{
using Condition = AssignedVariable;
using Conditions = std::vector<Condition>;
Conditions conditions;
Condition postcondition;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}
#endif

View File

@ -0,0 +1,66 @@
#ifndef __SAS__DESCRIPTION_H
#define __SAS__DESCRIPTION_H
#include <vector>
#include <boost/filesystem/path.hpp>
#include <plasp/sas/MutexGroup.h>
#include <plasp/sas/Operator.h>
#include <plasp/sas/Variable.h>
#include <plasp/sas/AxiomRule.h>
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<Variable> m_variables;
std::vector<MutexGroup> m_mutexGroups;
std::vector<AssignedVariable> m_initialStateFacts;
std::vector<AssignedVariable> m_goalFacts;
std::vector<Operator> m_operators;
std::vector<AxiomRule> m_axiomRules;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}
#endif

View File

@ -0,0 +1,33 @@
#ifndef __SAS__EFFECT_H
#define __SAS__EFFECT_H
#include <vector>
#include <plasp/sas/Variable.h>
namespace plasp
{
namespace sas
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Effect
//
////////////////////////////////////////////////////////////////////////////////////////////////////
struct Effect
{
using Condition = AssignedVariable;
using Conditions = std::vector<Condition>;
Conditions conditions;
Condition postcondition;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}
#endif

View File

@ -0,0 +1,30 @@
#ifndef __SAS__MUTEX_GROUP_H
#define __SAS__MUTEX_GROUP_H
#include <plasp/sas/Variable.h>
namespace plasp
{
namespace sas
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// MutexGroup
//
////////////////////////////////////////////////////////////////////////////////////////////////////
struct MutexGroup
{
using Fact = AssignedVariable;
using Facts = std::vector<Fact>;
Facts facts;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}
#endif

View File

@ -0,0 +1,38 @@
#ifndef __SAS__OPERATOR_H
#define __SAS__OPERATOR_H
#include <string>
#include <vector>
#include <plasp/sas/Effect.h>
#include <plasp/sas/Variable.h>
namespace plasp
{
namespace sas
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Operator
//
////////////////////////////////////////////////////////////////////////////////////////////////////
struct Operator
{
using Condition = AssignedVariable;
using Conditions = std::vector<Condition>;
using Effects = std::vector<Effect>;
std::string name;
Conditions preconditions;
Effects effects;
size_t costs;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}
#endif

View File

@ -0,0 +1,56 @@
#ifndef __SAS__PARSER_EXCEPTION_H
#define __SAS__PARSER_EXCEPTION_H
#include <exception>
#include <string>
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

29
include/plasp/sas/Value.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef __SAS__VALUE_H
#define __SAS__VALUE_H
#include <string>
namespace plasp
{
namespace sas
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Value
//
////////////////////////////////////////////////////////////////////////////////////////////////////
struct Value
{
static const Value Any;
std::string name;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}
#endif

View File

@ -0,0 +1,51 @@
#ifndef __SAS__VARIABLE_H
#define __SAS__VARIABLE_H
#include <string>
#include <vector>
#include <plasp/sas/Value.h>
namespace plasp
{
namespace sas
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Variable
//
////////////////////////////////////////////////////////////////////////////////////////////////////
struct Variable
{
using Values = std::vector<Value>;
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

31
src/CMakeLists.txt Normal file
View File

@ -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})

View File

@ -0,0 +1,470 @@
#include <plasp/sas/Description.h>
#include <iostream>
#include <boost/filesystem.hpp>
#include <plasp/sas/ParserException.h>
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<size_t>::max();
istream >> number;
if (number == std::numeric_limits<size_t>::max())
throw ParserException("Invalid number");
return number;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
const Variable &Description::parseVariable(std::istream &istream) const
{
auto variableID = std::numeric_limits<size_t>::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<int>::max();
istream >> valueID;
if (valueID == -1)
return Value::Any;
if (valueID < 0 || static_cast<size_t>(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<std::streamsize>::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<std::streamsize>::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");
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}

19
src/plasp/sas/Value.cpp Normal file
View File

@ -0,0 +1,19 @@
#include <plasp/sas/Value.h>
namespace plasp
{
namespace sas
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Value
//
////////////////////////////////////////////////////////////////////////////////////////////////////
const Value Value::Any = {"(any)"};
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}