1#include "storm-config.h"
32enum class CtmcEngine { PrismSparse, JaniSparse, JaniHybrid };
34class GBSparseGmmxxGmresIluEnvironment {
37 static const CtmcEngine engine = CtmcEngine::PrismSparse;
38 static const bool isExact =
false;
47 storm::utility::convertNumber<storm::RationalNumber>(1e-8));
50 storm::utility::convertNumber<storm::RationalNumber>(1e-8));
55class GBJaniSparseGmmxxGmresIluEnvironment {
58 static const CtmcEngine engine = CtmcEngine::JaniSparse;
59 static const bool isExact =
false;
68 storm::utility::convertNumber<storm::RationalNumber>(1e-8));
71 storm::utility::convertNumber<storm::RationalNumber>(1e-8));
76class GBJaniHybridCuddGmmxxGmresEnvironment {
79 static const CtmcEngine engine = CtmcEngine::JaniHybrid;
80 static const bool isExact =
false;
89 storm::utility::convertNumber<storm::RationalNumber>(1e-8));
92 storm::utility::convertNumber<storm::RationalNumber>(1e-8));
97class GBJaniHybridSylvanGmmxxGmresEnvironment {
100 static const CtmcEngine engine = CtmcEngine::JaniHybrid;
101 static const bool isExact =
false;
110 storm::utility::convertNumber<storm::RationalNumber>(1e-8));
113 storm::utility::convertNumber<storm::RationalNumber>(1e-8));
118class GBSparseEigenDGmresEnvironment {
121 static const CtmcEngine engine = CtmcEngine::PrismSparse;
122 static const bool isExact =
false;
135class GBSparseEigenDoubleLUEnvironment {
138 static const CtmcEngine engine = CtmcEngine::PrismSparse;
139 static const bool isExact =
false;
151class GBSparseNativeSorEnvironment {
154 static const CtmcEngine engine = CtmcEngine::PrismSparse;
155 static const bool isExact =
false;
169class DistrSparseGmmxxGmresIluEnvironment {
172 static const CtmcEngine engine = CtmcEngine::PrismSparse;
173 static const bool isExact =
false;
182 storm::utility::convertNumber<storm::RationalNumber>(1e-8));
185 storm::utility::convertNumber<storm::RationalNumber>(1e-8));
190class DistrSparseEigenDoubleLUEnvironment {
193 static const CtmcEngine engine = CtmcEngine::PrismSparse;
194 static const bool isExact =
false;
208class ValueIterationSparseEnvironment {
211 static const CtmcEngine engine = CtmcEngine::PrismSparse;
212 static const bool isExact =
false;
222class SoundEnvironment {
225 static const CtmcEngine engine = CtmcEngine::PrismSparse;
226 static const bool isExact =
false;
236template<
typename TestType>
237class LraCtmcCslModelCheckerTest :
public ::testing::Test {
239 typedef typename TestType::ValueType
ValueType;
243 LraCtmcCslModelCheckerTest() : _environment(TestType::createEnvironment()) {}
245 void SetUp()
override {
247 GTEST_SKIP() <<
"Z3 not available.";
255 return storm::utility::convertNumber<ValueType>(input);
260 bool isSparseModel()
const {
261 return std::is_same<typename TestType::ModelType, SparseModelType>::value;
263 bool isSymbolicModel()
const {
264 return std::is_same<typename TestType::ModelType, SymbolicModelType>::value;
266 CtmcEngine getEngine()
const {
267 return TestType::engine;
270 template<
typename MT =
typename TestType::ModelType>
271 typename std::enable_if<std::is_same<MT, SparseModelType>::value,
272 std::pair<std::shared_ptr<MT>, std::vector<std::shared_ptr<storm::logic::Formula const>>>>::type
273 buildModelFormulas(std::string
const& pathToPrismFile, std::string
const& formulasAsString, std::string
const& constantDefinitionString =
"")
const {
274 std::pair<std::shared_ptr<MT>, std::vector<std::shared_ptr<storm::logic::Formula const>>> result;
277 if (TestType::engine == CtmcEngine::PrismSparse) {
279 result.first = storm::api::buildSparseModel<ValueType>(program, result.second)->template as<MT>();
280 }
else if (TestType::engine == CtmcEngine::JaniSparse) {
282 janiData.first.substituteFunctions();
284 result.first = storm::api::buildSparseModel<ValueType>(janiData.first, result.second)->template as<MT>();
289 template<
typename MT =
typename TestType::ModelType>
290 typename std::enable_if<std::is_same<MT, SymbolicModelType>::value,
291 std::pair<std::shared_ptr<MT>, std::vector<std::shared_ptr<storm::logic::Formula const>>>>::type
292 buildModelFormulas(std::string
const& pathToPrismFile, std::string
const& formulasAsString, std::string
const& constantDefinitionString =
"")
const {
293 std::pair<std::shared_ptr<MT>, std::vector<std::shared_ptr<storm::logic::Formula const>>> result;
296 if (TestType::engine == CtmcEngine::JaniHybrid) {
298 janiData.first.substituteFunctions();
300 result.first = storm::api::buildSymbolicModel<TestType::ddType, ValueType>(janiData.first, result.second)->template as<MT>();
305 std::vector<storm::modelchecker::CheckTask<storm::logic::Formula, ValueType>> getTasks(
306 std::vector<std::shared_ptr<storm::logic::Formula const>>
const& formulas)
const {
307 std::vector<storm::modelchecker::CheckTask<storm::logic::Formula, ValueType>> result;
308 for (
auto const& f : formulas) {
309 result.emplace_back(*f);
314 template<
typename MT =
typename TestType::ModelType>
315 typename std::enable_if<std::is_same<MT, SparseModelType>::value, std::shared_ptr<storm::modelchecker::AbstractModelChecker<MT>>>::type createModelChecker(
316 std::shared_ptr<MT>
const& model)
const {
317 if (TestType::engine == CtmcEngine::PrismSparse || TestType::engine == CtmcEngine::JaniSparse) {
318 return std::make_shared<storm::modelchecker::SparseCtmcCslModelChecker<SparseModelType>>(*model);
323 template<
typename MT =
typename TestType::ModelType>
324 typename std::enable_if<std::is_same<MT, SymbolicModelType>::value, std::shared_ptr<storm::modelchecker::AbstractModelChecker<MT>>>::type
325 createModelChecker(std::shared_ptr<MT>
const& model)
const {
326 if (TestType::engine == CtmcEngine::JaniHybrid) {
327 return std::make_shared<storm::modelchecker::HybridCtmcCslModelChecker<SymbolicModelType>>(*model);
332 template<
typename MT =
typename TestType::ModelType>
333 typename std::enable_if<std::is_same<MT, SparseModelType>::value,
void>::type execute(std::shared_ptr<MT>
const& model,
334 std::function<
void()>
const& f)
const {
338 template<
typename MT =
typename TestType::ModelType>
339 typename std::enable_if<std::is_same<MT, SymbolicModelType>::value,
void>::type execute(std::shared_ptr<MT>
const& model,
340 std::function<
void()>
const& f)
const {
341 model->getManager().execute(f);
345 std::unique_ptr<storm::modelchecker::CheckResult>& result) {
347 result->filter(*filter);
348 return result->asQualitativeCheckResult().forallTrue();
352 std::unique_ptr<storm::modelchecker::CheckResult>& result) {
354 result->filter(*filter);
355 return result->asQuantitativeCheckResult<
ValueType>().getMin();
362 if (isSparseModel()) {
363 return std::make_unique<storm::modelchecker::ExplicitQualitativeCheckResult>(model->template as<SparseModelType>()->getInitialStates());
365 return std::make_unique<storm::modelchecker::SymbolicQualitativeCheckResult<TestType::ddType>>(
366 model->template as<SymbolicModelType>()->getReachableStates(), model->template as<SymbolicModelType>()->getInitialStates());
371typedef ::testing::Types<GBSparseGmmxxGmresIluEnvironment, GBJaniSparseGmmxxGmresIluEnvironment, GBJaniHybridCuddGmmxxGmresEnvironment,
372 GBJaniHybridSylvanGmmxxGmresEnvironment, GBSparseEigenDGmresEnvironment, GBSparseEigenDoubleLUEnvironment,
373 GBSparseNativeSorEnvironment, DistrSparseGmmxxGmresIluEnvironment, DistrSparseEigenDoubleLUEnvironment,
374 ValueIterationSparseEnvironment, SoundEnvironment>
379TYPED_TEST(LraCtmcCslModelCheckerTest, Cluster) {
380 std::string formulasString =
"LRA=? [\"minimum\"]";
382 auto modelFormulas = this->buildModelFormulas(STORM_TEST_RESOURCES_DIR
"/ctmc/cluster2.sm", formulasString);
383 auto model = std::move(modelFormulas.first);
384 auto tasks = this->getTasks(modelFormulas.second);
385 this->execute(model, [&]() {
386 EXPECT_EQ(276ul, model->getNumberOfStates());
387 EXPECT_EQ(1120ul, model->getNumberOfTransitions());
389 auto checker = this->createModelChecker(model);
390 std::unique_ptr<storm::modelchecker::CheckResult> result;
392 result = checker->check(this->env(), tasks[0]);
397TYPED_TEST(LraCtmcCslModelCheckerTest, Embedded) {
398 std::string formulasString =
"LRA=? [\"fail_sensors\"]";
400 auto modelFormulas = this->buildModelFormulas(STORM_TEST_RESOURCES_DIR
"/ctmc/embedded2.sm", formulasString);
401 auto model = std::move(modelFormulas.first);
402 auto tasks = this->getTasks(modelFormulas.second);
403 this->execute(model, [&]() {
404 EXPECT_EQ(3478ul, model->getNumberOfStates());
405 EXPECT_EQ(14639ul, model->getNumberOfTransitions());
407 auto checker = this->createModelChecker(model);
408 std::unique_ptr<storm::modelchecker::CheckResult> result;
410 result = checker->check(this->env(), tasks[0]);
415TYPED_TEST(LraCtmcCslModelCheckerTest, Polling) {
416 std::string formulasString =
"LRA=?[\"target\"]";
418 auto modelFormulas = this->buildModelFormulas(STORM_TEST_RESOURCES_DIR
"/ctmc/polling2.sm", formulasString);
419 auto model = std::move(modelFormulas.first);
420 auto tasks = this->getTasks(modelFormulas.second);
421 this->execute(model, [&]() {
422 EXPECT_EQ(12ul, model->getNumberOfStates());
423 EXPECT_EQ(22ul, model->getNumberOfTransitions());
425 auto checker = this->createModelChecker(model);
426 std::unique_ptr<storm::modelchecker::CheckResult> result;
428 result = checker->check(this->env(), tasks[0]);
433TYPED_TEST(LraCtmcCslModelCheckerTest, Tandem) {
434 std::string formulasString =
"LRA=? [\"first_queue_full\"]";
436 auto modelFormulas = this->buildModelFormulas(STORM_TEST_RESOURCES_DIR
"/ctmc/tandem5.sm", formulasString);
437 auto model = std::move(modelFormulas.first);
438 auto tasks = this->getTasks(modelFormulas.second);
439 this->execute(model, [&]() {
440 EXPECT_EQ(66ul, model->getNumberOfStates());
441 EXPECT_EQ(189ul, model->getNumberOfTransitions());
443 auto checker = this->createModelChecker(model);
444 std::unique_ptr<storm::modelchecker::CheckResult> result;
446 result = checker->check(this->env(), tasks[0]);
451TYPED_TEST(LraCtmcCslModelCheckerTest, Rewards) {
452 std::string formulasString =
"R=? [ LRA ]";
454 auto modelFormulas = this->buildModelFormulas(STORM_TEST_RESOURCES_DIR
"/ctmc/lrarewards.sm", formulasString);
455 auto model = std::move(modelFormulas.first);
456 auto tasks = this->getTasks(modelFormulas.second);
457 this->execute(model, [&]() {
458 EXPECT_EQ(4ul, model->getNumberOfStates());
459 EXPECT_EQ(6ul, model->getNumberOfTransitions());
461 auto checker = this->createModelChecker(model);
462 std::unique_ptr<storm::modelchecker::CheckResult> result;
464 result = checker->check(this->env(), tasks[0]);
469TYPED_TEST(LraCtmcCslModelCheckerTest, kanban) {
470 std::string formulasString =
"R{\"throughput\"}=? [ LRA ]";
472 auto modelFormulas = this->buildModelFormulas(STORM_TEST_RESOURCES_DIR
"/ctmc/kanban.prism", formulasString);
473 auto model = std::move(modelFormulas.first);
474 auto tasks = this->getTasks(modelFormulas.second);
475 this->execute(model, [&]() {
476 EXPECT_EQ(160ul, model->getNumberOfStates());
477 EXPECT_EQ(616ul, model->getNumberOfTransitions());
479 auto checker = this->createModelChecker(model);
480 std::unique_ptr<storm::modelchecker::CheckResult> result;
482 result = checker->check(this->env(), tasks[0]);
484 this->
parseNumber(
"1132372552133951639536770152429724263999896896549676426094918302160613340902023133969841067385167041200690481843915870926707"
485 "11590526535239899047608853509681914074220789038015289373871985431257486278/"
486 "1223067474012215838745994023624181143448435715858923491568712969277184634645504346456117443333632535902774869182827010789201"
487 "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