1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
use crate::states::{State, Stateful, States};
use crate::turing::{Head, Instruction};
use crate::{Extend, Resultant, Symbolic};
use serde::{Deserialize, Serialize};
use std::mem::replace;
#[derive(Clone, Debug, Default, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
pub struct Program<S: Symbolic> {
alphabet: Vec<S>,
instructions: Vec<Instruction<S>>,
final_state: State<States>,
}
impl<S: Symbolic> Program<S> {
pub fn new(alphabet: Vec<S>, final_state: State) -> Self {
let s: i64 = final_state.state().clone().into();
let capacity = alphabet.len() * s as usize;
let instructions = Vec::with_capacity(capacity);
Self {
alphabet,
instructions,
final_state,
}
}
pub fn alphabet(&self) -> &Vec<S> {
&self.alphabet
}
pub fn default_symbol(&self) -> &S {
&self.alphabet.first().unwrap()
}
pub fn instructions(&self) -> &Vec<Instruction<S>> {
&self.instructions
}
pub fn final_state(&self) -> &State {
&self.final_state
}
pub fn get(&self, head: Head<S>) -> Resultant<&Instruction<S>> {
if self.final_state().clone().state() < head.state().clone().state() {
return Err("The provided head is greater than the final state...".to_string());
}
if let Some(v) = self
.instructions()
.iter()
.find(|inst: &&Instruction<S>| inst.head().clone() == head)
{
return Ok(v);
}
Err("Failed to find instructions for the provided head...".to_string())
}
pub fn insert(&mut self, inst: Instruction<S>) -> Resultant<Option<Instruction<S>>> {
if inst.head().state() == &State::from(States::invalid()) {
return Err("Set error: Instruction cannot have 0 state in head...".to_string());
}
if !self.alphabet().contains(inst.head().symbol())
|| !self.alphabet().contains(inst.tail().symbol())
{
return Err(
"The provided instruction set fails to be represented within the alphabet..."
.to_string(),
);
}
if self.final_state().clone().state() < inst.head().state().clone().state()
|| self.final_state().clone().state() < inst.tail().state().clone().state()
{
return Err("Instructions have states greater than the ones availible...".to_string());
}
let position = self
.instructions()
.iter()
.position(|cand: &Instruction<S>| cand.head() == inst.head());
match position {
Some(index) => Ok(Some(replace(&mut self.instructions[index], inst))),
None => {
self.instructions.push(inst);
Ok(None)
}
}
}
}
impl<S: Symbolic> Extend<Instruction<S>> for Program<S> {
fn extend<T: IntoIterator<Item = Instruction<S>>>(&mut self, iter: T) -> Result<(), String> {
for i in iter {
self.insert(i)?;
}
Ok(())
}
}
#[cfg(test)]
mod test {
use super::*;
use crate::states::{State, States};
use crate::turing::{Instruction, Move};
#[test]
fn test_program() {
let inst = Instruction::from((
State::from(States::valid()),
"a",
State::from(States::valid()),
"b",
Move::Right,
));
let alphabet = vec!["a", "b", "c"];
let mut program = Program::new(alphabet, State::from(States::invalid()));
assert!(program.insert(inst.clone()).is_ok());
assert!(program.get(inst.head().clone()).is_ok())
}
}