Storm 1.13.0.1
A Modern Probabilistic Model Checker
Loading...
Searching...
No Matches
SparseMarkovAutomatonCslModelChecker.cpp
Go to the documentation of this file.
2
18
19namespace storm {
20namespace modelchecker {
21template<typename SparseMarkovAutomatonModelType>
23 : SparsePropositionalModelChecker<SparseMarkovAutomatonModelType>(model) {
24 // Intentionally left empty.
25}
26
27template<typename ModelType>
29 bool* requiresSingleInitialState) {
30 auto singleObjectiveFragment = storm::logic::csrlstar()
34 .setTimeAllowed(true)
39 auto multiObjectiveFragment =
42 singleObjectiveFragment.setBoundedUntilFormulasAllowed(false).setCumulativeRewardFormulasAllowed(false);
43 multiObjectiveFragment.setTimeBoundedUntilFormulasAllowed(false).setCumulativeRewardFormulasAllowed(false);
44 }
45 if (checkTask.getFormula().isInFragment(singleObjectiveFragment)) {
46 return true;
47 } else if (checkTask.isOnlyInitialStatesRelevantSet() && checkTask.getFormula().isInFragment(multiObjectiveFragment)) {
48 if (requiresSingleInitialState) {
49 *requiresSingleInitialState = true;
50 }
51 return true;
52 }
53 return false;
54}
55
56template<typename SparseMarkovAutomatonModelType>
58 bool requiresSingleInitialState = false;
59 if (canHandleStatic(checkTask, &requiresSingleInitialState)) {
60 return !requiresSingleInitialState || this->getModel().getInitialStates().getNumberOfSetBits() == 1;
61 } else {
62 return false;
63 }
64}
65
66template<typename SparseMarkovAutomatonModelType>
69 storm::logic::BoundedUntilFormula const& pathFormula = checkTask.getFormula();
70 STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException,
71 "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
72 STORM_LOG_THROW(this->getModel().isClosed(), storm::exceptions::InvalidPropertyException,
73 "Unable to compute time-bounded reachability probabilities in non-closed Markov automaton.");
74 std::unique_ptr<CheckResult> rightResultPointer = this->check(env, pathFormula.getRightSubformula());
75 ExplicitQualitativeCheckResult<ValueType> const& rightResult = rightResultPointer->template asExplicitQualitativeCheckResult<ValueType>();
76
77 std::unique_ptr<CheckResult> leftResultPointer = this->check(env, pathFormula.getLeftSubformula());
78 ExplicitQualitativeCheckResult<ValueType> const& leftResult = leftResultPointer->template asExplicitQualitativeCheckResult<ValueType>();
79
80 STORM_LOG_THROW(pathFormula.getTimeBoundReference().isTimeBound(), storm::exceptions::NotImplementedException,
81 "Currently step-bounded and reward-bounded properties on MAs are not supported.");
82 double lowerBound = 0;
83 double upperBound = 0;
84 if (pathFormula.hasLowerBound()) {
85 lowerBound = pathFormula.getLowerBound<double>();
86 }
87 if (pathFormula.hasUpperBound()) {
88 upperBound = pathFormula.getNonStrictUpperBound<double>();
89 } else {
91 }
92
94 env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getExitRates(),
95 this->getModel().getMarkovianStates(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), std::make_pair(lowerBound, upperBound));
96 return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(result)));
97}
98
99template<typename SparseMarkovAutomatonModelType>
102 storm::logic::NextFormula const& pathFormula = checkTask.getFormula();
103 STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException,
104 "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
105 std::unique_ptr<CheckResult> subResultPointer = this->check(env, pathFormula.getSubformula());
106 ExplicitQualitativeCheckResult<ValueType> const& subResult = subResultPointer->template asExplicitQualitativeCheckResult<ValueType>();
108 env, checkTask.getOptimizationDirection(), checkTask.getUncertaintyResolutionMode(), this->getModel().getTransitionMatrix(),
109 subResult.getTruthValuesVector());
110 return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult)));
111}
112
113template<typename SparseMarkovAutomatonModelType>
116 storm::logic::GloballyFormula const& pathFormula = checkTask.getFormula();
117 STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException,
118 "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
119 std::unique_ptr<CheckResult> subResultPointer = this->check(env, pathFormula.getSubformula());
120 ExplicitQualitativeCheckResult<ValueType> const& subResult = subResultPointer->template asExplicitQualitativeCheckResult<ValueType>();
122 env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(),
123 this->getModel().getBackwardTransitions(), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), checkTask.isProduceSchedulersSet());
124 std::unique_ptr<CheckResult> result(new ExplicitQuantitativeCheckResult<ValueType>(std::move(ret.values)));
125 if (checkTask.isProduceSchedulersSet() && ret.scheduler) {
126 result->asExplicitQuantitativeCheckResult<ValueType>().setScheduler(std::move(ret.scheduler));
127 }
128 return result;
129}
130
131template<typename SparseMarkovAutomatonModelType>
134 storm::logic::UntilFormula const& pathFormula = checkTask.getFormula();
135 STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException,
136 "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
137 std::unique_ptr<CheckResult> leftResultPointer = this->check(env, pathFormula.getLeftSubformula());
138 std::unique_ptr<CheckResult> rightResultPointer = this->check(env, pathFormula.getRightSubformula());
139 ExplicitQualitativeCheckResult<ValueType>& leftResult = leftResultPointer->template asExplicitQualitativeCheckResult<ValueType>();
140 ExplicitQualitativeCheckResult<ValueType>& rightResult = rightResultPointer->template asExplicitQualitativeCheckResult<ValueType>();
141
143 env, checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(),
144 leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet(), checkTask.isProduceSchedulersSet());
145 std::unique_ptr<CheckResult> result(new ExplicitQuantitativeCheckResult<ValueType>(std::move(ret.values)));
146 if (checkTask.isProduceSchedulersSet() && ret.scheduler) {
147 result->asExplicitQuantitativeCheckResult<ValueType>().setScheduler(std::move(ret.scheduler));
148 }
149 return result;
150}
151
152template<typename SparseMarkovAutomatonModelType>
155 storm::logic::HOAPathFormula const& pathFormula = checkTask.getFormula();
156
159
160 auto formulaChecker = [&](storm::logic::Formula const& formula) {
161 return this->check(env, formula)->template asExplicitQualitativeCheckResult<ValueType>().getTruthValuesVector();
162 };
163 auto apSets = helper.computeApSets(pathFormula.getAPMapping(), formulaChecker);
164 std::vector<ValueType> numericResult = helper.computeDAProductProbabilities(env, *pathFormula.readAutomaton(), apSets);
165
166 std::unique_ptr<CheckResult> result(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult)));
167 if (checkTask.isProduceSchedulersSet()) {
168 result->asExplicitQuantitativeCheckResult<ValueType>().setScheduler(
169 std::make_unique<storm::storage::Scheduler<ValueType>>(helper.extractScheduler(this->getModel())));
170 }
171
172 return result;
173}
174
175template<typename SparseMarkovAutomatonModelType>
178 storm::logic::PathFormula const& pathFormula = checkTask.getFormula();
179
180 STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException,
181 "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
182
185
186 auto formulaChecker = [&](storm::logic::Formula const& formula) {
187 return this->check(env, formula)->template asExplicitQualitativeCheckResult<ValueType>().getTruthValuesVector();
188 };
189 std::vector<ValueType> numericResult = helper.computeLTLProbabilities(env, pathFormula, formulaChecker);
190
191 std::unique_ptr<CheckResult> result(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult)));
192 if (checkTask.isProduceSchedulersSet()) {
193 result->asExplicitQuantitativeCheckResult<ValueType>().setScheduler(
194 std::make_unique<storm::storage::Scheduler<ValueType>>(helper.extractScheduler(this->getModel())));
195 }
196
197 return result;
198}
199
200template<typename SparseMarkovAutomatonModelType>
203 storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula();
204 STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException,
205 "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
206 STORM_LOG_THROW(this->getModel().isClosed(), storm::exceptions::InvalidPropertyException,
207 "Unable to compute reachability rewards in non-closed Markov automaton.");
208 std::unique_ptr<CheckResult> subResultPointer = this->check(env, eventuallyFormula.getSubformula());
209 ExplicitQualitativeCheckResult<ValueType> const& subResult = subResultPointer->template asExplicitQualitativeCheckResult<ValueType>();
210 auto rewardModel = storm::utility::createFilteredRewardModel(this->getModel(), checkTask);
211
213 env, checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(),
214 this->getModel().getExitRates(), this->getModel().getMarkovianStates(), rewardModel.get(), subResult.getTruthValuesVector(),
215 checkTask.isProduceSchedulersSet());
216 std::unique_ptr<CheckResult> result(new ExplicitQuantitativeCheckResult<ValueType>(std::move(ret.values)));
217 if (checkTask.isProduceSchedulersSet() && ret.scheduler) {
218 result->asExplicitQuantitativeCheckResult<ValueType>().setScheduler(std::move(ret.scheduler));
219 }
220 return result;
221}
222
223template<typename SparseMarkovAutomatonModelType>
226 STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException,
227 "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
228 STORM_LOG_THROW(this->getModel().isClosed(), storm::exceptions::InvalidPropertyException,
229 "Unable to compute reachability rewards in non-closed Markov automaton.");
230 auto rewardModel = storm::utility::createFilteredRewardModel(this->getModel(), checkTask);
231
233 env, checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(),
234 this->getModel().getExitRates(), this->getModel().getMarkovianStates(), rewardModel.get(), checkTask.isProduceSchedulersSet());
235 std::unique_ptr<CheckResult> result(new ExplicitQuantitativeCheckResult<ValueType>(std::move(ret.values)));
236 if (checkTask.isProduceSchedulersSet() && ret.scheduler) {
237 result->asExplicitQuantitativeCheckResult<ValueType>().setScheduler(std::move(ret.scheduler));
238 }
239 return result;
240}
241
242template<typename SparseMarkovAutomatonModelType>
245 storm::logic::StateFormula const& stateFormula = checkTask.getFormula();
246 STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException,
247 "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
248 STORM_LOG_THROW(this->getModel().isClosed(), storm::exceptions::InvalidPropertyException,
249 "Unable to compute long-run average in non-closed Markov automaton.");
250 std::unique_ptr<CheckResult> subResultPointer = this->check(env, stateFormula);
251 ExplicitQualitativeCheckResult<ValueType> const& subResult = subResultPointer->template asExplicitQualitativeCheckResult<ValueType>();
252
254 this->getModel().getTransitionMatrix(), this->getModel().getMarkovianStates(), this->getModel().getExitRates());
256 auto values = helper.computeLongRunAverageProbabilities(env, subResult.getTruthValuesVector());
257
258 std::unique_ptr<CheckResult> result(new ExplicitQuantitativeCheckResult<ValueType>(std::move(values)));
259 if (checkTask.isProduceSchedulersSet()) {
260 result->asExplicitQuantitativeCheckResult<ValueType>().setScheduler(std::make_unique<storm::storage::Scheduler<ValueType>>(helper.extractScheduler()));
261 }
262 return result;
263}
264
265template<typename SparseMarkovAutomatonModelType>
268 STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException,
269 "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
270 STORM_LOG_THROW(this->getModel().isClosed(), storm::exceptions::InvalidPropertyException,
271 "Unable to compute long run average rewards in non-closed Markov automaton.");
272 auto rewardModel = storm::utility::createFilteredRewardModel(this->getModel(), checkTask);
273
275 this->getModel().getTransitionMatrix(), this->getModel().getMarkovianStates(), this->getModel().getExitRates());
277 auto values = helper.computeLongRunAverageRewards(env, rewardModel.get());
278
279 std::unique_ptr<CheckResult> result(new ExplicitQuantitativeCheckResult<ValueType>(std::move(values)));
280 if (checkTask.isProduceSchedulersSet()) {
281 result->asExplicitQuantitativeCheckResult<ValueType>().setScheduler(std::make_unique<storm::storage::Scheduler<ValueType>>(helper.extractScheduler()));
282 }
283 return result;
284}
285
286template<typename SparseMarkovAutomatonModelType>
289 storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula();
290 STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException,
291 "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
292 STORM_LOG_THROW(this->getModel().isClosed(), storm::exceptions::InvalidPropertyException,
293 "Unable to compute expected times in non-closed Markov automaton.");
294 std::unique_ptr<CheckResult> subResultPointer = this->check(env, eventuallyFormula.getSubformula());
295 ExplicitQualitativeCheckResult<ValueType>& subResult = subResultPointer->template asExplicitQualitativeCheckResult<ValueType>();
296
298 env, checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(),
299 this->getModel().getExitRates(), this->getModel().getMarkovianStates(), subResult.getTruthValuesVector(), checkTask.isProduceSchedulersSet());
300 std::unique_ptr<CheckResult> result(new ExplicitQuantitativeCheckResult<ValueType>(std::move(ret.values)));
301 if (checkTask.isProduceSchedulersSet() && ret.scheduler) {
302 result->asExplicitQuantitativeCheckResult<ValueType>().setScheduler(std::move(ret.scheduler));
303 }
304 return result;
305}
306
307template<typename SparseMarkovAutomatonModelType>
312
315} // namespace modelchecker
316} // namespace storm
Formula const & getRightSubformula() const
Formula const & getLeftSubformula() const
TimeBoundReference const & getTimeBoundReference(unsigned i=0) const
ValueType getNonStrictUpperBound(unsigned i=0) const
storm::expressions::Expression const & getLowerBound(unsigned i=0) const
FragmentSpecification & setRewardAccumulationAllowed(bool newValue)
FragmentSpecification & setTimeBoundedUntilFormulasAllowed(bool newValue)
FragmentSpecification & setTotalRewardFormulasAllowed(bool newValue)
FragmentSpecification & setReachabilityRewardFormulasAllowed(bool newValue)
FragmentSpecification & setLongRunAverageRewardFormulasAllowed(bool newValue)
FragmentSpecification & setLongRunAverageProbabilitiesAllowed(bool newValue)
FragmentSpecification & setRewardOperatorsAllowed(bool newValue)
FragmentSpecification & setInstantaneousFormulasAllowed(bool newValue)
FragmentSpecification & setTimeAllowed(bool newValue)
const ap_to_formula_map & getAPMapping() const
std::shared_ptr< storm::automata::DeterministicAutomaton > readAutomaton() const
Formula const & getSubformula() const
virtual std::unique_ptr< CheckResult > check(Environment const &env, CheckTask< storm::logic::Formula, SolutionType > const &checkTask)
bool isOptimizationDirectionSet() const
Retrieves whether an optimization direction was set.
Definition CheckTask.h:149
bool isQualitativeSet() const
Retrieves whether the computation only needs to be performed qualitatively, because the values will o...
Definition CheckTask.h:259
FormulaType const & getFormula() const
Retrieves the formula from this task.
Definition CheckTask.h:142
bool isProduceSchedulersSet() const
Retrieves whether scheduler(s) are to be produced (if supported).
Definition CheckTask.h:281
storm::OptimizationDirection const & getOptimizationDirection() const
Retrieves the optimization direction (if set).
Definition CheckTask.h:156
bool isOnlyInitialStatesRelevantSet() const
Retrieves whether only the initial states are relevant in the computation.
Definition CheckTask.h:206
UncertaintyResolutionMode getUncertaintyResolutionMode() const
Retrieves the mode which decides how the uncertainty will be resolved.
Definition CheckTask.h:306
virtual std::unique_ptr< CheckResult > computeBoundedUntilProbabilities(Environment const &env, CheckTask< storm::logic::BoundedUntilFormula, ValueType > const &checkTask) override
static bool canHandleStatic(CheckTask< storm::logic::Formula, ValueType > const &checkTask, bool *requiresSingleInitialState=nullptr)
Returns false, if this task can certainly not be handled by this model checker (independent of the co...
virtual std::unique_ptr< CheckResult > computeUntilProbabilities(Environment const &env, CheckTask< storm::logic::UntilFormula, ValueType > const &checkTask) override
virtual std::unique_ptr< CheckResult > computeLTLProbabilities(Environment const &env, CheckTask< storm::logic::PathFormula, ValueType > const &checkTask) override
virtual std::unique_ptr< CheckResult > computeLongRunAverageProbabilities(Environment const &env, CheckTask< storm::logic::StateFormula, ValueType > const &checkTask) override
virtual std::unique_ptr< CheckResult > checkMultiObjectiveFormula(Environment const &env, CheckTask< storm::logic::MultiObjectiveFormula, ValueType > const &checkTask) override
SparseMarkovAutomatonCslModelChecker(SparseMarkovAutomatonModelType const &model)
virtual bool canHandle(CheckTask< storm::logic::Formula, ValueType > const &checkTask) const override
virtual std::unique_ptr< CheckResult > computeGloballyProbabilities(Environment const &env, CheckTask< storm::logic::GloballyFormula, ValueType > const &checkTask) override
virtual std::unique_ptr< CheckResult > computeTotalRewards(Environment const &env, CheckTask< storm::logic::TotalRewardFormula, ValueType > const &checkTask) override
virtual std::unique_ptr< CheckResult > computeNextProbabilities(Environment const &env, CheckTask< storm::logic::NextFormula, ValueType > const &checkTask) override
virtual std::unique_ptr< CheckResult > computeHOAPathProbabilities(Environment const &env, CheckTask< storm::logic::HOAPathFormula, ValueType > const &checkTask) override
virtual std::unique_ptr< CheckResult > computeLongRunAverageRewards(Environment const &env, CheckTask< storm::logic::LongRunAverageRewardFormula, ValueType > const &checkTask) override
virtual std::unique_ptr< CheckResult > computeReachabilityTimes(Environment const &env, CheckTask< storm::logic::EventuallyFormula, ValueType > const &checkTask) override
virtual std::unique_ptr< CheckResult > computeReachabilityRewards(Environment const &env, CheckTask< storm::logic::EventuallyFormula, ValueType > const &checkTask) override
Helper class for LTL model checking.
static MDPSparseModelCheckingHelperReturnType< ValueType > computeTotalRewards(Environment const &env, OptimizationDirection dir, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::SparseMatrix< ValueType > const &backwardTransitions, std::vector< ValueType > const &exitRateVector, storm::storage::BitVector const &markovianStates, RewardModelType const &rewardModel, bool produceScheduler)
static MDPSparseModelCheckingHelperReturnType< ValueType > computeReachabilityRewards(Environment const &env, OptimizationDirection dir, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::SparseMatrix< ValueType > const &backwardTransitions, std::vector< ValueType > const &exitRateVector, storm::storage::BitVector const &markovianStates, RewardModelType const &rewardModel, storm::storage::BitVector const &psiStates, bool produceScheduler)
static MDPSparseModelCheckingHelperReturnType< ValueType > computeUntilProbabilities(Environment const &env, OptimizationDirection dir, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::SparseMatrix< ValueType > const &backwardTransitions, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates, bool qualitative, bool produceScheduler)
static MDPSparseModelCheckingHelperReturnType< ValueType > computeReachabilityTimes(Environment const &env, OptimizationDirection dir, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::SparseMatrix< ValueType > const &backwardTransitions, std::vector< ValueType > const &exitRateVector, storm::storage::BitVector const &markovianStates, storm::storage::BitVector const &psiStates, bool produceScheduler)
static std::vector< ValueType > computeBoundedUntilProbabilities(Environment const &env, storm::solver::SolveGoal< ValueType > &&goal, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, std::vector< ValueType > const &exitRateVector, storm::storage::BitVector const &markovianStates, storm::storage::BitVector const &phiStates, storm::storage::BitVector const &psiStates, std::pair< double, double > const &boundsPair)
static MDPSparseModelCheckingHelperReturnType< SolutionType > computeGloballyProbabilities(Environment const &env, storm::solver::SolveGoal< ValueType, SolutionType > &&goal, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::SparseMatrix< ValueType > const &backwardTransitions, storm::storage::BitVector const &psiStates, bool qualitative, bool produceScheduler, bool useMecBasedTechnique=false)
static std::vector< SolutionType > computeNextProbabilities(Environment const &env, OptimizationDirection dir, UncertaintyResolutionMode uncertaintyResolutionMode, storm::storage::SparseMatrix< ValueType > const &transitionMatrix, storm::storage::BitVector const &nextStates)
Helper class for model checking queries that depend on the long run behavior of the (nondeterministic...
This class defines which action is chosen in a particular state of a non-deterministic model.
Definition Scheduler.h:18
#define STORM_LOG_THROW(cond, exception, message)
Definition macros.h:30
FragmentSpecification csrlstar()
FragmentSpecification multiObjective()
void setInformationFromCheckTaskNondeterministic(HelperType &helper, storm::modelchecker::CheckTask< FormulaType, typename ModelType::ValueType > const &checkTask, ModelType const &model)
Forwards relevant information stored in the given CheckTask to the given helper.
std::unique_ptr< CheckResult > performMultiObjectiveModelChecking(Environment const &env, SparseModelType const &model, storm::logic::MultiObjectiveFormula const &formula, bool produceScheduler)
FilteredRewardModel< RewardModelType > createFilteredRewardModel(RewardModelType const &baseRewardModel, storm::logic::RewardAccumulation const &acc, bool isDiscreteTimeModel)
ValueType infinity()
Definition constants.cpp:29
static const bool SupportsExponential