automata 0.0.2 → 0.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.
data/README.md CHANGED
@@ -2,8 +2,12 @@
2
2
 
3
3
  A sweet Ruby gem for creating and simulating deterministic/nondeterministic finite automata, push-down automata, and Turing machines.
4
4
 
5
+ __Note:__ This gem is still under development. Not all automata have been fully implemented yet.
6
+
5
7
  ## Installation
6
8
 
9
+ Requires __Ruby 1.9.3__.
10
+
7
11
  Add this line to your application's Gemfile:
8
12
 
9
13
  gem 'automata'
@@ -18,7 +22,7 @@ Or install it yourself as:
18
22
 
19
23
  ## Usage
20
24
 
21
- TODO: Write usage instructions here
25
+ We'll be adding some wiki pages with usage details soon.
22
26
 
23
27
  ## Contributing
24
28
 
@@ -0,0 +1,28 @@
1
+ ##
2
+ # Sample NFA build file
3
+ # Accepts: a* + (ab)*
4
+ #
5
+ states:
6
+ - q1
7
+ - q2
8
+ - q3
9
+ - q4
10
+ alphabet:
11
+ - a
12
+ - b
13
+ start: q1
14
+ accept:
15
+ - q1
16
+ - q2
17
+ - q4
18
+ transitions:
19
+ q1:
20
+ a:
21
+ - q2
22
+ - q3
23
+ q2:
24
+ a: q2
25
+ q3:
26
+ b: q4
27
+ q4:
28
+ a: q3
data/lib/automata/dfa.rb CHANGED
@@ -28,7 +28,7 @@ module Automata
28
28
  # Determines whether the DFA accepts the given string.
29
29
  #
30
30
  # * *Args*:
31
- # - +string* -> The string to use as input for the DFA.
31
+ # - +string+ -> The string to use as input for the DFA.
32
32
  #
33
33
  # * *Returns*:
34
34
  # Whether or not the DFA accepts the string (boolean).
@@ -0,0 +1,94 @@
1
+ module Automata
2
+
3
+ ##
4
+ # Deterministic Finite Automata.
5
+ #
6
+ # NFA nodes do not need to have a transition for each
7
+ # symbol in the alphabet. Empty transitions, denoted by
8
+ # the '&' charactar, force a transition to another node.
9
+ #
10
+ #--
11
+ # TODO: Check that each state is connected.
12
+ #
13
+ class NFA < StateDiagram
14
+
15
+ #--
16
+ # TODO: Check if valid NFA.
17
+ #
18
+
19
+ ##
20
+ # Determines whether the NFA accepts the given string.
21
+ #
22
+ # * *Args*:
23
+ # - +string+ -> The string to use as input for the DFA.
24
+ # * *Returns*:
25
+ # Whether or not the DFA accepts the string (boolean).
26
+ #
27
+ def accepts?(string)
28
+ heads = [@start]
29
+ string.each_char do |symbol|
30
+ newHeads = []
31
+ heads.each_with_index do |head, i|
32
+ #--
33
+ # Check if head can transition read symbol
34
+ # Head dies if no transition for symbol
35
+ if has_transition?(head, symbol)
36
+ transition(head, symbol).each { |t| newHeads << t }
37
+ end
38
+ end
39
+ heads = newHeads
40
+ break if heads.empty?
41
+ end
42
+
43
+ heads.each { |head| return true if accept_state? head }
44
+ false
45
+ end
46
+
47
+ ##
48
+ # Determine the states to transition to from a given
49
+ # state and input symbol.
50
+ #
51
+ # * *Args*:
52
+ # - +state+ -> State transitioning from.
53
+ # - +input+ -> Input symbol.
54
+ # * *Returns*:
55
+ # The array of transition states. Nil if none.
56
+ #
57
+ def transition(state, input)
58
+ if has_transition?(state, input)
59
+ dests = @transitions[state][input]
60
+ dests = [dests] unless dests.kind_of? Array
61
+ dests
62
+ else
63
+ nil
64
+ end
65
+ end
66
+
67
+ ##
68
+ # Determine whether or not a transition exists
69
+ # for a state, given an input symbol.
70
+ #
71
+ # * *Args*:
72
+ # - +state+ -> State transitioning from.
73
+ # - +input+ -> Input symbol.
74
+ # * *Returns*:
75
+ # Whether a transition exists. (boolean)
76
+ #
77
+ def has_transition?(state, input)
78
+ @transitions[state].has_key? input
79
+ end
80
+
81
+ ##
82
+ # Determine if a given state is an accept state.
83
+ #
84
+ # * *Args*:
85
+ # - +state+ -> The state.
86
+ # * *Returns*:
87
+ # Whether or not the state is an accept state. (boolean)
88
+ #
89
+ def accept_state?(state)
90
+ @accept.include? state
91
+ end
92
+ end
93
+
94
+ end
@@ -1,3 +1,3 @@
1
1
  module Automata
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
data/lib/automata.rb CHANGED
@@ -2,6 +2,7 @@ require "automata/version"
2
2
  require 'yaml'
3
3
  require "automata/state_diagram"
4
4
  require "automata/dfa"
5
+ require "automata/nfa"
5
6
 
6
7
  module Automata
7
8
  # Your code goes here...
