21 bool mPerformedSmtLoop =
false;
22 bool mFoundSolution =
false;
25 std::unordered_map<storm::storage::StateActionPair, storm::expressions::Variable> multistrategyVariables;
26 std::unordered_map<storm::expressions::Variable, bool> multistrategyVariablesToTakenMap;
27 std::unordered_map<uint_fast64_t, storm::expressions::Variable> mProbVariables;
28 std::unordered_map<uint_fast64_t, storm::expressions::Variable> mAlphaVariables;
29 std::unordered_map<storm::storage::StateActionTarget, storm::expressions::Variable> mBetaVariables;
30 std::unordered_map<uint_fast64_t, storm::expressions::Variable> mGammaVariables;
36 mPerformedSmtLoop(false),
37 mFoundSolution(false),
39 manager(solver.getManager()) {}
42 performSmtLoop(lowerBound, boundary, this->
mPenalties);
43 mPerformedSmtLoop =
true;
48 return mFoundSolution;
54 for (
auto const& entry : multistrategyVariables) {
55 if (!multistrategyVariablesToTakenMap.at(entry.second)) {
56 result.
disable(this->
mdp.getChoiceIndex(entry.first));
68 for (uint_fast64_t s : relevantStates) {
70 var = manager.declareRationalVariable(
"x_" + std::to_string(s));
71 solver.add(var >= manager.rational(0));
72 solver.add(var <= manager.rational(1));
73 mProbVariables[s] = var;
75 var = manager.declareBooleanVariable(
"alp_" + std::to_string(s));
76 mAlphaVariables[s] = var;
78 var = manager.declareRationalVariable(
"gam_" + std::to_string(s));
79 solver.add(var >= manager.rational(0));
80 solver.add(var <= manager.rational(1));
81 mGammaVariables[s] = var;
86 var = manager.declareBooleanVariable(
"y_" + std::to_string(s) +
"_" + std::to_string(a));
87 multistrategyVariables[stateAndAction] = var;
88 multistrategyVariablesToTakenMap[var] =
false;
92 for (
auto const& entry : this->
mdp.
getTransitionMatrix().getRow(this->mdp.getNondeterministicChoiceIndices()[s] + a)) {
93 if (entry.getValue() != 0) {
95 var = manager.declareBooleanVariable(
"beta_" + to_string(sat));
96 mBetaVariables[sat] = var;
106 void createConstraints(
bool lowerBound,
double boundary, storm::storage::BitVector
const& relevantStates) {
110 STORM_LOG_ASSERT(this->
mdp.getInitialStates().getNumberOfSetBits() == 1,
"No unique initial state.");
111 uint_fast64_t initialStateIndex = this->
mdp.getInitialStates().getNextSetIndex(0);
112 STORM_LOG_ASSERT(relevantStates[initialStateIndex],
"Initial state not relevant.");
114 solver.add(mProbVariables[initialStateIndex] >= manager.rational(boundary));
116 solver.add(mProbVariables[initialStateIndex] <= manager.rational(boundary));
118 for (uint_fast64_t s : relevantStates) {
119 std::vector<storm::expressions::Expression> expressions;
121 for (uint_fast64_t a = 0; a < this->
mdp.getNumberOfChoices(s); ++a) {
122 expressions.push_back(multistrategyVariables[storage::StateActionPair(s, a)]);
134 for (uint_fast64_t a = 0; a < this->
mdp.getNumberOfChoices(s); ++a) {
135 for (
auto const& entry : this->
mdp.getTransitionMatrix().getRow(this->mdp.getNondeterministicChoiceIndices()[s] + a)) {
136 if (entry.getValue() != 0 && relevantStates.get(entry.getColumn())) {
137 expressions.push_back(manager.rational(entry.getValue()) * mProbVariables[entry.getColumn()]);
138 }
else if (entry.getValue() != 0 && this->mGoals.get(entry.getColumn())) {
139 expressions.push_back(manager.rational(entry.getValue()));
193 void performSmtLoop(
bool lowerBound,
double boundary, PermissiveSchedulerPenalties
const& penalties) {
194 storm::storage::BitVector irrelevant = this->
mGoals | this->
mSinks;
195 storm::storage::BitVector relevantStates = ~irrelevant;
196 createVariables(relevantStates);
197 createConstraints(lowerBound, boundary, relevantStates);
205 std::shared_ptr<storm::solver::SmtSolver::ModelReference> model = solver.getModel();
207 std::vector<storage::StateActionPair> availableStateActionPairs;
208 for (uint_fast64_t s : relevantStates) {
209 for (uint_fast64_t a = 0; a < this->
mdp.getNumberOfChoices(s); ++a) {
210 auto stateAndAction = storage::StateActionPair(s, a);
212 auto multistrategyVariable = multistrategyVariables.at(stateAndAction);
213 if (model->getBooleanValue(multistrategyVariable)) {
214 multistrategyVariablesToTakenMap[multistrategyVariable] =
true;
215 solver.add(multistrategyVariable);
217 availableStateActionPairs.push_back(stateAndAction);
224 std::sort(availableStateActionPairs.begin(), availableStateActionPairs.end(),
225 [&penalties](storage::StateActionPair
const& first, storage::StateActionPair
const& second) {
226 return penalties.get(first) < penalties.get(second);
230 auto multistrategyVariable = multistrategyVariables.at(availableStateActionPairs.back());
232 result = solver.checkWithAssumptions({multistrategyVariable});
235 model = solver.getModel();
236 if (model->getBooleanValue(multistrategyVariable)) {
237 solver.add(multistrategyVariable);
238 multistrategyVariablesToTakenMap[multistrategyVariable] =
true;
241 availableStateActionPairs.pop_back();
243 }
while (!availableStateActionPairs.empty());
245 mFoundSolution =
true;
247 mFoundSolution =
false;