breily / states

Ruby library for creating finite state machines

states / machines.rb
100644 62 lines (55 sloc) 1.793 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#
# An assortment of example machines to show different ways to
# define states and machines, as well as demonstrate actions and
# special transitions.
#
 
require 'dfa'
 
# States set to recognize "(ab|ba)a*"
def regex_machine
    return DFA.new [
        State.new("A", {'a' => "B", 'b' => "C"}),
        State.new("B", {'b' => "D"}),
        State.new("C", {'a' => "E"}),
        State.new("D", {'a' => "F"}),
        State.new("E", {'a' => "F"}),
        State.new("F", {'a' => "F"}),
    ]
end
 
# States to implement Figure 1 from wikipedia's Finite state machine page
# Represents two doors/switches
def door_machine
    return DFA.new [
        State.new("Opened", {'close_door' => "Closed"}),
        State.new("Closed", {'open_door' => "Opened"})
    ]
end
 
# States to implement Figure 2 from wikipedia page
# Recognizes just the word 'nice'. :dot matches any input.
def nice_machine
    final = state "5", :final do
        transition :dot => :error
        on_enter { |x| puts "!! You spelled the word nice correctly" }
    end
    return DFA.new [
        State.new("1", {'n' => "2", :dot => :error}),
        State.new("2", {'i' => "3", :dot => :error}),
        State.new("3", {'c' => "4", :dot => :error}),
        State.new("4", {'e' => "5", :dot => :error}),
        final
    ]
end
 
# States to implement Figure 3 from wikipedia page
# Determine whether the number of zeros in a string of 1's and 0's
# is odd or even.
def binary_machine
    return DFA.new [
        State.new("Even", {'1' => "Even", '0' => "Odd"}),
        State.new("Odd", {'1' => "Odd", '0' => "Even"})
    ]
end
 
# Match Lisp's cdr/car/etc. functions
def carcdr
    return automaton 1, {"c" => 2},
                     2, {"a" => 2, "d" => 2, "r" => 3},
                     3, {"r" => 3}
end