GCC Code Coverage Report


Directory: ./
File: ZX/ZXRWGraphLikeSimplification.cpp
Date: 2022-10-15 05:10:18
Warnings: 6 unchecked decisions!
Exec Total Coverage
Lines: 136 159 85.5%
Functions: 9 9 100.0%
Branches: 174 342 50.9%
Decisions: 42 70 60.0%

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 "Utils/GraphHeaders.hpp"
16 #include "ZX/Rewrite.hpp"
17
18 namespace tket {
19
20 namespace zx {
21
22 /**
23 * Helper method for local complementation and pivoting.
24 * Checks that all neighbours of some vertex v are also ZSpiders.
25 * If v is Classical, all neighbours must also be Classical.
26 */
27 21 static bool can_complement_neighbourhood(
28 const ZXDiagram& diag, QuantumType vqtype, const ZXVertVec& neighbours) {
29
2/2
✓ Branch 5 taken 55 times.
✓ Branch 6 taken 10 times.
2/2
✓ Decision 'true' taken 55 times.
✓ Decision 'false' taken 10 times.
65 for (const ZXVert& n : neighbours) {
30
4/6
✓ Branch 1 taken 55 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 44 times.
✓ Branch 4 taken 11 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 44 times.
2/2
✓ Decision 'true' taken 11 times.
✓ Decision 'false' taken 44 times.
55 if (diag.get_zxtype(n) != ZXType::ZSpider ||
31 (vqtype == QuantumType::Classical &&
32
2/6
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 11 times.
✓ Branch 7 taken 44 times.
55 *diag.get_qtype(n) == QuantumType::Quantum))
33 11 return false;
34 }
35 10 return true;
36 }
37
38 1 bool Rewrite::remove_interior_cliffords_fun(ZXDiagram& diag) {
39
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
1/2
✓ Decision 'true' taken 1 times.
✗ Decision 'false' not taken.
1 if (!diag.is_graphlike()) return false;
40 1 bool success = false;
41
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 ZXVertSeqSet candidates;
42
8/10
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 28 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 28 times.
✓ Branch 10 taken 1 times.
✓ Branch 12 taken 28 times.
✓ Branch 13 taken 1 times.
✓ Branch 15 taken 1 times.
✓ Branch 16 taken 1 times.
30 BGL_FORALL_VERTICES(v, *diag.graph, ZXGraph) { candidates.insert(v); }
43 1 auto& view = candidates.get<TagSeq>();
44
2/2
✓ Branch 1 taken 41 times.
✓ Branch 2 taken 1 times.
2/2
✓ Decision 'true' taken 41 times.
✓ Decision 'false' taken 1 times.
42 while (!candidates.empty()) {
45 41 auto it = view.begin();
46
1/2
✓ Branch 1 taken 41 times.
✗ Branch 2 not taken.
41 ZXVert v = *it;
47
1/2
✓ Branch 1 taken 41 times.
✗ Branch 2 not taken.
41 view.erase(it);
48
3/4
✓ Branch 1 taken 41 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 24 times.
✓ Branch 4 taken 17 times.
2/2
✓ Decision 'true' taken 17 times.
✓ Decision 'false' taken 33 times.
50 if (!diag.is_proper_clifford_spider(v)) continue;
49
1/2
✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
17 const PhasedGen& spid = diag.get_vertex_ZXGen<PhasedGen>(v);
50
1/2
✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
17 QuantumType vqtype = *spid.get_qtype();
51
1/2
✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
17 ZXVertVec neighbours = diag.neighbours(v);
52
3/4
✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 9 times.
✓ Branch 4 taken 8 times.
2/2
✓ Decision 'true' taken 8 times.
✓ Decision 'false' taken 9 times.
17 if (!can_complement_neighbourhood(diag, vqtype, neighbours)) continue;
53 // Found an internal proper clifford spider on which we can perform local
54 // complementation
55 /**
56 * Complement the neighbourhoods' edges and modify the phase information
57 * on the neighbours.
58 **/
59 8 auto xi = neighbours.begin(), x_end = neighbours.end();
60
2/2
✓ Branch 2 taken 25 times.
✓ Branch 3 taken 8 times.
2/2
✓ Decision 'true' taken 25 times.
✓ Decision 'false' taken 8 times.
33 for (; xi != x_end; ++xi) {
61
2/2
✓ Branch 3 taken 31 times.
✓ Branch 4 taken 25 times.
2/2
✓ Decision 'true' taken 31 times.
✓ Decision 'false' taken 25 times.
56 for (auto yi = xi + 1; yi != x_end; ++yi) {
62 // Don't add a doubled edge between classicals to preserve graph-like
63
1/2
✓ Branch 0 taken 31 times.
✗ Branch 1 not taken.
2/2
✓ Decision 'true' taken 31 times.
✓ Decision 'false' taken 31 times.
62 if (!(vqtype == QuantumType::Quantum &&
64
2/4
✓ Branch 2 taken 31 times.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 31 times.
31 *diag.get_qtype(*xi) == QuantumType::Classical &&
65
1/6
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 31 times.
✗ Branch 8 not taken.
31 *diag.get_qtype(*yi) == QuantumType::Classical)) {
66
1/2
✓ Branch 3 taken 31 times.
✗ Branch 4 not taken.
31 std::optional<Wire> wire = diag.wire_between(*xi, *yi);
67
2/2
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 25 times.
2/2
✓ Decision 'true' taken 6 times.
✓ Decision 'false' taken 25 times.
31 if (wire)
68
1/2
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 diag.remove_wire(*wire);
69 else
70
1/2
✓ Branch 5 taken 25 times.
✗ Branch 6 not taken.
25 diag.add_wire(*xi, *yi, ZXWireType::H, vqtype);
71 }
72 }
73
1/2
✓ Branch 2 taken 25 times.
✗ Branch 3 not taken.
25 const PhasedGen& xi_op = diag.get_vertex_ZXGen<PhasedGen>(*xi);
74 // If `v` is Quantum, Classical neighbours will pick up both the +theta
75 // and -theta phases, cancelling out
76
1/2
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 50 times.
50 if (vqtype == QuantumType::Quantum &&
77
3/6
✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 25 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 25 times.
50 *xi_op.get_qtype() == QuantumType::Classical)
78 continue;
79 // Update phase information
80 25 ZXGen_ptr xi_new_op = std::make_shared<const PhasedGen>(
81
4/8
✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 25 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 25 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 25 times.
✗ Branch 11 not taken.
50 ZXType::ZSpider, xi_op.get_param() - spid.get_param(),
82
1/2
✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
50 *xi_op.get_qtype());
83
1/2
✓ Branch 2 taken 25 times.
✗ Branch 3 not taken.
25 diag.set_vertex_ZXGen_ptr(*xi, xi_new_op);
84
1/2
✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
25 candidates.insert(
85 25 *xi); // Changing the phase could introduce a new proper Clifford
86 25 }
87
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 diag.remove_vertex(v);
88 8 success = true;
89
2/2
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 9 times.
17 }
90 1 return success;
91 1 }
92
93 1 Rewrite Rewrite::remove_interior_cliffords() {
94
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 return Rewrite(remove_interior_cliffords_fun);
95 }
96
97 3 static void add_phase_to_vertices(
98 ZXDiagram& diag, const ZXVertSeqSet& verts, const Expr& phase) {
99
5/8
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 3 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 6 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 3 times.
✓ Branch 12 taken 3 times.
0/1
? Decision couldn't be analyzed.
6 for (const ZXVert& v : verts) {
100
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 const PhasedGen& old_spid = diag.get_vertex_ZXGen<PhasedGen>(v);
101 3 ZXGen_ptr new_spid = std::make_shared<const PhasedGen>(
102
4/8
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 3 times.
✗ Branch 11 not taken.
9 ZXType::ZSpider, old_spid.get_param() + phase, *old_spid.get_qtype());
103
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 diag.set_vertex_ZXGen_ptr(v, new_spid);
104 3 }
105 3 }
106
107 3 static void bipartite_complementation(
108 ZXDiagram& diag, const ZXVertSeqSet& sa, const ZXVertSeqSet& sb,
109 QuantumType qtype) {
110
5/8
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 4 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 1 times.
✓ Branch 13 taken 3 times.
0/1
? Decision couldn't be analyzed.
4 for (const ZXVert& a : sa.get<TagSeq>()) {
111
5/8
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 3 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 2 times.
✓ Branch 13 taken 1 times.
0/1
? Decision couldn't be analyzed.
3 for (const ZXVert& b : sb.get<TagSeq>()) {
112 // Don't add a doubled edge between classicals to preserve graph-like
113
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2/2
✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 2 times.
4 if (!(qtype == QuantumType::Quantum &&
114
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
2 *diag.get_qtype(a) == QuantumType::Classical &&
115
1/6
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
2 *diag.get_qtype(b) == QuantumType::Classical)) {
116
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 std::optional<Wire> wire = diag.wire_between(a, b);
117
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 2 times.
2 if (wire)
118 diag.remove_wire(*wire);
119 else
120
1/2
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
2 diag.add_wire(a, b, ZXWireType::H, qtype);
121 }
122 }
123 }
124 3 }
125
126 1 bool Rewrite::remove_interior_paulis_fun(ZXDiagram& diag) {
127
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
1/2
✓ Decision 'true' taken 1 times.
✗ Decision 'false' not taken.
1 if (!diag.is_graphlike()) return false;
128 1 bool success = false;
129
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 ZXVertSeqSet candidates; // Need an indirect iterator as BGL_FORALL_VERTICES
130 // breaks when removing the current vertex
131
8/10
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 20 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 20 times.
✓ Branch 10 taken 1 times.
✓ Branch 12 taken 20 times.
✓ Branch 13 taken 1 times.
✓ Branch 15 taken 1 times.
✓ Branch 16 taken 1 times.
22 BGL_FORALL_VERTICES(v, *diag.graph, ZXGraph) { candidates.insert(v); }
132 1 auto& view = candidates.get<TagSeq>();
133
2/2
✓ Branch 1 taken 19 times.
✓ Branch 2 taken 1 times.
2/2
✓ Decision 'true' taken 19 times.
✓ Decision 'false' taken 1 times.
20 while (!candidates.empty()) {
134 19 auto it = view.begin();
135
1/2
✓ Branch 1 taken 19 times.
✗ Branch 2 not taken.
19 ZXVert v = *it;
136
1/2
✓ Branch 1 taken 19 times.
✗ Branch 2 not taken.
19 view.erase(it);
137 // Check `v` is an interior Pauli
138
3/4
✓ Branch 1 taken 19 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 16 times.
✓ Branch 4 taken 3 times.
2/2
✓ Decision 'true' taken 3 times.
✓ Decision 'false' taken 18 times.
21 if (!diag.is_pauli_spider(v)) continue;
139
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 ZXVertVec v_ns = diag.neighbours(v);
140
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 QuantumType vqtype = *diag.get_qtype(v);
141
3/4
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 1 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 2 times.
3 if (!can_complement_neighbourhood(diag, vqtype, v_ns)) continue;
142 // Look for an interior Pauli neighbour
143 1 bool pair_found = false;
144 ZXVert u;
145 1 ZXVertVec u_ns;
146
1/2
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
1/2
✓ Decision 'true' taken 1 times.
✗ Decision 'false' not taken.
1 for (const ZXVert& n : v_ns) {
147
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
1/2
✓ Decision 'true' taken 1 times.
✗ Decision 'false' not taken.
1 if (!diag.is_pauli_spider(n)) continue;
148
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 ZXVertVec n_ns = diag.neighbours(n);
149
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 QuantumType nqtype = *diag.get_qtype(n);
150
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
1/2
✓ Decision 'true' taken 1 times.
✗ Decision 'false' not taken.
1 if (can_complement_neighbourhood(diag, nqtype, n_ns)) {
151 1 pair_found = true;
152 1 u = n;
153
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 u_ns = n_ns;
154 1 break;
155 }
156
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 }
157
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1/2
✓ Decision 'true' taken 1 times.
✗ Decision 'false' not taken.
1 if (!pair_found) continue;
158 // Found a valid pair
159 // Identify the three sets from the neighbourhoods of `u` and `v`
160
2/4
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
1 ZXVertSeqSet excl_v{v_ns.begin(), v_ns.end()};
161
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 excl_v.erase(u);
162
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 ZXVertSeqSet excl_u, joint;
163 1 auto& lookup_v = excl_v.get<TagKey>();
164
2/2
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 1 times.
2/2
✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 1 times.
3 for (const ZXVert& nu : u_ns) {
165
3/6
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 2 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 2 times.
2 if (lookup_v.find(nu) != lookup_v.end())
166 joint.insert(nu);
167 else
168
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 excl_u.insert(nu);
169 }
170
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 excl_u.erase(v);
171
1/2
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
1 excl_v.erase(joint.begin(), joint.end());
172
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 const PhasedGen& v_spid = diag.get_vertex_ZXGen<PhasedGen>(v);
173
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 const PhasedGen& u_spid = diag.get_vertex_ZXGen<PhasedGen>(u);
174
175
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 add_phase_to_vertices(
176
5/10
✓ 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.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
2 diag, joint, v_spid.get_param() + u_spid.get_param() + 1.);
177
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 add_phase_to_vertices(diag, excl_u, v_spid.get_param());
178
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 add_phase_to_vertices(diag, excl_v, u_spid.get_param());
179
180 // Because `can_complement_neighbourhood` checks all neighbours,
181 // v and u have the same QuantumType
182
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 bipartite_complementation(diag, joint, excl_u, vqtype);
183
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 bipartite_complementation(diag, joint, excl_v, vqtype);
184
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 bipartite_complementation(diag, excl_u, excl_v, vqtype);
185
186
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 diag.remove_vertex(u);
187
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 diag.remove_vertex(v);
188
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 candidates.erase(u);
189 1 success = true;
190
3/4
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✓ Branch 8 taken 2 times.
3 }
191 1 return success;
192 1 }
193
194 1 Rewrite Rewrite::remove_interior_paulis() {
195
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 return Rewrite(remove_interior_paulis_fun);
196 }
197
198 1 bool Rewrite::extend_at_boundary_paulis_fun(ZXDiagram& diag) {
199
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1/2
✓ Decision 'true' taken 1 times.
✗ Decision 'false' not taken.
1 if (!diag.is_graphlike()) return false;
200 1 bool success = false;
201
3/4
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 10 taken 8 times.
✓ Branch 11 taken 1 times.
0/1
? Decision couldn't be analyzed.
9 for (const ZXVert& b : diag.get_boundary()) {
202 // Valid ZX graph requires boundaries to have a unique neighbour
203
2/4
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
8 Wire bw = diag.adj_wires(b).at(0);
204
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 ZXVert u = diag.other_end(bw, b);
205
3/4
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 2 times.
2/2
✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 8 times.
10 if (!diag.is_pauli_spider(u)) continue;
206 2 bool has_internal_pauli = false;
207
3/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 8 taken 6 times.
✓ Branch 9 taken 2 times.
0/1
? Decision couldn't be analyzed.
8 for (const ZXVert& w : diag.neighbours(u)) {
208
2/4
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 6 times.
6 if (!diag.is_pauli_spider(w)) continue;
209 bool interior = true;
210
0/1
? Decision couldn't be analyzed.
for (const ZXVert& wn : diag.neighbours(w)) {
211
0/2
✗ Decision 'true' not taken.
✗ Decision 'false' not taken.
if (is_boundary_type(diag.get_zxtype(wn))) {
212 interior = false;
213 break;
214 }
215 }
216
0/2
✗ Decision 'true' not taken.
✗ Decision 'false' not taken.
if (interior) {
217 has_internal_pauli = true;
218 break;
219 }
220 2 }
221
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 2 times.
2 if (!has_internal_pauli) continue;
222 // We would like to pivot about (`u`, `w`) but `u` is by a boundary, so we
223 // extend it
224 ZXGen_ptr u_op = diag.get_vertex_ZXGen_ptr(u);
225 QuantumType qtype = *u_op->get_qtype();
226 ZXGen_ptr id =
227 std::make_shared<const PhasedGen>(ZXType::ZSpider, 0., qtype);
228 ZXVert z1 = diag.add_vertex(id);
229 ZXVert z2 = diag.add_vertex(u_op);
230 diag.add_wire(u, z1, ZXWireType::H, qtype);
231 diag.add_wire(z1, z2, ZXWireType::H, qtype);
232 diag.add_wire(z2, b, ZXWireType::Basic, qtype);
233 diag.remove_wire(bw);
234 diag.set_vertex_ZXGen_ptr(u, id);
235 success = true;
236 1 }
237 1 return success;
238 }
239
240 1 Rewrite Rewrite::extend_at_boundary_paulis() {
241
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 return Rewrite(extend_at_boundary_paulis_fun);
242 }
243
244 } // namespace zx
245
246 } // namespace tket
247