11 bool mPerformedSmtLoop =
false;
12 bool mFoundSolution =
false;
15 std::unordered_map<storm::storage::StateActionPair, storm::expressions::Variable> multistrategyVariables;
16 std::unordered_map<storm::expressions::Variable, bool> multistrategyVariablesToTakenMap;
17 std::unordered_map<uint_fast64_t, storm::expressions::Variable> mProbVariables;
18 std::unordered_map<uint_fast64_t, storm::expressions::Variable> mAlphaVariables;
19 std::unordered_map<storm::storage::StateActionTarget, storm::expressions::Variable> mBetaVariables;
20 std::unordered_map<uint_fast64_t, storm::expressions::Variable> mGammaVariables;
26 mPerformedSmtLoop(false),
27 mFoundSolution(false),
29 manager(solver.getManager()) {}
32 performSmtLoop(lowerBound, boundary, this->
mPenalties);
33 mPerformedSmtLoop =
true;
38 return mFoundSolution;
44 for (
auto const& entry : multistrategyVariables) {
45 if (!multistrategyVariablesToTakenMap.at(entry.second)) {
46 result.
disable(this->
mdp.getChoiceIndex(entry.first));
58 for (uint_fast64_t s : relevantStates) {
60 var = manager.declareRationalVariable(
"x_" + std::to_string(s));
61 solver.add(var >= manager.rational(0));
62 solver.add(var <= manager.rational(1));
63 mProbVariables[s] = var;
65 var = manager.declareBooleanVariable(
"alp_" + std::to_string(s));
66 mAlphaVariables[s] = var;
68 var = manager.declareRationalVariable(
"gam_" + std::to_string(s));
69 solver.add(var >= manager.rational(0));
70 solver.add(var <= manager.rational(1));
71 mGammaVariables[s] = var;
76 var = manager.declareBooleanVariable(
"y_" + std::to_string(s) +
"_" + std::to_string(a));
77 multistrategyVariables[stateAndAction] = var;
78 multistrategyVariablesToTakenMap[var] =
false;
82 for (
auto const& entry : this->
mdp.
getTransitionMatrix().getRow(this->mdp.getNondeterministicChoiceIndices()[s] + a)) {
83 if (entry.getValue() != 0) {
85 var = manager.declareBooleanVariable(
"beta_" + to_string(sat));
86 mBetaVariables[sat] = var;
96 void createConstraints(
bool lowerBound,
double boundary, storm::storage::BitVector
const& relevantStates) {
100 STORM_LOG_ASSERT(this->
mdp.getInitialStates().getNumberOfSetBits() == 1,
"No unique initial state.");
101 uint_fast64_t initialStateIndex = this->
mdp.getInitialStates().getNextSetIndex(0);
102 STORM_LOG_ASSERT(relevantStates[initialStateIndex],
"Initial state not relevant.");
104 solver.add(mProbVariables[initialStateIndex] >= manager.rational(boundary));
106 solver.add(mProbVariables[initialStateIndex] <= manager.rational(boundary));
108 for (uint_fast64_t s : relevantStates) {
109 std::string stateString = std::to_string(s);
110 std::vector<storm::expressions::Expression> expressions;
112 for (uint_fast64_t a = 0; a < this->
mdp.getNumberOfChoices(s); ++a) {
113 expressions.push_back(multistrategyVariables[storage::StateActionPair(s, a)]);
125 for (uint_fast64_t a = 0; a < this->
mdp.getNumberOfChoices(s); ++a) {
126 std::string sastring(stateString +
"_" + std::to_string(a));
128 for (
auto const& entry : this->
mdp.getTransitionMatrix().getRow(this->mdp.getNondeterministicChoiceIndices()[s] + a)) {
129 if (entry.getValue() != 0 && relevantStates.get(entry.getColumn())) {
130 expressions.push_back(manager.rational(entry.getValue()) * mProbVariables[entry.getColumn()]);
131 }
else if (entry.getValue() != 0 && this->mGoals.get(entry.getColumn())) {
132 expressions.push_back(manager.rational(entry.getValue()));
186 void performSmtLoop(
bool lowerBound,
double boundary, PermissiveSchedulerPenalties
const& penalties) {
187 storm::storage::BitVector irrelevant = this->
mGoals | this->
mSinks;
188 storm::storage::BitVector relevantStates = ~irrelevant;
189 createVariables(relevantStates);
190 createConstraints(lowerBound, boundary, relevantStates);
198 std::shared_ptr<storm::solver::SmtSolver::ModelReference> model = solver.getModel();
200 std::vector<storage::StateActionPair> availableStateActionPairs;
201 for (uint_fast64_t s : relevantStates) {
202 for (uint_fast64_t a = 0; a < this->
mdp.getNumberOfChoices(s); ++a) {
203 auto stateAndAction = storage::StateActionPair(s, a);
205 auto multistrategyVariable = multistrategyVariables.at(stateAndAction);
206 if (model->getBooleanValue(multistrategyVariable)) {
207 multistrategyVariablesToTakenMap[multistrategyVariable] =
true;
208 solver.add(multistrategyVariable);
210 availableStateActionPairs.push_back(stateAndAction);
217 std::sort(availableStateActionPairs.begin(), availableStateActionPairs.end(),
218 [&penalties](storage::StateActionPair
const& first, storage::StateActionPair
const& second) {
219 return penalties.get(first) < penalties.get(second);
223 auto multistrategyVariable = multistrategyVariables.at(availableStateActionPairs.back());
225 result = solver.checkWithAssumptions({multistrategyVariable});
228 model = solver.getModel();
229 if (model->getBooleanValue(multistrategyVariable)) {
230 solver.add(multistrategyVariable);
231 multistrategyVariablesToTakenMap[multistrategyVariable] =
true;
234 availableStateActionPairs.pop_back();
236 }
while (!availableStateActionPairs.empty());
238 mFoundSolution =
true;
240 mFoundSolution =
false;