All Downloads are FREE. Search and download functionalities are using the official Maven repository.

fj.test.Arbitrary Maven / Gradle / Ivy

Go to download

Functional Java is an open source library that supports closures for the Java programming language

The newest version!
package fj.test;

import fj.F;
import fj.F2;
import fj.F3;
import fj.F4;
import fj.F5;
import fj.F6;
import fj.F7;
import fj.F8;
import fj.Function;
import fj.Bottom;

import static fj.Function.compose;
import static fj.P.p;

import fj.P;
import fj.P1;
import fj.P2;
import fj.P3;
import fj.P4;
import fj.P5;
import fj.P6;
import fj.P7;
import fj.P8;
import fj.data.*;
import fj.LcgRng;
import fj.Ord;

import static fj.data.Enumerator.charEnumerator;
import static fj.data.List.asString;
import static fj.data.List.list;

import fj.data.List;
import fj.data.Set;

import static fj.data.Stream.range;
import static fj.test.Gen.choose;
import static fj.test.Gen.elements;
import static fj.test.Gen.fail;
import static fj.test.Gen.frequency;
import static fj.test.Gen.listOf;
import static fj.test.Gen.oneOf;
import static fj.test.Gen.promote;
import static fj.test.Gen.sized;
import static fj.test.Gen.value;

import static java.lang.Math.abs;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.*;

import static java.util.Locale.getAvailableLocales;
import static java.util.EnumSet.copyOf;

import java.util.HashMap;
import java.util.HashSet;
import java.util.PriorityQueue;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.SynchronousQueue;

/**
 * Common Gen helper functions.
 *
 * @version %build.number%
 */
public final class Arbitrary {

  /**
   * An arbitrary for functions.
   *
   * @param c The cogen for the function domain.
   * @param a The arbitrary for the function codomain.
   * @return An arbitrary for functions.
   */
  public static  Gen> arbF(final Cogen c, final Gen a) {
    return promote(x -> c.cogen(x, a));
  }

    public static  Gen> arbReader(Cogen aa, Gen ab) {
        return arbF(aa, ab).map(Reader::unit);
    }

    /**
     * An arbitrary for state.
     */
    public static  Gen> arbState(Gen as, Cogen cs, Gen aa) {
        return arbF(cs, arbP2(as, aa)).map(State::unit);
    }

    /**
     * An arbitrary for the LcgRng.
     */
    public static  Gen arbLcgRng() {
        return Arbitrary.arbLong.map(LcgRng::new);
    }

  /**
   * An arbitrary for functions.
   *
   * @param a The arbitrary for the function codomain.
   * @return An arbitrary for functions.
   */
  public static  Gen> arbFInvariant(final Gen a) {
    return a.map(Function.constant());
  }

  /**
   * An arbitrary for function-2.
   *
   * @param ca A cogen for the part of the domain of the function.
   * @param cb A cogen for the part of the domain of the function.
   * @param a  An arbitrary for the codomain of the function.
   * @return An arbitrary for function-2.
   */
  public static  Gen> arbF2(final Cogen ca, final Cogen cb,
                                                 final Gen a) {
    return arbF(ca, arbF(cb, a)).map(Function.uncurryF2());
  }

  /**
   * An arbitrary for function-2.
   *
   * @param a The arbitrary for the function codomain.
   * @return An arbitrary for function-2.
   */
  public static  Gen> arbF2Invariant(final Gen a) {
    return a.map(compose(Function.uncurryF2(), compose(Function.constant(), Function.constant())));
  }

  /**
   * An arbitrary for function-3.
   *
   * @param ca A cogen for the part of the domain of the function.
   * @param cb A cogen for the part of the domain of the function.
   * @param cc A cogen for the part of the domain of the function.
   * @param a  An arbitrary for the codomain of the function.
   * @return An arbitrary for function-3.
   */
  public static  Gen> arbF3(final Cogen ca, final Cogen cb,
                                                       final Cogen cc, final Gen a) {
    return arbF(ca, arbF(cb, arbF(cc, a))).map(Function.uncurryF3());
  }

  /**
   * An arbitrary for function-3.
   *
   * @param a The arbitrary for the function codomain.
   * @return An arbitrary for function-3.
   */
  public static  Gen> arbF3Invariant(final Gen a) {
    return a.map(compose(Function.uncurryF3(), compose(Function.constant(),
                                                                                 compose(
                                                                                     Function.constant(),
                                                                                     Function.constant()))));
  }

  /**
   * An arbitrary for function-4.
   *
   * @param ca A cogen for the part of the domain of the function.
   * @param cb A cogen for the part of the domain of the function.
   * @param cc A cogen for the part of the domain of the function.
   * @param cd A cogen for the part of the domain of the function.
   * @param a  An arbitrary for the codomain of the function.
   * @return An arbitrary for function-4.
   */
  public static  Gen> arbF4(final Cogen ca, final Cogen cb,
                                                             final Cogen cc, final Cogen cd,
                                                             final Gen a) {
    return arbF(ca, arbF(cb, arbF(cc, arbF(cd, a)))).map(Function.uncurryF4());
  }

  /**
   * An arbitrary for function-4.
   *
   * @param a The arbitrary for the function codomain.
   * @return An arbitrary for function-4.
   */
  public static  Gen> arbF4Invariant(final Gen a) {
    return a.map(compose(Function.uncurryF4(),
                                       compose(Function.constant(),
                                               compose(Function.constant(),
                                                       compose(Function.constant(),
                                                               Function.constant())))));
  }

