Skip to content

Commit 4350f47

Browse files
committed
Add Free Move feature to NFA for enhance NFA power
1 parent fb3fbbe commit 4350f47

File tree

1 file changed

+46
-1
lines changed

1 file changed

+46
-1
lines changed

machine/nfa.rb

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,16 @@ def follow_rules_for(state, character)
3333
def rules_for(state, character)
3434
rules.select { |rule| rule.applies_to?(state, character) } # select * where
3535
end
36+
37+
def follow_free_moves(states)
38+
more_states = next_states(states, nil)
39+
40+
if more_states.subset?(states)
41+
states
42+
else
43+
follow_free_moves(states + more_states)
44+
end
45+
end
3646
end
3747

3848
=begin
@@ -66,6 +76,10 @@ def read_string(str)
6676
read_char(character)
6777
end
6878
end
79+
80+
def current_states
81+
ruleset.follow_free_moves(super)
82+
end
6983
end
7084

7185
class NFAMaker < Struct.new(:start_state, :final_states, :ruleset)
@@ -86,4 +100,35 @@ def accepts?(str)
86100
# => false
87101
nfa.accepts?('babababa')
88102
# => true
89-
nfa.accepts?('bababababbbbbb')
103+
nfa.accepts?('bababababbbbbb')
104+
105+
106+
=begin
107+
#<struct NFARuleSet rules=[#<FARule 1 ----> 2>, #<FARule 1 ----> 4>,
108+
#<FARule 2 --a--> 3>, #<FARule 3 --a--> 2>, #<FARule 4 --a--> 5>,
109+
#<FARule 5 --a--> 6>, #<FARule 6 --a--> 7>]>
110+
=end
111+
ruleset = NFARuleSet.new([
112+
FARule.new(1, nil, 2), FARule.new(1, nil, 4),
113+
FARule.new(2, 'a', 3),
114+
FARule.new(3, 'a', 2),
115+
FARule.new(4, 'a', 5),
116+
FARule.new(5, 'a', 6),
117+
FARule.new(6, 'a', 4)
118+
])
119+
120+
# => #<Set: {2, 4}>
121+
ruleset.next_states(Set[1], nil)
122+
123+
# => #<Set: {1, 2, 4}>
124+
ruleset.follow_free_moves(Set[1])
125+
126+
nfa = NFAMaker.new(1, [2, 4], ruleset)
127+
# => true
128+
nfa.accepts?('aa')
129+
# => true
130+
nfa.accepts?('aaa')
131+
# => false
132+
nfa.accepts?('aaaaa')
133+
# => true
134+
nfa.accepts?('aaaaaa')

0 commit comments

Comments
 (0)