Browse Source

optimizations to trace formula generation

tempestpy_adaptions
dehnert 7 years ago
parent
commit
64cd0ae212
  1. 1
      src/storm/abstraction/MenuGameAbstractor.h
  2. 312
      src/storm/abstraction/MenuGameRefiner.cpp
  3. 8
      src/storm/abstraction/MenuGameRefiner.h
  4. 5
      src/storm/abstraction/jani/AutomatonAbstractor.cpp
  5. 5
      src/storm/abstraction/jani/AutomatonAbstractor.h
  6. 12
      src/storm/abstraction/jani/EdgeAbstractor.cpp
  7. 8
      src/storm/abstraction/jani/EdgeAbstractor.h
  8. 7
      src/storm/abstraction/jani/JaniMenuGameAbstractor.cpp
  9. 5
      src/storm/abstraction/jani/JaniMenuGameAbstractor.h
  10. 12
      src/storm/abstraction/prism/CommandAbstractor.cpp
  11. 8
      src/storm/abstraction/prism/CommandAbstractor.h
  12. 5
      src/storm/abstraction/prism/ModuleAbstractor.cpp
  13. 5
      src/storm/abstraction/prism/ModuleAbstractor.h
  14. 5
      src/storm/abstraction/prism/PrismMenuGameAbstractor.cpp
  15. 5
      src/storm/abstraction/prism/PrismMenuGameAbstractor.h

1
src/storm/abstraction/MenuGameAbstractor.h

