/// <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));
            }
        }
Example #2
0
 /// <summary>
 ///     Compare two <c>Chunk</c>
 /// </summary>
 /// <param name="other">The other <see cref="SymbolicChunk{T}" /> to compare with</param>
 /// <returns><c>true</c> if <c>this</c> have the same <see cref="Min" /> and <see cref="Max" />; <c>false</c> otherwise</returns>
 // ReSharper disable once MemberCanBePrivate.Global
 public bool Equals(SymbolicChunk <T> other) => Equals(MinIncluded, other.MinIncluded) && Equals(MaxIncluded, other.MaxIncluded);