Browse Source

started to extend storm-conv for array elimination

main
TimQu 7 years ago
parent
commit
274bfef652
  1. 35
      src/storm-conv-cli/storm-conv.cpp
  2. 14
      src/storm-conv/api/storm-conv.cpp
  3. 2
      src/storm-conv/api/storm-conv.h
  4. 4
      src/storm-conv/converter/options/JaniConversionOptions.cpp
  5. 8
      src/storm-conv/converter/options/JaniConversionOptions.h
  6. 13
      src/storm-conv/settings/modules/ConversionInputSettings.cpp
  7. 11
      src/storm-conv/settings/modules/ConversionInputSettings.h
  8. 12
      src/storm-conv/settings/modules/JaniExportSettings.cpp
  9. 6
      src/storm-conv/settings/modules/JaniExportSettings.h
  10. 5
      src/storm-gspn/api/storm-gspn.cpp
  11. 2
      src/storm-pgcl-cli/storm-pgcl.cpp
  12. 7
      src/storm/storage/jani/Model.cpp
  13. 8
      src/storm/storage/jani/Model.h

35
src/storm-conv-cli/storm-conv.cpp

@ -124,14 +124,49 @@ namespace storm {
} }
} }
void processJaniInput() {
auto const& input = storm::settings::getModule<storm::settings::modules::ConversionInputSettings>();
// Parse the jani model
auto janiModelProperties = storm::api::parseJaniModel(input.getJaniInputFilename());
storm::storage::SymbolicModelDescription janiModel(janiModelProperties.first);
// Parse properties (if available, otherwise take the ones from the jani file)
std::vector<storm::jani::Property> properties;
if (input.isPropertyInputSet()) {
boost::optional<std::set<std::string>> propertyFilter = storm::api::parsePropertyFilter(input.getPropertyInputFilter());
properties = storm::api::parsePropertiesForSymbolicModelDescription(input.getPropertyInput(), janiModel, propertyFilter);
} else {
properties.insert(properties.end(), janiModelProperties.second.begin(), janiModelProperties.second.end());
}
// Substitute constant definitions in program and properties.
std::string constantDefinitionString = input.getConstantDefinitionString();
auto constantDefinitions = janiModel.parseConstantDefinitions(constantDefinitionString);
janiModel = janiModel.preprocess(constantDefinitions);
if (!properties.empty()) {
properties = storm::api::substituteConstantsInProperties(properties, constantDefinitions);
}
// Branch on the type of output
auto const& output = storm::settings::getModule<storm::settings::modules::ConversionOutputSettings>();
if (output.isJaniOutputSet()) {
// processJaniInputJaniOutput(janiModel.asJaniModel(), properties);
} else {
STORM_LOG_THROW(false, storm::exceptions::InvalidSettingsException, "There is either no outputformat specified or the provided combination of input and output format is not compatible.");
}
}
void processOptions() { void processOptions() {
// Start by setting some urgent options (log levels, etc.) // Start by setting some urgent options (log levels, etc.)
setUrgentOptions(); setUrgentOptions();
// Branch on the type of input // Branch on the type of input
auto const& input = storm::settings::getModule<storm::settings::modules::ConversionInputSettings>(); auto const& input = storm::settings::getModule<storm::settings::modules::ConversionInputSettings>();
STORM_LOG_THROW(!(input.isPrismInputSet() && input.isJaniInputSet()), storm::exceptions::InvalidSettingsException, "Multiple input options were set.");
if (input.isPrismInputSet()) { if (input.isPrismInputSet()) {
processPrismInput(); processPrismInput();
} else if (input.isJaniInputSet()) {
processJaniInput();
} }
} }
} }

14
src/storm-conv/api/storm-conv.cpp

