From 2484a515a0112cd26a8c6089eb3dd1ee7ae294e8 Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Tue, 27 Oct 2015 23:30:51 +0100
Subject: [PATCH] some more work on bisim

Former-commit-id: aaa8088b009de8b1f0469cc2171b2821f1c6656e
---
 src/models/sparse/StandardRewardModel.cpp        |  4 +++-
 .../bisimulation/BisimulationDecomposition.cpp   | 15 +++++++++------
 src/storage/bisimulation/Block.cpp               |  2 +-
 ...terministicModelBisimulationDecomposition.cpp | 16 ++++++++--------
 src/storage/bisimulation/Partition.cpp           |  6 +++---
 src/utility/storm.h                              |  1 +
 6 files changed, 25 insertions(+), 19 deletions(-)

diff --git a/src/models/sparse/StandardRewardModel.cpp b/src/models/sparse/StandardRewardModel.cpp
index 1f7db2b79..fe63c4b78 100644
--- a/src/models/sparse/StandardRewardModel.cpp
+++ b/src/models/sparse/StandardRewardModel.cpp
@@ -147,6 +147,7 @@ namespace storm {
                 if (this->hasTransitionRewards()) {
                     if (this->hasStateActionRewards()) {
                         storm::utility::vector::addVectors<ValueType>(this->getStateActionRewardVector(), transitionMatrix.getPointwiseProductRowSumVector(this->getTransitionRewardMatrix()), this->getStateActionRewardVector());
+                        optionalStateActionRewardVector = boost::none;
                     } else {
                         this->optionalStateActionRewardVector = transitionMatrix.getPointwiseProductRowSumVector(this->getTransitionRewardMatrix());
                     }
@@ -157,8 +158,9 @@ namespace storm {
                         STORM_LOG_THROW(this->getStateRewardVector().size() == this->getStateActionRewardVector().size(), storm::exceptions::InvalidOperationException, "The reduction to state rewards is only possible of both the state and the state-action rewards have the same dimension.");
                         storm::utility::vector::addVectors<ValueType>(this->getStateActionRewardVector(), this->getStateRewardVector(), this->getStateRewardVector());
                     } else {
-                        this->optionalStateRewardVector = std::move(this->optionalStateRewardVector);
+                        this->optionalStateRewardVector = std::move(this->optionalStateActionRewardVector);
                     }
+                    optionalStateActionRewardVector = boost::none;
                 }
             }
             
