28#include "storm-config.h" 
   32namespace abstraction {
 
   37template<storm::dd::DdType DdType, 
typename ValueType>
 
   39                                                                  std::shared_ptr<storm::utility::solver::SmtSolverFactory> 
const& smtSolverFactory,
 
   42      smtSolverFactory(smtSolverFactory),
 
   43      abstractionInformation(model.getManager(), model.getAllExpressionVariables(), smtSolverFactory->create(model.getManager()),
 
   47      restrictToValidBlocks(
false),
 
   48      validBlockAbstractor(abstractionInformation, smtSolverFactory),
 
   50      refinementPerformed(
true) {
 
   52    STORM_LOG_WARN_COND(model.isLinear(), 
"The model appears to contain non-linear expressions, which may cause malfunctioning of the abstraction.");
 
   56    STORM_LOG_THROW(model.getNumberOfAutomata() == 1, storm::exceptions::WrongFormatException,
 
   57                    "Cannot create abstract model from program containing more than one automaton.");
 
   60    for (
auto const& range : this->model.get().getAllRangeExpressions()) {
 
   61        abstractionInformation.addConstraint(range);
 
   62        initialStateAbstractor.constrain(range);
 
   63        validBlockAbstractor.constrain(range);
 
   66    uint_fast64_t totalNumberOfEdges = 0;
 
   67    uint_fast64_t maximalDestinationCount = 0;
 
   68    std::vector<storm::expressions::Expression> allGuards;
 
   69    for (
auto const& automaton : model.getAutomata()) {
 
   70        for (
auto const& edge : automaton.getEdges()) {
 
   71            maximalDestinationCount = std::max(maximalDestinationCount, 
static_cast<uint_fast64_t
>(edge.getNumberOfDestinations()));
 
   74        totalNumberOfEdges += automaton.getNumberOfEdges();
 
   80    abstractionInformation.createEncodingVariables(
static_cast<uint_fast64_t
>(std::ceil(std::log2(totalNumberOfEdges))), 64,
 
   81                                                   static_cast<uint_fast64_t
>(std::ceil(std::log2(maximalDestinationCount))));
 
   84    auto const& settings = storm::settings::getModule<storm::settings::modules::AbstractionSettings>();
 
   85    bool useDecomposition = settings.isUseDecompositionSet();
 
   87    bool addPredicatesForValidBlocks = !restrictToValidBlocks;
 
   88    bool debug = settings.isDebugSet();
 
   89    for (
auto const& automaton : model.getAutomata()) {
 
   90        automata.emplace_back(automaton, abstractionInformation, this->smtSolverFactory, useDecomposition, addPredicatesForValidBlocks, debug);
 
   94    initialLocationsBdd = automata.front().getInitialLocationsBdd();
 
   95    edgeDecoratorAdd = automata.front().getEdgeDecoratorAdd();
 
 
   98template<storm::dd::DdType DdType, 
typename ValueType>
 
  100    return abstractionInformation.getDdManager();
 
 
  103template<storm::dd::DdType DdType, 
typename ValueType>
 
  106    std::vector<uint_fast64_t> predicateIndices;
 
  108        STORM_LOG_THROW(predicate.hasBooleanType(), storm::exceptions::InvalidArgumentException, 
"Expecting a predicate of type bool.");
 
  109        predicateIndices.push_back(abstractionInformation.getOrAddPredicate(predicate));
 
  113    for (
auto& automaton : automata) {
 
  114        automaton.refine(predicateIndices);
 
  118    initialStateAbstractor.refine(predicateIndices);
 
  120    if (this->restrictToValidBlocks) {
 
  122        validBlockAbstractor.refine(predicateIndices);
 
 
  128template<storm::dd::DdType DdType, 
typename ValueType>
 
  130    if (refinementPerformed) {
 
  131        currentGame = buildGame();
 
  132        refinementPerformed = 
false;
 
 
  137template<storm::dd::DdType DdType, 
typename ValueType>
 
  139    return abstractionInformation;
 
 
  142template<storm::dd::DdType DdType, 
typename ValueType>
 
  144    return automata.front().getGuard(player1Choice);
 
 
  147template<storm::dd::DdType DdType, 
typename ValueType>
 
  149    return automata.front().getNumberOfUpdates(player1Choice);
 
 
  152template<storm::dd::DdType DdType, 
typename ValueType>
 
  154    uint64_t player1Choice, uint64_t auxiliaryChoice)
 const {
 
  155    return automata.front().getVariableUpdates(player1Choice, auxiliaryChoice);
 
 
  158template<storm::dd::DdType DdType, 
typename ValueType>
 
  160    return automata.front().getAssignedVariables(player1Choice);
 
 
  163template<storm::dd::DdType DdType, 
typename ValueType>
 
  165    return std::make_pair(0, automata.front().getNumberOfEdges());
 
 
  168template<storm::dd::DdType DdType, 
typename ValueType>
 
  170    return model.get().getInitialStatesExpression({model.get().getAutomaton(0)});
 
 
  173template<storm::dd::DdType DdType, 
typename ValueType>
 
  176                                                                      smtSolverFactory->create(abstractionInformation.getExpressionManager()));
 
 
  180template<storm::dd::DdType DdType, 
typename ValueType>
 
  186    game.
bdd &= edgeDecoratorAdd.notZero();
 
  189    std::set<storm::expressions::Variable> variablesToAbstract(abstractionInformation.getPlayer1VariableSet(abstractionInformation.getPlayer1VariableCount()));
 
  190    std::set<storm::expressions::Variable> successorAndAuxVariables(abstractionInformation.getSuccessorVariables());
 
  192    variablesToAbstract.insert(player2Variables.begin(), player2Variables.end());
 
  193    auto auxVariables = abstractionInformation.getAuxVariableSet(0, abstractionInformation.getAuxVariableCount());
 
  194    variablesToAbstract.insert(auxVariables.begin(), auxVariables.end());
 
  195    successorAndAuxVariables.insert(auxVariables.begin(), auxVariables.end());
 
  199    if (this->isRestrictToRelevantStatesSet()) {
 
  201        for (
auto const& expression : this->terminalStateExpressions) {
 
  202            nonTerminalStates &= !this->getStates(expression);
 
  204        if (this->hasTargetStateExpression()) {
 
  205            nonTerminalStates &= !this->getStates(this->getTargetStateExpression());
 
  208    relevantStatesWatch.stop();
 
  212    if (this->restrictToValidBlocks) {
 
  217        auto choicesWithOnlyValidSuccessors =
 
  218            !game.
bdd.
andExists(!validBlocks.
swapVariables(abstractionInformation.getSourceSuccessorVariablePairs()), successorAndAuxVariables) &&
 
  222        extendedTransitionRelation &= validBlocks && choicesWithOnlyValidSuccessors;
 
  223        initialStates &= validBlocks;
 
  228    initialStates.
addMetaVariables(abstractionInformation.getSourcePredicateVariables());
 
  231                                                   abstractionInformation.getSuccessorVariables())
 
  234    relevantStatesWatch.start();
 
  235    if (this->isRestrictToRelevantStatesSet() && this->hasTargetStateExpression()) {
 
  237        storm::dd::Bdd<DdType> targetStates = reachableStates && this->getStates(this->getTargetStateExpression());
 
  241            targetStates, reachableStates, transitionRelation, abstractionInformation.getSourceVariables(), abstractionInformation.getSuccessorVariables());
 
  246            (reachableStates && !targetStates)
 
  247                .relationalProduct(transitionRelation, abstractionInformation.getSourceVariables(), abstractionInformation.getSuccessorVariables());
 
  250        transitionRelation &= reachableStates && reachableStates.
swapVariables(abstractionInformation.getExtendedSourceSuccessorVariablePairs());
 
  252        relevantStatesWatch.stop();
 
  253        STORM_LOG_TRACE(
"Restricting to relevant states took " << relevantStatesWatch.getTimeInMilliseconds() << 
"ms.");
 
  259    deadlockStates = reachableStates && !deadlockStates;
 
  263    if (!deadlockStates.
isZero()) {
 
  264        deadlockTransitions = (deadlockStates && abstractionInformation.getAllPredicateIdentities() && abstractionInformation.getAllLocationIdentities() &&
 
  265                               abstractionInformation.encodePlayer1Choice(0, abstractionInformation.getPlayer1VariableCount()) &&
 
  267                               abstractionInformation.encodeAux(0, 0, abstractionInformation.getAuxVariableCount()))
 
  268                                  .
template toAdd<ValueType>();
 
  272    BottomStateResult<DdType> bottomStateResult(abstractionInformation.getDdManager().getBddZero(), abstractionInformation.getDdManager().getBddZero());
 
  274    bool hasBottomStates = !bottomStateResult.states.isZero();
 
  280        (extendedTransitionRelation && reachableStates && reachableStates.
swapVariables(abstractionInformation.getExtendedSourceSuccessorVariablePairs()))
 
  281            .
template toAdd<ValueType>();
 
  282    transitionMatrix *= edgeDecoratorAdd;
 
  283    transitionMatrix += deadlockTransitions;
 
  287        (abstractionInformation.getBottomStateBdd(
true, 
true) && abstractionInformation.getBottomStateBdd(
false, 
true)).
template toAdd<ValueType>();
 
  288    reachableStates &= abstractionInformation.getBottomStateBdd(
true, 
true);
 
  289    initialStates &= abstractionInformation.getBottomStateBdd(
true, 
true);
 
  292    if (hasBottomStates) {
 
  293        transitionMatrix += bottomStateResult.transitions.template toAdd<ValueType>();
 
  294        reachableStates |= bottomStateResult.states;
 
  297    std::set<storm::expressions::Variable> allNondeterminismVariables = player2Variables;
 
  298    allNondeterminismVariables.insert(abstractionInformation.getPlayer1Variables().begin(), abstractionInformation.getPlayer1Variables().end());
 
  300    std::set<storm::expressions::Variable> allSourceVariables(abstractionInformation.getSourceVariables());
 
  301    allSourceVariables.insert(abstractionInformation.getBottomStateVariable(
true));
 
  302    std::set<storm::expressions::Variable> allSuccessorVariables(abstractionInformation.getSuccessorVariables());
 
  303    allSuccessorVariables.insert(abstractionInformation.getBottomStateVariable(
false));
 
  305    return std::make_unique<MenuGame<DdType, ValueType>>(
 
  306        abstractionInformation.getDdManagerAsSharedPointer(), reachableStates, initialStates, abstractionInformation.
getDdManager().getBddZero(),
 
  307        transitionMatrix, bottomStateResult.states, allSourceVariables, allSuccessorVariables, abstractionInformation.getExtendedSourceSuccessorVariablePairs(),
 
  308        std::set<storm::expressions::Variable>(abstractionInformation.getPlayer1Variables().begin(), abstractionInformation.getPlayer1Variables().end()),
 
  309        player2Variables, allNondeterminismVariables, auxVariables, abstractionInformation.getPredicateToBddMap());
 
  312template<storm::dd::DdType DdType, 
typename ValueType>
 
  315    this->exportToDot(*currentGame, filename, highlightStates, filter);
 
 
  318template<storm::dd::DdType DdType, 
typename ValueType>
 
  320    return abstractionInformation.getNumberOfPredicates();
 
 
  323template<storm::dd::DdType DdType, 
typename ValueType>
 
  325    terminalStateExpressions.emplace_back(expression);
 
 
  328template<storm::dd::DdType DdType, 
typename ValueType>
 
  330    for (
auto& automaton : automata) {
 
  331        automaton.notifyGuardsArePredicates();
 
 
  338#ifdef STORM_HAVE_CARL 
Bdd< LibraryType > existsAbstract(std::set< storm::expressions::Variable > const &metaVariables) const
Existentially abstracts from the given meta variables.
bool isZero() const
Retrieves whether this DD represents the constant zero function.
Bdd< LibraryType > andExists(Bdd< LibraryType > const &other, std::set< storm::expressions::Variable > const &existentialVariables) const
Computes the logical and of the current and the given BDD and existentially abstracts from the given ...
Bdd< LibraryType > swapVariables(std::vector< std::pair< storm::expressions::Variable, storm::expressions::Variable > > const &metaVariablePairs) const
Swaps the given pairs of meta variables in the BDD.
void addMetaVariables(std::set< storm::expressions::Variable > const &metaVariables)
Adds the given set of meta variables to the DD.
DdManager< LibraryType > & getDdManager() const
Retrieves the manager that is responsible for this DD.
storm::dd::Bdd< DdType > translate(storm::expressions::Expression const &expression)
std::vector< storm::expressions::Expression > const & getPredicates() const
storm::expressions::Expression getInitialStatesExpression() const
Retrieves the expression defining the legal initial values of the variables.
This class represents the settings for the abstraction procedures.
A class that provides convenience operations to display run times.
#define STORM_LOG_DEBUG(message)
#define STORM_LOG_TRACE(message)
#define STORM_LOG_WARN_COND(cond, message)
#define STORM_LOG_THROW(cond, exception, message)
storm::dd::Bdd< Type > computeBackwardsReachableStates(storm::dd::Bdd< Type > const &initialStates, storm::dd::Bdd< Type > const &constraintStates, storm::dd::Bdd< Type > const &transitions, std::set< storm::expressions::Variable > const &rowMetaVariables, std::set< storm::expressions::Variable > const &columnMetaVariables)
std::pair< storm::dd::Bdd< Type >, uint64_t > computeReachableStates(storm::dd::Bdd< Type > const &initialStates, storm::dd::Bdd< Type > const &transitions, std::set< storm::expressions::Variable > const &rowMetaVariables, std::set< storm::expressions::Variable > const &columnMetaVariables)
uint_fast64_t numberOfPlayer2Variables
storm::dd::Bdd< DdType > bdd