12#ifndef MCRL2_LTS_STATE_SPACE_GENERATOR_H
13#define MCRL2_LTS_STATE_SPACE_GENERATOR_H
45 const std::string& filename
56 mCRL2log(
log::info) <<
", but its trace could not be saved to '" << filename <<
"'";
64 const std::string& filename1,
66 const std::string& filename2
73 mCRL2log(
log::info) <<
" and saved traces to '" << filename1 <<
"' and '" << filename2 <<
"'";
77 mCRL2log(
log::info) <<
", but its traces could not be saved to '" << filename1 <<
"' and '" << filename2 <<
"'";
82template <
typename Explorer>
93 if constexpr (Explorer::is_stochastic)
95 for (
const std::pair<lps::multi_action, lps::stochastic_state>& t:
m_explorer.generate_transitions(s0))
108 for (
const std::pair<lps::multi_action, lps::state>& t:
m_explorer.generate_transitions(s0))
127 std::deque<lps::state> states{ s };
128 std::deque<lps::multi_action> actions;
132 auto i = m_backpointers.find(s1);
133 if (i == m_backpointers.end())
138 states.push_front(s0);
139 actions.push_front(find_action(s0, s1));
143 for (std::size_t i = 0; i < actions.size(); i++)
170template <
typename Explorer>
212 filename +=
"_" +
core::pp(a_i.label().name());
215 filename = filename +
".trc";
220 template <
typename Specification>
222 const Specification& lpsspec,
224 const std::set<core::identifier_string>& trace_actions_,
225 const std::set<lps::multi_action>& trace_multiactions_,
226 const std::string& filename_prefix_,
227 std::size_t max_trace_count
236 const auto& summands = lpsspec.process().action_summands();
238 for (
const auto& summand: summands)
272template <
typename Explorer>
284 const std::string& filename_prefix_,
285 std::size_t max_trace_count
294 mCRL2log(
log::info) <<
"Deadlock found (state index: " + std::to_string(s_index) +
")";
309template <
typename Explorer>
322 const std::string& filename_prefix_,
323 const std::size_t number_of_threads,
324 std::size_t max_trace_count = 0
331 assert(number_of_threads>0);
349 else if (i->second != s1)
351 mCRL2log(
log::info) <<
"Nondeterministic state found (state index: " + std::to_string(s0_index) +
")";
371template <
typename Explorer>
395 const std::set<core::identifier_string>& actions,
396 const std::string& filename_prefix_,
397 std::size_t max_trace_count
410 if (!contains(actions, a.label().name()))
420 if (is_hidden(summand))
428 if (is_hidden(summand))
447 std::string message =
"Divergent state found (state index: " + std::to_string(s_index) +
448 "), reachable from divergent state with index " + std::to_string(q->second);
455 std::unordered_set<lps::state> discovered;
460 std::unordered_set<lps::state> gray;
473 mCRL2log(
log::info) <<
"Divergent state found (state index: " + std::to_string(s_index) +
")";
509 mCRL2log(
log::info) <<
"Divergent state found (state index: " + std::to_string(s_index) +
")";
566 void finish_state(std::size_t state_count, std::size_t todo_list_size, std::size_t number_of_threads)
568 time_t new_log_time = 0;
570 static std::mutex exclusive_print_mutex;
576 exclusive_print_mutex.lock();
582 exclusive_print_mutex.unlock();
585 if (time(&new_log_time) >
last_log_time.load(std::memory_order_relaxed))
587 exclusive_print_mutex.lock();
592 if (number_of_threads>1)
596 <<
", explored " << 100.0 * ((float)
count / state_count)
603 <<
", explored " << 100.0 * ((float)
count / state_count)
604 <<
"%. Last level: " <<
level <<
", " << lvl_states <<
"st, "
605 << lvl_transitions <<
"tr.\n";
607 exclusive_print_mutex.unlock();
613 if (time(&new_log_time) >
last_log_time.load(std::memory_order_relaxed))
615 exclusive_print_mutex.lock();
621 exclusive_print_mutex.unlock();
631 if (number_of_threads==1)
641 << state_count <<
" state" << ((state_count == 1)?
"":
"s")
649template <
bool Stochastic,
bool Timed,
typename Specification>
677 std::unique_ptr<detail::divergence_detector<explorer_type>>(
696 template <
typename LTSBuilder>
708 [&](
const std::size_t thread_index,
const lps::state& s, std::size_t s_index)
712 m_trace_constructor.add_edge(*source, s);
717 if constexpr (!Stochastic)
719 m_divergence_detector->detect_divergence(s, s_index, m_trace_constructor, options.dfs_recursive);
726 static bool not_reported_yet=
true;
727 if (not_reported_yet)
729 not_reported_yet=
false;
739 [&](
const std::size_t thread_index,
const std::size_t number_of_threads,
741 const auto& s1,
const auto& s1_index, std::size_t summand_index)
743 if constexpr (Stochastic)
745 builder.add_transition(s0_index, a, s1_index, s1.probabilities, number_of_threads);
749 builder.add_transition(s0_index, a, s1_index, number_of_threads);
751 assert(thread_index<has_outgoing_transitions.size());
752 has_outgoing_transitions[thread_index].m_bool =
true;
768 [&](
const std::size_t thread_index,
const lps::state& s, std::size_t )
774 assert(thread_index<has_outgoing_transitions.size());
775 has_outgoing_transitions[thread_index].m_bool =
false;
783 [&](
const std::size_t thread_index,
const std::size_t number_of_threads,
784 const lps::state& s, std::size_t s_index, std::size_t todo_list_size)
786 assert(thread_index<has_outgoing_transitions.size());
800 if constexpr (Stochastic)
802 builder.set_initial_state(s_index, s.probabilities);
Read-only balanced binary tree of terms.
A unordered_map class in which aterms can be stored.
LPS summand containing a multi-action.
const lps::multi_action & multi_action() const
Returns the multi-action of this summand.
void abort() override
Abort the state space generation.
void generate_state_space(bool recursive, const StateType &s0, const SummandSequence ®ular_summands, const SummandSequence &confluent_summands, indexed_set_for_states_type &discovered, DiscoverState discover_state=DiscoverState(), ExamineTransition examine_transition=ExamineTransition(), StartState start_state=StartState(), FinishState finish_state=FinishState(), DiscoverInitialState discover_initial_state=DiscoverInitialState())
const indexed_set_for_states_type & state_map() const
Returns a mapping containing all discovered states.
const std::vector< explorer_summand > & confluent_summands() const
void set_process_parameter_values(const data::data_expression_list &values, data::mutable_indexed_substitution<> &sigma)
void generate_state_space_dfs_recursive(const state &s0, std::unordered_set< state > gray, std::unordered_set< state > &discovered, const SummandSequence ®ular_summands, const SummandSequence &confluent_summands, DiscoverState discover_state=DiscoverState(), ExamineTransition examine_transition=ExamineTransition(), TreeEdge tree_edge=TreeEdge(), BackEdge back_edge=BackEdge(), ForwardOrCrossEdge forward_or_cross_edge=ForwardOrCrossEdge(), FinishState finish_state=FinishState())
data::data_expression_list process_parameter_values(data::mutable_indexed_substitution<> &sigma) const
void generate_state_space_dfs_iterative(const state &s0, std::unordered_set< state > &discovered, const SummandSequence ®ular_summands, const SummandSequence &confluent_summands, DiscoverState discover_state=DiscoverState(), ExamineTransition examine_transition=ExamineTransition(), TreeEdge tree_edge=TreeEdge(), BackEdge back_edge=BackEdge(), ForwardOrCrossEdge forward_or_cross_edge=ForwardOrCrossEdge(), FinishState finish_state=FinishState())
const std::vector< explorer_summand > & regular_summands() const
typename std::conditional< Stochastic, stochastic_state, state >::type state_type
\brief A timed multi-action
const process::action_list & actions() const
action_detector(const Specification &lpsspec, trace_constructor< Explorer > &trace_constructor_, const std::set< core::identifier_string > &trace_actions_, const std::set< lps::multi_action > &trace_multiactions_, const std::string &filename_prefix_, std::size_t max_trace_count)
trace_constructor< Explorer > & m_trace_constructor
bool detect_action(const lps::state &s0, std::size_t s0_index, const lps::multi_action &a, const lps::state &s1, std::size_t summand_index)
bool match_action(const lps::action_summand &summand) const
const std::string & filename_prefix
std::size_t m_trace_count
std::vector< bool > summand_matches
const std::set< core::identifier_string > & trace_actions
std::string create_filename(const lps::multi_action &a)
bool match_summand(std::size_t i) const
const std::set< lps::multi_action > & trace_multiactions
std::size_t m_max_trace_count
deadlock_detector(trace_constructor< Explorer > &trace_constructor_, const std::string &filename_prefix_, std::size_t max_trace_count)
std::size_t m_max_trace_count
void detect_deadlock(const lps::state &s, std::size_t s_index)
trace_constructor< Explorer > & m_trace_constructor
std::size_t m_trace_count
const std::string & filename_prefix
const std::string & filename_prefix
std::vector< lps::explorer_summand > m_confluent_summands
std::size_t m_max_trace_count
std::size_t m_trace_count
typename Explorer::state_index_type state_index_type
utilities::unordered_map< lps::state, std::size_t > m_divergent_states
bool detect_divergence(const lps::state &s, std::size_t s_index, trace_constructor< Explorer > &global_trace_constructor, bool dfs_recursive=false)
std::vector< lps::explorer_summand > m_regular_summands
std::mutex divergence_detector_mutex
typename Explorer::state_type state_type
trace_constructor< Explorer > m_local_trace_constructor
typename std::conditional< Explorer::is_stochastic, std::forward_list< lps::state >, lps::state >::type last_discovered_type
divergence_detector(Explorer &explorer_, const std::set< core::identifier_string > &actions, const std::string &filename_prefix_, std::size_t max_trace_count)
trace_constructor< Explorer > & m_trace_constructor
std::size_t m_max_trace_count
std::size_t m_trace_count
std::vector< std::map< lps::multi_action, lps::state > > m_transitions_vec
nondeterminism_detector(trace_constructor< Explorer > &trace_constructor_, const std::string &filename_prefix_, const std::size_t number_of_threads, std::size_t max_trace_count=0)
void start_state(std::size_t thread_index)
bool detect_nondeterminism(const lps::state &s0, std::size_t s0_index, const lps::multi_action &a, const lps::state &s1, std::size_t thread_index)
const std::string & filename_prefix
std::size_t last_state_count
progress_monitor(lps::exploration_strategy search_strategy_)
std::atomic< std::size_t > transition_count
std::size_t last_transition_count
lps::exploration_strategy search_strategy
void examine_transition()
void finish_exploration(std::size_t state_count, std::size_t number_of_threads)
void finish_state(std::size_t state_count, std::size_t todo_list_size, std::size_t number_of_threads)
std::atomic< time_t > last_log_time
std::atomic< std::size_t > count
lps::multi_action find_action(const lps::state &s0, const lps::state &s1)
trace_constructor(Explorer &explorer_)
class trace construct_trace(const lps::state &s)
std::map< lps::state, lps::state > m_backpointers
void add_edge(const lps::state &s0, const lps::state &s1)
This class contains a trace consisting of a sequence of (timed) actions possibly with intermediate st...
const std::vector< lps::state > & states() const
void set_state(const lps::state &s)
Set the state at the current position.
void save(const std::string &filename, trace_format tf=tfMcrl2) const
Output the trace into a file with the indicated name.
void add_action(const mcrl2::lps::multi_action &action)
Add an action to the current trace.
Standard exception class for reporting runtime errors.
size_type size(std::size_t thread_index=0) const
The number of elements in the indexed set.
add your file description here.
#define mCRL2log(LEVEL)
mCRL2log(LEVEL) provides the stream used to log.
std::string pp(const atermpp::aterm &t)
Transform an aterm to an ascii string.
std::string pp(const identifier_string &x)
std::ostream & operator<<(std::ostream &out, const abstraction &x)
std::string pp(const action_summand &x)
void save_traces(class trace &tr, const std::string &filename1, class trace &tr2, const std::string &filename2)
bool save_trace(class trace &tr, const std::string &filename)
const lps::state & first_state(const lps::state &s)
bool contains(const atermpp::indexed_set< Key, ThreadSafe, Hash, Equals, Allocator, KeyTable > &c, const typename atermpp::indexed_set< Key, ThreadSafe, Hash, Equals, Allocator, KeyTable >::key_type &v, const std::size_t thread_index=0)
bool detect_nondeterminism
std::set< core::identifier_string > actions_internal_for_divergencies
std::size_t number_of_threads
bool suppress_progress_messages
std::vector< state > states
state_space_generator(const Specification &lpsspec, const lps::explorer_options &options_)
std::unique_ptr< detail::divergence_detector< explorer_type > > m_divergence_detector
const lps::explorer_options & options
bool max_states_exceeded(const std::size_t thread_index)
detail::action_detector< explorer_type > m_action_detector
detail::progress_monitor m_progress_monitor
typename explorer_type::state_type state_type
detail::trace_constructor< explorer_type > m_trace_constructor
detail::nondeterminism_detector< explorer_type > m_nondeterminism_detector
lps::explorer< Stochastic, Timed, Specification > explorer
detail::deadlock_detector< explorer_type > m_deadlock_detector
bool explore(LTSBuilder &builder)
The skip operation with a variable number of arguments.
This class allows to flexibly manipulate traces.