automata 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
data/lib/automata/dfa.rb CHANGED
@@ -1,49 +1,39 @@
1
1
  module Automata
2
-
3
- ##
4
2
  # Deterministic Finite Automata.
5
- #
6
- # Each state of a DFA must have exactly one transition for each transition
7
- # defined at creation.
8
- #
9
- #--
10
- # TODO: Check that each state is connected.
11
- #
12
3
  class DFA < StateDiagram
13
-
14
- ##
15
- # Verify that the initialized DFA is valid.
16
- #
17
- # * *Returns*:
18
- # Whether or not the DFA is valid (boolean).
4
+ # Verifies that the initialized DFA is valid.
5
+ # Checks that each state has a transition for each
6
+ # symbol in the alphabet.
19
7
  #
8
+ # @return [Boolean] whether or not the DFA is valid.
20
9
  def valid?
10
+ # @todo Check that each state is connected.
11
+ # Iterate through each states to verify the graph
12
+ # is not disjoint.
21
13
  @transitions.each do |key, val|
22
14
  @alphabet.each { |a| return false unless @transitions[key].has_key? a }
23
15
  end
24
16
  true
25
17
  end
26
18
 
27
- ##
28
- # Determines whether the DFA accepts the given string.
29
- #
30
- # * *Args*:
31
- # - +string+ -> The string to use as input for the DFA.
19
+ # Determines whether the DFA accepts a given string.
32
20
  #
33
- # * *Returns*:
34
- # Whether or not the DFA accepts the string (boolean).
35
- #
36
- def accepts?(string)
21
+ # @param [String] input the string to use as input for the DFA.
22
+ # @return [Boolean] whether or not the DFA accepts the string.
23
+ def accepts?(input)
37
24
  head = @start
38
- string.each_char do |symbol|
25
+ input.each_char do |symbol|
39
26
  head = @transitions[head][symbol]
40
27
  end
41
28
  is_accept_state? head
42
29
  end
43
30
 
31
+ # Determines if a given state is an accept state.
32
+ #
33
+ # @param [String] state the state label to check.
34
+ # @return [Boolean] whether or not the state is an accept state.
44
35
  def is_accept_state?(state)
45
36
  @accept.include? state
46
37
  end
47
38
  end
48
-
49
39
  end
data/lib/automata/nfa.rb CHANGED
@@ -1,39 +1,27 @@
1
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
- #
2
+ # Nondeterministic Finite Automata.
13
3
  class NFA < StateDiagram
4
+ # @todo Check that each state is connected.
5
+ # Iterate through each states to verify the graph
6
+ # is not disjoint.
14
7
 
15
- ##
16
- # Determines whether the NFA accepts the given string.
8
+ # Determines whether the NFA accepts a given string.
17
9
  #
18
- # * *Args*:
19
- # - +string+ -> The string to use as input for the DFA.
20
- # * *Returns*:
21
- # Whether or not the DFA accepts the string (boolean).
22
- #
23
- def accepts?(string)
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)
24
13
  heads = [@start]
25
14
 
26
- #--
27
15
  # Move any initial e-transitions
28
16
  if has_transition?(@start, '&')
29
17
  transition(@start, '&').each { |h| heads << h }
30
18
  end
31
19
 
32
- string.each_char do |symbol|
20
+ # Iterate through each symbol of input string
21
+ input.each_char do |symbol|
33
22
  newHeads, eTrans = [], []
34
23
 
35
24
  heads.each do |head|
36
- #--
37
25
  # Check if head can transition read symbol
38
26
  # Head dies if no transition for symbol
39
27
  if has_transition?(head, symbol)
@@ -41,7 +29,6 @@ module Automata
41
29
  end
42
30
  end
43
31
 
44
- #--
45
32
  # Move any e-transitions
46
33
  newHeads.each do |head|
47
34
  if has_transition?(head, '&')
@@ -58,52 +45,37 @@ module Automata
58
45
  false
59
46
  end
60
47
 
61
- ##
62
- # Determine the states to transition to from a given
63
- # state and input symbol.
64
- #
65
- # * *Args*:
66
- # - +state+ -> State transitioning from.
67
- # - +input+ -> Input symbol.
68
- # * *Returns*:
69
- # The array of transition states. Nil if none.
48
+ # Determines the transition states, if any, from a given
49
+ # beginning state and input symbol pair.
70
50
  #
