class_docstr: NeuralCFG From Kim et al
code: def forward(self, input):
      T, NT = self.T, self.NT
  
      def terms(words):
          b, n = input.shape[:2]
          term_prob = (
              torch.einsum(
                  "vh,th->tv", self.word_emb, self.mlp1(self.term_emb)
              )
              .log_softmax(-1)
              .unsqueeze(0)
              .unsqueeze(0)
              .expand(b, n, self.T, self.V)
          )
          indices = input.unsqueeze(2).expand(b, n, self.T).unsqueeze(3)
          term_prob = torch.gather(term_prob, 3, indices).squeeze(3)
          return term_prob
  
      def rules(b):
          return (
              torch.einsum(
                  "sh,tuh->stu", self.nonterm_emb, self.nonterm_emb_c
              )
              .view(NT, -1)
              .log_softmax(-1)
              .view(1, NT, NT + T, NT + T)
              .expand(b, NT, NT + T, NT + T)
          )
  
      def roots(b):
          return (
              torch.einsum(
                  "ah,th->t", self.s_emb, self.mlp2(self.root_emb)
              )
              .log_softmax(-1)
              .view(1, NT)
              .expand(b, NT)
          )
  
      batch = input.shape[0]
      return terms(input), rules(batch), roots(batch)
  
file_path: pytorch-struct/examples/networks/NeuralCFG.py
imports: import torch
  import torch.nn
label_desc: Use image node_id 2 for calling the NeuralCFG obj's underlying member method code with example usage: obj.forward(input) and returns: terms,  rules,  roots, term_prob, torch, torch