rstm_core/traits/
symbols.rs

1/*
2    Appellation: symbolic <module>
3    Contrib: FL03 <jo3mccain@icloud.com>
4*/
5
6/// [Alphabet] describes a finite set of symbols used to construct a formal language.
7///
8/// Ideally, the alphabet should be implemented on unit enums since
9/// each symbol can be represented as a unique variant and assigned
10/// a particular value. The values of the variants may then be used
11/// as pointers, specifiying the location of the symbol w.r.t. the
12/// alphabet.
13pub trait Alphabet {
14    type Elem;
15
16    fn as_slice(&self) -> &[Self::Elem];
17
18    fn as_mut_slice(&mut self) -> &mut [Self::Elem];
19
20    fn is_empty(&self) -> bool {
21        self.len() == 0
22    }
23
24    fn len(&self) -> usize {
25        self.as_slice().len()
26    }
27
28    fn to_vec(&self) -> Vec<Self::Elem>;
29}
30/// [`Symbolic`] is a marker trait used to signal a type that can be displayed.
31pub trait Symbolic: core::fmt::Debug + core::fmt::Display {
32    private! {}
33}
34
35/// The [`RawSymbol`] trait establishes the minimum requirements for a type to be used
36/// as a symbol within a Turing machine.
37pub trait RawSymbol: Symbolic + 'static {
38    private! {}
39}
40
41/// The [`Symbol`] trait extends the [`RawSymbol`] to define the expected behaviors of a symbol
42/// used within a Turing machine.
43pub trait Symbol
44where
45    Self: RawSymbol
46        + Clone
47        + Copy
48        + Default
49        + Eq
50        + Ord
51        + PartialEq
52        + PartialOrd
53        + Send
54        + Sync
55        + core::hash::Hash,
56{
57}
58
59/*
60 ************* Implementations *************
61*/
62
63impl<S> Symbolic for S
64where
65    S: core::fmt::Debug + core::fmt::Display,
66{
67    seal! {}
68}
69
70impl<S> RawSymbol for S
71where
72    S: Symbolic + 'static,
73{
74    seal! {}
75}
76
77impl<S> Symbol for S where S: RawSymbol + Copy + Default + Eq + Ord + Send + Sync + core::hash::Hash {}
78
79impl<S: Symbol> Alphabet for [S] {
80    type Elem = S;
81
82    fn as_slice(&self) -> &[S] {
83        self
84    }
85
86    fn as_mut_slice(&mut self) -> &mut [S] {
87        self
88    }
89
90    fn is_empty(&self) -> bool {
91        self.is_empty()
92    }
93
94    fn len(&self) -> usize {
95        self.len()
96    }
97
98    fn to_vec(&self) -> Vec<S> {
99        self.to_vec()
100    }
101}
102
103#[cfg(feature = "alloc")]
104mod impl_alloc {
105    use super::{Alphabet, Symbol};
106    use alloc::vec::Vec;
107
108    impl<S: Symbol> Alphabet for Vec<S> {
109        type Elem = S;
110
111        fn as_slice(&self) -> &[S] {
112            self.as_slice()
113        }
114
115        fn as_mut_slice(&mut self) -> &mut [S] {
116            self.as_mut_slice()
117        }
118
119        fn is_empty(&self) -> bool {
120            self.is_empty()
121        }
122
123        fn len(&self) -> usize {
124            self.len()
125        }
126
127        fn to_vec(&self) -> Vec<S> {
128            self.clone()
129        }
130    }
131}