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-2021 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  /* timestamp */
184  json::object_t* timestamp = new json::object_t();
185  time_t tt;
186  std::time(&tt);
187  auto gmt = std::gmtime(&tt);
188  {
189  /* date */
190  std::stringstream ss;
191  ss << std::put_time(gmt,"%F");
192  timestamp->push_back("date", new json::string_t(ss.str()));
193  }{
194  /* time */
195  std::stringstream ss;
196  ss << std::put_time(gmt, "%TZ");
197  timestamp->push_back("time", new json::string_t(ss.str()));
198  }
199  return timestamp;
200  }
201 
202 
203  template <unsigned version = version::fsm_json>
204  inline
207  {
208  json::object_t* creator = new json::object_t();
209  creator->push_back("programName", new json::string_t("awali"));
210  creator->push_back("version", new json::string_t(awali::version::full));
211  return creator;
212  }
213 
214 
215  template <unsigned version = version::fsm_json>
216  inline
219  {
221  format->push_back("name", new json::string_t("fsm-json"));
222  format->push_back("version", new json::string_t(std::to_string(version)));
223  return format;
224  }
225 
226 
227  template <typename Automaton, unsigned version = version::fsm_json>
228  inline
229  json_ast_t
230  aut_to_ast(Automaton aut,
231  json_ast_t extra_metadata = json_ast::empty(),
232  bool full = false)
233  {
234  auto ctx = aut->context();
235  auto ws = ctx.weightset();
236  auto ls = ctx.labelset();
237  json::object_t* root = new json::object_t();
238 
239  {
240  /* == format == */
241  root->push_back("format", json_format<version>());
242  root->push_back("kind", new json::string_t("Automaton"));
243  }{
244  /* == metadata == */
245  json::object_t* metadata = new json::object_t();
246  /* == name == */
247  if(!aut->get_name().empty())
248  metadata->push_back("name", new json::string_t(aut->get_name()));
249  /* == caption == */
250  if(!aut->get_desc().empty())
251  metadata->push_back("caption", new json::string_t(aut->get_desc()));
252  /* == creator == */
253  metadata->push_back("creator", json_creator<version>());
254  /* == timestamp == */
255  metadata->push_back("timestamp", json_timestamp<version>());
256  /* == user-defined metadata == */
257  for(auto p : extra_metadata->fields)
258  metadata->push_back(p.first, p.second->copy());
259  root->push_back("metadata", metadata);
260  }{
261  /* == context == */
262  json::object_t* context = ctx.template to_json<version>()->object();
263  root->push_back("context",context);
264  }{
265  /* == data == */
266  json::object_t* data = new json::object_t();
267  {
268  /* == states == */
270  for(unsigned i: aut->states()) {
271  json::object_t* one_state = new json::object_t();
272  one_state->push_back("id", new json::int_t(full?i:i-2));
273  if (aut->has_explicit_name(i))
274  one_state->push_back("name",
275  new json::string_t(aut->get_state_name(i)));
276  if (aut->is_initial(i))
277  one_state->push_back(
278  "initial",
279  ws->template value_to_json<version>(aut->get_initial_weight(i))
280  );
281  if (aut->is_final(i))
282  one_state->push_back(
283  "final",
284  ws->template value_to_json<version>(aut->get_final_weight(i)));
285  states->push_back(one_state);
286  }
287  data->push_back("states", states);
288  }{
289  /* == transitions == */
291  for(unsigned i: aut->transitions()) {
292  json::object_t* one_transition = new json::object_t();
293  {
294  /* == source == */
295  unsigned src = aut->src_of(i);
296  one_transition->push_back("source",
297  new json::int_t(full ? src : src-2));
298  }{
299  /* == destination == */
300  unsigned dst = aut->dst_of(i);
301  one_transition->push_back("destination",
302  new json::int_t(full ? dst : dst-2));
303  }{
304  /* == label == */
305  one_transition->push_back(
306  "label",
307  ls->template value_to_json<version>(aut->label_of(i)));
308  }{
309  /* == weight == */
310  if(!ws->is_one(aut->weight_of(i)) || ws->show_one()) {
311  one_transition->push_back(
312  "weight",
313  ws->template value_to_json<version>(aut->weight_of(i)) );
314  }
315  }
316  transitions->push_back(one_transition);
317  }
318  data->push_back("transitions", transitions);
319  }
320  root->push_back("data",data);
321  }
322  return std::shared_ptr<json::object_t>(root);
323  }
324 
325 
326  template <typename RatExpSet, unsigned version = version::fsm_json>
327  inline
328  json_ast_t
329  ratexp_to_ast(const RatExpSet& rs,
330  const typename RatExpSet::ratexp_t& e,
331  json_ast_t extra_metadata = json_ast::empty())
332  {
333  json::object_t* root = new json::object_t();
334  {
335  /* == format == */
336  root->push_back("format", json_format<version>());
337  root->push_back("kind", new json::string_t("Rational Expression"));
338  }{
339  /* == metadata == */
340  json::object_t* metadata = new json::object_t();
341  /* == creator == */
342  metadata->push_back("creator", json_creator<version>());
343  /* == timestamp == */
344  metadata->push_back("timestamp", json_timestamp<version>());
345  /* == user-defined metadata == */
346  for(auto p : extra_metadata->fields)
347  metadata->push_back(p.first, p.second->copy());
348  root->push_back("metadata", metadata);
349  }{
350  /* == context == */
351  root->push_back("context",rs.context().template to_json<version>());
352  }{
353  /* == data == */
354  root->push_back("data",rs.value_to_json(e));
355  }
356  return std::shared_ptr<json::object_t>(root);
357  }
358 
359 
360 }}//end of ns awali::stc
361 
362 #endif // !AWALI_ALGOS_JS_PRINT_EXP_HH
Definition: node.hh:424
Definition: node.hh:483
Definition: node.hh:365
object_t * push_back(std::string key, node_t *node)
Definition: node.hh:526
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:206
json_ast_t aut_to_ast(Automaton aut, json_ast_t extra_metadata=json_ast::empty(), bool full=false)
Definition: js_print.hh:230
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:329
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:218
static const std::string full
Completely version of Awali as a std::string.
Definition: version.hh:40
Main namespace of Awali.
Definition: ato.hh:22
std::shared_ptr< json::object_t > json_ast_t
Definition: json_ast.hh:27