code: def legalise_einsum_expr(*operands: Any) -> str:
      """Reproduction of einsum c side einsum parsing in python. **Parameters:**
      Intakes the same inputs as `contract_path`, but NOT the keyword args. The
      only.
  
      supported keyword argument is:
      - **shapes** - *(bool, optional)* Whether
          ``parse_einsum_input`` should assume
          arrays (the default) or
          array shapes have been supplied.
  
      Returns
      -------
      einsum_eqn : str
          Legalised einsum equation
  
      Examples
      --------
      The operand list is simplified to reduce printing:
  
      >>> a = np.random.rand(4, 4)
      >>> b = np.random.rand(4, 4, 4)
      >>> legalise_einsum_eqn(('...a,...a->...', a, b))
      'za,xza->xz'
  
      >>> parse_einsum_input((a, [Ellipsis, 0], b, [Ellipsis, 0]))
      'za,xza->xz'
      """
      if len(operands) == 0:
          raise ValueError("No input operands")
  
      if isinstance(operands[0], str):
          subscripts = operands[0].replace(" ", "")
          operands = [
              possibly_convert_to_numpy(x) for x in operands[1:]
          ]
      else:
          subscripts, operands = convert_interleaved_input(operands)
      operand_shapes = [o.shape for o in operands]
  
      # Check for proper "->"
      if ("-" in subscripts) or (">" in subscripts):
          invalid = (subscripts.count("-") > 1) or (
              subscripts.count(">") > 1
          )
          if invalid or (subscripts.count("->") != 1):
              raise ValueError("Subscripts can only contain one '->'.")
  
      # Parse ellipses
      if "." in subscripts:
          used = (
              subscripts.replace(".", "")
              .replace(",", "")
              .replace("->", "")
          )
          ellipse_inds = "".join(
              gen_unused_symbols(
                  used, max(len(x) for x in operand_shapes)
              )
          )
          longest = 0
  
          # Do we have an output to account for?
          if "->" in subscripts:
              input_tmp, output_sub = subscripts.split("->")
              split_subscripts = input_tmp.split(",")
              out_sub = True
          else:
              split_subscripts = subscripts.split(",")
              out_sub = False
  
          for num, sub in enumerate(split_subscripts):
              if "." in sub:
                  if (sub.count(".") != 3) or (sub.count("...") != 1):
                      raise ValueError("Invalid Ellipses.")
  
                  # Take into account numerical values
                  if operand_shapes[num] == ():
                      ellipse_count = 0
                  else:
                      ellipse_count = max(
                          len(operand_shapes[num]), 1
                      ) - (len(sub) - 3)
  
                  if ellipse_count > longest:
                      longest = ellipse_count
  
                  if ellipse_count < 0:
                      raise ValueError("Ellipses lengths do not match.")
                  elif ellipse_count == 0:
                      split_subscripts[num] = sub.replace("...", "")
                  else:
                      split_subscripts[num] = sub.replace(
                          "...", ellipse_inds[-ellipse_count:]
                      )
  
          subscripts = ",".join(split_subscripts)
  
          # Figure out output ellipses
          if longest == 0:
              out_ellipse = ""
          else:
              out_ellipse = ellipse_inds[-longest:]
  
          if out_sub:
              subscripts += "->" + output_sub.replace(
                  "...", out_ellipse
              )
          else:
              # Special care for outputless ellipses
              output_subscript = find_output_str(subscripts)
              normal_inds = "".join(
                  sorted(set(output_subscript) - set(out_ellipse))
              )
  
              subscripts += f"->{out_ellipse}{normal_inds}"
  
      # Build output string if does not exist
      if "->" in subscripts:
          input_subscripts, output_subscript = subscripts.split("->")
      else:
          (
              input_subscripts,
              output_subscript,
          ) = subscripts, find_output_str(subscripts)
  
      # Make sure output subscripts are in the input
      for char in output_subscript:
          if char not in input_subscripts:
              raise ValueError(
                  f"Output character '{char}' did not appear in the input"
              )
  
      # Make sure number operands is equivalent to the number of terms
      if len(input_subscripts.split(",")) != len(operands):
          raise ValueError(
              f"Number of einsum subscripts, {len(input_subscripts.split(','))}, must be"
              f" equal to the number of operands, {len(operands)}."
          )
  
      eqn = f"{input_subscripts}->{output_subscript}"
      return eqn
  
file_path: ivy/ivy/utils/einsum_parser.py
imports: import itertools
  from typing import Any, Dict, Iterator, List, Tuple, Union
  import numpy
label_desc: Use image node_id 10 for calling a global function with example usage: legalise_einsum_expr() and returns: eqn