Skip to main content

rstm_core/rules/impls/
impl_rule_repr.rs

1/*
2    Appellation: impl_rule_repr <module>
3    Created At: 2026.01.14:23:11:59
4    Contrib: @FL03
5*/
6use crate::rules::rule::Rule;
7use crate::rules::{Head, Tail};
8use rstm_state::RawState;
9
10impl<Q, A, R, B> Rule<&Q, &A, &R, &B>
11where
12    Q: RawState,
13    R: RawState,
14{
15    /// returns a new instance of the [`Rule`] with cloned elements
16    pub fn cloned(&self) -> Rule<Q, A, R, B>
17    where
18        Q: Clone,
19        A: Clone,
20        R: Clone,
21        B: Clone,
22    {
23        Rule {
24            head: self.head.cloned(),
25            tail: self.tail.cloned(),
26        }
27    }
28    /// returns a new instance of the [`Rule`] with copied elements
29    pub const fn copied(&self) -> Rule<Q, A, R, B>
30    where
31        Q: Copy,
32        A: Copy,
33        R: Copy,
34        B: Copy,
35    {
36        Rule {
37            head: self.head.copied(),
38            tail: self.tail.copied(),
39        }
40    }
41}
42
43impl<Q, A> Rule<Q, usize, Q, A>
44where
45    Q: RawState,
46{
47    /// this method shifts the head along the tape, returning a head containing the previous
48    /// state and symbol.
49    ///
50    /// **note**: this method **does not** check if the current nor the next state is halted,
51    /// it is up to the caller to establishing halting.
52    pub fn shift(&mut self, tape: &mut [A]) -> Option<Head<Q, A>>
53    where
54        A: Clone,
55        Q: Clone,
56    {
57        let Tail {
58            next_state,
59            direction,
60            write_symbol,
61        } = self.tail.clone();
62        if let Some(sym) = tape.get(self.head.symbol).cloned() {
63            // update the tape at the head's current position
64            tape[self.head.symbol] = write_symbol;
65            // update the head position based on the tail's direction
66            self.head.symbol += direction;
67            // reconstruct the previous head
68            let prev = Head {
69                state: self.head.replace_state(next_state),
70                symbol: sym,
71            };
72            return Some(prev);
73        }
74        #[cfg(feature = "tracing")]
75        tracing::error!(
76            "The position of the head ({}) is out of tape bounds for a tape of length {}",
77            self.head.symbol,
78            tape.len()
79        );
80        // return None if the head's position is out of bounds
81        None
82    }
83}