Storm 1.14.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 std::optional<double> upperBound;
84 if (pathFormula.hasLowerBound()) {
85 lowerBound = pathFormula.getLowerBound<double>();
86 }
87 if (pathFormula.hasUpperBound()) {
88 upperBound = pathFormula.getNonStrictUpperBound<double>();
89 }
90
92 env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(), this->getModel().getExitRates(),
93 this->getModel().getMarkovianStates(), leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), std::make_pair(lowerBound, upperBound));
94 return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(result)));
95}
96
97template<typename SparseMarkovAutomatonModelType>
100 storm::logic::NextFormula const& pathFormula = checkTask.getFormula();
101 STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException,
102 "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
103 std::unique_ptr<CheckResult> subResultPointer = this->check(env, pathFormula.getSubformula());
104 ExplicitQualitativeCheckResult<ValueType> const& subResult = subResultPointer->template asExplicitQualitativeCheckResult<ValueType>();
106 env, checkTask.getOptimizationDirection(), checkTask.getUncertaintyResolutionMode(), this->getModel().getTransitionMatrix(),
107 subResult.getTruthValuesVector());
108 return std::unique_ptr<CheckResult>(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult)));
109}
110
111template<typename SparseMarkovAutomatonModelType>
114 storm::logic::GloballyFormula const& pathFormula = checkTask.getFormula();
115 STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException,
116 "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
117 std::unique_ptr<CheckResult> subResultPointer = this->check(env, pathFormula.getSubformula());
118 ExplicitQualitativeCheckResult<ValueType> const& subResult = subResultPointer->template asExplicitQualitativeCheckResult<ValueType>();
120 env, storm::solver::SolveGoal<ValueType>(this->getModel(), checkTask), this->getModel().getTransitionMatrix(),
121 this->getModel().getBackwardTransitions(), subResult.getTruthValuesVector(), checkTask.isQualitativeSet(), checkTask.isProduceSchedulersSet());
122 std::unique_ptr<CheckResult> result(new ExplicitQuantitativeCheckResult<ValueType>(std::move(ret.values)));
123 if (checkTask.isProduceSchedulersSet() && ret.scheduler) {
124 result->asExplicitQuantitativeCheckResult<ValueType>().setScheduler(std::move(ret.scheduler));
125 }
126 return result;
127}
128
129template<typename SparseMarkovAutomatonModelType>
132 storm::logic::UntilFormula const& pathFormula = checkTask.getFormula();
133 STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException,
134 "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
135 std::unique_ptr<CheckResult> leftResultPointer = this->check(env, pathFormula.getLeftSubformula());
136 std::unique_ptr<CheckResult> rightResultPointer = this->check(env, pathFormula.getRightSubformula());
137 ExplicitQualitativeCheckResult<ValueType>& leftResult = leftResultPointer->template asExplicitQualitativeCheckResult<ValueType>();
138 ExplicitQualitativeCheckResult<ValueType>& rightResult = rightResultPointer->template asExplicitQualitativeCheckResult<ValueType>();
139
141 env, checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(),
142 leftResult.getTruthValuesVector(), rightResult.getTruthValuesVector(), checkTask.isQualitativeSet(), checkTask.isProduceSchedulersSet());
143 std::unique_ptr<CheckResult> result(new ExplicitQuantitativeCheckResult<ValueType>(std::move(ret.values)));
144 if (checkTask.isProduceSchedulersSet() && ret.scheduler) {
145 result->asExplicitQuantitativeCheckResult<ValueType>().setScheduler(std::move(ret.scheduler));
146 }
147 return result;
148}
149
150template<typename SparseMarkovAutomatonModelType>
153 storm::logic::HOAPathFormula const& pathFormula = checkTask.getFormula();
154
157
158 auto formulaChecker = [&](storm::logic::Formula const& formula) {
159 return this->check(env, formula)->template asExplicitQualitativeCheckResult<ValueType>().getTruthValuesVector();
160 };
161 auto apSets = helper.computeApSets(pathFormula.getAPMapping(), formulaChecker);
162 std::vector<ValueType> numericResult = helper.computeDAProductProbabilities(env, *pathFormula.readAutomaton(), apSets);
163
164 std::unique_ptr<CheckResult> result(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult)));
165 if (checkTask.isProduceSchedulersSet()) {
166 result->asExplicitQuantitativeCheckResult<ValueType>().setScheduler(
167 std::make_unique<storm::storage::Scheduler<ValueType>>(helper.extractScheduler(this->getModel())));
168 }
169
170 return result;
171}
172
173template<typename SparseMarkovAutomatonModelType>
176 storm::logic::PathFormula const& pathFormula = checkTask.getFormula();
177
178 STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException,
179 "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
180
183
184 auto formulaChecker = [&](storm::logic::Formula const& formula) {
185 return this->check(env, formula)->template asExplicitQualitativeCheckResult<ValueType>().getTruthValuesVector();
186 };
187 std::vector<ValueType> numericResult = helper.computeLTLProbabilities(env, pathFormula, formulaChecker);
188
189 std::unique_ptr<CheckResult> result(new ExplicitQuantitativeCheckResult<ValueType>(std::move(numericResult)));
190 if (checkTask.isProduceSchedulersSet()) {
191 result->asExplicitQuantitativeCheckResult<ValueType>().setScheduler(
192 std::make_unique<storm::storage::Scheduler<ValueType>>(helper.extractScheduler(this->getModel())));
193 }
194
195 return result;
196}
197
198template<typename SparseMarkovAutomatonModelType>
201 storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula();
202 STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException,
203 "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
204 STORM_LOG_THROW(this->getModel().isClosed(), storm::exceptions::InvalidPropertyException,
205 "Unable to compute reachability rewards in non-closed Markov automaton.");
206 std::unique_ptr<CheckResult> subResultPointer = this->check(env, eventuallyFormula.getSubformula());
207 ExplicitQualitativeCheckResult<ValueType> const& subResult = subResultPointer->template asExplicitQualitativeCheckResult<ValueType>();
208 auto rewardModel = storm::utility::createFilteredRewardModel(this->getModel(), checkTask);
209
211 env, checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(),
212 this->getModel().getExitRates(), this->getModel().getMarkovianStates(), rewardModel.get(), subResult.getTruthValuesVector(),
213 checkTask.isProduceSchedulersSet());
214 std::unique_ptr<CheckResult> result(new ExplicitQuantitativeCheckResult<ValueType>(std::move(ret.values)));
215 if (checkTask.isProduceSchedulersSet() && ret.scheduler) {
216 result->asExplicitQuantitativeCheckResult<ValueType>().setScheduler(std::move(ret.scheduler));
217 }
218 return result;
219}
220
221template<typename SparseMarkovAutomatonModelType>
224 STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException,
225 "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
226 STORM_LOG_THROW(this->getModel().isClosed(), storm::exceptions::InvalidPropertyException,
227 "Unable to compute reachability rewards in non-closed Markov automaton.");
228 auto rewardModel = storm::utility::createFilteredRewardModel(this->getModel(), checkTask);
229
231 env, checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(),
232 this->getModel().getExitRates(), this->getModel().getMarkovianStates(), rewardModel.get(), checkTask.isProduceSchedulersSet());
233 std::unique_ptr<CheckResult> result(new ExplicitQuantitativeCheckResult<ValueType>(std::move(ret.values)));
234 if (checkTask.isProduceSchedulersSet() && ret.scheduler) {
235 result->asExplicitQuantitativeCheckResult<ValueType>().setScheduler(std::move(ret.scheduler));
236 }
237 return result;
238}
239
240template<typename SparseMarkovAutomatonModelType>
243 storm::logic::StateFormula const& stateFormula = checkTask.getFormula();
244 STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException,
245 "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
246 STORM_LOG_THROW(this->getModel().isClosed(), storm::exceptions::InvalidPropertyException,
247 "Unable to compute long-run average in non-closed Markov automaton.");
248 std::unique_ptr<CheckResult> subResultPointer = this->check(env, stateFormula);
249 ExplicitQualitativeCheckResult<ValueType> const& subResult = subResultPointer->template asExplicitQualitativeCheckResult<ValueType>();
250
252 this->getModel().getTransitionMatrix(), this->getModel().getMarkovianStates(), this->getModel().getExitRates());
254 auto values = helper.computeLongRunAverageProbabilities(env, subResult.getTruthValuesVector());
255
256 std::unique_ptr<CheckResult> result(new ExplicitQuantitativeCheckResult<ValueType>(std::move(values)));
257 if (checkTask.isProduceSchedulersSet()) {
258 result->asExplicitQuantitativeCheckResult<ValueType>().setScheduler(std::make_unique<storm::storage::Scheduler<ValueType>>(helper.extractScheduler()));
259 }
260 return result;
261}
262
263template<typename SparseMarkovAutomatonModelType>
266 STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException,
267 "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
268 STORM_LOG_THROW(this->getModel().isClosed(), storm::exceptions::InvalidPropertyException,
269 "Unable to compute long run average rewards in non-closed Markov automaton.");
270 auto rewardModel = storm::utility::createFilteredRewardModel(this->getModel(), checkTask);
271
273 this->getModel().getTransitionMatrix(), this->getModel().getMarkovianStates(), this->getModel().getExitRates());
275 auto values = helper.computeLongRunAverageRewards(env, rewardModel.get());
276
277 std::unique_ptr<CheckResult> result(new ExplicitQuantitativeCheckResult<ValueType>(std::move(values)));
278 if (checkTask.isProduceSchedulersSet()) {
279 result->asExplicitQuantitativeCheckResult<ValueType>().setScheduler(std::make_unique<storm::storage::Scheduler<ValueType>>(helper.extractScheduler()));
280 }
281 return result;
282}
283
284template<typename SparseMarkovAutomatonModelType>
287 storm::logic::EventuallyFormula const& eventuallyFormula = checkTask.getFormula();
288 STORM_LOG_THROW(checkTask.isOptimizationDirectionSet(), storm::exceptions::InvalidPropertyException,
289 "Formula needs to specify whether minimal or maximal values are to be computed on nondeterministic model.");
290 STORM_LOG_THROW(this->getModel().isClosed(), storm::exceptions::InvalidPropertyException,
291 "Unable to compute expected times in non-closed Markov automaton.");
292 std::unique_ptr<CheckResult> subResultPointer = this->check(env, eventuallyFormula.getSubformula());
293 ExplicitQualitativeCheckResult<ValueType>& subResult = subResultPointer->template asExplicitQualitativeCheckResult<ValueType>();
294
296 env, checkTask.getOptimizationDirection(), this->getModel().getTransitionMatrix(), this->getModel().getBackwardTransitions(),
297 this->getModel().getExitRates(), this->getModel().getMarkovianStates(), subResult.getTruthValuesVector(), checkTask.isProduceSchedulersSet());
298 std::unique_ptr<CheckResult> result(new ExplicitQuantitativeCheckResult<ValueType>(std::move(ret.values)));
299 if (checkTask.isProduceSchedulersSet() && ret.scheduler) {
300 result->asExplicitQuantitativeCheckResult<ValueType>().setScheduler(std::move(ret.scheduler));
301 }
302 return result;
303}
304
305template<typename SparseMarkovAutomatonModelType>
310
313} // namespace modelchecker
314} // 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:148
bool isQualitativeSet() const
Retrieves whether the computation only needs to be performed qualitatively, because the values will o...
Definition CheckTask.h:258
FormulaType const & getFormula() const
Retrieves the formula from this task.
Definition CheckTask.h:141
bool isProduceSchedulersSet() const
Retrieves whether scheduler(s) are to be produced (if supported).
Definition CheckTask.h:280
storm::OptimizationDirection const & getOptimizationDirection() const
Retrieves the optimization direction (if set).
Definition CheckTask.h:155
bool isOnlyInitialStatesRelevantSet() const
Retrieves whether only the initial states are relevant in the computation.
Definition CheckTask.h:205
UncertaintyResolutionMode getUncertaintyResolutionMode() const
Retrieves the mode which decides how the uncertainty will be resolved.
Definition CheckTask.h:305
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 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, std::optional< double > > const &boundsPair)
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 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:28
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)
static const bool SupportsExponential