18#ifndef MCRL2_LTS_LTS_UTILITIES_H
19#define MCRL2_LTS_LTS_UTILITIES_H
37 const std::set<transition::size_type>& hidden_label_set,
45 sort(transitions.begin(),transitions.end(),
compare);
51 sort(transitions.begin(),transitions.end(),
compare);
57 sort(transitions.begin(),transitions.end(),
compare);
63 sort(transitions.begin(),transitions.end(),
compare);
69 sort(transitions.begin(),transitions.end(),
compare);
76 sort(transitions.begin(),transitions.end(),
compare);
90 return std::to_string(t.
from()) +
" -" + std::to_string(t.
label()) +
"-> " + std::to_string(t.
to());
95template <
bool USE_STACK>
97 const std::vector<transition>::iterator end,
98 std::function<std::size_t(
const transition&)> get_label,
99 std::vector<std::pair<std::size_t, std::size_t>>& count_sum_transitions_per_action,
100 const std::size_t tau_label_index=0,
106 for(std::pair<std::size_t, std::size_t> p: count_sum_transitions_per_action){ assert(p.first==0); }
107 assert(todo_stack.empty());
110 if (USE_STACK) todo_stack.push_back(tau_label_index);
111 for(std::vector<transition>::iterator ti=begin; ti!=end; ++ti)
114 std::size_t
label=get_label(t);
115 if (USE_STACK &&
label!=tau_label_index && count_sum_transitions_per_action[
label].first==0)
117 todo_stack.push_back(
label);
120 count_sum_transitions_per_action[
label].first++;
130 for(std::size_t a: todo_stack)
132 sum=sum+count_sum_transitions_per_action[a].first;
133 count_sum_transitions_per_action[a].second=sum;
138 for(std::pair<std::size_t, std::size_t>& p: count_sum_transitions_per_action)
147 std::vector<transition>::iterator current_leftmost_position=begin;
148 std::vector<std::size_t>::iterator current_leftmost_label=todo_stack.begin();
149 std::size_t current_label=USE_STACK?*current_leftmost_label:0;
150 while (current_leftmost_position!=end)
157 assert(current_leftmost_label!=todo_stack.end());
158 while (count_sum_transitions_per_action[current_label].first==0)
161 current_leftmost_label++;
162 if (current_leftmost_label==todo_stack.end())
166 current_label=*current_leftmost_label;
169 if (current_leftmost_label==todo_stack.end())
176 while (current_label<count_sum_transitions_per_action.size() &&
177 count_sum_transitions_per_action[current_label].first==0)
183 if (current_label==count_sum_transitions_per_action.size())
188 current_leftmost_position=begin+
189 count_sum_transitions_per_action[current_label].second-
190 count_sum_transitions_per_action[current_label].first;
195 while (current_leftmost_position!=end && get_label(*current_leftmost_position)==current_label)
197 current_leftmost_position++;
198 count_sum_transitions_per_action[current_label].first--;
203 if (count_sum_transitions_per_action[current_label].first>0)
207 transition transition_on_the_move= *current_leftmost_position;
212 std::size_t
label=get_label(transition_on_the_move);
213 std::size_t new_position=count_sum_transitions_per_action[
label].second-count_sum_transitions_per_action[
label].first;
215 assert(0<std::distance(begin,end)-new_position);
216 count_sum_transitions_per_action[
label].first--;
218 while (get_label(*(begin+new_position))==
label)
222 count_sum_transitions_per_action[
label].first--;
224 assert(get_label(transition_on_the_move)!=get_label(*(begin+new_position)));
226 std::swap(transition_on_the_move,*(begin+new_position));
228 while (get_label(transition_on_the_move)!=current_label);
230 *current_leftmost_position=transition_on_the_move;
231 current_leftmost_position++;
232 count_sum_transitions_per_action[current_label].first--;
241 std::function<std::size_t(
const transition&)> get_label,
242 const std::size_t number_of_labels,
243 const std::size_t tau_label_index)
245 std::vector<std::pair<std::size_t, std::size_t>> count_sum_transitions_per_action(number_of_labels, {0,0});
246 std::vector<std::size_t> todo_stack;
247 group_transitions_on_label<true>(transitions.begin(), transitions.end(), get_label,
248 count_sum_transitions_per_action, tau_label_index, todo_stack);
370 const std::size_t number_of_states)
372 std::vector<std::pair<std::size_t, std::size_t>> count_sum_transitions_per_action(number_of_labels, {0,0});
373 std::vector<std::size_t> todo_stack;
375 group_transitions_on_label<true>(transitions.begin(),
378 count_sum_transitions_per_action,
382 std::vector<std::size_t> todo_stack_target;
384 std::vector<std::pair<std::size_t, std::size_t>> value_sum_counter(number_of_states, {0,0});
385 std::vector<transition>::iterator begin=transitions.begin();
386 for(std::size_t
label: todo_stack)
389 todo_stack_target.clear();
390 std::vector<transition>::iterator end=transitions.begin()+count_sum_transitions_per_action[
label].second;
391 group_transitions_on_label<true>(begin, end, [](
const std::vector<transition>::value_type& t){
return t.to(); }, value_sum_counter, 0, todo_stack_target);
398 const std::size_t number_of_labels,
399 const std::size_t tau_label_index,
400 const std::size_t number_of_states)
402 constexpr std::size_t log2cache_size = 16;
403 constexpr std::size_t one=1;
404 assert(number_of_states>0);
405 assert(number_of_states< (one << 2*log2cache_size));
406 size_t relevant_bits=(number_of_states<2?1:std::log2(number_of_states-1)+1);
407 assert((one<<relevant_bits)>=number_of_states);
408 size_t mask=0, shift=0;
409 if (relevant_bits>log2cache_size)
412 mask=(one<<(relevant_bits/2))-1;
413 shift=relevant_bits-(relevant_bits/2);
417 mask=(one<<relevant_bits)-1;
424 std::vector<std::pair<std::size_t, std::size_t>> count_sum_transitions_per_tgt1(mask+1, {0,0});
425 std::vector<std::size_t> todo_stack;
427 group_transitions_on_label<false>(transitions.begin(),
429 [shift](
const transition& t){ return (t.to()>>shift); },
430 count_sum_transitions_per_tgt1);
437 std::vector<std::pair<std::size_t, std::size_t>> count_sum_transitions_per_tgt2(mask+1, {0,0});
438 std::vector<std::size_t> todo_stack_target;
439 std::vector<std::pair<std::size_t, std::size_t>> value_sum_counter(number_of_labels, {0,0});
441 std::vector<transition>::iterator begin=transitions.begin();
442 for(std::pair<std::size_t, std::size_t>& p1: count_sum_transitions_per_tgt1)
445 std::vector<transition>::iterator end=transitions.begin()+p1.second;
447 group_transitions_on_label<false>(begin,
450 count_sum_transitions_per_tgt2);
452 std::vector<transition>::iterator begina=begin;
453 for(std::pair<std::size_t, std::size_t>& p2: count_sum_transitions_per_tgt2)
456 std::vector<transition>::iterator enda=begin+p2.second;
458 group_transitions_on_label<true>(begina,
460 [](
const std::vector<transition>::value_type& t){
return t.label(); },
464 for(std::size_t i:todo_stack)
466 if (value_sum_counter[i].first!=0)
throw mcrl2::runtime_error(
"BLAH " + std::to_string(value_sum_counter[i].first));;
467 value_sum_counter[i].second=0;
469 todo_stack_target.clear();
478 std::vector<std::size_t> todo_stack_target;
480 std::vector<std::pair<std::size_t, std::size_t>> value_sum_counter(number_of_labels, {0,0});
481 std::vector<transition>::iterator begin=transitions.begin();
482 for(std::pair<std::size_t, std::size_t>& p: count_sum_transitions_per_tgt1)
485 std::vector<transition>::iterator end=transitions.begin()+p.second;
487 group_transitions_on_label<true>(begin,
493 for(std::size_t i:todo_stack)
495 value_sum_counter[i]={0,0};
497 todo_stack_target.clear();
503 std::size_t last_state=0;
504 std::size_t last_label=tau_label_index;
505 std::unordered_set<std::size_t> seen_labels;
510 if (last_state<t.
to())
512 last_label=tau_label_index;
518 assert(last_state==t.
to());
519 if (last_label!=t.
label())
521 seen_labels.insert(last_label);
522 assert(seen_labels.count(t.
label())==0);
523 last_label=t.
label();
530template <
class LTS_TYPE>
594template <
class CONTENT>
709inline std::size_t
from(
const outgoing_transitions_per_state_action_t::const_iterator& i)
711 return i->first.first;
715inline std::size_t
label(
const outgoing_transitions_per_state_action_t::const_iterator& i)
717 return i->first.second;
721inline std::size_t
to(
const outgoing_transitions_per_state_action_t::const_iterator& i)
732 result.insert(std::pair<std::pair<transition::size_type, transition::size_type>,
transition::size_type>(
733 std::pair<transition::size_type, transition::size_type>(t.from(), t.label()), t.to()));
740 const std::vector<transition>& trans,
741 const std::set<transition::size_type>& hide_label_set)
746 result.insert(std::pair<std::pair<transition::size_type, transition::size_type>,
transition::size_type>(
747 std::pair<transition::size_type, transition::size_type>(t.from(),
detail::apply_hidden_labels(t.label(),hide_label_set)), t.to()));
758 result.insert(std::pair<std::pair<transition::size_type, transition::size_type>,
transition::size_type>(
759 std::pair<transition::size_type, transition::size_type>(t.to(), t.label()), t.from()));
766 const std::vector<transition>& trans,
767 const std::set<transition::size_type>& hide_label_set)
772 result.insert(std::pair<std::pair<transition::size_type, transition::size_type>,
transition::size_type>(
773 std::pair<transition::size_type, transition::size_type>(t.to(),
detail::apply_hidden_labels(t.label(),hide_label_set)), t.from()));
782template <
class LABEL_TYPE >
786 return LABEL_TYPE(s);
799template <
class LTS_TYPE >
803 const typename LTS_TYPE::action_label_t lab=make_divergence_label<typename LTS_TYPE::action_label_t>(
"!@*&divergence&*@!");
804 std::size_t divergent_transition_label=l.add_action(lab);
805 assert(divergent_transition_label+1==l.num_action_labels());
808 if (l.is_tau(l.apply_hidden_label_map(t.label())) && t.to()==t.from())
810 t =
transition(t.to(),divergent_transition_label,t.to());
813 return divergent_transition_label;
817template <
class LTS_TYPE >
822 if (t.label()==divergent_transition_label)
824 t =
transition(t.from(),l.tau_label_index(),t.from());
Term containing a string.
\brief A timed multi-action
A class containing the values for action labels for the .lts format.
size_t upperbound(const state_type s) const
std::vector< CONTENT > m_states_with_outgoing_or_incoming_transition
size_t lowerbound(const state_type s) const
std::vector< size_t > m_indices
std::pair< label_type, state_type > label_state_pair
indexed_sorted_vector_for_transitions(const std::vector< transition > &transitions, state_type num_states, bool outgoing)
const std::vector< CONTENT > & get_transitions() const
A class containing triples, source label and target representing transitions.
size_type from() const
The source of the transition.
size_type label() const
The label of the transition.
size_type to() const
The target of the transition.
std::size_t size_type
The type of the elements in a transition.
Standard exception class for reporting runtime errors.
This file contains a class that contains labelled transition systems in lts (mcrl2) format.
void unmark_explicit_divergence_transitions(LTS_TYPE &l, const std::size_t divergent_transition_label)
LABEL_TYPE make_divergence_label(const std::string &s)
std::size_t mark_explicit_divergence_transitions(LTS_TYPE &l)
std::size_t apply_hidden_labels(const std::size_t n, const std::set< std::size_t > &hidden_action_set)
transition_sort_style
Transition sort styles.
std::multimap< std::pair< transition::size_type, transition::size_type >, transition::size_type > outgoing_transitions_per_state_action_t
Type for exploring transitions per state and action.
outgoing_transitions_per_state_action_t transitions_per_outgoing_state_action_pair_reversed(const std::vector< transition > &trans)
Provide the transitions as a multimap accessible per from state and label, ordered backwardly.
void group_transitions_on_label_tgt(std::vector< transition > &transitions, const std::size_t number_of_labels, const std::size_t tau_label_index, const std::size_t number_of_states)
static std::vector< std::size_t > bogus_todo_stack
std::size_t to(const outgoing_pair_t &p)
Target state of a label state pair.
outgoing_transitions_per_state_action_t transitions_per_outgoing_state_action_pair(const std::vector< transition > &trans)
Provide the transitions as a multimap accessible per from state and label.
void sort_transitions(std::vector< transition > &transitions, const std::set< transition::size_type > &hidden_label_set, transition_sort_style ts=src_lbl_tgt)
Sorts the transitions using a sort style.
void group_transitions_on_tgt_label(std::vector< transition > &transitions, const std::size_t number_of_labels, const std::size_t tau_label_index, const std::size_t number_of_states)
detail::indexed_sorted_vector_for_transitions< outgoing_pair_t > outgoing_transitions_per_state_t
std::string ptr(const transition t)
Sorts the transitions on labels. Action with the tau label are put first.
std::size_t label(const outgoing_pair_t &p)
Label of a pair of a label and target state.
std::size_t from(const outgoing_transitions_per_state_action_t::const_iterator &i)
From state of an iterator exploring transitions per outgoing state and action.
void group_transitions_on_label(const std::vector< transition >::iterator begin, const std::vector< transition >::iterator end, std::function< std::size_t(const transition &)> get_label, std::vector< std::pair< std::size_t, std::size_t > > &count_sum_transitions_per_action, const std::size_t tau_label_index=0, std::vector< std::size_t > &todo_stack=bogus_todo_stack)
std::pair< transition::size_type, transition::size_type > outgoing_pair_t
Type for exploring transitions per state.
bool compare(const LTS_TYPE &l1, const LTS_TYPE &l2, const lts_equivalence eq, const bool generate_counter_examples=false, const std::string &counter_example_file="", const bool structured_output=false)
Checks whether this LTS is equivalent to another LTS.
A class that takes a linear process specification and checks all tau-summands of that LPS for conflue...
void swap(atermpp::unprotected_aterm_core &t1, atermpp::unprotected_aterm_core &t2) noexcept
Swaps two aterms.