def inst(self, *instructions):
        """
        Mutates the Program object by appending new instructions.

        This function accepts a number of different valid forms, e.g.

            >>> p = Program()
            >>> p.inst(H(0)) # A single instruction
            >>> p.inst(H(0), H(1)) # Multiple instructions
            >>> p.inst([H(0), H(1)]) # A list of instructions
            >>> p.inst(H(i) for i in range(4)) # A generator of instructions
            >>> p.inst(("H", 1)) # A tuple representing an instruction
            >>> p.inst("H 0") # A string representing an instruction
            >>> q = Program()
            >>> p.inst(q) # Another program

        It can also be chained:
            >>> p = Program()
            >>> p.inst(H(0)).inst(H(1))

        :param instructions: A list of Instruction objects, e.g. Gates
        :return: self for method chaining
        """
        for instruction in instructions:
            if isinstance(instruction, list):
                self.inst(*instruction)
            elif isinstance(instruction, types.GeneratorType):
                self.inst(*instruction)
            elif isinstance(instruction, tuple):
                if len(instruction) == 0:
                    raise ValueError("tuple should have at least one element")
                elif len(instruction) == 1:
                    self.inst(instruction[0])
                else:
                    op = instruction[0]
                    if op == "MEASURE":
                        if len(instruction) == 2:
                            self.measure(instruction[1], None)
                        else:
                            self.measure(instruction[1], instruction[2])
                    else:
                        params = []
                        possible_params = instruction[1]
                        rest = instruction[2:]
                        if isinstance(possible_params, list):
                            params = possible_params
                        else:
                            rest = [possible_params] + list(rest)
                        self.gate(op, params, rest)
            elif isinstance(instruction, string_types):
                self.inst(run_parser(instruction.strip()))
            elif isinstance(instruction, Program):
                if id(self) == id(instruction):
                    raise ValueError("Nesting a program inside itself is not supported")

                for defgate in instruction._defined_gates:
                    self.inst(defgate)
                for instr in instruction._instructions:
                    self.inst(instr)

            # Implementation note: these two base cases are the only ones which modify the program
            elif isinstance(instruction, DefGate):
                defined_gate_names = [gate.name for gate in self._defined_gates]
                if instruction.name in defined_gate_names:
                    warnings.warn("Gate {} has already been defined in this program"
                                  .format(instruction.name))

                self._defined_gates.append(instruction)
            elif isinstance(instruction, AbstractInstruction):
                self._instructions.append(instruction)
                self._synthesized_instructions = None
            else:
                raise TypeError("Invalid instruction: {}".format(instruction))

        return self
def inst ( self , * instructions ) : for instruction in instructions : if isinstance ( instruction , list ) : self . inst ( * instruction ) elif isinstance ( instruction , types . GeneratorType ) : self . inst ( * instruction ) elif isinstance ( instruction , tuple ) : if len ( instruction ) == 0 : raise ValueError ( "tuple should have at least one element" ) elif len ( instruction ) == 1 : self . inst ( instruction [ 0 ] ) else : op = instruction [ 0 ] if op == "MEASURE" : if len ( instruction ) == 2 : self . measure ( instruction [ 1 ] , None ) else : self . measure ( instruction [ 1 ] , instruction [ 2 ] ) else : params = [ ] possible_params = instruction [ 1 ] rest = instruction [ 2 : ] if isinstance ( possible_params , list ) : params = possible_params else : rest = [ possible_params ] + list ( rest ) self . gate ( op , params , rest ) elif isinstance ( instruction , string_types ) : self . inst ( run_parser ( instruction . strip ( ) ) ) elif isinstance ( instruction , Program ) : if id ( self ) == id ( instruction ) : raise ValueError ( "Nesting a program inside itself is not supported" ) for defgate in instruction . _defined_gates : self . inst ( defgate ) for instr in instruction . _instructions : self . inst ( instr ) elif isinstance ( instruction , DefGate ) : defined_gate_names = [ gate . name for gate in self . _defined_gates ] if instruction . name in defined_gate_names : warnings . warn ( "Gate {} has already been defined in this program" . format ( instruction . name ) ) self . _defined_gates . append ( instruction ) elif isinstance ( instruction , AbstractInstruction ) : self . _instructions . append ( instruction ) self . _synthesized_instructions = None else : raise TypeError ( "Invalid instruction: {}" . format ( instruction ) ) return self
Mutates the Program object by appending new instructions.

        This function accepts a number of different valid forms, e.g.

            >>> p = Program()
            >>> p.inst(H(0)) # A single instruction
            >>> p.inst(H(0), H(1)) # Multiple instructions
            >>> p.inst([H(0), H(1)]) # A list of instructions
            >>> p.inst(H(i) for i in range(4)) # A generator of instructions
            >>> p.inst(("H", 1)) # A tuple representing an instruction
            >>> p.inst("H 0") # A string representing an instruction
            >>> q = Program()
            >>> p.inst(q) # Another program

        It can also be chained:
            >>> p = Program()
            >>> p.inst(H(0)).inst(H(1))

        :param instructions: A list of Instruction objects, e.g. Gates
        :return: self for method chaining