  /**
   * An arbitrary for function-5.
   *
   * @param ca A cogen for the part of the domain of the function.
   * @param cb A cogen for the part of the domain of the function.
   * @param cc A cogen for the part of the domain of the function.
   * @param cd A cogen for the part of the domain of the function.
   * @param ce A cogen for the part of the domain of the function.
   * @param a  An arbitrary for the codomain of the function.
   * @return An arbitrary for function-5.
   */
  public static  Gen> arbF5(final Cogen ca,
                                                                     final Cogen cb,
                                                                     final Cogen cc,
                                                                     final Cogen cd,
                                                                     final Cogen ce,
                                                                     final Gen a) {
    return arbF(ca, arbF(cb, arbF(cc, arbF(cd, arbF(ce, a))))).map(Function.uncurryF5());
  }

  /**
   * An arbitrary for function-5.
   *
   * @param a The arbitrary for the function codomain.
   * @return An arbitrary for function-5.
   */
  public static  Gen> arbF5Invariant(final Gen a) {
    return a.map(compose(Function.uncurryF5(),
                                       compose(Function.constant(),
                                               compose(Function.constant(),
                                                       compose(Function.constant(),
                                                               compose(Function.constant(),
                                                                       Function.constant()))))));
  }

  /**
   * An arbitrary for function-6.
   *
   * @param ca A cogen for the part of the domain of the function.
   * @param cb A cogen for the part of the domain of the function.
   * @param cc A cogen for the part of the domain of the function.
   * @param cd A cogen for the part of the domain of the function.
   * @param ce A cogen for the part of the domain of the function.
   * @param cf A cogen for the part of the domain of the function.
   * @param a  An arbitrary for the codomain of the function.
   * @return An arbitrary for function-6.
   */
  public static  Gen> arbF6(final Cogen ca,
                                                                           final Cogen cb,
                                                                           final Cogen cc,
                                                                           final Cogen cd,
                                                                           final Cogen ce,
                                                                           final Cogen cf,
                                                                           final Gen a) {
    return arbF(ca, arbF(cb, arbF(cc, arbF(cd, arbF(ce, arbF(cf, a)))))).map(
        Function.uncurryF6());
  }

  /**
   * An arbitrary for function-6.
   *
   * @param a The arbitrary for the function codomain.
   * @return An arbitrary for function-6.
   */
  public static  Gen> arbF6Invariant(final Gen a) {
    return a.map(compose(Function.uncurryF6(),
        compose(Function.>>>>>constant(),
            compose(Function.>>>>constant(),
                compose(Function.>>>constant(),
                    compose(Function.>>constant(),
                        compose(Function.>constant(),
                            Function.constant())))))));
  }

  /**
   * An arbitrary for function-7.
   *
   * @param ca A cogen for the part of the domain of the function.
   * @param cb A cogen for the part of the domain of the function.
   * @param cc A cogen for the part of the domain of the function.
   * @param cd A cogen for the part of the domain of the function.
   * @param ce A cogen for the part of the domain of the function.
   * @param cf A cogen for the part of the domain of the function.
   * @param cg A cogen for the part of the domain of the function.
   * @param a  An arbitrary for the codomain of the function.
   * @return An arbitrary for function-7.
   */
  public static  Gen> arbF7(final Cogen ca,
                                                                                 final Cogen cb,
                                                                                 final Cogen cc,
                                                                                 final Cogen cd,
                                                                                 final Cogen ce,
                                                                                 final Cogen cf,
                                                                                 final Cogen cg,
                                                                                 final Gen a) {
    return arbF(ca, arbF(cb, arbF(cc, arbF(cd, arbF(ce, arbF(cf, arbF(cg, a))))))).map(
        Function.uncurryF7());
  }

  /**
   * An arbitrary for function-7.
   *
   * @param a The arbitrary for the function codomain.
   * @return An arbitrary for function-7.
   */
  public static  Gen> arbF7Invariant(final Gen a) {
    return a.map(compose(Function.uncurryF7(),
        compose(Function.>>>>>>constant(),
            compose(Function.>>>>>constant(),
                compose(Function.>>>>constant(),
                    compose(Function.>>>constant(),
                        compose(Function.>>constant(),
                            compose(Function.>constant(),
                                Function.constant()))))))));
  }

  /**
   * An arbitrary for function-8.
   *
   * @param ca A cogen for the part of the domain of the function.
   * @param cb A cogen for the part of the domain of the function.
   * @param cc A cogen for the part of the domain of the function.
   * @param cd A cogen for the part of the domain of the function.
   * @param ce A cogen for the part of the domain of the function.
   * @param cf A cogen for the part of the domain of the function.
   * @param cg A cogen for the part of the domain of the function.
   * @param ch A cogen for the part of the domain of the function.
   * @param a  An arbitrary for the codomain of the function.
   * @return An arbitrary for function-8.
   */
  public static  Gen> arbF8(final Cogen ca,
                                                                                       final Cogen cb,
                                                                                       final Cogen cc,
                                                                                       final Cogen cd,
                                                                                       final Cogen ce,
                                                                                       final Cogen cf,
                                                                                       final Cogen cg,
                                                                                       final Cogen ch,
                                                                                       final Gen a) {
    return arbF(ca, arbF(cb, arbF(cc, arbF(cd, arbF(ce, arbF(cf, arbF(cg, arbF(ch, a)))))))).map(
        Function.uncurryF8());
  }

