/// <inheritdoc /> public void RemoveRange(ISymbolicNumericType <T> range, ISymbolicNumericType <T> errors) { var order = new SymbolicOrder <T>(range.MinValue, range.MaxValue); order.AddRange(Chunks); order.AddRange(range.Chunks); var unknownBounds = false; range.Chunks.ForEach(chunk => { if (!chunk.Min.Symbolic && !chunk.Max.Symbolic) { RemoveRange(order, chunk, errors, ref unknownBounds); } }); range.Chunks.ForEach(chunk => { if (chunk.Min.Symbolic || chunk.Max.Symbolic) { RemoveRange(order, chunk, errors, ref unknownBounds); } }); }
/// <summary> /// Remove /// <param name="remove"></param> /// from the current Range. /// </summary> /// <param name="order">The Partial Order of SymbolicConstants.</param> /// <param name="remove"></param> /// <param name="errors">The values removed several times.</param> /// <param name="unknownBounds">If we should add unknown bounds Range or all ranges.</param> /// <returns>The Range of the errors (removed multiple times)</returns> private void RemoveRange(SymbolicOrder <T> order, SymbolicChunk <T> remove, ISymbolicNumericType <T> errors, ref bool unknownBounds) { var comparable = false; foreach (var source in Chunks.ToArray()) { var beforeSource = order.LessThan(remove.Max, source.Min); if (beforeSource == true) { // Remove before Source // => do nothing continue; } var afterSource = order.GreaterThan(remove.Min, source.Max); if (afterSource == true) { // Remove after Source // => Do nothing continue; } if (beforeSource == null || afterSource == null) { // Unable to compare continue; } comparable = true; Chunks.Remove(source); var(sourceMin, sourceMinIncluded, sourceMax, sourceMaxIncluded) = source; var(removeMin, removeMinIncluded, removeMax, removeMaxIncluded) = remove; if (order.LessThan(removeMin, sourceMin) == true && order.LessThan(sourceMin, removeMax) == true) { // Remove starts too low errors.Range(removeMin, removeMinIncluded, sourceMin, !sourceMinIncluded); removeMin = sourceMin; removeMaxIncluded = sourceMinIncluded; } if (order.LessThan(removeMin, sourceMax) == true && order.LessThan(sourceMax, removeMax) == true) { // Remove ends too high errors.Range(sourceMax, !sourceMaxIncluded, removeMax, removeMaxIncluded); removeMax = sourceMax; removeMaxIncluded = sourceMaxIncluded; } if (removeMin.Equals(sourceMin)) { if (removeMinIncluded != sourceMinIncluded) { if (removeMinIncluded) { errors.Value(removeMin); } else { if (!unknownBounds) { Value(removeMin); } } removeMinIncluded = false; } sourceMin = removeMax; sourceMinIncluded = !removeMaxIncluded; } if (removeMax.Equals(sourceMax)) { if (removeMaxIncluded != sourceMaxIncluded) { if (removeMaxIncluded) { errors.Value(sourceMax); } else { if (!unknownBounds) { Value(sourceMax); } } removeMaxIncluded = false; } sourceMax = removeMin; sourceMaxIncluded = !removeMinIncluded; } if (unknownBounds) { continue; } if (order.LessThan(sourceMin, removeMin) == true && order.LessThan(removeMin, sourceMax) == true && !sourceMin.Equals(removeMax) || !removeMin.Equals(sourceMax) && order.LessThan(sourceMin, removeMax) == true && order.LessThan(removeMax, sourceMax) == true) { Range(sourceMin, sourceMinIncluded, removeMin, !removeMinIncluded); Range(removeMax, !removeMaxIncluded, sourceMax, sourceMaxIncluded); } else { if (order.LessThan(sourceMin, sourceMax) != false || sourceMinIncluded && sourceMaxIncluded) { Range(sourceMin, sourceMinIncluded, sourceMax, sourceMaxIncluded); } } } if (!comparable) { // Add ?..remove.Min and remove.Max..? if (!unknownBounds) { Chunks.Clear(); unknownBounds = true; } Chunks.Add(new SymbolicChunk <T>(new SymbolicConstant <T>(), remove.Min, true, !remove.MinIncluded)); Chunks.Add(new SymbolicChunk <T>(remove.Max, new SymbolicConstant <T>(), !remove.MaxIncluded, true)); } }