17 #ifndef AWALI_ALGOS_PROPER_HH 
   18 # define AWALI_ALGOS_PROPER_HH 
   21 # include <type_traits> 
   22 # include <unordered_map> 
   23 # include <unordered_set> 
   37 #include <awali/common/ato.cc> 
   41 namespace awali { 
namespace sttc {
 
   50       if (
auto cp = getenv(
"AWALI_DEBUG")) {
 
   61     template <
typename Aut,
 
   65       using automaton_t = 
typename std::remove_cv<Aut>::type;
 
   67       using weight_t = 
typename weightset_t::value_t;
 
   69       using transitions_t = std::vector<transition_t>;
 
   79         , empty_word_(aut->labelset()->one())        
 
   80         , todo_(aut->num_states())
 
   98           proper_here_<weightset_t::star_status()>(aut, prune);
 
  137             p.in_situ_remover_();
 
  140         catch (
const std::runtime_error&)
 
  154         using state_profile = std::tuple<size_t,size_t,size_t>;
 
  160         for (
auto s: aut_->states())
 
  163           if (
auto in_sp = aut_->in(s, empty_word_).size())
 
  165               auto out_sp = aut_->out(s, empty_word_).size();
 
  166               auto out = aut_->all_out(s).size();
 
  167               auto t = todo_.
emplace(s, state_profile
 
  168                                      {out_sp, out, in_sp});
 
  169               tickets_.emplace(s, t);
 
  178             std::cerr << 
"update heap (" << s << 
") ";
 
  180         auto t = tickets_.find(s);
 
  181         if (t != tickets_.end())
 
  183                        state_profile{aut_->out(s, empty_word_).size(),
 
  184                            aut_->all_out(s).size(),
 
  185                            aut_->in(s, empty_word_).size()});
 
  190       unsigned removed_ = 0;
 
  204       void in_situ_remover_(
state_t s)
 
  206         const auto& tr = aut_->in(s, empty_word_);
 
  211         weight_t 
star = ws_.one();
 
  212         using state_weight_t = std::pair<state_t, weight_t>;
 
  213         std::vector<state_weight_t> closure;
 
  216             weight_t weight = aut_->weight_of(t);
 
  219               star = ws_.star(weight);
 
  221               closure.emplace_back(src, weight);
 
  223             aut_->del_transition(t);
 
  240         for (
auto t: aut_->all_out(s))
 
  245             weight_t blow = ws_.mul(star, aut_->weight_of(t));
 
  246             aut_->set_weight(t, blow);
 
  248             label_t label = aut_->label_of(t);
 
  250             for (
auto pair: closure)
 
  253                 weight_t w = ws_.mul(
pair.second, blow);
 
  254                 aut_->add_transition(src, dst, label, w);
 
  258         unsigned added = aut_->all_out(s).size() * closure.size();
 
  261         if (prune_ && aut_->all_in(s).empty())
 
  264             removed += aut_->all_out(s).size();
 
  272           std::cerr << 
" -" << removed << 
"+" << added
 
  273                     << 
" (-" << removed_ << 
"+" << added_ << 
")";
 
  289       void in_situ_remover_()
 
  299         std::unordered_set<state_t> neighbors;
 
  300         while (!todo_.
empty())
 
  302             auto s = todo_.
pop();
 
  305             for (
auto t: aut_->in(s))
 
  309                   neighbors.emplace(n);
 
  311             for (
auto t: aut_->out(s))
 
  315                   neighbors.emplace(n);
 
  321             for (
auto n: neighbors)
 
  327       template <star_status_t Status>
 
  329       typename std::enable_if<Status == star_status_t::TOPS>::type
 
  330       proper_here_(automaton_t& aut, 
bool = 
true)
 
  333           raise(
"invalid automaton");
 
  338       template <star_status_t Status>
 
  340       typename std::enable_if<Status == star_status_t::ABSVAL>::type
 
  341       proper_here_(automaton_t& aut, 
bool prune = 
true)
 
  348       template <star_status_t Status>
 
  350       typename std::enable_if<Status == star_status_t::STARRABLE>::type
 
  351       proper_here_(automaton_t& aut, 
bool prune = 
true)
 
  360       template <star_status_t Status>
 
  362       typename std::enable_if<Status == star_status_t::NON_STARRABLE>::type
 
  363       proper_here_(automaton_t& aut, 
bool prune = 
true)
 
  375       const weightset_t& ws_;
 
  380       using heap_t=utils::min_heap<state_t,state_profile>;
 
  383       std::unordered_map<state_t, typename heap_t::claim_ticket_type> tickets_;
 
  394     template <
typename Aut>
 
  397       using automaton_t = 
typename std::remove_cv<Aut>::type;
 
  416   template <
typename Aut>
 
  425   template <
typename Aut>
 
  442   template <
typename Aut>
 
  445          bool prune = 
true, 
bool keep_history = 
true)
 
  446     -> decltype(
copy(aut))
 
  452       res = 
copy(aut,keep_history);
 
  461       raise(
"invalid direction parameter");
 
static constexpr void proper_here(automaton_t &, bool=true)
Definition: proper.hh:403
 
This class contains the core of the proper algorithm.
Definition: proper.hh:64
 
properer(automaton_t &aut, bool prune=true)
Get ready to eliminate spontaneous transitions.
Definition: proper.hh:75
 
static void proper_here(automaton_t &aut, bool prune=true)
Remove the epsilon-transitions of the input The behaviour of this method depends on the star_status o...
Definition: proper.hh:95
 
static bool in_situ_remover(automaton_t &aut, bool prune=true)
The core of the (backward) epsilon-removal.
Definition: proper.hh:132
 
direction_t
Used in some algorithms in which one may considers transitions forward or backwards.
Definition: enums.hh:35
 
@ FORWARD
Definition: enums.hh:36
 
@ BACKWARD
Definition: enums.hh:37
 
weightset_description weightset(const std::string &k)
 
std::vector< transition_t > transitions(abstract_automaton_t const *aut, bool all)
 
static int debug_level()
Debug level set in the user's environment.
Definition: proper.hh:48
 
unary< type_t::star, Label, Weight > star
Definition: fwd.hh:129
 
typename internal::label_t_of_impl< internal::base_t< ValueSet > >::type label_t_of
Helper to retrieve the type of the labels of a value set.
Definition: traits.hh:71
 
auto proper(const Aut &aut, direction_t dir=BACKWARD, bool prune=true, bool keep_history=true) -> decltype(copy(aut))
Eliminate spontaneous transitions.
Definition: proper.hh:444
 
typename internal::labelset_t_of_impl< internal::base_t< ValueSet > >::type labelset_t_of
Helper to retrieve the type of the labelset of a value set.
Definition: traits.hh:76
 
bool is_proper(const Aut &aut) ATTRIBUTE_CONST
Test whether an automaton is proper.
Definition: is_proper.hh:94
 
AutOut transpose(Aut &aut, bool keep_history=true)
Definition: transpose.hh:79
 
AutOut copy(const AutIn &input, Pred keep_state, bool keep_history=true, bool transpose=false)
A copy of input keeping only its states that are accepted by keep_state.
Definition: copy.hh:189
 
bool in_situ_remover(Aut &aut, bool prune=true)
Blindly eliminate epsilon transitions without checking for the validity of the automaton.
Definition: proper.hh:418
 
void transpose_here(Aut &aut)
Definition: transpose.hh:53
 
bool is_valid(const Aut &aut)
Tests if aut is valid.
Definition: is_valid.hh:162
 
void proper_here(Aut &aut, direction_t dir=BACKWARD, bool prune=true)
Eliminate spontaneous transitions in place.
Definition: proper.hh:427
 
void require(bool b, Args &&... args)
If b is not verified, raise an error with args as message.
Definition: raise.hh:55
 
pair_automaton< Aut > pair(const Aut &aut, bool keep_initials=false)
Definition: synchronizing_word.hh:266
 
typename internal::weightset_t_of_impl< internal::base_t< ValueSet > >::type weightset_t_of
Helper to retrieve the type of the weightset of a value set.
Definition: traits.hh:86
 
Main namespace of Awali.
Definition: ato.hh:22
 
int strict_atoi(const std::string &s)
 
unsigned state_t
Definition: types.hh:21
 
value_type pop()
Definition: heap.hh:58
 
void update(claim_ticket_type t, const priority_type &p)
Definition: heap.hh:79
 
claim_ticket_type emplace(const value_type &val, const priority_type &p)
Definition: heap.hh:46
 
void heapify()
Definition: heap.hh:72
 
size_t empty() const
Definition: heap.hh:42