27template <
class LTS_TYPE>
75 bool in_preorder(std::size_t s,std::size_t t)
const;
118 std::vector< std::vector<bool> >
P;
119 std::vector< std::vector<bool> >
Q;
128 void refine(
bool& change);
132 void touch(std::size_t a,std::size_t alpha);
133 void untouch(std::size_t alpha);
136 void dfs_visit(std::size_t u,std::vector<bool>& visited,
137 std::vector<std::size_t>& Sort);
141 void filter(std::size_t S,std::vector< std::vector<bool> >& R,
bool B);
142 void cleanup(std::size_t alpha,std::size_t beta);
150 std::string
print_relation(std::size_t s,std::vector< std::vector<bool> >& R);
158#define UNIVERSAL_PART (0)
160template <
class LTS_TYPE>
169template <
class LTS_TYPE>
179template <
class LTS_TYPE>
182 initialise_datastructures();
183 partitioning_algorithmG();
187template <
class LTS_TYPE>
213 mCRL2log(
log::debug) <<
"--------------------- ITERATION " << i <<
" ----------------------------------" << std::endl;
215 mCRL2log(
log::debug) <<
" iteration " << i <<
"; number of blocks: " << s_Sigma << std::endl;
240template <
class LTS_TYPE>
247 std::size_t
N = aut.num_states();
250 state_buckets.assign(
N,sb);
251 state_touched.assign(
N,
false);
258 for (std::size_t i = 0; i <
N; ++i)
262 state_buckets[i].prev = i-1;
270 state_buckets[i].next = i+1;
278 block_touched.assign(s_Pi,
false);
282 std::vector<std::size_t> vi;
283 children.assign(s_Sigma,vi);
284 std::vector<bool> vb(s_Sigma,
false);
285 P.assign(s_Sigma,vb);
286 for (std::size_t i = 0; i < s_Sigma; ++i)
288 children[i].push_back(i);
292 mCRL2log(
log::debug) <<
"--------------------- INITIALISATION ---------------------------" << std::endl;
293 mCRL2log(
log::debug) <<
" initialisation; number of blocks: " << s_Sigma << std::endl;
298template <
class LTS_TYPE>
301 std::size_t alpha, a, c;
302 std::vector<std::size_t>::iterator ci, last;
305 for (ptrdiff_t i = contents_u[gamma]; i !=
LIST_END;
306 i = state_buckets[i].next)
308 contents.push_back(std::size_t(i));
310 for (ptrdiff_t i = contents_t[gamma]; i !=
LIST_END;
311 i = state_buckets[i].next)
313 contents.push_back(std::size_t(i));
315 last = contents.end();
316 for (ci = contents.begin(); ci != last; ++ci)
321 for (outgoing_transitions_per_state_action_t::iterator
322 t=trans_index.lower_bound(std::pair < transition::size_type, transition::size_type >(c,l));
323 t!=trans_index.upper_bound(std::pair < transition::size_type, transition::size_type >(c,l)); ++t)
326 if (!state_touched[a])
330 if (!block_touched[alpha])
332 touched_blocks.push_back(alpha);
333 block_touched[alpha] =
true;
340template <
class LTS_TYPE>
343 std::vector<std::size_t>::iterator deltai, last;
344 last = children[gamma].end();
345 for (deltai = children[gamma].begin(); deltai != last; ++deltai)
347 initialise_Pi(*deltai,l);
354template <
class LTS_TYPE>
359 std::vector<std::size_t> v;
360 children.assign(s_Pi,v);
361 parent.assign(s_Pi,0);
363 for (alpha = 0; alpha < s_Pi; ++alpha)
365 children[alpha].push_back(alpha);
366 parent[alpha] = alpha;
371 mCRL2log(
log::debug) <<
"--------------------- Refine ---------------------------------------" << std::endl;
376 std::vector<std::size_t> Sort;
377 Sort.reserve(s_Sigma);
378 reverse_topological_sort(Sort);
386 std::vector<bool> v_false(s_Sigma,
false);
387 std::vector<std::size_t>::iterator alphai, last, gammai;
388 std::vector< std::vector<bool> >::iterator stable_alpha, P_gamma;
389 bool stable_alpha_gamma;
390 std::size_t gamma, delta, l;
393 for (l = 0; l < aut.num_action_labels(); ++l)
395 mCRL2log(
log::debug) <<
"---------------------------------------------------" << std::endl;
399 stable.assign(s_Pi,v_false);
402 for (gammai = Sort.begin(); gammai != Sort.end(); ++gammai)
406 touched_blocks.clear();
407 initialise_Sigma(gamma,l);
410 last = touched_blocks.end();
411 for (alphai = touched_blocks.begin(); alphai != last; ++alphai)
416 stable_alpha_gamma =
false;
417 stable_alpha = stable.begin() + alpha;
418 P_gamma = P.begin() + gamma;
419 for (delta = 0; delta < s_Sigma && !stable_alpha_gamma; ++delta)
421 if ((*stable_alpha)[delta] && (*P_gamma)[delta])
423 stable_alpha_gamma =
true;
426 (*stable_alpha)[gamma] = stable_alpha_gamma;
427 if (!stable_alpha_gamma)
435 children[parent[alpha]].push_back(s_Pi);
436 parent.push_back(parent[alpha]);
437 stable.push_back(*stable_alpha);
438 block_touched.push_back(
false);
442 contents_u.push_back(contents_u[alpha]);
446 for (ptrdiff_t i = contents_u[s_Pi]; i !=
LIST_END;
447 i = state_buckets[i].next)
453 stable[alpha][gamma] =
true;
461template <
class LTS_TYPE>
464 std::vector<bool> visited(s_Sigma,
false);
465 for (std::size_t u = 0; u < s_Sigma; ++u)
469 dfs_visit(u,visited,Sort);
474template <
class LTS_TYPE>
476 std::vector<std::size_t> &Sort)
479 for (std::size_t v = 0; v < s_Sigma; ++v)
481 if (!visited[v] && P[u][v])
483 dfs_visit(v,visited,Sort);
489template <
class LTS_TYPE>
492 state_touched[a] =
true;
493 ptrdiff_t p = state_buckets[a].prev;
494 ptrdiff_t n = state_buckets[a].next;
497 contents_u[alpha] = n;
501 state_buckets[p].next = n;
505 state_buckets[n].prev = p;
508 state_buckets[a].next = contents_t[alpha];
511 state_buckets[contents_t[alpha]].prev = a;
513 contents_t[alpha] = a;
517template <
class LTS_TYPE>
522 ptrdiff_t i = contents_t[alpha];
523 while (state_buckets[i].next !=
LIST_END)
525 state_touched[i] =
false;
526 i = state_buckets[i].next;
529 state_touched[i] =
false;
533 state_buckets[i].next = contents_u[alpha];
536 state_buckets[contents_u[alpha]].prev = i;
538 contents_u[alpha] = contents_t[alpha];
540 block_touched[alpha] =
false;
545template <
class LTS_TYPE>
549 mCRL2log(
log::debug) <<
"--------------------- Update ---------------------------------------" << std::endl;
551 std::size_t l,alpha,gamma;
552 std::vector<std::size_t>::iterator alphai, last;
559 for (l = 0; l < aut.num_action_labels(); ++l)
561 pre_exists[l].reserve(s_Sigma + 1);
562 pre_forall[l].reserve(s_Sigma + 1);
563 pre_exists[l].push_back(
exists->get_num_elements());
564 pre_forall[l].push_back(
forall->get_num_elements());
565 for (gamma = 0; gamma < s_Sigma; ++gamma)
567 touched_blocks.clear();
568 initialise_Sigma(gamma,l);
569 last = touched_blocks.end();
570 for (alphai = touched_blocks.begin(); alphai != last; ++alphai)
573 exists->add(alpha,l,gamma);
576 forall->add(alpha,l,gamma);
580 pre_exists[l].push_back(
exists->get_num_elements());
581 pre_forall[l].push_back(
forall->get_num_elements());
593 filter(s_Sigma,P,
false);
599 for (l = 0; l < aut.num_action_labels(); ++l)
601 pre_exists[l].reserve(s_Pi + 1);
602 pre_forall[l].reserve(s_Pi + 1);
603 pre_exists[l].push_back(
exists->get_num_elements());
604 pre_forall[l].push_back(
forall->get_num_elements());
605 for (gamma = 0; gamma < s_Pi; ++gamma)
607 touched_blocks.clear();
608 initialise_Pi(gamma,l);
609 last = touched_blocks.end();
610 for (alphai = touched_blocks.begin(); alphai != last; ++alphai)
613 exists->add(alpha,l,gamma);
616 forall->add(alpha,l,gamma);
620 pre_exists[l].push_back(
exists->get_num_elements());
621 pre_forall[l].push_back(
forall->get_num_elements());
636template <
class LTS_TYPE>
642 std::vector<std::size_t> v;
643 pre_exists.assign(aut.num_action_labels(),v);
644 pre_forall.assign(aut.num_action_labels(),v);
647template <
class LTS_TYPE>
651 std::vector<bool> v(s_Pi,
false);
654 std::size_t alpha,beta;
655 std::vector< std::vector<bool> >::iterator P_parent_alpha;
656 for (alpha = 0; alpha < s_Pi; ++alpha)
658 P_parent_alpha = P.begin() + parent[alpha];
659 for (beta = 0; beta < s_Pi; ++beta)
661 Q[alpha][beta] = (*P_parent_alpha)[parent[beta]];
669template <
class LTS_TYPE>
676 std::size_t alpha,beta,gamma,delta,l;
678 for (l = 0; l < aut.num_action_labels(); ++l)
680 for (delta = 0; delta < S; ++delta)
682 etrans.
set_end(pre_exists[l][delta+1]);
683 for (etrans.
set(pre_exists[l][delta]); !etrans.
is_end(); ++etrans)
685 beta = etrans.
get_x();
686 for (gamma = 0; gamma < S; ++gamma)
690 match->add(l,beta,gamma);
699 for (l = 0; l < aut.num_action_labels(); ++l)
701 for (gamma = 0; gamma < S; ++gamma)
703 atrans.
set_end(pre_forall[l][gamma+1]);
704 for (atrans.
set(pre_forall[l][gamma]); !atrans.
is_end(); ++atrans)
706 alpha = atrans.
get_x();
707 for (beta = 0; beta < s_Pi; ++beta)
709 if (Q[alpha][beta] && !match->find(l,beta,gamma))
711 Q[alpha][beta] =
false;
725template <
class LTS_TYPE>
728 std::size_t l,alpha1,beta1,delta;
729 bool match_l_beta1_alpha;
732 for (l = 0; l < aut.num_action_labels(); ++l)
734 alpha1i.
set_end(pre_forall[l][alpha+1]);
735 beta1i.
set_end(pre_exists[l][beta+1]);
736 for (beta1i.
set(pre_exists[l][beta]); !beta1i.
is_end(); ++beta1i)
738 beta1 = beta1i.
get_x();
739 match_l_beta1_alpha =
false;
740 for (delta = 0; delta < s_Pi && !match_l_beta1_alpha; ++delta)
742 if (
exists->find(beta1,l,delta) && Q[alpha][delta])
744 match_l_beta1_alpha =
true;
747 if (!match_l_beta1_alpha)
749 match->remove(l,beta1,alpha);
750 for (alpha1i.
set(pre_forall[l][alpha]); !alpha1i.
is_end();
753 alpha1 = alpha1i.
get_x();
754 if (Q[alpha1][beta1])
756 Q[alpha1][beta1] =
false;
757 cleanup(alpha1,beta1);
767template <
class LTS_TYPE>
772 std::vector < mcrl2::lts::transition> ts;
773 ts.reserve(
forall->get_num_elements());
775 std::vector<bool> pre_sim;
779 for (beta = 0; beta < s_Pi; ++beta)
781 for (l = 0; l < aut.num_action_labels(); ++l)
788 pre_sim.assign(s_Pi,
false);
789 for (gamma = 0; gamma < s_Pi; ++gamma)
792 if (gamma != beta && Q[beta][gamma])
794 alphai.
set_end(pre_exists[l][gamma+1]);
795 for (alphai.
set(pre_exists[l][gamma]); !alphai.
is_end();
798 pre_sim[alphai.
get_x()] =
true;
802 gammai.
set_end(pre_forall[l][beta+1]);
803 for (gammai.
set(pre_forall[l][beta]); !gammai.
is_end(); ++gammai)
805 gamma = gammai.
get_x();
817template <
class LTS_TYPE>
823template <
class LTS_TYPE>
829template <
class LTS_TYPE>
832 return Q[block_Pi[s]][block_Pi[t]];
835template <
class LTS_TYPE>
838 return (block_Pi[s] == block_Pi[t]);
972template <
class LTS_TYPE>
976 std::stringstream result;
977 result << print_Sigma() <<
"Simulation relation: " << print_relation(s_Sigma,P);
981template <
class LTS_TYPE>
985 std::stringstream result;
986 result << print_Pi() <<
"Simulation relation: " << print_relation(s_Pi,Q);
990template <
class LTS_TYPE>
994 std::stringstream result;
995 std::vector<std::size_t>::iterator ci, last;
996 for (std::size_t b = 0; b < s_Sigma; ++b)
998 result <<
"block " << b <<
": {";
999 last = children[b].end();
1000 for (ci = children[b].begin(); ci != last; ++ci)
1002 result << print_block(*ci);
1004 result <<
"}" << std::endl;
1006 return result.str();
1009template <
class LTS_TYPE>
1012 std::stringstream result;
1014 for (std::size_t b = 0; b < s_Pi; ++b)
1016 result <<
"block " << b <<
": {" << print_block(b) <<
"}" << std::endl;
1018 return result.str();
1021template <
class LTS_TYPE>
1024 std::stringstream result;
1026 for (ptrdiff_t i = contents_u[b]; i !=
LIST_END; i = state_buckets[i].next)
1030 for (ptrdiff_t i = contents_t[b]; i !=
LIST_END; i = state_buckets[i].next)
1034 return result.str();
1037template <
class LTS_TYPE>
1039 std::vector< std::vector<bool> > &R)
1042 std::stringstream result;
1044 std::size_t beta,gamma;
1045 for (beta = 0; beta < s; ++beta)
1047 for (gamma = 0; gamma < s; ++gamma)
1051 result <<
"(" << beta <<
"," << gamma <<
"),";
1055 result <<
"}" << std::endl;
1056 return result.str();
1059template <
class LTS_TYPE>
1063 std::stringstream result;
1069 <<
"," << i.
get_z() <<
"),";
1072 return result.str();
1075template <
class LTS_TYPE>
1079 std::stringstream result;
1080 result <<
"reverse topological sort is: [";
1081 for (std::size_t i = 0; i < Sort.size(); ++i)
1084 if (i+1 < Sort.size())
1089 result <<
"]" << std::endl;
1090 return result.str();
void set_end(std::size_t i)
existential quantification.
std::vector< ptrdiff_t > contents_t
std::string print_reverse_topological_sort(const std::vector< std::size_t > &Sort)
std::vector< std::size_t > touched_blocks
std::string print_structure(hash_table3 *struc)
std::size_t get_eq_class(std::size_t s) const
void initialise_Sigma(std::size_t gamma, std::size_t l)
std::vector< bool > state_touched
bool in_same_class(std::size_t s, std::size_t t) const
std::string print_Sigma()
std::vector< std::vector< std::size_t > > pre_forall
std::vector< ptrdiff_t > contents_u
std::vector< bool > block_touched
void dfs_visit(std::size_t u, std::vector< bool > &visited, std::vector< std::size_t > &Sort)
void cleanup(std::size_t alpha, std::size_t beta)
std::vector< std::vector< bool > > stable
std::vector< std::size_t > block_Pi
virtual void partitioning_algorithm()
void refine(bool &change)
std::string print_Sigma_P()
std::string print_relation(std::size_t s, std::vector< std::vector< bool > > &R)
mcrl2::lts::outgoing_transitions_per_state_action_t trans_index
std::size_t num_eq_classes() const
std::string print_block(std::size_t b)
std::vector< mcrl2::lts::transition > get_transitions() const
std::vector< std::vector< std::size_t > > pre_exists
std::vector< std::size_t > parent
void filter(std::size_t S, std::vector< std::vector< bool > > &R, bool B)
std::vector< state_bucket > state_buckets
std::vector< std::size_t > contents
void initialise_datastructures()
void touch(std::size_t a, std::size_t alpha)
std::vector< std::vector< bool > > P
void untouch(std::size_t alpha)
std::vector< std::vector< std::size_t > > children
void reverse_topological_sort(std::vector< std::size_t > &Sort)
std::vector< std::vector< bool > > Q
bool in_preorder(std::size_t s, std::size_t t) const
void partitioning_algorithmG()
void initialise_Pi(std::size_t gamma, std::size_t l)
A class containing triples, source label and target representing transitions.
std::size_t size_type
The type of the elements in a transition.
#define mCRL2log(LEVEL)
mCRL2log(LEVEL) provides the stream used to log.
This file contains a class that contains labelled transition systems in aut format.
This file contains a class that contains labelled transition systems in dot format.
This file contains a class that contains labelled transition systems in fsm format.
This file contains some utility functions to manipulate lts's.
normalizer< Function > N(const Function &f)
std::string pp(const abstraction &x)
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.
std::size_t to(const outgoing_pair_t &p)
Target state of a label state pair.
A class that takes a linear process specification and checks all tau-summands of that LPS for conflue...
Header file for hash table data structure used by the simulation preorder algorithm.
Checks whether condition holds for all types passed as variadic template.