|  | @ -10,6 +10,12 @@ | 
		
	
		
			
				|  |  | #include "src/utility/Hash.h"
 |  |  | #include "src/utility/Hash.h"
 | 
		
	
		
			
				|  |  | #include "src/utility/macros.h"
 |  |  | #include "src/utility/macros.h"
 | 
		
	
		
			
				|  |  | 
 |  |  | 
 | 
		
	
		
			
				|  |  |  |  |  | #include <bitset>
 | 
		
	
		
			
				|  |  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |  | #ifndef NDEBUG
 | 
		
	
		
			
				|  |  |  |  |  | //#define ASSERT_BITVECTOR
 | 
		
	
		
			
				|  |  |  |  |  | #endif
 | 
		
	
		
			
				|  |  |  |  |  | 
 | 
		
	
		
			
				|  |  | namespace storm { |  |  | namespace storm { | 
		
	
		
			
				|  |  |     namespace storage { |  |  |     namespace storage { | 
		
	
		
			
				|  |  | 
 |  |  | 
 | 
		
	
	
		
			
				|  | @ -413,6 +419,7 @@ namespace storm { | 
		
	
		
			
				|  |  |         } |  |  |         } | 
		
	
		
			
				|  |  | 
 |  |  | 
 | 
		
	
		
			
				|  |  |         uint_fast64_t BitVector::getAsInt(uint_fast64_t bitIndex, uint_fast64_t numberOfBits) const { |  |  |         uint_fast64_t BitVector::getAsInt(uint_fast64_t bitIndex, uint_fast64_t numberOfBits) const { | 
		
	
		
			
				|  |  |  |  |  |             assert(numberOfBits <= 64); | 
		
	
		
			
				|  |  |             uint64_t bucket = bitIndex >> 6; |  |  |             uint64_t bucket = bitIndex >> 6; | 
		
	
		
			
				|  |  |             uint64_t bitIndexInBucket = bitIndex & mod64mask; |  |  |             uint64_t bitIndexInBucket = bitIndex & mod64mask; | 
		
	
		
			
				|  |  | 
 |  |  | 
 | 
		
	
	
		
			
				|  | @ -663,6 +670,103 @@ namespace storm { | 
		
	
		
			
				|  |  |             return endIndex; |  |  |             return endIndex; | 
		
	
		
			
				|  |  |         } |  |  |         } | 
		
	
		
			
				|  |  |          |  |  |          | 
		
	
		
			
				|  |  |  |  |  |         BitVector BitVector::getAsBitVector(uint_fast64_t start, uint_fast64_t length) { | 
		
	
		
			
				|  |  |  |  |  |             BitVector result(length); | 
		
	
		
			
				|  |  |  |  |  |              | 
		
	
		
			
				|  |  |  |  |  |             uint_fast64_t index = 0; | 
		
	
		
			
				|  |  |  |  |  |             for ( ; index + 63 <= length; index += 63) { | 
		
	
		
			
				|  |  |  |  |  |                 result.setFromInt(index, 63, getAsInt(start + index, 63)); | 
		
	
		
			
				|  |  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |  |             // Insert remaining bits
 | 
		
	
		
			
				|  |  |  |  |  |             result.setFromInt(index, length-index, getAsInt(start+index, length-index)); | 
		
	
		
			
				|  |  |  |  |  |              | 
		
	
		
			
				|  |  |  |  |  | #ifdef ASSERT_BITVECTOR
 | 
		
	
		
			
				|  |  |  |  |  |             // Check correctness of getter
 | 
		
	
		
			
				|  |  |  |  |  |             for (uint_fast64_t i = 0; i < length; ++i) { | 
		
	
		
			
				|  |  |  |  |  |                 STORM_LOG_ASSERT(result.get(i) == get(start + i), "Getting of bits not correct for index " << i); | 
		
	
		
			
				|  |  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |  | #endif
 | 
		
	
		
			
				|  |  |  |  |  |             return result; | 
		
	
		
			
				|  |  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |  |          | 
		
	
		
			
				|  |  |  |  |  |         void BitVector::setFromBitVector(uint_fast64_t start, BitVector const& other) { | 
		
	
		
			
				|  |  |  |  |  |             uint_fast64_t index = 0; | 
		
	
		
			
				|  |  |  |  |  |             for ( ; index + 63 <= other.bitCount; index += 63) { | 
		
	
		
			
				|  |  |  |  |  |                 setFromInt(start+index, 63, other.getAsInt(index, 63)); | 
		
	
		
			
				|  |  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |  |             // Insert remaining bits
 | 
		
	
		
			
				|  |  |  |  |  |             setFromInt(start+index, other.bitCount-index, other.getAsInt(index, other.bitCount-index)); | 
		
	
		
			
				|  |  |  |  |  |              | 
		
	
		
			
				|  |  |  |  |  | #ifdef ASSERT_BITVECTOR
 | 
		
	
		
			
				|  |  |  |  |  |             // Check correctness of setter
 | 
		
	
		
			
				|  |  |  |  |  |             for (uint_fast64_t i = 0; i < other.bitCount; ++i) { | 
		
	
		
			
				|  |  |  |  |  |                 STORM_LOG_ASSERT(other.get(i) == get(start + i), "Setting of bits not correct for index " << i); | 
		
	
		
			
				|  |  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |  | #endif
 | 
		
	
		
			
				|  |  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |  |          | 
		
	
		
			
				|  |  |  |  |  |         bool BitVector::compareAndSwap(uint_fast64_t start1, uint_fast64_t start2, uint_fast64_t length) { | 
		
	
		
			
				|  |  |  |  |  |             if (length < 64) { | 
		
	
		
			
				|  |  |  |  |  |                 uint_fast64_t elem1 = getAsInt(start1, length); | 
		
	
		
			
				|  |  |  |  |  |                 uint_fast64_t elem2 = getAsInt(start2, length); | 
		
	
		
			
				|  |  |  |  |  |                 if (elem1 < elem2) { | 
		
	
		
			
				|  |  |  |  |  |                     // Swap elements
 | 
		
	
		
			
				|  |  |  |  |  |                     setFromInt(start1, length, elem2); | 
		
	
		
			
				|  |  |  |  |  |                     setFromInt(start2, length, elem1); | 
		
	
		
			
				|  |  |  |  |  |                     return true; | 
		
	
		
			
				|  |  |  |  |  |                 } | 
		
	
		
			
				|  |  |  |  |  |                 return false; | 
		
	
		
			
				|  |  |  |  |  |             } else { | 
		
	
		
			
				|  |  |  |  |  |                 //TODO improve performance
 | 
		
	
		
			
				|  |  |  |  |  |                 BitVector elem1 = getAsBitVector(start1, length); | 
		
	
		
			
				|  |  |  |  |  |                 BitVector elem2 = getAsBitVector(start2, length); | 
		
	
		
			
				|  |  |  |  |  |                  | 
		
	
		
			
				|  |  |  |  |  |                 if (!(elem1 < elem2)) { | 
		
	
		
			
				|  |  |  |  |  |                     // Elements already sorted
 | 
		
	
		
			
				|  |  |  |  |  | #ifdef ASSERT_BITVECTOR
 | 
		
	
		
			
				|  |  |  |  |  |                     // Check that sorted
 | 
		
	
		
			
				|  |  |  |  |  |                     for (uint_fast64_t i = 0; i < length; ++i) { | 
		
	
		
			
				|  |  |  |  |  |                         if (get(start1 + i) > get(start2 + i)) { | 
		
	
		
			
				|  |  |  |  |  |                             break; | 
		
	
		
			
				|  |  |  |  |  |                         } | 
		
	
		
			
				|  |  |  |  |  |                         STORM_LOG_ASSERT(get(start1 + i) >= get(start2 + i), "Bit vector not sorted for indices " << start1+i << " and " << start2+i); | 
		
	
		
			
				|  |  |  |  |  |                     } | 
		
	
		
			
				|  |  |  |  |  | #endif
 | 
		
	
		
			
				|  |  |  |  |  |                     return false; | 
		
	
		
			
				|  |  |  |  |  |                 } | 
		
	
		
			
				|  |  |  |  |  |                  | 
		
	
		
			
				|  |  |  |  |  | #ifdef ASSERT_BITVECTOR
 | 
		
	
		
			
				|  |  |  |  |  |                 BitVector check(*this); | 
		
	
		
			
				|  |  |  |  |  | #endif
 | 
		
	
		
			
				|  |  |  |  |  |                  | 
		
	
		
			
				|  |  |  |  |  |                 // Swap elements
 | 
		
	
		
			
				|  |  |  |  |  |                 setFromBitVector(start1, elem2); | 
		
	
		
			
				|  |  |  |  |  |                 setFromBitVector(start2, elem1); | 
		
	
		
			
				|  |  |  |  |  |                  | 
		
	
		
			
				|  |  |  |  |  | #ifdef ASSERT_BITVECTOR
 | 
		
	
		
			
				|  |  |  |  |  |                 // Check correctness of swapping
 | 
		
	
		
			
				|  |  |  |  |  |                 bool tmp; | 
		
	
		
			
				|  |  |  |  |  |                 for (uint_fast64_t i = 0; i < length; ++i) { | 
		
	
		
			
				|  |  |  |  |  |                     tmp = check.get(i + start1); | 
		
	
		
			
				|  |  |  |  |  |                     check.set(i + start1, check.get(i + start2)); | 
		
	
		
			
				|  |  |  |  |  |                     check.set(i + start2, tmp); | 
		
	
		
			
				|  |  |  |  |  |                 } | 
		
	
		
			
				|  |  |  |  |  |                 STORM_LOG_ASSERT(*this == check, "Swapping not correct"); | 
		
	
		
			
				|  |  |  |  |  |                  | 
		
	
		
			
				|  |  |  |  |  |                 // Check that sorted
 | 
		
	
		
			
				|  |  |  |  |  |                 for (uint_fast64_t i = 0; i < length; ++i) { | 
		
	
		
			
				|  |  |  |  |  |                     if (get(start1 + i) > get(start2 + i)) { | 
		
	
		
			
				|  |  |  |  |  |                         break; | 
		
	
		
			
				|  |  |  |  |  |                     } | 
		
	
		
			
				|  |  |  |  |  |                     STORM_LOG_ASSERT(get(start1 + i) >= get(start2 + i), "Bit vector not sorted for indices " << start1+i << " and " << start2+i); | 
		
	
		
			
				|  |  |  |  |  |                 } | 
		
	
		
			
				|  |  |  |  |  | #endif
 | 
		
	
		
			
				|  |  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |  |                 return true; | 
		
	
		
			
				|  |  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |  | 
 | 
		
	
		
			
				|  |  |         void BitVector::truncateLastBucket() { |  |  |         void BitVector::truncateLastBucket() { | 
		
	
		
			
				|  |  |             if ((bitCount & mod64mask) != 0) { |  |  |             if ((bitCount & mod64mask) != 0) { | 
		
	
		
			
				|  |  |                 bucketVector.back() &= ~((1ll << (64 - (bitCount & mod64mask))) - 1ll); |  |  |                 bucketVector.back() &= ~((1ll << (64 - (bitCount & mod64mask))) - 1ll); | 
		
	
	
		
			
				|  | @ -683,6 +787,26 @@ namespace storm { | 
		
	
		
			
				|  |  |             return out; |  |  |             return out; | 
		
	
		
			
				|  |  |         } |  |  |         } | 
		
	
		
			
				|  |  |          |  |  |          | 
		
	
		
			
				|  |  |  |  |  |         void BitVector::printBits(std::ostream& out) { | 
		
	
		
			
				|  |  |  |  |  |             out << "bit vector(" << getNumberOfSetBits() << "/" << bitCount << ") "; | 
		
	
		
			
				|  |  |  |  |  |             uint_fast64_t index = 0; | 
		
	
		
			
				|  |  |  |  |  |             for ( ; index * 64 <= bitCount; ++index) { | 
		
	
		
			
				|  |  |  |  |  |                 std::bitset<64> tmp(bucketVector[index]); | 
		
	
		
			
				|  |  |  |  |  |                 out << tmp << "|"; | 
		
	
		
			
				|  |  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |  |              | 
		
	
		
			
				|  |  |  |  |  |             --index; | 
		
	
		
			
				|  |  |  |  |  |             // Print last bits
 | 
		
	
		
			
				|  |  |  |  |  |             if (index * 64 < bitCount) { | 
		
	
		
			
				|  |  |  |  |  |                 assert(index == bucketVector.size() - 1); | 
		
	
		
			
				|  |  |  |  |  |                 std::bitset<64> tmp(bucketVector[index]); | 
		
	
		
			
				|  |  |  |  |  |                 for (size_t i = 0; i + index * 64 < bitCount; ++i) { | 
		
	
		
			
				|  |  |  |  |  |                     out << tmp[i]; | 
		
	
		
			
				|  |  |  |  |  |                 } | 
		
	
		
			
				|  |  |  |  |  |             } | 
		
	
		
			
				|  |  |  |  |  |             out << std::endl; | 
		
	
		
			
				|  |  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |  | 
 | 
		
	
		
			
				|  |  |         std::size_t NonZeroBitVectorHash::operator()(storm::storage::BitVector const& bv) const { |  |  |         std::size_t NonZeroBitVectorHash::operator()(storm::storage::BitVector const& bv) const { | 
		
	
		
			
				|  |  |             STORM_LOG_ASSERT(bv.size() > 0, "Cannot hash bit vector of zero size."); |  |  |             STORM_LOG_ASSERT(bv.size() > 0, "Cannot hash bit vector of zero size."); | 
		
	
		
			
				|  |  |             std::size_t result = 0; |  |  |             std::size_t result = 0; | 
		
	
	
		
			
				|  | 
 |