You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

188 lines
7.0 KiB

11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
  1. #include "util/OptionParser.h"
  2. #include "util/MinigridGrammar.h"
  3. #include "util/Grid.h"
  4. #include "util/ConfigYaml.h"
  5. #include <iostream>
  6. #include <fstream>
  7. #include <filesystem>
  8. #include <sstream>
  9. std::vector<std::string> parseCommaSeparatedString(std::string const& str) {
  10. std::vector<std::string> result;
  11. std::stringstream stream(str);
  12. while(stream.good()) {
  13. std::string substr;
  14. getline(stream, substr, ',');
  15. substr.at(0) = std::toupper(substr.at(0));
  16. result.push_back(substr);
  17. }
  18. return result;
  19. }
  20. struct printer {
  21. typedef boost::spirit::utf8_string string;
  22. void element(string const& tag, string const& value, int depth) const {
  23. for (int i = 0; i < (depth*4); ++i) std::cout << ' ';
  24. std::cout << "tag: " << tag;
  25. if (value != "") std::cout << ", value: " << value;
  26. std::cout << std::endl;
  27. }
  28. };
  29. void print_info(boost::spirit::info const& what) {
  30. using boost::spirit::basic_info_walker;
  31. printer pr;
  32. basic_info_walker<printer> walker(pr, what.tag, 0);
  33. boost::apply_visitor(walker, what.value);
  34. }
  35. void setProbability(const std::string& gridProperties, const std::vector<Probability> configProperties, const std::string& identifier, float& prop) {
  36. auto start_pos = gridProperties.find(identifier);
  37. std::string seperator = ";";
  38. if (start_pos != std::string::npos) {
  39. auto end_pos = gridProperties.find('\n', start_pos);
  40. auto value = gridProperties.substr(start_pos + identifier.length() + seperator.size(), end_pos - start_pos - identifier.length());
  41. prop = std::stod(value);
  42. }
  43. auto yaml_config_prop = std::find_if(configProperties.begin(), configProperties.end(), [&identifier](const Probability& obj) -> bool {return obj.probability_ == identifier;} );
  44. if (yaml_config_prop != configProperties.end()) {
  45. prop = (*yaml_config_prop).value_;
  46. }
  47. }
  48. int main(int argc, char* argv[]) {
  49. popl::OptionParser optionParser("Allowed options");
  50. auto helpOption = optionParser.add<popl::Switch>("h", "help", "Print this help message.");
  51. auto inputFilename = optionParser.add<popl::Value<std::string>>("i", "input-file", "Filename of the input file.");
  52. auto outputFilename = optionParser.add<popl::Value<std::string>>("o", "output-file", "Filename for the output file.");
  53. auto configFilename = optionParser.add<popl::Value<std::string>, popl::Attribute::optional>("c", "config-file", "Filename of the predicate configuration file.");
  54. try {
  55. optionParser.parse(argc, argv);
  56. if(helpOption->count() > 0) {
  57. std::cout << optionParser << std::endl;
  58. return EXIT_SUCCESS;
  59. }
  60. } catch (const popl::invalid_option &e) {
  61. return io::printPoplException(e);
  62. } catch (const std::exception &e) {
  63. std::cerr << "Exception: " << e.what() << "\n";
  64. return EXIT_FAILURE;
  65. }
  66. GridOptions gridOptions = { {}, {} };
  67. std::fstream file {outputFilename->value(0), file.trunc | file.out};
  68. std::fstream infile {inputFilename->value(0), infile.in};
  69. std::string line, content, background, rewards, properties;
  70. std::cout << "\n";
  71. bool parsingBackground = false;
  72. bool parsingStateRewards = false;
  73. bool parsingEnvironmentProperties = false;
  74. while (std::getline(infile, line) && !line.empty()) {
  75. if(line.at(0) == '-' && line.at(line.size() - 1) == '-' && parsingBackground) {
  76. parsingStateRewards = true;
  77. parsingBackground = false;
  78. continue;
  79. } else if (line.at(0) == '-' && line.at(line.size() - 1 ) == '-' && parsingStateRewards) {
  80. parsingStateRewards = false;
  81. parsingEnvironmentProperties = true;
  82. continue;
  83. } else if(line.at(0) == '-' && line.at(line.size() - 1) == '-') {
  84. parsingBackground = true;
  85. continue;
  86. }
  87. if(!parsingBackground && !parsingStateRewards && !parsingEnvironmentProperties) {
  88. content += line + "\n";
  89. } else if (parsingBackground) {
  90. background += line + "\n";
  91. } else if(parsingStateRewards) {
  92. rewards += line + "\n";
  93. } else if (parsingEnvironmentProperties) {
  94. properties += line + "\n";
  95. }
  96. }
  97. std::cout << "\n";
  98. pos_iterator_t contentFirst(content.begin());
  99. pos_iterator_t contentIter = contentFirst;
  100. pos_iterator_t contentLast(content.end());
  101. MinigridParser<pos_iterator_t> contentParser(contentFirst);
  102. pos_iterator_t backgroundFirst(background.begin());
  103. pos_iterator_t backgroundIter = backgroundFirst;
  104. pos_iterator_t backgroundLast(background.end());
  105. MinigridParser<pos_iterator_t> backgroundParser(backgroundFirst);
  106. cells contentCells;
  107. cells backgroundCells;
  108. std::vector<Configuration> configurations;
  109. std::vector<Probability> probabilities;
  110. std::map<coordinates, float> stateRewards;
  111. float faultyProbability = 0.1;
  112. float probIntended = 0.9;
  113. float probTurnIntended = 1;
  114. try {
  115. bool ok = phrase_parse(contentIter, contentLast, contentParser, qi::space, contentCells);
  116. // TODO if(background is not empty) {
  117. ok &= phrase_parse(backgroundIter, backgroundLast, backgroundParser, qi::space, backgroundCells);
  118. // TODO }
  119. if (configFilename->is_set()) {
  120. YamlConfigParser parser(configFilename->value(0));
  121. auto parseResult = parser.parseConfiguration();
  122. configurations = parseResult.configurations_;
  123. probabilities = parseResult.probabilities_;
  124. }
  125. boost::escaped_list_separator<char> seps('\\', ';', '\n');
  126. Tokenizer csvParser(rewards, seps);
  127. for(auto iter = csvParser.begin(); iter != csvParser.end(); ++iter) {
  128. int x = std::stoi(*iter);
  129. int y = std::stoi(*(++iter));
  130. float reward = std::stof(*(++iter));
  131. stateRewards[std::make_pair(x,y)] = reward;
  132. }
  133. if (!properties.empty()) {
  134. auto faultProbabilityIdentifier = std::string("FaultProbability");
  135. auto probForwardIntendedIdentifier = std::string("ProbForwardIntended");
  136. auto probTurnIntendedIdentifier = std::string("ProbTurnIntended");
  137. setProbability(properties, probabilities, faultProbabilityIdentifier, faultyProbability);
  138. setProbability(properties, probabilities, probForwardIntendedIdentifier, probIntended);
  139. setProbability(properties, probabilities, probTurnIntendedIdentifier, probTurnIntended);
  140. }
  141. if(ok) {
  142. Grid grid(contentCells, backgroundCells, gridOptions, stateRewards, probIntended, faultyProbability);
  143. // grid.printToPrism(std::cout, configurations , gridOptions.getModelType());
  144. std::stringstream ss;
  145. // grid.printToPrism(file, configurations ,prism::ModelType::MDP);
  146. grid.printToPrism(ss, configurations , gridOptions.getModelType());
  147. std::string str = ss.str();
  148. grid.applyOverwrites(str, configurations);
  149. file << str;
  150. }
  151. } catch(qi::expectation_failure<pos_iterator_t> const& e) {
  152. std::cout << "expected: "; print_info(e.what_);
  153. std::cout << "got: \"" << std::string(e.first, e.last) << '"' << std::endl;
  154. std::cout << "Expectation failure: " << e.what() << " at '" << std::string(e.first,e.last) << "'\n";
  155. } catch(const std::exception& e) {
  156. std::cerr << "Exception '" << typeid(e).name() << "' caught:" << std::endl;
  157. std::cerr << "\t" << e.what() << std::endl;
  158. std::exit(EXIT_FAILURE);
  159. }
  160. return 0;
  161. }