NFA-to-DFA 1.0.0
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.
- checksums.yaml +7 -0
 - data/lib/automaton.rb +310 -0
 - data/lib/state.rb +65 -0
 - data/lib/transition.rb +22 -0
 - metadata +46 -0
 
    
        checksums.yaml
    ADDED
    
    | 
         @@ -0,0 +1,7 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ---
         
     | 
| 
      
 2 
     | 
    
         
            +
            SHA1:
         
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: dfd6b44cf52809252cbc5a8657bbeedd881febd4
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: c97a3151f4c9b8f79c1ece3a5a323ba3b7a1167f
         
     | 
| 
      
 5 
     | 
    
         
            +
            SHA512:
         
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: d503c1d3b97952d578abb318ed435914e2eef4866811321c076c5ef3a80a87155a07db13ce6966fb5e58bba8c8d356f19124745915a44bd6bedfc93f7554af10
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: a51012d5dec578b58a4a66e0dea5ca4ca7bfc1f4253ba110cb25e2e032e361de8c5b48f9ca2bbb458446dc24d2693687dd3ff67ce397ad3c04d3ae56f9f8097e
         
     | 
    
        data/lib/automaton.rb
    ADDED
    
    | 
         @@ -0,0 +1,310 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #z f - mnozina stavu
         
     | 
| 
      
 2 
     | 
    
         
            +
            #a b - vstupni abeceda
         
     | 
| 
      
 3 
     | 
    
         
            +
            #z-a-f f-b-f - prechod Q-T-Q ze stavu Q pres pismeno T do stavu Q
         
     | 
| 
      
 4 
     | 
    
         
            +
            #z - Pocatecni stav
         
     | 
| 
      
 5 
     | 
    
         
            +
            #f - mnozina koncovych stavu
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            require 'graphviz'
         
     | 
| 
      
 8 
     | 
    
         
            +
            require_relative 'state.rb'
         
     | 
| 
      
 9 
     | 
    
         
            +
            require_relative 'transition.rb'
         
     | 
| 
      
 10 
     | 
    
         
            +
            class Automaton
         
     | 
| 
      
 11 
     | 
    
         
            +
              
         
     | 
| 
      
 12 
     | 
    
         
            +
              public
         
     | 
| 
      
 13 
     | 
    
         
            +
              
         
     | 
| 
      
 14 
     | 
    
         
            +
              def to_str
         
     | 
| 
      
 15 
     | 
    
         
            +
                ret_val = ""
         
     | 
| 
      
 16 
     | 
    
         
            +
                str = ""
         
     | 
| 
      
 17 
     | 
    
         
            +
                @states.each do |state|
         
     | 
| 
      
 18 
     | 
    
         
            +
                  str += state.id + " "
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
                ret_val += str.byteslice(0, str.length-1) + "\n"
         
     | 
| 
      
 21 
     | 
    
         
            +
                str = ""
         
     | 
| 
      
 22 
     | 
    
         
            +
               @alphabet.each do |a|
         
     | 
| 
      
 23 
     | 
    
         
            +
                  str+= a + " "
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
                ret_val += str.byteslice(0, str.length-1) + "\n"
         
     | 
| 
      
 26 
     | 
    
         
            +
                str = ""
         
     | 
| 
      
 27 
     | 
    
         
            +
                @transitions.each do |trans|
         
     | 
| 
      
 28 
     | 
    
         
            +
                  str += trans.beginning_state.id + "-" + trans.alphabet + "-" + trans.ending_state.id + " "
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
                ret_val += str.byteslice(0, str.length-1) + "\n"
         
     | 
| 
      
 31 
     | 
    
         
            +
                str = ""
         
     | 
| 
      
 32 
     | 
    
         
            +
                ret_val += @starting_state.id + "\n"
         
     | 
| 
      
 33 
     | 
    
         
            +
                @states.each do |state|
         
     | 
| 
      
 34 
     | 
    
         
            +
                  if state.is_final == true
         
     | 
| 
      
 35 
     | 
    
         
            +
                    str += state.id + " "
         
     | 
| 
      
 36 
     | 
    
         
            +
                  end
         
     | 
| 
      
 37 
     | 
    
         
            +
                end
         
     | 
| 
      
 38 
     | 
    
         
            +
                ret_val += str.byteslice(0, str.length-1)
         
     | 
| 
      
 39 
     | 
    
         
            +
                ret_val
         
     | 
| 
      
 40 
     | 
    
         
            +
              end
         
     | 
| 
      
 41 
     | 
    
         
            +
              
         
     | 
| 
      
 42 
     | 
    
         
            +
              def to_graph(path)
         
     | 
| 
      
 43 
     | 
    
         
            +
                g = GraphViz.new( :G, :type => :digraph)
         
     | 
| 
      
 44 
     | 
    
         
            +
                @states.each do |state|
         
     | 
| 
      
 45 
     | 
    
         
            +
                  #puts state.id
         
     | 
| 
      
 46 
     | 
    
         
            +
                  state.to_graph_node(g)
         
     | 
