Browse Source

Merge pull request 'Update of Yaml Config and Config Parsing' (#10) from yaml_config_changes into main

Reviewed-on: #10
main
Stefan Pranger 6 months ago
parent
commit
c485844e1d
  1. 33
      exampleConfig.yaml
  2. 80
      main.cpp
  3. 60
      util/ConfigYaml.cpp
  4. 50
      util/ConfigYaml.h
  5. 39
      util/Grid.cpp
  6. 4
      util/PrismModulesPrinter.cpp

33
exampleConfig.yaml

@ -0,0 +1,33 @@
---
labels:
- label: "AgentIsInGoal"
text: "AgentIsInGoal"
# constants:
# - constant: "prop_slippery_turn"
# type: "double"
# value: "9/9"
# overwrite: True
probabilities:
- probability: "FaultProbability"
value: 0.2
- probability: "ProbForwardIntended"
value: 0.1
- probability: "ProbTurnIntended"
value: 0.1
modules:
- module: "Agent"
commands:
- action: "[Agent_turn_left]"
guard: "AgentIsOnSlippery"
update: "True"
overwrite: True
index: 3
- action: "[Agent_turn_right]"
guard: "AgentIsOnSlippery"
update: "True"
overwrite: True
index: [0,1]
...

80
main.cpp

@ -42,21 +42,30 @@ void print_info(boost::spirit::info const& what) {
boost::apply_visitor(walker, what.value);
}
void setProbability(const std::string& gridProperties, const std::vector<Probability> configProperties, const std::string& identifier, float& prop) {
auto start_pos = gridProperties.find(identifier);
std::string seperator = ";";
if (start_pos != std::string::npos) {
auto end_pos = gridProperties.find('\n', start_pos);
auto value = gridProperties.substr(start_pos + identifier.length() + seperator.size(), end_pos - start_pos - identifier.length());
prop = std::stod(value);
}
auto yaml_config_prop = std::find_if(configProperties.begin(), configProperties.end(), [&identifier](const Probability& obj) -> bool {return obj.probability_ == identifier;} );
if (yaml_config_prop != configProperties.end()) {
prop = (*yaml_config_prop).value_;
}
}
int main(int argc, char* argv[]) {
popl::OptionParser optionParser("Allowed options");
auto helpOption = optionParser.add<popl::Switch>("h", "help", "Print this help message.");
auto inputFilename = optionParser.add<popl::Value<std::string>>("i", "input-file", "Filename of the input file.");
auto outputFilename = optionParser.add<popl::Value<std::string>>("o", "output-file", "Filename for the output file.");
auto agentsToBeConsidered = optionParser.add<popl::Value<std::string>, popl::Attribute::optional>("a", "agents", "Which parsed agents should be considered in the output. WIP.");
auto viewForAgents = optionParser.add<popl::Value<std::string>, popl::Attribute::optional>("v", "view", "Agents for which the 'view'('direction') variable should be included. WIP.");
auto probabilisticBehaviourAgents = optionParser.add<popl::Value<std::string>, popl::Attribute::optional>("p", "prob-beh", "Agents for which we want to include probabilistic actions");
auto probabilities = optionParser.add<popl::Value<std::string>, popl::Attribute::optional>("q", "probs", "The probabilities for which probabilistic actions should be added. WIP");
auto enforceOneWays = optionParser.add<popl::Switch>("f", "force-oneways", "Enforce encoding of oneways. This entails that slippery tiles do not allow turning and have prob 1 to shift the agent by one and makes turning impossible if in a one tile wide section of the grid.");
auto configFilename = optionParser.add<popl::Value<std::string>, popl::Attribute::optional>("c", "config-file", "Filename of the predicate configuration file.");
@ -75,35 +84,6 @@ int main(int argc, char* argv[]) {
}
GridOptions gridOptions = { {}, {} };
if(agentsToBeConsidered->is_set()) {
gridOptions.agentsToBeConsidered = parseCommaSeparatedString(agentsToBeConsidered->value(0));
}
if(viewForAgents->is_set()) {
gridOptions.agentsWithView = parseCommaSeparatedString(viewForAgents->value(0));
}
if(enforceOneWays->is_set()) {
gridOptions.enforceOneWays = true;
}
if(probabilisticBehaviourAgents->is_set()) {
gridOptions.agentsWithProbabilisticBehaviour = parseCommaSeparatedString(probabilisticBehaviourAgents->value(0));
for(auto const& a : gridOptions.agentsWithProbabilisticBehaviour) {
std::cout << a << std::endl;
}
if(probabilities->is_set()) {
std::vector<std::string> parsedStrings = parseCommaSeparatedString(probabilities->value(0));
std::transform(parsedStrings.begin(), parsedStrings.end(), std::back_inserter(gridOptions.probabilitiesForActions), [](const std::string& string) {
return std::stof(string);
});
for(auto const& a : gridOptions.probabilitiesForActions) {
std::cout << a << std::endl;
}
} else {
throw std::logic_error{ "When adding agents with probabilistic behaviour, you also need to specify a list of probabilities via --probs." };
}
}
std::fstream file {outputFilename->value(0), file.trunc | file.out};
std::fstream infile {inputFilename->value(0), infile.in};
std::string line, content, background, rewards, properties;
@ -148,9 +128,11 @@ int main(int argc, char* argv[]) {
cells contentCells;
cells backgroundCells;
std::vector<Configuration> configurations;
std::vector<Probability> probabilities;
std::map<coordinates, float> stateRewards;
float faultyProbability = 0.0;
float faultyProbability = 0.1;
float probIntended = 0.9;
float probTurnIntended = 1;
try {
bool ok = phrase_parse(contentIter, contentLast, contentParser, qi::space, contentCells);
@ -159,7 +141,9 @@ int main(int argc, char* argv[]) {
// TODO }
if (configFilename->is_set()) {
YamlConfigParser parser(configFilename->value(0));
configurations = parser.parseConfiguration();
auto parseResult = parser.parseConfiguration();
configurations = parseResult.configurations_;
probabilities = parseResult.probabilities_;
}
boost::escaped_list_separator<char> seps('\\', ';', '\n');
@ -171,20 +155,18 @@ int main(int argc, char* argv[]) {
stateRewards[std::make_pair(x,y)] = reward;
}
if (!properties.empty()) {
auto faultProbabilityIdentifier = std::string("FaultProbability:");
auto start_pos = properties.find(faultProbabilityIdentifier);
auto faultProbabilityIdentifier = std::string("FaultProbability");
auto probForwardIntendedIdentifier = std::string("ProbForwardIntended");
auto probTurnIntendedIdentifier = std::string("ProbTurnIntended");
if (start_pos != std::string::npos) {
auto end_pos = properties.find('\n', start_pos);
auto value = properties.substr(start_pos + faultProbabilityIdentifier.length(), end_pos - start_pos - faultProbabilityIdentifier.length());
faultyProbability = std::stod(value);
}
setProbability(properties, probabilities, faultProbabilityIdentifier, faultyProbability);
setProbability(properties, probabilities, probForwardIntendedIdentifier, probIntended);
setProbability(properties, probabilities, probTurnIntendedIdentifier, probTurnIntended);
}
if(ok) {
Grid grid(contentCells, backgroundCells, gridOptions, stateRewards, probIntended, faultyProbability);
grid.printToPrism(std::cout, configurations , gridOptions.getModelType());
// grid.printToPrism(std::cout, configurations , gridOptions.getModelType());
std::stringstream ss;
// grid.printToPrism(file, configurations ,prism::ModelType::MDP);
grid.printToPrism(ss, configurations , gridOptions.getModelType());

60
util/ConfigYaml.cpp

@ -11,8 +11,8 @@ std::ostream& operator << (std::ostream &os, const Formula& formula) {
return os;
}
std::ostream& operator << (std::ostream& os, const Action& action) {
os << action.action_;
std::ostream& operator << (std::ostream& os, const Command& command) {
os << command.action_;
return os;
}
@ -23,8 +23,8 @@ std::ostream& operator << (std::ostream& os, const Constant& constant) {
std::ostream& operator << (std::ostream& os, const Module& module) {
os << "Module: " << module.module_ << std::endl;
for (auto& action : module.actions_) {
os << action << std::endl;
for (auto& command : module.commands_) {
os << command << std::endl;
}
return os;
}
@ -45,7 +45,7 @@ std::string Formula::createExpression() const {
return "formula " + formula_ + " = " + content_ + Configuration::configuration_identifier_;
}
std::string Action::createExpression() const {
std::string Command::createExpression() const {
if (overwrite_) {
return action_ + "\t" + guard_ + "-> " + update_ + Configuration::overwrite_identifier_;
}
@ -65,7 +65,7 @@ YAML::Node YAML::convert<Module>::encode(const Module& rhs) {
YAML::Node node;
node.push_back(rhs.module_);
node.push_back(rhs.actions_);
node.push_back(rhs.commands_);
return node;
}
@ -74,12 +74,12 @@ bool YAML::convert<Module>::decode(const YAML::Node& node, Module& rhs) {
if (!node.Type() == NodeType::Map) {
return false;
}
rhs.actions_ = node["actions"].as<std::vector<Action>>();
rhs.commands_ = node["commands"].as<std::vector<Command>>();
rhs.module_ = node["module"].as<std::string>();
return true;
}
YAML::Node YAML::convert<Action>::encode(const Action& rhs) {
YAML::Node YAML::convert<Command>::encode(const Command& rhs) {
YAML::Node node;
node.push_back(rhs.action_);
@ -90,7 +90,7 @@ YAML::Node YAML::convert<Action>::encode(const Action& rhs) {
return node;
}
bool YAML::convert<Action>::decode(const YAML::Node& node, Action& rhs) {
bool YAML::convert<Command>::decode(const YAML::Node& node, Command& rhs) {
if (!node.Type() == NodeType::Map) {
return false;
}
@ -103,7 +103,12 @@ bool YAML::convert<Action>::decode(const YAML::Node& node, Action& rhs) {
rhs.overwrite_ = node["overwrite"].as<bool>();
}
if (node["index"]) {
rhs.index_ = node["index"].as<int>();
try {
rhs.indexes_ = node["index"].as<std::vector<int>>();
}
catch(const std::exception& e) {
rhs.indexes_ = {node["index"].as<int>()};
}
}
return true;
@ -185,11 +190,32 @@ bool YAML::convert<Constant>::decode(const YAML::Node& node, Constant& rhs) {
return true;
}
YAML::Node YAML::convert<Probability>::encode(const Probability& rhs) {
YAML::Node node;
node.push_back(rhs.probability_);
node.push_back(rhs.value_);
return node;
}
bool YAML::convert<Probability>::decode(const YAML::Node& node, Probability& rhs) {
if (!node.IsDefined() || !node["probability"] || !node["value"]) {
return false;
}
rhs.probability_ = node["probability"].as<std::string>();
rhs.value_ = node["value"].as<double>();
return true;
}
const std::string Configuration::configuration_identifier_ { "; // created through configuration"};
const std::string Configuration::overwrite_identifier_{"; // Overwritten through configuration"};
std::vector<Configuration> YamlConfigParser::parseConfiguration() {
YamlConfigParseResult YamlConfigParser::parseConfiguration() {
std::vector<Configuration> configuration;
std::vector<Probability> probabilities;
try {
YAML::Node config = YAML::LoadFile(file_);
@ -211,6 +237,10 @@ const std::string Configuration::overwrite_identifier_{"; // Overwritten through
if (config["constants"]) {
constants = config["constants"].as<std::vector<Constant>>();
}
if (config["probabilities"]) {
probabilities = config["probabilities"].as<std::vector<Probability>>();
}
for (auto& label : labels) {
configuration.push_back({label.createExpression(), label.label_ , ConfigType::Label, label.overwrite_});
@ -219,14 +249,14 @@ const std::string Configuration::overwrite_identifier_{"; // Overwritten through
configuration.push_back({formula.createExpression(), formula.formula_ ,ConfigType::Formula, formula.overwrite_});
}
for (auto& module : modules) {
for (auto& action : module.actions_) {
configuration.push_back({action.createExpression(), action.action_, ConfigType::Module, action.overwrite_, module.module_, action.index_});
for (auto& command : module.commands_) {
configuration.push_back({command.createExpression(), command.action_, ConfigType::Module, command.overwrite_, module.module_, command.indexes_});
}
}
for (auto& constant : constants) {
// std::cout << constant.constant_ << std::endl;
configuration.push_back({constant.createExpression(), "const " + constant.type_ + " " + constant.constant_, ConfigType::Constant, constant.overwrite_});
}
}
}
catch(const std::exception& e) {
std::cout << "Exception '" << typeid(e).name() << "' caught:" << std::endl;
@ -234,5 +264,5 @@ const std::string Configuration::overwrite_identifier_{"; // Overwritten through
std::cout << "while parsing configuration " << file_ << std::endl;
}
return configuration;
return YamlConfigParseResult(configuration, probabilities);
}

50
util/ConfigYaml.h

@ -2,6 +2,7 @@
#include <vector>
#include <ostream>
#include <utility>
#include "yaml-cpp/yaml.h"
@ -21,7 +22,7 @@ struct Configuration
std::string module_ {};
std::string expression_{};
std::string identifier_{};
int index_{};
std::vector<int> indexes_{0};
ConfigType type_ {ConfigType::Label};
bool overwrite_ {false};
@ -32,7 +33,7 @@ struct Configuration
, ConfigType type
, bool overwrite = false
, std::string module = ""
, int index = 0) : expression_(expression), identifier_(identifier), type_(type), overwrite_(overwrite), module_{module}, index_(index) {}
, std::vector<int> indexes = {0}) : expression_(expression), identifier_(identifier), type_(type), overwrite_(overwrite), module_{module}, indexes_(indexes) {}
~Configuration() = default;
Configuration(const Configuration&) = default;
@ -43,6 +44,17 @@ struct Configuration
}
};
struct Probability {
Probability() = default;
Probability(const Probability&) = default;
~Probability() = default;
std::string probability_;
double value_;
friend std::ostream& operator <<(std::ostream& os, const Probability& property);
};
struct Constant {
private:
@ -83,23 +95,23 @@ struct Formula {
friend std::ostream& operator << (std::ostream &os, const Formula& formula);
};
struct Action {
struct Command {
public:
std::string action_;
std::string guard_;
std::string update_;
int index_{0};
std::vector<int> indexes_{0};
bool overwrite_ {false};
std::string createExpression() const;
friend std::ostream& operator << (std::ostream& os, const Action& action);
friend std::ostream& operator << (std::ostream& os, const Command& command);
};
struct Module {
public:
std::vector<Action> actions_;
std::vector<Command> commands_;
std::string module_;
friend std::ostream& operator << (std::ostream& os, const Module& module);
@ -113,9 +125,9 @@ struct YAML::convert<Module> {
};
template<>
struct YAML::convert<Action> {
static YAML::Node encode(const Action& rhs);
static bool decode(const YAML::Node& node, Action& rhs);
struct YAML::convert<Command> {
static YAML::Node encode(const Command& rhs);
static bool decode(const YAML::Node& node, Command& rhs);
};
@ -137,6 +149,22 @@ struct YAML::convert<Constant> {
static bool decode(const YAML::Node& node, Constant& rhs);
};
template<>
struct YAML::convert<Probability> {
static YAML::Node encode(const Probability& rhs);
static bool decode(const YAML::Node& node, Probability& rhs);
};
struct YamlConfigParseResult {
YamlConfigParseResult(std::vector<Configuration> configurations, std::vector<Probability> probabilities)
: configurations_(configurations), probabilities_(probabilities) {}
~YamlConfigParseResult() = default;
YamlConfigParseResult(const YamlConfigParseResult&) = default;
std::vector<Configuration> configurations_;
std::vector<Probability> probabilities_;
};
struct YamlConfigParser {
public:
@ -144,8 +172,8 @@ struct YamlConfigParser {
YamlConfigParser(const YamlConfigParser&) = delete;
~YamlConfigParser() = default;
std::vector<Configuration> parseConfiguration();
YamlConfigParseResult parseConfiguration();
private:
std::string file_;
};
};

39
util/Grid.cpp

@ -104,29 +104,30 @@ void Grid::applyOverwrites(std::string& str, std::vector<Configuration>& configu
if (!config.overwrite_) {
continue;
}
size_t start_pos;
if (config.type_ == ConfigType::Formula) {
start_pos = str.find("formula " + config.identifier_);
} else if (config.type_ == ConfigType::Label) {
start_pos = str.find("label " + config.identifier_);
} else if (config.type_ == ConfigType::Module) {
auto iter = boost::find_nth(str, config.identifier_, config.index_);
for (auto& index : config.indexes_) {
size_t start_pos;
std::string search;
if (config.type_ == ConfigType::Formula) {
search = "formula " + config.identifier_;
} else if (config.type_ == ConfigType::Label) {
search = "label " + config.identifier_;
} else if (config.type_ == ConfigType::Module) {
search = config.identifier_;
}
else if (config.type_ == ConfigType::Constant) {
search = config.identifier_;
}
auto iter = boost::find_nth(str, search, index);
start_pos = std::distance(str.begin(), iter.begin());
}
else if (config.type_ == ConfigType::Constant) {
start_pos = str.find(config.identifier_);
size_t end_pos = str.find(';', start_pos) + 1;
if (start_pos == std::string::npos) {
std::cout << "Couldn't find overwrite:" << config.expression_ << std::endl;
if (end_pos != std::string::npos && end_pos != 0) {
std::string expression = config.expression_;
str.replace(start_pos, end_pos - start_pos , expression);
}
}
size_t end_pos = str.find(';', start_pos) + 1;
std::string expression = config.expression_;
str.replace(start_pos, end_pos - start_pos , expression);
}
}
void Grid::printToPrism(std::ostream& os, std::vector<Configuration>& configuration ,const prism::ModelType& modelType) {

4
util/PrismModulesPrinter.cpp

@ -78,6 +78,10 @@ namespace prism {
}
}
if (!configuration.empty()) {
printConfiguration(configuration);
}
return os;
}

Loading…
Cancel
Save