code: def build_compact_topo(
      tokens: List[int], with_self_loops: bool = True
  ) -> "k2.Fsa":
      """Build the compact CTC topology.
      Zero is assumed to be the ID of the blank symbol.
      See https://arxiv.org/abs/2110.03098
      """
      assert (
          -1 not in tokens
      ), "We assume -1 is ID of the final transition"
      assert 0 in tokens, "We assume 0 is the ID of the blank symbol"
  
      eps_num = tokens[-1] + 1
      selfloops_shift = int(with_self_loops)
      num_states = len(tokens) + selfloops_shift
      final_state = num_states
      arcs = ""
      for i in range(selfloops_shift, num_states):
          arcs += f"0 {i} {tokens[i - selfloops_shift]} {tokens[i - selfloops_shift]} 0.0\n"
      arcs += f"0 {final_state} -1 -1 0.0\n"
      for i in range(1, num_states):
          arcs += f"{i} 0 {eps_num} 0 0.0\n"
          if with_self_loops:
              arcs += f"{i} {i} {tokens[i - selfloops_shift]} 0 0.0\n"
      arcs += f"{final_state}"
      ans = k2.Fsa.from_str(arcs, num_aux_labels=1)
      ans = k2.arc_sort(ans)
      return ans
  
file_path: NeMo/nemo/collections/asr/parts/k2/topologies.py
imports: from functools import lru_cache
  from typing import List, Optional, Union
  import torch
  from nemo.core.utils.k2_guard import k2
label_desc: Use image node_id 3 for calling a global function with example usage: build_compact_topo(tokens, with__loops) and returns: ans