#include "storm/logic/Formula.h" #include "storm/utility/initialize.h" #include "storm/utility/storm.h" #include "storm/cli/cli.h" #include "storm/exceptions/BaseException.h" #include "storm/logic/Formula.h" #include "storm/settings/modules/GeneralSettings.h" #include "storm/settings/modules/CoreSettings.h" #include "storm/settings/modules/DebugSettings.h" #include "storm/settings/modules/GmmxxEquationSolverSettings.h" #include "storm/settings/modules/MinMaxEquationSolverSettings.h" #include "storm/settings/modules/NativeEquationSolverSettings.h" #include "storm/settings/modules/EliminationSettings.h" #include "storm/settings/modules/ResourceSettings.h" #include "storm-dft/parser/DFTGalileoParser.h" #include "storm-dft/parser/DFTJsonParser.h" #include "storm-dft/modelchecker/dft/DFTModelChecker.h" #include "storm-dft/modelchecker/dft/DFTASFChecker.h" #include "storm-dft/transformations/DftToGspnTransformator.h" #include "storm-dft/storage/dft/DftJsonExporter.h" #include "storm-dft/settings/modules/DFTSettings.h" #include "storm-gspn/storage/gspn/GSPN.h" #include "storm-gspn/storm-gspn.h" #include "storm/settings/modules/GSPNSettings.h" #include "storm/settings/modules/GSPNExportSettings.h" #include #include /*! * Analyse the given DFT according to the given properties. * We first load the DFT from the given file, then build the corresponding model and last check against the given properties. * * @param properties PCTL formulas capturing the properties to check. * @param symred Flag whether symmetry reduction should be used. * @param allowModularisation Flag whether modularisation should be applied if possible. * @param enableDC Flag whether Don't Care propagation should be used. * @param approximationError Allowed approximation error. */ template void analyzeDFT(std::vector const& properties, bool symred, bool allowModularisation, bool enableDC, double approximationError) { storm::settings::modules::DFTSettings const& dftSettings = storm::settings::getModule(); std::shared_ptr> dft; // Build DFT from given file. if (dftSettings.isDftJsonFileSet()) { storm::parser::DFTJsonParser parser; std::cout << "Loading DFT from file " << dftSettings.getDftJsonFilename() << std::endl; dft = std::make_shared>(parser.parseJson(dftSettings.getDftJsonFilename())); } else { storm::parser::DFTGalileoParser parser; std::cout << "Loading DFT from file " << dftSettings.getDftFilename() << std::endl; dft = std::make_shared>(parser.parseDFT(dftSettings.getDftFilename())); } // Build properties std::string propString = properties[0]; for (size_t i = 1; i < properties.size(); ++i) { propString += ";" + properties[i]; } std::vector> props = storm::extractFormulasFromProperties(storm::parsePropertiesForExplicit(propString)); STORM_LOG_ASSERT(props.size() > 0, "No properties found."); // Check model storm::modelchecker::DFTModelChecker modelChecker; modelChecker.check(*dft, props, symred, allowModularisation, enableDC, approximationError); modelChecker.printTimings(); modelChecker.printResults(); } /*! * Analyze the DFT with use of SMT solving. * * @param filename Path to DFT file in Galileo format. */ template void analyzeWithSMT(std::string filename) { std::cout << "Running DFT analysis on file " << filename << " with use of SMT" << std::endl; storm::parser::DFTGalileoParser parser; storm::storage::DFT dft = parser.parseDFT(filename); storm::modelchecker::DFTASFChecker asfChecker(dft); asfChecker.convert(); asfChecker.toFile("test.smt2"); //bool sat = dftSmtBuilder.check(); //std::cout << "SMT result: " << sat << std::endl; } /*! * Initialize the settings manager. */ void initializeSettings() { storm::settings::mutableManager().setName("StoRM-DyFTeE", "storm-dft"); // Register all known settings modules. storm::settings::addModule(); storm::settings::addModule(); storm::settings::addModule(); storm::settings::addModule(); //storm::settings::addModule(); //storm::settings::addModule(); //storm::settings::addModule(); storm::settings::addModule(); storm::settings::addModule(); storm::settings::addModule(); //storm::settings::addModule(); //storm::settings::addModule(); //storm::settings::addModule(); //storm::settings::addModule(); //storm::settings::addModule(); storm::settings::addModule(); storm::settings::addModule(); // For translation into JANI via GSPN. storm::settings::addModule(); storm::settings::addModule(); storm::settings::addModule(); } /*! * Entry point for the DyFTeE backend. * * @param argc The argc argument of main(). * @param argv The argv argument of main(). * @return Return code, 0 if successfull, not 0 otherwise. */ int main(const int argc, const char** argv) { try { storm::utility::setUp(); storm::cli::printHeader("StoRM-DyFTeE", argc, argv); initializeSettings(); bool optionsCorrect = storm::cli::parseOptions(argc, argv); if (!optionsCorrect) { return -1; } storm::settings::modules::DFTSettings const& dftSettings = storm::settings::getModule(); storm::settings::modules::GeneralSettings const& generalSettings = storm::settings::getModule(); if (!dftSettings.isDftFileSet() && !dftSettings.isDftJsonFileSet()) { STORM_LOG_THROW(false, storm::exceptions::InvalidSettingsException, "No input model."); } if (dftSettings.isExportToJson()) { STORM_LOG_THROW(dftSettings.isDftFileSet(), storm::exceptions::InvalidSettingsException, "No input model in Galileo format given."); storm::parser::DFTGalileoParser parser; storm::storage::DFT dft = parser.parseDFT(dftSettings.getDftFilename()); // Export to json storm::storage::DftJsonExporter::toFile(dft, dftSettings.getExportJsonFilename()); storm::utility::cleanUp(); return 0; } if (dftSettings.isTransformToGspn()) { std::shared_ptr> dft; if (dftSettings.isDftJsonFileSet()) { storm::parser::DFTJsonParser parser; dft = std::make_shared>(parser.parseJson(dftSettings.getDftJsonFilename())); } else { storm::parser::DFTGalileoParser parser(true, false); dft = std::make_shared>(parser.parseDFT(dftSettings.getDftFilename())); } storm::transformations::dft::DftToGspnTransformator gspnTransformator(*dft); gspnTransformator.transform(); storm::gspn::GSPN* gspn = gspnTransformator.obtainGSPN(); uint64_t toplevelFailedPlace = gspnTransformator.toplevelFailedPlaceId(); storm::handleGSPNExportSettings(*gspn); std::shared_ptr exprManager(new storm::expressions::ExpressionManager()); storm::builder::JaniGSPNBuilder builder(*gspn, exprManager); storm::jani::Model* model = builder.build(); storm::jani::Variable const& topfailedVar = builder.getPlaceVariable(toplevelFailedPlace); storm::expressions::Expression targetExpression = exprManager->integer(1) == topfailedVar.getExpressionVariable().getExpression(); auto evtlFormula = std::make_shared(targetExpression); auto tbFormula = std::make_shared(std::make_shared(true), evtlFormula, storm::logic::TimeBound(false, exprManager->integer(0)), storm::logic::TimeBound(false, exprManager->integer(10)), storm::logic::TimeBoundType::Time); auto tbUntil = std::make_shared(tbFormula); auto evFormula = std::make_shared(evtlFormula, storm::logic::FormulaContext::Time); auto rewFormula = std::make_shared(evFormula, storm::logic::OperatorInformation(), storm::logic::RewardMeasureType::Expectation); storm::settings::modules::JaniExportSettings const& janiSettings = storm::settings::getModule(); if (janiSettings.isJaniFileSet()) { storm::exportJaniModel(*model, {storm::jani::Property("time-bounded", tbUntil), storm::jani::Property("mttf", rewFormula)}, janiSettings.getJaniFilename()); } delete model; delete gspn; storm::utility::cleanUp(); return 0; } bool parametric = false; #ifdef STORM_HAVE_CARL parametric = generalSettings.isParametricSet(); #endif #ifdef STORM_HAVE_Z3 if (dftSettings.solveWithSMT()) { // Solve with SMT if (parametric) { // analyzeWithSMT(dftSettings.getDftFilename()); } else { analyzeWithSMT(dftSettings.getDftFilename()); } storm::utility::cleanUp(); return 0; } #endif // Set min or max std::string optimizationDirection = "min"; if (dftSettings.isComputeMaximalValue()) { STORM_LOG_THROW(!dftSettings.isComputeMinimalValue(), storm::exceptions::InvalidSettingsException, "Cannot compute minimal and maximal values at the same time."); optimizationDirection = "max"; } // Construct properties to check for std::vector properties; if (generalSettings.isPropertySet()) { properties.push_back(generalSettings.getProperty()); } if (dftSettings.usePropExpectedTime()) { properties.push_back("T" + optimizationDirection + "=? [F \"failed\"]"); } if (dftSettings.usePropProbability()) { properties.push_back("P" + optimizationDirection + "=? [F \"failed\"]"); } if (dftSettings.usePropTimebound()) { std::stringstream stream; stream << "P" << optimizationDirection << "=? [F<=" << dftSettings.getPropTimebound() << " \"failed\"]"; properties.push_back(stream.str()); } if (dftSettings.usePropTimepoints()) { for (double timepoint : dftSettings.getPropTimepoints()) { std::stringstream stream; stream << "P" << optimizationDirection << "=? [F<=" << timepoint << " \"failed\"]"; properties.push_back(stream.str()); } } if (properties.empty()) { STORM_LOG_THROW(false, storm::exceptions::InvalidSettingsException, "No property given."); } // Set possible approximation error double approximationError = 0.0; if (dftSettings.isApproximationErrorSet()) { approximationError = dftSettings.getApproximationError(); } // From this point on we are ready to carry out the actual computations. if (parametric) { #ifdef STORM_HAVE_CARL analyzeDFT(properties, dftSettings.useSymmetryReduction(), dftSettings.useModularisation(), !dftSettings.isDisableDC(), approximationError); #else STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Parameters are not supported in this build."); #endif } else { analyzeDFT(properties, dftSettings.useSymmetryReduction(), dftSettings.useModularisation(), !dftSettings.isDisableDC(), approximationError); } // All operations have now been performed, so we clean up everything and terminate. storm::utility::cleanUp(); return 0; } catch (storm::exceptions::BaseException const& exception) { STORM_LOG_ERROR("An exception caused StoRM-DyFTeE to terminate. The message of the exception is: " << exception.what()); return 1; } catch (std::exception const& exception) { STORM_LOG_ERROR("An unexpected exception occurred and caused StoRM-DyFTeE to terminate. The message of this exception is: " << exception.what()); return 2; } }