Storm 1.14.0.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());
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(storm::logic::EventuallyFormula::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.
312 storm::logic::RewardAccumulation rewAcc(model.isDiscreteTimeModel(), !model.isDiscreteTimeModel(), false);
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(storm::logic::NextFormula::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 {
517 if (model.getGlobalVariables().getNumberOfRealTransientVariables() == 1) {
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"] =
604 buildExpression(f.getSubformula().asInstantaneousRewardFormula().getBound(), model.getConstants(), model.getGlobalVariables());
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::WeakUntilFormula const& f, boost::any const& data) const {
653 ExportJsonType opDecl;
654 opDecl["op"] = "W";
655 opDecl["left"] = anyToJson(f.getLeftSubformula().accept(*this, data));
656 opDecl["right"] = anyToJson(f.getRightSubformula().accept(*this, data));
657 return opDecl;
658}
659
660boost::any FormulaToJaniJson::visit(storm::logic::ReleaseFormula const& f, boost::any const& data) const {
661 ExportJsonType opDecl;
662 opDecl["op"] = "R";
663 opDecl["left"] = anyToJson(f.getLeftSubformula().accept(*this, data));
664 opDecl["right"] = anyToJson(f.getRightSubformula().accept(*this, data));
665 return opDecl;
666}
667
668boost::any FormulaToJaniJson::visit(storm::logic::HOAPathFormula const&, boost::any const&) const {
669 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Jani currently does not support HOA path formulae.");
670}
671
673 STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Jani currently does not support discounted cumulative reward formulae.");
674}
675
676boost::any FormulaToJaniJson::visit(storm::logic::DiscountedTotalRewardFormula const&, boost::any const&) const {
677 STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Jani currently does not support discounted total reward formulae.");
678}
679
682 switch (optype) {
683 case OpType::And:
684 return "∧";
685 case OpType::Or:
686 return "∨";
687 case OpType::Xor:
688 return "≠";
689 case OpType::Implies:
690 return "⇒";
691 case OpType::Iff:
692 return "=";
693 case OpType::Plus:
694 return "+";
695 case OpType::Minus:
696 return "-";
697 case OpType::Times:
698 return "*";
699 case OpType::Divide:
700 return "/";
701 case OpType::Min:
702 return "min";
703 case OpType::Max:
704 return "max";
705 case OpType::Power:
706 return "pow";
707 case OpType::Modulo:
708 return "%";
709 case OpType::Logarithm:
710 return "log";
711 case OpType::Equal:
712 return "=";
713 case OpType::NotEqual:
714 return "≠";
715 case OpType::Less:
716 return "<";
717 case OpType::LessOrEqual:
718 return "≤";
719 case OpType::Greater:
720 return ">";
721 case OpType::GreaterOrEqual:
722 return "≥";
723 case OpType::Not:
724 return "¬";
725 case OpType::Floor:
726 return "floor";
727 case OpType::Ceil:
728 return "ceil";
729 case OpType::Ite:
730 return "ite";
731 case OpType::Sin:
732 return "sin";
733 case OpType::Cos:
734 return "cos";
735 default:
736 STORM_LOG_THROW(false, storm::exceptions::InvalidJaniException, "Operator not supported by Jani.");
737 }
738}
739
740ExportJsonType ExpressionToJson::translate(storm::expressions::Expression const& expr, std::vector<storm::jani::Constant> const& constants,
741 VariableSet const& globalVariables, VariableSet const& localVariables,
742 std::unordered_set<std::string> const& auxiliaryVariables) {
743 // Simplify the expression first and reduce the nesting
744 auto simplifiedExpr = storm::jani::reduceNestingInJaniExpression(expr.simplify());
745
746 ExpressionToJson visitor(constants, globalVariables, localVariables, auxiliaryVariables);
747 return anyToJson(simplifiedExpr.accept(visitor, boost::none));
748}
749
750boost::any ExpressionToJson::visit(storm::expressions::IfThenElseExpression const& expression, boost::any const& data) {
751 ExportJsonType opDecl;
752 opDecl["op"] = "ite";
753 opDecl["if"] = anyToJson(expression.getCondition()->accept(*this, data));
754 opDecl["then"] = anyToJson(expression.getThenExpression()->accept(*this, data));
755 opDecl["else"] = anyToJson(expression.getElseExpression()->accept(*this, data));
756 return opDecl;
757}
758boost::any ExpressionToJson::visit(storm::expressions::BinaryBooleanFunctionExpression const& expression, boost::any const& data) {
759 ExportJsonType opDecl;
760 opDecl["op"] = operatorTypeToJaniString(expression.getOperator());
761 opDecl["left"] = anyToJson(expression.getOperand(0)->accept(*this, data));
762 opDecl["right"] = anyToJson(expression.getOperand(1)->accept(*this, data));
763 return opDecl;
764}
765boost::any ExpressionToJson::visit(storm::expressions::BinaryNumericalFunctionExpression 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 if (expression.getOperator() == storm::expressions::OperatorType::Power && expression.getType().isIntegerType()) {
771 // power expressions that have integer type need to be "type casted"
772 ExportJsonType trc;
773 trc["op"] = "trc";
774 trc["exp"] = std::move(opDecl);
775 return trc;
776 } else {
777 return opDecl;
778 }
779}
780
781boost::any ExpressionToJson::visit(storm::expressions::BinaryRelationExpression const& expression, boost::any const& data) {
782 ExportJsonType opDecl;
783 opDecl["op"] = operatorTypeToJaniString(expression.getOperator());
784 opDecl["left"] = anyToJson(expression.getOperand(0)->accept(*this, data));
785 opDecl["right"] = anyToJson(expression.getOperand(1)->accept(*this, data));
786 return opDecl;
787}
788boost::any ExpressionToJson::visit(storm::expressions::VariableExpression const& expression, boost::any const&) {
789 if (auxiliaryVariables.count(expression.getVariableName())) {
790 return ExportJsonType(expression.getVariableName());
791 } else if (globalVariables.hasVariable(expression.getVariable())) {
792 return ExportJsonType(globalVariables.getVariable(expression.getVariable()).getName());
793 } else if (localVariables.hasVariable(expression.getVariable())) {
794 return ExportJsonType(localVariables.getVariable(expression.getVariable()).getName());
795 } else {
796 for (auto const& constant : constants) {
797 if (constant.getExpressionVariable() == expression.getVariable()) {
798 return ExportJsonType(constant.getName());
799 }
800 }
801 }
802 STORM_LOG_THROW(false, storm::exceptions::InvalidJaniException,
803 "Expression variable '" << expression.getVariableName() << "' not known in Jani data structures.");
804 return ExportJsonType(); // should not reach this point.
805}
806boost::any ExpressionToJson::visit(storm::expressions::UnaryBooleanFunctionExpression const& expression, boost::any const& data) {
807 ExportJsonType opDecl;
808 opDecl["op"] = operatorTypeToJaniString(expression.getOperator());
809 opDecl["exp"] = anyToJson(expression.getOperand()->accept(*this, data));
810 return opDecl;
811}
812boost::any ExpressionToJson::visit(storm::expressions::UnaryNumericalFunctionExpression const& expression, boost::any const& data) {
813 ExportJsonType opDecl;
814 opDecl["op"] = operatorTypeToJaniString(expression.getOperator());
816 opDecl["left"] = 0;
817 opDecl["right"] = anyToJson(expression.getOperand()->accept(*this, data));
818 } else {
819 opDecl["exp"] = anyToJson(expression.getOperand()->accept(*this, data));
820 }
821 return opDecl;
822}
823
824boost::any ExpressionToJson::visit(storm::expressions::BooleanLiteralExpression const& expression, boost::any const&) {
825 return ExportJsonType(expression.getValue());
826}
827boost::any ExpressionToJson::visit(storm::expressions::IntegerLiteralExpression const& expression, boost::any const&) {
828 return ExportJsonType(expression.getValue());
829}
830boost::any ExpressionToJson::visit(storm::expressions::RationalLiteralExpression const& expression, boost::any const&) {
831 ExportJsonType val(expression.getValue());
832
834 // Try if exact export is possible as fraction of two literals
835 auto const& value = expression.getValue();
837 if (!storm::utility::isOne(den)) {
839 ExportJsonType numJson(num), denJson(den);
841 val = ExportJsonType();
843 val["left"] = std::move(numJson);
844 val["right"] = std::move(denJson);
845 }
846 }
847 }
848 return val;
849}
850
851boost::any ExpressionToJson::visit(storm::expressions::ValueArrayExpression const& expression, boost::any const& data) {
852 ExportJsonType opDecl;
853 opDecl["op"] = "av";
854 std::vector<ExportJsonType> elements;
855 uint64_t size = expression.size()->evaluateAsInt();
856 for (uint64_t i = 0; i < size; ++i) {
857 elements.push_back(anyToJson(expression.at(i)->accept(*this, data)));
858 }
859 opDecl["elements"] = std::move(elements);
860 return opDecl;
861}
862
863boost::any ExpressionToJson::visit(storm::expressions::ConstructorArrayExpression const& expression, boost::any const& data) {
864 ExportJsonType opDecl;
865 opDecl["op"] = "ac";
866 opDecl["var"] = expression.getIndexVar().getName();
867 opDecl["length"] = anyToJson(expression.size()->accept(*this, data));
868 bool inserted = auxiliaryVariables.insert(expression.getIndexVar().getName()).second;
869 opDecl["exp"] = anyToJson(expression.getElementExpression()->accept(*this, data));
870 if (inserted) {
871 auxiliaryVariables.erase(expression.getIndexVar().getName());
872 }
873 return opDecl;
874}
875
876boost::any ExpressionToJson::visit(storm::expressions::ArrayAccessExpression const& expression, boost::any const& data) {
877 ExportJsonType opDecl;
878 opDecl["op"] = "aa";
879 opDecl["exp"] = anyToJson(expression.getOperand(0)->accept(*this, data));
880 opDecl["index"] = anyToJson(expression.getOperand(1)->accept(*this, data));
881 return opDecl;
882}
883
884boost::any ExpressionToJson::visit(storm::expressions::FunctionCallExpression const& expression, boost::any const& data) {
885 ExportJsonType opDecl;
886 opDecl["op"] = "call";
887 opDecl["function"] = expression.getFunctionIdentifier();
888 std::vector<ExportJsonType> arguments;
889 for (uint64_t i = 0; i < expression.getNumberOfArguments(); ++i) {
890 arguments.push_back(anyToJson(expression.getArgument(i)->accept(*this, data)));
891 }
892 opDecl["args"] = std::move(arguments);
893 return opDecl;
894}
895
897 ExportJsonType constantDecl;
898 constantDecl["constant"] = expression.asString();
899 return constantDecl;
900}
901
902void JsonExporter::toFile(storm::jani::Model const& janiModel, std::vector<storm::jani::Property> const& formulas, std::string const& filepath, bool checkValid,
903 bool compact) {
904 std::ofstream stream;
905 storm::io::openFile(filepath, stream, false, true);
906 toStream(janiModel, formulas, stream, checkValid, compact);
907 storm::io::closeFile(stream);
908}
909
910void JsonExporter::toStream(storm::jani::Model const& janiModel, std::vector<storm::jani::Property> const& formulas, std::ostream& os, bool checkValid,
911 bool compact) {
912 if (checkValid) {
913 janiModel.checkValid();
914 }
915 JsonExporter exporter;
916 STORM_LOG_INFO("Started to convert model " << janiModel.getName() << ".");
917 exporter.convertModel(janiModel, !compact);
918 STORM_LOG_INFO("Started to convert properties of model " << janiModel.getName() << ".");
919 exporter.convertProperties(formulas, janiModel);
920 STORM_LOG_INFO("Producing json output... " << janiModel.getName() << ".");
921 os << storm::dumpJson(exporter.finalize(), compact) << '\n';
922 STORM_LOG_INFO("Conversion completed " << janiModel.getName() << ".");
923}
924
925ExportJsonType buildActionArray(std::vector<storm::jani::Action> const& actions) {
926 std::vector<ExportJsonType> actionReprs;
927 uint64_t actIndex = 0;
928 for (auto const& act : actions) {
930 actIndex++;
931 continue;
932 }
933 actIndex++;
934 ExportJsonType actEntry;
935 actEntry["name"] = act.getName();
936 actionReprs.push_back(actEntry);
937 }
938
939 return ExportJsonType(actionReprs);
940}
941
943 ExportJsonType typeDescr;
944 if (type.isIntegerType()) {
945 typeDescr = "int";
946 } else if (type.isRationalType()) {
947 typeDescr = "real";
948 } else if (type.isBooleanType()) {
949 typeDescr = "bool";
950 } else if (type.isArrayType()) {
951 typeDescr["kind"] = "array";
952 typeDescr["base"] = buildTypeDescription(type.getElementType());
953 } else {
954 STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentException, "Unknown expression type.");
955 }
956 return typeDescr;
957}
958
960 std::vector<storm::jani::Constant> const& constants) {
963 getBoundsFromConstraints(typeDesc, var, constraint.getBaseExpression().getOperand(0), constants);
964 getBoundsFromConstraints(typeDesc, var, constraint.getBaseExpression().getOperand(1), constants);
965 } else if (constraint.getBaseExpression().isBinaryRelationExpression()) {
968 std::vector<bool> varOps(2, false);
969 for (int i : {0, 1}) {
970 varOps[i] = constraint.getOperand(i).isVariable() && constraint.getOperand(i).getBaseExpression().asVariableExpression().getVariable() == var;
971 }
972 storm::expressions::Expression boundExpr = varOps[0] ? constraint.getOperand(1) : constraint.getOperand(0);
973 if ((leq && varOps[0]) || (geq && varOps[1])) {
974 typeDesc["upper-bound"] = buildExpression(boundExpr, constants);
975 } else if ((leq && varOps[1]) || (geq && varOps[0])) {
976 typeDesc["lower-bound"] = buildExpression(boundExpr, constants);
977 } else {
978 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Jani Export for constant constraint " << constraint << " is not supported.");
979 }
980 } else {
981 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Jani Export for constant constraint " << constraint << " is not supported.");
982 }
983}
984
985ExportJsonType buildConstantsArray(std::vector<storm::jani::Constant> const& constants) {
986 std::vector<ExportJsonType> constantDeclarations;
987 for (auto const& constant : constants) {
988 ExportJsonType constantEntry;
989 constantEntry["name"] = constant.getName();
990 ExportJsonType typeDesc;
991 if (constant.hasConstraint()) {
992 typeDesc["kind"] = "bounded";
993 typeDesc["base"] = buildTypeDescription(constant.getType());
994 getBoundsFromConstraints(typeDesc, constant.getExpressionVariable(), constant.getConstraintExpression(), constants);
995 } else {
996 typeDesc = buildTypeDescription(constant.getType());
997 }
998 constantEntry["type"] = typeDesc;
999 if (constant.isDefined()) {
1000 constantEntry["value"] = buildExpression(constant.getExpression(), constants);
1001 }
1002 constantDeclarations.push_back(constantEntry);
1003 }
1004 return ExportJsonType(constantDeclarations);
1005}
1006
1007ExportJsonType buildType(storm::jani::JaniType const& type, std::vector<storm::jani::Constant> const& constants, VariableSet const& globalVariables,
1008 VariableSet const& localVariables = VariableSet()) {
1009 ExportJsonType typeDesc;
1010 if (type.isBasicType() || type.isClockType() || type.isContinuousType()) {
1011 typeDesc = type.getStringRepresentation();
1012 } else if (type.isBoundedType()) {
1013 typeDesc["kind"] = "bounded";
1014 auto const& bndType = type.asBoundedType();
1015 switch (bndType.getBaseType()) {
1017 typeDesc["base"] = "int";
1018 break;
1020 typeDesc["base"] = "real";
1021 break;
1022 }
1023 if (bndType.hasLowerBound()) {
1024 typeDesc["lower-bound"] = buildExpression(bndType.getLowerBound(), constants, globalVariables, localVariables);
1025 }
1026 if (bndType.hasUpperBound()) {
1027 typeDesc["upper-bound"] = buildExpression(bndType.getUpperBound(), constants, globalVariables, localVariables);
1028 }
1029 } else if (type.isArrayType()) {
1030 typeDesc["kind"] = "array";
1031 typeDesc["base"] = buildType(type.asArrayType().getBaseType(), constants, globalVariables, localVariables);
1032 } else {
1033 STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "Variable type not recognized in JSONExporter.");
1034 }
1035 return typeDesc;
1036}
1037
1038ExportJsonType buildVariablesArray(storm::jani::VariableSet const& varSet, std::vector<storm::jani::Constant> const& constants,
1039 VariableSet const& globalVariables, VariableSet const& localVariables = VariableSet()) {
1040 ExportJsonType variableDeclarations = std::vector<ExportJsonType>();
1041 for (auto const& variable : varSet) {
1042 ExportJsonType varEntry;
1043 varEntry["name"] = variable.getName();
1044 if (variable.isTransient()) {
1045 varEntry["transient"] = variable.isTransient();
1046 }
1047 varEntry["type"] = buildType(variable.getType(), constants, globalVariables, localVariables);
1048 if (variable.hasInitExpression()) {
1049 varEntry["initial-value"] = buildExpression(variable.getInitExpression(), constants, globalVariables, localVariables);
1050 }
1051 variableDeclarations.push_back(std::move(varEntry));
1052 }
1053 return variableDeclarations;
1054}
1055
1056ExportJsonType buildFunctionsArray(std::unordered_map<std::string, FunctionDefinition> const& functionDefinitions,
1057 std::vector<storm::jani::Constant> const& constants, VariableSet const& globalVariables,
1058 VariableSet const& localVariables = VariableSet()) {
1059 ExportJsonType functionDeclarations = std::vector<ExportJsonType>();
1060 for (auto const& nameFunDef : functionDefinitions) {
1061 storm::jani::FunctionDefinition const& funDef = nameFunDef.second;
1062 ExportJsonType funDefJson;
1063 funDefJson["name"] = nameFunDef.first;
1064 funDefJson["type"] = buildTypeDescription(funDef.getType());
1065 std::vector<ExportJsonType> parameterDeclarations;
1066 std::unordered_set<std::string> parameterNames;
1067 for (auto const& p : funDef.getParameters()) {
1068 ExportJsonType parDefJson;
1069 parDefJson["name"] = p.getName();
1070 parameterNames.insert(p.getName());
1071 parDefJson["type"] = buildTypeDescription(p.getType());
1072 parameterDeclarations.push_back(parDefJson);
1073 }
1074 funDefJson["parameters"] = parameterDeclarations;
1075 funDefJson["body"] = buildExpression(funDef.getFunctionBody(), constants, globalVariables, localVariables, parameterNames);
1076 functionDeclarations.push_back(std::move(funDefJson));
1077 }
1078 return functionDeclarations;
1079}
1080
1081ExportJsonType buildLValue(storm::jani::LValue const& lValue, std::vector<storm::jani::Constant> const& constants, VariableSet const& globalVariables,
1082 VariableSet const& localVariables) {
1083 if (lValue.isVariable()) {
1084 return lValue.getVariable().getName();
1085 } else {
1086 STORM_LOG_ASSERT(lValue.isArrayAccess(), "Unhandled LValue " << lValue << ".");
1087 ExportJsonType result = lValue.getVariable().getName();
1088 for (auto const& indexExpr : lValue.getArrayIndexVector()) {
1089 ExportJsonType newResult;
1090 newResult["op"] = "aa";
1091 newResult["exp"] = std::move(result);
1092 newResult["index"] = buildExpression(indexExpr, constants, globalVariables, localVariables);
1093 result = std::move(newResult);
1094 }
1095 return result;
1096 }
1097}
1098
1099ExportJsonType buildAssignmentArray(storm::jani::OrderedAssignments const& orderedAssignments, std::vector<storm::jani::Constant> const& constants,
1100 VariableSet const& globalVariables, VariableSet const& localVariables, bool commentExpressions) {
1101 ExportJsonType assignmentDeclarations = std::vector<ExportJsonType>();
1102 bool addIndex = orderedAssignments.hasMultipleLevels();
1103 for (auto const& assignment : orderedAssignments) {
1104 ExportJsonType assignmentEntry;
1105 assignmentEntry["ref"] = buildLValue(assignment.getLValue(), constants, globalVariables, localVariables);
1106 assignmentEntry["value"] = buildExpression(assignment.getAssignedExpression(), constants, globalVariables, localVariables);
1107 if (addIndex) {
1108 assignmentEntry["index"] = assignment.getLevel();
1109 }
1110 if (commentExpressions) {
1111 assignmentEntry["comment"] = assignment.getLValue().getName() + " <- " + assignment.getAssignedExpression().toString();
1112 }
1113 assignmentDeclarations.push_back(std::move(assignmentEntry));
1114 }
1115 return assignmentDeclarations;
1116}
1117
1118ExportJsonType buildLocationsArray(std::vector<storm::jani::Location> const& locations, std::vector<storm::jani::Constant> const& constants,
1119 VariableSet const& globalVariables, VariableSet const& localVariables, bool commentExpressions) {
1120 ExportJsonType locationDeclarations = std::vector<ExportJsonType>();
1121 for (auto const& location : locations) {
1122 ExportJsonType locEntry;
1123 locEntry["name"] = location.getName();
1124 if (location.hasTimeProgressInvariant()) {
1125 ExportJsonType timeProg;
1126 timeProg["exp"] = buildExpression(location.getTimeProgressInvariant(), constants, globalVariables, localVariables);
1127 if (commentExpressions) {
1128 timeProg["comment"] = location.getTimeProgressInvariant().toString();
1129 }
1130 locEntry["time-progress"] = std::move(timeProg);
1131 }
1132 if (!location.getAssignments().empty()) {
1133 locEntry["transient-values"] = buildAssignmentArray(location.getAssignments(), constants, globalVariables, localVariables, commentExpressions);
1134 }
1135 locationDeclarations.push_back(std::move(locEntry));
1136 }
1137 return locationDeclarations;
1138}
1139
1141 std::vector<std::string> names;
1142 for (auto const& initLocIndex : automaton.getInitialLocationIndices()) {
1143 names.push_back(automaton.getLocation(initLocIndex).getName());
1144 }
1145 return ExportJsonType(names);
1146}
1147
1148ExportJsonType buildDestinations(std::vector<EdgeDestination> const& destinations, std::map<uint64_t, std::string> const& locationNames,
1149 std::vector<storm::jani::Constant> const& constants, VariableSet const& globalVariables, VariableSet const& localVariables,
1150 bool commentExpressions) {
1151 STORM_LOG_ASSERT(destinations.size() > 0, "Expected at least one destination.");
1152 ExportJsonType destDeclarations = std::vector<ExportJsonType>();
1153 for (auto const& destination : destinations) {
1154 ExportJsonType destEntry;
1155 destEntry["location"] = locationNames.at(destination.getLocationIndex());
1156 bool prob1 = false;
1157 if (destination.getProbability().isLiteral()) {
1158 if (storm::utility::isOne(destination.getProbability().evaluateAsRational())) {
1159 prob1 = true;
1160 }
1161 }
1162 if (!prob1) {
1163 destEntry["probability"]["exp"] = buildExpression(destination.getProbability(), constants, globalVariables, localVariables);
1164 if (commentExpressions) {
1165 destEntry["probability"]["comment"] = destination.getProbability().toString();
1166 }
1167 }
1168 if (!destination.getOrderedAssignments().empty()) {
1169 destEntry["assignments"] =
1170 buildAssignmentArray(destination.getOrderedAssignments(), constants, globalVariables, localVariables, commentExpressions);
1171 }
1172 destDeclarations.push_back(std::move(destEntry));
1173 }
1174 return destDeclarations;
1175}
1176
1177ExportJsonType buildEdge(Edge const& edge, std::map<uint64_t, std::string> const& actionNames, std::map<uint64_t, std::string> const& locationNames,
1178 std::vector<storm::jani::Constant> const& constants, VariableSet const& globalVariables, VariableSet const& localVariables,
1179 bool commentExpressions) {
1180 STORM_LOG_THROW(edge.getDestinations().size() > 0, storm::exceptions::InvalidJaniException, "An edge without destinations is not allowed.");
1181 ExportJsonType edgeEntry;
1182 edgeEntry["location"] = locationNames.at(edge.getSourceLocationIndex());
1183 if (!edge.hasSilentAction()) {
1184 edgeEntry["action"] = actionNames.at(edge.getActionIndex());
1185 }
1186 if (edge.hasRate()) {
1187 edgeEntry["rate"]["exp"] = buildExpression(edge.getRate(), constants, globalVariables, localVariables);
1188 if (commentExpressions) {
1189 edgeEntry["rate"]["comment"] = edge.getRate().toString();
1190 }
1191 }
1192 if (!edge.getGuard().isTrue()) {
1193 edgeEntry["guard"]["exp"] = buildExpression(edge.getGuard(), constants, globalVariables, localVariables);
1194 if (commentExpressions) {
1195 edgeEntry["guard"]["comment"] = edge.getGuard().toString();
1196 }
1197 }
1198 edgeEntry["destinations"] = buildDestinations(edge.getDestinations(), locationNames, constants, globalVariables, localVariables, commentExpressions);
1199 if (!edge.getAssignments().empty()) {
1200 edgeEntry["assignments"] = buildAssignmentArray(edge.getAssignments(), constants, globalVariables, localVariables, commentExpressions);
1201 }
1202 return edgeEntry;
1203}
1204
1205ExportJsonType buildEdges(std::vector<Edge> const& edges, std::map<uint64_t, std::string> const& actionNames,
1206 std::map<uint64_t, std::string> const& locationNames, std::vector<storm::jani::Constant> const& constants,
1207 VariableSet const& globalVariables, VariableSet const& localVariables, bool commentExpressions) {
1208 ExportJsonType edgeDeclarations = std::vector<ExportJsonType>();
1209 for (auto const& edge : edges) {
1210 if (edge.getGuard().isFalse()) {
1211 continue;
1212 }
1213 edgeDeclarations.push_back(buildEdge(edge, actionNames, locationNames, constants, globalVariables, localVariables, commentExpressions));
1214 }
1215 return edgeDeclarations;
1216}
1217
1218ExportJsonType buildAutomataArray(std::vector<storm::jani::Automaton> const& automata, std::map<uint64_t, std::string> const& actionNames,
1219 std::vector<storm::jani::Constant> const& constants, VariableSet const& globalVariables, bool commentExpressions) {
1220 ExportJsonType automataDeclarations = std::vector<ExportJsonType>();
1221 for (auto const& automaton : automata) {
1222 ExportJsonType autoEntry;
1223 autoEntry["name"] = automaton.getName();
1224 autoEntry["variables"] = buildVariablesArray(automaton.getVariables(), constants, globalVariables, automaton.getVariables());
1225 if (!automaton.getFunctionDefinitions().empty()) {
1226 autoEntry["functions"] = buildFunctionsArray(automaton.getFunctionDefinitions(), constants, globalVariables, automaton.getVariables());
1227 }
1228 if (automaton.hasRestrictedInitialStates()) {
1229 autoEntry["restrict-initial"]["exp"] =
1230 buildExpression(automaton.getInitialStatesRestriction(), constants, globalVariables, automaton.getVariables());
1231 }
1232 autoEntry["locations"] = buildLocationsArray(automaton.getLocations(), constants, globalVariables, automaton.getVariables(), commentExpressions);
1233 autoEntry["initial-locations"] = buildInitialLocations(automaton);
1234 autoEntry["edges"] = buildEdges(automaton.getEdges(), actionNames, automaton.buildIdToLocationNameMap(), constants, globalVariables,
1235 automaton.getVariables(), commentExpressions);
1236 automataDeclarations.push_back(std::move(autoEntry));
1237 }
1238 return automataDeclarations;
1239}
1240
1241void JsonExporter::convertModel(storm::jani::Model const& janiModel, bool commentExpressions) {
1242 modelFeatures = janiModel.getModelFeatures();
1243 jsonStruct["jani-version"] = janiModel.getJaniVersion();
1244 jsonStruct["name"] = janiModel.getName();
1245 jsonStruct["type"] = to_string(janiModel.getModelType());
1246 jsonStruct["actions"] = buildActionArray(janiModel.getActions());
1247 jsonStruct["constants"] = buildConstantsArray(janiModel.getConstants());
1248 jsonStruct["variables"] = buildVariablesArray(janiModel.getGlobalVariables(), janiModel.getConstants(), janiModel.getGlobalVariables());
1249 if (!janiModel.getGlobalFunctionDefinitions().empty()) {
1250 jsonStruct["functions"] = buildFunctionsArray(janiModel.getGlobalFunctionDefinitions(), janiModel.getConstants(), janiModel.getGlobalVariables());
1251 }
1252 jsonStruct["restrict-initial"]["exp"] = buildExpression(janiModel.getInitialStatesRestriction(), janiModel.getConstants(), janiModel.getGlobalVariables());
1253 jsonStruct["automata"] = buildAutomataArray(janiModel.getAutomata(), janiModel.getActionIndexToNameMap(), janiModel.getConstants(),
1254 janiModel.getGlobalVariables(), commentExpressions);
1255 jsonStruct["system"] = CompositionJsonExporter::translate(janiModel.getSystemComposition());
1256}
1257
1258ExportJsonType JsonExporter::getEdgeAsJson(storm::jani::Model const& janiModel, uint64_t automatonIndex, uint64_t edgeIndex, bool commentExpressions) {
1259 auto const& automaton = janiModel.getAutomaton(automatonIndex);
1260 return buildEdge(automaton.getEdge(edgeIndex), janiModel.getActionIndexToNameMap(), automaton.buildIdToLocationNameMap(), janiModel.getConstants(),
1261 janiModel.getGlobalVariables(), automaton.getVariables(), commentExpressions);
1262}
1263
1265 switch (ft) {
1267 return "min";
1269 return "max";
1271 return "sum";
1273 return "avg";
1275 return "count";
1277 return "∃";
1279 return "∀";
1281 return "argmin";
1283 return "argmax";
1285 return "values";
1286 }
1287 STORM_LOG_THROW(false, storm::exceptions::IllegalArgumentException, "Unknown FilterType.");
1288}
1289
1291 ExportJsonType propDecl;
1292 propDecl["states"]["op"] = "initial";
1293 propDecl["op"] = "filter";
1294 propDecl["fun"] = janiFilterTypeString(fe.getFilterType());
1295 propDecl["values"] = FormulaToJaniJson::translate(*fe.getFormula(), model, modelFeatures);
1296 return propDecl;
1297}
1298
1299void JsonExporter::convertProperties(std::vector<storm::jani::Property> const& formulas, storm::jani::Model const& model) {
1300 ExportJsonType properties;
1301
1302 // For now, unset model-features that only relate to properties.
1303 // If such properties actually exist, these features will be re-added during formula conversion below.
1306 if (formulas.empty()) {
1307 jsonStruct["properties"] = ExportJsonType(ExportJsonType::value_t::array);
1308 return;
1309 }
1310
1311 for (auto const& f : formulas) {
1312 ExportJsonType propDecl;
1313 propDecl["name"] = f.getName();
1314 propDecl["expression"] = convertFilterExpression(f.getFilter(), model, modelFeatures);
1315 properties.push_back(std::move(propDecl));
1316 }
1317 jsonStruct["properties"] = std::move(properties);
1318}
1319
1320ExportJsonType JsonExporter::finalize() {
1321 jsonStruct["features"] = ExportJsonType::parse(modelFeatures.toString());
1322 return jsonStruct;
1323}
1324
1325} // namespace jani
1326} // 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:230
bool isBooleanType() const
Checks whether this type is a boolean type.
Definition Type.cpp:194
bool isIntegerType() const
Checks whether this type is an integral type.
Definition Type.cpp:198
bool isArrayType() const
Checks whether this type is an array type.
Definition Type.cpp:210
bool isRationalType() const
Checks whether this type is a rational type.
Definition Type.cpp:234
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
ModelFeatures & add(ModelFeature const &modelFeature)
void remove(ModelFeature const &modelFeature)
VariableSet & getGlobalVariables()
Retrieves the variables of this automaton.
Definition Model.cpp:717
Composition const & getSystemComposition() const
Retrieves the system composition expression.
Definition Model.cpp:945
storm::expressions::Expression const & getInitialStatesRestriction() const
Gets the expression restricting the legal initial values of the global variables.
Definition Model.cpp:1299
static const uint64_t SILENT_ACTION_INDEX
The index of the silent action.
Definition Model.h:658
std::vector< Automaton > & getAutomata()
Retrieves the automata of the model.
Definition Model.cpp:868
ModelType const & getModelType() const
Retrieves the type of the model.
Definition Model.cpp:117
std::vector< Constant > const & getConstants() const
Retrieves the constants of the model.
Definition Model.cpp:685
std::vector< Action > const & getActions() const
Retrieves the actions of the model.
Definition Model.cpp:642
uint64_t getJaniVersion() const
Retrieves the JANI-version of the model.
Definition Model.cpp:113
void checkValid() const
Checks if the model is valid JANI, which should be verified before any further operations are applied...
Definition Model.cpp:1416
std::string const & getName() const
Retrieves the name of the model.
Definition Model.cpp:133
ModelFeatures const & getModelFeatures() const
Retrieves the enabled model features.
Definition Model.cpp:125
Automaton & getAutomaton(std::string const &name)
Retrieves the automaton with the given name.
Definition Model.cpp:884
std::map< uint64_t, std::string > getActionIndexToNameMap() const
Builds a map with action indices mapped to their names.
Definition Model.cpp:1032
std::unordered_map< std::string, FunctionDefinition > const & getGlobalFunctionDefinitions() const
Retrieves all global function definitions.
Definition Model.cpp:777
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
storm::expressions::Expression const & getExpression() const
std::string const & getLabel() const
storm::logic::BinaryBooleanOperatorType OperatorType
storm::logic::BinaryBooleanOperatorType OperatorType
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:467
virtual bool isInstantaneousRewardFormula() const
Definition Formula.cpp:166
static std::shared_ptr< Formula const > getTrueFormula()
Definition Formula.cpp:227
LongRunAverageRewardFormula & asLongRunAverageRewardFormula()
Definition Formula.cpp:498
virtual bool isCumulativeRewardFormula() const
Definition Formula.cpp:158
virtual bool isLongRunAverageRewardFormula() const
Definition Formula.cpp:174
EventuallyFormula & asEventuallyFormula()
Definition Formula.cpp:371
InstantaneousRewardFormula & asInstantaneousRewardFormula()
Definition Formula.cpp:490
virtual bool isEventuallyFormula() const
Definition Formula.cpp:102
virtual bool isTotalRewardFormula() const
Definition Formula.cpp:178
CumulativeRewardFormula & asCumulativeRewardFormula()
Definition Formula.cpp:459
boost::any accept(FormulaVisitor const &visitor) const
Definition Formula.cpp:17
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:34
#define STORM_LOG_WARN(message)
Definition logging.h:35
#define STORM_LOG_TRACE(message)
Definition logging.h:22
#define STORM_LOG_ASSERT(cond, message)
Definition macros.h:9
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:39
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:39
NumberTraits< RationalType >::IntegerType denominator(RationalType const &number)
NumberTraits< RationalType >::IntegerType numerator(RationalType const &number)
TargetType convertNumber(SourceType 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:17