Browse Source

Merge remote-tracking branch 'origin/master' into reward-bounded-multi-objective

tempestpy_adaptions
TimQu 7 years ago
parent
commit
26efa18d32
  1. 1
      resources/3rdparty/CMakeLists.txt
  2. 4
      src/storm/modelchecker/prctl/helper/HybridMdpPrctlHelper.cpp
  3. 24
      src/storm/storage/dd/Add.cpp
  4. 3
      src/storm/storage/dd/Add.h
  5. 17
      src/storm/storage/dd/bisimulation/MdpPartitionRefiner.cpp
  6. 6
      src/storm/storage/dd/bisimulation/MdpPartitionRefiner.h
  7. 2
      src/storm/storage/dd/bisimulation/Partition.cpp
  8. 15
      src/storm/storage/dd/bisimulation/PartitionRefiner.cpp
  9. 3
      src/storm/storage/dd/bisimulation/PartitionRefiner.h
  10. 9
      src/storm/storage/dd/bisimulation/QuotientExtractor.cpp
  11. 4
      src/storm/storage/dd/sylvan/InternalSylvanAdd.cpp
  12. 2
      src/storm/storage/geometry/nativepolytopeconversion/QuickHull.cpp
  13. 2
      src/storm/utility/KwekMehlhorn.cpp
  14. 24
      src/test/storm/storage/SymbolicBisimulationDecompositionTest.cpp

1
resources/3rdparty/CMakeLists.txt

@ -27,6 +27,7 @@ ExternalProject_Get_Property(l3pp_ext source_dir)
set(l3pp_INCLUDE "${source_dir}/")
add_imported_library_interface(l3pp "${l3pp_INCLUDE}")
list(APPEND STORM_DEP_TARGETS l3pp)
add_dependencies(l3pp l3pp_ext)
#############################################################
##

4
src/storm/modelchecker/prctl/helper/HybridMdpPrctlHelper.cpp