| 
      
 47 
     | 
    
         
            +
                end
         
     | 
| 
      
 48 
     | 
    
         
            +
                g.each_node() do |name, node|
         
     | 
| 
      
 49 
     | 
    
         
            +
                  # puts name
         
     | 
| 
      
 50 
     | 
    
         
            +
                end
         
     | 
| 
      
 51 
     | 
    
         
            +
                @transitions.each do |trans|
         
     | 
| 
      
 52 
     | 
    
         
            +
                  trans.to_graph_transition(g)
         
     | 
| 
      
 53 
     | 
    
         
            +
                end
         
     | 
| 
      
 54 
     | 
    
         
            +
                g.each_edge do |ed|
         
     | 
| 
      
 55 
     | 
    
         
            +
                  #puts ed.node_one + " " + ed.node_two
         
     | 
| 
      
 56 
     | 
    
         
            +
                end
         
     | 
| 
      
 57 
     | 
    
         
            +
                g.output( :png => path )
         
     | 
| 
      
 58 
     | 
    
         
            +
              end
         
     | 
| 
      
 59 
     | 
    
         
            +
              
         
     | 
| 
      
 60 
     | 
    
         
            +
              def self.init(path)
         
     | 
| 
      
 61 
     | 
    
         
            +
                #nacteni ze souboru
         
     | 
| 
      
 62 
     | 
    
         
            +
                if File.file?(path)
         
     | 
| 
      
 63 
     | 
    
         
            +
                  data_arr = Array.new
         
     | 
| 
      
 64 
     | 
    
         
            +
                  index = 0
         
     | 
| 
      
 65 
     | 
    
         
            +
                  File.open(path).each_line do |line|
         
     | 
| 
      
 66 
     | 
    
         
            +
                    data_arr[index] = line
         
     | 
| 
      
 67 
     | 
    
         
            +
                    index = index + 1
         
     | 
| 
      
 68 
     | 
    
         
            +
                  end
         
     | 
| 
      
 69 
     | 
    
         
            +
                  if validate(data_arr)
         
     | 
| 
      
 70 
     | 
    
         
            +
                    get_valid_input(data_arr)
         
     | 
| 
      
 71 
     | 
    
         
            +
                  else
         
     | 
| 
      
 72 
     | 
    
         
            +
                    puts "Invalid input"
         
     | 
| 
      
 73 
     | 
    
         
            +
                    NIL
         
     | 
| 
      
 74 
     | 
    
         
            +
                  end
         
     | 
| 
      
 75 
     | 
    
         
            +
                else
         
     | 
| 
      
 76 
     | 
    
         
            +
                  puts "Invalid input"
         
     | 
| 
      
 77 
     | 
    
         
            +
                  NIL
         
     | 
| 
      
 78 
     | 
    
         
            +
                end
         
     | 
| 
      
 79 
     | 
    
         
            +
              end
         
     | 
| 
      
 80 
     | 
    
         
            +
              
         
     | 
| 
      
 81 
     | 
    
         
            +
              def self.validate(data_arr)
         
     | 
| 
      
 82 
     | 
    
         
            +
                parsed = []
         
     | 
| 
      
 83 
     | 
    
         
            +
                data_arr.each do |item|
         
     | 
| 
      
 84 
     | 
    
         
            +
                  parsed.push item.split(' ')
         
     | 
| 
      
 85 
     | 
    
         
            +
                end
         
     | 
| 
      
 86 
     | 
    
         
            +
                validate_transitions(parsed[0], parsed[1], parsed[2]) && validate_states(parsed[0], parsed[3], parsed[4])
         
     | 
| 
      
 87 
     | 
    
         
            +
              end
         
     | 
| 
      
 88 
     | 
    
         
            +
              
         
     | 
| 
      
 89 
     | 
    
         
            +
              #format: pismeno<mezera>pismeno...
         
     | 
| 
      
 90 
     | 
    
         
            +
              def accepts?(data)
         
     | 
| 
      
 91 
     | 
    
         
            +
                formatted_input = data.split(' ')
         
     | 
| 
      
 92 
     | 
    
         
            +
                @stack = Array.new
         
     | 
| 
      
 93 
     | 
    
         
            +
                @stack.push(@starting_state)
         
     | 
| 
      
 94 
     | 
    
         
            +
                formatted_input.size == 0 ? @starting_state.is_final : recurs_accepts?(formatted_input, 0)
         
     | 
| 
      
 95 
     | 
    
         
            +
              end
         
     | 
| 
      
 96 
     | 
    
         
            +
              
         
     | 
| 
      
 97 
     | 
    
         
            +
              def deterministic?
         
     | 
| 
      
 98 
     | 
    
         
            +
                @states.each do |state|
         
     | 
| 
      
 99 
     | 
    
         
            +
                  @alphabet.each do |char|
         
     | 
| 
      
 100 
     | 
    
         
            +
                    if state.get_next(char).size > 1
         
     | 
| 
      
 101 
     | 
    
         
            +
                      return false
         
     | 