@ -11,7 +11,7 @@
namespace storm { namespace storm {
namespace api { namespace api {
void postprocessJani(storm::jani::Model& janiModel, storm::converter::JaniConversionOptions options) {
void transformJani(storm::jani::Model& janiModel, std::vector<storm::jani::Property>& properties, storm::converter::JaniConversionOptions const& options) {
if (!options.locationVariables.empty()) { if (!options.locationVariables.empty()) {
for (auto const& pair : options.locationVariables) { for (auto const& pair : options.locationVariables) {
@ -21,7 +21,7 @@ namespace storm {
} }
} }
if (options.exportFlattened) {
if (options.flatten) {
std::shared_ptr<storm::utility::solver::SmtSolverFactory> smtSolverFactory; std::shared_ptr<storm::utility::solver::SmtSolverFactory> smtSolverFactory;
if (storm::settings::hasModule<storm::settings::modules::CoreSettings>()) { if (storm::settings::hasModule<storm::settings::modules::CoreSettings>()) {
smtSolverFactory = std::make_shared<storm::utility::solver::SmtSolverFactory>(); smtSolverFactory = std::make_shared<storm::utility::solver::SmtSolverFactory>();
@ -35,6 +35,14 @@ namespace storm {
janiModel.makeStandardJaniCompliant(); janiModel.makeStandardJaniCompliant();
} }
if (!options.allowArrays && janiModel.getModelFeatures().hasArrays()) {
janiModel.eliminateArrays(properties);
}
//if (!options.allowFunctions && janiModel.getModelFeatures().hasFunctions()) {
//janiModel = janiModel.substituteFunctions();
//}
if (options.modelName) { if (options.modelName) {
janiModel.setName(options.modelName.get()); janiModel.setName(options.modelName.get());
} }
@ -53,7 +61,7 @@ namespace storm {
} }
// Postprocess Jani model based on the options // Postprocess Jani model based on the options
postprocessJani(res.first, options.janiOptions);
transformJani(res.first, res.second, options.janiOptions);
return res; return res;
} }

2
src/storm-conv/api/storm-conv.h

@ -15,7 +15,7 @@ namespace storm {
namespace api { namespace api {
void postprocessJani(storm::jani::Model& janiModel, storm::converter::JaniConversionOptions options);
void transformJani(storm::jani::Model& janiModel, std::vector<storm::jani::Property>& properties, storm::converter::JaniConversionOptions const& options);
std::pair<storm::jani::Model, std::vector<storm::jani::Property>> convertPrismToJani(storm::prism::Program const& program, std::vector<storm::jani::Property> const& properties = std::vector<storm::jani::Property>(), storm::converter::PrismToJaniConverterOptions options = storm::converter::PrismToJaniConverterOptions()); std::pair<storm::jani::Model, std::vector<storm::jani::Property>> convertPrismToJani(storm::prism::Program const& program, std::vector<storm::jani::Property> const& properties = std::vector<storm::jani::Property>(), storm::converter::PrismToJaniConverterOptions options = storm::converter::PrismToJaniConverterOptions());

4
src/storm-conv/converter/options/JaniConversionOptions.cpp

@ -3,11 +3,11 @@
namespace storm { namespace storm {
namespace converter { namespace converter {
JaniConversionOptions::JaniConversionOptions() : standardCompliant(false), exportFlattened(false) {
JaniConversionOptions::JaniConversionOptions() : standardCompliant(false), flatten(false), allowArrays(true), allowFunctions(true) {
// Intentionally left empty // Intentionally left empty
}; };
JaniConversionOptions::JaniConversionOptions(storm::settings::modules::JaniExportSettings const& settings) : locationVariables(settings.getLocationVariables()), standardCompliant(settings.isExportAsStandardJaniSet()), exportFlattened(settings.isExportFlattenedSet()) {
JaniConversionOptions::JaniConversionOptions(storm::settings::modules::JaniExportSettings const& settings) : locationVariables(settings.getLocationVariables()), standardCompliant(settings.isExportAsStandardJaniSet()), flatten(settings.isExportFlattenedSet()), allowArrays(!settings.isEliminateArraysSet()), allowFunctions(!settings.isEliminateFunctionsSet()) {
// Intentionally left empty // Intentionally left empty
}; };
} }

8
src/storm-conv/converter/options/JaniConversionOptions.h

@ -21,11 +21,17 @@ namespace storm {
bool standardCompliant; bool standardCompliant;
/// If set, the model is transformed into a single automaton /// If set, the model is transformed into a single automaton
bool exportFlattened;
bool flatten;
/// If given, the model will get this name /// If given, the model will get this name
boost::optional<std::string> modelName; boost::optional<std::string> modelName;
/// If not set, arrays in the model are eliminated
bool allowArrays;
/// if not set, functions in the model are eliminated
bool allowFunctions;
}; };
} }
} }

13
src/storm-conv/settings/modules/ConversionInputSettings.cpp

@ -20,6 +20,7 @@ namespace storm {
const std::string ConversionInputSettings::prismInputOptionName = "prism"; const std::string ConversionInputSettings::prismInputOptionName = "prism";
const std::string ConversionInputSettings::prismCompatibilityOptionName = "prismcompat"; const std::string ConversionInputSettings::prismCompatibilityOptionName = "prismcompat";
const std::string ConversionInputSettings::prismCompatibilityOptionShortName = "pc"; const std::string ConversionInputSettings::prismCompatibilityOptionShortName = "pc";
const std::string ConversionInputSettings::janiInputOptionName = "jani";
ConversionInputSettings::ConversionInputSettings() : ModuleSettings(moduleName) { ConversionInputSettings::ConversionInputSettings() : ModuleSettings(moduleName) {
@ -27,10 +28,12 @@ namespace storm {
.addArgument(storm::settings::ArgumentBuilder::createStringArgument("property or filename", "The formula or the file containing the formulas.").build()) .addArgument(storm::settings::ArgumentBuilder::createStringArgument("property or filename", "The formula or the file containing the formulas.").build())
.addArgument(storm::settings::ArgumentBuilder::createStringArgument("filter", "The names of the properties to check.").setDefaultValueString("all").build()) .addArgument(storm::settings::ArgumentBuilder::createStringArgument("filter", "The names of the properties to check.").setDefaultValueString("all").build())
.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 + ").").setShortName(constantsOptionShortName)
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 (e.g., via --" + prismInputOptionName + ").").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()); .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, prismInputOptionName, false, "Parses the model given in the PRISM format.") this->addOption(storm::settings::OptionBuilder(moduleName, prismInputOptionName, false, "Parses the model given in the PRISM format.")
.addArgument(storm::settings::ArgumentBuilder::createStringArgument("filename", "The name of the file from which to read the PRISM input.").addValidatorString(ArgumentValidatorFactory::createExistingFileValidator()).build()).build()); .addArgument(storm::settings::ArgumentBuilder::createStringArgument("filename", "The name of the file from which to read the PRISM input.").addValidatorString(ArgumentValidatorFactory::createExistingFileValidator()).build()).build());
this->addOption(storm::settings::OptionBuilder(moduleName, janiInputOptionName, false, "Parses the model given in the JANI format.")
.addArgument(storm::settings::ArgumentBuilder::createStringArgument("filename", "The name of the file from which to read the JANI input.").addValidatorString(ArgumentValidatorFactory::createExistingFileValidator()).build()).build());
this->addOption(storm::settings::OptionBuilder(moduleName, prismCompatibilityOptionName, false, "Enables PRISM compatibility. This may be necessary to process some PRISM models.").setShortName(prismCompatibilityOptionShortName).build()); this->addOption(storm::settings::OptionBuilder(moduleName, prismCompatibilityOptionName, false, "Enables PRISM compatibility. This may be necessary to process some PRISM models.").setShortName(prismCompatibilityOptionShortName).build());
} }
@ -42,6 +45,14 @@ namespace storm {
return this->getOption(prismInputOptionName).getArgumentByName("filename").getValueAsString(); return this->getOption(prismInputOptionName).getArgumentByName("filename").getValueAsString();
} }
bool ConversionInputSettings::isJaniInputSet() const {
return this->getOption(janiInputOptionName).getHasOptionBeenSet();
}
std::string ConversionInputSettings::getJaniInputFilename() const {
return this->getOption(janiInputOptionName).getArgumentByName("filename").getValueAsString();
}
bool ConversionInputSettings::isPrismCompatibilityEnabled() const { bool ConversionInputSettings::isPrismCompatibilityEnabled() const {
return this->getOption(prismCompatibilityOptionName).getHasOptionBeenSet(); return this->getOption(prismCompatibilityOptionName).getHasOptionBeenSet();
} }

11
src/storm-conv/settings/modules/ConversionInputSettings.h

@ -63,6 +63,16 @@ namespace storm {
*/ */
bool isPrismCompatibilityEnabled() const; bool isPrismCompatibilityEnabled() const;
/*!
* Retrieves whether the Jani option was set.
*/
bool isJaniInputSet() const;
/*!
* Retrieves the name of the file that contains the jani model specification if the model was given.
*/
std::string getJaniInputFilename() const;
bool check() const override; bool check() const override;
void finalize() override; void finalize() override;
@ -78,6 +88,7 @@ namespace storm {
static const std::string prismInputOptionName; static const std::string prismInputOptionName;
static const std::string prismCompatibilityOptionName; static const std::string prismCompatibilityOptionName;
static const std::string prismCompatibilityOptionShortName; static const std::string prismCompatibilityOptionShortName;
static const std::string janiInputOptionName;
}; };

12
src/storm-conv/settings/modules/JaniExportSettings.cpp

@ -20,6 +20,8 @@ namespace storm {
const std::string JaniExportSettings::locationVariablesOptionName = "location-variables"; const std::string JaniExportSettings::locationVariablesOptionName = "location-variables";
const std::string JaniExportSettings::globalVariablesOptionName = "globalvars"; const std::string JaniExportSettings::globalVariablesOptionName = "globalvars";
const std::string JaniExportSettings::compactJsonOptionName = "compactjson"; const std::string JaniExportSettings::compactJsonOptionName = "compactjson";
const std::string JaniExportSettings::eliminateArraysOptionName = "eliminate-arrays";
const std::string JaniExportSettings::eliminateFunctionsOptionName = "eliminate-functions";
JaniExportSettings::JaniExportSettings() : ModuleSettings(moduleName) { JaniExportSettings::JaniExportSettings() : ModuleSettings(moduleName) {
@ -28,6 +30,8 @@ namespace storm {
this->addOption(storm::settings::OptionBuilder(moduleName, exportFlattenOptionName, false, "Flattens the composition of Automata to obtain an equivalent model that contains exactly one automaton").build()); this->addOption(storm::settings::OptionBuilder(moduleName, exportFlattenOptionName, false, "Flattens the composition of Automata to obtain an equivalent model that contains exactly one automaton").build());
this->addOption(storm::settings::OptionBuilder(moduleName, globalVariablesOptionName, false, "If set, variables will preferably be made global, e.g., to guarantee the same variable order as in the input file.").build()); this->addOption(storm::settings::OptionBuilder(moduleName, globalVariablesOptionName, false, "If set, variables will preferably be made global, e.g., to guarantee the same variable order as in the input file.").build());
this->addOption(storm::settings::OptionBuilder(moduleName, compactJsonOptionName, false, "If set, the size of the resulting jani file will be reduced at the cost of (human-)readability.").build()); this->addOption(storm::settings::OptionBuilder(moduleName, compactJsonOptionName, false, "If set, the size of the resulting jani file will be reduced at the cost of (human-)readability.").build());
this->addOption(storm::settings::OptionBuilder(moduleName, eliminateArraysOptionName, false, "If set, transforms the model such that array variables/expressions are eliminated.").build());
this->addOption(storm::settings::OptionBuilder(moduleName, eliminateFunctionsOptionName, false, "If set, transforms the model such that functions are eliminated.").build());
} }
bool JaniExportSettings::isExportAsStandardJaniSet() const { bool JaniExportSettings::isExportAsStandardJaniSet() const {
@ -66,6 +70,14 @@ namespace storm {
return this->getOption(compactJsonOptionName).getHasOptionBeenSet(); return this->getOption(compactJsonOptionName).getHasOptionBeenSet();
} }
bool JaniExportSettings::isEliminateArraysSet() const {
return this->getOption(eliminateArraysOptionName).getHasOptionBeenSet();
}
bool JaniExportSettings::isEliminateFunctionsSet() const {
return this->getOption(eliminateFunctionsOptionName).getHasOptionBeenSet();
}
void JaniExportSettings::finalize() { void JaniExportSettings::finalize() {
} }

6
src/storm-conv/settings/modules/JaniExportSettings.h

@ -23,6 +23,10 @@ namespace storm {
bool isGlobalVarsSet() const; bool isGlobalVarsSet() const;
bool isCompactJsonSet() const; bool isCompactJsonSet() const;
bool isEliminateArraysSet() const;
bool isEliminateFunctionsSet() const;
std::vector<std::pair<std::string, std::string>> getLocationVariables() const; std::vector<std::pair<std::string, std::string>> getLocationVariables() const;
@ -38,6 +42,8 @@ namespace storm {
static const std::string locationVariablesOptionName; static const std::string locationVariablesOptionName;
static const std::string globalVariablesOptionName; static const std::string globalVariablesOptionName;
static const std::string compactJsonOptionName; static const std::string compactJsonOptionName;
static const std::string eliminateArraysOptionName;
static const std::string eliminateFunctionsOptionName;
}; };
} }

5
src/storm-gspn/api/storm-gspn.cpp

@ -66,12 +66,13 @@ namespace storm {
storm::builder::JaniGSPNBuilder builder(gspn); storm::builder::JaniGSPNBuilder builder(gspn);
storm::jani::Model* model = builder.build("gspn_automaton", exportSettings.isAddJaniPropertiesSet()); storm::jani::Model* model = builder.build("gspn_automaton", exportSettings.isAddJaniPropertiesSet());
storm::api::postprocessJani(*model, options);
auto properties = janiProperyGetter(builder); auto properties = janiProperyGetter(builder);
if (exportSettings.isAddJaniPropertiesSet()) { if (exportSettings.isAddJaniPropertiesSet()) {
properties.insert(properties.end(), builder.getStandardProperties().begin(), builder.getStandardProperties().end()); properties.insert(properties.end(), builder.getStandardProperties().begin(), builder.getStandardProperties().end());
} }
storm::api::transformJani(*model, properties, options);
storm::api::exportJaniToFile(*model, properties, exportSettings.getWriteToJaniFilename(), jani.isCompactJsonSet()); storm::api::exportJaniToFile(*model, properties, exportSettings.getWriteToJaniFilename(), jani.isCompactJsonSet());
delete model; delete model;
} }

2
src/storm-pgcl-cli/storm-pgcl.cpp

@ -41,7 +41,7 @@ void initializeSettings() {
void handleJani(storm::jani::Model& model) { void handleJani(storm::jani::Model& model) {
auto const& jani = storm::settings::getModule<storm::settings::modules::JaniExportSettings>(); auto const& jani = storm::settings::getModule<storm::settings::modules::JaniExportSettings>();
storm::converter::JaniConversionOptions options(jani); storm::converter::JaniConversionOptions options(jani);
storm::api::postprocessJani(model, options);
storm::api::transformJani(model, {}, options);
if (storm::settings::getModule<storm::settings::modules::PGCLSettings>().isToJaniSet()) { if (storm::settings::getModule<storm::settings::modules::PGCLSettings>().isToJaniSet()) {
storm::api::exportJaniToFile(model, {}, storm::settings::getModule<storm::settings::modules::PGCLSettings>().getWriteToJaniFilename(), jani.isCompactJsonSet()); storm::api::exportJaniToFile(model, {}, storm::settings::getModule<storm::settings::modules::PGCLSettings>().getWriteToJaniFilename(), jani.isCompactJsonSet());
} else { } else {

7
src/storm/storage/jani/Model.cpp

@ -959,8 +959,11 @@ namespace storm {
return arrayEliminator.eliminate(*this, keepNonTrivialArrayAccess); return arrayEliminator.eliminate(*this, keepNonTrivialArrayAccess);
} }
void Model::eliminateArrays() {
eliminateArrays(false);
void Model::eliminateArrays(std::vector<Property>& properties) {
auto data = eliminateArrays(false);
for (auto& p : properties) {
data.transformProperty(p);
}
} }
void Model::setInitialStatesRestriction(storm::expressions::Expression const& initialStatesRestriction) { void Model::setInitialStatesRestriction(storm::expressions::Expression const& initialStatesRestriction) {

8
src/storm/storage/jani/Model.h

@ -35,6 +35,7 @@ namespace storm {
class Exporter; class Exporter;
class SynchronizationVector; class SynchronizationVector;
class ArrayEliminatorData; class ArrayEliminatorData;
class Property;
class Model { class Model {
public: public:
@ -380,7 +381,12 @@ namespace storm {
* @return data from the elimination. If non-trivial array accesses are kept, pointers to remaining array variables point to this data. * @return data from the elimination. If non-trivial array accesses are kept, pointers to remaining array variables point to this data.
*/ */
ArrayEliminatorData eliminateArrays(bool keepNonTrivialArrayAccess); ArrayEliminatorData eliminateArrays(bool keepNonTrivialArrayAccess);
void eliminateArrays();
/*!
* Eliminates occurring array variables and expressions by replacing array variables by multiple basic variables.
* @param properties also eliminates array expressions in the given properties
*/
void eliminateArrays(std::vector<Property>& properties);
/*! /*!
* Retrieves whether there is an expression restricting the legal initial values of the global variables. * Retrieves whether there is an expression restricting the legal initial values of the global variables.

Loading…
Cancel
Save