data/spec/nfa_spec.rb ADDED
@@ -0,0 +1,111 @@
1
+ require 'spec_helper'
2
+
3
+ describe Automata::NFA do
4
+
5
+ context "Initializing from a valid file" do
6
+ before do
7
+ @nfa = Automata::NFA.new(file: 'examples/nfa_sample.yml')
8
+ end
9
+
10
+ it "should accept 'a'" do
11
+ @nfa.accepts?('a').should == true
12
+ end
13
+
14
+ it "should accept 'aa'" do
15
+ @nfa.accepts?('aa').should == true
16
+ end
17
+
18
+ it "should accept the empty string" do
19
+ @nfa.accepts?('').should == true
20
+ end
21
+
22
+ it "should not accept 'b'" do
23
+ @nfa.accepts?('b').should == false
24
+ end
25
+
26
+ it "should accept 'ab'" do
27
+ @nfa.accepts?('ab').should == true
28
+ end
29
+
30
+ it "should accept 'abab'" do
31
+ @nfa.accepts?('abab').should == true
32
+ end
33
+
34
+ it "should accept 'aab'" do
35
+ @nfa.accepts?('aab').should == false
36
+ end
37
+ end
38
+
39
+ context "Initializing an empty NFA" do
40
+ before do
41
+ @nfa = Automata::NFA.new
42
+ end
43
+
44
+ it "should be created successfully" do
45
+ @nfa.should be_an_instance_of Automata::NFA
46
+ end
47
+ end
48
+
49
+ context "Initializing a NFA by params" do
50
+ before do
51
+ states = ['q1','q2','q3','q4']
52
+ alphabet = ['a','b']
53
+ start = 'q1'
54
+ accept = ['q1','q2','q4']
55
+ transitions = {
56
+ 'q1' => {
57
+ 'a' => ['q2','q3']
58
+ },
59
+ 'q2' => {
60
+ 'a' => 'q2'
61
+ },
62
+ 'q3' => {
63
+ 'b' => 'q4'
64
+ },
65
+ 'q4' => {
66
+ 'a' => 'q3'
67
+ }
68
+ }
69
+ params = {
70
+ states: states,
71
+ alphabet: alphabet,
72
+ start: start,
73
+ accept: accept,
74
+ transitions: transitions
75
+ }
76
+ @nfa = Automata::NFA.new(params)
77
+ end
78
+
79
+ it "should be created successfully" do
80
+ @nfa.should be_an_instance_of Automata::NFA
81
+ end
82
+
83
+ it "should accept 'a'" do
84
+ @nfa.accepts?('a').should == true
85
+ end
86
+
87
+ it "should accept 'aa'" do
88
+ @nfa.accepts?('aa').should == true
89
+ end
90
+
91
+ it "should accept the empty string" do
92
+ @nfa.accepts?('').should == true
93
+ end
94
+
95
+ it "should not accept 'b'" do
96
+ @nfa.accepts?('b').should == false
97
+ end
98
+
99
+ it "should accept 'ab'" do
100
+ @nfa.accepts?('ab').should == true
101
+ end
102
+
103
+ it "should accept 'abab'" do
104
+ @nfa.accepts?('abab').should == true
105
+ end
106
+
107
+ it "should accept 'aab'" do
108
+ @nfa.accepts?('aab').should == false
109
+ end
110
+ end
111
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: automata
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-04-23 00:00:00.000000000 Z
12
+ date: 2012-04-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
16
- requirement: &70316676891620 !ruby/object:Gem::Requirement
16
+ requirement: &70308841255600 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *70316676891620
24
+ version_requirements: *70308841255600
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rspec
27
- requirement: &70316676891100 !ruby/object:Gem::Requirement
27
+ requirement: &70308841254660 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,7 +32,7 @@ dependencies:
32
32
  version: 2.9.0
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *70316676891100
35
+ version_requirements: *70308841254660
36
36
  description: Create and simulate automaton.
37
37
  email:
38
38
  - jico@baligod.com
@@ -48,11 +48,14 @@ files:
48
48
  - Rakefile
49
49
  - automata.gemspec
50
50
  - examples/dfa_sample.yml
51
+ - examples/nfa_sample.yml
51
52
  - lib/automata.rb
52
53
  - lib/automata/dfa.rb
54
+ - lib/automata/nfa.rb
53
55
  - lib/automata/state_diagram.rb
54
56
  - lib/automata/version.rb
55
57
  - spec/dfa_spec.rb
58
+ - spec/nfa_spec.rb
56
59
  - spec/spec_helper.rb
57
60
  homepage: http://github.com/jico/automata
58
61
  licenses: []
@@ -68,7 +71,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
68
71
  version: '0'
69
72
  segments:
70
73
  - 0
71
- hash: -1178858470182539386
74
+ hash: -1969094852898081340
72
75
  required_rubygems_version: !ruby/object:Gem::Requirement
73
76
  none: false
74
77
  requirements:
@@ -77,7 +80,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
77
80
  version: '0'
78
81
  segments:
79
82
  - 0
80
- hash: -1178858470182539386
83
+ hash: -1969094852898081340
81
84
  requirements: []
82
85
  rubyforge_project:
83
86
  rubygems_version: 1.8.17
@@ -87,4 +90,5 @@ summary: This gem provides a number of classes to create and simulate Determinis
87
90
  Finite Automata, Push-down Automata, and Turing Machines.
88
91
  test_files:
89
92
  - spec/dfa_spec.rb
93
+ - spec/nfa_spec.rb
90
94
  - spec/spec_helper.rb