Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions src/storm-dft-cli/storm-dft.cpp
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
#include "storm-dft/api/storm-dft.h"
#include "storm-cli-utilities/cli.h"
#include "storm-dft/api/analysis.h"
#include "storm-dft/api/gspn_transformation.h"
#include "storm-dft/api/io.h"
#include "storm-dft/api/transformation.h"
#include "storm-dft/parser/BEOrderParser.h"
#include "storm-dft/settings/DftSettings.h"
#include "storm-dft/settings/modules/DftGspnSettings.h"
#include "storm-dft/settings/modules/DftIOSettings.h"
#include "storm-dft/settings/modules/FaultTreeSettings.h"
#include "storm-parsers/api/storm-parsers.h"
#include "storm/adapters/IntervalAdapter.h"
#include "storm-gspn/api/storm-gspn.h"
#include "storm-parsers/api/properties.h"
#include "storm/adapters/RationalFunctionAdapter.h"
#include "storm/adapters/RationalNumberAdapter.h"
#include "storm/api/properties.h"
#include "storm/exceptions/UnmetRequirementException.h"
#include "storm/settings/modules/GeneralSettings.h"
#include "storm/settings/modules/IOSettings.h"
Expand Down
154 changes: 65 additions & 89 deletions src/storm-dft/api/storm-dft.cpp → src/storm-dft/api/analysis.cpp
Original file line number Diff line number Diff line change
@@ -1,26 +1,46 @@
#include "storm-dft/api/storm-dft.h"
#include "analysis.h"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wrong naming scheme? Or is this the new naming scheme?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be honest, I thought this was the new naming scheme. But I am not sure whether we agreed on it.


#include <memory>
#include <vector>

#include "storm-conv/api/storm-conv.h"
#include "storm-conv/settings/modules/JaniExportSettings.h"
#include "storm-dft/adapters/SFTBDDPropertyFormulaAdapter.h"
#include "storm-dft/modelchecker/DftModularizationChecker.h"
#include "storm-dft/modelchecker/SFTBDDChecker.h"
#include "storm-dft/settings/modules/DftGspnSettings.h"
#include "storm-dft/settings/modules/FaultTreeSettings.h"
#include "storm-dft/storage/DFT.h"
#include "storm-dft/storage/DftJsonExporter.h"
#include "storm-dft/storage/SylvanBddManager.h"
#include "storm-dft/transformations/SftToBddTransformator.h"
#include "storm-dft/utility/FDEPConflictFinder.h"
#include "storm-dft/utility/FailureBoundFinder.h"
#include "storm-dft/utility/MTTFHelper.h"

#include "storm/environment/Environment.h"
#include "storm/adapters/RationalFunctionAdapter.h"

