Ejemplo n.º 1
0
func NewAutomaton(a *tomato.Automaton, targets []*tomato.State) tomato.Transition {
	if len(a.Ends()) != len(targets) {
		panic("Automaton transition targets must have same length as automaton ending states")
	}

	return &automatonTransition{a, targets}
}
Ejemplo n.º 2
0
// Transform any automaton to a synchronized and determinized automaton.
func Determinize(a *tomato.Automaton) *tomato.Automaton {
	closures := []Closure{}
	states := []*tomato.State{}
	ends := []*tomato.State{}

	var collect func(state *tomato.State) *tomato.State
	collect = func(state *tomato.State) *tomato.State {
		closure := EpsilonClosure(state)

		// Make sure this closure hasn't been already processed
		for i, c := range closures {
			if closure.equals(c) {
				return states[i]
			}
		}

		// Create a new state for this closure
		state = tomato.NewState()

		// Collect this closure's transitons
		trs := closureTransitions(closure)

		// Add closure & new state to list
		closures = append(closures, closure)
		states = append(states, state)

		// Does this new state is an ending one?
		if closureIsEnd(closure, a.Ends()) {
			ends = append(ends, state)
		}

		// Add transitions to new state
		for _, tr := range trs {
			targets := tr.Targets()
			newTargets := make([]*tomato.State, len(targets))
			for i, target := range targets {
				newTargets[i] = collect(target)
			}
			state.Add(tr.Duplicate(newTargets...))
		}

		return state
	}

	root := collect(a.Root())

	return tomato.NewAutomaton(root, ends)
}