Browse Source

Merge branch 'master' into philippTopologicalRevival

Conflicts:
	CMakeLists.txt
	src/storm.cpp

Former-commit-id: 16c8e8734a
main
PBerger 11 years ago
parent
commit
eca20ce085
  1. 4
      .gitignore
  2. 25
      CMakeLists.txt
  3. 0
      StormCPackConfig.cmake
  4. 4
      examples/dtmc/synchronous_leader/leader4_8.pm
  5. 4
      examples/dtmc/synchronous_leader/leader5_8.pm
  6. 4
      examples/dtmc/synchronous_leader/leader6_8.pm
  7. 9
      resources/3rdparty/cudd-2.5.0/CMakeLists.txt
  8. 3
      resources/3rdparty/cudd-2.5.0/src/cudd/cudd.h
  9. 261
      resources/3rdparty/cudd-2.5.0/src/cudd/cuddAddAbs.c
  10. 19
      resources/3rdparty/cudd-2.5.0/src/cudd/cuddExport.c
  11. 2
      resources/3rdparty/cudd-2.5.0/src/cudd/cuddInt.h
  12. 65
      resources/3rdparty/cudd-2.5.0/src/cudd/cuddSat.c
  13. 33
      resources/3rdparty/cudd-2.5.0/src/obj/cuddObj.cc
  14. 7
      resources/3rdparty/cudd-2.5.0/src/obj/cuddObj.hh
  15. 2
      resources/3rdparty/ltl2dstar-0.5.1/src/parsers/nba-parser-lbtt.lex.cpp
  16. 2
      resources/3rdparty/ltl2dstar-0.5.1/src/parsers/nba-parser-promela.lex.cpp
  17. 298
      src/adapters/ExplicitModelAdapter.h
  18. 4
      src/adapters/GmmxxAdapter.h
  19. 2
      src/adapters/SymbolicModelAdapter.h
  20. 367
      src/counterexamples/MILPMinimalLabelSetGenerator.h
  21. 146
      src/counterexamples/PathBasedSubsystemGenerator.h
  22. 2
      src/counterexamples/SMTMinimalCommandSetGenerator.h
  23. 31
      src/exceptions/ExceptionMacros.h
  24. 17
      src/exceptions/InvalidOperationException.h
  25. 18
      src/exceptions/InvalidTypeException.h
  26. 63
      src/ir/Assignment.cpp
  27. 98
      src/ir/Assignment.h
  28. 49
      src/ir/BooleanVariable.cpp
  29. 70
      src/ir/BooleanVariable.h
  30. 94
      src/ir/Command.cpp
  31. 134
      src/ir/Command.h
  32. 25
      src/ir/IR.h
  33. 72
      src/ir/IntegerVariable.cpp
  34. 98
      src/ir/IntegerVariable.h
  35. 200
      src/ir/Module.cpp
  36. 230
      src/ir/Module.h
  37. 300
      src/ir/Program.cpp
  38. 318
      src/ir/Program.h
  39. 53
      src/ir/RewardModel.cpp
  40. 88
      src/ir/RewardModel.h
  41. 60
      src/ir/StateReward.cpp
  42. 85
      src/ir/StateReward.h
  43. 65
      src/ir/TransitionReward.cpp
  44. 99
      src/ir/TransitionReward.h
  45. 130
      src/ir/Update.cpp
  46. 152
      src/ir/Update.h
  47. 74
      src/ir/Variable.cpp
  48. 124
      src/ir/Variable.h
  49. 85
      src/ir/expressions/BaseExpression.cpp
  50. 172
      src/ir/expressions/BaseExpression.h
  51. 67
      src/ir/expressions/BinaryBooleanFunctionExpression.cpp
  52. 69
      src/ir/expressions/BinaryBooleanFunctionExpression.h
  53. 52
      src/ir/expressions/BinaryExpression.cpp
  54. 66
      src/ir/expressions/BinaryExpression.h
  55. 96
      src/ir/expressions/BinaryNumericalFunctionExpression.cpp
  56. 72
      src/ir/expressions/BinaryNumericalFunctionExpression.h
  57. 75
      src/ir/expressions/BinaryRelationExpression.cpp
  58. 69
      src/ir/expressions/BinaryRelationExpression.h
  59. 45
      src/ir/expressions/BooleanConstantExpression.cpp
  60. 49
      src/ir/expressions/BooleanConstantExpression.h
  61. 49
      src/ir/expressions/BooleanLiteralExpression.cpp
  62. 55
      src/ir/expressions/BooleanLiteralExpression.h
  63. 132
      src/ir/expressions/ConstantExpression.h
  64. 45
      src/ir/expressions/DoubleConstantExpression.cpp
  65. 49
      src/ir/expressions/DoubleConstantExpression.h
  66. 49
      src/ir/expressions/DoubleLiteralExpression.cpp
  67. 55
      src/ir/expressions/DoubleLiteralExpression.h
  68. 49
      src/ir/expressions/ExpressionVisitor.h
  69. 26
      src/ir/expressions/Expressions.h
  70. 48
      src/ir/expressions/IntegerConstantExpression.cpp
  71. 51
      src/ir/expressions/IntegerConstantExpression.h
  72. 53
      src/ir/expressions/IntegerLiteralExpression.cpp
  73. 57
      src/ir/expressions/IntegerLiteralExpression.h
  74. 62
      src/ir/expressions/UnaryBooleanFunctionExpression.cpp
  75. 68
      src/ir/expressions/UnaryBooleanFunctionExpression.h
  76. 39
      src/ir/expressions/UnaryExpression.cpp
  77. 55
      src/ir/expressions/UnaryExpression.h
  78. 86
      src/ir/expressions/UnaryNumericalFunctionExpression.cpp
  79. 70
      src/ir/expressions/UnaryNumericalFunctionExpression.h
  80. 120
      src/ir/expressions/VariableExpression.cpp
  81. 98
      src/ir/expressions/VariableExpression.h
  82. 2
      src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.cpp
  83. 78
      src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h
  84. 2
      src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h
  85. 2
      src/modelchecker/prctl/SparseMdpPrctlModelChecker.h
  86. 6
      src/models/AbstractDeterministicModel.h
  87. 2
      src/models/AbstractModel.h
  88. 4
      src/models/AbstractNondeterministicModel.h
  89. 12
      src/models/Dtmc.h
  90. 14
      src/models/MarkovAutomaton.h
  91. 305
      src/parser/AtomicPropositionLabelingParser.cpp
  92. 36
      src/parser/AtomicPropositionLabelingParser.h
  93. 101
      src/parser/AutoParser.cpp
  94. 171
      src/parser/AutoParser.h
  95. 2
      src/parser/CslParser.h
  96. 80
      src/parser/DeterministicModelParser.cpp
  97. 151
      src/parser/DeterministicModelParser.h
  98. 465
      src/parser/DeterministicSparseTransitionParser.cpp
  99. 99
      src/parser/DeterministicSparseTransitionParser.h
  100. 400
      src/parser/ExpressionParser.cpp

4
.gitignore

@ -33,9 +33,13 @@ resources/3rdparty/cudd-2.5.0/
ipch/
obj/
CMakeFiles/
CPackConfig.cmake
# The build Dir
build/
build//CMakeLists.txt
/*.vcxproj
/*.filters
/*.sln
#Temp texteditor files
*.orig
*.*~

25
CMakeLists.txt

@ -123,6 +123,9 @@ elseif(MSVC)
# Windows.h breaks GMM in gmm_except.h because of its macro definition for min and max
add_definitions(/DNOMINMAX)
# since nobody cares at the moment
add_definitions(/wd4250)
if(ENABLE_Z3)
set(Z3_LIB_NAME "libz3")
endif()
@ -224,6 +227,13 @@ configure_file (
"${PROJECT_SOURCE_DIR}/storm-config.h.in"
"${PROJECT_BINARY_DIR}/include/storm-config.h"
)
# Configure a header file to pass the storm version to the source code
configure_file (
"${PROJECT_SOURCE_DIR}/storm-version.h.in"
"${PROJECT_BINARY_DIR}/include/storm-version.h"
)
# Add the binary dir include directory for storm-config.h
include_directories("${PROJECT_BINARY_DIR}/include")
@ -250,11 +260,11 @@ file(GLOB STORM_PARSER_FILES ${PROJECT_SOURCE_DIR}/src/parser/*.h ${PROJECT_SOUR
file(GLOB_RECURSE STORM_PARSER_PRISMPARSER_FILES ${PROJECT_SOURCE_DIR}/src/parser/prismparser/*.h ${PROJECT_SOURCE_DIR}/src/parser/prismparser/*.cpp)
file(GLOB_RECURSE STORM_SETTINGS_FILES ${PROJECT_SOURCE_DIR}/src/settings/*.h ${PROJECT_SOURCE_DIR}/src/settings/*.cpp)
file(GLOB_RECURSE STORM_SOLVER_FILES ${PROJECT_SOURCE_DIR}/src/solver/*.h ${PROJECT_SOURCE_DIR}/src/solver/*.cpp)
file(GLOB_RECURSE STORM_STORAGE_FILES ${PROJECT_SOURCE_DIR}/src/storage/*.h ${PROJECT_SOURCE_DIR}/src/storage/*.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)
@ -273,8 +283,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})
@ -283,6 +291,9 @@ source_group(parser\\prismparser FILES ${STORM_PARSER_PRISMPARSER_FILES})
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})
@ -542,4 +553,4 @@ INSTALL(TARGETS storm storm-functional-tests storm-performance-tests
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
)
include(CPackConfig.cmake)
include(StormCPackConfig.cmake)

0
CPackConfig.cmake → StormCPackConfig.cmake

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

9
resources/3rdparty/cudd-2.5.0/CMakeLists.txt

@ -25,5 +25,14 @@ if(MSVC)
add_definitions(/D_SCL_SECURE_NO_DEPRECATE /D_CRT_SECURE_NO_WARNINGS)
endif()
# Since we do not target Alphas, this symbol is always set
add_definitions(-DHAVE_IEEE_754)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
message(STATUS "CUDD: Targeting 64bit architecture")
add_definitions(-DSIZEOF_VOID_P=8)
add_definitions(-DSIZEOF_LONG=8)
endif()
# Add the library
add_library(cudd ${CUDD_SOURCES} ${CUDD_HEADERS} ${CUDD_HEADERS_CXX} ${CUDD_SOURCES_CXX})

3
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);
@ -962,6 +964,7 @@ extern DdNode * Cudd_Increasing (DdManager *dd, DdNode *f, int i);
extern int Cudd_EquivDC (DdManager *dd, DdNode *F, DdNode *G, DdNode *D);
extern int Cudd_bddLeqUnless (DdManager *dd, DdNode *f, DdNode *g, DdNode *D);
extern int Cudd_EqualSupNorm (DdManager *dd, DdNode *f, DdNode *g, CUDD_VALUE_TYPE tolerance, int pr);
extern int Cudd_EqualSupNormRel (DdManager *dd, DdNode *f, DdNode *g, CUDD_VALUE_TYPE tolerance, int pr);
extern DdNode * Cudd_bddMakePrime (DdManager *dd, DdNode *cube, DdNode *f);
extern DdNode * Cudd_bddMaximallyExpand(DdManager *dd, DdNode *lb, DdNode *ub, DdNode *f);
extern DdNode * Cudd_bddLargestPrimeUnate(DdManager *dd , DdNode *f, DdNode *phaseBdd);

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 */

19
resources/3rdparty/cudd-2.5.0/src/cudd/cuddExport.c

