22#include <spot/twa/twagraph.hh>
23#include <spot/twaalgos/emptiness.hh>
24#include <spot/misc/bitvect.hh>
66 template <
typename Iterator>
67 bool operator()(Iterator, Iterator)
const noexcept
78 const std::vector<unsigned>& sccof_;
79 unsigned desired_scc_;
81 keep_inner_scc(
const std::vector<unsigned>& sccof,
unsigned desired_scc)
82 : sccof_(sccof), desired_scc_(desired_scc)
86 template <
typename Iterator>
87 bool operator()(Iterator begin, Iterator end)
const noexcept
91 if (sccof_[*begin++] == desired_scc_)
100 template <
typename Graph,
typename Filter>
104 typedef typename std::conditional<std::is_const<Graph>::value,
105 const typename Graph::edge_storage_t,
106 typename Graph::edge_storage_t>::type
108 typedef value_type& reference;
109 typedef value_type* pointer;
110 typedef std::ptrdiff_t difference_type;
111 typedef std::forward_iterator_tag iterator_category;
113 typedef std::vector<unsigned>::const_iterator state_iterator;
115 typedef typename std::conditional<std::is_const<Graph>::value,
116 const typename Graph::edge_vector_t,
117 typename Graph::edge_vector_t>::type
120 typedef typename std::conditional<std::is_const<Graph>::value,
121 const typename Graph::state_vector,
122 typename Graph::state_vector>::type
124 typedef const typename Graph::dests_vector_t dv_t;
139 void inc_state_maybe_()
141 while (!t_ && (++pos_ != end_))
142 t_ = (*sv_)[*pos_].succ;
147 t_ = (*tv_)[t_].next_succ;
152 bool ignore_current()
154 unsigned dst = (*this)->dst;
158 if (!filt_(&(*this)->dst, 1 + &(*this)->dst))
161 return efilter_((*tv_)[t_], dst, efilter_data_)
162 != edge_filter_choice::keep;
168 const unsigned* d = dv_->data() + ~dst;
169 if (!filt_(d + 1, d + *d + 1))
175 const unsigned* end = d + *d + 1;
176 for (
const unsigned* i = d + 1; i != end; ++i)
178 if (efilter_((*tv_)[t_], *i, efilter_data_)
179 == edge_filter_choice::keep)
190 tv_t* tv, sv_t* sv, dv_t* dv, Filter filt,
192 : pos_(begin), end_(end), t_(0), tv_(tv), sv_(sv), dv_(dv), filt_(filt),
193 efilter_(efilter), efilter_data_(efilter_data)
198 t_ = (*sv_)[*pos_].succ;
200 while (pos_ != end_ && ignore_current())
208 while (pos_ != end_ && ignore_current());
221 return pos_ == o.pos_ && t_ == o.t_;
226 return pos_ != o.pos_ || t_ != o.t_;
229 reference operator*()
const
234 pointer operator->()
const
241 template <
typename Graph,
typename Filter>
246 typedef typename iter_t::tv_t tv_t;
247 typedef typename iter_t::sv_t sv_t;
248 typedef typename iter_t::dv_t dv_t;
249 typedef typename iter_t::state_iterator state_iterator;
251 state_iterator begin_;
261 scc_edges(state_iterator begin, state_iterator end,
262 tv_t* tv, sv_t* sv, dv_t* dv, Filter filt,
264 : begin_(begin), end_(end), tv_(tv), sv_(sv), dv_(dv), filt_(filt),
265 efilter_(efilter), efilter_data_(efilter_data)
271 return {begin_, end_, tv_, sv_, dv_, filt_, efilter_, efilter_data_};
276 return {end_, end_,
nullptr,
nullptr,
nullptr, filt_,
nullptr,
nullptr};
287 typedef std::vector<unsigned> scc_succs;
291 std::vector<unsigned> states_;
301 acc_({}), trivial_(
true), accepting_(
false),
302 rejecting_(
false), useful_(
false)
308 : acc_(acc), common_(common),
309 trivial_(trivial), accepting_(
false),
310 rejecting_(
false), useful_(
false)
314 bool is_trivial()
const
339 bool is_useful()
const
344 acc_cond::mark_t acc_marks()
const
349 acc_cond::mark_t common_marks()
const
354 const std::vector<unsigned>& states()
const
359 unsigned one_state()
const
364 const scc_succs& succ()
const
415 typedef std::underlying_type_t<scc_info_options> ut;
417 &
static_cast<ut
>(right));
423 typedef std::underlying_type_t<scc_info_options> ut;
425 |
static_cast<ut
>(right));
428 class SPOT_API scc_and_mark_filter;
454 typedef scc_info_node::scc_succs scc_succs;
462 std::vector<unsigned> sccof_;
463 std::vector<scc_node> node_;
464 const_twa_graph_ptr aut_;
465 unsigned initial_state_;
468 int one_acc_scc_ = -1;
472 void determine_usefulness();
474 const scc_node& node(
unsigned scc)
const
481 [[noreturn]]
static void report_need_track_states();
482 [[noreturn]]
static void report_need_track_succs();
483 [[noreturn]]
static void report_incompatible_stop_on_acc();
492 unsigned initial_state = ~0U,
493 edge_filter filter =
nullptr,
494 void* filter_data =
nullptr,
498 :
scc_info(aut, ~0
U, nullptr, nullptr, options)
520 const_twa_graph_ptr get_aut()
const
535 void* get_filter_data()
const
540 unsigned scc_count()
const
558 bool reachable_state(
unsigned st)
const
560 return scc_of(st) != -1U;
563 unsigned scc_of(
unsigned st)
const
568 std::vector<scc_node>::const_iterator begin()
const
570 return node_.begin();
573 std::vector<scc_node>::const_iterator end()
const
578 std::vector<scc_node>::const_iterator cbegin()
const
580 return node_.cbegin();
583 std::vector<scc_node>::const_iterator cend()
const
588 std::vector<scc_node>::const_reverse_iterator rbegin()
const
590 return node_.rbegin();
593 std::vector<scc_node>::const_reverse_iterator rend()
const
598 const std::vector<unsigned>& states_of(
unsigned scc)
const
601 report_need_track_states();
602 return node(scc).states();
610 internal::scc_edges<const twa_graph::graph_t, internal::keep_all>
613 auto& states = states_of(scc);
614 return {states.begin(), states.end(),
615 &aut_->edge_vector(), &aut_->states(),
616 &aut_->get_graph().dests_vector(),
630 auto& states = states_of(scc);
631 return {states.begin(), states.end(),
632 &aut_->edge_vector(), &aut_->states(),
633 &aut_->get_graph().dests_vector(),
635 const_cast<void*
>(filter_data_)};
638 unsigned one_state_of(
unsigned scc)
const
640 return node(scc).one_state();
646 SPOT_ASSERT(filter_ || scc_count() - 1 == scc_of(initial_state_));
647 return scc_of(initial_state_);
650 const scc_succs& succ(
unsigned scc)
const
653 report_need_track_succs();
654 return node(scc).succ();
657 bool is_trivial(
unsigned scc)
const
659 return node(scc).is_trivial();
662 SPOT_DEPRECATED(
"use acc_sets_of() instead")
663 acc_cond::mark_t acc(
unsigned scc)
const
665 return acc_sets_of(scc);
668 bool is_accepting_scc(
unsigned scc)
const
670 return node(scc).is_accepting();
673 bool is_rejecting_scc(
unsigned scc)
const
675 return node(scc).is_rejecting();
682 return aut_->acc().accepting(acc_sets_of(scc));
706 bool is_useful_scc(
unsigned scc)
const
709 report_incompatible_stop_on_acc();
711 report_need_track_succs();
712 return node(scc).is_useful();
715 bool is_useful_state(
unsigned st)
const
717 return reachable_state(st) && is_useful_scc(scc_of(st));
722 std::vector<std::set<acc_cond::mark_t>>
marks()
const;
723 std::set<acc_cond::mark_t> marks_of(
unsigned scc)
const;
726 SPOT_DEPRECATED(
"use marks() instead")
727 std::vector<std::set<
acc_cond::mark_t>> used_acc()
const
731 SPOT_DEPRECATED(
"use marks_of() instead")
732 std::set<
acc_cond::mark_t> used_acc_of(
unsigned scc)
const
734 return marks_of(scc);
742 return node(scc).acc_marks();
749 return node(scc).common_marks();
752 std::vector<bool> weak_sccs()
const;
754 bdd scc_ap_support(
unsigned scc)
const;
783 bool preserve_names =
false)
const;
791 std::vector<acc_cond::rs_pair>& pairs,
792 std::vector<unsigned>& res,
793 std::vector<unsigned>& old)
const;
799 std::vector<unsigned>
815 const_twa_graph_ptr aut_;
817 bool restore_old_acc_ =
false;
818 const bitvect* keep_ =
nullptr;
822 unsigned dst,
void* data);
829 unsigned dst,
void* data);
840 : lower_si_(&lower_si), lower_scc_(lower_scc), cut_sets_(cut_sets),
841 aut_(lower_si_->get_aut()), old_acc_(aut_->get_acceptance())
843 auto f = lower_si.get_filter();
844 if (f == &filter_mark_
845 || f == &filter_scc_and_mark_
846 || f == &filter_scc_and_mark_and_edges_)
848 const void* data = lower_si.get_filter_data();
850 cut_sets_ |= d.cut_sets_;
851 if (f == &filter_scc_and_mark_and_edges_)
871 : lower_si_(nullptr), cut_sets_(cut_sets), aut_(aut),
872 old_acc_(aut_->get_acceptance())
878 restore_acceptance();
881 void override_acceptance(
const acc_cond& new_acc)
883 std::const_pointer_cast<twa_graph>(aut_)->set_acceptance(new_acc);
884 restore_old_acc_ =
true;
887 void restore_acceptance()
889 if (!restore_old_acc_)
891 std::const_pointer_cast<twa_graph>(aut_)->set_acceptance(old_acc_);
892 restore_old_acc_ =
false;
895 const_twa_graph_ptr get_aut()
const
900 unsigned start_state()
const
903 return lower_si_->one_state_of(lower_scc_);
904 return aut_->get_init_state_number();
907 scc_info::edge_filter get_filter()
const
910 return filter_scc_and_mark_and_edges_;
912 return filter_scc_and_mark_;
922 SPOT_API std::ostream&
924 const_twa_graph_ptr aut,
scc_info* sccinfo =
nullptr);
An acceptance condition.
Definition: acc.hh:61
A bit vector.
Definition: bitvect.hh:51
Definition: sccinfo.hh:102
Definition: sccinfo.hh:243
Create a filter for SCC and marks.
Definition: sccinfo.hh:810
scc_and_mark_filter(const const_twa_graph_ptr &aut, acc_cond::mark_t cut_sets)
Specify how to restrict scc_info to some acceptance sets.
Definition: sccinfo.hh:869
scc_and_mark_filter(const scc_info &lower_si, unsigned lower_scc, acc_cond::mark_t cut_sets)
Specify how to restrict scc_info to some SCC and acceptance sets.
Definition: sccinfo.hh:837
Storage for SCC related information.
Definition: sccinfo.hh:285
bool is_rejecting() const
True if we know that all cycles in the SCC are rejecting.
Definition: sccinfo.hh:334
bool is_accepting() const
True if we know that the SCC has an accepting cycle.
Definition: sccinfo.hh:324
Compute an SCC map and gather assorted information.
Definition: sccinfo.hh:449
scc_info(const_twa_graph_ptr aut, scc_info_options options)
Create the scc_info map for aut.
Definition: sccinfo.hh:497
bool is_maximally_accepting_scc(unsigned scc) const
Whether a cycle going through all edges of the SCC is accepting.
Definition: sccinfo.hh:680
std::vector< std::set< acc_cond::mark_t > > marks() const
Returns, for each accepting SCC, the set of all marks appearing in it.
int one_accepting_scc() const
Return the number of one accepting SCC if any, -1 otherwise.
Definition: sccinfo.hh:553
unsigned initial() const
Get number of the SCC containing the initial state.
Definition: sccinfo.hh:644
internal::scc_edges< const twa_graph::graph_t, internal::keep_inner_scc > inner_edges_of(unsigned scc) const
A fake container to iterate over all edges between states of an SCC.
Definition: sccinfo.hh:628
bool check_scc_emptiness(unsigned n) const
Recompute whether an SCC is accepting or not.
void determine_unknown_acceptance()
Study the SCCs that are currently reported neither as accepting nor as rejecting because of the prese...
void get_accepting_run(unsigned scc, twa_run_ptr r) const
Retrieves an accepting run of the automaton whose cycle is in the SCC.
scc_info(const_twa_graph_ptr aut, unsigned initial_state=~0U, edge_filter filter=nullptr, void *filter_data=nullptr, scc_info_options options=scc_info_options::ALL)
Create the scc_info map for aut.
scc_info(const scc_and_mark_filter &filt)
Create an scc_info map from some filter.
Definition: sccinfo.hh:514
std::vector< unsigned > states_on_acc_cycle_of(unsigned scc) const
: Get all states visited by any accepting cycles of the 'scc'.
void states_on_acc_cycle_of_rec(unsigned scc, acc_cond::mark_t all_fin, acc_cond::mark_t all_inf, unsigned nb_pairs, std::vector< acc_cond::rs_pair > &pairs, std::vector< unsigned > &res, std::vector< unsigned > &old) const
: Recursive function used by states_on_acc_cycle_of().
acc_cond::mark_t common_sets_of(unsigned scc) const
Definition: sccinfo.hh:747
internal::scc_edges< const twa_graph::graph_t, internal::keep_all > edges_of(unsigned scc) const
A fake container to iterate over all edges leaving any state of an SCC.
Definition: sccinfo.hh:611
acc_cond::mark_t acc_sets_of(unsigned scc) const
Returns, for a given SCC, the set of all colors appearing in it. It is the set of colors that appear ...
Definition: sccinfo.hh:740
scc_info(const scc_and_mark_filter &filt, scc_info_options options)
Create an scc_info map from some filter.
std::vector< twa_graph_ptr > split_on_sets(unsigned scc, acc_cond::mark_t sets, bool preserve_names=false) const
Split an SCC into multiple automata separated by some acceptance sets.
edge_filter_choice(* edge_filter)(const twa_graph::edge_storage_t &e, unsigned dst, void *filter_data)
An edge_filter may be called on each edge to decide what to do with it.
Definition: sccinfo.hh:58
scc_info_options
Options to alter the behavior of scc_info.
Definition: sccinfo.hh:373
edge_filter_choice
An edge_filter may be called on each edge to decide what to do with it.
Definition: sccinfo.hh:56
@ TRACK_STATES_IF_FIN_USED
@ ALL
Default behavior: explore everything and track states and succs.
@ PROCESS_UNREACHABLE_STATES
Definition: automata.hh:26
std::ostream & dump_scc_info_dot(std::ostream &out, const_twa_graph_ptr aut, scc_info *sccinfo=nullptr)
Dump the SCC graph of aut on out.
const mc_rvalue operator|(const mc_rvalue &lhs, const mc_rvalue &rhs)
This function helps to find the output value from a set of threads that may have different values.
Definition: mc.hh:130
An acceptance mark.
Definition: acc.hh:84
Definition: sccinfo.hh:65
Definition: sccinfo.hh:76