diff --git a/src/storm-pars/analysis/AssumptionMaker.cpp b/src/storm-pars/analysis/AssumptionMaker.cpp index deb3913cd..ceb05ea72 100644 --- a/src/storm-pars/analysis/AssumptionMaker.cpp +++ b/src/storm-pars/analysis/AssumptionMaker.cpp @@ -7,8 +7,7 @@ namespace storm { namespace analysis { template - AssumptionMaker::AssumptionMaker(storm::analysis::LatticeExtender* latticeExtender, storm::analysis::AssumptionChecker* assumptionChecker, uint_fast64_t numberOfStates, bool validate) { - this->latticeExtender = latticeExtender; + AssumptionMaker::AssumptionMaker(storm::analysis::AssumptionChecker* assumptionChecker, uint_fast64_t numberOfStates, bool validate) { this->numberOfStates = numberOfStates; this->assumptionChecker = assumptionChecker; this->validate = validate; @@ -18,100 +17,40 @@ namespace storm { } } - template - std::map>> - AssumptionMaker::makeAssumptions(storm::analysis::Lattice *lattice, uint_fast64_t critical1, - uint_fast64_t critical2) { - std::map>> result; - - std::vector> emptySet; - if (critical1 == numberOfStates || critical2 == numberOfStates) { - result.insert(std::pair>>(lattice, emptySet)); - } else { - storm::expressions::Variable var1 = expressionManager->getVariable(std::to_string(critical1)); - storm::expressions::Variable var2 = expressionManager->getVariable(std::to_string(critical2)); - - std::vector> assumptions; - auto myMap = createAssumptions(var1, var2, new Lattice(lattice), assumptions); - result.insert(myMap.begin(), myMap.end()); - - std::vector> assumptions2; - myMap = createAssumptions(var2, var1, new Lattice(lattice), assumptions2); - result.insert(myMap.begin(), myMap.end()); - if (result.size() == 0) { - // No assumptions could be made, all not valid based on sampling, therefore returning original lattice - result.insert(std::pair>>(lattice, emptySet)); - } else { - delete lattice; - } - } - return result; - } - - template - std::map>> AssumptionMaker::runRecursive(storm::analysis::Lattice* lattice, std::vector> assumptions) { - std::map>> result; - // only the last assumption is new - std::tuple criticalTriple = this->latticeExtender->extendLattice(lattice, assumptions.back()); - - if (validate && assumptionChecker->validated(assumptions.back())) { - assert (assumptionChecker->valid(assumptions.back())); - assumptions.pop_back(); - } - - if (std::get<1>(criticalTriple) == numberOfStates) { - result.insert(std::pair>>(lattice, assumptions)); - } else { - auto val1 = std::get<1>(criticalTriple); - auto val2 = std::get<2>(criticalTriple); - storm::expressions::Variable var1 = expressionManager->getVariable(std::to_string(val1)); - storm::expressions::Variable var2 = expressionManager->getVariable(std::to_string(val2)); - // TODO: check of in lattice de relatie niet al andersom bestaat - - assert(lattice->compare(val1, val2) == storm::analysis::Lattice::UNKNOWN); - auto latticeCopy = new Lattice(lattice); - std::vector> assumptionsCopy = std::vector>( - assumptions); - auto myMap = createAssumptions(var1, var2, latticeCopy, assumptionsCopy); - result.insert(myMap.begin(), myMap.end()); + template + std::map, bool> AssumptionMaker::createAndCheckAssumption(uint_fast64_t val1, uint_fast64_t val2, storm::analysis::Lattice* lattice) { + std::map, bool> result; + + storm::expressions::Variable var1 = expressionManager->getVariable(std::to_string(val1)); + storm::expressions::Variable var2 = expressionManager->getVariable(std::to_string(val2)); + + std::shared_ptr assumption1 + = std::make_shared(storm::expressions::BinaryRelationExpression(*expressionManager, expressionManager->getBooleanType(), + var1.getExpression().getBaseExpressionPointer(), var2.getExpression().getBaseExpressionPointer(), + storm::expressions::BinaryRelationExpression::RelationType::GreaterOrEqual)); + bool result1 = (validate && assumptionChecker->validateAssumption(assumption1, lattice) && assumptionChecker->valid(assumption1)); + result[assumption1] = result1; + + std::shared_ptr assumption2 + = std::make_shared(storm::expressions::BinaryRelationExpression(*expressionManager, expressionManager->getBooleanType(), + var2.getExpression().getBaseExpressionPointer(), var1.getExpression().getBaseExpressionPointer(), + storm::expressions::BinaryRelationExpression::RelationType::GreaterOrEqual)); + bool result2 = (validate && assumptionChecker->validateAssumption(assumption2, lattice) && assumptionChecker->valid(assumption2)); + result[assumption2] = result2; - myMap = createAssumptions(var2, var1, lattice, assumptions); - result.insert(myMap.begin(), myMap.end()); - } return result; } template - std::map>> AssumptionMaker::createAssumptions(storm::expressions::Variable var1, storm::expressions::Variable var2, storm::analysis::Lattice* lattice, std::vector> assumptions) { - std::map>> result; - - std::shared_ptr assumption - = std::make_shared(storm::expressions::BinaryRelationExpression(*expressionManager, expressionManager->getBooleanType(), - var1.getExpression().getBaseExpressionPointer(), var2.getExpression().getBaseExpressionPointer(), - storm::expressions::BinaryRelationExpression::RelationType::GreaterOrEqual)); - if (assumptionChecker->checkOnSamples(assumption)) { - if (validate) { - assumptionChecker->validateAssumption(assumption, lattice); - if (!assumptionChecker->validated(assumption) || assumptionChecker->valid(assumption)) { - assumptions.push_back( - std::shared_ptr(assumption)); - result = (runRecursive(lattice, assumptions)); - } else if (assumptionChecker->validated(assumption) && !assumptionChecker->valid(assumption)) { - delete lattice; - } - } else { - assumptions.push_back(std::shared_ptr(assumption)); - result = (runRecursive(lattice, assumptions)); - } - - - } else { - delete lattice; - } - - return result; + std::shared_ptr AssumptionMaker::createEqualAssumption(uint_fast64_t val1, uint_fast64_t val2) { + storm::expressions::Variable var1 = expressionManager->getVariable(std::to_string(val1)); + storm::expressions::Variable var2 = expressionManager->getVariable(std::to_string(val2)); + return std::make_shared(storm::expressions::BinaryRelationExpression(*expressionManager, expressionManager->getBooleanType(), + var1.getExpression().getBaseExpressionPointer(), var2.getExpression().getBaseExpressionPointer(), + storm::expressions::BinaryRelationExpression::RelationType::Equal)); } + template class AssumptionMaker; } } diff --git a/src/storm-pars/analysis/AssumptionMaker.h b/src/storm-pars/analysis/AssumptionMaker.h index 1381d4ad0..190559a72 100644 --- a/src/storm-pars/analysis/AssumptionMaker.h +++ b/src/storm-pars/analysis/AssumptionMaker.h @@ -20,31 +20,18 @@ namespace storm { public: /*! * Constructs AssumptionMaker based on the lattice extender, the assumption checker and number of states of the model. - * + * TODO * @param latticeExtender The LatticeExtender which needs the assumptions made by the AssumptionMaker. * @param checker The AssumptionChecker which checks the assumptions at sample points. * @param numberOfStates The number of states of the model. */ - AssumptionMaker(storm::analysis::LatticeExtender* latticeExtender, storm::analysis::AssumptionChecker* checker, uint_fast64_t numberOfStates, bool validate); + AssumptionMaker( storm::analysis::AssumptionChecker* checker, uint_fast64_t numberOfStates, bool validate); - /*! - * Make the assumptions given a lattice and two states which could not be added to the lattice. Returns when no more assumptions can be made. - * - * @param lattice The lattice on which assumptions are needed to allow further extension. - * @param critical1 State number - * @param critical2 State number - * @return A mapping from pointers to different lattices and assumptions made to create the specific lattice. - */ - std::map>> makeAssumptions( - storm::analysis::Lattice *lattice, uint_fast64_t critical1, uint_fast64_t critical2); - - private: - std::map>> runRecursive(storm::analysis::Lattice* lattice, std::vector> assumptions); + std::map, bool> createAndCheckAssumption(uint_fast64_t val1, uint_fast64_t val2, storm::analysis::Lattice* lattice); - std::map>> createAssumptions(storm::expressions::Variable var1, storm::expressions::Variable var2, storm::analysis::Lattice* lattice,std::vector> assumptions); - - storm::analysis::LatticeExtender* latticeExtender; + std::shared_ptr createEqualAssumption(uint_fast64_t val1, uint_fast64_t val2); + private: storm::analysis::AssumptionChecker* assumptionChecker; std::shared_ptr expressionManager; @@ -58,3 +45,4 @@ namespace storm { } } #endif //STORM_ASSUMPTIONMAKER_H + diff --git a/src/storm-pars/analysis/Lattice.cpp b/src/storm-pars/analysis/Lattice.cpp index dbf2c0964..e015358cb 100644 --- a/src/storm-pars/analysis/Lattice.cpp +++ b/src/storm-pars/analysis/Lattice.cpp @@ -114,6 +114,10 @@ namespace storm { below->above.insert(above); } + void Lattice::mergeNodes(storm::analysis::Lattice::Node *n1, storm::analysis::Lattice::Node * n2) { + // TODO + } + int Lattice::compare(uint_fast64_t state1, uint_fast64_t state2) { return compare(getNode(state1), getNode(state2)); } diff --git a/src/storm-pars/analysis/Lattice.h b/src/storm-pars/analysis/Lattice.h index 37a86ea5e..b92570e65 100644 --- a/src/storm-pars/analysis/Lattice.h +++ b/src/storm-pars/analysis/Lattice.h @@ -61,6 +61,8 @@ namespace storm { */ void addRelationNodes(storm::analysis::Lattice::Node *above, storm::analysis::Lattice::Node * below); + void mergeNodes(storm::analysis::Lattice::Node *n1, storm::analysis::Lattice::Node * n2); + /*! * Compares the level of the nodes of the states. * Behaviour unknown when one or more of the states doesnot occur at any Node in the Lattice. diff --git a/src/storm-pars/analysis/LatticeExtender.cpp b/src/storm-pars/analysis/LatticeExtender.cpp index acb2a8952..004418d57 100644 --- a/src/storm-pars/analysis/LatticeExtender.cpp +++ b/src/storm-pars/analysis/LatticeExtender.cpp @@ -111,9 +111,34 @@ namespace storm { if (assumption != nullptr) { storm::expressions::BinaryRelationExpression expr = *assumption; STORM_LOG_THROW(expr.getRelationType() == - storm::expressions::BinaryRelationExpression::RelationType::GreaterOrEqual, - storm::exceptions::NotImplementedException, "Only GreaterOrEqual assumptions allowed"); - if (expr.getFirstOperand()->isVariable() && expr.getSecondOperand()->isVariable()) { + storm::expressions::BinaryRelationExpression::RelationType::GreaterOrEqual + || expr.getRelationType() == + storm::expressions::BinaryRelationExpression::RelationType::Equal, + storm::exceptions::NotImplementedException, "Only GreaterOrEqual or Equal assumptions allowed"); + if (expr.getRelationType() == storm::expressions::BinaryRelationExpression::RelationType::Equal) { + assert (expr.getFirstOperand()->isVariable() && expr.getSecondOperand()->isVariable()); + storm::expressions::Variable var1 = expr.getFirstOperand()->asVariableExpression().getVariable(); + storm::expressions::Variable var2 = expr.getSecondOperand()->asVariableExpression().getVariable(); + auto val1 = std::stoul(var1.getName(), nullptr, 0); + auto val2 = std::stoul(var2.getName(), nullptr, 0); + auto comp = lattice->compare(val1, val2); + assert (comp == storm::analysis::Lattice::UNKNOWN || comp == storm::analysis::Lattice::SAME); + storm::analysis::Lattice::Node *n1 = lattice->getNode(val1); + storm::analysis::Lattice::Node *n2 = lattice->getNode(val2); + + if (n1 != nullptr && n2 != nullptr) { + lattice->mergeNodes(n1, n2); + } else if (n1 != nullptr) { + lattice->addToNode(val2, n1); + } else if (n2 != nullptr) { + lattice->addToNode(val1, n2); + } else { + lattice->add(val1); + lattice->addToNode(val2, lattice->getNode(val1)); + + } + } else { + assert (expr.getFirstOperand()->isVariable() && expr.getSecondOperand()->isVariable()); storm::expressions::Variable largest = expr.getFirstOperand()->asVariableExpression().getVariable(); storm::expressions::Variable smallest = expr.getSecondOperand()->asVariableExpression().getVariable(); if (lattice->compare(std::stoul(largest.getName(), nullptr, 0), @@ -127,7 +152,8 @@ namespace storm { if (n1 != nullptr && n2 != nullptr) { lattice->addRelationNodes(n1, n2); } else if (n1 != nullptr) { - lattice->addBetween(std::stoul(smallest.getName(), nullptr, 0), n1, lattice->getBottom()); + lattice->addBetween(std::stoul(smallest.getName(), nullptr, 0), n1, + lattice->getBottom()); } else if (n2 != nullptr) { lattice->addBetween(std::stoul(largest.getName(), nullptr, 0), lattice->getTop(), n2); } else { diff --git a/src/storm-pars/analysis/MonotonicityChecker.cpp b/src/storm-pars/analysis/MonotonicityChecker.cpp index b6178dfa5..56daab152 100644 --- a/src/storm-pars/analysis/MonotonicityChecker.cpp +++ b/src/storm-pars/analysis/MonotonicityChecker.cpp @@ -27,6 +27,10 @@ namespace storm { this->formulas = formulas; this->validate = validate; this->resultCheckOnSamples = std::map>(); + if (model != nullptr) { + std::shared_ptr> sparseModel = model->as>(); + this->extender = new storm::analysis::LatticeExtender(sparseModel); + } } template @@ -124,7 +128,7 @@ namespace storm { } finalCheckWatch.stop(); - STORM_PRINT(std::endl << "Time for monotonicitycheck on lattice: " << finalCheckWatch << "." << std::endl << std::endl); + STORM_PRINT(std::endl << "Time for monotonicity check on lattice: " << finalCheckWatch << "." << std::endl << std::endl); return result; } @@ -132,29 +136,114 @@ namespace storm { std::map>> MonotonicityChecker::createLattice() { // Transform to Lattices storm::utility::Stopwatch latticeWatch(true); - std::shared_ptr> sparseModel = model->as>(); - storm::analysis::LatticeExtender *extender = new storm::analysis::LatticeExtender(sparseModel); std::tuple criticalTuple = extender->toLattice(formulas); + std::map>> result; - if (model->isOfType(storm::models::ModelType::Dtmc)) { - auto dtmc = model->as>(); - auto assumptionChecker = storm::analysis::AssumptionChecker(formulas[0], dtmc, 3); - auto assumptionMaker = storm::analysis::AssumptionMaker(extender, &assumptionChecker, sparseModel->getNumberOfStates(), validate); - result = assumptionMaker.makeAssumptions(std::get<0>(criticalTuple), std::get<1>(criticalTuple), std::get<2>(criticalTuple)); - } else if (model->isOfType(storm::models::ModelType::Dtmc)) { - auto mdp = model->as>(); - auto assumptionChecker = storm::analysis::AssumptionChecker(formulas[0], mdp, 3); - auto assumptionMaker = storm::analysis::AssumptionMaker(extender, &assumptionChecker, sparseModel->getNumberOfStates(), validate); - result = assumptionMaker.makeAssumptions(std::get<0>(criticalTuple), std::get<1>(criticalTuple), std::get<2>(criticalTuple)); + + auto val1 = std::get<1>(criticalTuple); + auto val2 = std::get<2>(criticalTuple); + auto numberOfStates = model->getNumberOfStates(); + std::vector> assumptions; + + if (val1 == numberOfStates && val2 == numberOfStates) { + result.insert(std::pair>>(std::get<0>(criticalTuple), assumptions)); + } else if (val1 != numberOfStates && val2 != numberOfStates) { + + storm::analysis::AssumptionChecker *assumptionChecker; + if (model->isOfType(storm::models::ModelType::Dtmc)) { + auto dtmc = model->as>(); + assumptionChecker = new storm::analysis::AssumptionChecker(formulas[0], dtmc, 3); + } else if (model->isOfType(storm::models::ModelType::Mdp)) { + auto mdp = model->as>(); + assumptionChecker = new storm::analysis::AssumptionChecker(formulas[0], mdp, 3); + } else { + STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, + "Unable to perform monotonicity analysis on the provided model type."); + } + auto assumptionMaker = new storm::analysis::AssumptionMaker(assumptionChecker, numberOfStates, validate); + result = extendLatticeWithAssumptions(std::get<0>(criticalTuple), assumptionMaker, val1, val2, assumptions); } else { - STORM_LOG_THROW(false, storm::exceptions::InvalidOperationException, "Unable to perform monotonicity analysis on the provided model type."); + assert(false); } - latticeWatch.stop(); STORM_PRINT(std::endl << "Total time for lattice creation: " << latticeWatch << "." << std::endl << std::endl); return result; } + template + std::map>> MonotonicityChecker::extendLatticeWithAssumptions(storm::analysis::Lattice* lattice, storm::analysis::AssumptionMaker* assumptionMaker, uint_fast64_t val1, uint_fast64_t val2, std::vector> assumptions) { + std::map>> result; + + auto numberOfStates = model->getNumberOfStates(); + if (val1 == numberOfStates || val2 == numberOfStates) { + assert (val1 == val2); + result.insert(std::pair>>(lattice, assumptions)); + } else { + auto assumptionPair = assumptionMaker->createAndCheckAssumption(val1, val2, lattice); + assert (assumptionPair.size() == 2); + auto itr = assumptionPair.begin(); + auto assumption1 = *itr; + ++itr; + auto assumption2 = *itr; + + if (!assumption1.second && !assumption2.second) { + // TODO check op lattice of er nog monotonicity is + auto assumptionsCopy = std::vector>(assumptions); + auto latticeCopy = new storm::analysis::Lattice(lattice); + assumptions.push_back(assumption1.first); + assumptionsCopy.push_back(assumption2.first); + + auto criticalTuple = extender->extendLattice(lattice, assumption1.first); + if (somewhereMonotonicity(std::get<0>(criticalTuple))) { + auto map = extendLatticeWithAssumptions(std::get<0>(criticalTuple), assumptionMaker, std::get<1>(criticalTuple), std::get<2>(criticalTuple), assumptions); + result.insert(map.begin(), map.end()); + } + + + criticalTuple = extender->extendLattice(latticeCopy, assumption2.first); + if (somewhereMonotonicity(std::get<0>(criticalTuple))) { + auto map = extendLatticeWithAssumptions(std::get<0>(criticalTuple), assumptionMaker, + std::get<1>(criticalTuple), std::get<2>(criticalTuple), + assumptionsCopy); + result.insert(map.begin(), map.end()); + } + } else if (assumption1.second && assumption2.second) { + auto assumption = assumptionMaker->createEqualAssumption(val1, val2); + if (!validate) { + assumptions.push_back(assumption); + } + // if validate is true and both hold, then they must be valid, so no need to add to assumptions + auto criticalTuple = extender->extendLattice(lattice, assumption); + if (somewhereMonotonicity(std::get<0>(criticalTuple))) { + result = extendLatticeWithAssumptions(std::get<0>(criticalTuple), assumptionMaker, std::get<1>(criticalTuple), std::get<2>(criticalTuple), assumptions); + } + } else if (assumption1.second) { + if (!validate) { + assumptions.push_back(assumption1.first); + } + // if validate is true and both hold, then they must be valid, so no need to add to assumptions + + auto criticalTuple = extender->extendLattice(lattice, assumption1.first); + + if (somewhereMonotonicity(std::get<0>(criticalTuple))) { + result = extendLatticeWithAssumptions(std::get<0>(criticalTuple), assumptionMaker, std::get<1>(criticalTuple), std::get<2>(criticalTuple), assumptions); + } + + } else { + assert (assumption2.second); + if (!validate) { + assumptions.push_back(assumption2.first); + } + // if validate is true and both hold, then they must be valid, so no need to add to assumptions + auto criticalTuple = extender->extendLattice(lattice, assumption2.first); + if (somewhereMonotonicity(std::get<0>(criticalTuple))) { + result = extendLatticeWithAssumptions(std::get<0>(criticalTuple), assumptionMaker, std::get<1>(criticalTuple), std::get<2>(criticalTuple), assumptions); + } + } + } + return result; + } + template std::map> MonotonicityChecker::analyseMonotonicity(uint_fast64_t j, storm::analysis::Lattice* lattice, storm::storage::SparseMatrix matrix) { storm::utility::Stopwatch analyseWatch(true); @@ -220,6 +309,7 @@ namespace storm { value->first &= derivative3.constantPart() >= 0; value->second &= derivative3.constantPart() <= 0; } else if (compare == storm::analysis::Lattice::SAME) { + // TODO: klopt dit // Behaviour doesn't matter, as the states are at the same level. } else { // As the relation between the states is unknown, we can't claim anything about the monotonicity. @@ -269,6 +359,73 @@ namespace storm { return varsMonotone; } + template + bool MonotonicityChecker::somewhereMonotonicity(storm::analysis::Lattice* lattice) { + std::shared_ptr> sparseModel = model->as>(); + auto matrix = sparseModel->getTransitionMatrix(); + + // TODO: tussenresultaten hergebruiken + std::map> varsMonotone; + + for (uint_fast64_t i = 0; i < matrix.getColumnCount(); ++i) { + // go over all rows + auto row = matrix.getRow(i); + auto first = (*row.begin()); + if (first.getValue() != ValueType(1)) { + std::map transitions; + + for (auto itr = row.begin(); itr != row.end(); ++itr) { + transitions.insert(std::pair((*itr).getColumn(), (*itr).getValue())); + } + + auto val = first.getValue(); + auto vars = val.gatherVariables(); + for (auto itr = vars.begin(); itr != vars.end(); ++itr) { + if (varsMonotone.find(*itr) == varsMonotone.end()) { + varsMonotone[*itr].first = true; + varsMonotone[*itr].second = true; + } + std::pair *value = &varsMonotone.find(*itr)->second; + std::pair old = *value; + + for (auto itr2 = transitions.begin(); itr2 != transitions.end(); ++itr2) { + for (auto itr3 = transitions.begin(); itr3 != transitions.end(); ++itr3) { + auto derivative2 = (*itr2).second.derivative(*itr); + auto derivative3 = (*itr3).second.derivative(*itr); + STORM_LOG_THROW(derivative2.isConstant() && derivative3.isConstant(), + storm::exceptions::NotSupportedException, + "Expecting derivative to be constant"); + + auto compare = lattice->compare((*itr2).first, (*itr3).first); + + 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. + value->first &= derivative2.constantPart() >= 0; + value->second &= derivative2.constantPart() <= 0; + } 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. + value->first &= derivative3.constantPart() >= 0; + value->second &= derivative3.constantPart() <= 0; + } else if (compare == storm::analysis::Lattice::SAME) { + // Behaviour doesn't matter, as the states are at the same level. + } else { + // As the relation between the states is unknown, we don't do anything + } + } + } + } + } + } + + bool result = false; + + for (auto itr = varsMonotone.begin(); !result && itr != varsMonotone.end(); ++itr) { + result = itr->second.first || itr->second.second; + } + return result; + } + + template std::map> MonotonicityChecker::checkOnSamples(std::shared_ptr> model, uint_fast64_t numberOfSamples) { storm::utility::Stopwatch samplesWatch(true); diff --git a/src/storm-pars/analysis/MonotonicityChecker.h b/src/storm-pars/analysis/MonotonicityChecker.h index 44676aa2c..c1590dd09 100644 --- a/src/storm-pars/analysis/MonotonicityChecker.h +++ b/src/storm-pars/analysis/MonotonicityChecker.h @@ -7,6 +7,8 @@ #include #include "Lattice.h" +#include "LatticeExtender.h" +#include "AssumptionMaker.h" #include "storm/storage/expressions/BinaryRelationExpression.h" #include "carl/core/Variable.h" @@ -42,6 +44,14 @@ namespace storm { */ std::map>> checkMonotonicity(); + /*! + * TODO + * @param lattice + * @param matrix + * @return + */ + bool somewhereMonotonicity(storm::analysis::Lattice* lattice) ; + private: //TODO: variabele type std::map> analyseMonotonicity(uint_fast64_t i, storm::analysis::Lattice* lattice, storm::storage::SparseMatrix matrix) ; @@ -52,6 +62,8 @@ namespace storm { std::map> checkOnSamples(std::shared_ptr> model, uint_fast64_t numberOfSamples); + std::map>> extendLatticeWithAssumptions(storm::analysis::Lattice* lattice, storm::analysis::AssumptionMaker* assumptionMaker, uint_fast64_t val1, uint_fast64_t val2, std::vector> assumptions); + std::shared_ptr model; std::vector> formulas; @@ -59,6 +71,8 @@ namespace storm { bool validate; std::map> resultCheckOnSamples; + + storm::analysis::LatticeExtender *extender; }; } } diff --git a/src/test/storm-pars/analysis/AssumptionMakerTest.cpp b/src/test/storm-pars/analysis/AssumptionMakerTest.cpp index 722ca69bf..f233d2563 100644 --- a/src/test/storm-pars/analysis/AssumptionMakerTest.cpp +++ b/src/test/storm-pars/analysis/AssumptionMakerTest.cpp @@ -53,12 +53,29 @@ TEST(AssumptionMakerTest, Brp_without_bisimulation) { ASSERT_EQ(186, std::get<2>(criticalTuple)); auto assumptionChecker = storm::analysis::AssumptionChecker(formulas[0], dtmc, 3); - auto assumptionMaker = storm::analysis::AssumptionMaker(extender, &assumptionChecker, dtmc->getNumberOfStates(), true); - auto result = assumptionMaker.makeAssumptions(std::get<0>(criticalTuple), std::get<1>(criticalTuple), std::get<2>(criticalTuple)); - EXPECT_EQ(1, result.size()); - auto lattice = result.begin()->first; - EXPECT_EQ(storm::analysis::Lattice::ABOVE, lattice->compare(186, 183)); - for (auto i = 0; i < dtmc->getNumberOfStates(); ++i) { - EXPECT_TRUE(lattice->getAddedStates()[i]); - } + auto assumptionMaker = storm::analysis::AssumptionMaker(&assumptionChecker, dtmc->getNumberOfStates(), true); + auto result = assumptionMaker.createAndCheckAssumption(std::get<1>(criticalTuple), std::get<2>(criticalTuple), std::get<0>(criticalTuple)); + + auto itr = result.begin(); + + auto var1 = itr->first->getManager().getVariable("183"); + auto var2 = itr->first->getManager().getVariable("186"); + + EXPECT_EQ(2, result.size()); + + EXPECT_EQ(false, itr->second); + EXPECT_EQ(true, itr->first->getFirstOperand()->isVariable()); + EXPECT_EQ(true, itr->first->getSecondOperand()->isVariable()); + EXPECT_EQ(var1, itr->first->getFirstOperand()->asVariableExpression().getVariable()); + EXPECT_EQ(var2, itr->first->getSecondOperand()->asVariableExpression().getVariable()); + EXPECT_EQ(storm::expressions::BinaryRelationExpression::RelationType::GreaterOrEqual, itr->first->getRelationType()); + + ++itr; + EXPECT_EQ(false, itr->second); + EXPECT_EQ(true, itr->first->getFirstOperand()->isVariable()); + EXPECT_EQ(true, itr->first->getSecondOperand()->isVariable()); + EXPECT_EQ(var2, itr->first->getFirstOperand()->asVariableExpression().getVariable()); + EXPECT_EQ(var1, itr->first->getSecondOperand()->asVariableExpression().getVariable()); + EXPECT_EQ(storm::expressions::BinaryRelationExpression::RelationType::GreaterOrEqual, itr->first->getRelationType()); + // TODO: createEqualsAssumption checken } diff --git a/src/test/storm-pars/analysis/MonotonicityCheckerTest.cpp b/src/test/storm-pars/analysis/MonotonicityCheckerTest.cpp index 7912bf7b0..af9f6628f 100644 --- a/src/test/storm-pars/analysis/MonotonicityCheckerTest.cpp +++ b/src/test/storm-pars/analysis/MonotonicityCheckerTest.cpp @@ -140,8 +140,8 @@ TEST(MonotonicityCheckerTest, Brp_with_bisimulation) { storm::analysis::MonotonicityChecker monotonicityChecker = storm::analysis::MonotonicityChecker(dtmc, formulas, true); auto result = monotonicityChecker.checkMonotonicity(); - EXPECT_EQ(result.size(), 1); - EXPECT_EQ(result.begin()->second.size(), 2); + EXPECT_EQ(1, result.size()); + EXPECT_EQ(2, result.begin()->second.size()); auto monotone = result.begin()->second.begin(); EXPECT_EQ(monotone->second.first, true); EXPECT_EQ(monotone->second.second, false);