diff --git a/prism/src/prism/ProbModel.java b/prism/src/prism/ProbModel.java
index 0ed024f7..f4d94587 100644
--- a/prism/src/prism/ProbModel.java
+++ b/prism/src/prism/ProbModel.java
@@ -472,6 +472,50 @@ public class ProbModel implements Model
if (old != null) JDD.Deref(old);
}
+ /**
+ * Add a label with corresponding state set, ensuring a unique, non-existing label.
+ * The label will be either "X" or "X_i" where X is the content of the {@code prefix} argument
+ * and i is a non-negative integer.
+ *
+ * Optionally, a set of defined label names can be passed so that those labels
+ * can be avoided. This can be obtained from the model checker via {@code getDefinedLabelNames()}.
+ *
+ * Note that a stored label takes precedence over the on-the-fly calculation
+ * of an ExpressionLabel, cf. {@link explicit.StateModelChecker#checkExpressionLabel}
+ *
[ STORES: labelDD, deref on later call to clear() ]
+ *
+ * @param prefix the prefix for the unique label
+ * @param labelDD the JDDNode with the state set for the label
+ * @param definedLabelNames set of names (optional, may be {@code null}) to check for existing labels
+ * @return the generated unique label
+ */
+ public String addUniqueLabelDD(String prefix, JDDNode labelDD, Set definedLabelNames)
+ {
+ String label;
+ int i = 0;
+ label = prefix; // first, try without appending _i
+ while (true) {
+ boolean labelOk = !hasLabelDD(label); // not directly attached to model
+ if (definedLabelNames != null) {
+ labelOk &= !definedLabelNames.contains(label); // not defined
+ }
+
+ if (labelOk) {
+ break;
+ }
+
+ // prepare next label to try
+ label = prefix+"_"+i;
+ if (i == Integer.MAX_VALUE)
+ throw new UnsupportedOperationException("Integer overflow trying to add unique label");
+
+ i++;
+ }
+
+ addLabelDD(label, labelDD);
+ return label;
+ }
+
/**
* Reset transition matrix DD.
* Note: Update reachable states and call {@code filterReachableStates}