class_docstr: Class to apply pattern matching in the forward direction.
class_docstr_tok: ["Class","to","apply","pattern","matching","in","the","forward","direction","."]
docstr: Apply the forward match algorithm and returns the list of matches given an initial match
  and a qubits configuration.
code: def run_forward_match(self):
      """Apply the forward match algorithm and returns the list of matches given an initial match
      and a qubits configuration.
      """
      # pylint: disable=too-many-branches,too-many-nested-blocks
  
      # Initialization
      self._init_successors_to_visit()
      self._init_matched_with_circuit()
      self._init_matched_with_pattern()
      self._init_is_blocked_circuit()
  
      # Initialize the list of matches and the stack of matched nodes (circuit)
      self._init_list_match()
      self._init_matched_nodes()
  
      # While the list of matched nodes is not empty
      while self.matched_nodes_list:
          # Return first element of the matched_nodes_list and removes it from the list
          v_first, successors_to_visit = self._get_node_forward(0)
          self._remove_node_forward(0)
  
          # If there is no successors to visit go to the end
          if not successors_to_visit:
              continue
  
          # Get the label and the node of the first successor to visit
          label = successors_to_visit[0]
          v = [label, self.circuit_dag.get_node(label)]
  
          # Update of the successors to visit.
          successors_to_visit.pop(0)
  
          # Update the matched_nodes_list with new attribute successor to visit and sort the list.
          self.matched_nodes_list.append(
              [v_first.node_id, v_first, successors_to_visit]
          )
          self.matched_nodes_list.sort(key=lambda x: x[2])
  
          # If the node is blocked and already matched go to the end
          if self.circuit_blocked[v[0]] | (
              self.circuit_matched_with[v[0]] != []
          ):
              continue
  
          # Search for potential candidates in the pattern
          self._find_forward_candidates(
              self.circuit_matched_with[v_first.node_id][0]
          )
  
          match = False
  
          # For loop over the candidates from the pattern to find a match.
          for i in self.candidates:
              # Break the for loop if a match is found.
              if match:
                  break
  
              node_circuit = self.circuit_dag.get_node(label)
              node_pattern = self.pattern_dag.get_node(i)
  
              # Necessary but not sufficient conditions for a match to happen.
              if (
                  len(self.wires[label]) != len(node_pattern.wires)
                  or set(self.wires[label]) != set(node_pattern.wires)
                  or node_circuit.op.name != node_pattern.op.name
              ):
                  continue
  
              # Compare two operations
              if _compare_operation_without_qubits(
                  node_circuit, node_pattern
              ):
                  if _compare_qubits(
                      node_circuit,
                      self.wires[label],
                      self.target_wires[label],
                      self.control_wires[label],
                      node_pattern.wires,
                      node_pattern.control_wires,
                      node_pattern.target_wires,
                  ):
                      # A match happens
                      self.circuit_matched_with[label] = [i]
                      self.pattern_matched_with[i] = [label]
  
                      # Append the new match to the list of matches.
                      self.match.append([i, label])
  
                      # Potential successors to visit (circuit) for a given match.
                      potential = self.circuit_dag.direct_successors(
                          label
                      )
  
                      # If the potential successors to visit are blocked or match, it is removed.
                      for potential_id in potential:
                          if self.circuit_blocked[potential_id] | (
                              self.circuit_matched_with[potential_id]
                              != []
                          ):
                              potential.remove(potential_id)
  
                      sorted_potential = sorted(potential)
  
                      #  Update the successor to visit attribute
                      successorstovisit = sorted_potential
  
                      # Add the updated node to the stack.
                      self.matched_nodes_list.append(
                          [v[0], v[1], successorstovisit]
                      )
                      self.matched_nodes_list.sort(key=lambda x: x[2])
                      match = True
                      continue
  
          # If no match is found, block the node and all the successors.
          if not match:
              self.circuit_blocked[label] = True
              for succ in v[1].successors:
                  self.circuit_blocked[succ] = True
  
imports: import copy
  import itertools
  from collections import OrderedDict
  from typing import Sequence, Callable
  import numpy
  import pennylane
  from pennylane.transforms import transform
  from pennylane import adjoint
  from pennylane.ops.qubit.attributes import symmetric_over_all_wires
  from pennylane.tape import QuantumTape, QuantumScript
  from pennylane.transforms.commutation_dag import commutation_dag
  from pennylane.wires import Wires
label_desc: Use image node_id 11 for calling the ForwardMatch obj's underlying member method code with example usage: obj.run_forward_match() without return types