GCC Code Coverage Report


Directory: ./
File: Predicates/Predicates.cpp
Date: 2022-10-15 05:10:18
Warnings: 21 unchecked decisions!
Exec Total Coverage
Lines: 373 512 72.9%
Functions: 42 119 35.3%
Branches: 556 1012 54.9%
Decisions: 144 208 69.2%

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 "Predicates.hpp"
16
17 #include "Gate/Gate.hpp"
18 #include "Mapping/Verification.hpp"
19 #include "OpType/OpTypeFunctions.hpp"
20 #include "Placement/Placement.hpp"
21 #include "Utils/MatrixAnalysis.hpp"
22 #include "Utils/UnitID.hpp"
23
24 namespace tket {
25
26 template <typename T>
27 204 static bool auto_implication(const T&, const Predicate& other) {
28 try {
29
2/2
✓ Branch 0 taken 101 times.
✓ Branch 1 taken 1 times.
204 (void)dynamic_cast<const T&>(other);
30
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
4 } catch (const std::bad_cast&) {
31
2/4
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
2 throw IncorrectPredicate(
32 "Cannot compare predicates of different subclasses");
33 }
34 202 return true;
35 }
36
37 template <typename T>
38 40 static PredicatePtr auto_meet(const T&, const Predicate& other) {
39 try {
40
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
40 (void)dynamic_cast<const T&>(other);
41
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
40 PredicatePtr pp = std::make_shared<T>();
42 80 return pp;
43
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
40 } catch (const std::bad_cast&) {
44 throw IncorrectPredicate(
45 "Cannot compare predicates of different subclasses");
46 }
47 }
48
49 template <typename T>
50 8 static std::string auto_name(const T&) {
51
2/4
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
16 return predicate_name(typeid(T));
52 }
53
54 10 const std::string& predicate_name(std::type_index idx) {
55 static const std::map<std::type_index, std::string> predicate_names = {
56 #define SET_PRED_NAME(a) {typeid(a), #a}
57 SET_PRED_NAME(CliffordCircuitPredicate),
58 SET_PRED_NAME(ConnectivityPredicate),
59 SET_PRED_NAME(DefaultRegisterPredicate),
60 SET_PRED_NAME(DirectednessPredicate),
61 SET_PRED_NAME(GateSetPredicate),
62 SET_PRED_NAME(MaxNQubitsPredicate),
63 SET_PRED_NAME(MaxTwoQubitGatesPredicate),
64 SET_PRED_NAME(NoBarriersPredicate),
65 SET_PRED_NAME(NoClassicalBitsPredicate),
66 SET_PRED_NAME(NoClassicalControlPredicate),
67 SET_PRED_NAME(NoFastFeedforwardPredicate),
68 SET_PRED_NAME(NoMidMeasurePredicate),
69 SET_PRED_NAME(NoSymbolsPredicate),
70 SET_PRED_NAME(GlobalPhasedXPredicate),
71 SET_PRED_NAME(NormalisedTK2Predicate),
72 SET_PRED_NAME(NoWireSwapsPredicate),
73 SET_PRED_NAME(PlacementPredicate),
74
24/48
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 9 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 1 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 22 not taken.
✓ Branch 24 taken 1 times.
✗ Branch 25 not taken.
✓ Branch 27 taken 1 times.
✗ Branch 28 not taken.
✓ Branch 30 taken 1 times.
✗ Branch 31 not taken.
✓ Branch 33 taken 1 times.
✗ Branch 34 not taken.
✓ Branch 36 taken 1 times.
✗ Branch 37 not taken.
✓ Branch 39 taken 1 times.
✗ Branch 40 not taken.
✓ Branch 42 taken 1 times.
✗ Branch 43 not taken.
✓ Branch 45 taken 1 times.
✗ Branch 46 not taken.
✓ Branch 48 taken 1 times.
✗ Branch 49 not taken.
✓ Branch 51 taken 1 times.
✗ Branch 52 not taken.
✓ Branch 54 taken 1 times.
✗ Branch 55 not taken.
✓ Branch 57 taken 1 times.
✗ Branch 58 not taken.
✓ Branch 61 taken 1 times.
✗ Branch 62 not taken.
✓ Branch 66 taken 18 times.
✓ Branch 67 taken 1 times.
✗ Branch 70 not taken.
✗ Branch 71 not taken.
✗ Branch 73 not taken.
✗ Branch 74 not taken.
28 SET_PRED_NAME(UserDefinedPredicate)};
75 #undef SET_PRED_NAME
76 10 return predicate_names.at(idx);
77 }
78
79 /////////////////////
80 // PREDICATE METHODS//
81 /////////////////////
82
83 60 bool GateSetPredicate::verify(const Circuit& circ) const {
84
7/8
✓ Branch 1 taken 60 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 1544 times.
✓ Branch 6 taken 42 times.
✓ Branch 8 taken 1544 times.
✓ Branch 9 taken 42 times.
✓ Branch 11 taken 60 times.
✓ Branch 12 taken 42 times.
1628 BGL_FORALL_VERTICES(v, circ.dag, DAG) {
85
1/2
✓ Branch 1 taken 1544 times.
✗ Branch 2 not taken.
1544 Op_ptr op = circ.get_Op_ptr_from_Vertex(v);
86
1/2
✓ Branch 2 taken 1544 times.
✗ Branch 3 not taken.
1544 OpDesc desc = op->get_desc();
87
3/4
✓ Branch 1 taken 1544 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 402 times.
✓ Branch 4 taken 1142 times.
2/2
✓ Decision 'true' taken 1142 times.
✓ Decision 'false' taken 402 times.
1544 if (desc.is_meta()) continue;
88 1142 OpType type = op->get_type();
89
2/2
✓ Branch 0 taken 256 times.
✓ Branch 1 taken 886 times.
2/2
✓ Decision 'true' taken 256 times.
✓ Decision 'false' taken 886 times.
1142 if (type == OpType::Conditional) {
90 256 const Conditional& cond = static_cast<const Conditional&>(*op);
91
1/2
✓ Branch 1 taken 256 times.
✗ Branch 2 not taken.
256 type = cond.get_op()->get_type();
92 }
93
3/4
✓ Branch 1 taken 1142 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 18 times.
✓ Branch 4 taken 1124 times.
0/1
? Decision couldn't be analyzed.
1142 if (!find_in_set(type, allowed_types_)) return false;
94
6/6
✓ Branch 1 taken 1124 times.
✓ Branch 2 taken 402 times.
✓ Branch 3 taken 18 times.
✓ Branch 5 taken 1124 times.
✓ Branch 6 taken 402 times.
✓ Branch 7 taken 18 times.
1964 }
95 42 return true;
96 }
97
98 23 bool GateSetPredicate::implies(const Predicate& other) const {
99 try {
100 const GateSetPredicate& other_p =
101
1/2
✓ Branch 0 taken 23 times.
✗ Branch 1 not taken.
23 dynamic_cast<const GateSetPredicate&>(other);
102
2/2
✓ Branch 5 taken 223 times.
✓ Branch 6 taken 16 times.
2/2
✓ Decision 'true' taken 223 times.
✓ Decision 'false' taken 16 times.
239 for (const OpType& ot : allowed_types_) {
103
3/4
✓ Branch 2 taken 223 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 7 times.
✓ Branch 6 taken 216 times.
2/2
✓ Decision 'true' taken 7 times.
✓ Decision 'false' taken 216 times.
223 if (other_p.allowed_types_.find(ot) == other_p.allowed_types_.end())
104 7 return false;
105 }
106 16 return true;
107 } catch (const std::bad_cast&) {
108 throw IncorrectPredicate(
109 "Cannot compare predicates of different subclasses");
110 }
111 }
112
113 PredicatePtr GateSetPredicate::meet(const Predicate& other) const {
114 try {
115 const GateSetPredicate& other_p =
116 dynamic_cast<const GateSetPredicate&>(other);
117 OpTypeSet new_set;
118
0/2
✗ Decision 'true' not taken.
✗ Decision 'false' not taken.
for (const OpType& ot : allowed_types_) {
119
0/2
✗ Decision 'true' not taken.
✗ Decision 'false' not taken.
if (other_p.allowed_types_.find(ot) != other_p.allowed_types_.end()) {
120 new_set.insert(ot);
121 }
122 }
123 PredicatePtr pp = std::make_shared<GateSetPredicate>(new_set);
124 return pp;
125 } catch (const std::bad_cast&) {
126 throw IncorrectPredicate(
127 "Cannot compare predicates of different subclasses");
128 }
129 }
130
131 3 std::string GateSetPredicate::to_string() const {
132
1/2
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
3 std::string str = auto_name(*this) + ":{ ";
133
2/2
✓ Branch 4 taken 35 times.
✓ Branch 5 taken 3 times.
2/2
✓ Decision 'true' taken 35 times.
✓ Decision 'false' taken 3 times.
38 for (const OpType& ot : allowed_types_) {
134
4/8
✓ Branch 1 taken 35 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 35 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 35 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 35 times.
✗ Branch 12 not taken.
35 str += (optypeinfo().find(ot)->second.name + " ");
135 }
136
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 str += "}";
137 3 return str;
138 }
139
140 45 bool NoClassicalControlPredicate::verify(const Circuit& circ) const {
141
7/8
✓ Branch 1 taken 45 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 1060 times.
✓ Branch 6 taken 41 times.
✓ Branch 8 taken 1060 times.
✓ Branch 9 taken 41 times.
✓ Branch 11 taken 45 times.
✓ Branch 12 taken 41 times.
1142 BGL_FORALL_VERTICES(v, circ.dag, DAG) {
142
1/2
✓ Branch 1 taken 1060 times.
✗ Branch 2 not taken.
1060 Op_ptr op = circ.get_Op_ptr_from_Vertex(v);
143 1060 OpType ot = op->get_type();
144
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1057 times.
2/2
✓ Decision 'true' taken 3 times.
✓ Decision 'false' taken 1057 times.
1060 if (ot == OpType::Conditional)
145 3 return false;
146
3/4
✓ Branch 0 taken 1055 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1055 times.
2/2
✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 1055 times.
1057 else if (ot == OpType::CircBox || ot == OpType::CustomGate) {
147 2 const Box& box = static_cast<const Box&>(*op);
148
4/6
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
✓ Branch 9 taken 1 times.
0/1
? Decision couldn't be analyzed.
2 if (!verify(*box.to_circuit())) return false;
149 }
150
2/2
✓ Branch 1 taken 1056 times.
✓ Branch 2 taken 4 times.
1060 }
151 41 return true;
152 }
153
154 3 bool NoClassicalControlPredicate::implies(const Predicate& other) const {
155 3 return auto_implication(*this, other);
156 }
157
158 1 PredicatePtr NoClassicalControlPredicate::meet(const Predicate& other) const {
159 1 return auto_meet(*this, other);
160 }
161
162 1 std::string NoClassicalControlPredicate::to_string() const {
163 1 return auto_name(*this);
164 }
165
166 41 static bool fast_feed_forward_helper(
167 const Command& com, unit_set_t& unset_bits) {
168 // Allows conditionals from unset_bits
169 // Encountering a measurement removed the bits from unset_bits
170 // Returns whether or not a feed-forward conditional is found
171 // Applies recursively for CircBoxes
172
2/2
✓ Branch 4 taken 17 times.
✓ Branch 5 taken 24 times.
2/2
✓ Decision 'true' taken 17 times.
✓ Decision 'false' taken 24 times.
41 if (com.get_op_ptr()->get_type() == OpType::Conditional) {
173 const Conditional& cond =
174 17 static_cast<const Conditional&>(*com.get_op_ptr());
175
1/2
✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
17 unit_vector_t all_args = com.get_args();
176 17 unit_vector_t::iterator arg_it = all_args.begin();
177
3/4
✓ Branch 1 taken 31 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 17 times.
✓ Branch 4 taken 14 times.
0/1
? Decision couldn't be analyzed.
31 for (unsigned i = 0; i < cond.get_width(); ++i) {
178
3/4
✓ Branch 3 taken 17 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 3 times.
✓ Branch 7 taken 14 times.
2/2
✓ Decision 'true' taken 14 times.
✓ Decision 'false' taken 3 times.
17 if (unset_bits.find(*arg_it) == unset_bits.end()) return false;
179 14 ++arg_it;
180 }
181
1/2
✓ Branch 3 taken 14 times.
✗ Branch 4 not taken.
14 unit_vector_t new_args = {arg_it, all_args.end()};
182
4/8
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 14 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 14 times.
✗ Branch 12 not taken.
28 Command new_com = {cond.get_op(), new_args};
183
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 return fast_feed_forward_helper(new_com, unset_bits);
184 17 } else if (
185
5/6
✓ Branch 3 taken 20 times.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 20 times.
✓ Branch 8 taken 4 times.
✓ Branch 9 taken 20 times.
68 com.get_op_ptr()->get_type() == OpType::CircBox ||
186
3/4
✓ Branch 3 taken 20 times.
✓ Branch 4 taken 4 times.
✓ Branch 6 taken 24 times.
✗ Branch 7 not taken.
44 com.get_op_ptr()->get_type() == OpType::CustomGate) {
187 4 const Box& box = static_cast<const Box&>(*com.get_op_ptr());
188 4 unit_map_t interface;
189 4 unit_set_t inner_set;
190 4 unsigned i = 0;
191
3/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 8 taken 4 times.
✓ Branch 9 taken 4 times.
0/1
? Decision couldn't be analyzed.
8 for (const Bit& b : com.get_bits()) {
192
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 Bit inner_bit(i);
193
2/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
4 interface.insert({Bit(i), b});
194
3/4
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 3 times.
✓ Branch 6 taken 1 times.
2/2
✓ Decision 'true' taken 3 times.
✓ Decision 'false' taken 1 times.
4 if (unset_bits.find(b) != unset_bits.end()) {
195
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 inner_set.insert(inner_bit);
196 }
197 4 ++i;
198 8 }
199
7/12
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 4 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 4 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 3 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 4 times.
✓ Branch 19 taken 3 times.
0/1
? Decision couldn't be analyzed.
7 for (const Command& c : *box.to_circuit()) {
200
3/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 3 times.
0/1
? Decision couldn't be analyzed.
4 if (!fast_feed_forward_helper(c, inner_set)) return false;
201
6/6
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 1 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 1 times.
✓ Branch 7 taken 3 times.
✓ Branch 8 taken 1 times.
9 }
202
2/2
✓ Branch 5 taken 3 times.
✓ Branch 6 taken 3 times.
2/2
✓ Decision 'true' taken 3 times.
✓ Decision 'false' taken 3 times.
6 for (const std::pair<const UnitID, UnitID>& pair : interface) {
203
3/4
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 1 times.
2/2
✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 1 times.
3 if (inner_set.find(pair.first) == inner_set.end())
204
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 unset_bits.erase(pair.second);
205 }
206
6/6
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 1 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 1 times.
✓ Branch 10 taken 6 times.
✓ Branch 11 taken 14 times.
2/2
✓ Decision 'true' taken 6 times.
✓ Decision 'false' taken 19 times.
25 } else if (com.get_op_ptr()->get_type() == OpType::Measure) {
207
2/4
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 6 times.
✗ Branch 6 not taken.
6 unset_bits.erase(com.get_args().at(1));
208 }
209 23 return true;
210 }
211
212 6 bool NoFastFeedforwardPredicate::verify(const Circuit& circ) const {
213
2/4
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
1/2
✓ Decision 'true' taken 6 times.
✗ Decision 'false' not taken.
6 if (circ.n_bits() == 0) return true;
214
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 bit_vector_t all_bits = circ.all_bits();
215
1/2
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
6 unit_set_t unset_bits = {all_bits.begin(), all_bits.end()};
216
6/10
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 23 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 20 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 23 times.
✓ Branch 14 taken 3 times.
0/1
? Decision couldn't be analyzed.
26 for (const Command& com : circ) {
217
3/4
✓ Branch 1 taken 23 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 20 times.
0/1
? Decision couldn't be analyzed.
23 if (!fast_feed_forward_helper(com, unset_bits)) return false;
218
6/6
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 3 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 3 times.
✓ Branch 7 taken 3 times.
✓ Branch 8 taken 3 times.
32 }
219 3 return true;
220 6 }
221
222 bool NoFastFeedforwardPredicate::implies(const Predicate& other) const {
223 return auto_implication(*this, other);
224 }
225
226 PredicatePtr NoFastFeedforwardPredicate::meet(const Predicate& other) const {
227 return auto_meet(*this, other);
228 }
229
230 std::string NoFastFeedforwardPredicate::to_string() const {
231 return auto_name(*this);
232 }
233
234 2 bool NoClassicalBitsPredicate::verify(const Circuit& circ) const {
235 // for classical edges, we currently require classical input
236 2 return (circ.n_bits() == 0);
237 }
238
239 bool NoClassicalBitsPredicate::implies(const Predicate& other) const {
240 return auto_implication(*this, other);
241 }
242
243 PredicatePtr NoClassicalBitsPredicate::meet(const Predicate& other) const {
244 return auto_meet(*this, other);
245 }
246
247 std::string NoClassicalBitsPredicate::to_string() const {
248 return auto_name(*this);
249 }
250
251 28 bool NoWireSwapsPredicate::verify(const Circuit& circ) const {
252
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 std::map<UnitID, QPathDetailed> paths = circ.all_unit_paths();
253
2/2
✓ Branch 5 taken 113 times.
✓ Branch 6 taken 22 times.
2/2
✓ Decision 'true' taken 113 times.
✓ Decision 'false' taken 22 times.
135 for (const std::pair<const UnitID, QPathDetailed>& path : paths) {
254
1/2
✓ Branch 2 taken 113 times.
✗ Branch 3 not taken.
113 UnitID out_id = circ.get_id_from_out(path.second.back().first);
255
3/4
✓ Branch 1 taken 113 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 107 times.
1/2
✓ Decision 'true' taken 113 times.
✗ Decision 'false' not taken.
113 if (path.first != out_id) return false;
256
2/2
✓ Branch 1 taken 107 times.
✓ Branch 2 taken 6 times.
113 }
257 22 return true;
258 28 }
259
260 60 bool NoWireSwapsPredicate::implies(const Predicate& other) const {
261 60 return auto_implication(*this, other);
262 }
263
264 PredicatePtr NoWireSwapsPredicate::meet(const Predicate& other) const {
265 return auto_meet(*this, other);
266 }
267
268 std::string NoWireSwapsPredicate::to_string() const { return auto_name(*this); }
269
270 46 bool MaxTwoQubitGatesPredicate::verify(const Circuit& circ) const {
271
7/8
✓ Branch 1 taken 46 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 6756 times.
✓ Branch 6 taken 45 times.
✓ Branch 8 taken 6756 times.
✓ Branch 9 taken 45 times.
✓ Branch 11 taken 46 times.
✓ Branch 12 taken 45 times.
6846 BGL_FORALL_VERTICES(v, circ.dag, DAG) {
272
2/4
✓ Branch 1 taken 6756 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 6756 times.
1/2
✓ Decision 'true' taken 6756 times.
✗ Decision 'false' not taken.
6756 if (circ.get_OpType_from_Vertex(v) == OpType::Barrier) continue;
273
3/4
✓ Branch 1 taken 6756 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 6755 times.
2/2
✓ Decision 'true' taken 45 times.
✓ Decision 'false' taken 6711 times.
6756 if (circ.n_in_edges_of_type(v, EdgeType::Quantum) > 2) return false;
274 }
275 45 return true;
276 }
277
278 39 bool MaxTwoQubitGatesPredicate::implies(const Predicate& other) const {
279 39 return auto_implication(*this, other);
280 }
281
282 19 PredicatePtr MaxTwoQubitGatesPredicate::meet(const Predicate& other) const {
283 19 return auto_meet(*this, other);
284 }
285
286 std::string MaxTwoQubitGatesPredicate::to_string() const {
287 return auto_name(*this);
288 }
289
290 14 bool PlacementPredicate::verify(const Circuit& circ) const {
291
3/4
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 8 taken 62 times.
✓ Branch 9 taken 10 times.
0/1
? Decision couldn't be analyzed.
72 for (const Qubit& qb : circ.all_qubits()) {
292
4/6
✓ Branch 1 taken 62 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 62 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 12 times.
✓ Branch 9 taken 50 times.
2/2
✓ Decision 'true' taken 50 times.
✓ Decision 'false' taken 12 times.
62 if (qb.reg_name() == Placement::unplaced_reg()) continue;
293
4/6
✓ Branch 2 taken 50 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 50 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 4 times.
✓ Branch 10 taken 46 times.
2/2
✓ Decision 'true' taken 14 times.
✓ Decision 'false' taken 36 times.
50 if (nodes_.find(Node(qb)) == nodes_.end()) return false;
294
2/2
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 4 times.
14 }
295 10 return true;
296 }
297
298 26 bool PlacementPredicate::implies(const Predicate& other) const {
299 const PlacementPredicate other_p =
300
2/4
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
✓ Branch 4 taken 26 times.
✗ Branch 5 not taken.
26 dynamic_cast<const PlacementPredicate&>(other);
301
2/2
✓ Branch 5 taken 96 times.
✓ Branch 6 taken 26 times.
2/2
✓ Decision 'true' taken 96 times.
✓ Decision 'false' taken 26 times.
122 for (const Node& node : nodes_) {
302
2/4
✓ Branch 2 taken 96 times.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 96 times.
2/2
✓ Decision 'true' taken 26 times.
✓ Decision 'false' taken 70 times.
96 if (other_p.nodes_.find(node) == other_p.nodes_.end()) return false;
303 }
304 26 return true;
305 26 }
306
307 PredicatePtr PlacementPredicate::meet(const Predicate& other) const {
308 try {
309 const PlacementPredicate& other_c =
310 dynamic_cast<const PlacementPredicate&>(other);
311 node_set_t nodes;
312
0/2
✗ Decision 'true' not taken.
✗ Decision 'false' not taken.
for (const Node& node : nodes_) {
313
0/2
✗ Decision 'true' not taken.
✗ Decision 'false' not taken.
if (other_c.nodes_.find(node) != other_c.nodes_.end()) nodes.insert(node);
314 }
315 PredicatePtr pp = std::make_shared<PlacementPredicate>(nodes);
316 return pp;
317 } catch (const std::bad_cast&) {
318 throw IncorrectPredicate(
319 "Cannot compare predicates of different subclasses");
320 }
321 }
322
323 std::string PlacementPredicate::to_string() const {
324 std::string str = auto_name(*this) + ":{ ";
325 str += ("Nodes: " + std::to_string(nodes_.size()) + " }");
326 return str;
327 }
328
329 50 bool ConnectivityPredicate::verify(const Circuit& circ) const {
330 50 return respects_connectivity_constraints(circ, arch_, false, true);
331 }
332
333 13 bool ConnectivityPredicate::implies(const Predicate& other) const {
334 try {
335 const ConnectivityPredicate& other_c =
336
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 dynamic_cast<const ConnectivityPredicate&>(other);
337 13 const Architecture& arc1 = arch_;
338 13 const Architecture& arc2 = other_c.arch_;
339 // Check that all nodes in arc1 are in arc2:
340
3/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 8 taken 116 times.
✓ Branch 9 taken 12 times.
0/1
? Decision couldn't be analyzed.
128 for (const Node& n : arc1.get_all_nodes_vec()) {
341
3/4
✓ Branch 1 taken 116 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 115 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 115 times.
116 if (!arc2.node_exists(n)) {
342 1 return false;
343 }
344
2/2
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 1 times.
13 }
345 // Collect all edges in arc1
346
3/4
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 11 taken 156 times.
✓ Branch 12 taken 11 times.
0/1
? Decision couldn't be analyzed.
167 for (auto [n1, n2] : arc1.get_all_edges_vec()) {
347
8/10
✓ Branch 1 taken 156 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 154 times.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✓ Branch 9 taken 1 times.
✓ Branch 10 taken 1 times.
✓ Branch 11 taken 155 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 155 times.
156 if (!arc2.edge_exists(n1, n2) && !arc2.edge_exists(n2, n1)) {
348 1 return false; // if not in second architecture, return false
349 }
350
4/4
✓ Branch 1 taken 155 times.
✓ Branch 2 taken 1 times.
✓ Branch 4 taken 11 times.
✓ Branch 5 taken 1 times.
168 }
351 11 return true;
352 } catch (const std::bad_cast&) {
353 throw IncorrectPredicate(
354 "Cannot compare predicates of different subclasses");
355 }
356 }
357
358 1 PredicatePtr ConnectivityPredicate::meet(const Predicate& other) const {
359 try {
360 const ConnectivityPredicate& other_c =
361
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 dynamic_cast<const ConnectivityPredicate&>(other);
362 1 const Architecture& arc1 = arch_;
363 1 const Architecture& arc2 = other_c.arch_;
364 1 std::vector<std::pair<Node, Node>> new_edges;
365 // Collect all edges in arc1 which are also in arc2
366
3/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 11 taken 2 times.
✓ Branch 12 taken 1 times.
0/1
? Decision couldn't be analyzed.
3 for (auto [n1, n2] : arc1.get_all_edges_vec()) {
367
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
1/2
✓ Decision 'true' taken 2 times.
✗ Decision 'false' not taken.
2 if (arc2.edge_exists(n1, n2)) {
368
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 new_edges.push_back({n1, n2});
369
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 new_edges.push_back({n2, n1});
370 }
371 3 }
372
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 Architecture arc3(new_edges);
373
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 PredicatePtr pp = std::make_shared<ConnectivityPredicate>(arc3);
374 2 return pp;
375
0/2
✗ Branch 5 not taken.
✗ Branch 6 not taken.
1 } catch (const std::bad_cast&) {
376 throw IncorrectPredicate(
377 "Cannot compare predicates of different subclasses");
378 }
379 }
380
381 std::string ConnectivityPredicate::to_string() const {
382 std::string str = auto_name(*this) + ":{ ";
383 str +=
384 ("Nodes: " + std::to_string(arch_.n_nodes()) +
385 ", Edges: " + std::to_string(arch_.n_connections())) += " }";
386 return str;
387 }
388
389 3 bool DirectednessPredicate::verify(const Circuit& circ) const {
390 3 return respects_connectivity_constraints(circ, arch_, true, false);
391 }
392
393 4 bool DirectednessPredicate::implies(const Predicate& other) const {
394 try {
395 const DirectednessPredicate& other_c =
396
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 dynamic_cast<const DirectednessPredicate&>(other);
397 4 const Architecture& arc1 = arch_;
398 4 const Architecture& arc2 = other_c.arch_;
399 // Collect all edges in arc1
400
3/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 11 taken 6 times.
✓ Branch 12 taken 1 times.
0/1
? Decision couldn't be analyzed.
7 for (auto [n1, n2] : arc1.get_all_edges_vec()) {
401 // directedness accounted for
402
3/4
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 3 times.
2/2
✓ Decision 'true' taken 3 times.
✓ Decision 'false' taken 3 times.
6 if (!arc2.edge_exists(n1, n2)) {
403 3 return false; // if not in second architecture, return false
404 }
405
4/4
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 3 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 3 times.
10 }
406 1 return true;
407 } catch (const std::bad_cast&) {
408 throw IncorrectPredicate(
409 "Cannot compare predicates of different subclasses");
410 }
411 }
412
413 1 PredicatePtr DirectednessPredicate::meet(const Predicate& other) const {
414 try {
415 const DirectednessPredicate& other_c =
416
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 dynamic_cast<const DirectednessPredicate&>(other);
417 1 const Architecture& arc1 = arch_;
418 1 const Architecture& arc2 = other_c.arch_;
419 1 std::vector<std::pair<Node, Node>> new_edges;
420 // Collect all edges in arc1 which are also in arc2
421
3/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 11 taken 2 times.
✓ Branch 12 taken 1 times.
0/1
? Decision couldn't be analyzed.
3 for (auto [n1, n2] : arc1.get_all_edges_vec()) {
422 // this also accounts for directedness, do we want that?
423
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
1/2
✓ Decision 'true' taken 2 times.
✗ Decision 'false' not taken.
2 if (arc2.edge_exists(n1, n2)) {
424
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 new_edges.push_back({n1, n2});
425 }
426 3 }
427
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 Architecture arc3(new_edges);
428
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 PredicatePtr pp = std::make_shared<DirectednessPredicate>(arc3);
429 2 return pp;
430
0/2
✗ Branch 5 not taken.
✗ Branch 6 not taken.
1 } catch (const std::bad_cast&) {
431 throw IncorrectPredicate(
432 "Cannot compare predicates of different subclasses");
433 }
434 }
435
436 std::string DirectednessPredicate::to_string() const {
437 std::string str = auto_name(*this) + ":{ ";
438 str +=
439 ("Nodes: " + std::to_string(arch_.n_nodes()) +
440 ", Edges: " + std::to_string(arch_.n_connections())) += " }";
441 return str;
442 }
443
444 2 bool CliffordCircuitPredicate::verify(const Circuit& circ) const {
445
7/8
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 25 times.
✓ Branch 6 taken 1 times.
✓ Branch 8 taken 25 times.
✓ Branch 9 taken 1 times.
✓ Branch 11 taken 2 times.
✓ Branch 12 taken 1 times.
27 BGL_FORALL_VERTICES(v, circ.dag, DAG) {
446
4/6
✓ Branch 1 taken 25 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 25 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
✓ Branch 9 taken 24 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 24 times.
25 if (!circ.get_Op_ptr_from_Vertex(v)->is_clifford()) return false;
447 }
448 1 return true;
449 }
450
451 bool CliffordCircuitPredicate::implies(const Predicate& other) const {
452 return auto_implication(*this, other);
453 }
454
455 PredicatePtr CliffordCircuitPredicate::meet(const Predicate& other) const {
456 return auto_meet(*this, other);
457 }
458
459 std::string CliffordCircuitPredicate::to_string() const {
460 return auto_name(*this);
461 }
462
463 bool UserDefinedPredicate::implies(const Predicate&) const {
464 throw IncorrectPredicate(
465 "Cannot deduce implication relations of user defined Predicates");
466 }
467
468 PredicatePtr UserDefinedPredicate::meet(const Predicate&) const {
469 throw IncorrectPredicate("Cannot find the meet of user defined Predicates");
470 }
471
472 bool UserDefinedPredicate::verify(const Circuit& circ) const {
473 return func_(circ);
474 }
475
476 std::string UserDefinedPredicate::to_string() const { return auto_name(*this); }
477
478 6 bool DefaultRegisterPredicate::verify(const Circuit& circ) const {
479 6 return circ.is_simple();
480 }
481
482 bool DefaultRegisterPredicate::implies(const Predicate& other) const {
483 return auto_implication(*this, other);
484 }
485
486 PredicatePtr DefaultRegisterPredicate::meet(const Predicate& other) const {
487 return auto_meet(*this, other);
488 }
489
490 std::string DefaultRegisterPredicate::to_string() const {
491 return auto_name(*this);
492 }
493
494 46 bool MaxNQubitsPredicate::verify(const Circuit& circ) const {
495 46 return circ.n_qubits() <= n_qubits_;
496 }
497
498 73 bool MaxNQubitsPredicate::implies(const Predicate& other) const {
499 try {
500 const MaxNQubitsPredicate& other_p =
501
1/2
✓ Branch 0 taken 73 times.
✗ Branch 1 not taken.
73 dynamic_cast<const MaxNQubitsPredicate&>(other);
502 73 return n_qubits_ <= other_p.n_qubits_;
503 } catch (const std::bad_cast&) {
504 throw IncorrectPredicate(
505 "Cannot compare predicates of different subclasses");
506 }
507 }
508
509 38 PredicatePtr MaxNQubitsPredicate::meet(const Predicate& other) const {
510 try {
511 const MaxNQubitsPredicate& other_p =
512
1/2
✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
38 dynamic_cast<const MaxNQubitsPredicate&>(other);
513
1/2
✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
76 return std::make_shared<MaxNQubitsPredicate>(
514 114 std::min(n_qubits_, other_p.n_qubits_));
515 } catch (const std::bad_cast&) {
516 throw IncorrectPredicate(
517 "Cannot compare predicates of different subclasses");
518 }
519 }
520
521 std::string MaxNQubitsPredicate::to_string() const {
522 return auto_name(*this) + "(" + std::to_string(n_qubits_) + ")";
523 }
524
525 bool NoBarriersPredicate::verify(const Circuit& circ) const {
526 BGL_FORALL_VERTICES(v, circ.dag, DAG) {
527 Op_ptr op = circ.get_Op_ptr_from_Vertex(v);
528
0/2
✗ Decision 'true' not taken.
✗ Decision 'false' not taken.
if (op->get_type() == OpType::Barrier) return false;
529
0/2
✗ Decision 'true' not taken.
✗ Decision 'false' not taken.
if (op->get_type() == OpType::CircBox ||
530 op->get_type() == OpType::CustomGate) {
531 const Box& box = static_cast<const Box&>(*op);
532
0/2
✗ Decision 'true' not taken.
✗ Decision 'false' not taken.
if (!verify(*box.to_circuit())) return false;
533 }
534 }
535 return true;
536 }
537
538 bool NoBarriersPredicate::implies(const Predicate& other) const {
539 return auto_implication(*this, other);
540 }
541
542 PredicatePtr NoBarriersPredicate::meet(const Predicate& other) const {
543 return auto_meet(*this, other);
544 }
545
546 std::string NoBarriersPredicate::to_string() const { return auto_name(*this); }
547
548 65 static bool mid_measure_helper(const Command& com, unit_set_t& measured_units) {
549 // Rejects gates acting on measured_units
550 // Encountering a measurement adds the qubit and bit to measured_units
551 // Returns whether or not a mid-circuit measurement is found
552 // Applies recursively for CircBoxes
553
2/2
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 64 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 64 times.
65 if (com.get_op_ptr()->get_type() == OpType::Conditional) {
554
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 unit_vector_t all_args = com.get_args();
555 const Conditional& cond =
556 1 static_cast<const Conditional&>(*com.get_op_ptr());
557 1 unit_vector_t::iterator arg_it = all_args.begin();
558
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
0/1
? Decision couldn't be analyzed.
1 for (unsigned i = 0; i < cond.get_width(); ++i) {
559
2/4
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 1 times.
1 if (measured_units.find(*arg_it) != measured_units.end()) return false;
560 ++arg_it;
561 }
562 unit_vector_t new_args = {arg_it, all_args.end()};
563 Command new_com = {cond.get_op(), new_args};
564 return mid_measure_helper(new_com, measured_units);
565 1 } else if (
566
5/6
✓ Branch 3 taken 60 times.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 60 times.
✓ Branch 8 taken 4 times.
✓ Branch 9 taken 60 times.
188 com.get_op_ptr()->get_type() == OpType::CircBox ||
567
3/4
✓ Branch 3 taken 60 times.
✓ Branch 4 taken 4 times.
✓ Branch 6 taken 64 times.
✗ Branch 7 not taken.
124 com.get_op_ptr()->get_type() == OpType::CustomGate) {
568 4 const Box& box = static_cast<const Box&>(*com.get_op_ptr());
569 4 unit_map_t interface;
570 4 unit_set_t inner_set;
571 4 unsigned q_count = 0;
572 4 unsigned b_count = 0;
573
3/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 8 taken 8 times.
✓ Branch 9 taken 4 times.
0/1
? Decision couldn't be analyzed.
12 for (const UnitID& u : com.get_args()) {
574 8 UnitID inner_unit = (u.type() == UnitType::Qubit)
575
1/4
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
5 ? static_cast<UnitID>(Qubit(q_count++))
576
7/10
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 3 times.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3 times.
✓ Branch 8 taken 5 times.
✓ Branch 9 taken 5 times.
✓ Branch 10 taken 3 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
16 : static_cast<UnitID>(Bit(b_count++));
577
1/2
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
8 interface.insert({inner_unit, u});
578
3/4
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 3 times.
✓ Branch 6 taken 5 times.
2/2
✓ Decision 'true' taken 3 times.
✓ Decision 'false' taken 5 times.
8 if (measured_units.find(u) != measured_units.end()) {
579
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 inner_set.insert(inner_unit);
580 }
581 12 }
582
7/12
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 4 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 6 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 5 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 6 times.
✓ Branch 19 taken 3 times.
0/1
? Decision couldn't be analyzed.
9 for (const Command& c : *box.to_circuit()) {
583
3/4
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 5 times.
0/1
? Decision couldn't be analyzed.
6 if (!mid_measure_helper(c, inner_set)) return false;
584
6/6
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 1 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 1 times.
✓ Branch 7 taken 3 times.
✓ Branch 8 taken 1 times.
11 }
585
2/2
✓ Branch 5 taken 6 times.
✓ Branch 6 taken 3 times.
2/2
✓ Decision 'true' taken 6 times.
✓ Decision 'false' taken 3 times.
9 for (const UnitID& u : inner_set) {
586
2/4
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
6 measured_units.insert(interface.at(u));
587 }
588 3 return true;
589
2/2
✓ Branch 6 taken 22 times.
✓ Branch 7 taken 38 times.
2/2
✓ Decision 'true' taken 22 times.
✓ Decision 'false' taken 42 times.
64 } else if (com.get_op_ptr()->get_type() == OpType::Measure) {
590 std::pair<unit_set_t::iterator, bool> q_inserted =
591
3/6
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 22 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 22 times.
✗ Branch 8 not taken.
22 measured_units.insert(com.get_args().at(0));
592 std::pair<unit_set_t::iterator, bool> c_inserted =
593
3/6
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 22 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 22 times.
✗ Branch 8 not taken.
22 measured_units.insert(com.get_args().at(1));
594
3/4
✓ Branch 0 taken 22 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21 times.
✓ Branch 3 taken 1 times.
22 return q_inserted.second && c_inserted.second;
595 } else {
596
3/4
✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
✓ Branch 8 taken 57 times.
✓ Branch 9 taken 34 times.
0/1
? Decision couldn't be analyzed.
91 for (const UnitID& a : com.get_args()) {
597
3/4
✓ Branch 2 taken 57 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 4 times.
✓ Branch 6 taken 53 times.
2/2
✓ Decision 'true' taken 38 times.
✓ Decision 'false' taken 19 times.
57 if (measured_units.find(a) != measured_units.end()) return false;
598
2/2
✓ Branch 1 taken 34 times.
✓ Branch 2 taken 4 times.
38 }
599 34 return true;
600 }
601 }
602
603 20 bool NoMidMeasurePredicate::verify(const Circuit& circ) const {
604
3/4
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 7 times.
✓ Branch 4 taken 13 times.
2/2
✓ Decision 'true' taken 13 times.
✓ Decision 'false' taken 7 times.
20 if (circ.n_bits() == 0) return true;
605 13 unit_set_t measured_units;
606
6/10
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 59 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 53 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 59 times.
✓ Branch 14 taken 7 times.
0/1
? Decision couldn't be analyzed.
66 for (const Command& com : circ) {
607
3/4
✓ Branch 1 taken 59 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 53 times.
0/1
? Decision couldn't be analyzed.
59 if (!mid_measure_helper(com, measured_units)) return false;
608
6/6
✓ Branch 1 taken 53 times.
✓ Branch 2 taken 6 times.
✓ Branch 4 taken 7 times.
✓ Branch 5 taken 6 times.
✓ Branch 7 taken 7 times.
✓ Branch 8 taken 6 times.
78 }
609 7 return true;
610 13 }
611
612 bool NoMidMeasurePredicate::implies(const Predicate& other) const {
613 return auto_implication(*this, other);
614 }
615
616 PredicatePtr NoMidMeasurePredicate::meet(const Predicate& other) const {
617 return auto_meet(*this, other);
618 }
619
620 std::string NoMidMeasurePredicate::to_string() const {
621 return auto_name(*this);
622 }
623
624 bool NoSymbolsPredicate::verify(const Circuit& circ) const {
625 return !circ.is_symbolic();
626 }
627
628 bool NoSymbolsPredicate::implies(const Predicate& other) const {
629 return auto_implication(*this, other);
630 }
631
632 PredicatePtr NoSymbolsPredicate::meet(const Predicate& other) const {
633 return auto_meet(*this, other);
634 }
635
636 std::string NoSymbolsPredicate::to_string() const { return auto_name(*this); }
637
638 7 bool GlobalPhasedXPredicate::verify(const Circuit& circ) const {
639
7/8
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 71 times.
✓ Branch 6 taken 5 times.
✓ Branch 8 taken 71 times.
✓ Branch 9 taken 5 times.
✓ Branch 11 taken 7 times.
✓ Branch 12 taken 5 times.
81 BGL_FORALL_VERTICES(v, circ.dag, DAG) {
640
3/4
✓ Branch 1 taken 71 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 63 times.
2/2
✓ Decision 'true' taken 8 times.
✓ Decision 'false' taken 63 times.
71 if (circ.get_OpType_from_Vertex(v) == OpType::NPhasedX) {
641
4/6
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✓ Branch 7 taken 6 times.
2/2
✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 6 times.
8 if (circ.n_in_edges_of_type(v, EdgeType::Quantum) != circ.n_qubits()) {
642 2 return false;
643 }
644 }
645 }
646 5 return true;
647 }
648
649 bool GlobalPhasedXPredicate::implies(const Predicate& other) const {
650 return auto_implication(*this, other);
651 }
652
653 PredicatePtr GlobalPhasedXPredicate::meet(const Predicate& other) const {
654 return auto_meet(*this, other);
655 }
656
657 std::string GlobalPhasedXPredicate::to_string() const {
658 return auto_name(*this);
659 }
660
661 27 bool NormalisedTK2Predicate::verify(const Circuit& circ) const {
662
7/8
✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 441 times.
✓ Branch 6 taken 24 times.
✓ Branch 8 taken 441 times.
✓ Branch 9 taken 24 times.
✓ Branch 11 taken 27 times.
✓ Branch 12 taken 24 times.
489 BGL_FORALL_VERTICES(v, circ.dag, DAG) {
663
1/2
✓ Branch 1 taken 441 times.
✗ Branch 2 not taken.
441 Op_ptr op = circ.get_Op_ptr_from_Vertex(v);
664 441 bool conditional = op->get_type() == OpType::Conditional;
665
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 427 times.
2/2
✓ Decision 'true' taken 14 times.
✓ Decision 'false' taken 427 times.
441 if (conditional) {
666 14 const Conditional& cond = static_cast<const Conditional&>(*op);
667
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 op = cond.get_op();
668 }
669
2/2
✓ Branch 2 taken 41 times.
✓ Branch 3 taken 400 times.
2/2
✓ Decision 'true' taken 41 times.
✓ Decision 'false' taken 400 times.
441 if (op->get_type() == OpType::TK2) {
670
1/2
✓ Branch 2 taken 41 times.
✗ Branch 3 not taken.
41 auto params = op->get_params();
671 TKET_ASSERT(params.size() == 3);
672
6/10
✓ Branch 2 taken 41 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 41 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 41 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 41 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 3 times.
✓ Branch 17 taken 38 times.
2/2
✓ Decision 'true' taken 3 times.
✓ Decision 'false' taken 38 times.
41 if (!in_weyl_chamber({params[0], params[1], params[2]})) {
673 3 return false;
674 }
675
2/2
✓ Branch 1 taken 38 times.
✓ Branch 2 taken 3 times.
41 }
676
2/2
✓ Branch 1 taken 438 times.
✓ Branch 2 taken 3 times.
441 }
677 24 return true;
678 }
679
680 bool NormalisedTK2Predicate::implies(const Predicate& other) const {
681 return auto_implication(*this, other);
682 }
683
684 PredicatePtr NormalisedTK2Predicate::meet(const Predicate& other) const {
685 return auto_meet(*this, other);
686 }
687
688 std::string NormalisedTK2Predicate::to_string() const {
689 return auto_name(*this);
690 }
691
692 44 void to_json(nlohmann::json& j, const PredicatePtr& pred_ptr) {
693
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 33 times.
2/2
✓ Decision 'true' taken 11 times.
✓ Decision 'false' taken 33 times.
44 if (std::shared_ptr<GateSetPredicate> cast_pred =
694 44 std::dynamic_pointer_cast<GateSetPredicate>(pred_ptr)) {
695
2/4
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 11 times.
✗ Branch 5 not taken.
11 j["type"] = "GateSetPredicate";
696
2/4
✓ Branch 3 taken 11 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 11 times.
✗ Branch 7 not taken.
11 j["allowed_types"] = cast_pred->get_allowed_types();
697
3/6
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 11 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 11 times.
✗ Branch 10 not taken.
11 std::sort(j["allowed_types"].begin(), j["allowed_types"].end());
698
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 31 times.
2/2
✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 31 times.
33 } else if (
699 std::shared_ptr<NoClassicalControlPredicate> cast_pred =
700 33 std::dynamic_pointer_cast<NoClassicalControlPredicate>(pred_ptr)) {
701
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 j["type"] = "NoClassicalControlPredicate";
702
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 29 times.
2/2
✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 29 times.
31 } else if (
703 std::shared_ptr<NoFastFeedforwardPredicate> cast_pred =
704 31 std::dynamic_pointer_cast<NoFastFeedforwardPredicate>(pred_ptr)) {
705
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 j["type"] = "NoFastFeedforwardPredicate";
706
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 27 times.
2/2
✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 27 times.
29 } else if (
707 std::shared_ptr<NoClassicalBitsPredicate> cast_pred =
708 29 std::dynamic_pointer_cast<NoClassicalBitsPredicate>(pred_ptr)) {
709
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 j["type"] = "NoClassicalBitsPredicate";
710
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 25 times.
2/2
✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 25 times.
27 } else if (
711 std::shared_ptr<NoWireSwapsPredicate> cast_pred =
712 27 std::dynamic_pointer_cast<NoWireSwapsPredicate>(pred_ptr)) {
713
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 j["type"] = "NoWireSwapsPredicate";
714
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 23 times.
2/2
✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 23 times.
25 } else if (
715 std::shared_ptr<MaxTwoQubitGatesPredicate> cast_pred =
716 25 std::dynamic_pointer_cast<MaxTwoQubitGatesPredicate>(pred_ptr)) {
717
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 j["type"] = "MaxTwoQubitGatesPredicate";
718
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 21 times.
2/2
✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 21 times.
23 } else if (
719 std::shared_ptr<PlacementPredicate> cast_pred =
720 23 std::dynamic_pointer_cast<PlacementPredicate>(pred_ptr)) {
721
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 j["type"] = "PlacementPredicate";
722
2/4
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
2 j["node_set"] = cast_pred->get_nodes();
723
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 19 times.
2/2
✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 19 times.
21 } else if (
724 std::shared_ptr<ConnectivityPredicate> cast_pred =
725 21 std::dynamic_pointer_cast<ConnectivityPredicate>(pred_ptr)) {
726
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 j["type"] = "ConnectivityPredicate";
727
2/4
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
2 j["architecture"] = cast_pred->get_arch();
728
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 17 times.
2/2
✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 17 times.
19 } else if (
729 std::shared_ptr<DirectednessPredicate> cast_pred =
730 19 std::dynamic_pointer_cast<DirectednessPredicate>(pred_ptr)) {
731
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 j["type"] = "DirectednessPredicate";
732
2/4
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
2 j["architecture"] = cast_pred->get_arch();
733
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 15 times.
2/2
✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 15 times.
17 } else if (
734 std::shared_ptr<CliffordCircuitPredicate> cast_pred =
735 17 std::dynamic_pointer_cast<CliffordCircuitPredicate>(pred_ptr)) {
736
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 j["type"] = "CliffordCircuitPredicate";
737
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 14 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 14 times.
15 } else if (
738 std::shared_ptr<UserDefinedPredicate> cast_pred =
739 15 std::dynamic_pointer_cast<UserDefinedPredicate>(pred_ptr)) {
740
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 j["type"] = "UserDefinedPredicate";
741
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 j["custom"] = "SERIALIZATION OF FUNCTIONS IS NOT YET SUPPORTED";
742
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 12 times.
2/2
✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 12 times.
14 } else if (
743 std::shared_ptr<DefaultRegisterPredicate> cast_pred =
744 14 std::dynamic_pointer_cast<DefaultRegisterPredicate>(pred_ptr)) {
745
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 j["type"] = "DefaultRegisterPredicate";
746
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 10 times.
2/2
✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 10 times.
12 } else if (
747 std::shared_ptr<MaxNQubitsPredicate> cast_pred =
748 12 std::dynamic_pointer_cast<MaxNQubitsPredicate>(pred_ptr)) {
749
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 j["type"] = "MaxNQubitsPredicate";
750
1/2
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 j["n_qubits"] = cast_pred->get_n_qubits();
751
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
2/2
✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 8 times.
10 } else if (
752 std::shared_ptr<NoBarriersPredicate> cast_pred =
753 10 std::dynamic_pointer_cast<NoBarriersPredicate>(pred_ptr)) {
754
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 j["type"] = "NoBarriersPredicate";
755
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
2/2
✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 6 times.
8 } else if (
756 std::shared_ptr<NoMidMeasurePredicate> cast_pred =
757 8 std::dynamic_pointer_cast<NoMidMeasurePredicate>(pred_ptr)) {
758
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 j["type"] = "NoMidMeasurePredicate";
759
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
2/2
✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 4 times.
6 } else if (
760 std::shared_ptr<NoSymbolsPredicate> cast_pred =
761 6 std::dynamic_pointer_cast<NoSymbolsPredicate>(pred_ptr)) {
762
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 j["type"] = "NoSymbolsPredicate";
763
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
2/2
✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 2 times.
4 } else if (
764 std::shared_ptr<GlobalPhasedXPredicate> cast_pred =
765 4 std::dynamic_pointer_cast<GlobalPhasedXPredicate>(pred_ptr)) {
766
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 j["type"] = "GlobalPhasedXPredicate";
767
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
1/2
✓ Decision 'true' taken 2 times.
✗ Decision 'false' not taken.
2 } else if (
768 std::shared_ptr<NormalisedTK2Predicate> cast_pred =
769 2 std::dynamic_pointer_cast<NormalisedTK2Predicate>(pred_ptr)) {
770
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 j["type"] = "NormalisedTK2Predicate";
771 } else {
772 throw JsonError("Cannot serialize PredicatePtr of unknown type.");
773 340 }
774 44 }
775
776 19 void from_json(const nlohmann::json& j, PredicatePtr& pred_ptr) {
777
2/4
✓ Branch 1 taken 19 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 19 times.
✗ Branch 5 not taken.
19 std::string classname = j.at("type").get<std::string>();
778
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 17 times.
2/2
✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 17 times.
19 if (classname == "GateSetPredicate") {
779
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 OpTypeSet allowed_types = j.at("allowed_types").get<OpTypeSet>();
780
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 pred_ptr = std::make_shared<GateSetPredicate>(allowed_types);
781
2/2
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 16 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 18 times.
19 } else if (classname == "NoClassicalControlPredicate") {
782
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pred_ptr = std::make_shared<NoClassicalControlPredicate>();
783
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 15 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 15 times.
16 } else if (classname == "NoFastFeedforwardPredicate") {
784
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pred_ptr = std::make_shared<NoFastFeedforwardPredicate>();
785
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 14 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 14 times.
15 } else if (classname == "NoClassicalBitsPredicate") {
786
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pred_ptr = std::make_shared<NoClassicalBitsPredicate>();
787
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 13 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 13 times.
14 } else if (classname == "NoWireSwapsPredicate") {
788
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pred_ptr = std::make_shared<NoWireSwapsPredicate>();
789
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 12 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 12 times.
13 } else if (classname == "MaxTwoQubitGatesPredicate") {
790
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pred_ptr = std::make_shared<MaxTwoQubitGatesPredicate>();
791
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 11 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 11 times.
12 } else if (classname == "PlacementPredicate") {
792
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 node_set_t node_set = j.at("node_set").get<node_set_t>();
793
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pred_ptr = std::make_shared<PlacementPredicate>(node_set);
794
2/2
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 10 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 11 times.
12 } else if (classname == "ConnectivityPredicate") {
795
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 Architecture arch = j.at("architecture").get<Architecture>();
796
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pred_ptr = std::make_shared<ConnectivityPredicate>(arch);
797
2/2
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 9 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 10 times.
11 } else if (classname == "DirectednessPredicate") {
798
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 Architecture arch = j.at("architecture").get<Architecture>();
799
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pred_ptr = std::make_shared<DirectednessPredicate>(arch);
800
2/2
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 8 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 9 times.
10 } else if (classname == "CliffordCircuitPredicate") {
801
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pred_ptr = std::make_shared<CliffordCircuitPredicate>();
802
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 7 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 7 times.
8 } else if (classname == "UserDefinedPredicate") {
803
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 throw PredicateNotSerializable(classname);
804
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 6 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 6 times.
7 } else if (classname == "DefaultRegisterPredicate") {
805
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pred_ptr = std::make_shared<DefaultRegisterPredicate>();
806
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 5 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 5 times.
6 } else if (classname == "MaxNQubitsPredicate") {
807
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 unsigned n_qubits = j.at("n_qubits").get<unsigned>();
808
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pred_ptr = std::make_shared<MaxNQubitsPredicate>(n_qubits);
809
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 4 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 4 times.
5 } else if (classname == "NoBarriersPredicate") {
810
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pred_ptr = std::make_shared<NoBarriersPredicate>();
811
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 3 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 3 times.
4 } else if (classname == "NoMidMeasurePredicate") {
812
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pred_ptr = std::make_shared<NoMidMeasurePredicate>();
813
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 2 times.
2/2
✓ Decision 'true' taken 1 times.
✓ Decision 'false' taken 2 times.
3 } else if (classname == "NoSymbolsPredicate") {
814
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pred_ptr = std::make_shared<NoSymbolsPredicate>();
815
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 } else if (classname == "GlobalPhasedXPredicate") {
816
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pred_ptr = std::make_shared<GlobalPhasedXPredicate>();
817
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1/2
✓ Decision 'true' taken 1 times.
✗ Decision 'false' not taken.
1 } else if (classname == "NormalisedTK2Predicate") {
818
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 pred_ptr = std::make_shared<NormalisedTK2Predicate>();
819 } else {
820 throw JsonError("Cannot load PredicatePtr of unknown type.");
821 }
822 19 }
823
824 } // namespace tket
825