hyper_machine/
hyper_machine.rs

1extern crate turing_machine_rs;
2
3use turing_machine_rs::instruction::{Move, State};
4use turing_machine_rs::machines::Classic;
5use turing_machine_rs::program::{Extend, Program};
6use turing_machine_rs::state::{Configuration, Tape};
7use turing_machine_rs::TuringMachine;
8
9// For more comfortable coding, use Result<(), String>:
10// `?` postfix symbol is better then `.unwrap()` postfix method call.
11fn main() -> Result<(), String> {
12    use nrm_machines::*;
13
14    let stand = new_stand_machine();
15    let zerofy = new_zerofy_machine();
16    let l_shift = new_left_shift_machine();
17    let r_shift = new_right_shift_machine();
18    let trans = new_trans_machine();
19
20    let mut program = Program::new(
21        vec![
22            stand.clone(),
23            zerofy.clone(),
24            l_shift.clone(),
25            r_shift.clone(),
26            trans.clone(),
27        ],
28        State(9),
29    );
30    // This is simplest implementation of `change choose second to choose third` machine
31    program.extend([
32        // Find l_shift
33        (1, r_shift.clone(), 1, r_shift.clone(), Move::Right),
34        (1, trans.clone(), 1, trans.clone(), Move::Right),
35        (1, zerofy.clone(), 1, zerofy.clone(), Move::Right),
36        (1, l_shift.clone(), 2, stand.clone(), Move::Left),
37        // Clear until r_shift
38        (2, zerofy.clone(), 2, stand.clone(), Move::Left),
39        (2, trans.clone(), 2, stand.clone(), Move::Left),
40        (2, r_shift.clone(), 3, r_shift.clone(), Move::Right),
41        //
42        // Set second r_shift
43        (3, stand.clone(), 4, r_shift.clone(), Move::Right),
44        // Set first trans
45        (4, stand.clone(), 5, trans.clone(), Move::Right),
46        // Set first zerofy
47        (5, stand.clone(), 6, zerofy.clone(), Move::Right),
48        // Set first l_shift
49        (6, stand.clone(), 7, l_shift.clone(), Move::Right),
50        // Set second trans
51        (7, stand.clone(), 8, trans.clone(), Move::Right),
52        // Set second zerofy
53        (8, stand.clone(), 9, zerofy.clone(), Move::Right),
54        // Set second l_shift and stop execution
55        (9, stand.clone(), 0, l_shift.clone(), Move::None),
56    ])?;
57
58    let hyper_machine = Classic::new(program, stand.clone())?;
59    let choose_second = Tape::new([
60        r_shift.clone(),
61        trans.clone(),
62        zerofy.clone(),
63        l_shift.clone(),
64    ]);
65    let result_choose_third = hyper_machine.translate_nrm(choose_second)?;
66
67    let expected_choose_third = Tape::new([
68        r_shift.clone(),
69        r_shift.clone(),
70        trans.clone(),
71        zerofy.clone(),
72        l_shift.clone(),
73        trans.clone(),
74        zerofy.clone(),
75        l_shift.clone(),
76    ]);
77
78    assert_eq!(expected_choose_third, result_choose_third);
79    println!("If you're reading this, hyper machine successful transform choose second machine");
80
81    let tape = Tape::from("0101101110");
82    let mut conf = Configuration::new_nrm(tape.clone())?;
83    for machine in result_choose_third.as_vec() {
84        conf = machine.execute(conf).unwrap();
85        conf.state = State(1)
86    }
87    println!(
88        "Choose third machine translate {} into {}",
89        String::from_iter(tape.as_vec()),
90        String::from_iter(conf.tape().as_vec())
91    );
92
93    Ok(())
94}
95
96// This module just contains several nrm machines
97mod nrm_machines {
98    use super::*;
99
100    pub fn new_stand_machine() -> Classic<char> {
101        let mut program = Program::new(vec!['0', '1'], State(1));
102        program
103            .extend([(1, '0', 0, '0', Move::None), (1, '1', 0, '1', Move::None)])
104            .unwrap();
105        Classic::new(program, '0').unwrap()
106    }
107
108    pub fn new_zerofy_machine() -> Classic<char> {
109        let mut program = Program::new(vec!['0', '1'], State(4));
110        program
111            .extend([
112                (1, '0', 2, '0', Move::Right),
113                (2, '0', 3, '0', Move::Left),
114                (2, '1', 2, '1', Move::Right),
115                (3, '0', 0, '0', Move::None),
116                (3, '1', 4, '0', Move::None),
117                (4, '0', 3, '0', Move::Left),
118            ])
119            .unwrap();
120        Classic::new(program, '0').unwrap()
121    }
122
123    pub fn new_left_shift_machine() -> Classic<char> {
124        let mut program = Program::new(vec!['0', '1'], State(2));
125        program
126            .extend([
127                (1, '0', 2, '0', Move::Left),
128                (2, '0', 0, '0', Move::None),
129                (2, '1', 2, '1', Move::Left),
130            ])
131            .unwrap();
132        Classic::new(program, '0').unwrap()
133    }
134
135    pub fn new_right_shift_machine() -> Classic<char> {
136        let mut program = Program::new(vec!['0', '1'], State(2));
137        program
138            .extend([
139                (1, '0', 2, '0', Move::Right),
140                (2, '0', 0, '0', Move::None),
141                (2, '1', 2, '1', Move::Right),
142            ])
143            .unwrap();
144        Classic::new(program, '0').unwrap()
145    }
146
147    pub fn new_trans_machine() -> Classic<char> {
148        let mut program = Program::new(vec!['0', '1'], State(19));
149        program
150            .extend([
151                (1, '0', 2, '0', Move::Right),
152                (2, '0', 3, '0', Move::None),
153                (2, '1', 2, '1', Move::Right),
154                (3, '0', 4, '0', Move::Left),
155                (4, '0', 7, '0', Move::None),
156                (4, '1', 5, '0', Move::None),
157                (5, '0', 6, '0', Move::Left),
158                (6, '0', 7, '1', Move::None),
159                (6, '1', 6, '1', Move::Left),
160                (7, '0', 16, '1', Move::None),
161                (7, '1', 8, '1', Move::Left),
162                (8, '0', 18, '0', Move::Right),
163                (8, '1', 9, '0', Move::None),
164                (9, '0', 10, '0', Move::Right),
165                (10, '0', 11, '1', Move::None),
166                (10, '1', 10, '1', Move::Right),
167                (11, '1', 12, '1', Move::Left),
168                (12, '1', 13, '0', Move::None),
169                (13, '0', 14, '0', Move::Left),
170                (14, '0', 15, '1', Move::None),
171                (14, '1', 14, '1', Move::Left),
172                (15, '0', 7, '0', Move::None),
173                (15, '1', 7, '1', Move::None),
174                (16, '1', 17, '1', Move::Left),
175                (17, '0', 19, '0', Move::Right),
176                (17, '1', 15, '0', Move::None),
177                (18, '0', 0, '0', Move::None),
178                (18, '1', 18, '1', Move::Right),
179                (19, '1', 0, '0', Move::None),
180            ])
181            .unwrap();
182        Classic::new(program, '0').unwrap()
183    }
184}