@@ -200,9 +200,7 @@ void compile_instructions(Circuit& qc, vector<INSTRUCTION> instructions, SymbolT
200200 else if (type == " -=" ) {
201201 subtract_append (qc, *qvar1, *qvar2, instruction.get_controls ());
202202
203- }
204-
205-
203+ }
206204
207205 // check if our operation is relational (comparison)
208206 if (isCompOp (type)) {
@@ -221,21 +219,6 @@ void compile_instructions(Circuit& qc, vector<INSTRUCTION> instructions, SymbolT
221219
222220 qc.add_qregister (*ancilla);
223221
224-
225- /*
226- // reuse garbage register
227- QuantumVariable* ancilla = Garbage::get_garbage()->get_garbage_register(num_qubits_ancilla);
228-
229- if(ancilla == nullptr) {
230- // create ancillary register
231- table->ADD_ANCILLA_REGISTER(num_qubits_ancilla);
232- // get ancillary register
233- QuantumVariable* ancilla = table->search_qtable(table->GET_ANCILLA_REGISTER());
234- }
235-
236- */
237-
238- // add ancillary register to circuit
239222
240223 // compile equality operator
241224 if (type == " ==" ) {
@@ -276,57 +259,134 @@ void compile_instructions(Circuit& qc, vector<INSTRUCTION> instructions, SymbolT
276259 }
277260
278261 // compile AND operator
262+
279263 else if (type == " &" ) {
264+ if (qvar1->get_num_qubits () > 1 || qvar2->get_num_qubits () > 1 ) {
265+ // n qubit OR gate, loop through all qubit pairs, eval or on ancilla, then X all of them, multi-controlled gate
266+ QuantumVariable* max_reg_and = qvar1;
267+ QuantumVariable* min_reg_and = qvar2;
268+ // get min and max qubits
269+ unsigned int max_qubits_and = qvar1->get_num_qubits ();
270+ unsigned int min_qubits_and = qvar2->get_num_qubits ();
271+ if (max_qubits_and < min_qubits_and) {
272+ swap (max_qubits_and, min_qubits_and);
273+ swap (max_reg_and, min_reg_and);
274+ }
275+
276+ // check if single qubit OR required or register-wide or
277+ QuantumVariable* ancilla_nbit_and = result_reg;
278+
279+ if (result_reg->get_num_qubits () == 1 ) {
280+ ancilla_nbit_and = alloc_ancilla (qc, max_qubits_and, table);
281+
282+ }
283+
284+ unsigned int diff = max_qubits_and - min_qubits_and;
285+ // and all common qubits
286+ for (int qbit_pair = diff; qbit_pair < max_qubits_and; qbit_pair++) {
287+ qc.ccx (max_reg_and->get_qreg (), qbit_pair, min_reg_and->get_qreg (), qbit_pair-diff, ancilla_nbit_and->get_qreg (), qbit_pair-diff);
288+ }
289+
290+
291+ // continue if not in if statement
292+ if (result_reg->get_num_qubits () > 1 ) continue ;
293+
294+
295+ // ELSE multi-controlled NOT onto single qubit
296+
297+ qc.x (ancilla_nbit_and->get_qreg ());
298+ qc.x (result_reg->get_qreg ());
299+
300+
301+ QuantumVariable* ancilla_mcgate = alloc_ancilla (qc, ancilla_nbit_and->get_num_qubits ()-1 , table);
302+ multi_ctrl_gate (qc, &Circuit::cx, ancilla_nbit_and, result_reg, ancilla_mcgate);
303+
304+
305+ // uncomputation
306+ qc.x (ancilla_nbit_and->get_qreg ());
307+
308+ for (int qbit_pair = max_qubits_and - min_qubits_and; qbit_pair < max_qubits_and; qbit_pair++) {
309+ qc.ccx (qvar1->get_qreg (), qbit_pair, qvar2->get_qreg (), qbit_pair, ancilla_nbit_and->get_qreg (), qbit_pair);
310+ }
311+
312+ Garbage::get_garbage ()->add_garbage (ancilla_mcgate);
313+ Garbage::get_garbage ()->add_garbage (ancilla_nbit_and);
314+ continue ;
315+ }
316+
317+
318+
280319 qc.ccx (qvar1->get_qreg (), 0 , qvar2->get_qreg (), 0 , result_reg->get_qreg (), 0 );
281- }
320+ }
282321
283322 // compile OR operator
284323 else if (type == " |" ) {
285324 if (qvar1->get_num_qubits () > 1 || qvar2->get_num_qubits () > 1 ) {
286325 // n qubit OR gate, loop through all qubit pairs, eval or on ancilla, then X all of them, multi-controlled gate
287326
288327 QuantumVariable* max_reg_or = qvar1;
328+ QuantumVariable* min_reg_or = qvar2;
289329 // get min and max qubits
290330 unsigned int max_qubits_or = qvar1->get_num_qubits ();
291331 unsigned int min_qubits_or = qvar2->get_num_qubits ();
292332 if (max_qubits_or < min_qubits_or) {
293333 swap (max_qubits_or, min_qubits_or);
294- max_reg_or = qvar2 ;
334+ swap ( max_reg_or, min_reg_or) ;
295335 }
296336
297- QuantumVariable* ancilla_nbit_or = alloc_ancilla (qc, max_qubits_or, table);
337+ // check if single qubit OR required or register-wide or
338+ QuantumVariable* ancilla_nbit_or = result_reg;
339+
340+ if (result_reg->get_num_qubits () == 1 ) {
341+ ancilla_nbit_or = alloc_ancilla (qc, max_qubits_or, table);
298342
343+ }
344+
345+ unsigned int diff = max_qubits_or - min_qubits_or;
299346 // OR common bits
300- for (int qbit_pair = max_qubits_or - min_qubits_or ; qbit_pair < max_qubits_or ; qbit_pair++ ) {
301- bitwise_or (qc, qvar1 , qbit_pair, qvar2 , qbit_pair, ancilla_nbit_or, qbit_pair);
347+ for (int qbit_pair = max_qubits_or - 1 ; qbit_pair >= diff ; qbit_pair-- ) {
348+ bitwise_or (qc, max_reg_or , qbit_pair, min_reg_or , qbit_pair-diff , ancilla_nbit_or, qbit_pair);
302349 }
303350
304351 // OR uncommon bits (case where one register is larger than the other, then OR with zero is simply copying the bit value
305- for (int qbit_cutoff = 0 ; qbit_cutoff < max_qubits_or - min_qubits_or ; qbit_cutoff++) {
352+ for (int qbit_cutoff = 0 ; qbit_cutoff < diff ; qbit_cutoff++) {
306353 qc.cx (max_reg_or->get_qreg (), qbit_cutoff, ancilla_nbit_or->get_qreg (), qbit_cutoff);
307354 }
308355
356+
357+ // continue if not in if statement
358+ if (result_reg->get_num_qubits () > 1 ) continue ;
359+
360+
361+ // Following block only for if statement bool
362+
309363 // NOT entire register
310364 qc.x (ancilla_nbit_or->get_qreg ());
311365
366+ // NOT result register
367+ qc.x (result_reg->get_qreg ());
368+
312369 QuantumVariable* ancilla_mcgate = alloc_ancilla (qc, ancilla_nbit_or->get_num_qubits ()-1 , table);
313370 multi_ctrl_gate (qc, &Circuit::cx, ancilla_nbit_or, result_reg, ancilla_mcgate);
314371
315372 // Uncompute NOT
316373 qc.x (ancilla_nbit_or->get_qreg ());
317374
318- // Uncompute OR operation on ancilla
319-
375+ // Uncompute OR operation on ancilla - START
320376 // OR common bits
321- for (int qbit_pair = max_qubits_or - min_qubits_or ; qbit_pair < max_qubits_or ; qbit_pair++ ) {
322- bitwise_or (qc, qvar1 , qbit_pair, qvar2 , qbit_pair, ancilla_nbit_or, qbit_pair);
377+ for (int qbit_pair = max_qubits_or - 1 ; qbit_pair >= diff ; qbit_pair-- ) {
378+ bitwise_or (qc, max_reg_or , qbit_pair, min_reg_or , qbit_pair-diff , ancilla_nbit_or, qbit_pair);
323379 }
324380
325381 // OR uncommon bits (case where one register is larger than the other, then OR with zero is simply copying the bit value
326- for (int qbit_cutoff = 0 ; qbit_cutoff < max_qubits_or - min_qubits_or ; qbit_cutoff++) {
382+ for (int qbit_cutoff = 0 ; qbit_cutoff < diff ; qbit_cutoff++) {
327383 qc.cx (max_reg_or->get_qreg (), qbit_cutoff, ancilla_nbit_or->get_qreg (), qbit_cutoff);
328384 }
385+ // END UNCOMPUTATION
329386
387+ // Garbage::get_garbage()->add_garbage(ancilla_mcgate);
388+ // Garbage::get_garbage()->add_garbage(ancilla_nbit_or);
389+
330390 continue ;
331391
332392 }
@@ -342,7 +402,6 @@ void compile_instructions(Circuit& qc, vector<INSTRUCTION> instructions, SymbolT
342402
343403 }
344404
345-
346405 }
347406
348407 else {
@@ -459,7 +518,37 @@ void compile_instructions(Circuit& qc, vector<INSTRUCTION> instructions, SymbolT
459518
460519 }
461520
521+ // compile range operator
522+ else if (type == " :" ) {
523+ // get number or right operand
524+ long long number = stoll (reg1);
525+
526+ // initialize number of qubits to zero
527+ int num_qubits = 0 ;
528+
529+ // check if range is a power-of-two
530+ // in other words, check if log2(number) is an element of the set consisting natural numbers
531+ if (reg0 == " 0" && ceil (log2 (number)) == floor (log2 (number))) {
532+ // set number of qubits
533+ // the reason for this is to only create a superposition of the range desired.
534+ // e.g., a register of 5 qubits but we want a superposition of 0:4
535+ // Therefore, we have to only put the last 2 qubits into superposition
536+ int num_qubits = floor (log2 (number));
537+
538+ // Apply HADAMARD Gate to each qubit we want to be in superpositon
539+ for (int i = (result_reg->get_num_qubits () - num_qubits); i < result_reg->get_num_qubits (); i++) {
540+ qc.h (result_reg->get_qreg (), i);
541+ }
462542
543+ }
544+
545+ // this should be implemented in later versions
546+ // to allow programmer to specify custom range, e.g. (1:100)
547+ else {
548+ int num_qubits = floor (log2 (number)) + 1 ;
549+ // apply operation to procure such a state
550+ }
551+ }
463552 }
464553 }
465554
0 commit comments