20#ifndef LIBLTS_FAILURES_REFINEMENT_H
21#define LIBLTS_FAILURES_REFINEMENT_H
39 template <
class COUNTER_EXAMPLE_CONSTRUCTOR >
87 template <
class COUNTER_EXAMPLE_CONSTRUCTOR >
88 inline bool antichain_insert(
89 anti_chain_type& anti_chain,
90 const state_states_counter_example_index_triple<COUNTER_EXAMPLE_CONSTRUCTOR>& impl_spec);
94 template <
class LTS_TYPE >
110 assert(t.from()<
m_l.num_states());
111 if (
m_l.is_tau(
m_l.apply_hidden_label_map(t.label())) && weak_reduction)
117 if (weak_reduction &&
m_l.is_tau(
m_l.apply_hidden_label_map(t.label())) &&
118 strongly_connected_component_partitioner.
in_same_class(t.from(),t.to()))
165 template <
class LTS_TYPE >
166 set_of_states collect_reachable_states_via_taus(
168 const lts_cache<LTS_TYPE>& weak_property_cache,
169 const bool weak_reduction);
171 template <
class LTS_TYPE >
172 set_of_states collect_reachable_states_via_an_action(
175 const lts_cache<LTS_TYPE>& weak_property_cache,
176 const bool weak_reduction,
179 template <
class LTS_TYPE >
180 bool refusals_contained_in(
181 const state_type impl,
182 const set_of_states& spec,
183 const lts_cache<LTS_TYPE>& weak_property_cache,
186 const bool provide_a_counter_example,
187 const bool structured_output);
225template<
typename LTS_TYPE>
227 const bool weak_reduction,
228 const bool preserve_divergence,
241 preserve_divergence);
259template <
class LTS_TYPE,
class COUNTER_EXAMPLE_CONSTRUCTOR = detail::dummy_counter_example_constructor >
264 const bool weak_reduction,
266 const bool preprocess =
true,
277 if (!generate_counter_example.is_dummy() && preprocess)
280 reduce(l2, weak_reduction, preserve_divergence, l2.initial_state());
283 std::size_t init_l2 = l2.initial_state() + l1.num_states();
287 if (generate_counter_example.is_dummy() && preprocess)
290 bool initial_equal =
false;
291 std::tie(init_l2, initial_equal) =
reduce(l1, weak_reduction, preserve_divergence, init_l2);
293 if (initial_equal && weak_reduction)
296 if (preserve_divergence)
300 mCRL2log(
log::verbose) <<
" branching bisimilar, so there is no need to check the refinement relation.\n";
307 std::deque<detail::state_states_counter_example_index_triple<COUNTER_EXAMPLE_CONSTRUCTOR>>
312 generate_counter_example.root_index() ) });
321 while (!working.empty())
323 detail::state_states_counter_example_index_triple < COUNTER_EXAMPLE_CONSTRUCTOR > impl_spec;
324 impl_spec.
swap(working.front());
330 bool spec_diverges =
false;
336 if (weak_property_cache.
diverges(s))
338 spec_diverges =
true;
363 !generate_counter_example.is_dummy(),
364 generate_counter_example.is_structured()))
374 const typename COUNTER_EXAMPLE_CONSTRUCTOR::index_type new_counterexample_index=
377 if (l1.is_tau(l1.apply_hidden_label_map(t.label())) && weak_reduction)
379 spec_prime=impl_spec.
states();
387 spec_prime.insert(reachable_states_from_s_via_e.begin(),reachable_states_from_s_via_e.end());
390 if (spec_prime.empty())
392 generate_counter_example.save_counter_example(new_counterexample_index,l1);
398 const detail::state_states_counter_example_index_triple < COUNTER_EXAMPLE_CONSTRUCTOR >
399 impl_spec_counterex(t.to(),spec_prime,new_counterexample_index);
405 working.push_back(impl_spec_counterex);
409 working.push_front(impl_spec_counterex);
427 template <
class LTS_TYPE >
431 const bool weak_reduction)
439 std::deque<state_type> todo_stack(s.begin(),s.end());
440 while (todo_stack.size()>0)
443 todo_stack.pop_front();
446 if (visited.insert(s).second)
448 todo_stack.push_back(s);
457 template <
class LTS_TYPE >
461 const bool weak_reduction)
467 template <
class LTS_TYPE >
472 const bool weak_reduction,
482 if (l.apply_hidden_label_map(t.label())==e)
484 assert(set_before_action_e.count(t.from())>0);
485 states_reachable_via_e.insert(t.to());
503 template <
class COUNTER_EXAMPLE_CONSTRUCTOR >
510 for(anti_chain_type::const_iterator i=anti_chain.lower_bound(impl_spec.
state()); i!=anti_chain.upper_bound(impl_spec.
state()); ++i)
514 if (std::includes(impl_spec.
states().begin(), impl_spec.
states().end(), s.begin(),s.end()))
522 for(anti_chain_type::iterator i=anti_chain.lower_bound(impl_spec.
state()); i!=anti_chain.upper_bound(impl_spec.
state()); )
527 if (std::includes(s.begin(), s.end(), impl_spec.
states().begin(),impl_spec.
states().end()))
530 i=anti_chain.erase(i);
537 anti_chain.insert(std::pair<detail::state_type,detail::set_of_states>(impl_spec.
state(),impl_spec.
states()));
542 template <
class LTS_TYPE >
547 static std::map<set_of_states, set_of_states> cache;
548 const std::map<set_of_states, set_of_states>::const_iterator i=cache.find(states);
555 assert(visited.empty());
556 static std::stack < state_type > todo_stack;
557 assert(todo_stack.empty());
562 if (weak_property_cache.
stable(s))
574 while (todo_stack.size()>0)
576 const state_type current_state=todo_stack.top();
581 if (weak_property_cache.
stable(s))
588 if (visited.insert(s).second)
595 cache[states]=result;
597 return cache[states];
606 template <
class LTS_TYPE >
613 const bool provide_a_counter_example,
614 const bool structured_output)
616 if (!weak_property_cache.
stable(impl))
return true;
619 bool success =
false;
625 if (!weak_property_cache.
stable(s)) {
continue; }
632 bool inclusion_success = std::includes(impl_action_labels.begin(), impl_action_labels.end(),
633 spec_action_labels.begin(), spec_action_labels.end());
634 if (inclusion_success)
644 if (impl_action_labels.count(a) == 0)
653 if (!success && provide_a_counter_example)
656 if (impl_action_labels.empty())
658 if (structured_output)
660 std::cout <<
"left-acceptance:\n";
669 if (structured_output)
671 std::cout <<
"left-acceptance: ";
677 std::string sep =
"";
680 if (structured_output)
682 std::cout << sep << l.action_label(a);
690 if (structured_output)
699 if (structured_output)
701 std::cout <<
"right-acceptance-sets: 0\n";
712 std::copy_if(spec.begin(), spec.end(), std::inserter(stable,stable.end()), [=](
const state_type s){return weak_property_cache.stable(s);});
714 if (structured_output)
716 std::cout <<
"right-acceptance-sets: " << stable.size () <<
"\n";
720 mCRL2log(
log::verbose) <<
"Below all corresponding stable acceptance sets of the right process are provided:\n";
725 if (structured_output)
727 std::cout <<
"right-acceptance: ";
733 std::string sep =
"";
736 if (structured_output)
738 std::cout << sep << l.action_label(a);
746 if (structured_output)
752 if (!structured_output)
Read-only balanced binary tree of terms.
implements the main algorithm for the branching bisimulation quotient
state_type get_eq_class(state_type const s) const
Get the equivalence class of a state.
void finalize_minimized_LTS()
Adapt the LTS after minimisation.
A class that can be used to construct counter examples if no.
bool stable(const state_type s) const
std::vector< bool > m_divergent
std::vector< std::vector< state_type > > m_tau_reachable_states
std::vector< action_label_set > m_enabled_actions
const std::vector< state_type > & tau_reachable_states(const state_type s) const
const action_label_set & action_labels(const state_type s) const
const std::vector< transition > & transitions(const state_type s) const
std::vector< std::vector< transition > > m_sorted_transitions
void calculate_weak_property_cache(const bool weak_reduction)
bool diverges(const state_type s) const
lts_cache(LTS_TYPE &l, const bool weak_reduction)
This class contains an scc partitioner removing inert tau loops.
std::size_t get_eq_class(const std::size_t s) const
Gives the equivalence class number of a state. The equivalence class numbers range from 0 upto (and e...
void replace_transition_system(const bool preserve_divergence_loops)
The lts for which this partioner is created is replaced by the lts modulo the calculated partition.
bool in_same_class(const std::size_t s, const std::size_t t) const
Returns whether two states are in the same bisimulation equivalence class.
state_states_counter_example_index_triple()
detail::state_type m_state
const set_of_states & states() const
Get the set of states.
state_type state() const
Get the state.
detail::set_of_states m_states
state_states_counter_example_index_triple(const state_type state, const set_of_states &states, const typename COUNTER_EXAMPLE_CONSTRUCTOR::index_type &counter_example_index)
Constructor.
void swap(state_states_counter_example_index_triple &other)
COUNTER_EXAMPLE_CONSTRUCTOR::index_type m_counter_example_index
const COUNTER_EXAMPLE_CONSTRUCTOR::index_type & counter_example_index() const
Get the counter example index.
A class that contains a labelled transition system.
states_size_type initial_state() const
Gets the initial state number of this LTS.
void clear_state_labels()
Clear the labels of an lts.
This class contains a trace consisting of a sequence of (timed) actions possibly with intermediate st...
A class containing triples, source label and target representing transitions.
O(m log n)-time branching bisimulation algorithm.
#define mCRL2log(LEVEL)
mCRL2log(LEVEL) provides the stream used to log.
void merge(LTS_TYPE &l1, const LTS_TYPE &l2)
std::multimap< detail::state_type, detail::set_of_states > anti_chain_type
std::size_t state_type
type used to store state (numbers and) counts
bool antichain_insert(anti_chain_type &anti_chain, const state_states_counter_example_index_triple< COUNTER_EXAMPLE_CONSTRUCTOR > &impl_spec)
std::size_t label_type
type used to store label numbers and counts
set_of_states collect_reachable_states_via_taus(const state_type s, const lts_cache< LTS_TYPE > &weak_property_cache, const bool weak_reduction)
const set_of_states & calculate_tau_reachable_states(const set_of_states &states, const lts_cache< LTS_TYPE > &weak_property_cache)
set_of_states collect_reachable_states_via_an_action(const state_type s, const label_type e, const lts_cache< LTS_TYPE > &weak_property_cache, const bool weak_reduction, const LTS_TYPE &l)
std::set< state_type > set_of_states
bool refusals_contained_in(const state_type impl, const set_of_states &spec, const lts_cache< LTS_TYPE > &weak_property_cache, label_type &culprit, const LTS_TYPE &l, const bool provide_a_counter_example, const bool structured_output)
This function checks that the refusals(impl) are contained in the refusals of spec,...
std::set< label_type > action_label_set
void report_statistics(refinement_statistics< T > &stats)
Print a message to debugging containing information about the given statistics.
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.
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...
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.
detail::anti_chain_type & antichain
std::size_t antichain_misses
std::size_t max_antichain
refinement_statistics(detail::anti_chain_type &antichain, std::deque< T > &working)
std::deque< T > & working
std::size_t antichain_inserts