Vcsn  2.0
Be Rational
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
is-ambiguous.hh
Go to the documentation of this file.
1 #ifndef VCSN_ALGOS_IS_AMBIGUOUS_HH
2 # define VCSN_ALGOS_IS_AMBIGUOUS_HH
3 
4 # include <vcsn/algos/accessible.hh>
5 # include <vcsn/algos/distance.hh>
6 # include <vcsn/algos/product.hh>
7 # include <vcsn/algos/scc.hh>
8 # include <vcsn/dyn/fwd.hh>
9 
10 namespace vcsn
11 {
12 
13  /*---------------.
14  | is_ambiguous. |
15  `---------------*/
16 
22  template <typename Aut>
23  bool is_ambiguous(const Aut& aut,
24  std::tuple<state_t_of<Aut>, state_t_of<Aut>>& witness)
25  {
26  auto prod = product(aut, aut);
27  // Check if there useful states outside of the diagonal. Since
28  // the product is accessible, check only for coaccessibles states.
29  auto coaccessible = coaccessible_states(prod);
30  for (const auto& o: prod->origins())
31  if (std::get<0>(o.second) != std::get<1>(o.second)
32  && has(coaccessible, o.first))
33  {
34  witness = o.second;
35  return true;
36  }
37  return false;
38  }
39 
40  template <typename Aut>
41  bool is_ambiguous(const Aut& aut)
42  {
43  std::tuple<state_t_of<Aut>, state_t_of<Aut>> dummy;
44  return is_ambiguous(aut, dummy);
45  }
46 
47  namespace dyn
48  {
49  namespace detail
50  {
52  template <class Aut>
53  bool is_ambiguous(const automaton& aut)
54  {
55  return is_ambiguous(aut->as<Aut>());
56  }
57 
59  (const automaton&) -> bool);
60  }
61  }
62 
63 
64  /*-----------------.
65  | ambiguous_word. |
66  `-----------------*/
67 
68  template <typename Aut>
69  typename labelset_t_of<Aut>::word_t ambiguous_word(const Aut& aut)
70  {
71  std::tuple<state_t_of<Aut>, state_t_of<Aut>> witness;
72  require(is_ambiguous(aut, witness),
73  "automaton is unambiguous");
74  const auto& ls = *aut->labelset();
75  typename labelset_t_of<Aut>::word_t res;
76  // Find the shortest word from initial to the witness.
77  auto s = std::get<0>(witness);
78  for (auto t: path_bfs(aut, aut->pre(), s))
79  {
80  auto l = aut->label_of(t);
81  if (!ls.is_special(l))
82  res = ls.concat(res, l);
83  }
84  for (auto t: path_bfs(aut, s, aut->post()))
85  {
86  auto l = aut->label_of(t);
87  if (!ls.is_special(l))
88  res = ls.concat(res, l);
89  }
90  return res;
91  }
92 
93 
94  namespace dyn
95  {
96  namespace detail
97  {
99  template <typename Aut>
100  label
102  {
103  const auto& a = aut->as<Aut>();
104  auto word = vcsn::ambiguous_word(a);
105  return make_label(make_wordset(*a->labelset()), word);
106  }
107 
109  (const automaton&) -> label);
110  }
111  }
112 
113 
114 
115  /*---------------------.
116  | is_cycle_ambiguous. |
117  `---------------------*/
118 
120  template <typename Aut>
121  bool is_cycle_ambiguous(const Aut& aut)
122  {
123  // Find all strongly connected components.
124  const auto& coms = scc(aut);
125  if (getenv("VCSN_DEBUG"))
126  {
127  std::cerr << "number states of automaton: " <<
128  aut->num_states() << std::endl;
129  std::cerr << "number components: " <<
130  coms.size() << std::endl;
131  }
132 
133  // Check each component if it is cycle-ambiguous.
134  if (coms.size() == 1)
135  return is_cycle_ambiguous_scc(aut);
136  for (const auto &c : coms)
137  {
138  const auto& a = aut_of_component(c, aut);
139  if (is_cycle_ambiguous_scc(a))
140  return true;
141  }
142  return false;
143  }
144 
147  template <typename Aut>
148  bool is_cycle_ambiguous_scc(const Aut& aut)
149  {
150  auto prod = product(aut, aut);
151  auto coms = scc(prod);
152  const auto& origins = prod->origins();
153  // In one SCC of prod = aut & aut, if there exist two states (s0,
154  // s0) (on the diagonal) and (s1, s2) with s1 != s2 (off the
155  // diagonal) then aut has two cycles with the same label:
156  // s0->s1->s0 and s0->s2->s0.
157  for (auto c : coms)
158  {
159  bool on = false;
160  bool off = false;
161  for (auto s : c)
162  {
163  auto p = origins.at(s);
164  if (std::get<0>(p) == std::get<1>(p))
165  on = true;
166  else
167  off = true;
168  if (on && off)
169  return true;
170  }
171  }
172  return false;
173  }
174 
175  namespace dyn
176  {
177  namespace detail
178  {
179  // Bridge.
180  template <typename Aut>
181  bool
183  {
184  const auto& a = aut->as<Aut>();
186  }
187 
189  (const automaton&) -> bool);
190  }
191  }
192 
193 
194 }
195 
196 #endif // !VCSN_ALGOS_IS_AMBIGUOUS_HH
filter_automaton< Aut > coaccessible(const Aut &a)
Definition: accessible.hh:134
bool is_ambiguous(const Aut &aut)
Definition: is-ambiguous.hh:41
REGISTER_DECLARE(accessible,(const automaton &) -> automaton)
std::shared_ptr< detail::automaton_base > automaton
Definition: automaton.hh:71
auto product(const Auts &...as) -> product_automaton< decltype(meet_automata(as...)), Auts...>
Build the (accessible part of the) product.
Definition: product.hh:445
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
Definition: traits.hh:34
Aut::element_type::automaton_nocv_t aut_of_component(const detail::component_t< Aut > &com, const Aut &aut)
Generate a subautomaton corresponding to an SCC.
Definition: scc.hh:250
std::vector< transition_t_of< Aut > > path_bfs(const Aut &aut, state_t_of< Aut > start, state_t_of< Aut > end)
A shortest path between two states.
Definition: distance.hh:119
labelset_t_of< Aut >::word_t ambiguous_word(const Aut &aut)
Definition: is-ambiguous.hh:69
law_t< LabelSet > make_wordset(const LabelSet &ls)
The wordset of a labelset.
Definition: labelset.hh:72
const detail::components_t< Aut > scc(const Aut &aut, SCC_ALGO algo=SCC_ALGO::TARJAN)
Find all strongly connected components of aut.
Definition: scc.hh:229
label ambiguous_word(const automaton &aut)
Bridge.
std::shared_ptr< const detail::label_base > label
Definition: fwd.hh:46
bool is_cycle_ambiguous(const automaton &aut)
bool is_cycle_ambiguous(const Aut &aut)
Whether aut is cycle-ambiguous.
bool is_ambiguous(const automaton &aut)
Bridge.
Definition: is-ambiguous.hh:53
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
label make_label(const LabelSet &ls, const typename LabelSet::value_t &l)
Definition: label.hh:82
bool is_cycle_ambiguous_scc(const Aut &aut)
Whether aut is cycle-ambiguous.
bool has(const std::map< Key, Value, Compare, Alloc > &s, const Key &e)
Definition: map.hh:35
void require(bool b, Args &&...args)
If b is not verified, raise an error with args as message.
Definition: raise.hh:39