GCC Code Coverage Report


Directory: ./
File: Transformations/OptimisationPass.cpp
Date: 2022-10-15 05:10:18
Exec Total Coverage
Lines: 109 111 98.2%
Functions: 18 18 100.0%
Branches: 203 395 51.4%
Decisions: 6 7 85.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 "OptimisationPass.hpp"
16
17 #include <stdexcept>
18
19 #include "BasicOptimisation.hpp"
20 #include "Circuit/CircPool.hpp"
21 #include "Circuit/CircUtils.hpp"
22 #include "CliffordOptimisation.hpp"
23 #include "CliffordReductionPass.hpp"
24 #include "Combinator.hpp"
25 #include "Decomposition.hpp"
26 #include "Gate/GatePtr.hpp"
27 #include "OpType/OpType.hpp"
28 #include "PhaseOptimisation.hpp"
29 #include "Rebase.hpp"
30 #include "ThreeQubitSquash.hpp"
31 #include "Transform.hpp"
32
33 namespace tket {
34
35 namespace Transforms {
36
37 1 Transform peephole_optimise_2q() {
38 return (
39
4/8
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
2 synthesise_tket() >> two_qubit_squash() >> hyper_clifford_squash() >>
40
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
3 synthesise_tket());
41 }
42
43 14 Transform full_peephole_optimise(bool allow_swaps, OpType target_2qb_gate) {
44
2/3
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
14 switch (target_2qb_gate) {
45 11 case OpType::CX:
46 return (
47
3/6
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 11 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 11 times.
✗ Branch 9 not taken.
33 synthesise_tket() >> two_qubit_squash(false) >>
48
4/8
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 11 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 11 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 11 times.
✗ Branch 11 not taken.
44 clifford_simp(allow_swaps) >> synthesise_tket() >>
49
4/8
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 11 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 11 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 11 times.
✗ Branch 11 not taken.
44 two_qubit_squash(allow_swaps) >> three_qubit_squash() >>
50
3/6
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 11 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 11 times.
✗ Branch 8 not taken.
33 clifford_simp(allow_swaps) >> synthesise_tket());
51 3 case OpType::TK2:
52 return (
53
3/6
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 3 times.
✗ Branch 9 not taken.
9 synthesise_tk() >> two_qubit_squash(OpType::TK2) >>
54
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.
12 clifford_simp(false) >> two_qubit_squash(OpType::TK2) >>
55
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.
12 synthesise_tk() >> three_qubit_squash(OpType::TK2) >>
56
3/6
✓ 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.
9 clifford_simp(false) >> two_qubit_squash(OpType::TK2) >>
57
2/4
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
6 synthesise_tk());
58
0/1
✗ Decision 'true' not taken.
default:
59 throw std::invalid_argument("Invalid target 2-qubit gate");
60 }
61 }
62
63 1 Transform canonical_hyper_clifford_squash() {
64
2/4
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
2 return optimise_via_PhaseGadget() >> two_qubit_squash() >>
65
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
3 hyper_clifford_squash();
66 }
67
68 2 Transform hyper_clifford_squash() {
69
2/4
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
4 return decompose_multi_qubits_CX() >> clifford_simp();
70 }
71
72 160 Transform clifford_simp(bool allow_swaps) {
73
3/6
✓ Branch 2 taken 160 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 160 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 160 times.
✗ Branch 9 not taken.
480 return decompose_cliffords_std() >> clifford_reduction(allow_swaps) >>
74
3/6
✓ Branch 1 taken 160 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 160 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 160 times.
✗ Branch 8 not taken.
480 decompose_multi_qubits_CX() >> singleq_clifford_sweep() >>
75
2/4
✓ Branch 1 taken 160 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 160 times.
✗ Branch 5 not taken.
480 squash_1qb_to_tk1();
76 }
77
78 15 Transform synthesise_tk() {
79
3/6
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 15 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 15 times.
✗ Branch 8 not taken.
30 Transform seq = commute_through_multis() >> remove_redundancies();
80
1/2
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
15 Transform rep = repeat(seq);
81
4/8
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 15 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 15 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 15 times.
✗ Branch 11 not taken.
30 Transform synth = decompose_multi_qubits_TK2() >> remove_redundancies() >>
82
2/4
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 15 times.
✗ Branch 5 not taken.
30 rep >> squash_1qb_to_tk1();
83
4/8
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 15 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 15 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 15 times.
✗ Branch 11 not taken.
30 Transform small_part = remove_redundancies() >> rep >> squash_1qb_to_tk1();
84 Transform repeat_synth = repeat_with_metric(
85
1/2
✓ Branch 2 taken 15 times.
✗ Branch 3 not taken.
90 small_part, [](const Circuit &circ) { return circ.n_vertices(); });
86
5/10
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 15 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 15 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 15 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 15 times.
✗ Branch 14 not taken.
45 return synth >> repeat_synth >> rebase_TK() >> remove_redundancies();
87 15 }
88
89 80 Transform synthesise_tket() {
90
3/6
✓ Branch 1 taken 80 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 80 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 80 times.
✗ Branch 8 not taken.
160 Transform seq = commute_through_multis() >> remove_redundancies();
91
1/2
✓ Branch 1 taken 80 times.
✗ Branch 2 not taken.
80 Transform rep = repeat(seq);
92
4/8
✓ Branch 1 taken 80 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 80 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 80 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 80 times.
✗ Branch 11 not taken.
160 Transform synth = decompose_multi_qubits_CX() >> remove_redundancies() >>
93
2/4
✓ Branch 1 taken 80 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 80 times.
✗ Branch 5 not taken.
160 rep >> squash_1qb_to_tk1();
94
4/8
✓ Branch 1 taken 80 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 80 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 80 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 80 times.
✗ Branch 11 not taken.
160 Transform small_part = remove_redundancies() >> rep >> squash_1qb_to_tk1();
95 Transform repeat_synth = repeat_with_metric(
96
1/2
✓ Branch 2 taken 80 times.
✗ Branch 3 not taken.
268 small_part, [](const Circuit &circ) { return circ.n_vertices(); });
97
5/10
✓ Branch 1 taken 80 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 80 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 80 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 80 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 80 times.
✗ Branch 14 not taken.
240 return synth >> repeat_synth >> rebase_tket() >> remove_redundancies();
98 80 }
99
100 7 static Transform CXs_from_phase_gadgets(CXConfigType cx_config) {
101 7 return Transform([=](Circuit &circ) {
102 7 bool success = false;
103 7 VertexList bin;
104
1/2
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
7 auto [i, end] = boost::vertices(circ.dag);
105
2/2
✓ Branch 1 taken 284 times.
✓ Branch 2 taken 7 times.
2/2
✓ Decision 'true' taken 284 times.
✓ Decision 'false' taken 7 times.
291 for (auto next = i; i != end; i = next) {
106 284 ++next;
107 284 Vertex a = *i;
108
1/2
✓ Branch 1 taken 284 times.
✗ Branch 2 not taken.
284 Op_ptr op = circ.get_Op_ptr_from_Vertex(a);
109
2/2
✓ Branch 2 taken 13 times.
✓ Branch 3 taken 271 times.
2/2
✓ Decision 'true' taken 13 times.
✓ Decision 'false' taken 271 times.
284 if (op->get_type() == OpType::PhaseGadget) {
110
1/2
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
13 unsigned n_qubits = op->n_qubits();
111 Circuit replacement =
112
2/4
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
13 phase_gadget(n_qubits, op->get_params()[0], cx_config);
113 Subcircuit sub = {
114
4/8
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 13 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 13 times.
✗ Branch 12 not taken.
26 {circ.get_in_edges(a)}, {circ.get_all_out_edges(a)}, {a}};
115
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 circ.substitute(replacement, sub, Circuit::VertexDeletion::Yes);
116 13 success = true;
117 13 }
118 284 }
119 7 return success;
120
1/2
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
14 });
121 }
122
123 7 Transform optimise_via_PhaseGadget(CXConfigType cx_config) {
124
5/10
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 7 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 7 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 7 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 7 times.
✗ Branch 15 not taken.
21 return rebase_tket() >> decompose_PhaseGadgets() >> smash_CX_PhaseGadgets() >>
125
3/6
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 7 times.
✗ Branch 8 not taken.
21 align_PhaseGadgets() >> CXs_from_phase_gadgets(cx_config) >>
126
2/4
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7 times.
✗ Branch 5 not taken.
21 synthesise_tket();
127 }
128
129 10 Transform synthesise_OQC() {
130 13 return Transform([](Circuit &circ) {
131
2/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
39 Transform rep_zx = squash_1qb_to_pqp(OpType::Rx, OpType::Rz) >>
132
3/6
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 13 times.
✗ Branch 8 not taken.
52 commute_through_multis() >> remove_redundancies();
133
4/8
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 13 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 13 times.
✗ Branch 11 not taken.
52 Transform seq = decompose_multi_qubits_CX() >> decompose_CX_to_ECR() >>
134
6/12
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 13 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 13 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 13 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 13 times.
✗ Branch 17 not taken.
78 decompose_ZX() >> repeat(rep_zx) >> rebase_OQC() >>
135
3/6
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 13 times.
✗ Branch 8 not taken.
52 commute_through_multis() >> remove_redundancies();
136
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 return seq.apply(circ);
137
1/2
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
23 });
138 }
139
140 /* Returns a Circuit with only HQS allowed Ops (Rz, PhasedX, ZZMax) */
141 9 Transform synthesise_HQS() {
142 12 return Transform([](Circuit &circ) {
143 Transform single_loop =
144
5/10
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 12 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 12 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 12 times.
✗ Branch 14 not taken.
24 remove_redundancies() >> commute_through_multis() >> reduce_XZ_chains();
145
3/6
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 12 times.
✗ Branch 8 not taken.
24 Transform hqs_loop = remove_redundancies() >> commute_and_combine_HQS2() >>
146
2/4
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
24 reduce_XZ_chains();
147 Transform main_seq =
148
6/12
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 12 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 12 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 12 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 12 times.
✗ Branch 17 not taken.
48 decompose_multi_qubits_CX() >> clifford_simp() >> decompose_ZX() >>
149
6/12
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 12 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 12 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 12 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 12 times.
✗ Branch 17 not taken.
72 repeat(single_loop) >> decompose_CX_to_HQS2() >> repeat(hqs_loop) >>
150
5/10
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 12 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 12 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 12 times.
✗ Branch 14 not taken.
48 decompose_ZX_to_HQS1() >> rebase_HQS() >> remove_redundancies();
151
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
24 return main_seq.apply(circ);
152
1/2
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
21 });
153 }
154
155 // TODO: Make the XXPhase gates combine
156 5 Transform synthesise_UMD() {
157
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
10 return Transform([](Circuit &circ) {
158
4/8
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 8 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 8 times.
✗ Branch 11 not taken.
24 bool success = (synthesise_tket() >> decompose_ZX() >>
159
3/6
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 8 times.
✗ Branch 8 not taken.
24 decompose_MolmerSorensen() >> squash_1qb_to_tk1())
160
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 .apply(circ);
161 8 VertexList bin;
162
7/8
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 353 times.
✓ Branch 6 taken 8 times.
✓ Branch 8 taken 353 times.
✓ Branch 9 taken 8 times.
✓ Branch 11 taken 8 times.
✓ Branch 12 taken 8 times.
369 BGL_FORALL_VERTICES(v, circ.dag, DAG) {
163
1/2
✓ Branch 1 taken 353 times.
✗ Branch 2 not taken.
353 const Op_ptr op_ptr = circ.get_Op_ptr_from_Vertex(v);
164 353 OpType type = op_ptr->get_type();
165
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 257 times.
2/2
✓ Decision 'true' taken 192 times.
✓ Decision 'false' taken 161 times.
353 if (type == OpType::TK1) {
166 std::vector<Expr> tk1_angles =
167
2/4
✓ Branch 2 taken 96 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 96 times.
✗ Branch 7 not taken.
192 as_gate_ptr(op_ptr)->get_tk1_angles();
168 Circuit in_circ = CircPool::tk1_to_PhasedXRz(
169
1/2
✓ Branch 4 taken 96 times.
✗ Branch 5 not taken.
96 tk1_angles[0], tk1_angles[1], tk1_angles[2]);
170
2/4
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 96 times.
✗ Branch 5 not taken.
96 remove_redundancies().apply(in_circ);
171 Subcircuit sub = {
172
4/8
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 96 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 96 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 96 times.
✗ Branch 12 not taken.
192 {circ.get_in_edges(v)}, {circ.get_all_out_edges(v)}, {v}};
173
1/2
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
96 bin.push_back(v);
174
1/2
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
96 circ.substitute(in_circ, sub, Circuit::VertexDeletion::No);
175
2/4
✓ Branch 2 taken 96 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 96 times.
✗ Branch 6 not taken.
96 circ.add_phase(tk1_angles[3]);
176 96 success = true;
177 96 }
178 353 }
179
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 circ.remove_vertices(
180 bin, Circuit::GraphRewiring::No, Circuit::VertexDeletion::Yes);
181 8 return success;
182
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
13 }) >>
183
3/6
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 5 times.
✗ Branch 8 not taken.
20 rebase_UMD() >> remove_redundancies();
184 }
185
186 } // namespace Transforms
187
188 } // namespace tket
189