| 
      
 102 
     | 
    
         
            +
                    end
         
     | 
| 
      
 103 
     | 
    
         
            +
                  end
         
     | 
| 
      
 104 
     | 
    
         
            +
                end
         
     | 
| 
      
 105 
     | 
    
         
            +
                true
         
     | 
| 
      
 106 
     | 
    
         
            +
              end
         
     | 
| 
      
 107 
     | 
    
         
            +
              
         
     | 
| 
      
 108 
     | 
    
         
            +
              def determine
         
     | 
| 
      
 109 
     | 
    
         
            +
                deterministic? ? self : determine_prot
         
     | 
| 
      
 110 
     | 
    
         
            +
              end
         
     | 
| 
      
 111 
     | 
    
         
            +
              
         
     | 
| 
      
 112 
     | 
    
         
            +
              protected
         
     | 
| 
      
 113 
     | 
    
         
            +
              
         
     | 
| 
      
 114 
     | 
    
         
            +
              attr_accessor :states, :alphabet, :transitions, :starting_state, :stack
         
     | 
| 
      
 115 
     | 
    
         
            +
              
         
     | 
| 
      
 116 
     | 
    
         
            +
              def recurs_accepts?(data, index)
         
     | 
| 
      
 117 
     | 
    
         
            +
                ret_val = false
         
     | 
| 
      
 118 
     | 
    
         
            +
                if @stack.size != 0
         
     | 
| 
      
 119 
     | 
    
         
            +
                  cnt = resolve_state_on_stack(data[index])
         
     | 
| 
      
 120 
     | 
    
         
            +
                  index = index + 1
         
     | 
| 
      
 121 
     | 
    
         
            +
                  if index == data.size
         
     | 
| 
      
 122 
     | 
    
         
            +
                    cnt.times do
         
     | 
| 
      
 123 
     | 
    
         
            +
                      if @stack.pop.is_final
         
     | 
| 
      
 124 
     | 
    
         
            +
                        ret_val = true
         
     | 
| 
      
 125 
     | 
    
         
            +
                      end
         
     | 
| 
      
 126 
     | 
    
         
            +
                    end
         
     | 
| 
      
 127 
     | 
    
         
            +
                  else
         
     | 
| 
      
 128 
     | 
    
         
            +
                    return recurs_accepts?(data,index)
         
     | 
| 
      
 129 
     | 
    
         
            +
                  end
         
     | 
| 
      
 130 
     | 
    
         
            +
                end
         
     | 
| 
      
 131 
     | 
    
         
            +
                ret_val
         
     | 
| 
      
 132 
     | 
    
         
            +
              end
         
     | 
| 
      
 133 
     | 
    
         
            +
              
         
     | 
| 
      
 134 
     | 
    
         
            +
              def self.get_valid_input(data_arr)
         
     | 
| 
      
 135 
     | 
    
         
            +
                states = Array.new
         
     | 
| 
      
 136 
     | 
    
         
            +
                fin = data_arr[4].split(' ')
         
     | 
| 
      
 137 
     | 
    
         
            +
                  
         
     | 
| 
      
 138 
     | 
    
         
            +
                data_arr[0].split(' ').each do |wrd|
         
     | 
| 
      
 139 
     | 
    
         
            +
                  states.push State.new(wrd)
         
     | 
| 
      
 140 
     | 
    
         
            +
                end
         
     | 
| 
      
 141 
     | 
    
         
            +
                fin.include?(states[0].id)
         
     | 
| 
      
 142 
     | 
    
         
            +
                states.each do |st|
         
     | 
| 
      
 143 
     | 
    
         
            +
                  (fin.include? st.id) ? st.finalize : NIL
         
     | 
| 
      
 144 
     | 
    
         
            +
                end
         
     | 
| 
      
 145 
     | 
    
         
            +
                alphabet = Array.new
         
     | 
| 
      
 146 
     | 
    
         
            +
                data_arr[1].split(' ').each do |wrd|
         
     | 
| 
      
 147 
     | 
    
         
            +
                  alphabet.insert(alphabet.size, wrd)
         
     | 
| 
      
 148 
     | 
    
         
            +
                end
         
     | 
| 
      
 149 
     | 
    
         
            +
                transitions = Array.new
         
     | 
| 
      
 150 
     | 
    
         
            +
                data_arr[2].split(' ').each do |wrd|
         
     | 
| 
      
 151 
     | 
    
         
            +
                  trans = wrd.split('-')
         
     | 
| 
      
 152 
     | 
    
         
            +
                  state1 = NIL
         
     | 
| 
      
 153 
     | 
    
         
            +
                  state2 = NIL
         
     | 
| 
      
 154 
     | 
    
         
            +
                  states.each do |item|
         
     | 
| 
      
 155 
     | 
    
         
            +
                    trans[0] == item.id ? state1 = item : NIL
         
     | 
| 
      
 156 
     | 
    
         
            +
                    trans[2] == item.id ? state2 = item : NIL
         
     | 
| 
      
 157 
     | 
    
         
            +
                    state1 != NIL && state2 != NIL ? break : NIL
         
     | 
