12#ifndef MCRL2_LPS_EXPLORER_H
13#define MCRL2_LPS_EXPLORER_H
19#include <condition_variable>
20#include "mcrl2/utilities/detail/io.h"
21#include "mcrl2/utilities/skip.h"
22#include "mcrl2/atermpp/standard_containers/vector.h"
23#include "mcrl2/atermpp/standard_containers/indexed_set.h"
24#include "mcrl2/atermpp/standard_containers/detail/unordered_map_implementation.h"
25#include "mcrl2/data/consistency.h"
26#include "mcrl2/data/enumerator.h"
27#include "mcrl2/data/find_quantifier_variables.h"
28#include "mcrl2/data/detail/enumerator_iteration_limit.h"
29#include "mcrl2/data/substitution_utility.h"
30#include "mcrl2/lps/detail/instantiate_global_variables.h"
31#include "mcrl2/lps/explorer_options.h"
32#include "mcrl2/lps/explorer_todo_set.h"
33#include "mcrl2/lps/explorer_utilities.h"
34#include "mcrl2/lps/find_representative.h"
35#include "mcrl2/lps/one_point_rule_rewrite.h"
36#include "mcrl2/lps/order_summand_variables.h"
37#include "mcrl2/lps/replace_constants_by_variables.h"
38#include "mcrl2/lps/resolve_name_clashes.h"
39#include "mcrl2/lps/stochastic_state.h"
40#include "mcrl2/lps/explorer_projections.h"
42#ifdef MCRL2_USE_CONTROL_FLOW
43#include <boost/container/small_vector.hpp>
44#include "mcrl2/lps/explorer_control_flow.h"
49template <
bool Stochastic,
bool Timed,
typename Specification>
105#ifdef MCRL2_USE_CONTROL_FLOW
128 Specification result = lpsspec;
129 detail::instantiate_global_variables(result);
130 lps::order_summand_variables(result);
131 resolve_summand_variable_name_clashes(result);
132 if (m_options.one_point_rule_rewrite)
134 one_point_rule_rewrite(result);
136 if (m_options.replace_constants_by_variables)
138 replace_constants_by_variables(result, m_global_rewr, m_global_sigma);
146 data::mutable_indexed_substitution<>& sigma,
149 return rewr(data::less_equal(t0, t1),sigma) == data::sort_bool::true_();
153 template <
typename SummandSequence>
155 const SummandSequence& summands,
156 data::mutable_indexed_substitution<>& sigma,
158 data::enumerator_algorithm<>& enumerator,
163 data::data_expression_list process_parameter_undo = process_parameter_values(sigma);
164 state result = lps::find_representative(u0,
166 {
return generate_successors(u, summands, sigma, rewr, enumerator, id_generator); });
167 set_process_parameter_values(process_parameter_undo, sigma);
172 template <
typename DataExpressionSequence>
174 const DataExpressionSequence& v,
175 data::mutable_indexed_substitution<>& sigma,
178 lps::make_state(result,
181 [&](data::data_expression& result,
const data::data_expression& x) { rewr(result, x, sigma);
return; });
184 template <
typename DataExpressionSequence>
187 const DataExpressionSequence& next_state,
188 data::mutable_indexed_substitution<>& sigma,
190 const data::enumerator_algorithm<>& enumerator)
const
195 enumerator.enumerate<enumerator_element>(
196 distribution.variables(),
197 distribution.distribution(),
199 [&](
const enumerator_element& p)
201 p.add_assignments(distribution.variables(), sigma, rewr);
202 result.probabilities.push_back(p.expression());
203 result.states.emplace_back();
204 compute_state(result.states.back(), next_state, sigma, rewr);
207 [](
const data::data_expression& x) {
return x == data::sort_real::real_zero(); }
209 data::remove_assignments(sigma, distribution.variables());
210 if (m_options.check_probabilities)
218 result.states.emplace_back();
219 compute_state(result.states.back(),next_state,sigma,rewr);
223 template <
typename DataExpressionSequence,
typename IndexSequence>
226 const DataExpressionSequence& next_state,
227 const IndexSequence& I_w,
228 data::mutable_indexed_substitution<>& sigma,
237 rewr(target, next_state[i], sigma);
242 template <
typename DataExpressionSequence,
typename IndexSequence>
246 const DataExpressionSequence& next_state,
247 const IndexSequence& I_w,
248 data::mutable_indexed_substitution<>& sigma,
250 data::enumerator_algorithm<>& enumerator)
const
255 enumerator.enumerate<enumerator_element>(
256 distribution.variables(),
257 distribution.distribution(),
259 [&](
const enumerator_element& p)
261 p.add_assignments(distribution.variables(), sigma, rewr);
262 result.probabilities.push_back(p.expression());
263 result.states.emplace_back();
264 compute_projected_state(result.states.back(), next_state, I_w, sigma, rewr);
267 [](
const data::data_expression& x) {
return x == data::sort_real::real_zero(); }
269 data::remove_assignments(sigma, distribution.variables());
271 if (m_options.check_probabilities)
279 result.states.emplace_back();
280 compute_projected_state(result.states.back(), next_state, I_w, sigma, rewr);
287 data::mutable_indexed_substitution<>& sigma,
292 return lps::multi_action(
293 process::action_list(
296 [&](process::action& result,
const process::action& a)
298 const data::data_expression_list& args = a.arguments();
299 process::make_action(result,
301 data::data_expression_list(args.begin(),
303 [&](data::data_expression& result,
304 const data::data_expression& x) ->
void
305 { rewr(result, x, sigma); }));
308 a.has_time() ? rewr(time, sigma) : time
314 data::mutable_indexed_substitution<>& sigma,
319 std::string printed_condition = data::pp(p_expression);
320 data::remove_assignments(sigma, m_process_parameters);
321 data::remove_assignments(sigma, summand.variables);
324 if (!data::find_quantifier_variables(p_expression).empty())
326 mCRL2log(log::log_level_t::info) <<
"The condition contains quantifiers, which means that rewriting to normal form could fail when the quantifier enumeration limit is too low. Use ---qlimit/-Q to increase the limit." << std::endl;
329 throw data::enumerator_error(
"Condition " + data::pp(reduced_condition) +
330 " does not rewrite to true or false. \nCulprit: "
331 + printed_condition.substr(0,2000)
332 + (printed_condition.size() > 2000 ?
"..." :
""));
341 template <
typename EmitSolution>
344 data::mutable_indexed_substitution<>& sigma,
347 data::enumerator_algorithm<>& enumerator,
348 EmitSolution emit_solution
351 rewr(condition, summand.condition, sigma);
357 if (summand.variables.empty())
360 check_enumerator_solution(condition, summand, sigma, rewr);
361 emit_solution(data::data_expression_list{});
365 enumerator.enumerate<enumerator_element>(
369 [&](
const enumerator_element& p)
371 check_enumerator_solution(p.expression(), summand, sigma, rewr);
372 emit_solution(p.assign_expressions(summand.variables, rewr));
383 void project(
lps::state& result,
const std::vector<std::size_t>& I_r,
const data::mutable_indexed_substitution<>& sigma)
389 [&](data::data_expression& target, std::size_t j)
391 sigma.apply(m_process_parameters[j], target);
398 template <
bool ReportActions =
true,
typename SummandSequence,
typename ReportTransition =
utilities::skip>
401 const SummandSequence& confluent_summands,
402 data::mutable_indexed_substitution<>& sigma,
407 data::enumerator_algorithm<>& enumerator,
409#ifdef MCRL2_USE_CONTROL_FLOW
412 ReportTransition report_transition = ReportTransition()
415 bool variables_are_assigned_to_sigma=
false;
417#ifdef MCRL2_USE_CONTROL_FLOW
418 if (active_cfg_vertices && !cfg_allows_summand(summand.index, *m_control_flow_graphs, *active_cfg_vertices))
424 auto process_transition =
425 [&](
const data::data_expression_list* assignments)
429 data::add_assignments(sigma, summand.variables, *assignments);
430 variables_are_assigned_to_sigma =
true;
433 if constexpr (Stochastic)
435 compute_stochastic_state(s1, summand.distribution, summand.next_state, sigma, rewr, enumerator);
439 compute_state(s1, summand.next_state, sigma, rewr);
440 if (!confluent_summands.empty())
442 s1 = find_representative(s1, confluent_summands, sigma, rewr, enumerator, id_generator);
446 if constexpr (ReportActions)
448 if (m_options.rewrite_actions)
450 lps::
multi_action a = rewrite_action(summand.multi_action, sigma, rewr);
451 report_transition(a, s1);
455 report_transition(summand.multi_action, s1);
460 report_transition(s1);
463 if (
m_recursive && variables_are_assigned_to_sigma)
465 data::remove_assignments(sigma, summand.variables);
466 variables_are_assigned_to_sigma =
false;
470 auto enumerate_projected_transitions =
473 std::vector<projected_transition> result;
477 summand, sigma, rewr, condition, enumerator,
478 [&](
const data::data_expression_list& e)
480 data::add_assignments(sigma, summand.variables, e);
481 lps::multi_action a = m_options.rewrite_actions ? rewrite_action(summand.multi_action, sigma, rewr) : summand.multi_action;
483 if constexpr (Stochastic)
488 throw mcrl2::runtime_error(
"A stochastic projection cache has not been implemented yet");
493 compute_projected_state(q, summand.next_state, summand.I_w, sigma, rewr);
494 result.emplace_back(a, q);
497 data::remove_assignments(sigma, summand.variables);
503 auto consume_projected_transitions =
504 [&](
const projected_transition& t)
507 const lps::state& q = t.second;
514 counting_iterator(0),
516 [&](data::data_expression& r, std::size_t i)
518 if (j < summand.I_w.size() && summand.I_w[j] == i)
525 rewr(r, m_process_parameters[i], sigma);
530 if constexpr (!Stochastic)
533 if (!confluent_summands.empty())
535 y = find_representative(y, confluent_summands, sigma, rewr, enumerator, id_generator);
537 if constexpr (utilities::is_applicable<ReportTransition, state_type,
void>::value)
539 report_transition(y);
543 report_transition(a, y);
551 y.probabilities.push_back(data::sort_real::real_one());
552 y.states.push_back(s_y);
553 if constexpr (utilities::is_applicable<ReportTransition, state_type,
void>::value)
555 report_transition(y);
559 report_transition(a, y);
569 if (m_options.use_projections && !summand.I_r.empty())
572 project(key, summand.I_r, sigma);
573 utilities::shared_guard g = atermpp::detail::g_thread_term_pool().lock_shared();
575 auto it = summand.projection_cache.find(key);
576 if (it == summand.projection_cache.end())
580 std::vector<projected_transition> projected = enumerate_projected_transitions();
581 it = summand.projection_cache.emplace(key, std::move(projected)).first;
588 for (
const projected_transition& t : it->second)
590 consume_projected_transitions(t);
593 else if (summand.cache_strategy == caching::none)
597 summand, sigma, rewr, condition, enumerator,
598 [&](
const data::data_expression_list& e)
600 process_transition(&e);
606 summand_cache_map& cache = summand.cache_strategy == caching::global ? global_cache : summand.local_cache;
607 utilities::shared_guard g = atermpp::detail::g_thread_term_pool().lock_shared();
609 auto q = cache.find(detail::cheap_cache_key(sigma, summand.gamma));
610 if (q == cache.end())
617 summand, sigma, rewr, condition, enumerator,
618 [&](
const data::data_expression_list& e)
620 solutions.push_front(e);
623 summand.compute_key(key, sigma);
624 q = cache.insert({key, solutions}).first;
631 for (
const auto& e :
static_cast<atermpp::term_list<data::data_expression_list>&>(q->second))
633 process_transition(e.empty() ?
nullptr : &e);
637 if (!
m_recursive && variables_are_assigned_to_sigma)
639 data::remove_assignments(sigma, summand.variables);
643 template <
typename SummandSequence>
656 std::list<transition> transitions;
657 data::add_assignments(sigma, m_process_parameters, s);
658#ifdef MCRL2_USE_CONTROL_FLOW
659 auto active_cfg_vertices = compute_active_cfg_vertices_if_enabled(sigma);
663 generate_transitions(
673#ifdef MCRL2_USE_CONTROL_FLOW
676 [&](
const lps::multi_action& a,
const state_type& s1)
680 const data::data_expression& t = s[m_n];
681 if (a.has_time() && less_equal(a.time(), t, sigma, rewr))
685 const data::data_expression& t1 = a.has_time() ? a.time() : t;
686 make_timed_state(state_, s1, t1);
687 transitions.emplace_back(a, state_);
691 transitions.emplace_back(a, s1);
700 template <
typename SummandSequence>
714 std::vector<state> result;
715 data::add_assignments(sigma, m_process_parameters, s0);
716#ifdef MCRL2_USE_CONTROL_FLOW
717 auto active_cfg_vertices = compute_active_cfg_vertices_if_enabled(sigma);
721 generate_transitions<
false>(
731#ifdef MCRL2_USE_CONTROL_FLOW
737 result.push_back(s1);
740 data::remove_assignments(sigma, summand.variables);
748 std::set<data::function_symbol> result = std::move(s);
749 result.insert(data::less_equal(data::sort_real::real_()));
750 result.insert(data::greater_equal(data::sort_real::real_()));
751 result.insert(data::sort_real::plus(data::sort_real::real_(), data::sort_real::real_()));
757 switch (m_options.search_strategy)
759 case lps::exploration_strategy::es_breadth:
return std::make_unique<breadth_first_todo_set>(init);
760 case lps::exploration_strategy::es_depth:
return std::make_unique<depth_first_todo_set>(init);
761 case lps::exploration_strategy::es_highway:
return std::make_unique<highway_todo_set>(init, m_options.highway_todo_max);
762 default:
throw mcrl2::runtime_error(
"unsupported search strategy");
766 template <
typename ForwardIterator>
769 switch (m_options.search_strategy)
771 case lps::exploration_strategy::es_breadth:
return std::make_unique<breadth_first_todo_set>(first, last);
772 case lps::exploration_strategy::es_depth:
return std::make_unique<depth_first_todo_set>(first, last);
773 case lps::exploration_strategy::es_highway:
return std::make_unique<highway_todo_set>(first, last, m_options.highway_todo_max);
774 default:
throw mcrl2::runtime_error(
"unsupported search strategy");
781 if (a.actions().empty())
783 return m_options.confluence_action ==
"tau";
785 else if (a.actions().size() == 1)
787 return std::string(a.actions().front().label().name()) == m_options.confluence_action;
794#ifdef MCRL2_USE_CONTROL_FLOW
805#ifdef MCRL2_USE_CONTROL_FLOW
807 if constexpr (!Stochastic)
809 if (m_options.use_control_flow)
811 lps::specification control_flow_lpsspec = lpsspec;
812 std::vector<cf_graph> graphs = compute_control_flow_graphs(control_flow_lpsspec, stategraph_options, compute_marking);
813 if (mCRL2logEnabled(log::log_level_t::debug))
815 for (
const cf_graph& G: graphs)
823 m_control_flow_graphs = std::move(graphs);
830 m_process_parameters = std::vector<data::variable>(params.begin(), params.end());
831 m_n = m_process_parameters.size();
832 timed_state.resize(m_n + 1);
833 m_initial_state = m_global_lpsspec.initial_process().expressions();
837 const auto& lpsspec_summands =
m_global_lpsspec.process().action_summands();
838 for (std::size_t i = 0; i < lpsspec_summands.size(); i++)
840 const auto& summand = lpsspec_summands[i];
841 caching cache_strategy = m_options.cached ? (m_options.global_cache ? lps::caching::global : lps::caching::local) : lps::caching::none;
842 if (is_confluent_tau(summand.multi_action()))
844 m_confluent_summands.emplace_back(summand, i, m_global_lpsspec.process().process_parameters(), cache_strategy);
848 m_regular_summands.emplace_back(summand, i, m_global_lpsspec.process().process_parameters(), cache_strategy);
853 if (m_options.use_projections)
855 auto [R, W] = compute_read_write_patterns_separated(lpsspec);
856 for (std::size_t i = 0; i < m_regular_summands.size(); ++i)
858 m_regular_summands[i].set_projection_attributes(R[i], W[i]);
868 return m_initial_state;
874 return m_global_rewr;
880 compute_stochastic_state(result, m_initial_distribution, m_initial_state, m_global_sigma, m_global_rewr, m_global_enumerator);
884 template <
typename DataExpressionSequence>
887 const DataExpressionSequence& next_state)
const
889 compute_stochastic_state(result, distribution, next_state, m_global_sigma, m_global_rewr, m_global_enumerator);
896 return out_edges(s, m_regular_summands, m_confluent_summands, m_global_sigma, m_global_rewr, m_global_enumerator, m_global_id_generator);
904 assert(summand_index<m_regular_summands.size());
906 std::vector(1, m_regular_summands[summand_index]),
907 m_confluent_summands,
908 m_global_sigma, m_global_rewr, m_global_enumerator, m_global_id_generator);
914 std::copy(s.begin(), s.end(), timed_state.begin());
915 timed_state.back() = t;
916 lps::make_state(result, timed_state.begin(), m_n + 1);
921 if constexpr (Stochastic)
923 return stochastic_state(s);
936 template<
typename StateType,
937 typename SummandSequence,
938 typename DiscoverState =
utilities::skip,
939 typename ExamineTransition =
utilities::skip,
942 typename DiscoverInitialState =
utilities::skip>
944 std::size_t thread_index,
945 std::atomic<std::size_t>& number_of_active_processes,
946 const SummandSequence& regular_summands,
947 const SummandSequence& confluent_summands,
948 indexed_set_for_states_type& discovered,
949 DiscoverState discover_state,
950 ExamineTransition examine_transition,
951 StartState start_state,
952 FinishState finish_state,
954 data::mutable_indexed_substitution<> thread_sigma
960 typename SummandSequence,
961 typename DiscoverState =
utilities::skip,
962 typename ExamineTransition =
utilities::skip,
965 typename DiscoverInitialState =
utilities::skip
970 const SummandSequence& regular_summands,
971 const SummandSequence& confluent_summands,
972 indexed_set_for_states_type& discovered,
973 DiscoverState discover_state = DiscoverState(),
974 ExamineTransition examine_transition = ExamineTransition(),
975 StartState start_state = StartState(),
976 FinishState finish_state = FinishState(),
978 DiscoverInitialState discover_initial_state = DiscoverInitialState()
988 typename DiscoverState =
utilities::skip,
989 typename ExamineTransition =
utilities::skip,
992 typename DiscoverInitialState =
utilities::skip
996 DiscoverState discover_state = DiscoverState(),
997 ExamineTransition examine_transition = ExamineTransition(),
998 StartState start_state = StartState(),
999 FinishState finish_state = FinishState(),
1000 DiscoverInitialState discover_initial_state = DiscoverInitialState()
1017#ifdef MCRL2_USE_CONTROL_FLOW
1032#ifdef MCRL2_USE_CONTROL_FLOW
1080#ifdef MCRL2_USE_CONTROL_FLOW
1092#ifdef MCRL2_USE_CONTROL_FLOW
1133 typename DiscoverState =
utilities::skip,
1134 typename ExamineTransition =
utilities::skip,
1137 typename ForwardOrCrossEdge =
utilities::skip,
1142 DiscoverState discover_state = DiscoverState(),
1143 ExamineTransition examine_transition = ExamineTransition(),
1144 TreeEdge tree_edge = TreeEdge(),
1145 BackEdge back_edge = BackEdge(),
1146 ForwardOrCrossEdge forward_or_cross_edge = ForwardOrCrossEdge(),
1147 FinishState finish_state = FinishState()
1154 typename SummandSequence,
1155 typename DiscoverState =
utilities::skip,
1156 typename ExamineTransition =
utilities::skip,
1159 typename ForwardOrCrossEdge =
utilities::skip,
1164 std::unordered_set<state>& discovered,
1165 const SummandSequence& regular_summands,
1166 const SummandSequence& confluent_summands,
1167 DiscoverState discover_state = DiscoverState(),
1168 ExamineTransition examine_transition = ExamineTransition(),
1169 TreeEdge tree_edge = TreeEdge(),
1170 BackEdge back_edge = BackEdge(),
1171 ForwardOrCrossEdge forward_or_cross_edge = ForwardOrCrossEdge(),
1172 FinishState finish_state = FinishState()
1177 typename DiscoverState =
utilities::skip,
1178 typename ExamineTransition =
utilities::skip,
1181 typename ForwardOrCrossEdge =
utilities::skip,
1186 DiscoverState discover_state = DiscoverState(),
1187 ExamineTransition examine_transition = ExamineTransition(),
1188 TreeEdge tree_edge = TreeEdge(),
1189 BackEdge back_edge = BackEdge(),
1190 ForwardOrCrossEdge forward_or_cross_edge = ForwardOrCrossEdge(),
1191 FinishState finish_state = FinishState()
1198 m_must_abort =
true;
1204 return m_discovered;
1209 return m_regular_summands;
1214 return m_confluent_summands;
1219 return m_process_parameters;
1224 return data::data_expression_list{m_process_parameters.begin(), m_process_parameters.end(), [&](
const data::variable& x) {
return sigma(x); }};
1230 assert(m_options.number_of_threads==1);
1231 return process_parameter_values(m_global_sigma);
1235 data::add_assignments(sigma, m_process_parameters, values);
1240 assert(m_options.number_of_threads==1);
1241 set_process_parameter_values(values, m_global_sigma);
1250#include "mcrl2/lps/explorer_bfs.h"
1251#include "mcrl2/lps/explorer_dfs.h"
A unordered_map class in which aterms can be stored.
data_expression & operator=(data_expression &&) noexcept=default
Rewriter that operates on data expressions.
data_expression operator()(const data_expression &d) const
Rewrites a data expression.
std::vector< data::variable > m_process_parameters
void make_timed_state(state &result, const state &s, const data::data_expression &t) const
data::enumerator_algorithm m_global_enumerator
void abort() override
Abort the state space generation.
lps::multi_action rewrite_action(const lps::multi_action &a, data::mutable_indexed_substitution<> &sigma, data::rewriter &rewr) const
Rewrite action a, and put it back in place.
std::vector< state > generate_successors(const state &s0, const SummandSequence &summands, data::mutable_indexed_substitution<> &sigma, data::rewriter &rewr, data::enumerator_algorithm<> &enumerator, data::enumerator_identifier_generator &id_generator, const SummandSequence &confluent_summands=SummandSequence())
std::condition_variable m_signal_global_todo_buffer_filled
void compute_stochastic_state(stochastic_state &result, const stochastic_distribution &distribution, const DataExpressionSequence &next_state) const
const state_type & make_state(const stochastic_state &s) const
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.
bool less_equal(const data::data_expression &t0, const data::data_expression &t1, data::mutable_indexed_substitution<> &sigma, data::rewriter &rewr) const
const std::vector< data::variable > & process_parameters() const
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 set_process_parameter_values(const data::data_expression_list &values)
~explorer() override=default
std::set< data::function_symbol > add_real_operators(std::set< data::function_symbol > s) const
data::enumerator_identifier_generator m_global_id_generator
explorer(const Specification &lpsspec, const explorer_options &options_, const data::rewriter &rewr)
void enumerate_solutions(const explorer_summand &summand, data::mutable_indexed_substitution<> &sigma, data::rewriter &rewr, data::data_expression &condition, data::enumerator_algorithm<> &enumerator, EmitSolution emit_solution)
Specification m_global_lpsspec
data::data_expression_list process_parameter_values() const
Process parameter values for use in a single thread.
void generate_transitions(const explorer_summand &summand, const SummandSequence &confluent_summands, data::mutable_indexed_substitution<> &sigma, data::rewriter &rewr, data::data_expression &condition, state_type &s1, atermpp::aterm key, data::enumerator_algorithm<> &enumerator, data::enumerator_identifier_generator &id_generator, ReportTransition report_transition=ReportTransition())
void generate_state_space_dfs_recursive(bool recursive, 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())
static constexpr bool is_timed
const data::data_expression_list & initial_state() const
void generate_state_space_thread(std::unique_ptr< todo_set > &todo, std::size_t thread_index, std::atomic< std::size_t > &number_of_active_processes, const SummandSequence ®ular_summands, const SummandSequence &confluent_summands, indexed_set_for_states_type &discovered, DiscoverState discover_state, ExamineTransition examine_transition, StartState start_state, FinishState finish_state, data::rewriter thread_rewr, data::mutable_indexed_substitution<> thread_sigma)
void generate_state_space(bool recursive, DiscoverState discover_state=DiscoverState(), ExamineTransition examine_transition=ExamineTransition(), StartState start_state=StartState(), FinishState finish_state=FinishState(), DiscoverInitialState discover_initial_state=DiscoverInitialState())
Generates the state space, and reports all discovered states and transitions by means of callback fun...
indexed_set_for_states_type m_discovered
state find_representative(state &u0, const SummandSequence &summands, data::mutable_indexed_substitution<> &sigma, data::rewriter &rewr, data::enumerator_algorithm<> &enumerator, data::enumerator_identifier_generator &id_generator)
std::vector< explorer_summand > m_regular_summands
const explorer_options m_options
summand_cache_map global_cache
const data::rewriter & get_rewriter() const
data::data_expression_list m_initial_state
std::mutex m_exclusive_state_access
data::mutable_indexed_substitution m_global_sigma
data::data_expression_list process_parameter_values(data::mutable_indexed_substitution<> &sigma) const
state_type make_state(const state &s) const
lps::stochastic_distribution m_initial_distribution
void compute_projected_state(lps::state &result, const DataExpressionSequence &next_state, const IndexSequence &I_w, data::mutable_indexed_substitution<> &sigma, const data::rewriter &rewr) const
void compute_state(state &result, const DataExpressionSequence &v, data::mutable_indexed_substitution<> &sigma, const data::rewriter &rewr) const
std::vector< explorer_summand > m_confluent_summands
void compute_initial_stochastic_state(stochastic_state &result) const
volatile std::atomic< bool > m_must_abort
data::rewriter m_global_rewr
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())
void check_enumerator_solution(const data::data_expression &p_expression, const explorer_summand &summand, data::mutable_indexed_substitution<> &sigma, data::rewriter &rewr) const
void compute_stochastic_state(stochastic_state &result, const stochastic_distribution &distribution, const DataExpressionSequence &next_state, data::mutable_indexed_substitution<> &sigma, const data::rewriter &rewr, const data::enumerator_algorithm<> &enumerator) const
const std::vector< explorer_summand > & regular_summands() const
std::unique_ptr< todo_set > make_todo_set(const state &init)
std::mutex m_global_todo_buffer_mutex
std::unique_ptr< todo_set > make_todo_set(ForwardIterator first, ForwardIterator last)
std::list< transition > out_edges(const state &s)
std::vector< data::data_expression > timed_state
void project(lps::state &result, const std::vector< std::size_t > &I_r, const data::mutable_indexed_substitution<> &sigma)
std::list< transition > out_edges(const state &s, const SummandSequence ®ular_summands, const SummandSequence &confluent_summands, data::mutable_indexed_substitution<> &sigma, data::rewriter &rewr, data::enumerator_algorithm<> &enumerator, data::enumerator_identifier_generator &id_generator)
Specification preprocess(const Specification &lpsspec)
std::list< transition > out_edges(const state &s, const std::size_t summand_index)
bool is_confluent_tau(const multi_action &a)
static constexpr bool is_stochastic
void generate_state_space_dfs_iterative(bool recursive, 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())
void compute_stochastic_projected_state(stochastic_state &result, const stochastic_distribution &distribution, const DataExpressionSequence &next_state, const IndexSequence &I_w, data::mutable_indexed_substitution<> &sigma, const data::rewriter &rewr, data::enumerator_algorithm<> &enumerator) const
\brief A timed multi-action
const process::action_list & actions() const
const data::data_expression & time() const
void enable_auto_select_probability(bool enable)
If enabled, automatically a probabilistic state is chosen using its intrinsic probability.
void select_transition(std::size_t transition_number)
Choose outgoing transition indexed by transition_number and add its state to the state vector.
void add_new_state(const lps::stochastic_state &s)
std::uniform_int_distribution< std::size_t > m_distrib
std::deque< simulator_state_t > m_full_trace
void randomly_select_state()
Randomly choose one state among a sequence of probabilistic states.
bool m_auto_select_probabilistic_state
void select_state(std::size_t state_number)
Choose one state among a sequence of probabilistic states.
simulation(const stochastic_specification &specification, data::rewrite_strategy strategy=data::rewrite_strategy())
Constructor.
void randomly_select_transition()
Randomly choose an outgoing transition and add its state to the state vector.
std::vector< transition_type > transitions(const lps::state &source_state)
bool match_trace_transition(lts::trace &trace)
void environment(std::vector< std::string > values)
Goto the state indicated by the environment, which is given by a vector of strings.
virtual ~simulation()=default
bool match_trace_probabilistic_state(lts::trace &trace)
data::rewriter m_rewriter
void save(const std::string &filename) const
Save the trace to a file.
bool probabilistic_state_must_be_selected(const std::size_t state_index) const
Indicate whether a probabilistic state has been selected.
const std::deque< simulator_state_t > & trace() const
Returns the current annotated state vector.
stochastic_specification m_specification
void truncate(std::size_t state_number, bool probabilistic)
Remove states from the end of the simulation, making state_number the last state.
void load(const std::string &filename)
Load a trace from a file.
\brief A stochastic distribution
bool is_defined() const
Returns true if the distribution is defined, i.e. it contains a valid distribution....
Linear process specification.
This class contains a trace consisting of a sequence of (timed) actions possibly with intermediate st...
#define mCRL2log(LEVEL)
mCRL2log(LEVEL) provides the stream used to log.
Namespace for system defined sort bool_.
const function_symbol & true_()
Constructor for function symbol true.
Namespace for system defined sort real_.
data_expression & real_one()
data_expression & real_zero()
bool is_false(const data_expression &x)
Test if x is false.
application greater_equal(const data_expression &arg0, const data_expression &arg1)
Application of function symbol >=.
A class that takes a linear process specification and checks all tau-summands of that LPS for conflue...
The main namespace for the LPS library.
void check_stochastic_state(const stochastic_state &s, const data::rewriter &rewr)
void check_probability(const data::data_expression &x, const data::rewriter &rewr)
std::string print_probability(const data::data_expression &x)
The main namespace for the Process library.
transition(lps::multi_action action_, const state_type &state_)
std::vector< transition_type > transitions
std::size_t transition_number
lps::stochastic_state source_state
stochastic_state(const state &s)
stochastic_state()=default
void push_back(const data::data_expression &probability, const state &s)
std::vector< data::data_expression > probabilities
std::vector< state > states