code: def compile_HLG(
      lang_dir: str, graph_dir: str, ngram_num: int
  ) -> k2.Fsa:
      """
      Args:
        lang_dir:
          The language directory contains lexicon fst
        graph_dir:
          The graph and output directory contains grammar fst
        ngram_num:
          Max order of n-gram language model
  
      Return:
        An FSA representing HLG.
      """
      lexicon = Lexicon(lang_dir)
      max_token_id = max(lexicon.tokens)
      logging.info(f"Building ctc_topo. max_token_id: {max_token_id}")
      H = make_h_no_blank(max_token_id)
      L = k2.Fsa.from_dict(torch.load(f"{lang_dir}/L_disambig.pt"))
  
      logging.info(f"Loading G_{ngram_num}_gram.fst.txt")
      with open(f"{graph_dir}/G_{ngram_num}_gram.fst.txt") as f:
          G = k2.Fsa.from_openfst(f.read(), acceptor=False)
          torch.save(G.as_dict(), f"{graph_dir}/G_{ngram_num}_gram.pt")
  
      first_token_disambig_id = lexicon.token_table["#0"]
      first_word_disambig_id = lexicon.word_table["#0"]
  
      L = k2.arc_sort(L)
      G = k2.arc_sort(G)
  
      logging.info("Intersecting L and G")
      LG = k2.compose(L, G)
      logging.info(f"LG shape: {LG.shape}")
  
      logging.info("Connecting LG")
      LG = k2.connect(LG)
      logging.info(f"LG shape after k2.connect: {LG.shape}")
  
      logging.info(type(LG.aux_labels))
      logging.info("Determinizing LG")
  
      LG = k2.determinize(LG)
      logging.info(type(LG.aux_labels))
  
      logging.info("Connecting LG after k2.determinize")
      LG = k2.connect(LG)
  
      logging.info("Removing disambiguation symbols on LG")
  
      LG.labels[LG.labels >= first_token_disambig_id] = 0
      # See https://github.com/k2-fsa/k2/issues/874
      # for why we need to set LG.properties to None
      LG.__dict__["_properties"] = None
  
      assert isinstance(LG.aux_labels, k2.RaggedTensor)
      LG.aux_labels.values[
          LG.aux_labels.values >= first_word_disambig_id
      ] = 0
  
      LG = k2.remove_epsilon(LG)
      logging.info(f"LG shape after k2.remove_epsilon: {LG.shape}")
  
      LG = k2.connect(LG)
      LG.aux_labels = LG.aux_labels.remove_values_eq(0)
  
      logging.info("Arc sorting LG")
      LG = k2.arc_sort(LG)
  
      logging.info("Composing H and LG")
      # CAUTION: The name of the inner_labels is fixed
      # to `tokens`. If you want to change it, please
      # also change other places in icefall that are using
      # it.
      HLG = k2.compose(H, LG, inner_labels="tokens")
  
      logging.info("Connecting HLG")
      HLG = k2.connect(HLG)
  
      logging.info("Arc sorting HLG")
      HLG = k2.arc_sort(HLG)
      logging.info(f"HLG.shape: {HLG.shape}")
  
      return HLG
  
file_path: espnet/egs2/slue-voxpopuli/slu1/pyscripts/k2/compile_hlg.py
imports: import argparse
  import logging
  from pathlib import Path
  import k2
  import torch
  from icefall.lexicon import Lexicon
label_desc: Use image node_id 3 for calling a global function with example usage: compile_HLG(lang_dir, graph_dir, ngram_num) and returns: HLG