Browse Source

Merge branch 'master' into param_dtmc2smt

Former-commit-id: 7eb2effb2f
main
sjunges 11 years ago
parent
commit
b654866cb2
  1. 9
      CMakeLists.txt
  2. 4
      examples/dtmc/synchronous_leader/leader4_8.pm
  3. 4
      examples/dtmc/synchronous_leader/leader5_8.pm
  4. 4
      examples/dtmc/synchronous_leader/leader6_8.pm
  5. 2
      resources/3rdparty/cudd-2.5.0/src/cudd/cudd.h
  6. 261
      resources/3rdparty/cudd-2.5.0/src/cudd/cuddAddAbs.c
  7. 2
      resources/3rdparty/cudd-2.5.0/src/cudd/cuddInt.h
  8. 17
      resources/3rdparty/cudd-2.5.0/src/obj/cuddObj.cc
  9. 2
      resources/3rdparty/cudd-2.5.0/src/obj/cuddObj.hh
  10. 291
      src/adapters/ExplicitModelAdapter.h
  11. 12
      src/counterexamples/MILPMinimalLabelSetGenerator.h
  12. 2
      src/counterexamples/SMTMinimalCommandSetGenerator.h
  13. 31
      src/exceptions/ExceptionMacros.h
  14. 17
      src/exceptions/InvalidOperationException.h
  15. 18
      src/exceptions/InvalidTypeException.h
  16. 63
      src/ir/Assignment.cpp
  17. 98
      src/ir/Assignment.h
  18. 49
      src/ir/BooleanVariable.cpp
  19. 70
      src/ir/BooleanVariable.h
  20. 94
      src/ir/Command.cpp
  21. 134
      src/ir/Command.h
  22. 25
      src/ir/IR.h
  23. 72
      src/ir/IntegerVariable.cpp
  24. 98
      src/ir/IntegerVariable.h
  25. 217
      src/ir/Module.cpp
  26. 226
      src/ir/Module.h
  27. 300
      src/ir/Program.cpp
  28. 318
      src/ir/Program.h
  29. 53
      src/ir/RewardModel.cpp
  30. 88
      src/ir/RewardModel.h
  31. 60
      src/ir/StateReward.cpp
  32. 85
      src/ir/StateReward.h
  33. 65
      src/ir/TransitionReward.cpp
  34. 99
      src/ir/TransitionReward.h
  35. 130
      src/ir/Update.cpp
  36. 152
      src/ir/Update.h
  37. 74
      src/ir/Variable.cpp
  38. 124
      src/ir/Variable.h
  39. 85
      src/ir/expressions/BaseExpression.cpp
  40. 172
      src/ir/expressions/BaseExpression.h
  41. 67
      src/ir/expressions/BinaryBooleanFunctionExpression.cpp
  42. 69
      src/ir/expressions/BinaryBooleanFunctionExpression.h
  43. 52
      src/ir/expressions/BinaryExpression.cpp
  44. 66
      src/ir/expressions/BinaryExpression.h
  45. 96
      src/ir/expressions/BinaryNumericalFunctionExpression.cpp
  46. 72
      src/ir/expressions/BinaryNumericalFunctionExpression.h
  47. 75
      src/ir/expressions/BinaryRelationExpression.cpp
  48. 69
      src/ir/expressions/BinaryRelationExpression.h
  49. 45
      src/ir/expressions/BooleanConstantExpression.cpp
  50. 49
      src/ir/expressions/BooleanConstantExpression.h
  51. 49
      src/ir/expressions/BooleanLiteralExpression.cpp
  52. 55
      src/ir/expressions/BooleanLiteralExpression.h
  53. 132
      src/ir/expressions/ConstantExpression.h
  54. 45
      src/ir/expressions/DoubleConstantExpression.cpp
  55. 49
      src/ir/expressions/DoubleConstantExpression.h
  56. 49
      src/ir/expressions/DoubleLiteralExpression.cpp
  57. 55
      src/ir/expressions/DoubleLiteralExpression.h
  58. 49
      src/ir/expressions/ExpressionVisitor.h
  59. 26
      src/ir/expressions/Expressions.h
  60. 48
      src/ir/expressions/IntegerConstantExpression.cpp
  61. 51
      src/ir/expressions/IntegerConstantExpression.h
  62. 53
      src/ir/expressions/IntegerLiteralExpression.cpp
  63. 57
      src/ir/expressions/IntegerLiteralExpression.h
  64. 62
      src/ir/expressions/UnaryBooleanFunctionExpression.cpp
  65. 68
      src/ir/expressions/UnaryBooleanFunctionExpression.h
  66. 39
      src/ir/expressions/UnaryExpression.cpp
  67. 55
      src/ir/expressions/UnaryExpression.h
  68. 86
      src/ir/expressions/UnaryNumericalFunctionExpression.cpp
  69. 70
      src/ir/expressions/UnaryNumericalFunctionExpression.h
  70. 120
      src/ir/expressions/VariableExpression.cpp
  71. 98
      src/ir/expressions/VariableExpression.h
  72. 756
      src/parser/PrismParser.cpp
  73. 347
      src/parser/PrismParser.h
  74. 253
      src/parser/prismparser/BaseGrammar.h
  75. 42
      src/parser/prismparser/BooleanExpressionGrammar.cpp
  76. 54
      src/parser/prismparser/BooleanExpressionGrammar.h
  77. 38
      src/parser/prismparser/ConstBooleanExpressionGrammar.cpp
  78. 47
      src/parser/prismparser/ConstBooleanExpressionGrammar.h
  79. 34
      src/parser/prismparser/ConstDoubleExpressionGrammar.cpp
  80. 41
      src/parser/prismparser/ConstDoubleExpressionGrammar.h
  81. 41
      src/parser/prismparser/ConstIntegerExpressionGrammar.cpp
  82. 42
      src/parser/prismparser/ConstIntegerExpressionGrammar.h
  83. 23
      src/parser/prismparser/IdentifierGrammars.cpp
  84. 42
      src/parser/prismparser/IdentifierGrammars.h
  85. 39
      src/parser/prismparser/Includes.h
  86. 42
      src/parser/prismparser/IntegerExpressionGrammar.cpp
  87. 50
      src/parser/prismparser/IntegerExpressionGrammar.h
  88. 295
      src/parser/prismparser/PrismGrammar.cpp
  89. 267
      src/parser/prismparser/PrismGrammar.h
  90. 75
      src/parser/prismparser/Tokens.h
  91. 191
      src/parser/prismparser/VariableState.cpp
  92. 207
      src/parser/prismparser/VariableState.h
  93. 30
      src/solver/GurobiLpSolver.cpp
  94. 225
      src/storage/dd/CuddDd.cpp
  95. 93
      src/storage/dd/CuddDd.h
  96. 96
      src/storage/dd/CuddDdManager.cpp
  97. 37
      src/storage/dd/CuddDdManager.h
  98. 2
      src/storage/dd/DdMetaVariable.cpp
  99. 2
      src/storage/dd/DdType.h
  100. 65
      src/storage/expressions/BaseExpression.cpp

9
CMakeLists.txt

@ -258,10 +258,9 @@ file(GLOB_RECURSE STORM_SETTINGS_FILES ${PROJECT_SOURCE_DIR}/src/settings/*.h ${
file(GLOB_RECURSE STORM_SOLVER_FILES ${PROJECT_SOURCE_DIR}/src/solver/*.h ${PROJECT_SOURCE_DIR}/src/solver/*.cpp)
file(GLOB STORM_STORAGE_FILES ${PROJECT_SOURCE_DIR}/src/storage/*.h ${PROJECT_SOURCE_DIR}/src/storage/*.cpp)
file(GLOB_RECURSE STORM_STORAGE_DD_FILES ${PROJECT_SOURCE_DIR}/src/storage/dd/*.h ${PROJECT_SOURCE_DIR}/src/storage/dd/*.cpp)
file(GLOB_RECURSE STORM_STORAGE_EXPRESSIONS_FILES ${PROJECT_SOURCE_DIR}/src/storage/expressions/*.h ${PROJECT_SOURCE_DIR}/src/storage/expressions/*.cpp)
file(GLOB_RECURSE STORM_STORAGE_PRISM_FILES ${PROJECT_SOURCE_DIR}/src/storage/prism/*.h ${PROJECT_SOURCE_DIR}/src/storage/prism/*.cpp)
file(GLOB_RECURSE STORM_UTILITY_FILES ${PROJECT_SOURCE_DIR}/src/utility/*.h ${PROJECT_SOURCE_DIR}/src/utility/*.cpp)
file(GLOB STORM_IR_FILES ${PROJECT_SOURCE_DIR}/src/ir/*.h ${PROJECT_SOURCE_DIR}/src/ir/*.cpp)
file(GLOB_RECURSE STORM_IR_EXPRESSIONS_FILES ${PROJECT_SOURCE_DIR}/src/ir/expressions/*.h ${PROJECT_SOURCE_DIR}/src/ir/expressions/*.cpp)
# Test Sources
# Note that the tests also need the source files, except for the main file
file(GLOB_RECURSE STORM_FUNCTIONAL_TEST_FILES ${STORM_CPP_TESTS_BASE_PATH}/functional/*.h ${STORM_CPP_TESTS_BASE_PATH}/functional/*.cpp)
@ -280,8 +279,6 @@ source_group(formula\\csl FILES ${STORM_FORMULA_CSL_FILES})
source_group(formula\\ltl FILES ${STORM_FORMULA_LTL_FILES})
source_group(formula\\prctl FILES ${STORM_FORMULA_PRCTL_FILES})
source_group(generated FILES ${STORM_BUILD_HEADERS})
source_group(ir FILES ${STORM_IR_FILES})
source_group(ir\\expressions FILES ${STORM_IR_EXPRESSIONS_FILES})
source_group(modelchecker FILES ${STORM_MODELCHECKER_FILES})
source_group(counterexamples FILES ${STORM_COUNTEREXAMPLES_FILES})
source_group(models FILES ${STORM_MODELS_FILES})
@ -291,6 +288,8 @@ source_group(settings FILES ${STORM_SETTINGS_FILES})
source_group(solver FILES ${STORM_SOLVER_FILES})
source_group(storage FILES ${STORM_STORAGE_FILES})
source_group(storage\\dd FILES ${STORM_STORAGE_DD_FILES})
source_group(storage\\expressions FILES ${STORM_STORAGE_EXPRESSIONS_FILES})
source_group(storage\\prism FILES ${STORM_STORAGE_PRISM_FILES})
source_group(utility FILES ${STORM_UTILITY_FILES})
source_group(functional-test FILES ${STORM_FUNCTIONAL_TEST_FILES})
source_group(performance-test FILES ${STORM_PERFORMANCE_TEST_FILES})

4
examples/dtmc/synchronous_leader/leader4_8.pm

@ -4,8 +4,8 @@
dtmc
// CONSTANTS
const N = 4; // number of processes
const K = 8; // range of probabilistic choice
const int N = 4; // number of processes
const int K = 8; // range of probabilistic choice
// counter module used to count the number of processes that have been read
// and to know when a process has decided

4
examples/dtmc/synchronous_leader/leader5_8.pm

@ -4,8 +4,8 @@
dtmc
// CONSTANTS
const N = 5; // number of processes
const K = 8; // range of probabilistic choice
const int N = 5; // number of processes
const int K = 8; // range of probabilistic choice
// counter module used to count the number of processes that have been read
// and to know when a process has decided

4
examples/dtmc/synchronous_leader/leader6_8.pm

@ -4,8 +4,8 @@
dtmc
// CONSTANTS
const N = 6; // number of processes
const K = 8; // range of probabilistic choice
const int N = 6; // number of processes
const int K = 8; // range of probabilistic choice
// counter module used to count the number of processes that have been read
// and to know when a process has decided

2
resources/3rdparty/cudd-2.5.0/src/cudd/cudd.h

@ -767,6 +767,8 @@ extern int Cudd_bddVarIsBound (DdManager *dd, int index);
extern DdNode * Cudd_addExistAbstract (DdManager *manager, DdNode *f, DdNode *cube);
extern DdNode * Cudd_addUnivAbstract (DdManager *manager, DdNode *f, DdNode *cube);
extern DdNode * Cudd_addOrAbstract (DdManager *manager, DdNode *f, DdNode *cube);
extern DdNode * Cudd_addMinAbstract(DdManager * manager, DdNode * f, DdNode * cube);
extern DdNode * Cudd_addMaxAbstract(DdManager * manager, DdNode * f, DdNode * cube);
extern DdNode * Cudd_addApply (DdManager *dd, DdNode * (*)(DdManager *, DdNode **, DdNode **), DdNode *f, DdNode *g);
extern DdNode * Cudd_addPlus (DdManager *dd, DdNode **f, DdNode **g);
extern DdNode * Cudd_addTimes (DdManager *dd, DdNode **f, DdNode **g);

261
resources/3rdparty/cudd-2.5.0/src/cudd/cuddAddAbs.c

@ -11,12 +11,16 @@
<li> Cudd_addExistAbstract()
<li> Cudd_addUnivAbstract()
<li> Cudd_addOrAbstract()
<li> Cudd_addMinAbstract()
<li> Cudd_addMaxAbstract()
</ul>
Internal procedures included in this module:
<ul>
<li> cuddAddExistAbstractRecur()
<li> cuddAddUnivAbstractRecur()
<li> cuddAddOrAbstractRecur()
<li> cuddAddMinAbstractRecur()
<li> cuddAddMaxAbstractRecur()
</ul>
Static procedures included in this module:
<ul>
@ -229,6 +233,82 @@ Cudd_addOrAbstract(
} /* end of Cudd_addOrAbstract */
/**Function********************************************************************
Synopsis [Abstracts all the variables in cube from the
ADD f by taking the minimum.]
Description [Abstracts all the variables in cube from the ADD f
by taking the minimum over all possible values taken by the
variables. Returns the abstracted ADD if successful; NULL
otherwise.]
SideEffects [None]
SeeAlso [Cudd_addUnivAbstract Cudd_addExistAbstract]
Note: Added by Dave Parker 14/6/99
******************************************************************************/
DdNode *
Cudd_addMinAbstract(
DdManager * manager,
DdNode * f,
DdNode * cube)
{
DdNode *res;
if (addCheckPositiveCube(manager, cube) == 0) {
(void) fprintf(manager->err,"Error: Can only abstract cubes");
return(NULL);
}
do {
manager->reordered = 0;
res = cuddAddMinAbstractRecur(manager, f, cube);
} while (manager->reordered == 1);
return(res);
} /* end of Cudd_addMinAbstract */
/**Function********************************************************************
Synopsis [Abstracts all the variables in cube from the
ADD f by taking the maximum.]
Description [Abstracts all the variables in cube from the ADD f
by taking the maximum over all possible values taken by the
variables. Returns the abstracted ADD if successful; NULL
otherwise.]
SideEffects [None]
SeeAlso [Cudd_addUnivAbstract Cudd_addExistAbstract]
Note: Added by Dave Parker 14/6/99
******************************************************************************/
DdNode *
Cudd_addMaxAbstract(
DdManager * manager,
DdNode * f,
DdNode * cube)
{
DdNode *res;
if (addCheckPositiveCube(manager, cube) == 0) {
(void) fprintf(manager->err,"Error: Can only abstract cubes");
return(NULL);
}
do {
manager->reordered = 0;
res = cuddAddMaxAbstractRecur(manager, f, cube);
} while (manager->reordered == 1);
return(res);
} /* end of Cudd_addMaxAbstract */
/*---------------------------------------------------------------------------*/
/* Definition of internal functions */
@ -542,7 +622,188 @@ cuddAddOrAbstractRecur(
} /* end of cuddAddOrAbstractRecur */
/**Function********************************************************************
Synopsis [Performs the recursive step of Cudd_addMinAbstract.]
Description [Performs the recursive step of Cudd_addMinAbstract.
Returns the ADD obtained by abstracting the variables of cube from f,
if successful; NULL otherwise.]
SideEffects [None]
SeeAlso []
******************************************************************************/
DdNode *
cuddAddMinAbstractRecur(
DdManager * manager,
DdNode * f,
DdNode * cube)
{
DdNode *T, *E, *res, *res1, *res2, *zero;
zero = DD_ZERO(manager);
/* Cube is guaranteed to be a cube at this point. */
if (f == zero || cuddIsConstant(cube)) {
return(f);
}
/* Abstract a variable that does not appear in f. */
if (cuddI(manager,f->index) > cuddI(manager,cube->index)) {
res = cuddAddMinAbstractRecur(manager, f, cuddT(cube));
return(res);
}
if ((res = cuddCacheLookup2(manager, Cudd_addMinAbstract, f, cube)) != NULL) {
return(res);
}
T = cuddT(f);
E = cuddE(f);
/* If the two indices are the same, so are their levels. */
if (f->index == cube->index) {
res1 = cuddAddMinAbstractRecur(manager, T, cuddT(cube));
if (res1 == NULL) return(NULL);
cuddRef(res1);
res2 = cuddAddMinAbstractRecur(manager, E, cuddT(cube));
if (res2 == NULL) {
Cudd_RecursiveDeref(manager,res1);
return(NULL);
}
cuddRef(res2);
res = cuddAddApplyRecur(manager, Cudd_addMinimum, res1, res2);
if (res == NULL) {
Cudd_RecursiveDeref(manager,res1);
Cudd_RecursiveDeref(manager,res2);
return(NULL);
}
cuddRef(res);
Cudd_RecursiveDeref(manager,res1);
Cudd_RecursiveDeref(manager,res2);
cuddCacheInsert2(manager, Cudd_addMinAbstract, f, cube, res);
cuddDeref(res);
return(res);
}
else { /* if (cuddI(manager,f->index) < cuddI(manager,cube->index)) */
res1 = cuddAddMinAbstractRecur(manager, T, cube);
if (res1 == NULL) return(NULL);
cuddRef(res1);
res2 = cuddAddMinAbstractRecur(manager, E, cube);
if (res2 == NULL) {
Cudd_RecursiveDeref(manager,res1);
return(NULL);
}
cuddRef(res2);
res = (res1 == res2) ? res1 :
cuddUniqueInter(manager, (int) f->index, res1, res2);
if (res == NULL) {
Cudd_RecursiveDeref(manager,res1);
Cudd_RecursiveDeref(manager,res2);
return(NULL);
}
cuddDeref(res1);
cuddDeref(res2);
cuddCacheInsert2(manager, Cudd_addMinAbstract, f, cube, res);
return(res);
}
} /* end of cuddAddMinAbstractRecur */
/**Function********************************************************************
Synopsis [Performs the recursive step of Cudd_addMaxAbstract.]
Description [Performs the recursive step of Cudd_addMaxAbstract.
Returns the ADD obtained by abstracting the variables of cube from f,
if successful; NULL otherwise.]
SideEffects [None]
SeeAlso []
******************************************************************************/
DdNode *
cuddAddMaxAbstractRecur(
DdManager * manager,
DdNode * f,
DdNode * cube)
{
DdNode *T, *E, *res, *res1, *res2, *zero;
zero = DD_ZERO(manager);
/* Cube is guaranteed to be a cube at this point. */
if (f == zero || cuddIsConstant(cube)) {
return(f);
}
/* Abstract a variable that does not appear in f. */
if (cuddI(manager,f->index) > cuddI(manager,cube->index)) {
res = cuddAddMaxAbstractRecur(manager, f, cuddT(cube));
return(res);
}
if ((res = cuddCacheLookup2(manager, Cudd_addMaxAbstract, f, cube)) != NULL) {
return(res);
}
T = cuddT(f);
E = cuddE(f);
/* If the two indices are the same, so are their levels. */
if (f->index == cube->index) {
res1 = cuddAddMaxAbstractRecur(manager, T, cuddT(cube));
if (res1 == NULL) return(NULL);
cuddRef(res1);
res2 = cuddAddMaxAbstractRecur(manager, E, cuddT(cube));
if (res2 == NULL) {
Cudd_RecursiveDeref(manager,res1);
return(NULL);
}
cuddRef(res2);
res = cuddAddApplyRecur(manager, Cudd_addMaximum, res1, res2);
if (res == NULL) {
Cudd_RecursiveDeref(manager,res1);
Cudd_RecursiveDeref(manager,res2);
return(NULL);
}
cuddRef(res);
Cudd_RecursiveDeref(manager,res1);
Cudd_RecursiveDeref(manager,res2);
cuddCacheInsert2(manager, Cudd_addMaxAbstract, f, cube, res);
cuddDeref(res);
return(res);
}
else { /* if (cuddI(manager,f->index) < cuddI(manager,cube->index)) */
res1 = cuddAddMaxAbstractRecur(manager, T, cube);
if (res1 == NULL) return(NULL);
cuddRef(res1);
res2 = cuddAddMaxAbstractRecur(manager, E, cube);
if (res2 == NULL) {
Cudd_RecursiveDeref(manager,res1);
return(NULL);
}
cuddRef(res2);
res = (res1 == res2) ? res1 :
cuddUniqueInter(manager, (int) f->index, res1, res2);
if (res == NULL) {
Cudd_RecursiveDeref(manager,res1);
Cudd_RecursiveDeref(manager,res2);
return(NULL);
}
cuddDeref(res1);
cuddDeref(res2);
cuddCacheInsert2(manager, Cudd_addMaxAbstract, f, cube, res);
return(res);
}
} /* end of cuddAddMaxAbstractRecur */
/*---------------------------------------------------------------------------*/
/* Definition of static functions */

2
resources/3rdparty/cudd-2.5.0/src/cudd/cuddInt.h

@ -1000,6 +1000,8 @@ dd->nextSample += 250000;}
extern DdNode * cuddAddExistAbstractRecur (DdManager *manager, DdNode *f, DdNode *cube);
extern DdNode * cuddAddUnivAbstractRecur (DdManager *manager, DdNode *f, DdNode *cube);
extern DdNode * cuddAddOrAbstractRecur (DdManager *manager, DdNode *f, DdNode *cube);
extern DdNode * cuddAddMinAbstractRecur (DdManager *manager, DdNode *f, DdNode *cube);
extern DdNode * cuddAddMaxAbstractRecur (DdManager *manager, DdNode *f, DdNode *cube);
extern DdNode * cuddAddApplyRecur (DdManager *dd, DdNode * (*)(DdManager *, DdNode **, DdNode **), DdNode *f, DdNode *g);
extern DdNode * cuddAddMonadicApplyRecur (DdManager * dd, DdNode * (*op)(DdManager *, DdNode *), DdNode * f);
extern DdNode * cuddAddScalarInverseRecur (DdManager *dd, DdNode *f, DdNode *epsilon);

17
resources/3rdparty/cudd-2.5.0/src/obj/cuddObj.cc

@ -2405,6 +2405,23 @@ ADD::OrAbstract(
} // ADD::OrAbstract
ADD
ADD::MinAbstract(const ADD& cube) const
{
DdManager *mgr = checkSameManager(cube);
DdNode *result = Cudd_addMinAbstract(mgr, node, cube.node);
checkReturnValue(result);
return ADD(p, result);
} // ADD::MinAbstract
ADD
ADD::MaxAbstract(const ADD& cube) const
{
DdManager *mgr = checkSameManager(cube);
DdNode *result = Cudd_addMaxAbstract(mgr, node, cube.node);
checkReturnValue(result);
return ADD(p, result);
} // ADD::MaxAbstract
ADD
ADD::Plus(

2
resources/3rdparty/cudd-2.5.0/src/obj/cuddObj.hh

@ -373,6 +373,8 @@ public:
ADD ExistAbstract(const ADD& cube) const;
ADD UnivAbstract(const ADD& cube) const;
ADD OrAbstract(const ADD& cube) const;
ADD MinAbstract(const ADD& cube) const;
ADD MaxAbstract(const ADD& cube) const;
ADD Plus(const ADD& g) const;
ADD Times(const ADD& g) const;
ADD Threshold(const ADD& g) const;

291
src/adapters/ExplicitModelAdapter.h

@ -15,12 +15,11 @@
#include <queue>
#include <boost/functional/hash.hpp>
#include <boost/container/flat_set.hpp>
#include <boost/algorithm/string.hpp>
#include "src/ir/Program.h"
#include "src/ir/RewardModel.h"
#include "src/ir/StateReward.h"
#include "src/ir/TransitionReward.h"
#include "src/utility/IRUtility.h"
#include "src/storage/prism/Program.h"
#include "src/storage/expressions/SimpleValuation.h"
#include "src/utility/PrismUtility.h"
#include "src/models/AbstractModel.h"
#include "src/models/Dtmc.h"
#include "src/models/Ctmc.h"
@ -29,20 +28,22 @@
#include "src/models/AtomicPropositionsLabeling.h"
#include "src/storage/SparseMatrix.h"
#include "src/settings/Settings.h"
#include "src/exceptions/ExceptionMacros.h"
#include "src/exceptions/WrongFormatException.h"
#include "log4cplus/logger.h"
#include "log4cplus/loggingmacros.h"
extern log4cplus::Logger logger;
using namespace storm::utility::ir;
namespace storm {
namespace adapters {
using namespace storm::utility::prism;
template<typename ValueType>
class ExplicitModelAdapter {
public:
typedef storm::expressions::SimpleValuation StateType;
typedef storm::expressions::SimpleValuationPointerHash StateHash;
typedef storm::expressions::SimpleValuationPointerCompare StateCompare;
typedef storm::expressions::SimpleValuationPointerLess StateLess;
// A structure holding information about the reachable state space.
struct StateInformation {
StateInformation() : reachableStates(), stateToIndexMap() {
@ -52,10 +53,19 @@ namespace storm {
// A list of reachable states.
std::vector<StateType*> reachableStates;
// A list of initial states.
std::vector<uint_fast64_t> initialStateIndices;
// A mapping from states to indices in the list of reachable states.
std::unordered_map<StateType*, uint_fast64_t, StateHash, StateCompare> stateToIndexMap;
};
// A structure storing information about the used variables of the program.
struct VariableInformation {
// A mapping of (integer) variable to their lower/upper bounds.
std::map<std::string, std::pair<int_fast64_t, int_fast64_t>> variableToBoundsMap;
};
// A structure holding the individual components of a model.
struct ModelComponents {
ModelComponents() : transitionMatrix(), stateLabeling(), stateRewards(), transitionRewardMatrix(), choiceLabeling() {
@ -78,6 +88,62 @@ namespace storm {
std::vector<boost::container::flat_set<uint_fast64_t>> choiceLabeling;
};
static std::map<std::string, storm::expressions::Expression> parseConstantDefinitionString(storm::prism::Program const& program, std::string const& constantDefinitionString) {
std::map<std::string, storm::expressions::Expression> constantDefinitions;
std::set<std::string> definedConstants;
if (!constantDefinitionString.empty()) {
// Parse the string that defines the undefined constants of the model and make sure that it contains exactly
// one value for each undefined constant of the model.
std::vector<std::string> definitions;
boost::split(definitions, constantDefinitionString, boost::is_any_of(","));
for (auto& definition : definitions) {
boost::trim(definition);
// Check whether the token could be a legal constant definition.
uint_fast64_t positionOfAssignmentOperator = definition.find('=');
if (positionOfAssignmentOperator == std::string::npos) {
throw storm::exceptions::InvalidArgumentException() << "Illegal constant definition string: syntax error.";
}
// Now extract the variable name and the value from the string.
std::string constantName = definition.substr(0, positionOfAssignmentOperator);
boost::trim(constantName);
std::string value = definition.substr(positionOfAssignmentOperator + 1);
boost::trim(value);
// Check whether the constant is a legal undefined constant of the program and if so, of what type it is.
if (program.hasConstant(constantName)) {
// Get the actual constant and check whether it's in fact undefined.
auto const& constant = program.getConstant(constantName);
LOG_THROW(!constant.isDefined(), storm::exceptions::InvalidArgumentException, "Illegally trying to define already defined constant '" << constantName <<"'.");
LOG_THROW(definedConstants.find(constantName) == definedConstants.end(), storm::exceptions::InvalidArgumentException, "Illegally trying to define constant '" << constantName <<"' twice.");
definedConstants.insert(constantName);
if (constant.getType() == storm::expressions::ExpressionReturnType::Bool) {
if (value == "true") {
constantDefinitions[constantName] = storm::expressions::Expression::createTrue();
} else if (value == "false") {
constantDefinitions[constantName] = storm::expressions::Expression::createFalse();
} else {
throw storm::exceptions::InvalidArgumentException() << "Illegal value for boolean constant: " << value << ".";
}
} else if (constant.getType() == storm::expressions::ExpressionReturnType::Int) {
int_fast64_t integerValue = std::stoi(value);
constantDefinitions[constantName] = storm::expressions::Expression::createIntegerLiteral(integerValue);
} else if (constant.getType() == storm::expressions::ExpressionReturnType::Double) {
double doubleValue = std::stod(value);
constantDefinitions[constantName] = storm::expressions::Expression::createDoubleLiteral(doubleValue);
}
} else {
throw storm::exceptions::InvalidArgumentException() << "Illegal constant definition string: unknown undefined constant " << constantName << ".";
}
}
}
return constantDefinitions;
}
/*!
* Convert the program given at construction time to an abstract model. The type of the model is the one
* specified in the program. The given reward model name selects the rewards that the model will contain.
@ -90,24 +156,33 @@ namespace storm {
* rewards.
* @return The explicit model that was given by the probabilistic program.
*/
static std::unique_ptr<storm::models::AbstractModel<ValueType>> translateProgram(storm::ir::Program program, std::string const& constantDefinitionString = "", std::string const& rewardModelName = "") {
static std::unique_ptr<storm::models::AbstractModel<ValueType>> translateProgram(storm::prism::Program program, std::string const& constantDefinitionString = "", std::string const& rewardModelName = "") {
// Start by defining the undefined constants in the model.
defineUndefinedConstants(program, constantDefinitionString);
// First, we need to parse the constant definition string.
std::map<std::string, storm::expressions::Expression> constantDefinitions = parseConstantDefinitionString(program, constantDefinitionString);
storm::prism::Program preparedProgram = program.defineUndefinedConstants(constantDefinitions);
LOG_THROW(!preparedProgram.hasUndefinedConstants(), storm::exceptions::InvalidArgumentException, "Program still contains undefined constants.");
// Now that we have defined all the constants in the program, we need to substitute their appearances in
// all expressions in the program so we can then evaluate them without having to store the values of the
// constants in the state (i.e., valuation).
preparedProgram = preparedProgram.substituteConstants();
ModelComponents modelComponents = buildModelComponents(program, rewardModelName);
ModelComponents modelComponents = buildModelComponents(preparedProgram, rewardModelName);
std::unique_ptr<storm::models::AbstractModel<ValueType>> result;
switch (program.getModelType()) {
case storm::ir::Program::DTMC:
case storm::prism::Program::ModelType::DTMC:
result = std::unique_ptr<storm::models::AbstractModel<ValueType>>(new storm::models::Dtmc<ValueType>(std::move(modelComponents.transitionMatrix), std::move(modelComponents.stateLabeling), rewardModelName != "" ? std::move(modelComponents.stateRewards) : boost::optional<std::vector<ValueType>>(), rewardModelName != "" ? std::move(modelComponents.transitionRewardMatrix) : boost::optional<storm::storage::SparseMatrix<ValueType>>(), std::move(modelComponents.choiceLabeling)));
break;
case storm::ir::Program::CTMC:
case storm::prism::Program::ModelType::CTMC:
result = std::unique_ptr<storm::models::AbstractModel<ValueType>>(new storm::models::Ctmc<ValueType>(std::move(modelComponents.transitionMatrix), std::move(modelComponents.stateLabeling), rewardModelName != "" ? std::move(modelComponents.stateRewards) : boost::optional<std::vector<ValueType>>(), rewardModelName != "" ? std::move(modelComponents.transitionRewardMatrix) : boost::optional<storm::storage::SparseMatrix<ValueType>>(), std::move(modelComponents.choiceLabeling)));
break;
case storm::ir::Program::MDP:
case storm::prism::Program::ModelType::MDP:
result = std::unique_ptr<storm::models::AbstractModel<ValueType>>(new storm::models::Mdp<ValueType>(std::move(modelComponents.transitionMatrix), std::move(modelComponents.stateLabeling), rewardModelName != "" ? std::move(modelComponents.stateRewards) : boost::optional<std::vector<ValueType>>(), rewardModelName != "" ? std::move(modelComponents.transitionRewardMatrix) : boost::optional<storm::storage::SparseMatrix<ValueType>>(), std::move(modelComponents.choiceLabeling)));
break;
case storm::ir::Program::CTMDP:
case storm::prism::Program::ModelType::CTMDP:
result = std::unique_ptr<storm::models::AbstractModel<ValueType>>(new storm::models::Ctmdp<ValueType>(std::move(modelComponents.transitionMatrix), std::move(modelComponents.stateLabeling), rewardModelName != "" ? std::move(modelComponents.stateRewards) : boost::optional<std::vector<ValueType>>(), rewardModelName != "" ? std::move(modelComponents.transitionRewardMatrix) : boost::optional<storm::storage::SparseMatrix<ValueType>>(), std::move(modelComponents.choiceLabeling)));
break;
default:
@ -116,36 +191,19 @@ namespace storm {
break;
}
// Undefine the constants so that the program can be used again somewhere else.
undefineUndefinedConstants(program);
return result;
}
private:
/*!
* Transforms a state into a somewhat readable string.
*
* @param state The state to transform into a string.
* @return A string representation of the state.
*/
static std::string toString(StateType const* state) {
std::stringstream ss;
for (unsigned int i = 0; i < state->first.size(); i++) ss << state->first[i] << "\t";
for (unsigned int i = 0; i < state->second.size(); i++) ss << state->second[i] << "\t";
return ss.str();
}
/*!
* Applies an update to the given state and returns the resulting new state object. This methods does not
* modify the given state but returns a new one.
*
* @param variableInformation A structure with information about the variables in the program.
* @params state The state to which to apply the update.
* @params update The update to apply.
* @return The resulting state.
*/
static StateType* applyUpdate(VariableInformation const& variableInformation, StateType const* state, storm::ir::Update const& update) {
static StateType* applyUpdate(VariableInformation const& variableInformation, StateType const* state, storm::prism::Update const& update) {
return applyUpdate(variableInformation, state, state, update);
}
@ -154,26 +212,28 @@ namespace storm {
* over the variable values of the given base state. This methods does not modify the given state but
* returns a new one.
*
* @param variableInformation A structure with information about the variables in the program.
* @param state The state to which to apply the update.
* @param baseState The state used for evaluating the update.
* @param update The update to apply.
* @return The resulting state.
*/
static StateType* applyUpdate(VariableInformation const& variableInformation, StateType const* state, StateType const* baseState, storm::ir::Update const& update) {
static StateType* applyUpdate(VariableInformation const& variableInformation, StateType const* state, StateType const* baseState, storm::prism::Update const& update) {
StateType* newState = new StateType(*state);
for (auto variableAssignmentPair : update.getBooleanAssignments()) {
setValue(newState, variableInformation.booleanVariableToIndexMap.at(variableAssignmentPair.first), variableAssignmentPair.second.getExpression()->getValueAsBool(baseState));
}
for (auto variableAssignmentPair : update.getIntegerAssignments()) {
int_fast64_t newVariableValue = variableAssignmentPair.second.getExpression()->getValueAsInt(baseState);
bool isLegalValueForVariable = newVariableValue >= variableInformation.lowerBounds.at(variableInformation.integerVariableToIndexMap.at(variableAssignmentPair.first)) && newVariableValue <= variableInformation.upperBounds.at(variableInformation.integerVariableToIndexMap.at(variableAssignmentPair.first));
if (!isLegalValueForVariable) {
throw storm::exceptions::InvalidStateException() << "Invalid value '" << newVariableValue << "' for variable \"" << variableInformation.integerVariables.at(variableInformation.integerVariableToIndexMap.at(variableAssignmentPair.first)).getName() << "\". Please strengthen the guards if necessary or enlarge the domains of the variables.";
// This variable needs to be declared prior to the switch, because of C++ rules.
int_fast64_t newValue = 0;
for (auto const& assignment : update.getAssignments()) {
switch (assignment.getExpression().getReturnType()) {
case storm::expressions::ExpressionReturnType::Bool: newState->setBooleanValue(assignment.getVariableName(), assignment.getExpression().evaluateAsBool(baseState)); break;
case storm::expressions::ExpressionReturnType::Int:
{
newValue = assignment.getExpression().evaluateAsInt(baseState);
auto const& boundsPair = variableInformation.variableToBoundsMap.find(assignment.getVariableName());
LOG_THROW(boundsPair->second.first <= newValue && newValue <= boundsPair->second.second, storm::exceptions::InvalidArgumentException, "Invalid value " << newValue << " for variable '" << assignment.getVariableName() << "'.");
newState->setIntegerValue(assignment.getVariableName(), newValue); break;
}
default: LOG_ASSERT(false, "Invalid type of assignment."); break;
}
setValue(newState, variableInformation.integerVariableToIndexMap.at(variableAssignmentPair.first), newVariableValue);
}
return newState;
}
@ -220,32 +280,32 @@ namespace storm {
* @param action The action label to select.
* @return A list of lists of active commands or nothing.
*/
static boost::optional<std::vector<std::list<storm::ir::Command>>> getActiveCommandsByAction(storm::ir::Program const& program, StateType const* state, std::string const& action) {
boost::optional<std::vector<std::list<storm::ir::Command>>> result((std::vector<std::list<storm::ir::Command>>()));
static boost::optional<std::vector<std::list<storm::prism::Command>>> getActiveCommandsByAction(storm::prism::Program const& program, StateType const* state, std::string const& action) {
boost::optional<std::vector<std::list<storm::prism::Command>>> result((std::vector<std::list<storm::prism::Command>>()));
// Iterate over all modules.
for (uint_fast64_t i = 0; i < program.getNumberOfModules(); ++i) {
storm::ir::Module const& module = program.getModule(i);
storm::prism::Module const& module = program.getModule(i);
// If the module has no command labeled with the given action, we can skip this module.
if (!module.hasAction(action)) {
continue;
}
std::set<uint_fast64_t> const& commandIndices = module.getCommandsByAction(action);
std::set<uint_fast64_t> const& commandIndices = module.getCommandIndicesByAction(action);
// If the module contains the action, but there is no command in the module that is labeled with
// this action, we don't have any feasible command combinations.
if (commandIndices.empty()) {
return boost::optional<std::vector<std::list<storm::ir::Command>>>();
return boost::optional<std::vector<std::list<storm::prism::Command>>>();
}
std::list<storm::ir::Command> commands;
std::list<storm::prism::Command> commands;
// Look up commands by their indices and add them if the guard evaluates to true in the given state.
for (uint_fast64_t commandIndex : commandIndices) {
storm::ir::Command const& command = module.getCommand(commandIndex);
if (command.getGuard()->getValueAsBool(state)) {
storm::prism::Command const& command = module.getCommand(commandIndex);
if (command.getGuardExpression().evaluateAsBool(state)) {
commands.push_back(command);
}
}
@ -253,7 +313,7 @@ namespace storm {
// If there was no enabled command although the module has some command with the required action label,
// we must not return anything.
if (commands.size() == 0) {
return boost::optional<std::vector<std::list<storm::ir::Command>>>();
return boost::optional<std::vector<std::list<storm::prism::Command>>>();
}
result.get().push_back(std::move(commands));
@ -261,23 +321,26 @@ namespace storm {
return result;
}
static std::list<Choice<ValueType>> getUnlabeledTransitions(storm::ir::Program const& program, StateInformation& stateInformation, VariableInformation const& variableInformation, uint_fast64_t stateIndex, std::queue<uint_fast64_t>& stateQueue) {
static std::list<Choice<ValueType>> getUnlabeledTransitions(storm::prism::Program const& program, StateInformation& stateInformation, VariableInformation const& variableInformation, uint_fast64_t stateIndex, std::queue<uint_fast64_t>& stateQueue) {
std::list<Choice<ValueType>> result;
StateType const* currentState = stateInformation.reachableStates[stateIndex];
// Iterate over all modules.
for (uint_fast64_t i = 0; i < program.getNumberOfModules(); ++i) {
storm::ir::Module const& module = program.getModule(i);
storm::prism::Module const& module = program.getModule(i);
// Iterate over all commands.
for (uint_fast64_t j = 0; j < module.getNumberOfCommands(); ++j) {
storm::ir::Command const& command = module.getCommand(j);
storm::prism::Command const& command = module.getCommand(j);
// Only consider unlabeled commands.
if (command.getActionName() != "") continue;
// Skip the command, if it is not enabled.
if (!command.getGuard()->getValueAsBool(currentState)) continue;
if (!command.getGuardExpression().evaluateAsBool(currentState)) {
continue;
}
result.push_back(Choice<ValueType>(""));
Choice<ValueType>& choice = result.back();
@ -286,7 +349,7 @@ namespace storm {
double probabilitySum = 0;
// Iterate over all updates of the current command.
for (uint_fast64_t k = 0; k < command.getNumberOfUpdates(); ++k) {
storm::ir::Update const& update = command.getUpdate(k);
storm::prism::Update const& update = command.getUpdate(k);
// Obtain target state index.
std::pair<bool, uint_fast64_t> flagTargetStateIndexPair = getOrAddStateIndex(applyUpdate(variableInformation, currentState, update), stateInformation);
@ -297,7 +360,7 @@ namespace storm {
}
// Update the choice by adding the probability/target state to it.
double probabilityToAdd = update.getLikelihoodExpression()->getValueAsDouble(currentState);
double probabilityToAdd = update.getLikelihoodExpression().evaluateAsDouble(currentState);
probabilitySum += probabilityToAdd;
boost::container::flat_set<uint_fast64_t> labels;
labels.insert(update.getGlobalIndex());
@ -305,27 +368,24 @@ namespace storm {
}
// Check that the resulting distribution is in fact a distribution.
if (std::abs(1 - probabilitySum) > storm::settings::Settings::getInstance()->getOptionByLongName("precision").getArgument(0).getValueAsDouble()) {
LOG4CPLUS_ERROR(logger, "Sum of update probabilities should be one for command:\n\t" << command.toString());
throw storm::exceptions::WrongFormatException() << "Sum of update probabilities should be one for command:\n\t" << command.toString();
}
LOG_THROW(std::abs(1 - probabilitySum) < storm::settings::Settings::getInstance()->getOptionByLongName("precision").getArgument(0).getValueAsDouble(), storm::exceptions::WrongFormatException, "Probabilities do not sum to one for command '" << command << "'.");
}
}
return result;
}
static std::list<Choice<ValueType>> getLabeledTransitions(storm::ir::Program const& program, StateInformation& stateInformation, VariableInformation const& variableInformation, uint_fast64_t stateIndex, std::queue<uint_fast64_t>& stateQueue) {
static std::list<Choice<ValueType>> getLabeledTransitions(storm::prism::Program const& program, StateInformation& stateInformation, VariableInformation const& variableInformation, uint_fast64_t stateIndex, std::queue<uint_fast64_t>& stateQueue) {
std::list<Choice<ValueType>> result;
for (std::string const& action : program.getActions()) {
StateType const* currentState = stateInformation.reachableStates[stateIndex];
boost::optional<std::vector<std::list<storm::ir::Command>>> optionalActiveCommandLists = getActiveCommandsByAction(program, currentState, action);
boost::optional<std::vector<std::list<storm::prism::Command>>> optionalActiveCommandLists = getActiveCommandsByAction(program, currentState, action);
// Only process this action label, if there is at least one feasible solution.
if (optionalActiveCommandLists) {
std::vector<std::list<storm::ir::Command>> const& activeCommandList = optionalActiveCommandLists.get();
std::vector<std::list<storm::ir::Command>::const_iterator> iteratorList(activeCommandList.size());
std::vector<std::list<storm::prism::Command>> const& activeCommandList = optionalActiveCommandLists.get();
std::vector<std::list<storm::prism::Command>::const_iterator> iteratorList(activeCommandList.size());
// Initialize the list of iterators.
for (size_t i = 0; i < activeCommandList.size(); ++i) {
@ -342,17 +402,17 @@ namespace storm {
// FIXME: This does not check whether a global variable is written multiple times. While the
// behaviour for this is undefined anyway, a warning should be issued in that case.
for (uint_fast64_t i = 0; i < iteratorList.size(); ++i) {
storm::ir::Command const& command = *iteratorList[i];
storm::prism::Command const& command = *iteratorList[i];
for (uint_fast64_t j = 0; j < command.getNumberOfUpdates(); ++j) {
storm::ir::Update const& update = command.getUpdate(j);
storm::prism::Update const& update = command.getUpdate(j);
for (auto const& stateProbabilityPair : *currentTargetStates) {
StateType* newTargetState = applyUpdate(variableInformation, stateProbabilityPair.first, currentState, update);
storm::storage::LabeledValues<double> newProbability;
double updateProbability = update.getLikelihoodExpression()->getValueAsDouble(currentState);
double updateProbability = update.getLikelihoodExpression().evaluateAsDouble(currentState);
for (auto const& valueLabelSetPair : stateProbabilityPair.second) {
// Copy the label set, so we can modify it.
boost::container::flat_set<uint_fast64_t> newLabelSet = valueLabelSetPair.second;
@ -459,13 +519,29 @@ namespace storm {
* @return A tuple containing a vector with all rows at which the nondeterministic choices of each state begin
* and a vector containing the labels associated with each choice.
*/
static std::vector<boost::container::flat_set<uint_fast64_t>> buildMatrices(storm::ir::Program const& program, VariableInformation const& variableInformation, std::vector<storm::ir::TransitionReward> const& transitionRewards, StateInformation& stateInformation, bool deterministicModel, storm::storage::SparseMatrixBuilder<ValueType>& transitionMatrixBuilder, storm::storage::SparseMatrixBuilder<ValueType>& transitionRewardMatrixBuilder) {
static std::vector<boost::container::flat_set<uint_fast64_t>> buildMatrices(storm::prism::Program const& program, VariableInformation const& variableInformation, std::vector<storm::prism::TransitionReward> const& transitionRewards, StateInformation& stateInformation, bool deterministicModel, storm::storage::SparseMatrixBuilder<ValueType>& transitionMatrixBuilder, storm::storage::SparseMatrixBuilder<ValueType>& transitionRewardMatrixBuilder) {
std::vector<boost::container::flat_set<uint_fast64_t>> choiceLabels;
// Initialize a queue and insert the initial state.
std::queue<uint_fast64_t> stateQueue;
StateType* initialState = getInitialState(program, variableInformation);
getOrAddStateIndex(initialState, stateInformation);
StateType* initialState = new StateType;
for (auto const& booleanVariable : program.getGlobalBooleanVariables()) {
initialState->addBooleanIdentifier(booleanVariable.getName(), booleanVariable.getInitialValueExpression().evaluateAsBool());
}
for (auto const& integerVariable : program.getGlobalIntegerVariables()) {
initialState->addIntegerIdentifier(integerVariable.getName(), integerVariable.getInitialValueExpression().evaluateAsInt());
}
for (auto const& module : program.getModules()) {
for (auto const& booleanVariable : module.getBooleanVariables()) {
initialState->addBooleanIdentifier(booleanVariable.getName(), booleanVariable.getInitialValueExpression().evaluateAsBool());
}
for (auto const& integerVariable : module.getIntegerVariables()) {
initialState->addIntegerIdentifier(integerVariable.getName(), integerVariable.getInitialValueExpression().evaluateAsInt());
}
}
std::pair<bool, uint_fast64_t> addIndexPair = getOrAddStateIndex(initialState, stateInformation);
stateInformation.initialStateIndices.push_back(addIndexPair.second);
stateQueue.push(stateInformation.stateToIndexMap[initialState]);
// Now explore the current state until there is no more reachable state.
@ -505,8 +581,8 @@ namespace storm {
// Now add all rewards that match this choice.
for (auto const& transitionReward : transitionRewards) {
if (transitionReward.getActionName() == "" && transitionReward.getStatePredicate()->getValueAsBool(stateInformation.reachableStates.at(currentState))) {
stateToRewardMap[stateProbabilityPair.first] += ValueType(transitionReward.getRewardValue()->getValueAsDouble(stateInformation.reachableStates.at(currentState)));
if (transitionReward.getActionName() == "" && transitionReward.getStatePredicateExpression().evaluateAsBool(stateInformation.reachableStates.at(currentState))) {
stateToRewardMap[stateProbabilityPair.first] += ValueType(transitionReward.getRewardValueExpression().evaluateAsDouble(stateInformation.reachableStates.at(currentState)));
}
}
}
@ -518,8 +594,8 @@ namespace storm {
// Now add all rewards that match this choice.
for (auto const& transitionReward : transitionRewards) {
if (transitionReward.getActionName() == choice.getActionLabel() && transitionReward.getStatePredicate()->getValueAsBool(stateInformation.reachableStates.at(currentState))) {
stateToRewardMap[stateProbabilityPair.first] += ValueType(transitionReward.getRewardValue()->getValueAsDouble(stateInformation.reachableStates.at(currentState)));
if (transitionReward.getActionName() == choice.getActionLabel() && transitionReward.getStatePredicateExpression().evaluateAsBool(stateInformation.reachableStates.at(currentState))) {
stateToRewardMap[stateProbabilityPair.first] += ValueType(transitionReward.getRewardValueExpression().evaluateAsDouble(stateInformation.reachableStates.at(currentState)));
}
}
}
@ -556,8 +632,8 @@ namespace storm {
// Now add all rewards that match this choice.
for (auto const& transitionReward : transitionRewards) {
if (transitionReward.getActionName() == "" && transitionReward.getStatePredicate()->getValueAsBool(stateInformation.reachableStates.at(currentState))) {
stateToRewardMap[stateProbabilityPair.first] += ValueType(transitionReward.getRewardValue()->getValueAsDouble(stateInformation.reachableStates.at(currentState)));
if (transitionReward.getActionName() == "" && transitionReward.getStatePredicateExpression().evaluateAsBool(stateInformation.reachableStates.at(currentState))) {
stateToRewardMap[stateProbabilityPair.first] += ValueType(transitionReward.getRewardValueExpression().evaluateAsDouble(stateInformation.reachableStates.at(currentState)));
}
}
@ -583,8 +659,8 @@ namespace storm {
// Now add all rewards that match this choice.
for (auto const& transitionReward : transitionRewards) {
if (transitionReward.getActionName() == choice.getActionLabel() && transitionReward.getStatePredicate()->getValueAsBool(stateInformation.reachableStates.at(currentState))) {
stateToRewardMap[stateProbabilityPair.first] += ValueType(transitionReward.getRewardValue()->getValueAsDouble(stateInformation.reachableStates.at(currentState)));
if (transitionReward.getActionName() == choice.getActionLabel() && transitionReward.getStatePredicateExpression().evaluateAsBool(stateInformation.reachableStates.at(currentState))) {
stateToRewardMap[stateProbabilityPair.first] += ValueType(transitionReward.getRewardValueExpression().evaluateAsDouble(stateInformation.reachableStates.at(currentState)));
}
}
@ -616,20 +692,28 @@ namespace storm {
* is considered.
* @return A structure containing the components of the resulting model.
*/
static ModelComponents buildModelComponents(storm::ir::Program const& program, std::string const& rewardModelName) {
static ModelComponents buildModelComponents(storm::prism::Program const& program, std::string const& rewardModelName) {
ModelComponents modelComponents;
VariableInformation variableInformation = createVariableInformation(program);
VariableInformation variableInformation;
for (auto const& integerVariable : program.getGlobalIntegerVariables()) {
variableInformation.variableToBoundsMap[integerVariable.getName()] = std::make_pair(integerVariable.getLowerBoundExpression().evaluateAsInt(), integerVariable.getUpperBoundExpression().evaluateAsInt());
}
for (auto const& module : program.getModules()) {
for (auto const& integerVariable : module.getIntegerVariables()) {
variableInformation.variableToBoundsMap[integerVariable.getName()] = std::make_pair(integerVariable.getLowerBoundExpression().evaluateAsInt(), integerVariable.getUpperBoundExpression().evaluateAsInt());
}
}
// Create the structure for storing the reachable state space.
StateInformation stateInformation;
// Get the selected reward model or create an empty one if none is selected.
storm::ir::RewardModel const& rewardModel = rewardModelName != "" ? program.getRewardModel(rewardModelName) : storm::ir::RewardModel();
storm::prism::RewardModel const& rewardModel = rewardModelName != "" ? program.getRewardModel(rewardModelName) : storm::prism::RewardModel();
// Determine whether we have to combine different choices to one or whether this model can have more than
// one choice per state.
bool deterministicModel = program.getModelType() == storm::ir::Program::DTMC || program.getModelType() == storm::ir::Program::CTMC;
bool deterministicModel = program.getModelType() == storm::prism::Program::ModelType::DTMC || program.getModelType() == storm::prism::Program::ModelType::CTMC;
// Build the transition and reward matrices.
storm::storage::SparseMatrixBuilder<ValueType> transitionMatrixBuilder(0, 0, 0, !deterministicModel, 0);
@ -662,30 +746,29 @@ namespace storm {
* @param stateInformation Information about the state space of the program.
* @return The state labeling of the given program.
*/
static storm::models::AtomicPropositionsLabeling buildStateLabeling(storm::ir::Program const& program, VariableInformation const& variableInformation, StateInformation const& stateInformation) {
std::map<std::string, std::unique_ptr<storm::ir::expressions::BaseExpression>> const& labels = program.getLabels();
static storm::models::AtomicPropositionsLabeling buildStateLabeling(storm::prism::Program const& program, VariableInformation const& variableInformation, StateInformation const& stateInformation) {
std::vector<storm::prism::Label> const& labels = program.getLabels();
storm::models::AtomicPropositionsLabeling result(stateInformation.reachableStates.size(), labels.size() + 1);
// Initialize labeling.
for (auto const& labelExpressionPair : labels) {
result.addAtomicProposition(labelExpressionPair.first);
for (auto const& label : labels) {
result.addAtomicProposition(label.getName());
}
for (uint_fast64_t index = 0; index < stateInformation.reachableStates.size(); index++) {
for (auto const& labelExpressionPair: labels) {
for (auto const& label : labels) {
// Add label to state, if the corresponding expression is true.
if (labelExpressionPair.second->getValueAsBool(stateInformation.reachableStates[index])) {
result.addAtomicPropositionToState(labelExpressionPair.first, index);
if (label.getStatePredicateExpression().evaluateAsBool(stateInformation.reachableStates[index])) {
result.addAtomicPropositionToState(label.getName(), index);
}
}
}
// Also label the initial state with the special label "init".
result.addAtomicProposition("init");
StateType* initialState = getInitialState(program, variableInformation);
uint_fast64_t initialIndex = stateInformation.stateToIndexMap.at(initialState);
result.addAtomicPropositionToState("init", initialIndex);
delete initialState;
for (auto const& index : stateInformation.initialStateIndices) {
result.addAtomicPropositionToState("init", index);
}
return result;
}
@ -697,14 +780,14 @@ namespace storm {
* @param stateInformation Information about the state space.
* @return A vector containing the state rewards for the state space.
*/
static std::vector<ValueType> buildStateRewards(std::vector<storm::ir::StateReward> const& rewards, StateInformation const& stateInformation) {
static std::vector<ValueType> buildStateRewards(std::vector<storm::prism::StateReward> const& rewards, StateInformation const& stateInformation) {
std::vector<ValueType> result(stateInformation.reachableStates.size());
for (uint_fast64_t index = 0; index < stateInformation.reachableStates.size(); index++) {
result[index] = ValueType(0);
for (auto const& reward : rewards) {
// Add this reward to the state if the state is included in the state reward.
if (reward.getStatePredicate()->getValueAsBool(stateInformation.reachableStates[index])) {
result[index] += ValueType(reward.getRewardValue()->getValueAsDouble(stateInformation.reachableStates[index]));
if (reward.getStatePredicateExpression().evaluateAsBool(stateInformation.reachableStates[index])) {
result[index] += ValueType(reward.getRewardValueExpression().evaluateAsDouble(stateInformation.reachableStates[index]));
}
}
}

12
src/counterexamples/MILPMinimalLabelSetGenerator.h

@ -11,7 +11,7 @@
#include <chrono>
#include "src/models/Mdp.h"
#include "src/ir/Program.h"
#include "src/storage/prism/Program.h"
#include "src/exceptions/NotImplementedException.h"
#include "src/exceptions/InvalidArgumentException.h"
#include "src/exceptions/InvalidStateException.h"
@ -92,8 +92,7 @@ namespace storm {
StateInformation result;
result.relevantStates = storm::utility::graph::performProbGreater0E(labeledMdp.getTransitionMatrix(), labeledMdp.getNondeterministicChoiceIndices(), labeledMdp.getBackwardTransitions(), phiStates, psiStates);
result.relevantStates &= ~psiStates;
result.problematicStates = storm::utility::graph::performProbGreater0E(labeledMdp.getTransitionMatrix(), labeledMdp.getNondeterministicChoiceIndices(), labeledMdp.getBackwardTransitions(), phiStates, psiStates);
result.problematicStates.complement();
result.problematicStates = storm::utility::graph::performProb0E(labeledMdp.getTransitionMatrix(), labeledMdp.getNondeterministicChoiceIndices(), labeledMdp.getBackwardTransitions(), phiStates, psiStates);
result.problematicStates &= result.relevantStates;
LOG4CPLUS_DEBUG(logger, "Found " << phiStates.getNumberOfSetBits() << " filter states.");
LOG4CPLUS_DEBUG(logger, "Found " << psiStates.getNumberOfSetBits() << " target states.");
@ -1001,7 +1000,7 @@ namespace storm {
* @param formulaPtr A pointer to a safety formula. The outermost operator must be a probabilistic bound operator with a strict upper bound. The nested
* formula can be either an unbounded until formula or an eventually formula.
*/
static void computeCounterexample(storm::ir::Program const& program, storm::models::Mdp<T> const& labeledMdp, storm::property::prctl::AbstractPrctlFormula<double> const* formulaPtr) {
static void computeCounterexample(storm::prism::Program const& program, storm::models::Mdp<T> const& labeledMdp, storm::property::prctl::AbstractPrctlFormula<double> const* formulaPtr) {
std::cout << std::endl << "Generating minimal label counterexample for formula " << formulaPtr->toString() << std::endl;
// First, we need to check whether the current formula is an Until-Formula.
storm::property::prctl::ProbabilisticBoundOperator<double> const* probBoundFormula = dynamic_cast<storm::property::prctl::ProbabilisticBoundOperator<double> const*>(formulaPtr);
@ -1046,9 +1045,8 @@ namespace storm {
std::cout << std::endl << "Computed minimal label set of size " << usedLabelSet.size() << " in " << std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count() << "ms." << std::endl;
std::cout << "Resulting program:" << std::endl;
storm::ir::Program restrictedProgram(program);
restrictedProgram.restrictCommands(usedLabelSet);
std::cout << restrictedProgram.toString() << std::endl;
storm::prism::Program restrictedProgram = program.restrictCommands(usedLabelSet);
std::cout << restrictedProgram << std::endl;
std::cout << std::endl << "-------------------------------------------" << std::endl;
// FIXME: Return the DTMC that results from applying the max scheduler in the MDP restricted to the computed label set.

2
src/counterexamples/SMTMinimalCommandSetGenerator.h

@ -25,7 +25,7 @@
#include "src/solver/GmmxxNondeterministicLinearEquationSolver.h"
#include "src/utility/counterexamples.h"
#include "src/utility/IRUtility.h"
#include "src/utility/PrismUtility.h"
namespace storm {
namespace counterexamples {

31
src/exceptions/ExceptionMacros.h

@ -0,0 +1,31 @@
#ifndef STORM_EXCEPTIONS_EXCEPTIONMACROS_H_
#define STORM_EXCEPTIONS_EXCEPTIONMACROS_H_
#include <cassert>
#include "log4cplus/logger.h"
#include "log4cplus/loggingmacros.h"
extern log4cplus::Logger logger;
#ifndef NDEBUG
#define LOG_ASSERT(cond, message) \
{ \
if (!(cond)) { \
LOG4CPLUS_ERROR(logger, message); \
assert(cond); \
} \
} while (false)
#else
#define LOG_ASSERT(cond, message) /* empty */
#endif
#define LOG_THROW(cond, exception, message) \
{ \
if (!(cond)) { \
LOG4CPLUS_ERROR(logger, message); \
throw exception() << message; \
} \
} while (false)
#endif /* STORM_EXCEPTIONS_EXCEPTIONMACROS_H_ */

17
src/exceptions/InvalidOperationException.h

@ -0,0 +1,17 @@
#ifndef STORM_EXCEPTIONS_INVALIDOPERATIONEXCEPTION_H_
#define STORM_EXCEPTIONS_INVALIDOPERATIONEXCEPTION_H_
#include "src/exceptions/BaseException.h"
namespace storm {
namespace exceptions {
/*!
* @brief This exception is thrown when an operation is invalid in this context
*/
STORM_EXCEPTION_DEFINE_NEW(InvalidOperationException)
} // namespace exceptions
} // namespace storm
#endif // STORM_EXCEPTIONS_INVALIDOPERATIONEXCEPTION_H_

18
src/exceptions/InvalidTypeException.h

@ -0,0 +1,18 @@
#ifndef STORM_EXCEPTIONS_INVALIDTYPEEXCEPTION_H_
#define STORM_EXCEPTIONS_INVALIDTYPEEXCEPTION_H_
#include "src/exceptions/BaseException.h"
namespace storm {
namespace exceptions {
/*!
* @brief This exception is thrown when a type is invalid in this context
*/
STORM_EXCEPTION_DEFINE_NEW(InvalidTypeException)
} // namespace exceptions
} // namespace storm
#endif // STORM_EXCEPTIONS_INVALIDTYPEEXCEPTION_H_

63
src/ir/Assignment.cpp

@ -1,63 +0,0 @@
/*
* Assignment.cpp
*
* Created on: 12.01.2013
* Author: Christian Dehnert
*/
#include <sstream>
#include "Assignment.h"
#include "src/parser/prismparser/VariableState.h"
namespace storm {
namespace ir {
Assignment::Assignment() : variableName(), expression() {
// Nothing to do here.
}
Assignment::Assignment(std::string const& variableName, std::unique_ptr<storm::ir::expressions::BaseExpression>&& expression)
: variableName(variableName), expression(std::move(expression)) {
// Nothing to do here.
}
Assignment::Assignment(Assignment const& oldAssignment, std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState)
: variableName(oldAssignment.variableName), expression(oldAssignment.expression->clone(renaming, variableState)) {
auto renamingPair = renaming.find(oldAssignment.variableName);
if (renamingPair != renaming.end()) {
this->variableName = renamingPair->second;
}
}
Assignment::Assignment(Assignment const& otherAssignment) : variableName(otherAssignment.variableName), expression() {
if (otherAssignment.expression != nullptr) {
expression = otherAssignment.expression->clone();
}
}
Assignment& Assignment::operator=(Assignment const& otherAssignment) {
if (this != &otherAssignment) {
this->variableName = otherAssignment.variableName;
this->expression = otherAssignment.expression->clone();
}
return *this;
}
std::string const& Assignment::getVariableName() const {
return variableName;
}
std::unique_ptr<storm::ir::expressions::BaseExpression> const& Assignment::getExpression() const {
return expression;
}
std::string Assignment::toString() const {
std::stringstream result;
result << "(" << variableName << "' = " << expression->toString() << ")";
return result.str();
}
} // namespace ir
} // namespace storm

98
src/ir/Assignment.h

@ -1,98 +0,0 @@
/*
* Assignment.h
*
* Created on: 06.01.2013
* Author: Christian Dehnert
*/
#ifndef STORM_IR_ASSIGNMENT_H_
#define STORM_IR_ASSIGNMENT_H_
#include <memory>
#include "expressions/BaseExpression.h"
namespace storm {
namespace parser {
namespace prism {
class VariableState;
} // namespace prismparser
} // namespace parser
namespace ir {
/*!
* A class representing the assignment of an expression to a variable.
*/
class Assignment {
public:
/*!
* Default constructor. Creates an empty assignment.
*/
Assignment();
/*!
* Constructs an assignment using the given variable name and expression.
*
* @param variableName The variable that this assignment targets.
* @param expression The expression to assign to the variable.
*/
Assignment(std::string const& variableName, std::unique_ptr<storm::ir::expressions::BaseExpression>&& expression);
/*!
* Creates a copy of the given assignment and performs the provided renaming.
*
* @param oldAssignment The assignment to copy.
* @param renaming A mapping from names that are to be renamed to the names they are to be
* replaced with.
* @param variableState An object knowing about the variables in the system.
*/
Assignment(Assignment const& oldAssignment, std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState);
/*!
* Performs a deep-copy of the given assignment.
*
* @param otherAssignment The assignment to copy.
*/
Assignment(Assignment const& otherAssignment);
/*!
* Performs a deep-copy of the given assignment and assigns it to the current one.
*
* @param otherAssignment The assignment to assign.
*/
Assignment& operator=(Assignment const& otherAssignment);
/*!
* Retrieves the name of the variable that this assignment targets.
*
* @return The name of the variable that this assignment targets.
*/
std::string const& getVariableName() const;
/*!
* Retrieves the expression that is assigned to the variable.
*
* @return The expression that is assigned to the variable.
*/
std::unique_ptr<storm::ir::expressions::BaseExpression> const& getExpression() const;
/*!
* Retrieves a string representation of this assignment.
* @returns a string representation of this assignment.
*/
std::string toString() const;
private:
// The name of the variable that this assignment targets.
std::string variableName;
// The expression that is assigned to the variable.
std::unique_ptr<storm::ir::expressions::BaseExpression> expression;
};
} // namespace ir
} // namespace storm
#endif /* STORM_IR_ASSIGNMENT_H_ */

49
src/ir/BooleanVariable.cpp

@ -1,49 +0,0 @@
/*
* BooleanVariable.cpp
*
* Created on: 12.01.2013
* Author: Christian Dehnert
*/
#include <sstream>
#include "BooleanVariable.h"
#include "src/parser/prismparser/VariableState.h"
namespace storm {
namespace ir {
BooleanVariable::BooleanVariable() : Variable() {
// Nothing to do here.
}
BooleanVariable::BooleanVariable(uint_fast64_t localIndex, uint_fast64_t globalIndex, std::string const& variableName, std::unique_ptr<storm::ir::expressions::BaseExpression>&& initialValue)
: Variable(localIndex, globalIndex, variableName, std::move(initialValue)) {
// Nothing to do here.
}
BooleanVariable::BooleanVariable(BooleanVariable const& oldVariable, std::string const& newName, uint_fast64_t newGlobalIndex, std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState)
: Variable(oldVariable, newName, newGlobalIndex, renaming, variableState) {
// Nothing to do here.
}
BooleanVariable& BooleanVariable::operator=(BooleanVariable const& otherVariable) {
if (this != &otherVariable) {
Variable::operator=(otherVariable);
}
return *this;
}
std::string BooleanVariable::toString() const {
std::stringstream result;
result << this->getName() << ": bool";
if (this->getInitialValue() != nullptr) {
result << " init " << this->getInitialValue()->toString();
}
result << ";";
return result.str();
}
} // namespace ir
} // namespace storm

70
src/ir/BooleanVariable.h

@ -1,70 +0,0 @@
/*
* BooleanVariable.h
*
* Created on: 08.01.2013
* Author: Christian Dehnert
*/
#ifndef STORM_IR_BOOLEANVARIABLE_H_
#define STORM_IR_BOOLEANVARIABLE_H_
#include <memory>
#include <map>
#include "src/ir/Variable.h"
namespace storm {
namespace parser {
namespace prism {
class VariableState;
} // namespace prismparser
} // namespace parser
namespace ir {
/*!
* A class representing a boolean variable.
*/
class BooleanVariable : public Variable {
public:
/*!
* Default constructor. Creates a boolean variable without a name.
*/
BooleanVariable();
/*!
* Creates a boolean variable with the given name and the given initial value.
*
* @param localIndex A module-local unique index for the variable.
* @param globalIndex A globally unique index for the variable.
* @param variableName The name of the variable.
* @param initialValue The expression that defines the initial value of the variable.
*/
BooleanVariable(uint_fast64_t localIndex, uint_fast64_t globalIndex, std::string const& variableName, std::unique_ptr<storm::ir::expressions::BaseExpression>&& initialValue = nullptr);
/*!
* Creates a copy of the given boolean variable and performs the provided renaming.
*
* @param oldVariable The variable to copy.
* @param newName New name of this variable.
* @param newGlobalIndex The new global index of the variable.
* @param renaming A mapping from names that are to be renamed to the names they are to be
* replaced with.
* @param variableState An object knowing about the variables in the system.
*/
BooleanVariable(BooleanVariable const& oldVariable, std::string const& newName, uint_fast64_t newGlobalIndex, std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState);
BooleanVariable& operator=(BooleanVariable const& otherVariable);
/*!
* Retrieves a string representation of this variable.
* @returns a string representation of this variable.
*/
std::string toString() const;
};
} // namespace ir
} // namespace storm
#endif /* STORM_IR_BOOLEANVARIABLE_H_ */

94
src/ir/Command.cpp

@ -1,94 +0,0 @@
/*
* Command.cpp
*
* Created on: 12.01.2013
* Author: Christian Dehnert
*/
#include <sstream>
#include <iostream>
#include "Command.h"
#include "src/parser/prismparser/VariableState.h"
namespace storm {
namespace ir {
Command::Command() : actionName(), guardExpression(), updates(), globalIndex() {
// Nothing to do here.
}
Command::Command(uint_fast64_t globalIndex, std::string const& actionName, std::unique_ptr<storm::ir::expressions::BaseExpression>&& guardExpression, std::vector<storm::ir::Update> const& updates)
: actionName(actionName), guardExpression(std::move(guardExpression)), updates(updates), globalIndex(globalIndex) {
// Nothing to do here.
}
Command::Command(Command const& oldCommand, uint_fast64_t newGlobalIndex, std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState& variableState)
: actionName(oldCommand.getActionName()), guardExpression(oldCommand.guardExpression->clone(renaming, variableState)), globalIndex(newGlobalIndex) {
auto renamingPair = renaming.find(this->actionName);
if (renamingPair != renaming.end()) {
this->actionName = renamingPair->second;
}
this->updates.reserve(oldCommand.getNumberOfUpdates());
for (Update const& update : oldCommand.updates) {
this->updates.emplace_back(update, variableState.getNextGlobalUpdateIndex(), renaming, variableState);
variableState.nextGlobalUpdateIndex++;
}
}
Command::Command(Command const& otherCommand) : actionName(otherCommand.actionName), guardExpression(), updates(otherCommand.updates), globalIndex(otherCommand.globalIndex) {
if (otherCommand.guardExpression != nullptr) {
guardExpression = otherCommand.guardExpression->clone();
}
}
Command& Command::operator=(Command const& otherCommand) {
if (this != &otherCommand) {
this->actionName = otherCommand.actionName;
this->guardExpression = otherCommand.guardExpression->clone();
this->updates = otherCommand.updates;
this->globalIndex = otherCommand.globalIndex;
}
return *this;
}
std::string const& Command::getActionName() const {
return this->actionName;
}
std::unique_ptr<storm::ir::expressions::BaseExpression> const& Command::getGuard() const {
return guardExpression;
}
uint_fast64_t Command::getNumberOfUpdates() const {
return this->updates.size();
}
storm::ir::Update const& Command::getUpdate(uint_fast64_t index) const {
return this->updates[index];
}
std::vector<storm::ir::Update> const& Command::getUpdates() const {
return this->updates;
}
uint_fast64_t Command::getGlobalIndex() const {
return this->globalIndex;
}
std::string Command::toString() const {
std::stringstream result;
result << "[" << actionName << "] " << guardExpression->toString() << " -> ";
for (uint_fast64_t i = 0; i < updates.size(); ++i) {
result << updates[i].toString();
if (i < updates.size() - 1) {
result << " + ";
}
}
result << ";";
return result.str();
}
} // namespace ir
} // namespace storm

134
src/ir/Command.h

@ -1,134 +0,0 @@
/*
* Command.h
*
* Created on: 06.01.2013
* Author: Christian Dehnert
*/
#ifndef STORM_IR_COMMAND_H_
#define STORM_IR_COMMAND_H_
#include <vector>
#include <string>
#include <map>
#include "expressions/BaseExpression.h"
#include "Update.h"
namespace storm {
namespace parser {
namespace prism {
class VariableState;
} // namespace prismparser
} // namespace parser
namespace ir {
/*!
* A class representing a command.
*/
class Command {
public:
/*!
* Default constructor. Creates a a command without name, guard and updates.
*/
Command();
/*!
* Creates a command with the given name, guard and updates.
*
* @param globalIndex The global index of the command.
* @param actionName The action name of the command.
* @param guardExpression the expression that defines the guard of the command.
* @param updates A list of updates that is associated with this command.
*/
Command(uint_fast64_t globalIndex, std::string const& actionName, std::unique_ptr<storm::ir::expressions::BaseExpression>&& guardExpression, std::vector<storm::ir::Update> const& updates);
/*!
* Creates a copy of the given command and performs the provided renaming.
*
* @param oldCommand The command to copy.
* @param newGlobalIndex The global index of the copy of the command.
* @param renaming A mapping from names that are to be renamed to the names they are to be
* replaced with.
* @param variableState An object knowing about the variables in the system.
*/
Command(Command const& oldCommand, uint_fast64_t newGlobalIndex, std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState& variableState);
/*!
* Performs a deep-copy of the given command.
*
* @param otherCommand The command to copy.
*/
Command(Command const& otherCommand);
Command& operator=(Command const& otherCommand);
/*!
* Retrieves the action name of this command.
*
* @return The action name of this command.
*/
std::string const& getActionName() const;
/*!
* Retrieves a reference to the guard of the command.
*
* @return A reference to the guard of the command.
*/
std::unique_ptr<storm::ir::expressions::BaseExpression> const& getGuard() const;
/*!
* Retrieves the number of updates associated with this command.
*
* @return The number of updates associated with this command.
*/
uint_fast64_t getNumberOfUpdates() const;
/*!
* Retrieves a reference to the update with the given index.
*
* @return A reference to the update with the given index.
*/
storm::ir::Update const& getUpdate(uint_fast64_t index) const;
/*!
* Retrieves a vector of all updates associated with this command.
*
* @return A vector of updates associated with this command.
*/
std::vector<storm::ir::Update> const& getUpdates() const;
/*!
* Retrieves the global index of the command, that is, a unique index over all modules.
*
* @return The global index of the command.
*/
uint_fast64_t getGlobalIndex() const;
/*!
* Retrieves a string representation of this command.
*
* @return A string representation of this command.
*/
std::string toString() const;
private:
// The name of the command.
std::string actionName;
// The expression that defines the guard of the command.
std::unique_ptr<storm::ir::expressions::BaseExpression> guardExpression;
// The list of updates of the command.
std::vector<storm::ir::Update> updates;
// The global index of the command.
uint_fast64_t globalIndex;
};
} // namespace ir
} // namespace storm
#endif /* STORM_IR_COMMAND_H_ */

25
src/ir/IR.h

@ -1,25 +0,0 @@
/*
* IR.h
*
* Created on: 06.01.2013
* Author: Christian Dehnert
*/
#ifndef STORM_IR_IR_H_
#define STORM_IR_IR_H_
// Bundle all headers to make it easy to include them.
#include "expressions/Expressions.h"
#include "Assignment.h"
#include "Update.h"
#include "Command.h"
#include "Variable.h"
#include "BooleanVariable.h"
#include "IntegerVariable.h"
#include "Module.h"
#include "StateReward.h"
#include "TransitionReward.h"
#include "RewardModel.h"
#include "Program.h"
#endif /* STORM_IR_IR_H_ */

72
src/ir/IntegerVariable.cpp

@ -1,72 +0,0 @@
/*
* IntegerVariable.cpp
*
* Created on: 12.01.2013
* Author: Christian Dehnert
*/
#include <sstream>
#include <iostream>
#include "IntegerVariable.h"
#include "src/parser/prismparser/VariableState.h"
namespace storm {
namespace ir {
IntegerVariable::IntegerVariable() : lowerBound(), upperBound() {
// Nothing to do here.
}
IntegerVariable::IntegerVariable(uint_fast64_t localIndex, uint_fast64_t globalIndex, std::string const& variableName, std::unique_ptr<storm::ir::expressions::BaseExpression>&& lowerBound, std::unique_ptr<storm::ir::expressions::BaseExpression>&& upperBound, std::unique_ptr<storm::ir::expressions::BaseExpression>&& initialValue)
: Variable(localIndex, globalIndex, variableName, std::move(initialValue)), lowerBound(std::move(lowerBound)), upperBound(std::move(upperBound)) {
// Nothing to do here.
}
IntegerVariable::IntegerVariable(IntegerVariable const& oldVariable, std::string const& newName, uint_fast64_t newGlobalIndex, std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState)
: Variable(oldVariable, newName, newGlobalIndex, renaming, variableState), lowerBound(oldVariable.lowerBound->clone(renaming, variableState)), upperBound(oldVariable.upperBound->clone(renaming, variableState)) {
// Nothing to do here.
}
IntegerVariable::IntegerVariable(IntegerVariable const& otherVariable) : Variable(otherVariable.getLocalIndex(), otherVariable.getGlobalIndex(), otherVariable.getName(), nullptr), lowerBound(), upperBound() {
if (otherVariable.getInitialValue() != nullptr) {
setInitialValue(otherVariable.getInitialValue()->clone());
}
if (otherVariable.lowerBound != nullptr) {
lowerBound = otherVariable.lowerBound->clone();
}
if (otherVariable.upperBound != nullptr) {
upperBound = otherVariable.upperBound->clone();
}
}
IntegerVariable& IntegerVariable::operator=(IntegerVariable const& otherVariable) {
if (this != &otherVariable) {
Variable::operator=(otherVariable);
this->lowerBound = otherVariable.lowerBound->clone();
this->upperBound = otherVariable.upperBound->clone();
}
return *this;
}
std::unique_ptr<storm::ir::expressions::BaseExpression> const& IntegerVariable::getLowerBound() const {
return this->lowerBound;
}
std::unique_ptr<storm::ir::expressions::BaseExpression> const& IntegerVariable::getUpperBound() const {
return this->upperBound;
}
std::string IntegerVariable::toString() const {
std::stringstream result;
result << this->getName() << ": [" << lowerBound->toString() << ".." << upperBound->toString() << "]";
if (this->getInitialValue() != nullptr) {
result << " init " + this->getInitialValue()->toString();
}
result << ";";
return result.str();
}
} // namespace ir
} // namespace storm

98
src/ir/IntegerVariable.h

@ -1,98 +0,0 @@
/*
* IntegerVariable.h
*
* Created on: 08.01.2013
* Author: Christian Dehnert
*/
#ifndef STORM_IR_INTEGERVARIABLE_H_
#define STORM_IR_INTEGERVARIABLE_H_
#include <memory>
#include "src/ir/Variable.h"
#include "expressions/BaseExpression.h"
namespace storm {
namespace parser {
namespace prism {
class VariableState;
} // namespace prismparser
} // namespace parser
namespace ir {
/*!
* A class representing an integer variable.
*/
class IntegerVariable : public Variable {
public:
/*!
* Default constructor. Creates an integer variable without a name and lower and upper bounds.
*/
IntegerVariable();
/*!
* Creates a boolean variable with the given name and the given initial value.
*
* @param localIndex A module-local unique index for the variable.
* @param globalIndex A globally unique index for the variable.
* @param variableName The name of the variable.
* @param lowerBound the lower bound of the domain of the variable.
* @param upperBound the upper bound of the domain of the variable.
* @param initialValue the expression that defines the initial value of the variable.
*/
IntegerVariable(uint_fast64_t localIndex, uint_fast64_t globalIndex, std::string const& variableName, std::unique_ptr<storm::ir::expressions::BaseExpression>&& lowerBound, std::unique_ptr<storm::ir::expressions::BaseExpression>&& upperBound, std::unique_ptr<storm::ir::expressions::BaseExpression>&& initialValue = nullptr);
/*!
* Creates a copy of the given integer variable and performs the provided renaming.
*
* @param oldVariable The variable to copy.
* @param newName New name of this variable.
* @param newGlobalIndex The new global index of the variable.
* @param renaming A mapping from names that are to be renamed to the names they are to be
* replaced with.
* @param variableState An object knowing about the variables in the system.
*/
IntegerVariable(IntegerVariable const& oldVariable, std::string const& newName, uint_fast64_t newGlobalIndex, std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState);
/*!
* Performs a deep-copy of the given variable.
*
* @param otherVariable The variable to copy.
*/
IntegerVariable(IntegerVariable const& otherVariable);
IntegerVariable& operator=(IntegerVariable const& otherVariable);
/*!
* Retrieves the lower bound for this integer variable.
* @returns the lower bound for this integer variable.
*/
std::unique_ptr<storm::ir::expressions::BaseExpression> const& getLowerBound() const;
/*!
* Retrieves the upper bound for this integer variable.
* @returns the upper bound for this integer variable.
*/
std::unique_ptr<storm::ir::expressions::BaseExpression> const& getUpperBound() const;
/*!
* Retrieves a string representation of this variable.
* @returns a string representation of this variable.
*/
std::string toString() const;
private:
// The lower bound of the domain of the variable.
std::unique_ptr<storm::ir::expressions::BaseExpression> lowerBound;
// The upper bound of the domain of the variable.
std::unique_ptr<storm::ir::expressions::BaseExpression> upperBound;
};
} // namespace ir
} // namespace storm
#endif /* STORM_IR_INTEGERVARIABLE_H_ */

217
src/ir/Module.cpp

@ -1,217 +0,0 @@
/*
* Module.cpp
*
* Created on: 12.01.2013
* Author: Christian Dehnert
*/
#include <sstream>
#include <iostream>
#include "utility/OsDetection.h"
#include "Module.h"
#include "src/parser/prismparser/VariableState.h"
#include "src/exceptions/OutOfRangeException.h"
#include "src/exceptions/InvalidArgumentException.h"
#include "log4cplus/logger.h"
#include "log4cplus/loggingmacros.h"
extern log4cplus::Logger logger;
namespace storm {
namespace ir {
Module::Module() : moduleName(), booleanVariables(), integerVariables(), booleanVariableToLocalIndexMap(),
integerVariableToLocalIndexMap(), commands(), actions(), actionsToCommandIndexMap() {
// Nothing to do here.
}
Module::Module(std::string const& moduleName,
std::vector<storm::ir::BooleanVariable> const& booleanVariables,
std::vector<storm::ir::IntegerVariable> const& integerVariables,
std::map<std::string, uint_fast64_t> const& booleanVariableToLocalIndexMap,
std::map<std::string, uint_fast64_t> const& integerVariableToLocalIndexMap,
std::vector<storm::ir::Command> const& commands)
: moduleName(moduleName), booleanVariables(booleanVariables), integerVariables(integerVariables),
booleanVariableToLocalIndexMap(booleanVariableToLocalIndexMap),
integerVariableToLocalIndexMap(integerVariableToLocalIndexMap), commands(commands), actions(), actionsToCommandIndexMap() {
// Initialize the internal mappings for fast information retrieval.
this->collectActions();
}
Module::Module(Module const& oldModule, std::string const& newModuleName, std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState& variableState)
: moduleName(newModuleName), booleanVariableToLocalIndexMap(oldModule.booleanVariableToLocalIndexMap), integerVariableToLocalIndexMap(oldModule.integerVariableToLocalIndexMap) {
LOG4CPLUS_TRACE(logger, "Start renaming " << oldModule.getName() << " to " << moduleName << ".");
// Iterate over boolean variables and rename them. If a variable was not renamed, this is an error and an exception
// is thrown.
this->booleanVariables.reserve(oldModule.getNumberOfBooleanVariables());
for (BooleanVariable const& booleanVariable : oldModule.booleanVariables) {
auto renamingPair = renaming.find(booleanVariable.getName());
if (renamingPair == renaming.end()) {
LOG4CPLUS_ERROR(logger, "Boolean variable " << moduleName << "." << booleanVariable.getName() << " was not renamed.");
throw storm::exceptions::InvalidArgumentException() << "Boolean variable " << moduleName << "." << booleanVariable.getName() << " was not renamed.";
} else {
uint_fast64_t globalIndex = variableState.addBooleanVariable(renamingPair->second);
this->booleanVariables.emplace_back(booleanVariable, renamingPair->second, globalIndex, renaming, variableState);
}
}
// Now do the same for the integer variables.
this->integerVariables.reserve(oldModule.getNumberOfIntegerVariables());
for (IntegerVariable const& integerVariable : oldModule.integerVariables) {
auto renamingPair = renaming.find(integerVariable.getName());
if (renamingPair == renaming.end()) {
LOG4CPLUS_ERROR(logger, "Integer variable " << moduleName << "." << integerVariable.getName() << " was not renamed.");
throw storm::exceptions::InvalidArgumentException() << "Integer variable " << moduleName << "." << integerVariable.getName() << " was not renamed.";
} else {
uint_fast64_t globalIndex = variableState.addIntegerVariable(renamingPair->second);
this->integerVariables.emplace_back(integerVariable, renamingPair->second, globalIndex, renaming, variableState);
}
}
// Now we are ready to clone all commands and rename them if requested.
this->commands.reserve(oldModule.getNumberOfCommands());
for (Command const& command : oldModule.commands) {
this->commands.emplace_back(command, variableState.getNextGlobalCommandIndex(), renaming, variableState);
variableState.nextGlobalCommandIndex++;
}
this->collectActions();
LOG4CPLUS_TRACE(logger, "Finished renaming...");
}
uint_fast64_t Module::getNumberOfBooleanVariables() const {
return this->booleanVariables.size();
}
storm::ir::BooleanVariable const& Module::getBooleanVariable(uint_fast64_t index) const {
return this->booleanVariables[index];
}
storm::ir::BooleanVariable const& Module::getBooleanVariable(std::string const& variableName) const {
uint_fast64_t index = this->getBooleanVariableIndex(variableName);
return this->booleanVariables[index];
}
uint_fast64_t Module::getNumberOfIntegerVariables() const {
return this->integerVariables.size();
}
storm::ir::IntegerVariable const& Module::getIntegerVariable(uint_fast64_t index) const {
return this->integerVariables[index];
}
storm::ir::IntegerVariable const& Module::getIntegerVariable(std::string const& variableName) const {
uint_fast64_t index = this->getIntegerVariableIndex(variableName);
return this->integerVariables[index];
}
uint_fast64_t Module::getNumberOfCommands() const {
return this->commands.size();
}
uint_fast64_t Module::getBooleanVariableIndex(std::string const& variableName) const {
auto it = booleanVariableToLocalIndexMap.find(variableName);
if (it != booleanVariableToLocalIndexMap.end()) {
return it->second;
}
LOG4CPLUS_ERROR(logger, "Cannot retrieve index of unknown boolean variable " << variableName << ".");
throw storm::exceptions::InvalidArgumentException() << "Cannot retrieve index of unknown boolean variable " << variableName << ".";
}
uint_fast64_t Module::getIntegerVariableIndex(std::string const& variableName) const {
auto it = integerVariableToLocalIndexMap.find(variableName);
if (it != integerVariableToLocalIndexMap.end()) {
return it->second;
}
LOG4CPLUS_ERROR(logger, "Cannot retrieve index of unknown integer variable " << variableName << ".");
throw storm::exceptions::InvalidArgumentException() << "Cannot retrieve index of unknown integer variable " << variableName << ".";
}
storm::ir::Command const& Module::getCommand(uint_fast64_t index) const {
return this->commands[index];
}
std::string const& Module::getName() const {
return this->moduleName;
}
std::string Module::toString() const {
std::stringstream result;
result << "module " << moduleName << std::endl;
for (auto variable : booleanVariables) {
result << "\t" << variable.toString() << std::endl;
}
for (auto variable : integerVariables) {
result << "\t" << variable.toString() << std::endl;
}
for (auto command : commands) {
result << "\t" << command.toString() << std::endl;
}
result << "endmodule" << std::endl;
return result.str();
}
std::set<std::string> const& Module::getActions() const {
return this->actions;
}
bool Module::hasAction(std::string const& action) const {
auto const& actionEntry = this->actions.find(action);
if (actionEntry != this->actions.end()) {
return true;
}
return false;
}
std::set<uint_fast64_t> const& Module::getCommandsByAction(std::string const& action) const {
auto actionsCommandSetPair = this->actionsToCommandIndexMap.find(action);
if (actionsCommandSetPair != this->actionsToCommandIndexMap.end()) {
return actionsCommandSetPair->second;
}
LOG4CPLUS_ERROR(logger, "Action name '" << action << "' does not exist in module.");
throw storm::exceptions::OutOfRangeException() << "Action name '" << action << "' does not exist in module.";
}
void Module::collectActions() {
// Clear the current mapping.
this->actionsToCommandIndexMap.clear();
// Add the mapping for all commands.
for (unsigned int id = 0; id < this->commands.size(); id++) {
std::string const& action = this->commands[id].getActionName();
if (action != "") {
if (this->actionsToCommandIndexMap.find(action) == this->actionsToCommandIndexMap.end()) {
this->actionsToCommandIndexMap.emplace(action, std::set<uint_fast64_t>());
}
this->actionsToCommandIndexMap[action].insert(id);
this->actions.insert(action);
}
}
// For all actions that are "in the module", but for which no command exists, we add the mapping to an empty
// set of commands.
for (auto const& action : this->actions) {
if (this->actionsToCommandIndexMap.find(action) == this->actionsToCommandIndexMap.end()) {
this->actionsToCommandIndexMap[action] = std::set<uint_fast64_t>();
}
}
}
void Module::restrictCommands(boost::container::flat_set<uint_fast64_t> const& indexSet) {
// First construct the new vector of commands.
std::vector<storm::ir::Command> newCommands;
for (auto const& command : commands) {
if (indexSet.find(command.getGlobalIndex()) != indexSet.end()) {
newCommands.push_back(std::move(command));
}
}
commands = std::move(newCommands);
// Then refresh the internal mappings.
this->collectActions();
}
} // namespace ir
} // namespace storm

226
src/ir/Module.h

@ -1,226 +0,0 @@
/*
* Module.h
*
* Created on: 04.01.2013
* Author: Christian Dehnert
*/
#ifndef STORM_IR_MODULE_H_
#define STORM_IR_MODULE_H_
#include "utility/OsDetection.h"
#include <boost/container/flat_set.hpp>
#ifdef LINUX
#include <boost/container/map.hpp>
#endif
#include <map>
#include <set>
#include <string>
#include <vector>
#include <memory>
#include "BooleanVariable.h"
#include "IntegerVariable.h"
#include "Command.h"
#include "expressions/VariableExpression.h"
namespace storm {
namespace parser {
namespace prism {
class VariableState;
} // namespace prismparser
} // namespace parser
namespace ir {
/*!
* A class representing a module.
*/
class Module {
public:
/*!
* Default constructor. Creates an empty module.
*/
Module();
/*!
* Creates a module with the given name, variables and commands.
*
* @param moduleName The name of the module.
* @param booleanVariables The boolean variables defined by the module.
* @param integerVariables The integer variables defined by the module.
* @param booleanVariableToLocalIndexMap A mapping of boolean variables to local (i.e. module-local) indices.
* @param integerVariableToLocalIndexMap A mapping of integer variables to local (i.e. module-local) indices.
* @param commands The commands of the module.
*/
Module(std::string const& moduleName, std::vector<storm::ir::BooleanVariable> const& booleanVariables,
std::vector<storm::ir::IntegerVariable> const& integerVariables,
std::map<std::string, uint_fast64_t> const& booleanVariableToLocalIndexMap,
std::map<std::string, uint_fast64_t> const& integerVariableToLocalIndexMap,
std::vector<storm::ir::Command> const& commands);
/*!
* Special copy constructor, implementing the module renaming functionality.
* This will create a new module having all identifiers renamed according to the given map.
*
* @param oldModule The module to be copied.
* @param newModuleName The name of the new module.
* @param renaming A mapping of identifiers to the new identifiers they are to be replaced with.
* @param variableState An object knowing about the variables in the system.
*/
Module(Module const& oldModule, std::string const& newModuleName, std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState& variableState);
/*!
* Retrieves the number of boolean variables in the module.
*
* @return the number of boolean variables in the module.
*/
uint_fast64_t getNumberOfBooleanVariables() const;
/*!
* Retrieves a reference to the boolean variable with the given index.
*
* @return A reference to the boolean variable with the given index.
*/
storm::ir::BooleanVariable const& getBooleanVariable(uint_fast64_t index) const;
/*!
* Retrieves a reference to the boolean variable with the given name.
*
* @return A reference to the boolean variable with the given name.
*/
storm::ir::BooleanVariable const& getBooleanVariable(std::string const& variableName) const;
/*!
* Retrieves the number of integer variables in the module.
*
* @return The number of integer variables in the module.
*/
uint_fast64_t getNumberOfIntegerVariables() const;
/*!
* Retrieves a reference to the integer variable with the given index.
*
* @return A reference to the integer variable with the given index.
*/
storm::ir::IntegerVariable const& getIntegerVariable(uint_fast64_t index) const;
/*!
* Retrieves a reference to the boolean variable with the given name.
*
* @return A reference to the boolean variable with the given name.
*/
storm::ir::IntegerVariable const& getIntegerVariable(std::string const& variableName) const;
/*!
* Retrieves the number of commands of this module.
*
* @return the number of commands of this module.
*/
uint_fast64_t getNumberOfCommands() const;
/*!
* Retrieves the index of the boolean variable with the given name.
*
* @param variableName The name of the boolean variable whose index to retrieve.
* @return The index of the boolean variable with the given name.
*/
uint_fast64_t getBooleanVariableIndex(std::string const& variableName) const;
/*!
* Retrieves the index of the integer variable with the given name.
*
* @param variableName The name of the integer variable whose index to retrieve.
* @return The index of the integer variable with the given name.
*/
uint_fast64_t getIntegerVariableIndex(std::string const& variableName) const;
/*!
* Retrieves a reference to the command with the given index.
*
* @return A reference to the command with the given index.
*/
storm::ir::Command const& getCommand(uint_fast64_t index) const;
/*!
* Retrieves the name of the module.
*
* @return The name of the module.
*/
std::string const& getName() const;
/*!
* Retrieves a string representation of this module.
*
* @return a string representation of this module.
*/
std::string toString() const;
/*!
* Retrieves the set of actions present in this module.
*
* @return the set of actions present in this module.
*/
std::set<std::string> const& getActions() const;
/*!
* Retrieves whether or not this module contains a command labeled with the given action.
*
* @param action The action name to look for in this module.
* @return True if the module has at least one command labeled with the given action.
*/
bool hasAction(std::string const& action) const;
/*!
* Retrieves the indices of all commands within this module that are labelled by the given action.
*
* @param action The action with which the commands have to be labelled.
* @return A set of indices of commands that are labelled with the given action.
*/
std::set<uint_fast64_t> const& getCommandsByAction(std::string const& action) const;
/*!
* Deletes all commands with indices not in the given set from the module.
*
* @param indexSet The set of indices for which to keep the commands.
*/
void restrictCommands(boost::container::flat_set<uint_fast64_t> const& indexSet);
private:
/*!
* Computes the locally maintained mappings for fast data retrieval.
*/
void collectActions();
// The name of the module.
std::string moduleName;
// A list of boolean variables.
std::vector<storm::ir::BooleanVariable> booleanVariables;
// A list of integer variables.
std::vector<storm::ir::IntegerVariable> integerVariables;
// A map of boolean variable names to their index.
std::map<std::string, uint_fast64_t> booleanVariableToLocalIndexMap;
// A map of integer variable names to their index.
std::map<std::string, uint_fast64_t> integerVariableToLocalIndexMap;
// The commands associated with the module.
std::vector<storm::ir::Command> commands;
// The set of actions present in this module.
std::set<std::string> actions;
// A map of actions to the set of commands labeled with this action.
std::map<std::string, std::set<uint_fast64_t>> actionsToCommandIndexMap;
};
} // namespace ir
} // namespace storm
#endif /* STORM_IR_MODULE_H_ */

300
src/ir/Program.cpp

@ -1,300 +0,0 @@
/*
* Program.cpp
*
* Created on: 12.01.2013
* Author: Christian Dehnert
*/
#include <sstream>
#include <iostream>
#include "Program.h"
#include "exceptions/InvalidArgumentException.h"
#include "src/exceptions/OutOfRangeException.h"
#include "log4cplus/logger.h"
#include "log4cplus/loggingmacros.h"
extern log4cplus::Logger logger;
namespace storm {
namespace ir {
Program::Program() : modelType(UNDEFINED), booleanUndefinedConstantExpressions(), integerUndefinedConstantExpressions(), doubleUndefinedConstantExpressions(), modules(), rewards(), actions(), actionsToModuleIndexMap(), variableToModuleIndexMap() {
// Nothing to do here.
}
Program::Program(ModelType modelType,
std::map<std::string, std::unique_ptr<storm::ir::expressions::BooleanConstantExpression>> const& booleanUndefinedConstantExpressions,
std::map<std::string, std::unique_ptr<storm::ir::expressions::IntegerConstantExpression>> const& integerUndefinedConstantExpressions,
std::map<std::string, std::unique_ptr<storm::ir::expressions::DoubleConstantExpression>> const& doubleUndefinedConstantExpressions,
std::vector<BooleanVariable> const& globalBooleanVariables,
std::vector<IntegerVariable> const& globalIntegerVariables,
std::map<std::string, uint_fast64_t> const& globalBooleanVariableToIndexMap,
std::map<std::string, uint_fast64_t> const& globalIntegerVariableToIndexMap,
std::vector<storm::ir::Module> const& modules,
std::map<std::string, storm::ir::RewardModel> const& rewards,
std::map<std::string, std::unique_ptr<storm::ir::expressions::BaseExpression>> const& labels)
: modelType(modelType), globalBooleanVariables(globalBooleanVariables), globalIntegerVariables(globalIntegerVariables),
globalBooleanVariableToIndexMap(globalBooleanVariableToIndexMap), globalIntegerVariableToIndexMap(globalIntegerVariableToIndexMap),
modules(modules), rewards(rewards), actionsToModuleIndexMap(), variableToModuleIndexMap() {
// Perform a deep-copy of the maps.
for (auto const& booleanUndefinedConstant : booleanUndefinedConstantExpressions) {
this->booleanUndefinedConstantExpressions[booleanUndefinedConstant.first] = std::unique_ptr<storm::ir::expressions::BooleanConstantExpression>(new storm::ir::expressions::BooleanConstantExpression(*booleanUndefinedConstant.second));
}
for (auto const& integerUndefinedConstant : integerUndefinedConstantExpressions) {
this->integerUndefinedConstantExpressions[integerUndefinedConstant.first] = std::unique_ptr<storm::ir::expressions::IntegerConstantExpression>(new storm::ir::expressions::IntegerConstantExpression(*integerUndefinedConstant.second));
}
for (auto const& doubleUndefinedConstant : doubleUndefinedConstantExpressions) {
this->doubleUndefinedConstantExpressions[doubleUndefinedConstant.first] = std::unique_ptr<storm::ir::expressions::DoubleConstantExpression>(new storm::ir::expressions::DoubleConstantExpression(*doubleUndefinedConstant.second));
}
for (auto const& label : labels) {
this->labels[label.first] = label.second->clone();
}
// Now build the mapping from action names to module indices so that the lookup can later be performed quickly.
for (unsigned int moduleIndex = 0; moduleIndex < this->modules.size(); moduleIndex++) {
Module const& module = this->modules[moduleIndex];
for (auto const& action : module.getActions()) {
if (this->actionsToModuleIndexMap.count(action) == 0) {
this->actionsToModuleIndexMap[action] = std::set<uint_fast64_t>();
}
this->actionsToModuleIndexMap[action].insert(moduleIndex);
this->actions.insert(action);
}
// Put in the appropriate entries for the mapping from variable names to module index.
for (uint_fast64_t booleanVariableIndex = 0; booleanVariableIndex < module.getNumberOfBooleanVariables(); ++booleanVariableIndex) {
this->variableToModuleIndexMap[module.getBooleanVariable(booleanVariableIndex).getName()] = moduleIndex;
}
for (uint_fast64_t integerVariableIndex = 0; integerVariableIndex < module.getNumberOfIntegerVariables(); ++integerVariableIndex) {
this->variableToModuleIndexMap[module.getIntegerVariable(integerVariableIndex).getName()] = moduleIndex;
}
}
}
Program::Program(Program const& otherProgram) : modelType(otherProgram.modelType), globalBooleanVariables(otherProgram.globalBooleanVariables),
globalIntegerVariables(otherProgram.globalIntegerVariables), globalBooleanVariableToIndexMap(otherProgram.globalBooleanVariableToIndexMap),
globalIntegerVariableToIndexMap(otherProgram.globalIntegerVariableToIndexMap), modules(otherProgram.modules), rewards(otherProgram.rewards),
actions(otherProgram.actions), actionsToModuleIndexMap(), variableToModuleIndexMap() {
// Perform deep-copy of the maps.
for (auto const& booleanUndefinedConstant : otherProgram.booleanUndefinedConstantExpressions) {
this->booleanUndefinedConstantExpressions[booleanUndefinedConstant.first] = std::unique_ptr<storm::ir::expressions::BooleanConstantExpression>(new storm::ir::expressions::BooleanConstantExpression(*booleanUndefinedConstant.second));
}
for (auto const& integerUndefinedConstant : otherProgram.integerUndefinedConstantExpressions) {
this->integerUndefinedConstantExpressions[integerUndefinedConstant.first] = std::unique_ptr<storm::ir::expressions::IntegerConstantExpression>(new storm::ir::expressions::IntegerConstantExpression(*integerUndefinedConstant.second));
}
for (auto const& doubleUndefinedConstant : otherProgram.doubleUndefinedConstantExpressions) {
this->doubleUndefinedConstantExpressions[doubleUndefinedConstant.first] = std::unique_ptr<storm::ir::expressions::DoubleConstantExpression>(new storm::ir::expressions::DoubleConstantExpression(*doubleUndefinedConstant.second));
}
for (auto const& label : otherProgram.labels) {
this->labels[label.first] = label.second->clone();
}
}
Program& Program::operator=(Program const& otherProgram) {
if (this != &otherProgram) {
this->modelType = otherProgram.modelType;
this->globalBooleanVariables = otherProgram.globalBooleanVariables;
this->globalIntegerVariables = otherProgram.globalIntegerVariables;
this->globalBooleanVariableToIndexMap = otherProgram.globalBooleanVariableToIndexMap;
this->globalIntegerVariableToIndexMap = otherProgram.globalIntegerVariableToIndexMap;
this->modules = otherProgram.modules;
this->rewards = otherProgram.rewards;
this->actions = otherProgram.actions;
this->actionsToModuleIndexMap = otherProgram.actionsToModuleIndexMap;
this->variableToModuleIndexMap = otherProgram.variableToModuleIndexMap;
// Perform deep-copy of the maps.
for (auto const& booleanUndefinedConstant : otherProgram.booleanUndefinedConstantExpressions) {
this->booleanUndefinedConstantExpressions[booleanUndefinedConstant.first] = std::unique_ptr<storm::ir::expressions::BooleanConstantExpression>(new storm::ir::expressions::BooleanConstantExpression(*booleanUndefinedConstant.second));
}
for (auto const& integerUndefinedConstant : otherProgram.integerUndefinedConstantExpressions) {
this->integerUndefinedConstantExpressions[integerUndefinedConstant.first] = std::unique_ptr<storm::ir::expressions::IntegerConstantExpression>(new storm::ir::expressions::IntegerConstantExpression(*integerUndefinedConstant.second));
}
for (auto const& doubleUndefinedConstant : otherProgram.doubleUndefinedConstantExpressions) {
this->doubleUndefinedConstantExpressions[doubleUndefinedConstant.first] = std::unique_ptr<storm::ir::expressions::DoubleConstantExpression>(new storm::ir::expressions::DoubleConstantExpression(*doubleUndefinedConstant.second));
}
for (auto const& label : otherProgram.labels) {
this->labels[label.first] = label.second->clone();
}
}
return *this;
}
Program::ModelType Program::getModelType() const {
return modelType;
}
std::string Program::toString() const {
std::stringstream result;
switch (modelType) {
case UNDEFINED: result << "undefined"; break;
case DTMC: result << "dtmc"; break;
case CTMC: result << "ctmc"; break;
case MDP: result << "mdp"; break;
case CTMDP: result << "ctmdp"; break;
}
result << std::endl;
for (auto const& element : booleanUndefinedConstantExpressions) {
result << "const bool " << element.second->toString() << ";" << std::endl;
}
for (auto const& element : integerUndefinedConstantExpressions) {
result << "const int " << element.second->toString() << ";" << std::endl;
}
for (auto const& element : doubleUndefinedConstantExpressions) {
result << "const double " << element.second->toString() << ";" << std::endl;
}
result << std::endl;
for (auto const& element : globalBooleanVariables) {
result << "global " << element.toString() << std::endl;
}
for (auto const& element : globalIntegerVariables) {
result << "global " << element.toString() << std::endl;
}
result << std::endl;
for (auto const& module : modules) {
result << module.toString() << std::endl;
}
for (auto const& rewardModel : rewards) {
result << rewardModel.second.toString() << std::endl;
}
for (auto const& label : labels) {
result << "label \"" << label.first << "\" = " << label.second->toString() <<";" << std::endl;
}
return result.str();
}
storm::ir::BooleanVariable const& Program::getGlobalBooleanVariable(uint_fast64_t index) const {
return this->globalBooleanVariables[index];
}
storm::ir::IntegerVariable const& Program::getGlobalIntegerVariable(uint_fast64_t index) const {
return this->globalIntegerVariables[index];
}
uint_fast64_t Program::getNumberOfModules() const {
return this->modules.size();
}
storm::ir::Module const& Program::getModule(uint_fast64_t index) const {
return this->modules[index];
}
std::set<std::string> const& Program::getActions() const {
return this->actions;
}
std::set<uint_fast64_t> const& Program::getModulesByAction(std::string const& action) const {
auto actionModuleSetPair = this->actionsToModuleIndexMap.find(action);
if (actionModuleSetPair == this->actionsToModuleIndexMap.end()) {
LOG4CPLUS_ERROR(logger, "Action name '" << action << "' does not exist.");
throw storm::exceptions::OutOfRangeException() << "Action name '" << action << "' does not exist.";
}
return actionModuleSetPair->second;
}
uint_fast64_t Program::getModuleIndexForVariable(std::string const& variableName) const {
auto variableNameToModuleIndexPair = this->variableToModuleIndexMap.find(variableName);
if (variableNameToModuleIndexPair != this->variableToModuleIndexMap.end()) {
return variableNameToModuleIndexPair->second;
}
throw storm::exceptions::OutOfRangeException() << "Variable '" << variableName << "' does not exist.";
}
uint_fast64_t Program::getNumberOfGlobalBooleanVariables() const {
return this->globalBooleanVariables.size();
}
uint_fast64_t Program::getNumberOfGlobalIntegerVariables() const {
return this->globalIntegerVariables.size();
}
storm::ir::RewardModel const& Program::getRewardModel(std::string const& name) const {
auto nameRewardModelPair = this->rewards.find(name);
if (nameRewardModelPair == this->rewards.end()) {
LOG4CPLUS_ERROR(logger, "Reward model '" << name << "' does not exist.");
throw storm::exceptions::OutOfRangeException() << "Reward model '" << name << "' does not exist.";
}
return nameRewardModelPair->second;
}
std::map<std::string, std::unique_ptr<storm::ir::expressions::BaseExpression>> const& Program::getLabels() const {
return this->labels;
}
bool Program::hasUndefinedBooleanConstant(std::string const& constantName) const {
return this->booleanUndefinedConstantExpressions.find(constantName) != this->booleanUndefinedConstantExpressions.end();
}
std::unique_ptr<storm::ir::expressions::BooleanConstantExpression> const& Program::getUndefinedBooleanConstantExpression(std::string const& constantName) const {
auto constantExpressionPair = this->booleanUndefinedConstantExpressions.find(constantName);
if (constantExpressionPair != this->booleanUndefinedConstantExpressions.end()) {
return constantExpressionPair->second;
} else {
throw storm::exceptions::InvalidArgumentException() << "Unknown undefined boolean constant " << constantName << ".";
}
}
bool Program::hasUndefinedIntegerConstant(std::string const& constantName) const {
return this->integerUndefinedConstantExpressions.find(constantName) != this->integerUndefinedConstantExpressions.end();
}
std::unique_ptr<storm::ir::expressions::IntegerConstantExpression> const& Program::getUndefinedIntegerConstantExpression(std::string const& constantName) const {
auto constantExpressionPair = this->integerUndefinedConstantExpressions.find(constantName);
if (constantExpressionPair != this->integerUndefinedConstantExpressions.end()) {
return constantExpressionPair->second;
} else {
throw storm::exceptions::InvalidArgumentException() << "Unknown undefined integer constant " << constantName << ".";
}
}
bool Program::hasUndefinedDoubleConstant(std::string const& constantName) const {
return this->doubleUndefinedConstantExpressions.find(constantName) != this->doubleUndefinedConstantExpressions.end();
}
std::unique_ptr<storm::ir::expressions::DoubleConstantExpression> const& Program::getUndefinedDoubleConstantExpression(std::string const& constantName) const {
auto constantExpressionPair = this->doubleUndefinedConstantExpressions.find(constantName);
if (constantExpressionPair != this->doubleUndefinedConstantExpressions.end()) {
return constantExpressionPair->second;
} else {
throw storm::exceptions::InvalidArgumentException() << "Unknown undefined double constant " << constantName << ".";
}
}
std::map<std::string, std::unique_ptr<storm::ir::expressions::BooleanConstantExpression>> const& Program::getBooleanUndefinedConstantExpressionsMap() const {
return this->booleanUndefinedConstantExpressions;
}
std::map<std::string, std::unique_ptr<storm::ir::expressions::IntegerConstantExpression>> const& Program::getIntegerUndefinedConstantExpressionsMap() const {
return this->integerUndefinedConstantExpressions;
}
std::map<std::string, std::unique_ptr<storm::ir::expressions::DoubleConstantExpression>> const& Program::getDoubleUndefinedConstantExpressionsMap() const {
return this->doubleUndefinedConstantExpressions;
}
uint_fast64_t Program::getGlobalIndexOfBooleanVariable(std::string const& variableName) const {
return this->globalBooleanVariableToIndexMap.at(variableName);
}
uint_fast64_t Program::getGlobalIndexOfIntegerVariable(std::string const& variableName) const {
return this->globalIntegerVariableToIndexMap.at(variableName);
}
void Program::restrictCommands(boost::container::flat_set<uint_fast64_t> const& indexSet) {
for (auto& module : modules) {
module.restrictCommands(indexSet);
}
}
} // namespace ir
} // namepsace storm

318
src/ir/Program.h

@ -1,318 +0,0 @@
/*
* Program.h
*
* Created on: 04.01.2013
* Author: Christian Dehnert
*/
#ifndef STORM_IR_PROGRAM_H_
#define STORM_IR_PROGRAM_H_
#include <map>
#include <vector>
#include <memory>
#include <set>
#include <boost/container/flat_set.hpp>
#include "expressions/BaseExpression.h"
#include "expressions/BooleanConstantExpression.h"
#include "expressions/IntegerConstantExpression.h"
#include "expressions/DoubleConstantExpression.h"
#include "Module.h"
#include "RewardModel.h"
namespace storm {
namespace ir {
/*!
* A class representing a program.
*/
class Program {
public:
/*!
* An enum for the different model types.
*/
enum ModelType {UNDEFINED, DTMC, CTMC, MDP, CTMDP};
/*!
* Default constructor. Creates an empty program.
*/
Program();
/*!
* Creates a program with the given model type, undefined constants, modules, rewards and labels.
*
* @param modelType The type of the model that this program gives rise to.
* @param booleanUndefinedConstantExpressions A map of undefined boolean constants to their
* expression nodes.
* @param integerUndefinedConstantExpressions A map of undefined integer constants to their
* expression nodes.
* @param doubleUndefinedConstantExpressions A map of undefined double constants to their
* expression nodes.
* @param globalBooleanVariables A list of global boolean variables.
* @param globalIntegerVariables A list of global integer variables.
* @param globalBooleanVariableToIndexMap A mapping from global boolean variable names to the index in the
* list of global boolean variables.
* @param globalIntegerVariableToIndexMap A mapping from global integer variable names to the index in the
* list of global integer variables.
* @param modules The modules of the program.
* @param rewards The reward models of the program.
* @param labels The labels defined for this model.
*/
Program(ModelType modelType,
std::map<std::string, std::unique_ptr<storm::ir::expressions::BooleanConstantExpression>> const& booleanUndefinedConstantExpressions,
std::map<std::string, std::unique_ptr<storm::ir::expressions::IntegerConstantExpression>> const& integerUndefinedConstantExpressions,
std::map<std::string, std::unique_ptr<storm::ir::expressions::DoubleConstantExpression>> const& doubleUndefinedConstantExpressions,
std::vector<BooleanVariable> const& globalBooleanVariables,
std::vector<IntegerVariable> const& globalIntegerVariables,
std::map<std::string, uint_fast64_t> const& globalBooleanVariableToIndexMap,
std::map<std::string, uint_fast64_t> const& globalIntegerVariableToIndexMap,
std::vector<storm::ir::Module> const& modules,
std::map<std::string, storm::ir::RewardModel> const& rewards,
std::map<std::string, std::unique_ptr<storm::ir::expressions::BaseExpression>> const& labels);
/*!
* Performs a deep-copy of the given program.
*
* @param otherProgram The program to copy.
*/
Program(Program const& otherProgram);
/*!
* Performs a deep-copy of the given program and assigns it to the current one.
*
* @param otherProgram The program to assign.
*/
Program& operator=(Program const& otherProgram);
/*!
* Retrieves the number of modules in the program.
*
* @return The number of modules in the program.
*/
uint_fast64_t getNumberOfModules() const;
/*!
* Retrieves a reference to the module with the given index.
*
* @param index The index of the module to retrieve.
* @return The module with the given index.
*/
storm::ir::Module const& getModule(uint_fast64_t index) const;
/*!
* Retrieves the model type of the model.
*
* @return The type of the model.
*/
ModelType getModelType() const;
/*!
* Retrieves a string representation of this program.
*
* @return A string representation of this program.
*/
std::string toString() const;
/*!
* Retrieves a reference to the global boolean variable with the given index.
*
* @return A reference to the global boolean variable with the given index.
*/
storm::ir::BooleanVariable const& getGlobalBooleanVariable(uint_fast64_t index) const;
/*!
* Retrieves a reference to the global integer variable with the given index.
*
* @return A reference to the global integer variable with the given index.
*/
storm::ir::IntegerVariable const& getGlobalIntegerVariable(uint_fast64_t index) const;
/*!
* Retrieves the set of actions present in this module.
*
* @return The set of actions present in this module.
*/
std::set<std::string> const& getActions() const;
/*!
* Retrieves the indices of all modules within this program that contain commands that are labelled with the given
* action.
*
* @param action The name of the action the modules are supposed to possess.
* @return A set of indices of all matching modules.
*/
std::set<uint_fast64_t> const& getModulesByAction(std::string const& action) const;
/*!
* Retrieves the index of the module in which the given variable name was declared.
*
* @param variableName The name of the variable to search.
* @return The index of the module in which the given variable name was declared.
*/
uint_fast64_t getModuleIndexForVariable(std::string const& variableName) const;
/*!
* Retrieves the number of global boolean variables of the program.
*
* @return The number of global boolean variables of the program.
*/
uint_fast64_t getNumberOfGlobalBooleanVariables() const;
/*!
* Retrieves the number of global integer variables of the program.
*
* @return The number of global integer variables of the program.
*/
uint_fast64_t getNumberOfGlobalIntegerVariables() const;
/*!
* Retrieves the reward model with the given name.
*
* @param name The name of the reward model to return.
* @return The reward model with the given name.
*/
storm::ir::RewardModel const& getRewardModel(std::string const& name) const;
/*!
* Retrieves all labels that are defined by the probabilitic program.
*
* @return A set of labels that are defined in the program.
*/
std::map<std::string, std::unique_ptr<storm::ir::expressions::BaseExpression>> const& getLabels() const;
/*!
* Retrieves whether the given constant name is an undefined boolean constant of the program.
*
* @return True if the given constant name is an undefined boolean constant of the program.
*/
bool hasUndefinedBooleanConstant(std::string const& constantName) const;
/*!
* Retrieves the expression associated with the given undefined boolean constant.
*
* @param constantName The name of the undefined boolean constant for which to retrieve the expression.
* @return The expression associated with the given undefined boolean constant.
*/
std::unique_ptr<storm::ir::expressions::BooleanConstantExpression> const& getUndefinedBooleanConstantExpression(std::string const& constantName) const;
/*!
* Retrieves whether the given constant name is an undefined integer constant of the program.
*
* @return True if the given constant name is an undefined integer constant of the program.
*/
bool hasUndefinedIntegerConstant(std::string const& constantName) const;
/*!
* Retrieves the expression associated with the given undefined integer constant.
*
* @param constantName The name of the undefined integer constant for which to retrieve the expression.
* @return The expression associated with the given undefined integer constant.
*/
std::unique_ptr<storm::ir::expressions::IntegerConstantExpression> const& getUndefinedIntegerConstantExpression(std::string const& constantName) const;
/*!
* Retrieves whether the given constant name is an undefined double constant of the program.
*
* @return True if the given constant name is an undefined double constant of the program.
*/
bool hasUndefinedDoubleConstant(std::string const& constantName) const;
/*!
* Retrieves the expression associated with the given undefined double constant.
*
* @param constantName The name of the undefined double constant for which to retrieve the expression.
* @return The expression associated with the given undefined double constant.
*/
std::unique_ptr<storm::ir::expressions::DoubleConstantExpression> const& getUndefinedDoubleConstantExpression(std::string const& constantName) const;
/*!
* Retrieves the mapping of undefined boolean constant names to their expression objects.
*
* @return The mapping of undefined boolean constant names to their expression objects.
*/
std::map<std::string, std::unique_ptr<storm::ir::expressions::BooleanConstantExpression>> const& getBooleanUndefinedConstantExpressionsMap() const;
/*!
* Retrieves the mapping of undefined integer constant names to their expression objects.
*
* @return The mapping of undefined integer constant names to their expression objects.
*/
std::map<std::string, std::unique_ptr<storm::ir::expressions::IntegerConstantExpression>> const& getIntegerUndefinedConstantExpressionsMap() const;
/*!
* Retrieves the mapping of undefined double constant names to their expression objects.
*
* @return The mapping of undefined double constant names to their expression objects.
*/
std::map<std::string, std::unique_ptr<storm::ir::expressions::DoubleConstantExpression>> const& getDoubleUndefinedConstantExpressionsMap() const;
/*!
* Retrieves the global index of the given boolean variable.
*
* @param variableName The name of the boolean variable whose index to retrieve.
*/
uint_fast64_t getGlobalIndexOfBooleanVariable(std::string const& variableName) const;
/*!
* Retrieves the global index of the integer boolean variable.
*
* @param variableName The name of the integer variable whose index to retrieve.
*/
uint_fast64_t getGlobalIndexOfIntegerVariable(std::string const& variableName) const;
/*!
* Deletes all commands with indices not in the given set from the program.
*
* @param indexSet The set of indices for which to keep the commands.
*/
void restrictCommands(boost::container::flat_set<uint_fast64_t> const& indexSet);
private:
// The type of the model.
ModelType modelType;
// A map of undefined boolean constants to their expression nodes.
std::map<std::string, std::unique_ptr<storm::ir::expressions::BooleanConstantExpression>> booleanUndefinedConstantExpressions;
// A map of undefined integer constants to their expressions nodes.
std::map<std::string, std::unique_ptr<storm::ir::expressions::IntegerConstantExpression>> integerUndefinedConstantExpressions;
// A map of undefined double constants to their expressions nodes.
std::map<std::string, std::unique_ptr<storm::ir::expressions::DoubleConstantExpression>> doubleUndefinedConstantExpressions;
// A list of global boolean variables.
std::vector<BooleanVariable> globalBooleanVariables;
// A list of global integer variables.
std::vector<IntegerVariable> globalIntegerVariables;
// A mapping from global boolean variable names to their indices.
std::map<std::string, uint_fast64_t> globalBooleanVariableToIndexMap;
// A mapping from global integer variable names to their indices.
std::map<std::string, uint_fast64_t> globalIntegerVariableToIndexMap;
// The modules associated with the program.
std::vector<storm::ir::Module> modules;
// The reward models associated with the program.
std::map<std::string, storm::ir::RewardModel> rewards;
// The labels that are defined for this model.
std::map<std::string, std::unique_ptr<storm::ir::expressions::BaseExpression>> labels;
// The set of actions present in this program.
std::set<std::string> actions;
// A map of actions to the set of modules containing commands labelled with this action.
std::map<std::string, std::set<uint_fast64_t>> actionsToModuleIndexMap;
// A mapping from variable names to the modules in which they were declared.
std::map<std::string, uint_fast64_t> variableToModuleIndexMap;
};
} // namespace ir
} // namespace storm
#endif /* STORM_IR_PROGRAM_H_ */

53
src/ir/RewardModel.cpp

@ -1,53 +0,0 @@
/*
* RewardModel.cpp
*
* Created on: 12.01.2013
* Author: Christian Dehnert
*/
#include <sstream>
#include "RewardModel.h"
namespace storm {
namespace ir {
RewardModel::RewardModel() : rewardModelName(), stateRewards(), transitionRewards() {
// Nothing to do here.
}
RewardModel::RewardModel(std::string const& rewardModelName, std::vector<storm::ir::StateReward> const& stateRewards, std::vector<storm::ir::TransitionReward> const& transitionRewards) : rewardModelName(rewardModelName), stateRewards(stateRewards), transitionRewards(transitionRewards) {
// Nothing to do here.
}
std::string RewardModel::toString() const {
std::stringstream result;
result << "rewards \"" << rewardModelName << "\"" << std::endl;
for (auto const& reward : stateRewards) {
result << reward.toString() << std::endl;
}
for (auto const& reward : transitionRewards) {
result << reward.toString() << std::endl;
}
result << "endrewards" << std::endl;
return result.str();
}
bool RewardModel::hasStateRewards() const {
return this->stateRewards.size() > 0;
}
std::vector<storm::ir::StateReward> const& RewardModel::getStateRewards() const {
return this->stateRewards;
}
bool RewardModel::hasTransitionRewards() const {
return this->transitionRewards.size() > 0;
}
std::vector<storm::ir::TransitionReward> const& RewardModel::getTransitionRewards() const {
return this->transitionRewards;
}
} // namespace ir
} // namespace storm

88
src/ir/RewardModel.h

@ -1,88 +0,0 @@
/*
* RewardModel.h
*
* Created on: 04.01.2013
* Author: Christian Dehnert
*/
#ifndef STORM_IR_REWARDMODEL_H_
#define STORM_IR_REWARDMODEL_H_
#include <string>
#include <vector>
#include "StateReward.h"
#include "TransitionReward.h"
namespace storm {
namespace ir {
/*!
* A class representing a reward model.
*/
class RewardModel {
public:
/*!
* Default constructor. Creates an empty reward model.
*/
RewardModel();
/*!
* Creates a reward module with the given name, state and transition rewards.
*
* @param rewardModelName The name of the reward model.
* @param stateRewards A vector of state-based rewards.
* @param transitionRewards A vector of transition-based rewards.
*/
RewardModel(std::string const& rewardModelName, std::vector<storm::ir::StateReward> const& stateRewards, std::vector<storm::ir::TransitionReward> const& transitionRewards);
/*!
* Retrieves a string representation of this reward model.
*
* @return a string representation of this reward model.
*/
std::string toString() const;
/*!
* Check, if there are any state rewards.
*
* @return True, iff there are any state rewards.
*/
bool hasStateRewards() const;
/*!
* Retrieves a vector of state rewards associated with this reward model.
*
* @return A vector containing the state rewards associated with this reward model.
*/
std::vector<storm::ir::StateReward> const& getStateRewards() const;
/*!
* Check, if there are any transition rewards.
*
* @return True, iff there are any transition rewards associated with this reward model.
*/
bool hasTransitionRewards() const;
/*!
* Retrieves a vector of transition rewards associated with this reward model.
*
* @return A vector of transition rewards associated with this reward model.
*/
std::vector<storm::ir::TransitionReward> const& getTransitionRewards() const;
private:
// The name of the reward model.
std::string rewardModelName;
// The state-based rewards associated with this reward model.
std::vector<storm::ir::StateReward> stateRewards;
// The transition-based rewards associated with this reward model.
std::vector<storm::ir::TransitionReward> transitionRewards;
};
} // namespace ir
} // namespace storm
#endif /* STORM_IR_REWARDMODEL_H_ */

60
src/ir/StateReward.cpp

@ -1,60 +0,0 @@
/*
* StateReward.cpp
*
* Created on: 12.01.2013
* Author: Christian Dehnert
*/
#include <sstream>
#include "StateReward.h"
namespace storm {
namespace ir {
StateReward::StateReward() : statePredicate(), rewardValue() {
// Nothing to do here.
}
StateReward::StateReward(std::unique_ptr<storm::ir::expressions::BaseExpression>&& statePredicate, std::unique_ptr<storm::ir::expressions::BaseExpression>&& rewardValue) : statePredicate(std::move(statePredicate)), rewardValue(std::move(rewardValue)) {
// Nothing to do here.
}
StateReward::StateReward(StateReward const& otherReward) {
if (otherReward.statePredicate != nullptr) {
statePredicate = otherReward.statePredicate->clone();
}
if (otherReward.rewardValue != nullptr) {
rewardValue = otherReward.rewardValue->clone();
}
}
StateReward& StateReward::operator=(StateReward const& otherReward) {
if (this != & otherReward) {
if (otherReward.statePredicate != nullptr) {
this->statePredicate = otherReward.statePredicate->clone();
}
if (otherReward.rewardValue != nullptr) {
this->rewardValue = otherReward.rewardValue->clone();
}
}
return *this;
}
std::string StateReward::toString() const {
std::stringstream result;
result << "\t" << statePredicate->toString() << ": " << rewardValue->toString() << ";";
return result.str();
}
std::unique_ptr<storm::ir::expressions::BaseExpression> const& StateReward::getStatePredicate() const {
return this->statePredicate;
}
std::unique_ptr<storm::ir::expressions::BaseExpression> const& StateReward::getRewardValue() const {
return this->rewardValue;
}
} // namespace ir
} // namespace storm

85
src/ir/StateReward.h

@ -1,85 +0,0 @@
/*
* StateReward.h
*
* Created on: Jan 10, 2013
* Author: Christian Dehnert
*/
#ifndef STORM_IR_STATEREWARD_H_
#define STORM_IR_STATEREWARD_H_
#include <memory>
#include "expressions/BaseExpression.h"
namespace storm {
namespace ir {
/*!
* A class representing a state reward.
*/
class StateReward {
public:
/*!
* Default constructor. Creates an empty state reward.
*/
StateReward();
/*!
* Creates a state reward for the states satisfying the given expression with the value given
* by a second expression.
*
* @param statePredicate The predicate that states earning this state-based reward need to
* satisfy.
* @param rewardValue An expression specifying the values of the rewards to attach to the
* states.
*/
StateReward(std::unique_ptr<storm::ir::expressions::BaseExpression>&& statePredicate, std::unique_ptr<storm::ir::expressions::BaseExpression>&& rewardValue);
/*!
* Performs a deep-copy of the given reward.
*
* @param otherReward The reward to copy.
*/
StateReward(StateReward const& otherReward);
/*!
* Performs a deep-copy of the given reward and assigns it to the current one.
*
* @param otherReward The reward to assign.
*/
StateReward& operator=(StateReward const& otherReward);
/*!
* Retrieves a string representation of this state reward.
*
* @return A string representation of this state reward.
*/
std::string toString() const;
/*!
* Retrieves the state predicate that is associated with this state reward.
*
* @return The state predicate that is associated with this state reward.
*/
std::unique_ptr<storm::ir::expressions::BaseExpression> const& getStatePredicate() const;
/*!
* Retrieves the reward value associated with this state reward.
*
* @return The reward value associated with this state reward.
*/
std::unique_ptr<storm::ir::expressions::BaseExpression> const& getRewardValue() const;
private:
// The predicate that characterizes the states that obtain this reward.
std::unique_ptr<storm::ir::expressions::BaseExpression> statePredicate;
// The expression that specifies the value of the reward obtained.
std::unique_ptr<storm::ir::expressions::BaseExpression> rewardValue;
};
} // namespace ir
} // namespace storm
#endif /* STORM_IR_STATEREWARD_H_ */

65
src/ir/TransitionReward.cpp

@ -1,65 +0,0 @@
/*
* TransitionReward.cpp
*
* Created on: 12.01.2013
* Author: Christian Dehnert
*/
#include <sstream>
#include "TransitionReward.h"
namespace storm {
namespace ir {
TransitionReward::TransitionReward() : commandName(), statePredicate(), rewardValue() {
// Nothing to do here.
}
TransitionReward::TransitionReward(std::string const& commandName, std::unique_ptr<storm::ir::expressions::BaseExpression>&& statePredicate, std::unique_ptr<storm::ir::expressions::BaseExpression>&& rewardValue) : commandName(commandName), statePredicate(std::move(statePredicate)), rewardValue(std::move(rewardValue)) {
// Nothing to do here.
}
TransitionReward::TransitionReward(TransitionReward const& otherReward) : commandName(otherReward.commandName), statePredicate(), rewardValue() {
if (otherReward.statePredicate != nullptr) {
statePredicate = otherReward.statePredicate->clone();
}
if (otherReward.rewardValue != nullptr) {
rewardValue = otherReward.rewardValue->clone();
}
}
TransitionReward& TransitionReward::operator=(TransitionReward const& otherReward) {
if (this != &otherReward) {
this->commandName = otherReward.commandName;
if (otherReward.statePredicate != nullptr) {
this->statePredicate = otherReward.statePredicate->clone();
}
if (otherReward.rewardValue != nullptr) {
this->rewardValue = otherReward.rewardValue->clone();
}
}
return *this;
}
std::string TransitionReward::toString() const {
std::stringstream result;
result << "\t[" << commandName << "] " << statePredicate->toString() << ": " << rewardValue->toString() << ";";
return result.str();
}
std::string const& TransitionReward::getActionName() const {
return this->commandName;
}
std::unique_ptr<storm::ir::expressions::BaseExpression> const& TransitionReward::getStatePredicate() const {
return this->statePredicate;
}
std::unique_ptr<storm::ir::expressions::BaseExpression> const& TransitionReward::getRewardValue() const {
return this->rewardValue;
}
} // namespace ir
} // namespace storm

99
src/ir/TransitionReward.h

@ -1,99 +0,0 @@
/*
* TransitionReward.h
*
* Created on: Jan 10, 2013
* Author: Christian Dehnert
*/
#ifndef STORM_IR_TRANSITIONREWARD_H_
#define STORM_IR_TRANSITIONREWARD_H_
#include <memory>
#include "expressions/BaseExpression.h"
namespace storm {
namespace ir {
/*!
* A class representing a transition reward.
*/
class TransitionReward {
public:
/*!
* Default constructor. Creates an empty transition reward.
*/
TransitionReward();
/*!
* Creates a transition reward for the transitions with the given name emanating from states
* satisfying the given expression with the value given by another expression.
*
* @param commandName The name of the command that obtains this reward.
* @param statePredicate The predicate that needs to hold before taking a transition with the
* previously specified name in order to obtain the reward.
* @param rewardValue An expression specifying the values of the rewards to attach to the
* transitions.
*/
TransitionReward(std::string const& commandName, std::unique_ptr<storm::ir::expressions::BaseExpression>&& statePredicate, std::unique_ptr<storm::ir::expressions::BaseExpression>&& rewardValue);
/*!
* Performs a deep-copy of the given transition reward.
*
* @param otherReward The transition reward to copy.
*/
TransitionReward(TransitionReward const& otherReward);
/*!
* Performs a deep-copy of the given transition reward and assigns it to the current one.
*
* @param otherReward The reward to assign.
*/
TransitionReward& operator=(TransitionReward const& otherReward);
/*!
* Retrieves a string representation of this transition reward.
*
* @return A string representation of this transition reward.
*/
std::string toString() const;
/*!
* Retrieves the action name that is associated with this transition reward.
*
* @return The action name that is associated with this transition reward.
*/
std::string const& getActionName() const;
/*!
* Retrieves the state predicate that is associated with this state reward.
*
* @return The state predicate that is associated with this state reward.
*/
std::unique_ptr<storm::ir::expressions::BaseExpression> const& getStatePredicate() const;
/*!
* Retrieves the reward value associated with this state reward.
*
* @return The reward value associated with this state reward.
*/
std::unique_ptr<storm::ir::expressions::BaseExpression> const& getRewardValue() const;
private:
// The name of the command this transition-based reward is attached to.
std::string commandName;
// A predicate that needs to be satisfied by states for the reward to be obtained (by taking
// a corresponding command transition).
std::unique_ptr<storm::ir::expressions::BaseExpression> statePredicate;
// The expression specifying the value of the reward obtained along the transitions.
std::unique_ptr<storm::ir::expressions::BaseExpression> rewardValue;
};
} // namespace ir
} // namespace storm
#endif /* STORM_IR_TRANSITIONREWARD_H_ */

130
src/ir/Update.cpp

@ -1,130 +0,0 @@
/*
* Update.cpp
*
* Created on: 12.01.2013
* Author: Christian Dehnert
*/
#include <sstream>
#include "Update.h"
#include "src/parser/prismparser/VariableState.h"
#include "src/exceptions/OutOfRangeException.h"
namespace storm {
namespace ir {
Update::Update() : likelihoodExpression(), booleanAssignments(), integerAssignments(), globalIndex() {
// Nothing to do here.
}
Update::Update(uint_fast64_t globalIndex, std::unique_ptr<storm::ir::expressions::BaseExpression>&& likelihoodExpression, std::map<std::string, storm::ir::Assignment> const& booleanAssignments, std::map<std::string, storm::ir::Assignment> const& integerAssignments)
: likelihoodExpression(std::move(likelihoodExpression)), booleanAssignments(booleanAssignments), integerAssignments(integerAssignments), globalIndex(globalIndex) {
// Nothing to do here.
}
Update::Update(Update const& update, uint_fast64_t newGlobalIndex, std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState& variableState) : globalIndex(newGlobalIndex) {
for (auto const& variableAssignmentPair : update.booleanAssignments) {
if (renaming.count(variableAssignmentPair.first) > 0) {
this->booleanAssignments[renaming.at(variableAssignmentPair.first)] = Assignment(variableAssignmentPair.second, renaming, variableState);
} else {
this->booleanAssignments[variableAssignmentPair.first] = Assignment(variableAssignmentPair.second, renaming, variableState);
}
}
for (auto const& variableAssignmentPair : update.integerAssignments) {
if (renaming.count(variableAssignmentPair.first) > 0) {
this->integerAssignments[renaming.at(variableAssignmentPair.first)] = Assignment(variableAssignmentPair.second, renaming, variableState);
} else {
this->integerAssignments[variableAssignmentPair.first] = Assignment(variableAssignmentPair.second, renaming, variableState);
}
}
this->likelihoodExpression = update.likelihoodExpression->clone(renaming, variableState);
}
Update::Update(Update const& otherUpdate) : likelihoodExpression(), booleanAssignments(otherUpdate.booleanAssignments), integerAssignments(otherUpdate.integerAssignments), globalIndex(otherUpdate.globalIndex) {
if (otherUpdate.likelihoodExpression != nullptr) {
likelihoodExpression = otherUpdate.likelihoodExpression->clone();
}
}
Update& Update::operator=(Update const& otherUpdate) {
if (this != &otherUpdate) {
if (otherUpdate.likelihoodExpression != nullptr) {
this->likelihoodExpression = otherUpdate.likelihoodExpression->clone();
}
this->booleanAssignments = otherUpdate.booleanAssignments;
this->integerAssignments = otherUpdate.integerAssignments;
this->globalIndex = otherUpdate.globalIndex;
}
return *this;
}
std::unique_ptr<storm::ir::expressions::BaseExpression> const& Update::getLikelihoodExpression() const {
return likelihoodExpression;
}
uint_fast64_t Update::getNumberOfBooleanAssignments() const {
return booleanAssignments.size();
}
uint_fast64_t Update::getNumberOfIntegerAssignments() const {
return integerAssignments.size();
}
std::map<std::string, storm::ir::Assignment> const& Update::getBooleanAssignments() const {
return booleanAssignments;
}
std::map<std::string, storm::ir::Assignment> const& Update::getIntegerAssignments() const {
return integerAssignments;
}
storm::ir::Assignment const& Update::getBooleanAssignment(std::string const& variableName) const {
auto variableAssignmentPair = booleanAssignments.find(variableName);
if (variableAssignmentPair == booleanAssignments.end()) {
throw storm::exceptions::OutOfRangeException() << "Cannot find boolean assignment for variable '"
<< variableName << "' in update " << this->toString() << ".";
}
return variableAssignmentPair->second;
}
storm::ir::Assignment const& Update::getIntegerAssignment(std::string const& variableName) const {
auto variableAssignmentPair = integerAssignments.find(variableName);
if (variableAssignmentPair == integerAssignments.end()) {
throw storm::exceptions::OutOfRangeException() << "Cannot find integer assignment for variable '"
<< variableName << "' in update " << this->toString() << ".";
}
return variableAssignmentPair->second;
}
uint_fast64_t Update::getGlobalIndex() const {
return this->globalIndex;
}
std::string Update::toString() const {
std::stringstream result;
result << likelihoodExpression->toString() << " : ";
uint_fast64_t i = 0;
for (auto const& assignment : booleanAssignments) {
result << assignment.second.toString();
if (i < booleanAssignments.size() - 1 || integerAssignments.size() > 0) {
result << " & ";
}
++i;
}
i = 0;
for (auto const& assignment : integerAssignments) {
result << assignment.second.toString();
if (i < integerAssignments.size() - 1) {
result << " & ";
}
++i;
}
return result.str();
}
} // namespace ir
} // namespace storm

152
src/ir/Update.h

@ -1,152 +0,0 @@
/*
* Update.h
*
* Created on: 06.01.2013
* Author: Christian Dehnert
*/
#ifndef STORM_IR_UPDATE_H_
#define STORM_IR_UPDATE_H_
#include <map>
#include <memory>
#include "expressions/BaseExpression.h"
#include "Assignment.h"
namespace storm {
namespace parser {
namespace prism {
class VariableState;
} // namespace prismparser
} // namespace parser
namespace ir {
/*!
* A class representing an update of a command.
*/
class Update {
public:
/*!
* Default constructor. Creates an empty update.
*/
Update();
/*!
* Creates an update with the given expression specifying the likelihood and the mapping of
* variable to their assignments.
*
* @param globalIndex The global index of the update.
* @param likelihoodExpression An expression specifying the likelihood of this update.
* @param assignments A map of variable names to their assignments.
*/
Update(uint_fast64_t globalIndex, std::unique_ptr<storm::ir::expressions::BaseExpression>&& likelihoodExpression, std::map<std::string, storm::ir::Assignment> const& booleanAssignments, std::map<std::string, storm::ir::Assignment> const& integerAssignments);
/*!
* Creates a copy of the given update and performs the provided renaming.
*
* @param update The update that is to be copied.
* @param newGlobalIndex The global index of the resulting update.
* @param renaming A mapping from names that are to be renamed to the names they are to be
* replaced with.
* @param variableState An object knowing about the variables in the system.
*/
Update(Update const& update, uint_fast64_t newGlobalIndex, std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState& variableState);
/*!
* Peforms a deep-copy of the given update.
*
* @param otherUpdate The update to copy.
*/
Update(Update const& otherUpdate);
/*!
* Performs a deep-copy of the given update and assigns it to the current one.
*
* @param otherUpdate The update to assign.
*/
Update& operator=(Update const& otherUpdate);
/*!
* Retrieves the expression for the likelihood of this update.
*
* @return The expression for the likelihood of this update.
*/
std::unique_ptr<storm::ir::expressions::BaseExpression> const& getLikelihoodExpression() const;
/*!
* Retrieves the number of boolean assignments associated with this update.
*
* @return The number of boolean assignments associated with this update.
*/
uint_fast64_t getNumberOfBooleanAssignments() const;
/*!
* Retrieves the number of integer assignments associated with this update.
*
* @return The number of integer assignments associated with this update.
*/
uint_fast64_t getNumberOfIntegerAssignments() const;
/*!
* Retrieves a reference to the map of boolean variable names to their respective assignments.
*
* @return A reference to the map of boolean variable names to their respective assignments.
*/
std::map<std::string, storm::ir::Assignment> const& getBooleanAssignments() const;
/*!
* Retrieves a reference to the map of integer variable names to their respective assignments.
*
* @return A reference to the map of integer variable names to their respective assignments.
*/
std::map<std::string, storm::ir::Assignment> const& getIntegerAssignments() const;
/*!
* Retrieves a reference to the assignment for the boolean variable with the given name.
*
* @return A reference to the assignment for the boolean variable with the given name.
*/
storm::ir::Assignment const& getBooleanAssignment(std::string const& variableName) const;
/*!
* Retrieves a reference to the assignment for the integer variable with the given name.
*
* @return A reference to the assignment for the integer variable with the given name.
*/
storm::ir::Assignment const& getIntegerAssignment(std::string const& variableName) const;
/*!
* Retrieves the global index of the update, that is, a unique index over all modules.
*
* @return The global index of the update.
*/
uint_fast64_t getGlobalIndex() const;
/*!
* Retrieves a string representation of this update.
*
* @return A string representation of this update.
*/
std::string toString() const;
private:
// An expression specifying the likelihood of taking this update.
std::unique_ptr<storm::ir::expressions::BaseExpression> likelihoodExpression;
// A mapping of boolean variable names to their assignments in this update.
std::map<std::string, storm::ir::Assignment> booleanAssignments;
// A mapping of integer variable names to their assignments in this update.
std::map<std::string, storm::ir::Assignment> integerAssignments;
// The global index of the update.
uint_fast64_t globalIndex;
};
} // namespace ir
} // namespace storm
#endif /* STORM_IR_UPDATE_H_ */

74
src/ir/Variable.cpp

@ -1,74 +0,0 @@
/*
* Variable.cpp
*
* Created on: 12.01.2013
* Author: Christian Dehnert
*/
#include <sstream>
#include <map>
#include <iostream>
#include "Variable.h"
#include "src/parser/prismparser/VariableState.h"
namespace storm {
namespace ir {
Variable::Variable() : localIndex(0), globalIndex(0), variableName(), initialValue() {
// Nothing to do here.
}
Variable::Variable(uint_fast64_t localIndex, uint_fast64_t globalIndex, std::string const& variableName, std::unique_ptr<storm::ir::expressions::BaseExpression>&& initialValue)
: localIndex(localIndex), globalIndex(globalIndex), variableName(variableName), initialValue(std::move(initialValue)) {
// Nothing to do here.
}
Variable::Variable(Variable const& otherVariable) : localIndex(otherVariable.localIndex), globalIndex(otherVariable.globalIndex), variableName(otherVariable.variableName), initialValue() {
if (otherVariable.initialValue != nullptr) {
initialValue = otherVariable.initialValue->clone();
}
}
Variable::Variable(Variable const& var, std::string const& newName, uint_fast64_t newGlobalIndex, std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState)
: localIndex(var.getLocalIndex()), globalIndex(newGlobalIndex), variableName(newName), initialValue() {
if (var.initialValue != nullptr) {
this->initialValue = var.initialValue->clone(renaming, variableState);
}
}
Variable& Variable::operator=(Variable const& otherVariable) {
if (this != &otherVariable) {
this->localIndex = otherVariable.localIndex;
this->globalIndex = otherVariable.globalIndex;
this->variableName = otherVariable.variableName;
if (otherVariable.initialValue != nullptr) {
this->initialValue = otherVariable.initialValue->clone();
}
}
return *this;
}
std::string const& Variable::getName() const {
return variableName;
}
uint_fast64_t Variable::getGlobalIndex() const {
return globalIndex;
}
uint_fast64_t Variable::getLocalIndex() const {
return localIndex;
}
std::unique_ptr<storm::ir::expressions::BaseExpression> const& Variable::getInitialValue() const {
return initialValue;
}
void Variable::setInitialValue(std::unique_ptr<storm::ir::expressions::BaseExpression>&& initialValue) {
this->initialValue = std::move(initialValue);
}
} // namespace ir
} // namespace storm

124
src/ir/Variable.h

@ -1,124 +0,0 @@
/*
* Variable.h
*
* Created on: 06.01.2013
* Author: Christian Dehnert
*/
#ifndef STORM_IR_VARIABLE_H_
#define STORM_IR_VARIABLE_H_
#include <string>
#include <memory>
#include "expressions/BaseExpression.h"
namespace storm {
namespace parser {
namespace prism {
class VariableState;
} // namespace prismparser
} // namespace parser
namespace ir {
/*!
* A class representing a untyped variable.
*/
class Variable {
public:
/*!
* Default constructor. Creates an unnamed, untyped variable without initial value.
*/
Variable();
/*!
* Creates an untyped variable with the given name and initial value.
*
* @param localIndex A module-local index for the variable.
* @param globalIndex A globally unique (among the variables of equal type) index for the variable.
* @param variableName the name of the variable.
* @param initialValue the expression that defines the initial value of the variable.
*/
Variable(uint_fast64_t localIndex, uint_fast64_t globalIndex, std::string const& variableName, std::unique_ptr<storm::ir::expressions::BaseExpression>&& initialValue = nullptr);
/*!
* Creates a copy of the given variable and performs the provided renaming.
*
* @param oldVariable The variable to copy.
* @param newName New name of this variable.
* @param newGlobalIndex The new global index of the variable.
* @param renaming A mapping from names that are to be renamed to the names they are to be
* replaced with.
* @param variableState An object knowing about the variables in the system.
*/
Variable(Variable const& oldVariable, std::string const& newName, uint_fast64_t newGlobalIndex, std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState);
/*!
* Creates a deep-copy of the given variable.
*
* @param otherVariable The variable to copy.
*/
Variable(Variable const& otherVariable);
/*!
* Creates a deep-copy of the given variable and assigns it to the current one.
*/
Variable& operator=(Variable const& otherVariable);
/*!
* Retrieves the name of the variable.
*
* @return The name of the variable.
*/
std::string const& getName() const;
/*!
* Retrieves the global index of the variable, i.e. the index in all variables of equal type
* of all modules.
*
* @return The global index of the variable.
*/
uint_fast64_t getGlobalIndex() const;
/*!
* Retrieves the global index of the variable, i.e. the index in all variables of equal type in
* the same module.
*
* @return The local index of the variable.
*/
uint_fast64_t getLocalIndex() const;
/*!
* Retrieves the expression defining the initial value of the variable.
*
* @return The expression defining the initial value of the variable.
*/
std::unique_ptr<storm::ir::expressions::BaseExpression> const& getInitialValue() const;
/*!
* Sets the initial value to the given expression.
*
* @param initialValue The new initial value.
*/
void setInitialValue(std::unique_ptr<storm::ir::expressions::BaseExpression>&& initialValue);
private:
// A unique (among the variables of equal type) index for the variable inside its module.
uint_fast64_t localIndex;
// A unique (among the variables of equal type) index for the variable over all modules.
uint_fast64_t globalIndex;
// The name of the variable.
std::string variableName;
// The expression defining the initial value of the variable.
std::unique_ptr<storm::ir::expressions::BaseExpression> initialValue;
};
} // namespace ir
} // namespace storm
#endif /* STORM_IR_VARIABLE_H_ */

85
src/ir/expressions/BaseExpression.cpp

@ -1,85 +0,0 @@
/*
* BaseExpression.cpp
*
* Created on: 10.06.2013
* Author: Christian Dehnert
*/
#include "BaseExpression.h"
namespace storm {
namespace ir {
namespace expressions {
BaseExpression::BaseExpression() : type(undefined) {
// Nothing to do here.
}
BaseExpression::BaseExpression(ReturnType type) : type(type) {
// Nothing to do here.
}
BaseExpression::BaseExpression(BaseExpression const& baseExpression) : type(baseExpression.type) {
// Nothing to do here.
}
BaseExpression::~BaseExpression() {
// Nothing to do here.
}
std::unique_ptr<BaseExpression> BaseExpression::substitute(std::unique_ptr<BaseExpression>&& expression, std::map<std::string, std::reference_wrapper<BaseExpression>> const& substitution) {
BaseExpression* result = expression->performSubstitution(substitution);
if (result != expression.get()) {
return std::unique_ptr<BaseExpression>(result);
} else {
return std::move(expression);
}
}
int_fast64_t BaseExpression::getValueAsInt(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const {
if (type != int_) {
throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression of type '"
<< this->getTypeName() << "' as 'int'.";
}
throw storm::exceptions::NotImplementedException() << "Cannot evaluate expression of type '"
<< this->getTypeName() << " because evaluation implementation is missing.";
}
bool BaseExpression::getValueAsBool(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const {
if (type != bool_) {
throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression of type '"
<< this->getTypeName() << "' as 'bool'.";
}
throw storm::exceptions::NotImplementedException() << "Cannot evaluate expression of type '"
<< this->getTypeName() << " because evaluation implementation is missing.";
}
double BaseExpression::getValueAsDouble(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const {
if (type != double_ && type != int_) {
throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression of type '"
<< this->getTypeName() << "' as 'double'.";
}
throw storm::exceptions::NotImplementedException() << "Cannot evaluate expression of type '"
<< this->getTypeName() << " because evaluation implementation is missing.";
}
std::string BaseExpression::getTypeName() const {
switch(type) {
case bool_: return std::string("bool");
case int_: return std::string("int");
case double_: return std::string("double");
default: return std::string("undefined");
}
}
BaseExpression::ReturnType BaseExpression::getType() const {
return type;
}
BaseExpression* BaseExpression::performSubstitution(std::map<std::string, std::reference_wrapper<BaseExpression>> const& substitution) {
return this;
}
} // namespace expressions
} // namespace ir
} // namespace storm

172
src/ir/expressions/BaseExpression.h

@ -1,172 +0,0 @@
/*
* BaseExpression.h
*
* Created on: 03.01.2013
* Author: Christian Dehnert
*/
#ifndef STORM_IR_EXPRESSIONS_BASEEXPRESSION_H_
#define STORM_IR_EXPRESSIONS_BASEEXPRESSION_H_
#include <string>
#include <vector>
#include <map>
#include <memory>
#include "src/exceptions/ExpressionEvaluationException.h"
#include "src/exceptions/NotImplementedException.h"
#include "ExpressionVisitor.h"
namespace storm {
// Forward-declare VariableState.
namespace parser {
namespace prism {
class VariableState;
} // namespace prismparser
} // namespace parser
namespace ir {
namespace expressions {
/*!
* The base class for all expressions.
*/
class BaseExpression {
public:
// Forward declare friend classes to allow access to substitute.
friend class BinaryExpression;
friend class UnaryExpression;
/*!
* Each node in an expression tree has a uniquely defined type from this enum.
*/
enum ReturnType {undefined, bool_, int_, double_};
/*!
* Creates an expression with undefined type.
*/
BaseExpression();
/*!
* Creates an expression with the given type.
*
* @param type The type of the expression.
*/
BaseExpression(ReturnType type);
/*!
* Copy-constructs from the given expression.
*
* @param baseExpression The expression to copy.
*/
BaseExpression(BaseExpression const& baseExpression);
/*!
* Destructor.
*/
virtual ~BaseExpression();
/*!
* Performes a deep-copy of the expression.
*
* @return A deep-copy of the expression.
*/
virtual std::unique_ptr<BaseExpression> clone() const = 0;
/*!
* Copies the expression tree underneath (including) the current node and performs the provided renaming.
*
* @param renaming A mapping from identifier names to strings they are to be replaced with.
* @param variableState An object knowing about the global variable state.
*/
virtual std::unique_ptr<BaseExpression> clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const = 0;
/*!
* Performs the given substitution by replacing each variable in the given expression that is a key in
* the map by a copy of the mapped expression.
*
* @param expression The expression in which to perform the substitution.
* @param substitution The substitution to apply.
* @return The resulting expression.
*/
static std::unique_ptr<BaseExpression> substitute(std::unique_ptr<BaseExpression>&& expression, std::map<std::string, std::reference_wrapper<BaseExpression>> const& substitution);
/*!
* Retrieves the value of the expression as an integer given the provided variable valuation.
*
* @param variableValues The variable valuation under which to evaluate the expression. If set to null,
* constant expressions can be evaluated without variable values. However, upon encountering a variable
* expression an expression is thrown, because evaluation is impossible without the variable values then.
* @return The value of the expression as an integer.
*/
virtual int_fast64_t getValueAsInt(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const;
/*!
* Retrieves the value of the expression as a boolean given the provided variable valuation.
*
* @param variableValues The variable valuation under which to evaluate the expression. If set to null,
* constant expressions can be evaluated without variable values. However, upon encountering a variable
* expression an expression is thrown, because evaluation is impossible without the variable values then.
* @return The value of the expression as a boolean.
*/
virtual bool getValueAsBool(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const;
/*!
* Retrieves the value of the expression as a double given the provided variable valuation.
*
* @param variableValues The variable valuation under which to evaluate the expression. If set to null,
* constant expressions can be evaluated without variable values. However, upon encountering a variable
* expression an expression is thrown, because evaluation is impossible without the variable values then.
* @return The value of the expression as a double.
*/
virtual double getValueAsDouble(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const;
/*!
* Acceptor method for visitor pattern.
*
* @param visitor The visitor that is supposed to visit each node of the expression tree.
*/
virtual void accept(ExpressionVisitor* visitor) = 0;
/*!
* Retrieves a string representation of the expression tree underneath the current node.
*
* @return A string representation of the expression tree underneath the current node.
*/
virtual std::string toString() const = 0;
/*!
* Retrieves a string representation of the type to which this node evaluates.
*
* @return A string representation of the type to which this node evaluates.
*/
std::string getTypeName() const;
/*!
* Retrieves the type to which the node evaluates.
*
* @return The type to which the node evaluates.
*/
ReturnType getType() const;
protected:
/*!
* Performs the given substitution on the expression, i.e. replaces all variables whose names are keys
* of the map by a copy of the expression they are associated with in the map. This is intended as a helper
* function for substitute.
*
* @param substitution The substitution to perform
*/
virtual BaseExpression* performSubstitution(std::map<std::string, std::reference_wrapper<BaseExpression>> const& substitution);
private:
// The type to which this node evaluates.
ReturnType type;
};
} // namespace expressions
} // namespace ir
} // namespace storm
#endif /* STORM_IR_EXPRESSIONS_BASEEXPRESSION_H_ */

67
src/ir/expressions/BinaryBooleanFunctionExpression.cpp

@ -1,67 +0,0 @@
/*
* BinaryBooleanFunctionExpression.cpp
*
* Created on: 10.06.2013
* Author: Christian Dehnert
*/
#include <sstream>
#include "BinaryBooleanFunctionExpression.h"
namespace storm {
namespace ir {
namespace expressions {
BinaryBooleanFunctionExpression::BinaryBooleanFunctionExpression(std::unique_ptr<BaseExpression>&& left, std::unique_ptr<BaseExpression>&& right, FunctionType functionType)
: BinaryExpression(bool_, std::move(left), std::move(right)), functionType(functionType) {
// Nothing to do here.
}
BinaryBooleanFunctionExpression::BinaryBooleanFunctionExpression(BinaryBooleanFunctionExpression const& binaryBooleanFunctionExpression)
: BinaryExpression(binaryBooleanFunctionExpression), functionType(binaryBooleanFunctionExpression.functionType) {
// Nothing to do here.
}
std::unique_ptr<BaseExpression> BinaryBooleanFunctionExpression::clone() const {
return std::unique_ptr<BaseExpression>(new BinaryBooleanFunctionExpression(this->getLeft()->clone(), this->getRight()->clone(), functionType));
}
std::unique_ptr<BaseExpression> BinaryBooleanFunctionExpression::clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const {
return std::unique_ptr<BaseExpression>(new BinaryBooleanFunctionExpression(this->getLeft()->clone(renaming, variableState), this->getRight()->clone(renaming, variableState), this->functionType));
}
bool BinaryBooleanFunctionExpression::getValueAsBool(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const {
bool resultLeft = this->getLeft()->getValueAsBool(variableValues);
bool resultRight = this->getRight()->getValueAsBool(variableValues);
switch(functionType) {
case AND: return resultLeft & resultRight; break;
case OR: return resultLeft | resultRight; break;
default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: "
<< "Unknown boolean binary operator: '" << functionType << "'.";
}
}
BinaryBooleanFunctionExpression::FunctionType BinaryBooleanFunctionExpression::getFunctionType() const {
return functionType;
}
void BinaryBooleanFunctionExpression::accept(ExpressionVisitor* visitor) {
visitor->visit(this);
}
std::string BinaryBooleanFunctionExpression::toString() const {
std::stringstream result;
result << "(" << this->getLeft()->toString();
switch (functionType) {
case AND: result << " & "; break;
case OR: result << " | "; break;
}
result << this->getRight()->toString() << ")";
return result.str();
}
} // namespace expressions
} // namespace ir
} // namespace storm

69
src/ir/expressions/BinaryBooleanFunctionExpression.h

@ -1,69 +0,0 @@
/*
* BinaryBooleanFunctionExpression.h
*
* Created on: 03.01.2013
* Author: Christian Dehnert
*/
#ifndef STORM_IR_EXPRESSIONS_BINARYBOOLEANFUNCTIONEXPRESSION_H_
#define STORM_IR_EXPRESSIONS_BINARYBOOLEANFUNCTIONEXPRESSION_H_
#include "BinaryExpression.h"
namespace storm {
namespace ir {
namespace expressions {
/*!
* A class representing a binary function expression of boolean type.
*/
class BinaryBooleanFunctionExpression : public BinaryExpression {
public:
/*!
* An enum type specifying the different functions applicable.
*/
enum FunctionType {AND, OR};
/*!
* Creates a binary boolean function expression tree node with the given children and function type.
*
* @param left The left child of the node.
* @param right The right child of the node.
* @param functionType The operator that is to be applied to the two children.
*/
BinaryBooleanFunctionExpression(std::unique_ptr<BaseExpression>&& left, std::unique_ptr<BaseExpression>&& right, FunctionType functionType);
/*!
* Copy-constructs from the given expression.
*
* @param binaryBooleanFunctionExpression The expression to copy.
*/
BinaryBooleanFunctionExpression(BinaryBooleanFunctionExpression const& binaryBooleanFunctionExpression);
virtual std::unique_ptr<BaseExpression> clone() const override;
virtual std::unique_ptr<BaseExpression> clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const override;
virtual bool getValueAsBool(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const override;
/*!
* Retrieves the operator that is associated with this node.
*
* @param The operator that is associated with this node.
*/
FunctionType getFunctionType() const;
virtual void accept(ExpressionVisitor* visitor) override;
virtual std::string toString() const override;
private:
// The operator that is associated with this node.
FunctionType functionType;
};
} // namespace expressions
} // namespace ir
} // namespace storm
#endif /* STORM_IR_EXPRESSIONS_BINARYBOOLEANFUNCTIONEXPRESSION_H_ */

52
src/ir/expressions/BinaryExpression.cpp

@ -1,52 +0,0 @@
/*
* BinaryBooleanFunctionExpression.cpp
*
* Created on: 10.06.2013
* Author: Christian Dehnert
*/
#include "BinaryExpression.h"
namespace storm {
namespace ir {
namespace expressions {
BinaryExpression::BinaryExpression(ReturnType type, std::unique_ptr<BaseExpression>&& left, std::unique_ptr<BaseExpression>&& right)
: BaseExpression(type), left(std::move(left)), right(std::move(right)) {
// Nothing to do here.
}
BinaryExpression::BinaryExpression(BinaryExpression const& binaryExpression) : BaseExpression(binaryExpression.getType()), left(binaryExpression.left->clone()), right(binaryExpression.right->clone()) {
// Nothing to do here.
}
BaseExpression* BinaryExpression::performSubstitution(std::map<std::string, std::reference_wrapper<BaseExpression>> const& substitution) {
// Get the new left successor recursively.
BaseExpression* newLeftSuccessor = left->performSubstitution(substitution);
// If the left successor changed, we need to update it. If it did not change, this must not be executed,
// because assigning to the unique_ptr will destroy the current successor immediately.
if (newLeftSuccessor != left.get()) {
left = std::unique_ptr<BaseExpression>(newLeftSuccessor);
}
// Now do the same thing for the right successor.
BaseExpression* newRightSuccessor = right->performSubstitution(substitution);
if (newRightSuccessor != right.get()) {
right = std::unique_ptr<BaseExpression>(newRightSuccessor);
}
return this;
}
std::unique_ptr<BaseExpression> const& BinaryExpression::getLeft() const {
return left;
}
std::unique_ptr<BaseExpression> const& BinaryExpression::getRight() const {
return right;
}
} // namespace expressions
} // namespace ir
} // namespace storm

66
src/ir/expressions/BinaryExpression.h

@ -1,66 +0,0 @@
/*
* BinaryExpression.h
*
* Created on: 27.01.2013
* Author: Christian Dehnert
*/
#ifndef STORM_IR_EXPRESSIONS_BINARYEXPRESSION_H_
#define STORM_IR_EXPRESSIONS_BINARYEXPRESSION_H_
#include "src/ir/expressions/BaseExpression.h"
namespace storm {
namespace ir {
namespace expressions {
/*!
* A class representing a generic binary expression.
*/
class BinaryExpression : public BaseExpression {
public:
/*!
* Constructs a binary expression with the given type and children.
* @param type The type of the binary expression.
* @param left The left child of the binary expression.
* @param right The right child of the binary expression.
*/
BinaryExpression(ReturnType type, std::unique_ptr<BaseExpression>&& left, std::unique_ptr<BaseExpression>&& right);
/*!
* Copy-constructs from the given expression.
*
* @param binaryExpression The expression to copy.
*/
BinaryExpression(BinaryExpression const& binaryExpression);
/*!
* Retrieves the left child of the expression node.
*
* @return The left child of the expression node.
*/
std::unique_ptr<BaseExpression> const& getLeft() const;
/*!
* Retrieves the right child of the expression node.
*
* @return The right child of the expression node.
*/
std::unique_ptr<BaseExpression> const& getRight() const;
protected:
virtual BaseExpression* performSubstitution(std::map<std::string, std::reference_wrapper<BaseExpression>> const& substitution) override;
private:
// The left child of the binary expression.
std::unique_ptr<BaseExpression> left;
// The right child of the binary expression.
std::unique_ptr<BaseExpression> right;
};
} // namespace expressions
} // namespace ir
} // namespace storm
#endif /* STORM_IR_EXPRESSIONS_BINARYEXPRESSION_H_ */

96
src/ir/expressions/BinaryNumericalFunctionExpression.cpp

@ -1,96 +0,0 @@
/*
* BinaryBooleanFunctionExpression.cpp
*
* Created on: 10.06.2013
* Author: Christian Dehnert
*/
#include <sstream>
#include <algorithm>
#include "BinaryNumericalFunctionExpression.h"
namespace storm {
namespace ir {
namespace expressions {
BinaryNumericalFunctionExpression::BinaryNumericalFunctionExpression(ReturnType type, std::unique_ptr<BaseExpression>&& left, std::unique_ptr<BaseExpression>&& right, FunctionType functionType)
: BinaryExpression(type, std::move(left), std::move(right)), functionType(functionType) {
// Nothing to do here.
}
BinaryNumericalFunctionExpression::BinaryNumericalFunctionExpression(BinaryNumericalFunctionExpression const& binaryNumericalFunctionExpression)
: BinaryExpression(binaryNumericalFunctionExpression), functionType(binaryNumericalFunctionExpression.functionType) {
// Nothing to do here.
}
std::unique_ptr<BaseExpression> BinaryNumericalFunctionExpression::clone() const {
return std::unique_ptr<BaseExpression>(new BinaryNumericalFunctionExpression(this->getType(), this->getLeft()->clone(), this->getRight()->clone(), functionType));
}
std::unique_ptr<BaseExpression> BinaryNumericalFunctionExpression::clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const {
return std::unique_ptr<BaseExpression>(new BinaryNumericalFunctionExpression(this->getType(), this->getLeft()->clone(renaming, variableState), this->getRight()->clone(renaming, variableState), this->functionType));
}
BinaryNumericalFunctionExpression::FunctionType BinaryNumericalFunctionExpression::getFunctionType() const {
return functionType;
}
int_fast64_t BinaryNumericalFunctionExpression::getValueAsInt(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const {
if (this->getType() != int_) {
BaseExpression::getValueAsInt(variableValues);
}
int_fast64_t resultLeft = this->getLeft()->getValueAsInt(variableValues);
int_fast64_t resultRight = this->getRight()->getValueAsInt(variableValues);
switch(functionType) {
case PLUS: return resultLeft + resultRight; break;
case MINUS: return resultLeft - resultRight; break;
case TIMES: return resultLeft * resultRight; break;
case DIVIDE: return resultLeft / resultRight; break;
case MIN: return std::min(resultLeft, resultRight); break;
case MAX: return std::max(resultLeft, resultRight); break;
default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: "
<< "Unknown numeric binary operator: '" << functionType << "'.";
}
}
double BinaryNumericalFunctionExpression::getValueAsDouble(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const {
if (this->getType() != double_ && this->getType() != int_) {
BaseExpression::getValueAsDouble(variableValues);
}
double resultLeft = this->getLeft()->getValueAsDouble(variableValues);
double resultRight = this->getRight()->getValueAsDouble(variableValues);
switch(functionType) {
case PLUS: return resultLeft + resultRight; break;
case MINUS: return resultLeft - resultRight; break;
case TIMES: return resultLeft * resultRight; break;
case DIVIDE: return resultLeft / resultRight; break;
case MIN: return std::min(resultLeft, resultRight); break;
case MAX: return std::max(resultLeft, resultRight); break;
default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: "
<< "Unknown numeric binary operator: '" << functionType << "'.";
}
}
void BinaryNumericalFunctionExpression::accept(ExpressionVisitor* visitor) {
visitor->visit(this);
}
std::string BinaryNumericalFunctionExpression::toString() const {
std::stringstream result;
switch (functionType) {
case PLUS: result << "(" << this->getLeft()->toString() << " + " << this->getRight()->toString() << ")"; break;
case MINUS: result << "(" << this->getLeft()->toString() << " - " << this->getRight()->toString() << ")"; break;
case TIMES: result << "(" << this->getLeft()->toString() << " * " << this->getRight()->toString() << ")"; break;
case DIVIDE: result << "(" << this->getLeft()->toString() << " / " << this->getRight()->toString() << ")"; break;
case MIN: result << "min(" << this->getLeft()->toString() << ", " << this->getRight()->toString() << ")"; break;
case MAX: result << "max(" << this->getLeft()->toString() << ", " << this->getRight()->toString() << ")"; break;
}
return result.str();
}
} // namespace expressions
} // namespace ir
} // namespace storm

72
src/ir/expressions/BinaryNumericalFunctionExpression.h

@ -1,72 +0,0 @@
/*
* BinaryFunctionExpression.h
*
* Created on: 03.01.2013
* Author: Christian Dehnert
*/
#ifndef STORM_IR_EXPRESSIONS_BINARYFUNCTIONEXPRESSION_H_
#define STORM_IR_EXPRESSIONS_BINARYFUNCTIONEXPRESSION_H_
#include "src/ir/expressions/BinaryExpression.h"
namespace storm {
namespace ir {
namespace expressions {
/*!
* A class representing a binary function expression of numerical type.
*/
class BinaryNumericalFunctionExpression : public BinaryExpression {
public:
/*!
* An enum type specifying the different functions applicable.
*/
enum FunctionType {PLUS, MINUS, TIMES, DIVIDE, MIN, MAX};
/*!
* Creates a binary numerical function expression with the given type, children and function type.
*
* @param type The type of the expression tree node.
* @param left The left child of the expression tree node.
* @param right The right child of the expression tree node.
* @param functionType The function that is applied to the children of this node.
*/
BinaryNumericalFunctionExpression(ReturnType type, std::unique_ptr<BaseExpression>&& left, std::unique_ptr<BaseExpression>&& right, FunctionType functionType);
/*!
* Performs a deep-copy of the given expression.
*
* @param binaryNumericalFunctionExpression The expression to copy.
*/
BinaryNumericalFunctionExpression(BinaryNumericalFunctionExpression const& binaryNumericalFunctionExpression);
virtual std::unique_ptr<BaseExpression> clone() const override;
virtual std::unique_ptr<BaseExpression> clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const override;
/*!
* Retrieves the operator that is associated with this node.
*
* @param The operator that is associated with this node.
*/
FunctionType getFunctionType() const;
virtual int_fast64_t getValueAsInt(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const override;
virtual double getValueAsDouble(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const override;
virtual void accept(ExpressionVisitor* visitor) override;
virtual std::string toString() const override;
private:
// The operator that is associated with this node.
FunctionType functionType;
};
} // namespace expressions
} // namespace ir
} // namespace storm
#endif /* STORM_IR_EXPRESSIONS_BINARYFUNCTIONEXPRESSION_H_ */

75
src/ir/expressions/BinaryRelationExpression.cpp

@ -1,75 +0,0 @@
/*
* BinaryBooleanFunctionExpression.cpp
*
* Created on: 10.06.2013
* Author: Christian Dehnert
*/
#include <sstream>
#include "BinaryRelationExpression.h"
namespace storm {
namespace ir {
namespace expressions {
BinaryRelationExpression::BinaryRelationExpression(std::unique_ptr<BaseExpression>&& left, std::unique_ptr<BaseExpression>&& right, RelationType relationType)
: BinaryExpression(bool_, std::move(left), std::move(right)), relationType(relationType) {
// Nothing to do here.
}
BinaryRelationExpression::BinaryRelationExpression(BinaryRelationExpression const& binaryRelationExpression)
: BinaryExpression(binaryRelationExpression), relationType(binaryRelationExpression.relationType) {
// Nothing to do here.
}
std::unique_ptr<BaseExpression> BinaryRelationExpression::clone() const {
return std::unique_ptr<BaseExpression>(new BinaryRelationExpression(this->getLeft()->clone(), this->getRight()->clone(), relationType));
}
std::unique_ptr<BaseExpression> BinaryRelationExpression::clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const {
return std::unique_ptr<BaseExpression>(new BinaryRelationExpression(this->getLeft()->clone(renaming, variableState), this->getRight()->clone(renaming, variableState), this->relationType));
}
bool BinaryRelationExpression::getValueAsBool(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const {
int_fast64_t resultLeft = this->getLeft()->getValueAsInt(variableValues);
int_fast64_t resultRight = this->getRight()->getValueAsInt(variableValues);
switch(relationType) {
case EQUAL: return resultLeft == resultRight; break;
case NOT_EQUAL: return resultLeft != resultRight; break;
case LESS: return resultLeft < resultRight; break;
case LESS_OR_EQUAL: return resultLeft <= resultRight; break;
case GREATER: return resultLeft > resultRight; break;
case GREATER_OR_EQUAL: return resultLeft >= resultRight; break;
default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: "
<< "Unknown boolean binary relation: '" << relationType << "'.";
}
}
BinaryRelationExpression::RelationType BinaryRelationExpression::getRelationType() const {
return relationType;
}
void BinaryRelationExpression::accept(ExpressionVisitor* visitor) {
visitor->visit(this);
}
std::string BinaryRelationExpression::toString() const {
std::stringstream result;
result << "(" << this->getLeft()->toString();
switch (relationType) {
case EQUAL: result << " = "; break;
case NOT_EQUAL: result << " != "; break;
case LESS: result << " < "; break;
case LESS_OR_EQUAL: result << " <= "; break;
case GREATER: result << " > "; break;
case GREATER_OR_EQUAL: result << " >= "; break;
}
result << this->getRight()->toString() << ")";
return result.str();
}
} // namespace expressions
} // namespace ir
} // namespace storm

69
src/ir/expressions/BinaryRelationExpression.h

@ -1,69 +0,0 @@
/*
* BinaryRelationExpression.h
*
* Created on: 03.01.2013
* Author: Christian Dehnert
*/
#ifndef STORM_IR_EXPRESSIONS_BINARYRELATIONEXPRESSION_H_
#define STORM_IR_EXPRESSIONS_BINARYRELATIONEXPRESSION_H_
#include "src/ir/expressions/BinaryExpression.h"
namespace storm {
namespace ir {
namespace expressions {
/*!
* A class representing a binary relation expression of boolean type.
*/
class BinaryRelationExpression : public BinaryExpression {
public:
/*!
* An enum type specifying the different relations applicable.
*/
enum RelationType {EQUAL, NOT_EQUAL, LESS, LESS_OR_EQUAL, GREATER, GREATER_OR_EQUAL};
/*!
* Creates a binary relation expression tree node with the given children and relation type.
*
* @param left The left child of the binary expression.
* @param right The right child of the binary expression.
* @param relationType The type of the relation associated with this node.
*/
BinaryRelationExpression(std::unique_ptr<BaseExpression>&& left, std::unique_ptr<BaseExpression>&& right, RelationType relationType);
/*!
* Copy-constructs from the given expression.
*
* @param binaryRelationExpression The expression to copy.
*/
BinaryRelationExpression(BinaryRelationExpression const& binaryRelationExpression);
virtual std::unique_ptr<BaseExpression> clone() const override;
virtual std::unique_ptr<BaseExpression> clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const override;
virtual bool getValueAsBool(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const override;
/*!
* Retrieves the relation that is associated with this node.
*
* @param The relation that is associated with this node.
*/
RelationType getRelationType() const;
virtual void accept(ExpressionVisitor* visitor) override;
virtual std::string toString() const override;
private:
// The relation operator associated with this node.
RelationType relationType;
};
} // namespace expressions
} // namespace ir
} // namespace storm
#endif /* STORM_IR_EXPRESSIONS_BINARYRELATIONEXPRESSION_H_ */

45
src/ir/expressions/BooleanConstantExpression.cpp

@ -1,45 +0,0 @@
/*
* BooleanConstantExpression.cpp
*
* Created on: 10.06.2013
* Author: Christian Dehnert
*/
#include "BooleanConstantExpression.h"
namespace storm {
namespace ir {
namespace expressions {
BooleanConstantExpression::BooleanConstantExpression(std::string const& constantName) : ConstantExpression<bool>(bool_, constantName) {
// Nothing to do here.
}
BooleanConstantExpression::BooleanConstantExpression(BooleanConstantExpression const& booleanConstantExpression) : ConstantExpression(booleanConstantExpression) {
// Nothing to do here.
}
std::unique_ptr<BaseExpression> BooleanConstantExpression::clone() const {
return std::unique_ptr<BaseExpression>(new BooleanConstantExpression(*this));
}
std::unique_ptr<BaseExpression> BooleanConstantExpression::clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const {
return std::unique_ptr<BaseExpression>(new BooleanConstantExpression(*this));
}
bool BooleanConstantExpression::getValueAsBool(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const {
if (!this->isDefined()) {
throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: "
<< "Boolean constant '" << this->getConstantName() << "' is undefined.";
} else {
return this->getValue();
}
}
void BooleanConstantExpression::accept(ExpressionVisitor* visitor) {
visitor->visit(this);
}
} // namespace expressions
} // namespace ir
} // namespace storm

49
src/ir/expressions/BooleanConstantExpression.h

@ -1,49 +0,0 @@
/*
* BooleanConstantExpression.h
*
* Created on: 04.01.2013
* Author: Christian Dehnert
*/
#ifndef STORM_IR_EXPRESSIONS_BOOLEANCONSTANTEXPRESSION_H_
#define STORM_IR_EXPRESSIONS_BOOLEANCONSTANTEXPRESSION_H_
#include "ConstantExpression.h"
namespace storm {
namespace ir {
namespace expressions {
/*!
* A class representing a boolean constant expression.
*/
class BooleanConstantExpression : public ConstantExpression<bool> {
public:
/*!
* Creates a boolean constant expression with the given constant name.
*
* @param constantName The name of the constant to use.
*/
BooleanConstantExpression(std::string const& constantName);
/*!
* Copy-constructs from the given expression.
*
* @param booleanConstantExpression The expression to copy.
*/
BooleanConstantExpression(BooleanConstantExpression const& booleanConstantExpression);
virtual std::unique_ptr<BaseExpression> clone() const override;
virtual std::unique_ptr<BaseExpression> clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const override;
virtual bool getValueAsBool(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const override;
virtual void accept(ExpressionVisitor* visitor) override;
};
} // namespace expressions
} // namespace ir
} // namespace storm
#endif /* STORM_IR_EXPRESSIONS_BOOLEANCONSTANTEXPRESSION_H_ */

49
src/ir/expressions/BooleanLiteralExpression.cpp

@ -1,49 +0,0 @@
/*
* BooleanLiteralExpression.cpp
*
* Created on: 04.01.2013
* Author: Christian Dehnert
*/
#include "BooleanLiteralExpression.h"
namespace storm {
namespace ir {
namespace expressions {
BooleanLiteralExpression::BooleanLiteralExpression(bool value) : BaseExpression(bool_), value(value) {
// Nothing to do here.
}
BooleanLiteralExpression::BooleanLiteralExpression(BooleanLiteralExpression const& booleanLiteralExpression)
: BaseExpression(booleanLiteralExpression), value(booleanLiteralExpression.value) {
// Nothing to do here.
}
std::unique_ptr<BaseExpression> BooleanLiteralExpression::clone() const {
return std::unique_ptr<BaseExpression>(new BooleanLiteralExpression(*this));
}
std::unique_ptr<BaseExpression> BooleanLiteralExpression::clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const {
return std::unique_ptr<BaseExpression>(new BooleanLiteralExpression(this->value));
}
bool BooleanLiteralExpression::getValueAsBool(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const {
return value;
}
void BooleanLiteralExpression::accept(ExpressionVisitor* visitor) {
visitor->visit(this);
}
std::string BooleanLiteralExpression::toString() const {
if (value) {
return std::string("true");
} else {
return std::string("false");
}
}
} // namespace expressions
} // namespace ir
} // namespace storm

55
src/ir/expressions/BooleanLiteralExpression.h

@ -1,55 +0,0 @@
/*
* BooleanLiteralExpression.h
*
* Created on: 03.01.2013
* Author: Christian Dehnert
*/
#ifndef STORM_IR_EXPRESSIONS_BOOLEANLITERALEXPRESSION_H_
#define STORM_IR_EXPRESSIONS_BOOLEANLITERALEXPRESSION_H_
#include "src/ir/expressions/BaseExpression.h"
namespace storm {
namespace ir {
namespace expressions {
/*!
* A class representing a boolean literal.
*/
class BooleanLiteralExpression : public BaseExpression {
public:
/*!
* Creates a boolean literal expression with the given value.
*
* @param value The value for the boolean literal.
*/
BooleanLiteralExpression(bool value);
/*!
* Copy-constructs from the given expression.
*
* @param booleanLiteralExpression The expression to copy.
*/
BooleanLiteralExpression(BooleanLiteralExpression const& booleanLiteralExpression);
virtual std::unique_ptr<BaseExpression> clone() const override;
virtual std::unique_ptr<BaseExpression> clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const override;
virtual bool getValueAsBool(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const override;
virtual void accept(ExpressionVisitor* visitor) override;
virtual std::string toString() const override;
private:
// The value of the boolean literal.
bool value;
};
} // namespace expressions
} // namespace ir
} // namespace storm
#endif /* STORM_IR_EXPRESSIONS_BOOLEANLITERALEXPRESSION_H_ */

132
src/ir/expressions/ConstantExpression.h

@ -1,132 +0,0 @@
/*
* ConstantExpression.h
*
* Created on: 03.01.2013
* Author: Christian Dehnert
*/
#ifndef STORM_IR_EXPRESSIONS_CONSTANTEXPRESSION_H_
#define STORM_IR_EXPRESSIONS_CONSTANTEXPRESSION_H_
#include "BaseExpression.h"
namespace storm {
namespace ir {
namespace expressions {
// A struct for storing whether the constant was defined and if so, what value it holds.
template<class T>
struct ConstantDefinitionStruct {
/*!
* Constructs a structure indicating that the constant has been defined with the given value.
*
* @param value The value with which the constant was defined.
*/
ConstantDefinitionStruct(T value) : value(value), defined(true) {
// Nothing to do here.
}
/*!
* Constructs a structure indicating that the constant has not yet been defined.
*
* @param value The value with which the constant was defined.
*/
ConstantDefinitionStruct() : value(), defined(false) {
// Nothing to do here.
}
T value;
bool defined;
};
/*!
* A class representing a generic constant expression.
*/
template<class T>
class ConstantExpression : public BaseExpression {
public:
/*!
* Constructs a constant expression of the given type with the given constant name.
*
* @param type The type of the constant.
* @param constantName The name of the constant.
*/
ConstantExpression(ReturnType type, std::string const& constantName) : BaseExpression(type), constantName(constantName), valueStructPointer(new ConstantDefinitionStruct<T>()) {
// Nothing to do here.
}
/*!
* Copy-constructs from the given expression.
*
* @param constantExpression The expression to copy.
*/
ConstantExpression(ConstantExpression const& constantExpression) : BaseExpression(constantExpression), constantName(constantExpression.constantName), valueStructPointer(constantExpression.valueStructPointer) {
// Nothing to do here.
}
/*!
* Retrieves the name of the constant.
*
* @return The name of the constant.
*/
std::string const& getConstantName() const {
return constantName;
}
virtual std::string toString() const override {
std::stringstream result;
if (this->valueStructPointer->defined) {
result << this->valueStructPointer->value;
} else {
result << this->getConstantName();
}
return result.str();
}
/*!
* Retrieves whether the constant is defined or not.
*
* @return True if the constant is defined.
*/
bool isDefined() const {
return this->valueStructPointer->defined;
}
/*!
* Retrieves the value of the constant if it is defined.
*/
T getValue() const {
return this->valueStructPointer->value;
}
/*!
* Defines the constant using the given value.
*
* @param value The value to use for defining the constant.
*/
void define(T value) {
this->valueStructPointer->defined = true;
this->valueStructPointer->value = value;
}
/*!
* Undefines the value that was previously set for this constant (if any).
*/
void undefine() {
this->valueStructPointer->defined = false;
this->valueStructPointer->value = T();
}
private:
// The name of the constant.
std::string constantName;
// The definedness status and (if applicable) the value of the constant.
std::shared_ptr<ConstantDefinitionStruct<T>> valueStructPointer;
};
} // namespace expressions
} // namespace ir
} // namespace storm
#endif /* STORM_IR_EXPRESSIONS_CONSTANTEXPRESSION_H_ */

45
src/ir/expressions/DoubleConstantExpression.cpp

@ -1,45 +0,0 @@
/*
* DoubleConstantExpression.cpp
*
* Created on: 10.06.2013
* Author: Christian Dehnert
*/
#include "DoubleConstantExpression.h"
namespace storm {
namespace ir {
namespace expressions {
DoubleConstantExpression::DoubleConstantExpression(std::string const& constantName) : ConstantExpression<double>(double_, constantName) {
// Nothing to do here.
}
DoubleConstantExpression::DoubleConstantExpression(DoubleConstantExpression const& doubleConstantExpression) : ConstantExpression(doubleConstantExpression) {
// Nothing to do here.
}
std::unique_ptr<BaseExpression> DoubleConstantExpression::clone() const {
return std::unique_ptr<BaseExpression>(new DoubleConstantExpression(*this));
}
std::unique_ptr<BaseExpression> DoubleConstantExpression::clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const {
return std::unique_ptr<BaseExpression>(new DoubleConstantExpression(*this));
}
double DoubleConstantExpression::getValueAsDouble(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const {
if (!this->isDefined()) {
throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: "
<< "Double constant '" << this->getConstantName() << "' is undefined.";
} else {
return this->getValue();
}
}
void DoubleConstantExpression::accept(ExpressionVisitor* visitor) {
visitor->visit(this);
}
} // namespace expressions
} // namespace ir
} // namespace storm

49
src/ir/expressions/DoubleConstantExpression.h

@ -1,49 +0,0 @@
/*
* DoubleConstantExpression.h
*
* Created on: 04.01.2013
* Author: Christian Dehnert
*/
#ifndef STORM_IR_EXPRESSIONS_DOUBLECONSTANTEXPRESSION_H_
#define STORM_IR_EXPRESSIONS_DOUBLECONSTANTEXPRESSION_H_
#include "ConstantExpression.h"
namespace storm {
namespace ir {
namespace expressions {
/*!
* A class representing a constant expression of type double.
*/
class DoubleConstantExpression : public ConstantExpression<double> {
public:
/*!
* Creates a double constant expression with the given constant name.
*
* @param constantName The name of the constant to use.
*/
DoubleConstantExpression(std::string const& constantName);
/*!
* Copy-constructs from the given expression.
*
* @param doubleConstantExpression The expression to copy.
*/
DoubleConstantExpression(DoubleConstantExpression const& doubleConstantExpression);
virtual std::unique_ptr<BaseExpression> clone() const override;
virtual std::unique_ptr<BaseExpression> clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const override;
virtual double getValueAsDouble(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const override;
virtual void accept(ExpressionVisitor* visitor) override;
};
} // namespace expressions
} // namespace ir
} // namespace storm
#endif /* STORM_IR_EXPRESSIONS_DOUBLECONSTANTEXPRESSION_H_ */

49
src/ir/expressions/DoubleLiteralExpression.cpp

@ -1,49 +0,0 @@
/*
* DoubleLiteralExpression.cpp
*
* Created on: 10.06.2013
* Author: Christian Dehnert
*/
#include <sstream>
#include "DoubleLiteralExpression.h"
namespace storm {
namespace ir {
namespace expressions {
DoubleLiteralExpression::DoubleLiteralExpression(double value) : BaseExpression(double_), value(value) {
// Nothing to do here.
}
DoubleLiteralExpression::DoubleLiteralExpression(DoubleLiteralExpression const& doubleLiteralExpression)
: BaseExpression(doubleLiteralExpression), value(doubleLiteralExpression.value) {
// Nothing to do here.
}
std::unique_ptr<BaseExpression> DoubleLiteralExpression::clone() const {
return std::unique_ptr<BaseExpression>(new DoubleLiteralExpression(*this));
}
std::unique_ptr<BaseExpression> DoubleLiteralExpression::clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const {
return std::unique_ptr<BaseExpression>(new DoubleLiteralExpression(this->value));
}
double DoubleLiteralExpression::getValueAsDouble(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const {
return value;
}
void DoubleLiteralExpression::accept(ExpressionVisitor* visitor) {
visitor->visit(this);
}
std::string DoubleLiteralExpression::toString() const {
std::stringstream result;
result << value;
return result.str();
}
} // namespace expressions
} // namespace ir
} // namespace storm

55
src/ir/expressions/DoubleLiteralExpression.h

@ -1,55 +0,0 @@
/*
* DoubleLiteralExpression.h
*
* Created on: 03.01.2013
* Author: Christian Dehnert
*/
#ifndef STORM_IR_EXPRESSIONS_DOUBLELITERALEXPRESSION_H_
#define STORM_IR_EXPRESSIONS_DOUBLELITERALEXPRESSION_H_
#include "src/ir/expressions/BaseExpression.h"
namespace storm {
namespace ir {
namespace expressions {
/*!
* A class representing a double literal.
*/
class DoubleLiteralExpression : public BaseExpression {
public:
/*!
* Creates a double literal expression with the given value.
*
* @param value The value for the double literal.
*/
DoubleLiteralExpression(double value);
/*!
* Copy-constructs from the given expression.
*
* @param doubleLiteralExpression The expression to copy.
*/
DoubleLiteralExpression(DoubleLiteralExpression const& doubleLiteralExpression);
virtual std::unique_ptr<BaseExpression> clone() const override;
virtual std::unique_ptr<BaseExpression> clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const override;
virtual double getValueAsDouble(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const override;
virtual void accept(ExpressionVisitor* visitor) override;
virtual std::string toString() const override;
private:
// The value of the double literal.
double value;
};
} // namespace expressions
} // namespace ir
} // namespace storm
#endif /* STORM_IR_EXPRESSIONS_DOUBLELITERALEXPRESSION_H_ */

49
src/ir/expressions/ExpressionVisitor.h

@ -1,49 +0,0 @@
/*
* ExpressionVisitor.h
*
* Created on: 26.01.2013
* Author: Christian Dehnert
*/
#ifndef STORM_IR_EXPRESSIONS_EXPRESSIONVISITOR_H_
#define STORM_IR_EXPRESSIONS_EXPRESSIONVISITOR_H_
namespace storm {
namespace ir {
namespace expressions {
class BaseExpression;
class BinaryBooleanFunctionExpression;
class BinaryNumericalFunctionExpression;
class BinaryRelationExpression;
class BooleanConstantExpression;
class BooleanLiteralExpression;
class DoubleConstantExpression;
class DoubleLiteralExpression;
class IntegerConstantExpression;
class IntegerLiteralExpression;
class UnaryBooleanFunctionExpression;
class UnaryNumericalFunctionExpression;
class VariableExpression;
class ExpressionVisitor {
public:
virtual void visit(BinaryBooleanFunctionExpression* expression) = 0;
virtual void visit(BinaryNumericalFunctionExpression* expression) = 0;
virtual void visit(BinaryRelationExpression* expression) = 0;
virtual void visit(BooleanConstantExpression* expression) = 0;
virtual void visit(BooleanLiteralExpression* expression) = 0;
virtual void visit(DoubleConstantExpression* expression) = 0;
virtual void visit(DoubleLiteralExpression* expression) = 0;
virtual void visit(IntegerConstantExpression* expression) = 0;
virtual void visit(IntegerLiteralExpression* expression) = 0;
virtual void visit(UnaryBooleanFunctionExpression* expression) = 0;
virtual void visit(UnaryNumericalFunctionExpression* expression) = 0;
virtual void visit(VariableExpression* expression) = 0;
};
} // namespace expressions
} // namespace ir
} // namespace storm
#endif /* STORM_IR_EXPRESSIONS_EXPRESSIONVISITOR_H_ */

26
src/ir/expressions/Expressions.h

@ -1,26 +0,0 @@
/*
* Expressions.h
*
* Created on: 03.01.2013
* Author: Christian Dehnert
*/
#ifndef STORM_IR_EXPRESSIONS_EXPRESSIONS_H_
#define STORM_IR_EXPRESSIONS_EXPRESSIONS_H_
#include "BaseExpression.h"
#include "BinaryBooleanFunctionExpression.h"
#include "BinaryNumericalFunctionExpression.h"
#include "BinaryRelationExpression.h"
#include "BooleanLiteralExpression.h"
#include "DoubleLiteralExpression.h"
#include "IntegerLiteralExpression.h"
#include "UnaryBooleanFunctionExpression.h"
#include "UnaryNumericalFunctionExpression.h"
#include "VariableExpression.h"
#include "ConstantExpression.h"
#include "BooleanConstantExpression.h"
#include "IntegerConstantExpression.h"
#include "DoubleConstantExpression.h"
#endif /* STORM_IR_EXPRESSIONS_EXPRESSIONS_H_ */

48
src/ir/expressions/IntegerConstantExpression.cpp

@ -1,48 +0,0 @@
/*
* IntegerConstantExpression.cpp
*
* Created on: 10.06.2013
* Author: Christian Dehnert
*/
#include "IntegerConstantExpression.h"
namespace storm {
namespace ir {
namespace expressions {
IntegerConstantExpression::IntegerConstantExpression(std::string const& constantName) : ConstantExpression(int_, constantName) {
// Nothing to do here.
}
IntegerConstantExpression::IntegerConstantExpression(IntegerConstantExpression const& integerConstantExpression) : ConstantExpression(integerConstantExpression) {
// Nothing to do here.
}
std::unique_ptr<BaseExpression> IntegerConstantExpression::clone() const {
return std::unique_ptr<BaseExpression>(new IntegerConstantExpression(*this));
}
std::unique_ptr<BaseExpression> IntegerConstantExpression::clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const {
return std::unique_ptr<BaseExpression>(new IntegerConstantExpression(*this));
}
double IntegerConstantExpression::getValueAsDouble(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const {
return static_cast<double>(getValueAsInt(variableValues));
}
int_fast64_t IntegerConstantExpression::getValueAsInt(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const {
if (!this->isDefined()) {
throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: "
<< "Integer constant '" << this->getConstantName() << "' is undefined.";
} else {
return this->getValue();
}
}
void IntegerConstantExpression::accept(ExpressionVisitor* visitor) {
visitor->visit(this);
}
} // namespace expressions
} // namespace ir
} // namespace storm

51
src/ir/expressions/IntegerConstantExpression.h

@ -1,51 +0,0 @@
/*
* IntegerConstantExpression.h
*
* Created on: 04.01.2013
* Author: Christian Dehnert
*/
#ifndef STORM_IR_EXPRESSIONS_INTEGERCONSTANTEXPRESSION_H_
#define STORM_IR_EXPRESSIONS_INTEGERCONSTANTEXPRESSION_H_
#include "ConstantExpression.h"
namespace storm {
namespace ir {
namespace expressions {
/*!
* A class representing a constant expression of type integer.
*/
class IntegerConstantExpression : public ConstantExpression<int_fast64_t> {
public:
/*!
* Creates an integer constant expression with the given constant name.
*
* @param constantName The name of the constant to use.
*/
IntegerConstantExpression(std::string const& constantName);
/*!
* Copy-constructs from the given expression.
*
* @param integerConstantExpression The expression to copy.
*/
IntegerConstantExpression(IntegerConstantExpression const& integerConstantExpression);
virtual std::unique_ptr<BaseExpression> clone() const override;
virtual std::unique_ptr<BaseExpression> clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const override;
virtual double getValueAsDouble(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const override;
virtual int_fast64_t getValueAsInt(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const override;
virtual void accept(ExpressionVisitor* visitor) override;
};
} // namespace expressions
} // namespace ir
} // namespace storm
#endif /* STORM_IR_EXPRESSIONS_INTEGERCONSTANTEXPRESSION_H_ */

53
src/ir/expressions/IntegerLiteralExpression.cpp

@ -1,53 +0,0 @@
/*
* IntegerLiteralExpression.cpp
*
* Created on: 03.01.2013
* Author: Christian Dehnert
*/
#include <sstream>
#include "IntegerLiteralExpression.h"
namespace storm {
namespace ir {
namespace expressions {
IntegerLiteralExpression::IntegerLiteralExpression(int_fast64_t value) : BaseExpression(int_), value(value) {
// Nothing to do here.
}
IntegerLiteralExpression::IntegerLiteralExpression(IntegerLiteralExpression const& integerLiteralExpression)
: BaseExpression(integerLiteralExpression), value(integerLiteralExpression.value) {
// Nothing to do here.
}
std::unique_ptr<BaseExpression> IntegerLiteralExpression::clone() const {
return std::unique_ptr<BaseExpression>(new IntegerLiteralExpression(*this));
}
std::unique_ptr<BaseExpression> IntegerLiteralExpression::clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const {
return std::unique_ptr<BaseExpression>(new IntegerLiteralExpression(this->value));
}
double IntegerLiteralExpression::getValueAsDouble(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const {
return static_cast<double>(value);
}
int_fast64_t IntegerLiteralExpression::getValueAsInt(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const {
return value;
}
void IntegerLiteralExpression::accept(ExpressionVisitor* visitor) {
visitor->visit(this);
}
std::string IntegerLiteralExpression::toString() const {
std::stringstream result;
result << value;
return result.str();
}
} // namespace expressions
} // namespace ir
} // namespace storm

57
src/ir/expressions/IntegerLiteralExpression.h

@ -1,57 +0,0 @@
/*
* IntegerLiteralExpression.h
*
* Created on: 03.01.2013
* Author: Christian Dehnert
*/
#ifndef STORM_IR_EXPRESSIONS_INTEGERLITERALEXPRESSION_H_
#define STORM_IR_EXPRESSIONS_INTEGERLITERALEXPRESSION_H_
#include "src/ir/expressions/BaseExpression.h"
namespace storm {
namespace ir {
namespace expressions {
/*!
* A class representing an integer literal.
*/
class IntegerLiteralExpression : public BaseExpression {
public:
/*!
* Creates an integer literal expression with the given value.
*
* @param value The value for the integer literal.
*/
IntegerLiteralExpression(int_fast64_t value);
/*!
* Copy-constructs from the given expression.
*
* @param integerLiteralExpression The expression to copy.
*/
IntegerLiteralExpression(IntegerLiteralExpression const& integerLiteralExpression);
virtual std::unique_ptr<BaseExpression> clone() const override;
virtual std::unique_ptr<BaseExpression> clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const override;
virtual double getValueAsDouble(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const override;
virtual int_fast64_t getValueAsInt(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const override;
virtual void accept(ExpressionVisitor* visitor) override;
virtual std::string toString() const override;
private:
// The value of the double literal.
int_fast64_t value;
};
} // namespace expressions
} // namespace ir
} // namespace storm
#endif /* STORM_IR_EXPRESSIONS_INTEGERLITERALEXPRESSION_H_ */

62
src/ir/expressions/UnaryBooleanFunctionExpression.cpp

@ -1,62 +0,0 @@
/*
* UnaryBooleanFunctionExpression.cpp
*
* Created on: 10.06.2013
* Author: Christian Dehnert
*/
#include <sstream>
#include "UnaryBooleanFunctionExpression.h"
namespace storm {
namespace ir {
namespace expressions {
UnaryBooleanFunctionExpression::UnaryBooleanFunctionExpression(std::unique_ptr<BaseExpression>&& child, FunctionType functionType) : UnaryExpression(bool_, std::move(child)), functionType(functionType) {
// Nothing to do here.
}
UnaryBooleanFunctionExpression::UnaryBooleanFunctionExpression(UnaryBooleanFunctionExpression const& unaryBooleanFunctionExpression) : UnaryExpression(unaryBooleanFunctionExpression), functionType(unaryBooleanFunctionExpression.functionType) {
// Nothing to do here.
}
std::unique_ptr<BaseExpression> UnaryBooleanFunctionExpression::clone() const {
return std::unique_ptr<BaseExpression>(new UnaryBooleanFunctionExpression(this->getChild()->clone(), functionType));
}
std::unique_ptr<BaseExpression> UnaryBooleanFunctionExpression::clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const {
return std::unique_ptr<BaseExpression>(new UnaryBooleanFunctionExpression(this->getChild()->clone(renaming, variableState), this->functionType));
}
UnaryBooleanFunctionExpression::FunctionType UnaryBooleanFunctionExpression::getFunctionType() const {
return functionType;
}
bool UnaryBooleanFunctionExpression::getValueAsBool(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const {
bool resultChild = this->getChild()->getValueAsBool(variableValues);
switch(functionType) {
case NOT: return !resultChild; break;
default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: "
<< "Unknown boolean unary operator: '" << functionType << "'.";
}
}
void UnaryBooleanFunctionExpression::accept(ExpressionVisitor* visitor) {
visitor->visit(this);
}
std::string UnaryBooleanFunctionExpression::toString() const {
std::stringstream result;
result << "(";
switch (functionType) {
case NOT: result << "!"; break;
}
result << this->getChild()->toString() << ")";
return result.str();
}
} // namespace expressions
} // namespace ir
} // namespace storm

68
src/ir/expressions/UnaryBooleanFunctionExpression.h

@ -1,68 +0,0 @@
/*
* UnaryBooleanFunctionExpression.h
*
* Created on: 03.01.2013
* Author: Christian Dehnert
*/
#ifndef STORM_IR_EXPRESSIONS_UNARYBOOLEANFUNCTIONEXPRESSION_H_
#define STORM_IR_EXPRESSIONS_UNARYBOOLEANFUNCTIONEXPRESSION_H_
#include "UnaryExpression.h"
namespace storm {
namespace ir {
namespace expressions {
/*!
* A class representing a unary function expression of boolean type.
*/
class UnaryBooleanFunctionExpression : public UnaryExpression {
public:
/*!
* An enum type specifying the different functions applicable.
*/
enum FunctionType {NOT};
/*!
* Creates a unary boolean function expression tree node with the given child and function type.
*
* @param child The child of the node.
* @param functionType The operator that is to be applied to the two children.
*/
UnaryBooleanFunctionExpression(std::unique_ptr<BaseExpression>&& child, FunctionType functionType);
/*!
* Copy-constructs from the given expression.
*
* @param unaryBooleanFunctionExpression The expression to copy.
*/
UnaryBooleanFunctionExpression(UnaryBooleanFunctionExpression const& unaryBooleanFunctionExpression);
virtual std::unique_ptr<BaseExpression> clone() const override;
virtual std::unique_ptr<BaseExpression> clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const override;
/*!
* Retrieves the operator that is associated with this node.
*
* @param The operator that is associated with this node.
*/
FunctionType getFunctionType() const;
virtual bool getValueAsBool(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const override;
virtual void accept(ExpressionVisitor* visitor) override;
virtual std::string toString() const override;
private:
// The operator that is associated with this node.
FunctionType functionType;
};
} // namespace expressions
} // namespace ir
} // namespace storm
#endif /* STORM_IR_EXPRESSIONS_UNARYBOOLEANFUNCTIONEXPRESSION_H_ */

39
src/ir/expressions/UnaryExpression.cpp

@ -1,39 +0,0 @@
/*
* UnaryExpression.cpp
*
* Created on: 27.01.2013
* Author: Christian Dehnert
*/
#include "UnaryExpression.h"
namespace storm {
namespace ir {
namespace expressions {
UnaryExpression::UnaryExpression(ReturnType type, std::unique_ptr<BaseExpression>&& child) : BaseExpression(type), child(std::move(child)) {
// Nothing to do here.
}
UnaryExpression::UnaryExpression(UnaryExpression const& unaryExpression) : BaseExpression(unaryExpression), child(unaryExpression.child->clone()) {
// Nothing to do here.
}
std::unique_ptr<BaseExpression> const& UnaryExpression::getChild() const {
return child;
}
BaseExpression* UnaryExpression::performSubstitution(std::map<std::string, std::reference_wrapper<BaseExpression>> const& substitution) {
BaseExpression* newChild = child->performSubstitution(substitution);
// Only update the child if it changed, because otherwise the child gets destroyed.
if (newChild != child.get()) {
child = std::unique_ptr<BaseExpression>(newChild);
}
return this;
}
} // namespace expressions
} // namespace ir
} // namespace storm

55
src/ir/expressions/UnaryExpression.h

@ -1,55 +0,0 @@
/*
* UnaryExpression.h
*
* Created on: 27.01.2013
* Author: Christian Dehnert
*/
#ifndef STORM_IR_EXPRESSIONS_UNARYEXPRESSION_H_
#define STORM_IR_EXPRESSIONS_UNARYEXPRESSION_H_
#include "BaseExpression.h"
namespace storm {
namespace ir {
namespace expressions {
/*!
* A class representing a generic unary expression.
*/
class UnaryExpression : public BaseExpression {
public:
/*!
* Constructs a unary expression with the given type and child.
* @param type The type of the unary expression.
* @param right The child of the unary expression.
*/
UnaryExpression(ReturnType type, std::unique_ptr<BaseExpression>&& child);
/*!
* Copy-constructs from the given expression.
*
* @param unaryExpression The expression to copy.
*/
UnaryExpression(UnaryExpression const& unaryExpression);
/*!
* Retrieves the child of the expression node.
*
* @return The child of the expression node.
*/
std::unique_ptr<BaseExpression> const& getChild() const;
protected:
virtual BaseExpression* performSubstitution(std::map<std::string, std::reference_wrapper<BaseExpression>> const& substitution) override;
private:
// The left child of the unary expression.
std::unique_ptr<BaseExpression> child;
};
} // namespace expressions
} // namespace ir
} // namespace storm
#endif /* STORM_IR_EXPRESSIONS_UNARYEXPRESSION_H_ */

86
src/ir/expressions/UnaryNumericalFunctionExpression.cpp

@ -1,86 +0,0 @@
/*
* UnaryFunctionExpression.h
*
* Created on: 03.01.2013
* Author: Christian Dehnert
*/
#include <cmath>
#include "UnaryNumericalFunctionExpression.h"
namespace storm {
namespace ir {
namespace expressions {
UnaryNumericalFunctionExpression::UnaryNumericalFunctionExpression(ReturnType type, std::unique_ptr<BaseExpression>&& child, FunctionType functionType) : UnaryExpression(type, std::move(child)), functionType(functionType) {
// Nothing to do here.
}
UnaryNumericalFunctionExpression::UnaryNumericalFunctionExpression(UnaryNumericalFunctionExpression const& unaryNumericalFunctionExpression) : UnaryExpression(unaryNumericalFunctionExpression), functionType(unaryNumericalFunctionExpression.functionType) {
// Nothing to do here.
}
std::unique_ptr<BaseExpression> UnaryNumericalFunctionExpression::clone() const {
return std::unique_ptr<BaseExpression>(new UnaryNumericalFunctionExpression(this->getType(), this->getChild()->clone(), functionType));
}
std::unique_ptr<BaseExpression> UnaryNumericalFunctionExpression::clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const {
return std::unique_ptr<BaseExpression>(new UnaryNumericalFunctionExpression(this->getType(), this->getChild()->clone(renaming, variableState), this->functionType));
}
int_fast64_t UnaryNumericalFunctionExpression::getValueAsInt(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const {
if (this->getType() != int_) {
BaseExpression::getValueAsInt(variableValues);
}
int_fast64_t resultChild = this->getChild()->getValueAsInt(variableValues);
switch(functionType) {
case MINUS: return -resultChild; break;
case FLOOR: return static_cast<int_fast64_t>(std::floor(resultChild)); break;
case CEIL: return static_cast<int_fast64_t>(std::ceil(resultChild)); break;
default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: "
<< "Unknown numerical unary operator: '" << functionType << "'.";
}
}
double UnaryNumericalFunctionExpression::getValueAsDouble(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const {
if (this->getType() != double_ && this->getType() != int_) {
BaseExpression::getValueAsDouble(variableValues);
}
double resultChild = this->getChild()->getValueAsDouble(variableValues);
switch(functionType) {
case MINUS: return -resultChild; break;
case FLOOR: return std::floor(resultChild); break;
case CEIL: return std::ceil(resultChild); break;
default: throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression: "
<< "Unknown numerical unary operator: '" << functionType << "'.";
}
}
UnaryNumericalFunctionExpression::FunctionType UnaryNumericalFunctionExpression::getFunctionType() const {
return functionType;
}
void UnaryNumericalFunctionExpression::accept(ExpressionVisitor* visitor) {
visitor->visit(this);
}
std::string UnaryNumericalFunctionExpression::toString() const {
std::stringstream result;
result << "(";
switch (functionType) {
case MINUS: result << "-"; break;
case FLOOR: result << "floor("; break;
case CEIL: result << "ceil("; break;
}
result << this->getChild()->toString() << ")";
return result.str();
}
} // namespace expressions
} // namespace ir
} // namespace storm

70
src/ir/expressions/UnaryNumericalFunctionExpression.h

@ -1,70 +0,0 @@
/*
* UnaryFunctionExpression.h
*
* Created on: 03.01.2013
* Author: Christian Dehnert
*/
#ifndef STORM_IR_EXPRESSIONS_UNARYFUNCTIONEXPRESSION_H_
#define STORM_IR_EXPRESSIONS_UNARYFUNCTIONEXPRESSION_H_
#include "UnaryExpression.h"
namespace storm {
namespace ir {
namespace expressions {
/*!
* A class representing a unary function expression of numerical type.
*/
class UnaryNumericalFunctionExpression : public UnaryExpression {
public:
/*!
* An enum type specifying the different functions applicable.
*/
enum FunctionType {MINUS, FLOOR, CEIL};
/*!
* Creates a unary numerical function expression tree node with the given child and function type.
*
* @param child The child of the node.
* @param functionType The operator that is to be applied to the two children.
*/
UnaryNumericalFunctionExpression(ReturnType type, std::unique_ptr<BaseExpression>&& child, FunctionType functionType);
/*!
* Copy-constructs from the given expression.
*
* @param unaryNumericalFunctionExpression The expression to copy.
*/
UnaryNumericalFunctionExpression(UnaryNumericalFunctionExpression const& unaryNumericalFunctionExpression);
virtual std::unique_ptr<BaseExpression> clone() const override;
virtual std::unique_ptr<BaseExpression> clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const override;
virtual int_fast64_t getValueAsInt(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const override;
virtual double getValueAsDouble(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const override;
/*!
* Retrieves the operator that is associated with this node.
*
* @param The operator that is associated with this node.
*/
FunctionType getFunctionType() const;
virtual void accept(ExpressionVisitor* visitor) override;
virtual std::string toString() const override;
private:
// The operator that is associated with this node.
FunctionType functionType;
};
} // namespace expressions
} // namespace ir
} // namespace storm
#endif /* STORM_IR_EXPRESSIONS_UNARYFUNCTIONEXPRESSION_H_ */

120
src/ir/expressions/VariableExpression.cpp

@ -1,120 +0,0 @@
/*
* VariableExpression.cpp
*
* Created on: 10.06.2013
* Author: Christian Dehnert
*/
#include "VariableExpression.h"
#include "src/parser/prismparser/VariableState.h"
#include "src/exceptions/ExpressionEvaluationException.h"
namespace storm {
namespace ir {
namespace expressions {
VariableExpression::VariableExpression(ReturnType type, std::string const& variableName) : BaseExpression(type), globalIndex(0), variableName(variableName) {
// Nothing to do here.
}
VariableExpression::VariableExpression(ReturnType type, uint_fast64_t globalIndex, std::string const& variableName)
: BaseExpression(type), globalIndex(globalIndex), variableName(variableName) {
// Nothing to do here.
}
VariableExpression::VariableExpression(VariableExpression const& variableExpression) : BaseExpression(variableExpression), globalIndex(variableExpression.globalIndex), variableName(variableExpression.variableName) {
// Nothing to do here.
}
std::unique_ptr<BaseExpression> VariableExpression::clone() const {
return std::unique_ptr<BaseExpression>(new VariableExpression(*this));
}
std::unique_ptr<BaseExpression> VariableExpression::clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const {
// Perform the proper cloning.
auto renamingPair = renaming.find(this->variableName);
if (renamingPair != renaming.end()) {
if (this->getType() == int_) {
return variableState.getIntegerVariableExpression(renamingPair->second)->clone();
} else {
return variableState.getBooleanVariableExpression(renamingPair->second)->clone();
}
} else {
if (this->getType() == int_) {
return variableState.getIntegerVariableExpression(this->variableName)->clone();
} else {
return variableState.getBooleanVariableExpression(this->variableName)->clone();
}
}
}
BaseExpression* VariableExpression::performSubstitution(std::map<std::string, std::reference_wrapper<BaseExpression>> const& substitution) {
// If the name of the variable is a key of the map, we need to replace it.
auto substitutionIterator = substitution.find(variableName);
if (substitutionIterator != substitution.end()) {
std::unique_ptr<BaseExpression> expressionClone = substitutionIterator->second.get().clone();
BaseExpression* rawPointer = expressionClone.release();
return rawPointer;
} else {
// Otherwise, we don't need to replace anything.
return this;
}
}
void VariableExpression::accept(ExpressionVisitor* visitor) {
visitor->visit(this);
}
std::string VariableExpression::toString() const {
return this->variableName;
}
int_fast64_t VariableExpression::getValueAsInt(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const {
if (this->getType() != int_) {
BaseExpression::getValueAsInt(variableValues);
}
if (variableValues != nullptr) {
return variableValues->second[globalIndex];
} else {
throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression involving variables without variable values.";
}
}
bool VariableExpression::getValueAsBool(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const {
if (this->getType() != bool_) {
BaseExpression::getValueAsBool(variableValues);
}
if (variableValues != nullptr) {
return variableValues->first[globalIndex];
} else {
throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression involving variables without variable values.";
}
}
double VariableExpression::getValueAsDouble(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const {
if (this->getType() != double_ && this->getType() != int_) {
BaseExpression::getValueAsDouble(variableValues);
}
// Because only int variables can deliver a double value, we only need to check them.
if (variableValues != nullptr) {
return static_cast<double>(variableValues->second[globalIndex]);
} else {
throw storm::exceptions::ExpressionEvaluationException() << "Cannot evaluate expression with variable '" << variableName << "' of type double.";
}
}
std::string const& VariableExpression::getVariableName() const {
return variableName;
}
uint_fast64_t VariableExpression::getGlobalVariableIndex() const {
return this->globalIndex;
}
} // namespace expressions
} // namespace ir
} // namespace storm

98
src/ir/expressions/VariableExpression.h

@ -1,98 +0,0 @@
/*
* VariableExpression.h
*
* Created on: 03.01.2013
* Author: Christian Dehnert
*/
#ifndef STORM_IR_EXPRESSIONS_VARIABLEEXPRESSION_H_
#define STORM_IR_EXPRESSIONS_VARIABLEEXPRESSION_H_
#include "BaseExpression.h"
namespace storm {
// Forward-declare VariableState.
namespace parser {
namespace prismparser {
class VariableState;
} // namespace prismparser
} // namespace parser
namespace ir {
namespace expressions {
/*!
* A class representing a variable in the expression tree.
*/
class VariableExpression : public BaseExpression {
public:
/*!
* Creates a variable expression of the given type with the given name. As this variable has no indices
* it is only meant as a dummy and needs to be replaced with a "full" variable expression.
*
* @param type The type of the variable.
* @param variableName The name of the variable.
*/
VariableExpression(ReturnType type, std::string const& variableName);
/*!
* Creates a variable expression of the given type with the given name and indices.
*
* @param type The type of the variable.
* @param globalIndex The global (i.e. program-wide) index of the variable.
* @param variableName The name of the variable.
*/
VariableExpression(ReturnType type, uint_fast64_t globalIndex, std::string const& variableName);
/*!
* Copy-constructs from the given expression.
*
* @param variableExpression The expression to copy.
*/
VariableExpression(VariableExpression const& variableExpression);
virtual std::unique_ptr<BaseExpression> clone() const override;
virtual std::unique_ptr<BaseExpression> clone(std::map<std::string, std::string> const& renaming, storm::parser::prism::VariableState const& variableState) const override;
virtual void accept(ExpressionVisitor* visitor) override;
virtual std::string toString() const override;
virtual int_fast64_t getValueAsInt(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const override;
virtual bool getValueAsBool(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const override;
virtual double getValueAsDouble(std::pair<std::vector<bool>, std::vector<int_fast64_t>> const* variableValues) const override;
/*!
* Retrieves the name of the variable.
*
* @return The name of the variable.
*/
std::string const& getVariableName() const;
/*!
* Retrieves the global (i.e. program-wide) index of the variable.
*
* @return The global index of the variable.
*/
uint_fast64_t getGlobalVariableIndex() const;
protected:
virtual BaseExpression* performSubstitution(std::map<std::string, std::reference_wrapper<BaseExpression>> const& substitution) override;
private:
// The global index of the variable.
uint_fast64_t globalIndex;
// The name of the variable.
std::string variableName;
};
} // namespace expressions
} // namespace ir
} // namespace storm
#endif /* STORM_IR_EXPRESSIONS_VARIABLEEXPRESSION_H_ */

756
src/parser/PrismParser.cpp

@ -1,128 +1,636 @@
/*
* PrismParser.cpp
*
* Created on: 11.01.2013
* Author: chris
*/
#include "PrismParser.h"
#include "src/utility/OsDetection.h"
#include "src/parser/prismparser/PrismGrammar.h"
// If the parser fails due to ill-formed data, this exception is thrown.
#include "src/parser/PrismParser.h"
#include "src/exceptions/InvalidArgumentException.h"
#include "src/exceptions/WrongFormatException.h"
// Needed for file IO.
#include <fstream>
#include <iomanip>
#include <limits>
#include "log4cplus/logger.h"
#include "log4cplus/loggingmacros.h"
extern log4cplus::Logger logger;
namespace storm {
namespace parser {
/*!
* Opens the given file for parsing, invokes the helper function to parse the actual content and
* closes the file properly, even if an exception is thrown in the parser. In this case, the
* exception is passed on to the caller.
*/
storm::ir::Program PrismParserFromFile(std::string const& filename) {
// Open file and initialize result.
std::ifstream inputFileStream(filename, std::ios::in);
storm::ir::Program result;
// Now try to parse the contents of the file.
try {
result = PrismParser(inputFileStream, filename);
} catch(std::exception& e) {
// In case of an exception properly close the file before passing exception.
inputFileStream.close();
throw e;
}
// Close the stream in case everything went smoothly and return result.
inputFileStream.close();
return result;
}
/*!
* Passes iterators to the input stream to the Boost spirit parser and thereby parses the input.
* If the parser throws an expectation failure exception, i.e. expected input different than the one
* provided, this is caught and displayed properly before the exception is passed on.
*/
storm::ir::Program PrismParser(std::istream& inputStream, std::string const& filename) {
// Prepare iterators to input.
// TODO: Right now, this parses the whole contents of the file into a string first.
// While this is usually not necessary, because there exist adapters that make an input stream
// iterable in both directions without storing it into a string, using the corresponding
// Boost classes gives an awful output under valgrind and is thus disabled for the time being.
std::string fileContent((std::istreambuf_iterator<char>(inputStream)), (std::istreambuf_iterator<char>()));
BaseIteratorType stringIteratorBegin = fileContent.begin();
BaseIteratorType stringIteratorEnd = fileContent.end();
PositionIteratorType positionIteratorBegin(stringIteratorBegin, stringIteratorEnd, filename);
PositionIteratorType positionIteratorBegin2(stringIteratorBegin, stringIteratorEnd, filename);
PositionIteratorType positionIteratorEnd;
// Prepare resulting intermediate representation of input.
storm::ir::Program result;
// In order to instantiate the grammar, we have to pass the type of the skipping parser.
// As this is more complex, we let Boost figure out the actual type for us.
prism::PrismGrammar grammar;
try {
// Now parse the content using phrase_parse in order to be able to supply a skipping parser.
// First run.
LOG4CPLUS_INFO(logger, "Start parsing...");
qi::phrase_parse(positionIteratorBegin, positionIteratorEnd, grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol, result);
grammar.prepareForSecondRun();
result = storm::ir::Program();
LOG4CPLUS_INFO(logger, "Start second parsing run...");
// Second run.
qi::phrase_parse(positionIteratorBegin2, positionIteratorEnd, grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol, result);
LOG4CPLUS_INFO(logger, "Finished parsing, here is the parsed program:" << std::endl << result.toString());
// Reset grammars.
grammar.resetGrammars();
} catch(const qi::expectation_failure<PositionIteratorType>& e) {
// If the parser expected content different than the one provided, display information
// about the location of the error.
const boost::spirit::classic::file_position_base<std::string>& pos = e.first.get_position();
// Construct the error message including a caret display of the position in the
// erroneous line.
std::stringstream msg;
std::string line = e.first.get_currentline();
while (line.find('\t') != std::string::npos) line.replace(line.find('\t'),1," ");
msg << pos.file << ", line " << pos.line << ", column " << pos.column
<< ": parse error: expected " << e.what_ << std::endl << "\t"
<< line << std::endl << "\t";
int i = 0;
for (i = 1; i < pos.column; ++i) {
msg << "-";
}
msg << "^";
for (; i < 80; ++i) {
msg << "-";
}
msg << std::endl;
std::cerr << msg.str();
// Reset grammars in any case.
grammar.resetGrammars();
// Now propagate exception.
throw storm::exceptions::WrongFormatException() << msg.str();
}
return result;
}
} // namespace parser
namespace parser {
storm::prism::Program PrismParser::parse(std::string const& filename, bool typeCheck) {
// Open file and initialize result.
std::ifstream inputFileStream(filename, std::ios::in);
LOG_THROW(inputFileStream.good(), storm::exceptions::WrongFormatException, "Unable to read from file " << filename << ".");
storm::prism::Program result;
// Now try to parse the contents of the file.
try {
std::string fileContent((std::istreambuf_iterator<char>(inputFileStream)), (std::istreambuf_iterator<char>()));
result = parseFromString(fileContent, filename, typeCheck);
} catch(std::exception& e) {
// In case of an exception properly close the file before passing exception.
inputFileStream.close();
throw e;
}
// Close the stream in case everything went smoothly and return result.
inputFileStream.close();
return result;
}
storm::prism::Program PrismParser::parseFromString(std::string const& input, std::string const& filename, bool typeCheck) {
PositionIteratorType first(input.begin());
PositionIteratorType iter = first;
PositionIteratorType last(input.end());
// Create empty result;
storm::prism::Program result;
// Create grammar.
storm::parser::PrismParser grammar(filename, first);
try {
// Now parse the content using phrase_parse in order to be able to supply a skipping parser.
bool succeeded = qi::phrase_parse(iter, last, grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol, result);
LOG_THROW(succeeded, storm::exceptions::WrongFormatException, "Parsing failed in first pass.");
if (typeCheck) {
first = PositionIteratorType(input.begin());
iter = first;
last = PositionIteratorType(input.end());
grammar.moveToSecondRun();
succeeded = qi::phrase_parse(iter, last, grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol, result);
LOG_THROW(succeeded, storm::exceptions::WrongFormatException, "Parsing failed in second pass.");
}
} catch (qi::expectation_failure<PositionIteratorType> const& e) {
// If the parser expected content different than the one provided, display information about the location of the error.
std::size_t lineNumber = boost::spirit::get_line(e.first);
// Now propagate exception.
LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << lineNumber << " of file " << filename << ".");
}
return result;
}
PrismParser::PrismParser(std::string const& filename, Iterator first) : PrismParser::base_type(start), secondRun(false), allowDoubleLiteralsFlag(true), filename(filename), annotate(first) {
// Parse simple identifier.
identifier %= qi::as_string[qi::raw[qi::lexeme[((qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_')))]]][qi::_pass = phoenix::bind(&PrismParser::isValidIdentifier, phoenix::ref(*this), qi::_1)];
identifier.name("identifier");
floorCeilExpression = ((qi::lit("floor")[qi::_a = true] | qi::lit("ceil")[qi::_a = false]) >> qi::lit("(") >> plusExpression >> qi::lit(")"))[phoenix::if_(qi::_a) [qi::_val = phoenix::bind(&PrismParser::createFloorExpression, phoenix::ref(*this), qi::_1)] .else_ [qi::_val = phoenix::bind(&PrismParser::createCeilExpression, phoenix::ref(*this), qi::_1)]];
floorCeilExpression.name("floor/ceil expression");
minMaxExpression = ((qi::lit("min")[qi::_a = true] | qi::lit("max")[qi::_a = false]) >> qi::lit("(") >> plusExpression >> qi::lit(",") >> plusExpression >> qi::lit(")"))[phoenix::if_(qi::_a) [qi::_val = phoenix::bind(&PrismParser::createMinimumExpression, phoenix::ref(*this), qi::_1, qi::_2)] .else_ [qi::_val = phoenix::bind(&PrismParser::createMaximumExpression, phoenix::ref(*this), qi::_1, qi::_2)]];
minMaxExpression.name("min/max expression");
identifierExpression = identifier[qi::_val = phoenix::bind(&PrismParser::getIdentifierExpression, phoenix::ref(*this), qi::_1)];
identifierExpression.name("identifier expression");
literalExpression = qi::lit("true")[qi::_val = phoenix::bind(&PrismParser::createTrueExpression, phoenix::ref(*this))] | qi::lit("false")[qi::_val = phoenix::bind(&PrismParser::createFalseExpression, phoenix::ref(*this))] | strict_double[qi::_val = phoenix::bind(&PrismParser::createDoubleLiteralExpression, phoenix::ref(*this), qi::_1, qi::_pass)] | qi::int_[qi::_val = phoenix::bind(&PrismParser::createIntegerLiteralExpression, phoenix::ref(*this), qi::_1)];
literalExpression.name("literal expression");
atomicExpression = minMaxExpression | floorCeilExpression | qi::lit("(") >> expression >> qi::lit(")") | literalExpression | identifierExpression;
atomicExpression.name("atomic expression");
unaryExpression = atomicExpression[qi::_val = qi::_1] | (qi::lit("!") >> atomicExpression)[qi::_val = phoenix::bind(&PrismParser::createNotExpression, phoenix::ref(*this), qi::_1)] | (qi::lit("-") >> atomicExpression)[qi::_val = phoenix::bind(&PrismParser::createMinusExpression, phoenix::ref(*this), qi::_1)];
unaryExpression.name("unary expression");
multiplicationExpression = unaryExpression[qi::_val = qi::_1] >> *((qi::lit("*")[qi::_a = true] | qi::lit("/")[qi::_a = false]) >> unaryExpression[phoenix::if_(qi::_a) [qi::_val = phoenix::bind(&PrismParser::createMultExpression, phoenix::ref(*this), qi::_val, qi::_1)] .else_ [qi::_val = phoenix::bind(&PrismParser::createDivExpression, phoenix::ref(*this), qi::_val, qi::_1)]]);
multiplicationExpression.name("multiplication expression");
plusExpression = multiplicationExpression[qi::_val = qi::_1] >> *((qi::lit("+")[qi::_a = true] | qi::lit("-")[qi::_a = false]) >> multiplicationExpression)[phoenix::if_(qi::_a) [qi::_val = phoenix::bind(&PrismParser::createPlusExpression, phoenix::ref(*this), qi::_val, qi::_1)] .else_ [qi::_val = phoenix::bind(&PrismParser::createMinusExpression, phoenix::ref(*this), qi::_val, qi::_1)]];
plusExpression.name("plus expression");
relativeExpression = (plusExpression >> qi::lit(">=") >> plusExpression)[qi::_val = phoenix::bind(&PrismParser::createGreaterOrEqualExpression, phoenix::ref(*this), qi::_1, qi::_2)] | (plusExpression >> qi::lit(">") >> plusExpression)[qi::_val = phoenix::bind(&PrismParser::createGreaterExpression, phoenix::ref(*this), qi::_1, qi::_2)] | (plusExpression >> qi::lit("<=") >> plusExpression)[qi::_val = phoenix::bind(&PrismParser::createLessOrEqualExpression, phoenix::ref(*this), qi::_1, qi::_2)] | (plusExpression >> qi::lit("<") >> plusExpression)[qi::_val = phoenix::bind(&PrismParser::createLessExpression, phoenix::ref(*this), qi::_1, qi::_2)] | (plusExpression >> qi::lit("=") >> plusExpression)[qi::_val = phoenix::bind(&PrismParser::createEqualsExpression, phoenix::ref(*this), qi::_1, qi::_2)] | (plusExpression >> qi::lit("!=") >> plusExpression)[qi::_val = phoenix::bind(&PrismParser::createNotEqualsExpression, phoenix::ref(*this), qi::_1, qi::_2)] | plusExpression[qi::_val = qi::_1];
relativeExpression.name("relative expression");
andExpression = relativeExpression[qi::_val = qi::_1] >> *(qi::lit("&") >> relativeExpression)[qi::_val = phoenix::bind(&PrismParser::createAndExpression, phoenix::ref(*this), qi::_val, qi::_1)];
andExpression.name("and expression");
orExpression = andExpression[qi::_val = qi::_1] >> *(qi::lit("|") >> andExpression)[qi::_val = phoenix::bind(&PrismParser::createOrExpression, phoenix::ref(*this), qi::_val, qi::_1)];
orExpression.name("or expression");
iteExpression = orExpression[qi::_val = qi::_1] >> -(qi::lit("?") > orExpression > qi::lit(":") > orExpression)[qi::_val = phoenix::bind(&PrismParser::createIteExpression, phoenix::ref(*this), qi::_val, qi::_1, qi::_2)];
iteExpression.name("if-then-else expression");
expression %= iteExpression;
expression.name("expression");
modelTypeDefinition %= modelType_;
modelTypeDefinition.name("model type");
undefinedBooleanConstantDefinition = ((qi::lit("const") >> qi::lit("bool")) > identifier > qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createUndefinedBooleanConstant, phoenix::ref(*this), qi::_1)];
undefinedBooleanConstantDefinition.name("undefined boolean constant declaration");
undefinedIntegerConstantDefinition = ((qi::lit("const") >> qi::lit("int")) > identifier > qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createUndefinedIntegerConstant, phoenix::ref(*this), qi::_1)];
undefinedIntegerConstantDefinition.name("undefined integer constant declaration");
undefinedDoubleConstantDefinition = ((qi::lit("const") >> qi::lit("double")) > identifier > qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createUndefinedDoubleConstant, phoenix::ref(*this), qi::_1)];
undefinedDoubleConstantDefinition.name("undefined double constant definition");
undefinedConstantDefinition = (undefinedBooleanConstantDefinition | undefinedIntegerConstantDefinition | undefinedDoubleConstantDefinition);
undefinedConstantDefinition.name("undefined constant definition");
definedBooleanConstantDefinition = ((qi::lit("const") >> qi::lit("bool") >> identifier >> qi::lit("=")) > expression > qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createDefinedBooleanConstant, phoenix::ref(*this), qi::_1, qi::_2)];
definedBooleanConstantDefinition.name("defined boolean constant declaration");
definedIntegerConstantDefinition = ((qi::lit("const") >> qi::lit("int") >> identifier >> qi::lit("=")) > expression >> qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createDefinedIntegerConstant, phoenix::ref(*this), qi::_1, qi::_2)];
definedIntegerConstantDefinition.name("defined integer constant declaration");
definedDoubleConstantDefinition = ((qi::lit("const") >> qi::lit("double") >> identifier >> qi::lit("=")) > expression > qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createDefinedDoubleConstant, phoenix::ref(*this), qi::_1, qi::_2)];
definedDoubleConstantDefinition.name("defined double constant declaration");
definedConstantDefinition %= (definedBooleanConstantDefinition | definedIntegerConstantDefinition | definedDoubleConstantDefinition);
definedConstantDefinition.name("defined constant definition");
formulaDefinition = (qi::lit("formula") > identifier > qi::lit("=") > expression > qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createFormula, phoenix::ref(*this), qi::_1, qi::_2)];
formulaDefinition.name("formula definition");
booleanVariableDefinition = ((identifier >> qi::lit(":") >> qi::lit("bool")) > ((qi::lit("init") > expression) | qi::attr(storm::expressions::Expression::createFalse())) > qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createBooleanVariable, phoenix::ref(*this), qi::_1, qi::_2)];
booleanVariableDefinition.name("boolean variable definition");
integerVariableDefinition = ((identifier >> qi::lit(":") >> qi::lit("[")[phoenix::bind(&PrismParser::allowDoubleLiterals, phoenix::ref(*this), false)]) > expression[qi::_a = qi::_1] > qi::lit("..") > expression > qi::lit("]")[phoenix::bind(&PrismParser::allowDoubleLiterals, phoenix::ref(*this), true)] > -(qi::lit("init") > expression[qi::_a = qi::_1]) > qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createIntegerVariable, phoenix::ref(*this), qi::_1, qi::_2, qi::_3, qi::_a)];
integerVariableDefinition.name("integer variable definition");
variableDefinition = (booleanVariableDefinition[phoenix::push_back(qi::_r1, qi::_1)] | integerVariableDefinition[phoenix::push_back(qi::_r2, qi::_1)]);
variableDefinition.name("variable declaration");
globalVariableDefinition = (qi::lit("global") > (booleanVariableDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::globalBooleanVariables, qi::_r1), qi::_1)] | integerVariableDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::globalIntegerVariables, qi::_r1), qi::_1)]));
globalVariableDefinition.name("global variable declaration list");
programHeader = modelTypeDefinition[phoenix::bind(&GlobalProgramInformation::modelType, qi::_r1) = qi::_1]
> *(definedConstantDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::constants, qi::_r1), qi::_1)] | undefinedConstantDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::constants, qi::_r1), qi::_1)])
> *(formulaDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::formulas, qi::_r1), qi::_1)])
> *(globalVariableDefinition(qi::_r1));
programHeader.name("program header");
stateRewardDefinition = (expression > qi::lit(":") > plusExpression >> qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createStateReward, phoenix::ref(*this), qi::_1, qi::_2)];
stateRewardDefinition.name("state reward definition");
transitionRewardDefinition = (qi::lit("[") > -(identifier[qi::_a = qi::_1]) > qi::lit("]") > expression > qi::lit(":") > plusExpression > qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createTransitionReward, phoenix::ref(*this), qi::_a, qi::_2, qi::_3)];
transitionRewardDefinition.name("transition reward definition");
rewardModelDefinition = (qi::lit("rewards") > -(qi::lit("\"") > identifier[qi::_a = qi::_1] > qi::lit("\""))
> +( stateRewardDefinition[phoenix::push_back(qi::_b, qi::_1)]
| transitionRewardDefinition[phoenix::push_back(qi::_c, qi::_1)]
)
>> qi::lit("endrewards"))[qi::_val = phoenix::bind(&PrismParser::createRewardModel, phoenix::ref(*this), qi::_a, qi::_b, qi::_c)];
rewardModelDefinition.name("reward model definition");
initialStatesConstruct = (qi::lit("init") > expression > qi::lit("endinit"))[qi::_pass = phoenix::bind(&PrismParser::addInitialStatesExpression, phoenix::ref(*this), qi::_1, qi::_r1)];
initialStatesConstruct.name("initial construct");
labelDefinition = (qi::lit("label") > -qi::lit("\"") > identifier > -qi::lit("\"") > qi::lit("=") > expression >> qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createLabel, phoenix::ref(*this), qi::_1, qi::_2)];
labelDefinition.name("label definition");
assignmentDefinition = (qi::lit("(") > identifier > qi::lit("'") > qi::lit("=") > expression > qi::lit(")"))[qi::_val = phoenix::bind(&PrismParser::createAssignment, phoenix::ref(*this), qi::_1, qi::_2)];
assignmentDefinition.name("assignment");
assignmentDefinitionList %= +assignmentDefinition % "&";
assignmentDefinitionList.name("assignment list");
updateDefinition = (((plusExpression > qi::lit(":")) | qi::attr(storm::expressions::Expression::createDoubleLiteral(1))) >> assignmentDefinitionList)[qi::_val = phoenix::bind(&PrismParser::createUpdate, phoenix::ref(*this), qi::_1, qi::_2, qi::_r1)];
updateDefinition.name("update");
updateListDefinition %= +updateDefinition(qi::_r1) % "+";
updateListDefinition.name("update list");
commandDefinition = (qi::lit("[") > -(identifier[qi::_a = qi::_1]) > qi::lit("]") > expression > qi::lit("->") > updateListDefinition(qi::_r1) > qi::lit(";"))[qi::_val = phoenix::bind(&PrismParser::createCommand, phoenix::ref(*this), qi::_a, qi::_2, qi::_3, qi::_r1)];
commandDefinition.name("command definition");
moduleDefinition = ((qi::lit("module") >> identifier >> *(variableDefinition(qi::_a, qi::_b))) > +commandDefinition(qi::_r1) > qi::lit("endmodule"))[qi::_val = phoenix::bind(&PrismParser::createModule, phoenix::ref(*this), qi::_1, qi::_a, qi::_b, qi::_2, qi::_r1)];
moduleDefinition.name("module definition");
moduleRenaming = ((qi::lit("module") >> identifier >> qi::lit("=")) > identifier > qi::lit("[")
> ((identifier > qi::lit("=") > identifier)[phoenix::insert(qi::_a, phoenix::construct<std::pair<std::string,std::string>>(qi::_1, qi::_2))] % ",") > qi::lit("]")
> qi::lit("endmodule"))[qi::_val = phoenix::bind(&PrismParser::createRenamedModule, phoenix::ref(*this), qi::_1, qi::_2, qi::_a, qi::_r1)];
moduleRenaming.name("module definition via renaming");
moduleDefinitionList %= +(moduleRenaming(qi::_r1) | moduleDefinition(qi::_r1))[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::modules, qi::_r1), qi::_1)];
moduleDefinitionList.name("module list");
start = (qi::eps > programHeader(qi::_a) > moduleDefinitionList(qi::_a) > *(initialStatesConstruct(qi::_a) | rewardModelDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::rewardModels, qi::_a), qi::_1)] | labelDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::labels, qi::_a), qi::_1)] | formulaDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::formulas, qi::_a), qi::_1)]) > qi::eoi)[qi::_val = phoenix::bind(&PrismParser::createProgram, phoenix::ref(*this), qi::_a)];
start.name("probabilistic program");
// Enable error reporting.
qi::on_error<qi::fail>(expression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
qi::on_error<qi::fail>(iteExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
qi::on_error<qi::fail>(orExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
qi::on_error<qi::fail>(andExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
qi::on_error<qi::fail>(relativeExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
qi::on_error<qi::fail>(plusExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
qi::on_error<qi::fail>(multiplicationExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
qi::on_error<qi::fail>(unaryExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
qi::on_error<qi::fail>(atomicExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
qi::on_error<qi::fail>(literalExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
qi::on_error<qi::fail>(identifierExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
qi::on_error<qi::fail>(minMaxExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
qi::on_error<qi::fail>(floorCeilExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4));
// Enable location tracking for important entities.
auto setLocationInfoFunction = this->annotate(qi::_val, qi::_1, qi::_3);
qi::on_success(undefinedBooleanConstantDefinition, setLocationInfoFunction);
qi::on_success(undefinedIntegerConstantDefinition, setLocationInfoFunction);
qi::on_success(undefinedDoubleConstantDefinition, setLocationInfoFunction);
qi::on_success(definedBooleanConstantDefinition, setLocationInfoFunction);
qi::on_success(definedIntegerConstantDefinition, setLocationInfoFunction);
qi::on_success(definedDoubleConstantDefinition, setLocationInfoFunction);
qi::on_success(booleanVariableDefinition, setLocationInfoFunction);
qi::on_success(integerVariableDefinition, setLocationInfoFunction);
qi::on_success(moduleDefinition, setLocationInfoFunction);
qi::on_success(moduleRenaming, setLocationInfoFunction);
qi::on_success(formulaDefinition, setLocationInfoFunction);
qi::on_success(rewardModelDefinition, setLocationInfoFunction);
qi::on_success(labelDefinition, setLocationInfoFunction);
qi::on_success(commandDefinition, setLocationInfoFunction);
qi::on_success(updateDefinition, setLocationInfoFunction);
qi::on_success(assignmentDefinition, setLocationInfoFunction);
}
void PrismParser::moveToSecondRun() {
this->secondRun = true;
}
void PrismParser::allowDoubleLiterals(bool flag) {
this->allowDoubleLiteralsFlag = flag;
}
std::string const& PrismParser::getFilename() const {
return this->filename;
}
bool PrismParser::isValidIdentifier(std::string const& identifier) {
if (this->keywords_.find(identifier) != nullptr) {
return false;
}
return true;
}
bool PrismParser::addInitialStatesExpression(storm::expressions::Expression initialStatesExpression, GlobalProgramInformation& globalProgramInformation) {
LOG_THROW(!globalProgramInformation.hasInitialStatesExpression, storm::exceptions::InvalidArgumentException, "Program must not define two initial constructs.");
if (globalProgramInformation.hasInitialStatesExpression) {
return false;
}
globalProgramInformation.hasInitialStatesExpression = true;
globalProgramInformation.initialStatesExpression = initialStatesExpression;
return true;
}
storm::expressions::Expression PrismParser::createIteExpression(storm::expressions::Expression e1, storm::expressions::Expression e2, storm::expressions::Expression e3) const {
if (!this->secondRun) {
return storm::expressions::Expression::createFalse();
} else {
return e1.ite(e2, e3);
}
}
storm::expressions::Expression PrismParser::createOrExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
if (!this->secondRun) {
return storm::expressions::Expression::createFalse();
} else {
return e1 || e2;
}
}
storm::expressions::Expression PrismParser::createAndExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
if (!this->secondRun) {
return storm::expressions::Expression::createFalse();
} else {
return e1 && e2;
}
}
storm::expressions::Expression PrismParser::createGreaterExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
if (!this->secondRun) {
return storm::expressions::Expression::createFalse();
} else {
return e1 > e2;
}
}
storm::expressions::Expression PrismParser::createGreaterOrEqualExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
if (!this->secondRun) {
return storm::expressions::Expression::createFalse();
} else {
return e1 >= e2;
}
}
storm::expressions::Expression PrismParser::createLessExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
if (!this->secondRun) {
return storm::expressions::Expression::createFalse();
} else {
return e1 < e2;
}
}
storm::expressions::Expression PrismParser::createLessOrEqualExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
if (!this->secondRun) {
return storm::expressions::Expression::createFalse();
} else {
return e1 <= e2;
}
}
storm::expressions::Expression PrismParser::createEqualsExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
if (!this->secondRun) {
return storm::expressions::Expression::createFalse();
} else {
return e1 == e2;
}
}
storm::expressions::Expression PrismParser::createNotEqualsExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
if (!this->secondRun) {
return storm::expressions::Expression::createFalse();
} else {
return e1 != e2;
}
}
storm::expressions::Expression PrismParser::createPlusExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
if (!this->secondRun) {
return storm::expressions::Expression::createFalse();
} else {
return e1 + e2;
}
}
storm::expressions::Expression PrismParser::createMinusExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
if (!this->secondRun) {
return storm::expressions::Expression::createFalse();
} else {
return e1 - e2;
}
}
storm::expressions::Expression PrismParser::createMultExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
if (!this->secondRun) {
return storm::expressions::Expression::createFalse();
} else {
return e1 * e2;
}
}
storm::expressions::Expression PrismParser::createDivExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
if (!this->secondRun) {
return storm::expressions::Expression::createFalse();
} else {
return e1 / e2;
}
}
storm::expressions::Expression PrismParser::createNotExpression(storm::expressions::Expression e1) const {
if (!this->secondRun) {
return storm::expressions::Expression::createFalse();
} else {
return !e1;
}
}
storm::expressions::Expression PrismParser::createMinusExpression(storm::expressions::Expression e1) const {
if (!this->secondRun) {
return storm::expressions::Expression::createFalse();
} else {
return -e1;
}
}
storm::expressions::Expression PrismParser::createTrueExpression() const {
if (!this->secondRun) {
return storm::expressions::Expression::createFalse();
} else {
return storm::expressions::Expression::createTrue();
}
}
storm::expressions::Expression PrismParser::createFalseExpression() const {
if (!this->secondRun) {
return storm::expressions::Expression::createFalse();
} else {
return storm::expressions::Expression::createFalse();
}
}
storm::expressions::Expression PrismParser::createDoubleLiteralExpression(double value, bool& pass) const {
// If we are not supposed to accept double expressions, we reject it by setting pass to false.
if (!this->allowDoubleLiteralsFlag) {
pass = false;
}
if (!this->secondRun) {
return storm::expressions::Expression::createFalse();
} else {
return storm::expressions::Expression::createDoubleLiteral(value);
}
}
storm::expressions::Expression PrismParser::createIntegerLiteralExpression(int value) const {
if (!this->secondRun) {
return storm::expressions::Expression::createFalse();
} else {
return storm::expressions::Expression::createIntegerLiteral(static_cast<int_fast64_t>(value));
}
}
storm::expressions::Expression PrismParser::createMinimumExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
if (!this->secondRun) {
return storm::expressions::Expression::createFalse();
} else {
return storm::expressions::Expression::minimum(e1, e2);
}
}
storm::expressions::Expression PrismParser::createMaximumExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
if (!this->secondRun) {
return storm::expressions::Expression::createFalse();
} else {
return storm::expressions::Expression::maximum(e1, e2);
}
}
storm::expressions::Expression PrismParser::createFloorExpression(storm::expressions::Expression e1) const {
if (!this->secondRun) {
return storm::expressions::Expression::createFalse();
} else {
return e1.floor();
}
}
storm::expressions::Expression PrismParser::createCeilExpression(storm::expressions::Expression e1) const {
if (!this->secondRun) {
return storm::expressions::Expression::createFalse();
} else {
return e1.ceil();
}
}
storm::expressions::Expression PrismParser::getIdentifierExpression(std::string const& identifier) const {
if (!this->secondRun) {
return storm::expressions::Expression::createFalse();
} else {
storm::expressions::Expression const* expression = this->identifiers_.find(identifier);
LOG_THROW(expression != nullptr, storm::exceptions::WrongFormatException, "Undeclared identifier '" << identifier << "'.");
return *expression;
}
}
storm::prism::Constant PrismParser::createUndefinedBooleanConstant(std::string const& newConstant) const {
this->identifiers_.add(newConstant, storm::expressions::Expression::createBooleanConstant(newConstant));
return storm::prism::Constant(storm::expressions::ExpressionReturnType::Bool, newConstant, this->getFilename());
}
storm::prism::Constant PrismParser::createUndefinedIntegerConstant(std::string const& newConstant) const {
this->identifiers_.add(newConstant, storm::expressions::Expression::createIntegerConstant(newConstant));
return storm::prism::Constant(storm::expressions::ExpressionReturnType::Int, newConstant, this->getFilename());
}
storm::prism::Constant PrismParser::createUndefinedDoubleConstant(std::string const& newConstant) const {
this->identifiers_.add(newConstant, storm::expressions::Expression::createDoubleConstant(newConstant));
return storm::prism::Constant(storm::expressions::ExpressionReturnType::Double, newConstant, this->getFilename());
}
storm::prism::Constant PrismParser::createDefinedBooleanConstant(std::string const& newConstant, storm::expressions::Expression expression) const {
this->identifiers_.add(newConstant, storm::expressions::Expression::createBooleanConstant(newConstant));
return storm::prism::Constant(storm::expressions::ExpressionReturnType::Bool, newConstant, expression, this->getFilename());
}
storm::prism::Constant PrismParser::createDefinedIntegerConstant(std::string const& newConstant, storm::expressions::Expression expression) const {
this->identifiers_.add(newConstant, storm::expressions::Expression::createIntegerConstant(newConstant));
return storm::prism::Constant(storm::expressions::ExpressionReturnType::Int, newConstant, expression, this->getFilename());
}
storm::prism::Constant PrismParser::createDefinedDoubleConstant(std::string const& newConstant, storm::expressions::Expression expression) const {
this->identifiers_.add(newConstant, storm::expressions::Expression::createDoubleConstant(newConstant));
return storm::prism::Constant(storm::expressions::ExpressionReturnType::Double, newConstant, expression, this->getFilename());
}
storm::prism::Formula PrismParser::createFormula(std::string const& formulaName, storm::expressions::Expression expression) const {
if (this->secondRun) {
this->identifiers_.add(formulaName, expression);
}
return storm::prism::Formula(formulaName, expression, this->getFilename());
}
storm::prism::Label PrismParser::createLabel(std::string const& labelName, storm::expressions::Expression expression) const {
return storm::prism::Label(labelName, expression, this->getFilename());
}
storm::prism::RewardModel PrismParser::createRewardModel(std::string const& rewardModelName, std::vector<storm::prism::StateReward> const& stateRewards, std::vector<storm::prism::TransitionReward> const& transitionRewards) const {
return storm::prism::RewardModel(rewardModelName, stateRewards, transitionRewards, this->getFilename());
}
storm::prism::StateReward PrismParser::createStateReward(storm::expressions::Expression statePredicateExpression, storm::expressions::Expression rewardValueExpression) const {
return storm::prism::StateReward(statePredicateExpression, rewardValueExpression, this->getFilename());
}
storm::prism::TransitionReward PrismParser::createTransitionReward(std::string const& actionName, storm::expressions::Expression statePredicateExpression, storm::expressions::Expression rewardValueExpression) const {
return storm::prism::TransitionReward(actionName, statePredicateExpression, rewardValueExpression, this->getFilename());
}
storm::prism::Assignment PrismParser::createAssignment(std::string const& variableName, storm::expressions::Expression assignedExpression) const {
return storm::prism::Assignment(variableName, assignedExpression, this->getFilename());
}
storm::prism::Update PrismParser::createUpdate(storm::expressions::Expression likelihoodExpression, std::vector<storm::prism::Assignment> const& assignments, GlobalProgramInformation& globalProgramInformation) const {
++globalProgramInformation.currentUpdateIndex;
return storm::prism::Update(globalProgramInformation.currentUpdateIndex - 1, likelihoodExpression, assignments, this->getFilename());
}
storm::prism::Command PrismParser::createCommand(std::string const& actionName, storm::expressions::Expression guardExpression, std::vector<storm::prism::Update> const& updates, GlobalProgramInformation& globalProgramInformation) const {
++globalProgramInformation.currentCommandIndex;
return storm::prism::Command(globalProgramInformation.currentCommandIndex - 1, actionName, guardExpression, updates, this->getFilename());
}
storm::prism::BooleanVariable PrismParser::createBooleanVariable(std::string const& variableName, storm::expressions::Expression initialValueExpression) const {
this->identifiers_.add(variableName, storm::expressions::Expression::createBooleanVariable(variableName));
return storm::prism::BooleanVariable(variableName, initialValueExpression, this->getFilename());
}
storm::prism::IntegerVariable PrismParser::createIntegerVariable(std::string const& variableName, storm::expressions::Expression lowerBoundExpression, storm::expressions::Expression upperBoundExpression, storm::expressions::Expression initialValueExpression) const {
this->identifiers_.add(variableName, storm::expressions::Expression::createIntegerVariable(variableName));
return storm::prism::IntegerVariable(variableName, lowerBoundExpression, upperBoundExpression, initialValueExpression, this->getFilename());
}
storm::prism::Module PrismParser::createModule(std::string const& moduleName, std::vector<storm::prism::BooleanVariable> const& booleanVariables, std::vector<storm::prism::IntegerVariable> const& integerVariables, std::vector<storm::prism::Command> const& commands, GlobalProgramInformation& globalProgramInformation) const {
globalProgramInformation.moduleToIndexMap[moduleName] = globalProgramInformation.modules.size();
return storm::prism::Module(moduleName, booleanVariables, integerVariables, commands, this->getFilename());
}
storm::prism::Module PrismParser::createRenamedModule(std::string const& newModuleName, std::string const& oldModuleName, std::map<std::string, std::string> const& renaming, GlobalProgramInformation& globalProgramInformation) const {
// Check whether the module to rename actually exists.
auto const& moduleIndexPair = globalProgramInformation.moduleToIndexMap.find(oldModuleName);
LOG_THROW(moduleIndexPair != globalProgramInformation.moduleToIndexMap.end(), storm::exceptions::WrongFormatException, "No module named '" << oldModuleName << "' to rename.");
storm::prism::Module const& moduleToRename = globalProgramInformation.modules[moduleIndexPair->second];
if (!this->secondRun) {
// Register all (renamed) variables for later use.
for (auto const& variable : moduleToRename.getBooleanVariables()) {
auto const& renamingPair = renaming.find(variable.getName());
LOG_THROW(renamingPair != renaming.end(), storm::exceptions::WrongFormatException, "Boolean variable '" << variable.getName() << " was not renamed.");
this->identifiers_.add(renamingPair->second, storm::expressions::Expression::createBooleanVariable(renamingPair->second));
}
for (auto const& variable : moduleToRename.getIntegerVariables()) {
auto const& renamingPair = renaming.find(variable.getName());
LOG_THROW(renamingPair != renaming.end(), storm::exceptions::WrongFormatException, "Integer variable '" << variable.getName() << " was not renamed.");
this->identifiers_.add(renamingPair->second, storm::expressions::Expression::createIntegerVariable(renamingPair->second));
}
// Return a dummy module in the first pass.
return storm::prism::Module();
} else {
// Add a mapping from the new module name to its (future) index.
globalProgramInformation.moduleToIndexMap[newModuleName] = globalProgramInformation.modules.size();
// Create a mapping from identifiers to the expressions they need to be replaced with.
std::map<std::string, storm::expressions::Expression> expressionRenaming;
for (auto const& namePair : renaming) {
storm::expressions::Expression const* substitutedExpression = this->identifiers_.find(namePair.second);
// If the mapped-to-value is an expression, we need to replace it.
if (substitutedExpression != nullptr) {
expressionRenaming.emplace(namePair.first, *substitutedExpression);
}
}
// Rename the boolean variables.
std::vector<storm::prism::BooleanVariable> booleanVariables;
for (auto const& variable : moduleToRename.getBooleanVariables()) {
auto const& renamingPair = renaming.find(variable.getName());
LOG_THROW(renamingPair != renaming.end(), storm::exceptions::WrongFormatException, "Boolean variable '" << variable.getName() << " was not renamed.");
booleanVariables.push_back(storm::prism::BooleanVariable(renamingPair->second, variable.getInitialValueExpression().substitute<std::map>(expressionRenaming), this->getFilename(), get_line(qi::_1)));
}
// Rename the integer variables.
std::vector<storm::prism::IntegerVariable> integerVariables;
for (auto const& variable : moduleToRename.getIntegerVariables()) {
auto const& renamingPair = renaming.find(variable.getName());
LOG_THROW(renamingPair != renaming.end(), storm::exceptions::WrongFormatException, "Integer variable '" << variable.getName() << " was not renamed.");
integerVariables.push_back(storm::prism::IntegerVariable(renamingPair->second, variable.getLowerBoundExpression().substitute<std::map>(expressionRenaming), variable.getUpperBoundExpression().substitute<std::map>(expressionRenaming), variable.getInitialValueExpression().substitute<std::map>(expressionRenaming), this->getFilename(), get_line(qi::_1)));
}
// Rename commands.
std::vector<storm::prism::Command> commands;
for (auto const& command : moduleToRename.getCommands()) {
std::vector<storm::prism::Update> updates;
for (auto const& update : command.getUpdates()) {
std::vector<storm::prism::Assignment> assignments;
for (auto const& assignment : update.getAssignments()) {
auto const& renamingPair = renaming.find(assignment.getVariableName());
if (renamingPair != renaming.end()) {
assignments.emplace_back(renamingPair->second, assignment.getExpression().substitute<std::map>(expressionRenaming), this->getFilename(), get_line(qi::_1));
} else {
assignments.emplace_back(assignment.getVariableName(), assignment.getExpression().substitute<std::map>(expressionRenaming), this->getFilename(), get_line(qi::_1));
}
}
updates.emplace_back(globalProgramInformation.currentUpdateIndex, update.getLikelihoodExpression().substitute<std::map>(expressionRenaming), assignments, this->getFilename(), get_line(qi::_1));
++globalProgramInformation.currentUpdateIndex;
}
std::string newActionName = command.getActionName();
auto const& renamingPair = renaming.find(command.getActionName());
if (renamingPair != renaming.end()) {
newActionName = renamingPair->second;
}
commands.emplace_back(globalProgramInformation.currentCommandIndex, newActionName, command.getGuardExpression().substitute<std::map>(expressionRenaming), updates, this->getFilename(), get_line(qi::_1));
++globalProgramInformation.currentCommandIndex;
}
return storm::prism::Module(newModuleName, booleanVariables, integerVariables, commands, this->getFilename());
}
}
storm::prism::Program PrismParser::createProgram(GlobalProgramInformation const& globalProgramInformation) const {
return storm::prism::Program(globalProgramInformation.modelType, globalProgramInformation.constants, globalProgramInformation.globalBooleanVariables, globalProgramInformation.globalIntegerVariables, globalProgramInformation.formulas, globalProgramInformation.modules, globalProgramInformation.rewardModels, globalProgramInformation.hasInitialStatesExpression, globalProgramInformation.initialStatesExpression, globalProgramInformation.labels, this->getFilename());
}
} // namespace parser
} // namespace storm

347
src/parser/PrismParser.h

@ -1,49 +1,320 @@
/* * PrismParser.h
*
* Created on: Jan 3, 2013
* Author: Christian Dehnert
*/
#ifndef STORM_PARSER_PRISMPARSER_H_
#define STORM_PARSER_PRISMPARSER_H_
// All classes of the intermediate representation are used.
#include "src/ir/IR.h"
#define STORM_PARSER_PRISMPARSER_H_
// Used for file input.
#include <istream>
// Include files for file input.
#include <fstream>
#include <memory>
#include <iomanip>
namespace storm {
namespace parser {
// Include boost spirit.
#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <boost/typeof/typeof.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/support_line_pos_iterator.hpp>
#include <boost/spirit/home/classic/iterator/position_iterator.hpp>
using namespace storm::ir;
using namespace storm::ir::expressions;
namespace qi = boost::spirit::qi;
namespace phoenix = boost::phoenix;
/*
* This functions parse the format of the PRISM model checker into an intermediate representation.
*/
typedef std::string::const_iterator BaseIteratorType;
typedef boost::spirit::line_pos_iterator<BaseIteratorType> PositionIteratorType;
typedef PositionIteratorType Iterator;
typedef BOOST_TYPEOF(boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol) Skipper;
typedef BOOST_TYPEOF(qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol | boost::spirit::ascii::space) Skipper2;
/*!
* Parses the given file into the intermediate representation assuming it complies with the
* PRISM syntax.
* @param filename the name of the file to parse.
* @return a shared pointer to the intermediate representation of the PRISM file.
*/
storm::ir::Program PrismParserFromFile(std::string const& filename);
#include "src/storage/prism/Program.h"
#include "src/storage/expressions/Expression.h"
#include "src/exceptions/ExceptionMacros.h"
/*!
* Parses the given input stream into the intermediate representation assuming it complies with
* the PRISM syntax.
* @param inputStream the input stream to parse.
* @param filename the name of the file the input stream belongs to. Used for diagnostics.
* @return a shared pointer to the intermediate representation of the PRISM file.
*/
storm::ir::Program PrismParser(std::istream& inputStream, std::string const& filename);
} // namespace parser
namespace storm {
namespace parser {
class GlobalProgramInformation {
public:
// Default construct the header information.
GlobalProgramInformation() = default;
// Members for all essential information that needs to be collected.
storm::prism::Program::ModelType modelType;
std::vector<storm::prism::Constant> constants;
std::vector<storm::prism::Formula> formulas;
std::vector<storm::prism::BooleanVariable> globalBooleanVariables;
std::vector<storm::prism::IntegerVariable> globalIntegerVariables;
std::map<std::string, uint_fast64_t> moduleToIndexMap;
std::vector<storm::prism::Module> modules;
std::vector<storm::prism::RewardModel> rewardModels;
std::vector<storm::prism::Label> labels;
storm::expressions::Expression initialStatesExpression;
bool hasInitialStatesExpression;
// Counters to provide unique indexing for commands and updates.
uint_fast64_t currentCommandIndex;
uint_fast64_t currentUpdateIndex;
};
class PrismParser : public qi::grammar<Iterator, storm::prism::Program(), qi::locals<GlobalProgramInformation>, Skipper> {
public:
/*!
* Parses the given file into the PRISM storage classes assuming it complies with the PRISM syntax.
*
* @param filename the name of the file to parse.
* @param typeCheck Sets whether the expressions are generated and therefore typechecked.
* @return The resulting PRISM program.
*/
static storm::prism::Program parse(std::string const& filename, bool typeCheck = true);
/*!
* Parses the given input stream into the PRISM storage classes assuming it complies with the PRISM syntax.
*
* @param input The input string to parse.
* @param filename The name of the file from which the input was read.
* @param typeCheck Sets whether the expressions are generated and therefore typechecked.
* @return The resulting PRISM program.
*/
static storm::prism::Program parseFromString(std::string const& input, std::string const& filename, bool typeCheck = true);
private:
struct modelTypeStruct : qi::symbols<char, storm::prism::Program::ModelType> {
modelTypeStruct() {
add
("dtmc", storm::prism::Program::ModelType::DTMC)
("ctmc", storm::prism::Program::ModelType::CTMC)
("mdp", storm::prism::Program::ModelType::MDP)
("ctmdp", storm::prism::Program::ModelType::CTMDP)
("ma", storm::prism::Program::ModelType::MA);
}
};
struct keywordsStruct : qi::symbols<char, bool> {
keywordsStruct() {
add
("dtmc", 1)
("ctmc", 2)
("mdp", 3)
("ctmdp", 4)
("ma", 5)
("const", 6)
("int", 7)
("bool", 8)
("module", 9)
("endmodule", 10)
("rewards", 11)
("endrewards", 12)
("true", 13)
("min", 14)
("max", 15)
("floor", 16)
("ceil", 17)
("init", 18)
("endinit", 19);
}
};
// Functor used for displaying error information.
struct ErrorHandler {
typedef qi::error_handler_result result_type;
template<typename T1, typename T2, typename T3, typename T4>
qi::error_handler_result operator()(T1 b, T2 e, T3 where, T4 const& what) const {
// LOG4CPLUS_ERROR(logger, "Error: expecting " << what << " in line " << get_line(where) << " at column " << get_column(b, where, 4) << ".");
std::cerr << "Error: expecting " << what << " in line " << get_line(where) << "." << std::endl;
T3 end(where);
while (end != e && *end != '\r' && *end != '\n') {
++end;
}
std::cerr << "Error: expecting " << what << " in line " << get_line(where) << ": \n" << std::string(get_line_start(b, where), end) << " ... \n" << std::setw(std::distance(b, where)) << '^' << "---- here\n";
return qi::fail;
}
};
// Functor used for annotating entities with line number information.
class PositionAnnotation {
public:
typedef void result_type;
PositionAnnotation(Iterator first) : first(first) {
// Intentionally left empty.
}
template<typename Entity, typename First, typename Last>
result_type operator()(Entity& entity, First f, Last l) const {
entity.setLineNumber(get_line(f));
}
private:
std::string filename;
Iterator const first;
};
/*!
* Creates a grammar for the given filename and the iterator to the first input to parse.
*
* @param filename The filename that is to be read. This is used for proper error reporting.
* @param first The iterator to the beginning of the input.
*/
PrismParser(std::string const& filename, Iterator first);
/*!
* Sets an internal flag that indicates the second run is now taking place.
*/
void moveToSecondRun();
// A flag that stores whether the grammar is currently doing the second run.
bool secondRun;
/*!
* Sets whether doubles literals are allowed in the parsed expression.
*
* @param flag Indicates whether to allow or forbid double literals in the parsed expression.
*/
void allowDoubleLiterals(bool flag);
// A flag that stores wether to allow or forbid double literals in parsed expressions.
bool allowDoubleLiteralsFlag;
// The name of the file being parsed.
std::string filename;
/*!
* Retrieves the name of the file currently being parsed.
*
* @return The name of the file currently being parsed.
*/
std::string const& getFilename() const;
// A function used for annotating the entities with their position.
phoenix::function<ErrorHandler> handler;
phoenix::function<PositionAnnotation> annotate;
// The starting point of the grammar.
qi::rule<Iterator, storm::prism::Program(), qi::locals<GlobalProgramInformation>, Skipper> start;
// Rules for model type.
qi::rule<Iterator, storm::prism::Program::ModelType(), Skipper> modelTypeDefinition;
// Rules for parsing the program header.
qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> programHeader;
qi::rule<Iterator, storm::prism::Constant(), Skipper> undefinedConstantDefinition;
qi::rule<Iterator, storm::prism::Constant(), Skipper> undefinedBooleanConstantDefinition;
qi::rule<Iterator, storm::prism::Constant(), Skipper> undefinedIntegerConstantDefinition;
qi::rule<Iterator, storm::prism::Constant(), Skipper> undefinedDoubleConstantDefinition;
qi::rule<Iterator, storm::prism::Constant(), Skipper> definedConstantDefinition;
qi::rule<Iterator, storm::prism::Constant(), Skipper> definedBooleanConstantDefinition;
qi::rule<Iterator, storm::prism::Constant(), Skipper> definedIntegerConstantDefinition;
qi::rule<Iterator, storm::prism::Constant(), Skipper> definedDoubleConstantDefinition;
// Rules for global variable definitions.
qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> globalVariableDefinition;
qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> globalBooleanVariableDefinition;
qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> globalIntegerVariableDefinition;
// Rules for modules definition.
qi::rule<Iterator, std::vector<storm::prism::Module>(GlobalProgramInformation&), Skipper> moduleDefinitionList;
qi::rule<Iterator, storm::prism::Module(GlobalProgramInformation&), qi::locals<std::vector<storm::prism::BooleanVariable>, std::vector<storm::prism::IntegerVariable>>, Skipper> moduleDefinition;
qi::rule<Iterator, storm::prism::Module(GlobalProgramInformation&), qi::locals<std::map<std::string, std::string>>, Skipper> moduleRenaming;
// Rules for variable definitions.
qi::rule<Iterator, qi::unused_type(std::vector<storm::prism::BooleanVariable>&, std::vector<storm::prism::IntegerVariable>&), Skipper> variableDefinition;
qi::rule<Iterator, storm::prism::BooleanVariable(), Skipper> booleanVariableDefinition;
qi::rule<Iterator, storm::prism::IntegerVariable(), qi::locals<storm::expressions::Expression>, Skipper> integerVariableDefinition;
// Rules for command definitions.
qi::rule<Iterator, storm::prism::Command(GlobalProgramInformation&), qi::locals<std::string>, Skipper> commandDefinition;
qi::rule<Iterator, std::vector<storm::prism::Update>(GlobalProgramInformation&), Skipper> updateListDefinition;
qi::rule<Iterator, storm::prism::Update(GlobalProgramInformation&), Skipper> updateDefinition;
qi::rule<Iterator, std::vector<storm::prism::Assignment>(), Skipper> assignmentDefinitionList;
qi::rule<Iterator, storm::prism::Assignment(), Skipper> assignmentDefinition;
// Rules for reward definitions.
qi::rule<Iterator, storm::prism::RewardModel(), qi::locals<std::string, std::vector<storm::prism::StateReward>, std::vector<storm::prism::TransitionReward>>, Skipper> rewardModelDefinition;
qi::rule<Iterator, storm::prism::StateReward(), Skipper> stateRewardDefinition;
qi::rule<Iterator, storm::prism::TransitionReward(), qi::locals<std::string>, Skipper> transitionRewardDefinition;
// Rules for initial states expression.
qi::rule<Iterator, qi::unused_type(GlobalProgramInformation&), Skipper> initialStatesConstruct;
// Rules for label definitions.
qi::rule<Iterator, storm::prism::Label(), Skipper> labelDefinition;
// Rules for formula definitions.
qi::rule<Iterator, storm::prism::Formula(), Skipper> formulaDefinition;
// Rules for identifier parsing.
qi::rule<Iterator, std::string(), Skipper> identifier;
// Rules for parsing a composed expression.
qi::rule<Iterator, storm::expressions::Expression(), Skipper> expression;
qi::rule<Iterator, storm::expressions::Expression(), Skipper> iteExpression;
qi::rule<Iterator, storm::expressions::Expression(), Skipper> orExpression;
qi::rule<Iterator, storm::expressions::Expression(), Skipper> andExpression;
qi::rule<Iterator, storm::expressions::Expression(), Skipper> relativeExpression;
qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> plusExpression;
qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> multiplicationExpression;
qi::rule<Iterator, storm::expressions::Expression(), Skipper> unaryExpression;
qi::rule<Iterator, storm::expressions::Expression(), Skipper> atomicExpression;
qi::rule<Iterator, storm::expressions::Expression(), Skipper> literalExpression;
qi::rule<Iterator, storm::expressions::Expression(), Skipper> identifierExpression;
qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> minMaxExpression;
qi::rule<Iterator, storm::expressions::Expression(), qi::locals<bool>, Skipper> floorCeilExpression;
// Parser that is used to recognize doubles only (as opposed to Spirit's double_ parser).
boost::spirit::qi::real_parser<double, boost::spirit::qi::strict_real_policies<double>> strict_double;
// Parsers that recognize special keywords and model types.
storm::parser::PrismParser::keywordsStruct keywords_;
storm::parser::PrismParser::modelTypeStruct modelType_;
qi::symbols<char, storm::expressions::Expression> identifiers_;
// Helper methods used in the grammar.
bool isValidIdentifier(std::string const& identifier);
bool addInitialStatesExpression(storm::expressions::Expression initialStatesExpression, GlobalProgramInformation& globalProgramInformation);
storm::expressions::Expression createIteExpression(storm::expressions::Expression e1, storm::expressions::Expression e2, storm::expressions::Expression e3) const;
storm::expressions::Expression createOrExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
storm::expressions::Expression createAndExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
storm::expressions::Expression createGreaterExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
storm::expressions::Expression createGreaterOrEqualExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
storm::expressions::Expression createLessExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
storm::expressions::Expression createLessOrEqualExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
storm::expressions::Expression createEqualsExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
storm::expressions::Expression createNotEqualsExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
storm::expressions::Expression createPlusExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
storm::expressions::Expression createMinusExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
storm::expressions::Expression createMultExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
storm::expressions::Expression createDivExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
storm::expressions::Expression createNotExpression(storm::expressions::Expression e1) const;
storm::expressions::Expression createMinusExpression(storm::expressions::Expression e1) const;
storm::expressions::Expression createTrueExpression() const;
storm::expressions::Expression createFalseExpression() const;
storm::expressions::Expression createDoubleLiteralExpression(double value, bool& pass) const;
storm::expressions::Expression createIntegerLiteralExpression(int value) const;
storm::expressions::Expression createMinimumExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
storm::expressions::Expression createMaximumExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const;
storm::expressions::Expression createFloorExpression(storm::expressions::Expression e1) const;
storm::expressions::Expression createCeilExpression(storm::expressions::Expression e1) const;
storm::expressions::Expression getIdentifierExpression(std::string const& identifier) const;
storm::prism::Constant createUndefinedBooleanConstant(std::string const& newConstant) const;
storm::prism::Constant createUndefinedIntegerConstant(std::string const& newConstant) const;
storm::prism::Constant createUndefinedDoubleConstant(std::string const& newConstant) const;
storm::prism::Constant createDefinedBooleanConstant(std::string const& newConstant, storm::expressions::Expression expression) const;
storm::prism::Constant createDefinedIntegerConstant(std::string const& newConstant, storm::expressions::Expression expression) const;
storm::prism::Constant createDefinedDoubleConstant(std::string const& newConstant, storm::expressions::Expression expression) const;
storm::prism::Formula createFormula(std::string const& formulaName, storm::expressions::Expression expression) const;
storm::prism::Label createLabel(std::string const& labelName, storm::expressions::Expression expression) const;
storm::prism::RewardModel createRewardModel(std::string const& rewardModelName, std::vector<storm::prism::StateReward> const& stateRewards, std::vector<storm::prism::TransitionReward> const& transitionRewards) const;
storm::prism::StateReward createStateReward(storm::expressions::Expression statePredicateExpression, storm::expressions::Expression rewardValueExpression) const;
storm::prism::TransitionReward createTransitionReward(std::string const& actionName, storm::expressions::Expression statePredicateExpression, storm::expressions::Expression rewardValueExpression) const;
storm::prism::Assignment createAssignment(std::string const& variableName, storm::expressions::Expression assignedExpression) const;
storm::prism::Update createUpdate(storm::expressions::Expression likelihoodExpression, std::vector<storm::prism::Assignment> const& assignments, GlobalProgramInformation& globalProgramInformation) const;
storm::prism::Command createCommand(std::string const& actionName, storm::expressions::Expression guardExpression, std::vector<storm::prism::Update> const& updates, GlobalProgramInformation& globalProgramInformation) const;
storm::prism::BooleanVariable createBooleanVariable(std::string const& variableName, storm::expressions::Expression initialValueExpression) const;
storm::prism::IntegerVariable createIntegerVariable(std::string const& variableName, storm::expressions::Expression lowerBoundExpression, storm::expressions::Expression upperBoundExpression, storm::expressions::Expression initialValueExpression) const;
storm::prism::Module createModule(std::string const& moduleName, std::vector<storm::prism::BooleanVariable> const& booleanVariables, std::vector<storm::prism::IntegerVariable> const& integerVariables, std::vector<storm::prism::Command> const& commands, GlobalProgramInformation& globalProgramInformation) const;
storm::prism::Module createRenamedModule(std::string const& newModuleName, std::string const& oldModuleName, std::map<std::string, std::string> const& renaming, GlobalProgramInformation& globalProgramInformation) const;
storm::prism::Program createProgram(GlobalProgramInformation const& globalProgramInformation) const;
};
} // namespace parser
} // namespace storm
#endif /* STORM_PARSER_PRISMPARSER_H_ */
#endif /* STORM_PARSER_PRISMPARSER_H_ */

253
src/parser/prismparser/BaseGrammar.h

@ -1,253 +0,0 @@
/*
* File: Keywords.h
* Author: nafur
*
* Created on April 10, 2013, 6:03 PM
*/
#ifndef BASEGRAMMAR_H
#define BASEGRAMMAR_H
#include "Includes.h"
#include "VariableState.h"
namespace storm {
namespace parser {
namespace prism {
/*!
* This is the base class for all expression grammars.
* It takes care of implementing a singleton, stores a VariableState and implements some common helper routines.
*/
template <typename T>
class BaseGrammar {
public:
/*!
* Constructor.
*/
BaseGrammar(std::shared_ptr<VariableState> const& state) : state(state) {}
/*!
* Create and return a new instance of class T, usually the subclass.
* @param state VariableState to be given to the constructor.
* @returns Instance of class T.
*/
static T& instance(std::shared_ptr<VariableState> const& state = nullptr) {
if (BaseGrammar::instanceObject == nullptr) {
BaseGrammar::instanceObject = std::shared_ptr<T>(new T(state));
if (!state->firstRun) BaseGrammar::instanceObject->secondRun();
}
return *BaseGrammar::instanceObject;
}
/*!
* Clear the cached instance.
*/
static void resetInstance() {
BaseGrammar::instanceObject = nullptr;
}
/*!
* Notify the cached object, that we will begin with the second parsing run.
*/
static void secondRun() {
if (BaseGrammar::instanceObject != nullptr) {
BaseGrammar::instanceObject->prepareSecondRun();
}
}
/*!
* Create a new boolean literal with the given value.
* @param value Value of the literal.
* @returns Boolean literal.
*/
std::shared_ptr<BaseExpression> createBoolLiteral(bool value) {
return std::shared_ptr<BaseExpression>(new BooleanLiteralExpression(value));
}
/*!
* Create a new double literal with the given value.
* @param value Value of the literal.
* @returns Double literal.
*/
std::shared_ptr<BaseExpression> createDoubleLiteral(double value) {
return std::shared_ptr<BaseExpression>(new DoubleLiteralExpression(value));
}
/*!
* Create a new integer literal with the given value.
* @param value Value of the literal.
* @returns Integer literal.
*/
std::shared_ptr<BaseExpression> createIntLiteral(int_fast64_t value) {
return std::shared_ptr<BaseExpression>(new IntegerLiteralExpression(value));
}
/*!
* Create a new plus expression. If addition is true, it will be an addition, otherwise a subtraction.
* @param left Left operand.
* @param addition Flag for addition or subtraction.
* @param right Right operand.
* @param type Return type.
* @returns Plus expression.
*/
std::shared_ptr<BaseExpression> createPlus(std::shared_ptr<BaseExpression> const& left, bool addition, std::shared_ptr<BaseExpression> const& right, BaseExpression::ReturnType type) {
if (addition) {
return std::shared_ptr<BaseExpression>(new BinaryNumericalFunctionExpression(type, left->clone(), right->clone(), BinaryNumericalFunctionExpression::PLUS));
} else {
return std::shared_ptr<BaseExpression>(new BinaryNumericalFunctionExpression(type, left->clone(), right->clone(), BinaryNumericalFunctionExpression::MINUS));
}
}
/*!
* Create a new double plus expression. If addition is true, it will be an addition, otherwise a subtraction.
* @param left Left operand.
* @param addition Flag for addition or subtraction.
* @param right Right operand.
* @returns Double plus expression.
*/
std::shared_ptr<BaseExpression> createDoublePlus(std::shared_ptr<BaseExpression> const& left, bool addition, std::shared_ptr<BaseExpression> const& right) {
return this->createPlus(left, addition, right, BaseExpression::double_);
}
/*!
* Create a new integer plus expression. If addition is true, it will be an addition, otherwise a subtraction.
* @param left Left operand.
* @param addition Flag for addition or subtraction.
* @param right Right operand.
* @returns Integer plus expression.
*/
std::shared_ptr<BaseExpression> createIntPlus(std::shared_ptr<BaseExpression> const& left, bool addition, std::shared_ptr<BaseExpression> const& right) {
return this->createPlus(left, addition, right, BaseExpression::int_);
}
/*!
* Create a new integer multiplication expression.
* @param left Left operand.
* @param right Right operand.
* @returns Integer multiplication expression.
*/
std::shared_ptr<BaseExpression> createIntMult(std::shared_ptr<BaseExpression> const& left, std::shared_ptr<BaseExpression> const& right) {
return std::shared_ptr<BaseExpression>(new BinaryNumericalFunctionExpression(BaseExpression::int_, left->clone(), right->clone(), BinaryNumericalFunctionExpression::TIMES));
}
/*!
* Create a new integer multiplication expression. If multiplication is true, it will be an multiplication, otherwise a division.
* @param left Left operand.
* @param addition Flag for multiplication or division.
* @param right Right operand.
* @returns Integer multiplication expression.
*/
std::shared_ptr<BaseExpression> createDoubleMult(std::shared_ptr<BaseExpression> const& left, bool multiplication, std::shared_ptr<BaseExpression> const& right) {
if (multiplication) {
return std::shared_ptr<BaseExpression>(new BinaryNumericalFunctionExpression(BaseExpression::double_, left->clone(), right->clone(), BinaryNumericalFunctionExpression::TIMES));
} else {
return std::shared_ptr<BaseExpression>(new BinaryNumericalFunctionExpression(BaseExpression::double_, left->clone(), right->clone(), BinaryNumericalFunctionExpression::DIVIDE));
}
}
/*!
* Creates an integer min/max expression.
*
* @param min Indicates whether the expression is min or max.
* @param left The left operand.
* @param right The right operand.
* @return An integer min/max expression.
*/
std::shared_ptr<BaseExpression> createIntMinMax(bool min, std::shared_ptr<BaseExpression> const& left, std::shared_ptr<BaseExpression> const& right) {
if (min) {
return std::shared_ptr<BaseExpression>(new BinaryNumericalFunctionExpression(BaseExpression::int_, left->clone(), right->clone(), BinaryNumericalFunctionExpression::MIN));
} else {
return std::shared_ptr<BaseExpression>(new BinaryNumericalFunctionExpression(BaseExpression::int_, left->clone(), right->clone(), BinaryNumericalFunctionExpression::MAX));
}
}
/*!
* Creates an integer floor/ceil expression.
*
* @param floor Indicates whether the expression is a floor expression.
* @param operand The argument of the floor/ceil operation.
* @return An integer floor/ceil expression.
*/
std::shared_ptr<BaseExpression> createIntFloorCeil(bool floor, std::shared_ptr<BaseExpression> const& operand) {
if (floor) {
return std::shared_ptr<BaseExpression>(new UnaryNumericalFunctionExpression(BaseExpression::int_, operand->clone(), UnaryNumericalFunctionExpression::FLOOR));
} else {
return std::shared_ptr<BaseExpression>(new UnaryNumericalFunctionExpression(BaseExpression::int_, operand->clone(), UnaryNumericalFunctionExpression::CEIL));
}
}
/*!
* Create a new binary relation expression.
* @param left Left operand.
* @param relationType Type of binary relation.
* @param right Right operand.
* @returns Binary relation expression.
*/
std::shared_ptr<BaseExpression> createRelation(std::shared_ptr<BaseExpression> const& left, BinaryRelationExpression::RelationType relationType, std::shared_ptr<BaseExpression> const& right) {
return std::shared_ptr<BaseExpression>(new BinaryRelationExpression(left->clone(), right->clone(), relationType));
}
/*!
* Create a new negation expression.
* @param child Expression to be negated.
* @returns Negation expression.
*/
std::shared_ptr<BaseExpression> createNot(std::shared_ptr<BaseExpression> const& child) {
return std::shared_ptr<UnaryBooleanFunctionExpression>(new UnaryBooleanFunctionExpression(child->clone(), UnaryBooleanFunctionExpression::NOT));
}
/*!
* Create a new And expression.
* @param left Left operand.
* @param right Right operand.
* @returns And expression.
*/
std::shared_ptr<BaseExpression> createAnd(std::shared_ptr<BaseExpression> const& left, std::shared_ptr<BaseExpression> const& right) {
return std::shared_ptr<BaseExpression>(new BinaryBooleanFunctionExpression(left->clone(), right->clone(), BinaryBooleanFunctionExpression::AND));
}
/*!
* Create a new Or expression.
* @param left Left operand.
* @param right Right operand.
* @returns Or expression.
*/
std::shared_ptr<BaseExpression> createOr(std::shared_ptr<BaseExpression> const& left, std::shared_ptr<BaseExpression> const& right) {
return std::shared_ptr<BinaryBooleanFunctionExpression>(new BinaryBooleanFunctionExpression(left->clone(), right->clone(), BinaryBooleanFunctionExpression::OR));
}
/*!
* Retrieve boolean variable by name.
* @param name Variable name.
* @returns Boolean variable.
*/
std::shared_ptr<BaseExpression> getBoolVariable(std::string const& name) {
return std::shared_ptr<BaseExpression>(new VariableExpression(*state->getBooleanVariableExpression(name)));
}
/*!
* Retrieve integer variable by name.
* @param name Variable name.
* @returns Integer variable.
*/
std::shared_ptr<BaseExpression> getIntVariable(std::string const& name) {
return std::shared_ptr<BaseExpression>(new VariableExpression(*state->getIntegerVariableExpression(name)));
}
/*!
* Base method to switch to second run. This does nothing.
* Any subclass that needs to do something in order to proceed to the second run should override this method.
*/
virtual void prepareSecondRun() {}
protected:
/*!
* Pointer to variable state.
*/
std::shared_ptr<VariableState> state;
private:
static std::shared_ptr<T> instanceObject;
static bool inSecondRun;
};
template <typename T>
std::shared_ptr<T> BaseGrammar<T>::instanceObject;
}
}
}
#endif /* BASEGRAMMAR_H */

42
src/parser/prismparser/BooleanExpressionGrammar.cpp

@ -1,42 +0,0 @@
#include "BooleanExpressionGrammar.h"
#include "IntegerExpressionGrammar.h"
#include "ConstBooleanExpressionGrammar.h"
namespace storm {
namespace parser {
namespace prism {
BooleanExpressionGrammar::BooleanExpressionGrammar(std::shared_ptr<VariableState> const& state)
: BooleanExpressionGrammar::base_type(booleanExpression), BaseGrammar(state) {
booleanExpression %= orExpression;
booleanExpression.name("boolean expression");
orExpression = andExpression[qi::_val = qi::_1] >> *(qi::lit("|") >> andExpression)[qi::_val = phoenix::bind(&BaseGrammar::createOr, this, qi::_val, qi::_1)];
orExpression.name("boolean expression");
andExpression = notExpression[qi::_val = qi::_1] >> *(qi::lit("&") >> notExpression)[qi::_val = phoenix::bind(&BaseGrammar::createAnd, this, qi::_val, qi::_1)];
andExpression.name("boolean expression");
notExpression = atomicBooleanExpression[qi::_val = qi::_1] | (qi::lit("!") >> atomicBooleanExpression)[qi::_val = phoenix::bind(&BaseGrammar::createNot, this, qi::_1)];
notExpression.name("boolean expression");
atomicBooleanExpression %= (relativeExpression | booleanVariableExpression | this->state->constantBooleanFormulas_ | this->state->booleanFormulas_ | qi::lit("(") >> booleanExpression >> qi::lit(")") | ConstBooleanExpressionGrammar::instance(this->state));
atomicBooleanExpression.name("boolean expression");
relativeExpression = (IntegerExpressionGrammar::instance(this->state) >> relations_ >> IntegerExpressionGrammar::instance(this->state))[qi::_val = phoenix::bind(&BaseGrammar::createRelation, this, qi::_1, qi::_2, qi::_3)];
relativeExpression.name("relative expression");
booleanVariableExpression = IdentifierGrammar::instance(this->state)[qi::_val = phoenix::bind(&BaseGrammar::getBoolVariable, this, qi::_1)];
booleanVariableExpression.name("boolean variable");
}
void BooleanExpressionGrammar::prepareSecondRun() {
booleanVariableExpression %= this->state->booleanVariables_;
booleanVariableExpression.name("boolean variable");
}
} // namespace prism
} // namespace parser
} // namespace storm

54
src/parser/prismparser/BooleanExpressionGrammar.h

@ -1,54 +0,0 @@
/*
* File: BooleanExpressionGrammar.h
* Author: nafur
*
* Created on April 10, 2013, 6:27 PM
*/
#ifndef BOOLEANEXPRESSIONGRAMMAR_H
#define BOOLEANEXPRESSIONGRAMMAR_H
#include "Includes.h"
#include "VariableState.h"
#include "IdentifierGrammars.h"
#include "Tokens.h"
#include <iostream>
namespace storm {
namespace parser {
namespace prism {
/*!
* This grammar parses (non constant) boolean expressions as used in prism models.
*/
class BooleanExpressionGrammar : public qi::grammar<Iterator, std::shared_ptr<BaseExpression>(), Skipper, Unused>, public BaseGrammar<BooleanExpressionGrammar> {
public:
BooleanExpressionGrammar(std::shared_ptr<VariableState> const& state);
/*!
* Switch to second run.
* Variable names may be any valid identifier in the first run, but only defined variables in the second run.
*/
virtual void prepareSecondRun();
private:
qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper, Unused> booleanExpression;
qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> orExpression;
qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> andExpression;
qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> notExpression;
qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> atomicBooleanExpression;
qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> relativeExpression;
qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> booleanVariableExpression;
/*!
* Parser relation operators.
*/
storm::parser::prism::relationalOperatorStruct relations_;
};
}
}
}
#endif /* BOOLEANEXPRESSIONGRAMMAR_H */

38
src/parser/prismparser/ConstBooleanExpressionGrammar.cpp

@ -1,38 +0,0 @@
#include "ConstBooleanExpressionGrammar.h"
#include "ConstIntegerExpressionGrammar.h"
namespace storm {
namespace parser {
namespace prism {
ConstBooleanExpressionGrammar::ConstBooleanExpressionGrammar(std::shared_ptr<VariableState> const& state)
: ConstBooleanExpressionGrammar::base_type(constantBooleanExpression), BaseGrammar(state) {
constantBooleanExpression %= constantOrExpression;
constantBooleanExpression.name("constant boolean expression");
constantOrExpression = constantAndExpression[qi::_val = qi::_1] >> *(qi::lit("|") >> constantAndExpression)[qi::_val = phoenix::bind(&BaseGrammar::createOr, this, qi::_val, qi::_1)];
constantOrExpression.name("constant boolean expression");
constantAndExpression = constantNotExpression[qi::_val = qi::_1] >> *(qi::lit("&") >> constantNotExpression)[qi::_val = phoenix::bind(&BaseGrammar::createAnd, this, qi::_val, qi::_1)];
constantAndExpression.name("constant boolean expression");
constantNotExpression = constantAtomicBooleanExpression[qi::_val = qi::_1] | (qi::lit("!") >> constantAtomicBooleanExpression)[qi::_val = phoenix::bind(&BaseGrammar::createNot, this, qi::_1)];
constantNotExpression.name("constant boolean expression");
constantAtomicBooleanExpression %= (constantRelativeExpression | this->state->constantBooleanFormulas_ | qi::lit("(") >> constantBooleanExpression >> qi::lit(")") | booleanLiteralExpression | booleanConstantExpression);
constantAtomicBooleanExpression.name("constant boolean expression");
constantRelativeExpression = (ConstIntegerExpressionGrammar::instance(this->state) >> relations_ >> ConstIntegerExpressionGrammar::instance(this->state))[qi::_val = phoenix::bind(&BaseGrammar::createRelation, this, qi::_1, qi::_2, qi::_3)];
constantRelativeExpression.name("constant boolean expression");
booleanConstantExpression %= (this->state->booleanConstants_ | booleanLiteralExpression);
booleanConstantExpression.name("boolean constant or literal");
booleanLiteralExpression = qi::bool_[qi::_val = phoenix::bind(&BaseGrammar::createBoolLiteral, this, qi::_1)];
booleanLiteralExpression.name("boolean literal");
}
}
}
}

47
src/parser/prismparser/ConstBooleanExpressionGrammar.h

@ -1,47 +0,0 @@
/*
* File: ConstBooleanExpressionGrammar.h
* Author: nafur
*
* Created on April 10, 2013, 6:34 PM
*/
#ifndef CONSTBOOLEANEXPRESSIONGRAMMAR_H
#define CONSTBOOLEANEXPRESSIONGRAMMAR_H
#include "Includes.h"
#include "VariableState.h"
#include "IdentifierGrammars.h"
#include "Tokens.h"
namespace storm {
namespace parser {
namespace prism {
/*!
* This grammar parses constant boolean expression as used in prism models.
*/
class ConstBooleanExpressionGrammar : public qi::grammar<Iterator, std::shared_ptr<BaseExpression>(), Skipper, Unused>, public BaseGrammar<ConstBooleanExpressionGrammar> {
public:
ConstBooleanExpressionGrammar(std::shared_ptr<VariableState> const& state);
private:
qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper, Unused> constantBooleanExpression;
qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> constantOrExpression;
qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> constantAndExpression;
qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> constantNotExpression;
qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> constantAtomicBooleanExpression;
qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> constantRelativeExpression;
qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> booleanConstantExpression;
qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> booleanLiteralExpression;
storm::parser::prism::relationalOperatorStruct relations_;
};
}
}
}
#endif /* CONSTBOOLEANEXPRESSIONGRAMMAR_H */

34
src/parser/prismparser/ConstDoubleExpressionGrammar.cpp

@ -1,34 +0,0 @@
#include "ConstDoubleExpressionGrammar.h"
namespace storm {
namespace parser {
namespace prism {
ConstDoubleExpressionGrammar::ConstDoubleExpressionGrammar(std::shared_ptr<VariableState> const& state)
: ConstDoubleExpressionGrammar::base_type(constantDoubleExpression), BaseGrammar(state) {
constantDoubleExpression %= constantDoublePlusExpression;
constantDoubleExpression.name("constant double expression");
constantDoublePlusExpression %= constantDoubleMultExpression[qi::_val = qi::_1] >> *((qi::lit("+")[qi::_a = true] | qi::lit("-")[qi::_a = false]) >> constantDoubleMultExpression)
[qi::_val = phoenix::bind(&BaseGrammar::createDoublePlus, this, qi::_val, qi::_a, qi::_1)];
constantDoublePlusExpression.name("constant double expression");
constantDoubleMultExpression %= constantAtomicDoubleExpression[qi::_val = qi::_1] >> *((qi::lit("*")[qi::_a = true] | qi::lit("/")[qi::_a = false]) >> constantAtomicDoubleExpression)
[qi::_val = phoenix::bind(&BaseGrammar::createDoubleMult, this, qi::_val, qi::_a, qi::_1)];
constantDoubleMultExpression.name("constant double expression");
constantAtomicDoubleExpression %= (qi::lit("(") >> constantDoubleExpression >> qi::lit(")") | this->state->constantDoubleFormulas_ | this->state->constantIntegerFormulas_ | doubleConstantExpression);
constantAtomicDoubleExpression.name("constant double expression");
doubleConstantExpression %= (this->state->doubleConstants_ | this->state->integerConstants_ | doubleLiteralExpression);
doubleConstantExpression.name("double constant or literal");
doubleLiteralExpression = qi::double_[qi::_val = phoenix::bind(&BaseGrammar::createDoubleLiteral, this, qi::_1)];
doubleLiteralExpression.name("double literal");
}
}
}
}

41
src/parser/prismparser/ConstDoubleExpressionGrammar.h

@ -1,41 +0,0 @@
/*
* File: ConstDoubleExpressionGrammar.h
* Author: nafur
*
* Created on April 10, 2013, 7:04 PM
*/
#ifndef CONSTDOUBLEEXPRESSIONGRAMMAR_H
#define CONSTDOUBLEEXPRESSIONGRAMMAR_H
#include "Includes.h"
#include "VariableState.h"
#include "IdentifierGrammars.h"
namespace storm {
namespace parser {
namespace prism {
/*!
* This grammar parses constant double expressions as used in prism models.
*/
class ConstDoubleExpressionGrammar : public qi::grammar<Iterator, std::shared_ptr<BaseExpression>(), Skipper, Unused>, public BaseGrammar<ConstDoubleExpressionGrammar> {
public:
ConstDoubleExpressionGrammar(std::shared_ptr<VariableState> const& state);
private:
qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper, Unused> constantDoubleExpression;
qi::rule<Iterator, std::shared_ptr<BaseExpression>(), qi::locals<bool>, Skipper> constantDoublePlusExpression;
qi::rule<Iterator, std::shared_ptr<BaseExpression>(), qi::locals<bool>, Skipper> constantDoubleMultExpression;
qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> constantAtomicDoubleExpression;
qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> doubleConstantExpression;
qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> doubleLiteralExpression;
};
}
}
}
#endif /* CONSTDOUBLEEXPRESSIONGRAMMAR_H */

41
src/parser/prismparser/ConstIntegerExpressionGrammar.cpp

@ -1,41 +0,0 @@
#include "ConstIntegerExpressionGrammar.h"
namespace storm {
namespace parser {
namespace prism {
ConstIntegerExpressionGrammar::ConstIntegerExpressionGrammar(std::shared_ptr<VariableState> const& state)
: ConstIntegerExpressionGrammar::base_type(constantIntegerExpression), BaseGrammar(state) {
constantIntegerExpression %= constantIntegerPlusExpression;
constantIntegerExpression.name("constant integer expression");
constantIntegerPlusExpression = constantIntegerMultExpression[qi::_val = qi::_1] >> *((qi::lit("+")[qi::_a = true] | qi::lit("-")[qi::_a = false]) >> constantIntegerMultExpression)
[qi::_val = phoenix::bind(&BaseGrammar::createIntPlus, this, qi::_val, qi::_a, qi::_1)];
constantIntegerPlusExpression.name("constant integer expression");
constantIntegerMultExpression %= constantAtomicIntegerExpression[qi::_val = qi::_1] >> *(qi::lit("*") >> constantAtomicIntegerExpression)
[qi::_val = phoenix::bind(&BaseGrammar::createIntMult, this, qi::_val, qi::_1)];
constantIntegerMultExpression.name("constant integer expression");
constantAtomicIntegerExpression %= (constantIntegerMinMaxExpression | constantIntegerFloorCeilExpression | this->state->constantIntegerFormulas_ | qi::lit("(") >> constantIntegerExpression >> qi::lit(")") | integerConstantExpression);
constantAtomicIntegerExpression.name("constant integer expression");
constantIntegerMinMaxExpression = ((qi::lit("min")[qi::_a = true] | qi::lit("max")[qi::_a = false]) >> qi::lit("(") >> constantIntegerExpression >> qi::lit(",") >> constantIntegerExpression >> qi::lit(")"))[qi::_val = phoenix::bind(&BaseGrammar::createIntMinMax, this, qi::_a, qi::_1, qi::_2)];
constantIntegerMinMaxExpression.name("integer min/max expression");
constantIntegerFloorCeilExpression = ((qi::lit("floor")[qi::_a = true] | qi::lit("ceil")[qi::_a = false]) >> qi::lit("(") >> constantIntegerExpression >> qi::lit(")"))[qi::_val = phoenix::bind(&BaseGrammar::createIntFloorCeil, this, qi::_a, qi::_1)];
constantIntegerFloorCeilExpression.name("integer floor/ceil expression");
integerConstantExpression %= (this->state->integerConstants_ | integerLiteralExpression);
integerConstantExpression.name("integer constant or literal");
integerLiteralExpression = qi::int_[qi::_val = phoenix::bind(&BaseGrammar::createIntLiteral, this, qi::_1)];
integerLiteralExpression.name("integer literal");
}
} // namespace prism
} // namespace parser
} // namespace storm

42
src/parser/prismparser/ConstIntegerExpressionGrammar.h

@ -1,42 +0,0 @@
/*
* File: ConstIntegerExpressionGrammar.h
* Author: nafur
*
* Created on April 10, 2013, 6:02 PM
*/
#ifndef CONSTINTEGEREXPRESSIONGRAMMAR_H
#define CONSTINTEGEREXPRESSIONGRAMMAR_H
#include "Includes.h"
#include "VariableState.h"
#include "IdentifierGrammars.h"
namespace storm {
namespace parser {
namespace prism {
/*!
* This grammar parses constant integer expressions as used in prism models.
*/
class ConstIntegerExpressionGrammar : public qi::grammar<Iterator, std::shared_ptr<BaseExpression>(), Skipper, Unused>, public BaseGrammar<ConstIntegerExpressionGrammar> {
public:
ConstIntegerExpressionGrammar(std::shared_ptr<VariableState> const& state);
private:
qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper, Unused> constantIntegerExpression;
qi::rule<Iterator, std::shared_ptr<BaseExpression>(), qi::locals<bool>, Skipper> constantIntegerPlusExpression;
qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> constantIntegerMultExpression;
qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> constantAtomicIntegerExpression;
qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> integerConstantExpression;
qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> integerLiteralExpression;
qi::rule<Iterator, std::shared_ptr<BaseExpression>(), qi::locals<bool>, Skipper> constantIntegerMinMaxExpression;
qi::rule<Iterator, std::shared_ptr<BaseExpression>(), qi::locals<bool>, Skipper> constantIntegerFloorCeilExpression;
};
}
}
}
#endif /* CONSTINTEGEREXPRESSIONGRAMMAR_H */

23
src/parser/prismparser/IdentifierGrammars.cpp

@ -1,23 +0,0 @@
#include "IdentifierGrammars.h"
namespace storm {
namespace parser {
namespace prism {
IdentifierGrammar::IdentifierGrammar(std::shared_ptr<VariableState> const& state)
: IdentifierGrammar::base_type(identifierName), BaseGrammar(state) {
identifierName %= qi::as_string[qi::raw[qi::lexeme[((qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_')))]]][ qi::_pass = phoenix::bind(&VariableState::isIdentifier, this->state.get(), qi::_1) ];
identifierName.name("identifier");
}
FreeIdentifierGrammar::FreeIdentifierGrammar(std::shared_ptr<VariableState> const& state)
: FreeIdentifierGrammar::base_type(freeIdentifierName), BaseGrammar(state) {
freeIdentifierName %= qi::as_string[qi::raw[qi::lexeme[((qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_')))]]][ qi::_pass = phoenix::bind(&VariableState::isFreeIdentifier, this->state.get(), qi::_1) ];
freeIdentifierName.name("identifier");
}
}
}
}

42
src/parser/prismparser/IdentifierGrammars.h

@ -1,42 +0,0 @@
/*
* File: Keywords.h
* Author: nafur
*
* Created on April 10, 2013, 6:03 PM
*/
#ifndef IDENTIFIERGRAMMARS_H
#define IDENTIFIERGRAMMARS_H
#include "Includes.h"
#include "BaseGrammar.h"
#include "VariableState.h"
namespace storm {
namespace parser {
namespace prism {
/*!
* This grammar parses a (possibly used) identifier as used in a prism models.
*/
class IdentifierGrammar : public qi::grammar<Iterator, std::string(), Skipper, Unused>, public BaseGrammar<IdentifierGrammar> {
public:
IdentifierGrammar(std::shared_ptr<VariableState> const& state);
private:
qi::rule<Iterator, std::string(), Skipper> identifierName;
};
/*!
* This grammar parses an used identifier as used in a prism models.
*/
class FreeIdentifierGrammar : public qi::grammar<Iterator, std::string(), Skipper, Unused>, public BaseGrammar<IdentifierGrammar> {
public:
FreeIdentifierGrammar(std::shared_ptr<VariableState> const& state);
private:
qi::rule<Iterator, std::string(), Skipper> freeIdentifierName;
};
}
}
}
#endif /* IDENTIFIERGRAMMARS_H */

39
src/parser/prismparser/Includes.h

@ -1,39 +0,0 @@
/*
* File: Includes
* Author: Gereon Kremer
*
* Created on April 10, 2013, 4:46 PM
*/
#ifndef BOOSTINCLUDES_H
#define BOOSTINCLUDES_H
// Used for Boost spirit.
#include <boost/typeof/typeof.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
// Include headers for spirit iterators. Needed for diagnostics and input stream iteration.
#include <boost/spirit/include/classic_position_iterator.hpp>
#include <boost/spirit/include/support_multi_pass.hpp>
namespace qi = boost::spirit::qi;
namespace phoenix = boost::phoenix;
typedef std::string::const_iterator BaseIteratorType;
typedef boost::spirit::classic::position_iterator2<BaseIteratorType> PositionIteratorType;
typedef PositionIteratorType Iterator;
typedef BOOST_TYPEOF(boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol) Skipper;
typedef BOOST_TYPEOF(qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol | boost::spirit::ascii::space) Skipper2;
typedef boost::spirit::unused_type Unused;
#include "src/ir/IR.h"
using namespace storm::ir;
using namespace storm::ir::expressions;
#include "log4cplus/logger.h"
#include "log4cplus/loggingmacros.h"
extern log4cplus::Logger logger;
#endif /* BOOSTINCLUDES_H */

42
src/parser/prismparser/IntegerExpressionGrammar.cpp

@ -1,42 +0,0 @@
#include "IntegerExpressionGrammar.h"
#include "IdentifierGrammars.h"
#include "ConstIntegerExpressionGrammar.h"
namespace storm {
namespace parser {
namespace prism {
IntegerExpressionGrammar::IntegerExpressionGrammar(std::shared_ptr<VariableState> const& state)
: IntegerExpressionGrammar::base_type(integerExpression), BaseGrammar(state) {
integerExpression %= integerPlusExpression;
integerExpression.name("integer expression");
integerPlusExpression = integerMultExpression[qi::_val = qi::_1] >> *((qi::lit("+")[qi::_a = true] | qi::lit("-")[qi::_a = false]) >> integerMultExpression)[qi::_val = phoenix::bind(&BaseGrammar::createIntPlus, this, qi::_val, qi::_a, qi::_1)];
integerPlusExpression.name("integer expression");
integerMultExpression %= atomicIntegerExpression[qi::_val = qi::_1] >> *(qi::lit("*") >> atomicIntegerExpression[qi::_val = phoenix::bind(&BaseGrammar::createIntMult, this, qi::_val, qi::_1)]);
integerMultExpression.name("integer expression");
atomicIntegerExpression %= (integerMinMaxExpression | integerFloorCeilExpression | this->state->constantIntegerFormulas_ | this->state->integerFormulas_ | qi::lit("(") >> integerExpression >> qi::lit(")") | integerVariableExpression | ConstIntegerExpressionGrammar::instance(this->state));
atomicIntegerExpression.name("integer expression");
integerMinMaxExpression = ((qi::lit("min")[qi::_a = true] | qi::lit("max")[qi::_a = false]) >> qi::lit("(") >> integerExpression >> qi::lit(",") >> integerExpression >> qi::lit(")"))[qi::_val = phoenix::bind(&BaseGrammar::createIntMinMax, this, qi::_a, qi::_1, qi::_2)];
integerMinMaxExpression.name("integer min/max expression");
integerFloorCeilExpression = ((qi::lit("floor")[qi::_a = true] | qi::lit("ceil")[qi::_a = false]) >> qi::lit("(") >> integerExpression >> qi::lit(")"))[qi::_val = phoenix::bind(&BaseGrammar::createIntFloorCeil, this, qi::_a, qi::_1)];
integerFloorCeilExpression.name("integer floor/ceil expression");
integerVariableExpression = IdentifierGrammar::instance(this->state)[qi::_val = phoenix::bind(&BaseGrammar::getIntVariable, this, qi::_1)];
integerVariableExpression.name("integer variable");
}
void IntegerExpressionGrammar::prepareSecondRun() {
integerVariableExpression %= this->state->integerVariables_;
integerVariableExpression.name("integer variable");
}
}
}
}

50
src/parser/prismparser/IntegerExpressionGrammar.h

@ -1,50 +0,0 @@
/*
* File: IntegerExpressionGrammar.h
* Author: nafur
*
* Created on April 10, 2013, 4:39 PM
*/
#ifndef INTEGEREXPRESSIONGRAMMAR_H
#define INTEGEREXPRESSIONGRAMMAR_H
#include "src/ir/IR.h"
#include "VariableState.h"
#include "Includes.h"
#include "IdentifierGrammars.h"
#include <memory>
namespace storm {
namespace parser {
namespace prism {
/*!
* This grammar parses a (non constant) integer expressions as used in prism models.
*/
class IntegerExpressionGrammar : public qi::grammar<Iterator, std::shared_ptr<BaseExpression>(), Skipper, Unused>, public BaseGrammar<IntegerExpressionGrammar> {
public:
IntegerExpressionGrammar(std::shared_ptr<VariableState> const& state);
/*!
* Switch to second run.
* Variable names may be any valid identifier in the first run, but only defined variables in the second run.
*/
virtual void prepareSecondRun();
private:
qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper, Unused> integerExpression;
qi::rule<Iterator, std::shared_ptr<BaseExpression>(), qi::locals<bool>, Skipper> integerPlusExpression;
qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> integerMultExpression;
qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> atomicIntegerExpression;
qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> integerVariableExpression;
qi::rule<Iterator, std::shared_ptr<BaseExpression>(), qi::locals<bool>, Skipper> integerMinMaxExpression;
qi::rule<Iterator, std::shared_ptr<BaseExpression>(), qi::locals<bool>, Skipper> integerFloorCeilExpression;
};
}
}
}
#endif /* INTEGEREXPRESSIONGRAMMAR_H */

295
src/parser/prismparser/PrismGrammar.cpp

@ -1,295 +0,0 @@
/*
* PrismGrammar.cpp
*
* Created on: 11.01.2013
* Author: chris
*/
// Needed for file IO.
#include <fstream>
#include <iomanip>
#include <limits>
#include "PrismGrammar.h"
#include "src/utility/OsDetection.h"
#include "src/parser/prismparser/Includes.h"
#include "src/parser/prismparser/BooleanExpressionGrammar.h"
#include "src/parser/prismparser/ConstBooleanExpressionGrammar.h"
#include "src/parser/prismparser/ConstDoubleExpressionGrammar.h"
#include "src/parser/prismparser/ConstIntegerExpressionGrammar.h"
#include "src/parser/prismparser/IntegerExpressionGrammar.h"
#include "src/parser/prismparser/IdentifierGrammars.h"
#include "src/parser/prismparser/VariableState.h"
#include "src/exceptions/InvalidArgumentException.h"
#include "log4cplus/logger.h"
#include "log4cplus/loggingmacros.h"
extern log4cplus::Logger logger;
// Some typedefs and namespace definitions to reduce code size.
typedef std::string::const_iterator BaseIteratorType;
typedef boost::spirit::classic::position_iterator2<BaseIteratorType> PositionIteratorType;
namespace qi = boost::spirit::qi;
namespace phoenix = boost::phoenix;
namespace storm {
namespace parser {
namespace prism {
void PrismGrammar::addLabel(std::string const& name, std::shared_ptr<BaseExpression> const& value, std::map<std::string, std::unique_ptr<BaseExpression>>& nameToExpressionMap) {
this->state->labelNames_.add(name, name);
nameToExpressionMap[name] = value->clone();
}
void PrismGrammar::addIntegerAssignment(std::string const& variable, std::shared_ptr<BaseExpression> const& value, std::map<std::string, Assignment>& variableToAssignmentMap) {
this->state->assignedIntegerVariables_.add(variable, variable);
variableToAssignmentMap[variable] = Assignment(variable, value->clone());
}
void PrismGrammar::addBooleanAssignment(std::string const& variable, std::shared_ptr<BaseExpression> const& value, std::map<std::string, Assignment>& variableToAssigmentMap) {
this->state->assignedBooleanVariables_.add(variable, variable);
variableToAssigmentMap[variable] = Assignment(variable, value->clone());
}
void PrismGrammar::addUndefinedBooleanConstant(std::string const& name, std::map<std::string, std::unique_ptr<BooleanConstantExpression>>& nameToExpressionMap) {
this->state->booleanConstants_.add(name, std::shared_ptr<BaseExpression>(new BooleanConstantExpression(name)));
this->state->allConstantNames_.add(name, name);
nameToExpressionMap.emplace(name, std::unique_ptr<BooleanConstantExpression>(new BooleanConstantExpression(dynamic_cast<BooleanConstantExpression&>(*this->state->booleanConstants_.at(name)))));
}
void PrismGrammar::addUndefinedIntegerConstant(std::string const& name, std::map<std::string, std::unique_ptr<IntegerConstantExpression>>& nameToExpressionMap) {
this->state->integerConstants_.add(name, std::shared_ptr<BaseExpression>(new IntegerConstantExpression(name)));
this->state->allConstantNames_.add(name, name);
nameToExpressionMap.emplace(name, std::unique_ptr<IntegerConstantExpression>(new IntegerConstantExpression(dynamic_cast<IntegerConstantExpression&>(*this->state->integerConstants_.at(name)))));
}
void PrismGrammar::addUndefinedDoubleConstant(std::string const& name, std::map<std::string, std::unique_ptr<DoubleConstantExpression>>& nameToExpressionMap) {
this->state->doubleConstants_.add(name, std::shared_ptr<BaseExpression>(new DoubleConstantExpression(name)));
this->state->allConstantNames_.add(name, name);
nameToExpressionMap.emplace(name, std::unique_ptr<DoubleConstantExpression>(new DoubleConstantExpression(dynamic_cast<DoubleConstantExpression&>(*this->state->doubleConstants_.at(name)))));
}
Module PrismGrammar::renameModule(std::string const& newName, std::string const& oldName, std::map<std::string, std::string> const& renaming) {
this->state->moduleNames_.add(newName, newName);
Module* old = this->moduleMap_.find(oldName);
if (old == nullptr) {
LOG4CPLUS_ERROR(logger, "Renaming module failed: module " << oldName << " does not exist.");
throw storm::exceptions::InvalidArgumentException() << "Renaming module failed: module " << oldName << " does not exist.";
}
Module res(*old, newName, renaming, *this->state);
this->moduleMap_.at(newName) = res;
return res;
}
Module PrismGrammar::createModule(std::string const& name, std::vector<BooleanVariable> const& bools, std::vector<IntegerVariable> const& ints, std::map<std::string, uint_fast64_t> const& boolids, std::map<std::string, uint_fast64_t> const& intids, std::vector<storm::ir::Command> const& commands) {
this->state->moduleNames_.add(name, name);
Module res(name, bools, ints, boolids, intids, commands);
this->moduleMap_.at(name) = res;
return res;
}
void PrismGrammar::createIntegerVariable(std::string const& name, std::shared_ptr<BaseExpression> const& lower, std::shared_ptr<BaseExpression> const& upper, std::shared_ptr<BaseExpression> const& init, std::vector<IntegerVariable>& vars, std::map<std::string, uint_fast64_t>& varids, bool isGlobalVariable) {
uint_fast64_t id = this->state->addIntegerVariable(name);
uint_fast64_t newLocalIndex = this->state->nextLocalIntegerVariableIndex;
vars.emplace_back(newLocalIndex, id, name, lower != nullptr ? lower->clone() : nullptr, upper != nullptr ? upper->clone() : nullptr, init != nullptr ? init->clone() : nullptr);
varids[name] = newLocalIndex;
++this->state->nextLocalIntegerVariableIndex;
this->state->localIntegerVariables_.add(name, name);
if (isGlobalVariable) {
this->state->globalIntegerVariables_.add(name, name);
}
}
void PrismGrammar::createBooleanVariable(std::string const& name, std::shared_ptr<BaseExpression> const& init, std::vector<BooleanVariable>& vars, std::map<std::string, uint_fast64_t>& varids, bool isGlobalVariable) {
uint_fast64_t id = this->state->addBooleanVariable(name);
uint_fast64_t newLocalIndex = this->state->nextLocalBooleanVariableIndex;
vars.emplace_back(newLocalIndex, id, name, init != nullptr ? init->clone() : nullptr);
varids[name] = newLocalIndex;
++this->state->nextLocalBooleanVariableIndex;
this->state->localBooleanVariables_.add(name, name);
if (isGlobalVariable) {
this->state->globalBooleanVariables_.add(name, name);
}
}
StateReward createStateReward(std::shared_ptr<BaseExpression> const& guard, std::shared_ptr<BaseExpression> const& reward) {
return StateReward(guard->clone(), reward->clone());
}
TransitionReward createTransitionReward(std::string const& label, std::shared_ptr<BaseExpression> const& guard, std::shared_ptr<BaseExpression> const& reward) {
return TransitionReward(label, guard->clone(), reward->clone());
}
void createRewardModel(std::string const& name, std::vector<StateReward>& stateRewards, std::vector<TransitionReward>& transitionRewards, std::map<std::string, RewardModel>& mapping) {
mapping[name] = RewardModel(name, stateRewards, transitionRewards);
}
Update PrismGrammar::createUpdate(std::shared_ptr<BaseExpression> const& likelihood, std::map<std::string, Assignment> const& bools, std::map<std::string, Assignment> const& ints) {
this->state->nextGlobalUpdateIndex++;
return Update(this->state->getNextGlobalUpdateIndex() - 1, likelihood != nullptr ? likelihood->clone() : nullptr, bools, ints);
}
Command PrismGrammar::createCommand(std::string const& label, std::shared_ptr<BaseExpression> const& guard, std::vector<Update> const& updates) {
this->state->nextGlobalCommandIndex++;
return Command(this->state->getNextGlobalCommandIndex() - 1, label, guard->clone(), updates);
}
Program createProgram(
Program::ModelType modelType,
std::map<std::string, std::unique_ptr<BooleanConstantExpression>> const& undefBoolConst,
std::map<std::string, std::unique_ptr<IntegerConstantExpression>> const& undefIntConst,
std::map<std::string, std::unique_ptr<DoubleConstantExpression>> const& undefDoubleConst,
GlobalVariableInformation const& globalVariableInformation,
std::vector<Module> const& modules,
std::map<std::string, RewardModel> const& rewards,
std::map<std::string, std::unique_ptr<BaseExpression>> const& labels) {
return Program(modelType, undefBoolConst, undefIntConst, undefDoubleConst,
globalVariableInformation.booleanVariables, globalVariableInformation.integerVariables,
globalVariableInformation.booleanVariableToIndexMap,
globalVariableInformation.integerVariableToIndexMap, modules, rewards, labels);
}
PrismGrammar::PrismGrammar() : PrismGrammar::base_type(start), state(new VariableState()) {
labelDefinition = (qi::lit("label") >> -qi::lit("\"") >> FreeIdentifierGrammar::instance(this->state) >> -qi::lit("\"") >> qi::lit("=") >> BooleanExpressionGrammar::instance(this->state) >> qi::lit(";"))
[phoenix::bind(&PrismGrammar::addLabel, this, qi::_1, qi::_2, qi::_r1)];
labelDefinition.name("label declaration");
labelDefinitionList %= *labelDefinition(qi::_r1);
labelDefinitionList.name("label declaration list");
// This block defines all entities that are needed for parsing a reward model.
stateRewardDefinition = (BooleanExpressionGrammar::instance(this->state) > qi::lit(":") > ConstDoubleExpressionGrammar::instance(this->state) >> qi::lit(";"))[qi::_val = phoenix::bind(&createStateReward, qi::_1, qi::_2)];
stateRewardDefinition.name("state reward definition");
transitionRewardDefinition = (qi::lit("[") > -(commandName[qi::_a = qi::_1]) > qi::lit("]") > BooleanExpressionGrammar::instance(this->state) > qi::lit(":") > ConstDoubleExpressionGrammar::instance(this->state) > qi::lit(";"))[qi::_val = phoenix::bind(&createTransitionReward, qi::_a, qi::_2, qi::_3)];
transitionRewardDefinition.name("transition reward definition");
rewardDefinition = (qi::lit("rewards") > qi::lit("\"") > FreeIdentifierGrammar::instance(this->state) > qi::lit("\"") > +(stateRewardDefinition[phoenix::push_back(qi::_a, qi::_1)] | transitionRewardDefinition[phoenix::push_back(qi::_b, qi::_1)]) >> qi::lit("endrewards"))
[phoenix::bind(&createRewardModel, qi::_1, qi::_a, qi::_b, qi::_r1)];
rewardDefinition.name("reward definition");
rewardDefinitionList = *rewardDefinition(qi::_r1);
rewardDefinitionList.name("reward definition list");
commandName %= this->state->commandNames_;
commandName.name("command name");
unassignedLocalBooleanVariableName %= (this->state->localBooleanVariables_ | this->state->globalBooleanVariables_) - this->state->assignedBooleanVariables_;
unassignedLocalBooleanVariableName.name("unassigned local/global boolean variable");
unassignedLocalIntegerVariableName %= (this->state->localIntegerVariables_ | this->state->globalIntegerVariables_) - this->state->assignedIntegerVariables_;
unassignedLocalIntegerVariableName.name("unassigned local/global integer variable");
// This block defines all entities that are needed for parsing a single command.
assignmentDefinition =
(qi::lit("(") >> unassignedLocalIntegerVariableName > qi::lit("'") > qi::lit("=") > IntegerExpressionGrammar::instance(this->state) > qi::lit(")"))[phoenix::bind(&PrismGrammar::addIntegerAssignment, this, qi::_1, qi::_2, qi::_r2)] |
(qi::lit("(") >> unassignedLocalBooleanVariableName > qi::lit("'") > qi::lit("=") > BooleanExpressionGrammar::instance(this->state) > qi::lit(")"))[phoenix::bind(&PrismGrammar::addBooleanAssignment, this, qi::_1, qi::_2, qi::_r1)];
assignmentDefinition.name("assignment");
assignmentDefinitionList = assignmentDefinition(qi::_r1, qi::_r2) % "&";
assignmentDefinitionList.name("assignment list");
updateDefinition = (((ConstDoubleExpressionGrammar::instance(this->state) >> qi::lit(":"))
| qi::attr(std::shared_ptr<BaseExpression>(new storm::ir::expressions::DoubleLiteralExpression(1))))[phoenix::clear(phoenix::ref(this->state->assignedBooleanVariables_)), phoenix::clear(phoenix::ref(this->state->assignedIntegerVariables_))]
>> assignmentDefinitionList(qi::_a, qi::_b))[qi::_val = phoenix::bind(&PrismGrammar::createUpdate, this, qi::_1, qi::_a, qi::_b)];
updateDefinition.name("update");
updateListDefinition = +updateDefinition % "+";
updateListDefinition.name("update list");
commandDefinition = (
qi::lit("[") > -(
(FreeIdentifierGrammar::instance(this->state)[phoenix::bind(this->state->commandNames_.add, qi::_1, qi::_1)] | commandName)[qi::_a = qi::_1]
) > qi::lit("]") > BooleanExpressionGrammar::instance(this->state) > qi::lit("->") > updateListDefinition > qi::lit(";")
)[qi::_val = phoenix::bind(&PrismGrammar::createCommand, this, qi::_a, qi::_2, qi::_3)];
commandDefinition.name("command");
// This block defines all entities that are needed for parsing variable definitions.
booleanVariableDefinition = (FreeIdentifierGrammar::instance(this->state) >> qi::lit(":") >> qi::lit("bool") > -(qi::lit("init") > ConstBooleanExpressionGrammar::instance(this->state)[qi::_b = phoenix::construct<std::shared_ptr<BaseExpression>>(qi::_1)]) > qi::lit(";"))
[phoenix::bind(&PrismGrammar::createBooleanVariable, this, qi::_1, qi::_b, qi::_r1, qi::_r2, qi::_r3)];
booleanVariableDefinition.name("boolean variable declaration");
integerVariableDefinition = (FreeIdentifierGrammar::instance(this->state) >> qi::lit(":") >> qi::lit("[") > ConstIntegerExpressionGrammar::instance(this->state) > qi::lit("..") > ConstIntegerExpressionGrammar::instance(this->state) > qi::lit("]") > -(qi::lit("init") > ConstIntegerExpressionGrammar::instance(this->state)[qi::_b = phoenix::construct<std::shared_ptr<BaseExpression>>(qi::_1)]) > qi::lit(";"))
[phoenix::bind(&PrismGrammar::createIntegerVariable, this, qi::_1, qi::_2, qi::_3, qi::_b, qi::_r1, qi::_r2, qi::_r3)];
integerVariableDefinition.name("integer variable declaration");
variableDefinition = (booleanVariableDefinition(qi::_r1, qi::_r3, false) | integerVariableDefinition(qi::_r2, qi::_r4, false));
variableDefinition.name("variable declaration");
// This block defines all entities that are needed for parsing a module.
moduleDefinition = (qi::lit("module") >> FreeIdentifierGrammar::instance(this->state)[phoenix::bind(&VariableState::clearLocalVariables, *this->state)]
>> *(variableDefinition(qi::_a, qi::_b, qi::_c, qi::_d)) >> +commandDefinition > qi::lit("endmodule"))
[qi::_val = phoenix::bind(&PrismGrammar::createModule, this, qi::_1, qi::_a, qi::_b, qi::_c, qi::_d, qi::_2)];
moduleDefinition.name("module");
moduleRenaming = (qi::lit("module") >> FreeIdentifierGrammar::instance(this->state) >> qi::lit("=")
> this->state->moduleNames_ > qi::lit("[") > *(
(IdentifierGrammar::instance(this->state) > qi::lit("=") > IdentifierGrammar::instance(this->state) >> -qi::lit(","))[phoenix::insert(qi::_a, phoenix::construct<std::pair<std::string,std::string>>(qi::_1, qi::_2))]
) > qi::lit("]") > qi::lit("endmodule"))
[qi::_val = phoenix::bind(&PrismGrammar::renameModule, this, qi::_1, qi::_2, qi::_a)];
moduleRenaming.name("renamed module");
moduleDefinitionList %= +(moduleDefinition | moduleRenaming);
moduleDefinitionList.name("module list");
// This block defines all entities that are needed for parsing global variable definitions.
globalVariableDefinitionList = *(qi::lit("global") > (booleanVariableDefinition(bind(&GlobalVariableInformation::booleanVariables, qi::_r1), bind(&GlobalVariableInformation::booleanVariableToIndexMap, qi::_r1), true) | integerVariableDefinition(bind(&GlobalVariableInformation::integerVariables, qi::_r1), bind(&GlobalVariableInformation::integerVariableToIndexMap, qi::_r1), true)));
globalVariableDefinitionList.name("global variable declaration list");
// This block defines all entities that are needed for parsing constant definitions.
definedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") >> FreeIdentifierGrammar::instance(this->state) >> qi::lit("=") > ConstBooleanExpressionGrammar::instance(this->state) > qi::lit(";"))[phoenix::bind(this->state->booleanConstants_.add, qi::_1, qi::_2), phoenix::bind(this->state->allConstantNames_.add, qi::_1, qi::_1), qi::_val = qi::_2];
definedBooleanConstantDefinition.name("defined boolean constant declaration");
definedIntegerConstantDefinition = (qi::lit("const") >> qi::lit("int") >> FreeIdentifierGrammar::instance(this->state) >> qi::lit("=") >> ConstIntegerExpressionGrammar::instance(this->state) >> qi::lit(";"))[phoenix::bind(this->state->integerConstants_.add, qi::_1, qi::_2), phoenix::bind(this->state->allConstantNames_.add, qi::_1, qi::_1), qi::_val = qi::_2];
definedIntegerConstantDefinition.name("defined integer constant declaration");
definedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") >> FreeIdentifierGrammar::instance(this->state) >> qi::lit("=") > ConstDoubleExpressionGrammar::instance(this->state) > qi::lit(";"))[phoenix::bind(this->state->doubleConstants_.add, qi::_1, qi::_2), phoenix::bind(this->state->allConstantNames_.add, qi::_1, qi::_1), qi::_val = qi::_2];
definedDoubleConstantDefinition.name("defined double constant declaration");
undefinedBooleanConstantDefinition = (qi::lit("const") >> qi::lit("bool") > FreeIdentifierGrammar::instance(this->state) > qi::lit(";"))[phoenix::bind(&PrismGrammar::addUndefinedBooleanConstant, this, qi::_1, qi::_r1)];
undefinedBooleanConstantDefinition.name("undefined boolean constant declaration");
undefinedIntegerConstantDefinition = (qi::lit("const") >> qi::lit("int") > FreeIdentifierGrammar::instance(this->state) > qi::lit(";"))[phoenix::bind(&PrismGrammar::addUndefinedIntegerConstant, this, qi::_1, qi::_r1)];
undefinedIntegerConstantDefinition.name("undefined integer constant declaration");
undefinedDoubleConstantDefinition = (qi::lit("const") >> qi::lit("double") > FreeIdentifierGrammar::instance(this->state) > qi::lit(";"))[phoenix::bind(&PrismGrammar::addUndefinedDoubleConstant, this, qi::_1, qi::_r1)];
undefinedDoubleConstantDefinition.name("undefined double constant declaration");
definedConstantDefinition %= (definedBooleanConstantDefinition | definedIntegerConstantDefinition | definedDoubleConstantDefinition);
definedConstantDefinition.name("defined constant declaration");
undefinedConstantDefinition = (undefinedBooleanConstantDefinition(qi::_r1) | undefinedIntegerConstantDefinition(qi::_r2) | undefinedDoubleConstantDefinition(qi::_r3));
undefinedConstantDefinition.name("undefined constant declaration");
constantDefinitionList = *(definedConstantDefinition | undefinedConstantDefinition(qi::_r1, qi::_r2, qi::_r3));
constantDefinitionList.name("constant declaration list");
constantBooleanFormulaDefinition = (qi::lit("formula") >> FreeIdentifierGrammar::instance(this->state) >> qi::lit("=") >> ConstBooleanExpressionGrammar::instance(this->state) >> qi::lit(";"))[phoenix::bind(this->state->constantBooleanFormulas_.add, qi::_1, qi::_2)];
constantBooleanFormulaDefinition.name("constant boolean formula definition");
booleanFormulaDefinition = (qi::lit("formula") >> FreeIdentifierGrammar::instance(this->state) >> qi::lit("=") >> BooleanExpressionGrammar::instance(this->state) >> qi::lit(";"))[phoenix::bind(this->state->booleanFormulas_.add, qi::_1, qi::_2)];
booleanFormulaDefinition.name("boolean formula definition");
constantIntegerFormulaDefinition = (qi::lit("formula") >> FreeIdentifierGrammar::instance(this->state) >> qi::lit("=") >> ConstIntegerExpressionGrammar::instance(this->state) >> qi::lit(";"))[phoenix::bind(this->state->constantIntegerFormulas_.add, qi::_1, qi::_2)];
constantIntegerFormulaDefinition.name("constant integer formula definition");
integerFormulaDefinition = (qi::lit("formula") >> FreeIdentifierGrammar::instance(this->state) >> qi::lit("=") >> IntegerExpressionGrammar::instance(this->state) >> qi::lit(";"))[phoenix::bind(this->state->integerFormulas_.add, qi::_1, qi::_2)];
integerFormulaDefinition.name("integer formula definition");
constantDoubleFormulaDefinition = (qi::lit("formula") >> FreeIdentifierGrammar::instance(this->state) >> qi::lit("=") >> ConstDoubleExpressionGrammar::instance(this->state) >> qi::lit(";"))[phoenix::bind(this->state->constantDoubleFormulas_.add, qi::_1, qi::_2)];
constantDoubleFormulaDefinition.name("constant double formula definition");
formulaDefinition = constantBooleanFormulaDefinition | booleanFormulaDefinition | constantIntegerFormulaDefinition | integerFormulaDefinition | constantDoubleFormulaDefinition;
formulaDefinition.name("formula definition");
formulaDefinitionList = *formulaDefinition;
formulaDefinitionList.name("formula definition list");
// This block defines all entities that are needed for parsing a program.
modelTypeDefinition = modelType_;
modelTypeDefinition.name("model type");
start = (qi::eps >
modelTypeDefinition >
constantDefinitionList(qi::_a, qi::_b, qi::_c) >
formulaDefinitionList >
globalVariableDefinitionList(qi::_d) >
moduleDefinitionList >
rewardDefinitionList(qi::_e) >
labelDefinitionList(qi::_f))[qi::_val = phoenix::bind(&createProgram, qi::_1, qi::_a, qi::_b, qi::_c, qi::_d, qi::_2, qi::_e, qi::_f)];
start.name("probabilistic program declaration");
}
void PrismGrammar::prepareForSecondRun() {
LOG4CPLUS_INFO(logger, "Preparing parser for second run.");
this->state->prepareForSecondRun();
BooleanExpressionGrammar::secondRun();
ConstBooleanExpressionGrammar::secondRun();
ConstDoubleExpressionGrammar::secondRun();
ConstIntegerExpressionGrammar::secondRun();
IntegerExpressionGrammar::secondRun();
}
void PrismGrammar::resetGrammars() {
LOG4CPLUS_INFO(logger, "Resetting grammars.");
BooleanExpressionGrammar::resetInstance();
ConstBooleanExpressionGrammar::resetInstance();
ConstDoubleExpressionGrammar::resetInstance();
ConstIntegerExpressionGrammar::resetInstance();
IntegerExpressionGrammar::resetInstance();
}
} // namespace prism
} // namespace parser
} // namespace storm

267
src/parser/prismparser/PrismGrammar.h

@ -1,267 +0,0 @@
/*
* File: PrismGrammar.h
* Author: nafur
*
* Created on April 30, 2013, 5:20 PM
*/
#ifndef STORM_PARSER_PRISMPARSER_PRISMGRAMMAR_H
#define STORM_PARSER_PRISMPARSER_PRISMGRAMMAR_H
// All classes of the intermediate representation are used.
#include "src/ir/IR.h"
#include "src/parser/prismparser/Includes.h"
#include "src/parser/prismparser/Tokens.h"
#include "src/parser/prismparser/IdentifierGrammars.h"
#include "src/parser/prismparser/VariableState.h"
#include "src/parser/prismparser/ConstBooleanExpressionGrammar.h"
#include "src/parser/prismparser/ConstDoubleExpressionGrammar.h"
#include "src/parser/prismparser/ConstIntegerExpressionGrammar.h"
#include "src/parser/prismparser/BooleanExpressionGrammar.h"
#include "src/parser/prismparser/IntegerExpressionGrammar.h"
// Used for file input.
#include <istream>
#include <memory>
namespace storm {
namespace parser {
namespace prism {
using namespace storm::ir;
using namespace storm::ir::expressions;
struct GlobalVariableInformation {
std::vector<BooleanVariable> booleanVariables;
std::vector<IntegerVariable> integerVariables;
std::map<std::string, uint_fast64_t> booleanVariableToIndexMap;
std::map<std::string, uint_fast64_t> integerVariableToIndexMap;
};
/*!
* The Boost spirit grammar for the PRISM language. Returns the intermediate representation of
* the input that complies with the PRISM syntax.
*/
class PrismGrammar : public qi::grammar<
Iterator,
Program(),
qi::locals<
std::map<std::string, std::unique_ptr<BooleanConstantExpression>>,
std::map<std::string, std::unique_ptr<IntegerConstantExpression>>,
std::map<std::string, std::unique_ptr<DoubleConstantExpression>>,
GlobalVariableInformation,
std::map<std::string, RewardModel>,
std::map<std::string, std::unique_ptr<BaseExpression>>
>,
Skipper> {
public:
/*!
* Default constructor that creates an empty and functional grammar.
*/
PrismGrammar();
/*!
* Puts all sub-grammars into the mode for performing the second run. A two-run model was chosen
* because modules can involve variables that are only declared afterwards, so the first run
* creates all variables and the second one tries to parse the full model.
*/
void prepareForSecondRun();
/*!
* Resets all sub-grammars, i.e. puts them into an initial state.
*/
void resetGrammars();
private:
std::shared_ptr<storm::parser::prism::VariableState> state;
struct qi::symbols<char, Module> moduleMap_;
// The starting point of the grammar.
qi::rule<
Iterator,
Program(),
qi::locals<
std::map<std::string, std::unique_ptr<BooleanConstantExpression>>,
std::map<std::string, std::unique_ptr<IntegerConstantExpression>>,
std::map<std::string, std::unique_ptr<DoubleConstantExpression>>,
GlobalVariableInformation,
std::map<std::string, RewardModel>,
std::map<std::string, std::unique_ptr<BaseExpression>>
>,
Skipper> start;
qi::rule<Iterator, Program::ModelType(), Skipper> modelTypeDefinition;
qi::rule<Iterator, qi::unused_type(std::map<std::string, std::unique_ptr<BooleanConstantExpression>>&, std::map<std::string, std::unique_ptr<IntegerConstantExpression>>&, std::map<std::string, std::unique_ptr<DoubleConstantExpression>>&), Skipper> constantDefinitionList;
qi::rule<Iterator, std::vector<Module>(), Skipper> moduleDefinitionList;
// Rules for global variable definitions
qi::rule<Iterator, qi::unused_type(GlobalVariableInformation&), Skipper> globalVariableDefinitionList;
// Rules for module definition.
qi::rule<Iterator, Module(), qi::locals<std::vector<BooleanVariable>, std::vector<IntegerVariable>, std::map<std::string, uint_fast64_t>, std::map<std::string, uint_fast64_t>>, Skipper> moduleDefinition;
qi::rule<Iterator, Module(), qi::locals<std::map<std::string, std::string>>, Skipper> moduleRenaming;
// Rules for variable definitions.
qi::rule<Iterator, qi::unused_type(std::vector<BooleanVariable>&, std::vector<IntegerVariable>&, std::map<std::string, uint_fast64_t>&, std::map<std::string, uint_fast64_t>&), Skipper> variableDefinition;
qi::rule<Iterator, qi::unused_type(std::vector<BooleanVariable>&, std::map<std::string, uint_fast64_t>&, bool), qi::locals<uint_fast64_t, std::shared_ptr<BaseExpression>>, Skipper> booleanVariableDefinition;
qi::rule<Iterator, qi::unused_type(std::vector<IntegerVariable>&, std::map<std::string, uint_fast64_t>&, bool), qi::locals<uint_fast64_t, std::shared_ptr<BaseExpression>>, Skipper> integerVariableDefinition;
// Rules for command definitions.
qi::rule<Iterator, Command(), qi::locals<std::string>, Skipper> commandDefinition;
qi::rule<Iterator, std::vector<Update>(), Skipper> updateListDefinition;
qi::rule<Iterator, Update(), qi::locals<std::map<std::string, Assignment>, std::map<std::string, Assignment>>, Skipper> updateDefinition;
qi::rule<Iterator, qi::unused_type(std::map<std::string, Assignment>&, std::map<std::string, Assignment>&), Skipper> assignmentDefinitionList;
qi::rule<Iterator, qi::unused_type(std::map<std::string, Assignment>&, std::map<std::string, Assignment>&), Skipper> assignmentDefinition;
// Rules for variable/command names.
qi::rule<Iterator, std::string(), Skipper> commandName;
qi::rule<Iterator, std::string(), Skipper> unassignedLocalBooleanVariableName;
qi::rule<Iterator, std::string(), Skipper> unassignedLocalIntegerVariableName;
// Rules for reward definitions.
qi::rule<Iterator, qi::unused_type(std::map<std::string, RewardModel>&), Skipper> rewardDefinitionList;
qi::rule<Iterator, qi::unused_type(std::map<std::string, RewardModel>&), qi::locals<std::vector<StateReward>, std::vector<TransitionReward>>, Skipper> rewardDefinition;
qi::rule<Iterator, StateReward(), Skipper> stateRewardDefinition;
qi::rule<Iterator, TransitionReward(), qi::locals<std::string>, Skipper> transitionRewardDefinition;
// Rules for label definitions.
qi::rule<Iterator, qi::unused_type(std::map<std::string, std::unique_ptr<BaseExpression>>&), Skipper> labelDefinitionList;
qi::rule<Iterator, qi::unused_type(std::map<std::string, std::unique_ptr<BaseExpression>>&), Skipper> labelDefinition;
// Rules for constant definitions.
qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> constantDefinition;
qi::rule<Iterator, qi::unused_type(std::map<std::string, std::unique_ptr<BooleanConstantExpression>>&, std::map<std::string, std::unique_ptr<IntegerConstantExpression>>&, std::map<std::string, std::unique_ptr<DoubleConstantExpression>>&), Skipper> undefinedConstantDefinition;
qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> definedConstantDefinition;
qi::rule<Iterator, qi::unused_type(std::map<std::string, std::unique_ptr<BooleanConstantExpression>>&), Skipper> undefinedBooleanConstantDefinition;
qi::rule<Iterator, qi::unused_type(std::map<std::string, std::unique_ptr<IntegerConstantExpression>>&), Skipper> undefinedIntegerConstantDefinition;
qi::rule<Iterator, qi::unused_type(std::map<std::string, std::unique_ptr<DoubleConstantExpression>>&), Skipper> undefinedDoubleConstantDefinition;
qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> definedBooleanConstantDefinition;
qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> definedIntegerConstantDefinition;
qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> definedDoubleConstantDefinition;
// Rules for formula definitions.
qi::rule<Iterator, qi::unused_type(), Skipper> formulaDefinitionList;
qi::rule<Iterator, qi::unused_type(), Skipper> formulaDefinition;
qi::rule<Iterator, qi::unused_type(), Skipper> constantIntegerFormulaDefinition;
qi::rule<Iterator, qi::unused_type(), Skipper> integerFormulaDefinition;
qi::rule<Iterator, qi::unused_type(), Skipper> constantDoubleFormulaDefinition;
qi::rule<Iterator, qi::unused_type(), Skipper> constantBooleanFormulaDefinition;
qi::rule<Iterator, qi::unused_type(), Skipper> booleanFormulaDefinition;
// Rules for variable recognition.
qi::rule<Iterator, std::shared_ptr<BaseExpression>(), Skipper> booleanVariableCreatorExpression;
qi::rule<Iterator, std::shared_ptr<BaseExpression>(), qi::locals<std::shared_ptr<BaseExpression>>, Skipper> integerVariableCreatorExpression;
storm::parser::prism::keywordsStruct keywords_;
storm::parser::prism::modelTypeStruct modelType_;
storm::parser::prism::relationalOperatorStruct relations_;
/*!
* Adds a label with the given name and expression to the given label-to-expression map.
*
* @param name The name of the label.
* @param expression The expression associated with the label.
* @param nameToExpressionMap The map to which the label is added.
*/
void addLabel(std::string const& name, std::shared_ptr<BaseExpression> const& value, std::map<std::string, std::unique_ptr<BaseExpression>>& nameToExpressionMap);
/*!
* Adds a boolean assignment for the given variable with the given expression and adds it to the
* provided variable-to-assignment map.
*
* @param variable The name of the variable that the assignment targets.
* @param expression The expression that is assigned to the variable.
* @param variableToAssignmentMap The map to which the assignment is added.
*/
void addBooleanAssignment(std::string const& variable, std::shared_ptr<BaseExpression> const& expression, std::map<std::string, Assignment>& variableToAssignmentMap);
/*!
* Adds a boolean assignment for the given variable with the given expression and adds it to the
* provided variable-to-assignment map.
*
* @param variable The name of the variable that the assignment targets.
* @param expression The expression that is assigned to the variable.
* @param variableToAssignmentMap The map to which the assignment is added.
*/
void addIntegerAssignment(std::string const& variable, std::shared_ptr<BaseExpression> const& expression, std::map<std::string, Assignment>& variableToAssignmentMap);
void addUndefinedBooleanConstant(std::string const& name, std::map<std::string, std::unique_ptr<BooleanConstantExpression>>& nameToExpressionMap);
void addUndefinedIntegerConstant(std::string const& name, std::map<std::string, std::unique_ptr<IntegerConstantExpression>>& nameToExpressionMap);
void addUndefinedDoubleConstant(std::string const& name, std::map<std::string, std::unique_ptr<DoubleConstantExpression>>& nameToExpressionMap);
/*!
* Creates a module by renaming, i.e. takes the module given by the old name, creates a new module
* with the given name which renames all identifiers according to the given mapping.
*
* @param name The name of the new module.
* @param oldName The name of the module that is to be copied (modulo renaming).
* @param renaming A mapping from identifiers to their new names.
*/
Module renameModule(std::string const& name, std::string const& oldName, std::map<std::string, std::string> const& renaming);
/*!
* Creates a new module with the given name, boolean and integer variables and commands.
*
* @param name The name of the module to create.
* @param booleanVariables The boolean variables of the module.
* @param integerVariables The integer variables of the module.
* @param booleanVariableToLocalIndexMap A mapping of boolean variables to module-local indices.
* @param integerVariableToLocalIndexMap A mapping of boolean variables to module-local indices.
* @param commands The commands associated with this module.
*/
Module createModule(std::string const& name, std::vector<BooleanVariable> const& booleanVariables, std::vector<IntegerVariable> const& integerVariables, std::map<std::string, uint_fast64_t> const& booleanVariableToLocalIndexMap, std::map<std::string, uint_fast64_t> const& integerVariableToLocalIndexMap, std::vector<storm::ir::Command> const& commands);
/*!
* Creates an integer variable with the given name, domain and initial value and adds it to the
* provided list of integer variables and the given mappings.
*
* @param name The name of the integer variable.
* @param lower The expression that defines the lower bound of the domain.
* @param upper The expression that defines the upper bound of the domain.
* @param init The expression that defines the initial value of the variable.
* @param integerVariableToGlobalIndexMap A mapping of integer variables to global indices.
* @param isGlobalVariable A flag indicating whether the variable is supposed to be global or not.
*/
void createIntegerVariable(std::string const& name, std::shared_ptr<BaseExpression> const& lower, std::shared_ptr<BaseExpression> const& upper, std::shared_ptr<BaseExpression> const& init, std::vector<IntegerVariable>& integerVariables, std::map<std::string, uint_fast64_t>& integerVariableToGlobalIndexMap, bool isGlobalVariable);
/*!
* Creates an boolean variable with the given name and initial value and adds it to the
* provided list of boolean variables and the given mappings.
*
* @param name The name of the boolean variable.
* @param init The expression that defines the initial value of the variable.
* @param booleanVariableToGlobalIndexMap A mapping of boolean variables to global indices.
* @param isGlobalVariable A flag indicating whether the variable is supposed to be global or not.
*/
void createBooleanVariable(std::string const& name, std::shared_ptr<BaseExpression> const& init, std::vector<BooleanVariable>& booleanVariables, std::map<std::string, uint_fast64_t>& booleanVariableToGlobalIndexMap, bool isGlobalVariable);
/*!
* Creates a command with the given label, guard and updates.
*
* @param label The label of the command.
* @param guard The guard of the command.
* @param updates The updates associated with the command.
*/
Command createCommand(std::string const& label, std::shared_ptr<BaseExpression> const& guard, std::vector<Update> const& updates);
/*!
* Creates an update with the given likelihood and the given assignments to boolean and integer variables, respectively.
*
* @param likelihood The likelihood of this update being executed.
* @param booleanAssignments The assignments to boolean variables this update involves.
* @param integerAssignments The assignments to integer variables this update involves.
*/
Update createUpdate(std::shared_ptr<BaseExpression> const& likelihood, std::map<std::string, Assignment> const& booleanAssignments, std::map<std::string, Assignment> const& integerAssignments);
};
} // namespace prism
} // namespace parser
} // namespace storm
#endif /* STORM_PARSER_PRISMPARSER_PRISMGRAMMAR_H */

75
src/parser/prismparser/Tokens.h

@ -1,75 +0,0 @@
/*
* File: Tokens.h
* Author: nafur
*
* Created on April 19, 2013, 11:17 PM
*/
#ifndef TOKENS_H
#define TOKENS_H
namespace storm {
namespace parser {
namespace prism {
/*!
* A structure mapping the textual representation of a model type to the model type
* representation of the intermediate representation.
*/
struct modelTypeStruct : qi::symbols<char, Program::ModelType> {
modelTypeStruct() {
add
("dtmc", Program::ModelType::DTMC)
("ctmc", Program::ModelType::CTMC)
("mdp", Program::ModelType::MDP)
("ctmdp", Program::ModelType::CTMDP)
;
}
};
/*!
* A structure defining the keywords that are not allowed to be chosen as identifiers.
*/
struct keywordsStruct : qi::symbols<char, unsigned> {
keywordsStruct() {
add
("dtmc", 1)
("ctmc", 2)
("mdp", 3)
("ctmdp", 4)
("const", 5)
("int", 6)
("bool", 7)
("module", 8)
("endmodule", 9)
("rewards", 10)
("endrewards", 11)
("true", 12)
("false", 13)
;
}
};
/*!
* A structure mapping the textual representation of a binary relation to the representation
* of the intermediate representation.
*/
struct relationalOperatorStruct : qi::symbols<char, BinaryRelationExpression::RelationType> {
relationalOperatorStruct() {
add
("=", BinaryRelationExpression::EQUAL)
("!=", BinaryRelationExpression::NOT_EQUAL)
("<", BinaryRelationExpression::LESS)
("<=", BinaryRelationExpression::LESS_OR_EQUAL)
(">", BinaryRelationExpression::GREATER)
(">=", BinaryRelationExpression::GREATER_OR_EQUAL)
;
}
};
}
}
}
#endif /* TOKENS_H */

191
src/parser/prismparser/VariableState.cpp

@ -1,191 +0,0 @@
#include "VariableState.h"
#include "src/exceptions/InvalidArgumentException.h"
namespace storm {
namespace parser {
namespace prism {
using namespace storm::ir;
using namespace storm::ir::expressions;
template<typename T>
struct SymbolDump {
SymbolDump(std::ostream& out) : out(out) {}
void operator() (std::basic_string<char> s, T elem) {
this->out << "\t" << s << " -> " << elem << std::endl;
}
private:
std::ostream& out;
};
template<typename T>
std::ostream& operator<<(std::ostream& out, qi::symbols<char, T>& symbols) {
out << "Dumping symbol table" << std::endl;
SymbolDump<T> dump(out);
symbols.for_each(dump);
return out;
}
std::ostream& operator<<(std::ostream& out, VariableState::variableNamesStruct& symbols) {
SymbolDump<std::string> dump(out);
symbols.for_each(dump);
return out;
}
VariableState::VariableState(bool firstRun) : firstRun(firstRun), keywords(), nextLocalBooleanVariableIndex(0), nextLocalIntegerVariableIndex(0), nextGlobalBooleanVariableIndex(0), nextGlobalIntegerVariableIndex(0), nextGlobalCommandIndex(0), nextGlobalUpdateIndex(0) {
// Nothing to do here.
}
uint_fast64_t VariableState::getNextLocalBooleanVariableIndex() const {
return this->nextLocalBooleanVariableIndex;
}
uint_fast64_t VariableState::getNextLocalIntegerVariableIndex() const {
return this->nextLocalIntegerVariableIndex;
}
uint_fast64_t VariableState::getNextGlobalBooleanVariableIndex() const {
return this->nextGlobalBooleanVariableIndex;
}
uint_fast64_t VariableState::getNextGlobalIntegerVariableIndex() const {
return this->nextGlobalIntegerVariableIndex;
}
uint_fast64_t VariableState::getNextGlobalCommandIndex() const {
return this->nextGlobalCommandIndex;
}
uint_fast64_t VariableState::getNextGlobalUpdateIndex() const {
return this->nextGlobalUpdateIndex;
}
uint_fast64_t VariableState::addBooleanVariable(std::string const& name) {
if (firstRun) {
LOG4CPLUS_TRACE(logger, "Adding boolean variable " << name << " with new id " << this->nextGlobalBooleanVariableIndex << ".");
this->booleanVariables_.add(name, std::shared_ptr<VariableExpression>(new VariableExpression(storm::ir::expressions::BaseExpression::bool_, this->nextGlobalBooleanVariableIndex, name)));
this->booleanVariableNames_.add(name, name);
++this->nextGlobalBooleanVariableIndex;
++this->nextLocalBooleanVariableIndex;
return this->nextGlobalBooleanVariableIndex - 1;
} else {
std::shared_ptr<VariableExpression> variableExpression = this->booleanVariables_.at(name);
if (variableExpression != nullptr) {
return variableExpression->getGlobalVariableIndex();
} else {
LOG4CPLUS_ERROR(logger, "Boolean variable " << name << " does not exist.");
throw storm::exceptions::InvalidArgumentException() << "Boolean variable " << name << " does not exist.";
}
}
}
uint_fast64_t VariableState::addIntegerVariable(std::string const& name) {
if (firstRun) {
LOG4CPLUS_TRACE(logger, "Adding integer variable " << name << " with new id " << this->nextGlobalIntegerVariableIndex << ".");
this->integerVariables_.add(name, std::shared_ptr<VariableExpression>(new VariableExpression(storm::ir::expressions::BaseExpression::int_, this->nextGlobalIntegerVariableIndex, name)));
this->integerVariableNames_.add(name, name);
++this->nextGlobalIntegerVariableIndex;
++this->nextLocalIntegerVariableIndex;
return this->nextGlobalIntegerVariableIndex - 1;
} else {
std::shared_ptr<VariableExpression> variableExpression = this->integerVariables_.at(name);
if (variableExpression != nullptr) {
return variableExpression->getGlobalVariableIndex();
} else {
LOG4CPLUS_ERROR(logger, "Integer variable " << name << " does not exist.");
throw storm::exceptions::InvalidArgumentException() << "Integer variable " << name << " does not exist.";
}
}
}
std::shared_ptr<VariableExpression> VariableState::getBooleanVariableExpression(std::string const& name) const {
std::shared_ptr<VariableExpression> const* variableExpression = this->booleanVariables_.find(name);
if (variableExpression != nullptr) {
return *variableExpression;
} else {
if (firstRun) {
LOG4CPLUS_TRACE(logger, "Trying to retrieve boolean variable " << name << " that was not yet created; returning dummy instead.");
return std::shared_ptr<VariableExpression>(new VariableExpression(BaseExpression::bool_, name));
} else {
LOG4CPLUS_ERROR(logger, "Boolean variable " << name << " does not exist.");
throw storm::exceptions::InvalidArgumentException() << "Boolean variable " << name << " does not exist.";
}
}
}
std::shared_ptr<VariableExpression> VariableState::getIntegerVariableExpression(std::string const& name) const {
std::shared_ptr<VariableExpression> const* variableExpression = this->integerVariables_.find(name);
if (variableExpression != nullptr) {
return *variableExpression;
} else {
if (firstRun) {
LOG4CPLUS_TRACE(logger, "Trying to retrieve integer variable " << name << " that was not yet created; returning dummy instead.");
return std::shared_ptr<VariableExpression>(new VariableExpression(BaseExpression::int_, name));
} else {
LOG4CPLUS_ERROR(logger, "Integer variable " << name << " does not exist.");
throw storm::exceptions::InvalidArgumentException() << "Integer variable " << name << " does not exist.";
}
}
}
std::shared_ptr<VariableExpression> VariableState::getVariableExpression(std::string const& name) const {
std::shared_ptr<VariableExpression> const* variableExpression = this->integerVariables_.find(name);
if (variableExpression != nullptr) {
return *variableExpression;
}
variableExpression = this->booleanVariables_.find(name);
if (variableExpression != nullptr) {
return *variableExpression;
}
LOG4CPLUS_ERROR(logger, "Variable " << name << " does not exist.");
throw storm::exceptions::InvalidArgumentException() << "Variable " << name << " does not exist.";
}
void VariableState::clearLocalVariables() {
this->localBooleanVariables_.clear();
this->localIntegerVariables_.clear();
this->nextLocalBooleanVariableIndex = 0;
this->nextLocalIntegerVariableIndex = 0;
}
bool VariableState::isFreeIdentifier(std::string const& identifier) const {
if (this->booleanVariableNames_.find(identifier) != nullptr) return false;
if (this->integerVariableNames_.find(identifier) != nullptr) return false;
if (this->allConstantNames_.find(identifier) != nullptr) return false;
if (this->labelNames_.find(identifier) != nullptr) return false;
if (this->moduleNames_.find(identifier) != nullptr) return false;
if (this->keywords.find(identifier) != nullptr) return false;
if (this->booleanFormulas_.find(identifier) != nullptr) return false;
if (this->integerFormulas_.find(identifier) != nullptr) return false;
if (this->doubleFormulas_.find(identifier) != nullptr) return false;
if (this->constantBooleanFormulas_.find(identifier) != nullptr) return false;
if (this->constantIntegerFormulas_.find(identifier) != nullptr) return false;
if (this->constantDoubleFormulas_.find(identifier) != nullptr) return false;
return true;
}
bool VariableState::isIdentifier(std::string const& identifier) const {
if (this->allConstantNames_.find(identifier) != nullptr) return false;
if (this->keywords.find(identifier) != nullptr) return false;
return true;
}
void VariableState::prepareForSecondRun() {
integerConstants_.clear();
booleanConstants_.clear();
doubleConstants_.clear();
allConstantNames_.clear();
constantBooleanFormulas_.clear();
booleanFormulas_.clear();
constantIntegerFormulas_.clear();
integerFormulas_.clear();
constantDoubleFormulas_.clear();
doubleFormulas_.clear();
this->firstRun = false;
nextGlobalCommandIndex = 0;
nextGlobalUpdateIndex = 0;
}
} // namespace prism
} // namespace parser
} // namespace storm

207
src/parser/prismparser/VariableState.h

@ -1,207 +0,0 @@
/*
* File: VariableState.h
* Author: nafur
*
* Created on April 10, 2013, 4:43 PM
*/
#ifndef STORM_PARSER_PRISMPARSER_VARIABLESTATE_H
#define STORM_PARSER_PRISMPARSER_VARIABLESTATE_H
#include <iostream>
#include "src/ir/IR.h"
#include "Includes.h"
#include "Tokens.h"
namespace storm {
namespace parser {
namespace prism {
using namespace storm::ir;
using namespace storm::ir::expressions;
template<typename T>
std::ostream& operator<<(std::ostream& out, qi::symbols<char, T>& symbols);
/*!
* This class contains the internal state that is needed for parsing a PRISM model.
*/
class VariableState {
public:
/*!
* Creates a new variable state object. By default, this object will be set to a state in which
* it is ready for performing a first run on some input. The first run creates all variables
* while the second one checks for the correct usage of variables in expressions.
*
* @param firstRun If set, this object will be in a state ready for performing the first run. If
* set to false, this object will assume that it has all variable data already.
*/
VariableState(bool firstRun = true);
/*!
* Indicator, if we are still in the first run.
*/
bool firstRun;
/*!
* A parser for all reserved keywords.
*/
keywordsStruct keywords;
/*!
* Internal counter for the local index of the next new boolean variable.
*/
uint_fast64_t nextLocalBooleanVariableIndex;
/*!
* Retrieves the next free local index for a boolean variable.
*
* @return The next free local index for a boolean variable.
*/
uint_fast64_t getNextLocalBooleanVariableIndex() const;
/*!
* Internal counter for the local index of the next new integer variable.
*/
uint_fast64_t nextLocalIntegerVariableIndex;
/*!
* Retrieves the next free global index for a integer variable.
*
* @return The next free global index for a integer variable.
*/
uint_fast64_t getNextLocalIntegerVariableIndex() const;
/*!
* Internal counter for the index of the next new boolean variable.
*/
uint_fast64_t nextGlobalBooleanVariableIndex;
/*!
* Retrieves the next free global index for a boolean variable.
*
* @return The next free global index for a boolean variable.
*/
uint_fast64_t getNextGlobalBooleanVariableIndex() const;
/*!
* Internal counter for the index of the next new integer variable.
*/
uint_fast64_t nextGlobalIntegerVariableIndex;
/*!
* Retrieves the next free global index for a integer variable.
*
* @return The next free global index for a integer variable.
*/
uint_fast64_t getNextGlobalIntegerVariableIndex() const;
/*!
* Internal counter for the index of the next command.
*/
uint_fast64_t nextGlobalCommandIndex;
/*!
* Retrieves the next free global index for a command.
*
* @return The next free global index for a command.
*/
uint_fast64_t getNextGlobalCommandIndex() const;
/*!
* Internal counter for the index of the next update.
*/
uint_fast64_t nextGlobalUpdateIndex;
/*!
* Retrieves the next free global index for an update.
*
* @return The next free global index for an update.
*/
uint_fast64_t getNextGlobalUpdateIndex() const;
// Structures mapping variable and constant names to the corresponding expression nodes of
// the intermediate representation.
struct qi::symbols<char, std::shared_ptr<VariableExpression>> integerVariables_, booleanVariables_;
struct qi::symbols<char, std::shared_ptr<BaseExpression>> integerConstants_, booleanConstants_, doubleConstants_, booleanFormulas_, constantBooleanFormulas_, integerFormulas_, constantIntegerFormulas_, doubleFormulas_, constantDoubleFormulas_;
// A structure representing the identity function over identifier names.
struct variableNamesStruct : qi::symbols<char, std::string> { }
integerVariableNames_, booleanVariableNames_, commandNames_, labelNames_, allConstantNames_, moduleNames_,
localBooleanVariables_, localIntegerVariables_, assignedBooleanVariables_, assignedIntegerVariables_,
globalBooleanVariables_, globalIntegerVariables_;
/*!
* Adds a new boolean variable with the given name.
*
* @param name The name of the variable.
* @return The global index of the variable.
*/
uint_fast64_t addBooleanVariable(std::string const& name);
/*!
* Adds a new integer variable with the given name.
*
* @param name The name of the variable.
* @return The global index of the variable.
*/
uint_fast64_t addIntegerVariable(std::string const& name);
/*!
* Retrieves the variable expression for the boolean variable with the given name.
*
* @param name The name of the boolean variable for which to retrieve the variable expression.
* @return The variable expression for the boolean variable with the given name.
*/
std::shared_ptr<VariableExpression> getBooleanVariableExpression(std::string const& name) const;
/*!
* Retrieves the variable expression for the integer variable with the given name.
*
* @param name The name of the integer variable for which to retrieve the variable expression.
* @return The variable expression for the integer variable with the given name.
*/
std::shared_ptr<VariableExpression> getIntegerVariableExpression(std::string const& name) const;
/*!
* Retrieve the variable expression for the variable with the given name.
*
* @param name The name of the variable for which to retrieve the variable expression.
* @return The variable expression for the variable with the given name.
*/
std::shared_ptr<VariableExpression> getVariableExpression(std::string const& name) const;
/*!
* Clears all local variables.
*/
void clearLocalVariables();
/*!
* Check if the given string is a free identifier.
*
* @param identifier A string to be checked.
* @return True iff the given string is a free identifier.
*/
bool isFreeIdentifier(std::string const& identifier) const;
/*!
* Check if given string is a valid identifier.
*
* @param identifier A string to be checked.
* @return True iff the given string is an identifier.
*/
bool isIdentifier(std::string const& identifier) const;
/*!
* Prepare state to proceed to second parser run. Currently, this clears the constants.
*/
void prepareForSecondRun();
};
} // namespace prism
} // namespace parser
} // namespace storm
#endif /* STORM_PARSER_PRISMPARSER_VARIABLESTATE_H */

30
src/solver/GurobiLpSolver.cpp

@ -1,6 +1,7 @@
#include "src/solver/GurobiLpSolver.h"
#ifdef STORM_HAVE_GUROBI
#include <numeric>
#include "src/exceptions/InvalidStateException.h"
#include "src/settings/Settings.h"
@ -162,12 +163,29 @@ namespace storm {
throw storm::exceptions::InvalidStateException() << "Sizes of variable indices vector and coefficients vector do not match.";
}
// Convert the uint vector to ints for proper input to Gurobi.
std::vector<int> variablesCopy(variables.begin(), variables.end());
// As Gurobi requires the indices to be unique, we now explicitly make them unique. For this, we sort the
// variables and coefficients and eliminated duplicates by adding the coefficients.
// Copy the coefficients, because Gurobi does not take the coefficients as const values. The alternative to this would be casting
// away the constness, which gives undefined behaviour if Gurobi actually modifies something.
std::vector<double> coefficientsCopy(coefficients);
// We start by sorting both vectors.
std::vector<uint_fast64_t> sortedVariables(variables);
std::vector<double> sortedCoefficients(coefficients);
std::vector<uint_fast64_t> permutation(variables.size());
std::iota(permutation.begin(), permutation.end(), 0);
std::sort(permutation.begin(), permutation.end(), [&] (uint_fast64_t i, uint_fast64_t j) { return variables[i] < variables[j]; } );
std::transform(permutation.begin(), permutation.end(), sortedVariables.begin(), [&] (uint_fast64_t i) { return variables[i]; } );
std::transform(permutation.begin(), permutation.end(), sortedCoefficients.begin(), [&] (uint_fast64_t i) { return coefficients[i]; } );
// Now we perform the duplicate elimination step.
std::vector<int> uniqueVariables;
std::vector<double> uniqueCoefficients;
for (uint_fast64_t i = 0; i < sortedVariables.size(); ++i) {
if (!uniqueVariables.empty() && uniqueVariables.back() == sortedVariables[i]) {
uniqueCoefficients.back() += sortedCoefficients[i];
} else {
uniqueVariables.push_back(static_cast<int>(sortedVariables[i]));
uniqueCoefficients.push_back(sortedCoefficients[i]);
}
}
bool strictBound = boundType == LESS || boundType == GREATER;
char sense = boundType == LESS || boundType == LESS_EQUAL ? GRB_LESS_EQUAL : boundType == EQUAL ? GRB_EQUAL : GRB_GREATER_EQUAL;
@ -181,7 +199,7 @@ namespace storm {
rightHandSideValue += storm::settings::Settings::getInstance()->getOptionByLongName("precision").getArgument(0).getValueAsDouble();
}
}
int error = GRBaddconstr(model, variablesCopy.size(), variablesCopy.data(), coefficientsCopy.data(), sense, rightHandSideValue, name == "" ? nullptr : name.c_str());
int error = GRBaddconstr(model, uniqueVariables.size(), uniqueVariables.data(), uniqueCoefficients.data(), sense, rightHandSideValue, name == "" ? nullptr : name.c_str());
if (error) {
LOG4CPLUS_ERROR(logger, "Unable to assert Gurobi constraint (" << GRBgeterrormsg(env) << ", error code " << error << ").");

225
src/storage/dd/CuddDd.cpp

@ -7,22 +7,26 @@
namespace storm {
namespace dd {
Dd<CUDD>::Dd(std::shared_ptr<DdManager<CUDD>> ddManager, ADD cuddAdd, std::set<std::string> const& containedMetaVariableNames) : ddManager(ddManager), cuddAdd(cuddAdd), containedMetaVariableNames(containedMetaVariableNames) {
Dd<DdType::CUDD>::Dd(std::shared_ptr<DdManager<DdType::CUDD>> ddManager, ADD cuddAdd, std::set<std::string> const& containedMetaVariableNames) : ddManager(ddManager), cuddAdd(cuddAdd), containedMetaVariableNames(containedMetaVariableNames) {
// Intentionally left empty.
}
bool Dd<CUDD>::operator==(Dd<CUDD> const& other) const {
return this->getCuddAdd() == other.getCuddAdd();
bool Dd<DdType::CUDD>::operator==(Dd<DdType::CUDD> const& other) const {
return this->cuddAdd == other.getCuddAdd();
}
Dd<CUDD> Dd<CUDD>::operator+(Dd<CUDD> const& other) const {
Dd<CUDD> result(*this);
bool Dd<DdType::CUDD>::operator!=(Dd<DdType::CUDD> const& other) const {
return this->cuddAdd != other.getCuddAdd();
}
Dd<DdType::CUDD> Dd<DdType::CUDD>::operator+(Dd<DdType::CUDD> const& other) const {
Dd<DdType::CUDD> result(*this);
result += other;
return result;
}
Dd<CUDD>& Dd<CUDD>::operator+=(Dd<CUDD> const& other) {
this->getCuddAdd() += other.getCuddAdd();
Dd<DdType::CUDD>& Dd<DdType::CUDD>::operator+=(Dd<DdType::CUDD> const& other) {
this->cuddAdd += other.getCuddAdd();
// Join the variable sets of the two participating DDs.
this->getContainedMetaVariableNames().insert(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().end());
@ -30,14 +34,14 @@ namespace storm {
return *this;
}
Dd<CUDD> Dd<CUDD>::operator*(Dd<CUDD> const& other) const {
Dd<CUDD> result(*this);
Dd<DdType::CUDD> Dd<DdType::CUDD>::operator*(Dd<DdType::CUDD> const& other) const {
Dd<DdType::CUDD> result(*this);
result *= other;
return result;
}
Dd<CUDD>& Dd<CUDD>::operator*=(Dd<CUDD> const& other) {
this->getCuddAdd() *= other.getCuddAdd();
Dd<DdType::CUDD>& Dd<DdType::CUDD>::operator*=(Dd<DdType::CUDD> const& other) {
this->cuddAdd *= other.getCuddAdd();
// Join the variable sets of the two participating DDs.
this->getContainedMetaVariableNames().insert(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().end());
@ -45,14 +49,14 @@ namespace storm {
return *this;
}
Dd<CUDD> Dd<CUDD>::operator-(Dd<CUDD> const& other) const {
Dd<CUDD> result(*this);
Dd<DdType::CUDD> Dd<DdType::CUDD>::operator-(Dd<DdType::CUDD> const& other) const {
Dd<DdType::CUDD> result(*this);
result -= other;
return result;
}
Dd<CUDD>& Dd<CUDD>::operator-=(Dd<CUDD> const& other) {
this->getCuddAdd() -= other.getCuddAdd();
Dd<DdType::CUDD>& Dd<DdType::CUDD>::operator-=(Dd<DdType::CUDD> const& other) {
this->cuddAdd -= other.getCuddAdd();
// Join the variable sets of the two participating DDs.
this->getContainedMetaVariableNames().insert(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().end());
@ -60,14 +64,14 @@ namespace storm {
return *this;
}
Dd<CUDD> Dd<CUDD>::operator/(Dd<CUDD> const& other) const {
Dd<CUDD> result(*this);
Dd<DdType::CUDD> Dd<DdType::CUDD>::operator/(Dd<DdType::CUDD> const& other) const {
Dd<DdType::CUDD> result(*this);
result /= other;
return result;
}
Dd<CUDD>& Dd<CUDD>::operator/=(Dd<CUDD> const& other) {
this->getCuddAdd().Divide(other.getCuddAdd());
Dd<DdType::CUDD>& Dd<DdType::CUDD>::operator/=(Dd<DdType::CUDD> const& other) {
this->cuddAdd = this->cuddAdd.Divide(other.getCuddAdd());
// Join the variable sets of the two participating DDs.
this->getContainedMetaVariableNames().insert(other.getContainedMetaVariableNames().begin(), other.getContainedMetaVariableNames().end());
@ -75,55 +79,55 @@ namespace storm {
return *this;
}
Dd<CUDD> Dd<CUDD>::operator~() const {
Dd<CUDD> result(*this);
Dd<DdType::CUDD> Dd<DdType::CUDD>::operator~() const {
Dd<DdType::CUDD> result(*this);
result.complement();
return result;
}
Dd<CUDD>& Dd<CUDD>::complement() {
this->getCuddAdd() = ~this->getCuddAdd();
Dd<DdType::CUDD>& Dd<DdType::CUDD>::complement() {
this->cuddAdd = ~this->cuddAdd;
return *this;
}
Dd<CUDD> Dd<CUDD>::equals(Dd<CUDD> const& other) const {
Dd<CUDD> result(*this);
result.getCuddAdd().Equals(other.getCuddAdd());
Dd<DdType::CUDD> Dd<DdType::CUDD>::equals(Dd<DdType::CUDD> const& other) const {
Dd<DdType::CUDD> result(*this);
result.cuddAdd = result.cuddAdd.Equals(other.getCuddAdd());
return result;
}
Dd<CUDD> Dd<CUDD>::notEquals(Dd<CUDD> const& other) const {
Dd<CUDD> result(*this);
result.getCuddAdd().NotEquals(other.getCuddAdd());
Dd<DdType::CUDD> Dd<DdType::CUDD>::notEquals(Dd<DdType::CUDD> const& other) const {
Dd<DdType::CUDD> result(*this);
result.cuddAdd = result.cuddAdd.NotEquals(other.getCuddAdd());
return result;
}
Dd<CUDD> Dd<CUDD>::less(Dd<CUDD> const& other) const {
Dd<CUDD> result(*this);
result.getCuddAdd().LessThan(other.getCuddAdd());
Dd<DdType::CUDD> Dd<DdType::CUDD>::less(Dd<DdType::CUDD> const& other) const {
Dd<DdType::CUDD> result(*this);
result.cuddAdd = result.cuddAdd.LessThan(other.getCuddAdd());
return result;
}
Dd<CUDD> Dd<CUDD>::lessOrEqual(Dd<CUDD> const& other) const {
Dd<CUDD> result(*this);
result.getCuddAdd().LessThanOrEqual(other.getCuddAdd());
Dd<DdType::CUDD> Dd<DdType::CUDD>::lessOrEqual(Dd<DdType::CUDD> const& other) const {
Dd<DdType::CUDD> result(*this);
result.cuddAdd = result.cuddAdd.LessThanOrEqual(other.getCuddAdd());
return result;
}
Dd<CUDD> Dd<CUDD>::greater(Dd<CUDD> const& other) const {
Dd<CUDD> result(*this);
result.getCuddAdd().GreaterThan(other.getCuddAdd());
Dd<DdType::CUDD> Dd<DdType::CUDD>::greater(Dd<DdType::CUDD> const& other) const {
Dd<DdType::CUDD> result(*this);
result.cuddAdd = result.cuddAdd.GreaterThan(other.getCuddAdd());
return result;
}
Dd<CUDD> Dd<CUDD>::greaterOrEqual(Dd<CUDD> const& other) const {
Dd<CUDD> result(*this);
result.getCuddAdd().GreaterThanOrEqual(other.getCuddAdd());
Dd<DdType::CUDD> Dd<DdType::CUDD>::greaterOrEqual(Dd<DdType::CUDD> const& other) const {
Dd<DdType::CUDD> result(*this);
result.cuddAdd = result.cuddAdd.GreaterThanOrEqual(other.getCuddAdd());
return result;
}
void Dd<CUDD>::existsAbstract(std::set<std::string> const& metaVariableNames) {
Dd<CUDD> cubeDd(this->getDdManager()->getOne());
void Dd<DdType::CUDD>::existsAbstract(std::set<std::string> const& metaVariableNames) {
Dd<DdType::CUDD> cubeDd(this->getDdManager()->getOne());
for (auto const& metaVariableName : metaVariableNames) {
// First check whether the DD contains the meta variable and erase it, if this is the case.
@ -132,15 +136,15 @@ namespace storm {
}
this->getContainedMetaVariableNames().erase(metaVariableName);
DdMetaVariable<CUDD> const& metaVariable = this->getDdManager()->getMetaVariable(metaVariableName);
DdMetaVariable<DdType::CUDD> const& metaVariable = this->getDdManager()->getMetaVariable(metaVariableName);
cubeDd *= metaVariable.getCube();
}
this->getCuddAdd().OrAbstract(cubeDd.getCuddAdd());
this->cuddAdd = this->cuddAdd.OrAbstract(cubeDd.getCuddAdd());
}
void Dd<CUDD>::sumAbstract(std::set<std::string> const& metaVariableNames) {
Dd<CUDD> cubeDd(this->getDdManager()->getOne());
void Dd<DdType::CUDD>::sumAbstract(std::set<std::string> const& metaVariableNames) {
Dd<DdType::CUDD> cubeDd(this->getDdManager()->getOne());
for (auto const& metaVariableName : metaVariableNames) {
// First check whether the DD contains the meta variable and erase it, if this is the case.
@ -149,15 +153,15 @@ namespace storm {
}
this->getContainedMetaVariableNames().erase(metaVariableName);
DdMetaVariable<CUDD> const& metaVariable = this->getDdManager()->getMetaVariable(metaVariableName);
DdMetaVariable<DdType::CUDD> const& metaVariable = this->getDdManager()->getMetaVariable(metaVariableName);
cubeDd *= metaVariable.getCube();
}
this->getCuddAdd().ExistAbstract(cubeDd.getCuddAdd());
this->cuddAdd = this->cuddAdd.ExistAbstract(cubeDd.getCuddAdd());
}
void Dd<CUDD>::minAbstract(std::set<std::string> const& metaVariableNames) {
Dd<CUDD> cubeDd(this->getDdManager()->getOne());
void Dd<DdType::CUDD>::minAbstract(std::set<std::string> const& metaVariableNames) {
Dd<DdType::CUDD> cubeDd(this->getDdManager()->getOne());
for (auto const& metaVariableName : metaVariableNames) {
// First check whether the DD contains the meta variable and erase it, if this is the case.
@ -166,15 +170,15 @@ namespace storm {
}
this->getContainedMetaVariableNames().erase(metaVariableName);
DdMetaVariable<CUDD> const& metaVariable = this->getDdManager()->getMetaVariable(metaVariableName);
DdMetaVariable<DdType::CUDD> const& metaVariable = this->getDdManager()->getMetaVariable(metaVariableName);
cubeDd *= metaVariable.getCube();
}
this->getCuddAdd().Minimum(cubeDd.getCuddAdd());
this->cuddAdd = this->cuddAdd.MinAbstract(cubeDd.getCuddAdd());
}
void Dd<CUDD>::maxAbstract(std::set<std::string> const& metaVariableNames) {
Dd<CUDD> cubeDd(this->getDdManager()->getOne());
void Dd<DdType::CUDD>::maxAbstract(std::set<std::string> const& metaVariableNames) {
Dd<DdType::CUDD> cubeDd(this->getDdManager()->getOne());
for (auto const& metaVariableName : metaVariableNames) {
// First check whether the DD contains the meta variable and erase it, if this is the case.
@ -183,19 +187,19 @@ namespace storm {
}
this->getContainedMetaVariableNames().erase(metaVariableName);
DdMetaVariable<CUDD> const& metaVariable = this->getDdManager()->getMetaVariable(metaVariableName);
DdMetaVariable<DdType::CUDD> const& metaVariable = this->getDdManager()->getMetaVariable(metaVariableName);
cubeDd *= metaVariable.getCube();
}
this->getCuddAdd().Maximum(cubeDd.getCuddAdd());
this->cuddAdd = this->cuddAdd.MaxAbstract(cubeDd.getCuddAdd());
}
void Dd<CUDD>::swapVariables(std::vector<std::pair<std::string, std::string>> const& metaVariablePairs) {
void Dd<DdType::CUDD>::swapVariables(std::vector<std::pair<std::string, std::string>> const& metaVariablePairs) {
std::vector<ADD> from;
std::vector<ADD> to;
for (auto const& metaVariablePair : metaVariablePairs) {
DdMetaVariable<CUDD> const& variable1 = this->getDdManager()->getMetaVariable(metaVariablePair.first);
DdMetaVariable<CUDD> const& variable2 = this->getDdManager()->getMetaVariable(metaVariablePair.second);
DdMetaVariable<DdType::CUDD> const& variable1 = this->getDdManager()->getMetaVariable(metaVariablePair.first);
DdMetaVariable<DdType::CUDD> const& variable2 = this->getDdManager()->getMetaVariable(metaVariablePair.second);
// Check if it's legal so swap the meta variables.
if (variable1.getNumberOfDdVariables() != variable2.getNumberOfDdVariables()) {
@ -223,10 +227,10 @@ namespace storm {
}
// Finally, call CUDD to swap the variables.
this->getCuddAdd().SwapVariables(from, to);
this->cuddAdd = this->cuddAdd.SwapVariables(from, to);
}
Dd<CUDD> Dd<CUDD>::multiplyMatrix(Dd<CUDD> const& otherMatrix, std::set<std::string> const& summationMetaVariableNames) {
Dd<DdType::CUDD> Dd<DdType::CUDD>::multiplyMatrix(Dd<DdType::CUDD> const& otherMatrix, std::set<std::string> const& summationMetaVariableNames) {
std::vector<ADD> summationDdVariables;
// Create the CUDD summation variables.
@ -241,11 +245,10 @@ namespace storm {
std::set<std::string> containedMetaVariableNames;
std::set_difference(unionOfMetaVariableNames.begin(), unionOfMetaVariableNames.end(), summationMetaVariableNames.begin(), summationMetaVariableNames.end(), std::inserter(containedMetaVariableNames, containedMetaVariableNames.begin()));
return Dd<CUDD>(this->getDdManager(), this->getCuddAdd().MatrixMultiply(otherMatrix.getCuddAdd(), summationDdVariables), containedMetaVariableNames);
return Dd<DdType::CUDD>(this->getDdManager(), this->cuddAdd.MatrixMultiply(otherMatrix.getCuddAdd(), summationDdVariables), containedMetaVariableNames);
}
uint_fast64_t Dd<CUDD>::getNonZeroCount() const {
uint_fast64_t Dd<DdType::CUDD>::getNonZeroCount() const {
std::size_t numberOfDdVariables = 0;
for (auto const& metaVariableName : this->containedMetaVariableNames) {
numberOfDdVariables += this->getDdManager()->getMetaVariable(metaVariableName).getNumberOfDdVariables();
@ -253,60 +256,85 @@ namespace storm {
return static_cast<uint_fast64_t>(this->cuddAdd.CountMinterm(static_cast<int>(numberOfDdVariables)));
}
uint_fast64_t Dd<CUDD>::getLeafCount() const {
uint_fast64_t Dd<DdType::CUDD>::getLeafCount() const {
return static_cast<uint_fast64_t>(this->cuddAdd.CountLeaves());
}
uint_fast64_t Dd<CUDD>::getNodeCount() const {
uint_fast64_t Dd<DdType::CUDD>::getNodeCount() const {
return static_cast<uint_fast64_t>(this->cuddAdd.nodeCount());
}
double Dd<CUDD>::getMin() const {
ADD constantMinAdd = this->getCuddAdd().FindMin();
double Dd<DdType::CUDD>::getMin() const {
ADD constantMinAdd = this->cuddAdd.FindMin();
return static_cast<double>(Cudd_V(constantMinAdd.getNode()));
}
double Dd<CUDD>::getMax() const {
ADD constantMaxAdd = this->getCuddAdd().FindMax();
double Dd<DdType::CUDD>::getMax() const {
ADD constantMaxAdd = this->cuddAdd.FindMax();
return static_cast<double>(Cudd_V(constantMaxAdd.getNode()));
}
void Dd<CUDD>::setValue(std::string const& metaVariableName, int_fast64_t variableValue, double targetValue) {
std::unordered_map<std::string, int_fast64_t> metaVariableNameToValueMap;
void Dd<DdType::CUDD>::setValue(std::string const& metaVariableName, int_fast64_t variableValue, double targetValue) {
std::map<std::string, int_fast64_t> metaVariableNameToValueMap;
metaVariableNameToValueMap.emplace(metaVariableName, variableValue);
this->setValue(metaVariableNameToValueMap, targetValue);
}
void Dd<CUDD>::setValue(std::string const& metaVariableName1, int_fast64_t variableValue1, std::string const& metaVariableName2, int_fast64_t variableValue2, double targetValue) {
std::unordered_map<std::string, int_fast64_t> metaVariableNameToValueMap;
void Dd<DdType::CUDD>::setValue(std::string const& metaVariableName1, int_fast64_t variableValue1, std::string const& metaVariableName2, int_fast64_t variableValue2, double targetValue) {
std::map<std::string, int_fast64_t> metaVariableNameToValueMap;
metaVariableNameToValueMap.emplace(metaVariableName1, variableValue1);
metaVariableNameToValueMap.emplace(metaVariableName2, variableValue2);
this->setValue(metaVariableNameToValueMap, targetValue);
}
void Dd<CUDD>::setValue(std::unordered_map<std::string, int_fast64_t> const& metaVariableNameToValueMap, double targetValue) {
Dd<CUDD> valueEncoding(this->getDdManager()->getOne());
void Dd<DdType::CUDD>::setValue(std::map<std::string, int_fast64_t> const& metaVariableNameToValueMap, double targetValue) {
Dd<DdType::CUDD> valueEncoding(this->getDdManager()->getOne());
for (auto const& nameValuePair : metaVariableNameToValueMap) {
valueEncoding *= this->getDdManager()->getEncoding(nameValuePair.first, nameValuePair.second);
// Also record that the DD now contains the meta variable.
this->addContainedMetaVariable(nameValuePair.first);
}
this->cuddAdd = valueEncoding.getCuddAdd().Ite(this->getDdManager()->getConstant(targetValue).getCuddAdd(), this->cuddAdd);
}
double Dd<DdType::CUDD>::getValue(std::map<std::string, int_fast64_t> const& metaVariableNameToValueMap) const {
std::set<std::string> remainingMetaVariables(this->getContainedMetaVariableNames());
Dd<DdType::CUDD> valueEncoding(this->getDdManager()->getOne());
for (auto const& nameValuePair : metaVariableNameToValueMap) {
valueEncoding *= this->getDdManager()->getEncoding(nameValuePair.first, nameValuePair.second);
if (this->containsMetaVariable(nameValuePair.first)) {
remainingMetaVariables.erase(nameValuePair.first);
}
}
if (!remainingMetaVariables.empty()) {
throw storm::exceptions::InvalidArgumentException() << "Cannot evaluate function for which not all inputs were given.";
}
this->getCuddAdd() = valueEncoding.getCuddAdd().Ite(this->getDdManager()->getConstant(targetValue).getCuddAdd(), this->cuddAdd);
Dd<DdType::CUDD> value = *this * valueEncoding;
value.sumAbstract(this->getContainedMetaVariableNames());
return static_cast<double>(Cudd_V(value.getCuddAdd().getNode()));
}
bool Dd<CUDD>::isOne() const {
bool Dd<DdType::CUDD>::isOne() const {
return *this == this->getDdManager()->getOne();
}
bool Dd<CUDD>::isZero() const {
bool Dd<DdType::CUDD>::isZero() const {
return *this == this->getDdManager()->getZero();
}
bool Dd<CUDD>::containsMetaVariable(std::string const& metaVariableName) const {
bool Dd<DdType::CUDD>::isConstant() const {
return Cudd_IsConstant(this->cuddAdd.getNode());
}
bool Dd<DdType::CUDD>::containsMetaVariable(std::string const& metaVariableName) const {
auto const& metaVariable = containedMetaVariableNames.find(metaVariableName);
return metaVariable != containedMetaVariableNames.end();
}
bool Dd<CUDD>::containsMetaVariables(std::set<std::string> metaVariableNames) const {
bool Dd<DdType::CUDD>::containsMetaVariables(std::set<std::string> metaVariableNames) const {
for (auto const& metaVariableName : metaVariableNames) {
auto const& metaVariable = containedMetaVariableNames.find(metaVariableName);
@ -317,38 +345,49 @@ namespace storm {
return true;
}
std::set<std::string> const& Dd<CUDD>::getContainedMetaVariableNames() const {
std::set<std::string> const& Dd<DdType::CUDD>::getContainedMetaVariableNames() const {
return this->containedMetaVariableNames;
}
std::set<std::string>& Dd<CUDD>::getContainedMetaVariableNames() {
std::set<std::string>& Dd<DdType::CUDD>::getContainedMetaVariableNames() {
return this->containedMetaVariableNames;
}
void Dd<CUDD>::exportToDot(std::string const& filename) const {
FILE* filePointer = fopen(filename.c_str() , "w");
this->getDdManager()->getCuddManager().DumpDot({this->cuddAdd}, nullptr, nullptr, filePointer);
fclose(filePointer);
void Dd<DdType::CUDD>::exportToDot(std::string const& filename) const {
std::vector<ADD> cuddAddVector = { this->cuddAdd };
if (filename.empty()) {
this->getDdManager()->getCuddManager().DumpDot(cuddAddVector);
} else {
FILE* filePointer = fopen(filename.c_str() , "w");
this->getDdManager()->getCuddManager().DumpDot(cuddAddVector, nullptr, nullptr, filePointer);
fclose(filePointer);
}
}
ADD Dd<CUDD>::getCuddAdd() {
ADD Dd<DdType::CUDD>::getCuddAdd() {
return this->cuddAdd;
}
ADD const& Dd<CUDD>::getCuddAdd() const {
ADD const& Dd<DdType::CUDD>::getCuddAdd() const {
return this->cuddAdd;
}
void Dd<CUDD>::addContainedMetaVariable(std::string const& metaVariableName) {
void Dd<DdType::CUDD>::addContainedMetaVariable(std::string const& metaVariableName) {
this->getContainedMetaVariableNames().insert(metaVariableName);
}
void Dd<CUDD>::removeContainedMetaVariable(std::string const& metaVariableName) {
void Dd<DdType::CUDD>::removeContainedMetaVariable(std::string const& metaVariableName) {
this->getContainedMetaVariableNames().erase(metaVariableName);
}
std::shared_ptr<DdManager<CUDD>> Dd<CUDD>::getDdManager() const {
std::shared_ptr<DdManager<DdType::CUDD>> Dd<DdType::CUDD>::getDdManager() const {
return this->ddManager;
}
std::ostream & operator<<(std::ostream& out, const Dd<DdType::CUDD>& dd) {
dd.exportToDot();
return out;
}
}
}

93
src/storage/dd/CuddDd.h

@ -1,9 +1,10 @@
#ifndef STORM_STORAGE_DD_CUDDDD_H_
#define STORM_STORAGE_DD_CUDDDD_H_
#include <unordered_map>
#include <map>
#include <set>
#include <memory>
#include <iostream>
#include "src/storage/dd/Dd.h"
#include "src/utility/OsDetection.h"
@ -17,26 +18,35 @@ namespace storm {
template<DdType Type> class DdManager;
template<>
class Dd<CUDD> {
class Dd<DdType::CUDD> {
public:
// Declare the DdManager class as friend so it can access the internals of a DD.
friend class DdManager<CUDD>;
friend class DdManager<DdType::CUDD>;
// Instantiate all copy/move constructors/assignments with the default implementation.
Dd() = default;
Dd(Dd<CUDD> const& other) = default;
Dd& operator=(Dd<CUDD> const& other) = default;
Dd(Dd<DdType::CUDD> const& other) = default;
Dd& operator=(Dd<DdType::CUDD> const& other) = default;
#ifndef WINDOWS
Dd(Dd<CUDD>&& other) = default;
Dd& operator=(Dd<CUDD>&& other) = default;
Dd(Dd<DdType::CUDD>&& other) = default;
Dd& operator=(Dd<DdType::CUDD>&& other) = default;
#endif
/*!
* Retrieves whether the two DDs represent the same function.
*
* @param other The DD that is to be compared with the current one.
* @return True if the DDs represent the same function.
*/
bool operator==(Dd<CUDD> const& other) const;
bool operator==(Dd<DdType::CUDD> const& other) const;
/*!
* Retrieves whether the two DDs represent different functions.
*
* @param other The DD that is to be compared with the current one.
* @return True if the DDs represent the different functions.
*/
bool operator!=(Dd<DdType::CUDD> const& other) const;
/*!
* Adds the two DDs.
@ -44,7 +54,7 @@ namespace storm {
* @param other The DD to add to the current one.
* @return The result of the addition.
*/
Dd<CUDD> operator+(Dd<CUDD> const& other) const;
Dd<DdType::CUDD> operator+(Dd<DdType::CUDD> const& other) const;
/*!
* Adds the given DD to the current one.
@ -52,7 +62,7 @@ namespace storm {
* @param other The DD to add to the current one.
* @return A reference to the current DD after the operation.
*/
Dd<CUDD>& operator+=(Dd<CUDD> const& other);
Dd<DdType::CUDD>& operator+=(Dd<DdType::CUDD> const& other);
/*!
* Multiplies the two DDs.
@ -60,7 +70,7 @@ namespace storm {
* @param other The DD to multiply with the current one.
* @return The result of the multiplication.
*/
Dd<CUDD> operator*(Dd<CUDD> const& other) const;
Dd<DdType::CUDD> operator*(Dd<DdType::CUDD> const& other) const;
/*!
* Multiplies the given DD with the current one and assigns the result to the current DD.
@ -68,7 +78,7 @@ namespace storm {
* @param other The DD to multiply with the current one.
* @return A reference to the current DD after the operation.
*/
Dd<CUDD>& operator*=(Dd<CUDD> const& other);
Dd<DdType::CUDD>& operator*=(Dd<DdType::CUDD> const& other);
/*!
* Subtracts the given DD from the current one.
@ -76,7 +86,7 @@ namespace storm {
* @param other The DD to subtract from the current one.
* @return The result of the subtraction.
*/
Dd<CUDD> operator-(Dd<CUDD> const& other) const;
Dd<DdType::CUDD> operator-(Dd<DdType::CUDD> const& other) const;
/*!
* Subtracts the given DD from the current one and assigns the result to the current DD.
@ -84,7 +94,7 @@ namespace storm {
* @param other The DD to subtract from the current one.
* @return A reference to the current DD after the operation.
*/
Dd<CUDD>& operator-=(Dd<CUDD> const& other);
Dd<DdType::CUDD>& operator-=(Dd<DdType::CUDD> const& other);
/*!
* Divides the current DD by the given one.
@ -92,7 +102,7 @@ namespace storm {
* @param other The DD by which to divide the current one.
* @return The result of the division.
*/
Dd<CUDD> operator/(Dd<CUDD> const& other) const;
Dd<DdType::CUDD> operator/(Dd<DdType::CUDD> const& other) const;
/*!
* Divides the current DD by the given one and assigns the result to the current DD.
@ -100,14 +110,14 @@ namespace storm {
* @param other The DD by which to divide the current one.
* @return A reference to the current DD after the operation.
*/
Dd<CUDD>& operator/=(Dd<CUDD> const& other);
Dd<DdType::CUDD>& operator/=(Dd<DdType::CUDD> const& other);
/*!
* Subtracts the DD from the constant zero function.
*
* @return The resulting function represented as a DD.
*/
Dd<CUDD> minus() const;
Dd<DdType::CUDD> minus() const;
/*!
* Retrieves the logical complement of the current DD. The result will map all encodings with a value
@ -115,7 +125,7 @@ namespace storm {
*
* @return The logical complement of the current DD.
*/
Dd<CUDD> operator~() const;
Dd<DdType::CUDD> operator~() const;
/*!
* Logically complements the current DD. The result will map all encodings with a value
@ -123,7 +133,7 @@ namespace storm {
*
* @return A reference to the current DD after the operation.
*/
Dd<CUDD>& complement();
Dd<DdType::CUDD>& complement();
/*!
* Retrieves the function that maps all evaluations to one that have an identical function values.
@ -131,7 +141,7 @@ namespace storm {
* @param other The DD with which to perform the operation.
* @return The resulting function represented as a DD.
*/
Dd<CUDD> equals(Dd<CUDD> const& other) const;
Dd<DdType::CUDD> equals(Dd<DdType::CUDD> const& other) const;
/*!
* Retrieves the function that maps all evaluations to one that have distinct function values.
@ -139,7 +149,7 @@ namespace storm {
* @param other The DD with which to perform the operation.
* @return The resulting function represented as a DD.
*/
Dd<CUDD> notEquals(Dd<CUDD> const& other) const;
Dd<DdType::CUDD> notEquals(Dd<DdType::CUDD> const& other) const;
/*!
* Retrieves the function that maps all evaluations to one whose function value in the first DD are less
@ -148,7 +158,7 @@ namespace storm {
* @param other The DD with which to perform the operation.
* @return The resulting function represented as a DD.
*/
Dd<CUDD> less(Dd<CUDD> const& other) const;
Dd<DdType::CUDD> less(Dd<DdType::CUDD> const& other) const;
/*!
* Retrieves the function that maps all evaluations to one whose function value in the first DD are less or
@ -157,7 +167,7 @@ namespace storm {
* @param other The DD with which to perform the operation.
* @return The resulting function represented as a DD.
*/
Dd<CUDD> lessOrEqual(Dd<CUDD> const& other) const;
Dd<DdType::CUDD> lessOrEqual(Dd<DdType::CUDD> const& other) const;
/*!
* Retrieves the function that maps all evaluations to one whose function value in the first DD are greater
@ -166,7 +176,7 @@ namespace storm {
* @param other The DD with which to perform the operation.
* @return The resulting function represented as a DD.
*/
Dd<CUDD> greater(Dd<CUDD> const& other) const;
Dd<DdType::CUDD> greater(Dd<DdType::CUDD> const& other) const;
/*!
* Retrieves the function that maps all evaluations to one whose function value in the first DD are greater
@ -175,7 +185,7 @@ namespace storm {
* @param other The DD with which to perform the operation.
* @return The resulting function represented as a DD.
*/
Dd<CUDD> greaterOrEqual(Dd<CUDD> const& other) const;
Dd<DdType::CUDD> greaterOrEqual(Dd<DdType::CUDD> const& other) const;
/*!
* Existentially abstracts from the given meta variables.
@ -222,7 +232,7 @@ namespace storm {
* matrix multiplication.
* @return A DD representing the result of the matrix-matrix multiplication.
*/
Dd<CUDD> multiplyMatrix(Dd<CUDD> const& otherMatrix, std::set<std::string> const& summationMetaVariableNames);
Dd<DdType::CUDD> multiplyMatrix(Dd<DdType::CUDD> const& otherMatrix, std::set<std::string> const& summationMetaVariableNames);
/*!
* Retrieves the number of encodings that are mapped to a non-zero value.
@ -294,7 +304,16 @@ namespace storm {
* have. All values must be within the range of the respective meta variable.
* @param targetValue The new function value of the modified encodings.
*/
void setValue(std::unordered_map<std::string, int_fast64_t> const& metaVariableNameToValueMap, double targetValue);
void setValue(std::map<std::string, int_fast64_t> const& metaVariableNameToValueMap = std::map<std::string, int_fast64_t>(), double targetValue = 0);
/*!
* Retrieves the value of the function when all meta variables are assigned the values of the given mapping.
* Note that the mapping must specify values for all meta variables contained in the DD.
*
* @param metaVariableNameToValueMap A mapping of meta variable names to their values.
* @return The value of the function evaluated with the given input.
*/
double getValue(std::map<std::string, int_fast64_t> const& metaVariableNameToValueMap = std::map<std::string, int_fast64_t>()) const;
/*!
* Retrieves whether this DD represents the constant one function.
@ -310,6 +329,13 @@ namespace storm {
*/
bool isZero() const;
/*!
* Retrieves whether this DD represents a constant function.
*
* @return True if this DD represents a constants function.
*/
bool isConstant() const;
/*!
* Retrieves whether the given meta variable is contained in the DD.
*
@ -345,20 +371,21 @@ namespace storm {
*
* @param filename The name of the file to which the DD is to be exported.
*/
void exportToDot(std::string const& filename) const;
void exportToDot(std::string const& filename = "") const;
/*!
* Retrieves the manager that is responsible for this DD.
*
* A pointer to the manager that is responsible for this DD.
*/
std::shared_ptr<DdManager<CUDD>> getDdManager() const;
std::shared_ptr<DdManager<DdType::CUDD>> getDdManager() const;
friend std::ostream & operator<<(std::ostream& out, const Dd<DdType::CUDD>& dd);
private:
/*!
* Retrieves the CUDD ADD object associated with this DD.
* Retrieves a reference to the CUDD ADD object associated with this DD.
*
* @return The CUDD ADD object assoicated with this DD.
* @return The CUDD ADD object associated with this DD.
*/
ADD getCuddAdd();
@ -390,10 +417,10 @@ namespace storm {
* @param cuddAdd The CUDD ADD to store.
* @param
*/
Dd(std::shared_ptr<DdManager<CUDD>> ddManager, ADD cuddAdd, std::set<std::string> const& containedMetaVariableNames = std::set<std::string>());
Dd(std::shared_ptr<DdManager<DdType::CUDD>> ddManager, ADD cuddAdd, std::set<std::string> const& containedMetaVariableNames = std::set<std::string>());
// A pointer to the manager responsible for this DD.
std::shared_ptr<DdManager<CUDD>> ddManager;
std::shared_ptr<DdManager<DdType::CUDD>> ddManager;
// The ADD created by CUDD.
ADD cuddAdd;

96
src/storage/dd/CuddDdManager.cpp

@ -4,34 +4,47 @@
#include "src/storage/dd/CuddDdManager.h"
#include "src/exceptions/InvalidArgumentException.h"
#include <iostream>
namespace storm {
namespace dd {
DdManager<CUDD>::DdManager() : metaVariableMap(), cuddManager() {
DdManager<DdType::CUDD>::DdManager() : metaVariableMap(), cuddManager() {
// Intentionally left empty.
}
Dd<CUDD> DdManager<CUDD>::getOne() {
return Dd<CUDD>(this->shared_from_this(), cuddManager.addOne());
Dd<DdType::CUDD> DdManager<DdType::CUDD>::getOne() {
return Dd<DdType::CUDD>(this->shared_from_this(), cuddManager.addOne());
}
Dd<CUDD> DdManager<CUDD>::getZero() {
return Dd<CUDD>(this->shared_from_this(), cuddManager.addZero());
Dd<DdType::CUDD> DdManager<DdType::CUDD>::getZero() {
return Dd<DdType::CUDD>(this->shared_from_this(), cuddManager.addZero());
}
Dd<CUDD> DdManager<CUDD>::getConstant(double value) {
return Dd<CUDD>(this->shared_from_this(), cuddManager.constant(value));
Dd<DdType::CUDD> DdManager<DdType::CUDD>::getConstant(double value) {
return Dd<DdType::CUDD>(this->shared_from_this(), cuddManager.constant(value));
}
Dd<CUDD> DdManager<CUDD>::getEncoding(std::string const& metaVariableName, int_fast64_t value) {
std::vector<Dd<CUDD>> ddVariables = this->getMetaVariable(metaVariableName).getDdVariables();
Dd<DdType::CUDD> DdManager<DdType::CUDD>::getEncoding(std::string const& metaVariableName, int_fast64_t value) {
// Check whether the meta variable exists.
if (!this->hasMetaVariable(metaVariableName)) {
throw storm::exceptions::InvalidArgumentException() << "Unknown meta variable name '" << metaVariableName << "'.";
}
DdMetaVariable<DdType::CUDD> const& metaVariable = this->getMetaVariable(metaVariableName);
// Check whether the value is legal for this meta variable.
if (value < metaVariable.getLow() || value > metaVariable.getHigh()) {
throw storm::exceptions::InvalidArgumentException() << "Illegal value " << value << " for meta variable '" << metaVariableName << "'.";
}
// Now compute the encoding relative to the low value of the meta variable.
value -= metaVariable.getLow();
std::vector<Dd<DdType::CUDD>> const& ddVariables = metaVariable.getDdVariables();
Dd<CUDD> result;
Dd<DdType::CUDD> result;
if (value & (1ull << (ddVariables.size() - 1))) {
result = ddVariables[0];
} else {
result = ddVariables[0];
result = ~ddVariables[0];
}
for (std::size_t i = 1; i < ddVariables.size(); ++i) {
@ -41,21 +54,42 @@ namespace storm {
result *= ~ddVariables[i];
}
}
return result;
}
Dd<DdType::CUDD> DdManager<DdType::CUDD>::getRange(std::string const& metaVariableName) {
// Check whether the meta variable exists.
if (!this->hasMetaVariable(metaVariableName)) {
throw storm::exceptions::InvalidArgumentException() << "Unknown meta variable name '" << metaVariableName << "'.";
}
storm::dd::DdMetaVariable<DdType::CUDD> const& metaVariable = this->getMetaVariable(metaVariableName);
Dd<DdType::CUDD> result = this->getZero();
for (int_fast64_t value = metaVariable.getLow(); value <= metaVariable.getHigh(); ++value) {
result.setValue(metaVariableName, value, static_cast<double>(1));
}
return result;
}
Dd<CUDD> DdManager<CUDD>::getRange(std::string const metaVariableName) {
storm::dd::DdMetaVariable<CUDD> const& metaVariable = this->getMetaVariable(metaVariableName);
Dd<DdType::CUDD> DdManager<DdType::CUDD>::getIdentity(std::string const& metaVariableName) {
// Check whether the meta variable exists.
if (!this->hasMetaVariable(metaVariableName)) {
throw storm::exceptions::InvalidArgumentException() << "Unknown meta variable name '" << metaVariableName << "'.";
}
storm::dd::DdMetaVariable<DdType::CUDD> const& metaVariable = this->getMetaVariable(metaVariableName);
Dd<CUDD> result = this->getZero();
Dd<DdType::CUDD> result = this->getZero();
for (int_fast64_t value = metaVariable.getLow(); value <= metaVariable.getHigh(); ++value) {
result.setValue(metaVariableName, value - metaVariable.getLow(), static_cast<double>(value));
result.setValue(metaVariableName, value, static_cast<double>(value));
}
return result;
}
void DdManager<CUDD>::addMetaVariable(std::string const& name, int_fast64_t low, int_fast64_t high) {
void DdManager<DdType::CUDD>::addMetaVariable(std::string const& name, int_fast64_t low, int_fast64_t high) {
// Check whether a meta variable already exists.
if (this->hasMetaVariable(name)) {
throw storm::exceptions::InvalidArgumentException() << "A meta variable '" << name << "' already exists.";
@ -68,15 +102,15 @@ namespace storm {
std::size_t numberOfBits = static_cast<std::size_t>(std::ceil(std::log2(high - low + 1)));
std::vector<Dd<CUDD>> variables;
std::vector<Dd<DdType::CUDD>> variables;
for (std::size_t i = 0; i < numberOfBits; ++i) {
variables.emplace_back(Dd<CUDD>(this->shared_from_this(), cuddManager.addVar(), {name}));
variables.emplace_back(Dd<DdType::CUDD>(this->shared_from_this(), cuddManager.addVar(), {name}));
}
metaVariableMap.emplace(name, DdMetaVariable<CUDD>(name, low, high, variables, this->shared_from_this()));
metaVariableMap.emplace(name, DdMetaVariable<DdType::CUDD>(name, low, high, variables, this->shared_from_this()));
}
void DdManager<CUDD>::addMetaVariablesInterleaved(std::vector<std::string> const& names, int_fast64_t low, int_fast64_t high) {
void DdManager<DdType::CUDD>::addMetaVariablesInterleaved(std::vector<std::string> const& names, int_fast64_t low, int_fast64_t high) {
// Make sure that at least one meta variable is added.
if (names.size() == 0) {
throw storm::exceptions::InvalidArgumentException() << "Illegal to add zero meta variables.";
@ -103,30 +137,30 @@ namespace storm {
// Add the variables in interleaved order.
std::size_t numberOfBits = static_cast<std::size_t>(std::ceil(std::log2(high - low + 1)));
std::vector<std::vector<Dd<CUDD>>> variables(names.size());
std::vector<std::vector<Dd<DdType::CUDD>>> variables(names.size());
for (uint_fast64_t bit = 0; bit < numberOfBits; ++bit) {
for (uint_fast64_t i = 0; i < names.size(); ++i) {
variables[i].emplace_back(Dd<CUDD>(this->shared_from_this(), cuddManager.addVar(), {names[i]}));
variables[i].emplace_back(Dd<DdType::CUDD>(this->shared_from_this(), cuddManager.addVar(), {names[i]}));
}
}
// Now add the meta variables.
for (uint_fast64_t i = 0; i < names.size(); ++i) {
metaVariableMap.emplace(names[i], DdMetaVariable<CUDD>(names[i], low, high, variables[i], this->shared_from_this()));
metaVariableMap.emplace(names[i], DdMetaVariable<DdType::CUDD>(names[i], low, high, variables[i], this->shared_from_this()));
}
}
DdMetaVariable<CUDD> const& DdManager<CUDD>::getMetaVariable(std::string const& metaVariableName) const {
DdMetaVariable<DdType::CUDD> const& DdManager<DdType::CUDD>::getMetaVariable(std::string const& metaVariableName) const {
auto const& nameVariablePair = metaVariableMap.find(metaVariableName);
if (!this->hasMetaVariable(metaVariableName)) {
throw storm::exceptions::InvalidArgumentException() << "Unknown meta variable name.";
throw storm::exceptions::InvalidArgumentException() << "Unknown meta variable name '" << metaVariableName << "'.";
}
return nameVariablePair->second;
}
std::set<std::string> DdManager<CUDD>::getAllMetaVariableNames() const {
std::set<std::string> DdManager<DdType::CUDD>::getAllMetaVariableNames() const {
std::set<std::string> result;
for (auto const& nameValuePair : metaVariableMap) {
result.insert(nameValuePair.first);
@ -134,15 +168,15 @@ namespace storm {
return result;
}
std::size_t DdManager<CUDD>::getNumberOfMetaVariables() const {
std::size_t DdManager<DdType::CUDD>::getNumberOfMetaVariables() const {
return this->metaVariableMap.size();
}
bool DdManager<CUDD>::hasMetaVariable(std::string const& metaVariableName) const {
bool DdManager<DdType::CUDD>::hasMetaVariable(std::string const& metaVariableName) const {
return this->metaVariableMap.find(metaVariableName) != this->metaVariableMap.end();
}
Cudd& DdManager<CUDD>::getCuddManager() {
Cudd& DdManager<DdType::CUDD>::getCuddManager() {
return this->cuddManager;
}
}

37
src/storage/dd/CuddDdManager.h

@ -14,10 +14,10 @@
namespace storm {
namespace dd {
template<>
class DdManager<CUDD> : public std::enable_shared_from_this<DdManager<CUDD>> {
class DdManager<DdType::CUDD> : public std::enable_shared_from_this<DdManager<DdType::CUDD>> {
public:
// To break the cylic dependencies, we need to forward-declare the other DD-related classes.
friend class Dd<CUDD>;
friend class Dd<DdType::CUDD>;
/*!
* Creates an empty manager without any meta variables.
@ -25,11 +25,11 @@ namespace storm {
DdManager();
// Explictly forbid copying a DdManager, but allow moving it.
DdManager(DdManager<CUDD> const& other) = delete;
DdManager<CUDD>& operator=(DdManager<CUDD> const& other) = delete;
DdManager(DdManager<DdType::CUDD> const& other) = delete;
DdManager<DdType::CUDD>& operator=(DdManager<DdType::CUDD> const& other) = delete;
#ifndef WINDOWS
DdManager(DdManager<CUDD>&& other) = default;
DdManager<CUDD>& operator=(DdManager<CUDD>&& other) = default;
DdManager(DdManager<DdType::CUDD>&& other) = default;
DdManager<DdType::CUDD>& operator=(DdManager<DdType::CUDD>&& other) = default;
#endif
/*!
@ -37,21 +37,21 @@ namespace storm {
*
* @return A DD representing the constant one function.
*/
Dd<CUDD> getOne();
Dd<DdType::CUDD> getOne();
/*!
* Retrieves a DD representing the constant zero function.
*
* @return A DD representing the constant zero function.
*/
Dd<CUDD> getZero();
Dd<DdType::CUDD> getZero();
/*!
* Retrieves a DD representing the constant function with the given value.
*
* @return A DD representing the constant function with the given value.
*/
Dd<CUDD> getConstant(double value);
Dd<DdType::CUDD> getConstant(double value);
/*!
* Retrieves the DD representing the function that maps all inputs which have the given meta variable equal
@ -62,16 +62,25 @@ namespace storm {
* @return The DD representing the function that maps all inputs which have the given meta variable equal
* to the given value one.
*/
Dd<CUDD> getEncoding(std::string const& metaVariableName, int_fast64_t value);
Dd<DdType::CUDD> getEncoding(std::string const& metaVariableName, int_fast64_t value);
/*!
* Retrieves the DD representing the range of the meta variable, i.e., a function that maps all legal values
* of the range of the meta variable to one.
*
* @param metaVariableName The name of the meta variable whose range to retrieve.
* @return The range of the meta variable
* @return The range of the meta variable.
*/
Dd<CUDD> getRange(std::string const metaVariableName);
Dd<DdType::CUDD> getRange(std::string const& metaVariableName);
/*!
* Retrieves the DD representing the identity of the meta variable, i.e., a function that maps all legal
* values of the range of the meta variable to themselves.
*
* @param metaVariableName The name of the meta variable whose identity to retrieve.
* @return The identity of the meta variable.
*/
Dd<DdType::CUDD> getIdentity(std::string const& metaVariableName);
/*!
* Adds a meta variable with the given name and range.
@ -97,7 +106,7 @@ namespace storm {
* @param metaVariableName The name of the meta variable to retrieve.
* @return The meta variable with the given name.
*/
DdMetaVariable<CUDD> const& getMetaVariable(std::string const& metaVariableName) const;
DdMetaVariable<DdType::CUDD> const& getMetaVariable(std::string const& metaVariableName) const;
/*!
* Retrieves the names of all meta variables that have been added to the manager.
@ -130,7 +139,7 @@ namespace storm {
Cudd& getCuddManager();
// A mapping from variable names to the meta variable information.
std::unordered_map<std::string, DdMetaVariable<CUDD>> metaVariableMap;
std::unordered_map<std::string, DdMetaVariable<DdType::CUDD>> metaVariableMap;
// The manager responsible for the DDs created/modified with this DdManager.
Cudd cuddManager;

2
src/storage/dd/DdMetaVariable.cpp

@ -47,6 +47,6 @@ namespace storm {
}
// Explicitly instantiate DdMetaVariable.
template class DdMetaVariable<CUDD>;
template class DdMetaVariable<DdType::CUDD>;
}
}

2
src/storage/dd/DdType.h

@ -3,7 +3,7 @@
namespace storm {
namespace dd {
enum DdType {
enum class DdType {
CUDD
};
}

65
src/storage/expressions/BaseExpression.cpp

@ -0,0 +1,65 @@
#include "src/storage/expressions/BaseExpression.h"
#include "src/exceptions/ExceptionMacros.h"
#include "src/exceptions/InvalidTypeException.h"
namespace storm {
namespace expressions {
BaseExpression::BaseExpression(ExpressionReturnType returnType) : returnType(returnType) {
// Intentionally left empty.
}
ExpressionReturnType BaseExpression::getReturnType() const {
return this->returnType;
}
bool BaseExpression::hasIntegralReturnType() const {
return this->getReturnType() == ExpressionReturnType::Int;
}
bool BaseExpression::hasNumericalReturnType() const {
return this->getReturnType() == ExpressionReturnType::Double || this->getReturnType() == ExpressionReturnType::Int;
}
bool BaseExpression::hasBooleanReturnType() const {
return this->getReturnType() == ExpressionReturnType::Bool;
}
int_fast64_t BaseExpression::evaluateAsInt(Valuation const* valuation) const {
LOG_THROW(false, storm::exceptions::InvalidTypeException, "Unable to evaluate expression as integer.");
}
bool BaseExpression::evaluateAsBool(Valuation const* valuation) const {
LOG_THROW(false, storm::exceptions::InvalidTypeException, "Unable to evaluate expression as boolean.");
}
double BaseExpression::evaluateAsDouble(Valuation const* valuation) const {
LOG_THROW(false, storm::exceptions::InvalidTypeException, "Unable to evaluate expression as double.");
}
bool BaseExpression::isConstant() const {
return false;
}
bool BaseExpression::isTrue() const {
return false;
}
bool BaseExpression::isFalse() const {
return false;
}
std::shared_ptr<BaseExpression const> BaseExpression::getSharedPointer() const {
return this->shared_from_this();
}
std::ostream& operator<<(std::ostream& stream, ExpressionReturnType const& enumValue) {
stream << static_cast<std::underlying_type<ExpressionReturnType>::type>(enumValue);
return stream;
}
std::ostream& operator<<(std::ostream& stream, BaseExpression const& expression) {
expression.printToStream(stream);
return stream;
}
}
}

Some files were not shown because too many files changed in this diff

|||||||
100:0
Loading…
Cancel
Save