Skip to main content

rstm_core/rules/
head.rs

1/*
2    Appellation: head <module>
3    Contrib: FL03 <jo3mccain@icloud.com>
4*/
5use rstm_state::{RawState, State};
6
7/// a type alias for a [`Head`] containing immutable references to its state and symbol
8pub type HeadRef<'a, Q, S> = Head<&'a Q, &'a S>;
9/// a type alias for a [`Head`] containing mutable references to its state and symbol
10pub type HeadMut<'a, Q, S> = Head<&'a mut Q, &'a mut S>;
11/// a type alias for a [`Head`] containing a reference to the state and a mutable reference to
12/// the symbol
13pub type HeadEntry<'a, Q, S> = Head<&'a Q, &'a mut S>;
14/// The [`Head`] of a Turing machine is defined to be a two-tuple consisting of a state and a
15/// symbol. Our implementation is generic over both the state and symbol types, allowing for
16/// flexibility in their representation(s).
17#[derive(Clone, Copy, Default, PartialEq, Eq, Hash, Ord, PartialOrd)]
18#[cfg_attr(
19    feature = "serde",
20    derive(serde::Deserialize, serde::Serialize),
21    serde(rename_all = "snake_case")
22)]
23#[repr(C)]
24pub struct Head<Q, A> {
25    #[cfg_attr(feature = "serde", serde(alias = "current_state"))]
26    pub state: State<Q>,
27    #[cfg_attr(feature = "serde", serde(alias = "current_symbol"))]
28    pub symbol: A,
29}
30/// [`RawHead`] is a marker trait used to define an interface for objects capable of being
31/// used as a _head_ in the context of Turing machine rules.
32pub trait RawHead {
33    type State: RawState;
34    type Symbol;
35    /// returns a reference to the current state of the head
36    fn state(&self) -> &State<Self::State>;
37    /// returns a reference to the symbol of the head
38    fn symbol(&self) -> &Self::Symbol;
39
40    private! {}
41}
42/// The [`RawHeadMut`] trait extends the [`RawHead`] trait by providing mutable access to
43pub trait RawHeadMut: RawHead {
44    /// returns a mutable reference to the current state of the head
45    fn state_mut(&mut self) -> &mut State<Self::State>;
46    /// returns a mutable reference to the symbol of the head
47    fn symbol_mut(&mut self) -> &mut Self::Symbol;
48}
49/// The [`HeadRepr`] trait extends the [`RawHead`] trait with standard initialization routines.
50pub trait HeadRepr: RawHead + Sized {
51    /// creates a new head from the given state and symbol
52    fn new(state: Self::State, symbol: Self::Symbol) -> Self;
53    /// create a new head from the given state, using a default symbol
54    fn from_state(state: Self::State) -> Self
55    where
56        Self::Symbol: Default,
57    {
58        Self::new(state, Default::default())
59    }
60    /// create a new head from the given symbol, using a default state
61    fn from_symbol(symbol: Self::Symbol) -> Self
62    where
63        Self::State: Default,
64    {
65        Self::new(Default::default(), symbol)
66    }
67}
68
69/*
70 ************* Implementations *************
71*/
72impl<Q, A> RawHead for (State<Q>, A)
73where
74    Q: RawState,
75{
76    type State = Q;
77    type Symbol = A;
78    seal! {}
79    /// returns an immutable reference to the state.
80    fn state(&self) -> &State<Q> {
81        &self.0
82    }
83    /// returns an immutable reference to the symbol.
84    fn symbol(&self) -> &A {
85        &self.1
86    }
87}
88
89impl<Q, A> RawHeadMut for (State<Q>, A)
90where
91    Q: RawState,
92{
93    /// returns a mutable reference to the state.
94    fn state_mut(&mut self) -> &mut State<Q> {
95        &mut self.0
96    }
97    /// returns a mutable reference to the symbol.
98    fn symbol_mut(&mut self) -> &mut A {
99        &mut self.1
100    }
101}
102
103impl<Q, A> HeadRepr for (State<Q>, A)
104where
105    Q: RawState,
106{
107    /// creates a new head from the given state and symbol
108    fn new(state: Q, symbol: A) -> Self {
109        (State(state), symbol)
110    }
111}
112
113impl<Q, A> RawHead for Head<Q, A>
114where
115    Q: RawState,
116{
117    type State = Q;
118    type Symbol = A;
119    seal! {}
120    /// returns an immutable reference to the state.
121    fn state(&self) -> &State<Q> {
122        &self.state
123    }
124    /// returns an immutable reference to the symbol.
125    fn symbol(&self) -> &A {
126        &self.symbol
127    }
128}
129
130impl<Q, A> RawHeadMut for Head<Q, A>
131where
132    Q: RawState,
133{
134    /// returns a mutable reference to the state.
135    fn state_mut(&mut self) -> &mut State<Q> {
136        &mut self.state
137    }
138    /// returns a mutable reference to the symbol.
139    fn symbol_mut(&mut self) -> &mut A {
140        &mut self.symbol
141    }
142}
143
144impl<Q, A> HeadRepr for Head<Q, A>
145where
146    Q: RawState,
147{
148    /// creates a new head from the given state and symbol
149    fn new(state: Q, symbol: A) -> Self {
150        Self {
151            state: State(state),
152            symbol,
153        }
154    }
155}
156#[cfg(test)]
157mod tests {
158    use super::Head;
159
160    #[test]
161    fn test_head_creation() {
162        let head = Head::new("s", 0usize);
163        assert_eq! { head, ("s", 0usize) }
164    }
165}