@ -174,7 +174,7 @@ namespace storm {
template < typename ParametricType , typename ConstantType >
template < typename ParametricType , typename ConstantType >
SparseDtmcRegionModelChecker < ParametricType , ConstantType > : : SparseDtmcRegionModelChecker ( storm : : models : : sparse : : Dtmc < ParametricType > const & model ) : model ( model ) , eliminationModelChecker ( model ) , smtSolver ( nullptr ) , probabilityOperatorFormula ( nullptr ) {
SparseDtmcRegionModelChecker < ParametricType , ConstantType > : : SparseDtmcRegionModelChecker ( storm : : models : : sparse : : Dtmc < ParametricType > const & model ) : model ( model ) , eliminationModelChecker ( model ) , smtSolver ( nullptr ) , probabilityOperatorFormula ( nullptr ) , sampleDtmc ( nullptr ) , approxMdp ( nullptr ) {
// Intentionally left empty.
// Intentionally left empty.
}
}
@ -255,6 +255,8 @@ namespace storm {
eliminateStatesConstSucc ( this - > subsystem , this - > flexibleTransitions , this - > flexibleBackwardTransitions , this - > oneStepProbabilities , this - > hasOnlyLinearFunctions , this - > initialState ) ;
eliminateStatesConstSucc ( this - > subsystem , this - > flexibleTransitions , this - > flexibleBackwardTransitions , this - > oneStepProbabilities , this - > hasOnlyLinearFunctions , this - > initialState ) ;
STORM_LOG_DEBUG ( " Eliminated " < < subsystem . size ( ) - subsystem . getNumberOfSetBits ( ) < < " of " < < subsystem . size ( ) < < " states that had constant outgoing transitions. " < < std : : endl ) ;
STORM_LOG_DEBUG ( " Eliminated " < < subsystem . size ( ) - subsystem . getNumberOfSetBits ( ) < < " of " < < subsystem . size ( ) < < " states that had constant outgoing transitions. " < < std : : endl ) ;
std : : cout < < " Eliminated " < < subsystem . size ( ) - subsystem . getNumberOfSetBits ( ) < < " of " < < subsystem . size ( ) < < " states that had constant outgoing transitions. " < < std : : endl ;
std : : cout < < " Eliminated " < < subsystem . size ( ) - subsystem . getNumberOfSetBits ( ) < < " of " < < subsystem . size ( ) < < " states that had constant outgoing transitions. " < < std : : endl ;
//eliminate the remaining states to get the reachability probability function
//eliminate the remaining states to get the reachability probability function
this - > sparseTransitions = flexibleTransitions . getSparseMatrix ( ) ;
this - > sparseTransitions = flexibleTransitions . getSparseMatrix ( ) ;
this - > sparseBackwardTransitions = this - > sparseTransitions . transpose ( ) ;
this - > sparseBackwardTransitions = this - > sparseTransitions . transpose ( ) ;
@ -270,6 +272,7 @@ namespace storm {
std : : chrono : : high_resolution_clock : : time_point timeInitialStateEliminationEnd = std : : chrono : : high_resolution_clock : : now ( ) ;
std : : chrono : : high_resolution_clock : : time_point timeInitialStateEliminationEnd = std : : chrono : : high_resolution_clock : : now ( ) ;
initializeSampleDtmcAndApproxMdp ( this - > sampleDtmc , this - > sampleDtmcMapping , this - > approxMdp , this - > approxMdpMapping , this - > approxMdpSubstitutions , this - > subsystem , this - > sparseTransitions , this - > oneStepProbabilities , this - > initialState ) ;
initializeSMTSolver ( this - > smtSolver , this - > reachProbFunction , * this - > probabilityOperatorFormula ) ;
initializeSMTSolver ( this - > smtSolver , this - > reachProbFunction , * this - > probabilityOperatorFormula ) ;
//some information for statistics...
//some information for statistics...
@ -282,6 +285,9 @@ namespace storm {
this - > numOfRegionsSolvedThroughApproximation = 0 ;
this - > numOfRegionsSolvedThroughApproximation = 0 ;
this - > numOfRegionsSolvedThroughSubsystemSmt = 0 ;
this - > numOfRegionsSolvedThroughSubsystemSmt = 0 ;
this - > numOfRegionsSolvedThroughFullSmt = 0 ;
this - > numOfRegionsSolvedThroughFullSmt = 0 ;
this - > numOfRegionsExistsBoth = 0 ;
this - > numOfRegionsAllSat = 0 ;
this - > numOfRegionsAllViolated = 0 ;
this - > timeCheckRegion = std : : chrono : : high_resolution_clock : : duration : : zero ( ) ;
this - > timeCheckRegion = std : : chrono : : high_resolution_clock : : duration : : zero ( ) ;
this - > timeSampling = std : : chrono : : high_resolution_clock : : duration : : zero ( ) ;
this - > timeSampling = std : : chrono : : high_resolution_clock : : duration : : zero ( ) ;
this - > timeApproximation = std : : chrono : : high_resolution_clock : : duration : : zero ( ) ;
this - > timeApproximation = std : : chrono : : high_resolution_clock : : duration : : zero ( ) ;
@ -325,6 +331,203 @@ namespace storm {
subsys . set ( initialState , true ) ;
subsys . set ( initialState , true ) ;
}
}
template < typename ParametricType , typename ConstantType >
void SparseDtmcRegionModelChecker < ParametricType , ConstantType > : : initializeSampleDtmcAndApproxMdp (
std : : shared_ptr < storm : : models : : sparse : : Dtmc < ConstantType > > & sampleDtmc ,
std : : vector < std : : pair < ParametricType , storm : : storage : : MatrixEntry < storm : : storage : : sparse : : state_type , ConstantType > & > > & sampleDtmcMapping ,
std : : shared_ptr < storm : : models : : sparse : : Mdp < ConstantType > > & approxMdp ,
std : : vector < std : : tuple < ParametricType , storm : : storage : : MatrixEntry < storm : : storage : : sparse : : state_type , ConstantType > & , std : : size_t > > & approxMdpMapping ,
std : : vector < std : : map < VariableType , TypeOfBound > > & approxMdpSubstitutions ,
storm : : storage : : BitVector const & subsys ,
storm : : storage : : SparseMatrix < ParametricType > const & transitions ,
std : : vector < ParametricType > const & oneStepProbs ,
storm : : storage : : sparse : : state_type const & initState ) {
//the matrix "transitions" might have empty rows where states have been eliminated.
//The DTMC/ MDP matrices should not have such rows. We therefore leave them out, but we have to change the indices of the states accordingly.
std : : vector < storm : : storage : : sparse : : state_type > newStateIndexMap ( transitions . getRowCount ( ) , transitions . getRowCount ( ) ) ; //initialize with some illegal index to easily check if a transition leads to an unselected state
storm : : storage : : sparse : : state_type newStateIndex = 0 ;
for ( auto const & state : subsys ) {
newStateIndexMap [ state ] = newStateIndex ;
+ + newStateIndex ;
}
//We need to add a target state to which the oneStepProbabilities will lead as well as a sink state to which the "missing" probability will lead
storm : : storage : : sparse : : state_type numStates = newStateIndex + 2 ;
storm : : storage : : sparse : : state_type targetState = numStates - 2 ;
storm : : storage : : sparse : : state_type sinkState = numStates - 1 ;
//We can now fill in the dummy data of the transition matrices for dtmc and mdp
std : : vector < ParametricType > oneStepToSink ( oneStepProbs . size ( ) , storm : : utility : : zero < ParametricType > ( ) ) ; // -2 because not needed for target and sink state
storm : : storage : : SparseMatrixBuilder < ConstantType > dtmcMatrixBuilder ( numStates , numStates ) ;
storm : : storage : : SparseMatrixBuilder < ConstantType > mdpMatrixBuilder ( 0 , numStates , 0 , true , true , numStates ) ;
std : : vector < std : : map < VariableType , TypeOfBound > > mdpRowSubstitutions ;
storm : : storage : : sparse : : state_type currentMdpRow = 0 ;
//go through rows:
for ( storm : : storage : : sparse : : state_type oldStateIndex : subsys ) {
ParametricType valueToSinkState = storm : : utility : : regions : : getNewFunction < ParametricType , BoundType > ( storm : : utility : : one < BoundType > ( ) ) ;
// the dtmc and the mdp rows need to sum up to one, therefore the first entry that we add has value one.
ConstantType dummyEntry = storm : : utility : : one < ConstantType > ( ) ;
// store the columns and values that we have added because we need the same information for the next rows in the mdp
std : : vector < std : : pair < storm : : storage : : sparse : : state_type , ConstantType > > rowInformation ;
mdpMatrixBuilder . newRowGroup ( currentMdpRow ) ;
std : : set < VariableType > occurringParameters ;
//go through columns:
for ( auto const & entry : transitions . getRow ( oldStateIndex ) ) {
valueToSinkState - = entry . getValue ( ) ;
storm : : utility : : regions : : gatherOccurringVariables ( entry . getValue ( ) , occurringParameters ) ;
dtmcMatrixBuilder . addNextValue ( newStateIndexMap [ oldStateIndex ] , newStateIndexMap [ entry . getColumn ( ) ] , dummyEntry ) ;
mdpMatrixBuilder . addNextValue ( currentMdpRow , newStateIndexMap [ entry . getColumn ( ) ] , dummyEntry ) ;
rowInformation . emplace_back ( std : : make_pair ( newStateIndexMap [ entry . getColumn ( ) ] , dummyEntry ) ) ;
dummyEntry = storm : : utility : : zero < ConstantType > ( ) ;
STORM_LOG_THROW ( newStateIndexMap [ entry . getColumn ( ) ] ! = transitions . getRowCount ( ) , storm : : exceptions : : UnexpectedException , " There is a transition to a state that should have been eliminated. " ) ;
}
//transition to target state
if ( ! this - > parametricTypeComparator . isZero ( oneStepProbs [ oldStateIndex ] ) ) {
valueToSinkState - = oneStepProbs [ oldStateIndex ] ;
storm : : utility : : regions : : gatherOccurringVariables ( oneStepProbs [ oldStateIndex ] , occurringParameters ) ;
dtmcMatrixBuilder . addNextValue ( newStateIndexMap [ oldStateIndex ] , targetState , dummyEntry ) ;
mdpMatrixBuilder . addNextValue ( currentMdpRow , targetState , dummyEntry ) ;
rowInformation . emplace_back ( std : : make_pair ( targetState , dummyEntry ) ) ;
dummyEntry = storm : : utility : : zero < ConstantType > ( ) ;
}
//transition to sink state
if ( ! this - > parametricTypeComparator . isZero ( valueToSinkState ) ) {
dtmcMatrixBuilder . addNextValue ( newStateIndexMap [ oldStateIndex ] , sinkState , dummyEntry ) ;
mdpMatrixBuilder . addNextValue ( currentMdpRow , sinkState , dummyEntry ) ;
rowInformation . emplace_back ( std : : make_pair ( sinkState , dummyEntry ) ) ;
oneStepToSink [ oldStateIndex ] = valueToSinkState ;
}
// Find the different combinations of occuring variables and lower/upper bounds (mathematically speaking we want to have the set 'occuringVariables times {u,l}' )
std : : size_t numOfSubstitutions = std : : pow ( 2 , occurringParameters . size ( ) ) ; //1 substitution = 1 combination of lower and upper bounds
for ( uint_fast64_t substitutionId = 0 ; substitutionId < numOfSubstitutions ; + + substitutionId ) {
//interprete substitutionId as a bit sequence
//the occurringParameters.size() least significant bits of substitutionId will always represent the next substitution that we have to add
//(00...0 = lower bounds for all parameters, 11...1 = upper bounds for all parameters)
mdpRowSubstitutions . emplace_back ( ) ;
std : : size_t parameterIndex = 0 ;
for ( auto const & parameter : occurringParameters ) {
if ( ( substitutionId > > parameterIndex ) % 2 = = 0 ) {
mdpRowSubstitutions . back ( ) . insert ( std : : make_pair ( parameter , TypeOfBound : : LOWER ) ) ;
}
else {
mdpRowSubstitutions . back ( ) . insert ( std : : make_pair ( parameter , TypeOfBound : : UPPER ) ) ;
}
+ + parameterIndex ;
}
}
//We already added one row in the MDP. Now add the remaining 2^(occuringParameters.size())-1 rows
for ( + + currentMdpRow ; currentMdpRow < mdpRowSubstitutions . size ( ) ; + + currentMdpRow ) {
for ( auto const & entryOfThisRow : rowInformation ) {
mdpMatrixBuilder . addNextValue ( currentMdpRow , entryOfThisRow . first , entryOfThisRow . second ) ;
}
}
}
//add self loops on the additional states (i.e., target and sink)
dtmcMatrixBuilder . addNextValue ( targetState , targetState , storm : : utility : : one < ConstantType > ( ) ) ;
dtmcMatrixBuilder . addNextValue ( sinkState , sinkState , storm : : utility : : one < ConstantType > ( ) ) ;
mdpMatrixBuilder . newRowGroup ( currentMdpRow ) ;
mdpMatrixBuilder . addNextValue ( currentMdpRow , targetState , storm : : utility : : one < ConstantType > ( ) ) ;
+ + currentMdpRow ;
mdpMatrixBuilder . newRowGroup ( currentMdpRow ) ;
mdpMatrixBuilder . addNextValue ( currentMdpRow , sinkState , storm : : utility : : one < ConstantType > ( ) ) ;
+ + currentMdpRow ;
//The DTMC labeling
storm : : models : : sparse : : StateLabeling dtmcStateLabeling ( numStates ) ;
storm : : storage : : BitVector initLabel ( numStates , false ) ;
initLabel . set ( newStateIndexMap [ this - > initialState ] , true ) ;
dtmcStateLabeling . addLabel ( " init " , std : : move ( initLabel ) ) ;
storm : : storage : : BitVector targetLabel ( numStates , false ) ;
targetLabel . set ( numStates - 2 , true ) ;
dtmcStateLabeling . addLabel ( " target " , std : : move ( targetLabel ) ) ;
storm : : storage : : BitVector sinkLabel ( numStates , false ) ;
sinkLabel . set ( numStates - 1 , true ) ;
dtmcStateLabeling . addLabel ( " sink " , std : : move ( sinkLabel ) ) ;
// The MDP labeling (is the same)
storm : : models : : sparse : : StateLabeling mdpStateLabeling ( dtmcStateLabeling ) ;
// other ingredients
boost : : optional < std : : vector < ConstantType > > dtmcNoStateRewards , mdpNoStateRewards ;
boost : : optional < storm : : storage : : SparseMatrix < ConstantType > > dtmcNoTransitionRewards , mdpNoTransitionRewards ;
boost : : optional < std : : vector < boost : : container : : flat_set < uint_fast64_t > > > dtmcNoChoiceLabeling , mdpNoChoiceLabeling ;
// the final dtmc and mdp
sampleDtmc = std : : make_shared < storm : : models : : sparse : : Dtmc < ConstantType > > ( dtmcMatrixBuilder . build ( ) , std : : move ( dtmcStateLabeling ) , std : : move ( dtmcNoStateRewards ) , std : : move ( dtmcNoTransitionRewards ) , std : : move ( dtmcNoChoiceLabeling ) ) ;
approxMdp = std : : make_shared < storm : : models : : sparse : : Mdp < ConstantType > > ( mdpMatrixBuilder . build ( ) , std : : move ( mdpStateLabeling ) , std : : move ( mdpNoStateRewards ) , std : : move ( mdpNoTransitionRewards ) , std : : move ( mdpNoChoiceLabeling ) ) ;
//build mapping vectors and the substitution vector.
sampleDtmcMapping = std : : vector < std : : pair < ParametricType , storm : : storage : : MatrixEntry < storm : : storage : : sparse : : state_type , ConstantType > & > > ( ) ;
sampleDtmcMapping . reserve ( sampleDtmc - > getTransitionMatrix ( ) . getEntryCount ( ) ) ;
approxMdpMapping = std : : vector < std : : tuple < ParametricType , storm : : storage : : MatrixEntry < storm : : storage : : sparse : : state_type , ConstantType > & , std : : size_t > > ( ) ;
approxMdpMapping . reserve ( approxMdp - > getTransitionMatrix ( ) . getEntryCount ( ) ) ;
approxMdpSubstitutions = std : : vector < std : : map < VariableType , TypeOfBound > > ( ) ;
currentMdpRow = 0 ;
//go through rows:
for ( storm : : storage : : sparse : : state_type oldStateIndex : subsys ) {
//Get the index of the substitution for the current mdp row. (add it to approxMdpSubstitutions if we see this substitution the first time)
std : : size_t substitutionIndex = std : : find ( approxMdpSubstitutions . begin ( ) , approxMdpSubstitutions . end ( ) , mdpRowSubstitutions [ currentMdpRow ] ) - approxMdpSubstitutions . begin ( ) ;
if ( substitutionIndex = = approxMdpSubstitutions . size ( ) ) {
approxMdpSubstitutions . push_back ( mdpRowSubstitutions [ currentMdpRow ] ) ;
}
typename storm : : storage : : SparseMatrix < ConstantType > : : iterator dtmcEntryIt = sampleDtmc - > getTransitionMatrix ( ) . getRow ( newStateIndexMap [ oldStateIndex ] ) . begin ( ) ;
typename storm : : storage : : SparseMatrix < ConstantType > : : iterator mdpEntryIt = approxMdp - > getTransitionMatrix ( ) . getRow ( currentMdpRow ) . begin ( ) ;
//go through columns to fill the dtmc and the first mdp row (of this group):
for ( auto const & entry : transitions . getRow ( oldStateIndex ) ) {
STORM_LOG_THROW ( newStateIndexMap [ entry . getColumn ( ) ] = = dtmcEntryIt - > getColumn ( ) , storm : : exceptions : : UnexpectedException , " The entries of the DTMC matrix and the pDtmc Transitionmatrix do not match " ) ;
STORM_LOG_THROW ( newStateIndexMap [ entry . getColumn ( ) ] = = mdpEntryIt - > getColumn ( ) , storm : : exceptions : : UnexpectedException , " The entries of the MDP matrix and the pDtmc Transitionmatrix do not match ( " < < newStateIndexMap [ entry . getColumn ( ) ] < < " vs " < < mdpEntryIt - > getColumn ( ) < < " ) " ) ;
sampleDtmcMapping . emplace_back ( entry . getValue ( ) , * dtmcEntryIt ) ;
approxMdpMapping . emplace_back ( entry . getValue ( ) , * mdpEntryIt , substitutionIndex ) ;
+ + dtmcEntryIt ;
+ + mdpEntryIt ;
}
//transition to target state
if ( ! this - > parametricTypeComparator . isZero ( oneStepProbs [ oldStateIndex ] ) ) {
STORM_LOG_THROW ( targetState = = dtmcEntryIt - > getColumn ( ) , storm : : exceptions : : UnexpectedException , " The entry of the DTMC matrix should match the target state but it does not. " ) ;
STORM_LOG_THROW ( targetState = = mdpEntryIt - > getColumn ( ) , storm : : exceptions : : UnexpectedException , " The entry of the MDP matrix should match the target state but it does not. " ) ;
sampleDtmcMapping . emplace_back ( oneStepProbs [ oldStateIndex ] , * dtmcEntryIt ) ;
approxMdpMapping . emplace_back ( oneStepProbs [ oldStateIndex ] , * mdpEntryIt , substitutionIndex ) ;
+ + dtmcEntryIt ;
+ + mdpEntryIt ;
}
//transition to sink state
if ( ! this - > parametricTypeComparator . isZero ( oneStepToSink [ oldStateIndex ] ) ) {
STORM_LOG_THROW ( sinkState = = dtmcEntryIt - > getColumn ( ) , storm : : exceptions : : UnexpectedException , " The entry of the DTMC matrix should match the sink state but it does not. " ) ;
STORM_LOG_THROW ( sinkState = = mdpEntryIt - > getColumn ( ) , storm : : exceptions : : UnexpectedException , " The entry of the MDP matrix should match the sink state but it does not. " ) ;
sampleDtmcMapping . emplace_back ( oneStepToSink [ oldStateIndex ] , * dtmcEntryIt ) ;
approxMdpMapping . emplace_back ( oneStepToSink [ oldStateIndex ] , * mdpEntryIt , substitutionIndex ) ;
+ + dtmcEntryIt ;
+ + mdpEntryIt ;
}
//fill in the remaining rows of the mdp
storm : : storage : : sparse : : state_type startOfNextRowGroup = currentMdpRow + approxMdp - > getTransitionMatrix ( ) . getRowGroupSize ( newStateIndexMap [ oldStateIndex ] ) ;
for ( + + currentMdpRow ; currentMdpRow < startOfNextRowGroup ; + + currentMdpRow ) {
//Get the new substitution index
substitutionIndex = std : : find ( approxMdpSubstitutions . begin ( ) , approxMdpSubstitutions . end ( ) , mdpRowSubstitutions [ currentMdpRow ] ) - approxMdpSubstitutions . begin ( ) ;
if ( substitutionIndex = = approxMdpSubstitutions . size ( ) ) {
approxMdpSubstitutions . push_back ( mdpRowSubstitutions [ currentMdpRow ] ) ;
}
//go through columns
mdpEntryIt = approxMdp - > getTransitionMatrix ( ) . getRow ( currentMdpRow ) . begin ( ) ;
for ( auto const & entry : transitions . getRow ( oldStateIndex ) ) {
STORM_LOG_THROW ( newStateIndexMap [ entry . getColumn ( ) ] = = mdpEntryIt - > getColumn ( ) , storm : : exceptions : : UnexpectedException , " The entries of the MDP matrix and the pDtmc Transitionmatrix do not match " ) ;
approxMdpMapping . emplace_back ( entry . getValue ( ) , * mdpEntryIt , substitutionIndex ) ;
+ + mdpEntryIt ;
}
//transition to target state
if ( ! this - > parametricTypeComparator . isZero ( oneStepProbs [ oldStateIndex ] ) ) {
STORM_LOG_THROW ( targetState = = mdpEntryIt - > getColumn ( ) , storm : : exceptions : : UnexpectedException , " The entry of the MDP matrix should match the target state but it does not. " ) ;
approxMdpMapping . emplace_back ( oneStepProbs [ oldStateIndex ] , * mdpEntryIt , substitutionIndex ) ;
+ + mdpEntryIt ;
}
//transition to sink state
if ( ! this - > parametricTypeComparator . isZero ( oneStepToSink [ oldStateIndex ] ) ) {
STORM_LOG_THROW ( sinkState = = mdpEntryIt - > getColumn ( ) , storm : : exceptions : : UnexpectedException , " The entry of the MDP matrix should match the sink state but it does not. " ) ;
approxMdpMapping . emplace_back ( oneStepToSink [ oldStateIndex ] , * mdpEntryIt , substitutionIndex ) ;
+ + mdpEntryIt ;
}
}
}
}
template < typename ParametricType , typename ConstantType >
template < typename ParametricType , typename ConstantType >
ParametricType SparseDtmcRegionModelChecker < ParametricType , ConstantType > : : computeReachProbFunction (
ParametricType SparseDtmcRegionModelChecker < ParametricType , ConstantType > : : computeReachProbFunction (
@ -444,7 +647,7 @@ namespace storm {
STORM_LOG_THROW ( this - > probabilityOperatorFormula ! = nullptr , storm : : exceptions : : InvalidStateException , " Tried to analyze a region although no property has been specified " ) ;
STORM_LOG_THROW ( this - > probabilityOperatorFormula ! = nullptr , storm : : exceptions : : InvalidStateException , " Tried to analyze a region although no property has been specified " ) ;
STORM_LOG_DEBUG ( " Analyzing the region " < < region . toString ( ) ) ;
STORM_LOG_DEBUG ( " Analyzing the region " < < region . toString ( ) ) ;
std : : cout < < " Analyzing the region " < < region . toString ( ) < < std : : endl ;
// std::cout << "Analyzing the region " << region.toString() << std::endl;
//switches for the different steps.
//switches for the different steps.
bool doApproximation = this - > hasOnlyLinearFunctions ; // this approach is only correct if the model has only linear functions
bool doApproximation = this - > hasOnlyLinearFunctions ; // this approach is only correct if the model has only linear functions
@ -457,13 +660,13 @@ namespace storm {
std : : vector < ConstantType > upperBounds ;
std : : vector < ConstantType > upperBounds ;
if ( doApproximation ) {
if ( doApproximation ) {
STORM_LOG_DEBUG ( " Checking approximative probabilities... " ) ;
STORM_LOG_DEBUG ( " Checking approximative probabilities... " ) ;
std : : cout < < " Checking approximative probabilities... " < < std : : endl ;
// std::cout << " Checking approximative probabilities..." << std::endl;
if ( checkApproximativeProbabilities ( region , lowerBounds , upperBounds ) ) {
if ( checkApproximativeProbabilities ( region , lowerBounds , upperBounds ) ) {
+ + this - > numOfRegionsSolvedThroughApproximation ;
+ + this - > numOfRegionsSolvedThroughApproximation ;
STORM_LOG_DEBUG ( " Result ' " < < region . checkResultToString ( ) < < " ' obtained through approximation. " ) ;
STORM_LOG_DEBUG ( " Result ' " < < region . checkResultToString ( ) < < " ' obtained through approximation. " ) ;
doSampling = false ;
doSampling = false ;
doSubsystemSmt = false ;
doSubsystemSmt = false ;
doFullSmt = true ; //TODO set this back to false.. this is just for testing
doFullSmt = false ;
}
}
}
}
std : : chrono : : high_resolution_clock : : time_point timeApproximationEnd = std : : chrono : : high_resolution_clock : : now ( ) ;
std : : chrono : : high_resolution_clock : : time_point timeApproximationEnd = std : : chrono : : high_resolution_clock : : now ( ) ;
@ -471,13 +674,13 @@ namespace storm {
std : : chrono : : high_resolution_clock : : time_point timeSamplingStart = std : : chrono : : high_resolution_clock : : now ( ) ;
std : : chrono : : high_resolution_clock : : time_point timeSamplingStart = std : : chrono : : high_resolution_clock : : now ( ) ;
if ( doSampling ) {
if ( doSampling ) {
STORM_LOG_DEBUG ( " Checking sample points... " ) ;
STORM_LOG_DEBUG ( " Checking sample points... " ) ;
std : : cout < < " Checking sample points... " < < std : : endl ;
// std::cout << " Checking sample points..." << std::endl;
if ( checkSamplePoints ( region ) ) {
if ( checkSamplePoints ( region ) ) {
+ + this - > numOfRegionsSolvedThroughSampling ;
+ + this - > numOfRegionsSolvedThroughSampling ;
STORM_LOG_DEBUG ( " Result ' " < < region . checkResultToString ( ) < < " ' obtained through sampling. " ) ;
STORM_LOG_DEBUG ( " Result ' " < < region . checkResultToString ( ) < < " ' obtained through sampling. " ) ;
doApproximation = false ;
doApproximation = false ;
doSubsystemSmt = false ;
doSubsystemSmt = false ;
doFullSmt = true ; //TODO set this back to false.. this is just for testing
doFullSmt = false ;
}
}
}
}
std : : chrono : : high_resolution_clock : : time_point timeSamplingEnd = std : : chrono : : high_resolution_clock : : now ( ) ;
std : : chrono : : high_resolution_clock : : time_point timeSamplingEnd = std : : chrono : : high_resolution_clock : : now ( ) ;
@ -491,7 +694,7 @@ namespace storm {
std : : chrono : : high_resolution_clock : : time_point timeFullSmtStart = std : : chrono : : high_resolution_clock : : now ( ) ;
std : : chrono : : high_resolution_clock : : time_point timeFullSmtStart = std : : chrono : : high_resolution_clock : : now ( ) ;
if ( doFullSmt ) {
if ( doFullSmt ) {
STORM_LOG_DEBUG ( " Checking with Smt Solving... " ) ;
STORM_LOG_DEBUG ( " Checking with Smt Solving... " ) ;
std : : cout < < " Checking with Smt Solving... " < < std : : endl ;
// std::cout << " Checking with Smt Solving..." << std::endl;
if ( checkFullSmt ( region ) ) {
if ( checkFullSmt ( region ) ) {
+ + this - > numOfRegionsSolvedThroughFullSmt ;
+ + this - > numOfRegionsSolvedThroughFullSmt ;
STORM_LOG_DEBUG ( " Result ' " < < region . checkResultToString ( ) < < " ' obtained through Smt Solving. " ) ;
STORM_LOG_DEBUG ( " Result ' " < < region . checkResultToString ( ) < < " ' obtained through Smt Solving. " ) ;
@ -510,22 +713,46 @@ namespace storm {
this - > timeApproximation + = timeApproximationEnd - timeApproximationStart ;
this - > timeApproximation + = timeApproximationEnd - timeApproximationStart ;
this - > timeSubsystemSmt + = timeSubsystemSmtEnd - timeSubsystemSmtStart ;
this - > timeSubsystemSmt + = timeSubsystemSmtEnd - timeSubsystemSmtStart ;
this - > timeFullSmt + = timeFullSmtEnd - timeFullSmtStart ;
this - > timeFullSmt + = timeFullSmtEnd - timeFullSmtStart ;
switch ( region . getCheckResult ( ) ) {
case RegionCheckResult : : EXISTSBOTH :
+ + this - > numOfRegionsExistsBoth ;
break ;
case RegionCheckResult : : ALLSAT :
+ + this - > numOfRegionsAllSat ;
break ;
case RegionCheckResult : : ALLVIOLATED :
+ + this - > numOfRegionsAllViolated ;
break ;
default :
break ;
}
}
}
template < typename ParametricType , typename ConstantType >
template < typename ParametricType , typename ConstantType >
void SparseDtmcRegionModelChecker < ParametricType , ConstantType > : : checkRegions ( std : : vector < ParameterRegion > & regions ) {
void SparseDtmcRegionModelChecker < ParametricType , ConstantType > : : checkRegions ( std : : vector < ParameterRegion > & regions ) {
STORM_LOG_DEBUG ( " Checking " < < regions . size ( ) < < " regions. " ) ;
std : : cout < < " Checking " < < regions . size ( ) < < " regions. Progress: " ;
std : : cout . flush ( ) ;
uint_fast64_t progress = 0 ;
uint_fast64_t checkedRegions = 0 ;
for ( auto & region : regions ) {
for ( auto & region : regions ) {
this - > checkRegion ( region ) ;
this - > checkRegion ( region ) ;
if ( ( checkedRegions + + ) * 10 / regions . size ( ) = = progress ) {
std : : cout < < progress + + ;
std : : cout . flush ( ) ;
}
}
}
}
std : : cout < < std : : endl ;
}
template < typename ParametricType , typename ConstantType >
template < typename ParametricType , typename ConstantType >
bool SparseDtmcRegionModelChecker < ParametricType , ConstantType > : : checkSamplePoints ( ParameterRegion & region ) {
bool SparseDtmcRegionModelChecker < ParametricType , ConstantType > : : checkSamplePoints ( ParameterRegion & region ) {
auto samplingPoints = region . getVerticesOfRegion ( region . getVariables ( ) ) ; //test the 4 corner points
auto samplingPoints = region . getVerticesOfRegion ( region . getVariables ( ) ) ; //test the 4 corner points
for ( auto const & point : samplingPoints ) {
for ( auto const & point : samplingPoints ) {
if ( checkPoint ( region , point , tru e) ) {
if ( checkPoint ( region , point , fals e) ) {
return true ;
return true ;
}
}
}
}
@ -540,7 +767,26 @@ namespace storm {
valueInBoundOfFormula = this - > valueIsInBoundOfFormula ( storm : : utility : : regions : : evaluateFunction < ParametricType , ConstantType > ( this - > reachProbFunction , point ) ) ;
valueInBoundOfFormula = this - > valueIsInBoundOfFormula ( storm : : utility : : regions : : evaluateFunction < ParametricType , ConstantType > ( this - > reachProbFunction , point ) ) ;
}
}
else {
else {
STORM_LOG_THROW ( false , storm : : exceptions : : NotImplementedException , " sample point check with model instantiation not yet implemented " ) ;
//put the values into the dtmc matrix
for ( std : : pair < ParametricType , typename storm : : storage : : MatrixEntry < storm : : storage : : sparse : : state_type , ConstantType > & > & mappingPair : this - > sampleDtmcMapping ) {
mappingPair . second . setValue ( storm : : utility : : regions : : convertNumber < BoundType , ConstantType > (
storm : : utility : : regions : : evaluateFunction < ParametricType , ConstantType > ( mappingPair . first , point )
)
) ;
}
std : : shared_ptr < storm : : logic : : Formula > targetFormulaPtr ( new storm : : logic : : AtomicLabelFormula ( " target " ) ) ;
storm : : logic : : EventuallyFormula eventuallyFormula ( targetFormulaPtr ) ;
storm : : modelchecker : : SparseDtmcPrctlModelChecker < ConstantType > modelChecker ( * this - > sampleDtmc ) ;
std : : unique_ptr < storm : : modelchecker : : CheckResult > resultPtr = modelChecker . computeEventuallyProbabilities ( eventuallyFormula , false ) ;
valueInBoundOfFormula = this - > valueIsInBoundOfFormula ( resultPtr - > asExplicitQuantitativeCheckResult < ConstantType > ( ) . getValueVector ( ) [ * this - > sampleDtmc - > getInitialStates ( ) . begin ( ) ] ) ;
//Delete from here
// ConstantType result=resultPtr->asExplicitQuantitativeCheckResult<ConstantType>().getValueVector()[*this->sampleDtmc->getInitialStates().begin()];
// ConstantType otherresult=storm::utility::regions::convertNumber<BoundType, ConstantType>(storm::utility::regions::evaluateFunction<ParametricType, ConstantType>(this->reachProbFunction, point));
// STORM_LOG_THROW((std::abs(result - otherresult) <= 0.01),storm::exceptions::UnexpectedException, "The results of new DTMC algorithm does not match: " << result << " vs. " << otherresult);
//To here
}
}
if ( valueInBoundOfFormula ) {
if ( valueInBoundOfFormula ) {
@ -571,12 +817,14 @@ namespace storm {
STORM_LOG_THROW ( this - > hasOnlyLinearFunctions , storm : : exceptions : : UnexpectedException , " Tried to generate bounds on the probability (only applicable if all functions are linear), but there are nonlinear functions. " ) ;
STORM_LOG_THROW ( this - > hasOnlyLinearFunctions , storm : : exceptions : : UnexpectedException , " Tried to generate bounds on the probability (only applicable if all functions are linear), but there are nonlinear functions. " ) ;
//build the mdp and a reachability formula and create a modelchecker
//build the mdp and a reachability formula and create a modelchecker
std : : chrono : : high_resolution_clock : : time_point timeMDPBuildStart = std : : chrono : : high_resolution_clock : : now ( ) ;
std : : chrono : : high_resolution_clock : : time_point timeMDPBuildStart = std : : chrono : : high_resolution_clock : : now ( ) ;
storm : : models : : sparse : : Mdp < ConstantType > mdp = buildMdpForApproximation ( region ) ;
buildMdpForApproximation ( region ) ;
std : : chrono : : high_resolution_clock : : time_point timeMDPBuildEnd = std : : chrono : : high_resolution_clock : : now ( ) ;
std : : chrono : : high_resolution_clock : : time_point timeMDPBuildEnd = std : : chrono : : high_resolution_clock : : now ( ) ;
this - > timeMDPBuild + = timeMDPBuildEnd - timeMDPBuildStart ;
this - > timeMDPBuild + = timeMDPBuildEnd - timeMDPBuildStart ;
std : : shared_ptr < storm : : logic : : Formula > targetFormulaPtr ( new storm : : logic : : AtomicLabelFormula ( " target " ) ) ;
std : : shared_ptr < storm : : logic : : Formula > targetFormulaPtr ( new storm : : logic : : AtomicLabelFormula ( " target " ) ) ;
storm : : logic : : EventuallyFormula eventuallyFormula ( targetFormulaPtr ) ;
storm : : logic : : EventuallyFormula eventuallyFormula ( targetFormulaPtr ) ;
storm : : modelchecker : : SparseMdpPrctlModelChecker < ConstantType > modelChecker ( mdp ) ;
storm : : modelchecker : : SparseMdpPrctlModelChecker < ConstantType > modelChecker ( * this - > approxMdp ) ;
//Decide whether we should compute lower or upper bounds first.
//Decide whether we should compute lower or upper bounds first.
//This does not matter if the current result is unknown. However, let us assume that it is more likely that the final result will be ALLSAT. So we test this first.
//This does not matter if the current result is unknown. However, let us assume that it is more likely that the final result will be ALLSAT. So we test this first.
@ -620,10 +868,19 @@ namespace storm {
//perform model checking on the mdp
//perform model checking on the mdp
std : : unique_ptr < storm : : modelchecker : : CheckResult > resultPtr = modelChecker . computeEventuallyProbabilities ( eventuallyFormula , false , opType ) ;
std : : unique_ptr < storm : : modelchecker : : CheckResult > resultPtr = modelChecker . computeEventuallyProbabilities ( eventuallyFormula , false , opType ) ;
//DELETE FROM HERE
// storm::models::sparse::Mdp<ConstantType> othermdp = buildMdpForApproximation2(region);
// storm::modelchecker::SparseMdpPrctlModelChecker<ConstantType> othermodelChecker(othermdp);
// std::unique_ptr<storm::modelchecker::CheckResult> otherresultPtr = othermodelChecker.computeEventuallyProbabilities(eventuallyFormula,false,opType);
// ConstantType origResult=resultPtr->asExplicitQuantitativeCheckResult<ConstantType>().getValueVector()[*this->approxMdp->getInitialStates().begin()];
// ConstantType otherResult=otherresultPtr->asExplicitQuantitativeCheckResult<ConstantType>().getValueVector()[*othermdp.getInitialStates().begin()];
// STORM_LOG_THROW(this->constantTypeComparator.isEqual(origResult,otherResult),storm::exceptions::UnexpectedException, "The results of new mdp algorithm does not match: " << origResult << " vs. " << otherResult);
//TO HERE
//check if the approximation yielded a conclusive result
//check if the approximation yielded a conclusive result
if ( opType = = storm : : logic : : OptimalityType : : Maximize ) {
if ( opType = = storm : : logic : : OptimalityType : : Maximize ) {
upperBounds = resultPtr - > asExplicitQuantitativeCheckResult < ConstantType > ( ) . getValueVector ( ) ;
upperBounds = resultPtr - > asExplicitQuantitativeCheckResult < ConstantType > ( ) . getValueVector ( ) ;
if ( valueIsInBoundOfFormula ( upperBounds [ * mdp . getInitialStates ( ) . begin ( ) ] ) ) {
if ( valueIsInBoundOfFormula ( upperBounds [ * this - > approxMdp - > getInitialStates ( ) . begin ( ) ] ) ) {
if ( ( this - > probabilityOperatorFormula - > getComparisonType ( ) = = storm : : logic : : ComparisonType : : Less ) | |
if ( ( this - > probabilityOperatorFormula - > getComparisonType ( ) = = storm : : logic : : ComparisonType : : Less ) | |
( this - > probabilityOperatorFormula - > getComparisonType ( ) = = storm : : logic : : ComparisonType : : LessEqual ) ) {
( this - > probabilityOperatorFormula - > getComparisonType ( ) = = storm : : logic : : ComparisonType : : LessEqual ) ) {
region . setCheckResult ( RegionCheckResult : : ALLSAT ) ;
region . setCheckResult ( RegionCheckResult : : ALLSAT ) ;
@ -639,11 +896,11 @@ namespace storm {
}
}
//flip the optype for the next iteration
//flip the optype for the next iteration
opType = storm : : logic : : OptimalityType : : Minimize ;
opType = storm : : logic : : OptimalityType : : Minimize ;
if ( i = = 1 ) std : : cout < < " Requiring a second model checker run (with Minimize) " < < std : : endl ;
// if(i==1) std::cout << " Requiring a second model checker run (with Minimize)" << std::endl;
}
}
else if ( opType = = storm : : logic : : OptimalityType : : Minimize ) {
else if ( opType = = storm : : logic : : OptimalityType : : Minimize ) {
lowerBounds = resultPtr - > asExplicitQuantitativeCheckResult < ConstantType > ( ) . getValueVector ( ) ;
lowerBounds = resultPtr - > asExplicitQuantitativeCheckResult < ConstantType > ( ) . getValueVector ( ) ;
if ( valueIsInBoundOfFormula ( lowerBounds [ * mdp . getInitialStates ( ) . begin ( ) ] ) ) {
if ( valueIsInBoundOfFormula ( lowerBounds [ * this - > approxMdp - > getInitialStates ( ) . begin ( ) ] ) ) {
if ( ( this - > probabilityOperatorFormula - > getComparisonType ( ) = = storm : : logic : : ComparisonType : : Greater ) | |
if ( ( this - > probabilityOperatorFormula - > getComparisonType ( ) = = storm : : logic : : ComparisonType : : Greater ) | |
( this - > probabilityOperatorFormula - > getComparisonType ( ) = = storm : : logic : : ComparisonType : : GreaterEqual ) ) {
( this - > probabilityOperatorFormula - > getComparisonType ( ) = = storm : : logic : : ComparisonType : : GreaterEqual ) ) {
region . setCheckResult ( RegionCheckResult : : ALLSAT ) ;
region . setCheckResult ( RegionCheckResult : : ALLSAT ) ;
@ -659,7 +916,7 @@ namespace storm {
}
}
//flip the optype for the next iteration
//flip the optype for the next iteration
opType = storm : : logic : : OptimalityType : : Maximize ;
opType = storm : : logic : : OptimalityType : : Maximize ;
if ( i = = 1 ) std : : cout < < " Requiring a second model checker run (with Maximize) " < < std : : endl ;
// if(i==1) std::cout << " Requiring a second model checker run (with Maximize)" << std::endl;
}
}
}
}
@ -668,7 +925,37 @@ namespace storm {
}
}
template < typename ParametricType , typename ConstantType >
template < typename ParametricType , typename ConstantType >
storm : : models : : sparse : : Mdp < ConstantType > SparseDtmcRegionModelChecker < ParametricType , ConstantType > : : buildMdpForApproximation ( const ParameterRegion & region ) {
void SparseDtmcRegionModelChecker < ParametricType , ConstantType > : : buildMdpForApproximation ( const ParameterRegion & region ) {
//instantiate the substitutions for the given region
std : : vector < std : : map < VariableType , BoundType > > substitutions ( this - > approxMdpSubstitutions . size ( ) ) ;
for ( uint_fast64_t substitutionIndex = 0 ; substitutionIndex < this - > approxMdpSubstitutions . size ( ) ; + + substitutionIndex ) {
for ( std : : pair < VariableType , TypeOfBound > const & sub : this - > approxMdpSubstitutions [ substitutionIndex ] ) {
switch ( sub . second ) {
case TypeOfBound : : LOWER :
substitutions [ substitutionIndex ] . insert ( std : : make_pair ( sub . first , region . getLowerBound ( sub . first ) ) ) ;
break ;
case TypeOfBound : : UPPER :
substitutions [ substitutionIndex ] . insert ( std : : make_pair ( sub . first , region . getUpperBound ( sub . first ) ) ) ;
break ;
default :
STORM_LOG_THROW ( false , storm : : exceptions : : UnexpectedException , " Unexpected Type of Bound " ) ;
}
}
}
//now put the values into the mdp matrix
for ( std : : tuple < ParametricType , typename storm : : storage : : MatrixEntry < storm : : storage : : sparse : : state_type , ConstantType > & , size_t > & mappingTriple : this - > approxMdpMapping ) {
std : : get < 1 > ( mappingTriple ) . setValue ( storm : : utility : : regions : : convertNumber < BoundType , ConstantType > (
storm : : utility : : regions : : evaluateFunction < ParametricType , ConstantType > ( std : : get < 0 > ( mappingTriple ) , substitutions [ std : : get < 2 > ( mappingTriple ) ] )
)
) ;
}
}
//DELETEME
template < typename ParametricType , typename ConstantType >
storm : : models : : sparse : : Mdp < ConstantType > SparseDtmcRegionModelChecker < ParametricType , ConstantType > : : buildMdpForApproximation2 ( const ParameterRegion & region ) {
//We are going to build a (non parametric) MDP which has an action for the lower bound and an action for the upper bound of every parameter
//We are going to build a (non parametric) MDP which has an action for the lower bound and an action for the upper bound of every parameter
//The matrix (and the Choice labeling)
//The matrix (and the Choice labeling)
@ -877,16 +1164,94 @@ namespace storm {
}
}
}
}
template < typename ParametricType , typename ConstantType >
template < typename ValueType >
bool SparseDtmcRegionModelChecker < ParametricType , ConstantType > : : valueIsInBoundOfFormula ( ValueType value ) {
STORM_LOG_THROW ( this - > probabilityOperatorFormula ! = nullptr , storm : : exceptions : : InvalidStateException , " Tried to compare a value to the bound of a formula, but no formula specified. " ) ;
double valueAsDouble = storm : : utility : : regions : : convertNumber < ValueType , double > ( value ) ;
// std::cout << "checked whether value: " << value << " (= " << valueAsDouble << " double ) is in bound of formula: " << *this->probabilityOperatorFormula << std::endl;
// std::cout << " (valueAsDouble >= this->probabilityOperatorFormula->getBound()) is " << (valueAsDouble >= this->probabilityOperatorFormula->getBound()) << std::endl;
switch ( this - > probabilityOperatorFormula - > getComparisonType ( ) ) {
case storm : : logic : : ComparisonType : : Greater :
return ( valueAsDouble > this - > probabilityOperatorFormula - > getBound ( ) ) ;
case storm : : logic : : ComparisonType : : GreaterEqual :
return ( valueAsDouble > = this - > probabilityOperatorFormula - > getBound ( ) ) ;
case storm : : logic : : ComparisonType : : Less :
return ( valueAsDouble < this - > probabilityOperatorFormula - > getBound ( ) ) ;
case storm : : logic : : ComparisonType : : LessEqual :
return ( valueAsDouble < = this - > probabilityOperatorFormula - > getBound ( ) ) ;
default :
STORM_LOG_THROW ( false , storm : : exceptions : : InvalidArgumentException , " the comparison relation of the formula is not supported " ) ;
}
}
template < typename ParametricType , typename ConstantType >
void SparseDtmcRegionModelChecker < ParametricType , ConstantType > : : printStatisticsToStream ( std : : ostream & outstream ) {
if ( this - > probabilityOperatorFormula = = nullptr ) {
outstream < < " Statistic Region Model Checker Statistics Error: No formula specified. " < < std : : endl ;
return ;
}
std : : chrono : : milliseconds timePreprocessingInMilliseconds = std : : chrono : : duration_cast < std : : chrono : : milliseconds > ( this - > timePreprocessing ) ;
std : : chrono : : milliseconds timeInitialStateEliminationInMilliseconds = std : : chrono : : duration_cast < std : : chrono : : milliseconds > ( this - > timeInitialStateElimination ) ;
std : : chrono : : milliseconds timeComputeReachProbFunctionInMilliseconds = std : : chrono : : duration_cast < std : : chrono : : milliseconds > ( this - > timeComputeReachProbFunction ) ;
std : : chrono : : milliseconds timeCheckRegionInMilliseconds = std : : chrono : : duration_cast < std : : chrono : : milliseconds > ( this - > timeCheckRegion ) ;
std : : chrono : : milliseconds timeSammplingInMilliseconds = std : : chrono : : duration_cast < std : : chrono : : milliseconds > ( this - > timeSampling ) ;
std : : chrono : : milliseconds timeApproximationInMilliseconds = std : : chrono : : duration_cast < std : : chrono : : milliseconds > ( this - > timeApproximation ) ;
std : : chrono : : milliseconds timeMDPBuildInMilliseconds = std : : chrono : : duration_cast < std : : chrono : : milliseconds > ( this - > timeMDPBuild ) ;
std : : chrono : : milliseconds timeFullSmtInMilliseconds = std : : chrono : : duration_cast < std : : chrono : : milliseconds > ( this - > timeFullSmt ) ;
std : : chrono : : high_resolution_clock : : duration timeOverall = timePreprocessing + timeCheckRegion ; // + ...
std : : chrono : : milliseconds timeOverallInMilliseconds = std : : chrono : : duration_cast < std : : chrono : : milliseconds > ( timeOverall ) ;
std : : size_t subsystemTransitions = this - > sparseTransitions . getNonzeroEntryCount ( ) ;
for ( auto const & transition : this - > oneStepProbabilities ) {
if ( ! this - > parametricTypeComparator . isZero ( transition ) ) {
+ + subsystemTransitions ;
}
}
uint_fast64_t numOfSolvedRegions = this - > numOfRegionsExistsBoth + this - > numOfRegionsAllSat + this - > numOfRegionsAllViolated ;
outstream < < std : : endl < < " Statistics Region Model Checker Statistics: " < < std : : endl ;
outstream < < " ----------------------------------------------- " < < std : : endl ;
outstream < < " Model: " < < this - > model . getNumberOfStates ( ) < < " states, " < < this - > model . getNumberOfTransitions ( ) < < " transitions. " < < std : : endl ;
outstream < < " Reduced model: " < < this - > subsystem . getNumberOfSetBits ( ) < < " states, " < < subsystemTransitions < < " transitions " < < std : : endl ;
outstream < < " Formula: " < < * this - > probabilityOperatorFormula < < std : : endl ;
outstream < < ( this - > hasOnlyLinearFunctions ? " A " : " Not a " ) < < " ll occuring functions in the model are linear " < < std : : endl ;
outstream < < " Number of checked regions: " < < this - > numOfCheckedRegions < < std : : endl ;
outstream < < " Number of solved regions: " < < numOfSolvedRegions < < " ( " < < numOfSolvedRegions * 100 / this - > numOfCheckedRegions < < " %) " < < std : : endl ;
outstream < < " AllSat: " < < this - > numOfRegionsAllSat < < " ( " < < this - > numOfRegionsAllSat * 100 / this - > numOfCheckedRegions < < " %) " < < std : : endl ;
outstream < < " AllViolated: " < < this - > numOfRegionsAllViolated < < " ( " < < this - > numOfRegionsAllViolated * 100 / this - > numOfCheckedRegions < < " %) " < < std : : endl ;
outstream < < " ExistsBoth: " < < this - > numOfRegionsExistsBoth < < " ( " < < this - > numOfRegionsExistsBoth * 100 / this - > numOfCheckedRegions < < " %) " < < std : : endl ;
outstream < < " Unsolved: " < < this - > numOfCheckedRegions - numOfSolvedRegions < < " ( " < < ( this - > numOfCheckedRegions - numOfSolvedRegions ) * 100 / this - > numOfCheckedRegions < < " %) " < < std : : endl ;
outstream < < " -- " < < std : : endl ;
outstream < < " " < < this - > numOfRegionsSolvedThroughSampling < < " regions solved through Sampling " < < std : : endl ;
outstream < < " " < < this - > numOfRegionsSolvedThroughApproximation < < " regions solved through Approximation " < < std : : endl ;
outstream < < " " < < this - > numOfRegionsSolvedThroughSubsystemSmt < < " regions solved through SubsystemSmt " < < std : : endl ;
outstream < < " " < < this - > numOfRegionsSolvedThroughFullSmt < < " regions solved through FullSmt " < < std : : endl ;
outstream < < std : : endl ;
outstream < < " Running times: " < < std : : endl ;
outstream < < " " < < timeOverallInMilliseconds . count ( ) < < " ms overall " < < std : : endl ;
outstream < < " " < < timePreprocessingInMilliseconds . count ( ) < < " ms Preprocessing including... " < < std : : endl ;
outstream < < " " < < timeInitialStateEliminationInMilliseconds . count ( ) < < " ms Initial state elimination including... " < < std : : endl ;
outstream < < " " < < timeComputeReachProbFunctionInMilliseconds . count ( ) < < " ms to compute the reachability probability function " < < std : : endl ;
outstream < < " " < < timeCheckRegionInMilliseconds . count ( ) < < " ms Region Check including... " < < std : : endl ;
outstream < < " " < < timeSammplingInMilliseconds . count ( ) < < " ms Sampling " < < std : : endl ;
outstream < < " " < < timeApproximationInMilliseconds . count ( ) < < " ms Approximation including... " < < std : : endl ;
outstream < < " " < < timeMDPBuildInMilliseconds . count ( ) < < " ms to build the MDP " < < std : : endl ;
outstream < < " " < < timeFullSmtInMilliseconds . count ( ) < < " ms Full Smt solving " < < std : : endl ;
outstream < < " ----------------------------------------------- " < < std : : endl ;
}
# ifdef STORM_HAVE_CARL
//DELETEME
template < >
template < >
std : : pair < storm : : storage : : SparseMatrix < double > , std : : vector < boost : : container : : flat_set < uint_fast64_t > > > SparseDtmcRegionModelChecker < storm : : RationalFunction , double > : : instantiateFlexibleMatrix ( FlexibleMatrix const & matrix , std : : vector < std : : map < storm : : Variable , storm : : RationalFunction : : CoeffType > > const & substitutions , storm : : storage : : BitVector const & filter , bool addSinkState , std : : vector < storm : : RationalFunction > const & oneStepProbabilities , bool addSelfLoops ) const {
std : : pair < storm : : storage : : SparseMatrix < double > , std : : vector < boost : : container : : flat_set < uint_fast64_t > > > SparseDtmcRegionModelChecker < storm : : RationalFunction , double > : : instantiateFlexibleMatrix ( FlexibleMatrix const & matrix , std : : vector < std : : map < storm : : Variable , storm : : RationalFunction : : CoeffType > > const & substitutions , storm : : storage : : BitVector const & filter , bool addSinkState , std : : vector < storm : : RationalFunction > const & oneStepProbabilities , bool addSelfLoops ) const {
@ -984,13 +1349,14 @@ namespace storm {
return std : : pair < storm : : storage : : SparseMatrix < double > , std : : vector < boost : : container : : flat_set < uint_fast64_t > > > ( matrixBuilder . build ( ) , std : : move ( choiceLabeling ) ) ;
return std : : pair < storm : : storage : : SparseMatrix < double > , std : : vector < boost : : container : : flat_set < uint_fast64_t > > > ( matrixBuilder . build ( ) , std : : move ( choiceLabeling ) ) ;
}
}
//DELETEME
template < typename ParametricType , typename ConstantType >
template < typename ParametricType , typename ConstantType >
std : : pair < storm : : storage : : SparseMatrix < double > , std : : vector < boost : : container : : flat_set < uint_fast64_t > > > SparseDtmcRegionModelChecker < ParametricType , ConstantType > : : instantiateFlexibleMatrix ( FlexibleMatrix const & matrix , std : : vector < std : : map < storm : : Variable , storm : : RationalFunction : : CoeffType > > const & substitutions , storm : : storage : : BitVector const & filter , bool addSinkState , std : : vector < ParametricType > const & oneStepProbabilities , bool addSelfLoops ) const {
std : : pair < storm : : storage : : SparseMatrix < double > , std : : vector < boost : : container : : flat_set < uint_fast64_t > > > SparseDtmcRegionModelChecker < ParametricType , ConstantType > : : instantiateFlexibleMatrix ( FlexibleMatrix const & matrix , std : : vector < std : : map < storm : : Variable , storm : : RationalFunction : : CoeffType > > const & substitutions , storm : : storage : : BitVector const & filter , bool addSinkState , std : : vector < ParametricType > const & oneStepProbabilities , bool addSelfLoops ) const {
STORM_LOG_THROW ( false , storm : : exceptions : : IllegalArgumentException , " Instantiation of flexible matrix is not supported for this type " ) ;
STORM_LOG_THROW ( false , storm : : exceptions : : IllegalArgumentException , " Instantiation of flexible matrix is not supported for this type " ) ;
}
}
# ifdef STORM_HAVE_CARL
//DELETEME
template < >
template < >
void SparseDtmcRegionModelChecker < storm : : RationalFunction , double > : : eliminateStates ( storm : : storage : : BitVector & subsystem , FlexibleMatrix & flexibleMatrix , std : : vector < storm : : RationalFunction > & oneStepProbabilities , FlexibleMatrix & flexibleBackwardTransitions , storm : : storage : : BitVector const & initialstates , storm : : storage : : SparseMatrix < storm : : RationalFunction > const & forwardTransitions , boost : : optional < std : : vector < std : : size_t > > const & statePriorities ) {
void SparseDtmcRegionModelChecker < storm : : RationalFunction , double > : : eliminateStates ( storm : : storage : : BitVector & subsystem , FlexibleMatrix & flexibleMatrix , std : : vector < storm : : RationalFunction > & oneStepProbabilities , FlexibleMatrix & flexibleBackwardTransitions , storm : : storage : : BitVector const & initialstates , storm : : storage : : SparseMatrix < storm : : RationalFunction > const & forwardTransitions , boost : : optional < std : : vector < std : : size_t > > const & statePriorities ) {
@ -1057,7 +1423,7 @@ namespace storm {
STORM_LOG_THROW ( false , storm : : exceptions : : IllegalArgumentException , " elimination of states not suported for this type " ) ;
STORM_LOG_THROW ( false , storm : : exceptions : : IllegalArgumentException , " elimination of states not suported for this type " ) ;
}
}
//OBSOLETE ...
template < >
template < >
void SparseDtmcRegionModelChecker < storm : : RationalFunction , double > : : 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 SparseDtmcRegionModelChecker < storm : : RationalFunction , double > : : 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 ) {
carl : : VariablePool & varPool = carl : : VariablePool : : getInstance ( ) ;
carl : : VariablePool & varPool = carl : : VariablePool : : getInstance ( ) ;
@ -1092,6 +1458,7 @@ namespace storm {
STORM_LOG_THROW ( false , storm : : exceptions : : IllegalArgumentException , " SMT formulation is not supported for this type " ) ;
STORM_LOG_THROW ( false , storm : : exceptions : : IllegalArgumentException , " SMT formulation is not supported for this type " ) ;
}
}
//DELETEME
template < >
template < >
void SparseDtmcRegionModelChecker < storm : : RationalFunction , double > : : 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 & compType ) {
void SparseDtmcRegionModelChecker < storm : : RationalFunction , double > : : 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 & compType ) {
//We are going to build a new (non parametric) MDP which has an action for the lower bound and an action for the upper bound of every parameter
//We are going to build a new (non parametric) MDP which has an action for the lower bound and an action for the upper bound of every parameter
@ -1165,6 +1532,7 @@ namespace storm {
STORM_LOG_THROW ( false , storm : : exceptions : : IllegalArgumentException , " restricting Probability Variables is not supported for this type " ) ;
STORM_LOG_THROW ( false , storm : : exceptions : : IllegalArgumentException , " restricting Probability Variables is not supported for this type " ) ;
}
}
//DELETEME
template < >
template < >
bool SparseDtmcRegionModelChecker < storm : : RationalFunction , double > : : checkRegionOld ( storm : : logic : : Formula const & formula , std : : vector < ParameterRegion > parameterRegions ) {
bool SparseDtmcRegionModelChecker < storm : : RationalFunction , double > : : checkRegionOld ( storm : : logic : : Formula const & formula , std : : vector < ParameterRegion > parameterRegions ) {
//Note: this is an 'experimental' implementation
//Note: this is an 'experimental' implementation
@ -1340,79 +1708,10 @@ namespace storm {
STORM_LOG_THROW ( false , storm : : exceptions : : IllegalArgumentException , " Region check is not supported for this type " ) ;
STORM_LOG_THROW ( false , storm : : exceptions : : IllegalArgumentException , " Region check is not supported for this type " ) ;
}
}
template < typename ParametricType , typename ConstantType >
template < typename ValueType >
bool SparseDtmcRegionModelChecker < ParametricType , ConstantType > : : valueIsInBoundOfFormula ( ValueType value ) {
STORM_LOG_THROW ( this - > probabilityOperatorFormula ! = nullptr , storm : : exceptions : : InvalidStateException , " Tried to compare a value to the bound of a formula, but no formula specified. " ) ;
double valueAsDouble = storm : : utility : : regions : : convertNumber < ValueType , double > ( value ) ;
switch ( this - > probabilityOperatorFormula - > getComparisonType ( ) ) {
case storm : : logic : : ComparisonType : : Greater :
return ( valueAsDouble > this - > probabilityOperatorFormula - > getBound ( ) ) ;
case storm : : logic : : ComparisonType : : GreaterEqual :
return ( valueAsDouble > = this - > probabilityOperatorFormula - > getBound ( ) ) ;
case storm : : logic : : ComparisonType : : Less :
return ( valueAsDouble < this - > probabilityOperatorFormula - > getBound ( ) ) ;
case storm : : logic : : ComparisonType : : LessEqual :
return ( valueAsDouble < = this - > probabilityOperatorFormula - > getBound ( ) ) ;
default :
STORM_LOG_THROW ( false , storm : : exceptions : : InvalidArgumentException , " the comparison relation of the formula is not supported " ) ;
}
}
template < typename ParametricType , typename ConstantType >
void SparseDtmcRegionModelChecker < ParametricType , ConstantType > : : printStatisticsToStream ( std : : ostream & outstream ) {
if ( this - > probabilityOperatorFormula = = nullptr ) {
outstream < < " Statistic Region Model Checker Statistics Error: No formula specified. " < < std : : endl ;
return ;
}
std : : chrono : : milliseconds timePreprocessingInMilliseconds = std : : chrono : : duration_cast < std : : chrono : : milliseconds > ( this - > timePreprocessing ) ;
std : : chrono : : milliseconds timeInitialStateEliminationInMilliseconds = std : : chrono : : duration_cast < std : : chrono : : milliseconds > ( this - > timeInitialStateElimination ) ;
std : : chrono : : milliseconds timeComputeReachProbFunctionInMilliseconds = std : : chrono : : duration_cast < std : : chrono : : milliseconds > ( this - > timeComputeReachProbFunction ) ;
std : : chrono : : milliseconds timeCheckRegionInMilliseconds = std : : chrono : : duration_cast < std : : chrono : : milliseconds > ( this - > timeCheckRegion ) ;
std : : chrono : : milliseconds timeSammplingInMilliseconds = std : : chrono : : duration_cast < std : : chrono : : milliseconds > ( this - > timeSampling ) ;
std : : chrono : : milliseconds timeApproximationInMilliseconds = std : : chrono : : duration_cast < std : : chrono : : milliseconds > ( this - > timeApproximation ) ;
std : : chrono : : milliseconds timeMDPBuildInMilliseconds = std : : chrono : : duration_cast < std : : chrono : : milliseconds > ( this - > timeMDPBuild ) ;
std : : chrono : : milliseconds timeFullSmtInMilliseconds = std : : chrono : : duration_cast < std : : chrono : : milliseconds > ( this - > timeFullSmt ) ;
std : : chrono : : high_resolution_clock : : duration timeOverall = timePreprocessing + timeCheckRegion ; // + ...
std : : chrono : : milliseconds timeOverallInMilliseconds = std : : chrono : : duration_cast < std : : chrono : : milliseconds > ( timeOverall ) ;
std : : size_t subsystemTransitions = this - > sparseTransitions . getNonzeroEntryCount ( ) ;
for ( auto const & transition : this - > oneStepProbabilities ) {
if ( ! this - > parametricTypeComparator . isZero ( transition ) ) {
+ + subsystemTransitions ;
}
}
outstream < < std : : endl < < " Statistics Region Model Checker Statistics: " < < std : : endl ;
outstream < < " ----------------------------------------------- " < < std : : endl ;
outstream < < " Model: " < < this - > model . getNumberOfStates ( ) < < " states, " < < this - > model . getNumberOfTransitions ( ) < < " transitions. " < < std : : endl ;
outstream < < " Reduced model: " < < this - > subsystem . getNumberOfSetBits ( ) < < " states, " < < subsystemTransitions < < " transitions " < < std : : endl ;
outstream < < " Formula: " < < * this - > probabilityOperatorFormula < < std : : endl ;
outstream < < ( this - > hasOnlyLinearFunctions ? " A " : " Not a " ) < < " ll occuring functions in the model are linear " < < std : : endl ;
outstream < < " Number of checked regions: " < < this - > numOfCheckedRegions < < " with... " < < std : : endl ;
outstream < < " " < < this - > numOfRegionsSolvedThroughSampling < < " regions solved through Sampling " < < std : : endl ;
outstream < < " " < < this - > numOfRegionsSolvedThroughApproximation < < " regions solved through Approximation " < < std : : endl ;
outstream < < " " < < this - > numOfRegionsSolvedThroughSubsystemSmt < < " regions solved through SubsystemSmt " < < std : : endl ;
outstream < < " " < < this - > numOfRegionsSolvedThroughFullSmt < < " regions solved through FullSmt " < < std : : endl ;
outstream < < " Running times: " < < std : : endl ;
outstream < < " " < < timeOverallInMilliseconds . count ( ) < < " ms overall " < < std : : endl ;
outstream < < " " < < timePreprocessingInMilliseconds . count ( ) < < " ms Preprocessing including... " < < std : : endl ;
outstream < < " " < < timeInitialStateEliminationInMilliseconds . count ( ) < < " ms Initial state elimination including... " < < std : : endl ;
outstream < < " " < < timeComputeReachProbFunctionInMilliseconds . count ( ) < < " ms to compute the reachability probability function " < < std : : endl ;
outstream < < " " < < timeCheckRegionInMilliseconds . count ( ) < < " ms Region Check including... " < < std : : endl ;
outstream < < " " < < timeSammplingInMilliseconds . count ( ) < < " ms Sampling " < < std : : endl ;
outstream < < " " < < timeApproximationInMilliseconds . count ( ) < < " ms Approximation including... " < < std : : endl ;
outstream < < " " < < timeMDPBuildInMilliseconds . count ( ) < < " ms to build the MDP " < < std : : endl ;
outstream < < " " < < timeFullSmtInMilliseconds . count ( ) < < " ms Full Smt solving " < < std : : endl ;
outstream < < " ----------------------------------------------- " < < std : : endl ;
# endif
}
# endif
# ifdef STORM_HAVE_CARL
# ifdef STORM_HAVE_CARL
template class SparseDtmcRegionModelChecker < storm : : RationalFunction , double > ;
template class SparseDtmcRegionModelChecker < storm : : RationalFunction , double > ;