  /**
   * An arbitrary for function-8.
   *
   * @param a The arbitrary for the function codomain.
   * @return An arbitrary for function-8.
   */
  public static  Gen> arbF8Invariant(
      final Gen a) {
    return a.map(compose(Function.uncurryF8(),
        compose(Function.>>>>>>>constant(),
            compose(Function.>>>>>>constant(),
                compose(Function.>>>>>constant(),
                    compose(
                        Function.>>>>constant(),
                        compose(Function.>>>constant(),
                            compose(
                                Function.>>constant(),
                                compose(Function.>constant(),
                                    Function.constant())))))))));
  }

  /**
   * An arbitrary implementation for boolean values.
   */
  public static final Gen arbBoolean = elements(true, false);

  /**
   * An arbitrary implementation for integer values.
   */
  public static final Gen arbInteger = sized(i -> choose(-i, i));

  /**
   * An arbitrary implementation for integer values that checks boundary values (0, 1, -1,
   * max, min, max - 1, min + 1) with a frequency of 1% each then generates from {@link
   * #arbInteger} the remainder of the time (93%).
   */
  public static final Gen arbIntegerBoundaries = sized(i -> frequency(list(p(1, value(0)),
                        p(1, value(1)),
                        p(1, value(-1)),
                        p(1, value(Integer.MAX_VALUE)),
                        p(1, value(Integer.MIN_VALUE)),
                        p(1, value(Integer.MAX_VALUE - 1)),
                        p(1, value(Integer.MIN_VALUE + 1)),
                        p(93, arbInteger))));

  /**
   * An arbitrary implementation for long values.
   */
  public static final Gen arbLong =
      arbInteger.bind(arbInteger, i1 -> i2 -> (long) i1 << 32L & i2);

  /**
   * An arbitrary implementation for long values that checks boundary values (0, 1, -1, max,
   * min, max - 1, min + 1) with a frequency of 1% each then generates from {@link #arbLong}
   * the remainder of the time (93%).
   */
  public static final Gen arbLongBoundaries = sized(i -> frequency(list(p(1, value(0L)),
                        p(1, value(1L)),
                        p(1, value(-1L)),
                        p(1, value(Long.MAX_VALUE)),
                        p(1, value(Long.MIN_VALUE)),
                        p(1, value(Long.MAX_VALUE - 1L)),
                        p(1, value(Long.MIN_VALUE + 1L)),
                        p(93, arbLong))));

  /**
   * An arbitrary implementation for byte values.
   */
  public static final Gen arbByte = arbInteger.map(i -> (byte) i.intValue());

  /**
   * An arbitrary implementation for byte values that checks boundary values (0, 1, -1, max,
   * min, max - 1, min + 1) with a frequency of 1% each then generates from {@link #arbByte}
   * the remainder of the time (93%).
   */
  public static final Gen arbByteBoundaries = sized(i -> frequency(list(p(1, value((byte) 0)),
                        p(1, value((byte) 1)),
                        p(1, value((byte) -1)),
                        p(1, value(Byte.MAX_VALUE)),
                        p(1, value(Byte.MIN_VALUE)),
                        p(1, value((byte) (Byte.MAX_VALUE - 1))),
                        p(1, value((byte) (Byte.MIN_VALUE + 1))),
                        p(93, arbByte))));

  /**
   * An arbitrary implementation for short values.
   */
  public static final Gen arbShort = arbInteger.map(i -> (short) i.intValue());

  /**
   * An arbitrary implementation for short values that checks boundary values (0, 1, -1, max,
   * min, max - 1, min + 1) with a frequency of 1% each then generates from {@link #arbShort}
   * the remainder of the time (93%).
   */
  public static final Gen arbShortBoundaries = sized(i -> frequency(list(p(1, value((short) 0)),
                        p(1, value((short) 1)),
                        p(1, value((short) -1)),
                        p(1, value(Short.MAX_VALUE)),
                        p(1, value(Short.MIN_VALUE)),
                        p(1, value((short) (Short.MAX_VALUE - 1))),
                        p(1, value((short) (Short.MIN_VALUE + 1))),
                        p(93, arbShort))));

  /**
   * An arbitrary implementation for character values.
   */
  public static final Gen arbCharacter = choose(0, 65536).map(i -> (char) i.intValue());

  /**
   * An arbitrary implementation for character values that checks boundary values (max, min,
   * max - 1, min + 1) with a frequency of 1% each then generates from {@link #arbCharacter}
   * the remainder of the time (96%).
   */
  public static final Gen arbCharacterBoundaries = sized(i -> frequency(list(p(1, value(Character.MIN_VALUE)),
                        p(1, value((char) (Character.MIN_VALUE + 1))),
                        p(1, value(Character.MAX_VALUE)),
                        p(1, value((char) (Character.MAX_VALUE - 1))),
                        p(95, arbCharacter))));

  /**
   * An arbitrary implementation for double values.
   */
  public static final Gen arbDouble = sized(i -> choose((double) -i, i));

  /**
   * An arbitrary implementation for double values that checks boundary values (0, 1, -1, max,
   * min, min (normal), NaN, -infinity, infinity, max - 1) with a frequency of 1% each then
   * generates from {@link #arbDouble} the remainder of the time (91%).
   */
  public static final Gen arbDoubleBoundaries = sized(i -> frequency(list(p(1, value(0D)),
                        p(1, value(1D)),
                        p(1, value(-1D)),
                        p(1, value(Double.MAX_VALUE)),
                        p(1, value(Double.MIN_VALUE)),
                        p(1, value(Double.NaN)),
                        p(1, value(Double.NEGATIVE_INFINITY)),
                        p(1, value(Double.POSITIVE_INFINITY)),
                        p(1, value(Double.MAX_VALUE - 1D)),
                        p(91, arbDouble))));

