public static IEnumerable <Inverse> InvertConditionals(Conditional conditional, Pipeline backward, string affectedTag, ImmutableList <CollectionIdentifier> collectionIdentifiers) { return(InvertPipeline(conditional.ChildPipeline) .Select(childInverse => new Inverse( childInverse.InversePipeline.Compose(backward), Subset.Empty.Add(affectedTag), conditional.Exists ? Operation.Add : Operation.Remove, Subset.FromPipeline(backward), childInverse.Projection, collectionIdentifiers))); }
public static IEnumerable <Inverse> InvertPaths(Label start, Pipeline pipeline, Path path, Projection projection, Pipeline backward, ImmutableList <CollectionIdentifier> collectionIdentifiers) { var nextBackward = backward.PrependPath(ReversePath(path)); var conditionalInverses = from conditional in pipeline.Conditionals where conditional.Start == path.Target from inverse in InvertConditionals(conditional, nextBackward, start.Name, collectionIdentifiers) select inverse; var nestedInverses = from namedSpecification in projection.GetNamedSpecifications() let nestedSpecification = namedSpecification.specification from nestedPath in nestedSpecification.Pipeline.Paths where nestedPath.Start == path.Target let collectionIdentifier = NewCollectionIdentifier(namedSpecification.name, Subset.FromPipeline(nextBackward)) from nestedInverse in InvertPaths( start, nestedSpecification.Pipeline, nestedPath, nestedSpecification.Projection, nextBackward, collectionIdentifiers.Add(collectionIdentifier)) select nestedInverse; var inversePipeline = nextBackward.AddStart(path.Target); var newInverse = new Inverse( inversePipeline, Subset.Empty.Add(start.Name), Operation.Add, Subset.FromPipeline(inversePipeline), projection, collectionIdentifiers); var nextInverses = from nextPath in pipeline.Paths where nextPath.Start == path.Target from nextInverse in InvertPaths(start, pipeline, nextPath, projection, nextBackward, collectionIdentifiers) select nextInverse; return(nextInverses.Concat(conditionalInverses).Concat(nestedInverses).Prepend(newInverse)); }