Storm 1.11.1.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
TestBdd.cpp
Go to the documentation of this file.
1#include "storm-config.h"
2#include "test/storm_gtest.h"
3
10
11namespace {
12
13struct SftTestData {
14 std::string testname;
15 std::string filepath;
16 std::string bddHash;
17 double probabilityAtTimeboundOne;
18 double mttf;
19 std::vector<double> birnbaum;
20 std::vector<double> CIF;
21 std::vector<double> DIF;
22 std::vector<double> RAW;
23 std::vector<double> RRW;
24
25 friend std::ostream &operator<<(std::ostream &os, SftTestData const &data) {
26 auto printVector = [&os](std::vector<double> const &arr) {
27 os << ", {";
28 for (auto const &i : arr) {
29 os << i;
30 // will leave trailing ", " but its simpler
31 // and would still be a valid initializer
32 os << ", ";
33 }
34 os << '}';
35 };
36
37 os << "{\"" << data.testname << '"';
38 os << ", \"" << data.filepath << '"';
39 os << ", \"" << data.bddHash << '"';
40 os << ", " << data.probabilityAtTimeboundOne;
41 os << ", " << data.mttf;
42 printVector(data.birnbaum);
43 printVector(data.CIF);
44 printVector(data.DIF);
45 printVector(data.RAW);
46 printVector(data.RRW);
47 os << '}';
48 return os;
49 }
50};
51
52class SftBddTest : public testing::TestWithParam<SftTestData> {
53 protected:
54 void SetUp() override {
55#ifdef STORM_HAVE_SYLVAN
56 auto const &param{TestWithParam::GetParam()};
57 auto dft{storm::dft::api::loadDFTGalileoFile<double>(param.filepath)};
58 checker = std::make_shared<storm::dft::modelchecker::SFTBDDChecker>(dft);
59#else
60 GTEST_SKIP() << "Library Sylvan not available.";
61#endif
62 }
63
64 std::shared_ptr<storm::dft::modelchecker::SFTBDDChecker> checker;
65};
66
67TEST_P(SftBddTest, bddHash) {
68#ifdef STORM_HAVE_SYLVAN
69 auto const &param{TestWithParam::GetParam()};
70 EXPECT_EQ(checker->getTransformator()->transformTopLevel().GetShaHash(), param.bddHash);
71#else
72 GTEST_SKIP() << "Library Sylvan not available.";
73#endif
74}
75
76TEST_P(SftBddTest, ProbabilityAtTimeOne) {
77 auto const &param{TestWithParam::GetParam()};
78 EXPECT_NEAR(checker->getProbabilityAtTimebound(1), param.probabilityAtTimeboundOne, 1e-6);
79}
80
81TEST_P(SftBddTest, MTTF) {
82 auto const &param{TestWithParam::GetParam()};
83 EXPECT_NEAR(storm::dft::utility::MTTFHelperProceeding(checker->getDFT()), param.mttf, 1e-5);
84 EXPECT_NEAR(storm::dft::utility::MTTFHelperVariableChange(checker->getDFT()), param.mttf, 1e-5);
85}
86
87template<typename T1, typename T2>
88void expectVectorNear(T1 const &v1, T2 const &v2, double const precision = 1e-6) {
89 ASSERT_EQ(v1.size(), v2.size());
90 for (size_t i{0}; i < v1.size(); ++i) {
91 if (!std::isinf(v1[i])) {
92 EXPECT_NEAR(v1[i], v2[i], precision);
93 } else {
94 EXPECT_EQ(v1[i], v2[i]);
95 }
96 }
97}
98
99TEST_P(SftBddTest, Birnbaum) {
100 auto const &param{TestWithParam::GetParam()};
101 expectVectorNear(checker->getAllBirnbaumFactorsAtTimebound(1), param.birnbaum);
102}
103
104TEST_P(SftBddTest, CIF) {
105 auto const &param{TestWithParam::GetParam()};
106 expectVectorNear(checker->getAllCIFsAtTimebound(1), param.CIF);
107}
108
109TEST_P(SftBddTest, DIF) {
110 auto const &param{TestWithParam::GetParam()};
111 expectVectorNear(checker->getAllDIFsAtTimebound(1), param.DIF);
112}
113
114TEST_P(SftBddTest, RAW) {
115 auto const &param{TestWithParam::GetParam()};
116 expectVectorNear(checker->getAllRAWsAtTimebound(1), param.RAW);
117}
118
119TEST_P(SftBddTest, RRW) {
120 auto const &param{TestWithParam::GetParam()};
121 expectVectorNear(checker->getAllRRWsAtTimebound(1), param.RRW);
122}
123
124static std::vector<SftTestData> sftTestData{
125 {
126 "And",
127 STORM_TEST_RESOURCES_DIR "/dft/bdd/AndTest.dft",
128 "07251c962e40a962c342b8673fd18b45a1461ebd917f83f6720aa106cf277f9f",
129 0.25,
130 2.164042561,
131 {0.5, 0.5},
132 {1, 1},
133 {1, 1},
134 {2, 2},
135 {INFINITY, INFINITY},
136 },
137 {
138 "Or",
139 STORM_TEST_RESOURCES_DIR "/dft/bdd/OrTest.dft",
140 "c5cf2304417926961c3e1ce1d876fc2886ece1365fd946bfd3e1abd71401696d",
141 0.75,
142 0.7213475204,
143 {0.5, 0.5},
144 {0.3333333333, 0.3333333333},
145 {0.666667, 0.666667},
146 {1.333333333, 1.333333333},
147 {1.5, 1.5},
148 },
149 {
150 "AndOr",
151 STORM_TEST_RESOURCES_DIR "/dft/bdd/AndOrTest.dft",
152 "fc1e9a418e3c207e81ffa7fde7768f027b6996732c4216c1ed5de6861dbc86ae",
153 0.5625,
154 1.082021281,
155 {0.375, 0.375, 0.375, 0.375},
156 {0.3333333333, 0.3333333333, 0.3333333333, 0.3333333333},
157 {0.666667, 0.666667, 0.666667, 0.666667},
158 {1.333333333, 1.333333333, 1.333333333, 1.333333333},
159 {1.5, 1.5, 1.5, 1.5},
160 },
161 {
162 "Vot",
163 STORM_TEST_RESOURCES_DIR "/dft/bdd/VotTest.dft",
164 "c005a8d6ad70cc497e1efa3733b0dc52e94c465572d3f1fc5de4983ddd178094",
165 0.6875,
166 0.8415721072,
167 {0.375, 0.375, 0.375, 0.375},
168 {0.27272727, 0.27272727, 0.27272727, 0.27272727},
169 {0.636364, 0.636364, 0.636364, 0.636364},
170 {1.27272727, 1.27272727, 1.27272727, 1.27272727},
171 {1.375, 1.375, 1.375, 1.375},
172 },
173 {
174 "Importance",
175 STORM_TEST_RESOURCES_DIR "/dft/bdd/ImportanceTest.dft",
176 "38221c1eb557dd6f15cf33faf61e18c4e426fab2fb909c56ac0d5f4ff0be499f",
177 0.2655055433,
178 1.977074913,
179 {0.531011, 0.368041, 0.224763, 0.0596235, 0.0543206, 0.0810368, 0},
180 {1, 0.693094, 0.153453, 0.112283, 0.09231, 0.192934, 0},
181 {1, 0.846547, 0.306906, 0.556142, 0.501849, 0.703097, 0.5},
182 {2, 1.693094106, 1.693094106, 1.112283035, 1.112283035, 1.112283035, 1},
183 {INFINITY, 3.25832778, 1.18127, 1.126485175, 1.1016977, 1.23905588, 1},
184 },
185};
186INSTANTIATE_TEST_SUITE_P(SFTs, SftBddTest, testing::ValuesIn(sftTestData), [](auto const &info) { return info.param.testname; });
187
188TEST(TestBdd, AndOrRelevantEvents) {
189#ifdef STORM_HAVE_SYLVAN
190 auto dft = storm::dft::api::loadDFTGalileoFile<double>(STORM_TEST_RESOURCES_DIR "/dft/bdd/AndOrTest.dft");
191 auto manager = std::make_shared<storm::dft::storage::SylvanBddManager>();
192 storm::dft::utility::RelevantEvents relevantEvents{"F", "F1", "F2", "x1"};
194
195 auto const result = transformer.transformRelevantEvents();
196
197 EXPECT_EQ(result.size(), 4ul);
198
199 EXPECT_EQ(result.at("F").GetShaHash(), "fc1e9a418e3c207e81ffa7fde7768f027b6996732c4216c1ed5de6861dbc86ae");
200 EXPECT_EQ(result.at("F1").GetShaHash(), "c5cf2304417926961c3e1ce1d876fc2886ece1365fd946bfd3e1abd71401696d");
201 EXPECT_EQ(result.at("F2").GetShaHash(), "a4f129fa27c6cd32625b088811d4b12f8059ae0547ee035c083deed9ef9d2c59");
202 EXPECT_EQ(result.at("x1").GetShaHash(), "b0d991484e405a391b6d3d241fed9c00d4a2e5bf6f57300512394d819253893d");
203#else
204 GTEST_SKIP() << "Library Sylvan not available.";
205#endif
206}
207
208TEST(TestBdd, AndOrRelevantEventsChecked) {
209#ifdef STORM_HAVE_SYLVAN
210 auto dft = storm::dft::api::loadDFTGalileoFile<double>(STORM_TEST_RESOURCES_DIR "/dft/bdd/AndOrTest.dft");
211 auto manager{std::make_shared<storm::dft::storage::SylvanBddManager>()};
212 storm::dft::utility::RelevantEvents relevantEvents{"F", "F1", "F2", "x1"};
213 auto transformator{std::make_shared<storm::dft::transformations::SftToBddTransformator<double>>(dft, manager, relevantEvents)};
214
215 storm::dft::modelchecker::SFTBDDChecker checker{transformator};
216
217 auto relevantEventsBdds = transformator->transformRelevantEvents();
218
219 EXPECT_NEAR(checker.getProbabilityAtTimebound(relevantEventsBdds["F"], 1), 0.5625, 1e-6);
220
221 EXPECT_NEAR(checker.getProbabilityAtTimebound(relevantEventsBdds["F1"], 1), 0.75, 1e-6);
222 EXPECT_NEAR(checker.getProbabilityAtTimebound(relevantEventsBdds["F2"], 1), 0.75, 1e-6);
223
224 EXPECT_NEAR(checker.getProbabilityAtTimebound(relevantEventsBdds["x1"], 1), 0.5, 1e-6);
225#else
226 GTEST_SKIP() << "Library Sylvan not available.";
227#endif
228}
229
230TEST(TestBdd, AndOrFormulaFail) {
231#ifdef STORM_HAVE_SYLVAN
232 auto dft = storm::dft::api::loadDFTGalileoFile<double>(STORM_TEST_RESOURCES_DIR "/dft/bdd/AndOrTest.dft");
233 auto const props{storm::api::extractFormulasFromProperties(storm::api::parseProperties("P=? [F < 1 !\"F2_failed\"];"))};
235
236 STORM_SILENT_EXPECT_THROW(checker.check(), storm::exceptions::NotSupportedException);
237#else
238 GTEST_SKIP() << "Library Sylvan not available.";
239#endif
240}
241
242TEST(TestBdd, AndOrFormula) {
243#ifdef STORM_HAVE_SYLVAN
244 auto dft = storm::dft::api::loadDFTGalileoFile<double>(STORM_TEST_RESOURCES_DIR "/dft/bdd/AndOrTest.dft");
245 auto const props{
247 "P=? [F <= 1 \"F_failed\"];"
248 "P=? [F <= 1 \"F1_failed\" & \"F2_failed\"];"
249 "P=? [F = 1 !\"failed\"];"
250 "P=? [F = 1 !\"F1_failed\"];"
251 "P=? [F = 1 !\"F2_failed\"];"
252 "P=? [F <= 1 \"F1_failed\"];"
253 "P=? [F <= 1 \"F2_failed\"];"))};
255
256 auto const resultProbs{checker.check()};
257 auto const result{checker.formulasToBdd()};
258
259 EXPECT_EQ(result.size(), 8ul);
260
261 EXPECT_EQ(resultProbs[0], resultProbs[1]);
262 EXPECT_EQ(resultProbs[1], resultProbs[2]);
263 EXPECT_NEAR(resultProbs[0], 0.5625, 1e-6);
264
265 EXPECT_NEAR(resultProbs[3], 1 - resultProbs[0], 1e-6);
266
267 EXPECT_EQ(resultProbs[6], resultProbs[7]);
268 EXPECT_NEAR(resultProbs[6], 0.75, 1e-6);
269
270 EXPECT_EQ(resultProbs[4], resultProbs[5]);
271 EXPECT_NEAR(resultProbs[4], 1 - resultProbs[6], 1e-6);
272
273 EXPECT_EQ(result[0], result[1]);
274 EXPECT_EQ(result[1], result[2]);
275 EXPECT_EQ(result[2], result[0]);
276
277 EXPECT_EQ(result[0].GetBDD(), result[1].GetBDD());
278 EXPECT_EQ(result[1].GetBDD(), result[2].GetBDD());
279 EXPECT_EQ(result[2].GetBDD(), result[0].GetBDD());
280
281 EXPECT_EQ(result[0].GetBDD(), (!result[3]).GetBDD());
282 EXPECT_NE(result[0].GetBDD(), result[3].GetBDD());
283
284 EXPECT_EQ(result[6].GetBDD(), (!result[4]).GetBDD());
285 EXPECT_NE(result[6].GetBDD(), result[4].GetBDD());
286
287 EXPECT_EQ(result[7].GetBDD(), (!result[5]).GetBDD());
288 EXPECT_NE(result[7].GetBDD(), result[5].GetBDD());
289
290 EXPECT_NE(result[3].GetBDD(), result[4].GetBDD());
291
292 EXPECT_EQ(result[0].GetShaHash(), "fc1e9a418e3c207e81ffa7fde7768f027b6996732c4216c1ed5de6861dbc86ae");
293 EXPECT_EQ(result[1].GetShaHash(), "fc1e9a418e3c207e81ffa7fde7768f027b6996732c4216c1ed5de6861dbc86ae");
294 EXPECT_EQ(result[2].GetShaHash(), "fc1e9a418e3c207e81ffa7fde7768f027b6996732c4216c1ed5de6861dbc86ae");
295 EXPECT_EQ(result[3].GetShaHash(), "fc1e9a418e3c207e81ffa7fde7768f027b6996732c4216c1ed5de6861dbc86ae");
296 EXPECT_EQ(result[4].GetShaHash(), "c5cf2304417926961c3e1ce1d876fc2886ece1365fd946bfd3e1abd71401696d");
297 EXPECT_EQ(result[5].GetShaHash(), "a4f129fa27c6cd32625b088811d4b12f8059ae0547ee035c083deed9ef9d2c59");
298 EXPECT_EQ(result[6].GetShaHash(), "c5cf2304417926961c3e1ce1d876fc2886ece1365fd946bfd3e1abd71401696d");
299 EXPECT_EQ(result[7].GetShaHash(), "a4f129fa27c6cd32625b088811d4b12f8059ae0547ee035c083deed9ef9d2c59");
300#else
301 GTEST_SKIP() << "Library Sylvan not available.";
302#endif
303}
304
305} // namespace
TEST(OrderTest, Simple)
Definition OrderTest.cpp:15
std::vector< ValueType > check(size_t const chunksize=0)
Calculate the properties specified by the formulas.
Main class for the SFTBDDChecker.
std::vector< storm::jani::Property > parseProperties(storm::parser::FormulaParser &formulaParser, std::string const &inputString, boost::optional< std::set< std::string > > const &propertyFilter)
std::vector< std::shared_ptr< storm::logic::Formula const > > extractFormulasFromProperties(std::vector< storm::jani::Property > const &properties)
std::ostream & operator<<(std::ostream &out, Counterexample const &counterexample)
double MTTFHelperVariableChange(std::shared_ptr< storm::dft::storage::DFT< double > > const dft, double const stepsize)
Tries to numerically approximate the mttf of the given dft by integrating 1 - cdf(dft) by changing th...
double MTTFHelperProceeding(std::shared_ptr< storm::dft::storage::DFT< double > > const dft, double const stepsize, double const precision)
Tries to numerically approximate the mttf of the given dft by integrating 1 - cdf(dft) with Simpson's...
SettingsManager const & manager()
Retrieves the settings manager.
#define STORM_SILENT_EXPECT_THROW(statement, expected_exception)
Definition storm_gtest.h:31