Awali
Another Weighted Automata library
copy.hh
Go to the documentation of this file.
1 // This file is part of Awali.
2 // Copyright 2016-2023 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_COPY_HH
18 # define AWALI_ALGOS_COPY_HH
19 
20 # include <unordered_map>
21 
25 #include <awali/sttc/misc/set.hh>
27 
28 namespace awali { namespace sttc {
29 
30 
31  /*------------------.
32  | copy(automaton). |
33  `------------------*/
34 
35  namespace internal
36  {
39  template <typename AutIn, typename AutOut, typename InOutMap=std::unordered_map<state_t, state_t>>
40  struct copier
41  {
42  copier(const AutIn& in, AutOut& out)
43  : in_(in)
44  , out_(out)
45  {}
46 
47  template <typename Pred>
48  void operator()(Pred keep_state, bool transpose, bool same_index)
49  {
50  // Copy the states. We cannot iterate on the transitions
51  // only, as we would lose the states without transitions.
52  out_state[in_->pre()] = out_->pre();
53  out_state[in_->post()] = out_->post();
54  for (auto s: in_->states())
55  if (keep_state(s)) {
56  if(same_index) {
57  out_->add_state(s);
58  out_state[s] = s;
59  if(in_->has_name(s))
60  out_->set_state_name(s, in_->get_state_name(s));
61  }
62  else
63  out_state[s] = out_->add_state();
64  }
65  for (auto t : in_->all_transitions())
66  {
67  auto src = out_state.find(in_->src_of(t));
68  auto dst = out_state.find(in_->dst_of(t));
69  if (src != out_state.end() && dst != out_state.end())
70  out_->new_transition_copy(src->second, dst->second,
71  in_, t, transpose);
72  }
73  }
74 
75  template <typename Pred>
76  void no_weight(Pred keep_state, bool same_index)
77  {
78  // Copy the states. We cannot iterate on the transitions
79  // only, as we would lose the states without transitions.
80  out_state[in_->pre()] = out_->pre();
81  out_state[in_->post()] = out_->post();
82  for (auto s: in_->states())
83  if (keep_state(s)) {
84  if(same_index) {
85  out_->add_state(s);
86  out_state[s] = s;
87  if(in_->has_name(s))
88  out_->set_state_name(s, in_->get_state_name(s));
89  }
90  else
91  out_state[s] = out_->add_state();
92  }
93  for (auto t : in_->all_transitions())
94  {
95  auto src = out_state.find(in_->src_of(t));
96  auto dst = out_state.find(in_->dst_of(t));
97  if (src != out_state.end() && dst != out_state.end())
98  out_->new_transition(src->second, dst->second,
99  in_->label_of(t));
100  }
101  }
102 
104  using origins_t = std::map<state_t, state_t>;
105  origins_t
106  origins() const
107  {
108  origins_t res;
109  for (const auto& p: out_state)
110  res[p.second] = p.first;
111  return res;
112  }
113 
115  static
116  std::ostream&
117  print(const origins_t& orig, std::ostream& o)
118  {
119  o << "/* Origins.\n"
120  << " node [shape = box, style = rounded]\n";
121  for (auto p : orig)
122  if (2 <= p.first)
123  o << " " << p.first - 2
124  << " [label = \"" << p.second - 2 << "\"]\n";
125  o << "*/\n";
126  return o;
127  }
128 
129  void set_history() {
130  auto history = std::make_shared<single_history<AutIn>>(in_);
131  out_->set_history(history);
132  for (auto p: in_->all_states()) {
133  history->add_state(out_state[p], p);
134  if(in_->has_name(p)) {
135  out_->set_state_name(out_state[p], in_->get_state_name(p));
136  }
137  }
138  }
139 
140  const InOutMap& in_out_map() const {
141  return out_state;
142  }
143 
145  const AutIn& in_;
147  AutOut& out_;
149  InOutMap out_state;
150  };
151  }
152 
155  template <typename AutIn, typename AutOut, typename Pred>
156  inline
157  void
158  copy_into(const AutIn& in, AutOut& out, Pred keep_state, bool keep_history=true, bool transpose=false, bool same_index=false)
159  {
161  copy(keep_state, transpose, same_index);
162  if(keep_history)
163  copy.set_history();
164  }
165 
166  template <typename AutIn, typename AutOut>
167  inline
168  void
169  copy_into(const AutIn& in, AutOut& out, bool keep_history=true, bool transpose=false, bool same_index=false)
170  {
171  copy_into(in, out, [](state_t) { return true; }, keep_history, transpose, same_index);
172  }
173 
174  template <typename AutIn, typename AutOut, typename Pred>
175  inline
176  void
177  copy_support(const AutIn& in, AutOut& out, Pred keep_state, bool keep_history=true, bool same_index=false)
178  {
180  copy.no_weight(keep_state, same_index);
181  if(keep_history)
182  copy.set_history();
183  }
184 
185  template <typename AutIn, typename AutOut>
186  inline
187  void
188  copy_support(const AutIn& in, AutOut& out, bool keep_history=true, bool same_index=false)
189  {
191  copy.no_weight([](state_t) { return true; }, same_index);
192  if(keep_history)
193  copy.set_history();
194  }
195 
198  template <typename AutIn,
199  typename AutOut = typename AutIn::element_type::automaton_nocv_t,
200  typename Pred>
201  inline
202  AutOut
203  copy(const AutIn& input, Pred keep_state, bool keep_history=true, bool transpose=false, bool same_index=false)
204  {
205  // FIXME: here, we need a means to convert the given input context
206  // (e.g. letter -> B) into the destination one (e.g., letter ->
207  // Q). The automaton constructor wants the exact context type.
208  auto res = make_mutable_automaton(input->context());
209  sttc::copy_into(input, res, keep_state, keep_history, transpose, same_index);
210  res->set_name(input->get_name());
211  res->set_desc(input->get_desc());
212  return res;
213  }
214 
216  template <typename AutIn,
217  typename AutOut = typename AutIn::element_type::automaton_nocv_t>
218  inline
219  AutOut
220  copy(const AutIn& input, bool keep_history=true, bool transpose=false, bool same_index=false)
221  {
222  return sttc::copy<AutIn, AutOut>(input,
223  [](state_t) { return true; }, keep_history, transpose, same_index);
224  }
225 
228  template <typename AutIn,
229  typename AutOut = typename AutIn::element_type::automaton_nocv_t>
230  inline
231  AutOut
232  copy(const AutIn& input, const std::set<state_t>& keep, bool keep_history=true, bool transpose=false, bool same_index=false)
233  {
234  return sttc::copy<AutIn, AutOut>
235  (input,
236  [&keep](state_t s) { return keep.find(s)!=keep.end(); }, keep_history, transpose, same_index);
237  }
238 
239 }}//end of ns awali::stc
240 
241 #endif // !AWALI_ALGOS_COPY_HH
void copy_into(const AutIn &in, AutOut &out, Pred keep_state, bool keep_history=true, bool transpose=false, bool same_index=false)
Copy an automaton.
Definition: copy.hh:158
AutOut copy(const AutIn &input, Pred keep_state, bool keep_history=true, bool transpose=false, bool same_index=false)
A copy of input keeping only its states that are accepted by keep_state.
Definition: copy.hh:203
void copy_support(const AutIn &in, AutOut &out, Pred keep_state, bool keep_history=true, bool same_index=false)
Definition: copy.hh:177
AutOut transpose(Aut &aut, bool keep_history=true)
Definition: transpose.hh:79
mutable_automaton< Context > make_mutable_automaton(const Context &ctx)
Definition: mutable_automaton.hh:931
Main namespace of Awali.
Definition: ato.hh:22
unsigned state_t
Definition: types.hh:21
Copy an automaton.
Definition: copy.hh:41
const AutIn & in_
Input automaton.
Definition: copy.hh:145
static std::ostream & print(const origins_t &orig, std::ostream &o)
Print the origins.
Definition: copy.hh:117
origins_t origins() const
Definition: copy.hh:106
const InOutMap & in_out_map() const
Definition: copy.hh:140
InOutMap out_state
input state -> output state.
Definition: copy.hh:149
copier(const AutIn &in, AutOut &out)
Definition: copy.hh:42
std::map< state_t, state_t > origins_t
A map from result state to original state.
Definition: copy.hh:104
void no_weight(Pred keep_state, bool same_index)
Definition: copy.hh:76
AutOut & out_
Output automaton.
Definition: copy.hh:147
void operator()(Pred keep_state, bool transpose, bool same_index)
Definition: copy.hh:48
void set_history()
Definition: copy.hh:129