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); })); };
static (IExampleSpace <T>?exampleSpace, int countTaken) TakeRec(IExampleSpace <T> exampleSpace, int count) { if (count <= 0) { return(null, 0); } var takenSubspace = new List <IExampleSpace <T> >(); var countTaken = 1; foreach (var subExampleSpace in exampleSpace.Subspace) { if (countTaken >= count) { break; } var(takenSubExampleSpace, subCountTaken) = TakeRec(subExampleSpace, count - countTaken); if (takenSubExampleSpace != null) { takenSubspace.Add(takenSubExampleSpace); } countTaken += subCountTaken; } var takenExampleSpace = ExampleSpaceFactory.Create <T>(exampleSpace.Current, takenSubspace); return(takenExampleSpace, countTaken); }
public static ExplorationStage <T> NonCounterexample( IExampleSpace <T> exampleSpace, IEnumerable <int> path) => new ExplorationStage <T>( nonCounterexample: new NonCounterexample(exampleSpace, path), counterexample: null, discard: null);
private static void AssertUnlimited <T>(IExampleSpace <IEnumerable <T> > exampleSpace) { exampleSpace.Traverse().Take(10).ToList().ForEach(enumerable => { AssertUnlimited(enumerable); }); }
private static void AssertLimit <T>(IExampleSpace <IEnumerable <T> > exampleSpace, int expectedLimit) { exampleSpace.Traverse().Take(10).ToList().ForEach(enumerable => { AssertLimit(enumerable, expectedLimit); }); }
public static string Render <T>( this IExampleSpace <T> exampleSpace, Func <T, string> renderValue) { var lines = RenderLines(exampleSpace, renderValue).ToList(); return(string.Join(Environment.NewLine, lines)); }
/// <summary> /// Maps all of the examples in an example space by the given selector function. /// </summary> /// <typeparam name="T">The type of the target example space's values.</typeparam> /// <typeparam name="TResult">The new type of an example's value</typeparam> /// <param name="exampleSpace">The example space to operate on.</param> /// <param name="selector">A function to apply to each example in the example space.</param> /// <returns>A new example space with the mapping function applied.</returns> public static IExampleSpace <TResult> MapExamples <T, TResult>( this IExampleSpace <T> exampleSpace, Func <IExample <T>, IExample <TResult> > f) { return(ExampleSpaceFactory.Create( f(exampleSpace.Current), exampleSpace.Subspace.Select(es => MapExamples(es, f)))); }
public static ExplorationStage <T> Counterexample( IExampleSpace <T> exampleSpace, IEnumerable <int> path, Exception?exception) => new ExplorationStage <T>( nonCounterexample: null, counterexample: new Counterexample(exampleSpace, path, exception), discard: null);
static IEnumerable <IExample <T> > SampleRec(IExampleSpace <T> exampleSpace) { yield return(exampleSpace.Current); foreach (var subExampleSpace in exampleSpace.Subspace.SelectMany(es => SampleRec(es))) { yield return(subExampleSpace); } }
/// <summary> /// Maps all of the example values in an example space by the given selector function. /// </summary> /// <typeparam name="T">The type of the target example space's values.</typeparam> /// <typeparam name="TResult">The new type of an example's value</typeparam> /// <param name="exampleSpace">The example space to operate on.</param> /// <param name="selector">A function to apply to each value in the example space.</param> /// <returns>A new example space with the mapping function applied.</returns> public static IExampleSpace <TResult> Map <T, TResult>( this IExampleSpace <T> exampleSpace, Func <T, TResult> f) { return(exampleSpace.MapExamples(example => new Example <TResult>( example.Id, f(example.Value), example.Distance))); }
static ExplorationStage <T> AnalyzeExampleSpace( IExampleSpace <T> exampleSpace, IEnumerable <int> path, AnalyzeExploration <T> analyze) { return(analyze(exampleSpace.Current).Match( onSuccess: () => ExplorationStage <T> .Factory.NonCounterexample(exampleSpace, path), onDiscard: () => ExplorationStage <T> .Factory.Discard(exampleSpace), onFail: exception => ExplorationStage <T> .Factory.Counterexample(exampleSpace, path, exception))); }
public static IEnumerable <IExample <T> > TraverseExamples <T>(this IExampleSpace <T> exampleSpace) { yield return(exampleSpace.Current); foreach (var exampleSubSpace in exampleSpace.Subspace) { foreach (var subExample in TraverseExamples(exampleSubSpace)) { yield return(subExample); } } }
static IEnumerable <IExampleSpace <TResult> > BindSubspace( IExampleSpace <T> leftExampleSpace, Func <T, IGen <TResult> > selector, GenParameters parameters) { var stream = BindExampleSpace(leftExampleSpace, selector, parameters); foreach (var iteration in stream) { if (iteration.ToEither <TResult, TResult>().IsLeft(out IGenInstance <TResult> instance)) { yield return(instance.ExampleSpace); } } }
/// <summary> /// Filters the examples in an example space by the given predicate. /// </summary> /// <typeparam name="T">The type of the target example space's values.</typeparam> /// <param name="exampleSpace">The example space to operate on.</param> /// <param name="pred">The predicate used to test each value in the example space.</param> /// <returns>A new example space, containing only the examples whose values passed the predicate.</returns> public static IExampleSpace <T>?Filter <T>( this IExampleSpace <T> exampleSpace, Func <T, bool> pred) { if (pred(exampleSpace.Current.Value) == false) { return(null); } return(ExampleSpaceFactory.Create( exampleSpace.Current, exampleSpace.Subspace .Select(es => es.Filter(pred)) .Where(es => es != null) .Cast <IExampleSpace <T> >())); }
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))); }
public static IExampleSpace <T> Cast <T>(this IExampleSpace exampleSpace) { T newValue; try { newValue = (T)exampleSpace.Current.Value; } catch { newValue = (T)Convert.ChangeType(exampleSpace.Current.Value, typeof(T)); } var example = new Example <T>(exampleSpace.Current.Id, newValue, exampleSpace.Current.Distance); var subspace = exampleSpace.Subspace.Select(child => Cast <T>(child)); return(ExampleSpaceFactory.Create(example, subspace)); }
private static IEnumerable <string> RenderLines <T>(IExampleSpace <T> exampleSpace, Func <T, string> renderValue) { // TODO: Would be more efficient if an example exposed that it was terminal (the last one of a shrink) // TODO: Measure the max space of a value, pad all the renderings by that // TODO: F*****g grinds to a halt on big spaces var example = exampleSpace.Current; var distance = example.Distance; var distanceRounded = Math.Round(example.Distance, 4); var distanceRendered = distance == distanceRounded?distanceRounded.ToString() : $"{distanceRounded}..."; yield return($"{renderValue(example.Value)} (Id = {example.Id.HashCode}, Distance = {distanceRendered})"); var subExampleSpaces = exampleSpace.Subspace.ToList(); for (var index = 0; index < subExampleSpaces.Count; index++) { var subExampleSpace = subExampleSpaces[index]; var isLastSubExampleSpace = index == subExampleSpaces.Count - 1; var firstPrefix = isLastSubExampleSpace ? "└> " : "├> "; var otherPrefix = isLastSubExampleSpace ? " " : "| "; var subLines = RenderLines(subExampleSpace, renderValue).ToList(); for (var subIndex = 0; subIndex < subLines.Count; subIndex++) { if (subIndex == 0) { yield return($"{firstPrefix}{subLines[subIndex]}"); } else { yield return($"{otherPrefix}{subLines[subIndex]}"); } } } }
public static IEnumerable <ExplorationStage <T> > Explore <T>( this IExampleSpace <T> exampleSpace, AnalyzeExploration <T> analyze) {
private record CounterexampleSubspace <T>( IExampleSpace <T> CounterexampleSpace, IEnumerable <int> Path);
public static ExplorationStage <T> Discard(IExampleSpace <T> exampleSpace) => new ExplorationStage <T>( nonCounterexample: null, counterexample: null, discard: new Discard(exampleSpace));
public static List <IExample <T> > Sample <T>( this IExampleSpace <T> exampleSpace, int maxExamples = 10) {
static SubspaceExploration <T> GetSubspaceExploration(AnalyzeExploration <T> analyze, IExampleSpace <T> exampleSpace) => exampleSpace.Subspace .Select((exampleSpace, subspaceIndex) =>
public static IExampleSpace <T> Take <T>(this IExampleSpace <T> exampleSpace, int count) {
public static IEnumerable <T> Traverse <T>(this IExampleSpace <T> exampleSpace) => exampleSpace.TraverseExamples().Select(example => example.Value);