Browse Source

Merge branch 'master' into deterministicScheds

main
Tim Quatmann 6 years ago
parent
commit
92dd97b06a
  1. 1
      CHANGELOG.md
  2. 2
      resources/3rdparty/CMakeLists.txt
  3. 2
      resources/3rdparty/sylvan/src/sylvan_obj_bdd_storm.hpp
  4. 1
      resources/3rdparty/sylvan/src/sylvan_obj_mtbdd_storm.hpp
  5. 16
      resources/3rdparty/sylvan/src/sylvan_obj_storm.cpp
  6. 10
      src/storm-cli-utilities/model-handling.h
  7. 27
      src/storm-parsers/parser/DirectEncodingParser.cpp
  8. 2
      src/storm-parsers/parser/ValueParser.cpp
  9. 4
      src/storm-pomdp-cli/storm-pomdp.cpp
  10. 12
      src/storm/api/export.h
  11. 24
      src/storm/models/sparse/StandardRewardModel.cpp
  12. 10
      src/storm/models/sparse/StandardRewardModel.h
  13. 17
      src/storm/models/symbolic/Model.cpp
  14. 2
      src/storm/models/symbolic/Model.h
  15. 11
      src/storm/settings/modules/IOSettings.cpp
  16. 21
      src/storm/settings/modules/IOSettings.h
  17. 48
      src/storm/storage/SparseMatrix.cpp
  18. 5
      src/storm/storage/SparseMatrix.h
  19. 5
      src/storm/storage/dd/Add.cpp
  20. 2
      src/storm/storage/dd/Add.h
  21. 5
      src/storm/storage/dd/Bdd.cpp
  22. 2
      src/storm/storage/dd/Bdd.h
  23. 7
      src/storm/storage/dd/Dd.h
  24. 5
      src/storm/storage/dd/Odd.cpp
  25. 7
      src/storm/storage/dd/Odd.h
  26. 267
      src/storm/storage/dd/cudd/InternalCuddAdd.cpp
  27. 8
      src/storm/storage/dd/cudd/InternalCuddAdd.h
  28. 5
      src/storm/storage/dd/cudd/InternalCuddBdd.cpp
  29. 9
      src/storm/storage/dd/cudd/InternalCuddBdd.h
  30. 10
      src/storm/storage/dd/sylvan/InternalSylvanAdd.cpp
  31. 9
      src/storm/storage/dd/sylvan/InternalSylvanAdd.h
  32. 8
      src/storm/storage/dd/sylvan/InternalSylvanBdd.cpp
  33. 9
      src/storm/storage/dd/sylvan/InternalSylvanBdd.h
  34. 4
      src/storm/storage/sparse/ChoiceOrigins.cpp
  35. 7
      src/storm/storage/sparse/ChoiceOrigins.h
  36. 95
      src/storm/transformer/SubsystemBuilder.cpp
  37. 9
      src/storm/transformer/SubsystemBuilder.h
  38. 35
      src/storm/utility/DDEncodingExporter.cpp
  39. 20
      src/storm/utility/DDEncodingExporter.h
  40. 11
      src/storm/utility/DirectEncodingExporter.cpp
  41. 12
      src/storm/utility/graph.cpp
  42. 1
      src/storm/utility/graph.h

1
CHANGELOG.md

@ -21,6 +21,7 @@ Version 1.3.x
- Fixed sparse bisimulation of MDPs (which failed if all non-absorbing states in the quotient are initial)
- Fixed linking with Mathsat on macOS
- Fixed compilation for macOS mojave
- Support for export of MTBDDs from storm
### Version 1.3.0 (2018/12)
- Slightly improved scheduler extraction

2
resources/3rdparty/CMakeLists.txt

@ -478,7 +478,9 @@ ExternalProject_Add(
LOG_BUILD ON
DEPENDS ${sylvan_dep}
BUILD_BYPRODUCTS ${STORM_3RDPARTY_BINARY_DIR}/sylvan/src/libsylvan${STATIC_EXT}
BUILD_ALWAYS 1
)
# BUILD ALWAYS ON due to: https://stackoverflow.com/questions/46708124/cmake-doesnt-rebuild-externalproject-on-changes
ExternalProject_Get_Property(sylvan source_dir)
ExternalProject_Get_Property(sylvan binary_dir)

2
resources/3rdparty/sylvan/src/sylvan_obj_bdd_storm.hpp

@ -2,6 +2,8 @@
Mtbdd toDoubleMtbdd() const;
Mtbdd toInt64Mtbdd() const;
Mtbdd toStormRationalNumberMtbdd() const;
void PrintText(FILE *out) const;
#if defined(SYLVAN_HAVE_CARL) || defined(STORM_HAVE_CARL)
Mtbdd toStormRationalFunctionMtbdd() const;
#endif

1
resources/3rdparty/sylvan/src/sylvan_obj_mtbdd_storm.hpp

@ -7,6 +7,7 @@ double NonZeroCount(size_t variableCount) const;
bool isValid() const;
void PrintDot(FILE *out) const;
std::string GetShaHash() const;
void PrintText(FILE *out) const;
Mtbdd Minus(const Mtbdd &other) const;
Mtbdd Divide(const Mtbdd &other) const;

16
resources/3rdparty/sylvan/src/sylvan_obj_storm.cpp

