1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
//! Set/space primitives for defining machine learning problems.
//!
//! `spaces` provides set/space primitives to be used for defining properties of
//! machine learning problems. Traits such as `Space`, and it's derivatives, may
//! be used to define state/action spaces, for example. Mappings between
//! different spaces may also be defined using traits such as `Surjection` to
//! streamline many common preprocessing and type conversion tasks.
extern crate itertools;
extern crate num_traits;

#[cfg(feature = "serialize")]
#[macro_use]
extern crate serde;

mod macros;

import_all!(card);

pub mod discrete;
pub mod real;

import_all!(interval);
import_all!(partition);

import_all!(arrays);
import_all!(tuples);

pub type Euclidean<const N: usize> = [real::Reals; N];

pub type Intervals<const N: usize> = [Interval; N];

/// Trait for defining geometric spaces.
pub trait Space {
    /// The dimensionality of the space.
    const DIM: usize;

    /// The data representation of elements of the space.
    type Value: Clone;

    /// Return the number of elements in the set comprising the space.
    fn card(&self) -> Card;

    /// Returns true iff `val` is contained within the space.
    fn contains(&self, val: &Self::Value) -> bool;
}

impl<D: Space> Space for Box<D> {
    const DIM: usize = D::DIM;

    type Value = D::Value;

    fn card(&self) -> Card { (**self).card() }

    fn contains(&self, val: &Self::Value) -> bool { (**self).contains(val) }
}

impl<'a, D: Space> Space for &'a D {
    const DIM: usize = D::DIM;

    type Value = D::Value;

    fn card(&self) -> Card { (**self).card() }

    fn contains(&self, val: &Self::Value) -> bool { (**self).contains(val) }
}

pub trait OrderedSpace: Space
where Self::Value: PartialOrd
{
    /// Returns the value of the space's minimum value, if it exists.
    fn min(&self) -> Option<Self::Value> { None }

    /// Return the infimum of the space.
    fn inf(&self) -> Option<Self::Value> { self.min() }

    /// Returns the value of the dimension's supremum, if it exists.
    fn max(&self) -> Option<Self::Value> { None }

    /// Returns the supremum of the space.
    fn sup(&self) -> Option<Self::Value> { self.max() }

    /// Returns true iff `self` has a well-defined infimum.
    fn is_lower_bounded(&self) -> bool { self.inf().is_some() }

    /// Returns true iff `self` has a well-defined supremum.
    fn is_upper_bounded(&self) -> bool { self.sup().is_some() }

    /// Returns true iff `self` has a well-defined minimum and maximum.
    fn is_bounded(&self) -> bool { self.is_lower_bounded() && self.is_upper_bounded() }
}

/// Trait for defining spaces containing a finite set of values.
pub trait FiniteSpace: Space {
    fn to_ordinal(&self) -> ::std::ops::Range<usize> {
        0..self
            .card()
            .expect_finite("Finite spaces must have finite cardinality.")
    }
}

/// Trait for types that can be combined in the form of a union.
///
/// The union of a collection of sets is the set that contains all elements in
/// the collection.
pub trait Union<S = Self> {
    /// Return a space enclosing `self` and `other` of type `Self`.
    fn union(self, other: &S) -> Self;

    /// Return a space enclosing `self` and all `other_spaces` of
    /// type `Self`.
    fn union_many(self, other_spaces: &[S]) -> Self
    where Self: Sized {
        other_spaces
            .into_iter()
            .fold(self, |acc, other_space| acc.union(other_space))
    }
}

/// Trait for types that can be combined in the form of an intersection.
///
/// The intersection of a collection of sets is the set that contains only those
/// elements present in each.
pub trait Intersect<S = Self> {
    /// Return the smallest space enclosing `self` and `other` of type `Self`.
    fn intersect(self, other: &S) -> Self;

    /// Return the smallest space enclosing `self` and all `other_spaces` of
    /// type `Self`.
    fn intersect_many(self, other_spaces: &[S]) -> Self
    where Self: Sized {
        other_spaces
            .into_iter()
            .fold(self, |acc, other_space| acc.intersect(other_space))
    }
}

mod prelude {
    pub use super::{Card, FiniteSpace, Intersect, OrderedSpace, Space, Union};
}