namespace storm::dft {
namespace api {

storm::dft::utility::RelevantEvents computeRelevantEvents(std::vector<std::shared_ptr<storm::logic::Formula const>> const& properties,
std::vector<std::string> const& additionalRelevantEventNames) {
storm::dft::utility::RelevantEvents events(additionalRelevantEventNames.begin(), additionalRelevantEventNames.end());
events.insertNamesFromProperties(properties.begin(), properties.end());
return events;
}

template<typename ValueType>
typename storm::dft::modelchecker::DFTModelChecker<ValueType>::dft_results analyzeDFT(
storm::dft::storage::DFT<ValueType> const& dft, std::vector<std::shared_ptr<storm::logic::Formula const>> const& properties, bool symred,
bool allowModularisation, storm::dft::utility::RelevantEvents const& relevantEvents, bool allowDCForRelevant, double approximationError,
storm::dft::builder::ApproximationHeuristic approximationHeuristic, bool eliminateChains, storm::transformer::EliminationLabelBehavior labelBehavior,
bool printOutput) {
storm::dft::modelchecker::DFTModelChecker<ValueType> modelChecker(printOutput);
typename storm::dft::modelchecker::DFTModelChecker<ValueType>::dft_results results =
modelChecker.check(dft, properties, symred, allowModularisation, relevantEvents, allowDCForRelevant, approximationError, approximationHeuristic,
eliminateChains, labelBehavior);
if (printOutput) {
modelChecker.printTimings();
modelChecker.printResults(results);
}
return results;
}

template<>
void analyzeDFTBdd(std::shared_ptr<storm::dft::storage::DFT<double>> const& dft, bool const exportToDot, std::string const& filename, bool const calculateMttf,
double const mttfPrecision, double const mttfStepsize, std::string const mttfAlgorithmName, bool const calculateMCS,
Expand Down Expand Up @@ -178,30 +198,6 @@ void analyzeDFTBdd(std::shared_ptr<storm::dft::storage::DFT<storm::RationalFunct
STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "BDD analysis is not supported for this data type.");
}

template<typename ValueType>
void exportDFTToJsonFile(storm::dft::storage::DFT<ValueType> const& dft, std::string const& file) {
storm::dft::storage::DftJsonExporter<ValueType>::toFile(dft, file);
}

template<typename ValueType>
std::string exportDFTToJsonString(storm::dft::storage::DFT<ValueType> const& dft) {
std::stringstream stream;
storm::dft::storage::DftJsonExporter<ValueType>::toStream(dft, stream);
return stream.str();
}

template<>
void exportDFTToSMT(storm::dft::storage::DFT<double> const& dft, std::string const& file) {
storm::dft::modelchecker::DFTASFChecker asfChecker(dft);
asfChecker.convert();
asfChecker.toFile(file);
}

template<>
void exportDFTToSMT(storm::dft::storage::DFT<storm::RationalFunction> const& dft, std::string const& file) {
STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Export to SMT does not support this data type.");
}

template<>
void analyzeDFTSMT(storm::dft::storage::DFT<double> const& dft, bool printOutput) {
uint64_t solverTimeout = 10;
Expand All @@ -219,71 +215,51 @@ void analyzeDFTSMT(storm::dft::storage::DFT<storm::RationalFunction> const& dft,
STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Analysis by SMT not supported for this data type.");
}

template<>
std::pair<std::shared_ptr<storm::gspn::GSPN>, uint64_t> transformToGSPN(storm::dft::storage::DFT<double> const& dft) {
storm::dft::settings::modules::FaultTreeSettings const& ftSettings = storm::settings::getModule<storm::dft::settings::modules::FaultTreeSettings>();
storm::dft::settings::modules::DftGspnSettings const& dftGspnSettings = storm::settings::getModule<storm::dft::settings::modules::DftGspnSettings>();

// Set Don't Care elements
std::set<uint64_t> dontCareElements;
if (!ftSettings.isDisableDC()) {
// Insert all elements as Don't Care elements
for (std::size_t i = 0; i < dft.nrElements(); i++) {
dontCareElements.insert(dft.getElement(i)->id());
}
}

// Transform to GSPN
storm::dft::transformations::DftToGspnTransformator<double> gspnTransformator(dft);
auto priorities = gspnTransformator.computePriorities(dftGspnSettings.isExtendPriorities());
gspnTransformator.transform(priorities, dontCareElements, !dftGspnSettings.isDisableSmartTransformation(), dftGspnSettings.isMergeDCFailed(),
dftGspnSettings.isExtendPriorities());
std::shared_ptr<storm::gspn::GSPN> gspn(gspnTransformator.obtainGSPN());
return std::make_pair(gspn, gspnTransformator.toplevelFailedPlaceId());
}

template<>
std::pair<std::shared_ptr<storm::gspn::GSPN>, uint64_t> transformToGSPN(storm::dft::storage::DFT<storm::RationalFunction> const& dft) {
STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Transformation to GSPN not supported for this data type.");
template<typename ValueType>
std::pair<uint64_t, uint64_t> computeBEFailureBounds(storm::dft::storage::DFT<ValueType> const& dft, bool useSMT, double solverTimeout) {
uint64_t lowerBEBound = storm::dft::utility::FailureBoundFinder::getLeastFailureBound(dft, useSMT, solverTimeout);
uint64_t upperBEBound = storm::dft::utility::FailureBoundFinder::getAlwaysFailedBound(dft, useSMT, solverTimeout);
return std::make_pair(lowerBEBound, upperBEBound);
}

std::shared_ptr<storm::jani::Model> transformToJani(storm::gspn::GSPN const& gspn, uint64_t toplevelFailedPlace) {
// Build Jani model
storm::builder::JaniGSPNBuilder builder(gspn);
std::shared_ptr<storm::jani::Model> model(builder.build("dft_gspn"));

// Build properties
std::shared_ptr<storm::expressions::ExpressionManager> const& exprManager = gspn.getExpressionManager();
storm::jani::Variable const& topfailedVar = builder.getPlaceVariable(toplevelFailedPlace);
storm::expressions::Expression targetExpression = exprManager->integer(1) == topfailedVar.getExpressionVariable().getExpression();
// Add variable for easier access to 'failed' state
builder.addTransientVariable(model.get(), "failed", targetExpression);
auto failedFormula = std::make_shared<storm::logic::AtomicExpressionFormula>(targetExpression);
auto properties = builder.getStandardProperties(model.get(), failedFormula, "Failed", "a failed state", true);
template<typename ValueType>
bool computeDependencyConflicts(storm::dft::storage::DFT<ValueType>& dft, bool useSMT, double solverTimeout) {
std::vector<std::pair<uint64_t, uint64_t>> fdepConflicts =
storm::dft::utility::FDEPConflictFinder<ValueType>::getDependencyConflicts(dft, useSMT, solverTimeout);

// Export Jani to file
storm::dft::settings::modules::DftGspnSettings const& dftGspnSettings = storm::settings::getModule<storm::dft::settings::modules::DftGspnSettings>();
if (dftGspnSettings.isWriteToJaniSet()) {
auto const& jani = storm::settings::getModule<storm::settings::modules::JaniExportSettings>();
storm::api::exportJaniToFile(*model, properties, dftGspnSettings.getWriteToJaniFilename(), jani.isCompactJsonSet());
for (auto const& pair : fdepConflicts) {
STORM_LOG_DEBUG("Conflict between " << dft.getElement(pair.first)->name() << " and " << dft.getElement(pair.second)->name());
}

return model;
}

storm::dft::utility::RelevantEvents computeRelevantEvents(std::vector<std::shared_ptr<storm::logic::Formula const>> const& properties,
std::vector<std::string> const& additionalRelevantEventNames) {
storm::dft::utility::RelevantEvents events(additionalRelevantEventNames.begin(), additionalRelevantEventNames.end());
events.insertNamesFromProperties(properties.begin(), properties.end());
return events;
// Set the conflict map of the dft
std::set<uint64_t> conflict_set;
for (auto const& conflict : fdepConflicts) {
conflict_set.insert(conflict.first);
conflict_set.insert(conflict.second);
}
for (size_t depId : dft.getDependencies()) {
if (!conflict_set.contains(depId)) {
dft.setDependencyNotInConflict(depId);
}
}
return !fdepConflicts.empty();
}

// Explicitly instantiate methods
template void exportDFTToJsonFile(storm::dft::storage::DFT<double> const&, std::string const&);
template std::string exportDFTToJsonString(storm::dft::storage::DFT<double> const&);

template void exportDFTToJsonFile(storm::dft::storage::DFT<storm::RationalFunction> const&, std::string const&);
template std::string exportDFTToJsonString(storm::dft::storage::DFT<storm::RationalFunction> const&);
template typename storm::dft::modelchecker::DFTModelChecker<double>::dft_results analyzeDFT(storm::dft::storage::DFT<double> const&,
std::vector<std::shared_ptr<storm::logic::Formula const>> const&,
bool, bool, storm::dft::utility::RelevantEvents const&, bool,
double, storm::dft::builder::ApproximationHeuristic, bool,
storm::transformer::EliminationLabelBehavior, bool);
template std::pair<uint64_t, uint64_t> computeBEFailureBounds(storm::dft::storage::DFT<double> const&, bool, double);
template bool computeDependencyConflicts(storm::dft::storage::DFT<double>&, bool, double);

template typename storm::dft::modelchecker::DFTModelChecker<storm::RationalFunction>::dft_results analyzeDFT(
storm::dft::storage::DFT<storm::RationalFunction> const&, std::vector<std::shared_ptr<storm::logic::Formula const>> const&, bool, bool,
storm::dft::utility::RelevantEvents const&, bool, double, storm::dft::builder::ApproximationHeuristic, bool, storm::transformer::EliminationLabelBehavior,
bool);
template std::pair<uint64_t, uint64_t> computeBEFailureBounds(storm::dft::storage::DFT<storm::RationalFunction> const&, bool, double);
template bool computeDependencyConflicts(storm::dft::storage::DFT<storm::RationalFunction>&, bool, double);

} // namespace api
} // namespace storm::dft
94 changes: 94 additions & 0 deletions src/storm-dft/api/analysis.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#pragma once

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "storm-dft/builder/DftExplorationHeuristic.h"
#include "storm-dft/modelchecker/DFTModelChecker.h"
#include "storm-dft/storage/DFT.h"
#include "storm-dft/utility/RelevantEvents.h"
#include "storm/logic/Formula.h"

namespace storm::dft {
namespace api {

/*!
* Get relevant event ids from given relevant event names and labels in properties.
*
* @param properties List of properties. All events occurring in a property are relevant.
* @param additionalRelevantEventNames List of names of additional relevant events.
* @return Relevant events.
*/
storm::dft::utility::RelevantEvents computeRelevantEvents(std::vector<std::shared_ptr<storm::logic::Formula const>> const& properties,
std::vector<std::string> const& additionalRelevantEventNames);

/*!
* Compute the exact or approximate analysis result of the given DFT according to the given properties.
* First the Markov model is built from the DFT and then this model is checked against the given properties.
*
* @param dft DFT.
* @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 relevantEvents Relevant events which should be observed.
* @param allowDCForRelevant Whether to allow Don't Care propagation for relevant events
* @param approximationError Allowed approximation error. Value 0 indicates no approximation.
* @param approximationHeuristic Heuristic used for state space exploration.
* @param eliminateChains If true, chains of non-Markovian states are eliminated from the resulting MA.
* @param labelBehavior Behavior of labels of eliminated states
* @param printOutput If true, model information, timings, results, etc. are printed.
* @return Results.
*/
template<typename ValueType>
typename storm::dft::modelchecker::DFTModelChecker<ValueType>::dft_results analyzeDFT(
storm::dft::storage::DFT<ValueType> const& dft, std::vector<std::shared_ptr<storm::logic::Formula const>> const& properties, bool symred = true,
bool allowModularisation = true, storm::dft::utility::RelevantEvents const& relevantEvents = {}, bool allowDCForRelevant = false,
double approximationError = 0.0, storm::dft::builder::ApproximationHeuristic approximationHeuristic = storm::dft::builder::ApproximationHeuristic::DEPTH,
bool eliminateChains = false, storm::transformer::EliminationLabelBehavior labelBehavior = storm::transformer::EliminationLabelBehavior::KeepLabels,
bool printOutput = false);

/*!
* Analyze the DFT using BDDs
*
* @param dft DFT
* @param exportToDot If true exports the bdd representing the top level event of the dft in the dot format
* @param filename The name of the file for exporting to dot
* @param calculateMttf If true calculates the mean time to failure
* @param mttfPrecision A constant that is used to determine if the mttf calculation converged
* @param mttfStepsize A constant that is used in the mttf calculation
* @param mttfAlgorithmName The name of the mttf algorithm to use
* @param calculateMCS If true calculates the minimal cut sets
* @param calculateProbability If true calculates the system failure probability
* @param useModularisation If true tries modularisation
* @param importanceMeasureName The name of the importance measure to calculate
* @param timepoints The timebounds for probability calculations
* @param properties The bounded until formulas to check (emulating the CTMC method)
* @param additionalRelevantEventNames A vector of relevant events to be considered
* @param chunksize The size of the chunks of doubles to work on at a time
*/
template<typename ValueType>
void analyzeDFTBdd(std::shared_ptr<storm::dft::storage::DFT<ValueType>> const& dft, bool const exportToDot, std::string const& filename,
bool const calculateMttf, double const mttfPrecision, double const mttfStepsize, std::string const mttfAlgorithmName,
bool const calculateMCS, bool const calculateProbability, bool const useModularisation, std::string const importanceMeasureName,
std::vector<double> const& timepoints, std::vector<std::shared_ptr<storm::logic::Formula const>> const& properties,
std::vector<std::string> const& additionalRelevantEventNames, size_t const chunksize);

/*!
* Analyze the DFT using the SMT encoding
*
* @param dft DFT.
* @param printOutput If true, output is printed.
*/
template<typename ValueType>
void analyzeDFTSMT(storm::dft::storage::DFT<ValueType> const& dft, bool printOutput);

template<typename ValueType>
std::pair<uint64_t, uint64_t> computeBEFailureBounds(storm::dft::storage::DFT<ValueType> const& dft, bool useSMT, double solverTimeout);

template<typename ValueType>
bool computeDependencyConflicts(storm::dft::storage::DFT<ValueType>& dft, bool useSMT, double solverTimeout);

} // namespace api
} // namespace storm::dft
Loading
Loading