diff --git a/src/storage/bisimulation/BisimulationDecomposition.cpp b/src/storage/bisimulation/BisimulationDecomposition.cpp
index 120f88f88..d550c510c 100644
--- a/src/storage/bisimulation/BisimulationDecomposition.cpp
+++ b/src/storage/bisimulation/BisimulationDecomposition.cpp
@@ -28,7 +28,10 @@ namespace storm {
         
         template<typename ModelType>
         BisimulationDecomposition<ModelType>::Options::Options(ModelType const& model, std::vector<std::shared_ptr<storm::logic::Formula>> const& formulas) : Options() {
-            if (formulas.size() == 1) {
+            if (formulas.empty()) {
+                this->respectedAtomicPropositions = model.getStateLabeling().getLabels();
+                this->keepRewards = true;
+            } if (formulas.size() == 1) {
                 this->preserveSingleFormula(model, *formulas.front());
             } else {
                 for (auto const& formula : formulas) {
@@ -202,7 +205,7 @@ namespace storm {
                 splitter->unmarkAsSplitter();
                 
                 // Now refine the partition using the current splitter.
-                std::cout << "refining based on splitter " << splitter->getId() << std::endl;
+//                std::cout << "refining based on splitter " << splitter->getId() << std::endl;
                 refinePartitionBasedOnSplitter(*splitter, splitterQueue);
             }
         }
@@ -236,8 +239,8 @@ namespace storm {
                 this->splitInitialPartitionBasedOnStateRewards();
             }
             
-            std::cout << "successfully built (label) initial partition" << std::endl;
-            partition.print();
+//            std::cout << "successfully built (label) initial partition" << std::endl;
+//            partition.print();
         }
         
         template<typename ModelType>
@@ -257,8 +260,8 @@ namespace storm {
                 this->splitInitialPartitionBasedOnStateRewards();
             }
             
-            std::cout << "successfully built (measure-driven) initial partition" << std::endl;
-            partition.print();
+//            std::cout << "successfully built (measure-driven) initial partition" << std::endl;
+//            partition.print();
         }
         
         template<typename ModelType>
diff --git a/src/storage/bisimulation/Block.cpp b/src/storage/bisimulation/Block.cpp
index 2157baeb3..2de49e62a 100644
--- a/src/storage/bisimulation/Block.cpp
+++ b/src/storage/bisimulation/Block.cpp
@@ -35,7 +35,7 @@ namespace storm {
             }
             
             void Block::setBeginIndex(storm::storage::sparse::state_type beginIndex) {
-                std::cout << "setting beg index to " << beginIndex << " [" << this << "]" << std::endl;
+//                std::cout << "setting beg index to " << beginIndex << " [" << this << "]" << std::endl;
                 this->beginIndex = beginIndex;
                 STORM_LOG_ASSERT(beginIndex < endIndex, "Unable to resize block to illegal size.");
             }
diff --git a/src/storage/bisimulation/DeterministicModelBisimulationDecomposition.cpp b/src/storage/bisimulation/DeterministicModelBisimulationDecomposition.cpp
index 9a739cea3..565dfef91 100644
--- a/src/storage/bisimulation/DeterministicModelBisimulationDecomposition.cpp
+++ b/src/storage/bisimulation/DeterministicModelBisimulationDecomposition.cpp
@@ -29,8 +29,8 @@ namespace storm {
         
         template<typename ModelType>
         DeterministicModelBisimulationDecomposition<ModelType>::DeterministicModelBisimulationDecomposition(ModelType const& model, typename BisimulationDecomposition<ModelType>::Options const& options) : BisimulationDecomposition<ModelType>(model, options), probabilitiesToCurrentSplitter(model.getNumberOfStates(), storm::utility::zero<ValueType>()), predecessorsOfCurrentSplitter(model.getNumberOfStates()) {
-            STORM_LOG_THROW(!model.hasRewardModel() || model.hasUniqueRewardModel(), storm::exceptions::IllegalFunctionCallException, "Bisimulation currently only supports models with at most one reward model.");
-            STORM_LOG_THROW(!model.hasRewardModel() || model.getUniqueRewardModel()->second.hasOnlyStateRewards(), storm::exceptions::IllegalFunctionCallException, "Bisimulation is currently supported for models with state rewards only. Consider converting the transition rewards to state rewards (via suitable function calls).");
+            STORM_LOG_THROW(!options.keepRewards || !model.hasRewardModel() || model.hasUniqueRewardModel(), storm::exceptions::IllegalFunctionCallException, "Bisimulation currently only supports models with at most one reward model.");
+            STORM_LOG_THROW(!options.keepRewards || !model.hasRewardModel() || model.getUniqueRewardModel()->second.hasOnlyStateRewards(), storm::exceptions::IllegalFunctionCallException, "Bisimulation is currently supported for models with state rewards only. Consider converting the transition rewards to state rewards (via suitable function calls).");
             STORM_LOG_THROW(options.type != BisimulationType::Weak || !options.bounded, storm::exceptions::IllegalFunctionCallException, "Weak bisimulation cannot preserve bounded properties.");
         }
         
@@ -160,7 +160,7 @@ namespace storm {
         template<typename ModelType>
         void DeterministicModelBisimulationDecomposition<ModelType>::refinePredecessorBlocksOfSplitter(std::list<Block*>& predecessorBlocks, std::deque<bisimulation::Block*>& splitterQueue) {
             for (auto block : predecessorBlocks) {
-                std::cout << "splitting predecessor block " << block->getId() << " of splitter" << std::endl;
+//                std::cout << "splitting predecessor block " << block->getId() << " of splitter" << std::endl;
                 this->partition.splitBlock(*block, [this] (storm::storage::sparse::state_type const& state1, storm::storage::sparse::state_type const& state2) {
                     bool firstIsPredecessor = isPredecessorOfCurrentSplitter(state1);
                     bool secondIsPredecessor = isPredecessorOfCurrentSplitter(state2);
@@ -175,7 +175,7 @@ namespace storm {
                     splitterQueue.emplace_back(&block);
                 });
 //                this->partition.print();
-                std::cout << "size: " << this->partition.size() << std::endl;
+//                std::cout << "size: " << this->partition.size() << std::endl;
                 
                 // Remember that we have refined the block.
                 block->setNeedsRefinement(false);
@@ -227,10 +227,10 @@ namespace storm {
                 }
             }
             
-            std::cout << "probs of splitter predecessors: " << std::endl;
-            for (auto state : predecessorsOfCurrentSplitter) {
-                std::cout << state << " [" << this->partition.getBlock(state).getId() << "]" << " -> " << probabilitiesToCurrentSplitter[state] << std::endl;
-            }
+//            std::cout << "probs of splitter predecessors: " << std::endl;
+//            for (auto state : predecessorsOfCurrentSplitter) {
+//                std::cout << state << " [" << this->partition.getBlock(state).getId() << "]" << " -> " << probabilitiesToCurrentSplitter[state] << std::endl;
+//            }
             
             if (this->options.type == BisimulationType::Strong || this->model.getType() == storm::models::ModelType::Ctmc) {
                 refinePredecessorBlocksOfSplitter(predecessorBlocks, splitterQueue);
diff --git a/src/storage/bisimulation/Partition.cpp b/src/storage/bisimulation/Partition.cpp
index cf9dfa8aa..bbe45fc0a 100644
--- a/src/storage/bisimulation/Partition.cpp
+++ b/src/storage/bisimulation/Partition.cpp
@@ -142,7 +142,7 @@ namespace storm {
             std::pair<std::vector<std::unique_ptr<Block>>::iterator, bool> Partition::splitBlock(Block& block, storm::storage::sparse::state_type position) {
                 STORM_LOG_THROW(position >= block.getBeginIndex() && position <= block.getEndIndex(), storm::exceptions::InvalidArgumentException, "Cannot split block at illegal position.");
 
-                std::cout << "splitting " << block.getId() << " at pos " << position << " (was " << block.getBeginIndex() << " to " << block.getEndIndex() << ")" << std::endl;
+//                std::cout << "splitting " << block.getId() << " at pos " << position << " (was " << block.getBeginIndex() << " to " << block.getEndIndex() << ")" << std::endl;
                 
                 // In case one of the resulting blocks would be empty, we simply return the current block and do not create
                 // a new one.
@@ -157,7 +157,7 @@ namespace storm {
                 auto newBlockIt = std::prev(blocks.end());
                 
                 // Resize the current block appropriately.
-                std::cout << "setting begin pos of block " << block.getId() << " to " << position << std::endl;
+//                std::cout << "setting begin pos of block " << block.getId() << " to " << position << std::endl;
                 block.setBeginIndex(position);
                 
                 // Mark both blocks as splitters.
@@ -171,7 +171,7 @@ namespace storm {
             }
             
             bool Partition::splitBlock(Block& block, std::function<bool (storm::storage::sparse::state_type, storm::storage::sparse::state_type)> const& less, std::function<void (Block&)> const& newBlockCallback) {
-                std::cout << "sorting the block [" << block.getId() << "]" << std::endl;
+//                std::cout << "sorting the block [" << block.getId() << "]" << std::endl;
                 // Sort the range of the block such that all states that have the label are moved to the front.
                 std::sort(this->begin(block), this->end(block), less);
                 
diff --git a/src/utility/storm.h b/src/utility/storm.h
index 2eea34738..221545743 100644
--- a/src/utility/storm.h
+++ b/src/utility/storm.h
@@ -126,6 +126,7 @@ namespace storm {
         }
         
         storm::storage::DeterministicModelBisimulationDecomposition<ModelType> bisimulationDecomposition(*model, options);
+        bisimulationDecomposition.computeBisimulationDecomposition();
         model = bisimulationDecomposition.getQuotient();
         std::cout << "done." << std::endl << std::endl;
         return model;