STORM_LOG_THROW(storm::settings::getModule<storm::settings::modules::CoreSettings>().getEngine()==storm::settings::modules::CoreSettings::Engine::Sparse,storm::exceptions::InvalidSettingsException,"Only the sparse engine supports explicit model input.");
// If the model is given in an explicit format, we parse the properties without allowing expressions
STORM_LOG_THROW(model->getType()==storm::models::ModelType::Dtmc||model->getType()==storm::models::ModelType::Ctmc,storm::exceptions::InvalidSettingsException,"Currently parametric verification is only available for DTMCs and CTMCs.");
STORM_LOG_THROW(model.isPrismProgram(),storm::exceptions::InvalidSettingsException,"Exploration engine is currently only applicable to PRISM models.");
STORM_LOG_THROW(program.getModelType()==storm::prism::Program::ModelType::DTMC||program.getModelType()==storm::prism::Program::ModelType::MDP,storm::exceptions::InvalidSettingsException,"Currently exploration-based verification is only available for DTMCs and MDPs.");
STORM_LOG_THROW(storm::settings::getModule<storm::settings::modules::CoreSettings>().getEngine()==storm::settings::modules::CoreSettings::Engine::Sparse,storm::exceptions::InvalidSettingsException,"Cannot use this data type with an engine different than the sparse one.");
STORM_LOG_THROW(storm::settings::getModule<storm::settings::modules::CoreSettings>().getEngine()==storm::settings::modules::CoreSettings::Engine::Sparse,storm::exceptions::InvalidSettingsException,"Cannot use this data type with an engine different than the sparse one.");
return{parseFormula(propertyStructure.at("left"),"Operand of operator "+opstring),parseFormula(propertyStructure.at("right"),"Operand of operator "+opstring)};
pi.lowerBound=parseExpression(piStructure.at("lower"),"Lower bound for property interval");
// TODO substitute constants.
STORM_LOG_THROW(!pi.lowerBound.containsVariables(),storm::exceptions::NotSupportedException,"Only constant expressions are supported as lower bounds");
}
if(piStructure.count("lower-exclusive")>0){
STORM_LOG_THROW(pi.lowerBound.isInitialized(),storm::exceptions::InvalidJaniException,"Lower-exclusive can only be set if a lower bound is present");
pi.upperBound=parseExpression(piStructure.at("upper"),"Upper bound for property interval");
// TODO substitute constants.
STORM_LOG_THROW(!pi.upperBound.containsVariables(),storm::exceptions::NotSupportedException,"Only constant expressions are supported as upper bounds");
}
if(piStructure.count("upper-exclusive")>0){
STORM_LOG_THROW(pi.lowerBound.isInitialized(),storm::exceptions::InvalidJaniException,"Lower-exclusive can only be set if a lower bound is present");
STORM_LOG_THROW(pi.lowerBound.isInitialized()||pi.upperBound.isInitialized(),storm::exceptions::InvalidJaniException,"Bounded operators must be bounded");
STORM_LOG_THROW(pi.hasUpperBound(),storm::exceptions::NotSupportedException,"Storm only supports step-bounded until with an upper bound");
if(pi.hasLowerBound()){
STORM_LOG_THROW(pi.lowerBound.evaluateAsInt()==0,storm::exceptions::NotSupportedException,"Storm only supports step-bounded until without a (non-trivial) lower-bound");
}
int64_tupperBound=pi.upperBound.evaluateAsInt();
if(pi.upperBoundStrict){
upperBound--;
}
STORM_LOG_THROW(upperBound>=0,storm::exceptions::InvalidJaniException,"Step-bounds cannot be negative");
STORM_LOG_THROW(expressionStructure.at("op")=="filter",storm::exceptions::InvalidJaniException,"Top level operation of a property must be a filter");
STORM_LOG_THROW(expressionStructure.count("fun")==1,storm::exceptions::InvalidJaniException,"Filter must have a function descritpion");
std::stringfunDescr=getString(expressionStructure.at("fun"),"Filter function in property named "+name);
storm::jani::FilterTypeft;
storm::modelchecker::FilterTypeft;
if(funDescr=="min"){
ft=storm::jani::FilterType::MIN;
ft=storm::modelchecker::FilterType::MIN;
}elseif(funDescr=="max"){
ft=storm::jani::FilterType::MAX;
ft=storm::modelchecker::FilterType::MAX;
}elseif(funDescr=="sum"){
ft=storm::jani::FilterType::SUM;
ft=storm::modelchecker::FilterType::SUM;
}elseif(funDescr=="avg"){
ft=storm::jani::FilterType::AVG;
ft=storm::modelchecker::FilterType::AVG;
}elseif(funDescr=="count"){
ft=storm::jani::FilterType::COUNT;
ft=storm::modelchecker::FilterType::COUNT;
}elseif(funDescr=="∀"){
ft=storm::jani::FilterType::FORALL;
ft=storm::modelchecker::FilterType::FORALL;
}elseif(funDescr=="∃"){
ft=storm::jani::FilterType::EXISTS;
ft=storm::modelchecker::FilterType::EXISTS;
}elseif(funDescr=="argmin"){
ft=storm::jani::FilterType::ARGMIN;
ft=storm::modelchecker::FilterType::ARGMIN;
}elseif(funDescr=="argmax"){
ft=storm::jani::FilterType::ARGMAX;
ft=storm::modelchecker::FilterType::ARGMAX;
}elseif(funDescr=="values"){
ft=storm::jani::FilterType::VALUES;
ft=storm::modelchecker::FilterType::VALUES;
}else{
STORM_LOG_THROW(false,storm::exceptions::InvalidJaniException,"Unknown filter description "<<funDescr<<" in property named "<<name);
}
STORM_LOG_THROW(expressionStructure.count("states")==1,storm::exceptions::InvalidJaniException,"Filter must have a states description");
STORM_LOG_THROW(expressionStructure.at("states").is_string(),storm::exceptions::NotImplementedException,"We only support properties where the filter has a non-complex description of the states");
std::stringstatesDescr=getString(expressionStructure.at("states"),"Filtered states in property named "+name);
STORM_LOG_THROW(expressionStructure.at("states").count("op")>0,storm::exceptions::NotImplementedException,"We only support properties where the filter has initial states");
std::stringstatesDescr=getString(expressionStructure.at("states").at("op"),"Filtered states in property named "+name);
STORM_LOG_THROW(statesDescr=="initial",storm::exceptions::NotImplementedException,"Only initial states are allowed as set of states we are interested in.");
STORM_LOG_THROW(expressionStructure.count("values")==1,storm::exceptions::InvalidJaniException,"Values as input for a filter must be given");
autoformula=parseFormula(expressionStructure.at("values"),"Values of property "+name);
this->addOption(storm::settings::OptionBuilder(moduleName,prismCompatibilityOptionName,false,"Enables PRISM compatibility. This may be necessary to process some PRISM models.").setShortName(prismCompatibilityOptionShortName).build());
@ -57,6 +60,8 @@ namespace storm {
.addArgument(storm::settings::ArgumentBuilder::createStringArgument("filename","The file from which to read the choice labels.").addValidationFunctionString(storm::settings::ArgumentValidators::existingReadableFileValidator()).build()).build());
this->addOption(storm::settings::OptionBuilder(moduleName,constantsOptionName,false,"Specifies the constant replacements to use in symbolic models. Note that this requires the model to be given as an symbolic model (i.e., via --"+prismInputOptionName+" or --"+janiInputOptionName+").").setShortName(constantsOptionShortName)
.addArgument(storm::settings::ArgumentBuilder::createStringArgument("values","A comma separated list of constants and their value, e.g. a=1,b=2,c=3.").setDefaultValueString("").build()).build());
this->addOption(storm::settings::OptionBuilder(moduleName,janiPropertyOptionName,false,"Specifies the properties from the jani model (given by --"+janiInputOptionName+") to be checked.").setShortName(janiPropertyOptionShortName)
.addArgument(storm::settings::ArgumentBuilder::createStringArgument("values","A comma separated list of properties to be checked").setDefaultValueString("").build()).build());