We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Add __repr__ to XmonDevice
See e.g. `TrialResult` or `Circuit` for how these should work.

```python
    def __repr__(self):
        return ('TrialResult(params={!r}, '
                'repetitions={!r}, '
                'measurements={!r})').format(self.params,
                                             self.repetitions,
                                             self.measurements)
```

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `cirq/google/xmon_device.py`
Content:
```
1 # Copyright 2018 The Cirq Developers
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 #     https://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 from typing import Iterable, cast, Optional, List, TYPE_CHECKING
16 
17 from cirq import ops, circuits
18 from cirq.devices import Device
19 from cirq.google import xmon_gates, convert_to_xmon_gates
20 from cirq.google.xmon_gate_extensions import xmon_gate_ext
21 from cirq.devices.grid_qubit import GridQubit
22 from cirq.value import Duration
23 
24 from cirq.circuits import TextDiagramDrawer
25 
26 
27 if TYPE_CHECKING:
28     # pylint: disable=unused-import
29     from typing import Set
30 
31 
32 class XmonDevice(Device):
33     """A device with qubits placed in a grid. Neighboring qubits can interact.
34     """
35 
36     def __init__(self,
37                  measurement_duration: Duration,
38                  exp_w_duration: Duration,
39                  exp_11_duration: Duration,
40                  qubits: Iterable[GridQubit]) -> None:
41         """Initializes the description of an xmon device.
42 
43         Args:
44             measurement_duration: The maximum duration of a measurement.
45             exp_w_duration: The maximum duration of an ExpW operation.
46             exp_11_duration: The maximum duration of an ExpZ operation.
47             qubits: Qubits on the device, identified by their x, y location.
48         """
49         self._measurement_duration = measurement_duration
50         self._exp_w_duration = exp_w_duration
51         self._exp_z_duration = exp_11_duration
52         self.qubits = frozenset(qubits)
53 
54     def decompose_operation(self, operation: ops.Operation) -> ops.OP_TREE:
55         return convert_to_xmon_gates.ConvertToXmonGates().convert(operation)
56 
57     def neighbors_of(self, qubit: GridQubit):
58         """Returns the qubits that the given qubit can interact with."""
59         possibles = [
60             GridQubit(qubit.row + 1, qubit.col),
61             GridQubit(qubit.row - 1, qubit.col),
62             GridQubit(qubit.row, qubit.col + 1),
63             GridQubit(qubit.row, qubit.col - 1),
64         ]
65         return [e for e in possibles if e in self.qubits]
66 
67     def duration_of(self, operation):
68         if isinstance(operation, ops.GateOperation):
69             g = xmon_gate_ext.try_cast(xmon_gates.XmonGate, operation.gate)
70             if isinstance(g, xmon_gates.Exp11Gate):
71                 return self._exp_z_duration
72             if isinstance(g, xmon_gates.ExpWGate):
73                 return self._exp_w_duration
74             if isinstance(g, xmon_gates.XmonMeasurementGate):
75                 return self._measurement_duration
76             if isinstance(g, xmon_gates.ExpZGate):
77                 # Z gates are performed in the control software.
78                 return Duration()
79         raise ValueError('Unsupported gate type: {!r}'.format(operation))
80 
81     def validate_gate(self, gate: ops.Gate):
82         """Raises an error if the given gate isn't allowed.
83 
84         Raises:
85             ValueError: Unsupported gate.
86         """
87         if not isinstance(gate, (xmon_gates.Exp11Gate,
88                                  xmon_gates.ExpWGate,
89                                  xmon_gates.XmonMeasurementGate,
90                                  xmon_gates.ExpZGate)):
91             raise ValueError('Unsupported gate type: {!r}'.format(gate))
92 
93     def validate_operation(self, operation: ops.Operation):
94         if not isinstance(operation, ops.GateOperation):
95             raise ValueError('Unsupported operation: {!r}'.format(operation))
96 
97         self.validate_gate(operation.gate)
98 
99         for q in operation.qubits:
100             if not isinstance(q, GridQubit):
101                 raise ValueError('Unsupported qubit type: {!r}'.format(q))
102             if q not in self.qubits:
103                 raise ValueError('Qubit not on device: {!r}'.format(q))
104 
105         if (len(operation.qubits) == 2
106                 and not isinstance(operation.gate,
107                                    xmon_gates.XmonMeasurementGate)):
108             p, q = operation.qubits
109             if not cast(GridQubit, p).is_adjacent(q):
110                 raise ValueError(
111                     'Non-local interaction: {!r}.'.format(operation))
112 
113     def _check_if_exp11_operation_interacts_with_any(
114             self,
115             exp11_op: ops.GateOperation,
116             others: Iterable[ops.GateOperation]) -> bool:
117         return any(self._check_if_exp11_operation_interacts(exp11_op, op)
118                    for op in others)
119 
120     def _check_if_exp11_operation_interacts(
121             self,
122             exp11_op: ops.GateOperation,
123             other_op: ops.GateOperation) -> bool:
124         if isinstance(other_op.gate, xmon_gates.ExpZGate):
125             return False
126         if isinstance(other_op.gate, xmon_gates.ExpWGate):
127             return False
128 
129         return any(cast(GridQubit, q).is_adjacent(cast(GridQubit, p))
130                    for q in exp11_op.qubits
131                    for p in other_op.qubits)
132 
133     def validate_scheduled_operation(self, schedule, scheduled_operation):
134         self.validate_operation(scheduled_operation.operation)
135 
136         if isinstance(scheduled_operation.operation.gate,
137                       xmon_gates.Exp11Gate):
138             for other in schedule.operations_happening_at_same_time_as(
139                     scheduled_operation):
140                 if self._check_if_exp11_operation_interacts(
141                         cast(ops.GateOperation, scheduled_operation.operation),
142                         cast(ops.GateOperation, other.operation)):
143                     raise ValueError(
144                         'Adjacent Exp11 operations: {} vs {}.'.format(
145                             scheduled_operation, other))
146 
147     def validate_circuit(self, circuit: circuits.Circuit):
148         super().validate_circuit(circuit)
149         _verify_unique_measurement_keys(circuit.all_operations())
150 
151     def validate_moment(self, moment: circuits.Moment):
152         super().validate_moment(moment)
153         for op in moment.operations:
154             if (isinstance(op, ops.GateOperation) and
155                     isinstance(op.gate, xmon_gates.Exp11Gate)):
156                 for other in moment.operations:
157                     if (other is not op and
158                             self._check_if_exp11_operation_interacts(
159                                 cast(ops.GateOperation, op),
160                                 cast(ops.GateOperation, other))):
161                         raise ValueError(
162                             'Adjacent Exp11 operations: {}.'.format(moment))
163 
164     def can_add_operation_into_moment(self,
165                                       operation: ops.Operation,
166                                       moment: circuits.Moment) -> bool:
167         self.validate_moment(moment)
168 
169         if not super().can_add_operation_into_moment(operation, moment):
170             return False
171         if (isinstance(operation, ops.GateOperation) and
172                 isinstance(operation.gate, xmon_gates.Exp11Gate)):
173             return not self._check_if_exp11_operation_interacts_with_any(
174                 cast(ops.GateOperation, operation),
175                 cast(Iterable[ops.GateOperation], moment.operations))
176         return True
177 
178     def validate_schedule(self, schedule):
179         _verify_unique_measurement_keys(
180             s.operation for s in schedule.scheduled_operations)
181         for scheduled_operation in schedule.scheduled_operations:
182             self.validate_scheduled_operation(schedule, scheduled_operation)
183 
184     def at(self, row: int, col: int) -> Optional[GridQubit]:
185         """Returns the qubit at the given position, if there is one, else None.
186         """
187         q = GridQubit(row, col)
188         return q if q in self.qubits else None
189 
190     def row(self, row: int) -> List[GridQubit]:
191         """Returns the qubits in the given row, in ascending order."""
192         return sorted(q for q in self.qubits if q.row == row)
193 
194     def col(self, col: int) -> List[GridQubit]:
195         """Returns the qubits in the given column, in ascending order."""
196         return sorted(q for q in self.qubits if q.col == col)
197 
198     def __str__(self):
199         diagram = TextDiagramDrawer()
200 
201         for q in self.qubits:
202             diagram.write(q.col, q.row, str(q))
203             for q2 in self.neighbors_of(q):
204                 diagram.grid_line(q.col, q.row, q2.col, q2.row)
205 
206         return diagram.render(
207             horizontal_spacing=3,
208             vertical_spacing=2,
209             use_unicode_characters=True)
210 
211     def __eq__(self, other):
212         if not isinstance(other, (XmonDevice, type(self))):
213             return NotImplemented
214         return (self._measurement_duration == other._measurement_duration and
215                 self._exp_w_duration == other._exp_w_duration and
216                 self._exp_z_duration == other._exp_z_duration and
217                 self.qubits == other.qubits)
218 
219     def __ne__(self, other):
220         return not self == other
221 
222     def __hash__(self):
223         return hash((XmonDevice, self._measurement_duration,
224                      self._exp_w_duration, self._exp_z_duration, self.qubits))
225 
226 
227 def _verify_unique_measurement_keys(operations: Iterable[ops.Operation]):
228     seen = set()  # type: Set[str]
229     for op in operations:
230         if ops.MeasurementGate.is_measurement(op):
231             key = cast(ops.MeasurementGate,
232                        cast(ops.GateOperation, op).gate).key
233             if key in seen:
234                 raise ValueError('Measurement key {} repeated'.format(key))
235             seen.add(key)
236
```
--- 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/cirq/google/xmon_device.py b/cirq/google/xmon_device.py
--- a/cirq/google/xmon_device.py
+++ b/cirq/google/xmon_device.py
@@ -195,6 +195,15 @@
         """Returns the qubits in the given column, in ascending order."""
         return sorted(q for q in self.qubits if q.col == col)
 
