|
|
@ -14,7 +14,6 @@ |
|
|
|
#include "storm/utility/initialize.h"
|
|
|
|
#include "storm-cli-utilities/cli.h"
|
|
|
|
#include "storm-parsers/api/storm-parsers.h"
|
|
|
|
#include "storm-dft/transformations/DftTransformator.h"
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
@ -25,52 +24,40 @@ void processOptions() { |
|
|
|
// Start by setting some urgent options (log levels, resources, etc.)
|
|
|
|
storm::cli::setUrgentOptions(); |
|
|
|
|
|
|
|
storm::settings::modules::DftIOSettings const& dftIOSettings = storm::settings::getModule<storm::settings::modules::DftIOSettings>(); |
|
|
|
storm::settings::modules::FaultTreeSettings const& faultTreeSettings = storm::settings::getModule<storm::settings::modules::FaultTreeSettings>(); |
|
|
|
storm::settings::modules::IOSettings const& ioSettings = storm::settings::getModule<storm::settings::modules::IOSettings>(); |
|
|
|
storm::settings::modules::DftGspnSettings const& dftGspnSettings = storm::settings::getModule<storm::settings::modules::DftGspnSettings>(); |
|
|
|
storm::settings::modules::TransformationSettings const &transformationSettings = storm::settings::getModule<storm::settings::modules::TransformationSettings>(); |
|
|
|
|
|
|
|
auto dftTransformator = storm::transformations::dft::DftTransformator<ValueType>(); |
|
|
|
|
|
|
|
if (!dftIOSettings.isDftFileSet() && !dftIOSettings.isDftJsonFileSet()) { |
|
|
|
STORM_LOG_THROW(false, storm::exceptions::InvalidSettingsException, "No input model given."); |
|
|
|
} |
|
|
|
auto const& dftIOSettings = storm::settings::getModule<storm::settings::modules::DftIOSettings>(); |
|
|
|
auto const& faultTreeSettings = storm::settings::getModule<storm::settings::modules::FaultTreeSettings>(); |
|
|
|
auto const& ioSettings = storm::settings::getModule<storm::settings::modules::IOSettings>(); |
|
|
|
auto const& dftGspnSettings = storm::settings::getModule<storm::settings::modules::DftGspnSettings>(); |
|
|
|
auto const& transformationSettings = storm::settings::getModule<storm::settings::modules::TransformationSettings>(); |
|
|
|
|
|
|
|
// Build DFT from given file
|
|
|
|
std::shared_ptr<storm::storage::DFT<ValueType>> dft; |
|
|
|
if (dftIOSettings.isDftJsonFileSet()) { |
|
|
|
STORM_LOG_DEBUG("Loading DFT from file " << dftIOSettings.getDftJsonFilename()); |
|
|
|
if (dftIOSettings.isDftFileSet()) { |
|
|
|
STORM_LOG_DEBUG("Loading DFT from Galileo file " << dftIOSettings.getDftFilename()); |
|
|
|
dft = storm::api::loadDFTGalileoFile<ValueType>(dftIOSettings.getDftFilename()); |
|
|
|
} else if (dftIOSettings.isDftJsonFileSet()) { |
|
|
|
STORM_LOG_DEBUG("Loading DFT from Json file " << dftIOSettings.getDftJsonFilename()); |
|
|
|
dft = storm::api::loadDFTJsonFile<ValueType>(dftIOSettings.getDftJsonFilename()); |
|
|
|
} else { |
|
|
|
STORM_LOG_DEBUG("Loading DFT from file " << dftIOSettings.getDftFilename()); |
|
|
|
dft = storm::api::loadDFTGalileoFile<ValueType>(dftIOSettings.getDftFilename()); |
|
|
|
STORM_LOG_THROW(false, storm::exceptions::InvalidSettingsException, "No input model given."); |
|
|
|
} |
|
|
|
|
|
|
|
// DFT statistics
|
|
|
|
if (dftIOSettings.isDisplayStatsSet()) { |
|
|
|
dft->writeStatsToStream(std::cout); |
|
|
|
} |
|
|
|
|
|
|
|
// Export to json
|
|
|
|
if (dftIOSettings.isExportToJson()) { |
|
|
|
// Export to json
|
|
|
|
storm::api::exportDFTToJsonFile<ValueType>(*dft, dftIOSettings.getExportJsonFilename()); |
|
|
|
} |
|
|
|
|
|
|
|
// Limit to one constantly failed BE
|
|
|
|
if (faultTreeSettings.isUniqueFailedBE()) { |
|
|
|
dft = dftTransformator.transformUniqueFailedBe(*dft); |
|
|
|
} |
|
|
|
|
|
|
|
// Eliminate non-binary dependencies
|
|
|
|
if (!dft->getDependencies().empty()) { |
|
|
|
dft = dftTransformator.transformBinaryFDEPs(*dft); |
|
|
|
} |
|
|
|
// Check well-formedness of DFT
|
|
|
|
auto wellFormedResult = storm::api::isWellFormed(*dft, false); |
|
|
|
STORM_LOG_THROW(wellFormedResult.first, storm::exceptions::UnmetRequirementException, "DFT is not well-formed: " << wellFormedResult.second); |
|
|
|
|
|
|
|
// Transformation to GSPN
|
|
|
|
if (dftGspnSettings.isTransformToGspn()) { |
|
|
|
// Transform to GSPN
|
|
|
|
std::pair<std::shared_ptr<storm::gspn::GSPN>, uint64_t> pair = storm::api::transformToGSPN(*dft); |
|
|
|
std::shared_ptr<storm::gspn::GSPN> gspn = pair.first; |
|
|
|
uint64_t toplevelFailedPlace = pair.second; |
|
|
@ -79,13 +66,13 @@ void processOptions() { |
|
|
|
storm::api::handleGSPNExportSettings(*gspn); |
|
|
|
|
|
|
|
// Transform to Jani
|
|
|
|
// TODO analyse Jani model
|
|
|
|
std::shared_ptr<storm::jani::Model> model = storm::api::transformToJani(*gspn, toplevelFailedPlace); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
// SMT
|
|
|
|
// Export to SMT
|
|
|
|
if (dftIOSettings.isExportToSmt()) { |
|
|
|
// Export to smtlib2
|
|
|
|
storm::api::exportDFTToSMT<ValueType>(*dft, dftIOSettings.getExportSmtFilename()); |
|
|
|
return; |
|
|
|
} |
|
|
@ -95,35 +82,35 @@ void processOptions() { |
|
|
|
#ifdef STORM_HAVE_Z3
|
|
|
|
if (faultTreeSettings.solveWithSMT()) { |
|
|
|
useSMT = true; |
|
|
|
STORM_PRINT("Use SMT for preprocessing" << std::endl) |
|
|
|
STORM_LOG_DEBUG("Use SMT for preprocessing"); |
|
|
|
} |
|
|
|
#endif
|
|
|
|
|
|
|
|
// Apply transformations
|
|
|
|
// TODO transform later before actual analysis
|
|
|
|
dft = storm::api::applyTransformations(*dft, faultTreeSettings.isUniqueFailedBE(), true); |
|
|
|
|
|
|
|
|
|
|
|
dft->setDynamicBehaviorInfo(); |
|
|
|
|
|
|
|
storm::api::PreprocessingResult preResults; |
|
|
|
preResults.lowerBEBound = storm::dft::utility::FailureBoundFinder::getLeastFailureBound(*dft, useSMT, |
|
|
|
solverTimeout); |
|
|
|
preResults.upperBEBound = storm::dft::utility::FailureBoundFinder::getAlwaysFailedBound(*dft, useSMT, |
|
|
|
solverTimeout); |
|
|
|
STORM_LOG_DEBUG("BE FAILURE BOUNDS" << std::endl << "========================================" << std::endl << |
|
|
|
// TODO: always needed?
|
|
|
|
preResults.lowerBEBound = storm::dft::utility::FailureBoundFinder::getLeastFailureBound(*dft, useSMT, solverTimeout); |
|
|
|
preResults.upperBEBound = storm::dft::utility::FailureBoundFinder::getAlwaysFailedBound(*dft, useSMT, solverTimeout); |
|
|
|
STORM_LOG_DEBUG("BE failure bounds" << std::endl << "========================================" << std::endl << |
|
|
|
"Lower bound: " << std::to_string(preResults.lowerBEBound) << std::endl << |
|
|
|
"Upper bound: " << std::to_string(preResults.upperBEBound) << std::endl); |
|
|
|
"Upper bound: " << std::to_string(preResults.upperBEBound)); |
|
|
|
|
|
|
|
// TODO: move into API call?
|
|
|
|
preResults.fdepConflicts = storm::dft::utility::FDEPConflictFinder<ValueType>::getDependencyConflicts(*dft, useSMT, solverTimeout); |
|
|
|
|
|
|
|
if (preResults.fdepConflicts.empty()) { |
|
|
|
STORM_LOG_DEBUG("No FDEP conflicts found" << std::endl); |
|
|
|
STORM_LOG_DEBUG("No FDEP conflicts found"); |
|
|
|
} else { |
|
|
|
STORM_LOG_DEBUG("========================================" << std::endl << |
|
|
|
"FDEP CONFLICTS" << std::endl << |
|
|
|
"========================================" |
|
|
|
<< std::endl); |
|
|
|
STORM_LOG_DEBUG("========================================" << std::endl << "FDEP CONFLICTS" << std::endl << "========================================"); |
|
|
|
} |
|
|
|
for (auto pair: preResults.fdepConflicts) { |
|
|
|
STORM_LOG_DEBUG("Conflict between " << dft->getElement(pair.first)->name() << " and " |
|
|
|
<< dft->getElement(pair.second)->name() << std::endl); |
|
|
|
STORM_LOG_DEBUG("Conflict between " << dft->getElement(pair.first)->name() << " and " << dft->getElement(pair.second)->name()); |
|
|
|
} |
|
|
|
|
|
|
|
// Set the conflict map of the dft
|
|
|
@ -140,16 +127,16 @@ void processOptions() { |
|
|
|
|
|
|
|
|
|
|
|
#ifdef STORM_HAVE_Z3
|
|
|
|
if (faultTreeSettings.solveWithSMT()) { |
|
|
|
if (useSMT) { |
|
|
|
// Solve with SMT
|
|
|
|
STORM_LOG_DEBUG("Running DFT analysis with use of SMT" << std::endl); |
|
|
|
STORM_LOG_DEBUG("Running DFT analysis with use of SMT"); |
|
|
|
// Set dynamic behavior vector
|
|
|
|
storm::api::analyzeDFTSMT(*dft, true); |
|
|
|
} |
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
// From now on we analyse DFT via model checking
|
|
|
|
// From now on we analyse the DFT via model checking
|
|
|
|
|
|
|
|
// Set min or max
|
|
|
|
std::string optimizationDirection = "min"; |
|
|
@ -256,10 +243,8 @@ void processOptions() { |
|
|
|
approximationError = faultTreeSettings.getApproximationError(); |
|
|
|
} |
|
|
|
storm::api::analyzeDFT<ValueType>(*dft, props, faultTreeSettings.useSymmetryReduction(), faultTreeSettings.useModularisation(), relevantEvents, |
|
|
|
faultTreeSettings.isAllowDCForRelevantEvents(), approximationError, |
|
|
|
faultTreeSettings.getApproximationHeuristic(), |
|
|
|
transformationSettings.isChainEliminationSet(), |
|
|
|
transformationSettings.isIgnoreLabelingSet(), true); |
|
|
|
faultTreeSettings.isAllowDCForRelevantEvents(), approximationError, faultTreeSettings.getApproximationHeuristic(), |
|
|
|
transformationSettings.isChainEliminationSet(), transformationSettings.isIgnoreLabelingSet(), true); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|