Awali
Another Weighted Automata library
js_print.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_JS_PRINT_EXP_HH
18 # define AWALI_ALGOS_JS_PRINT_EXP_HH
19 
20 #include <awali/common/version.hh>
23 #include <awali/sttc/ctx/fwd.hh>
24 #include <awali/sttc/misc/raise.hh>
26 #include <awali/common/json_ast.hh>
27 #include <awali/common/tuple.hh>
28 # include <stack>
29 # include <iostream>
30 # include <iomanip>
31 # include <ctime>
32 # include <sstream>
33 
34 namespace awali { namespace sttc {
35 
36 
37  /*---------------------.
38  | Json export(ratexp). |
39  `---------------------*/
40 
41 // namespace rat
42 // {
43 // template <typename RatExpSet>
44 // class js_print_visitor
45 // : public RatExpSet::const_visitor
46 // {
47 // public:
48 // using ratexpset_t = RatExpSet;
49 // using context_t = context_t_of<ratexpset_t>;
50 // using labelset_t = labelset_t_of<context_t>;
51 // using ratexp_t = typename ratexpset_t::value_t;
52 // using weightset_t = weightset_t_of<ratexpset_t>;
53 // using super_type = typename ratexpset_t::const_visitor;
54 // using node_t = typename super_type::node_t;
55 //
56 // constexpr static const char* me() { return "js-print-exp"; }
57 //
58 // js_print_visitor(const ratexpset_t& rs, std::ostream& o)
59 // : rs_(rs), stream_(o)
60 // {}
61 //
62 // std::ostream& operator()(const ratexp_t& v)
63 // {
64 // v->accept(*this);
65 // return stream_;
66 // }
67 //
68 // AWALI_RAT_UNSUPPORTED(ldiv)
69 // AWALI_RAT_UNSUPPORTED(transposition)
70 //
71 // AWALI_RAT_VISIT(zero,)
72 // {
73 // stream_ << "\"zero\":null" ;
74 // }
75 //
76 // AWALI_RAT_VISIT(one,)
77 // {
78 // stream_ << "\"one\":null";
79 // }
80 //
81 // AWALI_RAT_VISIT(atom, e)
82 // {
83 // stream_ << "\"label\":" ;
84 // ls_.js_print(stream_, e.value());
85 // }
86 //
87 // AWALI_RAT_VISIT(sum, e)
88 // {
89 // stream_ << "\"sum\":[";
90 // for (unsigned i = 0, n = e.size(); i < n; ++i) {
91 // const auto& v = e[i];
92 // stream_ << '{';
93 // v->accept(*this);
94 // stream_ << ((i<n-1)?"},":"}");
95 // }
96 // stream_ << ']';
97 // }
98 //
99 // AWALI_RAT_VISIT(prod, e)
100 // {
101 // stream_ << "\"prod\":[";
102 // for (unsigned i = 0, n = e.size(); i < n; ++i) {
103 // const auto& v = e[i];
104 // stream_ << '{';
105 // v->accept(*this);
106 // stream_ << ((i<n-1)?"},":"}");
107 // }
108 // stream_ << ']';
109 // }
110 //
111 // AWALI_RAT_VISIT(conjunction, e)
112 // {
113 // stream_ << "\"conjunction\":[";
114 // for (unsigned i = 0, n = e.size(); i < n; ++i) {
115 // const auto& v = e[i];
116 // stream_ << '{';
117 // v->accept(*this);
118 // stream_ << ((i<n-1)?"},":"}");
119 // }
120 // stream_ << ']';
121 // }
122 //
123 // AWALI_RAT_VISIT(shuffle, e)
124 // {
125 // stream_ << "\"shuffle\":[";
126 // for (unsigned i = 0, n = e.size(); i < n; ++i) {
127 // const auto& v = e[i];
128 // stream_ << '{';
129 // v->accept(*this);
130 // stream_ << ((i<n-1)?"},":"}");
131 // }
132 // stream_ << ']';
133 // }
134 //
135 // AWALI_RAT_VISIT(complement, e)
136 // {
137 // stream_ << "\"node\":\"Complement\", \"value\":";
138 // stream_ << '{';
139 // e.sub()->accept(*this);
140 // stream_ << '}';
141 // }
142 //
143 // AWALI_RAT_VISIT(star, e)
144 // {
145 // stream_ << "\"star\":";
146 // stream_ << '{';
147 // e.sub()->accept(*this);
148 // stream_ << '}';
149 // }
150 //
151 // AWALI_RAT_VISIT(lweight, e)
152 // {
153 // stream_ << "\"lweight\":\"";
154 // ws_.print(e.weight(), stream_);
155 // stream_ << "\", ";
156 // e.sub()->accept(*this);
157 // }
158 //
159 // AWALI_RAT_VISIT(rweight, e)
160 // {
161 // stream_ << "\"rweight\":\"";
162 // ws_.print(e.weight(), stream_);
163 // stream_ << "\", ";
164 // e.sub()->accept(*this);
165 // }
166 //
167 // private:
168 // ratexpset_t rs_;
169 // std::ostream& stream_;
170 // /// Shorthand to the weightset.
171 // weightset_t ws_ = *rs_.weightset();
172 // labelset_t ls_ = *rs_.labelset();
173 // };
174 //
175 // } // rat::
176 
177 
178  template <unsigned version = version::fsm_json>
179  inline
180  json::object_t*
182  {
183  version::check_fsmjson<version>();
184  /* timestamp */
185  json::object_t* timestamp = new json::object_t();
186  time_t tt;
187  std::time(&tt);
188  auto gmt = std::gmtime(&tt);
189  {
190  /* date */
191  std::stringstream ss;
192  ss << std::put_time(gmt,"%F");
193  timestamp->push_back("date", new json::string_t(ss.str()));
194  }{
195  /* time */
196  std::stringstream ss;
197  ss << std::put_time(gmt, "%TZ");
198  timestamp->push_back("time", new json::string_t(ss.str()));
199  }
200  return timestamp;
201  }
202 
203 
204  template <unsigned version = version::fsm_json>
205  inline
208  {
209  version::check_fsmjson<version>();
210  json::object_t* creator = new json::object_t();
211  creator->push_back("programName", new json::string_t("awali"));
212  creator->push_back("version", new json::string_t(awali::version::full));
213  return creator;
214  }
215 
216 
217  template <unsigned version = version::fsm_json>
218  inline
221  {
222  version::check_fsmjson<version>();
224  format->push_back("name", new json::string_t("fsm-json"));
225  format->push_back("version", new json::string_t(std::to_string(version)));
226  return format;
227  }
228 
229 
230  template <typename Automaton, unsigned version = version::fsm_json>
231  inline
232  json_ast_t
233  aut_to_ast(Automaton aut,
234  json_ast_t extra_metadata = json_ast::empty(),
235  bool full = false)
236  {
237  version::check_fsmjson<version>();
238  auto ctx = aut->context();
239  auto ws = ctx.weightset();
240  auto ls = ctx.labelset();
241  json::object_t* root = new json::object_t();
242 
243  {
244  /* == format == */
245  root->push_back("format", json_format<version>());
246  root->push_back("kind", new json::string_t("Automaton"));
247  }{
248  /* == metadata == */
249  json::object_t* metadata = new json::object_t();
250  /* == name == */
251  if(!aut->get_name().empty())
252  metadata->push_back("name", new json::string_t(aut->get_name()));
253  /* == caption == */
254  if(!aut->get_desc().empty())
255  metadata->push_back("caption", new json::string_t(aut->get_desc()));
256  /* == creator == */
257  metadata->push_back("creator", json_creator<version>());
258  /* == timestamp == */
259  metadata->push_back("timestamp", json_timestamp<version>());
260  /* == user-defined metadata == */
261  for(auto p : extra_metadata->fields)
262  metadata->push_back(p.first, p.second->copy());
263  root->push_back("metadata", metadata);
264  }{
265  /* == context == */
266  json::object_t* context = ctx.template to_json<version>()->object();
267  root->push_back("context",context);
268  }{
269  /* == data == */
270  json::object_t* data = new json::object_t();
271  {
272  /* == states == */
274  for(unsigned i: aut->states()) {
275  json::object_t* one_state = new json::object_t();
276  one_state->push_back("id", new json::int_t(full?i:i-2));
277  if (aut->has_explicit_name(i))
278  one_state->push_back("name",
279  new json::string_t(aut->get_state_name(i)));
280  if (aut->is_initial(i))
281  one_state->push_back(
282  "initial",
283  ws->template value_to_json<version>(aut->get_initial_weight(i))
284  );
285  if (aut->is_final(i))
286  one_state->push_back(
287  "final",
288  ws->template value_to_json<version>(aut->get_final_weight(i)));
289  if (aut->has_history(i)) {
290  std::stringstream ss;
291  aut->print_state_history(i,ss);
292  one_state->push_back("history",new json::string_t(ss.str()));
293  }
294  states->push_back(one_state);
295  }
296  data->push_back("states", states);
297  }{
298  /* == transitions == */
300  for(unsigned i: aut->transitions()) {
301  json::object_t* one_transition = new json::object_t();
302  {
303  /* == source == */
304  unsigned src = aut->src_of(i);
305  one_transition->push_back("source",
306  new json::int_t(full ? src : src-2));
307  }{
308  /* == destination == */
309  unsigned dst = aut->dst_of(i);
310  one_transition->push_back("destination",
311  new json::int_t(full ? dst : dst-2));
312  }{
313  /* == label == */
314  one_transition->push_back(
315  "label",
316  ls->template value_to_json<version>(aut->label_of(i)));
317  }{
318  /* == weight == */
319  if(!ws->is_one(aut->weight_of(i)) || ws->show_one()) {
320  one_transition->push_back(
321  "weight",
322  ws->template value_to_json<version>(aut->weight_of(i)) );
323  }
324  }
325  transitions->push_back(one_transition);
326  }
327  data->push_back("transitions", transitions);
328  }
329  root->push_back("data",data);
330  }
331  return std::shared_ptr<json::object_t>(root);
332  }
333 
334 
335  template <typename RatExpSet, unsigned version = version::fsm_json>
336  inline
337  json_ast_t
338  ratexp_to_ast(const RatExpSet& rs,
339  const typename RatExpSet::ratexp_t& e,
340  json_ast_t extra_metadata = json_ast::empty())
341  {
342  version::check_fsmjson<version>();
343  json::object_t* root = new json::object_t();
344  {
345  /* == format == */
346  root->push_back("format", json_format<version>());
347  root->push_back("kind", new json::string_t("Rational Expression"));
348  }{
349  /* == metadata == */
350  json::object_t* metadata = new json::object_t();
351  /* == creator == */
352  metadata->push_back("creator", json_creator<version>());
353  /* == timestamp == */
354  metadata->push_back("timestamp", json_timestamp<version>());
355  /* == user-defined metadata == */
356  for(auto p : extra_metadata->fields)
357  metadata->push_back(p.first, p.second->copy());
358  root->push_back("metadata", metadata);
359  }{
360  /* == context == */
361  root->push_back("context",rs.context().template to_json<version>());
362  }{
363  /* == data == */
364  root->push_back("data",rs.value_to_json(e));
365  }
366  return std::shared_ptr<json::object_t>(root);
367  }
368 
369 
370 }}//end of ns awali::stc
371 
372 #endif // !AWALI_ALGOS_JS_PRINT_EXP_HH
Definition: node.hh:431
Definition: node.hh:488
Definition: node.hh:367
object_t * push_back(std::string key, node_t *node)
Definition: node.hh:529
carries the algebraic settings of automata
Definition: context.hh:40
std::vector< transition_t > transitions(abstract_automaton_t const *aut, bool all)
std::vector< state_t > states(abstract_automaton_t const *aut, bool all)
json_ast_t empty()
Builds an empty json_ast_t.
Definition: json_ast.hh:33
std::string to_string(identities i)
json::object_t * json_creator()
Definition: js_print.hh:207
json_ast_t aut_to_ast(Automaton aut, json_ast_t extra_metadata=json_ast::empty(), bool full=false)
Definition: js_print.hh:233
json::object_t * json_timestamp()
Definition: js_print.hh:181
json_ast_t ratexp_to_ast(const RatExpSet &rs, const typename RatExpSet::ratexp_t &e, json_ast_t extra_metadata=json_ast::empty())
Definition: js_print.hh:338
auto format(const ValueSet &vs, const typename ValueSet::value_t &v, Args &&... args) -> std::string
Format v via vs.print.
Definition: stream.hh:109
json::object_t * json_format()
Definition: js_print.hh:220
static const std::string full
Completely version of Awali as a std::string.
Definition: version.hh:42
Main namespace of Awali.
Definition: ato.hh:22
std::shared_ptr< json::object_t > json_ast_t
Definition: json_ast.hh:27