Browse Source
add common.IntSet: interface for an ordered set of integers, providing fast membership test
add common.IntSet: interface for an ordered set of integers, providing fast membership test
Wrappers for BitSet and singleton values are provided. git-svn-id: https://www.prismmodelchecker.org/svn/prism/prism/trunk@12105 bbc10eb1-c90d-0410-af57-cb519fbb1720master
1 changed files with 238 additions and 0 deletions
@ -0,0 +1,238 @@ |
|||||
|
//============================================================================== |
||||
|
// |
||||
|
// Copyright (c) 2016- |
||||
|
// Authors: |
||||
|
// * Joachim Klein <klein@tcs.inf.tu-dresden.de> (TU Dresden) |
||||
|
// |
||||
|
//------------------------------------------------------------------------------ |
||||
|
// |
||||
|
// This file is part of PRISM. |
||||
|
// |
||||
|
// PRISM is free software; you can redistribute it and/or modify |
||||
|
// it under the terms of the GNU General Public License as published by |
||||
|
// the Free Software Foundation; either version 2 of the License, or |
||||
|
// (at your option) any later version. |
||||
|
// |
||||
|
// PRISM is distributed in the hope that it will be useful, |
||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
// GNU General Public License for more details. |
||||
|
// |
||||
|
// You should have received a copy of the GNU General Public License |
||||
|
// along with PRISM; if not, write to the Free Software Foundation, |
||||
|
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
||||
|
// |
||||
|
//============================================================================== |
||||
|
|
||||
|
package common; |
||||
|
|
||||
|
import java.util.BitSet; |
||||
|
import java.util.Spliterator; |
||||
|
import java.util.Spliterators; |
||||
|
import java.util.PrimitiveIterator.OfInt; |
||||
|
import java.util.stream.IntStream; |
||||
|
import java.util.stream.StreamSupport; |
||||
|
|
||||
|
import common.IterableBitSet; |
||||
|
|
||||
|
/** |
||||
|
* Interface for an ordered set of integers that allows efficient |
||||
|
* (1) iteration (normal and reversed order) |
||||
|
* and (2) efficient tests of set membership. |
||||
|
* <br> |
||||
|
* Provides static helpers for wrapping a BitSet or a singleton value. |
||||
|
*/ |
||||
|
public interface IntSet extends Iterable<Integer> |
||||
|
{ |
||||
|
/** Return a PrimitiveIterator.OfInt iterator for iteration, normal order */ |
||||
|
public OfInt iterator(); |
||||
|
|
||||
|
/** Return a PrimitiveIterator.OfInt iterator for iteration, reversed order */ |
||||
|
public OfInt reversedIterator(); |
||||
|
|
||||
|
/** Return the cardinality (number of elements) for this set */ |
||||
|
public int cardinality(); |
||||
|
|
||||
|
/** Return true if {@code index} is a member of this set */ |
||||
|
public boolean contains(int index); |
||||
|
|
||||
|
/** |
||||
|
* Return true if {@code index} is a member of this set |
||||
|
* (convenience method to ease migration from use of BitSet). |
||||
|
* <p> |
||||
|
* <i>Default implementation</i>: Calls contains(index). |
||||
|
*/ |
||||
|
public default boolean get(int index) |
||||
|
{ |
||||
|
return contains(index); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Return true if this set contains the {@code other} |
||||
|
* set. |
||||
|
* <p> |
||||
|
* <i>Default implementation</i>: |
||||
|
* Tests via contains for all elements of other. |
||||
|
*/ |
||||
|
public default boolean contains(IntSet other) |
||||
|
{ |
||||
|
return other.stream().allMatch(this::contains); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Return true if this set contains the {@code other} |
||||
|
* set. |
||||
|
* <p> |
||||
|
* <i>Default implementation</i>: |
||||
|
* Uses contains(IntSet other). |
||||
|
*/ |
||||
|
public default boolean contains(BitSet other) |
||||
|
{ |
||||
|
return contains(asIntSet(other)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Produce an IntStream for this set. |
||||
|
* <p> |
||||
|
* <i>Default implementation</i>: |
||||
|
* Wrap iterator() into an intStream. |
||||
|
*/ |
||||
|
public default IntStream stream() { |
||||
|
return StreamSupport.intStream( |
||||
|
() -> Spliterators.spliterator( |
||||
|
iterator(), cardinality(), |
||||
|
Spliterator.DISTINCT), |
||||
|
Spliterator.SIZED | Spliterator.DISTINCT, |
||||
|
false); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Wrapper class for obtaining an IntSet from a BitSet. |
||||
|
* <p> |
||||
|
* Note: The BitSet should not be modified as long as the |
||||
|
* derived IntSet is in use. |
||||
|
*/ |
||||
|
public static class IntSetFromBitSet implements IntSet |
||||
|
{ |
||||
|
/** The wrapped BitSet */ |
||||
|
private BitSet bs; |
||||
|
/** The cardinality of the underlying BitSet (cached, -1 = not yet computed */ |
||||
|
int cardinality = -1; |
||||
|
|
||||
|
/** Constructor */ |
||||
|
public IntSetFromBitSet(BitSet bs) |
||||
|
{ |
||||
|
this.bs = bs; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public OfInt iterator() |
||||
|
{ |
||||
|
return IterableBitSet.getSetBits(bs).iterator(); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public OfInt reversedIterator() |
||||
|
{ |
||||
|
return IterableBitSet.getSetBitsReversed(bs).iterator(); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public IntStream stream() |
||||
|
{ |
||||
|
return bs.stream(); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public int cardinality() |
||||
|
{ |
||||
|
// not yet computed? |
||||
|
if (cardinality == -1) |
||||
|
cardinality = bs.cardinality(); |
||||
|
|
||||
|
return cardinality; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public boolean contains(int index) |
||||
|
{ |
||||
|
return bs.get(index); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
/** Convenience class for simulating a singleton set */ |
||||
|
public static class SingletonIntSet implements IntSet |
||||
|
{ |
||||
|
/** The single member of this singleton set */ |
||||
|
private int singleMember; |
||||
|
|
||||
|
/** |
||||
|
* Constructor. |
||||
|
* @param singleMember the single member of this set |
||||
|
*/ |
||||
|
public SingletonIntSet(int singleMember) |
||||
|
{ |
||||
|
this.singleMember = singleMember; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public OfInt iterator() |
||||
|
{ |
||||
|
return new OfInt() { |
||||
|
boolean done = false; |
||||
|
@Override |
||||
|
public boolean hasNext() |
||||
|
{ |
||||
|
return !done; |
||||
|
} |
||||
|
@Override |
||||
|
public int nextInt() |
||||
|
{ |
||||
|
done = true; |
||||
|
return singleMember; |
||||
|
} |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public OfInt reversedIterator() |
||||
|
{ |
||||
|
// iteration order does not matter for singleton set |
||||
|
return iterator(); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public int cardinality() |
||||
|
{ |
||||
|
return 1; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public boolean contains(int index) |
||||
|
{ |
||||
|
return index == singleMember; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Static constructor for obtaining an IntSet from a BitSet |
||||
|
* <p> |
||||
|
* Note: The BitSet should not be modified as long as the derived IntSet is in use. |
||||
|
* @param bs The underlying BitSet |
||||
|
*/ |
||||
|
public static IntSet asIntSet(BitSet bs) |
||||
|
{ |
||||
|
return new IntSetFromBitSet(bs); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Static constructor for obtaining an IntSet for a singleton set. |
||||
|
* @param singleMember The single member of the singleton set |
||||
|
*/ |
||||
|
public static IntSet asIntSet(int singleMember) |
||||
|
{ |
||||
|
return new SingletonIntSet(singleMember); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue