12#ifndef MCRL2_LTS_DETAIL_FSM_BUILDER_H
13#define MCRL2_LTS_DETAIL_FSM_BUILDER_H
16#include "mcrl2/lts/lts_fsm.h"
17#include "mcrl2/utilities/parse_numbers.h"
24 std::size_t n=s.find(c1);
27 n=std::min(n,s.find(c2));
29 if (n==std::string::npos)
33 throw mcrl2::runtime_error(
"Expect '" + c1 +
"' in distribution " + s +
".");
37 throw mcrl2::runtime_error(
"Expect either '" + c1 +
"' or '" + c2 +
" in distribution " + s +
".");
40 std::string result=s.substr(0,n);
47 if (distribution.find(
'[')==std::string::npos)
49 std::size_t state_number=utilities::parse_natural_number(distribution);
52 throw mcrl2::runtime_error(
"Transition has a zero as target state number.");
54 return lts_fsm_base::probabilistic_state(state_number-1);
58 std::vector<lts_fsm_base::state_probability_pair> result;
59 std::string s = utilities::trim_copy(distribution);
60 if (!s.starts_with(
"["))
62 throw mcrl2::runtime_error(
"Distribution does not start with ']': " + distribution +
".");
65 for(; s.size() > 1; s = utilities::trim_copy(s))
67 std::size_t state_number = utilities::parse_natural_number(split_string_until(s,
" "));
68 if (state_number == 0)
70 throw mcrl2::runtime_error(
"Transition has a zero as target state number.");
72 std::string enumerator = split_string_until(s,
"/");
73 std::string denominator = split_string_until(s,
" ",
"]");
74 result.emplace_back(state_number - 1, utilities::probabilistic_arbitrary_precision_fraction(enumerator,denominator));
76 return lts_fsm_base::probabilistic_state(result.begin(), result.end());
88 fsm_parameter(
const std::string& name,
const std::string& cardinality,
const std::string& sort,
const std::vector<std::string>& values)
118 return m_cardinality;
123 return m_cardinality;
153 if (source == 0 || target == 0)
155 throw mcrl2::runtime_error(
"A transition contains a state with state number 0.");
159 fsm_transition(
const std::string& source_text,
const std::string& target_text,
const std::string& label)
162 std::size_t source = utilities::parse_natural_number(source_text);
165 throw mcrl2::runtime_error(
"A transition constains a source state with number 0.");
167 m_source = source - 1;
168 m_target = parse_distribution(target_text);
225 labels[action_label_string::tau_action()] = 0;
232 if (distribution.size()>1)
234 for (
const detail::lts_fsm_base::state_probability_pair& p: distribution)
236 max = std::max(max, p.state());
241 max=distribution.get();
246 void add_transition(
const std::string& source,
const std::string& target,
const std::string& label)
251 std::size_t max = std::max(t.source(),find_maximal_state_index(t.target()))+1;
253 if (
fsm.num_states() <= max)
255 fsm.set_num_states(max,
fsm.has_state_info());
257 auto i = labels.find(t.label());
258 lts_fsm_t::labels_size_type label_index = 0;
259 if (i == labels.end())
261 assert(t.label() != action_label_string::tau_action());
262 label_index = fsm.add_action(action_label_string(t.label()));
263 labels[t.label()] = label_index;
267 label_index = i->second;
270 const std::size_t probabilistic_state_index = fsm.add_probabilistic_state(detail::lts_fsm_base::probabilistic_state(t.target()));
271 fsm.add_transition(transition(t.source(), label_index, probabilistic_state_index));
276 fsm.add_state(state_label_fsm(values));
279 void add_parameter(
const std::string& name,
const std::string& cardinality,
const std::string& sort,
const std::vector<std::string>& domain_values)
281 parameters.emplace_back(name, cardinality, sort, domain_values);
286 const lts_fsm_base::probabilistic_state d=parse_distribution(distribution);
287 std::size_t max=find_maximal_state_index(d)+1;
289 if (
fsm.num_states() <= max)
291 fsm.set_num_states(max,
fsm.has_state_info());
293 fsm.add_probabilistic_state(detail::lts_fsm_base::probabilistic_state(d));
295 fsm.set_initial_probabilistic_state(d);
301 std::size_t index = 0;
302 for (
const fsm_parameter& param: parameters)
304 if (param.cardinality() > 0)
306 fsm.add_process_parameter(param.name(), param.sort());
307 for (
const std::string& value: param.values())
309 fsm.add_state_element_value(index, value);
319 if (
fsm.num_states() == 0)
325 fsm.set_initial_probabilistic_state(detail::lts_fsm_base::probabilistic_state(0));
function object to compare two constln_t pointers based on their contents
std::vector< std::string > m_values
std::size_t m_cardinality
const std::vector< std::string > & values() const
std::size_t cardinality() const
const std::string & name() const
fsm_parameter(const std::string &name, const std::string &cardinality, const std::string &sort, const std::vector< std::string > &values)
std::vector< std::string > & values()
const std::string & sort() const
std::size_t & cardinality()
const std::string & label() const
const lts_fsm_base::probabilistic_state & target() const
lts_fsm_base::probabilistic_state & target()
fsm_transition(std::size_t source, std::size_t target, const std::string &label)
fsm_transition(const std::string &source_text, const std::string &target_text, const std::string &label)
detail::lts_fsm_base::probabilistic_state m_target
std::size_t source() const
std::vector< std::string > parse_domain_values(const std::string &text)
void run(std::istream &from)
void parse_parameter(const std::string &line)
states next_state(states state)
const std::regex regex_quoted_string
void parse_state(const std::string &line)
const std::regex regex_parameter
simple_fsm_parser(probabilistic_lts_fsm_t &fsm)
const std::regex regex_transition
void parse_initial_distribution(const std::string &line)
detail::fsm_builder builder
void parse_transition(const std::string &line)
const std::regex regex_probabilistic_initial_distribution
A class to contain labelled transition systems in graphviz format.
void save(const std::string &filename) const
Save the labelled transition system to a file.
void save(std::ostream &os) const
Save the labelled transition system to a stream.
A class to contain labelled transition systems in graphviz format.
void save(std::ostream &os) const
Save the labelled transition system to a stream.
void save(const std::string &filename) const
Save the labelled transition system to a file.
The class lts_fsm_t contains labelled transition systems in .fsm format.
std::string split_string_until(std::string &s, const std::string &c1, const std::string &c2="")
lts_fsm_base::probabilistic_state parse_distribution(const std::string &distribution)
void parse_fsm_specification(std::istream &from, probabilistic_lts_fsm_t &result)
void parse_fsm_specification(const std::string &text, probabilistic_lts_fsm_t &result)
fsm_builder(probabilistic_lts_fsm_t &fsm_)
std::map< std::string, std::size_t > labels
void add_initial_distribution(const std::string &distribution)
void add_state(const std::vector< std::size_t > &values)
probabilistic_lts_fsm_t & fsm
void add_parameter(const std::string &name, const std::string &cardinality, const std::string &sort, const std::vector< std::string > &domain_values)
void add_transition(const std::string &source, const std::string &target, const std::string &label)
bool m_initial_state_is_set
std::vector< fsm_parameter > parameters
std::size_t find_maximal_state_index(const lts_fsm_base::probabilistic_state &distribution)