You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
274 lines
11 KiB
274 lines
11 KiB
#include "gtest/gtest.h"
|
|
#include "storm-config.h"
|
|
|
|
#include "storm-dft/api/storm-dft.h"
|
|
#include "storm-dft/transformations/DftTransformator.h"
|
|
#include "storm-parsers/api/storm-parsers.h"
|
|
|
|
namespace {
|
|
|
|
// Configurations for DFT analysis
|
|
struct DftAnalysisConfig {
|
|
bool useSR;
|
|
bool useMod;
|
|
bool useDC;
|
|
bool allowDCForRelevantEvents;
|
|
};
|
|
|
|
class NoOptimizationsConfig {
|
|
public:
|
|
typedef double ValueType;
|
|
|
|
static DftAnalysisConfig createConfig() {
|
|
return DftAnalysisConfig{false, false, false, true};
|
|
}
|
|
};
|
|
|
|
class DontCareConfig {
|
|
public:
|
|
typedef double ValueType;
|
|
|
|
static DftAnalysisConfig createConfig() {
|
|
return DftAnalysisConfig{false, false, true, true};
|
|
}
|
|
};
|
|
|
|
class ModularisationConfig {
|
|
public:
|
|
typedef double ValueType;
|
|
|
|
static DftAnalysisConfig createConfig() {
|
|
return DftAnalysisConfig{false, true, false, true};
|
|
}
|
|
};
|
|
|
|
class SymmetryReductionConfig {
|
|
public:
|
|
typedef double ValueType;
|
|
|
|
static DftAnalysisConfig createConfig() {
|
|
return DftAnalysisConfig{true, false, false, true};
|
|
}
|
|
};
|
|
|
|
class AllOptimizationsConfig {
|
|
public:
|
|
typedef double ValueType;
|
|
|
|
static DftAnalysisConfig createConfig() {
|
|
return DftAnalysisConfig{true, true, true, true};
|
|
}
|
|
};
|
|
|
|
// General base class for testing of DFT model checking
|
|
template<typename TestType>
|
|
class DftModelCheckerTest : public ::testing::Test {
|
|
public:
|
|
typedef typename TestType::ValueType ValueType;
|
|
|
|
DftModelCheckerTest() : config(TestType::createConfig()) {
|
|
}
|
|
|
|
DftAnalysisConfig const& getConfig() const {
|
|
return config;
|
|
}
|
|
|
|
double analyzeMTTF(std::string const& file) {
|
|
storm::transformations::dft::DftTransformator<double> dftTransformator = storm::transformations::dft::DftTransformator<double>();
|
|
std::shared_ptr<storm::storage::DFT<double>> dft = dftTransformator.transformBinaryFDEPs(
|
|
*(storm::api::loadDFTGalileoFile<double>(file)));
|
|
EXPECT_TRUE(storm::api::isWellFormed(*dft).first);
|
|
std::string property = "Tmin=? [F \"failed\"]";
|
|
std::vector<std::shared_ptr<storm::logic::Formula const>> properties = storm::api::extractFormulasFromProperties(storm::api::parseProperties(property));
|
|
std::set<size_t> relevantEvents;
|
|
if (!config.useDC) {
|
|
relevantEvents = dft->getAllIds();
|
|
}
|
|
typename storm::modelchecker::DFTModelChecker<double>::dft_results results = storm::api::analyzeDFT<double>(*dft, properties, config.useSR, config.useMod,
|
|
relevantEvents, config.allowDCForRelevantEvents);
|
|
return boost::get<double>(results[0]);
|
|
}
|
|
|
|
double analyzeReliability(std::string const &file, double bound) {
|
|
storm::transformations::dft::DftTransformator<double> dftTransformator = storm::transformations::dft::DftTransformator<double>();
|
|
std::shared_ptr<storm::storage::DFT<double>> dft = dftTransformator.transformBinaryFDEPs(*(storm::api::loadDFTGalileoFile<double>(file)));
|
|
EXPECT_TRUE(storm::api::isWellFormed(*dft).first);
|
|
std::string property = "Pmin=? [F<=" + std::to_string(bound) + " \"failed\"]";
|
|
std::vector<std::shared_ptr<storm::logic::Formula const>> properties = storm::api::extractFormulasFromProperties(
|
|
storm::api::parseProperties(property));
|
|
std::set<size_t> relevantEvents;
|
|
if (!config.useDC) {
|
|
relevantEvents = dft->getAllIds();
|
|
}
|
|
typename storm::modelchecker::DFTModelChecker<double>::dft_results results = storm::api::analyzeDFT<double>(*dft, properties, config.useSR, config.useMod,
|
|
relevantEvents, config.allowDCForRelevantEvents);
|
|
return boost::get<double>(results[0]);
|
|
}
|
|
|
|
private:
|
|
DftAnalysisConfig config;
|
|
};
|
|
|
|
typedef ::testing::Types<
|
|
NoOptimizationsConfig,
|
|
DontCareConfig,
|
|
ModularisationConfig,
|
|
SymmetryReductionConfig,
|
|
AllOptimizationsConfig
|
|
> TestingTypes;
|
|
|
|
TYPED_TEST_CASE(DftModelCheckerTest, TestingTypes);
|
|
|
|
TYPED_TEST(DftModelCheckerTest, AndMTTF) {
|
|
double result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/and.dft");
|
|
EXPECT_FLOAT_EQ(result, 3);
|
|
}
|
|
|
|
TYPED_TEST(DftModelCheckerTest, OrMTTF) {
|
|
double result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/or.dft");
|
|
EXPECT_FLOAT_EQ(result, 1);
|
|
}
|
|
|
|
TYPED_TEST(DftModelCheckerTest, VotingMTTF) {
|
|
double result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/voting.dft");
|
|
EXPECT_FLOAT_EQ(result, 5 / 3.0);
|
|
result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/voting2.dft");
|
|
EXPECT_FLOAT_EQ(result, 10 / 17.0);
|
|
result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/voting3.dft");
|
|
EXPECT_FLOAT_EQ(result, 1.7356173);
|
|
result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/voting4.dft");
|
|
EXPECT_FLOAT_EQ(result, 5 / 6.0);
|
|
}
|
|
|
|
TYPED_TEST(DftModelCheckerTest, PandMTTF) {
|
|
double result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/pand.dft");
|
|
EXPECT_EQ(result, storm::utility::infinity<double>());
|
|
}
|
|
|
|
TYPED_TEST(DftModelCheckerTest, PorMTTF) {
|
|
double result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/por.dft");
|
|
EXPECT_EQ(result, storm::utility::infinity<double>());
|
|
}
|
|
|
|
TYPED_TEST(DftModelCheckerTest, FdepMTTF) {
|
|
if (this->getConfig().useMod) {
|
|
EXPECT_THROW(this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/fdep.dft"), storm::exceptions::NotSupportedException);
|
|
EXPECT_THROW(this->
|
|
analyzeMTTF(STORM_TEST_RESOURCES_DIR
|
|
"/dft/fdep2.dft"), storm::exceptions::NotSupportedException);
|
|
EXPECT_THROW(this->
|
|
analyzeMTTF(STORM_TEST_RESOURCES_DIR
|
|
"/dft/fdep3.dft"), storm::exceptions::NotSupportedException);
|
|
EXPECT_THROW(this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/fdep4.dft"), storm::exceptions::NotSupportedException);
|
|
EXPECT_THROW(this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/fdep5.dft"), storm::exceptions::NotSupportedException);
|
|
} else {
|
|
double result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR
|
|
"/dft/fdep.dft");
|
|
EXPECT_FLOAT_EQ(result, 2 / 3.0);
|
|
result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR
|
|
"/dft/fdep2.dft");
|
|
EXPECT_FLOAT_EQ(result,
|
|
2);
|
|
result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR
|
|
"/dft/fdep3.dft");
|
|
EXPECT_FLOAT_EQ(result,
|
|
2.5);
|
|
result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/fdep4.dft");
|
|
EXPECT_FLOAT_EQ(result, 1);
|
|
result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/fdep5.dft");
|
|
EXPECT_FLOAT_EQ(result, 3);
|
|
}
|
|
}
|
|
|
|
TYPED_TEST(DftModelCheckerTest, PdepMTTF) {
|
|
double result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/pdep.dft");
|
|
EXPECT_FLOAT_EQ(result, 8 / 3.0);
|
|
|
|
if (this->getConfig().useMod) {
|
|
EXPECT_THROW(this->
|
|
analyzeMTTF(STORM_TEST_RESOURCES_DIR
|
|
"/dft/pdep2.dft"), storm::exceptions::NotSupportedException);
|
|
EXPECT_THROW(this->
|
|
analyzeMTTF(STORM_TEST_RESOURCES_DIR
|
|
"/dft/pdep3.dft"), storm::exceptions::NotSupportedException);
|
|
EXPECT_THROW(this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/pdep4.dft"), storm::exceptions::NotSupportedException);
|
|
} else {
|
|
result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR
|
|
"/dft/pdep2.dft");
|
|
EXPECT_FLOAT_EQ(result,
|
|
38 / 15.0);
|
|
result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR
|
|
"/dft/pdep3.dft");
|
|
EXPECT_FLOAT_EQ(result,
|
|
67 / 24.0);
|
|
result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/pdep4.dft");
|
|
EXPECT_EQ(result, storm::utility::infinity<double>());
|
|
}
|
|
}
|
|
|
|
TYPED_TEST(DftModelCheckerTest, SpareMTTF) {
|
|
double result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/spare.dft");
|
|
EXPECT_FLOAT_EQ(result, 46 / 13.0);
|
|
result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/spare2.dft");
|
|
EXPECT_FLOAT_EQ(result, 43 / 23.0);
|
|
result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/spare3.dft");
|
|
EXPECT_FLOAT_EQ(result, 14 / 11.0);
|
|
result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/spare4.dft");
|
|
EXPECT_FLOAT_EQ(result, 4.8458967);
|
|
result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/spare5.dft");
|
|
EXPECT_FLOAT_EQ(result, 8 / 3.0);
|
|
result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/spare6.dft");
|
|
EXPECT_FLOAT_EQ(result, 1.4);
|
|
result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/spare7.dft");
|
|
EXPECT_FLOAT_EQ(result, 3.6733334);
|
|
result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/spare8.dft");
|
|
EXPECT_FLOAT_EQ(result, 4.78846); // DFTCalc has result of 4.33779 due to different semantics of nested spares
|
|
}
|
|
|
|
TYPED_TEST(DftModelCheckerTest, SeqMTTF) {
|
|
double result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/seq.dft");
|
|
EXPECT_FLOAT_EQ(result, 4);
|
|
result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/seq2.dft");
|
|
EXPECT_FLOAT_EQ(result, 6);
|
|
result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/seq3.dft");
|
|
EXPECT_FLOAT_EQ(result, 6);
|
|
result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/seq4.dft");
|
|
EXPECT_FLOAT_EQ(result, 6);
|
|
result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/seq5.dft");
|
|
EXPECT_EQ(result, storm::utility::infinity<double>());
|
|
|
|
result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/mutex.dft");
|
|
EXPECT_FLOAT_EQ(result, 0.5);
|
|
result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/mutex2.dft");
|
|
EXPECT_FLOAT_EQ(result, storm::utility::infinity<double>());
|
|
result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/mutex3.dft");
|
|
EXPECT_FLOAT_EQ(result, storm::utility::infinity<double>());
|
|
if (this->
|
|
|
|
getConfig()
|
|
|
|
.useMod){
|
|
EXPECT_THROW(this->
|
|
analyzeMTTF(STORM_TEST_RESOURCES_DIR
|
|
"/dft/seq6.dft"), storm::exceptions::NotSupportedException);
|
|
}
|
|
else {
|
|
result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR
|
|
"/dft/seq6.dft");
|
|
EXPECT_FLOAT_EQ(result,
|
|
30000);
|
|
}
|
|
}
|
|
|
|
TYPED_TEST(DftModelCheckerTest, Symmetry) {
|
|
double result = this->analyzeMTTF(STORM_TEST_RESOURCES_DIR "/dft/symmetry6.dft");
|
|
EXPECT_FLOAT_EQ(result, 1.373226284);
|
|
result = this->analyzeReliability(STORM_TEST_RESOURCES_DIR "/dft/symmetry6.dft", 1.0);
|
|
EXPECT_FLOAT_EQ(result, 0.3421934224);
|
|
}
|
|
|
|
TYPED_TEST(DftModelCheckerTest, HecsReliability) {
|
|
double result = this->analyzeReliability(STORM_TEST_RESOURCES_DIR "/dft/hecs_2_2.dft", 1.0);
|
|
EXPECT_FLOAT_EQ(result, 0.00021997582);
|
|
}
|
|
}
|