code: def compute_grammar_scores(
      self,
      hypo: Chain,
      score_types: List[str],
  ) -> Dict[str, float]:
      scores = {}
  
      def _average_results(results):
          grammar_scores = [prob for _step, prob in results]
          return sum(grammar_scores) / len(grammar_scores)
  
      grammar_results = self.check_grammar(
          hypo.chain, self.grammar_batch
      )
      assert all(
          hypo_step == grmr_step
          for hypo_step, (grmr_step, _prob) in zip(
              hypo.chain, grammar_results
          )
      ), "steps were returned out of order"
  
      if GRAMMAR_STEP in score_types:
          scores[GRAMMAR_STEP] = _average_results(grammar_results)
      if GRAMMAR_STEP_MAX in score_types:
          # Minimum correctness score, i.e. maximum probability of error
          scores[GRAMMAR_STEP_MAX] = min(
              prob for _, prob in grammar_results
          )
  
      return scores
  
imports: from collections import defaultdict
  import itertools
  import math
  import numpy
  from typing import Any, Dict, Iterable, List, Optional, Tuple, Union
  import torch
  from torch import nn
  from tqdm import tqdm
  from projects.roscoe.utils import cosine_similarity_scaled, embedding_alignment, al_mean
label_desc: Use image node_id 29 for calling the Evaluator obj's underlying member method code with example usage: obj.compute_grammar_scores(hypo, score_types) and returns: scores, unknown