Browse Source

Merge branch 'master' into simplified_levels

main
Sebastian Junges 8 years ago
parent
commit
8bdf6fe6b3
  1. 2
      resources/3rdparty/CMakeLists.txt
  2. 4
      resources/3rdparty/include_cpptemplate.cmake
  3. 23
      src/storm-dft/modelchecker/dft/DFTASFChecker.cpp
  4. 17
      src/storm-dft/parser/DFTGalileoParser.cpp
  5. 14
      src/storm-dft/parser/DFTJsonParser.cpp
  6. 8
      src/storm-gspn-cli/storm-gspn.cpp
  7. 20
      src/storm-gspn/storm-gspn.h
  8. 11
      src/storm-pgcl-cli/storm-pgcl.cpp
  9. 9
      src/storm-pgcl/parser/PgclParser.cpp
  10. 5
      src/storm/abstraction/MenuGameAbstractor.cpp
  11. 16
      src/storm/cli/entrypoints.h
  12. 82
      src/storm/modelchecker/multiobjective/pcaa/SparseMaPcaaWeightVectorChecker.cpp
  13. 4
      src/storm/modelchecker/multiobjective/pcaa/SparseMaPcaaWeightVectorChecker.h
  14. 44
      src/storm/modelchecker/multiobjective/pcaa/SparsePcaaQuantitativeQuery.cpp
  15. 107
      src/storm/modelchecker/multiobjective/pcaa/SparsePcaaWeightVectorChecker.cpp
  16. 5
      src/storm/modelchecker/region/ParameterRegion.cpp
  17. 19
      src/storm/models/symbolic/Model.cpp
  18. 11
      src/storm/models/symbolic/Model.h
  19. 5
      src/storm/parser/AtomicPropositionLabelingParser.cpp
  20. 5
      src/storm/parser/DeterministicSparseTransitionParser.cpp
  21. 9
      src/storm/parser/FormulaParser.cpp
  22. 14
      src/storm/parser/JaniParser.cpp
  23. 18
      src/storm/parser/MappedFile.cpp
  24. 8
      src/storm/parser/MappedFile.h
  25. 5
      src/storm/parser/MarkovAutomatonSparseTransitionParser.cpp
  26. 5
      src/storm/parser/NondeterministicSparseTransitionParser.cpp
  27. 10
      src/storm/parser/PrismParser.cpp
  28. 5
      src/storm/parser/SparseChoiceLabelingParser.cpp
  29. 5
      src/storm/parser/SparseStateRewardParser.cpp
  30. 8
      src/storm/settings/SettingsManager.cpp
  31. 13
      src/storm/solver/SmtlibSmtSolver.cpp
  32. 77
      src/storm/storage/SparseMatrix.cpp
  33. 6
      src/storm/storage/dd/Odd.cpp
  34. 8
      src/storm/storage/expressions/BaseExpression.cpp
  35. 10
      src/storm/storage/expressions/BaseExpression.h
  36. 14
      src/storm/storage/expressions/BinaryNumericalFunctionExpression.cpp
  37. 29
      src/storm/storage/expressions/BinaryRelationExpression.cpp
  38. 13
      src/storm/storage/expressions/ToRationalNumberVisitor.cpp
  39. 9
      src/storm/storage/expressions/ToRationalNumberVisitor.h
  40. 15
      src/storm/storage/expressions/UnaryNumericalFunctionExpression.cpp
  41. 18
      src/storm/storage/jani/JSONExporter.cpp
  42. 2
      src/storm/storage/jani/Model.cpp
  43. 6
      src/storm/storage/jani/ParallelComposition.cpp
  44. 50
      src/storm/transformer/SymbolicToSparseTransformer.cpp
  45. 15
      src/storm/transformer/SymbolicToSparseTransformer.h
  46. 9
      src/storm/utility/cli.cpp
  47. 4
      src/storm/utility/constants.cpp
  48. 15
      src/storm/utility/export.h
  49. 81
      src/storm/utility/file.h
  50. 13
      src/storm/utility/storm.h
  51. 10
      src/test/builder/DdJaniModelBuilderTest.cpp
  52. 7
      src/test/parser/MappedFileTest.cpp

2
resources/3rdparty/CMakeLists.txt

@ -201,7 +201,7 @@ if(USE_CARL)
message("START CARL CONFIG PROCESS")
file(MAKE_DIRECTORY ${STORM_3RDPARTY_BINARY_DIR}/carl_download)
execute_process(
COMMAND ${CMAKE_COMMAND} ${STORM_3RDPARTY_SOURCE_DIR}/carl "-DSTORM_3RDPARTY_BINARY_DIR=${STORM_3RDPARTY_BINARY_DIR}"
COMMAND ${CMAKE_COMMAND} ${STORM_3RDPARTY_SOURCE_DIR}/carl "-DSTORM_3RDPARTY_BINARY_DIR=${STORM_3RDPARTY_BINARY_DIR}" "-DBoost_LIBRARY_DIRS=${Boost_LIBRARY_DIRS}" "-DBoost_INCLUDE_DIRS=${Boost_INCLUDE_DIRS}"
WORKING_DIRECTORY ${STORM_3RDPARTY_BINARY_DIR}/carl_download
OUTPUT_VARIABLE carlconfig_out
RESULT_VARIABLE carlconfig_result)

4
resources/3rdparty/include_cpptemplate.cmake

@ -17,7 +17,7 @@ ExternalProject_Add(
INSTALL_COMMAND ""
BUILD_IN_SOURCE 0
LOG_BUILD ON
BUILD_BYPRODUCTS ${CPPTEMPLATE_LIB_DIR}/cpptemplate${DYNAMIC_EXT} ${CPPTEMPLATE_LIB_DIR}/cpptemplate${STATIC_EXT}
BUILD_BYPRODUCTS ${CPPTEMPLATE_LIB_DIR}/cpptemplate${STATIC_EXT}
)
set(CPPTEMPLATE_INCLUDE_DIR ${STORM_3RDPARTY_SOURCE_DIR}/cpptemplate)
@ -26,4 +26,4 @@ add_dependencies(resources cpptemplate)
message(STATUS "storm - Linking with cpptemplate.")
add_imported_library(cpptempl STATIC ${CPPTEMPLATE_STATIC_LIBRARY} ${CPPTEMPLATE_INCLUDE_DIR})
list(APPEND STORM_DEP_TARGETS cpptempl_STATIC)
list(APPEND STORM_DEP_TARGETS cpptempl_STATIC)

23
src/storm-dft/modelchecker/dft/DFTASFChecker.cpp

@ -1,5 +1,6 @@
#include "DFTASFChecker.h"
#include <string>
#include "storm/utility/file.h"
namespace storm {
@ -394,24 +395,22 @@ namespace storm {
}
void DFTASFChecker::toFile(std::string const& filename) {
std::ofstream ofs;
std::cout << "Writing to " << filename << std::endl;
ofs.open(filename);
ofs << "; time point variables" << std::endl;
std::ofstream stream;
storm::utility::openFile(filename, stream);
stream << "; time point variables" << std::endl;
for (auto const& timeVarEntry : timePointVariables) {
ofs << "(declare-fun " << varNames[timeVarEntry.second] << "() Int)" << std::endl;
stream << "(declare-fun " << varNames[timeVarEntry.second] << "() Int)" << std::endl;
}
ofs << "; claim variables" << std::endl;
stream << "; claim variables" << std::endl;
for (auto const& claimVarEntry : claimVariables) {
ofs << "(declare-fun " << varNames[claimVarEntry.second] << "() Int)" << std::endl;
stream << "(declare-fun " << varNames[claimVarEntry.second] << "() Int)" << std::endl;
}
for (auto const& constraint : constraints) {
ofs << "; " << constraint->description() << std::endl;
ofs << "(assert " << constraint->toSmtlib2(varNames) << ")" << std::endl;
stream << "; " << constraint->description() << std::endl;
stream << "(assert " << constraint->toSmtlib2(varNames) << ")" << std::endl;
}
ofs << "(check-sat)" << std::endl;
ofs.close();
stream << "(check-sat)" << std::endl;
storm::utility::closeFile(stream);
}
}
}

17
src/storm-dft/parser/DFTGalileoParser.cpp

