19#define BRANCH_BIS_EXPERIMENT_JFG
21#ifndef MCRL2_LTS_LTS_ALGORITHM_H
22#define MCRL2_LTS_LTS_ALGORITHM_H
27#ifdef BRANCH_BIS_EXPERIMENT_JFG
51template <
class LTS_TYPE>
68template <
class LTS_TYPE>
72 const bool generate_counter_examples =
false,
73 const std::string& counter_example_file = std::string(),
74 const bool structured_output =
false)
87 if (generate_counter_examples)
102#ifdef BRANCH_BIS_EXPERIMENT_JFG
110 if (generate_counter_examples)
112 mCRL2log(
mcrl2::log::warning) <<
"The default branching bisimulation comparison algorithm cannot generate counter examples. A slower partition refinement algorithm (Martens/Groote 2024) is used instead.\n";
125#ifdef BRANCH_BIS_EXPERIMENT_JFG
133 if (generate_counter_examples)
135 mCRL2log(
mcrl2::log::warning) <<
"The default divergence-preserving branching bisimulation comparison algorithm cannot generate counter examples. Therefore the slower gv algorithm is used instead.\n";
148#ifdef BRANCH_BIS_EXPERIMENT_JFG
156 if (generate_counter_examples)
164 if (generate_counter_examples)
166 mCRL2log(
log::warning) <<
"Cannot generate counter examples for divergence-preserving weak bisimulation\n";
172 if (generate_counter_examples)
177 std::size_t init_l2 = l2.initial_state() + l1.num_states();
187 if (generate_counter_examples)
189 mCRL2log(
log::warning) <<
"Cannot generate counter examples for ready-simulation equivalence\n";
192 std::size_t init_l2 = l2.initial_state() + l1.num_states();
211 if (generate_counter_examples)
219 if (generate_counter_examples)
262template <
class LTS_TYPE>
263bool compare(
const LTS_TYPE& l1,
266 const bool generate_counter_examples =
false,
267 const std::string& counter_example_file =
"",
268 const bool structured_output =
false);
291template <
class LTS_TYPE >
295 const bool generate_counter_example,
296 const std::string& counter_example_file =
"",
297 const bool structured_output =
false,
299 const bool preprocess =
true);
315template <
class LTS_TYPE >
316bool compare(
const LTS_TYPE& l1,
319 const bool generate_counter_example,
320 const std::string& counter_example_file =
"",
321 const bool structured_output =
false,
323 const bool preprocess =
true);
326template <
class LTS_TYPE>
340template <
class SL,
class AL,
class BASE>
346 std::vector < bool > visited(l.num_states(),
false);
347 std::stack<std::size_t> todo;
349 visited[l.initial_state()]=
true;
350 todo.push(l.initial_state());
352 while (!todo.empty())
354 std::size_t state_to_consider=todo.top();
360 assert(visited[state_to_consider] && state_to_consider<l.num_states() &&
to(p)<l.num_states());
373 bool all_reachable = find(visited.begin(),visited.end(),
false)==visited.end();
375 if (!all_reachable && remove_unreachable)
380 std::vector < detail::state_type > state_map(l.num_states());
381 std::vector < detail::state_type > label_map(l.num_action_labels());
383 lts < SL, AL, BASE> new_lts=l;
386 std::size_t new_nstates = 0;
387 for (std::size_t i=0; i<l.num_states(); i++)
391 state_map[i] = new_nstates;
392 if (l.has_state_info())
394 new_lts.add_state(l.state_label(i));
404 for (
const transition& t: l.get_transitions())
406 if (visited[t.from()])
408 label_map[t.label()] = 1;
413 std::size_t new_nlabels = 0;
414 for (std::size_t i=0; i<l.num_action_labels(); i++)
418 label_map[i] = new_nlabels;
419 new_lts.add_action(l.action_label(i));
424 for (
const transition& t: l.get_transitions())
426 if (visited[t.from()])
428 new_lts.add_transition(
transition(state_map[t.from()],label_map[t.label()],state_map[t.to()]));
432 new_lts.set_initial_state(state_map.at(l.initial_state()));
436 return all_reachable;
449template <
class SL,
class AL,
class PROBABILISTIC_STATE,
class BASE>
450bool reachability_check(probabilistic_lts < SL, AL, PROBABILISTIC_STATE, BASE>& l,
bool remove_unreachable =
false)
455 std::vector < bool > visited(l.
num_states(),
false);
456 std::stack<std::size_t> todo;
462 visited[s.state()]=
true;
463 todo.push(s.state());
473 while (!todo.empty())
475 std::size_t state_to_consider=todo.top();
487 if (!visited[pr.state()])
489 visited[pr.state()]=
true;
490 todo.push(pr.state());
510 bool all_reachable = find(visited.begin(),visited.end(),
false)==visited.end();
512 if (!all_reachable && remove_unreachable)
517 std::vector < detail::state_type > state_map(l.
num_states());
520 probabilistic_lts < SL, AL, PROBABILISTIC_STATE, BASE> new_lts=l;
523 std::size_t new_nstates = 0;
528 state_map[i] = new_nstates;
543 if (visited[t.from()])
545 label_map[t.label()] = 1;
550 std::size_t new_nlabels = 0;
555 label_map[i] = new_nlabels;
563 if (visited[t.from()])
569 PROBABILISTIC_STATE new_initial_state;
572 new_initial_state.clear();
579 for(
const typename PROBABILISTIC_STATE::state_probability_pair& s: l.
probabilistic_state(i))
581 new_initial_state.add(state_map[s.state()], s.probability());
587 new_initial_state.clear();
596 new_initial_state.add(state_map[s.state()], s.probability());
603 return all_reachable;
609template <
class LTS_TYPE>
616template <
class LTS_TYPE>
617void merge(LTS_TYPE& l1,
const LTS_TYPE& l2)
628template <
class LTS_TYPE>
651#ifdef BRANCH_BIS_EXPERIMENT_JFG
679#ifdef BRANCH_BIS_EXPERIMENT_JFG
707#ifdef BRANCH_BIS_EXPERIMENT_JFG
772 l.clear_state_labels();
773 l.clear_transitions();
777 l.set_initial_state(sp.
get_eq_class(l.initial_state()));
780 l.clear_transitions();
781 for (std::vector <transition>::const_iterator i=trans.begin(); i!=trans.end(); ++i)
783 l.add_transition(*i);
799 l.clear_state_labels();
800 l.clear_transitions();
804 l.set_initial_state(rsp.
get_eq_class(l.initial_state()));
807 l.clear_transitions();
808 for (std::vector <transition>::const_iterator i=trans.begin(); i!=trans.end(); ++i)
810 l.add_transition(*i);
849template <
class LTS_TYPE>
850bool compare(
const LTS_TYPE& l1,
const LTS_TYPE& l2,
const lts_equivalence eq,
const bool generate_counter_examples,
const std::string& counter_example_file,
const bool structured_output)
857 LTS_TYPE l1_copy(l1);
858 LTS_TYPE l2_copy(l2);
859 return destructive_compare(l1_copy, l2_copy, eq ,generate_counter_examples, counter_example_file, structured_output);
864template <
class LTS_TYPE>
865bool compare(
const LTS_TYPE& l1,
const LTS_TYPE& l2,
const lts_preorder pre,
const bool generate_counter_example,
const std::string& counter_example_file,
const bool structured_output,
const lps::exploration_strategy strategy,
const bool preprocess)
867 LTS_TYPE l1_copy(l1);
868 LTS_TYPE l2_copy(l2);
869 return destructive_compare(l1_copy, l2_copy, pre, generate_counter_example, counter_example_file, structured_output, strategy, preprocess);
872template <
class LTS_TYPE>
883 const std::size_t init_l2 = l2.initial_state() + l1.num_states();
901 const std::size_t init_l2 = l2.initial_state() + l1.num_states();
911 return rsp.
in_preorder(l1.initial_state(),init_l2);
949 if (generate_counter_example)
958 if (generate_counter_example)
967 if (generate_counter_example)
976 if (generate_counter_example)
985 if (generate_counter_example)
999template <
class LTS_TYPE>
1002 if (l.num_transitions() == 0)
1007 std::vector<transition> temporary_copy_of_transitions = l.get_transitions();
1012 transition& previous_t=temporary_copy_of_transitions[0];
1013 bool previous_t_is_valid=
false;
1014 for(
const transition& t: temporary_copy_of_transitions)
1016 if (previous_t_is_valid)
1018 if (previous_t.
from()==t.from() &&
1019 previous_t.
label()==t.label() &&
1020 previous_t.
to()!=t.to())
1026 previous_t_is_valid=
true;
1035template <
class LTS_TYPE>
1039 std::vector<transition>& d_trans,
1066template <
class LTS_TYPE>
1071 std::vector<transition> d_transs;
1072 std::vector<std::ptrdiff_t> d_states;
1075 d_states.push_back(l.initial_state());
1081 l.clear_transitions();
1082 l.clear_state_labels();
1083 std::size_t d_ntransitions = 0;
1084 std::vector < transition > d_transitions;
1087 std::size_t i,
to,lbl,n_t;
1097 sort(d_transs.begin(),d_transs.end(),
compare);
1099 n_t = d_transs.size();
1101 for (lbl = 0; lbl < l.num_action_labels(); ++lbl)
1104 while (i < n_t && l.apply_hidden_label_map(d_transs[i].label()) < lbl)
1108 while (i < n_t && l.apply_hidden_label_map(d_transs[i].label()) == lbl)
1110 to = d_transs[i].to();
1111 d_states.push_back(
to);
1112 while (i < n_t && l.apply_hidden_label_map(d_transs[i].label()) == lbl &&
1113 d_transs[i].to() ==
to)
1125 if (d_ntransitions%10000 == 0)
1128 "generated " << tss.
get_next_tag() <<
" states and " << d_ntransitions
1129 <<
" transitions; explored " << d_id <<
" states" << std::endl;
1139 l.set_num_states(d_id,
false);
1140 l.set_initial_state(0);
1144 l.add_transition(t);
A class that can be used to store counterexample trees and.
size_t upperbound(const state_type s) const
size_t lowerbound(const state_type s) const
const std::vector< CONTENT > & get_transitions() const
virtual void partitioning_algorithm()
std::size_t get_eq_class(std::size_t s) const
bool in_same_class(std::size_t s, std::size_t t) const
virtual void partitioning_algorithm()
std::size_t num_eq_classes() const
std::vector< mcrl2::lts::transition > get_transitions() const
bool in_preorder(std::size_t s, std::size_t t) const
labels_size_type num_action_labels() const
Gets the number of action labels of this LTS.
void add_transition(const transition &t)
Add a transition to the lts.
states_size_type num_states() const
Gets the number of states of this LTS.
ACTION_LABEL_T action_label(const labels_size_type action) const
Gets the label of an action.
bool has_state_info() const
Checks whether this LTS has state values associated with its states.
STATE_LABEL_T state_label(const states_size_type state) const
Gets the label of a state.
states_size_type add_state(const STATE_LABEL_T &label=STATE_LABEL_T())
Adds a state to this LTS.
const std::vector< transition > & get_transitions() const
Gets a const reference to the vector of transitions of the current lts.
labels_size_type add_action(const ACTION_LABEL_T &label)
Adds an action with a label to this LTS.
void set_initial_probabilistic_state(const PROBABILISTIC_STATE_T &state)
Sets the probabilistic initial state number of this LTS.
const PROBABILISTIC_STATE_T & initial_probabilistic_state() const
Gets the initial state number of this LTS.
void swap(probabilistic_lts &other)
Swap this lts with the supplied supplied LTS.
labels_size_type num_probabilistic_states() const
Gets the number of probabilistic states of this LTS.
void clear()
Clear the transitions system.
states_size_type add_probabilistic_state(const PROBABILISTIC_STATE_T &s)
Adds a probabilistic state to this LTS.
const PROBABILISTIC_STATE_T & probabilistic_state(const states_size_type index) const
Gets the probabilistic label of an index.
Signature based reductions for labelled transition systems.
void run()
Perform the reduction, modulo the equivalence for which the signature has been passed in as template ...
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.
bool is_set_empty(ptrdiff_t set)
ptrdiff_t get_set_child_left(ptrdiff_t set)
ptrdiff_t create_set(std::vector< ptrdiff_t > &elems)
ptrdiff_t get_set(ptrdiff_t tag)
ptrdiff_t get_set_child_right(ptrdiff_t set)
ptrdiff_t set_set_tag(ptrdiff_t set)
Standard exception class for reporting runtime errors.
void bisimulation_reduce_gjkw(LTS_TYPE &l, bool branching=false, bool preserve_divergence=false)
Reduce transition system l with respect to strong or (divergence preserving) branching bisimulation.
bool destructive_bisimulation_compare_dnj(LTS_TYPE &l1, LTS_TYPE &l2, bool const branching=false, bool const preserve_divergence=false, bool const generate_counter_examples=false, const std::string &="", bool=false)
Checks whether the two initial states of two LTSs are strong or (divergence-preserving) branching bis...
bool destructive_bisimulation_compare_gjkw(LTS_TYPE &l1, LTS_TYPE &l2, bool branching=false, bool preserve_divergence=false, bool generate_counter_examples=false)
Checks whether the two initial states of two LTSs are strong or branching bisimilar.
void bisimulation_reduce_dnj(LTS_TYPE &l, bool const branching=false, bool const preserve_divergence=false)
Reduce transition system l with respect to strong or (divergence-preserving) branching bisimulation.
O(m log n)-time branching bisimulation algorithm similar to liblts_bisim_dnj.h which does not use bun...
O(m log n)-time stuttering equivalence algorithm.
Author(s): # Carlos Gregorio-Rodriguez, Luis LLana, Rafael Martinez-Torres.
This file defines an algorithm for weak bisimulation, by calculating the transitive tau closure and a...
#define mCRL2log(LEVEL)
mCRL2log(LEVEL) provides the stream used to log.
Type recording the equivalence reductions supported by the LTS library.
Supperted preorders for LTSes.
void merge(LTS_TYPE &l1, const LTS_TYPE &l2)
bool destructive_branching_bisimulation_compare_minimal_depth(LTS_TYPE &l1, LTS_TYPE &l2, const std::string &counter_example_file)
bool coupled_simulation_compare(LTS_TYPE &l1, LTS_TYPE &l2)
void weak_bisimulation_reduce(LTS_TYPE &l, const bool preserve_divergences=false)
Reduce LTS l with respect to (divergence-preserving) weak bisimulation.
bool destructive_bisimulation_compare_minimal_depth(LTS_TYPE &l1, LTS_TYPE &l2, const std::string &counter_example_file)
std::size_t state_type
type used to store state (numbers and) counts
void bisimulation_reduce(LTS_TYPE &l, const bool branching=false, const bool preserve_divergences=false)
Reduce transition system l with respect to strong or (divergence preserving) branching bisimulation.
bool destructive_bisimulation_compare(LTS_TYPE &l1, LTS_TYPE &l2, const bool branching=false, const bool preserve_divergences=false, const bool generate_counter_examples=false, const std::string &counter_example_file="", const bool structured_output=false)
Checks whether the two initial states of two lts's are strong or branching bisimilar.
bool destructive_bisimulation_compare_gj(LTS_TYPE &l1, LTS_TYPE &l2, const bool branching=false, const bool preserve_divergence=false, const bool generate_counter_examples=false, const std::string &="", bool=false)
Checks whether the two initial states of two LTSs are strong or (divergence-preserving) branching bis...
bool destructive_weak_bisimulation_compare(LTS_TYPE &l1, LTS_TYPE &l2, const bool preserve_divergences=false)
Checks whether the initial states of two LTSs are weakly bisimilar.
void bisimulation_reduce_gj(LTS_TYPE &l, const bool branching=false, const bool preserve_divergence=false)
nonmember functions serving as interface with the rest of mCRL2
void get_trans(const outgoing_transitions_per_state_t &begin, tree_set_store &tss, std::size_t d, std::vector< transition > &d_trans, LTS_TYPE &aut)
void tau_star_reduce(lts< STATE_LABEL_T, ACTION_LABEL_T, LTS_BASE_CLASS > &l)
lts_equivalence
LTS equivalence relations.
@ lts_eq_branching_bisim_sigref
@ lts_eq_divergence_preserving_weak_bisim
@ lts_eq_branching_bisim_gjkw
@ lts_red_determinisation
@ lts_eq_branching_bisim_gv
@ lts_eq_divergence_preserving_branching_bisim_sigref
@ lts_eq_divergence_preserving_branching_bisim
@ lts_eq_branching_bisim_gj
@ lts_eq_divergence_preserving_branching_bisim_gjkw
@ lts_eq_divergence_preserving_branching_bisim_gv
@ lts_eq_divergence_preserving_branching_bisim_gj
bool is_deterministic(const LTS_TYPE &l)
Checks whether this LTS is deterministic.
lts_preorder
LTS preorder relations.
@ lts_pre_failures_refinement
@ lts_pre_failures_divergence_refinement
@ lts_pre_weak_trace_anti_chain
@ lts_pre_weak_failures_refinement
@ lts_pre_trace_anti_chain
std::size_t to(const outgoing_pair_t &p)
Target state of a label state pair.
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 determinise(LTS_TYPE &l)
Determinises this LTS.
bool destructive_compare(LTS_TYPE &l1, LTS_TYPE &l2, const lts_equivalence eq, const bool generate_counter_examples=false, const std::string &counter_example_file=std::string(), const bool structured_output=false)
Checks whether this LTS is equivalent to another LTS.
std::pair< std::size_t, bool > reduce(LTS_TYPE <s, const bool weak_reduction, const bool preserve_divergence, std::size_t l2_init)
Preprocess the LTS for destructive refinement checking.
void merge(LTS_TYPE &l1, const LTS_TYPE &l2)
Merge the second lts into the first lts.
bool reachability_check(lts< SL, AL, BASE > &l, bool remove_unreachable=false)
Checks whether all states in this LTS are reachable from the initial state and remove unreachable sta...
bool destructive_refinement_checker(LTS_TYPE &l1, LTS_TYPE &l2, const refinement_type refinement, const bool weak_reduction, const lps::exploration_strategy strategy, const bool preprocess=true, COUNTER_EXAMPLE_CONSTRUCTOR generate_counter_example=detail::dummy_counter_example_constructor())
This function checks using algorithms in the paper mentioned above whether transition system l1 is in...
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.
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...
Implementation of LTS reductions using the signature refinement approach of S. Blom and S....