diff --git a/benches/large_case.rs b/benches/large_case.rs index 476228c8..14e8d497 100644 --- a/benches/large_case.rs +++ b/benches/large_case.rs @@ -4,16 +4,21 @@ use std::time::Duration; extern crate criterion; use self::criterion::*; +use pubgrub::bounded_range::BoundedRange; +use pubgrub::discrete_range::DiscreteRange; use pubgrub::package::Package; use pubgrub::solver::{resolve, OfflineDependencyProvider}; use pubgrub::version::{NumberVersion, SemanticVersion, Version}; +use pubgrub::version_set::VersionSet; use serde::de::Deserialize; use std::hash::Hash; -fn bench<'a, P: Package + Deserialize<'a>, V: Version + Hash + Deserialize<'a>>( +fn bench<'a, P: Package + Deserialize<'a>, V: VersionSet + Deserialize<'a>>( b: &mut Bencher, case: &'a str, -) { +) where + ::V: Deserialize<'a>, +{ let dependency_provider: OfflineDependencyProvider = ron::de::from_str(&case).unwrap(); b.iter(|| { @@ -33,13 +38,17 @@ fn bench_nested(c: &mut Criterion) { let case = case.unwrap().path(); let name = case.file_name().unwrap().to_string_lossy(); let data = std::fs::read_to_string(&case).unwrap(); - if name.ends_with("u16_NumberVersion.ron") { + if name.ends_with("u16_discrete_NumberVersion.ron") { group.bench_function(name, |b| { - bench::(b, &data); + bench::>(b, &data); + }); + } else if name.ends_with("u16_bounded_NumberVersion.ron") { + group.bench_function(name, |b| { + bench::>(b, &data); }); } else if name.ends_with("str_SemanticVersion.ron") { group.bench_function(name, |b| { - bench::<&str, SemanticVersion>(b, &data); + bench::<&str, DiscreteRange>(b, &data); }); } } diff --git a/examples/branching_error_reporting.rs b/examples/branching_error_reporting.rs index d4dfb719..682e725b 100644 --- a/examples/branching_error_reporting.rs +++ b/examples/branching_error_reporting.rs @@ -1,12 +1,12 @@ // SPDX-License-Identifier: MPL-2.0 +use pubgrub::bounded_range::BoundedRange; use pubgrub::error::PubGrubError; -use pubgrub::range::Range; use pubgrub::report::{DefaultStringReporter, Reporter}; use pubgrub::solver::{resolve, OfflineDependencyProvider}; use pubgrub::version::SemanticVersion; -type SemVS = Range; +type SemVS = BoundedRange; // https://github.com/dart-lang/pub/blob/master/doc/solver.md#branching-error-reporting fn main() { @@ -14,16 +14,16 @@ fn main() { #[rustfmt::skip] // root 1.0.0 depends on foo ^1.0.0 dependency_provider.add_dependencies( - "root", (1, 0, 0), - [("foo", Range::from_range_bounds((1, 0, 0)..(2, 0, 0)))], + "root", (1, 0, 0), + [("foo", BoundedRange::from_range_bounds((1, 0, 0)..(2, 0, 0)))], ); #[rustfmt::skip] // foo 1.0.0 depends on a ^1.0.0 and b ^1.0.0 dependency_provider.add_dependencies( "foo", (1, 0, 0), [ - ("a", Range::from_range_bounds((1, 0, 0)..(2, 0, 0))), - ("b", Range::from_range_bounds((1, 0, 0)..(2, 0, 0))), + ("a", BoundedRange::from_range_bounds((1, 0, 0)..(2, 0, 0))), + ("b", BoundedRange::from_range_bounds((1, 0, 0)..(2, 0, 0))), ], ); #[rustfmt::skip] @@ -31,15 +31,15 @@ fn main() { dependency_provider.add_dependencies( "foo", (1, 1, 0), [ - ("x", Range::from_range_bounds((1, 0, 0)..(2, 0, 0))), - ("y", Range::from_range_bounds((1, 0, 0)..(2, 0, 0))), + ("x", BoundedRange::from_range_bounds((1, 0, 0)..(2, 0, 0))), + ("y", BoundedRange::from_range_bounds((1, 0, 0)..(2, 0, 0))), ], ); #[rustfmt::skip] // a 1.0.0 depends on b ^2.0.0 dependency_provider.add_dependencies( - "a", (1, 0, 0), - [("b", Range::from_range_bounds((2, 0, 0)..(3, 0, 0)))], + "a", (1, 0, 0), + [("b", BoundedRange::from_range_bounds((2, 0, 0)..(3, 0, 0)))], ); // b 1.0.0 and 2.0.0 have no dependencies. dependency_provider.add_dependencies("b", (1, 0, 0), []); @@ -47,8 +47,8 @@ fn main() { #[rustfmt::skip] // x 1.0.0 depends on y ^2.0.0. dependency_provider.add_dependencies( - "x", (1, 0, 0), - [("y", Range::from_range_bounds((2, 0, 0)..(3, 0, 0)))], + "x", (1, 0, 0), + [("y", BoundedRange::from_range_bounds((2, 0, 0)..(3, 0, 0)))], ); // y 1.0.0 and 2.0.0 have no dependencies. dependency_provider.add_dependencies("y", (1, 0, 0), []); diff --git a/examples/caching_dependency_provider.rs b/examples/caching_dependency_provider.rs index cb278942..5b3c2836 100644 --- a/examples/caching_dependency_provider.rs +++ b/examples/caching_dependency_provider.rs @@ -3,13 +3,13 @@ use std::cell::RefCell; use std::error::Error; +use pubgrub::bounded_range::BoundedRange; use pubgrub::package::Package; -use pubgrub::range::Range; use pubgrub::solver::{resolve, Dependencies, DependencyProvider, OfflineDependencyProvider}; use pubgrub::version::NumberVersion; use pubgrub::version_set::VersionSet; -type NumVS = Range; +type NumVS = BoundedRange; // An example implementing caching dependency provider that will // store queried dependencies in memory and check them before querying more from remote. diff --git a/examples/doc_interface.rs b/examples/doc_interface.rs index d409dcce..768bcb09 100644 --- a/examples/doc_interface.rs +++ b/examples/doc_interface.rs @@ -1,10 +1,10 @@ // SPDX-License-Identifier: MPL-2.0 -use pubgrub::range::Range; +use pubgrub::bounded_range::BoundedRange; use pubgrub::solver::{resolve, OfflineDependencyProvider}; use pubgrub::version::NumberVersion; -type NumVS = Range; +type NumVS = BoundedRange; // `root` depends on `menu` and `icons` // `menu` depends on `dropdown` @@ -14,10 +14,10 @@ type NumVS = Range; fn main() { let mut dependency_provider = OfflineDependencyProvider::<&str, NumVS>::new(); dependency_provider.add_dependencies( - "root", 1, [("menu", Range::any()), ("icons", Range::any())], + "root", 1, [("menu", BoundedRange::any()), ("icons", BoundedRange::any())], ); - dependency_provider.add_dependencies("menu", 1, [("dropdown", Range::any())]); - dependency_provider.add_dependencies("dropdown", 1, [("icons", Range::any())]); + dependency_provider.add_dependencies("menu", 1, [("dropdown", BoundedRange::any())]); + dependency_provider.add_dependencies("dropdown", 1, [("icons", BoundedRange::any())]); dependency_provider.add_dependencies("icons", 1, []); // Run the algorithm. diff --git a/examples/doc_interface_error.rs b/examples/doc_interface_error.rs index a3d7e61e..77bac976 100644 --- a/examples/doc_interface_error.rs +++ b/examples/doc_interface_error.rs @@ -1,12 +1,12 @@ // SPDX-License-Identifier: MPL-2.0 +use pubgrub::bounded_range::BoundedRange; use pubgrub::error::PubGrubError; -use pubgrub::range::Range; use pubgrub::report::{DefaultStringReporter, Reporter}; use pubgrub::solver::{resolve, OfflineDependencyProvider}; use pubgrub::version::SemanticVersion; -type SemVS = Range; +type SemVS = BoundedRange; // `root` depends on `menu`, `icons 1.0.0` and `intl 5.0.0` // `menu 1.0.0` depends on `dropdown < 2.0.0` @@ -20,46 +20,46 @@ fn main() { let mut dependency_provider = OfflineDependencyProvider::<&str, SemVS>::new(); // Direct dependencies: menu and icons. dependency_provider.add_dependencies("root", (1, 0, 0), [ - ("menu", Range::any()), - ("icons", Range::exact((1, 0, 0))), - ("intl", Range::exact((5, 0, 0))), + ("menu", BoundedRange::any()), + ("icons", BoundedRange::exact((1, 0, 0))), + ("intl", BoundedRange::exact((5, 0, 0))), ]); // Dependencies of the menu lib. dependency_provider.add_dependencies("menu", (1, 0, 0), [ - ("dropdown", Range::from_range_bounds(..(2, 0, 0))), + ("dropdown", BoundedRange::from_range_bounds(..(2, 0, 0))), ]); dependency_provider.add_dependencies("menu", (1, 1, 0), [ - ("dropdown", Range::from_range_bounds((2, 0, 0)..)), + ("dropdown", BoundedRange::from_range_bounds((2, 0, 0)..)), ]); dependency_provider.add_dependencies("menu", (1, 2, 0), [ - ("dropdown", Range::from_range_bounds((2, 0, 0)..)), + ("dropdown", BoundedRange::from_range_bounds((2, 0, 0)..)), ]); dependency_provider.add_dependencies("menu", (1, 3, 0), [ - ("dropdown", Range::from_range_bounds((2, 0, 0)..)), + ("dropdown", BoundedRange::from_range_bounds((2, 0, 0)..)), ]); dependency_provider.add_dependencies("menu", (1, 4, 0), [ - ("dropdown", Range::from_range_bounds((2, 0, 0)..)), + ("dropdown", BoundedRange::from_range_bounds((2, 0, 0)..)), ]); dependency_provider.add_dependencies("menu", (1, 5, 0), [ - ("dropdown", Range::from_range_bounds((2, 0, 0)..)), + ("dropdown", BoundedRange::from_range_bounds((2, 0, 0)..)), ]); // Dependencies of the dropdown lib. dependency_provider.add_dependencies("dropdown", (1, 8, 0), [ - ("intl", Range::exact((3, 0, 0))), + ("intl", BoundedRange::exact((3, 0, 0))), ]); dependency_provider.add_dependencies("dropdown", (2, 0, 0), [ - ("icons", Range::exact((2, 0, 0))), + ("icons", BoundedRange::exact((2, 0, 0))), ]); dependency_provider.add_dependencies("dropdown", (2, 1, 0), [ - ("icons", Range::exact((2, 0, 0))), + ("icons", BoundedRange::exact((2, 0, 0))), ]); dependency_provider.add_dependencies("dropdown", (2, 2, 0), [ - ("icons", Range::exact((2, 0, 0))), + ("icons", BoundedRange::exact((2, 0, 0))), ]); dependency_provider.add_dependencies("dropdown", (2, 3, 0), [ - ("icons", Range::exact((2, 0, 0))), + ("icons", BoundedRange::exact((2, 0, 0))), ]); // Icons have no dependencies. diff --git a/examples/doc_interface_semantic.rs b/examples/doc_interface_semantic.rs index cce059bc..ea823b87 100644 --- a/examples/doc_interface_semantic.rs +++ b/examples/doc_interface_semantic.rs @@ -1,12 +1,12 @@ // SPDX-License-Identifier: MPL-2.0 +use pubgrub::bounded_range::BoundedRange; use pubgrub::error::PubGrubError; -use pubgrub::range::Range; use pubgrub::report::{DefaultStringReporter, Reporter}; use pubgrub::solver::{resolve, OfflineDependencyProvider}; use pubgrub::version::SemanticVersion; -type SemVS = Range; +type SemVS = BoundedRange; // `root` depends on `menu` and `icons 1.0.0` // `menu 1.0.0` depends on `dropdown < 2.0.0` @@ -19,43 +19,43 @@ fn main() { let mut dependency_provider = OfflineDependencyProvider::<&str, SemVS>::new(); // Direct dependencies: menu and icons. dependency_provider.add_dependencies("root", (1, 0, 0), [ - ("menu", Range::any()), - ("icons", Range::exact((1, 0, 0))), + ("menu", BoundedRange::any()), + ("icons", BoundedRange::exact((1, 0, 0))), ]); // Dependencies of the menu lib. dependency_provider.add_dependencies("menu", (1, 0, 0), [ - ("dropdown", Range::from_range_bounds(..(2, 0, 0))), + ("dropdown", BoundedRange::from_range_bounds(..(2, 0, 0))), ]); dependency_provider.add_dependencies("menu", (1, 1, 0), [ - ("dropdown", Range::from_range_bounds((2, 0, 0)..)), + ("dropdown", BoundedRange::from_range_bounds((2, 0, 0)..)), ]); dependency_provider.add_dependencies("menu", (1, 2, 0), [ - ("dropdown", Range::from_range_bounds((2, 0, 0)..)), + ("dropdown", BoundedRange::from_range_bounds((2, 0, 0)..)), ]); dependency_provider.add_dependencies("menu", (1, 3, 0), [ - ("dropdown", Range::from_range_bounds((2, 0, 0)..)), + ("dropdown", BoundedRange::from_range_bounds((2, 0, 0)..)), ]); dependency_provider.add_dependencies("menu", (1, 4, 0), [ - ("dropdown", Range::from_range_bounds((2, 0, 0)..)), + ("dropdown", BoundedRange::from_range_bounds((2, 0, 0)..)), ]); dependency_provider.add_dependencies("menu", (1, 5, 0), [ - ("dropdown", Range::from_range_bounds((2, 0, 0)..)), + ("dropdown", BoundedRange::from_range_bounds((2, 0, 0)..)), ]); // Dependencies of the dropdown lib. dependency_provider.add_dependencies("dropdown", (1, 8, 0), []); dependency_provider.add_dependencies("dropdown", (2, 0, 0), [ - ("icons", Range::exact((2, 0, 0))), + ("icons", BoundedRange::exact((2, 0, 0))), ]); dependency_provider.add_dependencies("dropdown", (2, 1, 0), [ - ("icons", Range::exact((2, 0, 0))), + ("icons", BoundedRange::exact((2, 0, 0))), ]); dependency_provider.add_dependencies("dropdown", (2, 2, 0), [ - ("icons", Range::exact((2, 0, 0))), + ("icons", BoundedRange::exact((2, 0, 0))), ]); dependency_provider.add_dependencies("dropdown", (2, 3, 0), [ - ("icons", Range::exact((2, 0, 0))), + ("icons", BoundedRange::exact((2, 0, 0))), ]); // Icons has no dependency. diff --git a/examples/linear_error_reporting.rs b/examples/linear_error_reporting.rs index 8624fe2a..32f1d4d2 100644 --- a/examples/linear_error_reporting.rs +++ b/examples/linear_error_reporting.rs @@ -1,12 +1,12 @@ // SPDX-License-Identifier: MPL-2.0 +use pubgrub::bounded_range::BoundedRange; use pubgrub::error::PubGrubError; -use pubgrub::range::Range; use pubgrub::report::{DefaultStringReporter, Reporter}; use pubgrub::solver::{resolve, OfflineDependencyProvider}; use pubgrub::version::SemanticVersion; -type SemVS = Range; +type SemVS = BoundedRange; // https://github.com/dart-lang/pub/blob/master/doc/solver.md#linear-error-reporting fn main() { @@ -16,21 +16,21 @@ fn main() { dependency_provider.add_dependencies( "root", (1, 0, 0), [ - ("foo", Range::from_range_bounds((1, 0, 0)..(2, 0, 0))), - ("baz", Range::from_range_bounds((1, 0, 0)..(2, 0, 0))), + ("foo", BoundedRange::from_range_bounds((1, 0, 0)..(2, 0, 0))), + ("baz", BoundedRange::from_range_bounds((1, 0, 0)..(2, 0, 0))), ], ); #[rustfmt::skip] // foo 1.0.0 depends on bar ^2.0.0 dependency_provider.add_dependencies( - "foo", (1, 0, 0), - [("bar", Range::from_range_bounds((2, 0, 0)..(3, 0, 0)))], + "foo", (1, 0, 0), + [("bar", BoundedRange::from_range_bounds((2, 0, 0)..(3, 0, 0)))], ); #[rustfmt::skip] // bar 2.0.0 depends on baz ^3.0.0 dependency_provider.add_dependencies( - "bar", (2, 0, 0), - [("baz", Range::from_range_bounds((3, 0, 0)..(4, 0, 0)))], + "bar", (2, 0, 0), + [("baz", BoundedRange::from_range_bounds((3, 0, 0)..(4, 0, 0)))], ); // baz 1.0.0 and 3.0.0 have no dependencies dependency_provider.add_dependencies("baz", (1, 0, 0), []); diff --git a/src/bounded_range.rs b/src/bounded_range.rs new file mode 100644 index 00000000..14da412d --- /dev/null +++ b/src/bounded_range.rs @@ -0,0 +1,602 @@ +// SPDX-License-Identifier: MPL-2.0 + +//! Ranges are constraints defining sets of versions. +//! +//! Concretely, those constraints correspond to any set of versions +//! representable as the concatenation, union, and complement +//! of the ranges building blocks. +//! +//! Those building blocks are: +//! - [none()](Range::none): the empty set +//! - [any()](Range::any): the set of all possible versions +//! - [exact(v)](Range::exact): the set containing only the version v +//! - [higher_than(v)](Range::higher_than): the set defined by `v <= versions` +//! - [strictly_lower_than(v)](Range::strictly_lower_than): the set defined by `versions < v` +//! - [between(v1, v2)](Range::between): the set defined by `v1 <= versions < v2` + +use crate::{internal::small_vec::SmallVec, version_set::VersionSet}; +use std::ops::RangeBounds; +use std::{ + cmp::Ordering, + fmt::{Debug, Display, Formatter}, + ops::Bound::{self, Excluded, Included, Unbounded}, +}; + +/// A Range represents multiple intervals of a continuous range of monotone increasing +/// values. +#[derive(Debug, Clone, Eq, PartialEq, Hash)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(transparent))] +pub struct BoundedRange { + segments: SmallVec>, +} + +type Interval = (Bound, Bound); + +impl BoundedRange { + /// Empty set of versions. + pub fn none() -> Self { + Self { + segments: SmallVec::empty(), + } + } + + /// Set of all possible versions + pub fn any() -> Self { + Self { + segments: SmallVec::one((Unbounded, Unbounded)), + } + } + + /// Set of all versions higher or equal to some version + pub fn higher_than(v: impl Into) -> Self { + Self { + segments: SmallVec::one((Included(v.into()), Unbounded)), + } + } + + /// Set of all versions higher to some version + pub fn strictly_higher_than(v: impl Into) -> Self { + Self { + segments: SmallVec::one((Excluded(v.into()), Unbounded)), + } + } + + /// Set of all versions lower to some version + pub fn strictly_lower_than(v: impl Into) -> Self { + Self { + segments: SmallVec::one((Unbounded, Excluded(v.into()))), + } + } + + /// Set of all versions lower or equal to some version + pub fn lower_than(v: impl Into) -> Self { + Self { + segments: SmallVec::one((Unbounded, Included(v.into()))), + } + } + + /// Set of versions greater or equal to `v1` but less than `v2`. + pub fn between(v1: impl Into, v2: impl Into) -> Self { + Self { + segments: SmallVec::one((Included(v1.into()), Excluded(v2.into()))), + } + } +} + +impl BoundedRange { + /// Set containing exactly one version + pub fn exact(v: impl Into) -> Self { + let v = v.into(); + Self { + segments: SmallVec::one((Included(v.clone()), Included(v))), + } + } + + /// Set containing all versions expect one + pub fn not_equal(v: impl Into) -> Self { + let v = v.into(); + Self { + segments: SmallVec::Two([(Unbounded, Excluded(v.clone())), (Excluded(v), Unbounded)]), + } + } + + /// Convert to something that can be used with + /// [BTreeMap::range](std::collections::BTreeMap::range). + /// All versions contained in self, will be in the output, + /// but there may be versions in the output that are not contained in self. + /// Returns None if the range is empty. + pub fn bounding_range(&self) -> Option<(Bound<&V>, Bound<&V>)> { + self.segments.first().map(|(start, _)| { + let end = self + .segments + .last() + .expect("if there is a first element, there must be a last element"); + (bounds_as_ref(start), bounds_as_ref(&end.1)) + }) + } + + /// Returns the complement of this Range. + pub fn negate(&self) -> Self { + match self.segments.first() { + // Complement of ∅ is ∞ + None => Self::any(), + + // Complement of ∞ is ∅ + Some((Unbounded, Unbounded)) => Self::none(), + + // First high bound is +∞ + Some((Included(v), Unbounded)) => Self::strictly_lower_than(v.clone()), + Some((Excluded(v), Unbounded)) => Self::lower_than(v.clone()), + + Some((Unbounded, Included(v))) => { + Self::negate_segments(Excluded(v.clone()), &self.segments[1..]) + } + Some((Unbounded, Excluded(v))) => { + Self::negate_segments(Included(v.clone()), &self.segments[1..]) + } + Some((Included(_), Included(_))) + | Some((Included(_), Excluded(_))) + | Some((Excluded(_), Included(_))) + | Some((Excluded(_), Excluded(_))) => Self::negate_segments(Unbounded, &self.segments), + } + } + + /// Helper function performing the negation of intervals in segments. + fn negate_segments(start: Bound, segments: &[Interval]) -> Self { + let mut complement_segments: SmallVec> = SmallVec::empty(); + let mut start = start; + for (v1, v2) in segments { + complement_segments.push(( + start, + match v1 { + Included(v) => Excluded(v.clone()), + Excluded(v) => Included(v.clone()), + Unbounded => unreachable!(), + }, + )); + start = match v2 { + Included(v) => Excluded(v.clone()), + Excluded(v) => Included(v.clone()), + Unbounded => Unbounded, + } + } + if !matches!(start, Unbounded) { + complement_segments.push((start, Unbounded)); + } + + Self { + segments: complement_segments, + } + } +} + +impl BoundedRange { + /// Returns true if the this Range contains the specified value. + pub fn contains(&self, v: &V) -> bool { + for segment in self.segments.iter() { + if match segment { + (Unbounded, Unbounded) => true, + (Unbounded, Included(end)) => v <= end, + (Unbounded, Excluded(end)) => v < end, + (Included(start), Unbounded) => v >= start, + (Included(start), Included(end)) => v >= start && v <= end, + (Included(start), Excluded(end)) => v >= start && v < end, + (Excluded(start), Unbounded) => v > start, + (Excluded(start), Included(end)) => v > start && v <= end, + (Excluded(start), Excluded(end)) => v > start && v < end, + } { + return true; + } + } + false + } + + /// Construct a simple range from anything that impls [RangeBounds] like `v1..v2`. + pub fn from_range_bounds(bounds: R) -> Self + where + R: RangeBounds, + IV: Clone + Into, + { + let start = match bounds.start_bound() { + Included(v) => Included(v.clone().into()), + Excluded(v) => Excluded(v.clone().into()), + Unbounded => Unbounded, + }; + let end = match bounds.end_bound() { + Included(v) => Included(v.clone().into()), + Excluded(v) => Excluded(v.clone().into()), + Unbounded => Unbounded, + }; + match (start, end) { + (Included(a), Included(b)) if b < a => Self::none(), + (Excluded(a), Excluded(b)) if b < a => Self::none(), + (Included(a), Excluded(b)) if b <= a => Self::none(), + (Excluded(a), Included(b)) if b <= a => Self::none(), + (a, b) => Self { + segments: SmallVec::one((a, b)), + }, + } + } +} + +/// Implementation of [`Bound::as_ref`] which is currently marked as unstable. +fn bounds_as_ref(bounds: &Bound) -> Bound<&V> { + match bounds { + Included(v) => Included(v), + Excluded(v) => Excluded(v), + Unbounded => Unbounded, + } +} + +impl BoundedRange { + /// Computes the union of two sets of versions. + pub fn union(&self, other: &Self) -> Self { + self.negate().intersection(&other.negate()).negate() + } + + /// Computes the intersection of two sets of versions. + pub fn intersection(&self, other: &Self) -> Self { + let mut segments: SmallVec> = SmallVec::empty(); + let mut left_iter = self.segments.iter(); + let mut right_iter = other.segments.iter(); + let mut left = left_iter.next(); + let mut right = right_iter.next(); + while let (Some((left_lower, left_upper)), Some((right_lower, right_upper))) = (left, right) + { + // Check if the left range completely smaller than the right range. + if let ( + Included(left_upper_version) | Excluded(left_upper_version), + Included(right_lower_version) | Excluded(right_lower_version), + ) = (left_upper, right_lower) + { + match left_upper_version.cmp(right_lower_version) { + Ordering::Less => { + // Left range is disjoint from the right range. + left = left_iter.next(); + continue; + } + Ordering::Equal => { + if !matches!((left_upper, right_lower), (Included(_), Included(_))) { + // Left and right are overlapping exactly, but one of the bounds is exclusive, therefor the ranges are disjoint + left = left_iter.next(); + continue; + } + } + Ordering::Greater => { + // Left upper bound is greater than right lower bound, so the lower bound is the right lower bound + } + } + } + // Check if the right range completely smaller than the left range. + if let ( + Included(left_lower_version) | Excluded(left_lower_version), + Included(right_upper_version) | Excluded(right_upper_version), + ) = (left_lower, right_upper) + { + match right_upper_version.cmp(left_lower_version) { + Ordering::Less => { + // Right range is disjoint from the left range. + right = right_iter.next(); + continue; + } + Ordering::Equal => { + if !matches!((right_upper, left_lower), (Included(_), Included(_))) { + // Left and right are overlapping exactly, but one of the bounds is exclusive, therefor the ranges are disjoint + right = right_iter.next(); + continue; + } + } + Ordering::Greater => { + // Right upper bound is greater than left lower bound, so the lower bound is the left lower bound + } + } + } + + // At this point we know there is an overlap between the versions, find the lowest bound + let lower = match (left_lower, right_lower) { + (Unbounded, Included(_) | Excluded(_)) => right_lower.clone(), + (Included(_) | Excluded(_), Unbounded) => left_lower.clone(), + (Unbounded, Unbounded) => Unbounded, + (Included(l) | Excluded(l), Included(r) | Excluded(r)) => match l.cmp(r) { + Ordering::Less => right_lower.clone(), + Ordering::Equal => match (left_lower, right_lower) { + (Included(_), Excluded(v)) => Excluded(v.clone()), + (Excluded(_), Excluded(v)) => Excluded(v.clone()), + (Excluded(v), Included(_)) => Excluded(v.clone()), + (Included(_), Included(v)) => Included(v.clone()), + _ => unreachable!(), + }, + Ordering::Greater => left_lower.clone(), + }, + }; + + // At this point we know there is an overlap between the versions, find the lowest bound + let upper = match (left_upper, right_upper) { + (Unbounded, Included(_) | Excluded(_)) => { + right = right_iter.next(); + right_upper.clone() + } + (Included(_) | Excluded(_), Unbounded) => { + left = left_iter.next(); + left_upper.clone() + } + (Unbounded, Unbounded) => { + left = left_iter.next(); + right = right_iter.next(); + Unbounded + } + (Included(l) | Excluded(l), Included(r) | Excluded(r)) => match l.cmp(r) { + Ordering::Less => { + left = left_iter.next(); + left_upper.clone() + } + Ordering::Equal => match (left_upper, right_upper) { + (Included(_), Excluded(v)) => { + right = right_iter.next(); + Excluded(v.clone()) + } + (Excluded(_), Excluded(v)) => { + left = left_iter.next(); + right = right_iter.next(); + Excluded(v.clone()) + } + (Excluded(v), Included(_)) => { + left = left_iter.next(); + Excluded(v.clone()) + } + (Included(_), Included(v)) => { + left = left_iter.next(); + right = right_iter.next(); + Included(v.clone()) + } + _ => unreachable!(), + }, + Ordering::Greater => { + right = right_iter.next(); + right_upper.clone() + } + }, + }; + + segments.push((lower, upper)); + } + + Self { segments } + } +} + +impl VersionSet for BoundedRange { + type V = T; + + fn empty() -> Self { + BoundedRange::none() + } + + fn singleton(v: Self::V) -> Self { + BoundedRange::exact(v) + } + + fn complement(&self) -> Self { + BoundedRange::negate(self) + } + + fn intersection(&self, other: &Self) -> Self { + BoundedRange::intersection(self, other) + } + + fn contains(&self, v: &Self::V) -> bool { + BoundedRange::contains(self, v) + } + + fn full() -> Self { + BoundedRange::any() + } + + fn union(&self, other: &Self) -> Self { + BoundedRange::union(self, other) + } +} + +// REPORT ###################################################################### + +impl Display for BoundedRange { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + if self.segments.is_empty() { + write!(f, "∅")?; + } else { + for (idx, segment) in self.segments.iter().enumerate() { + if idx > 0 { + write!(f, ", ")?; + } + match segment { + (Unbounded, Unbounded) => write!(f, "*")?, + (Unbounded, Included(v)) => write!(f, "<={v}")?, + (Unbounded, Excluded(v)) => write!(f, "<{v}")?, + (Included(v), Unbounded) => write!(f, ">={v}")?, + (Included(v), Included(b)) => { + if v == b { + write!(f, "{v}")? + } else { + write!(f, ">={v},<={b}")? + } + } + (Included(v), Excluded(b)) => write!(f, ">={v}, <{b}")?, + (Excluded(v), Unbounded) => write!(f, ">{v}")?, + (Excluded(v), Included(b)) => write!(f, ">{v}, <={b}")?, + (Excluded(v), Excluded(b)) => write!(f, ">{v}, <{b}")?, + }; + } + } + Ok(()) + } +} + +// TESTS ####################################################################### + +#[cfg(test)] +pub mod tests { + use proptest::prelude::*; + use proptest::test_runner::TestRng; + + use super::*; + + pub fn strategy() -> impl Strategy> { + prop::collection::vec(any::(), 0..10) + .prop_map(|mut vec| { + vec.sort_unstable(); + vec.dedup(); + vec + }) + .prop_perturb(|vec, mut rng| { + let mut segments = SmallVec::empty(); + let mut iter = vec.into_iter().peekable(); + if let Some(first) = iter.next() { + fn next_bound>( + iter: &mut I, + rng: &mut TestRng, + ) -> Bound { + if let Some(next) = iter.next() { + if rng.gen_bool(0.5) { + Included(next) + } else { + Excluded(next) + } + } else { + Unbounded + } + } + + let start = if rng.gen_bool(0.3) { + Unbounded + } else { + if rng.gen_bool(0.5) { + Included(first) + } else { + Excluded(first) + } + }; + + let end = next_bound(&mut iter, &mut rng); + segments.push((start, end)); + + while iter.peek().is_some() { + let start = next_bound(&mut iter, &mut rng); + let end = next_bound(&mut iter, &mut rng); + segments.push((start, end)); + } + } + return BoundedRange { segments }; + }) + } + + fn version_strat() -> impl Strategy { + any::() + } + + proptest! { + + // Testing negate ---------------------------------- + + #[test] + fn negate_is_different(range in strategy()) { + assert_ne!(range.negate(), range); + } + + #[test] + fn double_negate_is_identity(range in strategy()) { + assert_eq!(range.negate().negate(), range); + } + + #[test] + fn negate_contains_opposite(range in strategy(), version in version_strat()) { + assert_ne!(range.contains(&version), range.negate().contains(&version)); + } + + // Testing intersection ---------------------------- + + #[test] + fn intersection_is_symmetric(r1 in strategy(), r2 in strategy()) { + assert_eq!(r1.intersection(&r2), r2.intersection(&r1)); + } + + #[test] + fn intersection_with_any_is_identity(range in strategy()) { + assert_eq!(BoundedRange::any().intersection(&range), range); + } + + #[test] + fn intersection_with_none_is_none(range in strategy()) { + assert_eq!(BoundedRange::none().intersection(&range), BoundedRange::none()); + } + + #[test] + fn intersection_is_idempotent(r1 in strategy(), r2 in strategy()) { + assert_eq!(r1.intersection(&r2).intersection(&r2), r1.intersection(&r2)); + } + + #[test] + fn intersection_is_associative(r1 in strategy(), r2 in strategy(), r3 in strategy()) { + assert_eq!(r1.intersection(&r2).intersection(&r3), r1.intersection(&r2.intersection(&r3))); + } + + #[test] + fn intesection_of_complements_is_none(range in strategy()) { + assert_eq!(range.negate().intersection(&range), BoundedRange::none()); + } + + #[test] + fn intesection_contains_both(r1 in strategy(), r2 in strategy(), version in version_strat()) { + assert_eq!(r1.intersection(&r2).contains(&version), r1.contains(&version) && r2.contains(&version)); + } + + // Testing union ----------------------------------- + + #[test] + fn union_of_complements_is_any(range in strategy()) { + assert_eq!(range.negate().union(&range), BoundedRange::any()); + } + + #[test] + fn union_contains_either(r1 in strategy(), r2 in strategy(), version in version_strat()) { + assert_eq!(r1.union(&r2).contains(&version), r1.contains(&version) || r2.contains(&version)); + } + + // Testing contains -------------------------------- + + #[test] + fn always_contains_exact(version in version_strat()) { + assert!(BoundedRange::exact(version).contains(&version)); + } + + #[test] + fn contains_negation(range in strategy(), version in version_strat()) { + assert_ne!(range.contains(&version), range.negate().contains(&version)); + } + + #[test] + fn contains_intersection(range in strategy(), version in version_strat()) { + assert_eq!(range.contains(&version), range.intersection(&BoundedRange::exact(version)) != BoundedRange::none()); + } + + #[test] + fn contains_bounding_range(range in strategy(), version in version_strat()) { + if range.contains(&version) { + assert!(range.bounding_range().map(|b| b.contains(&version)).unwrap_or(false)); + } + } + + #[test] + fn from_range_bounds(range in any::<(Bound, Bound)>(), version in version_strat()) { + let rv: BoundedRange = BoundedRange::from_range_bounds(range); + assert_eq!(range.contains(&version), rv.contains(&version)); + } + + #[test] + fn from_range_bounds_round_trip(range in any::<(Bound, Bound)>()) { + let rv: BoundedRange = BoundedRange::from_range_bounds(range); + let rv2: BoundedRange = rv.bounding_range().map(BoundedRange::from_range_bounds::<_, u32>).unwrap_or_else(BoundedRange::none); + assert_eq!(rv, rv2); + } + } +} diff --git a/src/range.rs b/src/discrete_range.rs similarity index 92% rename from src/range.rs rename to src/discrete_range.rs index b0ca3bc4..229f25da 100644 --- a/src/range.rs +++ b/src/discrete_range.rs @@ -22,14 +22,14 @@ use crate::internal::small_vec::SmallVec; use crate::version::Version; use crate::version_set::VersionSet; -impl VersionSet for Range { +impl VersionSet for DiscreteRange { type V = V; // Constructors fn empty() -> Self { - Range::none() + DiscreteRange::none() } fn singleton(v: Self::V) -> Self { - Range::exact(v) + DiscreteRange::exact(v) } // Operations fn complement(&self) -> Self { @@ -48,14 +48,14 @@ impl VersionSet for Range { #[derive(Debug, Clone, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(transparent))] -pub struct Range { +pub struct DiscreteRange { segments: SmallVec>, } type Interval = (V, Option); // Range building blocks. -impl Range { +impl DiscreteRange { /// Empty set of versions. pub fn none() -> Self { Self { @@ -137,7 +137,7 @@ impl Range { } // Set operations. -impl Range { +impl DiscreteRange { // Negate ################################################################## /// Compute the complement set of versions. @@ -150,7 +150,7 @@ impl Range { // Complement of * is ∅ if v == &V::lowest() { Self::none() - // Complement of "v <= _" is "_ < v" + // Complement of "v <= _" is "_ < v" } else { Self::strictly_lower_than(v.clone()) } @@ -171,7 +171,7 @@ impl Range { /// For example: /// [ (v1, None) ] => [ (start, Some(v1)) ] /// [ (v1, Some(v2)) ] => [ (start, Some(v1)), (v2, None) ] - fn negate_segments(start: V, segments: &[Interval]) -> Range { + fn negate_segments(start: V, segments: &[Interval]) -> DiscreteRange { let mut complement_segments = SmallVec::empty(); let mut start = Some(start); for (v1, maybe_v2) in segments { @@ -287,7 +287,7 @@ impl Range { } // Other useful functions. -impl Range { +impl DiscreteRange { /// Check if a range contains a given version. pub fn contains(&self, version: &V) -> bool { for (v1, maybe_v2) in &self.segments { @@ -331,7 +331,7 @@ impl Range { // REPORT ###################################################################### -impl fmt::Display for Range { +impl fmt::Display for DiscreteRange { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self.segments.as_slice() { [] => write!(f, "∅"), @@ -368,7 +368,7 @@ pub mod tests { use super::*; - pub fn strategy() -> impl Strategy> { + pub fn strategy() -> impl Strategy> { prop::collection::vec(any::(), 0..10).prop_map(|mut vec| { vec.sort_unstable(); vec.dedup(); @@ -380,7 +380,7 @@ pub mod tests { if let [v] = pair_iter.remainder() { segments.push((NumberVersion(*v), None)); } - Range { segments } + DiscreteRange { segments } }) } @@ -416,12 +416,12 @@ pub mod tests { #[test] fn intersection_with_any_is_identity(range in strategy()) { - assert_eq!(Range::any().intersection(&range), range); + assert_eq!(DiscreteRange::any().intersection(&range), range); } #[test] fn intersection_with_none_is_none(range in strategy()) { - assert_eq!(Range::none().intersection(&range), Range::none()); + assert_eq!(DiscreteRange::none().intersection(&range), DiscreteRange::none()); } #[test] @@ -436,7 +436,7 @@ pub mod tests { #[test] fn intesection_of_complements_is_none(range in strategy()) { - assert_eq!(range.negate().intersection(&range), Range::none()); + assert_eq!(range.negate().intersection(&range), DiscreteRange::none()); } #[test] @@ -448,7 +448,7 @@ pub mod tests { #[test] fn union_of_complements_is_any(range in strategy()) { - assert_eq!(range.negate().union(&range), Range::any()); + assert_eq!(range.negate().union(&range), DiscreteRange::any()); } #[test] @@ -460,7 +460,7 @@ pub mod tests { #[test] fn always_contains_exact(version in version_strat()) { - assert!(Range::exact(version).contains(&version)); + assert!(DiscreteRange::exact(version).contains(&version)); } #[test] @@ -470,7 +470,7 @@ pub mod tests { #[test] fn contains_intersection(range in strategy(), version in version_strat()) { - assert_eq!(range.contains(&version), range.intersection(&Range::exact(version)) != Range::none()); + assert_eq!(range.contains(&version), range.intersection(&DiscreteRange::exact(version)) != DiscreteRange::none()); } #[test] @@ -482,14 +482,14 @@ pub mod tests { #[test] fn from_range_bounds(range in any::<(Bound, Bound)>(), version in version_strat()) { - let rv: Range = Range::from_range_bounds(range); + let rv: DiscreteRange = DiscreteRange::from_range_bounds(range); assert_eq!(range.contains(&version.0), rv.contains(&version)); } #[test] fn from_range_bounds_round_trip(range in any::<(Bound, Bound)>()) { - let rv: Range = Range::from_range_bounds(range); - let rv2: Range = rv.bounding_range().map(Range::from_range_bounds::<_, NumberVersion>).unwrap_or_else(Range::none); + let rv: DiscreteRange = DiscreteRange::from_range_bounds(range); + let rv2: DiscreteRange = rv.bounding_range().map(DiscreteRange::from_range_bounds::<_, NumberVersion>).unwrap_or_else(DiscreteRange::none); assert_eq!(rv, rv2); } } diff --git a/src/internal/incompatibility.rs b/src/internal/incompatibility.rs index dd093a08..ff3a4143 100644 --- a/src/internal/incompatibility.rs +++ b/src/internal/incompatibility.rs @@ -257,7 +257,7 @@ impl fmt::Display for Incompatibility { #[cfg(test)] pub mod tests { use super::*; - use crate::range::Range; + use crate::bounded_range::BoundedRange; use crate::term::tests::strategy as term_strat; use crate::type_aliases::Map; use proptest::prelude::*; @@ -276,12 +276,12 @@ pub mod tests { let mut store = Arena::new(); let i1 = store.alloc(Incompatibility { package_terms: SmallMap::Two([("p1", t1.clone()), ("p2", t2.negate())]), - kind: Kind::UnavailableDependencies("0", Range::any()) + kind: Kind::UnavailableDependencies("0", BoundedRange::any()) }); let i2 = store.alloc(Incompatibility { package_terms: SmallMap::Two([("p2", t2), ("p3", t3.clone())]), - kind: Kind::UnavailableDependencies("0", Range::any()) + kind: Kind::UnavailableDependencies("0", BoundedRange::any()) }); let mut i3 = Map::default(); diff --git a/src/internal/small_vec.rs b/src/internal/small_vec.rs index 2c3fe4f4..ae412170 100644 --- a/src/internal/small_vec.rs +++ b/src/internal/small_vec.rs @@ -1,4 +1,5 @@ use std::fmt; +use std::hash::{Hash, Hasher}; use std::ops::Deref; #[derive(Clone)] @@ -108,6 +109,13 @@ impl fmt::Debug for SmallVec { } } +impl Hash for SmallVec { + fn hash(&self, state: &mut H) { + self.len().hash(state); + Hash::hash_slice(self.as_slice(), state); + } +} + #[cfg(feature = "serde")] impl serde::Serialize for SmallVec { fn serialize(&self, s: S) -> Result { diff --git a/src/lib.rs b/src/lib.rs index bc34599b..900fd802 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -48,17 +48,17 @@ //! ``` //! # use pubgrub::solver::{OfflineDependencyProvider, resolve}; //! # use pubgrub::version::NumberVersion; -//! # use pubgrub::range::Range; +//! # use pubgrub::bounded_range::BoundedRange; //! -//! type NumVS = Range; +//! type NumVS = BoundedRange; //! //! let mut dependency_provider = OfflineDependencyProvider::<&str, NumVS>::new(); //! //! dependency_provider.add_dependencies( -//! "root", 1, [("menu", Range::any()), ("icons", Range::any())], +//! "root", 1, [("menu", BoundedRange::any()), ("icons", BoundedRange::any())], //! ); -//! dependency_provider.add_dependencies("menu", 1, [("dropdown", Range::any())]); -//! dependency_provider.add_dependencies("dropdown", 1, [("icons", Range::any())]); +//! dependency_provider.add_dependencies("menu", 1, [("dropdown", BoundedRange::any())]); +//! dependency_provider.add_dependencies("dropdown", 1, [("icons", BoundedRange::any())]); //! dependency_provider.add_dependencies("icons", 1, []); //! //! // Run the algorithm. @@ -79,14 +79,14 @@ //! ``` //! # use pubgrub::solver::{DependencyProvider, Dependencies}; //! # use pubgrub::version::SemanticVersion; -//! # use pubgrub::range::Range; +//! # use pubgrub::bounded_range::BoundedRange; //! # use pubgrub::type_aliases::Map; //! # use std::error::Error; //! # use std::borrow::Borrow; //! # //! # struct MyDependencyProvider; //! # -//! type SemVS = Range; +//! type SemVS = BoundedRange; //! //! impl DependencyProvider for MyDependencyProvider { //! fn choose_package_version, U: Borrow>(&self,packages: impl Iterator) -> Result<(T, Option), Box> { @@ -177,9 +177,9 @@ //! # use pubgrub::report::{DefaultStringReporter, Reporter}; //! # use pubgrub::error::PubGrubError; //! # use pubgrub::version::NumberVersion; -//! # use pubgrub::range::Range; +//! # use pubgrub::bounded_range::BoundedRange; //! # -//! # type NumVS = Range; +//! # type NumVS = BoundedRange; //! # //! # let dependency_provider = OfflineDependencyProvider::<&str, NumVS>::new(); //! # let root_package = "root"; @@ -216,9 +216,10 @@ #![allow(clippy::rc_buffer)] #![warn(missing_docs)] +pub mod bounded_range; +pub mod discrete_range; pub mod error; pub mod package; -pub mod range; pub mod report; pub mod solver; pub mod term; diff --git a/src/solver.rs b/src/solver.rs index 846f220c..fb469978 100644 --- a/src/solver.rs +++ b/src/solver.rs @@ -44,9 +44,9 @@ //! # use pubgrub::solver::{resolve, OfflineDependencyProvider}; //! # use pubgrub::version::NumberVersion; //! # use pubgrub::error::PubGrubError; -//! # use pubgrub::range::Range; +//! # use pubgrub::bounded_range::BoundedRange; //! # -//! # type NumVS = Range; +//! # type NumVS = BoundedRange; //! # //! # fn try_main() -> Result<(), PubGrubError<&'static str, NumVS>> { //! # let dependency_provider = OfflineDependencyProvider::<&str, NumVS>::new(); diff --git a/src/term.rs b/src/term.rs index 3028dbe1..2ce6fb0c 100644 --- a/src/term.rs +++ b/src/term.rs @@ -181,14 +181,13 @@ impl Display for Term { #[cfg(test)] pub mod tests { use super::*; - use crate::range::Range; - use crate::version::NumberVersion; + use crate::bounded_range::BoundedRange; use proptest::prelude::*; - pub fn strategy() -> impl Strategy>> { + pub fn strategy() -> impl Strategy>> { prop_oneof![ - crate::range::tests::strategy().prop_map(Term::Positive), - crate::range::tests::strategy().prop_map(Term::Negative), + crate::bounded_range::tests::strategy().prop_map(Term::Positive), + crate::bounded_range::tests::strategy().prop_map(Term::Negative), ] } diff --git a/test-examples/large_case_u16_bounded_NumberVersion.ron b/test-examples/large_case_u16_bounded_NumberVersion.ron new file mode 100644 index 00000000..7f7204df --- /dev/null +++ b/test-examples/large_case_u16_bounded_NumberVersion.ron @@ -0,0 +1,5524 @@ +{ + 0: { + 0: { + 13: [ + (Included(0), Excluded(13)), + ], + 96: [ + (Included(0), Excluded(15)), + ], + 344: [ + (Included(0), Excluded(15)), + ], + 475: [ + (Included(3), Excluded(4)), + ], + 479: [ + (Included(0), Unbounded), + ], + 523: [ + (Included(0), Excluded(10)), + ], + 600: [ + (Included(0), Unbounded), + ], + }, + }, + 13: { + 10: { + 215: [ + (Included(1), Excluded(14)), + ], + 227: [ + (Included(0), Unbounded), + ], + 505: [ + (Included(0), Excluded(14)), + ], + }, + 12: { + 100: [ + (Included(6), Unbounded), + ], + 124: [ + (Included(0), Excluded(15)), + ], + 208: [ + (Included(0), Excluded(8)), + ], + 287: [ + (Included(3), Excluded(6)), + ], + 396: [ + (Included(9), Excluded(12)), + ], + 405: [ + (Included(2), Unbounded), + ], + 574: [ + (Included(0), Excluded(10)), + ], + }, + 13: { + 171: [ + (Included(2), Excluded(12)), + ], + 441: [ + (Included(0), Excluded(3)), + ], + 505: [ + (Included(1), Excluded(18)), + ], + 547: [ + (Included(8), Unbounded), + ], + }, + }, + 96: { + 10: { + 169: [ + (Included(9), Excluded(11)), + ], + 259: [ + (Included(0), Excluded(1)), + ], + 341: [ + (Included(2), Excluded(15)), + ], + 344: [ + (Included(3), Excluded(14)), + ], + 418: [ + (Included(8), Excluded(16)), + ], + 443: [ + (Included(0), Excluded(15)), + ], + 447: [ + (Included(3), Unbounded), + ], + 500: [ + (Included(5), Excluded(13)), + ], + 619: [ + (Included(4), Excluded(15)), + ], + }, + 12: { + 128: [ + (Included(5), Excluded(14)), + ], + 249: [ + (Included(0), Unbounded), + ], + 352: [ + (Included(0), Excluded(17)), + ], + 405: [ + (Included(6), Excluded(12)), + ], + 595: [ + (Included(5), Unbounded), + ], + 600: [ + (Included(8), Excluded(10)), + ], + 613: [ + (Included(0), Excluded(11)), + ], + }, + 14: { + 171: [ + (Included(0), Excluded(3)), + ], + 242: [ + (Included(5), Excluded(14)), + ], + 255: [ + (Included(8), Unbounded), + ], + 370: [ + (Included(6), Unbounded), + ], + 559: [ + (Included(0), Excluded(9)), + ], + 574: [ + (Included(0), Excluded(2)), + ], + 593: [ + (Included(3), Unbounded), + ], + 599: [ + (Included(0), Excluded(15)), + ], + }, + }, + 128: { + 5: { + 541: [ + (Included(0), Excluded(14)), + ], + }, + 8: { + 316: [ + (Included(3), Excluded(18)), + ], + 349: [ + (Included(0), Excluded(11)), + ], + 410: [ + (Included(5), Excluded(6)), + ], + 523: [ + (Included(8), Excluded(11)), + ], + 547: [ + (Included(3), Excluded(18)), + ], + 595: [ + (Included(6), Unbounded), + ], + 619: [ + (Included(2), Unbounded), + ], + }, + 9: { + 250: [ + (Included(7), Excluded(19)), + ], + 259: [ + (Included(0), Unbounded), + ], + 265: [ + (Included(0), Excluded(8)), + ], + 287: [ + (Included(2), Excluded(13)), + ], + 447: [ + (Included(0), Unbounded), + ], + 455: [ + (Included(2), Excluded(16)), + ], + 505: [ + (Included(1), Excluded(18)), + ], + 541: [ + (Included(0), Excluded(7)), + ], + 574: [ + (Included(0), Excluded(15)), + ], + }, + 11: { + 190: [ + (Included(0), Excluded(1)), + ], + 242: [ + (Included(5), Excluded(10)), + ], + 265: [ + (Included(1), Excluded(13)), + ], + 287: [ + (Included(1), Excluded(3)), + ], + 316: [ + (Included(4), Unbounded), + ], + 335: [ + (Included(2), Excluded(4)), + ], + 344: [ + (Included(6), Unbounded), + ], + 349: [ + (Included(4), Excluded(15)), + ], + 418: [ + (Included(3), Excluded(4)), + ], + 477: [ + (Included(0), Unbounded), + ], + 595: [ + (Included(6), Excluded(17)), + ], + 606: [ + (Included(6), Unbounded), + ], + 635: [ + (Included(0), Excluded(18)), + ], + }, + 12: { + 190: [ + (Included(3), Excluded(14)), + ], + 250: [ + (Included(5), Excluded(8)), + ], + 328: [ + (Included(0), Excluded(16)), + ], + 484: [ + (Included(6), Excluded(8)), + ], + 500: [ + (Included(0), Excluded(3)), + ], + 547: [ + (Included(4), Excluded(17)), + ], + }, + 13: { + 190: [ + (Included(3), Excluded(6)), + ], + 312: [ + (Included(0), Excluded(11)), + ], + 341: [ + (Included(0), Excluded(7)), + ], + 348: [ + (Included(0), Unbounded), + ], + 484: [ + (Included(4), Excluded(9)), + ], + 495: [ + (Included(5), Excluded(12)), + ], + }, + 15: { + 205: [ + (Included(5), Excluded(13)), + ], + 312: [ + (Included(0), Excluded(13)), + ], + 335: [ + (Included(2), Excluded(7)), + ], + 346: [ + (Included(0), Unbounded), + ], + 385: [ + (Included(0), Excluded(4)), + ], + 589: [ + (Included(0), Excluded(9)), + ], + }, + }, + 190: { + 0: { + 202: [ + (Included(9), Excluded(10)), + ], + 251: [ + (Included(0), Excluded(18)), + ], + 265: [ + (Included(8), Unbounded), + ], + 293: [ + (Included(7), Excluded(12)), + ], + 328: [ + (Included(2), Excluded(13)), + ], + 535: [ + (Included(3), Excluded(14)), + ], + }, + 3: { + 400: [ + (Included(0), Excluded(1)), + ], + 441: [ + (Included(0), Unbounded), + ], + }, + 5: { + 250: [ + (Included(4), Excluded(19)), + ], + 619: [ + (Included(4), Excluded(7)), + ], + 627: [ + (Included(4), Unbounded), + ], + }, + 8: { + 265: [ + (Included(0), Excluded(8)), + ], + 541: [ + (Included(0), Excluded(7)), + ], + 560: [ + (Included(0), Excluded(5)), + ], + 600: [ + (Included(6), Unbounded), + ], + }, + 9: { + 199: [ + (Included(3), Excluded(16)), + ], + 208: [ + (Included(0), Unbounded), + ], + 227: [ + (Included(4), Excluded(16)), + ], + 287: [ + (Included(1), Excluded(12)), + ], + 334: [ + (Included(0), Excluded(6)), + ], + 341: [ + (Included(0), Excluded(12)), + ], + 348: [ + (Included(7), Unbounded), + ], + 396: [ + (Included(4), Excluded(19)), + ], + 400: [ + (Included(4), Excluded(5)), + ], + 523: [ + (Included(8), Excluded(9)), + ], + 547: [ + (Included(2), Excluded(17)), + ], + }, + 11: { + 210: [ + (Included(8), Excluded(15)), + ], + 334: [ + (Included(5), Excluded(6)), + ], + 345: [ + (Included(1), Excluded(12)), + ], + 349: [ + (Included(3), Unbounded), + ], + 370: [ + (Included(0), Unbounded), + ], + 484: [ + (Included(0), Excluded(8)), + ], + 495: [ + (Included(1), Excluded(13)), + ], + 594: [ + (Included(1), Unbounded), + ], + }, + 12: { + 645: [ + (Included(6), Excluded(17)), + ], + }, + 13: { + 205: [ + (Included(2), Excluded(13)), + ], + 287: [ + (Included(4), Unbounded), + ], + 328: [ + (Included(2), Excluded(14)), + ], + 450: [ + (Included(3), Excluded(17)), + ], + 491: [ + (Included(2), Excluded(4)), + ], + 660: [ + (Included(0), Excluded(4)), + ], + }, + 17: { + 245: [ + (Included(2), Excluded(4)), + ], + 250: [ + (Included(0), Excluded(12)), + ], + 364: [ + (Included(9), Unbounded), + ], + 559: [ + (Included(0), Excluded(13)), + ], + 576: [ + (Included(7), Excluded(9)), + ], + }, + 19: { + 316: [ + (Included(3), Excluded(17)), + ], + 589: [ + (Included(7), Unbounded), + ], + 600: [ + (Included(6), Excluded(9)), + ], + 608: [ + (Included(6), Excluded(7)), + ], + 627: [ + (Included(4), Excluded(15)), + ], + 662: [ + (Included(8), Excluded(17)), + ], + }, + }, + 215: { + 8: { + 245: [ + (Included(0), Excluded(2)), + ], + 334: [ + (Included(0), Excluded(6)), + ], + 341: [ + (Included(0), Excluded(12)), + ], + 450: [ + (Included(0), Excluded(18)), + ], + 606: [ + (Included(0), Unbounded), + ], + 608: [ + (Included(0), Excluded(10)), + ], + }, + 11: { + 228: [ + (Included(0), Excluded(15)), + ], + 245: [ + (Included(0), Excluded(4)), + ], + 316: [ + (Included(3), Excluded(18)), + ], + 505: [ + (Included(1), Excluded(14)), + ], + 559: [ + (Included(1), Excluded(13)), + ], + 601: [ + (Included(8), Excluded(13)), + ], + 613: [ + (Included(8), Excluded(11)), + ], + }, + 13: { + 450: [ + (Included(3), Excluded(5)), + ], + 662: [ + (Included(6), Excluded(19)), + ], + }, + 15: { + 349: [ + (Included(0), Excluded(12)), + ], + 619: [ + (Included(0), Excluded(7)), + ], + }, + }, + 227: { + 3: { + 348: [ + (Included(0), Excluded(3)), + ], + 448: [ + (Included(2), Excluded(13)), + ], + 559: [ + (Included(9), Excluded(11)), + ], + 594: [ + (Included(1), Excluded(12)), + ], + 650: [ + (Included(0), Excluded(15)), + ], + }, + 4: { + 264: [ + (Included(0), Excluded(4)), + ], + 344: [ + (Included(6), Excluded(7)), + ], + 479: [ + (Included(0), Unbounded), + ], + 562: [ + (Included(4), Excluded(5)), + ], + }, + 5: { + 265: [ + (Included(7), Excluded(10)), + ], + 316: [ + (Included(4), Excluded(17)), + ], + 405: [ + (Included(2), Excluded(8)), + ], + 471: [ + (Included(0), Unbounded), + ], + 593: [ + (Included(4), Unbounded), + ], + }, + 6: { + 448: [ + (Included(0), Excluded(13)), + ], + 625: [ + (Included(0), Excluded(7)), + ], + }, + 8: { + 328: [ + (Included(3), Excluded(16)), + ], + 462: [ + (Included(7), Excluded(8)), + ], + 495: [ + (Included(0), Excluded(5)), + ], + 613: [ + (Included(0), Excluded(4)), + ], + 627: [ + (Included(0), Excluded(2)), + ], + 660: [ + (Included(0), Excluded(10)), + ], + }, + 9: { + 334: [ + (Included(1), Unbounded), + ], + 351: [ + (Included(0), Excluded(7)), + ], + 410: [ + (Included(5), Excluded(8)), + ], + 574: [ + (Included(2), Excluded(15)), + ], + 599: [ + (Included(2), Excluded(13)), + ], + }, + 10: { + 230: [ + (Included(7), Excluded(17)), + ], + 242: [ + (Included(4), Unbounded), + ], + 287: [ + (Included(1), Excluded(7)), + ], + 650: [ + (Included(4), Unbounded), + ], + }, + 14: { + 455: [ + (Included(9), Excluded(18)), + ], + 625: [ + (Included(8), Excluded(9)), + ], + }, + 15: { + 450: [ + (Included(0), Excluded(4)), + ], + 523: [ + (Included(1), Excluded(14)), + ], + }, + 16: { + 255: [ + (Included(1), Excluded(14)), + ], + 589: [ + (Included(1), Unbounded), + ], + }, + 17: { + 312: [ + (Included(6), Excluded(12)), + ], + 348: [ + (Included(9), Excluded(15)), + ], + 371: [ + (Included(2), Excluded(19)), + ], + 455: [ + (Included(4), Excluded(13)), + ], + 495: [ + (Included(3), Excluded(9)), + ], + 547: [ + (Included(6), Unbounded), + ], + 562: [ + (Included(4), Excluded(13)), + ], + }, + 18: { + 312: [ + (Included(5), Unbounded), + ], + 584: [ + (Included(3), Unbounded), + ], + 660: [ + (Included(0), Unbounded), + ], + }, + }, + 228: { + 6: { + 293: [ + (Included(7), Excluded(11)), + ], + 341: [ + (Included(0), Excluded(2)), + ], + 559: [ + (Included(8), Unbounded), + ], + 608: [ + (Included(6), Unbounded), + ], + 613: [ + (Included(8), Excluded(11)), + ], + }, + 7: { + 523: [ + (Included(9), Unbounded), + ], + 595: [ + (Included(0), Excluded(15)), + ], + 662: [ + (Included(6), Excluded(17)), + ], + }, + 14: { + 371: [ + (Included(0), Excluded(12)), + ], + 491: [ + (Included(0), Unbounded), + ], + }, + 15: { + 250: [ + (Included(4), Excluded(18)), + ], + 265: [ + (Included(0), Excluded(13)), + ], + 606: [ + (Included(7), Excluded(17)), + ], + }, + 17: { + 341: [ + (Included(0), Excluded(15)), + ], + 535: [ + (Included(2), Excluded(13)), + ], + 559: [ + (Included(1), Unbounded), + ], + }, + }, + 245: { + 1: { + 334: [ + (Included(5), Excluded(9)), + ], + 613: [ + (Included(0), Excluded(9)), + ], + }, + 2: { + 268: [ + (Included(9), Excluded(14)), + ], + 541: [ + (Included(7), Excluded(16)), + ], + }, + 3: { + 293: [ + (Included(0), Excluded(8)), + ], + 335: [ + (Included(0), Excluded(7)), + ], + 364: [ + (Included(2), Excluded(13)), + ], + 547: [ + (Included(2), Excluded(17)), + ], + 569: [ + (Included(8), Excluded(13)), + ], + }, + 5: { + 450: [ + (Included(0), Excluded(14)), + ], + 495: [ + (Included(8), Excluded(12)), + ], + 576: [ + (Included(8), Unbounded), + ], + 660: [ + (Included(0), Excluded(10)), + ], + }, + }, + 249: { + 9: { + 251: [ + (Included(0), Unbounded), + ], + 477: [ + (Included(3), Unbounded), + ], + 523: [ + (Included(0), Excluded(11)), + ], + 560: [ + (Included(4), Excluded(7)), + ], + }, + 10: { + 341: [ + (Included(6), Excluded(11)), + ], + 349: [ + (Included(6), Unbounded), + ], + 645: [ + (Included(2), Excluded(6)), + ], + }, + 15: { + 250: [ + (Included(4), Excluded(6)), + ], + 312: [ + (Included(1), Excluded(13)), + ], + 448: [ + (Included(2), Unbounded), + ], + 547: [ + (Included(0), Excluded(3)), + ], + 613: [ + (Included(0), Excluded(9)), + ], + }, + }, + 250: { + 2: { + 345: [ + (Included(7), Excluded(10)), + ], + 441: [ + (Included(0), Excluded(16)), + ], + 448: [ + (Included(0), Excluded(13)), + ], + 450: [ + (Included(0), Excluded(18)), + ], + 455: [ + (Included(0), Excluded(18)), + ], + 495: [ + (Included(3), Excluded(9)), + ], + 505: [ + (Included(3), Excluded(18)), + ], + 595: [ + (Included(2), Excluded(15)), + ], + 613: [ + (Included(0), Unbounded), + ], + }, + 4: { + 462: [ + (Included(4), Excluded(15)), + ], + 471: [ + (Included(0), Excluded(3)), + ], + 559: [ + (Included(0), Unbounded), + ], + 560: [ + (Included(4), Unbounded), + ], + 584: [ + (Included(0), Unbounded), + ], + 660: [ + (Included(9), Unbounded), + ], + }, + 5: { + 349: [ + (Included(1), Excluded(5)), + ], + 495: [ + (Included(3), Excluded(10)), + ], + 547: [ + (Included(5), Excluded(12)), + ], + 660: [ + (Included(0), Excluded(2)), + ], + }, + 7: { + 600: [ + (Included(6), Excluded(10)), + ], + 660: [ + (Included(3), Unbounded), + ], + }, + 9: { + 334: [ + (Included(6), Excluded(12)), + ], + 348: [ + (Included(0), Excluded(4)), + ], + 650: [ + (Included(2), Excluded(8)), + ], + }, + 10: { + 287: [ + (Included(0), Excluded(10)), + ], + 297: [ + (Included(7), Unbounded), + ], + 334: [ + (Included(0), Excluded(16)), + ], + 364: [ + (Included(0), Excluded(11)), + ], + 370: [ + (Included(0), Unbounded), + ], + }, + 11: { + 410: [ + (Included(9), Excluded(17)), + ], + 445: [ + (Included(0), Excluded(6)), + ], + 523: [ + (Included(6), Excluded(10)), + ], + 595: [ + (Included(0), Excluded(11)), + ], + }, + 12: { + 293: [ + (Included(7), Excluded(11)), + ], + 335: [ + (Included(1), Excluded(16)), + ], + }, + 14: { + 287: [ + (Included(8), Excluded(10)), + ], + 462: [ + (Included(2), Excluded(13)), + ], + 477: [ + (Included(7), Excluded(8)), + ], + 523: [ + (Included(0), Excluded(7)), + ], + }, + 15: { + 352: [ + (Included(7), Unbounded), + ], + 484: [ + (Included(1), Unbounded), + ], + 627: [ + (Included(2), Excluded(13)), + ], + }, + 17: { + 341: [ + (Included(2), Excluded(7)), + ], + 450: [ + (Included(6), Unbounded), + ], + 479: [ + (Included(0), Unbounded), + ], + 560: [ + (Included(0), Excluded(3)), + ], + 574: [ + (Included(9), Excluded(11)), + ], + }, + 18: { + 265: [ + (Included(0), Excluded(10)), + ], + 312: [ + (Included(2), Excluded(14)), + ], + 491: [ + (Included(2), Excluded(4)), + ], + 593: [ + (Included(8), Excluded(10)), + ], + 600: [ + (Included(9), Unbounded), + ], + 608: [ + (Included(0), Excluded(10)), + ], + }, + 19: { + 335: [ + (Included(2), Excluded(16)), + ], + 349: [ + (Included(1), Excluded(6)), + ], + 405: [ + (Included(0), Unbounded), + ], + }, + }, + 255: { + 5: { + 348: [ + (Included(4), Excluded(5)), + ], + 396: [ + (Included(7), Unbounded), + ], + 441: [ + (Included(8), Excluded(9)), + ], + 535: [ + (Included(0), Excluded(7)), + ], + }, + 8: { + 312: [ + (Included(2), Excluded(14)), + ], + }, + 11: { + 349: [ + (Included(1), Excluded(13)), + ], + 448: [ + (Included(0), Excluded(13)), + ], + 462: [ + (Included(3), Excluded(8)), + ], + 535: [ + (Included(2), Excluded(14)), + ], + }, + 13: { + 405: [ + (Included(9), Excluded(10)), + ], + 574: [ + (Included(0), Excluded(19)), + ], + 608: [ + (Included(2), Unbounded), + ], + 645: [ + (Included(6), Excluded(17)), + ], + }, + 14: { + 265: [ + (Included(2), Excluded(13)), + ], + 348: [ + (Included(9), Unbounded), + ], + 370: [ + (Included(0), Unbounded), + ], + 541: [ + (Included(7), Excluded(9)), + ], + }, + 16: { + 348: [ + (Included(3), Excluded(17)), + ], + 349: [ + (Included(4), Unbounded), + ], + 625: [ + (Included(6), Unbounded), + ], + }, + }, + 259: { + 0: { + 341: [ + (Included(0), Excluded(2)), + ], + 348: [ + (Included(2), Excluded(18)), + ], + 349: [ + (Included(1), Unbounded), + ], + 535: [ + (Included(5), Excluded(13)), + ], + 593: [ + (Included(4), Excluded(9)), + ], + 600: [ + (Included(9), Unbounded), + ], + 601: [ + (Included(4), Excluded(7)), + ], + }, + 5: { + 262: [ + (Included(5), Unbounded), + ], + 287: [ + (Included(1), Unbounded), + ], + }, + 10: { + 662: [ + (Included(7), Excluded(9)), + ], + }, + 11: { + 341: [ + (Included(7), Excluded(15)), + ], + 345: [ + (Included(1), Excluded(4)), + ], + 405: [ + (Included(0), Excluded(15)), + ], + 448: [ + (Included(1), Excluded(17)), + ], + 593: [ + (Included(4), Unbounded), + ], + }, + 12: { + 352: [ + (Included(0), Excluded(15)), + ], + 541: [ + (Included(5), Excluded(17)), + ], + 601: [ + (Included(2), Unbounded), + ], + }, + }, + 265: { + 6: { + 405: [ + (Included(7), Excluded(11)), + ], + 455: [ + (Included(5), Excluded(16)), + ], + 462: [ + (Included(4), Unbounded), + ], + 576: [ + (Included(0), Excluded(16)), + ], + }, + 7: { + 455: [ + (Included(0), Excluded(9)), + ], + 535: [ + (Included(5), Excluded(16)), + ], + 613: [ + (Included(0), Excluded(4)), + ], + 619: [ + (Included(2), Excluded(9)), + ], + 650: [ + (Included(0), Excluded(8)), + ], + }, + 9: { + 448: [ + (Included(5), Excluded(16)), + ], + 523: [ + (Included(0), Excluded(19)), + ], + 562: [ + (Included(4), Excluded(13)), + ], + 601: [ + (Included(4), Excluded(16)), + ], + }, + 11: { + 316: [ + (Included(6), Excluded(11)), + ], + }, + 12: { + 352: [ + (Included(0), Excluded(15)), + ], + 593: [ + (Included(1), Excluded(14)), + ], + 601: [ + (Included(5), Unbounded), + ], + 619: [ + (Included(0), Excluded(9)), + ], + }, + 18: { + 335: [ + (Included(6), Excluded(19)), + ], + 345: [ + (Included(1), Excluded(11)), + ], + 349: [ + (Included(0), Excluded(7)), + ], + 574: [ + (Included(1), Excluded(9)), + ], + }, + 19: { + 396: [ + (Included(4), Excluded(16)), + ], + 462: [ + (Included(2), Excluded(13)), + ], + }, + }, + 287: { + 0: { + 400: [ + (Included(4), Unbounded), + ], + 576: [ + (Included(6), Excluded(18)), + ], + }, + 1: { + 437: [ + (Included(0), Unbounded), + ], + 500: [ + (Included(0), Excluded(3)), + ], + 505: [ + (Included(6), Excluded(14)), + ], + 589: [ + (Included(1), Excluded(7)), + ], + }, + 2: { + 312: [ + (Included(9), Excluded(11)), + ], + }, + 3: { + 328: [ + (Included(9), Unbounded), + ], + 418: [ + (Included(0), Excluded(1)), + ], + }, + 5: { + 335: [ + (Included(6), Unbounded), + ], + 495: [ + (Included(5), Unbounded), + ], + 595: [ + (Included(0), Unbounded), + ], + 662: [ + (Included(7), Excluded(19)), + ], + }, + 6: { + 364: [ + (Included(4), Unbounded), + ], + 441: [ + (Included(0), Excluded(14)), + ], + 589: [ + (Included(6), Excluded(11)), + ], + }, + 8: { + 341: [ + (Included(0), Excluded(11)), + ], + 349: [ + (Included(0), Excluded(6)), + ], + 523: [ + (Included(0), Excluded(1)), + ], + }, + 9: { + 477: [ + (Included(1), Excluded(13)), + ], + 484: [ + (Included(7), Excluded(18)), + ], + 584: [ + (Included(1), Unbounded), + ], + 601: [ + (Included(6), Excluded(18)), + ], + }, + 11: { + 312: [ + (Included(0), Excluded(11)), + ], + 341: [ + (Included(0), Excluded(8)), + ], + 346: [ + (Included(2), Excluded(14)), + ], + 371: [ + (Included(2), Excluded(19)), + ], + 385: [ + (Included(9), Unbounded), + ], + 569: [ + (Included(0), Excluded(19)), + ], + }, + 12: { + 335: [ + (Included(1), Excluded(3)), + ], + 349: [ + (Included(0), Excluded(13)), + ], + 462: [ + (Included(2), Unbounded), + ], + 541: [ + (Included(5), Unbounded), + ], + 562: [ + (Included(1), Unbounded), + ], + }, + 13: { + 316: [ + (Included(0), Excluded(4)), + ], + 334: [ + (Included(6), Excluded(16)), + ], + 396: [ + (Included(9), Excluded(15)), + ], + }, + 14: { + 334: [ + (Included(3), Excluded(8)), + ], + 335: [ + (Included(1), Excluded(7)), + ], + 341: [ + (Included(6), Excluded(12)), + ], + 410: [ + (Included(7), Excluded(17)), + ], + 535: [ + (Included(0), Unbounded), + ], + 562: [ + (Included(8), Unbounded), + ], + 593: [ + (Included(8), Excluded(12)), + ], + }, + 16: { + 562: [ + (Included(4), Excluded(9)), + ], + }, + 19: { + 328: [ + (Included(9), Unbounded), + ], + 396: [ + (Included(5), Excluded(19)), + ], + 562: [ + (Included(4), Excluded(9)), + ], + }, + }, + 293: { + 3: { + 344: [ + (Included(9), Unbounded), + ], + 443: [ + (Included(4), Unbounded), + ], + 600: [ + (Included(6), Excluded(13)), + ], + }, + 7: { + 593: [ + (Included(4), Excluded(9)), + ], + }, + 10: { + 328: [ + (Included(3), Excluded(14)), + ], + 450: [ + (Included(6), Excluded(8)), + ], + 574: [ + (Included(4), Excluded(11)), + ], + }, + 11: { + 364: [ + (Included(2), Excluded(13)), + ], + 443: [ + (Included(2), Excluded(15)), + ], + 662: [ + (Included(0), Unbounded), + ], + }, + 12: { + 326: [ + (Included(0), Excluded(16)), + ], + 334: [ + (Included(3), Excluded(16)), + ], + 455: [ + (Included(8), Excluded(16)), + ], + }, + }, + 312: { + 0: { + 326: [ + (Included(6), Unbounded), + ], + 505: [ + (Included(1), Excluded(18)), + ], + }, + 1: { + 448: [ + (Included(0), Excluded(17)), + ], + }, + 2: { + 462: [ + (Included(3), Excluded(7)), + ], + 523: [ + (Included(3), Excluded(15)), + ], + 560: [ + (Included(0), Excluded(9)), + ], + 593: [ + (Included(1), Excluded(13)), + ], + 594: [ + (Included(1), Excluded(12)), + ], + 599: [ + (Included(1), Excluded(2)), + ], + 627: [ + (Included(4), Excluded(16)), + ], + }, + 3: { + 348: [ + (Included(8), Excluded(14)), + ], + 455: [ + (Included(8), Unbounded), + ], + 535: [ + (Included(5), Excluded(6)), + ], + 541: [ + (Included(0), Excluded(8)), + ], + 569: [ + (Included(6), Excluded(10)), + ], + 589: [ + (Included(7), Excluded(11)), + ], + 599: [ + (Included(1), Excluded(15)), + ], + 601: [ + (Included(9), Unbounded), + ], + 627: [ + (Included(1), Excluded(18)), + ], + }, + 4: { + 335: [ + (Included(0), Excluded(9)), + ], + 500: [ + (Included(2), Excluded(13)), + ], + 547: [ + (Included(0), Excluded(14)), + ], + 584: [ + (Included(1), Excluded(12)), + ], + 594: [ + (Included(4), Unbounded), + ], + 606: [ + (Included(9), Unbounded), + ], + 619: [ + (Included(4), Excluded(15)), + ], + }, + 6: { + 445: [ + (Included(5), Excluded(9)), + ], + 491: [ + (Included(3), Excluded(6)), + ], + 523: [ + (Included(1), Excluded(19)), + ], + 599: [ + (Included(1), Excluded(3)), + ], + 635: [ + (Included(1), Excluded(18)), + ], + }, + 9: { + 547: [ + (Included(3), Excluded(18)), + ], + 559: [ + (Included(8), Excluded(10)), + ], + 662: [ + (Included(6), Excluded(18)), + ], + }, + 10: { + 448: [ + (Included(3), Unbounded), + ], + 601: [ + (Included(6), Excluded(9)), + ], + }, + 11: { + 316: [ + (Included(0), Excluded(3)), + ], + 523: [ + (Included(9), Excluded(11)), + ], + 560: [ + (Included(0), Excluded(9)), + ], + 593: [ + (Included(8), Excluded(12)), + ], + 608: [ + (Included(7), Unbounded), + ], + }, + 12: { + 341: [ + (Included(6), Unbounded), + ], + 443: [ + (Included(2), Unbounded), + ], + }, + 13: { + 345: [ + (Included(4), Excluded(11)), + ], + 348: [ + (Included(4), Excluded(17)), + ], + 484: [ + (Included(0), Excluded(15)), + ], + 562: [ + (Included(0), Excluded(15)), + ], + 594: [ + (Included(0), Excluded(2)), + ], + 619: [ + (Included(8), Excluded(15)), + ], + }, + 15: { + 352: [ + (Included(0), Excluded(15)), + ], + }, + 16: { + 335: [ + (Included(2), Unbounded), + ], + 352: [ + (Included(4), Unbounded), + ], + 462: [ + (Included(2), Excluded(4)), + ], + 484: [ + (Included(4), Excluded(15)), + ], + 562: [ + (Included(0), Excluded(13)), + ], + 589: [ + (Included(0), Excluded(11)), + ], + 599: [ + (Included(6), Excluded(13)), + ], + 619: [ + (Included(0), Excluded(15)), + ], + }, + }, + 316: { + 2: { + 396: [ + (Included(5), Excluded(11)), + ], + 448: [ + (Included(1), Unbounded), + ], + 505: [ + (Included(2), Excluded(3)), + ], + 574: [ + (Included(4), Excluded(19)), + ], + 601: [ + (Included(6), Excluded(7)), + ], + 625: [ + (Included(8), Unbounded), + ], + }, + 3: { + 619: [ + (Included(2), Excluded(9)), + ], + 662: [ + (Included(7), Excluded(19)), + ], + }, + 6: { + 450: [ + (Included(6), Unbounded), + ], + 635: [ + (Included(5), Excluded(15)), + ], + }, + 10: { + 349: [ + (Included(6), Excluded(8)), + ], + 500: [ + (Included(5), Excluded(13)), + ], + 505: [ + (Included(0), Excluded(14)), + ], + 627: [ + (Included(1), Excluded(19)), + ], + }, + 13: { + 346: [ + (Included(2), Excluded(17)), + ], + 396: [ + (Included(5), Excluded(18)), + ], + 410: [ + (Included(0), Excluded(10)), + ], + 450: [ + (Included(6), Excluded(15)), + ], + 475: [ + (Included(0), Unbounded), + ], + 494: [ + (Included(0), Excluded(6)), + ], + }, + 14: { + 662: [ + (Included(7), Unbounded), + ], + }, + 16: { + 484: [ + (Included(1), Unbounded), + ], + 495: [ + (Included(5), Excluded(12)), + ], + 505: [ + (Included(6), Excluded(10)), + ], + }, + 17: { + 335: [ + (Included(2), Unbounded), + ], + 344: [ + (Included(6), Excluded(10)), + ], + 541: [ + (Included(3), Unbounded), + ], + }, + 19: { + 341: [ + (Included(6), Excluded(11)), + ], + 370: [ + (Included(0), Unbounded), + ], + 371: [ + (Included(2), Excluded(14)), + ], + 495: [ + (Included(1), Excluded(13)), + ], + 600: [ + (Included(6), Unbounded), + ], + }, + }, + 328: { + 0: { + 352: [ + (Included(5), Unbounded), + ], + 541: [ + (Included(6), Excluded(17)), + ], + }, + 1: { + 334: [ + (Included(3), Excluded(9)), + ], + 650: [ + (Included(0), Excluded(3)), + ], + }, + 5: { + 396: [ + (Included(7), Excluded(19)), + ], + }, + 9: { + 345: [ + (Included(0), Excluded(4)), + ], + 448: [ + (Included(1), Unbounded), + ], + 450: [ + (Included(7), Unbounded), + ], + 535: [ + (Included(8), Excluded(13)), + ], + 600: [ + (Included(6), Excluded(8)), + ], + }, + 12: {}, + 13: { + 410: [ + (Included(5), Excluded(10)), + ], + 441: [ + (Included(3), Excluded(16)), + ], + 595: [ + (Included(0), Excluded(16)), + ], + 627: [ + (Included(0), Unbounded), + ], + }, + 15: { + 348: [ + (Included(3), Excluded(14)), + ], + 396: [ + (Included(7), Excluded(15)), + ], + 455: [ + (Included(2), Excluded(17)), + ], + 589: [ + (Included(6), Excluded(8)), + ], + }, + 18: { + 396: [ + (Included(0), Excluded(12)), + ], + 450: [ + (Included(3), Excluded(4)), + ], + 455: [ + (Included(8), Excluded(11)), + ], + 535: [ + (Included(3), Unbounded), + ], + 569: [ + (Included(8), Excluded(10)), + ], + 584: [ + (Included(5), Unbounded), + ], + 594: [ + (Included(0), Excluded(6)), + ], + 601: [ + (Included(5), Excluded(18)), + ], + 613: [ + (Included(8), Excluded(11)), + ], + }, + }, + 334: { + 0: { + 405: [ + (Included(0), Excluded(10)), + ], + 599: [ + (Included(2), Excluded(15)), + ], + 613: [ + (Included(6), Unbounded), + ], + }, + 1: { + 396: [ + (Included(7), Excluded(19)), + ], + 477: [ + (Included(1), Excluded(16)), + ], + 484: [ + (Included(4), Unbounded), + ], + 491: [ + (Included(8), Unbounded), + ], + 541: [ + (Included(6), Excluded(15)), + ], + 662: [ + (Included(3), Excluded(8)), + ], + }, + 3: { + 450: [ + (Included(7), Excluded(15)), + ], + 477: [ + (Included(1), Excluded(14)), + ], + 535: [ + (Included(5), Excluded(16)), + ], + 569: [ + (Included(2), Excluded(19)), + ], + 645: [ + (Included(2), Excluded(7)), + ], + }, + 5: { + 418: [ + (Included(0), Unbounded), + ], + 455: [ + (Included(4), Excluded(10)), + ], + }, + 6: { + 410: [ + (Included(5), Excluded(14)), + ], + 418: [ + (Included(0), Excluded(4)), + ], + 462: [ + (Included(2), Excluded(5)), + ], + }, + 7: { + 405: [ + (Included(2), Excluded(7)), + ], + 593: [ + (Included(0), Unbounded), + ], + 662: [ + (Included(0), Excluded(4)), + ], + }, + 8: { + 348: [ + (Included(4), Unbounded), + ], + 437: [ + (Included(0), Excluded(16)), + ], + 484: [ + (Included(1), Excluded(15)), + ], + 491: [ + (Included(0), Excluded(4)), + ], + 627: [ + (Included(2), Unbounded), + ], + }, + 11: { + 349: [ + (Included(1), Excluded(12)), + ], + 491: [ + (Included(5), Excluded(7)), + ], + 660: [ + (Included(0), Excluded(2)), + ], + }, + 15: { + 364: [ + (Included(4), Excluded(13)), + ], + 601: [ + (Included(6), Excluded(18)), + ], + 662: [ + (Included(5), Excluded(17)), + ], + }, + 19: { + 647: [ + (Included(1), Unbounded), + ], + }, + }, + 335: { + 0: { + 601: [ + (Included(1), Unbounded), + ], + }, + 1: { + 455: [ + (Included(0), Excluded(18)), + ], + 495: [ + (Included(3), Excluded(13)), + ], + 569: [ + (Included(6), Excluded(19)), + ], + }, + 2: { + 448: [ + (Included(1), Excluded(17)), + ], + 625: [ + (Included(0), Excluded(9)), + ], + 660: [ + (Included(0), Excluded(4)), + ], + }, + 3: { + 346: [ + (Included(2), Excluded(15)), + ], + 443: [ + (Included(2), Unbounded), + ], + 455: [ + (Included(4), Excluded(9)), + ], + 475: [ + (Included(9), Unbounded), + ], + 523: [ + (Included(0), Excluded(9)), + ], + }, + 6: { + 345: [ + (Included(3), Excluded(15)), + ], + 396: [ + (Included(0), Excluded(4)), + ], + 505: [ + (Included(0), Excluded(7)), + ], + }, + 7: { + 455: [ + (Included(7), Unbounded), + ], + 477: [ + (Included(3), Excluded(14)), + ], + }, + 8: { + 599: [ + (Included(7), Excluded(14)), + ], + }, + 11: { + 547: [ + (Included(3), Excluded(6)), + ], + 600: [ + (Included(0), Excluded(9)), + ], + 627: [ + (Included(7), Unbounded), + ], + }, + 12: { + 445: [ + (Included(0), Excluded(9)), + ], + }, + 15: { + 462: [ + (Included(4), Unbounded), + ], + }, + 16: { + 405: [ + (Included(7), Unbounded), + ], + 471: [ + (Included(0), Excluded(3)), + ], + 627: [ + (Included(7), Excluded(12)), + ], + }, + 17: { + 396: [ + (Included(0), Excluded(18)), + ], + 418: [ + (Included(3), Excluded(19)), + ], + 574: [ + (Included(1), Excluded(19)), + ], + 645: [ + (Included(5), Unbounded), + ], + }, + 18: { + 345: [ + (Included(0), Excluded(15)), + ], + 471: [ + (Included(0), Excluded(2)), + ], + 584: [ + (Included(0), Excluded(12)), + ], + 589: [ + (Included(8), Excluded(9)), + ], + }, + 19: { + 344: [ + (Included(3), Excluded(16)), + ], + 345: [ + (Included(9), Unbounded), + ], + 547: [ + (Included(7), Unbounded), + ], + 574: [ + (Included(4), Unbounded), + ], + 584: [ + (Included(3), Unbounded), + ], + }, + }, + 341: { + 1: { + 348: [ + (Included(6), Excluded(18)), + ], + 370: [ + (Included(0), Unbounded), + ], + 479: [ + (Included(0), Unbounded), + ], + 574: [ + (Included(4), Excluded(11)), + ], + 593: [ + (Included(1), Unbounded), + ], + }, + 2: { + 346: [ + (Included(0), Excluded(5)), + ], + 364: [ + (Included(9), Excluded(12)), + ], + 450: [ + (Included(6), Excluded(15)), + ], + }, + 6: { + 348: [ + (Included(0), Excluded(13)), + ], + 484: [ + (Included(4), Unbounded), + ], + 494: [ + (Included(5), Unbounded), + ], + 595: [ + (Included(4), Unbounded), + ], + }, + 7: { + 447: [ + (Included(1), Unbounded), + ], + 627: [ + (Included(7), Excluded(12)), + ], + }, + 10: { + 505: [ + (Included(2), Unbounded), + ], + 576: [ + (Included(0), Excluded(16)), + ], + }, + 11: { + 348: [ + (Included(0), Excluded(11)), + ], + 364: [ + (Included(4), Excluded(8)), + ], + 541: [ + (Included(7), Excluded(8)), + ], + }, + 14: { + 348: [ + (Included(4), Excluded(16)), + ], + 445: [ + (Included(8), Unbounded), + ], + 448: [ + (Included(3), Excluded(16)), + ], + 600: [ + (Included(2), Excluded(13)), + ], + }, + 16: { + 535: [ + (Included(6), Unbounded), + ], + 547: [ + (Included(0), Excluded(19)), + ], + 601: [ + (Included(6), Unbounded), + ], + }, + 17: { + 396: [ + (Included(4), Excluded(16)), + ], + 477: [ + (Included(4), Excluded(16)), + ], + 569: [ + (Included(3), Unbounded), + ], + }, + }, + 344: { + 2: { + 396: [ + (Included(4), Excluded(19)), + ], + 477: [ + (Included(4), Unbounded), + ], + 576: [ + (Included(8), Excluded(11)), + ], + 647: [ + (Included(0), Excluded(4)), + ], + }, + 3: { + 405: [ + (Included(1), Excluded(14)), + ], + 574: [ + (Included(8), Excluded(11)), + ], + }, + 6: { + 364: [ + (Included(5), Excluded(13)), + ], + 599: [ + (Included(7), Excluded(15)), + ], + }, + 9: { + 450: [ + (Included(3), Excluded(17)), + ], + }, + 13: { + 345: [ + (Included(4), Excluded(12)), + ], + 352: [ + (Included(0), Excluded(10)), + ], + 475: [ + (Included(3), Unbounded), + ], + 560: [ + (Included(4), Excluded(9)), + ], + 594: [ + (Included(4), Excluded(12)), + ], + }, + 14: { + 348: [ + (Included(0), Excluded(12)), + ], + 441: [ + (Included(0), Excluded(9)), + ], + 443: [ + (Included(2), Unbounded), + ], + 462: [ + (Included(4), Unbounded), + ], + 523: [ + (Included(0), Excluded(12)), + ], + 599: [ + (Included(7), Excluded(14)), + ], + }, + 15: { + 349: [ + (Included(7), Excluded(13)), + ], + 437: [ + (Included(5), Unbounded), + ], + }, + 19: { + 352: [ + (Included(9), Excluded(16)), + ], + 625: [ + (Included(6), Excluded(9)), + ], + }, + }, + 345: { + 0: { + 441: [ + (Included(8), Unbounded), + ], + 601: [ + (Included(0), Excluded(5)), + ], + 635: [ + (Included(1), Unbounded), + ], + }, + 1: { + 349: [ + (Included(5), Excluded(11)), + ], + 364: [ + (Included(5), Excluded(11)), + ], + 371: [ + (Included(0), Excluded(12)), + ], + 491: [ + (Included(0), Excluded(4)), + ], + 569: [ + (Included(8), Excluded(19)), + ], + 627: [ + (Included(2), Excluded(18)), + ], + }, + 3: { + 405: [ + (Included(4), Excluded(11)), + ], + 450: [ + (Included(0), Excluded(17)), + ], + 475: [ + (Included(0), Unbounded), + ], + 541: [ + (Included(8), Excluded(15)), + ], + }, + 4: { + 349: [ + (Included(0), Excluded(13)), + ], + 405: [ + (Included(0), Excluded(14)), + ], + 418: [ + (Included(0), Excluded(9)), + ], + 462: [ + (Included(3), Excluded(5)), + ], + 523: [ + (Included(1), Excluded(2)), + ], + 535: [ + (Included(5), Unbounded), + ], + 595: [ + (Included(0), Excluded(16)), + ], + }, + 6: { + 455: [ + (Included(7), Excluded(18)), + ], + 495: [ + (Included(0), Excluded(10)), + ], + 569: [ + (Included(3), Excluded(17)), + ], + }, + 7: { + 471: [ + (Included(2), Unbounded), + ], + 535: [ + (Included(6), Excluded(14)), + ], + }, + 9: { + 447: [ + (Included(8), Excluded(12)), + ], + 595: [ + (Included(0), Excluded(16)), + ], + }, + 10: { + 396: [ + (Included(3), Excluded(8)), + ], + 455: [ + (Included(0), Excluded(17)), + ], + 523: [ + (Included(0), Excluded(14)), + ], + 562: [ + (Included(1), Excluded(12)), + ], + }, + 11: {}, + 13: { + 562: [ + (Included(0), Excluded(18)), + ], + }, + 14: { + 346: [ + (Included(2), Excluded(13)), + ], + 445: [ + (Included(0), Unbounded), + ], + 484: [ + (Included(6), Unbounded), + ], + }, + 17: { + 364: [ + (Included(5), Excluded(13)), + ], + }, + 18: { + 349: [ + (Included(1), Excluded(8)), + ], + 410: [ + (Included(0), Excluded(14)), + ], + 448: [ + (Included(3), Unbounded), + ], + 491: [ + (Included(6), Unbounded), + ], + 627: [ + (Included(1), Excluded(12)), + ], + }, + 19: { + 437: [ + (Included(0), Unbounded), + ], + 523: [ + (Included(0), Unbounded), + ], + 541: [ + (Included(8), Unbounded), + ], + 601: [ + (Included(6), Excluded(13)), + ], + 662: [ + (Included(7), Excluded(19)), + ], + }, + }, + 346: { + 1: { + 400: [ + (Included(4), Excluded(5)), + ], + 560: [ + (Included(4), Excluded(5)), + ], + 574: [ + (Included(0), Excluded(15)), + ], + 662: [ + (Included(5), Excluded(17)), + ], + }, + 2: { + 396: [ + (Included(9), Excluded(16)), + ], + 455: [ + (Included(8), Excluded(10)), + ], + 484: [ + (Included(0), Excluded(17)), + ], + 535: [ + (Included(3), Excluded(14)), + ], + }, + 4: { + 455: [ + (Included(4), Excluded(5)), + ], + 484: [ + (Included(2), Excluded(17)), + ], + 495: [ + (Included(4), Excluded(10)), + ], + 535: [ + (Included(6), Excluded(13)), + ], + 608: [ + (Included(0), Unbounded), + ], + }, + 6: { + 349: [ + (Included(1), Excluded(5)), + ], + 599: [ + (Included(4), Unbounded), + ], + 608: [ + (Included(6), Excluded(13)), + ], + 635: [ + (Included(7), Unbounded), + ], + }, + 10: {}, + 12: { + 505: [ + (Included(3), Excluded(18)), + ], + 627: [ + (Included(7), Excluded(15)), + ], + }, + 13: { + 352: [ + (Included(0), Excluded(16)), + ], + 437: [ + (Included(0), Excluded(12)), + ], + 448: [ + (Included(6), Excluded(17)), + ], + 600: [ + (Included(9), Excluded(10)), + ], + 635: [ + (Included(5), Unbounded), + ], + 662: [ + (Included(0), Excluded(18)), + ], + }, + 14: { + 500: [ + (Included(5), Excluded(13)), + ], + 589: [ + (Included(7), Excluded(11)), + ], + }, + 16: { + 418: [ + (Included(3), Excluded(17)), + ], + 455: [ + (Included(8), Excluded(17)), + ], + 660: [ + (Included(3), Excluded(10)), + ], + }, + 18: { + 666: [ + (Included(0), Unbounded), + ], + }, + 19: { + 349: [ + (Included(4), Excluded(9)), + ], + 351: [ + (Included(0), Excluded(7)), + ], + 450: [ + (Included(6), Excluded(17)), + ], + }, + }, + 348: { + 2: { + 484: [ + (Included(0), Excluded(5)), + ], + }, + 3: { + 385: [ + (Included(5), Unbounded), + ], + 400: [ + (Included(0), Unbounded), + ], + 477: [ + (Included(1), Excluded(13)), + ], + 608: [ + (Included(0), Unbounded), + ], + 613: [ + (Included(0), Unbounded), + ], + }, + 4: { + 484: [ + (Included(7), Excluded(11)), + ], + 491: [ + (Included(0), Unbounded), + ], + 593: [ + (Included(0), Excluded(13)), + ], + 619: [ + (Included(2), Unbounded), + ], + 627: [ + (Included(1), Excluded(19)), + ], + }, + 7: { + 370: [ + (Included(6), Unbounded), + ], + 418: [ + (Included(9), Unbounded), + ], + 500: [ + (Included(5), Excluded(13)), + ], + 547: [ + (Included(1), Excluded(14)), + ], + 594: [ + (Included(4), Excluded(6)), + ], + 595: [ + (Included(2), Excluded(11)), + ], + }, + 8: { + 505: [ + (Included(3), Unbounded), + ], + 547: [ + (Included(2), Excluded(4)), + ], + 559: [ + (Included(8), Excluded(9)), + ], + 560: [ + (Included(2), Unbounded), + ], + 562: [ + (Included(0), Excluded(12)), + ], + 594: [ + (Included(1), Unbounded), + ], + }, + 9: { + 418: [ + (Included(0), Excluded(19)), + ], + 477: [ + (Included(8), Unbounded), + ], + 505: [ + (Included(0), Excluded(11)), + ], + 574: [ + (Included(1), Unbounded), + ], + }, + 10: { + 349: [ + (Included(5), Excluded(13)), + ], + 471: [ + (Included(2), Excluded(3)), + ], + }, + 11: { + 494: [ + (Included(0), Excluded(2)), + ], + }, + 12: { + 541: [ + (Included(6), Unbounded), + ], + 599: [ + (Included(1), Excluded(8)), + ], + }, + 13: { + 600: [ + (Included(6), Excluded(10)), + ], + 635: [ + (Included(1), Unbounded), + ], + 650: [ + (Included(7), Unbounded), + ], + }, + 14: { + 437: [ + (Included(0), Excluded(12)), + ], + 594: [ + (Included(1), Excluded(12)), + ], + }, + 15: { + 477: [ + (Included(1), Excluded(3)), + ], + 500: [ + (Included(6), Unbounded), + ], + }, + 16: { + 405: [ + (Included(4), Excluded(15)), + ], + 523: [ + (Included(8), Excluded(11)), + ], + 595: [ + (Included(0), Unbounded), + ], + 606: [ + (Included(7), Excluded(8)), + ], + 625: [ + (Included(0), Excluded(2)), + ], + }, + 17: { + 495: [ + (Included(9), Unbounded), + ], + }, + 18: {}, + }, + 349: { + 0: { + 352: [ + (Included(0), Excluded(17)), + ], + 599: [ + (Included(1), Excluded(14)), + ], + 601: [ + (Included(4), Excluded(17)), + ], + }, + 1: { + 559: [ + (Included(9), Excluded(13)), + ], + 593: [ + (Included(0), Excluded(12)), + ], + }, + 2: { + 396: [ + (Included(4), Excluded(12)), + ], + 600: [ + (Included(9), Unbounded), + ], + }, + 3: {}, + 4: { + 450: [ + (Included(3), Excluded(6)), + ], + 505: [ + (Included(1), Excluded(3)), + ], + 547: [ + (Included(0), Excluded(3)), + ], + }, + 5: { + 484: [ + (Included(4), Excluded(5)), + ], + 541: [ + (Included(5), Excluded(16)), + ], + 627: [ + (Included(7), Excluded(8)), + ], + }, + 6: { + 500: [ + (Included(0), Excluded(6)), + ], + 625: [ + (Included(6), Excluded(9)), + ], + }, + 7: { + 418: [ + (Included(9), Unbounded), + ], + 541: [ + (Included(7), Excluded(9)), + ], + 601: [ + (Included(7), Unbounded), + ], + }, + 8: { + 445: [ + (Included(0), Excluded(6)), + ], + 450: [ + (Included(4), Excluded(8)), + ], + 541: [ + (Included(8), Excluded(9)), + ], + 547: [ + (Included(3), Excluded(13)), + ], + 600: [ + (Included(8), Unbounded), + ], + 601: [ + (Included(0), Excluded(5)), + ], + 619: [ + (Included(0), Excluded(5)), + ], + }, + 9: { + 396: [ + (Included(0), Excluded(15)), + ], + 405: [ + (Included(1), Excluded(2)), + ], + }, + 10: { + 627: [ + (Included(7), Excluded(18)), + ], + }, + 11: { + 495: [ + (Included(0), Excluded(9)), + ], + 523: [ + (Included(8), Excluded(11)), + ], + }, + 12: { + 477: [ + (Included(0), Excluded(3)), + ], + }, + 14: { + 385: [ + (Included(0), Excluded(6)), + ], + 576: [ + (Included(8), Excluded(18)), + ], + 589: [ + (Included(0), Excluded(8)), + ], + 608: [ + (Included(0), Excluded(7)), + ], + 662: [ + (Included(3), Excluded(8)), + ], + }, + 17: { + 396: [ + (Included(5), Excluded(18)), + ], + 455: [ + (Included(4), Excluded(16)), + ], + }, + }, + 352: { + 5: {}, + 6: { + 477: [ + (Included(9), Excluded(14)), + ], + 562: [ + (Included(2), Unbounded), + ], + }, + 9: { + 601: [ + (Included(1), Excluded(6)), + ], + }, + 10: { + 574: [ + (Included(8), Excluded(10)), + ], + }, + 14: { + 437: [ + (Included(5), Excluded(16)), + ], + 584: [ + (Included(3), Excluded(12)), + ], + 647: [ + (Included(0), Unbounded), + ], + }, + 15: { + 477: [ + (Included(1), Excluded(14)), + ], + 560: [ + (Included(0), Excluded(7)), + ], + 594: [ + (Included(1), Unbounded), + ], + }, + 16: { + 613: [ + (Included(8), Unbounded), + ], + }, + 17: { + 477: [ + (Included(2), Excluded(14)), + ], + 484: [ + (Included(6), Excluded(18)), + ], + 547: [ + (Included(0), Excluded(5)), + ], + 593: [ + (Included(4), Excluded(13)), + ], + 613: [ + (Included(0), Unbounded), + ], + }, + }, + 364: { + 0: { + 562: [ + (Included(8), Excluded(18)), + ], + }, + 4: { + 523: [ + (Included(1), Excluded(7)), + ], + }, + 5: { + 601: [ + (Included(4), Excluded(9)), + ], + 645: [ + (Included(6), Unbounded), + ], + }, + 7: { + 396: [ + (Included(3), Excluded(11)), + ], + }, + 9: { + 595: [ + (Included(2), Excluded(15)), + ], + }, + 10: {}, + 11: {}, + 12: { + 437: [ + (Included(0), Unbounded), + ], + 455: [ + (Included(0), Excluded(18)), + ], + 484: [ + (Included(8), Excluded(11)), + ], + 601: [ + (Included(1), Excluded(13)), + ], + }, + 14: { + 589: [ + (Included(7), Excluded(8)), + ], + }, + }, + 371: { + 9: { + 400: [ + (Included(0), Excluded(1)), + ], + 455: [ + (Included(0), Excluded(9)), + ], + 477: [ + (Included(9), Excluded(16)), + ], + 645: [ + (Included(0), Excluded(7)), + ], + }, + 11: { + 405: [ + (Included(5), Excluded(7)), + ], + 410: [ + (Included(0), Excluded(6)), + ], + 547: [ + (Included(2), Excluded(13)), + ], + 574: [ + (Included(2), Excluded(12)), + ], + 576: [ + (Included(0), Excluded(18)), + ], + 589: [ + (Included(6), Excluded(8)), + ], + }, + 12: { + 443: [ + (Included(0), Excluded(15)), + ], + 475: [ + (Included(0), Excluded(4)), + ], + 547: [ + (Included(0), Excluded(14)), + ], + 562: [ + (Included(0), Excluded(18)), + ], + }, + 13: { + 400: [ + (Included(0), Excluded(1)), + ], + 601: [ + (Included(4), Excluded(15)), + ], + }, + 18: { + 455: [ + (Included(7), Excluded(13)), + ], + 627: [ + (Included(0), Excluded(16)), + ], + }, + 19: { + 495: [ + (Included(0), Excluded(10)), + ], + 505: [ + (Included(0), Excluded(11)), + ], + 523: [ + (Included(1), Excluded(15)), + ], + }, + }, + 396: { + 1: { + 477: [ + (Included(4), Excluded(10)), + ], + 574: [ + (Included(1), Excluded(19)), + ], + 606: [ + (Included(6), Unbounded), + ], + }, + 3: { + 562: [ + (Included(8), Excluded(18)), + ], + 569: [ + (Included(0), Excluded(17)), + ], + 576: [ + (Included(5), Unbounded), + ], + }, + 4: { + 535: [ + (Included(8), Excluded(14)), + ], + 589: [ + (Included(1), Excluded(9)), + ], + 627: [ + (Included(7), Unbounded), + ], + }, + 5: { + 484: [ + (Included(4), Excluded(18)), + ], + }, + 7: { + 562: [ + (Included(2), Unbounded), + ], + 608: [ + (Included(0), Unbounded), + ], + }, + 9: { + 448: [ + (Included(5), Excluded(17)), + ], + 523: [ + (Included(9), Excluded(10)), + ], + 660: [ + (Included(0), Unbounded), + ], + }, + 10: { + 484: [ + (Included(0), Excluded(15)), + ], + 547: [ + (Included(1), Excluded(13)), + ], + 619: [ + (Included(2), Excluded(9)), + ], + }, + 11: { + 441: [ + (Included(8), Excluded(16)), + ], + 589: [ + (Included(7), Excluded(11)), + ], + }, + 14: { + 535: [ + (Included(2), Unbounded), + ], + 650: [ + (Included(2), Excluded(15)), + ], + }, + 15: { + 418: [ + (Included(8), Unbounded), + ], + 495: [ + (Included(1), Excluded(13)), + ], + 523: [ + (Included(8), Excluded(14)), + ], + 547: [ + (Included(1), Excluded(19)), + ], + 627: [ + (Included(7), Unbounded), + ], + 650: [ + (Included(0), Excluded(15)), + ], + }, + 17: { + 441: [ + (Included(5), Unbounded), + ], + }, + 18: { + 443: [ + (Included(0), Excluded(1)), + ], + 662: [ + (Included(6), Excluded(18)), + ], + }, + 19: { + 443: [ + (Included(2), Excluded(15)), + ], + 593: [ + (Included(0), Excluded(5)), + ], + }, + }, + 400: { + 0: { + 443: [ + (Included(0), Excluded(13)), + ], + 462: [ + (Included(4), Excluded(5)), + ], + }, + 4: { + 666: [ + (Included(0), Unbounded), + ], + }, + 9: { + 462: [ + (Included(4), Unbounded), + ], + 599: [ + (Included(0), Excluded(3)), + ], + 600: [ + (Included(6), Excluded(8)), + ], + }, + }, + 405: { + 0: { + 455: [ + (Included(8), Excluded(9)), + ], + 599: [ + (Included(7), Excluded(15)), + ], + 625: [ + (Included(6), Excluded(7)), + ], + }, + 1: { + 484: [ + (Included(6), Excluded(17)), + ], + 594: [ + (Included(1), Excluded(6)), + ], + 662: [ + (Included(6), Excluded(18)), + ], + }, + 2: { + 410: [ + (Included(0), Unbounded), + ], + 477: [ + (Included(2), Excluded(16)), + ], + 484: [ + (Included(4), Excluded(9)), + ], + 601: [ + (Included(2), Excluded(17)), + ], + }, + 4: { + 450: [ + (Included(4), Excluded(17)), + ], + 462: [ + (Included(2), Excluded(7)), + ], + 495: [ + (Included(0), Unbounded), + ], + 559: [ + (Included(0), Unbounded), + ], + 562: [ + (Included(8), Excluded(13)), + ], + }, + 5: { + 447: [ + (Included(8), Excluded(12)), + ], + 477: [ + (Included(2), Unbounded), + ], + 600: [ + (Included(6), Unbounded), + ], + }, + 6: { + 495: [ + (Included(0), Excluded(6)), + ], + 594: [ + (Included(2), Unbounded), + ], + 635: [ + (Included(4), Excluded(16)), + ], + }, + 7: { + 547: [ + (Included(2), Excluded(12)), + ], + 562: [ + (Included(0), Excluded(15)), + ], + }, + 9: { + 635: [ + (Included(4), Excluded(10)), + ], + }, + 10: { + 547: [ + (Included(5), Excluded(19)), + ], + 559: [ + (Included(0), Excluded(12)), + ], + }, + 11: {}, + 13: { + 450: [ + (Included(3), Excluded(17)), + ], + 523: [ + (Included(9), Excluded(15)), + ], + 562: [ + (Included(1), Excluded(15)), + ], + 574: [ + (Included(0), Unbounded), + ], + 627: [ + (Included(7), Excluded(19)), + ], + }, + 14: { + 600: [ + (Included(0), Excluded(9)), + ], + 650: [ + (Included(7), Excluded(15)), + ], + }, + 17: { + 450: [ + (Included(7), Excluded(17)), + ], + 491: [ + (Included(0), Excluded(6)), + ], + 505: [ + (Included(2), Excluded(10)), + ], + }, + }, + 410: { + 3: { + 475: [ + (Included(0), Excluded(4)), + ], + 484: [ + (Included(0), Excluded(18)), + ], + 505: [ + (Included(1), Excluded(18)), + ], + 660: [ + (Included(3), Excluded(10)), + ], + }, + 5: { + 447: [ + (Included(8), Unbounded), + ], + 477: [ + (Included(1), Excluded(13)), + ], + }, + 7: {}, + 9: { + 569: [ + (Included(2), Excluded(19)), + ], + }, + 13: { + 491: [ + (Included(5), Excluded(6)), + ], + 541: [ + (Included(8), Unbounded), + ], + }, + 16: { + 484: [ + (Included(0), Excluded(15)), + ], + 523: [ + (Included(0), Excluded(14)), + ], + 601: [ + (Included(4), Excluded(15)), + ], + }, + 18: { + 477: [ + (Included(1), Excluded(14)), + ], + 595: [ + (Included(0), Excluded(14)), + ], + }, + }, + 418: { + 0: { + 627: [ + (Included(3), Excluded(15)), + ], + }, + 3: { + 450: [ + (Included(3), Excluded(6)), + ], + 535: [ + (Included(3), Excluded(16)), + ], + 627: [ + (Included(7), Excluded(13)), + ], + }, + 8: { + 484: [ + (Included(7), Excluded(8)), + ], + 574: [ + (Included(0), Excluded(12)), + ], + 601: [ + (Included(2), Excluded(18)), + ], + }, + 15: { + 441: [ + (Included(0), Excluded(16)), + ], + 450: [ + (Included(4), Unbounded), + ], + }, + 16: { + 662: [ + (Included(0), Unbounded), + ], + }, + 18: { + 437: [ + (Included(0), Excluded(16)), + ], + 576: [ + (Included(8), Excluded(9)), + ], + 595: [ + (Included(3), Excluded(17)), + ], + }, + 19: { + 505: [ + (Included(0), Excluded(2)), + ], + }, + }, + 437: { + 11: { + 450: [ + (Included(6), Excluded(11)), + ], + }, + 15: { + 535: [ + (Included(8), Unbounded), + ], + 541: [ + (Included(3), Excluded(16)), + ], + 593: [ + (Included(9), Excluded(12)), + ], + 600: [ + (Included(0), Excluded(8)), + ], + 635: [ + (Included(9), Unbounded), + ], + }, + 16: { + 450: [ + (Included(4), Excluded(17)), + ], + 475: [ + (Included(9), Unbounded), + ], + 500: [ + (Included(0), Excluded(3)), + ], + 547: [ + (Included(3), Excluded(17)), + ], + 593: [ + (Included(8), Excluded(13)), + ], + }, + }, + 441: { + 2: {}, + 8: { + 462: [ + (Included(3), Excluded(8)), + ], + 491: [ + (Included(3), Excluded(6)), + ], + }, + 13: { + 445: [ + (Included(8), Unbounded), + ], + 569: [ + (Included(0), Excluded(13)), + ], + }, + 15: { + 455: [ + (Included(4), Excluded(5)), + ], + 505: [ + (Included(6), Excluded(14)), + ], + }, + 16: { + 560: [ + (Included(8), Unbounded), + ], + 589: [ + (Included(8), Excluded(11)), + ], + }, + }, + 443: { + 0: { + 447: [ + (Included(0), Excluded(12)), + ], + 500: [ + (Included(0), Unbounded), + ], + 505: [ + (Included(0), Excluded(18)), + ], + 547: [ + (Included(3), Unbounded), + ], + }, + 12: { + 523: [ + (Included(6), Excluded(19)), + ], + 562: [ + (Included(0), Excluded(13)), + ], + 606: [ + (Included(0), Excluded(7)), + ], + }, + 14: { + 450: [ + (Included(3), Excluded(15)), + ], + 574: [ + (Included(0), Excluded(2)), + ], + 595: [ + (Included(2), Excluded(14)), + ], + }, + 17: { + 569: [ + (Included(6), Unbounded), + ], + }, + }, + 447: { + 1: { + 541: [ + (Included(8), Unbounded), + ], + }, + 8: { + 645: [ + (Included(0), Excluded(1)), + ], + }, + 11: { + 541: [ + (Included(6), Excluded(9)), + ], + }, + 13: { + 606: [ + (Included(6), Excluded(17)), + ], + 662: [ + (Included(6), Unbounded), + ], + }, + 14: { + 450: [ + (Included(6), Excluded(15)), + ], + 500: [ + (Included(0), Unbounded), + ], + 541: [ + (Included(6), Excluded(15)), + ], + }, + }, + 448: { + 3: { + 562: [ + (Included(8), Excluded(11)), + ], + 662: [ + (Included(6), Excluded(18)), + ], + }, + 11: { + 450: [ + (Included(0), Excluded(17)), + ], + 455: [ + (Included(0), Excluded(16)), + ], + 477: [ + (Included(0), Unbounded), + ], + 505: [ + (Included(1), Excluded(7)), + ], + 601: [ + (Included(1), Excluded(5)), + ], + 625: [ + (Included(4), Excluded(7)), + ], + 650: [ + (Included(0), Excluded(15)), + ], + 660: [ + (Included(0), Unbounded), + ], + }, + 12: { + 562: [ + (Included(0), Excluded(15)), + ], + }, + 13: { + 455: [ + (Included(7), Unbounded), + ], + 650: [ + (Included(4), Excluded(15)), + ], + }, + 15: {}, + 16: { + 660: [ + (Included(0), Excluded(4)), + ], + }, + 19: { + 484: [ + (Included(7), Excluded(8)), + ], + 601: [ + (Included(4), Excluded(7)), + ], + }, + }, + 450: { + 2: { + 601: [ + (Included(1), Excluded(18)), + ], + }, + 3: { + 505: [ + (Included(1), Excluded(2)), + ], + }, + 4: {}, + 5: { + 484: [ + (Included(8), Excluded(17)), + ], + 547: [ + (Included(4), Excluded(13)), + ], + 576: [ + (Included(8), Unbounded), + ], + 594: [ + (Included(4), Unbounded), + ], + }, + 6: { + 645: [ + (Included(5), Unbounded), + ], + }, + 7: { + 477: [ + (Included(0), Excluded(5)), + ], + 593: [ + (Included(9), Unbounded), + ], + 645: [ + (Included(6), Unbounded), + ], + }, + 10: {}, + 13: { + 495: [ + (Included(3), Excluded(5)), + ], + }, + 14: { + 471: [ + (Included(2), Unbounded), + ], + 495: [ + (Included(9), Excluded(12)), + ], + 562: [ + (Included(2), Excluded(15)), + ], + 619: [ + (Included(2), Excluded(7)), + ], + }, + 16: { + 500: [ + (Included(0), Unbounded), + ], + 535: [ + (Included(2), Excluded(14)), + ], + 594: [ + (Included(4), Excluded(12)), + ], + }, + 17: { + 560: [ + (Included(0), Excluded(9)), + ], + 562: [ + (Included(1), Unbounded), + ], + 599: [ + (Included(0), Excluded(2)), + ], + }, + 19: { + 471: [ + (Included(2), Unbounded), + ], + 523: [ + (Included(0), Excluded(14)), + ], + 576: [ + (Included(0), Excluded(16)), + ], + 645: [ + (Included(2), Unbounded), + ], + 662: [ + (Included(7), Excluded(9)), + ], + }, + }, + 455: { + 2: { + 491: [ + (Included(0), Excluded(1)), + ], + 559: [ + (Included(0), Excluded(12)), + ], + 560: [ + (Included(0), Unbounded), + ], + }, + 4: { + 600: [ + (Included(0), Excluded(13)), + ], + }, + 7: { + 484: [ + (Included(4), Excluded(17)), + ], + 574: [ + (Included(2), Excluded(15)), + ], + 595: [ + (Included(0), Excluded(2)), + ], + }, + 8: { + 560: [ + (Included(6), Unbounded), + ], + 574: [ + (Included(4), Excluded(12)), + ], + 599: [ + (Included(7), Excluded(14)), + ], + }, + 9: { + 562: [ + (Included(4), Excluded(18)), + ], + 595: [ + (Included(0), Excluded(14)), + ], + 601: [ + (Included(0), Excluded(6)), + ], + }, + 10: { + 600: [ + (Included(6), Excluded(8)), + ], + 613: [ + (Included(6), Unbounded), + ], + 662: [ + (Included(3), Excluded(9)), + ], + }, + 12: { + 666: [ + (Included(0), Unbounded), + ], + }, + 15: { + 666: [ + (Included(0), Unbounded), + ], + }, + 16: { + 495: [ + (Included(3), Excluded(4)), + ], + 599: [ + (Included(2), Excluded(3)), + ], + 650: [ + (Included(2), Unbounded), + ], + }, + 17: { + 491: [ + (Included(9), Excluded(10)), + ], + 569: [ + (Included(3), Excluded(19)), + ], + 662: [ + (Included(7), Excluded(19)), + ], + }, + 19: {}, + }, + 462: { + 1: {}, + 2: { + 477: [ + (Included(0), Excluded(10)), + ], + 574: [ + (Included(2), Excluded(12)), + ], + 601: [ + (Included(4), Excluded(17)), + ], + 606: [ + (Included(6), Unbounded), + ], + 625: [ + (Included(4), Excluded(9)), + ], + }, + 3: { + 589: [ + (Included(8), Excluded(11)), + ], + 608: [ + (Included(9), Unbounded), + ], + }, + 4: { + 479: [ + (Included(0), Excluded(6)), + ], + 635: [ + (Included(1), Excluded(5)), + ], + }, + 6: { + 535: [ + (Included(6), Unbounded), + ], + 599: [ + (Included(2), Excluded(14)), + ], + 608: [ + (Included(0), Excluded(5)), + ], + 613: [ + (Included(8), Excluded(11)), + ], + }, + 7: { + 484: [ + (Included(2), Excluded(18)), + ], + 574: [ + (Included(4), Excluded(19)), + ], + 606: [ + (Included(6), Excluded(17)), + ], + }, + 12: { + 477: [ + (Included(1), Excluded(8)), + ], + 547: [ + (Included(4), Excluded(18)), + ], + 574: [ + (Included(9), Unbounded), + ], + 593: [ + (Included(8), Excluded(14)), + ], + }, + 14: { + 491: [ + (Included(3), Excluded(7)), + ], + }, + 16: { + 608: [ + (Included(0), Excluded(7)), + ], + }, + }, + 471: { + 1: { + 484: [ + (Included(2), Excluded(9)), + ], + 569: [ + (Included(8), Excluded(10)), + ], + 599: [ + (Included(1), Excluded(13)), + ], + }, + 2: { + 494: [ + (Included(0), Unbounded), + ], + 608: [ + (Included(0), Unbounded), + ], + }, + 18: { + 484: [ + (Included(4), Excluded(18)), + ], + 523: [ + (Included(9), Excluded(10)), + ], + 576: [ + (Included(7), Excluded(18)), + ], + 662: [ + (Included(8), Excluded(18)), + ], + }, + }, + 475: { + 0: { + 500: [ + (Included(6), Unbounded), + ], + 560: [ + (Included(4), Unbounded), + ], + 569: [ + (Included(2), Unbounded), + ], + 589: [ + (Included(8), Excluded(11)), + ], + 608: [ + (Included(6), Excluded(10)), + ], + }, + 3: { + 599: [ + (Included(1), Excluded(8)), + ], + 619: [ + (Included(2), Excluded(15)), + ], + }, + 9: { + 593: [ + (Included(4), Excluded(13)), + ], + }, + }, + 477: { + 0: { + 505: [ + (Included(1), Excluded(18)), + ], + 562: [ + (Included(0), Excluded(13)), + ], + }, + 1: { + 523: [ + (Included(0), Excluded(15)), + ], + }, + 2: { + 484: [ + (Included(0), Excluded(12)), + ], + 608: [ + (Included(0), Excluded(13)), + ], + }, + 4: { + 541: [ + (Included(4), Excluded(16)), + ], + 601: [ + (Included(0), Excluded(1)), + ], + }, + 7: { + 569: [ + (Included(0), Excluded(19)), + ], + 600: [ + (Included(0), Unbounded), + ], + }, + 9: { + 484: [ + (Included(2), Excluded(15)), + ], + 569: [ + (Included(8), Excluded(19)), + ], + 608: [ + (Included(9), Excluded(13)), + ], + 645: [ + (Included(5), Excluded(7)), + ], + 650: [ + (Included(7), Excluded(15)), + ], + 660: [ + (Included(0), Excluded(4)), + ], + }, + 12: {}, + 13: { + 495: [ + (Included(3), Excluded(6)), + ], + 535: [ + (Included(5), Excluded(7)), + ], + 595: [ + (Included(3), Excluded(16)), + ], + }, + 15: { + 635: [ + (Included(5), Excluded(18)), + ], + }, + 18: { + 495: [ + (Included(3), Excluded(10)), + ], + 562: [ + (Included(4), Excluded(15)), + ], + 574: [ + (Included(1), Excluded(19)), + ], + 613: [ + (Included(8), Excluded(11)), + ], + }, + 19: { + 584: [ + (Included(0), Excluded(12)), + ], + 600: [ + (Included(9), Excluded(13)), + ], + 608: [ + (Included(0), Excluded(5)), + ], + }, + }, + 479: { + 5: { + 523: [ + (Included(0), Unbounded), + ], + }, + 14: { + 484: [ + (Included(0), Excluded(8)), + ], + 589: [ + (Included(1), Excluded(7)), + ], + }, + }, + 484: { + 0: { + 594: [ + (Included(0), Excluded(12)), + ], + }, + 2: { + 505: [ + (Included(9), Excluded(14)), + ], + 535: [ + (Included(3), Unbounded), + ], + 560: [ + (Included(2), Excluded(9)), + ], + 574: [ + (Included(2), Excluded(5)), + ], + }, + 4: { + 574: [ + (Included(0), Excluded(1)), + ], + }, + 6: { + 662: [ + (Included(5), Excluded(17)), + ], + }, + 7: { + 491: [ + (Included(3), Excluded(4)), + ], + 613: [ + (Included(0), Excluded(4)), + ], + }, + 8: { + 541: [ + (Included(6), Unbounded), + ], + }, + 10: {}, + 11: { + 541: [ + (Included(6), Excluded(17)), + ], + }, + 14: { + 645: [ + (Included(0), Unbounded), + ], + }, + 16: { + 491: [ + (Included(3), Unbounded), + ], + 600: [ + (Included(8), Unbounded), + ], + 613: [ + (Included(0), Excluded(4)), + ], + }, + 17: { + 635: [ + (Included(9), Excluded(18)), + ], + }, + 18: { + 495: [ + (Included(5), Excluded(10)), + ], + 574: [ + (Included(0), Excluded(12)), + ], + 601: [ + (Included(0), Excluded(19)), + ], + }, + }, + 491: { + 0: {}, + 2: { + 595: [ + (Included(6), Unbounded), + ], + 662: [ + (Included(5), Excluded(17)), + ], + }, + 3: { + 547: [ + (Included(7), Excluded(19)), + ], + }, + 5: { + 595: [ + (Included(4), Excluded(16)), + ], + 647: [ + (Included(0), Excluded(4)), + ], + }, + 6: { + 662: [ + (Included(6), Excluded(18)), + ], + }, + 9: { + 662: [ + (Included(6), Unbounded), + ], + }, + 18: { + 569: [ + (Included(6), Excluded(13)), + ], + 594: [ + (Included(5), Excluded(6)), + ], + 595: [ + (Included(0), Excluded(17)), + ], + 635: [ + (Included(4), Unbounded), + ], + 662: [ + (Included(7), Unbounded), + ], + }, + }, + 494: { + 1: { + 547: [ + (Included(1), Excluded(19)), + ], + 562: [ + (Included(0), Unbounded), + ], + 599: [ + (Included(2), Excluded(8)), + ], + 619: [ + (Included(6), Excluded(11)), + ], + }, + 5: { + 574: [ + (Included(8), Unbounded), + ], + 601: [ + (Included(0), Excluded(19)), + ], + }, + 12: { + 495: [ + (Included(1), Unbounded), + ], + 601: [ + (Included(6), Unbounded), + ], + 645: [ + (Included(6), Excluded(7)), + ], + }, + }, + 495: { + 1: {}, + 3: { + 608: [ + (Included(6), Excluded(13)), + ], + }, + 4: {}, + 5: { + 595: [ + (Included(5), Excluded(17)), + ], + 650: [ + (Included(4), Excluded(15)), + ], + }, + 8: { + 576: [ + (Included(0), Excluded(9)), + ], + }, + 9: {}, + 11: { + 547: [ + (Included(6), Excluded(13)), + ], + 559: [ + (Included(8), Excluded(12)), + ], + 594: [ + (Included(1), Unbounded), + ], + 613: [ + (Included(8), Unbounded), + ], + 645: [ + (Included(0), Excluded(7)), + ], + }, + 12: { + 662: [ + (Included(0), Excluded(4)), + ], + }, + 16: { + 608: [ + (Included(9), Unbounded), + ], + }, + }, + 500: { + 2: { + 613: [ + (Included(8), Unbounded), + ], + }, + 5: { + 594: [ + (Included(0), Unbounded), + ], + }, + 12: {}, + 16: { + 601: [ + (Included(6), Excluded(13)), + ], + 627: [ + (Included(7), Unbounded), + ], + }, + }, + 505: { + 0: { + 535: [ + (Included(0), Excluded(14)), + ], + }, + 1: { + 666: [ + (Included(0), Unbounded), + ], + }, + 2: { + 535: [ + (Included(8), Excluded(13)), + ], + 619: [ + (Included(0), Excluded(5)), + ], + 662: [ + (Included(7), Excluded(19)), + ], + }, + 6: { + 559: [ + (Included(1), Excluded(12)), + ], + }, + 9: {}, + 10: { + 589: [ + (Included(1), Excluded(2)), + ], + 595: [ + (Included(0), Unbounded), + ], + }, + 13: { + 584: [ + (Included(1), Excluded(12)), + ], + 589: [ + (Included(0), Excluded(8)), + ], + 595: [ + (Included(0), Excluded(16)), + ], + 600: [ + (Included(0), Excluded(13)), + ], + 619: [ + (Included(4), Excluded(15)), + ], + }, + 17: { + 589: [ + (Included(7), Excluded(8)), + ], + 619: [ + (Included(6), Excluded(9)), + ], + }, + 18: { + 547: [ + (Included(6), Excluded(12)), + ], + }, + }, + 523: { + 0: { + 613: [ + (Included(0), Unbounded), + ], + }, + 1: { + 608: [ + (Included(0), Excluded(13)), + ], + 662: [ + (Included(7), Excluded(19)), + ], + }, + 6: {}, + 8: { + 594: [ + (Included(0), Excluded(12)), + ], + 600: [ + (Included(6), Excluded(10)), + ], + }, + 9: { + 562: [ + (Included(7), Unbounded), + ], + 569: [ + (Included(6), Excluded(17)), + ], + }, + 10: {}, + 11: { + 535: [ + (Included(8), Unbounded), + ], + 576: [ + (Included(8), Excluded(16)), + ], + 619: [ + (Included(4), Excluded(5)), + ], + }, + 13: { + 593: [ + (Included(6), Excluded(14)), + ], + }, + 14: { + 645: [ + (Included(6), Unbounded), + ], + }, + 18: { + 619: [ + (Included(0), Excluded(5)), + ], + 625: [ + (Included(4), Unbounded), + ], + 627: [ + (Included(4), Excluded(16)), + ], + }, + 19: { + 535: [ + (Included(0), Excluded(14)), + ], + 650: [ + (Included(0), Unbounded), + ], + }, + }, + 535: { + 1: { + 599: [ + (Included(6), Excluded(11)), + ], + }, + 5: { + 547: [ + (Included(2), Excluded(14)), + ], + 559: [ + (Included(0), Excluded(10)), + ], + }, + 6: { + 541: [ + (Included(0), Unbounded), + ], + }, + 8: {}, + 12: {}, + 13: { + 635: [ + (Included(5), Excluded(10)), + ], + 662: [ + (Included(7), Excluded(9)), + ], + }, + 15: { + 608: [ + (Included(0), Excluded(7)), + ], + }, + 16: { + 625: [ + (Included(4), Excluded(9)), + ], + 627: [ + (Included(8), Unbounded), + ], + }, + }, + 541: { + 1: { + 601: [ + (Included(1), Excluded(15)), + ], + }, + 6: {}, + 7: { + 547: [ + (Included(4), Excluded(19)), + ], + 593: [ + (Included(4), Excluded(9)), + ], + 650: [ + (Included(4), Unbounded), + ], + }, + 8: { + 625: [ + (Included(4), Excluded(7)), + ], + }, + 13: { + 574: [ + (Included(2), Excluded(15)), + ], + 589: [ + (Included(1), Unbounded), + ], + 635: [ + (Included(4), Unbounded), + ], + }, + 14: { + 547: [ + (Included(6), Unbounded), + ], + 599: [ + (Included(2), Excluded(13)), + ], + 627: [ + (Included(7), Excluded(19)), + ], + }, + 15: { + 547: [ + (Included(0), Excluded(14)), + ], + 576: [ + (Included(0), Unbounded), + ], + 662: [ + (Included(0), Excluded(4)), + ], + }, + 16: { + 645: [ + (Included(2), Excluded(7)), + ], + }, + 17: { + 650: [ + (Included(4), Unbounded), + ], + }, + }, + 547: { + 0: { + 650: [ + (Included(2), Excluded(15)), + ], + }, + 2: { + 635: [ + (Included(0), Excluded(15)), + ], + }, + 3: {}, + 4: { + 635: [ + (Included(5), Excluded(15)), + ], + 645: [ + (Included(6), Excluded(17)), + ], + }, + 5: {}, + 6: {}, + 11: { + 574: [ + (Included(1), Excluded(5)), + ], + 584: [ + (Included(3), Excluded(4)), + ], + 662: [ + (Included(0), Excluded(19)), + ], + }, + 12: {}, + 13: { + 589: [ + (Included(8), Excluded(11)), + ], + 601: [ + (Included(4), Excluded(16)), + ], + }, + 14: { + 601: [ + (Included(5), Excluded(17)), + ], + }, + 16: {}, + 17: { + 574: [ + (Included(9), Excluded(15)), + ], + 650: [ + (Included(7), Excluded(15)), + ], + 662: [ + (Included(3), Excluded(19)), + ], + }, + 18: { + 569: [ + (Included(0), Unbounded), + ], + 662: [ + (Included(0), Excluded(8)), + ], + }, + 19: {}, + }, + 559: { + 8: { + 650: [ + (Included(4), Unbounded), + ], + }, + 9: { + 560: [ + (Included(4), Excluded(9)), + ], + }, + 10: {}, + 11: { + 574: [ + (Included(1), Unbounded), + ], + }, + 12: {}, + 18: { + 601: [ + (Included(1), Excluded(15)), + ], + }, + }, + 560: { + 0: { + 589: [ + (Included(1), Excluded(11)), + ], + 613: [ + (Included(0), Excluded(9)), + ], + }, + 2: { + 593: [ + (Included(0), Excluded(13)), + ], + }, + 4: {}, + 6: { + 600: [ + (Included(0), Excluded(8)), + ], + }, + 8: { + 600: [ + (Included(8), Excluded(13)), + ], + 635: [ + (Included(4), Unbounded), + ], + }, + 16: {}, + }, + 562: { + 0: { + 576: [ + (Included(6), Excluded(17)), + ], + 593: [ + (Included(6), Unbounded), + ], + }, + 4: { + 608: [ + (Included(0), Excluded(5)), + ], + }, + 8: { + 606: [ + (Included(0), Excluded(17)), + ], + 645: [ + (Included(0), Excluded(3)), + ], + }, + 10: {}, + 11: { + 574: [ + (Included(8), Unbounded), + ], + 647: [ + (Included(0), Unbounded), + ], + }, + 12: {}, + 14: { + 569: [ + (Included(0), Excluded(10)), + ], + 635: [ + (Included(0), Unbounded), + ], + }, + 17: {}, + 18: { + 635: [ + (Included(5), Excluded(15)), + ], + 662: [ + (Included(8), Excluded(9)), + ], + }, + }, + 569: { + 3: { + 574: [ + (Included(0), Excluded(10)), + ], + }, + 6: { + 595: [ + (Included(0), Excluded(17)), + ], + 601: [ + (Included(8), Excluded(13)), + ], + 635: [ + (Included(9), Excluded(16)), + ], + }, + 8: { + 635: [ + (Included(4), Excluded(16)), + ], + 647: [ + (Included(0), Unbounded), + ], + }, + 9: { + 584: [ + (Included(1), Unbounded), + ], + }, + 12: { + 627: [ + (Included(0), Excluded(13)), + ], + }, + 13: { + 589: [ + (Included(0), Unbounded), + ], + }, + 16: { + 599: [ + (Included(2), Excluded(8)), + ], + 645: [ + (Included(0), Excluded(17)), + ], + }, + 18: { + 574: [ + (Included(4), Excluded(15)), + ], + 645: [ + (Included(6), Excluded(17)), + ], + 647: [ + (Included(0), Unbounded), + ], + }, + 19: { + 574: [ + (Included(0), Unbounded), + ], + 589: [ + (Included(8), Excluded(11)), + ], + }, + }, + 574: { + 0: { + 593: [ + (Included(0), Excluded(5)), + ], + }, + 1: { + 600: [ + (Included(9), Unbounded), + ], + }, + 2: { + 589: [ + (Included(6), Unbounded), + ], + 650: [ + (Included(4), Excluded(15)), + ], + }, + 4: {}, + 8: { + 635: [ + (Included(4), Excluded(18)), + ], + }, + 9: {}, + 10: {}, + 11: { + 601: [ + (Included(8), Excluded(16)), + ], + 625: [ + (Included(4), Excluded(5)), + ], + }, + 14: { + 576: [ + (Included(5), Excluded(17)), + ], + 593: [ + (Included(8), Unbounded), + ], + 601: [ + (Included(4), Unbounded), + ], + }, + 18: { + 650: [ + (Included(0), Excluded(8)), + ], + }, + 19: {}, + }, + 576: { + 4: { + 645: [ + (Included(5), Unbounded), + ], + }, + 7: {}, + 8: {}, + 10: { + 601: [ + (Included(0), Excluded(15)), + ], + }, + 15: { + 593: [ + (Included(4), Excluded(12)), + ], + 594: [ + (Included(0), Excluded(12)), + ], + }, + 16: { + 599: [ + (Included(4), Unbounded), + ], + }, + 17: { + 625: [ + (Included(4), Excluded(7)), + ], + }, + 19: {}, + }, + 584: { + 1: { + 599: [ + (Included(0), Excluded(2)), + ], + 600: [ + (Included(7), Excluded(13)), + ], + }, + 3: {}, + 11: {}, + 15: {}, + }, + 589: { + 0: { + 595: [ + (Included(4), Unbounded), + ], + }, + 1: {}, + 6: { + 619: [ + (Included(8), Excluded(9)), + ], + 660: [ + (Included(3), Excluded(10)), + ], + }, + 7: { + 635: [ + (Included(0), Excluded(2)), + ], + }, + 8: { + 600: [ + (Included(8), Unbounded), + ], + }, + 10: {}, + 15: { + 599: [ + (Included(4), Unbounded), + ], + 645: [ + (Included(2), Excluded(6)), + ], + }, + }, + 593: { + 0: { + 595: [ + (Included(0), Excluded(14)), + ], + 608: [ + (Included(2), Unbounded), + ], + }, + 4: { + 650: [ + (Included(4), Unbounded), + ], + }, + 6: { + 625: [ + (Included(0), Unbounded), + ], + }, + 8: {}, + 9: {}, + 11: {}, + 12: {}, + 13: {}, + 15: { + 635: [ + (Included(9), Excluded(15)), + ], + }, + }, + 594: { + 0: { + 613: [ + (Included(8), Unbounded), + ], + 619: [ + (Included(2), Unbounded), + ], + 662: [ + (Included(6), Excluded(19)), + ], + }, + 1: { + 625: [ + (Included(0), Unbounded), + ], + 647: [ + (Included(0), Excluded(4)), + ], + }, + 4: {}, + 5: {}, + 11: { + 619: [ + (Included(2), Unbounded), + ], + 662: [ + (Included(6), Excluded(16)), + ], + }, + 12: {}, + }, + 595: { + 1: {}, + 2: {}, + 10: {}, + 13: { + 599: [ + (Included(7), Excluded(11)), + ], + }, + 14: { + 619: [ + (Included(2), Excluded(15)), + ], + }, + 15: {}, + 16: {}, + 19: {}, + }, + 599: { + 0: { + 635: [ + (Included(1), Excluded(10)), + ], + }, + 1: { + 635: [ + (Included(0), Excluded(10)), + ], + }, + 2: {}, + 6: { + 625: [ + (Included(6), Excluded(9)), + ], + }, + 7: {}, + 10: { + 662: [ + (Included(3), Excluded(7)), + ], + }, + 12: {}, + 13: { + 600: [ + (Included(6), Unbounded), + ], + }, + 14: { + 601: [ + (Included(5), Excluded(18)), + ], + }, + 18: { + 627: [ + (Included(5), Excluded(18)), + ], + }, + }, + 600: { + 5: { + 625: [ + (Included(8), Unbounded), + ], + }, + 6: {}, + 7: {}, + 8: {}, + 9: { + 660: [ + (Included(3), Excluded(4)), + ], + }, + 12: {}, + 18: { + 601: [ + (Included(5), Excluded(9)), + ], + 635: [ + (Included(1), Excluded(6)), + ], + }, + }, + 601: { + 0: { + 608: [ + (Included(0), Excluded(10)), + ], + }, + 1: { + 625: [ + (Included(6), Excluded(7)), + ], + }, + 4: {}, + 5: { + 650: [ + (Included(4), Unbounded), + ], + }, + 6: { + 650: [ + (Included(2), Unbounded), + ], + }, + 8: {}, + 12: {}, + 14: {}, + 15: { + 608: [ + (Included(9), Excluded(13)), + ], + }, + 16: { + 650: [ + (Included(0), Excluded(15)), + ], + }, + 17: {}, + 18: {}, + 19: {}, + }, + 606: { + 3: { + 619: [ + (Included(8), Excluded(15)), + ], + }, + 6: {}, + 7: {}, + 16: {}, + 19: { + 662: [ + (Included(6), Excluded(16)), + ], + }, + }, + 608: { + 4: {}, + 6: { + 635: [ + (Included(5), Excluded(18)), + ], + }, + 9: {}, + 12: { + 662: [ + (Included(7), Unbounded), + ], + }, + 17: {}, + }, + 613: { + 3: {}, + 8: { + 627: [ + (Included(7), Excluded(15)), + ], + 662: [ + (Included(0), Excluded(4)), + ], + }, + 10: { + 635: [ + (Included(1), Excluded(16)), + ], + }, + 16: { + 619: [ + (Included(4), Excluded(9)), + ], + 635: [ + (Included(4), Excluded(18)), + ], + }, + }, + 619: { + 1: {}, + 2: { + 625: [ + (Included(6), Unbounded), + ], + }, + 4: { + 650: [ + (Included(0), Unbounded), + ], + }, + 6: {}, + 8: {}, + 10: {}, + 14: { + 645: [ + (Included(2), Unbounded), + ], + 662: [ + (Included(0), Excluded(8)), + ], + }, + 15: {}, + }, + 625: { + 1: { + 627: [ + (Included(2), Excluded(19)), + ], + }, + 4: {}, + 6: { + 647: [ + (Included(0), Unbounded), + ], + }, + 8: {}, + 10: {}, + }, + 627: { + 1: {}, + 3: {}, + 7: {}, + 11: {}, + 12: {}, + 14: {}, + 15: { + 650: [ + (Included(2), Excluded(15)), + ], + }, + 17: { + 662: [ + (Included(8), Excluded(19)), + ], + }, + 18: {}, + 19: { + 635: [ + (Included(4), Unbounded), + ], + }, + }, + 635: { + 0: {}, + 1: {}, + 4: { + 660: [ + (Included(0), Unbounded), + ], + }, + 5: {}, + 9: {}, + 14: { + 662: [ + (Included(5), Excluded(19)), + ], + }, + 15: {}, + 17: {}, + 18: {}, + }, + 645: { + 0: {}, + 2: { + 660: [ + (Included(3), Unbounded), + ], + }, + 5: {}, + 6: {}, + 16: {}, + 17: {}, + }, + 647: { + 3: {}, + 11: {}, + }, + 650: { + 0: {}, + 2: {}, + 7: {}, + 14: {}, + 16: { + 660: [ + (Included(0), Unbounded), + ], + }, + }, + 660: { + 1: {}, + 3: {}, + 9: { + 662: [ + (Included(3), Excluded(19)), + ], + }, + 15: {}, + }, + 662: { + 2: {}, + 3: {}, + 6: {}, + 7: {}, + 8: {}, + 15: {}, + 16: {}, + 17: {}, + 18: {}, + 19: {}, + }, +} diff --git a/test-examples/large_case_u16_NumberVersion.ron b/test-examples/large_case_u16_discrete_NumberVersion.ron similarity index 100% rename from test-examples/large_case_u16_NumberVersion.ron rename to test-examples/large_case_u16_discrete_NumberVersion.ron diff --git a/tests/examples.rs b/tests/examples.rs index 9040bc23..6bf02fc6 100644 --- a/tests/examples.rs +++ b/tests/examples.rs @@ -1,12 +1,12 @@ // SPDX-License-Identifier: MPL-2.0 -use pubgrub::range::Range; +use pubgrub::bounded_range::BoundedRange; use pubgrub::solver::{resolve, OfflineDependencyProvider}; use pubgrub::type_aliases::Map; use pubgrub::version::{NumberVersion, SemanticVersion}; -type NumVS = Range; -type SemVS = Range; +type NumVS = BoundedRange; +type SemVS = BoundedRange; use log::LevelFilter; use std::io::Write; @@ -26,13 +26,13 @@ fn no_conflict() { let mut dependency_provider = OfflineDependencyProvider::<&str, SemVS>::new(); #[rustfmt::skip] dependency_provider.add_dependencies( - "root", (1, 0, 0), - [("foo", Range::between((1, 0, 0), (2, 0, 0)))], + "root", (1, 0, 0), + [("foo", BoundedRange::between((1, 0, 0), (2, 0, 0)))], ); #[rustfmt::skip] dependency_provider.add_dependencies( - "foo", (1, 0, 0), - [("bar", Range::between((1, 0, 0), (2, 0, 0)))], + "foo", (1, 0, 0), + [("bar", BoundedRange::between((1, 0, 0), (2, 0, 0)))], ); dependency_provider.add_dependencies("bar", (1, 0, 0), []); dependency_provider.add_dependencies("bar", (2, 0, 0), []); @@ -59,14 +59,14 @@ fn avoiding_conflict_during_decision_making() { dependency_provider.add_dependencies( "root", (1, 0, 0), [ - ("foo", Range::between((1, 0, 0), (2, 0, 0))), - ("bar", Range::between((1, 0, 0), (2, 0, 0))), + ("foo", BoundedRange::between((1, 0, 0), (2, 0, 0))), + ("bar", BoundedRange::between((1, 0, 0), (2, 0, 0))), ], ); #[rustfmt::skip] dependency_provider.add_dependencies( - "foo", (1, 1, 0), - [("bar", Range::between((2, 0, 0), (3, 0, 0)))], + "foo", (1, 1, 0), + [("bar", BoundedRange::between((2, 0, 0), (3, 0, 0)))], ); dependency_provider.add_dependencies("foo", (1, 0, 0), []); dependency_provider.add_dependencies("bar", (1, 0, 0), []); @@ -93,19 +93,19 @@ fn conflict_resolution() { let mut dependency_provider = OfflineDependencyProvider::<&str, SemVS>::new(); #[rustfmt::skip] dependency_provider.add_dependencies( - "root", (1, 0, 0), - [("foo", Range::higher_than((1, 0, 0)))], + "root", (1, 0, 0), + [("foo", BoundedRange::higher_than((1, 0, 0)))], ); #[rustfmt::skip] dependency_provider.add_dependencies( - "foo", (2, 0, 0), - [("bar", Range::between((1, 0, 0), (2, 0, 0)))], + "foo", (2, 0, 0), + [("bar", BoundedRange::between((1, 0, 0), (2, 0, 0)))], ); dependency_provider.add_dependencies("foo", (1, 0, 0), []); #[rustfmt::skip] dependency_provider.add_dependencies( - "bar", (1, 0, 0), - [("foo", Range::between((1, 0, 0), (2, 0, 0)))], + "bar", (1, 0, 0), + [("foo", BoundedRange::between((1, 0, 0), (2, 0, 0)))], ); // Run the algorithm. @@ -130,8 +130,8 @@ fn conflict_with_partial_satisfier() { dependency_provider.add_dependencies( "root", (1, 0, 0), [ - ("foo", Range::between((1, 0, 0), (2, 0, 0))), - ("target", Range::between((2, 0, 0), (3, 0, 0))), + ("foo", BoundedRange::between((1, 0, 0), (2, 0, 0))), + ("target", BoundedRange::between((2, 0, 0), (3, 0, 0))), ], ); #[rustfmt::skip] @@ -139,29 +139,29 @@ fn conflict_with_partial_satisfier() { dependency_provider.add_dependencies( "foo", (1, 1, 0), [ - ("left", Range::between((1, 0, 0), (2, 0, 0))), - ("right", Range::between((1, 0, 0), (2, 0, 0))), + ("left", BoundedRange::between((1, 0, 0), (2, 0, 0))), + ("right", BoundedRange::between((1, 0, 0), (2, 0, 0))), ], ); dependency_provider.add_dependencies("foo", (1, 0, 0), []); #[rustfmt::skip] // left 1.0.0 depends on shared >=1.0.0 dependency_provider.add_dependencies( - "left", (1, 0, 0), - [("shared", Range::higher_than((1, 0, 0)))], + "left", (1, 0, 0), + [("shared", BoundedRange::higher_than((1, 0, 0)))], ); #[rustfmt::skip] // right 1.0.0 depends on shared <2.0.0 dependency_provider.add_dependencies( - "right", (1, 0, 0), - [("shared", Range::strictly_lower_than((2, 0, 0)))], + "right", (1, 0, 0), + [("shared", BoundedRange::strictly_lower_than((2, 0, 0)))], ); dependency_provider.add_dependencies("shared", (2, 0, 0), []); #[rustfmt::skip] // shared 1.0.0 depends on target ^1.0.0 dependency_provider.add_dependencies( - "shared", (1, 0, 0), - [("target", Range::between((1, 0, 0), (2, 0, 0)))], + "shared", (1, 0, 0), + [("target", BoundedRange::between((1, 0, 0), (2, 0, 0)))], ); dependency_provider.add_dependencies("target", (2, 0, 0), []); dependency_provider.add_dependencies("target", (1, 0, 0), []); @@ -191,11 +191,15 @@ fn conflict_with_partial_satisfier() { fn double_choices() { init_log(); let mut dependency_provider = OfflineDependencyProvider::<&str, NumVS>::new(); - dependency_provider.add_dependencies("a", 0, [("b", Range::any()), ("c", Range::any())]); - dependency_provider.add_dependencies("b", 0, [("d", Range::exact(0))]); - dependency_provider.add_dependencies("b", 1, [("d", Range::exact(1))]); + dependency_provider.add_dependencies( + "a", + 0, + [("b", BoundedRange::any()), ("c", BoundedRange::any())], + ); + dependency_provider.add_dependencies("b", 0, [("d", BoundedRange::exact(0))]); + dependency_provider.add_dependencies("b", 1, [("d", BoundedRange::exact(1))]); dependency_provider.add_dependencies("c", 0, []); - dependency_provider.add_dependencies("c", 1, [("d", Range::exact(2))]); + dependency_provider.add_dependencies("c", 1, [("d", BoundedRange::exact(2))]); dependency_provider.add_dependencies("d", 0, []); // Solution. diff --git a/tests/proptest.rs b/tests/proptest.rs index fa775720..c94f9dc3 100644 --- a/tests/proptest.rs +++ b/tests/proptest.rs @@ -4,7 +4,6 @@ use std::{collections::BTreeSet as Set, error::Error}; use pubgrub::error::PubGrubError; use pubgrub::package::Package; -use pubgrub::range::Range; use pubgrub::report::{DefaultStringReporter, Reporter}; use pubgrub::solver::{ choose_package_with_fewest_versions, resolve, Dependencies, DependencyProvider, @@ -90,14 +89,16 @@ impl> DependencyProvid } } -type NumVS = Range; -type SemVS = Range; +// type NumVS = pubgrub::discrete_range::DiscreteRange; +// type SemVS = pubgrub::discrete_range::DiscreteRange; +type NumVS = pubgrub::bounded_range::BoundedRange; +type SemVS = pubgrub::bounded_range::BoundedRange; #[test] #[should_panic] fn should_cancel_can_panic() { let mut dependency_provider = OfflineDependencyProvider::<_, NumVS>::new(); - dependency_provider.add_dependencies(0, 0, [(666, Range::any())]); + dependency_provider.add_dependencies(0, 0, [(666, NumVS::any())]); // Run the algorithm. let _ = resolve( @@ -197,15 +198,15 @@ pub fn registry_strategy( deps.push(( dep_name, if c == 0 && d == s_last_index { - Range::any() + NumVS::any() } else if c == 0 { - Range::strictly_lower_than(s[d].0 + 1) + NumVS::strictly_lower_than(s[d].0 + 1) } else if d == s_last_index { - Range::higher_than(s[c].0) + NumVS::higher_than(s[c].0) } else if c == d { - Range::exact(s[c].0) + NumVS::exact(s[c].0) } else { - Range::between(s[c].0, s[d].0 + 1) + NumVS::between(s[c].0, s[d].0 + 1) }, )) } @@ -227,7 +228,7 @@ pub fn registry_strategy( dependency_provider.add_dependencies( name, ver, - deps.unwrap_or_else(|| vec![(bad_name.clone(), Range::any())]), + deps.unwrap_or_else(|| vec![(bad_name.clone(), NumVS::any())]), ); } @@ -488,8 +489,21 @@ fn large_case() { let name = case.file_name().unwrap().to_string_lossy(); eprintln!("{}", name); let data = std::fs::read_to_string(&case).unwrap(); - if name.ends_with("u16_NumberVersion.ron") { - let dependency_provider: OfflineDependencyProvider = + if name.ends_with("u16_discrete_NumberVersion.ron") { + let dependency_provider: OfflineDependencyProvider> = + ron::de::from_str(&data).unwrap(); + let mut sat = SatResolve::new(&dependency_provider); + for p in dependency_provider.packages() { + for n in dependency_provider.versions(p).unwrap() { + if let Ok(s) = resolve(&dependency_provider, p.clone(), n.clone()) { + assert!(sat.sat_is_valid_solution(&s)); + } else { + assert!(!sat.sat_resolve(p, &n)); + } + } + } + } else if name.ends_with("u16_bounded_NumberVersion.ron") { + let dependency_provider: OfflineDependencyProvider> = ron::de::from_str(&data).unwrap(); let mut sat = SatResolve::new(&dependency_provider); for p in dependency_provider.packages() { diff --git a/tests/tests.rs b/tests/tests.rs index 77e4385b..0cd5e975 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -1,11 +1,11 @@ // SPDX-License-Identifier: MPL-2.0 +use pubgrub::bounded_range::BoundedRange; use pubgrub::error::PubGrubError; -use pubgrub::range::Range; use pubgrub::solver::{resolve, OfflineDependencyProvider}; use pubgrub::version::NumberVersion; -type NumVS = Range; +type NumVS = BoundedRange; #[test] fn same_result_on_repeated_runs() { @@ -14,9 +14,13 @@ fn same_result_on_repeated_runs() { dependency_provider.add_dependencies("c", 0, []); dependency_provider.add_dependencies("c", 2, []); dependency_provider.add_dependencies("b", 0, []); - dependency_provider.add_dependencies("b", 1, [("c", Range::between(0, 1))]); + dependency_provider.add_dependencies("b", 1, [("c", BoundedRange::between(0, 1))]); - dependency_provider.add_dependencies("a", 0, [("b", Range::any()), ("c", Range::any())]); + dependency_provider.add_dependencies( + "a", + 0, + [("b", BoundedRange::any()), ("c", BoundedRange::any())], + ); let name = "a"; let ver = NumberVersion(0); @@ -32,13 +36,13 @@ fn same_result_on_repeated_runs() { #[test] fn should_always_find_a_satisfier() { let mut dependency_provider = OfflineDependencyProvider::<_, NumVS>::new(); - dependency_provider.add_dependencies("a", 0, [("b", Range::none())]); + dependency_provider.add_dependencies("a", 0, [("b", BoundedRange::none())]); assert!(matches!( resolve(&dependency_provider, "a", 0), Err(PubGrubError::DependencyOnTheEmptySet { .. }) )); - dependency_provider.add_dependencies("c", 0, [("a", Range::any())]); + dependency_provider.add_dependencies("c", 0, [("a", BoundedRange::any())]); assert!(matches!( resolve(&dependency_provider, "c", 0), Err(PubGrubError::DependencyOnTheEmptySet { .. }) @@ -48,7 +52,7 @@ fn should_always_find_a_satisfier() { #[test] fn cannot_depend_on_self() { let mut dependency_provider = OfflineDependencyProvider::<_, NumVS>::new(); - dependency_provider.add_dependencies("a", 0, [("a", Range::any())]); + dependency_provider.add_dependencies("a", 0, [("a", BoundedRange::any())]); assert!(matches!( resolve(&dependency_provider, "a", 0), Err(PubGrubError::SelfDependency { .. })