Line | Branch | Decision | Exec | Source |
---|---|---|---|---|
1 | // Copyright 2019-2022 Cambridge Quantum Computing | |||
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 | #pragma once | |||
16 | #include <string> | |||
17 | #include <typeindex> | |||
18 | ||||
19 | #include "Architecture/Architecture.hpp" | |||
20 | #include "Transformations/Transform.hpp" | |||
21 | ||||
22 | namespace tket { | |||
23 | class Predicate; | |||
24 | ||||
25 | typedef std::shared_ptr<Predicate> PredicatePtr; | |||
26 | ||||
27 | JSON_DECL(PredicatePtr) | |||
28 | ||||
29 | class IncorrectPredicate : public std::logic_error { | |||
30 | public: | |||
31 | 1 | explicit IncorrectPredicate(const std::string& exception_string) | ||
32 | 1 | : std::logic_error(exception_string) {} | ||
33 | }; | |||
34 | ||||
35 | class UnsatisfiedPredicate : public std::logic_error { | |||
36 | public: | |||
37 | 4 | explicit UnsatisfiedPredicate(const std::string& pred_name) | ||
38 | 4 | : std::logic_error( | ||
39 |
1/2✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
|
4 | "Predicate requirements are not satisfied: " + pred_name) {} | |
40 | }; | |||
41 | ||||
42 | class PredicateNotSerializable : public std::logic_error { | |||
43 | public: | |||
44 | 1 | explicit PredicateNotSerializable(const std::string& pred_name) | ||
45 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | : std::logic_error("Predicate not serializable: " + pred_name) {} | |
46 | }; | |||
47 | ||||
48 | const std::string& predicate_name(std::type_index idx); | |||
49 | ||||
50 | ///////////////////// | |||
51 | // PREDICATE CLASSES// | |||
52 | ///////////////////// | |||
53 | ||||
54 | // abstract interface class | |||
55 | class Predicate { | |||
56 | public: | |||
57 | virtual bool verify(const Circuit& circ) const = 0; | |||
58 | ||||
59 | // implication currently only works between predicates of the same subclass | |||
60 | virtual bool implies(const Predicate& other) const = 0; | |||
61 | virtual PredicatePtr meet(const Predicate& other) const = 0; | |||
62 | virtual std::string to_string() const = 0; | |||
63 | ✗ | virtual ~Predicate(){}; // satisfy compiler | ||
64 | }; | |||
65 | ||||
66 | // all Predicate subclasses must inherit from `Predicate` | |||
67 | class GateSetPredicate : public Predicate { | |||
68 | public: | |||
69 | ✗ | explicit GateSetPredicate(const OpTypeSet& allowed_types) | ||
70 | ✗ | : allowed_types_(allowed_types) {} | ||
71 | bool verify(const Circuit& circ) const override; | |||
72 | bool implies(const Predicate& other) const override; | |||
73 | PredicatePtr meet(const Predicate& other) const override; | |||
74 | ||||
75 | std::string to_string() const override; | |||
76 | ✗ | const OpTypeSet& get_allowed_types() const { return allowed_types_; } | ||
77 | ||||
78 | private: | |||
79 | const OpTypeSet allowed_types_; | |||
80 | }; | |||
81 | ||||
82 | /** | |||
83 | * Asserts that there are no conditional gates in the circuit. | |||
84 | */ | |||
85 | class NoClassicalControlPredicate : public Predicate { | |||
86 | public: | |||
87 | bool verify(const Circuit& circ) const override; | |||
88 | bool implies(const Predicate& other) const override; | |||
89 | PredicatePtr meet(const Predicate& other) const override; | |||
90 | std::string to_string() const override; | |||
91 | }; | |||
92 | ||||
93 | class NoFastFeedforwardPredicate : public Predicate { | |||
94 | // verifies Circuit has no classical bits which are written from quantum gates | |||
95 | // and then read in later in the Circuit | |||
96 | public: | |||
97 | bool verify(const Circuit& circ) const override; | |||
98 | bool implies(const Predicate& other) const override; | |||
99 | PredicatePtr meet(const Predicate& other) const override; | |||
100 | std::string to_string() const override; | |||
101 | }; | |||
102 | ||||
103 | class NoClassicalBitsPredicate : public Predicate { | |||
104 | // this verifies that the Circuit uses no classical bits | |||
105 | // (read or write -- so no measures and no classical controls) | |||
106 | public: | |||
107 | bool verify(const Circuit& circ) const override; | |||
108 | bool implies(const Predicate& other) const override; | |||
109 | PredicatePtr meet(const Predicate& other) const override; | |||
110 | std::string to_string() const override; | |||
111 | }; | |||
112 | ||||
113 | class NoWireSwapsPredicate : public Predicate { | |||
114 | /** | |||
115 | * Verifies that you can follow the paths of each qubit/bit in the circuit | |||
116 | * and finish on the same qubit/bit you started with | |||
117 | */ | |||
118 | public: | |||
119 | bool verify(const Circuit& circ) const override; | |||
120 | bool implies(const Predicate& other) const override; | |||
121 | PredicatePtr meet(const Predicate& other) const override; | |||
122 | std::string to_string() const override; | |||
123 | }; | |||
124 | ||||
125 | class MaxTwoQubitGatesPredicate : public Predicate { | |||
126 | // this verifies that the Circuit uses no gates with greater than 2 qubits | |||
127 | // Barriers are ignored | |||
128 | public: | |||
129 | bool verify(const Circuit& circ) const override; | |||
130 | bool implies(const Predicate& other) const override; | |||
131 | PredicatePtr meet(const Predicate& other) const override; | |||
132 | std::string to_string() const override; | |||
133 | }; | |||
134 | ||||
135 | class PlacementPredicate : public Predicate { | |||
136 | public: | |||
137 | ✗ | explicit PlacementPredicate(const Architecture& arch) | ||
138 | ✗ | : nodes_(arch.nodes()) {} | ||
139 | ✗ | explicit PlacementPredicate(const node_set_t& nodes) : nodes_(nodes) {} | ||
140 | bool verify(const Circuit& circ) const override; | |||
141 | bool implies(const Predicate& other) const override; | |||
142 | PredicatePtr meet(const Predicate& other) const override; | |||
143 | std::string to_string() const override; | |||
144 | ✗ | const node_set_t& get_nodes() const { return nodes_; } | ||
145 | ||||
146 | private: | |||
147 | const node_set_t nodes_; | |||
148 | }; | |||
149 | ||||
150 | class ConnectivityPredicate : public Predicate { | |||
151 | public: | |||
152 | ✗ | explicit ConnectivityPredicate(const Architecture& arch) : arch_(arch) {} | ||
153 | bool verify(const Circuit& circ) const override; | |||
154 | bool implies(const Predicate& other) const override; | |||
155 | PredicatePtr meet(const Predicate& other) const override; | |||
156 | std::string to_string() const override; | |||
157 | ✗ | const Architecture& get_arch() const { return arch_; } | ||
158 | ||||
159 | private: | |||
160 | const Architecture arch_; | |||
161 | }; | |||
162 | ||||
163 | class DirectednessPredicate : public Predicate { | |||
164 | public: | |||
165 | ✗ | explicit DirectednessPredicate(const Architecture& arch) : arch_(arch) {} | ||
166 | bool verify(const Circuit& circ) const override; | |||
167 | bool implies(const Predicate& other) const override; | |||
168 | PredicatePtr meet(const Predicate& other) const override; | |||
169 | std::string to_string() const override; | |||
170 | ✗ | const Architecture& get_arch() const { return arch_; } | ||
171 | ||||
172 | private: | |||
173 | const Architecture arch_; | |||
174 | }; | |||
175 | ||||
176 | class CliffordCircuitPredicate : public Predicate { | |||
177 | public: | |||
178 | bool verify(const Circuit& circ) const override; | |||
179 | bool implies(const Predicate& other) const override; | |||
180 | PredicatePtr meet(const Predicate& other) const override; | |||
181 | std::string to_string() const override; | |||
182 | }; | |||
183 | ||||
184 | class UserDefinedPredicate : public Predicate { | |||
185 | public: | |||
186 | explicit UserDefinedPredicate(const std::function<bool(const Circuit&)>& func) | |||
187 | : func_(func) {} | |||
188 | bool verify(const Circuit& circ) const override; | |||
189 | bool implies(const Predicate&) const override; | |||
190 | PredicatePtr meet(const Predicate&) const override; | |||
191 | std::string to_string() const override; | |||
192 | ||||
193 | private: | |||
194 | const std::function<bool(const Circuit&)> func_; | |||
195 | }; | |||
196 | ||||
197 | class DefaultRegisterPredicate : public Predicate { | |||
198 | public: | |||
199 | bool verify(const Circuit& circ) const override; | |||
200 | bool implies(const Predicate& other) const override; | |||
201 | PredicatePtr meet(const Predicate& other) const override; | |||
202 | std::string to_string() const override; | |||
203 | }; | |||
204 | ||||
205 | class MaxNQubitsPredicate : public Predicate { | |||
206 | public: | |||
207 | ✗ | explicit MaxNQubitsPredicate(unsigned n_qubits) : n_qubits_(n_qubits) {} | ||
208 | bool verify(const Circuit& circ) const override; | |||
209 | bool implies(const Predicate& other) const override; | |||
210 | PredicatePtr meet(const Predicate& other) const override; | |||
211 | std::string to_string() const override; | |||
212 | ✗ | unsigned get_n_qubits() const { return n_qubits_; } | ||
213 | ||||
214 | private: | |||
215 | const unsigned n_qubits_; | |||
216 | }; | |||
217 | ||||
218 | /** | |||
219 | * Asserts that the circuit contains no \ref OpType::Barrier | |||
220 | */ | |||
221 | class NoBarriersPredicate : public Predicate { | |||
222 | public: | |||
223 | bool verify(const Circuit& circ) const override; | |||
224 | bool implies(const Predicate& other) const override; | |||
225 | PredicatePtr meet(const Predicate& other) const override; | |||
226 | std::string to_string() const override; | |||
227 | }; | |||
228 | ||||
229 | /** | |||
230 | * Asserts that any measurements occur at the end of the circuit | |||
231 | */ | |||
232 | class NoMidMeasurePredicate : public Predicate { | |||
233 | public: | |||
234 | bool verify(const Circuit& circ) const override; | |||
235 | bool implies(const Predicate& other) const override; | |||
236 | PredicatePtr meet(const Predicate& other) const override; | |||
237 | std::string to_string() const override; | |||
238 | }; | |||
239 | ||||
240 | /** | |||
241 | * Asserts that no gates in the circuit have symbolic parameters | |||
242 | */ | |||
243 | class NoSymbolsPredicate : public Predicate { | |||
244 | public: | |||
245 | bool verify(const Circuit& circ) const override; | |||
246 | bool implies(const Predicate& other) const override; | |||
247 | PredicatePtr meet(const Predicate& other) const override; | |||
248 | std::string to_string() const override; | |||
249 | }; | |||
250 | ||||
251 | /** | |||
252 | * Asserts that all NPhasedX gates act on all qubits | |||
253 | * In the future, it might be useful to have a generic GlobalGatePredicate | |||
254 | * for other global gates, or flag some gates as global | |||
255 | */ | |||
256 | class GlobalPhasedXPredicate : public Predicate { | |||
257 | public: | |||
258 | bool verify(const Circuit& circ) const override; | |||
259 | bool implies(const Predicate& other) const override; | |||
260 | PredicatePtr meet(const Predicate& other) const override; | |||
261 | std::string to_string() const override; | |||
262 | }; | |||
263 | ||||
264 | /** | |||
265 | * Asserts that all TK2 gates are normalised | |||
266 | * | |||
267 | * A gate TK2(a, b, c) is considered normalised if | |||
268 | * | |||
269 | * - If all expressions are non symbolic, then it must hold | |||
270 | * `0.5 ≥ a ≥ b ≥ |c|`. | |||
271 | * - In the ordering (a, b, c), any symbolic expression must appear before | |||
272 | * non-symbolic ones. The remaining non-symbolic expressions must still be | |||
273 | * ordered in non-increasing order and must be in the interval [0, 1/2], | |||
274 | * with the exception of the last one that may be in [-1/2, 1/2]. | |||
275 | */ | |||
276 | class NormalisedTK2Predicate : public Predicate { | |||
277 | public: | |||
278 | bool verify(const Circuit& circ) const override; | |||
279 | bool implies(const Predicate& other) const override; | |||
280 | PredicatePtr meet(const Predicate& other) const override; | |||
281 | std::string to_string() const override; | |||
282 | }; | |||
283 | ||||
284 | } // namespace tket | |||
285 |