You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
332 lines
19 KiB
332 lines
19 KiB
#ifndef STORM_MODELCHECKER_REACHABILITY_SPARSEDTMCREGIONMODELCHECKER_H_
|
|
#define STORM_MODELCHECKER_REACHABILITY_SPARSEDTMCREGIONMODELCHECKER_H_
|
|
|
|
#include <type_traits>
|
|
|
|
#include "src/storage/sparse/StateType.h"
|
|
#include "src/models/sparse/Dtmc.h"
|
|
#include "src/models/sparse/Mdp.h"
|
|
#include "src/utility/constants.h"
|
|
#include "utility/regions.h"
|
|
#include "src/solver/Smt2SmtSolver.h"
|
|
#include "SparseDtmcEliminationModelChecker.h"
|
|
|
|
namespace storm {
|
|
namespace modelchecker {
|
|
|
|
template<typename ParametricType, typename ConstantType>
|
|
class SparseDtmcRegionModelChecker {
|
|
public:
|
|
|
|
//The type of variables and bounds depends on the template arguments
|
|
typedef typename std::conditional<(std::is_same<ParametricType,storm::RationalFunction>::value), storm::Variable,std::nullptr_t>::type VariableType;
|
|
typedef typename std::conditional<(std::is_same<ParametricType,storm::RationalFunction>::value), storm::RationalFunction::CoeffType,std::nullptr_t>::type BoundType;
|
|
|
|
/*!
|
|
* The possible results for a single region
|
|
*/
|
|
enum class RegionCheckResult {
|
|
UNKNOWN, /*!< the result is unknown */
|
|
EXISTSSAT, /*!< the formula is satisfied for at least one parameter evaluation that lies in the given region */
|
|
EXISTSVIOLATED, /*!< the formula is violated for at least one parameter evaluation that lies in the given region */
|
|
EXISTSBOTH, /*!< the formula is satisfied for some parameters but also violated for others */
|
|
ALLSAT, /*!< the formula is satisfied for all parameters in the given region */
|
|
ALLVIOLATED /*!< the formula is violated for all parameters in the given region */
|
|
};
|
|
|
|
class ParameterRegion{
|
|
public:
|
|
|
|
ParameterRegion(std::map<VariableType, BoundType> lowerBounds, std::map<VariableType, BoundType> upperBounds);
|
|
|
|
|
|
|
|
std::set<VariableType> getVariables() const;
|
|
BoundType const& getLowerBound(VariableType const& variable) const;
|
|
BoundType const& getUpperBound(VariableType const& variable) const;
|
|
const std::map<VariableType, BoundType> getUpperBounds() const;
|
|
const std::map<VariableType, BoundType> getLowerBounds() const;
|
|
|
|
/*
|
|
* Returns a vector of all possible combinations of lower and upper bounds of the given variables.
|
|
* The first entry of the returned vector will map every variable to its lower bound
|
|
* The second entry will map every variable to its lower bound, except the first one (i.e. *consVariables.begin())
|
|
* ...
|
|
* The last entry will map every variable to its upper bound
|
|
*
|
|
* If the given set of variables is empty, the returned vector will contain an empty map
|
|
*/
|
|
std::vector<std::map<VariableType, BoundType>> getVerticesOfRegion(std::set<VariableType> const& consideredVariables) const;
|
|
|
|
//returns the currently set check result as a string
|
|
std::string checkResultToString() const;
|
|
|
|
//returns the region as string in the format 0.3<=p<=0.4,0.2<=q<=0.5;
|
|
std::string toString() const;
|
|
|
|
void setCheckResult(RegionCheckResult checkResult);
|
|
RegionCheckResult getCheckResult() const;
|
|
|
|
/*!
|
|
* Sets a point in the region for which the considered property is not satisfied.
|
|
*/
|
|
void setViolatedPoint(std::map<VariableType, BoundType> const& violatedPoint);
|
|
|
|
/*!
|
|
* Retrieves a point in the region for which is considered property is not satisfied.
|
|
* If such a point is not known, the returned map is empty.
|
|
*/
|
|
std::map<VariableType, BoundType> getViolatedPoint() const;
|
|
|
|
|
|
/*!
|
|
* Sets a point in the region for which the considered property is satisfied.
|
|
*/
|
|
void setSatPoint(std::map<VariableType, BoundType> const& satPoint);
|
|
|
|
/*!
|
|
* Retrieves a point in the region for which is considered property is satisfied.
|
|
* If such a point is not known, the returned map is empty.
|
|
*/
|
|
std::map<VariableType, BoundType> getSatPoint() const;
|
|
|
|
private:
|
|
|
|
std::map<VariableType, BoundType> const lowerBounds;
|
|
std::map<VariableType, BoundType> const upperBounds;
|
|
RegionCheckResult checkResult;
|
|
std::map<VariableType, BoundType> satPoint;
|
|
std::map<VariableType, BoundType> violatedPoint;
|
|
|
|
|
|
};
|
|
|
|
explicit SparseDtmcRegionModelChecker(storm::models::sparse::Dtmc<ParametricType> const& model);
|
|
|
|
/*!
|
|
* Checks if the given formula can be handled by this
|
|
* @param formula the formula to be checked
|
|
*/
|
|
bool canHandle(storm::logic::Formula const& formula) const;
|
|
|
|
/*!
|
|
* Specifies the considered formula.
|
|
* A few preprocessing steps are performed.
|
|
* If another formula has been specified before, all 'context' regarding the old formula is lost.
|
|
*
|
|
* @param formula the formula to be considered.
|
|
*/
|
|
void specifyFormula(storm::logic::Formula const& formula);
|
|
|
|
/*!
|
|
* Checks whether the given formula holds for all parameters that lie in the given region.
|
|
* Sets the region checkresult accordingly. Moreover, region.satPoint and/or an region.violatedPoint will be set.
|
|
*
|
|
* @note A formula has to be specified first.
|
|
*
|
|
* @param region The considered region
|
|
*
|
|
*/
|
|
void checkRegion(ParameterRegion& region);
|
|
|
|
/*!
|
|
* Checks for every given region whether the specified formula holds for all parameters that lie in that region.
|
|
* Sets the region checkresult accordingly. Moreover, region.satPoint and/or an region.violatedPoint will be set.
|
|
*
|
|
* @note A formula has to be specified first.
|
|
*
|
|
* @param region The considered region
|
|
*/
|
|
void checkRegions(std::vector<ParameterRegion>& regions);
|
|
|
|
/*!
|
|
* Checks whether the given formula holds for all possible parameters that satisfy the given parameter regions
|
|
* ParameterRegions should contain all parameters.
|
|
*/
|
|
bool checkRegionOld(storm::logic::Formula const& formula, std::vector<ParameterRegion> parameterRegions);
|
|
|
|
/*!
|
|
* Prints statistical information (mostly running times) to the given stream.
|
|
*/
|
|
void printStatisticsToStream(std::ostream& outstream);
|
|
private:
|
|
|
|
typedef typename storm::modelchecker::SparseDtmcEliminationModelChecker<ParametricType>::FlexibleSparseMatrix FlexibleMatrix;
|
|
|
|
/*!
|
|
* Represents the current state of this
|
|
*/
|
|
// enum class RegionCheckerState{
|
|
// NOFORMULA, /*!< there is no formula */
|
|
// INITIALIZED, /*!< a formula has been specified. Ready to get regions*/
|
|
// };
|
|
|
|
#ifdef STORM_HAVE_CARL
|
|
/*!
|
|
* Instantiates the matrix, i.e., evaluate the occurring functions according to the given substitutions of the variables.
|
|
* One row of the given flexible matrix will be one rowgroup in the returned matrix, consisting of one row for every substitution.
|
|
* The returned matrix can be seen as the transition matrix of an MDP with the action labeling given by the returned vector of sets.
|
|
* Only the rows selected by the given filter are considered. (filter should have size==matrix.getNumberOfRows())
|
|
* An exception is thrown if there is a transition from a selected state to an unselected state
|
|
* If one step probabilities are given, a new state is added which can be considered as target state.
|
|
* The "missing" probability can be redirected to a sink state
|
|
* By convention, the target state will have index filter.getNumberOfSetBits() and the sink state will be the state with the highest index (so right after the target state)
|
|
*
|
|
* @param matrix the considered flexible matrix
|
|
* @param substitutions A list of mappings, each assigning a constant value to every variable
|
|
* @param filter selects the rows of this flexibleMatrix, that will be considered
|
|
* @param addSinkState adds a state with a self loop to which the "missing" probability will lead
|
|
* @param oneStepProbabilities if given, a new state is added to which there are transitions for all non-zero entries in this vector
|
|
* @param addSelfLoops if set, zero valued selfloops will be added in every row
|
|
*
|
|
* @return A matrix with constant (double) entries and a choice labeling
|
|
*/
|
|
std::pair<storm::storage::SparseMatrix<double>,std::vector<boost::container::flat_set<uint_fast64_t>>> instantiateFlexibleMatrix(FlexibleMatrix const& matrix, std::vector<std::map<storm::Variable, storm::RationalFunction::CoeffType>> const& substitutions, storm::storage::BitVector const& filter, bool addSinkState=true, std::vector<ParametricType> const& oneStepProbabilities=std::vector<ParametricType>(), bool addSelfLoops=true) const;
|
|
//todo add const keyword
|
|
|
|
//eliminates some of the states according to different strategies.
|
|
void eliminateStates(storm::storage::BitVector& subsystem, FlexibleMatrix& flexibleMatrix, std::vector<ParametricType>& oneStepProbabilities, FlexibleMatrix& flexibleBackwardTransitions, storm::storage::BitVector const& initialStates, storm::storage::SparseMatrix<ParametricType> const& forwardTransitions, boost::optional<std::vector<std::size_t>> const& statePriorities = {});
|
|
|
|
void formulateModelWithSMT(storm::solver::Smt2SmtSolver& solver, std::vector<storm::RationalFunction::PolyType>& stateProbVars, storm::storage::BitVector const& subsystem, FlexibleMatrix const& flexibleMatrix, std::vector<storm::RationalFunction> const& oneStepProbabilities);
|
|
|
|
void restrictProbabilityVariables(storm::solver::Smt2SmtSolver& solver, std::vector<storm::RationalFunction::PolyType> const& stateProbVars, storm::storage::BitVector const& subsystem, FlexibleMatrix const& flexibleMatrix, std::vector<storm::RationalFunction> const& oneStepProbabilities, ParameterRegion const& region, storm::logic::ComparisonType const& compTypeOfProperty);
|
|
#endif
|
|
template <typename ValueType>
|
|
bool valueIsInBoundOfFormula(ValueType value);
|
|
|
|
/*!
|
|
* eliminates all states for which the outgoing transitions are constant.
|
|
* Also checks whether the non constant functions are linear
|
|
*/
|
|
void eliminateStatesConstSucc(
|
|
storm::storage::BitVector& subsys,
|
|
FlexibleMatrix& flexTransitions,
|
|
FlexibleMatrix& flexBackwardTransitions,
|
|
std::vector<ParametricType>& oneStepProbs,
|
|
bool& allFunctionsAreLinear,
|
|
storm::storage::sparse::state_type const& initState
|
|
);
|
|
|
|
//Computes the reachability probability function by performing state elimination
|
|
ParametricType computeReachProbFunction(
|
|
storm::storage::BitVector const& subsys,
|
|
FlexibleMatrix const& flexTransitions,
|
|
FlexibleMatrix const& flexBackwardTransitions,
|
|
storm::storage::SparseMatrix<ParametricType> const& spTransitions,
|
|
storm::storage::SparseMatrix<ParametricType> const& spBackwardTransitions,
|
|
std::vector<ParametricType> const& oneStepProbs,
|
|
storm::storage::sparse::state_type const& initState
|
|
);
|
|
|
|
//initializes the given solver which can later be used to give an exact result regarding the whole model.
|
|
void initializeSMTSolver(std::shared_ptr<storm::solver::Smt2SmtSolver>& solver, ParametricType const& reachProbFunction, storm::logic::ProbabilityOperatorFormula const& formula);
|
|
|
|
/*!
|
|
* Checks the value of the function at some sampling points within the given region.
|
|
* May set the satPoint and violatedPoint of the regions if they are not yet specified and such points are found
|
|
* Also changes the regioncheckresult of the region to EXISTSSAT, EXISTSVIOLATED, or EXISTSBOTH
|
|
*
|
|
* @return true if an violated point as well as a sat point has been found during the process
|
|
*/
|
|
bool checkSamplePoints(ParameterRegion& region);
|
|
|
|
/*!
|
|
* Checks the value of the function at the given sampling point.
|
|
* May set the satPoint and violatedPoint of the regions if thy are not yet specified and such point is given.
|
|
* Also changes the regioncheckresult of the region to EXISTSSAT, EXISTSVIOLATED, or EXISTSBOTH
|
|
*
|
|
* @param viaReachProbFunction if set, the sampling will be done via the reachProbFunction.
|
|
* Otherwise, the model will be instantiated and checked
|
|
*
|
|
* @return true if an violated point as well as a sat point has been found, i.e., the check result is changed to EXISTSOTH
|
|
*/
|
|
bool checkPoint(ParameterRegion& region, std::map<VariableType, BoundType>const& point, bool viaReachProbFunction=false);
|
|
|
|
/*!
|
|
* Builds an MDP that is used to compute bounds on the maximal/minimal reachability probability,
|
|
* If this approximation already yields that the property is satisfied/violated in the whole region,
|
|
* true is returned and the regioncheckresult of the region is changed accordingly.
|
|
* The computed bounds are stored in the given vectors.
|
|
* However, it only the lowerBounds (or upperBounds) need to be computed in order to get a conclusive result,
|
|
* the upperBounds (or lowerBounds) vector remains untouched.
|
|
*/
|
|
bool checkApproximativeProbabilities(ParameterRegion& region, std::vector<ConstantType>& lowerBounds, std::vector<ConstantType>& upperBounds);
|
|
|
|
|
|
/*!
|
|
* Actually builds the mdp that is used to obtain bounds on the maximal/minimal reachability probability
|
|
*/
|
|
storm::models::sparse::Mdp<ConstantType> buildMdpForApproximation(ParameterRegion const& region);
|
|
|
|
/*!
|
|
* Starts the SMTSolver to get the result.
|
|
* The current regioncheckresult of the region should be EXISTSSAT or EXISTVIOLATED.
|
|
* Otherwise, a sampingPoint will be computed.
|
|
* True is returned iff the solver was successful (i.e., it returned sat or unsat)
|
|
* A Sat- or Violated point is set, if the solver has found one.
|
|
* The region checkResult of the given region is changed accordingly.
|
|
*/
|
|
bool checkFullSmt(ParameterRegion& region);
|
|
|
|
|
|
// The model this model checker is supposed to analyze.
|
|
storm::models::sparse::Dtmc<ParametricType> const& model;
|
|
|
|
//classes that provide auxilliary functions
|
|
// Instance of an elimination model checker to access its functions
|
|
storm::modelchecker::SparseDtmcEliminationModelChecker<ParametricType> eliminationModelChecker;
|
|
// comparators that can be used to compare constants.
|
|
storm::utility::ConstantsComparator<ParametricType> parametricTypeComparator;
|
|
storm::utility::ConstantsComparator<ConstantType> constantTypeComparator;
|
|
|
|
|
|
std::shared_ptr<storm::solver::Smt2SmtSolver> smtSolver;
|
|
|
|
|
|
//the following members depend on the currently specified formula:
|
|
|
|
//the currently specified formula
|
|
std::unique_ptr<storm::logic::ProbabilityOperatorFormula> probabilityOperatorFormula;
|
|
|
|
// The ingredients of the model where constant transitions have been eliminated as much as possible
|
|
// the probability matrix
|
|
FlexibleMatrix flexibleTransitions;
|
|
storm::storage::SparseMatrix<ParametricType> sparseTransitions;
|
|
//the corresponding backward transitions
|
|
FlexibleMatrix flexibleBackwardTransitions;
|
|
storm::storage::SparseMatrix<ParametricType> sparseBackwardTransitions;
|
|
// the propabilities to go to a state with probability 1 in one step (belongs to flexibleTransitions)
|
|
std::vector<ParametricType> oneStepProbabilities;
|
|
// the initial state
|
|
storm::storage::sparse::state_type initialState;
|
|
// the set of states that have not been eliminated
|
|
storm::storage::BitVector subsystem;
|
|
// a flag that is true if there are only linear functions at transitions of the model
|
|
bool hasOnlyLinearFunctions;
|
|
|
|
// The function for the reachability probability in the initial state
|
|
ParametricType reachProbFunction;
|
|
|
|
|
|
// runtimes and other information for statistics.
|
|
uint_fast64_t numOfCheckedRegions;
|
|
uint_fast64_t numOfRegionsSolvedThroughSampling;
|
|
uint_fast64_t numOfRegionsSolvedThroughApproximation;
|
|
uint_fast64_t numOfRegionsSolvedThroughSubsystemSmt;
|
|
uint_fast64_t numOfRegionsSolvedThroughFullSmt;
|
|
|
|
std::chrono::high_resolution_clock::duration timePreprocessing;
|
|
std::chrono::high_resolution_clock::duration timeInitialStateElimination;
|
|
std::chrono::high_resolution_clock::duration timeComputeReachProbFunction;
|
|
std::chrono::high_resolution_clock::duration timeCheckRegion;
|
|
std::chrono::high_resolution_clock::duration timeSampling;
|
|
std::chrono::high_resolution_clock::duration timeApproximation;
|
|
std::chrono::high_resolution_clock::duration timeMDPBuild;
|
|
std::chrono::high_resolution_clock::duration timeSubsystemSmt;
|
|
std::chrono::high_resolution_clock::duration timeFullSmt;
|
|
};
|
|
|
|
} // namespace modelchecker
|
|
} // namespace storm
|
|
|
|
#endif /* STORM_MODELCHECKER_REACHABILITY_SPARSEDTMCREGIONMODELCHECKER_H_ */
|