Tim Quatmann
6 years ago
5 changed files with 505 additions and 0 deletions
-
20resources/examples/testfiles/dtmc/quantiles_simple_dtmc.pm
-
80resources/examples/testfiles/mdp/quantiles_firewire.nm
-
72resources/examples/testfiles/mdp/quantiles_resources.nm
-
31resources/examples/testfiles/mdp/quantiles_simple_mdp.nm
-
302src/test/storm/modelchecker/QuantileQueryTest.cpp
@ -0,0 +1,20 @@ |
|||||
|
|
||||
|
dtmc |
||||
|
|
||||
|
module main |
||||
|
s : [0..3] init 0; |
||||
|
|
||||
|
[] s=0 -> 0.4 : (s'=1) + 0.4 : (s'=2) + 0.2 : (s'=3); |
||||
|
[a] s=1 -> 1 : (s'=0); |
||||
|
[b] s=2 -> 1 : (s'=0); |
||||
|
[] s=3 -> 1 : (s'=3); |
||||
|
endmodule |
||||
|
|
||||
|
rewards "first" |
||||
|
[a] true : 1; |
||||
|
endrewards |
||||
|
|
||||
|
rewards "second" |
||||
|
[b] true : 2; |
||||
|
endrewards |
||||
|
|
@ -0,0 +1,80 @@ |
|||||
|
// integer semantics version of abstract firewire protocol |
||||
|
// gxn 23/05/2001 |
||||
|
|
||||
|
mdp |
||||
|
|
||||
|
// wire delay |
||||
|
const int delay; |
||||
|
|
||||
|
// probability of choosing fast and slow |
||||
|
const double fast = 0.5; |
||||
|
const double slow = 1-fast; |
||||
|
|
||||
|
// largest constant the clock of the system is compared to |
||||
|
const int kx = 167; |
||||
|
|
||||
|
module abstract_firewire |
||||
|
|
||||
|
// clock |
||||
|
x : [0..kx+1]; |
||||
|
|
||||
|
// local state |
||||
|
s : [0..9]; |
||||
|
// 0 -start_start |
||||
|
// 1 -fast_start |
||||
|
// 2 -start_fast |
||||
|
// 3 -start_slow |
||||
|
// 4 -slow_start |
||||
|
// 5 -fast_fast |
||||
|
// 6 -fast_slow |
||||
|
// 7 -slow_fast |
||||
|
// 8 -slow_slow |
||||
|
// 9 -done |
||||
|
|
||||
|
// initial state |
||||
|
[time] s=0 & x<delay -> (x'=min(x+1,kx+1)); |
||||
|
[round] s=0 -> fast : (s'=1) + slow : (s'=4); |
||||
|
[round] s=0 -> fast : (s'=2) + slow : (s'=3); |
||||
|
// fast_start |
||||
|
[time] s=1 & x<delay -> (x'=min(x+1,kx+1)); |
||||
|
[] s=1 -> fast : (s'=5) & (x'=0) + slow : (s'=6) & (x'=0); |
||||
|
// start_fast |
||||
|
[time] s=2 & x<delay -> (x'=min(x+1,kx+1)); |
||||
|
[] s=2 -> fast : (s'=5) & (x'=0) + slow : (s'=7) & (x'=0); |
||||
|
// start_slow |
||||
|
[time] s=3 & x<delay -> (x'=min(x+1,kx+1)); |
||||
|
[] s=3 -> fast : (s'=6) & (x'=0) + slow : (s'=8) & (x'=0); |
||||
|
// slow_start |
||||
|
[time] s=4 & x<delay -> (x'=min(x+1,kx+1)); |
||||
|
[] s=4 -> fast : (s'=7) & (x'=0) + slow : (s'=8) & (x'=0); |
||||
|
// fast_fast |
||||
|
[time] s=5 & (x<85) -> (x'=min(x+1,kx+1)); |
||||
|
[] s=5 & (x>=76) -> (s'=0) & (x'=0); |
||||
|
[] s=5 & (x>=76-delay) -> (s'=9) & (x'=0); |
||||
|
// fast_slow |
||||
|
[time] s=6 & x<167 -> (x'=min(x+1,kx+1)); |
||||
|
[] s=6 & x>=159-delay -> (s'=9) & (x'=0); |
||||
|
// slow_fast |
||||
|
[time] s=7 & x<167 -> (x'=min(x+1,kx+1)); |
||||
|
[] s=7 & x>=159-delay -> (s'=9) & (x'=0); |
||||
|
// slow_slow |
||||
|
[time] s=8 & x<167 -> (x'=min(x+1,kx+1)); |
||||
|
[] s=8 & x>=159 -> (s'=0) & (x'=0); |
||||
|
[] s=8 & x>=159-delay -> (s'=9) & (x'=0); |
||||
|
// done |
||||
|
[] s=9 -> (s'=s); |
||||
|
|
||||
|
endmodule |
||||
|
|
||||
|
// labels |
||||
|
label "done" = s=9; |
||||
|
|
||||
|
//reward structures |
||||
|
// time |
||||
|
rewards "time" |
||||
|
[time] true : 1; |
||||
|
endrewards |
||||
|
// number of rounds |
||||
|
rewards "rounds" |
||||
|
[round] true : 1; |
||||
|
endrewards |
@ -0,0 +1,72 @@ |
|||||
|
mdp |
||||
|
|
||||
|
const int WIDTH = 5; |
||||
|
const int HEIGHT = 5; |
||||
|
const int XINIT = 3; |
||||
|
const int YINIT = 1; |
||||
|
|
||||
|
const double pAttack = 1/10; |
||||
|
|
||||
|
formula left_of_gold = x=2 & y=5; |
||||
|
formula right_of_gold = x=4 & y=5; |
||||
|
formula below_of_gold = (x=3 & y=4); |
||||
|
formula above_of_gold = false; |
||||
|
formula left_of_gem = (x=4 & y=4); |
||||
|
formula right_of_gem = false; |
||||
|
formula below_of_gem = (x=5 & y=3); |
||||
|
formula above_of_gem = (x=5 & y=5); |
||||
|
formula left_of_home = x=2 & y=1; |
||||
|
formula right_of_home = x=4 & y=1; |
||||
|
formula above_of_home = x=3 & y=2; |
||||
|
formula below_of_home = false; |
||||
|
formula left_of_enemy = (x=3 & y=5) | (x=2 & y=4); |
||||
|
formula right_of_enemy = (x=5 & y=5) | (x=4 & y=4); |
||||
|
formula above_of_enemy = x=3 & y=5; |
||||
|
formula below_of_enemy = (x=3 & y=3) | (x=4 & y=4); |
||||
|
|
||||
|
module robot |
||||
|
|
||||
|
gold : bool init false; |
||||
|
gem : bool init false; |
||||
|
attacked : bool init false; |
||||
|
|
||||
|
x : [1..WIDTH] init XINIT; |
||||
|
y : [1..HEIGHT] init YINIT; |
||||
|
|
||||
|
[right] !left_of_enemy & x<WIDTH -> (attacked'=false) & (x'=x+1) & (gold' = (gold & !left_of_home) | left_of_gold) & (gem' = (gem & !left_of_home) | left_of_gem); |
||||
|
[left] !right_of_enemy & x>1 -> (attacked'=false) & (x'=x-1) & (gold' = (gold & !right_of_home) | right_of_gold) & (gem' = (gem & !right_of_home) | right_of_gem); |
||||
|
[top] !below_of_enemy & y<HEIGHT -> (attacked'=false) & (y'=y+1) & (gold' = (gold & !below_of_home) | below_of_gold) & (gem' = (gem & !below_of_home) | below_of_gem); |
||||
|
[down] !above_of_enemy & y>1 -> (attacked'=false) & (y'=y-1) & (gold' = (gold & !above_of_home) | above_of_gold) & (gem' = (gem & !above_of_home) | above_of_gem); |
||||
|
|
||||
|
[right] left_of_enemy & x<WIDTH -> pAttack : (attacked'=true) & (x'=XINIT) & (y'=YINIT) & (gold'=false) & (gem'=false) + (1-pAttack) : (attacked'=false) & (x'=x+1) & (gold' = (gold & !left_of_home) | left_of_gold) & (gem' = (gem & !left_of_home) | left_of_gem); |
||||
|
[left] right_of_enemy & x>1 -> pAttack : (attacked'=true) & (x'=XINIT) & (y'=YINIT) & (gold'=false) & (gem'=false) + (1-pAttack) : (attacked'=false) & (x'=x-1) & (gold' = (gold & !right_of_home) | right_of_gold) & (gem' = (gem & !right_of_home) | right_of_gem); |
||||
|
[top] below_of_enemy & y<HEIGHT -> pAttack : (attacked'=true) & (x'=XINIT) & (y'=YINIT) & (gold'=false) & (gem'=false) + (1-pAttack) : (attacked'=false) & (y'=y+1) & (gold' = (gold & !below_of_home) | below_of_gold) & (gem' = (gem & !below_of_home) | below_of_gem); |
||||
|
[down] above_of_enemy & y>1 -> pAttack : (attacked'=true) & (x'=XINIT) & (y'=YINIT) & (gold'=false) & (gem'=false) + (1-pAttack) : (attacked'=false) & (y'=y-1) & (gold' = (gold & !above_of_home) | above_of_gold) & (gem' = (gem & !above_of_home) | above_of_gem); |
||||
|
endmodule |
||||
|
|
||||
|
rewards "attacks" |
||||
|
attacked : 1; |
||||
|
endrewards |
||||
|
|
||||
|
rewards "steps" |
||||
|
[left] true : 1; |
||||
|
[right] true : 1; |
||||
|
[top] true : 1; |
||||
|
[down] true : 1; |
||||
|
endrewards |
||||
|
|
||||
|
rewards "gold" |
||||
|
[right] left_of_home & gold : 1; |
||||
|
[left] right_of_home & gold : 1; |
||||
|
[top] below_of_home & gold : 1; |
||||
|
[down] above_of_home & gold : 1; |
||||
|
endrewards |
||||
|
|
||||
|
rewards "gem" |
||||
|
[right] left_of_home & gem : 1; |
||||
|
[left] right_of_home & gem : 1; |
||||
|
[top] below_of_home & gem : 1; |
||||
|
[down] above_of_home & gem: 1; |
||||
|
endrewards |
||||
|
|
||||
|
|
@ -0,0 +1,31 @@ |
|||||
|
|
||||
|
mdp |
||||
|
|
||||
|
module main |
||||
|
s : [0..6] init 6; |
||||
|
|
||||
|
[] s=6 -> 1 : (s'=0); |
||||
|
[] s=6 -> 1 : (s'=5); |
||||
|
[a] s=5 -> 1 : (s'=5); |
||||
|
[b] s=5 -> 1 : (s'=1); |
||||
|
[] s=0 -> 1/10: (s'=1) + 9/10: (s'=3); |
||||
|
[] s=0 -> 1/10: (s'=1) + 9/10: (s'=4); |
||||
|
[a] s=3 -> 1: (s'=0); |
||||
|
[b] s=3 -> 1: (s'=0); |
||||
|
[] s=1 -> 1: (s'=2); |
||||
|
[] s=2 -> 1: (s'=2); |
||||
|
endmodule |
||||
|
|
||||
|
rewards "first" |
||||
|
[a] true : 1; |
||||
|
endrewards |
||||
|
|
||||
|
rewards "second" |
||||
|
[b] s=3 : 1; |
||||
|
[b] s=5 : 2; |
||||
|
endrewards |
||||
|
|
||||
|
rewards "third" |
||||
|
true : 0.7; |
||||
|
endrewards |
||||
|
|
@ -0,0 +1,302 @@ |
|||||
|
#include "gtest/gtest.h"
|
||||
|
#include "storm-config.h"
|
||||
|
|
||||
|
#include "test/storm_gtest.h"
|
||||
|
|
||||
|
#include "storm/api/builder.h"
|
||||
|
#include "storm-parsers/api/model_descriptions.h"
|
||||
|
#include "storm/api/properties.h"
|
||||
|
#include "storm-parsers/api/properties.h"
|
||||
|
#include "storm/parser/CSVParser.h"
|
||||
|
|
||||
|
#include "storm/models/sparse/Mdp.h"
|
||||
|
#include "storm/models/sparse/StandardRewardModel.h"
|
||||
|
#include "storm/modelchecker/prctl/SparseMdpPrctlModelChecker.h"
|
||||
|
#include "storm/modelchecker/prctl/SparseDtmcPrctlModelChecker.h"
|
||||
|
#include "storm/modelchecker/results/ExplicitParetoCurveCheckResult.h"
|
||||
|
#include "storm/modelchecker/results/ExplicitQualitativeCheckResult.h"
|
||||
|
#include "storm/modelchecker/results/ExplicitQuantitativeCheckResult.h"
|
||||
|
#include "storm/environment/solver/MinMaxSolverEnvironment.h"
|
||||
|
#include "storm/logic/Formulas.h"
|
||||
|
#include "storm/storage/jani/Property.h"
|
||||
|
|
||||
|
namespace { |
||||
|
|
||||
|
enum class MdpEngine {PrismSparse, JaniSparse, JitSparse, Hybrid, PrismDd, JaniDd}; |
||||
|
|
||||
|
class UnsoundEnvironment { |
||||
|
public: |
||||
|
typedef double ValueType; |
||||
|
static storm::Environment createEnvironment() { |
||||
|
storm::Environment env; |
||||
|
env.solver().minMax().setPrecision(storm::utility::convertNumber<storm::RationalNumber>(1e-10)); |
||||
|
return env; |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
class SoundEnvironment { |
||||
|
public: |
||||
|
typedef double ValueType; |
||||
|
static storm::Environment createEnvironment() { |
||||
|
storm::Environment env; |
||||
|
env.solver().setForceSoundness(true); |
||||
|
return env; |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
class ExactEnvironment { |
||||
|
public: |
||||
|
typedef storm::RationalNumber ValueType; |
||||
|
static storm::Environment createEnvironment() { |
||||
|
storm::Environment env; |
||||
|
return env; |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
template<typename TestType> |
||||
|
class QuantileQueryTest : public ::testing::Test { |
||||
|
public: |
||||
|
typedef typename TestType::ValueType ValueType; |
||||
|
QuantileQueryTest() : _environment(TestType::createEnvironment()) {} |
||||
|
storm::Environment const& env() const { return _environment; } |
||||
|
ValueType parseNumber(std::string const& input) const { |
||||
|
if (input.find("inf") != std::string::npos) { |
||||
|
return storm::utility::infinity<ValueType>(); |
||||
|
} |
||||
|
return storm::utility::convertNumber<ValueType>(input); |
||||
|
} |
||||
|
|
||||
|
template <typename MT> |
||||
|
std::pair<std::shared_ptr<MT>, std::vector<std::shared_ptr<storm::logic::Formula const>>> buildModelFormulas(std::string const& pathToPrismFile, std::string const& formulasAsString, std::string const& constantDefinitionString = "") const { |
||||
|
std::pair<std::shared_ptr<MT>, std::vector<std::shared_ptr<storm::logic::Formula const>>> result; |
||||
|
storm::prism::Program program = storm::api::parseProgram(pathToPrismFile); |
||||
|
program = storm::utility::prism::preprocess(program, constantDefinitionString); |
||||
|
result.second = storm::api::extractFormulasFromProperties(storm::api::parsePropertiesForPrismProgram(formulasAsString, program)); |
||||
|
result.first = storm::api::buildSparseModel<ValueType>(program, result.second)->template as<MT>(); |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
std::vector<storm::modelchecker::CheckTask<storm::logic::Formula, ValueType>> getTasks(std::vector<std::shared_ptr<storm::logic::Formula const>> const& formulas) const { |
||||
|
std::vector<storm::modelchecker::CheckTask<storm::logic::Formula, ValueType>> result; |
||||
|
for (auto const& f : formulas) { |
||||
|
result.emplace_back(*f, true); // only initial states are relevant
|
||||
|
} |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
template <typename MT> |
||||
|
typename std::enable_if<std::is_same<MT, storm::models::sparse::Mdp<ValueType>>::value, std::shared_ptr<storm::modelchecker::AbstractModelChecker<MT>>>::type |
||||
|
createModelChecker(std::shared_ptr<MT> const& model) const { |
||||
|
return std::make_shared<storm::modelchecker::SparseMdpPrctlModelChecker<MT>>(*model); |
||||
|
} |
||||
|
template <typename MT> |
||||
|
typename std::enable_if<std::is_same<MT, storm::models::sparse::Dtmc<ValueType>>::value, std::shared_ptr<storm::modelchecker::AbstractModelChecker<MT>>>::type |
||||
|
createModelChecker(std::shared_ptr<MT> const& model) const { |
||||
|
return std::make_shared<storm::modelchecker::SparseDtmcPrctlModelChecker<MT>>(*model); |
||||
|
} |
||||
|
|
||||
|
std::pair<bool, std::string> compareResult(std::shared_ptr<storm::models::sparse::Model<ValueType>> const& model, std::unique_ptr<storm::modelchecker::CheckResult>& result, std::vector<std::string> const& expected) { |
||||
|
bool equal = true; |
||||
|
std::string errorMessage = ""; |
||||
|
auto filter = getInitialStateFilter(model); |
||||
|
result->filter(*filter); |
||||
|
std::vector<std::vector<ValueType>> resultPoints; |
||||
|
if (result->isExplicitParetoCurveCheckResult()) { |
||||
|
resultPoints = result->asExplicitParetoCurveCheckResult<ValueType>().getPoints(); |
||||
|
} else { |
||||
|
if (!result->isExplicitQuantitativeCheckResult()) { |
||||
|
return { false, "The CheckResult has unexpected type."}; |
||||
|
} |
||||
|
resultPoints = {{ result->asExplicitQuantitativeCheckResult<ValueType>().getMax() }}; |
||||
|
} |
||||
|
std::vector<std::vector<ValueType>> expectedPoints; |
||||
|
for (auto const& pointAsString : expected) { |
||||
|
std::vector<ValueType> point; |
||||
|
for (auto const& entry : storm::parser::parseCommaSeperatedValues(pointAsString)) { |
||||
|
point.push_back(parseNumber(entry)); |
||||
|
} |
||||
|
expectedPoints.push_back(std::move(point)); |
||||
|
} |
||||
|
for (auto const& resPoint : resultPoints) { |
||||
|
bool contained = false; |
||||
|
for (auto const& expPoint : expectedPoints) { |
||||
|
if (resPoint == expPoint) { |
||||
|
contained = true; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
if (!contained) { |
||||
|
equal = false; |
||||
|
errorMessage += "The result " + storm::utility::vector::toString(resPoint) + " is not contained in the expected solution. "; |
||||
|
} |
||||
|
} |
||||
|
for (auto const& expPoint : expectedPoints) { |
||||
|
bool contained = false; |
||||
|
for (auto const& resPoint : resultPoints) { |
||||
|
if (resPoint == expPoint) { |
||||
|
contained = true; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
if (!contained) { |
||||
|
equal = false; |
||||
|
errorMessage += "The expected " + storm::utility::vector::toString(expPoint) + " is not contained in the obtained solution. "; |
||||
|
} |
||||
|
} |
||||
|
return {equal, errorMessage}; |
||||
|
} |
||||
|
|
||||
|
private: |
||||
|
storm::Environment _environment; |
||||
|
|
||||
|
std::unique_ptr<storm::modelchecker::QualitativeCheckResult> getInitialStateFilter(std::shared_ptr<storm::models::sparse::Model<ValueType>> const& model) const { |
||||
|
return std::make_unique<storm::modelchecker::ExplicitQualitativeCheckResult>(model->getInitialStates()); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
typedef ::testing::Types< |
||||
|
UnsoundEnvironment, |
||||
|
SoundEnvironment, |
||||
|
ExactEnvironment |
||||
|
> TestingTypes; |
||||
|
|
||||
|
TYPED_TEST_CASE(QuantileQueryTest, TestingTypes); |
||||
|
|
||||
|
|
||||
|
TYPED_TEST(QuantileQueryTest, simple_Dtmc) { |
||||
|
typedef storm::models::sparse::Dtmc<typename TestFixture::ValueType> ModelType; |
||||
|
|
||||
|
std::string formulasString = "quantile(max A, max B, P>0.95 [F{\"first\"}<=A,{\"second\"}<=B s=3]);\n"; |
||||
|
|
||||
|
auto modelFormulas = this->template buildModelFormulas<ModelType>(STORM_TEST_RESOURCES_DIR "/dtmc/quantiles_simple_dtmc.pm", formulasString); |
||||
|
auto model = std::move(modelFormulas.first); |
||||
|
auto tasks = this->getTasks(modelFormulas.second); |
||||
|
EXPECT_EQ(4ul, model->getNumberOfStates()); |
||||
|
EXPECT_EQ(6ul, model->getNumberOfTransitions()); |
||||
|
auto checker = this->template createModelChecker<ModelType>(model); |
||||
|
std::unique_ptr<storm::modelchecker::CheckResult> result; |
||||
|
std::vector<std::string> expectedResult; |
||||
|
std::pair<bool, std::string> compare; |
||||
|
uint64_t taskId = 0; |
||||
|
|
||||
|
expectedResult.clear(); |
||||
|
expectedResult.push_back("7, 18"); |
||||
|
expectedResult.push_back("8, 16"); |
||||
|
expectedResult.push_back("9, 14"); |
||||
|
result = checker->check(this->env(), tasks[taskId++]); |
||||
|
compare = this->compareResult(model, result, expectedResult); |
||||
|
EXPECT_TRUE(compare.first) << compare.second; |
||||
|
} |
||||
|
|
||||
|
TYPED_TEST(QuantileQueryTest, simple_Mdp) { |
||||
|
typedef storm::models::sparse::Mdp<typename TestFixture::ValueType> ModelType; |
||||
|
|
||||
|
std::string formulasString = "quantile(B1, B2, Pmax>0.5 [F{\"first\"}>=B1,{\"second\"}>=B2 s=1]);\n"; |
||||
|
formulasString += "quantile(B1, B2, Pmax>0.5 [F{\"first\"}<=B1,{\"second\"}<=B2 s=1]);\n"; |
||||
|
formulasString += "quantile(B1, B2, Pmin>0.5 [F{\"first\"}<=B1,{\"second\"}<=B2 s=1]);\n"; |
||||
|
formulasString += "quantile(B1, Pmax>0.5 [F{\"second\"}>=B1 s=1]);\n"; |
||||
|
formulasString += "quantile(B1, B2, B3, Pmax>0.5 [F{\"first\"}<=B1,{\"second\"}<=B2,{\"third\"}<=B3 s=1]);\n"; |
||||
|
|
||||
|
auto modelFormulas = this->template buildModelFormulas<ModelType>(STORM_TEST_RESOURCES_DIR "/mdp/quantiles_simple_mdp.nm", formulasString); |
||||
|
auto model = std::move(modelFormulas.first); |
||||
|
auto tasks = this->getTasks(modelFormulas.second); |
||||
|
EXPECT_EQ(7ul, model->getNumberOfStates()); |
||||
|
EXPECT_EQ(13ul, model->getNumberOfTransitions()); |
||||
|
auto checker = this->template createModelChecker<ModelType>(model); |
||||
|
std::unique_ptr<storm::modelchecker::CheckResult> result; |
||||
|
std::vector<std::string> expectedResult; |
||||
|
std::pair<bool, std::string> compare; |
||||
|
uint64_t taskId = 0; |
||||
|
|
||||
|
expectedResult.clear(); |
||||
|
expectedResult.push_back(" 0, 6"); |
||||
|
expectedResult.push_back(" 1, 5"); |
||||
|
expectedResult.push_back(" 2, 4"); |
||||
|
expectedResult.push_back(" 3, 3"); |
||||
|
expectedResult.push_back("inf, 2"); |
||||
|
result = checker->check(this->env(), tasks[taskId++]); |
||||
|
compare = this->compareResult(model, result, expectedResult); |
||||
|
EXPECT_TRUE(compare.first) << compare.second; |
||||
|
|
||||
|
expectedResult.clear(); |
||||
|
expectedResult.push_back(" 0, 2"); |
||||
|
expectedResult.push_back(" 5, 1"); |
||||
|
expectedResult.push_back(" 6, 0"); |
||||
|
result = checker->check(this->env(), tasks[taskId++]); |
||||
|
compare = this->compareResult(model, result, expectedResult); |
||||
|
EXPECT_TRUE(compare.first) << compare.second; |
||||
|
|
||||
|
expectedResult.clear(); |
||||
|
result = checker->check(this->env(), tasks[taskId++]); |
||||
|
compare = this->compareResult(model, result, expectedResult); |
||||
|
EXPECT_TRUE(compare.first) << compare.second; |
||||
|
|
||||
|
expectedResult.clear(); |
||||
|
expectedResult.push_back(" 6"); |
||||
|
result = checker->check(this->env(), tasks[taskId++]); |
||||
|
compare = this->compareResult(model, result, expectedResult); |
||||
|
EXPECT_TRUE(compare.first) << compare.second; |
||||
|
|
||||
|
expectedResult.clear(); |
||||
|
expectedResult.push_back(" 0, 2, 1.4"); |
||||
|
expectedResult.push_back(" 5, 1, 9.8"); |
||||
|
expectedResult.push_back(" 6, 0, 9.8"); |
||||
|
result = checker->check(this->env(), tasks[taskId++]); |
||||
|
compare = this->compareResult(model, result, expectedResult); |
||||
|
EXPECT_TRUE(compare.first) << compare.second; |
||||
|
} |
||||
|
|
||||
|
TYPED_TEST(QuantileQueryTest, firewire) { |
||||
|
typedef storm::models::sparse::Mdp<typename TestFixture::ValueType> ModelType; |
||||
|
|
||||
|
std::string formulasString = "quantile(min TIME, min ROUNDS, Pmax>0.95 [F{\"time\"}<=TIME,{\"rounds\"}<=ROUNDS \"done\"]);\n"; |
||||
|
|
||||
|
auto modelFormulas = this->template buildModelFormulas<ModelType>(STORM_TEST_RESOURCES_DIR "/mdp/quantiles_firewire.nm", formulasString, "delay=36"); |
||||
|
auto model = std::move(modelFormulas.first); |
||||
|
auto tasks = this->getTasks(modelFormulas.second); |
||||
|
EXPECT_EQ(776ul, model->getNumberOfStates()); |
||||
|
EXPECT_EQ(1411ul, model->getNumberOfTransitions()); |
||||
|
auto checker = this->template createModelChecker<ModelType>(model); |
||||
|
std::unique_ptr<storm::modelchecker::CheckResult> result; |
||||
|
std::vector<std::string> expectedResult; |
||||
|
std::pair<bool, std::string> compare; |
||||
|
uint64_t taskId = 0; |
||||
|
|
||||
|
expectedResult.clear(); |
||||
|
expectedResult.push_back("123, 1"); |
||||
|
result = checker->check(this->env(), tasks[taskId++]); |
||||
|
compare = this->compareResult(model, result, expectedResult); |
||||
|
EXPECT_TRUE(compare.first) << compare.second; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
TYPED_TEST(QuantileQueryTest, resources) { |
||||
|
typedef storm::models::sparse::Mdp<typename TestFixture::ValueType> ModelType; |
||||
|
|
||||
|
std::string formulasString = "quantile(max GOLD, max GEM, Pmax>0.95 [F{\"gold\"}>=GOLD,{\"gem\"}>=GEM,{\"steps\"}<=100 true]);\n"; |
||||
|
|
||||
|
auto modelFormulas = this->template buildModelFormulas<ModelType>(STORM_TEST_RESOURCES_DIR "/mdp/quantiles_resources.nm", formulasString); |
||||
|
auto model = std::move(modelFormulas.first); |
||||
|
auto tasks = this->getTasks(modelFormulas.second); |
||||
|
EXPECT_EQ(94ul, model->getNumberOfStates()); |
||||
|
EXPECT_EQ(326ul, model->getNumberOfTransitions()); |
||||
|
auto checker = this->template createModelChecker<ModelType>(model); |
||||
|
std::unique_ptr<storm::modelchecker::CheckResult> result; |
||||
|
std::vector<std::string> expectedResult; |
||||
|
std::pair<bool, std::string> compare; |
||||
|
uint64_t taskId = 0; |
||||
|
|
||||
|
expectedResult.clear(); |
||||
|
expectedResult.push_back("0, 10"); |
||||
|
expectedResult.push_back("1, 9"); |
||||
|
expectedResult.push_back("4, 8"); |
||||
|
expectedResult.push_back("7, 7"); |
||||
|
expectedResult.push_back("8, 4"); |
||||
|
expectedResult.push_back("9, 2"); |
||||
|
expectedResult.push_back("10, 0"); |
||||
|
result = checker->check(this->env(), tasks[taskId++]); |
||||
|
compare = this->compareResult(model, result, expectedResult); |
||||
|
EXPECT_TRUE(compare.first) << compare.second; |
||||
|
|
||||
|
} |
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue