Storm 1.14.0.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
PrismParserGrammar.h
Go to the documentation of this file.
1#pragma once
2
3// Include files for file input.
4#include <fstream>
5#include <iomanip>
6#include <memory>
7
12
13namespace storm {
14namespace expressions {
16}
17} // namespace storm
18
19namespace storm {
20namespace parser {
22
23// A class that stores information about the parsed program.
25 public:
26 // Default construct the header information.
28 : modelType(storm::prism::Program::ModelType::UNDEFINED),
29 constants(),
30 formulas(),
35 modules(),
37 labels(),
44 // Map the empty action to index 0.
45 actionIndices.emplace("", 0);
46 }
47
49 // Clear all data except the action to indices mapping.
51 constants.clear();
52 formulas.clear();
55 players.clear();
58 modules.clear();
59 rewardModels.clear();
60 labels.clear();
61 observationLabels.clear();
62 hasInitialConstruct = false;
65 systemCompositionConstruct = boost::none;
66
69 }
70
71 // Members for all essential information that needs to be collected.
73 std::vector<storm::prism::Constant> constants;
74 std::vector<storm::prism::Formula> formulas;
75 std::vector<storm::prism::BooleanVariable> globalBooleanVariables;
76 std::vector<storm::prism::IntegerVariable> globalIntegerVariables;
77 std::map<std::string, uint_fast64_t> moduleToIndexMap;
78 std::map<std::string, uint_fast64_t> actionIndices;
79 std::vector<storm::prism::Module> modules;
80 std::vector<storm::prism::RewardModel> rewardModels;
81 std::vector<storm::prism::Label> labels;
82 std::vector<storm::prism::ObservationLabel> observationLabels;
83 std::vector<storm::prism::Player> players;
84 std::set<uint_fast64_t> playerControlledModules;
85 std::set<uint_fast64_t> playerControlledActions;
86
90 boost::optional<storm::prism::SystemCompositionConstruct> systemCompositionConstruct;
91
92 // Counters to provide unique indexing for commands and updates.
93 uint_fast64_t currentCommandIndex;
94 uint_fast64_t currentUpdateIndex;
95};
96
97class PrismParserGrammar : public qi::grammar<Iterator, storm::prism::Program(), Skipper> {
98 public:
105 static storm::prism::Program parse(std::string const& filename, bool prismCompatability = false);
106
114 static storm::prism::Program parseFromString(std::string const& input, std::string const& filename, bool prismCompatability = false);
115
116 private:
117 struct modelTypeStruct : qi::symbols<char, storm::prism::Program::ModelType> {
118 modelTypeStruct() {
122 }
123 };
124
125 struct keywordsStruct : qi::symbols<char, uint_fast64_t> {
126 keywordsStruct() {
127 add("dtmc", 1)("ctmc", 2)("mdp", 3)("ctmdp", 4)("ma", 5)("pomdp", 6)("pta", 7)("smg", 8)("const", 9)("int", 10)("bool", 11)("module", 12)(
128 "endmodule", 13)("rewards", 14)("endrewards", 15)("true", 16)("false", 17)("min", 18)("max", 19)("floor", 20)("ceil", 21)("init", 22)(
129 "atLeastOneOf", 23)("atMostOneOf", 24)("exactlyOneOf", 25)("endinit", 26)("invariant", 27)("endinvariant", 28)("player", 29)("endplayer", 30);
130 }
131 };
132
133 // Same as keywordsStruct, without the model-type-specific keywords (see isValidIdentifier).
134 struct expressionKeywordsStruct : qi::symbols<char, uint_fast64_t> {
135 expressionKeywordsStruct() {
136 add("dtmc", 1)("ctmc", 2)("mdp", 3)("ctmdp", 4)("ma", 5)("pomdp", 6)("pta", 7)("smg", 8)("const", 9)("int", 10)("bool", 11)("module", 12)(
137 "endmodule", 13)("rewards", 14)("endrewards", 15)("true", 16)("false", 17)("min", 18)("max", 19)("floor", 20)("ceil", 21)("init", 22)(
138 "atLeastOneOf", 23)("atMostOneOf", 24)("exactlyOneOf", 25)("endinit", 26);
139 }
140 };
141
142 // Functor used for annotating entities with line number information.
143 class PositionAnnotation {
144 public:
145 typedef void result_type;
146
147 PositionAnnotation(Iterator first) : first(first) {
148 // Intentionally left empty.
149 }
150
151 template<typename Entity, typename First, typename Last>
152 result_type operator()(Entity& entity, First f, Last) const {
153 entity.setLineNumber(get_line(f));
154 }
155
156 private:
157 std::string filename;
158 Iterator const first;
159 };
160
167 PrismParserGrammar(std::string const& filename, Iterator first, bool prismCompatibility);
168
172 void moveToSecondRun();
173
177 void createFormulaIdentifiers(std::vector<storm::prism::Formula> const& formulas);
178
179 // A flag that stores whether the grammar is currently doing the second run.
180 bool secondRun;
181
182 bool prismCompatibility;
183
189 void allowDoubleLiterals(bool flag);
190
191 // The name of the file being parsed.
192 std::string filename;
193
199 std::string const& getFilename() const;
200
201 // Name of the last identifier that was rejected for coinciding with a reserved keyword.
202 // Only meaningful for diagnosing an actual parse failure, since valid parses may speculatively
203 // (and harmlessly) try identifiers that collide with keywords while exploring grammar alternatives.
204 std::string lastRejectedKeywordIdentifier;
205
206 // Collects the observable variables and maps them to true, if they are actually declared.
207 mutable std::map<std::string, bool> observables;
208
209 // Store the expressions of formulas. They have to be parsed after the first and before the second run
210 std::vector<std::string> formulaExpressions;
211 // Stores a proper order in which formulas can be evaluated. This is necessary since formulas might depend on each other.
212 // E.g. for "formula x = y; formula y = z;" we have to swap the order of the two formulas.
213 std::vector<uint64_t> formulaOrder;
214
215 // A function used for annotating the entities with their position.
216 phoenix::function<PositionAnnotation> annotate;
217
218 // An object gathering information about the program while parsing.
219 GlobalProgramInformation globalProgramInformation;
220
221 // The starting point of the grammar.
222 qi::rule<Iterator, storm::prism::Program(), Skipper> start;
223
224 // Rules for model type.
225 qi::rule<Iterator, storm::prism::Program::ModelType(), Skipper> modelTypeDefinition;
226
227 // Rules for parsing expressions of specific type
228 qi::rule<Iterator, storm::expressions::Expression(), Skipper> boolExpression;
229 qi::rule<Iterator, storm::expressions::Expression(), Skipper> intExpression;
230 qi::rule<Iterator, storm::expressions::Expression(), Skipper> numericalExpression;
231
232 // Rules for parsing the program header.
233 qi::rule<Iterator, storm::prism::Constant(), Skipper> undefinedConstantDefinition;
234 qi::rule<Iterator, storm::prism::Constant(), Skipper> undefinedBooleanConstantDefinition;
235 qi::rule<Iterator, storm::prism::Constant(), Skipper> undefinedIntegerConstantDefinition;
236 qi::rule<Iterator, storm::prism::Constant(), Skipper> undefinedDoubleConstantDefinition;
237 qi::rule<Iterator, storm::prism::Constant(), Skipper> definedConstantDefinition;
238 qi::rule<Iterator, storm::prism::Constant(), Skipper> definedBooleanConstantDefinition;
239 qi::rule<Iterator, storm::prism::Constant(), Skipper> definedIntegerConstantDefinition;
240 qi::rule<Iterator, storm::prism::Constant(), Skipper> definedDoubleConstantDefinition;
241
242 // Rules for global variable definitions.
243 qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> globalVariableDefinition;
244
245 // Rules for modules definition.
246 qi::rule<Iterator, std::string(), Skipper> knownModuleName;
247 qi::rule<Iterator, std::string(), Skipper> freshModuleName;
249 qi::locals<std::vector<storm::prism::BooleanVariable>, std::vector<storm::prism::IntegerVariable>, std::vector<storm::prism::ClockVariable>>,
250 Skipper>
251 moduleDefinition;
252 qi::rule<Iterator, storm::prism::ModuleRenaming, qi::locals<std::map<std::string, std::string>>, Skipper> moduleRenaming;
253 qi::rule<Iterator, storm::prism::Module(GlobalProgramInformation&), qi::locals<std::string, storm::prism::ModuleRenaming>, Skipper> renamedModule;
254
255 // Rules for variable definitions.
256 qi::rule<Iterator,
257 qi::unused_type(std::vector<storm::prism::BooleanVariable>&, std::vector<storm::prism::IntegerVariable>&,
258 std::vector<storm::prism::ClockVariable>&),
259 Skipper>
260 variableDefinition;
261 qi::rule<Iterator, storm::prism::BooleanVariable(), qi::locals<storm::expressions::Expression>, Skipper> booleanVariableDefinition;
262 qi::rule<Iterator, storm::prism::IntegerVariable(), qi::locals<storm::expressions::Expression>, Skipper> integerVariableDefinition;
263 qi::rule<Iterator, storm::prism::IntegerVariable(), qi::locals<storm::expressions::Expression>, Skipper> boundedIntegerVariableDefinition;
264 qi::rule<Iterator, storm::prism::IntegerVariable(), qi::locals<storm::expressions::Expression>, Skipper> unboundedIntegerVariableDefinition;
265 qi::rule<Iterator, storm::prism::ClockVariable(), qi::locals<storm::expressions::Expression>, Skipper> clockVariableDefinition;
266
267 // Rules for command definitions.
268 qi::rule<Iterator, storm::prism::Command(GlobalProgramInformation&), qi::locals<bool>, Skipper> commandDefinition;
269 qi::rule<Iterator, std::vector<storm::prism::Update>(GlobalProgramInformation&), Skipper> updateListDefinition;
270 qi::rule<Iterator, storm::prism::Update(GlobalProgramInformation&), Skipper> updateDefinition;
271 qi::rule<Iterator, typename storm::prism::Update::ExpressionPair, Skipper> likelihoodDefinition;
272 qi::rule<Iterator, std::vector<storm::prism::Assignment>(), Skipper> assignmentDefinitionList;
273 qi::rule<Iterator, storm::prism::Assignment(), Skipper> assignmentDefinition;
274 qi::rule<Iterator, std::string(), Skipper> knownActionName;
275
276 // Rules for reward definitions.
277 qi::rule<Iterator, std::string(), Skipper> freshRewardModelName;
279 qi::locals<std::string, std::vector<storm::prism::StateReward>, std::vector<storm::prism::StateActionReward>,
280 std::vector<storm::prism::TransitionReward>>,
281 Skipper>
282 rewardModelDefinition;
283 qi::rule<Iterator, storm::prism::StateReward(), Skipper> stateRewardDefinition;
284 qi::rule<Iterator, storm::prism::StateActionReward(GlobalProgramInformation&), Skipper> stateActionRewardDefinition;
286 qi::locals<std::string, storm::expressions::Expression, storm::expressions::Expression, storm::expressions::Expression>, Skipper>
287 transitionRewardDefinition;
288
289 // Rules for player definitions
290 qi::rule<Iterator, std::string(), Skipper> freshPlayerName;
291 qi::rule<Iterator, std::string(), qi::locals<std::string>, Skipper> playerControlledActionName;
292 qi::rule<Iterator, std::string(), qi::locals<std::string>, Skipper> playerControlledModuleName;
293 qi::rule<Iterator, storm::prism::Player(GlobalProgramInformation&), qi::locals<std::string, std::vector<std::string>, std::vector<std::string>>, Skipper>
294 playerConstruct;
295
296 // Rules for initial states expression.
297 qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> initialStatesConstruct;
298
299 // Rules for POMDP observables (standard prism)
300 qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> observablesConstruct;
301
302 // Rules for invariant constructs
303 qi::rule<Iterator, storm::expressions::Expression(), Skipper> invariantConstruct;
304
305 // Rules for the system composition.
306 qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> systemCompositionConstruct;
307 qi::rule<Iterator, std::shared_ptr<storm::prism::Composition>(), Skipper> parallelComposition;
308 qi::rule<Iterator, qi::unused_type(), Skipper> synchronizingParallelComposition;
309 qi::rule<Iterator, qi::unused_type(), Skipper> interleavingParallelComposition;
310 qi::rule<Iterator, std::set<std::string>(), Skipper> restrictedParallelComposition;
311 qi::rule<Iterator, std::shared_ptr<storm::prism::Composition>(), Skipper> hidingOrRenamingComposition;
312 qi::rule<Iterator, std::shared_ptr<storm::prism::Composition>(), Skipper> hidingComposition;
313 qi::rule<Iterator, std::shared_ptr<storm::prism::Composition>(), Skipper> renamingComposition;
314 qi::rule<Iterator, std::shared_ptr<storm::prism::Composition>(), Skipper> atomicComposition;
315 qi::rule<Iterator, std::shared_ptr<storm::prism::Composition>(), Skipper> moduleComposition;
316 qi::rule<Iterator, std::set<std::string>(), Skipper> actionNameList;
317 qi::rule<Iterator, std::map<std::string, std::string>(), Skipper> actionRenamingList;
318
319 // Rules for label definitions.
320 qi::rule<Iterator, storm::prism::Label(), Skipper> labelDefinition;
321 qi::rule<Iterator, std::string(), Skipper> freshLabelName;
322
323 // Rules for observable (observation-label) definitions.
324 qi::rule<Iterator, storm::prism::ObservationLabel(), Skipper> observableDefinition;
325 qi::rule<Iterator, std::string(), Skipper> freshObservationLabelName;
326
327 // Rules for formula definitions.
328 qi::rule<Iterator, std::string(), Skipper> formulaDefinitionRhs;
329 qi::rule<Iterator, storm::prism::Formula(), Skipper> formulaDefinition;
330
331 // Rules for identifier parsing.
332 qi::rule<Iterator, std::string(), Skipper> identifier;
333 qi::rule<Iterator, std::string(), Skipper> freshIdentifier;
334
335 // Parsers that recognize special keywords and model types.
336 storm::parser::PrismParserGrammar::keywordsStruct keywords_;
337 // Same as keywords_, but without the keywords that are only reserved for a specific model type
338 // (see isValidIdentifier) -- the model type is not statically known here, so this is unconditional.
339 storm::parser::PrismParserGrammar::expressionKeywordsStruct expressionKeywords_;
340 storm::parser::PrismParserGrammar::modelTypeStruct modelType_;
341 qi::symbols<char, storm::expressions::Expression> identifiers_;
342
343 // Parser and manager used for recognizing expressions.
344 std::shared_ptr<storm::expressions::ExpressionManager> manager;
345 std::shared_ptr<storm::parser::ExpressionParser> expressionParser;
346
347 // Helper methods used in the grammar.
348 bool isValidIdentifier(std::string const& identifier);
349 // Logs the last keyword collision recorded by isValidIdentifier, if any. Called from the top-level error handler.
350 void reportRejectedKeywordIdentifier();
351 bool isFreshIdentifier(std::string const& identifier);
352 bool isKnownModuleName(std::string const& moduleName, bool inSecondRun);
353 bool isFreshModuleName(std::string const& moduleName);
354 bool isKnownActionName(std::string const& actionName, bool inSecondRun);
355 bool isFreshLabelName(std::string const& moduleName);
356 bool isFreshObservationLabelName(std::string const& labelName);
357 bool isFreshRewardModelName(std::string const& moduleName);
358 bool isFreshPlayerName(std::string const& playerName);
359 bool isOfBoolType(storm::expressions::Expression const& expression);
360 bool isOfIntType(storm::expressions::Expression const& expression);
361 bool isOfNumericalType(storm::expressions::Expression const& expression);
362 bool isValidModuleRenaming(std::string const& oldModuleName, storm::prism::ModuleRenaming const& renaming,
363 GlobalProgramInformation const& globalProgramInformation) const;
364 bool addInitialStatesConstruct(storm::expressions::Expression const& initialStatesExpression, GlobalProgramInformation& globalProgramInformation);
365 bool addSystemCompositionConstruct(std::shared_ptr<storm::prism::Composition> const& composition, GlobalProgramInformation& globalProgramInformation);
366 void setModelType(GlobalProgramInformation& globalProgramInformation, storm::prism::Program::ModelType const& modelType);
367
368 std::shared_ptr<storm::prism::Composition> createModuleComposition(std::string const& moduleName) const;
369 std::shared_ptr<storm::prism::Composition> createRenamingComposition(std::shared_ptr<storm::prism::Composition> const& subcomposition,
370 std::map<std::string, std::string> const& renaming) const;
371 std::shared_ptr<storm::prism::Composition> createHidingComposition(std::shared_ptr<storm::prism::Composition> const& subcomposition,
372 std::set<std::string> const& actionsToHide) const;
373 std::shared_ptr<storm::prism::Composition> createSynchronizingParallelComposition(std::shared_ptr<storm::prism::Composition> const& left,
374 std::shared_ptr<storm::prism::Composition> const& right) const;
375 std::shared_ptr<storm::prism::Composition> createInterleavingParallelComposition(std::shared_ptr<storm::prism::Composition> const& left,
376 std::shared_ptr<storm::prism::Composition> const& right) const;
377 std::shared_ptr<storm::prism::Composition> createRestrictedParallelComposition(std::shared_ptr<storm::prism::Composition> const& left,
378 std::set<std::string> const& synchronizingActions,
379 std::shared_ptr<storm::prism::Composition> const& right) const;
380
381 storm::prism::Constant createUndefinedBooleanConstant(std::string const& newConstant) const;
382 storm::prism::Constant createUndefinedIntegerConstant(std::string const& newConstant) const;
383 storm::prism::Constant createUndefinedDoubleConstant(std::string const& newConstant) const;
384 storm::prism::Constant createDefinedBooleanConstant(std::string const& newConstant, storm::expressions::Expression expression) const;
385 storm::prism::Constant createDefinedIntegerConstant(std::string const& newConstant, storm::expressions::Expression expression) const;
386 storm::prism::Constant createDefinedDoubleConstant(std::string const& newConstant, storm::expressions::Expression expression) const;
387 storm::prism::Formula createFormulaFirstRun(std::string const& formulaName, std::string const& expression);
388 storm::prism::Formula createFormulaSecondRun(std::string const& formulaName, storm::expressions::Expression const& expression);
389 storm::prism::Label createLabel(std::string const& labelName, storm::expressions::Expression expression) const;
390 storm::prism::ObservationLabel createObservationLabel(std::string const& labelName, storm::expressions::Expression expression) const;
391 storm::prism::RewardModel createRewardModel(std::string const& rewardModelName, std::vector<storm::prism::StateReward> const& stateRewards,
392 std::vector<storm::prism::StateActionReward> const& stateActionRewards,
393 std::vector<storm::prism::TransitionReward> const& transitionRewards) const;
394 storm::prism::StateReward createStateReward(storm::expressions::Expression statePredicateExpression,
395 storm::expressions::Expression rewardValueExpression) const;
396 storm::prism::StateActionReward createStateActionReward(boost::optional<std::string> const& actionName,
397 storm::expressions::Expression statePredicateExpression,
398 storm::expressions::Expression rewardValueExpression,
399 GlobalProgramInformation& globalProgramInformation) const;
400 storm::prism::TransitionReward createTransitionReward(boost::optional<std::string> const& actionName,
401 storm::expressions::Expression sourceStatePredicateExpression,
402 storm::expressions::Expression targetStatePredicateExpression,
403 storm::expressions::Expression rewardValueExpression,
404 GlobalProgramInformation& globalProgramInformation) const;
405 storm::prism::Assignment createAssignment(std::string const& variableName, storm::expressions::Expression assignedExpression) const;
406 storm::prism::Update createUpdate(typename storm::prism::Update::ExpressionPair likelihoodExpressions,
407 std::vector<storm::prism::Assignment> const& assignments, GlobalProgramInformation& globalProgramInformation) const;
408
409 storm::prism::Command createCommand(bool markovianCommand, boost::optional<std::string> const& actionName, storm::expressions::Expression guardExpression,
410 std::vector<storm::prism::Update> const& updates, GlobalProgramInformation& globalProgramInformation) const;
411 storm::prism::Command createDummyCommand(boost::optional<std::string> const& actionName, GlobalProgramInformation& globalProgramInformation) const;
412 storm::prism::BooleanVariable createBooleanVariable(std::string const& variableName, storm::expressions::Expression initialValueExpression) const;
413 storm::prism::IntegerVariable createIntegerVariable(std::string const& variableName, storm::expressions::Expression lowerBoundExpression,
414 storm::expressions::Expression upperBoundExpression,
415 storm::expressions::Expression initialValueExpression) const;
416 storm::prism::ClockVariable createClockVariable(std::string const& variableName) const;
417 storm::prism::Module createModule(std::string const& moduleName, std::vector<storm::prism::BooleanVariable> const& booleanVariables,
418 std::vector<storm::prism::IntegerVariable> const& integerVariables,
419 std::vector<storm::prism::ClockVariable> const& clockVariables,
420 boost::optional<storm::expressions::Expression> const& invariant, std::vector<storm::prism::Command> const& commands,
421 GlobalProgramInformation& globalProgramInformation) const;
422 storm::prism::ModuleRenaming createModuleRenaming(std::map<std::string, std::string> const& renaming) const;
423 storm::prism::Module createRenamedModule(std::string const& newModuleName, std::string const& oldModuleName, storm::prism::ModuleRenaming const& renaming,
424 GlobalProgramInformation& globalProgramInformation) const;
425 storm::prism::Player createPlayer(std::string const& playerName, std::vector<std::string> const& moduleNames, std::vector<std::string> const& commandNames);
426 storm::prism::Program createProgram(GlobalProgramInformation const& globalProgramInformation) const;
427 bool addObservablesConstruct(std::vector<std::string> const& observables, GlobalProgramInformation& globalProgramInformation);
428
429 void removeInitialConstruct(GlobalProgramInformation& globalProgramInformation) const;
430
431 // An error handler function.
432 phoenix::function<SpiritErrorHandler> handler;
433};
434} // namespace parser
435} // namespace storm
PositionIteratorType Iterator
This class is responsible for managing a set of typed variables and all expressions using these varia...
std::vector< storm::prism::ObservationLabel > observationLabels
std::vector< storm::prism::Module > modules
std::vector< storm::prism::Constant > constants
std::vector< storm::prism::Label > labels
storm::prism::Program::ModelType modelType
std::set< uint_fast64_t > playerControlledActions
std::vector< storm::prism::Player > players
std::vector< storm::prism::BooleanVariable > globalBooleanVariables
std::vector< storm::prism::Formula > formulas
boost::optional< storm::prism::SystemCompositionConstruct > systemCompositionConstruct
std::map< std::string, uint_fast64_t > actionIndices
storm::prism::InitialConstruct initialConstruct
std::vector< storm::prism::RewardModel > rewardModels
std::map< std::string, uint_fast64_t > moduleToIndexMap
std::set< uint_fast64_t > playerControlledModules
std::vector< storm::prism::IntegerVariable > globalIntegerVariables
static storm::prism::Program parseFromString(std::string const &input, std::string const &filename, bool prismCompatability=false)
Parses the given input stream into the PRISM storage classes assuming it complies with the PRISM synt...
static storm::prism::Program parse(std::string const &filename, bool prismCompatability=false)
Parses the given file into the PRISM storage classes assuming it complies with the PRISM syntax.
ModelType
An enum for the different model types.
Definition Program.h:35
std::pair< storm::expressions::Expression, storm::expressions::Expression > ExpressionPair
Definition Update.h:12
Contains all file parsers and helper classes.