| 
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -360,8 +360,8 @@ namespace storm { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					         | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        template<storm::dd::DdType Type, typename ValueType> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        std::vector<std::vector<storm::expressions::Expression>> MenuGameRefiner<Type, ValueType>::buildTrace(storm::expressions::ExpressionManager& expressionManager, storm::abstraction::MenuGame<Type, ValueType> const& game, storm::dd::Bdd<Type> const& spanningTree, storm::dd::Bdd<Type> const& pivotState) const { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            std::vector<std::vector<storm::expressions::Expression>> result; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        std::pair<std::vector<std::vector<storm::expressions::Expression>>, std::map<storm::expressions::Variable, storm::expressions::Expression>> MenuGameRefiner<Type, ValueType>::buildTrace(storm::expressions::ExpressionManager& expressionManager, storm::abstraction::MenuGame<Type, ValueType> const& game, storm::dd::Bdd<Type> const& spanningTree, storm::dd::Bdd<Type> const& pivotState) const { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            std::vector<std::vector<storm::expressions::Expression>> predicates; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					             | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            // Prepare some variables.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            AbstractionInformation<Type> const& abstractionInformation = abstractor.get().getAbstractionInformation(); | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -385,12 +385,12 @@ namespace storm { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            for (auto const& variable : oldToNewVariables) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                lastSubstitution[variable.second] = variable.second; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            std::map<storm::expressions::Variable, storm::expressions::Variable> stepVariableToCopiedVariableMap; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            std::map<storm::expressions::Variable, storm::expressions::Expression> stepVariableToCopiedVariableMap; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					             | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            // Start with the target state part of the trace.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            storm::storage::BitVector decodedTargetState = abstractionInformation.decodeState(pivotState); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            result.emplace_back(abstractionInformation.getPredicates(decodedTargetState)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            for (auto& predicate : result.back()) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            predicates.emplace_back(abstractionInformation.getPredicates(decodedTargetState)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            for (auto& predicate : predicates.back()) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                predicate = predicate.changeManager(expressionManager); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					             | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -403,8 +403,6 @@ namespace storm { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                storm::dd::Bdd<Type> predecessorTransition = currentState.swapVariables(game.getRowColumnMetaVariablePairs()) && spanningTree; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                std::tuple<storm::storage::BitVector, uint64_t, uint64_t> decodedPredecessor = abstractionInformation.decodeStatePlayer1ChoiceAndUpdate(predecessorTransition); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // predecessorTransition.template toAdd<ValueType>().exportToDot("pred_" + std::to_string(cnt) + ".dot");
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // Create a new copy of each variable to use for this step.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                std::map<storm::expressions::Variable, storm::expressions::Expression> substitution; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                for (auto const& variablePair : oldToNewVariables) { | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -418,52 +416,67 @@ namespace storm { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                for (auto const& update : variableUpdates) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    storm::expressions::Variable newVariable = oldToNewVariables.at(update.first); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    if (update.second.hasBooleanType()) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        result.back().push_back(storm::expressions::iff(lastSubstitution.at(oldToNewVariables.at(update.first)), update.second.changeManager(expressionManager).substitute(substitution))); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        predicates.back().push_back(storm::expressions::iff(lastSubstitution.at(oldToNewVariables.at(update.first)), update.second.changeManager(expressionManager).substitute(substitution))); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    } else { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        result.back().push_back(lastSubstitution.at(oldToNewVariables.at(update.first)) == update.second.changeManager(expressionManager).substitute(substitution)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        predicates.back().push_back(lastSubstitution.at(oldToNewVariables.at(update.first)) == update.second.changeManager(expressionManager).substitute(substitution)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // Add the guard of the choice.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                result.back().push_back(abstractor.get().getGuard(std::get<1>(decodedPredecessor)).changeManager(expressionManager).substitute(substitution)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                predicates.back().push_back(abstractor.get().getGuard(std::get<1>(decodedPredecessor)).changeManager(expressionManager).substitute(substitution)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // Retrieve the predicate valuation in the predecessor.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                result.emplace_back(abstractionInformation.getPredicates(std::get<0>(decodedPredecessor))); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                for (auto& predicate : result.back()) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                predicates.emplace_back(abstractionInformation.getPredicates(std::get<0>(decodedPredecessor))); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                for (auto& predicate : predicates.back()) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    predicate = predicate.changeManager(expressionManager).substitute(substitution); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // Move backwards one step.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                lastSubstitution = std::move(substitution); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                currentState = predecessorTransition.existsAbstract(variablesToAbstract); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                ++cnt; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					             | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            result.back().push_back(initialExpression.changeManager(expressionManager).substitute(lastSubstitution)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            return result; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            predicates.back().push_back(initialExpression.changeManager(expressionManager).substitute(lastSubstitution)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            return std::make_pair(predicates, stepVariableToCopiedVariableMap); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					         | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        template<storm::dd::DdType Type, typename ValueType> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        boost::optional<RefinementPredicates> MenuGameRefiner<Type, ValueType>::derivePredicatesFromInterpolation(storm::abstraction::MenuGame<Type, ValueType> const& game, PivotStateResult<Type> const& pivotStateResult, 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 { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					             | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            AbstractionInformation<Type> const& abstractionInformation = abstractor.get().getAbstractionInformation(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					             | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            // Compute the most probable path from any initial state to the pivot state.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            storm::dd::Bdd<Type> spanningTree = getMostProbablePathSpanningTree(game, pivotStateResult.pivotState, pivotStateResult.fromDirection == storm::OptimizationDirection::Minimize ? minPlayer1Strategy && minPlayer2Strategy : maxPlayer1Strategy && maxPlayer2Strategy); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					             | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            // Create a new expression manager that we can use for the interpolation.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            std::shared_ptr<storm::expressions::ExpressionManager> interpolationManager = abstractor.get().getAbstractionInformation().getExpressionManager().clone(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            std::shared_ptr<storm::expressions::ExpressionManager> interpolationManager = abstractionInformation.getExpressionManager().clone(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					             | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            // Build the trace of the most probable path in terms of which predicates hold in each step.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            std::vector<std::vector<storm::expressions::Expression>> trace = buildTrace(*interpolationManager, game, spanningTree, pivotStateResult.pivotState); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            std::pair<std::vector<std::vector<storm::expressions::Expression>>, std::map<storm::expressions::Variable, storm::expressions::Expression>> traceAndVariableSubstitution = buildTrace(*interpolationManager, game, spanningTree, pivotStateResult.pivotState); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            auto const& trace = traceAndVariableSubstitution.first; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            auto const& variableSubstitution = traceAndVariableSubstitution.second; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            // Create solver and interpolation groups.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            storm::solver::MathsatSmtSolver interpolatingSolver(*interpolationManager, storm::solver::MathsatSmtSolver::Options(true, false, true)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            uint64_t stepCounter = 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            for (auto const& step : trace) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            auto traceIt = trace.rbegin(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            auto traceIte = trace.rend(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            for (; traceIt != traceIte; ++traceIt) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                auto const& step = *traceIt; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                interpolatingSolver.push(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                interpolatingSolver.setInterpolationGroup(stepCounter); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                for (auto const& predicate : step) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    interpolatingSolver.add(predicate); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                ++stepCounter; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					             | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                storm::solver::SmtSolver::CheckResult result = interpolatingSolver.check(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                // If the result already became unsatisfiable
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                if (result == storm::solver::SmtSolver::CheckResult::Unsat) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    STORM_LOG_TRACE("Trace formula became unsatisfiable after step " << (stepCounter - 1) << "."); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    break; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					             | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            // Now encode the trace as an SMT problem.
 | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -473,11 +486,13 @@ namespace storm { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                std::vector<storm::expressions::Expression> interpolants; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                std::vector<uint64_t> prefix; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                for (uint64_t step = stepCounter; step > 1; --step) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    prefix.push_back(step - 1); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    storm::expressions::Expression interpolant = interpolatingSolver.getInterpolant(prefix); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    STORM_LOG_ASSERT(!interpolant.isTrue() && !interpolant.isFalse(), "Expected other interpolant."); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    interpolants.push_back(interpolant); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                for (uint64_t step = 0; step + 1 < stepCounter; ++step) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    prefix.push_back(step); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    storm::expressions::Expression interpolant = interpolatingSolver.getInterpolant(prefix).substitute(variableSubstitution).changeManager(abstractionInformation.getExpressionManager()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    if (!interpolant.isTrue() && !interpolant.isFalse()) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        STORM_LOG_DEBUG("Derived new predicate (based on interpolation): " << interpolant); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                        interpolants.push_back(interpolant); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                return boost::make_optional(RefinementPredicates(RefinementPredicates::Source::Interpolation, interpolants)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } else { | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
				
				 | 
				
					
  |