14#ifndef MCRL2_LTS_SIGREF_H
15#define MCRL2_LTS_SIGREF_H
25typedef std::set<std::pair<std::size_t, std::size_t> >
signature_t;
28template <
class LTS_T >
54 virtual void quotient_transitions(std::set<transition>& transitions,
const std::vector<std::size_t>& partition)
56 for(std::vector<transition>::const_iterator i =
m_lts.get_transitions().begin(); i !=
m_lts.get_transitions().end(); ++i)
58 transitions.insert(
transition(partition[i->from()], i->label(), partition[i->to()]));
73template <
class LTS_T >
85 mCRL2log(
log::verbose) <<
"initialising signature computation for strong bisimulation" << std::endl;
94 for(std::vector<transition>::const_iterator i =
m_lts.get_transitions().begin(); i !=
m_lts.get_transitions().end(); ++i)
96 m_sig[i->from()].insert(std::make_pair(
m_lts.apply_hidden_label_map(i->label()), partition[i->to()]));
103template <
class LTS_T >
126 void insert(
const std::vector<std::size_t>& partition,
const std::size_t t,
const std::size_t label_,
const std::size_t block)
128 if(
m_sig[t].
insert(std::make_pair(label_, block)).second)
138 if(
m_lts.is_tau(
m_lts.apply_hidden_label_map(
label(p))) && partition[t] == partition[
to(p)])
140 insert(partition,
to(p), label_, block);
152 mCRL2log(
log::verbose) <<
"initialising signature computation for branching bisimulation" << std::endl;
160 for(std::vector<transition>::const_iterator i =
m_lts.get_transitions().begin(); i !=
m_lts.get_transitions().end(); ++i)
162 if (!(
m_lts.is_tau(
m_lts.apply_hidden_label_map(i->label())) && (partition[i->from()] == partition[i->to()])))
164 insert(partition, i->from(),
m_lts.apply_hidden_label_map(i->label()), partition[i->to()]);
170 virtual void quotient_transitions(std::set<transition>& transitions,
const std::vector<std::size_t>& partition)
172 for(std::vector<transition>::const_iterator i =
m_lts.get_transitions().begin(); i !=
m_lts.get_transitions().end(); ++i)
174 if(partition[i->from()] != partition[i->to()] || !
m_lts.is_tau(
m_lts.apply_hidden_label_map(i->label())))
176 transitions.insert(
transition(partition[i->from()],
m_lts.apply_hidden_label_map(i->label()), partition[i->to()]));
183template <
class LTS_T >
203 std::size_t unused = 1, lastscc = 1;
204 std::vector<std::size_t> scc(
m_lts.num_states(), 0);
205 std::vector<std::size_t> low(
m_lts.num_states(), 0);
206 std::stack<std::size_t> stack;
207 std::stack<std::size_t> sccstack;
212 for (std::size_t i = 0; i <
m_lts.num_states(); ++i)
216 while (!stack.empty())
218 const std::size_t vi = stack.top();
224 if (low[vi] == 0 && scc[vi] == 0)
233 for (std::size_t i=m_lts_succ_transitions.
lowerbound(vi); i<m_lts_succ_transitions.
upperbound(vi); ++i)
236 if ((low[
to(t)] == 0) && (scc[
to(t)] == 0) && (
m_lts.is_tau(
m_lts.apply_hidden_label_map(
label(t)))))
245 for (std::size_t i=m_lts_succ_transitions.
lowerbound(vi); i<m_lts_succ_transitions.
upperbound(vi); ++i)
249 low[vi] = low[vi] < low[
to(t)] ? low[vi] : low[
to(t)];
251 if (low[vi] == scc[vi])
253 std::size_t tos, scc_id = lastscc++;
254 std::vector<std::size_t> this_scc;
257 tos = sccstack.top();
261 this_scc.push_back(tos);
267 if(this_scc.size() == 1)
271 for (std::size_t i_=m_lts_succ_transitions.
lowerbound(vi); i_<m_lts_succ_transitions.
upperbound(vi); ++i_)
302 mCRL2log(
log::verbose) <<
"initialising signature computation for divergence preserving branching bisimulation" << std::endl;
315 for(std::vector<transition>::const_iterator i =
m_lts.get_transitions().begin(); i !=
m_lts.get_transitions().end(); ++i)
317 if(!(partition[i->from()] == partition[i->to()] &&
m_lts.is_tau(
m_lts.apply_hidden_label_map(i->label())))
320 insert(partition, i->from(),
m_lts.apply_hidden_label_map(i->label()), partition[i->to()]);
326 virtual void quotient_transitions(std::set<transition>& transitions,
const std::vector<std::size_t>& partition)
328 for(std::vector<transition>::const_iterator i =
m_lts.get_transitions().begin(); i !=
m_lts.get_transitions().end(); ++i)
330 if(!(partition[i->from()] == partition[i->to()] &&
m_lts.is_tau(
m_lts.apply_hidden_label_map(i->label())))
331 ||
m_sig[i->from()].find(std::make_pair(
m_lts.apply_hidden_label_map(i->label()), partition[i->to()])) !=
m_sig[i->from()].end())
333 transitions.insert(
transition(partition[i->from()],
m_lts.apply_hidden_label_map(i->label()), partition[i->to()]));
348template <
class LTS_T,
typename Signature >
370 std::stringstream os;
372 for(signature_t::const_iterator i = sig.begin(); i != sig.end() ; ++i)
374 os <<
" (" <<
pp(
m_lts.action_label(i->first)) <<
", " << i->second <<
") ";
384 std::size_t count_prev =
m_count;
385 std::size_t iterations = 0;
392 <<
" currently have " <<
m_count <<
" blocks" << std::endl;
399 std::map<signature_t, std::size_t> hashtable;
401 for(std::size_t i = 0; i <
m_lts.num_states(); ++i)
403 if(hashtable.find(
m_signature.get_signature(i)) == hashtable.end())
411 for(std::size_t i = 0; i <
m_lts.num_states(); ++i)
418 }
while (count_prev !=
m_count);
433 std::set<transition> transitions;
437 m_lts.clear_transitions();
438 for(std::set<transition>::const_iterator i = transitions.begin(); i != transitions.end(); ++i)
440 m_lts.add_transition(*i);
461 m_lts.clear_state_labels();
size_t upperbound(const state_type s) const
size_t lowerbound(const state_type s) const
const std::vector< CONTENT > & get_transitions() const
Class for computing the signature for strong bisimulation.
virtual void compute_signature(const std::vector< std::size_t > &partition)
signature_bisim(const LTS_T <s_)
Constructor.
Class for computing the signature for branching bisimulation.
virtual void compute_signature(const std::vector< std::size_t > &partition)
outgoing_transitions_per_state_t m_prev_transitions
Store the incoming transitions per state.
signature_branching_bisim(const LTS_T <s_)
Constructor
void insert(const std::vector< std::size_t > &partition, const std::size_t t, const std::size_t label_, const std::size_t block)
Insert function.
virtual void quotient_transitions(std::set< transition > &transitions, const std::vector< std::size_t > &partition)
Class for computing the signature for divergence preserving branching bisimulation.
virtual void quotient_transitions(std::set< transition > &transitions, const std::vector< std::size_t > &partition)
virtual void compute_signature(const std::vector< std::size_t > &partition)
signature_divergence_preserving_branching_bisim(const LTS_T <s_)
Constructor.
void compute_tau_sccs()
Iterative implementation of Tarjan's SCC algorithm.
std::vector< bool > m_divergent
Record for each vertex whether it is in a tau-scc.
Base class for signature computation.
const LTS_T & m_lts
The labelled transition system for which the signature is computed.
virtual const signature_t & get_signature(std::size_t i) const
Return the signature for state i.
virtual void quotient_transitions(std::set< transition > &transitions, const std::vector< std::size_t > &partition)
Compute the transitions for the quotient according to partition.
virtual void compute_signature(const std::vector< std::size_t > &partition)=0
Compute a new signature based on partition.
std::vector< signature_t > m_sig
Signature stored per state.
signature(const LTS_T <s_)
Constructor.
Signature based reductions for labelled transition systems.
void compute_partition()
Compute the partition. Repeatedly updates the signatures, and the partition, until the partition stab...
LTS_T & m_lts
The LTS that we are reducing.
void run()
Perform the reduction, modulo the equivalence for which the signature has been passed in as template ...
std::vector< std::size_t > m_partition
Current partition; for each state (std::size_t) the block in which it resides is recorded.
std::size_t m_count
The number of blocks in the current partition.
std::string print_sig(const signature_t &sig)
Print a signature (for debugging purposes)
sigref(LTS_T <s_)
Constructor.
Signature m_signature
Instance of a class performing the signature computation for the current equivalence.
void quotient()
Perform the quotient with respect to the partition that has been computed.
A class containing triples, source label and target representing transitions.
#define mCRL2log(LEVEL)
mCRL2log(LEVEL) provides the stream used to log.
This file contains some utility functions to manipulate lts's.
std::string pp(const abstraction &x)
std::size_t to(const outgoing_pair_t &p)
Target state of a label state pair.
std::set< std::pair< std::size_t, std::size_t > > signature_t
A signature is a pair of an action label and a block.
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.
std::size_t label(const outgoing_pair_t &p)
Label of a pair of a label and target state.
std::pair< transition::size_type, transition::size_type > outgoing_pair_t
Type for exploring transitions per state.
A class that takes a linear process specification and checks all tau-summands of that LPS for conflue...