  /**
   * An arbitrary implementation for float values.
   */
  public static final Gen arbFloat = arbDouble.map(d -> (float) d.doubleValue());

  /**
   * An arbitrary implementation for float values that checks boundary values (0, 1, -1, max,
   * min, NaN, -infinity, infinity, max - 1) with a frequency of 1% each then generates from
   * {@link #arbFloat} the remainder of the time (91%).
   */
  public static final Gen arbFloatBoundaries = sized(i -> frequency(list(p(1, value(0F)),
                        p(1, value(1F)),
                        p(1, value(-1F)),
                        p(1, value(Float.MAX_VALUE)),
                        p(1, value(Float.MIN_VALUE)),
                        p(1, value(Float.NaN)),
                        p(1, value(Float.NEGATIVE_INFINITY)),
                        p(1, value(Float.POSITIVE_INFINITY)),
                        p(1, value(Float.MAX_VALUE - 1F)),
                        p(91, arbFloat))));

  /**
   * An arbitrary implementation for string values.
   */
  public static final Gen arbString =
      arbList(arbCharacter).map(List::asString);

  /**
   * An arbitrary implementation for string values with characters in the US-ASCII range.
   */
  public static final Gen arbUSASCIIString =
      arbList(arbCharacter).map(cs -> asString(cs.map(c -> (char) (c % 128))));

  /**
   * An arbitrary implementation for string values with alpha-numeric characters.
   */
  public static final Gen arbAlphaNumString =
      arbList(elements(range(charEnumerator, 'a', 'z').append(
          range(charEnumerator, 'A', 'Z')).append(
          range(charEnumerator, '0', '9')).toArray().array(Character[].class))).map(asString());

  /**
   * An arbitrary implementation for string buffer values.
   */
  public static final Gen arbStringBuffer =
      arbString.map(StringBuffer::new);

  /**
   * An arbitrary implementation for string builder values.
   */
  public static final Gen arbStringBuilder =
      arbString.map(StringBuilder::new);

  /**
   * Returns an arbitrary implementation for generators.
   *
   * @param aa an arbitrary implementation for the type over which the generator is defined.
   * @return An arbitrary implementation for generators.
   */
  public static  Gen> arbGen(final Gen aa) {
    return sized(i -> {
      if (i == 0)
        return fail();
      else
        return aa.map(Gen::value).resize(i - 1);
    });
  }

  /**
   * Returns an arbitrary implementation for optional values.
   *
   * @param aa an arbitrary implementation for the type over which the optional value is defined.
   * @return An arbitrary implementation for optional values.
   */
  public static  Gen> arbOption(final Gen aa) {
    return sized(i -> i == 0 ?
           value(Option.none()) :
           aa.map(Option::some).resize(i - 1));
  }

  /**
   * Returns an arbitrary implementation for the disjoint union.
   *
   * @param aa An arbitrary implementation for the type over which one side of the disjoint union is
   *           defined.
   * @param ab An arbitrary implementation for the type over which one side of the disjoint union is
   *           defined.
   * @return An arbitrary implementation for the disjoint union.
   */
  @SuppressWarnings("unchecked")
  public static  Gen> arbEither(final Gen aa, final Gen ab) {
    final Gen> left = aa.map(Either::left);
    final Gen> right = ab.map(Either::right);
    return oneOf(list(left, right));
  }

  /**
   * Returns an arbitrary implementation for lists.
   *
   * @param aa An arbitrary implementation for the type over which the list is defined.
   * @return An arbitrary implementation for lists.
   */
  public static  Gen> arbList(final Gen aa) {
    return listOf(aa);
  }

	/**
	 * Returns an arbitrary list of integers.
	 */
	public static  Gen> arbListInteger() {
		return listOf(arbInteger);
	}

	/**
	 * Returns an arbitrary list of strings.
	 */
	public static  Gen> arbListString() {
		return listOf(arbString);
	}

	/**
	 * Returns an arbitrary list of booleans.
	 */
	public static  Gen> arbListBoolean() {
		return listOf(arbBoolean);
	}

	/**
	 * Returns an arbitrary list of doubles.
	 */
	public static  Gen> arbListDouble() {
		return listOf(arbDouble);
	}

	public static  Gen> arbNonEmptyList(final Gen aa) {
    return Gen.listOf1(aa).map(list -> NonEmptyList.fromList(list).some());
  }

    /**
     * Returns an arbitrary Validation for the given arbitrary parameters.
     */
    public static  Gen> arbValidation(final Gen aa, final Gen ab) {
        return arbBoolean.bind(bool -> bool ? ab.map(Validation::success) : aa.map(Validation::fail));
    }

  /**
   * Returns an arbitrary implementation for streams.
   *
   * @param aa An arbitrary implementation for the type over which the stream is defined.
   * @return An arbitrary implementation for streams.
   */
  public static  Gen> arbStream(final Gen aa) {
    return arbList(aa).map(List::toStream);
  }

