code: func reverse(a *Automaton) (*Automaton, map[int]bool) {
  	if isEmpty(a) {
  		return newEmptyAutomaton(), nil
  	}
  
  	numStates := a.numStates()
  
  	// build a new automaton with all edges reversed
  	b := newAutomatonBuilder()
  
  	// initial node; we'll add epsilon transitions in the end:
  	b.createState()
  	for s := 0; s < numStates; s++ {
  		b.createState()
  	}
  
  	// old initial state becomes new accept state:
  	b.setAccept(1, true)
  
  	t := newTransition()
  	for s := 0; s < numStates; s++ {
  		numTransitions := a.numTransitions(s)
  		a.initTransition(s, t)
  		for i := 0; i < numTransitions; i++ {
  			a.nextTransition(t)
  			b.addTransitionRange(t.dest+1, s+1, t.min, t.max)
  		}
  	}
  
  	ans := b.finish()
  	initialStates := make(map[int]bool)
  
  	acceptStates := a.isAccept
  	for s := acceptStates.NextSetBit(0); s != -1; s = acceptStates.NextSetBit(s + 1) {
  		ans.addEpsilon(0, int(s+1))
  		initialStates[int(s+1)] = true
  	}
  
  	ans.finishState()
  	return ans, initialStates
  }
docs: /* Returns an automaton accepting the reverse language. */