diff --git a/prism/src/parser/ExplicitFiles2ModulesFile.java b/prism/src/parser/ExplicitFiles2ModulesFile.java
index a606acd8..487fdc34 100644
--- a/prism/src/parser/ExplicitFiles2ModulesFile.java
+++ b/prism/src/parser/ExplicitFiles2ModulesFile.java
@@ -30,12 +30,17 @@ import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import parser.ast.Declaration;
import parser.ast.DeclarationBool;
import parser.ast.DeclarationInt;
import parser.ast.DeclarationType;
import parser.ast.Expression;
+import parser.ast.ExpressionIdent;
+import parser.ast.ExpressionLiteral;
+import parser.ast.LabelList;
import parser.ast.Module;
import parser.ast.ModulesFile;
import parser.type.Type;
@@ -70,10 +75,14 @@ public class ExplicitFiles2ModulesFile extends PrismComponent
}
/**
- * Build a ModulesFile corresponding to the passed in states/transitions files.
+ * Build a ModulesFile corresponding to the passed in states/transitions/labels files.
* If {@code typeOverride} is null, we assume model is an MDP.
+ *
+ * @param statesFile states file (may be {@code null})
+ * @param transFile transitions file
+ * @param labelsFile labels file (may be {@code null})
*/
- public ModulesFile buildModulesFile(File statesFile, File transFile, ModelType typeOverride) throws PrismException
+ public ModulesFile buildModulesFile(File statesFile, File transFile, File labelsFile, ModelType typeOverride) throws PrismException
{
ModulesFile modulesFile;
ModelType modelType;
@@ -85,6 +94,12 @@ public class ExplicitFiles2ModulesFile extends PrismComponent
modulesFile = createVarInfoFromTransFile(transFile);
}
+ // Generate and store a label list from the labelsFile, if available.
+ // This way, expressions can refer to the labels later on.
+ if (labelsFile != null) {
+ modulesFile.setLabelList(createLabelListFromLabelsFile(labelsFile));
+ }
+
// Set model type: if no preference stated, assume default of MDP
modelType = (typeOverride == null) ? ModelType.MDP : typeOverride;
modulesFile.setModelType(modelType);
@@ -251,4 +266,51 @@ public class ExplicitFiles2ModulesFile extends PrismComponent
return modulesFile;
}
+
+
+ /**
+ * Create a LabelList from a labels file, i.e., a label definition per
+ * label that is encountered in the file.
+ *
+ * In the label definitions, the label expression is set to "false",
+ * the actual information about the states belonging to the label
+ * is later on directly stored in the model.
+ *
+ * The "init" and "deadlock" labels are skipped, as they have special
+ * meaning and are implicitly defined for all models.
+ */
+ private LabelList createLabelListFromLabelsFile(File labelsFile) throws PrismException
+ {
+ LabelList list = new LabelList();
+
+ try (BufferedReader in = new BufferedReader(new FileReader(labelsFile))) {
+ // read first line (label names)
+ String labelNames = in.readLine();
+ // split
+ Pattern label = Pattern.compile("(\\d+)=\"([^\"]+)\"\\s*");
+ Matcher matcher = label.matcher(labelNames);
+ while (matcher.find()) {
+ String labelName = matcher.group(2);
+
+ if (labelName.equals("init") || labelName.equals("deadlock")) {
+ // "init" and "deadlock" are special labels that exist
+ // in every model, so we don't need to add them to the ModulesFile
+ continue;
+ }
+
+ // TODO: Check that label name is valid identifier
+
+ if (list.getLabelIndex(labelName) != -1) {
+ throw new PrismException("duplicate label \"" + labelName + "\"");
+ }
+
+ Expression falseExpression = new ExpressionLiteral(TypeBool.getInstance(), false);
+ list.addLabel(new ExpressionIdent(labelName), falseExpression);
+ }
+ } catch (IOException e) {
+ throw new PrismException("File I/O error reading from \"" + labelsFile + "\"");
+ }
+ return list;
+ }
+
}
diff --git a/prism/src/prism/Prism.java b/prism/src/prism/Prism.java
index 3fe7eb64..00aeebea 100644
--- a/prism/src/prism/Prism.java
+++ b/prism/src/prism/Prism.java
@@ -1834,7 +1834,7 @@ public class Prism extends PrismComponent implements PrismSettingsListener
clearBuiltModel();
// Construct ModulesFile
ExplicitFiles2ModulesFile ef2mf = new ExplicitFiles2ModulesFile(this);
- currentModulesFile = ef2mf.buildModulesFile(statesFile, transFile, typeOverride);
+ currentModulesFile = ef2mf.buildModulesFile(statesFile, transFile, labelsFile, typeOverride);
// Store explicit files info for later
explicitFilesStatesFile = statesFile;
explicitFilesTransFile = transFile;