+    def __repr__(self):
+        return ('XmonDevice(measurement_duration={!r}, '
+                'exp_w_duration={!r}, '
+                'exp_11_duration={!r} '
+                'qubits={!r})').format(self._measurement_duration,
+                                       self._exp_w_duration,
+                                       self._exp_z_duration,
+                                       sorted(self.qubits))
+
     def __str__(self):
         diagram = TextDiagramDrawer()

{"golden_diff": "diff --git a/cirq/google/xmon_device.py b/cirq/google/xmon_device.py\n--- a/cirq/google/xmon_device.py\n+++ b/cirq/google/xmon_device.py\n@@ -195,6 +195,15 @@\n         \"\"\"Returns the qubits in the given column, in ascending order.\"\"\"\n         return sorted(q for q in self.qubits if q.col == col)\n \n+    def __repr__(self):\n+        return ('XmonDevice(measurement_duration={!r}, '\n+                'exp_w_duration={!r}, '\n+                'exp_11_duration={!r} '\n+                'qubits={!r})').format(self._measurement_duration,\n+                                       self._exp_w_duration,\n+                                       self._exp_z_duration,\n+                                       sorted(self.qubits))\n+\n     def __str__(self):\n         diagram = TextDiagramDrawer()\n", "issue": "Add __repr__ to XmonDevice\nSee e.g. `TrialResult` or `Circuit` for how these should work.\r\n\r\n```python\r\n    def __repr__(self):\r\n        return ('TrialResult(params={!r}, '\r\n                'repetitions={!r}, '\r\n                'measurements={!r})').format(self.params,\r\n                                             self.repetitions,\r\n                                             self.measurements)\r\n```\n", "before_files": [{"content": "# Copyright 2018 The Cirq Developers\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#     https://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\nfrom typing import Iterable, cast, Optional, List, TYPE_CHECKING\n\nfrom cirq import ops, circuits\nfrom cirq.devices import Device\nfrom cirq.google import xmon_gates, convert_to_xmon_gates\nfrom cirq.google.xmon_gate_extensions import xmon_gate_ext\nfrom cirq.devices.grid_qubit import GridQubit\nfrom cirq.value import Duration\n\nfrom cirq.circuits import TextDiagramDrawer\n\n\nif TYPE_CHECKING:\n    # pylint: disable=unused-import\n    from typing import Set\n\n\nclass XmonDevice(Device):\n    \"\"\"A device with qubits placed in a grid. Neighboring qubits can interact.\n    \"\"\"\n\n    def __init__(self,\n                 measurement_duration: Duration,\n                 exp_w_duration: Duration,\n                 exp_11_duration: Duration,\n                 qubits: Iterable[GridQubit]) -> None:\n        \"\"\"Initializes the description of an xmon device.\n\n        Args:\n            measurement_duration: The maximum duration of a measurement.\n            exp_w_duration: The maximum duration of an ExpW operation.\n            exp_11_duration: The maximum duration of an ExpZ operation.\n            qubits: Qubits on the device, identified by their x, y location.\n        \"\"\"\n        self._measurement_duration = measurement_duration\n        self._exp_w_duration = exp_w_duration\n        self._exp_z_duration = exp_11_duration\n        self.qubits = frozenset(qubits)\n\n    def decompose_operation(self, operation: ops.Operation) -> ops.OP_TREE:\n        return convert_to_xmon_gates.ConvertToXmonGates().convert(operation)\n\n    def neighbors_of(self, qubit: GridQubit):\n        \"\"\"Returns the qubits that the given qubit can interact with.\"\"\"\n        possibles = [\n            GridQubit(qubit.row + 1, qubit.col),\n            GridQubit(qubit.row - 1, qubit.col),\n            GridQubit(qubit.row, qubit.col + 1),\n            GridQubit(qubit.row, qubit.col - 1),\n        ]\n        return [e for e in possibles if e in self.qubits]\n\n    def duration_of(self, operation):\n        if isinstance(operation, ops.GateOperation):\n            g = xmon_gate_ext.try_cast(xmon_gates.XmonGate, operation.gate)\n            if isinstance(g, xmon_gates.Exp11Gate):\n                return self._exp_z_duration\n            if isinstance(g, xmon_gates.ExpWGate):\n                return self._exp_w_duration\n            if isinstance(g, xmon_gates.XmonMeasurementGate):\n                return self._measurement_duration\n            if isinstance(g, xmon_gates.ExpZGate):\n                # Z gates are performed in the control software.\n                return Duration()\n        raise ValueError('Unsupported gate type: {!r}'.format(operation))\n\n    def validate_gate(self, gate: ops.Gate):\n        \"\"\"Raises an error if the given gate isn't allowed.\n\n        Raises:\n            ValueError: Unsupported gate.\n        \"\"\"\n        if not isinstance(gate, (xmon_gates.Exp11Gate,\n                                 xmon_gates.ExpWGate,\n                                 xmon_gates.XmonMeasurementGate,\n                                 xmon_gates.ExpZGate)):\n            raise ValueError('Unsupported gate type: {!r}'.format(gate))\n\n    def validate_operation(self, operation: ops.Operation):\n        if not isinstance(operation, ops.GateOperation):\n            raise ValueError('Unsupported operation: {!r}'.format(operation))\n\n        self.validate_gate(operation.gate)\n\n        for q in operation.qubits:\n            if not isinstance(q, GridQubit):\n                raise ValueError('Unsupported qubit type: {!r}'.format(q))\n            if q not in self.qubits:\n                raise ValueError('Qubit not on device: {!r}'.format(q))\n\n        if (len(operation.qubits) == 2\n                and not isinstance(operation.gate,\n                                   xmon_gates.XmonMeasurementGate)):\n            p, q = operation.qubits\n            if not cast(GridQubit, p).is_adjacent(q):\n                raise ValueError(\n                    'Non-local interaction: {!r}.'.format(operation))\n\n    def _check_if_exp11_operation_interacts_with_any(\n            self,\n            exp11_op: ops.GateOperation,\n            others: Iterable[ops.GateOperation]) -> bool:\n        return any(self._check_if_exp11_operation_interacts(exp11_op, op)\n                   for op in others)\n\n    def _check_if_exp11_operation_interacts(\n            self,\n            exp11_op: ops.GateOperation,\n            other_op: ops.GateOperation) -> bool:\n        if isinstance(other_op.gate, xmon_gates.ExpZGate):\n            return False\n        if isinstance(other_op.gate, xmon_gates.ExpWGate):\n            return False\n\n        return any(cast(GridQubit, q).is_adjacent(cast(GridQubit, p))\n                   for q in exp11_op.qubits\n                   for p in other_op.qubits)\n\n    def validate_scheduled_operation(self, schedule, scheduled_operation):\n        self.validate_operation(scheduled_operation.operation)\n\n        if isinstance(scheduled_operation.operation.gate,\n                      xmon_gates.Exp11Gate):\n            for other in schedule.operations_happening_at_same_time_as(\n                    scheduled_operation):\n                if self._check_if_exp11_operation_interacts(\n                        cast(ops.GateOperation, scheduled_operation.operation),\n                        cast(ops.GateOperation, other.operation)):\n                    raise ValueError(\n                        'Adjacent Exp11 operations: {} vs {}.'.format(\n                            scheduled_operation, other))\n\n    def validate_circuit(self, circuit: circuits.Circuit):\n        super().validate_circuit(circuit)\n        _verify_unique_measurement_keys(circuit.all_operations())\n\n    def validate_moment(self, moment: circuits.Moment):\n        super().validate_moment(moment)\n        for op in moment.operations:\n            if (isinstance(op, ops.GateOperation) and\n                    isinstance(op.gate, xmon_gates.Exp11Gate)):\n                for other in moment.operations:\n                    if (other is not op and\n                            self._check_if_exp11_operation_interacts(\n                                cast(ops.GateOperation, op),\n                                cast(ops.GateOperation, other))):\n                        raise ValueError(\n                            'Adjacent Exp11 operations: {}.'.format(moment))\n\n    def can_add_operation_into_moment(self,\n                                      operation: ops.Operation,\n                                      moment: circuits.Moment) -> bool:\n        self.validate_moment(moment)\n\n        if not super().can_add_operation_into_moment(operation, moment):\n            return False\n        if (isinstance(operation, ops.GateOperation) and\n                isinstance(operation.gate, xmon_gates.Exp11Gate)):\n            return not self._check_if_exp11_operation_interacts_with_any(\n                cast(ops.GateOperation, operation),\n                cast(Iterable[ops.GateOperation], moment.operations))\n        return True\n\n    def validate_schedule(self, schedule):\n        _verify_unique_measurement_keys(\n            s.operation for s in schedule.scheduled_operations)\n        for scheduled_operation in schedule.scheduled_operations:\n            self.validate_scheduled_operation(schedule, scheduled_operation)\n\n    def at(self, row: int, col: int) -> Optional[GridQubit]:\n        \"\"\"Returns the qubit at the given position, if there is one, else None.\n        \"\"\"\n        q = GridQubit(row, col)\n        return q if q in self.qubits else None\n\n    def row(self, row: int) -> List[GridQubit]:\n        \"\"\"Returns the qubits in the given row, in ascending order.\"\"\"\n        return sorted(q for q in self.qubits if q.row == row)\n\n    def col(self, col: int) -> List[GridQubit]:\n        \"\"\"Returns the qubits in the given column, in ascending order.\"\"\"\n        return sorted(q for q in self.qubits if q.col == col)\n\n    def __str__(self):\n        diagram = TextDiagramDrawer()\n\n        for q in self.qubits:\n            diagram.write(q.col, q.row, str(q))\n            for q2 in self.neighbors_of(q):\n                diagram.grid_line(q.col, q.row, q2.col, q2.row)\n\n        return diagram.render(\n            horizontal_spacing=3,\n            vertical_spacing=2,\n            use_unicode_characters=True)\n\n    def __eq__(self, other):\n        if not isinstance(other, (XmonDevice, type(self))):\n            return NotImplemented\n        return (self._measurement_duration == other._measurement_duration and\n                self._exp_w_duration == other._exp_w_duration and\n                self._exp_z_duration == other._exp_z_duration and\n                self.qubits == other.qubits)\n\n    def __ne__(self, other):\n        return not self == other\n\n    def __hash__(self):\n        return hash((XmonDevice, self._measurement_duration,\n                     self._exp_w_duration, self._exp_z_duration, self.qubits))\n\n\ndef _verify_unique_measurement_keys(operations: Iterable[ops.Operation]):\n    seen = set()  # type: Set[str]\n    for op in operations:\n        if ops.MeasurementGate.is_measurement(op):\n            key = cast(ops.MeasurementGate,\n                       cast(ops.GateOperation, op).gate).key\n            if key in seen:\n                raise ValueError('Measurement key {} repeated'.format(key))\n            seen.add(key)\n", "path": "cirq/google/xmon_device.py"}], "after_files": [{"content": "# Copyright 2018 The Cirq Developers\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#     https://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\nfrom typing import Iterable, cast, Optional, List, TYPE_CHECKING\n\nfrom cirq import ops, circuits\nfrom cirq.devices import Device\nfrom cirq.google import xmon_gates, convert_to_xmon_gates\nfrom cirq.google.xmon_gate_extensions import xmon_gate_ext\nfrom cirq.devices.grid_qubit import GridQubit\nfrom cirq.value import Duration\n\nfrom cirq.circuits import TextDiagramDrawer\n\n\nif TYPE_CHECKING:\n    # pylint: disable=unused-import\n    from typing import Set\n\n\nclass XmonDevice(Device):\n    \"\"\"A device with qubits placed in a grid. Neighboring qubits can interact.\n    \"\"\"\n\n    def __init__(self,\n                 measurement_duration: Duration,\n                 exp_w_duration: Duration,\n                 exp_11_duration: Duration,\n                 qubits: Iterable[GridQubit]) -> None:\n        \"\"\"Initializes the description of an xmon device.\n\n        Args:\n            measurement_duration: The maximum duration of a measurement.\n            exp_w_duration: The maximum duration of an ExpW operation.\n            exp_11_duration: The maximum duration of an ExpZ operation.\n            qubits: Qubits on the device, identified by their x, y location.\n        \"\"\"\n        self._measurement_duration = measurement_duration\n        self._exp_w_duration = exp_w_duration\n        self._exp_z_duration = exp_11_duration\n        self.qubits = frozenset(qubits)\n\n    def decompose_operation(self, operation: ops.Operation) -> ops.OP_TREE:\n        return convert_to_xmon_gates.ConvertToXmonGates().convert(operation)\n\n    def neighbors_of(self, qubit: GridQubit):\n        \"\"\"Returns the qubits that the given qubit can interact with.\"\"\"\n        possibles = [\n            GridQubit(qubit.row + 1, qubit.col),\n            GridQubit(qubit.row - 1, qubit.col),\n            GridQubit(qubit.row, qubit.col + 1),\n            GridQubit(qubit.row, qubit.col - 1),\n        ]\n        return [e for e in possibles if e in self.qubits]\n\n    def duration_of(self, operation):\n        if isinstance(operation, ops.GateOperation):\n            g = xmon_gate_ext.try_cast(xmon_gates.XmonGate, operation.gate)\n            if isinstance(g, xmon_gates.Exp11Gate):\n                return self._exp_z_duration\n            if isinstance(g, xmon_gates.ExpWGate):\n                return self._exp_w_duration\n            if isinstance(g, xmon_gates.XmonMeasurementGate):\n                return self._measurement_duration\n            if isinstance(g, xmon_gates.ExpZGate):\n                # Z gates are performed in the control software.\n                return Duration()\n        raise ValueError('Unsupported gate type: {!r}'.format(operation))\n\n    def validate_gate(self, gate: ops.Gate):\n        \"\"\"Raises an error if the given gate isn't allowed.\n\n        Raises:\n            ValueError: Unsupported gate.\n        \"\"\"\n        if not isinstance(gate, (xmon_gates.Exp11Gate,\n                                 xmon_gates.ExpWGate,\n                                 xmon_gates.XmonMeasurementGate,\n                                 xmon_gates.ExpZGate)):\n            raise ValueError('Unsupported gate type: {!r}'.format(gate))\n\n    def validate_operation(self, operation: ops.Operation):\n        if not isinstance(operation, ops.GateOperation):\n            raise ValueError('Unsupported operation: {!r}'.format(operation))\n\n        self.validate_gate(operation.gate)\n\n        for q in operation.qubits:\n            if not isinstance(q, GridQubit):\n                raise ValueError('Unsupported qubit type: {!r}'.format(q))\n            if q not in self.qubits:\n                raise ValueError('Qubit not on device: {!r}'.format(q))\n\n        if (len(operation.qubits) == 2\n                and not isinstance(operation.gate,\n                                   xmon_gates.XmonMeasurementGate)):\n            p, q = operation.qubits\n            if not cast(GridQubit, p).is_adjacent(q):\n                raise ValueError(\n                    'Non-local interaction: {!r}.'.format(operation))\n\n    def _check_if_exp11_operation_interacts_with_any(\n            self,\n            exp11_op: ops.GateOperation,\n            others: Iterable[ops.GateOperation]) -> bool:\n        return any(self._check_if_exp11_operation_interacts(exp11_op, op)\n                   for op in others)\n\n    def _check_if_exp11_operation_interacts(\n            self,\n            exp11_op: ops.GateOperation,\n            other_op: ops.GateOperation) -> bool:\n        if isinstance(other_op.gate, xmon_gates.ExpZGate):\n            return False\n        if isinstance(other_op.gate, xmon_gates.ExpWGate):\n            return False\n\n        return any(cast(GridQubit, q).is_adjacent(cast(GridQubit, p))\n                   for q in exp11_op.qubits\n                   for p in other_op.qubits)\n\n    def validate_scheduled_operation(self, schedule, scheduled_operation):\n        self.validate_operation(scheduled_operation.operation)\n\n        if isinstance(scheduled_operation.operation.gate,\n                      xmon_gates.Exp11Gate):\n            for other in schedule.operations_happening_at_same_time_as(\n                    scheduled_operation):\n                if self._check_if_exp11_operation_interacts(\n                        cast(ops.GateOperation, scheduled_operation.operation),\n                        cast(ops.GateOperation, other.operation)):\n                    raise ValueError(\n                        'Adjacent Exp11 operations: {} vs {}.'.format(\n                            scheduled_operation, other))\n\n    def validate_circuit(self, circuit: circuits.Circuit):\n        super().validate_circuit(circuit)\n        _verify_unique_measurement_keys(circuit.all_operations())\n\n    def validate_moment(self, moment: circuits.Moment):\n        super().validate_moment(moment)\n        for op in moment.operations:\n            if (isinstance(op, ops.GateOperation) and\n                    isinstance(op.gate, xmon_gates.Exp11Gate)):\n                for other in moment.operations:\n                    if (other is not op and\n                            self._check_if_exp11_operation_interacts(\n                                cast(ops.GateOperation, op),\n                                cast(ops.GateOperation, other))):\n                        raise ValueError(\n                            'Adjacent Exp11 operations: {}.'.format(moment))\n\n    def can_add_operation_into_moment(self,\n                                      operation: ops.Operation,\n                                      moment: circuits.Moment) -> bool:\n        self.validate_moment(moment)\n\n        if not super().can_add_operation_into_moment(operation, moment):\n            return False\n        if (isinstance(operation, ops.GateOperation) and\n                isinstance(operation.gate, xmon_gates.Exp11Gate)):\n            return not self._check_if_exp11_operation_interacts_with_any(\n                cast(ops.GateOperation, operation),\n                cast(Iterable[ops.GateOperation], moment.operations))\n        return True\n\n    def validate_schedule(self, schedule):\n        _verify_unique_measurement_keys(\n            s.operation for s in schedule.scheduled_operations)\n        for scheduled_operation in schedule.scheduled_operations:\n            self.validate_scheduled_operation(schedule, scheduled_operation)\n\n    def at(self, row: int, col: int) -> Optional[GridQubit]:\n        \"\"\"Returns the qubit at the given position, if there is one, else None.\n        \"\"\"\n        q = GridQubit(row, col)\n        return q if q in self.qubits else None\n\n    def row(self, row: int) -> List[GridQubit]:\n        \"\"\"Returns the qubits in the given row, in ascending order.\"\"\"\n        return sorted(q for q in self.qubits if q.row == row)\n\n    def col(self, col: int) -> List[GridQubit]:\n        \"\"\"Returns the qubits in the given column, in ascending order.\"\"\"\n        return sorted(q for q in self.qubits if q.col == col)\n\n    def __repr__(self):\n        return ('XmonDevice(measurement_duration={!r}, '\n                'exp_w_duration={!r}, '\n                'exp_11_duration={!r} '\n                'qubits={!r})').format(self._measurement_duration,\n                                       self._exp_w_duration,\n                                       self._exp_z_duration,\n                                       sorted(self.qubits))\n\n    def __str__(self):\n        diagram = TextDiagramDrawer()\n\n        for q in self.qubits:\n            diagram.write(q.col, q.row, str(q))\n            for q2 in self.neighbors_of(q):\n                diagram.grid_line(q.col, q.row, q2.col, q2.row)\n\n        return diagram.render(\n            horizontal_spacing=3,\n            vertical_spacing=2,\n            use_unicode_characters=True)\n\n    def __eq__(self, other):\n        if not isinstance(other, (XmonDevice, type(self))):\n            return NotImplemented\n        return (self._measurement_duration == other._measurement_duration and\n                self._exp_w_duration == other._exp_w_duration and\n                self._exp_z_duration == other._exp_z_duration and\n                self.qubits == other.qubits)\n\n    def __ne__(self, other):\n        return not self == other\n\n    def __hash__(self):\n        return hash((XmonDevice, self._measurement_duration,\n                     self._exp_w_duration, self._exp_z_duration, self.qubits))\n\n\ndef _verify_unique_measurement_keys(operations: Iterable[ops.Operation]):\n    seen = set()  # type: Set[str]\n    for op in operations:\n        if ops.MeasurementGate.is_measurement(op):\n            key = cast(ops.MeasurementGate,\n                       cast(ops.GateOperation, op).gate).key\n            if key in seen:\n                raise ValueError('Measurement key {} repeated'.format(key))\n            seen.add(key)\n", "path": "cirq/google/xmon_device.py"}]}