25 :
public ExpSet::const_visitor
28 "zpc: requires nullable labels");
31 using automaton_t = Aut;
32 using expressionset_t = ExpSet;
38 using super_t =
typename expressionset_t::const_visitor;
41 constexpr
static const char* me() {
return "zpc"; }
45 const expressionset_t&
rs,
48 , res_(make_shared_ptr<automaton_t>(ctx))
52 zpc_visitor(
const expressionset_t& rs,
bool compact)
57 operator()(
const typename expressionset_t::value_t&
v)
60 res_->set_initial(initial_);
61 res_->set_final(final_);
63 for (
auto t:
all_in(res_, res_->post()))
64 res_->set_weight(t, ws_.mul(res_->weight_of(t), final_weight_));
66 return std::move(res_);
76 using tuple_t =
typename super_t::tuple_t;
77 virtual void visit(
const tuple_t&, std::true_type)
override
79 raise(me(),
": tuple is not supported");
84 initial_ = res_->new_state();
85 final_ = res_->new_state();
90 initial_ = res_->new_state();
91 final_ = res_->new_state();
93 res_->set_final(initial_);
98 initial_ = res_->new_state();
99 final_ = res_->new_state();
102 res_->new_transition(initial_, final_,
103 res_->labelset()->conv(*rs_.labelset(),
125 state_t initial = res_->new_state();
127 e.sub()->accept(*
this);
129 state_t
final = res_->new_state();
131 auto cst = ws_.star(res_->get_final_weight(initial_));
132 res_->unset_final(initial_);
134 res_->new_transition(initial, initial_, epsilon_, cst);
135 res_->new_transition(final_,
final, epsilon_, cst);
136 res_->new_transition(final_, initial_, epsilon_, cst);
141 res_->set_final(initial_, cst);
146 e.sub()->accept(*
this);
148 const weight_t& w = e.weight();
149 for (
auto t:
all_out(res_, initial_))
150 res_->set_weight(t, ws_.mul(w, res_->weight_of(t)));
155 e.sub()->accept(*
this);
157 final_weight_ = ws_.mul(e.weight(), final_weight_);
160 void sum_regular(
const sum_t& e)
162 state_t initial = res_->new_state();
164 weight_t cst = ws_.zero();
165 std::vector<state_t> finals_;
170 res_->new_transition(initial, initial_, epsilon_);
171 finals_.push_back(final_);
173 cst = ws_.add(cst, res_->get_final_weight(initial_));
174 res_->unset_final(initial_);
177 state_t
final = res_->new_state();
179 for (
auto s: finals_)
180 res_->new_transition(s,
final, epsilon_);
186 res_->set_final(initial_, cst);
189 void prod_regular(
const prod_t& e)
191 std::vector<state_t> state_stack;
194 for (
auto i = 0; i < e.size() - 1; ++i)
195 state_stack.push_back(res_->new_state());
197 e.head()->accept(*
this);
203 state_t initial_e = initial_;
204 state_t final_e = final_;
207 state_t initial = initial_e;
208 state_t
final = automaton_t::element_type::null_state();
210 initial = state_stack.back();
211 state_stack.pop_back();
212 res_->new_transition(initial, initial_e, epsilon_);
214 for (
auto t: e.tail())
218 final = res_->new_state();
219 res_->new_transition(final_,
final, epsilon_);
221 auto cst_e = res_->get_final_weight(initial_e);
222 auto cst_f = res_->get_final_weight(initial_);
224 res_->new_transition(initial, initial_, epsilon_, cst_e);
225 res_->unset_final(initial_e);
226 res_->new_transition(final_e,
final, epsilon_, cst_f);
227 res_->unset_final(initial_);
229 res_->set_final(initial, ws_.mul(cst_e, cst_f));
231 res_->new_transition(final_e, initial_, epsilon_);
236 if (!state_stack.empty())
238 initial = state_stack.back();
239 state_stack.pop_back();
241 res_->new_transition(initial, initial_e, epsilon_);
249 void sum_compact(
const sum_t& e)
251 e.head()->accept(*
this);
253 weight_t cst = res_->get_final_weight(initial_);
254 res_->unset_final(initial_);
256 state_t initial = initial_;
257 state_t initial_e = initial;
258 state_t final_e = final_;
260 for (
auto c: e.tail())
263 cst = ws_.add(cst, res_->get_final_weight(initial_));
264 res_->unset_final(initial_);
266 res_->new_transition(initial_e, initial_, epsilon_);
267 res_->new_transition(final_e, final_, epsilon_);
269 initial_e = initial_;
275 res_->set_final(initial_, cst);
278 void prod_compact(
const prod_t& e)
280 e.head()->accept(*
this);
282 state_t initial_e = initial_;
283 state_t final_e = final_;
286 state_t initial = initial_e;
289 for (
auto t: e.tail())
294 auto cst_e = res_->get_final_weight(initial_e);
295 auto cst_f = res_->get_final_weight(initial_);
297 res_->new_transition(initial, initial_, epsilon_, cst_e);
298 res_->unset_final(initial_e);
299 res_->new_transition(final_e,
final, epsilon_, cst_f);
300 res_->unset_final(initial_);
302 res_->set_final(initial, ws_.mul(cst_e, cst_f));
304 res_->new_transition(final_e, initial_, epsilon_);
315 const expressionset_t& rs_;
316 const weightset_t& ws_ = *rs_.weightset();
319 const label_t epsilon_ = res_->labelset()->one();
320 state_t initial_ = automaton_t::element_type::null_state();
321 state_t final_ = automaton_t::element_type::null_state();
322 weight_t final_weight_ = ws_.one();
332 template <Automaton Aut,
typename ExpSet>
336 const typename ExpSet::value_t&
r,
337 const std::string& algo =
"auto")
346 {
"auto", std::string(
"regular")},
364 template <
typename ExpSet,
typename String>
370 using expressionset_t = ExpSet;
371 const auto& e = exp->as<expressionset_t>();
374 using ctx_t = decltype(ctx);
automaton zpc(const expression &exp, const std::string &algo)
Bridge.
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.
automaton make_automaton(const Aut &aut)
Build a dyn::automaton.
auto(const automaton &lhs, const automaton &rhs, const std::string &algo) -> automaton sum_t
An inner node implementing a weight.
#define VCSN_RAT_VISIT(Type, Val)
A mapping from strings to Values.
auto all_in(const Aut &aut, state_t_of< Aut > s)
Indexes of transitions entering state s.
typename detail::context_t_of_impl< base_t< ValueSet >>::type context_t_of
Build a ZPC automaton from an expression.
typename detail::weightset_t_of_impl< base_t< ValueSet >>::type weightset_t_of
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.
Provide a variadic mul on top of a binary mul(), and one().
std::shared_ptr< detail::mutable_automaton_impl< Context >> mutable_automaton
nullableset_context_t< context< LabelSet, WeightSet > > make_nullableset_context(const context< LabelSet, WeightSet > &ctx)
The nullableset context of a context.
typename detail::state_t_of_impl< base_t< ValueSet >>::type state_t_of
typename detail::label_t_of_impl< base_t< ValueSet >>::type label_t_of
An inner node with multiple children.
std::shared_ptr< detail::expression_base > expression
typename detail::weight_t_of_impl< base_t< ValueSet >>::type weight_t_of
#define VCSN_RAT_UNSUPPORTED(Type)
auto all_out(const Aut &aut, state_t_of< Aut > s)
Indexes of transitions leaving state s.
std::shared_ptr< detail::automaton_base > automaton