@ -502,9 +502,11 @@ Cudd_DumpDot(
scan = nodelist[j];
while (scan != NULL) {
if (st_is_member(visited,(char *) scan)) {
retval = fprintf(fp,"\"%p\";\n",
(void *) ((mask & (ptrint) scan) / sizeof(DdNode)));
if (retval == EOF) goto failure;
if (scan != Cudd_ReadZero(dd)) {
retval = fprintf(fp,"\"%p\";\n",
(void *) ((mask & (ptrint) scan) / sizeof(DdNode)));
if (retval == EOF) goto failure;
}
}
scan = scan->next;
}
@ -541,6 +543,12 @@ Cudd_DumpDot(
scan = nodelist[j];
while (scan != NULL) {
if (st_is_member(visited,(char *) scan)) {
retval = fprintf(fp,
"\"%p\" [label = \"%s\"];\n",
(void *) ((mask & (ptrint) scan) /
sizeof(DdNode)), inames[dd->invperm[i]]);
if (retval == EOF) goto failure;
if (cuddT(scan) != Cudd_ReadZero(dd)) {
retval = fprintf(fp,
"\"%p\" -> \"%p\";\n",
(void *) ((mask & (ptrint) scan) /
@ -548,6 +556,8 @@ Cudd_DumpDot(
(void *) ((mask & (ptrint) cuddT(scan)) /
sizeof(DdNode)));
if (retval == EOF) goto failure;
}
if (cuddE(scan) != Cudd_ReadZero(dd)) {
if (Cudd_IsComplement(cuddE(scan))) {
retval = fprintf(fp,
"\"%p\" -> \"%p\" [style = dotted];\n",
@ -565,6 +575,7 @@ Cudd_DumpDot(
}
if (retval == EOF) goto failure;
}
}
scan = scan->next;
}
}
@ -578,11 +589,13 @@ Cudd_DumpDot(
scan = nodelist[j];
while (scan != NULL) {
if (st_is_member(visited,(char *) scan)) {
if (scan != Cudd_ReadZero(dd)) {
retval = fprintf(fp,"\"%p\" [label = \"%g\"];\n",
(void *) ((mask & (ptrint) scan) / sizeof(DdNode)),
cuddV(scan));
if (retval == EOF) goto failure;
}
}
scan = scan->next;
}
}

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);

65
resources/3rdparty/cudd-2.5.0/src/cudd/cuddSat.c

@ -853,6 +853,71 @@ Cudd_EqualSupNorm(
} /* end of Cudd_EqualSupNorm */
/**Function********************************************************************
Synopsis [Compares two ADDs for equality within tolerance.]
Description [Same as Cudd_EqualSupNorm but tests for max _relative_ difference
i.e. (f-g/f)<e instead of (f-g)<e ]
SideEffects [None]
SeeAlso []
******************************************************************************/
int
Cudd_EqualSupNormRel(
DdManager * dd /* manager */,
DdNode * f /* first ADD */,
DdNode * g /* second ADD */,
CUDD_VALUE_TYPE tolerance /* maximum allowed difference */,
int pr /* verbosity level */)
{
DdNode *fv, *fvn, *gv, *gvn, *r;
unsigned int topf, topg;
statLine(dd);
/* Check terminal cases. */
if (f == g) return(1);
if (Cudd_IsConstant(f) && Cudd_IsConstant(g)) {
if (ddAbs((cuddV(f) - cuddV(g))/cuddV(f)) < tolerance) {
return(1);
} else {
if (pr>0) {
(void) fprintf(dd->out,"Offending nodes:\n");
(void) fprintf(dd->out,
"f: address = %p\t value = %40.30f\n",
(void *) f, cuddV(f));
(void) fprintf(dd->out,
"g: address = %p\t value = %40.30f\n",
(void *) g, cuddV(g));
}
return(0);
}
}
/* We only insert the result in the cache if the comparison is
** successful. Therefore, if we hit we return 1. */
r = cuddCacheLookup2(dd,(DD_CTFP)Cudd_EqualSupNormRel,f,g);
if (r != NULL) {
return(1);
}
/* Compute the cofactors and solve the recursive subproblems. */
topf = cuddI(dd,f->index);
topg = cuddI(dd,g->index);
if (topf <= topg) {fv = cuddT(f); fvn = cuddE(f);} else {fv = fvn = f;}
if (topg <= topf) {gv = cuddT(g); gvn = cuddE(g);} else {gv = gvn = g;}
if (!Cudd_EqualSupNormRel(dd,fv,gv,tolerance,pr)) return(0);
if (!Cudd_EqualSupNormRel(dd,fvn,gvn,tolerance,pr)) return(0);
cuddCacheInsert2(dd,(DD_CTFP)Cudd_EqualSupNormRel,f,g,DD_ONE(dd));
return(1);
} /* end of Cudd_EqualSupNormRel */
/**Function********************************************************************

33
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(
@ -4730,6 +4747,16 @@ ADD::EqualSupNorm(
} // ADD::EqualSupNorm
bool
ADD::EqualSupNormRel(
const ADD& g,
CUDD_VALUE_TYPE tolerance,
int pr) const
{
DdManager *mgr = checkSameManager(g);
return Cudd_EqualSupNormRel(mgr, node, g.node, tolerance, pr) != 0;
} // ADD::EqualSupNormRel
BDD
BDD::MakePrime(
@ -5250,14 +5277,14 @@ ABDD::FirstCube(
int
NextCube(
ABDD::NextCube(
DdGen * gen,
int ** cube,
CUDD_VALUE_TYPE * value)
CUDD_VALUE_TYPE * value)
{
return Cudd_NextCube(gen, cube, value);
} // NextCube
} // ABDD::NextCube
BDD

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

@ -192,6 +192,7 @@ public:
const;
int CountLeaves() const;
DdGen * FirstCube(int ** cube, CUDD_VALUE_TYPE * value) const;
static int NextCube(DdGen * gen, int ** cube, CUDD_VALUE_TYPE * value);
double Density(int nvars) const;
}; // ABDD
@ -373,6 +374,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;
@ -424,8 +427,8 @@ public:
ADD TimesPlus(const ADD& B, std::vector<ADD> z) const;
ADD Triangle(const ADD& g, std::vector<ADD> z) const;
ADD Eval(int * inputs) const;
bool EqualSupNorm(const ADD& g, CUDD_VALUE_TYPE tolerance, int pr) const;
bool EqualSupNorm(const ADD& g, CUDD_VALUE_TYPE tolerance, int pr = 0) const;
bool EqualSupNormRel(const ADD& g, CUDD_VALUE_TYPE tolerance, int pr = 0) const;
}; // ADD

2
resources/3rdparty/ltl2dstar-0.5.1/src/parsers/nba-parser-lbtt.lex.cpp

@ -31,7 +31,7 @@
/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
#if (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L) || defined _WIN32
#include <inttypes.h>
typedef int8_t flex_int8_t;
typedef uint8_t flex_uint8_t;

2
resources/3rdparty/ltl2dstar-0.5.1/src/parsers/nba-parser-promela.lex.cpp

@ -31,7 +31,7 @@
/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
#if (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L) || defined _WIN32
#include <inttypes.h>
typedef int8_t flex_int8_t;
typedef uint8_t flex_uint8_t;

298
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.");
ModelComponents modelComponents = buildModelComponents(program, rewardModelName);
// 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(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,25 +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::list<storm::ir::Command> commands;
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::prism::Command>>>();
}
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);
}
}
@ -246,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));
@ -254,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();
@ -279,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);
@ -290,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());
@ -298,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) {
@ -335,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;
@ -452,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.
@ -476,6 +559,8 @@ namespace storm {
// requested and issue an error otherwise.
if (totalNumberOfChoices == 0) {
if (storm::settings::Settings::getInstance()->isSet("fixDeadlocks")) {
// Insert empty choice labeling for added self-loop transitions.
choiceLabels.push_back(boost::container::flat_set<uint_fast64_t>());
transitionMatrixBuilder.addNextValue(currentRow, currentState, storm::utility::constantOne<ValueType>());
++currentRow;
} else {
@ -498,8 +583,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)));
}
}
}
@ -511,8 +596,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)));
}
}
}
@ -549,8 +634,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)));
}
}
@ -576,8 +661,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)));
}
}
@ -609,20 +694,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);
@ -655,30 +748,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;
}
@ -690,14 +782,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]));
}
}
}

4
src/adapters/GmmxxAdapter.h

@ -51,8 +51,8 @@ public:
columns.reserve(matrix.getEntryCount());
for (auto const& entry : matrix) {
columns.emplace_back(entry.first);
values.emplace_back(entry.second);
columns.emplace_back(entry.getColumn());
values.emplace_back(entry.getValue());
}
std::swap(result->ir, columns);

2
src/adapters/SymbolicModelAdapter.h

@ -157,7 +157,6 @@ private:
for (uint_fast64_t j = 0; j < module.getNumberOfBooleanVariables(); ++j) {
storm::ir::BooleanVariable const& booleanVariable = module.getBooleanVariable(j);
bool initialValue = booleanVariable.getInitialValue()->getValueAsBool(nullptr);
*initialStates *= *cuddUtility->getConstantEncoding(1, variableToRowDecisionDiagramVariableMap[booleanVariable.getName()]);
}
for (uint_fast64_t j = 0; j < module.getNumberOfIntegerVariables(); ++j) {
@ -187,7 +186,6 @@ private:
}
bool changed;
int iter = 0;
do {
changed = false;
*newReachableStates = *reachableStates * *systemAdd01;

367
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"
@ -65,13 +65,13 @@ namespace storm {
* A helper struct capturing information about the variables of the MILP formulation.
*/
struct VariableInformation {
std::unordered_map<uint_fast64_t, uint_fast64_t> labelToVariableIndexMap;
std::unordered_map<uint_fast64_t, std::list<uint_fast64_t>> stateToChoiceVariablesIndexMap;
std::unordered_map<uint_fast64_t, uint_fast64_t> initialStateToChoiceVariableIndexMap;
std::unordered_map<uint_fast64_t, uint_fast64_t> stateToProbabilityVariableIndexMap;
uint_fast64_t virtualInitialStateVariableIndex;
std::unordered_map<uint_fast64_t, uint_fast64_t> problematicStateToVariableIndexMap;
std::unordered_map<std::pair<uint_fast64_t, uint_fast64_t>, uint_fast64_t, PairHash> problematicTransitionToVariableIndexMap;
std::unordered_map<uint_fast64_t, std::string> labelToVariableMap;
std::unordered_map<uint_fast64_t, std::list<std::string>> stateToChoiceVariablesMap;
std::unordered_map<uint_fast64_t, std::string> initialStateToChoiceVariableMap;
std::unordered_map<uint_fast64_t, std::string> stateToProbabilityVariableMap;
std::string virtualInitialStateVariable;
std::unordered_map<uint_fast64_t, std::string> problematicStateToVariableMap;
std::unordered_map<std::pair<uint_fast64_t, uint_fast64_t>, std::string, PairHash> problematicTransitionToVariableMap;
uint_fast64_t numberOfVariables;
VariableInformation() : numberOfVariables(0) {}
@ -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.");
@ -131,7 +130,7 @@ namespace storm {
bool allSuccessorsProblematic = true;
for (auto const& successorEntry : transitionMatrix.getRow(row)) {
// If there is a relevant successor, we need to add the labels of the current choice.
if (stateInformation.relevantStates.get(successorEntry.first) || psiStates.get(successorEntry.first)) {
if (stateInformation.relevantStates.get(successorEntry.getColumn()) || psiStates.get(successorEntry.getColumn())) {
for (auto const& label : choiceLabeling[row]) {
result.allRelevantLabels.insert(label);
}
@ -140,7 +139,7 @@ namespace storm {
result.relevantChoicesForRelevantStates[state].push_back(row);
}
}
if (!stateInformation.problematicStates.get(successorEntry.first)) {
if (!stateInformation.problematicStates.get(successorEntry.getColumn())) {
allSuccessorsProblematic = false;
}
}
@ -168,15 +167,15 @@ namespace storm {
* @param relevantLabels The set of relevant labels of the model.
* @return A mapping from labels to variable indices.
*/
static std::pair<std::unordered_map<uint_fast64_t, uint_fast64_t>, uint_fast64_t> createLabelVariables(storm::solver::LpSolver& solver, boost::container::flat_set<uint_fast64_t> const& relevantLabels) {
int error = 0;
static std::pair<std::unordered_map<uint_fast64_t, std::string>, uint_fast64_t> createLabelVariables(storm::solver::LpSolver& solver, boost::container::flat_set<uint_fast64_t> const& relevantLabels) {
std::stringstream variableNameBuffer;
std::unordered_map<uint_fast64_t, uint_fast64_t> resultingMap;
std::unordered_map<uint_fast64_t, std::string> resultingMap;
for (auto const& label : relevantLabels) {
variableNameBuffer.str("");
variableNameBuffer.clear();
variableNameBuffer << "label" << label;
resultingMap[label] = solver.createBinaryVariable(variableNameBuffer.str(), 1);
resultingMap[label] = variableNameBuffer.str();
solver.addBinaryVariable(resultingMap[label], 1);
}
return std::make_pair(resultingMap, relevantLabels.size());
}
@ -189,20 +188,20 @@ namespace storm {
* @param choiceInformation The information about the choices of the model.
* @return A mapping from states to a list of choice variable indices.
*/
static std::pair<std::unordered_map<uint_fast64_t, std::list<uint_fast64_t>>, uint_fast64_t> createSchedulerVariables(storm::solver::LpSolver& solver, StateInformation const& stateInformation, ChoiceInformation const& choiceInformation) {
int error = 0;
static std::pair<std::unordered_map<uint_fast64_t, std::list<std::string>>, uint_fast64_t> createSchedulerVariables(storm::solver::LpSolver& solver, StateInformation const& stateInformation, ChoiceInformation const& choiceInformation) {
std::stringstream variableNameBuffer;
uint_fast64_t numberOfVariablesCreated = 0;
std::unordered_map<uint_fast64_t, std::list<uint_fast64_t>> resultingMap;
std::unordered_map<uint_fast64_t, std::list<std::string>> resultingMap;
for (auto state : stateInformation.relevantStates) {
resultingMap.emplace(state, std::list<uint_fast64_t>());
resultingMap.emplace(state, std::list<std::string>());
std::list<uint_fast64_t> const& relevantChoicesForState = choiceInformation.relevantChoicesForRelevantStates.at(state);
for (uint_fast64_t row : relevantChoicesForState) {
variableNameBuffer.str("");
variableNameBuffer.clear();
variableNameBuffer << "choice" << row << "in" << state;
resultingMap[state].push_back(solver.createBinaryVariable(variableNameBuffer.str(), 0));
resultingMap[state].push_back(variableNameBuffer.str());
solver.addBinaryVariable(resultingMap[state].back());
++numberOfVariablesCreated;
}
}
@ -218,11 +217,10 @@ namespace storm {
* @param stateInformation The information about the states of the model.
* @return A mapping from initial states to choice variable indices.
*/
static std::pair<std::unordered_map<uint_fast64_t, uint_fast64_t>, uint_fast64_t> createInitialChoiceVariables(storm::solver::LpSolver& solver, storm::models::Mdp<T> const& labeledMdp, StateInformation const& stateInformation) {
int error = 0;
static std::pair<std::unordered_map<uint_fast64_t, std::string>, uint_fast64_t> createInitialChoiceVariables(storm::solver::LpSolver& solver, storm::models::Mdp<T> const& labeledMdp, StateInformation const& stateInformation) {
std::stringstream variableNameBuffer;
uint_fast64_t numberOfVariablesCreated = 0;
std::unordered_map<uint_fast64_t, uint_fast64_t> resultingMap;
std::unordered_map<uint_fast64_t, std::string> resultingMap;
for (auto initialState : labeledMdp.getLabeledStates("init")) {
// Only consider this initial state if it is relevant.
@ -230,7 +228,8 @@ namespace storm {
variableNameBuffer.str("");
variableNameBuffer.clear();
variableNameBuffer << "init" << initialState;
resultingMap[initialState] = solver.createBinaryVariable(variableNameBuffer.str(), 0);
resultingMap[initialState] = variableNameBuffer.str();
solver.addBinaryVariable(resultingMap[initialState]);
++numberOfVariablesCreated;
}
}
@ -244,36 +243,36 @@ namespace storm {
* @param stateInformation The information about the states in the model.
* @return A mapping from states to the index of the corresponding probability variables.
*/
static std::pair<std::unordered_map<uint_fast64_t, uint_fast64_t>, uint_fast64_t> createProbabilityVariables(storm::solver::LpSolver& solver, StateInformation const& stateInformation) {
int error = 0;
static std::pair<std::unordered_map<uint_fast64_t, std::string>, uint_fast64_t> createProbabilityVariables(storm::solver::LpSolver& solver, StateInformation const& stateInformation) {
std::stringstream variableNameBuffer;
uint_fast64_t numberOfVariablesCreated = 0;
std::unordered_map<uint_fast64_t, uint_fast64_t> resultingMap;
std::unordered_map<uint_fast64_t, std::string> resultingMap;
for (auto state : stateInformation.relevantStates) {
variableNameBuffer.str("");
variableNameBuffer.clear();
variableNameBuffer << "p" << state;
resultingMap[state] = solver.createContinuousVariable(variableNameBuffer.str(), storm::solver::LpSolver::BOUNDED, 0, 1, 0);
resultingMap[state] = variableNameBuffer.str();
solver.addBoundedContinuousVariable(resultingMap[state], 0, 1);
++numberOfVariablesCreated;
}
return std::make_pair(resultingMap, numberOfVariablesCreated);
}
/*!
* Creates the variables for the probabilities in the model.
* Creates the variable for the probability of the virtual initial state.
*
* @param solver The MILP solver.
* @param maximizeProbability If set to true, the objective function is constructed in a way that a
* label-minimal subsystem of maximal probability is computed.
* @return The index of the variable for the probability of the virtual initial state.
*/
static std::pair<uint_fast64_t, uint_fast64_t> createVirtualInitialStateVariable(storm::solver::LpSolver& solver, bool maximizeProbability = false) {
int error = 0;
static std::pair<std::string, uint_fast64_t> createVirtualInitialStateVariable(storm::solver::LpSolver& solver, bool maximizeProbability = false) {
std::stringstream variableNameBuffer;
variableNameBuffer << "pinit";
return std::make_pair(solver.createContinuousVariable(variableNameBuffer.str(), storm::solver::LpSolver::BOUNDED, 0, 1, 0), 1);
std::string variableName = variableNameBuffer.str();
solver.addBoundedContinuousVariable(variableName, 0, 1);
return std::make_pair(variableName, 1);
}
/*!
@ -284,11 +283,10 @@ namespace storm {
* @param stateInformation The information about the states in the model.
* @return A mapping from problematic states to the index of the corresponding variables.
*/
static std::pair<std::unordered_map<uint_fast64_t, uint_fast64_t>, uint_fast64_t> createProblematicStateVariables(storm::solver::LpSolver& solver, storm::models::Mdp<T> const& labeledMdp, StateInformation const& stateInformation, ChoiceInformation const& choiceInformation) {
int error = 0;
static std::pair<std::unordered_map<uint_fast64_t, std::string>, uint_fast64_t> createProblematicStateVariables(storm::solver::LpSolver& solver, storm::models::Mdp<T> const& labeledMdp, StateInformation const& stateInformation, ChoiceInformation const& choiceInformation) {
std::stringstream variableNameBuffer;
uint_fast64_t numberOfVariablesCreated = 0;
std::unordered_map<uint_fast64_t, uint_fast64_t> resultingMap;
std::unordered_map<uint_fast64_t, std::string> resultingMap;
for (auto state : stateInformation.problematicStates) {
// First check whether there is not already a variable for this state and advance to the next state
@ -297,19 +295,21 @@ namespace storm {
variableNameBuffer.str("");
variableNameBuffer.clear();
variableNameBuffer << "r" << state;
resultingMap[state] = solver.createContinuousVariable(variableNameBuffer.str(), storm::solver::LpSolver::BOUNDED, 0, 1, 0);
resultingMap[state] = variableNameBuffer.str();
solver.addBoundedContinuousVariable(resultingMap[state], 0, 1);
++numberOfVariablesCreated;
}
std::list<uint_fast64_t> const& relevantChoicesForState = choiceInformation.relevantChoicesForRelevantStates.at(state);
for (uint_fast64_t row : relevantChoicesForState) {
for (auto const& successorEntry : labeledMdp.getTransitionMatrix().getRow(row)) {
if (stateInformation.relevantStates.get(successorEntry.first)) {
if (resultingMap.find(successorEntry.first) == resultingMap.end()) {
if (stateInformation.relevantStates.get(successorEntry.getColumn())) {
if (resultingMap.find(successorEntry.getColumn()) == resultingMap.end()) {
variableNameBuffer.str("");
variableNameBuffer.clear();
variableNameBuffer << "r" << successorEntry.first;
resultingMap[state] = solver.createContinuousVariable(variableNameBuffer.str(), storm::solver::LpSolver::BOUNDED, 0, 1, 0);
variableNameBuffer << "r" << successorEntry.getColumn();
resultingMap[successorEntry.getColumn()] = variableNameBuffer.str();
solver.addBoundedContinuousVariable(resultingMap[successorEntry.getColumn()], 0, 1);
++numberOfVariablesCreated;
}
}
@ -328,21 +328,21 @@ namespace storm {
* @param choiceInformation The information about the choices in the model.
* @return A mapping from problematic choices to the index of the corresponding variables.
*/
static std::pair<std::unordered_map<std::pair<uint_fast64_t, uint_fast64_t>, uint_fast64_t, PairHash>, uint_fast64_t> createProblematicChoiceVariables(storm::solver::LpSolver& solver, storm::models::Mdp<T> const& labeledMdp, StateInformation const& stateInformation, ChoiceInformation const& choiceInformation) {
int error = 0;
static std::pair<std::unordered_map<std::pair<uint_fast64_t, uint_fast64_t>, std::string, PairHash>, uint_fast64_t> createProblematicChoiceVariables(storm::solver::LpSolver& solver, storm::models::Mdp<T> const& labeledMdp, StateInformation const& stateInformation, ChoiceInformation const& choiceInformation) {
std::stringstream variableNameBuffer;
uint_fast64_t numberOfVariablesCreated = 0;
std::unordered_map<std::pair<uint_fast64_t, uint_fast64_t>, uint_fast64_t, PairHash> resultingMap;
std::unordered_map<std::pair<uint_fast64_t, uint_fast64_t>, std::string, PairHash> resultingMap;
for (auto state : stateInformation.problematicStates) {
std::list<uint_fast64_t> const& relevantChoicesForState = choiceInformation.relevantChoicesForRelevantStates.at(state);
for (uint_fast64_t row : relevantChoicesForState) {
for (auto const& successorEntry : labeledMdp.getTransitionMatrix().getRow(row)) {
if (stateInformation.relevantStates.get(successorEntry.first)) {
if (stateInformation.relevantStates.get(successorEntry.getColumn())) {
variableNameBuffer.str("");
variableNameBuffer.clear();
variableNameBuffer << "t" << state << "to" << successorEntry.first;
resultingMap[std::make_pair(state, successorEntry.first)] = solver.createBinaryVariable(variableNameBuffer.str(), 0);
variableNameBuffer << "t" << state << "to" << successorEntry.getColumn();
resultingMap[std::make_pair(state, successorEntry.getColumn())] = variableNameBuffer.str();
solver.addBinaryVariable(resultingMap[std::make_pair(state, successorEntry.getColumn())]);
++numberOfVariablesCreated;
}
}
@ -366,44 +366,44 @@ namespace storm {
VariableInformation result;
// Create variables for involved labels.
std::pair<std::unordered_map<uint_fast64_t, uint_fast64_t>, uint_fast64_t> labelVariableResult = createLabelVariables(solver, choiceInformation.allRelevantLabels);
result.labelToVariableIndexMap = std::move(labelVariableResult.first);
std::pair<std::unordered_map<uint_fast64_t, std::string>, uint_fast64_t> labelVariableResult = createLabelVariables(solver, choiceInformation.allRelevantLabels);
result.labelToVariableMap = std::move(labelVariableResult.first);
result.numberOfVariables += labelVariableResult.second;
LOG4CPLUS_DEBUG(logger, "Created variables for labels.");
// Create scheduler variables for relevant states and their actions.
std::pair<std::unordered_map<uint_fast64_t, std::list<uint_fast64_t>>, uint_fast64_t> schedulerVariableResult = createSchedulerVariables(solver, stateInformation, choiceInformation);
result.stateToChoiceVariablesIndexMap = std::move(schedulerVariableResult.first);
std::pair<std::unordered_map<uint_fast64_t, std::list<std::string>>, uint_fast64_t> schedulerVariableResult = createSchedulerVariables(solver, stateInformation, choiceInformation);
result.stateToChoiceVariablesMap = std::move(schedulerVariableResult.first);
result.numberOfVariables += schedulerVariableResult.second;
LOG4CPLUS_DEBUG(logger, "Created variables for nondeterministic choices.");
// Create scheduler variables for nondeterministically choosing an initial state.
std::pair<std::unordered_map<uint_fast64_t, uint_fast64_t>, uint_fast64_t> initialChoiceVariableResult = createInitialChoiceVariables(solver, labeledMdp, stateInformation);
result.initialStateToChoiceVariableIndexMap = std::move(initialChoiceVariableResult.first);
std::pair<std::unordered_map<uint_fast64_t, std::string>, uint_fast64_t> initialChoiceVariableResult = createInitialChoiceVariables(solver, labeledMdp, stateInformation);
result.initialStateToChoiceVariableMap = std::move(initialChoiceVariableResult.first);
result.numberOfVariables += initialChoiceVariableResult.second;
LOG4CPLUS_DEBUG(logger, "Created variables for the nondeterministic choice of the initial state.");
// Create variables for probabilities for all relevant states.
std::pair<std::unordered_map<uint_fast64_t, uint_fast64_t>, uint_fast64_t> probabilityVariableResult = createProbabilityVariables(solver, stateInformation);
result.stateToProbabilityVariableIndexMap = std::move(probabilityVariableResult.first);
std::pair<std::unordered_map<uint_fast64_t, std::string>, uint_fast64_t> probabilityVariableResult = createProbabilityVariables(solver, stateInformation);
result.stateToProbabilityVariableMap = std::move(probabilityVariableResult.first);
result.numberOfVariables += probabilityVariableResult.second;
LOG4CPLUS_DEBUG(logger, "Created variables for the reachability probabilities.");
// Create a probability variable for a virtual initial state that nondeterministically chooses one of the system's real initial states as its target state.
std::pair<uint_fast64_t, uint_fast64_t> virtualInitialStateVariableResult = createVirtualInitialStateVariable(solver);
result.virtualInitialStateVariableIndex = virtualInitialStateVariableResult.first;
std::pair<std::string, uint_fast64_t> virtualInitialStateVariableResult = createVirtualInitialStateVariable(solver);
result.virtualInitialStateVariable = virtualInitialStateVariableResult.first;
result.numberOfVariables += virtualInitialStateVariableResult.second;
LOG4CPLUS_DEBUG(logger, "Created variables for the virtual initial state.");
// Create variables for problematic states.
std::pair<std::unordered_map<uint_fast64_t, uint_fast64_t>, uint_fast64_t> problematicStateVariableResult = createProblematicStateVariables(solver, labeledMdp, stateInformation, choiceInformation);
result.problematicStateToVariableIndexMap = std::move(problematicStateVariableResult.first);
std::pair<std::unordered_map<uint_fast64_t, std::string>, uint_fast64_t> problematicStateVariableResult = createProblematicStateVariables(solver, labeledMdp, stateInformation, choiceInformation);
result.problematicStateToVariableMap = std::move(problematicStateVariableResult.first);
result.numberOfVariables += problematicStateVariableResult.second;
LOG4CPLUS_DEBUG(logger, "Created variables for the problematic states.");
// Create variables for problematic choices.
std::pair<std::unordered_map<std::pair<uint_fast64_t, uint_fast64_t>, uint_fast64_t, PairHash>, uint_fast64_t> problematicTransitionVariableResult = createProblematicChoiceVariables(solver, labeledMdp, stateInformation, choiceInformation);
result.problematicTransitionToVariableIndexMap = problematicTransitionVariableResult.first;
std::pair<std::unordered_map<std::pair<uint_fast64_t, uint_fast64_t>, std::string, PairHash>, uint_fast64_t> problematicTransitionVariableResult = createProblematicChoiceVariables(solver, labeledMdp, stateInformation, choiceInformation);
result.problematicTransitionToVariableMap = problematicTransitionVariableResult.first;
result.numberOfVariables += problematicTransitionVariableResult.second;
LOG4CPLUS_DEBUG(logger, "Created variables for the problematic choices.");
@ -427,7 +427,13 @@ namespace storm {
* @return The total number of constraints that were created.
*/
static uint_fast64_t assertProbabilityGreaterThanThreshold(storm::solver::LpSolver& solver, storm::models::Mdp<T> const& labeledMdp, VariableInformation const& variableInformation, double probabilityThreshold, bool strictBound) {
solver.addConstraint("ProbGreaterThreshold", {variableInformation.virtualInitialStateVariableIndex}, {1}, strictBound ? storm::solver::LpSolver::GREATER : storm::solver::LpSolver::GREATER_EQUAL, probabilityThreshold);
storm::expressions::Expression constraint;
if (strictBound) {
constraint = storm::expressions::Expression::createDoubleVariable(variableInformation.virtualInitialStateVariable) > storm::expressions::Expression::createDoubleLiteral(probabilityThreshold);
} else {
constraint = storm::expressions::Expression::createDoubleVariable(variableInformation.virtualInitialStateVariable) >= storm::expressions::Expression::createDoubleLiteral(probabilityThreshold);
}
solver.addConstraint("ProbGreaterThreshold", constraint);
return 1;
}
@ -443,28 +449,28 @@ namespace storm {
// Assert that the policy chooses at most one action in each state of the system.
uint_fast64_t numberOfConstraintsCreated = 0;
for (auto state : stateInformation.relevantStates) {
std::list<uint_fast64_t> const& choiceVariableIndices = variableInformation.stateToChoiceVariablesIndexMap.at(state);
std::vector<uint_fast64_t> variables;
std::vector<double> coefficients(choiceVariableIndices.size(), 1);
variables.reserve(choiceVariableIndices.size());
for (auto choiceVariableIndex : choiceVariableIndices) {
variables.push_back(choiceVariableIndex);
std::list<std::string> const& choiceVariableIndices = variableInformation.stateToChoiceVariablesMap.at(state);
storm::expressions::Expression constraint = storm::expressions::Expression::createDoubleLiteral(0);
for (auto const& choiceVariable : choiceVariableIndices) {
constraint = constraint + storm::expressions::Expression::createIntegerVariable(choiceVariable);
}
solver.addConstraint("ValidPolicy" + std::to_string(numberOfConstraintsCreated), variables, coefficients, storm::solver::LpSolver::LESS_EQUAL, 1);
constraint = constraint <= storm::expressions::Expression::createDoubleLiteral(1);
solver.addConstraint("ValidPolicy" + std::to_string(numberOfConstraintsCreated), constraint);
++numberOfConstraintsCreated;
}
// Now assert that the virtual initial state picks exactly one initial state from the system as its
// successor state.
std::vector<uint_fast64_t> variables;
variables.reserve(variableInformation.initialStateToChoiceVariableIndexMap.size());
std::vector<double> coefficients(variableInformation.initialStateToChoiceVariableIndexMap.size(), 1);
for (auto initialStateVariableIndexPair : variableInformation.initialStateToChoiceVariableIndexMap) {
variables.push_back(initialStateVariableIndexPair.second);
storm::expressions::Expression constraint = storm::expressions::Expression::createDoubleLiteral(0);
for (auto const& initialStateVariablePair : variableInformation.initialStateToChoiceVariableMap) {
constraint = constraint + storm::expressions::Expression::createIntegerVariable(initialStateVariablePair.second);
}
constraint = constraint == storm::expressions::Expression::createDoubleLiteral(1);
solver.addConstraint("VirtualInitialStateChoosesOneInitialState", variables, coefficients, storm::solver::LpSolver::EQUAL, 1);
solver.addConstraint("VirtualInitialStateChoosesOneInitialState", constraint);
++numberOfConstraintsCreated;
return numberOfConstraintsCreated;
@ -486,13 +492,14 @@ namespace storm {
std::vector<boost::container::flat_set<uint_fast64_t>> const& choiceLabeling = labeledMdp.getChoiceLabeling();
for (auto state : stateInformation.relevantStates) {
std::list<uint_fast64_t>::const_iterator choiceVariableIndicesIterator = variableInformation.stateToChoiceVariablesIndexMap.at(state).begin();
std::list<std::string>::const_iterator choiceVariableIterator = variableInformation.stateToChoiceVariablesMap.at(state).begin();
for (auto choice : choiceInformation.relevantChoicesForRelevantStates.at(state)) {
for (auto label : choiceLabeling[choice]) {
solver.addConstraint("ChoicesImplyLabels" + std::to_string(numberOfConstraintsCreated), {variableInformation.labelToVariableIndexMap.at(label), *choiceVariableIndicesIterator}, {1, -1}, storm::solver::LpSolver::GREATER_EQUAL, 0);
storm::expressions::Expression constraint = storm::expressions::Expression::createIntegerVariable(variableInformation.labelToVariableMap.at(label)) - storm::expressions::Expression::createIntegerVariable(*choiceVariableIterator) >= storm::expressions::Expression::createDoubleLiteral(0);
solver.addConstraint("ChoicesImplyLabels" + std::to_string(numberOfConstraintsCreated), constraint);
++numberOfConstraintsCreated;
}
++choiceVariableIndicesIterator;
++choiceVariableIterator;
}
}
return numberOfConstraintsCreated;
@ -511,16 +518,12 @@ namespace storm {
static uint_fast64_t assertZeroProbabilityWithoutChoice(storm::solver::LpSolver& solver, StateInformation const& stateInformation, ChoiceInformation const& choiceInformation, VariableInformation const& variableInformation) {
uint_fast64_t numberOfConstraintsCreated = 0;
for (auto state : stateInformation.relevantStates) {
std::list<uint_fast64_t> const& choiceVariableIndices = variableInformation.stateToChoiceVariablesIndexMap.at(state);
std::vector<double> coefficients(choiceVariableIndices.size() + 1, -1);
coefficients[0] = 1;
std::vector<uint_fast64_t> variables;
variables.reserve(variableInformation.stateToChoiceVariablesIndexMap.at(state).size() + 1);
variables.push_back(variableInformation.stateToProbabilityVariableIndexMap.at(state));
variables.insert(variables.end(), choiceVariableIndices.begin(), choiceVariableIndices.end());
solver.addConstraint("ProbabilityIsZeroIfNoAction" + std::to_string(numberOfConstraintsCreated), variables, coefficients, storm::solver::LpSolver::LESS_EQUAL, 0);
storm::expressions::Expression constraint = storm::expressions::Expression::createDoubleVariable(variableInformation.stateToProbabilityVariableMap.at(state));
for (auto const& choiceVariable : variableInformation.stateToChoiceVariablesMap.at(state)) {
constraint = constraint - storm::expressions::Expression::createIntegerVariable(choiceVariable);
}
constraint = constraint <= storm::expressions::Expression::createDoubleLiteral(0);
solver.addConstraint("ProbabilityIsZeroIfNoAction" + std::to_string(numberOfConstraintsCreated), constraint);
++numberOfConstraintsCreated;
}
return numberOfConstraintsCreated;
@ -539,42 +542,33 @@ namespace storm {
*/
static uint_fast64_t assertReachabilityProbabilities(storm::solver::LpSolver& solver, storm::models::Mdp<T> const& labeledMdp, storm::storage::BitVector const& psiStates, StateInformation const& stateInformation, ChoiceInformation const& choiceInformation, VariableInformation const& variableInformation) {
uint_fast64_t numberOfConstraintsCreated = 0;
int error = 0;
for (auto state : stateInformation.relevantStates) {
std::vector<double> coefficients;
std::vector<uint_fast64_t> variables;
std::list<uint_fast64_t>::const_iterator choiceVariableIndicesIterator = variableInformation.stateToChoiceVariablesIndexMap.at(state).begin();
std::list<std::string>::const_iterator choiceVariableIterator = variableInformation.stateToChoiceVariablesMap.at(state).begin();
for (auto choice : choiceInformation.relevantChoicesForRelevantStates.at(state)) {
variables.clear();
coefficients.clear();
variables.push_back(variableInformation.stateToProbabilityVariableIndexMap.at(state));
coefficients.push_back(1.0);
storm::expressions::Expression constraint = storm::expressions::Expression::createDoubleVariable(variableInformation.stateToProbabilityVariableMap.at(state));
double rightHandSide = 1;
for (auto const& successorEntry : labeledMdp.getTransitionMatrix().getRow(choice)) {
if (stateInformation.relevantStates.get(successorEntry.first)) {
variables.push_back(static_cast<int>(variableInformation.stateToProbabilityVariableIndexMap.at(successorEntry.first)));
coefficients.push_back(-successorEntry.second);
} else if (psiStates.get(successorEntry.first)) {
rightHandSide += successorEntry.second;
if (stateInformation.relevantStates.get(successorEntry.getColumn())) {
constraint = constraint - storm::expressions::Expression::createDoubleLiteral(successorEntry.getValue()) * storm::expressions::Expression::createDoubleVariable(variableInformation.stateToProbabilityVariableMap.at(successorEntry.getColumn()));
} else if (psiStates.get(successorEntry.getColumn())) {
rightHandSide += successorEntry.getValue();
}
}
coefficients.push_back(1);
variables.push_back(*choiceVariableIndicesIterator);
solver.addConstraint("ReachabilityProbabilities" + std::to_string(numberOfConstraintsCreated), variables, coefficients, storm::solver::LpSolver::LESS_EQUAL, rightHandSide);
constraint = constraint + storm::expressions::Expression::createIntegerVariable(*choiceVariableIterator) <= storm::expressions::Expression::createDoubleLiteral(rightHandSide);
solver.addConstraint("ReachabilityProbabilities" + std::to_string(numberOfConstraintsCreated), constraint);
++numberOfConstraintsCreated;
++choiceVariableIndicesIterator;
++choiceVariableIterator;
}
}
// Make sure that the virtual initial state is being assigned the probability from the initial state
// that it selected as a successor state.
for (auto initialStateVariableIndexPair : variableInformation.initialStateToChoiceVariableIndexMap) {
solver.addConstraint("VirtualInitialStateHasCorrectProbability" + std::to_string(numberOfConstraintsCreated), {variableInformation.virtualInitialStateVariableIndex, variableInformation.stateToProbabilityVariableIndexMap.at(initialStateVariableIndexPair.first), initialStateVariableIndexPair.second}, {1, -1, 1}, storm::solver::LpSolver::LESS_EQUAL, 1);
for (auto const& initialStateVariablePair : variableInformation.initialStateToChoiceVariableMap) {
storm::expressions::Expression constraint = storm::expressions::Expression::createDoubleVariable(variableInformation.virtualInitialStateVariable) - storm::expressions::Expression::createDoubleVariable(variableInformation.stateToProbabilityVariableMap.at(initialStateVariablePair.first)) + storm::expressions::Expression::createDoubleVariable(initialStateVariablePair.second) <= storm::expressions::Expression::createDoubleLiteral(1);
solver.addConstraint("VirtualInitialStateHasCorrectProbability" + std::to_string(numberOfConstraintsCreated), constraint);
++numberOfConstraintsCreated;
}
@ -596,44 +590,34 @@ namespace storm {
for (auto stateListPair : choiceInformation.problematicChoicesForProblematicStates) {
for (auto problematicChoice : stateListPair.second) {
std::list<uint_fast64_t>::const_iterator choiceVariableIndicesIterator = variableInformation.stateToChoiceVariablesIndexMap.at(stateListPair.first).begin();
std::list<std::string>::const_iterator choiceVariableIterator = variableInformation.stateToChoiceVariablesMap.at(stateListPair.first).begin();
for (auto relevantChoice : choiceInformation.relevantChoicesForRelevantStates.at(stateListPair.first)) {
if (relevantChoice == problematicChoice) {
break;
}
++choiceVariableIndicesIterator;
++choiceVariableIterator;
}
std::vector<uint_fast64_t> variables;
std::vector<double> coefficients;
variables.push_back(*choiceVariableIndicesIterator);
coefficients.push_back(1);
storm::expressions::Expression constraint = storm::expressions::Expression::createDoubleVariable(*choiceVariableIterator);
for (auto const& successorEntry : labeledMdp.getTransitionMatrix().getRow(problematicChoice)) {
variables.push_back(variableInformation.problematicTransitionToVariableIndexMap.at(std::make_pair(stateListPair.first, successorEntry.first)));
coefficients.push_back(-1);
constraint = constraint - storm::expressions::Expression::createDoubleVariable(variableInformation.problematicTransitionToVariableMap.at(std::make_pair(stateListPair.first, successorEntry.getColumn())));
}
constraint = constraint <= storm::expressions::Expression::createDoubleLiteral(0);
solver.addConstraint("UnproblematicStateReachable" + std::to_string(numberOfConstraintsCreated), variables, coefficients, storm::solver::LpSolver::LESS_EQUAL, 0);
solver.addConstraint("UnproblematicStateReachable" + std::to_string(numberOfConstraintsCreated), constraint);
++numberOfConstraintsCreated;
}
}
for (auto state : stateInformation.problematicStates) {
for (auto problematicChoice : choiceInformation.problematicChoicesForProblematicStates.at(state)) {
for (auto const& successorEntry : labeledMdp.getTransitionMatrix().getRow(state)) {
std::vector<uint_fast64_t> variables;
std::vector<double> coefficients;
variables.push_back(variableInformation.problematicStateToVariableIndexMap.at(state));
coefficients.push_back(1);
variables.push_back(variableInformation.problematicStateToVariableIndexMap.at(successorEntry.first));
coefficients.push_back(-1);
variables.push_back(variableInformation.problematicTransitionToVariableIndexMap.at(std::make_pair(state, successorEntry.first)));
coefficients.push_back(1);
for (auto const& successorEntry : labeledMdp.getTransitionMatrix().getRow(problematicChoice)) {
storm::expressions::Expression constraint = storm::expressions::Expression::createDoubleVariable(variableInformation.problematicStateToVariableMap.at(state));
constraint = constraint - storm::expressions::Expression::createDoubleVariable(variableInformation.problematicStateToVariableMap.at(successorEntry.getColumn()));
constraint = constraint + storm::expressions::Expression::createDoubleVariable(variableInformation.problematicTransitionToVariableMap.at(std::make_pair(state, successorEntry.getColumn())));
constraint = constraint < storm::expressions::Expression::createDoubleLiteral(1);
solver.addConstraint("UnproblematicStateReachable" + std::to_string(numberOfConstraintsCreated), variables, coefficients, storm::solver::LpSolver::LESS, 1);
solver.addConstraint("UnproblematicStateReachable" + std::to_string(numberOfConstraintsCreated), constraint);
++numberOfConstraintsCreated;
}
}
@ -655,7 +639,8 @@ namespace storm {
uint_fast64_t numberOfConstraintsCreated = 0;
for (auto label : choiceInformation.knownLabels) {
solver.addConstraint("KnownLabels" + std::to_string(numberOfConstraintsCreated), {variableInformation.labelToVariableIndexMap.at(label)}, {1}, storm::solver::LpSolver::EQUAL, 1);
storm::expressions::Expression constraint = storm::expressions::Expression::createDoubleVariable(variableInformation.labelToVariableMap.at(label)) == storm::expressions::Expression::createDoubleLiteral(1);
solver.addConstraint("KnownLabels" + std::to_string(numberOfConstraintsCreated), constraint);
++numberOfConstraintsCreated;
}
@ -676,61 +661,52 @@ namespace storm {
static uint_fast64_t assertSchedulerCuts(storm::solver::LpSolver& solver, storm::models::Mdp<T> const& labeledMdp, storm::storage::BitVector const& psiStates, StateInformation const& stateInformation, ChoiceInformation const& choiceInformation, VariableInformation const& variableInformation) {
storm::storage::SparseMatrix<T> backwardTransitions = labeledMdp.getBackwardTransitions();
uint_fast64_t numberOfConstraintsCreated = 0;
std::vector<uint_fast64_t> variables;
std::vector<double> coefficients;
for (auto state : stateInformation.relevantStates) {
// Assert that all states, that select an action, this action either has a non-zero probability to
// go to a psi state directly, or in the successor states, at least one action is selected as well.
std::list<uint_fast64_t>::const_iterator choiceVariableIndicesIterator = variableInformation.stateToChoiceVariablesIndexMap.at(state).begin();
std::list<std::string>::const_iterator choiceVariableIterator = variableInformation.stateToChoiceVariablesMap.at(state).begin();
for (auto choice : choiceInformation.relevantChoicesForRelevantStates.at(state)) {
bool psiStateReachableInOneStep = false;
for (auto const& successorEntry : labeledMdp.getTransitionMatrix().getRow(choice)) {
if (psiStates.get(successorEntry.first)) {
if (psiStates.get(successorEntry.getColumn())) {
psiStateReachableInOneStep = true;
}
}
if (!psiStateReachableInOneStep) {
variables.clear();
coefficients.clear();
variables.push_back(static_cast<int>(*choiceVariableIndicesIterator));
coefficients.push_back(1);
storm::expressions::Expression constraint = storm::expressions::Expression::createDoubleVariable(*choiceVariableIterator);
for (auto const& successorEntry : labeledMdp.getTransitionMatrix().getRow(choice)) {
if (state != successorEntry.first && stateInformation.relevantStates.get(successorEntry.first)) {
std::list<uint_fast64_t> const& successorChoiceVariableIndices = variableInformation.stateToChoiceVariablesIndexMap.at(successorEntry.first);
if (state != successorEntry.getColumn() && stateInformation.relevantStates.get(successorEntry.getColumn())) {
std::list<std::string> const& successorChoiceVariableIndices = variableInformation.stateToChoiceVariablesMap.at(successorEntry.getColumn());
for (auto choiceVariableIndex : successorChoiceVariableIndices) {
variables.push_back(choiceVariableIndex);
coefficients.push_back(-1);
for (auto const& choiceVariable : successorChoiceVariableIndices) {
constraint = constraint - storm::expressions::Expression::createDoubleVariable(choiceVariable);
}
}
}
constraint = constraint <= storm::expressions::Expression::createDoubleLiteral(1);
solver.addConstraint("SchedulerCuts" + std::to_string(numberOfConstraintsCreated), variables, coefficients, storm::solver::LpSolver::LESS_EQUAL, 1);
solver.addConstraint("SchedulerCuts" + std::to_string(numberOfConstraintsCreated), constraint);
++numberOfConstraintsCreated;
}
++choiceVariableIndicesIterator;
++choiceVariableIterator;
}
// For all states assert that there is either a selected incoming transition in the subsystem or the
// state is the chosen initial state if there is one selected action in the current state.
variables.clear();
coefficients.clear();
for (auto choiceVariableIndex : variableInformation.stateToChoiceVariablesIndexMap.at(state)) {
variables.push_back(choiceVariableIndex);
coefficients.push_back(1);
storm::expressions::Expression constraint = storm::expressions::Expression::createDoubleLiteral(0);
for (auto const& choiceVariable : variableInformation.stateToChoiceVariablesMap.at(state)) {
constraint = constraint + storm::expressions::Expression::createDoubleVariable(choiceVariable);
}
// Compute the set of predecessors.
std::unordered_set<uint_fast64_t> predecessors;
for (auto const& predecessorEntry : backwardTransitions.getRow(state)) {
if (state != predecessorEntry.first) {
predecessors.insert(predecessorEntry.first);
if (state != predecessorEntry.getColumn()) {
predecessors.insert(predecessorEntry.getColumn());
}
}
@ -740,13 +716,13 @@ namespace storm {
continue;
}
std::list<uint_fast64_t>::const_iterator choiceVariableIndicesIterator = variableInformation.stateToChoiceVariablesIndexMap.at(predecessor).begin();
std::list<std::string>::const_iterator choiceVariableIterator = variableInformation.stateToChoiceVariablesMap.at(predecessor).begin();
for (auto relevantChoice : choiceInformation.relevantChoicesForRelevantStates.at(predecessor)) {
bool choiceTargetsCurrentState = false;
// Check if the current choice targets the current state.
for (auto const& successorEntry : labeledMdp.getTransitionMatrix().getRow(relevantChoice)) {
if (state == successorEntry.first) {
if (state == successorEntry.getColumn()) {
choiceTargetsCurrentState = true;
break;
}
@ -754,45 +730,42 @@ namespace storm {
// If it does, we can add the choice to the sum.
if (choiceTargetsCurrentState) {
variables.push_back(static_cast<int>(*choiceVariableIndicesIterator));
coefficients.push_back(-1);
constraint = constraint - storm::expressions::Expression::createDoubleVariable(*choiceVariableIterator);
}
++choiceVariableIndicesIterator;
++choiceVariableIterator;
}
}
// If the current state is an initial state and is selected as a successor state by the virtual
// initial state, then this also justifies making a choice in the current state.
if (labeledMdp.getLabeledStates("init").get(state)) {
variables.push_back(variableInformation.initialStateToChoiceVariableIndexMap.at(state));
coefficients.push_back(-1);
constraint = constraint - storm::expressions::Expression::createDoubleVariable(variableInformation.initialStateToChoiceVariableMap.at(state));
}
constraint = constraint <= storm::expressions::Expression::createDoubleLiteral(0);
solver.addConstraint("SchedulerCuts" + std::to_string(numberOfConstraintsCreated), variables, coefficients, storm::solver::LpSolver::LESS_EQUAL, 0);
solver.addConstraint("SchedulerCuts" + std::to_string(numberOfConstraintsCreated), constraint);
++numberOfConstraintsCreated;
}
// Assert that at least one initial state selects at least one action.
variables.clear();
coefficients.clear();
storm::expressions::Expression constraint = storm::expressions::Expression::createDoubleLiteral(0);
for (auto initialState : labeledMdp.getLabeledStates("init")) {
for (auto choiceVariableIndex : variableInformation.stateToChoiceVariablesIndexMap.at(initialState)) {
variables.push_back(choiceVariableIndex);
coefficients.push_back(1);
for (auto const& choiceVariable : variableInformation.stateToChoiceVariablesMap.at(initialState)) {
constraint = constraint + storm::expressions::Expression::createDoubleVariable(choiceVariable);
}
}
solver.addConstraint("SchedulerCuts" + std::to_string(numberOfConstraintsCreated), variables, coefficients, storm::solver::LpSolver::GREATER_EQUAL, 1);
constraint = constraint >= storm::expressions::Expression::createDoubleLiteral(1);
solver.addConstraint("SchedulerCuts" + std::to_string(numberOfConstraintsCreated), constraint);
++numberOfConstraintsCreated;
// Add constraints that ensure at least one choice is selected that targets a psi state.
variables.clear();
coefficients.clear();
constraint = storm::expressions::Expression::createDoubleLiteral(0);
std::unordered_set<uint_fast64_t> predecessors;
for (auto psiState : psiStates) {
// Compute the set of predecessors.
for (auto const& predecessorEntry : backwardTransitions.getRow(psiState)) {
if (psiState != predecessorEntry.first) {
predecessors.insert(predecessorEntry.first);
if (psiState != predecessorEntry.getColumn()) {
predecessors.insert(predecessorEntry.getColumn());
}
}
}
@ -803,13 +776,13 @@ namespace storm {
continue;
}
std::list<uint_fast64_t>::const_iterator choiceVariableIndicesIterator = variableInformation.stateToChoiceVariablesIndexMap.at(predecessor).begin();
std::list<std::string>::const_iterator choiceVariableIterator = variableInformation.stateToChoiceVariablesMap.at(predecessor).begin();
for (auto relevantChoice : choiceInformation.relevantChoicesForRelevantStates.at(predecessor)) {
bool choiceTargetsPsiState = false;
// Check if the current choice targets the current state.
for (auto const& successorEntry : labeledMdp.getTransitionMatrix().getRow(relevantChoice)) {
if (psiStates.get(successorEntry.first)) {
if (psiStates.get(successorEntry.getColumn())) {
choiceTargetsPsiState = true;
break;
}
@ -817,14 +790,14 @@ namespace storm {
// If it does, we can add the choice to the sum.
if (choiceTargetsPsiState) {
variables.push_back(*choiceVariableIndicesIterator);
coefficients.push_back(1);
constraint = constraint + storm::expressions::Expression::createDoubleVariable(*choiceVariableIterator);
}
++choiceVariableIndicesIterator;
++choiceVariableIterator;
}
}
constraint = constraint >= storm::expressions::Expression::createDoubleLiteral(1);
solver.addConstraint("SchedulerCuts" + std::to_string(numberOfConstraintsCreated), variables, coefficients, storm::solver::LpSolver::GREATER_EQUAL, 1);
solver.addConstraint("SchedulerCuts" + std::to_string(numberOfConstraintsCreated), constraint);
++numberOfConstraintsCreated;
return numberOfConstraintsCreated;
@ -881,6 +854,9 @@ namespace storm {
LOG4CPLUS_DEBUG(logger, "Asserted scheduler cuts.");
}
// Finally, we can tell the solver to incorporate the latest changes.
solver.update();
LOG4CPLUS_INFO(logger, "Successfully created " << numberOfConstraints << " MILP constraints.");
}
@ -893,7 +869,7 @@ namespace storm {
static boost::container::flat_set<uint_fast64_t> getUsedLabelsInSolution(storm::solver::LpSolver const& solver, VariableInformation const& variableInformation) {
boost::container::flat_set<uint_fast64_t> result;
for (auto labelVariablePair : variableInformation.labelToVariableIndexMap) {
for (auto const& labelVariablePair : variableInformation.labelToVariableMap) {
bool labelTaken = solver.getBinaryValue(labelVariablePair.second);
if (labelTaken) {
@ -917,10 +893,10 @@ namespace storm {
std::map<uint_fast64_t, uint_fast64_t> result;
for (auto state : stateInformation.relevantStates) {
std::list<uint_fast64_t>::const_iterator choiceVariableIndicesIterator = variableInformation.stateToChoiceVariablesIndexMap.at(state).begin();
std::list<std::string>::const_iterator choiceVariableIterator = variableInformation.stateToChoiceVariablesIndexMap.at(state).begin();
for (auto choice : choiceInformation.relevantChoicesForRelevantStates.at(state)) {
bool choiceTaken = solver.getBinaryValue(*choiceVariableIndicesIterator);
++choiceVariableIndicesIterator;
bool choiceTaken = solver.getBinaryValue(*choiceVariableIterator);
++choiceVariableIterator;
if (choiceTaken) {
result.emplace_hint(result.end(), state, choice);
}
@ -939,20 +915,20 @@ namespace storm {
*/
static std::pair<uint_fast64_t, double> getReachabilityProbability(storm::solver::LpSolver const& solver, storm::models::Mdp<T> const& labeledMdp, VariableInformation const& variableInformation) {
uint_fast64_t selectedInitialState = 0;
for (auto initialStateVariableIndexPair : variableInformation.initialStateToChoiceVariableIndexMap) {
bool initialStateChosen = solver.getBinaryValue(initialStateVariableIndexPair.second);
for (auto const& initialStateVariablePair : variableInformation.initialStateToChoiceVariableMap) {
bool initialStateChosen = solver.getBinaryValue(initialStateVariablePair.second);
if (initialStateChosen) {
selectedInitialState = initialStateVariableIndexPair.first;
selectedInitialState = initialStateVariablePair.first;
break;
}
}
double reachabilityProbability = solver.getContinuousValue(variableInformation.virtualInitialStateVariableIndex);
double reachabilityProbability = solver.getContinuousValue(variableInformation.virtualInitialStateVariable);
return std::make_pair(selectedInitialState, reachabilityProbability);
}
public:
static boost::container::flat_set<uint_fast64_t> getMinimalLabelSet(storm::models::Mdp<T> const& labeledMdp, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates, double probabilityThreshold, bool strictBound, bool checkThresholdFeasible = false, bool includeSchedulerCuts = false) {
// (0) Check whether the MDP is indeed labeled.
if (!labeledMdp.hasChoiceLabeling()) {
@ -1009,7 +985,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);
@ -1021,7 +997,7 @@ namespace storm {
LOG4CPLUS_ERROR(logger, "Illegal comparison operator in formula " << probBoundFormula->toString() << ". Only upper bounds are supported for counterexample generation.");
throw storm::exceptions::InvalidPropertyException() << "Illegal comparison operator in formula " << probBoundFormula->toString() << ". Only upper bounds are supported for counterexample generation.";
}
bool strictBound = !probBoundFormula->getComparisonOperator() == storm::property::ComparisonType::LESS;
bool strictBound = !(probBoundFormula->getComparisonOperator() == storm::property::ComparisonType::LESS);
// Now derive the probability threshold we need to exceed as well as the phi and psi states. Simultaneously, check whether the formula is of a valid shape.
double bound = probBoundFormula->getBound();
@ -1054,9 +1030,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.

146
src/counterexamples/PathBasedSubsystemGenerator.h

@ -69,31 +69,31 @@ public:
for(auto const& trans : transMat.getRow(init)) {
//save transition only if it's no 'virtual transition of prob 0 and it doesn't go from init state to init state.
if(trans.second != (T) 0 && !subSysStates.get(trans.first)) {
if(trans.getValue() != (T) 0 && !subSysStates.get(trans.getColumn())) {
//new state?
if(distances[trans.first].second == (T) -1) {
distances[trans.first].first = init;
distances[trans.first].second = trans.second;
if(distances[trans.getColumn()].second == (T) -1) {
distances[trans.getColumn()].first = init;
distances[trans.getColumn()].second = trans.getValue();
activeSet.insert(std::pair<uint_fast64_t, T>(trans.first, distances[trans.first].second));
activeSet.insert(std::pair<uint_fast64_t, T>(trans.getColumn(), distances[trans.getColumn()].second));
}
else if(distances[trans.first].second < trans.second){
else if(distances[trans.getColumn()].second < trans.getValue()){
//This state has already been discovered
//And the distance can be improved by using this transition.
//find state in set, remove it, reenter it with new and correct values.
auto range = activeSet.equal_range(std::pair<uint_fast64_t, T>(trans.first, distances[trans.first].second));
auto range = activeSet.equal_range(std::pair<uint_fast64_t, T>(trans.getColumn(), distances[trans.getColumn()].second));
for(;range.first != range.second; range.first++) {
if(trans.first == range.first->first) {
if(trans.getColumn() == range.first->first) {
activeSet.erase(range.first);
break;
}
}
distances[trans.first].first = init;
distances[trans.first].second = trans.second;
distances[trans.getColumn()].first = init;
distances[trans.getColumn()].second = trans.getValue();
activeSet.insert(std::pair<uint_fast64_t, T>(trans.first, trans.second));
activeSet.insert(std::pair<uint_fast64_t, T>(trans.getColumn(), trans.getValue()));
}
}
}
@ -115,36 +115,36 @@ public:
// Look at all neighbors
for(auto const& trans : transMat.getRow(activeState.first)) {
// Only consider the transition if it's not virtual
if(trans.second != (T) 0) {
if(trans.getValue() != (T) 0) {
T distance = activeState.second * trans.second;
T distance = activeState.second * trans.getValue();
//not discovered or initial terminal state
if(distances[trans.first].second == (T)-1) {
if(distances[trans.getColumn()].second == (T)-1) {
//New state discovered -> save it
distances[trans.first].first = activeState.first;
distances[trans.first].second = distance;
distances[trans.getColumn()].first = activeState.first;
distances[trans.getColumn()].second = distance;
// push newly discovered state into activeSet
activeSet.insert(std::pair<uint_fast64_t, T>(trans.first, distance));
activeSet.insert(std::pair<uint_fast64_t, T>(trans.getColumn(), distance));
}
else if(distances[trans.first].second < distance ){
else if(distances[trans.getColumn()].second < distance) {
//This state has already been discovered
//And the distance can be improved by using this transition.
//find state in set, remove it, reenter it with new and correct values.
auto range = activeSet.equal_range(std::pair<uint_fast64_t, T>(trans.first, distances[trans.first].second));
auto range = activeSet.equal_range(std::pair<uint_fast64_t, T>(trans.getColumn(), distances[trans.getColumn()].second));
for(;range.first != range.second; range.first++) {
if(trans.first == range.first->first) {
if(trans.getColumn() == range.first->first) {
activeSet.erase(range.first);
break;
}
}
distances[trans.first].first = activeState.first;
distances[trans.first].second = distance;
activeSet.insert(std::pair<uint_fast64_t, T>(trans.first, distance));
distances[trans.getColumn()].first = activeState.first;
distances[trans.getColumn()].second = distance;
activeSet.insert(std::pair<uint_fast64_t, T>(trans.getColumn(), distance));
}
}
}
@ -182,33 +182,33 @@ public:
for(auto const& trans : transMat.getRow(init)) {
//save transition only if it's no 'virtual transition of prob 0 and it doesn't go from init state to init state.
if(trans.second != (T) 0 && !subSysStates.get(trans.first)) {
if(trans.getValue() != (T) 0 && !subSysStates.get(trans.getColumn())) {
//new state?
if(distances[trans.first].second == (T) -1) {
if(distances[trans.getColumn()].second == (T) -1) {
//for initialization of subsys -> subsys search use prob (init -> subsys state -> found state) instead of prob(subsys state -> found state)
distances[trans.first].first = init;
distances[trans.first].second = trans.second * (itDistances[init].second == -1 ? 1 : itDistances[init].second);
distances[trans.getColumn()].first = init;
distances[trans.getColumn()].second = trans.getValue() * (itDistances[init].second == -1 ? 1 : itDistances[init].second);
activeSet.insert(std::pair<uint_fast64_t, T>(trans.first, distances[trans.first].second));
activeSet.insert(std::pair<uint_fast64_t, T>(trans.getColumn(), distances[trans.getColumn()].second));
}
else if(distances[trans.first].second < trans.second * itDistances[init].second){
else if(distances[trans.getColumn()].second < trans.getValue() * itDistances[init].second){
//This state has already been discovered
//And the distance can be improved by using this transition.
//find state in set, remove it, reenter it with new and correct values.
auto range = activeSet.equal_range(std::pair<uint_fast64_t, T>(trans.first, distances[trans.first].second));
auto range = activeSet.equal_range(std::pair<uint_fast64_t, T>(trans.getColumn(), distances[trans.getColumn()].second));
for(;range.first != range.second; range.first++) {
if(trans.first == range.first->first) {
if(trans.getColumn() == range.first->first) {
activeSet.erase(range.first);
break;
}
}
//for initialization of subsys -> subsys search use prob (init -> subsys state -> found state) instead of prob(subsys state -> found state)
distances[trans.first].first = init;
distances[trans.first].second = trans.second * (itDistances[init].second == -1 ? 1 : itDistances[init].second);
distances[trans.getColumn()].first = init;
distances[trans.getColumn()].second = trans.getValue() * (itDistances[init].second == -1 ? 1 : itDistances[init].second);
activeSet.insert(std::pair<uint_fast64_t, T>(trans.first, trans.second));
activeSet.insert(std::pair<uint_fast64_t, T>(trans.getColumn(), trans.getValue()));
}
}
}
@ -225,7 +225,7 @@ public:
activeSet.erase(--activeSet.end());
// Always stop at first target/terminal state
//if(terminalStates.get(activeState.first) || subSysStates.get(activeState.first)) break;
//if(terminalStates.get(activeState.getColumn()) || subSysStates.get(activeState.getColumn())) break;
// If this is an initial state, do not consider its outgoing transitions, since all relevant ones have already been considered
// Same goes for forbidden states since they may not be used on a path, except as last node.
@ -233,36 +233,36 @@ public:
// Look at all neighbors
for(auto const& trans : transMat.getRow(activeState.first)) {
// Only consider the transition if it's not virtual
if(trans.second != (T) 0) {
if(trans.getValue() != (T) 0) {
T distance = activeState.second * trans.second;
T distance = activeState.second * trans.getValue();
//not discovered or initial terminal state
if(distances[trans.first].second == (T)-1) {
if(distances[trans.getColumn()].second == (T)-1) {
//New state discovered -> save it
distances[trans.first].first = activeState.first;
distances[trans.first].second = distance;
distances[trans.getColumn()].first = activeState.first;
distances[trans.getColumn()].second = distance;
// push newly discovered state into activeSet
activeSet.insert(std::pair<uint_fast64_t, T>(trans.first, distance));
activeSet.insert(std::pair<uint_fast64_t, T>(trans.getColumn(), distance));
}
else if(distances[trans.first].second < distance ){
else if(distances[trans.getColumn()].second < distance) {
//This state has already been discovered
//And the distance can be improved by using this transition.
//find state in set, remove it, reenter it with new and correct values.
auto range = activeSet.equal_range(std::pair<uint_fast64_t, T>(trans.first, distances[trans.first].second));
auto range = activeSet.equal_range(std::pair<uint_fast64_t, T>(trans.getColumn(), distances[trans.getColumn()].second));
for(;range.first != range.second; range.first++) {
if(trans.first == range.first->first) {
if(trans.getColumn() == range.first->first) {
activeSet.erase(range.first);
break;
}
}
distances[trans.first].first = activeState.first;
distances[trans.first].second = distance;
activeSet.insert(std::pair<uint_fast64_t, T>(trans.first, distance));
distances[trans.getColumn()].first = activeState.first;
distances[trans.getColumn()].second = distance;
activeSet.insert(std::pair<uint_fast64_t, T>(trans.getColumn(), distance));
}
}
}
@ -292,8 +292,8 @@ public:
// if there is a terminal state that is an initial state then prob == 1 and return
if(initStates.get(*target)){
distances[*target].first = *target;
distances[*target].second = (T) 1;
distances[*target].getColumn() = *target;
distances[*target].getValue() = (T) 1;
return;
}
@ -302,19 +302,19 @@ public:
//only use if allowed and not in subsys and not terminal
if(allowedStates.get(*iter) && !subSysStates.get(*iter) && !terminalStates.get(*iter)) {
//new state?
if(distances[*iter].second == (T) -1) {
if(distances[*iter].getValue() == (T) -1) {
// save as discovered and push into active set
distances[*iter].first = *target; //successor
distances[*iter].second = transMat.getValue(*iter, *target); //prob of shortest path
distances[*iter].getColumn() = *target; //successor
distances[*iter].getValue() = transMat.getValue(*iter, *target); //prob of shortest path
activeSet.insert(std::pair<uint_fast64_t, T>(*iter, probabilities[*iter])); //prob of reaching some terminal state from pred.
}
else {
// state was already discovered
// is this the better transition?
if(distances[*iter].second > transMat.getValue(*iter, *target)) {
distances[*iter].first = *target;
distances[*iter].second = transMat.getValue(*iter, *target);
if(distances[*iter].getValue() > transMat.getValue(*iter, *target)) {
distances[*iter].getColumn() = *target;
distances[*iter].getValue() = transMat.getValue(*iter, *target);
}
}
}
@ -328,19 +328,19 @@ public:
//only use if allowed and not in subsys and not terminal
if(allowedStates.get(*iter) && !subSysStates.get(*iter) && !terminalStates.get(*iter)) {
//new state?
if(distances[*iter].second == (T) -1) {
if(distances[*iter].getValue() == (T) -1) {
// save as discovered and push into active set
distances[*iter].first = *sysState; //successor
distances[*iter].second = transMat.getValue(*iter, *sysState); //prob of shortest path
distances[*iter].getColumn() = *sysState; //successor
distances[*iter].getValue() = transMat.getValue(*iter, *sysState); //prob of shortest path
activeSet.insert(std::pair<uint_fast64_t, T>(*iter, probabilities[*iter])); //prob of reaching some terminal state from pred.
}
else {
// state was already discovered
// is this the better transition?
if(distances[*iter].second > transMat.getValue(*iter, *sysState)) {
distances[*iter].first = *sysState;
distances[*iter].second = transMat.getValue(*iter, *sysState);
if(distances[*iter].getValue() > transMat.getValue(*iter, *sysState)) {
distances[*iter].getColumn() = *sysState;
distances[*iter].getValue() = transMat.getValue(*iter, *sysState);
}
}
}
@ -355,7 +355,7 @@ public:
while(!activeSet.empty()) {
// copy here since using a reference leads to segfault
state = *(--activeSet.end());
activeState = state.first;
activeState = state.getColumn();
activeSet.erase(--activeSet.end());
//stop on the first subsys/init state
@ -368,19 +368,19 @@ public:
//only if transition is not "virtual" and no selfloop
if(*iter != activeState && transMat.getValue(*iter, activeState) != (T) 0) {
//new state?
if(distances[*iter].second == (T) -1) {
if(distances[*iter].getValue() == (T) -1) {
// save as discovered and push into active set
distances[*iter].first = activeState;
distances[*iter].second = transMat.getValue(*iter, activeState) * distances[activeState].second;
distances[*iter].getColumn() = activeState;
distances[*iter].getValue() = transMat.getValue(*iter, activeState) * distances[activeState].getValue();
activeSet.insert(std::pair<uint_fast64_t, T>(*iter, probabilities[*iter]));
}
else {
// state was already discovered
// is this the better transition?
if(distances[*iter].second < transMat.getValue(*iter, activeState) * distances[activeState].second) {
distances[*iter].first = activeState;
distances[*iter].second = transMat.getValue(*iter, activeState) * distances[activeState].second;
if(distances[*iter].getValue() < transMat.getValue(*iter, activeState) * distances[activeState].getValue()) {
distances[*iter].getColumn() = activeState;
distances[*iter].getValue() = transMat.getValue(*iter, activeState) * distances[activeState].getValue();
}
}
}
@ -389,15 +389,15 @@ public:
}
//get path probability
probability = distances[activeState].second;
probability = distances[activeState].getValue();
if(probability == (T) -1) probability = 1;
// iterate over the successors until reaching the end of the finite path
shortestPath.push_back(activeState);
activeState = distances[activeState].first;
activeState = distances[activeState].getColumn();
while(!terminalStates.get(activeState) && !subSysStates.get(activeState)) {
shortestPath.push_back(activeState);
activeState = distances[activeState].first;
activeState = distances[activeState].getColumn();
}
shortestPath.push_back(activeState);
}
@ -482,7 +482,7 @@ public:
shortestPath.push_back(bestIndex);
//At last compensate for the distance between init and source state
probability = itSearch ? probability : probability / itDistances[bestIndex].second;
probability = itSearch ? probability : probability / itDistances[bestIndex].first;
}
private:
@ -507,7 +507,7 @@ public:
/*!
*
*/
static storm::models::Dtmc<T> computeCriticalSubsystem(storm::models::Dtmc<T>& model, storm::property::prctl::AbstractStateFormula<T> const& stateFormula) {
static storm::models::Dtmc<T> computeCriticalSubsystem(storm::models::Dtmc<T> & model, storm::property::prctl::AbstractStateFormula<T> const& stateFormula) {
//-------------------------------------------------------------
// 1. Strip and handle formulas

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_ */

200
src/ir/Module.cpp

@ -1,200 +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() {
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);
}
}
}
void Module::restrictCommands(boost::container::flat_set<uint_fast64_t> const& indexSet) {
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);
}
} // namespace ir
} // namespace storm

230
src/ir/Module.h

@ -1,230 +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.
#ifdef LINUX
boost::container::map<std::string, std::set<uint_fast64_t>> actionsToCommandIndexMap;
#else
std::map<std::string, std::set<uint_fast64_t>> actionsToCommandIndexMap;
#endif
};
} // 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_ */

2
src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.cpp

@ -5,4 +5,4 @@ bool SparseMarkovAutomatonCslModelCheckerOptionsRegistered = storm::settings::Se
instance->addOption(storm::settings::OptionBuilder("GmmxxLinearEquationSolver", "digiprecision", "", "Precision used for iterative solving of linear equation systems").addArgument(storm::settings::ArgumentBuilder::createDoubleArgument("precision value", "Precision").setDefaultValueDouble(1e-4).addValidationFunctionDouble(storm::settings::ArgumentValidators::doubleRangeValidatorExcluding(0.0, 1.0)).build()).build());
return true;
});
});

78
src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h

@ -103,10 +103,10 @@ namespace storm {
for (auto state : markovianNonGoalStates) {
for (auto& element : aMarkovian.getRow(rowIndex)) {
ValueType eTerm = std::exp(-exitRates[state] * delta);
if (element.first == rowIndex) {
element.second = (storm::utility::constantOne<ValueType>() - eTerm) * element.second + eTerm;
if (element.getColumn() == rowIndex) {
element.getValue() = (storm::utility::constantOne<ValueType>() - eTerm) * element.getValue() + eTerm;
} else {
element.second = (storm::utility::constantOne<ValueType>() - eTerm) * element.second;
element.getValue() = (storm::utility::constantOne<ValueType>() - eTerm) * element.getValue();
}
}
++rowIndex;
@ -116,7 +116,7 @@ namespace storm {
rowIndex = 0;
for (auto state : markovianNonGoalStates) {
for (auto& element : aMarkovianToProbabilistic.getRow(rowIndex)) {
element.second = (1 - std::exp(-exitRates[state] * delta)) * element.second;
element.getValue() = (1 - std::exp(-exitRates[state] * delta)) * element.getValue();
}
++rowIndex;
}
@ -133,8 +133,8 @@ namespace storm {
bMarkovianFixed.push_back(storm::utility::constantZero<ValueType>());
for (auto& element : transitionMatrix.getRowGroup(state)) {
if (goalStates.get(element.first)) {
bMarkovianFixed.back() += (1 - std::exp(-exitRates[state] * delta)) * element.second;
if (goalStates.get(element.getColumn())) {
bMarkovianFixed.back() += (1 - std::exp(-exitRates[state] * delta)) * element.getValue();
}
}
}
@ -314,13 +314,13 @@ namespace storm {
b.push_back(storm::utility::constantZero<ValueType>());
for (auto element : transitionMatrix.getRow(choice)) {
if (statesNotContainedInAnyMec.get(element.first)) {
if (statesNotContainedInAnyMec.get(element.getColumn())) {
// If the target state is not contained in an MEC, we can copy over the entry.
sspMatrixBuilder.addNextValue(currentChoice, statesNotInMecsBeforeIndex[element.first], element.second);
sspMatrixBuilder.addNextValue(currentChoice, statesNotInMecsBeforeIndex[element.getColumn()], element.getValue());
} else {
// If the target state is contained in MEC i, we need to add the probability to the corresponding field in the vector
// so that we are able to write the cumulative probability to the MEC into the matrix.
auxiliaryStateToProbabilityMap[stateToMecIndexMap[element.first]] += element.second;
auxiliaryStateToProbabilityMap[stateToMecIndexMap[element.getColumn()]] += element.getValue();
}
}
@ -350,13 +350,13 @@ namespace storm {
b.push_back(storm::utility::constantZero<ValueType>());
for (auto element : transitionMatrix.getRow(choice)) {
if (statesNotContainedInAnyMec.get(element.first)) {
if (statesNotContainedInAnyMec.get(element.getColumn())) {
// If the target state is not contained in an MEC, we can copy over the entry.
sspMatrixBuilder.addNextValue(currentChoice, statesNotInMecsBeforeIndex[element.first], element.second);
sspMatrixBuilder.addNextValue(currentChoice, statesNotInMecsBeforeIndex[element.getColumn()], element.getValue());
} else {
// If the target state is contained in MEC i, we need to add the probability to the corresponding field in the vector
// so that we are able to write the cumulative probability to the MEC into the matrix.
auxiliaryStateToProbabilityMap[stateToMecIndexMap[element.first]] += element.second;
auxiliaryStateToProbabilityMap[stateToMecIndexMap[element.getColumn()]] += element.getValue();
}
}
@ -428,61 +428,61 @@ namespace storm {
*/
static ValueType computeLraForMaximalEndComponent(bool min, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, storm::storage::BitVector const& markovianStates, std::vector<ValueType> const& exitRates, storm::storage::BitVector const& goalStates, storm::storage::MaximalEndComponent const& mec, uint_fast64_t mecIndex = 0) {
std::shared_ptr<storm::solver::LpSolver> solver = storm::utility::solver::getLpSolver("LRA for MEC");
solver->setModelSense(min ? storm::solver::LpSolver::MAXIMIZE : storm::solver::LpSolver::MINIMIZE);
solver->setModelSense(min ? storm::solver::LpSolver::ModelSense::Maximize : storm::solver::LpSolver::ModelSense::Minimize);
// First, we need to create the variables for the problem.
std::map<uint_fast64_t, uint_fast64_t> stateToVariableIndexMap;
std::map<uint_fast64_t, std::string> stateToVariableNameMap;
for (auto const& stateChoicesPair : mec) {
stateToVariableIndexMap[stateChoicesPair.first] = solver->createContinuousVariable("x" + std::to_string(stateChoicesPair.first), storm::solver::LpSolver::UNBOUNDED, 0, 0, 0);
std::string variableName = "x" + std::to_string(stateChoicesPair.first);
stateToVariableNameMap[stateChoicesPair.first] = variableName;
solver->addUnboundedContinuousVariable(variableName);
}
uint_fast64_t lraValueVariableIndex = solver->createContinuousVariable("k", storm::solver::LpSolver::UNBOUNDED, 0, 0, 1);
solver->addUnboundedContinuousVariable("k", 1);
solver->update();
// Now we encode the problem as constraints.
std::vector<uint_fast64_t> variables;
std::vector<double> coefficients;
for (auto const& stateChoicesPair : mec) {
uint_fast64_t state = stateChoicesPair.first;
// Now, based on the type of the state, create a suitable constraint.
if (markovianStates.get(state)) {
variables.clear();
coefficients.clear();
variables.push_back(stateToVariableIndexMap.at(state));
coefficients.push_back(1);
storm::expressions::Expression constraint = storm::expressions::Expression::createDoubleVariable(stateToVariableNameMap.at(state));
for (auto element : transitionMatrix.getRow(nondeterministicChoiceIndices[state])) {
variables.push_back(stateToVariableIndexMap.at(element.first));
coefficients.push_back(-element.second);
constraint = constraint - storm::expressions::Expression::createDoubleVariable(stateToVariableNameMap.at(element.getColumn()));
}
variables.push_back(lraValueVariableIndex);
coefficients.push_back(storm::utility::constantOne<ValueType>() / exitRates[state]);
solver->addConstraint("state" + std::to_string(state), variables, coefficients, min ? storm::solver::LpSolver::LESS_EQUAL : storm::solver::LpSolver::GREATER_EQUAL, goalStates.get(state) ? storm::utility::constantOne<ValueType>() / exitRates[state] : storm::utility::constantZero<ValueType>());
constraint = constraint + storm::expressions::Expression::createDoubleLiteral(storm::utility::constantOne<ValueType>() / exitRates[state]) * storm::expressions::Expression::createDoubleVariable("k");
storm::expressions::Expression rightHandSide = goalStates.get(state) ? storm::expressions::Expression::createDoubleLiteral(storm::utility::constantOne<ValueType>() / exitRates[state]) : storm::expressions::Expression::createDoubleLiteral(storm::utility::constantZero<ValueType>());
if (min) {
constraint = constraint <= rightHandSide;
} else {
constraint = constraint >= rightHandSide;
}
solver->addConstraint("state" + std::to_string(state), constraint);
} else {
// For probabilistic states, we want to add the constraint x_s <= sum P(s, a, s') * x_s' where a is the current action
// and the sum ranges over all states s'.
for (auto choice : stateChoicesPair.second) {
variables.clear();
coefficients.clear();
variables.push_back(stateToVariableIndexMap.at(state));
coefficients.push_back(1);
storm::expressions::Expression constraint = storm::expressions::Expression::createDoubleVariable(stateToVariableNameMap.at(state));
for (auto element : transitionMatrix.getRow(choice)) {
variables.push_back(stateToVariableIndexMap.at(element.first));
coefficients.push_back(-element.second);
constraint = constraint - storm::expressions::Expression::createDoubleVariable(stateToVariableNameMap.at(element.getColumn()));
}
solver->addConstraint("state" + std::to_string(state), variables, coefficients, min ? storm::solver::LpSolver::LESS_EQUAL : storm::solver::LpSolver::GREATER_EQUAL, storm::utility::constantZero<ValueType>());
storm::expressions::Expression rightHandSide = storm::expressions::Expression::createDoubleLiteral(storm::utility::constantZero<ValueType>());
if (min) {
constraint = constraint <= rightHandSide;
} else {
constraint = constraint >= rightHandSide;
}
solver->addConstraint("state" + std::to_string(state), constraint);
}
}
}
solver->optimize();
return solver->getContinuousValue(lraValueVariableIndex);
return solver->getContinuousValue("k");
}
/*!

2
src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h

@ -393,7 +393,7 @@ public:
// Perform the actual matrix-vector multiplication as long as the bound of the formula is met.
if (linearEquationSolver != nullptr) {
this->linearEquationSolver->performMatrixVectorMultiplication(this->getModel().getTransitionMatrix(), result, &totalRewardVector, formula.getBound());
this->linearEquationSolver->performMatrixVectorMultiplication(this->getModel().getTransitionMatrix(), result, &totalRewardVector, static_cast<uint_fast64_t>(formula.getBound()));
} else {
throw storm::exceptions::InvalidStateException() << "No valid linear equation solver available.";
}

2
src/modelchecker/prctl/SparseMdpPrctlModelChecker.h

@ -410,7 +410,7 @@ namespace storm {
result.resize(this->getModel().getNumberOfStates());
}
this->nondeterministicLinearEquationSolver->performMatrixVectorMultiplication(this->minimumOperatorStack.top(), this->getModel().getTransitionMatrix(), result, &totalRewardVector, formula.getBound());
this->nondeterministicLinearEquationSolver->performMatrixVectorMultiplication(this->minimumOperatorStack.top(), this->getModel().getTransitionMatrix(), result, &totalRewardVector, static_cast<uint_fast64_t>(formula.getBound()));
return result;
}

6
src/models/AbstractDeterministicModel.h

@ -87,9 +87,9 @@ class AbstractDeterministicModel: public AbstractModel<T> {
for (uint_fast64_t i = 0; i < this->transitionMatrix.getRowCount(); ++i, ++rowIt) {
typename storm::storage::SparseMatrix<T>::const_rows row = this->transitionMatrix.getRow(i);
for (auto const& transition : row) {
if (transition.second != storm::utility::constantZero<T>()) {
if (subsystem == nullptr || subsystem->get(transition.first)) {
outStream << "\t" << i << " -> " << transition.first << " [ label= \"" << transition.second << "\" ];" << std::endl;
if (transition.getValue() != storm::utility::constantZero<T>()) {
if (subsystem == nullptr || subsystem->get(transition.getColumn())) {
outStream << "\t" << i << " -> " << transition.getColumn() << " [ label= \"" << transition.getValue() << "\" ];" << std::endl;
}
}
}

2
src/models/AbstractModel.h

@ -220,7 +220,7 @@ class AbstractModel: public std::enable_shared_from_this<AbstractModel<T>> {
* @return The number of (non-zero) transitions of the model.
*/
virtual uint_fast64_t getNumberOfTransitions() const {
return this->getTransitionMatrix().getEntryCount();
return this->getTransitionMatrix().getNonzeroEntryCount();
}
/*!

4
src/models/AbstractNondeterministicModel.h

@ -189,8 +189,8 @@ namespace storm {
// Now draw all probabilitic arcs that belong to this nondeterminstic choice.
for (auto const& transition : row) {
if (subsystem == nullptr || subsystem->get(transition.first)) {
outStream << "\t\"" << state << "c" << choice << "\" -> " << transition.first << " [ label= \"" << transition.second << "\" ]";
if (subsystem == nullptr || subsystem->get(transition.getColumn())) {
outStream << "\t\"" << state << "c" << choice << "\" -> " << transition.getColumn() << " [ label= \"" << transition.getValue() << "\" ]";
// If we were given a scheduler to highlight, we do so now.
if (scheduler != nullptr) {

12
src/models/Dtmc.h

@ -170,7 +170,7 @@ public:
for(uint_fast64_t row = 0; row < origMat.getRowCount(); ++row) {
if(subSysStates.get(row)){
for(auto const& entry : origMat.getRow(row)) {
if(subSysStates.get(entry.first)) {
if(subSysStates.get(entry.getColumn())) {
subSysTransitionCount++;
}
}
@ -198,10 +198,10 @@ public:
if(subSysStates.get(row)){
// Transfer transitions
for(auto& entry : origMat.getRow(row)) {
if(subSysStates.get(entry.first)) {
newMatBuilder.addNextValue(newRow, stateMapping[entry.first], entry.second);
if(subSysStates.get(entry.getColumn())) {
newMatBuilder.addNextValue(newRow, stateMapping[entry.getColumn()], entry.getValue());
} else {
rest += entry.second;
rest += entry.getValue();
}
}
@ -251,8 +251,8 @@ public:
if(subSysStates.get(row)){
// Transfer transition rewards
for(auto& entry : this->getTransitionRewardMatrix().getRow(row)) {
if(subSysStates.get(entry.first)) {
newTransRewardsBuilder.addNextValue(newRow, stateMapping[entry.first], entry.second);
if(subSysStates.get(entry.getColumn())) {
newTransRewardsBuilder.addNextValue(newRow, stateMapping[entry.getColumn()], entry.getValue());
}
}

14
src/models/MarkovAutomaton.h

@ -123,7 +123,7 @@ namespace storm {
}
// Then compute how many rows the new matrix is going to have.
uint_fast64_t newNumberOfRows = this->getNumberOfChoices() - numberOfHybridStates;
//uint_fast64_t newNumberOfRows = this->getNumberOfChoices() - numberOfHybridStates;
// Create the matrix for the new transition relation and the corresponding nondeterministic choice vector.
storm::storage::SparseMatrixBuilder<T> newTransitionMatrixBuilder(0, 0, 0, true, this->getNumberOfStates() + 1);
@ -147,7 +147,7 @@ namespace storm {
for (uint_fast64_t row = this->getTransitionMatrix().getRowGroupIndices()[state] + (this->isHybridState(state) ? 1 : 0); row < this->getTransitionMatrix().getRowGroupIndices()[state + 1]; ++row) {
for (auto const& entry : this->transitionMatrix.getRow(row)) {
newTransitionMatrixBuilder.addNextValue(currentChoice, entry.first, entry.second);
newTransitionMatrixBuilder.addNextValue(currentChoice, entry.getColumn(), entry.getValue());
}
++currentChoice;
}
@ -220,8 +220,8 @@ namespace storm {
// Now draw all probabilitic arcs that belong to this nondeterminstic choice.
for (auto const& transition : row) {
if (subsystem == nullptr || subsystem->get(transition.first)) {
outStream << "\t\"" << state << "c" << choice << "\" -> " << transition.first << " [ label= \"" << transition.second << "\" ]";
if (subsystem == nullptr || subsystem->get(transition.getColumn())) {
outStream << "\t\"" << state << "c" << choice << "\" -> " << transition.getColumn() << " [ label= \"" << transition.getValue() << "\" ]";
// If we were given a scheduler to highlight, we do so now.
if (scheduler != nullptr) {
@ -237,8 +237,8 @@ namespace storm {
} else {
// In this case we are emitting a Markovian choice, so draw the arrows directly to the target states.
for (auto const& transition : row) {
if (subsystem == nullptr || subsystem->get(transition.first)) {
outStream << "\t\"" << state << "\" -> " << transition.first << " [ label= \"" << transition.second << " (" << this->exitRates[state] << ")\" ]";
if (subsystem == nullptr || subsystem->get(transition.getColumn())) {
outStream << "\t\"" << state << "\" -> " << transition.getColumn() << " [ label= \"" << transition.getValue() << " (" << this->exitRates[state] << ")\" ]";
}
}
}
@ -259,7 +259,7 @@ namespace storm {
void turnRatesToProbabilities() {
for (auto state : this->markovianStates) {
for (auto& transition : this->transitionMatrix.getRowGroup(state)) {
transition.second /= this->exitRates[state];
transition.getValue() /= this->exitRates[state];
}
}
}

305
src/parser/AtomicPropositionLabelingParser.cpp

@ -7,192 +7,171 @@
#include "src/parser/AtomicPropositionLabelingParser.h"
#include <errno.h>
#include <time.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <locale.h>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <string>
#include <clocale>
#include <iostream>
#include "src/utility/cstring.h"
#include "src/parser/MappedFile.h"
#include "src/exceptions/WrongFormatException.h"
#include "src/exceptions/FileIoException.h"
#include "src/utility/OsDetection.h"
#include "log4cplus/logger.h"
#include "log4cplus/loggingmacros.h"
extern log4cplus::Logger logger;
namespace storm {
namespace parser {
namespace parser {
using namespace storm::utility::cstring;
/*!
* Reads a label file and puts the result in a labeling structure.
*
* Labelings created with this method have to be freed with the delete operator.
* @param node_count the number of states.
* @param filename input .lab file's name.
* @return The pointer to the created labeling object.
*/
storm::models::AtomicPropositionsLabeling AtomicPropositionLabelingParser(uint_fast64_t node_count, std::string const & filename) {
/*
* Open file.
*/
if (!storm::parser::fileExistsAndIsReadable(filename.c_str())) {
LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": File does not exist or is not readable.");
throw storm::exceptions::FileIoException() << "The supplied Labeling input file \"" << filename << "\" does not exist or is not readable by this process.";
}
/*
* Find out about the used line endings.
*/
SupportedLineEndingsEnum lineEndings = findUsedLineEndings(filename, true);
MappedFile file(filename.c_str());
char* buf = file.data;
/*
* First run: obtain number of propositions.
*/
char separator[5];// = " \r\n\t";
storm::parser::getMatchingSeparatorString(separator, sizeof(separator), lineEndings);
bool foundDecl = false, foundEnd = false;
uint_fast32_t proposition_count = 0;
{
size_t cnt = 0;
/*
* Iterate over tokens until we hit #END or end of file.
*/
while(buf[0] != '\0') {
buf += cnt;
cnt = strcspn(buf, separator); // position of next separator
if (cnt > 0) {
/*
* next token is #DECLARATION: just skip it
* next token is #END: stop search
* otherwise increase proposition_count
*/
if (strncmp(buf, "#DECLARATION", cnt) == 0) {
foundDecl = true;
continue;
} else if (strncmp(buf, "#END", cnt) == 0) {
foundEnd = true;
break;
storm::models::AtomicPropositionsLabeling AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(uint_fast64_t stateCount, std::string const & filename) {
// Open the given file.
if (!MappedFile::fileExistsAndIsReadable(filename.c_str())) {
LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": File does not exist or is not readable.");
throw storm::exceptions::FileIoException() << "The supplied Labeling input file \"" << filename << "\" does not exist or is not readable by this process.";
}
MappedFile file(filename.c_str());
char* buf = file.getData();
// First pass: Count the number of propositions.
bool foundDecl = false, foundEnd = false;
uint_fast32_t proposition_count = 0;
size_t cnt = 0;
// Iterate over tokens until we hit #END or the end of the file.
while(buf[0] != '\0') {
//Move the buffer to the beginning of the next word.
buf += cnt;
buf = trimWhitespaces(buf);
// Get the number of characters until the next separator.
cnt = skipWord(buf) - buf;
if (cnt > 0) {
// If the next token is #DECLARATION: Just skip it.
// If the next token is #END: Stop the search.
// Otherwise increase proposition_count.
if (strncmp(buf, "#DECLARATION", cnt) == 0) {
foundDecl = true;
continue;
} else if (strncmp(buf, "#END", cnt) == 0) {
foundEnd = true;
break;
}
proposition_count++;
}
proposition_count++;
} else {
buf++; // next char is separator, one step forward
}
}
/*
* If #DECLARATION or #END were not found, the file format is wrong
*/
if (!(foundDecl && foundEnd)) {
LOG4CPLUS_ERROR(logger, "Wrong file format in (" << filename << "). File header is corrupted.");
if (!foundDecl) LOG4CPLUS_ERROR(logger, "\tDid not find #DECLARATION token.");
if (!foundEnd) LOG4CPLUS_ERROR(logger, "\tDid not find #END token.");
throw storm::exceptions::WrongFormatException();
}
}
/*
* create labeling object with given node and proposition count
*/
storm::models::AtomicPropositionsLabeling labeling(node_count, proposition_count);
/*
* second run: add propositions and node labels to labeling
*
* first thing to do: reset file pointer
*/
buf = file.data;
{
/*
* load propositions
* As we already checked the file format, we can be a bit sloppy here...
*/
char proposition[128]; // buffer for proposition names
size_t cnt = 0;
do {
buf += cnt;
cnt = strcspn(buf, separator); // position of next separator
if (cnt >= sizeof(proposition)) {
/*
* if token is longer than our buffer, the following strncpy code might get risky...
*/
LOG4CPLUS_ERROR(logger, "Wrong file format in (" << filename << "). Atomic proposition with length > " << (sizeof(proposition)-1) << " was found.");
// If #DECLARATION or #END have not been found, the file format is wrong.
if (!(foundDecl && foundEnd)) {
LOG4CPLUS_ERROR(logger, "Wrong file format in (" << filename << "). File header is corrupted.");
if (!foundDecl) LOG4CPLUS_ERROR(logger, "\tDid not find #DECLARATION token.");
if (!foundEnd) LOG4CPLUS_ERROR(logger, "\tDid not find #END token.");
throw storm::exceptions::WrongFormatException();
} else if (cnt > 0) {
/*
* next token is: #DECLARATION: just skip it
* next token is: #END: stop search
* otherwise: copy token to buffer, append trailing null byte and hand it to labeling
*/
if (strncmp(buf, "#DECLARATION", cnt) == 0) continue;
if (strncmp(buf, "#END", cnt) == 0) break;
strncpy(proposition, buf, cnt);
proposition[cnt] = '\0';
labeling.addAtomicProposition(proposition);
} else {
cnt = 1; // next char is separator, one step forward
}
} while (cnt > 0);
/*
* Right here, the buf pointer is still pointing to our last token,
* i.e. to #END. We want to skip this one...
*/
buf += 4;
}
{
/*
* now parse node label assignments
*/
uint_fast64_t node;
char proposition[128];
size_t cnt;
/*
* iterate over nodes
*/
while (buf[0] != '\0') {
/*
* parse node number, then iterate over propositions
*/
node = checked_strtol(buf, &buf);
while ((buf[0] != '\r') && (buf[0] != '\n') && (buf[0] != '\0')) {
cnt = strcspn(buf, separator);
if (cnt == 0) {
/*
* next char is a separator
* if it's a newline, we continue with next node
* otherwise we skip it and try again
*/
if (buf[0] == '\n' || buf[0] == '\r') break;
buf++;
} else {
/*
* copy proposition to buffer and add it to labeling
*/
// Create labeling object with given node and proposition count.
storm::models::AtomicPropositionsLabeling labeling(stateCount, proposition_count);
// Second pass: Add propositions and node labels to labeling.
// First thing to do: Reset the file pointer.
buf = file.getData();
// Prepare a buffer for proposition names.
char proposition[128];
cnt = 0;
// Parse proposition names.
// As we already checked the file header, we know that #DECLARATION and #END are tokens in the character stream.
while(buf[0] != '\0') {
//Move the buffer to the beginning of the next word.
buf += cnt;
buf = trimWhitespaces(buf);
// Get the number of characters until the next separator.
cnt = skipWord(buf) - buf;
if (cnt >= sizeof(proposition)) {
// if token is longer than our buffer, the following strncpy code might get risky...
LOG4CPLUS_ERROR(logger, "Wrong file format in (" << filename << "). Atomic proposition with length > " << (sizeof(proposition)-1) << " was found.");
throw storm::exceptions::WrongFormatException();
} else if (cnt > 0) {
// If the next token is #DECLARATION: Just skip it.
if (strncmp(buf, "#DECLARATION", cnt) == 0) continue;
// If the next token is #END: Stop the search.
if (strncmp(buf, "#END", cnt) == 0) break;
// Otherwise copy the token to the buffer, append a trailing null byte and hand it to labeling.
strncpy(proposition, buf, cnt);
proposition[cnt] = '\0';
labeling.addAtomicPropositionToState(proposition, node);
buf += cnt;
labeling.addAtomicProposition(proposition);
}
}
// At this point, the pointer buf is still pointing to our last token, i.e. to #END.
// We want to skip it.
buf += 4;
// Now eliminate remaining whitespaces such as empty lines and start parsing.
buf = trimWhitespaces(buf);
uint_fast64_t state = 0;
uint_fast64_t lastState = (uint_fast64_t)-1;
cnt = 0;
// Now parse the assignments of labels to nodes.
while (buf[0] != '\0') {
// Parse the state number and iterate over its labels (atomic propositions).
// Stop at the end of the line.
state = checked_strtol(buf, &buf);
// If the state has already been read or skipped once there might be a problem with the file (doubled lines, or blocks).
if(state <= lastState && lastState != (uint_fast64_t)-1) {
LOG4CPLUS_ERROR(logger, "Wrong file format in (" << filename << "). State " << state << " was found but has already been read or skipped previously.");
throw storm::exceptions::WrongFormatException() << "State " << state << " was found but has already been read or skipped previously.";
}
while ((buf[0] != '\r') && (buf[0] != '\n') && (buf[0] != '\0')) {
cnt = skipWord(buf) - buf;
if (cnt == 0) {
// The next character is a separator.
// If it is a line separator, we continue with next node.
// Otherwise, we skip it and try again.
if (buf[0] == '\n' || buf[0] == '\r') break;
buf++;
} else {
// Copy the label to the buffer, null terminate it and add it to labeling.
strncpy(proposition, buf, cnt);
proposition[cnt] = '\0';
// Has the label been declared in the header?
if(!labeling.containsAtomicProposition(proposition)) {
LOG4CPLUS_ERROR(logger, "Wrong file format in (" << filename << "). Atomic proposition" << proposition << " was found but not declared.");
throw storm::exceptions::WrongFormatException();
}
labeling.addAtomicPropositionToState(proposition, state);
buf += cnt;
}
}
buf = trimWhitespaces(buf);
lastState = state;
}
buf = storm::parser::trimWhitespaces(buf);
return labeling;
}
}
return labeling;
}
} // namespace parser
} // namespace parser
} // namespace storm

36
src/parser/AtomicPropositionLabelingParser.h

@ -1,23 +1,33 @@
#ifndef STORM_PARSER_LABPARSER_H_
#define STORM_PARSER_LABPARSER_H_
#ifndef STORM_PARSER_ATOMICPROPOSITIONLABELINGPARSER_H_
#define STORM_PARSER_ATOMICPROPOSITIONLABELINGPARSER_H_
#include "src/models/AtomicPropositionsLabeling.h"
#include <cstdint>
#include "src/parser/Parser.h"
namespace storm {
namespace parser {
#include <memory>
/*!
* This class can be used to parse a labeling file.
*
* Since the labeling is state based, the same label parser can be used for all models.
*/
class AtomicPropositionLabelingParser {
namespace storm {
namespace parser {
public:
/*!
* Reads a label file and puts the result in an AtomicPropositionsLabeling object.
*
* @param stateCount The number of states of the model to be labeled.
* @param filename The path and name of the labeling (.lab) file.
* @return The parsed labeling as an AtomicPropositionsLabeling object.
*/
static storm::models::AtomicPropositionsLabeling parseAtomicPropositionLabeling(uint_fast64_t stateCount, std::string const &filename);
/*!
* @brief Load label file and return initialized AtomicPropositionsLabeling object.
*
*/
storm::models::AtomicPropositionsLabeling AtomicPropositionLabelingParser(uint_fast64_t node_count, std::string const &filename);
};
} // namespace parser
} // namespace parser
} // namespace storm
#endif /* STORM_PARSER_LABPARSER_H_ */
#endif /* STORM_PARSER_ATOMICPROPOSITIONLABELINGPARSER_H_ */

101
src/parser/AutoParser.cpp

@ -0,0 +1,101 @@
/*
* AutoParser.cpp
*
* Created on: Jan 20, 2014
* Author: Manuel S. Weiand
*/
#include "src/parser/AutoParser.h"
#include "src/parser/MappedFile.h"
#include "src/parser/DeterministicModelParser.h"
#include "src/parser/NondeterministicModelParser.h"
#include "src/parser/MarkovAutomatonParser.h"
#include "src/exceptions/WrongFormatException.h"
#include "src/utility/cstring.h"
#include "src/utility/OsDetection.h"
namespace storm {
namespace parser {
using namespace storm::utility::cstring;
std::shared_ptr<storm::models::AbstractModel<double>> AutoParser::parseModel(std::string const & transitionsFilename,
std::string const & labelingFilename,
std::string const & stateRewardFilename,
std::string const & transitionRewardFilename) {
// Find and parse the model type hint.
storm::models::ModelType type = AutoParser::analyzeHint(transitionsFilename);
// In case the hint string is unknown or could not be found, throw an exception.
if (type == storm::models::Unknown) {
LOG4CPLUS_ERROR(logger, "Could not determine file type of " << transitionsFilename << ".");
LOG4CPLUS_ERROR(logger, "The first line of the file should contain a format hint. Please fix your file and try again.");
throw storm::exceptions::WrongFormatException() << "Could not determine type of file " << transitionsFilename;
} else {
LOG4CPLUS_INFO(logger, "Model type seems to be " << type);
}
// Do the actual parsing.
std::shared_ptr<storm::models::AbstractModel<double>> model;
switch (type) {
case storm::models::DTMC: {
model.reset(new storm::models::Dtmc<double>(std::move(DeterministicModelParser::parseDtmc(transitionsFilename, labelingFilename, stateRewardFilename, transitionRewardFilename))));
break;
}
case storm::models::CTMC: {
model.reset(new storm::models::Ctmc<double>(std::move(DeterministicModelParser::parseCtmc(transitionsFilename, labelingFilename, stateRewardFilename, transitionRewardFilename))));
break;
}
case storm::models::MDP: {
model.reset(new storm::models::Mdp<double>(std::move(NondeterministicModelParser::parseMdp(transitionsFilename, labelingFilename, stateRewardFilename, transitionRewardFilename))));
break;
}
case storm::models::CTMDP: {
model.reset(new storm::models::Ctmdp<double>(std::move(NondeterministicModelParser::parseCtmdp(transitionsFilename, labelingFilename, stateRewardFilename, transitionRewardFilename))));
break;
}
case storm::models::MA: {
model.reset(new storm::models::MarkovAutomaton<double>(storm::parser::MarkovAutomatonParser::parseMarkovAutomaton(transitionsFilename, labelingFilename, stateRewardFilename, transitionRewardFilename)));
break;
}
default:
LOG4CPLUS_WARN(logger, "Unknown/Unhandled Model Type which cannot be parsed."); // Unknown
}
return model;
}
storm::models::ModelType AutoParser::analyzeHint(std::string const & filename) {
storm::models::ModelType hintType = storm::models::Unknown;
// Open the file.
MappedFile file(filename.c_str());
char* buf = file.getData();
// Find and read in the hint.
char hint[65];
// %60s => The input hint can be AT MOST 60 chars long.
#ifdef WINDOWS
sscanf_s(buf, "%60s", hint, sizeof(hint));
#else
sscanf(buf, "%60s", hint);
#endif
for (char* c = hint; *c != '\0'; c++) *c = toupper(*c);
// Check if the hint value is known and store the appropriate enum value.
if (strncmp(hint, "DTMC", sizeof(hint)) == 0) hintType = storm::models::DTMC;
else if (strncmp(hint, "CTMC", sizeof(hint)) == 0) hintType = storm::models::CTMC;
else if (strncmp(hint, "MDP", sizeof(hint)) == 0) hintType = storm::models::MDP;
else if (strncmp(hint, "CTMDP", sizeof(hint)) == 0) hintType = storm::models::CTMDP;
else if (strncmp(hint, "MA", sizeof(hint)) == 0) hintType = storm::models::MA;
return hintType;
}
} // namespace parser
} // namespace storm

171
src/parser/AutoParser.h

@ -1,140 +1,63 @@
#ifndef STORM_PARSER_AUTOPARSER_H_
#define STORM_PARSER_AUTOPARSER_H_
#include "src/parser/Parser.h"
#include "src/models/AbstractModel.h"
#include "src/exceptions/WrongFormatException.h"
#include "src/models/AbstractModel.h"
#include "src/parser/DeterministicModelParser.h"
#include "src/parser/NondeterministicModelParser.h"
#include "src/parser/MarkovAutomatonParser.h"
#include <memory>
#include <iostream>
#include <utility>
#include <string>
#include <cctype>
namespace storm {
namespace parser {
/*!
* @brief Checks the given files and parses the model within these files.
*
* This parser analyzes the format hint in the first line of the transition
* file. If this is a valid format, it will use the parser for this format,
* otherwise it will throw an exception.
*
* When the files are parsed successfully, the parsed ModelType and Model
* can be obtained via getType() and getModel<ModelClass>().
*/
template<class T>
class AutoParser {
public:
AutoParser(std::string const & transitionSystemFile, std::string const & labelingFile,
std::string const & stateRewardFile = "", std::string const & transitionRewardFile = "") : model(nullptr) {
storm::models::ModelType type = this->analyzeHint(transitionSystemFile);
if (type == storm::models::Unknown) {
LOG4CPLUS_ERROR(logger, "Could not determine file type of " << transitionSystemFile << ".");
LOG4CPLUS_ERROR(logger, "The first line of the file should contain a format hint. Please fix your file and try again.");
throw storm::exceptions::WrongFormatException() << "Could not determine type of file " << transitionSystemFile;
} else {
LOG4CPLUS_INFO(logger, "Model type seems to be " << type);
}
// Do actual parsing
switch (type) {
case storm::models::DTMC: {
this->model.reset(new storm::models::Dtmc<double>(std::move(DeterministicModelParserAsDtmc(transitionSystemFile, labelingFile, stateRewardFile, transitionRewardFile))));
break;
}
case storm::models::CTMC: {
this->model.reset(new storm::models::Ctmc<double>(std::move(DeterministicModelParserAsCtmc(transitionSystemFile, labelingFile, stateRewardFile, transitionRewardFile))));
break;
}
case storm::models::MDP: {
this->model.reset(new storm::models::Mdp<double>(std::move(NondeterministicModelParserAsMdp(transitionSystemFile, labelingFile, stateRewardFile, transitionRewardFile))));
break;
}
case storm::models::CTMDP: {
this->model.reset(new storm::models::Ctmdp<double>(std::move(NondeterministicModelParserAsCtmdp(transitionSystemFile, labelingFile, stateRewardFile, transitionRewardFile))));
break;
}
case storm::models::MA: {
this->model.reset(new storm::models::MarkovAutomaton<double>(storm::parser::MarkovAutomatonParser::parseMarkovAutomaton(transitionSystemFile, labelingFile, stateRewardFile, transitionRewardFile)));
break;
}
default: ; // Unknown
}
if (!this->model) {
LOG4CPLUS_WARN(logger, "Unknown/Unhandled Model Type. Model is still null.");
}
}
/*!
* @brief Returns the type of model that was parsed.
*/
storm::models::ModelType getType() {
if (this->model) {
return this->model->getType();
} else {
return storm::models::Unknown;
}
}
/*!
* @brief Returns the model with the given type.
*/
template <typename Model>
std::shared_ptr<Model> getModel() {
return this->model->template as<Model>();
}
/*!
* Contains all file parsers and helper classes.
*
* This namespace contains everything needed to load data files (like
* atomic propositions, transition systems, formulas, etc.) including
* methods for efficient file access (see MappedFile).
*/
namespace parser {
private:
/*!
* @brief Open file and read file format hint.
* This class automatically chooses the correct parser for the given files and returns the corresponding model.
* The choice of the parser is made using the model hint at the beginning of the given transition file.
*/
storm::models::ModelType analyzeHint(const std::string& filename) {
storm::models::ModelType hintType = storm::models::Unknown;
// Parse the File and check for the Line Endings
storm::parser::SupportedLineEndingsEnum lineEndings = storm::parser::findUsedLineEndings(filename);
// Open file
MappedFile file(filename.c_str());
char* buf = file.data;
// parse hint
char hint[128];
// %20s => The Input Hint can be AT MOST 120 chars long
storm::parser::scanForModelHint(hint, sizeof(hint), buf, lineEndings);
for (char* c = hint; *c != '\0'; c++) *c = toupper(*c);
// check hint
if (strncmp(hint, "DTMC", sizeof(hint)) == 0) hintType = storm::models::DTMC;
else if (strncmp(hint, "CTMC", sizeof(hint)) == 0) hintType = storm::models::CTMC;
else if (strncmp(hint, "MDP", sizeof(hint)) == 0) hintType = storm::models::MDP;
else if (strncmp(hint, "CTMDP", sizeof(hint)) == 0) hintType = storm::models::CTMDP;
else if (strncmp(hint, "MA", sizeof(hint)) == 0) hintType = storm::models::MA;
return hintType;
}
class AutoParser {
public:
/*!
* Checks the given files and parses the model within these files.
*
* This parser analyzes the format hint in the first line of the transition file.
* If this is a valid format, it will use the parser for this format, otherwise it will throw an exception.
*
* When the files are parsed successfully, a shared pointer owning the resulting model is returned.
* The concrete model can be obtained using the as<Type>() member of the AbstractModel class.
*
* @note The number of states of the model is determined by the transitions file.
* The labeling file may therefore not contain labels of states that are not contained in the transitions file.
*
* @param transitionsFilename The path and name of the file containing the transitions of the model.
* @param labelingFilename The path and name of the file containing the labels for the states of the model.
* @param stateRewardFilename The path and name of the file that contains the state reward of the model. This file is optional.
* @param transitionRewardFilename The path and name of the file that contains the transition rewards of the model. This file is optional.
* @return A shared_ptr containing the resulting model.
*/
static std::shared_ptr<storm::models::AbstractModel<double>> parseModel(std::string const & transitionsFilename,
std::string const & labelingFilename,
std::string const & stateRewardFilename = "",
std::string const & transitionRewardFilename = "");
private:
/*!
* Opens the given file and parses the file format hint.
*
* @param filename The path and name of the file that is to be analysed.
* @return The type of the model as an enum value.
*/
static storm::models::ModelType analyzeHint(std::string const & filename);
};
/*!
* @brief Pointer to a parser that has parsed the given transition system.
*/
std::shared_ptr<storm::models::AbstractModel<T>> model;
};
} // namespace parser
} // namespace parser
} // namespace storm
#endif /* STORM_PARSER_AUTOPARSER_H_ */

2
src/parser/CslParser.h

@ -8,8 +8,6 @@
#ifndef STORM_PARSER_CSLPARSER_H_
#define STORM_PARSER_CSLPARSER_H_
#include "Parser.h"
#include "src/formula/Csl.h"
#include <functional>

80
src/parser/DeterministicModelParser.cpp

@ -15,63 +15,45 @@
#include "src/parser/SparseStateRewardParser.h"
namespace storm {
namespace parser {
namespace parser {
/*!
* Parses a transition file and a labeling file
* Note that the labeling file may have at most as many nodes as the transition file!
*
* @param transitionSystemFile String containing the location of the transition file (....tra)
* @param labelingFile String containing the location of the labeling file (....lab)
* @param stateRewardFile String containing the location of the state reward file (...srew)
* @param transitionRewardFile String containing the location of the transition reward file (...trew)
*/
DeterministicModelParserResultContainer<double> parseDeterministicModel(std::string const & transitionSystemFile, std::string const & labelingFile,
std::string const & stateRewardFile, std::string const & transitionRewardFile) {
storm::storage::SparseMatrix<double> resultTransitionSystem(std::move(storm::parser::DeterministicSparseTransitionParser(transitionSystemFile)));
DeterministicModelParser::Result DeterministicModelParser::parseDeterministicModel(std::string const & transitionsFilename, std::string const & labelingFilename, std::string const & stateRewardFilename, std::string const & transitionRewardFilename) {
uint_fast64_t stateCount = resultTransitionSystem.getColumnCount();
// Parse the transitions.
storm::storage::SparseMatrix<double> transitions(std::move(storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitions(transitionsFilename)));
uint_fast64_t rowCount = resultTransitionSystem.getRowCount();
uint_fast64_t stateCount = transitions.getColumnCount();
storm::models::AtomicPropositionsLabeling resultLabeling(std::move(storm::parser::AtomicPropositionLabelingParser(stateCount, labelingFile)));
// Parse the state labeling.
storm::models::AtomicPropositionsLabeling labeling(std::move(storm::parser::AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(stateCount, labelingFilename)));
DeterministicModelParserResultContainer<double> result(std::move(resultTransitionSystem), std::move(resultLabeling));
// Construct the result.
DeterministicModelParser::Result result(std::move(transitions), std::move(labeling));
if (stateRewardFile != "") {
result.stateRewards.reset(storm::parser::SparseStateRewardParser(stateCount, stateRewardFile));
}
if (transitionRewardFile != "") {
RewardMatrixInformationStruct* rewardMatrixInfo = new RewardMatrixInformationStruct(rowCount, stateCount, nullptr);
result.transitionRewards.reset(std::move(storm::parser::DeterministicSparseTransitionParser(transitionRewardFile, false, rewardMatrixInfo)));
delete rewardMatrixInfo;
}
// Only parse state rewards if a file is given.
if (stateRewardFilename != "") {
result.stateRewards = storm::parser::SparseStateRewardParser::parseSparseStateReward(stateCount, stateRewardFilename);
}
return result;
}
// Only parse transition rewards if a file is given.
if (transitionRewardFilename != "") {
result.transitionRewards = storm::parser::DeterministicSparseTransitionParser::parseDeterministicTransitionRewards(transitionRewardFilename, result.transitionSystem);
}
/*!
* Uses the Function parseDeterministicModel internally to parse the given input files.
* @note This is a Short-Hand for Constructing a Dtmc directly from the data returned by @parseDeterministicModel
* @return A Dtmc Model
*/
storm::models::Dtmc<double> DeterministicModelParserAsDtmc(std::string const & transitionSystemFile, std::string const & labelingFile,
std::string const & stateRewardFile, std::string const & transitionRewardFile) {
DeterministicModelParserResultContainer<double> parserResult(std::move(parseDeterministicModel(transitionSystemFile, labelingFile, stateRewardFile, transitionRewardFile)));
return storm::models::Dtmc<double>(std::move(parserResult.transitionSystem), std::move(parserResult.labeling), std::move(parserResult.stateRewards), std::move(parserResult.transitionRewards), boost::optional<std::vector<boost::container::flat_set<uint_fast64_t>>>());
}
/*!
* Uses the Function parseDeterministicModel internally to parse the given input files.
* @note This is a Short-Hand for Constructing a Ctmc directly from the data returned by @parseDeterministicModel
* @return A Ctmc Model
*/
storm::models::Ctmc<double> DeterministicModelParserAsCtmc(std::string const & transitionSystemFile, std::string const & labelingFile,
std::string const & stateRewardFile, std::string const & transitionRewardFile) {
DeterministicModelParserResultContainer<double> parserResult(std::move(parseDeterministicModel(transitionSystemFile, labelingFile, stateRewardFile, transitionRewardFile)));
return storm::models::Ctmc<double>(std::move(parserResult.transitionSystem), std::move(parserResult.labeling), std::move(parserResult.stateRewards), std::move(parserResult.transitionRewards), boost::optional<std::vector<boost::container::flat_set<uint_fast64_t>>>());
}
return result;
}
storm::models::Dtmc<double> DeterministicModelParser::parseDtmc(std::string const & transitionsFilename, std::string const & labelingFilename, std::string const & stateRewardFilename, std::string const & transitionRewardFilename) {
DeterministicModelParser::Result parserResult(std::move(parseDeterministicModel(transitionsFilename, labelingFilename, stateRewardFilename, transitionRewardFilename)));
return storm::models::Dtmc<double>(std::move(parserResult.transitionSystem), std::move(parserResult.labeling), std::move(parserResult.stateRewards), std::move(parserResult.transitionRewards), boost::optional<std::vector<boost::container::flat_set<uint_fast64_t>>>());
}
storm::models::Ctmc<double> DeterministicModelParser::parseCtmc(std::string const & transitionsFilename, std::string const & labelingFilename, std::string const & stateRewardFilename, std::string const & transitionRewardFilename) {
} /* namespace parser */
DeterministicModelParser::Result parserResult(std::move(parseDeterministicModel(transitionsFilename, labelingFilename, stateRewardFilename, transitionRewardFilename)));
return storm::models::Ctmc<double>(std::move(parserResult.transitionSystem), std::move(parserResult.labeling), std::move(parserResult.stateRewards), std::move(parserResult.transitionRewards), boost::optional<std::vector<boost::container::flat_set<uint_fast64_t>>>());
}
} /* namespace parser */
} /* namespace storm */

151
src/parser/DeterministicModelParser.h

@ -8,54 +8,123 @@
#ifndef STORM_PARSER_DETERMINISTICMODELPARSER_H_
#define STORM_PARSER_DETERMINISTICMODELPARSER_H_
#include "src/parser/Parser.h"
#include "src/models/Dtmc.h"
#include "src/models/Ctmc.h"
#include <boost/optional.hpp>
namespace storm {
namespace parser {
namespace parser {
/*!
* @brief Load label and transition file and returns an initialized dtmc or ctmc object.
*
* @note This class creates a new Dtmc or Ctmc object
*
* @note The labeling representation in the file may use at most as much nodes as are specified in the transition system.
*/
/*!
* Loads a deterministic model (Dtmc or Ctmc) from files.
*
* Given the file paths of the files holding the transitions, the atomic propositions and optionally the state- and transition rewards
* it loads the files, parses them and returns the desired model.
*/
class DeterministicModelParser {
public:
storm::models::Dtmc<double> DeterministicModelParserAsDtmc(std::string const & transitionSystemFile, std::string const & labelingFile,
std::string const & stateRewardFile = "", std::string const & transitionRewardFile = "");
storm::models::Ctmc<double> DeterministicModelParserAsCtmc(std::string const & transitionSystemFile, std::string const & labelingFile,
std::string const & stateRewardFile = "", std::string const & transitionRewardFile = "");
/*!
* A structure containing the parsed components of a deterministic model.
*/
struct Result {
/*!
* @brief This Class acts as a container much like std::pair for the four return values of the DeterministicModelParser
*/
template <class T>
class DeterministicModelParserResultContainer {
public:
storm::storage::SparseMatrix<T> transitionSystem;
storm::models::AtomicPropositionsLabeling labeling;
boost::optional<std::vector<T>> stateRewards;
boost::optional<storm::storage::SparseMatrix<T>> transitionRewards;
DeterministicModelParserResultContainer(storm::storage::SparseMatrix<T>& transitionSystem, storm::models::AtomicPropositionsLabeling& labeling) : transitionSystem(transitionSystem), labeling(labeling) { }
DeterministicModelParserResultContainer(storm::storage::SparseMatrix<T>&& transitionSystem, storm::models::AtomicPropositionsLabeling&& labeling) : transitionSystem(std::move(transitionSystem)), labeling(std::move(labeling)) { }
DeterministicModelParserResultContainer(const DeterministicModelParserResultContainer & other) : transitionSystem(other.transitionSystem),
labeling(other.labeling), stateRewards(other.stateRewards), transitionRewards(other.transitionRewards) {}
DeterministicModelParserResultContainer(DeterministicModelParserResultContainer && other) : transitionSystem(std::move(other.transitionSystem)),
labeling(std::move(other.labeling)), stateRewards(std::move(other.stateRewards)), transitionRewards(std::move(other.transitionRewards)) {}
private:
DeterministicModelParserResultContainer() {}
};
DeterministicModelParserResultContainer<double> parseDeterministicModel(std::string const & transitionSystemFile, std::string const & labelingFile,
std::string const & stateRewardFile = "", std::string const & transitionRewardFile = "");
} /* namespace parser */
/*!
* The copy constructor.
*
* @param transitionSystem The transition system to be contained in the Result.
* @param labeling The the labeling of the transition system to be contained in the Result.
*/
Result(storm::storage::SparseMatrix<double>& transitionSystem, storm::models::AtomicPropositionsLabeling& labeling) : transitionSystem(transitionSystem), labeling(labeling) {
// Intentionally left empty.
}
/*!
* The move constructor.
*
* @param transitionSystem The transition system to be contained in the Result.
* @param labeling The the labeling of the transition system to be contained in the Result.
*/
Result(storm::storage::SparseMatrix<double>&& transitionSystem, storm::models::AtomicPropositionsLabeling&& labeling) : transitionSystem(std::move(transitionSystem)), labeling(std::move(labeling)) {
// Intentionally left empty.
}
//! A matrix representing the transitions of the model
storm::storage::SparseMatrix<double> transitionSystem;
//! The labels of each state.
storm::models::AtomicPropositionsLabeling labeling;
//! Optional rewards for each state.
boost::optional<std::vector<double>> stateRewards;
//! Optional rewards for each transition.
boost::optional<storm::storage::SparseMatrix<double>> transitionRewards;
};
/*!
* Parse a Dtmc.
*
* This method is an adapter to the actual parsing function.
* I.e. it uses @parseDeterministicModel internally to parse the given input files, takes its result and compiles it into a Dtmc.
*
* @note The number of states of the model is determined by the transitions file.
* The labeling file may therefore not contain labels of states that are not contained in the transitions file.
*
* @param transitionsFilename The path and name of the file containing the transitions of the model.
* @param labelingFilename The path and name of the file containing the labels for the states of the model.
* @param stateRewardFilename The path and name of the file containing the state reward of the model. This file is optional.
* @param transitionRewardFilename The path and name of the file containing the transition rewards of the model. This file is optional.
* @return The parsed Dtmc.
*/
static storm::models::Dtmc<double> parseDtmc(std::string const & transitionsFilename,
std::string const & labelingFilename,
std::string const & stateRewardFilename = "",
std::string const & transitionRewardFilename = "");
/*!
* Parse a Ctmc.
*
* This method is an adapter to the actual parsing function.
* I.e. it uses @parseDeterministicModel internally to parse the given input files, takes its result and compiles it into a Ctmc.
*
* @note The number of states of the model is determined by the transitions file.
* The labeling file may therefore not contain labels of states that are not contained in the transitions file.
*
* @param transitionsFilename The path and name of the file containing the transitions of the model.
* @param labelingFilename The path and name of the file containing the labels for the states of the model.
* @param stateRewardFilename The path and name of the file containing the state reward of the model. This file is optional.
* @param transitionRewardFilename The path and name of the file containing the transition rewards of the model. This file is optional.
* @return The parsed Ctmc.
*/
static storm::models::Ctmc<double> parseCtmc(std::string const & transitionsFilename,
std::string const & labelingFilename,
std::string const & stateRewardFilename = "",
std::string const & transitionRewardFilename = "");
private:
/*!
* Parses a deterministic model from the given files.
* Calls sub-parsers on the given files and fills the container with the results.
*
* @note The number of states of the model is determined by the transitions file.
* The labeling file may therefore not contain labels of states that are not contained in the transitions file.
*
* @param transitionsFilename The path and name of the file containing the transitions of the model.
* @param labelingFilename The path and name of the file containing the labels for the states of the model.
* @param stateRewardFilename The path and name of the file containing the state reward of the model. This file is optional.
* @param transitionRewardFilename The path and name of the file containing the transition rewards of the model. This file is optional.
* @return The parsed model encapsulated in a Result structure.
*/
static Result parseDeterministicModel(std::string const & transitionsFilename,
std::string const & labelingFilename,
std::string const & stateRewardFilename = "",
std::string const & transitionRewardFilename = "");
};
} /* namespace parser */
} /* namespace storm */
#endif /* STORM_PARSER_DETERMINISTICMODELPARSER_H_ */

465
src/parser/DeterministicSparseTransitionParser.cpp

@ -7,22 +7,18 @@
#include "src/parser/DeterministicSparseTransitionParser.h"
#include <errno.h>
#include <time.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <locale.h>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <cstdint>
#include <clocale>
#include <iostream>
#include <string>
#include "src/utility/constants.h"
#include "src/utility/cstring.h"
#include "src/parser/MappedFile.h"
#include "src/exceptions/FileIoException.h"
#include "src/exceptions/WrongFormatException.h"
#include <cstdint>
#include "src/settings/Settings.h"
#include "log4cplus/logger.h"
@ -30,253 +26,250 @@
extern log4cplus::Logger logger;
namespace storm {
namespace parser {
namespace parser {
/*!
* @brief Perform first pass through the file and obtain number of
* non-zero cells and maximum node id.
*
* This method does the first pass through the .tra file and computes
* the number of non-zero elements.
* It also calculates the maximum node id and stores it in maxnode.
*
* @return The number of non-zero elements
* @param buf Data to scan. Is expected to be some char array.
* @param maxnode Is set to highest id of all nodes.
*/
uint_fast64_t firstPass(char* buf, SupportedLineEndingsEnum lineEndings, uint_fast64_t& maxnode, RewardMatrixInformationStruct* rewardMatrixInformation) {
bool isRewardMatrix = rewardMatrixInformation != nullptr;
uint_fast64_t nonZeroEntryCount = 0;
/*
* Check file header and extract number of transitions.
*/
if (!isRewardMatrix) {
// skip format hint
buf = storm::parser::forwardToNextLine(buf, lineEndings);
}
/*
* Check all transitions for non-zero diagonal entries and deadlock states.
*/
int_fast64_t lastRow = -1;
uint_fast64_t row, col;
uint_fast64_t readTransitionCount = 0;
bool rowHadDiagonalEntry = false;
double val;
maxnode = 0;
while (buf[0] != '\0') {
/*
* Read row and column.
*/
row = checked_strtol(buf, &buf);
col = checked_strtol(buf, &buf);
if (!isRewardMatrix) {
if (lastRow != (int_fast64_t)row) {
if ((lastRow != -1) && (!rowHadDiagonalEntry)) {
++nonZeroEntryCount;
rowHadDiagonalEntry = true;
}
for (uint_fast64_t skippedRow = (uint_fast64_t)(lastRow + 1); skippedRow < row; ++skippedRow) {
++nonZeroEntryCount;
}
lastRow = row;
rowHadDiagonalEntry = false;
}
using namespace storm::utility::cstring;
if (col == row) {
rowHadDiagonalEntry = true;
} else if (col > row && !rowHadDiagonalEntry) {
rowHadDiagonalEntry = true;
++nonZeroEntryCount;
}
storm::storage::SparseMatrix<double> DeterministicSparseTransitionParser::parseDeterministicTransitions(std::string const& filename) {
storm::storage::SparseMatrix<double> emptyMatrix;
return DeterministicSparseTransitionParser::parse(filename, false, emptyMatrix);
}
/*
* Check if one is larger than the current maximum id.
*/
if (row > maxnode) maxnode = row;
if (col > maxnode) maxnode = col;
/*
* Read probability of this transition.
* Check, if the value is a probability, i.e. if it is between 0 and 1.
*/
val = checked_strtod(buf, &buf);
if ((val < 0.0) || (val > 1.0)) {
LOG4CPLUS_ERROR(logger, "Expected a positive probability but got \"" << val << "\".");
return 0;
storm::storage::SparseMatrix<double> DeterministicSparseTransitionParser::parseDeterministicTransitionRewards(std::string const& filename, storm::storage::SparseMatrix<double> const & transitionMatrix) {
return DeterministicSparseTransitionParser::parse(filename, true, transitionMatrix);
}
++nonZeroEntryCount;
++readTransitionCount;
buf = trimWhitespaces(buf);
}
if (!rowHadDiagonalEntry && !isRewardMatrix) {
++nonZeroEntryCount;
}
storm::storage::SparseMatrix<double> DeterministicSparseTransitionParser::parse(std::string const& filename, bool isRewardFile, storm::storage::SparseMatrix<double> const & transitionMatrix) {
// Enforce locale where decimal point is '.'.
setlocale(LC_NUMERIC, "C");
return nonZeroEntryCount;
}
if (!MappedFile::fileExistsAndIsReadable(filename.c_str())) {
LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": File does not exist or is not readable.");
throw storm::exceptions::FileIoException() << "The supplied Transition input file \"" << filename << "\" does not exist or is not readable by this process.";
}
// Open file.
MappedFile file(filename.c_str());
char* buf = file.getData();
// Perform first pass, i.e. count entries that are not zero.
bool insertDiagonalEntriesIfMissing = !isRewardFile;
DeterministicSparseTransitionParser::FirstPassResult firstPass = DeterministicSparseTransitionParser::firstPass(file.getData(), insertDiagonalEntriesIfMissing);
/*!
* Reads a .tra file and produces a sparse matrix representing the described Markov Chain.
*
* Matrices created with this method have to be freed with the delete operator.
* @param filename input .tra file's name.
* @return a pointer to the created sparse matrix.
*/
LOG4CPLUS_INFO(logger, "First pass on " << filename << " shows " << firstPass.numberOfNonzeroEntries << " NonZeros.");
storm::storage::SparseMatrix<double> DeterministicSparseTransitionParser(std::string const& filename, bool insertDiagonalEntriesIfMissing, RewardMatrixInformationStruct* rewardMatrixInformation) {
/*
* Enforce locale where decimal point is '.'.
*/
setlocale(LC_NUMERIC, "C");
bool isRewardMatrix = rewardMatrixInformation != nullptr;
if (!fileExistsAndIsReadable(filename.c_str())) {
LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": File does not exist or is not readable.");
throw storm::exceptions::FileIoException() << "The supplied Transition input file \"" << filename << "\" does not exist or is not readable by this process.";
}
/*
* Find out about the used line endings.
*/
SupportedLineEndingsEnum lineEndings = findUsedLineEndings(filename, true);
/*
* Open file.
*/
MappedFile file(filename.c_str());
char* buf = file.data;
/*
* Perform first pass, i.e. count entries that are not zero.
*/
uint_fast64_t maxStateId;
uint_fast64_t nonZeroEntryCount = firstPass(file.data, lineEndings, maxStateId, rewardMatrixInformation);
LOG4CPLUS_INFO(logger, "First pass on " << filename << " shows " << nonZeroEntryCount << " NonZeros.");
/*
* If first pass returned zero, the file format was wrong.
*/
if (nonZeroEntryCount == 0) {
LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": erroneous file format.");
throw storm::exceptions::WrongFormatException();
}
/*
* Perform second pass-
*
* From here on, we already know that the file header is correct.
*/
/*
* Read file header, extract number of states.
*/
if (!isRewardMatrix) {
// skip format hint
buf = storm::parser::forwardToNextLine(buf, lineEndings);
}
// If the matrix that is being parsed is a reward matrix, it should match the size of the
// transition matrix.
if (isRewardMatrix) {
if (maxStateId + 1 > rewardMatrixInformation->rowCount || maxStateId + 1 > rewardMatrixInformation->columnCount) {
LOG4CPLUS_ERROR(logger, "Reward matrix has more rows or columns than transition matrix.");
throw storm::exceptions::WrongFormatException() << "Reward matrix has more rows or columns than transition matrix.";
} else {
maxStateId = rewardMatrixInformation->rowCount - 1;
}
}
/*
* Creating matrix here.
* The number of non-zero elements is computed by firstPass().
*/
LOG4CPLUS_INFO(logger, "Attempting to create matrix of size " << (maxStateId+1) << " x " << (maxStateId+1) << ".");
storm::storage::SparseMatrixBuilder<double> matrixBuilder(maxStateId + 1, maxStateId + 1, nonZeroEntryCount);
int_fast64_t row, lastRow = -1, col;
double val;
bool fixDeadlocks = storm::settings::Settings::getInstance()->isSet("fixDeadlocks");
bool hadDeadlocks = false;
bool rowHadDiagonalEntry = false;
/*
* Read all transitions from file. Note that we assume that the
* transitions are listed in canonical order, otherwise this will not
* work, i.e. the values in the matrix will be at wrong places.
*/
while (buf[0] != '\0') {
/*
* Read row, col and value.
*/
row = checked_strtol(buf, &buf);
col = checked_strtol(buf, &buf);
val = checked_strtod(buf, &buf);
if (lastRow != row) {
if ((lastRow != -1) && (!rowHadDiagonalEntry)) {
if (insertDiagonalEntriesIfMissing && !isRewardMatrix) {
matrixBuilder.addNextValue(lastRow, lastRow, storm::utility::constantZero<double>());
// LOG4CPLUS_DEBUG(logger, "While parsing " << filename << ": state " << lastRow << " has no transition to itself. Inserted a 0-transition. (1)");
} else if (!isRewardMatrix) {
// LOG4CPLUS_WARN(logger, "Warning while parsing " << filename << ": state " << lastRow << " has no transition to itself.");
// If first pass returned zero, the file format was wrong.
if (firstPass.numberOfNonzeroEntries == 0) {
LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": empty or erroneous file format.");
throw storm::exceptions::WrongFormatException();
}
// No increment for lastRow
rowHadDiagonalEntry = true;
}
for (int_fast64_t skippedRow = lastRow + 1; skippedRow < row; ++skippedRow) {
hadDeadlocks = true;
if (fixDeadlocks && !isRewardMatrix) {
matrixBuilder.addNextValue(skippedRow, skippedRow, storm::utility::constantOne<double>());
rowHadDiagonalEntry = true;
// LOG4CPLUS_WARN(logger, "Warning while parsing " << filename << ": state " << skippedRow << " has no outgoing transitions. A self-loop was inserted.");
} else if (!isRewardMatrix) {
// LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": state " << skippedRow << " has no outgoing transitions.");
// FIXME Why no exception at this point? This will break the App.
// Perform second pass.
// Skip the format hint if it is there.
buf = trimWhitespaces(buf);
if(buf[0] < '0' || buf[0] > '9') {
buf = forwardToLineEnd(buf);
buf = trimWhitespaces(buf);
}
}
lastRow = row;
rowHadDiagonalEntry = false;
if(isRewardFile) {
// The reward matrix should match the size of the transition matrix.
if (firstPass.highestStateIndex + 1 > transitionMatrix.getRowCount() || firstPass.highestStateIndex + 1 > transitionMatrix.getColumnCount()) {
LOG4CPLUS_ERROR(logger, "Reward matrix has more rows or columns than transition matrix.");
throw storm::exceptions::WrongFormatException() << "Reward matrix has more rows or columns than transition matrix.";
} else {
// If we found the right number of states or less, we set it to the number of states represented by the transition matrix.
firstPass.highestStateIndex = transitionMatrix.getRowCount() - 1;
}
}
// Creating matrix builder here.
// The actual matrix will be build once all contents are inserted.
storm::storage::SparseMatrixBuilder<double> resultMatrix(firstPass.highestStateIndex + 1, firstPass.highestStateIndex + 1, firstPass.numberOfNonzeroEntries);
uint_fast64_t row, col, lastRow = 0;
double val;
bool fixDeadlocks = storm::settings::Settings::getInstance()->isSet("fixDeadlocks");
bool hadDeadlocks = false;
bool rowHadDiagonalEntry = false;
// Read all transitions from file. Note that we assume that the
// transitions are listed in canonical order, otherwise this will not
// work, i.e. the values in the matrix will be at wrong places.
// Different parsing routines for transition systems and transition rewards.
if(isRewardFile) {
while (buf[0] != '\0') {
// Read next transition.
row = checked_strtol(buf, &buf);
col = checked_strtol(buf, &buf);
val = checked_strtod(buf, &buf);
resultMatrix.addNextValue(row, col, val);
buf = trimWhitespaces(buf);
}
} else {
while (buf[0] != '\0') {
// Read next transition.
row = checked_strtol(buf, &buf);
col = checked_strtol(buf, &buf);
val = checked_strtod(buf, &buf);
// Test if we moved to a new row.
// Handle all incomplete or skipped rows.
if (lastRow != row) {
if (!rowHadDiagonalEntry) {
if (insertDiagonalEntriesIfMissing) {
resultMatrix.addNextValue(lastRow, lastRow, storm::utility::constantZero<double>());
LOG4CPLUS_DEBUG(logger, "While parsing " << filename << ": state " << lastRow << " has no transition to itself. Inserted a 0-transition. (1)");
} else {
LOG4CPLUS_WARN(logger, "Warning while parsing " << filename << ": state " << lastRow << " has no transition to itself.");
}
// No increment for lastRow.
rowHadDiagonalEntry = true;
}
for (uint_fast64_t skippedRow = lastRow + 1; skippedRow < row; ++skippedRow) {
hadDeadlocks = true;
if (fixDeadlocks) {
resultMatrix.addNextValue(skippedRow, skippedRow, storm::utility::constantOne<double>());
rowHadDiagonalEntry = true;
LOG4CPLUS_WARN(logger, "Warning while parsing " << filename << ": state " << skippedRow << " has no outgoing transitions. A self-loop was inserted.");
} else {
LOG4CPLUS_ERROR(logger, "Error while parsing " << filename << ": state " << skippedRow << " has no outgoing transitions.");
// Before throwing the appropriate exception we will give notice of all deadlock states.
}
}
lastRow = row;
rowHadDiagonalEntry = false;
}
if (col == row) {
rowHadDiagonalEntry = true;
}
if (col > row && !rowHadDiagonalEntry) {
if (insertDiagonalEntriesIfMissing) {
resultMatrix.addNextValue(row, row, storm::utility::constantZero<double>());
LOG4CPLUS_DEBUG(logger, "While parsing " << filename << ": state " << row << " has no transition to itself. Inserted a 0-transition. (2)");
} else {
LOG4CPLUS_WARN(logger, "Warning while parsing " << filename << ": state " << row << " has no transition to itself.");
}
rowHadDiagonalEntry = true;
}
resultMatrix.addNextValue(row, col, val);
buf = trimWhitespaces(buf);
}
if (!rowHadDiagonalEntry) {
if (insertDiagonalEntriesIfMissing) {
resultMatrix.addNextValue(lastRow, lastRow, storm::utility::constantZero<double>());
LOG4CPLUS_DEBUG(logger, "While parsing " << filename << ": state " << lastRow << " has no transition to itself. Inserted a 0-transition. (3)");
} else {
LOG4CPLUS_WARN(logger, "Warning while parsing " << filename << ": state " << lastRow << " has no transition to itself.");
}
}
// If we encountered deadlock and did not fix them, now is the time to throw the exception.
if (!fixDeadlocks && hadDeadlocks) throw storm::exceptions::WrongFormatException() << "Some of the nodes had deadlocks. You can use --fixDeadlocks to insert self-loops on the fly.";
}
// Finally, build the actual matrix, test and return it.
storm::storage::SparseMatrix<double> result = resultMatrix.build();
// Since we cannot do the testing if each transition for which there is a reward in the reward file also exists in the transition matrix during parsing, we have to do it afterwards.
if(isRewardFile && !result.isSubmatrixOf(transitionMatrix)) {
LOG4CPLUS_ERROR(logger, "There are rewards for non existent transitions given in the reward file.");
throw storm::exceptions::WrongFormatException() << "There are rewards for non existent transitions given in the reward file.";
}
return result;
}
if (col == row) {
rowHadDiagonalEntry = true;
} else if (col > row && !rowHadDiagonalEntry) {
rowHadDiagonalEntry = true;
if (insertDiagonalEntriesIfMissing && !isRewardMatrix) {
matrixBuilder.addNextValue(row, row, storm::utility::constantZero<double>());
// LOG4CPLUS_DEBUG(logger, "While parsing " << filename << ": state " << row << " has no transition to itself. Inserted a 0-transition. (2)");
} else if (!isRewardMatrix) {
// LOG4CPLUS_WARN(logger, "Warning while parsing " << filename << ": state " << row << " has no transition to itself.");
DeterministicSparseTransitionParser::FirstPassResult DeterministicSparseTransitionParser::firstPass(char* buf, bool insertDiagonalEntriesIfMissing) {
DeterministicSparseTransitionParser::FirstPassResult result;
// Skip the format hint if it is there.
buf = trimWhitespaces(buf);
if(buf[0] < '0' || buf[0] > '9') {
buf = forwardToLineEnd(buf);
buf = trimWhitespaces(buf);
}
}
matrixBuilder.addNextValue(row, col, val);
buf = trimWhitespaces(buf);
}
// Check all transitions for non-zero diagonal entries and deadlock states.
uint_fast64_t row, col, lastRow = 0, lastCol = -1;
bool rowHadDiagonalEntry = false;
while (buf[0] != '\0') {
// Read the transition.
row = checked_strtol(buf, &buf);
col = checked_strtol(buf, &buf);
// The actual read value is not needed here.
checked_strtod(buf, &buf);
// Compensate for missing diagonal entries if desired.
if (insertDiagonalEntriesIfMissing) {
if (lastRow != row) {
if(!rowHadDiagonalEntry) {
++result.numberOfNonzeroEntries;
}
// Compensate for missing rows.
for (uint_fast64_t skippedRow = lastRow + 1; skippedRow < row; ++skippedRow) {
++result.numberOfNonzeroEntries;
}
rowHadDiagonalEntry = false;
}
if (col == row) {
rowHadDiagonalEntry = true;
}
if (col > row && !rowHadDiagonalEntry) {
rowHadDiagonalEntry = true;
++result.numberOfNonzeroEntries;
}
}
if (!rowHadDiagonalEntry) {
if (insertDiagonalEntriesIfMissing && !isRewardMatrix) {
matrixBuilder.addNextValue(lastRow, lastRow, storm::utility::constantZero<double>());
// LOG4CPLUS_DEBUG(logger, "While parsing " << filename << ": state " << lastRow << " has no transition to itself. Inserted a 0-transition. (3)");
} else if (!isRewardMatrix) {
// LOG4CPLUS_WARN(logger, "Warning while parsing " << filename << ": state " << lastRow << " has no transition to itself.");
}
}
// Check if a higher state id was found.
if (row > result.highestStateIndex) result.highestStateIndex = row;
if (col > result.highestStateIndex) result.highestStateIndex = col;
if (!fixDeadlocks && hadDeadlocks) throw storm::exceptions::WrongFormatException() << "Some of the nodes had deadlocks. You can use --fixDeadlocks to insert self-loops on the fly.";
++result.numberOfNonzeroEntries;
return matrixBuilder.build();
}
// Have we already seen this transition?
if (row == lastRow && col == lastCol) {
LOG4CPLUS_ERROR(logger, "The same transition (" << row << ", " << col << ") is given twice.");
throw storm::exceptions::InvalidArgumentException() << "The same transition (" << row << ", " << col << ") is given twice.";
}
lastRow = row;
lastCol = col;
buf = trimWhitespaces(buf);
}
if(insertDiagonalEntriesIfMissing) {
if (!rowHadDiagonalEntry) {
++result.numberOfNonzeroEntries;
}
//Compensate for missing rows at the end of the file.
for (uint_fast64_t skippedRow = (uint_fast64_t)(lastRow + 1); skippedRow <= result.highestStateIndex; ++skippedRow) {
++result.numberOfNonzeroEntries;
}
}
return result;
}
} // namespace parser
} // namespace parser
} // namespace storm

99
src/parser/DeterministicSparseTransitionParser.h

@ -1,23 +1,90 @@
#ifndef STORM_PARSER_TRAPARSER_H_
#define STORM_PARSER_TRAPARSER_H_
#ifndef STORM_PARSER_DETERMINISTICSPARSETRANSITIONPARSER_H_
#define STORM_PARSER_DETERMINISTICSPARSETRANSITIONPARSER_H_
#include "src/storage/SparseMatrix.h"
#include "src/parser/Parser.h"
#include "src/utility/OsDetection.h"
namespace storm {
namespace parser {
#include <memory>
/*!
* This class can be used to parse a file containing either transitions or transition rewards of a deterministic model.
*
* The file is parsed in two passes.
* The first pass tests the file format and collects statistical data needed for the second pass.
* The second pass then parses the file data and constructs a SparseMatrix representing it.
*/
class DeterministicSparseTransitionParser {
public:
namespace storm {
namespace parser {
/*!
* @brief Load a deterministic transition system from file and create a
* sparse adjacency matrix whose entries represent the weights of the edges
*/
storm::storage::SparseMatrix<double> DeterministicSparseTransitionParser(std::string const& filename, bool insertDiagonalEntriesIfMissing = true, RewardMatrixInformationStruct* rewardMatrixInformation = nullptr);
} // namespace parser
/*!
* A structure representing the result of the first pass of this parser. It contains the number of non-zero entries in the model and the highest state index.
*/
struct FirstPassResult {
/*!
* The default constructor.
* Constructs an empty FirstPassResult.
*/
FirstPassResult() : numberOfNonzeroEntries(0), highestStateIndex(0) {
// Intentionally left empty.
}
//! The total number of non-zero entries of the model.
uint_fast64_t numberOfNonzeroEntries;
//! The highest state index that appears in the model.
uint_fast64_t highestStateIndex;
};
/*!
* Load a deterministic transition system from file and create a
* sparse adjacency matrix whose entries represent the weights of the edges.
*
* @param filename The path and name of the file to be parsed.
* @param insertDiagonalEntriesIfMissing A flag set iff entries on the primary diagonal of the matrix should be added in case they are missing in the parsed file.
* @return A SparseMatrix containing the parsed transition system.
*/
static storm::storage::SparseMatrix<double> parseDeterministicTransitions(std::string const& filename);
/*!
* Load the transition rewards for a deterministic transition system from file and create a
* sparse adjacency matrix whose entries represent the rewards of the respective transitions.
*
* @param filename The path and name of the file to be parsed.
* @param transitionMatrix The transition matrix of the model in which the reward matrix is to be used in.
* The dimensions (rows and columns) of the two matrices should match.
* @return A SparseMatrix containing the parsed transition rewards.
*/
static storm::storage::SparseMatrix<double> parseDeterministicTransitionRewards(std::string const& filename, storm::storage::SparseMatrix<double> const & transitionMatrix);
private:
/*
* Performs the first pass on the input pointed to by the given buffer to obtain the number of
* transitions and the maximum node id.
*
* @param buffer The buffer that contains the input.
* @param insertDiagonalEntriesIfMissing A flag set iff entries on the primary diagonal of the matrix should be added in case they are missing in the parsed file.
* @return A structure representing the result of the first pass.
*/
static FirstPassResult firstPass(char* buffer, bool insertDiagonalEntriesIfMissing = true);
/*
* The main parsing routine.
* Opens the given file, calls the first pass and performs the second pass, parsing the content of the file into a SparseMatrix.
*
* @param filename The path and name of the file to be parsed.
* @param rewardFile A flag set iff the file to be parsed contains transition rewards.
* @param insertDiagonalEntriesIfMissing A flag set iff entries on the primary diagonal of the matrix should be added in case they are missing in the parsed file.
* @param transitionMatrix The transition matrix of the model in which the reward matrix is to be used in.
* The dimensions (rows and columns) of the two matrices should match.
* @return A SparseMatrix containing the parsed file contents.
*/
static storm::storage::SparseMatrix<double> parse(std::string const& filename, bool isRewardFile, storm::storage::SparseMatrix<double> const & transitionMatrix);
};
} // namespace parser
} // namespace storm
#endif /* STORM_PARSER_TRAPARSER_H_ */
#endif /* STORM_PARSER_DETERMINISTICSPARSETRANSITIONPARSER_H_ */

400
src/parser/ExpressionParser.cpp

@ -0,0 +1,400 @@
#include "src/parser/ExpressionParser.h"
#include "src/exceptions/InvalidArgumentException.h"
#include "src/exceptions/InvalidTypeException.h"
#include "src/exceptions/WrongFormatException.h"
namespace storm {
namespace parser {
ExpressionParser::ExpressionParser(qi::symbols<char, uint_fast64_t> const& invalidIdentifiers_) : ExpressionParser::base_type(expression), createExpressions(false), acceptDoubleLiterals(true), identifiers_(nullptr), invalidIdentifiers_(invalidIdentifiers_) {
identifier %= qi::as_string[qi::raw[qi::lexeme[((qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_')))]]][qi::_pass = phoenix::bind(&ExpressionParser::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(&ExpressionParser::createFloorExpression, phoenix::ref(*this), qi::_1)] .else_ [qi::_val = phoenix::bind(&ExpressionParser::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(&ExpressionParser::createMinimumExpression, phoenix::ref(*this), qi::_1, qi::_2)] .else_ [qi::_val = phoenix::bind(&ExpressionParser::createMaximumExpression, phoenix::ref(*this), qi::_1, qi::_2)]];
minMaxExpression.name("min/max expression");
identifierExpression = identifier[qi::_val = phoenix::bind(&ExpressionParser::getIdentifierExpression, phoenix::ref(*this), qi::_1)];
identifierExpression.name("identifier expression");
literalExpression = qi::lit("true")[qi::_val = phoenix::bind(&ExpressionParser::createTrueExpression, phoenix::ref(*this))] | qi::lit("false")[qi::_val = phoenix::bind(&ExpressionParser::createFalseExpression, phoenix::ref(*this))] | strict_double[qi::_val = phoenix::bind(&ExpressionParser::createDoubleLiteralExpression, phoenix::ref(*this), qi::_1, qi::_pass)] | qi::int_[qi::_val = phoenix::bind(&ExpressionParser::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(&ExpressionParser::createNotExpression, phoenix::ref(*this), qi::_1)] | (qi::lit("-") >> atomicExpression)[qi::_val = phoenix::bind(&ExpressionParser::createMinusExpression, phoenix::ref(*this), qi::_1)];
unaryExpression.name("unary expression");
powerExpression = unaryExpression[qi::_val = qi::_1] >> -(qi::lit("^") > expression)[qi::_val = phoenix::bind(&ExpressionParser::createPowerExpression, phoenix::ref(*this), qi::_val, qi::_1)];
powerExpression.name("power expression");
multiplicationExpression = powerExpression[qi::_val = qi::_1] >> *((qi::lit("*")[qi::_a = true] | qi::lit("/")[qi::_a = false]) >> powerExpression[phoenix::if_(qi::_a) [qi::_val = phoenix::bind(&ExpressionParser::createMultExpression, phoenix::ref(*this), qi::_val, qi::_1)] .else_ [qi::_val = phoenix::bind(&ExpressionParser::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(&ExpressionParser::createPlusExpression, phoenix::ref(*this), qi::_val, qi::_1)] .else_ [qi::_val = phoenix::bind(&ExpressionParser::createMinusExpression, phoenix::ref(*this), qi::_val, qi::_1)]];
plusExpression.name("plus expression");
relativeExpression = (plusExpression >> qi::lit(">=") >> plusExpression)[qi::_val = phoenix::bind(&ExpressionParser::createGreaterOrEqualExpression, phoenix::ref(*this), qi::_1, qi::_2)] | (plusExpression >> qi::lit(">") >> plusExpression)[qi::_val = phoenix::bind(&ExpressionParser::createGreaterExpression, phoenix::ref(*this), qi::_1, qi::_2)] | (plusExpression >> qi::lit("<=") >> plusExpression)[qi::_val = phoenix::bind(&ExpressionParser::createLessOrEqualExpression, phoenix::ref(*this), qi::_1, qi::_2)] | (plusExpression >> qi::lit("<") >> plusExpression)[qi::_val = phoenix::bind(&ExpressionParser::createLessExpression, phoenix::ref(*this), qi::_1, qi::_2)] | plusExpression[qi::_val = qi::_1];
relativeExpression.name("relative expression");
equalityExpression = relativeExpression[qi::_val = qi::_1] >> *((qi::lit("=")[qi::_a = true] | qi::lit("!=")[qi::_a = false]) >> relativeExpression)[phoenix::if_(qi::_a) [ qi::_val = phoenix::bind(&ExpressionParser::createEqualsExpression, phoenix::ref(*this), qi::_val, qi::_1) ] .else_ [ qi::_val = phoenix::bind(&ExpressionParser::createNotEqualsExpression, phoenix::ref(*this), qi::_val, qi::_1) ] ];
equalityExpression.name("equality expression");
andExpression = equalityExpression[qi::_val = qi::_1] >> *(qi::lit("&") >> equalityExpression)[qi::_val = phoenix::bind(&ExpressionParser::createAndExpression, phoenix::ref(*this), qi::_val, qi::_1)];
andExpression.name("and expression");
orExpression = andExpression[qi::_val = qi::_1] >> *((qi::lit("|")[qi::_a = true] | qi::lit("=>")[qi::_a = false]) >> andExpression)[phoenix::if_(qi::_a) [qi::_val = phoenix::bind(&ExpressionParser::createOrExpression, phoenix::ref(*this), qi::_val, qi::_1)] .else_ [qi::_val = phoenix::bind(&ExpressionParser::createImpliesExpression, 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(&ExpressionParser::createIteExpression, phoenix::ref(*this), qi::_val, qi::_1, qi::_2)];
iteExpression.name("if-then-else expression");
expression %= iteExpression;
expression.name("expression");
// 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>(equalityExpression, 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));
}
void ExpressionParser::setIdentifierMapping(qi::symbols<char, storm::expressions::Expression> const* identifiers_) {
if (identifiers_ != nullptr) {
this->createExpressions = true;
this->identifiers_ = identifiers_;
} else {
this->createExpressions = false;
this->identifiers_ = nullptr;
}
}
void ExpressionParser::unsetIdentifierMapping() {
this->createExpressions = false;
this->identifiers_ = nullptr;
}
void ExpressionParser::setAcceptDoubleLiterals(bool flag) {
this->acceptDoubleLiterals = flag;
}
storm::expressions::Expression ExpressionParser::createIteExpression(storm::expressions::Expression e1, storm::expressions::Expression e2, storm::expressions::Expression e3) const {
if (this->createExpressions) {
try {
return e1.ite(e2, e3);
} catch (storm::exceptions::InvalidTypeException const& e) {
LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
}
} else {
return storm::expressions::Expression::createFalse();
}
}
storm::expressions::Expression ExpressionParser::createImpliesExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
if (this->createExpressions) {
try {
return e1.implies(e2);
} catch (storm::exceptions::InvalidTypeException const& e) {
LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
}
} else {
return storm::expressions::Expression::createFalse();
}
}
storm::expressions::Expression ExpressionParser::createOrExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
if (this->createExpressions) {
try {
return e1 || e2;
} catch (storm::exceptions::InvalidTypeException const& e) {
LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
}
} else {
return storm::expressions::Expression::createFalse();
}
}
storm::expressions::Expression ExpressionParser::createAndExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
if (this->createExpressions) {
try{
return e1 && e2;
} catch (storm::exceptions::InvalidTypeException const& e) {
LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
}
} else {
return storm::expressions::Expression::createFalse();
}
}
storm::expressions::Expression ExpressionParser::createGreaterExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
if (this->createExpressions) {
try {
return e1 > e2;
} catch (storm::exceptions::InvalidTypeException const& e) {
LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
}
} else {
return storm::expressions::Expression::createFalse();
}
}
storm::expressions::Expression ExpressionParser::createGreaterOrEqualExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
if (this->createExpressions) {
try {
return e1 >= e2;
} catch (storm::exceptions::InvalidTypeException const& e) {
LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
}
} else {
return storm::expressions::Expression::createFalse();
}
}
storm::expressions::Expression ExpressionParser::createLessExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
if (this->createExpressions) {
try {
return e1 < e2;
} catch (storm::exceptions::InvalidTypeException const& e) {
LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
}
} else {
return storm::expressions::Expression::createFalse();
}
}
storm::expressions::Expression ExpressionParser::createLessOrEqualExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
if (this->createExpressions) {
try {
return e1 <= e2;
} catch (storm::exceptions::InvalidTypeException const& e) {
LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
}
} else {
return storm::expressions::Expression::createFalse();
}
}
storm::expressions::Expression ExpressionParser::createEqualsExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
if (this->createExpressions) {
try {
if (e1.hasBooleanReturnType() && e2.hasBooleanReturnType()) {
return e1.iff(e2);
} else {
return e1 == e2;
}
} catch (storm::exceptions::InvalidTypeException const& e) {
LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
}
} else {
return storm::expressions::Expression::createFalse();
}
}
storm::expressions::Expression ExpressionParser::createNotEqualsExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
if (this->createExpressions) {
try {
return e1 != e2;
} catch (storm::exceptions::InvalidTypeException const& e) {
LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
}
} else {
return storm::expressions::Expression::createFalse();
}
}
storm::expressions::Expression ExpressionParser::createPlusExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
if (this->createExpressions) {
try {
return e1 + e2;
} catch (storm::exceptions::InvalidTypeException const& e) {
LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
}
} else {
return storm::expressions::Expression::createFalse();
}
}
storm::expressions::Expression ExpressionParser::createMinusExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
if (this->createExpressions) {
try {
return e1 - e2;
} catch (storm::exceptions::InvalidTypeException const& e) {
LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
}
} else {
return storm::expressions::Expression::createFalse();
}
}
storm::expressions::Expression ExpressionParser::createMultExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
if (this->createExpressions) {
try {
return e1 * e2;
} catch (storm::exceptions::InvalidTypeException const& e) {
LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
}
} else {
return storm::expressions::Expression::createFalse();
}
}
storm::expressions::Expression ExpressionParser::createPowerExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
if (this->createExpressions) {
try {
return e1 ^ e2;
} catch (storm::exceptions::InvalidTypeException const& e) {
LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
}
} else {
return storm::expressions::Expression::createFalse();
}
}
storm::expressions::Expression ExpressionParser::createDivExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
if (this->createExpressions) {
try {
return e1 / e2;
} catch (storm::exceptions::InvalidTypeException const& e) {
LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
}
} else {
return storm::expressions::Expression::createFalse();
}
}
storm::expressions::Expression ExpressionParser::createNotExpression(storm::expressions::Expression e1) const {
if (this->createExpressions) {
try {
return !e1;
} catch (storm::exceptions::InvalidTypeException const& e) {
LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
}
} else {
return storm::expressions::Expression::createFalse();
}
}
storm::expressions::Expression ExpressionParser::createMinusExpression(storm::expressions::Expression e1) const {
if (this->createExpressions) {
try {
return -e1;
} catch (storm::exceptions::InvalidTypeException const& e) {
LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
}
} else {
return storm::expressions::Expression::createFalse();
}
}
storm::expressions::Expression ExpressionParser::createTrueExpression() const {
if (this->createExpressions) {
return storm::expressions::Expression::createTrue();
} else {
return storm::expressions::Expression::createFalse();
}
}
storm::expressions::Expression ExpressionParser::createFalseExpression() const {
return storm::expressions::Expression::createFalse();
}
storm::expressions::Expression ExpressionParser::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->acceptDoubleLiterals) {
pass = false;
}
if (this->createExpressions) {
return storm::expressions::Expression::createDoubleLiteral(value);
} else {
return storm::expressions::Expression::createFalse();
}
}
storm::expressions::Expression ExpressionParser::createIntegerLiteralExpression(int value) const {
if (this->createExpressions) {
return storm::expressions::Expression::createIntegerLiteral(static_cast<int_fast64_t>(value));
} else {
return storm::expressions::Expression::createFalse();
}
}
storm::expressions::Expression ExpressionParser::createMinimumExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
if (this->createExpressions) {
try {
return storm::expressions::Expression::minimum(e1, e2);
} catch (storm::exceptions::InvalidTypeException const& e) {
LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
}
} else {
return storm::expressions::Expression::createFalse();
}
}
storm::expressions::Expression ExpressionParser::createMaximumExpression(storm::expressions::Expression e1, storm::expressions::Expression e2) const {
if (this->createExpressions) {
try {
return storm::expressions::Expression::maximum(e1, e2);
} catch (storm::exceptions::InvalidTypeException const& e) {
LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
}
} else {
return storm::expressions::Expression::createFalse();
}
}
storm::expressions::Expression ExpressionParser::createFloorExpression(storm::expressions::Expression e1) const {
if (this->createExpressions) {
try {
return e1.floor();
} catch (storm::exceptions::InvalidTypeException const& e) {
LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
}
} else {
return storm::expressions::Expression::createFalse();
}
}
storm::expressions::Expression ExpressionParser::createCeilExpression(storm::expressions::Expression e1) const {
if (this->createExpressions) {
try {
return e1.ceil();
} catch (storm::exceptions::InvalidTypeException const& e) {
LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": " << e.what());
}
} else {
return storm::expressions::Expression::createFalse();
}
}
storm::expressions::Expression ExpressionParser::getIdentifierExpression(std::string const& identifier) const {
if (this->createExpressions) {
LOG_THROW(this->identifiers_ != nullptr, storm::exceptions::WrongFormatException, "Unable to substitute identifier expressions without given mapping.");
storm::expressions::Expression const* expression = this->identifiers_->find(identifier);
LOG_THROW(expression != nullptr, storm::exceptions::WrongFormatException, "Parsing error in line " << get_line(qi::_3) << ": Undeclared identifier '" << identifier << "'.");
return *expression;
} else {
return storm::expressions::Expression::createFalse();
}
}
bool ExpressionParser::isValidIdentifier(std::string const& identifier) {
if (this->invalidIdentifiers_.find(identifier) != nullptr) {
return false;
}
return true;
}
}
}

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

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