143 lines
4.6 KiB
Rust
143 lines
4.6 KiB
Rust
use std::collections::VecDeque;
|
|
use std::fmt::{Display, Formatter, Result};
|
|
|
|
fn main() {
|
|
println!("Simple incrementer");
|
|
let rules_si = vec!(
|
|
Rule::new("q0", '1', '1', Direction::Right, "q0"),
|
|
Rule::new("q0", 'B', '1', Direction::Stay, "qf")
|
|
);
|
|
let states_si = vec!("q0", "qf");
|
|
let terminating_states_si = vec!("qf");
|
|
let permissible_symbols_si = vec!('B', '1');
|
|
let mut tm_si = TM::new(states_si, "q0", terminating_states_si, permissible_symbols_si, 'B', rules_si, "111");
|
|
while !tm_si.is_done() {
|
|
println!("{}", tm_si);
|
|
tm_si.step();
|
|
}
|
|
|
|
println!("___________________");
|
|
println!("Three-state busy beaver");
|
|
let rules_bb3 = vec!(
|
|
Rule::new("a", '0', '1', Direction::Right, "b"),
|
|
Rule::new("a", '1', '1', Direction::Left, "c"),
|
|
Rule::new("b", '0', '1', Direction::Left, "a"),
|
|
Rule::new("b", '1', '1', Direction::Right, "b"),
|
|
Rule::new("c", '0', '1', Direction::Left, "b"),
|
|
Rule::new("c", '1', '1', Direction::Stay, "halt"),
|
|
);
|
|
let states_bb3 = vec!("a", "b", "c", "halt");
|
|
let terminating_states_bb3 = vec!("halt");
|
|
let permissible_symbols_bb3 = vec!('0', '1');
|
|
let mut tm_bb3 = TM::new(states_bb3 ,"a", terminating_states_bb3, permissible_symbols_bb3, '0', rules_bb3, "0");
|
|
while !tm_bb3.is_done() {
|
|
println!("{}", tm_bb3);
|
|
tm_bb3.step();
|
|
}
|
|
println!("{}", tm_bb3);
|
|
|
|
println!("___________________");
|
|
println!("Five-state busy beaver");
|
|
let rules_bb5 = vec!(
|
|
Rule::new("A", '0', '1', Direction::Right, "B"),
|
|
Rule::new("A", '1', '1', Direction::Left, "C"),
|
|
Rule::new("B", '0', '1', Direction::Right, "C"),
|
|
Rule::new("B", '1', '1', Direction::Right, "B"),
|
|
Rule::new("C", '0', '1', Direction::Right, "D"),
|
|
Rule::new("C", '1', '0', Direction::Left, "E"),
|
|
Rule::new("D", '0', '1', Direction::Left, "A"),
|
|
Rule::new("D", '1', '1', Direction::Left, "D"),
|
|
Rule::new("E", '0', '1', Direction::Stay, "H"),
|
|
Rule::new("E", '1', '0', Direction::Left, "A"),
|
|
);
|
|
let states_bb5 = vec!("A", "B", "C", "D", "E", "H");
|
|
let terminating_states_bb5 = vec!("H");
|
|
let permissible_symbols_bb5 = vec!('0', '1');
|
|
let mut tm_bb5 = TM::new(states_bb5 ,"A", terminating_states_bb5, permissible_symbols_bb5, '0', rules_bb5, "0");
|
|
let mut steps = 0;
|
|
while !tm_bb5.is_done() {
|
|
tm_bb5.step();
|
|
steps += 1;
|
|
}
|
|
println!("Steps: {}", steps);
|
|
println!("Band lenght: {}", tm_bb5.band.len());
|
|
}
|
|
|
|
struct TM<'a> {
|
|
state: &'a str,
|
|
terminating_states: Vec<&'a str>,
|
|
rules: Vec<Rule<'a>>,
|
|
band: VecDeque<char>,
|
|
head: usize,
|
|
blank: char,
|
|
}
|
|
|
|
struct Rule<'a> {
|
|
state: &'a str,
|
|
read: char,
|
|
write: char,
|
|
dir: Direction,
|
|
new_state: &'a str,
|
|
}
|
|
|
|
enum Direction{
|
|
Left,
|
|
Right,
|
|
Stay,
|
|
}
|
|
|
|
impl<'a> TM<'a> {
|
|
|
|
fn new(_states: Vec<&'a str>, initial_state: &'a str, terminating_states: Vec<&'a str>, _permissible_symbols: Vec<char>, blank: char, rules: Vec<Rule<'a>>, input: &str) -> Self {
|
|
Self { state: initial_state, terminating_states, rules, band: input.chars().collect::<VecDeque<_>>(), head: 0, blank }
|
|
}
|
|
|
|
fn is_done(&self) -> bool {
|
|
self.terminating_states.contains(&self.state)
|
|
}
|
|
|
|
fn step(&mut self) {
|
|
let field = self.band.get(self.head).unwrap();
|
|
let rule = self.rules.iter().find(|rule| rule.state == self.state && &rule.read == field).unwrap();
|
|
let field = self.band.get_mut(self.head).unwrap();
|
|
*field = rule.write;
|
|
self.state = rule.new_state;
|
|
match rule.dir {
|
|
Direction::Left => {
|
|
if self.head == 0 {
|
|
self.band.push_front(self.blank)
|
|
} else {
|
|
self.head -= 1;
|
|
}
|
|
},
|
|
Direction::Right => {
|
|
if self.head == self.band.len() - 1 {
|
|
self.band.push_back(self.blank)
|
|
}
|
|
self.head += 1;
|
|
},
|
|
Direction::Stay => {},
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'a> Display for TM<'a> {
|
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
|
|
let band = self.band.iter().enumerate().map(|(i, c)| {
|
|
if i == self.head {
|
|
format!("[{}]", c)
|
|
} else {
|
|
format!(" {} ", c)
|
|
}
|
|
}).fold(String::new(), |acc, val| acc + &val);
|
|
write!(f, "{}\t{}", self.state, band)
|
|
}
|
|
}
|
|
|
|
|
|
impl<'a> Rule<'a> {
|
|
fn new(state: &'a str, read: char, write: char, dir: Direction, new_state: &'a str) -> Self {
|
|
Self { state, read, write, dir, new_state }
|
|
}
|
|
}
|