Storm 1.11.1.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
JSONExporter.cpp
Go to the documentation of this file.
1#include "JSONExporter.h"
2
3#include <fstream>
4#include <iostream>
5#include <vector>
6
9#include "storm/io/file.h"
11
16
29
31
40
41namespace storm {
42namespace jani {
43
44ExportJsonType anyToJson(boost::any&& input) {
45 boost::any tmp(std::move(input));
46 ExportJsonType res = std::move(*boost::any_cast<ExportJsonType>(&tmp));
47 return res;
48}
49
50ExportJsonType buildExpression(storm::expressions::Expression const& exp, std::vector<storm::jani::Constant> const& constants,
51 VariableSet const& globalVariables = VariableSet(), VariableSet const& localVariables = VariableSet(),
52 std::unordered_set<std::string> const& auxiliaryVariables = {}) {
53 STORM_LOG_TRACE("Exporting " << exp);
54 return ExpressionToJson::translate(exp, constants, globalVariables, localVariables, auxiliaryVariables);
55}
56
58 public:
59 CompositionJsonExporter(bool allowRecursion) : allowRecursion(allowRecursion) {}
60
61 static ExportJsonType translate(storm::jani::Composition const& comp, bool allowRecursion = true) {
62 CompositionJsonExporter visitor(allowRecursion);
63 return anyToJson(comp.accept(visitor, boost::none));
64 }
65
66 virtual boost::any visit(AutomatonComposition const& composition, boost::any const&) {
67 ExportJsonType compDecl;
68 ExportJsonType autDecl;
69 autDecl["automaton"] = composition.getAutomatonName();
70 std::vector<ExportJsonType> elements;
71 elements.push_back(autDecl);
72 compDecl["elements"] = elements;
73 return compDecl;
74 }
75
76 virtual boost::any visit(ParallelComposition const& composition, boost::any const& data) {
77 ExportJsonType compDecl;
78
79 std::vector<ExportJsonType> elems;
80 for (auto const& subcomp : composition.getSubcompositions()) {
81 ExportJsonType elemDecl;
82 if (subcomp->isAutomatonComposition()) {
83 elemDecl["automaton"] = std::static_pointer_cast<AutomatonComposition>(subcomp)->getAutomatonName();
84 } else {
85 STORM_LOG_THROW(allowRecursion, storm::exceptions::InvalidJaniException, "Nesting composition " << *subcomp << " is not supported by JANI.");
86 elemDecl = anyToJson(subcomp->accept(*this, data));
87 }
88 elems.push_back(elemDecl);
89 }
90 compDecl["elements"] = elems;
91 std::vector<ExportJsonType> synElems;
92 for (auto const& syncs : composition.getSynchronizationVectors()) {
93 ExportJsonType syncDecl;
94 syncDecl["synchronise"] = std::vector<std::string>();
95 for (auto const& syncIn : syncs.getInput()) {
97 syncDecl["synchronise"].push_back(nullptr);
98 } else {
99 syncDecl["synchronise"].push_back(syncIn);
100 }
101 }
102 syncDecl["result"] = syncs.getOutput();
103 synElems.push_back(syncDecl);
104 }
105 if (!synElems.empty()) {
106 compDecl["syncs"] = synElems;
107 }
108
109 return compDecl;
110 }
111
112 private:
113 bool allowRecursion;
114};
115
117 switch (ct) {
119 return "<";
121 return "≤";
123 return ">";
125 return "≥";
126 }
127 STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentException, "Unknown ComparisonType");
128}
129
130ExportJsonType FormulaToJaniJson::constructPropertyInterval(boost::optional<storm::expressions::Expression> const& lower,
131 boost::optional<bool> const& lowerExclusive,
132 boost::optional<storm::expressions::Expression> const& upper,
133 boost::optional<bool> const& upperExclusive) const {
134 STORM_LOG_THROW((lower.is_initialized() || upper.is_initialized()), storm::exceptions::InvalidJaniException,
135 "PropertyInterval needs either a lower or an upper bound, but none was given.");
136 STORM_LOG_THROW((lower.is_initialized() || !lowerExclusive.is_initialized()), storm::exceptions::InvalidJaniException,
137 "PropertyInterval defines wether the lower bound is exclusive but no lower bound is given.");
138 STORM_LOG_THROW((upper.is_initialized() || !upperExclusive.is_initialized()), storm::exceptions::InvalidJaniException,
139 "PropertyInterval defines wether the upper bound is exclusive but no upper bound is given.");
140
141 ExportJsonType iDecl;
142 if (lower) {
143 iDecl["lower"] = buildExpression(*lower, model.getConstants(), model.getGlobalVariables());
144 if (lowerExclusive) {
145 iDecl["lower-exclusive"] = *lowerExclusive;
146 }
147 }
148 if (upper) {
149 iDecl["upper"] = buildExpression(*upper, model.getConstants(), model.getGlobalVariables());
150 if (upperExclusive) {
151 iDecl["upper-exclusive"] = *upperExclusive;
152 }
153 }
154 return iDecl;
155}
156
157ExportJsonType FormulaToJaniJson::constructRewardAccumulation(storm::logic::RewardAccumulation const& rewardAccumulation,
158 std::string const& rewardModelName) const {
159 storm::jani::RewardModelInformation info(model, rewardModelName);
160
161 bool steps = rewardAccumulation.isStepsSet() && (info.hasActionRewards() || info.hasTransitionRewards());
162 bool time = rewardAccumulation.isTimeSet() && !model.isDiscreteTimeModel() && info.hasStateRewards();
163 bool exit = rewardAccumulation.isExitSet() && info.hasStateRewards();
164
165 return constructRewardAccumulation(storm::logic::RewardAccumulation(steps, time, exit));
166}
167
168ExportJsonType FormulaToJaniJson::constructRewardAccumulation(storm::logic::RewardAccumulation const& rewardAccumulation) const {
169 std::vector<std::string> res;
170 if (rewardAccumulation.isStepsSet()) {
171 res.push_back("steps");
172 }
173 if (rewardAccumulation.isTimeSet()) {
174 res.push_back("time");
175 }
176 if (rewardAccumulation.isExitSet()) {
177 stateExitRewards = true;
178 res.push_back("exit");
179 }
180 return res;
181}
182
183ExportJsonType FormulaToJaniJson::constructStandardRewardAccumulation(std::string const& rewardModelName) const {
184 if (model.isDiscreteTimeModel()) {
185 return constructRewardAccumulation(storm::logic::RewardAccumulation(true, false, true), rewardModelName);
186 } else {
187 return constructRewardAccumulation(storm::logic::RewardAccumulation(true, true, false), rewardModelName);
188 }
189}
190
192 FormulaToJaniJson translator(model);
193 auto result = anyToJson(formula.accept(translator));
194 if (translator.containsStateExitRewards()) {
196 }
197 if (translator.containsMultiObjectiveProperties()) {
199 }
200 return result;
201}
202
204 return stateExitRewards;
205}
206
208 return multiObjectiveProperties;
209}
210
211boost::any FormulaToJaniJson::visit(storm::logic::AtomicExpressionFormula const& f, boost::any const&) const {
212 return buildExpression(f.getExpression(), model.getConstants(), model.getGlobalVariables());
213}
214
215boost::any FormulaToJaniJson::visit(storm::logic::AtomicLabelFormula const& f, boost::any const&) const {
216 ExportJsonType opDecl(f.getLabel());
217 return opDecl;
218}
219boost::any FormulaToJaniJson::visit(storm::logic::BinaryBooleanStateFormula const& f, boost::any const& data) const {
220 ExportJsonType opDecl;
222 opDecl["op"] = op == storm::logic::BinaryBooleanStateFormula::OperatorType::And ? "∧" : "∨";
223 opDecl["left"] = anyToJson(f.getLeftSubformula().accept(*this, data));
224 opDecl["right"] = anyToJson(f.getRightSubformula().accept(*this, data));
225 return opDecl;
226}
227boost::any FormulaToJaniJson::visit(storm::logic::BinaryBooleanPathFormula const& f, boost::any const& data) const {
228 ExportJsonType opDecl;
230 opDecl["op"] = op == storm::logic::BinaryBooleanPathFormula::OperatorType::And ? "∧" : "∨";
231 opDecl["left"] = boost::any_cast<ExportJsonType>(f.getLeftSubformula().accept(*this, data));
232 opDecl["right"] = boost::any_cast<ExportJsonType>(f.getRightSubformula().accept(*this, data));
233 return opDecl;
234}
235boost::any FormulaToJaniJson::visit(storm::logic::BooleanLiteralFormula const& f, boost::any const&) const {
236 ExportJsonType opDecl(f.isTrueFormula() ? true : false);
237 return opDecl;
238}
239boost::any FormulaToJaniJson::visit(storm::logic::BoundedUntilFormula const& f, boost::any const& data) const {
240 STORM_LOG_THROW(!f.hasMultiDimensionalSubformulas(), storm::exceptions::NotSupportedException,
241 "Jani export of multi-dimensional bounded until formulas is not supported.");
242 ExportJsonType opDecl;
243 opDecl["op"] = "U";
244 opDecl["left"] = anyToJson(f.getLeftSubformula().accept(*this, data));
245 opDecl["right"] = anyToJson(f.getRightSubformula().accept(*this, data));
246
247 bool hasStepBounds(false), hasTimeBounds(false);
248 std::vector<ExportJsonType> rewardBounds;
249
250 for (uint64_t i = 0; i < f.getDimension(); ++i) {
251 boost::optional<storm::expressions::Expression> lower, upper;
252 boost::optional<bool> lowerExclusive, upperExclusive;
253 if (f.hasLowerBound(i)) {
254 lower = f.getLowerBound(i);
255 lowerExclusive = f.isLowerBoundStrict(i);
256 }
257 if (f.hasUpperBound(i)) {
258 upper = f.getUpperBound(i);
259 upperExclusive = f.isUpperBoundStrict(i);
260 }
261 ExportJsonType propertyInterval = constructPropertyInterval(lower, lowerExclusive, upper, upperExclusive);
262
263 auto tbr = f.getTimeBoundReference(i);
264 if (tbr.isStepBound() || (model.isDiscreteTimeModel() && tbr.isTimeBound())) {
265 STORM_LOG_THROW(!hasStepBounds, storm::exceptions::NotSupportedException,
266 "Jani export of until formulas with multiple step bounds is not supported.");
267 hasStepBounds = true;
268 opDecl["step-bounds"] = propertyInterval;
269 } else if (tbr.isRewardBound()) {
270 ExportJsonType rewbound;
271 rewbound["exp"] = buildExpression(model.getRewardModelExpression(tbr.getRewardName()), model.getConstants(), model.getGlobalVariables());
272 if (tbr.hasRewardAccumulation()) {
273 rewbound["accumulate"] = constructRewardAccumulation(tbr.getRewardAccumulation(), tbr.getRewardName());
274 } else {
275 rewbound["accumulate"] = constructStandardRewardAccumulation(tbr.getRewardName());
276 }
277 rewbound["bounds"] = propertyInterval;
278 rewardBounds.push_back(std::move(rewbound));
279 } else {
280 STORM_LOG_THROW(!hasTimeBounds, storm::exceptions::NotSupportedException,
281 "Jani export of until formulas with multiple time bounds is not supported.");
282 hasTimeBounds = true;
283 opDecl["time-bounds"] = propertyInterval;
284 }
285 }
286 if (!rewardBounds.empty()) {
287 opDecl["reward-bounds"] = ExportJsonType(rewardBounds);
288 }
289 return opDecl;
290}
291
292boost::any FormulaToJaniJson::visit(storm::logic::ConditionalFormula const&, boost::any const&) const {
293 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Jani currently does not support conditional formulae");
294}
295
296boost::any FormulaToJaniJson::visit(storm::logic::CumulativeRewardFormula const&, boost::any const&) const {
297 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Storm currently does not support translating cumulative reward formulae");
298}
299
300boost::any FormulaToJaniJson::visit(storm::logic::EventuallyFormula const& f, boost::any const& data) const {
301 ExportJsonType opDecl;
302 opDecl["op"] = "U";
303 opDecl["left"] = anyToJson(f.getTrueFormula()->accept(*this, data));
304 opDecl["right"] = anyToJson(f.getSubformula().accept(*this, data));
305 return opDecl;
306}
307
308boost::any FormulaToJaniJson::visit(storm::logic::TimeOperatorFormula const& f, boost::any const& data) const {
309 ExportJsonType opDecl;
310
311 // Create standard reward accumulation for time operator formulas.
315 }
316 auto rewAccJson = constructRewardAccumulation(rewAcc);
317
318 if (f.hasBound()) {
319 auto bound = f.getBound();
320 opDecl["op"] = comparisonTypeToJani(bound.comparisonType);
321 if (f.hasOptimalityType()) {
322 opDecl["left"]["op"] = f.getOptimalityType() == storm::solver::OptimizationDirection::Minimize ? "Emin" : "Emax";
324 opDecl["left"]["reach"] = anyToJson(f.getSubformula().asEventuallyFormula().getSubformula().accept(*this, data));
325 } else {
326 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Unsupported subformula for time operator formula " << f);
327 }
328 } else {
329 opDecl["left"]["op"] =
330 (bound.comparisonType == storm::logic::ComparisonType::Less || bound.comparisonType == storm::logic::ComparisonType::LessEqual) ? "Emax"
331 : "Emin";
332 opDecl["left"]["reach"] = anyToJson(f.getSubformula().asEventuallyFormula().getSubformula().accept(*this, data));
333 }
334 opDecl["left"]["exp"] = ExportJsonType(1);
335 opDecl["left"]["accumulate"] = rewAccJson;
336 opDecl["right"] = buildExpression(bound.threshold, model.getConstants(), model.getGlobalVariables());
337 } else {
338 if (f.hasOptimalityType()) {
339 opDecl["op"] = f.getOptimalityType() == storm::solver::OptimizationDirection::Minimize ? "Emin" : "Emax";
341 opDecl["reach"] = anyToJson(f.getSubformula().asEventuallyFormula().getSubformula().accept(*this, data));
342 } else {
343 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Unsupported subformula for time operator formula " << f);
344 }
345 } else {
346 // TODO add checks
347 opDecl["op"] = "Emin";
348 opDecl["reach"] = anyToJson(f.getSubformula().asEventuallyFormula().getSubformula().accept(*this, data));
349 }
350 opDecl["exp"] = ExportJsonType(1);
351 opDecl["accumulate"] = rewAccJson;
352 }
353 return opDecl;
354}
355
356boost::any FormulaToJaniJson::visit(storm::logic::GloballyFormula const& f, boost::any const& data) const {
357 ExportJsonType opDecl;
358 opDecl["op"] = "G";
359 opDecl["exp"] = anyToJson(f.getSubformula().accept(*this, data));
360 return opDecl;
361}
362
363boost::any FormulaToJaniJson::visit(storm::logic::GameFormula const&, boost::any const&) const {
364 STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Conversion of game formulas to Jani is not supported.");
365}
366
367boost::any FormulaToJaniJson::visit(storm::logic::InstantaneousRewardFormula const&, boost::any const&) const {
368 STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Jani currently does not support conversion of an instanteneous reward formula");
369}
370
371boost::any FormulaToJaniJson::visit(storm::logic::LongRunAverageOperatorFormula const& f, boost::any const& data) const {
372 ExportJsonType opDecl;
373 if (f.hasBound()) {
374 auto bound = f.getBound();
375 opDecl["op"] = comparisonTypeToJani(bound.comparisonType);
376 if (f.hasOptimalityType()) {
377 opDecl["left"]["op"] = f.getOptimalityType() == storm::solver::OptimizationDirection::Minimize ? "Smin" : "Smax";
378 opDecl["left"]["exp"] = anyToJson(f.getSubformula().accept(*this, data));
379 } else {
380 opDecl["left"]["op"] =
381 (bound.comparisonType == storm::logic::ComparisonType::Less || bound.comparisonType == storm::logic::ComparisonType::LessEqual) ? "Smax"
382 : "Smin";
383 opDecl["left"]["exp"] = anyToJson(f.getSubformula().accept(*this, data));
384 }
385 opDecl["right"] = buildExpression(bound.threshold, model.getConstants(), model.getGlobalVariables());
386 } else {
387 if (f.hasOptimalityType()) {
388 opDecl["op"] = f.getOptimalityType() == storm::solver::OptimizationDirection::Minimize ? "Smin" : "Smax";
389 opDecl["exp"] = anyToJson(f.getSubformula().accept(*this, data));
390
391 } else {
392 // TODO add checks
393 opDecl["op"] = "Smin";
394 opDecl["exp"] = anyToJson(f.getSubformula().accept(*this, data));
395 }
396 }
397 return opDecl;
398}
399
400boost::any FormulaToJaniJson::visit(storm::logic::LongRunAverageRewardFormula const&, boost::any const&) const {
401 // ExportJsonType opDecl;
402 // if(f.()) {
403 // auto bound = f.getBound();
404 // opDecl["op"] = comparisonTypeToJani(bound.comparisonType);
405 // if(f.hasOptimalityType()) {
406 // opDecl["left"]["op"] = f.getOptimalityType() == storm::solver::OptimizationDirection::Minimize ? "Smin" : "Smax";
407 // opDecl["left"]["exp"] = anyToJson(f.getSubformula().accept(*this, boost::none));
408 // } else {
409 // opDecl["left"]["op"] = (bound.comparisonType == storm::logic::ComparisonType::Less || bound.comparisonType ==
410 // storm::logic::ComparisonType::LessEqual) ? "Smax" : "Smin"; opDecl["left"]["exp"] = anyToJson(f.getSubformula().accept(*this,
411 // boost::none));
412 // }
413 // opDecl["right"] = ExpressionToJson::translate(bound.threshold);
414 // } else {
415 // if(f.hasOptimalityType()) {
416 // opDecl["op"] = f.getOptimalityType() == storm::solver::OptimizationDirection::Minimize ? "Smin" : "Smax";
417 // opDecl["exp"] = anyToJson(f.getSubformula().accept(*this, boost::none));
418 //
419 // } else {
420 // // TODO add checks
421 // opDecl["op"] = "Pmin";
422 // opDecl["exp"] = anyToJson(f.getSubformula().accept(*this, boost::none));
423 // }
424 // }
425 // return opDecl;
426
427 STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Jani currently does not support conversion of an LRA reward formula");
428}
429
430boost::any FormulaToJaniJson::visit(storm::logic::MultiObjectiveFormula const& f, boost::any const& data) const {
431 multiObjectiveProperties = true;
432 ExportJsonType opDecl;
433 opDecl["op"] = "Multi";
434 STORM_LOG_ASSERT(f.isTradeoff() || f.isLexicographic(), "Unexpected multi-objective formula type.");
435 opDecl["type"] = f.isTradeoff() ? "tradeoff" : "lexicographic";
436 opDecl["properties"] = ExportJsonType::array();
437 for (auto const& subformula : f.getSubformulas()) {
438 auto p = ExportJsonType::object();
439 auto subFormulaCopy = subformula->clone();
440 if (subFormulaCopy->isOperatorFormula()) {
441 auto& operatorFormula = subFormulaCopy->asOperatorFormula();
442 if (operatorFormula.hasBound()) {
443 if (!operatorFormula.hasOptimalityType()) {
444 // Set a sane optimality type because JANI properties require some
445 auto const derivedOptimalityType = storm::logic::isLowerBound(operatorFormula.getBound().comparisonType)
446 ? storm::solver::OptimizationDirection::Maximize
447 : storm::solver::OptimizationDirection::Minimize;
448 operatorFormula.setOptimalityType(derivedOptimalityType);
449 }
450 } else {
452 operatorFormula.hasOptimalityType(), storm::exceptions::NotSupportedException,
453 "Unable to export a multi-objective formula since the optimization direction for subformula " << *subFormulaCopy << " can not be derived.");
454 p["opt"] = storm::solver::minimize(subformula->asOperatorFormula().getOptimalityType()) ? "min" : "max";
455 }
456 } else {
458 subFormulaCopy->hasQualitativeResult(), storm::exceptions::NotSupportedException,
459 "Unable to export a multi-objective formula since the optimization direction for subformula " << *subFormulaCopy << " can not be derived.");
460 }
461 p["exp"] = anyToJson(subFormulaCopy->accept(*this, data));
462 opDecl["properties"].push_back(std::move(p));
463 }
464 return opDecl;
465}
466
467boost::any FormulaToJaniJson::visit(storm::logic::QuantileFormula const&, boost::any const&) const {
468 STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Jani currently does not support conversion of a Quantile formula");
469}
470
471boost::any FormulaToJaniJson::visit(storm::logic::NextFormula const& f, boost::any const& data) const {
472 ExportJsonType opDecl;
473 opDecl["op"] = "U";
474 opDecl["left"] = anyToJson(f.getTrueFormula()->accept(*this, data));
475 opDecl["right"] = anyToJson(f.getSubformula().accept(*this, data));
476 auto intervalExpressionManager = std::make_shared<storm::expressions::ExpressionManager>();
477 opDecl["step-bounds"] = constructPropertyInterval(intervalExpressionManager->integer(1), false, intervalExpressionManager->integer(1), false);
478 return opDecl;
479}
480
481boost::any FormulaToJaniJson::visit(storm::logic::ProbabilityOperatorFormula const& f, boost::any const& data) const {
482 ExportJsonType opDecl;
483
484 if (f.hasBound()) {
485 auto bound = f.getBound();
486 opDecl["op"] = comparisonTypeToJani(bound.comparisonType);
487 if (f.hasOptimalityType()) {
488 opDecl["left"]["op"] = f.getOptimalityType() == storm::solver::OptimizationDirection::Minimize ? "Pmin" : "Pmax";
489 opDecl["left"]["exp"] = anyToJson(f.getSubformula().accept(*this, data));
490 } else {
491 opDecl["left"]["op"] =
492 (bound.comparisonType == storm::logic::ComparisonType::Less || bound.comparisonType == storm::logic::ComparisonType::LessEqual) ? "Pmax"
493 : "Pmin";
494 opDecl["left"]["exp"] = anyToJson(f.getSubformula().accept(*this, data));
495 }
496 opDecl["right"] = buildExpression(bound.threshold, model.getConstants(), model.getGlobalVariables());
497 } else {
498 if (f.hasOptimalityType()) {
499 opDecl["op"] = f.getOptimalityType() == storm::solver::OptimizationDirection::Minimize ? "Pmin" : "Pmax";
500 opDecl["exp"] = anyToJson(f.getSubformula().accept(*this, data));
501
502 } else {
503 // TODO add checks
504 opDecl["op"] = "Pmin";
505 opDecl["exp"] = anyToJson(f.getSubformula().accept(*this, data));
506 }
507 }
508 return opDecl;
509}
510
511boost::any FormulaToJaniJson::visit(storm::logic::RewardOperatorFormula const& f, boost::any const& data) const {
512 ExportJsonType opDecl;
513 std::string rewardModelName;
514 if (f.hasRewardModelName()) {
515 rewardModelName = f.getRewardModelName();
516 } else {
518 for (auto const& variable : model.getGlobalVariables().getRealVariables()) {
519 if (variable.isTransient()) {
520 rewardModelName = variable.getName();
521 STORM_LOG_WARN("Reward model name was not given, assuming the only global real transient variable '" << rewardModelName
522 << "' to measure the reward.");
523 break;
524 }
525 }
526 }
527 }
528 STORM_LOG_THROW(!rewardModelName.empty(), storm::exceptions::NotSupportedException, "Reward name has to be specified for Jani-conversion");
529
530 std::string opString = "";
532 opString = "S";
533 } else {
534 opString = "E";
535 }
536 if (f.hasOptimalityType()) {
537 opString += storm::solver::minimize(f.getOptimalityType()) ? "min" : "max";
538 } else if (f.hasBound()) {
539 opString += storm::logic::isLowerBound(f.getBound().comparisonType) ? "min" : "max";
540 } else {
541 opString += "min";
542 }
543
544 opDecl["op"] = opString;
545 auto setRewardAccumulation = [&opDecl, &rewardModelName, this](auto const& subformula) {
546 opDecl["accumulate"] = subformula.hasRewardAccumulation() ? constructRewardAccumulation(subformula.getRewardAccumulation(), rewardModelName)
547 : constructStandardRewardAccumulation(rewardModelName);
548 };
549
551 opDecl["reach"] = anyToJson(f.getSubformula().asEventuallyFormula().getSubformula().accept(*this, data));
552 setRewardAccumulation(f.getSubformula().asEventuallyFormula());
553 } else if (f.getSubformula().isCumulativeRewardFormula()) {
554 auto const& subf = f.getSubformula().asCumulativeRewardFormula();
555 setRewardAccumulation(subf);
556 auto isStepInstant = [this, &subf](uint64_t i) {
557 return subf.getTimeBoundReference(i).isStepBound() || (model.isDiscreteTimeModel() && subf.getTimeBoundReference(i).isTimeBound());
558 };
559 auto getInstantExpression = [&subf, &isStepInstant](uint64_t i) {
560 auto instantExpr = subf.getBound(i);
561 // handle strict bounds
562 if (subf.isBoundStrict(i)) {
563 // Jani can't represent strict bounds. Only in case of step bounds we can decrease the bound by one as a workaround.
564 STORM_LOG_THROW(isStepInstant(i), storm::exceptions::NotSupportedException,
565 "Jani export of cumulative reward formula " << subf << " with strict time or reward bound is not supported.");
566 instantExpr = instantExpr - subf.getBound(i).getManager().integer(1);
567 }
568 // ensure correct type for step instants
569 if (isStepInstant(i) && !instantExpr.getType().isIntegerType()) {
570 instantExpr = storm::expressions::floor(instantExpr);
571 }
572 return instantExpr;
573 };
574 if (subf.isMultiDimensional() || subf.getTimeBoundReference().isRewardBound()) {
575 opDecl["reward-instants"] = ExportJsonType::array();
576 for (uint64_t i = 0; i < subf.getDimension(); ++i) {
577 ExportJsonType instantDecl;
578 auto const& tbr = subf.getTimeBoundReference(i);
579 instantDecl["exp"] =
580 tbr.isRewardBound() ? buildExpression(model.getRewardModelExpression(tbr.getRewardName()), model.getConstants(), model.getGlobalVariables())
581 : ExportJsonType(1);
582 if (tbr.isRewardBound()) {
583 if (tbr.hasRewardAccumulation()) {
584 instantDecl["accumulate"] = constructRewardAccumulation(tbr.getRewardAccumulation(), tbr.getRewardName());
585 } else {
586 instantDecl["accumulate"] = constructStandardRewardAccumulation(tbr.getRewardName());
587 }
588 } else if (isStepInstant(i)) {
589 instantDecl["accumulate"] = constructRewardAccumulation(storm::logic::RewardAccumulation(true, false, false));
590 } else {
591 instantDecl["accumulate"] = constructRewardAccumulation(storm::logic::RewardAccumulation(false, true, false));
592 }
593 instantDecl["instant"] = buildExpression(getInstantExpression(i), model.getConstants(), model.getGlobalVariables());
594 opDecl["reward-instants"].push_back(std::move(instantDecl));
595 }
596 } else {
597 opDecl[isStepInstant(0) ? "step-instant" : "time-instant"] =
598 buildExpression(getInstantExpression(0), model.getConstants(), model.getGlobalVariables());
599 }
600 } else if (f.getSubformula().isTotalRewardFormula()) {
601 setRewardAccumulation(f.getSubformula().asTotalRewardFormula());
603 opDecl[model.isDiscreteTimeModel() ? "step-instant" : "time-instant"] =
606 setRewardAccumulation(f.getSubformula().asLongRunAverageRewardFormula());
607 } else {
608 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Unhandled subformula for jani export: " << f.getSubformula());
609 }
610 opDecl["exp"] = buildExpression(model.getRewardModelExpression(rewardModelName), model.getConstants(), model.getGlobalVariables());
611
612 if (f.hasBound()) {
613 ExportJsonType compDecl;
614 auto bound = f.getBound();
615 compDecl["op"] = comparisonTypeToJani(bound.comparisonType);
616 compDecl["left"] = std::move(opDecl);
617 compDecl["right"] = buildExpression(bound.threshold, model.getConstants(), model.getGlobalVariables());
618 return compDecl;
619 } else {
620 return opDecl;
621 }
622}
623
624boost::any FormulaToJaniJson::visit(storm::logic::TotalRewardFormula const&, boost::any const&) const {
625 STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Jani currently does not support a total reward formula");
626}
627
628boost::any FormulaToJaniJson::visit(storm::logic::UnaryBooleanStateFormula const& f, boost::any const& data) const {
629 STORM_LOG_ASSERT(f.getOperator() == storm::logic::UnaryBooleanStateFormula::OperatorType::Not, "Unsupported operator");
630 ExportJsonType opDecl;
631 opDecl["op"] = "¬";
632 opDecl["exp"] = anyToJson(f.getSubformula().accept(*this, data));
633 return opDecl;
634}
635
636boost::any FormulaToJaniJson::visit(storm::logic::UnaryBooleanPathFormula const& f, boost::any const& data) const {
637 STORM_LOG_ASSERT(f.getOperator() == storm::logic::UnaryBooleanStateFormula::OperatorType::Not, "Unsupported operator");
638 ExportJsonType opDecl;
639 opDecl["op"] = "¬";
640 opDecl["exp"] = boost::any_cast<ExportJsonType>(f.getSubformula().accept(*this, data));
641 return opDecl;
642}
643
644boost::any FormulaToJaniJson::visit(storm::logic::UntilFormula const& f, boost::any const& data) const {
645 ExportJsonType opDecl;
646 opDecl["op"] = "U";
647 opDecl["left"] = anyToJson(f.getLeftSubformula().accept(*this, data));
648 opDecl["right"] = anyToJson(f.getRightSubformula().accept(*this, data));
649 return opDecl;
650}
651
652boost::any FormulaToJaniJson::visit(storm::logic::HOAPathFormula const&, boost::any const&) const {
653 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Jani currently does not support HOA path formulae");
654}
655
657 STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Jani currently does not support discounted cumulative reward formulae");
658}
659
660boost::any FormulaToJaniJson::visit(storm::logic::DiscountedTotalRewardFormula const&, boost::any const&) const {
661 STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Jani currently does not support discounted total reward formulae");
662}
663
666 switch (optype) {
667 case OpType::And:
668 return "∧";
669 case OpType::Or:
670 return "∨";
671 case OpType::Xor:
672 return "≠";
673 case OpType::Implies:
674 return "⇒";
675 case OpType::Iff:
676 return "=";
677 case OpType::Plus:
678 return "+";
679 case OpType::Minus:
680 return "-";
681 case OpType::Times:
682 return "*";
683 case OpType::Divide:
684 return "/";
685 case OpType::Min:
686 return "min";
687 case OpType::Max:
688 return "max";
689 case OpType::Power:
690 return "pow";
691 case OpType::Modulo:
692 return "%";
693 case OpType::Logarithm:
694 return "log";
695 case OpType::Equal:
696 return "=";
697 case OpType::NotEqual:
698 return "≠";
699 case OpType::Less:
700 return "<";
701 case OpType::LessOrEqual:
702 return "≤";
703 case OpType::Greater:
704 return ">";
705 case OpType::GreaterOrEqual:
706 return "≥";
707 case OpType::Not:
708 return "¬";
709 case OpType::Floor:
710 return "floor";
711 case OpType::Ceil:
712 return "ceil";
713 case OpType::Ite:
714 return "ite";
715 case OpType::Sin:
716 return "sin";
717 case OpType::Cos:
718 return "cos";
719 default:
720 STORM_LOG_THROW(false, storm::exceptions::InvalidJaniException, "Operator not supported by Jani");
721 }
722}
723
724ExportJsonType ExpressionToJson::translate(storm::expressions::Expression const& expr, std::vector<storm::jani::Constant> const& constants,
725 VariableSet const& globalVariables, VariableSet const& localVariables,
726 std::unordered_set<std::string> const& auxiliaryVariables) {
727 // Simplify the expression first and reduce the nesting
728 auto simplifiedExpr = storm::jani::reduceNestingInJaniExpression(expr.simplify());
729
730 ExpressionToJson visitor(constants, globalVariables, localVariables, auxiliaryVariables);
731 return anyToJson(simplifiedExpr.accept(visitor, boost::none));
732}
733
734boost::any ExpressionToJson::visit(storm::expressions::IfThenElseExpression const& expression, boost::any const& data) {
735 ExportJsonType opDecl;
736 opDecl["op"] = "ite";
737 opDecl["if"] = anyToJson(expression.getCondition()->accept(*this, data));
738 opDecl["then"] = anyToJson(expression.getThenExpression()->accept(*this, data));
739 opDecl["else"] = anyToJson(expression.getElseExpression()->accept(*this, data));
740 return opDecl;
741}
742boost::any ExpressionToJson::visit(storm::expressions::BinaryBooleanFunctionExpression const& expression, boost::any const& data) {
743 ExportJsonType opDecl;
744 opDecl["op"] = operatorTypeToJaniString(expression.getOperator());
745 opDecl["left"] = anyToJson(expression.getOperand(0)->accept(*this, data));
746 opDecl["right"] = anyToJson(expression.getOperand(1)->accept(*this, data));
747 return opDecl;
748}
749boost::any ExpressionToJson::visit(storm::expressions::BinaryNumericalFunctionExpression const& expression, boost::any const& data) {
750 ExportJsonType opDecl;
751 opDecl["op"] = operatorTypeToJaniString(expression.getOperator());
752 opDecl["left"] = anyToJson(expression.getOperand(0)->accept(*this, data));
753 opDecl["right"] = anyToJson(expression.getOperand(1)->accept(*this, data));
754 if (expression.getOperator() == storm::expressions::OperatorType::Power && expression.getType().isIntegerType()) {
755 // power expressions that have integer type need to be "type casted"
756 ExportJsonType trc;
757 trc["op"] = "trc";
758 trc["exp"] = std::move(opDecl);
759 return trc;
760 } else {
761 return opDecl;
762 }
763}
764
765boost::any ExpressionToJson::visit(storm::expressions::BinaryRelationExpression const& expression, boost::any const& data) {
766 ExportJsonType opDecl;
767 opDecl["op"] = operatorTypeToJaniString(expression.getOperator());
768 opDecl["left"] = anyToJson(expression.getOperand(0)->accept(*this, data));
769 opDecl["right"] = anyToJson(expression.getOperand(1)->accept(*this, data));
770 return opDecl;
771}
772boost::any ExpressionToJson::visit(storm::expressions::VariableExpression const& expression, boost::any const&) {
773 if (auxiliaryVariables.count(expression.getVariableName())) {
774 return ExportJsonType(expression.getVariableName());
775 } else if (globalVariables.hasVariable(expression.getVariable())) {
776 return ExportJsonType(globalVariables.getVariable(expression.getVariable()).getName());
777 } else if (localVariables.hasVariable(expression.getVariable())) {
778 return ExportJsonType(localVariables.getVariable(expression.getVariable()).getName());
779 } else {
780 for (auto const& constant : constants) {
781 if (constant.getExpressionVariable() == expression.getVariable()) {
782 return ExportJsonType(constant.getName());
783 }
784 }
785 }
786 STORM_LOG_THROW(false, storm::exceptions::InvalidJaniException,
787 "Expression variable '" << expression.getVariableName() << "' not known in Jani data structures.");
788 return ExportJsonType(); // should not reach this point.
789}
790boost::any ExpressionToJson::visit(storm::expressions::UnaryBooleanFunctionExpression const& expression, boost::any const& data) {
791 ExportJsonType opDecl;
792 opDecl["op"] = operatorTypeToJaniString(expression.getOperator());
793 opDecl["exp"] = anyToJson(expression.getOperand()->accept(*this, data));
794 return opDecl;
795}
796boost::any ExpressionToJson::visit(storm::expressions::UnaryNumericalFunctionExpression const& expression, boost::any const& data) {
797 ExportJsonType opDecl;
798 opDecl["op"] = operatorTypeToJaniString(expression.getOperator());
800 opDecl["left"] = 0;
801 opDecl["right"] = anyToJson(expression.getOperand()->accept(*this, data));
802 } else {
803 opDecl["exp"] = anyToJson(expression.getOperand()->accept(*this, data));
804 }
805 return opDecl;
806}
807
808boost::any ExpressionToJson::visit(storm::expressions::BooleanLiteralExpression const& expression, boost::any const&) {
809 return ExportJsonType(expression.getValue());
810}
811boost::any ExpressionToJson::visit(storm::expressions::IntegerLiteralExpression const& expression, boost::any const&) {
812 return ExportJsonType(expression.getValue());
813}
814boost::any ExpressionToJson::visit(storm::expressions::RationalLiteralExpression const& expression, boost::any const&) {
815 ExportJsonType val(expression.getValue());
816
818 // Try if exact export is possible as fraction of two literals
819 auto [num, den] = storm::utility::asFraction(expression.getValue());
820 if (!storm::utility::isOne(den)) {
821 ExportJsonType numJson(num), denJson(den);
823 val = ExportJsonType();
825 val["left"] = std::move(numJson);
826 val["right"] = std::move(denJson);
827 }
828 }
829 }
830 return val;
831}
832
833boost::any ExpressionToJson::visit(storm::expressions::ValueArrayExpression const& expression, boost::any const& data) {
834 ExportJsonType opDecl;
835 opDecl["op"] = "av";
836 std::vector<ExportJsonType> elements;
837 uint64_t size = expression.size()->evaluateAsInt();
838 for (uint64_t i = 0; i < size; ++i) {
839 elements.push_back(anyToJson(expression.at(i)->accept(*this, data)));
840 }
841 opDecl["elements"] = std::move(elements);
842 return opDecl;
843}
844
845boost::any ExpressionToJson::visit(storm::expressions::ConstructorArrayExpression const& expression, boost::any const& data) {
846 ExportJsonType opDecl;
847 opDecl["op"] = "ac";
848 opDecl["var"] = expression.getIndexVar().getName();
849 opDecl["length"] = anyToJson(expression.size()->accept(*this, data));
850 bool inserted = auxiliaryVariables.insert(expression.getIndexVar().getName()).second;
851 opDecl["exp"] = anyToJson(expression.getElementExpression()->accept(*this, data));
852 if (inserted) {
853 auxiliaryVariables.erase(expression.getIndexVar().getName());
854 }
855 return opDecl;
856}
857
858boost::any ExpressionToJson::visit(storm::expressions::ArrayAccessExpression const& expression, boost::any const& data) {
859 ExportJsonType opDecl;
860 opDecl["op"] = "aa";
861 opDecl["exp"] = anyToJson(expression.getOperand(0)->accept(*this, data));
862 opDecl["index"] = anyToJson(expression.getOperand(1)->accept(*this, data));
863 return opDecl;
864}
865
866boost::any ExpressionToJson::visit(storm::expressions::FunctionCallExpression const& expression, boost::any const& data) {
867 ExportJsonType opDecl;
868 opDecl["op"] = "call";
869 opDecl["function"] = expression.getFunctionIdentifier();
870 std::vector<ExportJsonType> arguments;
871 for (uint64_t i = 0; i < expression.getNumberOfArguments(); ++i) {
872 arguments.push_back(anyToJson(expression.getArgument(i)->accept(*this, data)));
873 }
874 opDecl["args"] = std::move(arguments);
875 return opDecl;
876}
877
879 ExportJsonType constantDecl;
880 constantDecl["constant"] = expression.asString();
881 return constantDecl;
882}
883
884void JsonExporter::toFile(storm::jani::Model const& janiModel, std::vector<storm::jani::Property> const& formulas, std::string const& filepath, bool checkValid,
885 bool compact) {
886 std::ofstream stream;
887 storm::io::openFile(filepath, stream, false, true);
888 toStream(janiModel, formulas, stream, checkValid, compact);
889 storm::io::closeFile(stream);
890}
891
892void JsonExporter::toStream(storm::jani::Model const& janiModel, std::vector<storm::jani::Property> const& formulas, std::ostream& os, bool checkValid,
893 bool compact) {
894 if (checkValid) {
895 janiModel.checkValid();
896 }
897 JsonExporter exporter;
898 STORM_LOG_INFO("Started to convert model " << janiModel.getName() << ".");
899 exporter.convertModel(janiModel, !compact);
900 STORM_LOG_INFO("Started to convert properties of model " << janiModel.getName() << ".");
901 exporter.convertProperties(formulas, janiModel);
902 STORM_LOG_INFO("Producing json output... " << janiModel.getName() << ".");
903 os << storm::dumpJson(exporter.finalize(), compact) << '\n';
904 STORM_LOG_INFO("Conversion completed " << janiModel.getName() << ".");
905}
906
907ExportJsonType buildActionArray(std::vector<storm::jani::Action> const& actions) {
908 std::vector<ExportJsonType> actionReprs;
909 uint64_t actIndex = 0;
910 for (auto const& act : actions) {
912 actIndex++;
913 continue;
914 }
915 actIndex++;
916 ExportJsonType actEntry;
917 actEntry["name"] = act.getName();
918 actionReprs.push_back(actEntry);
919 }
920
921 return ExportJsonType(actionReprs);
922}
923
925 ExportJsonType typeDescr;
926 if (type.isIntegerType()) {
927 typeDescr = "int";
928 } else if (type.isRationalType()) {
929 typeDescr = "real";
930 } else if (type.isBooleanType()) {
931 typeDescr = "bool";
932 } else if (type.isArrayType()) {
933 typeDescr["kind"] = "array";
934 typeDescr["base"] = buildTypeDescription(type.getElementType());
935 } else {
936 STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentException, "Unknown expression type.");
937 }
938 return typeDescr;
939}
940
942 std::vector<storm::jani::Constant> const& constants) {
945 getBoundsFromConstraints(typeDesc, var, constraint.getBaseExpression().getOperand(0), constants);
946 getBoundsFromConstraints(typeDesc, var, constraint.getBaseExpression().getOperand(1), constants);
947 } else if (constraint.getBaseExpression().isBinaryRelationExpression()) {
950 std::vector<bool> varOps(2, false);
951 for (int i : {0, 1}) {
952 varOps[i] = constraint.getOperand(i).isVariable() && constraint.getOperand(i).getBaseExpression().asVariableExpression().getVariable() == var;
953 }
954 storm::expressions::Expression boundExpr = varOps[0] ? constraint.getOperand(1) : constraint.getOperand(0);
955 if ((leq && varOps[0]) || (geq && varOps[1])) {
956 typeDesc["upper-bound"] = buildExpression(boundExpr, constants);
957 } else if ((leq && varOps[1]) || (geq && varOps[0])) {
958 typeDesc["lower-bound"] = buildExpression(boundExpr, constants);
959 } else {
960 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Jani Export for constant constraint " << constraint << " is not supported.");
961 }
962 } else {
963 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Jani Export for constant constraint " << constraint << " is not supported.");
964 }
965}
966
967ExportJsonType buildConstantsArray(std::vector<storm::jani::Constant> const& constants) {
968 std::vector<ExportJsonType> constantDeclarations;
969 for (auto const& constant : constants) {
970 ExportJsonType constantEntry;
971 constantEntry["name"] = constant.getName();
972 ExportJsonType typeDesc;
973 if (constant.hasConstraint()) {
974 typeDesc["kind"] = "bounded";
975 typeDesc["base"] = buildTypeDescription(constant.getType());
976 getBoundsFromConstraints(typeDesc, constant.getExpressionVariable(), constant.getConstraintExpression(), constants);
977 } else {
978 typeDesc = buildTypeDescription(constant.getType());
979 }
980 constantEntry["type"] = typeDesc;
981 if (constant.isDefined()) {
982 constantEntry["value"] = buildExpression(constant.getExpression(), constants);
983 }
984 constantDeclarations.push_back(constantEntry);
985 }
986 return ExportJsonType(constantDeclarations);
987}
988
989ExportJsonType buildType(storm::jani::JaniType const& type, std::vector<storm::jani::Constant> const& constants, VariableSet const& globalVariables,
990 VariableSet const& localVariables = VariableSet()) {
991 ExportJsonType typeDesc;
992 if (type.isBasicType() || type.isClockType() || type.isContinuousType()) {
993 typeDesc = type.getStringRepresentation();
994 } else if (type.isBoundedType()) {
995 typeDesc["kind"] = "bounded";
996 auto const& bndType = type.asBoundedType();
997 switch (bndType.getBaseType()) {
999 typeDesc["base"] = "int";
1000 break;
1002 typeDesc["base"] = "real";
1003 break;
1004 }
1005 if (bndType.hasLowerBound()) {
1006 typeDesc["lower-bound"] = buildExpression(bndType.getLowerBound(), constants, globalVariables, localVariables);
1007 }
1008 if (bndType.hasUpperBound()) {
1009 typeDesc["upper-bound"] = buildExpression(bndType.getUpperBound(), constants, globalVariables, localVariables);
1010 }
1011 } else if (type.isArrayType()) {
1012 typeDesc["kind"] = "array";
1013 typeDesc["base"] = buildType(type.asArrayType().getBaseType(), constants, globalVariables, localVariables);
1014 } else {
1015 STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Variable type not recognized in JSONExporter");
1016 }
1017 return typeDesc;
1018}
1019
1020ExportJsonType buildVariablesArray(storm::jani::VariableSet const& varSet, std::vector<storm::jani::Constant> const& constants,
1021 VariableSet const& globalVariables, VariableSet const& localVariables = VariableSet()) {
1022 ExportJsonType variableDeclarations = std::vector<ExportJsonType>();
1023 for (auto const& variable : varSet) {
1024 ExportJsonType varEntry;
1025 varEntry["name"] = variable.getName();
1026 if (variable.isTransient()) {
1027 varEntry["transient"] = variable.isTransient();
1028 }
1029 varEntry["type"] = buildType(variable.getType(), constants, globalVariables, localVariables);
1030 if (variable.hasInitExpression()) {
1031 varEntry["initial-value"] = buildExpression(variable.getInitExpression(), constants, globalVariables, localVariables);
1032 }
1033 variableDeclarations.push_back(std::move(varEntry));
1034 }
1035 return variableDeclarations;
1036}
1037
1038ExportJsonType buildFunctionsArray(std::unordered_map<std::string, FunctionDefinition> const& functionDefinitions,
1039 std::vector<storm::jani::Constant> const& constants, VariableSet const& globalVariables,
1040 VariableSet const& localVariables = VariableSet()) {
1041 ExportJsonType functionDeclarations = std::vector<ExportJsonType>();
1042 for (auto const& nameFunDef : functionDefinitions) {
1043 storm::jani::FunctionDefinition const& funDef = nameFunDef.second;
1044 ExportJsonType funDefJson;
1045 funDefJson["name"] = nameFunDef.first;
1046 funDefJson["type"] = buildTypeDescription(funDef.getType());
1047 std::vector<ExportJsonType> parameterDeclarations;
1048 std::unordered_set<std::string> parameterNames;
1049 for (auto const& p : funDef.getParameters()) {
1050 ExportJsonType parDefJson;
1051 parDefJson["name"] = p.getName();
1052 parameterNames.insert(p.getName());
1053 parDefJson["type"] = buildTypeDescription(p.getType());
1054 parameterDeclarations.push_back(parDefJson);
1055 }
1056 funDefJson["parameters"] = parameterDeclarations;
1057 funDefJson["body"] = buildExpression(funDef.getFunctionBody(), constants, globalVariables, localVariables, parameterNames);
1058 functionDeclarations.push_back(std::move(funDefJson));
1059 }
1060 return functionDeclarations;
1061}
1062
1063ExportJsonType buildLValue(storm::jani::LValue const& lValue, std::vector<storm::jani::Constant> const& constants, VariableSet const& globalVariables,
1064 VariableSet const& localVariables) {
1065 if (lValue.isVariable()) {
1066 return lValue.getVariable().getName();
1067 } else {
1068 STORM_LOG_ASSERT(lValue.isArrayAccess(), "Unhandled LValue " << lValue << ".");
1069 ExportJsonType result = lValue.getVariable().getName();
1070 for (auto const& indexExpr : lValue.getArrayIndexVector()) {
1071 ExportJsonType subLValue = std::move(result);
1072 result.clear();
1073 result["op"] = "aa";
1074 result["exp"] = std::move(subLValue);
1075 result["index"] = buildExpression(indexExpr, constants, globalVariables, localVariables);
1076 }
1077 return result;
1078 }
1079}
1080
1081ExportJsonType buildAssignmentArray(storm::jani::OrderedAssignments const& orderedAssignments, std::vector<storm::jani::Constant> const& constants,
1082 VariableSet const& globalVariables, VariableSet const& localVariables, bool commentExpressions) {
1083 ExportJsonType assignmentDeclarations = std::vector<ExportJsonType>();
1084 bool addIndex = orderedAssignments.hasMultipleLevels();
1085 for (auto const& assignment : orderedAssignments) {
1086 ExportJsonType assignmentEntry;
1087 assignmentEntry["ref"] = buildLValue(assignment.getLValue(), constants, globalVariables, localVariables);
1088 assignmentEntry["value"] = buildExpression(assignment.getAssignedExpression(), constants, globalVariables, localVariables);
1089 if (addIndex) {
1090 assignmentEntry["index"] = assignment.getLevel();
1091 }
1092 if (commentExpressions) {
1093 assignmentEntry["comment"] = assignment.getLValue().getName() + " <- " + assignment.getAssignedExpression().toString();
1094 }
1095 assignmentDeclarations.push_back(std::move(assignmentEntry));
1096 }
1097 return assignmentDeclarations;
1098}
1099
1100ExportJsonType buildLocationsArray(std::vector<storm::jani::Location> const& locations, std::vector<storm::jani::Constant> const& constants,
1101 VariableSet const& globalVariables, VariableSet const& localVariables, bool commentExpressions) {
1102 ExportJsonType locationDeclarations = std::vector<ExportJsonType>();
1103 for (auto const& location : locations) {
1104 ExportJsonType locEntry;
1105 locEntry["name"] = location.getName();
1106 if (location.hasTimeProgressInvariant()) {
1107 ExportJsonType timeProg;
1108 timeProg["exp"] = buildExpression(location.getTimeProgressInvariant(), constants, globalVariables, localVariables);
1109 if (commentExpressions) {
1110 timeProg["comment"] = location.getTimeProgressInvariant().toString();
1111 }
1112 locEntry["time-progress"] = std::move(timeProg);
1113 }
1114 if (!location.getAssignments().empty()) {
1115 locEntry["transient-values"] = buildAssignmentArray(location.getAssignments(), constants, globalVariables, localVariables, commentExpressions);
1116 }
1117 locationDeclarations.push_back(std::move(locEntry));
1118 }
1119 return locationDeclarations;
1120}
1121
1123 std::vector<std::string> names;
1124 for (auto const& initLocIndex : automaton.getInitialLocationIndices()) {
1125 names.push_back(automaton.getLocation(initLocIndex).getName());
1126 }
1127 return ExportJsonType(names);
1128}
1129
1130ExportJsonType buildDestinations(std::vector<EdgeDestination> const& destinations, std::map<uint64_t, std::string> const& locationNames,
1131 std::vector<storm::jani::Constant> const& constants, VariableSet const& globalVariables, VariableSet const& localVariables,
1132 bool commentExpressions) {
1133 assert(destinations.size() > 0);
1134 ExportJsonType destDeclarations = std::vector<ExportJsonType>();
1135 for (auto const& destination : destinations) {
1136 ExportJsonType destEntry;
1137 destEntry["location"] = locationNames.at(destination.getLocationIndex());
1138 bool prob1 = false;
1139 if (destination.getProbability().isLiteral()) {
1140 if (storm::utility::isOne(destination.getProbability().evaluateAsRational())) {
1141 prob1 = true;
1142 }
1143 }
1144 if (!prob1) {
1145 destEntry["probability"]["exp"] = buildExpression(destination.getProbability(), constants, globalVariables, localVariables);
1146 if (commentExpressions) {
1147 destEntry["probability"]["comment"] = destination.getProbability().toString();
1148 }
1149 }
1150 if (!destination.getOrderedAssignments().empty()) {
1151 destEntry["assignments"] =
1152 buildAssignmentArray(destination.getOrderedAssignments(), constants, globalVariables, localVariables, commentExpressions);
1153 }
1154 destDeclarations.push_back(std::move(destEntry));
1155 }
1156 return destDeclarations;
1157}
1158
1159ExportJsonType buildEdge(Edge const& edge, std::map<uint64_t, std::string> const& actionNames, std::map<uint64_t, std::string> const& locationNames,
1160 std::vector<storm::jani::Constant> const& constants, VariableSet const& globalVariables, VariableSet const& localVariables,
1161 bool commentExpressions) {
1162 STORM_LOG_THROW(edge.getDestinations().size() > 0, storm::exceptions::InvalidJaniException, "An edge without destinations is not allowed.");
1163 ExportJsonType edgeEntry;
1164 edgeEntry["location"] = locationNames.at(edge.getSourceLocationIndex());
1165 if (!edge.hasSilentAction()) {
1166 edgeEntry["action"] = actionNames.at(edge.getActionIndex());
1167 }
1168 if (edge.hasRate()) {
1169 edgeEntry["rate"]["exp"] = buildExpression(edge.getRate(), constants, globalVariables, localVariables);
1170 if (commentExpressions) {
1171 edgeEntry["rate"]["comment"] = edge.getRate().toString();
1172 }
1173 }
1174 if (!edge.getGuard().isTrue()) {
1175 edgeEntry["guard"]["exp"] = buildExpression(edge.getGuard(), constants, globalVariables, localVariables);
1176 if (commentExpressions) {
1177 edgeEntry["guard"]["comment"] = edge.getGuard().toString();
1178 }
1179 }
1180 edgeEntry["destinations"] = buildDestinations(edge.getDestinations(), locationNames, constants, globalVariables, localVariables, commentExpressions);
1181 if (!edge.getAssignments().empty()) {
1182 edgeEntry["assignments"] = buildAssignmentArray(edge.getAssignments(), constants, globalVariables, localVariables, commentExpressions);
1183 }
1184 return edgeEntry;
1185}
1186
1187ExportJsonType buildEdges(std::vector<Edge> const& edges, std::map<uint64_t, std::string> const& actionNames,
1188 std::map<uint64_t, std::string> const& locationNames, std::vector<storm::jani::Constant> const& constants,
1189 VariableSet const& globalVariables, VariableSet const& localVariables, bool commentExpressions) {
1190 ExportJsonType edgeDeclarations = std::vector<ExportJsonType>();
1191 for (auto const& edge : edges) {
1192 if (edge.getGuard().isFalse()) {
1193 continue;
1194 }
1195 edgeDeclarations.push_back(buildEdge(edge, actionNames, locationNames, constants, globalVariables, localVariables, commentExpressions));
1196 }
1197 return edgeDeclarations;
1198}
1199
1200ExportJsonType buildAutomataArray(std::vector<storm::jani::Automaton> const& automata, std::map<uint64_t, std::string> const& actionNames,
1201 std::vector<storm::jani::Constant> const& constants, VariableSet const& globalVariables, bool commentExpressions) {
1202 ExportJsonType automataDeclarations = std::vector<ExportJsonType>();
1203 for (auto const& automaton : automata) {
1204 ExportJsonType autoEntry;
1205 autoEntry["name"] = automaton.getName();
1206 autoEntry["variables"] = buildVariablesArray(automaton.getVariables(), constants, globalVariables, automaton.getVariables());
1207 if (!automaton.getFunctionDefinitions().empty()) {
1208 autoEntry["functions"] = buildFunctionsArray(automaton.getFunctionDefinitions(), constants, globalVariables, automaton.getVariables());
1209 }
1210 if (automaton.hasRestrictedInitialStates()) {
1211 autoEntry["restrict-initial"]["exp"] =
1212 buildExpression(automaton.getInitialStatesRestriction(), constants, globalVariables, automaton.getVariables());
1213 }
1214 autoEntry["locations"] = buildLocationsArray(automaton.getLocations(), constants, globalVariables, automaton.getVariables(), commentExpressions);
1215 autoEntry["initial-locations"] = buildInitialLocations(automaton);
1216 autoEntry["edges"] = buildEdges(automaton.getEdges(), actionNames, automaton.buildIdToLocationNameMap(), constants, globalVariables,
1217 automaton.getVariables(), commentExpressions);
1218 automataDeclarations.push_back(std::move(autoEntry));
1219 }
1220 return automataDeclarations;
1221}
1222
1223void JsonExporter::convertModel(storm::jani::Model const& janiModel, bool commentExpressions) {
1224 modelFeatures = janiModel.getModelFeatures();
1225 jsonStruct["jani-version"] = janiModel.getJaniVersion();
1226 jsonStruct["name"] = janiModel.getName();
1227 jsonStruct["type"] = to_string(janiModel.getModelType());
1228 jsonStruct["actions"] = buildActionArray(janiModel.getActions());
1229 jsonStruct["constants"] = buildConstantsArray(janiModel.getConstants());
1230 jsonStruct["variables"] = buildVariablesArray(janiModel.getGlobalVariables(), janiModel.getConstants(), janiModel.getGlobalVariables());
1231 if (!janiModel.getGlobalFunctionDefinitions().empty()) {
1232 jsonStruct["functions"] = buildFunctionsArray(janiModel.getGlobalFunctionDefinitions(), janiModel.getConstants(), janiModel.getGlobalVariables());
1233 }
1234 jsonStruct["restrict-initial"]["exp"] = buildExpression(janiModel.getInitialStatesRestriction(), janiModel.getConstants(), janiModel.getGlobalVariables());
1235 jsonStruct["automata"] = buildAutomataArray(janiModel.getAutomata(), janiModel.getActionIndexToNameMap(), janiModel.getConstants(),
1236 janiModel.getGlobalVariables(), commentExpressions);
1237 jsonStruct["system"] = CompositionJsonExporter::translate(janiModel.getSystemComposition());
1238}
1239
1240ExportJsonType JsonExporter::getEdgeAsJson(storm::jani::Model const& janiModel, uint64_t automatonIndex, uint64_t edgeIndex, bool commentExpressions) {
1241 auto const& automaton = janiModel.getAutomaton(automatonIndex);
1242 return buildEdge(automaton.getEdge(edgeIndex), janiModel.getActionIndexToNameMap(), automaton.buildIdToLocationNameMap(), janiModel.getConstants(),
1243 janiModel.getGlobalVariables(), automaton.getVariables(), commentExpressions);
1244}
1245
1247 switch (ft) {
1249 return "min";
1251 return "max";
1253 return "sum";
1255 return "avg";
1257 return "count";
1259 return "∃";
1261 return "∀";
1263 return "argmin";
1265 return "argmax";
1267 return "values";
1268 }
1269 STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentException, "Unknown FilterType");
1270}
1271
1273 ExportJsonType propDecl;
1274 propDecl["states"]["op"] = "initial";
1275 propDecl["op"] = "filter";
1276 propDecl["fun"] = janiFilterTypeString(fe.getFilterType());
1277 propDecl["values"] = FormulaToJaniJson::translate(*fe.getFormula(), model, modelFeatures);
1278 return propDecl;
1279}
1280
1281void JsonExporter::convertProperties(std::vector<storm::jani::Property> const& formulas, storm::jani::Model const& model) {
1282 ExportJsonType properties;
1283
1284 // For now, unset model-features that only relate to properties.
1285 // If such properties actually exist, these features will be re-added during formula conversion below.
1288 if (formulas.empty()) {
1289 jsonStruct["properties"] = ExportJsonType(ExportJsonType::value_t::array);
1290 return;
1291 }
1292
1293 for (auto const& f : formulas) {
1294 ExportJsonType propDecl;
1295 propDecl["name"] = f.getName();
1296 propDecl["expression"] = convertFilterExpression(f.getFilter(), model, modelFeatures);
1297 properties.push_back(std::move(propDecl));
1298 }
1299 jsonStruct["properties"] = std::move(properties);
1300}
1301
1302ExportJsonType JsonExporter::finalize() {
1303 jsonStruct["features"] = ExportJsonType::parse(modelFeatures.toString());
1304 return jsonStruct;
1305}
1306
1307} // namespace jani
1308} // namespace storm
virtual bool isBinaryRelationExpression() const
virtual bool isBinaryBooleanFunctionExpression() const
virtual std::shared_ptr< BaseExpression const > getOperand(uint_fast64_t operandIndex) const
Retrieves the given operand from the expression.
VariableExpression const & asVariableExpression() const
Type const & getType() const
Retrieves the type of the expression.
virtual OperatorType getOperator() const
Retrieves the operator of a function application.
virtual storm::expressions::OperatorType getOperator() const override
Retrieves the operator of a function application.
virtual std::shared_ptr< BaseExpression const > getOperand(uint_fast64_t operandIndex) const override
Retrieves the given operand from the expression.
virtual storm::expressions::OperatorType getOperator() const override
Retrieves the operator of a function application.
virtual storm::expressions::OperatorType getOperator() const override
Retrieves the operator of a function application.
bool getValue() const
Retrieves the value of the boolean literal.
Represents an array of the given size, where the i'th entry is determined by the elementExpression,...
virtual std::shared_ptr< BaseExpression const > size() const override
std::shared_ptr< BaseExpression const > const & getElementExpression() const
storm::expressions::Variable const & getIndexVar() const
Expression simplify() const
Simplifies the expression according to some basic rules.
bool isVariable() const
Retrieves whether the expression is a variable.
Expression getOperand(uint_fast64_t operandIndex) const
Retrieves the given operand from the expression.
BaseExpression const & getBaseExpression() const
Retrieves the base expression underlying this expression object.
std::string toString() const
Converts the expression into a string.
bool isTrue() const
Checks if the expression is equal to the boolean literal true.
Represents an array with a given list of elements.
std::shared_ptr< BaseExpression const > getArgument(uint64_t i) const
std::shared_ptr< BaseExpression const > getElseExpression() const
Retrieves the else expression of the if-then-else expression.
std::shared_ptr< BaseExpression const > getCondition() const
Retrieves the condition expression of the if-then-else expression.
std::shared_ptr< BaseExpression const > getThenExpression() const
Retrieves the then expression of the if-then-else expression.
int_fast64_t getValue() const
Retrieves the value of the integer literal.
storm::RationalNumber getValue() const
Retrieves the value of the double literal.
std::string asString() const
Get the Transcendental number as string, like in the Jani file (single character)
Type getElementType() const
Retrieves the element type of the type, provided that it is an Array type.
Definition Type.cpp:210
bool isBooleanType() const
Checks whether this type is a boolean type.
Definition Type.cpp:178
bool isIntegerType() const
Checks whether this type is an integral type.
Definition Type.cpp:182
bool isArrayType() const
Checks whether this type is an array type.
Definition Type.cpp:194
bool isRationalType() const
Checks whether this type is a rational type.
Definition Type.cpp:214
virtual storm::expressions::OperatorType getOperator() const override
Retrieves the operator of a function application.
virtual std::shared_ptr< BaseExpression const > getOperand(uint_fast64_t operandIndex) const override
Retrieves the given operand from the expression.
virtual storm::expressions::OperatorType getOperator() const override
Retrieves the operator of a function application.
Represents an array with a given list of elements.
virtual std::shared_ptr< BaseExpression const > size() const override
virtual std::shared_ptr< BaseExpression const > at(uint64_t i) const override
Variable const & getVariable() const
Retrieves the variable associated with this expression.
std::string const & getVariableName() const
Retrieves the name of the variable associated with this expression.
std::string const & getName() const
Retrieves the name of the variable.
Definition Variable.cpp:46
JaniType & getBaseType()
Definition ArrayType.cpp:18
std::string const & getAutomatonName() const
Retrieves the name of the automaton this composition element refers to.
Location const & getLocation(uint64_t index) const
Retrieves the location with the given index.
std::set< uint64_t > const & getInitialLocationIndices() const
Retrieves the indices of the initial locations.
virtual boost::any accept(CompositionVisitor &visitor, boost::any const &data) const =0
virtual boost::any visit(ParallelComposition const &composition, boost::any const &data)
virtual boost::any visit(AutomatonComposition const &composition, boost::any const &)
static ExportJsonType translate(storm::jani::Composition const &comp, bool allowRecursion=true)
CompositionJsonExporter(bool allowRecursion)
bool hasSilentAction() const
Returns whether it contains the silent action.
Definition Edge.cpp:102
uint64_t getActionIndex() const
Retrieves the id of the action with which this edge is labeled.
Definition Edge.cpp:45
std::vector< EdgeDestination > const & getDestinations() const
Retrieves the destinations of this edge.
Definition Edge.cpp:77
bool hasRate() const
Retrieves whether this edge has an associated rate.
Definition Edge.cpp:49
uint64_t getSourceLocationIndex() const
Retrieves the index of the source location.
Definition Edge.cpp:41
OrderedAssignments const & getAssignments() const
Retrieves the assignments of this edge.
Definition Edge.cpp:89
storm::expressions::Expression const & getRate() const
Retrieves the rate of this edge.
Definition Edge.cpp:53
storm::expressions::Expression const & getGuard() const
Retrieves the guard of this edge.
Definition Edge.cpp:65
virtual boost::any visit(storm::expressions::IfThenElseExpression const &expression, boost::any const &data)
static ExportJsonType translate(storm::expressions::Expression const &expr, std::vector< storm::jani::Constant > const &constants, VariableSet const &globalVariables, VariableSet const &localVariables, std::unordered_set< std::string > const &auxiliaryVariables)
std::shared_ptr< storm::logic::Formula const > const & getFormula() const
Definition Property.h:48
storm::modelchecker::FilterType getFilterType() const
Definition Property.h:56
static ExportJsonType translate(storm::logic::Formula const &formula, storm::jani::Model const &model, storm::jani::ModelFeatures &modelFeatures)
bool containsMultiObjectiveProperties() const
virtual boost::any visit(storm::logic::AtomicExpressionFormula const &f, boost::any const &data) const
storm::expressions::Expression const & getFunctionBody() const
Retrieves the expression that defines the function.
std::vector< storm::expressions::Variable > const & getParameters() const
Retrieves the parameters of the function.
storm::expressions::Type const & getType() const
Retrieves the type of the function.
ArrayType const & asArrayType() const
Definition JaniType.cpp:47
virtual bool isContinuousType() const
Definition JaniType.cpp:27
virtual std::string getStringRepresentation() const =0
Retrieves a string representation of the type.
virtual bool isArrayType() const
Definition JaniType.cpp:19
virtual bool isBoundedType() const
Definition JaniType.cpp:15
virtual bool isBasicType() const
Definition JaniType.cpp:11
BoundedType const & asBoundedType() const
Definition JaniType.cpp:39
virtual bool isClockType() const
Definition JaniType.cpp:23
static ExportJsonType getEdgeAsJson(storm::jani::Model const &janiModel, uint64_t automatonIndex, uint64_t edgeIndex, bool commentExpressions=true)
static void toFile(storm::jani::Model const &janiModel, std::vector< storm::jani::Property > const &formulas, std::string const &filepath, bool checkValid=true, bool compact=false)
static void toStream(storm::jani::Model const &janiModel, std::vector< storm::jani::Property > const &formulas, std::ostream &ostream, bool checkValid=false, bool compact=false)
bool isVariable() const
Definition LValue.cpp:20
std::vector< storm::expressions::Expression > & getArrayIndexVector()
Returns the referred variable. In case of an array access, this is the referred array variable.
Definition LValue.cpp:40
bool isArrayAccess() const
Returns true if the lValue refers either to an array variable or to an array access.
Definition LValue.cpp:32
storm::jani::Variable const & getVariable() const
To check if the array is fully accessed, so result will be of the most inner child Type....
Definition LValue.cpp:28
std::string const & getName() const
Retrieves the name of the location.
Definition Location.cpp:19
std::string toString() const
ModelFeatures & add(ModelFeature const &modelFeature)
void remove(ModelFeature const &modelFeature)
VariableSet & getGlobalVariables()
Retrieves the variables of this automaton.
Definition Model.cpp:721
storm::expressions::Expression getRewardModelExpression(std::string const &identifier) const
Retrieves the defining reward expression of the reward model with the given identifier.
Definition Model.cpp:813
Composition const & getSystemComposition() const
Retrieves the system composition expression.
Definition Model.cpp:949
storm::expressions::Expression const & getInitialStatesRestriction() const
Gets the expression restricting the legal initial values of the global variables.
Definition Model.cpp:1293
static const uint64_t SILENT_ACTION_INDEX
The index of the silent action.
Definition Model.h:642
std::vector< Automaton > & getAutomata()
Retrieves the automata of the model.
Definition Model.cpp:872
ModelType const & getModelType() const
Retrieves the type of the model.
Definition Model.cpp:121
std::vector< Constant > const & getConstants() const
Retrieves the constants of the model.
Definition Model.cpp:689
std::vector< Action > const & getActions() const
Retrieves the actions of the model.
Definition Model.cpp:646
uint64_t getJaniVersion() const
Retrieves the JANI-version of the model.
Definition Model.cpp:117
void checkValid() const
Checks if the model is valid JANI, which should be verified before any further operations are applied...
Definition Model.cpp:1410
std::string const & getName() const
Retrieves the name of the model.
Definition Model.cpp:137
bool isDiscreteTimeModel() const
Determines whether this model is a discrete-time model.
Definition Model.cpp:1378
ModelFeatures const & getModelFeatures() const
Retrieves the enabled model features.
Definition Model.cpp:129
Automaton & getAutomaton(std::string const &name)
Retrieves the automaton with the given name.
Definition Model.cpp:888
std::map< uint64_t, std::string > getActionIndexToNameMap() const
Builds a map with action indices mapped to their names.
Definition Model.cpp:1036
std::unordered_map< std::string, FunctionDefinition > const & getGlobalFunctionDefinitions() const
Retrieves all global function definitions.
Definition Model.cpp:781
bool hasMultipleLevels(bool onlyTransient=false) const
Checks whether the assignments have several levels.
bool empty(bool onlyTransient=false) const
Retrieves whether this set of assignments is empty.
std::vector< SynchronizationVector > const & getSynchronizationVectors() const
Retrieves the synchronization vectors of the parallel composition.
std::vector< std::shared_ptr< Composition > > const & getSubcompositions() const
Retrieves the subcompositions of the parallel composition.
static const std::string NO_ACTION_INPUT
std::string const & getName() const
Retrieves the name of the variable.
Definition Variable.cpp:34
bool hasVariable(std::string const &name) const
Retrieves whether this variable set contains a variable with the given name.
detail::Variables< Variable > getRealVariables()
Retrieves the real variables in this set.
Variable const & getVariable(std::string const &name) const
Retrieves the variable with the given name.
uint64_t getNumberOfRealTransientVariables() const
Retrieves the number of real transient variables in this variable set.
storm::expressions::Expression const & getExpression() const
std::string const & getLabel() const
Formula const & getRightSubformula() const
Formula const & getLeftSubformula() const
Formula const & getRightSubformula() const
Formula const & getLeftSubformula() const
virtual bool isTrueFormula() const override
TimeBoundReference const & getTimeBoundReference(unsigned i=0) const
bool isLowerBoundStrict(unsigned i=0) const
storm::expressions::Expression const & getUpperBound(unsigned i=0) const
storm::expressions::Expression const & getLowerBound(unsigned i=0) const
bool isUpperBoundStrict(unsigned i=0) const
RewardAccumulation const & getRewardAccumulation() const
TotalRewardFormula & asTotalRewardFormula()
Definition Formula.cpp:437
virtual bool isInstantaneousRewardFormula() const
Definition Formula.cpp:152
static std::shared_ptr< Formula const > getTrueFormula()
Definition Formula.cpp:213
LongRunAverageRewardFormula & asLongRunAverageRewardFormula()
Definition Formula.cpp:468
virtual bool isCumulativeRewardFormula() const
Definition Formula.cpp:144
virtual bool isLongRunAverageRewardFormula() const
Definition Formula.cpp:160
EventuallyFormula & asEventuallyFormula()
Definition Formula.cpp:341
InstantaneousRewardFormula & asInstantaneousRewardFormula()
Definition Formula.cpp:460
virtual bool isEventuallyFormula() const
Definition Formula.cpp:88
virtual bool isTotalRewardFormula() const
Definition Formula.cpp:164
CumulativeRewardFormula & asCumulativeRewardFormula()
Definition Formula.cpp:429
boost::any accept(FormulaVisitor const &visitor) const
Definition Formula.cpp:16
storm::expressions::Expression const & getBound() const
std::vector< std::shared_ptr< Formula const > > const & getSubformulas() const
Bound const & getBound() const
storm::solver::OptimizationDirection const & getOptimalityType() const
std::string const & getRewardModelName() const
Retrieves the name of the reward model this property refers to (if any).
bool hasRewardModelName() const
Retrieves whether the reward model refers to a specific reward model.
Formula const & getSubformula() const
Formula const & getSubformula() const
#define STORM_LOG_INFO(message)
Definition logging.h:24
#define STORM_LOG_WARN(message)
Definition logging.h:25
#define STORM_LOG_TRACE(message)
Definition logging.h:12
#define STORM_LOG_ASSERT(cond, message)
Definition macros.h:11
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:30
Expression floor(Expression const &first)
void closeFile(std::ofstream &stream)
Close the given file after writing.
Definition file.h:47
void openFile(std::string const &filepath, std::ofstream &filestream, bool append=false, bool silent=false)
Open the given file for writing.
Definition file.h:18
ExportJsonType buildAutomataArray(std::vector< storm::jani::Automaton > const &automata, std::map< uint64_t, std::string > const &actionNames, std::vector< storm::jani::Constant > const &constants, VariableSet const &globalVariables, bool commentExpressions)
ExportJsonType buildEdge(Edge const &edge, std::map< uint64_t, std::string > const &actionNames, std::map< uint64_t, std::string > const &locationNames, std::vector< storm::jani::Constant > const &constants, VariableSet const &globalVariables, VariableSet const &localVariables, bool commentExpressions)
ExportJsonType buildTypeDescription(storm::expressions::Type const &type)
ExportJsonType buildFunctionsArray(std::unordered_map< std::string, FunctionDefinition > const &functionDefinitions, std::vector< storm::jani::Constant > const &constants, VariableSet const &globalVariables, VariableSet const &localVariables=VariableSet())
ExportJsonType convertFilterExpression(storm::jani::FilterExpression const &fe, storm::jani::Model const &model, storm::jani::ModelFeatures &modelFeatures)
storm::json< storm::RationalNumber > ExportJsonType
ExportJsonType buildDestinations(std::vector< EdgeDestination > const &destinations, std::map< uint64_t, std::string > const &locationNames, std::vector< storm::jani::Constant > const &constants, VariableSet const &globalVariables, VariableSet const &localVariables, bool commentExpressions)
std::string comparisonTypeToJani(storm::logic::ComparisonType ct)
ExportJsonType buildLValue(storm::jani::LValue const &lValue, std::vector< storm::jani::Constant > const &constants, VariableSet const &globalVariables, VariableSet const &localVariables)
ExportJsonType buildAssignmentArray(storm::jani::OrderedAssignments const &orderedAssignments, std::vector< storm::jani::Constant > const &constants, VariableSet const &globalVariables, VariableSet const &localVariables, bool commentExpressions)
ExportJsonType buildInitialLocations(storm::jani::Automaton const &automaton)
ExportJsonType buildActionArray(std::vector< storm::jani::Action > const &actions)
ExportJsonType buildExpression(storm::expressions::Expression const &exp, std::vector< storm::jani::Constant > const &constants, VariableSet const &globalVariables=VariableSet(), VariableSet const &localVariables=VariableSet(), std::unordered_set< std::string > const &auxiliaryVariables={})
ExportJsonType buildType(storm::jani::JaniType const &type, std::vector< storm::jani::Constant > const &constants, VariableSet const &globalVariables, VariableSet const &localVariables=VariableSet())
ExportJsonType buildConstantsArray(std::vector< storm::jani::Constant > const &constants)
std::string to_string(ModelType const &type)
Definition ModelType.cpp:10
std::string janiFilterTypeString(storm::modelchecker::FilterType const &ft)
storm::expressions::Expression reduceNestingInJaniExpression(storm::expressions::Expression const &expression)
ExportJsonType anyToJson(boost::any &&input)
ExportJsonType buildEdges(std::vector< Edge > const &edges, std::map< uint64_t, std::string > const &actionNames, std::map< uint64_t, std::string > const &locationNames, std::vector< storm::jani::Constant > const &constants, VariableSet const &globalVariables, VariableSet const &localVariables, bool commentExpressions)
ExportJsonType buildVariablesArray(storm::jani::VariableSet const &varSet, std::vector< storm::jani::Constant > const &constants, VariableSet const &globalVariables, VariableSet const &localVariables=VariableSet())
ExportJsonType buildLocationsArray(std::vector< storm::jani::Location > const &locations, std::vector< storm::jani::Constant > const &constants, VariableSet const &globalVariables, VariableSet const &localVariables, bool commentExpressions)
std::string operatorTypeToJaniString(storm::expressions::OperatorType optype)
void getBoundsFromConstraints(ExportJsonType &typeDesc, storm::expressions::Variable const &var, storm::expressions::Expression const &constraint, std::vector< storm::jani::Constant > const &constants)
bool isLowerBound(ComparisonType t)
bool constexpr minimize(OptimizationDirection d)
bool isOne(ValueType const &a)
Definition constants.cpp:34
std::pair< ValueType, ValueType > asFraction(ValueType const &number)
bool isJsonNumberExportAccurate(storm::json< ValueType > const &j)
std::string dumpJson(storm::json< ValueType > const &j, bool compact)
Dumps the given json object, producing a String.
ComparisonType comparisonType
Definition Bound.h:18