71
- def transition(state, input)
72
- if has_transition?(state, input)
73
- dests = @transitions[state][input]
74
- dests = [dests] unless dests.kind_of? Array
75
- dests
76
- else
77
- nil
78
- end
51
+ # @note NFA ε-transitions
52
+ # ε-transitions are supported through the use of the
53
+ # reserved input alphabet character '&'.
54
+ # @param [String] state state label for beginning state.
55
+ # @param [String] symbol input symbol.
56
+ # @return [Array] Array of destination transition states.
57
+ def transition(state, symbol)
58
+ dests = @transitions[state][symbol]
59
+ dests = [dests] unless dests.kind_of? Array
60
+ dests
79
61
  end
80
62
 
81
- ##
82
- # Determine whether or not a transition exists
83
- # for a state, given an input symbol.
63
+ # Determines whether or not any transition states exist
64
+ # given a beginning state and input symbol pair.
84
65
  #
85
- # * *Args*:
86
- # - +state+ -> State transitioning from.
87
- # - +input+ -> Input symbol.
88
- # * *Returns*:
89
- # Whether a transition exists. (boolean)
90
- #
91
- def has_transition?(state, input)
66
+ # @param (see #transition)
67
+ # @return [Boolean] Whether or not a transition exists.
68
+ def has_transition?(state, symbol)
92
69
  return false unless @transitions.include? state
93
- @transitions[state].has_key? input
70
+ @transitions[state].has_key? symbol
94
71
  end
95
72
 
96
- ##
97
- # Determine if a given state is an accept state.
98
- #
99
- # * *Args*:
100
- # - +state+ -> The state.
101
- # * *Returns*:
102
- # Whether or not the state is an accept state. (boolean)
73
+ # Determines if a given state is an accept state.
103
74
  #
75
+ # @param [String] state the state label to check.
76
+ # @return [Boolean] whether or not the state is an accept state.
104
77
  def accept_state?(state)
105
78
  @accept.include? state
106
79
  end
107
80
  end
108
-
109
81
  end
@@ -1,14 +1,25 @@
1
1
  module Automata
2
-
3
- ##
4
2
  # A generic state diagram class represented as a 5-tuple.
5
- #
6
- #--
7
- # TODO: Check for valid transitions against declared states and alphabet.
8
- #
9
3
  class StateDiagram
10
4
  attr_accessor :states, :alphabet, :start, :accept, :transitions
11
5
 
6
+ # @todo Validate machine
7
+ # Check that each transition reads a valid, declared
8
+ # input symbol.
9
+
10
+ # Initialize and build a StateDiagram object.
11
+ #
12
+ # @param [Hash] params the parameters to build the machine with.
13
+ # @option [String] :file a YAML file containing machine params.
14
+ # @option [Array<String>] :states the state labels of the machine.
15
+ # @option [Array<String>] :alphabet the alphabet of input symbols.
16
+ # @option [String] :start the start state of the machine.
17
+ # @option [Array<String>] :accept the accept states of the machine.
18
+ # @option [Hash] :transitions nested hash of transitions for each state.
19
+ # @note The :transitions hash structure will vary
20
+ # Different machines will require different transition structures.
21
+ # Please refer to the {http://github.com/jico/automata/wiki wiki}
22
+ # for details regarding each machine type.
12
23
  def initialize(params={})
13
24
  yaml = {}
14
25
  yaml = YAML::load_file(params[:file]) if params.has_key? :file
@@ -18,7 +29,5 @@ module Automata
18
29
  @accept = yaml['accept'] || params[:accept]
19
30
  @transitions = yaml['transitions'] || params[:transitions]
20
31
  end
21
-
22
32
  end
23
-
24
33
  end
@@ -1,3 +1,3 @@
1
1
  module Automata
2
- VERSION = "0.0.6"
2
+ VERSION = "0.0.7"
3
3
  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.6
4
+ version: 0.0.7
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2012-04-25 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
16
- requirement: &70295152631100 !ruby/object:Gem::Requirement
16
+ requirement: &70318108152500 !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: *70295152631100
24
+ version_requirements: *70318108152500
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rspec
27
- requirement: &70295152630000 !ruby/object:Gem::Requirement
27
+ requirement: &70318108151900 !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: *70295152630000
35
+ version_requirements: *70318108151900
36
36
  description: Create and simulate automaton.
37
37
  email:
38
38
  - jico@baligod.com
@@ -72,7 +72,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
72
72
  version: '0'
73
73
  segments:
74
74
  - 0
75
- hash: 830920834745777469
75
+ hash: 149328891026543090
76
76
  required_rubygems_version: !ruby/object:Gem::Requirement
77
77
  none: false
78
78
  requirements:
@@ -81,7 +81,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
81
81
  version: '0'
82
82
  segments:
83
83
  - 0
84
- hash: 830920834745777469
84
+ hash: 149328891026543090
85
85
  requirements: []
86
86
  rubyforge_project:
87
87
  rubygems_version: 1.8.17