Browse Source

simplified state signature computation in dd-based bisimulation

tempestpy_adaptions
dehnert 7 years ago
parent
commit
c0f07557ed
  1. 17
      src/storm/storage/dd/bisimulation/MdpPartitionRefiner.cpp
  2. 6
      src/storm/storage/dd/bisimulation/MdpPartitionRefiner.h
  3. 2
      src/storm/storage/dd/bisimulation/Partition.cpp
  4. 15
      src/storm/storage/dd/bisimulation/PartitionRefiner.cpp
  5. 3
      src/storm/storage/dd/bisimulation/PartitionRefiner.h
  6. 24
      src/test/storm/storage/SymbolicBisimulationDecompositionTest.cpp

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 << "[" << index << "] 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);

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