11namespace modelchecker {
15template<
typename ValueType,
bool Nondeterministic>
16const uint_fast64_t SparseLTLSchedulerHelper<ValueType, Nondeterministic>::DEFAULT_INFSET = 0;
18template<
typename ValueType,
bool Nondeterministic>
19uint_fast64_t SparseLTLSchedulerHelper<ValueType, Nondeterministic>::InfSetPool::getOrCreateIndex(
storm::storage::BitVector&& infSet) {
20 auto it = std::find(_storage.begin(), _storage.end(), infSet);
21 if (it == _storage.end()) {
22 _storage.push_back(std::move(infSet));
23 return _storage.size() - 1;
25 return distance(_storage.begin(), it);
29template<
typename ValueType,
bool Nondeterministic>
30storm::storage::BitVector const& SparseLTLSchedulerHelper<ValueType, Nondeterministic>::InfSetPool::get(uint_fast64_t index)
const {
31 STORM_LOG_ASSERT(index < size(),
"inf set index " << index <<
" is invalid.");
32 return _storage[index];
35template<
typename ValueType,
bool Nondeterministic>
36uint_fast64_t SparseLTLSchedulerHelper<ValueType, Nondeterministic>::InfSetPool::size()
const {
37 return _storage.size();
40template<
typename ValueType,
bool Nondeterministic>
42 : _randomScheduler(false), _accInfSets(numProductStates,
boost::none) {
46template<
typename ValueType,
bool Nondeterministic>
48 return (daState * _infSets.size()) + infSet;
51template<
typename ValueType,
bool Nondeterministic>
52void SparseLTLSchedulerHelper<ValueType, Nondeterministic>::SparseLTLSchedulerHelper::setRandom() {
53 this->_randomScheduler =
true;
56template<
typename ValueType,
bool Nondeterministic>
62 [&containingMec](
auto const& accStateChoicesPair) { return containingMec.containsState(accStateChoicesPair.first); }),
63 "All states in the acceptingEC must be contained in the containing mec.");
65 for (
auto const& [state, _] : acceptingEc) {
66 acceptingEcStates.
set(state);
70 if (acceptingEc.
size() < containingMec.
size()) {
72 for (
auto const& [state, _] : containingMec) {
73 if (!acceptingEcStates.
get(state)) {
74 remainingMecStates.
set(state);
79 storm::utility::graph::computeSchedulerProb1E<ValueType>(remainingMecStates, product->
getProductModel().getTransitionMatrix(),
80 product->
getProductModel().getBackwardTransitions(), remainingMecStates, acceptingEcStates,
84 for (
auto pState : remainingMecStates) {
85 this->_producedChoices.insert(
91 std::set<uint_fast64_t> infSetIds;
92 for (
auto const& literal : conjunction) {
93 if (literal->isAtom()) {
94 const cpphoafparser::AtomAcceptance& atom = literal->getAtom();
95 if (atom.getType() == cpphoafparser::AtomAcceptance::TEMPORAL_INF) {
97 if (atom.isNegated()) {
98 infSet = ~acceptance.getAcceptanceSet(atom.getAcceptanceSet());
103 infSetIds.insert(_infSets.getOrCreateIndex(std::move(infSet)));
110 if (infSetIds.empty()) {
116 for (
auto const& mecState : acceptingEcStates) {
117 STORM_LOG_ASSERT(!_accInfSets[mecState].is_initialized(),
"accepting inf sets were already defined for a MEC state which is not expected.");
118 _accInfSets[mecState].emplace(infSetIds);
123 for (uint_fast64_t
id : infSetIds) {
129 storm::utility::graph::computeSchedulerProb1E<ValueType>(acceptingEcStates, product->
getProductModel().getTransitionMatrix(),
130 product->
getProductModel().getBackwardTransitions(), acceptingEcStates, infStatesWithinMec,
134 for (
auto pState : infStatesWithinMec) {
141 for (
auto pState : acceptingEcStates) {
143 this->_producedChoices.insert(
149template<
typename ValueType,
bool Nondeterministic>
156 STORM_LOG_ASSERT(_infSets.size() > 0,
"There is no inf set. Were the accepting ECs processed before?");
159 uint64_t numMemoryStates = (numDaStates) * (_infSets.size());
167 for (uint_fast64_t infSet = 0; infSet < _infSets.size(); ++infSet) {
168 _dontCareStates[getMemoryState(automatonState, infSet)].set(modelState,
true);
172 if (acceptingProductStates.
get(pState)) {
175 for (uint_fast64_t infSet = 0; infSet < _infSets.size(); ++infSet) {
184 this->_accInfSets[pState] = std::set<uint_fast64_t>({DEFAULT_INFSET});
185 if (reachScheduler->isDontCare(pState)) {
191 reachScheduler->getChoice(pState)});
194 static_assert(DEFAULT_INFSET == 0,
"This code assumes that the default infset is 0");
195 for (uint_fast64_t infSet = 1; infSet < _infSets.size(); ++infSet) {
206 _memoryTransitions = std::vector<std::vector<storm::storage::BitVector>>(
210 uint_fast64_t automatonTo = productBuilder.
getSuccessor(automatonFrom, modelState);
215 "The list of InfSets for the product state <" << modelState <<
", " << automatonTo <<
"> is undefined.");
216 std::set<uint_fast64_t>
const& daProductStateInfSets = _accInfSets[daProductState].get();
221 for (uint_fast64_t currentInfSet = 0; currentInfSet < _infSets.size(); ++currentInfSet) {
222 uint_fast64_t newInfSet;
224 if (daProductStateInfSets.count(currentInfSet) == 0) {
226 newInfSet = *daProductStateInfSets.begin();
227 }
else if (daProductStateInfSets.size() > 1 && (_infSets.get(currentInfSet).get(daProductState))) {
231 auto nextInfSetIt = daProductStateInfSets.find(currentInfSet);
232 STORM_LOG_ASSERT(nextInfSetIt != daProductStateInfSets.end(),
"The list of InfSets for the product state <"
233 << modelState <<
", " << automatonTo
234 <<
"> does not contain the infSet " << currentInfSet);
236 if (nextInfSetIt == daProductStateInfSets.end()) {
238 nextInfSetIt = daProductStateInfSets.begin();
240 newInfSet = *nextInfSetIt;
243 newInfSet = currentInfSet;
245 _memoryTransitions[getMemoryState(automatonFrom, currentInfSet)][getMemoryState(automatonTo, newInfSet)].set(modelState);
253 this->_memoryInitialStates = std::vector<uint_fast64_t>(transitionMatrix.
getRowGroupCount());
258 "The memory successor state for the model state " << modelState <<
"does not exist in the DA-Model Product.");
260 "The list of InfSets for the product state <" << modelState <<
", " << automatonState <<
"> is undefined.");
262 auto infSet = _accInfSets[product->
getProductStateIndex(modelState, automatonState)].get().begin();
263 _memoryInitialStates[modelState] = getMemoryState(automatonState, *infSet);
267template<
typename ValueType,
bool Nondeterministic>
270 if (_randomScheduler) {
273 scheduler.setChoice(0, state);
287 memoryBuilder.setTransition(startState, goalState, this->_memoryTransitions[startState][goalState]);
292 if (onlyInitialStatesRelevant) {
294 for (uint_fast64_t modelState : model.getInitialStates()) {
295 memoryBuilder.setInitialMemoryState(modelState, this->_memoryInitialStates[modelState]);
299 for (uint_fast64_t modelState = 0; modelState < model.
getNumberOfStates(); ++modelState) {
300 memoryBuilder.setInitialMemoryState(modelState, this->_memoryInitialStates[modelState]);
311 for (
const auto& choice : this->_producedChoices) {
315 uint_fast64_t infSet = std::get<2>(choice.first);
316 STORM_LOG_ASSERT(!this->_dontCareStates[getMemoryState(daState, infSet)].get(modelState),
"Tried to set choice for dontCare state.");
317 scheduler.setChoice(choice.second, modelState, getMemoryState(daState, infSet));
321 for (uint_fast64_t memoryState = 0; memoryState < this->_dontCareStates.size(); ++memoryState) {
322 for (
auto state : this->_dontCareStates[memoryState]) {
323 scheduler.setDontCare(state, memoryState);
328 STORM_LOG_ASSERT(scheduler.isDeterministicScheduler(),
"Expected a deterministic scheduler");
329 STORM_LOG_ASSERT(!scheduler.isPartialScheduler(),
"Expected a fully defined scheduler");
334template class SparseLTLSchedulerHelper<double, false>;
335template class SparseLTLSchedulerHelper<double, true>;
337#ifdef STORM_HAVE_CARL
338template class SparseLTLSchedulerHelper<storm::RationalNumber, false>;
339template class SparseLTLSchedulerHelper<storm::RationalNumber, true>;
340template class SparseLTLSchedulerHelper<storm::RationalFunction, false>;
storm::storage::BitVector & getAcceptanceSet(unsigned int index)
Helper class for scheduler construction in LTL model checking.
void saveProductEcChoices(automata::AcceptanceCondition const &acceptance, storm::storage::MaximalEndComponent const &acceptingEC, storm::storage::MaximalEndComponent const &containingMEC, std::vector< automata::AcceptanceCondition::acceptance_expr::ptr > const &conjunction, typename transformer::DAProduct< productModelType >::ptr product)
Save choices for states in the accepting end component of the DA-Model product and for the states in ...
void prepareScheduler(uint_fast64_t numDaStates, storm::storage::BitVector const &acceptingProductStates, std::unique_ptr< storm::storage::Scheduler< ValueType > > reachScheduler, transformer::DAProductBuilder const &productBuilder, typename transformer::DAProduct< productModelType >::ptr product, storm::storage::BitVector const &modelStatesOfInterest, storm::storage::SparseMatrix< ValueType > const &transitionMatrix)
Extracts scheduler choices and creates the memory structure for the LTL-Scheduler.
SparseLTLSchedulerHelper(uint_fast64_t numProductStates)
Initializes the helper.
Base class for all sparse models.
virtual uint_fast64_t getNumberOfStates() const override
Returns the number of states of the model.
A bit vector that is internally represented as a vector of 64-bit values.
void set(uint_fast64_t index, bool value=true)
Sets the given truth value at the given index.
bool get(uint_fast64_t index) const
Retrieves the truth value of the bit at the given index and performs a bound check.
This class represents a maximal end-component of a nondeterministic model.
iterator end()
Retrieves an iterator that points past the last state and its choices in the MEC.
set_type const & getChoicesForState(uint_fast64_t state) const
Retrieves the choices for the given state that are contained in this MEC under the assumption that th...
iterator begin()
Retrieves an iterator that points to the first state and its choices in the MEC.
This class represents a (deterministic) memory structure that can be used to encode certain events (s...
This class defines which action is chosen in a particular state of a non-deterministic model.
SchedulerChoice< ValueType > const & getChoice(uint_fast64_t modelState, uint_fast64_t memoryState=0) const
Gets the choice defined by the scheduler for the given model and memory state.
void setChoice(SchedulerChoice< ValueType > const &choice, uint_fast64_t modelState, uint_fast64_t memoryState=0)
Sets the choice defined by the scheduler for the given state.
A class that holds a possibly non-square matrix in the compressed row storage format.
index_type getRowGroupCount() const
Returns the number of row groups in the matrix.
#define STORM_LOG_ASSERT(cond, message)