Vcsn  2.0
Be Rational
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
ratexp-automaton.hh
Go to the documentation of this file.
1 #ifndef VCSN_CORE_RATEXP_AUTOMATON_HH
2 # define VCSN_CORE_RATEXP_AUTOMATON_HH
3 
4 # include <memory>
5 # include <stack>
6 # include <string>
7 
8 # include <vcsn/misc/escape.hh>
9 # include <vcsn/misc/map.hh>
11 
12 # include <vcsn/core/fwd.hh> // ratexp_automaton
15 
16 //# define DEBUG 1
17 
18 # if DEBUG
19 # define DEBUG_IFELSE(Then, Else) Then
20 # else
21 # define DEBUG_IFELSE(Then, Else) Else
22 # endif
23 
24 # define DEBUG_IF(Then) DEBUG_IFELSE(Then,)
25 
26 namespace vcsn
27 {
28  namespace detail
29  {
31  template <typename Aut>
32  class ratexp_automaton_impl
33  : public automaton_decorator<Aut>
34  {
35  public:
36  using automaton_t = Aut;
40  using ratexp_t = typename ratexpset_t::value_t;
44 
46  : super_t(ctx)
47  , rs_(ctx, rat::identities::trivial)
48  {}
49 
51  static std::string sname()
52  {
53  return "ratexp_automaton<" + super_t::sname() + ">";
54  }
55 
57  std::string vname(bool full = true) const
58  {
59  return "ratexp_automaton<" + super_t::vname(full) + ">";
60  }
61 
63  using smap = std::unordered_map<ratexp_t, state_t,
66 
70  {
71  // Benches show that the map_.emplace technique is slower, and
72  // then that operator[] is faster than emplace.
73  state_t res;
74  auto i = map_.find(r);
75  if (i == std::end(map_))
76  {
77  DEBUG_IF(
78  std::cerr << "New state: ";
79  rs_.print(r, std::cerr) << '\n';
80  );
81  res = super_t::new_state();
82  map_[r] = res;
83  todo_.push(r);
84  }
85  else
86  res = i->second;
87  return res;
88  }
89 
91  void
92  add_transition(state_t src, const ratexp_t& dst,
93  const label_t& l, const weight_t& w)
94  {
95  super_t::add_transition(src, state(dst), l, w);
96  }
97 
99  void
100  new_transition(state_t src, const ratexp_t& dst,
101  const label_t& l, const weight_t& w)
102  {
103  super_t::new_transition(src, state(dst), l, w);
104  }
105 
106  using super_t::set_initial;
107  void
108  set_initial(const ratexp_t& s, const weight_t& w)
109  {
111  }
112 
113  bool state_has_name(state_t s) const
114  {
115  return (s != super_t::pre()
116  && s != super_t::post()
117  && has(origins(), s));
118  }
119 
120  std::ostream&
121  print_state_name(state_t s, std::ostream& o,
122  const std::string& fmt = "text",
123  bool = false) const
124  {
125  auto i = origins().find(s);
126  if (i == std::end(origins()))
127  this->print_state(s, o);
128  else
129  rs_.print(i->second, o, fmt);
130  return o;
131  }
132 
134  using origins_t = std::map<state_t, ratexp_t>;
136  const origins_t&
137  origins() const
138  {
139  if (origins_.empty())
140  for (const auto& p: map_)
141  origins_[p.second] = p.first;
142  return origins_;
143  }
144 
148  std::stack<ratexp_t> todo_;
151  };
152  }
153 }
154 
155 #endif // !VCSN_CORE_RATEXP_AUTOMATON_HH
void set_initial(const ratexp_t &s, const weight_t &w)
static constexpr auto sname(Args &&...args) -> decltype(automaton_t::element_type::sname(std::forward< Args >(args)...))
void new_transition(state_t src, const ratexp_t &dst, const label_t &l, const weight_t &w)
state_t state(const ratexp_t &r)
The state for ratexp r.
std::string vname(bool full=true) const
Dynamic name.
typename ratexpset_t::value_t ratexp_t
#define DEBUG_IF(Then)
auto vname(Args &&...args) const -> decltype(aut_-> vname(std::forward< Args >(args)...))
auto new_state(Args &&...args) -> decltype(aut_-> new_state(std::forward< Args >(args)...))
context_t_of< automaton_t > context_t
std::map< state_t, ratexp_t > origins_t
Ordered map: state -> its derived term.
auto set_initial(Args &&...args) -> decltype(aut_-> set_initial(std::forward< Args >(args)...))
typename detail::context_t_of_impl< base_t< ValueSet >>::type context_t_of
Definition: traits.hh:32
void add_transition(state_t src, const ratexp_t &dst, const label_t &l, const weight_t &w)
Aggregate an automaton, and forward calls to it.
std::ostream & print_state_name(state_t s, std::ostream &o, const std::string &fmt="text", bool=false) const
typename detail::label_t_of_impl< base_t< ValueSet >>::type label_t_of
Definition: traits.hh:33
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:36
const origins_t & origins() const
ratexp_automaton_impl(const context_t &ctx)
ratexpset_t rs_
The ratexp's set.
typename detail::weight_t_of_impl< base_t< ValueSet >>::type weight_t_of
Definition: traits.hh:37
std::unordered_map< ratexp_t, state_t, vcsn::hash< ratexpset_t >, vcsn::equal_to< ratexpset_t >> smap
Symbolic states to state handlers.
static constexpr auto pre(Args &&...args) -> decltype(automaton_t::element_type::pre(std::forward< Args >(args)...))
This is useful to make hashes with labels or weights as keys without using non-default constructors; ...
Definition: hash.hh:42
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
Definition: traits.hh:35
auto add_transition(Args &&...args) -> decltype(aut_-> add_transition(std::forward< Args >(args)...))
static std::string sname()
Static name.
identities
A ratexpset can implement several different sets of identities on expressions.
Definition: identities.hh:17
auto new_transition(Args &&...args) -> decltype(aut_-> new_transition(std::forward< Args >(args)...))
auto print_state(Args &&...args) const -> decltype(aut_-> print_state(std::forward< Args >(args)...))
variadic_mul_mixin< detail::r_impl > r
Definition: fwd.hh:42
bool has(const std::map< Key, Value, Compare, Alloc > &s, const Key &e)
Definition: map.hh:35
static constexpr auto post(Args &&...args) -> decltype(automaton_t::element_type::post(std::forward< Args >(args)...))
This is useful to make hashes with labels or weights as keys without using non-default constructors; ...
Definition: hash.hh:26
std::stack< ratexp_t > todo_
States to visit.