automata 0.1.0 → 1.0.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.
data/.gitignore CHANGED
@@ -15,3 +15,6 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
+ *.sublime-project
19
+ *.sublime-workspace
20
+ *.tmproj
data/README.md CHANGED
@@ -39,26 +39,24 @@ We can easily define a machine's _n_-tuples in a YAML file. For example, let's c
39
39
  - C
40
40
  - D
41
41
  alphabet:
42
- - '0'
43
- - '1'
42
+ - 0
43
+ - 1
44
44
  start: A
45
45
  accept:
46
46
  - C
47
47
  transitions:
48
48
  A:
49
- '0': B
50
- '1': D
49
+ 0: B
50
+ 1: D
51
51
  B:
52
- '0': C
53
- '1': D
52
+ 0: C
53
+ 1: D
54
54
  C:
55
- '0': C
56
- '1': C
55
+ 0: C
56
+ 1: C
57
57
  D:
58
- '0': D
59
- '1': D
60
-
61
- __Note:__ Integer hash keys are currently unsupported, hence they must be wrapped in quotes.
58
+ 0: D
59
+ 1: D
62
60
 
63
61
  With our machine defined, we can create a new DFA object from the file.
64
62
 
@@ -87,11 +85,11 @@ Now that we've built a machine, we can pass it input and let it work its magic.
87
85
  >> dfa.accepts? '0101'
88
86
  => false
89
87
 