@ -530,11 +530,13 @@ namespace storm {
// Then compute the reward vector to use in the computation.
storm::dd::Add<DdType, ValueType> subvector = rewardModel.getTotalRewardVector(maybeStatesAdd, choiceFilterAdd, submatrix, model.getColumnVariables());
std::vector<uint_fast64_t> rowGroupSizes = (submatrix.notZero().existsAbstract(model.getColumnVariables()) || subvector.notZero()).template toAdd<uint_fast64_t>().sumAbstract(model.getNondeterminismVariables()).toVector(odd);
// Finally cut away all columns targeting non-maybe states (or non-(maybe or target) states, respectively).
submatrix *= extendMaybeStates ? maybeStatesWithTargetStates.swapVariables(model.getRowColumnMetaVariablePairs()).template toAdd<ValueType>() : maybeStatesAdd.swapVariables(model.getRowColumnMetaVariablePairs());
// Translate the symbolic matrix/vector to their explicit representations.
std::pair<storm::storage::SparseMatrix<ValueType>, std::vector<ValueType>> explicitRepresentation = submatrix.toMatrixVector(subvector, model.getNondeterminismVariables(), odd, odd);
std::pair<storm::storage::SparseMatrix<ValueType>, std::vector<ValueType>> explicitRepresentation = submatrix.toMatrixVector(std::move(rowGroupSizes), subvector, model.getRowVariables(), model.getColumnVariables(), model.getNondeterminismVariables(), odd, odd);
// Fulfill the solver's requirements.
SolverRequirementsData<ValueType> solverRequirementsData;

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

@ -799,6 +799,14 @@ namespace storm {
template<DdType LibraryType, typename ValueType>
std::pair<storm::storage::SparseMatrix<ValueType>, std::vector<ValueType>> Add<LibraryType, ValueType>::toMatrixVector(storm::dd::Add<LibraryType, ValueType> const& vector, std::set<storm::expressions::Variable> const& rowMetaVariables, std::set<storm::expressions::Variable> const& columnMetaVariables, std::set<storm::expressions::Variable> const& groupMetaVariables, storm::dd::Odd const& rowOdd, storm::dd::Odd const& columnOdd) const {
// Count how many choices each row group has.
std::vector<uint_fast64_t> rowGroupIndices = (this->notZero().existsAbstract(columnMetaVariables) || vector.notZero()).template toAdd<uint_fast64_t>().sumAbstract(groupMetaVariables).toVector(rowOdd);
return toMatrixVector(std::move(rowGroupIndices), vector, rowMetaVariables, columnMetaVariables, groupMetaVariables, rowOdd, columnOdd);
}
template<DdType LibraryType, typename ValueType>
std::pair<storm::storage::SparseMatrix<ValueType>, std::vector<ValueType>> Add<LibraryType, ValueType>::toMatrixVector(std::vector<uint_fast64_t>&& rowGroupIndices, storm::dd::Add<LibraryType, ValueType> const& vector, std::set<storm::expressions::Variable> const& rowMetaVariables, std::set<storm::expressions::Variable> const& columnMetaVariables, std::set<storm::expressions::Variable> const& groupMetaVariables, storm::dd::Odd const& rowOdd, storm::dd::Odd const& columnOdd) const {
std::vector<uint_fast64_t> ddRowVariableIndices;
std::vector<uint_fast64_t> ddColumnVariableIndices;
std::vector<uint_fast64_t> ddGroupVariableIndices;
@ -829,9 +837,6 @@ namespace storm {
std::sort(ddGroupVariableIndices.begin(), ddGroupVariableIndices.end());
Bdd<LibraryType> columnVariableCube = Bdd<LibraryType>::getCube(this->getDdManager(), columnMetaVariables);
// Count how many choices each row group has.
std::vector<uint_fast64_t> rowGroupIndices = (this->notZero().existsAbstract(columnMetaVariables) || vector.notZero()).template toAdd<uint_fast64_t>().sumAbstract(groupMetaVariables).toVector(rowOdd);
// Transform the row group sizes to the actual row group indices.
rowGroupIndices.resize(rowGroupIndices.size() + 1);
@ -853,7 +858,7 @@ namespace storm {
for (auto const& internalAdd : internalAddGroups) {
groups.push_back(std::make_pair(Add<LibraryType, ValueType>(this->getDdManager(), internalAdd.first, rowAndColumnMetaVariables), Add<LibraryType, ValueType>(this->getDdManager(), internalAdd.second, rowMetaVariables)));
}
// Create the actual storage for the non-zero entries.
std::vector<storm::storage::MatrixEntry<uint_fast64_t, ValueType>> columnsAndValues(this->getNonZeroCount());
@ -866,12 +871,12 @@ namespace storm {
std::pair<Add<LibraryType, ValueType>, Add<LibraryType, ValueType>> const& ddPair = groups[i];
Bdd<LibraryType> matrixDdNotZero = ddPair.first.notZero();
Bdd<LibraryType> vectorDdNotZero = ddPair.second.notZero();
std::vector<uint64_t> tmpRowIndications = matrixDdNotZero.template toAdd<uint_fast64_t>().sumAbstract(columnMetaVariables).toVector(rowOdd);
for (uint64_t offset = 0; offset < tmpRowIndications.size(); ++offset) {
rowIndications[rowGroupIndices[offset]] += tmpRowIndications[offset];
}
ddPair.second.internalAdd.composeWithExplicitVector(rowOdd, ddRowVariableIndices, rowGroupIndices, explicitVector, std::plus<ValueType>());
statesWithGroupEnabled[i] = (matrixDdNotZero.existsAbstract(columnMetaVariables) || vectorDdNotZero).template toAdd<uint_fast64_t>();
@ -881,7 +886,7 @@ namespace storm {
// Since we modified the rowGroupIndices, we need to restore the correct values.
stateToRowGroupCount.composeWithExplicitVector(rowOdd, ddRowVariableIndices, rowGroupIndices, std::minus<uint_fast64_t>());
// Now that we computed the number of entries in each row, compute the corresponding offsets in the entry vector.
tmp = 0;
tmp2 = 0;
@ -908,10 +913,11 @@ namespace storm {
rowIndications[i] = rowIndications[i - 1];
}
rowIndications[0] = 0;
return std::make_pair(storm::storage::SparseMatrix<ValueType>(columnOdd.getTotalOffset(), std::move(rowIndications), std::move(columnsAndValues), std::move(rowGroupIndices)), std::move(explicitVector));
}
}
template<DdType LibraryType, typename ValueType>
void Add<LibraryType, ValueType>::exportToDot(std::string const& filename, bool showVariablesIfPossible) const {
internalAdd.exportToDot(filename, this->getDdManager().getDdVariableNames(), showVariablesIfPossible);

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

@ -639,7 +639,8 @@ namespace storm {
* @return The matrix that is represented by this ADD.
*/
std::pair<storm::storage::SparseMatrix<ValueType>, std::vector<ValueType>> toMatrixVector(storm::dd::Add<LibraryType, ValueType> const& vector, std::set<storm::expressions::Variable> const& groupMetaVariables, storm::dd::Odd const& rowOdd, storm::dd::Odd const& columnOdd) const;
std::pair<storm::storage::SparseMatrix<ValueType>, std::vector<ValueType>> toMatrixVector(std::vector<uint_fast64_t>&& rowGroupSizes, storm::dd::Add<LibraryType, ValueType> const& vector, std::set<storm::expressions::Variable> const& rowMetaVariables, std::set<storm::expressions::Variable> const& columnMetaVariables, std::set<storm::expressions::Variable> const& groupMetaVariables, storm::dd::Odd const& rowOdd, storm::dd::Odd const& columnOdd) const;
/*!
* Exports the DD to the given file in the dot format.
*

17
src/storm/storage/dd/bisimulation/MdpPartitionRefiner.cpp

@ -8,7 +8,7 @@ namespace storm {
namespace bisimulation {
template<storm::dd::DdType DdType, typename ValueType>
MdpPartitionRefiner<DdType, ValueType>::MdpPartitionRefiner(storm::models::symbolic::Mdp<DdType, ValueType> const& mdp, Partition<DdType, ValueType> const& initialStatePartition) : PartitionRefiner<DdType, ValueType>(mdp, initialStatePartition), choicePartition(Partition<DdType, ValueType>::createTrivialChoicePartition(mdp, initialStatePartition.getBlockVariables())), stateSignatureComputer(mdp.getQualitativeTransitionMatrix(), mdp.getColumnAndNondeterminismVariables(), SignatureMode::Qualitative, true), stateSignatureRefiner(mdp.getManager(), this->statePartition.getBlockVariable(), mdp.getRowVariables(), true) {
MdpPartitionRefiner<DdType, ValueType>::MdpPartitionRefiner(storm::models::symbolic::Mdp<DdType, ValueType> const& mdp, Partition<DdType, ValueType> const& initialStatePartition) : PartitionRefiner<DdType, ValueType>(mdp, initialStatePartition), mdp(mdp), choicePartition(Partition<DdType, ValueType>::createTrivialChoicePartition(mdp, initialStatePartition.getBlockVariables())), stateSignatureRefiner(mdp.getManager(), this->statePartition.getBlockVariable(), mdp.getRowVariables(), true) {
// Intentionally left empty.
}
@ -29,10 +29,19 @@ namespace storm {
} else {
this->choicePartition = newChoicePartition;
// If the choice partition changed, refine the state partition. Use qualitative mode we must properly abstract from choice counts.
// Compute state signatures.
storm::dd::Bdd<DdType> choicePartitionAsBdd;
if (this->choicePartition.storedAsBdd()) {
choicePartitionAsBdd = this->choicePartition.asBdd();
} else {
choicePartitionAsBdd = this->choicePartition.asAdd().notZero();
}
Signature<DdType, ValueType> stateSignature(choicePartitionAsBdd.existsAbstract(mdp.getNondeterminismVariables()).template toAdd<ValueType>());
// If the choice partition changed, refine the state partition.
STORM_LOG_TRACE("Refining state partition.");
Partition<DdType, ValueType> newStatePartition = this->internalRefine(this->stateSignatureComputer, this->stateSignatureRefiner, this->statePartition, this->choicePartition, SignatureMode::Qualitative);
Partition<DdType, ValueType> newStatePartition = this->internalRefine(stateSignature, this->stateSignatureRefiner, this->statePartition);
if (newStatePartition == this->statePartition) {
this->status = Status::FixedPoint;
return false;

6
src/storm/storage/dd/bisimulation/MdpPartitionRefiner.h

@ -34,12 +34,12 @@ namespace storm {
private:
virtual bool refineWrtStateActionRewards(storm::dd::Add<DdType, ValueType> const& stateActionRewards) override;
// The model to refine.
storm::models::symbolic::Mdp<DdType, ValueType> const& mdp;
// The choice partition in the refinement process.
Partition<DdType, ValueType> choicePartition;
// The object used to compute the state signatures.
SignatureComputer<DdType, ValueType> stateSignatureComputer;
// The object used to refine the state partition based on the signatures.
SignatureRefiner<DdType, ValueType> stateSignatureRefiner;
};

2
src/storm/storage/dd/bisimulation/Partition.cpp

@ -100,7 +100,7 @@ namespace storm {
template<storm::dd::DdType DdType, typename ValueType>
Partition<DdType, ValueType> Partition<DdType, ValueType>::createTrivialChoicePartition(storm::models::symbolic::NondeterministicModel<DdType, ValueType> const& model, std::pair<storm::expressions::Variable, storm::expressions::Variable> const& blockVariables) {
storm::dd::Bdd<DdType> choicePartitionBdd = (!model.getIllegalMask() && model.getReachableStates()).renameVariables(model.getRowVariables(), model.getColumnVariables()) && model.getManager().getEncoding(blockVariables.first, 0, false);
storm::dd::Bdd<DdType> choicePartitionBdd = (!model.getIllegalMask() && model.getReachableStates()) && model.getManager().getEncoding(blockVariables.first, 0, false);
// Store the partition as an ADD only in the case of CUDD.
if (DdType == storm::dd::DdType::CUDD) {

15
src/storm/storage/dd/bisimulation/PartitionRefiner.cpp

@ -64,14 +64,27 @@ namespace storm {
}
auto totalTimeInRefinement = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - start).count();
++refinements;
STORM_LOG_TRACE("Refinement " << refinements << " produced " << newPartition.getNumberOfBlocks() << " blocks and was completed in " << totalTimeInRefinement << "ms (signature: " << signatureTime << "ms, refinement: " << refinementTime << "ms).");
++refinements;
return newPartition;
} else {
return oldPartition;
}
}
template <storm::dd::DdType DdType, typename ValueType>
Partition<DdType, ValueType> PartitionRefiner<DdType, ValueType>::internalRefine(Signature<DdType, ValueType> const& signature, SignatureRefiner<DdType, ValueType>& signatureRefiner, Partition<DdType, ValueType> const& oldPartition) {
STORM_LOG_TRACE("Signature " << refinements << " DD has " << signature.getSignatureAdd().getNodeCount() << " nodes.");
auto start = std::chrono::high_resolution_clock::now();
auto newPartition = signatureRefiner.refine(oldPartition, signature);
auto totalTimeInRefinement = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - start).count();
STORM_LOG_TRACE("Refinement " << refinements << " produced " << newPartition.getNumberOfBlocks() << " blocks and was completed in " << totalTimeInRefinement << "ms.");
++refinements;
return newPartition;
}
template <storm::dd::DdType DdType, typename ValueType>
bool PartitionRefiner<DdType, ValueType>::refineWrtRewardModel(storm::models::symbolic::StandardRewardModel<DdType, ValueType> const& rewardModel) {
STORM_LOG_THROW(!rewardModel.hasTransitionRewards(), storm::exceptions::NotSupportedException, "Symbolic bisimulation currently does not support transition rewards.");

3
src/storm/storage/dd/bisimulation/PartitionRefiner.h

@ -50,7 +50,8 @@ namespace storm {
protected:
Partition<DdType, ValueType> internalRefine(SignatureComputer<DdType, ValueType>& stateSignatureComputer, SignatureRefiner<DdType, ValueType>& signatureRefiner, Partition<DdType, ValueType> const& oldPartition, Partition<DdType, ValueType> const& targetPartition, SignatureMode const& mode = SignatureMode::Eager);
Partition<DdType, ValueType> internalRefine(Signature<DdType, ValueType> const& signature, SignatureRefiner<DdType, ValueType>& signatureRefiner, Partition<DdType, ValueType> const& oldPartition);
virtual bool refineWrtStateRewards(storm::dd::Add<DdType, ValueType> const& stateRewards);
virtual bool refineWrtStateActionRewards(storm::dd::Add<DdType, ValueType> const& stateActionRewards);

9
src/storm/storage/dd/bisimulation/QuotientExtractor.cpp

@ -427,7 +427,7 @@ namespace storm {
void createBlockToOffsetMappingRec(DdNodePtr partitionNode, DdNodePtr representativesNode, DdNodePtr variables, storm::dd::Odd const& odd, uint64_t offset) {
STORM_LOG_ASSERT(partitionNode != Cudd_ReadLogicZero(ddman) || representativesNode == Cudd_ReadLogicZero(ddman), "Expected representative to be zero if the partition is zero.");
if (representativesNode == Cudd_ReadLogicZero(ddman)) {
if (representativesNode == Cudd_ReadLogicZero(ddman) || partitionNode == Cudd_ReadLogicZero(ddman)) {
return;
}
@ -471,7 +471,7 @@ namespace storm {
}
void extractVectorRec(DdNodePtr vector, DdNodePtr representativesNode, DdNodePtr variables, storm::dd::Odd const& odd, uint64_t offset, std::vector<ValueType>& result) {
if (representativesNode == Cudd_ReadLogicZero(ddman)) {
if (representativesNode == Cudd_ReadLogicZero(ddman) || vector == Cudd_ReadZero(ddman)) {
return;
}
@ -643,7 +643,7 @@ namespace storm {
}
void extractVectorRec(MTBDD vector, BDD representativesNode, BDD variables, storm::dd::Odd const& odd, uint64_t offset, std::vector<ValueType>& result) {
if (representativesNode == sylvan_false) {
if (representativesNode == sylvan_false || mtbdd_iszero(vector)) {
return;
}
@ -680,7 +680,7 @@ namespace storm {
void createBlockToOffsetMappingRec(BDD partitionNode, BDD representativesNode, BDD variables, storm::dd::Odd const& odd, uint64_t offset) {
STORM_LOG_ASSERT(partitionNode != sylvan_false || representativesNode == sylvan_false, "Expected representative to be zero if the partition is zero.");
if (representativesNode == sylvan_false) {
if (representativesNode == sylvan_false || partitionNode == sylvan_false) {
return;
}
@ -892,6 +892,7 @@ namespace storm {
boost::optional<std::vector<ValueType>> quotientStateActionRewards;
if (rewardModel.hasStateActionRewards()) {
rewardModel.getStateActionRewardVector().exportToDot("vector.dot");
quotientStateActionRewards = sparseExtractor.extractStateActionVector(rewardModel.getStateActionRewardVector());
}

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

@ -57,9 +57,7 @@ namespace storm {
bool negated = mtbdd_hascomp(node);
STORM_LOG_ASSERT(mtbdd_gettype(node) == sylvan_storm_rational_number_get_type(), "Expected a storm::RationalNumber value.");
uint64_t value = mtbdd_getvalue(node);
storm_rational_number_ptr ptr = (storm_rational_number_ptr)value;
storm_rational_number_ptr ptr = (storm_rational_number_ptr)mtbdd_getstorm_rational_number_ptr(node);
storm::RationalNumber* rationalNumber = (storm::RationalNumber*)(ptr);
return negated ? -(*rationalNumber) : (*rationalNumber);

2
src/storm/storage/geometry/nativepolytopeconversion/QuickHull.cpp

@ -34,7 +34,7 @@ namespace storm {
for (uint_fast64_t vertexIndex : vertexIndices){
insidePoint += points[vertexIndex];
}
insidePoint /= storm::utility::convertNumber<ValueType>((uint_fast64_t) vertexIndices.size());
insidePoint /= storm::utility::convertNumber<ValueType>(static_cast<uint_fast64_t>(vertexIndices.size()));
// Create the initial facets from the found vertices.
std::vector<Facet> facets = computeInitialFacets(points, vertexIndices, insidePoint);

2
src/storm/utility/KwekMehlhorn.cpp

@ -31,7 +31,7 @@ namespace storm {
std::pair<typename NumberTraits<RationalType>::IntegerType, typename NumberTraits<RationalType>::IntegerType> truncateToRational(ImpreciseType const& value, uint64_t precision) {
typedef typename NumberTraits<RationalType>::IntegerType IntegerType;
IntegerType powerOfTen = storm::utility::pow(storm::utility::convertNumber<IntegerType>(10ull), precision);
IntegerType powerOfTen = storm::utility::pow(storm::utility::convertNumber<IntegerType>(static_cast<uint64_t>(10)), precision);
IntegerType truncated = storm::utility::trunc<RationalType>(value * powerOfTen);
return std::make_pair(truncated, powerOfTen);
}

24
src/test/storm/storage/SymbolicBisimulationDecompositionTest.cpp

@ -87,11 +87,11 @@ TEST(SymbolicModelBisimulationDecomposition, TwoDice_Cudd) {
decomposition.compute();
std::shared_ptr<storm::models::Model<double>> quotient = decomposition.getQuotient();
EXPECT_EQ(135ul, quotient->getNumberOfStates());
EXPECT_EQ(366ul, quotient->getNumberOfTransitions());
EXPECT_EQ(77ul, quotient->getNumberOfStates());
EXPECT_EQ(210ul, quotient->getNumberOfTransitions());
EXPECT_EQ(storm::models::ModelType::Mdp, quotient->getType());
EXPECT_TRUE(quotient->isSymbolicModel());
EXPECT_EQ(194ul, (quotient->as<storm::models::symbolic::Mdp<storm::dd::DdType::CUDD, double>>()->getNumberOfChoices()));
EXPECT_EQ(116ul, (quotient->as<storm::models::symbolic::Mdp<storm::dd::DdType::CUDD, double>>()->getNumberOfChoices()));
storm::parser::FormulaParser formulaParser;
std::shared_ptr<storm::logic::Formula const> formula = formulaParser.parseSingleFormulaFromString("Pmin=? [F \"two\"]");
@ -103,11 +103,11 @@ TEST(SymbolicModelBisimulationDecomposition, TwoDice_Cudd) {
decomposition2.compute();
quotient = decomposition2.getQuotient();
EXPECT_EQ(40ul, quotient->getNumberOfStates());
EXPECT_EQ(110ul, quotient->getNumberOfTransitions());
EXPECT_EQ(11ul, quotient->getNumberOfStates());
EXPECT_EQ(34ul, quotient->getNumberOfTransitions());
EXPECT_EQ(storm::models::ModelType::Mdp, quotient->getType());
EXPECT_TRUE(quotient->isSymbolicModel());
EXPECT_EQ(66ul, (quotient->as<storm::models::symbolic::Mdp<storm::dd::DdType::CUDD, double>>()->getNumberOfChoices()));
EXPECT_EQ(19ul, (quotient->as<storm::models::symbolic::Mdp<storm::dd::DdType::CUDD, double>>()->getNumberOfChoices()));
}
TEST(SymbolicModelBisimulationDecomposition, AsynchronousLeader_Cudd) {
@ -125,11 +125,11 @@ TEST(SymbolicModelBisimulationDecomposition, AsynchronousLeader_Cudd) {
decomposition.compute();
std::shared_ptr<storm::models::Model<double>> quotient = decomposition.getQuotient();
EXPECT_EQ(1166ul, quotient->getNumberOfStates());
EXPECT_EQ(2769ul, quotient->getNumberOfTransitions());
EXPECT_EQ(252ul, quotient->getNumberOfStates());
EXPECT_EQ(624ul, quotient->getNumberOfTransitions());
EXPECT_EQ(storm::models::ModelType::Mdp, quotient->getType());
EXPECT_TRUE(quotient->isSymbolicModel());
EXPECT_EQ(2237ul, (quotient->as<storm::models::symbolic::Mdp<storm::dd::DdType::CUDD, double>>()->getNumberOfChoices()));
EXPECT_EQ(500ul, (quotient->as<storm::models::symbolic::Mdp<storm::dd::DdType::CUDD, double>>()->getNumberOfChoices()));
std::vector<std::shared_ptr<storm::logic::Formula const>> formulas;
formulas.push_back(formula);
@ -138,9 +138,9 @@ TEST(SymbolicModelBisimulationDecomposition, AsynchronousLeader_Cudd) {
decomposition2.compute();
quotient = decomposition2.getQuotient();
EXPECT_EQ(1166ul, quotient->getNumberOfStates());
EXPECT_EQ(2769ul, quotient->getNumberOfTransitions());
EXPECT_EQ(1107ul, quotient->getNumberOfStates());
EXPECT_EQ(2684ul, quotient->getNumberOfTransitions());
EXPECT_EQ(storm::models::ModelType::Mdp, quotient->getType());
EXPECT_TRUE(quotient->isSymbolicModel());
EXPECT_EQ(2237ul, (quotient->as<storm::models::symbolic::Mdp<storm::dd::DdType::CUDD, double>>()->getNumberOfChoices()));
EXPECT_EQ(2152ul, (quotient->as<storm::models::symbolic::Mdp<storm::dd::DdType::CUDD, double>>()->getNumberOfChoices()));
}
Loading…
Cancel
Save