From e958ca68997fb33cfcd0951d0f4a96aacc5d47c2 Mon Sep 17 00:00:00 2001 From: Jason Staten Date: Wed, 30 May 2018 16:21:44 -0600 Subject: [PATCH 1/4] It computes! --- .gitignore | 2 + Cargo.lock | 4 ++ Cargo.toml | 6 +++ src/main.rs | 118 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 130 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 src/main.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..53eaa21 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/target +**/*.rs.bk diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..bdb4737 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,4 @@ +[[package]] +name = "rsturing" +version = "0.1.0" + diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..42112cd --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "rsturing" +version = "0.1.0" +authors = ["Jason Staten "] + +[dependencies] diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..d60f10b --- /dev/null +++ b/src/main.rs @@ -0,0 +1,118 @@ +type State = usize; + +#[derive(Debug, PartialEq, Clone)] +enum Cell { + Blank, + Zero, + One, +} + +#[derive(Debug)] +enum Move { + Stay, + Left, + Right, +} + +struct Transition { + start: State, + end: State, + read: Cell, + write: Cell, + operation: Move, +} + +struct Machine { + initial: State, + done: State, + transitions: Vec, +} + +type Tape = Vec; + +fn run(machine: Machine, code: Tape) -> Tape { + let mut position = 0; + let mut state = machine.initial; + let mut tape = code.to_vec(); + tape.resize(10, Cell::Blank); + + while state != machine.done { + let transition; + { + let cell = tape.get(position).unwrap_or(&Cell::Blank); + transition = machine + .transitions + .iter() + .find(|t| t.start == state && &t.read == cell) + .expect("Missing transition"); + } + state = transition.end; + tape[position] = transition.write.clone(); + position = match transition.operation { + Move::Left => position - 1, + Move::Right => position + 1, + Move::Stay => position, + }; + } + + return tape; +} + +#[test] +fn test_build() { + let machine = Machine { + initial: 0, + done: 2, + transitions: vec![ + Transition { + start: 0, + end: 0, + read: Cell::Zero, + write: Cell::Zero, + operation: Move::Right, + }, + Transition { + start: 0, + end: 0, + read: Cell::One, + write: Cell::One, + operation: Move::Right, + }, + Transition { + start: 0, + end: 1, + read: Cell::Blank, + write: Cell::Blank, + operation: Move::Left, + }, + Transition { + start: 1, + end: 1, + read: Cell::One, + write: Cell::Zero, + operation: Move::Left, + }, + Transition { + start: 1, + end: 2, + read: Cell::Zero, + write: Cell::One, + operation: Move::Stay, + }, + Transition { + start: 1, + end: 2, + read: Cell::Blank, + write: Cell::One, + operation: Move::Stay, + }, + ], + }; + + let result = run(machine, vec![Cell::One, Cell::One, Cell::Zero, Cell::One]); + println!("{:?}", result); + + let mut expected = vec![Cell::One, Cell::One, Cell::One, Cell::Zero]; + expected.resize(10, Cell::Blank); + assert_eq!(result, expected); +} From 559bd6c73d36c28a51ed235e425928dea0e5f720 Mon Sep 17 00:00:00 2001 From: Jason Staten Date: Wed, 30 May 2018 16:35:44 -0600 Subject: [PATCH 2/4] readme --- readme.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 readme.md diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..1d7758b --- /dev/null +++ b/readme.md @@ -0,0 +1,3 @@ +# Rust Turing Machine + +I made a turing machine when reading Impostor's Handbook From f7ce05f42a574fb07356a4945c66c3d14e6dbc1f Mon Sep 17 00:00:00 2001 From: Jason Staten Date: Wed, 30 May 2018 16:36:32 -0600 Subject: [PATCH 3/4] license --- LICENSE | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..8fcba53 --- /dev/null +++ b/LICENSE @@ -0,0 +1,16 @@ +ISC License (ISC) +Copyright (c) 2018, Jason Staten + +Permission to use, copy, modify, and/or distribute this software for +any purpose with or without fee is hereby granted, provided that the +above copyright notice and this permission notice appear in all +copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. From 73d027f8f7888d91cafdfc564a5126960cbfcc7b Mon Sep 17 00:00:00 2001 From: Jason Staten Date: Thu, 7 Jun 2018 23:17:47 -0600 Subject: [PATCH 4/4] Add finite state machine --- src/fsm.rs | 72 ++++++++++++++++++++++++++++++++++++++ src/lib.rs | 2 ++ src/{main.rs => turing.rs} | 0 3 files changed, 74 insertions(+) create mode 100644 src/fsm.rs create mode 100644 src/lib.rs rename src/{main.rs => turing.rs} (100%) diff --git a/src/fsm.rs b/src/fsm.rs new file mode 100644 index 0000000..bd15636 --- /dev/null +++ b/src/fsm.rs @@ -0,0 +1,72 @@ +#[derive(Debug, PartialEq, Copy, Clone)] +enum State { + Idle, + TimeInput, + Cook, + Pause, + Done, +} + +enum Event { + DigitPressed, + StopPressed, + StartPressed, + TimerElapsed, +} + +struct Microwave { + state: State, +} + +impl Microwave { + fn dispatch(&mut self, event: Event) { + use self::Event::*; + use self::State::*; + + self.state = match (self.state, event) { + (Idle, DigitPressed) => TimeInput, + (TimeInput, DigitPressed) => TimeInput, + (TimeInput, StartPressed) => Cook, + (TimeInput, StopPressed) => Idle, + (Cook, TimerElapsed) => Done, + (Cook, StopPressed) => Pause, + (Pause, StartPressed) => Cook, + (Pause, StopPressed) => Idle, + (Done, StopPressed) => Idle, + _ => self.state, + } + } +} + +#[test] +fn test_fsm() { + use self::Event::*; + use self::State::*; + + let mut mic = Microwave { state: Idle }; + // Punch in numbers + mic.dispatch(DigitPressed); + mic.dispatch(DigitPressed); + mic.dispatch(DigitPressed); + assert_eq!(mic.state, TimeInput); + + // Start microwave + mic.dispatch(StartPressed); + assert_eq!(mic.state, Cook); + + // Check if food is hot + mic.dispatch(StopPressed); + assert_eq!(mic.state, Pause); + + // Continue cooking + mic.dispatch(StartPressed); + assert_eq!(mic.state, Cook); + + // Timer finished + mic.dispatch(TimerElapsed); + assert_eq!(mic.state, Done); + + // Clear "done" message + mic.dispatch(StopPressed); + assert_eq!(mic.state, Idle); +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..30c96e0 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,2 @@ +pub mod fsm; +pub mod turing; diff --git a/src/main.rs b/src/turing.rs similarity index 100% rename from src/main.rs rename to src/turing.rs