2#include <boost/algorithm/string.hpp>
4#ifdef STORM_HAVE_XERCES
17bool isOnlyWhitespace(std::string
const& in) {
18 return std::all_of(in.begin(), in.end(), [](
char c) { return std::isspace(static_cast<unsigned char>(c)); });
25GreatSpnEditorProjectParser::GreatSpnEditorProjectParser(std::string
const& constantDefinitionString)
27 if (constantDefinitionString !=
"") {
28 std::vector<std::string> constDefs;
29 boost::split(constDefs, constantDefinitionString, boost::is_any_of(
","));
30 for (
auto const& pair : constDefs) {
31 std::vector<std::string> keyvaluepair;
32 boost::split(keyvaluepair, pair, boost::is_any_of(
"="));
33 STORM_LOG_THROW(keyvaluepair.size() == 2, storm::exceptions::WrongFormatException,
34 "Expected a constant definition of the form N=42 but got " << pair);
35 constantDefinitions.emplace(keyvaluepair.at(0), keyvaluepair.at(1));
40storm::gspn::GSPN* GreatSpnEditorProjectParser::parse(xercesc::DOMElement
const* elementRoot) {
41 if (storm::adapters::XMLtoString(elementRoot->getTagName()) ==
"project") {
42 traverseProjectElement(elementRoot);
43 return builder.buildGspn(manager, constantsSubstitution);
46 STORM_LOG_THROW(
false, storm::exceptions::UnexpectedException,
"Failed to identify the root element.\n");
50void GreatSpnEditorProjectParser::traverseProjectElement(xercesc::DOMNode
const*
const node) {
52 for (uint_fast64_t i = 0;
i < node->getAttributes()->getLength(); ++
i) {
53 auto attr = node->getAttributes()->item(i);
54 auto name = storm::adapters::getName(attr);
56 if (name.compare(
"version") == 0 || name.compare(
"name") == 0) {
61 STORM_PRINT_AND_LOG(
"unknown attribute (node=" + storm::adapters::XMLtoString(node->getNodeName()) +
"): " + name +
"\n");
66 for (uint_fast64_t i = 0;
i < node->getChildNodes()->getLength(); ++
i) {
67 auto child = node->getChildNodes()->item(i);
68 auto name = storm::adapters::getName(child);
70 if (name.compare(
"gspn") == 0) {
71 traverseGspnElement(child);
72 }
else if (isOnlyWhitespace(name)) {
77 STORM_PRINT_AND_LOG(
"unknown child (node=" + storm::adapters::XMLtoString(node->getNodeName()) +
"): " + name +
"\n");
82void GreatSpnEditorProjectParser::traverseGspnElement(xercesc::DOMNode
const*
const node) {
84 for (uint_fast64_t i = 0;
i < node->getAttributes()->getLength(); ++
i) {
85 auto attr = node->getAttributes()->item(i);
86 auto name = storm::adapters::getName(attr);
88 if (name.compare(
"name") == 0) {
89 builder.setGspnName(storm::adapters::XMLtoString(attr->getNodeValue()));
90 }
else if (name.compare(
"show-color-cmd") == 0 || name.compare(
"show-fluid-cmd") == 0 || name.compare(
"zoom") == 0) {
95 STORM_PRINT_AND_LOG(
"unknown attribute (node=" + storm::adapters::XMLtoString(node->getNodeName()) +
"): " + name +
"\n");
100 for (uint_fast64_t i = 0;
i < node->getChildNodes()->getLength(); ++
i) {
101 auto child = node->getChildNodes()->item(i);
102 auto name = storm::adapters::getName(child);
104 if (name.compare(
"nodes") == 0) {
105 traverseNodesElement(child);
106 }
else if (name.compare(
"edges") == 0) {
107 traverseEdgesElement(child);
108 }
else if (isOnlyWhitespace(name)) {
113 STORM_PRINT_AND_LOG(
"unknown child (node=" + storm::adapters::XMLtoString(node->getNodeName()) +
"): " + name +
"\n");
118void GreatSpnEditorProjectParser::traverseNodesElement(xercesc::DOMNode
const*
const node) {
120 for (uint_fast64_t i = 0;
i < node->getAttributes()->getLength(); ++
i) {
121 auto attr = node->getAttributes()->item(i);
122 auto name = storm::adapters::getName(attr);
126 STORM_PRINT_AND_LOG(
"unknown attribute (node=" + storm::adapters::XMLtoString(node->getNodeName()) +
"): " + name +
"\n");
131 constantsSubstitution.clear();
132 expressionParser = std::make_shared<storm::parser::ExpressionParser>(*manager);
133 std::unordered_map<std::string, storm::expressions::Expression> identifierMapping;
134 expressionParser->setIdentifierMapping(identifierMapping);
135 for (uint_fast64_t i = 0;
i < node->getChildNodes()->getLength(); ++
i) {
136 auto child = node->getChildNodes()->item(i);
137 auto name = storm::adapters::getName(child);
138 if (name.compare(
"constant") == 0 || name.compare(
"template") == 0) {
139 traverseConstantOrTemplateElement(child);
143 expressionParser = std::make_shared<storm::parser::ExpressionParser>(*manager);
145 identifierMapping.emplace(var.getName(), var.getExpression());
147 expressionParser->setIdentifierMapping(identifierMapping);
149 for (uint_fast64_t i = 0;
i < node->getChildNodes()->getLength(); ++
i) {
150 auto child = node->getChildNodes()->item(i);
151 auto name = storm::adapters::getName(child);
153 if (name.compare(
"place") == 0) {
154 traversePlaceElement(child);
155 }
else if (name.compare(
"transition") == 0) {
156 traverseTransitionElement(child);
157 }
else if (name.compare(
"constant") == 0 || name.compare(
"template") == 0) {
159 }
else if (isOnlyWhitespace(name)) {
164 STORM_PRINT_AND_LOG(
"unknown child (node=" + storm::adapters::XMLtoString(node->getNodeName()) +
"): " + name +
"\n");
169void GreatSpnEditorProjectParser::traverseConstantOrTemplateElement(xercesc::DOMNode
const*
const node) {
170 std::string identifier;
172 std::string valueStr =
"";
175 for (uint_fast64_t i = 0;
i < node->getAttributes()->getLength(); ++
i) {
176 auto attr = node->getAttributes()->item(i);
177 auto name = storm::adapters::getName(attr);
179 if (name.compare(
"name") == 0) {
180 identifier = storm::adapters::XMLtoString(attr->getNodeValue());
181 }
else if (name.compare(
"consttype") == 0 || name.compare(
"type") == 0) {
182 if (storm::adapters::XMLtoString(attr->getNodeValue()).compare(
"REAL") == 0) {
183 type =
manager->getRationalType();
184 }
else if (storm::adapters::XMLtoString(attr->getNodeValue()).compare(
"INTEGER") == 0) {
185 type =
manager->getIntegerType();
187 STORM_PRINT_AND_LOG(
"Unknown consttype: " << storm::adapters::XMLtoString(attr->getNodeValue()) <<
'\n');
189 }
else if (name.compare(
"value") == 0) {
190 valueStr = storm::adapters::XMLtoString(attr->getNodeValue());
191 }
else if ((name ==
"x") || (name ==
"y")) {
196 STORM_PRINT_AND_LOG(
"unknown attribute (node=" + storm::adapters::XMLtoString(node->getNodeName()) +
"): " + name +
"\n");
201 "Multiple definitions of constant '" << identifier <<
"' were found.");
202 if (valueStr ==
"") {
203 auto constDef = constantDefinitions.find(identifier);
204 STORM_LOG_THROW(constDef != constantDefinitions.end(), storm::exceptions::NotSupportedException,
205 "Constant '" << identifier <<
"' has no value defined.");
206 valueStr = constDef->second;
210 var =
manager->declareRationalVariable(identifier);
211 expressionParser->setAcceptDoubleLiterals(
true);
213 var =
manager->declareIntegerVariable(identifier);
214 expressionParser->setAcceptDoubleLiterals(
false);
216 STORM_LOG_THROW(
false, storm::exceptions::NotSupportedException,
"Unknown type of constant" << type <<
".");
218 constantsSubstitution.emplace(var, expressionParser->parseFromString(valueStr));
221 for (uint_fast64_t i = 0;
i < node->getChildNodes()->getLength(); ++
i) {
222 auto child = node->getChildNodes()->item(i);
223 auto name = storm::adapters::getName(child);
225 if (isOnlyWhitespace(name)) {
230 STORM_PRINT_AND_LOG(
"unknown child (node=" + storm::adapters::XMLtoString(node->getNodeName()) +
"): " + name +
"\n");
235void GreatSpnEditorProjectParser::traverseEdgesElement(xercesc::DOMNode
const*
const node) {
237 for (uint_fast64_t i = 0;
i < node->getAttributes()->getLength(); ++
i) {
238 auto attr = node->getAttributes()->item(i);
239 auto name = storm::adapters::getName(attr);
243 STORM_PRINT_AND_LOG(
"unknown attribute (node=" + storm::adapters::XMLtoString(node->getNodeName()) +
"): " + name +
"\n");
247 for (uint_fast64_t i = 0;
i < node->getChildNodes()->getLength(); ++
i) {
248 auto child = node->getChildNodes()->item(i);
249 auto name = storm::adapters::getName(child);
251 if (name.compare(
"arc") == 0) {
252 traverseArcElement(child);
253 }
else if (isOnlyWhitespace(name)) {
258 STORM_PRINT_AND_LOG(
"unknown child (node=" + storm::adapters::XMLtoString(node->getNodeName()) +
"): " + name +
"\n");
263bool ignorePlaceAttribute(std::string
const& name) {
265 if ((name ==
"label-x") || (name ==
"label-y") || (name ==
"x") || (name ==
"y")) {
271void GreatSpnEditorProjectParser::traversePlaceElement(xercesc::DOMNode
const*
const node) {
273 std::string placeName;
274 uint64_t initialTokens = 0;
276 for (uint_fast64_t i = 0;
i < node->getAttributes()->getLength(); ++
i) {
277 auto attr = node->getAttributes()->item(i);
278 auto name = storm::adapters::getName(attr);
280 if (name.compare(
"name") == 0) {
281 placeName = storm::adapters::XMLtoString(attr->getNodeValue());
282 }
else if (name.compare(
"marking") == 0) {
283 initialTokens = parseInt(storm::adapters::XMLtoString(attr->getNodeValue()));
284 }
else if (ignorePlaceAttribute(name)) {
289 STORM_PRINT_AND_LOG(
"unknown attribute (node=" + storm::adapters::XMLtoString(node->getNodeName()) +
"): " + name +
"\n");
294 for (uint_fast64_t i = 0;
i < node->getChildNodes()->getLength(); ++
i) {
295 auto child = node->getChildNodes()->item(i);
296 auto name = storm::adapters::getName(child);
298 if (isOnlyWhitespace(name)) {
303 STORM_PRINT_AND_LOG(
"unknown child (node=" + storm::adapters::XMLtoString(node->getNodeName()) +
"): " + name +
"\n");
306 builder.addPlace(boost::none, initialTokens, placeName);
309bool ignoreTransitionAttribute(std::string
const& name) {
311 if ((name ==
"label-x") || (name ==
"label-y") || (name ==
"x") || (name ==
"y") || (name ==
"nservers-x") || (name ==
"delay-x") || (name ==
"delay-y") ||
312 (name ==
"rotation")) {
318void GreatSpnEditorProjectParser::traverseTransitionElement(xercesc::DOMNode
const*
const node) {
319 std::string transitionName;
320 bool immediateTransition;
323 uint64_t priority = 1;
324 boost::optional<uint64_t> numServers;
327 for (uint_fast64_t i = 0;
i < node->getAttributes()->getLength(); ++
i) {
328 auto attr = node->getAttributes()->item(i);
329 auto name = storm::adapters::getName(attr);
331 if (name.compare(
"name") == 0) {
332 transitionName = storm::adapters::XMLtoString(attr->getNodeValue());
333 }
else if (name.compare(
"type") == 0) {
334 if (storm::adapters::XMLtoString(attr->getNodeValue()).compare(
"EXP") == 0) {
335 immediateTransition =
false;
336 }
else if (storm::adapters::XMLtoString(attr->getNodeValue()).compare(
"IMM") == 0) {
337 immediateTransition =
true;
339 STORM_PRINT_AND_LOG(
"unknown transition type: " << storm::adapters::XMLtoString(attr->getNodeValue()));
341 }
else if (name.compare(
"delay") == 0) {
342 rate = parseReal(storm::adapters::XMLtoString(attr->getNodeValue()));
343 }
else if (name.compare(
"weight") == 0) {
344 weight = parseReal(storm::adapters::XMLtoString(attr->getNodeValue()));
345 }
else if (name.compare(
"priority") == 0) {
346 priority = parseInt(storm::adapters::XMLtoString(attr->getNodeValue()));
347 }
else if (name.compare(
"nservers") == 0) {
348 std::string nservers = storm::adapters::XMLtoString(attr->getNodeValue());
349 if (nservers ==
"Single") {
351 }
else if (nservers ==
"Infinite") {
354 numServers = parseInt(nservers);
356 }
else if (ignoreTransitionAttribute(name)) {
361 STORM_PRINT_AND_LOG(
"unknown attribute (node=" + storm::adapters::XMLtoString(node->getNodeName()) +
"): " + name +
"\n");
365 if (immediateTransition) {
366 builder.addImmediateTransition(priority, weight, transitionName);
368 builder.addTimedTransition(0, rate, numServers, transitionName);
372 for (uint_fast64_t i = 0;
i < node->getChildNodes()->getLength(); ++
i) {
373 auto child = node->getChildNodes()->item(i);
374 auto name = storm::adapters::getName(child);
376 if (isOnlyWhitespace(name)) {
381 STORM_PRINT_AND_LOG(
"unknown child (node=" + storm::adapters::XMLtoString(node->getNodeName()) +
"): " + name +
"\n");
386bool ignoreArcAttribute(std::string
const& name) {
387 if ((name ==
"mult-x") || (name ==
"mult-y") || (name ==
"mult-k")) {
393bool ignoreArcChild(std::string
const& name) {
394 if (name ==
"point") {
400void GreatSpnEditorProjectParser::traverseArcElement(xercesc::DOMNode
const*
const node) {
401 std::string head =
"____NOT_SET____";
402 std::string tail =
"____NOT_SET____";
403 std::string kind =
"____NOT_SET____";
404 uint_fast64_t mult = 1;
407 for (uint_fast64_t i = 0;
i < node->getAttributes()->getLength(); ++
i) {
408 auto attr = node->getAttributes()->item(i);
409 auto name = storm::adapters::getName(attr);
411 if (name.compare(
"head") == 0) {
412 head = storm::adapters::XMLtoString(attr->getNodeValue());
413 }
else if (name.compare(
"tail") == 0) {
414 tail = storm::adapters::XMLtoString(attr->getNodeValue());
415 }
else if (name.compare(
"kind") == 0 || name.compare(
"type") == 0) {
416 kind = storm::adapters::XMLtoString(attr->getNodeValue());
417 }
else if (name.compare(
"mult") == 0) {
418 mult = parseInt(storm::adapters::XMLtoString(attr->getNodeValue()));
419 }
else if (ignoreArcAttribute(name)) {
424 STORM_PRINT_AND_LOG(
"unknown attribute (node=" + storm::adapters::XMLtoString(node->getNodeName()) +
"): " + name +
"\n");
428 STORM_LOG_THROW(head.compare(
"____NOT_SET____") != 0, storm::exceptions::WrongFormatException,
"Arc must have a head");
429 STORM_LOG_THROW(tail.compare(
"____NOT_SET____") != 0, storm::exceptions::WrongFormatException,
"Arc must have a tail");
430 STORM_LOG_THROW(kind.compare(
"____NOT_SET____") != 0, storm::exceptions::WrongFormatException,
"Arc must have a kind");
432 if (kind.compare(
"INPUT") == 0) {
433 builder.addInputArc(tail, head, mult);
434 }
else if (kind.compare(
"INHIBITOR") == 0) {
435 builder.addInhibitionArc(tail, head, mult);
436 }
else if (kind.compare(
"OUTPUT") == 0) {
437 builder.addOutputArc(tail, head, mult);
443 for (uint_fast64_t i = 0;
i < node->getChildNodes()->getLength(); ++
i) {
444 auto child = node->getChildNodes()->item(i);
445 auto name = storm::adapters::getName(child);
447 if (isOnlyWhitespace(name)) {
449 }
else if (ignoreArcChild(name)) {
454 STORM_PRINT_AND_LOG(
"unknown child (node=" + storm::adapters::XMLtoString(node->getNodeName()) +
"): " + name +
"\n");
459int64_t GreatSpnEditorProjectParser::parseInt(std::string str) {
460 expressionParser->setAcceptDoubleLiterals(
false);
461 auto expr = expressionParser->parseFromString(str).substitute(constantsSubstitution);
462 STORM_LOG_ASSERT(!expr.containsVariables(),
"Can not evaluate expression " << str <<
" as it contains undefined variables.");
463 return expr.evaluateAsInt();
466double GreatSpnEditorProjectParser::parseReal(std::string str) {
467 expressionParser->setAcceptDoubleLiterals(
true);
468 auto expr = expressionParser->parseFromString(str).substitute(constantsSubstitution);
469 STORM_LOG_ASSERT(!expr.containsVariables(),
"Can not evaluate expression " << str <<
" as it contains undefined variables.");
470 return expr.evaluateAsDouble();
bool isIntegerType() const
Checks whether this type is an integral type.
bool isRationalType() const
Checks whether this type is a rational type.
#define STORM_LOG_ASSERT(cond, message)
#define STORM_LOG_THROW(cond, exception, message)
#define STORM_PRINT_AND_LOG(message)
SettingsManager const & manager()
Retrieves the settings manager.
std::set< storm::RationalFunctionVariable > getVariables(std::vector< storm::RationalFunction > const &vector)