Awali
Another Weighted Automata library
printer.hxx
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_CORE_RAT_PRINTER_HXX
18 # define AWALI_CORE_RAT_PRINTER_HXX
19 
21 #include <awali/sttc/misc/indent.hh>
22 #include <awali/sttc/misc/raise.hh>
23 
24 namespace awali { namespace sttc
25 {
26  namespace rat
27  {
28 
29  inline
30  std::ostream&
31  operator<<(std::ostream& o, type_t t)
32  {
33  switch (t)
34  {
35 # define CASE(T) case type_t::T: o << #T; break
36  CASE(zero);
37  CASE(one);
38  CASE(atom);
39  CASE(sum);
40  CASE(prod);
41  CASE(ldiv);
43  CASE(shuffle);
44  CASE(star);
45  CASE(maybe);
46  CASE(plus);
48  CASE(lweight);
49  CASE(rweight);
51 # undef CASE
52  }
53  return o;
54  }
55 
56  template <typename RatExpSet>
57  inline
59  std::ostream& out,
60  const bool debug)
61  : out_(out)
62  , ctx_(rs.context())
63  , identities_(rs.identities())
64  , debug_(debug)
65  {}
66 
67 
68 # define DEFINE \
69  template <typename RatExpSet> \
70  inline \
71  auto \
72  printer<RatExpSet>
73 
74  DEFINE::operator()(const node_t& v)
75  -> std::ostream&
76  {
77  static bool print = !! getenv("AWALI_PRINT");
78  static bool debug = !! getenv("AWALI_DEBUG");
79  if (print)
80  out_ << '<' << v.type() << '>' << sttc::incendl;
81  if (debug && format_ == "latex" && identities_ == identities_t::series)
82  out_ << "{\\color{red}{";
83  else if (debug && format_ == "latex" && identities_ == identities_t::trivial)
84  out_ << "{\\color{blue}{";
85  v.accept(*this);
86  if (debug && format_ == "latex" && identities_ == identities_t::series)
87  out_ << "}}";
88  else if (debug && format_ == "latex" && identities_ == identities_t::trivial)
89  out_ << "}}";
90  if (print)
91  out_ << sttc::decendl << "</" << v.type() << '>';
92  return out_;
93  }
94 
95  DEFINE::format(const std::string& format)
96  -> void
97  {
98  format_ = format;
99  if (format_ == "latex")
100  {
101  lgroup_ = "{";
102  rgroup_ = "}";
103  langle_ = " \\langle ";
104  rangle_ = " \\rangle ";
105  lparen_ = "\\left(";
106  rparen_ = "\\right)";
107  star_ = "^{*}";
108  maybe_ = "^{?}";
109  plus_ = "^{+}";
110  complement_ = "^{c}";
111  transposition_ = "^{T}";
112  conjunction_ = " \\& ";
113  shuffle_ = " \\between ";
114  product_ = " \\, ";
115  sum_
116  = (identities_ == identities_t::series) ? " \\oplus " : " + ";
117  zero_ = "\\emptyset";
118  one_ = "\\varepsilon";
119  lmul_ = "\\,";
120  rmul_ = "\\,";
121  ldiv_ = " \\backslash ";
122  }
123  else if (format_ == "text")
124  {
125  lgroup_ = "";
126  rgroup_ = "";
127  langle_ = "<";
128  rangle_ = ">";
129  lparen_ = "(";
130  rparen_ = ")";
131  star_ = "*";
132  maybe_ = "?";
133  plus_ = "{+}";
134  complement_ = "{c}";
135  transposition_ = "{T}";
136  conjunction_ = "&";
137  shuffle_ = ":";
138  product_ = "";
139  sum_ = "+";
140  zero_ = "\\z";
141  one_ = "\\e";
142  lmul_ = "";
143  rmul_ = "";
144  ldiv_ = "{\\}";
145  }
146  else
147  raise("invalid output format for ratexp: ", str_escape(format));
148  }
149 
150  DEFINE::precedence(const node_t& v) const
151  -> precedence_t
152  {
153  const atom_t* atom = dynamic_cast<const atom_t*>(&v);
154  if (atom && ! ctx_.labelset()->is_letter(atom->value()))
155  return precedence_t::word;
156  else
157  switch (v.type())
158  {
159 # define CASE(Type) \
160  case exp::type_t::Type: \
161  return precedence_t::Type;
162  CASE(atom);
163  CASE(complement);
164  CASE(conjunction);
165  CASE(ldiv);
166  CASE(lweight);
167  CASE(one);
168  CASE(prod);
169  CASE(rweight);
170  CASE(shuffle);
171  CASE(star);
172  CASE(maybe);
173  CASE(plus);
174  CASE(sum);
176  CASE(zero);
177 # undef CASE
178  }
179  abort(); // Unreachable.
180  }
181 
182 # define VISIT(Type) \
183  DEFINE::visit(const Type ## _t& v) \
184  -> void
185 
186  VISIT(lweight)
187  {
188  out_ << langle_;
189  ctx_.weightset()->print(v.weight(), out_, format_);
190  out_ << rangle_ << lmul_;
191  print_child(*v.sub(), v);
192  }
193 
194  VISIT(rweight)
195  {
196  print_child(*v.sub(), v);
197  out_ << rmul_ << langle_;
198  ctx_.weightset()->print(v.weight(), out_, format_);
199  out_ << rangle_;
200  }
201 
202  VISIT(zero)
203  {
204  (void) v;
205  out_ << zero_;
206  }
207 
208  VISIT(one)
209  {
210  (void) v;
211  out_ << one_;
212  }
213 
214  VISIT(atom)
215  {
216  ctx_.labelset()->print(v.value(), out_, format_);
217  }
218 
219  DEFINE::print_child(const node_t& child, const node_t& parent)
220  -> void
221  {
222  static bool force = !! getenv("AWALI_PARENS");
223  bool parent_has_precedence = precedence(child) <= precedence(parent);
224  bool needs_parens =
225  (force
226  || (parent_has_precedence
227  && ! (parent.is_unary() && child.is_unary())));
228  if (needs_parens)
229  out_ << lparen_;
230  else if (parent.is_unary())
231  out_ << lgroup_;
232  operator()(child);
233  if (needs_parens)
234  out_ << rparen_;
235  else if (parent.is_unary())
236  out_ << rgroup_;
237  }
238 
239  template <typename RatExpSet>
240  template <type_t Type>
241  inline
242  auto
243  printer<RatExpSet>::print(const unary_t<Type>& v, const char* op)
244  -> void
245  {
246  print_child(*v.sub(), v);
247  out_ << op;
248  }
249 
250  template <typename RatExpSet>
251  template <type_t Type>
252  inline
253  auto
255  -> void
256  {
257  bool first = true;
258  for (auto i: n)
259  {
260  if (! first)
261  out_ << op;
262  print_child(*i, n);
263  first = false;
264  }
265  }
266 
267 # undef VISIT
268 # undef DEFINE
269 
270  } // namespace rat
271 }}//end of ns awali::stc
272 
273 #endif // !AWALI_CORE_RAT_PRINTER_HXX
carries the algebraic settings of automata
Definition: context.hh:40
The semiring of Natural numbers.
Definition: n.hh:34
Definition: ratexp.hh:280
const label_t & value() const
Definition: ratexp.hxx:53
Definition: ratexp.hh:262
Definition: printer.hh:36
typename super_type::node_t node_t
Definition: printer.hh:43
RatExpSet ratexpset_t
Definition: printer.hh:38
typename super_type::template unary_t< Type > unary_t
Definition: printer.hh:46
printer(const ratexpset_t &rs, std::ostream &out, const bool debug=!!getenv("AWALI_PARENS"))
Definition: printer.hxx:58
typename super_type::template variadic_t< Type > variadic_t
Definition: printer.hh:48
Definition: ratexp.hh:176
An inner node with multiple children.
Definition: ratexp.hh:115
An inner node implementing a weight.
Definition: ratexp.hh:208
weight_node< type_t::lweight, Label, Weight > lweight
Definition: fwd.hh:174
constant< type_t::zero, Label, Weight > zero
Definition: fwd.hh:117
type_t
The possible types of ratexps.
Definition: fwd.hh:48
weight_node< type_t::rweight, Label, Weight > rweight
Definition: fwd.hh:177
std::ostream & operator<<(std::ostream &o, type_t t)
Definition: printer.hxx:31
constant< type_t::one, Label, Weight > one
Definition: fwd.hh:120
identities
A ratexpset can implement several different sets of identities on expressions.
Definition: identities.hh:32
std::ostream & str_escape(std::ostream &os, const int c)
Definition: escape.hh:30
auto format(const ValueSet &vs, const typename ValueSet::value_t &v, Args &&... args) -> std::string
Format v via vs.print.
Definition: stream.hh:109
std::ostream & print(const RatExpSet &rs, const typename RatExpSet::ratexp_t &e, std::ostream &o, bool with_dot=false)
Definition: print_exp.hh:227
Main namespace of Awali.
Definition: ato.hh:22
#define CASE(T)
#define VISIT(Type)
Definition: printer.hxx:182