Storm
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 {
15class ExpressionManager;
16}
17} // namespace storm
18
19namespace storm {
20namespace parser {
21class ExpressionParser;
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(),
43 // Map the empty action to index 0.
44 actionIndices.emplace("", 0);
45 }
46
48 // Clear all data except the action to indices mapping.
50 constants.clear();
51 formulas.clear();
54 players.clear();
57 modules.clear();
58 rewardModels.clear();
59 labels.clear();
60 observationLabels.clear();
61 hasInitialConstruct = false;
63 systemCompositionConstruct = boost::none;
64
67 }
68
69 // Members for all essential information that needs to be collected.
71 std::vector<storm::prism::Constant> constants;
72 std::vector<storm::prism::Formula> formulas;
73 std::vector<storm::prism::BooleanVariable> globalBooleanVariables;
74 std::vector<storm::prism::IntegerVariable> globalIntegerVariables;
75 std::map<std::string, uint_fast64_t> moduleToIndexMap;
76 std::map<std::string, uint_fast64_t> actionIndices;
77 std::vector<storm::prism::Module> modules;
78 std::vector<storm::prism::RewardModel> rewardModels;
79 std::vector<storm::prism::Label> labels;
80 std::vector<storm::prism::ObservationLabel> observationLabels;
81 std::vector<storm::prism::Player> players;
82 std::set<uint_fast64_t> playerControlledModules;
83 std::set<uint_fast64_t> playerControlledActions;
84
87 boost::optional<storm::prism::SystemCompositionConstruct> systemCompositionConstruct;
88
89 // Counters to provide unique indexing for commands and updates.
90 uint_fast64_t currentCommandIndex;
91 uint_fast64_t currentUpdateIndex;
92};
93
94class PrismParserGrammar : public qi::grammar<Iterator, storm::prism::Program(), Skipper> {
95 public:
102 static storm::prism::Program parse(std::string const& filename, bool prismCompatability = false);
103
111 static storm::prism::Program parseFromString(std::string const& input, std::string const& filename, bool prismCompatability = false);
112
113 private:
114 struct modelTypeStruct : qi::symbols<char, storm::prism::Program::ModelType> {
115 modelTypeStruct() {
119 }
120 };
121
122 struct keywordsStruct : qi::symbols<char, uint_fast64_t> {
123 keywordsStruct() {
124 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)(
125 "endmodule", 13)("rewards", 14)("endrewards", 15)("true", 16)("false", 17)("min", 18)("max", 19)("floor", 20)("ceil", 21)("init", 22)(
126 "atLeastOneOf", 23)("atMostOneOf", 24)("exactlyOneOf", 25)("endinit", 26)("invariant", 27)("endinvariant", 28)("player", 29)("endplayer", 30);
127 }
128 };
129
130 // Functor used for annotating entities with line number information.
131 class PositionAnnotation {
132 public:
133 typedef void result_type;
134
135 PositionAnnotation(Iterator first) : first(first) {
136 // Intentionally left empty.
137 }
138
139 template<typename Entity, typename First, typename Last>
140 result_type operator()(Entity& entity, First f, Last) const {
141 entity.setLineNumber(get_line(f));
142 }
143
144 private:
145 std::string filename;
146 Iterator const first;
147 };
148
155 PrismParserGrammar(std::string const& filename, Iterator first, bool prismCompatibility);
156
160 void moveToSecondRun();
161
165 void createFormulaIdentifiers(std::vector<storm::prism::Formula> const& formulas);
166
167 // A flag that stores whether the grammar is currently doing the second run.
168 bool secondRun;
169
170 bool prismCompatibility;
171
177 void allowDoubleLiterals(bool flag);
178
179 // The name of the file being parsed.
180 std::string filename;
181
187 std::string const& getFilename() const;
188
189 mutable std::set<std::string> observables;
190
191 // Store the expressions of formulas. They have to be parsed after the first and before the second run
192 std::vector<std::string> formulaExpressions;
193 // Stores a proper order in which formulas can be evaluated. This is necessary since formulas might depend on each other.
194 // E.g. for "formula x = y; formula y = z;" we have to swap the order of the two formulas.
195 std::vector<uint64_t> formulaOrder;
196
197 // A function used for annotating the entities with their position.
198 phoenix::function<PositionAnnotation> annotate;
199
200 // An object gathering information about the program while parsing.
201 GlobalProgramInformation globalProgramInformation;
202
203 // The starting point of the grammar.
204 qi::rule<Iterator, storm::prism::Program(), Skipper> start;
205
206 // Rules for model type.
207 qi::rule<Iterator, storm::prism::Program::ModelType(), Skipper> modelTypeDefinition;
208
209 // Rules for parsing expressions of specific type
210 qi::rule<Iterator, storm::expressions::Expression(), Skipper> boolExpression;
211 qi::rule<Iterator, storm::expressions::Expression(), Skipper> intExpression;
212 qi::rule<Iterator, storm::expressions::Expression(), Skipper> numericalExpression;
213
214 // Rules for parsing the program header.
215 qi::rule<Iterator, storm::prism::Constant(), Skipper> undefinedConstantDefinition;
216 qi::rule<Iterator, storm::prism::Constant(), Skipper> undefinedBooleanConstantDefinition;
217 qi::rule<Iterator, storm::prism::Constant(), Skipper> undefinedIntegerConstantDefinition;
218 qi::rule<Iterator, storm::prism::Constant(), Skipper> undefinedDoubleConstantDefinition;
219 qi::rule<Iterator, storm::prism::Constant(), Skipper> definedConstantDefinition;
220 qi::rule<Iterator, storm::prism::Constant(), Skipper> definedBooleanConstantDefinition;
221 qi::rule<Iterator, storm::prism::Constant(), Skipper> definedIntegerConstantDefinition;
222 qi::rule<Iterator, storm::prism::Constant(), Skipper> definedDoubleConstantDefinition;
223
224 // Rules for global variable definitions.
225 qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> globalVariableDefinition;
226
227 // Rules for modules definition.
228 qi::rule<Iterator, std::string(), Skipper> knownModuleName;
229 qi::rule<Iterator, std::string(), Skipper> freshModuleName;
231 qi::locals<std::vector<storm::prism::BooleanVariable>, std::vector<storm::prism::IntegerVariable>, std::vector<storm::prism::ClockVariable>>,
232 Skipper>
233 moduleDefinition;
234 qi::rule<Iterator, storm::prism::ModuleRenaming, qi::locals<std::map<std::string, std::string>>, Skipper> moduleRenaming;
235 qi::rule<Iterator, storm::prism::Module(GlobalProgramInformation&), qi::locals<std::string, storm::prism::ModuleRenaming>, Skipper> renamedModule;
236
237 // Rules for variable definitions.
238 qi::rule<Iterator,
239 qi::unused_type(std::vector<storm::prism::BooleanVariable>&, std::vector<storm::prism::IntegerVariable>&,
240 std::vector<storm::prism::ClockVariable>&),
241 Skipper>
242 variableDefinition;
243 qi::rule<Iterator, storm::prism::BooleanVariable(), qi::locals<storm::expressions::Expression>, Skipper> booleanVariableDefinition;
244 qi::rule<Iterator, storm::prism::IntegerVariable(), qi::locals<storm::expressions::Expression>, Skipper> integerVariableDefinition;
245 qi::rule<Iterator, storm::prism::IntegerVariable(), qi::locals<storm::expressions::Expression>, Skipper> boundedIntegerVariableDefinition;
246 qi::rule<Iterator, storm::prism::IntegerVariable(), qi::locals<storm::expressions::Expression>, Skipper> unboundedIntegerVariableDefinition;
247 qi::rule<Iterator, storm::prism::ClockVariable(), qi::locals<storm::expressions::Expression>, Skipper> clockVariableDefinition;
248
249 // Rules for command definitions.
250 qi::rule<Iterator, storm::prism::Command(GlobalProgramInformation&), qi::locals<bool>, Skipper> commandDefinition;
251 qi::rule<Iterator, std::vector<storm::prism::Update>(GlobalProgramInformation&), Skipper> updateListDefinition;
252 qi::rule<Iterator, storm::prism::Update(GlobalProgramInformation&), Skipper> updateDefinition;
253 qi::rule<Iterator, std::vector<storm::prism::Assignment>(), Skipper> assignmentDefinitionList;
254 qi::rule<Iterator, storm::prism::Assignment(), Skipper> assignmentDefinition;
255 qi::rule<Iterator, std::string(), Skipper> knownActionName;
256
257 // Rules for reward definitions.
258 qi::rule<Iterator, std::string(), Skipper> freshRewardModelName;
260 qi::locals<std::string, std::vector<storm::prism::StateReward>, std::vector<storm::prism::StateActionReward>,
261 std::vector<storm::prism::TransitionReward>>,
262 Skipper>
263 rewardModelDefinition;
264 qi::rule<Iterator, storm::prism::StateReward(), Skipper> stateRewardDefinition;
265 qi::rule<Iterator, storm::prism::StateActionReward(GlobalProgramInformation&), Skipper> stateActionRewardDefinition;
267 qi::locals<std::string, storm::expressions::Expression, storm::expressions::Expression, storm::expressions::Expression>, Skipper>
268 transitionRewardDefinition;
269
270 // Rules for player definitions
271 qi::rule<Iterator, std::string(), Skipper> freshPlayerName;
272 qi::rule<Iterator, std::string(), qi::locals<std::string>, Skipper> playerControlledActionName;
273 qi::rule<Iterator, std::string(), qi::locals<std::string>, Skipper> playerControlledModuleName;
274 qi::rule<Iterator, storm::prism::Player(GlobalProgramInformation&), qi::locals<std::string, std::vector<std::string>, std::vector<std::string>>, Skipper>
275 playerConstruct;
276
277 // Rules for initial states expression.
278 qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> initialStatesConstruct;
279
280 // Rules for POMDP observables (standard prism)
281 qi::rule<Iterator, qi::unused_type(), Skipper> observablesConstruct;
282
283 // Rules for invariant constructs
284 qi::rule<Iterator, storm::expressions::Expression(), Skipper> invariantConstruct;
285
286 // Rules for the system composition.
287 qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> systemCompositionConstruct;
288 qi::rule<Iterator, std::shared_ptr<storm::prism::Composition>(), Skipper> parallelComposition;
289 qi::rule<Iterator, qi::unused_type(), Skipper> synchronizingParallelComposition;
290 qi::rule<Iterator, qi::unused_type(), Skipper> interleavingParallelComposition;
291 qi::rule<Iterator, std::set<std::string>(), Skipper> restrictedParallelComposition;
292 qi::rule<Iterator, std::shared_ptr<storm::prism::Composition>(), Skipper> hidingOrRenamingComposition;
293 qi::rule<Iterator, std::shared_ptr<storm::prism::Composition>(), Skipper> hidingComposition;
294 qi::rule<Iterator, std::shared_ptr<storm::prism::Composition>(), Skipper> renamingComposition;
295 qi::rule<Iterator, std::shared_ptr<storm::prism::Composition>(), Skipper> atomicComposition;
296 qi::rule<Iterator, std::shared_ptr<storm::prism::Composition>(), Skipper> moduleComposition;
297 qi::rule<Iterator, std::set<std::string>(), Skipper> actionNameList;
298 qi::rule<Iterator, std::map<std::string, std::string>(), Skipper> actionRenamingList;
299
300 // Rules for label definitions.
301 qi::rule<Iterator, storm::prism::Label(), Skipper> labelDefinition;
302 qi::rule<Iterator, std::string(), Skipper> freshLabelName;
303
304 // Rules for observable (observation-label) definitions.
305 qi::rule<Iterator, storm::prism::ObservationLabel(), Skipper> observableDefinition;
306 qi::rule<Iterator, std::string(), Skipper> freshObservationLabelName;
307
308 // Rules for formula definitions.
309 qi::rule<Iterator, std::string(), Skipper> formulaDefinitionRhs;
310 qi::rule<Iterator, storm::prism::Formula(), Skipper> formulaDefinition;
311
312 // Rules for identifier parsing.
313 qi::rule<Iterator, std::string(), Skipper> identifier;
314 qi::rule<Iterator, std::string(), Skipper> freshIdentifier;
315
316 // Parsers that recognize special keywords and model types.
317 storm::parser::PrismParserGrammar::keywordsStruct keywords_;
318 storm::parser::PrismParserGrammar::modelTypeStruct modelType_;
319 qi::symbols<char, storm::expressions::Expression> identifiers_;
320
321 // Parser and manager used for recognizing expressions.
322 std::shared_ptr<storm::expressions::ExpressionManager> manager;
323 std::shared_ptr<storm::parser::ExpressionParser> expressionParser;
324
325 // Helper methods used in the grammar.
326 bool isValidIdentifier(std::string const& identifier);
327 bool isFreshIdentifier(std::string const& identifier);
328 bool isKnownModuleName(std::string const& moduleName, bool inSecondRun);
329 bool isFreshModuleName(std::string const& moduleName);
330 bool isKnownActionName(std::string const& actionName, bool inSecondRun);
331 bool isFreshLabelName(std::string const& moduleName);
332 bool isFreshObservationLabelName(std::string const& labelName);
333 bool isFreshRewardModelName(std::string const& moduleName);
334 bool isFreshPlayerName(std::string const& playerName);
335 bool isOfBoolType(storm::expressions::Expression const& expression);
336 bool isOfIntType(storm::expressions::Expression const& expression);
337 bool isOfNumericalType(storm::expressions::Expression const& expression);
338 bool isValidModuleRenaming(std::string const& oldModuleName, storm::prism::ModuleRenaming const& renaming,
339 GlobalProgramInformation const& globalProgramInformation) const;
340 bool addInitialStatesConstruct(storm::expressions::Expression const& initialStatesExpression, GlobalProgramInformation& globalProgramInformation);
341 bool addSystemCompositionConstruct(std::shared_ptr<storm::prism::Composition> const& composition, GlobalProgramInformation& globalProgramInformation);
342 void setModelType(GlobalProgramInformation& globalProgramInformation, storm::prism::Program::ModelType const& modelType);
343
344 std::shared_ptr<storm::prism::Composition> createModuleComposition(std::string const& moduleName) const;
345 std::shared_ptr<storm::prism::Composition> createRenamingComposition(std::shared_ptr<storm::prism::Composition> const& subcomposition,
346 std::map<std::string, std::string> const& renaming) const;
347 std::shared_ptr<storm::prism::Composition> createHidingComposition(std::shared_ptr<storm::prism::Composition> const& subcomposition,
348 std::set<std::string> const& actionsToHide) const;
349 std::shared_ptr<storm::prism::Composition> createSynchronizingParallelComposition(std::shared_ptr<storm::prism::Composition> const& left,
350 std::shared_ptr<storm::prism::Composition> const& right) const;
351 std::shared_ptr<storm::prism::Composition> createInterleavingParallelComposition(std::shared_ptr<storm::prism::Composition> const& left,
352 std::shared_ptr<storm::prism::Composition> const& right) const;
353 std::shared_ptr<storm::prism::Composition> createRestrictedParallelComposition(std::shared_ptr<storm::prism::Composition> const& left,
354 std::set<std::string> const& synchronizingActions,
355 std::shared_ptr<storm::prism::Composition> const& right) const;
356
357 storm::prism::Constant createUndefinedBooleanConstant(std::string const& newConstant) const;
358 storm::prism::Constant createUndefinedIntegerConstant(std::string const& newConstant) const;
359 storm::prism::Constant createUndefinedDoubleConstant(std::string const& newConstant) const;
360 storm::prism::Constant createDefinedBooleanConstant(std::string const& newConstant, storm::expressions::Expression expression) const;
361 storm::prism::Constant createDefinedIntegerConstant(std::string const& newConstant, storm::expressions::Expression expression) const;
362 storm::prism::Constant createDefinedDoubleConstant(std::string const& newConstant, storm::expressions::Expression expression) const;
363 storm::prism::Formula createFormulaFirstRun(std::string const& formulaName, std::string const& expression);
364 storm::prism::Formula createFormulaSecondRun(std::string const& formulaName, storm::expressions::Expression const& expression);
365 storm::prism::Label createLabel(std::string const& labelName, storm::expressions::Expression expression) const;
366 storm::prism::ObservationLabel createObservationLabel(std::string const& labelName, storm::expressions::Expression expression) const;
367 storm::prism::RewardModel createRewardModel(std::string const& rewardModelName, std::vector<storm::prism::StateReward> const& stateRewards,
368 std::vector<storm::prism::StateActionReward> const& stateActionRewards,
369 std::vector<storm::prism::TransitionReward> const& transitionRewards) const;
370 storm::prism::StateReward createStateReward(storm::expressions::Expression statePredicateExpression,
371 storm::expressions::Expression rewardValueExpression) const;
372 storm::prism::StateActionReward createStateActionReward(boost::optional<std::string> const& actionName,
373 storm::expressions::Expression statePredicateExpression,
374 storm::expressions::Expression rewardValueExpression,
375 GlobalProgramInformation& globalProgramInformation) const;
376 storm::prism::TransitionReward createTransitionReward(boost::optional<std::string> const& actionName,
377 storm::expressions::Expression sourceStatePredicateExpression,
378 storm::expressions::Expression targetStatePredicateExpression,
379 storm::expressions::Expression rewardValueExpression,
380 GlobalProgramInformation& globalProgramInformation) const;
381 storm::prism::Assignment createAssignment(std::string const& variableName, storm::expressions::Expression assignedExpression) const;
382 storm::prism::Update createUpdate(storm::expressions::Expression likelihoodExpression, std::vector<storm::prism::Assignment> const& assignments,
383 GlobalProgramInformation& globalProgramInformation) const;
384 storm::prism::Command createCommand(bool markovianCommand, boost::optional<std::string> const& actionName, storm::expressions::Expression guardExpression,
385 std::vector<storm::prism::Update> const& updates, GlobalProgramInformation& globalProgramInformation) const;
386 storm::prism::Command createDummyCommand(boost::optional<std::string> const& actionName, GlobalProgramInformation& globalProgramInformation) const;
387 storm::prism::BooleanVariable createBooleanVariable(std::string const& variableName, storm::expressions::Expression initialValueExpression) const;
388 storm::prism::IntegerVariable createIntegerVariable(std::string const& variableName, storm::expressions::Expression lowerBoundExpression,
389 storm::expressions::Expression upperBoundExpression,
390 storm::expressions::Expression initialValueExpression) const;
391 storm::prism::ClockVariable createClockVariable(std::string const& variableName) const;
392 storm::prism::Module createModule(std::string const& moduleName, std::vector<storm::prism::BooleanVariable> const& booleanVariables,
393 std::vector<storm::prism::IntegerVariable> const& integerVariables,
394 std::vector<storm::prism::ClockVariable> const& clockVariables,
395 boost::optional<storm::expressions::Expression> const& invariant, std::vector<storm::prism::Command> const& commands,
396 GlobalProgramInformation& globalProgramInformation) const;
397 storm::prism::ModuleRenaming createModuleRenaming(std::map<std::string, std::string> const& renaming) const;
398 storm::prism::Module createRenamedModule(std::string const& newModuleName, std::string const& oldModuleName, storm::prism::ModuleRenaming const& renaming,
399 GlobalProgramInformation& globalProgramInformation) const;
400 storm::prism::Player createPlayer(std::string const& playerName, std::vector<std::string> const& moduleNames, std::vector<std::string> const& commandNames);
401 storm::prism::Program createProgram(GlobalProgramInformation const& globalProgramInformation) const;
402 void createObservablesList(std::vector<std::string> const& observables);
403
404 void removeInitialConstruct(GlobalProgramInformation& globalProgramInformation) const;
405
406 // An error handler function.
407 phoenix::function<SpiritErrorHandler> handler;
408};
409} // namespace parser
410} // namespace storm
PositionIteratorType Iterator
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:37
LabParser.cpp.
Definition cli.cpp:18