automata 0.0.6 → 0.0.7

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/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