diff --git a/prism/.classpath b/prism/.classpath
index 1bef3aa5af..4b1d86cb08 100644
--- a/prism/.classpath
+++ b/prism/.classpath
@@ -1,7 +1,12 @@
-
+
+
+
+
+
+
@@ -12,5 +17,6 @@
+
diff --git a/prism/Makefile b/prism/Makefile
index 12544d2ef2..72d4748056 100644
--- a/prism/Makefile
+++ b/prism/Makefile
@@ -14,6 +14,7 @@
# If this is a problem, the best solution is to create symlinks.
export PRISM_SRC_DIR = src
+export PRISM_TESTS_DIR = unit-tests
export PRISM_CLASSES_DIR = classes
export PRISM_OBJ_DIR = obj
export PRISM_LIB_DIR = lib
@@ -176,6 +177,7 @@ else
endif
LD = $(CXX)
JAVAC = javac
+JAVA = java
export CC CXX LD JAVAC JAVACC
@@ -323,6 +325,7 @@ export CFLAGS CXXFLAGS LDFLAGS JFLAGS LIBPREFIX LIBSUFFIX
##########################################
MAKE_DIRS = dd jdd odd dv prism mtbdd sparse hybrid parser settings userinterface pepa/compiler simulator jltl2ba jltl2dstar explicit pta param strat automata common cex
+TEST_DIRS = common
EXT_PACKAGES = lpsolve55 lp_solve_5.5_java
@@ -368,7 +371,7 @@ extpackages: checks
# Compile main PRISM code
# (we also do some preparatory checks, and build launch scripts afterwards)
-prism: checks make_dirs bin_scripts
+prism: checks make_dirs bin_scripts make_tests
# Compile each (top-level) source directory separately
make_dirs:
@@ -397,6 +400,22 @@ make_dirs:
(dos2unix $(PRISM_INCLUDE_DIR)/jni/*.h) \
fi;
+make_tests:
+ @for dir in $(TEST_DIRS); do \
+ echo Making $(PRISM_TESTS_DIR)/$$dir ...; \
+ (cd $(PRISM_TESTS_DIR)/$$dir && \
+ $(MAKE) \
+ CUDD_DIR="$(CUDD_DIR)" \
+ JAVA_INCLUDES="$(JAVA_INCLUDES)" \
+ JAVA_JNI_H_DIR="$(JAVA_JNI_H_DIR)" \
+ JAVA_JNI_MD_H_DIR="$(JAVA_JNI_MD_H_DIR)" \
+ SHARED="$(SHARED)" \
+ EXE="$(EXE)" \
+ LIBMATH="$(LIBMATH)" \
+ CLASSPATHSEP="$(CLASSPATHSEP)") \
+ || exit 1; \
+ done; \
+
# Copy/modify the launch scripts and put in the bin directory
bin_scripts:
@for target in $(BIN_TARGETS); do \
@@ -472,6 +491,8 @@ count_loc:
###########
# Testing #
###########
+unittests:
+ $(JAVA) -jar lib/junit-platform-console-standalone-1.7.2.jar -cp classes --scan-classpath
# Run a single test case from the test suite (useful quick check that the build was ok)
test:
diff --git a/prism/lib/junit-platform-console-standalone-1.7.2.jar b/prism/lib/junit-platform-console-standalone-1.7.2.jar
new file mode 100644
index 0000000000..f37056501f
Binary files /dev/null and b/prism/lib/junit-platform-console-standalone-1.7.2.jar differ
diff --git a/prism/src/common/IntSet.java b/prism/src/common/IntSet.java
index 8bac70fd54..1ca419be81 100644
--- a/prism/src/common/IntSet.java
+++ b/prism/src/common/IntSet.java
@@ -3,6 +3,7 @@
// Copyright (c) 2016-
// Authors:
// * Joachim Klein (TU Dresden)
+// * Steffen Maercker (TU Dresden)
//
//------------------------------------------------------------------------------
//
@@ -27,13 +28,18 @@
package common;
import java.util.BitSet;
+import java.util.Objects;
+import java.util.PrimitiveIterator;
import java.util.Spliterator;
import java.util.Spliterators;
-import java.util.PrimitiveIterator.OfInt;
+import java.util.function.IntPredicate;
import java.util.stream.IntStream;
import java.util.stream.StreamSupport;
import common.IterableBitSet;
+import common.iterable.FunctionalPrimitiveIterable;
+import common.iterable.FunctionalPrimitiveIterator;
+import common.iterable.SingletonIterable;
/**
* Interface for an ordered set of integers that allows efficient
@@ -42,19 +48,16 @@
*
* Provides static helpers for wrapping a BitSet or a singleton value.
*/
-public interface IntSet extends Iterable
+public interface IntSet extends FunctionalPrimitiveIterable.OfInt
{
- /** 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 a FunctionalPrimitiveIterator.OfInt iterator for iteration, reversed order */
+ FunctionalPrimitiveIterator.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);
+ default long cardinality()
+ {
+ return count();
+ }
/**
* Return true if {@code index} is a member of this set
@@ -62,7 +65,7 @@ public interface IntSet extends Iterable
*
* Default implementation: Calls contains(index).
*/
- public default boolean get(int index)
+ default boolean get(int index)
{
return contains(index);
}
@@ -74,9 +77,9 @@ public default boolean get(int index)
* Default implementation:
* Tests via contains for all elements of other.
*/
- public default boolean contains(IntSet other)
+ default boolean contains(IntSet other)
{
- return other.stream().allMatch(this::contains);
+ return other.allMatch((IntPredicate) this::contains);
}
/**
@@ -86,7 +89,7 @@ public default boolean contains(IntSet other)
* Default implementation:
* Uses contains(IntSet other).
*/
- public default boolean contains(BitSet other)
+ default boolean contains(BitSet other)
{
return contains(asIntSet(other));
}
@@ -97,23 +100,32 @@ public default boolean contains(BitSet other)
* Default implementation:
* Wrap iterator() into an intStream.
*/
- public default IntStream stream() {
+ default IntStream stream()
+ {
return StreamSupport.intStream(
- () -> Spliterators.spliterator(
- iterator(), cardinality(),
- Spliterator.DISTINCT),
+ () -> spliterator(),
Spliterator.SIZED | Spliterator.DISTINCT,
false);
}
+ @Override
+ default Spliterator.OfInt spliterator()
+ {
+ return Spliterators.spliterator(
+ iterator(),
+ cardinality(),
+ Spliterator.SIZED | Spliterator.DISTINCT);
+ }
+
/** Return this set as a String */
- public default String asString()
+ @Override
+ default String asString()
{
// can't overload toString() with a default method in interface
StringBuffer sb = new StringBuffer();
sb.append("{");
boolean first = true;
- for (OfInt it = iterator(); it.hasNext(); ) {
+ for (PrimitiveIterator.OfInt it = iterator(); it.hasNext(); ) {
if (!first)
sb.append(",");
first = false;
@@ -123,33 +135,36 @@ public default String asString()
return sb.toString();
}
+
+
/**
* Wrapper class for obtaining an IntSet from a BitSet.
*
* Note: The BitSet should not be modified as long as the
* derived IntSet is in use.
*/
- public static class IntSetFromBitSet implements IntSet
+ static class IntSetFromBitSet implements IntSet
{
/** The wrapped BitSet */
- private BitSet bs;
+ protected BitSet bs;
/** The cardinality of the underlying BitSet (cached, -1 = not yet computed) */
int cardinality = -1;
/** Constructor */
public IntSetFromBitSet(BitSet bs)
{
+ Objects.requireNonNull(bs);
this.bs = bs;
}
@Override
- public OfInt iterator()
+ public FunctionalPrimitiveIterator.OfInt iterator()
{
return IterableBitSet.getSetBits(bs).iterator();
}
@Override
- public OfInt reversedIterator()
+ public FunctionalPrimitiveIterator.OfInt reversedIterator()
{
return IterableBitSet.getSetBitsReversed(bs).iterator();
}
@@ -161,7 +176,7 @@ public IntStream stream()
}
@Override
- public int cardinality()
+ public long count()
{
// not yet computed?
if (cardinality == -1)
@@ -183,86 +198,53 @@ public String toString()
}
};
+
+
/** Convenience class for simulating a singleton set */
- public static class SingletonIntSet implements IntSet
+ static class SingletonIntSet extends SingletonIterable.OfInt 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;
+ super(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()
+ public FunctionalPrimitiveIterator.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;
- }
-
@Override
public String toString()
{
- return "{" + singleMember + "}";
+ return "{" + element + "}";
}
-
}
/**
- * Static constructor for obtaining an IntSet from a BitSet
+ * Factory method for obtaining an IntSet from a BitSet
*
* 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)
+ static IntSet asIntSet(BitSet bs)
{
return new IntSetFromBitSet(bs);
}
/**
- * Static constructor for obtaining an IntSet for a singleton set.
+ * Factory method for obtaining an IntSet for a singleton set.
+ *
* @param singleMember The single member of the singleton set
*/
- public static IntSet asIntSet(int singleMember)
+ static IntSet asIntSet(int singleMember)
{
return new SingletonIntSet(singleMember);
}
-
}
-
diff --git a/prism/src/common/IterableBitSet.java b/prism/src/common/IterableBitSet.java
index da2e85bfcf..8e90563a17 100644
--- a/prism/src/common/IterableBitSet.java
+++ b/prism/src/common/IterableBitSet.java
@@ -2,7 +2,7 @@
//
// Copyright (c) 2014-
// Authors:
-// * Steffen Maercker (TU Dresden)
+// * Steffen Maercker (TU Dresden)
// * Joachim Klein (TU Dresden)
//
//------------------------------------------------------------------------------
@@ -30,9 +30,9 @@
import java.util.BitSet;
import java.util.NoSuchElementException;
import java.util.Objects;
-import java.util.PrimitiveIterator.OfInt;
-import common.iterable.IterableInt;
+import common.iterable.FunctionalPrimitiveIterable;
+import common.iterable.FunctionalPrimitiveIterator;
/**
* Convenience class to loop easily over the set/clear bits of a BitSet.
@@ -40,7 +40,7 @@
* For example:
* for (Integer index : getSetBits(set)) { ... }
*/
-public class IterableBitSet implements IterableInt
+public class IterableBitSet implements FunctionalPrimitiveIterable.OfInt
{
protected final BitSet set;
protected final boolean clearBits;
@@ -92,7 +92,7 @@ public IterableBitSet(BitSet set, Integer maxIndex, boolean clearBits, boolean r
}
/** Implementation of the iterator over the set bits */
- private class SetBitsIterator implements OfInt
+ private class SetBitsIterator implements FunctionalPrimitiveIterator.OfInt
{
private int current = -1;
private int next = set.nextSetBit(0);
@@ -130,7 +130,7 @@ public void remove()
}
/** Implementation of the iterator over the set bits (reverse order) */
- private class SetBitsReversedIterator implements OfInt
+ private class SetBitsReversedIterator implements FunctionalPrimitiveIterator.OfInt
{
private int current = -1;
private int next;
@@ -168,7 +168,7 @@ public void remove()
}
/** Implementation of the iterator over the cleared bits, requires that {@code maxIndex != null} */
- private class ClearBitsIterator implements OfInt
+ private class ClearBitsIterator implements FunctionalPrimitiveIterator.OfInt
{
private int current = -1;
private int next = set.nextClearBit(0);
@@ -206,7 +206,7 @@ public void remove()
}
/** Implementation of the iterator over the clear bits (reverse order), requires that {@code maxIndex != null} */
- private class ClearBitsReversedIterator implements OfInt
+ private class ClearBitsReversedIterator implements FunctionalPrimitiveIterator.OfInt
{
private int current = -1;
private int next;
@@ -244,7 +244,7 @@ public void remove()
}
@Override
- public OfInt iterator()
+ public FunctionalPrimitiveIterator.OfInt iterator()
{
if (clearBits == false) {
if (reversed) {
diff --git a/prism/src/common/IterableStateSet.java b/prism/src/common/IterableStateSet.java
index 86427129c5..d7f14e8317 100644
--- a/prism/src/common/IterableStateSet.java
+++ b/prism/src/common/IterableStateSet.java
@@ -3,7 +3,7 @@
// Copyright (c) 2014-
// Authors:
// * Joachim Klein (TU Dresden)
-// * Steffen Märcker (TU Dresden)
+// * Steffen Märcker (TU Dresden)
//
//------------------------------------------------------------------------------
//
@@ -25,22 +25,23 @@
//
//==============================================================================
-
package common;
import java.util.BitSet;
-import java.util.PrimitiveIterator.OfInt;
-import common.iterable.*;
+import common.iterable.EmptyIterable;
+import common.iterable.FunctionalPrimitiveIterable;
+import common.iterable.FunctionalPrimitiveIterator;
+import common.iterable.Range;
/**
* A convenience wrapper around IterableBitSet that handles the three cases of
* iterating over the set or cleared bits of a BitSet representing a set of states
* as well as iterating over all states if the BitSet is {@code null}.
*/
-public class IterableStateSet implements IterableInt
+public class IterableStateSet implements FunctionalPrimitiveIterable.OfInt
{
- private final IterableInt setOfStates;
+ protected final FunctionalPrimitiveIterable.OfInt setOfStates;
/**
* Constructor (iterate over all states 0..numStates-1)
@@ -91,16 +92,16 @@ public IterableStateSet(BitSet setOfStates, int numStates, boolean complement, b
if (setOfStates == null || (setOfStates.length() == numStates && setOfStates.cardinality() == numStates)) {
// all states
if (complement) {
- this.setOfStates = EmptyIterable.OfInt();
+ this.setOfStates = EmptyIterable.ofInt();
} else {
- this.setOfStates = reversed ? new RangeIntIterable(numStates-1, 0) : new RangeIntIterable(0, numStates-1);
+ this.setOfStates = reversed ? new Range(numStates).reversed() : new Range(numStates);
}
} else if (setOfStates.isEmpty()) {
// no states
if (complement) {
- this.setOfStates = reversed ? new RangeIntIterable(numStates-1, 0) : new RangeIntIterable(0, numStates-1);
+ this.setOfStates = reversed ? new Range(numStates).reversed() : new Range(numStates);
} else {
- this.setOfStates = EmptyIterable.OfInt();
+ this.setOfStates = EmptyIterable.ofInt();
}
} else {
// build appropriate IterableBitSet with maxIndex = numStates-1
@@ -109,7 +110,7 @@ public IterableStateSet(BitSet setOfStates, int numStates, boolean complement, b
}
@Override
- public OfInt iterator()
+ public FunctionalPrimitiveIterator.OfInt iterator()
{
return setOfStates.iterator();
}
diff --git a/prism/src/common/IteratorTools.java b/prism/src/common/IteratorTools.java
index 24a0e79847..ea4b9e4d74 100644
--- a/prism/src/common/IteratorTools.java
+++ b/prism/src/common/IteratorTools.java
@@ -2,7 +2,7 @@
//
// Copyright (c) 2016-
// Authors:
-// * Steffen Maercker (TU Dresden)
+// * Steffen Maercker (TU Dresden)
// * Joachim Klein (TU Dresden)
//
//------------------------------------------------------------------------------
@@ -28,148 +28,233 @@
package common;
import java.util.Iterator;
-import java.util.function.DoublePredicate;
-import java.util.function.IntPredicate;
-import java.util.function.LongPredicate;
-import java.util.function.Predicate;
-
-import common.iterable.FilteringIterator;
-import common.iterable.MappingIterator;
-
+import java.util.OptionalDouble;
+import java.util.OptionalInt;
+import java.util.OptionalLong;
import java.util.PrimitiveIterator.OfDouble;
import java.util.PrimitiveIterator.OfInt;
import java.util.PrimitiveIterator.OfLong;
+import java.util.function.Predicate;
-/** Convenience methods for performing operations on Iterators / Iterables */
+import common.iterable.Reducible;
+
+/**
+ * Convenience methods for performing operations on Iterators / Iterables
+ */
public class IteratorTools
{
- /** Count the number of elements */
- public static int count(final Iterable> iterable)
+ /**
+ * Boolean AND-function: Are all elements true?
+ */
+ public static boolean and(Iterator booleans)
{
- return count(iterable.iterator());
+ while (booleans.hasNext()) {
+ if (!booleans.next()) {
+ return false;
+ }
+ }
+ return true;
}
- /** Count the number of elements */
- public static int count(final Iterator> iterator)
+ /**
+ * Boolean OR-function: Is at least one elements true?
+ */
+ public static boolean or(Iterator booleans)
{
- if (iterator instanceof OfInt) {
- return count((OfInt) iterator);
- }
- if (iterator instanceof OfLong) {
- return count((OfLong) iterator);
- }
- if (iterator instanceof OfDouble) {
- return count((OfDouble) iterator);
+ while (booleans.hasNext()) {
+ if (booleans.next()) {
+ return true;
+ }
}
+ return false;
+ }
- int count=0;
- for (; iterator.hasNext(); iterator.next()) {
- count++;
- }
- return count;
+ /**
+ * Count the number of elements
+ */
+ public static long count(Iterable> iterable)
+ {
+ return Reducible.extend(iterable).count();
}
- /** Count the number of elements */
- public static int count(final OfInt iterator)
+ /**
+ * Count the number of elements
+ */
+ public static long count(Iterator> iterator)
{
- // call nextInt to avoid unnecessary boxing
- int count=0;
- for (; iterator.hasNext(); iterator.nextInt()) {
- count++;
- }
- return count;
+ return Reducible.extend(iterator).count();
}
- /** Count the number of elements */
- public static int count(final OfLong iterator)
+ /**
+ * Count the number of elements
+ */
+ public static long count(Iterable iterable, Predicate super T> predicate)
{
- // call nextLong to avoid unnecessary boxing
- int count=0;
- for (; iterator.hasNext(); iterator.nextLong()) {
- count++;
- }
- return count;
+ return Reducible.extend(iterable).count(predicate);
}
- /** Count the number of elements */
- public static int count(final OfDouble iterator)
+ /**
+ * Count the number of elements
+ */
+ public static long count(Iterator iterator, Predicate super T> predicate)
{
- // call nextDouble to avoid unnecessary boxing
- int count=0;
- for (; iterator.hasNext(); iterator.nextDouble()) {
- count++;
- }
- return count;
+ return Reducible.extend(iterator).count(predicate);
}
- /** Count the number of elements matching the predicate */
- public static int count(final Iterable iterable, final Predicate super T> predicate)
+ /**
+ * Maximum over iterator elements
+ */
+ public static OptionalDouble max(OfDouble numbers)
{
- return count(iterable.iterator(), predicate);
+ return Reducible.extend(numbers).max();
}
- /** Count the number of elements matching the predicate */
- public static int count(final Iterator iterator, final Predicate super T> predicate)
+ /**
+ * Maximum over iterator elements
+ */
+ public static OptionalInt max(OfInt numbers)
{
- if (iterator instanceof OfInt && predicate instanceof IntPredicate) {
- return count(new FilteringIterator.OfInt((OfInt) iterator, (IntPredicate) predicate));
- }
- if (iterator instanceof OfLong && predicate instanceof LongPredicate) {
- return count(new FilteringIterator.OfLong((OfLong) iterator, (LongPredicate) predicate));
- }
- if (iterator instanceof OfDouble && predicate instanceof DoublePredicate) {
- return count(new FilteringIterator.OfDouble((OfDouble) iterator, (DoublePredicate) predicate));
- }
+ return Reducible.extend(numbers).max();
+ }
- return count(new FilteringIterator.Of<>(iterator, predicate));
+ /**
+ * Maximum over iterator elements
+ */
+ public static OptionalLong max(OfLong numbers)
+ {
+ return Reducible.extend(numbers).max();
}
- /** Sum over iterator elements */
- public static int sumInt(final Iterator numbers)
+ /**
+ * Maximum over non-null iterator elements
+ */
+ public static OptionalDouble maxDouble(Iterator numbers)
{
- return sum(MappingIterator.toInt(numbers));
+ return Reducible.unboxDouble(Reducible.extend(numbers).nonNull()).max();
}
- /** Sum over iterator elements */
- public static int sum(final OfInt numbers)
+ /**
+ * Maximum over non-null iterator elements
+ */
+ public static OptionalInt maxInt(Iterator numbers)
{
- int sum = 0;
- while (numbers.hasNext()) {
- sum += numbers.nextInt();
- }
- return sum;
+ return Reducible.unboxInt(Reducible.extend(numbers).nonNull()).max();
}
- /** Sum over iterator elements */
- public static long sumLong(final Iterator numbers)
+ /**
+ * Maximum over non-null iterator elements
+ */
+ public static OptionalLong maxLong(Iterator numbers)
{
- return sum(MappingIterator.toLong(numbers));
+ return Reducible.unboxLong(Reducible.extend(numbers).nonNull()).max();
}
- /** Sum over iterator elements */
- public static long sum(final OfLong numbers)
+ /**
+ * Minimum over iterator elements
+ */
+ public static OptionalDouble min(OfDouble numbers)
{
- long sum = 0;
- while (numbers.hasNext()) {
- sum += numbers.nextLong();
- }
- return sum;
+ return Reducible.extend(numbers).min();
}
- /** Sum over iterator elements */
- public static double sumDouble(final Iterator numbers)
+ /**
+ * Minimum over iterator elements
+ */
+ public static OptionalInt min(OfInt numbers)
{
- return sum(MappingIterator.toDouble(numbers));
+ return Reducible.extend(numbers).min();
}
- /** Sum over iterator elements */
- public static double sum(final OfDouble numbers)
+ /**
+ * Minimum over iterator elements
+ */
+ public static OptionalLong min(OfLong numbers)
{
- double sum = 0;
- while (numbers.hasNext()) {
- sum += numbers.nextDouble();
- }
- return sum;
+ return Reducible.extend(numbers).min();
+ }
+
+ /**
+ * Minimum over non-null iterator elements
+ */
+ public static OptionalDouble minDouble(Iterator numbers)
+ {
+ return Reducible.unboxDouble(Reducible.extend(numbers).nonNull()).min();
}
+ /**
+ * Minimum over non-null iterator elements
+ */
+ public static OptionalInt minInt(Iterator numbers)
+ {
+ return Reducible.unboxInt(Reducible.extend(numbers).nonNull()).min();
+ }
+
+ /**
+ * Minimum over non-null iterator elements
+ */
+ public static OptionalLong minLong(Iterator numbers)
+ {
+ return Reducible.unboxLong(Reducible.extend(numbers).nonNull()).min();
+ }
+
+ /**
+ * Sum over iterator elements
+ */
+ public static double sum(OfDouble numbers)
+ {
+ return Reducible.extend(numbers).sum();
+ }
+
+ /**
+ * Sum over iterator elements
+ */
+ public static long sum(OfInt numbers)
+ {
+ return Reducible.extend(numbers).sum();
+ }
+
+ /**
+ * Sum over iterator elements
+ */
+ public static long sum(OfLong numbers)
+ {
+ return Reducible.extend(numbers).sum();
+ }
+
+ /**
+ * Sum over non-null iterator elements
+ */
+ public static double sumDouble(Iterator numbers)
+ {
+ return Reducible.unboxDouble(Reducible.extend(numbers).nonNull()).sum();
+ }
+
+ /**
+ * Sum over non-null iterator elements
+ */
+ public static long sumInt(Iterator numbers)
+ {
+ return Reducible.unboxInt(Reducible.extend(numbers).nonNull()).sum();
+ }
+
+ /**
+ * Sum over non-null iterator elements
+ */
+ public static long sumLong(Iterator numbers)
+ {
+ return Reducible.unboxLong(Reducible.extend(numbers).nonNull()).sum();
+ }
+
+ /**
+ * Create String "name = {e_1, e_2}".
+ *
+ * @param name name of a variable
+ * @param iterator the iterator to be printed
+ */
+ public static void printIterator(String name, Iterator iterator)
+ {
+ System.out.print(name + " = ");
+ System.out.print(Reducible.extend(iterator).asString());
+ System.out.println();
+ }
}
diff --git a/prism/src/common/Makefile b/prism/src/common/Makefile
index 115bf5b4ae..b22ca64d73 100644
--- a/prism/src/common/Makefile
+++ b/prism/src/common/Makefile
@@ -14,7 +14,7 @@ PRISM_DIR_REL = ../..
JNI_GEN_HEADER_DIR=$(THIS_DIR)/$(PRISM_DIR_REL)/$(PRISM_INCLUDE_DIR)/jni
-JAVA_FILES_ALL = $(wildcard *.java iterable/*.java functions/primitive/*.java)
+JAVA_FILES_ALL = $(wildcard *.java iterable/*.java functions/*.java)
JAVA_FILES = $(subst package-info.java,,$(JAVA_FILES_ALL))
CLASS_FILES = $(JAVA_FILES:%.java=$(PRISM_DIR_REL)/$(PRISM_CLASSES_DIR)/$(THIS_DIR)/%.class)
diff --git a/prism/src/common/functions/primitive/PairPredicateInt.java b/prism/src/common/functions/DoubleLongToDoubleFunction.java
similarity index 74%
rename from prism/src/common/functions/primitive/PairPredicateInt.java
rename to prism/src/common/functions/DoubleLongToDoubleFunction.java
index 4c1d8f4ae7..e60702ad91 100644
--- a/prism/src/common/functions/primitive/PairPredicateInt.java
+++ b/prism/src/common/functions/DoubleLongToDoubleFunction.java
@@ -1,9 +1,8 @@
//==============================================================================
//
-// Copyright (c) 2016-
+// Copyright (c) 2020-
// Authors:
-// * Steffen Maercker (TU Dresden)
-// * Joachim Klein (TU Dresden)
+// * Steffen Maercker (TU Dresden)
//
//------------------------------------------------------------------------------
//
@@ -25,11 +24,16 @@
//
//==============================================================================
-package common.functions.primitive;
+package common.functions;
-/** Functional interface for a predicate (int, int) -> boolean */
+/**
+ * Functional interface for a binary function (double, long) -> double.
+ */
@FunctionalInterface
-public interface PairPredicateInt
+public interface DoubleLongToDoubleFunction
{
- public abstract boolean test(int element1, int element2);
+ /**
+ * Applies this function to the given arguments.
+ */
+ double applyAsDouble(double d, long l);
}
diff --git a/prism/src/common/functions/DoubleObjToDoubleFunction.java b/prism/src/common/functions/DoubleObjToDoubleFunction.java
new file mode 100644
index 0000000000..5417cdc7c0
--- /dev/null
+++ b/prism/src/common/functions/DoubleObjToDoubleFunction.java
@@ -0,0 +1,51 @@
+//==============================================================================
+//
+// Copyright (c) 2020-
+// Authors:
+// * Steffen Maercker (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.functions;
+
+import java.util.Objects;
+import java.util.function.DoubleUnaryOperator;
+
+/**
+ * Functional interface for a binary function (double, T) -> double.
+ */
+@FunctionalInterface
+public interface DoubleObjToDoubleFunction
+{
+ /**
+ * Applies this function to the given arguments.
+ */
+ double applyAsDouble(double d, T t);
+
+ /**
+ * Returns a composed function that first applies this function to
+ * its input, and then applies the {@code after} function to the result.
+ */
+ default DoubleObjToDoubleFunction andThen(DoubleUnaryOperator after) {
+ Objects.requireNonNull(after);
+ return (double d, T t) -> after.applyAsDouble(applyAsDouble(d, t));
+ }
+}
diff --git a/prism/src/common/iterable/IterableInt.java b/prism/src/common/functions/IntDoubleToIntFunction.java
similarity index 74%
rename from prism/src/common/iterable/IterableInt.java
rename to prism/src/common/functions/IntDoubleToIntFunction.java
index db8e42531e..3a3f1404c1 100644
--- a/prism/src/common/iterable/IterableInt.java
+++ b/prism/src/common/functions/IntDoubleToIntFunction.java
@@ -1,8 +1,8 @@
//==============================================================================
//
-// Copyright (c) 2016-
+// Copyright (c) 2020-
// Authors:
-// * Steffen Maercker (TU Dresden)
+// * Steffen Maercker (TU Dresden)
//
//------------------------------------------------------------------------------
//
@@ -24,13 +24,16 @@
//
//==============================================================================
-package common.iterable;
+package common.functions;
-import java.util.PrimitiveIterator.OfInt;
-
-/** Iterable for a PrimitiveIterator.OfInt */
-public interface IterableInt extends Iterable
+/**
+ * Functional interface for a binary function (int, double) -> int.
+ */
+@FunctionalInterface
+public interface IntDoubleToIntFunction
{
- @Override
- public OfInt iterator();
+ /**
+ * Applies this function to the given arguments.
+ */
+ int applyAsInt(int i, double d);
}
diff --git a/prism/src/common/iterable/IterableDouble.java b/prism/src/common/functions/IntLongToIntFunction.java
similarity index 74%
rename from prism/src/common/iterable/IterableDouble.java
rename to prism/src/common/functions/IntLongToIntFunction.java
index f2690013e3..fd3bf44389 100644
--- a/prism/src/common/iterable/IterableDouble.java
+++ b/prism/src/common/functions/IntLongToIntFunction.java
@@ -1,8 +1,8 @@
//==============================================================================
//
-// Copyright (c) 2016-
+// Copyright (c) 2020-
// Authors:
-// * Steffen Maercker (TU Dresden)
+// * Steffen Maercker (TU Dresden)
//
//------------------------------------------------------------------------------
//
@@ -24,13 +24,16 @@
//
//==============================================================================
-package common.iterable;
+package common.functions;
-import java.util.PrimitiveIterator.OfDouble;
-
-/** Iterable for a PrimitiveIterator.OfDouble */
-public interface IterableDouble extends Iterable
+/**
+ * Functional interface for a binary function (int, long) -> int.
+ */
+@FunctionalInterface
+public interface IntLongToIntFunction
{
- @Override
- public OfDouble iterator();
+ /**
+ * Applies this function to the given arguments.
+ */
+ int applyAsInt(int i, long l);
}
diff --git a/prism/src/common/functions/IntObjToIntFunction.java b/prism/src/common/functions/IntObjToIntFunction.java
new file mode 100644
index 0000000000..db70e8bae7
--- /dev/null
+++ b/prism/src/common/functions/IntObjToIntFunction.java
@@ -0,0 +1,51 @@
+//==============================================================================
+//
+// Copyright (c) 2020-
+// Authors:
+// * Steffen Maercker (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.functions;
+
+import java.util.Objects;
+import java.util.function.IntUnaryOperator;
+
+/**
+ * Functional interface for a binary function (int, T) -> int.
+ */
+@FunctionalInterface
+public interface IntObjToIntFunction
+{
+ /**
+ * Applies this function to the given arguments.
+ */
+ int applyAsInt(int i, T t);
+
+ /**
+ * Returns a composed function that first applies this function to
+ * its input, and then applies the {@code after} function to the result.
+ */
+ default IntObjToIntFunction andThen(IntUnaryOperator after) {
+ Objects.requireNonNull(after);
+ return (int i, T t) -> after.applyAsInt(applyAsInt(i, t));
+ }
+}
diff --git a/prism/src/common/iterable/IterableLong.java b/prism/src/common/functions/LongDoubleToLongFunction.java
similarity index 74%
rename from prism/src/common/iterable/IterableLong.java
rename to prism/src/common/functions/LongDoubleToLongFunction.java
index c113ef73f1..9196fce233 100644
--- a/prism/src/common/iterable/IterableLong.java
+++ b/prism/src/common/functions/LongDoubleToLongFunction.java
@@ -1,8 +1,8 @@
//==============================================================================
//
-// Copyright (c) 2016-
+// Copyright (c) 2020-
// Authors:
-// * Steffen Maercker (TU Dresden)
+// * Steffen Maercker (TU Dresden)
//
//------------------------------------------------------------------------------
//
@@ -24,13 +24,16 @@
//
//==============================================================================
-package common.iterable;
+package common.functions;
-import java.util.PrimitiveIterator.OfLong;
-
-/** Iterable for a PrimitiveIterator.OfLong */
-public interface IterableLong extends Iterable
+/**
+ * Functional interface for a binary function (int, double) -> int.
+ */
+@FunctionalInterface
+public interface LongDoubleToLongFunction
{
- @Override
- public OfLong iterator();
+ /**
+ * Applies this function to the given arguments.
+ */
+ long applyAsLong(long l, double i);
}
diff --git a/prism/src/common/functions/LongObjToLongFunction.java b/prism/src/common/functions/LongObjToLongFunction.java
new file mode 100644
index 0000000000..3bac121046
--- /dev/null
+++ b/prism/src/common/functions/LongObjToLongFunction.java
@@ -0,0 +1,51 @@
+//==============================================================================
+//
+// Copyright (c) 2020-
+// Authors:
+// * Steffen Maercker (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.functions;
+
+import java.util.Objects;
+import java.util.function.LongUnaryOperator;
+
+/**
+ * Functional interface for a binary function (long, T) -> long.
+ */
+@FunctionalInterface
+public interface LongObjToLongFunction
+{
+ /**
+ * Applies this function to the given arguments.
+ */
+ long applyAsLong(long i, T t);
+
+ /**
+ * Returns a composed function that first applies this function to
+ * its input, and then applies the {@code after} function to the result.
+ */
+ default LongObjToLongFunction andThen(LongUnaryOperator after) {
+ Objects.requireNonNull(after);
+ return (long l, T t) -> after.applyAsLong(applyAsLong(l, t));
+ }
+}
diff --git a/prism/src/common/functions/ObjDoubleFunction.java b/prism/src/common/functions/ObjDoubleFunction.java
new file mode 100644
index 0000000000..6cdd6b307f
--- /dev/null
+++ b/prism/src/common/functions/ObjDoubleFunction.java
@@ -0,0 +1,51 @@
+//==============================================================================
+//
+// Copyright (c) 2016-
+// Authors:
+// * Steffen Maercker (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.functions;
+
+import java.util.Objects;
+import java.util.function.Function;
+
+/**
+ * Functional interface for a binary function (T, double) -> R.
+ */
+@FunctionalInterface
+public interface ObjDoubleFunction
+{
+ /**
+ * Applies this function to the given arguments.
+ */
+ R apply(T t, double d);
+
+ /**
+ * Returns a composed function that first applies this function to
+ * its input, and then applies the {@code after} function to the result.
+ */
+ default ObjDoubleFunction andThen(Function super R, ? extends V> after) {
+ Objects.requireNonNull(after);
+ return (T t, double d) -> after.apply(apply(t, d));
+ }
+}
diff --git a/prism/src/common/functions/ObjIntFunction.java b/prism/src/common/functions/ObjIntFunction.java
new file mode 100644
index 0000000000..33cf0fa85f
--- /dev/null
+++ b/prism/src/common/functions/ObjIntFunction.java
@@ -0,0 +1,51 @@
+//==============================================================================
+//
+// Copyright (c) 2016-
+// Authors:
+// * Steffen Maercker (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.functions;
+
+import java.util.Objects;
+import java.util.function.Function;
+
+/**
+ * Functional interface for a binary function (T, int) -> R.
+ */
+@FunctionalInterface
+public interface ObjIntFunction
+{
+ /**
+ * Applies this function to the given arguments.
+ */
+ R apply(T t, int i);
+
+ /**
+ * Returns a composed function that first applies this function to
+ * its input, and then applies the {@code after} function to the result.
+ */
+ default ObjIntFunction andThen(Function super R, ? extends V> after) {
+ Objects.requireNonNull(after);
+ return (T t, int i) -> after.apply(apply(t, i));
+ }
+}
diff --git a/prism/src/common/functions/ObjLongFunction.java b/prism/src/common/functions/ObjLongFunction.java
new file mode 100644
index 0000000000..b774fbce51
--- /dev/null
+++ b/prism/src/common/functions/ObjLongFunction.java
@@ -0,0 +1,51 @@
+//==============================================================================
+//
+// Copyright (c) 2016-
+// Authors:
+// * Steffen Maercker (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.functions;
+
+import java.util.Objects;
+import java.util.function.Function;
+
+/**
+ * Functional interface for a binary function (T, long) -> R.
+ */
+@FunctionalInterface
+public interface ObjLongFunction
+{
+ /**
+ * Applies this function to the given arguments.
+ */
+ R apply(T t, long l);
+
+ /**
+ * Returns a composed function that first applies this function to
+ * its input, and then applies the {@code after} function to the result.
+ */
+ default ObjLongFunction andThen(Function super R, ? extends V> after) {
+ Objects.requireNonNull(after);
+ return (T t, long l) -> after.apply(apply(t, l));
+ }
+}
diff --git a/prism/src/common/functions/PairPredicateInt.java b/prism/src/common/functions/PairPredicateInt.java
new file mode 100644
index 0000000000..d1b4cb242f
--- /dev/null
+++ b/prism/src/common/functions/PairPredicateInt.java
@@ -0,0 +1,48 @@
+//==============================================================================
+//
+// Copyright (c) 2016-
+// Authors:
+// * Steffen Maercker (TU Dresden)
+// * Joachim Klein (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.functions;
+
+/**
+ * Functional interface for a predicate (int, int) -> boolean.
+ */
+@FunctionalInterface
+public interface PairPredicateInt
+{
+ /**
+ * Evaluates this predicate on the given arguments.
+ */
+ boolean test(int i, int j);
+
+ /**
+ * Returns a predicate that represents the logical negation of this predicate.
+ */
+ default PairPredicateInt negate()
+ {
+ return (i, j) -> !test(i, j);
+ }
+}
diff --git a/prism/src/common/iterable/ArrayIterator.java b/prism/src/common/iterable/ArrayIterator.java
new file mode 100644
index 0000000000..5182034c45
--- /dev/null
+++ b/prism/src/common/iterable/ArrayIterator.java
@@ -0,0 +1,280 @@
+//==============================================================================
+//
+// Copyright (c) 2016-
+// Authors:
+// * Steffen Maercker (TU Dresden)
+// * Marcus Daum (Frauenhofer Institut)
+//
+//------------------------------------------------------------------------------
+//
+// 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.iterable;
+
+import java.util.Objects;
+
+/**
+ * Abstract base class of efficient Iterators over array slices.
+ * Implementations should release the underlying array after iteration.
+ *
+ * @param type of the array elements
+ */
+public abstract class ArrayIterator implements FunctionalIterator
+{
+ protected final int toIndex;
+ protected int nextIndex;
+
+ /**
+ * Iterate over all elements in index interval [fromIndex, toIndex).
+ *
+ * @param fromIndex first index, inclusive
+ * @param toIndex last index, exclusive
+ * @param length length of the array
+ */
+ protected ArrayIterator(int fromIndex, int toIndex, int length)
+ {
+ Objects.checkFromToIndex(fromIndex, toIndex, length);
+ this.nextIndex = fromIndex;
+ this.toIndex = toIndex;
+ }
+
+ @Override
+ public boolean hasNext()
+ {
+ if (nextIndex < toIndex) {
+ return true;
+ }
+ release();
+ return false;
+ }
+
+ @Override
+ public long count()
+ {
+ return Math.max(0, toIndex - nextIndex);
+ }
+
+ /**
+ * Get the index of the next element.
+ */
+ public int nextIndex()
+ {
+ requireNext();
+ return nextIndex;
+ }
+
+ /**
+ * Release reference to the underlying array.
+ */
+ @Override
+ public void release()
+ {
+ nextIndex = toIndex;
+ }
+
+ /**
+ * Generic implementation of an Iterator over an array slice.
+ *
+ * @param type of the array elements
+ */
+ public static class Of extends ArrayIterator
+ {
+ /** Placeholder array after Iterator is exhausted */
+ public static final Object[] EMPTY_OBJECT = new Object[0];
+
+ protected E[] elements;
+
+ /**
+ * Iterate over all elements.
+ */
+ @SafeVarargs
+ public Of(E... elements)
+ {
+ this(elements, 0, elements.length);
+ }
+
+ /**
+ * Iterate over all elements in index interval [fromIndex, toIndex).
+ *
+ * @param fromIndex first index, inclusive
+ * @param toIndex last index, exclusive
+ */
+ public Of(E[] elements, int fromIndex, int toIndex)
+ {
+ super(fromIndex, toIndex, elements.length);
+ this.elements = elements;
+ }
+
+ @Override
+ public E next()
+ {
+ requireNext();
+ return elements[nextIndex++];
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void release()
+ {
+ super.release();
+ elements = (E[]) EMPTY_OBJECT;
+ }
+ }
+
+
+
+ /**
+ * Primitive specialisation for {@code double} of an Iterator over an array slice.
+ */
+ public static class OfDouble extends ArrayIterator implements FunctionalPrimitiveIterator.OfDouble
+ {
+ /** Placeholder array after Iterator is exhausted */
+ public static final double[] EMPTY_DOUBLE = new double[0];
+
+ protected double[] elements;
+
+ /**
+ * Iterate over all elements.
+ */
+ public OfDouble(double... elements)
+ {
+ this(elements, 0, elements.length);
+ }
+
+ /**
+ * Iterate over all elements in index interval [fromIndex, toIndex).
+ *
+ * @param fromIndex first index, inclusive
+ * @param toIndex last index, exclusive
+ */
+ public OfDouble(double[] elements, int fromIndex, int toIndex)
+ {
+ super(fromIndex, toIndex, elements.length);
+ this.elements = elements;
+ }
+
+ @Override
+ public double nextDouble()
+ {
+ requireNext();
+ return elements[nextIndex++];
+ }
+
+ @Override
+ public void release()
+ {
+ super.release();
+ elements = EMPTY_DOUBLE;
+ }
+ }
+
+
+
+ /**
+ * Primitive specialisation for {@code int} of an Iterator over an array slice.
+ */
+ public static class OfInt extends ArrayIterator implements FunctionalPrimitiveIterator.OfInt
+ {
+ /** Placeholder array after Iterator is exhausted */
+ public static final int[] EMPTY_INT = new int[0];
+
+ protected int[] elements;
+
+ /**
+ * Iterate over all elements.
+ */
+ public OfInt(int... elements)
+ {
+ this(elements, 0, elements.length);
+ }
+
+ /**
+ * Iterate over all elements in index interval [fromIndex, toIndex).
+ *
+ * @param fromIndex first index, inclusive
+ * @param toIndex last index, exclusive
+ */
+ public OfInt(int[] elements, int fromIndex, int toIndex)
+ {
+ super(fromIndex, toIndex, elements.length);
+ this.elements = elements;
+ }
+
+ @Override
+ public int nextInt()
+ {
+ requireNext();
+ return elements[nextIndex++];
+ }
+
+ @Override
+ public void release()
+ {
+ super.release();
+ elements = EMPTY_INT;
+ }
+ }
+
+
+
+ /**
+ * Primitive specialisation for {@code long} of an Iterator over an array slice.
+ */
+ public static class OfLong extends ArrayIterator implements FunctionalPrimitiveIterator.OfLong
+ {
+ /** Placeholder array after Iterator is exhausted */
+ public static final long[] EMPTY_LONG = new long[0];
+
+ protected long[] elements;
+
+ /**
+ * Iterate over all elements.
+ */
+ public OfLong(long... elements)
+ {
+ this(elements, 0, elements.length);
+ }
+
+ /**
+ * Iterate over all elements in index interval [fromIndex, toIndex).
+ *
+ * @param fromIndex first index, inclusive
+ * @param toIndex last index, exclusive
+ */
+ public OfLong(long[] elements, int fromIndex, int toIndex)
+ {
+ super(fromIndex, toIndex, elements.length);
+ this.elements = elements;
+ }
+
+ @Override
+ public long nextLong()
+ {
+ requireNext();
+ return elements[nextIndex++];
+ }
+
+ @Override
+ public void release()
+ {
+ super.release();
+ elements = EMPTY_LONG;
+ }
+ }
+}
diff --git a/prism/src/common/iterable/CartesianProduct.java b/prism/src/common/iterable/CartesianProduct.java
new file mode 100644
index 0000000000..7c573ab814
--- /dev/null
+++ b/prism/src/common/iterable/CartesianProduct.java
@@ -0,0 +1,212 @@
+//==============================================================================
+//
+// Copyright (c) 2018-
+// Authors:
+// * Steffen Maercker (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.iterable;
+
+import java.lang.reflect.Array;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.function.Function;
+
+import common.IteratorTools;
+
+/**
+ * This class provides static methods to construct
+ * the Cartesian product of a set of iterables.
+ * The implementation computes the tuples on the fly for space efficiency.
+ * It relies on an efficient implementation of {@code flatMap}.
+ *
+ * Since Stream::flatMap preallocates memory for the complete stream,
+ * we have to use the alternative implementation from FunctionalIterable.
+ *
+ */
+public class CartesianProduct
+{
+ /**
+ * Variant of the Cartesian product with {@code Object} as common super-type of the tuple/iterable elements.
+ * Elements of the product are distinct and safe to store/use elsewhere.
+ *
+ * @param iterables iterables to build Cartesian product from
+ * @see #of(Iterable)
+ */
+ public static FunctionalIterable