Awali
Another Weighted Automata library
merge.hh
Go to the documentation of this file.
1 // This file is part of Awali.
2 // Copyright 2016-2022 Sylvain Lombardy, Victor Marsault, Jacques Sakarovitch
3 //
4 // Awali is a free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 
17 #ifndef AWALI_ALGOS_MERGE_HH
18 # define AWALI_ALGOS_MERGE_HH
19 
20 # include <algorithm> // min_element.
21 # include <unordered_map>
22 # include <unordered_set>
23 
27 
28 namespace awali {
29  namespace sttc {
30 
31 
32  namespace internal
33  {
34  // Apply a merge onto an automaton: fuse equivalent states.
35  template <typename Aut, typename StateList>
36  class merger
37  {
38  public:
39  using automaton_t = Aut;
40  using class_t = unsigned;
41  using class_to_set_t = std::vector<StateList>;
42  using set_t = StateList;
43  using state_to_class_t = std::unordered_map<state_t, class_t>;
44  using class_to_state_t = std::vector<state_t>;
45 
46  // \param class_to_set The equivalence classes.
47  // Might be modified to put the states with the
48  // smallest ID first in their class.
49  merger(class_to_set_t& class_to_set, bool keep_history)
50  : class_to_set_(class_to_set)
51  , num_classes_(class_to_set_.size())
52  , keep_history_(keep_history)
53  { }
54 
57  {
58  state_to_class_t state_to_class;
59  for (unsigned c = 0; c < num_classes_; ++c)
60  for (auto s: class_to_set_[c])
61  state_to_class[s] = c;
62 
63  automaton_t res = make_shared_ptr<automaton_t>(aut->context());
64  class_to_res_state_.resize(num_classes_);
65  for (unsigned c = 0; c < num_classes_; ++c)
66  {
67  const set_t& set = class_to_set_[c];
68  state_t s = *set.begin();
69  if(s==aut->pre())
70  class_to_res_state_[c]=res->pre();
71  else if(s == aut->post())
72  class_to_res_state_[c]=res->post();
73  else {
74  class_to_res_state_[c]=res->add_state();
75  res->set_state_name(class_to_res_state_[c],
76  aut->get_state_name(*std::min_element(begin(class_to_set_[c]),
77  end(class_to_set_[c]))));
78  }
79  }
80  for (unsigned c = 0; c < num_classes_; ++c)
81  {
82  // Copy the transitions of the first state of the class in
83  // the result.
84  state_t s = *class_to_set_[c].begin();
85  state_t src = class_to_res_state_[c];
86  for (auto t : aut->all_out(s))
87  {
88  state_t d = aut->dst_of(t);
89  state_t dst = class_to_res_state_[state_to_class[d]];
90  res->add_transition(src, dst, aut->label_of(t), aut->weight_of(t));
91  }
92  }
93  if(keep_history_) {
94  auto history = std::make_shared<partition_history<automaton_t>>(aut);
95  res->set_history(history);
96  for (unsigned c = 0; c < num_classes_; ++c){
97  std::set<state_t> from;
98  for(auto s : class_to_set_[c])
99  from.emplace(s);
100  history->add_state(class_to_res_state_[c], from);
101  }
102  }
103  return res;
104  }
105 
108  {
109  return build_result_(aut);
110  }
111 
112  private:
113  class_to_set_t& class_to_set_;
114  unsigned num_classes_;
115  class_to_state_t class_to_res_state_;
116  bool keep_history_;
117  };
118  } // internal::
119 
120  template <typename Aut, typename StateList>
121  inline
122  auto
123  merge(const Aut& a, std::vector<StateList>& classes, bool keep_history=true)
124  -> Aut
125  {
126  internal::merger<Aut, StateList> merge(classes, keep_history);
127  return merge(a);
128  }
129 
130  }
131 }//end of ns awali::stc
132 
133 #endif // !AWALI_ALGOS_MERGE_HH
The semiring of complex numbers.
Definition: c.hh:44
Definition: merge.hh:37
std::vector< StateList > class_to_set_t
Definition: merge.hh:41
std::unordered_map< state_t, class_t > state_to_class_t
Definition: merge.hh:43
automaton_t build_result_(const automaton_t &aut)
Build the resulting automaton.
Definition: merge.hh:56
Aut automaton_t
Definition: merge.hh:39
merger(class_to_set_t &class_to_set, bool keep_history)
Definition: merge.hh:49
unsigned class_t
Definition: merge.hh:40
std::vector< state_t > class_to_state_t
Definition: merge.hh:44
automaton_t operator()(const automaton_t &aut)
The minimized automaton.
Definition: merge.hh:107
StateList set_t
Definition: merge.hh:42
json_ast_t from(std::istream &i)
Builds a json_ast_t from an input stream.
auto merge(const Aut &a, std::vector< StateList > &classes, bool keep_history=true) -> Aut
Definition: merge.hh:123
Main namespace of Awali.
Definition: ato.hh:22
unsigned state_t
Definition: types.hh:21