Vcsn  2.1
Be Rational
insplit.hh
Go to the documentation of this file.
1 #pragma once
2 
3 #include <unordered_map>
4 
5 #include <vcsn/dyn/automaton.hh> // dyn::make_automaton
6 #include <vcsn/algos/copy.hh> // real_context
7 #include <vcsn/algos/fwd.hh>
8 #include <vcsn/misc/pair.hh>
9 
10 namespace vcsn
11 {
12  namespace detail
13  {
14  template <typename Aut>
15  class insplitter
16  {
17  static_assert(labelset_t_of<Aut>::has_one(), "insplit: the labelset must have a one label");
18  using automaton_t = Aut;
22 
23  using pair_t = std::pair<state_t, bool>;
24 
25  // Associate a state with itself and (possibly) the new one from the split
26  // false: Original state
27  // true: Duplicated via splitting
28  std::unordered_map<pair_t, state_t> states_assoc;
29 
30  public:
31  insplitter(const Aut& aut)
33  {}
34 
35  automaton_t operator()(const Aut& aut)
36  {
37 
38  states_assoc[pair_t(aut->pre(), false)] = res_->pre();
39  states_assoc[pair_t(aut->post(), false)] = res_->post();
40 
41  for (auto st : aut->states())
42  {
43  bool epsilon_in = false;
44  bool letter_in = false;
45 
46  for (auto tr : aut->all_in(st))
47  {
48  if (is_spontaneous(aut, tr))
49  epsilon_in = true;
50  else
51  letter_in = true;
52  if (epsilon_in && letter_in)
53  break;
54  }
55  if (epsilon_in)
56  states_assoc[pair_t(st, true)] = res_->new_state();
57  if (letter_in)
58  states_assoc[pair_t(st, false)] = res_->new_state();
59  }
60 
61  for (auto st : aut->all_states())
62  for (bool epsilon : { false, true })
63  if (exists(st, epsilon))
64  for (auto t : aut->all_out(st))
65  res_->add_transition_copy(states_assoc[pair_t(st, epsilon)],
66  states_assoc[pair_t(aut->dst_of(t),
67  is_spontaneous(aut, t))],
68  aut, t);
69 
70  return std::move(res_);
71  }
72 
73  private:
74  inline bool exists(state_t st, bool epsilon)
75  {
76  return states_assoc.find(pair_t(st, epsilon)) != states_assoc.end();
77  }
78 
79  bool
80  is_spontaneous(const Aut& aut, transition_t tr)
81  {
82  return aut->labelset()->is_one(aut->label_of(tr));
83  }
84 
86  };
87 
88  template<typename Aut>
90  insplit(Aut& aut)
91  {
93  return insplit(aut);
94  }
95 
96  template<typename Aut>
98  insplit(Aut& aut)
99  {
100  return aut;
101  }
102  } // namespace detail
103 
104  template <typename Aut>
105  inline
106  auto
107  insplit(const Aut& aut)
108  -> decltype(detail::insplit(aut))
109  {
110  return detail::insplit(aut);
111  }
112 
113  namespace dyn
114  {
115  namespace detail
116  {
118  template <typename Aut>
119  automaton
120  insplit(const automaton& aut)
121  {
122  const auto& a = aut->as<Aut>();
123  return make_automaton(::vcsn::insplit(a));
124  }
125  }
126  }
127 
128 } // namespace vcsn
bool exists(state_t st, bool epsilon)
Definition: insplit.hh:74
typename detail::label_t_of_impl< base_t< ValueSet >>::type label_t_of
Definition: traits.hh:46
insplitter(const Aut &aut)
Definition: insplit.hh:31
bool is_spontaneous(const Aut &aut, transition_t tr)
Definition: insplit.hh:80
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
Definition: traits.hh:48
typename std::enable_if< Cond, T >::type enable_if_t
Definition: type_traits.hh:16
auto real_context(const Aut &aut) -> decltype(real_context_impl< Aut >::context(aut))
For a focus automaton, its genuine context (not the visible one), and for all the other automata...
Definition: copy.hh:221
std::pair< state_t, bool > pair_t
Definition: insplit.hh:23
SharedPtr make_shared_ptr(Args &&...args)
Same as std::make_shared, but parameterized by the shared_ptr type, not the (pointed to) element_type...
Definition: memory.hh:14
automaton make_automaton(const Aut &aut)
Build a dyn::automaton.
Definition: automaton.hh:75
state_t_of< automaton_t > state_t
Definition: insplit.hh:19
vcsn::enable_if_t< labelset_t_of< Aut >::has_one(), Aut > insplit(Aut &aut)
Definition: insplit.hh:90
transition_t_of< automaton_t > transition_t
Definition: insplit.hh:21
std::shared_ptr< detail::automaton_base > automaton
Definition: automaton.hh:69
auto insplit(const Aut &aut) -> decltype(detail::insplit(aut))
Definition: insplit.hh:107
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
Definition: traits.hh:47
typename detail::transition_t_of_impl< base_t< ValueSet >>::type transition_t_of
Definition: traits.hh:49
label_t_of< automaton_t > label_t
Definition: insplit.hh:20
std::unordered_map< pair_t, state_t > states_assoc
Definition: insplit.hh:28
automaton insplit(const automaton &aut)
Bridge.
Definition: insplit.hh:120
automaton_t operator()(const Aut &aut)
Definition: insplit.hh:35