code: def amplification_circuit(algorithm: Program, oracle: Program,
                            qubits: List[int],
                            num_iter: int,
                            decompose_diffusion: bool = False) -> Program:
      
      program = Program()
  
      uniform_superimposer = Program().inst([H(qubit) for qubit in qubits])
      program += uniform_superimposer
      if decompose_diffusion:
          diffusion = decomposed_diffusion_program(qubits)
      else:
          diffusion = diffusion_program(qubits)
      # To avoid redefining gates, we collect them before building our program.
      defined_gates = oracle.defined_gates + algorithm.defined_gates + diffusion.defined_gates
      for _ in range(num_iter):
          program += (oracle.instructions
                   + algorithm.dagger().instructions
                   + diffusion.instructions
                   + algorithm.instructions)
      # We redefine the gates in the new program.
      for gate in defined_gates:
          program.defgate(gate.name, gate.matrix)
      return program
docs: Returns a program that does ``num_iter`` rounds of amplification, given a measurement-less
      algorithm, an oracle, and a list of qubits to operate on.
  
      :param algorithm: A program representing a measurement-less algorithm run on qubits.
      :param oracle: An oracle maps any basis vector ``|psi>`` to either ``+|psi>`` or
          ``-|psi>`` depending on whether ``|psi>`` is in the desirable subspace or the undesirable
          subspace.
      :param qubits: the qubits to operate on
      :param num_iter: number of iterations of amplifications to run
      :param decompose_diffusion: If True, decompose the Grover diffusion gate into two qubit
       gates. If False, use a defgate to define the gate.
      :return: The amplified algorithm.