allen_intervals/lib.rs
1//! In 1983 James F. Allen published a paper in which he proposed [thirteen basic relations between time intervals][allen-interval-algebra],
2//! that are distinct, exhaustive, and qualitative:
3//!
4//! > Allen, J. F. (1983).
5//! > Maintaining knowledge about temporal intervals.
6//! > Communications of the ACM, 26(11), 832-843.
7//!
8//! - *distinct*, because no pair of definite intervals can be related by more than one of the relationships
9//! - *exhaustive*, because any pair of definite intervals are described by one of the relations
10//! - *qualitative*, (rather than quantitative) because no numeric time spans are considered
11//!
12//! Allen's intervals support both, [discrete][time-domains] and [continuous][time-domains] [time domains][time-domains].
13//!
14//! ## Discrete (i.e. quantized) time-domain
15//!
16//! > [Wikipedia][time-domains]: Discrete time views values of variables as occurring at distinct, separate "points in time",
17//! > or equivalently as being unchanged throughout each non-zero region of time ("time period")
18//! > —that is, time is viewed as a discrete variable.
19//! > Thus a non-time variable jumps from one value to another as time moves from one time period to the next.
20//! > This view of time corresponds to a digital clock that gives a fixed reading of 10:37 for a while,
21//! > and then jumps to a new fixed reading of 10:38, etc.
22//! > In this framework, each variable of interest is measured once at each time period.
23//! > The number of measurements between any two time periods is finite.
24//! > Measurements are typically made at sequential integer values of the variable "time".
25//!
26//! If your time-values are represented using an integer type (e.g. `f32` or `f64`), then your time domain is most likely continuous.
27//!
28//! > 💡 In discrete time domains Allen's intervals behave like as if they had exclusive end bounds
29//! > (similar to exclusive ranges: `..`, `..y`, `x..` and `x..y`).
30//!
31//! > ⚠️ Values in discrete (i.e. quantized) domains have a length.
32//! > As such an interval `IntervalTo { end: x }` is considered
33//! > meeting a range `IntervalFrom { start: x }`, rather than overlapping it.
34//!
35//! ## Continuous (i.e. un-quantized) time-domain
36//!
37//! > [Wikipedia][time-domains]: Continuous time views variables as having a particular value only for an infinitesimally short amount of time.
38//! > Between any two points in time there are an infinite number of other points in time.
39//! > The variable "time" ranges over the entire real number line, or depending on the context,
40//! > over some subset of it such as the non-negative reals. Thus time is viewed as a continuous variable.
41//! >
42//! > A continuous signal or a continuous-time signal is a varying quantity (a signal) whose domain,
43//! > which is often time, is a continuum (e.g., a connected interval of the reals).
44//! > That is, the function's domain is an uncountable set. The function itself need not to be continuous.
45//! > To contrast, a discrete-time signal has a countable domain, like the natural numbers.
46//!
47//! If your time-values are represented using a floating-point type (e.g. `f32` or `f64`), then your time domain is most likely continuous.
48//!
49//! > 💡 In continuous time domains Allen's intervals behave like as if they had exclusive end bounds
50//! > (similar to inclusive ranges:`..`, `..=y`, `x..` and `x..=y`).
51//!
52//! > ⚠️ Values in continuous domains have an infinitesimally short (i.e. ~0.0) length.
53//! > As such a range `IntervalTo { end: x.y }`` is considered
54//! > meeting a range `IntervalFrom { start: x }`, rather than overlapping it.
55//!
56//! # Examples
57//!
58//! ```
59//! use allen_intervals::{Contains, FromIntervals, Interval, Meets, NonEmpty, Precedes, Relation};
60//!
61//! // Allen's interval algebra is only defined for non-empty intervals.
62//! // We thus need to wrap them in `NonEmpty<T>` first:
63//! let s: NonEmpty<_> = Interval { start: 1, end: 4 }.try_into().unwrap();
64//! let t: NonEmpty<_> = Interval { start: 5, end: 8 }.try_into().unwrap();
65//!
66//! assert_eq!(
67//! Relation::from_intervals(&s, &t),
68//! Relation::Precedes { is_inverted: false }
69//! );
70//! assert_eq!(
71//! Relation::from_intervals(&t, &s),
72//! Relation::Precedes { is_inverted: true }
73//! );
74//!
75//! assert!(s.precedes(&t));
76//! assert!(t.is_preceded_by(&s));
77//!
78//! // Allen's interval algebra is only defined for non-empty intervals.
79//! // We thus need to wrap them in `NonEmpty<T>` first:
80//! let s: NonEmpty<_> = Interval { start: 1, end: 5 }.try_into().unwrap();
81//! let t: NonEmpty<_> = Interval { start: 5, end: 9 }.try_into().unwrap();
82//!
83//! assert_eq!(
84//! Relation::from_intervals(&s, &t),
85//! Relation::Meets { is_inverted: false }
86//! );
87//! assert_eq!(
88//! Relation::from_intervals(&t, &s),
89//! Relation::Meets { is_inverted: true }
90//! );
91//!
92//! assert!(s.meets(&t));
93//! assert!(t.is_met_by(&s));
94//!
95//! // Allen's interval algebra is only defined for non-empty intervals.
96//! // We thus need to wrap them in `NonEmpty<T>` first:
97//! let s: NonEmpty<_> = Interval { start: 3, end: 7 }.try_into().unwrap();
98//! let t: NonEmpty<_> = Interval { start: 4, end: 6 }.try_into().unwrap();
99//!
100//! assert_eq!(
101//! Relation::from_intervals(&s, &t),
102//! Relation::Contains { is_inverted: false }
103//! );
104//! assert_eq!(
105//! Relation::from_intervals(&t, &s),
106//! Relation::Contains { is_inverted: true }
107//! );
108//!
109//! assert!(s.contains(&t));
110//! assert!(t.is_contained_by(&s));
111//! ```
112//!
113//! [allen-interval-algebra]: https://en.wikipedia.org/wiki/Allen%27s_interval_algebra
114//! [quantization]: https://en.wikipedia.org/wiki/Quantization
115//! [time-domains]: https://en.wikipedia.org/wiki/Discrete_time_and_continuous_time
116
117#![cfg_attr(all(not(test), not(feature = "std")), no_std)]
118#![warn(missing_docs)]
119
120#[cfg(all(not(test), not(feature = "std")))]
121extern crate core as std;
122
123#[cfg(all(test, feature = "std"))]
124extern crate std;
125
126mod atomic;
127mod bounds;
128mod from_intervals;
129mod interval;
130mod non_empty;
131mod relation;
132
133pub use self::{bounds::*, from_intervals::*, interval::*, non_empty::*, relation::*};
134
135use self::atomic::*;