26 :
public ExpSet::const_visitor
29 "zpc: requires nullable labels");
32 using automaton_t = Aut;
33 using expressionset_t = ExpSet;
39 using super_t =
typename expressionset_t::const_visitor;
42 constexpr
static const char* me() {
return "zpc"; }
46 const expressionset_t&
rs,
49 , res_(make_shared_ptr<automaton_t>(ctx))
53 zpc_visitor(
const expressionset_t& rs,
bool compact)
58 operator()(
const typename expressionset_t::value_t&
v)
63 res_->set_initial(initial_);
64 res_->set_final(final_);
66 for (
auto t:
all_in(res_, res_->post()))
67 res_->set_weight(t, ws_.mul(res_->weight_of(t), final_weight_));
69 return std::move(res_);
71 catch (
const std::runtime_error& e)
74 " while computing ZPC automaton of: ",
to_string(rs_, v));
87 void visit(
const tuple_t&, std::true_type)
override
89 raise(me(),
": tuple is not supported");
94 initial_ = res_->new_state();
95 final_ = res_->new_state();
100 initial_ = res_->new_state();
101 final_ = res_->new_state();
103 res_->set_final(initial_);
108 initial_ = res_->new_state();
109 final_ = res_->new_state();
112 res_->new_transition(initial_, final_,
113 res_->labelset()->conv(*rs_.labelset(),
135 state_t initial = res_->new_state();
137 e.sub()->accept(*
this);
139 state_t
final = res_->new_state();
141 auto cst = ws_.star(res_->get_final_weight(initial_));
142 res_->unset_final(initial_);
144 res_->new_transition(initial, initial_, epsilon_, cst);
145 res_->new_transition(final_,
final, epsilon_, cst);
146 res_->new_transition(final_, initial_, epsilon_, cst);
151 res_->set_final(initial_, cst);
156 e.sub()->accept(*
this);
158 const weight_t& w = e.weight();
159 for (
auto t:
all_out(res_, initial_))
160 res_->set_weight(t, ws_.mul(w, res_->weight_of(t)));
165 e.sub()->accept(*
this);
167 final_weight_ = ws_.mul(e.weight(), final_weight_);
170 void add_regular(
const add_t& e)
172 state_t initial = res_->new_state();
174 weight_t cst = ws_.zero();
175 std::vector<state_t> finals_;
180 res_->new_transition(initial, initial_, epsilon_);
181 finals_.push_back(final_);
183 cst = ws_.add(cst, res_->get_final_weight(initial_));
184 res_->unset_final(initial_);
187 state_t
final = res_->new_state();
189 for (
auto s: finals_)
190 res_->new_transition(s,
final, epsilon_);
196 res_->set_final(initial_, cst);
199 void prod_regular(
const mul_t& e)
201 std::vector<state_t> state_stack;
204 for (
auto i = 0; i < e.size() - 1; ++i)
205 state_stack.push_back(res_->new_state());
207 e.head()->accept(*
this);
213 state_t initial_e = initial_;
214 state_t final_e = final_;
217 state_t initial = initial_e;
218 state_t
final = automaton_t::element_type::null_state();
220 initial = state_stack.back();
221 state_stack.pop_back();
222 res_->new_transition(initial, initial_e, epsilon_);
224 for (
auto t: e.tail())
228 final = res_->new_state();
229 res_->new_transition(final_,
final, epsilon_);
231 auto cst_e = res_->get_final_weight(initial_e);
232 auto cst_f = res_->get_final_weight(initial_);
234 res_->new_transition(initial, initial_, epsilon_, cst_e);
235 res_->unset_final(initial_e);
236 res_->new_transition(final_e,
final, epsilon_, cst_f);
237 res_->unset_final(initial_);
239 res_->set_final(initial, ws_.mul(cst_e, cst_f));
241 res_->new_transition(final_e, initial_, epsilon_);
246 if (!state_stack.empty())
248 initial = state_stack.back();
249 state_stack.pop_back();
251 res_->new_transition(initial, initial_e, epsilon_);
259 void add_compact(
const add_t& e)
261 e.head()->accept(*
this);
263 weight_t cst = res_->get_final_weight(initial_);
264 res_->unset_final(initial_);
266 state_t initial = initial_;
267 state_t initial_e = initial;
268 state_t final_e = final_;
270 for (
auto c: e.tail())
273 cst = ws_.add(cst, res_->get_final_weight(initial_));
274 res_->unset_final(initial_);
276 res_->new_transition(initial_e, initial_, epsilon_);
277 res_->new_transition(final_e, final_, epsilon_);
279 initial_e = initial_;
285 res_->set_final(initial_, cst);
288 void prod_compact(
const mul_t& e)
290 e.head()->accept(*
this);
292 state_t initial_e = initial_;
293 state_t final_e = final_;
296 state_t initial = initial_e;
299 for (
auto t: e.tail())
304 auto cst_e = res_->get_final_weight(initial_e);
305 auto cst_f = res_->get_final_weight(initial_);
307 res_->new_transition(initial, initial_, epsilon_, cst_e);
308 res_->unset_final(initial_e);
309 res_->new_transition(final_e,
final, epsilon_, cst_f);
310 res_->unset_final(initial_);
312 res_->set_final(initial, ws_.mul(cst_e, cst_f));
314 res_->new_transition(final_e, initial_, epsilon_);
325 const expressionset_t& rs_;
326 const weightset_t& ws_ = *rs_.weightset();
329 const label_t epsilon_ = res_->labelset()->one();
330 state_t initial_ = automaton_t::element_type::null_state();
331 state_t final_ = automaton_t::element_type::null_state();
332 weight_t final_weight_ = ws_.one();
342 template <Automaton Aut,
typename ExpSet>
346 const typename ExpSet::value_t&
r,
347 const std::string& algo =
"auto")
356 {
"auto", std::string(
"regular")},
374 template <
typename ExpSet,
typename String>
380 using expressionset_t = ExpSet;
381 const auto& e = exp->
as<expressionset_t>();
384 using ctx_t = decltype(ctx);
386 return ::vcsn::zpc<automaton_t>(
ctx, e.valueset(), e.value(), algo);
An inner node with multiple children.
Aut zpc(const context_t_of< Aut > &ctx, const ExpSet &rs, const typename ExpSet::value_t &r, const std::string &algo="auto")
Build a ZPC automaton from an expression.
auto all_out(const Aut &aut, state_t_of< Aut > s)
Indexes of transitions leaving state s.
A mapping from strings to Values.
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
#define VCSN_RAT_UNSUPPORTED(Type)
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
static dyn::context ctx(const driver &d)
Get the context of the driver.
auto(const std::vector< automaton > &as) -> automaton tuple_t
nullableset_context_t< context< LabelSet, WeightSet > > make_nullableset_context(const context< LabelSet, WeightSet > &ctx)
The nullableset context of a context.
Provide a variadic mul on top of a binary mul(), and one().
auto all_in(const Aut &aut, state_t_of< Aut > s)
Indexes of transitions entering state s.
typename detail::weightset_t_of_impl< base_t< ValueSet >>::type weightset_t_of
std::string to_string(identities i)
Wrapper around operator<<.
automaton zpc(const expression &exp, const std::string &algo)
Bridge.
typename detail::weight_t_of_impl< base_t< ValueSet >>::type weight_t_of
typename detail::context_t_of_impl< base_t< ValueSet >>::type context_t_of
#define VCSN_RAT_VISIT(Type, Val)
std::shared_ptr< detail::mutable_automaton_impl< Context >> mutable_automaton
auto & as()
Extract wrapped typed automaton.
An inner node implementing a weight.
auto(const automaton &lhs, const automaton &rhs, const std::string &algo) -> automaton add_t
Build a ZPC automaton from an expression.
value_impl< detail::expression_tag > expression
typename detail::label_t_of_impl< base_t< ValueSet >>::type label_t_of