@ -37,6 +37,7 @@ namespace storm {
virtual uint64_t getNumberOfUpdates(uint64_t player1Choice) const = 0;
std::vector<std::map<storm::expressions::Variable, storm::expressions::Expression>> getVariableUpdates(uint64_t player1Choice) const;
virtual std::map<storm::expressions::Variable, storm::expressions::Expression> getVariableUpdates(uint64_t player1Choice, uint64_t auxiliaryChoice) const = 0;
virtual std::set<storm::expressions::Variable> const& getAssignedVariables(uint64_t player1Choice) const = 0;
virtual storm::expressions::Expression getInitialExpression() const = 0;
/*!

312
src/storm/abstraction/MenuGameRefiner.cpp

@ -12,6 +12,7 @@
#include "storm/storage/dd/Odd.h"
#include "storm/utility/dd.h"
#include "storm/utility/solver.h"
#include "storm/utility/shortestPaths.h"
#include "storm/solver/MathsatSmtSolver.h"
@ -478,6 +479,10 @@ namespace storm {
for (auto& predicate : predicates.back()) {
predicate = predicate.changeManager(expressionManager);
}
// Add ranges of variables.
for (auto const& pred : abstractionInformation.getConstraints()) {
predicates.back().push_back(pred.changeManager(expressionManager));
}
// Perform a backward search for an initial state.
storm::dd::Bdd<Type> currentState = pivotState;
@ -526,7 +531,10 @@ namespace storm {
for (auto& predicate : predicates.back()) {
predicate = predicate.changeManager(expressionManager).substitute(substitution);
}
// Add ranges of variables.
for (auto const& pred : abstractionInformation.getConstraints()) {
predicates.back().push_back(pred.changeManager(expressionManager).substitute(substitution));
}
// Move backwards one step.
lastSubstitution = std::move(substitution);
currentState = predecessorTransition.existsAbstract(variablesToAbstract);
@ -540,7 +548,28 @@ namespace storm {
const uint64_t ExplicitPivotStateResult<ValueType>::NO_PREDECESSOR = std::numeric_limits<uint64_t>::max();
template<storm::dd::DdType Type, typename ValueType>
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, ExplicitPivotStateResult<ValueType> const& pivotStateResult, storm::dd::Odd const& odd) const {
std::pair<std::vector<uint64_t>, std::vector<uint64_t>> MenuGameRefiner<Type, ValueType>::buildReversedLabeledPath(ExplicitPivotStateResult<ValueType> const& pivotStateResult) const {
std::pair<std::vector<uint64_t>, std::vector<uint64_t>> result;
result.first.emplace_back(pivotStateResult.pivotState);
uint64_t currentState = pivotStateResult.predecessors[pivotStateResult.pivotState].first;
uint64_t currentAction = pivotStateResult.predecessors[pivotStateResult.pivotState].second;
while (currentState != ExplicitPivotStateResult<ValueType>::NO_PREDECESSOR) {
STORM_LOG_ASSERT(currentAction != ExplicitPivotStateResult<ValueType>::NO_PREDECESSOR, "Expected predecessor action.");
result.first.emplace_back(currentState);
result.second.emplace_back(currentAction);
currentAction = pivotStateResult.predecessors[currentState].second;
currentState = pivotStateResult.predecessors[currentState].first;
}
STORM_LOG_ASSERT(result.first.size() == result.second.size() + 1, "Path size mismatch.");
return result;
}
template<storm::dd::DdType Type, typename ValueType>
std::pair<std::vector<std::vector<storm::expressions::Expression>>, std::map<storm::expressions::Variable, storm::expressions::Expression>> MenuGameRefiner<Type, ValueType>::buildTraceFromReversedLabeledPath(storm::expressions::ExpressionManager& expressionManager, std::vector<uint64_t> const& reversedPath, std::vector<uint64_t> const& reversedLabels, storm::dd::Odd const& odd, std::vector<uint64_t> const* stateToOffset) const {
STORM_LOG_ASSERT(reversedPath.size() == reversedLabels.size() + 1, "Path size mismatch.");
std::vector<std::vector<storm::expressions::Expression>> predicates;
@ -557,94 +586,128 @@ namespace storm {
for (auto const& variable : oldVariables) {
oldToNewVariables[variable] = expressionManager.getVariable(variable.getName());
}
std::map<storm::expressions::Variable, storm::expressions::Expression> lastSubstitution;
std::map<storm::expressions::Variable, storm::expressions::Expression> currentSubstitution;
for (auto const& variable : oldToNewVariables) {
lastSubstitution[variable.second] = variable.second;
currentSubstitution[variable.second] = variable.second;
}
std::map<storm::expressions::Variable, storm::expressions::Expression> stepVariableToCopiedVariableMap;
// The state valuation also includes the bottom state, so we need to reserve one more than the number of
// predicates here.
storm::storage::BitVector extendedPredicateValuation = odd.getEncoding(pivotStateResult.pivotState, abstractionInformation.getNumberOfPredicates() + 1);
auto pathIt = reversedPath.rbegin();
// Decode initial state. The state valuation also includes the bottom state, so we need to reserve one more
// than the number of predicates here.
storm::storage::BitVector extendedPredicateValuation = odd.getEncoding(stateToOffset ? (*stateToOffset)[*pathIt] : *pathIt, abstractionInformation.getNumberOfPredicates() + 1);
++pathIt;
// Decode pivot state.
// Add all predicates of initial block.
predicates.emplace_back(abstractionInformation.getPredicatesExcludingBottom(extendedPredicateValuation));
for (auto& predicate : predicates.back()) {
predicate = predicate.changeManager(expressionManager);
}
// Perform a backward traversal from the pivot state along the chosen predecessors until there is no more
// predecessors.
uint64_t currentState = pivotStateResult.predecessors[pivotStateResult.pivotState].first;
uint64_t currentAction = pivotStateResult.predecessors[pivotStateResult.pivotState].second;
while (currentState != ExplicitPivotStateResult<ValueType>::NO_PREDECESSOR) {
// 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) {
storm::expressions::Variable variableCopy = expressionManager.declareVariableCopy(variablePair.second);
substitution[variablePair.second] = variableCopy;
stepVariableToCopiedVariableMap[variableCopy] = variablePair.second;
// Add ranges of further constraints.
for (auto const& pred : abstractionInformation.getConstraints()) {
predicates.back().push_back(pred.changeManager(expressionManager));
}
// Add initial expression.
predicates.back().push_back(initialExpression.changeManager(expressionManager));
// Traverse the path and construct necessary formula parts.
auto actionIt = reversedLabels.rbegin();
for (; pathIt != reversedPath.rend(); ++pathIt) {
// Add new predicate frame.
predicates.emplace_back();
// Add guard of action.
predicates.back().emplace_back(abstractor.get().getGuard(*actionIt).changeManager(expressionManager).substitute(currentSubstitution));
// Determine which variables are affected by the updates of the player 1 choice.
std::set<storm::expressions::Variable> const& assignedVariables = abstractor.get().getAssignedVariables(*actionIt);
// Create new instances of the affected variables.
std::map<storm::expressions::Variable, storm::expressions::Variable> newVariableMaps;
for (auto const& variable : assignedVariables) {
storm::expressions::Variable variableCopy = expressionManager.declareVariableCopy(variable);
newVariableMaps[oldToNewVariables.at(variable)] = variableCopy;
stepVariableToCopiedVariableMap[variableCopy] = variable;
}
// Retrieve the variable updates that the predecessor needs to perform to get to the current state.
auto variableUpdateVector = abstractor.get().getVariableUpdates(currentAction);
// Retrieves the possible updates to the variables.
auto variableUpdateVector = abstractor.get().getVariableUpdates(*actionIt);
// Encode these updates.
storm::expressions::Expression allVariableUpdateExpression;
for (auto const& variableUpdates : variableUpdateVector) {
storm::expressions::Expression variableUpdateExpression;
for (auto const& oldNewVariablePair : oldToNewVariables) {
storm::expressions::Variable const& newVariable = oldNewVariablePair.second;
// If the variable was set, use its update expression.
auto updateIt = variableUpdates.find(oldNewVariablePair.first);
if (updateIt != variableUpdates.end()) {
auto const& update = *updateIt;
if (update.second.hasBooleanType()) {
variableUpdateExpression = variableUpdateExpression && storm::expressions::iff(lastSubstitution.at(newVariable), update.second.changeManager(expressionManager).substitute(substitution));
} else {
variableUpdateExpression = variableUpdateExpression && lastSubstitution.at(newVariable) == update.second.changeManager(expressionManager).substitute(substitution);
}
for (auto const& update : variableUpdates) {
if (update.second.hasBooleanType()) {
variableUpdateExpression = variableUpdateExpression && storm::expressions::iff(newVariableMaps.at(update.first), update.second.changeManager(expressionManager).substitute(currentSubstitution));
} else {
// Otherwise, make sure that the new variable maintains the old value.
if (newVariable.hasBooleanType()) {
variableUpdateExpression = variableUpdateExpression && storm::expressions::iff(lastSubstitution.at(newVariable), substitution.at(newVariable));
} else {
variableUpdateExpression = variableUpdateExpression && lastSubstitution.at(newVariable) == substitution.at(newVariable);
}
variableUpdateExpression = variableUpdateExpression && newVariableMaps.at(update.first) == update.second.changeManager(expressionManager).substitute(currentSubstitution);
}
}
allVariableUpdateExpression = allVariableUpdateExpression || variableUpdateExpression;
}
// Add variable update expression.
predicates.back().emplace_back(allVariableUpdateExpression);
// Add the guard of the choice.
predicates.back().emplace_back(abstractor.get().getGuard(currentAction).changeManager(expressionManager).substitute(substitution));
// Incorporate the new variables in the current substitution.
for (auto const& variablePair : newVariableMaps) {
currentSubstitution[variablePair.first] = variablePair.second;
}
// Retrieve the predicate valuation in the predecessor.
extendedPredicateValuation = odd.getEncoding(currentState, abstractionInformation.getNumberOfPredicates() + 1);
predicates.emplace_back(abstractionInformation.getPredicatesExcludingBottom(extendedPredicateValuation));
for (auto& predicate : predicates.back()) {
predicate = predicate.changeManager(expressionManager).substitute(substitution);
// Decode current state.
extendedPredicateValuation = odd.getEncoding(stateToOffset ? (*stateToOffset)[*pathIt] : *pathIt, abstractionInformation.getNumberOfPredicates() + 1);
// Encode the predicates whose value might have changed.
// FIXME: could be optimized by precomputation.
for (uint64_t predicateIndex = 0; predicateIndex < abstractionInformation.getNumberOfPredicates(); ++predicateIndex) {
auto const& predicate = abstractionInformation.getPredicateByIndex(predicateIndex);
std::set<storm::expressions::Variable> usedVariables = predicate.getVariables();
bool containsAssignedVariables = false;
for (auto usedIt = usedVariables.begin(), assignedIt = assignedVariables.begin();;) {
if (usedIt == usedVariables.end() || assignedIt == assignedVariables.end()) {
break;
}
if (*usedIt == *assignedIt) {
containsAssignedVariables = true;
break;
}
if (*usedIt < *assignedIt) {
++usedIt;
} else {
++assignedIt;
}
}
if (containsAssignedVariables) {
auto transformedPredicate = predicate.changeManager(expressionManager).substitute(currentSubstitution);
predicates.back().emplace_back(extendedPredicateValuation.get(predicateIndex + 1) ? transformedPredicate : !transformedPredicate);
}
}
// Move backwards one step.
lastSubstitution = std::move(substitution);
// Enforce ranges of all assigned variables.
// for (auto const& variablePair : newVariableMaps) {
// for (auto const& )
// }
std::pair<uint64_t, uint64_t> predecessorPair = pivotStateResult.predecessors[currentState];
currentState = predecessorPair.first;
currentAction = predecessorPair.second;
++actionIt;
}
predicates.back().push_back(initialExpression.changeManager(expressionManager).substitute(lastSubstitution));
std::reverse(predicates.begin(), predicates.end());
return std::make_pair(predicates, stepVariableToCopiedVariableMap);
}
template<storm::dd::DdType Type>
boost::optional<RefinementPredicates> derivePredicatesFromInterpolation(storm::expressions::ExpressionManager& interpolationManager, AbstractionInformation<Type> const& abstractionInformation, std::vector<std::vector<storm::expressions::Expression>> const& trace, std::map<storm::expressions::Variable, storm::expressions::Expression> const& variableSubstitution) {
template<storm::dd::DdType Type, typename ValueType>
boost::optional<RefinementPredicates> MenuGameRefiner<Type, ValueType>::derivePredicatesFromInterpolationFromTrace(storm::expressions::ExpressionManager& interpolationManager, std::vector<std::vector<storm::expressions::Expression>> const& trace, std::map<storm::expressions::Variable, storm::expressions::Expression> const& variableSubstitution) const {
AbstractionInformation<Type> const& abstractionInformation = abstractor.get().getAbstractionInformation();
auto start = std::chrono::high_resolution_clock::now();
boost::optional<RefinementPredicates> predicates;
@ -656,7 +719,6 @@ namespace storm {
auto traceIt = trace.rbegin();
auto traceIte = trace.rend();
for (; traceIt != traceIte; ++traceIt) {
auto iterationStart = std::chrono::high_resolution_clock::now();
auto const& step = *traceIt;
interpolatingSolver.push();
@ -664,13 +726,11 @@ namespace storm {
for (auto const& predicate : step) {
interpolatingSolver.add(predicate);
}
auto iterationEnd = std::chrono::high_resolution_clock::now();
STORM_LOG_TRACE("Asserting step of trace formula took " << std::chrono::duration_cast<std::chrono::milliseconds>(iterationEnd - iterationStart).count() << "ms.");
++stepCounter;
}
auto assertionEnd = std::chrono::high_resolution_clock::now();
STORM_LOG_TRACE("Asserting trace formula until unsatisfiability took " << std::chrono::duration_cast<std::chrono::milliseconds>(assertionEnd - assertionStart).count() << "ms.");
STORM_LOG_TRACE("Asserting trace formula took " << std::chrono::duration_cast<std::chrono::milliseconds>(assertionEnd - assertionStart).count() << "ms.");
// Now encode the trace as an SMT problem.
storm::solver::SmtSolver::CheckResult result = interpolatingSolver.check();
@ -682,11 +742,18 @@ namespace storm {
for (uint64_t step = 0; step < stepCounter; ++step) {
prefix.push_back(step);
storm::expressions::Expression interpolant = interpolatingSolver.getInterpolant(prefix).substitute(variableSubstitution).changeManager(abstractionInformation.getExpressionManager());
if (!interpolant.isTrue() && !interpolant.isFalse()) {
if (interpolant.isFalse()) {
// If the interpolant is false, it means that the prefix has become unsatisfiable.
break;
}
if (!interpolant.isTrue()) {
STORM_LOG_DEBUG("Derived new predicate (based on interpolation at step " << step << " out of " << stepCounter << "): " << interpolant);
interpolants.push_back(interpolant);
}
}
STORM_LOG_ASSERT(!interpolants.empty(), "Expected to have non-empty set of interpolants.");
predicates = boost::make_optional(RefinementPredicates(RefinementPredicates::Source::Interpolation, interpolants));
} else {
STORM_LOG_TRACE("Trace formula is satisfiable, not using interpolation.");
@ -723,7 +790,7 @@ namespace storm {
auto end = std::chrono::high_resolution_clock::now();
STORM_LOG_DEBUG("Building the trace and variable substitution for interpolation from symbolic most-probable paths result took " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms.");
return storm::abstraction::derivePredicatesFromInterpolation(*interpolationManager, abstractionInformation, traceAndVariableSubstitution.first, traceAndVariableSubstitution.second);
return derivePredicatesFromInterpolationFromTrace(*interpolationManager, traceAndVariableSubstitution.first, traceAndVariableSubstitution.second);
}
template<storm::dd::DdType Type, typename ValueType>
@ -735,11 +802,18 @@ namespace storm {
// Build the trace of the most probable path in terms of which predicates hold in each step.
auto start = std::chrono::high_resolution_clock::now();
std::pair<std::vector<std::vector<storm::expressions::Expression>>, std::map<storm::expressions::Variable, storm::expressions::Expression>> traceAndVariableSubstitution = buildTrace(*interpolationManager, game, pivotStateResult, odd);
std::pair<std::vector<uint64_t>, std::vector<uint64_t>> labeledReversedPath = buildReversedLabeledPath(pivotStateResult);
// If the initial state is the pivot state, we can stop here.
if (labeledReversedPath.first.size() == 1) {
return boost::none;
}
std::pair<std::vector<std::vector<storm::expressions::Expression>>, std::map<storm::expressions::Variable, storm::expressions::Expression>> traceAndVariableSubstitution = buildTraceFromReversedLabeledPath(*interpolationManager, labeledReversedPath.first, labeledReversedPath.second, odd);
auto end = std::chrono::high_resolution_clock::now();
STORM_LOG_DEBUG("Building the trace and variable substitution for interpolation from explicit most-probable paths result took " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms.");
return storm::abstraction::derivePredicatesFromInterpolation(*interpolationManager, abstractionInformation, traceAndVariableSubstitution.first, traceAndVariableSubstitution.second);
return derivePredicatesFromInterpolationFromTrace(*interpolationManager, traceAndVariableSubstitution.first, traceAndVariableSubstitution.second);
}
template<storm::dd::DdType Type, typename ValueType>
@ -980,9 +1054,112 @@ namespace storm {
return boost::none;
}
template<storm::dd::DdType Type, typename ValueType>
boost::optional<RefinementPredicates> MenuGameRefiner<Type, ValueType>::derivePredicatesFromInterpolationReversedPath(storm::dd::Odd const& odd, storm::expressions::ExpressionManager& interpolationManager, std::vector<uint64_t> const& reversedPath, std::vector<uint64_t> const& stateToOffset, std::vector<uint64_t> const& reversedLabels) const {
// Build the trace of the most probable path in terms of which predicates hold in each step.
auto start = std::chrono::high_resolution_clock::now();
std::pair<std::vector<std::vector<storm::expressions::Expression>>, std::map<storm::expressions::Variable, storm::expressions::Expression>> traceAndVariableSubstitution = buildTraceFromReversedLabeledPath(interpolationManager, reversedPath, reversedLabels, odd, &stateToOffset);
auto end = std::chrono::high_resolution_clock::now();
STORM_LOG_DEBUG("Building the trace and variable substitution for interpolation from explicit most-probable paths result took " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms.");
return derivePredicatesFromInterpolationFromTrace(interpolationManager, traceAndVariableSubstitution.first, traceAndVariableSubstitution.second);
}
template<storm::dd::DdType Type, typename ValueType>
boost::optional<RefinementPredicates> MenuGameRefiner<Type, ValueType>::derivePredicatesFromInterpolationKShortestPaths(storm::dd::Odd const& odd, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<uint64_t> const& player1Grouping, std::vector<uint64_t> const& player1Labeling, std::vector<uint64_t> const& player2Labeling, storm::storage::BitVector const& initialStates, storm::storage::BitVector const& constraintStates, storm::storage::BitVector const& targetStates, ValueType minProbability, ValueType maxProbability, ExplicitGameStrategyPair const& maxStrategyPair) const {
// Extract the underlying DTMC of the max strategy pair.
// Start by determining which states are reachable.
storm::storage::BitVector reachableStatesInMaxFragment(initialStates);
std::vector<uint64_t> stack(initialStates.begin(), initialStates.end());
while (!stack.empty()) {
uint64_t currentState = stack.back();
stack.pop_back();
uint64_t player2Successor = maxStrategyPair.getPlayer1Strategy().getChoice(currentState);
uint64_t player2Choice = maxStrategyPair.getPlayer2Strategy().getChoice(player2Successor);
for (auto const& successorEntry : transitionMatrix.getRow(player2Choice)) {
if (!reachableStatesInMaxFragment.get(successorEntry.getColumn())) {
reachableStatesInMaxFragment.set(successorEntry.getColumn());
if (!targetStates.get(successorEntry.getColumn())) {
stack.push_back(successorEntry.getColumn());
}
}
}
}
uint64_t numberOfReachableStates = reachableStatesInMaxFragment.getNumberOfSetBits();
std::vector<uint64_t> reachableStatesWithLowerIndex = reachableStatesInMaxFragment.getNumberOfSetBitsBeforeIndices();
// Now construct the matrix just for these entries.
storm::storage::SparseMatrixBuilder<ValueType> builder(numberOfReachableStates, numberOfReachableStates);
storm::storage::BitVector dtmcInitialStates(numberOfReachableStates);
typename storm::utility::ksp::ShortestPathsGenerator<ValueType>::StateProbMap targetProbabilities;
std::vector<uint64_t> stateToOffset(numberOfReachableStates);
std::vector<uint64_t> dtmcPlayer1Labels(numberOfReachableStates);
uint64_t currentRow = 0;
for (auto currentState : reachableStatesInMaxFragment) {
stateToOffset[currentRow] = currentState;
if (targetStates.get(currentState)) {
targetProbabilities[currentRow] = storm::utility::one<ValueType>();
builder.addNextValue(currentRow, currentRow, storm::utility::one<ValueType>());
} else {
uint64_t player2Successor = maxStrategyPair.getPlayer1Strategy().getChoice(currentState);
dtmcPlayer1Labels[currentRow] = player1Labeling[player2Successor];
uint64_t player2Choice = maxStrategyPair.getPlayer2Strategy().getChoice(player2Successor);
for (auto const& successorEntry : transitionMatrix.getRow(player2Choice)) {
builder.addNextValue(currentRow, reachableStatesWithLowerIndex[successorEntry.getColumn()], successorEntry.getValue());
}
}
if (initialStates.get(currentState)) {
dtmcInitialStates.set(currentRow);
}
++currentRow;
}
storm::storage::SparseMatrix<ValueType> dtmcMatrix = builder.build();
// Create a new expression manager that we can use for the interpolation.
AbstractionInformation<Type> const& abstractionInformation = abstractor.get().getAbstractionInformation();
std::shared_ptr<storm::expressions::ExpressionManager> interpolationManager = abstractionInformation.getExpressionManager().clone();
// Use a path generator to compute k-shortest-paths.
storm::utility::ksp::ShortestPathsGenerator<ValueType> pathGenerator(dtmcMatrix, targetProbabilities, dtmcInitialStates, storm::utility::ksp::MatrixFormat::straight);
uint64_t currentShortestPath = 1;
bool considerNextPath = true;
boost::optional<RefinementPredicates> result;
while (currentShortestPath < 100 && considerNextPath) {
auto reversedPath = pathGenerator.getPathAsList(currentShortestPath);
std::vector<uint64_t> reversedLabels;
for (auto stateIt = reversedPath.rbegin(); stateIt != reversedPath.rend() - 1; ++stateIt) {
reversedLabels.push_back(player1Labeling[maxStrategyPair.getPlayer1Strategy().getChoice(stateToOffset[*stateIt])]);
}
boost::optional<RefinementPredicates> pathPredicates = derivePredicatesFromInterpolationReversedPath(odd, *interpolationManager, reversedPath, stateToOffset, reversedLabels);
if (pathPredicates) {
if (!result) {
result = RefinementPredicates(RefinementPredicates::Source::Interpolation, pathPredicates.get().getPredicates());
} else {
result.get().addPredicates(pathPredicates.get().getPredicates());
}
}
++currentShortestPath;
}
exit(-1);
return result;
}
template<storm::dd::DdType Type, typename ValueType>
bool MenuGameRefiner<Type, ValueType>::refine(storm::abstraction::MenuGame<Type, ValueType> const& game, storm::dd::Odd const& odd, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<uint64_t> const& player1Grouping, std::vector<uint64_t> const& player1Labeling, std::vector<uint64_t> const& player2Labeling, storm::storage::BitVector const& initialStates, storm::storage::BitVector const& constraintStates, storm::storage::BitVector const& targetStates, ExplicitQualitativeGameResultMinMax const& qualitativeResult, ExplicitGameStrategyPair const& minStrategyPair, ExplicitGameStrategyPair const& maxStrategyPair) const {
// boost::optional<RefinementPredicates> kShortestPathPredicates = derivePredicatesFromInterpolationKShortestPaths(odd, transitionMatrix, player1Grouping, player1Labeling, player2Labeling, initialStates, constraintStates, targetStates, storm::utility::zero<ValueType>(), storm::utility::one<ValueType>(), maxStrategyPair);
// Compute the set of states whose result we have for the min and max case.
storm::storage::BitVector relevantStates = (qualitativeResult.getProb0Min().getStates() | qualitativeResult.getProb1Min().getStates()) & (qualitativeResult.getProb0Max().getStates() | qualitativeResult.getProb1Max().getStates());
@ -1054,6 +1231,11 @@ namespace storm {
template<storm::dd::DdType Type, typename ValueType>
bool MenuGameRefiner<Type, ValueType>::refine(storm::abstraction::MenuGame<Type, ValueType> const& game, storm::dd::Odd const& odd, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<uint64_t> const& player1Grouping, std::vector<uint64_t> const& player1Labeling, std::vector<uint64_t> const& player2Labeling, storm::storage::BitVector const& initialStates, storm::storage::BitVector const& constraintStates, storm::storage::BitVector const& targetStates, ExplicitQuantitativeResultMinMax<ValueType> const& quantitativeResult, ExplicitGameStrategyPair const& minStrategyPair, ExplicitGameStrategyPair const& maxStrategyPair) const {
ValueType lower = quantitativeResult.getMin().getRange(initialStates).first;
ValueType upper = quantitativeResult.getMax().getRange(initialStates).second;
// boost::optional<RefinementPredicates> kShortestPathPredicates = derivePredicatesFromInterpolationKShortestPaths(odd, transitionMatrix, player1Grouping, player1Labeling, player2Labeling, initialStates, constraintStates, targetStates, lower, upper, maxStrategyPair);
// Compute the set of states whose result we have for the min and max case.
storm::storage::BitVector relevantStates(odd.getTotalOffset(), true);

8
src/storm/abstraction/MenuGameRefiner.h

@ -157,12 +157,18 @@ namespace storm {
*/
std::vector<RefinementCommand> createGlobalRefinement(std::vector<storm::expressions::Expression> const& predicates) const;
boost::optional<RefinementPredicates> derivePredicatesFromInterpolationFromTrace(storm::expressions::ExpressionManager& interpolationManager, std::vector<std::vector<storm::expressions::Expression>> const& trace, std::map<storm::expressions::Variable, storm::expressions::Expression> const& variableSubstitution) const;
boost::optional<RefinementPredicates> derivePredicatesFromInterpolation(storm::abstraction::MenuGame<Type, ValueType> const& game, SymbolicPivotStateResult<Type, ValueType> const& symbolicPivotStateResult, 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;
std::pair<std::vector<std::vector<storm::expressions::Expression>>, std::map<storm::expressions::Variable, storm::expressions::Expression>> 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::pair<std::vector<std::vector<storm::expressions::Expression>>, std::map<storm::expressions::Variable, storm::expressions::Expression>> buildTrace(storm::expressions::ExpressionManager& expressionManager, storm::abstraction::MenuGame<Type, ValueType> const& game, ExplicitPivotStateResult<ValueType> const& pivotStateResult, storm::dd::Odd const& odd) const;
std::pair<std::vector<uint64_t>, std::vector<uint64_t>> buildReversedLabeledPath(ExplicitPivotStateResult<ValueType> const& pivotStateResult) const;
std::pair<std::vector<std::vector<storm::expressions::Expression>>, std::map<storm::expressions::Variable, storm::expressions::Expression>> buildTraceFromReversedLabeledPath(storm::expressions::ExpressionManager& expressionManager, std::vector<uint64_t> const& reversedPath, std::vector<uint64_t> const& reversedLabels, storm::dd::Odd const& odd, std::vector<uint64_t> const* stateToOffset = nullptr) const;
boost::optional<RefinementPredicates> derivePredicatesFromInterpolation(storm::abstraction::MenuGame<Type, ValueType> const& game, ExplicitPivotStateResult<ValueType> const& pivotStateResult, storm::dd::Odd const& odd) const;
boost::optional<RefinementPredicates> derivePredicatesFromInterpolationKShortestPaths(storm::dd::Odd const& odd, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<uint64_t> const& player1Grouping, std::vector<uint64_t> const& player1Labeling, std::vector<uint64_t> const& player2Labeling, storm::storage::BitVector const& initialStates, storm::storage::BitVector const& constraintStates, storm::storage::BitVector const& targetStates, ValueType minProbability, ValueType maxProbability, ExplicitGameStrategyPair const& maxStrategyPair) const;
boost::optional<RefinementPredicates> derivePredicatesFromInterpolationReversedPath(storm::dd::Odd const& odd, storm::expressions::ExpressionManager& interpolationManager, std::vector<uint64_t> const& reversedPath, std::vector<uint64_t> const& stateToOffset, std::vector<uint64_t> const& player1Labels) const;
void performRefinement(std::vector<RefinementCommand> const& refinementCommands) const;
/// The underlying abstractor to refine.

5
src/storm/abstraction/jani/AutomatonAbstractor.cpp

@ -61,6 +61,11 @@ namespace storm {
return edges[player1Choice].getVariableUpdates(auxiliaryChoice);
}
template <storm::dd::DdType DdType, typename ValueType>
std::set<storm::expressions::Variable> const& AutomatonAbstractor<DdType, ValueType>::getAssignedVariables(uint64_t player1Choice) const {
return edges[player1Choice].getAssignedVariables();
}
template <storm::dd::DdType DdType, typename ValueType>
GameBddResult<DdType> AutomatonAbstractor<DdType, ValueType>::abstract() {
// First, we retrieve the abstractions of all commands.

5
src/storm/abstraction/jani/AutomatonAbstractor.h

@ -68,6 +68,11 @@ namespace storm {
*/
std::map<storm::expressions::Variable, storm::expressions::Expression> getVariableUpdates(uint64_t player1Choice, uint64_t auxiliaryChoice) const;
/*!
* Retrieves the variables assigned by the given player 1 choice.
*/
std::set<storm::expressions::Variable> const& getAssignedVariables(uint64_t player1Choice) const;
/*!
* Computes the abstraction of the module wrt. to the current set of predicates.
*

12
src/storm/abstraction/jani/EdgeAbstractor.cpp

@ -36,6 +36,13 @@ namespace storm {
// Assert the guard of the command.
smtSolver->add(edge.getGuard());
// Construct assigned variables.
for (auto const& destination : edge.getDestinations()) {
for (auto const& assignment : destination.getOrderedAssignments()) {
assignedVariables.insert(assignment.getExpressionVariable());
}
}
}
template <storm::dd::DdType DdType, typename ValueType>
@ -75,6 +82,11 @@ namespace storm {
return edge.get().getDestination(auxiliaryChoice).getAsVariableToExpressionMap();
}
template <storm::dd::DdType DdType, typename ValueType>
std::set<storm::expressions::Variable> const& EdgeAbstractor<DdType, ValueType>::getAssignedVariables() const {
return assignedVariables;
}
template <storm::dd::DdType DdType, typename ValueType>
void EdgeAbstractor<DdType, ValueType>::recomputeCachedBdd() {
if (useDecomposition) {

8
src/storm/abstraction/jani/EdgeAbstractor.h

@ -83,6 +83,11 @@ namespace storm {
*/
std::map<storm::expressions::Variable, storm::expressions::Expression> getVariableUpdates(uint64_t auxiliaryChoice) const;
/*!
* Retrieves the assigned variables.
*/
std::set<storm::expressions::Variable> const& getAssignedVariables() const;
/*!
* Computes the abstraction of the edge wrt. to the current set of predicates.
*
@ -230,6 +235,9 @@ namespace storm {
// The concrete edge this abstract command refers to.
std::reference_wrapper<storm::jani::Edge const> edge;
// The variables to which this edge assigns expressions.
std::set<storm::expressions::Variable> assignedVariables;
// The local expression-related information.
LocalExpressionInformation<DdType> localExpressionInformation;

7
src/storm/abstraction/jani/JaniMenuGameAbstractor.cpp

@ -129,6 +129,11 @@ namespace storm {
return automata.front().getVariableUpdates(player1Choice, auxiliaryChoice);
}
template <storm::dd::DdType DdType, typename ValueType>
std::set<storm::expressions::Variable> const& JaniMenuGameAbstractor<DdType, ValueType>::getAssignedVariables(uint64_t player1Choice) const {
return automata.front().getAssignedVariables(player1Choice);
}
template <storm::dd::DdType DdType, typename ValueType>
std::pair<uint64_t, uint64_t> JaniMenuGameAbstractor<DdType, ValueType>::getPlayer1ChoiceRange() const {
return std::make_pair(0, automata.front().getNumberOfEdges());
@ -219,7 +224,7 @@ namespace storm {
bool hasBottomStates = !bottomStateResult.states.isZero();
// Construct the transition matrix by cutting away the transitions of unreachable states.
storm::dd::Add<DdType, ValueType> transitionMatrix = (game.bdd && reachableStates).template toAdd<ValueType>();
storm::dd::Add<DdType, ValueType> transitionMatrix = (game.bdd && reachableStates && reachableStates.swapVariables(abstractionInformation.getSourceSuccessorVariablePairs())).template toAdd<ValueType>();
transitionMatrix *= edgeDecoratorAdd;
transitionMatrix += deadlockTransitions;

5
src/storm/abstraction/jani/JaniMenuGameAbstractor.h

@ -86,6 +86,11 @@ namespace storm {
*/
std::map<storm::expressions::Variable, storm::expressions::Expression> getVariableUpdates(uint64_t player1Choice, uint64_t auxiliaryChoice) const override;
/*!
* Retrieves the variables assigned by the given player 1 choice.
*/
virtual std::set<storm::expressions::Variable> const& getAssignedVariables(uint64_t player1Choice) const override;
/*!
* Retrieves the range of player 1 choices.
*/

12
src/storm/abstraction/prism/CommandAbstractor.cpp

@ -36,6 +36,13 @@ namespace storm {
// Assert the guard of the command.
smtSolver->add(command.getGuardExpression());
// Construct assigned variables.
for (auto const& update : command.getUpdates()) {
for (auto const& assignment : update.getAssignments()) {
assignedVariables.insert(assignment.getVariable());
}
}
}
template <storm::dd::DdType DdType, typename ValueType>
@ -75,6 +82,11 @@ namespace storm {
return command.get().getUpdate(auxiliaryChoice).getAsVariableToExpressionMap();
}
template <storm::dd::DdType DdType, typename ValueType>
std::set<storm::expressions::Variable> const& CommandAbstractor<DdType, ValueType>::getAssignedVariables() const {
return assignedVariables;
}
template <storm::dd::DdType DdType, typename ValueType>
void CommandAbstractor<DdType, ValueType>::recomputeCachedBdd() {
if (useDecomposition) {

8
src/storm/abstraction/prism/CommandAbstractor.h

@ -81,6 +81,11 @@ namespace storm {
*/
std::map<storm::expressions::Variable, storm::expressions::Expression> getVariableUpdates(uint64_t auxiliaryChoice) const;
/*!
* Retrieves the assigned variables.
*/
std::set<storm::expressions::Variable> const& getAssignedVariables() const;
/*!
* Computes the abstraction of the command wrt. to the current set of predicates.
*
@ -223,6 +228,9 @@ namespace storm {
// The concrete command this abstract command refers to.
std::reference_wrapper<storm::prism::Command const> command;
// The variables to which this command assigns expressions.
std::set<storm::expressions::Variable> assignedVariables;
// The local expression-related information.
LocalExpressionInformation<DdType> localExpressionInformation;

5
src/storm/abstraction/prism/ModuleAbstractor.cpp

@ -55,6 +55,11 @@ namespace storm {
return commands[player1Choice].getVariableUpdates(auxiliaryChoice);
}
template <storm::dd::DdType DdType, typename ValueType>
std::set<storm::expressions::Variable> const& ModuleAbstractor<DdType, ValueType>::getAssignedVariables(uint64_t player1Choice) const {
return commands[player1Choice].getAssignedVariables();
}
template <storm::dd::DdType DdType, typename ValueType>
GameBddResult<DdType> ModuleAbstractor<DdType, ValueType>::abstract() {
// First, we retrieve the abstractions of all commands.

5
src/storm/abstraction/prism/ModuleAbstractor.h

@ -71,6 +71,11 @@ namespace storm {
*/
std::map<storm::expressions::Variable, storm::expressions::Expression> getVariableUpdates(uint64_t player1Choice, uint64_t auxiliaryChoice) const;
/*!
* Retrieves the variables assigned by the given player 1 choice.
*/
std::set<storm::expressions::Variable> const& getAssignedVariables(uint64_t player1Choice) const;
/*!
* Computes the abstraction of the module wrt. to the current set of predicates.
*

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

@ -125,6 +125,11 @@ namespace storm {
return modules.front().getVariableUpdates(player1Choice, auxiliaryChoice);
}
template <storm::dd::DdType DdType, typename ValueType>
std::set<storm::expressions::Variable> const& PrismMenuGameAbstractor<DdType, ValueType>::getAssignedVariables(uint64_t player1Choice) const {
return modules.front().getAssignedVariables(player1Choice);
}
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());

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

@ -86,6 +86,11 @@ namespace storm {
*/
std::map<storm::expressions::Variable, storm::expressions::Expression> getVariableUpdates(uint64_t player1Choice, uint64_t auxiliaryChoice) const override;
/*!
* Retrieves the variables assigned by the given player 1 choice.
*/
virtual std::set<storm::expressions::Variable> const& getAssignedVariables(uint64_t player1Choice) const override;
/*!
* Retrieves the range of player 1 choices.
*/

Loading…
Cancel
Save