class_docstr: Mutate layer choice nodes.
  
  One mutator corresponds to all layer choices with the same label.
  The choices in layer choice each correspond to a cell in the graph model space,
  which is to support nested layer choice.
code: def mutate(self, model: GraphModelSpace) -> None:
      candidates = self.nodes[0].operation.parameters["candidates"]
      chosen = self.choice(candidates)
      for node in self.nodes:
          # Each layer choice corresponds to a cell, which is unconnected in the base graph.
          # We add the connections here in the mutation logic.
          # Thus, the mutated model should not be mutated again. Everything should be based on the original base graph.
          target = model.graphs[cast(Cell, node.operation).cell_name]
          chosen_node = target.get_node_by_name(chosen)
          assert chosen_node is not None
          target.add_edge((target.input_node, 0), (chosen_node, None))
          target.add_edge(
              (chosen_node, None), (target.output_node, None)
          )
          operation = cast(Cell, node.operation)
          target_node = cast(Node, model.get_node_by_name(node.name))
          target_node.update_operation(Cell(operation.cell_name))
  
          # remove redundant nodes
          for rm_node in list(
              target.hidden_nodes
          ):  # remove from a list on the fly will cause issues
              if rm_node.name != chosen_node.name:
                  rm_node.remove()
  
imports: from __future__ import annotations
  from typing import Any, List, Tuple, Dict, Iterable, cast
  from nni.mutable import MutableExpression, Categorical, frozen_context, label_scope
  from nni.nas.space import Graph, GraphModelSpace, Node, StationaryMutator, Mutator
  from nni.nas.space.graph_op import Cell
label_desc: Use image node_id 2 for calling the LayerChoiceMutator obj's underlying member method code with example usage: obj.mutate(model) without return types