12#include "mcrl2/utilities/unordered_map.h"
13#include "mcrl2/lts/lts_aut.h"
14#include "mcrl2/lts/detail/liblts_swap_to_from_probabilistic_lts.h"
17using namespace mcrl2::
lts;
19static void read_newline(std::istream& is,
const std::size_t line_no)
25 while (ch ==
' ' && is.good())
31 if (ch ==
'\r' && is.good())
36 if (ch !=
'\n' && !is.eof())
40 throw mcrl2::runtime_error(
"Expect a newline after the header des(...,...,...).");
44 throw mcrl2::runtime_error(
"Expect a newline after the transition at line " + std::to_string(line_no) +
".");
54 is >> std::skipws >> ch;
55 for( ; isdigit(
static_cast<
unsigned char>(ch)) ; is.get(ch))
62 throw mcrl2::runtime_error(
"Expect a number at line " + std::to_string(line_no) +
".");
66template <
class AUT_LTS_TYPE>
71 assert(labs.at(action_label_string::tau_action())==0);
72 action_label_string as(s);
73 const mcrl2::utilities::unordered_map < action_label_string, std::size_t >::const_iterator i=labs.find(as);
76 label=l.add_action(as);
86static void check_state(std::size_t state, std::size_t number_of_states, std::size_t line_no)
88 if (state>=number_of_states)
90 throw mcrl2::runtime_error(
"The state number " + std::to_string(state) +
" is not below the number of states (" +
91 std::to_string(number_of_states) +
"). Found at line " + std::to_string(line_no) +
".");
95static void check_states(mcrl2::lts::probabilistic_lts_aut_t::probabilistic_state_t& probability_state,
96 std::size_t number_of_states, std::size_t line_no)
98 if (probability_state.size()<=1)
100 check_state(probability_state.get(), number_of_states, line_no);
104 for(mcrl2::lts::probabilistic_lts_aut_t::probabilistic_state_t::state_probability_pair& p: probability_state)
106 check_state(p.state(), number_of_states, line_no);
117 mcrl2::lts::probabilistic_lts_aut_t::probabilistic_state_t& result,
118 const std::size_t line_no)
120 assert(result.size()==0);
124 is >> std::skipws >> state;
128 throw mcrl2::runtime_error(
"Expect a state number at line " + std::to_string(line_no) +
".");
133 is >> std::skipws >> ch;
136 if (!isdigit(
static_cast<
unsigned char>(ch)))
144 mcrl2::
utilities::probabilistic_arbitrary_precision_fraction remainder=mcrl2::
utilities::probabilistic_arbitrary_precision_fraction::one();
145 while (is.good() && !ready)
148 std::string enumerator;
149 read_natural_number_to_string(is,enumerator,line_no);
151 is >> std::skipws >> ch;
154 throw mcrl2::runtime_error(
"Expect a / in a probability at line " + std::to_string(line_no) +
".");
157 std::string denominator;
158 read_natural_number_to_string(is,denominator,line_no);
159 mcrl2::utilities::probabilistic_arbitrary_precision_fraction frac(enumerator,denominator);
160 remainder=remainder-frac;
161 result.add(state, frac);
163 is >> std::skipws >> state;
167 throw mcrl2::runtime_error(
"Expect a state number at line " + std::to_string(line_no) +
".");
172 is >> std::skipws >> ch;
175 if (!isdigit(
static_cast<
unsigned char>(ch)))
181 result.add(state, remainder);
187 mcrl2::lts::probabilistic_lts_aut_t::probabilistic_state_t& initial_state,
188 std::size_t& num_transitions,
189 std::size_t& num_states)
193 is >> std::skipws >> s;
197 throw mcrl2::runtime_error(
"Expect an .aut file to start with 'des'.");
201 is >> std::skipws >> ch;
205 throw mcrl2::runtime_error(
"Expect an opening bracket '(' after 'des' in the first line of a .aut file.");
208 read_probabilistic_state(is,initial_state,1);
210 is >> std::skipws >> ch;
213 throw mcrl2::runtime_error(
"Expect a comma after the first number in the first line of a .aut file.");
216 is >> std::skipws >> num_transitions;
218 is >> std::skipws >> ch;
221 throw mcrl2::runtime_error(
"Expect a comma after the second number in the first line of a .aut file.");
224 is >> std::skipws >> num_states;
230 throw mcrl2::runtime_error(
"Expect a closing bracket ')' after the third number in the first line of a .aut file.");
240 const std::size_t line_no)
243 is >> std::skipws >> ch;
253 is >> std::skipws >> from;
255 is >> std::skipws >> ch;
258 throw mcrl2::runtime_error(
"Expect that the first number is followed by a comma at line " + std::to_string(line_no) +
".");
261 is >> std::skipws >> ch;
267 is >> std::noskipws >> ch;
268 while ((ch !=
'"') && !is.eof())
275 throw mcrl2::runtime_error(
"Expect that the second item is a quoted label (using \") at line " + std::to_string(line_no) +
".");
277 is >> std::skipws >> ch;
285 while ((ch !=
',') && !is.eof())
294 throw mcrl2::runtime_error(
"Expect a comma after the quoted label at line " + std::to_string(line_no) +
".");
304 mcrl2::lts::probabilistic_lts_aut_t::probabilistic_state_t& target_probabilistic_state,
305 const std::size_t line_no)
307 if (!read_initial_part_of_an_aut_transition(is,from,label,line_no))
312 read_probabilistic_state(is,target_probabilistic_state,line_no);
318 throw mcrl2::runtime_error(
"Expect a closing bracket at the end of the transition at line " + std::to_string(line_no) +
".");
321 read_newline(is,line_no);
330 const std::size_t line_no)
332 if (!read_initial_part_of_an_aut_transition(is,from,label,line_no))
337 is >> std::skipws >> to;
343 throw mcrl2::runtime_error(
"Expect a closing bracket at the end of the transition at line " + std::to_string(line_no) +
".");
346 read_newline(is,line_no);
351 mcrl2::lts::probabilistic_lts_aut_t::probabilistic_state_t& probabilistic_state,
353 mcrl2::utilities::unordered_map < std::size_t, std::size_t>& indices_of_single_probabilistic_states,
354 mcrl2::utilities::unordered_map < mcrl2::lts::probabilistic_lts_aut_t::probabilistic_state_t, std::size_t>&
355 indices_of_multiple_probabilistic_states)
357 std::size_t fresh_index = indices_of_single_probabilistic_states.size()+indices_of_multiple_probabilistic_states.size();
360 if (probabilistic_state.size()<=1)
362 index = indices_of_single_probabilistic_states.insert(
363 std::pair< std::size_t, std::size_t>
364 (probabilistic_state.get(),fresh_index)).first->second;
368 assert(probabilistic_state.size()>1);
369 index = indices_of_multiple_probabilistic_states.insert(
370 std::pair< mcrl2::lts::probabilistic_lts_aut_t::probabilistic_state_t, std::size_t>
371 (probabilistic_state,fresh_index)).first->second;
374 if (index==fresh_index)
376 std::size_t probabilistic_state_index=l.add_and_reset_probabilistic_state(probabilistic_state);
377 assert(probabilistic_state_index==index);
378 (
void)probabilistic_state_index;
386 std::size_t line_no = 1;
387 std::size_t ntrans = 0;
388 std::size_t nstate = 0;
390 mcrl2::lts::probabilistic_lts_aut_t::probabilistic_state_t initial_probabilistic_state;
391 read_aut_header(is,initial_probabilistic_state,ntrans,nstate);
397 mcrl2::utilities::unordered_map < std::size_t, std::size_t> indices_of_single_probabilistic_states;
398 mcrl2::utilities::unordered_map < mcrl2::lts::probabilistic_lts_aut_t::probabilistic_state_t, std::size_t> indices_of_multiple_probabilistic_states;
400 check_states(initial_probabilistic_state, nstate, line_no);
404 throw mcrl2::runtime_error(
"cannot parse AUT input that has no states; at least an initial state is required.");
407 l.set_num_states(nstate,
false);
408 l.clear_transitions(ntrans);
410 mcrl2::utilities::unordered_map < action_label_string, std::size_t > action_labels;
411 action_labels[action_label_string::tau_action()]=0;
412 l.set_initial_probabilistic_state(initial_probabilistic_state);
414 mcrl2::lts::probabilistic_lts_aut_t::probabilistic_state_t probabilistic_target_state;
420 probabilistic_target_state.clear();
424 if (!read_aut_transition(is,from,s,probabilistic_target_state,line_no))
429 check_state(from, nstate, line_no);
430 check_states(probabilistic_target_state, nstate, line_no);
431 std::size_t index = add_probablistic_state(probabilistic_target_state, l, indices_of_single_probabilistic_states, indices_of_multiple_probabilistic_states);
433 l.add_transition(transition(from,find_label_index(s,action_labels,l),index));
436 if (ntrans != l.num_transitions())
438 throw mcrl2::runtime_error(
"number of transitions read (" + std::to_string(l.num_transitions()) +
439 ") does not correspond to the number of transition given in the header (" + std::to_string(ntrans) +
").");
445 std::size_t line_no = 1;
446 std::size_t ntrans = 0;
447 std::size_t nstate = 0;
449 mcrl2::lts::probabilistic_lts_aut_t::probabilistic_state_t initial_probabilistic_state;
450 read_aut_header(is,initial_probabilistic_state,ntrans,nstate);
452 if (initial_probabilistic_state.size()>1)
454 throw mcrl2::runtime_error(
"Encountered an initial probability distribution while reading an non probabilistic .aut file.");
457 check_states(initial_probabilistic_state, nstate, line_no);
461 throw mcrl2::runtime_error(
"cannot parse AUT input that has no states; at least an initial state is required.");
464 l.set_num_states(nstate,
false);
465 l.clear_transitions(ntrans);
467 mcrl2::utilities::unordered_map < action_label_string, std::size_t > action_labels;
468 action_labels[action_label_string::tau_action()]=0;
469 l.set_initial_state(initial_probabilistic_state.get());
478 if (!read_aut_transition(is,from,s,to,line_no))
483 check_state(from, nstate, line_no);
484 check_state(to, nstate, line_no);
485 l.add_transition(transition(from,find_label_index(s,action_labels,l),to));
488 if (ntrans != l.num_transitions())
490 throw mcrl2::runtime_error(
"number of transitions read (" + std::to_string(l.num_transitions()) +
491 ") does not correspond to the number of transition given in the header (" + std::to_string(ntrans) +
").");
498 mcrl2::
utilities::probabilistic_arbitrary_precision_fraction previous_probability;
499 bool first_element=
true;
500 if (prob_state.size()<=1)
502 os << prob_state.get();
506 for (
const mcrl2::lts::probabilistic_lts_aut_t::probabilistic_state_t::state_probability_pair& p: prob_state)
511 previous_probability=p.probability();
516 os <<
" " << pp(previous_probability) <<
" " << p.state();
517 previous_probability=p.probability();
527 write_probabilistic_state(l.initial_probabilistic_state(),os);
529 os <<
"," << l.num_transitions() <<
"," << l.num_states() <<
")" <<
"\n";
531 for (
const transition& t: l.get_transitions())
533 os <<
"(" << t.from() <<
",\"" << pp(l.action_label(l.apply_hidden_label_map(t.label()))) <<
"\",";
534 write_probabilistic_state(l.probabilistic_state(t.to()),os);
542 os <<
"des (" << l.initial_state() <<
"," << l.num_transitions() <<
"," << l.num_states() <<
")" <<
"\n";
544 for (
const transition& t: l.get_transitions())
546 os <<
"(" << t.from() <<
",\""
547 << pp(l.action_label(l.apply_hidden_label_map(t.label()))) <<
"\","
548 << t.to() <<
")" <<
"\n";
558 if (filename==
"" || filename==
"-")
560 read_from_aut(*
this, std::cin);
564 std::ifstream is(filename.c_str());
568 throw mcrl2::runtime_error(
"cannot open .aut file '" + filename +
".");
571 read_from_aut(*
this,is);
578 read_from_aut(*
this,is);
583 if (filename==
"" || filename==
"-")
585 write_to_aut(*
this, std::cout);
589 std::ofstream os(filename.c_str());
593 throw mcrl2::runtime_error(
"cannot create .aut file '" + filename +
".");
595 write_to_aut(*
this,os);
602 if (filename.empty() || filename==
"-")
604 read_from_aut(*
this, std::cin);
608 std::ifstream is(filename.c_str());
612 throw mcrl2::runtime_error(
"cannot open .aut file '" + filename +
".");
615 read_from_aut(*
this,is);
622 read_from_aut(*
this,is);
627 if (filename.empty() || filename==
"-")
629 write_to_aut(*
this, std::cout);
633 std::ofstream os(filename.c_str());
637 throw mcrl2::runtime_error(
"cannot create .aut file '" + filename +
".");
639 write_to_aut(*
this,os);
A simple labelled transition format with only strings as action labels.
void load(const std::string &filename)
Load the labelled transition system from a file.
void load(std::istream &is)
Load the labelled transition system from an input stream.
void save(const std::string &filename) const
Save the labelled transition system to file.
A simple labelled transition format with only strings as action labels.
void load(const std::string &filename)
Load the labelled transition system from a file.
void load(std::istream &is)
Load the labelled transition system from an input stream.
void save(const std::string &filename) const
Save the labelled transition system to file.
static void read_probabilistic_state(std::istream &is, mcrl2::lts::probabilistic_lts_aut_t::probabilistic_state_t &result, const std::size_t line_no)
static void write_probabilistic_state(const mcrl2::lts::probabilistic_lts_aut_t::probabilistic_state_t &prob_state, std::ostream &os)
static void write_to_aut(const lts_aut_t &l, std::ostream &os)
static void read_from_aut(probabilistic_lts_aut_t &l, std::istream &is)
static size_t add_probablistic_state(mcrl2::lts::probabilistic_lts_aut_t::probabilistic_state_t &probabilistic_state, probabilistic_lts_aut_t &l, mcrl2::utilities::unordered_map< std::size_t, std::size_t > &indices_of_single_probabilistic_states, mcrl2::utilities::unordered_map< mcrl2::lts::probabilistic_lts_aut_t::probabilistic_state_t, std::size_t > &indices_of_multiple_probabilistic_states)
static void read_newline(std::istream &is, const std::size_t line_no)
static void read_aut_header(std::istream &is, mcrl2::lts::probabilistic_lts_aut_t::probabilistic_state_t &initial_state, std::size_t &num_transitions, std::size_t &num_states)
static void write_to_aut(const probabilistic_lts_aut_t &l, std::ostream &os)
static bool read_initial_part_of_an_aut_transition(std::istream &is, std::size_t &from, std::string &label, const std::size_t line_no)
static void read_natural_number_to_string(std::istream &is, std::string &s, const std::size_t line_no)
static void check_states(mcrl2::lts::probabilistic_lts_aut_t::probabilistic_state_t &probability_state, std::size_t number_of_states, std::size_t line_no)
static void check_state(std::size_t state, std::size_t number_of_states, std::size_t line_no)
static bool read_aut_transition(std::istream &is, std::size_t &from, std::string &label, mcrl2::lts::probabilistic_lts_aut_t::probabilistic_state_t &target_probabilistic_state, const std::size_t line_no)
static std::size_t find_label_index(const std::string &s, mcrl2::utilities::unordered_map< action_label_string, std::size_t > &labs, AUT_LTS_TYPE &l)
static void read_from_aut(lts_aut_t &l, std::istream &is)