| 
      
 158 
     | 
    
         
            +
                  end
         
     | 
| 
      
 159 
     | 
    
         
            +
                  transitions.insert(transitions.size, Transition.new(state1, trans[1], state2))
         
     | 
| 
      
 160 
     | 
    
         
            +
                  state1.add_transition(transitions[transitions.size-1])
         
     | 
| 
      
 161 
     | 
    
         
            +
                end
         
     | 
| 
      
 162 
     | 
    
         
            +
                starting = NIL
         
     | 
| 
      
 163 
     | 
    
         
            +
                states.each do |item2|
         
     | 
| 
      
 164 
     | 
    
         
            +
                  if item2.id == data_arr[3].split(' ')[0]
         
     | 
| 
      
 165 
     | 
    
         
            +
                    starting = item2
         
     | 
| 
      
 166 
     | 
    
         
            +
                    item2.to_starting_node
         
     | 
| 
      
 167 
     | 
    
         
            +
                    break
         
     | 
| 
      
 168 
     | 
    
         
            +
                  end
         
     | 
| 
      
 169 
     | 
    
         
            +
                end
         
     | 
| 
      
 170 
     | 
    
         
            +
                Automaton.new(states, alphabet, transitions, starting)
         
     | 
| 
      
 171 
     | 
    
         
            +
              end
         
     | 
| 
      
 172 
     | 
    
         
            +
              
         
     | 
| 
      
 173 
     | 
    
         
            +
              def determine_prot
         
     | 
| 
      
 174 
     | 
    
         
            +
                #https://edux.fit.cvut.cz/courses/BI-AAG/_media/lectures/03/bi-aag-03-operace_s_automaty-4.pdf
         
     | 
| 
      
 175 
     | 
    
         
            +
                undetermined_states = Array.new
         
     | 
| 
      
 176 
     | 
    
         
            +
                determined_states = Array.new
         
     | 
| 
      
 177 
     | 
    
         
            +
                transits = Array.new
         
     | 
| 
      
 178 
     | 
    
         
            +
                tot_transits = Array.new
         
     | 
| 
      
 179 
     | 
    
         
            +
                curr_states = Array.new
         
     | 
| 
      
 180 
     | 
    
         
            +
                undetermined_states[0] = @starting_state.clone
         
     | 
| 
      
 181 
     | 
    
         
            +
                new_begin_state = undetermined_states[0]
         
     | 
| 
      
 182 
     | 
    
         
            +
                while(undetermined_states.size > 0)
         
     | 
| 
      
 183 
     | 
    
         
            +
                  temp_state = undetermined_states[0]
         
     | 
| 
      
 184 
     | 
    
         
            +
                  curr_states.clear
         
     | 
| 
      
 185 
     | 
    
         
            +
                  transits.clear
         
     | 
| 
      
 186 
     | 
    
         
            +
                  @alphabet.each do |char|
         
     | 
| 
      
 187 
     | 
    
         
            +
                    t_states_by_char = temp_state.get_next(char)
         
     | 
| 
      
 188 
     | 
    
         
            +
                    if t_states_by_char.size > 0
         
     | 
| 
      
 189 
     | 
    
         
            +
                      state_id = merge_state_names(t_states_by_char)
         
     | 
| 
      
 190 
     | 
    
         
            +
                      state = find_state(state_id, determined_states, undetermined_states)
         
     | 
| 
      
 191 
     | 
    
         
            +
                      if state
         
     | 
| 
      
 192 
     | 
    
         
            +
                        transits.push(Transition.new(temp_state, char, state))
         
     | 
| 
      
 193 
     | 
    
         
            +
                        tot_transits.push(Transition.new(temp_state, char, state))
         
     | 
| 
      
 194 
     | 
    
         
            +
                      else
         
     | 
| 
      
 195 
     | 
    
         
            +
                        #Tvorba noveho statu
         
     | 
| 
      
 196 
     | 
    
         
            +
                        state = State.new(state_id)
         
     | 
| 
      
 197 
     | 
    
         
            +
                        state.associate_transitions(@transitions)
         
     | 
| 
      
 198 
     | 
    
         
            +
                        undetermined_states.push(state)
         
     | 
| 
      
 199 
     | 
    
         
            +
                        transits.push(Transition.new(temp_state, char, state))
         
     | 
| 
      
 200 
     | 
    
         
            +
                        tot_transits.push(Transition.new(temp_state, char, state))
         
     | 
| 
      
 201 
     | 
    
         
            +
                      end
         
     | 
| 
      
 202 
     | 
    
         
            +
                    end
         
     | 
| 
      
 203 
     | 
    
         
            +
                  end
         
     | 
| 
      
 204 
     | 
    
         
            +
                  temp_state.clear_transitions
         
     | 
| 
      
 205 
     | 
    
         
            +
                  transits.each do |transit|
         
     | 
| 
      
 206 
     | 
    
         
            +
                    temp_state.add_transition(transit)
         
     | 
| 
      
 207 
     | 
    
         
            +
                  end
         
     | 
