1 #ifndef VCSN_ALGOS_HAS_TWINS_PROPERTY_HH
2 # define VCSN_ALGOS_HAS_TWINS_PROPERTY_HH
31 template <
typename Aut>
45 std::unordered_map<state_t, weight_t> wm;
47 const auto& ws = *aut->weightset();
49 auto ws1 = ws.template set<0>();
50 auto s0 = *component.begin();
51 std::stack<state_t> todo;
59 for (
auto t : aut->all_out(s))
61 auto dst = aut->dst_of(t);
62 if (
has(component, dst))
64 auto w = ws.mul(wm[s], aut->weight_of(t));
72 auto w2 = ws.mul(wm[dst], w);
74 if (!ws1.equals(std::get<0>(w2), std::get<1>(w2)))
86 template <
typename Aut>
91 return ci.
check(c, aut);
102 template <
typename InAut,
typename OutAut>
104 OutAut& naut1, OutAut& naut2)
107 std::unordered_map<state_t, state_t> ms;
109 ms[aut->pre()] = naut1->pre();
110 ms[aut->post()] = naut1->post();
111 for (
auto s : aut->states())
113 ms[s] = naut1->new_state();
117 const auto& ws = *aut->weightset();
118 for (
auto t : aut->all_transitions())
120 auto src = aut->src_of(t);
121 auto dst = aut->dst_of(t);
122 auto w = aut->weight_of(t);
123 auto l = aut->label_of(t);
124 auto nw1 = std::make_tuple(w, ws.one());
125 auto nw2 = std::make_tuple(ws.one(), w);
126 naut1->new_transition(ms[src], ms[dst], l, nw1);
127 naut2->new_transition(ms[src], ms[dst], l, nw2);
132 template <
typename Aut>
136 "has_twins_property: requires a cycle-unambiguous automaton");
139 auto ws = *aut->weightset();
140 auto nt = std::make_tuple(ws, ws);
150 auto a =
product(naut1, naut2);
168 template <
typename Aut>
171 const auto& a = aut->as<Aut>();
180 #endif // !VCSN_ALGOS_HAS_TWINS_PROPERTY_HH
mutable_automaton< Context > make_mutable_automaton(const Context &ctx)
REGISTER_DECLARE(accessible,(const automaton &) -> automaton)
std::shared_ptr< detail::automaton_base > automaton
auto product(const Auts &...as) -> product_automaton< decltype(meet_automata(as...)), Auts...>
Build the (accessible part of the) product.
A ValueSet which is a Cartesian product of ValueSets.
bool has_twins_property(const automaton &aut)
Whether all the paths between any two states have the same weight (i.e., for all s0, s1, any two paths p0, p1 between s0 and s1 have the same weight w_{s0,s1}).
std::set< state_t_of< Aut >> component_t
An strongly-connected component: list of states.
transition_t_of< Aut > transition_t
void create_states_and_trans_(const InAut &aut, OutAut &naut1, OutAut &naut2)
Create states and the transitions two new automata naut1 and naut2 with weight of transition <(w...
bool cycle_identity(const detail::component_t< Aut > &c, const Aut &aut)
Check the weight of two states on this component is unique.
filter_automaton< Aut > trim(const Aut &a)
state_t_of< Aut > state_t
typename detail::transition_t_of_impl< base_t< ValueSet >>::type transition_t_of
const detail::components_t< Aut > scc(const Aut &aut, SCC_ALGO algo=SCC_ALGO::TARJAN)
Find all strongly connected components of aut.
bool check(const component_t &component, const Aut &aut)
By DFS starting in s0, check that all the states are reached with a single weight.
bool has_twins_property(const Aut &aut)
Whether aut has the twins property.
typename detail::weight_t_of_impl< base_t< ValueSet >>::type weight_t_of
bool is_cycle_ambiguous(const Aut &aut)
Whether aut is cycle-ambiguous.
weight_t_of< Aut > weight_t
detail::component_t< Aut > component_t
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
Ctx make_context(const std::string &name)
bool has(const std::map< Key, Value, Compare, Alloc > &s, const Key &e)
void require(bool b, Args &&...args)
If b is not verified, raise an error with args as message.