You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
108 lines
4.2 KiB
108 lines
4.2 KiB
#include "src/storage/gspn/Marking.h"
|
|
|
|
namespace storm {
|
|
namespace gspn {
|
|
Marking::Marking(uint_fast64_t numberOfPlaces, uint_fast64_t maxNumberOfTokens) {
|
|
this->numberOfPlaces = numberOfPlaces;
|
|
this->maxNumberOfTokens = maxNumberOfTokens;
|
|
|
|
this->numberOfBits = calculateNumberOfBits(maxNumberOfTokens);
|
|
this->marking = storm::storage::BitVector(numberOfBits * numberOfPlaces);
|
|
}
|
|
|
|
uint_fast64_t Marking::getNumberOfPlaces() {
|
|
return this->numberOfPlaces;
|
|
}
|
|
|
|
uint_fast64_t Marking::getMaxNumberOfTokens() {
|
|
return this->maxNumberOfTokens;
|
|
}
|
|
|
|
void Marking::setNumberOfTokensAt(uint_fast64_t place, uint_fast64_t numberOfTokens) {
|
|
// TODO check range (place < getNumberOfPlaces(), numberOfTokens < getMaxNumberOfTokens())
|
|
for (uint_fast64_t i = place * numberOfBits; i <(place * numberOfBits) + numberOfBits; ++i) {
|
|
if (numberOfTokens % 2 == 0) {
|
|
marking.set(i, false);
|
|
} else {
|
|
marking.set(i, true);
|
|
}
|
|
numberOfTokens /= 2;
|
|
}
|
|
}
|
|
|
|
uint_fast64_t Marking::getNumberOfTokensAt(uint_fast64_t place) {
|
|
uint_fast64_t tokens = 0;
|
|
for (uint_fast64_t i = place * numberOfBits, mult = 0; i < (place * numberOfBits) + numberOfBits; ++i, ++mult) {
|
|
if (marking.get(i)) {
|
|
tokens += std::pow(2, mult);
|
|
}
|
|
}
|
|
return tokens;
|
|
}
|
|
|
|
bool Marking::setNumberOfPlaces(uint_fast64_t numberOfPlaces) {
|
|
if (numberOfPlaces == this->numberOfPlaces) {
|
|
return true;
|
|
}
|
|
if (numberOfPlaces > this->numberOfPlaces) {
|
|
marking.resize(numberOfPlaces * numberOfBits);
|
|
return true;
|
|
} else {
|
|
auto diff = this->numberOfPlaces - numberOfPlaces;
|
|
for (uint64_t i = 0; i < diff; ++i) {
|
|
if (getNumberOfTokensAt(numberOfPlaces-1-i) != 0) {
|
|
// TODO error
|
|
return false;
|
|
}
|
|
}
|
|
marking.resize(numberOfPlaces * numberOfBits);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
bool Marking::setMaxNumberOfTokens(uint_fast64_t maxNumberOfTokens) {
|
|
for (uint64_t i = 0; i < getNumberOfPlaces(); ++i) {
|
|
if (getNumberOfTokensAt(i) > maxNumberOfTokens) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (maxNumberOfTokens == getMaxNumberOfTokens()) {
|
|
return true;
|
|
}
|
|
|
|
uint_fast64_t newNumberOfBits = calculateNumberOfBits(maxNumberOfTokens);
|
|
if (maxNumberOfTokens < getMaxNumberOfTokens()) {
|
|
for (uint_fast64_t i = 0; i < getNumberOfPlaces(); ++i) {
|
|
for (uint_fast64_t j = 0; j < numberOfBits; ++j) {
|
|
marking.set(i*newNumberOfBits + j , marking.get(i*numberOfBits + j));
|
|
}
|
|
}
|
|
marking.resize(getNumberOfPlaces() * newNumberOfBits);
|
|
} else {
|
|
marking.resize(getNumberOfPlaces() * newNumberOfBits);
|
|
for (int_fast64_t i = getNumberOfPlaces()-1; i >= 0; --i) {
|
|
for (int_fast64_t j = numberOfBits-1; j >= 0; --j) {
|
|
for (uint_fast64_t diff = 0; diff < newNumberOfBits-numberOfBits; ++diff) {
|
|
marking.set(i*newNumberOfBits+j+diff+1, 0);
|
|
}
|
|
marking.set(i*newNumberOfBits+j, marking.get(i*numberOfBits+j));
|
|
}
|
|
}
|
|
}
|
|
numberOfBits = newNumberOfBits;
|
|
return true;
|
|
}
|
|
|
|
void Marking::incNumberOfPlaces() {
|
|
setNumberOfPlaces(getNumberOfPlaces()+1);
|
|
}
|
|
|
|
uint_fast64_t Marking::calculateNumberOfBits(uint_fast64_t maxNumber) {
|
|
if (maxNumber == 0) {
|
|
return 1;
|
|
}
|
|
return std::floor(std::log2(maxNumber)) + 1;
|
|
}
|
|
}
|
|
}
|