LearnTA  0.0.1
ota_json_parser.hh
1 
6 #pragma once
7 
8 #include <stdexcept>
9 
10 #include <boost/property_tree/ptree.hpp>
11 #include <boost/property_tree/json_parser.hpp>
12 #include <boost/foreach.hpp>
13 
14 #include "timed_automaton.hh"
15 
16 
17 namespace learnta {
18 
22  class OtaJsonParser {
23  private:
24  std::vector<Alphabet> alphabet;
25  TimedAutomaton target;
26  inline static void validateLabel(const std::string &label) {
27  if (label.size() != 1) {
28  throw std::invalid_argument("Invalid alphabet: " + label);
29  }
30  }
31  public:
32  explicit OtaJsonParser(const std::string &jsonPath) {
33  target.maxConstraints = {0};
34 
35  boost::property_tree::ptree pt;
36  boost::property_tree::read_json(jsonPath, pt);
37 
38  // Construct the alphabet
39  BOOST_FOREACH (const auto &child, pt.get_child("sigma")) {
40  learnta::OtaJsonParser::validateLabel(child.second.data());
41  this->alphabet.push_back(child.second.data().front());
42  }
43 
44  // Construct states
45  std::unordered_map<std::string, std::shared_ptr<TAState>> states;
46  const auto acceptNode = pt.get_child("accept");
47  BOOST_FOREACH (const auto &child, pt.get_child("l")) {
48  const std::string &stateName = child.second.data();
49  bool isMatch = false;
50  BOOST_FOREACH(const auto &acceptedState, acceptNode) {
51  if (acceptedState.second.data() == stateName) {
52  isMatch = true;
53  break;
54  }
55  }
56  states[stateName] = std::make_shared<TAState>(isMatch);
57  }
58 
59  // Construct the states
60  target.states.reserve(states.size());
61  std::transform(states.begin(), states.end(), std::back_inserter(target.states), [](const auto &state) {
62  return state.second;
63  });
64 
65  // Construct the initial states
66  target.initialStates = {states.at(pt.get_child("init").data())};
67 
68  // Construct the transitions
69  BOOST_FOREACH (const auto &child, pt.get_child("tran")) {
70  auto it = child.second.begin();
71  const std::string sourceName = it->second.data();
72  it = boost::next(it);
73  learnta::OtaJsonParser::validateLabel(it->second.data());
74  const Alphabet label = it->second.data().front();
75  it = boost::next(it);
76  const std::string range = it->second.data();
77  it = boost::next(it);
78  const bool reset = it->second.data() == "r";
79  it = boost::next(it);
80  const std::string targetName = it->second.data();
81 
82  // Make guard
83  std::vector<Constraint> guard;
84  const auto pos = range.find(',');
85  // Make the lower bound
86  const std::string lowerBoundString = range.substr(0, pos);
87  if (lowerBoundString != "[0") {
88  int constant = atoi(lowerBoundString.substr(1).c_str());
89  target.maxConstraints.at(0) = std::max(target.maxConstraints.at(0), constant);
90  if (lowerBoundString.front() == '[') {
91  // Closed
92  guard.push_back(ConstraintMaker(0) >= constant);
93  } else {
94  // Open
95  guard.push_back(ConstraintMaker(0) > constant);
96  }
97  }
98  // Make the upper bound
99  std::string upperBoundString = range.substr(pos + 1);
100  if (upperBoundString != "+)") {
101  if (upperBoundString.back() == ']') {
102  upperBoundString.pop_back();
103  int constant = atoi(upperBoundString.c_str());
104  target.maxConstraints.at(0) = std::max(target.maxConstraints.at(0), constant);
105  // Closed
106  guard.push_back(ConstraintMaker(0) <= atoi(upperBoundString.c_str()));
107  } else {
108  int constant = atoi(upperBoundString.c_str());
109  target.maxConstraints.at(0) = std::max(target.maxConstraints.at(0), constant);
110  // Open
111  guard.push_back(ConstraintMaker(0) < atoi(upperBoundString.c_str()));
112  }
113  }
114  const auto sourceState = states.at(sourceName);
115  const auto targetState = states.at(targetName).get();
116  TATransition::Resets resetVariables;
117  if (reset) {
118  resetVariables.emplace_back(0, 0.0);
119  }
120  if (sourceState->next.find(label) == sourceState->next.end()) {
121  sourceState->next[label] = {TATransition{targetState, resetVariables, guard}};
122  } else {
123  sourceState->next[label].emplace_back(targetState, resetVariables, guard);
124  }
125  }
126 
127  if (!target.deterministic()) {
128  throw std::invalid_argument("Nondeterministic TA is given");
129  }
130  }
131 
132  [[nodiscard]] const std::vector<Alphabet> &getAlphabet() const {
133  return alphabet;
134  }
135 
136  [[nodiscard]] const TimedAutomaton &getTarget() const {
137  return target;
138  }
139  };
140 }
Definition: constraint.hh:210
Parser of one clock TAs in the json format of https://github.com/Leslieaj/OTALearning.
Definition: ota_json_parser.hh:22
Definition: experiment_runner.hh:23
std::vector< std::shared_ptr< State > > initialStates
The initial states of this automaton.
Definition: common_types.hh:24
std::vector< std::shared_ptr< State > > states
The states of this automaton.
Definition: common_types.hh:19
A state of timed automata.
Definition: timed_automaton.hh:82
A timed automaton.
Definition: timed_automaton.hh:213
std::vector< int > maxConstraints
The maximum constraints for each clock variables.
Definition: timed_automaton.hh:215