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 +16 -26
- data/lib/automata/nfa.rb +31 -59
- data/lib/automata/state_diagram.rb +17 -8
- data/lib/automata/version.rb +1 -1
- metadata +7 -7
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
|
-
#
|
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
|
-
#
|
34
|
-
#
|
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
|
-
|
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
|
-
#
|
19
|
-
#
|
20
|
-
|
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
|
-
|
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
|
-
#
|
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
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
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
|
-
#
|
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
|
-
#
|
86
|
-
#
|
87
|
-
|
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?
|
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
|
data/lib/automata/version.rb
CHANGED
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.
|
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: &
|
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: *
|
24
|
+
version_requirements: *70318108152500
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rspec
|
27
|
-
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: *
|
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:
|
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:
|
84
|
+
hash: 149328891026543090
|
85
85
|
requirements: []
|
86
86
|
rubyforge_project:
|
87
87
|
rubygems_version: 1.8.17
|