  /**
   * Returns an arbitrary implementation for arrays.
   *
   * @param aa An arbitrary implementation for the type over which the array is defined.
   * @return An arbitrary implementation for arrays.
   */
  public static  Gen> arbArray(final Gen aa) {
    return arbList(aa).map(List::toArray);
  }

  /**
   * Returns an arbitrary implementation for sequences.
   *
   * @param aa An arbitrary implementation for the type over which the sequence is defined.
   * @return An arbitrary implementation for sequences.
   */
  @SuppressWarnings("unchecked")
  public static  Gen> arbSeq(final Gen aa) {
    return arbArray(aa).map(Seq::iterableSeq);
  }

	public static  Gen> arbSet(Ord ord, final Gen aa) {
		return arbList(aa).map(list -> Set.iterableSet(ord, list));
	}

    public static  Gen> arbSet(Ord ord, final Gen aa, int max) {
        return choose(0, max).bind(i -> Gen.sequenceN(i, aa)).map(list -> Set.iterableSet(ord, list));
    }


    /**
   * Returns an arbitrary implementation for throwables.
   *
   * @param as An arbitrary used for the throwable message.
   * @return An arbitrary implementation for throwables.
   */
  public static Gen arbThrowable(final Gen as) {
    return as.map(Throwable::new);
  }

  /**
   * An arbitrary implementation for throwables.
   */
  public static final Gen arbThrowable = arbThrowable(arbString);

  // BEGIN java.util

  /**
   * Returns an arbitrary implementation for array lists.
   *
   * @param aa An arbitrary implementation for the type over which the array list is defined.
   * @return An arbitrary implementation for array lists.
   */
  public static  Gen> arbArrayList(final Gen aa) {
    return arbArray(aa).map(Array::toJavaList);
  }

  /**
   * An arbitrary implementation for bit sets.
   */
  public static final Gen arbBitSet =
      arbList(arbBoolean).map(bs -> {
        final BitSet s = new BitSet(bs.length());
        bs.zipIndex().foreachDoEffect(bi -> s.set(bi._2(), bi._1()));
        return s;
      });

  /**
   * An arbitrary implementation for calendars.
   */
  public static final Gen arbCalendar = arbLong.map(i -> {
    final Calendar c = Calendar.getInstance();
    c.setTimeInMillis(i);
    return c;
  });

  /**
   * An arbitrary implementation for dates.
   */
  public static final Gen arbDate = arbLong.map(Date::new);

  /**
   * Returns an arbitrary implementation for a Java enumeration.
   *
   * @param clazz The type of enum to return an arbitrary of.
   * @return An arbitrary for instances of the supplied enum type.
   */
  public static > Gen arbEnumValue(final Class clazz) {
    return elements(clazz.getEnumConstants());
  }

  /**
   * Returns an arbitrary implementation for enum maps.
   *
   * @param ak An arbitrary implementation for the type over which the enum map's keys are defined.
   * @param av An arbitrary implementation for the type over which the enum map's values are
   *           defined.
   * @return An arbitrary implementation for enum maps.
   */
  public static , V> Gen> arbEnumMap(final Gen ak,
                                                                           final Gen av) {
    return arbHashtable(ak, av).map(EnumMap::new);
  }

  /**
   * Returns an arbitrary implementation for enum sets.
   *
   * @param aa An arbitrary implementation for the type over which the enum set is defined.
   * @return An arbitrary implementation for enum sets.
   */
  public static > Gen> arbEnumSet(final Gen aa) {
    return arbArray(aa).map(a -> copyOf(a.asJavaList()));
  }

  /**
   * An arbitrary implementation for gregorian calendars.
   */
  public static final Gen arbGregorianCalendar =
      arbLong.map(i -> {
        final GregorianCalendar c = new GregorianCalendar();
        c.setTimeInMillis(i);
        return c;
      });

  /**
   * Returns an arbitrary implementation for hash maps.
   *
   * @param ak An arbitrary implementation for the type over which the hash map's keys are defined.
   * @param av An arbitrary implementation for the type over which the hash map's values are
   *           defined.
   * @return An arbitrary implementation for hash maps.
   */
  public static  Gen> arbHashMap(final Gen ak, final Gen av) {
    return arbHashtable(ak, av).map(HashMap::new);
  }

  /**
   * Returns an arbitrary implementation for hash sets.
   *
   * @param aa An arbitrary implementation for the type over which the hash set is defined.
   * @return An arbitrary implementation for hash sets.
   */
  public static  Gen> arbHashSet(final Gen aa) {
    return arbArray(aa).map(a -> new HashSet<>(a.asJavaList()));
  }

  /**
   * Returns an arbitrary implementation for hash tables.
   *
   * @param ak An arbitrary implementation for the type over which the hash table's keys are
   *           defined.
   * @param av An arbitrary implementation for the type over which the hash table's values are
   *           defined.
   * @return An arbitrary implementation for hash tables.
   */
  public static  Gen> arbHashtable(final Gen ak, final Gen av) {
    return arbList(ak).bind(arbList(av), ks -> vs -> {
      final Hashtable t = new Hashtable<>();

      ks.zip(vs).foreachDoEffect(kv -> t.put(kv._1(), kv._2()));

      return t;
    });
  }

  /**
   * Returns an arbitrary implementation for identity hash maps.
   *
   * @param ak An arbitrary implementation for the type over which the identity hash map's keys are
   *           defined.
   * @param av An arbitrary implementation for the type over which the identity hash map's values
   *           are defined.
   * @return An arbitrary implementation for identity hash maps.
   */
  public static  Gen> arbIdentityHashMap(final Gen ak,
                                                                           final Gen av) {
    return arbHashtable(ak, av).map(IdentityHashMap::new);
  }