| 
      
 208 
     | 
    
         
            +
                  undetermined_states.delete(temp_state)
         
     | 
| 
      
 209 
     | 
    
         
            +
                  determined_states.push(temp_state)
         
     | 
| 
      
 210 
     | 
    
         
            +
                end
         
     | 
| 
      
 211 
     | 
    
         
            +
                
         
     | 
| 
      
 212 
     | 
    
         
            +
                determined_states
         
     | 
| 
      
 213 
     | 
    
         
            +
                @alphabet
         
     | 
| 
      
 214 
     | 
    
         
            +
                tot_transits
         
     | 
| 
      
 215 
     | 
    
         
            +
                new_begin_state
         
     | 
| 
      
 216 
     | 
    
         
            +
                finals = associate_finals(determined_states)
         
     | 
| 
      
 217 
     | 
    
         
            +
                Automaton.new(determined_states, @alphabet.clone, tot_transits, new_begin_state)
         
     | 
| 
      
 218 
     | 
    
         
            +
              end
         
     | 
| 
      
 219 
     | 
    
         
            +
              
         
     | 
| 
      
 220 
     | 
    
         
            +
              private
         
     | 
| 
      
 221 
     | 
    
         
            +
              
         
     | 
| 
      
 222 
     | 
    
         
            +
              def associate_finals(stat)
         
     | 
| 
      
 223 
     | 
    
         
            +
                ret_val = Array.new
         
     | 
| 
      
 224 
     | 
    
         
            +
                @states.each do |orig|
         
     | 
| 
      
 225 
     | 
    
         
            +
                  if orig.is_final
         
     | 
| 
      
 226 
     | 
    
         
            +
                    stat.each do |state|
         
     | 
| 
      
 227 
     | 
    
         
            +
                      state.id.split(',').each do |id|
         
     | 
| 
      
 228 
     | 
    
         
            +
                        if id == orig.id
         
     | 
| 
      
 229 
     | 
    
         
            +
                          state.finalize
         
     | 
| 
      
 230 
     | 
    
         
            +
                          ret_val.push(state)
         
     | 
| 
      
 231 
     | 
    
         
            +
                          break 2
         
     | 
| 
      
 232 
     | 
    
         
            +
                        end
         
     | 
| 
      
 233 
     | 
    
         
            +
                      end
         
     | 
| 
      
 234 
     | 
    
         
            +
                    end
         
     | 
| 
      
 235 
     | 
    
         
            +
                  end
         
     | 
| 
      
 236 
     | 
    
         
            +
                end
         
     | 
| 
      
 237 
     | 
    
         
            +
                ret_val
         
     | 
| 
      
 238 
     | 
    
         
            +
              end
         
     | 
| 
      
 239 
     | 
    
         
            +
              
         
     | 
| 
      
 240 
     | 
    
         
            +
              def find_state(state_id, container, container2)
         
     | 
| 
      
 241 
     | 
    
         
            +
                str = ""
         
     | 
| 
      
 242 
     | 
    
         
            +
                state_id.split(' ').sort.each do |st|
         
     | 
| 
      
 243 
     | 
    
         
            +
                  str += st
         
     | 
| 
      
 244 
     | 
    
         
            +
                end
         
     | 
| 
      
 245 
     | 
    
         
            +
                # state_id = str.slice(0, str.size - 2)
         
     | 
| 
      
 246 
     | 
    
         
            +
                container.each do |state|
         
     | 
| 
      
 247 
     | 
    
         
            +
                  if state.id == state_id
         
     | 
| 
      
 248 
     | 
    
         
            +
                    return state
         
     | 
| 
      
 249 
     | 
    
         
            +
                  end
         
     | 
| 
      
 250 
     | 
    
         
            +
                end
         
     | 
| 
      
 251 
     | 
    
         
            +
                container2.each do |state|
         
     | 
| 
      
 252 
     | 
    
         
            +
                  if state.id == state_id
         
     | 
| 
      
 253 
     | 
    
         
            +
                    return state
         
     | 
| 
      
 254 
     | 
    
         
            +
                  end
         
     | 
| 
      
 255 
     | 
    
         
            +
                end
         
     | 
| 
      
 256 
     | 
    
         
            +
                NIL
         
     | 
| 
      
 257 
     | 
    
         
            +
              end
         
     | 
| 
      
 258 
     | 
    
         
            +
              
         
     | 
| 
      
 259 
     | 
    
         
            +
              def merge_state_names(states)
         
     | 
| 
      
 260 
     | 
    
         
            +
                arr = Array.new
         
     | 
| 
      
 261 
     | 
    
         
            +
                states.each do |state|
         
     | 
| 
      
 262 
     | 
    
         
            +
                  arr.push(state.id)
         
     | 
| 
      
 263 
     | 
    
         
            +
                end
         
     | 
| 
      
 264 
     | 
    
         
            +
                arr = arr.uniq.sort
         
     | 
| 
      
 265 
     | 
    
         
            +
                last = arr.pop
         
     | 
