| 
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -106,30 +106,130 @@ namespace storm { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    ++index; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // Proceed by relating the blocks via assignments until nothing changes anymore.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // Merge all blocks that are related via the right-hand side of assignments.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                for (auto const& update : command.get().getUpdates()) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    for (auto const& assignment : update.getAssignments()) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        std::set<storm::expressions::Variable> rhsVariables = assignment.getExpression().getVariables(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        if (!rhsVariables.empty()) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            uint64_t blockToKeep = variableToLocalBlockIndex.at(*rhsVariables.begin()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            for (auto const& variable : rhsVariables) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                uint64_t block = variableToLocalBlockIndex.at(variable); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                if (block != blockToKeep) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                    for (auto const& blockIndex : relevantBlockPartition[block]) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                        for (auto const& variable : localExpressionInformation.getVariableBlockWithIndex(blockIndex)) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                            variableToLocalBlockIndex[variable] = blockToKeep; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                    relevantBlockPartition[blockToKeep].insert(relevantBlockPartition[block].begin(), relevantBlockPartition[block].end()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                    relevantBlockPartition[block].clear(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // Proceed by relating the blocks via assignment-variables and the expressions of their assigned expressions.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                bool changed = false; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                do { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    changed = false; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    for (auto const& update : command.get().getUpdates()) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        for (auto const& assignment : update.getAssignments()) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            std::set<storm::expressions::Variable> rhsVariables = assignment.getExpression().getVariables(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                             | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            if (!rhsVariables.empty()) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                storm::expressions::Variable const& representativeVariable = *rhsVariables.begin(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                uint64_t representativeBlock = variableToLocalBlockIndex.at(representativeVariable); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                uint64_t assignmentVariableBlock = variableToLocalBlockIndex.at(assignment.getVariable()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                // If the blocks are different, we merge them now
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                if (assignmentVariableBlock != representativeBlock) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                    changed = true; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                     | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                    for (auto const& blockIndex : relevantBlockPartition[assignmentVariableBlock]) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                        for (auto const& variable : localExpressionInformation.getVariableBlockWithIndex(blockIndex)) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                            variableToLocalBlockIndex[variable] = representativeBlock; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                    relevantBlockPartition[representativeBlock].insert(relevantBlockPartition[assignmentVariableBlock].begin(), relevantBlockPartition[assignmentVariableBlock].end()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                    relevantBlockPartition[assignmentVariableBlock].clear(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                     | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } while (changed); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // if the decomposition has size 1, use the plain technique from before
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // otherwise, enumerate the abstract guard so we do this only once
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // then enumerate the solutions for each of the blocks of the decomposition
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // multiply the results
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // multiply with the abstract guard
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // multiply with missing identities
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // Now remove all blocks that are empty and obtain the partition.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                std::vector<std::set<uint64_t>> cleanedRelevantBlockPartition; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                for (auto& element : relevantBlockPartition) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    if (!element.empty()) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        cleanedRelevantBlockPartition.emplace_back(std::move(element)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                relevantBlockPartition = std::move(cleanedRelevantBlockPartition); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // cache and return result
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // if the decomposition has size 1, use the plain technique from before
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                if (relevantBlockPartition.size() == 1) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    STORM_LOG_TRACE("Relevant block partition size is one, falling back to regular computation."); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    recomputeCachedBdd(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } else { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    // otherwise, enumerate the abstract guard so we do this only once
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    std::set<uint64_t> relatedGuardPredicates = localExpressionInformation.getRelatedExpressions(command.get().getGuardExpression().getVariables()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    std::vector<storm::expressions::Variable> guardDecisionVariables; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    std::vector<std::pair<storm::expressions::Variable, uint_fast64_t>> guardVariablesAndPredicates; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    for (auto const& element : relevantPredicatesAndVariables.first) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        if (relatedGuardPredicates.find(element.second) != relatedGuardPredicates.end()) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            guardDecisionVariables.push_back(element.first); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            guardVariablesAndPredicates.push_back(element); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    uint64_t numberOfSolutions = 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    abstractGuard = this->getAbstractionInformation().getDdManager().getBddZero(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    smtSolver->allSat(decisionVariables, [this,&guardVariablesAndPredicates,&numberOfSolutions] (storm::solver::SmtSolver::ModelReference const& model) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        abstractGuard |= getSourceStateBdd(model, guardVariablesAndPredicates); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        ++numberOfSolutions; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        return true; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    }); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    STORM_LOG_TRACE("Enumerated " << numberOfSolutions << " for abstract guard."); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                     | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    // then enumerate the solutions for each of the blocks of the decomposition
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    for (auto const& block : relevantBlockPartition) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        std::set<uint64_t> relevantPredicates; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        for (auto const& innerBlock : block) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            relevantPredicates.insert(localExpressionInformation.getExpressionBlock(innerBlock).begin(), localExpressionInformation.getExpressionBlock(innerBlock).end()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        std::vector<storm::expressions::Variable> decisionVariables; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        std::vector<std::vector<std::pair<storm::expressions::Variable, uint_fast64_t>>> variablesAndPredicates; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        for (uint64_t updateIndex = 0; updateIndex < command.get().getNumberOfUpdates(); ++updateIndex) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            variablesAndPredicates.emplace_back(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            for (auto const& element : relevantPredicatesAndVariables.second[updateIndex]) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                if (relevantPredicates.find(element.second) != relevantPredicates.end()) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                    decisionVariables.push_back(element.first); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                    variablesAndPredicates.back().push_back(element); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                     | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        std::unordered_map<storm::dd::Bdd<DdType>, std::vector<storm::dd::Bdd<DdType>>> sourceToDistributionsMap; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        numberOfSolutions = 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        smtSolver->allSat(decisionVariables, [&sourceToDistributionsMap,this,&numberOfSolutions] (storm::solver::SmtSolver::ModelReference const& model) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            sourceToDistributionsMap[getSourceStateBdd(model, relevantPredicatesAndVariables.first)].push_back(getDistributionBdd(model, relevantPredicatesAndVariables.second)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            ++numberOfSolutions; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            return true; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        }); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                     | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    // multiply the results
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                     | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    // multiply with the abstract guard
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                     | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    // multiply with missing identities
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                     | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    // cache and return result
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					             | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            template <storm::dd::DdType DdType, typename ValueType> | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -141,7 +241,7 @@ namespace storm { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                std::unordered_map<storm::dd::Bdd<DdType>, std::vector<storm::dd::Bdd<DdType>>> sourceToDistributionsMap; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                uint64_t numberOfSolutions = 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                smtSolver->allSat(decisionVariables, [&sourceToDistributionsMap,this,&numberOfSolutions] (storm::solver::SmtSolver::ModelReference const& model) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    sourceToDistributionsMap[getSourceStateBdd(model)].push_back(getDistributionBdd(model)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    sourceToDistributionsMap[getSourceStateBdd(model, relevantPredicatesAndVariables.first)].push_back(getDistributionBdd(model, relevantPredicatesAndVariables.second)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    ++numberOfSolutions; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    return true; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                }); | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -283,9 +383,9 @@ namespace storm { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					             | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            template <storm::dd::DdType DdType, typename ValueType> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            storm::dd::Bdd<DdType> CommandAbstractor<DdType, ValueType>::getSourceStateBdd(storm::solver::SmtSolver::ModelReference const& model) const { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            storm::dd::Bdd<DdType> CommandAbstractor<DdType, ValueType>::getSourceStateBdd(storm::solver::SmtSolver::ModelReference const& model, std::vector<std::pair<storm::expressions::Variable, uint_fast64_t>> const& variablePredicates) const { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                storm::dd::Bdd<DdType> result = this->getAbstractionInformation().getDdManager().getBddOne(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                for (auto const& variableIndexPair : relevantPredicatesAndVariables.first) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                for (auto const& variableIndexPair : variablePredicates) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    if (model.getBooleanValue(variableIndexPair.first)) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        result &= this->getAbstractionInformation().encodePredicateAsSource(variableIndexPair.second); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    } else { | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -298,14 +398,14 @@ namespace storm { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					             | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            template <storm::dd::DdType DdType, typename ValueType> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            storm::dd::Bdd<DdType> CommandAbstractor<DdType, ValueType>::getDistributionBdd(storm::solver::SmtSolver::ModelReference const& model) const { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            storm::dd::Bdd<DdType> CommandAbstractor<DdType, ValueType>::getDistributionBdd(storm::solver::SmtSolver::ModelReference const& model, std::vector<std::vector<std::pair<storm::expressions::Variable, uint_fast64_t>>> const& variablePredicates) const { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                storm::dd::Bdd<DdType> result = this->getAbstractionInformation().getDdManager().getBddZero(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                for (uint_fast64_t updateIndex = 0; updateIndex < command.get().getNumberOfUpdates(); ++updateIndex) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    storm::dd::Bdd<DdType> updateBdd = this->getAbstractionInformation().getDdManager().getBddOne(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    // Translate block variables for this update into a successor block.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    for (auto const& variableIndexPair : relevantPredicatesAndVariables.second[updateIndex]) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    for (auto const& variableIndexPair : variablePredicates[updateIndex]) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        if (model.getBooleanValue(variableIndexPair.first)) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            updateBdd &= this->getAbstractionInformation().encodePredicateAsSuccessor(variableIndexPair.second); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        } else { | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
				
				 | 
				
					
  |