@ -156,6 +156,9 @@ namespace storm {
/ / If set , bisimulation will be applied .
bool applyBisimulation ;
/ / If set , a transformation to Jani will be enforced
bool transformToJani ;
/ / Which data type is to be used for numbers . . .
enum class ValueType {
FinitePrecision ,
@ -175,16 +178,17 @@ namespace storm {
void getModelProcessingInformationPortfolio ( SymbolicInput const & input , ModelProcessingInformation & mpi ) {
auto hints = storm : : settings : : getModule < storm : : settings : : modules : : HintSettings > ( ) ;
STORM_LOG_THROW ( input . model . is_initialized ( ) , storm : : exceptions : : InvalidArgumentException , " Portfolio engine requires a symbolic model (PRISM or JANI. " ) ;
STORM_LOG_THROW ( input . model . is_initialized ( ) , storm : : exceptions : : InvalidArgumentException , " Portfolio engine requires a JANI input model. " ) ;
STORM_LOG_THROW ( input . model - > isJaniModel ( ) , storm : : exceptions : : InvalidArgumentException , " Portfolio engine requires a JANI input model. " ) ;
std : : vector < storm : : jani : : Property > const & properties = input . preprocessedProperties . is_initialized ( ) ? input . preprocessedProperties . get ( ) : input . properties ;
STORM_LOG_THROW ( ! properties . empty ( ) , storm : : exceptions : : InvalidArgumentException , " Portfolio engine requires a property. " ) ;
STORM_LOG_WARN_COND ( properties . size ( ) = = 1 , " Portfolio engine does not support decisions based on multiple properties. Only the first property will be considered. " ) ;
storm : : utility : : Portfolio pf ;
if ( hints . isNumberStatesSet ( ) ) {
pf . predict ( input . model . get ( ) , properties . front ( ) , hints . getNumberStates ( ) ) ;
pf . predict ( input . model - > asJaniModel ( ) , properties . front ( ) , hints . getNumberStates ( ) ) ;
} else {
pf . predict ( input . model . get ( ) , properties . front ( ) ) ;
pf . predict ( input . model - > asJaniModel ( ) , properties . front ( ) ) ;
}
mpi . engine = pf . getEngine ( ) ;
@ -202,8 +206,14 @@ namespace storm {
< < std : : noboolalpha < < std : : endl ) ;
}
ModelProcessingInformation getModelProcessingInformation ( SymbolicInput const & input ) {
/*!
* Sets the model processing information based on the given input .
* Finding the right model processing information might require a conversion to jani .
* In this case , the jani conversion is stored in the transformedJaniInput pointer ( unless it is null )
*/
ModelProcessingInformation getModelProcessingInformation ( SymbolicInput const & input , std : : shared_ptr < SymbolicInput > const & transformedJaniInput = nullptr ) {
ModelProcessingInformation mpi ;
auto ioSettings = storm : : settings : : getModule < storm : : settings : : modules : : IOSettings > ( ) ;
auto coreSettings = storm : : settings : : getModule < storm : : settings : : modules : : CoreSettings > ( ) ;
auto generalSettings = storm : : settings : : getModule < storm : : settings : : modules : : GeneralSettings > ( ) ;
auto bisimulationSettings = storm : : settings : : getModule < storm : : settings : : modules : : BisimulationSettings > ( ) ;
@ -224,10 +234,29 @@ namespace storm {
}
/ / Since the remaining settings could depend on the ones above , we need apply the portfolio engine now .
bool usePortfolio = mpi . engine = = storm : : utility : : Engine : : Portfolio ;
bool usePortfolio = input . model . is_initialized ( ) & & mpi . engine = = storm : : utility : : Engine : : Portfolio ;
if ( usePortfolio ) {
if ( input . model - > isJaniModel ( ) ) {
/ / This can potentially overwrite the settings above , but will not overwrite settings that were explicitly set by the user ( e . g . we will not disable bisimulation or disable exact arithmetic )
getModelProcessingInformationPortfolio ( input , mpi ) ;
} else {
/ / Transform Prism to jani first
STORM_LOG_ASSERT ( input . model - > isPrismProgram ( ) , " Unexpected type of input. " ) ;
SymbolicInput janiInput ;
janiInput . properties = input . properties ;
storm : : prism : : Program const & prog = input . model . get ( ) . asPrismProgram ( ) ;
auto modelAndProperties = prog . toJani ( input . preprocessedProperties . is_initialized ( ) ? input . preprocessedProperties . get ( ) : input . properties ) ;
janiInput . model = modelAndProperties . first ;
if ( ! modelAndProperties . second . empty ( ) ) {
janiInput . preprocessedProperties = std : : move ( modelAndProperties . second ) ;
}
/ / This can potentially overwrite the settings above , but will not overwrite settings that were explicitly set by the user ( e . g . we will not disable bisimulation or disable exact arithmetic )
getModelProcessingInformationPortfolio ( janiInput , mpi ) ;
if ( transformedJaniInput ) {
/ / We cache the transformation result .
* transformedJaniInput = std : : move ( janiInput ) ;
}
}
}
/ / Check whether these settings are compatible with the provided input .
@ -256,6 +285,14 @@ namespace storm {
}
}
/ / Set whether a transformation to jani is required or necessary
mpi . transformToJani = ioSettings . isPrismToJaniSet ( ) ;
auto builderType = storm : : utility : : getBuilderType ( mpi . engine ) ;
bool transformToJaniForJit = builderType = = storm : : builder : : BuilderType : : Jit ;
STORM_LOG_WARN_COND ( mpi . transformToJani | | ! transformToJaniForJit , " The JIT-based model builder is only available for JANI models, automatically converting the PRISM input model. " ) ;
bool transformToJaniForDdMA = ( builderType = = storm : : builder : : BuilderType : : Dd ) & & ( input . model - > getModelType ( ) = = storm : : storage : : SymbolicModelDescription : : ModelType : : MA ) ;
STORM_LOG_WARN_COND ( mpi . transformToJani | | ! transformToJaniForDdMA , " Dd-based model builder for Markov Automata is only available for JANI models, automatically converting the PRISM input model. " ) ;
mpi . transformToJani | = ( transformToJaniForJit | | transformToJaniForDdMA ) ;
/ / Set the Valuetype used during model building
mpi . buildValueType = mpi . verificationValueType ;
@ -294,17 +331,11 @@ namespace storm {
}
}
SymbolicInput preprocessSymbolicInput ( SymbolicInput const & input , storm : : utility : : Engine const & engine ) {
std : : pair < SymbolicInput , ModelProcessingInformation > preprocessSymbolicInput ( SymbolicInput const & input ) {
auto ioSettings = storm : : settings : : getModule < storm : : settings : : modules : : IOSettings > ( ) ;
auto builderType = storm : : utility : : getBuilderType ( engine ) ;
SymbolicInput output = input ;
if ( output . model & & output . model . get ( ) . isJaniModel ( ) ) {
storm : : jani : : ModelFeatures supportedFeatures = storm : : api : : getSupportedJaniFeatures ( builderType ) ;
storm : : api : : simplifyJaniModel ( output . model . get ( ) . asJaniModel ( ) , output . properties , supportedFeatures ) ;
}
/ / Substitute constant definitions in symbolic input .
std : : string constantDefinitionString = ioSettings . getConstantDefinitionString ( ) ;
std : : map < storm : : expressions : : Variable , storm : : expressions : : Expression > constantDefinitions ;
@ -315,25 +346,22 @@ namespace storm {
if ( ! output . properties . empty ( ) ) {
output . properties = storm : : api : : substituteConstantsInProperties ( output . properties , constantDefinitions ) ;
}
ensureNoUndefinedPropertyConstants ( output . properties ) ;
auto transformedJani = std : : make_shared < SymbolicInput > ( ) ;
ModelProcessingInformation mpi = getModelProcessingInformation ( output , transformedJani ) ;
/ / Check whether conversion for PRISM to JANI is requested or necessary .
if ( input . model & & input . model . get ( ) . isPrismProgram ( ) ) {
bool transformToJani = ioSettings . isPrismToJaniSet ( ) ;
bool transformToJaniForJit = builderType = = storm : : builder : : BuilderType : : Jit ;
STORM_LOG_WARN_COND ( transformToJani | | ! transformToJaniForJit , " The JIT-based model builder is only available for JANI models, automatically converting the PRISM input model. " ) ;
bool transformToJaniForDdMA = ( builderType = = storm : : builder : : BuilderType : : Dd ) & & ( input . model - > getModelType ( ) = = storm : : storage : : SymbolicModelDescription : : ModelType : : MA ) ;
STORM_LOG_WARN_COND ( transformToJani | | ! transformToJaniForDdMA , " Dd-based model builder for Markov Automata is only available for JANI models, automatically converting the PRISM input model. " ) ;
transformToJani | = ( transformToJaniForJit | | transformToJaniForDdMA ) ;
auto builderType = storm : : utility : : getBuilderType ( mpi . engine ) ;
if ( transformToJani ) {
/ / Check whether conversion for PRISM to JANI is requested or necessary .
if ( output . model & & output . model . get ( ) . isPrismProgram ( ) ) {
if ( mpi . transformToJani ) {
if ( transformedJani - > model ) {
/ / Use the cached transformation if possible
output = std : : move ( * transformedJani ) ;
} else {
storm : : prism : : Program const & model = output . model . get ( ) . asPrismProgram ( ) ;
auto modelAndProperties = model . toJani ( output . properties ) ;
/ / Remove functions here
modelAndProperties . first . substituteFunctions ( ) ;
output . model = modelAndProperties . first ;
if ( ! modelAndProperties . second . empty ( ) ) {
@ -341,8 +369,14 @@ namespace storm {
}
}
}
}
return output ;
if ( output . model & & output . model . get ( ) . isJaniModel ( ) ) {
storm : : jani : : ModelFeatures supportedFeatures = storm : : api : : getSupportedJaniFeatures ( builderType ) ;
storm : : api : : simplifyJaniModel ( output . model . get ( ) . asJaniModel ( ) , output . properties , supportedFeatures ) ;
}
return { output , mpi } ;
}
void exportSymbolicInput ( SymbolicInput const & input ) {
@ -355,16 +389,6 @@ namespace storm {
}
}
SymbolicInput parseAndPreprocessSymbolicInput ( storm : : utility : : Engine const & engine ) {
/ / Get the used builder type to handle cases where preprocessing depends on it
auto buildSettings = storm : : settings : : getModule < storm : : settings : : modules : : BuildSettings > ( ) ;
SymbolicInput input = parseSymbolicInput ( ) ;
input = preprocessSymbolicInput ( input , engine ) ;
exportSymbolicInput ( input ) ;
return input ;
}
std : : vector < std : : shared_ptr < storm : : logic : : Formula const > > createFormulasToRespect ( std : : vector < storm : : jani : : Property > const & properties ) {
std : : vector < std : : shared_ptr < storm : : logic : : Formula const > > result = storm : : api : : extractFormulasFromProperties ( properties ) ;