pub struct Interval<T: Ord> { /* private fields */ }Expand description
Deterministic half-open interval over an ordered endpoint domain.
Interval<T> represents [start, end): start is included and end is
excluded. The interval is valid only when start < end.
Intervals derive Ord, so ordered collections such as BTreeSet keep
them in lexicographic (start, end) order. That is the deterministic order
later temporal coalescing code should use.
§Examples
use std::collections::BTreeSet;
use relmath::temporal::Interval;
let windows = BTreeSet::from([
Interval::new(3, 5).expect("expected valid interval"),
Interval::new(1, 4).expect("expected valid interval"),
Interval::new(1, 3).expect("expected valid interval"),
]);
assert_eq!(
windows.into_iter().collect::<Vec<_>>(),
vec![
Interval::new(1, 3).expect("expected valid interval"),
Interval::new(1, 4).expect("expected valid interval"),
Interval::new(3, 5).expect("expected valid interval"),
]
);Implementations§
Source§impl<T: Ord> Interval<T>
impl<T: Ord> Interval<T>
Sourcepub fn new(start: T, end: T) -> Result<Self, IntervalError<T>>
pub fn new(start: T, end: T) -> Result<Self, IntervalError<T>>
Creates one valid half-open interval [start, end).
Returns an explicit error when start >= end.
§Examples
use relmath::temporal::{Interval, IntervalError};
let valid = Interval::new(2, 5).expect("expected valid interval");
assert_eq!(valid.start(), &2);
assert_eq!(valid.end(), &5);
assert_eq!(
Interval::new(5, 2),
Err(IntervalError::InvalidBounds { start: 5, end: 2 })
);Examples found in repository?
5fn main() {
6 let draft_review = Interval::new(9, 12).expect("expected valid interval");
7 let approval = Interval::new(12, 15).expect("expected valid interval");
8 let audit = Interval::new(11, 13).expect("expected valid interval");
9
10 let full_shift = draft_review
11 .coalesce(&approval)
12 .expect("adjacent intervals should coalesce");
13 let audit_window = full_shift
14 .restrict_to(&audit)
15 .expect("expected non-empty overlap");
16
17 assert!(draft_review.contains(&9));
18 assert!(!draft_review.contains(&12));
19 assert!(!draft_review.overlaps(&approval));
20 assert!(draft_review.is_adjacent_to(&approval));
21 assert_eq!(
22 audit_window,
23 Interval::new(11, 13).expect("expected valid interval")
24 );
25
26 println!(
27 "full shift: {:?}, audit overlap: {:?}",
28 full_shift, audit_window
29 );
30}More examples
22fn main() {
23 let evidence = ProvenanceRelation::from_facts([
24 (("alice", "review"), "directory"),
25 (("bob", "approve"), "policy"),
26 ]);
27 let permissions = AnnotatedRelation::from_facts([
28 (("alice", "review"), BooleanSemiring::TRUE),
29 (("bob", "approve"), BooleanSemiring::TRUE),
30 ]);
31 let schedule = ValidTimeRelation::from_facts([
32 (
33 ("alice", "review"),
34 Interval::new(1, 3).expect("expected valid interval"),
35 ),
36 (
37 ("bob", "approve"),
38 Interval::new(2, 4).expect("expected valid interval"),
39 ),
40 ]);
41
42 let exact_evidence = exact_pairs(&evidence);
43 let exact_permissions = exact_pairs(&permissions);
44 let exact_schedule = exact_pairs(&schedule);
45
46 assert_eq!(
47 exact_evidence.to_vec(),
48 vec![("alice", "review"), ("bob", "approve")]
49 );
50 assert_eq!(exact_permissions.to_vec(), exact_evidence.to_vec());
51 assert_eq!(exact_schedule.to_vec(), exact_evidence.to_vec());
52
53 assert_eq!(
54 evidence
55 .why(&("alice", "review"))
56 .expect("expected witness")
57 .to_vec(),
58 vec!["directory"]
59 );
60 assert_eq!(
61 permissions.annotation_of(&("alice", "review")),
62 Some(&BooleanSemiring::TRUE)
63 );
64 assert_eq!(
65 schedule
66 .valid_time_of(&("alice", "review"))
67 .expect("expected interval support")
68 .to_vec(),
69 vec![Interval::new(1, 3).expect("expected valid interval")]
70 );
71
72 println!(
73 "witness={:?}, annotation={:?}, interval_support={:?}, exact_support={:?}",
74 evidence
75 .why(&("alice", "review"))
76 .expect("expected witness")
77 .to_vec(),
78 permissions.annotation_of(&("alice", "review")),
79 schedule
80 .valid_time_of(&("alice", "review"))
81 .expect("expected interval support")
82 .to_vec(),
83 exact_schedule.to_vec()
84 );
85}8fn main() {
9 let assignments = ValidTimeRelation::from_facts([
10 (
11 ("alice", "review"),
12 Interval::new(1, 3).expect("expected valid interval"),
13 ),
14 (
15 ("alice", "review"),
16 Interval::new(3, 5).expect("expected valid interval"),
17 ),
18 (
19 ("bob", "approve"),
20 Interval::new(2, 4).expect("expected valid interval"),
21 ),
22 ]);
23
24 let alice = UnaryRelation::singleton("alice");
25 let fact_support = assignments.support();
26 let exact_support = assignments.to_binary_relation();
27 let audit_window = Interval::new(2, 4).expect("expected valid interval");
28 let active_at_three = assignments.snapshot_at(&3);
29 let audit_assignments = assignments.restrict_to(&audit_window);
30
31 assert_eq!(
32 assignments
33 .valid_time_of(&("alice", "review"))
34 .expect("expected support")
35 .to_vec(),
36 vec![Interval::new(1, 5).expect("expected valid interval")]
37 );
38 assert!(assignments.is_active_at(&("alice", "review"), &4));
39 assert!(!assignments.is_active_at(&("alice", "review"), &5));
40 assert_eq!(
41 active_at_three.to_vec(),
42 vec![("alice", "review"), ("bob", "approve")]
43 );
44 assert_eq!(
45 fact_support.to_vec(),
46 vec![("alice", "review"), ("bob", "approve")]
47 );
48 assert_eq!(
49 audit_assignments
50 .valid_time_of(&("alice", "review"))
51 .expect("expected support")
52 .to_vec(),
53 vec![Interval::new(2, 4).expect("expected valid interval")]
54 );
55 assert_eq!(
56 audit_assignments.to_binary_relation().to_vec(),
57 vec![("alice", "review"), ("bob", "approve")]
58 );
59 assert_eq!(exact_support.image(&alice).to_vec(), vec!["review"]);
60
61 println!(
62 "fact support: {:?}; active at t=3: {:?}; audit restriction: {:?}",
63 fact_support.to_vec(),
64 active_at_three.to_vec(),
65 audit_assignments
66 .valid_time_of(&("alice", "review"))
67 .expect("expected support")
68 .to_vec()
69 );
70}Sourcepub fn contains(&self, point: &T) -> bool
pub fn contains(&self, point: &T) -> bool
Returns true when point lies inside [start, end).
§Examples
use relmath::temporal::Interval;
let window = Interval::new(10, 12).expect("expected valid interval");
assert!(window.contains(&10));
assert!(window.contains(&11));
assert!(!window.contains(&12));Examples found in repository?
5fn main() {
6 let draft_review = Interval::new(9, 12).expect("expected valid interval");
7 let approval = Interval::new(12, 15).expect("expected valid interval");
8 let audit = Interval::new(11, 13).expect("expected valid interval");
9
10 let full_shift = draft_review
11 .coalesce(&approval)
12 .expect("adjacent intervals should coalesce");
13 let audit_window = full_shift
14 .restrict_to(&audit)
15 .expect("expected non-empty overlap");
16
17 assert!(draft_review.contains(&9));
18 assert!(!draft_review.contains(&12));
19 assert!(!draft_review.overlaps(&approval));
20 assert!(draft_review.is_adjacent_to(&approval));
21 assert_eq!(
22 audit_window,
23 Interval::new(11, 13).expect("expected valid interval")
24 );
25
26 println!(
27 "full shift: {:?}, audit overlap: {:?}",
28 full_shift, audit_window
29 );
30}Sourcepub fn overlaps(&self, other: &Self) -> bool
pub fn overlaps(&self, other: &Self) -> bool
Returns true when the intervals overlap with non-empty intersection.
Directly adjacent intervals do not overlap under half-open semantics.
§Examples
use relmath::temporal::Interval;
let left = Interval::new(1, 3).expect("expected valid interval");
let overlap = Interval::new(2, 4).expect("expected valid interval");
let adjacent = Interval::new(3, 5).expect("expected valid interval");
assert!(left.overlaps(&overlap));
assert!(!left.overlaps(&adjacent));Examples found in repository?
5fn main() {
6 let draft_review = Interval::new(9, 12).expect("expected valid interval");
7 let approval = Interval::new(12, 15).expect("expected valid interval");
8 let audit = Interval::new(11, 13).expect("expected valid interval");
9
10 let full_shift = draft_review
11 .coalesce(&approval)
12 .expect("adjacent intervals should coalesce");
13 let audit_window = full_shift
14 .restrict_to(&audit)
15 .expect("expected non-empty overlap");
16
17 assert!(draft_review.contains(&9));
18 assert!(!draft_review.contains(&12));
19 assert!(!draft_review.overlaps(&approval));
20 assert!(draft_review.is_adjacent_to(&approval));
21 assert_eq!(
22 audit_window,
23 Interval::new(11, 13).expect("expected valid interval")
24 );
25
26 println!(
27 "full shift: {:?}, audit overlap: {:?}",
28 full_shift, audit_window
29 );
30}Sourcepub fn is_adjacent_to(&self, other: &Self) -> bool
pub fn is_adjacent_to(&self, other: &Self) -> bool
Returns true when the intervals touch at exactly one boundary.
Adjacent intervals are not overlapping, but later valid-time layers may still coalesce them into one canonical support fragment.
Examples found in repository?
5fn main() {
6 let draft_review = Interval::new(9, 12).expect("expected valid interval");
7 let approval = Interval::new(12, 15).expect("expected valid interval");
8 let audit = Interval::new(11, 13).expect("expected valid interval");
9
10 let full_shift = draft_review
11 .coalesce(&approval)
12 .expect("adjacent intervals should coalesce");
13 let audit_window = full_shift
14 .restrict_to(&audit)
15 .expect("expected non-empty overlap");
16
17 assert!(draft_review.contains(&9));
18 assert!(!draft_review.contains(&12));
19 assert!(!draft_review.overlaps(&approval));
20 assert!(draft_review.is_adjacent_to(&approval));
21 assert_eq!(
22 audit_window,
23 Interval::new(11, 13).expect("expected valid interval")
24 );
25
26 println!(
27 "full shift: {:?}, audit overlap: {:?}",
28 full_shift, audit_window
29 );
30}Sourcepub fn can_coalesce_with(&self, other: &Self) -> bool
pub fn can_coalesce_with(&self, other: &Self) -> bool
Returns true when the intervals can be coalesced.
This is true for overlapping or directly adjacent intervals.
Source§impl<T: Ord + Clone> Interval<T>
impl<T: Ord + Clone> Interval<T>
Sourcepub fn intersection(&self, other: &Self) -> Option<Self>
pub fn intersection(&self, other: &Self) -> Option<Self>
Returns the non-empty intersection of two intervals.
When the intervals are disjoint or only touch at one boundary, this
returns None.
§Examples
use relmath::temporal::Interval;
let left = Interval::new(1, 4).expect("expected valid interval");
let right = Interval::new(3, 6).expect("expected valid interval");
assert_eq!(
left.intersection(&right),
Some(Interval::new(3, 4).expect("expected valid interval"))
);Sourcepub fn restrict_to(&self, constraint: &Self) -> Option<Self>
pub fn restrict_to(&self, constraint: &Self) -> Option<Self>
Restricts this interval to the overlap with constraint.
This is an interval-level helper for later temporal restrict_to
behavior on valid-time relations.
Examples found in repository?
5fn main() {
6 let draft_review = Interval::new(9, 12).expect("expected valid interval");
7 let approval = Interval::new(12, 15).expect("expected valid interval");
8 let audit = Interval::new(11, 13).expect("expected valid interval");
9
10 let full_shift = draft_review
11 .coalesce(&approval)
12 .expect("adjacent intervals should coalesce");
13 let audit_window = full_shift
14 .restrict_to(&audit)
15 .expect("expected non-empty overlap");
16
17 assert!(draft_review.contains(&9));
18 assert!(!draft_review.contains(&12));
19 assert!(!draft_review.overlaps(&approval));
20 assert!(draft_review.is_adjacent_to(&approval));
21 assert_eq!(
22 audit_window,
23 Interval::new(11, 13).expect("expected valid interval")
24 );
25
26 println!(
27 "full shift: {:?}, audit overlap: {:?}",
28 full_shift, audit_window
29 );
30}Sourcepub fn coalesce(&self, other: &Self) -> Option<Self>
pub fn coalesce(&self, other: &Self) -> Option<Self>
Coalesces two overlapping or directly adjacent intervals.
Returns None when the intervals are strictly disjoint.
§Examples
use relmath::temporal::Interval;
let morning = Interval::new(9, 12).expect("expected valid interval");
let afternoon = Interval::new(12, 15).expect("expected valid interval");
assert_eq!(
morning.coalesce(&afternoon),
Some(Interval::new(9, 15).expect("expected valid interval"))
);Examples found in repository?
5fn main() {
6 let draft_review = Interval::new(9, 12).expect("expected valid interval");
7 let approval = Interval::new(12, 15).expect("expected valid interval");
8 let audit = Interval::new(11, 13).expect("expected valid interval");
9
10 let full_shift = draft_review
11 .coalesce(&approval)
12 .expect("adjacent intervals should coalesce");
13 let audit_window = full_shift
14 .restrict_to(&audit)
15 .expect("expected non-empty overlap");
16
17 assert!(draft_review.contains(&9));
18 assert!(!draft_review.contains(&12));
19 assert!(!draft_review.overlaps(&approval));
20 assert!(draft_review.is_adjacent_to(&approval));
21 assert_eq!(
22 audit_window,
23 Interval::new(11, 13).expect("expected valid interval")
24 );
25
26 println!(
27 "full shift: {:?}, audit overlap: {:?}",
28 full_shift, audit_window
29 );
30}Trait Implementations§
Source§impl<T: Ord + Clone> Extend<Interval<T>> for ValidTimeSupport<T>
impl<T: Ord + Clone> Extend<Interval<T>> for ValidTimeSupport<T>
Source§fn extend<I: IntoIterator<Item = Interval<T>>>(&mut self, iter: I)
fn extend<I: IntoIterator<Item = Interval<T>>>(&mut self, iter: I)
Source§fn extend_one(&mut self, item: A)
fn extend_one(&mut self, item: A)
extend_one)Source§fn extend_reserve(&mut self, additional: usize)
fn extend_reserve(&mut self, additional: usize)
extend_one)