  /**
   * Returns an arbitrary implementation for linked hash maps.
   *
   * @param ak An arbitrary implementation for the type over which the linked hash map's keys are
   *           defined.
   * @param av An arbitrary implementation for the type over which the linked hash map's values are
   *           defined.
   * @return An arbitrary implementation for linked hash maps.
   */
  public static  Gen> arbLinkedHashMap(final Gen ak, final Gen av) {
    return arbHashtable(ak, av).map(LinkedHashMap::new);
  }

  /**
   * Returns an arbitrary implementation for hash sets.
   *
   * @param aa An arbitrary implementation for the type over which the hash set is defined.
   * @return An arbitrary implementation for hash sets.
   */
  public static  Gen> arbLinkedHashSet(final Gen aa) {
    return arbArray(aa).map(a -> new LinkedHashSet<>(a.asJavaList()));
  }

  /**
   * Returns an arbitrary implementation for linked lists.
   *
   * @param aa An arbitrary implementation for the type over which the linked list is defined.
   * @return An arbitrary implementation for linked lists.
   */
  public static  Gen> arbLinkedList(final Gen aa) {
    return arbArray(aa).map(a -> new LinkedList<>(a.asJavaList()));
  }

  /**
   * Returns an arbitrary implementation for priority queues.
   *
   * @param aa An arbitrary implementation for the type over which the priority queue is defined.
   * @return An arbitrary implementation for priority queues.
   */
  public static  Gen> arbPriorityQueue(final Gen aa) {
    return arbArray(aa).map(a -> new PriorityQueue<>(a.asJavaList()));
  }

  /**
   * An arbitrary implementation for properties.
   */
  public static final Gen arbProperties =
      arbHashtable(arbString, arbString).map(ht -> {
        final Properties p = new Properties();

        for (final Map.Entry entry : ht.entrySet()) {
          p.setProperty(entry.getKey(), entry.getValue());
        }

        return p;
      });

  /**
   * Returns an arbitrary implementation for stacks.
   *
   * @param aa An arbitrary implementation for the type over which the stack is defined.
   * @return An arbitrary implementation for stacks.
   */
  public static  Gen> arbStack(final Gen aa) {
    return arbArray(aa).map(a -> {
      final Stack s = new Stack<>();
      s.addAll(a.asJavaList());
      return s;
    });
  }

  /**
   * Returns an arbitrary implementation for java.util tree maps.
   *
   * @param ak An arbitrary implementation for the type over which the tree map's keys are defined.
   * @param av An arbitrary implementation for the type over which the tree map's values are
   *           defined.
   * @return An arbitrary implementation for tree maps.
   */
  public static  Gen> arbJavaTreeMap(final Gen ak, final Gen av) {
    return arbHashtable(ak, av).map(java.util.TreeMap::new);
  }

    /**
     * Returns an arbitrary implementation for tree maps.
     */
    public static  Gen> arbTreeMap(Ord ord, Gen>> al) {
        return al.map(list -> fj.data.TreeMap.iterableTreeMap(ord, list));
    }

    /**
     * Returns an arbitrary implementation for tree maps.
     */
    public static  Gen> arbTreeMap(Ord ord, Gen ak, Gen av) {
        return arbTreeMap(ord, arbList(arbP2(ak, av)));
    }

    /**
     * Returns an arbitrary implementation for tree maps where the map size is the given arbitrary integer.
     */
    public static  Gen> arbTreeMap(Ord ord, Gen ak, Gen av, Gen ai) {
        Gen>> gl2 = ai.bind(i -> {
            if (i < 0) {
                throw Bottom.error("Undefined: arbitrary natural is negative (" + i + ")");
            }
            return Gen.sequenceN(Math.max(i, 0), arbP2(ak, av));
        });
        return arbTreeMap(ord, gl2);
    }

    /**
     * Returns an arbitrary implementation for tree maps where the size is less than or equal to the max size.
     */
    public static  Gen> arbTreeMap(Ord ord, Gen ak, Gen av, int maxSize) {
        if (maxSize < 0) {
          throw Bottom.error("Undefined: arbitrary natural is negative (" + maxSize + ")");
        }
        return arbTreeMap(ord, ak, av, choose(0, maxSize));
    }

  /**
   * Returns an arbitrary implementation for tree sets.
   *
   * @param aa An arbitrary implementation for the type over which the tree set is defined.
   * @return An arbitrary implementation for tree sets.
   */
  public static  Gen> arbTreeSet(final Gen aa) {
    return arbArray(aa).map(a -> new TreeSet<>(a.asJavaList()));
  }

  /**
   * Returns an arbitrary implementation for vectors.
   *
   * @param aa An arbitrary implementation for the type over which the vector is defined.
   * @return An arbitrary implementation for vectors.
   */
  @SuppressWarnings("UseOfObsoleteCollectionType")
  public static  Gen> arbVector(final Gen aa) {
    return arbArray(aa).map(a -> new Vector<>(a.asJavaList()));
  }

  /**
   * Returns an arbitrary implementation for weak hash maps.
   *
   * @param ak An arbitrary implementation for the type over which the weak hash map's keys are
   *           defined.
   * @param av An arbitrary implementation for the type over which the weak hash map's values are
   *           defined.
   * @return An arbitrary implementation for weak hash maps.
   */
  public static  Gen> arbWeakHashMap(final Gen ak, final Gen av) {
    return arbHashtable(ak, av).map(WeakHashMap::new);
  }

