| 
					
					
						
							
						
					
					
				 | 
				@ -30,19 +30,32 @@ namespace storm { | 
			
		
		
	
		
			
				 | 
				 | 
				
 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				        template <typename ValueType> | 
				 | 
				 | 
				        template <typename ValueType> | 
			
		
		
	
		
			
				 | 
				 | 
				        std::map<storm::analysis::Lattice*, std::map<carl::Variable, std::pair<bool, bool>>> MonotonicityChecker<ValueType>::checkMonotonicity() { | 
				 | 
				 | 
				        std::map<storm::analysis::Lattice*, std::map<carl::Variable, std::pair<bool, bool>>> MonotonicityChecker<ValueType>::checkMonotonicity() { | 
			
		
		
	
		
			
				 | 
				 | 
				            bool maybeMonotone = true; | 
				 | 
				 | 
				 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            std::map<carl::Variable, std::pair<bool, bool>> maybeMonotone; | 
			
		
		
	
		
			
				 | 
				 | 
				            if (model->isOfType(storm::models::ModelType::Dtmc)) { | 
				 | 
				 | 
				            if (model->isOfType(storm::models::ModelType::Dtmc)) { | 
			
		
		
	
		
			
				 | 
				 | 
				                auto dtmcModel = model->as<storm::models::sparse::Dtmc<ValueType>>(); | 
				 | 
				 | 
				 | 
			
		
		
	
		
			
				 | 
				 | 
				                maybeMonotone = checkOnSamples(dtmcModel,3); | 
				 | 
				 | 
				 | 
			
		
		
	
		
			
				 | 
				 | 
				            } //TODO mdp
 | 
				 | 
				 | 
				 | 
			
		
		
	
		
			
				 | 
				 | 
				            if (maybeMonotone) { | 
				 | 
				 | 
				 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                auto dtmc = model->as<storm::models::sparse::Dtmc<ValueType>>(); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                maybeMonotone = checkOnSamples(dtmc,3); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            } else if (model->isOfType(storm::models::ModelType::Mdp)) { | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                auto mdp = model->as<storm::models::sparse::Mdp<ValueType>>(); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                maybeMonotone = checkOnSamples(mdp,3); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            } else { | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Unable to perform monotonicity analysis on the provided model type."); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            } | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            bool allNotMonotone = true; | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            for (auto itr = maybeMonotone.begin(); itr != maybeMonotone.end(); ++itr) { | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                if (itr->second.first || itr->second.second) { | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                    allNotMonotone = false; | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                } | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            } | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            if (!allNotMonotone) { | 
			
		
		
	
		
			
				 | 
				 | 
				                auto map = createLattice(); | 
				 | 
				 | 
				                auto map = createLattice(); | 
			
		
		
	
		
			
				 | 
				 | 
				                std::shared_ptr<storm::models::sparse::Model<ValueType>> sparseModel = model->as<storm::models::sparse::Model<ValueType>>(); | 
				 | 
				 | 
				                std::shared_ptr<storm::models::sparse::Model<ValueType>> sparseModel = model->as<storm::models::sparse::Model<ValueType>>(); | 
			
		
		
	
		
			
				 | 
				 | 
				                auto matrix = sparseModel->getTransitionMatrix(); | 
				 | 
				 | 
				                auto matrix = sparseModel->getTransitionMatrix(); | 
			
		
		
	
		
			
				 | 
				 | 
				                return checkMonotonicity(map, matrix); | 
				 | 
				 | 
				                return checkMonotonicity(map, matrix); | 
			
		
		
	
		
			
				 | 
				 | 
				            } else { | 
				 | 
				 | 
				            } else { | 
			
		
		
	
		
			
				 | 
				 | 
				                std::map<storm::analysis::Lattice*, std::map<carl::Variable, std::pair<bool, bool>>> result; | 
				 | 
				 | 
				                std::map<storm::analysis::Lattice*, std::map<carl::Variable, std::pair<bool, bool>>> result; | 
			
		
		
	
		
			
				 | 
				 | 
				                std::cout << "Not monotone" << std::endl; | 
				 | 
				 | 
				 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                STORM_PRINT(std::endl << "Not monotone in all parameters" << std::endl); | 
			
		
		
	
		
			
				 | 
				 | 
				                return result; | 
				 | 
				 | 
				                return result; | 
			
		
		
	
		
			
				 | 
				 | 
				            } | 
				 | 
				 | 
				            } | 
			
		
		
	
		
			
				 | 
				 | 
				        } | 
				 | 
				 | 
				        } | 
			
		
		
	
	
		
			
				| 
					
						
							
						
					
					
						
							
						
					
					
				 | 
				@ -86,6 +99,9 @@ namespace storm { | 
			
		
		
	
		
			
				 | 
				 | 
				                    STORM_PRINT("Result is constant" << std::endl); | 
				 | 
				 | 
				                    STORM_PRINT("Result is constant" << std::endl); | 
			
		
		
	
		
			
				 | 
				 | 
				                } else { | 
				 | 
				 | 
				                } else { | 
			
		
		
	
		
			
				 | 
				 | 
				                    for (auto itr2 = varsMonotone.begin(); itr2 != varsMonotone.end(); ++itr2) { | 
				 | 
				 | 
				                    for (auto itr2 = varsMonotone.begin(); itr2 != varsMonotone.end(); ++itr2) { | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                        if (!resultCheckOnSamples[itr2->first].first && !resultCheckOnSamples[itr2->first].second) { | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                            STORM_PRINT("  - Not monotone in: " << itr2->first << std::endl); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                        } else { | 
			
		
		
	
		
			
				 | 
				 | 
				                            if (itr2->second.first) { | 
				 | 
				 | 
				                            if (itr2->second.first) { | 
			
		
		
	
		
			
				 | 
				 | 
				                                STORM_PRINT("  - Monotone increasing in: " << itr2->first << std::endl); | 
				 | 
				 | 
				                                STORM_PRINT("  - Monotone increasing in: " << itr2->first << std::endl); | 
			
		
		
	
		
			
				 | 
				 | 
				                            } else { | 
				 | 
				 | 
				                            } else { | 
			
		
		
	
	
		
			
				| 
					
					
					
						
							
						
					
				 | 
				@ -97,6 +113,7 @@ namespace storm { | 
			
		
		
	
		
			
				 | 
				 | 
				                                STORM_PRINT("  - Do not know if monotone decreasing in: " << itr2->first << std::endl); | 
				 | 
				 | 
				                                STORM_PRINT("  - Do not know if monotone decreasing in: " << itr2->first << std::endl); | 
			
		
		
	
		
			
				 | 
				 | 
				                            } | 
				 | 
				 | 
				                            } | 
			
		
		
	
		
			
				 | 
				 | 
				                        } | 
				 | 
				 | 
				                        } | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                    } | 
			
		
		
	
		
			
				 | 
				 | 
				                    result.insert( | 
				 | 
				 | 
				                    result.insert( | 
			
		
		
	
		
			
				 | 
				 | 
				                            std::pair<storm::analysis::Lattice *, std::map<carl::Variable, std::pair<bool, bool>>>( | 
				 | 
				 | 
				                            std::pair<storm::analysis::Lattice *, std::map<carl::Variable, std::pair<bool, bool>>>( | 
			
		
		
	
		
			
				 | 
				 | 
				                                    lattice, varsMonotone)); | 
				 | 
				 | 
				                                    lattice, varsMonotone)); | 
			
		
		
	
	
		
			
				| 
					
					
					
						
							
						
					
				 | 
				@ -118,13 +135,13 @@ namespace storm { | 
			
		
		
	
		
			
				 | 
				 | 
				            std::tuple<storm::analysis::Lattice*, uint_fast64_t, uint_fast64_t> criticalTuple = extender->toLattice(formulas); | 
				 | 
				 | 
				            std::tuple<storm::analysis::Lattice*, uint_fast64_t, uint_fast64_t> criticalTuple = extender->toLattice(formulas); | 
			
		
		
	
		
			
				 | 
				 | 
				            std::map<storm::analysis::Lattice*, std::vector<std::shared_ptr<storm::expressions::BinaryRelationExpression>>> result; | 
				 | 
				 | 
				            std::map<storm::analysis::Lattice*, std::vector<std::shared_ptr<storm::expressions::BinaryRelationExpression>>> result; | 
			
		
		
	
		
			
				 | 
				 | 
				            if (model->isOfType(storm::models::ModelType::Dtmc)) { | 
				 | 
				 | 
				            if (model->isOfType(storm::models::ModelType::Dtmc)) { | 
			
		
		
	
		
			
				 | 
				 | 
				                auto dtmcModel = model->as<storm::models::sparse::Dtmc<ValueType>>(); | 
				 | 
				 | 
				 | 
			
		
		
	
		
			
				 | 
				 | 
				                auto assumptionChecker = storm::analysis::AssumptionChecker<ValueType>(formulas[0], dtmcModel, 3); | 
				 | 
				 | 
				 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                auto dtmc = model->as<storm::models::sparse::Dtmc<ValueType>>(); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                auto assumptionChecker = storm::analysis::AssumptionChecker<ValueType>(formulas[0], dtmc, 3); | 
			
		
		
	
		
			
				 | 
				 | 
				                auto assumptionMaker = storm::analysis::AssumptionMaker<ValueType>(extender, &assumptionChecker, sparseModel->getNumberOfStates(), validate); | 
				 | 
				 | 
				                auto assumptionMaker = storm::analysis::AssumptionMaker<ValueType>(extender, &assumptionChecker, sparseModel->getNumberOfStates(), validate); | 
			
		
		
	
		
			
				 | 
				 | 
				                result = assumptionMaker.makeAssumptions(std::get<0>(criticalTuple), std::get<1>(criticalTuple), std::get<2>(criticalTuple)); | 
				 | 
				 | 
				                result = assumptionMaker.makeAssumptions(std::get<0>(criticalTuple), std::get<1>(criticalTuple), std::get<2>(criticalTuple)); | 
			
		
		
	
		
			
				 | 
				 | 
				            } else if (model->isOfType(storm::models::ModelType::Dtmc)) { | 
				 | 
				 | 
				            } else if (model->isOfType(storm::models::ModelType::Dtmc)) { | 
			
		
		
	
		
			
				 | 
				 | 
				                auto mdpModel = model->as<storm::models::sparse::Mdp<ValueType>>(); | 
				 | 
				 | 
				 | 
			
		
		
	
		
			
				 | 
				 | 
				                auto assumptionChecker = storm::analysis::AssumptionChecker<ValueType>(formulas[0], mdpModel, 3); | 
				 | 
				 | 
				 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                auto mdp = model->as<storm::models::sparse::Mdp<ValueType>>(); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                auto assumptionChecker = storm::analysis::AssumptionChecker<ValueType>(formulas[0], mdp, 3); | 
			
		
		
	
		
			
				 | 
				 | 
				                auto assumptionMaker = storm::analysis::AssumptionMaker<ValueType>(extender, &assumptionChecker, sparseModel->getNumberOfStates(), validate); | 
				 | 
				 | 
				                auto assumptionMaker = storm::analysis::AssumptionMaker<ValueType>(extender, &assumptionChecker, sparseModel->getNumberOfStates(), validate); | 
			
		
		
	
		
			
				 | 
				 | 
				                result = assumptionMaker.makeAssumptions(std::get<0>(criticalTuple), std::get<1>(criticalTuple), std::get<2>(criticalTuple)); | 
				 | 
				 | 
				                result = assumptionMaker.makeAssumptions(std::get<0>(criticalTuple), std::get<1>(criticalTuple), std::get<2>(criticalTuple)); | 
			
		
		
	
		
			
				 | 
				 | 
				            } else { | 
				 | 
				 | 
				            } else { | 
			
		
		
	
	
		
			
				| 
					
					
					
						
							
						
					
				 | 
				@ -138,6 +155,8 @@ namespace storm { | 
			
		
		
	
		
			
				 | 
				 | 
				
 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				        template <typename ValueType> | 
				 | 
				 | 
				        template <typename ValueType> | 
			
		
		
	
		
			
				 | 
				 | 
				        std::map<carl::Variable, std::pair<bool, bool>> MonotonicityChecker<ValueType>::analyseMonotonicity(uint_fast64_t j, storm::analysis::Lattice* lattice, storm::storage::SparseMatrix<ValueType> matrix) { | 
				 | 
				 | 
				        std::map<carl::Variable, std::pair<bool, bool>> MonotonicityChecker<ValueType>::analyseMonotonicity(uint_fast64_t j, storm::analysis::Lattice* lattice, storm::storage::SparseMatrix<ValueType> matrix) { | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            storm::utility::Stopwatch analyseWatch(true); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				            std::map<carl::Variable, std::pair<bool, bool>> varsMonotone; | 
				 | 
				 | 
				            std::map<carl::Variable, std::pair<bool, bool>> varsMonotone; | 
			
		
		
	
		
			
				 | 
				 | 
				            std::ofstream myfile; | 
				 | 
				 | 
				            std::ofstream myfile; | 
			
		
		
	
		
			
				 | 
				 | 
				            std::string filename = "mc" + std::to_string(j) + ".dot"; | 
				 | 
				 | 
				            std::string filename = "mc" + std::to_string(j) + ".dot"; | 
			
		
		
	
	
		
			
				| 
					
						
							
						
					
					
						
							
						
					
					
				 | 
				@ -165,29 +184,38 @@ namespace storm { | 
			
		
		
	
		
			
				 | 
				 | 
				                    auto val = first.getValue(); | 
				 | 
				 | 
				                    auto val = first.getValue(); | 
			
		
		
	
		
			
				 | 
				 | 
				                    auto vars = val.gatherVariables(); | 
				 | 
				 | 
				                    auto vars = val.gatherVariables(); | 
			
		
		
	
		
			
				 | 
				 | 
				                    for (auto itr = vars.begin(); itr != vars.end(); ++itr) { | 
				 | 
				 | 
				                    for (auto itr = vars.begin(); itr != vars.end(); ++itr) { | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                        if (!resultCheckOnSamples[*itr].first && !resultCheckOnSamples[*itr].second) { | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                            if (varsMonotone.find(*itr) == varsMonotone.end()) { | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                varsMonotone[*itr].first = false; | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                varsMonotone[*itr].second = false; | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                            } | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                            color = "color = red, "; | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                        } else { | 
			
		
		
	
		
			
				 | 
				 | 
				                            if (varsMonotone.find(*itr) == varsMonotone.end()) { | 
				 | 
				 | 
				                            if (varsMonotone.find(*itr) == varsMonotone.end()) { | 
			
		
		
	
		
			
				 | 
				 | 
				                                varsMonotone[*itr].first = true; | 
				 | 
				 | 
				                                varsMonotone[*itr].first = true; | 
			
		
		
	
		
			
				 | 
				 | 
				                                varsMonotone[*itr].second = true; | 
				 | 
				 | 
				                                varsMonotone[*itr].second = true; | 
			
		
		
	
		
			
				 | 
				 | 
				                            } | 
				 | 
				 | 
				                            } | 
			
		
		
	
		
			
				 | 
				 | 
				                        std::pair<bool, bool>* value = &varsMonotone.find(*itr)->second; | 
				 | 
				 | 
				 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                            std::pair<bool, bool> *value = &varsMonotone.find(*itr)->second; | 
			
		
		
	
		
			
				 | 
				 | 
				                            std::pair<bool, bool> old = *value; | 
				 | 
				 | 
				                            std::pair<bool, bool> old = *value; | 
			
		
		
	
		
			
				 | 
				 | 
				
 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				                            for (auto itr2 = transitions.begin(); itr2 != transitions.end(); ++itr2) { | 
				 | 
				 | 
				                            for (auto itr2 = transitions.begin(); itr2 != transitions.end(); ++itr2) { | 
			
		
		
	
		
			
				 | 
				 | 
				                                for (auto itr3 = transitions.begin(); itr3 != transitions.end(); ++itr3) { | 
				 | 
				 | 
				                                for (auto itr3 = transitions.begin(); itr3 != transitions.end(); ++itr3) { | 
			
		
		
	
		
			
				 | 
				 | 
				                                    auto derivative2 = (*itr2).second.derivative(*itr); | 
				 | 
				 | 
				                                    auto derivative2 = (*itr2).second.derivative(*itr); | 
			
		
		
	
		
			
				 | 
				 | 
				                                    auto derivative3 = (*itr3).second.derivative(*itr); | 
				 | 
				 | 
				                                    auto derivative3 = (*itr3).second.derivative(*itr); | 
			
		
		
	
		
			
				 | 
				 | 
				                                STORM_LOG_THROW(derivative2.isConstant() && derivative3.isConstant(), storm::exceptions::NotSupportedException, "Expecting derivative to be constant"); | 
				 | 
				 | 
				 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                    STORM_LOG_THROW(derivative2.isConstant() && derivative3.isConstant(), | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                                    storm::exceptions::NotSupportedException, | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                                    "Expecting derivative to be constant"); | 
			
		
		
	
		
			
				 | 
				 | 
				
 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				                                    auto compare = lattice->compare((*itr2).first, (*itr3).first); | 
				 | 
				 | 
				                                    auto compare = lattice->compare((*itr2).first, (*itr3).first); | 
			
		
		
	
		
			
				 | 
				 | 
				
 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				                                    if (compare == storm::analysis::Lattice::ABOVE) { | 
				 | 
				 | 
				                                    if (compare == storm::analysis::Lattice::ABOVE) { | 
			
		
		
	
		
			
				 | 
				 | 
				                                        // As the first state (itr2) is above the second state (itr3) it is sufficient to look at the derivative of itr2.
 | 
				 | 
				 | 
				                                        // As the first state (itr2) is above the second state (itr3) it is sufficient to look at the derivative of itr2.
 | 
			
		
		
	
		
			
				 | 
				 | 
				                                    value->first &=derivative2.constantPart() >= 0; | 
				 | 
				 | 
				 | 
			
		
		
	
		
			
				 | 
				 | 
				                                    value->second &=derivative2.constantPart() <= 0; | 
				 | 
				 | 
				 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                        value->first &= derivative2.constantPart() >= 0; | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                        value->second &= derivative2.constantPart() <= 0; | 
			
		
		
	
		
			
				 | 
				 | 
				                                    } else if (compare == storm::analysis::Lattice::BELOW) { | 
				 | 
				 | 
				                                    } else if (compare == storm::analysis::Lattice::BELOW) { | 
			
		
		
	
		
			
				 | 
				 | 
				                                        // As the second state (itr3) is above the first state (itr2) it is sufficient to look at the derivative of itr3.
 | 
				 | 
				 | 
				                                        // As the second state (itr3) is above the first state (itr2) it is sufficient to look at the derivative of itr3.
 | 
			
		
		
	
		
			
				 | 
				 | 
				                                    value->first &=derivative3.constantPart() >= 0; | 
				 | 
				 | 
				 | 
			
		
		
	
		
			
				 | 
				 | 
				                                    value->second &=derivative3.constantPart() <= 0; | 
				 | 
				 | 
				 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                        value->first &= derivative3.constantPart() >= 0; | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                        value->second &= derivative3.constantPart() <= 0; | 
			
		
		
	
		
			
				 | 
				 | 
				                                    } else if (compare == storm::analysis::Lattice::SAME) { | 
				 | 
				 | 
				                                    } else if (compare == storm::analysis::Lattice::SAME) { | 
			
		
		
	
		
			
				 | 
				 | 
				                                        // Behaviour doesn't matter, as the states are at the same level.
 | 
				 | 
				 | 
				                                        // Behaviour doesn't matter, as the states are at the same level.
 | 
			
		
		
	
		
			
				 | 
				 | 
				                                    } else { | 
				 | 
				 | 
				                                    } else { | 
			
		
		
	
	
		
			
				| 
					
					
					
						
							
						
					
				 | 
				@ -208,6 +236,7 @@ namespace storm { | 
			
		
		
	
		
			
				 | 
				 | 
				                                color = "color = blue, "; | 
				 | 
				 | 
				                                color = "color = blue, "; | 
			
		
		
	
		
			
				 | 
				 | 
				                            } | 
				 | 
				 | 
				                            } | 
			
		
		
	
		
			
				 | 
				 | 
				                        } | 
				 | 
				 | 
				                        } | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                    } | 
			
		
		
	
		
			
				 | 
				 | 
				
 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				                    for (auto itr = transitions.begin(); itr != transitions.end(); ++itr) { | 
				 | 
				 | 
				                    for (auto itr = transitions.begin(); itr != transitions.end(); ++itr) { | 
			
		
		
	
		
			
				 | 
				 | 
				                        myfile << "\t" << i << " -> " << itr->first << "[" << color << "label=\"" << itr->second << "\"];" | 
				 | 
				 | 
				                        myfile << "\t" << i << " -> " << itr->first << "[" << color << "label=\"" << itr->second << "\"];" | 
			
		
		
	
	
		
			
				| 
					
					
					
						
							
						
					
				 | 
				@ -231,24 +260,42 @@ namespace storm { | 
			
		
		
	
		
			
				 | 
				 | 
				            myfile << "\t}" << std::endl; | 
				 | 
				 | 
				            myfile << "\t}" << std::endl; | 
			
		
		
	
		
			
				 | 
				 | 
				            myfile << "}" << std::endl; | 
				 | 
				 | 
				            myfile << "}" << std::endl; | 
			
		
		
	
		
			
				 | 
				 | 
				            myfile.close(); | 
				 | 
				 | 
				            myfile.close(); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            analyseWatch.stop(); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            STORM_PRINT(std::endl << "Time to check monotonicity based on the lattice: " << analyseWatch << "." << std::endl << std::endl); | 
			
		
		
	
		
			
				 | 
				 | 
				            return varsMonotone; | 
				 | 
				 | 
				            return varsMonotone; | 
			
		
		
	
		
			
				 | 
				 | 
				        } | 
				 | 
				 | 
				        } | 
			
		
		
	
		
			
				 | 
				 | 
				
 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				        template <typename ValueType> | 
				 | 
				 | 
				        template <typename ValueType> | 
			
		
		
	
		
			
				 | 
				 | 
				        bool MonotonicityChecker<ValueType>::checkOnSamples(std::shared_ptr<storm::models::sparse::Dtmc<ValueType>> model, uint_fast64_t numberOfSamples) { | 
				 | 
				 | 
				 | 
			
		
		
	
		
			
				 | 
				 | 
				            bool monDecr = true; | 
				 | 
				 | 
				 | 
			
		
		
	
		
			
				 | 
				 | 
				            bool monIncr = true; | 
				 | 
				 | 
				 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				        std::map<carl::Variable, std::pair<bool, bool>> MonotonicityChecker<ValueType>::checkOnSamples(std::shared_ptr<storm::models::sparse::Dtmc<ValueType>> model, uint_fast64_t numberOfSamples) { | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            storm::utility::Stopwatch samplesWatch(true); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            std::map<carl::Variable, std::pair<bool, bool>> result; | 
			
		
		
	
		
			
				 | 
				 | 
				
 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				            auto instantiator = storm::utility::ModelInstantiator<storm::models::sparse::Dtmc<ValueType>, storm::models::sparse::Dtmc<double>>(*model); | 
				 | 
				 | 
				            auto instantiator = storm::utility::ModelInstantiator<storm::models::sparse::Dtmc<ValueType>, storm::models::sparse::Dtmc<double>>(*model); | 
			
		
		
	
		
			
				 | 
				 | 
				            auto matrix = model->getTransitionMatrix(); | 
				 | 
				 | 
				            auto matrix = model->getTransitionMatrix(); | 
			
		
		
	
		
			
				 | 
				 | 
				            std::set<storm::RationalFunctionVariable> variables =  storm::models::sparse::getProbabilityParameters(*model); | 
				 | 
				 | 
				 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            std::set<carl::Variable> variables =  storm::models::sparse::getProbabilityParameters(*model); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            for (auto itr = variables.begin(); itr != variables.end(); ++itr) { | 
			
		
		
	
		
			
				 | 
				 | 
				                double previous = -1; | 
				 | 
				 | 
				                double previous = -1; | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                bool monDecr = true; | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                bool monIncr = true; | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				                for (auto i = 0; i < numberOfSamples; ++i) { | 
				 | 
				 | 
				                for (auto i = 0; i < numberOfSamples; ++i) { | 
			
		
		
	
		
			
				 | 
				 | 
				                    auto valuation = storm::utility::parametric::Valuation<ValueType>(); | 
				 | 
				 | 
				                    auto valuation = storm::utility::parametric::Valuation<ValueType>(); | 
			
		
		
	
		
			
				 | 
				 | 
				                for (auto itr = variables.begin(); itr != variables.end(); ++itr) { | 
				 | 
				 | 
				 | 
			
		
		
	
		
			
				 | 
				 | 
				                    // TODO: Type
 | 
				 | 
				 | 
				 | 
			
		
		
	
		
			
				 | 
				 | 
				                    auto val = std::pair<storm::RationalFunctionVariable, storm::RationalFunctionCoefficient>((*itr), storm::utility::convertNumber<storm::RationalFunctionCoefficient>(boost::lexical_cast<std::string>((i+1)/(double (numberOfSamples + 1))))); | 
				 | 
				 | 
				 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                    for (auto itr2 = variables.begin(); itr2 != variables.end(); ++itr2) { | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                        // Only change value for current variable
 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                        if ((*itr) == (*itr2)) { | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                            auto val = std::pair<carl::Variable, storm::RationalFunctionCoefficient>( | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                    (*itr2), storm::utility::convertNumber<storm::RationalFunctionCoefficient>( | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                            boost::lexical_cast<std::string>((i + 1) / (double(numberOfSamples + 1))))); | 
			
		
		
	
		
			
				 | 
				 | 
				                            valuation.insert(val); | 
				 | 
				 | 
				                            valuation.insert(val); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                        } else { | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                            auto val = std::pair<carl::Variable, storm::RationalFunctionCoefficient>( | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                    (*itr2), storm::utility::convertNumber<storm::RationalFunctionCoefficient>( | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                            boost::lexical_cast<std::string>((1) / (double(numberOfSamples + 1))))); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                            valuation.insert(val); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                        } | 
			
		
		
	
		
			
				 | 
				 | 
				                    } | 
				 | 
				 | 
				                    } | 
			
		
		
	
		
			
				 | 
				 | 
				                    storm::models::sparse::Dtmc<double> sampleModel = instantiator.instantiate(valuation); | 
				 | 
				 | 
				                    storm::models::sparse::Dtmc<double> sampleModel = instantiator.instantiate(valuation); | 
			
		
		
	
		
			
				 | 
				 | 
				                    auto checker = storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>>(sampleModel); | 
				 | 
				 | 
				                    auto checker = storm::modelchecker::SparseDtmcPrctlModelChecker<storm::models::sparse::Dtmc<double>>(sampleModel); | 
			
		
		
	
	
		
			
				| 
					
						
							
						
					
					
						
							
						
					
					
				 | 
				@ -281,8 +328,83 @@ namespace storm { | 
			
		
		
	
		
			
				 | 
				 | 
				                    } | 
				 | 
				 | 
				                    } | 
			
		
		
	
		
			
				 | 
				 | 
				                    previous = initial; | 
				 | 
				 | 
				                    previous = initial; | 
			
		
		
	
		
			
				 | 
				 | 
				                } | 
				 | 
				 | 
				                } | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                result.insert(std::pair<carl::Variable, std::pair<bool, bool>>(*itr, std::pair<bool,bool>(monIncr, monDecr))); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            } | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            samplesWatch.stop(); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            STORM_PRINT(std::endl << "Time to check monotonicity on samples: " << samplesWatch << "." << std::endl << std::endl); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            resultCheckOnSamples = result; | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            return result; | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				        } | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				        template <typename ValueType> | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				        std::map<carl::Variable, std::pair<bool, bool>> MonotonicityChecker<ValueType>::checkOnSamples(std::shared_ptr<storm::models::sparse::Mdp<ValueType>> model, uint_fast64_t numberOfSamples) { | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            storm::utility::Stopwatch samplesWatch(true); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            std::map<carl::Variable, std::pair<bool, bool>> result; | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            auto instantiator = storm::utility::ModelInstantiator<storm::models::sparse::Mdp<ValueType>, storm::models::sparse::Mdp<double>>(*model); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            auto matrix = model->getTransitionMatrix(); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            std::set<carl::Variable> variables =  storm::models::sparse::getProbabilityParameters(*model); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            for (auto itr = variables.begin(); itr != variables.end(); ++itr) { | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                double previous = -1; | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                bool monDecr = true; | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                bool monIncr = true; | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                for (auto i = 0; i < numberOfSamples; ++i) { | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                    auto valuation = storm::utility::parametric::Valuation<ValueType>(); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                    for (auto itr2 = variables.begin(); itr2 != variables.end(); ++itr2) { | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                        // Only change value for current variable
 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                        if ((*itr) == (*itr2)) { | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                            auto val = std::pair<carl::Variable, storm::RationalFunctionCoefficient>( | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                    (*itr2), storm::utility::convertNumber<storm::RationalFunctionCoefficient>( | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                            boost::lexical_cast<std::string>((i + 1) / (double(numberOfSamples + 1))))); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                            valuation.insert(val); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                        } else { | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                            auto val = std::pair<carl::Variable, storm::RationalFunctionCoefficient>( | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                    (*itr2), storm::utility::convertNumber<storm::RationalFunctionCoefficient>( | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                            boost::lexical_cast<std::string>((1) / (double(numberOfSamples + 1))))); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                            valuation.insert(val); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                        } | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                    } | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                    storm::models::sparse::Mdp<double> sampleModel = instantiator.instantiate(valuation); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                    auto checker = storm::modelchecker::SparseMdpPrctlModelChecker<storm::models::sparse::Mdp<double>>(sampleModel); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                    std::unique_ptr<storm::modelchecker::CheckResult> checkResult; | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                    auto formula = formulas[0]; | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                    if (formula->isProbabilityOperatorFormula() && | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                        formula->asProbabilityOperatorFormula().getSubformula().isUntilFormula()) { | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                        const storm::modelchecker::CheckTask<storm::logic::UntilFormula, double> checkTask = storm::modelchecker::CheckTask<storm::logic::UntilFormula, double>( | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                (*formula).asProbabilityOperatorFormula().getSubformula().asUntilFormula()); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                        checkResult = checker.computeUntilProbabilities(Environment(), checkTask); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                    } else if (formula->isProbabilityOperatorFormula() && | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                               formula->asProbabilityOperatorFormula().getSubformula().isEventuallyFormula()) { | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                        const storm::modelchecker::CheckTask<storm::logic::EventuallyFormula, double> checkTask = storm::modelchecker::CheckTask<storm::logic::EventuallyFormula, double>( | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                (*formula).asProbabilityOperatorFormula().getSubformula().asEventuallyFormula()); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                        checkResult = checker.computeReachabilityProbabilities(Environment(), checkTask); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                    } else { | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                        STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                                        "Expecting until or eventually formula"); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                    } | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                    auto quantitativeResult = checkResult->asExplicitQuantitativeCheckResult<double>(); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                    std::vector<double> values = quantitativeResult.getValueVector(); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                    auto initialStates = model->getInitialStates(); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                    double initial = 0; | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                    for (auto i = initialStates.getNextSetIndex(0); i < model->getNumberOfStates(); i = initialStates.getNextSetIndex(i+1)) { | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                        initial += values[i]; | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                    } | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                    if (previous != -1) { | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                        monDecr &= previous >= initial; | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                        monIncr &= previous <= initial; | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                    } | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                    previous = initial; | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                } | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				                result.insert(std::pair<carl::Variable, std::pair<bool, bool>>(*itr, std::pair<bool,bool>(monIncr, monDecr))); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            } | 
			
		
		
	
		
			
				 | 
				 | 
				
 | 
				 | 
				 | 
				
 | 
			
		
		
	
		
			
				 | 
				 | 
				            bool result = monDecr || monIncr; | 
				 | 
				 | 
				 | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            samplesWatch.stop(); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            STORM_PRINT(std::endl << "Time to check monotonicity on samples: " << samplesWatch << "." << std::endl << std::endl); | 
			
		
		
	
		
			
				 | 
				 | 
				 | 
				 | 
				 | 
				            resultCheckOnSamples = result; | 
			
		
		
	
		
			
				 | 
				 | 
				            return result; | 
				 | 
				 | 
				            return result; | 
			
		
		
	
		
			
				 | 
				 | 
				        } | 
				 | 
				 | 
				        } | 
			
		
		
	
		
			
				 | 
				 | 
				
 | 
				 | 
				 | 
				
 | 
			
		
		
	
	
		
			
				| 
					
						
							
						
					
					
					
				 | 
				
  |