automata 0.0.3 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -22,7 +22,75 @@ Or install it yourself as:
22
22
 
23
23
  ## Usage
24
24
 
25
- We'll be adding some wiki pages with usage details soon.
25
+ ### Creating a new machine
26
+
27
+ Defining a new machine can be done in two ways:
28
+ * From a structured YAML file.
29
+ * Through class setter methods.
30
+
31
+ #### Building with YAML
32
+
33
+ We can easily define a machine's _n_-tuples in a YAML file. For example, let's create a DFA defined by the 5-tuple (_states_, _alphabet_, _start_, _accept_, _transitions_). We create the file `examples/dfa_sample.yml` with the following content:
34
+
35
+ states:
36
+ - A
37
+ - B
38
+ - C
39
+ - D
40
+ alphabet:
41
+ - '0'
42
+ - '1'
43
+ start: A
44
+ accept:
45
+ - C
46
+ transitions:
47
+ A:
48
+ '0': B
49
+ '1': D
50
+ B:
51
+ '0': C
52
+ '1': D
53
+ C:
54
+ '0': C
55
+ '1': C
56
+ D:
57
+ '0': D
58
+ '1': D
59
+
60
+ __Note:__ Integer hash keys are currently unsupported, hence they must be wrapped in quotes.
61
+
62
+ With our machine defined, we can create a new DFA object from the file.
63
+
64
+ dfa = Automata::DFA.new(file: 'examples/dfa_sample.yml')
65
+
66
+ Presto! We have a fully functioning DFA machine.
67
+
68
+ #### Building with setters
69
+
70
+ You also have the option of setting each variable in the machine's _n_-tuple definition. For example, let's create a new empty DFA and define its states.
71
+
72
+ dfa = Automata::DFA.new
73
+ dfa.states = ['A', 'B', 'C', 'D']
74
+
75
+ We can define each property of the DFA in a similar manner.
76
+
77
+ ### Playing with our machine
78
+
79
+ Now that we've built a machine, we can pass it input and let it work its magic. Consider our DFA built using our `examples/dfa_sample.yml` file, which accepts all strings starting with _00_. Let's experiment with some input:
80
+
81
+ # We can make sure it's a valid DFA
82
+ >> dfa.is_valid?
83
+ => true
84
+ >> dfa.accepts? '001'
85
+ => true
86
+ >> dfa.accepts? '0101'
87
+ => false
88
+
89
+ Awesomesauce.
90
+
91
+ ## Special Characters
92
+
93
+ * _&_ - Represents an ε-transition (epsilon/empty transition)
26
94
 
27
95
  ## Contributing
28
96
 
@@ -1,20 +1,29 @@
1
+ ##
2
+ # Sample DFA file.
3
+ #
4
+ # Accepts all binary strings starting with 00.
5
+ #
1
6
  states:
2
- - q1
3
- - q2
4
- - q3
7
+ - A
8
+ - B
9
+ - C
10
+ - D
5
11
  alphabet:
6
12
  - '0'
7
13
  - '1'
8
- start: q1
14
+ start: A
9
15
  accept:
10
- - q3
16
+ - C
11
17
  transitions:
12
- q1:
13
- '0': q2
14
- '1': q2
15
- q2:
16
- '0': q1
17
- '1': q3
18
- q3:
19
- '0': q3
20
- '1': q3
18
+ A:
19
+ '0': B
20
+ '1': D
21
+ B:
22
+ '0': C
23
+ '1': D
24
+ C:
25
+ '0': C
26
+ '1': C
27
+ D:
28
+ '0': D
29
+ '1': D
@@ -0,0 +1,31 @@
1
+ ##
2
+ # Sample NFA build file
3
+ #
4
+ # Accepts all binary strings where
5
+ # the last symbol is 0 or
6
+ # which contain only 1's
7
+ #
8
+ states:
9
+ - A
10
+ - B
11
+ - C
12
+ - D
13
+ alphabet:
14
+ - '0'
15
+ - '1'
16
+ start: B
17
+ accept:
18
+ - A
19
+ - D
20
+ transitions:
21
+ A:
22
+ '1': A
23
+ B:
24
+ '&':
25
+ - A
26
+ - C
27
+ C:
28
+ '0':
29
+ - C
30
+ - D
31
+ '1': C
data/lib/automata/nfa.rb CHANGED
@@ -12,10 +12,6 @@ module Automata
12
12
  #
13
13
  class NFA < StateDiagram
14
14
 
15
- #--
16
- # TODO: Check if valid NFA.
17
- #
18
-
19
15
  ##
20
16
  # Determines whether the NFA accepts the given string.
21
17
  #
@@ -27,8 +23,18 @@ module Automata
27
23
  def accepts?(string)
28
24
  heads = [@start]
29
25
  string.each_char do |symbol|
30
- newHeads = []
31
- heads.each_with_index do |head, i|
26
+ newHeads, eTrans = [], []
27
+
28
+ #--
29
+ # Move any e-transitions
30
+ heads.each do |head|
31
+ if has_transition?(head, '&')
32
+ transition(head, '&').each { |t| eTrans << t }
33
+ end
34
+ end
35
+ eTrans.each { |h| heads << h }
36
+
37
+ heads.each do |head|
32
38
  #--
33
39
  # Check if head can transition read symbol
34
40
  # Head dies if no transition for symbol
