Skip to content

Commit fb3fbbe

Browse files
committed
[+]: Add Implementation of NFA
1 parent 9ccd44d commit fb3fbbe

File tree

1 file changed

+54
-1
lines changed

1 file changed

+54
-1
lines changed

machine/nfa.rb

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,57 @@ 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-
end
36+
end
37+
38+
=begin
39+
#<struct NFARuleSet rules=[#<FARule 1 --a--> 1>, #<FARule 1 --b--> 1>, #<FARule 1 --b--> 2>,
40+
#<FARule 2 --a--> 3>, #<FARule 2 --b--> 3>, #<FARule 3 --a--> 4>, #<FARule 3 --b--> 4>]>
41+
=end
42+
ruleset = NFARuleSet.new([
43+
FARule.new(1, 'a', 1), FARule.new(1, 'b', 1), FARule.new(1, 'b', 2),
44+
FARule.new(2, 'a', 3), FARule.new(2, 'b', 3), FARule.new(3, 'a', 4),
45+
FARule.new(3, 'b', 4)
46+
])
47+
48+
# => #<Set: {1, 2}>
49+
ruleset.next_states(Set[1], 'b')
50+
# => #<Set: {1, 3, 4}>
51+
ruleset.next_states(Set[1,2,3], 'a')
52+
# => #<Set: {1, 2, 4}>
53+
ruleset.next_states(Set[1,3], 'b')
54+
55+
class NFA < Struct.new(:current_states, :final_states, :ruleset)
56+
def accepting?
57+
(current_states & final_states).any? # set intersection operation is empty?
58+
end
59+
60+
def read_char(character)
61+
self.current_states = ruleset.next_states(current_states,character)
62+
end
63+
64+
def read_string(str)
65+
str.chars.each do |character|
66+
read_char(character)
67+
end
68+
end
69+
end
70+
71+
class NFAMaker < Struct.new(:start_state, :final_states, :ruleset)
72+
def make_nfa
73+
NFA.new(Set[start_state], final_states, ruleset)
74+
end
75+
76+
def accepts?(str)
77+
make_nfa.tap { |nfa| nfa.read_string(str) }.accepting?
78+
end
79+
end
80+
81+
nfa = NFAMaker.new(1, [4], ruleset)
82+
# => true
83+
nfa.accepts?('bab')
84+
# => true
85+
nfa.accepts?('bababab')
86+
# => false
87+
nfa.accepts?('babababa')
88+
# => true
89+
nfa.accepts?('bababababbbbbb')

0 commit comments

Comments
 (0)