Class: Fae::FiniteAutomata

Inherits:
Object
  • Object
show all
Defined in:
lib/fae/finite_automata.rb

Overview

The main class that drives the Finite Automata evaluation.

Takes in a language, states, and strings, and checks them to validate a state diagram.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(language, description) ⇒ FiniteAutomata

Initializes a new instance of the FiniteAutomata.

Parameters:

  • language (Language)

    a language instance

  • description (String)

    the description of the finite automata



14
15
16
17
18
19
20
# File 'lib/fae/finite_automata.rb', line 14

def initialize(language, description)
  @states = []
  @strings = []
  @invalids = []
  @language = language
  @description = description
end

Instance Attribute Details

#descriptionObject (readonly)

Returns the value of attribute description.



8
9
10
# File 'lib/fae/finite_automata.rb', line 8

def description
  @description
end

#languageObject (readonly)

Returns the value of attribute language.



8
9
10
# File 'lib/fae/finite_automata.rb', line 8

def language
  @language
end

#statesObject (readonly)

Returns the value of attribute states.



8
9
10
# File 'lib/fae/finite_automata.rb', line 8

def states
  @states
end

#stringsObject (readonly)

Returns the value of attribute strings.



8
9
10
# File 'lib/fae/finite_automata.rb', line 8

def strings
  @strings
end

Instance Method Details

#add_states(states) ⇒ Object

Adds strings to check against when evaluating.

Parameters:

  • states (Array)

    an array of states



41
42
43
44
45
# File 'lib/fae/finite_automata.rb', line 41

def add_states(states)
  states.each do |state|
    add_state(state)
  end
end

#add_string(string) ⇒ Object

Adds a single string to the strings array.

Parameters:

  • string (String)

    the string to add



34
35
36
# File 'lib/fae/finite_automata.rb', line 34

def add_string(string)
  @strings << string
end

#add_strings(strings) ⇒ Object

Adds strings to check against when evaluating.

Parameters:

  • strings (Array)

    an array of strings



25
26
27
28
29
# File 'lib/fae/finite_automata.rb', line 25

def add_strings(strings)
  strings.each do |string|
    @strings << string
  end
end

#difference(fa) ⇒ Object

Generates the finite automata for the difference of two different finite automatas.

Parameters:

  • fa (FiniteAutomata)

    the finite automata to difference this one with



84
85
86
# File 'lib/fae/finite_automata.rb', line 84

def difference(fa)
  perform_set_operation(:difference, fa)
end

#evaluate!Object

Runs the evaluation on the finite automata.



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/fae/finite_automata.rb', line 89

def evaluate!
  @invalids = []
  if (@states.length == 0)
    raise "You must add some states to your Finite Automata before checking strings"
  end

  puts """Evaluating strings for #{@description} using language #{@language.characters}".colorize(:yellow)
  @strings.each do |string|
    valid = evaluate_string(string)
    if (!valid)
      @invalids << string
    end
  end

  num_invalid = @invalids.length
  if (num_invalid > 0)
    puts "State diagram may be incorrect for #{@description}".colorize(:red)
    puts "\nA total of #{num_invalid} string#{'s' if num_invalid != 1} did not meet your expectations:\n"

    @invalids.each do |string|
      expected_string = string.expected ? "valid".colorize(:green) : "invalid".colorize(:red)
      puts "* You expected the string '#{string.colorize(:blue)}' to be #{expected_string}"
    end
    puts "\nIf these expectations are correct, then your state diagram needs revising. Otherwise, you've simply expected the wrong values."
  else
    puts "State diagram is correct.".colorize(:green)
  end
  puts
end

#get_state(name) ⇒ Object

Retrieves a state from this finite automata by name.

Parameters:

  • name (String)

    the name of the state to find



50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/fae/finite_automata.rb', line 50

def get_state(name)
  retrieved_state = nil
  @states.each do |state|
    if (state.name == name)
      retrieved_state = state
      break
    end
  end
  if (retrieved_state.nil?)
    raise "State #{name} was not found in this Finite Automata. Ensure that all states have outputs for #{@language.characters}"
  end
  return retrieved_state
end

#intersection(fa) ⇒ Object

Generates the finite automata for the intersection of two different finite automatas.

Parameters:

  • fa (FiniteAutomata)

    the finite automata to intersect this one with



68
69
70
# File 'lib/fae/finite_automata.rb', line 68

def intersection(fa)
  perform_set_operation(:intersection, fa)
end

#to_sObject



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/fae/finite_automata.rb', line 119

def to_s
  output = ""
  output << "Description: ".colorize(:yellow) + @description
  output << "\nLanguage: ".colorize(:yellow) + language.characters.to_s
  output << "\nStates:".colorize(:yellow)
  @states.each do |state|
    output << "\n  State #{state.name}: ".colorize(:blue)
    state.paths.keys.each do |key|
      output << "\n    #{'~'.colorize(:yellow)} #{key} #{'->'.colorize(:light_black)} #{state.paths[key]}"
    end
    accepting = state.accepting ? "accepting".colorize(:green) : "not accepting".colorize(:red)
    output << "\n    #{'~'.colorize(:yellow)} #{accepting}"
  end
  return output
end

#union(fa) ⇒ Object

Generates the finite automata for the union of two different finite automatas.

Parameters:



76
77
78
# File 'lib/fae/finite_automata.rb', line 76

def union(fa)
  perform_set_operation(:union, fa)
end