summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2014-08-08 18:49:30 (GMT)
committerStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2014-08-08 18:49:30 (GMT)
commitb95a9c2d23c4bfba84dfac8683c47153d598e09f (patch)
tree827a4c4f707c9ee3688997a20868ea4b86b65861 /src
parent799ca6d265d7a362526d66e7f615f914695b867e (diff)
downloaduscxml-b95a9c2d23c4bfba84dfac8683c47153d598e09f.zip
uscxml-b95a9c2d23c4bfba84dfac8683c47153d598e09f.tar.gz
uscxml-b95a9c2d23c4bfba84dfac8683c47153d598e09f.tar.bz2
Be more explicit as to why a configuration is invalid
Diffstat (limited to 'src')
-rw-r--r--src/uscxml/Interpreter.cpp40
-rw-r--r--src/uscxml/debug/SCXMLDotWriter.cpp45
-rw-r--r--src/uscxml/transform/ChartToFSM.cpp28
-rw-r--r--src/uscxml/transform/ChartToFSM.h3
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);
};