Browse Source

some more work towards abstraction refinement

Former-commit-id: 360cb016c3
tempestpy_adaptions
dehnert 9 years ago
parent
commit
4f7eaa0a43
  1. 6
      src/abstraction/MenuGame.cpp
  2. 2
      src/abstraction/StateSetAbstractor.cpp
  3. 3
      src/abstraction/StateSetAbstractor.h
  4. 2
      src/abstraction/prism/AbstractCommand.cpp
  5. 6
      src/abstraction/prism/AbstractProgram.cpp
  6. 4
      src/abstraction/prism/AbstractProgram.h
  7. 8
      src/abstraction/prism/PrismMenuGameAbstractor.cpp
  8. 2
      src/abstraction/prism/PrismMenuGameAbstractor.h
  9. 38
      src/modelchecker/abstraction/GameBasedMdpModelChecker.cpp
  10. 14
      src/modelchecker/abstraction/GameBasedMdpModelChecker.h
  11. 5
      src/models/symbolic/Model.cpp
  12. 8
      src/storage/prism/Program.cpp
  13. 11
      src/storage/prism/Program.h

6
src/abstraction/MenuGame.cpp

@ -5,6 +5,7 @@
#include "src/storage/dd/Bdd.h"
#include "src/storage/dd/Add.h"
#include "src/storage/dd/DdManager.h"
#include "src/models/symbolic/StandardRewardModel.h"
@ -41,6 +42,11 @@ namespace storm {
template<storm::dd::DdType Type, typename ValueType>
storm::dd::Bdd<Type> MenuGame<Type, ValueType>::getStates(storm::expressions::Expression const& expression, bool negated) const {
if (expression.isTrue()) {
return this->getReachableStates();
} else if (expression.isFalse()) {
return this->getManager().getBddZero();
}
auto it = expressionToBddMap.find(expression);
STORM_LOG_THROW(it != expressionToBddMap.end(), storm::exceptions::InvalidArgumentException, "The given expression was not used in the abstraction process and can therefore not be retrieved.");
if (negated) {

2
src/abstraction/StateSetAbstractor.cpp

@ -11,7 +11,7 @@ namespace storm {
namespace abstraction {
template <storm::dd::DdType DdType, typename ValueType>
StateSetAbstractor<DdType, ValueType>::StateSetAbstractor(AbstractionInformation<DdType>& abstractionInformation, std::set<storm::expressions::Variable> const& allVariables, std::vector<storm::expressions::Expression> const& statePredicates, storm::utility::solver::SmtSolverFactory const& smtSolverFactory) : smtSolver(smtSolverFactory.create(abstractionInformation.getExpressionManager())), abstractionInformation(abstractionInformation), localExpressionInformation(allVariables), relevantPredicatesAndVariables(), concretePredicateVariables(), needsRecomputation(false), cachedBdd(abstractionInformation.getDdManager().getBddZero()), constraint(abstractionInformation.getDdManager().getBddOne()) {
StateSetAbstractor<DdType, ValueType>::StateSetAbstractor(AbstractionInformation<DdType>& abstractionInformation, std::set<storm::expressions::Variable> const& allVariables, std::vector<storm::expressions::Expression> const& statePredicates, std::shared_ptr<storm::utility::solver::SmtSolverFactory> const& smtSolverFactory) : smtSolver(smtSolverFactory->create(abstractionInformation.getExpressionManager())), abstractionInformation(abstractionInformation), localExpressionInformation(allVariables), relevantPredicatesAndVariables(), concretePredicateVariables(), needsRecomputation(false), cachedBdd(abstractionInformation.getDdManager().getBddZero()), constraint(abstractionInformation.getDdManager().getBddOne()) {
// Assert all state predicates.
for (auto const& predicate : statePredicates) {

3
src/abstraction/StateSetAbstractor.h

@ -8,6 +8,7 @@
#include "src/storage/dd/DdType.h"
#include "src/utility/solver.h"
#include "src/solver/SmtSolver.h"
#include "src/abstraction/LocalExpressionInformation.h"
@ -51,7 +52,7 @@ namespace storm {
* supposed to abstract.
* @param smtSolverFactory A factory that can create new SMT solvers.
*/
StateSetAbstractor(AbstractionInformation<DdType>& abstractionInformation, std::set<storm::expressions::Variable> const& allVariables, std::vector<storm::expressions::Expression> const& statePredicates, storm::utility::solver::SmtSolverFactory const& smtSolverFactory);
StateSetAbstractor(AbstractionInformation<DdType>& abstractionInformation, std::set<storm::expressions::Variable> const& allVariables, std::vector<storm::expressions::Expression> const& statePredicates, std::shared_ptr<storm::utility::solver::SmtSolverFactory> const& smtSolverFactory = std::make_shared<storm::utility::solver::MathsatSmtSolverFactory>());
/*!
* Refines the abstractor by making the given predicates new abstract predicates.

2
src/abstraction/prism/AbstractCommand.cpp

@ -32,7 +32,7 @@ namespace storm {
// Refine the command based on all initial predicates.
std::vector<uint_fast64_t> allPredicateIndices(abstractionInformation.getNumberOfPredicates());
for (auto index = 0; index < abstractionInformation.getNumberOfPredicates(); ++index) {
for (uint_fast64_t index = 0; index < abstractionInformation.getNumberOfPredicates(); ++index) {
allPredicateIndices[index] = index;
}
this->refine(allPredicateIndices);

6
src/abstraction/prism/AbstractProgram.cpp

@ -17,11 +17,11 @@ namespace storm {
namespace prism {
template <storm::dd::DdType DdType, typename ValueType>
AbstractProgram<DdType, ValueType>::AbstractProgram(storm::expressions::ExpressionManager& expressionManager, storm::prism::Program const& program,
AbstractProgram<DdType, ValueType>::AbstractProgram(storm::prism::Program const& program,
std::vector<storm::expressions::Expression> const& initialPredicates,
std::unique_ptr<storm::utility::solver::SmtSolverFactory>&& smtSolverFactory,
std::shared_ptr<storm::utility::solver::SmtSolverFactory> const& smtSolverFactory,
bool addAllGuards)
: program(program), smtSolverFactory(std::move(smtSolverFactory)), abstractionInformation(expressionManager), modules(), initialStateAbstractor(abstractionInformation, program.getAllExpressionVariables(), {program.getInitialConstruct().getInitialStatesExpression()}, *this->smtSolverFactory), addedAllGuards(addAllGuards), bottomStateAbstractor(abstractionInformation, program.getAllExpressionVariables(), program.getAllGuards(true), *this->smtSolverFactory), currentGame(nullptr) {
: program(program), smtSolverFactory(smtSolverFactory), abstractionInformation(program.getManager()), modules(), initialStateAbstractor(abstractionInformation, program.getAllExpressionVariables(), {program.getInitialConstruct().getInitialStatesExpression()}, this->smtSolverFactory), addedAllGuards(addAllGuards), bottomStateAbstractor(abstractionInformation, program.getAllExpressionVariables(), program.getAllGuards(true), this->smtSolverFactory), currentGame(nullptr) {
// For now, we assume that there is a single module. If the program has more than one module, it needs
// to be flattened before the procedure.

4
src/abstraction/prism/AbstractProgram.h

@ -45,7 +45,7 @@ namespace storm {
* @param smtSolverFactory A factory that is to be used for creating new SMT solvers.
* @param addAllGuards A flag that indicates whether all guards of the program should be added to the initial set of predicates.
*/
AbstractProgram(storm::expressions::ExpressionManager& expressionManager, storm::prism::Program const& program, std::vector<storm::expressions::Expression> const& initialPredicates, std::unique_ptr<storm::utility::solver::SmtSolverFactory>&& smtSolverFactory = std::make_unique<storm::utility::solver::SmtSolverFactory>(), bool addAllGuards = false);
AbstractProgram(storm::prism::Program const& program, std::vector<storm::expressions::Expression> const& initialPredicates, std::shared_ptr<storm::utility::solver::SmtSolverFactory> const& smtSolverFactory = std::make_shared<storm::utility::solver::MathsatSmtSolverFactory>(), bool addAllGuards = false);
AbstractProgram(AbstractProgram const&) = default;
AbstractProgram& operator=(AbstractProgram const&) = default;
@ -97,7 +97,7 @@ namespace storm {
std::reference_wrapper<storm::prism::Program const> program;
// A factory that can be used to create new SMT solvers.
std::unique_ptr<storm::utility::solver::SmtSolverFactory> smtSolverFactory;
std::shared_ptr<storm::utility::solver::SmtSolverFactory> smtSolverFactory;
// An object containing all information about the abstraction like predicates and the corresponding DDs.
AbstractionInformation<DdType> abstractionInformation;

8
src/abstraction/prism/PrismMenuGameAbstractor.cpp

@ -1,5 +1,7 @@
#include "src/abstraction/prism/PrismMenuGameAbstractor.h"
#include "src/models/symbolic/StandardRewardModel.h"
#include "src/settings/SettingsManager.h"
#include "src/settings/modules/AbstractionSettings.h"
@ -8,7 +10,7 @@ namespace storm {
namespace prism {
template <storm::dd::DdType DdType, typename ValueType>
PrismMenuGameAbstractor<DdType, ValueType>::PrismMenuGameAbstractor(storm::expressions::ExpressionManager& expressionManager, storm::prism::Program const& program, std::vector<storm::expressions::Expression> const& initialPredicates, storm::utility::solver::SmtSolverFactory const& smtSolverFactory) : abstractProgram(expressionManager, program, initialPredicates, std::move(smtSolverFactory), storm::settings::getModule<storm::settings::modules::AbstractionSettings>().isAddAllGuardsSet()) {
PrismMenuGameAbstractor<DdType, ValueType>::PrismMenuGameAbstractor(storm::prism::Program const& program, std::vector<storm::expressions::Expression> const& initialPredicates, std::shared_ptr<storm::utility::solver::SmtSolverFactory> const& smtSolverFactory) : abstractProgram(program, initialPredicates, smtSolverFactory, storm::settings::getModule<storm::settings::modules::AbstractionSettings>().isAddAllGuardsSet()) {
// Intentionally left empty.
}
@ -21,7 +23,9 @@ namespace storm {
void PrismMenuGameAbstractor<DdType, ValueType>::refine(std::vector<storm::expressions::Expression> const& predicates) {
abstractProgram.refine(predicates);
}
template class PrismMenuGameAbstractor<storm::dd::DdType::CUDD, double>;
template class PrismMenuGameAbstractor<storm::dd::DdType::Sylvan, double>;
}
}
}

2
src/abstraction/prism/PrismMenuGameAbstractor.h

@ -11,7 +11,7 @@ namespace storm {
template <storm::dd::DdType DdType, typename ValueType>
class PrismMenuGameAbstractor : public MenuGameAbstractor<DdType, ValueType> {
public:
PrismMenuGameAbstractor(storm::expressions::ExpressionManager& expressionManager, storm::prism::Program const& program, std::vector<storm::expressions::Expression> const& initialPredicates, storm::utility::solver::SmtSolverFactory const& smtSolverFactory);
PrismMenuGameAbstractor(storm::prism::Program const& program, std::vector<storm::expressions::Expression> const& initialPredicates, std::shared_ptr<storm::utility::solver::SmtSolverFactory> const& smtSolverFactory = std::make_shared<storm::utility::solver::MathsatSmtSolverFactory>());
virtual storm::abstraction::MenuGame<DdType, ValueType> abstract() override;
virtual void refine(std::vector<storm::expressions::Expression> const& predicates) override;

38
src/modelchecker/abstraction/GameBasedMdpModelChecker.cpp

@ -8,6 +8,7 @@
#include "src/logic/FragmentSpecification.h"
#include "src/utility/graph.h"
#include "src/utility/macros.h"
#include "src/exceptions/NotSupportedException.h"
@ -18,7 +19,7 @@
namespace storm {
namespace modelchecker {
template<storm::dd::DdType Type, typename ValueType>
GameBasedMdpModelChecker<Type, ValueType>::GameBasedMdpModelChecker(storm::expressions::ExpressionManager& expressionManager, storm::prism::Program const& program, std::unique_ptr<storm::utility::solver::SmtSolverFactory>&& smtSolverFactory) : originalProgram(program), expressionManager(expressionManager), smtSolverFactory(std::move(smtSolverFactory)) {
GameBasedMdpModelChecker<Type, ValueType>::GameBasedMdpModelChecker(storm::prism::Program const& program, std::shared_ptr<storm::utility::solver::SmtSolverFactory> const& smtSolverFactory) : originalProgram(program), smtSolverFactory(smtSolverFactory) {
STORM_LOG_THROW(program.getModelType() == storm::prism::Program::ModelType::DTMC || program.getModelType() == storm::prism::Program::ModelType::MDP, storm::exceptions::NotSupportedException, "Currently only DTMCs/MDPs are supported by the game-based model checker.");
// Start by preparing the program. That is, we flatten the modules if there is more than one.
@ -57,18 +58,31 @@ namespace storm {
std::unique_ptr<CheckResult> GameBasedMdpModelChecker<Type, ValueType>::performGameBasedAbstractionRefinement(CheckTask<storm::logic::Formula> const& checkTask, storm::expressions::Expression const& constraintExpression, storm::expressions::Expression const& targetStateExpression) {
STORM_LOG_THROW(checkTask.isOnlyInitialStatesRelevantSet(), storm::exceptions::InvalidPropertyException, "The game-based abstraction refinement model checker can only compute the result for the initial states.");
// Set up initial predicates.
std::vector<storm::expressions::Expression> initialPredicates;
initialPredicates.push_back(targetStateExpression);
if (!constraintExpression.isTrue() && !constraintExpression.isFalse()) {
initialPredicates.push_back(constraintExpression);
}
storm::abstraction::prism::PrismMenuGameAbstractor<Type, ValueType> abstractor(expressionManager, preprocessedProgram, initialPredicates, *smtSolverFactory);
// Derive the optimization direction for player 1 (assuming menu-game abstraction).
storm::OptimizationDirection player1Direction = checkTask.isOptimizationDirectionSet() ? checkTask.getOptimizationDirection() : storm::OptimizationDirection::Maximize;
storm::abstraction::prism::PrismMenuGameAbstractor<Type, ValueType> abstractor(preprocessedProgram, initialPredicates, smtSolverFactory);
// 1. build initial abstraction based on the the constraint expression (if not 'true') and the target state expression.
storm::abstraction::MenuGame<Type, ValueType> game = abstractor.abstract();
STORM_LOG_DEBUG("Initial abstraction has " << game.getNumberOfStates() << " (player 1) states and " << game.getNumberOfTransitions() << " transitions.");
// 2. solve the game wrt. to min/max as given by checkTask and min/max for the abstraction player to obtain two bounds.
// Note that we have to deal with bottom states if not all guards were added in the beginning.
// Also note that it might be the case that not both bounds need to be computed if there is a bound given in checkTask.
computeProb01States(player1Direction, game, constraintExpression, targetStateExpression);
// std::unique_ptr<storm::utility::solver::SymbolicGameSolverFactory<Type, ValueType>> gameSolverFactory = std::make_unique<storm::utility::solver::SymbolicGameSolverFactory<Type, ValueType>>();
// gameSolverFactory->create(game.getTransitionMatrix(), game.getReachableStates());
// storm::dd::Add<Type, ValueType> const& A, storm::dd::Bdd<Type> const& allRows, std::set<storm::expressions::Variable> const& rowMetaVariables, std::set<storm::expressions::Variable> const& columnMetaVariables, std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs, std::set<storm::expressions::Variable> const& player1Variables, std::set<storm::expressions::Variable> const& player2Variables
// 3. if the bounds suffice to complete checkTask, return result now.
@ -77,6 +91,26 @@ namespace storm {
return nullptr;
}
template<storm::dd::DdType Type, typename ValueType>
void GameBasedMdpModelChecker<Type, ValueType>::computeProb01States(storm::OptimizationDirection player1Direction, storm::abstraction::MenuGame<Type, ValueType> const& game, storm::expressions::Expression const& constraintExpression, storm::expressions::Expression const& targetStateExpression) {
storm::dd::Bdd<Type> transitionMatrixBdd = game.getTransitionMatrix().toBdd();
storm::dd::Bdd<Type> bottomStatesBdd = game.getBottomStates();
game.getTransitionMatrix().exportToDot("trans.dot");
bottomStatesBdd.template toAdd<ValueType>().exportToDot("bottom.dot");
// Start by computing the states with probability 0/1 for the case in which player 2 minimizes.
storm::utility::graph::GameProb01Result<Type> prob0Min = storm::utility::graph::performProb0(game, transitionMatrixBdd, game.getStates(constraintExpression), game.getStates(targetStateExpression), player1Direction, storm::OptimizationDirection::Minimize, true);
storm::utility::graph::GameProb01Result<Type> prob1Min = storm::utility::graph::performProb1(game, transitionMatrixBdd, game.getStates(constraintExpression), game.getStates(targetStateExpression), player1Direction, storm::OptimizationDirection::Minimize, true);
// Now compute the states with probability 0/1 for the case in which player 2 maximizes.
storm::utility::graph::GameProb01Result<Type> prob0Max = storm::utility::graph::performProb0(game, transitionMatrixBdd, game.getStates(constraintExpression), game.getStates(targetStateExpression), player1Direction, storm::OptimizationDirection::Maximize, true);
storm::utility::graph::GameProb01Result<Type> prob1Max = storm::utility::graph::performProb1(game, transitionMatrixBdd, game.getStates(constraintExpression), game.getStates(targetStateExpression), player1Direction, storm::OptimizationDirection::Maximize, true);
STORM_LOG_DEBUG("Min: " << prob0Min.states.getNonZeroCount() << " no states, " << prob1Min.states.getNonZeroCount() << " yes states.");
STORM_LOG_DEBUG("Max: " << prob0Max.states.getNonZeroCount() << " no states, " << prob1Max.states.getNonZeroCount() << " yes states.");
}
template<storm::dd::DdType Type, typename ValueType>
storm::expressions::Expression GameBasedMdpModelChecker<Type, ValueType>::getExpression(storm::logic::Formula const& formula) {
STORM_LOG_THROW(formula.isAtomicExpressionFormula() || formula.isAtomicLabelFormula(), storm::exceptions::InvalidPropertyException, "The target states have to be given as label or an expression.");

14
src/modelchecker/abstraction/GameBasedMdpModelChecker.h

@ -10,6 +10,11 @@
#include "src/storage/dd/DdType.h"
namespace storm {
namespace abstraction {
template<storm::dd::DdType Type, typename ValueType>
class MenuGame;
}
namespace modelchecker {
template<storm::dd::DdType Type, typename ValueType>
class GameBasedMdpModelChecker : public AbstractModelChecker {
@ -21,7 +26,7 @@ namespace storm {
* @param program The program that implicitly specifies the model to check.
* @param smtSolverFactory A factory used to create SMT solver when necessary.
*/
explicit GameBasedMdpModelChecker(storm::expressions::ExpressionManager& expressionManager, storm::prism::Program const& program, std::unique_ptr<storm::utility::solver::SmtSolverFactory>&& smtSolverFactory = std::make_unique<storm::utility::solver::MathsatSmtSolverFactory>());
explicit GameBasedMdpModelChecker(storm::prism::Program const& program, std::shared_ptr<storm::utility::solver::SmtSolverFactory> const& smtSolverFactory = std::make_shared<storm::utility::solver::MathsatSmtSolverFactory>());
virtual ~GameBasedMdpModelChecker() override;
@ -33,6 +38,8 @@ namespace storm {
private:
std::unique_ptr<CheckResult> performGameBasedAbstractionRefinement(CheckTask<storm::logic::Formula> const& checkTask, storm::expressions::Expression const& constraintExpression, storm::expressions::Expression const& targetStateExpression);
void computeProb01States(storm::OptimizationDirection player1Direction, storm::abstraction::MenuGame<Type, ValueType> const& game, storm::expressions::Expression const& constraintExpression, storm::expressions::Expression const& targetStateExpression);
storm::expressions::Expression getExpression(storm::logic::Formula const& formula);
// The original program that was used to create this model checker.
@ -42,11 +49,8 @@ namespace storm {
// original program.
storm::prism::Program preprocessedProgram;
/// The expression manager over which to build expressions during the abstraction.
storm::expressions::ExpressionManager& expressionManager;
// A factory that is used for creating SMT solvers when needed.
std::unique_ptr<storm::utility::solver::SmtSolverFactory> smtSolverFactory;
std::shared_ptr<storm::utility::solver::SmtSolverFactory> smtSolverFactory;
};
}
}

5
src/models/symbolic/Model.cpp

@ -72,6 +72,11 @@ namespace storm {
template<storm::dd::DdType Type, typename ValueType>
storm::dd::Bdd<Type> Model<Type, ValueType>::getStates(storm::expressions::Expression const& expression) const {
if (expression.isTrue()) {
return this->getReachableStates();
} else if (expression.isFalse()) {
return manager->getBddZero();
}
STORM_LOG_THROW(rowExpressionAdapter != nullptr, storm::exceptions::InvalidOperationException, "Cannot create BDD for expression without expression adapter.");
return rowExpressionAdapter->translateExpression(expression).toBdd() && this->reachableStates;
}

8
src/storage/prism/Program.cpp

@ -1231,7 +1231,7 @@ namespace storm {
return Program(this->manager, modelType, newConstants, getGlobalBooleanVariables(), getGlobalIntegerVariables(), getFormulas(), newModules, getActionNameToIndexMapping(), getRewardModels(), getLabels(), getInitialConstruct(), this->getOptionalSystemCompositionConstruct());
}
Program Program::flattenModules(std::unique_ptr<storm::utility::solver::SmtSolverFactory> const& smtSolverFactory) const {
Program Program::flattenModules(std::shared_ptr<storm::utility::solver::SmtSolverFactory> const& smtSolverFactory) const {
// If the current program has only one module, we can simply return a copy.
if (this->getNumberOfModules() == 1) {
return Program(*this);
@ -1512,11 +1512,7 @@ namespace storm {
return this->indexToActionMap.rbegin()->first;
}
storm::expressions::ExpressionManager const& Program::getManager() const {
return *this->manager;
}
storm::expressions::ExpressionManager& Program::getManager() {
storm::expressions::ExpressionManager& Program::getManager() const {
return *this->manager;
}

11
src/storage/prism/Program.h

@ -546,7 +546,7 @@ namespace storm {
* @param smtSolverFactory an SMT solver factory to use. If none is given, the default one is used.
* @return The resulting program.
*/
Program flattenModules(std::unique_ptr<storm::utility::solver::SmtSolverFactory> const& smtSolverFactory = std::unique_ptr<storm::utility::solver::SmtSolverFactory>(new storm::utility::solver::SmtSolverFactory())) const;
Program flattenModules(std::shared_ptr<storm::utility::solver::SmtSolverFactory> const& smtSolverFactory = std::shared_ptr<storm::utility::solver::SmtSolverFactory>(new storm::utility::solver::SmtSolverFactory())) const;
friend std::ostream& operator<<(std::ostream& stream, Program const& program);
@ -555,14 +555,7 @@ namespace storm {
*
* @return The manager responsible for the expressions of this program.
*/
storm::expressions::ExpressionManager const& getManager() const;
/*!
* Retrieves the manager responsible for the expressions of this program.
*
* @return The manager responsible for the expressions of this program.
*/
storm::expressions::ExpressionManager& getManager();
storm::expressions::ExpressionManager& getManager() const;
/*!
*

Loading…
Cancel
Save