@ -10,6 +10,7 @@
#include "storm/exceptions/FileIoException.h"
#include "storm/exceptions/NotSupportedException.h"
#include "storm/utility/macros.h"
#include "storm/utility/file.h"
namespace storm {
namespace parser {
@ -49,18 +50,10 @@ namespace storm {
std::string parametricToken = "param";
std::ifstream file;
file.exceptions ( std::ifstream::failbit );
try {
file.open(filename);
}
catch (std::ifstream::failure e) {
STORM_LOG_THROW(false, storm::exceptions::FileIoException, "Exception during file opening on " << filename << ".");
return;
}
file.exceptions( std::ifstream::goodbit );
storm::utility::openFile(filename, file);
std::string line;
while(std::getline(file, line)) {
while (std::getline(file, line)) {
bool success = true;
STORM_LOG_TRACE("Parsing: " << line);
size_t commentstarts = line.find("//");
@ -143,7 +136,7 @@ namespace storm {
if(!builder.setTopLevel(toplevelId)) {
STORM_LOG_THROW(false, storm::exceptions::FileIoException, "Top level id unknown.");
}
file.close();
storm::utility::closeFile(file);
}
template<typename ValueType>

14
src/storm-dft/parser/DFTJsonParser.cpp

@ -10,6 +10,7 @@
#include "storm/exceptions/FileIoException.h"
#include "storm/exceptions/NotSupportedException.h"
#include "storm/utility/macros.h"
#include "storm/utility/file.h"
namespace storm {
namespace parser {
@ -52,19 +53,10 @@ namespace storm {
STORM_LOG_DEBUG("Parsing from JSON");
std::ifstream file;
file.exceptions ( std::ifstream::failbit );
try {
file.open(filename);
}
catch (std::ifstream::failure e) {
STORM_LOG_THROW(false, storm::exceptions::FileIoException, "Exception during file opening on " << filename << ".");
return;
}
file.exceptions( std::ifstream::goodbit );
storm::utility::openFile(filename, file);
json parsedJson;
parsedJson << file;
file.close();
storm::utility::closeFile(file);
// Start by building mapping from ids to names
std::map<std::string, std::string> nameMapping;

8
src/storm-gspn-cli/storm-gspn.cpp

@ -56,19 +56,19 @@ void initializeSettings() {
std::unordered_map<std::string, uint64_t> parseCapacitiesList(std::string const& filename) {
std::unordered_map<std::string, uint64_t> map;
std::ifstream ifs;
ifs.open(filename);
std::ifstream stream;
storm::utility::openFile(filename, stream);
std::string line;
while( std::getline(ifs, line) ) {
while ( std::getline(stream, line) ) {
std::vector<std::string> strs;
boost::split(strs, line, boost::is_any_of("\t "));
STORM_LOG_THROW(strs.size() == 2, storm::exceptions::WrongFormatException, "Expect key value pairs");
std::cout << std::stoll(strs[1]) << std::endl;
map[strs[0]] = std::stoll(strs[1]);
}
storm::utility::closeFile(stream);
return map;
}

20
src/storm-gspn/storm-gspn.h

@ -8,6 +8,8 @@
#include "storm/settings/SettingsManager.h"
#include "storm/settings/modules/GSPNExportSettings.h"
#include "storm/utility/file.h"
namespace storm {
/**
* Builds JANI model from GSPN.
@ -21,23 +23,23 @@ namespace storm {
storm::settings::modules::GSPNExportSettings const& exportSettings = storm::settings::getModule<storm::settings::modules::GSPNExportSettings>();
if (exportSettings.isWriteToDotSet()) {
std::ofstream fs;
fs.open(exportSettings.getWriteToDotFilename());
storm::utility::openFile(exportSettings.getWriteToDotFilename(), fs);
gspn.writeDotToStream(fs);
fs.close();
storm::utility::closeFile(fs);
}
if (exportSettings.isWriteToPnproSet()) {
std::ofstream fs;
fs.open(exportSettings.getWriteToPnproFilename());
storm::utility::openFile(exportSettings.getWriteToPnproFilename(), fs);
gspn.toPnpro(fs);
fs.close();
storm::utility::closeFile(fs);
}
if (exportSettings.isWriteToPnmlSet()) {
std::ofstream fs;
fs.open(exportSettings.getWriteToPnmlFilename());
storm::utility::openFile(exportSettings.getWriteToPnmlFilename(), fs);
gspn.toPnml(fs);
fs.close();
storm::utility::closeFile(fs);
}
if (exportSettings.isDisplayStatsSet()) {
@ -48,13 +50,13 @@ namespace storm {
if (exportSettings.isWriteStatsToFileSet()) {
std::ofstream fs;
fs.open(exportSettings.getWriteStatsFilename());
storm::utility::openFile(exportSettings.getWriteStatsFilename(), fs);
gspn.writeStatsToStream(fs);
fs.close();
storm::utility::closeFile(fs);
}
}
}
}

11
src/storm-pgcl-cli/storm-pgcl.cpp

@ -47,13 +47,10 @@ void handleJani(storm::jani::Model& model) {
void programGraphToDotFile(storm::ppg::ProgramGraph const& prog) {
std::string filepath = storm::settings::getModule<storm::settings::modules::PGCLSettings>().getProgramGraphDotOutputFilename();
std::ofstream ofs;
ofs.open(filepath, std::ofstream::out );
if (ofs.is_open()) {
prog.printDot(ofs);
} else {
STORM_LOG_THROW(false, storm::exceptions::FileIoException, "Cannot open " << filepath);
}
std::ofstream stream;
storm::utility::openFile(filepath, stream);
prog.printDot(stream);
storm::utility::closeFile(stream);
}
int main(const int argc, const char** argv) {

9
src/storm-pgcl/parser/PgclParser.cpp

@ -1,6 +1,7 @@
#include "PgclParser.h"
// If the parser fails due to ill-formed data, this exception is thrown.
#include "storm/exceptions/WrongFormatException.h"
#include "storm/utility/file.h"
namespace storm {
namespace parser {
@ -9,8 +10,8 @@ namespace storm {
storm::pgcl::PgclProgram result;
// Open file and initialize result.
std::ifstream inputFileStream(filename, std::ios::in);
STORM_LOG_THROW(inputFileStream.good(), storm::exceptions::WrongFormatException, "Unable to read from file '" << filename << "'.");
std::ifstream inputFileStream;
storm::utility::openFile(filename, inputFileStream);
// Now try to parse the contents of the file.
try {
@ -18,12 +19,12 @@ namespace storm {
result = parseFromString(fileContent, filename);
} catch(std::exception& e) {
// In case of an exception properly close the file before passing exception.
inputFileStream.close();
storm::utility::closeFile(inputFileStream);
throw e;
}
// Close the stream in case everything went smoothly and return result.
inputFileStream.close();
storm::utility::closeFile(inputFileStream);
return result;
}

5
src/storm/abstraction/MenuGameAbstractor.cpp

@ -7,6 +7,7 @@
#include "storm/storage/dd/Add.h"
#include "storm/storage/dd/Bdd.h"
#include "storm/utility/dd.h"
#include "storm/utility/file.h"
#include "storm-config.h"
#include "storm/adapters/CarlAdapter.h"
@ -47,7 +48,8 @@ namespace storm {
template <storm::dd::DdType DdType, typename ValueType>
void MenuGameAbstractor<DdType, ValueType>::exportToDot(storm::abstraction::MenuGame<DdType, ValueType> const& currentGame, std::string const& filename, storm::dd::Bdd<DdType> const& highlightStatesBdd, storm::dd::Bdd<DdType> const& filter) const {
std::ofstream out(filename);
std::ofstream out;
storm::utility::openFile(filename, out);
AbstractionInformation<DdType> const& abstractionInformation = this->getAbstractionInformation();
storm::dd::Add<DdType, ValueType> filteredTransitions = filter.template toAdd<ValueType>() * currentGame.getTransitionMatrix();
@ -130,6 +132,7 @@ namespace storm {
}
out << "}" << std::endl;
storm::utility::closeFile(out);
}
template class MenuGameAbstractor<storm::dd::DdType::CUDD, double>;

16
src/storm/cli/entrypoints.h

@ -324,10 +324,18 @@ namespace storm {
// And export if required.
if(storm::settings::getModule<storm::settings::modules::IOSettings>().isExportExplicitSet()) {
std::ofstream ofs;
ofs.open(storm::settings::getModule<storm::settings::modules::IOSettings>().getExportExplicitFilename(), std::ofstream::out);
storm::exporter::explicitExportSparseModel(ofs, sparseModel, model.getParameterNames());
ofs.close();
std::ofstream stream;
storm::utility::openFile(storm::settings::getModule<storm::settings::modules::IOSettings>().getExportExplicitFilename(), stream);
storm::exporter::explicitExportSparseModel(stream, sparseModel, model.getParameterNames());
storm::utility::closeFile(stream);
}
// And export DOT if required.
if(storm::settings::getModule<storm::settings::modules::IOSettings>().isExportDotSet()) {
std::ofstream stream;
storm::utility::openFile(storm::settings::getModule<storm::settings::modules::IOSettings>().getExportDotFilename(), stream);
sparseModel->writeDotToStream(stream);
storm::utility::closeFile(stream);
}
}

82
src/storm/modelchecker/multiobjective/pcaa/SparseMaPcaaWeightVectorChecker.cpp

@ -74,12 +74,12 @@ namespace storm {
updateDataToCurrentEpoch(MS, PS, *minMax, consideredObjectives, currentEpoch, weightVector, lowerTimeBoundIt, lowerTimeBounds, upperTimeBoundIt, upperTimeBounds);
// Compute the values that can be obtained at probabilistic states in the current time epoch
performPSStep(PS, MS, *minMax, *linEq, optimalChoicesAtCurrentEpoch, consideredObjectives);
performPSStep(PS, MS, *minMax, *linEq, optimalChoicesAtCurrentEpoch, consideredObjectives, weightVector);
// Compute values that can be obtained at Markovian states after letting one (digitized) time unit pass.
// Only perform such a step if there is time left.
if(currentEpoch>0) {
performMSStep(MS, PS, consideredObjectives);
performMSStep(MS, PS, consideredObjectives, weightVector);
--currentEpoch;
} else {
break;
@ -354,55 +354,65 @@ namespace storm {
}
template <class SparseMaModelType>
void SparseMaPcaaWeightVectorChecker<SparseMaModelType>::performPSStep(SubModel& PS, SubModel const& MS, MinMaxSolverData& minMax, LinEqSolverData& linEq, std::vector<uint_fast64_t>& optimalChoicesAtCurrentEpoch, storm::storage::BitVector const& consideredObjectives) const {
void SparseMaPcaaWeightVectorChecker<SparseMaModelType>::performPSStep(SubModel& PS, SubModel const& MS, MinMaxSolverData& minMax, LinEqSolverData& linEq, std::vector<uint_fast64_t>& optimalChoicesAtCurrentEpoch, storm::storage::BitVector const& consideredObjectives, std::vector<ValueType> const& weightVector) const {
// compute a choice vector for the probabilistic states that is optimal w.r.t. the weighted reward vector
minMax.solver->solveEquations(PS.weightedSolutionVector, minMax.b);
auto newScheduler = minMax.solver->getScheduler();
// check whether the linEqSolver needs to be updated, i.e., whether the scheduler has changed
if(linEq.solver == nullptr || newScheduler->getChoices() != optimalChoicesAtCurrentEpoch) {
if(consideredObjectives.getNumberOfSetBits() == 1 && storm::utility::isOne(weightVector[*consideredObjectives.begin()])) {
// In this case there is no need to perform the computation on the individual objectives
optimalChoicesAtCurrentEpoch = newScheduler->getChoices();
linEq.solver = nullptr;
storm::storage::SparseMatrix<ValueType> linEqMatrix = PS.toPS.selectRowsFromRowGroups(optimalChoicesAtCurrentEpoch, true);
linEqMatrix.convertToEquationSystem();
linEq.solver = linEq.factory.create(std::move(linEqMatrix));
linEq.solver->setCachingEnabled(true);
}
// Get the results for the individual objectives.
// Note that we do not consider an estimate for each objective (as done in the unbounded phase) since the results from the previous epoch are already pretty close
for(auto objIndex : consideredObjectives) {
auto const& objectiveRewardVectorPS = PS.objectiveRewardVectors[objIndex];
auto const& objectiveSolutionVectorMS = MS.objectiveSolutionVectors[objIndex];
// compute rhs of equation system, i.e., PS.toMS * x + Rewards
// To safe some time, only do this for the obtained optimal choices
auto itGroupIndex = PS.toPS.getRowGroupIndices().begin();
auto itChoiceOffset = optimalChoicesAtCurrentEpoch.begin();
for(auto& bValue : linEq.b) {
uint_fast64_t row = (*itGroupIndex) + (*itChoiceOffset);
bValue = objectiveRewardVectorPS[row];
for(auto const& entry : PS.toMS.getRow(row)){
bValue += entry.getValue() * objectiveSolutionVectorMS[entry.getColumn()];
PS.objectiveSolutionVectors[*consideredObjectives.begin()] = PS.weightedSolutionVector;
} else {
// check whether the linEqSolver needs to be updated, i.e., whether the scheduler has changed
if(linEq.solver == nullptr || newScheduler->getChoices() != optimalChoicesAtCurrentEpoch) {
optimalChoicesAtCurrentEpoch = newScheduler->getChoices();
linEq.solver = nullptr;
storm::storage::SparseMatrix<ValueType> linEqMatrix = PS.toPS.selectRowsFromRowGroups(optimalChoicesAtCurrentEpoch, true);
linEqMatrix.convertToEquationSystem();
linEq.solver = linEq.factory.create(std::move(linEqMatrix));
linEq.solver->setCachingEnabled(true);
}
// Get the results for the individual objectives.
// Note that we do not consider an estimate for each objective (as done in the unbounded phase) since the results from the previous epoch are already pretty close
for(auto objIndex : consideredObjectives) {
auto const& objectiveRewardVectorPS = PS.objectiveRewardVectors[objIndex];
auto const& objectiveSolutionVectorMS = MS.objectiveSolutionVectors[objIndex];
// compute rhs of equation system, i.e., PS.toMS * x + Rewards
// To safe some time, only do this for the obtained optimal choices
auto itGroupIndex = PS.toPS.getRowGroupIndices().begin();
auto itChoiceOffset = optimalChoicesAtCurrentEpoch.begin();
for(auto& bValue : linEq.b) {
uint_fast64_t row = (*itGroupIndex) + (*itChoiceOffset);
bValue = objectiveRewardVectorPS[row];
for(auto const& entry : PS.toMS.getRow(row)){
bValue += entry.getValue() * objectiveSolutionVectorMS[entry.getColumn()];
}
++itGroupIndex;
++itChoiceOffset;
}
++itGroupIndex;
++itChoiceOffset;
linEq.solver->solveEquations(PS.objectiveSolutionVectors[objIndex], linEq.b);
}
linEq.solver->solveEquations(PS.objectiveSolutionVectors[objIndex], linEq.b);
}
}
template <class SparseMaModelType>
void SparseMaPcaaWeightVectorChecker<SparseMaModelType>::performMSStep(SubModel& MS, SubModel const& PS, storm::storage::BitVector const& consideredObjectives) const {
void SparseMaPcaaWeightVectorChecker<SparseMaModelType>::performMSStep(SubModel& MS, SubModel const& PS, storm::storage::BitVector const& consideredObjectives, std::vector<ValueType> const& weightVector) const {
MS.toMS.multiplyWithVector(MS.weightedSolutionVector, MS.auxChoiceValues);
storm::utility::vector::addVectors(MS.weightedRewardVector, MS.auxChoiceValues, MS.weightedSolutionVector);
MS.toPS.multiplyWithVector(PS.weightedSolutionVector, MS.auxChoiceValues);
storm::utility::vector::addVectors(MS.weightedSolutionVector, MS.auxChoiceValues, MS.weightedSolutionVector);
for(auto objIndex : consideredObjectives) {
MS.toMS.multiplyWithVector(MS.objectiveSolutionVectors[objIndex], MS.auxChoiceValues);
storm::utility::vector::addVectors(MS.objectiveRewardVectors[objIndex], MS.auxChoiceValues, MS.objectiveSolutionVectors[objIndex]);
MS.toPS.multiplyWithVector(PS.objectiveSolutionVectors[objIndex], MS.auxChoiceValues);
storm::utility::vector::addVectors(MS.objectiveSolutionVectors[objIndex], MS.auxChoiceValues, MS.objectiveSolutionVectors[objIndex]);
if(consideredObjectives.getNumberOfSetBits() == 1 && storm::utility::isOne(weightVector[*consideredObjectives.begin()])) {
// In this case there is no need to perform the computation on the individual objectives
MS.objectiveSolutionVectors[*consideredObjectives.begin()] = MS.weightedSolutionVector;
} else {
for(auto objIndex : consideredObjectives) {
MS.toMS.multiplyWithVector(MS.objectiveSolutionVectors[objIndex], MS.auxChoiceValues);
storm::utility::vector::addVectors(MS.objectiveRewardVectors[objIndex], MS.auxChoiceValues, MS.objectiveSolutionVectors[objIndex]);
MS.toPS.multiplyWithVector(PS.objectiveSolutionVectors[objIndex], MS.auxChoiceValues);
storm::utility::vector::addVectors(MS.objectiveSolutionVectors[objIndex], MS.auxChoiceValues, MS.objectiveSolutionVectors[objIndex]);
}
}
}

4
src/storm/modelchecker/multiobjective/pcaa/SparseMaPcaaWeightVectorChecker.h

@ -138,7 +138,7 @@ namespace storm {
*
* The resulting values represent the rewards at probabilistic states that are obtained at the current time epoch.
*/
void performPSStep(SubModel& PS, SubModel const& MS, MinMaxSolverData& minMax, LinEqSolverData& linEq, std::vector<uint_fast64_t>& optimalChoicesAtCurrentEpoch, storm::storage::BitVector const& consideredObjectives) const;
void performPSStep(SubModel& PS, SubModel const& MS, MinMaxSolverData& minMax, LinEqSolverData& linEq, std::vector<uint_fast64_t>& optimalChoicesAtCurrentEpoch, storm::storage::BitVector const& consideredObjectives, std::vector<ValueType> const& weightVector) const;
/*
* Performs a step for the Markovian states, that is
@ -146,7 +146,7 @@ namespace storm {
*
* The resulting values represent the rewards at Markovian states that are obtained after one (digitized) time unit has passed.
*/
void performMSStep(SubModel& MS, SubModel const& PS, storm::storage::BitVector const& consideredObjectives) const;
void performMSStep(SubModel& MS, SubModel const& PS, storm::storage::BitVector const& consideredObjectives, std::vector<ValueType> const& weightVector) const;
};

44
src/storm/modelchecker/multiobjective/pcaa/SparsePcaaQuantitativeQuery.cpp

@ -51,8 +51,6 @@ namespace storm {
template <class SparseModelType, typename GeometryValueType>
std::unique_ptr<CheckResult> SparsePcaaQuantitativeQuery<SparseModelType, GeometryValueType>::check() {
// First find one solution that achieves the given thresholds ...
if(this->checkAchievability()) {
// ... then improve it
@ -73,21 +71,26 @@ namespace storm {
template <class SparseModelType, typename GeometryValueType>
bool SparsePcaaQuantitativeQuery<SparseModelType, GeometryValueType>::checkAchievability() {
// We don't care for the optimizing objective at this point
this->diracWeightVectorsToBeChecked.set(indexOfOptimizingObjective, false);
if(this->objectives.size()>1) {
// We don't care for the optimizing objective at this point
this->diracWeightVectorsToBeChecked.set(indexOfOptimizingObjective, false);
while(!this->maxStepsPerformed()){
WeightVector separatingVector = this->findSeparatingVector(thresholds);
this->updateWeightedPrecisionInAchievabilityPhase(separatingVector);
this->performRefinementStep(std::move(separatingVector));
//Pick the threshold for the optimizing objective low enough so valid solutions are not excluded
thresholds[indexOfOptimizingObjective] = std::min(thresholds[indexOfOptimizingObjective], this->refinementSteps.back().lowerBoundPoint[indexOfOptimizingObjective]);
if(!checkIfThresholdsAreSatisfied(this->overApproximation)){
return false;
}
if(checkIfThresholdsAreSatisfied(this->underApproximation)){
return true;
while(!this->maxStepsPerformed()){
WeightVector separatingVector = this->findSeparatingVector(thresholds);
this->updateWeightedPrecisionInAchievabilityPhase(separatingVector);
this->performRefinementStep(std::move(separatingVector));
//Pick the threshold for the optimizing objective low enough so valid solutions are not excluded
thresholds[indexOfOptimizingObjective] = std::min(thresholds[indexOfOptimizingObjective], this->refinementSteps.back().lowerBoundPoint[indexOfOptimizingObjective]);
if(!checkIfThresholdsAreSatisfied(this->overApproximation)){
return false;
}
if(checkIfThresholdsAreSatisfied(this->underApproximation)){
return true;
}
}
} else {
// If there is only one objective than its the optimizing one. Thus the query has to be achievable.
return true;
}
STORM_LOG_ERROR("Could not check whether thresholds are achievable: Exceeded maximum number of refinement steps");
return false;
@ -124,6 +127,12 @@ namespace storm {
// thresholds) and (with very low probability) a scheduler that satisfies all (possibly strict) thresholds.
GeometryValueType result = storm::utility::zero<GeometryValueType>();
while(!this->maxStepsPerformed()) {
if(this->refinementSteps.empty()) {
// We did not make any refinement steps during the checkAchievability phase (e.g., because there is only one objective).
this->weightVectorChecker->setWeightedPrecision(storm::utility::convertNumber<typename SparseModelType::ValueType>(storm::settings::getModule<storm::settings::modules::MultiObjectiveSettings>().getPrecision()));
WeightVector separatingVector = directionOfOptimizingObjective;
this->performRefinementStep(std::move(separatingVector));
}
std::pair<Point, bool> optimizationRes = this->underApproximation->intersection(thresholdsAsPolytope)->optimize(directionOfOptimizingObjective);
STORM_LOG_THROW(optimizationRes.second, storm::exceptions::UnexpectedException, "The underapproximation is either unbounded or empty.");
result = optimizationRes.first[indexOfOptimizingObjective];
@ -155,11 +164,12 @@ namespace storm {
void SparsePcaaQuantitativeQuery<SparseModelType, GeometryValueType>::updateWeightedPrecisionInImprovingPhase(WeightVector const& weights) {
STORM_LOG_THROW(!storm::utility::isZero(weights[this->indexOfOptimizingObjective]), exceptions::UnexpectedException, "The chosen weight-vector gives zero weight for the objective that is to be optimized.");
// If weighs[indexOfOptimizingObjective] is low, the computation of the weightVectorChecker needs to be more precise.
// Our heuristic ensures that if p is the new vertex of the under-approximation, then max{ eps | p' = p + (0..0 eps 0..0) is in the over-approximation } <= multiobjective_precision/2
// Our heuristic ensures that if p is the new vertex of the under-approximation, then max{ eps | p' = p + (0..0 eps 0..0) is in the over-approximation } <= multiobjective_precision/0.9
GeometryValueType weightedPrecision = weights[this->indexOfOptimizingObjective] * storm::utility::convertNumber<GeometryValueType>(storm::settings::getModule<storm::settings::modules::MultiObjectiveSettings>().getPrecision());
// Normalize by division with the Euclidean Norm of the weight-vector
weightedPrecision /= storm::utility::sqrt(storm::utility::vector::dotProduct(weights, weights));
weightedPrecision /= GeometryValueType(2);
weightedPrecision *= storm::utility::convertNumber<GeometryValueType>(0.9);
this->weightVectorChecker->setWeightedPrecision(storm::utility::convertNumber<typename SparseModelType::ValueType>(weightedPrecision));
}

107
src/storm/modelchecker/multiobjective/pcaa/SparsePcaaWeightVectorChecker.cpp

@ -158,52 +158,71 @@ namespace storm {
template <class SparseModelType>
void SparsePcaaWeightVectorChecker<SparseModelType>::unboundedIndividualPhase(std::vector<ValueType> const& weightVector) {
storm::storage::SparseMatrix<ValueType> deterministicMatrix = model.getTransitionMatrix().selectRowsFromRowGroups(this->scheduler.getChoices(), true);
storm::storage::SparseMatrix<ValueType> deterministicBackwardTransitions = deterministicMatrix.transpose();
std::vector<ValueType> deterministicStateRewards(deterministicMatrix.getRowCount());
storm::solver::GeneralLinearEquationSolverFactory<ValueType> linearEquationSolverFactory;
// We compute an estimate for the results of the individual objectives which is obtained from the weighted result and the result of the objectives computed so far.
// Note that weightedResult = Sum_{i=1}^{n} w_i * objectiveResult_i.
std::vector<ValueType> weightedSumOfUncheckedObjectives = weightedResult;
ValueType sumOfWeightsOfUncheckedObjectives = storm::utility::vector::sum_if(weightVector, objectivesWithNoUpperTimeBound);
for(uint_fast64_t const& objIndex : storm::utility::vector::getSortedIndices(weightVector)) {
if(objectivesWithNoUpperTimeBound.get(objIndex)){
offsetsToLowerBound[objIndex] = storm::utility::zero<ValueType>();
offsetsToUpperBound[objIndex] = storm::utility::zero<ValueType>();
storm::utility::vector::selectVectorValues(deterministicStateRewards, this->scheduler.getChoices(), model.getTransitionMatrix().getRowGroupIndices(), discreteActionRewards[objIndex]);
storm::storage::BitVector statesWithRewards = ~storm::utility::vector::filterZero(deterministicStateRewards);
// As target states, we pick the states from which no reward is reachable.
storm::storage::BitVector targetStates = ~storm::utility::graph::performProbGreater0(deterministicBackwardTransitions, storm::storage::BitVector(deterministicMatrix.getRowCount(), true), statesWithRewards);
// Compute the estimate for this objective
if(!storm::utility::isZero(weightVector[objIndex])) {
objectiveResults[objIndex] = weightedSumOfUncheckedObjectives;
storm::utility::vector::scaleVectorInPlace(objectiveResults[objIndex], storm::utility::one<ValueType>() / sumOfWeightsOfUncheckedObjectives);
}
// Make sure that the objectiveResult is initialized in some way
objectiveResults[objIndex].resize(model.getNumberOfStates(), storm::utility::zero<ValueType>());
// Invoke the linear equation solver
objectiveResults[objIndex] = storm::modelchecker::helper::SparseDtmcPrctlHelper<ValueType>::computeReachabilityRewards(deterministicMatrix,
deterministicBackwardTransitions,
deterministicStateRewards,
targetStates,
false, //no qualitative checking,
linearEquationSolverFactory,
objectiveResults[objIndex]);
// Update the estimate for the next objectives.
if(!storm::utility::isZero(weightVector[objIndex])) {
storm::utility::vector::addScaledVector(weightedSumOfUncheckedObjectives, objectiveResults[objIndex], -weightVector[objIndex]);
sumOfWeightsOfUncheckedObjectives -= weightVector[objIndex];
if(objectivesWithNoUpperTimeBound.getNumberOfSetBits() == 1 && storm::utility::isOne(weightVector[*objectivesWithNoUpperTimeBound.begin()])) {
objectiveResults[*objectivesWithNoUpperTimeBound.begin()] = weightedResult;
for (uint_fast64_t objIndex2 = 0; objIndex2 < objectives.size(); ++objIndex2) {
if(*objectivesWithNoUpperTimeBound.begin() != objIndex2) {
objectiveResults[objIndex2] = std::vector<ValueType>(model.getNumberOfStates(), storm::utility::zero<ValueType>());
}
} else {
objectiveResults[objIndex] = std::vector<ValueType>(model.getNumberOfStates(), storm::utility::zero<ValueType>());
}
}
} else {
storm::storage::SparseMatrix<ValueType> deterministicMatrix = model.getTransitionMatrix().selectRowsFromRowGroups(this->scheduler.getChoices(), true);
storm::storage::SparseMatrix<ValueType> deterministicBackwardTransitions = deterministicMatrix.transpose();
std::vector<ValueType> deterministicStateRewards(deterministicMatrix.getRowCount());
storm::solver::GeneralLinearEquationSolverFactory<ValueType> linearEquationSolverFactory;
// We compute an estimate for the results of the individual objectives which is obtained from the weighted result and the result of the objectives computed so far.
// Note that weightedResult = Sum_{i=1}^{n} w_i * objectiveResult_i.
std::vector<ValueType> weightedSumOfUncheckedObjectives = weightedResult;
ValueType sumOfWeightsOfUncheckedObjectives = storm::utility::vector::sum_if(weightVector, objectivesWithNoUpperTimeBound);
for (uint_fast64_t const &objIndex : storm::utility::vector::getSortedIndices(weightVector)) {
if (objectivesWithNoUpperTimeBound.get(objIndex)) {
offsetsToLowerBound[objIndex] = storm::utility::zero<ValueType>();
offsetsToUpperBound[objIndex] = storm::utility::zero<ValueType>();
storm::utility::vector::selectVectorValues(deterministicStateRewards, this->scheduler.getChoices(), model.getTransitionMatrix().getRowGroupIndices(), discreteActionRewards[objIndex]);
storm::storage::BitVector statesWithRewards = ~storm::utility::vector::filterZero(deterministicStateRewards);
// As maybestates we pick the states from which a state with reward is reachable
storm::storage::BitVector maybeStates = storm::utility::graph::performProbGreater0(deterministicBackwardTransitions, storm::storage::BitVector(deterministicMatrix.getRowCount(), true), statesWithRewards);
// Compute the estimate for this objective
if (!storm::utility::isZero(weightVector[objIndex])) {
objectiveResults[objIndex] = weightedSumOfUncheckedObjectives;
storm::utility::vector::scaleVectorInPlace(objectiveResults[objIndex], storm::utility::one<ValueType>() / sumOfWeightsOfUncheckedObjectives);
}
// Make sure that the objectiveResult is initialized correctly
objectiveResults[objIndex].resize(model.getNumberOfStates(), storm::utility::zero<ValueType>());
if (!maybeStates.empty()) {
storm::storage::SparseMatrix<ValueType> submatrix = deterministicMatrix.getSubmatrix(
true, maybeStates, maybeStates, true);
// Converting the matrix from the fixpoint notation to the form needed for the equation
// system. That is, we go from x = A*x + b to (I-A)x = b.
submatrix.convertToEquationSystem();
// Prepare solution vector and rhs of the equation system.
std::vector<ValueType> x = storm::utility::vector::filterVector(objectiveResults[objIndex], maybeStates);
std::vector<ValueType> b = storm::utility::vector::filterVector(deterministicStateRewards, maybeStates);
// Now solve the resulting equation system.
std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> solver = linearEquationSolverFactory.create(std::move(submatrix));
solver->solveEquations(x, b);
// Set the result for this objective accordingly
storm::utility::vector::setVectorValues<ValueType>(objectiveResults[objIndex], maybeStates, x);
storm::utility::vector::setVectorValues<ValueType>(objectiveResults[objIndex], ~maybeStates, storm::utility::zero<ValueType>());
}
// Update the estimate for the next objectives.
if (!storm::utility::isZero(weightVector[objIndex])) {
storm::utility::vector::addScaledVector(weightedSumOfUncheckedObjectives, objectiveResults[objIndex], -weightVector[objIndex]);
sumOfWeightsOfUncheckedObjectives -= weightVector[objIndex];
}
} else {
objectiveResults[objIndex] = std::vector<ValueType>(model.getNumberOfStates(), storm::utility::zero<ValueType>());
}
}
}
}
template <class SparseModelType>

5
src/storm/modelchecker/region/ParameterRegion.cpp

@ -7,7 +7,8 @@
#include "storm/settings/modules/RegionSettings.h"
#include "storm/exceptions/InvalidSettingsException.h"
#include "storm/exceptions/InvalidArgumentException.h"
#include "utility/constants.h"
#include "storm/utility/constants.h"
#include "storm/utility/file.h"
namespace storm {
namespace modelchecker {
@ -283,7 +284,7 @@ namespace storm {
}
else{
//if we reach this point we can assume that the region is given as a file.
STORM_LOG_THROW(storm::parser::MappedFile::fileExistsAndIsReadable(storm::settings::getModule<storm::settings::modules::RegionSettings>().getRegionFilePath().c_str()), storm::exceptions::InvalidSettingsException, "The path to the file in which the regions are specified is not valid.");
STORM_LOG_THROW(storm::utility::fileExistsAndIsReadable(storm::settings::getModule<storm::settings::modules::RegionSettings>().getRegionFilePath()), storm::exceptions::InvalidSettingsException, "The path to the file in which the regions are specified is not valid.");
storm::parser::MappedFile mf(storm::settings::getModule<storm::settings::modules::RegionSettings>().getRegionFilePath().c_str());
regionsString = std::string(mf.getData(),mf.getDataSize());
}

19
src/storm/models/symbolic/Model.cpp

@ -71,6 +71,11 @@ namespace storm {
storm::dd::Bdd<Type> const& Model<Type, ValueType>::getInitialStates() const {
return initialStates;
}
template<storm::dd::DdType Type, typename ValueType>
storm::dd::Bdd<Type> const& Model<Type, ValueType>::getDeadlockStates() const {
return deadlockStates;
}
template<storm::dd::DdType Type, typename ValueType>
storm::dd::Bdd<Type> Model<Type, ValueType>::getStates(std::string const& label) const {
@ -192,12 +197,26 @@ namespace storm {
bool Model<Type, ValueType>::hasRewardModel() const {
return !this->rewardModels.empty();
}
template<storm::dd::DdType Type, typename ValueType>
std::unordered_map<std::string, typename Model<Type, ValueType>::RewardModelType> const& Model<Type, ValueType>::getRewardModels() const {
return this->rewardModels;
}
template<storm::dd::DdType Type, typename ValueType>
void Model<Type, ValueType>::printModelInformationToStream(std::ostream& out) const {
this->printModelInformationHeaderToStream(out);
this->printModelInformationFooterToStream(out);
}
template<storm::dd::DdType Type, typename ValueType>
std::vector<std::string> Model<Type, ValueType>::getLabels() const {
std::vector<std::string> labels;
for(auto const& entry : labelToExpressionMap) {
labels.push_back(entry.first);
}
return labels;
}
template<storm::dd::DdType Type, typename ValueType>
void Model<Type, ValueType>::printModelInformationHeaderToStream(std::ostream& out) const {

11
src/storm/models/symbolic/Model.h

@ -130,7 +130,12 @@ namespace storm {
* @return The initial states of the model.
*/
storm::dd::Bdd<Type> const& getInitialStates() const;
/*
* Retrieves the deadlock states of the model.
*/
storm::dd::Bdd<Type> const& getDeadlockStates() const;
/*!
* Returns the sets of states labeled with the given label.
*
@ -246,6 +251,8 @@ namespace storm {
* @return True iff the model has a reward model.
*/
bool hasRewardModel() const;
std::unordered_map<std::string, RewardModelType> const& getRewardModels() const;
/*!
* Retrieves the number of reward models associated with this model.
@ -257,6 +264,8 @@ namespace storm {
virtual void printModelInformationToStream(std::ostream& out) const override;
virtual bool isSymbolicModel() const override;
std::vector<std::string> getLabels() const;
protected:

5
src/storm/parser/AtomicPropositionLabelingParser.cpp

@ -24,11 +24,6 @@ namespace storm {
storm::models::sparse::StateLabeling AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(uint_fast64_t stateCount, std::string const & filename) {
// Open the given file.
if (!MappedFile::fileExistsAndIsReadable(filename.c_str())) {
STORM_LOG_ERROR("Error while parsing " << filename << ": The supplied Labeling input file does not exist or is not readable by this process.");
throw storm::exceptions::FileIoException() << "Error while parsing " << filename << ": The supplied Labeling input file does not exist or is not readable by this process.";
}
MappedFile file(filename.c_str());
char const* buf = file.getData();

5
src/storm/parser/DeterministicSparseTransitionParser.cpp

@ -41,11 +41,6 @@ namespace storm {
// Enforce locale where decimal point is '.'.
setlocale(LC_NUMERIC, "C");
if (!MappedFile::fileExistsAndIsReadable(filename.c_str())) {
STORM_LOG_ERROR("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 const* buf = file.getData();

9
src/storm/parser/FormulaParser.cpp

@ -15,6 +15,7 @@
#include "storm/storage/expressions/ExpressionEvaluator.h"
#include "FormulaParserGrammar.h"
#include "storm/storage/expressions/ExpressionManager.h"
#include "storm/utility/file.h"
namespace storm {
namespace parser {
@ -65,8 +66,8 @@ namespace storm {
std::vector<storm::jani::Property> FormulaParser::parseFromFile(std::string const& filename) const {
// Open file and initialize result.
std::ifstream inputFileStream(filename, std::ios::in);
STORM_LOG_THROW(inputFileStream.good(), storm::exceptions::WrongFormatException, "Unable to read from file '" << filename << "'.");
std::ifstream inputFileStream;
storm::utility::openFile(filename, inputFileStream);
std::vector<storm::jani::Property> properties;
@ -76,12 +77,12 @@ namespace storm {
properties = parseFromString(fileContent);
} catch(std::exception& e) {
// In case of an exception properly close the file before passing exception.
inputFileStream.close();
storm::utility::closeFile(inputFileStream);
throw e;
}
// Close the stream in case everything went smoothly and return result.
inputFileStream.close();
storm::utility::closeFile(inputFileStream);
return properties;
}

14
src/storm/parser/JaniParser.cpp

@ -25,6 +25,7 @@
#include <boost/lexical_cast.hpp>
#include "storm/utility/macros.h"
#include "storm/utility/file.h"
namespace storm {
namespace parser {
@ -71,18 +72,9 @@ namespace storm {
void JaniParser::readFile(std::string const &path) {
std::ifstream file;
file.exceptions ( std::ifstream::failbit );
try {
file.open(path);
}
catch (std::ifstream::failure e) {
STORM_LOG_THROW(false, storm::exceptions::FileIoException, "Exception during file opening on " << path << ".");
return;
}
file.exceptions( std::ifstream::goodbit );
storm::utility::openFile(path, file);
parsedStructure << file;
file.close();
storm::utility::closeFile(file);
}
std::pair<storm::jani::Model, std::map<std::string, storm::jani::Property>> JaniParser::parseModel(bool parseProperties) {

18
src/storm/parser/MappedFile.cpp

@ -15,10 +15,14 @@
#include "storm/exceptions/FileIoException.h"
#include "storm/utility/macros.h"
#include "storm/utility/file.h"
namespace storm {
namespace parser {
MappedFile::MappedFile(const char* filename) {
STORM_LOG_THROW(storm::utility::fileExistsAndIsReadable(filename), storm::exceptions::FileIoException, "Error while reading " << filename << ": The file does not exist or is not readable.");
#if defined LINUX || defined MACOSX
// Do file mapping for reasonable systems.
@ -29,15 +33,11 @@ namespace storm {
#else
if (stat64(filename, &(this->st)) != 0) {
#endif
STORM_LOG_ERROR("Error in stat(" << filename << "): Probably, this file does not exist.");
throw exceptions::FileIoException() << "MappedFile Error in stat(): Probably, this file does not exist.";
STORM_LOG_THROW(false, storm::exceptions::FileIoException, "Error in stat(" << filename << "): Probably, this file does not exist.");
}
this->file = open(filename, O_RDONLY);
if (this->file < 0) {
STORM_LOG_ERROR("Error in open(" << filename << "): Probably, we may not read this file.");
throw exceptions::FileIoException() << "MappedFile Error in open(): Probably, we may not read this file.";
}
STORM_LOG_THROW(this->file >= 0, storm::exceptions::FileIoException, "Error in open(" << filename << "): Probably, we may not read this file.");
this->data = static_cast<char*>(mmap(NULL, this->st.st_size, PROT_READ, MAP_PRIVATE, this->file, 0));
if (this->data == MAP_FAILED) {
@ -90,12 +90,6 @@ namespace storm {
#endif
}
bool MappedFile::fileExistsAndIsReadable(const char* filename) {
// Test by opening an input file stream and testing the stream flags.
std::ifstream fin(filename);
return fin.good();
}
char const* MappedFile::getData() const {
return data;
}

8
src/storm/parser/MappedFile.h

@ -49,14 +49,6 @@ namespace storm {
*/
~MappedFile();
/*!
* Tests whether the given file exists and is readable.
*qi
* @param filename Path and name of the file to be tested.
* @return True iff the file exists and is readable.
*/
static bool fileExistsAndIsReadable(const char* filename);
/*!
* Returns a pointer to the beginning of the mapped file data.
*

5
src/storm/parser/MarkovAutomatonSparseTransitionParser.cpp

@ -294,11 +294,6 @@ namespace storm {
// Set the locale to correctly recognize floating point numbers.
setlocale(LC_NUMERIC, "C");
if (!MappedFile::fileExistsAndIsReadable(filename.c_str())) {
STORM_LOG_ERROR("Error while parsing " << filename << ": File does not exist or is not readable.");
throw storm::exceptions::FileIoException() << "Error while parsing " << filename << ": File does not exist or is not readable.";
}
// Open file and prepare pointer to buffer.
MappedFile file(filename.c_str());
char const* buf = file.getData();

5
src/storm/parser/NondeterministicSparseTransitionParser.cpp

@ -39,11 +39,6 @@ namespace storm {
// Enforce locale where decimal point is '.'.
setlocale(LC_NUMERIC, "C");
if (!MappedFile::fileExistsAndIsReadable(filename.c_str())) {
STORM_LOG_ERROR("Error while parsing " << filename << ": File does not exist or is not readable.");
throw storm::exceptions::FileIoException() << "Error while parsing " << filename << ": File does not exist or is not readable.";
}
// Open file.
MappedFile file(filename.c_str());
char const* buf = file.getData();

10
src/storm/parser/PrismParser.cpp

@ -7,6 +7,7 @@
#include "storm/exceptions/InvalidArgumentException.h"
#include "storm/exceptions/InvalidTypeException.h"
#include "storm/utility/macros.h"
#include "storm/utility/file.h"
#include "storm/exceptions/WrongFormatException.h"
#include "storm/storage/expressions/ExpressionManager.h"
@ -17,9 +18,8 @@ namespace storm {
namespace parser {
storm::prism::Program PrismParser::parse(std::string const& filename) {
// Open file and initialize result.
std::ifstream inputFileStream(filename);
STORM_LOG_THROW(inputFileStream.good(), storm::exceptions::WrongFormatException, "Unable to read from file '" << filename << "'.");
std::ifstream inputFileStream;
storm::utility::openFile(filename, inputFileStream);
storm::prism::Program result;
// Now try to parse the contents of the file.
@ -28,12 +28,12 @@ namespace storm {
result = parseFromString(fileContent, filename);
} catch(std::exception& e) {
// In case of an exception properly close the file before passing exception.
inputFileStream.close();
storm::utility::closeFile(inputFileStream);
throw e;
}
// Close the stream in case everything went smoothly and return result.
inputFileStream.close();
storm::utility::closeFile(inputFileStream);
return result;
}

5
src/storm/parser/SparseChoiceLabelingParser.cpp

@ -13,11 +13,6 @@ namespace storm {
std::vector<storm::models::sparse::LabelSet> SparseChoiceLabelingParser::parseChoiceLabeling(std::vector<uint_fast64_t> const& nondeterministicChoiceIndices, std::string const& filename) {
// Open file.
if (!MappedFile::fileExistsAndIsReadable(filename.c_str())) {
STORM_LOG_ERROR("Error while parsing " << filename << ": File does not exist or is not readable.");
throw storm::exceptions::FileIoException() << "Error while parsing " << filename << ": File does not exist or is not readable.";
}
MappedFile file(filename.c_str());
char const* buf = file.getData();

5
src/storm/parser/SparseStateRewardParser.cpp

@ -17,11 +17,6 @@ namespace storm {
template<typename ValueType>
std::vector<ValueType> SparseStateRewardParser<ValueType>::parseSparseStateReward(uint_fast64_t stateCount, std::string const& filename) {
// Open file.
if (!MappedFile::fileExistsAndIsReadable(filename.c_str())) {
STORM_LOG_ERROR("Error while parsing " << filename << ": File does not exist or is not readable.");
throw storm::exceptions::FileIoException() << "Error while parsing " << filename << ": File does not exist or is not readable.";
}
MappedFile file(filename.c_str());
char const* buf = file.getData();

8
src/storm/settings/SettingsManager.cpp

@ -39,6 +39,7 @@
#include "storm/settings/modules/JitBuilderSettings.h"
#include "storm/settings/modules/MultiObjectiveSettings.h"
#include "storm/utility/macros.h"
#include "storm/utility/file.h"
#include "storm/settings/Option.h"
namespace storm {
@ -394,8 +395,8 @@ namespace storm {
std::map<std::string, std::vector<std::string>> SettingsManager::parseConfigFile(std::string const& filename) const {
std::map<std::string, std::vector<std::string>> result;
std::ifstream input(filename);
STORM_LOG_THROW(input.good(), storm::exceptions::OptionParserException, "Could not read from config file '" << filename << "'.");
std::ifstream input;
storm::utility::openFile(filename, input);
bool globalScope = true;
std::string activeModule = "";
@ -480,7 +481,8 @@ namespace storm {
}
}
}
storm::utility::closeFile(input);
return result;
}

13
src/storm/solver/SmtlibSmtSolver.cpp

@ -16,9 +16,10 @@
#include "storm/exceptions/InvalidStateException.h"
#include "storm/exceptions/IllegalArgumentException.h"
#include "storm/exceptions/IllegalFunctionCallException.h"
#include "utility/macros.h"
#include "adapters/CarlAdapter.h"
#include "exceptions/UnexpectedException.h"
#include "storm/utility/macros.h"
#include "storm/utility/file.h"
#include "storm/adapters/CarlAdapter.h"
#include "storm/exceptions/UnexpectedException.h"
namespace storm {
namespace solver {
@ -245,9 +246,9 @@ namespace storm {
if (storm::settings::getModule<storm::settings::modules::Smt2SmtSolverSettings>().isExportSmtLibScriptSet()){
STORM_LOG_DEBUG("The SMT-LIBv2 commands are exportet to the given file");
commandFile.open(storm::settings::getModule<storm::settings::modules::Smt2SmtSolverSettings>().getExportSmtLibScriptPath(), std::ios::trunc);
isCommandFileOpen=commandFile.is_open();
STORM_LOG_THROW(isCommandFileOpen, storm::exceptions::InvalidArgumentException, "The file where the smt2commands should be written to could not be opened");
storm::utility::openFile(storm::settings::getModule<storm::settings::modules::Smt2SmtSolverSettings>().getExportSmtLibScriptPath(), commandFile);
isCommandFileOpen = true;
// TODO also close file
}
//some initial commands

77
src/storm/storage/SparseMatrix.cpp

@ -1165,7 +1165,7 @@ namespace storm {
return result;
}
template<typename ValueType>
void SparseMatrix<ValueType>::multiplyWithVector(std::vector<ValueType> const& vector, std::vector<ValueType>& result) const {
#ifdef STORM_HAVE_INTELTBB
@ -1178,59 +1178,60 @@ namespace storm {
return multiplyWithVectorSequential(vector, result);
#endif
}
template<typename ValueType>
void SparseMatrix<ValueType>::multiplyWithVectorSequential(std::vector<ValueType> const& vector, std::vector<ValueType>& result) const {
const_iterator it = this->begin();
const_iterator ite;
std::vector<index_type>::const_iterator rowIterator = rowIndications.begin();
typename std::vector<ValueType>::iterator resultIterator = result.begin();
typename std::vector<ValueType>::iterator resultIteratorEnd = result.end();
// If the vector to multiply with and the target vector are actually the same, we need an auxiliary variable
// to store the intermediate result.
if (&vector == &result) {
for (; resultIterator != resultIteratorEnd; ++rowIterator, ++resultIterator) {
ValueType tmpValue = storm::utility::zero<ValueType>();
for (ite = this->begin() + *(rowIterator + 1); it != ite; ++it) {
tmpValue += it->getValue() * vector[it->getColumn()];
}
*resultIterator = tmpValue;
}
STORM_LOG_WARN("Matrix-vector-multiplication invoked but the target vector uses the same memory as the input vector. This requires to allocate auxiliary memory.");
std::vector<ValueType> tmpVector(this->getRowCount());
multiplyWithVectorSequential(vector, tmpVector);
result = std::move(tmpVector);
} else {
const_iterator it = this->begin();
const_iterator ite;
std::vector<index_type>::const_iterator rowIterator = rowIndications.begin();
typename std::vector<ValueType>::iterator resultIterator = result.begin();
typename std::vector<ValueType>::iterator resultIteratorEnd = result.end();
for (; resultIterator != resultIteratorEnd; ++rowIterator, ++resultIterator) {
*resultIterator = storm::utility::zero<ValueType>();
for (ite = this->begin() + *(rowIterator + 1); it != ite; ++it) {
*resultIterator += it->getValue() * vector[it->getColumn()];
}
}
}
}
#ifdef STORM_HAVE_INTELTBB
template<typename ValueType>
void SparseMatrix<ValueType>::multiplyWithVectorParallel(std::vector<ValueType> const& vector, std::vector<ValueType>& result) const {
tbb::parallel_for(tbb::blocked_range<index_type>(0, result.size(), 10),
[&] (tbb::blocked_range<index_type> const& range) {
index_type startRow = range.begin();
index_type endRow = range.end();
const_iterator it = this->begin(startRow);
const_iterator ite;
std::vector<index_type>::const_iterator rowIterator = this->rowIndications.begin() + startRow;
std::vector<index_type>::const_iterator rowIteratorEnd = this->rowIndications.begin() + endRow;
typename std::vector<ValueType>::iterator resultIterator = result.begin() + startRow;
typename std::vector<ValueType>::iterator resultIteratorEnd = result.begin() + endRow;
for (; resultIterator != resultIteratorEnd; ++rowIterator, ++resultIterator) {
*resultIterator = storm::utility::zero<ValueType>();
for (ite = this->begin() + *(rowIterator + 1); it != ite; ++it) {
*resultIterator += it->getValue() * vector[it->getColumn()];
if (&vector == &result) {
STORM_LOG_WARN("Matrix-vector-multiplication invoked but the target vector uses the same memory as the input vector. This requires to allocate auxiliary memory.");
std::vector<ValueType> tmpVector(this->getRowCount());
multiplyWithVectorParallel(vector, tmpVector);
result = std::move(tmpVector);
} else {
tbb::parallel_for(tbb::blocked_range<index_type>(0, result.size(), 10),
[&] (tbb::blocked_range<index_type> const& range) {
index_type startRow = range.begin();
index_type endRow = range.end();
const_iterator it = this->begin(startRow);
const_iterator ite;
std::vector<index_type>::const_iterator rowIterator = this->rowIndications.begin() + startRow;
std::vector<index_type>::const_iterator rowIteratorEnd = this->rowIndications.begin() + endRow;
typename std::vector<ValueType>::iterator resultIterator = result.begin() + startRow;
typename std::vector<ValueType>::iterator resultIteratorEnd = result.begin() + endRow;
for (; resultIterator != resultIteratorEnd; ++rowIterator, ++resultIterator) {
*resultIterator = storm::utility::zero<ValueType>();
for (ite = this->begin() + *(rowIterator + 1); it != ite; ++it) {
*resultIterator += it->getValue() * vector[it->getColumn()];
}
}
}
});
});
}
}
#endif

6
src/storm/storage/dd/Odd.cpp

@ -6,6 +6,7 @@
#include "storm/utility/macros.h"
#include "storm/exceptions/InvalidArgumentException.h"
#include "storm/utility/file.h"
namespace storm {
namespace dd {
@ -86,7 +87,7 @@ namespace storm {
void Odd::exportToDot(std::string const& filename) const {
std::ofstream dotFile;
dotFile.open (filename);
storm::utility::openFile(filename, dotFile);
// Print header.
dotFile << "digraph \"ODD\" {" << std::endl << "center=true;" << std::endl << "edge [dir = none];" << std::endl;
@ -129,8 +130,7 @@ namespace storm {
}
dotFile << "}" << std::endl;
dotFile.close();
storm::utility::closeFile(dotFile);
}
void Odd::addToLevelToOddNodesMap(std::map<uint_fast64_t, std::vector<std::reference_wrapper<storm::dd::Odd const>>>& levelToOddNodesMap, uint_fast64_t level) const {

8
src/storm/storage/expressions/BaseExpression.cpp

@ -5,6 +5,7 @@
#include "storm/exceptions/InvalidAccessException.h"
#include "storm/storage/expressions/Expressions.h"
#include "storm/storage/expressions/ToRationalNumberVisitor.h"
namespace storm {
namespace expressions {
@ -51,7 +52,12 @@ namespace storm {
double BaseExpression::evaluateAsDouble(Valuation const*) const {
STORM_LOG_THROW(false, storm::exceptions::InvalidTypeException, "Unable to evaluate expression as double.");
}
storm::RationalNumber BaseExpression::evaluateAsRational() const {
ToRationalNumberVisitor<storm::RationalNumber> v;
return v.toRationalNumber(this->toExpression());
}
uint_fast64_t BaseExpression::getArity() const {
return 0;
}

10
src/storm/storage/expressions/BaseExpression.h

@ -7,6 +7,7 @@
#include <map>
#include <iostream>
#include "storm/adapters/NumberAdapter.h"
#include "storm/storage/expressions/Type.h"
#include "storm/utility/OsDetection.h"
#include <boost/any.hpp>
@ -90,6 +91,15 @@ namespace storm {
*/
virtual double evaluateAsDouble(Valuation const* valuation = nullptr) const;
/*!
* Evaluates the expression and returns the resulting rational number.
* If the return type of the expression is not a rational number
* or the expression could not be evaluated, an exception is thrown.
*
* @return The rational number value of the expression.
*/
virtual storm::RationalNumber evaluateAsRational() const;
/*!
* Returns the arity of the expression.
*

14
src/storm/storage/expressions/BinaryNumericalFunctionExpression.cpp

@ -1,6 +1,7 @@
#include <algorithm>
#include <cmath>
#include "storm/adapters/NumberAdapter.h"
#include "storm/storage/expressions/BinaryNumericalFunctionExpression.h"
#include "storm/storage/expressions/IntegerLiteralExpression.h"
#include "storm/storage/expressions/RationalLiteralExpression.h"
@ -90,16 +91,21 @@ namespace storm {
}
return std::shared_ptr<BaseExpression>(new IntegerLiteralExpression(this->getManager(), newValue));
} else if (this->hasRationalType()) {
double firstOperandEvaluation = firstOperandSimplified->evaluateAsDouble();
double secondOperandEvaluation = secondOperandSimplified->evaluateAsDouble();
double newValue = 0;
storm::RationalNumber firstOperandEvaluation = firstOperandSimplified->evaluateAsRational();
storm::RationalNumber secondOperandEvaluation = secondOperandSimplified->evaluateAsRational();
storm::RationalNumber newValue = 0;
switch (this->getOperatorType()) {
case OperatorType::Plus: newValue = firstOperandEvaluation + secondOperandEvaluation; break;
case OperatorType::Minus: newValue = firstOperandEvaluation - secondOperandEvaluation; break;
case OperatorType::Times: newValue = firstOperandEvaluation * secondOperandEvaluation; break;
case OperatorType::Min: newValue = std::min(firstOperandEvaluation, secondOperandEvaluation); break;
case OperatorType::Max: newValue = std::max(firstOperandEvaluation, secondOperandEvaluation); break;
case OperatorType::Power: newValue = static_cast<int_fast64_t>(std::pow(firstOperandEvaluation, secondOperandEvaluation)); break;
case OperatorType::Power: {
STORM_LOG_THROW(carl::isInteger(secondOperandEvaluation), storm::exceptions::InvalidStateException, "Can not simplify pow() with fractional exponent.");
std::size_t exponent = carl::toInt<carl::uint>(secondOperandEvaluation);
newValue = carl::pow(firstOperandEvaluation, exponent);
break;
}
case OperatorType::Divide: STORM_LOG_THROW(false, storm::exceptions::InvalidStateException, "Unable to simplify division."); break;
}
return std::shared_ptr<BaseExpression>(new RationalLiteralExpression(this->getManager(), newValue));

29
src/storm/storage/expressions/BinaryRelationExpression.cpp

@ -4,6 +4,7 @@
#include "storm/storage/expressions/BooleanLiteralExpression.h"
#include "storm/utility/macros.h"
#include "storm/utility/constants.h"
#include "storm/exceptions/InvalidTypeException.h"
#include "storm/storage/expressions/ExpressionVisitor.h"
@ -48,28 +49,28 @@ namespace storm {
std::shared_ptr<BaseExpression const> secondOperandSimplified = this->getSecondOperand()->simplify();
if (firstOperandSimplified->isLiteral() && secondOperandSimplified->isLiteral()) {
boost::variant<int_fast64_t, double> firstOperandEvaluation;
boost::variant<int_fast64_t, double> secondOperandEvaluation;
storm::RationalNumber firstOperandEvaluation;
storm::RationalNumber secondOperandEvaluation;
if (firstOperandSimplified->hasIntegerType()) {
firstOperandEvaluation = firstOperandSimplified->evaluateAsInt();
firstOperandEvaluation = storm::utility::convertNumber<storm::RationalNumber>(firstOperandSimplified->evaluateAsInt());
} else {
firstOperandEvaluation = firstOperandSimplified->evaluateAsDouble();
firstOperandEvaluation = firstOperandSimplified->evaluateAsRational();
}
if (secondOperandSimplified->hasIntegerType()) {
secondOperandEvaluation = secondOperandSimplified->evaluateAsInt();
secondOperandEvaluation = storm::utility::convertNumber<storm::RationalNumber>(secondOperandSimplified->evaluateAsInt());
} else {
secondOperandEvaluation = secondOperandSimplified->evaluateAsDouble();
secondOperandEvaluation = secondOperandSimplified->evaluateAsRational();
}
bool truthValue = false;
switch (this->getRelationType()) {
case RelationType::Equal: truthValue = (firstOperandSimplified->hasIntegerType() ? boost::get<int_fast64_t>(firstOperandEvaluation) : boost::get<double>(firstOperandEvaluation)) == (secondOperandSimplified->hasIntegerType() ? boost::get<int_fast64_t>(secondOperandEvaluation) : boost::get<double>(secondOperandEvaluation)); break;
case RelationType::NotEqual: truthValue = (firstOperandSimplified->hasIntegerType() ? boost::get<int_fast64_t>(firstOperandEvaluation) : boost::get<double>(firstOperandEvaluation)) != (secondOperandSimplified->hasIntegerType() ? boost::get<int_fast64_t>(secondOperandEvaluation) : boost::get<double>(secondOperandEvaluation)); break;
case RelationType::Greater: truthValue = (firstOperandSimplified->hasIntegerType() ? boost::get<int_fast64_t>(firstOperandEvaluation) : boost::get<double>(firstOperandEvaluation)) > (secondOperandSimplified->hasIntegerType() ? boost::get<int_fast64_t>(secondOperandEvaluation) : boost::get<double>(secondOperandEvaluation)); break;
case RelationType::GreaterOrEqual: truthValue = (firstOperandSimplified->hasIntegerType() ? boost::get<int_fast64_t>(firstOperandEvaluation) : boost::get<double>(firstOperandEvaluation)) >= (secondOperandSimplified->hasIntegerType() ? boost::get<int_fast64_t>(secondOperandEvaluation) : boost::get<double>(secondOperandEvaluation)); break;
case RelationType::Less: truthValue = (firstOperandSimplified->hasIntegerType() ? boost::get<int_fast64_t>(firstOperandEvaluation) : boost::get<double>(firstOperandEvaluation)) < (secondOperandSimplified->hasIntegerType() ? boost::get<int_fast64_t>(secondOperandEvaluation) : boost::get<double>(secondOperandEvaluation)); break;
case RelationType::LessOrEqual: truthValue = (firstOperandSimplified->hasIntegerType() ? boost::get<int_fast64_t>(firstOperandEvaluation) : boost::get<double>(firstOperandEvaluation)) <= (secondOperandSimplified->hasIntegerType() ? boost::get<int_fast64_t>(secondOperandEvaluation) : boost::get<double>(secondOperandEvaluation)); break;
case RelationType::Equal: truthValue = firstOperandEvaluation == secondOperandEvaluation; break;
case RelationType::NotEqual: truthValue = firstOperandEvaluation != secondOperandEvaluation; break;
case RelationType::Greater: truthValue = firstOperandEvaluation > secondOperandEvaluation; break;
case RelationType::GreaterOrEqual: truthValue = firstOperandEvaluation >= secondOperandEvaluation; break;
case RelationType::Less: truthValue = firstOperandEvaluation < secondOperandEvaluation; break;
case RelationType::LessOrEqual: truthValue = firstOperandEvaluation <= secondOperandEvaluation; break;
}
return std::shared_ptr<BaseExpression>(new BooleanLiteralExpression(this->getManager(), truthValue));
}

13
src/storm/storage/expressions/ToRationalNumberVisitor.cpp

@ -7,6 +7,11 @@
namespace storm {
namespace expressions {
template<typename RationalNumberType>
ToRationalNumberVisitor<RationalNumberType>::ToRationalNumberVisitor() : ExpressionVisitor() {
// Intentionally left empty.
}
template<typename RationalNumberType>
ToRationalNumberVisitor<RationalNumberType>::ToRationalNumberVisitor(ExpressionEvaluatorBase<RationalNumberType> const& evaluator) : ExpressionVisitor(), evaluator(evaluator) {
// Intentionally left empty.
@ -19,7 +24,13 @@ namespace storm {
template<typename RationalNumberType>
boost::any ToRationalNumberVisitor<RationalNumberType>::visit(IfThenElseExpression const& expression, boost::any const& data) {
bool conditionValue = evaluator.asBool(expression.getCondition());
bool conditionValue;
if (evaluator) {
conditionValue = evaluator->asBool(expression.getCondition());
} else {
// no evaluator, fall back to evaluateBool
conditionValue = expression.getCondition()->evaluateAsBool();
}
if (conditionValue) {
return expression.getThenExpression()->accept(*this, data);
} else {

9
src/storm/storage/expressions/ToRationalNumberVisitor.h

@ -2,6 +2,8 @@
#include <unordered_map>
#include <boost/optional.hpp>
#include "storm/adapters/CarlAdapter.h"
#include "storm/storage/expressions/Expression.h"
@ -16,7 +18,8 @@ namespace storm {
template<typename RationalNumberType>
class ToRationalNumberVisitor : public ExpressionVisitor {
public:
ToRationalNumberVisitor(ExpressionEvaluatorBase<RationalNumberType> const& evaluator);
ToRationalNumberVisitor();
ToRationalNumberVisitor(ExpressionEvaluatorBase<RationalNumberType> const& evaluator);
RationalNumberType toRationalNumber(Expression const& expression);
@ -36,8 +39,8 @@ namespace storm {
private:
std::unordered_map<storm::expressions::Variable, RationalNumberType> valueMapping;
// A reference to an expression evaluator (mainly for resolving the boolean condition in IfThenElse expressions)
ExpressionEvaluatorBase<RationalNumberType> const& evaluator;
// An optional reference to an expression evaluator (mainly for resolving the boolean condition in IfThenElse expressions)
boost::optional<ExpressionEvaluatorBase<RationalNumberType> const&> evaluator;
};
}
}

15
src/storm/storage/expressions/UnaryNumericalFunctionExpression.cpp

@ -2,11 +2,13 @@
#include <boost/variant.hpp>
#include "storm/adapters/NumberAdapter.h"
#include "storm/storage/expressions/UnaryNumericalFunctionExpression.h"
#include "storm/storage/expressions/IntegerLiteralExpression.h"
#include "storm/storage/expressions/RationalLiteralExpression.h"
#include "ExpressionVisitor.h"
#include "storm/utility/macros.h"
#include "storm/utility/constants.h"
#include "storm/exceptions/InvalidTypeException.h"
#include "storm/exceptions/InvalidOperationException.h"
@ -65,14 +67,13 @@ namespace storm {
std::shared_ptr<BaseExpression const> operandSimplified = this->getOperand()->simplify();
if (operandSimplified->isLiteral()) {
boost::variant<int_fast64_t, double> operandEvaluation;
boost::variant<int_fast64_t, storm::RationalNumber> operandEvaluation;
if (operandSimplified->hasIntegerType()) {
operandEvaluation = operandSimplified->evaluateAsInt();
} else {
operandEvaluation = operandSimplified->evaluateAsDouble();
operandEvaluation = operandSimplified->evaluateAsRational();
}
boost::variant<int_fast64_t, double> result;
if (operandSimplified->hasIntegerType()) {
int_fast64_t value = 0;
switch (this->getOperatorType()) {
@ -82,11 +83,11 @@ namespace storm {
}
return std::shared_ptr<BaseExpression>(new IntegerLiteralExpression(this->getManager(), value));
} else {
double value = 0;
storm::RationalNumber value = storm::utility::zero<storm::RationalNumber>();
switch (this->getOperatorType()) {
case OperatorType::Minus: value = -boost::get<double>(operandEvaluation); break;
case OperatorType::Floor: value = std::floor(boost::get<double>(operandEvaluation)); break;
case OperatorType::Ceil: value = std::ceil(boost::get<double>(operandEvaluation)); break;
case OperatorType::Minus: value = -boost::get<storm::RationalNumber>(operandEvaluation); break;
case OperatorType::Floor: value = carl::floor(boost::get<storm::RationalNumber>(operandEvaluation)); break;
case OperatorType::Ceil: value = carl::ceil(boost::get<storm::RationalNumber>(operandEvaluation)); break;
}
return std::shared_ptr<BaseExpression>(new RationalLiteralExpression(this->getManager(), value));
}

18
src/storm/storage/jani/JSONExporter.cpp

@ -5,6 +5,7 @@
#include <vector>
#include "storm/utility/macros.h"
#include "storm/utility/file.h"
#include "storm/exceptions/FileIoException.h"
#include "storm/exceptions/NotSupportedException.h"
@ -525,20 +526,11 @@ namespace storm {
return modernjson::json(expression.getValueAsDouble());
}
void JsonExporter::toFile(storm::jani::Model const& janiModel, std::vector<storm::jani::Property> const& formulas, std::string const& filepath, bool checkValid) {
std::ofstream ofs;
ofs.open (filepath, std::ofstream::out );
if(ofs.is_open()) {
toStream(janiModel, formulas, ofs, checkValid);
} else {
STORM_LOG_THROW(false, storm::exceptions::FileIoException, "Cannot open " << filepath);
}
std::ofstream stream;
storm::utility::openFile(filepath, stream);
toStream(janiModel, formulas, stream, checkValid);
storm::utility::closeFile(stream);
}
void JsonExporter::toStream(storm::jani::Model const& janiModel, std::vector<storm::jani::Property> const& formulas, std::ostream& os, bool checkValid) {

2
src/storm/storage/jani/Model.cpp

@ -1150,7 +1150,7 @@ namespace storm {
}
bool Model::reusesActionsInComposition() const {
if(composition->isParallelComposition()) {
if (composition->isParallelComposition()) {
return composition->asParallelComposition().areActionsReused();
}
return false;

6
src/storm/storage/jani/ParallelComposition.cpp

@ -195,13 +195,15 @@ namespace storm {
for (auto const& vector : synchronizationVectors) {
std::string const& action = vector.getInput(inputIndex);
if (action != SynchronizationVector::NO_ACTION_INPUT) {
return true;
if (actions.find(action) != actions.end()) {
return true;
}
actions.insert(action);
}
}
// And check recursively, in case we have nested parallel composition
if (subcompositions.at(inputIndex)->isParallelComposition()) {
if(subcompositions.at(inputIndex)->asParallelComposition().areActionsReused()) {
if (subcompositions.at(inputIndex)->asParallelComposition().areActionsReused()) {
return true;
}
}

50
src/storm/transformer/SymbolicToSparseTransformer.cpp

@ -0,0 +1,50 @@
#include "SymbolicToSparseTransformer.h"
#include "storm/storage/dd/DdManager.h"
#include "storm/storage/dd/Add.h"
#include "storm/storage/dd/Bdd.h"
#include "storm/models/symbolic/StandardRewardModel.h"
#include "storm/models/sparse/StandardRewardModel.h"
namespace storm {
namespace transformer {
template<storm::dd::DdType Type, typename ValueType>
std::shared_ptr<storm::models::sparse::Mdp<ValueType>> SymbolicMdpToSparseMdpTransformer<Type, ValueType>::translate(
storm::models::symbolic::Mdp<Type, ValueType> const& symbolicMdp) {
storm::dd::Odd odd = symbolicMdp.getReachableStates().createOdd();
storm::storage::SparseMatrix<ValueType> transitionMatrix = symbolicMdp.getTransitionMatrix().toMatrix(symbolicMdp.getNondeterminismVariables(), odd, odd);
std::unordered_map<std::string, storm::models::sparse::StandardRewardModel<ValueType>> rewardModels;
for (auto const& rewardModelNameAndModel : symbolicMdp.getRewardModels()) {
boost::optional<std::vector<ValueType>> stateRewards;
boost::optional<std::vector<ValueType>> stateActionRewards;
boost::optional<storm::storage::SparseMatrix<ValueType>> transitionRewards;
if (rewardModelNameAndModel.second.hasStateRewards()) {
stateRewards = rewardModelNameAndModel.second.getStateRewardVector().toVector(odd);
}
if (rewardModelNameAndModel.second.hasStateActionRewards()) {
stateActionRewards = rewardModelNameAndModel.second.getStateActionRewardVector().toVector(odd);
}
if (rewardModelNameAndModel.second.hasTransitionRewards()) {
transitionRewards = rewardModelNameAndModel.second.getTransitionRewardMatrix().toMatrix(symbolicMdp.getNondeterminismVariables(), odd, odd);
}
rewardModels.emplace(rewardModelNameAndModel.first,storm::models::sparse::StandardRewardModel<ValueType>(stateRewards, stateActionRewards, transitionRewards));
}
storm::models::sparse::StateLabeling labelling;
labelling.addLabel("initial", symbolicMdp.getInitialStates().toVector(odd));
labelling.addLabel("deadlock", symbolicMdp.getDeadlockStates().toVector(odd));
for(auto const& label : symbolicMdp.getLabels()) {
labelling.addLabel(label, symbolicMdp.getStates(label).toVector(odd));
}
return std::make_shared<storm::models::sparse::Mdp<ValueType>>(transitionMatrix, labelling, rewardModels);
}
template class SymbolicMdpToSparseMdpTransformer<storm::dd::DdType::CUDD, double>;
template class SymbolicMdpToSparseMdpTransformer<storm::dd::DdType::Sylvan, double>;
}
}

15
src/storm/transformer/SymbolicToSparseTransformer.h

@ -0,0 +1,15 @@
#pragma once
#include "storm/models/sparse/Mdp.h"
#include "storm/models/symbolic/Mdp.h"
namespace storm {
namespace transformer {
template<storm::dd::DdType Type, typename ValueType>
class SymbolicMdpToSparseMdpTransformer {
public:
static std::shared_ptr<storm::models::sparse::Mdp<ValueType>> translate(storm::models::symbolic::Mdp<Type, ValueType> const& symbolicMdp);
};
}
}

9
src/storm/utility/cli.cpp

@ -1,6 +1,7 @@
#include "storm/utility/cli.h"
#include "storm/utility/macros.h"
#include "storm/utility/constants.h"
#include "storm/exceptions/WrongFormatException.h"
namespace storm {
@ -52,8 +53,12 @@ namespace storm {
int_fast64_t integerValue = std::stoi(value);
constantDefinitions[variable] = manager.integer(integerValue);
} else if (variable.hasRationalType()) {
double doubleValue = std::stod(value);
constantDefinitions[variable] = manager.rational(doubleValue);
try {
storm::RationalNumber rationalValue = storm::utility::convertNumber<storm::RationalNumber>(value);
constantDefinitions[variable] = manager.rational(rationalValue);
} catch (std::exception& e) {
STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "Illegal constant definition string '" << constantName << "=" << value << "': " << e.what());
}
}
} else {
STORM_LOG_THROW(false, storm::exceptions::WrongFormatException, "Illegal constant definition string: unknown undefined constant '" << constantName << "'.");

4
src/storm/utility/constants.cpp

@ -397,12 +397,12 @@ namespace storm {
template<>
RationalFunction convertNumber(int_fast64_t const& number){
STORM_LOG_ASSERT(static_cast<carl::sint>(number) == number, "Rationalizing failed, because the number is too large.");
return RationalFunction(carl::rationalize<RationalNumber>(static_cast<carl::uint>(number)));
return RationalFunction(carl::rationalize<RationalNumber>(static_cast<carl::sint>(number)));
}
template<>
RationalNumber convertNumber(std::string const& number) {
return carl::rationalize<RationalNumber>(number);
return carl::parse<RationalNumber>(number);
}
template<>

15
src/storm/utility/export.h

@ -12,7 +12,7 @@
#include <boost/optional.hpp>
#include "storm/utility/macros.h"
#include "storm/exceptions/FileIoException.h"
#include "storm/utility/file.h"
//#include "storm/storage/parameters.h"
//#include "storm/settings/modules/ParametricSettings.h"
@ -40,19 +40,11 @@ namespace storm {
filestream.close();
}
*/
inline void exportStringToFile(std::string const& str, std::string filepath) {
std::ofstream filestream;
filestream.open(filepath);
STORM_LOG_THROW(filestream.is_open(), storm::exceptions::FileIoException , "Could not open file " << filepath << ".");
filestream << str;
}
template <typename ValueType>
inline void exportDataToCSVFile(std::string filepath, std::vector<std::vector<ValueType>> const& data, boost::optional<std::vector<std::string>> const& columnHeaders) {
std::ofstream filestream;
filestream.open(filepath);
STORM_LOG_THROW(filestream.is_open(), storm::exceptions::FileIoException , "Could not open file " << filepath << ".");
storm::utility::openFile(filepath, filestream);
if(columnHeaders) {
for(auto columnIt = columnHeaders->begin(); columnIt != columnHeaders->end(); ++columnIt) {
@ -73,10 +65,9 @@ namespace storm {
}
filestream << std::endl;
}
storm::utility::closeFile(filestream);
}
}
}
#endif

81
src/storm/utility/file.h

@ -0,0 +1,81 @@
/**
* @file: file.h
* @author: Sebastian Junges
*
* @since October 7, 2014
*/
#ifndef STORM_UTILITY_FILE_H_
#define STORM_UTILITY_FILE_H_
#include <iostream>
#include "storm/utility/macros.h"
#include "storm/exceptions/FileIoException.h"
namespace storm {
namespace utility {
/*!
* Open the given file for writing.
*
* @param filename Path and name of the file to be tested.
* @param filestream Contains the file handler afterwards.
* @param append If true, the new content is appended instead of clearing the existing content.
*/
inline void openFile(std::string const& filepath, std::ofstream& filestream, bool append = false) {
if (append) {
filestream.open(filepath, std::ios::app);
} else {
filestream.open(filepath);
}
STORM_LOG_THROW(filestream, storm::exceptions::FileIoException , "Could not open file " << filepath << ".");
STORM_PRINT_AND_LOG("Write to file " << filepath << "." << std::endl);
}
/*!
* Open the given file for reading.
*
* @param filename Path and name of the file to be tested.
* @param filestream Contains the file handler afterwards.
*/
inline void openFile(std::string const& filepath, std::ifstream& filestream) {
filestream.open(filepath);
STORM_LOG_THROW(filestream, storm::exceptions::FileIoException , "Could not open file " << filepath << ".");
}
/*!
* Close the given file after writing.
*
* @param filestream Contains the file handler to close.
*/
inline void closeFile(std::ofstream& stream) {
stream.close();
}
/*!
* Close the given file after reading.
*
* @param filestream Contains the file handler to close.
*/
inline void closeFile(std::ifstream& stream) {
stream.close();
}
/*!
* Tests whether the given file exists and is readable.
*
* @param filename Path and name of the file to be tested.
* @return True iff the file exists and is readable.
*/
inline bool fileExistsAndIsReadable(std::string const& filename) {
// Test by opening an input file stream and testing the stream flags.
std::ifstream filestream;
filestream.open(filename);
return filestream.good();
}
}
}
#endif

13
src/storm/utility/storm.h

@ -97,6 +97,7 @@
#include "storm/exceptions/NotSupportedException.h"
#include "storm/utility/Stopwatch.h"
#include "storm/utility/file.h"
namespace storm {
@ -434,7 +435,7 @@ namespace storm {
inline void exportParametricResultToFile(storm::RationalFunction const& result, storm::models::sparse::Dtmc<storm::RationalFunction>::ConstraintCollector const& constraintCollector, std::string const& path) {
std::ofstream filestream;
filestream.open(path);
storm::utility::openFile(path, filestream);
// TODO: add checks.
filestream << "!Parameters: ";
std::set<storm::RationalFunctionVariable> vars = result.gatherVariables();
@ -445,7 +446,7 @@ namespace storm {
std::copy(constraintCollector.getWellformedConstraints().begin(), constraintCollector.getWellformedConstraints().end(), std::ostream_iterator<storm::ArithConstraint<storm::RationalFunction>>(filestream, "\n"));
filestream << "!Graph-preserving Constraints: " << std::endl;
std::copy(constraintCollector.getGraphPreservingConstraints().begin(), constraintCollector.getGraphPreservingConstraints().end(), std::ostream_iterator<storm::ArithConstraint<storm::RationalFunction>>(filestream, "\n"));
filestream.close();
storm::utility::closeFile(filestream);
}
template<>
@ -623,10 +624,10 @@ namespace storm {
template<typename ValueType>
void exportMatrixToFile(std::shared_ptr<storm::models::sparse::Model<ValueType>> model, std::string const& filepath) {
STORM_LOG_THROW(model->getType() != storm::models::ModelType::Ctmc, storm::exceptions::NotImplementedException, "This functionality is not yet implemented." );
std::ofstream ofs;
ofs.open (filepath, std::ofstream::out);
model->getTransitionMatrix().printAsMatlabMatrix(ofs);
ofs.close();
std::ofstream stream;
storm::utility::openFile(filepath, stream);
model->getTransitionMatrix().printAsMatlabMatrix(stream);
storm::utility::closeFile(stream);
}
}

10
src/test/builder/DdJaniModelBuilderTest.cpp

@ -17,6 +17,8 @@
#include "storm/settings/SettingsManager.h"
#include "storm/settings/modules/IOSettings.h"
#include "storm/exceptions/InvalidSettingsException.h"
TEST(DdJaniModelBuilderTest_Sylvan, Dtmc) {
storm::storage::SymbolicModelDescription modelDescription = storm::parser::PrismParser::parse(STORM_TEST_RESOURCES_DIR "/dtmc/die.pm");
storm::jani::Model janiModel = modelDescription.toJani(true).preprocess().asJaniModel();
@ -363,7 +365,9 @@ TEST(DdJaniModelBuilderTest_Cudd, SynchronizationVectors) {
inputVector.push_back("c");
inputVector.push_back("b");
synchronizationVectors.push_back(storm::jani::SynchronizationVector(inputVector, "e"));
EXPECT_THROW(newComposition = std::make_shared<storm::jani::ParallelComposition>(automataCompositions, synchronizationVectors), storm::exceptions::WrongFormatException);
newComposition = std::make_shared<storm::jani::ParallelComposition>(automataCompositions, synchronizationVectors);
janiModel.setSystemComposition(newComposition);
EXPECT_THROW(model = builder.build(janiModel), storm::exceptions::InvalidSettingsException);
}
TEST(DdJaniModelBuilderTest_Sylvan, SynchronizationVectors) {
@ -419,7 +423,9 @@ TEST(DdJaniModelBuilderTest_Sylvan, SynchronizationVectors) {
inputVector.push_back("c");
inputVector.push_back("b");
synchronizationVectors.push_back(storm::jani::SynchronizationVector(inputVector, "e"));
EXPECT_THROW(newComposition = std::make_shared<storm::jani::ParallelComposition>(automataCompositions, synchronizationVectors), storm::exceptions::WrongFormatException);
newComposition = std::make_shared<storm::jani::ParallelComposition>(automataCompositions, synchronizationVectors);
janiModel.setSystemComposition(newComposition);
EXPECT_THROW(model = builder.build(janiModel), storm::exceptions::InvalidSettingsException);
}
TEST(DdJaniModelBuilderTest_Sylvan, Composition) {

7
src/test/parser/MappedFileTest.cpp

@ -11,6 +11,7 @@
#include <string>
#include "storm/parser/MappedFile.h"
#include "storm/utility/cstring.h"
#include "storm/utility/file.h"
#include "storm/exceptions/FileIoException.h"
TEST(MappedFileTest, NonExistingFile) {
@ -41,12 +42,12 @@ TEST(MappedFileTest, ExistsAndReadble) {
// Test the fileExistsAndIsReadable() method under various circumstances.
// File exists and is readable.
ASSERT_TRUE(storm::parser::MappedFile::fileExistsAndIsReadable(STORM_TEST_RESOURCES_DIR "/txt/testStringFile.txt"));
ASSERT_TRUE(storm::utility::fileExistsAndIsReadable(STORM_TEST_RESOURCES_DIR "/txt/testStringFile.txt"));
// File does not exist.
ASSERT_FALSE(storm::parser::MappedFile::fileExistsAndIsReadable(STORM_TEST_RESOURCES_DIR "/nonExistingFile.not"));
ASSERT_FALSE(storm::utility::fileExistsAndIsReadable(STORM_TEST_RESOURCES_DIR "/nonExistingFile.not"));
// File exists but is not readable.
// TODO: Find portable solution to providing a situation in which a file exists but is not readable.
//ASSERT_FALSE(storm::parser::MappedFile::fileExistsAndIsReadable(STORM_TEST_RESOURCES_DIR "/parser/unreadableFile.txt"));
//ASSERT_FALSE(storm::utility::fileExistsAndIsReadable(STORM_TEST_RESOURCES_DIR "/parser/unreadableFile.txt"));
}
Loading…
Cancel
Save