|
20 | 20 | #define R(s1, s2) (stateNum + stateNum * stateNum + (s1) * stateNum + (s2)) |
21 | 21 |
|
22 | 22 | namespace { |
| 23 | +/// Copy result base fields from src and check state-number overflow for product-shaped expansion. |
| 24 | +template <typename Symbol> |
| 25 | +void gate_copy_result_base_and_check_overflow( |
| 26 | + AUTOQ::Automata<Symbol>& result, |
| 27 | + const AUTOQ::Automata<Symbol>& src) |
| 28 | +{ |
| 29 | + using State = typename AUTOQ::Automata<Symbol>::State; |
| 30 | + result.name = src.name; |
| 31 | + result.qubitNum = src.qubitNum; |
| 32 | + result.isTopdownDeterministic = src.isTopdownDeterministic; |
| 33 | + result.finalStates = src.finalStates; |
| 34 | + result.hasLoop = src.hasLoop; |
| 35 | + result.vars = src.vars; |
| 36 | + result.constraints = src.constraints; |
| 37 | + bool overflow = (src.stateNum > (std::numeric_limits<State>::max() - src.stateNum) / src.stateNum / 2); |
| 38 | + if (overflow) |
| 39 | + THROW_AUTOQ_ERROR("The number of states after multiplication is too large."); |
| 40 | +} |
| 41 | + |
23 | 42 | template <typename Symbol> |
24 | 43 | void flush_qcfi_to_result( |
25 | 44 | AUTOQ::Automata<Symbol>& result, |
@@ -47,20 +66,7 @@ void flush_qcfi_to_result( |
47 | 66 | template <typename Symbol> |
48 | 67 | void AUTOQ::Automata<Symbol>::general_single_qubit_gate(int t, const std::function<Symbol(const Symbol&, const Symbol&)> &u1u2, const std::function<Symbol(const Symbol&, const Symbol&)> &u3u4) { |
49 | 68 | AUTOQ::Automata<Symbol> result; |
50 | | - result.name = name; |
51 | | - result.qubitNum = qubitNum; |
52 | | - result.isTopdownDeterministic = isTopdownDeterministic; // IMPORTANT: Avoid missing copying new fields afterwards. |
53 | | - result.finalStates = finalStates; |
54 | | - result.hasLoop = hasLoop; // IMPORTANT: Avoid missing copying new fields afterwards. |
55 | | - result.vars = vars; // IMPORTANT: Avoid missing copying new fields afterwards. |
56 | | - result.constraints = constraints; // IMPORTANT: Avoid missing copying new fields afterwards. |
57 | | - |
58 | | - bool overflow = (stateNum > (std::numeric_limits<State>::max()-stateNum) / stateNum / 2); // want: 2 * stateNum^2 + stateNum <= max |
59 | | - if (overflow) |
60 | | - THROW_AUTOQ_ERROR("The number of states after multiplication is too large."); |
61 | | - // s < stateNum -> s |
62 | | - // (s1, s2, L) -> stateNum + s1 * stateNum + s2 |
63 | | - // (s1, s2, R) -> stateNum + stateNum^2 + s1 * stateNum + s2 -> max == 2 * stateNum^2 + stateNum - 1 |
| 69 | + gate_copy_result_base_and_check_overflow(result, *this); |
64 | 70 |
|
65 | 71 | // We assume here transitions are ordered by symbols. |
66 | 72 | // x_i are placed in the beginning, and leaves are placed in the end. |
@@ -181,20 +187,7 @@ void AUTOQ::Automata<Symbol>::general_controlled_gate(int c, int c2, int t, cons |
181 | 187 | } |
182 | 188 |
|
183 | 189 | AUTOQ::Automata<Symbol> result; |
184 | | - result.name = name; |
185 | | - result.qubitNum = qubitNum; |
186 | | - result.isTopdownDeterministic = isTopdownDeterministic; // IMPORTANT: Avoid missing copying new fields afterwards. |
187 | | - result.finalStates = finalStates; |
188 | | - result.hasLoop = hasLoop; // IMPORTANT: Avoid missing copying new fields afterwards. |
189 | | - result.vars = vars; // IMPORTANT: Avoid missing copying new fields afterwards. |
190 | | - result.constraints = constraints; // IMPORTANT: Avoid missing copying new fields afterwards. |
191 | | - |
192 | | - bool overflow = (stateNum > (std::numeric_limits<State>::max()-stateNum) / stateNum / 2); // want: 2 * stateNum^2 + stateNum <= max |
193 | | - if (overflow) |
194 | | - THROW_AUTOQ_ERROR("The number of states after multiplication is too large."); |
195 | | - // s < stateNum -> s |
196 | | - // (s1, s2, L) -> stateNum + s1 * stateNum + s2 |
197 | | - // (s1, s2, R) -> stateNum + stateNum^2 + s1 * stateNum + s2 -> max == 2 * stateNum^2 + stateNum |
| 190 | + gate_copy_result_base_and_check_overflow(result, *this); |
198 | 191 |
|
199 | 192 | // We assume here transitions are ordered by symbols. |
200 | 193 | // x_i are placed in the beginning, and leaves are placed in the end. |
|
0 commit comments