  // END java.util

  // BEGIN java.util.concurrent

  /**
   * Returns an arbitrary implementation for array blocking queues.
   *
   * @param aa An arbitrary implementation for the type over which the array blocking queue is
   *           defined.
   * @return An arbitrary implementation for array blocking queues.
   */
  public static  Gen> arbArrayBlockingQueue(final Gen aa) {
    return arbArray(aa).bind(arbInteger, arbBoolean,
        a -> capacity -> fair -> new ArrayBlockingQueue<>(a.length() + abs(capacity),
            fair, a.asJavaList()));
  }

  /**
   * Returns an arbitrary implementation for concurrent hash maps.
   *
   * @param ak An arbitrary implementation for the type over which the concurrent hash map's keys
   *           are defined.
   * @param av An arbitrary implementation for the type over which the concurrent hash map's values
   *           are defined.
   * @return An arbitrary implementation for concurrent hash maps.
   */
  public static  Gen> arbConcurrentHashMap(final Gen ak,
                                                                               final Gen av) {
    return arbHashtable(ak, av).map(ConcurrentHashMap::new);
  }

  /**
   * Returns an arbitrary implementation for concurrent linked queues.
   *
   * @param aa An arbitrary implementation for the type over which the concurrent linked queue is
   *           defined.
   * @return An arbitrary implementation for concurrent linked queues.
   */
  public static  Gen> arbConcurrentLinkedQueue(final Gen aa) {
    return arbArray(aa).map(a -> new ConcurrentLinkedQueue<>(a.asJavaList()));
  }

  /**
   * Returns an arbitrary implementation for copy-on-write array lists.
   *
   * @param aa An arbitrary implementation for the type over which the copy-on-write array list is
   *           defined.
   * @return An arbitrary implementation for copy-on-write array lists.
   */
  public static  Gen> arbCopyOnWriteArrayList(final Gen aa) {
    return arbArray(aa).map(a -> new CopyOnWriteArrayList<>(a.asJavaList()));
  }

  /**
   * Returns an arbitrary implementation for copy-on-write array sets.
   *
   * @param aa An arbitrary implementation for the type over which the copy-on-write array set is
   *           defined.
   * @return An arbitrary implementation for copy-on-write array sets.
   */
  public static  Gen> arbCopyOnWriteArraySet(final Gen aa) {
    return arbArray(aa).map(a -> new CopyOnWriteArraySet<>(a.asJavaList()));
  }

  /**
   * Returns an arbitrary implementation for delay queues.
   *
   * @param aa An arbitrary implementation for the type over which the delay queue is defined.
   * @return An arbitrary implementation for delay queues.
   */
  public static  Gen> arbDelayQueue(final Gen aa) {
    return arbArray(aa).map(a -> new DelayQueue<>(a.asJavaList()));
  }

  /**
   * Returns an arbitrary implementation for linked blocking queues.
   *
   * @param aa An arbitrary implementation for the type over which the linked blocking queue is
   *           defined.
   * @return An arbitrary implementation for linked blocking queues.
   */
  public static  Gen> arbLinkedBlockingQueue(final Gen aa) {
    return arbArray(aa).map(a -> new LinkedBlockingQueue<>(a.asJavaList()));
  }

  /**
   * Returns an arbitrary implementation for priority blocking queues.
   *
   * @param aa An arbitrary implementation for the type over which the priority blocking queue is
   *           defined.
   * @return An arbitrary implementation for priority blocking queues.
   */
  public static  Gen> arbPriorityBlockingQueue(final Gen aa) {
    return arbArray(aa).map(a -> new PriorityBlockingQueue<>(a.asJavaList()));
  }

  /**
   * Returns an arbitrary implementation for priority blocking queues.
   *
   * @param aa An arbitrary implementation for the type over which the priority blocking queue is
   *           defined.
   * @return An arbitrary implementation for priority blocking queues.
   */
  public static  Gen> arbSynchronousQueue(final Gen aa) {
    return arbArray(aa).bind(arbBoolean, a -> fair -> {
      final SynchronousQueue q = new SynchronousQueue<>(fair);
      q.addAll(a.asJavaList());
      return q;
    });
  }

  // END java.util.concurrent

  // BEGIN java.sql

  /**
   * An arbitrary implementation for SQL dates.
   */
  public static final Gen arbSQLDate = arbLong.map(java.sql.Date::new);

  /**
   * An arbitrary implementation for SQL times.
   */
  public static final Gen Gen> arbP1(final Gen aa) {
    return aa.map(P::p);
  }

  /**
   * Returns an arbitrary implementation for product-2 values.
   *
   * @param aa An arbitrary implementation for one of the types over which the product-2 is
   *           defined.
   * @param ab An Arbitrary implementation for one of the types over which the product-2 is
   *           defined.
   * @return An arbitrary implementation for product-2 values.
   */
  public static  Gen> arbP2(final Gen aa, final Gen ab) {
    return aa.bind(ab, a -> b -> p(a, b));
  }

