We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[BUG] `adjoint(adjoint(op))` returns identity
### Expected behavior

When queuing `adjoint(adjoint(op))` in a tape, op should be added

### Actual behavior

op and adjoint(op) are queued

### Additional information

Here is a simple example, where the original circuit contains an adjoint and is taken to a new circuit that executes the original and its adjoint, Since `adjoint(adjoint())` becomes identity, the original circuit is restored (instead of the identity, as expected:

```python
with qml.tape.QuantumTape() as circuit:
    qml.adjoint(qml.RX(0.5, wires=0))
    qml.expval(qml.PauliZ(0))

base_ops = circuit.expand().copy(copy_operations=True).operations

new_list_of_ops = [op for op in base_ops]
new_list_of_ops += [adjoint(op) for op in base_ops[::-1]]

with QuantumTape() as new_circuit:
    for op in new_list_of_ops:
        apply(op)

    for meas in circuit.measurements:
        apply(meas)

dev = qml.device("default.qubit", wires=range(2))
>>> print(qml.execute([circuit], dev, gradient_fn=None), qml.execute([new_circuit], dev, gradient_fn=None))
[array([0.87758256])] [array([0.87758256])]
```
But the latter should yield 1 since it is supposed to be the identity.

### Source code

_No response_

### Tracebacks

_No response_

### System information

```shell
0.24.0.dev0
```


### Existing GitHub issues

- [X] I have searched existing GitHub issues to make sure the issue does not already exist.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `pennylane/ops/op_math/adjoint_class.py`
Content:
```
1 # Copyright 2018-2022 Xanadu Quantum Technologies Inc.
2 
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 
7 #     http://www.apache.org/licenses/LICENSE-2.0
8 
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 """
15 This submodule defines the symbolic operation that indicates the adjoint of an operator.
16 """
17 from pennylane.operation import Operator, Operation, AdjointUndefinedError, Observable
18 from pennylane.queuing import QueuingContext
19 from pennylane.math import transpose, conj
20 
21 
22 # pylint: disable=no-member
23 class AdjointOperation(Operation):
24     """This mixin class is dynamically added to an ``Adjoint`` instance if the provided base class is an ``Operation``.
25 
26     .. warning::
27         This mixin class should never be initialized independent of ``Adjoint``.
28 
29     Overriding the dunder method ``__new__`` in ``Adjoint`` allows us to customize the creation of an instance and dynamically
30     add in parent classes.
31 
32     .. note:: Once the ``Operation`` class does not contain any unique logic any more, this mixin class can be removed.
33     """
34 
35     # This inverse behavior only needs to temporarily patch behavior until in-place inversion is removed.
36 
37     @property
38     def _inverse(self):
39         return self.base._inverse  # pylint: disable=protected-access
40 
41     @_inverse.setter
42     def _inverse(self, boolean):
43         self.base._inverse = boolean  # pylint: disable=protected-access
44         # refresh name as base_name got updated.
45         self._name = f"Adjoint({self.base.name})"
46 
47     def inv(self):
48         self.base.inv()
49         # refresh name as base_name got updated.
50         self._name = f"Adjoint({self.base.name})"
51         return self
52 
53     @property
54     def base_name(self):
55         return self._name
56 
57     @property
58     def name(self):
59         return self._name
60 
61     # pylint: disable=missing-function-docstring
62     @property
63     def basis(self):
64         return self.base.basis
65 
66     @property
67     def control_wires(self):
68         return self.base.control_wires
69 
70     def single_qubit_rot_angles(self):
71         omega, theta, phi = self.base.single_qubit_rot_angles()
72         return [-phi, -theta, -omega]
73 
74     @property
75     def grad_method(self):
76         return self.base.grad_method
77 
78     # pylint: disable=missing-function-docstring
79     @property
80     def grad_recipe(self):
81         return self.base.grad_recipe
82 
83     def get_parameter_shift(self, idx):
84         return self.base.get_parameter_shift(idx)
85 
86     @property
87     def parameter_frequencies(self):
88         return self.base.parameter_frequencies
89 
90     def generator(self):
91         return -1.0 * self.base.generator()
92 
93 
94 # pylint: disable=too-many-public-methods
95 class Adjoint(Operator):
96     """
97     The Adjoint of an operator.
98 
99     Args:
100         base (~.operation.Operator): The operator that is adjointed.
101 
102     .. seealso:: :func:`~.adjoint`, :meth:`~.operation.Operator.adjoint`
103 
104     This is a *developer*-facing class, and the :func:`~.adjoint` transform should be used to construct instances
105     of this class.
106 
107     **Example**
108 
109     >>> op = Adjoint(qml.S(0))
110     >>> op.name
111     'Adjoint(S)'
112     >>> qml.matrix(op)
113     array([[1.-0.j, 0.-0.j],
114        [0.-0.j, 0.-1.j]])
115     >>> qml.generator(Adjoint(qml.RX(1.0, wires=0)))
116     (PauliX(wires=[0]), 0.5)
117     >>> Adjoint(qml.RX(1.234, wires=0)).data
118     [1.234]
119 
120     .. details::
121         :title: Developer Details
122 
123     This class mixes in parent classes based on the inheritance tree of the provided ``Operator``.  For example, when
124     provided an ``Operation``, the instance will inherit from ``Operation`` and the ``AdjointOperation`` mixin.
125 
126     >>> op = Adjoint(qml.RX(1.234, wires=0))
127     >>> isinstance(op, qml.operation.Operation)
128     True
129     >>> isinstance(op, AdjointOperation)
130     True
131     >>> op.grad_method
132     'A'
133 
134     If the base class is an ``Observable`` instead, the ``Adjoint`` will be an ``Observable`` as well.
135 
136     >>> op = Adjoint(1.0 * qml.PauliX(0))
137     >>> isinstance(op, qml.operation.Observable)
138     True
139     >>> isinstance(op, qml.operation.Operation)
140     False
141     >>> Adjoint(qml.PauliX(0)) @ qml.PauliY(1)
142     Adjoint(PauliX)(wires=[0]) @ PauliY(wires=[1])
143 
144     """
145 
146     _operation_type = None  # type if base inherits from operation and not observable
147     _operation_observable_type = None  # type if base inherits from both operation and observable
148     _observable_type = None  # type if base inherits from observable and not operation
149 
150     # pylint: disable=unused-argument
151     def __new__(cls, base=None, do_queue=True, id=None):
152         """Mixes in parents based on inheritance structure of base.
153 
154         Though all the types will be named "Adjoint", their *identity* and location in memory will be different
155         based on ``base``'s inheritance.  We cache the different types in private class variables so that:
156 
157         >>> Adjoint(op).__class__ is Adjoint(op).__class__
158         True
159         >>> type(Adjoint(op)) == type(Adjoint(op))
160         True
161         >>> Adjoint(qml.RX(1.2, wires=0)).__class__ is Adjoint._operation_type
162         True
163         >>> Adjoint(qml.PauliX(0)).__class__ is Adjoint._operation_observable_type
164         True
165 
166         """
167 
168         if isinstance(base, Operation):
169             if isinstance(base, Observable):
170                 if cls._operation_observable_type is None:
171                     class_bases = (AdjointOperation, Adjoint, Observable, Operation)
172                     cls._operation_observable_type = type(
173                         "Adjoint", class_bases, dict(cls.__dict__)
174                     )
175                 return object.__new__(cls._operation_observable_type)
176 
177             # not an observable
178             if cls._operation_type is None:
179                 class_bases = (AdjointOperation, Adjoint, Operation)
180                 cls._operation_type = type("Adjoint", class_bases, dict(cls.__dict__))
181             return object.__new__(cls._operation_type)
182 
183         if isinstance(base, Observable):
184             if cls._observable_type is None:
185                 class_bases = (Adjoint, Observable)
186                 cls._observable_type = type("Adjoint", class_bases, dict(cls.__dict__))
187             return object.__new__(cls._observable_type)
188 
189         return object.__new__(Adjoint)
190 
191     # pylint: disable=attribute-defined-outside-init
192     def __copy__(self):
193         # this method needs to be overwritten becuase the base must be copied too.
194         copied_op = object.__new__(type(self))
195         # copied_op must maintain inheritance structure of self
196         # For example, it must keep AdjointOperation if self has it
197         # this way preserves inheritance structure
198 
199         copied_base = self.base.__copy__()
200         copied_op._hyperparameters = {"base": copied_base}
201         for attr, value in vars(self).items():
202             if attr not in {"data", "base", "_hyperparameters"}:
203                 setattr(copied_op, attr, value)
204 
205         return copied_op
206 
207     # pylint: disable=super-init-not-called
208     def __init__(self, base=None, do_queue=True, id=None):
209         self.hyperparameters["base"] = base
210         self._id = id
211         self.queue_idx = None
212 
213         self._name = f"Adjoint({self.base.name})"
214 
215         if do_queue:
216             self.queue()
217 
218     @property
219     def base(self):
220         """The operator that is adjointed."""
221         return self.hyperparameters["base"]
222 
223     @property
224     def data(self):
225         """Trainable parameters that the operator depends on."""
226         return self.base.data
227 
228     @data.setter
229     def data(self, new_data):
230         """Allows us to set base operation parameters."""
231         self.base.data = new_data
232 
233     @property
234     def parameters(self):
235         return self.base.parameters
236 
237     @property
238     def num_params(self):
239         return self.base.num_params
240 
241     @property
242     def wires(self):
243         return self.base.wires
244 
245     # pylint: disable=protected-access
246     @property
247     def _wires(self):
248         return self.base._wires
249 
250     # pylint: disable=protected-access
251     @_wires.setter
252     def _wires(self, new_wires):
253         # we should have a better way of updating wires than accessing a private attribute.
254         self.base._wires = new_wires
255 
256     @property
257     def num_wires(self):
258         return self.base.num_wires
259 
260     @property
261     def batch_size(self):
262         return self.base.batch_size
263 
264     @property
265     def ndim_params(self):
266         return self.base.ndim_params
267 
268     @property
269     def is_hermitian(self):
270         return self.base.is_hermitian
271 
272     def queue(self, context=QueuingContext):
273         context.safe_update_info(self.base, owner=self)
274         context.append(self, owns=self.base)
275 
276         return self
277 
278     def label(self, decimals=None, base_label=None, cache=None):
279         return self.base.label(decimals, base_label, cache=cache) + "†"
280 
281     # pylint: disable=arguments-differ
282     @staticmethod
283     def compute_matrix(*params, base=None):
284         base_matrix = base.compute_matrix(*params, **base.hyperparameters)
285         return transpose(conj(base_matrix))
286 
287     def decomposition(self):
288         try:
289             return [self.base.adjoint()]
290         except AdjointUndefinedError:
291             base_decomp = self.base.decomposition()
292             return [Adjoint(op) for op in reversed(base_decomp)]
293 
294     # pylint: disable=arguments-differ
295     @staticmethod
296     def compute_sparse_matrix(*params, base=None):
297         base_matrix = base.compute_sparse_matrix(*params, **base.hyperparameters)
298         return transpose(conj(base_matrix)).tocsr()
299 
300     def eigvals(self):
301         # Cannot define ``compute_eigvals`` because Hermitian only defines ``eigvals``
302         return conj(self.base.eigvals())
303 
304     def diagonalizing_gates(self):
305         return self.base.diagonalizing_gates()
306 
307     # pylint: disable=arguments-renamed, invalid-overridden-method
308     @property
309     def has_matrix(self):
310         return self.base.has_matrix
311 
312     def adjoint(self):
313         return self.base
314 
315     @property
316     def _queue_category(self):
317         """Used for sorting objects into their respective lists in `QuantumTape` objects.
318 
319         This property is a temporary solution that should not exist long-term and should not be
320         used outside of ``QuantumTape._process_queue``.
321 
322         Returns ``_queue_cateogory`` for base operator.
323         """
324         return self.base._queue_category  # pylint: disable=protected-access
325
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/pennylane/ops/op_math/adjoint_class.py b/pennylane/ops/op_math/adjoint_class.py
--- a/pennylane/ops/op_math/adjoint_class.py
+++ b/pennylane/ops/op_math/adjoint_class.py
@@ -310,7 +310,7 @@
         return self.base.has_matrix
 
     def adjoint(self):
-        return self.base
+        return self.base.queue()
 
     @property
     def _queue_category(self):

{"golden_diff": "diff --git a/pennylane/ops/op_math/adjoint_class.py b/pennylane/ops/op_math/adjoint_class.py\n--- a/pennylane/ops/op_math/adjoint_class.py\n+++ b/pennylane/ops/op_math/adjoint_class.py\n@@ -310,7 +310,7 @@\n         return self.base.has_matrix\n \n     def adjoint(self):\n-        return self.base\n+        return self.base.queue()\n \n     @property\n     def _queue_category(self):\n", "issue": "[BUG] `adjoint(adjoint(op))` returns identity\n### Expected behavior\n\nWhen queuing `adjoint(adjoint(op))` in a tape, op should be added\n\n### Actual behavior\n\nop and adjoint(op) are queued\n\n### Additional information\n\nHere is a simple example, where the original circuit contains an adjoint and is taken to a new circuit that executes the original and its adjoint, Since `adjoint(adjoint())` becomes identity, the original circuit is restored (instead of the identity, as expected:\r\n\r\n```python\r\nwith qml.tape.QuantumTape() as circuit:\r\n    qml.adjoint(qml.RX(0.5, wires=0))\r\n    qml.expval(qml.PauliZ(0))\r\n\r\nbase_ops = circuit.expand().copy(copy_operations=True).operations\r\n\r\nnew_list_of_ops = [op for op in base_ops]\r\nnew_list_of_ops += [adjoint(op) for op in base_ops[::-1]]\r\n\r\nwith QuantumTape() as new_circuit:\r\n    for op in new_list_of_ops:\r\n        apply(op)\r\n\r\n    for meas in circuit.measurements:\r\n        apply(meas)\r\n\r\ndev = qml.device(\"default.qubit\", wires=range(2))\r\n>>> print(qml.execute([circuit], dev, gradient_fn=None), qml.execute([new_circuit], dev, gradient_fn=None))\r\n[array([0.87758256])] [array([0.87758256])]\r\n```\r\nBut the latter should yield 1 since it is supposed to be the identity.\n\n### Source code\n\n_No response_\n\n### Tracebacks\n\n_No response_\n\n### System information\n\n```shell\n0.24.0.dev0\n```\n\n\n### Existing GitHub issues\n\n- [X] I have searched existing GitHub issues to make sure the issue does not already exist.\n", "before_files": [{"content": "# Copyright 2018-2022 Xanadu Quantum Technologies Inc.\n\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n\n#     http://www.apache.org/licenses/LICENSE-2.0\n\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\"\"\"\nThis submodule defines the symbolic operation that indicates the adjoint of an operator.\n\"\"\"\nfrom pennylane.operation import Operator, Operation, AdjointUndefinedError, Observable\nfrom pennylane.queuing import QueuingContext\nfrom pennylane.math import transpose, conj\n\n\n# pylint: disable=no-member\nclass AdjointOperation(Operation):\n    \"\"\"This mixin class is dynamically added to an ``Adjoint`` instance if the provided base class is an ``Operation``.\n\n    .. warning::\n        This mixin class should never be initialized independent of ``Adjoint``.\n\n    Overriding the dunder method ``__new__`` in ``Adjoint`` allows us to customize the creation of an instance and dynamically\n    add in parent classes.\n\n    .. note:: Once the ``Operation`` class does not contain any unique logic any more, this mixin class can be removed.\n    \"\"\"\n\n    # This inverse behavior only needs to temporarily patch behavior until in-place inversion is removed.\n\n    @property\n    def _inverse(self):\n        return self.base._inverse  # pylint: disable=protected-access\n\n    @_inverse.setter\n    def _inverse(self, boolean):\n        self.base._inverse = boolean  # pylint: disable=protected-access\n        # refresh name as base_name got updated.\n        self._name = f\"Adjoint({self.base.name})\"\n\n    def inv(self):\n        self.base.inv()\n        # refresh name as base_name got updated.\n        self._name = f\"Adjoint({self.base.name})\"\n        return self\n\n    @property\n    def base_name(self):\n        return self._name\n\n    @property\n    def name(self):\n        return self._name\n\n    # pylint: disable=missing-function-docstring\n    @property\n    def basis(self):\n        return self.base.basis\n\n    @property\n    def control_wires(self):\n        return self.base.control_wires\n\n    def single_qubit_rot_angles(self):\n        omega, theta, phi = self.base.single_qubit_rot_angles()\n        return [-phi, -theta, -omega]\n\n    @property\n    def grad_method(self):\n        return self.base.grad_method\n\n    # pylint: disable=missing-function-docstring\n    @property\n    def grad_recipe(self):\n        return self.base.grad_recipe\n\n    def get_parameter_shift(self, idx):\n        return self.base.get_parameter_shift(idx)\n\n    @property\n    def parameter_frequencies(self):\n        return self.base.parameter_frequencies\n\n    def generator(self):\n        return -1.0 * self.base.generator()\n\n\n# pylint: disable=too-many-public-methods\nclass Adjoint(Operator):\n    \"\"\"\n    The Adjoint of an operator.\n\n    Args:\n        base (~.operation.Operator): The operator that is adjointed.\n\n    .. seealso:: :func:`~.adjoint`, :meth:`~.operation.Operator.adjoint`\n\n    This is a *developer*-facing class, and the :func:`~.adjoint` transform should be used to construct instances\n    of this class.\n\n    **Example**\n\n    >>> op = Adjoint(qml.S(0))\n    >>> op.name\n    'Adjoint(S)'\n    >>> qml.matrix(op)\n    array([[1.-0.j, 0.-0.j],\n       [0.-0.j, 0.-1.j]])\n    >>> qml.generator(Adjoint(qml.RX(1.0, wires=0)))\n    (PauliX(wires=[0]), 0.5)\n    >>> Adjoint(qml.RX(1.234, wires=0)).data\n    [1.234]\n\n    .. details::\n        :title: Developer Details\n\n    This class mixes in parent classes based on the inheritance tree of the provided ``Operator``.  For example, when\n    provided an ``Operation``, the instance will inherit from ``Operation`` and the ``AdjointOperation`` mixin.\n\n    >>> op = Adjoint(qml.RX(1.234, wires=0))\n    >>> isinstance(op, qml.operation.Operation)\n    True\n    >>> isinstance(op, AdjointOperation)\n    True\n    >>> op.grad_method\n    'A'\n\n    If the base class is an ``Observable`` instead, the ``Adjoint`` will be an ``Observable`` as well.\n\n    >>> op = Adjoint(1.0 * qml.PauliX(0))\n    >>> isinstance(op, qml.operation.Observable)\n    True\n    >>> isinstance(op, qml.operation.Operation)\n    False\n    >>> Adjoint(qml.PauliX(0)) @ qml.PauliY(1)\n    Adjoint(PauliX)(wires=[0]) @ PauliY(wires=[1])\n\n    \"\"\"\n\n    _operation_type = None  # type if base inherits from operation and not observable\n    _operation_observable_type = None  # type if base inherits from both operation and observable\n    _observable_type = None  # type if base inherits from observable and not operation\n\n    # pylint: disable=unused-argument\n    def __new__(cls, base=None, do_queue=True, id=None):\n        \"\"\"Mixes in parents based on inheritance structure of base.\n\n        Though all the types will be named \"Adjoint\", their *identity* and location in memory will be different\n        based on ``base``'s inheritance.  We cache the different types in private class variables so that:\n\n        >>> Adjoint(op).__class__ is Adjoint(op).__class__\n        True\n        >>> type(Adjoint(op)) == type(Adjoint(op))\n        True\n        >>> Adjoint(qml.RX(1.2, wires=0)).__class__ is Adjoint._operation_type\n        True\n        >>> Adjoint(qml.PauliX(0)).__class__ is Adjoint._operation_observable_type\n        True\n\n        \"\"\"\n\n        if isinstance(base, Operation):\n            if isinstance(base, Observable):\n                if cls._operation_observable_type is None:\n                    class_bases = (AdjointOperation, Adjoint, Observable, Operation)\n                    cls._operation_observable_type = type(\n                        \"Adjoint\", class_bases, dict(cls.__dict__)\n                    )\n                return object.__new__(cls._operation_observable_type)\n\n            # not an observable\n            if cls._operation_type is None:\n                class_bases = (AdjointOperation, Adjoint, Operation)\n                cls._operation_type = type(\"Adjoint\", class_bases, dict(cls.__dict__))\n            return object.__new__(cls._operation_type)\n\n        if isinstance(base, Observable):\n            if cls._observable_type is None:\n                class_bases = (Adjoint, Observable)\n                cls._observable_type = type(\"Adjoint\", class_bases, dict(cls.__dict__))\n            return object.__new__(cls._observable_type)\n\n        return object.__new__(Adjoint)\n\n    # pylint: disable=attribute-defined-outside-init\n    def __copy__(self):\n        # this method needs to be overwritten becuase the base must be copied too.\n        copied_op = object.__new__(type(self))\n        # copied_op must maintain inheritance structure of self\n        # For example, it must keep AdjointOperation if self has it\n        # this way preserves inheritance structure\n\n        copied_base = self.base.__copy__()\n        copied_op._hyperparameters = {\"base\": copied_base}\n        for attr, value in vars(self).items():\n            if attr not in {\"data\", \"base\", \"_hyperparameters\"}:\n                setattr(copied_op, attr, value)\n\n        return copied_op\n\n    # pylint: disable=super-init-not-called\n    def __init__(self, base=None, do_queue=True, id=None):\n        self.hyperparameters[\"base\"] = base\n        self._id = id\n        self.queue_idx = None\n\n        self._name = f\"Adjoint({self.base.name})\"\n\n        if do_queue:\n            self.queue()\n\n    @property\n    def base(self):\n        \"\"\"The operator that is adjointed.\"\"\"\n        return self.hyperparameters[\"base\"]\n\n    @property\n    def data(self):\n        \"\"\"Trainable parameters that the operator depends on.\"\"\"\n        return self.base.data\n\n    @data.setter\n    def data(self, new_data):\n        \"\"\"Allows us to set base operation parameters.\"\"\"\n        self.base.data = new_data\n\n    @property\n    def parameters(self):\n        return self.base.parameters\n\n    @property\n    def num_params(self):\n        return self.base.num_params\n\n    @property\n    def wires(self):\n        return self.base.wires\n\n    # pylint: disable=protected-access\n    @property\n    def _wires(self):\n        return self.base._wires\n\n    # pylint: disable=protected-access\n    @_wires.setter\n    def _wires(self, new_wires):\n        # we should have a better way of updating wires than accessing a private attribute.\n        self.base._wires = new_wires\n\n    @property\n    def num_wires(self):\n        return self.base.num_wires\n\n    @property\n    def batch_size(self):\n        return self.base.batch_size\n\n    @property\n    def ndim_params(self):\n        return self.base.ndim_params\n\n    @property\n    def is_hermitian(self):\n        return self.base.is_hermitian\n\n    def queue(self, context=QueuingContext):\n        context.safe_update_info(self.base, owner=self)\n        context.append(self, owns=self.base)\n\n        return self\n\n    def label(self, decimals=None, base_label=None, cache=None):\n        return self.base.label(decimals, base_label, cache=cache) + \"\u2020\"\n\n    # pylint: disable=arguments-differ\n    @staticmethod\n    def compute_matrix(*params, base=None):\n        base_matrix = base.compute_matrix(*params, **base.hyperparameters)\n        return transpose(conj(base_matrix))\n\n    def decomposition(self):\n        try:\n            return [self.base.adjoint()]\n        except AdjointUndefinedError:\n            base_decomp = self.base.decomposition()\n            return [Adjoint(op) for op in reversed(base_decomp)]\n\n    # pylint: disable=arguments-differ\n    @staticmethod\n    def compute_sparse_matrix(*params, base=None):\n        base_matrix = base.compute_sparse_matrix(*params, **base.hyperparameters)\n        return transpose(conj(base_matrix)).tocsr()\n\n    def eigvals(self):\n        # Cannot define ``compute_eigvals`` because Hermitian only defines ``eigvals``\n        return conj(self.base.eigvals())\n\n    def diagonalizing_gates(self):\n        return self.base.diagonalizing_gates()\n\n    # pylint: disable=arguments-renamed, invalid-overridden-method\n    @property\n    def has_matrix(self):\n        return self.base.has_matrix\n\n    def adjoint(self):\n        return self.base\n\n    @property\n    def _queue_category(self):\n        \"\"\"Used for sorting objects into their respective lists in `QuantumTape` objects.\n\n        This property is a temporary solution that should not exist long-term and should not be\n        used outside of ``QuantumTape._process_queue``.\n\n        Returns ``_queue_cateogory`` for base operator.\n        \"\"\"\n        return self.base._queue_category  # pylint: disable=protected-access\n", "path": "pennylane/ops/op_math/adjoint_class.py"}], "after_files": [{"content": "# Copyright 2018-2022 Xanadu Quantum Technologies Inc.\n\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n\n#     http://www.apache.org/licenses/LICENSE-2.0\n\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\"\"\"\nThis submodule defines the symbolic operation that indicates the adjoint of an operator.\n\"\"\"\nfrom pennylane.operation import Operator, Operation, AdjointUndefinedError, Observable\nfrom pennylane.queuing import QueuingContext\nfrom pennylane.math import transpose, conj\n\n\n# pylint: disable=no-member\nclass AdjointOperation(Operation):\n    \"\"\"This mixin class is dynamically added to an ``Adjoint`` instance if the provided base class is an ``Operation``.\n\n    .. warning::\n        This mixin class should never be initialized independent of ``Adjoint``.\n\n    Overriding the dunder method ``__new__`` in ``Adjoint`` allows us to customize the creation of an instance and dynamically\n    add in parent classes.\n\n    .. note:: Once the ``Operation`` class does not contain any unique logic any more, this mixin class can be removed.\n    \"\"\"\n\n    # This inverse behavior only needs to temporarily patch behavior until in-place inversion is removed.\n\n    @property\n    def _inverse(self):\n        return self.base._inverse  # pylint: disable=protected-access\n\n    @_inverse.setter\n    def _inverse(self, boolean):\n        self.base._inverse = boolean  # pylint: disable=protected-access\n        # refresh name as base_name got updated.\n        self._name = f\"Adjoint({self.base.name})\"\n\n    def inv(self):\n        self.base.inv()\n        # refresh name as base_name got updated.\n        self._name = f\"Adjoint({self.base.name})\"\n        return self\n\n    @property\n    def base_name(self):\n        return self._name\n\n    @property\n    def name(self):\n        return self._name\n\n    # pylint: disable=missing-function-docstring\n    @property\n    def basis(self):\n        return self.base.basis\n\n    @property\n    def control_wires(self):\n        return self.base.control_wires\n\n    def single_qubit_rot_angles(self):\n        omega, theta, phi = self.base.single_qubit_rot_angles()\n        return [-phi, -theta, -omega]\n\n    @property\n    def grad_method(self):\n        return self.base.grad_method\n\n    # pylint: disable=missing-function-docstring\n    @property\n    def grad_recipe(self):\n        return self.base.grad_recipe\n\n    def get_parameter_shift(self, idx):\n        return self.base.get_parameter_shift(idx)\n\n    @property\n    def parameter_frequencies(self):\n        return self.base.parameter_frequencies\n\n    def generator(self):\n        return -1.0 * self.base.generator()\n\n\n# pylint: disable=too-many-public-methods\nclass Adjoint(Operator):\n    \"\"\"\n    The Adjoint of an operator.\n\n    Args:\n        base (~.operation.Operator): The operator that is adjointed.\n\n    .. seealso:: :func:`~.adjoint`, :meth:`~.operation.Operator.adjoint`\n\n    This is a *developer*-facing class, and the :func:`~.adjoint` transform should be used to construct instances\n    of this class.\n\n    **Example**\n\n    >>> op = Adjoint(qml.S(0))\n    >>> op.name\n    'Adjoint(S)'\n    >>> qml.matrix(op)\n    array([[1.-0.j, 0.-0.j],\n       [0.-0.j, 0.-1.j]])\n    >>> qml.generator(Adjoint(qml.RX(1.0, wires=0)))\n    (PauliX(wires=[0]), 0.5)\n    >>> Adjoint(qml.RX(1.234, wires=0)).data\n    [1.234]\n\n    .. details::\n        :title: Developer Details\n\n    This class mixes in parent classes based on the inheritance tree of the provided ``Operator``.  For example, when\n    provided an ``Operation``, the instance will inherit from ``Operation`` and the ``AdjointOperation`` mixin.\n\n    >>> op = Adjoint(qml.RX(1.234, wires=0))\n    >>> isinstance(op, qml.operation.Operation)\n    True\n    >>> isinstance(op, AdjointOperation)\n    True\n    >>> op.grad_method\n    'A'\n\n    If the base class is an ``Observable`` instead, the ``Adjoint`` will be an ``Observable`` as well.\n\n    >>> op = Adjoint(1.0 * qml.PauliX(0))\n    >>> isinstance(op, qml.operation.Observable)\n    True\n    >>> isinstance(op, qml.operation.Operation)\n    False\n    >>> Adjoint(qml.PauliX(0)) @ qml.PauliY(1)\n    Adjoint(PauliX)(wires=[0]) @ PauliY(wires=[1])\n\n    \"\"\"\n\n    _operation_type = None  # type if base inherits from operation and not observable\n    _operation_observable_type = None  # type if base inherits from both operation and observable\n    _observable_type = None  # type if base inherits from observable and not operation\n\n    # pylint: disable=unused-argument\n    def __new__(cls, base=None, do_queue=True, id=None):\n        \"\"\"Mixes in parents based on inheritance structure of base.\n\n        Though all the types will be named \"Adjoint\", their *identity* and location in memory will be different\n        based on ``base``'s inheritance.  We cache the different types in private class variables so that:\n\n        >>> Adjoint(op).__class__ is Adjoint(op).__class__\n        True\n        >>> type(Adjoint(op)) == type(Adjoint(op))\n        True\n        >>> Adjoint(qml.RX(1.2, wires=0)).__class__ is Adjoint._operation_type\n        True\n        >>> Adjoint(qml.PauliX(0)).__class__ is Adjoint._operation_observable_type\n        True\n\n        \"\"\"\n\n        if isinstance(base, Operation):\n            if isinstance(base, Observable):\n                if cls._operation_observable_type is None:\n                    class_bases = (AdjointOperation, Adjoint, Observable, Operation)\n                    cls._operation_observable_type = type(\n                        \"Adjoint\", class_bases, dict(cls.__dict__)\n                    )\n                return object.__new__(cls._operation_observable_type)\n\n            # not an observable\n            if cls._operation_type is None:\n                class_bases = (AdjointOperation, Adjoint, Operation)\n                cls._operation_type = type(\"Adjoint\", class_bases, dict(cls.__dict__))\n            return object.__new__(cls._operation_type)\n\n        if isinstance(base, Observable):\n            if cls._observable_type is None:\n                class_bases = (Adjoint, Observable)\n                cls._observable_type = type(\"Adjoint\", class_bases, dict(cls.__dict__))\n            return object.__new__(cls._observable_type)\n\n        return object.__new__(Adjoint)\n\n    # pylint: disable=attribute-defined-outside-init\n    def __copy__(self):\n        # this method needs to be overwritten becuase the base must be copied too.\n        copied_op = object.__new__(type(self))\n        # copied_op must maintain inheritance structure of self\n        # For example, it must keep AdjointOperation if self has it\n        # this way preserves inheritance structure\n\n        copied_base = self.base.__copy__()\n        copied_op._hyperparameters = {\"base\": copied_base}\n        for attr, value in vars(self).items():\n            if attr not in {\"data\", \"base\", \"_hyperparameters\"}:\n                setattr(copied_op, attr, value)\n\n        return copied_op\n\n    # pylint: disable=super-init-not-called\n    def __init__(self, base=None, do_queue=True, id=None):\n        self.hyperparameters[\"base\"] = base\n        self._id = id\n        self.queue_idx = None\n\n        self._name = f\"Adjoint({self.base.name})\"\n\n        if do_queue:\n            self.queue()\n\n    @property\n    def base(self):\n        \"\"\"The operator that is adjointed.\"\"\"\n        return self.hyperparameters[\"base\"]\n\n    @property\n    def data(self):\n        \"\"\"Trainable parameters that the operator depends on.\"\"\"\n        return self.base.data\n\n    @data.setter\n    def data(self, new_data):\n        \"\"\"Allows us to set base operation parameters.\"\"\"\n        self.base.data = new_data\n\n    @property\n    def parameters(self):\n        return self.base.parameters\n\n    @property\n    def num_params(self):\n        return self.base.num_params\n\n    @property\n    def wires(self):\n        return self.base.wires\n\n    # pylint: disable=protected-access\n    @property\n    def _wires(self):\n        return self.base._wires\n\n    # pylint: disable=protected-access\n    @_wires.setter\n    def _wires(self, new_wires):\n        # we should have a better way of updating wires than accessing a private attribute.\n        self.base._wires = new_wires\n\n    @property\n    def num_wires(self):\n        return self.base.num_wires\n\n    @property\n    def batch_size(self):\n        return self.base.batch_size\n\n    @property\n    def ndim_params(self):\n        return self.base.ndim_params\n\n    @property\n    def is_hermitian(self):\n        return self.base.is_hermitian\n\n    def queue(self, context=QueuingContext):\n        context.safe_update_info(self.base, owner=self)\n        context.append(self, owns=self.base)\n\n        return self\n\n    def label(self, decimals=None, base_label=None, cache=None):\n        return self.base.label(decimals, base_label, cache=cache) + \"\u2020\"\n\n    # pylint: disable=arguments-differ\n    @staticmethod\n    def compute_matrix(*params, base=None):\n        base_matrix = base.compute_matrix(*params, **base.hyperparameters)\n        return transpose(conj(base_matrix))\n\n    def decomposition(self):\n        try:\n            return [self.base.adjoint()]\n        except AdjointUndefinedError:\n            base_decomp = self.base.decomposition()\n            return [Adjoint(op) for op in reversed(base_decomp)]\n\n    # pylint: disable=arguments-differ\n    @staticmethod\n    def compute_sparse_matrix(*params, base=None):\n        base_matrix = base.compute_sparse_matrix(*params, **base.hyperparameters)\n        return transpose(conj(base_matrix)).tocsr()\n\n    def eigvals(self):\n        # Cannot define ``compute_eigvals`` because Hermitian only defines ``eigvals``\n        return conj(self.base.eigvals())\n\n    def diagonalizing_gates(self):\n        return self.base.diagonalizing_gates()\n\n    # pylint: disable=arguments-renamed, invalid-overridden-method\n    @property\n    def has_matrix(self):\n        return self.base.has_matrix\n\n    def adjoint(self):\n        return self.base.queue()\n\n    @property\n    def _queue_category(self):\n        \"\"\"Used for sorting objects into their respective lists in `QuantumTape` objects.\n\n        This property is a temporary solution that should not exist long-term and should not be\n        used outside of ``QuantumTape._process_queue``.\n\n        Returns ``_queue_cateogory`` for base operator.\n        \"\"\"\n        return self.base._queue_category  # pylint: disable=protected-access\n", "path": "pennylane/ops/op_math/adjoint_class.py"}]}