rbtm 2.0.3
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 +7 -0
- data/bin/rbtm +49 -0
- data/bin/rbtm_rule +33 -0
- data/lib/rbtm.rb +37 -0
- data/lib/rbtm/head.rb +63 -0
- metadata +50 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 35b68522df47f8515925d555a836d3417cad65dd
|
|
4
|
+
data.tar.gz: e4c53e17100bf5ae40677ec24b9c6c39345d3734
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 5f4c3d8fd2ea001996f6eaeb29fc0896dade94ec88f377363756b66d87ab87ba4a2a0445a385fdf89f098d22fe4f2af706c424b9d82e3605a76fea9af25fe47c
|
|
7
|
+
data.tar.gz: bb8ca23db9178ad5e966f0625513323891b81349fd8b1c0016155cb24bcdfc211f60a189c4d28602ffd8fa95b3c29ed68123fdf44dbf248a59b0924a1d3fbff0
|
data/bin/rbtm
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
require 'rbtm'
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def stop(reason)
|
|
6
|
+
puts reason
|
|
7
|
+
exit
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
begin
|
|
12
|
+
rule = ARGV.fetch(0)
|
|
13
|
+
tape = ARGV.fetch(1)
|
|
14
|
+
rescue
|
|
15
|
+
stop('Usage: rbtm <rule> <tape> [-v]')
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
VERBOSE = ARGV[2].to_s.include?('v')
|
|
19
|
+
|
|
20
|
+
stop('Rule file does not exist.') unless File.exists?(rule)
|
|
21
|
+
|
|
22
|
+
if File.exists?(tape)
|
|
23
|
+
tape = File.read(tape).strip
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
rules, state = Rbtm.parse(rule)
|
|
27
|
+
stop('No valid rules.') if rules.empty?
|
|
28
|
+
head = Rbtm::Head.new(tape, state)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
if VERBOSE
|
|
32
|
+
print 'Seconds per frame? (default: 0.5) '
|
|
33
|
+
SLEEP_TIME = (num = $stdin.gets.to_f).zero? ? 0.5 : num
|
|
34
|
+
COLS = `tput cols`.to_i
|
|
35
|
+
|
|
36
|
+
system('clear')
|
|
37
|
+
Rbtm.turing_machine(rules, head) do |h|
|
|
38
|
+
first = (head.index / COLS) * COLS
|
|
39
|
+
puts "#{' ' * head.index}v"[first...(first + COLS)]
|
|
40
|
+
puts head.tape[first...(first + COLS)]
|
|
41
|
+
puts
|
|
42
|
+
puts head.state
|
|
43
|
+
sleep(SLEEP_TIME)
|
|
44
|
+
system('clear')
|
|
45
|
+
end
|
|
46
|
+
else
|
|
47
|
+
Rbtm.turing_machine(rules, head)
|
|
48
|
+
end
|
|
49
|
+
puts head
|
data/bin/rbtm_rule
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def stop(reason)
|
|
5
|
+
puts reason
|
|
6
|
+
exit
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
begin
|
|
11
|
+
file = ARGV.fetch(0)
|
|
12
|
+
rescue
|
|
13
|
+
stop('Usage: rbtm_rule <file>')
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
print 'States: '
|
|
18
|
+
states = $stdin.gets.split.uniq
|
|
19
|
+
|
|
20
|
+
print 'Alphabet: '
|
|
21
|
+
alphabet = $stdin.gets.strip.split(//).uniq
|
|
22
|
+
alphabet.map! { |c| c[0] }
|
|
23
|
+
|
|
24
|
+
File.open(file, 'w') do |f|
|
|
25
|
+
contents = ''
|
|
26
|
+
|
|
27
|
+
states.each do |s|
|
|
28
|
+
alphabet.each { |c| contents << "#{s}\t#{c}\n" }
|
|
29
|
+
contents << "\n"
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
f.write(contents)
|
|
33
|
+
end
|
data/lib/rbtm.rb
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
module Rbtm
|
|
2
|
+
|
|
3
|
+
##
|
|
4
|
+
# Regexp for matching rules.
|
|
5
|
+
REGEX = /\s*(\w+)\s+(\w)\s+(\w+)\s+(\w)\s+([LNR])/
|
|
6
|
+
|
|
7
|
+
##
|
|
8
|
+
# Parses rules and start state from a file.
|
|
9
|
+
def self.parse(file)
|
|
10
|
+
rules = {}
|
|
11
|
+
state = nil
|
|
12
|
+
|
|
13
|
+
File.readlines(file).each do |line|
|
|
14
|
+
next unless line =~ REGEX
|
|
15
|
+
|
|
16
|
+
state ||= $1
|
|
17
|
+
rules[[$1, $2]] = [$3, $4, $5]
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
[rules, state]
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
##
|
|
24
|
+
# Runs a Turing machine. Yields current head if given a block.
|
|
25
|
+
def self.turing_machine(rules, head)
|
|
26
|
+
loop do
|
|
27
|
+
rule = rules[head.signature]
|
|
28
|
+
|
|
29
|
+
yield head if block_given?
|
|
30
|
+
break unless rule
|
|
31
|
+
|
|
32
|
+
head.operate(rule)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
require 'rbtm/head'
|
data/lib/rbtm/head.rb
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
module Rbtm
|
|
2
|
+
|
|
3
|
+
##
|
|
4
|
+
# The read/write head of the Turing machine.
|
|
5
|
+
class Head
|
|
6
|
+
attr_reader :index, :state, :tape
|
|
7
|
+
|
|
8
|
+
def initialize(str, state)
|
|
9
|
+
@tape = (str.empty? ? '_' : str.dup)
|
|
10
|
+
@state = state
|
|
11
|
+
@index = 0
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
##
|
|
15
|
+
# Operates on the tape using the given rule.
|
|
16
|
+
def operate(rule)
|
|
17
|
+
@state = rule[0]
|
|
18
|
+
write(rule[1])
|
|
19
|
+
|
|
20
|
+
case rule[2]
|
|
21
|
+
when 'L'
|
|
22
|
+
left
|
|
23
|
+
when 'R'
|
|
24
|
+
right
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def signature
|
|
29
|
+
[state, read]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def to_s
|
|
33
|
+
tape.sub(/^_+/, '').sub(/_+$/, '')
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
def left
|
|
39
|
+
if index.zero?
|
|
40
|
+
pad
|
|
41
|
+
else
|
|
42
|
+
@index -= 1
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def pad
|
|
47
|
+
tape.insert(index, '_')
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def read
|
|
51
|
+
tape[index]
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def right
|
|
55
|
+
@index += 1
|
|
56
|
+
pad if index == tape.size
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def write(char)
|
|
60
|
+
tape[index] = char
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: rbtm
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 2.0.3
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- loatbac
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2016-06-23 00:00:00.000000000 Z
|
|
12
|
+
dependencies: []
|
|
13
|
+
description: A simple Turing machine gem for Ruby; type "rbtm" in bash to run, or
|
|
14
|
+
"rbtm_rule" to generate a rule template.
|
|
15
|
+
email:
|
|
16
|
+
executables:
|
|
17
|
+
- rbtm
|
|
18
|
+
- rbtm_rule
|
|
19
|
+
extensions: []
|
|
20
|
+
extra_rdoc_files: []
|
|
21
|
+
files:
|
|
22
|
+
- bin/rbtm
|
|
23
|
+
- bin/rbtm_rule
|
|
24
|
+
- lib/rbtm.rb
|
|
25
|
+
- lib/rbtm/head.rb
|
|
26
|
+
homepage: https://github.com/LoaTBaC/rbtm
|
|
27
|
+
licenses:
|
|
28
|
+
- MIT
|
|
29
|
+
metadata: {}
|
|
30
|
+
post_install_message:
|
|
31
|
+
rdoc_options: []
|
|
32
|
+
require_paths:
|
|
33
|
+
- lib
|
|
34
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
35
|
+
requirements:
|
|
36
|
+
- - ">="
|
|
37
|
+
- !ruby/object:Gem::Version
|
|
38
|
+
version: '0'
|
|
39
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
40
|
+
requirements:
|
|
41
|
+
- - ">="
|
|
42
|
+
- !ruby/object:Gem::Version
|
|
43
|
+
version: '0'
|
|
44
|
+
requirements: []
|
|
45
|
+
rubyforge_project:
|
|
46
|
+
rubygems_version: 2.6.4
|
|
47
|
+
signing_key:
|
|
48
|
+
specification_version: 4
|
|
49
|
+
summary: A simple Turing machine for Ruby
|
|
50
|
+
test_files: []
|