static IEnumerable <IGenIteration <TResult> > BindExampleSpace( IExampleSpace <T> exampleSpace, Func <T, IGen <TResult> > selector, GenParameters parameters) { return(selector(exampleSpace.Current.Value).Advanced .Run(parameters) .TakeWhileInclusive(iteration => !iteration.IsInstance()) .Select(iteration => { return iteration.Match( onInstance: instance => { var jointExampleSpace = JoinExampleSpaces( exampleSpace, instance.ExampleSpace, selector, parameters); return GenIterationFactory.Instance( iteration.ReplayParameters, iteration.NextParameters, jointExampleSpace); }, onError: error => error, onDiscard: discard => discard); })); };
IEnumerable <IGenIteration <T> > GenFunc(GenParameters parameters) { while (true) { var replayParameters = parameters; var(value, nextParameters) = func(replayParameters); parameters = nextParameters; yield return(GenIterationFactory.Instance(replayParameters, nextParameters, ExampleSpaceFactory.Singleton(value))); } }
/// <summary> /// Projects each element in a generator to a new form. /// </summary> /// <typeparam name="T">The type of the generator's value.</typeparam> /// <typeparam name="TResult">The type of the resultant generator's value.</typeparam> /// <param name="gen">The generator to apply the projection to.</param> /// <param name="selector">A projection function to apply to each value.</param> /// <returns>A new generator with the projection applied.</returns> /// <summary> /// Projects each element in a generator to a new form. /// </summary> /// <typeparam name="T">The type of the generator's value.</typeparam> /// <typeparam name="TResult">The type of the resultant generator's value.</typeparam> /// <param name="gen">The generator to apply the projection to.</param> /// <param name="selector">A projection function to apply to each value.</param> /// <returns>A new generator with the projection applied.</returns> public static IGen <TResult> Select <T, TResult>(this IGen <T> gen, Func <T, TResult> selector) { GenInstanceTransformation <T, TResult> transformation = (instance) => { var sourceExampleSpace = instance.ExampleSpace; var projectedExampleSpace = instance.ExampleSpace.Map(selector); return(GenIterationFactory.Instance( instance.ReplayParameters, instance.NextParameters, projectedExampleSpace, instance.ExampleSpaceHistory)); }; return(gen.TransformInstances(transformation)); }
public static IGen <T> Unfold <T>( this IGen <T> gen, Func <T, IExampleSpace <T> > unfolder) { GenInstanceTransformation <T, T> transformation = (instance) => { return(GenIterationFactory.Instance( instance.ReplayParameters, instance.NextParameters, unfolder(instance.ExampleSpace.Current.Value), instance.ExampleSpaceHistory)); }; return(gen.TransformInstances(transformation)); }
protected override IEnumerable <IGenIteration <IEnumerable <T> > > Run(GenParameters parameters) { var rng = parameters.Rng; do { var initialRng = rng; var nextRng = initialRng.Next(); var forkedRng = initialRng.Fork(); var exampleSpace = CreateInfiniteEnumerableSpace(_elementGen, parameters.With(rng: forkedRng), _iterationLimit); yield return(GenIterationFactory.Instance( parameters.With(rng: initialRng), parameters.With(rng: nextRng), exampleSpace)); rng = rng.Next(); } while (true); }
/// <summary> /// Filters a generator's values based on a predicate. Does not alter the structure of the stream. Instead, /// it replaces the filtered value with a token, which enables discard counting whilst running the generator. /// </summary> /// <param name="gen">The generator to apply the predicate to.</param> /// <param name="pred">A predicate function that tests each value.</param> /// <returns>A new generator with the filter applied.</returns> public static IGen <T> Where <T>(this IGen <T> gen, Func <T, bool> pred) { GenInstanceTransformation <T, T> applyPredicateToInstance = (instance) => { var filteredExampleSpace = instance.ExampleSpace.Filter(pred); if (filteredExampleSpace == null) { return(GenIterationFactory.Discard <T>( instance.ReplayParameters, instance.NextParameters, instance.ExampleSpace)); } return(GenIterationFactory.Instance( instance.ReplayParameters, instance.NextParameters, filteredExampleSpace, instance.ExampleSpaceHistory)); }; GenStreamTransformation <T, T> resizeAndTerminateAfterConsecutiveDiscards = (stream) => { const int MaxConsecutiveDiscards = 10; return(stream .WithConsecutiveDiscardCount(_ => true, iteration => iteration.IsDiscard()) .Select((x) => { var(iteration, consecutiveDiscardCount) = x; if (consecutiveDiscardCount >= MaxConsecutiveDiscards) { var resizedIteration = GenIterationFactory.Discard <T>( iteration.ReplayParameters, iteration.NextParameters.With(size: iteration.NextParameters.Size.BigIncrement()), iteration.Data.Discard !.ExampleSpace); return (iteration: resizedIteration, consecutiveDiscardCount); }
public static IGen <T> NoShrink <T>(this IGen <T> gen) => gen.TransformInstances(instance => GenIterationFactory.Instance( instance.ReplayParameters, instance.NextParameters, ExampleSpaceFactory.Singleton(instance.ExampleSpace.Current.Id, instance.ExampleSpace.Current.Value), instance.ExampleSpaceHistory));
public static IGen <T> Cast <T>(this IGen gen) => new FunctionalGen <T>(parameters => gen.Advanced .Run(parameters) .Select(iteration => iteration.Data.Match( onInstance: instance => GenIterationFactory.Instance <T>( iteration.ReplayParameters, iteration.NextParameters, instance.ExampleSpace.Cast <T>(), instance.ExampleSpaceHistory), onError: error => GenIterationFactory.Error <T>( iteration.ReplayParameters, iteration.NextParameters, error.GenName, error.Message), onDiscard: discard => GenIterationFactory.Discard <T>( iteration.ReplayParameters, iteration.NextParameters, discard.ExampleSpace))));