Vcsn  2.4
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 <typename = void>
194  struct visit_tuple
195  {
197  template <size_t I>
198  void print_(const tuple_t& v)
199  {
200  auto rs = detail::project<I>(self_.rs_);
201  const auto& r = std::get<I>(v.sub());
203  auto name = printer.print_(r);
205  << name_ << " -> " << name;
206  }
207 
209  template <size_t... I>
211  {
212  using swallow = int[];
213  (void) swallow
214  {
215  (print_<I>(v),
216  0)...
217  };
218  }
219 
221  void operator()(const tuple_t& v)
222  {
223  auto name = self_.name_(v);
224  if (name.second)
225  {
226  name_ = name.first;
228  << name_
229  << " [label=\"" << self_.tuple_ << "\"]";
230  print_(v, labelset_t::indices);
231  }
232  self_.last_name_ = name.first;
233  }
236  name_t name_ = {};
237  };
238 
239  void visit(const tuple_t& v, std::true_type) override
240  {
241  detail::static_if<context_t::is_lat>
242  ([this](auto&& v){ visit_tuple<decltype(v)>{*this}(v); })
243  (v);
244  }
245 
248  template <typename Node>
249  std::pair<name_t, bool> name_(const Node& n)
250  {
251  if (physical_)
252  {
253  auto p = names_->emplace(&n, 0);
254  if (p.second)
255  p.first->second = names_->size();
256  return {p.first->second, p.second};
257  }
258  else
259  return {(*count_)++, true};
260  }
261 
263  template <rat::exp::type_t Type>
264  void print_(const constant_t<Type>& n, const char* op)
265  {
266  auto name = name_(n);
267  if (name.second)
268  {
269  out_ << vcsn::iendl;
270  out_ << name.first
271  << " [label=\"" << op << "\"]";
272  }
273  last_name_ = name.first;
274  }
275 
277  template <rat::exp::type_t Type>
278  void print_(const unary_t<Type>& n, const char* op)
279  {
280  auto name = name_(n);
281  if (name.second)
282  {
283  auto sub = print_(n.sub());
284  out_ << vcsn::iendl
285  << name.first << " [label=\"" << op << "\"]"
286  << vcsn::iendl
287  << name.first << " -> " << sub;
288  }
289  last_name_ = name.first;
290  }
291 
293  template <rat::exp::type_t Type>
294  void print_(const variadic_t<Type>& n, const char* op)
295  {
296  auto name = name_(n);
297  if (name.second)
298  {
299  auto subs
301  [this](const auto& i)
302  {
303  return this->print_(i);
304  }) ;
305  out_<< vcsn::iendl
306  << name.first << " [label=\"" << op << "\"]";
307  for (auto s: subs)
308  out_ << vcsn::iendl
309  << name.first << " -> " << s;
310  }
311  last_name_ = name.first;
312  }
313 
316  {
317  auto res = name_(w).first;
318  out_ << vcsn::iendl
319  << res << " [label=\"";
320  rs_.weightset()->print(w, out_, fmt_.for_weights());
321  out_ << "\"]";
322  return res;
323  }
324 
326  void print_(const lweight_t& n)
327  {
328  auto name = name_(n);
329  if (name.second)
330  {
331  auto weight = print_(n.weight());
332  auto sub = print_(n.sub());
333  out_
334  << vcsn::iendl
335  << name.first << " [label=\"" << lweight_ << "\"]" << vcsn::iendl
336  << name.first << " -> " << weight << vcsn::iendl
337  << name.first << " -> " << sub;
338  }
339  last_name_ = name.first;
340  }
341 
343  void print_(const rweight_t& n)
344  {
345  auto name = name_(n);
346  if (name.second)
347  {
348  auto sub = print_(n.sub());
349  auto weight = print_(n.weight());
350  out_
351  << vcsn::iendl
352  << name.first << " [label=\"" << rweight_ << "\"]" << vcsn::iendl
353  << name.first << " -> " << sub << vcsn::iendl
354  << name.first << " -> " << weight;
355  }
356  last_name_ = name.first;
357  }
358 
360  void print_(const atom_t& n)
361  {
362  auto name = name_(n);
363  if (name.second)
364  {
365  out_ << vcsn::iendl
366  << name.first << " [label=\"";
367  rs_.labelset()->print(n.value(), out_, fmt_.for_labels());
368  out_ << "\"]";
369  }
370  last_name_ = name.first;
371  }
372 
374  std::ostream& out_;
376  class format fmt_;
379 
382  bool physical_ = false;
383 
385  using names_t = std::unordered_map<const void*, name_t>;
387  std::shared_ptr<names_t> names_ = std::make_shared<names_t>();
388 
391  std::shared_ptr<unsigned> count_ = std::make_shared<unsigned>(0);
394 
396  const char* lweight_ = nullptr;
397  const char* rweight_ = nullptr;
399  const char* ldivide_ = nullptr;
401  const char* add_ = nullptr;
402  const char* complement_ = nullptr;
403  const char* compose_ = nullptr;
404  const char* conjunction_ = nullptr;
405  const char* infiltrate_ = nullptr;
406  const char* mul_ = nullptr;
407  const char* shuffle_ = nullptr;
408  const char* star_ = nullptr;
409  const char* transposition_ = nullptr;
410 
412  const char* tuple_ = nullptr;
413 
415  const char* zero_ = nullptr;
416  const char* one_ = nullptr;
417  };
418 
419  template <typename ExpSet>
421  make_dot_printer(const ExpSet& rs, std::ostream& out,
422  bool physical = false)
423  {
424  return {rs, out, physical};
425  }
426  } // namespace rat
427 } // namespace vcsn
typename super_t::node_t node_t
Actual node, without indirection.
Definition: dot.hh:33
class format fmt_
Output format.
Definition: dot.hh:376
static constexpr const char * me()
Name of this algorithm, for error messages.
Definition: dot.hh:44
dot_printer(const expressionset_t &rs, dot_printer< OtherExpSet > &other)
Construct from another dot_printer.
Definition: dot.hh:66
context_t_of< expressionset_t > context_t
Definition: dot.hh:26
void print_(const unary_t< Type > &n, const char *op)
Print a unary node.
Definition: dot.hh:278
VCSN_RAT_VISIT(atom, v)
Definition: dot.hh:176
name_t print_(const value_t &v)
Easy recursion: print an expression and return its ID.
Definition: dot.hh:163
auto rs
Definition: lift.hh:152
return res
Definition: multiply.hh:398
format for_labels() const
A copy of this format, but to print labels.
Definition: format.hh:42
const char * zero_
The constants.
Definition: dot.hh:415
Print for LaTeX.
Definition: format.hh:22
VCSN_RAT_VISIT(lweight, v)
Definition: dot.hh:182
value_impl< detail::weight_tag > weight
Definition: fwd.hh:28
std::shared_ptr< unsigned > count_
The node counter, used to name the nodes.
Definition: dot.hh:391
const expressionset_t & rs_
The expressionset.
Definition: dot.hh:378
std::ostream & decendl(std::ostream &o)
Decrement the indentation, print an end of line, and set the indentation.
Definition: indent.cc:59
An inner node implementing a weight.
Definition: expression.hh:255
void print_(const atom_t &n)
Print a label.
Definition: dot.hh:360
Pretty-printer for rational expressions.
Definition: fwd.hh:28
void operator()(const tuple_t &v)
Entry point.
Definition: dot.hh:221
VCSN_RAT_VISIT(ldivide, v)
Definition: dot.hh:181
const char * star_
Definition: dot.hh:408
An input/output format for valuesets.
Definition: format.hh:13
name_t last_name_
The name of the last visited node.
Definition: dot.hh:393
Provide a variadic mul on top of a binary mul(), and one().
Definition: fwd.hh:46
typename detail::label_t_of_impl< base_t< ValueSet >>::type label_t_of
Definition: traits.hh:62
VCSN_RAT_VISIT(shuffle, v)
Definition: dot.hh:186
VCSN_RAT_VISIT(transposition, v)
Definition: dot.hh:188
typename super_t::template variadic_t< Type > variadic_t
Definition: dot.hh:41
typename expressionset_t::identities_t identities_t
Definition: dot.hh:27
const char * infiltrate_
Definition: dot.hh:405
typename detail::labelset_t_of_impl< base_t< ValueSet >>::type labelset_t_of
Definition: traits.hh:63
Pretty-printer for rational expressions.
Definition: dot.hh:18
const char * add_
The expression operators.
Definition: dot.hh:401
void visit(const tuple_t &v, std::true_type) override
Definition: dot.hh:239
void print_(const lweight_t &n)
Print a left-weight.
Definition: dot.hh:326
std::unordered_map< const void *, name_t > names_t
If physical_ is enabled, register the identifiers of the nodes.
Definition: dot.hh:385
void print_(const constant_t< Type > &n, const char *op)
Print a nullary node.
Definition: dot.hh:264
VCSN_RAT_VISIT(infiltrate, v)
Definition: dot.hh:180
labelset_t_of< context_t > labelset_t
Definition: dot.hh:28
friend class dot_printer
Make it possible to view members from dot_printer's with a different template parameter.
Definition: dot.hh:80
Definition: a-star.hh:8
VCSN_RAT_VISIT(mul, v)
Definition: dot.hh:183
const char * rweight_
Definition: dot.hh:397
ExpSet expressionset_t
Definition: dot.hh:22
auto out(const Aut &aut, state_t_of< Aut > s)
Indexes of visible transitions leaving state s.
Definition: automaton.hh:85
typename expressionset_t::const_visitor super_t
Definition: dot.hh:23
const char * conjunction_
Definition: dot.hh:404
Print as rich UTF-8 text, escaped.
Definition: format.hh:30
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
void print_(const variadic_t< Type > &n, const char *op)
Print a variadic node.
Definition: dot.hh:294
std::ostream & operator()(const value_t &v)
Entry point: print v as a complete Dot graph.
Definition: dot.hh:146
bool physical_
Whether to display the physical DAG rather than the logical tree.
Definition: dot.hh:382
Print as plain (ASCII) text, escaped.
Definition: format.hh:28
const char * complement_
Definition: dot.hh:402
typename detail::weight_t_of_impl< base_t< ValueSet >>::type weight_t_of
Definition: traits.hh:66
VCSN_RAT_VISIT(conjunction, v)
Definition: dot.hh:179
const char * mul_
Definition: dot.hh:406
std::ostream & iendl(std::ostream &o)
Print an end of line, then set the indentation.
Definition: indent.cc:49
const char * transposition_
Definition: dot.hh:409
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
dot_printer< ExpSet > make_dot_printer(const ExpSet &rs, std::ostream &out, bool physical=false)
Definition: dot.hh:421
typename super_t::template constant_t< Type > constant_t
Definition: dot.hh:37
const char * compose_
Definition: dot.hh:403
void print_(const tuple_t &v)
Print one tape.
Definition: dot.hh:198
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
const char * tuple_
Tuple tape separator.
Definition: dot.hh:412
const char * one_
Definition: dot.hh:416
An inner node with multiple children.
Definition: expression.hh:118
std::shared_ptr< names_t > names_
A shared_ptr, to support tuples.
Definition: dot.hh:387
return v
Definition: multiply.hh:361
dot_printer(const expressionset_t &rs, std::ostream &out, bool physical=false)
A printer.
Definition: dot.hh:52
std::ostream & incendl(std::ostream &o)
Increment the indentation, print an end of line, and set the indentation.
Definition: indent.cc:54
name_t name_
The name of the tuple node.
Definition: dot.hh:236
Indentation relative functions.
const char * shuffle_
Definition: dot.hh:407
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
typename super_t::template unary_t< Type > unary_t
Definition: dot.hh:39
std::ostream & out_
Output stream.
Definition: dot.hh:374
VCSN_RAT_VISIT(one, v)
Definition: dot.hh:184
name_t print_(const weight_t &w)
Print a weight.
Definition: dot.hh:315
VCSN_RAT_VISIT(zero, v)
Definition: dot.hh:189
VCSN_RAT_VISIT(star, v)
Definition: dot.hh:187
VCSN_RAT_VISIT(complement, v)
Definition: dot.hh:177
typename detail::context_t_of_impl< base_t< ValueSet >>::type context_t_of
Definition: traits.hh:61
typename super_t::tuple_t tuple_t
Definition: dot.hh:191
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:249
void format(format fmt)
Set output format.
Definition: dot.hh:83
void print_(const rweight_t &n)
Print a right-weight.
Definition: dot.hh:343
const char * lweight_
External product.
Definition: dot.hh:396
const char * ldivide_
Quotient.
Definition: dot.hh:399
void print_(const tuple_t &v, detail::index_sequence< I... >)
Print all the tapes.
Definition: dot.hh:210
VCSN_RAT_VISIT(rweight, v)
Definition: dot.hh:185