automata 0.1.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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