GCC Code Coverage Report


Directory: ./
File: Transformations/SingleQubitSquash.cpp
Date: 2022-10-15 05:10:18
Warnings: 3 unchecked decisions!
Exec Total Coverage
Lines: 152 169 89.9%
Functions: 13 16 81.2%
Branches: 193 298 64.8%
Decisions: 43 52 82.7%

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 "SingleQubitSquash.hpp"
16
17 #include "Circuit/Circuit.hpp"
18 #include "Circuit/DAGDefs.hpp"
19 #include "Gate/Gate.hpp"
20
21 namespace tket {
22
23 10 SingleQubitSquash::SingleQubitSquash(const SingleQubitSquash &other)
24 10 : squasher_(other.squasher_->clone()),
25 10 circ_(other.circ_),
26 10 reversed_(other.reversed_) {}
27
28 SingleQubitSquash &SingleQubitSquash::operator=(
29 const SingleQubitSquash &other) {
30 squasher_ = other.squasher_->clone();
31 circ_ = other.circ_;
32 reversed_ = other.reversed_;
33 return *this;
34 }
35
36 SingleQubitSquash::SingleQubitSquash(SingleQubitSquash &&other)
37 : squasher_(std::move(other.squasher_)),
38 circ_(other.circ_),
39 reversed_(other.reversed_) {}
40
41 SingleQubitSquash &SingleQubitSquash::operator=(SingleQubitSquash &&other) {
42 squasher_ = std::move(other.squasher_);
43 circ_ = other.circ_;
44 reversed_ = other.reversed_;
45 return *this;
46 }
47
48 6370 bool SingleQubitSquash::squash() {
49 6370 bool success = false;
50
51
1/2
✓ Branch 1 taken 6370 times.
✗ Branch 2 not taken.
6370 VertexVec inputs = circ_.q_inputs();
52
1/2
✓ Branch 1 taken 6370 times.
✗ Branch 2 not taken.
6370 VertexVec outputs = circ_.q_outputs();
53
3/4
✓ Branch 1 taken 15798 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 9428 times.
✓ Branch 4 taken 6370 times.
0/1
? Decision couldn't be analyzed.
15798 for (unsigned i = 0; i < circ_.n_qubits(); ++i) {
54
1/2
✓ Branch 2 taken 9428 times.
✗ Branch 3 not taken.
9428 Edge in = circ_.get_nth_out_edge(inputs[i], 0);
55
1/2
✓ Branch 2 taken 9428 times.
✗ Branch 3 not taken.
9428 Edge out = circ_.get_nth_in_edge(outputs[i], 0);
56
2/2
✓ Branch 0 taken 9393 times.
✓ Branch 1 taken 35 times.
2/2
✓ Decision 'true' taken 9393 times.
✓ Decision 'false' taken 35 times.
9428 if (reversed_) {
57
1/2
✓ Branch 1 taken 9393 times.
✗ Branch 2 not taken.
9393 success |= squash_between(out, in);
58 } else {
59
1/2
✓ Branch 1 taken 35 times.
✗ Branch 2 not taken.
35 success |= squash_between(in, out);
60 }
61 }
62
63 6370 return success;
64 6370 }
65
66 9723 bool SingleQubitSquash::squash_between(const Edge &in, const Edge &out) {
67
1/2
✓ Branch 2 taken 9723 times.
✗ Branch 3 not taken.
9723 squasher_->clear();
68 9723 Edge e = in;
69
1/2
✓ Branch 1 taken 9723 times.
✗ Branch 2 not taken.
9723 Vertex v = next_vertex(e);
70 9723 std::vector<Gate_ptr> single_chain;
71 9723 VertexVec bin;
72 9723 bool success = false;
73 9723 Condition condition = std::nullopt;
74 while (true) {
75
1/2
✓ Branch 1 taken 256609 times.
✗ Branch 2 not taken.
256609 Op_ptr v_op = circ_.get_Op_ptr_from_Vertex(v);
76 256609 OpType v_type = v_op->get_type();
77 256609 bool move_to_next_vertex = false;
78 256609 bool reset_search = false;
79 256609 Condition this_condition = std::nullopt;
80
81
2/2
✓ Branch 0 taken 278 times.
✓ Branch 1 taken 256331 times.
2/2
✓ Decision 'true' taken 278 times.
✓ Decision 'false' taken 256331 times.
256609 if (v_type == OpType::Conditional) {
82 // => deal with conditional case
83
1/2
✓ Branch 1 taken 278 times.
✗ Branch 2 not taken.
278 this_condition = get_condition(v);
84
1/2
✓ Branch 2 taken 278 times.
✗ Branch 3 not taken.
278 v_op = static_cast<const Conditional &>(*v_op).get_op();
85 278 v_type = v_op->get_type();
86
87
2/2
✓ Branch 1 taken 230 times.
✓ Branch 2 taken 48 times.
2/2
✓ Decision 'true' taken 230 times.
✓ Decision 'false' taken 48 times.
278 if (single_chain.empty()) {
88
1/2
✓ Branch 1 taken 230 times.
✗ Branch 2 not taken.
230 condition = this_condition;
89 }
90 }
91
92 715947 bool is_squashable = circ_.n_in_edges_of_type(v, EdgeType::Quantum) == 1 &&
93
6/8
✓ Branch 1 taken 256609 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 202729 times.
✓ Branch 4 taken 53880 times.
✓ Branch 6 taken 202729 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 202488 times.
✓ Branch 9 taken 241 times.
459097 is_gate_type(v_type) &&
94
8/14
✓ Branch 3 taken 202488 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 202488 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 202228 times.
✓ Branch 9 taken 260 times.
✓ Branch 10 taken 202488 times.
✓ Branch 11 taken 54121 times.
✓ Branch 13 taken 202488 times.
✓ Branch 14 taken 54121 times.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
459097 squasher_->accepts(as_gate_ptr(v_op));
95
96
10/12
✓ Branch 1 taken 256609 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 247031 times.
✓ Branch 4 taken 9578 times.
✓ Branch 6 taken 247031 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 246992 times.
✓ Branch 9 taken 39 times.
✓ Branch 10 taken 202216 times.
✓ Branch 11 taken 44776 times.
✓ Branch 12 taken 202216 times.
✓ Branch 13 taken 54393 times.
2/2
✓ Decision 'true' taken 202216 times.
✓ Decision 'false' taken 54393 times.
256609 if (e != out && condition == this_condition && is_squashable) {
97 // => add gate to current squash
98
5/8
✓ Branch 1 taken 201648 times.
✓ Branch 2 taken 568 times.
✓ Branch 5 taken 201648 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 202216 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 202216 times.
✗ Branch 13 not taken.
202216 squasher_->append(as_gate_ptr(reversed_ ? v_op->dagger() : v_op));
99 202216 move_to_next_vertex = true;
100 } else {
101 // => squash and reset
102 54393 reset_search = true;
103
2/2
✓ Branch 1 taken 17044 times.
✓ Branch 2 taken 37349 times.
2/2
✓ Decision 'true' taken 17044 times.
✓ Decision 'false' taken 37349 times.
54393 if (single_chain.empty()) {
104 // => nothing to do, move on
105 17044 move_to_next_vertex = true;
106 } else {
107
1/2
✓ Branch 1 taken 37349 times.
✗ Branch 2 not taken.
37349 Circuit sub;
108 37349 std::optional<Pauli> commutation_colour = std::nullopt;
109
8/10
✓ Branch 1 taken 37349 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 28561 times.
✓ Branch 4 taken 8788 times.
✓ Branch 7 taken 28561 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 28518 times.
✓ Branch 10 taken 43 times.
✓ Branch 11 taken 28518 times.
✓ Branch 12 taken 8831 times.
2/2
✓ Decision 'true' taken 28518 times.
✓ Decision 'false' taken 8831 times.
37349 if (is_gate_type(v_type) && v_op->n_qubits() > 1) {
110 commutation_colour =
111
2/4
✓ Branch 1 taken 28518 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 28518 times.
✗ Branch 5 not taken.
28518 circ_.commuting_basis(v, PortType::Target, next_port(e));
112 28518 move_to_next_vertex = true;
113 }
114
1/2
✓ Branch 2 taken 37349 times.
✗ Branch 3 not taken.
37349 auto pair = squasher_->flush(commutation_colour);
115
1/2
✓ Branch 1 taken 37349 times.
✗ Branch 2 not taken.
37349 sub = pair.first;
116 37349 Gate_ptr left_over_gate = pair.second;
117
2/2
✓ Branch 1 taken 161 times.
✓ Branch 2 taken 37188 times.
2/2
✓ Decision 'true' taken 161 times.
✓ Decision 'false' taken 37188 times.
37349 if (left_over_gate != nullptr) {
118 // => commute leftover through before squashing
119
2/4
✓ Branch 1 taken 161 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 161 times.
✗ Branch 6 not taken.
161 insert_left_over_gate(left_over_gate, next_edge(v, e), condition);
120 161 left_over_gate = nullptr;
121 }
122
2/2
✓ Branch 0 taken 37049 times.
✓ Branch 1 taken 300 times.
2/2
✓ Decision 'true' taken 37049 times.
✓ Decision 'false' taken 300 times.
37349 if (reversed_) {
123
2/4
✓ Branch 1 taken 37049 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 37049 times.
✗ Branch 5 not taken.
37049 sub = sub.dagger();
124 }
125
126 // we squash if the replacement is at least as good as the original
127 // (and it's not a no-op)
128
4/6
✓ Branch 1 taken 37349 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 37349 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 29483 times.
✓ Branch 8 taken 7866 times.
2/2
✓ Decision 'true' taken 29483 times.
✓ Decision 'false' taken 7866 times.
37349 if (sub_is_better(sub, single_chain)) {
129
1/2
✓ Branch 1 taken 29483 times.
✗ Branch 2 not taken.
29483 substitute(sub, bin, e, condition);
130 29483 success = true;
131 }
132 37349 }
133 }
134
8/10
✓ Branch 1 taken 256609 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 253807 times.
✓ Branch 4 taken 2802 times.
✓ Branch 6 taken 253807 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 6921 times.
✓ Branch 9 taken 246886 times.
✓ Branch 10 taken 9723 times.
✓ Branch 11 taken 246886 times.
2/2
✓ Decision 'true' taken 9723 times.
✓ Decision 'false' taken 246886 times.
256609 if (e == out || is_last_optype(v_type)) {
135
1/2
✓ Branch 2 taken 9723 times.
✗ Branch 3 not taken.
9723 squasher_->clear();
136 9723 break;
137 }
138
2/2
✓ Branch 0 taken 246839 times.
✓ Branch 1 taken 47 times.
2/2
✓ Decision 'true' taken 246839 times.
✓ Decision 'false' taken 47 times.
246886 if (move_to_next_vertex) {
139
3/4
✓ Branch 1 taken 246839 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 246835 times.
✓ Branch 4 taken 4 times.
2/2
✓ Decision 'true' taken 246835 times.
✓ Decision 'false' taken 4 times.
246839 if (is_gate_type(v_type)) {
140
1/2
✓ Branch 1 taken 246835 times.
✗ Branch 2 not taken.
246835 bin.push_back(v);
141
2/4
✓ Branch 2 taken 246835 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 246835 times.
✗ Branch 6 not taken.
246835 single_chain.push_back(as_gate_ptr(v_op));
142 }
143
1/2
✓ Branch 1 taken 246839 times.
✗ Branch 2 not taken.
246839 e = next_edge(v, e);
144
1/2
✓ Branch 1 taken 246839 times.
✗ Branch 2 not taken.
246839 v = next_vertex(e);
145 }
146
2/2
✓ Branch 0 taken 44670 times.
✓ Branch 1 taken 202216 times.
2/2
✓ Decision 'true' taken 44670 times.
✓ Decision 'false' taken 202216 times.
246886 if (reset_search) {
147 44670 bin.clear();
148 44670 single_chain.clear();
149
1/2
✓ Branch 2 taken 44670 times.
✗ Branch 3 not taken.
44670 squasher_->clear();
150 44670 condition = std::nullopt;
151 }
152
4/4
✓ Branch 1 taken 246886 times.
✓ Branch 2 taken 9723 times.
✓ Branch 4 taken 246886 times.
✓ Branch 5 taken 9723 times.
513218 }
153 9723 return success;
154 9723 }
155
156 29483 void SingleQubitSquash::substitute(
157 const Circuit &sub, const VertexVec &single_chain, Edge &e,
158 const Condition &condition) {
159 // backup edge
160
2/4
✓ Branch 1 taken 29483 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 29483 times.
✗ Branch 5 not taken.
29483 VertPort backup = {next_vertex(e), next_port(e)};
161
162
2/2
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 29473 times.
2/2
✓ Decision 'true' taken 10 times.
✓ Decision 'false' taken 29473 times.
29483 if (condition) {
163
2/4
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
10 circ_.substitute_conditional(
164 10 sub, single_chain.front(), Circuit::VertexDeletion::No);
165 } else {
166
1/2
✓ Branch 2 taken 29473 times.
✗ Branch 3 not taken.
29473 circ_.substitute(sub, single_chain.front(), Circuit::VertexDeletion::No);
167 }
168
1/2
✓ Branch 1 taken 29483 times.
✗ Branch 2 not taken.
29483 circ_.remove_vertices(
169
1/2
✓ Branch 4 taken 29483 times.
✗ Branch 5 not taken.
58966 VertexSet{single_chain.begin(), single_chain.end()},
170 Circuit::GraphRewiring::Yes, Circuit::VertexDeletion::Yes);
171
172 // restore backup
173
1/2
✓ Branch 1 taken 29483 times.
✗ Branch 2 not taken.
29483 e = prev_edge(backup);
174 29483 }
175
176 161 void SingleQubitSquash::insert_left_over_gate(
177 Op_ptr left_over, const Edge &e, const Condition &condition) {
178
2/2
✓ Branch 0 taken 148 times.
✓ Branch 1 taken 13 times.
2/2
✓ Decision 'true' taken 148 times.
✓ Decision 'false' taken 13 times.
161 if (reversed_) {
179
1/2
✓ Branch 2 taken 148 times.
✗ Branch 3 not taken.
148 left_over = left_over->dagger();
180 }
181 161 EdgeVec preds;
182 161 op_signature_t sigs;
183
2/2
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 156 times.
2/2
✓ Decision 'true' taken 5 times.
✓ Decision 'false' taken 156 times.
161 if (condition) {
184 5 left_over = std::make_shared<Conditional>(
185
1/2
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
10 left_over, (unsigned)condition->first.size(), condition->second);
186 }
187
1/2
✓ Branch 3 taken 161 times.
✗ Branch 4 not taken.
161 Vertex new_v = circ_.add_vertex(left_over);
188
2/2
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 156 times.
2/2
✓ Decision 'true' taken 10 times.
✓ Decision 'false' taken 151 times.
161 if (condition) {
189
2/2
✓ Branch 5 taken 5 times.
✓ Branch 6 taken 5 times.
2/2
✓ Decision 'true' taken 5 times.
✓ Decision 'false' taken 5 times.
10 for (const VertPort &vp : condition->first) {
190
2/4
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
5 preds.push_back(circ_.get_nth_out_edge(vp.first, vp.second));
191
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 sigs.push_back(EdgeType::Boolean);
192 }
193 }
194
1/2
✓ Branch 1 taken 161 times.
✗ Branch 2 not taken.
161 preds.push_back(e);
195
1/2
✓ Branch 1 taken 161 times.
✗ Branch 2 not taken.
161 sigs.push_back(EdgeType::Quantum);
196
1/2
✓ Branch 1 taken 161 times.
✗ Branch 2 not taken.
161 circ_.rewire(new_v, preds, sigs);
197 161 }
198
199 37349 bool SingleQubitSquash::sub_is_better(
200 const Circuit &sub, const std::vector<Gate_ptr> chain) const {
201 37349 const unsigned n_gates = sub.n_gates();
202
4/4
✓ Branch 1 taken 7961 times.
✓ Branch 2 taken 29388 times.
✓ Branch 3 taken 7893 times.
✓ Branch 4 taken 68 times.
53203 return n_gates < chain.size() ||
203
2/2
✓ Branch 2 taken 95 times.
✓ Branch 3 taken 7798 times.
53203 (n_gates == chain.size() && !is_equal(sub, chain, reversed_));
204 }
205
206 // returns a description of the condition of current vertex
207 278 SingleQubitSquash::Condition SingleQubitSquash::get_condition(Vertex v) const {
208
1/2
✓ Branch 1 taken 278 times.
✗ Branch 2 not taken.
278 Op_ptr v_op = circ_.get_Op_ptr_from_Vertex(v);
209 278 OpType v_type = v_op->get_type();
210
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 278 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 278 times.
278 if (v_type != OpType::Conditional) {
211 throw BadOpType("Cannot get condition from non-conditional OpType", v_type);
212 }
213 278 const Conditional &cond_op = static_cast<const Conditional &>(*v_op);
214
1/2
✓ Branch 1 taken 278 times.
✗ Branch 2 not taken.
278 EdgeVec ins = circ_.get_in_edges(v);
215 278 Condition cond = std::pair<std::list<VertPort>, unsigned>();
216
3/4
✓ Branch 1 taken 664 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 386 times.
✓ Branch 4 taken 278 times.
0/1
? Decision couldn't be analyzed.
664 for (port_t p = 0; p < cond_op.get_width(); ++p) {
217
1/2
✓ Branch 1 taken 386 times.
✗ Branch 2 not taken.
386 Edge in_p = ins.at(p);
218
2/4
✓ Branch 1 taken 386 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 386 times.
✗ Branch 5 not taken.
386 VertPort vp = {circ_.source(in_p), circ_.get_source_port(in_p)};
219
1/2
✓ Branch 2 taken 386 times.
✗ Branch 3 not taken.
386 cond->first.push_back(vp);
220 }
221
1/2
✓ Branch 1 taken 278 times.
✗ Branch 2 not taken.
278 cond->second = cond_op.get_value();
222 556 return cond;
223 278 }
224
225 // simple utils respecting reversed boolean
226 286045 Vertex SingleQubitSquash::next_vertex(const Edge &e) const {
227
2/2
✓ Branch 0 taken 284938 times.
✓ Branch 1 taken 1107 times.
286045 return reversed_ ? circ_.source(e) : circ_.target(e);
228 }
229
230 58001 port_t SingleQubitSquash::next_port(const Edge &e) const {
231
2/2
✓ Branch 0 taken 57774 times.
✓ Branch 1 taken 227 times.
58001 return reversed_ ? circ_.get_source_port(e) : circ_.get_target_port(e);
232 }
233
234 29483 Edge SingleQubitSquash::prev_edge(const VertPort &pair) const {
235 29376 return reversed_ ? circ_.get_nth_out_edge(pair.first, pair.second)
236
2/2
✓ Branch 0 taken 29376 times.
✓ Branch 1 taken 107 times.
29483 : circ_.get_nth_in_edge(pair.first, pair.second);
237 }
238
239 247000 Edge SingleQubitSquash::next_edge(const Vertex &v, const Edge &e) const {
240
2/2
✓ Branch 0 taken 246317 times.
✓ Branch 1 taken 683 times.
247000 return reversed_ ? circ_.get_last_edge(v, e) : circ_.get_next_edge(v, e);
241 }
242
243 253807 bool SingleQubitSquash::is_last_optype(OpType type) const {
244
4/4
✓ Branch 0 taken 253084 times.
✓ Branch 1 taken 723 times.
✓ Branch 3 taken 246207 times.
✓ Branch 4 taken 6877 times.
500737 return (reversed_ && is_initial_q_type(type)) ||
245
4/4
✓ Branch 0 taken 723 times.
✓ Branch 1 taken 246207 times.
✓ Branch 3 taken 44 times.
✓ Branch 4 taken 679 times.
500737 (!reversed_ && is_final_q_type(type));
246 }
247
248 15634 bool SingleQubitSquash::is_equal(
249 const Circuit &circ, const std::vector<Gate_ptr> &gates, bool reversed) {
250
2/2
✓ Branch 0 taken 7741 times.
✓ Branch 1 taken 7893 times.
2/2
✓ Decision 'true' taken 7741 times.
✓ Decision 'false' taken 7893 times.
15634 if (reversed) {
251
2/4
✓ Branch 4 taken 7741 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 7741 times.
✗ Branch 8 not taken.
7741 return is_equal(circ, {gates.rbegin(), gates.rend()});
252 }
253
2/4
✓ Branch 1 taken 7893 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 7893 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 7893 times.
7893 if (circ.n_qubits() != 1) {
254 throw CircuitInvalidity("Only circuits with one qubit are supported");
255 }
256
257
1/2
✓ Branch 1 taken 7893 times.
✗ Branch 2 not taken.
7893 auto it1 = circ.begin();
258 7893 auto it2 = gates.cbegin();
259
260
7/12
✓ Branch 1 taken 26280 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 18482 times.
✓ Branch 5 taken 7798 times.
✓ Branch 8 taken 18482 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 26280 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 18482 times.
✓ Branch 14 taken 7798 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
0/1
? Decision couldn't be analyzed.
26280 while (it1 != circ.end() && it2 != gates.end()) {
261
1/2
✓ Branch 3 taken 18482 times.
✗ Branch 4 not taken.
18482 const Gate_ptr op1 = as_gate_ptr(it1->get_op_ptr());
262
1/2
✓ Branch 3 taken 18482 times.
✗ Branch 4 not taken.
18482 const Gate_ptr op2 = as_gate_ptr(*it2);
263
3/4
✓ Branch 3 taken 18482 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 95 times.
✓ Branch 6 taken 18387 times.
2/2
✓ Decision 'true' taken 95 times.
✓ Decision 'false' taken 18387 times.
18482 if (!(*op1 == *op2)) {
264 95 return false;
265 }
266
1/2
✓ Branch 1 taken 18387 times.
✗ Branch 2 not taken.
18387 ++it1;
267 18387 ++it2;
268
4/4
✓ Branch 1 taken 18387 times.
✓ Branch 2 taken 95 times.
✓ Branch 4 taken 18387 times.
✓ Branch 5 taken 95 times.
18577 }
269
270
5/12
✓ Branch 1 taken 7798 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7798 times.
✗ Branch 5 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 7798 times.
✓ Branch 10 taken 7798 times.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✓ Branch 14 taken 7798 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 7798 times.
7798 if (it1 != circ.end() || it2 != gates.cend()) {
271 return false;
272 }
273 7798 return true;
274 7893 }
275
276 } // namespace tket
277