diff options
author | Stefan Radomski <radomski@tk.informatik.tu-darmstadt.de> | 2014-08-08 18:49:30 (GMT) |
---|---|---|
committer | Stefan Radomski <radomski@tk.informatik.tu-darmstadt.de> | 2014-08-08 18:49:30 (GMT) |
commit | b95a9c2d23c4bfba84dfac8683c47153d598e09f (patch) | |
tree | 827a4c4f707c9ee3688997a20868ea4b86b65861 /src/uscxml | |
parent | 799ca6d265d7a362526d66e7f615f914695b867e (diff) | |
download | uscxml-b95a9c2d23c4bfba84dfac8683c47153d598e09f.zip uscxml-b95a9c2d23c4bfba84dfac8683c47153d598e09f.tar.gz uscxml-b95a9c2d23c4bfba84dfac8683c47153d598e09f.tar.bz2 |
Be more explicit as to why a configuration is invalid
Diffstat (limited to 'src/uscxml')
-rw-r--r-- | src/uscxml/Interpreter.cpp | 40 | ||||
-rw-r--r-- | src/uscxml/debug/SCXMLDotWriter.cpp | 45 | ||||
-rw-r--r-- | src/uscxml/transform/ChartToFSM.cpp | 28 | ||||
-rw-r--r-- | src/uscxml/transform/ChartToFSM.h | 3 |
4 files changed, 67 insertions, 49 deletions
diff --git a/src/uscxml/Interpreter.cpp b/src/uscxml/Interpreter.cpp index b9b5d94..7556961 100644 --- a/src/uscxml/Interpreter.cpp +++ b/src/uscxml/Interpreter.cpp @@ -2648,24 +2648,16 @@ bool InterpreterImpl::isLegalConfiguration(const std::list<std::string>& config) */ bool InterpreterImpl::isLegalConfiguration(const NodeSet<std::string>& config) { -#if VERBOSE - std::cout << "Checking whether {"; - std::string seperator; - for (int i = 0; i < config.size(); i++) { - std::cout << seperator << ATTR(config[i], "id"); - seperator = ", "; - } - std::cout << "} is legal" << std::endl; -#endif - // The configuration contains exactly one child of the <scxml> element. NodeSet<std::string> scxmlChilds = getChildStates(_scxml); - bool foundScxmlChild = false; + Node<std::string> foundScxmlChild; for (int i = 0; i < scxmlChilds.size(); i++) { if (isMember(scxmlChilds[i], config)) { - if (foundScxmlChild) + if (foundScxmlChild) { + LOG(ERROR) << "Invalid configuration: Multiple childs of scxml root are active '" << ATTR_CAST(foundScxmlChild, "id") << "' and '" << ATTR_CAST(scxmlChilds[i], "id") << "'"; return false; - foundScxmlChild = true; + } + foundScxmlChild = scxmlChilds[i]; } } if (!foundScxmlChild) @@ -2679,8 +2671,10 @@ bool InterpreterImpl::isLegalConfiguration(const NodeSet<std::string>& config) { break; } } - if (!foundAtomicState) + if (!foundAtomicState) { + LOG(ERROR) << "Invalid configuration: No atomic state is active"; return false; + } // When the configuration contains an atomic state, it contains all of its <state> and <parallel> ancestors. for (int i = 0; i < config.size(); i++) { @@ -2690,8 +2684,10 @@ bool InterpreterImpl::isLegalConfiguration(const NodeSet<std::string>& config) { if (isState(Element<std::string>(parent)) && (iequals(LOCALNAME(parent), "state") || iequals(LOCALNAME(parent), "parallel"))) { - if (!isMember(parent, config)) + if (!isMember(parent, config)) { + LOG(ERROR) << "Invalid configuration: atomic state '" << ATTR_CAST(config[i], "id") << "' is active, but parent '" << ATTR_CAST(parent, "id") << "' is not"; return false; + } } } } @@ -2701,19 +2697,24 @@ bool InterpreterImpl::isLegalConfiguration(const NodeSet<std::string>& config) { for (int i = 0; i < config.size(); i++) { Element<std::string> configElem(config[i]); if (!isAtomic(configElem) && !isParallel(configElem)) { - bool foundChildState = false; + Node<std::string> foundChildState; //std::cout << config[i] << std::endl; NodeSet<std::string> childs = getChildStates(config[i]); for (int j = 0; j < childs.size(); j++) { //std::cout << childs[j] << std::endl; if (isMember(childs[j], config)) { - if (foundChildState) + if (foundChildState) { + LOG(ERROR) << "Invalid configuration: Multiple childs of compound '" << ATTR_CAST(config[i], "id") + << "' are active '" << ATTR_CAST(foundChildState, "id") << "' and '" << ATTR_CAST(childs[j], "id") << "'"; return false; - foundChildState = true; + } + foundChildState = childs[j]; } } - if (!foundChildState) + if (!foundChildState) { + LOG(ERROR) << "Invalid configuration: No childs of compound '" << ATTR_CAST(config[i], "id") << "' are active"; return false; + } } } @@ -2723,6 +2724,7 @@ bool InterpreterImpl::isLegalConfiguration(const NodeSet<std::string>& config) { NodeSet<std::string> childs = getChildStates(config[i]); for (int j = 0; j < childs.size(); j++) { if (!isMember(childs[j], config) && !isHistory(Element<std::string>(childs[j]))) { + LOG(ERROR) << "Invalid configuration: Not all children of parallel '" << ATTR_CAST(config[i], "id") << "' are active i.e. '" << ATTR_CAST(childs[j], "id") << "' is not"; return false; } } diff --git a/src/uscxml/debug/SCXMLDotWriter.cpp b/src/uscxml/debug/SCXMLDotWriter.cpp index 1b9555e..5c15dbd 100644 --- a/src/uscxml/debug/SCXMLDotWriter.cpp +++ b/src/uscxml/debug/SCXMLDotWriter.cpp @@ -124,26 +124,26 @@ void SCXMLDotWriter::writeTo(std::ostream& os) { continue; } - os << getPrefix() << "\"" << edgeIter->from << "\""; + os << getPrefix() << "\"" << portEscape(edgeIter->from) << "\""; if (edgeIter->fromPort.size() > 0) { - os << std::string(":\"") + edgeIter->fromPort + "\":e"; + os << std::string(":\"") + portEscape(edgeIter->fromPort) + "\":e"; } else { os << ":__name"; } os << " -> "; if (_histories.find(edgeIter->to) != _histories.end()) { - os << getPrefix() << "\"" << _histories.find(edgeIter->to)->second.to << "\""; + os << getPrefix() << "\"" << portEscape(_histories.find(edgeIter->to)->second.to) << "\""; if (_histories.find(edgeIter->to)->second.toPort.size() > 0) { - os << std::string(":\"") + _histories.find(edgeIter->to)->second.toPort + "\""; + os << std::string(":\"") + portEscape(_histories.find(edgeIter->to)->second.toPort) + "\""; } else { os << ":__name"; } } else { - os << getPrefix() << "\"" << edgeIter->to << "\""; + os << getPrefix() << "\"" << portEscape(edgeIter->to) << "\""; if (edgeIter->toPort.size() > 0) { - os << std::string(":\"") + edgeIter->toPort + "\""; + os << std::string(":\"") + portEscape(edgeIter->toPort) + "\""; } else { os << ":__name"; } @@ -274,7 +274,7 @@ void SCXMLDotWriter::writeStateElement(std::ostream& os, const Element<std::stri if (subgraph) { _indentation++; os << std::endl; - os << getPrefix() << "subgraph \"cluster_" << stateId << "\" {" << std::endl; + os << getPrefix() << "subgraph \"cluster_" << portEscape(stateId) << "\" {" << std::endl; _indentation++; os << getPrefix() << "fontsize=14" << std::endl; os << getPrefix() << "label=<" << nameForNode(stateElem) << ">" << std::endl; @@ -294,7 +294,7 @@ void SCXMLDotWriter::writeStateElement(std::ostream& os, const Element<std::stri // is this a subgraph? os << std::endl; - os << getPrefix() << "\"" << stateId << "\" [" << std::endl; + os << getPrefix() << "\"" << portEscape(stateId) << "\" [" << std::endl; _indentation++; os << getPrefix() << "fontsize=10," << std::endl; @@ -401,7 +401,7 @@ void SCXMLDotWriter::writeStateElement(std::ostream& os, const Element<std::stri // write history states NodeSet<std::string> histories = InterpreterImpl::filterChildElements(_xmlNSPrefix + "history", stateElem); for (int i = 0; i < histories.size(); i++) { - os << " <tr><td port=\"" << ATTR_CAST(histories[i], "id") << "\" balign=\"left\" colspan=\"" << (nrOutPorts == 0 ? 1 : 2) << "\"><b>history: </b>" << ATTR_CAST(histories[i], "id") << "</td></tr>" << std::endl; + os << " <tr><td port=\"" << portEscape(ATTR_CAST(histories[i], "id")) << "\" balign=\"left\" colspan=\"" << (nrOutPorts == 0 ? 1 : 2) << "\"><b>history: </b>" << ATTR_CAST(histories[i], "id") << "</td></tr>" << std::endl; } @@ -772,7 +772,10 @@ std::string SCXMLDotWriter::getDetailedLabel(const Element<std::string>& elem, i std::string SCXMLDotWriter::portEscape(const std::string& text) { std::string escaped(text); boost::replace_all(escaped, ".", "-"); - return text; + boost::replace_all(escaped, "{", "-"); + boost::replace_all(escaped, "}", "-"); + boost::replace_all(escaped, ":", "-"); + return escaped; } std::string SCXMLDotWriter::dotEscape(const std::string& text) { @@ -840,17 +843,17 @@ std::string SCXMLDotWriter::idForNode(const Node<std::string>& node) { if (node.getNodeType() == Node_base::ELEMENT_NODE) { Element<std::string> elem = (Element<std::string>)node; - if (InterpreterImpl::isFinal(elem) && _isFlat) { - // ignore visited and history with final elements - FlatStateIdentifier flatId(elem.getAttribute("id")); - - std::stringstream activeSS; - activeSS << "active-"; - for (std::list<std::string>::const_iterator activeIter = flatId.getActive().begin(); activeIter != flatId.getActive().end(); activeIter++) { - activeSS << *activeIter << "-"; - } - return activeSS.str(); - } +// if (InterpreterImpl::isFinal(elem) && _isFlat) { +// // ignore visited and history with final elements +// FlatStateIdentifier flatId(elem.getAttribute("id")); +// +// std::stringstream activeSS; +// activeSS << "active-"; +// for (std::list<std::string>::const_iterator activeIter = flatId.getActive().begin(); activeIter != flatId.getActive().end(); activeIter++) { +// activeSS << *activeIter << "-"; +// } +// return activeSS.str(); +// } if (elem.hasAttribute("name")) { elemId = elem.getAttribute("name"); diff --git a/src/uscxml/transform/ChartToFSM.cpp b/src/uscxml/transform/ChartToFSM.cpp index 073805f..0aac811 100644 --- a/src/uscxml/transform/ChartToFSM.cpp +++ b/src/uscxml/transform/ChartToFSM.cpp @@ -206,7 +206,7 @@ InterpreterState FlatteningInterpreter::interpret() { GlobalState::gIndex = 0; _start = new GlobalState(_configuration, _alreadyEntered, _historyValue, _nsInfo.xmlNSPrefix); _globalConf[_start->stateId] = _start; - _globalConf[_start->stateId]->index = GlobalState::gIndex++; + _globalConf[_start->stateId]->index = toStr(GlobalState::gIndex++); NodeSet<std::string> initialTransitions; @@ -473,7 +473,7 @@ void FlatteningInterpreter::explode() { } _globalConf[globalState->stateId] = globalState; - _globalConf[globalState->stateId]->index = GlobalState::gIndex++; + _globalConf[globalState->stateId]->index = toStr(GlobalState::gIndex++); assert(isLegalConfiguration(configuration)); if(_globalConf[globalState->stateId]->isFinal) @@ -568,7 +568,10 @@ void FlatteningInterpreter::explode() { if (tthread::chrono::system_clock::now() - _lastTimeStamp > 1000) { _lastTimeStamp = tthread::chrono::system_clock::now(); // std::cout << globalState->stateId << " [" << nrElements << "]: " << std::endl; - std::cout << _perfTotal << " [" << _perfProcessed << "/sec]" << std::endl; + std::cout << "States: " << _globalConf.size() << " - "; + std::cout << "Tested: " << _perfTotal << " [" << _perfProcessed << "/sec] - "; + std::cout << "Current Complexity: 2**" << nrElements << " = " << pow(2.0, static_cast<double>(nrElements)); + std::cout << std::endl; _perfProcessed = 0; } @@ -667,10 +670,16 @@ NEXT_DEPTH: _currGlobalTransition = *transListIter; microstep((*transListIter)->transitions); if (!isLegalConfiguration(_configuration)) { - std::cout << "invalid configuration from " << globalState->stateId << std::endl; + FlatStateIdentifier fromState(configuration, alreadyEntered, historyValue); + FlatStateIdentifier toState(_configuration, _alreadyEntered, _historyValue); + std::cerr << "invalid configuration after transition " << std::endl + << "from \t" << fromState.getStateId() << std::endl + << "to \t" << toState.getStateId() << std::endl + << "via ------" << std::endl; for (int i = 0; i < (*transListIter)->transitions.size(); i++) { - std::cout << (*transListIter)->transitions[i] << std::endl; + std::cerr << (*transListIter)->transitions[i] << std::endl; } + std::cerr << "----------" << std::endl; assert(false); } explode(); @@ -752,13 +761,12 @@ Node<std::string> FlatteningInterpreter::globalStateToNode(GlobalState* globalSt Element<std::string> state = _flatDoc.createElementNS(_nsInfo.nsURL, "state"); _nsInfo.setPrefix(state); + state.setAttribute("ref", globalState->index); state.setAttribute("id", globalState->stateId); if (globalState->isFinal) state.setAttribute("final", "true"); -// state.setAttribute("index", toStr(globalState->index)); - std::list<GlobalTransition*> transitionList; for (std::map<std::string, GlobalTransition*>::iterator outIter = globalState->outgoing.begin(); outIter != globalState->outgoing.end(); @@ -769,10 +777,13 @@ Node<std::string> FlatteningInterpreter::globalStateToNode(GlobalState* globalSt transitionList = sortTransitions(transitionList); // std::cout << "/////////////////" << std::endl; + size_t index = 0; for (std::list<GlobalTransition*>::iterator outIter = transitionList.begin(); outIter != transitionList.end(); outIter++) { + (*outIter)->index = globalState->index + ":" + toStr(index); state.appendChild(globalTransitionToNode(*outIter)); + index++; } // std::cout << "/////////////////" << std::endl; @@ -786,6 +797,8 @@ Node<std::string> FlatteningInterpreter::globalTransitionToNode(GlobalTransition Element<std::string> transition = _flatDoc.createElementNS(_nsInfo.nsURL, "transition"); _nsInfo.setPrefix(transition); +// transition.setAttribute("ref", globalTransition->index); + if (!globalTransition->isEventless) { transition.setAttribute("event", globalTransition->eventDesc); } @@ -822,7 +835,6 @@ Node<std::string> FlatteningInterpreter::globalTransitionToNode(GlobalTransition transition.setAttribute("prioPerLevel", nrSS.str()); #endif - transition.setAttribute("id", globalTransition->transitionId); // std::cout << " firstPerLevel:" << feSS.str() << " " << globalTransition->transitionId << std::endl; // std::cout << "event: " << globalTransition->eventDesc << " firstPerLevel:" << feSS.str() << " numberPerLevel:" << nrSS.str() << " prioPerLevel:" << prSS.str() << " " << globalTransition->transitionId << std::endl; diff --git a/src/uscxml/transform/ChartToFSM.h b/src/uscxml/transform/ChartToFSM.h index 5ee5c8e..64b3640 100644 --- a/src/uscxml/transform/ChartToFSM.h +++ b/src/uscxml/transform/ChartToFSM.h @@ -51,7 +51,7 @@ public: static int gIndex; - int index; + std::string index; bool isFinal; }; @@ -99,6 +99,7 @@ public: std::string source; std::string destination; + std::string index; protected: std::list<std::string> getCommonEvents(const Arabica::XPath::NodeSet<std::string>& transitions); }; |