90
- Awesomesauce.
88
+ Awesomesauce. Please refer to the [wiki](https://github.com/jico/automata/wiki "automata wiki") for more details.
91
89
 
92
90
  ## Special Characters
93
91
 
94
- * _&_ - Represents an ε-transition (epsilon transition)
92
+ * _&_ - Represents an ε-transition (epsilon transition). Note that you must wrap the symbol in quotes.
95
93
 
96
94
  ## Contributing
97
95
 
@@ -2,7 +2,7 @@
2
2
  require File.expand_path('../lib/automata/version', __FILE__)
3
3
 
4
4
  Gem::Specification.new do |gem|
5
- gem.authors = ["Jico Baligod"]
5
+ gem.authors = ["Jico Baligod", "Lukas Sabota"]
6
6
  gem.email = ["jico@baligod.com"]
7
7
  gem.description = %q{Create and simulate automaton.}
8
8
  gem.summary = %q{This gem provides a number of classes to create and simulate Deterministic/Nondeterministic Finite Automata, Push-down Automata, and Turing Machines.}
@@ -0,0 +1,38 @@
1
+ ## # Sample PDA file.
2
+ #
3
+ # Accepts balanced parentheses only.
4
+ #
5
+ # '@' to represent delta
6
+ # 'ACCEPT' to represent unique, single start state
7
+ states:
8
+ - S
9
+ - A
10
+ - B
11
+ - ha
12
+ alphabet:
13
+ - '('
14
+ - ')'
15
+ start: S
16
+ accept: ha
17
+ transitions:
18
+ S:
19
+ '&':
20
+ to: 'A'
21
+ push: '@'
22
+ A:
23
+ '(':
24
+ to: 'A'
25
+ push: 'x'
26
+ ')':
27
+ to: 'B'
28
+ pop: 'x'
29
+ B:
30
+ '(':
31
+ to: 'A'
32
+ push: 'x'
33
+ ')':
34
+ to: 'B'
35
+ pop: 'x'
36
+ '&':
37
+ to: 'ha'
38
+ pop: '@'
@@ -0,0 +1,49 @@
1
+ ##
2
+ # Sample TM build file
3
+ #
4
+ # Accepts all binary strings containing
5
+ # the substring 101.
6
+ #
7
+ # Notes:
8
+ # '@' denotes the blank for the tape alphabet
9
+ # 'ACCEPT' denotes unique accept state (include in transition)
10
+ # 'REJECT' denotes unique reject state (include in transition)
11
+ states:
12
+ - A
13
+ - B
14
+ - C
15
+ inputAlphabet:
16
+ - 0
17
+ - 1
18
+ tapeAlphabet:
19
+ - 0
20
+ - 1
21
+ start: A
22
+ transitions:
23
+ A:
24
+ 0:
25
+ to: A
26
+ write: 0
27
+ move: R
28
+ 1:
29
+ to: B
30
+ write: 1
31
+ move: R
32
+ B:
33
+ 1:
34
+ to: B
35
+ write: 1
36
+ move: R
37
+ 0:
38
+ to: C
39
+ write: 0
40
+ move: R
41
+ C:
42
+ 1:
43
+ to: ACCEPT
44
+ write: 1
45
+ move: R
46
+ 0:
47
+ to: A
48
+ write: 0
49
+ move: R
@@ -3,6 +3,8 @@ require 'yaml'
3
3
  require "automata/state_diagram"
4
4
  require "automata/dfa"
5
5
  require "automata/nfa"
6
+ require "automata/pda"
7
+ require "automata/turing"
6
8
 
7
9
  module Automata
8
10
 
@@ -18,4 +20,4 @@ class Hash
18
20
  obj = obj.inject({}){|h,(k,v)| h[k.to_s] = Hash.keys_to_strings(v); h}
19
21
  return obj
20
22
  end
21
- end
23
+ end
@@ -18,14 +18,33 @@ module Automata
18
18
  return true
19
19
  end
20
20
 
21
+ # Runs the input on the machine and returns a Hash describing
22
+ # the machine's final state after running.
23
+ #
24
+ # @param [String] input the string to use as input for the DFA
25
+ # @return [Hash] a hash describing the DFA state after running
26
+ # * :input [String] the original input string
27
+ # * :accept [Boolean] whether or not the DFA accepted the string
28
+ # * :head [String] the state which the head is currently on
29
+ def feed(input)
30
+ head = @start.to_s
31
+ input.each_char { |symbol| head = @transitions[head][symbol] }
32
+ accept = is_accept_state? head
33
+ resp = {
34
+ input: input,
35
+ accept: accept,
36
+ head: head
37
+ }
38
+ resp
39
+ end
40
+
21
41
  # Determines whether the DFA accepts a given string.
22
42
  #
23
43
  # @param [String] input the string to use as input for the DFA.
24
44
  # @return [Boolean] whether or not the DFA accepts the string.
25
45
  def accepts?(input)
26
- head = @start.to_s
27
- input.each_char { |symbol| head = @transitions[head][symbol] }
28
- is_accept_state? head
46
+ resp = feed(input)
47
+ resp[:accept]
29
48
  end
30
49
 
31
50
  # Determines if a given state is an accept state.
@@ -5,11 +5,15 @@ module Automata
5
5
  # Iterate through each states to verify the graph
6
6
  # is not disjoint.
7
7
 
8
- # Determines whether the NFA accepts a given string.
8
+ # Runs the input on the machine and returns a Hash describing
9
+ # the machine's final state after running.
9
10
  #
10
- # @param [String] input the string to use as input for the NFA.
11
- # @return [Boolean] Whether or not the NFA accepts the input string.
12
- def accepts?(input)
11
+ # @param [String] input the string to use as input for the NFA
12
+ # @return [Hash] a hash describing the NFA state after running
13
+ # * :input [String] the original input string
14
+ # * :accept [Boolean] whether or not the NFA accepted the string
15
+ # * :heads [Array] the state which the head is currently on
16
+ def feed(input)
13
17
  heads = [@start]
14
18
 
15
19
  # Move any initial e-transitions
@@ -41,8 +45,23 @@ module Automata
41
45
  break if heads.empty?
42
46
  end
43
47
 
44
- heads.each { |head| return true if accept_state? head }
45
- false
48
+ accept = false
49
+ heads.each { |head| accept = true if accept_state? head }
50
+
51
+ resp = {
52
+ input: input,
53
+ accept: accept,
54
+ heads: heads
55
+ }
56
+ end
57
+
58
+ # Determines whether the NFA accepts a given string.
59
+ #
60
+ # @param [String] input the string to use as input for the NFA.
61
+ # @return [Boolean] Whether or not the NFA accepts the input string.
62
+ def accepts?(input)
63
+ resp = feed(input)
64
+ resp[:accept]
46
65
  end
47
66
 
48
67
  # Determines the transition states, if any, from a given
@@ -0,0 +1,159 @@
1
+ module Automata
2
+ # Push Down Automata
3
+ class PDA < NFA
4
+ attr_accessor :stack
5
+
6
+ # Initialize a PDA object.
7
+ def initialize(params={})
8
+ super(params)
9
+ @alphabet << '&' unless !@alphabet || @alphabet.include?('&')
10
+ @stack = []
11
+ end
12
+
13
+ # Runs the input on the machine and returns a Hash describing
14
+ # the machine's final state after running.
15
+ #
16
+ # @param [String] input the string to use as input for the PDA
17
+ # @return [Hash] a hash describing the PDA state after running
18
+ # * :input [String] the original input string
19
+ # * :accept [Boolean] whether or not the PDA accepted the string
20
+ # * :heads [Array] the state which the head is currently on
21
+ def feed(input)
22
+ heads, @stack, accept = [@start], [], false
23
+
24
+ # Move any initial e-transitions
25
+ eTrans = transition(@start, '&') if has_transition?(@start, '&')
26
+ heads += eTrans
27
+
28
+ puts "initial heads: #{heads}"
29
+ puts "initial stack: #{@stack}"
30
+
31
+ # Iterate through each symbol of input string
32
+ input.each_char do |symbol|
33
+ newHeads = []
34
+
35
+ puts "Reading symbol: #{symbol}"
36
+
37
+ heads.each do |head|
38
+ puts "At head #{head}"
39
+
40
+ # Check if head can transition read symbol
41
+ # Head dies if no transition for symbol
42
+ if has_transition?(head, symbol)
43
+ puts "Head #{head} transitions #{symbol}"
44
+ puts "stack: #{@stack}"
45
+ transition(head, symbol).each { |t| newHeads << t }
46
+ puts "heads: #{newHeads}"
47
+ puts "stack: #{@stack}"
48
+ end
49
+
50
+ end
51
+
52
+ heads = newHeads
53
+ break if heads.empty?
54
+ end
55
+
56
+ puts "Loop finished"
57
+
58
+ accept = includes_accept_state? heads
59
+
60
+ puts "heads: #{heads}"
61
+ puts "stack: #{stack}"
62
+ puts "accept: #{accept}"
63
+
64
+ resp = {
65
+ input: input,
66
+ accept: accept,
67
+ heads: heads,
68
+ stack: stack
69
+ }
70
+ end
71
+
72
+
73
+ # Determines whether the PDA accepts a given string.
74
+ #
75
+ # This method is intended to override the parent accepts method.
76
+ #
77
+ # @param [String] input the string to use as input for PDA.
78
+ # @return [Boolean] whether or not the PDA accepts the string.
79
+ def accepts?(input)
80
+ resp = feed(input)
81
+ resp[:accept]
82
+ end
83
+
84
+ # Determines the transition states, if any, from a given
85
+ # beginning state and input symbol pair.
86
+ #
87
+ # @param [String] state state label for beginning state.
88
+ # @param [String] symbol input symbol.
89
+ # @return [Array] Array of destination transition states.
90
+ def transition(state, symbol, stackTop=nil)
91
+ dests = []
92
+
93
+ if has_transition?(state, symbol)
94
+ actions = @transitions[state][symbol]
95
+ stackTop ||= @stack.last
96
+ able = true
97
+ @stack.push actions['push'] if actions['push']
98
+ if actions['pop']
99
+ able = false unless stackTop == actions['pop']
100
+ @stack.pop if able
101
+ end
102
+ if able
103
+ dests << actions['to']
104
+
105
+ if has_transition?(actions['to'], '&')
106
+ actions = @transitions[actions['to']]['&']
107
+ able = true
108
+ @stack.push actions['push'] if actions['push']
109
+ if actions['pop']
110
+ able = false unless @stack.last == actions['pop']
111
+ @stack.pop if able
112
+ end
113
+ if able
114
+ dests << actions['to']
115
+ end
116
+ end
117
+ dests
118
+ else
119
+ return dests
120
+ end
121
+ else
122
+ return []
123
+ end
124
+ end
125
+
126
+ def pop?(symbol)
127
+ @stack.last == symbol
128
+ end
129
+
130
+ # Determines whether or not any transition states exist
131
+ # given a beginning state and input symbol pair.
132
+ #
133
+ # @param (see #transition)
134
+ # @return [Boolean] Whether or not a transition exists.
135
+ def has_transition?(state, symbol)
136
+ return false unless @transitions.has_key? state
137
+ if @transitions[state].has_key? symbol
138
+ actions = @transitions[state][symbol]
139
+ return false if actions['pop'] && @stack.last != actions['pop']
140
+ return true
141
+ else
142
+ return false
143
+ end
144
+ end
145
+
146
+ # Determines if a given state is an accept state.
147
+ #
148
+ # @param [String] state the state label to check.
149
+ # @return [Boolean] whether or not the state is an accept state.
150
+ def accept_state?(state)
151
+ @accept.include? state
152
+ end
153
+
154
+ def includes_accept_state?(states)
155
+ states.each { |s| return true if accept_state? s }
156
+ return false
157
+ end
158
+ end
159
+ end
@@ -0,0 +1,157 @@
1
+ module Automata
2
+ # Turing Machine
3
+ class Turing < StateDiagram
4
+ attr_accessor :inputAlphabet, :tapeAlphabet, :tape, :reject
5
+
6
+ # @todo Check that each state is connected.
7
+ # Iterate through each states to verify the graph
8
+ # is not disjoint.
9
+
10
+ def initialize(params={})
11
+ yaml = {}
12
+ yaml = YAML::load_file(params[:file]) if params.has_key? :file
13
+ super(params)
14
+ @inputAlphabet = params[:inputAlphabet] || yaml['inputAlphabet']
15
+ @tapeAlphabet = params[:tapeAlphabet] || yaml['tapeAlphabet']
16
+ @tape = Tape.new
17
+ @accept = false
18
+ @reject = false
19
+ end
20
+
21
+ # Runs the input on the turing machine and returns a Hash describing
22
+ # the machine's final state after running.
23
+ #
24
+ # @param [String] input the string to use as input/tape for the TM
25
+ # @return [Hash] a hash describing the TM state after running
26
+ # * :input [String] the original input string
27
+ # * :accept [Boolean] whether or not the TM halted in an accept state
28
+ # * :reject [Boolean] whether or not the TM halted in a reject state
29
+ # * :head [String] the state which the head halted
30
+ # * :tape [String] the resulting tape string
31
+ def feed(input)
32
+ @tape = Tape.new(input)
33
+ @accept = false
34
+ @reject = false
35
+
36
+ stateHead = @start.to_s
37
+ input.each_char do |symbol|
38
+ toState = transition(stateHead, symbol)
39
+ if @accept || @reject
40
+ break
41
+ else
42
+ stateHead = toState
43
+ end
44
+ end
45
+
46
+ resp = {
47
+ input: input,
48
+ accept: @accept,
49
+ reject: @reject,
50
+ head: stateHead,
51
+ tape: @tape.memory,
52
+ output: @tape.output
53
+ }
54
+ resp
55
+ end
56
+
57
+ # Determines whether the TM halts in an accept state.
58
+ #
59
+ # @param [String] input the string to use as input for the TM.
60
+ # @return [Boolean] Whether or not the TM accepts the input string.
61
+ def accepts?(input)
62
+ resp = feed(input)
63
+ resp[:accept]
64
+ end
65
+
66
+ # Determines whether the TM halts in an reject state.
67
+ #
68
+ # @param [String] input the string to use as input for the TM.
69
+ # @return [Boolean] Whether or not the TM rejects the input string.
70
+ def rejects?(input)
71
+ resp = feed(input)
72
+ resp[:reject]
73
+ end
74
+
75
+ # Determines the transition states, if any, from a given
76
+ # beginning state and input symbol pair.
77
+ #
78
+ # @note Turing machines have two unique states:
79
+ # * +ACCEPT+ Unique accept state
80
+ # * +REJECT+ Unique reject state
81
+ # @param [String] state state label for beginning state.
82
+ # @param [String] symbol input symbol.
83
+ # @return [Array] Array of destination transition states.
84
+ def transition(state, symbol)
85
+ actions = @transitions[state][symbol]
86
+ @tape.transition(symbol, actions['write'], actions['move'])
87
+
88
+ # Flip the bits for halting states
89
+ @accept = true if actions['to'] == 'ACCEPT'
90
+ @reject = true if actions['to'] == 'REJECT'
91
+ @head = actions['to']
92
+ end
93
+
94
+ # Determines whether or not any transition states exist
95
+ # given a beginning state and input symbol pair.
96
+ #
97
+ # @param (see #transition)
98
+ # @return [Boolean] Whether or not a transition exists.
99
+ def has_transition?(state, read)
100
+ return false unless @transitions.include? state
101
+ @transitions[state].has_key? read
102
+ end
103
+
104
+ end
105
+
106
+ # Turing Machine tape
107
+ class Tape
108
+ attr_accessor :memory
109
+
110
+ # Creates a new tape.
111
+ #
112
+ # @param [String] string the input string
113
+ def initialize(string=nil)
114
+ if string
115
+ @memory = []
116
+ @memory << '@' unless string[0] == '@'
117
+ @memory += string.split('')
118
+ @memory << '@' unless string[-1] == '@'
119
+ @head = 1
120
+ end
121
+ end
122
+
123
+ # Transitions the tape.
124
+ #
125
+ # @param [String] read the input symbol read
126
+ # @param [String] write the symbol to write
127
+ # @param [String] move Either 'L', 'R', or 'S' (default) to
128
+ # move left, right, or stay, respectively.
129
+ # @return [Boolean] whether the transition succeeded
130
+ def transition(read, write, move)
131
+ if read == @memory[@head]
132
+ @memory[@head] = write
133
+ case move
134
+ when 'R'
135
+ # Move right
136
+ @memory << '@' if @memory[@head + 1]
137
+ @head += 1
138
+ when 'L'
139
+ # Move left
140
+ @memory.unshift('@') if @head == 0
141
+ @head -= 1
142
+ end
143
+ return true
144
+ else
145
+ return false
146
+ end
147
+ end
148
+
149
+ # Trims the memory empty cells and outputs the tape string.
150
+ #
151
+ # @return [String] the tape memory string
152
+ def output
153
+ @memory.join.sub(/^@*/, '').sub(/@*$/, '')
154
+ end
155
+
156
+ end
157
+ end
@@ -1,3 +1,3 @@
1
1
  module Automata
2
- VERSION = "0.1.0"
2
+ VERSION = "1.0.0"
3
3
  end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+
3
+ describe Automata::PDA do
4
+
5
+ ##
6
+ # balanced bracket pda
7
+ #
8
+ context "Initializing from a valid file" do
9
+ before do
10
+ @pda = Automata::PDA.new(file: 'examples/pda_sample.yml')
11
+ end
12
+
13
+ it "should have transition S, &" do
14
+ @pda.has_transition?('S','&').should == true
15
+ end
16
+
17
+ it "should have transition A, (" do
18
+ @pda.has_transition?('S','&').should == true
19
+ end
20
+
21
+ it "should accept '()'" do
22
+ @pda.accepts?('()').should == true
23
+ end
24
+
25
+ it "should accept '(())'" do
26
+ @pda.accepts?('(())').should == true
27
+ end
28
+
29
+ it "should not accept the empty string" do
30
+ @pda.accepts?('').should == false
31
+ end
32
+
33
+ it "should not accept '(('" do
34
+ @pda.accepts?('((').should == false
35
+ end
36
+
37
+ it "should not accept '())'" do
38
+ @pda.accepts?('())').should == false
39
+ end
40
+
41
+ it "should accept '(()())'" do
42
+ @pda.accepts?('(()())').should == true
43
+ end
44
+
45
+ it "should not accept '(()'" do
46
+ @pda.accepts?('(()').should == false
47
+ end
48
+ end
49
+
50
+ context "Initializing an empty pda" do
51
+ before do
52
+ @pda = Automata::PDA.new
53
+ end
54
+
55
+ it "should be created successfully" do
56
+ @pda.should be_an_instance_of Automata::PDA
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,141 @@
1
+ require 'spec_helper'
2
+
3
+ describe Automata::Turing do
4
+
5
+ ##
6
+ # Turing from file
7
+ #
8
+ context "Initializing from a valid file" do
9
+ before do
10
+ @turing = Automata::Turing.new(file: 'examples/turing_1.yml')
11
+ end
12
+
13
+ it "should not accept '0'" do
14
+ @turing.accepts?('0').should == false
15
+ end
16
+
17
+ it "should not accept '1'" do
18
+ @turing.accepts?('1').should == false
19
+ end
20
+
21
+ it "should not accept the empty string" do
22
+ @turing.accepts?('').should == false
23
+ end
24
+
25
+ it "should not accept '01'" do
26
+ @turing.accepts?('01').should == false
27
+ end
28
+
29
+ it "should accept '101'" do
30
+ @turing.accepts?('101').should == true
31
+ end
32
+
33
+ it "should accept '1010'" do
34
+ @turing.accepts?('1010').should == true
35
+ end
36
+
37
+ it "should accept '01011'" do
38
+ @turing.accepts?('01011').should == true
39
+ end
40
+ end
41
+
42
+ context "Initializing an empty Turing" do
43
+ before do
44
+ @turing = Automata::Turing.new
45
+ end
46
+
47
+ it "should be created successfully" do
48
+ @turing.should be_an_instance_of Automata::Turing
49
+ end
50
+ end
51
+
52
+ ##
53
+ # Turing params
54
+ #
55
+ context "Initializing a Turing by params" do
56
+ before do
57
+ states = ['A','B','C']
58
+ inputAlphabet = [0,1]
59
+ tapeAlphabet = [0,1]
60
+ start = 'A'
61
+ transitions = {
62
+ 'A' => {
63
+ 0 => {
64
+ to: 'A',
65
+ write: 0,
66
+ move: 'R'
67
+ },
68
+ 1 => {
69
+ to: 'B',
70
+ write: 1,
71
+ move: 'R'
72
+ }
73
+ },
74
+ 'B' => {
75
+ 0 => {
76
+ to: 'C',
77
+ write: 0,
78
+ move: 'R'
79
+ },
80
+ 1 => {
81
+ to: 'B',
82
+ write: 1,
83
+ move: 'R'
84
+ }
85
+ },
86
+ 'C' => {
87
+ 0 => {
88
+ to: 'A',
89
+ write: 0,
90
+ move: 'R'
91
+ },
92
+ 1 => {
93
+ to: 'ACCEPT',
94
+ write: 1,
95
+ move: 'R'
96
+ }
97
+ }
98
+ }
99
+ params = {
100
+ states: states,
101
+ inputAlphabet: inputAlphabet,
102
+ tapeAlphabet: tapeAlphabet,
103
+ start: start,
104
+ transitions: transitions
105
+ }
106
+ @turing = Automata::Turing.new(params)
107
+ end
108
+
109
+ it "should be created successfully" do
110
+ @turing.should be_an_instance_of Automata::Turing
111
+ end
112
+
113
+ it "should not accept '0'" do
114
+ @turing.accepts?('0').should == false
115
+ end
116
+
117
+ it "should not accept '1'" do
118
+ @turing.accepts?('1').should == false
119
+ end
120
+
121
+ it "should not accept the empty string" do
122
+ @turing.accepts?('').should == false
123
+ end
124
+
125
+ it "should not accept '01'" do
126
+ @turing.accepts?('01').should == false
127
+ end
128
+
129
+ it "should accept '101'" do
130
+ @turing.accepts?('101').should == true
131
+ end
132
+
133
+ it "should accept '1010'" do
134
+ @turing.accepts?('1010').should == true
135
+ end
136
+
137
+ it "should accept '01011'" do
138
+ @turing.accepts?('01011').should == true
139
+ end
140
+ end
141
+ end
metadata CHANGED
@@ -1,19 +1,20 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: automata
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 1.0.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Jico Baligod
9
+ - Lukas Sabota
9
10
  autorequire:
10
11
  bindir: bin
11
12
  cert_chain: []
12
- date: 2012-04-27 00:00:00.000000000 Z
13
+ date: 2012-04-30 00:00:00.000000000 Z
13
14
  dependencies:
14
15
  - !ruby/object:Gem::Dependency
15
16
  name: rake
16
- requirement: &70286071406040 !ruby/object:Gem::Requirement
17
+ requirement: &70159780666060 !ruby/object:Gem::Requirement
17
18
  none: false
18
19
  requirements:
19
20
  - - ! '>='
@@ -21,10 +22,10 @@ dependencies:
21
22
  version: '0'
22
23
  type: :development
23
24
  prerelease: false
24
- version_requirements: *70286071406040
25
+ version_requirements: *70159780666060
25
26
  - !ruby/object:Gem::Dependency
26
27
  name: rspec
27
- requirement: &70286071405420 !ruby/object:Gem::Requirement
28
+ requirement: &70159780280380 !ruby/object:Gem::Requirement
28
29
  none: false
29
30
  requirements:
30
31
  - - ~>
@@ -32,7 +33,7 @@ dependencies:
32
33
  version: 2.9.0
33
34
  type: :development
34
35
  prerelease: false
35
- version_requirements: *70286071405420
36
+ version_requirements: *70159780280380
36
37
  description: Create and simulate automaton.
37
38
  email:
38
39
  - jico@baligod.com
@@ -50,14 +51,20 @@ files:
50
51
  - examples/dfa_sample.yml
51
52
  - examples/nfa_1.yml
52
53
  - examples/nfa_2.yml
54
+ - examples/pda_sample.yml
55
+ - examples/turing_1.yml
53
56
  - lib/automata.rb
54
57
  - lib/automata/dfa.rb
55
58
  - lib/automata/nfa.rb
59
+ - lib/automata/pda.rb
56
60
  - lib/automata/state_diagram.rb
61
+ - lib/automata/turing.rb
57
62
  - lib/automata/version.rb
58
63
  - spec/dfa_spec.rb
59
64
  - spec/nfa_spec.rb
65
+ - spec/pda_spec.rb
60
66
  - spec/spec_helper.rb
67
+ - spec/turing_spec.rb
61
68
  homepage: http://github.com/jico/automata
62
69
  licenses: []
63
70
  post_install_message:
@@ -72,7 +79,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
72
79
  version: '0'
73
80
  segments:
74
81
  - 0
75
- hash: 3744273630478255702
82
+ hash: -3684933468062137733
76
83
  required_rubygems_version: !ruby/object:Gem::Requirement
77
84
  none: false
78
85
  requirements:
@@ -81,7 +88,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
81
88
  version: '0'
82
89
  segments:
83
90
  - 0
84
- hash: 3744273630478255702
91
+ hash: -3684933468062137733
85
92
  requirements: []
86
93
  rubyforge_project:
87
94
  rubygems_version: 1.8.17
@@ -92,4 +99,6 @@ summary: This gem provides a number of classes to create and simulate Determinis
92
99
  test_files:
93
100
  - spec/dfa_spec.rb
94
101
  - spec/nfa_spec.rb
102
+ - spec/pda_spec.rb
95
103
  - spec/spec_helper.rb
104
+ - spec/turing_spec.rb