@ -1,4 +1,5 @@
#include "storm_wrapper.h"
#include "sylvan_bdd.h"
#include "sylvan_mtbdd_storm.h"
#include "sylvan_storm_rational_number.h"
#include "sylvan_storm_rational_function.h"
@ -20,6 +21,14 @@ Sylvan::initCustomMtbdd()
Functions added to sylvan's Bdd class.
*********************************************/
void
Bdd::PrintText(FILE *out) const {
sylvan_serialize_reset();
size_t v = sylvan_serialize_add(bdd);
fprintf(out, "bdd%s,", bdd&sylvan_complement?"-":"+");
sylvan_serialize_totext(out);
}
Mtbdd
Bdd::toDoubleMtbdd() const {
LACE_ME;
@ -92,6 +101,13 @@ Mtbdd::PrintDot(FILE *out) const {
mtbdd_fprintdot(out, mtbdd);
}
void
Mtbdd::PrintText(FILE *out) const {
LACE_ME;
MTBDD dds[1] = { mtbdd };
mtbdd_writer_totext(out, dds, 1);
}
std::string
Mtbdd::GetShaHash() const {
char buf[65];

10
src/storm-cli-utilities/model-handling.h

@ -386,7 +386,15 @@ namespace storm {
template <storm::dd::DdType DdType, typename ValueType>
void exportDdModel(std::shared_ptr<storm::models::symbolic::Model<DdType, ValueType>> const& model, SymbolicInput const& input) {
// Intentionally left empty.
auto ioSettings = storm::settings::getModule<storm::settings::modules::IOSettings>();
if (ioSettings.isExportDdSet()) {
storm::api::exportSparseModelAsDrdd(model, ioSettings.getExportDdFilename());
}
if (ioSettings.isExportDotSet()) {
storm::api::exportSymbolicModelAsDot(model, ioSettings.getExportDotFilename());
}
}
template <storm::dd::DdType DdType, typename ValueType>

27
src/storm-parsers/parser/DirectEncodingParser.cpp

@ -2,6 +2,8 @@
#include <iostream>
#include <string>
#include <regex>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/predicate.hpp>
@ -215,7 +217,29 @@ namespace storm {
// Parse labels
if (!line.empty()) {
std::vector<std::string> labels;
boost::split(labels, line, boost::is_any_of(" "));
// Labels are separated by whitespace and can optionally be enclosed in quotation marks
// Regex for labels with two cases:
// * Enclosed in quotation marks: \"([^\"]+?)\"(?=(\s|$|\"))
// - First part matches string enclosed in quotation marks with no quotation mark inbetween (\"([^\"]+?)\")
// - second part is lookahead which ensures that after the matched part either whitespace, end of line or a new quotation mark follows (?=(\s|$|\"))
// * Separated by whitespace: [^\s\"]+?(?=(\s|$))
// - First part matches string without whitespace and quotation marks [^\s\"]+?
// - Second part is again lookahead matching whitespace or end of line (?=(\s|$))
std::regex labelRegex(R"(\"([^\"]+?)\"(?=(\s|$|\"))|([^\s\"]+?(?=(\s|$))))");
// Iterate over matches
auto match_begin = std::sregex_iterator(line.begin(), line.end(), labelRegex);
auto match_end = std::sregex_iterator();
for (std::sregex_iterator i = match_begin; i != match_end; ++i) {
std::smatch match = *i;
// Find matched group and add as label
if (match.length(1) > 0) {
labels.push_back(match.str(1));
} else {
labels.push_back(match.str(3));
}
}
for (std::string label : labels) {
if (!modelComponents->stateLabeling.containsLabel(label)) {
modelComponents->stateLabeling.addLabel(label);
@ -255,6 +279,7 @@ namespace storm {
std::string valueStr = line.substr(posColon+2);
ValueType value = valueParser.parseValue(valueStr);
STORM_LOG_TRACE("Transition " << row << " -> " << target << ": " << value);
STORM_LOG_THROW(target < stateSize, storm::exceptions::WrongFormatException, "Target state " << target << " is greater than state size " << stateSize);
builder.addNextValue(row, target, value);
}
}

2
src/storm-parsers/parser/ValueParser.cpp

@ -7,7 +7,7 @@ namespace storm {
template<typename ValueType>
void ValueParser<ValueType>::addParameter(std::string const& parameter) {
STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Parameters are not supported in this build.");
STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Parameters are not supported in this build (Have you checked storm-pars?).");
}
template<>

4
src/storm-pomdp-cli/storm-pomdp.cpp

@ -204,8 +204,12 @@ int main(const int argc, const char** argv) {
STORM_PRINT_AND_LOG(" done." << std::endl);
}
} else {
STORM_LOG_WARN("Nothing to be done. Did you forget to specify a formula?");
}
// All operations have now been performed, so we clean up everything and terminate.
storm::utility::cleanUp();
return 0;

12
src/storm/api/export.h

@ -3,6 +3,7 @@
#include "storm/settings/SettingsManager.h"
#include "storm/utility/DirectEncodingExporter.h"
#include "storm/utility/DDEncodingExporter.h"
#include "storm/utility/file.h"
#include "storm/utility/macros.h"
@ -23,6 +24,11 @@ namespace storm {
storm::exporter::explicitExportSparseModel(stream, model, parameterNames);
storm::utility::closeFile(stream);
}
template<storm::dd::DdType Type, typename ValueType>
void exportSparseModelAsDrdd(std::shared_ptr<storm::models::symbolic::Model<Type,ValueType>> const& model, std::string const& filename) {
storm::exporter::explicitExportSymbolicModel(filename, model);
}
template <typename ValueType>
void exportSparseModelAsDot(std::shared_ptr<storm::models::sparse::Model<ValueType>> const& model, std::string const& filename) {
@ -31,6 +37,10 @@ namespace storm {
model->writeDotToStream(stream);
storm::utility::closeFile(stream);
}
template<storm::dd::DdType Type, typename ValueType>
void exportSymbolicModelAsDot(std::shared_ptr<storm::models::symbolic::Model<Type,ValueType>> const& model, std::string const& filename) {
model->writeDotToFile(filename);
}
}
}

24
src/storm/models/sparse/StandardRewardModel.cpp

@ -339,6 +339,24 @@ namespace storm {
void StandardRewardModel<ValueType>::setStateActionRewardValue(uint_fast64_t row, ValueType const& value) {
this->optionalStateActionRewardVector.get()[row] = value;
}
template<typename ValueType>
template<typename MatrixValueType>
void StandardRewardModel<ValueType>::clearRewardAtState(uint_fast64_t state, storm::storage::SparseMatrix<MatrixValueType> const& transitions) {
if (hasStateRewards()) {
getStateRewardVector()[state] = storm::utility::zero<ValueType>();
}
if (hasStateActionRewards()) {
for (uint_fast64_t choice = transitions.getRowGroupIndices()[state]; choice < transitions.getRowGroupIndices()[state + 1]; ++choice) {
getStateActionRewardVector()[choice] = storm::utility::zero<ValueType>();
}
}
if (hasTransitionRewards()) {
for (auto& entry : getTransitionRewardMatrix().getRowGroup(state)) {
entry.setValue(storm::utility::zero<ValueType>());
}
}
}
template<typename ValueType>
bool StandardRewardModel<ValueType>::empty() const {
@ -412,7 +430,7 @@ namespace storm {
template storm::storage::BitVector StandardRewardModel<double>::getChoicesWithZeroReward(storm::storage::SparseMatrix<double> const& transitionMatrix) const;
template storm::storage::BitVector StandardRewardModel<double>::getChoicesWithFilter(storm::storage::SparseMatrix<double> const& transitionMatrix, std::function<bool(double const&)> const& filter) const;
template double StandardRewardModel<double>::getTotalStateActionReward(uint_fast64_t stateIndex, uint_fast64_t choiceIndex, storm::storage::SparseMatrix<double> const& transitionMatrix, double const& stateRewardWeight, double const& actionRewardWeight) const;
template void StandardRewardModel<double>::clearRewardAtState(uint_fast64_t state, storm::storage::SparseMatrix<double> const& transitionMatrix);
template void StandardRewardModel<double>::reduceToStateBasedRewards(storm::storage::SparseMatrix<double> const& transitionMatrix, bool reduceToStateRewards, std::vector<double> const* weights);
template void StandardRewardModel<double>::setStateActionReward(uint_fast64_t choiceIndex, double const & newValue);
template void StandardRewardModel<double>::setStateReward(uint_fast64_t state, double const & newValue);
@ -440,6 +458,7 @@ namespace storm {
template storm::storage::BitVector StandardRewardModel<storm::RationalNumber>::getChoicesWithFilter(storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, std::function<bool(storm::RationalNumber const&)> const& filter) const;
template storm::RationalNumber StandardRewardModel<storm::RationalNumber>::getTotalStateActionReward(uint_fast64_t stateIndex, uint_fast64_t choiceIndex, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, storm::RationalNumber const& stateRewardWeight, storm::RationalNumber const& actionRewardWeight) const;
template void StandardRewardModel<storm::RationalNumber>::reduceToStateBasedRewards(storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix, bool reduceToStateRewards, std::vector<storm::RationalNumber> const* weights);
template void StandardRewardModel<storm::RationalNumber>::clearRewardAtState(uint_fast64_t state, storm::storage::SparseMatrix<storm::RationalNumber> const& transitionMatrix);
template void StandardRewardModel<storm::RationalNumber>::setStateActionReward(uint_fast64_t choiceIndex, storm::RationalNumber const & newValue);
template void StandardRewardModel<storm::RationalNumber>::setStateReward(uint_fast64_t state, storm::RationalNumber const & newValue);
template class StandardRewardModel<storm::RationalNumber>;
@ -452,7 +471,7 @@ namespace storm {
template storm::storage::BitVector StandardRewardModel<storm::RationalFunction>::getStatesWithFilter(storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrix, std::function<bool(storm::RationalFunction const&)> const& filter) const;
template storm::storage::BitVector StandardRewardModel<storm::RationalFunction>::getChoicesWithZeroReward(storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrix) const;
template storm::storage::BitVector StandardRewardModel<storm::RationalFunction>::getChoicesWithFilter(storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrix, std::function<bool(storm::RationalFunction const&)> const& filter) const;
template void StandardRewardModel<storm::RationalFunction>::clearRewardAtState(uint_fast64_t state, storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrix);
template std::vector<storm::RationalFunction> StandardRewardModel<storm::RationalFunction>::getTotalActionRewardVector(storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrix, std::vector<storm::RationalFunction> const& stateRewardWeights) const;
template storm::RationalFunction StandardRewardModel<storm::RationalFunction>::getTotalStateActionReward(uint_fast64_t stateIndex, uint_fast64_t choiceIndex, storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrix, storm::RationalFunction const& stateRewardWeight, storm::RationalFunction const& actionRewardWeight) const;
template void StandardRewardModel<storm::RationalFunction>::reduceToStateBasedRewards(storm::storage::SparseMatrix<storm::RationalFunction> const& transitionMatrix, bool reduceToStateRewards, std::vector<storm::RationalFunction> const* weights);
@ -471,6 +490,7 @@ namespace storm {
template void StandardRewardModel<storm::Interval>::setStateActionReward(uint_fast64_t choiceIndex, storm::Interval const & newValue);
template void StandardRewardModel<storm::Interval>::setStateReward(uint_fast64_t state, double const & newValue);
template void StandardRewardModel<storm::Interval>::setStateReward(uint_fast64_t state, storm::Interval const & newValue);
template void StandardRewardModel<storm::Interval>::clearRewardAtState(uint_fast64_t state, storm::storage::SparseMatrix<double> const& transitionMatrix);
template void StandardRewardModel<storm::Interval>::reduceToStateBasedRewards(storm::storage::SparseMatrix<double> const& transitionMatrix, bool reduceToStateRewards, std::vector<double> const* weights);
template class StandardRewardModel<storm::Interval>;
template std::ostream& operator<<<storm::Interval>(std::ostream& out, StandardRewardModel<storm::Interval> const& rewardModel);

10
src/storm/models/sparse/StandardRewardModel.h

@ -123,9 +123,13 @@ namespace storm {
*/
template<typename T>
void setStateActionReward(uint_fast64_t choiceIndex, T const& newValue);
//ValueType maximalStateActionReward() const;
/*!
* Sets all available rewards at this state to zero.
*/
template<typename MatrixValueType>
void clearRewardAtState(uint_fast64_t state, storm::storage::SparseMatrix<MatrixValueType> const& transitions);
/*!
* Retrieves an optional value that contains the state-action reward vector if there is one.
*

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

@ -368,7 +368,17 @@ namespace storm {
bool Model<Type, ValueType>::supportsParameters() const {
return std::is_same<ValueType, storm::RationalFunction>::value;
}
template<storm::dd::DdType Type, typename ValueType>
void Model<Type, ValueType>::writeDotToFile(std::string const& filename) const {
this->getTransitionMatrix().exportToDot(filename, true);
this->getInitialStates().exportToDot(filename, true);
for (auto const& lab : this->getLabels()) {
this->getStates(lab).exportToDot(filename,true);
}
}
template<storm::dd::DdType Type, typename ValueType>
bool Model<Type, ValueType>::hasParameters() const {
if (!this->supportsParameters()) {
@ -403,7 +413,10 @@ namespace storm {
std::set<storm::RationalFunctionVariable> const& Model<storm::dd::DdType::Sylvan, storm::RationalFunction>::getParameters() const {
return parameters;
}
template<storm::dd::DdType Type, typename ValueType>
template<typename NewValueType>
typename std::enable_if<!std::is_same<ValueType, NewValueType>::value, std::shared_ptr<Model<Type, NewValueType>>>::type Model<Type, ValueType>::toValueType() const {

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

@ -343,6 +343,8 @@ namespace storm {
template<typename NewValueType>
typename std::enable_if<std::is_same<ValueType, NewValueType>::value, std::shared_ptr<Model<Type, NewValueType>>>::type toValueType() const;
void writeDotToFile(std::string const& filename) const;
protected:
/*!
* Sets the transition matrix of the model.

11
src/storm/settings/modules/IOSettings.cpp

@ -19,6 +19,7 @@ namespace storm {
const std::string IOSettings::moduleName = "io";
const std::string IOSettings::exportDotOptionName = "exportdot";
const std::string IOSettings::exportExplicitOptionName = "exportexplicit";
const std::string IOSettings::exportDdOptionName = "exportdd";
const std::string IOSettings::exportJaniDotOptionName = "exportjanidot";
const std::string IOSettings::exportCdfOptionName = "exportcdf";
const std::string IOSettings::exportCdfOptionShortName = "cdf";
@ -56,6 +57,8 @@ namespace storm {
this->addOption(storm::settings::OptionBuilder(moduleName, exportCdfOptionName, false, "Exports the cumulative density function for reward bounded properties into a .csv file.").setIsAdvanced().setShortName(exportCdfOptionShortName).addArgument(storm::settings::ArgumentBuilder::createStringArgument("directory", "A path to an existing directory where the cdf files will be stored.").build()).build());
this->addOption(storm::settings::OptionBuilder(moduleName, exportExplicitOptionName, "", "If given, the loaded model will be written to the specified file in the drn format.")
.addArgument(storm::settings::ArgumentBuilder::createStringArgument("filename", "the name of the file to which the model is to be writen.").build()).build());
this->addOption(storm::settings::OptionBuilder(moduleName, exportDdOptionName, "", "If given, the loaded model will be written to the specified file in the drdd format.")
.addArgument(storm::settings::ArgumentBuilder::createStringArgument("filename", "the name of the file to which the model is to be writen.").build()).build());
this->addOption(storm::settings::OptionBuilder(moduleName, explicitOptionName, false, "Parses the model given in an explicit (sparse) representation.").setShortName(explicitOptionShortName)
.addArgument(storm::settings::ArgumentBuilder::createStringArgument("transition filename", "The name of the file from which to read the transitions.").addValidatorString(ArgumentValidatorFactory::createExistingFileValidator()).build())
.addArgument(storm::settings::ArgumentBuilder::createStringArgument("labeling filename", "The name of the file from which to read the state labeling.").addValidatorString(ArgumentValidatorFactory::createExistingFileValidator()).build()).build());
@ -124,6 +127,14 @@ namespace storm {
std::string IOSettings::getExportExplicitFilename() const {
return this->getOption(exportExplicitOptionName).getArgumentByName("filename").getValueAsString();
}
bool IOSettings::isExportDdSet() const {
return this->getOption(exportDdOptionName).getHasOptionBeenSet();
}
std::string IOSettings::getExportDdFilename() const {
return this->getOption(exportDdOptionName).getArgumentByName("filename").getValueAsString();
}
bool IOSettings::isExportCdfSet() const {
return this->getOption(exportCdfOptionName).getHasOptionBeenSet();

21
src/storm/settings/modules/IOSettings.h

@ -59,12 +59,26 @@ namespace storm {
bool isExportExplicitSet() const;
/*!
* Retrieves thename in which to write the model in explicit format, if the option was set.
* Retrieves the name in which to write the model in explicit format, if the option was set.
*
* @return The name of the file in which to write the exported mode.
* @return The name of the file in which to write the exported model.
*/
std::string getExportExplicitFilename() const;
/*!
* Retrieves whether the export-to-dd option was set
*
* @return True if the export-to-explicit option was set
*/
bool isExportDdSet() const;
/*!
* Retrieves the name in which to write the model in dd format, if the option was set.
*
* @return The name of the file in which to write the exported model.
*/
std::string getExportDdFilename() const;
/*!
* Retrieves whether the cumulative density function for reward bounded properties should be exported
*/
@ -308,6 +322,7 @@ namespace storm {
static const std::string exportDotOptionName;
static const std::string exportJaniDotOptionName;
static const std::string exportExplicitOptionName;
static const std::string exportDdOptionName;
static const std::string exportCdfOptionName;
static const std::string exportCdfOptionShortName;
static const std::string explicitOptionName;

48
src/storm/storage/SparseMatrix.cpp

@ -690,17 +690,30 @@ namespace storm {
// If the row has no elements in it, we cannot make it absorbing, because we would need to move all elements
// in the vector of nonzeros otherwise.
if (columnValuePtr >= columnValuePtrEnd) {
throw storm::exceptions::InvalidStateException() << "Illegal call to SparseMatrix::makeRowDirac: cannot make row " << row << " absorbing, but there is no entry in this row.";
throw storm::exceptions::InvalidStateException() << "Illegal call to SparseMatrix::makeRowDirac: cannot make row " << row << " absorbing, because there is no entry in this row.";
}
iterator lastColumnValuePtr = this->end(row) - 1;
// If there is at least one entry in this row, we can just set it to one, modify its column value to the
// If there is at least one entry in this row, we can set it to one, modify its column value to the
// one given by the parameter and set all subsequent elements of this row to zero.
columnValuePtr->setColumn(column);
columnValuePtr->setValue(storm::utility::one<ValueType>());
++columnValuePtr;
for (; columnValuePtr != columnValuePtrEnd; ++columnValuePtr) {
// However, we want to preserve that column indices within a row are ascending, so we pick an entry that is close to the desired column index
while (columnValuePtr->getColumn() < column && columnValuePtr != lastColumnValuePtr) {
if (!storm::utility::isZero(columnValuePtr->getValue())) {
--this->nonzeroEntryCount;
}
columnValuePtr->setValue(storm::utility::zero<ValueType>());
++columnValuePtr;
}
// At this point, we have found the first entry whose column is >= the desired column (or the last entry of the row, if no such column exist)
if (storm::utility::isZero(columnValuePtr->getValue())) {
++this->nonzeroEntryCount;
columnValuePtr->setColumn(0);
}
columnValuePtr->setValue(storm::utility::one<ValueType>());
columnValuePtr->setColumn(column);
for (++columnValuePtr; columnValuePtr != columnValuePtrEnd; ++columnValuePtr) {
if (!storm::utility::isZero(columnValuePtr->getValue())) {
--this->nonzeroEntryCount;
}
columnValuePtr->setValue(storm::utility::zero<ValueType>());
}
}
@ -1060,6 +1073,27 @@ namespace storm {
return result;
}
template<typename ValueType>
void SparseMatrix<ValueType>::dropZeroEntries() {
updateNonzeroEntryCount();
if (getNonzeroEntryCount() != getEntryCount()) {
SparseMatrixBuilder<ValueType> builder(getRowCount(), getColumnCount(), getNonzeroEntryCount(), true);
for (index_type row = 0; row < getRowCount(); ++row) {
for (auto const& entry : getRow(row)) {
if (!storm::utility::isZero(entry.getValue())) {
builder.addNextValue(row, entry.getColumn(), entry.getValue());
}
}
}
SparseMatrix<ValueType> result = builder.build();
// Add a row grouping if necessary.
if (!hasTrivialRowGrouping()) {
result.setRowGroupIndices(getRowGroupIndices());
}
*this = std::move(result);
}
}
template<typename ValueType>
SparseMatrix<ValueType> SparseMatrix<ValueType>::selectRowsFromRowGroups(std::vector<index_type> const& rowGroupToRowIndexMapping, bool insertDiagonalEntries) const {
// First, we need to count how many non-zero entries the resulting matrix will have and reserve space for

5
src/storm/storage/SparseMatrix.h

@ -726,6 +726,11 @@ namespace storm {
*/
SparseMatrix filterEntries(storm::storage::BitVector const& rowFilter) const;
/*!
* Removes all zero entries from this.
*/
void dropZeroEntries();
/**
* Compares two rows.
* @param i1 Index of first row

5
src/storm/storage/dd/Add.cpp

@ -1009,6 +1009,11 @@ namespace storm {
void Add<LibraryType, ValueType>::exportToDot(std::string const& filename, bool showVariablesIfPossible) const {
internalAdd.exportToDot(filename, this->getDdManager().getDdVariableNames(), showVariablesIfPossible);
}
template<DdType LibraryType, typename ValueType>
void Add<LibraryType, ValueType>::exportToText(std::string const& filename) const {
internalAdd.exportToText(filename);
}
template<DdType LibraryType, typename ValueType>
AddIterator<LibraryType, ValueType> Add<LibraryType, ValueType>::begin(bool enumerateDontCareMetaVariables) const {

2
src/storm/storage/dd/Add.h

@ -693,6 +693,8 @@ namespace storm {
* @param filename The name of the file to which the DD is to be exported.
*/
void exportToDot(std::string const& filename, bool showVariablesIfPossible = true) const override;
virtual void exportToText(std::string const& filename) const override;
/*!
* Retrieves an iterator that points to the first meta variable assignment with a non-zero function value.

5
src/storm/storage/dd/Bdd.cpp

@ -491,6 +491,11 @@ namespace storm {
void Bdd<LibraryType>::exportToDot(std::string const& filename, bool showVariablesIfPossible) const {
internalBdd.exportToDot(filename, this->getDdManager().getDdVariableNames(), showVariablesIfPossible);
}
template<DdType LibraryType>
void Bdd<LibraryType>::exportToText(std::string const& filename) const {
internalBdd.exportToText(filename);
}
template<DdType LibraryType>
Bdd<LibraryType> Bdd<LibraryType>::getCube(DdManager<LibraryType> const& manager, std::set<storm::expressions::Variable> const& metaVariables) {

2
src/storm/storage/dd/Bdd.h

@ -379,6 +379,8 @@ namespace storm {
virtual uint_fast64_t getLevel() const override;
virtual void exportToDot(std::string const& filename, bool showVariablesIfPossible = true) const override;
virtual void exportToText(std::string const& filename) const override;
/*!
* Retrieves the cube of all given meta variables.

7
src/storm/storage/dd/Dd.h

@ -103,6 +103,13 @@ namespace storm {
* @param filename The name of the file to which the DD is to be exported.
*/
virtual void exportToDot(std::string const& filename, bool showVariablesIfPossible = true) const = 0;
/*!
* Exports the DD to the given file in the dot format.
*
* @param filename The name of the file to which the DD is to be exported.
*/
virtual void exportToText(std::string const& filename) const = 0;
/*!
* Retrieves the manager that is responsible for this DD.

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

@ -11,6 +11,7 @@
#include "storm/utility/file.h"
#include "storm/adapters/RationalFunctionAdapter.h"
#include "storm/exceptions/NotSupportedException.h"
namespace storm {
namespace dd {
@ -158,6 +159,10 @@ namespace storm {
dotFile << "}" << std::endl;
storm::utility::closeFile(dotFile);
}
void Odd::exportToText(std::string const& filename) const {
STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Operation not supported");
}
void getEncodingRec(Odd const& odd, uint64_t index, uint64_t offset, storm::storage::BitVector& result) {
if (odd.isTerminalNode()) {

7
src/storm/storage/dd/Odd.h

@ -133,6 +133,13 @@ namespace storm {
* @param filename The name of the file to which to write the dot output.
*/
void exportToDot(std::string const& filename) const;
/*!
* Exports the ODD in the text format to the given file.
*
* @param filename The name of the file to which to write the dot output.
*/
void exportToText(std::string const& filename) const;
/*!
* Retrieves the encoding for the given offset.

267
src/storm/storage/dd/cudd/InternalCuddAdd.cpp

@ -16,173 +16,177 @@
namespace storm {
namespace dd {
template<typename ValueType>
InternalAdd<DdType::CUDD, ValueType>::InternalAdd(InternalDdManager<DdType::CUDD> const* ddManager, cudd::ADD cuddAdd) : ddManager(ddManager), cuddAdd(cuddAdd) {
InternalAdd<DdType::CUDD, ValueType>::InternalAdd(InternalDdManager <DdType::CUDD> const *ddManager, cudd::ADD cuddAdd) : ddManager(ddManager), cuddAdd(cuddAdd) {
// Intentionally left empty.
}
template<typename ValueType>
bool InternalAdd<DdType::CUDD, ValueType>::operator==(InternalAdd<DdType::CUDD, ValueType> const& other) const {
bool InternalAdd<DdType::CUDD, ValueType>::operator==(InternalAdd <DdType::CUDD, ValueType> const &other) const {
return this->getCuddAdd() == other.getCuddAdd();
}
template<typename ValueType>
bool InternalAdd<DdType::CUDD, ValueType>::operator!=(InternalAdd<DdType::CUDD, ValueType> const& other) const {
bool InternalAdd<DdType::CUDD, ValueType>::operator!=(InternalAdd <DdType::CUDD, ValueType> const &other) const {
return !(*this == other);
}
template<typename ValueType>
InternalAdd<DdType::CUDD, ValueType> InternalAdd<DdType::CUDD, ValueType>::operator+(InternalAdd<DdType::CUDD, ValueType> const& other) const {
InternalAdd <DdType::CUDD, ValueType> InternalAdd<DdType::CUDD, ValueType>::operator+(InternalAdd <DdType::CUDD, ValueType> const &other) const {
return InternalAdd<DdType::CUDD, ValueType>(ddManager, this->getCuddAdd() + other.getCuddAdd());
}
template<typename ValueType>
InternalAdd<DdType::CUDD, ValueType>& InternalAdd<DdType::CUDD, ValueType>::operator+=(InternalAdd<DdType::CUDD, ValueType> const& other) {
InternalAdd <DdType::CUDD, ValueType> &InternalAdd<DdType::CUDD, ValueType>::operator+=(InternalAdd <DdType::CUDD, ValueType> const &other) {
this->cuddAdd = this->getCuddAdd() + other.getCuddAdd();
return *this;
}
template<typename ValueType>
InternalAdd<DdType::CUDD, ValueType> InternalAdd<DdType::CUDD, ValueType>::operator*(InternalAdd<DdType::CUDD, ValueType> const& other) const {
InternalAdd <DdType::CUDD, ValueType> InternalAdd<DdType::CUDD, ValueType>::operator*(InternalAdd <DdType::CUDD, ValueType> const &other) const {
return InternalAdd<DdType::CUDD, ValueType>(ddManager, this->getCuddAdd() * other.getCuddAdd());
}
template<typename ValueType>
InternalAdd<DdType::CUDD, ValueType>& InternalAdd<DdType::CUDD, ValueType>::operator*=(InternalAdd<DdType::CUDD, ValueType> const& other) {
InternalAdd <DdType::CUDD, ValueType> &InternalAdd<DdType::CUDD, ValueType>::operator*=(InternalAdd <DdType::CUDD, ValueType> const &other) {
this->cuddAdd = this->getCuddAdd() * other.getCuddAdd();
return *this;
}
template<typename ValueType>
InternalAdd<DdType::CUDD, ValueType> InternalAdd<DdType::CUDD, ValueType>::operator-(InternalAdd<DdType::CUDD, ValueType> const& other) const {
InternalAdd <DdType::CUDD, ValueType> InternalAdd<DdType::CUDD, ValueType>::operator-(InternalAdd <DdType::CUDD, ValueType> const &other) const {
return InternalAdd<DdType::CUDD, ValueType>(ddManager, this->getCuddAdd() - other.getCuddAdd());
}
template<typename ValueType>
InternalAdd<DdType::CUDD, ValueType>& InternalAdd<DdType::CUDD, ValueType>::operator-=(InternalAdd<DdType::CUDD, ValueType> const& other) {
InternalAdd <DdType::CUDD, ValueType> &InternalAdd<DdType::CUDD, ValueType>::operator-=(InternalAdd <DdType::CUDD, ValueType> const &other) {
this->cuddAdd = this->getCuddAdd() - other.getCuddAdd();
return *this;
}
template<typename ValueType>
InternalAdd<DdType::CUDD, ValueType> InternalAdd<DdType::CUDD, ValueType>::operator/(InternalAdd<DdType::CUDD, ValueType> const& other) const {
InternalAdd <DdType::CUDD, ValueType> InternalAdd<DdType::CUDD, ValueType>::operator/(InternalAdd <DdType::CUDD, ValueType> const &other) const {
return InternalAdd<DdType::CUDD, ValueType>(ddManager, this->getCuddAdd().Divide(other.getCuddAdd()));
}
template<typename ValueType>
InternalAdd<DdType::CUDD, ValueType>& InternalAdd<DdType::CUDD, ValueType>::operator/=(InternalAdd<DdType::CUDD, ValueType> const& other) {
InternalAdd <DdType::CUDD, ValueType> &InternalAdd<DdType::CUDD, ValueType>::operator/=(InternalAdd <DdType::CUDD, ValueType> const &other) {
this->cuddAdd = this->getCuddAdd().Divide(other.getCuddAdd());
return *this;
}
template<typename ValueType>
InternalBdd<DdType::CUDD> InternalAdd<DdType::CUDD, ValueType>::equals(InternalAdd<DdType::CUDD, ValueType> const& other) const {
InternalBdd <DdType::CUDD> InternalAdd<DdType::CUDD, ValueType>::equals(InternalAdd <DdType::CUDD, ValueType> const &other) const {
return InternalBdd<DdType::CUDD>(ddManager, this->getCuddAdd().EqualsBdd(other.getCuddAdd()));
}
template<typename ValueType>
InternalBdd<DdType::CUDD> InternalAdd<DdType::CUDD, ValueType>::notEquals(InternalAdd<DdType::CUDD, ValueType> const& other) const {
InternalBdd <DdType::CUDD> InternalAdd<DdType::CUDD, ValueType>::notEquals(InternalAdd <DdType::CUDD, ValueType> const &other) const {
return InternalBdd<DdType::CUDD>(ddManager, this->getCuddAdd().NotEqualsBdd(other.getCuddAdd()));
}
template<typename ValueType>
InternalBdd<DdType::CUDD> InternalAdd<DdType::CUDD, ValueType>::less(InternalAdd<DdType::CUDD, ValueType> const& other) const {
InternalBdd <DdType::CUDD> InternalAdd<DdType::CUDD, ValueType>::less(InternalAdd <DdType::CUDD, ValueType> const &other) const {
return InternalBdd<DdType::CUDD>(ddManager, this->getCuddAdd().LessThanBdd(other.getCuddAdd()));
}
template<typename ValueType>
InternalBdd<DdType::CUDD> InternalAdd<DdType::CUDD, ValueType>::lessOrEqual(InternalAdd<DdType::CUDD, ValueType> const& other) const {
InternalBdd <DdType::CUDD> InternalAdd<DdType::CUDD, ValueType>::lessOrEqual(InternalAdd <DdType::CUDD, ValueType> const &other) const {
return InternalBdd<DdType::CUDD>(ddManager, this->getCuddAdd().LessThanOrEqualBdd(other.getCuddAdd()));
}
template<typename ValueType>
InternalBdd<DdType::CUDD> InternalAdd<DdType::CUDD, ValueType>::greater(InternalAdd<DdType::CUDD, ValueType> const& other) const {
InternalBdd <DdType::CUDD> InternalAdd<DdType::CUDD, ValueType>::greater(InternalAdd <DdType::CUDD, ValueType> const &other) const {
return InternalBdd<DdType::CUDD>(ddManager, this->getCuddAdd().GreaterThanBdd(other.getCuddAdd()));
}
template<typename ValueType>
InternalBdd<DdType::CUDD> InternalAdd<DdType::CUDD, ValueType>::greaterOrEqual(InternalAdd<DdType::CUDD, ValueType> const& other) const {
InternalBdd <DdType::CUDD> InternalAdd<DdType::CUDD, ValueType>::greaterOrEqual(InternalAdd <DdType::CUDD, ValueType> const &other) const {
return InternalBdd<DdType::CUDD>(ddManager, this->getCuddAdd().GreaterThanOrEqualBdd(other.getCuddAdd()));
}
template<typename ValueType>
InternalAdd<DdType::CUDD, ValueType> InternalAdd<DdType::CUDD, ValueType>::pow(InternalAdd<DdType::CUDD, ValueType> const& other) const {
InternalAdd <DdType::CUDD, ValueType> InternalAdd<DdType::CUDD, ValueType>::pow(InternalAdd <DdType::CUDD, ValueType> const &other) const {
return InternalAdd<DdType::CUDD, ValueType>(ddManager, this->getCuddAdd().Pow(other.getCuddAdd()));
}
template<typename ValueType>
InternalAdd<DdType::CUDD, ValueType> InternalAdd<DdType::CUDD, ValueType>::mod(InternalAdd<DdType::CUDD, ValueType> const& other) const {
InternalAdd <DdType::CUDD, ValueType> InternalAdd<DdType::CUDD, ValueType>::mod(InternalAdd <DdType::CUDD, ValueType> const &other) const {
return InternalAdd<DdType::CUDD, ValueType>(ddManager, this->getCuddAdd().Mod(other.getCuddAdd()));
}
template<typename ValueType>
InternalAdd<DdType::CUDD, ValueType> InternalAdd<DdType::CUDD, ValueType>::logxy(InternalAdd<DdType::CUDD, ValueType> const& other) const {
InternalAdd <DdType::CUDD, ValueType> InternalAdd<DdType::CUDD, ValueType>::logxy(InternalAdd <DdType::CUDD, ValueType> const &other) const {
return InternalAdd<DdType::CUDD, ValueType>(ddManager, this->getCuddAdd().LogXY(other.getCuddAdd()));
}
template<typename ValueType>
InternalAdd<DdType::CUDD, ValueType> InternalAdd<DdType::CUDD, ValueType>::floor() const {
InternalAdd <DdType::CUDD, ValueType> InternalAdd<DdType::CUDD, ValueType>::floor() const {
return InternalAdd<DdType::CUDD, ValueType>(ddManager, this->getCuddAdd().Floor());
}
template<typename ValueType>
InternalAdd<DdType::CUDD, ValueType> InternalAdd<DdType::CUDD, ValueType>::ceil() const {
InternalAdd <DdType::CUDD, ValueType> InternalAdd<DdType::CUDD, ValueType>::ceil() const {
return InternalAdd<DdType::CUDD, ValueType>(ddManager, this->getCuddAdd().Ceil());
}
template<typename ValueType>
InternalAdd<DdType::CUDD, storm::RationalNumber> InternalAdd<DdType::CUDD, ValueType>::sharpenKwekMehlhorn(size_t precision) const {
InternalAdd <DdType::CUDD, storm::RationalNumber> InternalAdd<DdType::CUDD, ValueType>::sharpenKwekMehlhorn(size_t precision) const {
STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Operation not supported");
}
template<typename ValueType>
InternalAdd<DdType::CUDD, ValueType> InternalAdd<DdType::CUDD, ValueType>::minimum(InternalAdd<DdType::CUDD, ValueType> const& other) const {
InternalAdd <DdType::CUDD, ValueType> InternalAdd<DdType::CUDD, ValueType>::minimum(InternalAdd <DdType::CUDD, ValueType> const &other) const {
return InternalAdd<DdType::CUDD, ValueType>(ddManager, this->getCuddAdd().Minimum(other.getCuddAdd()));
}
template<typename ValueType>
InternalAdd<DdType::CUDD, ValueType> InternalAdd<DdType::CUDD, ValueType>::maximum(InternalAdd<DdType::CUDD, ValueType> const& other) const {
InternalAdd <DdType::CUDD, ValueType> InternalAdd<DdType::CUDD, ValueType>::maximum(InternalAdd <DdType::CUDD, ValueType> const &other) const {
return InternalAdd<DdType::CUDD, ValueType>(ddManager, this->getCuddAdd().Maximum(other.getCuddAdd()));
}
template<typename ValueType>
template<typename TargetValueType>
typename std::enable_if<std::is_same<ValueType, TargetValueType>::value, InternalAdd<DdType::CUDD, TargetValueType>>::type InternalAdd<DdType::CUDD, ValueType>::toValueType() const {
typename std::enable_if<std::is_same<ValueType, TargetValueType>::value, InternalAdd < DdType::CUDD, TargetValueType>>
::type InternalAdd<DdType::CUDD, ValueType>::toValueType() const {
return *this;
}
template<typename ValueType>
template<typename TargetValueType>
typename std::enable_if<!std::is_same<ValueType, TargetValueType>::value, InternalAdd<DdType::CUDD, TargetValueType>>::type InternalAdd<DdType::CUDD, ValueType>::toValueType() const {
typename std::enable_if<!std::is_same<ValueType, TargetValueType>::value, InternalAdd < DdType::CUDD, TargetValueType>>
::type InternalAdd<DdType::CUDD, ValueType>::toValueType() const {
STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Operation not supported");
}
template<typename ValueType>
InternalAdd<DdType::CUDD, ValueType> InternalAdd<DdType::CUDD, ValueType>::sumAbstract(InternalBdd<DdType::CUDD> const& cube) const {
InternalAdd <DdType::CUDD, ValueType> InternalAdd<DdType::CUDD, ValueType>::sumAbstract(InternalBdd <DdType::CUDD> const &cube) const {
return InternalAdd<DdType::CUDD, ValueType>(ddManager, this->getCuddAdd().ExistAbstract(cube.toAdd<ValueType>().getCuddAdd()));
}
template<typename ValueType>
InternalAdd<DdType::CUDD, ValueType> InternalAdd<DdType::CUDD, ValueType>::minAbstract(InternalBdd<DdType::CUDD> const& cube) const {
InternalAdd <DdType::CUDD, ValueType> InternalAdd<DdType::CUDD, ValueType>::minAbstract(InternalBdd <DdType::CUDD> const &cube) const {
return InternalAdd<DdType::CUDD, ValueType>(ddManager, this->getCuddAdd().MinAbstract(cube.toAdd<ValueType>().getCuddAdd()));
}
template<typename ValueType>
InternalBdd<DdType::CUDD> InternalAdd<DdType::CUDD, ValueType>::minAbstractRepresentative(InternalBdd<DdType::CUDD> const& cube) const {
return InternalBdd<DdType::CUDD>(ddManager, this->getCuddAdd().MinAbstractRepresentative(cube.toAdd<ValueType>().getCuddAdd()));
template<typename ValueType>
InternalBdd <DdType::CUDD> InternalAdd<DdType::CUDD, ValueType>::minAbstractRepresentative(InternalBdd <DdType::CUDD> const &cube) const {
return InternalBdd<DdType::CUDD>(ddManager, this->getCuddAdd().MinAbstractRepresentative(cube.toAdd<ValueType>().getCuddAdd()));
}
template<typename ValueType>
InternalAdd<DdType::CUDD, ValueType> InternalAdd<DdType::CUDD, ValueType>::maxAbstract(InternalBdd<DdType::CUDD> const& cube) const {
InternalAdd <DdType::CUDD, ValueType> InternalAdd<DdType::CUDD, ValueType>::maxAbstract(InternalBdd <DdType::CUDD> const &cube) const {
return InternalAdd<DdType::CUDD, ValueType>(ddManager, this->getCuddAdd().MaxAbstract(cube.toAdd<ValueType>().getCuddAdd()));
}
template<typename ValueType>
InternalBdd<DdType::CUDD> InternalAdd<DdType::CUDD, ValueType>::maxAbstractRepresentative(InternalBdd<DdType::CUDD> const& cube) const {
return InternalBdd<DdType::CUDD>(ddManager, this->getCuddAdd().MaxAbstractRepresentative(cube.toAdd<ValueType>().getCuddAdd()));
template<typename ValueType>
InternalBdd <DdType::CUDD> InternalAdd<DdType::CUDD, ValueType>::maxAbstractRepresentative(InternalBdd <DdType::CUDD> const &cube) const {
return InternalBdd<DdType::CUDD>(ddManager, this->getCuddAdd().MaxAbstractRepresentative(cube.toAdd<ValueType>().getCuddAdd()));
}
template<typename ValueType>
bool InternalAdd<DdType::CUDD, ValueType>::equalModuloPrecision(InternalAdd<DdType::CUDD, ValueType> const& other, ValueType const& precision, bool relative) const {
bool InternalAdd<DdType::CUDD, ValueType>::equalModuloPrecision(InternalAdd <DdType::CUDD, ValueType> const &other, ValueType const &precision, bool relative) const {
if (relative) {
return this->getCuddAdd().EqualSupNormRel(other.getCuddAdd(), precision);
} else {
@ -191,14 +195,14 @@ namespace storm {
}
template<>
bool InternalAdd<DdType::CUDD, storm::RationalNumber>::equalModuloPrecision(InternalAdd<DdType::CUDD, storm::RationalNumber> const& other, storm::RationalNumber const& precision, bool relative) const {
bool InternalAdd<DdType::CUDD, storm::RationalNumber>::equalModuloPrecision(InternalAdd <DdType::CUDD, storm::RationalNumber> const &other, storm::RationalNumber const &precision, bool relative) const {
STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Operation not supported.");
}
template<typename ValueType>
InternalAdd<DdType::CUDD, ValueType> InternalAdd<DdType::CUDD, ValueType>::swapVariables(std::vector<InternalBdd<DdType::CUDD>> const& from, std::vector<InternalBdd<DdType::CUDD>> const& to) const {
std::vector<cudd::ADD> fromAdd;
std::vector<cudd::ADD> toAdd;
InternalAdd <DdType::CUDD, ValueType> InternalAdd<DdType::CUDD, ValueType>::swapVariables(std::vector <InternalBdd<DdType::CUDD>> const &from, std::vector <InternalBdd<DdType::CUDD>> const &to) const {
std::vector <cudd::ADD> fromAdd;
std::vector <cudd::ADD> toAdd;
STORM_LOG_ASSERT(fromAdd.size() == toAdd.size(), "Sizes of vectors do not match.");
for (auto it1 = from.begin(), ite1 = from.end(), it2 = to.begin(); it1 != ite1; ++it1, ++it2) {
fromAdd.push_back(it1->getCuddBdd().Add());
@ -206,30 +210,30 @@ namespace storm {
}
return InternalAdd<DdType::CUDD, ValueType>(ddManager, this->getCuddAdd().SwapVariables(fromAdd, toAdd));
}
template<typename ValueType>
InternalAdd<DdType::CUDD, ValueType> InternalAdd<DdType::CUDD, ValueType>::permuteVariables(std::vector<InternalBdd<DdType::CUDD>> const& from, std::vector<InternalBdd<DdType::CUDD>> const& to) const {
InternalAdd <DdType::CUDD, ValueType> InternalAdd<DdType::CUDD, ValueType>::permuteVariables(std::vector <InternalBdd<DdType::CUDD>> const &from, std::vector <InternalBdd<DdType::CUDD>> const &to) const {
// Build the full permutation.
uint64_t numberOfVariables = ddManager->getCuddManager().ReadSize();
int* permutation = new int[numberOfVariables];
int *permutation = new int[numberOfVariables];
for (uint64_t variable = 0; variable < numberOfVariables; ++variable) {
permutation[variable] = variable;
}
for (auto it1 = from.begin(), ite1 = from.end(), it2 = to.begin(); it1 != ite1; ++it1, ++it2) {
permutation[it1->getIndex()] = it2->getIndex();
}
InternalAdd<DdType::CUDD, ValueType> result(ddManager, this->getCuddAdd().Permute(permutation));
InternalAdd <DdType::CUDD, ValueType> result(ddManager, this->getCuddAdd().Permute(permutation));
delete[] permutation;
return result;
}
template<typename ValueType>
InternalAdd<DdType::CUDD, ValueType> InternalAdd<DdType::CUDD, ValueType>::multiplyMatrix(InternalAdd<DdType::CUDD, ValueType> const& otherMatrix, std::vector<InternalBdd<DdType::CUDD>> const& summationDdVariables) const {
InternalAdd <DdType::CUDD, ValueType> InternalAdd<DdType::CUDD, ValueType>::multiplyMatrix(InternalAdd <DdType::CUDD, ValueType> const &otherMatrix, std::vector <InternalBdd<DdType::CUDD>> const &summationDdVariables) const {
// Create the CUDD summation variables.
std::vector<cudd::ADD> summationAdds;
for (auto const& ddVariable : summationDdVariables) {
std::vector <cudd::ADD> summationAdds;
for (auto const &ddVariable : summationDdVariables) {
summationAdds.push_back(ddVariable.toAdd<ValueType>().getCuddAdd());
}
@ -237,72 +241,72 @@ namespace storm {
// return InternalAdd<DdType::CUDD, ValueType>(ddManager, this->getCuddAdd().Triangle(otherMatrix.getCuddAdd(), summationAdds));
return InternalAdd<DdType::CUDD, ValueType>(ddManager, this->getCuddAdd().MatrixMultiply(otherMatrix.getCuddAdd(), summationAdds));
}
template<typename ValueType>
InternalAdd<DdType::CUDD, ValueType> InternalAdd<DdType::CUDD, ValueType>::multiplyMatrix(InternalBdd<DdType::CUDD> const& otherMatrix, std::vector<InternalBdd<DdType::CUDD>> const& summationDdVariables) const {
InternalAdd <DdType::CUDD, ValueType> InternalAdd<DdType::CUDD, ValueType>::multiplyMatrix(InternalBdd <DdType::CUDD> const &otherMatrix, std::vector <InternalBdd<DdType::CUDD>> const &summationDdVariables) const {
return this->multiplyMatrix(otherMatrix.template toAdd<ValueType>(), summationDdVariables);
}
template<typename ValueType>
InternalBdd<DdType::CUDD> InternalAdd<DdType::CUDD, ValueType>::greater(ValueType const& value) const {
InternalBdd <DdType::CUDD> InternalAdd<DdType::CUDD, ValueType>::greater(ValueType const &value) const {
return InternalBdd<DdType::CUDD>(ddManager, this->getCuddAdd().BddStrictThreshold(value));
}
template<>
InternalBdd<DdType::CUDD> InternalAdd<DdType::CUDD, storm::RationalNumber>::greater(storm::RationalNumber const& value) const {
InternalBdd <DdType::CUDD> InternalAdd<DdType::CUDD, storm::RationalNumber>::greater(storm::RationalNumber const &value) const {
STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Operation not supported.");
}
template<typename ValueType>
InternalBdd<DdType::CUDD> InternalAdd<DdType::CUDD, ValueType>::greaterOrEqual(ValueType const& value) const {
InternalBdd <DdType::CUDD> InternalAdd<DdType::CUDD, ValueType>::greaterOrEqual(ValueType const &value) const {
return InternalBdd<DdType::CUDD>(ddManager, this->getCuddAdd().BddThreshold(value));
}
template<>
InternalBdd<DdType::CUDD> InternalAdd<DdType::CUDD, storm::RationalNumber>::greaterOrEqual(storm::RationalNumber const& value) const {
InternalBdd <DdType::CUDD> InternalAdd<DdType::CUDD, storm::RationalNumber>::greaterOrEqual(storm::RationalNumber const &value) const {
STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Operation not supported.");
}
template<typename ValueType>
InternalBdd<DdType::CUDD> InternalAdd<DdType::CUDD, ValueType>::less(ValueType const& value) const {
InternalBdd <DdType::CUDD> InternalAdd<DdType::CUDD, ValueType>::less(ValueType const &value) const {
return InternalBdd<DdType::CUDD>(ddManager, ~this->getCuddAdd().BddThreshold(value));
}
template<>
InternalBdd<DdType::CUDD> InternalAdd<DdType::CUDD, storm::RationalNumber>::less(storm::RationalNumber const& value) const {
InternalBdd <DdType::CUDD> InternalAdd<DdType::CUDD, storm::RationalNumber>::less(storm::RationalNumber const &value) const {
STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Operation not supported.");
}
template<typename ValueType>
InternalBdd<DdType::CUDD> InternalAdd<DdType::CUDD, ValueType>::lessOrEqual(ValueType const& value) const {
InternalBdd <DdType::CUDD> InternalAdd<DdType::CUDD, ValueType>::lessOrEqual(ValueType const &value) const {
return InternalBdd<DdType::CUDD>(ddManager, ~this->getCuddAdd().BddStrictThreshold(value));
}
template<>
InternalBdd<DdType::CUDD> InternalAdd<DdType::CUDD, storm::RationalNumber>::lessOrEqual(storm::RationalNumber const& value) const {
InternalBdd <DdType::CUDD> InternalAdd<DdType::CUDD, storm::RationalNumber>::lessOrEqual(storm::RationalNumber const &value) const {
STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Operation not supported.");
}
template<typename ValueType>
InternalBdd<DdType::CUDD> InternalAdd<DdType::CUDD, ValueType>::notZero() const {
InternalBdd <DdType::CUDD> InternalAdd<DdType::CUDD, ValueType>::notZero() const {
return InternalBdd<DdType::CUDD>(ddManager, this->getCuddAdd().BddPattern());
}
template<typename ValueType>
InternalAdd<DdType::CUDD, ValueType> InternalAdd<DdType::CUDD, ValueType>::constrain(InternalAdd<DdType::CUDD, ValueType> const& constraint) const {
InternalAdd <DdType::CUDD, ValueType> InternalAdd<DdType::CUDD, ValueType>::constrain(InternalAdd <DdType::CUDD, ValueType> const &constraint) const {
return InternalAdd<DdType::CUDD, ValueType>(ddManager, this->getCuddAdd().Constrain(constraint.getCuddAdd()));
}
template<typename ValueType>
InternalAdd<DdType::CUDD, ValueType> InternalAdd<DdType::CUDD, ValueType>::restrict(InternalAdd<DdType::CUDD, ValueType> const& constraint) const {
InternalAdd <DdType::CUDD, ValueType> InternalAdd<DdType::CUDD, ValueType>::restrict(InternalAdd <DdType::CUDD, ValueType> const &constraint) const {
return InternalAdd<DdType::CUDD, ValueType>(ddManager, this->getCuddAdd().Restrict(constraint.getCuddAdd()));
}
template<typename ValueType>
InternalBdd<DdType::CUDD> InternalAdd<DdType::CUDD, ValueType>::getSupport() const {
InternalBdd <DdType::CUDD> InternalAdd<DdType::CUDD, ValueType>::getSupport() const {
return InternalBdd<DdType::CUDD>(ddManager, this->getCuddAdd().Support());
}
template<typename ValueType>
uint_fast64_t InternalAdd<DdType::CUDD, ValueType>::getNonZeroCount(uint_fast64_t numberOfDdVariables) const {
// If the number of DD variables is zero, CUDD returns a number greater 0 for constant nodes different from
@ -312,93 +316,98 @@ namespace storm {
}
return static_cast<uint_fast64_t>(this->getCuddAdd().CountMinterm(static_cast<int>(numberOfDdVariables)));
}
template<typename ValueType>
uint_fast64_t InternalAdd<DdType::CUDD, ValueType>::getLeafCount() const {
return static_cast<uint_fast64_t>(this->getCuddAdd().CountLeaves());
}
template<typename ValueType>
uint_fast64_t InternalAdd<DdType::CUDD, ValueType>::getNodeCount() const {
return static_cast<uint_fast64_t>(this->getCuddAdd().nodeCount());
}
template<typename ValueType>
ValueType InternalAdd<DdType::CUDD, ValueType>::getMin() const {
cudd::ADD constantMinAdd = this->getCuddAdd().FindMin();
return storm::utility::convertNumber<ValueType>(Cudd_V(constantMinAdd.getNode()));
}
template<typename ValueType>
ValueType InternalAdd<DdType::CUDD, ValueType>::getMax() const {
cudd::ADD constantMaxAdd = this->getCuddAdd().FindMax();
return storm::utility::convertNumber<ValueType>(Cudd_V(constantMaxAdd.getNode()));
}
template<typename ValueType>
ValueType InternalAdd<DdType::CUDD, ValueType>::getValue() const {
return storm::utility::convertNumber<ValueType>(Cudd_V(this->getCuddAdd().getNode()));
}
template<typename ValueType>
bool InternalAdd<DdType::CUDD, ValueType>::isOne() const {
return this->getCuddAdd().IsOne();
}
template<typename ValueType>
bool InternalAdd<DdType::CUDD, ValueType>::isZero() const {
return this->getCuddAdd().IsZero();
}
template<typename ValueType>
bool InternalAdd<DdType::CUDD, ValueType>::isConstant() const {
return Cudd_IsConstant(this->getCuddAdd().getNode());
}
template<typename ValueType>
uint_fast64_t InternalAdd<DdType::CUDD, ValueType>::getIndex() const {
return static_cast<uint_fast64_t>(this->getCuddAdd().NodeReadIndex());
}
template<typename ValueType>
uint_fast64_t InternalAdd<DdType::CUDD, ValueType>::getLevel() const {
return static_cast<uint_fast64_t>(ddManager->getCuddManager().ReadPerm(this->getIndex()));
}
template<typename ValueType>
void InternalAdd<DdType::CUDD, ValueType>::exportToDot(std::string const& filename, std::vector<std::string> const& ddVariableNamesAsStrings, bool showVariablesIfPossible) const {
void InternalAdd<DdType::CUDD, ValueType>::exportToDot(std::string const &filename, std::vector <std::string> const &ddVariableNamesAsStrings, bool showVariablesIfPossible) const {
// Build the name input of the DD.
std::vector<char*> ddNames;
std::vector<char *> ddNames;
std::string ddName("f");
ddNames.push_back(new char[ddName.size() + 1]);
std::copy(ddName.c_str(), ddName.c_str() + 2, ddNames.back());
// Now build the variables names.
std::vector<char*> ddVariableNames;
for (auto const& element : ddVariableNamesAsStrings) {
std::vector<char *> ddVariableNames;
for (auto const &element : ddVariableNamesAsStrings) {
ddVariableNames.push_back(new char[element.size() + 1]);
std::copy(element.c_str(), element.c_str() + element.size() + 1, ddVariableNames.back());
}
// Open the file, dump the DD and close it again.
FILE* filePointer = fopen(filename.c_str() , "w");
std::vector<cudd::ADD> cuddAddVector = { this->getCuddAdd() };
FILE *filePointer = fopen(filename.c_str(), "w");
std::vector <cudd::ADD> cuddAddVector = {this->getCuddAdd()};
if (showVariablesIfPossible) {
ddManager->getCuddManager().DumpDot(cuddAddVector, ddVariableNames.data(), &ddNames[0], filePointer);
} else {
ddManager->getCuddManager().DumpDot(cuddAddVector, nullptr, &ddNames[0], filePointer);
}
fclose(filePointer);
// Finally, delete the names.
for (char* element : ddNames) {
for (char *element : ddNames) {
delete[] element;
}
for (char* element : ddVariableNames) {
for (char *element : ddVariableNames) {
delete[] element;
}
}
template<typename ValueType>
void InternalAdd<DdType::CUDD, ValueType>::exportToText(std::string const &) const {
STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Operation not supported");
}
template<typename ValueType>
AddIterator<DdType::CUDD, ValueType> InternalAdd<DdType::CUDD, ValueType>::begin(DdManager<DdType::CUDD> const& fullDdManager, InternalBdd<DdType::CUDD> const&, uint_fast64_t, std::set<storm::expressions::Variable> const& metaVariables, bool enumerateDontCareMetaVariables) const {
int* cube;

8
src/storm/storage/dd/cudd/InternalCuddAdd.h

@ -515,7 +515,13 @@ namespace storm {
* @param ddVariableNamesAsString The names of the DD variables to display in the dot file.
*/
void exportToDot(std::string const& filename, std::vector<std::string> const& ddVariableNamesAsStrings, bool showVariablesIfPossible = true) const;
/*!
* Exports the DD to the given file in a textual format as specified in Sylvan.
*
* @param filename The name of the file to which the DD is to be exported.
*/
void exportToText(std::string const& filename) const;
/*!
* Retrieves an iterator that points to the first meta variable assignment with a non-zero function value.
*

5
src/storm/storage/dd/cudd/InternalCuddBdd.cpp

@ -9,6 +9,7 @@
#include "storm/storage/PairHash.h"
#include "storm/utility/macros.h"
#include "storm/exceptions/NotSupportedException.h"
namespace storm {
namespace dd {
@ -211,6 +212,10 @@ namespace storm {
delete element;
}
}
void InternalBdd<DdType::CUDD>::exportToText(std::string const&) const {
STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Operation not supported");
}
cudd::BDD InternalBdd<DdType::CUDD>::getCuddBdd() const {
return this->cuddBdd;

9
src/storm/storage/dd/cudd/InternalCuddBdd.h

@ -328,7 +328,14 @@ namespace storm {
* @param ddVariableNamesAsStrings The names of the variables to display in the dot file.
*/
void exportToDot(std::string const& filename, std::vector<std::string> const& ddVariableNamesAsStrings, bool showVariablesIfPossible = true) const;
/*!
* Exports the DD to the given file in a textual format as specified in Sylvan.
*
* @param filename The name of the file to which the DD is to be exported.
*/
void exportToText(std::string const& filename) const;
/*!
* Converts a BDD to an equivalent ADD.
*

10
src/storm/storage/dd/sylvan/InternalSylvanAdd.cpp

@ -802,10 +802,18 @@ namespace storm {
template<typename ValueType>
void InternalAdd<DdType::Sylvan, ValueType>::exportToDot(std::string const& filename, std::vector<std::string> const&, bool) const {
// Open the file, dump the DD and close it again.
FILE* filePointer = fopen(filename.c_str() , "w");
FILE* filePointer = fopen(filename.c_str() , "a+");
this->sylvanMtbdd.PrintDot(filePointer);
fclose(filePointer);
}
template<typename ValueType>
void InternalAdd<DdType::Sylvan, ValueType>::exportToText(std::string const& filename) const {
// Open the file, dump the DD and close it again.
FILE* filePointer = fopen(filename.c_str() , "a+");
this->sylvanMtbdd.PrintText(filePointer);
fclose(filePointer);
}
template<typename ValueType>
AddIterator<DdType::Sylvan, ValueType> InternalAdd<DdType::Sylvan, ValueType>::begin(DdManager<DdType::Sylvan> const& fullDdManager, InternalBdd<DdType::Sylvan> const& variableCube, uint_fast64_t numberOfDdVariables, std::set<storm::expressions::Variable> const& metaVariables, bool enumerateDontCareMetaVariables) const {

9
src/storm/storage/dd/sylvan/InternalSylvanAdd.h

@ -506,6 +506,13 @@ namespace storm {
* @param ddVariableNamesAsString The names of the DD variables to display in the dot file.
*/
void exportToDot(std::string const& filename, std::vector<std::string> const& ddVariableNamesAsStrings, bool showVariablesIfPossible = true) const;
/*!
* Exports the DD to the given file in a textual format as specified in Sylvan.
*
* @param filename The name of the file to which the DD is to be exported.
*/
void exportToText(std::string const& filename) const;
/*!
* Retrieves an iterator that points to the first meta variable assignment with a non-zero function value.
@ -778,7 +785,7 @@ namespace storm {
#ifdef STORM_HAVE_CARL
/*!
* Retrieves the sylvan representation of the given storm::RatíonalFunction.
* Retrieves the sylvan representation of the given storm::Rat�onalFunction.
*
* @return The sylvan node for the given value.
*/

8
src/storm/storage/dd/sylvan/InternalSylvanBdd.cpp

@ -233,10 +233,16 @@ namespace storm {
}
void InternalBdd<DdType::Sylvan>::exportToDot(std::string const& filename, std::vector<std::string> const&, bool) const {
FILE* filePointer = fopen(filename.c_str() , "w");
FILE* filePointer = fopen(filename.c_str() , "a+");
this->sylvanBdd.PrintDot(filePointer);
fclose(filePointer);
}
void InternalBdd<DdType::Sylvan>::exportToText(std::string const& filename) const {
FILE* filePointer = fopen(filename.c_str() , "a+");
this->sylvanBdd.PrintText(filePointer);
fclose(filePointer);
}
sylvan::Bdd& InternalBdd<DdType::Sylvan>::getSylvanBdd() {
return sylvanBdd;

9
src/storm/storage/dd/sylvan/InternalSylvanBdd.h

@ -317,7 +317,14 @@ namespace storm {
* @param ddVariableNamesAsStrings The names of the variables to display in the dot file.
*/
void exportToDot(std::string const& filename, std::vector<std::string> const& ddVariableNamesAsStrings, bool showVariablesIfPossible = true) const;
/*!
* Exports the DD to the given file in a textual format as specified in Sylvan.
*
* @param filename The name of the file to which the DD is to be exported.
*/
void exportToText(std::string const& filename) const;
/*!
* Converts a BDD to an equivalent ADD.
*

4
src/storm/storage/sparse/ChoiceOrigins.cpp

@ -73,6 +73,10 @@ namespace storm {
return cloneWithNewIndexToIdentifierMapping(std::move(indexToIdentifierMapping));
}
void ChoiceOrigins::clearOriginOfChoice(uint_fast64_t choiceIndex) {
indexToIdentifier[choiceIndex] = getIdentifierForChoicesWithNoOrigin();
}
std::shared_ptr<ChoiceOrigins> ChoiceOrigins::selectChoices(std::vector<uint_fast64_t> const& selectedChoices) const {
std::vector<uint_fast64_t> indexToIdentifierMapping;
indexToIdentifierMapping.reserve(selectedChoices.size());

7
src/storm/storage/sparse/ChoiceOrigins.h

@ -68,6 +68,11 @@ namespace storm {
*/
std::shared_ptr<ChoiceOrigins> selectChoices(storm::storage::BitVector const& selectedChoices) const;
/*
* Removes origin information of the given choice.
*/
void clearOriginOfChoice(uint_fast64_t choiceIndex);
/*
* Derive new choice origins from this by selecting the given choices.
* If an invalid choice index is selected, the corresponding choice will get the identifier for choices with no origin.
@ -90,7 +95,7 @@ namespace storm {
*/
virtual void computeIdentifierInfos() const = 0;
std::vector<uint_fast64_t> const indexToIdentifier;
std::vector<uint_fast64_t> indexToIdentifier;
// cached identifier infos might be empty if identifiers have not been generated yet.
mutable std::vector<std::string> identifierToInfo;

95
src/storm/transformer/SubsystemBuilder.cpp

@ -16,6 +16,7 @@
#include "storm/utility/builder.h"
#include "storm/exceptions/InvalidArgumentException.h"
#include "storm/exceptions/InvalidOperationException.h"
#include "storm/exceptions/UnexpectedException.h"
namespace storm {
@ -37,6 +38,7 @@ namespace storm {
} else {
STORM_LOG_THROW(originalModel.isOfType(storm::models::ModelType::Dtmc) || originalModel.isOfType(storm::models::ModelType::Mdp), storm::exceptions::UnexpectedException, "Unexpected model type.");
}
// Nothing to be done if the model has deadlock States
}
template<typename RewardModelType>
@ -59,6 +61,7 @@ namespace storm {
template <typename ValueType, typename RewardModelType>
SubsystemBuilderReturnType<ValueType, RewardModelType> internalBuildSubsystem(storm::models::sparse::Model<ValueType, RewardModelType> const& originalModel, storm::storage::BitVector const& subsystemStates, storm::storage::BitVector const& subsystemActions, SubsystemBuilderOptions const& options ) {
auto const& groupIndices = originalModel.getTransitionMatrix().getRowGroupIndices();
SubsystemBuilderReturnType<ValueType, RewardModelType> result;
uint_fast64_t subsystemStateCount = subsystemStates.getNumberOfSetBits();
if (options.buildStateMapping) {
@ -67,21 +70,20 @@ namespace storm {
if (options.buildActionMapping) {
result.newToOldActionIndexMapping.reserve(subsystemActions.getNumberOfSetBits());
}
if (options.buildKeptActions) {
result.keptActions = storm::storage::BitVector(originalModel.getTransitionMatrix().getRowCount(), false);
storm::storage::BitVector deadlockStates;
if (options.fixDeadlocks) {
deadlockStates.resize(subsystemStates.size(), false);
}
// Get the set of actions that stay in the subsystem.
// Also establish the mappings if requested.
storm::storage::BitVector keptActions(originalModel.getTransitionMatrix().getRowCount(), false);
for (auto subsysState : subsystemStates) {
if (options.buildStateMapping) {
result.newToOldStateIndexMapping.push_back(subsysState);
}
bool keepAtLeastOneAction = !options.checkTransitionsOutside; // For debug mode only.
bool atLeastOneActionSelected = false; // For debug mode only.
for (uint_fast64_t row = subsystemActions.getNextSetIndex(originalModel.getTransitionMatrix().getRowGroupIndices()[subsysState]); row < originalModel.getTransitionMatrix().getRowGroupIndices()[subsysState+1]; row = subsystemActions.getNextSetIndex(row+1)) {
bool hasDeadlock = true;
for (uint_fast64_t row = subsystemActions.getNextSetIndex(groupIndices[subsysState]); row < groupIndices[subsysState+1]; row = subsystemActions.getNextSetIndex(row + 1)) {
bool allRowEntriesStayInSubsys = true;
atLeastOneActionSelected = true;
if (options.checkTransitionsOutside) {
for (auto const &entry : originalModel.getTransitionMatrix().getRow(row)) {
if (!subsystemStates.get(entry.getColumn())) {
@ -91,42 +93,87 @@ namespace storm {
}
}
if (allRowEntriesStayInSubsys) {
keepAtLeastOneAction = true;
if (options.buildActionMapping) {
result.newToOldActionIndexMapping.push_back(row);
}
keptActions.set(row, true);
hasDeadlock = false;
}
}
if (hasDeadlock) {
STORM_LOG_THROW(options.fixDeadlocks, storm::exceptions::InvalidOperationException, "Expected that in each state, at least one action is selected. Got a deadlock state instead. (violated at " << subsysState << ")");
if (options.buildActionMapping) {
result.newToOldActionIndexMapping.push_back(row);
}
if (options.buildKeptActions) {
result.keptActions.set(row, allRowEntriesStayInSubsys);
result.newToOldActionIndexMapping.push_back(std::numeric_limits<uint64_t>::max());
}
deadlockStates.set(subsysState);
}
if (!atLeastOneActionSelected && options.fixDeadlocks) {
}
STORM_LOG_ASSERT(atLeastOneActionSelected, "Expected that in each state, at least one action is selected. (violated at " << subsysState << ")");
STORM_LOG_ASSERT(keepAtLeastOneAction, "Expected that in each state, at least one action is preserved at least one action is selected. (violated at " << subsysState << ")");
}
// If we have deadlock states we keep an action in each rowgroup of a deadlock states.
bool hasDeadlockStates = !deadlockStates.empty();
if (options.buildKeptActions) {
// store them now, before changing them.
result.keptActions = keptActions;
}
for (auto const& deadlockState : deadlockStates) {
keptActions.set(groupIndices[deadlockState], true);
}
// Transform the components of the model
storm::storage::sparse::ModelComponents<ValueType, RewardModelType> components;
components.transitionMatrix = originalModel.getTransitionMatrix().getSubmatrix(false, result.keptActions, subsystemStates);
if (hasDeadlockStates) {
// make deadlock choices a selfloop
components.transitionMatrix = originalModel.getTransitionMatrix();
components.transitionMatrix.makeRowGroupsAbsorbing(deadlockStates);
components.transitionMatrix.dropZeroEntries();
components.transitionMatrix = components.transitionMatrix.getSubmatrix(false, keptActions, subsystemStates);
} else {
components.transitionMatrix = originalModel.getTransitionMatrix().getSubmatrix(false, keptActions, subsystemStates);
}
components.stateLabeling = originalModel.getStateLabeling().getSubLabeling(subsystemStates);
for (auto const& rewardModel : originalModel.getRewardModels()){
components.rewardModels.insert(std::make_pair(rewardModel.first, transformRewardModel(rewardModel.second, subsystemStates, result.keptActions)));
components.rewardModels.insert(std::make_pair(rewardModel.first, transformRewardModel(rewardModel.second, subsystemStates, keptActions)));
}
if (originalModel.hasChoiceLabeling()) {
components.choiceLabeling = originalModel.getChoiceLabeling().getSubLabeling(result.keptActions);
components.choiceLabeling = originalModel.getChoiceLabeling().getSubLabeling(keptActions);
}
if (originalModel.hasStateValuations()) {
components.stateValuations = originalModel.getStateValuations().selectStates(subsystemStates);
}
if (originalModel.hasChoiceOrigins()) {
components.choiceOrigins = originalModel.getChoiceOrigins()->selectChoices(result.keptActions);
components.choiceOrigins = originalModel.getChoiceOrigins()->selectChoices(keptActions);
}
if (hasDeadlockStates) {
auto subDeadlockStates = deadlockStates % subsystemStates;
assert(deadlockStates.getNumberOfSetBits() == subDeadlockStates.getNumberOfSetBits());
// erase rewards, choice labels, choice origins
for (auto& rewModel : components.rewardModels) {
for (auto const& state : subDeadlockStates) {
rewModel.second.clearRewardAtState(state, components.transitionMatrix);
}
}
if (components.choiceLabeling) {
storm::storage::BitVector nonDeadlockChoices(components.transitionMatrix.getRowCount(), true);
for (auto const& state : subDeadlockStates) {
auto const& choice = components.transitionMatrix.getRowGroupIndices()[state];
nonDeadlockChoices.set(choice, false);
}
for (auto const& label : components.choiceLabeling.get().getLabels()) {
components.choiceLabeling->setChoices(label, components.choiceLabeling->getChoices(label) & nonDeadlockChoices);
}
}
if (components.choiceOrigins) {
for (auto const& state : subDeadlockStates) {
auto const& choice = components.transitionMatrix.getRowGroupIndices()[state];
components.choiceOrigins.get()->clearOriginOfChoice(choice);
}
}
}
transformModelSpecificComponents<ValueType, RewardModelType>(originalModel, subsystemStates, components);
result.model = storm::utility::builder::buildModelFromComponents(originalModel.getType(), std::move(components));
STORM_LOG_DEBUG("Subsystem Builder is done. Resulting model has " << result.model->getNumberOfStates() << " states.");
return result;
}

9
src/storm/transformer/SubsystemBuilder.h

@ -17,6 +17,7 @@ namespace storm {
// Gives for each state in the resulting model the corresponding state in the original model.
std::vector<uint_fast64_t> newToOldStateIndexMapping;
// Gives for each action in the resulting model the corresponding action in the original model.
// If this action was introduced to fix a deadlock, it will get index std::numeric_limits<uint64_t>::max()
std::vector<uint64_t> newToOldActionIndexMapping;
// marks the actions of the original model that are still available in the subsystem
storm::storage::BitVector keptActions;
@ -27,7 +28,7 @@ namespace storm {
bool buildStateMapping = true;
bool buildActionMapping = false;
bool buildKeptActions = true;
bool fixDeadlocks = true;
bool fixDeadlocks = false;
};
/*
@ -40,7 +41,9 @@ namespace storm {
* * it originates from a state that is part of the subsystem AND
* * it does not contain a transition leading to a state outside of the subsystem.
*
* If this introduces a deadlock state (i.e., a state without an action) an exception is thrown.
* If this introduces a deadlock state (i.e., a state without an action) it is either
* * fixed by inserting a selfloop (if fixDeadlocks is true) or
* * an exception is thrown (otherwise).
*
* @param originalModel The original model.
* @param subsystemStates The selected states.
@ -49,5 +52,7 @@ namespace storm {
*/
template <typename ValueType, typename RewardModelType = storm::models::sparse::StandardRewardModel<ValueType>>
SubsystemBuilderReturnType<ValueType, RewardModelType> buildSubsystem(storm::models::sparse::Model<ValueType, RewardModelType> const& originalModel, storm::storage::BitVector const& subsystemStates, storm::storage::BitVector const& subsystemActions, bool keepUnreachableStates = true, SubsystemBuilderOptions options = SubsystemBuilderOptions());
}
}

35
src/storm/utility/DDEncodingExporter.cpp

@ -0,0 +1,35 @@
#include "storm/utility/DDEncodingExporter.h"
#include "storm/utility/file.h"
#include "storm/models/symbolic/StandardRewardModel.h"
namespace storm {
namespace exporter {
template<storm::dd::DdType Type, typename ValueType>
void explicitExportSymbolicModel(std::string const& filename, std::shared_ptr <storm::models::symbolic::Model<Type, ValueType>> symbolicModel) {
std::ofstream filestream;
storm::utility::openFile(filename,filestream);
filestream << "// storm exported dd" << std::endl;
filestream << "%transitions" << std::endl;
storm::utility::closeFile(filestream);
symbolicModel->getTransitionMatrix().exportToText(filename);
storm::utility::openFile(filename,filestream,true,true);
filestream << "%initial" << std::endl;
storm::utility::closeFile(filestream);
symbolicModel->getInitialStates().template toAdd<ValueType>().exportToText(filename);
for(auto const& label : symbolicModel->getLabels()) {
storm::utility::openFile(filename,filestream,true,true);
filestream << std::endl << "%label " << label << std::endl;
storm::utility::closeFile(filestream);
symbolicModel->getStates(label).template toAdd<ValueType>().exportToText(filename);
}
}
template void explicitExportSymbolicModel<storm::dd::DdType::CUDD,double>(std::string const&, std::shared_ptr<storm::models::symbolic::Model<storm::dd::DdType::CUDD, double>> sparseModel);
template void explicitExportSymbolicModel<storm::dd::DdType::Sylvan,double>(std::string const&, std::shared_ptr<storm::models::symbolic::Model<storm::dd::DdType::Sylvan, double>> sparseModel);
template void explicitExportSymbolicModel<storm::dd::DdType::Sylvan, storm::RationalNumber>(std::string const&, std::shared_ptr<storm::models::symbolic::Model<storm::dd::DdType::Sylvan, storm::RationalNumber>> sparseModel);
template void explicitExportSymbolicModel<storm::dd::DdType::Sylvan, storm::RationalFunction>(std::string const&, std::shared_ptr<storm::models::symbolic::Model<storm::dd::DdType::Sylvan, storm::RationalFunction>> sparseModel);
}
}

20
src/storm/utility/DDEncodingExporter.h

@ -0,0 +1,20 @@
#pragma once
#include "storm/models/symbolic/Model.h"
namespace storm {
namespace exporter {
/*!
* Exports a sparse model into the explicit drdd format.
*
* @param filename File path
* @param symbolicModel Model to export
*/
template<storm::dd::DdType Type,typename ValueType>
void explicitExportSymbolicModel(std::string const& filename, std::shared_ptr<storm::models::symbolic::Model<Type,ValueType>> symbolicModel);
}
}

11
src/storm/utility/DirectEncodingExporter.cpp

@ -1,3 +1,4 @@
#include <storm/exceptions/NotSupportedException.h>
#include "DirectEncodingExporter.h"
#include "storm/adapters/RationalFunctionAdapter.h"
@ -88,9 +89,15 @@ namespace storm {
os << " {" << sparseModel->template as<storm::models::sparse::Pomdp<ValueType>>()->getObservation(group) << "}";
}
// Write labels
// Write labels. Only labels with a whitespace are put in (double) quotation marks.
for(auto const& label : sparseModel->getStateLabeling().getLabelsOfState(group)) {
os << " " << label;
STORM_LOG_THROW(std::count( label.begin(), label.end(), '\"' ) == 0, storm::exceptions::NotSupportedException, "Labels with quotation marks are not supported in the DRN format and therefore may not be exported.");
// TODO consider escaping the quotation marks. Not sure whether that is a good idea.
if (std::count_if( label.begin(), label.end(), isspace ) > 0) {
os << " \"" << label << "\"";
} else {
os << " " << label;
}
}
os << std::endl;

12
src/storm/utility/graph.cpp

@ -37,16 +37,22 @@ namespace storm {
uint_fast64_t numberOfStates = transitionMatrix.getRowGroupCount();
// Initialize the stack used for the DFS with the states.
std::vector<uint_fast64_t> stack(initialStates.begin(), initialStates.end());
std::vector<uint_fast64_t> stack;
stack.reserve(initialStates.size());
for (auto const& state : initialStates) {
if (constraintStates.get(state)) {
stack.push_back(state);
}
}
// Initialize the stack for the step bound, if the number of steps is bounded.
std::vector<uint_fast64_t> stepStack;
std::vector<uint_fast64_t> remainingSteps;
if (useStepBound) {
stepStack.reserve(numberOfStates);
stepStack.insert(stepStack.begin(), initialStates.getNumberOfSetBits(), maximalSteps);
stepStack.insert(stepStack.begin(), stack.size(), maximalSteps);
remainingSteps.resize(numberOfStates);
for (auto state : initialStates) {
for (auto state : stack) {
remainingSteps[state] = maximalSteps;
}
}

1
src/storm/utility/graph.h

@ -60,6 +60,7 @@ namespace storm {
* Performs a forward depth-first search through the underlying graph structure to identify the states that
* are reachable from the given set only passing through a constrained set of states until some target
* have been reached.
* If an initial state or a (constrained-reachable) target state is not in the constrained set, it will be added to the reachable states but not explored.
*
* @param transitionMatrix The transition relation of the graph structure to search.
* @param initialStates The set of states from which to start the search.

Loading…
Cancel
Save