|
@ -17,7 +17,7 @@ namespace storm { |
|
|
namespace menu_games { |
|
|
namespace menu_games { |
|
|
|
|
|
|
|
|
template <storm::dd::DdType DdType, typename ValueType> |
|
|
template <storm::dd::DdType DdType, typename ValueType> |
|
|
AbstractProgram<DdType, ValueType>::AbstractProgram(storm::expressions::ExpressionManager& expressionManager, storm::prism::Program const& program, std::vector<storm::expressions::Expression> const& initialPredicates, std::unique_ptr<storm::utility::solver::SmtSolverFactory>&& smtSolverFactory, bool addAllGuards) : smtSolverFactory(std::move(smtSolverFactory)), ddInformation(std::make_shared<storm::dd::DdManager<DdType>>()), expressionInformation(expressionManager, initialPredicates, program.getAllExpressionVariables(), program.getAllRangeExpressions()), modules(), program(program), initialStateAbstractor(expressionInformation, ddInformation, *this->smtSolverFactory), addedAllGuards(addAllGuards), bottomStateAbstractor(expressionInformation, ddInformation, *this->smtSolverFactory), currentGame(nullptr) { |
|
|
|
|
|
|
|
|
AbstractProgram<DdType, ValueType>::AbstractProgram(storm::expressions::ExpressionManager& expressionManager, storm::prism::Program const& program, std::vector<storm::expressions::Expression> const& initialPredicates, std::unique_ptr<storm::utility::solver::SmtSolverFactory>&& smtSolverFactory, bool addAllGuards) : smtSolverFactory(std::move(smtSolverFactory)), ddInformation(std::make_shared<storm::dd::DdManager<DdType>>(), initialPredicates), expressionInformation(expressionManager, initialPredicates, program.getAllExpressionVariables(), program.getAllRangeExpressions()), modules(), program(program), initialStateAbstractor(expressionInformation, ddInformation, {program.getInitialConstruct().getInitialStatesExpression()}, *this->smtSolverFactory), addedAllGuards(addAllGuards), bottomStateAbstractor(expressionInformation, ddInformation, program.getAllGuards(), *this->smtSolverFactory), currentGame(nullptr) { |
|
|
|
|
|
|
|
|
// For now, we assume that there is a single module. If the program has more than one module, it needs
|
|
|
// For now, we assume that there is a single module. If the program has more than one module, it needs
|
|
|
// to be flattened before the procedure.
|
|
|
// to be flattened before the procedure.
|
|
@ -25,15 +25,12 @@ namespace storm { |
|
|
|
|
|
|
|
|
uint_fast64_t totalNumberOfCommands = 0; |
|
|
uint_fast64_t totalNumberOfCommands = 0; |
|
|
uint_fast64_t maximalUpdateCount = 0; |
|
|
uint_fast64_t maximalUpdateCount = 0; |
|
|
|
|
|
std::vector<storm::expressions::Expression> allGuards; |
|
|
for (auto const& module : program.getModules()) { |
|
|
for (auto const& module : program.getModules()) { |
|
|
// If we were requested to add all guards to the set of predicates, we do so now.
|
|
|
// If we were requested to add all guards to the set of predicates, we do so now.
|
|
|
for (auto const& command : module.getCommands()) { |
|
|
for (auto const& command : module.getCommands()) { |
|
|
if (addAllGuards) { |
|
|
if (addAllGuards) { |
|
|
expressionInformation.predicates.push_back(command.getGuardExpression()); |
|
|
expressionInformation.predicates.push_back(command.getGuardExpression()); |
|
|
} else { |
|
|
|
|
|
// If not all guards were added, we also need to populate the bottom state abstractor.
|
|
|
|
|
|
std::cout << "adding " << !command.getGuardExpression() << std::endl; |
|
|
|
|
|
bottomStateAbstractor.addPredicate(!command.getGuardExpression()); |
|
|
|
|
|
} |
|
|
} |
|
|
maximalUpdateCount = std::max(maximalUpdateCount, static_cast<uint_fast64_t>(command.getNumberOfUpdates())); |
|
|
maximalUpdateCount = std::max(maximalUpdateCount, static_cast<uint_fast64_t>(command.getNumberOfUpdates())); |
|
|
} |
|
|
} |
|
@ -42,33 +39,25 @@ namespace storm { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Create DD variable for the command encoding.
|
|
|
// Create DD variable for the command encoding.
|
|
|
ddInformation.commandDdVariable = ddInformation.manager->addMetaVariable("command", 0, totalNumberOfCommands - 1).first; |
|
|
|
|
|
|
|
|
ddInformation.commandDdVariable = ddInformation.manager->addMetaVariable("command", 0, totalNumberOfCommands - 1, std::make_pair(storm::dd::MetaVariablePosition::Above, ddInformation.predicateDdVariables.front().first)).first; |
|
|
|
|
|
|
|
|
// Create DD variable for update encoding.
|
|
|
// Create DD variable for update encoding.
|
|
|
ddInformation.updateDdVariable = ddInformation.manager->addMetaVariable("update", 0, maximalUpdateCount - 1).first; |
|
|
|
|
|
|
|
|
ddInformation.updateDdVariable = ddInformation.manager->addMetaVariable("update", 0, maximalUpdateCount - 1, std::make_pair(storm::dd::MetaVariablePosition::Above, ddInformation.predicateDdVariables.front().first)).first; |
|
|
|
|
|
|
|
|
// Create DD variables encoding the nondeterministic choices of player 2.
|
|
|
// Create DD variables encoding the nondeterministic choices of player 2.
|
|
|
// NOTE: currently we assume that 100 variables suffice, which corresponds to 2^100 possible choices.
|
|
|
// NOTE: currently we assume that 100 variables suffice, which corresponds to 2^100 possible choices.
|
|
|
// If for some reason this should not be enough, we could grow this vector dynamically, but odds are
|
|
|
// If for some reason this should not be enough, we could grow this vector dynamically, but odds are
|
|
|
// that it's impossible to treat such models in any event.
|
|
|
// that it's impossible to treat such models in any event.
|
|
|
for (uint_fast64_t index = 0; index < 100; ++index) { |
|
|
for (uint_fast64_t index = 0; index < 100; ++index) { |
|
|
storm::expressions::Variable newOptionVar = ddInformation.manager->addMetaVariable("opt" + std::to_string(index)).first; |
|
|
|
|
|
|
|
|
storm::expressions::Variable newOptionVar = ddInformation.manager->addMetaVariable("opt" + std::to_string(index), std::make_pair(storm::dd::MetaVariablePosition::Above, ddInformation.predicateDdVariables.front().first)).first; |
|
|
ddInformation.optionDdVariables.push_back(std::make_pair(newOptionVar, ddInformation.manager->getIdentity(newOptionVar).toBdd())); |
|
|
ddInformation.optionDdVariables.push_back(std::make_pair(newOptionVar, ddInformation.manager->getIdentity(newOptionVar).toBdd())); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Create DD variables for all predicates.
|
|
|
|
|
|
for (auto const& predicate : expressionInformation.predicates) { |
|
|
|
|
|
ddInformation.addPredicate(predicate); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// For each module of the concrete program, we create an abstract counterpart.
|
|
|
// For each module of the concrete program, we create an abstract counterpart.
|
|
|
for (auto const& module : program.getModules()) { |
|
|
for (auto const& module : program.getModules()) { |
|
|
modules.emplace_back(module, expressionInformation, ddInformation, *this->smtSolverFactory); |
|
|
modules.emplace_back(module, expressionInformation, ddInformation, *this->smtSolverFactory); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Add the initial state expression to the initial state abstractor.
|
|
|
|
|
|
initialStateAbstractor.addPredicate(program.getInitialConstruct().getInitialStatesExpression()); |
|
|
|
|
|
|
|
|
|
|
|
// Finally, retrieve the command-update probability ADD, so we can multiply it with the abstraction BDD later.
|
|
|
// Finally, retrieve the command-update probability ADD, so we can multiply it with the abstraction BDD later.
|
|
|
commandUpdateProbabilitiesAdd = modules.front().getCommandUpdateProbabilitiesAdd(); |
|
|
commandUpdateProbabilitiesAdd = modules.front().getCommandUpdateProbabilitiesAdd(); |
|
|
|
|
|
|
|
@ -151,10 +140,10 @@ namespace storm { |
|
|
if (addedAllGuards) { |
|
|
if (addedAllGuards) { |
|
|
bottomStates = ddInformation.manager->getBddZero(); |
|
|
bottomStates = ddInformation.manager->getBddZero(); |
|
|
} else { |
|
|
} else { |
|
|
bottomStates = bottomStateAbstractor.getAbstractStates(); |
|
|
|
|
|
|
|
|
// bottomStates = bottomStateAbstractor.getAbstractStates();
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
std::cout << "found " << (reachableStates && bottomStates).getNonZeroCount() << " reachable bottom states" << std::endl; |
|
|
|
|
|
|
|
|
// std::cout << "found " << (reachableStates && bottomStates).getNonZeroCount() << " reachable bottom states" << std::endl;
|
|
|
|
|
|
|
|
|
// Find the deadlock states in the model.
|
|
|
// Find the deadlock states in the model.
|
|
|
storm::dd::Bdd<DdType> deadlockStates = transitionRelation.existsAbstract(ddInformation.successorVariables); |
|
|
storm::dd::Bdd<DdType> deadlockStates = transitionRelation.existsAbstract(ddInformation.successorVariables); |
|
|