Storm
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
TimeTravelling.cpp
Go to the documentation of this file.
1#include "TimeTravelling.h"
2#include <carl/core/Variable.h>
3#include <carl/core/VariablePool.h>
4#include <algorithm>
5#include <cstdint>
6#include <cstdlib>
7#include <fstream>
8#include <functional>
9#include <map>
10#include <queue>
11#include <set>
12#include <stack>
13#include <string>
14#include <vector>
28#include "storm/utility/graph.h"
31
32#define WRITE_DTMCS 0
33
34namespace storm {
35namespace transformer {
36
41 uint64_t initialState = dtmc.getInitialStates().getNextSetIndex(0);
42
43 auto allParameters = storm::models::sparse::getAllParameters(dtmc);
44
45 std::set<std::string> labelsInFormula;
46 for (auto const& atomicLabelFormula : checkTask.getFormula().getAtomicLabelFormulas()) {
47 labelsInFormula.emplace(atomicLabelFormula->getLabel());
48 }
49
50 models::sparse::StateLabeling runningLabeling(dtmc.getStateLabeling());
51
52 // Check the reward model - do not touch states with rewards
53 boost::optional<std::vector<RationalFunction>> stateRewardVector;
54 boost::optional<std::string> stateRewardName;
55 if (checkTask.getFormula().isRewardOperatorFormula()) {
56 if (checkTask.isRewardModelSet()) {
58 stateRewardVector = dtmc.getRewardModel(checkTask.getRewardModel()).getStateRewardVector();
59 stateRewardName = checkTask.getRewardModel();
60 } else {
62 stateRewardVector = dtmc.getRewardModel("").getStateRewardVector();
63 stateRewardName = dtmc.getUniqueRewardModelName();
64 }
65 }
66
67 auto const constantVariable = carl::VariablePool::getInstance().getFreshPersistentVariable();
68 auto topologicalOrdering = utility::graph::getTopologicalSort<RationalFunction>(transitionMatrix, {initialState});
69 auto flexibleMatrix = storage::FlexibleSparseMatrix<RationalFunction>(transitionMatrix);
70
71 std::stack<uint64_t> topologicalOrderingStack;
72 for (auto rit = topologicalOrdering.begin(); rit != topologicalOrdering.end(); ++rit) {
73 topologicalOrderingStack.push(*rit);
74 }
75
76 // Initialize counting
77 std::map<RationalFunctionVariable, std::map<uint64_t, std::set<uint64_t>>> treeStates;
78 std::map<RationalFunctionVariable, std::set<uint64_t>> workingSets;
79
80 auto backwardsTransitions = flexibleMatrix.createSparseMatrix().transpose(true);
81 // Count number of parameter occurences per state
82 for (uint64_t row = 0; row < flexibleMatrix.getRowCount(); row++) {
83 for (auto const& entry : flexibleMatrix.getRow(row)) {
84 if (entry.getValue().isConstant()) {
85 continue;
86 }
87 STORM_LOG_ERROR_COND(entry.getValue().gatherVariables().size() == 1, "Flip minimization only supports transitions with a single parameter.");
88 auto parameter = *entry.getValue().gatherVariables().begin();
89 auto cache = entry.getValue().nominatorAsPolynomial().pCache();
90 STORM_LOG_ERROR_COND(entry.getValue().denominator().isOne() && entry.getValue().nominator().isUnivariate() &&
91 entry.getValue().nominator().getSingleVariable() == parameter && entry.getValue().nominator().factorization().size() == 1,
92 "Flip minimization only supports simple pMCs.");
93 STORM_LOG_ERROR_COND(flexibleMatrix.getRow(row).size() == 2, "Flip minimization only supports transitions with a single parameter.");
94 workingSets[parameter].emplace(row);
95 treeStates[parameter][row].emplace(row);
96 if (utility::isOne(entry.getValue().derivative(entry.getValue().nominator().getSingleVariable()))) {
97 } else if (utility::isOne(-entry.getValue().derivative(entry.getValue().nominator().getSingleVariable()))) {
98 } else {
99 STORM_LOG_ERROR_COND(false, "Flip minimization only supports transitions with a single parameter.");
100 }
101 }
102 }
103
104 // To prevent infinite unrolling of parametric loops
105 // We have already reordered with these as root
106 std::set<std::pair<RationalFunctionVariable, std::set<uint64_t>>> alreadyReorderedWrt;
107
108 updateTreeStates(treeStates, workingSets, flexibleMatrix, allParameters, stateRewardVector, runningLabeling, labelsInFormula);
109 while (!topologicalOrderingStack.empty()) {
110 auto state = topologicalOrderingStack.top();
111 topologicalOrderingStack.pop();
112 // Check if we can reach more than one var from here (by the original matrix)
113 bool performJipConvert = false;
114 bool reorderingPossible = false;
115
116 bool alreadyReorderedWrtThis = true;
117 for (auto const& parameter : allParameters) {
118 if (!treeStates[parameter].count(state)) {
119 continue;
120 }
121 // If we can reach more than two equal parameters, we can reorder
122 auto const entry = treeStates.at(parameter).at(state);
123 if (entry.size() >= 2) {
124 performJipConvert = true;
125 reorderingPossible = true;
126 }
127
128 // For the duplicate checking, new states automatically count as duplicates. Thus, they are filtered out here.
129 std::set<uint64_t> entriesInOldDtmc;
130 const uint64_t statesOfDtmc = dtmc.getNumberOfStates();
131 std::copy_if(entry.begin(), entry.end(), std::inserter(entriesInOldDtmc, entriesInOldDtmc.end()),
132 [statesOfDtmc](uint64_t value) { return value < statesOfDtmc; });
133
134 // Check if we have already reordered w.r.t. this and enter it into the map
135 if (alreadyReorderedWrt.count(std::make_pair(parameter, entriesInOldDtmc)) == 0) {
136 alreadyReorderedWrtThis = false;
137 }
138 alreadyReorderedWrt.emplace(std::make_pair(parameter, entry));
139 }
140
141 if (!performJipConvert || alreadyReorderedWrtThis) {
142 continue;
143 }
144 std::map<uint64_t, bool> alreadyVisited;
145 collapseConstantTransitions(state, flexibleMatrix, alreadyVisited, treeStates, allParameters, stateRewardVector, runningLabeling, labelsInFormula);
146
147#if WRITE_DTMCS
148 models::sparse::Dtmc<RationalFunction> newnewDTMC(flexibleMatrix.createSparseMatrix(), runningLabeling);
149 if (stateRewardVector) {
150 models::sparse::StandardRewardModel<RationalFunction> newRewardModel(*stateRewardVector);
151 newnewDTMC.addRewardModel(*stateRewardName, newRewardModel);
152 }
153 std::ofstream file;
154 storm::io::openFile("dots/jipconvert_" + std::to_string(flexibleMatrix.getRowCount()) + ".dot", file);
155 newnewDTMC.writeDotToStream(file);
157 // newnewDTMC.writeDotToStream(std::cout);
158 newnewDTMC.getTransitionMatrix().isProbabilistic();
159#endif
160
161 // Now our matrix is in Jip normal form. Now re-order if that is needed
162 if (reorderingPossible) {
163 std::map<storm::RationalFunctionVariable, std::set<uint64_t>> parameterBuckets;
164 std::map<storm::RationalFunctionVariable, RationalFunction> cumulativeProbabilities;
165
166 std::map<uint64_t, uint64_t> pTransitions;
167 std::map<uint64_t, uint64_t> oneMinusPTransitions;
168
169 std::map<uint64_t, RationalFunction> directProbs;
170
171 std::map<storm::RationalFunctionVariable, RationalFunction> pRationalFunctions;
172 std::map<storm::RationalFunctionVariable, RationalFunction> oneMinusPRationalFunctions;
173
174 for (auto const& entry : flexibleMatrix.getRow(state)) {
175 // Identify parameter of successor (or constant)
176 if (stateRewardVector && !stateRewardVector->at(entry.getColumn()).isZero()) {
177 parameterBuckets[constantVariable].emplace(entry.getColumn());
178 cumulativeProbabilities[constantVariable] += entry.getValue();
179 directProbs[entry.getColumn()] = entry.getValue();
180 continue;
181 }
182 RationalFunctionVariable parameterOfSuccessor;
183 for (auto const& entry2 : flexibleMatrix.getRow(entry.getColumn())) {
184 if (entry2.getValue().isZero()) {
185 continue;
186 }
187 if (entry2.getValue().isConstant()) {
188 parameterOfSuccessor = constantVariable;
189 break;
190 }
191
192 STORM_LOG_ERROR_COND(entry2.getValue().gatherVariables().size() == 1,
193 "Flip minimization only supports transitions with a single parameter.");
194 parameterOfSuccessor = *entry2.getValue().gatherVariables().begin();
195 auto cache = entry2.getValue().nominatorAsPolynomial().pCache();
196 STORM_LOG_ERROR_COND(entry2.getValue().denominator().isOne() && entry2.getValue().nominator().isUnivariate() &&
197 entry2.getValue().nominator().getSingleVariable() == parameterOfSuccessor &&
198 entry2.getValue().nominator().factorization().size() == 1,
199 "Flip minimization only supports simple pMCs.");
200 STORM_LOG_ERROR_COND(flexibleMatrix.getRow(entry.getColumn()).size() == 2,
201 "Flip minimization only supports transitions with a single parameter.");
202 if (utility::isOne(entry2.getValue().derivative(entry2.getValue().nominator().getSingleVariable()))) {
203 pRationalFunctions[parameterOfSuccessor] = entry2.getValue();
204 pTransitions[entry.getColumn()] = entry2.getColumn();
205 } else if (utility::isOne(-entry2.getValue().derivative(entry2.getValue().nominator().getSingleVariable()))) {
206 oneMinusPRationalFunctions[parameterOfSuccessor] = entry2.getValue();
207 oneMinusPTransitions[entry.getColumn()] = entry2.getColumn();
208 } else {
209 STORM_LOG_ERROR_COND(false, "Flip minimization only supports transitions with a single parameter.");
210 }
211 }
212 parameterBuckets[parameterOfSuccessor].emplace(entry.getColumn());
213 cumulativeProbabilities[parameterOfSuccessor] += entry.getValue();
214 directProbs[entry.getColumn()] = entry.getValue();
215 }
216
217 // TODO slow could be done better if flexible matrix had ability to add states
218 uint64_t newMatrixSize = flexibleMatrix.getRowCount() + 3 * parameterBuckets.size();
219 if (parameterBuckets.count(constantVariable)) {
220 newMatrixSize -= 2;
221 }
223 storage::FlexibleSparseMatrix<RationalFunction> matrixWithAdditionalStates(builder.build(newMatrixSize, newMatrixSize, 0));
224 for (uint64_t row = 0; row < flexibleMatrix.getRowCount(); row++) {
225 matrixWithAdditionalStates.getRow(row) = flexibleMatrix.getRow(row);
226 }
227
228 workingSets.clear();
229
230 uint64_t newStateIndex = flexibleMatrix.getRowCount();
231 matrixWithAdditionalStates.getRow(state).clear();
232 for (auto const& entry : parameterBuckets) {
233 matrixWithAdditionalStates.getRow(state).push_back(
234 storage::MatrixEntry<uint64_t, RationalFunction>(newStateIndex, cumulativeProbabilities.at(entry.first)));
235 STORM_LOG_INFO("Reorder: " << state << " -> " << newStateIndex);
236
237 if (entry.first == constantVariable) {
238 for (auto const& successor : entry.second) {
239 matrixWithAdditionalStates.getRow(newStateIndex)
241 directProbs.at(successor) / cumulativeProbabilities.at(entry.first)));
242 }
243 // Issue: multiple transitions can go to a single state, not allowed
244 // Solution: Join them
245 matrixWithAdditionalStates.getRow(newStateIndex) = joinDuplicateTransitions(matrixWithAdditionalStates.getRow(newStateIndex));
246
247 workingSets[entry.first].emplace(newStateIndex);
248 for (auto const& entry : matrixWithAdditionalStates.getRow(newStateIndex)) {
249 for (auto const& parameter : allParameters) {
250 workingSets[parameter].emplace(entry.getColumn());
251 }
252 }
253
254 newStateIndex += 1;
255 } else {
256 matrixWithAdditionalStates.getRow(newStateIndex)
257 .push_back(storage::MatrixEntry<uint64_t, RationalFunction>(newStateIndex + 1, pRationalFunctions.at(entry.first)));
258 matrixWithAdditionalStates.getRow(newStateIndex)
259 .push_back(storage::MatrixEntry<uint64_t, RationalFunction>(newStateIndex + 2, oneMinusPRationalFunctions.at(entry.first)));
260
261 for (auto const& successor : entry.second) {
262 // Remove transition from being counted (for now, we will re-add it below)
263 for (auto& state : treeStates.at(entry.first)) {
264 if (state.first != successor) {
265 state.second.erase(successor);
266 }
267 }
268 // If it's still needed, re-count it
269 workingSets[entry.first].emplace(successor);
270
271 matrixWithAdditionalStates.getRow(newStateIndex + 1)
272 .push_back(storage::MatrixEntry<uint64_t, RationalFunction>(pTransitions.at(successor),
273 directProbs.at(successor) / cumulativeProbabilities.at(entry.first)));
274 matrixWithAdditionalStates.getRow(newStateIndex + 2)
275 .push_back(storage::MatrixEntry<uint64_t, RationalFunction>(oneMinusPTransitions.at(successor),
276 directProbs.at(successor) / cumulativeProbabilities.at(entry.first)));
277 }
278 // Issue: multiple transitions can go to a single state, not allowed
279 // Solution: Join them
280 matrixWithAdditionalStates.getRow(newStateIndex + 1) = joinDuplicateTransitions(matrixWithAdditionalStates.getRow(newStateIndex + 1));
281 matrixWithAdditionalStates.getRow(newStateIndex + 2) = joinDuplicateTransitions(matrixWithAdditionalStates.getRow(newStateIndex + 2));
282
283 treeStates[entry.first][newStateIndex].emplace(newStateIndex);
284 workingSets[entry.first].emplace(newStateIndex);
285 workingSets[entry.first].emplace(newStateIndex + 1);
286 workingSets[entry.first].emplace(newStateIndex + 2);
287
288 for (auto const& entry : matrixWithAdditionalStates.getRow(newStateIndex + 1)) {
289 for (auto const& parameter : allParameters) {
290 workingSets[parameter].emplace(entry.getColumn());
291 }
292 }
293 for (auto const& entry : matrixWithAdditionalStates.getRow(newStateIndex + 2)) {
294 for (auto const& parameter : allParameters) {
295 workingSets[parameter].emplace(entry.getColumn());
296 }
297 }
298
299 newStateIndex += 3;
300 }
301 }
302
303 // Extend labeling to more states
304 models::sparse::StateLabeling nextNewLabels =
305 extendStateLabeling(runningLabeling, flexibleMatrix.getRowCount(), newMatrixSize, state, labelsInFormula);
306
307 for (uint64_t i = flexibleMatrix.getRowCount(); i < newMatrixSize; i++) {
308 // Next consider the new states
309 topologicalOrderingStack.push(i);
310 // New states have zero reward
311 if (stateRewardVector) {
312 stateRewardVector->push_back(storm::utility::zero<RationalFunction>());
313 }
314 }
315 runningLabeling = nextNewLabels;
316
317 updateTreeStates(treeStates, workingSets, matrixWithAdditionalStates, allParameters, stateRewardVector, runningLabeling, labelsInFormula);
318
319 flexibleMatrix = matrixWithAdditionalStates;
320 backwardsTransitions = flexibleMatrix.createSparseMatrix().transpose(true);
321 }
322 }
323
324#if WRITE_DTMCS
325 models::sparse::Dtmc<RationalFunction> newnewnewDTMC(flexibleMatrix.createSparseMatrix(), runningLabeling);
326 if (stateRewardVector) {
327 models::sparse::StandardRewardModel<RationalFunction> newRewardModel(*stateRewardVector);
328 newnewnewDTMC.addRewardModel(*stateRewardName, newRewardModel);
329 }
330 std::ofstream file2;
331 storm::io::openFile("dots/travel_" + std::to_string(flexibleMatrix.getRowCount()) + ".dot", file2);
332 newnewnewDTMC.writeDotToStream(file2);
334 newnewnewDTMC.getTransitionMatrix().isProbabilistic();
335#endif
336
337 transitionMatrix = flexibleMatrix.createSparseMatrix();
338
339 // Delete states (2)
340 {
341 storage::BitVector trueVector(transitionMatrix.getRowCount(), true);
342 storage::BitVector falseVector(transitionMatrix.getRowCount(), false);
343 storage::BitVector initialStates(transitionMatrix.getRowCount(), false);
344 initialStates.set(initialState, true);
345 storage::BitVector reachableStates = storm::utility::graph::getReachableStates(transitionMatrix, initialStates, trueVector, falseVector);
346 transitionMatrix = transitionMatrix.getSubmatrix(false, reachableStates, reachableStates);
347 runningLabeling = runningLabeling.getSubLabeling(reachableStates);
348 uint64_t newInitialState = 0;
349 for (uint64_t i = 0; i < initialState; i++) {
350 if (reachableStates.get(i)) {
351 newInitialState++;
352 }
353 }
354 initialState = newInitialState;
355 if (stateRewardVector) {
356 std::vector<RationalFunction> newStateRewardVector;
357 for (uint64_t i = 0; i < stateRewardVector->size(); i++) {
358 if (reachableStates.get(i)) {
359 newStateRewardVector.push_back(stateRewardVector->at(i));
360 } else {
361 STORM_LOG_ERROR_COND(stateRewardVector->at(i).isZero(), "Deleted non-zero reward.");
362 }
363 }
364 stateRewardVector = newStateRewardVector;
365 }
366 }
367
368 models::sparse::Dtmc<RationalFunction> newDTMC(transitionMatrix, runningLabeling);
369
370 storage::BitVector newInitialStates(transitionMatrix.getRowCount());
371 newInitialStates.set(initialState, true);
372 newDTMC.setInitialStates(newInitialStates);
373
374 if (stateRewardVector) {
375 models::sparse::StandardRewardModel<RationalFunction> newRewardModel(*stateRewardVector);
376 newDTMC.addRewardModel(*stateRewardName, newRewardModel);
377 }
378
379 return newDTMC;
380}
381
382std::vector<storm::storage::MatrixEntry<uint64_t, RationalFunction>> TimeTravelling::joinDuplicateTransitions(
384 std::vector<uint64_t> keyOrder;
385 std::map<uint64_t, storm::storage::MatrixEntry<uint64_t, RationalFunction>> existingEntries;
386 for (auto const& entry : entries) {
387 if (existingEntries.count(entry.getColumn())) {
388 existingEntries.at(entry.getColumn()).setValue(existingEntries.at(entry.getColumn()).getValue() + entry.getValue());
389 } else {
390 existingEntries[entry.getColumn()] = entry;
391 keyOrder.push_back(entry.getColumn());
392 }
393 }
394 std::vector<storm::storage::MatrixEntry<uint64_t, RationalFunction>> newEntries;
395 for (uint64_t key : keyOrder) {
396 newEntries.push_back(existingEntries.at(key));
397 }
398 return newEntries;
399}
400
401models::sparse::StateLabeling TimeTravelling::extendStateLabeling(models::sparse::StateLabeling const& oldLabeling, uint64_t oldSize, uint64_t newSize,
402 uint64_t stateWithLabels, const std::set<std::string> labelsInFormula) {
403 models::sparse::StateLabeling newLabels(newSize);
404 for (auto const& label : oldLabeling.getLabels()) {
405 newLabels.addLabel(label);
406 }
407 for (uint64_t state = 0; state < oldSize; state++) {
408 for (auto const& label : oldLabeling.getLabelsOfState(state)) {
409 newLabels.addLabelToState(label, state);
410 }
411 }
412 for (uint64_t i = oldSize; i < newSize; i++) {
413 // We assume that everything that we time-travel has the same labels for now.
414 for (auto const& label : oldLabeling.getLabelsOfState(stateWithLabels)) {
415 if (labelsInFormula.count(label)) {
416 newLabels.addLabelToState(label, i);
417 }
418 }
419 }
420 return newLabels;
421}
422
423bool labelsIntersectedEqual(const std::set<std::string>& labels1, const std::set<std::string>& labels2, const std::set<std::string>& intersection) {
424 for (auto const& label : intersection) {
425 bool set1ContainsLabel = labels1.count(label) > 0;
426 bool set2ContainsLabel = labels2.count(label) > 0;
427 if (set1ContainsLabel != set2ContainsLabel) {
428 return false;
429 }
430 }
431 return true;
432}
433
434void TimeTravelling::updateTreeStates(std::map<RationalFunctionVariable, std::map<uint64_t, std::set<uint64_t>>>& treeStates,
435 std::map<RationalFunctionVariable, std::set<uint64_t>>& workingSets,
436 storage::FlexibleSparseMatrix<RationalFunction>& flexibleMatrix, const std::set<carl::Variable>& allParameters,
437 const boost::optional<std::vector<RationalFunction>>& stateRewardVector,
438 const models::sparse::StateLabeling stateLabeling, const std::set<std::string> labelsInFormula) {
439 auto backwardsTransitions = flexibleMatrix.createSparseMatrix().transpose(true);
440 for (auto const& parameter : allParameters) {
441 std::set<uint64_t> workingSet = workingSets[parameter];
442 while (!workingSet.empty()) {
443 std::set<uint64_t> newWorkingSet;
444 for (uint64_t row : workingSet) {
445 if (stateRewardVector && !stateRewardVector->at(row).isZero()) {
446 continue;
447 }
448 for (auto const& entry : backwardsTransitions.getRow(row)) {
449 if (entry.getValue().isConstant() &&
450 labelsIntersectedEqual(stateLabeling.getLabelsOfState(entry.getColumn()), stateLabeling.getLabelsOfState(row), labelsInFormula)) {
451 // If the set of tree states at the current position is a subset of the set of
452 // tree states of the parent state, we've reached some loop. Then we can stop.
453 bool isSubset = true;
454 for (auto const& state : treeStates.at(parameter)[row]) {
455 if (!treeStates.at(parameter)[entry.getColumn()].count(state)) {
456 isSubset = false;
457 break;
458 }
459 }
460 if (isSubset) {
461 continue;
462 }
463 for (auto const& state : treeStates.at(parameter).at(row)) {
464 treeStates.at(parameter).at(entry.getColumn()).emplace(state);
465 }
466 newWorkingSet.emplace(entry.getColumn());
467 }
468 }
469 }
470 workingSet = newWorkingSet;
471 }
472 }
473}
474
475bool TimeTravelling::collapseConstantTransitions(uint64_t state, storage::FlexibleSparseMatrix<RationalFunction>& matrix,
476 std::map<uint64_t, bool>& alreadyVisited,
477 const std::map<RationalFunctionVariable, std::map<uint64_t, std::set<uint64_t>>>& treeStates,
478 const std::set<carl::Variable>& allParameters,
479 const boost::optional<std::vector<RationalFunction>>& stateRewardVector,
480 const models::sparse::StateLabeling stateLabeling, const std::set<std::string> labelsInFormula) {
481 auto copiedRow = matrix.getRow(state);
482 bool firstIteration = true;
483 for (auto const& entry : copiedRow) {
484 // ignore zero-entries
485 if (entry.getValue().isZero()) {
486 continue;
487 }
488 // if this is a parameteric transition, for now this means returning and ending our preprocessing
489 if (!entry.getValue().isConstant()) {
490 return false;
491 }
492 uint64_t nextState = entry.getColumn();
493 bool continueConvertingHere;
494 if (stateRewardVector && !stateRewardVector->at(entry.getColumn()).isZero()) {
495 continueConvertingHere = false;
496 } else if (!labelsIntersectedEqual(stateLabeling.getLabelsOfState(state), stateLabeling.getLabelsOfState(nextState), labelsInFormula)) {
497 continueConvertingHere = false;
498 } else {
499 if (alreadyVisited.count(nextState)) {
500 continueConvertingHere = alreadyVisited.at(nextState);
501 } else {
502 alreadyVisited[nextState] = false;
503 continueConvertingHere = collapseConstantTransitions(nextState, matrix, alreadyVisited, treeStates, allParameters, stateRewardVector,
504 stateLabeling, labelsInFormula);
505 alreadyVisited[nextState] = continueConvertingHere;
506 }
507 }
508 RationalFunction probability = entry.getValue();
509 if (firstIteration) {
510 matrix.getRow(state).clear();
511 firstIteration = false;
512 }
513 if (continueConvertingHere) {
514 for (auto const& successor : matrix.getRow(nextState)) {
515 RationalFunction succProbability = successor.getValue();
516 storm::storage::MatrixEntry<uint64_t, RationalFunction> newEntry(successor.getColumn(), probability * succProbability);
517 STORM_LOG_INFO("JipConvert: " << state << " -> " << successor.getColumn() << " w/ " << probability * succProbability);
518 matrix.getRow(state).push_back(newEntry);
519 }
520 } else {
521 matrix.getRow(state).push_back(entry);
522 }
523 }
524 std::sort(matrix.getRow(state).begin(), matrix.getRow(state).end(),
525 [](const storage::MatrixEntry<uint64_t, RationalFunction>& a, const storage::MatrixEntry<uint64_t, RationalFunction>& b) -> bool {
526 return a.getColumn() > b.getColumn();
527 });
528 matrix.getRow(state) = joinDuplicateTransitions(matrix.getRow(state));
529 return true;
530}
531
532class TimeTravelling;
533} // namespace transformer
534} // namespace storm
bool isRewardModelSet() const
Retrieves whether a reward model was set.
Definition CheckTask.h:190
std::string const & getRewardModel() const
Retrieves the reward model over which to perform the checking (if set).
Definition CheckTask.h:197
FormulaType const & getFormula() const
Retrieves the formula from this task.
Definition CheckTask.h:140
virtual void writeDotToStream(std::ostream &outStream, size_t maxWidthLabel=30, bool includeLabeling=true, storm::storage::BitVector const *subsystem=nullptr, std::vector< ValueType > const *firstValue=nullptr, std::vector< ValueType > const *secondValue=nullptr, std::vector< uint_fast64_t > const *stateColoring=nullptr, std::vector< std::string > const *colors=nullptr, std::vector< uint_fast64_t > *scheduler=nullptr, bool finalizeOutput=true) const override
This class represents a discrete-time Markov chain.
Definition Dtmc.h:14
virtual void reduceToStateBasedRewards() override
Converts the transition rewards of all reward models to state-based rewards.
Definition Dtmc.cpp:41
storm::storage::SparseMatrix< ValueType > const & getTransitionMatrix() const
Retrieves the matrix representing the transitions of the model.
Definition Model.cpp:197
void setInitialStates(storm::storage::BitVector const &states)
Overwrites the initial states of the model.
Definition Model.cpp:182
void addRewardModel(std::string const &rewardModelName, RewardModelType const &rewModel)
Adds a reward model to the model.
Definition Model.cpp:254
storm::models::sparse::StateLabeling const & getStateLabeling() const
Returns the state labeling associated with this model.
Definition Model.cpp:319
virtual uint_fast64_t getNumberOfStates() const override
Returns the number of states of the model.
Definition Model.cpp:162
RewardModelType const & getRewardModel(std::string const &rewardModelName) const
Retrieves the reward model with the given name, if one exists.
Definition Model.cpp:218
virtual std::string const & getUniqueRewardModelName() const override
Retrieves the name of the unique reward model, if there exists exactly one.
Definition Model.cpp:292
storm::storage::BitVector const & getInitialStates() const
Retrieves the initial states of the model.
Definition Model.cpp:177
This class manages the labeling of the state space with a number of (atomic) labels.
std::set< std::string > getLabelsOfState(storm::storage::sparse::state_type state) const
Retrieves the set of labels attached to the given state.
StateLabeling getSubLabeling(storm::storage::BitVector const &states) const
Retrieves the sub labeling that represents the same labeling as the current one for all selected stat...
A bit vector that is internally represented as a vector of 64-bit values.
Definition BitVector.h:18
uint_fast64_t getNextSetIndex(uint_fast64_t startingIndex) const
Retrieves the index of the bit that is the next bit set to true in the bit vector.
void set(uint_fast64_t index, bool value=true)
Sets the given truth value at the given index.
bool get(uint_fast64_t index) const
Retrieves the truth value of the bit at the given index and performs a bound check.
The flexible sparse matrix is used during state elimination.
storm::storage::SparseMatrix< ValueType > createSparseMatrix()
Creates a sparse matrix from the flexible sparse matrix.
row_type & getRow(index_type)
Returns an object representing the given row.
A class that can be used to build a sparse matrix by adding value by value.
SparseMatrix< value_type > build(index_type overriddenRowCount=0, index_type overriddenColumnCount=0, index_type overriddenRowGroupCount=0)
A class that holds a possibly non-square matrix in the compressed row storage format.
SparseMatrix getSubmatrix(bool useGroups, storm::storage::BitVector const &rowConstraint, storm::storage::BitVector const &columnConstraint, bool insertDiagonalEntries=false, storm::storage::BitVector const &makeZeroColumns=storm::storage::BitVector()) const
Creates a submatrix of the current matrix by dropping all rows and columns whose bits are not set to ...
index_type getRowCount() const
Returns the number of rows of the matrix.
models::sparse::Dtmc< RationalFunction > timeTravel(models::sparse::Dtmc< RationalFunction > const &model, modelchecker::CheckTask< logic::Formula, RationalFunction > const &checkTask)
Perform time-travelling on the given model and the given checkTask.
#define STORM_LOG_INFO(message)
Definition logging.h:29
#define STORM_LOG_ERROR_COND(cond, message)
Definition macros.h:52
void closeFile(std::ofstream &stream)
Close the given file after writing.
Definition file.h:47
void openFile(std::string const &filepath, std::ofstream &filestream, bool append=false, bool silent=false)
Open the given file for writing.
Definition file.h:18
std::set< storm::RationalFunctionVariable > getAllParameters(Model< storm::RationalFunction > const &model)
Get all parameters (probability, rewards, and rates) occurring in the model.
Definition Model.cpp:728
bool labelsIntersectedEqual(const std::set< std::string > &labels1, const std::set< std::string > &labels2, const std::set< std::string > &intersection)
storm::storage::BitVector getReachableStates(storm::storage::SparseMatrix< T > const &transitionMatrix, storm::storage::BitVector const &initialStates, storm::storage::BitVector const &constraintStates, storm::storage::BitVector const &targetStates, bool useStepBound, uint_fast64_t maximalSteps, boost::optional< storm::storage::BitVector > const &choiceFilter)
Performs a forward depth-first search through the underlying graph structure to identify the states t...
Definition graph.cpp:48
bool isOne(ValueType const &a)
Definition constants.cpp:36
LabParser.cpp.
Definition cli.cpp:18
carl::Variable RationalFunctionVariable
carl::RationalFunction< Polynomial, true > RationalFunction