canonical method

Range<C> canonical(
  1. DiscreteDomain<C> domain
)

Returns the canonical form of this range in the given domain. The canonical form has the following properties:

  • equivalence: {@code a.canonical().contains(v) == a.contains(v)} for all {@code v} (in other words, {@code ContiguousSet.create(a.canonical(domain), domain).equals( ContiguousSet.create(a, domain))}
  • uniqueness: unless {@code a.isEmpty()}, {@code ContiguousSet.create(a, domain).equals(ContiguousSet.create(b, domain))} implies {@code a.canonical(domain).equals(b.canonical(domain))}
  • idempotence: {@code a.canonical(domain).canonical(domain).equals(a.canonical(domain))}

Furthermore, this method guarantees that the range returned will be one of the following canonical forms:

  • [start..end)
  • [start..+∞)
  • (-∞..end) (only if type {@code C} is unbounded below)
  • (-∞..+∞) (only if type {@code C} is unbounded below)

Implementation

Range<C> canonical(DiscreteDomain<C> domain) {
  checkNotNull(domain);
  Cut<C> lower = lowerBound.canonical(domain);
  Cut<C> upper = upperBound.canonical(domain);
  return (lower == lowerBound && upper == upperBound)
      ? this
      : create(lower, upper);
}