public static IExampleSpace <TResult> MergeInternal <T, TResult>( List <IExampleSpace <T> > exampleSpaces, Func <List <T>, TResult> mergeValues, ShrinkFunc <List <IExampleSpace <T> > > shrinkExampleSpaces, MeasureFunc <List <IExampleSpace <T> > > measureMerge, ImmutableHashSet <ExampleId> encounteredIds, bool enableSmallestExampleSpacesOptimization, bool isRoot) { IExampleSpace <TResult> GenerateNextExampleSpace(IEnumerable <IExampleSpace <T> > exampleSpaces, ImmutableHashSet <ExampleId> encounteredIds) { return(MergeInternal( exampleSpaces.ToList(), mergeValues, shrinkExampleSpaces, measureMerge, encounteredIds, enableSmallestExampleSpacesOptimization, false)); } var mergedId = exampleSpaces.Aggregate( ExampleId.Primitive(exampleSpaces.Count()), (acc, curr) => ExampleId.Combine(acc, curr.Current.Id)); var mergedValue = mergeValues(exampleSpaces.Select(es => es.Current.Value).ToList()); var mergedDistance = measureMerge(exampleSpaces); var current = new Example <TResult>( mergedId, mergedValue, mergedDistance); var smallestExampleSpacesShrink = enableSmallestExampleSpacesOptimization && isRoot && exampleSpaces.Any(exampleSpace => exampleSpace.Subspace.Any()) ? exampleSpaces .Select(exampleSpace => { var smallestExampleSpace = exampleSpace.Subspace.FirstOrDefault() ?? exampleSpace; return(smallestExampleSpace); }) .ToList() : null; var exampleSpaceCullingShrinks = shrinkExampleSpaces(exampleSpaces); var subspaceMergingShrinks = exampleSpaces .Select((exampleSpace, index) => LiftAndInsertSubspace(exampleSpaces, exampleSpace.Subspace, index)) .SelectMany(exampleSpaces => exampleSpaces); var shrinks = TraverseUnencountered( Enumerable.Concat( smallestExampleSpacesShrink == null ? Enumerable.Empty <List <IExampleSpace <T> > >() : new[] { smallestExampleSpacesShrink }.AsEnumerable(), Enumerable.Concat(exampleSpaceCullingShrinks, subspaceMergingShrinks)), encounteredIds, GenerateNextExampleSpace); return(new ExampleSpace <TResult>(current, shrinks)); }
static IExampleSpace <TResult> JoinExampleSpaces( IExampleSpace <T> leftExampleSpace, IExampleSpace <TResult> rightExampleSpace, Func <T, IGen <TResult> > selector, GenParameters parameters) { var jointExampleSpace = rightExampleSpace.MapExamples(example => new Example <TResult>( ExampleId.Combine(leftExampleSpace.Current.Id, example.Id), example.Value, leftExampleSpace.Current.Distance + example.Distance)); var boundLeftSubspace = leftExampleSpace.Subspace.SelectMany(leftExampleSubspace => BindSubspace(leftExampleSubspace, selector, parameters)); return(ExampleSpaceFactory.Create( jointExampleSpace.Current, Enumerable.Concat(boundLeftSubspace, rightExampleSpace.Subspace))); }