Vcsn  2.3
Be Rational
dot.hh
Go to the documentation of this file.
1 #pragma once
2 
3 #include <iostream>
4 #include <memory>
5 
6 #include <vcsn/algos/project.hh> // bad layering: should not be in algos.
8 #include <vcsn/misc/algorithm.hh> // transform
9 #include <vcsn/misc/format.hh>
10 #include <vcsn/misc/indent.hh>
11 
12 namespace vcsn
13 {
14  namespace rat
15  {
17  template <typename ExpSet>
19  : public ExpSet::const_visitor
20  {
21  public:
22  using expressionset_t = ExpSet;
23  using super_t = typename expressionset_t::const_visitor;
25 
27  using identities_t = typename expressionset_t::identities_t;
31 
33  using node_t = typename super_t::node_t;
35  using value_t = typename node_t::value_t;
36  template <type_t Type>
37  using constant_t = typename super_t::template constant_t<Type>;
38  template <type_t Type>
39  using unary_t = typename super_t::template unary_t<Type>;
40  template <type_t Type>
41  using variadic_t = typename super_t::template variadic_t<Type>;
42 
44  constexpr static const char* me() { return "dot_printer"; }
45 
52  dot_printer(const expressionset_t& rs, std::ostream& out,
53  bool physical = false)
54  : out_{out}
55  , rs_{rs}
56  , physical_{physical}
57  {
58  format(vcsn::format("utf8"));
59  }
60 
65  template <typename OtherExpSet>
68  : out_{other.out_}
69  , rs_{rs}
70  , physical_{other.physical_}
71  , names_{other.names_}
72  , count_{other.count_}
73  {
74  format(other.fmt_);
75  }
76 
79  template <typename OtherExpSet>
80  friend class dot_printer;
81 
83  void format(format fmt)
84  {
85  fmt_ = fmt;
86  if (fmt_ == format::latex)
87  {
88  add_ = (rs_.identities().is_distributive() ? " \\oplus "
89  : " + ");
90  complement_ = "^{c}";
91  compose_ = "@";
92  conjunction_ = " \\& ";
93  infiltrate_ = " \\uparrow ";
94  ldivide_ = " \\backslash ";
95  lweight_ = "\\,";
96  one_ = "\\varepsilon";
97  mul_ = " \\, ";
98  rweight_ = "\\,";
99  shuffle_ = " \\between ";
100  star_ = "^{*}";
101  transposition_ = "^{T}";
102  tuple_ = " \\mid ";
103  zero_ = "\\emptyset";
104  }
105  else if (fmt_ == format::text)
106  {
107  add_ = "+";
108  complement_ = "{c}";
109  compose_ = "@";
110  conjunction_ = "&";
111  infiltrate_ = "&:";
112  ldivide_ = "{\\}";
113  lweight_ = "<.>.";
114  one_ = "\\e";
115  mul_ = ".";
116  rweight_ = ".<.>";
117  shuffle_ = ":";
118  star_ = "*";
119  transposition_ = "{T}";
120  tuple_ = "|";
121  zero_ = "\\z";
122  }
123  else if (fmt_ == format::utf8)
124  {
125  add_ = "+";
126  complement_ = "ᶜ";
127  compose_ = "@";
128  conjunction_ = "&";
129  infiltrate_ = "&:";
130  ldivide_ = "{\\}";
131  lweight_ = "⟨.⟩.";
132  one_ = "ε";
133  mul_ = ".";
134  rweight_ = ".⟨.⟩";
135  shuffle_ = ":";
136  star_ = "*";
137  transposition_ = "ᵗ";
138  tuple_ = "|";
139  zero_ = "∅";
140  }
141  else
142  raise("expression: invalid format: ", fmt_);
143  }
144 
146  std::ostream& operator()(const value_t& v)
147  {
148  out_ << "digraph" << vcsn::iendl
149  << "{" << vcsn::incendl
150  << "edge [arrowhead = vee, arrowsize = .6]" << vcsn::iendl
151  << "node [shape = circle, style = rounded, width = 0.5]\n";
152  print_(v);
154  << "}";
155  return out_;
156  }
157 
158  private:
160  using name_t = unsigned;
161 
164  {
165  return print_(*v);
166  }
167 
170  {
171  v.accept(*this);
172  return last_name_;
173  }
174 
190 
191  using tuple_t = typename super_t::tuple_t;
192 
193  template <bool = context_t::is_lat,
194  typename Dummy = void>
195  struct visit_tuple
196  {
198  template <size_t I>
199  void print_(const tuple_t& v)
200  {
201  auto rs = detail::project<I>(self_.rs_);
202  const auto& r = std::get<I>(v.sub());
204  auto name = printer.print_(r);
206  << name_ << " -> " << name;
207  }
208 
210  template <size_t... I>
212  {
213  using swallow = int[];
214  (void) swallow
215  {
216  (print_<I>(v),
217  0)...
218  };
219  }
220 
222  void operator()(const tuple_t& v)
223  {
224  auto name = self_.name_(v);
225  if (name.second)
226  {
227  name_ = name.first;
229  << name_
230  << " [label=\"" << self_.tuple_ << "\"]";
231  print_(v, labelset_t::indices);
232  }
233  self_.last_name_ = name.first;
234  }
238  };
239 
240  template <typename Dummy>
241  struct visit_tuple<false, Dummy>
242  {
243  void operator()(const tuple_t&)
244  {
246  }
247  const self_t& self_;
248  };
249 
250  void visit(const tuple_t& v, std::true_type) override
251  {
252  visit_tuple<>{*this}(v);
253  }
254 
257  template <typename Node>
258  std::pair<name_t, bool> name_(const Node& n)
259  {
260  if (physical_)
261  {
262  auto p = names_->emplace(&n, 0);
263  if (p.second)
264  p.first->second = names_->size();
265  return {p.first->second, p.second};
266  }
267  else
268  return {(*count_)++, true};
269  }
270 
272  template <rat::exp::type_t Type>
273  void print_(const constant_t<Type>& n, const char* op)
274  {
275  auto name = name_(n);
276  if (name.second)
277  {
278  out_ << name.first
279  << " [label=\"" << op << "\"]";
280  }
281  last_name_ = name.first;
282  }
283 
285  template <rat::exp::type_t Type>
286  void print_(const unary_t<Type>& n, const char* op)
287  {
288  auto name = name_(n);
289  if (name.second)
290  {
291  auto sub = print_(n.sub());
292  out_ << vcsn::iendl
293  << name.first << " [label=\"" << op << "\"]"
294  << vcsn::iendl
295  << name.first << " -> " << sub;
296  }
297  last_name_ = name.first;
298  }
299 
301  template <rat::exp::type_t Type>
302  void print_(const variadic_t<Type>& n, const char* op)
303  {
304  auto name = name_(n);
305  if (name.second)
306  {
307  auto subs
309  [this](const auto& i)
310  {
311  return this->print_(i);
312  }) ;
313  out_<< vcsn::iendl
314  << name.first << " [label=\"" << op << "\"]";
315  for (auto s: subs)
316  out_ << vcsn::iendl
317  << name.first << " -> " << s;
318  }
319  last_name_ = name.first;
320  }
321 
324  {
325  auto res = name_(w).first;
326  out_ << vcsn::iendl
327  << res << " [label=\"";
328  rs_.weightset()->print(w, out_, fmt_.for_weights());
329  out_ << "\"]";
330  return res;
331  }
332 
334  void print_(const lweight_t& n)
335  {
336  auto name = name_(n);
337  if (name.second)
338  {
339  auto weight = print_(n.weight());
340  auto sub = print_(n.sub());
341  out_ << vcsn::iendl
342  << name.first << " [label=\"" << lweight_ << "\"]" << vcsn::iendl
343  << name.first << " -> " << weight << vcsn::iendl
344  << name.first << " -> " << sub;
345  }
346  last_name_ = name.first;
347  }
348 
350  void print_(const rweight_t& n)
351  {
352  auto name = name_(n);
353  if (name.second)
354  {
355  auto sub = print_(n.sub());
356  auto weight = print_(n.weight());
357  out_ << vcsn::iendl
358  << name.first << " [label=\"" << rweight_ << "\"]" << vcsn::iendl
359  << name.first << " -> " << sub << vcsn::iendl
360  << name.first << " -> " << weight;
361  }
362  last_name_ = name.first;
363  }
364 
366  void print_(const atom_t& n)
367  {
368  auto name = name_(n);
369  if (name.second)
370  {
371  out_ << vcsn::iendl;
372  out_ << name.first << " [label=\"";
373  rs_.labelset()->print(n.value(), out_, fmt_.for_labels());
374  out_ << "\"]";
375  }
376  last_name_ = name.first;
377  }
378 
380  std::ostream& out_;
382  class format fmt_;
385 
388  bool physical_ = false;
389 
391  using names_t = std::unordered_map<const void*, name_t>;
393  std::shared_ptr<names_t> names_ = std::make_shared<names_t>();
394 
397  std::shared_ptr<unsigned> count_ = std::make_shared<unsigned>(0);
400 
402  const char* lweight_ = nullptr;
403  const char* rweight_ = nullptr;
405  const char* ldivide_ = nullptr;
407  const char* add_ = nullptr;
408  const char* complement_ = nullptr;
409  const char* compose_ = nullptr;
410  const char* conjunction_ = nullptr;
411  const char* infiltrate_ = nullptr;
412  const char* mul_ = nullptr;
413  const char* shuffle_ = nullptr;
414  const char* star_ = nullptr;
415  const char* transposition_ = nullptr;
416 
418  const char* tuple_ = nullptr;
419 
421  const char* zero_ = nullptr;
422  const char* one_ = nullptr;
423  };
424 
425  template <typename ExpSet>
427  make_dot_printer(const ExpSet& rs, std::ostream& out,
428  bool physical = false)
429  {
430  return {rs, out, physical};
431  }
432  } // namespace rat
433 } // namespace vcsn
return v
Definition: multiply.hh:361
dot_printer(const expressionset_t &rs, dot_printer< OtherExpSet > &other)
Construct from another dot_printer.
Definition: dot.hh:66
VCSN_RAT_VISIT(one, v)
Definition: dot.hh:184
context_t_of< expressionset_t > context_t
Definition: dot.hh:26
value_impl< detail::weight_tag > weight
Definition: fwd.hh:28
void print_(const unary_t< Type > &n, const char *op)
Print a unary node.
Definition: dot.hh:286
dot_printer< ExpSet > make_dot_printer(const ExpSet &rs, std::ostream &out, bool physical=false)
Definition: dot.hh:427
typename detail::weight_t_of_impl< base_t< ValueSet >>::type weight_t_of
Definition: traits.hh:66
name_t print_(const value_t &v)
Easy recursion: print an expression and return its ID.
Definition: dot.hh:163
format for_labels() const
A copy of this format, but to print labels.
Definition: format.hh:42
#define BUILTIN_UNREACHABLE()
Definition: builtins.hh:13
VCSN_RAT_VISIT(star, v)
Definition: dot.hh:187
name_t name_
The name of the tuple node.
Definition: dot.hh:237
void visit(const tuple_t &v, std::true_type) override
Definition: dot.hh:250
std::ostream & incendl(std::ostream &o)
Increment the indentation, print an end of line, and set the indentation.
Definition: indent.cc:54
std::unordered_map< const void *, name_t > names_t
If physical_ is enabled, register the identifiers of the nodes.
Definition: dot.hh:391
const char * star_
Definition: dot.hh:414
const expressionset_t & rs_
The expressionset.
Definition: dot.hh:384
VCSN_RAT_VISIT(mul, v)
Definition: dot.hh:183
void print_(const atom_t &n)
Print a label.
Definition: dot.hh:366
ExpSet expressionset_t
Definition: dot.hh:22
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
Definition: traits.hh:63
name_t last_name_
The name of the last visited node.
Definition: dot.hh:399
class format fmt_
Output format.
Definition: dot.hh:382
typename detail::context_t_of_impl< base_t< ValueSet >>::type context_t_of
Definition: traits.hh:61
std::ostream & iendl(std::ostream &o)
Print an end of line, then set the indentation.
Definition: indent.cc:49
static constexpr const char * me()
Name of this algorithm, for error messages.
Definition: dot.hh:44
void print_(const variadic_t< Type > &n, const char *op)
Print a variadic node.
Definition: dot.hh:302
typename super_t::template variadic_t< Type > variadic_t
Definition: dot.hh:41
const char * infiltrate_
Definition: dot.hh:411
void print_(const tuple_t &v, detail::index_sequence< I... >)
Print all the tapes.
Definition: dot.hh:211
std::ostream & decendl(std::ostream &o)
Decrement the indentation, print an end of line, and set the indentation.
Definition: indent.cc:59
auto out(const Aut &aut, state_t_of< Aut > s)
Indexes of visible transitions leaving state s.
Definition: automaton.hh:64
An inner node implementing a weight.
Definition: expression.hh:264
VCSN_RAT_VISIT(infiltrate, v)
Definition: dot.hh:180
labelset_t_of< context_t > labelset_t
Definition: dot.hh:28
typename expressionset_t::identities_t identities_t
Definition: dot.hh:27
return res
Definition: multiply.hh:398
typename expressionset_t::const_visitor super_t
Definition: dot.hh:23
VCSN_RAT_VISIT(ldivide, v)
Definition: dot.hh:181
const char * conjunction_
Definition: dot.hh:410
const char * add_
The expression operators.
Definition: dot.hh:407
void print_(const lweight_t &n)
Print a left-weight.
Definition: dot.hh:334
const char * tuple_
Tuple tape separator.
Definition: dot.hh:418
const char * one_
Definition: dot.hh:422
bool physical_
Whether to display the physical DAG rather than the logical tree.
Definition: dot.hh:388
friend class dot_printer
Make it possible to view members from dot_printer's with a different template parameter.
Definition: dot.hh:80
const char * shuffle_
Definition: dot.hh:413
auto rs
Definition: lift.hh:152
typename super_t::template unary_t< Type > unary_t
Definition: dot.hh:39
VCSN_RAT_VISIT(shuffle, v)
Definition: dot.hh:186
std::ostream & out_
Output stream.
Definition: dot.hh:380
VCSN_RAT_VISIT(transposition, v)
Definition: dot.hh:188
Definition: a-star.hh:8
const char * transposition_
Definition: dot.hh:415
typename detail::label_t_of_impl< base_t< ValueSet >>::type label_t_of
Definition: traits.hh:62
typename super_t::template constant_t< Type > constant_t
Definition: dot.hh:37
const char * compose_
Definition: dot.hh:409
An input/output format for valuesets.
Definition: format.hh:13
VCSN_RAT_VISIT(add, v)
Definition: dot.hh:175
unsigned name_t
A type to label the node.
Definition: dot.hh:160
VCSN_RAT_VISIT(compose, v)
Definition: dot.hh:178
void print_(const constant_t< Type > &n, const char *op)
Print a nullary node.
Definition: dot.hh:273
Indentation relative functions.
VCSN_RAT_VISIT(zero, v)
Definition: dot.hh:189
VCSN_RAT_VISIT(complement, v)
Definition: dot.hh:177
typename super_t::tuple_t tuple_t
Definition: dot.hh:191
const char * rweight_
Definition: dot.hh:403
name_t print_(const node_t &v)
Easy recursion: print an expression and return its ID.
Definition: dot.hh:169
weight_t_of< context_t > weight_t
Definition: dot.hh:30
typename node_t::value_t value_t
A shared_ptr to node_t.
Definition: dot.hh:35
Pretty-printer for rational expressions.
Definition: fwd.hh:28
Pretty-printer for rational expressions.
Definition: dot.hh:18
const char * lweight_
External product.
Definition: dot.hh:402
const char * ldivide_
Quotient.
Definition: dot.hh:405
Print as rich UTF-8 text, escaped.
Definition: format.hh:30
VCSN_RAT_VISIT(rweight, v)
Definition: dot.hh:185
std::ostream & operator()(const value_t &v)
Entry point: print v as a complete Dot graph.
Definition: dot.hh:146
dot_printer(const expressionset_t &rs, std::ostream &out, bool physical=false)
A printer.
Definition: dot.hh:52
const char * complement_
Definition: dot.hh:408
VCSN_RAT_VISIT(conjunction, v)
Definition: dot.hh:179
const char * mul_
Definition: dot.hh:412
void print_(const tuple_t &v)
Print one tape.
Definition: dot.hh:199
std::pair< name_t, bool > name_(const Node &n)
The identifier for this node, and a Boolean stating whether we should traverse (again) this node...
Definition: dot.hh:258
VCSN_RAT_VISIT(atom, v)
Definition: dot.hh:176
An inner node with multiple children.
Definition: expression.hh:118
name_t print_(const weight_t &w)
Print a weight.
Definition: dot.hh:323
Print for LaTeX.
Definition: format.hh:22
const char * zero_
The constants.
Definition: dot.hh:421
auto transform(const Container &c, Fun &&fun)
Map a unary function on a container of values, and return the vector the results. ...
Definition: algorithm.hh:157
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:46
Print as plain (ASCII) text, escaped.
Definition: format.hh:28
VCSN_RAT_VISIT(lweight, v)
Definition: dot.hh:182
std::shared_ptr< names_t > names_
A shared_ptr, to support tuples.
Definition: dot.hh:393
std::shared_ptr< unsigned > count_
The node counter, used to name the nodes.
Definition: dot.hh:397
void operator()(const tuple_t &v)
Entry point.
Definition: dot.hh:222
void format(format fmt)
Set output format.
Definition: dot.hh:83
typename super_t::node_t node_t
Actual node, without indirection.
Definition: dot.hh:33
void print_(const rweight_t &n)
Print a right-weight.
Definition: dot.hh:350
format for_weights() const
A copy of this format, but to print weights.
Definition: format.hh:50
label_t_of< context_t > label_t
Definition: dot.hh:29