diff --git a/prism/src/parser/visitor/ExpressionTraverseNonNested.java b/prism/src/parser/visitor/ExpressionTraverseNonNested.java
index 0fd7f1df..96d192a4 100644
--- a/prism/src/parser/visitor/ExpressionTraverseNonNested.java
+++ b/prism/src/parser/visitor/ExpressionTraverseNonNested.java
@@ -26,26 +26,33 @@
package parser.visitor;
+import parser.ast.ExpressionExists;
+import parser.ast.ExpressionForAll;
import parser.ast.ExpressionProb;
import parser.ast.ExpressionReward;
import parser.ast.ExpressionSS;
+import parser.ast.ExpressionStrategy;
import prism.PrismLangException;
/**
- * Base class for recursively traversing an Expression, but not
- * entering nested P/R/SS subexpressions.
- *
- * By default, will not recurse into the P/R/SS elements, but
- * can be configured to allow a certain amount of nested P/R/SS
- * elements before stopping.
- *
- *
- * Subclasses should not override
+ * Base class for recursively traversing an Expression,
+ * but not recursing into nested state formulas, i.e.,
*
- * - {@code visit(ExpressionProb)}
- * - {@code visit(ExpressionReward)}
- * - {@code visit(ExpressionSS)}
+ * - the P, R, S operators,
+ * - the CTL E and A operators,
+ * - the strategy <<>> and [[]] operators.
*
+ *
+ * Intuitively, given a PRCTL* path formula, all expressions
+ * that form the top-level LTL path formula will be visited,
+ * without recursing into the nested non-Boolean state formulas.
+ *
+ * Optionally, a nesting limit can be specified to allow a given
+ * amount of nesting levels.
+ *
+ *
+ * Subclasses should not override any of the {@code visit(...)} methods;
+ * override the {@code visitPre()} or {@code visitPost()} methods instead.
*/
public class ExpressionTraverseNonNested extends ASTTraverse
{
@@ -73,45 +80,80 @@ public class ExpressionTraverseNonNested extends ASTTraverse
return currentNesting <= nestingLimit;
}
- @Override
- public Object visit(ExpressionProb e) throws PrismLangException
+ /**
+ * Check whether entering a nested expression at the current
+ * nesting level is fine.
+ */
+ private boolean enter()
{
currentNesting++;
// only visit if we are still in limit
if (!inLimit()) {
currentNesting--;
- return null;
+ return false;
}
- Object rv = super.visit(e);
+ return true;
+ }
+
+ /** Exits the current nesting level and return the object resulting from the visit */
+ private Object exit(Object e)
+ {
currentNesting--;
- return rv;
+ return e;
}
+ // P operator
+ @Override
+ public Object visit(ExpressionProb e) throws PrismLangException
+ {
+ if (!enter())
+ return null;
+ return exit(super.visit(e));
+ }
+
+ // R operator
@Override
public Object visit(ExpressionReward e) throws PrismLangException
{
- currentNesting++;
- // only visit if we are still in limit
- if (!inLimit()) {
- currentNesting--;
+ if (!enter())
return null;
- }
- Object rv = super.visit(e);
- currentNesting--;
- return rv;
+ return exit(super.visit(e));
}
+ // S operator
@Override
public Object visit(ExpressionSS e) throws PrismLangException
{
- currentNesting++;
- // only visit if we are still in limit
- if (!inLimit()) {
- currentNesting--;
+ if (!enter())
return null;
- }
- Object rv = super.visit(e);
- currentNesting--;
- return rv;
+ return exit(super.visit(e));
+ }
+
+ // strategy operators
+ @Override
+ public Object visit(ExpressionStrategy e) throws PrismLangException
+ {
+ if (!enter())
+ return null;
+ return exit(super.visit(e));
}
+
+ // CTL E operator
+ @Override
+ public Object visit(ExpressionExists e) throws PrismLangException
+ {
+ if (!enter())
+ return null;
+ return exit(super.visit(e));
+ }
+
+ // CTL A operator
+ @Override
+ public Object visit(ExpressionForAll e) throws PrismLangException
+ {
+ if (!enter())
+ return null;
+ return exit(super.visit(e));
+ }
+
}