///|
/// Return whether any arc uses epsilon on either label side.
pub fn[W] transducer_has_epsilon(transducer : Transducer[W]) -> Bool {
  for arcs in transducer.outgoing {
    for arc in arcs {
      if label_is_epsilon(arc.input) || label_is_epsilon(arc.output) {
        return true
      }
    }
  }
  false
}

///|
fn[W] copy_builder_shell(transducer : Transducer[W]) -> TransducerBuilder[W] {
  let builder = transducer_builder(transducer.semiring)
  for _ in 0.. ignore(set_start(builder, start))
    None => ()
  }
  for state in 0.. ignore(set_final(builder, state, weight))
      None => ()
    }
  }
  builder
}

///|
/// Copy a transducer while replacing each output label with its input label.
pub fn[W] project_input(transducer : Transducer[W]) -> Transducer[W] {
  let builder = copy_builder_shell(transducer)
  for source in 0.. Transducer[W] {
  let builder = copy_builder_shell(transducer)
  for source in 0.. Transducer[W] {
  let builder = copy_builder_shell(transducer)
  for source in 0..