Created
May 18, 2009 07:06
-
-
Save jarsen/113356 to your computer and use it in GitHub Desktop.
For a cs theory class. Will take a NFA-lambda machine and print out it's corresponding DFA
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby -wKU | |
#nfa_converter.rb | |
# converts a given NFA-lambda to it's corresponding DFA and prints | |
# corresponding transition rules. | |
$: << File.expand_path(File.dirname(__FILE__)) | |
require 'NFA' | |
ARGV.each do |fileName| # each argument passed through bash is a file to convert | |
puts "Constructing state machine for #{fileName}..." | |
nfa = NFA.new fileName | |
puts "Original NFA-Lambda:" | |
puts nfa | |
puts | |
puts "Corresponding DFA:" | |
puts nfa.to_DFA | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'set' | |
class State | |
attr_accessor :name | |
def initialize(name) | |
@name = name | |
end | |
def to_s | |
name | |
end | |
end | |
class Transition | |
attr_accessor :state, :symbol, :next_state | |
def initialize state, symbol, next_state | |
@state, @symbol, @next_state = state, symbol, next_state | |
end | |
def lambda? | |
@symbol == "l" | |
end | |
def to_s | |
state + symbol + next_state | |
end | |
end | |
class NFA | |
attr_accessor :states, :alphabet, :transitions, :start, :finals | |
def initialize fileName | |
@states = Set.new # set up all of the arrays for keepings states and things | |
@alphabet = Set.new | |
@transitions = Set.new | |
@finals = Set.new | |
file = File.read(fileName).split("\n") #read in the file | |
@start = State.new file.shift #get the name of the start state | |
@states.add @start | |
#add line 2 - final states | |
file.shift.split(" ").each do |name| | |
state = State.new name | |
@states.add state | |
@finals.add state | |
end | |
#add line 4 - non-final states | |
file.shift.split(" ").each do |name| | |
@states.add State.new(name) | |
end | |
#the rest are transitions | |
file.each do |line| | |
state, symbol, next_state = line.split(/([a-z]*)/) | |
transitions.add Transition.new(state, symbol, next_state) | |
alphabet.add symbol | |
end | |
end | |
def to_DFA | |
q_prime = lambda_closure start.name # step 1 | |
while true # step 2 | |
continue = do #figure out if we have more to do | |
end | |
if continue do | |
y = t | |
else break | |
end | |
end | |
end | |
def t qi, symbol | |
closure = lambda_closure qi | |
results = Set.new closure | |
# find a transition where symbol and qj match, add to new closure | |
transitions.each do |transition| | |
if closure.include? transition.state and transition.symbol == symbol then | |
results.add transition.next_state | |
end | |
end | |
results | |
end | |
def lambda_closure qi | |
closure = Set.new [qi] # basis | |
transitions.each do |transition| # recursive step | |
closure.merge lambda_closure(transition.next_state) if transition.state == qi and transition.lambda? | |
end | |
closure | |
end | |
def to_s | |
str = start.name + "\n" | |
finals.each { |state| str << state.name + " " } | |
str << "\n" | |
(states - finals - [start]).each { |state| str << state.name + " " } | |
str << "\n" | |
transitions.each { |transition| str << transition.to_s + "\n"} | |
return str | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment