12namespace modelchecker {
16template<
typename ValueType,
bool Nondeterministic>
17const uint_fast64_t SparseLTLSchedulerHelper<ValueType, Nondeterministic>::DEFAULT_INFSET = 0;
19template<
typename ValueType,
bool Nondeterministic>
20uint_fast64_t SparseLTLSchedulerHelper<ValueType, Nondeterministic>::InfSetPool::getOrCreateIndex(
storm::storage::BitVector&& infSet) {
21 auto it = std::find(_storage.begin(), _storage.end(), infSet);
22 if (it == _storage.end()) {
23 _storage.push_back(std::move(infSet));
24 return _storage.size() - 1;
26 return distance(_storage.begin(), it);
30template<
typename ValueType,
bool Nondeterministic>
31storm::storage::BitVector const& SparseLTLSchedulerHelper<ValueType, Nondeterministic>::InfSetPool::get(uint_fast64_t index)
const {
32 STORM_LOG_ASSERT(index < size(),
"inf set index " << index <<
" is invalid.");
33 return _storage[index];
36template<
typename ValueType,
bool Nondeterministic>
37uint_fast64_t SparseLTLSchedulerHelper<ValueType, Nondeterministic>::InfSetPool::size()
const {
38 return _storage.size();
41template<
typename ValueType,
bool Nondeterministic>
43 : _randomScheduler(false), _accInfSets(numProductStates,
boost::none) {
47template<
typename ValueType,
bool Nondeterministic>
49 return (daState * _infSets.size()) + infSet;
52template<
typename ValueType,
bool Nondeterministic>
53void SparseLTLSchedulerHelper<ValueType, Nondeterministic>::SparseLTLSchedulerHelper::setRandom() {
54 this->_randomScheduler =
true;
57template<
typename ValueType,
bool Nondeterministic>
63 [&containingMec](
auto const& accStateChoicesPair) { return containingMec.containsState(accStateChoicesPair.first); }),
64 "All states in the acceptingEC must be contained in the containing mec.");
66 for (
auto const& [state, _] : acceptingEc) {
67 acceptingEcStates.
set(state);
71 if (acceptingEc.
size() < containingMec.
size()) {
73 for (
auto const& [state, _] : containingMec) {
74 if (!acceptingEcStates.
get(state)) {
75 remainingMecStates.
set(state);
80 storm::utility::graph::computeSchedulerProb1E<ValueType>(remainingMecStates, product->
getProductModel().getTransitionMatrix(),
81 product->
getProductModel().getBackwardTransitions(), remainingMecStates, acceptingEcStates,
85 for (
auto pState : remainingMecStates) {
86 this->_producedChoices.insert(
92 std::set<uint_fast64_t> infSetIds;
93 for (
auto const& literal : conjunction) {
94 if (literal->isAtom()) {
95 const cpphoafparser::AtomAcceptance& atom = literal->getAtom();
96 if (atom.getType() == cpphoafparser::AtomAcceptance::TEMPORAL_INF) {
98 if (atom.isNegated()) {
99 infSet = ~acceptance.getAcceptanceSet(atom.getAcceptanceSet());
104 infSetIds.insert(_infSets.getOrCreateIndex(std::move(infSet)));
111 if (infSetIds.empty()) {
117 for (
auto const& mecState : acceptingEcStates) {
118 STORM_LOG_ASSERT(!_accInfSets[mecState].is_initialized(),
"accepting inf sets were already defined for a MEC state which is not expected.");
119 _accInfSets[mecState].emplace(infSetIds);
124 for (uint_fast64_t
id : infSetIds) {
130 storm::utility::graph::computeSchedulerProb1E<ValueType>(acceptingEcStates, product->
getProductModel().getTransitionMatrix(),
131 product->
getProductModel().getBackwardTransitions(), acceptingEcStates, infStatesWithinMec,
135 for (
auto pState : infStatesWithinMec) {
142 for (
auto pState : acceptingEcStates) {
144 this->_producedChoices.insert(
150template<
typename ValueType,
bool Nondeterministic>
157 STORM_LOG_ASSERT(_infSets.size() > 0,
"There is no inf set. Were the accepting ECs processed before?");
160 uint64_t numMemoryStates = (numDaStates) * (_infSets.size());
168 for (uint_fast64_t infSet = 0; infSet < _infSets.size(); ++infSet) {
169 _dontCareStates[getMemoryState(automatonState, infSet)].set(modelState,
true);
173 if (acceptingProductStates.
get(pState)) {
176 for (uint_fast64_t infSet = 0; infSet < _infSets.size(); ++infSet) {
185 this->_accInfSets[pState] = std::set<uint_fast64_t>({DEFAULT_INFSET});
186 if (reachScheduler->isDontCare(pState)) {
192 reachScheduler->getChoice(pState)});
195 static_assert(DEFAULT_INFSET == 0,
"This code assumes that the default infset is 0");
196 for (uint_fast64_t infSet = 1; infSet < _infSets.size(); ++infSet) {
207 _memoryTransitions = std::vector<std::vector<storm::storage::BitVector>>(
211 uint_fast64_t automatonTo = productBuilder.
getSuccessor(automatonFrom, modelState);
216 "The list of InfSets for the product state <" << modelState <<
", " << automatonTo <<
"> is undefined.");
217 std::set<uint_fast64_t>
const& daProductStateInfSets = _accInfSets[daProductState].get();
222 for (uint_fast64_t currentInfSet = 0; currentInfSet < _infSets.size(); ++currentInfSet) {
223 uint_fast64_t newInfSet;
225 if (daProductStateInfSets.count(currentInfSet) == 0) {
227 newInfSet = *daProductStateInfSets.begin();
228 }
else if (daProductStateInfSets.size() > 1 && (_infSets.get(currentInfSet).get(daProductState))) {
232 auto nextInfSetIt = daProductStateInfSets.find(currentInfSet);
233 STORM_LOG_ASSERT(nextInfSetIt != daProductStateInfSets.end(),
"The list of InfSets for the product state <"
234 << modelState <<
", " << automatonTo
235 <<
"> does not contain the infSet " << currentInfSet);
237 if (nextInfSetIt == daProductStateInfSets.end()) {
239 nextInfSetIt = daProductStateInfSets.begin();
241 newInfSet = *nextInfSetIt;
244 newInfSet = currentInfSet;
246 _memoryTransitions[getMemoryState(automatonFrom, currentInfSet)][getMemoryState(automatonTo, newInfSet)].set(modelState);
254 this->_memoryInitialStates = std::vector<uint_fast64_t>(transitionMatrix.
getRowGroupCount());
259 "The memory successor state for the model state " << modelState <<
"does not exist in the DA-Model Product.");
261 "The list of InfSets for the product state <" << modelState <<
", " << automatonState <<
"> is undefined.");
263 auto infSet = _accInfSets[product->
getProductStateIndex(modelState, automatonState)].get().begin();
264 _memoryInitialStates[modelState] = getMemoryState(automatonState, *infSet);
268template<
typename ValueType,
bool Nondeterministic>
271 if (_randomScheduler) {
274 scheduler.setChoice(0, state);
288 memoryBuilder.setTransition(startState, goalState, this->_memoryTransitions[startState][goalState]);
293 if (onlyInitialStatesRelevant) {
295 for (uint_fast64_t modelState : model.getInitialStates()) {
296 memoryBuilder.setInitialMemoryState(modelState, this->_memoryInitialStates[modelState]);
300 for (uint_fast64_t modelState = 0; modelState < model.
getNumberOfStates(); ++modelState) {
301 memoryBuilder.setInitialMemoryState(modelState, this->_memoryInitialStates[modelState]);
312 for (
const auto& choice : this->_producedChoices) {
316 uint_fast64_t infSet = std::get<2>(choice.first);
317 STORM_LOG_ASSERT(!this->_dontCareStates[getMemoryState(daState, infSet)].get(modelState),
"Tried to set choice for dontCare state.");
318 scheduler.setChoice(choice.second, modelState, getMemoryState(daState, infSet));
322 for (uint_fast64_t memoryState = 0; memoryState < this->_dontCareStates.size(); ++memoryState) {
323 for (
auto state : this->_dontCareStates[memoryState]) {
324 scheduler.setDontCare(state, memoryState);
329 STORM_LOG_ASSERT(scheduler.isDeterministicScheduler(),
"Expected a deterministic scheduler");
330 STORM_LOG_ASSERT(!scheduler.isPartialScheduler(),
"Expected a fully defined scheduler");
335template class SparseLTLSchedulerHelper<double, false>;
336template class SparseLTLSchedulerHelper<double, true>;
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(uint64_t index, bool value=true)
Sets the given truth value at the given index.
bool get(uint64_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)