@ -4,6 +4,7 @@
# include "storm/settings/modules/DebugSettings.h"
# include "storm/settings/modules/DebugSettings.h"
# include "storm-pomdp-cli/settings/modules/POMDPSettings.h"
# include "storm-pomdp-cli/settings/modules/POMDPSettings.h"
# include "storm-pomdp-cli/settings/modules/GridApproximationSettings.h"
# include "storm-pomdp-cli/settings/modules/GridApproximationSettings.h"
# include "storm-pomdp-cli/settings/modules/QualitativePOMDPAnalysisSettings.h"
# include "storm-pomdp-cli/settings/PomdpSettings.h"
# include "storm-pomdp-cli/settings/PomdpSettings.h"
# include "storm/analysis/GraphConditions.h"
# include "storm/analysis/GraphConditions.h"
@ -115,14 +116,15 @@
// return validFormula;
// return validFormula;
//}
//}
//
//
//template<typename ValueType>
//std::set<uint32_t> extractObservations(storm::models::sparse::Pomdp<ValueType> const& pomdp, storm::storage::BitVector const& states) {
// std::set<uint32_t> observations;
// for(auto state : states) {
// observations.insert(pomdp.getObservation(state));
// }
// return observations;
//}
template < typename ValueType >
std : : set < uint32_t > extractObservations ( storm : : models : : sparse : : Pomdp < ValueType > const & pomdp , storm : : storage : : BitVector const & states ) {
// TODO move.
std : : set < uint32_t > observations ;
for ( auto state : states ) {
observations . insert ( pomdp . getObservation ( state ) ) ;
}
return observations ;
}
//
//
///*!
///*!
// * Entry point for the pomdp backend.
// * Entry point for the pomdp backend.
@ -236,7 +238,6 @@ namespace storm {
STORM_PRINT_AND_LOG ( oldChoiceCount - pomdp - > getNumberOfChoices ( ) < < " choices eliminated through self-loop elimination. " < < std : : endl ) ;
STORM_PRINT_AND_LOG ( oldChoiceCount - pomdp - > getNumberOfChoices ( ) < < " choices eliminated through self-loop elimination. " < < std : : endl ) ;
preprocessingPerformed = true ;
preprocessingPerformed = true ;
}
}
> > > > > > > prism - pomdp
}
}
if ( pomdpSettings . isQualitativeReductionSet ( ) & & formulaInfo . isNonNestedReachabilityProbability ( ) ) {
if ( pomdpSettings . isQualitativeReductionSet ( ) & & formulaInfo . isNonNestedReachabilityProbability ( ) ) {
storm : : analysis : : QualitativeAnalysis < ValueType > qualitativeAnalysis ( * pomdp ) ;
storm : : analysis : : QualitativeAnalysis < ValueType > qualitativeAnalysis ( * pomdp ) ;
@ -272,70 +273,31 @@ namespace storm {
}
}
}
}
template < typename ValueType , storm : : dd : : DdType DdType >
bool perform Analysis( std : : shared_ptr < storm : : models : : sparse : : Pomdp < ValueType > > const & pomdp , storm : : pomdp : : analysis : : FormulaInformation const & formulaInfo , storm : : logic : : Formula const & formula ) {
template < typename ValueType >
void performQualitative Analysis( std : : shared_ptr < storm : : models : : sparse : : Pomdp < ValueType > > const & pomdp , storm : : pomdp : : analysis : : FormulaInformation const & formulaInfo , storm : : logic : : Formula const & formula ) {
auto const & pomdpSettings = storm : : settings : : getModule < storm : : settings : : modules : : POMDPSettings > ( ) ;
auto const & pomdpSettings = storm : : settings : : getModule < storm : : settings : : modules : : POMDPSettings > ( ) ;
bool analysisPerformed = false ;
if ( pomdpSettings . isGridApproximationSet ( ) ) {
STORM_PRINT_AND_LOG ( " Applying grid approximation... " ) ;
auto const & gridSettings = storm : : settings : : getModule < storm : : settings : : modules : : GridApproximationSettings > ( ) ;
typename storm : : pomdp : : modelchecker : : ApproximatePOMDPModelchecker < ValueType > : : Options options ;
options . initialGridResolution = gridSettings . getGridResolution ( ) ;
options . explorationThreshold = storm : : utility : : convertNumber < ValueType > ( gridSettings . getExplorationThreshold ( ) ) ;
options . doRefinement = gridSettings . isRefineSet ( ) ;
options . refinementPrecision = storm : : utility : : convertNumber < ValueType > ( gridSettings . getRefinementPrecision ( ) ) ;
options . numericPrecision = storm : : utility : : convertNumber < ValueType > ( gridSettings . getNumericPrecision ( ) ) ;
options . cacheSubsimplices = gridSettings . isCacheSimplicesSet ( ) ;
if ( storm : : NumberTraits < ValueType > : : IsExact ) {
if ( gridSettings . isNumericPrecisionSetFromDefault ( ) ) {
STORM_LOG_WARN_COND ( storm : : utility : : isZero ( options . numericPrecision ) , " Setting numeric precision to zero because exact arithmethic is used. " ) ;
options . numericPrecision = storm : : utility : : zero < ValueType > ( ) ;
} else {
STORM_LOG_WARN_COND ( storm : : utility : : isZero ( options . numericPrecision ) , " A non-zero numeric precision was set although exact arithmethic is used. Results might be inexact. " ) ;
}
}
storm : : pomdp : : modelchecker : : ApproximatePOMDPModelchecker < ValueType > checker = storm : : pomdp : : modelchecker : : ApproximatePOMDPModelchecker < ValueType > ( * pomdp , options ) ;
std : : unique_ptr < storm : : pomdp : : modelchecker : : POMDPCheckResult < ValueType > > result = checker . check ( formula ) ;
checker . printStatisticsToStream ( std : : cout ) ;
if ( result ) {
if ( storm : : utility : : resources : : isTerminate ( ) ) {
STORM_PRINT_AND_LOG ( " \n Result till abort: " )
} else {
STORM_PRINT_AND_LOG ( " \n Result: " )
}
printResult ( result - > underApproxValue , result - > overApproxValue ) ;
STORM_PRINT_AND_LOG ( std : : endl ) ;
} else {
STORM_PRINT_AND_LOG ( " \n Result: Not available. " < < std : : endl ) ;
}
analysisPerformed = true ;
}
if ( pomdpSettings . isMemlessSearchSet ( ) ) {
auto const & qualSettings = storm : : settings : : getModule < storm : : settings : : modules : : QualitativePOMDPAnalysisSettings > ( ) ;
STORM_LOG_THROW ( formulaInfo . isNonNestedReachabilityProbability ( ) , storm : : exceptions : : NotSupportedException , " Qualitative memoryless scheduler search is not implemented for this property type. " ) ;
STORM_LOG_THROW ( formulaInfo . isNonNestedReachabilityProbability ( ) , storm : : exceptions : : NotSupportedException , " Qualitative memoryless scheduler search is not implemented for this property type. " ) ;
storm : : analysis : : QualitativeAnalysis < double > qualitativeAnalysis ( * pomdp ) ;
STORM_LOG_TRACE ( " Run qualitative preprocessing... " ) ;
storm : : analysis : : QualitativeAnalysis < ValueType > qualitativeAnalysis ( * pomdp ) ;
// After preprocessing, this might be done cheaper.
// After preprocessing, this might be done cheaper.
storm : : storage : : BitVector targetStates = qualitativeAnalysis . analyseProb1 ( formula - > asProbabilityOperatorFormula ( ) ) ;
storm : : storage : : BitVector surelyNotAlmostSurelyReachTarget = qualitativeAnalysis . analyseProbSmaller1 ( formula - > asProbabilityOperatorFormula ( ) ) ;
storm : : storage : : BitVector targetStates = qualitativeAnalysis . analyseProb1 ( formula . asProbabilityOperatorFormula ( ) ) ;
STORM_LOG_TRACE ( " target states: " < < targetStates ) ;
storm : : storage : : BitVector surelyNotAlmostSurelyReachTarget = qualitativeAnalysis . analyseProbSmaller1 ( formula . asProbabilityOperatorFormula ( ) ) ;
std : : set < uint32_t > targetObservationSet = extractObservations ( * pomdp , targetStates ) ;
std : : set < uint32_t > targetObservationSet = extractObservations ( * pomdp , targetStates ) ;
// std::cout << std::endl;
// pomdp->writeDotToStream(std::cout);
// std::cout << std::endl;
// std::cout << std::endl;
storm : : expressions : : ExpressionManager expressionManager ;
storm : : expressions : : ExpressionManager expressionManager ;
std : : shared_ptr < storm : : utility : : solver : : SmtSolverFactory > smtSolverFactory = std : : make_shared < storm : : utility : : solver : : Z3SmtSolverFactory > ( ) ;
std : : shared_ptr < storm : : utility : : solver : : SmtSolverFactory > smtSolverFactory = std : : make_shared < storm : : utility : : solver : : Z3SmtSolverFactory > ( ) ;
uint64_t lookahead = pomdpQ ualSettings. getLookahead ( ) ;
uint64_t lookahead = qualSettings . getLookahead ( ) ;
if ( lookahead = = 0 ) {
if ( lookahead = = 0 ) {
lookahead = pomdp - > getNumberOfStates ( ) ;
lookahead = pomdp - > getNumberOfStates ( ) ;
}
}
storm : : pomdp : : MemlessSearchOptions options ;
storm : : pomdp : : MemlessSearchOptions options ;
options . onlyDeterministicStrategies = pomdpQ ualSettings. isOnlyDeterministicSet ( ) ;
options . onlyDeterministicStrategies = qualSettings . isOnlyDeterministicSet ( ) ;
uint64_t loglevel = 0 ;
uint64_t loglevel = 0 ;
// TODO a big ugly, but we have our own loglevels.
// TODO a big ugly, but we have our own loglevels.
if ( storm : : utility : : getLogLevel ( ) = = l3pp : : LogLevel : : INFO ) {
if ( storm : : utility : : getLogLevel ( ) = = l3pp : : LogLevel : : INFO ) {
@ -349,8 +311,8 @@ namespace storm {
}
}
options . setDebugLevel ( loglevel ) ;
options . setDebugLevel ( loglevel ) ;
if ( pomdpQ ualSettings. isExportSATCallsSet ( ) ) {
options . setExportSATCalls ( pomdpQ ualSettings. getExportSATCallsPath ( ) ) ;
if ( q ualSettings. isExportSATCallsSet ( ) ) {
options . setExportSATCalls ( q ualSettings. getExportSATCallsPath ( ) ) ;
}
}
if ( storm : : utility : : graph : : checkIfECWithChoiceExists ( pomdp - > getTransitionMatrix ( ) , pomdp - > getBackwardTransitions ( ) , ~ targetStates & ~ surelyNotAlmostSurelyReachTarget , storm : : storage : : BitVector ( pomdp - > getNumberOfChoices ( ) , true ) ) ) {
if ( storm : : utility : : graph : : checkIfECWithChoiceExists ( pomdp - > getTransitionMatrix ( ) , pomdp - > getBackwardTransitions ( ) , ~ targetStates & ~ surelyNotAlmostSurelyReachTarget , storm : : storage : : BitVector ( pomdp - > getNumberOfChoices ( ) , true ) ) ) {
@ -361,20 +323,71 @@ namespace storm {
STORM_LOG_DEBUG ( " No lookahead required. " ) ;
STORM_LOG_DEBUG ( " No lookahead required. " ) ;
}
}
if ( pomdpSettings . getMemlessSearchMethod ( ) = = " ccd16memless " ) {
storm : : pomdp : : QualitativeStrategySearchNaive < double > memlessSearch ( * pomdp , targetObservationSet , targetStates , surelyNotAlmostSurelyReachTarget , smtSolverFactory ) ;
memlessSearch . findNewStrategyForSomeState ( lookahead ) ;
STORM_LOG_TRACE ( " target states: " < < targetStates ) ;
if ( pomdpSettings . getMemlessSearchMethod ( ) = = " ccd-memless " ) {
storm : : pomdp : : QualitativeStrategySearchNaive < ValueType > memlessSearch ( * pomdp , targetObservationSet , targetStates , surelyNotAlmostSurelyReachTarget , smtSolverFactory ) ;
if ( qualSettings . isWinningRegionSet ( ) ) {
STORM_LOG_ERROR ( " Computing winning regions is not supported by ccd-memless. " ) ;
} else {
memlessSearch . analyzeForInitialStates ( lookahead ) ;
}
} else if ( pomdpSettings . getMemlessSearchMethod ( ) = = " iterative " ) {
} else if ( pomdpSettings . getMemlessSearchMethod ( ) = = " iterative " ) {
storm : : pomdp : : MemlessStrategySearchQualitative < double > memlessSearch ( * pomdp , targetObservationSet , targetStates , surelyNotAlmostSurelyReachTarget , smtSolverFactory , options ) ;
memlessSearch . findNewStrategyForSomeState ( lookahead ) ;
memlessSearch . finalizeStatistics ( ) ;
memlessSearch . getStatistics ( ) . print ( ) ;
storm : : pomdp : : MemlessStrategySearchQualitative < ValueType > search ( * pomdp , targetObservationSet , targetStates , surelyNotAlmostSurelyReachTarget , smtSolverFactory , options ) ;
if ( qualSettings . isWinningRegionSet ( ) ) {
search . findNewStrategyForSomeState ( lookahead ) ;
} else {
search . analyzeForInitialStates ( lookahead ) ;
}
search . finalizeStatistics ( ) ;
search . getStatistics ( ) . print ( ) ;
} else {
} else {
STORM_LOG_ERROR ( " This method is not implemented. " ) ;
STORM_LOG_ERROR ( " This method is not implemented. " ) ;
}
}
}
template < typename ValueType , storm : : dd : : DdType DdType >
bool performAnalysis ( std : : shared_ptr < storm : : models : : sparse : : Pomdp < ValueType > > const & pomdp , storm : : pomdp : : analysis : : FormulaInformation const & formulaInfo , storm : : logic : : Formula const & formula ) {
auto const & pomdpSettings = storm : : settings : : getModule < storm : : settings : : modules : : POMDPSettings > ( ) ;
bool analysisPerformed = false ;
if ( pomdpSettings . isGridApproximationSet ( ) ) {
STORM_PRINT_AND_LOG ( " Applying grid approximation... " ) ;
auto const & gridSettings = storm : : settings : : getModule < storm : : settings : : modules : : GridApproximationSettings > ( ) ;
typename storm : : pomdp : : modelchecker : : ApproximatePOMDPModelchecker < ValueType > : : Options options ;
options . initialGridResolution = gridSettings . getGridResolution ( ) ;
options . explorationThreshold = storm : : utility : : convertNumber < ValueType > ( gridSettings . getExplorationThreshold ( ) ) ;
options . doRefinement = gridSettings . isRefineSet ( ) ;
options . refinementPrecision = storm : : utility : : convertNumber < ValueType > ( gridSettings . getRefinementPrecision ( ) ) ;
options . numericPrecision = storm : : utility : : convertNumber < ValueType > ( gridSettings . getNumericPrecision ( ) ) ;
options . cacheSubsimplices = gridSettings . isCacheSimplicesSet ( ) ;
if ( storm : : NumberTraits < ValueType > : : IsExact ) {
if ( gridSettings . isNumericPrecisionSetFromDefault ( ) ) {
STORM_LOG_WARN_COND ( storm : : utility : : isZero ( options . numericPrecision ) , " Setting numeric precision to zero because exact arithmethic is used. " ) ;
options . numericPrecision = storm : : utility : : zero < ValueType > ( ) ;
} else {
STORM_LOG_WARN_COND ( storm : : utility : : isZero ( options . numericPrecision ) , " A non-zero numeric precision was set although exact arithmethic is used. Results might be inexact. " ) ;
}
}
storm : : pomdp : : modelchecker : : ApproximatePOMDPModelchecker < ValueType > checker = storm : : pomdp : : modelchecker : : ApproximatePOMDPModelchecker < ValueType > ( * pomdp , options ) ;
std : : unique_ptr < storm : : pomdp : : modelchecker : : POMDPCheckResult < ValueType > > result = checker . check ( formula ) ;
checker . printStatisticsToStream ( std : : cout ) ;
if ( result ) {
if ( storm : : utility : : resources : : isTerminate ( ) ) {
STORM_PRINT_AND_LOG ( " \n Result till abort: " )
} else {
STORM_PRINT_AND_LOG ( " \n Result: " )
}
printResult ( result - > underApproxValue , result - > overApproxValue ) ;
STORM_PRINT_AND_LOG ( std : : endl ) ;
} else {
STORM_PRINT_AND_LOG ( " \n Result: Not available. " < < std : : endl ) ;
}
analysisPerformed = true ;
analysisPerformed = true ;
}
}
if ( pomdpSettings . isMemlessSearchSet ( ) ) {
performQualitativeAnalysis ( pomdp , formulaInfo , formula ) ;
analysisPerformed = true ;
}
if ( pomdpSettings . isCheckFullyObservableSet ( ) ) {
if ( pomdpSettings . isCheckFullyObservableSet ( ) ) {
STORM_PRINT_AND_LOG ( " Analyzing the formula on the fully observable MDP ... " ) ;
STORM_PRINT_AND_LOG ( " Analyzing the formula on the fully observable MDP ... " ) ;
auto resultPtr = storm : : api : : verifyWithSparseEngine < ValueType > ( pomdp - > template as < storm : : models : : sparse : : Mdp < ValueType > > ( ) , storm : : api : : createTask < ValueType > ( formula . asSharedPointer ( ) , true ) ) ;
auto resultPtr = storm : : api : : verifyWithSparseEngine < ValueType > ( pomdp - > template as < storm : : models : : sparse : : Mdp < ValueType > > ( ) , storm : : api : : createTask < ValueType > ( formula . asSharedPointer ( ) , true ) ) ;
@ -488,15 +501,6 @@ namespace storm {
storm : : transformer : : MakePOMDPCanonic < ValueType > makeCanonic ( * pomdp ) ;
storm : : transformer : : MakePOMDPCanonic < ValueType > makeCanonic ( * pomdp ) ;
pomdp = makeCanonic . transform ( ) ;
pomdp = makeCanonic . transform ( ) ;
// if (ioSettings.isExportDotSet()) {
// std::shared_ptr<storm::models::sparse::Model<double>> sparseModel = pomdp;
// storm::api::exportSparseModelAsDot(sparseModel, ioSettings.getExportDotFilename(), ioSettings.getExportDotMaxWidth());
// }
// if (ioSettings.isExportExplicitSet()) {
// std::shared_ptr<storm::models::sparse::Model<double>> sparseModel = pomdp;
// storm::api::exportSparseModelAsDrn(sparseModel, ioSettings.getExportExplicitFilename());
// }
std : : shared_ptr < storm : : logic : : Formula const > formula ;
std : : shared_ptr < storm : : logic : : Formula const > formula ;
if ( ! symbolicInput . properties . empty ( ) ) {
if ( ! symbolicInput . properties . empty ( ) ) {
formula = symbolicInput . properties . front ( ) . getRawFormula ( ) ;
formula = symbolicInput . properties . front ( ) . getRawFormula ( ) ;
@ -523,16 +527,18 @@ namespace storm {
}
}
sw . restart ( ) ;
sw . restart ( ) ;
if ( performAnalysis < ValueType , DdType > ( pomdp , formulaInfo , * formula ) ) {
if ( performTransformation < ValueType , DdType > ( pomdp , * formula ) ) {
sw . stop ( ) ;
sw . stop ( ) ;
STORM_PRINT_AND_LOG ( " Time for POMDP analysis : " < < sw < < " s. " < < std : : endl ) ;
STORM_PRINT_AND_LOG ( " Time for POMDP transformation(s) : " < < sw < < " s. " < < std : : endl ) ;
}
}
sw . restart ( ) ;
sw . restart ( ) ;
if ( performTransformation < ValueType , DdType > ( pomdp , * formula ) ) {
if ( performAnalysis < ValueType , DdType > ( pomdp , formulaInfo , * formula ) ) {
sw . stop ( ) ;
sw . stop ( ) ;
STORM_PRINT_AND_LOG ( " Time for POMDP tr ansformat ion( s) : " < < sw < < " s. " < < std : : endl ) ;
STORM_PRINT_AND_LOG ( " Time for POMDP analy sis: " < < sw < < " s. " < < std : : endl ) ;
}
}
} else {
} else {
STORM_LOG_WARN ( " Nothing to be done. Did you forget to specify a formula? " ) ;
STORM_LOG_WARN ( " Nothing to be done. Did you forget to specify a formula? " ) ;
}
}