Storm
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
SparseDtmcPrctlHelper.cpp
Go to the documentation of this file.
2
5
9
13
16
21
23
29
30#include "storm/io/export.h"
34
37
43
44namespace storm {
45namespace modelchecker {
46namespace helper {
47
48template<>
49std::map<storm::storage::sparse::state_type, storm::RationalFunction> SparseDtmcPrctlHelper<storm::RationalFunction>::computeRewardBoundedValues(
51 std::shared_ptr<storm::logic::OperatorFormula const> /*rewardBoundedFormula*/) {
52 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "The specified property is not supported by this value type.");
53 return std::map<storm::storage::sparse::state_type, storm::RationalFunction>();
54}
55
56template<typename ValueType, typename RewardModelType>
57std::map<storm::storage::sparse::state_type, ValueType> SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeRewardBoundedValues(
58 Environment const& env, storm::models::sparse::Dtmc<ValueType> const& model, std::shared_ptr<storm::logic::OperatorFormula const> rewardBoundedFormula) {
59 storm::utility::Stopwatch swAll(true), swBuild, swCheck;
60
62
63 // Get lower and upper bounds for the solution.
64 auto lowerBound = rewardUnfolding.getLowerObjectiveBound();
65 auto upperBound = rewardUnfolding.getUpperObjectiveBound();
66
67 // Initialize epoch models
68 auto initEpoch = rewardUnfolding.getStartEpoch();
69 auto epochOrder = rewardUnfolding.getEpochComputationOrder(initEpoch);
70
71 // initialize data that will be needed for each epoch
72 std::vector<ValueType> x, b;
73 std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> linEqSolver;
74
75 Environment preciseEnv = env;
76 ValueType precision = rewardUnfolding.getRequiredEpochModelPrecision(
77 initEpoch, storm::utility::convertNumber<ValueType>(storm::settings::getModule<storm::settings::modules::GeneralSettings>().getPrecision()));
78 preciseEnv.solver().setLinearEquationSolverPrecision(storm::utility::convertNumber<storm::RationalNumber>(precision));
79
80 // In case of cdf export we store the necessary data.
81 std::vector<std::vector<ValueType>> cdfData;
82
83 // Set the correct equation problem format.
85 rewardUnfolding.setEquationSystemFormatForEpochModel(linearEquationSolverFactory.getEquationProblemFormat(preciseEnv));
86
87 storm::utility::ProgressMeasurement progress("epochs");
88 progress.setMaxCount(epochOrder.size());
89 progress.startNewMeasurement(0);
90 uint64_t numCheckedEpochs = 0;
91 for (auto const& epoch : epochOrder) {
92 swBuild.start();
93 auto& epochModel = rewardUnfolding.setCurrentEpoch(epoch);
94 swBuild.stop();
95 swCheck.start();
96 rewardUnfolding.setSolutionForCurrentEpoch(epochModel.analyzeSingleObjective(preciseEnv, x, b, linEqSolver, lowerBound, upperBound));
97 swCheck.stop();
99 !rewardUnfolding.getEpochManager().hasBottomDimension(epoch)) {
100 std::vector<ValueType> cdfEntry;
101 for (uint64_t i = 0; i < rewardUnfolding.getEpochManager().getDimensionCount(); ++i) {
102 uint64_t offset = rewardUnfolding.getDimension(i).boundType == helper::rewardbounded::DimensionBoundType::LowerBound ? 1 : 0;
103 cdfEntry.push_back(storm::utility::convertNumber<ValueType>(rewardUnfolding.getEpochManager().getDimensionOfEpoch(epoch, i) + offset) *
104 rewardUnfolding.getDimension(i).scalingFactor);
105 }
106 cdfEntry.push_back(rewardUnfolding.getInitialStateResult(epoch));
107 cdfData.push_back(std::move(cdfEntry));
108 }
109 ++numCheckedEpochs;
110 progress.updateProgress(numCheckedEpochs);
112 break;
113 }
114 }
115
116 std::map<storm::storage::sparse::state_type, ValueType> result;
117 for (auto initState : model.getInitialStates()) {
118 result[initState] = rewardUnfolding.getInitialStateResult(initEpoch, initState);
119 }
120
121 swAll.stop();
122
124 std::vector<std::string> headers;
125 for (uint64_t i = 0; i < rewardUnfolding.getEpochManager().getDimensionCount(); ++i) {
126 headers.push_back(rewardUnfolding.getDimension(i).formula->toString());
127 }
128 headers.push_back("Result");
129 storm::io::exportDataToCSVFile<ValueType, std::string, std::string>(
130 storm::settings::getModule<storm::settings::modules::IOSettings>().getExportCdfDirectory() + "cdf.csv", cdfData, headers);
131 }
132
134 STORM_PRINT_AND_LOG("---------------------------------\n");
135 STORM_PRINT_AND_LOG("Statistics:\n");
136 STORM_PRINT_AND_LOG("---------------------------------\n");
137 STORM_PRINT_AND_LOG(" #checked epochs: " << epochOrder.size() << ".\n");
138 STORM_PRINT_AND_LOG(" overall Time: " << swAll << ".\n");
139 STORM_PRINT_AND_LOG("Epoch Model building Time: " << swBuild << ".\n");
140 STORM_PRINT_AND_LOG("Epoch Model checking Time: " << swCheck << ".\n");
141 STORM_PRINT_AND_LOG("---------------------------------\n");
142 }
143
144 return result;
145}
146
147template<typename ValueType, typename RewardModelType>
150 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates,
151 bool qualitative, ModelCheckerHint const& hint) {
152 std::vector<ValueType> result(transitionMatrix.getRowCount(), storm::utility::zero<ValueType>());
153
154 // We need to identify the maybe states (states which have a probability for satisfying the until formula
155 // that is strictly between 0 and 1) and the states that satisfy the formula with probability 1.
156 storm::storage::BitVector maybeStates, statesWithProbability1;
157
158 if (hint.isExplicitModelCheckerHint() && hint.template asExplicitModelCheckerHint<ValueType>().getComputeOnlyMaybeStates()) {
159 maybeStates = hint.template asExplicitModelCheckerHint<ValueType>().getMaybeStates();
160
161 // Treat the states with probability one
162 std::vector<ValueType> const& resultsForNonMaybeStates = hint.template asExplicitModelCheckerHint<ValueType>().getResultHint();
163 statesWithProbability1 = storm::storage::BitVector(maybeStates.size(), false);
164 storm::storage::BitVector nonMaybeStates = ~maybeStates;
165 for (auto state : nonMaybeStates) {
166 if (storm::utility::isOne(resultsForNonMaybeStates[state])) {
167 statesWithProbability1.set(state, true);
168 result[state] = storm::utility::one<ValueType>();
169 } else {
170 STORM_LOG_THROW(storm::utility::isZero(resultsForNonMaybeStates[state]), storm::exceptions::IllegalArgumentException,
171 "Expected that the result hint specifies probabilities in {0,1} for non-maybe states");
172 }
173 }
174
175 STORM_LOG_INFO("Preprocessing: " << statesWithProbability1.getNumberOfSetBits() << " states with probability 1 (" << maybeStates.getNumberOfSetBits()
176 << " states remaining).");
177 } else {
178 // Get all states that have probability 0 and 1 of satisfying the until-formula.
179 std::pair<storm::storage::BitVector, storm::storage::BitVector> statesWithProbability01 =
180 storm::utility::graph::performProb01(backwardTransitions, phiStates, psiStates);
181 storm::storage::BitVector statesWithProbability0 = std::move(statesWithProbability01.first);
182 statesWithProbability1 = std::move(statesWithProbability01.second);
183 maybeStates = ~(statesWithProbability0 | statesWithProbability1);
184
185 STORM_LOG_INFO("Preprocessing: " << statesWithProbability1.getNumberOfSetBits() << " states with probability 1, "
186 << statesWithProbability0.getNumberOfSetBits() << " with probability 0 (" << maybeStates.getNumberOfSetBits()
187 << " states remaining).");
188
189 // Set values of resulting vector that are known exactly.
190 storm::utility::vector::setVectorValues<ValueType>(result, statesWithProbability0, storm::utility::zero<ValueType>());
191 storm::utility::vector::setVectorValues<ValueType>(result, statesWithProbability1, storm::utility::one<ValueType>());
192 }
193
194 // Check if the values of the maybe states are relevant for the SolveGoal
195 bool maybeStatesNotRelevant = goal.hasRelevantValues() && goal.relevantValues().isDisjointFrom(maybeStates);
196
197 // Check whether we need to compute exact probabilities for some states.
198 if (qualitative || maybeStatesNotRelevant) {
199 // Set the values for all maybe-states to 0.5 to indicate that their probability values are neither 0 nor 1.
200 storm::utility::vector::setVectorValues<ValueType>(result, maybeStates, storm::utility::convertNumber<ValueType>(0.5));
201 } else {
202 if (!maybeStates.empty()) {
203 // In this case we have to compute the probabilities.
204
205 // Check whether we need to convert the input to equation system format.
207 bool convertToEquationSystem =
209
210 // We can eliminate the rows and columns from the original transition probability matrix.
211 storm::storage::SparseMatrix<ValueType> submatrix = transitionMatrix.getSubmatrix(true, maybeStates, maybeStates, convertToEquationSystem);
212 if (convertToEquationSystem) {
213 // Converting the matrix from the fixpoint notation to the form needed for the equation
214 // system. That is, we go from x = A*x + b to (I-A)x = b.
215 submatrix.convertToEquationSystem();
216 }
217
218 // Initialize the x vector with the hint (if available) or with 0.5 for each element.
219 // This is the initial guess for the iterative solvers. It should be safe as for all
220 // 'maybe' states we know that the probability is strictly larger than 0.
221 std::vector<ValueType> x;
222 if (hint.isExplicitModelCheckerHint() && hint.template asExplicitModelCheckerHint<ValueType>().hasResultHint()) {
223 x = storm::utility::vector::filterVector(hint.template asExplicitModelCheckerHint<ValueType>().getResultHint(), maybeStates);
224 } else {
225 x = std::vector<ValueType>(maybeStates.getNumberOfSetBits(), storm::utility::convertNumber<ValueType>(0.5));
226 }
227
228 // Prepare the right-hand side of the equation system. For entry i this corresponds to
229 // the accumulated probability of going from state i to some 'yes' state.
230 std::vector<ValueType> b = transitionMatrix.getConstrainedRowSumVector(maybeStates, statesWithProbability1);
231
232 // Now solve the created system of linear equations.
233 goal.restrictRelevantValues(maybeStates);
234 std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> solver =
235 storm::solver::configureLinearEquationSolver(env, std::move(goal), linearEquationSolverFactory, std::move(submatrix));
236 solver->setBounds(storm::utility::zero<ValueType>(), storm::utility::one<ValueType>());
237 solver->solveEquations(env, x, b);
238
239 // Set values of resulting vector according to result.
240 storm::utility::vector::setVectorValues<ValueType>(result, maybeStates, x);
241 }
242 }
243 return result;
244}
245
246template<typename ValueType, typename RewardModelType>
249 storm::storage::BitVector const& initialStates, storm::storage::BitVector const& phiStates, storm::storage::BitVector const& psiStates) {
250 uint_fast64_t numberOfStates = transitionMatrix.getRowCount();
251 std::vector<ValueType> result(numberOfStates, storm::utility::zero<ValueType>());
252
253 // All states are relevant
254 storm::storage::BitVector relevantStates(numberOfStates, true);
255
256 // Compute exact probabilities for some states.
257 if (!relevantStates.empty()) {
258 // Check whether we need to convert the input to equation system format.
260 bool convertToEquationSystem =
262
263 storm::storage::SparseMatrix<ValueType> submatrix(transitionMatrix);
264 submatrix.makeRowsAbsorbing(phiStates);
265 submatrix.makeRowsAbsorbing(psiStates);
266 // submatrix.deleteDiagonalEntries(psiStates);
267 // storm::storage::BitVector failState(numberOfStates, false);
268 // failState.set(0, true);
269 submatrix.deleteDiagonalEntries();
270 submatrix = submatrix.transpose();
271 submatrix = submatrix.getSubmatrix(true, relevantStates, relevantStates, convertToEquationSystem);
272
273 if (convertToEquationSystem) {
274 // Converting the matrix from the fixpoint notation to the form needed for the equation
275 // system. That is, we go from x = A*x + b to (I-A)x = b.
276 submatrix.convertToEquationSystem();
277 }
278
279 // Initialize the x vector with 0.5 for each element.
280 // This is the initial guess for the iterative solvers. It should be safe as for all
281 // 'maybe' states we know that the probability is strictly larger than 0.
282 std::vector<ValueType> x = std::vector<ValueType>(relevantStates.getNumberOfSetBits(), storm::utility::convertNumber<ValueType>(0.5));
283
284 // Prepare the right-hand side of the equation system.
285 std::vector<ValueType> b(relevantStates.getNumberOfSetBits(), storm::utility::zero<ValueType>());
286 // Set initial states
287 size_t i = 0;
288 ValueType initDist = storm::utility::one<ValueType>() / storm::utility::convertNumber<ValueType>(initialStates.getNumberOfSetBits());
289 for (auto state : relevantStates) {
290 if (initialStates.get(state)) {
291 b[i] = initDist;
292 }
293 ++i;
294 }
295
296 // Now solve the created system of linear equations.
297 goal.restrictRelevantValues(relevantStates);
298 std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> solver =
299 storm::solver::configureLinearEquationSolver(env, std::move(goal), linearEquationSolverFactory, std::move(submatrix));
300 solver->setBounds(storm::utility::zero<ValueType>(), storm::utility::one<ValueType>());
301 solver->solveEquations(env, x, b);
302
303 // Set values of resulting vector according to result.
304 storm::utility::vector::setVectorValues<ValueType>(result, relevantStates, x);
305 }
306 return result;
307}
308
309template<typename ValueType, typename RewardModelType>
312 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& psiStates, bool qualitative) {
313 goal.oneMinus();
314 std::vector<ValueType> result = computeUntilProbabilities(env, std::move(goal), transitionMatrix, backwardTransitions,
315 storm::storage::BitVector(transitionMatrix.getRowCount(), true), ~psiStates, qualitative);
316 for (auto& entry : result) {
317 entry = storm::utility::one<ValueType>() - entry;
318 }
319 return result;
320}
321
322template<typename ValueType, typename RewardModelType>
324 Environment const& env, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& nextStates) {
325 // Create the vector with which to multiply and initialize it correctly.
326 std::vector<ValueType> result(transitionMatrix.getRowCount());
327 storm::utility::vector::setVectorValues(result, nextStates, storm::utility::one<ValueType>());
328
329 // Perform one single matrix-vector multiplication.
330 auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, transitionMatrix);
331 multiplier->multiply(env, result, nullptr, result);
332 return result;
333}
334
335template<typename ValueType, typename RewardModelType>
338 RewardModelType const& rewardModel, uint_fast64_t stepBound) {
339 // Initialize result to the null vector.
340 std::vector<ValueType> result(transitionMatrix.getRowCount());
341
342 // Compute the reward vector to add in each step based on the available reward models.
343 std::vector<ValueType> totalRewardVector = rewardModel.getTotalRewardVector(transitionMatrix);
344
345 // Perform the matrix vector multiplication as often as required by the formula bound.
346 auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, transitionMatrix);
347 multiplier->repeatedMultiply(env, result, &totalRewardVector, stepBound);
348
349 return result;
350}
351
352template<typename ValueType, typename RewardModelType>
355 RewardModelType const& rewardModel, uint_fast64_t stepCount) {
356 // Only compute the result if the model has a state-based reward this->getModel().
357 STORM_LOG_THROW(rewardModel.hasStateRewards(), storm::exceptions::InvalidPropertyException,
358 "Computing instantaneous rewards for a reward model that does not define any state-rewards. The result is trivially 0.");
359
360 // Initialize result to state rewards of the model.
361 std::vector<ValueType> result = rewardModel.getStateRewardVector();
362
363 // Perform the matrix vector multiplication as often as required by the formula bound.
364 auto multiplier = storm::solver::MultiplierFactory<ValueType>().create(env, transitionMatrix);
365 multiplier->repeatedMultiply(env, result, nullptr, stepCount);
366
367 return result;
368}
369
370template<typename ValueType, typename RewardModelType>
373 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, bool qualitative, ModelCheckerHint const& hint) {
374 // Identify the states from which only states with zero reward are reachable.
375 // We can then compute reachability rewards assuming these states as target set.
376 storm::storage::BitVector statesWithoutReward = rewardModel.getStatesWithZeroReward(transitionMatrix);
377 storm::storage::BitVector rew0States = storm::utility::graph::performProbGreater0(backwardTransitions, statesWithoutReward, ~statesWithoutReward);
378 rew0States.complement();
379 return computeReachabilityRewards(env, std::move(goal), transitionMatrix, backwardTransitions, rewardModel, rew0States, qualitative, hint);
380}
381
382template<typename ValueType, typename RewardModelType>
385 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates,
386 bool qualitative, ModelCheckerHint const& hint) {
387 return computeReachabilityRewards(
388 env, std::move(goal), transitionMatrix, backwardTransitions,
389 [&](uint_fast64_t numberOfRows, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::BitVector const& maybeStates) {
390 return rewardModel.getTotalRewardVector(numberOfRows, transitionMatrix, maybeStates);
391 },
392 targetStates, qualitative, [&]() { return rewardModel.getStatesWithZeroReward(transitionMatrix); }, hint);
393}
394
395template<typename ValueType, typename RewardModelType>
398 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, std::vector<ValueType> const& totalStateRewardVector,
399 storm::storage::BitVector const& targetStates, bool qualitative, ModelCheckerHint const& hint) {
400 return computeReachabilityRewards(
401 env, std::move(goal), transitionMatrix, backwardTransitions,
402 [&](uint_fast64_t numberOfRows, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const& maybeStates) {
403 std::vector<ValueType> result(numberOfRows);
404 storm::utility::vector::selectVectorValues(result, maybeStates, totalStateRewardVector);
405 return result;
406 },
407 targetStates, qualitative, [&]() { return storm::utility::vector::filterZero(totalStateRewardVector); }, hint);
408}
409
410template<typename ValueType, typename RewardModelType>
413 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates, bool qualitative,
414 ModelCheckerHint const& hint) {
415 return computeReachabilityRewards(
416 env, std::move(goal), transitionMatrix, backwardTransitions,
417 [&](uint_fast64_t numberOfRows, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&) {
418 return std::vector<ValueType>(numberOfRows, storm::utility::one<ValueType>());
419 },
420 targetStates, qualitative, [&]() { return storm::storage::BitVector(transitionMatrix.getRowGroupCount(), false); }, hint);
421}
422
423// This function computes an upper bound on the reachability rewards (see Baier et al, CAV'17).
424template<typename ValueType>
425std::vector<ValueType> computeUpperRewardBounds(storm::storage::SparseMatrix<ValueType> const& transitionMatrix, std::vector<ValueType> const& rewards,
426 std::vector<ValueType> const& oneStepTargetProbabilities) {
427 DsMpiDtmcUpperRewardBoundsComputer<ValueType> dsmpi(transitionMatrix, rewards, oneStepTargetProbabilities);
428 std::vector<ValueType> bounds = dsmpi.computeUpperBounds();
429 return bounds;
430}
431
432template<>
433std::vector<storm::RationalFunction> computeUpperRewardBounds(storm::storage::SparseMatrix<storm::RationalFunction> const& /*transitionMatrix*/,
434 std::vector<storm::RationalFunction> const& /*rewards*/,
435 std::vector<storm::RationalFunction> const& /*oneStepTargetProbabilities*/) {
436 STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Computing upper reward bounds is not supported for rational functions.");
437}
438
439template<typename ValueType, typename RewardModelType>
442 storm::storage::SparseMatrix<ValueType> const& backwardTransitions,
443 std::function<std::vector<ValueType>(uint_fast64_t, storm::storage::SparseMatrix<ValueType> const&, storm::storage::BitVector const&)> const&
444 totalStateRewardVectorGetter,
445 storm::storage::BitVector const& targetStates, bool qualitative, std::function<storm::storage::BitVector()> const& zeroRewardStatesGetter,
446 ModelCheckerHint const& hint) {
447 std::vector<ValueType> result(transitionMatrix.getRowCount(), storm::utility::zero<ValueType>());
448
449 // Determine which states have reward zero
450 storm::storage::BitVector rew0States;
452 rew0States = storm::utility::graph::performProb1(backwardTransitions, zeroRewardStatesGetter(), targetStates);
453 } else {
454 rew0States = targetStates;
455 }
456
457 // Determine which states have a reward that is less than infinity.
458 storm::storage::BitVector maybeStates;
459 if (hint.isExplicitModelCheckerHint() && hint.template asExplicitModelCheckerHint<ValueType>().getComputeOnlyMaybeStates()) {
460 maybeStates = hint.template asExplicitModelCheckerHint<ValueType>().getMaybeStates();
461 storm::utility::vector::setVectorValues(result, ~(maybeStates | rew0States), storm::utility::infinity<ValueType>());
462
463 STORM_LOG_INFO("Preprocessing: " << rew0States.getNumberOfSetBits() << " States with reward zero (" << maybeStates.getNumberOfSetBits()
464 << " states remaining).");
465 } else {
466 storm::storage::BitVector trueStates(transitionMatrix.getRowCount(), true);
467 storm::storage::BitVector infinityStates = storm::utility::graph::performProb1(backwardTransitions, trueStates, rew0States);
468 infinityStates.complement();
469 maybeStates = ~(rew0States | infinityStates);
470
471 STORM_LOG_INFO("Preprocessing: " << infinityStates.getNumberOfSetBits() << " states with reward infinity, " << rew0States.getNumberOfSetBits()
472 << " states with reward zero (" << maybeStates.getNumberOfSetBits() << " states remaining).");
473
474 storm::utility::vector::setVectorValues(result, infinityStates, storm::utility::infinity<ValueType>());
475 }
476
477 // Check if the values of the maybe states are relevant for the SolveGoal
478 bool maybeStatesNotRelevant = goal.hasRelevantValues() && goal.relevantValues().isDisjointFrom(maybeStates);
479
480 // Check whether we need to compute exact rewards for some states.
481 if (qualitative || maybeStatesNotRelevant) {
482 // Set the values for all maybe-states to 1 to indicate that their reward values
483 // are neither 0 nor infinity.
484 storm::utility::vector::setVectorValues<ValueType>(result, maybeStates, storm::utility::one<ValueType>());
485 } else {
486 if (!maybeStates.empty()) {
487 // Check whether we need to convert the input to equation system format.
489 bool convertToEquationSystem =
491
492 // In this case we have to compute the reward values for the remaining states.
493 // We can eliminate the rows and columns from the original transition probability matrix.
494 storm::storage::SparseMatrix<ValueType> submatrix = transitionMatrix.getSubmatrix(true, maybeStates, maybeStates, convertToEquationSystem);
495
496 // Initialize the x vector with the hint (if available) or with 1 for each element.
497 // This is the initial guess for the iterative solvers.
498 std::vector<ValueType> x;
499 if (hint.isExplicitModelCheckerHint() && hint.template asExplicitModelCheckerHint<ValueType>().hasResultHint()) {
500 x = storm::utility::vector::filterVector(hint.template asExplicitModelCheckerHint<ValueType>().getResultHint(), maybeStates);
501 } else {
502 x = std::vector<ValueType>(submatrix.getColumnCount(), storm::utility::one<ValueType>());
503 }
504
505 // Prepare the right-hand side of the equation system.
506 std::vector<ValueType> b = totalStateRewardVectorGetter(submatrix.getRowCount(), transitionMatrix, maybeStates);
507
508 storm::solver::LinearEquationSolverRequirements requirements = linearEquationSolverFactory.getRequirements(env);
509 boost::optional<std::vector<ValueType>> upperRewardBounds;
510 requirements.clearLowerBounds();
511 if (requirements.upperBounds()) {
512 upperRewardBounds = computeUpperRewardBounds(submatrix, b, transitionMatrix.getConstrainedRowSumVector(maybeStates, rew0States));
513 requirements.clearUpperBounds();
514 }
515 STORM_LOG_THROW(!requirements.hasEnabledCriticalRequirement(), storm::exceptions::UncheckedRequirementException,
516 "Solver requirements " + requirements.getEnabledRequirementsAsString() + " not checked.");
517
518 // If necessary, convert the matrix from the fixpoint notation to the form needed for the equation system.
519 if (convertToEquationSystem) {
520 // go from x = A*x + b to (I-A)x = b.
521 submatrix.convertToEquationSystem();
522 }
523
524 // Create the solver.
525 goal.restrictRelevantValues(maybeStates);
526 std::unique_ptr<storm::solver::LinearEquationSolver<ValueType>> solver =
527 storm::solver::configureLinearEquationSolver(env, std::move(goal), linearEquationSolverFactory, std::move(submatrix));
528 solver->setLowerBound(storm::utility::zero<ValueType>());
529 if (upperRewardBounds) {
530 solver->setUpperBounds(std::move(upperRewardBounds.get()));
531 }
532
533 // Now solve the resulting equation system.
534 solver->solveEquations(env, x, b);
535
536 // Set values of resulting vector according to result.
537 storm::utility::vector::setVectorValues<ValueType>(result, maybeStates, x);
538 }
539 }
540 return result;
541}
542
543template<typename ValueType, typename RewardModelType>
544typename SparseDtmcPrctlHelper<ValueType, RewardModelType>::BaierTransformedModel SparseDtmcPrctlHelper<ValueType, RewardModelType>::computeBaierTransformation(
545 Environment const& env, storm::storage::SparseMatrix<ValueType> const& transitionMatrix, storm::storage::SparseMatrix<ValueType> const& backwardTransitions,
546 storm::storage::BitVector const& targetStates, storm::storage::BitVector const& conditionStates,
547 boost::optional<std::vector<ValueType>> const& stateRewards) {
548 BaierTransformedModel result;
549
550 // Start by computing all 'before' states, i.e. the states for which the conditional probability is defined.
551 std::vector<ValueType> probabilitiesToReachConditionStates =
552 computeUntilProbabilities(env, storm::solver::SolveGoal<ValueType>(), transitionMatrix, backwardTransitions,
553 storm::storage::BitVector(transitionMatrix.getRowCount(), true), conditionStates, false);
554
555 result.beforeStates = storm::storage::BitVector(targetStates.size(), true);
556 uint_fast64_t state = 0;
557 uint_fast64_t beforeStateIndex = 0;
558 for (auto const& value : probabilitiesToReachConditionStates) {
559 if (value == storm::utility::zero<ValueType>()) {
560 result.beforeStates.set(state, false);
561 } else {
562 probabilitiesToReachConditionStates[beforeStateIndex] = value;
563 ++beforeStateIndex;
564 }
565 ++state;
566 }
567 probabilitiesToReachConditionStates.resize(beforeStateIndex);
568
569 if (targetStates.empty()) {
570 result.noTargetStates = true;
571 return result;
572 } else if (!result.beforeStates.empty()) {
573 // If there are some states for which the conditional probability is defined and there are some
574 // states that can reach the target states without visiting condition states first, we need to
575 // do more work.
576
577 // First, compute the relevant states and some offsets.
578 storm::storage::BitVector allStates(targetStates.size(), true);
579 std::vector<uint_fast64_t> numberOfBeforeStatesUpToState = result.beforeStates.getNumberOfSetBitsBeforeIndices();
580 storm::storage::BitVector statesWithProbabilityGreater0 = storm::utility::graph::performProbGreater0(backwardTransitions, allStates, targetStates);
581 statesWithProbabilityGreater0 &= storm::utility::graph::getReachableStates(transitionMatrix, conditionStates, allStates, targetStates);
582 uint_fast64_t normalStatesOffset = result.beforeStates.getNumberOfSetBits();
583 std::vector<uint_fast64_t> numberOfNormalStatesUpToState = statesWithProbabilityGreater0.getNumberOfSetBitsBeforeIndices();
584
585 // All transitions going to states with probability zero, need to be redirected to a deadlock state.
586 bool addDeadlockState = false;
587 uint_fast64_t deadlockState = normalStatesOffset + statesWithProbabilityGreater0.getNumberOfSetBits();
588
589 // Now, we create the matrix of 'before' and 'normal' states.
591
592 // Start by creating the transitions of the 'before' states.
593 uint_fast64_t currentRow = 0;
594 for (auto beforeState : result.beforeStates) {
595 if (conditionStates.get(beforeState)) {
596 // For condition states, we move to the 'normal' states.
597 ValueType zeroProbability = storm::utility::zero<ValueType>();
598 for (auto const& successorEntry : transitionMatrix.getRow(beforeState)) {
599 if (statesWithProbabilityGreater0.get(successorEntry.getColumn())) {
600 builder.addNextValue(currentRow, normalStatesOffset + numberOfNormalStatesUpToState[successorEntry.getColumn()],
601 successorEntry.getValue());
602 } else {
603 zeroProbability += successorEntry.getValue();
604 }
605 }
606 if (!storm::utility::isZero(zeroProbability)) {
607 builder.addNextValue(currentRow, deadlockState, zeroProbability);
608 }
609 } else {
610 // For non-condition states, we scale the probabilities going to other before states.
611 for (auto const& successorEntry : transitionMatrix.getRow(beforeState)) {
612 if (result.beforeStates.get(successorEntry.getColumn())) {
613 builder.addNextValue(currentRow, numberOfBeforeStatesUpToState[successorEntry.getColumn()],
614 successorEntry.getValue() *
615 probabilitiesToReachConditionStates[numberOfBeforeStatesUpToState[successorEntry.getColumn()]] /
616 probabilitiesToReachConditionStates[currentRow]);
617 }
618 }
619 }
620 ++currentRow;
621 }
622
623 // Then, create the transitions of the 'normal' states.
624 for (auto state : statesWithProbabilityGreater0) {
625 ValueType zeroProbability = storm::utility::zero<ValueType>();
626 for (auto const& successorEntry : transitionMatrix.getRow(state)) {
627 if (statesWithProbabilityGreater0.get(successorEntry.getColumn())) {
628 builder.addNextValue(currentRow, normalStatesOffset + numberOfNormalStatesUpToState[successorEntry.getColumn()], successorEntry.getValue());
629 } else {
630 zeroProbability += successorEntry.getValue();
631 }
632 }
633 if (!storm::utility::isZero(zeroProbability)) {
634 addDeadlockState = true;
635 builder.addNextValue(currentRow, deadlockState, zeroProbability);
636 }
637 ++currentRow;
638 }
639 if (addDeadlockState) {
640 builder.addNextValue(deadlockState, deadlockState, storm::utility::one<ValueType>());
641 }
642
643 // Build the new transition matrix and the new targets.
644 result.transitionMatrix = builder.build(addDeadlockState ? (deadlockState + 1) : deadlockState);
645 storm::storage::BitVector newTargetStates = targetStates % result.beforeStates;
646 newTargetStates.resize(result.transitionMatrix.get().getRowCount());
647 for (auto state : targetStates % statesWithProbabilityGreater0) {
648 newTargetStates.set(normalStatesOffset + state, true);
649 }
650 result.targetStates = std::move(newTargetStates);
651
652 // If a reward model was given, we need to compute the rewards for the transformed model.
653 if (stateRewards) {
654 std::vector<ValueType> newStateRewards(result.beforeStates.getNumberOfSetBits());
655 storm::utility::vector::selectVectorValues(newStateRewards, result.beforeStates, stateRewards.get());
656
657 newStateRewards.reserve(result.transitionMatrix.get().getRowCount());
658 for (auto state : statesWithProbabilityGreater0) {
659 newStateRewards.push_back(stateRewards.get()[state]);
660 }
661 // Add a zero reward to the deadlock state.
662 if (addDeadlockState) {
663 newStateRewards.push_back(storm::utility::zero<ValueType>());
664 }
665 result.stateRewards = std::move(newStateRewards);
666 }
667 }
668
669 return result;
670}
671
672template<typename ValueType, typename RewardModelType>
673storm::storage::BitVector SparseDtmcPrctlHelper<ValueType, RewardModelType>::BaierTransformedModel::getNewRelevantStates() const {
674 storm::storage::BitVector newRelevantStates(transitionMatrix.get().getRowCount());
675 for (uint64_t i = 0; i < this->beforeStates.getNumberOfSetBits(); ++i) {
676 newRelevantStates.set(i);
677 }
678 return newRelevantStates;
679}
680
681template<typename ValueType, typename RewardModelType>
682storm::storage::BitVector SparseDtmcPrctlHelper<ValueType, RewardModelType>::BaierTransformedModel::getNewRelevantStates(
683 storm::storage::BitVector const& oldRelevantStates) const {
684 storm::storage::BitVector result = oldRelevantStates % this->beforeStates;
685 result.resize(transitionMatrix.get().getRowCount());
686 return result;
687}
688
689template<typename ValueType, typename RewardModelType>
692 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, storm::storage::BitVector const& targetStates,
693 storm::storage::BitVector const& conditionStates, bool qualitative) {
694 // Prepare result vector.
695 std::vector<ValueType> result(transitionMatrix.getRowCount(), storm::utility::infinity<ValueType>());
696
697 if (!conditionStates.empty()) {
698 BaierTransformedModel transformedModel =
699 computeBaierTransformation(env, transitionMatrix, backwardTransitions, targetStates, conditionStates, boost::none);
700
701 if (transformedModel.noTargetStates) {
702 storm::utility::vector::setVectorValues(result, transformedModel.beforeStates, storm::utility::zero<ValueType>());
703 } else {
704 // At this point, we do not need to check whether there are 'before' states, since the condition
705 // states were non-empty so there is at least one state with a positive probability of satisfying
706 // the condition.
707
708 // Now compute reachability probabilities in the transformed model.
709 storm::storage::SparseMatrix<ValueType> const& newTransitionMatrix = transformedModel.transitionMatrix.get();
710 storm::storage::BitVector newRelevantValues;
711 if (goal.hasRelevantValues()) {
712 newRelevantValues = transformedModel.getNewRelevantStates(goal.relevantValues());
713 } else {
714 newRelevantValues = transformedModel.getNewRelevantStates();
715 }
716 goal.setRelevantValues(std::move(newRelevantValues));
717 std::vector<ValueType> conditionalProbabilities =
718 computeUntilProbabilities(env, std::move(goal), newTransitionMatrix, newTransitionMatrix.transpose(),
719 storm::storage::BitVector(newTransitionMatrix.getRowCount(), true), transformedModel.targetStates.get(), qualitative);
720
721 storm::utility::vector::setVectorValues(result, transformedModel.beforeStates, conditionalProbabilities);
722 }
723 }
724
725 return result;
726}
727
728template<typename ValueType, typename RewardModelType>
731 storm::storage::SparseMatrix<ValueType> const& backwardTransitions, RewardModelType const& rewardModel, storm::storage::BitVector const& targetStates,
732 storm::storage::BitVector const& conditionStates, bool qualitative) {
733 // Prepare result vector.
734 std::vector<ValueType> result(transitionMatrix.getRowCount(), storm::utility::infinity<ValueType>());
735
736 if (!conditionStates.empty()) {
737 BaierTransformedModel transformedModel = computeBaierTransformation(env, transitionMatrix, backwardTransitions, targetStates, conditionStates,
738 rewardModel.getTotalRewardVector(transitionMatrix));
739
740 if (transformedModel.noTargetStates) {
741 storm::utility::vector::setVectorValues(result, transformedModel.beforeStates, storm::utility::zero<ValueType>());
742 } else {
743 // At this point, we do not need to check whether there are 'before' states, since the condition
744 // states were non-empty so there is at least one state with a positive probability of satisfying
745 // the condition.
746
747 // Now compute reachability probabilities in the transformed model.
748 storm::storage::SparseMatrix<ValueType> const& newTransitionMatrix = transformedModel.transitionMatrix.get();
749 storm::storage::BitVector newRelevantValues;
750 if (goal.hasRelevantValues()) {
751 newRelevantValues = transformedModel.getNewRelevantStates(goal.relevantValues());
752 } else {
753 newRelevantValues = transformedModel.getNewRelevantStates();
754 }
755 goal.setRelevantValues(std::move(newRelevantValues));
756 std::vector<ValueType> conditionalRewards =
757 computeReachabilityRewards(env, std::move(goal), newTransitionMatrix, newTransitionMatrix.transpose(), transformedModel.stateRewards.get(),
758 transformedModel.targetStates.get(), qualitative);
759 storm::utility::vector::setVectorValues(result, transformedModel.beforeStates, conditionalRewards);
760 }
761 }
762
763 return result;
764}
765
766template class SparseDtmcPrctlHelper<double>;
767
768#ifdef STORM_HAVE_CARL
771#endif
772} // namespace helper
773} // namespace modelchecker
774} // namespace storm
SolverEnvironment & solver()
void setLinearEquationSolverPrecision(boost::optional< storm::RationalNumber > const &newPrecision, boost::optional< bool > const &relativePrecision=boost::none)
This class contains information that might accelerate the model checking process.
static std::vector< ValueType > computeNextProbabilities(Environment const &env, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::BitVector const &nextStates)
static std::vector< ValueType > computeReachabilityTimes(Environment const &env, storm::solver::SolveGoal< ValueType > &&goal, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::SparseMatrix< ValueType > const &backwardTransitions, storm::storage::BitVector const &targetStates, bool qualitative, ModelCheckerHint const &hint=ModelCheckerHint())
static std::vector< ValueType > computeReachabilityRewards(Environment const &env, storm::solver::SolveGoal< ValueType > &&goal, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::SparseMatrix< ValueType > const &backwardTransitions, RewardModelType const &rewardModel, storm::storage::BitVector const &targetStates, bool qualitative, ModelCheckerHint const &hint=ModelCheckerHint())
static std::vector< ValueType > computeUntilProbabilities(Environment const &env, storm::solver::SolveGoal< ValueType > &&goal, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::SparseMatrix< ValueType > const &backwardTransitions, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates, bool qualitative, ModelCheckerHint const &hint=ModelCheckerHint())
static std::vector< ValueType > computeConditionalProbabilities(Environment const &env, storm::solver::SolveGoal< ValueType > &&goal, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::SparseMatrix< ValueType > const &backwardTransitions, storm::storage::BitVector const &targetStates, storm::storage::BitVector const &conditionStates, bool qualitative)
static std::vector< ValueType > computeAllUntilProbabilities(Environment const &env, storm::solver::SolveGoal< ValueType > &&goal, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::BitVector const &initialStates, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates)
static std::vector< ValueType > computeTotalRewards(Environment const &env, storm::solver::SolveGoal< ValueType > &&goal, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::SparseMatrix< ValueType > const &backwardTransitions, RewardModelType const &rewardModel, bool qualitative, ModelCheckerHint const &hint=ModelCheckerHint())
static std::map< storm::storage::sparse::state_type, ValueType > computeRewardBoundedValues(Environment const &env, storm::models::sparse::Dtmc< ValueType > const &model, std::shared_ptr< storm::logic::OperatorFormula const > rewardBoundedFormula)
static std::vector< ValueType > computeConditionalRewards(Environment const &env, storm::solver::SolveGoal< ValueType > &&goal, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::SparseMatrix< ValueType > const &backwardTransitions, RewardModelType const &rewardModel, storm::storage::BitVector const &targetStates, storm::storage::BitVector const &conditionStates, bool qualitative)
static std::vector< ValueType > computeInstantaneousRewards(Environment const &env, storm::solver::SolveGoal< ValueType > &&goal, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, RewardModelType const &rewardModel, uint_fast64_t stepCount)
static std::vector< ValueType > computeGloballyProbabilities(Environment const &env, storm::solver::SolveGoal< ValueType > &&goal, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::SparseMatrix< ValueType > const &backwardTransitions, storm::storage::BitVector const &psiStates, bool qualitative)
static std::vector< ValueType > computeCumulativeRewards(Environment const &env, storm::solver::SolveGoal< ValueType > &&goal, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, RewardModelType const &rewardModel, uint_fast64_t stepBound)
uint64_t getDimensionOfEpoch(Epoch const &epoch, uint64_t const &dimension) const
Epoch getStartEpoch(bool setUnknownDimsToBottom=false)
Retrieves the desired epoch that needs to be analyzed to compute the reward bounded values.
EpochModel< ValueType, SingleObjectiveMode > & setCurrentEpoch(Epoch const &epoch)
std::vector< Epoch > getEpochComputationOrder(Epoch const &startEpoch, bool stopAtComputedEpochs=false)
Computes a sequence of epochs that need to be analyzed to get a result at the start epoch.
ValueType getRequiredEpochModelPrecision(Epoch const &startEpoch, ValueType const &precision)
Returns the precision required for the analyzis of each epoch model in order to achieve the given ove...
boost::optional< ValueType > getUpperObjectiveBound(uint64_t objectiveIndex=0)
Returns an upper/lower bound for the objective result in every state (if this bound could be computed...
void setEquationSystemFormatForEpochModel(storm::solver::LinearEquationSolverProblemFormat eqSysFormat)
This class represents a discrete-time Markov chain.
Definition Dtmc.h:14
storm::storage::BitVector const & getInitialStates() const
Retrieves the initial states of the model.
Definition Model.cpp:177
LinearEquationSolverRequirements getRequirements(Environment const &env) const
Retrieves the requirements of the solver if it was created with the current settings.
virtual LinearEquationSolverProblemFormat getEquationProblemFormat(Environment const &env) const
Retrieves the problem format that the solver expects if it was created with the current settings.
std::string getEnabledRequirementsAsString() const
Checks whether there are no critical requirements left.
std::unique_ptr< Multiplier< ValueType > > create(Environment const &env, storm::storage::SparseMatrix< ValueType > const &matrix)
A bit vector that is internally represented as a vector of 64-bit values.
Definition BitVector.h:18
void complement()
Negates all bits in the bit vector.
bool empty() const
Retrieves whether no bits are set to true in this bit vector.
void resize(uint_fast64_t newLength, bool init=false)
Resizes the bit vector to hold the given new number of bits.
void set(uint_fast64_t index, bool value=true)
Sets the given truth value at the given index.
size_t size() const
Retrieves the number of bits this bit vector can store.
uint_fast64_t getNumberOfSetBits() const
Returns the number of bits that are set to true in this bit vector.
std::vector< uint_fast64_t > getNumberOfSetBitsBeforeIndices() const
Retrieves a vector that holds at position i the number of bits set before index i.
bool get(uint_fast64_t index) const
Retrieves the truth value of the bit at the given index and performs a bound check.
A class that can be used to build a sparse matrix by adding value by value.
void addNextValue(index_type row, index_type column, value_type const &value)
Sets the matrix entry at the given row and column to the given 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.
void convertToEquationSystem()
Transforms the matrix into an equation system.
void makeRowsAbsorbing(storm::storage::BitVector const &rows, bool dropZeroEntries=false)
This function makes the given rows absorbing.
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 ...
std::vector< value_type > getConstrainedRowSumVector(storm::storage::BitVector const &rowConstraint, storm::storage::BitVector const &columnConstraint) const
Computes a vector whose i-th entry is the sum of the entries in the i-th selected row where only thos...
index_type getRowGroupCount() const
Returns the number of row groups in the matrix.
index_type getColumnCount() const
Returns the number of columns of the matrix.
void deleteDiagonalEntries(bool dropZeroEntries=false)
Sets all diagonal elements to zero.
storm::storage::SparseMatrix< value_type > transpose(bool joinGroups=false, bool keepZeros=false) const
Transposes the matrix.
index_type getRowCount() const
Returns the number of rows of the matrix.
A class that provides convenience operations to display run times.
bool updateProgress(uint64_t count)
Updates the progress to the current count and prints it if the delay passed.
void setMaxCount(uint64_t maxCount)
Sets the maximal possible count.
void startNewMeasurement(uint64_t startCount)
Starts a new measurement, dropping all progress information collected so far.
A class that provides convenience operations to display run times.
Definition Stopwatch.h:14
void start()
Start stopwatch (again) and start measuring time.
Definition Stopwatch.cpp:48
void stop()
Stop stopwatch and add measured time to total time.
Definition Stopwatch.cpp:42
#define STORM_LOG_INFO(message)
Definition logging.h:29
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:30
#define STORM_PRINT_AND_LOG(message)
Definition macros.h:68
SFTBDDChecker::ValueType ValueType
std::vector< ValueType > computeUpperRewardBounds(storm::storage::SparseMatrix< ValueType > const &transitionMatrix, std::vector< ValueType > const &rewards, std::vector< ValueType > const &oneStepTargetProbabilities)
SettingsType const & getModule()
Get module.
std::unique_ptr< storm::solver::LinearEquationSolver< ValueType > > configureLinearEquationSolver(Environment const &env, SolveGoal< ValueType, SolutionType > &&goal, storm::solver::LinearEquationSolverFactory< ValueType > const &factory, MatrixType &&matrix)
Definition SolveGoal.h:128
std::pair< storm::storage::BitVector, storm::storage::BitVector > performProb01(storm::models::sparse::DeterministicModel< T > const &model, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates)
Computes the sets of states that have probability 0 or 1, respectively, of satisfying phi until psi i...
Definition graph.cpp:400
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
storm::storage::BitVector performProbGreater0(storm::storage::SparseMatrix< T > const &backwardTransitions, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates, bool useStepBound, uint_fast64_t maximalSteps)
Performs a backward depth-first search trough the underlying graph structure of the given model to de...
Definition graph.cpp:322
storm::storage::BitVector performProb1(storm::storage::SparseMatrix< T > const &backwardTransitions, storm::storage::BitVector const &, storm::storage::BitVector const &psiStates, storm::storage::BitVector const &statesWithProbabilityGreater0)
Computes the set of states of the given model for which all paths lead to the given set of target sta...
Definition graph.cpp:383
bool isTerminate()
Check whether the program should terminate (due to some abort signal).
void setVectorValues(std::vector< T > &vector, storm::storage::BitVector const &positions, std::vector< T > const &values)
Sets the provided values at the provided positions in the given vector.
Definition vector.h:83
void selectVectorValues(std::vector< T > &vector, storm::storage::BitVector const &positions, std::vector< T > const &values)
Selects the elements from a vector at the specified positions and writes them consecutively into anot...
Definition vector.h:189
storm::storage::BitVector filterZero(std::vector< T > const &values)
Retrieves a bit vector containing all the indices for which the value at this position is equal to ze...
Definition vector.h:563
std::vector< Type > filterVector(std::vector< Type > const &in, storm::storage::BitVector const &filter)
Definition vector.h:1213
bool isOne(ValueType const &a)
Definition constants.cpp:36
bool isZero(ValueType const &a)
Definition constants.cpp:41
LabParser.cpp.
Definition cli.cpp:18