summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2014-08-27 15:02:18 (GMT)
committerStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2014-08-27 15:02:18 (GMT)
commit2897a12e5e73d527e9548c987b29e4fb0a3685b1 (patch)
treec75eee16ae14e16bc9e9f89034954dd3056f57b5
parent46b840bdc4d7c4385aaa34cd71ccd1184739e741 (diff)
downloaduscxml-2897a12e5e73d527e9548c987b29e4fb0a3685b1.zip
uscxml-2897a12e5e73d527e9548c987b29e4fb0a3685b1.tar.gz
uscxml-2897a12e5e73d527e9548c987b29e4fb0a3685b1.tar.bz2
Switched to new Interpreter implementation per default
-rw-r--r--src/uscxml/Interpreter.cpp51
-rw-r--r--src/uscxml/interpreter/InterpreterRC.cpp333
-rw-r--r--src/uscxml/interpreter/InterpreterRC.h8
3 files changed, 206 insertions, 186 deletions
diff --git a/src/uscxml/Interpreter.cpp b/src/uscxml/Interpreter.cpp
index aa4475c..e10a343 100644
--- a/src/uscxml/Interpreter.cpp
+++ b/src/uscxml/Interpreter.cpp
@@ -49,7 +49,7 @@
#include "uscxml/Factory.h"
-#if 1
+#if 0
# define INTERPRETER_IMPL InterpreterDraft6
# include "uscxml/interpreter/InterpreterDraft6.h"
#else
@@ -1055,15 +1055,7 @@ Arabica::XPath::NodeSet<std::string> InterpreterImpl::selectEventlessTransitions
states.push_back(_configuration[i]);
}
states.to_document_order();
-
-#if VERBOSE
- std::cout << "Atomic States: ";
- for (int i = 0; i < atomicStates.size(); i++) {
- std::cout << ATTR(atomicStates[i], "id") << ", ";
- }
- std::cout << std::endl;
-#endif
-
+
unsigned int index = 0;
while(states.size() > index) {
bool foundTransition = false;
@@ -2564,39 +2556,41 @@ Arabica::DOM::Node<std::string> InterpreterImpl::getAncestorElement(const Arabic
*/
Arabica::DOM::Node<std::string> InterpreterImpl::findLCCA(const Arabica::XPath::NodeSet<std::string>& states) {
-#if VERBOSE
+#if VERBOSE_FIND_LCCA
std::cout << "findLCCA: ";
for (int i = 0; i < states.size(); i++) {
- std::cout << ATTR(states[i], "id") << " - " << TAGNAME(states[i]) << ", ";
+ std::cout << ATTR_CAST(states[i], "id") << ", ";
}
std::cout << std::endl << std::flush;
#endif
-
+
Arabica::XPath::NodeSet<std::string> ancestors = getProperAncestors(states[0], Arabica::DOM::Node<std::string>());
-// ancestors.push_back(states[0]); // state[0] may already be the ancestor - bug in W3C spec?
Arabica::DOM::Node<std::string> ancestor;
+
for (int i = 0; i < ancestors.size(); i++) {
if (!isCompound(Element<std::string>(ancestors[i])))
continue;
for (int j = 0; j < states.size(); j++) {
-#if VERBOSE
- std::cout << "Checking " << TAGNAME(states[j]) << " and " << TAGNAME(ancestors[i]) << std::endl;
+
+#if VERBOSE_FIND_LCCA
+ std::cout << "Checking " << ATTR_CAST(states[j], "id") << " and " << ATTR_CAST(ancestors[i], "id") << std::endl;
#endif
- if (!isDescendant(states[j], ancestors[i]) && (states[j] != ancestors[i]))
+
+ if (!isDescendant(states[j], ancestors[i]))
goto NEXT_ANCESTOR;
}
ancestor = ancestors[i];
break;
-NEXT_ANCESTOR:
+ NEXT_ANCESTOR:
;
}
-
+
// take uppermost root as ancestor
if (!ancestor)
ancestor = _scxml;
assert(ancestor);
-#if VERBOSE
- std::cout << " -> " << ATTR(ancestor, "id") << " " << ancestor.getLocalName() << std::endl;
+#if VERBOSE_FIND_LCCA
+ std::cout << " -> " << ATTR_CAST(ancestor, "id") << " " << ancestor.getLocalName() << std::endl;
#endif
return ancestor;
}
@@ -3192,8 +3186,11 @@ bool InterpreterImpl::isLegalConfiguration(const NodeSet<std::string>& config) {
foundScxmlChild = scxmlChilds[i];
}
}
- if (!foundScxmlChild)
+ if (!foundScxmlChild) {
+ LOG(ERROR) << "Invalid configuration: No childs of scxml root are active";
+
return false;
+ }
// The configuration contains one or more atomic states.
bool foundAtomicState = false;
@@ -3208,6 +3205,16 @@ bool InterpreterImpl::isLegalConfiguration(const NodeSet<std::string>& config) {
return false;
}
+ // the configuration contains no history pseudo-states
+ for (int i = 0; i < config.size(); i++) {
+ if (isHistory(Element<std::string>(config[i]))) {
+ LOG(ERROR) << "Invalid configuration: history state " << ATTR_CAST(config[i], "id") << " 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++) {
if (isAtomic(Element<std::string>(config[i]))) {
diff --git a/src/uscxml/interpreter/InterpreterRC.cpp b/src/uscxml/interpreter/InterpreterRC.cpp
index 4d2b4f6..d976244 100644
--- a/src/uscxml/interpreter/InterpreterRC.cpp
+++ b/src/uscxml/interpreter/InterpreterRC.cpp
@@ -27,13 +27,15 @@
#include "uscxml/DOMUtils.h"
#define VERBOSE 0
+#define VERBOSE_STATE_SELECTION 0
+#define VERBOSE_FIND_LCCA 0
namespace uscxml {
using namespace Arabica::XPath;
using namespace Arabica::DOM;
-#ifdef VERBOSE
+#if 1
size_t padding = 0;
std::string getPadding() {
std::string pad = "";
@@ -95,6 +97,14 @@ bool InterpreterRC::hasIntersection(const Arabica::XPath::NodeSet<std::string>&
void InterpreterRC::exitStates(const Arabica::XPath::NodeSet<std::string>& enabledTransitions) {
NodeSet<std::string> statesToExit = computeExitSet(enabledTransitions);
+#if VERBOSE_STATE_SELECTION
+ std::cout << "exitStates: ";
+ for (int i = 0; i < statesToExit.size(); i++) {
+ std::cout << ATTR_CAST(statesToExit[i], "id") << " ";
+ }
+ std::cout << std::endl;
+#endif
+
// remove statesToExit from _statesToInvoke
std::list<Node<std::string> > tmp;
for (int i = 0; i < _statesToInvoke.size(); i++) {
@@ -108,6 +118,7 @@ void InterpreterRC::exitStates(const Arabica::XPath::NodeSet<std::string>& enabl
statesToExit.forward(false);
statesToExit.sort();
+
for (int i = 0; i < statesToExit.size(); i++) {
NodeSet<std::string> histories = filterChildElements(_nsInfo.xmlNSPrefix + "history", statesToExit[i]);
for (int j = 0; j < histories.size(); j++) {
@@ -156,27 +167,37 @@ void InterpreterRC::exitStates(const Arabica::XPath::NodeSet<std::string>& enabl
}
}
-
+/*
+function computeExitSet(transitions)
+ statesToExit = new OrderedSet
+ for t in transitions:
+ if(t.target):
+ domain = getTransitionDomain(t)
+ for s in configuration:
+ if isDescendant(s,domain):
+ statesToExit.add(s)
+ return statesToExit
+*/
Arabica::XPath::NodeSet<std::string> InterpreterRC::computeExitSet(const Arabica::XPath::NodeSet<std::string>& transitions) {
NodeSet<std::string> statesToExit;
for (unsigned int i = 0; i < transitions.size(); i++) {
Element<std::string> t(transitions[i]);
- if (isTargetless(t))
- continue;
- Arabica::DOM::Node<std::string> domain = getTransitionDomain(t);
- if (!domain)
- continue;
- for (unsigned int j = 0; j < _configuration.size(); j++) {
- const Node<std::string>& s = _configuration[j];
- if (isDescendant(s, domain)) {
- statesToExit.push_back(s);
+ if (!isTargetless(t)) {
+ Arabica::DOM::Node<std::string> domain = getTransitionDomain(t);
+ if (!domain)
+ continue;
+ for (unsigned int j = 0; j < _configuration.size(); j++) {
+ const Node<std::string>& s = _configuration[j];
+ if (isDescendant(s, domain)) {
+ statesToExit.push_back(s);
+ }
}
}
}
#if VERBOSE
std::cout << "computeExitSet: ";
for (int i = 0; i < statesToExit.size(); i++) {
- std::cout << ATTR(statesToExit[i], "id") << " ";
+ std::cout << ATTR_CAST(statesToExit[i], "id") << " ";
}
std::cout << std::endl;
#endif
@@ -189,7 +210,6 @@ Arabica::XPath::NodeSet<std::string> InterpreterRC::computeExitSet(const Arabica
return computeExitSet(transitions);
}
-
void InterpreterRC::enterStates(const Arabica::XPath::NodeSet<std::string>& enabledTransitions) {
NodeSet<std::string> statesToEnter;
NodeSet<std::string> statesForDefaultEntry;
@@ -199,6 +219,14 @@ void InterpreterRC::enterStates(const Arabica::XPath::NodeSet<std::string>& enab
computeEntrySet(enabledTransitions, statesToEnter, statesForDefaultEntry, defaultHistoryContent);
statesToEnter.to_document_order();
+#if VERBOSE_STATE_SELECTION
+ std::cout << "enterStates: ";
+ for (int i = 0; i < statesToEnter.size(); i++) {
+ std::cout << ATTR_CAST(statesToEnter[i], "id") << " ";
+ }
+ std::cout << std::endl;
+#endif
+
for (int i = 0; i < statesToEnter.size(); i++) {
Element<std::string> s = (Element<std::string>)statesToEnter[i];
@@ -207,7 +235,6 @@ void InterpreterRC::enterStates(const Arabica::XPath::NodeSet<std::string>& enab
_configuration.push_back(s);
_statesToInvoke.push_back(s);
- // if (_binding == LATE && stateElem.getAttribute("isFirstEntry").size() > 0) {
if (_binding == LATE && !isMember(s, _alreadyEntered)) {
NodeSet<std::string> dataModelElems = filterChildElements(_nsInfo.xmlNSPrefix + "datamodel", s);
if(dataModelElems.size() > 0 && _dataModel) {
@@ -218,19 +245,22 @@ void InterpreterRC::enterStates(const Arabica::XPath::NodeSet<std::string>& enab
}
}
_alreadyEntered.push_back(s);
- // stateElem.setAttribute("isFirstEntry", "");
}
// execute onentry executable content
NodeSet<std::string> onEntryElems = filterChildElements(_nsInfo.xmlNSPrefix + "onEntry", s);
executeContent(onEntryElems, false);
- USCXML_MONITOR_CALLBACK3(afterEnteringState, s, i + 1 < statesToEnter.size())
-
if (isMember(s, statesForDefaultEntry)) {
// execute initial transition content for compound states
Arabica::XPath::NodeSet<std::string> transitions = _xpath.evaluate("" + _nsInfo.xpathPrefix + "initial/" + _nsInfo.xpathPrefix + "transition", s).asNodeSet();
- executeContent(transitions);
+ if (transitions.size() > 0) {
+ executeContent(transitions);
+ }
}
+
+ USCXML_MONITOR_CALLBACK3(afterEnteringState, s, i + 1 < statesToEnter.size())
+
+// std::cout << "HIST?: " << ATTR(s, "id") << std::endl;
if (defaultHistoryContent.find(ATTR(s, "id")) != defaultHistoryContent.end()) {
executeContent(Element<std::string>(defaultHistoryContent[ATTR(s, "id")]));
}
@@ -263,133 +293,76 @@ void InterpreterRC::enterStates(const Arabica::XPath::NodeSet<std::string>& enab
}
}
+/*
+procedure computeEntrySet(transitions, statesToEnter, statesForDefaultEntry, defaultHistoryContent)
+ for t in transitions:
+ for s in t.target:
+ addDescendantStatesToEnter(s,statesToEnter,statesForDefaultEntry, defaultHistoryContent)
+ ancestor = getTransitionDomain(t)
+ for s in getEffectiveTargetStates(t)):
+ addAncestorStatesToEnter(s, ancestor, statesToEnter, statesForDefaultEntry, defaultHistoryContent)
+*/
void InterpreterRC::computeEntrySet(const Arabica::XPath::NodeSet<std::string>& transitions,
NodeSet<std::string>& statesToEnter,
NodeSet<std::string>& statesForDefaultEntry,
- std::map<std::string, Arabica::DOM::Node<std::string> > defaultHistoryContent) {
+ std::map<std::string, Arabica::DOM::Node<std::string> >& defaultHistoryContent) {
-#if 1
+ // add all descendants in a dedicated first step
for (int i = 0; i < transitions.size(); i++) {
Element<std::string> t(transitions[i]);
NodeSet<std::string> targets = getTargetStates(t);
-
-#if VERBOSE
- std::cout << "computeEntrySet: ";
- for (int i = 0; i < targets.size(); i++) {
- std::cout << ATTR_CAST(targets[i], "id") << " ";
- }
- std::cout << std::endl;
-#endif
-
-
- for (int j = 0; j < targets.size(); j++) {
- Element<std::string> s = Element<std::string>(targets[j]);
- addDescendantStatesToEnter(s,statesToEnter,statesForDefaultEntry, defaultHistoryContent);
- }
-
for (int j = 0; j < targets.size(); j++) {
Element<std::string> s = Element<std::string>(targets[j]);
- addDescendantStatesToEnter(s,statesToEnter,statesForDefaultEntry, defaultHistoryContent);
+ addDescendantStatesToEnter(s, statesToEnter, statesForDefaultEntry, defaultHistoryContent);
}
-
-#if VERBOSE
- std::cout << "after addDescendantStatesToEnter: ";
- for (int i = 0; i < statesToEnter.size(); i++) {
- std::cout << ATTR_CAST(statesToEnter[i], "id") << " ";
- }
- std::cout << std::endl;
-#endif
-
- Element<std::string> ancestor = Element<std::string>(getTransitionDomain(t));
- NodeSet<std::string> effectiveTargetStates = getEffectiveTargetStates(t);
-
- for (int j = 0; j < effectiveTargetStates.size(); j++) {
- Element<std::string> s = Element<std::string>(effectiveTargetStates[j]);
- addAncestorStatesToEnter(s, ancestor, statesToEnter, statesForDefaultEntry, defaultHistoryContent);
- }
-
-#if VERBOSE
- std::cout << "after addAncestorStatesToEnter: ";
- for (int i = 0; i < statesToEnter.size(); i++) {
- std::cout << ATTR_CAST(statesToEnter[i], "id") << " ";
- }
- std::cout << std::endl;
-#endif
-
}
-
-
-
-#else
+ // only now add the ancestors
for (int i = 0; i < transitions.size(); i++) {
Element<std::string> t(transitions[i]);
+ Element<std::string> ancestor = Element<std::string>(getTransitionDomain(t));
+ NodeSet<std::string> effectiveTargetStates = getEffectiveTargetStates(t);
- NodeSet<std::string> targets = getTargetStates(t);
- for (int j = 0; j < targets.size(); j++) {
- if (!isMember(targets[j], statesToEnter)) {
-#if VERBOSE
- std::cout << "adding: " << ATTR_CAST(anc, "id") << std::endl;
-#endif
- statesToEnter.push_back(targets[j]);
- }
- }
- }
-
-#if VERBOSE
- std::cout << "before addDescendantStatesToEnter: ";
- for (int i = 0; i < statesToEnter.size(); i++) {
- std::cout << ATTR_CAST(statesToEnter[i], "id") << " ";
- }
- std::cout << std::endl;
-#endif
-
- NodeSet<std::string> tmp = statesToEnter;
- for (int i = 0; i < tmp.size(); i++) {
- assert(tmp[i]);
- addDescendantStatesToEnter(tmp[i],statesToEnter,statesForDefaultEntry, defaultHistoryContent);
- }
-
-#if VERBOSE
- std::cout << "after addDescendantStatesToEnter: ";
- for (int i = 0; i < statesToEnter.size(); i++) {
- std::cout << ATTR_CAST(statesToEnter[i], "id") << " ";
- }
- std::cout << std::endl;
-#endif
-
- for (int i = 0; i < transitions.size(); i++) {
- Element<std::string> t = (Element<std::string>)transitions[i];
- Node<std::string> ancestor = getTransitionDomain(t);
- NodeSet<std::string> targets = getTargetStates(t);
- for (int j = 0; j < targets.size(); j++) {
- const Node<std::string>& s = targets[j];
+ for (int j = 0; j < effectiveTargetStates.size(); j++) {
+ Element<std::string> s = Element<std::string>(effectiveTargetStates[j]);
addAncestorStatesToEnter(s, ancestor, statesToEnter, statesForDefaultEntry, defaultHistoryContent);
}
- }
-#if VERBOSE
- std::cout << "after addAncestorStatesToEnter: ";
- for (int i = 0; i < statesToEnter.size(); i++) {
- std::cout << ATTR_CAST(statesToEnter[i], "id") << " ";
}
- std::cout << std::endl;
-#endif
-
-#endif
}
+/*
+function getEffectiveTargetStates(transition)
+ effectiveTargets = new OrderedSet()
+ for s in transition.target
+ if isHistoryState(s):
+ if historyValue[s.id]:
+ effectiveTargets.union(historyValue[s.id])
+ else:
+ effectiveTargets.union(getEffectiveTargetStates(s.transition))
+ else:
+ effectiveTargets.add(s)
+ return effectiveTargets
+*/
+
Arabica::XPath::NodeSet<std::string> InterpreterRC::getEffectiveTargetStates(const Arabica::DOM::Element<std::string>& transition) {
NodeSet<std::string> effectiveTargets;
- NodeSet<std::string> targets = getTargetStates(transition);
-
+
+ NodeSet<std::string> targets;
+ if (isState(transition)) {
+ targets = getInitialStates(transition);
+ return targets;
+ } else {
+ targets = getTargetStates(transition);
+ }
+
for (int j = 0; j < targets.size(); j++) {
Element<std::string> s = Element<std::string>(targets[j]);
if (isHistory(s)) {
if (_historyValue.find(ATTR(s, "id")) != _historyValue.end()) {
- targets.push_back(_historyValue["id"]);
+ targets.push_back(_historyValue[ATTR(s, "id")]);
} else {
NodeSet<std::string> histTrans = filterChildElements(_nsInfo.xmlNSPrefix + "transition", s);
// TODO: what if there are many history transitions?
@@ -407,24 +380,61 @@ Arabica::XPath::NodeSet<std::string> InterpreterRC::getEffectiveTargetStates(con
void InterpreterRC::computeEntrySet(const Arabica::DOM::Node<std::string>& transition,
NodeSet<std::string>& statesToEnter,
NodeSet<std::string>& statesForDefaultEntry,
- std::map<std::string, Arabica::DOM::Node<std::string> > defaultHistoryContent) {
+ std::map<std::string, Arabica::DOM::Node<std::string> >& defaultHistoryContent) {
Arabica::XPath::NodeSet<std::string> transitions;
transitions.push_back(transition);
computeEntrySet(transitions, statesToEnter, statesForDefaultEntry, defaultHistoryContent);
}
+
+/*
+procedure addDescendantStatesToEnter(state,statesToEnter,statesForDefaultEntry, defaultHistoryContent):
+ if isHistoryState(state):
+ if historyValue[state.id]:
+ for s in historyValue[state.id]:
+ addDescendantStatesToEnter(s,statesToEnter,statesForDefaultEntry, defaultHistoryContent)
+ addAncestorStatesToEnter(s, state.parent, statesToEnter, statesForDefaultEntry, defaultHistoryContent)
+ else:
+ defaultHistoryContent[state.parent.id] = state.transition.content
+ for s in state.transition.target:
+ addDescendantStatesToEnter(s,statesToEnter,statesForDefaultEntry, defaultHistoryContent)
+ addAncestorStatesToEnter(s, state.parent, statesToEnter, statesForDefaultEntry, defaultHistoryContent)
+ else:
+ statesToEnter.add(state)
+ if isCompoundState(state):
+ statesForDefaultEntry.add(state)
+ for s in getEffectiveTargetStates(state.initial.transition):
+ addDescendantStatesToEnter(s,statesToEnter,statesForDefaultEntry, defaultHistoryContent)
+ addAncestorStatesToEnter(s, state, statesToEnter, statesForDefaultEntry, defaultHistoryContent)
+ else:
+ if isParallelState(state):
+ for child in getChildStates(state):
+ if not statesToEnter.some(lambda s: isDescendant(s,child)):
+ addDescendantStatesToEnter(child,statesToEnter,statesForDefaultEntry, defaultHistoryContent)
+*/
void InterpreterRC::addDescendantStatesToEnter(const Arabica::DOM::Element<std::string>& state,
Arabica::XPath::NodeSet<std::string>& statesToEnter,
Arabica::XPath::NodeSet<std::string>& statesForDefaultEntry,
- std::map<std::string, Arabica::DOM::Node<std::string> > defaultHistoryContent) {
+ std::map<std::string, Arabica::DOM::Node<std::string> >& defaultHistoryContent) {
-#if VERBOSE
+#if VERBOSE_STATE_SELECTION
std::cout << getPadding() << "addDescendantStatesToEnter: " << ATTR(state, "id") << std::endl;
padding++;
#endif
if (isHistory(state)) {
+ /*
+ if historyValue[state.id]:
+ for s in historyValue[state.id]:
+ addDescendantStatesToEnter(s,statesToEnter,statesForDefaultEntry, defaultHistoryContent)
+ addAncestorStatesToEnter(s, state.parent, statesToEnter, statesForDefaultEntry, defaultHistoryContent)
+ else:
+ defaultHistoryContent[state.parent.id] = state.transition.content
+ for s in state.transition.target:
+ addDescendantStatesToEnter(s,statesToEnter,statesForDefaultEntry, defaultHistoryContent)
+ addAncestorStatesToEnter(s, state.parent, statesToEnter, statesForDefaultEntry, defaultHistoryContent)
+ */
std::string stateId = ATTR(state, "id");
if (_historyValue.find(stateId) != _historyValue.end()) {
const Arabica::XPath::NodeSet<std::string>& historyValue = _historyValue[stateId];
@@ -438,7 +448,8 @@ void InterpreterRC::addDescendantStatesToEnter(const Arabica::DOM::Element<std::
NodeSet<std::string> transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", state);
if (transitions.size() > 0) {
// TODO: what if there are many history transitions?
- defaultHistoryContent[stateId] = transitions[0];
+// std::cout << "HIST: " << ATTR_CAST(getParentState(state), "id") << std::endl;
+ defaultHistoryContent[ATTR_CAST(getParentState(state), "id")] = transitions[0];
}
for (int i = 0; i < transitions.size(); i++) {
@@ -451,9 +462,22 @@ void InterpreterRC::addDescendantStatesToEnter(const Arabica::DOM::Element<std::
}
}
} else {
+ /*
+ statesToEnter.add(state)
+ if isCompoundState(state):
+ statesForDefaultEntry.add(state)
+ for s in getEffectiveTargetStates(state.initial.transition):
+ addDescendantStatesToEnter(s,statesToEnter,statesForDefaultEntry, defaultHistoryContent)
+ addAncestorStatesToEnter(s, state, statesToEnter, statesForDefaultEntry, defaultHistoryContent)
+ else:
+ if isParallelState(state):
+ for child in getChildStates(state):
+ if not statesToEnter.some(lambda s: isDescendant(s,child)):
+ addDescendantStatesToEnter(child,statesToEnter,statesForDefaultEntry, defaultHistoryContent)
+ */
if (!isMember(state, statesToEnter)) { // adding an existing element invalidates old reference
-#if VERBOSE
+#if VERBOSE_STATE_SELECTION
std::cout << getPadding() << "adding: " << ATTR_CAST(state, "id") << std::endl;
#endif
statesToEnter.push_back(state);
@@ -462,10 +486,11 @@ void InterpreterRC::addDescendantStatesToEnter(const Arabica::DOM::Element<std::
if (isCompound(state)) {
statesForDefaultEntry.push_back(state);
- NodeSet<std::string> targets = getInitialStates(Element<std::string>(state));
+ // test 579 - initial leads to history still fails
+ NodeSet<std::string> targets = getEffectiveTargetStates(Element<std::string>(state));
for (int i = 0; i < targets.size(); i++) {
const Element<std::string>& s = Element<std::string>(targets[i]);
- addDescendantStatesToEnter(s,statesToEnter,statesForDefaultEntry, defaultHistoryContent);
+ addDescendantStatesToEnter(s, statesToEnter, statesForDefaultEntry, defaultHistoryContent);
}
for (int i = 0; i < targets.size(); i++) {
@@ -495,13 +520,22 @@ BREAK_LOOP:
padding--;
}
+/*
+procedure addAncestorStatesToEnter(state, ancestor, statesToEnter, statesForDefaultEntry, defaultHistoryContent)
+ for anc in getProperAncestors(state,ancestor):
+ statesToEnter.add(anc)
+ if isParallelState(anc):
+ for child in getChildStates(anc):
+ if not statesToEnter.some(lambda s: isDescendant(s,child)):
+ addDescendantStatesToEnter(child,statesToEnter,statesForDefaultEntry, defaultHistoryContent)
+*/
void InterpreterRC::addAncestorStatesToEnter(const Arabica::DOM::Element<std::string>& state,
const Arabica::DOM::Element<std::string>& ancestor,
Arabica::XPath::NodeSet<std::string>& statesToEnter,
Arabica::XPath::NodeSet<std::string>& statesForDefaultEntry,
- std::map<std::string, Arabica::DOM::Node<std::string> > defaultHistoryContent) {
+ std::map<std::string, Arabica::DOM::Node<std::string> >& defaultHistoryContent) {
-#if VERBOSE
+#if VERBOSE_STATE_SELECTION
std::cout << getPadding() << "addAncestorStatesToEnter: " << ATTR(state, "id") << " - " << ATTR(ancestor, "id") << std::endl;
padding++;
#endif
@@ -509,10 +543,12 @@ void InterpreterRC::addAncestorStatesToEnter(const Arabica::DOM::Element<std::st
NodeSet<std::string> ancestors = getProperAncestors(state, ancestor);
for (int i = 0; i < ancestors.size(); i++) {
const Node<std::string>& anc = ancestors[i];
-#if VERBOSE
+#if VERBOSE_STATE_SELECTION
std::cout << getPadding() << "adding: " << ATTR_CAST(anc, "id") << std::endl;
#endif
+
statesToEnter.push_back(anc);
+
if (isParallel(Element<std::string>(anc))) {
NodeSet<std::string> childStates = getChildStates(anc);
for (int j = 0; j < childStates.size(); j++) {
@@ -532,46 +568,24 @@ BREAK_LOOP:
padding--;
}
-
+/*
+function getTransitionDomain(t)
+ tstates = getEffectiveTargetStates(t)
+ if not tstates:
+ return null
+ elif t.type == "internal" and isCompoundState(t.source) and tstates.every(lambda s: isDescendant(s,t.source)):
+ return t.source
+ else:
+ return findLCCA([t.source].append(tstates))
+*/
Arabica::DOM::Node<std::string> InterpreterRC::getTransitionDomain(const Arabica::DOM::Element<std::string>& transition) {
-#if 1
-
NodeSet<std::string> tStates = getEffectiveTargetStates(transition);
- Node<std::string> source = getSourceState(transition);
-
if (tStates.size() == 0) {
return Arabica::DOM::Node<std::string>(); // null
}
std::string transitionType = (HAS_ATTR(transition, "type") ? ATTR(transition, "type") : "external");
-
- if (iequals(transitionType, "internal") && isCompound(Element<std::string>(source))) {
- for (int i = 0; i < tStates.size(); i++) {
- const Node<std::string>& s = tStates[i];
- if (!isDescendant(s, source))
- goto BREAK_LOOP;
- }
- return source;
- }
-
-BREAK_LOOP:
- Arabica::XPath::NodeSet<std::string> states;
- states.push_back(source);
- states.push_back(tStates);
- return findLCCA(states);
-
-#else
- NodeSet<std::string> tStates = getTargetStates(transition);
Node<std::string> source = getSourceState(transition);
-#if VERBOSE
- std::cout << "getTransitionDomain: " << std::endl << transition << std::endl;
-#endif
-
- if (tStates.size() == 0) {
- return Arabica::DOM::Node<std::string>(); // null
- }
- std::string transitionType = (HAS_ATTR(transition, "type") ? ATTR(transition, "type") : "external");
-
if (iequals(transitionType, "internal") && isCompound(Element<std::string>(source))) {
for (int i = 0; i < tStates.size(); i++) {
const Node<std::string>& s = tStates[i];
@@ -580,13 +594,12 @@ BREAK_LOOP:
}
return source;
}
+
BREAK_LOOP:
- ;
Arabica::XPath::NodeSet<std::string> states;
states.push_back(source);
states.push_back(tStates);
return findLCCA(states);
-#endif
}
} \ No newline at end of file
diff --git a/src/uscxml/interpreter/InterpreterRC.h b/src/uscxml/interpreter/InterpreterRC.h
index 3dae973..d65e85a 100644
--- a/src/uscxml/interpreter/InterpreterRC.h
+++ b/src/uscxml/interpreter/InterpreterRC.h
@@ -37,11 +37,11 @@ class InterpreterRC : public InterpreterImpl {
void computeEntrySet(const Arabica::XPath::NodeSet<std::string>& transitions,
Arabica::XPath::NodeSet<std::string>& statesToEnter,
Arabica::XPath::NodeSet<std::string>& statesForDefaultEntry,
- std::map<std::string, Arabica::DOM::Node<std::string> > defaultHistoryContent);
+ std::map<std::string, Arabica::DOM::Node<std::string> >& defaultHistoryContent);
void computeEntrySet(const Arabica::DOM::Node<std::string>& transition,
Arabica::XPath::NodeSet<std::string>& statesToEnter,
Arabica::XPath::NodeSet<std::string>& statesForDefaultEntry,
- std::map<std::string, Arabica::DOM::Node<std::string> > defaultHistoryContent);
+ std::map<std::string, Arabica::DOM::Node<std::string> >& defaultHistoryContent);
Arabica::DOM::Node<std::string> getTransitionDomain(const Arabica::DOM::Element<std::string>& transition);
Arabica::XPath::NodeSet<std::string> getEffectiveTargetStates(const Arabica::DOM::Element<std::string>& transition);
@@ -49,13 +49,13 @@ class InterpreterRC : public InterpreterImpl {
void addDescendantStatesToEnter(const Arabica::DOM::Element<std::string>& state,
Arabica::XPath::NodeSet<std::string>& statesToEnter,
Arabica::XPath::NodeSet<std::string>& statesForDefaultEntry,
- std::map<std::string, Arabica::DOM::Node<std::string> > defaultHistoryContent);
+ std::map<std::string, Arabica::DOM::Node<std::string> >& defaultHistoryContent);
void addAncestorStatesToEnter(const Arabica::DOM::Element<std::string>& state,
const Arabica::DOM::Element<std::string>& ancestor,
Arabica::XPath::NodeSet<std::string>& statesToEnter,
Arabica::XPath::NodeSet<std::string>& statesForDefaultEntry,
- std::map<std::string, Arabica::DOM::Node<std::string> > defaultHistoryContent);
+ std::map<std::string, Arabica::DOM::Node<std::string> >& defaultHistoryContent);
};