| 
      
 266 
     | 
    
         
            +
                str = ""
         
     | 
| 
      
 267 
     | 
    
         
            +
                arr.each do |id|
         
     | 
| 
      
 268 
     | 
    
         
            +
                  str += id + ","
         
     | 
| 
      
 269 
     | 
    
         
            +
                end
         
     | 
| 
      
 270 
     | 
    
         
            +
                str += last
         
     | 
| 
      
 271 
     | 
    
         
            +
                str
         
     | 
| 
      
 272 
     | 
    
         
            +
              end
         
     | 
| 
      
 273 
     | 
    
         
            +
              
         
     | 
| 
      
 274 
     | 
    
         
            +
              def resolve_state_on_stack(char)
         
     | 
| 
      
 275 
     | 
    
         
            +
                popped = @stack.pop
         
     | 
| 
      
 276 
     | 
    
         
            +
                arr = popped.get_next(char)
         
     | 
| 
      
 277 
     | 
    
         
            +
                arr.each do |item|
         
     | 
| 
      
 278 
     | 
    
         
            +
                  @stack.push(item)
         
     | 
| 
      
 279 
     | 
    
         
            +
                end
         
     | 
| 
      
 280 
     | 
    
         
            +
                arr.size
         
     | 
| 
      
 281 
     | 
    
         
            +
              end
         
     | 
| 
      
 282 
     | 
    
         
            +
              
         
     | 
| 
      
 283 
     | 
    
         
            +
              def initialize(stat_arr, alph_arr, trans_arr, start)
         
     | 
| 
      
 284 
     | 
    
         
            +
                @states = stat_arr
         
     | 
| 
      
 285 
     | 
    
         
            +
                @alphabet = alph_arr
         
     | 
| 
      
 286 
     | 
    
         
            +
                @transitions = trans_arr
         
     | 
| 
      
 287 
     | 
    
         
            +
                @starting_state = start
         
     | 
| 
      
 288 
     | 
    
         
            +
              end
         
     | 
| 
      
 289 
     | 
    
         
            +
              
         
     | 
| 
      
 290 
     | 
    
         
            +
              def self.validate_states(states, start, final)
         
     | 
| 
      
 291 
     | 
    
         
            +
                if states.include? start[0]
         
     | 
| 
      
 292 
     | 
    
         
            +
                  final.each do |fin|
         
     | 
| 
      
 293 
     | 
    
         
            +
                    if !(states.include? fin)
         
     | 
| 
      
 294 
     | 
    
         
            +
                      return false
         
     | 
| 
      
 295 
     | 
    
         
            +
                    end
         
     | 
| 
      
 296 
     | 
    
         
            +
                    return true
         
     | 
| 
      
 297 
     | 
    
         
            +
                  end
         
     | 
| 
      
 298 
     | 
    
         
            +
                  return false
         
     | 
| 
      
 299 
     | 
    
         
            +
                end
         
     | 
| 
      
 300 
     | 
    
         
            +
                return false
         
     | 
| 
      
 301 
     | 
    
         
            +
              end
         
     | 
| 
      
 302 
     | 
    
         
            +
              
         
     | 
| 
      
 303 
     | 
    
         
            +
              def self.validate_transitions(states, alphabet, transitions)
         
     | 
| 
      
 304 
     | 
    
         
            +
                transitions.each do |tr|
         
     | 
| 
      
 305 
     | 
    
         
            +
                  trans = tr.split('-')
         
     | 
| 
      
 306 
     | 
    
         
            +
                  ((states.include? trans[0]) && (states.include? trans[2]) && (alphabet.include? trans[1])) ? NIL : (return false)
         
     | 
| 
      
 307 
     | 
    
         
            +
                end
         
     | 
| 
      
 308 
     | 
    
         
            +
                true
         
     | 
| 
      
 309 
     | 
    
         
            +
              end
         
     | 
| 
      
 310 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/state.rb
    ADDED
    
    | 
         @@ -0,0 +1,65 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # To change this template, choose Tools | Templates
         
     | 
| 
      
 2 
     | 
    
         
            +
            # and open the template in the editor.
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            require 'graphviz'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require_relative 'transition.rb'
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            class State
         
     | 
| 
      
 8 
     | 
    
         
            +
              attr_reader :id, :is_final, :graphviz_node, :is_starting
         
     | 
| 
      
 9 
     | 
    
         
            +
              
         
     | 
| 
      
 10 
     | 
    
         
            +
              def initialize(id)
         
     | 
| 
      
 11 
     | 
    
         
            +
                @id = id
         
     | 
| 
      
 12 
     | 
    
         
            +
                @is_final = false
         
     | 
| 
      
 13 
     | 
    
         
            +
                @transitions = Array.new
         
     | 
| 
      
 14 
     | 
    
         
            +
                @graphviz_init = false
         
     | 
| 
      
 15 
     | 
    
         
            +
                @is_starting = false
         
     | 
| 
      
 16 
     | 
    
         
            +
              end
         
     | 
| 
      
 17 
     | 
    
         
            +
              
         
     | 
