1#include "storm-config.h"
32enum class CtmcEngine { PrismSparse, JaniSparse, JaniHybrid };
35class GBSparseGmmxxGmresIluEnvironment {
38 static const CtmcEngine engine = CtmcEngine::PrismSparse;
39 static const bool isExact =
false;
48 storm::utility::convertNumber<storm::RationalNumber>(1e-8));
51 storm::utility::convertNumber<storm::RationalNumber>(1e-8));
56class GBJaniSparseGmmxxGmresIluEnvironment {
59 static const CtmcEngine engine = CtmcEngine::JaniSparse;
60 static const bool isExact =
false;
69 storm::utility::convertNumber<storm::RationalNumber>(1e-8));
72 storm::utility::convertNumber<storm::RationalNumber>(1e-8));
77class GBJaniHybridCuddGmmxxGmresEnvironment {
80 static const CtmcEngine engine = CtmcEngine::JaniHybrid;
81 static const bool isExact =
false;
90 storm::utility::convertNumber<storm::RationalNumber>(1e-8));
93 storm::utility::convertNumber<storm::RationalNumber>(1e-8));
98class GBJaniHybridSylvanGmmxxGmresEnvironment {
101 static const CtmcEngine engine = CtmcEngine::JaniHybrid;
102 static const bool isExact =
false;
111 storm::utility::convertNumber<storm::RationalNumber>(1e-8));
114 storm::utility::convertNumber<storm::RationalNumber>(1e-8));
120class GBSparseEigenDGmresEnvironment {
123 static const CtmcEngine engine = CtmcEngine::PrismSparse;
124 static const bool isExact =
false;
137class GBSparseEigenDoubleLUEnvironment {
140 static const CtmcEngine engine = CtmcEngine::PrismSparse;
141 static const bool isExact =
false;
153class GBSparseNativeSorEnvironment {
156 static const CtmcEngine engine = CtmcEngine::PrismSparse;
157 static const bool isExact =
false;
172class DistrSparseGmmxxGmresIluEnvironment {
175 static const CtmcEngine engine = CtmcEngine::PrismSparse;
176 static const bool isExact =
false;
185 storm::utility::convertNumber<storm::RationalNumber>(1e-8));
188 storm::utility::convertNumber<storm::RationalNumber>(1e-8));
194class DistrSparseEigenDoubleLUEnvironment {
197 static const CtmcEngine engine = CtmcEngine::PrismSparse;
198 static const bool isExact =
false;
212class ValueIterationSparseEnvironment {
215 static const CtmcEngine engine = CtmcEngine::PrismSparse;
216 static const bool isExact =
false;
226class SoundEnvironment {
229 static const CtmcEngine engine = CtmcEngine::PrismSparse;
230 static const bool isExact =
false;
240template<
typename TestType>
241class LraCtmcCslModelCheckerTest :
public ::testing::Test {
243 typedef typename TestType::ValueType
ValueType;
247 LraCtmcCslModelCheckerTest() : _environment(TestType::createEnvironment()) {}
249 void SetUp()
override {
251 GTEST_SKIP() <<
"Z3 not available.";
259 return storm::utility::convertNumber<ValueType>(input);
264 bool isSparseModel()
const {
265 return std::is_same<typename TestType::ModelType, SparseModelType>::value;
267 bool isSymbolicModel()
const {
268 return std::is_same<typename TestType::ModelType, SymbolicModelType>::value;
270 CtmcEngine getEngine()
const {
271 return TestType::engine;
274 template<
typename MT =
typename TestType::ModelType>
275 typename std::enable_if<std::is_same<MT, SparseModelType>::value,
276 std::pair<std::shared_ptr<MT>, std::vector<std::shared_ptr<storm::logic::Formula const>>>>::type
277 buildModelFormulas(std::string
const& pathToPrismFile, std::string
const& formulasAsString, std::string
const& constantDefinitionString =
"")
const {
278 std::pair<std::shared_ptr<MT>, std::vector<std::shared_ptr<storm::logic::Formula const>>> result;
281 if (TestType::engine == CtmcEngine::PrismSparse) {
283 result.first = storm::api::buildSparseModel<ValueType>(program, result.second)->template as<MT>();
284 }
else if (TestType::engine == CtmcEngine::JaniSparse) {
286 janiData.first.substituteFunctions();
288 result.first = storm::api::buildSparseModel<ValueType>(janiData.first, result.second)->template as<MT>();
293 template<
typename MT =
typename TestType::ModelType>
294 typename std::enable_if<std::is_same<MT, SymbolicModelType>::value,
295 std::pair<std::shared_ptr<MT>, std::vector<std::shared_ptr<storm::logic::Formula const>>>>::type
296 buildModelFormulas(std::string
const& pathToPrismFile, std::string
const& formulasAsString, std::string
const& constantDefinitionString =
"")
const {
297 std::pair<std::shared_ptr<MT>, std::vector<std::shared_ptr<storm::logic::Formula const>>> result;
300 if (TestType::engine == CtmcEngine::JaniHybrid) {
302 janiData.first.substituteFunctions();
304 result.first = storm::api::buildSymbolicModel<TestType::ddType, ValueType>(janiData.first, result.second)->template as<MT>();
309 std::vector<storm::modelchecker::CheckTask<storm::logic::Formula, ValueType>> getTasks(
310 std::vector<std::shared_ptr<storm::logic::Formula const>>
const& formulas)
const {
311 std::vector<storm::modelchecker::CheckTask<storm::logic::Formula, ValueType>> result;
312 for (
auto const& f : formulas) {
313 result.emplace_back(*f);
318 template<
typename MT =
typename TestType::ModelType>
319 typename std::enable_if<std::is_same<MT, SparseModelType>::value, std::shared_ptr<storm::modelchecker::AbstractModelChecker<MT>>>::type createModelChecker(
320 std::shared_ptr<MT>
const& model)
const {
321 if (TestType::engine == CtmcEngine::PrismSparse || TestType::engine == CtmcEngine::JaniSparse) {
322 return std::make_shared<storm::modelchecker::SparseCtmcCslModelChecker<SparseModelType>>(*model);
327 template<
typename MT =
typename TestType::ModelType>
328 typename std::enable_if<std::is_same<MT, SymbolicModelType>::value, std::shared_ptr<storm::modelchecker::AbstractModelChecker<MT>>>::type
329 createModelChecker(std::shared_ptr<MT>
const& model)
const {
330 if (TestType::engine == CtmcEngine::JaniHybrid) {
331 return std::make_shared<storm::modelchecker::HybridCtmcCslModelChecker<SymbolicModelType>>(*model);
336 template<
typename MT =
typename TestType::ModelType>
337 typename std::enable_if<std::is_same<MT, SparseModelType>::value,
void>::type execute(std::shared_ptr<MT>
const& model,
338 std::function<
void()>
const& f)
const {
342 template<
typename MT =
typename TestType::ModelType>
343 typename std::enable_if<std::is_same<MT, SymbolicModelType>::value,
void>::type execute(std::shared_ptr<MT>
const& model,
344 std::function<
void()>
const& f)
const {
345 model->getManager().execute(f);
349 std::unique_ptr<storm::modelchecker::CheckResult>& result) {
351 result->filter(*filter);
352 return result->asQualitativeCheckResult().forallTrue();
356 std::unique_ptr<storm::modelchecker::CheckResult>& result) {
358 result->filter(*filter);
359 return result->asQuantitativeCheckResult<
ValueType>().getMin();
366 if (isSparseModel()) {
367 return std::make_unique<storm::modelchecker::ExplicitQualitativeCheckResult>(model->template as<SparseModelType>()->getInitialStates());
369 return std::make_unique<storm::modelchecker::SymbolicQualitativeCheckResult<TestType::ddType>>(
370 model->template as<SymbolicModelType>()->getReachableStates(), model->template as<SymbolicModelType>()->getInitialStates());
375typedef ::testing::Types<
377 GBSparseGmmxxGmresIluEnvironment, GBJaniSparseGmmxxGmresIluEnvironment, GBJaniHybridCuddGmmxxGmresEnvironment, GBJaniHybridSylvanGmmxxGmresEnvironment,
378 DistrSparseGmmxxGmresIluEnvironment,
380 GBSparseEigenDGmresEnvironment, GBSparseEigenDoubleLUEnvironment, GBSparseNativeSorEnvironment, DistrSparseEigenDoubleLUEnvironment,
381 ValueIterationSparseEnvironment, SoundEnvironment>
386TYPED_TEST(LraCtmcCslModelCheckerTest, Cluster) {
387 std::string formulasString =
"LRA=? [\"minimum\"]";
389 auto modelFormulas = this->buildModelFormulas(STORM_TEST_RESOURCES_DIR
"/ctmc/cluster2.sm", formulasString);
390 auto model = std::move(modelFormulas.first);
391 auto tasks = this->getTasks(modelFormulas.second);
392 this->execute(model, [&]() {
393 EXPECT_EQ(276ul, model->getNumberOfStates());
394 EXPECT_EQ(1120ul, model->getNumberOfTransitions());
396 auto checker = this->createModelChecker(model);
397 std::unique_ptr<storm::modelchecker::CheckResult> result;
399 result = checker->check(this->env(), tasks[0]);
404TYPED_TEST(LraCtmcCslModelCheckerTest, Embedded) {
405 std::string formulasString =
"LRA=? [\"fail_sensors\"]";
407 auto modelFormulas = this->buildModelFormulas(STORM_TEST_RESOURCES_DIR
"/ctmc/embedded2.sm", formulasString);
408 auto model = std::move(modelFormulas.first);
409 auto tasks = this->getTasks(modelFormulas.second);
410 this->execute(model, [&]() {
411 EXPECT_EQ(3478ul, model->getNumberOfStates());
412 EXPECT_EQ(14639ul, model->getNumberOfTransitions());
414 auto checker = this->createModelChecker(model);
415 std::unique_ptr<storm::modelchecker::CheckResult> result;
417 result = checker->check(this->env(), tasks[0]);
422TYPED_TEST(LraCtmcCslModelCheckerTest, Polling) {
423 std::string formulasString =
"LRA=?[\"target\"]";
425 auto modelFormulas = this->buildModelFormulas(STORM_TEST_RESOURCES_DIR
"/ctmc/polling2.sm", formulasString);
426 auto model = std::move(modelFormulas.first);
427 auto tasks = this->getTasks(modelFormulas.second);
428 this->execute(model, [&]() {
429 EXPECT_EQ(12ul, model->getNumberOfStates());
430 EXPECT_EQ(22ul, model->getNumberOfTransitions());
432 auto checker = this->createModelChecker(model);
433 std::unique_ptr<storm::modelchecker::CheckResult> result;
435 result = checker->check(this->env(), tasks[0]);
440TYPED_TEST(LraCtmcCslModelCheckerTest, Tandem) {
441 std::string formulasString =
"LRA=? [\"first_queue_full\"]";
443 auto modelFormulas = this->buildModelFormulas(STORM_TEST_RESOURCES_DIR
"/ctmc/tandem5.sm", formulasString);
444 auto model = std::move(modelFormulas.first);
445 auto tasks = this->getTasks(modelFormulas.second);
446 this->execute(model, [&]() {
447 EXPECT_EQ(66ul, model->getNumberOfStates());
448 EXPECT_EQ(189ul, model->getNumberOfTransitions());
450 auto checker = this->createModelChecker(model);
451 std::unique_ptr<storm::modelchecker::CheckResult> result;
453 result = checker->check(this->env(), tasks[0]);
458TYPED_TEST(LraCtmcCslModelCheckerTest, Rewards) {
459 std::string formulasString =
"R=? [ LRA ]";
461 auto modelFormulas = this->buildModelFormulas(STORM_TEST_RESOURCES_DIR
"/ctmc/lrarewards.sm", formulasString);
462 auto model = std::move(modelFormulas.first);
463 auto tasks = this->getTasks(modelFormulas.second);
464 this->execute(model, [&]() {
465 EXPECT_EQ(4ul, model->getNumberOfStates());
466 EXPECT_EQ(6ul, model->getNumberOfTransitions());
468 auto checker = this->createModelChecker(model);
469 std::unique_ptr<storm::modelchecker::CheckResult> result;
471 result = checker->check(this->env(), tasks[0]);
476TYPED_TEST(LraCtmcCslModelCheckerTest, kanban) {
477 std::string formulasString =
"R{\"throughput\"}=? [ LRA ]";
479 auto modelFormulas = this->buildModelFormulas(STORM_TEST_RESOURCES_DIR
"/ctmc/kanban.prism", formulasString);
480 auto model = std::move(modelFormulas.first);
481 auto tasks = this->getTasks(modelFormulas.second);
482 this->execute(model, [&]() {
483 EXPECT_EQ(160ul, model->getNumberOfStates());
484 EXPECT_EQ(616ul, model->getNumberOfTransitions());
486 auto checker = this->createModelChecker(model);
487 std::unique_ptr<storm::modelchecker::CheckResult> result;
489 result = checker->check(this->env(), tasks[0]);
491 this->
parseNumber(
"1132372552133951639536770152429724263999896896549676426094918302160613340902023133969841067385167041200690481843915870926707"
492 "11590526535239899047608853509681914074220789038015289373871985431257486278/"
493 "1223067474012215838745994023624181143448435715858923491568712969277184634645504346456117443333632535902774869182827010789201"
494 "972713368729205674432492059242349591780604188152950845769793378621446766887"),
std::unique_ptr< storm::modelchecker::QualitativeCheckResult > getInitialStateFilter(std::shared_ptr< storm::models::sparse::Model< storm::Interval > > const &model)
double getQuantitativeResultAtInitialState(std::shared_ptr< storm::models::sparse::Model< storm::Interval > > const &model, std::unique_ptr< storm::modelchecker::CheckResult > &result)
void setPrecision(storm::RationalNumber value)
void setPreconditioner(storm::solver::EigenLinearEquationSolverPreconditioner value)
void setMethod(storm::solver::EigenLinearEquationSolverMethod value)
SolverEnvironment & solver()
void setMethod(storm::solver::GmmxxLinearEquationSolverMethod value)
void setPrecision(storm::RationalNumber value)
void setPreconditioner(storm::solver::GmmxxLinearEquationSolverPreconditioner value)
void setDetLraMethod(storm::solver::LraMethod value, bool isSetFromDefault=false)
void setPrecision(storm::RationalNumber value)
void setSorOmega(storm::RationalNumber const &value)
void setMethod(storm::solver::NativeLinearEquationSolverMethod value)
void setLinearEquationSolverType(storm::solver::EquationSolverType const &value, bool isSetFromDefault=false)
EigenSolverEnvironment & eigen()
void setForceSoundness(bool value)
NativeSolverEnvironment & native()
GmmxxSolverEnvironment & gmmxx()
LongRunAverageSolverEnvironment & lra()
This class represents a continuous-time Markov chain.
This class represents a continuous-time Markov chain.
std::vector< storm::jani::Property > parsePropertiesForPrismProgram(std::string const &inputString, storm::prism::Program const &program, boost::optional< std::set< std::string > > const &propertyFilter)
storm::prism::Program parseProgram(std::string const &filename, bool prismCompatibility, bool simplify)
std::vector< std::shared_ptr< storm::logic::Formula const > > extractFormulasFromProperties(std::vector< storm::jani::Property > const &properties)
std::pair< storm::jani::Model, std::vector< storm::jani::Property > > convertPrismToJani(storm::prism::Program const &program, storm::converter::PrismToJaniConverterOptions options)
SFTBDDChecker::ValueType ValueType
NumberType parseNumber(std::string const &value)
Parse number from string.
storm::prism::Program preprocess(storm::prism::Program const &program, std::map< storm::expressions::Variable, storm::expressions::Expression > const &constantDefinitions)
storm::storage::BitVector filter(std::vector< T > const &values, std::function< bool(T const &value)> const &function)
Retrieves a bit vector containing all the indices for which the value at this position makes the give...
TYPED_TEST(GraphTestAR, SymbolicProb01StochasticGameDieSmall)
TYPED_TEST_SUITE(GraphTestAR, TestingTypes,)
::testing::Types< Cudd, Sylvan > TestingTypes