From 61701b9f1be7c1de7f32c948e5422bb3b295cc64 Mon Sep 17 00:00:00 2001 From: Joachim Klein Date: Fri, 21 Jul 2017 14:12:54 +0000 Subject: [PATCH] some more helpers for iterators / predicates [with Steffen Maercker] git-svn-id: https://www.prismmodelchecker.org/svn/prism/prism/trunk@12120 bbc10eb1-c90d-0410-af57-cb519fbb1720 --- .../functions/primitive/PairPredicateInt.java | 35 ++ .../common/iterable/FilteringIterable.java | 164 +++++++ .../src/common/iterable/MappingIterator.java | 463 ++++++++++++++++++ .../common/iterable/SingletonIterable.java | 70 +++ 4 files changed, 732 insertions(+) create mode 100644 prism/src/common/functions/primitive/PairPredicateInt.java create mode 100644 prism/src/common/iterable/FilteringIterable.java create mode 100644 prism/src/common/iterable/MappingIterator.java create mode 100644 prism/src/common/iterable/SingletonIterable.java diff --git a/prism/src/common/functions/primitive/PairPredicateInt.java b/prism/src/common/functions/primitive/PairPredicateInt.java new file mode 100644 index 00000000..4c1d8f4a --- /dev/null +++ b/prism/src/common/functions/primitive/PairPredicateInt.java @@ -0,0 +1,35 @@ +//============================================================================== +// +// 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.primitive; + +/** Functional interface for a predicate (int, int) -> boolean */ +@FunctionalInterface +public interface PairPredicateInt +{ + public abstract boolean test(int element1, int element2); +} diff --git a/prism/src/common/iterable/FilteringIterable.java b/prism/src/common/iterable/FilteringIterable.java new file mode 100644 index 00000000..b161b2e9 --- /dev/null +++ b/prism/src/common/iterable/FilteringIterable.java @@ -0,0 +1,164 @@ +//============================================================================== +// +// 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.iterable; + +import java.util.Iterator; +import java.util.PrimitiveIterator; +import java.util.function.DoublePredicate; +import java.util.function.IntPredicate; +import java.util.function.LongPredicate; +import java.util.function.Predicate; + +/** + * Base class for Iterables around FilteringIterators, + * static constructors for deduplicating entries. */ +public abstract class FilteringIterable implements Iterable +{ + protected final Iterable iterable; + + public FilteringIterable(final Iterable iterable) + { + this.iterable = iterable; + } + + public static class Of extends FilteringIterable + { + private Predicate predicate; + + public Of(Iterable iterable, Predicate predicate) + { + super(iterable); + this.predicate = predicate; + } + + @Override + public Iterator iterator() + { + return new FilteringIterator.Of<>(iterable, predicate); + } + } + + public static class OfInt extends FilteringIterable implements IterableInt + { + private IntPredicate predicate; + + public OfInt(IterableInt iterable, IntPredicate predicate) + { + super(iterable); + this.predicate = predicate; + } + + @Override + public PrimitiveIterator.OfInt iterator() + { + return new FilteringIterator.OfInt((IterableInt) iterable, predicate); + } + } + + public static class OfLong extends FilteringIterable implements IterableLong + { + private LongPredicate predicate; + + public OfLong(IterableLong iterable, LongPredicate predicate) + { + super(iterable); + this.predicate = predicate; + } + + @Override + public PrimitiveIterator.OfLong iterator() + { + return new FilteringIterator.OfLong((IterableLong) iterable, predicate); + } + } + + public static class OfDouble extends FilteringIterable implements IterableDouble + { + private DoublePredicate predicate; + + public OfDouble(IterableDouble iterable, DoublePredicate predicate) + { + super(iterable); + this.predicate = predicate; + } + + @Override + public PrimitiveIterator.OfDouble iterator() + { + return new FilteringIterator.OfDouble((IterableDouble) iterable, predicate); + } + } + + public static IterableInt dedupe(IterableInt iterable) + { + return new IterableInt() + { + @Override + public PrimitiveIterator.OfInt iterator() + { + return FilteringIterator.dedupe(iterable.iterator()); + } + }; + } + + public static IterableLong dedupe(IterableLong iterable) + { + return new IterableLong() + { + @Override + public PrimitiveIterator.OfLong iterator() + { + return FilteringIterator.dedupe(iterable.iterator()); + } + }; + } + + public static IterableDouble dedupe(IterableDouble iterable) + { + return new IterableDouble() + { + @Override + public PrimitiveIterator.OfDouble iterator() + { + return FilteringIterator.dedupe(iterable.iterator()); + } + }; + } + + public static Iterable dedupe(Iterable iterable) + { + return new Iterable() + { + @Override + public Iterator iterator() + { + return FilteringIterator.dedupe(iterable.iterator()); + } + }; + } +} diff --git a/prism/src/common/iterable/MappingIterator.java b/prism/src/common/iterable/MappingIterator.java new file mode 100644 index 00000000..8f81d74f --- /dev/null +++ b/prism/src/common/iterable/MappingIterator.java @@ -0,0 +1,463 @@ +package common.iterable; + +import java.util.Iterator; +import java.util.PrimitiveIterator.OfDouble; +import java.util.PrimitiveIterator.OfInt; +import java.util.PrimitiveIterator.OfLong; +import java.util.function.DoubleFunction; +import java.util.function.DoubleToIntFunction; +import java.util.function.DoubleToLongFunction; +import java.util.function.DoubleUnaryOperator; +import java.util.function.Function; +import java.util.function.IntFunction; +import java.util.function.IntToDoubleFunction; +import java.util.function.IntToLongFunction; +import java.util.function.IntUnaryOperator; +import java.util.function.LongFunction; +import java.util.function.LongToDoubleFunction; +import java.util.function.LongToIntFunction; +import java.util.function.LongUnaryOperator; +import java.util.function.ToDoubleFunction; +import java.util.function.ToIntFunction; +import java.util.function.ToLongFunction; + +/** Helpers for mapping Iterators to another Iterator, performing some mapping on the elements */ +public abstract class MappingIterator implements Iterator +{ + protected final Iterator iterator; + + public MappingIterator(Iterable iterable) + { + this(iterable.iterator()); + } + + public MappingIterator(Iterator iterator) + { + this.iterator = iterator; + } + + @Override + public boolean hasNext() + { + return iterator.hasNext(); + } + + @Override + public void remove() + { + iterator.remove(); + } + + /** Map an Iterator to an Iterator using the given mapping function */ + public static class From extends MappingIterator + { + protected final Function function; + + public From(Iterable iterable, Function function) + { + this(iterable.iterator(), function); + } + + public From(Iterator iterator, Function function) + { + super(iterator); + this.function = function; + } + + @Override + public T next() + { + return function.apply(iterator.next()); + } + } + + /** Map an Iterable to a PrimitiveIterator.OfInt */ + public static OfInt toInt(Iterable iterable) + { + return toInt(iterable.iterator()); + } + + /** Map an Iterator to a PrimitiveIterator.OfInt */ + public static OfInt toInt(Iterator iterator) + { + if (iterator instanceof OfInt) { + return (OfInt) iterator; + } + return new ToInt<>(iterator, Integer::intValue); + } + + /** Map an Iterator to a PrimitiveIterator.OfInt using the given mapping function */ + public static class ToInt extends MappingIterator implements OfInt + { + protected ToIntFunction function; + + public ToInt(Iterable iterable, ToIntFunction function) + { + this(iterable.iterator(), function); + } + + public ToInt(Iterator iterator, ToIntFunction function) + { + super(iterator); + this.function = function; + } + + @Override + public int nextInt() + { + return function.applyAsInt(iterator.next()); + } + } + + /** Map an Iterable to a PrimitiveIterator.OfDouble */ + public static OfDouble toDouble(Iterable iterable) + { + return toDouble(iterable.iterator()); + } + + /** Map an Iterator to a PrimitiveIterator.OfDouble */ + public static OfDouble toDouble(Iterator iterator) + { + if (iterator instanceof OfDouble) { + return (OfDouble) iterator; + } + return new ToDouble<>(iterator, Double::doubleValue); + } + + /** Map an Iterator to a PrimitiveIterator.OfDouble using the given mapping function */ + public static class ToDouble extends MappingIterator implements OfDouble + { + protected ToDoubleFunction function; + + public ToDouble(Iterable iterable, ToDoubleFunction function) + { + this(iterable.iterator(), function); + } + + public ToDouble(Iterator iterator, ToDoubleFunction function) + { + super(iterator); + this.function = function; + } + + @Override + public double nextDouble() + { + return function.applyAsDouble(iterator.next()); + } + } + + /** Map an Iterable to a PrimitiveIterator.OfLong */ + public static OfLong toLong(Iterable iterable) + { + return toLong(iterable.iterator()); + } + + /** Map an Iterator to a PrimitiveIterator.OfLong */ + public static OfLong toLong(Iterator iterator) + { + if (iterator instanceof OfLong) { + return (OfLong) iterator; + } + return new ToLong<>(iterator, Long::longValue); + } + + /** Map an Iterator to a PrimitiveIterator.OfLong using the given mapping function */ + public static class ToLong extends MappingIterator implements OfLong + { + protected ToLongFunction function; + + public ToLong(Iterable iterable, ToLongFunction function) + { + this(iterable.iterator(), function); + } + + public ToLong(Iterator iterator, ToLongFunction function) + { + super(iterator); + this.function = function; + } + + @Override + public long nextLong() + { + return function.applyAsLong(iterator.next()); + } + } + + /** Map an iterator over integers to an iterator over T */ + public static class FromInt extends MappingIterator + { + protected IntFunction function; + + public FromInt(IterableInt iterable, IntFunction function) + { + this(iterable.iterator(), function); + } + + public FromInt(OfInt iterator, IntFunction function) + { + super(iterator); + this.function = function; + } + + @Override + public T next() + { + return function.apply(((OfInt) iterator).nextInt()); + } + } + + /** Map an iterator over integers to another iterator over integers */ + public static class FromIntToInt extends MappingIterator implements OfInt + { + protected IntUnaryOperator function; + + public FromIntToInt(IterableInt iterable, IntUnaryOperator function) + { + this(iterable.iterator(), function); + } + + public FromIntToInt(OfInt iterator, IntUnaryOperator function) + { + super(iterator); + this.function = function; + } + + @Override + public int nextInt() + { + return function.applyAsInt(((OfInt) iterator).nextInt()); + } + } + + /** Map an iterator over integers to iterator over doubles */ + public static class FromIntToDouble extends MappingIterator implements OfDouble + { + protected IntToDoubleFunction function; + + public FromIntToDouble(IterableInt iterable, IntToDoubleFunction function) + { + this(iterable.iterator(), function); + } + + public FromIntToDouble(OfInt iterator, IntToDoubleFunction function) + { + super(iterator); + this.function = function; + } + + @Override + public double nextDouble() + { + return function.applyAsDouble(((OfInt) iterator).nextInt()); + } + } + + /** Map an iterator over integers to iterator over longs */ + public static class FromIntToLong extends MappingIterator implements OfLong + { + protected IntToLongFunction function; + + public FromIntToLong(IterableInt iterable, IntToLongFunction function) + { + this(iterable.iterator(), function); + } + + public FromIntToLong(OfInt iterator, IntToLongFunction function) + { + super(iterator); + this.function = function; + } + + @Override + public long nextLong() + { + return function.applyAsLong(((OfInt) iterator).nextInt()); + } + } + + /** Map an iterator over doubles to an iterator over T */ + public static class FromDouble extends MappingIterator + { + protected DoubleFunction function; + + public FromDouble(IterableDouble iterable, DoubleFunction function) + { + this(iterable.iterator(), function); + } + + public FromDouble(OfDouble iterator, DoubleFunction function) + { + super(iterator); + this.function = function; + } + + @Override + public T next() + { + return function.apply(((OfDouble) iterator).nextDouble()); + } + } + + /** Map an iterator over doubles to an iterator over integers */ + public static class FromDoubleToInt extends MappingIterator implements OfInt + { + protected DoubleToIntFunction function; + + public FromDoubleToInt(IterableDouble iterable, DoubleToIntFunction function) + { + this(iterable.iterator(), function); + } + + public FromDoubleToInt(OfDouble iterator, DoubleToIntFunction function) + { + super(iterator); + this.function = function; + } + + @Override + public int nextInt() + { + return function.applyAsInt(((OfDouble) iterator).nextDouble()); + } + } + + /** Map an iterator over doubles to another iterator over doubles */ + public static class FromDoubleToDouble extends MappingIterator implements OfDouble + { + protected DoubleUnaryOperator function; + + public FromDoubleToDouble(IterableDouble iterable, DoubleUnaryOperator function) + { + this(iterable.iterator(), function); + } + + public FromDoubleToDouble(OfDouble iterator, DoubleUnaryOperator function) + { + super(iterator); + this.function = function; + } + + @Override + public double nextDouble() + { + return function.applyAsDouble(((OfDouble) iterator).nextDouble()); + } + } + + /** Map an iterator over doubles to an iterator over longs */ + public static class FromDoubleToLong extends MappingIterator implements OfLong + { + protected DoubleToLongFunction function; + + public FromDoubleToLong(IterableDouble iterable, DoubleToLongFunction function) + { + this(iterable.iterator(), function); + } + + public FromDoubleToLong(OfDouble iterator, DoubleToLongFunction function) + { + super(iterator); + this.function = function; + } + + @Override + public long nextLong() + { + return function.applyAsLong(((OfDouble) iterator).nextDouble()); + } + } + + /** Map an iterator over longs to an iterator over T */ + public static class FromLong extends MappingIterator + { + protected LongFunction function; + + public FromLong(IterableLong iterable, LongFunction function) + { + this(iterable.iterator(), function); + } + + public FromLong(OfLong iterator, LongFunction function) + { + super(iterator); + this.function = function; + } + + @Override + public T next() + { + return function.apply(((OfLong) iterator).nextLong()); + } + } + + /** Map an iterator over longs to an iterator over integers */ + public static class FromLongToInt extends MappingIterator implements OfInt + { + protected LongToIntFunction function; + + public FromLongToInt(IterableLong iterable, LongToIntFunction function) + { + this(iterable.iterator(), function); + } + + public FromLongToInt(OfLong iterator, LongToIntFunction function) + { + super(iterator); + this.function = function; + } + + @Override + public int nextInt() + { + return function.applyAsInt(((OfLong) iterator).nextLong()); + } + } + + /** Map an iterator over longs to an iterator over doubles */ + public static class FromLongToDouble extends MappingIterator implements OfDouble + { + protected LongToDoubleFunction function; + + public FromLongToDouble(IterableLong iterable, LongToDoubleFunction function) + { + this(iterable.iterator(), function); + } + + public FromLongToDouble(OfLong iterator, LongToDoubleFunction function) + { + super(iterator); + this.function = function; + } + + @Override + public double nextDouble() + { + return function.applyAsDouble(((OfLong) iterator).nextLong()); + } + } + + /** Map an iterator over longs to another iterator over longs */ + public static class FromLongToLong extends MappingIterator implements OfLong + { + protected LongUnaryOperator function; + + public FromLongToLong(IterableLong iterable, LongUnaryOperator function) + { + this(iterable.iterator(), function); + } + + public FromLongToLong(OfLong iterator, LongUnaryOperator function) + { + super(iterator); + this.function = function; + } + + @Override + public long nextLong() + { + return function.applyAsLong(((OfLong) iterator).nextLong()); + } + } +} diff --git a/prism/src/common/iterable/SingletonIterable.java b/prism/src/common/iterable/SingletonIterable.java new file mode 100644 index 00000000..ae568213 --- /dev/null +++ b/prism/src/common/iterable/SingletonIterable.java @@ -0,0 +1,70 @@ +package common.iterable; + +import java.util.Iterator; + +public abstract class SingletonIterable implements Iterable +{ + public static class Of extends SingletonIterable + { + final T element; + + public Of(T theElement) + { + element = theElement; + } + + @Override + public Iterator iterator() + { + return new SingletonIterator.Of<>(element); + } + } + + public static class OfInt extends SingletonIterable implements IterableInt + { + final int element; + + public OfInt(int theElement) + { + element = theElement; + } + + @Override + public SingletonIterator.OfInt iterator() + { + return new SingletonIterator.OfInt(element); + } + } + + public static class OfLong extends SingletonIterable implements IterableLong + { + final long element; + + public OfLong(long theElement) + { + element = theElement; + } + + @Override + public SingletonIterator.OfLong iterator() + { + return new SingletonIterator.OfLong(element); + } + } + + public static class OfDouble extends SingletonIterable implements IterableDouble + { + final double element; + + public OfDouble(double theElement) + { + element = theElement; + } + + @Override + public SingletonIterator.OfDouble iterator() + { + return new SingletonIterator.OfDouble(element); + } + } +}