rstm_core/actors/
actor.rs1use super::Executor;
6use crate::rules::RuleSet;
7use crate::{Direction, Error, Head, State};
8
9#[derive(Clone, Default, Eq, Hash, PartialEq, PartialOrd)]
16pub struct Actor<Q, A> {
17 pub(crate) head: Head<Q, usize>,
19 pub(crate) tape: Vec<A>,
21}
22
23impl<Q, A> Actor<Q, A> {
24 pub fn new(alpha: impl IntoIterator<Item = A>, state: State<Q>, symbol: usize) -> Self {
25 Self {
26 head: Head { state, symbol },
27 tape: Vec::from_iter(alpha),
28 }
29 }
30 pub fn from_state(state: State<Q>) -> Self {
33 Self {
34 head: Head { state, symbol: 0 },
35 tape: Vec::new(),
36 }
37 }
38 pub fn with_alpha<I>(self, alpha: I) -> Self
40 where
41 I: IntoIterator<Item = A>,
42 {
43 Self {
44 tape: Vec::from_iter(alpha),
45 ..self
46 }
47 }
48 pub fn with_head(self, head: Head<Q, usize>) -> Self {
50 Self { head, ..self }
51 }
52 pub fn with_position(self, symbol: usize) -> Self {
54 Self {
55 head: Head {
56 symbol,
57 ..self.head
58 },
59 ..self
60 }
61 }
62 pub fn with_state(self, state: State<Q>) -> Self {
64 Self {
65 head: Head { state, ..self.head },
66 ..self
67 }
68 }
69 pub fn tape(&self) -> &[A] {
71 &self.tape
72 }
73 pub fn tape_mut(&mut self) -> &mut [A] {
75 &mut self.tape
76 }
77 pub const fn head(&self) -> &Head<Q, usize> {
79 &self.head
80 }
81 pub fn head_mut(&mut self) -> &mut Head<Q, usize> {
83 &mut self.head
84 }
85 pub fn head_ref(&self) -> Head<&Q, usize> {
88 Head {
89 state: self.head.state.to_ref(),
90 symbol: self.head.symbol,
91 }
92 }
93 pub fn position(&self) -> usize {
95 self.head().symbol
96 }
97 pub fn state(&self) -> State<&Q> {
99 self.head().state()
100 }
101 pub fn state_mut(&mut self) -> State<&mut Q> {
103 self.head_mut().state_mut()
104 }
105 pub fn execute(self, program: RuleSet<Q, A>) -> Executor<Q, A> {
108 Executor::new(self, program)
109 }
110 pub fn is_empty(&self) -> bool {
112 self.tape.is_empty()
113 }
114 pub fn is_halted(&self) -> bool
116 where
117 Q: 'static,
118 {
119 self.head().state.is_halt()
120 }
121 #[inline]
123 pub fn len(&self) -> usize {
124 self.tape.len()
125 }
126 #[cfg_attr(
128 feature = "tracing",
129 tracing::instrument(skip_all, name = "read", target = "actor")
130 )]
131 pub fn read(&self) -> Result<Head<&'_ Q, &'_ A>, Error> {
132 #[cfg(feature = "tracing")]
133 tracing::trace!("Reading the tape...");
134 self.tape
135 .get(self.position())
136 .map(|symbol| Head {
137 state: self.state(),
138 symbol,
139 })
140 .ok_or(Error::index_out_of_bounds(self.position(), self.len()))
141 }
142
143 #[cfg_attr(
145 feature = "tracing",
146 tracing::instrument(skip_all, name = "write", target = "actor")
147 )]
148 pub fn write(&mut self, value: A) {
149 #[cfg(feature = "tracing")]
150 tracing::trace!("Writing to the tape...");
151 let pos = self.position();
152
153 if pos == usize::MAX {
154 #[cfg(feature = "tracing")]
155 tracing::trace!("Prepending to the tape...");
156 self.tape.insert(0, value);
158 } else if pos >= self.len() {
159 #[cfg(feature = "tracing")]
160 tracing::trace!("Appending to the tape...");
161 self.tape.push(value);
163 } else {
164 self.tape[pos] = value;
165 }
166 }
167 #[cfg_attr(
171 feature = "tracing",
172 tracing::instrument(skip_all, name = "handle", target = "actor")
173 )]
174 pub(crate) fn step(
175 &mut self,
176 direction: Direction,
177 state: State<Q>,
178 symbol: A,
179 ) -> Head<Q, usize> {
180 #[cfg(feature = "tracing")]
181 tracing::trace!("Transitioning the actor...");
182 self.write(symbol);
184 self.head.replace(state, self.position() + direction)
186 }
187}
188
189impl<Q, S> core::fmt::Debug for Actor<Q, S>
190where
191 S: core::fmt::Debug,
192{
193 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
194 for (i, c) in self.tape.iter().enumerate() {
195 if i == self.position() {
196 write!(f, "[{c:?}]")?;
197 } else {
198 write!(f, "{c:?}")?;
199 }
200 }
201 Ok(())
202 }
203}
204
205impl<Q, S> core::fmt::Display for Actor<Q, S>
206where
207 S: core::fmt::Display,
208{
209 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
210 for (i, c) in self.tape.iter().enumerate() {
211 if i == self.position() {
212 write!(f, "[{c}]")?;
213 } else {
214 write!(f, "{c}")?;
215 }
216 }
217 Ok(())
218 }
219}