22 #include <spot/misc/common.hh> 24 #include <type_traits> 30 #include <type_traits> 34 template <
typename State_Data,
typename Edge_Data,
bool Alternating = false>
40 template <
typename Of,
typename ...Args>
43 static const bool value =
false;
46 template <
typename Of,
typename Arg1,
typename ...Args>
49 static const bool value =
50 std::is_base_of<Of, typename std::decay<Arg1>::type>::value;
60 template <typename Data, bool boxed = !std::is_class<Data>::value>
67 template <
typename... Args,
68 typename =
typename std::enable_if<
70 boxed_label(Args&&... args)
71 noexcept(std::is_nothrow_constructible<Data, Args...>::value)
72 : label{std::forward<Args>(args)...}
79 explicit boxed_label()
80 noexcept(std::is_nothrow_constructible<Data>::value)
89 const Data& data()
const 94 bool operator<(
const boxed_label& other)
const 96 return label < other.label;
103 typedef std::tuple<> data_t;
109 const std::tuple<>& data()
const 116 template <
typename Data>
122 template <
typename... Args,
123 typename =
typename std::enable_if<
125 boxed_label(Args&&... args)
126 noexcept(std::is_nothrow_constructible<Data, Args...>::value)
127 : Data{std::forward<Args>(args)...}
134 explicit boxed_label()
135 noexcept(std::is_nothrow_constructible<Data>::value)
144 const Data& data()
const 157 template <
typename Edge,
typename State_Data>
164 template <
typename... Args,
165 typename =
typename std::enable_if<
167 distate_storage(Args&&... args)
168 noexcept(std::is_nothrow_constructible<State_Data, Args...>::value)
169 : State_Data{std::forward<Args>(args)...}
181 template <
typename StateIn,
182 typename StateOut,
typename Edge,
typename Edge_Data>
193 noexcept(std::is_nothrow_constructible<Edge_Data>::value)
199 template <
typename... Args>
201 StateIn src, Args&&... args)
202 noexcept(std::is_nothrow_constructible<Edge_Data, Args...>::value
203 && std::is_nothrow_constructible<StateOut, StateOut>::value
204 && std::is_nothrow_constructible<Edge, Edge>::value)
205 : Edge_Data{std::forward<Args>(args)...},
206 dst(dst), next_succ(next_succ), src(src)
222 return this->data() < other.data();
227 return src == other.src &&
229 this->data() == other.data();
241 template <
typename Graph>
243 std::iterator<std::forward_iterator_tag,
245 std::conditional<std::is_const<Graph>::value,
246 const typename Graph::edge_storage_t,
247 typename Graph::edge_storage_t>::type>
250 std::iterator<std::forward_iterator_tag,
252 std::conditional<std::is_const<Graph>::value,
253 const typename Graph::edge_storage_t,
254 typename Graph::edge_storage_t>::type>
257 typedef typename Graph::edge edge;
279 typename super::reference
282 return g_->edge_storage(t_);
285 const typename super::reference
288 return g_->edge_storage(t_);
291 typename super::pointer
294 return &g_->edge_storage(t_);
297 const typename super::pointer
300 return &g_->edge_storage(t_);
305 t_ = operator*().next_succ;
312 t_ = operator*().next_succ;
316 operator bool()
const 331 template <
typename Graph>
336 typedef typename Graph::state_storage_t state_storage_t;
337 typedef typename Graph::edge edge;
340 : super(g, t), src_(src), prev_(0)
347 this->t_ = this->operator*().next_succ;
361 edge next = this->operator*().next_succ;
366 this->g_->edge_storage(prev_).next_succ = next;
370 if (src_.succ == this->t_)
373 if (src_.succ_tail == this->t_)
375 src_.succ_tail = prev_;
380 this->operator*().next_succ = this->t_;
385 ++this->g_->killed_edge_;
389 state_storage_t& src_;
400 template <
typename Graph>
404 typedef typename Graph::edge edge;
434 template <
typename Graph>
436 std::iterator<std::forward_iterator_tag,
438 std::conditional<std::is_const<Graph>::value,
439 const typename Graph::edge_storage_t,
440 typename Graph::edge_storage_t>::type>
443 std::iterator<std::forward_iterator_tag,
445 std::conditional<std::is_const<Graph>::value,
446 const typename Graph::edge_storage_t,
447 typename Graph::edge_storage_t>::type>
450 typedef typename std::conditional<std::is_const<Graph>::value,
451 const typename Graph::edge_vector_t,
452 typename Graph::edge_vector_t>::type
460 unsigned s = tv_.size();
463 while (t_ < s && tv_[t_].next_succ == t_);
474 : t_(tv.size()), tv_(tv)
501 typename super::reference
507 const typename super::reference
513 const typename super::pointer
519 typename super::pointer
527 template <
typename Graph>
531 typedef typename std::conditional<std::is_const<Graph>::value,
532 const typename Graph::edge_vector_t,
533 typename Graph::edge_vector_t>::type
561 template <
typename State_Data,
typename Edge_Data,
bool Alternating>
572 static constexpr
bool alternating()
578 typedef State_Data state_data_t;
579 typedef Edge_Data edge_data_t;
583 typedef unsigned state;
584 typedef unsigned edge;
588 typedef typename std::conditional<Alternating,
590 state>::type out_state;
598 typedef std::vector<state_storage_t> state_vector;
599 typedef std::vector<edge_storage_t> edge_vector_t;
601 state_vector states_;
602 edge_vector_t edges_;
604 unsigned killed_edge_;
612 digraph(
unsigned max_states = 10,
unsigned max_trans = 0)
615 states_.reserve(max_states);
617 max_trans = max_states * 2;
618 edges_.reserve(max_trans + 1);
623 edges_[0].next_succ = 0;
626 unsigned num_states()
const 628 return states_.size();
631 unsigned num_edges()
const 633 return edges_.size() - killed_edge_ - 1;
636 bool valid_trans(edge t)
const 640 return (t < edges_.size() &&
641 edges_[t].next_succ != t);
644 template <
typename... Args>
645 state new_state(Args&&... args)
647 state s = states_.size();
648 states_.emplace_back(std::forward<Args>(args)...);
652 template <
typename... Args>
653 state new_states(
unsigned n, Args&&... args)
655 state s = states_.size();
656 states_.reserve(s + n);
658 states_.emplace_back(std::forward<Args>(args)...);
663 state_storage(state s)
665 assert(s < states_.size());
669 const state_storage_t&
670 state_storage(state s)
const 672 assert(s < states_.size());
678 typename state_storage_t::data_t&
681 assert(s < states_.size());
682 return states_[s].data();
686 const typename state_storage_t::data_t&
687 state_data(state s)
const 689 assert(s < states_.size());
690 return states_[s].data();
696 assert(s < edges_.size());
700 const edge_storage_t&
701 edge_storage(edge s)
const 703 assert(s < edges_.size());
707 typename edge_storage_t::data_t&
710 assert(s < edges_.size());
711 return edges_[s].data();
714 const typename edge_storage_t::data_t&
715 edge_data(edge s)
const 717 assert(s < edges_.size());
718 return edges_[s].data();
721 template <
typename... Args>
723 new_edge(state src, out_state dst, Args&&... args)
725 assert(src < states_.size());
727 edge t = edges_.size();
728 edges_.emplace_back(dst, 0, src, std::forward<Args>(args)...);
730 edge st = states_[src].succ_tail;
731 assert(st < t || !st);
733 states_[src].succ = t;
735 edges_[st].next_succ = t;
736 states_[src].succ_tail = t;
740 state index_of_state(
const state_storage_t& ss)
const 742 assert(!states_.empty());
743 return &ss - &states_.front();
746 edge index_of_edge(
const edge_storage_t&
tt)
const 748 assert(!edges_.empty());
749 return &tt - &edges_.front();
755 return {
this, states_[src].succ};
759 out(state_storage_t& src)
761 return out(index_of_state(src));
767 return {
this, states_[src].succ};
771 out(state_storage_t& src)
const 773 return out(index_of_state(src));
777 out_iteraser(state_storage_t& src)
779 return {
this, src.succ, src};
783 out_iteraser(state src)
785 return out_iteraser(state_storage(src));
788 const state_vector& states()
const 793 state_vector& states()
813 const edge_vector_t& edge_vector()
const 818 edge_vector_t& edge_vector()
823 bool is_dead_edge(
unsigned t)
const 825 return edges_[t].next_succ == t;
828 bool is_dead_edge(
const edge_storage_t& t)
const 830 return t.next_succ == index_of_edge(t);
835 void dump_storage(std::ostream& o)
const 837 unsigned tend = edges_.size();
838 for (
unsigned t = 1; t < tend; ++t)
840 o <<
't' << t <<
": (s" 841 << edges_[t].src <<
", s" 842 << edges_[t].dst <<
") t" 843 << edges_[t].next_succ <<
'\n';
845 unsigned send = states_.size();
846 for (
unsigned s = 0; s < send; ++s)
848 o <<
's' << s <<
": t" 849 << states_[s].succ <<
" t" 850 << states_[s].succ_tail <<
'\n';
858 void remove_dead_edges_()
860 if (killed_edge_ == 0)
862 auto i = std::remove_if(edges_.begin() + 1, edges_.end(),
863 [
this](
const edge_storage_t& t) {
864 return this->is_dead_edge(t);
866 edges_.erase(i, edges_.end());
873 template<
class Predicate = std::less<edge_storage_t>>
874 void sort_edges_(Predicate p = Predicate())
878 std::stable_sort(edges_.begin() + 1, edges_.end(), p);
885 state last_src = -1
U;
886 edge tend = edges_.size();
887 for (edge t = 1; t < tend; ++t)
889 state src = edges_[t].src;
892 states_[src].succ = t;
895 states_[last_src].succ_tail = t - 1;
896 edges_[t - 1].next_succ = 0;
898 while (++last_src != src)
900 states_[last_src].succ = 0;
901 states_[last_src].succ_tail = 0;
906 edges_[t - 1].next_succ = t;
911 states_[last_src].succ_tail = tend - 1;
912 edges_[tend - 1].next_succ = 0;
914 unsigned send = states_.size();
915 while (++last_src != send)
917 states_[last_src].succ = 0;
918 states_[last_src].succ_tail = 0;
928 void rename_states_(
const std::vector<unsigned>& newst)
930 assert(newst.size() == states_.size());
931 unsigned tend = edges_.size();
932 for (
unsigned t = 1; t < tend; t++)
934 edges_[t].dst = newst[edges_[t].dst];
935 edges_[t].src = newst[edges_[t].src];
939 void defrag_states(std::vector<unsigned>&& newst,
unsigned used_states)
941 assert(newst.size() == states_.size());
942 assert(used_states > 0);
948 unsigned send = states_.size();
949 for (state s = 0; s < send; ++s)
951 state dst = newst[s];
959 auto t = states_[s].succ;
961 std::swap(t, edges_[t].next_succ);
964 states_[dst] = std::move(states_[s]);
966 states_.resize(used_states);
971 unsigned tend = edges_.size();
972 std::vector<edge> newidx(tend);
974 for (edge t = 1; t < tend; ++t)
979 edges_[dest] = std::move(edges_[t]);
987 for (edge t = 1; t < dest; ++t)
989 auto& tr = edges_[t];
990 tr.next_succ = newidx[tr.next_succ];
991 tr.dst = newst[tr.dst];
992 tr.src = newst[tr.src];
993 assert(tr.dst != -1
U);
997 for (
auto& s: states_)
999 s.succ = newidx[s.succ];
1000 s.succ_tail = newidx[s.succ_tail];
digraph(unsigned max_states=10, unsigned max_trans=0)
construct an empty graph
Definition: graph.hh:612
Abstract class for states.
Definition: twa.hh:43