@@ -244,6 +244,54 @@ TEST_F(ZXFunctionalityTest, CRZ) {
244244 EXPECT_TRUE (d.connected (d.getInput (0 ), d.getOutput (0 )));
245245}
246246
247+ TEST_F (ZXFunctionalityTest, MultiCZ) {
248+ using namespace qc ::literals;
249+ qc = qc::QuantumComputation (3 );
250+ qc.mcz ({1 , 2 }, 0 );
251+
252+ auto qcPrime = qc::QuantumComputation (3 );
253+ qcPrime.h (0 );
254+ qcPrime.mcx ({1 , 2 }, 0 );
255+ qcPrime.h (0 );
256+
257+ auto d = FunctionalityConstruction::buildFunctionality (&qc);
258+
259+ auto dPrime = FunctionalityConstruction::buildFunctionality (&qcPrime);
260+
261+ d.concat (dPrime.invert ());
262+
263+ fullReduce (d);
264+
265+ EXPECT_TRUE (d.isIdentity ());
266+ EXPECT_TRUE (d.globalPhaseIsZero ());
267+ EXPECT_TRUE (d.connected (d.getInput (0 ), d.getOutput (0 )));
268+ }
269+ TEST_F (ZXFunctionalityTest, CCZ) {
270+ using namespace qc ::literals;
271+ const std::string testfile = " OPENQASM 2.0;"
272+ " include \" qelib1.inc\" ;"
273+ " qreg q[3];"
274+ " ccz q[0],q[1],q[2];\n " ;
275+
276+ qc = qasm3::Importer::imports (testfile);
277+ auto qcPrime = qc::QuantumComputation (3 );
278+ qcPrime.h (0 );
279+ qcPrime.mcx ({1 , 2 }, 0 );
280+ qcPrime.h (0 );
281+
282+ auto d = FunctionalityConstruction::buildFunctionality (&qc);
283+
284+ auto dPrime = FunctionalityConstruction::buildFunctionality (&qcPrime);
285+
286+ d.concat (dPrime.invert ());
287+
288+ fullReduce (d);
289+
290+ EXPECT_TRUE (d.isIdentity ());
291+ EXPECT_TRUE (d.globalPhaseIsZero ());
292+ EXPECT_TRUE (d.connected (d.getInput (0 ), d.getOutput (0 )));
293+ }
294+
247295TEST_F (ZXFunctionalityTest, MultiControlX) {
248296 using namespace qc ::literals;
249297 qc = qc::QuantumComputation (4 );
@@ -333,7 +381,75 @@ TEST_F(ZXFunctionalityTest, MultiControlX1) {
333381 EXPECT_TRUE (d.connected (d.getInput (0 ), d.getOutput (0 )));
334382}
335383
336- TEST_F (ZXFunctionalityTest, MultiCRZ) {
384+ TEST_F (ZXFunctionalityTest, MultiControlZ) {
385+ using namespace qc ::literals;
386+ qc = qc::QuantumComputation (4 );
387+ qc.mcz ({1 , 2 , 3 }, 0 );
388+
389+ auto qcPrime = qc::QuantumComputation (4 );
390+ qcPrime.h (0 );
391+ qcPrime.mcx ({1 , 2 , 3 }, 0 );
392+ qcPrime.h (0 );
393+
394+ auto d = FunctionalityConstruction::buildFunctionality (&qc);
395+
396+ auto dPrime = FunctionalityConstruction::buildFunctionality (&qcPrime);
397+
398+ d.concat (dPrime.invert ());
399+
400+ fullReduce (d);
401+
402+ EXPECT_TRUE (d.isIdentity ());
403+ EXPECT_TRUE (d.globalPhaseIsZero ());
404+ EXPECT_TRUE (d.connected (d.getInput (0 ), d.getOutput (0 )));
405+ EXPECT_TRUE (d.connected (d.getInput (1 ), d.getOutput (1 )));
406+ EXPECT_TRUE (d.connected (d.getInput (2 ), d.getOutput (2 )));
407+ }
408+
409+ TEST_F (ZXFunctionalityTest, MultiControlZ0) {
410+ using namespace qc ::literals;
411+ qc = qc::QuantumComputation (1 );
412+ qc.mcz ({}, 0 );
413+
414+ auto qcPrime = qc::QuantumComputation (1 );
415+ qcPrime.z (0 );
416+
417+ auto d = FunctionalityConstruction::buildFunctionality (&qc);
418+
419+ auto dPrime = FunctionalityConstruction::buildFunctionality (&qcPrime);
420+
421+ d.concat (dPrime.invert ());
422+
423+ fullReduce (d);
424+
425+ EXPECT_TRUE (d.isIdentity ());
426+ EXPECT_TRUE (d.globalPhaseIsZero ());
427+ EXPECT_TRUE (d.connected (d.getInput (0 ), d.getOutput (0 )));
428+ }
429+
430+ TEST_F (ZXFunctionalityTest, MultiControlZ1) {
431+ using namespace qc ::literals;
432+ qc = qc::QuantumComputation (2 );
433+ qc.mcz ({1 }, 0 );
434+
435+ auto qcPrime = qc::QuantumComputation (2 );
436+ qcPrime.cz (1 , 0 );
437+
438+ auto d = FunctionalityConstruction::buildFunctionality (&qc);
439+
440+ auto dPrime = FunctionalityConstruction::buildFunctionality (&qcPrime);
441+
442+ d.concat (dPrime.invert ());
443+
444+ fullReduce (d);
445+
446+ EXPECT_TRUE (d.isIdentity ());
447+ EXPECT_TRUE (d.globalPhaseIsZero ());
448+ EXPECT_TRUE (d.connected (d.getInput (0 ), d.getOutput (0 )));
449+ }
450+
451+
452+ TEST_F (ZXFunctionalityTest, MultiControlRZ) {
337453 using namespace qc ::literals;
338454 qc = qc::QuantumComputation (3 );
339455 qc.mcrz (PI / 4 , {1 , 2 }, 0 );
@@ -348,6 +464,49 @@ TEST_F(ZXFunctionalityTest, MultiCRZ) {
348464 EXPECT_TRUE (d.connected (d.getInput (0 ), d.getOutput (0 )));
349465}
350466
467+ TEST_F (ZXFunctionalityTest, MultiControlRZ0) {
468+ using namespace qc ::literals;
469+ qc = qc::QuantumComputation (1 );
470+ qc.mcrz (PI / 4 , {}, 0 );
471+
472+ auto qcPrime = qc::QuantumComputation (1 );
473+ qcPrime.rz (PI / 4 , 0 );
474+
475+ auto d = FunctionalityConstruction::buildFunctionality (&qc);
476+
477+ auto dPrime = FunctionalityConstruction::buildFunctionality (&qcPrime);
478+
479+ d.concat (dPrime.invert ());
480+
481+ fullReduce (d);
482+
483+ EXPECT_TRUE (d.isIdentity ());
484+ EXPECT_TRUE (d.globalPhaseIsZero ());
485+ EXPECT_TRUE (d.connected (d.getInput (0 ), d.getOutput (0 )));
486+ }
487+
488+ TEST_F (ZXFunctionalityTest, MultiControlRZ1) {
489+ using namespace qc ::literals;
490+ qc = qc::QuantumComputation (2 );
491+ qc.mcrz (PI / 4 , {1 }, 0 );
492+
493+ auto qcPrime = qc::QuantumComputation (2 );
494+ qcPrime.crz (PI / 4 , 1 , 0 );
495+
496+ auto d = FunctionalityConstruction::buildFunctionality (&qc);
497+
498+ auto dPrime = FunctionalityConstruction::buildFunctionality (&qcPrime);
499+
500+ d.concat (dPrime.invert ());
501+
502+ fullReduce (d);
503+
504+ EXPECT_TRUE (d.isIdentity ());
505+ EXPECT_TRUE (d.globalPhaseIsZero ());
506+ EXPECT_TRUE (d.connected (d.getInput (0 ), d.getOutput (0 )));
507+ }
508+
509+
351510TEST_F (ZXFunctionalityTest, UnsupportedControl) {
352511 using namespace qc ::literals;
353512 qc = qc::QuantumComputation (2 );
0 commit comments