GCC Code Coverage Report


Directory: ./
File: ZX/ZXGenerator.cpp
Date: 2022-10-15 05:10:18
Warnings: 6 unchecked decisions!
Exec Total Coverage
Lines: 195 244 79.9%
Functions: 53 59 89.8%
Branches: 136 299 45.5%
Decisions: 29 62 46.8%

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 #include "ZX/ZXGenerator.hpp"
16
17 #include <sstream>
18 #include <tkassert/Assert.hpp>
19
20 #include "ZX/ZXDiagram.hpp"
21
22 namespace tket {
23
24 namespace zx {
25
26 /**
27 * ZXType CLASS SETS
28 */
29
30 6868 bool find_in_set(const ZXType& val, const ZXTypeSet& set) {
31
1/2
✓ Branch 2 taken 6868 times.
✗ Branch 3 not taken.
6868 return set.find(val) != set.end();
32 }
33
34 3391 bool is_boundary_type(ZXType type) {
35 static const ZXTypeSet boundaries = {
36
4/8
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3390 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
3391 ZXType::Input, ZXType::Output, ZXType::Open};
37 3391 return find_in_set(type, boundaries);
38 }
39
40 742 bool is_basic_gen_type(ZXType type) {
41 static const ZXTypeSet basics = {
42 ZXType::ZSpider, ZXType::XSpider, ZXType::Hbox, ZXType::XY, ZXType::XZ,
43
4/8
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 741 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
742 ZXType::YZ, ZXType::PX, ZXType::PY, ZXType::PZ};
44 742 return find_in_set(type, basics);
45 }
46
47 567 bool is_spider_type(ZXType type) {
48
4/8
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 566 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
567 static const ZXTypeSet spiders = {ZXType::ZSpider, ZXType::XSpider};
49 567 return find_in_set(type, spiders);
50 }
51
52 811 bool is_directed_type(ZXType type) {
53
4/8
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 810 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
811 static const ZXTypeSet directed = {ZXType::Triangle, ZXType::ZXBox};
54 811 return find_in_set(type, directed);
55 }
56
57 611 bool is_MBQC_type(ZXType type) {
58 static const ZXTypeSet MBQC = {ZXType::XY, ZXType::XZ, ZXType::YZ,
59
4/8
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 610 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
611 ZXType::PX, ZXType::PY, ZXType::PZ};
60 611 return find_in_set(type, MBQC);
61 }
62
63 666 bool is_phase_type(ZXType type) {
64 static const ZXTypeSet phases = {ZXType::ZSpider, ZXType::XSpider,
65 ZXType::Hbox, ZXType::XY,
66
4/8
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 665 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
666 ZXType::XZ, ZXType::YZ};
67 666 return find_in_set(type, phases);
68 }
69
70 80 bool is_Clifford_gen_type(ZXType type) {
71
4/8
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 79 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
80 static const ZXTypeSet cliffords = {ZXType::PX, ZXType::PY, ZXType::PZ};
72 80 return find_in_set(type, cliffords);
73 }
74
75 /**
76 * ZXGen (Base class) implementation
77 */
78
79 1174 ZXGen::ZXGen(ZXType type) : type_(type) {}
80
81 14107 ZXType ZXGen::get_type() const { return type_; }
82
83 3 bool ZXGen::operator==(const ZXGen& other) const {
84
3/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 1 times.
3 return (this->type_ == other.type_) && is_equal(other);
85 }
86
87 bool ZXGen::is_equal(const ZXGen&) const { return true; }
88
89 2394 ZXGen::~ZXGen() {}
90
91 625 ZXGen_ptr ZXGen::create_gen(ZXType type, QuantumType qtype) {
92 625 ZXGen_ptr op;
93
5/6
✓ Branch 0 taken 351 times.
✓ Branch 1 taken 133 times.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 68 times.
✓ Branch 4 taken 62 times.
✗ Branch 5 not taken.
625 switch (type) {
94 351 case ZXType::Input:
95 case ZXType::Output:
96 case ZXType::Open: {
97
1/2
✓ Branch 1 taken 351 times.
✗ Branch 2 not taken.
351 op = std::make_shared<const BoundaryGen>(type, qtype);
98 351 break;
99 }
100 133 case ZXType::ZSpider:
101 case ZXType::XSpider:
102 case ZXType::XY:
103 case ZXType::XZ:
104 case ZXType::YZ: {
105
1/2
✓ Branch 1 taken 133 times.
✗ Branch 2 not taken.
133 op = std::make_shared<const PhasedGen>(type, 0., qtype);
106 133 break;
107 }
108
1/1
✓ Decision 'true' taken 11 times.
11 case ZXType::Hbox: {
109
1/2
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
11 op = std::make_shared<const PhasedGen>(type, -1., qtype);
110 11 break;
111 }
112 68 case ZXType::PX:
113 case ZXType::PY:
114 case ZXType::PZ: {
115
1/2
✓ Branch 1 taken 68 times.
✗ Branch 2 not taken.
68 op = std::make_shared<const CliffordGen>(type, false, qtype);
116 68 break;
117 }
118
1/1
✓ Decision 'true' taken 62 times.
62 case ZXType::Triangle: {
119
1/2
✓ Branch 1 taken 62 times.
✗ Branch 2 not taken.
62 op = std::make_shared<const DirectedGen>(type, qtype);
120 62 break;
121 }
122
0/1
✗ Decision 'true' not taken.
default:
123 throw ZXError("Cannot instantiate a ZXGen of the required type");
124 }
125 625 return op;
126 }
127
128 423 ZXGen_ptr ZXGen::create_gen(ZXType type, const Expr& param, QuantumType qtype) {
129 423 ZXGen_ptr op;
130
2/2
✓ Branch 0 taken 422 times.
✓ Branch 1 taken 1 times.
423 switch (type) {
131 422 case ZXType::ZSpider:
132 case ZXType::XSpider:
133 case ZXType::XY:
134 case ZXType::XZ:
135 case ZXType::YZ:
136 case ZXType::Hbox: {
137
1/2
✓ Branch 1 taken 422 times.
✗ Branch 2 not taken.
422 op = std::make_shared<const PhasedGen>(type, param, qtype);
138 422 break;
139 }
140
1/1
✓ Decision 'true' taken 1 times.
1 default:
141
2/4
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
1 throw ZXError(
142 "Cannot instantiate a parameterised ZXGen of the required "
143 2 "type");
144 }
145 422 return op;
146 1 }
147
148 9 ZXGen_ptr ZXGen::create_gen(ZXType type, bool param, QuantumType qtype) {
149 9 ZXGen_ptr op;
150
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 switch (type) {
151 9 case ZXType::PX:
152 case ZXType::PY:
153 case ZXType::PZ: {
154
1/2
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
9 op = std::make_shared<const CliffordGen>(type, param, qtype);
155 9 break;
156 }
157
0/1
✗ Decision 'true' not taken.
default:
158 throw ZXError(
159 "Cannot instantiate a parameterised ZXGen of the required "
160 "type");
161 }
162 9 return op;
163 }
164
165 /**
166 * BoundaryGen implementation
167 */
168
169 358 BoundaryGen::BoundaryGen(ZXType type, QuantumType qtype)
170 358 : ZXGen(type), qtype_(qtype) {
171
2/4
✓ Branch 1 taken 358 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 358 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 358 times.
358 if (!is_boundary_type(type)) {
172
0/1
? Decision couldn't be analyzed.
throw ZXError("Unsupported ZXType for BoundaryGen");
173 }
174 358 }
175
176 445 std::optional<QuantumType> BoundaryGen::get_qtype() const { return qtype_; }
177
178 239 bool BoundaryGen::valid_edge(
179 std::optional<unsigned> port, QuantumType qtype) const {
180
4/4
✓ Branch 1 taken 238 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 237 times.
✓ Branch 4 taken 1 times.
239 return !port && (qtype == this->qtype_);
181 }
182
183 22 SymSet BoundaryGen::free_symbols() const { return {}; }
184
185 12 ZXGen_ptr BoundaryGen::symbol_substitution(
186 const SymEngine::map_basic_basic&) const {
187 12 return ZXGen_ptr();
188 }
189
190 5 std::string BoundaryGen::get_name(bool) const {
191
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 std::stringstream st;
192
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
1/2
✓ Decision 'true' taken 5 times.
✗ Decision 'false' not taken.
5 if (qtype_ == QuantumType::Quantum) {
193
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 st << "Q-";
194 } else {
195 st << "C-";
196 }
197
2/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
5 switch (type_) {
198
1/1
✓ Decision 'true' taken 3 times.
3 case ZXType::Input:
199
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 st << "Input";
200 3 break;
201
1/1
✓ Decision 'true' taken 2 times.
2 case ZXType::Output:
202
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 st << "Output";
203 2 break;
204
0/1
✗ Decision 'true' not taken.
case ZXType::Open:
205 st << "Open";
206 break;
207
0/1
✗ Decision 'true' not taken.
default:
208 throw ZXError("BoundaryGen with invalid ZXType");
209 }
210
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
10 return st.str();
211 5 }
212
213 bool BoundaryGen::is_equal(const ZXGen& other) const {
214 const BoundaryGen& other_bgen = static_cast<const BoundaryGen&>(other);
215 return (this->qtype_ == other_bgen.qtype_);
216 }
217
218 /**
219 * BasicGen implementation
220 */
221
222 742 BasicGen::BasicGen(ZXType type, QuantumType qtype)
223 742 : ZXGen(type), qtype_(qtype) {
224
3/4
✓ Branch 1 taken 742 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 741 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 741 times.
742 if (!is_basic_gen_type(type)) {
225
2/4
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
0/1
? Decision couldn't be analyzed.
1 throw ZXError("Unsupported ZXType for BasicGen");
226 }
227 742 }
228
229 1095 std::optional<QuantumType> BasicGen::get_qtype() const { return qtype_; }
230
231 1105 bool BasicGen::valid_edge(
232 std::optional<unsigned> port, QuantumType qtype) const {
233
4/4
✓ Branch 1 taken 1104 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 397 times.
✓ Branch 4 taken 707 times.
1502 return !port && (qtype == QuantumType::Quantum ||
234
2/2
✓ Branch 0 taken 396 times.
✓ Branch 1 taken 1 times.
1502 this->qtype_ == QuantumType::Classical);
235 }
236
237 3 bool BasicGen::is_equal(const ZXGen& other) const {
238 3 const BasicGen& other_basic = static_cast<const BasicGen&>(other);
239 3 return this->qtype_ == other_basic.qtype_;
240 }
241
242 /**
243 * PhasedGen implementation
244 */
245 662 PhasedGen::PhasedGen(ZXType type, const Expr& param, QuantumType qtype)
246
1/2
✓ Branch 2 taken 661 times.
✗ Branch 3 not taken.
662 : BasicGen(type, qtype), param_(param) {
247
2/4
✓ Branch 1 taken 661 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 661 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 661 times.
661 if (!is_phase_type(type)) {
248
0/1
? Decision couldn't be analyzed.
throw ZXError("Unsupported ZXType for PhasedGen");
249 }
250 661 }
251
252 339 Expr PhasedGen::get_param() const { return param_; }
253
254 14 SymSet PhasedGen::free_symbols() const { return expr_free_symbols(param_); }
255
256 10 ZXGen_ptr PhasedGen::symbol_substitution(
257 const SymEngine::map_basic_basic& sub_map) const {
258
1/2
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
10 return std::make_shared<const PhasedGen>(type_, param_.subs(sub_map), qtype_);
259 }
260
261 9 std::string PhasedGen::get_name(bool) const {
262
1/2
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
9 std::stringstream st;
263
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 5 times.
2/2
✓ Decision 'true' taken 4 times.
✓ Decision 'false' taken 5 times.
9 if (qtype_ == QuantumType::Quantum) {
264
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 st << "Q-";
265 } else {
266
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 st << "C-";
267 }
268
3/7
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
9 switch (type_) {
269
1/1
✓ Decision 'true' taken 4 times.
4 case ZXType::ZSpider:
270
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 st << "Z";
271 4 break;
272
1/1
✓ Decision 'true' taken 3 times.
3 case ZXType::XSpider:
273
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 st << "X";
274 3 break;
275
1/1
✓ Decision 'true' taken 2 times.
2 case ZXType::Hbox:
276
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 st << "H";
277 2 break;
278
0/1
✗ Decision 'true' not taken.
case ZXType::XY:
279 st << "XY";
280 break;
281
0/1
✗ Decision 'true' not taken.
case ZXType::XZ:
282 st << "XZ";
283 break;
284
0/1
✗ Decision 'true' not taken.
case ZXType::YZ:
285 st << "YZ";
286 break;
287
0/1
✗ Decision 'true' not taken.
default:
288 throw ZXError("PhasedGen with invalid ZXType");
289 }
290
3/6
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 9 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 9 times.
✗ Branch 8 not taken.
9 st << "(" << param_ << ")";
291
1/2
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
18 return st.str();
292 9 }
293
294 1 bool PhasedGen::is_equal(const ZXGen& other) const {
295
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1/2
✓ Decision 'true' taken 1 times.
✗ Decision 'false' not taken.
1 if (!BasicGen::is_equal(other)) return false;
296 1 const PhasedGen& other_basic = static_cast<const PhasedGen&>(other);
297 1 return this->param_ == other_basic.param_;
298 }
299
300 /**
301 * CliffordGen implementation
302 */
303 80 CliffordGen::CliffordGen(ZXType type, bool param, QuantumType qtype)
304 80 : BasicGen(type, qtype), param_(param) {
305
2/4
✓ Branch 1 taken 80 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 80 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 80 times.
80 if (!is_Clifford_gen_type(type)) {
306
0/1
? Decision couldn't be analyzed.
throw ZXError("Unsupported ZXType for CliffordGen");
307 }
308 80 }
309
310 171 bool CliffordGen::get_param() const { return param_; }
311
312 1 SymSet CliffordGen::free_symbols() const { return {}; }
313
314 ZXGen_ptr CliffordGen::symbol_substitution(
315 const SymEngine::map_basic_basic&) const {
316 return ZXGen_ptr();
317 }
318
319 1 std::string CliffordGen::get_name(bool) const {
320
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 std::stringstream st;
321
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 1 times.
1 if (qtype_ == QuantumType::Quantum) {
322 st << "Q-";
323 } else {
324
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 st << "C-";
325 }
326
1/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1 switch (type_) {
327
1/1
✓ Decision 'true' taken 1 times.
1 case ZXType::PX:
328
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 st << "X";
329 1 break;
330
0/1
✗ Decision 'true' not taken.
case ZXType::PY:
331 st << "Y";
332 break;
333
0/1
✗ Decision 'true' not taken.
case ZXType::PZ:
334 st << "Z";
335 break;
336
0/1
✗ Decision 'true' not taken.
default:
337 throw ZXError("CliffordGen with invalid ZXType");
338 }
339
3/6
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
1 st << "(" << param_ << ")";
340
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 return st.str();
341 1 }
342
343 2 bool CliffordGen::is_equal(const ZXGen& other) const {
344
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 1 times.
2 if (!BasicGen::is_equal(other)) return false;
345 1 const CliffordGen& other_basic = static_cast<const CliffordGen&>(other);
346 1 return this->param_ == other_basic.param_;
347 }
348
349 /**
350 * ZXDirected (abstract intermediate class) implementation
351 */
352
353 74 ZXDirected::ZXDirected(ZXType type) : ZXGen(type) {
354
2/4
✓ Branch 1 taken 74 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 74 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 74 times.
74 if (!is_directed_type(type)) {
355
0/1
? Decision couldn't be analyzed.
throw ZXError("Unsupported ZXType for ZXDirected");
356 }
357 74 }
358
359 /**
360 * DirectedGen implementation
361 */
362
363 64 DirectedGen::DirectedGen(ZXType type, QuantumType qtype)
364 64 : ZXDirected(type), qtype_(qtype) {
365
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 64 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 64 times.
64 if (type != ZXType::Triangle) {
366
0/1
? Decision couldn't be analyzed.
throw ZXError("Unsupported ZXType for DirectedGen");
367 }
368 64 }
369
370 100 std::optional<QuantumType> DirectedGen::get_qtype() const { return qtype_; }
371
372 94 bool DirectedGen::valid_edge(
373 std::optional<unsigned> port, QuantumType qtype) const {
374
6/6
✓ Branch 1 taken 93 times.
✓ Branch 2 taken 1 times.
✓ Branch 5 taken 92 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 91 times.
✓ Branch 8 taken 1 times.
94 return port && (*port < this->n_ports()) && (qtype == this->qtype_);
375 }
376
377 3 SymSet DirectedGen::free_symbols() const { return {}; }
378
379 2 ZXGen_ptr DirectedGen::symbol_substitution(
380 const SymEngine::map_basic_basic&) const {
381 2 return ZXGen_ptr();
382 }
383
384 2 std::string DirectedGen::get_name(bool) const {
385
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 1 times.
2 if (qtype_ == QuantumType::Quantum) {
386
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 return "Q-Tri";
387 } else {
388
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 return "C-Tri";
389 }
390 }
391
392 bool DirectedGen::is_equal(const ZXGen& other) const {
393 const DirectedGen& other_dir = static_cast<const DirectedGen&>(other);
394 return (this->qtype_ == other_dir.qtype_);
395 }
396
397 139 unsigned DirectedGen::n_ports() const { return 2; }
398
399 std::vector<QuantumType> DirectedGen::get_signature() const {
400 return std::vector<QuantumType>(2, qtype_);
401 }
402
403 /**
404 * ZXBox implementation
405 */
406
407 10 ZXBox::ZXBox(const ZXDiagram& diag)
408 : ZXDirected(ZXType::ZXBox),
409
1/2
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
10 diag_(std::make_shared<const ZXDiagram>(diag)) {}
410
411 4 std::shared_ptr<const ZXDiagram> ZXBox::get_diagram() const { return diag_; }
412
413 2 std::optional<QuantumType> ZXBox::get_qtype() const { return std::nullopt; }
414
415 22 bool ZXBox::valid_edge(std::optional<unsigned> port, QuantumType qtype) const {
416
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 22 times.
1/2
✓ Decision 'true' taken 22 times.
✗ Decision 'false' not taken.
22 if (!port) return false;
417
1/2
✓ Branch 4 taken 22 times.
✗ Branch 5 not taken.
22 ZXVertVec boundary = diag_->get_boundary();
418
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 22 times.
1/2
✓ Decision 'true' taken 22 times.
✗ Decision 'false' not taken.
22 if (*port >= boundary.size()) return false;
419
2/4
✓ Branch 3 taken 22 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 22 times.
✗ Branch 7 not taken.
22 return (qtype == diag_->get_qtype(boundary.at(*port)));
420 22 }
421
422 3 SymSet ZXBox::free_symbols() const { return diag_->free_symbols(); }
423
424 2 ZXGen_ptr ZXBox::symbol_substitution(
425 const SymEngine::map_basic_basic& sub_map) const {
426
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 ZXDiagram new_diag(*diag_);
427
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 new_diag.symbol_substitution(sub_map);
428
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
4 return std::make_shared<const ZXBox>(new_diag);
429 2 }
430
431
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 std::string ZXBox::get_name(bool) const { return "Box"; }
432
433 bool ZXBox::is_equal(const ZXGen&) const {
434 // Checking for a proper graph isomorphism is difficult. Safest to just assume
435 // all boxes are unique.
436 return false;
437 }
438
439
1/2
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
10 unsigned ZXBox::n_ports() const { return diag_->get_boundary().size(); }
440
441 2 std::vector<QuantumType> ZXBox::get_signature() const {
442
1/2
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 ZXVertVec boundary = diag_->get_boundary();
443 2 std::vector<QuantumType> sig;
444
2/2
✓ Branch 5 taken 4 times.
✓ Branch 6 taken 2 times.
2/2
✓ Decision 'true' taken 4 times.
✓ Decision 'false' taken 2 times.
6 for (const ZXVert& b : boundary) {
445
1/2
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 std::optional<QuantumType> qt = diag_->get_qtype(b);
446 TKET_ASSERT(qt.has_value());
447
1/2
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 sig.push_back(*qt);
448 }
449 4 return sig;
450 2 }
451
452 } // namespace zx
453
454 } // namespace tket
455