@ -27,55 +27,83 @@
# include "storm-parsers/api/storm-parsers.h"
# include "storm-parsers/api/storm-parsers.h"
TEST ( MonotonicityCheckerTest , Derivative_checker ) {
TEST ( MonotonicityCheckerTest , Derivative_checker ) {
// Create the region
typename storm : : storage : : ParameterRegion < storm : : RationalFunction > : : Valuation lowerBoundaries ;
typename storm : : storage : : ParameterRegion < storm : : RationalFunction > : : Valuation upperBoundaries ;
auto region = storm : : storage : : ParameterRegion < storm : : RationalFunction > ( std : : move ( lowerBoundaries ) , std : : move ( upperBoundaries ) ) ;
// Derivative 0
// Derivative 0
auto constFunction = storm : : RationalFunction ( 0 ) ;
auto constFunction = storm : : RationalFunction ( 0 ) ;
auto constFunctionRes = storm : : analysis : : MonotonicityChecker < storm : : RationalFunction > : : checkDerivative ( constFunction ) ;
auto constFunctionRes = storm : : analysis : : MonotonicityChecker < storm : : RationalFunction > : : checkDerivative ( constFunction , region ) ;
EXPECT_TRUE ( constFunctionRes . first ) ;
EXPECT_TRUE ( constFunctionRes . first ) ;
EXPECT_TRUE ( constFunctionRes . second ) ;
EXPECT_TRUE ( constFunctionRes . second ) ;
// Derivative 5
// Derivative 5
constFunction = storm : : RationalFunction ( 5 ) ;
constFunction = storm : : RationalFunction ( 5 ) ;
constFunctionRes = storm : : analysis : : MonotonicityChecker < storm : : RationalFunction > : : checkDerivative ( constFunction ) ;
constFunctionRes = storm : : analysis : : MonotonicityChecker < storm : : RationalFunction > : : checkDerivative ( constFunction , region ) ;
EXPECT_TRUE ( constFunctionRes . first ) ;
EXPECT_TRUE ( constFunctionRes . first ) ;
EXPECT_FALSE ( constFunctionRes . second ) ;
EXPECT_FALSE ( constFunctionRes . second ) ;
// Derivative -4
// Derivative -4
constFunction = storm : : RationalFunction ( storm : : RationalFunction ( 1 ) - constFunction ) ;
constFunction = storm : : RationalFunction ( storm : : RationalFunction ( 1 ) - constFunction ) ;
constFunctionRes = storm : : analysis : : MonotonicityChecker < storm : : RationalFunction > : : checkDerivative ( constFunction ) ;
constFunctionRes = storm : : analysis : : MonotonicityChecker < storm : : RationalFunction > : : checkDerivative ( constFunction , region ) ;
EXPECT_FALSE ( constFunctionRes . first ) ;
EXPECT_FALSE ( constFunctionRes . first ) ;
EXPECT_TRUE ( constFunctionRes . second ) ;
EXPECT_TRUE ( constFunctionRes . second ) ;
std : : shared_ptr < storm : : RawPolynomialCache > cache = std : : make_shared < storm : : RawPolynomialCache > ( ) ;
std : : shared_ptr < storm : : RawPolynomialCache > cache = std : : make_shared < storm : : RawPolynomialCache > ( ) ;
carl : : StringParser parser ;
carl : : StringParser parser ;
parser . setVariables ( { " p " , " q " } ) ;
parser . setVariables ( { " p " , " q " } ) ;
// Create the region
auto functionP = storm : : RationalFunction ( storm : : Polynomial ( parser . template parseMultivariatePolynomial < storm : : RationalFunctionCoefficient > ( " p " ) , cache ) ) ;
auto functionQ = storm : : RationalFunction ( storm : : Polynomial ( parser . template parseMultivariatePolynomial < storm : : RationalFunctionCoefficient > ( " q " ) , cache ) ) ;
auto varsP = functionP . gatherVariables ( ) ;
auto varsQ = functionQ . gatherVariables ( ) ;
storm : : utility : : parametric : : Valuation < storm : : RationalFunction > lowerBoundaries2 ;
storm : : utility : : parametric : : Valuation < storm : : RationalFunction > upperBoundaries2 ;
for ( auto var : varsP ) {
typename storm : : storage : : ParameterRegion < storm : : RationalFunction > : : CoefficientType lb = storm : : utility : : convertNumber < typename storm : : storage : : ParameterRegion < storm : : RationalFunction > : : CoefficientType > ( 0 + 0.000001 ) ;
typename storm : : storage : : ParameterRegion < storm : : RationalFunction > : : CoefficientType ub = storm : : utility : : convertNumber < typename storm : : storage : : ParameterRegion < storm : : RationalFunction > : : CoefficientType > ( 1 - 0.000001 ) ;
lowerBoundaries2 . emplace ( std : : make_pair ( var , lb ) ) ;
upperBoundaries2 . emplace ( std : : make_pair ( var , ub ) ) ;
}
for ( auto var : varsQ ) {
typename storm : : storage : : ParameterRegion < storm : : RationalFunction > : : CoefficientType lb = storm : : utility : : convertNumber < typename storm : : storage : : ParameterRegion < storm : : RationalFunction > : : CoefficientType > ( 0 + 0.000001 ) ;
typename storm : : storage : : ParameterRegion < storm : : RationalFunction > : : CoefficientType ub = storm : : utility : : convertNumber < typename storm : : storage : : ParameterRegion < storm : : RationalFunction > : : CoefficientType > ( 1 - 0.000001 ) ;
lowerBoundaries2 . emplace ( std : : make_pair ( var , lb ) ) ;
upperBoundaries2 . emplace ( std : : make_pair ( var , ub ) ) ;
}
region = storm : : storage : : ParameterRegion < storm : : RationalFunction > ( std : : move ( lowerBoundaries2 ) , std : : move ( upperBoundaries2 ) ) ;
// Derivative p
// Derivative p
auto function = storm : : RationalFunction ( storm : : Polynomial ( parser . template parseMultivariatePolynomial < storm : : RationalFunctionCoefficient > ( " p " ) , cache ) ) ;
auto functionRes = storm : : analysis : : MonotonicityChecker < storm : : RationalFunction > : : checkDerivative ( function ) ;
auto function = functionP ;
auto functionRes = storm : : analysis : : MonotonicityChecker < storm : : RationalFunction > : : checkDerivative ( function , region ) ;
EXPECT_TRUE ( functionRes . first ) ;
EXPECT_TRUE ( functionRes . first ) ;
EXPECT_FALSE ( functionRes . second ) ;
EXPECT_FALSE ( functionRes . second ) ;
// Derivative 1-p
// Derivative 1-p
auto functionDecr = storm : : RationalFunction ( storm : : RationalFunction ( 1 ) - function ) ;
auto functionDecr = storm : : RationalFunction ( storm : : RationalFunction ( 1 ) - function ) ;
auto functionDecrRes = storm : : analysis : : MonotonicityChecker < storm : : RationalFunction > : : checkDerivative ( functionDecr ) ;
auto functionDecrRes = storm : : analysis : : MonotonicityChecker < storm : : RationalFunction > : : checkDerivative ( functionDecr , region ) ;
EXPECT_TRUE ( functionDecrRes . first ) ;
EXPECT_TRUE ( functionDecrRes . first ) ;
EXPECT_FALSE ( functionDecrRes . second ) ;
EXPECT_FALSE ( functionDecrRes . second ) ;
// Derivative 1-2p
// Derivative 1-2p
auto functionNonMonotonic = storm : : RationalFunction ( storm : : RationalFunction ( 1 ) - storm : : RationalFunction ( 2 ) * function ) ;
auto functionNonMonotonic = storm : : RationalFunction ( storm : : RationalFunction ( 1 ) - storm : : RationalFunction ( 2 ) * function ) ;
auto functionNonMonotonicRes = storm : : analysis : : MonotonicityChecker < storm : : RationalFunction > : : checkDerivative ( functionNonMonotonic ) ;
auto functionNonMonotonicRes = storm : : analysis : : MonotonicityChecker < storm : : RationalFunction > : : checkDerivative ( functionNonMonotonic , region ) ;
EXPECT_FALSE ( functionNonMonotonicRes . first ) ;
EXPECT_FALSE ( functionNonMonotonicRes . first ) ;
EXPECT_FALSE ( functionNonMonotonicRes . second ) ;
EXPECT_FALSE ( functionNonMonotonicRes . second ) ;
// Derivative -p
// Derivative -p
functionDecr = storm : : RationalFunction ( storm : : RationalFunction ( 0 ) - function ) ;
functionDecr = storm : : RationalFunction ( storm : : RationalFunction ( 0 ) - function ) ;
functionDecrRes = storm : : analysis : : MonotonicityChecker < storm : : RationalFunction > : : checkDerivative ( functionDecr ) ;
functionDecrRes = storm : : analysis : : MonotonicityChecker < storm : : RationalFunction > : : checkDerivative ( functionDecr , region ) ;
EXPECT_FALSE ( functionDecrRes . first ) ;
EXPECT_FALSE ( functionDecrRes . first ) ;
EXPECT_TRUE ( functionDecrRes . second ) ;
EXPECT_TRUE ( functionDecrRes . second ) ;
// Derivative p*q
// Derivative p*q
function = storm : : RationalFunction ( storm : : Polynomial ( parser . template parseMultivariatePolynomial < storm : : RationalFunctionCoefficient > ( " p " ) , cache ) )
* storm : : RationalFunction ( storm : : Polynomial ( parser . template parseMultivariatePolynomial < storm : : RationalFunctionCoefficient > ( " q " ) , cache ) ) ;
functionRes = storm : : analysis : : MonotonicityChecker < storm : : RationalFunction > : : checkDerivative ( function ) ;
function = functionP * functionQ ;
functionRes = storm : : analysis : : MonotonicityChecker < storm : : RationalFunction > : : checkDerivative ( function , region ) ;
EXPECT_TRUE ( functionRes . first ) ;
EXPECT_TRUE ( functionRes . first ) ;
EXPECT_FALSE ( functionRes . second ) ;
EXPECT_FALSE ( functionRes . second ) ;
}
}
@ -103,10 +131,24 @@ TEST(MonotonicityCheckerTest, Brp_with_bisimulation_no_samples) {
dtmc = storm : : api : : performBisimulationMinimization < storm : : RationalFunction > ( model , formulas , bisimType ) - > as < storm : : models : : sparse : : Dtmc < storm : : RationalFunction > > ( ) ;
dtmc = storm : : api : : performBisimulationMinimization < storm : : RationalFunction > ( model , formulas , bisimType ) - > as < storm : : models : : sparse : : Dtmc < storm : : RationalFunction > > ( ) ;
// Create the region
typename storm : : storage : : ParameterRegion < storm : : RationalFunction > : : Valuation lowerBoundaries ;
typename storm : : storage : : ParameterRegion < storm : : RationalFunction > : : Valuation upperBoundaries ;
std : : set < typename storm : : storage : : ParameterRegion < storm : : RationalFunction > : : VariableType > vars = storm : : models : : sparse : : getProbabilityParameters ( * dtmc ) ;
for ( auto var : vars ) {
typename storm : : storage : : ParameterRegion < storm : : RationalFunction > : : CoefficientType lb = storm : : utility : : convertNumber < typename storm : : storage : : ParameterRegion < storm : : RationalFunction > : : CoefficientType > ( 0 + 0.000001 ) ;
typename storm : : storage : : ParameterRegion < storm : : RationalFunction > : : CoefficientType ub = storm : : utility : : convertNumber < typename storm : : storage : : ParameterRegion < storm : : RationalFunction > : : CoefficientType > ( 1 - 0.000001 ) ;
lowerBoundaries . emplace ( std : : make_pair ( var , lb ) ) ;
upperBoundaries . emplace ( std : : make_pair ( var , ub ) ) ;
}
auto region = storm : : storage : : ParameterRegion < storm : : RationalFunction > ( std : : move ( lowerBoundaries ) , std : : move ( upperBoundaries ) ) ;
std : : vector < storm : : storage : : ParameterRegion < storm : : RationalFunction > > regions = { region } ;
ASSERT_EQ ( dtmc - > getNumberOfStates ( ) , 99ull ) ;
ASSERT_EQ ( dtmc - > getNumberOfStates ( ) , 99ull ) ;
ASSERT_EQ ( dtmc - > getNumberOfTransitions ( ) , 195ull ) ;
ASSERT_EQ ( dtmc - > getNumberOfTransitions ( ) , 195ull ) ;
storm : : analysis : : MonotonicityChecker < storm : : RationalFunction > monotonicityChecker = storm : : analysis : : MonotonicityChecker < storm : : RationalFunction > ( dtmc , formulas , true ) ;
storm : : analysis : : MonotonicityChecker < storm : : RationalFunction > monotonicityChecker = storm : : analysis : : MonotonicityChecker < storm : : RationalFunction > ( dtmc , formulas , regions , true ) ;
auto result = monotonicityChecker . checkMonotonicity ( ) ;
auto result = monotonicityChecker . checkMonotonicity ( ) ;
EXPECT_EQ ( 1 , result . size ( ) ) ;
EXPECT_EQ ( 1 , result . size ( ) ) ;
EXPECT_EQ ( 2 , result . begin ( ) - > second . size ( ) ) ;
EXPECT_EQ ( 2 , result . begin ( ) - > second . size ( ) ) ;
@ -138,10 +180,23 @@ TEST(MonotonicityCheckerTest, Brp_with_bisimulation_samples) {
dtmc = storm : : api : : performBisimulationMinimization < storm : : RationalFunction > ( model , formulas , bisimType ) - > as < storm : : models : : sparse : : Dtmc < storm : : RationalFunction > > ( ) ;
dtmc = storm : : api : : performBisimulationMinimization < storm : : RationalFunction > ( model , formulas , bisimType ) - > as < storm : : models : : sparse : : Dtmc < storm : : RationalFunction > > ( ) ;
// Create the region
typename storm : : storage : : ParameterRegion < storm : : RationalFunction > : : Valuation lowerBoundaries ;
typename storm : : storage : : ParameterRegion < storm : : RationalFunction > : : Valuation upperBoundaries ;
std : : set < typename storm : : storage : : ParameterRegion < storm : : RationalFunction > : : VariableType > vars = storm : : models : : sparse : : getProbabilityParameters ( * dtmc ) ;
for ( auto var : vars ) {
typename storm : : storage : : ParameterRegion < storm : : RationalFunction > : : CoefficientType lb = storm : : utility : : convertNumber < typename storm : : storage : : ParameterRegion < storm : : RationalFunction > : : CoefficientType > ( 0 + 0.000001 ) ;
typename storm : : storage : : ParameterRegion < storm : : RationalFunction > : : CoefficientType ub = storm : : utility : : convertNumber < typename storm : : storage : : ParameterRegion < storm : : RationalFunction > : : CoefficientType > ( 1 - 0.000001 ) ;
lowerBoundaries . emplace ( std : : make_pair ( var , lb ) ) ;
upperBoundaries . emplace ( std : : make_pair ( var , ub ) ) ;
}
auto region = storm : : storage : : ParameterRegion < storm : : RationalFunction > ( std : : move ( lowerBoundaries ) , std : : move ( upperBoundaries ) ) ;
std : : vector < storm : : storage : : ParameterRegion < storm : : RationalFunction > > regions = { region } ;
ASSERT_EQ ( dtmc - > getNumberOfStates ( ) , 99ull ) ;
ASSERT_EQ ( dtmc - > getNumberOfStates ( ) , 99ull ) ;
ASSERT_EQ ( dtmc - > getNumberOfTransitions ( ) , 195ull ) ;
ASSERT_EQ ( dtmc - > getNumberOfTransitions ( ) , 195ull ) ;
storm : : analysis : : MonotonicityChecker < storm : : RationalFunction > monotonicityChecker = storm : : analysis : : MonotonicityChecker < storm : : RationalFunction > ( dtmc , formulas , true , 50 ) ;
a uto monotonicityChecker = storm : : analysis : : MonotonicityChecker < storm : : RationalFunction > ( dtmc , formulas , region s , true , 50 ) ;
auto result = monotonicityChecker . checkMonotonicity ( ) ;
auto result = monotonicityChecker . checkMonotonicity ( ) ;
EXPECT_EQ ( 1 , result . size ( ) ) ;
EXPECT_EQ ( 1 , result . size ( ) ) ;
EXPECT_EQ ( 2 , result . begin ( ) - > second . size ( ) ) ;
EXPECT_EQ ( 2 , result . begin ( ) - > second . size ( ) ) ;