11#ifndef _LIBLTS_PBISIM_GRV_H
12#define _LIBLTS_PBISIM_GRV_H
24template <
class LTS_TYPE>
36 l.num_states() <<
" states and " <<
37 l.num_transitions() <<
" transitions\n";
38 timer.
start(
"bisimulation_reduce (grv)");
41 timer.
finish(
"bisimulation_reduce (grv)");
75 std::set<transition> resulting_transitions;
77 const std::vector<transition>& trans =
aut.get_transitions();
80 resulting_transitions.insert(
87 aut.clear_transitions();
90 for (
const transition& t : resulting_transitions)
92 aut.add_transition(t);
101 std::vector<typename LTS_TYPE::probabilistic_state_t> new_probabilistic_states;
106 if (prob_block.states.size()>0)
109 new_probabilistic_states.push_back(equivalent_ps);
114 aut.clear_probabilistic_states();
117 for (
const typename LTS_TYPE::probabilistic_state_t& new_ps : new_probabilistic_states)
119 aut.add_probabilistic_state(new_ps);
122 typename LTS_TYPE::probabilistic_state_t old_initial_prob_state =
aut.initial_probabilistic_state();
124 aut.set_initial_probabilistic_state(new_initial_prob_state);
216 struct probabilistic_mark_type;
234 std::vector< embedded_list<probabilistic_state_type> >
middle;
282 const std::vector< embedded_list<action_transition_type> >&
transitions()
const
306 transition_list_with_t.
erase(*t_ptr);
357 std::size_t count_state_to_constellation=0;
361 if (t.from==t1.from &&
365 count_state_to_constellation++;
368 if (count_state_to_constellation!=*t.state_to_constellation_count_ptr)
370 mCRL2log(
log::error) <<
"Transition " << t.from <<
"--" << t.label <<
"->" << t.to <<
" has inconsistent constellation_count: " <<
371 *t.state_to_constellation_count_ptr <<
". Should be " << count_state_to_constellation <<
".\n";
380 std::size_t counted_states=0;
383 counted_states=counted_states+b.states.size();
385 assert(counted_states==c.number_of_states);
391 std::size_t counted_states=0;
394 counted_states=counted_states+b.states.size();
396 assert(counted_states==c.number_of_states);
401 assert(b.states.size()>0);
403 assert(b.marking==
nullptr);
408 assert(b.marking==
nullptr);
416 std::cerr << info <<
" ---------------------------------------------------------------------- \n";
417 std::cerr <<
"Number of action blocks " <<
action_blocks.size() <<
"\n";
423 std::cerr <<
"ACTION BLOCK INFO ------------------------\n";
424 std::cerr <<
"PARENT CONSTELLATION " << b.parent_constellation <<
"\n";
425 std::cerr <<
"NR STATES " << b.states.size() <<
"\n";
428 std::cerr <<
"INCOMING TRANS " << t.from <<
" --" << t.label <<
"-> " << t.to <<
"\n";
434 std::cerr <<
"probabilistic BLOCK INFO ------------------------\n";
435 std::cerr <<
"PARENT CONSTELLATION " << b.parent_constellation <<
"\n";
436 std::cerr <<
"NR STATES " << b.states.size() <<
"\n";
439 std::cerr <<
"INCOMING TRANS " << t.from <<
" --" << t.label <<
"-> " << t.to <<
"\n";
467 initial_action_block.
states.push_back(s);
469 assert(
aut.num_states()==initial_action_block.
states.size());
488 initial_probabilistic_block.
states.push_back(s);
490 assert(
aut.num_probabilistic_states()==initial_probabilistic_block.
states.size());
511 b.parent_constellation = 0;
512 initial_action_const.
blocks.push_back(b);
517 std::vector<std::size_t*> new_count_ptr(
aut.num_states(),
nullptr);
525 assert(t.from<new_count_ptr.size());
526 if (new_count_ptr[t.from]==
nullptr)
531 t.state_to_constellation_count_ptr = new_count_ptr[t.from];
532 (*new_count_ptr[t.from])++;
538 new_count_ptr[t.from] =
nullptr;
554 block.incoming_probabilistic_transitions.push_back(t);
557 if (initial_action_const.
blocks.size()>1)
581 at.
label = t.label();
593 for (std::size_t i = 0; i <
aut.num_probabilistic_states(); i++)
595 const typename LTS_TYPE::probabilistic_state_t& ps =
aut.probabilistic_state(i);
599 for (
const typename LTS_TYPE::probabilistic_state_t::state_probability_pair& sp_pair : ps)
602 pt.
label = sp_pair.probability();
603 pt.
to = sp_pair.state();
613 pt.
label = LTS_TYPE::probabilistic_state_t::probability_t::one();
633 static std::size_t count=0;
if (count++ == 1000) {
marked_action_blocks.shrink_to_fit(); count=0; }
645 if (parent_block.
marking==
nullptr)
651 move_list_element_back<action_state_type>(s, parent_block.
states, parent_block.
marking->
left);
659 if (0 == block_marking.action_block->states.size())
662 block_marking.action_block->states = block_marking.left;
669 new_block.
states = block_marking.left;
680 block_marking.left.clear();
681 block_marking.action_block->marking=
nullptr;
696 template <
typename LIST_ELEMENT>
699 source_list.
erase(s);
706 template<
typename LIST_ELEMENT>
709 source_list.
erase(s);
729 assert(non_trivial_action_const->
blocks.size()>=2);
747 bool already_on_non_trivial_constellations_stack =
probabilistic_constellations[B.probabilistic_block->parent_constellation].blocks.size()>1;
750 B.probabilistic_block->states = *B.large_block_ptr;
751 B.large_block_ptr->clear();
755 if (B.left.size() > 0)
762 if (B.right.size() > 0)
771 if (middle.size() > 0)
779 if (!already_on_non_trivial_constellations_stack &&
probabilistic_constellations[B.probabilistic_block->parent_constellation].blocks.size()>1)
782 assert(parent_const.
blocks.size()>1);
798 assert(non_trivial_probabilistic_const->
blocks.size()>=2);
817 bool already_on_non_trivial_constellations_stack =
action_constellations[B.action_block->parent_constellation].blocks.size()>1;
820 B.action_block->states = *B.large_block_ptr;
821 B.large_block_ptr->clear();
824 if (B.left.size() > 0)
830 if (B.right.size() > 0)
837 if (B.middle.size() > 0)
844 if (!already_on_non_trivial_constellations_stack &&
action_constellations[B.action_block->parent_constellation].blocks.size()>1)
847 assert(parent_const.
blocks.size()>1);
870 new_block.
states = states_of_new_block;
871 states_of_new_block.
clear();
905 new_block.
states = states_of_new_block;
906 states_of_new_block.
clear();
983 static std::size_t count=0;
if (count++ == 1000) {
marked_action_blocks.shrink_to_fit(); count=0; }
997 move_list_element_back<probabilistic_state_type>((s), middle_temp, B.left);
1023 B.middle.emplace_back();
1027 if (current_probability != cumulative_prob_state_pair.first)
1031 current_probability = cumulative_prob_state_pair.first;
1032 B.middle.emplace_back();
1035 move_list_element_back<probabilistic_state_type>((*s), middle_temp, B.middle.
back());
1042 if (B.left.size() > B.large_block_ptr->size())
1044 B.large_block_ptr = &B.left;
1050 if (middle_set.size() > B.large_block_ptr->size())
1052 B.large_block_ptr = &middle_set;
1057 B.probabilistic_block->marking =
nullptr;
1070 assert(action_walker_begin!=action_walker_end && action_walker_begin->label==a);
1077 action_walker!=action_walker_end && action_walker->label==a;
1122 move_list_element_back<action_state_type>(s, B.left, B.middle);
1131 if (B.left.size() > B.large_block_ptr->size())
1133 B.large_block_ptr = &B.left;
1135 if (B.middle.size() > B.large_block_ptr->size())
1137 B.large_block_ptr = &B.middle;
1141 B.action_block->marking =
nullptr;
1147 action_walker_begin!=action_walker_end && action_walker_begin->label==a;
1148 action_walker_begin++)
1182 assert(non_trivial_action_const->
blocks.size()>=2);
1191 Bc = &non_trivial_action_const->
blocks.back();
1196 non_trivial_action_const->
blocks.erase(*Bc);
1202 if (non_trivial_action_const->
blocks.size() > 1)
1213 new_action_const.
blocks.push_back(*Bc);
1231 Bc = &non_trivial_probabilistic_const->
blocks.back();
1236 non_trivial_probabilistic_const->
blocks.erase(*Bc);
1242 if (non_trivial_probabilistic_const->
blocks.size() > 1)
1252 new_probabilistic_const.
blocks.push_back(*Bc);
1260 typename LTS_TYPE::probabilistic_state_t new_prob_state;
1265 std::map <state_key_type, probability_fraction_type> prob_state_map;
1266 for (
const typename LTS_TYPE::probabilistic_state_t::state_probability_pair& sp_pair : ps)
1271 if (prob_state_map.count(new_state) == 0)
1274 prob_state_map[new_state] = sp_pair.probability();
1279 prob_state_map[new_state] = prob_state_map[new_state] + sp_pair.probability();
1283 typename std::map<state_key_type, probability_fraction_type>::iterator i = prob_state_map.begin();
1284 if (++i==prob_state_map.end())
1286 new_prob_state.set(prob_state_map.begin()->first);
1291 for (
const auto& i: prob_state_map)
1293 new_prob_state.add(i.first, i.second);
1302 return new_prob_state;
1308 assert(pb.
states.size()>0);
1316 const typename LTS_TYPE::probabilistic_state_t& old_prob_state =
aut.probabilistic_state(s_key);
1330template <
class LTS_TYPE>
1338template <
class LTS_TYPE>
1348template <
class LTS_TYPE>
1351template <
class LTS_TYPE>
1358 l.clear_state_labels();
1366template <
class LTS_TYPE>
1372 LTS_TYPE l1_copy(l1);
1373 LTS_TYPE l2_copy(l2);
1377template <
class LTS_TYPE>
1383 std::size_t initial_probabilistic_state_key_l1;
1384 std::size_t initial_probabilistic_state_key_l2;
1392 initial_probabilistic_state_key_l2 = l1.num_probabilistic_states() - 1;
1393 initial_probabilistic_state_key_l1 = l1.num_probabilistic_states() - 2;
1398 initial_probabilistic_state_key_l1);
void add_grouped_transitions_to_block(probabilistic_block_type &block)
void add_single_transition(action_transition_type &t)
std::stack< label_type > m_occupancy_indicator
std::vector< embedded_list< action_transition_type > > m_transitions_per_label
void add_transitions(std::vector< action_transition_type > &transitions)
void initialize(const std::size_t number_of_labels)
void move_incoming_transitions(probabilistic_state_type s, embedded_list< action_transition_type > &transition_list_with_t)
const std::vector< embedded_list< action_transition_type > > & transitions() const
std::deque< action_mark_type > marked_action_blocks
std::vector< std::pair< probability_label_type, probabilistic_state_type * > > grouped_states_per_probability_in_block
transitions_per_label_t transitions_per_label
std::deque< probabilistic_block_type > probabilistic_blocks
void refine_partition_until_it_becomes_stable(void)
Refine partition until it becomes stable.
std::size_t state_key_type
void split_action_block(action_block_type &block_to_split, embedded_list< action_state_type > &states_of_new_block)
Split an action block.
std::stack< action_constellation_type * > non_trivial_action_constellations
LTS_TYPE::probabilistic_state_t calculate_new_probabilistic_state(typename LTS_TYPE::probabilistic_state_t ps)
LTS_TYPE::probabilistic_state_t calculate_equivalent_probabilistic_state(probabilistic_block_type &pb)
std::size_t get_eq_probabilistic_class(const std::size_t s)
Gives the bisimulation equivalence probabilistic class number of a probabilistic state.
std::size_t transition_key_type
void move_list_element_back(LIST_ELEMENT &s, embedded_list< LIST_ELEMENT > &source_list, embedded_list< LIST_ELEMENT > &dest_list)
LTS_TYPE::probabilistic_state_t::probability_t probability_label_type
std::vector< probabilistic_state_type > probabilistic_states
bool in_same_probabilistic_class_grv(const std::size_t s, const std::size_t t)
Returns whether two states are in the same probabilistic bisimulation equivalence class.
std::stack< probabilistic_constellation_type * > non_trivial_probabilistic_constellations
void print_structure(const std::string &info)
std::size_t constellation_key_type
std::vector< action_transition_type > action_transitions
std::size_t block_key_type
bool check_data_structure()
void mark_probabilistic(const action_block_type &Bc, std::deque< probabilistic_mark_type > &marked_probabilistic_blocks)
Gives the probabilistic blocks that are marked by block Bc.
probabilistic_block_type * choose_probabilistic_splitter(probabilistic_constellation_type *non_trivial_probabilistic_const)
Choose an splitter block from a non trivial constellation.
LTS_TYPE::probabilistic_state_t::probability_t probability_fraction_type
action_block_type * choose_action_splitter(action_constellation_type *non_trivial_action_const)
Choose an splitter block from a non trivial constellation.
prob_bisim_partitioner_grv(LTS_TYPE &l, utilities::execution_timer &timer)
Creates a probabilistic bisimulation partitioner for an PLTS.
std::size_t get_eq_class(const std::size_t s)
Gives the bisimulation equivalence class number of a state.
void mark_action(std::deque< action_mark_type > &marked_action_blocks, const label_type &a, typename embedded_list< action_transition_type >::iterator &action_walker_begin, const typename embedded_list< action_transition_type >::iterator action_walker_end)
Gives the action blocks that are marked by probabilistic block Bc.
std::deque< probabilistic_transition_type > probabilistic_transitions
std::deque< action_constellation_type > action_constellations
std::vector< action_state_type > action_states
void preprocessing_stage()
void replace_transitions()
Replaces the transition relation of the current lts by the transitions of the bisimulation reduced tr...
std::deque< action_block_type > action_blocks
void refine_initial_action_block(const std::vector< embedded_list< action_transition_type > > &transitions_per_label)
void replace_probabilistic_states()
Replaces the probabilistic states of the current lts by the probabilistic states of the bisimulation ...
void create_initial_partition(void)
std::deque< probabilistic_constellation_type > probabilistic_constellations
void split_probabilistic_block(probabilistic_block_type &block_to_split, embedded_list< probabilistic_state_type > &states_of_new_block)
Split a probabilistic block.
std::size_t num_eq_classes() const
Gives the number of bisimulation equivalence classes of the LTS.
std::deque< std::size_t > state_to_constellation_count
std::deque< probabilistic_mark_type > marked_probabilistic_blocks
void move_list_element_front(LIST_ELEMENT &s, embedded_list< LIST_ELEMENT > &source_list, embedded_list< LIST_ELEMENT > &dest_list)
Move an element of a list to the front of another the list.
A class containing triples, source label and target representing transitions.
Simple timer to time the CPU time used by a piece of code.
void start(const std::string &timing_name)
Start measurement with a hint.
void finish(const std::string &timing_name)
Finish a measurement with a hint.
Class to obtain running times of code.
#define mCRL2log(LEVEL)
mCRL2log(LEVEL) provides the stream used to log.
void probabilistic_bisimulation_reduce_grv(LTS_TYPE &l, utilities::execution_timer &timer)
Reduce transition system l with respect to probabilistic bisimulation.
bool probabilistic_bisimulation_compare_grv(const LTS_TYPE &l1, const LTS_TYPE &l2, utilities::execution_timer &timer)
Checks whether the two initial states of two plts's are probabilistic bisimilar.
void plts_merge(LTS_TYPE &l1, const LTS_TYPE &l2)
bool destructive_probabilistic_bisimulation_compare_grv(LTS_TYPE &l1, LTS_TYPE &l2, utilities::execution_timer &timer)
Checks whether the two initial states of two plts's are probabilistic bisimilar.
A class that takes a linear process specification and checks all tau-summands of that LPS for conflue...
embedded_list< probabilistic_transition_type > incoming_probabilistic_transitions
embedded_list< action_state_type > states
action_mark_type * marking
constellation_key_type parent_constellation
embedded_list< action_block_type > blocks
std::size_t number_of_states
embedded_list< action_state_type > * large_block_ptr
embedded_list< action_state_type > right
embedded_list< action_state_type > left
action_mark_type(action_block_type &B)
embedded_list< action_state_type > middle
action_block_type * action_block
std::vector< probabilistic_transition_type * > incoming_transitions
std::size_t * transition_count_ptr
std::size_t residual_transition_cnt
block_key_type parent_block
std::size_t * state_to_constellation_count_ptr
embedded_list< action_transition_type > incoming_action_transitions
probabilistic_block_type()
constellation_key_type parent_constellation
embedded_list< probabilistic_state_type > states
probabilistic_mark_type * marking
embedded_list< probabilistic_block_type > blocks
std::size_t number_of_states
probabilistic_mark_type(probabilistic_block_type &B)
embedded_list< probabilistic_state_type > left
probabilistic_block_type * probabilistic_block
std::vector< embedded_list< probabilistic_state_type > > middle
embedded_list< probabilistic_state_type > right
embedded_list< probabilistic_state_type > * large_block_ptr
block_key_type parent_block
std::vector< action_transition_type * > incoming_transitions
probability_label_type cumulative_probability
probability_label_type label