rstm_rules/traits/
instruction.rs

1/*
2    appellation: transition <module>
3    authors: @FL03
4*/
5use crate::rule::Rule;
6use rstm_core::{Direction, Head, Symbol, Tail};
7use rstm_state::{RawState, State};
8
9/// The [`Scope`] trait is used to describe objects containing information or references to the
10/// current state and symbol of a Turing machine.
11pub trait Scope<Q, S>
12where
13    Q: RawState,
14{
15    fn current_state(&self) -> &State<Q>;
16
17    fn current_symbol(&self) -> &S;
18}
19
20/// [`Directive`] is a trait describing the `tail` of a typical Turing machine;
21pub trait Directive<Q, S>
22where
23    Q: RawState,
24{
25    fn direction(&self) -> Direction;
26
27    fn next_state(&self) -> &State<Q>;
28
29    fn next_symbol(&self) -> &S;
30}
31
32/// The [`Instruction`] trait defines the expected behaviors of a particular rule within a
33/// Turing machine program.
34pub trait Instruction<Q, S>
35where
36    Q: RawState,
37{
38    /// returns a copy of the direction of the head
39    fn direction(&self) -> Direction;
40    /// returns a reference to the current state of the Turing machine
41    fn current_state(&self) -> &State<Q>;
42    /// returns a reference to the next state of the Turing machine
43    fn next_state(&self) -> &State<Q>;
44    /// returns a reference to the current symbol under the head
45    fn symbol(&self) -> &S;
46    /// returns a reference to the symbol to be written by the head
47    fn write_symbol(&self) -> &S;
48    /// returns an instance of [`Head`] containing references to the current state and symbol
49    fn head(&self) -> Head<&Q, &S> {
50        Head {
51            state: self.current_state().view(),
52            symbol: self.symbol(),
53        }
54    }
55    /// returns an instance of [`Tail`] containing references to the next state and symbol
56    fn tail(&self) -> Tail<&Q, &S> {
57        Tail {
58            direction: self.direction(),
59            next_state: self.next_state().view(),
60            write_symbol: self.write_symbol(),
61        }
62    }
63    /// returns an instance of [`Rule`] containing references to the states and symbols within
64    fn as_rule(&self) -> Rule<&Q, &S> {
65        Rule {
66            head: self.head(),
67            tail: self.tail(),
68        }
69    }
70}
71
72/*
73 ************* Implementations *************
74*/
75impl<A, Q, S> Instruction<Q, S> for A
76where
77    A: Scope<Q, S> + Directive<Q, S>,
78    Q: RawState,
79    S: Symbol,
80{
81    fn direction(&self) -> Direction {
82        self.direction()
83    }
84
85    fn current_state(&self) -> &State<Q> {
86        self.current_state()
87    }
88
89    fn next_state(&self) -> &State<Q> {
90        self.next_state()
91    }
92
93    fn symbol(&self) -> &S {
94        self.current_symbol()
95    }
96
97    fn write_symbol(&self) -> &S {
98        self.next_symbol()
99    }
100}
101
102impl<Q, S> Scope<Q, S> for (State<Q>, S)
103where
104    Q: RawState,
105{
106    fn current_state(&self) -> &State<Q> {
107        &self.0
108    }
109
110    fn current_symbol(&self) -> &S {
111        &self.1
112    }
113}
114
115impl<Q, S> Scope<Q, S> for Head<Q, S>
116where
117    Q: RawState,
118{
119    fn current_state(&self) -> &State<Q> {
120        self.state()
121    }
122
123    fn current_symbol(&self) -> &S {
124        &self.symbol
125    }
126}
127
128impl<Q, S> Scope<Q, S> for Rule<Q, S>
129where
130    Q: RawState,
131{
132    fn current_state(&self) -> &State<Q> {
133        self.state()
134    }
135
136    fn current_symbol(&self) -> &S {
137        self.symbol()
138    }
139}
140
141impl<Q, S> Directive<Q, S> for (Direction, State<Q>, S)
142where
143    Q: RawState,
144{
145    fn direction(&self) -> Direction {
146        self.0
147    }
148
149    fn next_state(&self) -> &State<Q> {
150        &self.1
151    }
152
153    fn next_symbol(&self) -> &S {
154        &self.2
155    }
156}
157
158impl<Q, S> Directive<Q, S> for Tail<Q, S>
159where
160    Q: RawState,
161{
162    fn direction(&self) -> Direction {
163        self.direction
164    }
165
166    fn next_state(&self) -> &State<Q> {
167        self.state()
168    }
169
170    fn next_symbol(&self) -> &S {
171        self.symbol()
172    }
173}
174
175impl<Q, S> Directive<Q, S> for Rule<Q, S>
176where
177    Q: RawState,
178{
179    fn direction(&self) -> Direction {
180        self.direction()
181    }
182
183    fn next_state(&self) -> &State<Q> {
184        self.tail().state()
185    }
186
187    fn next_symbol(&self) -> &S {
188        self.write_symbol()
189    }
190}