Awali
Another Weighted Automata library
copy.hh
Go to the documentation of this file.
1 // This file is part of Awali.
2 // Copyright 2016-2021 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=false)
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  out_state[s] = out_->add_state();
57 
58  for (auto t : in_->all_transitions())
59  {
60  auto src = out_state.find(in_->src_of(t));
61  auto dst = out_state.find(in_->dst_of(t));
62  if (src != out_state.end() && dst != out_state.end())
63  out_->new_transition_copy(src->second, dst->second,
64  in_, t, transpose);
65  }
66  }
67 
68  template <typename Pred>
69  void no_weight(Pred keep_state)
70  {
71  // Copy the states. We cannot iterate on the transitions
72  // only, as we would lose the states without transitions.
73  out_state[in_->pre()] = out_->pre();
74  out_state[in_->post()] = out_->post();
75  for (auto s: in_->states())
76  if (keep_state(s))
77  out_state[s] = out_->add_state();
78 
79  for (auto t : in_->all_transitions())
80  {
81  auto src = out_state.find(in_->src_of(t));
82  auto dst = out_state.find(in_->dst_of(t));
83  if (src != out_state.end() && dst != out_state.end())
84  out_->new_transition(src->second, dst->second,
85  in_->label_of(t));
86  }
87  }
88 
90  using origins_t = std::map<state_t, state_t>;
91  origins_t
92  origins() const
93  {
94  origins_t res;
95  for (const auto& p: out_state)
96  res[p.second] = p.first;
97  return res;
98  }
99 
101  static
102  std::ostream&
103  print(const origins_t& orig, std::ostream& o)
104  {
105  o << "/* Origins.\n"
106  << " node [shape = box, style = rounded]\n";
107  for (auto p : orig)
108  if (2 <= p.first)
109  o << " " << p.first - 2
110  << " [label = \"" << p.second - 2 << "\"]\n";
111  o << "*/\n";
112  return o;
113  }
114 
115  void set_history() {
116  auto history = std::make_shared<single_history<AutIn>>(in_);
117  out_->set_history(history);
118  for (auto p: in_->all_states())
119  history->add_state(out_state[p], p);
120  }
121 
122  const InOutMap& in_out_map() const {
123  return out_state;
124  }
125 
127  const AutIn& in_;
129  AutOut& out_;
131  InOutMap out_state;
132  };
133  }
134 
137  template <typename AutIn, typename AutOut, typename Pred>
138  inline
139  void
140  copy_into(const AutIn& in, AutOut& out, Pred keep_state, bool keep_history=true, bool transpose=false)
141  {
143  copy(keep_state, transpose);
144  if(keep_history)
145  copy.set_history();
146  }
147 
148  template <typename AutIn, typename AutOut>
149  inline
150  void
151  copy_into(const AutIn& in, AutOut& out, bool keep_history=true, bool transpose=false)
152  {
153  copy_into(in, out, [](state_t) { return true; }, keep_history, transpose);
154  }
155 
156  template <typename AutIn, typename AutOut, typename Pred>
157  inline
158  void
159  copy_support(const AutIn& in, AutOut& out, Pred keep_state, bool keep_history=true)
160  {
162  copy.no_weight(keep_state);
163  if(keep_history)
164  copy.set_history();
165  }
166 
167  template <typename AutIn, typename AutOut>
168  inline
169  void
170  copy_support(const AutIn& in, AutOut& out, bool keep_history=true)
171  {
173  copy.no_weight([](state_t) { return true; });
174  if(keep_history)
175  copy.set_history();
176  }
177 
180  template <typename AutIn,
181  typename AutOut = typename AutIn::element_type::automaton_nocv_t,
182  typename Pred>
183  inline
184  AutOut
185  copy(const AutIn& input, Pred keep_state, bool keep_history=true, bool transpose=false)
186  {
187  // FIXME: here, we need a means to convert the given input context
188  // (e.g. letter -> B) into the destination one (e.g., letter ->
189  // Q). The automaton constructor wants the exact context type.
190  auto res = make_mutable_automaton(input->context());
191  sttc::copy_into(input, res, keep_state, keep_history, transpose);
192  res->set_name(input->get_name());
193  res->set_desc(input->get_desc());
194  return res;
195  }
196 
198  template <typename AutIn,
199  typename AutOut = typename AutIn::element_type::automaton_nocv_t>
200  inline
201  AutOut
202  copy(const AutIn& input, bool keep_history=true, bool transpose=false)
203  {
204  return sttc::copy<AutIn, AutOut>(input,
205  [](state_t) { return true; }, keep_history, transpose);
206  }
207 
210  template <typename AutIn,
211  typename AutOut = typename AutIn::element_type::automaton_nocv_t>
212  inline
213  AutOut
214  copy(const AutIn& input, const std::set<state_t>& keep, bool keep_history=true, bool transpose=false)
215  {
216  return sttc::copy<AutIn, AutOut>
217  (input,
218  [&keep](state_t s) { return keep.find(s)!=keep.end(); }, keep_history, transpose);
219  }
220 
221 }}//end of ns awali::stc
222 
223 #endif // !AWALI_ALGOS_COPY_HH
void copy_support(const AutIn &in, AutOut &out, Pred keep_state, bool keep_history=true)
Definition: copy.hh:159
void copy_into(const AutIn &in, AutOut &out, Pred keep_state, bool keep_history=true, bool transpose=false)
Copy an automaton.
Definition: copy.hh:140
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:185
mutable_automaton< Context > make_mutable_automaton(const Context &ctx)
Definition: mutable_automaton.hh:911
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:127
static std::ostream & print(const origins_t &orig, std::ostream &o)
Print the origins.
Definition: copy.hh:103
origins_t origins() const
Definition: copy.hh:92
const InOutMap & in_out_map() const
Definition: copy.hh:122
InOutMap out_state
input state -> output state.
Definition: copy.hh:131
void no_weight(Pred keep_state)
Definition: copy.hh:69
copier(const AutIn &in, AutOut &out)
Definition: copy.hh:42
void operator()(Pred keep_state, bool transpose=false)
Definition: copy.hh:48
std::map< state_t, state_t > origins_t
A map from result state to original state.
Definition: copy.hh:90
AutOut & out_
Output automaton.
Definition: copy.hh:129
void set_history()
Definition: copy.hh:115