001    package fj.test;
002    
003    import static fj.Function.curry;
004    import static fj.Function.compose2;
005    import static fj.P.p;
006    import fj.F;
007    import fj.F2;
008    import fj.F3;
009    import fj.F4;
010    import fj.F5;
011    import fj.F6;
012    import fj.F7;
013    import fj.F8;
014    import fj.P;
015    import fj.P1;
016    import fj.P2;
017    import static fj.P2.__2;
018    import fj.data.List;
019    import fj.data.Option;
020    import static fj.data.Option.none;
021    import fj.data.Stream;
022    import static fj.test.Arg.arg;
023    import static fj.test.CheckResult.exhausted;
024    import static fj.test.CheckResult.falsified;
025    import static fj.test.CheckResult.genException;
026    import static fj.test.CheckResult.passed;
027    import static fj.test.CheckResult.propException;
028    import static fj.test.CheckResult.proven;
029    import static fj.test.Result.noResult;
030    
031    import static java.lang.Math.round;
032    
033    /**
034     * Represents an algebraic property about a program that may be {@link #check(Rand, int, int, int,
035     * int) checked} for its truth value. For example, it is true that "for all integers (call it x) and
036     * for all integers (call it y), then x + y is equivalent to y + x". This statement is a (algebraic)
037     * property, proposition or theorem that, when checked, will at least (depending on arguments) fail
038     * to be falsified — since there does not exist a counter-example to this statement.
039     *
040     * @version %build.number%<br>
041     *          <ul>
042     *          <li>$LastChangedRevision: 5 $</li>
043     *          <li>$LastChangedDate: 2008-12-06 16:49:43 +1000 (Sat, 06 Dec 2008) $</li>
044     *          <li>$LastChangedBy: tonymorris $</li>
045     *          </ul>
046     */
047    public final class Property {
048      private final F<Integer, F<Rand, Result>> f;
049    
050      private Property(final F<Integer, F<Rand, Result>> f) {
051        this.f = f;
052      }
053    
054      /**
055       * Returns the result of applying the given size and random generator.
056       *
057       * @param i The size to use to obtain a result.
058       * @param r The random generator to use to obtain a result.
059       * @return The result of applying the given size and random generator.
060       */
061      public Result prop(final int i, final Rand r) {
062        return f.f(i).f(r);
063      }
064    
065      /**
066       * Returns a generator of results from this property.
067       *
068       * @return A generator of results from this property.
069       */
070      public Gen<Result> gen() {
071        return Gen.gen(new F<Integer, F<Rand, Result>>() {
072          public F<Rand, Result> f(final Integer i) {
073            return new F<Rand, Result>() {
074              public Result f(final Rand r) {
075                return f.f(i).f(r);
076              }
077            };
078          }
079        });
080      }
081    
082      /**
083       * Performs a conjunction of this property with the given property.
084       *
085       * @param p The property to perform the conjunction with.
086       * @return A conjunction of this property with the given property.
087       */
088      public Property and(final Property p) {
089        return fromGen(gen().bind(p.gen(), new F<Result, F<Result, Result>>() {
090          public F<Result, Result> f(final Result res1) {
091            return new F<Result, Result>() {
092              public Result f(final Result res2) {
093                if (res1.isException() || res1.isFalsified())
094                  return res1;
095                else if (res2.isException() || res2.isFalsified())
096                  return res2;
097                else if (res1.isProven() || res1.isUnfalsified())
098                  return res2;
099                else if (res2.isProven() || res2.isUnfalsified())
100                  return res1;
101                else
102                  return noResult();
103              }
104            };
105          }
106        }));
107      }
108    
109      /**
110       * Performs a disjunction of this property with the given property.
111       *
112       * @param p The property to perform the disjunction with.
113       * @return A disjunction of this property with the given property.
114       */
115      public Property or(final Property p) {
116        return fromGen(gen().bind(p.gen(), new F<Result, F<Result, Result>>() {
117          public F<Result, Result> f(final Result res1) {
118            return new F<Result, Result>() {
119              public Result f(final Result res2) {
120                if (res1.isException() || res1.isFalsified())
121                  return res1;
122                else if (res2.isException() || res2.isFalsified())
123                  return res2;
124                else if (res1.isProven() || res1.isUnfalsified())
125                  return res1;
126                else if (res2.isProven() || res2.isUnfalsified())
127                  return res2;
128                else
129                  return noResult();
130              }
131            };
132          }
133        }));
134      }
135    
136      /**
137       * Performs a sequence of this property with the given property. The returned property holds if
138       * and only if this property and the given property also hold. If one property does not hold, but
139       * the other does, then the returned property will produce the same result and the property that
140       * holds.
141       *
142       * @param p The property to sequence this property with.
143       * @return A sequence of this property with the given property.
144       */
145      public Property sequence(final Property p) {
146        return fromGen(gen().bind(p.gen(), new F<Result, F<Result, Result>>() {
147          public F<Result, Result> f(final Result res1) {
148            return new F<Result, Result>() {
149              public Result f(final Result res2) {
150                if (res1.isException() || res1.isProven() || res1.isUnfalsified())
151                  return res1;
152                else if (res2.isException() || res2.isProven() || res2.isUnfalsified())
153                  return res2;
154                else if (res1.isFalsified())
155                  return res2;
156                else if (res2.isFalsified())
157                  return res1;
158                else
159                  return noResult();
160              }
161            };
162          }
163        }));
164      }
165    
166      /**
167       * Checks this property using the given arguments and produces a result.
168       *
169       * @param r             The random generator to use for checking.
170       * @param minSuccessful The minimum number of successful tests before a result is reached.
171       * @param maxDiscarded  The maximum number of tests discarded because they did not satisfy
172       *                      pre-conditions (i.e. {@link #implies(boolean, P1)}).
173       * @param minSize       The minimum size to use for checking.
174       * @param maxSize       The maximum size to use for checking.
175       * @return A result after checking this property.
176       */
177      public CheckResult check(final Rand r,
178                               final int minSuccessful,
179                               final int maxDiscarded,
180                               final int minSize,
181                               final int maxSize) {
182        int s = 0;
183        int d = 0;
184        float sz = minSize;
185        CheckResult res;
186    
187        while (true) {
188          final float size = s == 0 && d == 0 ? minSize : sz + (maxSize - sz) / (minSuccessful - s);
189          try {
190            final Result x = f.f(round(size)).f(r);
191            if (x.isNoResult())
192              if (d + 1 >= maxDiscarded) {
193                res = exhausted(s, d + 1);
194                break;
195              } else {
196                sz = size;
197                d++;
198              }
199            else if (x.isProven()) {
200              res = proven(x.args().some(), s + 1, d);
201              break;
202            } else if (x.isUnfalsified())
203              if (s + 1 >= minSuccessful) {
204                res = passed(s + 1, d);
205                break;
206              } else {
207                sz = size;
208                s++;
209              }
210            else if (x.isFalsified()) {
211              res = falsified(x.args().some(), s, d);
212              break;
213            } else if (x.isException()) {
214              res = propException(x.args().some(), x.exception().some(), s, d);
215              break;
216            }
217          } catch (final Throwable t) {
218            genException(t, s, d);
219          }
220        }
221    
222        return res;
223      }
224    
225      /**
226       * Checks this property using a {@link Rand#Rand(F, F) standard random generator} and the given
227       * arguments to produce a result.
228       *
229       * @param minSuccessful The minimum number of successful tests before a result is reached.
230       * @param maxDiscarded  The maximum number of tests discarded because they did not satisfy
231       *                      pre-conditions (i.e. {@link #implies(boolean, P1)}).
232       * @param minSize       The minimum size to use for checking.
233       * @param maxSize       The maximum size to use for checking.
234       * @return A result after checking this property.
235       */
236      public CheckResult check(final int minSuccessful,
237                               final int maxDiscarded,
238                               final int minSize,
239                               final int maxSize) {
240        return check(Rand.standard, minSuccessful, maxDiscarded, minSize, maxSize);
241      }
242    
243      /**
244       * Checks this property using the given random generator, 100 minimum successful checks, 500
245       * maximum discarded tests, minimum size of 0, maximum size of 100.
246       *
247       * @param r The random generator.
248       * @return A result after checking this property.
249       */
250      public CheckResult check(final Rand r) {
251        return check(r, 100, 500, 0, 100);
252      }
253    
254      /**
255       * Checks this property using the given random generator, 100 minimum successful checks, 500
256       * maximum discarded tests, the given minimum size and the given maximum size.
257       *
258       * @param r       The random generator.
259       * @param minSize The minimum size to use for checking.
260       * @param maxSize The maximum size to use for checking.
261       * @return A result after checking this property.
262       */
263      public CheckResult check(final Rand r, final int minSize, final int maxSize) {
264        return check(r, 100, 500, minSize, maxSize);
265      }
266    
267      /**
268       * Checks this property using a {@link Rand#Rand(F, F) standard random generator}, 100 minimum
269       * successful checks, 500 maximum discarded tests and the given arguments to produce a result.
270       *
271       * @param minSize The minimum size to use for checking.
272       * @param maxSize The maximum size to use for checking.
273       * @return A result after checking this property.
274       */
275      public CheckResult check(final int minSize,
276                               final int maxSize) {
277        return check(100, 500, minSize, maxSize);
278      }
279    
280      /**
281       * Checks this property using a {@link Rand#Rand(F, F) standard random generator}, 100 minimum
282       * successful checks, 500 maximum discarded tests, minimum size of 0, maximum size of 100.
283       *
284       * @return A result after checking this property.
285       */
286      public CheckResult check() {
287        return check(0, 100);
288      }
289    
290      /**
291       * Checks this property using a {@link Rand#Rand(F, F) standard random generator}, the given minimum
292       * successful checks, 500 maximum discarded tests, minimum size of 0, maximum size of 100.
293       *
294       * @param minSuccessful The minimum number of successful tests before a result is reached.
295       * @return A result after checking this property.
296       */
297      public CheckResult minSuccessful(final int minSuccessful) {
298        return check(minSuccessful, 500, 0, 100);
299      }
300    
301      /**
302       * Checks this property using the given random generator, the given minimum
303       * successful checks, 500 maximum discarded tests, minimum size of 0, maximum size of 100.
304       *
305       * @param r             The random generator.
306       * @param minSuccessful The minimum number of successful tests before a result is reached.
307       * @return A result after checking this property.
308       */
309      public CheckResult minSuccessful(final Rand r, final int minSuccessful) {
310        return check(r, minSuccessful, 500, 0, 100);
311      }
312    
313      /**
314       * Checks this property using a {@link Rand#Rand(F, F) standard random generator}, 100 minimum
315       * successful checks, the given maximum discarded tests, minimum size of 0, maximum size of 100.
316       *
317       * @param maxDiscarded The maximum number of tests discarded because they did not satisfy
318       *                     pre-conditions (i.e. {@link #implies(boolean, P1)}).
319       * @return A result after checking this property.
320       */
321      public CheckResult maxDiscarded(final int maxDiscarded) {
322        return check(100, maxDiscarded, 0, 100);
323      }
324    
325      /**
326       * Checks this property using a the given random generator}, 100 minimum
327       * successful checks, the given maximum discarded tests, minimum size of 0, maximum size of 100.
328       *
329       * @param r            The random generator.
330       * @param maxDiscarded The maximum number of tests discarded because they did not satisfy
331       *                     pre-conditions (i.e. {@link #implies(boolean, P1)}).
332       * @return A result after checking this property.
333       */
334      public CheckResult maxDiscarded(final Rand r, final int maxDiscarded) {
335        return check(r, 100, maxDiscarded, 0, 100);
336      }
337    
338      /**
339       * Checks this property using a {@link Rand#Rand(F, F) standard random generator}, 100 minimum
340       * successful checks, 500 maximum discarded tests, the given minimum size, maximum size of 100.
341       *
342       * @param minSize The minimum size to use for checking.
343       * @return A result after checking this property.
344       */
345      public CheckResult minSize(final int minSize) {
346        return check(100, 500, minSize, 100);
347      }
348    
349      /**
350       * Checks this property using the given random generator, 100 minimum
351       * successful checks, 500 maximum discarded tests, the given minimum size, maximum size of 100.
352       *
353       * @param r       The random generator.
354       * @param minSize The minimum size to use for checking.
355       * @return A result after checking this property.
356       */
357      public CheckResult minSize(final Rand r, final int minSize) {
358        return check(r, 100, 500, minSize, 100);
359      }
360    
361      /**
362       * Checks this property using a {@link Rand#Rand(F, F) standard random generator}, 100 minimum
363       * successful checks, 500 maximum discarded tests, minimum size of 0, the given maximum size.
364       *
365       * @param maxSize The maximum size to use for checking.
366       * @return A result after checking this property.
367       */
368      public CheckResult maxSize(final int maxSize) {
369        return check(100, 500, 0, maxSize);
370      }
371    
372      /**
373       * Checks this property using the given random generator, 100 minimum
374       * successful checks, 500 maximum discarded tests, minimum size of 0, the given maximum size.
375       *
376       * @param r       The random generator.
377       * @param maxSize The maximum size to use for checking.
378       * @return A result after checking this property.
379       */
380      public CheckResult maxSize(final Rand r, final int maxSize) {
381        return check(r, 100, 500, 0, maxSize);
382      }
383    
384      /**
385       * Returns a property that produces a result only if the given condition satisfies. The result
386       * will be taken from the given property.
387       *
388       * @param b The condition that, if satisfied, produces the given property.
389       * @param p The property to return if the condition satisfies.
390       * @return A property that produces a result only if the given condition satisfies.
391       */
392      public static Property implies(final boolean b, final P1<Property> p) {
393        return b ? p._1() : new Property(new F<Integer, F<Rand, Result>>() {
394          public F<Rand, Result> f(final Integer i) {
395            return new F<Rand, Result>() {
396              public Result f(final Rand r) {
397                return noResult();
398              }
399            };
400          }
401        });
402      }
403    
404      /**
405       * Returns a property from the given function.
406       *
407       * @param f The function to construct the returned property with.
408       * @return A property from the given function.
409       */
410      public static Property prop(final F<Integer, F<Rand, Result>> f) {
411        return new Property(f);
412      }
413    
414      /**
415       * Returns a property that always has the given result.
416       *
417       * @param r The result of the returned property.
418       * @return A property that always has the given result.
419       */
420      public static Property prop(final Result r) {
421        return new Property(new F<Integer, F<Rand, Result>>() {
422          public F<Rand, Result> f(final Integer integer) {
423            return new F<Rand, Result>() {
424              public Result f(final Rand x) {
425                return r;
426              }
427            };
428          }
429        });
430      }
431    
432      /**
433       * Returns a property that is either proven (the given condition satsifies) or falsified
434       * otherwise.
435       *
436       * @param b The condition that, if satisfied, returns a property that is proven; otherwise, the
437       *          property is falsified.
438       * @return A property that is either proven (the given condition satsifies) or falsified
439       *         otherwise.
440       */
441      public static Property prop(final boolean b) {
442        return b ? prop(Result.proven(List.<Arg<?>>nil())) : prop(Result.falsified(List.<Arg<?>>nil()));
443      }
444    
445      /**
446       * Constructs a property from a generator of results.
447       *
448       * @param g The generator of results to constructor a property with.
449       * @return A property from a generator of results.
450       */
451      public static Property fromGen(final Gen<Result> g) {
452        return prop(new F<Integer, F<Rand, Result>>() {
453          public F<Rand, Result> f(final Integer i) {
454            return new F<Rand, Result>() {
455              public Result f(final Rand r) {
456                return g.gen(i, r);
457              }
458            };
459          }
460        });
461      }
462    
463      /**
464       * Returns a property where its result is derived from universal quantification across the
465       * application of its arguments.
466       *
467       * @param g      The generator to produces values from to produce the property with.
468       * @param shrink The shrink strategy to use upon falsification.
469       * @param f      The function to produce properties with results.
470       * @return A property where its result is derived from universal quantification across the
471       *         application of its arguments.
472       */
473      public static <A> Property forall(final Gen<A> g, final Shrink<A> shrink, final F<A, P1<Property>> f) {
474        return prop(new F<Integer, F<Rand, Result>>() {
475          public F<Rand, Result> f(final Integer i) {
476            return new F<Rand, Result>() {
477              public Result f(final Rand r) {
478                final class Util {
479                  Option<P2<A, Result>> first(final Stream<A> as, final int shrinks) {
480                    final Stream<Option<P2<A, Result>>> results = as.map(new F<A, Option<P2<A, Result>>>() {
481                      public Option<P2<A, Result>> f(final A a) {
482                        final Result result = exception(f.f(a)).prop(i, r);
483    
484                        return result.toOption().map(new F<Result, P2<A, Result>>() {
485                          public P2<A, Result> f(final Result result) {
486                            return p(a, result.provenAsUnfalsified().addArg(arg(a, shrinks)));
487                          }
488                        });
489                      }
490                    });
491    
492                    if (results.isEmpty())
493                      return none();
494                    else return results.find(new F<Option<P2<A, Result>>, Boolean>() {
495                      public Boolean f(final Option<P2<A, Result>> o) {
496                        return failed(o);
497                      }
498                    }).orSome(new P1<Option<P2<A, Result>>>() {
499                      public Option<P2<A, Result>> _1() {
500                        return results.head();
501                      }
502                    });
503                  }
504    
505                  public boolean failed(final Option<P2<A, Result>> o) {
506                    return o.isSome() && o.some()._2().failed();
507                  }
508                }
509    
510                final Util u = new Util();
511    
512                Option<P2<A, Result>> x = u.first(Stream.single(g.gen(i, r)), 0);
513                final F<P2<A, Result>, Result> __2 = __2();
514                if (u.failed(x)) {
515                  Option<Result> or;
516                  int shrinks = 0;
517    
518                  do {
519                    shrinks++;
520                    or = x.map(__2);
521                    x = u.first(shrink.shrink(x.some()._1()), shrinks);
522                  }
523                  while (u.failed(x));
524    
525                  return noResult(or);
526                } else
527                  return noResult(x.map(__2));
528              }
529            };
530          }
531        });
532      }
533    
534      /**
535       * Returns a property where its result is derived from universal quantification across the
536       * application of its arguments.
537       *
538       * @param aa The arbitrrary to produces values from to produce the property with.
539       * @param sa The shrink strategy to use upon falsification.
540       * @param f  The function to produce properties with results.
541       * @return A property where its result is derived from universal quantification across the
542       *         application of its arguments.
543       */
544      public static <A> Property propertyP(final Arbitrary<A> aa, final Shrink<A> sa, final F<A, P1<Property>> f) {
545        return forall(aa.gen, sa, f);
546      }
547    
548      /**
549       * Returns a property where its result is derived from universal quantification across the
550       * application of its arguments.
551       *
552       * @param aa The arbitrrary to produces values from to produce the property with.
553       * @param sa The shrink strategy to use upon falsification.
554       * @param f  The function to produce properties with results.
555       * @return A property where its result is derived from universal quantification across the
556       *         application of its arguments.
557       */
558      public static <A> Property property(final Arbitrary<A> aa, final Shrink<A> sa, final F<A, Property> f) {
559        return propertyP(aa, sa, P1.curry(f));
560      }
561    
562      /**
563       * Returns a property where its result is derived from universal quantification across the
564       * application of its arguments. No shrinking occurs upon falsification.
565       *
566       * @param aa The arbitrrary to produces values from to produce the property with.
567       * @param f  The function to produce properties with results.
568       * @return A property where its result is derived from universal quantification across the
569       *         application of its arguments.
570       */
571      public static <A> Property propertyP(final Arbitrary<A> aa, final F<A, P1<Property>> f) {
572        return propertyP(aa, Shrink.<A>empty(), f);
573      }
574    
575      /**
576       * Returns a property where its result is derived from universal quantification across the
577       * application of its arguments. No shrinking occurs upon falsification.
578       *
579       * @param aa The arbitrrary to produces values from to produce the property with.
580       * @param f  The function to produce properties with results.
581       * @return A property where its result is derived from universal quantification across the
582       *         application of its arguments.
583       */
584      public static <A> Property property(final Arbitrary<A> aa, final F<A, Property> f) {
585        return propertyP(aa, P1.curry(f));
586      }
587    
588    
589      /**
590       * Returns a property where its result is derived from universal quantification across the
591       * application of its arguments.
592       *
593       * @param aa The arbitrrary to produces values from to produce the property with.
594       * @param ab The arbitrrary to produces values from to produce the property with.
595       * @param sa The shrink strategy to use upon falsification.
596       * @param sb The shrink strategy to use upon falsification.
597       * @param f  The function to produce properties with results.
598       * @return A property where its result is derived from universal quantification across the
599       *         application of its arguments.
600       */
601      public static <A, B> Property propertyP(final Arbitrary<A> aa, final Arbitrary<B> ab, final Shrink<A> sa, final Shrink<B> sb, final F<A, F<B, P1<Property>>> f) {
602        return property(aa, sa, new F<A, Property>() {
603          public Property f(final A a) {
604            return propertyP(ab, sb, new F<B, P1<Property>>() {
605              public P1<Property> f(final B b) {
606                return f.f(a).f(b);
607              }
608            });
609          }
610        });
611      }
612    
613      /**
614       * Returns a property where its result is derived from universal quantification across the
615       * application of its arguments.
616       *
617       * @param aa The arbitrrary to produces values from to produce the property with.
618       * @param ab The arbitrrary to produces values from to produce the property with.
619       * @param sa The shrink strategy to use upon falsification.
620       * @param sb The shrink strategy to use upon falsification.
621       * @param f  The function to produce properties with results.
622       * @return A property where its result is derived from universal quantification across the
623       *         application of its arguments.
624       */
625      public static <A, B> Property property(final Arbitrary<A> aa, final Arbitrary<B> ab, final Shrink<A> sa, final Shrink<B> sb, final F<A, F<B, Property>> f) {
626        return propertyP(aa, ab, sa, sb, compose2(P.<Property>p1(), f));
627      }
628    
629      /**
630       * Returns a property where its result is derived from universal quantification across the
631       * application of its arguments. No shrinking occurs upon falsification.
632       *
633       * @param aa The arbitrrary to produces values from to produce the property with.
634       * @param ab The arbitrrary to produces values from to produce the property with.
635       * @param f  The function to produce properties with results.
636       * @return A property where its result is derived from universal quantification across the
637       *         application of its arguments.
638       */
639      public static <A, B> Property propertyP(final Arbitrary<A> aa, final Arbitrary<B> ab, final F<A, F<B, P1<Property>>> f) {
640        return property(aa, new F<A, Property>() {
641          public Property f(final A a) {
642            return propertyP(ab, new F<B, P1<Property>>() {
643              public P1<Property> f(final B b) {
644                return f.f(a).f(b);
645              }
646            });
647          }
648        });
649      }
650    
651      /**
652       * Returns a property where its result is derived from universal quantification across the
653       * application of its arguments. No shrinking occurs upon falsification.
654       *
655       * @param aa The arbitrrary to produces values from to produce the property with.
656       * @param ab The arbitrrary to produces values from to produce the property with.
657       * @param f  The function to produce properties with results.
658       * @return A property where its result is derived from universal quantification across the
659       *         application of its arguments.
660       */
661      public static <A, B> Property property(final Arbitrary<A> aa, final Arbitrary<B> ab, final F<A, F<B, Property>> f) {
662        return propertyP(aa, ab, compose2(P.<Property>p1(), f));
663      }
664    
665      /**
666       * Returns a property where its result is derived from universal quantification across the
667       * application of its arguments.
668       *
669       * @param aa The arbitrrary to produces values from to produce the property with.
670       * @param ab The arbitrrary to produces values from to produce the property with.
671       * @param sa The shrink strategy to use upon falsification.
672       * @param sb The shrink strategy to use upon falsification.
673       * @param f  The function to produce properties with results.
674       * @return A property where its result is derived from universal quantification across the
675       *         application of its arguments.
676       */
677      public static <A, B> Property propertyP(final Arbitrary<A> aa, final Arbitrary<B> ab, final Shrink<A> sa, final Shrink<B> sb, final F2<A, B, P1<Property>> f) {
678        return propertyP(aa, ab, sa, sb, curry(f));
679      }
680    
681      /**
682       * Returns a property where its result is derived from universal quantification across the
683       * application of its arguments.
684       *
685       * @param aa The arbitrrary to produces values from to produce the property with.
686       * @param ab The arbitrrary to produces values from to produce the property with.
687       * @param sa The shrink strategy to use upon falsification.
688       * @param sb The shrink strategy to use upon falsification.
689       * @param f  The function to produce properties with results.
690       * @return A property where its result is derived from universal quantification across the
691       *         application of its arguments.
692       */
693      public static <A, B> Property property(final Arbitrary<A> aa, final Arbitrary<B> ab, final Shrink<A> sa, final Shrink<B> sb, final F2<A, B, Property> f) {
694        return propertyP(aa, ab, sa, sb, compose2(P.<Property>p1(), curry(f)));
695      }
696    
697      /**
698       * Returns a property where its result is derived from universal quantification across the
699       * application of its arguments. No shrinking occurs upon falsification.
700       *
701       * @param aa The arbitrrary to produces values from to produce the property with.
702       * @param ab The arbitrrary to produces values from to produce the property with.
703       * @param f  The function to produce properties with results.
704       * @return A property where its result is derived from universal quantification across the
705       *         application of its arguments.
706       */
707      public static <A, B> Property propertyP(final Arbitrary<A> aa, final Arbitrary<B> ab, final F2<A, B, P1<Property>> f) {
708        return propertyP(aa, ab, curry(f));
709      }
710    
711      /**
712       * Returns a property where its result is derived from universal quantification across the
713       * application of its arguments. No shrinking occurs upon falsification.
714       *
715       * @param aa The arbitrrary to produces values from to produce the property with.
716       * @param ab The arbitrrary to produces values from to produce the property with.
717       * @param f  The function to produce properties with results.
718       * @return A property where its result is derived from universal quantification across the
719       *         application of its arguments.
720       */
721      public static <A, B> Property property(final Arbitrary<A> aa, final Arbitrary<B> ab, final F2<A, B, Property> f) {
722        return propertyP(aa, ab, compose2(P.<Property>p1(), curry(f)));
723      }
724    
725      /**
726       * Returns a property where its result is derived from universal quantification across the
727       * application of its arguments.
728       *
729       * @param aa The arbitrrary to produces values from to produce the property with.
730       * @param ab The arbitrrary to produces values from to produce the property with.
731       * @param ac The arbitrrary to produces values from to produce the property with.
732       * @param sa The shrink strategy to use upon falsification.
733       * @param sb The shrink strategy to use upon falsification.
734       * @param sc The shrink strategy to use upon falsification.
735       * @param f  The function to produce properties with results.
736       * @return A property where its result is derived from universal quantification across the
737       *         application of its arguments.
738       */
739      public static <A, B, C> Property property(final Arbitrary<A> aa,
740                                                final Arbitrary<B> ab,
741                                                final Arbitrary<C> ac,
742                                                final Shrink<A> sa,
743                                                final Shrink<B> sb,
744                                                final Shrink<C> sc,
745                                                final F<A, F<B, F<C, Property>>> f) {
746        return property(aa, ab, sa, sb, new F<A, F<B, Property>>() {
747          public F<B, Property> f(final A a) {
748            return new F<B, Property>() {
749              public Property f(final B b) {
750                return property(ac, sc, new F<C, Property>() {
751                  public Property f(final C c) {
752                    return f.f(a).f(b).f(c);
753                  }
754                });
755              }
756            };
757          }
758        });
759      }
760    
761      /**
762       * Returns a property where its result is derived from universal quantification across the
763       * application of its arguments. No shrinking occurs upon falsification.
764       *
765       * @param aa The arbitrrary to produces values from to produce the property with.
766       * @param ab The arbitrrary to produces values from to produce the property with.
767       * @param ac The arbitrrary to produces values from to produce the property with.
768       * @param f  The function to produce properties with results.
769       * @return A property where its result is derived from universal quantification across the
770       *         application of its arguments.
771       */
772      public static <A, B, C> Property property(final Arbitrary<A> aa,
773                                                final Arbitrary<B> ab,
774                                                final Arbitrary<C> ac,
775                                                final F<A, F<B, F<C, Property>>> f) {
776        return property(aa, ab, new F<A, F<B, Property>>() {
777          public F<B, Property> f(final A a) {
778            return new F<B, Property>() {
779              public Property f(final B b) {
780                return property(ac, new F<C, Property>() {
781                  public Property f(final C c) {
782                    return f.f(a).f(b).f(c);
783                  }
784                });
785              }
786            };
787          }
788        });
789      }
790    
791      /**
792       * Returns a property where its result is derived from universal quantification across the
793       * application of its arguments.
794       *
795       * @param aa The arbitrrary to produces values from to produce the property with.
796       * @param ab The arbitrrary to produces values from to produce the property with.
797       * @param ac The arbitrrary to produces values from to produce the property with.
798       * @param sa The shrink strategy to use upon falsification.
799       * @param sb The shrink strategy to use upon falsification.
800       * @param sc The shrink strategy to use upon falsification.
801       * @param f  The function to produce properties with results.
802       * @return A property where its result is derived from universal quantification across the
803       *         application of its arguments.
804       */
805      public static <A, B, C> Property property(final Arbitrary<A> aa,
806                                                final Arbitrary<B> ab,
807                                                final Arbitrary<C> ac,
808                                                final Shrink<A> sa,
809                                                final Shrink<B> sb,
810                                                final Shrink<C> sc,
811                                                final F3<A, B, C, Property> f) {
812        return property(aa, ab, ac, sa, sb, sc, curry(f));
813      }
814    
815      /**
816       * Returns a property where its result is derived from universal quantification across the
817       * application of its arguments. No shrinking occurs upon falsification.
818       *
819       * @param aa The arbitrrary to produces values from to produce the property with.
820       * @param ab The arbitrrary to produces values from to produce the property with.
821       * @param ac The arbitrrary to produces values from to produce the property with.
822       * @param f  The function to produce properties with results.
823       * @return A property where its result is derived from universal quantification across the
824       *         application of its arguments.
825       */
826      public static <A, B, C> Property property(final Arbitrary<A> aa,
827                                                final Arbitrary<B> ab,
828                                                final Arbitrary<C> ac,
829                                                final F3<A, B, C, Property> f) {
830        return property(aa, ab, ac, curry(f));
831      }
832    
833      /**
834       * Returns a property where its result is derived from universal quantification across the
835       * application of its arguments.
836       *
837       * @param aa The arbitrrary to produces values from to produce the property with.
838       * @param ab The arbitrrary to produces values from to produce the property with.
839       * @param ac The arbitrrary to produces values from to produce the property with.
840       * @param ad The arbitrrary to produces values from to produce the property with.
841       * @param sa The shrink strategy to use upon falsification.
842       * @param sb The shrink strategy to use upon falsification.
843       * @param sc The shrink strategy to use upon falsification.
844       * @param sd The shrink strategy to use upon falsification.
845       * @param f  The function to produce properties with results.
846       * @return A property where its result is derived from universal quantification across the
847       *         application of its arguments.
848       */
849      public static <A, B, C, D> Property property(final Arbitrary<A> aa,
850                                                   final Arbitrary<B> ab,
851                                                   final Arbitrary<C> ac,
852                                                   final Arbitrary<D> ad,
853                                                   final Shrink<A> sa,
854                                                   final Shrink<B> sb,
855                                                   final Shrink<C> sc,
856                                                   final Shrink<D> sd,
857                                                   final F<A, F<B, F<C, F<D, Property>>>> f) {
858        return property(aa, ab, ac, sa, sb, sc, new F<A, F<B, F<C, Property>>>() {
859          public F<B, F<C, Property>> f(final A a) {
860            return new F<B, F<C, Property>>() {
861              public F<C, Property> f(final B b) {
862                return new F<C, Property>() {
863                  public Property f(final C c) {
864                    return property(ad, sd, new F<D, Property>() {
865                      public Property f(final D d) {
866                        return f.f(a).f(b).f(c).f(d);
867                      }
868                    });
869                  }
870                };
871              }
872            };
873          }
874        });
875      }
876    
877      /**
878       * Returns a property where its result is derived from universal quantification across the
879       * application of its arguments. No shrinking occurs upon falsification.
880       *
881       * @param aa The arbitrrary to produces values from to produce the property with.
882       * @param ab The arbitrrary to produces values from to produce the property with.
883       * @param ac The arbitrrary to produces values from to produce the property with.
884       * @param ad The arbitrrary to produces values from to produce the property with.
885       * @param f  The function to produce properties with results.
886       * @return A property where its result is derived from universal quantification across the
887       *         application of its arguments.
888       */
889      public static <A, B, C, D> Property property(final Arbitrary<A> aa,
890                                                   final Arbitrary<B> ab,
891                                                   final Arbitrary<C> ac,
892                                                   final Arbitrary<D> ad,
893                                                   final F<A, F<B, F<C, F<D, Property>>>> f) {
894        return property(aa, ab, ac, new F<A, F<B, F<C, Property>>>() {
895          public F<B, F<C, Property>> f(final A a) {
896            return new F<B, F<C, Property>>() {
897              public F<C, Property> f(final B b) {
898                return new F<C, Property>() {
899                  public Property f(final C c) {
900                    return property(ad, new F<D, Property>() {
901                      public Property f(final D d) {
902                        return f.f(a).f(b).f(c).f(d);
903                      }
904                    });
905                  }
906                };
907              }
908            };
909          }
910        });
911      }
912    
913      /**
914       * Returns a property where its result is derived from universal quantification across the
915       * application of its arguments.
916       *
917       * @param aa The arbitrrary to produces values from to produce the property with.
918       * @param ab The arbitrrary to produces values from to produce the property with.
919       * @param ac The arbitrrary to produces values from to produce the property with.
920       * @param ad The arbitrrary to produces values from to produce the property with.
921       * @param sa The shrink strategy to use upon falsification.
922       * @param sb The shrink strategy to use upon falsification.
923       * @param sc The shrink strategy to use upon falsification.
924       * @param sd The shrink strategy to use upon falsification.
925       * @param f  The function to produce properties with results.
926       * @return A property where its result is derived from universal quantification across the
927       *         application of its arguments.
928       */
929      public static <A, B, C, D> Property property(final Arbitrary<A> aa,
930                                                   final Arbitrary<B> ab,
931                                                   final Arbitrary<C> ac,
932                                                   final Arbitrary<D> ad,
933                                                   final Shrink<A> sa,
934                                                   final Shrink<B> sb,
935                                                   final Shrink<C> sc,
936                                                   final Shrink<D> sd,
937                                                   final F4<A, B, C, D, Property> f) {
938        return property(aa, ab, ac, ad, sa, sb, sc, sd, curry(f));
939      }
940    
941      /**
942       * Returns a property where its result is derived from universal quantification across the
943       * application of its arguments. No shrinking occurs upon falsification.
944       *
945       * @param aa The arbitrrary to produces values from to produce the property with.
946       * @param ab The arbitrrary to produces values from to produce the property with.
947       * @param ac The arbitrrary to produces values from to produce the property with.
948       * @param ad The arbitrrary to produces values from to produce the property with.
949       * @param f  The function to produce properties with results.
950       * @return A property where its result is derived from universal quantification across the
951       *         application of its arguments.
952       */
953      public static <A, B, C, D> Property property(final Arbitrary<A> aa,
954                                                   final Arbitrary<B> ab,
955                                                   final Arbitrary<C> ac,
956                                                   final Arbitrary<D> ad,
957                                                   final F4<A, B, C, D, Property> f) {
958        return property(aa, ab, ac, ad, curry(f));
959      }
960    
961      /**
962       * Returns a property where its result is derived from universal quantification across the
963       * application of its arguments.
964       *
965       * @param aa The arbitrrary to produces values from to produce the property with.
966       * @param ab The arbitrrary to produces values from to produce the property with.
967       * @param ac The arbitrrary to produces values from to produce the property with.
968       * @param ad The arbitrrary to produces values from to produce the property with.
969       * @param ae The arbitrrary to produces values from to produce the property with.
970       * @param sa The shrink strategy to use upon falsification.
971       * @param sb The shrink strategy to use upon falsification.
972       * @param sc The shrink strategy to use upon falsification.
973       * @param sd The shrink strategy to use upon falsification.
974       * @param se The shrink strategy to use upon falsification.
975       * @param f  The function to produce properties with results.
976       * @return A property where its result is derived from universal quantification across the
977       *         application of its arguments.
978       */
979      public static <A, B, C, D, E> Property property(final Arbitrary<A> aa,
980                                                      final Arbitrary<B> ab,
981                                                      final Arbitrary<C> ac,
982                                                      final Arbitrary<D> ad,
983                                                      final Arbitrary<E> ae,
984                                                      final Shrink<A> sa,
985                                                      final Shrink<B> sb,
986                                                      final Shrink<C> sc,
987                                                      final Shrink<D> sd,
988                                                      final Shrink<E> se,
989                                                      final F<A, F<B, F<C, F<D, F<E, Property>>>>> f) {
990        return property(aa, ab, ac, ad, sa, sb, sc, sd, new F<A, F<B, F<C, F<D, Property>>>>() {
991          public F<B, F<C, F<D, Property>>> f(final A a) {
992            return new F<B, F<C, F<D, Property>>>() {
993              public F<C, F<D, Property>> f(final B b) {
994                return new F<C, F<D, Property>>() {
995                  public F<D, Property> f(final C c) {
996                    return new F<D, Property>() {
997                      public Property f(final D d) {
998                        return property(ae, se, new F<E, Property>() {
999                          public Property f(final E e) {
1000                            return f.f(a).f(b).f(c).f(d).f(e);
1001                          }
1002                        });
1003                      }
1004                    };
1005                  }
1006                };
1007              }
1008            };
1009          }
1010        });
1011      }
1012    
1013      /**
1014       * Returns a property where its result is derived from universal quantification across the
1015       * application of its arguments. No shrinking occurs upon falsification.
1016       *
1017       * @param aa The arbitrrary to produces values from to produce the property with.
1018       * @param ab The arbitrrary to produces values from to produce the property with.
1019       * @param ac The arbitrrary to produces values from to produce the property with.
1020       * @param ad The arbitrrary to produces values from to produce the property with.
1021       * @param ae The arbitrrary to produces values from to produce the property with.
1022       * @param f  The function to produce properties with results.
1023       * @return A property where its result is derived from universal quantification across the
1024       *         application of its arguments.
1025       */
1026      public static <A, B, C, D, E> Property property(final Arbitrary<A> aa,
1027                                                      final Arbitrary<B> ab,
1028                                                      final Arbitrary<C> ac,
1029                                                      final Arbitrary<D> ad,
1030                                                      final Arbitrary<E> ae,
1031                                                      final F<A, F<B, F<C, F<D, F<E, Property>>>>> f) {
1032        return property(aa, ab, ac, ad, new F<A, F<B, F<C, F<D, Property>>>>() {
1033          public F<B, F<C, F<D, Property>>> f(final A a) {
1034            return new F<B, F<C, F<D, Property>>>() {
1035              public F<C, F<D, Property>> f(final B b) {
1036                return new F<C, F<D, Property>>() {
1037                  public F<D, Property> f(final C c) {
1038                    return new F<D, Property>() {
1039                      public Property f(final D d) {
1040                        return property(ae, new F<E, Property>() {
1041                          public Property f(final E e) {
1042                            return f.f(a).f(b).f(c).f(d).f(e);
1043                          }
1044                        });
1045                      }
1046                    };
1047                  }
1048                };
1049              }
1050            };
1051          }
1052        });
1053      }
1054    
1055      /**
1056       * Returns a property where its result is derived from universal quantification across the
1057       * application of its arguments.
1058       *
1059       * @param aa The arbitrrary to produces values from to produce the property with.
1060       * @param ab The arbitrrary to produces values from to produce the property with.
1061       * @param ac The arbitrrary to produces values from to produce the property with.
1062       * @param ad The arbitrrary to produces values from to produce the property with.
1063       * @param ae The arbitrrary to produces values from to produce the property with.
1064       * @param sa The shrink strategy to use upon falsification.
1065       * @param sb The shrink strategy to use upon falsification.
1066       * @param sc The shrink strategy to use upon falsification.
1067       * @param sd The shrink strategy to use upon falsification.
1068       * @param se The shrink strategy to use upon falsification.
1069       * @param f  The function to produce properties with results.
1070       * @return A property where its result is derived from universal quantification across the
1071       *         application of its arguments.
1072       */
1073      public static <A, B, C, D, E> Property property(final Arbitrary<A> aa,
1074                                                      final Arbitrary<B> ab,
1075                                                      final Arbitrary<C> ac,
1076                                                      final Arbitrary<D> ad,
1077                                                      final Arbitrary<E> ae,
1078                                                      final Shrink<A> sa,
1079                                                      final Shrink<B> sb,
1080                                                      final Shrink<C> sc,
1081                                                      final Shrink<D> sd,
1082                                                      final Shrink<E> se,
1083                                                      final F5<A, B, C, D, E, Property> f) {
1084        return property(aa, ab, ac, ad, ae, sa, sb, sc, sd, se, curry(f));
1085      }
1086    
1087      /**
1088       * Returns a property where its result is derived from universal quantification across the
1089       * application of its arguments. No shrinking occurs upon falsification.
1090       *
1091       * @param aa The arbitrrary to produces values from to produce the property with.
1092       * @param ab The arbitrrary to produces values from to produce the property with.
1093       * @param ac The arbitrrary to produces values from to produce the property with.
1094       * @param ad The arbitrrary to produces values from to produce the property with.
1095       * @param ae The arbitrrary to produces values from to produce the property with.
1096       * @param f  The function to produce properties with results.
1097       * @return A property where its result is derived from universal quantification across the
1098       *         application of its arguments.
1099       */
1100      public static <A, B, C, D, E> Property property(final Arbitrary<A> aa,
1101                                                      final Arbitrary<B> ab,
1102                                                      final Arbitrary<C> ac,
1103                                                      final Arbitrary<D> ad,
1104                                                      final Arbitrary<E> ae,
1105                                                      final F5<A, B, C, D, E, Property> f) {
1106        return property(aa, ab, ac, ad, ae, curry(f));
1107      }
1108    
1109      /**
1110       * Returns a property where its result is derived from universal quantification across the
1111       * application of its arguments.
1112       *
1113       * @param aa The arbitrrary to produces values from to produce the property with.
1114       * @param ab The arbitrrary to produces values from to produce the property with.
1115       * @param ac The arbitrrary to produces values from to produce the property with.
1116       * @param ad The arbitrrary to produces values from to produce the property with.
1117       * @param ae The arbitrrary to produces values from to produce the property with.
1118       * @param af The arbitrrary to produces values from to produce the property with.
1119       * @param sa The shrink strategy to use upon falsification.
1120       * @param sb The shrink strategy to use upon falsification.
1121       * @param sc The shrink strategy to use upon falsification.
1122       * @param sd The shrink strategy to use upon falsification.
1123       * @param se The shrink strategy to use upon falsification.
1124       * @param sf The shrink strategy to use upon falsification.
1125       * @param f  The function to produce properties with results.
1126       * @return A property where its result is derived from universal quantification across the
1127       *         application of its arguments.
1128       */
1129      public static <A, B, C, D, E, F$> Property property(final Arbitrary<A> aa,
1130                                                          final Arbitrary<B> ab,
1131                                                          final Arbitrary<C> ac,
1132                                                          final Arbitrary<D> ad,
1133                                                          final Arbitrary<E> ae,
1134                                                          final Arbitrary<F$> af,
1135                                                          final Shrink<A> sa,
1136                                                          final Shrink<B> sb,
1137                                                          final Shrink<C> sc,
1138                                                          final Shrink<D> sd,
1139                                                          final Shrink<E> se,
1140                                                          final Shrink<F$> sf,
1141                                                          final F<A, F<B, F<C, F<D, F<E, F<F$, Property>>>>>> f) {
1142        return property(aa, ab, ac, ad, ae, sa, sb, sc, sd, se, new F<A, F<B, F<C, F<D, F<E, Property>>>>>() {
1143          public F<B, F<C, F<D, F<E, Property>>>> f(final A a) {
1144            return new F<B, F<C, F<D, F<E, Property>>>>() {
1145              public F<C, F<D, F<E, Property>>> f(final B b) {
1146                return new F<C, F<D, F<E, Property>>>() {
1147                  public F<D, F<E, Property>> f(final C c) {
1148                    return new F<D, F<E, Property>>() {
1149                      public F<E, Property> f(final D d) {
1150                        return new F<E, Property>() {
1151                          public Property f(final E e) {
1152                            return property(af, sf, new F<F$, Property>() {
1153                              public Property f(final F$ f$) {
1154                                return f.f(a).f(b).f(c).f(d).f(e).f(f$);
1155                              }
1156                            });
1157                          }
1158                        };
1159                      }
1160                    };
1161                  }
1162                };
1163              }
1164            };
1165          }
1166        });
1167      }
1168    
1169      /**
1170       * Returns a property where its result is derived from universal quantification across the
1171       * application of its arguments. No shrinking occurs upon falsification.
1172       *
1173       * @param aa The arbitrrary to produces values from to produce the property with.
1174       * @param ab The arbitrrary to produces values from to produce the property with.
1175       * @param ac The arbitrrary to produces values from to produce the property with.
1176       * @param ad The arbitrrary to produces values from to produce the property with.
1177       * @param ae The arbitrrary to produces values from to produce the property with.
1178       * @param af The arbitrrary to produces values from to produce the property with.
1179       * @param f  The function to produce properties with results.
1180       * @return A property where its result is derived from universal quantification across the
1181       *         application of its arguments.
1182       */
1183      public static <A, B, C, D, E, F$> Property property(final Arbitrary<A> aa,
1184                                                          final Arbitrary<B> ab,
1185                                                          final Arbitrary<C> ac,
1186                                                          final Arbitrary<D> ad,
1187                                                          final Arbitrary<E> ae,
1188                                                          final Arbitrary<F$> af,
1189                                                          final F<A, F<B, F<C, F<D, F<E, F<F$, Property>>>>>> f) {
1190        return property(aa, ab, ac, ad, ae, new F<A, F<B, F<C, F<D, F<E, Property>>>>>() {
1191          public F<B, F<C, F<D, F<E, Property>>>> f(final A a) {
1192            return new F<B, F<C, F<D, F<E, Property>>>>() {
1193              public F<C, F<D, F<E, Property>>> f(final B b) {
1194                return new F<C, F<D, F<E, Property>>>() {
1195                  public F<D, F<E, Property>> f(final C c) {
1196                    return new F<D, F<E, Property>>() {
1197                      public F<E, Property> f(final D d) {
1198                        return new F<E, Property>() {
1199                          public Property f(final E e) {
1200                            return property(af, new F<F$, Property>() {
1201                              public Property f(final F$ f$) {
1202                                return f.f(a).f(b).f(c).f(d).f(e).f(f$);
1203                              }
1204                            });
1205                          }
1206                        };
1207                      }
1208                    };
1209                  }
1210                };
1211              }
1212            };
1213          }
1214        });
1215      }
1216    
1217      /**
1218       * Returns a property where its result is derived from universal quantification across the
1219       * application of its arguments.
1220       *
1221       * @param aa The arbitrrary to produces values from to produce the property with.
1222       * @param ab The arbitrrary to produces values from to produce the property with.
1223       * @param ac The arbitrrary to produces values from to produce the property with.
1224       * @param ad The arbitrrary to produces values from to produce the property with.
1225       * @param ae The arbitrrary to produces values from to produce the property with.
1226       * @param af The arbitrrary to produces values from to produce the property with.
1227       * @param sa The shrink strategy to use upon falsification.
1228       * @param sb The shrink strategy to use upon falsification.
1229       * @param sc The shrink strategy to use upon falsification.
1230       * @param sd The shrink strategy to use upon falsification.
1231       * @param se The shrink strategy to use upon falsification.
1232       * @param sf The shrink strategy to use upon falsification.
1233       * @param f  The function to produce properties with results.
1234       * @return A property where its result is derived from universal quantification across the
1235       *         application of its arguments.
1236       */
1237      public static <A, B, C, D, E, F$> Property property(final Arbitrary<A> aa,
1238                                                          final Arbitrary<B> ab,
1239                                                          final Arbitrary<C> ac,
1240                                                          final Arbitrary<D> ad,
1241                                                          final Arbitrary<E> ae,
1242                                                          final Arbitrary<F$> af,
1243                                                          final Shrink<A> sa,
1244                                                          final Shrink<B> sb,
1245                                                          final Shrink<C> sc,
1246                                                          final Shrink<D> sd,
1247                                                          final Shrink<E> se,
1248                                                          final Shrink<F$> sf,
1249                                                          final F6<A, B, C, D, E, F$, Property> f) {
1250        return property(aa, ab, ac, ad, ae, af, sa, sb, sc, sd, se, sf, curry(f));
1251      }
1252    
1253      /**
1254       * Returns a property where its result is derived from universal quantification across the
1255       * application of its arguments. No shrinking occurs upon falsification.
1256       *
1257       * @param aa The arbitrrary to produces values from to produce the property with.
1258       * @param ab The arbitrrary to produces values from to produce the property with.
1259       * @param ac The arbitrrary to produces values from to produce the property with.
1260       * @param ad The arbitrrary to produces values from to produce the property with.
1261       * @param ae The arbitrrary to produces values from to produce the property with.
1262       * @param af The arbitrrary to produces values from to produce the property with.
1263       * @param f  The function to produce properties with results.
1264       * @return A property where its result is derived from universal quantification across the
1265       *         application of its arguments.
1266       */
1267      public static <A, B, C, D, E, F$> Property property(final Arbitrary<A> aa,
1268                                                          final Arbitrary<B> ab,
1269                                                          final Arbitrary<C> ac,
1270                                                          final Arbitrary<D> ad,
1271                                                          final Arbitrary<E> ae,
1272                                                          final Arbitrary<F$> af,
1273                                                          final F6<A, B, C, D, E, F$, Property> f) {
1274        return property(aa, ab, ac, ad, ae, af, curry(f));
1275      }
1276    
1277      /**
1278       * Returns a property where its result is derived from universal quantification across the
1279       * application of its arguments.
1280       *
1281       * @param aa The arbitrrary to produces values from to produce the property with.
1282       * @param ab The arbitrrary to produces values from to produce the property with.
1283       * @param ac The arbitrrary to produces values from to produce the property with.
1284       * @param ad The arbitrrary to produces values from to produce the property with.
1285       * @param ae The arbitrrary to produces values from to produce the property with.
1286       * @param af The arbitrrary to produces values from to produce the property with.
1287       * @param ag The arbitrrary to produces values from to produce the property with.
1288       * @param sa The shrink strategy to use upon falsification.
1289       * @param sb The shrink strategy to use upon falsification.
1290       * @param sc The shrink strategy to use upon falsification.
1291       * @param sd The shrink strategy to use upon falsification.
1292       * @param se The shrink strategy to use upon falsification.
1293       * @param sf The shrink strategy to use upon falsification.
1294       * @param sg The shrink strategy to use upon falsification.
1295       * @param f  The function to produce properties with results.
1296       * @return A property where its result is derived from universal quantification across the
1297       *         application of its arguments.
1298       */
1299      public static <A, B, C, D, E, F$, G> Property property(final Arbitrary<A> aa,
1300                                                             final Arbitrary<B> ab,
1301                                                             final Arbitrary<C> ac,
1302                                                             final Arbitrary<D> ad,
1303                                                             final Arbitrary<E> ae,
1304                                                             final Arbitrary<F$> af,
1305                                                             final Arbitrary<G> ag,
1306                                                             final Shrink<A> sa,
1307                                                             final Shrink<B> sb,
1308                                                             final Shrink<C> sc,
1309                                                             final Shrink<D> sd,
1310                                                             final Shrink<E> se,
1311                                                             final Shrink<F$> sf,
1312                                                             final Shrink<G> sg,
1313                                                             final F<A, F<B, F<C, F<D, F<E, F<F$, F<G, Property>>>>>>> f) {
1314        return property(aa, ab, ac, ad, ae, af, sa, sb, sc, sd, se, sf, new F<A, F<B, F<C, F<D, F<E, F<F$, Property>>>>>>() {
1315          public F<B, F<C, F<D, F<E, F<F$, Property>>>>> f(final A a) {
1316            return new F<B, F<C, F<D, F<E, F<F$, Property>>>>>() {
1317              public F<C, F<D, F<E, F<F$, Property>>>> f(final B b) {
1318                return new F<C, F<D, F<E, F<F$, Property>>>>() {
1319                  public F<D, F<E, F<F$, Property>>> f(final C c) {
1320                    return new F<D, F<E, F<F$, Property>>>() {
1321                      public F<E, F<F$, Property>> f(final D d) {
1322                        return new F<E, F<F$, Property>>() {
1323                          public F<F$, Property> f(final E e) {
1324                            return new F<F$, Property>() {
1325                              public Property f(final F$ f$) {
1326                                return property(ag, sg, new F<G, Property>() {
1327                                  public Property f(final G g) {
1328                                    return f.f(a).f(b).f(c).f(d).f(e).f(f$).f(g);
1329                                  }
1330                                });
1331                              }
1332                            };
1333                          }
1334                        };
1335                      }
1336                    };
1337                  }
1338                };
1339              }
1340            };
1341          }
1342        });
1343      }
1344    
1345      /**
1346       * Returns a property where its result is derived from universal quantification across the
1347       * application of its arguments. No shrinking occurs upon falsification.
1348       *
1349       * @param aa The arbitrrary to produces values from to produce the property with.
1350       * @param ab The arbitrrary to produces values from to produce the property with.
1351       * @param ac The arbitrrary to produces values from to produce the property with.
1352       * @param ad The arbitrrary to produces values from to produce the property with.
1353       * @param ae The arbitrrary to produces values from to produce the property with.
1354       * @param af The arbitrrary to produces values from to produce the property with.
1355       * @param ag The arbitrrary to produces values from to produce the property with.
1356       * @param f  The function to produce properties with results.
1357       * @return A property where its result is derived from universal quantification across the
1358       *         application of its arguments.
1359       */
1360      public static <A, B, C, D, E, F$, G> Property property(final Arbitrary<A> aa,
1361                                                             final Arbitrary<B> ab,
1362                                                             final Arbitrary<C> ac,
1363                                                             final Arbitrary<D> ad,
1364                                                             final Arbitrary<E> ae,
1365                                                             final Arbitrary<F$> af,
1366                                                             final Arbitrary<G> ag,
1367                                                             final F<A, F<B, F<C, F<D, F<E, F<F$, F<G, Property>>>>>>> f) {
1368        return property(aa, ab, ac, ad, ae, af, new F<A, F<B, F<C, F<D, F<E, F<F$, Property>>>>>>() {
1369          public F<B, F<C, F<D, F<E, F<F$, Property>>>>> f(final A a) {
1370            return new F<B, F<C, F<D, F<E, F<F$, Property>>>>>() {
1371              public F<C, F<D, F<E, F<F$, Property>>>> f(final B b) {
1372                return new F<C, F<D, F<E, F<F$, Property>>>>() {
1373                  public F<D, F<E, F<F$, Property>>> f(final C c) {
1374                    return new F<D, F<E, F<F$, Property>>>() {
1375                      public F<E, F<F$, Property>> f(final D d) {
1376                        return new F<E, F<F$, Property>>() {
1377                          public F<F$, Property> f(final E e) {
1378                            return new F<F$, Property>() {
1379                              public Property f(final F$ f$) {
1380                                return property(ag, new F<G, Property>() {
1381                                  public Property f(final G g) {
1382                                    return f.f(a).f(b).f(c).f(d).f(e).f(f$).f(g);
1383                                  }
1384                                });
1385                              }
1386                            };
1387                          }
1388                        };
1389                      }
1390                    };
1391                  }
1392                };
1393              }
1394            };
1395          }
1396        });
1397      }
1398    
1399      /**
1400       * Returns a property where its result is derived from universal quantification across the
1401       * application of its arguments.
1402       *
1403       * @param aa The arbitrrary to produces values from to produce the property with.
1404       * @param ab The arbitrrary to produces values from to produce the property with.
1405       * @param ac The arbitrrary to produces values from to produce the property with.
1406       * @param ad The arbitrrary to produces values from to produce the property with.
1407       * @param ae The arbitrrary to produces values from to produce the property with.
1408       * @param af The arbitrrary to produces values from to produce the property with.
1409       * @param ag The arbitrrary to produces values from to produce the property with.
1410       * @param sa The shrink strategy to use upon falsification.
1411       * @param sb The shrink strategy to use upon falsification.
1412       * @param sc The shrink strategy to use upon falsification.
1413       * @param sd The shrink strategy to use upon falsification.
1414       * @param se The shrink strategy to use upon falsification.
1415       * @param sf The shrink strategy to use upon falsification.
1416       * @param sg The shrink strategy to use upon falsification.
1417       * @param f  The function to produce properties with results.
1418       * @return A property where its result is derived from universal quantification across the
1419       *         application of its arguments.
1420       */
1421      public static <A, B, C, D, E, F$, G> Property property(final Arbitrary<A> aa,
1422                                                             final Arbitrary<B> ab,
1423                                                             final Arbitrary<C> ac,
1424                                                             final Arbitrary<D> ad,
1425                                                             final Arbitrary<E> ae,
1426                                                             final Arbitrary<F$> af,
1427                                                             final Arbitrary<G> ag,
1428                                                             final Shrink<A> sa,
1429                                                             final Shrink<B> sb,
1430                                                             final Shrink<C> sc,
1431                                                             final Shrink<D> sd,
1432                                                             final Shrink<E> se,
1433                                                             final Shrink<F$> sf,
1434                                                             final Shrink<G> sg,
1435                                                             final F7<A, B, C, D, E, F$, G, Property> f) {
1436        return property(aa, ab, ac, ad, ae, af, ag, sa, sb, sc, sd, se, sf, sg, curry(f));
1437      }
1438    
1439      /**
1440       * Returns a property where its result is derived from universal quantification across the
1441       * application of its arguments. No shrinking occurs upon falsification.
1442       *
1443       * @param aa The arbitrrary to produces values from to produce the property with.
1444       * @param ab The arbitrrary to produces values from to produce the property with.
1445       * @param ac The arbitrrary to produces values from to produce the property with.
1446       * @param ad The arbitrrary to produces values from to produce the property with.
1447       * @param ae The arbitrrary to produces values from to produce the property with.
1448       * @param af The arbitrrary to produces values from to produce the property with.
1449       * @param ag The arbitrrary to produces values from to produce the property with.
1450       * @param f  The function to produce properties with results.
1451       * @return A property where its result is derived from universal quantification across the
1452       *         application of its arguments.
1453       */
1454      public static <A, B, C, D, E, F$, G> Property property(final Arbitrary<A> aa,
1455                                                             final Arbitrary<B> ab,
1456                                                             final Arbitrary<C> ac,
1457                                                             final Arbitrary<D> ad,
1458                                                             final Arbitrary<E> ae,
1459                                                             final Arbitrary<F$> af,
1460                                                             final Arbitrary<G> ag,
1461                                                             final F7<A, B, C, D, E, F$, G, Property> f) {
1462        return property(aa, ab, ac, ad, ae, af, ag, curry(f));
1463      }
1464    
1465      /**
1466       * Returns a property where its result is derived from universal quantification across the
1467       * application of its arguments.
1468       *
1469       * @param aa The arbitrrary to produces values from to produce the property with.
1470       * @param ab The arbitrrary to produces values from to produce the property with.
1471       * @param ac The arbitrrary to produces values from to produce the property with.
1472       * @param ad The arbitrrary to produces values from to produce the property with.
1473       * @param ae The arbitrrary to produces values from to produce the property with.
1474       * @param af The arbitrrary to produces values from to produce the property with.
1475       * @param ag The arbitrrary to produces values from to produce the property with.
1476       * @param ah The arbitrrary to produces values from to produce the property with.
1477       * @param sa The shrink strategy to use upon falsification.
1478       * @param sb The shrink strategy to use upon falsification.
1479       * @param sc The shrink strategy to use upon falsification.
1480       * @param sd The shrink strategy to use upon falsification.
1481       * @param se The shrink strategy to use upon falsification.
1482       * @param sf The shrink strategy to use upon falsification.
1483       * @param sg The shrink strategy to use upon falsification.
1484       * @param sh The shrink strategy to use upon falsification.
1485       * @param f  The function to produce properties with results.
1486       * @return A property where its result is derived from universal quantification across the
1487       *         application of its arguments.
1488       */
1489      public static <A, B, C, D, E, F$, G, H> Property property(final Arbitrary<A> aa,
1490                                                                final Arbitrary<B> ab,
1491                                                                final Arbitrary<C> ac,
1492                                                                final Arbitrary<D> ad,
1493                                                                final Arbitrary<E> ae,
1494                                                                final Arbitrary<F$> af,
1495                                                                final Arbitrary<G> ag,
1496                                                                final Arbitrary<H> ah,
1497                                                                final Shrink<A> sa,
1498                                                                final Shrink<B> sb,
1499                                                                final Shrink<C> sc,
1500                                                                final Shrink<D> sd,
1501                                                                final Shrink<E> se,
1502                                                                final Shrink<F$> sf,
1503                                                                final Shrink<G> sg,
1504                                                                final Shrink<H> sh,
1505                                                                final F<A, F<B, F<C, F<D, F<E, F<F$, F<G, F<H, Property>>>>>>>> f) {
1506        return property(aa, ab, ac, ad, ae, af, ag, sa, sb, sc, sd, se, sf, sg, new F<A, F<B, F<C, F<D, F<E, F<F$, F<G, Property>>>>>>>() {
1507          public F<B, F<C, F<D, F<E, F<F$, F<G, Property>>>>>> f(final A a) {
1508            return new F<B, F<C, F<D, F<E, F<F$, F<G, Property>>>>>>() {
1509              public F<C, F<D, F<E, F<F$, F<G, Property>>>>> f(final B b) {
1510                return new F<C, F<D, F<E, F<F$, F<G, Property>>>>>() {
1511                  public F<D, F<E, F<F$, F<G, Property>>>> f(final C c) {
1512                    return new F<D, F<E, F<F$, F<G, Property>>>>() {
1513                      public F<E, F<F$, F<G, Property>>> f(final D d) {
1514                        return new F<E, F<F$, F<G, Property>>>() {
1515                          public F<F$, F<G, Property>> f(final E e) {
1516                            return new F<F$, F<G, Property>>() {
1517                              public F<G, Property> f(final F$ f$) {
1518                                return new F<G, Property>() {
1519                                  public Property f(final G g) {
1520                                    return property(ah, sh, new F<H, Property>() {
1521                                      public Property f(final H h) {
1522                                        return f.f(a).f(b).f(c).f(d).f(e).f(f$).f(g).f(h);
1523                                      }
1524                                    });
1525                                  }
1526                                };
1527                              }
1528                            };
1529                          }
1530                        };
1531                      }
1532                    };
1533                  }
1534                };
1535              }
1536            };
1537          }
1538        });
1539      }
1540    
1541      /**
1542       * Returns a property where its result is derived from universal quantification across the
1543       * application of its arguments. No shrinking occurs upon falsification.
1544       *
1545       * @param aa The arbitrrary to produces values from to produce the property with.
1546       * @param ab The arbitrrary to produces values from to produce the property with.
1547       * @param ac The arbitrrary to produces values from to produce the property with.
1548       * @param ad The arbitrrary to produces values from to produce the property with.
1549       * @param ae The arbitrrary to produces values from to produce the property with.
1550       * @param af The arbitrrary to produces values from to produce the property with.
1551       * @param ag The arbitrrary to produces values from to produce the property with.
1552       * @param ah The arbitrrary to produces values from to produce the property with.
1553       * @param f  The function to produce properties with results.
1554       * @return A property where its result is derived from universal quantification across the
1555       *         application of its arguments.
1556       */
1557      public static <A, B, C, D, E, F$, G, H> Property property(final Arbitrary<A> aa,
1558                                                                final Arbitrary<B> ab,
1559                                                                final Arbitrary<C> ac,
1560                                                                final Arbitrary<D> ad,
1561                                                                final Arbitrary<E> ae,
1562                                                                final Arbitrary<F$> af,
1563                                                                final Arbitrary<G> ag,
1564                                                                final Arbitrary<H> ah,
1565                                                                final F<A, F<B, F<C, F<D, F<E, F<F$, F<G, F<H, Property>>>>>>>> f) {
1566        return property(aa, ab, ac, ad, ae, af, ag, new F<A, F<B, F<C, F<D, F<E, F<F$, F<G, Property>>>>>>>() {
1567          public F<B, F<C, F<D, F<E, F<F$, F<G, Property>>>>>> f(final A a) {
1568            return new F<B, F<C, F<D, F<E, F<F$, F<G, Property>>>>>>() {
1569              public F<C, F<D, F<E, F<F$, F<G, Property>>>>> f(final B b) {
1570                return new F<C, F<D, F<E, F<F$, F<G, Property>>>>>() {
1571                  public F<D, F<E, F<F$, F<G, Property>>>> f(final C c) {
1572                    return new F<D, F<E, F<F$, F<G, Property>>>>() {
1573                      public F<E, F<F$, F<G, Property>>> f(final D d) {
1574                        return new F<E, F<F$, F<G, Property>>>() {
1575                          public F<F$, F<G, Property>> f(final E e) {
1576                            return new F<F$, F<G, Property>>() {
1577                              public F<G, Property> f(final F$ f$) {
1578                                return new F<G, Property>() {
1579                                  public Property f(final G g) {
1580                                    return property(ah, new F<H, Property>() {
1581                                      public Property f(final H h) {
1582                                        return f.f(a).f(b).f(c).f(d).f(e).f(f$).f(g).f(h);
1583                                      }
1584                                    });
1585                                  }
1586                                };
1587                              }
1588                            };
1589                          }
1590                        };
1591                      }
1592                    };
1593                  }
1594                };
1595              }
1596            };
1597          }
1598        });
1599      }
1600    
1601      /**
1602       * Returns a property where its result is derived from universal quantification across the
1603       * application of its arguments.
1604       *
1605       * @param aa The arbitrrary to produces values from to produce the property with.
1606       * @param ab The arbitrrary to produces values from to produce the property with.
1607       * @param ac The arbitrrary to produces values from to produce the property with.
1608       * @param ad The arbitrrary to produces values from to produce the property with.
1609       * @param ae The arbitrrary to produces values from to produce the property with.
1610       * @param af The arbitrrary to produces values from to produce the property with.
1611       * @param ag The arbitrrary to produces values from to produce the property with.
1612       * @param ah The arbitrrary to produces values from to produce the property with.
1613       * @param sa The shrink strategy to use upon falsification.
1614       * @param sb The shrink strategy to use upon falsification.
1615       * @param sc The shrink strategy to use upon falsification.
1616       * @param sd The shrink strategy to use upon falsification.
1617       * @param se The shrink strategy to use upon falsification.
1618       * @param sf The shrink strategy to use upon falsification.
1619       * @param sg The shrink strategy to use upon falsification.
1620       * @param sh The shrink strategy to use upon falsification.
1621       * @param f  The function to produce properties with results.
1622       * @return A property where its result is derived from universal quantification across the
1623       *         application of its arguments.
1624       */
1625      public static <A, B, C, D, E, F$, G, H> Property property(final Arbitrary<A> aa,
1626                                                                final Arbitrary<B> ab,
1627                                                                final Arbitrary<C> ac,
1628                                                                final Arbitrary<D> ad,
1629                                                                final Arbitrary<E> ae,
1630                                                                final Arbitrary<F$> af,
1631                                                                final Arbitrary<G> ag,
1632                                                                final Arbitrary<H> ah,
1633                                                                final Shrink<A> sa,
1634                                                                final Shrink<B> sb,
1635                                                                final Shrink<C> sc,
1636                                                                final Shrink<D> sd,
1637                                                                final Shrink<E> se,
1638                                                                final Shrink<F$> sf,
1639                                                                final Shrink<G> sg,
1640                                                                final Shrink<H> sh,
1641                                                                final F8<A, B, C, D, E, F$, G, H, Property> f) {
1642        return property(aa, ab, ac, ad, ae, af, ag, ah, sa, sb, sc, sd, se, sf, sg, sh, curry(f));
1643      }
1644    
1645      /**
1646       * Returns a property where its result is derived from universal quantification across the
1647       * application of its arguments. No shrinking occurs upon falsification.
1648       *
1649       * @param aa The arbitrrary to produces values from to produce the property with.
1650       * @param ab The arbitrrary to produces values from to produce the property with.
1651       * @param ac The arbitrrary to produces values from to produce the property with.
1652       * @param ad The arbitrrary to produces values from to produce the property with.
1653       * @param ae The arbitrrary to produces values from to produce the property with.
1654       * @param af The arbitrrary to produces values from to produce the property with.
1655       * @param ag The arbitrrary to produces values from to produce the property with.
1656       * @param ah The arbitrrary to produces values from to produce the property with.
1657       * @param f  The function to produce properties with results.
1658       * @return A property where its result is derived from universal quantification across the
1659       *         application of its arguments.
1660       */
1661      public static <A, B, C, D, E, F$, G, H> Property property(final Arbitrary<A> aa,
1662                                                                final Arbitrary<B> ab,
1663                                                                final Arbitrary<C> ac,
1664                                                                final Arbitrary<D> ad,
1665                                                                final Arbitrary<E> ae,
1666                                                                final Arbitrary<F$> af,
1667                                                                final Arbitrary<G> ag,
1668                                                                final Arbitrary<H> ah,
1669                                                                final F8<A, B, C, D, E, F$, G, H, Property> f) {
1670        return property(aa, ab, ac, ad, ae, af, ag, ah, curry(f));
1671      }
1672    
1673      /**
1674       * Returns a property that has a result of exception, if the evaluation of the given property
1675       * throws an exception; otherwise, the given property is returned.
1676       *
1677       * @param p A property to evaluate to check for an exception.
1678       * @return A property that has a result of exception, if the evaluation of the given property
1679       *         throws an exception; otherwise, the given property is returned.
1680       */
1681      public static Property exception(final P1<Property> p) {
1682        try {
1683          return p._1();
1684        } catch (final Throwable t) {
1685          return new Property(new F<Integer, F<Rand, Result>>() {
1686            public F<Rand, Result> f(final Integer i) {
1687              return new F<Rand, Result>() {
1688                public Result f(final Rand r) {
1689                  return Result.exception(List.<Arg<?>>nil(), t);
1690                }
1691              };
1692            }
1693          });
1694        }
1695      }
1696    }