| 
      
 18 
     | 
    
         
            +
              def to_starting_node
         
     | 
| 
      
 19 
     | 
    
         
            +
                @is_starting = true
         
     | 
| 
      
 20 
     | 
    
         
            +
              end
         
     | 
| 
      
 21 
     | 
    
         
            +
                
         
     | 
| 
      
 22 
     | 
    
         
            +
              def graph_id
         
     | 
| 
      
 23 
     | 
    
         
            +
                is_starting ? (@id + "/init") : @id
         
     | 
| 
      
 24 
     | 
    
         
            +
              end
         
     | 
| 
      
 25 
     | 
    
         
            +
              
         
     | 
| 
      
 26 
     | 
    
         
            +
              def to_graph_node(graphviz_graph)
         
     | 
| 
      
 27 
     | 
    
         
            +
                if @is_final
         
     | 
| 
      
 28 
     | 
    
         
            +
                  @graphviz_node = graphviz_graph.add_nodes(graph_id, :shape => "doublecircle")
         
     | 
| 
      
 29 
     | 
    
         
            +
                else
         
     | 
| 
      
 30 
     | 
    
         
            +
                  @graphviz_node = graphviz_graph.add_nodes(graph_id, :shape => "circle")
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
                @graphviz_init = false
         
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
      
 34 
     | 
    
         
            +
              
         
     | 
| 
      
 35 
     | 
    
         
            +
              def finalize
         
     | 
| 
      
 36 
     | 
    
         
            +
                @is_final = true
         
     | 
| 
      
 37 
     | 
    
         
            +
              end
         
     | 
| 
      
 38 
     | 
    
         
            +
              
         
     | 
| 
      
 39 
     | 
    
         
            +
              def add_transition(tr)
         
     | 
| 
      
 40 
     | 
    
         
            +
                @transitions.insert(@transitions.size, tr)
         
     | 
| 
      
 41 
     | 
    
         
            +
              end
         
     | 
| 
      
 42 
     | 
    
         
            +
              
         
     | 
| 
      
 43 
     | 
    
         
            +
              def clear_transitions
         
     | 
| 
      
 44 
     | 
    
         
            +
                @transitions.clear
         
     | 
| 
      
 45 
     | 
    
         
            +
              end
         
     | 
| 
      
 46 
     | 
    
         
            +
              
         
     | 
| 
      
 47 
     | 
    
         
            +
              def associate_transitions(all_transitions)
         
     | 
| 
      
 48 
     | 
    
         
            +
                @transitions.clear
         
     | 
| 
      
 49 
     | 
    
         
            +
                @id.split(',').each do |id_part|
         
     | 
| 
      
 50 
     | 
    
         
            +
                  all_transitions.each do |transition|
         
     | 
| 
      
 51 
     | 
    
         
            +
                    if id_part == transition.beginning_state.id
         
     | 
| 
      
 52 
     | 
    
         
            +
                      add_transition(transition)
         
     | 
| 
      
 53 
     | 
    
         
            +
                    end
         
     | 
| 
      
 54 
     | 
    
         
            +
                  end
         
     | 
| 
      
 55 
     | 
    
         
            +
                end
         
     | 
| 
      
 56 
     | 
    
         
            +
              end
         
     | 
| 
      
 57 
     | 
    
         
            +
              
         
     | 
| 
      
 58 
     | 
    
         
            +
              def get_next(char)
         
     | 
| 
      
 59 
     | 
    
         
            +
                ret_val = Array.new
         
     | 
| 
      
 60 
     | 
    
         
            +
                @transitions.each do |trans|
         
     | 
| 
      
 61 
     | 
    
         
            +
                  trans.alphabet == char ? ret_val.insert(ret_val.size, trans.ending_state) : NIL
         
     | 
| 
      
 62 
     | 
    
         
            +
                end
         
     | 
| 
      
 63 
     | 
    
         
            +
                ret_val
         
     | 
| 
      
 64 
     | 
    
         
            +
              end
         
     | 
| 
      
 65 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/transition.rb
    ADDED
    
    | 
         @@ -0,0 +1,22 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
             
     | 
| 
      
 2 
     | 
    
         
            +
            require 'graphviz'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require_relative 'state.rb'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            class Transition
         
     | 
| 
      
 6 
     | 
    
         
            +
              
         
     | 
| 
      
 7 
     | 
    
         
            +
              attr_reader :beginning_state, :alphabet, :ending_state
         
     | 
| 
      
 8 
     | 
    
         
            +
              
         
     | 
| 
      
 9 
     | 
    
         
            +
              def initialize(beg_state, alphabet, end_state)
         
     | 
| 
      
 10 
     | 
    
         
            +
                @beginning_state = beg_state
         
     | 
| 
      
 11 
     | 
    
         
            +
                @alphabet = alphabet
         
     | 
| 
      
 12 
     | 
    
         
            +
                @ending_state = end_state
         
     | 
| 
      
 13 
     | 
    
         
            +
              end
         
     | 
| 
      
 14 
     | 
    
         
            +
              
         
     | 
