Vcsn  2.0
Be Rational
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
insplit.hh
Go to the documentation of this file.
1 #ifndef VCSN_ALGOS_INSPLIT_HH
2 # define VCSN_ALGOS_INSPLIT_HH
3 
4 # include <unordered_map>
5 
6 # include <vcsn/dyn/automaton.hh> // dyn::make_automaton
7 # include <vcsn/algos/copy.hh>
8 # include <vcsn/algos/fwd.hh>
9 # include <vcsn/misc/pair.hh>
10 # include <vcsn/misc/attributes.hh>
11 
12 namespace vcsn
13 {
14  namespace detail
15  {
16  template <typename Aut>
17  class insplitter
18  {
19  using automaton_t = Aut;
23 
24  using pair_t = typename std::pair<state_t, bool>;
25 
26  // Associate a state with itself and (possibly) the new one from the split
27  // false: Original state
28  // true: Duplicated via splitting
29  std::unordered_map<pair_t, state_t> states_assoc;
30 
31  public:
32  insplitter(const Aut& aut)
34  {}
35 
36  automaton_t operator()(const Aut& aut)
37  {
39  return aut;
40 
41  states_assoc[pair_t(aut->pre(), false)] = res_->pre();
42  states_assoc[pair_t(aut->post(), false)] = res_->post();
43 
44  for (auto st : aut->states())
45  {
46  bool epsilon_in = false;
47  bool letter_in = false;
48 
49  for (auto tr : aut->all_in(st))
50  {
51  if (is_one(aut, tr))
52  epsilon_in = true;
53  else
54  letter_in = true;
55  if (epsilon_in && letter_in)
56  break;
57  }
58  if (epsilon_in)
59  states_assoc[pair_t(st, true)] = res_->new_state();
60  if (letter_in)
61  states_assoc[pair_t(st, false)] = res_->new_state();
62  }
63 
64  for (auto st : aut->all_states())
65  for (bool epsilon : { false, true })
66  if (exists(st, epsilon))
67  for (auto t : aut->all_out(st))
68  res_->add_transition_copy(states_assoc[pair_t(st, epsilon)],
69  states_assoc[pair_t(aut->dst_of(t),
70  is_one(aut, t))],
71  aut, t);
72 
73  return std::move(res_);
74  }
75 
76  private:
77  inline bool exists(state_t st, bool epsilon)
78  {
79  return states_assoc.find(pair_t(st, epsilon)) != states_assoc.end();
80  }
81 
82  template <typename A>
83  typename std::enable_if<labelset_t_of<A>::has_one(),
84  bool>::type
85  is_one(const A& aut, transition_t tr)
86  {
87  return aut->labelset()->is_one(aut->label_of(tr));
88  }
89 
90  template <typename A>
91  typename std::enable_if<!labelset_t_of<A>::has_one(),
92  bool>::type
93  is_one(const A&, transition_t)
94  {
95  raise("lal should not reach this point!");
96  }
97 
99  };
100 
101  template<typename Aut>
102  typename std::enable_if<labelset_t_of<Aut>::has_one(), Aut>::type
103  insplit(Aut& aut)
104  {
106  return insplit(aut);
107  }
108 
109  template<typename Aut>
110  typename std::enable_if<!labelset_t_of<Aut>::has_one(), Aut>::type
111  insplit(Aut& aut)
112  {
113  return aut;
114  }
115  } // namespace detail
116 
117  template <typename Aut>
118  inline
119  auto
120  insplit(const Aut& aut)
121  -> decltype(detail::insplit(aut))
122  {
123  return detail::insplit(aut);
124  }
125 
126  namespace dyn
127  {
128  namespace detail
129  {
131  template <typename Aut>
132  automaton
133  insplit(const automaton& aut)
134  {
135  const auto& a = aut->as<Aut>();
136  return make_automaton(::vcsn::insplit(a));
137  }
138 
140  (const automaton& aut) -> automaton);
141  }
142  }
143 
144 } // namespace vcsn
145 
146 #endif // !VCSN_ALGOS_INSPLIT_HH
insplitter(const Aut &aut)
Definition: insplit.hh:32
std::enable_if<!labelset_t_of< A >::has_one(), bool >::type is_one(const A &, transition_t)
Definition: insplit.hh:93
bool exists(state_t st, bool epsilon)
Definition: insplit.hh:77
REGISTER_DECLARE(accessible,(const automaton &) -> automaton)
std::shared_ptr< detail::automaton_base > automaton
Definition: automaton.hh:71
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
Definition: traits.hh:34
automaton insplit(const automaton &aut)
Bridge.
Definition: insplit.hh:133
automaton_t operator()(const Aut &aut)
Definition: insplit.hh:36
automaton make_automaton(const Aut &aut)
Build a dyn::automaton.
Definition: automaton.hh:77
state_t_of< automaton_t > state_t
Definition: insplit.hh:20
auto insplit(const Aut &aut) -> decltype(detail::insplit(aut))
Definition: insplit.hh:120
std::enable_if< labelset_t_of< A >::has_one(), bool >::type is_one(const A &aut, transition_t tr)
Definition: insplit.hh:85
typename detail::label_t_of_impl< base_t< ValueSet >>::type label_t_of
Definition: traits.hh:33
std::unordered_map< pair_t, state_t > states_assoc
Definition: insplit.hh:29
std::enable_if< labelset_t_of< Aut >::has_one(), Aut >::type insplit(Aut &aut)
Definition: insplit.hh:103
typename detail::transition_t_of_impl< base_t< ValueSet >>::type transition_t_of
Definition: traits.hh:36
label_t_of< automaton_t > label_t
Definition: insplit.hh:21
auto real_context(const Aut &aut) -> decltype(real_context_impl< Aut >::context(aut))
Definition: copy.hh:157
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
Definition: traits.hh:35
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:15
typename std::pair< state_t, bool > pair_t
Definition: insplit.hh:24
transition_t_of< automaton_t > transition_t
Definition: insplit.hh:22