Skip to content

A generic Nondeterministic Finite Automaton implementation in Swift (Standard library only - Foundation free!)

Notifications You must be signed in to change notification settings

mikidep/SwiftAutomata

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

24 Commits
 
 
 
 
 
 

Repository files navigation

SwiftNFA

SwiftNFA is a way to implement Nondeterministic Finite Automata in Swift. ###Usage SwiftNFA has a main generic class called NFA that represents the automaton. You can instantiate an automaton with NFA<StateType, SymbolType>(initialState: iState, acceptingStates: aStates), where StateType is the type of the objects that represent states of the automaton, SymbolType is the type of the objects that the automaton will be receiving as input, initialState is a StateType representation for the initial state and aStates an array (or Set) with the accepting states of the automaton. For example:

let automaton = NFA<Int, Character>(initialState: 0, acceptingStates: [1, 4])

Will give you an automaton that reads Character's, uses Int's to refer to its own states, starts in state 0 and accepts input if and only if there is a path in its graph ending in states 1 or 4 whose non-epsilon moves are sequentially given by the characters of the input. But I don't have to explain NFA's to you, do I?

The method addMoveFromState(forSymbol:toState) adds a transition with a given symbol of type SymbolType, or an ε-transition if the symbol is nil, from a given state to a given state. You may also use the methods addEpsilonMoveFromState(toState:), addMove() and addMoves() to add moves in whatever fashion you prefer. addMove() will take a 3-tuple composed by the applicable state, the symbol (which, again, can be nil to signify an ε-move) and the target state; addMoves() will take an array of such tuples.

For example, consider the following NFA:

NFA example

Starting from the automaton instantiated above, the one in the picture is constructed with the following code (the order of the instructions is not relevant):

automaton.addMoveFromState(1, forSymbol: "a", toState: 1)
automaton.addMoveFromState(0, forSymbol: nil, toState: 1)   // nil symbol: ε-move!
automaton.addEpsilonMoveFromState(0, toState:2)
automaton.addMove((2, "a", 3))
automaton.addMoves([(3, "b", 4), (4, nil, 2)])

After you've added new moves, you need to call the initialize() method before you can run the automaton, like so:

automaton.initialize()

This is also the method you need to call if you want to reset the automaton to its initial state. After the initialization, the automaton is iterated via the method iterateWithSymbol(), with an argument of type SymbolType of course. The method returns a member of the enum NFAStatus, either .Running if the automaton is still running but has not reached an accepting state yet, or .Accepting if the automaton has reached an accepting state, or nil if the automaton dies (i.e. there is no possible move to follow for the given symbol).

let test = "ababaa  "
for c in test {
	println(automaton.iterateWithSymbol(c))
}

The code above outputs:

Optional(NFAStatus.Accepting)
Optional(NFAStatus.Accepting)
Optional(NFAStatus.Running)
Optional(NFAStatus.Accepting)
Optional(NFAStatus.Running)
nil
nil
nil

###Initializers NFA features two initializers, one for a machine without moves, and another, init(movesTable: (symbolMoves:, epsilonMoves:), initialState:, acceptingStates:) which lets you specify a moves table: this is given as a tuple composed by a 2D Map with the non-ε moves, such that symbolMoves[state, symbol] = targetState, and a Dictionary containing all the ε-moves such that epsilonMoves[state] = targetState. A table of the same format is also the value of the read only property movesTable, which exposes the machine's current transitions table.

###What's with the Foundation free thing? As far as I know, there is still a possibility that Apple will open source Swift as it consolidates into a more stable language; furthermore, an open source port called Phoenix is being developed. Anyway, in addition to me being a fan of standard libraries, I would love to see SwiftNFA used in some open source code outside the Apple ecosystem, and using Apple's Foundation wouldn't make it just as easy and clean.

About

A generic Nondeterministic Finite Automaton implementation in Swift (Standard library only - Foundation free!)

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages