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 |