Skip to main content

rstm_core/rules/
tail.rs

1/*
2    Appellation: tail <module>
3    Created At: 2025.12.15:21:29:04
4    Contrib: @FL03
5*/
6use crate::Direction;
7use rstm_state::{RawState, State};
8
9/// A type alias for a [`Tail`] containing immutable references to the next state and symbol.
10pub type TailRef<'a, Q, A> = Tail<&'a Q, &'a A>;
11/// A type alias for a [`Tail`] containing mutable references to the next state and symbol.
12pub type TailMut<'a, Q, A> = Tail<&'a mut Q, &'a mut A>;
13/// The [`Tail`] of a rule defines the _reaction_ of the actor under specific conditions.
14/// Specifically, it defines the next state, the symbol to write, and the direction to move
15#[derive(Clone, Copy, Default, PartialEq, Eq, Hash, Ord, PartialOrd)]
16#[cfg_attr(
17    feature = "serde",
18    derive(serde::Deserialize, serde::Serialize),
19    serde(deny_unknown_fields, rename_all = "snake_case")
20)]
21#[repr(C)]
22pub struct Tail<Q, A> {
23    /// defines the direction to move after writing the symbol
24    #[cfg_attr(feature = "serde", serde(alias = "move_direction", alias = "dir"))]
25    pub direction: Direction,
26    #[cfg_attr(feature = "serde", serde(alias = "write_state"))]
27    pub next_state: State<Q>,
28    #[cfg_attr(feature = "serde", serde(alias = "next_symbol"))]
29    pub write_symbol: A,
30}
31/// [`RawTail`] is a sealed marker trait used to denote objects capable of being used to
32/// represent the _tail_ of a rule for a Turing machine.
33pub trait RawTail {
34    type State: RawState;
35    type Symbol;
36    private! {}
37    /// returns the direction of the tail.
38    fn direction(&self) -> Direction;
39    /// returns an immutable reference to the next state.
40    fn next_state(&self) -> &State<Self::State>;
41    /// returns a reference to the symbol configured for the head to write next.
42    fn write_symbol(&self) -> &Self::Symbol;
43}
44/// The [`RawTailMut`] provides mutable access to the components of a tail.
45pub trait RawTailMut: RawTail {
46    /// returns a mutable reference to the direction of the tail.
47    fn direction_mut(&mut self) -> &mut Direction;
48    /// returns a mutable reference to the next state.
49    fn next_state_mut(&mut self) -> &mut State<Self::State>;
50    /// returns a mutable reference to the symbol to write.
51    fn write_symbol_mut(&mut self) -> &mut Self::Symbol;
52}
53/// The [`TailRepr`] trait extends the [`RawTail`] trait with standard initialization routines.
54pub trait TailRepr: RawTail + Sized {
55    /// creates a new tail from the given direction, next state, and symbol to write
56    fn new(direction: Direction, next_state: Self::State, write_symbol: Self::Symbol) -> Self;
57    /// creates a new tail that moves right after writing the symbol and transitioning to the
58    /// next state
59    fn right(next_state: Self::State, write_symbol: Self::Symbol) -> Self {
60        Self::new(Direction::Right, next_state, write_symbol)
61    }
62    /// creates a new tail that moves left after writing the symbol and transitioning to the
63    /// next state
64    fn left(next_state: Self::State, write_symbol: Self::Symbol) -> Self {
65        Self::new(Direction::Left, next_state, write_symbol)
66    }
67    fn stay(next_state: Self::State, write_symbol: Self::Symbol) -> Self {
68        Self::new(Direction::Stay, next_state, write_symbol)
69    }
70}
71/*
72 ************* Implementations *************
73*/
74impl<Q, A> RawTail for (Direction, State<Q>, A)
75where
76    Q: RawState,
77{
78    type State = Q;
79    type Symbol = A;
80
81    seal! {}
82    /// returns the direction of the tail.
83    fn direction(&self) -> Direction {
84        self.0
85    }
86    /// returns an immutable reference to the next state.
87    fn next_state(&self) -> &State<Q> {
88        &self.1
89    }
90    /// returns an immutable reference to the symbol to write.
91    fn write_symbol(&self) -> &A {
92        &self.2
93    }
94}
95
96impl<Q, A> RawTailMut for (Direction, State<Q>, A)
97where
98    Q: RawState,
99{
100    /// returns a mutable reference to the direction of the tail.
101    fn direction_mut(&mut self) -> &mut Direction {
102        &mut self.0
103    }
104    /// returns a mutable reference to the next state.
105    fn next_state_mut(&mut self) -> &mut State<Q> {
106        &mut self.1
107    }
108    /// returns a mutable reference to the symbol to write.
109    fn write_symbol_mut(&mut self) -> &mut A {
110        &mut self.2
111    }
112}
113
114impl<Q, A> TailRepr for (Direction, State<Q>, A)
115where
116    Q: RawState,
117{
118    /// creates a new tail from the given direction, next state, and symbol to write
119    fn new(direction: Direction, next_state: Q, write_symbol: A) -> Self {
120        (direction, State(next_state), write_symbol)
121    }
122}
123
124impl<Q, A> RawTail for Tail<Q, A>
125where
126    Q: RawState,
127{
128    type State = Q;
129    type Symbol = A;
130
131    seal! {}
132    /// returns the direction of the tail.
133    fn direction(&self) -> Direction {
134        self.direction
135    }
136    /// returns an immutable reference to the next state.
137    fn next_state(&self) -> &State<Q> {
138        &self.next_state
139    }
140    /// returns an immutable reference to the symbol to write.
141    fn write_symbol(&self) -> &A {
142        &self.write_symbol
143    }
144}
145impl<Q, A> RawTailMut for Tail<Q, A>
146where
147    Q: RawState,
148{
149    /// returns a mutable reference to the direction of the tail.
150    fn direction_mut(&mut self) -> &mut Direction {
151        &mut self.direction
152    }
153    /// returns a mutable reference to the next state.
154    fn next_state_mut(&mut self) -> &mut State<Q> {
155        &mut self.next_state
156    }
157    /// returns a mutable reference to the symbol to write.
158    fn write_symbol_mut(&mut self) -> &mut A {
159        &mut self.write_symbol
160    }
161}
162
163impl<Q, A> TailRepr for Tail<Q, A>
164where
165    Q: RawState,
166{
167    /// creates a new tail from the given direction, next state, and symbol to write
168    fn new(direction: Direction, next_state: Q, write_symbol: A) -> Self {
169        Self {
170            direction,
171            next_state: State(next_state),
172            write_symbol,
173        }
174    }
175}
176
177#[cfg(test)]
178mod tests {
179    use super::*;
180
181    #[test]
182    fn test_tail_init() {
183        let tail: Tail<&str, char> = Tail::right("q1", 'a');
184        assert_eq! {
185            tail,
186            (
187                Direction::Right,
188                State("q1"),
189                'a'
190            )
191        }
192    }
193}