  /**
   * Returns an arbitrary implementation for product-3 values.
   *
   * @param aa An arbitrary implementation for one of the types over which the product-3 is
   *           defined.
   * @param ab An Arbitrary implementation for one of the types over which the product-3 is
   *           defined.
   * @param ac An arbitrary implementation for one of the types over which the product-3 is
   *           defined.
   * @return An arbitrary implementation for product-3 values.
   */
  public static  Gen> arbP3(final Gen aa, final Gen ab,
                                                 final Gen ac) {
    return aa.bind(ab, ac, a -> b -> c -> p(a, b, c));
  }

  /**
   * Returns an arbitrary implementation for product-4 values.
   *
   * @param aa An arbitrary implementation for one of the types over which the product-4 is
   *           defined.
   * @param ab An Arbitrary implementation for one of the types over which the product-4 is
   *           defined.
   * @param ac An arbitrary implementation for one of the types over which the product-4 is
   *           defined.
   * @param ad An arbitrary implementation for one of the types over which the product-4 is
   *           defined.
   * @return An arbitrary implementation for product-4 values.
   */
  public static  Gen> arbP4(final Gen aa, final Gen ab,
                                                       final Gen ac, final Gen ad) {
    return aa.bind(ab, ac, ad, a -> b -> c -> d -> p(a, b, c, d));
  }

  /**
   * Returns an arbitrary implementation for product-5 values.
   *
   * @param aa An arbitrary implementation for one of the types over which the product-5 is
   *           defined.
   * @param ab An Arbitrary implementation for one of the types over which the product-5 is
   *           defined.
   * @param ac An arbitrary implementation for one of the types over which the product-5 is
   *           defined.
   * @param ad An arbitrary implementation for one of the types over which the product-5 is
   *           defined.
   * @param ae An arbitrary implementation for one of the types over which the product-5 is
   *           defined.
   * @return An arbitrary implementation for product-5 values.
   */
  public static  Gen> arbP5(final Gen aa, final Gen ab,
                                                             final Gen ac, final Gen ad,
                                                             final Gen ae) {
    return aa.bind(ab, ac, ad, ae, a -> b -> c -> d -> e -> p(a, b, c, d, e));
  }

  /**
   * Returns an arbitrary implementation for product-6 values.
   *
   * @param aa An arbitrary implementation for one of the types over which the product-6 is
   *           defined.
   * @param ab An Arbitrary implementation for one of the types over which the product-6 is
   *           defined.
   * @param ac An arbitrary implementation for one of the types over which the product-6 is
   *           defined.
   * @param ad An arbitrary implementation for one of the types over which the product-6 is
   *           defined.
   * @param ae An arbitrary implementation for one of the types over which the product-6 is
   *           defined.
   * @param af An arbitrary implementation for one of the types over which the product-7 is
   *           defined.
   * @return An arbitrary implementation for product-6 values.
   */
  public static  Gen> arbP6(final Gen aa, final Gen ab,
                                                                     final Gen ac, final Gen ad,
                                                                     final Gen ae,
                                                                     final Gen af) {
    return aa.bind(ab, ac, ad, ae, af,
        a -> b -> c -> d -> e -> f -> p(a, b, c, d, e, f));
  }

  /**
   * Returns an arbitrary implementation for product-7 values.
   *
   * @param aa An arbitrary implementation for one of the types over which the product-7 is
   *           defined.
   * @param ab An Arbitrary implementation for one of the types over which the product-7 is
   *           defined.
   * @param ac An arbitrary implementation for one of the types over which the product-7 is
   *           defined.
   * @param ad An arbitrary implementation for one of the types over which the product-7 is
   *           defined.
   * @param ae An arbitrary implementation for one of the types over which the product-7 is
   *           defined.
   * @param af An arbitrary implementation for one of the types over which the product-7 is
   *           defined.
   * @param ag An arbitrary implementation for one of the types over which the product-8 is
   *           defined.
   * @return An arbitrary implementation for product-7 values.
   */
  public static  Gen> arbP7(final Gen aa,
                                                                           final Gen ab,
                                                                           final Gen ac,
                                                                           final Gen ad,
                                                                           final Gen ae,
                                                                           final Gen af,
                                                                           final Gen ag) {
    return aa.bind(ab, ac, ad, ae, af, ag,
        a -> b -> c -> d -> e -> f -> g -> p(a, b, c, d, e, f, g));
  }

  /**
   * Returns an arbitrary implementation for product-8 values.
   *
   * @param aa An arbitrary implementation for one of the types over which the product-8 is
   *           defined.
   * @param ab An Arbitrary implementation for one of the types over which the product-8 is
   *           defined.
   * @param ac An arbitrary implementation for one of the types over which the product-8 is
   *           defined.
   * @param ad An arbitrary implementation for one of the types over which the product-8 is
   *           defined.
   * @param ae An arbitrary implementation for one of the types over which the product-8 is
   *           defined.
   * @param af An arbitrary implementation for one of the types over which the product-8 is
   *           defined.
   * @param ag An arbitrary implementation for one of the types over which the product-8 is
   *           defined.
   * @param ah An arbitrary implementation for one of the types over which the product-8 is
   *           defined.
   * @return An arbitrary implementation for product-8 values.
   */
  public static  Gen> arbP8(final Gen aa,
                                                                                 final Gen ab,
                                                                                 final Gen ac,
                                                                                 final Gen ad,
                                                                                 final Gen ae,
                                                                                 final Gen af,
                                                                                 final Gen ag,
                                                                                 final Gen ah) {
    return aa.bind(ab, ac, ad, ae, af, ag, ah,
        a -> b -> c -> d -> e -> f -> g -> h -> p(a, b, c, d, e, f, g, h));
  }

}