Skip to main content

Interval

Struct Interval 

Source
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>

Source

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?
examples/intervals.rs (line 6)
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
Hide additional examples
examples/capability_boundaries.rs (line 34)
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}
examples/valid_time.rs (line 12)
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}
Source

pub fn start(&self) -> &T

Returns the inclusive lower bound of the interval.

Source

pub fn end(&self) -> &T

Returns the exclusive upper bound of the interval.

Source

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?
examples/intervals.rs (line 17)
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}
Source

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?
examples/intervals.rs (line 19)
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}
Source

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?
examples/intervals.rs (line 20)
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}
Source

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>

Source

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"))
);
Source

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?
examples/intervals.rs (line 14)
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}
Source

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?
examples/intervals.rs (line 11)
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: Clone + Ord> Clone for Interval<T>

Source§

fn clone(&self) -> Interval<T>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<T: Debug + Ord> Debug for Interval<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T: Ord + Clone> Extend<Interval<T>> for ValidTimeSupport<T>

Source§

fn extend<I: IntoIterator<Item = Interval<T>>>(&mut self, iter: I)

Extends a collection with the contents of an iterator. Read more
Source§

fn extend_one(&mut self, item: A)

🔬This is a nightly-only experimental API. (extend_one)
Extends a collection with exactly one element.
Source§

fn extend_reserve(&mut self, additional: usize)

🔬This is a nightly-only experimental API. (extend_one)
Reserves capacity in a collection for the given number of additional elements. Read more
Source§

impl<T: Ord + Clone> FromIterator<Interval<T>> for ValidTimeSupport<T>

Source§

fn from_iter<I: IntoIterator<Item = Interval<T>>>(iter: I) -> Self

Creates a value from an iterator. Read more
Source§

impl<T: Ord + Ord> Ord for Interval<T>

Source§

fn cmp(&self, other: &Interval<T>) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · Source§

fn max(self, other: Self) -> Self
where Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · Source§

fn min(self, other: Self) -> Self
where Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · Source§

fn clamp(self, min: Self, max: Self) -> Self
where Self: Sized,

Restrict a value to a certain interval. Read more
Source§

impl<T: PartialEq + Ord> PartialEq for Interval<T>

Source§

fn eq(&self, other: &Interval<T>) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<T: PartialOrd + Ord> PartialOrd for Interval<T>

Source§

fn partial_cmp(&self, other: &Interval<T>) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · Source§

fn lt(&self, other: &Rhs) -> bool

Tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · Source§

fn le(&self, other: &Rhs) -> bool

Tests less than or equal to (for self and other) and is used by the <= operator. Read more
1.0.0 · Source§

fn gt(&self, other: &Rhs) -> bool

Tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · Source§

fn ge(&self, other: &Rhs) -> bool

Tests greater than or equal to (for self and other) and is used by the >= operator. Read more
Source§

impl<T: Eq + Ord> Eq for Interval<T>

Source§

impl<T: Ord> StructuralPartialEq for Interval<T>

Auto Trait Implementations§

§

impl<T> Freeze for Interval<T>
where T: Freeze,

§

impl<T> RefUnwindSafe for Interval<T>
where T: RefUnwindSafe,

§

impl<T> Send for Interval<T>
where T: Send,

§

impl<T> Sync for Interval<T>
where T: Sync,

§

impl<T> Unpin for Interval<T>
where T: Unpin,

§

impl<T> UnsafeUnpin for Interval<T>
where T: UnsafeUnpin,

§

impl<T> UnwindSafe for Interval<T>
where T: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.