23template<storm::dd::DdType DdType,
typename ValueType>
25 std::shared_ptr<storm::utility::solver::SmtSolverFactory>
const& smtSolverFactory,
29 smtSolverFactory(smtSolverFactory),
30 abstractionInformation(env, program.getManager(), program.getAllExpressionVariables(), smtSolverFactory->create(program.getManager()),
33 initialStateAbstractor(abstractionInformation, {program.getInitialStatesExpression()}, this->smtSolverFactory),
34 validBlockAbstractor(abstractionInformation, smtSolverFactory),
36 refinementPerformed(
false) {
39 STORM_LOG_THROW(program.getNumberOfModules() == 1, storm::exceptions::WrongFormatException,
40 "Cannot create abstract program from program containing too many modules.");
43 for (
auto const& range : this->program.get().getAllRangeExpressions()) {
44 abstractionInformation.addConstraint(range);
45 initialStateAbstractor.constrain(range);
46 validBlockAbstractor.constrain(range);
49 uint_fast64_t totalNumberOfCommands = 0;
50 uint_fast64_t maximalUpdateCount = 0;
51 std::vector<storm::expressions::Expression> allGuards;
52 for (
auto const& module : program.getModules()) {
53 for (
auto const& command : module.getCommands()) {
54 maximalUpdateCount = std::max(maximalUpdateCount,
static_cast<uint_fast64_t
>(command.getNumberOfUpdates()));
57 totalNumberOfCommands +=
module.getNumberOfCommands();
63 abstractionInformation.createEncodingVariables(
static_cast<uint_fast64_t
>(std::ceil(std::log2(totalNumberOfCommands))), 64,
64 static_cast<uint_fast64_t
>(std::ceil(std::log2(maximalUpdateCount))));
67 bool useDecomposition = options.useDecomposition;
68 restrictToValidBlocks = options.restrictToValidBlocks;
69 bool addPredicatesForValidBlocks = !restrictToValidBlocks;
70 bool debug = options.debug;
71 for (
auto const& module : program.getModules()) {
72 this->modules.emplace_back(module, abstractionInformation, this->smtSolverFactory, useDecomposition, addPredicatesForValidBlocks, debug);
76 commandUpdateProbabilitiesAdd = modules.front().getCommandUpdateProbabilitiesAdd();
79template<storm::dd::DdType DdType,
typename ValueType>
81 return abstractionInformation.getDdManager();
84template<storm::dd::DdType DdType,
typename ValueType>
87 std::vector<uint_fast64_t> predicateIndices;
89 STORM_LOG_THROW(predicate.hasBooleanType(), storm::exceptions::InvalidArgumentException,
"Expecting a predicate of type bool.");
90 predicateIndices.push_back(abstractionInformation.getOrAddPredicate(predicate));
94 for (
auto& module : modules) {
95 module.refine(predicateIndices);
99 initialStateAbstractor.refine(predicateIndices);
101 if (restrictToValidBlocks) {
103 validBlockAbstractor.refine(predicateIndices);
109template<storm::dd::DdType DdType,
typename ValueType>
111 if (refinementPerformed) {
112 currentGame = buildGame();
113 refinementPerformed =
false;
118template<storm::dd::DdType DdType,
typename ValueType>
120 return abstractionInformation;
123template<storm::dd::DdType DdType,
typename ValueType>
125 return modules.front().getGuard(player1Choice);
128template<storm::dd::DdType DdType,
typename ValueType>
130 return modules.front().getNumberOfUpdates(player1Choice);
133template<storm::dd::DdType DdType,
typename ValueType>
135 uint64_t player1Choice, uint64_t auxiliaryChoice)
const {
136 return modules.front().getVariableUpdates(player1Choice, auxiliaryChoice);
139template<storm::dd::DdType DdType,
typename ValueType>
141 return modules.front().getAssignedVariables(player1Choice);
144template<storm::dd::DdType DdType,
typename ValueType>
146 return std::make_pair(0, modules.front().getCommands().size());
149template<storm::dd::DdType DdType,
typename ValueType>
151 return program.get().getInitialStatesExpression();
154template<storm::dd::DdType DdType,
typename ValueType>
157 smtSolverFactory->create(abstractionInformation.getExpressionManager()));
161template<storm::dd::DdType DdType,
typename ValueType>
162std::unique_ptr<MenuGame<DdType, ValueType>> PrismMenuGameAbstractor<DdType, ValueType>::buildGame() {
167 std::set<storm::expressions::Variable> variablesToAbstract(abstractionInformation.getPlayer1VariableSet(abstractionInformation.getPlayer1VariableCount()));
168 std::set<storm::expressions::Variable> successorAndAuxVariables(abstractionInformation.getSuccessorVariables());
170 variablesToAbstract.insert(player2Variables.begin(), player2Variables.end());
171 auto auxVariables = abstractionInformation.getAuxVariableSet(0, abstractionInformation.getAuxVariableCount());
172 variablesToAbstract.insert(auxVariables.begin(), auxVariables.end());
173 successorAndAuxVariables.insert(auxVariables.begin(), auxVariables.end());
177 if (this->isRestrictToRelevantStatesSet()) {
179 for (
auto const& expression : this->terminalStateExpressions) {
180 nonTerminalStates &= !this->getStates(expression);
182 if (this->hasTargetStateExpression()) {
183 nonTerminalStates &= !this->getStates(this->getTargetStateExpression());
186 relevantStatesWatch.stop();
190 if (restrictToValidBlocks) {
195 auto choicesWithOnlyValidSuccessors =
196 !game.
bdd.
andExists(!validBlocks.
swapVariables(abstractionInformation.getSourceSuccessorVariablePairs()), successorAndAuxVariables) &&
200 extendedTransitionRelation &= validBlocks && choicesWithOnlyValidSuccessors;
201 initialStates &= validBlocks;
206 initialStates.
addMetaVariables(abstractionInformation.getSourcePredicateVariables());
209 abstractionInformation.getSuccessorVariables())
212 relevantStatesWatch.start();
213 if (this->isRestrictToRelevantStatesSet() && this->hasTargetStateExpression()) {
215 storm::dd::Bdd<DdType> targetStates = reachableStates && this->getStates(this->getTargetStateExpression());
219 targetStates, reachableStates, transitionRelation, abstractionInformation.getSourceVariables(), abstractionInformation.getSuccessorVariables());
224 (reachableStates && !targetStates)
225 .relationalProduct(transitionRelation, abstractionInformation.getSourceVariables(), abstractionInformation.getSuccessorVariables());
228 transitionRelation &= reachableStates && reachableStates.
swapVariables(abstractionInformation.getExtendedSourceSuccessorVariablePairs());
230 relevantStatesWatch.stop();
231 STORM_LOG_TRACE(
"Restricting to relevant states took " << relevantStatesWatch.getTimeInMilliseconds() <<
"ms.");
236 storm::dd::Bdd<DdType> deadlockStates = transitionRelation.
existsAbstract(abstractionInformation.getSuccessorVariables());
237 deadlockStates = reachableStates && !deadlockStates;
240 storm::dd::Add<DdType, ValueType> deadlockTransitions = abstractionInformation.
getDdManager().template getAddZero<ValueType>();
241 if (!deadlockStates.
isZero()) {
242 deadlockTransitions = (deadlockStates && abstractionInformation.getAllPredicateIdentities() &&
243 abstractionInformation.encodePlayer1Choice(0, abstractionInformation.getPlayer1VariableCount()) &&
245 abstractionInformation.encodeAux(0, 0, abstractionInformation.getAuxVariableCount()))
246 .template toAdd<ValueType>();
250 BottomStateResult<DdType> bottomStateResult(abstractionInformation.getDdManager().getBddZero(), abstractionInformation.getDdManager().getBddZero());
252 bool hasBottomStates = !bottomStateResult.states.isZero();
257 storm::dd::Add<DdType, ValueType> transitionMatrix =
258 (extendedTransitionRelation && reachableStates && reachableStates.
swapVariables(abstractionInformation.getSourceSuccessorVariablePairs()))
259 .template toAdd<ValueType>();
260 transitionMatrix *= commandUpdateProbabilitiesAdd;
261 transitionMatrix += deadlockTransitions;
265 (abstractionInformation.getBottomStateBdd(
true,
true) && abstractionInformation.getBottomStateBdd(
false,
true)).template toAdd<ValueType>();
266 reachableStates &= abstractionInformation.getBottomStateBdd(
true,
true);
267 initialStates &= abstractionInformation.getBottomStateBdd(
true,
true);
270 if (hasBottomStates) {
271 transitionMatrix += bottomStateResult.transitions.template toAdd<ValueType>();
272 reachableStates |= bottomStateResult.states;
275 std::set<storm::expressions::Variable> allNondeterminismVariables = player2Variables;
276 allNondeterminismVariables.insert(abstractionInformation.getPlayer1Variables().begin(), abstractionInformation.getPlayer1Variables().end());
278 std::set<storm::expressions::Variable> allSourceVariables(abstractionInformation.getSourceVariables());
279 allSourceVariables.insert(abstractionInformation.getBottomStateVariable(
true));
280 std::set<storm::expressions::Variable> allSuccessorVariables(abstractionInformation.getSuccessorVariables());
281 allSuccessorVariables.insert(abstractionInformation.getBottomStateVariable(
false));
283 return std::make_unique<MenuGame<DdType, ValueType>>(
284 abstractionInformation.getDdManagerAsSharedPointer(), reachableStates, initialStates, abstractionInformation.getDdManager().getBddZero(),
285 transitionMatrix, bottomStateResult.states, allSourceVariables, allSuccessorVariables, abstractionInformation.getExtendedSourceSuccessorVariablePairs(),
286 std::set<storm::expressions::Variable>(abstractionInformation.getPlayer1Variables().begin(), abstractionInformation.getPlayer1Variables().end()),
287 player2Variables, allNondeterminismVariables, auxVariables, abstractionInformation.getPredicateToBddMap());
290template<storm::dd::DdType DdType,
typename ValueType>
293 this->
exportToDot(*currentGame, filename, highlightStates, filter);
296template<storm::dd::DdType DdType,
typename ValueType>
298 return abstractionInformation.getNumberOfPredicates();
301template<storm::dd::DdType DdType,
typename ValueType>
303 terminalStateExpressions.emplace_back(expression);
306template<storm::dd::DdType DdType,
typename ValueType>
308 for (
auto& module : modules) {
309 module.notifyGuardsArePredicates();
Bdd< LibraryType > existsAbstract(std::set< storm::expressions::Variable > const &metaVariables) const
Existentially abstracts from the given meta variables.
bool isZero() const
Retrieves whether this DD represents the constant zero function.
Bdd< LibraryType > andExists(Bdd< LibraryType > const &other, std::set< storm::expressions::Variable > const &existentialVariables) const
Computes the logical and of the current and the given BDD and existentially abstracts from the given ...
Bdd< LibraryType > swapVariables(std::vector< std::pair< storm::expressions::Variable, storm::expressions::Variable > > const &metaVariablePairs) const
Swaps the given pairs of meta variables in the BDD.
void addMetaVariables(std::set< storm::expressions::Variable > const &metaVariables)
Adds the given set of meta variables to the DD.
DdManager< LibraryType > & getDdManager() const
Retrieves the manager that is responsible for this DD.
storm::dd::Bdd< DdType > translate(storm::expressions::Expression const &expression)
std::vector< storm::expressions::Expression > const & getPredicates() const
A class that provides convenience operations to display run times.
#define STORM_LOG_DEBUG(message)
#define STORM_LOG_TRACE(message)
#define STORM_LOG_THROW(cond, exception, message)
storm::dd::Bdd< Type > computeBackwardsReachableStates(storm::dd::Bdd< Type > const &initialStates, storm::dd::Bdd< Type > const &constraintStates, storm::dd::Bdd< Type > const &transitions, std::set< storm::expressions::Variable > const &rowMetaVariables, std::set< storm::expressions::Variable > const &columnMetaVariables)
std::pair< storm::dd::Bdd< Type >, uint64_t > computeReachableStates(storm::dd::Bdd< Type > const &initialStates, storm::dd::Bdd< Type > const &transitions, std::set< storm::expressions::Variable > const &rowMetaVariables, std::set< storm::expressions::Variable > const &columnMetaVariables)
Options that configure the game-based abstraction-refinement procedure.
uint_fast64_t numberOfPlayer2Variables
storm::dd::Bdd< DdType > bdd