292 lines
13 KiB
292 lines
13 KiB
#ifndef STORM_STORAGE_BISIMULATIONDECOMPOSITION_H_
|
|
#define STORM_STORAGE_BISIMULATIONDECOMPOSITION_H_
|
|
|
|
#include "storm/settings/SettingsManager.h"
|
|
#include "storm/settings/modules/BisimulationSettings.h"
|
|
#include "storm/storage/sparse/StateType.h"
|
|
#include "storm/storage/Decomposition.h"
|
|
#include "storm/storage/StateBlock.h"
|
|
#include "storm/storage/bisimulation/Partition.h"
|
|
#include "storm/storage/bisimulation/BisimulationType.h"
|
|
#include "storm/solver/OptimizationDirection.h"
|
|
|
|
#include "storm/logic/Formulas.h"
|
|
|
|
#include "storm/utility/constants.h"
|
|
#include "storm/utility/ConstantsComparator.h"
|
|
|
|
namespace storm {
|
|
namespace logic {
|
|
class Formula;
|
|
}
|
|
|
|
namespace storage {
|
|
|
|
inline BisimulationType resolveBisimulationTypeChoice(BisimulationTypeChoice c) {
|
|
switch(c) {
|
|
case BisimulationTypeChoice::Strong:
|
|
return BisimulationType::Strong;
|
|
case BisimulationTypeChoice::Weak:
|
|
return BisimulationType::Weak;
|
|
case BisimulationTypeChoice::FromSettings:
|
|
if (storm::settings::getModule<storm::settings::modules::BisimulationSettings>().isWeakBisimulationSet()) {
|
|
return BisimulationType::Weak;
|
|
} else {
|
|
return BisimulationType::Strong;
|
|
}
|
|
}
|
|
return BisimulationType::Strong;
|
|
}
|
|
|
|
/*!
|
|
* This class is the superclass of all decompositions of a sparse model into its bisimulation quotient.
|
|
*/
|
|
template <typename ModelType, typename BlockDataType>
|
|
class BisimulationDecomposition : public Decomposition<StateBlock> {
|
|
public:
|
|
typedef typename ModelType::ValueType ValueType;
|
|
typedef typename ModelType::RewardModelType RewardModelType;
|
|
|
|
// A class that offers the possibility to customize the bisimulation.
|
|
struct Options {
|
|
|
|
|
|
// Creates an object representing the default values for all options.
|
|
Options();
|
|
|
|
/*!
|
|
* Creates an object representing the options necessary to obtain the quotient while still preserving
|
|
* the given formula.
|
|
*
|
|
* @param The model for which the quotient model shall be computed. This needs to be given in order to
|
|
* derive a suitable initial partition.
|
|
* @param formula The formula that is to be preserved.
|
|
*/
|
|
Options(ModelType const& model, storm::logic::Formula const& formula);
|
|
|
|
/*!
|
|
* Creates an object representing the options necessary to obtain the smallest quotient while still
|
|
* preserving the given formulas.
|
|
*
|
|
* @param The model for which the quotient model shall be computed. This needs to be given in order to
|
|
* derive a suitable initial partition.
|
|
* @param formulas The formulas that need to be preserved.
|
|
*/
|
|
Options(ModelType const& model, std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas);
|
|
|
|
/*!
|
|
* Changes the options in a way that the given formula is preserved.
|
|
*
|
|
* @param formula The only formula to check.
|
|
*/
|
|
void preserveFormula(storm::logic::Formula const& formula);
|
|
|
|
/**
|
|
* Sets the bisimulation type. If the bisimulation type is set to weak,
|
|
* we also change the bounded flag (as bounded properties are not preserved under
|
|
* weak bisimulation).
|
|
*/
|
|
void setType(BisimulationType t) {
|
|
if(t == BisimulationType::Weak) {
|
|
bounded = false;
|
|
}
|
|
type = t;
|
|
}
|
|
|
|
BisimulationType getType() const {
|
|
return this->type;
|
|
}
|
|
|
|
bool getBounded() const {
|
|
return this->bounded;
|
|
}
|
|
|
|
bool getKeepRewards() const {
|
|
return this->keepRewards;
|
|
}
|
|
|
|
bool isOptimizationDirectionSet() const {
|
|
return static_cast<bool>(optimalityType);
|
|
}
|
|
|
|
OptimizationDirection getOptimizationDirection() const {
|
|
STORM_LOG_ASSERT(optimalityType, "Optimality type not set.");
|
|
return optimalityType.get();
|
|
}
|
|
|
|
// A flag that indicates whether a measure driven initial partition is to be used. If this flag is set
|
|
// to true, the two optional pairs phiStatesAndLabel and psiStatesAndLabel must be set. Then, the
|
|
// measure driven initial partition wrt. to the states phi and psi is taken.
|
|
bool measureDrivenInitialPartition;
|
|
boost::optional<storm::storage::BitVector> phiStates;
|
|
boost::optional<storm::storage::BitVector> psiStates;
|
|
|
|
/// An optional set of strings that indicate which of the atomic propositions of the model are to be
|
|
/// respected and which may be ignored. If not given, all atomic propositions of the model are respected.
|
|
boost::optional<std::set<std::string>> respectedAtomicPropositions;
|
|
|
|
/// A flag that governs whether the quotient model is actually built or only the decomposition is computed.
|
|
bool buildQuotient;
|
|
|
|
private:
|
|
boost::optional<OptimizationDirection> optimalityType;
|
|
|
|
/// A flag that indicates whether or not the state-rewards of the model are to be respected (and should
|
|
/// be kept in the quotient model, if one is built).
|
|
bool keepRewards;
|
|
|
|
/// A flag that indicates whether a strong or a weak bisimulation is to be computed.
|
|
BisimulationType type;
|
|
|
|
/// A flag that indicates whether step-bounded properties are to be preserved. This may only be set to tru
|
|
/// when computing strong bisimulation equivalence.
|
|
bool bounded;
|
|
|
|
/*!
|
|
* Sets the options under the assumption that the given formula is the only one that is to be checked.
|
|
*
|
|
* @param model The model for which to preserve the formula.
|
|
* @param formula The only formula to check.
|
|
*/
|
|
void preserveSingleFormula(ModelType const& model, storm::logic::Formula const& formula);
|
|
|
|
/*!
|
|
* Adds the given expressions and labels to the set of respected atomic propositions.
|
|
*
|
|
* @param expressions The expressions to respect.
|
|
* @param labels The labels to respect.
|
|
*/
|
|
void addToRespectedAtomicPropositions(std::vector<std::shared_ptr<storm::logic::AtomicExpressionFormula const>> const& expressions, std::vector<std::shared_ptr<storm::logic::AtomicLabelFormula const>> const& labels);
|
|
|
|
/*
|
|
* Checks whether a measure driven partition is possible with the given formula and sets the necessary
|
|
* data if this is the case.
|
|
*
|
|
* @param model The model for which to derive the data.
|
|
* @param formula The formula for which to derive the data for the measure driven initial partition (if
|
|
* applicable).
|
|
*/
|
|
void checkAndSetMeasureDrivenInitialPartition(ModelType const& model, storm::logic::Formula const& formula);
|
|
};
|
|
|
|
/*!
|
|
* Decomposes the given model into equivalance classes of a bisimulation.
|
|
*
|
|
* @param model The model to decompose.
|
|
* @param options The options to use during for the decomposition.
|
|
*/
|
|
BisimulationDecomposition(ModelType const& model, Options const& options);
|
|
|
|
virtual ~BisimulationDecomposition() = default;
|
|
|
|
/*!
|
|
* Retrieves the quotient of the model under the computed bisimulation.
|
|
*
|
|
* @return The quotient model.
|
|
*/
|
|
std::shared_ptr<ModelType> getQuotient() const;
|
|
|
|
/*!
|
|
* Computes the decomposition of the model into bisimulation equivalence classes. If requested, a quotient
|
|
* model is built.
|
|
*/
|
|
void computeBisimulationDecomposition();
|
|
|
|
protected:
|
|
/*!
|
|
* Decomposes the given model into equivalance classes of a bisimulation.
|
|
*
|
|
* @param model The model to decompose.
|
|
* @param backwardTransition The backward transitions of the model.
|
|
* @param options The options to use during for the decomposition.
|
|
*/
|
|
BisimulationDecomposition(ModelType const& model, storm::storage::SparseMatrix<ValueType> const& backwardTransitions, Options const& options);
|
|
|
|
/*!
|
|
* Performs the partition refinement on the model and thereby computes the equivalence classes under strong
|
|
* bisimulation equivalence. If required, the quotient model is built and may be retrieved using
|
|
* getQuotient().
|
|
*/
|
|
void performPartitionRefinement();
|
|
|
|
/*!
|
|
* Refines the partition by considering the given splitter. All blocks that become potential splitters
|
|
* because of this refinement, are marked as splitters and inserted into the splitter vector.
|
|
*
|
|
* @param splitter The splitter to use.
|
|
* @param splitterVector The vector into which to insert the newly discovered potential splitters.
|
|
*/
|
|
virtual void refinePartitionBasedOnSplitter(bisimulation::Block<BlockDataType>& splitter, std::vector<bisimulation::Block<BlockDataType>*>& splitterQueue) = 0;
|
|
|
|
/*!
|
|
* Builds the quotient model based on the previously computed equivalence classes (stored in the blocks
|
|
* of the decomposition.
|
|
*/
|
|
virtual void buildQuotient() = 0;
|
|
|
|
/*!
|
|
* Initializes the initial partition based on all respected labels.
|
|
*/
|
|
virtual void initializeLabelBasedPartition();
|
|
|
|
/*!
|
|
* Creates the measure-driven initial partition for reaching psi states from phi states.
|
|
*/
|
|
virtual void initializeMeasureDrivenPartition();
|
|
|
|
/*!
|
|
* A function that can initialize auxiliary data structures. It is called after initializing the initial partition.
|
|
*/
|
|
virtual void initialize();
|
|
|
|
/*!
|
|
* Computes the set of states with probability 0/1 for satisfying phi until psi. This is used for the measure
|
|
* driven initial partition.
|
|
*
|
|
* @return The states with probability 0 and 1.
|
|
*/
|
|
virtual std::pair<storm::storage::BitVector, storm::storage::BitVector> getStatesWithProbability01() = 0;
|
|
|
|
/*!
|
|
* Splits the initial partition based on the (unique) reward model of the current model.
|
|
*/
|
|
virtual void splitInitialPartitionBasedOnRewards();
|
|
|
|
/*!
|
|
* Splits the initial partition based on the given reward vector.
|
|
*/
|
|
virtual void splitInitialPartitionBasedOnRewards(std::vector<ValueType> const& rewardVector);
|
|
|
|
/*!
|
|
* Splits the initial partition based on the given vector of action rewards.
|
|
*/
|
|
virtual void splitInitialPartitionBasedOnActionRewards(std::vector<std::set<ValueType>> const& rewardVector);
|
|
|
|
/*!
|
|
* Constructs the blocks of the decomposition object based on the current partition.
|
|
*/
|
|
void extractDecompositionBlocks();
|
|
|
|
// The model to decompose.
|
|
ModelType const& model;
|
|
|
|
// The backward transitions of the model.
|
|
storm::storage::SparseMatrix<ValueType> backwardTransitions;
|
|
|
|
// The options used during construction.
|
|
Options options;
|
|
|
|
// The current partition (used by partition refinement).
|
|
storm::storage::bisimulation::Partition<BlockDataType> partition;
|
|
|
|
// A comparator used for comparing the distances of constants.
|
|
storm::utility::ConstantsComparator<ValueType> comparator;
|
|
|
|
// The quotient, if it was build. Otherwhise a null pointer.
|
|
std::shared_ptr<ModelType> quotient;
|
|
};
|
|
}
|
|
}
|
|
|
|
|
|
#endif /* STORM_STORAGE_BISIMULATIONDECOMPOSITION_H_ */
|