def get_scores(self,
                 temperature=1,
                 lhs_nonterminal_bias=None,
                 rhs_emb_idxs=None,
                 lhs_emb_idxs=None,
                 approximate_denominator=False):
    """Computes scores.

    P(lhs|rhs) = sum over types { P(type|rhs) * P(lhs|type) }
    logP(lhs|rhs) = log sum over types { P(type|rhs) * P(lhs|type) }

    Can be computed as below for greater numerical stability:

    logP(lhs|rhs) = log sum exp over types { logP(type|rhs) + logP(lhs|type) }

    P(type|rhs) is "softmax" of score(rhs, type) normalized across type.
    P(lhs|type) is "softmax" of score(type, lhs) normalized across lhs.

    Args:
      temperature: Float indicating temperature for softmax (1 = standard
        softmax).
      lhs_nonterminal_bias: <float>[1, num_lhs_emb].
      rhs_emb_idxs: <int32>[num_rhs_emb_idxs].
      lhs_emb_idxs: <int32>[num_lhs_emb_idxs].
      approximate_denominator: Bool indicating whether to approximate the
        denominator of the softmax over rules by only considering rules in the
        current batch.

    Returns:
      <float>[num_lhs_emb, num_rhs_emb]
    """
    rhs_type_scores = self.rhs_type_scores
    type_lhs_scores = self.type_lhs_scores
    if rhs_emb_idxs is not None:
      rhs_type_scores = tf.gather(rhs_type_scores, rhs_emb_idxs, axis=0)
    # Gather *before* the softmax if approximate_denominator.
    if lhs_emb_idxs is not None and approximate_denominator:
      type_lhs_scores = tf.gather(type_lhs_scores, lhs_emb_idxs, axis=1)
    if lhs_nonterminal_bias is None:
      lhs_nonterminal_bias = tf.zeros_like(type_lhs_scores)

    # <float>[num_rhs_emb, num_types]
    logp_type_given_rhs = tf.nn.log_softmax(
        rhs_type_scores / temperature, axis=1)
    # <float>[num_types, num_lhs_emb]
    logp_lhs_given_type = tf.nn.log_softmax(
        type_lhs_scores / temperature + lhs_nonterminal_bias, axis=1)

    # Gather *after* the softmax to not affect denominator.
    if lhs_emb_idxs is not None and not approximate_denominator:
      logp_lhs_given_type = tf.gather(logp_lhs_given_type, lhs_emb_idxs, axis=1)

    # Avoid broadcast to large matrix.
    logp_lhs_given_rhs = _log_matmul_exp(logp_type_given_rhs,
                                         logp_lhs_given_type)

    # Transpose to provide expected return type.
    logp_lhs_given_rhs_t = tf.transpose(logp_lhs_given_rhs)
    return logp_lhs_given_rhs_t
Computes scores.

    P(lhs|rhs) = sum over types { P(type|rhs) * P(lhs|type) }
    logP(lhs|rhs) = log sum over types { P(type|rhs) * P(lhs|type) }

    Can be computed as below for greater numerical stability:

    logP(lhs|rhs) = log sum exp over types { logP(type|rhs) + logP(lhs|type) }

    P(type|rhs) is "softmax" of score(rhs, type) normalized across type.
    P(lhs|type) is "softmax" of score(type, lhs) normalized across lhs.

    Args:
      temperature: Float indicating temperature for softmax (1 = standard
        softmax).
      lhs_nonterminal_bias: <float>[1, num_lhs_emb].
      rhs_emb_idxs: <int32>[num_rhs_emb_idxs].
      lhs_emb_idxs: <int32>[num_lhs_emb_idxs].
      approximate_denominator: Bool indicating whether to approximate the
        denominator of the softmax over rules by only considering rules in the
        current batch.

    Returns:
      <float>[num_lhs_emb, num_rhs_emb]
    
language/compgen/csl/model/weighted_model.py