Browse Source

introduced refinement command to capture a specific refinement

tempestpy_adaptions
dehnert 8 years ago
parent
commit
24eede3e19
  1. 14
      src/storm/abstraction/AbstractionInformation.cpp
  2. 17
      src/storm/abstraction/AbstractionInformation.h
  3. 5
      src/storm/abstraction/MenuGameAbstractor.h
  4. 44
      src/storm/abstraction/MenuGameRefiner.cpp
  5. 13
      src/storm/abstraction/MenuGameRefiner.h
  6. 27
      src/storm/abstraction/RefinementCommand.cpp
  7. 36
      src/storm/abstraction/RefinementCommand.h
  8. 51
      src/storm/abstraction/prism/PrismMenuGameAbstractor.cpp
  9. 34
      src/storm/abstraction/prism/PrismMenuGameAbstractor.h

14
src/storm/abstraction/AbstractionInformation.cpp

@ -14,7 +14,7 @@ namespace storm {
namespace abstraction {
template<storm::dd::DdType DdType>
AbstractionInformation<DdType>::AbstractionInformation(storm::expressions::ExpressionManager& expressionManager, std::shared_ptr<storm::dd::DdManager<DdType>> ddManager) : expressionManager(expressionManager), ddManager(ddManager), allPredicateIdentities(ddManager->getBddOne()) {
AbstractionInformation<DdType>::AbstractionInformation(storm::expressions::ExpressionManager& expressionManager, std::unique_ptr<storm::solver::SmtSolver>&& smtSolver, std::shared_ptr<storm::dd::DdManager<DdType>> ddManager) : expressionManager(expressionManager), equivalenceChecker(std::move(smtSolver)), ddManager(ddManager), allPredicateIdentities(ddManager->getBddOne()) {
// Intentionally left empty.
}
@ -40,7 +40,15 @@ namespace storm {
}
template<storm::dd::DdType DdType>
uint_fast64_t AbstractionInformation<DdType>::addPredicate(storm::expressions::Expression const& predicate) {
uint_fast64_t AbstractionInformation<DdType>::getOrAddPredicate(storm::expressions::Expression const& predicate) {
// Check if we already have an equivalent predicate.
for (uint64_t index = 0; index < predicates.size(); ++index) {
auto const& oldPredicate = predicates[index];
if (equivalenceChecker.areEquivalent(oldPredicate, predicate)) {
return index;
}
}
std::size_t predicateIndex = predicates.size();
predicateToIndexMap[predicate] = predicateIndex;
@ -68,7 +76,7 @@ namespace storm {
std::vector<uint_fast64_t> AbstractionInformation<DdType>::addPredicates(std::vector<storm::expressions::Expression> const& predicates) {
std::vector<uint_fast64_t> predicateIndices;
for (auto const& predicate : predicates) {
predicateIndices.push_back(this->addPredicate(predicate));
predicateIndices.push_back(this->getOrAddPredicate(predicate));
}
return predicateIndices;
}

17
src/storm/abstraction/AbstractionInformation.h

@ -3,11 +3,16 @@
#include <vector>
#include <set>
#include <cstdint>
#include <memory>
#include "storm/storage/dd/DdType.h"
#include "storm/storage/dd/Bdd.h"
#include "storm/solver/SmtSolver.h"
#include "storm/storage/expressions/EquivalenceChecker.h"
namespace storm {
namespace expressions {
class ExpressionManager;
@ -29,8 +34,10 @@ namespace storm {
* Creates a new abstraction information object.
*
* @param expressionManager The manager responsible for all variables and expressions during the abstraction process.
* @param smtSolver An SMT solver that is used to detect equivalent predicates.
* @param ddManager The manager responsible for the DDs.
*/
AbstractionInformation(storm::expressions::ExpressionManager& expressionManager, std::shared_ptr<storm::dd::DdManager<DdType>> ddManager = std::make_shared<storm::dd::DdManager<DdType>>());
AbstractionInformation(storm::expressions::ExpressionManager& expressionManager, std::unique_ptr<storm::solver::SmtSolver>&& smtSolver, std::shared_ptr<storm::dd::DdManager<DdType>> ddManager = std::make_shared<storm::dd::DdManager<DdType>>());
/*!
* Adds the given variable.
@ -69,12 +76,13 @@ namespace storm {
std::vector<storm::expressions::Expression> const& getConstraints() const;
/*!
* Adds the given predicate.
* Gets the index of a predicate that is equivalent to the provided one. If none exists, the predicate is
* added.
*
* @param predicate The predicate to add.
* @return The index of the newly added predicate in the global list of predicates.
*/
uint_fast64_t addPredicate(storm::expressions::Expression const& predicate);
uint_fast64_t getOrAddPredicate(storm::expressions::Expression const& predicate);
/*!
* Adds the given predicates.
@ -462,6 +470,9 @@ namespace storm {
/// A mapping from predicates to their indices in the predicate list.
std::unordered_map<storm::expressions::Expression, uint64_t> predicateToIndexMap;
/// An object that can detect equivalence of predicates.
storm::expressions::EquivalenceChecker equivalenceChecker;
/// The current set of predicates used in the abstraction.
std::vector<storm::expressions::Expression> predicates;

5
src/storm/abstraction/MenuGameAbstractor.h

@ -1,10 +1,12 @@
#pragma once
#include <map>
#include <vector>
#include "storm/storage/dd/DdType.h"
#include "storm/abstraction/MenuGame.h"
#include "storm/abstraction/RefinementCommand.h"
#include "storm/storage/expressions/Expression.h"
@ -23,10 +25,11 @@ namespace storm {
/// Retrieves information about the abstraction.
virtual AbstractionInformation<DdType> const& getAbstractionInformation() const = 0;
virtual storm::expressions::Expression const& getGuard(uint64_t player1Choice) const = 0;
virtual std::pair<uint64_t, uint64_t> getPlayer1ChoiceRange() const = 0;
virtual std::map<storm::expressions::Variable, storm::expressions::Expression> getVariableUpdates(uint64_t player1Choice, uint64_t auxiliaryChoice) const = 0;
/// Methods to refine the abstraction.
virtual void refine(std::vector<storm::expressions::Expression> const& predicates) = 0;
virtual void refine(std::vector<RefinementCommand> const& commands) = 0;
/// Exports a representation of the current abstraction state in the dot format.
virtual void exportToDot(std::string const& filename, storm::dd::Bdd<DdType> const& highlightStates, storm::dd::Bdd<DdType> const& filter) const = 0;

44
src/storm/abstraction/MenuGameRefiner.cpp

@ -13,12 +13,21 @@ namespace storm {
template<storm::dd::DdType Type, typename ValueType>
MenuGameRefiner<Type, ValueType>::MenuGameRefiner(MenuGameAbstractor<Type, ValueType>& abstractor, std::unique_ptr<storm::solver::SmtSolver>&& smtSolver) : abstractor(abstractor), splitPredicates(storm::settings::getModule<storm::settings::modules::AbstractionSettings>().isSplitPredicatesSet()), splitter(), equivalenceChecker(std::move(smtSolver)) {
// Intentionally left empty.
if (storm::settings::getModule<storm::settings::modules::AbstractionSettings>().isAddAllGuardsSet()) {
std::vector<storm::expressions::Expression> guards;
std::pair<uint64_t, uint64_t> player1Choices = this->abstractor.get().getPlayer1ChoiceRange();
for (uint64_t index = player1Choices.first; index < player1Choices.second; ++index) {
guards.push_back(this->abstractor.get().getGuard(index));
}
performRefinement(createGlobalRefinement(guards));
}
}
template<storm::dd::DdType Type, typename ValueType>
void MenuGameRefiner<Type, ValueType>::refine(std::vector<storm::expressions::Expression> const& predicates) const {
abstractor.get().refine(predicates);
performRefinement(createGlobalRefinement(predicates));
}
template<storm::dd::DdType Type, typename ValueType>
@ -226,7 +235,8 @@ namespace storm {
// Derive predicate based on the selected pivot state.
storm::expressions::Expression newPredicate = derivePredicateFromPivotState(game, pivotState, minPlayer1Strategy, minPlayer2Strategy, maxPlayer1Strategy, maxPlayer2Strategy);
performRefinement({newPredicate});
std::vector<storm::expressions::Expression> preparedPredicates = preprocessPredicates({newPredicate});
performRefinement(createGlobalRefinement(preparedPredicates));
return true;
}
@ -253,12 +263,13 @@ namespace storm {
// Derive predicate based on the selected pivot state.
storm::expressions::Expression newPredicate = derivePredicateFromPivotState(game, pivotState, minPlayer1Strategy, minPlayer2Strategy, maxPlayer1Strategy, maxPlayer2Strategy);
performRefinement({newPredicate});
std::vector<storm::expressions::Expression> preparedPredicates = preprocessPredicates({newPredicate});
performRefinement(createGlobalRefinement(preparedPredicates));
return true;
}
template<storm::dd::DdType Type, typename ValueType>
bool MenuGameRefiner<Type, ValueType>::performRefinement(std::vector<storm::expressions::Expression> const& predicates) const {
std::vector<storm::expressions::Expression> MenuGameRefiner<Type, ValueType>::preprocessPredicates(std::vector<storm::expressions::Expression> const& predicates) const {
if (splitPredicates) {
std::vector<storm::expressions::Expression> cleanedAtoms;
@ -292,13 +303,30 @@ namespace storm {
}
}
abstractor.get().refine(cleanedAtoms);
return cleanedAtoms;
} else {
// If no splitting of the predicates is required, just forward the refinement request to the abstractor.
abstractor.get().refine(predicates);
}
return true;
return predicates;
}
template<storm::dd::DdType Type, typename ValueType>
std::vector<RefinementCommand> MenuGameRefiner<Type, ValueType>::createGlobalRefinement(std::vector<storm::expressions::Expression> const& predicates) const {
std::vector<RefinementCommand> commands;
// std::pair<uint64_t, uint64_t> player1Choices = abstractor.get().getPlayer1ChoiceRange();
// for (uint64_t index = player1Choices.first; index < player1Choices.second; ++index) {
// commands.emplace_back(index, predicates);
// }
commands.emplace_back(predicates);
return commands;
}
template<storm::dd::DdType Type, typename ValueType>
void MenuGameRefiner<Type, ValueType>::performRefinement(std::vector<RefinementCommand> const& refinementCommands) const {
abstractor.get().refine(refinementCommands);
}
template class MenuGameRefiner<storm::dd::DdType::CUDD, double>;

13
src/storm/abstraction/MenuGameRefiner.h

@ -4,6 +4,7 @@
#include <vector>
#include <memory>
#include "storm/abstraction/RefinementCommand.h"
#include "storm/abstraction/QualitativeResultMinMax.h"
#include "storm/abstraction/QuantitativeResultMinMax.h"
@ -54,10 +55,18 @@ namespace storm {
private:
storm::expressions::Expression derivePredicateFromDifferingChoices(storm::dd::Bdd<Type> const& pivotState, storm::dd::Bdd<Type> const& player1Choice, storm::dd::Bdd<Type> const& lowerChoice, storm::dd::Bdd<Type> const& upperChoice) const;
storm::expressions::Expression derivePredicateFromPivotState(storm::abstraction::MenuGame<Type, ValueType> const& game, storm::dd::Bdd<Type> const& pivotState, storm::dd::Bdd<Type> const& minPlayer1Strategy, storm::dd::Bdd<Type> const& minPlayer2Strategy, storm::dd::Bdd<Type> const& maxPlayer1Strategy, storm::dd::Bdd<Type> const& maxPlayer2Strategy) const;
/*!
* Takes the given predicates, preprocesses them and then refines the abstractor.
* Preprocesses the predicates.
*/
bool performRefinement(std::vector<storm::expressions::Expression> const& predicates) const;
std::vector<storm::expressions::Expression> preprocessPredicates(std::vector<storm::expressions::Expression> const& predicates) const;
/*!
* Creates a set of refinement commands that amounts to splitting all player 1 choices with the given set of predicates.
*/
std::vector<RefinementCommand> createGlobalRefinement(std::vector<storm::expressions::Expression> const& predicates) const;
void performRefinement(std::vector<RefinementCommand> const& refinementCommands) const;
/// The underlying abstractor to refine.
std::reference_wrapper<MenuGameAbstractor<Type, ValueType>> abstractor;

27
src/storm/abstraction/RefinementCommand.cpp

@ -0,0 +1,27 @@
#include "storm/abstraction/RefinementCommand.h"
namespace storm {
namespace abstraction {
RefinementCommand::RefinementCommand(uint64_t referencedPlayer1Choice, std::vector<storm::expressions::Expression> const& predicates) : referencedPlayer1Choice(referencedPlayer1Choice), predicates(predicates) {
// Intentionally left empty.
}
RefinementCommand::RefinementCommand(std::vector<storm::expressions::Expression> const& predicates) : predicates(predicates) {
// Intentionally left empty.
}
bool RefinementCommand::refersToPlayer1Choice() const {
return static_cast<bool>(referencedPlayer1Choice);
}
uint64_t RefinementCommand::getReferencedPlayer1Choice() const {
return referencedPlayer1Choice.get();
}
std::vector<storm::expressions::Expression> const& RefinementCommand::getPredicates() const {
return predicates;
}
}
}

36
src/storm/abstraction/RefinementCommand.h

@ -0,0 +1,36 @@
#pragma once
#include <cstdint>
#include <vector>
#include <boost/optional.hpp>
#include "storm/storage/expressions/Expression.h"
namespace storm {
namespace abstraction {
class RefinementCommand {
public:
/*!
* Creates a new refinement command for the given player 1 choice.
*/
RefinementCommand(uint64_t referencedPlayer1Choice, std::vector<storm::expressions::Expression> const& predicates);
/*!
* Creates a new refinement command for all player 1 choices.
*/
RefinementCommand(std::vector<storm::expressions::Expression> const& predicates);
/// Access to the details of this refinement commands.
bool refersToPlayer1Choice() const;
uint64_t getReferencedPlayer1Choice() const;
std::vector<storm::expressions::Expression> const& getPredicates() const;
private:
boost::optional<uint64_t> referencedPlayer1Choice;
std::vector<storm::expressions::Expression> predicates;
};
}
}

51
src/storm/abstraction/prism/PrismMenuGameAbstractor.cpp

@ -17,6 +17,7 @@
#include "storm/utility/solver.h"
#include "storm/exceptions/WrongFormatException.h"
#include "storm/exceptions/InvalidArgumentException.h"
#include "storm/exceptions/NotSupportedException.h"
#include "storm-config.h"
#include "storm/adapters/CarlAdapter.h"
@ -29,9 +30,8 @@ namespace storm {
template <storm::dd::DdType DdType, typename ValueType>
PrismMenuGameAbstractor<DdType, ValueType>::PrismMenuGameAbstractor(storm::prism::Program const& program,
std::shared_ptr<storm::utility::solver::SmtSolverFactory> const& smtSolverFactory,
bool addAllGuards)
: program(program), smtSolverFactory(smtSolverFactory), abstractionInformation(program.getManager()), modules(), initialStateAbstractor(abstractionInformation, program.getAllExpressionVariables(), {program.getInitialStatesExpression()}, this->smtSolverFactory), addedAllGuards(addAllGuards), currentGame(nullptr), refinementPerformed(false) {
std::shared_ptr<storm::utility::solver::SmtSolverFactory> const& smtSolverFactory)
: program(program), smtSolverFactory(smtSolverFactory), abstractionInformation(program.getManager(), smtSolverFactory->create(program.getManager())), modules(), initialStateAbstractor(abstractionInformation, program.getAllExpressionVariables(), {program.getInitialStatesExpression()}, this->smtSolverFactory), currentGame(nullptr), refinementPerformed(false) {
// 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.
@ -52,9 +52,6 @@ namespace storm {
for (auto const& module : program.getModules()) {
// If we were requested to add all guards to the set of predicates, we do so now.
for (auto const& command : module.getCommands()) {
if (addAllGuards) {
allGuards.push_back(command.getGuardExpression());
}
maximalUpdateCount = std::max(maximalUpdateCount, static_cast<uint_fast64_t>(command.getNumberOfUpdates()));
}
@ -68,45 +65,40 @@ namespace storm {
// For each module of the concrete program, we create an abstract counterpart.
for (auto const& module : program.getModules()) {
this->modules.emplace_back(module, abstractionInformation, this->smtSolverFactory, addAllGuards);
this->modules.emplace_back(module, abstractionInformation, this->smtSolverFactory);
}
// Retrieve the command-update probability ADD, so we can multiply it with the abstraction BDD later.
commandUpdateProbabilitiesAdd = modules.front().getCommandUpdateProbabilitiesAdd();
// Now that we have created all other DD variables, we create the DD variables for the predicates.
std::vector<storm::expressions::Expression> initialPredicates;
if (addAllGuards) {
for (auto const& guard : allGuards) {
initialPredicates.push_back(guard);
}
}
template <storm::dd::DdType DdType, typename ValueType>
void PrismMenuGameAbstractor<DdType, ValueType>::refine(std::vector<RefinementCommand> const& commands) {
for (auto const& command : commands) {
STORM_LOG_THROW(!command.refersToPlayer1Choice(), storm::exceptions::NotSupportedException, "Currently only global refinement is supported.");
refine(command);
refinementPerformed |= !command.getPredicates().empty();
}
// Finally, refine using the all predicates and build game as a by-product.
this->refine(initialPredicates);
}
template <storm::dd::DdType DdType, typename ValueType>
void PrismMenuGameAbstractor<DdType, ValueType>::refine(std::vector<storm::expressions::Expression> const& predicates) {
void PrismMenuGameAbstractor<DdType, ValueType>::refine(RefinementCommand const& command) {
// Add the predicates to the global list of predicates and gather their indices.
std::vector<uint_fast64_t> newPredicateIndices;
for (auto const& predicate : predicates) {
std::vector<uint_fast64_t> predicateIndices;
for (auto const& predicate : command.getPredicates()) {
STORM_LOG_THROW(predicate.hasBooleanType(), storm::exceptions::InvalidArgumentException, "Expecting a predicate of type bool.");
newPredicateIndices.push_back(abstractionInformation.addPredicate(predicate));
predicateIndices.push_back(abstractionInformation.getOrAddPredicate(predicate));
}
// Refine all abstract modules.
for (auto& module : modules) {
module.refine(newPredicateIndices);
module.refine(predicateIndices);
}
// Refine initial state abstractor.
initialStateAbstractor.refine(newPredicateIndices);
// Update the flag that stores whether a refinement was performed.
refinementPerformed = refinementPerformed || !newPredicateIndices.empty();
initialStateAbstractor.refine(predicateIndices);
}
template <storm::dd::DdType DdType, typename ValueType>
MenuGame<DdType, ValueType> PrismMenuGameAbstractor<DdType, ValueType>::abstract() {
if (refinementPerformed) {
@ -131,6 +123,11 @@ namespace storm {
return modules.front().getVariableUpdates(player1Choice, auxiliaryChoice);
}
template <storm::dd::DdType DdType, typename ValueType>
std::pair<uint64_t, uint64_t> PrismMenuGameAbstractor<DdType, ValueType>::getPlayer1ChoiceRange() const {
return std::make_pair(0, modules.front().getCommands().size());
}
template <storm::dd::DdType DdType, typename ValueType>
storm::dd::Bdd<DdType> PrismMenuGameAbstractor<DdType, ValueType>::getStates(storm::expressions::Expression const& predicate) {
STORM_LOG_ASSERT(currentGame != nullptr, "Game was not properly created.");

34
src/storm/abstraction/prism/PrismMenuGameAbstractor.h

@ -5,6 +5,7 @@
#include "storm/abstraction/MenuGameAbstractor.h"
#include "storm/abstraction/AbstractionInformation.h"
#include "storm/abstraction/MenuGame.h"
#include "storm/abstraction/RefinementCommand.h"
#include "storm/abstraction/prism/ModuleAbstractor.h"
#include "storm/storage/dd/Add.h"
@ -42,9 +43,8 @@ namespace storm {
* @param expressionManager The manager responsible for the expressions of the program.
* @param program The concrete program for which to build the abstraction.
* @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.
*/
PrismMenuGameAbstractor(storm::prism::Program const& program, std::shared_ptr<storm::utility::solver::SmtSolverFactory> const& smtSolverFactory = std::make_shared<storm::utility::solver::MathsatSmtSolverFactory>(), bool addAllGuards = false);
PrismMenuGameAbstractor(storm::prism::Program const& program, std::shared_ptr<storm::utility::solver::SmtSolverFactory> const& smtSolverFactory = std::make_shared<storm::utility::solver::MathsatSmtSolverFactory>());
PrismMenuGameAbstractor(PrismMenuGameAbstractor const&) = default;
PrismMenuGameAbstractor& operator=(PrismMenuGameAbstractor const&) = default;
@ -56,14 +56,14 @@ namespace storm {
*
* @return The abstract stochastic two player game.
*/
MenuGame<DdType, ValueType> abstract();
MenuGame<DdType, ValueType> abstract() override;
/*!
* Retrieves information about the abstraction.
*
* @return The abstraction information object.
*/
AbstractionInformation<DdType> const& getAbstractionInformation() const;
AbstractionInformation<DdType> const& getAbstractionInformation() const override;
/*!
* Retrieves the guard predicate of the given player 1 choice.
@ -71,13 +71,18 @@ namespace storm {
* @param player1Choice The choice for which to retrieve the guard.
* @return The guard of the player 1 choice.
*/
storm::expressions::Expression const& getGuard(uint64_t player1Choice) const;
storm::expressions::Expression const& getGuard(uint64_t player1Choice) const override;
/*!
* Retrieves a mapping from variables to expressions that define their updates wrt. to the given player
* 1 choice and auxiliary choice.
*/
std::map<storm::expressions::Variable, storm::expressions::Expression> getVariableUpdates(uint64_t player1Choice, uint64_t auxiliaryChoice) const;
std::map<storm::expressions::Variable, storm::expressions::Expression> getVariableUpdates(uint64_t player1Choice, uint64_t auxiliaryChoice) const override;
/*!
* Retrieves the range of player 1 choices.
*/
std::pair<uint64_t, uint64_t> getPlayer1ChoiceRange() const override;
/*!
* Retrieves the set of states (represented by a BDD) satisfying the given predicate, assuming that it
@ -89,12 +94,19 @@ namespace storm {
storm::dd::Bdd<DdType> getStates(storm::expressions::Expression const& predicate);
/*!
* Refines the abstract program with the given predicates.
* Performs the given refinement commands.
*
* @param predicates The new predicates.
* @param commands The commands to perform.
*/
void refine(std::vector<storm::expressions::Expression> const& predicates);
virtual void refine(std::vector<RefinementCommand> const& commands) override;
/*!
* Performs the given refinement command.
*
* @param command The command to perform.
*/
void refine(RefinementCommand const& command);
/*!
* Exports the current state of the abstraction in the dot format to the given file.
*
@ -102,7 +114,7 @@ namespace storm {
* @param highlightStates A BDD characterizing states that will be highlighted.
* @param filter A filter that is applied to select which part of the game to export.
*/
void exportToDot(std::string const& filename, storm::dd::Bdd<DdType> const& highlightStates, storm::dd::Bdd<DdType> const& filter) const;
void exportToDot(std::string const& filename, storm::dd::Bdd<DdType> const& highlightStates, storm::dd::Bdd<DdType> const& filter) const override;
private:
/*!

Loading…
Cancel
Save