| 
      
 15 
     | 
    
         
            +
              def to_graph_transition(graphviz_graph)
         
     | 
| 
      
 16 
     | 
    
         
            +
                graphviz_graph.add_edges( @beginning_state.graphviz_node, @ending_state.graphviz_node, :label => @alphabet)
         
     | 
| 
      
 17 
     | 
    
         
            +
              end
         
     | 
| 
      
 18 
     | 
    
         
            +
              
         
     | 
| 
      
 19 
     | 
    
         
            +
              def print
         
     | 
| 
      
 20 
     | 
    
         
            +
                puts @beginning_state.id + "-" + @alphabet + "-" + @ending_state.id
         
     | 
| 
      
 21 
     | 
    
         
            +
              end
         
     | 
| 
      
 22 
     | 
    
         
            +
            end
         
     | 
    
        metadata
    ADDED
    
    | 
         @@ -0,0 +1,46 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            --- !ruby/object:Gem::Specification
         
     | 
| 
      
 2 
     | 
    
         
            +
            name: NFA-to-DFA
         
     | 
| 
      
 3 
     | 
    
         
            +
            version: !ruby/object:Gem::Version
         
     | 
| 
      
 4 
     | 
    
         
            +
              version: 1.0.0
         
     | 
| 
      
 5 
     | 
    
         
            +
            platform: ruby
         
     | 
| 
      
 6 
     | 
    
         
            +
            authors:
         
     | 
| 
      
 7 
     | 
    
         
            +
            - Martin Zachov
         
     | 
| 
      
 8 
     | 
    
         
            +
            autorequire: 
         
     | 
| 
      
 9 
     | 
    
         
            +
            bindir: bin
         
     | 
| 
      
 10 
     | 
    
         
            +
            cert_chain: []
         
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2013-10-15 00:00:00.000000000 Z
         
     | 
| 
      
 12 
     | 
    
         
            +
            dependencies: []
         
     | 
| 
      
 13 
     | 
    
         
            +
            description: Finite automaton determinizer
         
     | 
| 
      
 14 
     | 
    
         
            +
            email: nick@quaran.to
         
     | 
| 
      
 15 
     | 
    
         
            +
            executables: []
         
     | 
| 
      
 16 
     | 
    
         
            +
            extensions: []
         
     | 
| 
      
 17 
     | 
    
         
            +
            extra_rdoc_files: []
         
     | 
| 
      
 18 
     | 
    
         
            +
            files:
         
     | 
| 
      
 19 
     | 
    
         
            +
            - lib/state.rb
         
     | 
| 
      
 20 
     | 
    
         
            +
            - lib/automaton.rb
         
     | 
| 
      
 21 
     | 
    
         
            +
            - lib/transition.rb
         
     | 
| 
      
 22 
     | 
    
         
            +
            homepage: http://fit.cvut.cz
         
     | 
| 
      
 23 
     | 
    
         
            +
            licenses:
         
     | 
| 
      
 24 
     | 
    
         
            +
            - GNU GPL
         
     | 
| 
      
 25 
     | 
    
         
            +
            metadata: {}
         
     | 
| 
      
 26 
     | 
    
         
            +
            post_install_message: 
         
     | 
| 
      
 27 
     | 
    
         
            +
            rdoc_options: []
         
     | 
| 
      
 28 
     | 
    
         
            +
            require_paths:
         
     | 
| 
      
 29 
     | 
    
         
            +
            - lib
         
     | 
| 
      
 30 
     | 
    
         
            +
            required_ruby_version: !ruby/object:Gem::Requirement
         
     | 
| 
      
 31 
     | 
    
         
            +
              requirements:
         
     | 
| 
      
 32 
     | 
    
         
            +
              - - '>='
         
     | 
| 
      
 33 
     | 
    
         
            +
                - !ruby/object:Gem::Version
         
     | 
| 
      
 34 
     | 
    
         
            +
                  version: '0'
         
     | 
| 
      
 35 
     | 
    
         
            +
            required_rubygems_version: !ruby/object:Gem::Requirement
         
     | 
| 
      
 36 
     | 
    
         
            +
              requirements:
         
     | 
| 
      
 37 
     | 
    
         
            +
              - - '>='
         
     | 
| 
      
 38 
     | 
    
         
            +
                - !ruby/object:Gem::Version
         
     | 
| 
      
 39 
     | 
    
         
            +
                  version: '0'
         
     | 
| 
      
 40 
     | 
    
         
            +
            requirements: []
         
     | 
| 
      
 41 
     | 
    
         
            +
            rubyforge_project: 
         
     | 
| 
      
 42 
     | 
    
         
            +
            rubygems_version: 2.0.3
         
     | 
| 
      
 43 
     | 
    
         
            +
            signing_key: 
         
     | 
| 
      
 44 
     | 
    
         
            +
            specification_version: 4
         
     | 
| 
      
 45 
     | 
    
         
            +
            summary: Hola!
         
     | 
| 
      
 46 
     | 
    
         
            +
            test_files: []
         
     |