turing_machine 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +6 -2
- data/bin/turing_machine +6 -2
- data/instruction_sets/copy +10 -0
- data/lib/turing_machine.rb +1 -0
- data/lib/turing_machine/command_line_parser.rb +43 -0
- data/lib/turing_machine/instance.rb +2 -2
- data/lib/turing_machine/tape.rb +13 -10
- data/lib/turing_machine/version.rb +1 -1
- data/spec/command_line_parser_spec.rb +25 -0
- data/spec/instance_spec.rb +10 -10
- data/spec/tape_spec.rb +43 -9
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 69b723c3c3b1fa44ff2c610c31427d78d671f3af
|
4
|
+
data.tar.gz: 450138ddef11a944e89ef4b7fe59cd1ba022c56f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d0243d15028a9223ca6dce3ba47ee9e3ac2c47fe6e444d0415052bb7626ad9ed84bbcbdf75d00fe8afac833a8af3e5396e5b83eec2c87fe02d381b0a2e6a1c44
|
7
|
+
data.tar.gz: c9d9e26a2b25ed0bba74acf8ddbee1893b934a262fa4557f4da4d87a312529c769c2b725d7a8f3ea3e8a68944da937520862b78edb6563d5c894560b8cf304a9
|
data/README.md
CHANGED
@@ -21,9 +21,13 @@ or create your own. Then run the Turing machine with, for example:
|
|
21
21
|
|
22
22
|
$ turing_machine instruction_sets/busy_beaver_1
|
23
23
|
|
24
|
-
|
24
|
+
To initialize the tape with some data, use `--tape`:
|
25
|
+
|
26
|
+
$ turing_machine instruction_sets/copy --tape 111
|
27
|
+
|
28
|
+
Finally, look at the
|
25
29
|
[InstructionsParser class](lib/turing_machine/instructions_parser.rb) for a
|
26
|
-
documentation of the instruction format.
|
30
|
+
documentation of the instruction format if you want to write your own.
|
27
31
|
|
28
32
|
## Contributing
|
29
33
|
|
data/bin/turing_machine
CHANGED
@@ -4,8 +4,12 @@ require 'turing_machine'
|
|
4
4
|
|
5
5
|
include TuringMachine
|
6
6
|
|
7
|
+
cli_parser = CommandLineParser.new(ARGV)
|
8
|
+
options = cli_parser.parse
|
9
|
+
|
7
10
|
if ARGV[0].nil?
|
8
|
-
|
11
|
+
puts cli_parser.help
|
12
|
+
exit
|
9
13
|
else
|
10
14
|
filename = ARGV[0]
|
11
15
|
end
|
@@ -21,7 +25,7 @@ instructions = parser.parse
|
|
21
25
|
|
22
26
|
initial_state = 'A'
|
23
27
|
|
24
|
-
instance = Instance.new(instructions, initial_state)
|
28
|
+
instance = Instance.new(instructions, initial_state, Tape.new(options.tape))
|
25
29
|
|
26
30
|
# This should be testable.
|
27
31
|
loop do
|
data/lib/turing_machine.rb
CHANGED
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require 'ostruct'
|
3
|
+
|
4
|
+
module TuringMachine
|
5
|
+
|
6
|
+
class CommandLineParser
|
7
|
+
|
8
|
+
def initialize(args)
|
9
|
+
@args = args
|
10
|
+
@options = OpenStruct.new
|
11
|
+
@options.tape = '0'
|
12
|
+
|
13
|
+
@opt_parser = OptionParser.new do |opts|
|
14
|
+
opts.banner = "Usage: turing_machine instruction_set [options]"
|
15
|
+
|
16
|
+
opts.on("-t", "--tape DATA", "Initialize the tape with DATA") do |data|
|
17
|
+
@options.tape = data
|
18
|
+
end
|
19
|
+
|
20
|
+
opts.on_tail("-h", "--help", "Show this message") do
|
21
|
+
puts opts
|
22
|
+
exit
|
23
|
+
end
|
24
|
+
|
25
|
+
opts.on_tail("--version", "Show version") do
|
26
|
+
puts VERSION
|
27
|
+
exit
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def parse
|
33
|
+
@opt_parser.parse!(@args)
|
34
|
+
@options
|
35
|
+
end
|
36
|
+
|
37
|
+
def help
|
38
|
+
@opt_parser.help
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
@@ -3,10 +3,10 @@ module TuringMachine
|
|
3
3
|
# Public: An instance of a Turing machine.
|
4
4
|
class Instance
|
5
5
|
|
6
|
-
def initialize(instructions, initial_state)
|
6
|
+
def initialize(instructions, initial_state, tape = Tape.new)
|
7
7
|
@instructions = Instructions.new(instructions)
|
8
8
|
@state = StateRegister.new(initial_state)
|
9
|
-
@tape =
|
9
|
+
@tape = tape
|
10
10
|
@sequence = 1
|
11
11
|
end
|
12
12
|
|
data/lib/turing_machine/tape.rb
CHANGED
@@ -3,19 +3,15 @@ module TuringMachine
|
|
3
3
|
# Public: The tape of a Turing machine, combined with the head.
|
4
4
|
class Tape
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
@symbols =
|
10
|
-
@index =
|
6
|
+
BLANK_SYMBOL = '0'
|
7
|
+
|
8
|
+
def initialize(data = BLANK_SYMBOL)
|
9
|
+
@symbols = data.scan(/./)
|
10
|
+
@index = 0
|
11
11
|
end
|
12
12
|
|
13
13
|
attr_reader :index
|
14
14
|
|
15
|
-
# def size
|
16
|
-
# @symbols.size
|
17
|
-
# end
|
18
|
-
|
19
15
|
def head
|
20
16
|
@symbols[@index]
|
21
17
|
end
|
@@ -24,11 +20,18 @@ module TuringMachine
|
|
24
20
|
@symbols[@index] = symbol
|
25
21
|
end
|
26
22
|
|
23
|
+
# Public: Move the head to the left.
|
27
24
|
def shift_left
|
28
|
-
@index
|
25
|
+
if @index == 0
|
26
|
+
@symbols.unshift(BLANK_SYMBOL)
|
27
|
+
else
|
28
|
+
@index -= 1
|
29
|
+
end
|
29
30
|
end
|
30
31
|
|
32
|
+
# Public: Move the head to the right.
|
31
33
|
def shift_right
|
34
|
+
@symbols.push(BLANK_SYMBOL) if @index == @symbols.size - 1
|
32
35
|
@index += 1
|
33
36
|
end
|
34
37
|
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
include TuringMachine
|
4
|
+
|
5
|
+
describe CommandLineParser do
|
6
|
+
|
7
|
+
it 'parses -t' do
|
8
|
+
cli_parser = CommandLineParser.new %w( -t 11011 )
|
9
|
+
options = cli_parser.parse
|
10
|
+
expect(options.tape).to eq '11011'
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'parses --tape' do
|
14
|
+
cli_parser = CommandLineParser.new %w( --tape 101 )
|
15
|
+
options = cli_parser.parse
|
16
|
+
expect(options.tape).to eq '101'
|
17
|
+
end
|
18
|
+
|
19
|
+
specify 'tape default value' do
|
20
|
+
cli_parser = CommandLineParser.new []
|
21
|
+
options = cli_parser.parse
|
22
|
+
expect(options.tape).to eq '0'
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
data/spec/instance_spec.rb
CHANGED
@@ -16,16 +16,16 @@ initial_state = 'A'
|
|
16
16
|
describe Instance do
|
17
17
|
it 'produces an output' do
|
18
18
|
instance = Instance.new(instructions, initial_state)
|
19
|
-
expected = " 1
|
20
|
-
"
|
19
|
+
expected = " 1 0 A -> 1RB\n" +
|
20
|
+
" ^"
|
21
21
|
expect(instance.to_s).to eq expected
|
22
22
|
end
|
23
23
|
|
24
24
|
it 'computes a step' do
|
25
25
|
instance = Instance.new(instructions, initial_state)
|
26
26
|
instance.proceed
|
27
|
-
expected = " 2
|
28
|
-
"
|
27
|
+
expected = " 2 10 B -> 1LA\n" +
|
28
|
+
" ^"
|
29
29
|
expect(instance.to_s).to eq expected
|
30
30
|
end
|
31
31
|
|
@@ -36,8 +36,8 @@ describe Instance do
|
|
36
36
|
}
|
37
37
|
instance = Instance.new(instructions, initial_state)
|
38
38
|
instance.proceed
|
39
|
-
expected = " 2
|
40
|
-
"
|
39
|
+
expected = " 2 1 HALT\n" +
|
40
|
+
" ^"
|
41
41
|
expect(instance.to_s).to eq expected
|
42
42
|
end
|
43
43
|
end
|
@@ -49,8 +49,8 @@ describe Instance do
|
|
49
49
|
}
|
50
50
|
instance = Instance.new(instructions, initial_state)
|
51
51
|
instance.proceed
|
52
|
-
expected = " 2
|
53
|
-
"
|
52
|
+
expected = " 2 0 HALT\n" +
|
53
|
+
" ^"
|
54
54
|
expect(instance.to_s).to eq expected
|
55
55
|
|
56
56
|
end
|
@@ -74,8 +74,8 @@ describe Instance do
|
|
74
74
|
}
|
75
75
|
instance = Instance.new(instructions, initial_state)
|
76
76
|
instance.proceed
|
77
|
-
expected = " 2
|
78
|
-
"
|
77
|
+
expected = " 2 10 HALT\n" +
|
78
|
+
" ^"
|
79
79
|
expect(instance.to_s).to eq expected
|
80
80
|
end
|
81
81
|
|
data/spec/tape_spec.rb
CHANGED
@@ -8,12 +8,17 @@ describe Tape do
|
|
8
8
|
|
9
9
|
describe '.new' do
|
10
10
|
|
11
|
-
# it 'has a single cell' do
|
12
|
-
# expect(tape.size).to eq 1
|
13
|
-
# end
|
14
|
-
|
15
11
|
it 'has a initial current symbol of "0"' do
|
16
|
-
expect(tape.head).to eq
|
12
|
+
expect(tape.head).to eq Tape::BLANK_SYMBOL
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'takes optional data as an argument' do
|
16
|
+
tape_with_data = Tape.new('101')
|
17
|
+
expect(tape_with_data.index).to eq 0
|
18
|
+
tape_with_data.shift_right
|
19
|
+
expect(tape_with_data.head).to eq '0'
|
20
|
+
tape_with_data.shift_right
|
21
|
+
expect(tape_with_data.head).to eq '1'
|
17
22
|
end
|
18
23
|
|
19
24
|
end
|
@@ -32,19 +37,48 @@ describe Tape do
|
|
32
37
|
it 'moves to the cell to the left' do
|
33
38
|
tape.head = '1'
|
34
39
|
tape.shift_left
|
35
|
-
expect(tape.head).to eq
|
40
|
+
expect(tape.head).to eq Tape::BLANK_SYMBOL
|
36
41
|
end
|
37
42
|
|
38
43
|
it 'moves to the cell to the right' do
|
39
44
|
tape.head = '1'
|
40
45
|
tape.shift_right
|
41
|
-
expect(tape.head).to eq
|
46
|
+
expect(tape.head).to eq Tape::BLANK_SYMBOL
|
47
|
+
end
|
48
|
+
|
49
|
+
specify do
|
50
|
+
tape.shift_left
|
51
|
+
tape.shift_right
|
52
|
+
tape.shift_left
|
53
|
+
expect("#{tape}").to eq Tape::BLANK_SYMBOL * 2
|
42
54
|
end
|
43
55
|
|
44
56
|
end
|
45
57
|
|
46
|
-
|
47
|
-
|
58
|
+
describe 'string representation' do
|
59
|
+
|
60
|
+
context 'default initialization' do
|
61
|
+
it 'has a representation' do
|
62
|
+
expect("#{tape}").to eq Tape::BLANK_SYMBOL
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context 'after left move' do
|
67
|
+
it 'has a representation' do
|
68
|
+
tape.head = '1'
|
69
|
+
tape.shift_left
|
70
|
+
expect("#{tape}").to eq Tape::BLANK_SYMBOL + '1'
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context 'after right move' do
|
75
|
+
it 'has a representation' do
|
76
|
+
tape.head = '1'
|
77
|
+
tape.shift_right
|
78
|
+
expect("#{tape}").to eq '1' + Tape::BLANK_SYMBOL
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
48
82
|
end
|
49
83
|
|
50
84
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: turing_machine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Xavier Nayrac
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-02-
|
11
|
+
date: 2015-02-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -118,15 +118,18 @@ files:
|
|
118
118
|
- instruction_sets/busy_beaver_3
|
119
119
|
- instruction_sets/busy_beaver_3-2
|
120
120
|
- instruction_sets/busy_beaver_4
|
121
|
+
- instruction_sets/copy
|
121
122
|
- instruction_sets/copy_with_data
|
122
123
|
- instruction_sets/write101
|
123
124
|
- lib/turing_machine.rb
|
125
|
+
- lib/turing_machine/command_line_parser.rb
|
124
126
|
- lib/turing_machine/instance.rb
|
125
127
|
- lib/turing_machine/instructions.rb
|
126
128
|
- lib/turing_machine/instructions_parser.rb
|
127
129
|
- lib/turing_machine/state_register.rb
|
128
130
|
- lib/turing_machine/tape.rb
|
129
131
|
- lib/turing_machine/version.rb
|
132
|
+
- spec/command_line_parser_spec.rb
|
130
133
|
- spec/instance_spec.rb
|
131
134
|
- spec/instructions_parser_spec.rb
|
132
135
|
- spec/instructions_spec.rb
|
@@ -160,6 +163,7 @@ signing_key:
|
|
160
163
|
specification_version: 4
|
161
164
|
summary: A Turing machine
|
162
165
|
test_files:
|
166
|
+
- spec/command_line_parser_spec.rb
|
163
167
|
- spec/instance_spec.rb
|
164
168
|
- spec/instructions_parser_spec.rb
|
165
169
|
- spec/instructions_spec.rb
|