@@ -75,6 +81,7 @@ module Automata
75
81
  # Whether a transition exists. (boolean)
76
82
  #
77
83
  def has_transition?(state, input)
84
+ return false unless @transitions.include? state
78
85
  @transitions[state].has_key? input
79
86
  end
80
87
 
@@ -1,3 +1,3 @@
1
1
  module Automata
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.5"
3
3
  end
data/spec/dfa_spec.rb CHANGED
@@ -11,8 +11,8 @@ describe Automata::DFA do
11
11
  @dfa.should be_valid
12
12
  end
13
13
 
14
- it "should accept '01'" do
15
- @dfa.accepts?('01').should == true
14
+ it "should accept '00'" do
15
+ @dfa.accepts?('00').should == true
16
16
  end
17
17
 
18
18
  it "should accept '001101'" do
@@ -23,8 +23,20 @@ describe Automata::DFA do
23
23
  @dfa.accepts?('').should == false
24
24
  end
25
25
 
26
- it "should not accept '10'" do
27
- @dfa.accepts?('10').should == false
26
+ it "should not accept '0'" do
27
+ @dfa.accepts?('0').should == false
28
+ end
29
+
30
+ it "should not accept '1'" do
31
+ @dfa.accepts?('1').should == false
32
+ end
33
+
34
+ it "should not accept '01'" do
35
+ @dfa.accepts?('01').should == false
36
+ end
37
+
38
+ it "should not accept '100'" do
39
+ @dfa.accepts?('100').should == false
28
40
  end
29
41
  end
30
42
 
@@ -40,22 +52,26 @@ describe Automata::DFA do
40
52
 
41
53
  context "Initializing a DFA by params" do
42
54
  before do
43
- states = ['q1','q2','q3']
44
- alphabet = ['0','1']
45
- start = 'q1'
46
- accept = ['q3']
55
+ states = %w( A B C D )
56
+ alphabet = %w( 0 1 )
57
+ start = 'A'
58
+ accept = %w( C )
47
59
  transitions = {
48
- 'q1' => {
49
- '0' => 'q2',
50
- '1' => 'q2'
60
+ 'A' => {
61
+ '0' => 'B',
62
+ '1' => 'D'
63
+ },
64
+ 'B' => {
65
+ '0' => 'C',
66
+ '1' => 'D'
51
67
  },
52
- 'q2' => {
53
- '0' => 'q1',
54
- '1' => 'q3'
68
+ 'C' => {
69
+ '0' => 'C',
70
+ '1' => 'C'
55
71
  },
56
- 'q3' => {
57
- '0' => 'q3',
58
- '1' => 'q3'
72
+ 'D' => {
73
+ '0' => 'D',
74
+ '1' => 'D'
59
75
  }
60
76
  }
61
77
  params = {
@@ -72,8 +88,8 @@ describe Automata::DFA do
72
88
  @dfa.should be_valid
73
89
  end
74
90
 
75
- it "should accept '01'" do
76
- @dfa.accepts?('01').should == true
91
+ it "should accept '00'" do
92
+ @dfa.accepts?('00').should == true
77
93
  end
78
94
 
79
95
  it "should accept '001101'" do
@@ -84,8 +100,20 @@ describe Automata::DFA do
84
100
  @dfa.accepts?('').should == false
85
101
  end
86
102
 
87
- it "should not accept '10'" do
88
- @dfa.accepts?('10').should == false
103
+ it "should not accept '0'" do
104
+ @dfa.accepts?('0').should == false
105
+ end
106
+
107
+ it "should not accept '1'" do
108
+ @dfa.accepts?('1').should == false
109
+ end
110
+
111
+ it "should not accept '01'" do
112
+ @dfa.accepts?('01').should == false
113
+ end
114
+
115
+ it "should not accept '100'" do
116
+ @dfa.accepts?('100').should == false
89
117
  end
90
118
  end
91
119
  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.3
4
+ version: 0.0.5
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-24 00:00:00.000000000 Z
12
+ date: 2012-04-25 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
16
- requirement: &70308841255600 !ruby/object:Gem::Requirement
16
+ requirement: &70101266746740 !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: *70308841255600
24
+ version_requirements: *70101266746740
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rspec
27
- requirement: &70308841254660 !ruby/object:Gem::Requirement
27
+ requirement: &70101266745440 !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: *70308841254660
35
+ version_requirements: *70101266745440
36
36
  description: Create and simulate automaton.
37
37
  email:
38
38
  - jico@baligod.com
@@ -48,6 +48,7 @@ files:
48
48
  - Rakefile
49
49
  - automata.gemspec
50
50
  - examples/dfa_sample.yml
51
+ - examples/nfa_2.yml
51
52
  - examples/nfa_sample.yml
52
53
  - lib/automata.rb
53
54
  - lib/automata/dfa.rb
@@ -71,7 +72,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
71
72
  version: '0'
72
73
  segments:
73
74
  - 0
74
- hash: -1969094852898081340
75
+ hash: -2023160774653295454
75
76
  required_rubygems_version: !ruby/object:Gem::Requirement
76
77
  none: false
77
78
  requirements:
@@ -80,7 +81,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
80
81
  version: '0'
81
82
  segments:
82
83
  - 0
83
- hash: -1969094852898081340
84
+ hash: -2023160774653295454
84
85
  requirements: []
85
86
  rubyforge_project:
86
87
  rubygems_version: 1.8.17