Vcsn  2.0
Be Rational
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
is-functional.hh
Go to the documentation of this file.
1 #ifndef VCSN_ALGOS_IS_FUNCTIONAL_HH
2 # define VCSN_ALGOS_IS_FUNCTIONAL_HH
3 
4 # include <queue>
5 # include <utility>
6 
7 # include <vcsn/algos/accessible.hh>
8 # include <vcsn/algos/compose.hh>
9 # include <vcsn/dyn/automaton.hh>
10 # include <vcsn/dyn/fwd.hh>
11 # include <vcsn/labelset/tupleset.hh>
13 
14 namespace vcsn
15 {
16  /*---------------.
17  | is-functional. |
18  `---------------*/
19 
25  template <typename Aut>
26  bool is_identity(const Aut& aut)
27  {
28  using state_t = state_t_of<Aut>;
29  using labelset_t = labelset_t_of<Aut>;
30 
32  using wordset_t = detail::law_t<labelset_t>;
33  using word_t = typename wordset_t::value_t;
34  wordset_t ls = make_wordset(*aut->labelset());
36  auto ls1 = ls.template set<0>();
39  std::unordered_map<state_t, word_t> rs;
40 
41  auto coaccessibles = coaccessible_states(aut);
42  std::queue<state_t> todo;
43  auto pre = aut->pre();
44  todo.push(pre);
45  rs.emplace(pre, ls.one());
46  // When reaching the final state, there must be no residue.
47  // Instead of checking this case especially, just make sure
48  // that when we reach post, we only collected (\e, \e).
49  rs.emplace(aut->post(), ls.one());
50 
51  while (!todo.empty())
52  {
53  auto s = todo.front();
54  todo.pop();
55  for (auto t : aut->all_out(s))
56  {
57  auto l = aut->label_of(t);
58  auto dst = aut->dst_of(t);
59  if (has(coaccessibles, dst))
60  {
61  auto p = rs[s];
62  p = ls.concat(p, l);
63  // Eliminate longest common prefix.
64  ls.lnormalize_here(p);
65  if (!has(rs, dst))
66  {
67  rs.emplace(dst, p);
68  todo.emplace(dst);
69  }
70  else if (!ls.equals(p, rs[dst]))
71  return false;
72  }
73  }
74  }
75  return true;
76  }
77 
80  template <typename Aut>
81  bool is_functional(const Aut& aut)
82  {
83  // Compose aut and its invert.
84  auto l = blind<0>(aut);
85  auto r = insplit(blind<0>(aut));
87  auto c = compose.compose();
88  return is_identity(c);
89  }
90 
91  namespace dyn
92  {
93  namespace detail
94  {
96  template <class Aut>
97  bool is_functional(const automaton& aut)
98  {
99  return is_functional(aut->as<Aut>());
100  }
101 
103  (const automaton&) -> bool);
104  }
105  }
106 }
107 
108 #endif // !VCSN_ALGOS_IS_FUNCTIONAL_HH
REGISTER_DECLARE(accessible,(const automaton &) -> automaton)
std::shared_ptr< detail::automaton_base > automaton
Definition: automaton.hh:71
Build the (accessible part of the) composition.
Definition: compose.hh:30
bool is_functional(const automaton &aut)
Bridge.
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
Definition: traits.hh:34
auto insplit(const Aut &aut) -> decltype(detail::insplit(aut))
Definition: insplit.hh:120
typename law_traits< LabelSet >::type law_t
The smallest wordset that includes LabelSet.
Definition: labelset.hh:67
bool is_functional(const Aut &aut)
Whether aut is functional.
law_t< LabelSet > make_wordset(const LabelSet &ls)
The wordset of a labelset.
Definition: labelset.hh:72
auto compose(Lhs &lhs, Rhs &rhs) -> typename detail::composer< blind_automaton< 1, Lhs >, blind_automaton< 0, Rhs >>::automaton_t
Build the (accessible part of the) composition.
Definition: compose.hh:289
automaton_t compose()
The (accessible part of the) product of lhs_ and rhs_.
Definition: compose.hh:111
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:36
states_t< Aut > coaccessible_states(const Aut &a)
Definition: accessible.hh:61
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
Definition: traits.hh:35
bool is_identity(const Aut &aut)
Whether transducer aut is equivalent to the identity function on all successful path.
bool has(const std::map< Key, Value, Compare, Alloc > &s, const Key &e)
Definition: map.hh:35