Awali
Another Weighted Automata library
grail.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_GRAIL_HH
18 # define AWALI_ALGOS_GRAIL_HH
19 
20 # include <iostream>
21 # include <map>
22 
25 #include <awali/sttc/weightset/fwd.hh> // b
27 
28 namespace awali { namespace sttc {
29 
30 
31  namespace internal
32  {
33 
34  /*------------.
35  | outputter. |
36  `------------*/
37 
41  template <typename Aut>
42  class outputter
43  {
44  protected:
45  using automaton_t = Aut;
46 
47  public:
48  outputter(const automaton_t& aut, std::ostream& out)
49  : aut_(aut)
50  , os_(out)
51  {}
52 
53  virtual ~outputter() = default;
54 
55  // Should not be public, but needed by GCC 4.8.1.
56  // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58972
57 
58  protected:
63 
65  using states_t = std::vector<state_t>;
66 
68  virtual std::string
69  label_(const label_t& l)
70  {
71  return ls_.is_one(l) ? "@epsilon" : format(ls_, l);
72  }
73 
77  {
78  aut_->print_state(aut_->src_of(t), os_);
79  os_ << ' ' << label_(aut_->label_of(t)) << ' ';
80  aut_->print_state(aut_->dst_of(t), os_);
81  }
82 
88  std::string format_entry_(state_t src, state_t dst,
89  const std::string& fmt = "text")
90  {
91  auto entry = get_entry(aut_, src, dst);
92  return ps_.format(entry, ", ", fmt);
93  }
94 
96  void output_state_(const state_t s)
97  {
98  std::vector<transition_t> ts;
99  for (auto t : aut_->out(s))
100  ts.push_back(t);
101  std::sort
102  (begin(ts), end(ts),
103  [this](transition_t l, transition_t r)
104  {
105  return (std::forward_as_tuple(aut_->label_of(l), aut_->dst_of(l))
106  < std::forward_as_tuple(aut_->label_of(r), aut_->dst_of(r)));
107  });
108  for (auto t : ts)
109  {
110  os_ << '\n';
112  }
113  }
114 
118  {
119  for (auto s: aut_->states())
120  output_state_(s);
121  }
122 
124  void list_states_(const states_t& ss)
125  {
126  for (auto s: ss)
127  {
128  os_ << ' ';
129  aut_->print_state(s, os_);
130  }
131  }
132 
135  {
136  states_t res;
137  for (auto t: aut_->initial_transitions())
138  res.emplace_back(aut_->dst_of(t));
139  std::sort(begin(res), end(res));
140  return res;
141  }
142 
145  {
146  states_t res;
147  for (auto t: aut_->final_transitions())
148  res.emplace_back(aut_->src_of(t));
149  std::sort(begin(res), end(res));
150  return res;
151  }
152 
156  std::ostream& os_;
158  const labelset_t_of<automaton_t>& ls_ = *aut_->labelset();
160  const weightset_t& ws_ = *aut_->weightset();
163  };
164 
165  }
166 
167 
168  /*---------.
169  | fadoer. |
170  `---------*/
171 
172  namespace internal
173  {
174 
178  template <typename Aut>
179  class fadoer: public outputter<Aut>
180  {
182  "requires labels_are_(letters|nullable)");
183  // FIXME: Not right: F2 is also using bool, but it is not bool.
184  static_assert(std::is_same<weightset_t_of<Aut>, b>::value,
185  "requires Boolean weights");
186 
187  using super_type = outputter<Aut>;
188 
189  using super_type::aut_;
190  using super_type::finals_;
191  using super_type::initials_;
193  using super_type::os_;
195  using super_type::ws_;
196 
197  using super_type::super_type;
198 
199  public:
201  // http://www.dcc.fc.up.pt/~rvr/FAdoDoc/_modules/fa.html#saveToFile
202  void operator()()
203  {
204  bool is_deter = is_deterministic_(aut_);
205  os_ << (is_deter ? "@DFA" : "@NFA");
206  list_states_(finals_());
207  if (!is_deter)
208  {
209  os_ << " *";
210  list_states_(initials_());
211  }
212  output_transitions_();
213  }
214 
215  private:
216  template <typename A>
217  typename std::enable_if<labelset_t_of<A>::is_free(),
218  bool>::type
219  is_deterministic_(const A& a)
220  {
221  return is_deterministic(a);
222  }
223 
224  template <typename A>
225  typename std::enable_if<!labelset_t_of<A>::is_free(),
226  bool>::type
227  is_deterministic_(const A&)
228  {
229  return false;
230  }
231  };
232 
233  }
234 
235  template <typename Aut>
236  std::ostream&
237  fado(const Aut& aut, std::ostream& out)
238  {
239  internal::fadoer<Aut> fado{aut, out};
240  fado();
241  return out;
242  }
243 
244  /*----------.
245  | grailer. |
246  `----------*/
247 
248  namespace internal
249  {
255  template <typename Aut>
256  class grailer: public outputter<Aut>
257  {
259  "requires labels_are_(letters|nullable)");
260  // FIXME: Not right: F2 is also using bool, but it is not bool.
261  static_assert(std::is_same<weightset_t_of<Aut>, b>::value,
262  "requires Boolean weights");
263 
264  using super_type = outputter<Aut>;
265 
266  using typename super_type::automaton_t;
267 
268  using super_type::aut_;
269  using super_type::finals_;
270  using super_type::initials_;
271  using super_type::os_;
273  using super_type::ws_;
274 
275  using super_type::super_type;
276 
277  public:
279  void operator()()
280  {
281  // Don't end with a \n.
282  const char* sep = "";
283  for (auto s: initials_())
284  {
285  os_ << sep
286  << "(START) |- ";
287  aut_->print_state(s, os_);
288  sep = "\n";
289  }
290  output_transitions_();
291  for (auto s: finals_())
292  {
293  os_ << '\n';
294  aut_->print_state(s, os_) << " -| (FINAL)";
295  }
296  }
297  };
298  }
299 
300  template <typename Aut>
301  std::ostream&
302  grail(const Aut& aut, std::ostream& out)
303  {
304  internal::grailer<Aut> grail{aut, out};
305  grail();
306  return out;
307  }
308 
309 }}//end of ns awali::stc
310 
311 #endif // !AWALI_ALGOS_GRAIL_HH
The Boolean semring.
Definition: b.hh:38
Format an automaton into Fado.
Definition: grail.hh:180
void operator()()
Actually output aut_ on os_.
Definition: grail.hh:202
Format an automaton into Fado.
Definition: grail.hh:257
void operator()()
Actually output aut_ on os_.
Definition: grail.hh:279
Factor common bits in automaton formatting.
Definition: grail.hh:43
void output_state_(const state_t s)
Output transitions, sorted lexicographically on (Label, Dest).
Definition: grail.hh:96
void output_transitions_()
Output transitions, sorted lexicographically.
Definition: grail.hh:117
outputter(const automaton_t &aut, std::ostream &out)
Definition: grail.hh:48
std::string format_entry_(state_t src, state_t dst, const std::string &fmt="text")
The labels and weights of transitions from src to dst.
Definition: grail.hh:88
virtual std::string label_(const label_t &l)
Convert a label to its representation.
Definition: grail.hh:69
context_t_of< automaton_t > context_t
Definition: grail.hh:59
const automaton_t & aut_
The automaton we have to output.
Definition: grail.hh:154
void list_states_(const states_t &ss)
List names of states in ss, preceded by ' '.
Definition: grail.hh:124
states_t finals_()
The list of final states, sorted.
Definition: grail.hh:144
weight_t_of< automaton_t > weight_t
Definition: grail.hh:62
virtual void output_transition_(transition_t t)
Output the transition t.
Definition: grail.hh:76
Aut automaton_t
Definition: grail.hh:45
const labelset_t_of< automaton_t > & ls_
Short-hand to the labelset.
Definition: grail.hh:158
const weightset_t & ws_
Short-hand to the weightset.
Definition: grail.hh:160
std::ostream & os_
Output stream.
Definition: grail.hh:156
std::vector< state_t > states_t
A list of states.
Definition: grail.hh:65
const polynomialset< context_t_of< automaton_t > > ps_
Short-hand to the polynomialset used to print the entries.
Definition: grail.hh:162
label_t_of< automaton_t > label_t
Definition: grail.hh:60
states_t initials_()
The list of initial states, sorted.
Definition: grail.hh:134
weightset_t_of< automaton_t > weightset_t
Definition: grail.hh:61
Linear combination of labels: map labels to weights.
Definition: polynomialset.hh:69
std::string format(const value_t &v, const std::string &sep=" + ", const std::string &fmt="text") const
Definition: polynomialset.hh:620
The semiring of floating Numbers.
Definition: r.hh:35
static constexpr TOP< void > value
Definition: priority.hh:93
bool is_deterministic(const Aut &aut, state_t s)
Whether state s is deterministic in aut.
Definition: is_deterministic.hxx:48
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
void sort(Aut a, Compare p)
Definition: sort.hh:28
typename internal::weight_t_of_impl< internal::base_t< ValueSet > >::type weight_t_of
Helper to retrieve the type of the weights of a value set.
Definition: traits.hh:81
polynomialset< context_t_of< Aut > >::value_t get_entry(const Aut &aut, state_t s, state_t d)
The entry between two states of an automaton.
Definition: polynomialset.hh:790
typename internal::context_t_of_impl< internal::base_t< ValueSet > >::type context_t_of
Helper to retrieve the type of the context of a value set.
Definition: traits.hh:66
std::ostream & grail(const Aut &aut, std::ostream &out)
Definition: grail.hh:302
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
std::ostream & fado(const Aut &aut, std::ostream &out)
Definition: grail.hh:237
auto format(const ValueSet &vs, const typename ValueSet::value_t &v, Args &&... args) -> std::string
Format v via vs.print.
Definition: stream.hh:109
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
unsigned state_t
Definition: types.hh:21
unsigned transition_t
Definition: types.hh:22