From a7ba06ea47c14e1566768a2b87d0b1bbfbbc89dd Mon Sep 17 00:00:00 2001
From: Tianyi Wang <tianyi1.wang@tum.de>
Date: Mon, 15 May 2023 20:39:38 +0200
Subject: [PATCH 01/43] =?UTF-8?q?=E2=9C=85=20add=20Task,=20Executor=20and?=
 =?UTF-8?q?=20Result=20classes?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 include/Executor.hpp         | 19 ++++++++++++++++++
 include/Result.hpp           | 28 ++++++++++++++++++++++++++
 include/ResultBase.hpp       | 22 +++++++++++++++++++++
 include/SimulationTask.hpp   | 17 ++++++++++++++++
 include/Task.hpp             | 15 ++++++++++++++
 include/VerificationTask.hpp | 19 ++++++++++++++++++
 src/CMakeLists.txt           | 38 ++++++++++++++++++++++--------------
 src/Result.cpp               | 18 +++++++++++++++++
 src/SimulationTask.cpp       |  8 ++++++++
 src/VerificationTask.cpp     |  7 +++++++
 10 files changed, 176 insertions(+), 15 deletions(-)
 create mode 100644 include/Executor.hpp
 create mode 100644 include/Result.hpp
 create mode 100644 include/ResultBase.hpp
 create mode 100644 include/SimulationTask.hpp
 create mode 100644 include/Task.hpp
 create mode 100644 include/VerificationTask.hpp
 create mode 100644 src/Result.cpp
 create mode 100644 src/SimulationTask.cpp
 create mode 100644 src/VerificationTask.cpp

diff --git a/include/Executor.hpp b/include/Executor.hpp
new file mode 100644
index 0000000..a64e881
--- /dev/null
+++ b/include/Executor.hpp
@@ -0,0 +1,19 @@
+//
+// Created by Tianyi Wang on 5/14/23.
+//
+
+#ifndef DD_EVAL_EXECUTOR_HPP
+#define DD_EVAL_EXECUTOR_HPP
+
+#endif //DD_EVAL_EXECUTOR_HPP
+
+#include "Task.hpp"
+
+class Executor {
+private:
+    Task *task;
+};
+
+void executeTask(Task *task) {
+    task->execute();
+}
diff --git a/include/Result.hpp b/include/Result.hpp
new file mode 100644
index 0000000..e3aa8fb
--- /dev/null
+++ b/include/Result.hpp
@@ -0,0 +1,28 @@
+//
+// Created by Tianyi Wang on 5/14/23.
+//
+
+#ifndef DD_EVAL_RESULT_HPP
+#define DD_EVAL_RESULT_HPP
+
+
+#include "ResultBase.hpp"
+#include <string>
+#include <nlohmann/json.hpp>
+
+using json = nlohmann::json;
+
+class Result : public ResultBase {
+public:
+    Result(const std::string& name, double value);
+
+    json toJson() const override;
+    std::string toString() const override;
+
+private:
+    std::string name_;
+    double value_;
+};
+
+#endif  // DD_EVAL_RESULT_HPP
+
diff --git a/include/ResultBase.hpp b/include/ResultBase.hpp
new file mode 100644
index 0000000..3fde0c1
--- /dev/null
+++ b/include/ResultBase.hpp
@@ -0,0 +1,22 @@
+//
+// Created by Tianyi Wang on 5/15/23.
+//
+
+#ifndef DD_EVAL_RESULTBASE_HPP
+#define DD_EVAL_RESULTBASE_HPP
+
+#include <nlohmann/json.hpp>
+
+using json = nlohmann::json;
+
+class ResultBase {
+public:
+    virtual ~ResultBase() = default;
+
+    virtual json toJson() const = 0;
+    virtual std::string toString() const = 0;
+};
+
+
+#endif //DD_EVAL_RESULTBASE_HPP
+
diff --git a/include/SimulationTask.hpp b/include/SimulationTask.hpp
new file mode 100644
index 0000000..75da9a4
--- /dev/null
+++ b/include/SimulationTask.hpp
@@ -0,0 +1,17 @@
+//
+// Created by Tianyi Wang on 5/14/23.
+//
+
+#ifndef DD_EVAL_SIMULATIONTASK_HPP
+#define DD_EVAL_SIMULATIONTASK_HPP
+
+#endif //DD_EVAL_SIMULATIONTASK_HPP
+
+#include "Task.hpp"
+
+class SimulationTask : public Task {
+//public:
+//    SimulationTask(QuantumCircuit qc);
+//private:
+//    QuantumCircuit qc_;
+};
\ No newline at end of file
diff --git a/include/Task.hpp b/include/Task.hpp
new file mode 100644
index 0000000..332630b
--- /dev/null
+++ b/include/Task.hpp
@@ -0,0 +1,15 @@
+//
+// Created by Tianyi Wang on 5/14/23.
+//
+
+#ifndef DD_EVAL_TASK_HPP
+#define DD_EVAL_TASK_HPP
+
+#endif //DD_EVAL_TASK_HPP
+
+#include "Result.hpp"
+
+class Task {
+public:
+    virtual Result execute() = 0;
+};
diff --git a/include/VerificationTask.hpp b/include/VerificationTask.hpp
new file mode 100644
index 0000000..702131b
--- /dev/null
+++ b/include/VerificationTask.hpp
@@ -0,0 +1,19 @@
+//
+// Created by Tianyi Wang on 5/14/23.
+//
+
+#ifndef DD_EVAL_VERIFICATIONTASK_HPP
+#define DD_EVAL_VERIFICATIONTASK_HPP
+
+#endif //DD_EVAL_VERIFICATIONTASK_HPP
+
+
+#include "Task.hpp"
+
+class VerificationTask : public Task {
+//public:
+//    VerificationTask(QuantumCircuit qc1, QuantumCircuit qc2);
+//private:
+//    QuantumCircuit qc1_;
+//    QuantumCircuit qc2_;
+};
\ No newline at end of file
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 120ed07..796b04e 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -6,26 +6,34 @@ add_subdirectory("${PROJECT_SOURCE_DIR}/extern/ddsim" "extern/ddsim"
 add_subdirectory("${PROJECT_SOURCE_DIR}/extern/qcec" "extern/qcec"
                  EXCLUDE_FROM_ALL)
 
-# add_library( ${PROJECT_NAME} ${PROJECT_SOURCE_DIR}/include/checker
-# ${PROJECT_SOURCE_DIR}/include/Configuration.hpp
-# ${PROJECT_SOURCE_DIR}/include/EquivalenceCriterion.hpp
-# ${PROJECT_SOURCE_DIR}/include/EquivalenceCheckingManager.hpp
-# ${PROJECT_SOURCE_DIR}/include/ThreadSafeQueue.hpp
-# EquivalenceCheckingManager.cpp checker/EquivalenceChecker.cpp
-# checker/dd/DDEquivalenceChecker.cpp checker/dd/DDConstructionChecker.cpp
-# checker/dd/DDSimulationChecker.cpp checker/dd/DDAlternatingChecker.cpp
-# checker/dd/applicationscheme/GateCostApplicationScheme.cpp
-# checker/dd/simulation/StateGenerator.cpp checker/zx/ZXChecker.cpp)
+if(NOT TARGET nlohmann_json)
+  add_subdirectory("${PROJECT_SOURCE_DIR}/extern/ddsim/extern/qfr/extern/json" "qfr/json"
+                   EXCLUDE_FROM_ALL)
+endif()
 
-add_library(${PROJECT_NAME} INTERFACE)
+if(NOT TARGET ${PROJECT_NAME})
+    add_library(
+        ${PROJECT_NAME}
+        ${PROJECT_SOURCE_DIR}/include/Executor.hpp
+        ${PROJECT_SOURCE_DIR}/include/Result.hpp
+        ${PROJECT_SOURCE_DIR}/include/ResultBase.hpp
+        ${PROJECT_SOURCE_DIR}/include/SimulationTask.hpp
+        ${PROJECT_SOURCE_DIR}/include/Task.hpp
+        ${PROJECT_SOURCE_DIR}/include/VerificationTask.hpp
+        Result.cpp
+        SimulationTask.cpp
+        VerificationTask.cpp)
 
 # set include directories
-target_include_directories(
-  ${PROJECT_NAME} INTERFACE ${PROJECT_SOURCE_DIR}/include
+    target_include_directories(
+        ${PROJECT_NAME} INTERFACE ${PROJECT_SOURCE_DIR}/include
                             ${PROJECT_BINARY_DIR}/include)
 
 # link to the MQT libraries
-target_link_libraries(${PROJECT_NAME} INTERFACE MQT::ddsim MQT::qcec)
+    target_link_libraries(${PROJECT_NAME} INTERFACE MQT::ddsim MQT::qcec)
+
+    target_link_libraries(${PROJECT_NAME} PUBLIC nlohmann_json)
 
 # add MQT alias
-add_library(MQT::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
+    add_library(MQT::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
+endif()
\ No newline at end of file
diff --git a/src/Result.cpp b/src/Result.cpp
new file mode 100644
index 0000000..fb055bc
--- /dev/null
+++ b/src/Result.cpp
@@ -0,0 +1,18 @@
+//
+// Created by Tianyi Wang on 5/14/23.
+//
+
+#include "../include/Result.hpp"
+
+Result::Result(const std::string& name, double value) : name_(name), value_(value) {}
+
+json Result::toJson() const {
+    json resultJson;
+    resultJson["name"] = name_;
+    resultJson["value"] = value_;
+    return resultJson;
+}
+
+std::string Result::toString() const {
+    return toJson().dump();
+}
diff --git a/src/SimulationTask.cpp b/src/SimulationTask.cpp
new file mode 100644
index 0000000..b8d5b1c
--- /dev/null
+++ b/src/SimulationTask.cpp
@@ -0,0 +1,8 @@
+//
+// Created by Tianyi Wang on 5/14/23.
+//
+
+#include "../include/SimulationTask.hpp"
+//take one circuit
+
+
diff --git a/src/VerificationTask.cpp b/src/VerificationTask.cpp
new file mode 100644
index 0000000..f44d834
--- /dev/null
+++ b/src/VerificationTask.cpp
@@ -0,0 +1,7 @@
+//
+// Created by Tianyi Wang on 5/14/23.
+//
+
+#include "../include/VerificationTask.hpp"
+//take two circuits
+

From f13c774f3d289992408ee0c18f484d521c87740f Mon Sep 17 00:00:00 2001
From: "pre-commit-ci[bot]"
 <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Date: Mon, 15 May 2023 18:50:49 +0000
Subject: [PATCH 02/43] =?UTF-8?q?=F0=9F=8E=A8=20pre-commit=20fixes?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 include/Executor.hpp         |  8 +++----
 include/Result.hpp           | 17 +++++++------
 include/ResultBase.hpp       | 10 ++++----
 include/SimulationTask.hpp   | 12 +++++-----
 include/Task.hpp             |  4 ++--
 include/VerificationTask.hpp | 15 ++++++------
 src/CMakeLists.txt           | 46 ++++++++++++++++++------------------
 src/Result.cpp               | 15 ++++++------
 src/SimulationTask.cpp       |  4 +---
 src/VerificationTask.cpp     |  3 +--
 10 files changed, 62 insertions(+), 72 deletions(-)

diff --git a/include/Executor.hpp b/include/Executor.hpp
index a64e881..3af7046 100644
--- a/include/Executor.hpp
+++ b/include/Executor.hpp
@@ -5,15 +5,13 @@
 #ifndef DD_EVAL_EXECUTOR_HPP
 #define DD_EVAL_EXECUTOR_HPP
 
-#endif //DD_EVAL_EXECUTOR_HPP
+#endif // DD_EVAL_EXECUTOR_HPP
 
 #include "Task.hpp"
 
 class Executor {
 private:
-    Task *task;
+  Task* task;
 };
 
-void executeTask(Task *task) {
-    task->execute();
-}
+void executeTask(Task* task) { task->execute(); }
diff --git a/include/Result.hpp b/include/Result.hpp
index e3aa8fb..481184a 100644
--- a/include/Result.hpp
+++ b/include/Result.hpp
@@ -5,24 +5,23 @@
 #ifndef DD_EVAL_RESULT_HPP
 #define DD_EVAL_RESULT_HPP
 
-
 #include "ResultBase.hpp"
-#include <string>
+
 #include <nlohmann/json.hpp>
+#include <string>
 
 using json = nlohmann::json;
 
 class Result : public ResultBase {
 public:
-    Result(const std::string& name, double value);
+  Result(const std::string& name, double value);
 
-    json toJson() const override;
-    std::string toString() const override;
+  json        toJson() const override;
+  std::string toString() const override;
 
 private:
-    std::string name_;
-    double value_;
+  std::string name_;
+  double      value_;
 };
 
-#endif  // DD_EVAL_RESULT_HPP
-
+#endif // DD_EVAL_RESULT_HPP
diff --git a/include/ResultBase.hpp b/include/ResultBase.hpp
index 3fde0c1..71b5c1e 100644
--- a/include/ResultBase.hpp
+++ b/include/ResultBase.hpp
@@ -11,12 +11,10 @@ using json = nlohmann::json;
 
 class ResultBase {
 public:
-    virtual ~ResultBase() = default;
+  virtual ~ResultBase() = default;
 
-    virtual json toJson() const = 0;
-    virtual std::string toString() const = 0;
+  virtual json        toJson() const   = 0;
+  virtual std::string toString() const = 0;
 };
 
-
-#endif //DD_EVAL_RESULTBASE_HPP
-
+#endif // DD_EVAL_RESULTBASE_HPP
diff --git a/include/SimulationTask.hpp b/include/SimulationTask.hpp
index 75da9a4..91e64ec 100644
--- a/include/SimulationTask.hpp
+++ b/include/SimulationTask.hpp
@@ -5,13 +5,13 @@
 #ifndef DD_EVAL_SIMULATIONTASK_HPP
 #define DD_EVAL_SIMULATIONTASK_HPP
 
-#endif //DD_EVAL_SIMULATIONTASK_HPP
+#endif // DD_EVAL_SIMULATIONTASK_HPP
 
 #include "Task.hpp"
 
 class SimulationTask : public Task {
-//public:
-//    SimulationTask(QuantumCircuit qc);
-//private:
-//    QuantumCircuit qc_;
-};
\ No newline at end of file
+  // public:
+  //     SimulationTask(QuantumCircuit qc);
+  // private:
+  //     QuantumCircuit qc_;
+};
diff --git a/include/Task.hpp b/include/Task.hpp
index 332630b..7ce92fb 100644
--- a/include/Task.hpp
+++ b/include/Task.hpp
@@ -5,11 +5,11 @@
 #ifndef DD_EVAL_TASK_HPP
 #define DD_EVAL_TASK_HPP
 
-#endif //DD_EVAL_TASK_HPP
+#endif // DD_EVAL_TASK_HPP
 
 #include "Result.hpp"
 
 class Task {
 public:
-    virtual Result execute() = 0;
+  virtual Result execute() = 0;
 };
diff --git a/include/VerificationTask.hpp b/include/VerificationTask.hpp
index 702131b..1f85666 100644
--- a/include/VerificationTask.hpp
+++ b/include/VerificationTask.hpp
@@ -5,15 +5,14 @@
 #ifndef DD_EVAL_VERIFICATIONTASK_HPP
 #define DD_EVAL_VERIFICATIONTASK_HPP
 
-#endif //DD_EVAL_VERIFICATIONTASK_HPP
-
+#endif // DD_EVAL_VERIFICATIONTASK_HPP
 
 #include "Task.hpp"
 
 class VerificationTask : public Task {
-//public:
-//    VerificationTask(QuantumCircuit qc1, QuantumCircuit qc2);
-//private:
-//    QuantumCircuit qc1_;
-//    QuantumCircuit qc2_;
-};
\ No newline at end of file
+  // public:
+  //     VerificationTask(QuantumCircuit qc1, QuantumCircuit qc2);
+  // private:
+  //     QuantumCircuit qc1_;
+  //     QuantumCircuit qc2_;
+};
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 796b04e..25131aa 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -7,33 +7,33 @@ add_subdirectory("${PROJECT_SOURCE_DIR}/extern/qcec" "extern/qcec"
                  EXCLUDE_FROM_ALL)
 
 if(NOT TARGET nlohmann_json)
-  add_subdirectory("${PROJECT_SOURCE_DIR}/extern/ddsim/extern/qfr/extern/json" "qfr/json"
-                   EXCLUDE_FROM_ALL)
+  add_subdirectory("${PROJECT_SOURCE_DIR}/extern/ddsim/extern/qfr/extern/json"
+                   "qfr/json" EXCLUDE_FROM_ALL)
 endif()
 
 if(NOT TARGET ${PROJECT_NAME})
-    add_library(
-        ${PROJECT_NAME}
-        ${PROJECT_SOURCE_DIR}/include/Executor.hpp
-        ${PROJECT_SOURCE_DIR}/include/Result.hpp
-        ${PROJECT_SOURCE_DIR}/include/ResultBase.hpp
-        ${PROJECT_SOURCE_DIR}/include/SimulationTask.hpp
-        ${PROJECT_SOURCE_DIR}/include/Task.hpp
-        ${PROJECT_SOURCE_DIR}/include/VerificationTask.hpp
-        Result.cpp
-        SimulationTask.cpp
-        VerificationTask.cpp)
+  add_library(
+    ${PROJECT_NAME}
+    ${PROJECT_SOURCE_DIR}/include/Executor.hpp
+    ${PROJECT_SOURCE_DIR}/include/Result.hpp
+    ${PROJECT_SOURCE_DIR}/include/ResultBase.hpp
+    ${PROJECT_SOURCE_DIR}/include/SimulationTask.hpp
+    ${PROJECT_SOURCE_DIR}/include/Task.hpp
+    ${PROJECT_SOURCE_DIR}/include/VerificationTask.hpp
+    Result.cpp
+    SimulationTask.cpp
+    VerificationTask.cpp)
 
-# set include directories
-    target_include_directories(
-        ${PROJECT_NAME} INTERFACE ${PROJECT_SOURCE_DIR}/include
-                            ${PROJECT_BINARY_DIR}/include)
+  # set include directories
+  target_include_directories(
+    ${PROJECT_NAME} INTERFACE ${PROJECT_SOURCE_DIR}/include
+                              ${PROJECT_BINARY_DIR}/include)
 
-# link to the MQT libraries
-    target_link_libraries(${PROJECT_NAME} INTERFACE MQT::ddsim MQT::qcec)
+  # link to the MQT libraries
+  target_link_libraries(${PROJECT_NAME} INTERFACE MQT::ddsim MQT::qcec)
 
-    target_link_libraries(${PROJECT_NAME} PUBLIC nlohmann_json)
+  target_link_libraries(${PROJECT_NAME} PUBLIC nlohmann_json)
 
-# add MQT alias
-    add_library(MQT::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
-endif()
\ No newline at end of file
+  # add MQT alias
+  add_library(MQT::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
+endif()
diff --git a/src/Result.cpp b/src/Result.cpp
index fb055bc..a317706 100644
--- a/src/Result.cpp
+++ b/src/Result.cpp
@@ -4,15 +4,14 @@
 
 #include "../include/Result.hpp"
 
-Result::Result(const std::string& name, double value) : name_(name), value_(value) {}
+Result::Result(const std::string& name, double value)
+    : name_(name), value_(value) {}
 
 json Result::toJson() const {
-    json resultJson;
-    resultJson["name"] = name_;
-    resultJson["value"] = value_;
-    return resultJson;
+  json resultJson;
+  resultJson["name"]  = name_;
+  resultJson["value"] = value_;
+  return resultJson;
 }
 
-std::string Result::toString() const {
-    return toJson().dump();
-}
+std::string Result::toString() const { return toJson().dump(); }
diff --git a/src/SimulationTask.cpp b/src/SimulationTask.cpp
index b8d5b1c..ffd5b0b 100644
--- a/src/SimulationTask.cpp
+++ b/src/SimulationTask.cpp
@@ -3,6 +3,4 @@
 //
 
 #include "../include/SimulationTask.hpp"
-//take one circuit
-
-
+// take one circuit
diff --git a/src/VerificationTask.cpp b/src/VerificationTask.cpp
index f44d834..a6a95b4 100644
--- a/src/VerificationTask.cpp
+++ b/src/VerificationTask.cpp
@@ -3,5 +3,4 @@
 //
 
 #include "../include/VerificationTask.hpp"
-//take two circuits
-
+// take two circuits

From 5b501eaccc5a6f54ba1bfeba36d2c98c166d4cbc Mon Sep 17 00:00:00 2001
From: Tianyi Wang <tianyi1.wang@tum.de>
Date: Tue, 16 May 2023 17:33:21 +0200
Subject: [PATCH 03/43] First review suggestions taken

---
 include/Executor.hpp         | 28 +++++++++++++++-------------
 include/Result.hpp           | 28 ----------------------------
 include/ResultBase.hpp       | 22 ----------------------
 include/Results.hpp          | 23 +++++++++++++++++++++++
 include/SimulationTask.hpp   | 22 +++++++++-------------
 include/Task.hpp             | 14 +++++---------
 include/VerificationTask.hpp | 26 +++++++++++---------------
 src/CMakeLists.txt           | 17 +++++------------
 src/Executor.cpp             | 32 ++++++++++++++++++++++++++++++++
 src/SimulationTask.cpp       |  6 +-----
 src/VerificationTask.cpp     |  6 +-----
 11 files changed, 102 insertions(+), 122 deletions(-)
 delete mode 100644 include/Result.hpp
 delete mode 100644 include/ResultBase.hpp
 create mode 100644 include/Results.hpp
 create mode 100644 src/Executor.cpp

diff --git a/include/Executor.hpp b/include/Executor.hpp
index a64e881..16f355a 100644
--- a/include/Executor.hpp
+++ b/include/Executor.hpp
@@ -1,19 +1,21 @@
-//
-// Created by Tianyi Wang on 5/14/23.
-//
-
-#ifndef DD_EVAL_EXECUTOR_HPP
-#define DD_EVAL_EXECUTOR_HPP
-
-#endif //DD_EVAL_EXECUTOR_HPP
+#pragma once
 
 #include "Task.hpp"
+#include <memory>
+
 
 class Executor {
+public:
+    virtual ~Executor() = default;
+    virtual json executeTask() = 0;
+
+    const std::shared_ptr<Task> &getTask() const;
+
+    explicit Executor(){
+    };
+
+    void setTask(const std::shared_ptr<Task> &task);
+    virtual std::string getIdentifier() = 0;
 private:
-    Task *task;
+    std::shared_ptr<Task> task;
 };
-
-void executeTask(Task *task) {
-    task->execute();
-}
diff --git a/include/Result.hpp b/include/Result.hpp
deleted file mode 100644
index e3aa8fb..0000000
--- a/include/Result.hpp
+++ /dev/null
@@ -1,28 +0,0 @@
-//
-// Created by Tianyi Wang on 5/14/23.
-//
-
-#ifndef DD_EVAL_RESULT_HPP
-#define DD_EVAL_RESULT_HPP
-
-
-#include "ResultBase.hpp"
-#include <string>
-#include <nlohmann/json.hpp>
-
-using json = nlohmann::json;
-
-class Result : public ResultBase {
-public:
-    Result(const std::string& name, double value);
-
-    json toJson() const override;
-    std::string toString() const override;
-
-private:
-    std::string name_;
-    double value_;
-};
-
-#endif  // DD_EVAL_RESULT_HPP
-
diff --git a/include/ResultBase.hpp b/include/ResultBase.hpp
deleted file mode 100644
index 3fde0c1..0000000
--- a/include/ResultBase.hpp
+++ /dev/null
@@ -1,22 +0,0 @@
-//
-// Created by Tianyi Wang on 5/15/23.
-//
-
-#ifndef DD_EVAL_RESULTBASE_HPP
-#define DD_EVAL_RESULTBASE_HPP
-
-#include <nlohmann/json.hpp>
-
-using json = nlohmann::json;
-
-class ResultBase {
-public:
-    virtual ~ResultBase() = default;
-
-    virtual json toJson() const = 0;
-    virtual std::string toString() const = 0;
-};
-
-
-#endif //DD_EVAL_RESULTBASE_HPP
-
diff --git a/include/Results.hpp b/include/Results.hpp
new file mode 100644
index 0000000..7b7e2dc
--- /dev/null
+++ b/include/Results.hpp
@@ -0,0 +1,23 @@
+#pragma once
+
+#include <nlohmann/json.hpp>
+#include "Task.hpp"
+#include "Executor.hpp"
+
+using json = nlohmann::json;
+
+class Results {
+public:
+    virtual ~Results() = default;
+
+    virtual json toJson() const = 0;
+    virtual std::string toString() const { return toJson().dump(2); }
+
+    Results(Task task, Executor executor) {
+        identifier = task.getIdentifier() + "_" + executor.getIdentifier();
+    }
+
+
+private:
+    std::string identifier;
+};
diff --git a/include/SimulationTask.hpp b/include/SimulationTask.hpp
index 75da9a4..8601070 100644
--- a/include/SimulationTask.hpp
+++ b/include/SimulationTask.hpp
@@ -1,17 +1,13 @@
-//
-// Created by Tianyi Wang on 5/14/23.
-//
-
-#ifndef DD_EVAL_SIMULATIONTASK_HPP
-#define DD_EVAL_SIMULATIONTASK_HPP
-
-#endif //DD_EVAL_SIMULATIONTASK_HPP
+#pragma once
 
 #include "Task.hpp"
+#include "QuantumComputation.hpp"
 
 class SimulationTask : public Task {
-//public:
-//    SimulationTask(QuantumCircuit qc);
-//private:
-//    QuantumCircuit qc_;
-};
\ No newline at end of file
+public:
+    explicit SimulationTask(qc::QuantumComputation qc) {
+        this->qc = qc.clone();
+    };
+private:
+    qc::QuantumComputation qc;
+};
diff --git a/include/Task.hpp b/include/Task.hpp
index 332630b..9c36667 100644
--- a/include/Task.hpp
+++ b/include/Task.hpp
@@ -1,15 +1,11 @@
-//
-// Created by Tianyi Wang on 5/14/23.
-//
+#pragma once
 
-#ifndef DD_EVAL_TASK_HPP
-#define DD_EVAL_TASK_HPP
+#include <nlohmann/json.hpp>
 
-#endif //DD_EVAL_TASK_HPP
-
-#include "Result.hpp"
+using json = nlohmann::json;
 
 class Task {
 public:
-    virtual Result execute() = 0;
+    virtual ~Task() = default;
+    virtual std::string getIdentifier() = 0;
 };
diff --git a/include/VerificationTask.hpp b/include/VerificationTask.hpp
index 702131b..79ae39d 100644
--- a/include/VerificationTask.hpp
+++ b/include/VerificationTask.hpp
@@ -1,19 +1,15 @@
-//
-// Created by Tianyi Wang on 5/14/23.
-//
-
-#ifndef DD_EVAL_VERIFICATIONTASK_HPP
-#define DD_EVAL_VERIFICATIONTASK_HPP
-
-#endif //DD_EVAL_VERIFICATIONTASK_HPP
-
+#pragma once
 
 #include "Task.hpp"
+#include "QuantumComputation.hpp"
 
 class VerificationTask : public Task {
-//public:
-//    VerificationTask(QuantumCircuit qc1, QuantumCircuit qc2);
-//private:
-//    QuantumCircuit qc1_;
-//    QuantumCircuit qc2_;
-};
\ No newline at end of file
+public:
+    VerificationTask(qc::QuantumComputation qc1, qc::QuantumComputation qc2) {
+        this->qc1 = qc1.clone();
+        this->qc2 = qc2.clone();
+    };
+private:
+    qc::QuantumComputation qc1;
+    qc::QuantumComputation qc2;
+};
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 796b04e..b2c6cd2 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -6,33 +6,26 @@ add_subdirectory("${PROJECT_SOURCE_DIR}/extern/ddsim" "extern/ddsim"
 add_subdirectory("${PROJECT_SOURCE_DIR}/extern/qcec" "extern/qcec"
                  EXCLUDE_FROM_ALL)
 
-if(NOT TARGET nlohmann_json)
-  add_subdirectory("${PROJECT_SOURCE_DIR}/extern/ddsim/extern/qfr/extern/json" "qfr/json"
-                   EXCLUDE_FROM_ALL)
-endif()
-
 if(NOT TARGET ${PROJECT_NAME})
     add_library(
         ${PROJECT_NAME}
         ${PROJECT_SOURCE_DIR}/include/Executor.hpp
-        ${PROJECT_SOURCE_DIR}/include/Result.hpp
-        ${PROJECT_SOURCE_DIR}/include/ResultBase.hpp
+            ${PROJECT_SOURCE_DIR}/include/Results.hpp
         ${PROJECT_SOURCE_DIR}/include/SimulationTask.hpp
         ${PROJECT_SOURCE_DIR}/include/Task.hpp
         ${PROJECT_SOURCE_DIR}/include/VerificationTask.hpp
         Result.cpp
         SimulationTask.cpp
-        VerificationTask.cpp)
+        VerificationTask.cpp
+        Executor.cpp CircuitSimulatorExecutor.cpp ../include/CircuitSimulatorExecutor.hpp VerificationExecutor.cpp ../include/VerificationExecutor.hpp AlternatingVerificationExecutor.cpp ../include/AlternatingVerificationExecutor.hpp)
 
 # set include directories
     target_include_directories(
-        ${PROJECT_NAME} INTERFACE ${PROJECT_SOURCE_DIR}/include
+        ${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR}/include
                             ${PROJECT_BINARY_DIR}/include)
 
 # link to the MQT libraries
-    target_link_libraries(${PROJECT_NAME} INTERFACE MQT::ddsim MQT::qcec)
-
-    target_link_libraries(${PROJECT_NAME} PUBLIC nlohmann_json)
+    target_link_libraries(${PROJECT_NAME} PUBLIC MQT::ddsim MQT::qcec)
 
 # add MQT alias
     add_library(MQT::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
diff --git a/src/Executor.cpp b/src/Executor.cpp
new file mode 100644
index 0000000..4f153c9
--- /dev/null
+++ b/src/Executor.cpp
@@ -0,0 +1,32 @@
+#include "Executor.hpp"
+#include <chrono>
+
+class Executor::Executor {
+    json executeTask() {
+        json result;
+        auto start = std::chrono::high_resolution_clock::now();
+
+        this->executeTask();
+        // Add memory usage later
+
+        auto stop = std::chrono::high_resolution_clock::now();
+        auto runtime = std::chrono::duration_cast<std::chrono::microseconds>(stop-start);
+        result["runtime"] = runtime.count();
+        std::string const identifier = this->getTask()->getIdentifier() + "_" + this->getIdentifier();
+        result["identifier"] = identifier;
+        return result;
+        // what about the Results class?
+    }
+};
+
+//add adapter for simulators
+const std::shared_ptr<Task> &Executor::getTask() const {
+    return task;
+}
+
+void Executor::setTask(const std::shared_ptr<Task> &newTask) {
+    this->task = newTask;
+}
+
+
+
diff --git a/src/SimulationTask.cpp b/src/SimulationTask.cpp
index b8d5b1c..0daaecf 100644
--- a/src/SimulationTask.cpp
+++ b/src/SimulationTask.cpp
@@ -1,8 +1,4 @@
-//
-// Created by Tianyi Wang on 5/14/23.
-//
-
-#include "../include/SimulationTask.hpp"
+#include "SimulationTask.hpp"
 //take one circuit
 
 
diff --git a/src/VerificationTask.cpp b/src/VerificationTask.cpp
index f44d834..eb48d02 100644
--- a/src/VerificationTask.cpp
+++ b/src/VerificationTask.cpp
@@ -1,7 +1,3 @@
-//
-// Created by Tianyi Wang on 5/14/23.
-//
-
-#include "../include/VerificationTask.hpp"
+#include "VerificationTask.hpp"
 //take two circuits
 

From ce8ba49ab95298a16d5c04541f856a195da8c89b Mon Sep 17 00:00:00 2001
From: "pre-commit-ci[bot]"
 <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Date: Tue, 16 May 2023 15:35:36 +0000
Subject: [PATCH 04/43] =?UTF-8?q?=F0=9F=8E=A8=20pre-commit=20fixes?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 include/Executor.hpp         | 18 +++++++-------
 include/Results.hpp          | 20 ++++++++--------
 include/SimulationTask.hpp   |  9 ++++---
 include/Task.hpp             |  4 ++--
 include/VerificationTask.hpp | 15 ++++++------
 src/CMakeLists.txt           | 44 +++++++++++++++++++---------------
 src/Executor.cpp             | 46 +++++++++++++++++-------------------
 src/SimulationTask.cpp       |  2 +-
 src/VerificationTask.cpp     |  2 +-
 9 files changed, 82 insertions(+), 78 deletions(-)

diff --git a/include/Executor.hpp b/include/Executor.hpp
index 16f355a..d1cd51f 100644
--- a/include/Executor.hpp
+++ b/include/Executor.hpp
@@ -1,21 +1,21 @@
 #pragma once
 
 #include "Task.hpp"
-#include <memory>
 
+#include <memory>
 
 class Executor {
 public:
-    virtual ~Executor() = default;
-    virtual json executeTask() = 0;
+  virtual ~Executor()        = default;
+  virtual json executeTask() = 0;
+
+  const std::shared_ptr<Task>& getTask() const;
 
-    const std::shared_ptr<Task> &getTask() const;
+  explicit Executor(){};
 
-    explicit Executor(){
-    };
+  void                setTask(const std::shared_ptr<Task>& task);
+  virtual std::string getIdentifier() = 0;
 
-    void setTask(const std::shared_ptr<Task> &task);
-    virtual std::string getIdentifier() = 0;
 private:
-    std::shared_ptr<Task> task;
+  std::shared_ptr<Task> task;
 };
diff --git a/include/Results.hpp b/include/Results.hpp
index 7b7e2dc..4f74340 100644
--- a/include/Results.hpp
+++ b/include/Results.hpp
@@ -1,23 +1,23 @@
 #pragma once
 
-#include <nlohmann/json.hpp>
-#include "Task.hpp"
 #include "Executor.hpp"
+#include "Task.hpp"
+
+#include <nlohmann/json.hpp>
 
 using json = nlohmann::json;
 
 class Results {
 public:
-    virtual ~Results() = default;
-
-    virtual json toJson() const = 0;
-    virtual std::string toString() const { return toJson().dump(2); }
+  virtual ~Results() = default;
 
-    Results(Task task, Executor executor) {
-        identifier = task.getIdentifier() + "_" + executor.getIdentifier();
-    }
+  virtual json        toJson() const = 0;
+  virtual std::string toString() const { return toJson().dump(2); }
 
+  Results(Task task, Executor executor) {
+    identifier = task.getIdentifier() + "_" + executor.getIdentifier();
+  }
 
 private:
-    std::string identifier;
+  std::string identifier;
 };
diff --git a/include/SimulationTask.hpp b/include/SimulationTask.hpp
index 8601070..6dbd207 100644
--- a/include/SimulationTask.hpp
+++ b/include/SimulationTask.hpp
@@ -1,13 +1,12 @@
 #pragma once
 
-#include "Task.hpp"
 #include "QuantumComputation.hpp"
+#include "Task.hpp"
 
 class SimulationTask : public Task {
 public:
-    explicit SimulationTask(qc::QuantumComputation qc) {
-        this->qc = qc.clone();
-    };
+  explicit SimulationTask(qc::QuantumComputation qc) { this->qc = qc.clone(); };
+
 private:
-    qc::QuantumComputation qc;
+  qc::QuantumComputation qc;
 };
diff --git a/include/Task.hpp b/include/Task.hpp
index 9c36667..2085fc6 100644
--- a/include/Task.hpp
+++ b/include/Task.hpp
@@ -6,6 +6,6 @@ using json = nlohmann::json;
 
 class Task {
 public:
-    virtual ~Task() = default;
-    virtual std::string getIdentifier() = 0;
+  virtual ~Task()                     = default;
+  virtual std::string getIdentifier() = 0;
 };
diff --git a/include/VerificationTask.hpp b/include/VerificationTask.hpp
index 79ae39d..795362a 100644
--- a/include/VerificationTask.hpp
+++ b/include/VerificationTask.hpp
@@ -1,15 +1,16 @@
 #pragma once
 
-#include "Task.hpp"
 #include "QuantumComputation.hpp"
+#include "Task.hpp"
 
 class VerificationTask : public Task {
 public:
-    VerificationTask(qc::QuantumComputation qc1, qc::QuantumComputation qc2) {
-        this->qc1 = qc1.clone();
-        this->qc2 = qc2.clone();
-    };
+  VerificationTask(qc::QuantumComputation qc1, qc::QuantumComputation qc2) {
+    this->qc1 = qc1.clone();
+    this->qc2 = qc2.clone();
+  };
+
 private:
-    qc::QuantumComputation qc1;
-    qc::QuantumComputation qc2;
+  qc::QuantumComputation qc1;
+  qc::QuantumComputation qc2;
 };
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 1f3f565..3c09bdd 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -7,26 +7,32 @@ add_subdirectory("${PROJECT_SOURCE_DIR}/extern/qcec" "extern/qcec"
                  EXCLUDE_FROM_ALL)
 
 if(NOT TARGET ${PROJECT_NAME})
-    add_library(
-        ${PROJECT_NAME}
-        ${PROJECT_SOURCE_DIR}/include/Executor.hpp
-            ${PROJECT_SOURCE_DIR}/include/Results.hpp
-        ${PROJECT_SOURCE_DIR}/include/SimulationTask.hpp
-        ${PROJECT_SOURCE_DIR}/include/Task.hpp
-        ${PROJECT_SOURCE_DIR}/include/VerificationTask.hpp
-        Result.cpp
-        SimulationTask.cpp
-        VerificationTask.cpp
-        Executor.cpp CircuitSimulatorExecutor.cpp ../include/CircuitSimulatorExecutor.hpp VerificationExecutor.cpp ../include/VerificationExecutor.hpp AlternatingVerificationExecutor.cpp ../include/AlternatingVerificationExecutor.hpp)
+  add_library(
+    ${PROJECT_NAME}
+    ${PROJECT_SOURCE_DIR}/include/Executor.hpp
+    ${PROJECT_SOURCE_DIR}/include/Results.hpp
+    ${PROJECT_SOURCE_DIR}/include/SimulationTask.hpp
+    ${PROJECT_SOURCE_DIR}/include/Task.hpp
+    ${PROJECT_SOURCE_DIR}/include/VerificationTask.hpp
+    Result.cpp
+    SimulationTask.cpp
+    VerificationTask.cpp
+    Executor.cpp
+    CircuitSimulatorExecutor.cpp
+    ../include/CircuitSimulatorExecutor.hpp
+    VerificationExecutor.cpp
+    ../include/VerificationExecutor.hpp
+    AlternatingVerificationExecutor.cpp
+    ../include/AlternatingVerificationExecutor.hpp)
 
-# set include directories
-    target_include_directories(
-        ${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR}/include
-                            ${PROJECT_BINARY_DIR}/include)
+  # set include directories
+  target_include_directories(
+    ${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR}/include
+                           ${PROJECT_BINARY_DIR}/include)
 
-# link to the MQT libraries
-    target_link_libraries(${PROJECT_NAME} PUBLIC MQT::ddsim MQT::qcec)
+  # link to the MQT libraries
+  target_link_libraries(${PROJECT_NAME} PUBLIC MQT::ddsim MQT::qcec)
 
-# add MQT alias
-    add_library(MQT::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
+  # add MQT alias
+  add_library(MQT::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
 endif()
diff --git a/src/Executor.cpp b/src/Executor.cpp
index 4f153c9..f6ea61d 100644
--- a/src/Executor.cpp
+++ b/src/Executor.cpp
@@ -1,32 +1,30 @@
 #include "Executor.hpp"
+
 #include <chrono>
 
 class Executor::Executor {
-    json executeTask() {
-        json result;
-        auto start = std::chrono::high_resolution_clock::now();
-
-        this->executeTask();
-        // Add memory usage later
-
-        auto stop = std::chrono::high_resolution_clock::now();
-        auto runtime = std::chrono::duration_cast<std::chrono::microseconds>(stop-start);
-        result["runtime"] = runtime.count();
-        std::string const identifier = this->getTask()->getIdentifier() + "_" + this->getIdentifier();
-        result["identifier"] = identifier;
-        return result;
-        // what about the Results class?
-    }
+  json executeTask() {
+    json result;
+    auto start = std::chrono::high_resolution_clock::now();
+
+    this->executeTask();
+    // Add memory usage later
+
+    auto stop = std::chrono::high_resolution_clock::now();
+    auto runtime =
+        std::chrono::duration_cast<std::chrono::microseconds>(stop - start);
+    result["runtime"] = runtime.count();
+    std::string const identifier =
+        this->getTask()->getIdentifier() + "_" + this->getIdentifier();
+    result["identifier"] = identifier;
+    return result;
+    // what about the Results class?
+  }
 };
 
-//add adapter for simulators
-const std::shared_ptr<Task> &Executor::getTask() const {
-    return task;
-}
+// add adapter for simulators
+const std::shared_ptr<Task>& Executor::getTask() const { return task; }
 
-void Executor::setTask(const std::shared_ptr<Task> &newTask) {
-    this->task = newTask;
+void Executor::setTask(const std::shared_ptr<Task>& newTask) {
+  this->task = newTask;
 }
-
-
-
diff --git a/src/SimulationTask.cpp b/src/SimulationTask.cpp
index 7ddfdf6..2d38955 100644
--- a/src/SimulationTask.cpp
+++ b/src/SimulationTask.cpp
@@ -1,2 +1,2 @@
 #include "SimulationTask.hpp"
-//take one circuit
+// take one circuit
diff --git a/src/VerificationTask.cpp b/src/VerificationTask.cpp
index 935567b..9d76be3 100644
--- a/src/VerificationTask.cpp
+++ b/src/VerificationTask.cpp
@@ -1,2 +1,2 @@
 #include "VerificationTask.hpp"
-//take two circuits
+// take two circuits

From 3db7fe5e454464a7d9f8f33b3323e55ec073447c Mon Sep 17 00:00:00 2001
From: Tianyi Wang <tianyi1.wang@tum.de>
Date: Fri, 19 May 2023 01:16:32 +0200
Subject: [PATCH 05/43] Refactored executor-task architecture

---
 include/AlternatingVerificationExecutor.hpp |  5 +++
 include/CircuitSimulatorExecutor.hpp        |  5 +++
 include/Executor.hpp                        | 11 +++---
 include/SimulationExecutor.hpp              | 12 +++++++
 include/VerificationExecutor.hpp            | 12 +++++++
 src/AlternatingVerificationExecutor.cpp     |  1 +
 src/CMakeLists.txt                          | 18 +++++-----
 src/CircuitSimulatorExecutor.cpp            |  1 +
 src/Executor.cpp                            |  8 +++--
 src/Result.cpp                              | 38 ++++++++++++++-------
 src/SimulationExecutor.cpp                  |  3 ++
 src/VerificationExecutor.cpp                |  3 ++
 12 files changed, 86 insertions(+), 31 deletions(-)
 create mode 100644 include/AlternatingVerificationExecutor.hpp
 create mode 100644 include/CircuitSimulatorExecutor.hpp
 create mode 100644 include/SimulationExecutor.hpp
 create mode 100644 include/VerificationExecutor.hpp
 create mode 100644 src/AlternatingVerificationExecutor.cpp
 create mode 100644 src/CircuitSimulatorExecutor.cpp
 create mode 100644 src/SimulationExecutor.cpp
 create mode 100644 src/VerificationExecutor.cpp

diff --git a/include/AlternatingVerificationExecutor.hpp b/include/AlternatingVerificationExecutor.hpp
new file mode 100644
index 0000000..4fa2263
--- /dev/null
+++ b/include/AlternatingVerificationExecutor.hpp
@@ -0,0 +1,5 @@
+#pragma once
+
+#include "VerificationExecutor.hpp"
+
+class AlternatingVerificationExecutor : public VerificationExecutor {};
diff --git a/include/CircuitSimulatorExecutor.hpp b/include/CircuitSimulatorExecutor.hpp
new file mode 100644
index 0000000..cc82af1
--- /dev/null
+++ b/include/CircuitSimulatorExecutor.hpp
@@ -0,0 +1,5 @@
+#pragma once
+
+#include "SimulationExecutor.hpp"
+
+class CircuitSimulatorExecutor : public SimulationExecutor {};
diff --git a/include/Executor.hpp b/include/Executor.hpp
index d1cd51f..a11eabb 100644
--- a/include/Executor.hpp
+++ b/include/Executor.hpp
@@ -8,13 +8,10 @@ class Executor {
 public:
   virtual ~Executor()        = default;
   virtual json executeTask() = 0;
-
-  const std::shared_ptr<Task>& getTask() const;
-
-  explicit Executor(){};
-
-  void                setTask(const std::shared_ptr<Task>& task);
-  virtual std::string getIdentifier() = 0;
+  explicit Executor()        = default;
+  const std::shared_ptr<Task>& getTask();
+  void                         setTask(const std::shared_ptr<Task>& task);
+  virtual std::string          getIdentifier() = 0;
 
 private:
   std::shared_ptr<Task> task;
diff --git a/include/SimulationExecutor.hpp b/include/SimulationExecutor.hpp
new file mode 100644
index 0000000..f2c3c14
--- /dev/null
+++ b/include/SimulationExecutor.hpp
@@ -0,0 +1,12 @@
+#pragma once
+
+#include "Executor.hpp"
+#include "SimulationTask.hpp"
+
+class SimulationExecutor : public Executor {
+public:
+  explicit SimulationExecutor(const std::shared_ptr<SimulationTask>& task) {
+    setTask(task);
+  };
+  json executeTask() override;
+};
diff --git a/include/VerificationExecutor.hpp b/include/VerificationExecutor.hpp
new file mode 100644
index 0000000..bcfe9a4
--- /dev/null
+++ b/include/VerificationExecutor.hpp
@@ -0,0 +1,12 @@
+#pragma once
+
+#include "Executor.hpp"
+#include "VerificationTask.hpp"
+
+class VerificationExecutor : public Executor {
+public:
+  explicit VerificationExecutor(const std::shared_ptr<VerificationTask>& task) {
+    setTask(task);
+  };
+  json executeTask() override;
+};
diff --git a/src/AlternatingVerificationExecutor.cpp b/src/AlternatingVerificationExecutor.cpp
new file mode 100644
index 0000000..d3d1834
--- /dev/null
+++ b/src/AlternatingVerificationExecutor.cpp
@@ -0,0 +1 @@
+#include "AlternatingVerificationExecutor.hpp"
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 3c09bdd..e1b6044 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -10,20 +10,22 @@ if(NOT TARGET ${PROJECT_NAME})
   add_library(
     ${PROJECT_NAME}
     ${PROJECT_SOURCE_DIR}/include/Executor.hpp
-    ${PROJECT_SOURCE_DIR}/include/Results.hpp
-    ${PROJECT_SOURCE_DIR}/include/SimulationTask.hpp
+    ${PROJECT_SOURCE_DIR}/include/SimulationExecutor.hpp
+    ${PROJECT_SOURCE_DIR}/include/VerificationExecutor.hpp
+    ${PROJECT_SOURCE_DIR}/include/CircuitSimulatorExecutor.hpp
+    ${PROJECT_SOURCE_DIR}/include/AlternatingVerificationExecutor.hpp
+    # ${PROJECT_SOURCE_DIR}/include/Results.hpp
     ${PROJECT_SOURCE_DIR}/include/Task.hpp
+    ${PROJECT_SOURCE_DIR}/include/SimulationTask.hpp
     ${PROJECT_SOURCE_DIR}/include/VerificationTask.hpp
-    Result.cpp
-    SimulationTask.cpp
-    VerificationTask.cpp
+    # Result.cpp
     Executor.cpp
+    SimulationExecutor.cpp
     CircuitSimulatorExecutor.cpp
-    ../include/CircuitSimulatorExecutor.hpp
     VerificationExecutor.cpp
-    ../include/VerificationExecutor.hpp
     AlternatingVerificationExecutor.cpp
-    ../include/AlternatingVerificationExecutor.hpp)
+    SimulationTask.cpp
+    VerificationTask.cpp)
 
   # set include directories
   target_include_directories(
diff --git a/src/CircuitSimulatorExecutor.cpp b/src/CircuitSimulatorExecutor.cpp
new file mode 100644
index 0000000..ce98a6e
--- /dev/null
+++ b/src/CircuitSimulatorExecutor.cpp
@@ -0,0 +1 @@
+#include "CircuitSimulatorExecutor.hpp"
diff --git a/src/Executor.cpp b/src/Executor.cpp
index f6ea61d..72f865f 100644
--- a/src/Executor.cpp
+++ b/src/Executor.cpp
@@ -7,8 +7,9 @@ class Executor::Executor {
     json result;
     auto start = std::chrono::high_resolution_clock::now();
 
-    this->executeTask();
-    // Add memory usage later
+    //    this->executeTask();
+    // execute the actual task
+    // Add memory usage
 
     auto stop = std::chrono::high_resolution_clock::now();
     auto runtime =
@@ -23,8 +24,9 @@ class Executor::Executor {
 };
 
 // add adapter for simulators
-const std::shared_ptr<Task>& Executor::getTask() const { return task; }
 
 void Executor::setTask(const std::shared_ptr<Task>& newTask) {
   this->task = newTask;
 }
+
+const std::shared_ptr<Task>& Executor::getTask() { return task; }
diff --git a/src/Result.cpp b/src/Result.cpp
index a317706..fef28a5 100644
--- a/src/Result.cpp
+++ b/src/Result.cpp
@@ -1,17 +1,29 @@
+// #include "Result.hpp"
+
+// Result::Result(const std::string& name, double value) : name_(name),
+// value_(value) {}
 //
-// Created by Tianyi Wang on 5/14/23.
+// json Result::toJson() const {
+//     json resultJson;
+//     resultJson["name"] = name_;
+//     resultJson["value"] = value_;
+//     return resultJson;
+// }
 //
+// std::string Result::toString() const {
+//     return toJson().dump();
+// }
 
-#include "../include/Result.hpp"
-
-Result::Result(const std::string& name, double value)
-    : name_(name), value_(value) {}
-
-json Result::toJson() const {
-  json resultJson;
-  resultJson["name"]  = name_;
-  resultJson["value"] = value_;
-  return resultJson;
-}
+#include "Results.hpp"
 
-std::string Result::toString() const { return toJson().dump(); }
+// Results::Results(const std::string& name, double value)
+//     : name_(name), value_(value) {}
+//
+// json Result::toJson() const {
+//   json resultJson;
+//   resultJson["name"]  = name_;
+//   resultJson["value"] = value_;
+//   return resultJson;
+// }
+//
+// std::string Result::toString() const { return toJson().dump(); }
diff --git a/src/SimulationExecutor.cpp b/src/SimulationExecutor.cpp
new file mode 100644
index 0000000..5acc2ab
--- /dev/null
+++ b/src/SimulationExecutor.cpp
@@ -0,0 +1,3 @@
+#include "../include/SimulationExecutor.hpp"
+
+json SimulationExecutor::executeTask() { return nullptr; }
diff --git a/src/VerificationExecutor.cpp b/src/VerificationExecutor.cpp
new file mode 100644
index 0000000..de9fcf2
--- /dev/null
+++ b/src/VerificationExecutor.cpp
@@ -0,0 +1,3 @@
+#include "VerificationExecutor.hpp"
+
+json VerificationExecutor::executeTask() { return nullptr; }

From 4e133831095828a24c8af54080827e245bf4b4ea Mon Sep 17 00:00:00 2001
From: Tianyi Wang <tianyi1.wang@tum.de>
Date: Fri, 19 May 2023 01:33:03 +0200
Subject: [PATCH 06/43] Refactored naming

---
 include/Executor.hpp | 2 +-
 src/Executor.cpp     | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/include/Executor.hpp b/include/Executor.hpp
index a11eabb..ef5a9ab 100644
--- a/include/Executor.hpp
+++ b/include/Executor.hpp
@@ -14,5 +14,5 @@ class Executor {
   virtual std::string          getIdentifier() = 0;
 
 private:
-  std::shared_ptr<Task> task;
+  std::shared_ptr<Task> m_task;
 };
diff --git a/src/Executor.cpp b/src/Executor.cpp
index 72f865f..0d148f3 100644
--- a/src/Executor.cpp
+++ b/src/Executor.cpp
@@ -25,8 +25,8 @@ class Executor::Executor {
 
 // add adapter for simulators
 
-void Executor::setTask(const std::shared_ptr<Task>& newTask) {
-  this->task = newTask;
+void Executor::setTask(const std::shared_ptr<Task>& task) {
+  this->m_task = task;
 }
 
-const std::shared_ptr<Task>& Executor::getTask() { return task; }
+const std::shared_ptr<Task>& Executor::getTask() { return m_task; }

From d602218d67aaab7e54aaa7b1c39810eb806f2cae Mon Sep 17 00:00:00 2001
From: Tianyi Wang <tianyi1.wang@tum.de>
Date: Wed, 24 May 2023 17:08:51 +0200
Subject: [PATCH 07/43] Refactor simulation executor

---
 include/CircuitSimulatorExecutor.hpp |  6 +++-
 include/Results.hpp                  | 46 ++++++++++++++--------------
 include/SimulationExecutor.hpp       |  2 +-
 src/CircuitSimulatorExecutor.cpp     | 26 ++++++++++++++++
 src/SimulationExecutor.cpp           |  2 ++
 5 files changed, 57 insertions(+), 25 deletions(-)

diff --git a/include/CircuitSimulatorExecutor.hpp b/include/CircuitSimulatorExecutor.hpp
index cc82af1..ff0bba3 100644
--- a/include/CircuitSimulatorExecutor.hpp
+++ b/include/CircuitSimulatorExecutor.hpp
@@ -2,4 +2,8 @@
 
 #include "SimulationExecutor.hpp"
 
-class CircuitSimulatorExecutor : public SimulationExecutor {};
+class CircuitSimulatorExecutor : public SimulationExecutor {
+public:
+  json        executeTask() override;
+  std::string getIdentifier() override;
+};
diff --git a/include/Results.hpp b/include/Results.hpp
index 4f74340..56d509a 100644
--- a/include/Results.hpp
+++ b/include/Results.hpp
@@ -1,23 +1,23 @@
-#pragma once
-
-#include "Executor.hpp"
-#include "Task.hpp"
-
-#include <nlohmann/json.hpp>
-
-using json = nlohmann::json;
-
-class Results {
-public:
-  virtual ~Results() = default;
-
-  virtual json        toJson() const = 0;
-  virtual std::string toString() const { return toJson().dump(2); }
-
-  Results(Task task, Executor executor) {
-    identifier = task.getIdentifier() + "_" + executor.getIdentifier();
-  }
-
-private:
-  std::string identifier;
-};
+// #pragma once
+//
+// #include "Executor.hpp"
+// #include "Task.hpp"
+//
+// #include <nlohmann/json.hpp>
+//
+// using json = nlohmann::json;
+//
+// class Results {
+// public:
+//   virtual ~Results() = default;
+//
+//   virtual json        toJson() const = 0;
+//   virtual std::string toString() const { return toJson().dump(2); }
+//
+//   Results(Task task, Executor executor) {
+//     identifier = task.getIdentifier() + "_" + executor.getIdentifier();
+//   }
+//
+// private:
+//   std::string identifier;
+// };
diff --git a/include/SimulationExecutor.hpp b/include/SimulationExecutor.hpp
index f2c3c14..2494975 100644
--- a/include/SimulationExecutor.hpp
+++ b/include/SimulationExecutor.hpp
@@ -7,6 +7,6 @@ class SimulationExecutor : public Executor {
 public:
   explicit SimulationExecutor(const std::shared_ptr<SimulationTask>& task) {
     setTask(task);
-  };
+  }
   json executeTask() override;
 };
diff --git a/src/CircuitSimulatorExecutor.cpp b/src/CircuitSimulatorExecutor.cpp
index ce98a6e..3cb3962 100644
--- a/src/CircuitSimulatorExecutor.cpp
+++ b/src/CircuitSimulatorExecutor.cpp
@@ -1 +1,27 @@
 #include "CircuitSimulatorExecutor.hpp"
+
+class CircuitSimulatorExecutor::CircuitSimulatorExecutor {};
+
+std::string CircuitSimulatorExecutor::getIdentifier() {
+  return std::string("This is a circuit simulator executor");
+  // refactor
+}
+
+json CircuitSimulatorExecutor::executeTask() {
+  json result;
+  auto start = std::chrono::high_resolution_clock::now();
+
+  //    this->executeTask();
+  // execute the actual task
+  // Add memory usage
+
+  auto stop = std::chrono::high_resolution_clock::now();
+  auto runtime =
+      std::chrono::duration_cast<std::chrono::microseconds>(stop - start);
+  result["runtime"] = runtime.count();
+  std::string const identifier =
+      this->getTask()->getIdentifier() + "_" + this->getIdentifier();
+  result["identifier"] = identifier;
+  return result;
+  //    return SimulationExecutor::executeTask();
+}
diff --git a/src/SimulationExecutor.cpp b/src/SimulationExecutor.cpp
index 5acc2ab..169b1ae 100644
--- a/src/SimulationExecutor.cpp
+++ b/src/SimulationExecutor.cpp
@@ -1,3 +1,5 @@
 #include "../include/SimulationExecutor.hpp"
 
 json SimulationExecutor::executeTask() { return nullptr; }
+
+// SimulationExecutor::SimulationExecutor() {}

From d5000f4efe6684943f5af188fb6a40d01b729ea5 Mon Sep 17 00:00:00 2001
From: Tianyi Wang <tianyi1.wang@tum.de>
Date: Thu, 1 Jun 2023 01:01:24 +0200
Subject: [PATCH 08/43] Refactored executor and simulatorexecutor

---
 include/CircuitSimulatorExecutor.hpp | 30 +++++++++++++
 include/Executor.hpp                 |  9 ++--
 include/SimulationExecutor.hpp       | 11 ++++-
 include/SimulationTask.hpp           | 14 ++++--
 include/VerificationExecutor.hpp     |  9 ++--
 src/CircuitSimulatorExecutor.cpp     | 67 +++++++++++++++++++++++++---
 src/Executor.cpp                     | 51 +++++++++++----------
 src/SimulationExecutor.cpp           | 12 +++--
 src/SimulationTask.cpp               |  4 ++
 src/VerificationExecutor.cpp         |  2 +-
 test/CMakeLists.txt                  |  2 +-
 11 files changed, 163 insertions(+), 48 deletions(-)

diff --git a/include/CircuitSimulatorExecutor.hpp b/include/CircuitSimulatorExecutor.hpp
index ff0bba3..3449802 100644
--- a/include/CircuitSimulatorExecutor.hpp
+++ b/include/CircuitSimulatorExecutor.hpp
@@ -1,9 +1,39 @@
 #pragma once
 
+#include "CircuitSimulator.hpp"
 #include "SimulationExecutor.hpp"
 
 class CircuitSimulatorExecutor : public SimulationExecutor {
 public:
+  CircuitSimulatorExecutor() = default;
+
+  //    explicit CircuitSimulatorExecutor();
+  //  explicit CircuitSimulatorExecutor(std::unique_ptr<SimulationTask>
+  //  &mSimTask);
+
   json        executeTask() override;
   std::string getIdentifier() override;
+
+private:
+  std::unique_ptr<SimulationTask> mSimTask;
+
+public:
+  [[nodiscard]] const std::unique_ptr<SimulationTask>& getMSimTask() const;
+
+  void setMSimTask(std::unique_ptr<SimulationTask>& simTask);
+
+private:
+  std::unique_ptr<CircuitSimulator<>> mCircuitSimulator;
+
+public:
+  const std::unique_ptr<CircuitSimulator<>>& getCircuitSimulator();
+
+  void
+  setCircuitSimulator(std::unique_ptr<CircuitSimulator<>>& circuitSimulator);
+  // public:
+  //     [[nodiscard]] const CircuitSimulator<dd::DDPackageConfig>
+  //     &getCircuitSimulator() const;
+  //
+  //     void setCircuitSimulator(const CircuitSimulator<dd::DDPackageConfig>
+  //     &circuitSimulator);
 };
diff --git a/include/Executor.hpp b/include/Executor.hpp
index ef5a9ab..5775e04 100644
--- a/include/Executor.hpp
+++ b/include/Executor.hpp
@@ -9,10 +9,11 @@ class Executor {
   virtual ~Executor()        = default;
   virtual json executeTask() = 0;
   explicit Executor()        = default;
-  const std::shared_ptr<Task>& getTask();
-  void                         setTask(const std::shared_ptr<Task>& task);
-  virtual std::string          getIdentifier() = 0;
+  //  virtual const std::unique_ptr<Task>& getTask();
+  //  virtual void                         setTask(const std::unique_ptr<Task>
+  //  &task);
+  virtual std::string getIdentifier() = 0;
 
 private:
-  std::shared_ptr<Task> m_task;
+  std::unique_ptr<Task> mTask;
 };
diff --git a/include/SimulationExecutor.hpp b/include/SimulationExecutor.hpp
index 2494975..822996d 100644
--- a/include/SimulationExecutor.hpp
+++ b/include/SimulationExecutor.hpp
@@ -5,8 +5,15 @@
 
 class SimulationExecutor : public Executor {
 public:
-  explicit SimulationExecutor(const std::shared_ptr<SimulationTask>& task) {
+  SimulationExecutor() = default;
+  explicit SimulationExecutor(std::unique_ptr<SimulationTask>& task) {
     setTask(task);
   }
-  json executeTask() override;
+
+  const std::unique_ptr<Task>& getTask();
+
+  void setTask(std::unique_ptr<SimulationTask>& task);
+
+private:
+  std::unique_ptr<SimulationTask> mTask;
 };
diff --git a/include/SimulationTask.hpp b/include/SimulationTask.hpp
index 6dbd207..efde458 100644
--- a/include/SimulationTask.hpp
+++ b/include/SimulationTask.hpp
@@ -5,8 +5,16 @@
 
 class SimulationTask : public Task {
 public:
-  explicit SimulationTask(qc::QuantumComputation qc) { this->qc = qc.clone(); };
+  SimulationTask() = default;
 
-private:
-  qc::QuantumComputation qc;
+  explicit SimulationTask(std::unique_ptr<qc::QuantumComputation> qc)
+      : qc(std::move(qc)) {}
+
+protected:
+  std::unique_ptr<qc::QuantumComputation> qc;
+
+public:
+  std::unique_ptr<qc::QuantumComputation>& getQc() { return qc; }
+
+  std::string getIdentifier() override;
 };
diff --git a/include/VerificationExecutor.hpp b/include/VerificationExecutor.hpp
index bcfe9a4..ed47c56 100644
--- a/include/VerificationExecutor.hpp
+++ b/include/VerificationExecutor.hpp
@@ -5,8 +5,9 @@
 
 class VerificationExecutor : public Executor {
 public:
-  explicit VerificationExecutor(const std::shared_ptr<VerificationTask>& task) {
-    setTask(task);
-  };
-  json executeTask() override;
+  //  explicit VerificationExecutor(const std::shared_ptr<VerificationTask>&
+  //  task) {
+  //    setTask(task);
+  //  };
+  //  json executeTask() override;
 };
diff --git a/src/CircuitSimulatorExecutor.cpp b/src/CircuitSimulatorExecutor.cpp
index 3cb3962..058952d 100644
--- a/src/CircuitSimulatorExecutor.cpp
+++ b/src/CircuitSimulatorExecutor.cpp
@@ -1,27 +1,82 @@
 #include "CircuitSimulatorExecutor.hpp"
 
-class CircuitSimulatorExecutor::CircuitSimulatorExecutor {};
+class CircuitSimulatorExecutor::CircuitSimulatorExecutor {
+  //    CircuitSimulatorExecutor(std::unique_ptr<SimulationTask> &simTask) {
+  //        setMSimTask(simTask);
+  //    }
+  //    CircuitSimulatorExecutor(std::unique_ptr<SimulationTask> &simTask) {
+  //        mSimTask = std::move(simTask);
+  //    }
+  //    CircuitSimulatorExecutor() {
+  //        mCircuitSimulator =
+  //        CircuitSimulator(std::move(this->getMSimTask()->getQc()));
+  //    }
+};
 
 std::string CircuitSimulatorExecutor::getIdentifier() {
-  return std::string("This is a circuit simulator executor");
+  return {"This is a circuit simulator executor"};
   // refactor
 }
 
 json CircuitSimulatorExecutor::executeTask() {
   json result;
   auto start = std::chrono::high_resolution_clock::now();
+  std::cout << "I'm here in testa\n";
 
-  //    this->executeTask();
   // execute the actual task
+  const auto results = mCircuitSimulator->simulate(1024U);
+  //  std::cout << results << std::endl;
+  // use the results
   // Add memory usage
 
   auto stop = std::chrono::high_resolution_clock::now();
   auto runtime =
       std::chrono::duration_cast<std::chrono::microseconds>(stop - start);
-  result["runtime"] = runtime.count();
-  std::string const identifier =
-      this->getTask()->getIdentifier() + "_" + this->getIdentifier();
+  result["runtime"]            = runtime.count();
+  std::string const identifier = "test identifier";
+  //      this->getTask()->getIdentifier() + "_" + this->getIdentifier();
+  std::cout << "I'm here in testc\n";
   result["identifier"] = identifier;
+
+  result["00"] = results.count("00");
+  result["01"] = results.count("01");
+  result["10"] = results.count("10");
+  result["11"] = results.count("11");
+  // what about more qubits?
+  std::cout << "I'm here in testd\n";
   return result;
   //    return SimulationExecutor::executeTask();
 }
+
+const std::unique_ptr<SimulationTask>&
+CircuitSimulatorExecutor::getMSimTask() const {
+  return mSimTask;
+}
+
+void CircuitSimulatorExecutor::setMSimTask(
+    std::unique_ptr<SimulationTask>& simTask) {
+  mSimTask = std::move(simTask);
+}
+
+const std::unique_ptr<CircuitSimulator<>>&
+CircuitSimulatorExecutor::getCircuitSimulator() {
+  return mCircuitSimulator;
+}
+
+void CircuitSimulatorExecutor::setCircuitSimulator(
+    std::unique_ptr<CircuitSimulator<>>& circuitSimulator) {
+  mCircuitSimulator = std::move(circuitSimulator);
+}
+
+// CircuitSimulatorExecutor(std::unique_ptr<SimulationTask> &mSimTask)
+//         : SimulationExecutor(task), mSimTask(mSimTask) {}
+
+// const CircuitSimulator<dd::DDPackageConfig>
+// &CircuitSimulatorExecutor::getCircuitSimulator() const {
+//     return circuitSimulator;
+// }
+//
+// void CircuitSimulatorExecutor::setCircuitSimulator(const
+// CircuitSimulator<dd::DDPackageConfig> &circuitSimulator) {
+//     CircuitSimulatorExecutor::circuitSimulator = circuitSimulator;
+// }
diff --git a/src/Executor.cpp b/src/Executor.cpp
index 0d148f3..2e01da0 100644
--- a/src/Executor.cpp
+++ b/src/Executor.cpp
@@ -3,30 +3,33 @@
 #include <chrono>
 
 class Executor::Executor {
-  json executeTask() {
-    json result;
-    auto start = std::chrono::high_resolution_clock::now();
+  //  json executeTask() {
+  //    json result;
+  //    auto start = std::chrono::high_resolution_clock::now();
+  //
+  //    //    this->executeTask();
+  //    // execute the actual task
+  //    // Add memory usage
+  //
+  //    auto stop = std::chrono::high_resolution_clock::now();
+  //    auto runtime =
+  //        std::chrono::duration_cast<std::chrono::microseconds>(stop - start);
+  //    result["runtime"] = runtime.count();
+  //    std::string const identifier =
+  //        this->getTask()->getIdentifier() + "_" + this->getIdentifier();
+  //    result["identifier"] = identifier;
+  //    return result;
+  //    // what about the Results class?
+  //    json result;
+  //    return result;
+  //  }
+  //};
 
-    //    this->executeTask();
-    // execute the actual task
-    // Add memory usage
+  // add adapter for simulators
 
-    auto stop = std::chrono::high_resolution_clock::now();
-    auto runtime =
-        std::chrono::duration_cast<std::chrono::microseconds>(stop - start);
-    result["runtime"] = runtime.count();
-    std::string const identifier =
-        this->getTask()->getIdentifier() + "_" + this->getIdentifier();
-    result["identifier"] = identifier;
-    return result;
-    // what about the Results class?
-  }
+  // void Executor::setTask(const std::unique_ptr<Task> &task) {
+  //   this->mTask = task;
+  // }
+  //
+  // const std::unique_ptr<Task>& Executor::getTask() { return mTask; }
 };
-
-// add adapter for simulators
-
-void Executor::setTask(const std::shared_ptr<Task>& task) {
-  this->m_task = task;
-}
-
-const std::shared_ptr<Task>& Executor::getTask() { return m_task; }
diff --git a/src/SimulationExecutor.cpp b/src/SimulationExecutor.cpp
index 169b1ae..d8577d7 100644
--- a/src/SimulationExecutor.cpp
+++ b/src/SimulationExecutor.cpp
@@ -1,5 +1,11 @@
-#include "../include/SimulationExecutor.hpp"
+#include "SimulationExecutor.hpp"
 
-json SimulationExecutor::executeTask() { return nullptr; }
+// json SimulationExecutor::executeTask() { return nullptr; }
 
-// SimulationExecutor::SimulationExecutor() {}
+const std::unique_ptr<Task>& SimulationExecutor::getTask() {
+  return std::move(mTask);
+}
+
+void SimulationExecutor::setTask(std::unique_ptr<SimulationTask>& task) {
+  mTask = std::move(task);
+}
diff --git a/src/SimulationTask.cpp b/src/SimulationTask.cpp
index 2d38955..0dc1564 100644
--- a/src/SimulationTask.cpp
+++ b/src/SimulationTask.cpp
@@ -1,2 +1,6 @@
 #include "SimulationTask.hpp"
 // take one circuit
+std::string SimulationTask::getIdentifier() {
+  return "This is a simulation task";
+  // refactor
+}
diff --git a/src/VerificationExecutor.cpp b/src/VerificationExecutor.cpp
index de9fcf2..e35f42e 100644
--- a/src/VerificationExecutor.cpp
+++ b/src/VerificationExecutor.cpp
@@ -1,3 +1,3 @@
 #include "VerificationExecutor.hpp"
 
-json VerificationExecutor::executeTask() { return nullptr; }
+// json VerificationExecutor::executeTask() { return nullptr; }
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 70d0463..5415991 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -11,4 +11,4 @@ if(NOT TARGET gtest OR NOT TARGET gmock)
 endif()
 
 package_add_test(${PROJECT_NAME}_test ${PROJECT_NAME} test_ddsim_simple.cpp
-                 test_qcec_simple.cpp)
+                 test_qcec_simple.cpp test_sim.cpp)

From 0091d357c2bc96af82f1aabd759350fd55ac9af3 Mon Sep 17 00:00:00 2001
From: Tianyi Wang <tianyi1.wang@tum.de>
Date: Thu, 1 Jun 2023 01:01:56 +0200
Subject: [PATCH 09/43] Added dummy test (other tests WIP)

---
 test/circuits.json |   7 ++
 test/test_sim.cpp  | 294 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 301 insertions(+)
 create mode 100644 test/circuits.json
 create mode 100644 test/test_sim.cpp

diff --git a/test/circuits.json b/test/circuits.json
new file mode 100644
index 0000000..94328ef
--- /dev/null
+++ b/test/circuits.json
@@ -0,0 +1,7 @@
+[
+  {
+    "description": "empty_circuit",
+    "initial_circuit": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[1];\n",
+    "expected_00": 1024
+  }
+]
diff --git a/test/test_sim.cpp b/test/test_sim.cpp
new file mode 100644
index 0000000..f35ee35
--- /dev/null
+++ b/test/test_sim.cpp
@@ -0,0 +1,294 @@
+#include "CircuitSimulatorExecutor.hpp"
+#include "SimulationTask.hpp"
+
+#include "gtest/gtest.h"
+
+namespace cs {
+
+//    struct TestConfiguration {
+//        // given input (either as tableau or as circuit)
+//        std::string description;
+//        std::string initialCircuit;
+//
+//        // expected output
+//        std::size_t expected00{};
+//    };
+
+// NOLINTNEXTLINE (readability-identifier-naming)
+//    inline void from_json(const nlohmann::json &j, TestConfiguration &test) {
+//        test.description = j.at("description").get<std::string>();
+//        if (j.contains("initial_circuit")) {
+//            test.initialCircuit = j.at("initial_circuit").get<std::string>();
+//        }
+//        test.expected00 = j.at("expected_00").get<std::size_t>();
+//
+//    }
+
+//    static std::vector<TestConfiguration> getTests(const std::string &path) {
+//        std::ifstream input(path);
+//        nlohmann::json j;
+//        input >> j;
+//        return j;
+//    }
+//    : public ::testing::TestWithParam<TestConfiguration>
+class SimulatorTest {
+protected:
+  //        void SetUp() override {
+  //            test = GetParam();
+  //            std::cout << "I'm here in setup\n";
+
+  //            if (!test.initialCircuit.empty()) {
+  //                std::stringstream ss(test.initialCircuit);
+  //                qc::QuantumComputation qc{};
+  //                qc.import(ss, qc::Format::OpenQASM);
+  //                std::cout << "Initial circuit:\n" << qc;
+  //                std::cout << "NQubits:\n" << qc.getNqubits();
+  //            }
+  //            else {
+  //                throw std::runtime_error("No circuit!");
+  //            }
+  //            config = Configuration();
+  //            config.verbosity = plog::Severity::verbose;
+  //            config.dumpIntermediateResults = true;
+  //        }
+
+  //        void TearDown() override {
+  //            std::cout << "I'm here in teardown\n";
+  //            std::cout << "Results:\n" << results << "\n";
+
+  //            resultTableau = synthesizer.getResultTableau();
+  //            std::cout << "Resulting tableau:\n" << resultTableau;
+  //            EXPECT_EQ(resultTableau, targetTableau);
+  //            EXPECT_EQ(expected00, 1024);
+  //            const auto &resultCircuit = synthesizer.getResultCircuit();
+  //            std::cout << "Resulting Circuit:\n" << resultCircuit;
+  //            consistencyCheck(resultCircuit);
+  //        }
+
+  //        void consistencyCheck(const qc::QuantumComputation &qc) const {
+  //            auto circuitTableau = initialTableau;
+  //            for (const auto &gate: qc) {
+  //                circuitTableau.applyGate(gate.get());
+  //            }
+  //            EXPECT_EQ(resultTableau, circuitTableau);
+  //        }
+
+  //        Tableau initialTableau;
+  //        Tableau initialTableauWithDestabilizer;
+  //        Tableau targetTableau;
+  //        Tableau targetTableauWithDestabilizer;
+  //        Configuration config;
+  //        CliffordSynthesizer synthesizer;
+  //        CliffordSynthesizer synthesizerWithDestabilizer;
+  //        Results results;
+  //        Results resultsWithDestabilizer;
+  //        Tableau resultTableau;
+  //        Tableau resultTableauWithDestabilizer;
+  //        CircuitSimulatorExecutor circuitSimulatorExecutor;
+  //        TestConfiguration test;
+  //        SimulationTask simulationTask;
+  //        json result;
+};
+
+//    INSTANTIATE_TEST_SUITE_P(
+//            Tableaus, SynthesisTest,
+//            testing::ValuesIn(getTests("cliffordsynthesis/tableaus.json")),
+//            [](const testing::TestParamInfo<SynthesisTest::ParamType>& inf) {
+//                return inf.param.description;
+//            });
+
+//    INSTANTIATE_TEST_SUITE_P(
+//            Circuits, SimulatorTest,
+//            testing::ValuesIn(getTests("/Users/tianyiwang/Documents/tum/GR/repos/dd_eval/test/circuits.json")),
+//            [](const testing::TestParamInfo<SimulatorTest::ParamType>& inf) {
+//                return inf.param.description;
+//            });
+
+TEST(SimulatorTest, EmptyCircuit) {
+  auto qc             = std::make_unique<qc::QuantumComputation>(2U);
+  auto simulationTask = std::make_unique<SimulationTask>(std::move(qc));
+  auto circuitSimulator =
+      std::make_unique<CircuitSimulator<>>(std::move(simulationTask->getQc()));
+  auto circuitSimulatorExecutor = std::make_unique<CircuitSimulatorExecutor>();
+  circuitSimulatorExecutor->setCircuitSimulator(circuitSimulator);
+  circuitSimulatorExecutor->setMSimTask(simulationTask);
+  json const result = circuitSimulatorExecutor->executeTask();
+
+  EXPECT_EQ(1, result["00"]);
+}
+
+//    TEST_P(SynthesisTest, GatesMaxSAT) {
+//        config.target    = TargetMetric::Gates;
+//        config.useMaxSAT = true;
+//        synthesizer.synthesize(config);
+//        results = synthesizer.getResults();
+//
+//        EXPECT_EQ(results.getGates(), test.expectedMinimalGates);
+//    }
+//
+//    TEST_P(SynthesisTest, Depth) {
+//        config.target = TargetMetric::Depth;
+//        synthesizer.synthesize(config);
+//        results = synthesizer.getResults();
+//
+//        EXPECT_EQ(results.getDepth(), test.expectedMinimalDepth);
+//    }
+//
+//    TEST_P(SynthesisTest, DepthMaxSAT) {
+//        config.target    = TargetMetric::Depth;
+//        config.useMaxSAT = true;
+//        synthesizer.synthesize(config);
+//        results = synthesizer.getResults();
+//
+//        EXPECT_EQ(results.getDepth(), test.expectedMinimalDepth);
+//    }
+//
+//    TEST_P(SynthesisTest, DepthMinimalGates) {
+//        config.target                              = TargetMetric::Depth;
+//        config.minimizeGatesAfterDepthOptimization = true;
+//        synthesizer.synthesize(config);
+//        results = synthesizer.getResults();
+//
+//        EXPECT_EQ(results.getDepth(), test.expectedMinimalDepth);
+//        EXPECT_EQ(results.getGates(),
+//        test.expectedMinimalGatesAtMinimalDepth);
+//    }
+//
+//    TEST_P(SynthesisTest, DepthMinimalTimeSteps) {
+//        config.target           = TargetMetric::Depth;
+//        config.minimalTimesteps = test.expectedMinimalDepth;
+//        synthesizer.synthesize(config);
+//        results = synthesizer.getResults();
+//
+//        EXPECT_EQ(results.getDepth(), test.expectedMinimalDepth);
+//    }
+//
+//    TEST_P(SynthesisTest, DepthMinimalGatesMaxSAT) {
+//        config.target                              = TargetMetric::Depth;
+//        config.useMaxSAT                           = true;
+//        config.minimizeGatesAfterDepthOptimization = true;
+//        synthesizer.synthesize(config);
+//        results = synthesizer.getResults();
+//
+//        EXPECT_EQ(results.getDepth(), test.expectedMinimalDepth);
+//        EXPECT_EQ(results.getGates(),
+//        test.expectedMinimalGatesAtMinimalDepth);
+//    }
+//
+//    TEST_P(SynthesisTest, TwoQubitGates) {
+//        config.target = TargetMetric::TwoQubitGates;
+//        config.tryHigherGateLimitForTwoQubitGateOptimization = true;
+//        synthesizer.synthesize(config);
+//        results = synthesizer.getResults();
+//
+//        EXPECT_EQ(results.getTwoQubitGates(),
+//        test.expectedMinimalTwoQubitGates);
+//    }
+//
+//    TEST_P(SynthesisTest, TwoQubitGatesMaxSAT) {
+//        config.target = TargetMetric::TwoQubitGates;
+//        config.tryHigherGateLimitForTwoQubitGateOptimization = true;
+//        config.useMaxSAT                                     = true;
+//        synthesizer.synthesize(config);
+//        results = synthesizer.getResults();
+//
+//        EXPECT_EQ(results.getTwoQubitGates(),
+//        test.expectedMinimalTwoQubitGates);
+//    }
+//
+//    TEST_P(SynthesisTest, TwoQubitGatesMinimalGates) {
+//        config.target = TargetMetric::TwoQubitGates;
+//        config.tryHigherGateLimitForTwoQubitGateOptimization = true;
+//        config.minimizeGatesAfterTwoQubitGateOptimization    = true;
+//        synthesizer.synthesize(config);
+//        results = synthesizer.getResults();
+//
+//        EXPECT_EQ(results.getTwoQubitGates(),
+//        test.expectedMinimalTwoQubitGates); EXPECT_EQ(results.getGates(),
+//                  test.expectedMinimalGatesAtMinimalTwoQubitGates);
+//    }
+//
+//    TEST_P(SynthesisTest, TwoQubitGatesMinimalGatesMaxSAT) {
+//        config.target = TargetMetric::TwoQubitGates;
+//        config.tryHigherGateLimitForTwoQubitGateOptimization = true;
+//        config.minimizeGatesAfterTwoQubitGateOptimization    = true;
+//        config.useMaxSAT                                     = true;
+//        synthesizer.synthesize(config);
+//        results = synthesizer.getResults();
+//
+//        EXPECT_EQ(results.getTwoQubitGates(),
+//        test.expectedMinimalTwoQubitGates); EXPECT_EQ(results.getGates(),
+//                  test.expectedMinimalGatesAtMinimalTwoQubitGates);
+//    }
+//
+//    TEST_P(SynthesisTest, TestDestabilizerGates) {
+//        if (!initialTableauWithDestabilizer.getTableau().empty()) {
+//            std::cout << "Testing with destabilizer" << std::endl;
+//            config.target    = TargetMetric::Gates;
+//            config.useMaxSAT = true;
+//
+//            synthesizer.synthesize(config);
+//            synthesizerWithDestabilizer.synthesize(config);
+//            results                 = synthesizer.getResults();
+//            resultsWithDestabilizer =
+//            synthesizerWithDestabilizer.getResults();
+//
+//            EXPECT_GE(resultsWithDestabilizer.getGates(), results.getGates());
+//        } else {
+//            std::cout << "Testing without destabilizer" << std::endl;
+//            config.target    = TargetMetric::Gates;
+//            config.useMaxSAT = true;
+//
+//            synthesizer.synthesize(config);
+//            results = synthesizer.getResults();
+//        }
+//    }
+//
+//    TEST_P(SynthesisTest, TestDestabilizerDepth) {
+//        if (!initialTableauWithDestabilizer.getTableau().empty()) {
+//            std::cout << "Testing with destabilizer" << std::endl;
+//            config.target    = TargetMetric::Depth;
+//            config.useMaxSAT = true;
+//
+//            synthesizer.synthesize(config);
+//            synthesizerWithDestabilizer.synthesize(config);
+//            results                 = synthesizer.getResults();
+//            resultsWithDestabilizer =
+//            synthesizerWithDestabilizer.getResults();
+//
+//            EXPECT_GE(resultsWithDestabilizer.getDepth(), results.getDepth());
+//        } else {
+//            std::cout << "Testing without destabilizer" << std::endl;
+//            config.target    = TargetMetric::Gates;
+//            config.useMaxSAT = true;
+//
+//            synthesizer.synthesize(config);
+//            results = synthesizer.getResults();
+//        }
+//    }
+//
+//    TEST_P(SynthesisTest, TestDestabilizerTwoQubitGates) {
+//        if (!initialTableauWithDestabilizer.getTableau().empty()) {
+//            std::cout << "Testing with destabilizer" << std::endl;
+//            config.target    = TargetMetric::TwoQubitGates;
+//            config.useMaxSAT = true;
+//
+//            synthesizer.synthesize(config);
+//            synthesizerWithDestabilizer.synthesize(config);
+//            results                 = synthesizer.getResults();
+//            resultsWithDestabilizer =
+//            synthesizerWithDestabilizer.getResults();
+//
+//            EXPECT_GE(resultsWithDestabilizer.getTwoQubitGates(),
+//                      results.getTwoQubitGates());
+//        } else {
+//            std::cout << "Testing without destabilizer" << std::endl;
+//            config.target    = TargetMetric::Gates;
+//            config.useMaxSAT = true;
+//
+//            synthesizer.synthesize(config);
+//            results = synthesizer.getResults();
+//        }
+//    }
+
+} // namespace cs

From 19883ebcca906b91ae9a67616282bf712bf746e3 Mon Sep 17 00:00:00 2001
From: Tianyi Wang <tianyi1.wang@tum.de>
Date: Thu, 1 Jun 2023 20:02:13 +0200
Subject: [PATCH 10/43] Refactored test code to not let the task consume the qc

---
 src/CircuitSimulatorExecutor.cpp | 3 ---
 test/test_sim.cpp                | 8 ++++----
 2 files changed, 4 insertions(+), 7 deletions(-)

diff --git a/src/CircuitSimulatorExecutor.cpp b/src/CircuitSimulatorExecutor.cpp
index 058952d..6153626 100644
--- a/src/CircuitSimulatorExecutor.cpp
+++ b/src/CircuitSimulatorExecutor.cpp
@@ -21,7 +21,6 @@ std::string CircuitSimulatorExecutor::getIdentifier() {
 json CircuitSimulatorExecutor::executeTask() {
   json result;
   auto start = std::chrono::high_resolution_clock::now();
-  std::cout << "I'm here in testa\n";
 
   // execute the actual task
   const auto results = mCircuitSimulator->simulate(1024U);
@@ -35,7 +34,6 @@ json CircuitSimulatorExecutor::executeTask() {
   result["runtime"]            = runtime.count();
   std::string const identifier = "test identifier";
   //      this->getTask()->getIdentifier() + "_" + this->getIdentifier();
-  std::cout << "I'm here in testc\n";
   result["identifier"] = identifier;
 
   result["00"] = results.count("00");
@@ -43,7 +41,6 @@ json CircuitSimulatorExecutor::executeTask() {
   result["10"] = results.count("10");
   result["11"] = results.count("11");
   // what about more qubits?
-  std::cout << "I'm here in testd\n";
   return result;
   //    return SimulationExecutor::executeTask();
 }
diff --git a/test/test_sim.cpp b/test/test_sim.cpp
index f35ee35..e52e865 100644
--- a/test/test_sim.cpp
+++ b/test/test_sim.cpp
@@ -105,10 +105,10 @@ class SimulatorTest {
 //            });
 
 TEST(SimulatorTest, EmptyCircuit) {
-  auto qc             = std::make_unique<qc::QuantumComputation>(2U);
-  auto simulationTask = std::make_unique<SimulationTask>(std::move(qc));
-  auto circuitSimulator =
-      std::make_unique<CircuitSimulator<>>(std::move(simulationTask->getQc()));
+  auto qc               = std::make_unique<qc::QuantumComputation>(2U);
+  auto clonedQC         = std::make_unique<qc::QuantumComputation>(qc->clone());
+  auto simulationTask   = std::make_unique<SimulationTask>(std::move(clonedQC));
+  auto circuitSimulator = std::make_unique<CircuitSimulator<>>(std::move(qc));
   auto circuitSimulatorExecutor = std::make_unique<CircuitSimulatorExecutor>();
   circuitSimulatorExecutor->setCircuitSimulator(circuitSimulator);
   circuitSimulatorExecutor->setMSimTask(simulationTask);

From 62db93e20611e6dad370e66d3c0d8483bfd14387 Mon Sep 17 00:00:00 2001
From: Tianyi Wang <tianyi1.wang@tum.de>
Date: Thu, 1 Jun 2023 20:05:42 +0200
Subject: [PATCH 11/43] Fixed a getter function in SimulationExecutor to
 address a warning

---
 include/SimulationExecutor.hpp | 2 +-
 src/SimulationExecutor.cpp     | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/include/SimulationExecutor.hpp b/include/SimulationExecutor.hpp
index 822996d..09b8587 100644
--- a/include/SimulationExecutor.hpp
+++ b/include/SimulationExecutor.hpp
@@ -10,7 +10,7 @@ class SimulationExecutor : public Executor {
     setTask(task);
   }
 
-  const std::unique_ptr<Task>& getTask();
+  const std::unique_ptr<SimulationTask>& getMTask();
 
   void setTask(std::unique_ptr<SimulationTask>& task);
 
diff --git a/src/SimulationExecutor.cpp b/src/SimulationExecutor.cpp
index d8577d7..73d9c3e 100644
--- a/src/SimulationExecutor.cpp
+++ b/src/SimulationExecutor.cpp
@@ -2,8 +2,8 @@
 
 // json SimulationExecutor::executeTask() { return nullptr; }
 
-const std::unique_ptr<Task>& SimulationExecutor::getTask() {
-  return std::move(mTask);
+const std::unique_ptr<SimulationTask>& SimulationExecutor::getMTask() {
+  return mTask;
 }
 
 void SimulationExecutor::setTask(std::unique_ptr<SimulationTask>& task) {

From e54c574221ed4ea6d5c09750b83794f8256376e6 Mon Sep 17 00:00:00 2001
From: Tianyi Wang <tianyi1.wang@tum.de>
Date: Thu, 1 Jun 2023 21:59:05 +0200
Subject: [PATCH 12/43] Move non-parameterized simple test case to a separate
 file

---
 test/CMakeLists.txt          |   2 +-
 test/circuits.json           |   4 +-
 test/test_sim.cpp            | 294 -----------------------------------
 test/test_simexec_simple.cpp |  19 +++
 4 files changed, 22 insertions(+), 297 deletions(-)
 delete mode 100644 test/test_sim.cpp
 create mode 100644 test/test_simexec_simple.cpp

diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 5415991..e464a8d 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -11,4 +11,4 @@ if(NOT TARGET gtest OR NOT TARGET gmock)
 endif()
 
 package_add_test(${PROJECT_NAME}_test ${PROJECT_NAME} test_ddsim_simple.cpp
-                 test_qcec_simple.cpp test_sim.cpp)
+                 test_qcec_simple.cpp test_simexec_simple.cpp test_simexec.cpp)
diff --git a/test/circuits.json b/test/circuits.json
index 94328ef..b0e91e3 100644
--- a/test/circuits.json
+++ b/test/circuits.json
@@ -1,7 +1,7 @@
 [
   {
     "description": "empty_circuit",
-    "initial_circuit": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[1];\n",
-    "expected_00": 1024
+    "initial_circuit": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];\n",
+    "expected_00": 1
   }
 ]
diff --git a/test/test_sim.cpp b/test/test_sim.cpp
deleted file mode 100644
index e52e865..0000000
--- a/test/test_sim.cpp
+++ /dev/null
@@ -1,294 +0,0 @@
-#include "CircuitSimulatorExecutor.hpp"
-#include "SimulationTask.hpp"
-
-#include "gtest/gtest.h"
-
-namespace cs {
-
-//    struct TestConfiguration {
-//        // given input (either as tableau or as circuit)
-//        std::string description;
-//        std::string initialCircuit;
-//
-//        // expected output
-//        std::size_t expected00{};
-//    };
-
-// NOLINTNEXTLINE (readability-identifier-naming)
-//    inline void from_json(const nlohmann::json &j, TestConfiguration &test) {
-//        test.description = j.at("description").get<std::string>();
-//        if (j.contains("initial_circuit")) {
-//            test.initialCircuit = j.at("initial_circuit").get<std::string>();
-//        }
-//        test.expected00 = j.at("expected_00").get<std::size_t>();
-//
-//    }
-
-//    static std::vector<TestConfiguration> getTests(const std::string &path) {
-//        std::ifstream input(path);
-//        nlohmann::json j;
-//        input >> j;
-//        return j;
-//    }
-//    : public ::testing::TestWithParam<TestConfiguration>
-class SimulatorTest {
-protected:
-  //        void SetUp() override {
-  //            test = GetParam();
-  //            std::cout << "I'm here in setup\n";
-
-  //            if (!test.initialCircuit.empty()) {
-  //                std::stringstream ss(test.initialCircuit);
-  //                qc::QuantumComputation qc{};
-  //                qc.import(ss, qc::Format::OpenQASM);
-  //                std::cout << "Initial circuit:\n" << qc;
-  //                std::cout << "NQubits:\n" << qc.getNqubits();
-  //            }
-  //            else {
-  //                throw std::runtime_error("No circuit!");
-  //            }
-  //            config = Configuration();
-  //            config.verbosity = plog::Severity::verbose;
-  //            config.dumpIntermediateResults = true;
-  //        }
-
-  //        void TearDown() override {
-  //            std::cout << "I'm here in teardown\n";
-  //            std::cout << "Results:\n" << results << "\n";
-
-  //            resultTableau = synthesizer.getResultTableau();
-  //            std::cout << "Resulting tableau:\n" << resultTableau;
-  //            EXPECT_EQ(resultTableau, targetTableau);
-  //            EXPECT_EQ(expected00, 1024);
-  //            const auto &resultCircuit = synthesizer.getResultCircuit();
-  //            std::cout << "Resulting Circuit:\n" << resultCircuit;
-  //            consistencyCheck(resultCircuit);
-  //        }
-
-  //        void consistencyCheck(const qc::QuantumComputation &qc) const {
-  //            auto circuitTableau = initialTableau;
-  //            for (const auto &gate: qc) {
-  //                circuitTableau.applyGate(gate.get());
-  //            }
-  //            EXPECT_EQ(resultTableau, circuitTableau);
-  //        }
-
-  //        Tableau initialTableau;
-  //        Tableau initialTableauWithDestabilizer;
-  //        Tableau targetTableau;
-  //        Tableau targetTableauWithDestabilizer;
-  //        Configuration config;
-  //        CliffordSynthesizer synthesizer;
-  //        CliffordSynthesizer synthesizerWithDestabilizer;
-  //        Results results;
-  //        Results resultsWithDestabilizer;
-  //        Tableau resultTableau;
-  //        Tableau resultTableauWithDestabilizer;
-  //        CircuitSimulatorExecutor circuitSimulatorExecutor;
-  //        TestConfiguration test;
-  //        SimulationTask simulationTask;
-  //        json result;
-};
-
-//    INSTANTIATE_TEST_SUITE_P(
-//            Tableaus, SynthesisTest,
-//            testing::ValuesIn(getTests("cliffordsynthesis/tableaus.json")),
-//            [](const testing::TestParamInfo<SynthesisTest::ParamType>& inf) {
-//                return inf.param.description;
-//            });
-
-//    INSTANTIATE_TEST_SUITE_P(
-//            Circuits, SimulatorTest,
-//            testing::ValuesIn(getTests("/Users/tianyiwang/Documents/tum/GR/repos/dd_eval/test/circuits.json")),
-//            [](const testing::TestParamInfo<SimulatorTest::ParamType>& inf) {
-//                return inf.param.description;
-//            });
-
-TEST(SimulatorTest, EmptyCircuit) {
-  auto qc               = std::make_unique<qc::QuantumComputation>(2U);
-  auto clonedQC         = std::make_unique<qc::QuantumComputation>(qc->clone());
-  auto simulationTask   = std::make_unique<SimulationTask>(std::move(clonedQC));
-  auto circuitSimulator = std::make_unique<CircuitSimulator<>>(std::move(qc));
-  auto circuitSimulatorExecutor = std::make_unique<CircuitSimulatorExecutor>();
-  circuitSimulatorExecutor->setCircuitSimulator(circuitSimulator);
-  circuitSimulatorExecutor->setMSimTask(simulationTask);
-  json const result = circuitSimulatorExecutor->executeTask();
-
-  EXPECT_EQ(1, result["00"]);
-}
-
-//    TEST_P(SynthesisTest, GatesMaxSAT) {
-//        config.target    = TargetMetric::Gates;
-//        config.useMaxSAT = true;
-//        synthesizer.synthesize(config);
-//        results = synthesizer.getResults();
-//
-//        EXPECT_EQ(results.getGates(), test.expectedMinimalGates);
-//    }
-//
-//    TEST_P(SynthesisTest, Depth) {
-//        config.target = TargetMetric::Depth;
-//        synthesizer.synthesize(config);
-//        results = synthesizer.getResults();
-//
-//        EXPECT_EQ(results.getDepth(), test.expectedMinimalDepth);
-//    }
-//
-//    TEST_P(SynthesisTest, DepthMaxSAT) {
-//        config.target    = TargetMetric::Depth;
-//        config.useMaxSAT = true;
-//        synthesizer.synthesize(config);
-//        results = synthesizer.getResults();
-//
-//        EXPECT_EQ(results.getDepth(), test.expectedMinimalDepth);
-//    }
-//
-//    TEST_P(SynthesisTest, DepthMinimalGates) {
-//        config.target                              = TargetMetric::Depth;
-//        config.minimizeGatesAfterDepthOptimization = true;
-//        synthesizer.synthesize(config);
-//        results = synthesizer.getResults();
-//
-//        EXPECT_EQ(results.getDepth(), test.expectedMinimalDepth);
-//        EXPECT_EQ(results.getGates(),
-//        test.expectedMinimalGatesAtMinimalDepth);
-//    }
-//
-//    TEST_P(SynthesisTest, DepthMinimalTimeSteps) {
-//        config.target           = TargetMetric::Depth;
-//        config.minimalTimesteps = test.expectedMinimalDepth;
-//        synthesizer.synthesize(config);
-//        results = synthesizer.getResults();
-//
-//        EXPECT_EQ(results.getDepth(), test.expectedMinimalDepth);
-//    }
-//
-//    TEST_P(SynthesisTest, DepthMinimalGatesMaxSAT) {
-//        config.target                              = TargetMetric::Depth;
-//        config.useMaxSAT                           = true;
-//        config.minimizeGatesAfterDepthOptimization = true;
-//        synthesizer.synthesize(config);
-//        results = synthesizer.getResults();
-//
-//        EXPECT_EQ(results.getDepth(), test.expectedMinimalDepth);
-//        EXPECT_EQ(results.getGates(),
-//        test.expectedMinimalGatesAtMinimalDepth);
-//    }
-//
-//    TEST_P(SynthesisTest, TwoQubitGates) {
-//        config.target = TargetMetric::TwoQubitGates;
-//        config.tryHigherGateLimitForTwoQubitGateOptimization = true;
-//        synthesizer.synthesize(config);
-//        results = synthesizer.getResults();
-//
-//        EXPECT_EQ(results.getTwoQubitGates(),
-//        test.expectedMinimalTwoQubitGates);
-//    }
-//
-//    TEST_P(SynthesisTest, TwoQubitGatesMaxSAT) {
-//        config.target = TargetMetric::TwoQubitGates;
-//        config.tryHigherGateLimitForTwoQubitGateOptimization = true;
-//        config.useMaxSAT                                     = true;
-//        synthesizer.synthesize(config);
-//        results = synthesizer.getResults();
-//
-//        EXPECT_EQ(results.getTwoQubitGates(),
-//        test.expectedMinimalTwoQubitGates);
-//    }
-//
-//    TEST_P(SynthesisTest, TwoQubitGatesMinimalGates) {
-//        config.target = TargetMetric::TwoQubitGates;
-//        config.tryHigherGateLimitForTwoQubitGateOptimization = true;
-//        config.minimizeGatesAfterTwoQubitGateOptimization    = true;
-//        synthesizer.synthesize(config);
-//        results = synthesizer.getResults();
-//
-//        EXPECT_EQ(results.getTwoQubitGates(),
-//        test.expectedMinimalTwoQubitGates); EXPECT_EQ(results.getGates(),
-//                  test.expectedMinimalGatesAtMinimalTwoQubitGates);
-//    }
-//
-//    TEST_P(SynthesisTest, TwoQubitGatesMinimalGatesMaxSAT) {
-//        config.target = TargetMetric::TwoQubitGates;
-//        config.tryHigherGateLimitForTwoQubitGateOptimization = true;
-//        config.minimizeGatesAfterTwoQubitGateOptimization    = true;
-//        config.useMaxSAT                                     = true;
-//        synthesizer.synthesize(config);
-//        results = synthesizer.getResults();
-//
-//        EXPECT_EQ(results.getTwoQubitGates(),
-//        test.expectedMinimalTwoQubitGates); EXPECT_EQ(results.getGates(),
-//                  test.expectedMinimalGatesAtMinimalTwoQubitGates);
-//    }
-//
-//    TEST_P(SynthesisTest, TestDestabilizerGates) {
-//        if (!initialTableauWithDestabilizer.getTableau().empty()) {
-//            std::cout << "Testing with destabilizer" << std::endl;
-//            config.target    = TargetMetric::Gates;
-//            config.useMaxSAT = true;
-//
-//            synthesizer.synthesize(config);
-//            synthesizerWithDestabilizer.synthesize(config);
-//            results                 = synthesizer.getResults();
-//            resultsWithDestabilizer =
-//            synthesizerWithDestabilizer.getResults();
-//
-//            EXPECT_GE(resultsWithDestabilizer.getGates(), results.getGates());
-//        } else {
-//            std::cout << "Testing without destabilizer" << std::endl;
-//            config.target    = TargetMetric::Gates;
-//            config.useMaxSAT = true;
-//
-//            synthesizer.synthesize(config);
-//            results = synthesizer.getResults();
-//        }
-//    }
-//
-//    TEST_P(SynthesisTest, TestDestabilizerDepth) {
-//        if (!initialTableauWithDestabilizer.getTableau().empty()) {
-//            std::cout << "Testing with destabilizer" << std::endl;
-//            config.target    = TargetMetric::Depth;
-//            config.useMaxSAT = true;
-//
-//            synthesizer.synthesize(config);
-//            synthesizerWithDestabilizer.synthesize(config);
-//            results                 = synthesizer.getResults();
-//            resultsWithDestabilizer =
-//            synthesizerWithDestabilizer.getResults();
-//
-//            EXPECT_GE(resultsWithDestabilizer.getDepth(), results.getDepth());
-//        } else {
-//            std::cout << "Testing without destabilizer" << std::endl;
-//            config.target    = TargetMetric::Gates;
-//            config.useMaxSAT = true;
-//
-//            synthesizer.synthesize(config);
-//            results = synthesizer.getResults();
-//        }
-//    }
-//
-//    TEST_P(SynthesisTest, TestDestabilizerTwoQubitGates) {
-//        if (!initialTableauWithDestabilizer.getTableau().empty()) {
-//            std::cout << "Testing with destabilizer" << std::endl;
-//            config.target    = TargetMetric::TwoQubitGates;
-//            config.useMaxSAT = true;
-//
-//            synthesizer.synthesize(config);
-//            synthesizerWithDestabilizer.synthesize(config);
-//            results                 = synthesizer.getResults();
-//            resultsWithDestabilizer =
-//            synthesizerWithDestabilizer.getResults();
-//
-//            EXPECT_GE(resultsWithDestabilizer.getTwoQubitGates(),
-//                      results.getTwoQubitGates());
-//        } else {
-//            std::cout << "Testing without destabilizer" << std::endl;
-//            config.target    = TargetMetric::Gates;
-//            config.useMaxSAT = true;
-//
-//            synthesizer.synthesize(config);
-//            results = synthesizer.getResults();
-//        }
-//    }
-
-} // namespace cs
diff --git a/test/test_simexec_simple.cpp b/test/test_simexec_simple.cpp
new file mode 100644
index 0000000..bfeab3f
--- /dev/null
+++ b/test/test_simexec_simple.cpp
@@ -0,0 +1,19 @@
+#include "CircuitSimulator.hpp"
+#include "CircuitSimulatorExecutor.hpp"
+#include "SimulationTask.hpp"
+
+#include <gtest/gtest.h>
+#include <memory>
+
+TEST(DDSIMExecSimpleTest, EmptyCircuit) {
+  auto qc               = std::make_unique<qc::QuantumComputation>(2U);
+  auto clonedQC         = std::make_unique<qc::QuantumComputation>(qc->clone());
+  auto simulationTask   = std::make_unique<SimulationTask>(std::move(clonedQC));
+  auto circuitSimulator = std::make_unique<CircuitSimulator<>>(std::move(qc));
+  auto circuitSimulatorExecutor = std::make_unique<CircuitSimulatorExecutor>();
+  circuitSimulatorExecutor->setCircuitSimulator(circuitSimulator);
+  circuitSimulatorExecutor->setMSimTask(simulationTask);
+  json const result = circuitSimulatorExecutor->executeTask();
+
+  EXPECT_EQ(1, result["00"]);
+}

From 791147757cdcd3ae006d04d1d07f407fd392ef06 Mon Sep 17 00:00:00 2001
From: Tianyi Wang <tianyi1.wang@tum.de>
Date: Thu, 1 Jun 2023 22:12:40 +0200
Subject: [PATCH 13/43] Clean up the test suite for SimulatorExecutors

---
 test/test_simexec.cpp | 73 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 73 insertions(+)
 create mode 100644 test/test_simexec.cpp

diff --git a/test/test_simexec.cpp b/test/test_simexec.cpp
new file mode 100644
index 0000000..ea6bd4e
--- /dev/null
+++ b/test/test_simexec.cpp
@@ -0,0 +1,73 @@
+#include "CircuitSimulatorExecutor.hpp"
+#include "SimulationTask.hpp"
+
+#include "gtest/gtest.h"
+
+struct TestConfiguration {
+  // given input
+  std::string description;
+  std::string initialCircuit;
+
+  // expected output
+  std::size_t expected00{};
+};
+
+// NOLINTNEXTLINE (readability-identifier-naming)
+inline void from_json(const nlohmann::json& j, TestConfiguration& test) {
+  test.description    = j.at("description").get<std::string>();
+  test.initialCircuit = j.at("initial_circuit").get<std::string>();
+  test.expected00     = j.at("expected_00").get<std::size_t>();
+}
+
+static std::vector<TestConfiguration> getTests(const std::string& path) {
+  std::ifstream  input(path);
+  nlohmann::json j;
+  input >> j;
+  return j;
+}
+
+class SimulatorTest : public ::testing::TestWithParam<TestConfiguration> {
+protected:
+  void SetUp() override {
+    test = GetParam();
+
+    if (test.initialCircuit.empty()) {
+      throw std::runtime_error("No circuit!");
+    }
+    std::stringstream      ss(test.initialCircuit);
+    qc::QuantumComputation qc{};
+    qc.import(ss, qc::Format::OpenQASM);
+    std::cout << "Initial circuit:\n" << qc;
+
+    qcForTask      = std::make_unique<qc::QuantumComputation>(qc.clone());
+    qcForSim       = std::make_unique<qc::QuantumComputation>(qc.clone());
+    simulationTask = std::make_unique<SimulationTask>(std::move(qcForTask));
+    circuitSimulator =
+        std::make_unique<CircuitSimulator<>>(std::move(qcForSim));
+    circuitSimulatorExecutor = std::make_unique<CircuitSimulatorExecutor>();
+    circuitSimulatorExecutor->setCircuitSimulator(circuitSimulator);
+    circuitSimulatorExecutor->setMSimTask(simulationTask);
+  }
+
+  void TearDown() override { std::cout << "Tearing down...\n"; }
+
+  std::unique_ptr<qc::QuantumComputation>   qcForTask;
+  std::unique_ptr<qc::QuantumComputation>   qcForSim;
+  std::unique_ptr<SimulationTask>           simulationTask;
+  std::unique_ptr<CircuitSimulator<>>       circuitSimulator;
+  std::unique_ptr<CircuitSimulatorExecutor> circuitSimulatorExecutor;
+  TestConfiguration                         test;
+};
+
+INSTANTIATE_TEST_SUITE_P(
+    Circuits, SimulatorTest,
+    testing::ValuesIn(getTests(
+        "/Users/tianyiwang/Documents/tum/GR/repos/dd_eval/test/circuits.json")),
+    [](const testing::TestParamInfo<SimulatorTest::ParamType>& inf) {
+      return inf.param.description;
+    });
+
+TEST_P(SimulatorTest, EmptyCircuit) {
+  json const result = circuitSimulatorExecutor->executeTask();
+  EXPECT_EQ(result["00"], test.expected00);
+}

From 032226e2783a98425cd9feaa09c39f250d2f0d5a Mon Sep 17 00:00:00 2001
From: Tianyi Wang <tianyi1.wang@tum.de>
Date: Fri, 2 Jun 2023 13:58:10 +0200
Subject: [PATCH 14/43] Remove redundant comments

---
 include/CircuitSimulatorExecutor.hpp | 11 +--------
 include/Executor.hpp                 | 12 ++++------
 include/SimulationExecutor.hpp       |  3 ---
 src/CMakeLists.txt                   |  3 ---
 src/CircuitSimulatorExecutor.cpp     | 32 +++----------------------
 src/Executor.cpp                     | 35 ----------------------------
 src/SimulationExecutor.cpp           |  2 --
 src/SimulationTask.cpp               |  3 ++-
 8 files changed, 11 insertions(+), 90 deletions(-)
 delete mode 100644 src/Executor.cpp

diff --git a/include/CircuitSimulatorExecutor.hpp b/include/CircuitSimulatorExecutor.hpp
index 3449802..a9ab970 100644
--- a/include/CircuitSimulatorExecutor.hpp
+++ b/include/CircuitSimulatorExecutor.hpp
@@ -6,10 +6,7 @@
 class CircuitSimulatorExecutor : public SimulationExecutor {
 public:
   CircuitSimulatorExecutor() = default;
-
-  //    explicit CircuitSimulatorExecutor();
-  //  explicit CircuitSimulatorExecutor(std::unique_ptr<SimulationTask>
-  //  &mSimTask);
+  //  simulator and task must be set before use
 
   json        executeTask() override;
   std::string getIdentifier() override;
@@ -30,10 +27,4 @@ class CircuitSimulatorExecutor : public SimulationExecutor {
 
   void
   setCircuitSimulator(std::unique_ptr<CircuitSimulator<>>& circuitSimulator);
-  // public:
-  //     [[nodiscard]] const CircuitSimulator<dd::DDPackageConfig>
-  //     &getCircuitSimulator() const;
-  //
-  //     void setCircuitSimulator(const CircuitSimulator<dd::DDPackageConfig>
-  //     &circuitSimulator);
 };
diff --git a/include/Executor.hpp b/include/Executor.hpp
index 5775e04..5042bcd 100644
--- a/include/Executor.hpp
+++ b/include/Executor.hpp
@@ -6,14 +6,12 @@
 
 class Executor {
 public:
-  virtual ~Executor()        = default;
-  virtual json executeTask() = 0;
-  explicit Executor()        = default;
-  //  virtual const std::unique_ptr<Task>& getTask();
-  //  virtual void                         setTask(const std::unique_ptr<Task>
-  //  &task);
+  virtual ~Executor() = default;
+  explicit Executor() = default;
+
+  virtual json        executeTask()   = 0;
   virtual std::string getIdentifier() = 0;
 
 private:
-  std::unique_ptr<Task> mTask;
+  std::unique_ptr<Task> task;
 };
diff --git a/include/SimulationExecutor.hpp b/include/SimulationExecutor.hpp
index 09b8587..38cffdc 100644
--- a/include/SimulationExecutor.hpp
+++ b/include/SimulationExecutor.hpp
@@ -6,9 +6,6 @@
 class SimulationExecutor : public Executor {
 public:
   SimulationExecutor() = default;
-  explicit SimulationExecutor(std::unique_ptr<SimulationTask>& task) {
-    setTask(task);
-  }
 
   const std::unique_ptr<SimulationTask>& getMTask();
 
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index e1b6044..a113869 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -14,12 +14,9 @@ if(NOT TARGET ${PROJECT_NAME})
     ${PROJECT_SOURCE_DIR}/include/VerificationExecutor.hpp
     ${PROJECT_SOURCE_DIR}/include/CircuitSimulatorExecutor.hpp
     ${PROJECT_SOURCE_DIR}/include/AlternatingVerificationExecutor.hpp
-    # ${PROJECT_SOURCE_DIR}/include/Results.hpp
     ${PROJECT_SOURCE_DIR}/include/Task.hpp
     ${PROJECT_SOURCE_DIR}/include/SimulationTask.hpp
     ${PROJECT_SOURCE_DIR}/include/VerificationTask.hpp
-    # Result.cpp
-    Executor.cpp
     SimulationExecutor.cpp
     CircuitSimulatorExecutor.cpp
     VerificationExecutor.cpp
diff --git a/src/CircuitSimulatorExecutor.cpp b/src/CircuitSimulatorExecutor.cpp
index 6153626..1e11f5c 100644
--- a/src/CircuitSimulatorExecutor.cpp
+++ b/src/CircuitSimulatorExecutor.cpp
@@ -1,21 +1,10 @@
 #include "CircuitSimulatorExecutor.hpp"
 
-class CircuitSimulatorExecutor::CircuitSimulatorExecutor {
-  //    CircuitSimulatorExecutor(std::unique_ptr<SimulationTask> &simTask) {
-  //        setMSimTask(simTask);
-  //    }
-  //    CircuitSimulatorExecutor(std::unique_ptr<SimulationTask> &simTask) {
-  //        mSimTask = std::move(simTask);
-  //    }
-  //    CircuitSimulatorExecutor() {
-  //        mCircuitSimulator =
-  //        CircuitSimulator(std::move(this->getMSimTask()->getQc()));
-  //    }
-};
+class CircuitSimulatorExecutor::CircuitSimulatorExecutor {};
 
 std::string CircuitSimulatorExecutor::getIdentifier() {
   return {"This is a circuit simulator executor"};
-  // refactor
+  // refactor. how?
 }
 
 json CircuitSimulatorExecutor::executeTask() {
@@ -24,7 +13,6 @@ json CircuitSimulatorExecutor::executeTask() {
 
   // execute the actual task
   const auto results = mCircuitSimulator->simulate(1024U);
-  //  std::cout << results << std::endl;
   // use the results
   // Add memory usage
 
@@ -40,9 +28,8 @@ json CircuitSimulatorExecutor::executeTask() {
   result["01"] = results.count("01");
   result["10"] = results.count("10");
   result["11"] = results.count("11");
-  // what about more qubits?
+  // what about circuits with not 2 qubits?
   return result;
-  //    return SimulationExecutor::executeTask();
 }
 
 const std::unique_ptr<SimulationTask>&
@@ -64,16 +51,3 @@ void CircuitSimulatorExecutor::setCircuitSimulator(
     std::unique_ptr<CircuitSimulator<>>& circuitSimulator) {
   mCircuitSimulator = std::move(circuitSimulator);
 }
-
-// CircuitSimulatorExecutor(std::unique_ptr<SimulationTask> &mSimTask)
-//         : SimulationExecutor(task), mSimTask(mSimTask) {}
-
-// const CircuitSimulator<dd::DDPackageConfig>
-// &CircuitSimulatorExecutor::getCircuitSimulator() const {
-//     return circuitSimulator;
-// }
-//
-// void CircuitSimulatorExecutor::setCircuitSimulator(const
-// CircuitSimulator<dd::DDPackageConfig> &circuitSimulator) {
-//     CircuitSimulatorExecutor::circuitSimulator = circuitSimulator;
-// }
diff --git a/src/Executor.cpp b/src/Executor.cpp
deleted file mode 100644
index 2e01da0..0000000
--- a/src/Executor.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-#include "Executor.hpp"
-
-#include <chrono>
-
-class Executor::Executor {
-  //  json executeTask() {
-  //    json result;
-  //    auto start = std::chrono::high_resolution_clock::now();
-  //
-  //    //    this->executeTask();
-  //    // execute the actual task
-  //    // Add memory usage
-  //
-  //    auto stop = std::chrono::high_resolution_clock::now();
-  //    auto runtime =
-  //        std::chrono::duration_cast<std::chrono::microseconds>(stop - start);
-  //    result["runtime"] = runtime.count();
-  //    std::string const identifier =
-  //        this->getTask()->getIdentifier() + "_" + this->getIdentifier();
-  //    result["identifier"] = identifier;
-  //    return result;
-  //    // what about the Results class?
-  //    json result;
-  //    return result;
-  //  }
-  //};
-
-  // add adapter for simulators
-
-  // void Executor::setTask(const std::unique_ptr<Task> &task) {
-  //   this->mTask = task;
-  // }
-  //
-  // const std::unique_ptr<Task>& Executor::getTask() { return mTask; }
-};
diff --git a/src/SimulationExecutor.cpp b/src/SimulationExecutor.cpp
index 73d9c3e..6371eb4 100644
--- a/src/SimulationExecutor.cpp
+++ b/src/SimulationExecutor.cpp
@@ -1,7 +1,5 @@
 #include "SimulationExecutor.hpp"
 
-// json SimulationExecutor::executeTask() { return nullptr; }
-
 const std::unique_ptr<SimulationTask>& SimulationExecutor::getMTask() {
   return mTask;
 }
diff --git a/src/SimulationTask.cpp b/src/SimulationTask.cpp
index 0dc1564..fa6fa33 100644
--- a/src/SimulationTask.cpp
+++ b/src/SimulationTask.cpp
@@ -1,6 +1,7 @@
 #include "SimulationTask.hpp"
 // take one circuit
+
 std::string SimulationTask::getIdentifier() {
   return "This is a simulation task";
-  // refactor
+  // refactor. how?
 }

From 60c8c090d881f7db072f41a70e8912e2912e27e2 Mon Sep 17 00:00:00 2001
From: Tianyi Wang <tianyi1.wang@tum.de>
Date: Fri, 2 Jun 2023 14:25:38 +0200
Subject: [PATCH 15/43] Replace absolute path with relative path

---
 test/CMakeLists.txt   | 3 ++-
 test/test_simexec.cpp | 4 +---
 2 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index e464a8d..92f6c5d 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -9,6 +9,7 @@ if(NOT TARGET gtest OR NOT TARGET gmock)
   add_subdirectory("${PROJECT_SOURCE_DIR}/${GTEST_PATH}" "${GTEST_PATH}"
                    EXCLUDE_FROM_ALL)
 endif()
-
+configure_file(${CMAKE_SOURCE_DIR}/test/circuits.json
+               ${CMAKE_CURRENT_BINARY_DIR}/circuits.json COPYONLY)
 package_add_test(${PROJECT_NAME}_test ${PROJECT_NAME} test_ddsim_simple.cpp
                  test_qcec_simple.cpp test_simexec_simple.cpp test_simexec.cpp)
diff --git a/test/test_simexec.cpp b/test/test_simexec.cpp
index ea6bd4e..b889181 100644
--- a/test/test_simexec.cpp
+++ b/test/test_simexec.cpp
@@ -60,9 +60,7 @@ class SimulatorTest : public ::testing::TestWithParam<TestConfiguration> {
 };
 
 INSTANTIATE_TEST_SUITE_P(
-    Circuits, SimulatorTest,
-    testing::ValuesIn(getTests(
-        "/Users/tianyiwang/Documents/tum/GR/repos/dd_eval/test/circuits.json")),
+    Circuits, SimulatorTest, testing::ValuesIn(getTests("circuits.json")),
     [](const testing::TestParamInfo<SimulatorTest::ParamType>& inf) {
       return inf.param.description;
     });

From 30350b2e2239c05bd493e20dbc93409f5baf625c Mon Sep 17 00:00:00 2001
From: Tianyi Wang <tianyi1.wang@tum.de>
Date: Fri, 2 Jun 2023 14:26:09 +0200
Subject: [PATCH 16/43] Refactor the results json

---
 src/CircuitSimulatorExecutor.cpp | 21 +++++++++++----------
 test/circuits.json               |  2 +-
 test/test_simexec.cpp            | 12 +++++++++++-
 test/test_simexec_simple.cpp     |  2 +-
 4 files changed, 24 insertions(+), 13 deletions(-)

diff --git a/src/CircuitSimulatorExecutor.cpp b/src/CircuitSimulatorExecutor.cpp
index 1e11f5c..53988ff 100644
--- a/src/CircuitSimulatorExecutor.cpp
+++ b/src/CircuitSimulatorExecutor.cpp
@@ -7,28 +7,29 @@ std::string CircuitSimulatorExecutor::getIdentifier() {
   // refactor. how?
 }
 
+template <typename KTy, typename VTy>
+inline void toJson(json& j, const std::map<KTy, VTy>& m) {
+  for (const auto& entry : m) {
+    j[entry.first] = entry.second;
+  }
+}
+
 json CircuitSimulatorExecutor::executeTask() {
   json result;
   auto start = std::chrono::high_resolution_clock::now();
 
-  // execute the actual task
   const auto results = mCircuitSimulator->simulate(1024U);
-  // use the results
+  toJson(result, results);
   // Add memory usage
 
   auto stop = std::chrono::high_resolution_clock::now();
   auto runtime =
       std::chrono::duration_cast<std::chrono::microseconds>(stop - start);
-  result["runtime"]            = runtime.count();
-  std::string const identifier = "test identifier";
-  //      this->getTask()->getIdentifier() + "_" + this->getIdentifier();
+  result["runtime"] = runtime.count();
+  std::string const identifier =
+      this->getMSimTask()->getIdentifier() + "_" + this->getIdentifier();
   result["identifier"] = identifier;
 
-  result["00"] = results.count("00");
-  result["01"] = results.count("01");
-  result["10"] = results.count("10");
-  result["11"] = results.count("11");
-  // what about circuits with not 2 qubits?
   return result;
 }
 
diff --git a/test/circuits.json b/test/circuits.json
index b0e91e3..dac448d 100644
--- a/test/circuits.json
+++ b/test/circuits.json
@@ -2,6 +2,6 @@
   {
     "description": "empty_circuit",
     "initial_circuit": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];\n",
-    "expected_00": 1
+    "expected_00": 1024
   }
 ]
diff --git a/test/test_simexec.cpp b/test/test_simexec.cpp
index b889181..2181cb7 100644
--- a/test/test_simexec.cpp
+++ b/test/test_simexec.cpp
@@ -37,7 +37,7 @@ class SimulatorTest : public ::testing::TestWithParam<TestConfiguration> {
     std::stringstream      ss(test.initialCircuit);
     qc::QuantumComputation qc{};
     qc.import(ss, qc::Format::OpenQASM);
-    std::cout << "Initial circuit:\n" << qc;
+    std::cout << "Circuit:\n" << qc;
 
     qcForTask      = std::make_unique<qc::QuantumComputation>(qc.clone());
     qcForSim       = std::make_unique<qc::QuantumComputation>(qc.clone());
@@ -59,6 +59,14 @@ class SimulatorTest : public ::testing::TestWithParam<TestConfiguration> {
   TestConfiguration                         test;
 };
 
+void printAll(const json& jsonObject) {
+  for (auto it = jsonObject.begin(); it != jsonObject.end(); ++it) {
+    const auto& key   = it.key();
+    const auto& value = it.value();
+    std::cout << key << ": " << value << std::endl;
+  }
+}
+
 INSTANTIATE_TEST_SUITE_P(
     Circuits, SimulatorTest, testing::ValuesIn(getTests("circuits.json")),
     [](const testing::TestParamInfo<SimulatorTest::ParamType>& inf) {
@@ -67,5 +75,7 @@ INSTANTIATE_TEST_SUITE_P(
 
 TEST_P(SimulatorTest, EmptyCircuit) {
   json const result = circuitSimulatorExecutor->executeTask();
+  std::cout << "Results:" << std::endl;
+  printAll(result);
   EXPECT_EQ(result["00"], test.expected00);
 }
diff --git a/test/test_simexec_simple.cpp b/test/test_simexec_simple.cpp
index bfeab3f..5b5dfad 100644
--- a/test/test_simexec_simple.cpp
+++ b/test/test_simexec_simple.cpp
@@ -15,5 +15,5 @@ TEST(DDSIMExecSimpleTest, EmptyCircuit) {
   circuitSimulatorExecutor->setMSimTask(simulationTask);
   json const result = circuitSimulatorExecutor->executeTask();
 
-  EXPECT_EQ(1, result["00"]);
+  EXPECT_EQ(1024, result["00"]);
 }

From d03e6617d42721ad3a393b6f90114aa94671b7ca Mon Sep 17 00:00:00 2001
From: Tianyi Wang <tianyi1.wang@tum.de>
Date: Fri, 2 Jun 2023 15:14:16 +0200
Subject: [PATCH 17/43] Added verification executor classes and a simple test

---
 include/AlternatingVerificationExecutor.hpp | 29 ++++++++++++-
 include/VerificationExecutor.hpp            | 14 ++++---
 include/VerificationTask.hpp                | 15 +++----
 src/AlternatingVerificationExecutor.cpp     | 46 +++++++++++++++++++++
 src/SimulationTask.cpp                      |  1 -
 src/VerificationExecutor.cpp                |  9 +++-
 src/VerificationTask.cpp                    |  6 ++-
 test/CMakeLists.txt                         | 10 ++++-
 test/test_qcecexec_simple.cpp               | 26 ++++++++++++
 9 files changed, 138 insertions(+), 18 deletions(-)
 create mode 100644 test/test_qcecexec_simple.cpp

diff --git a/include/AlternatingVerificationExecutor.hpp b/include/AlternatingVerificationExecutor.hpp
index 4fa2263..d93f83b 100644
--- a/include/AlternatingVerificationExecutor.hpp
+++ b/include/AlternatingVerificationExecutor.hpp
@@ -1,5 +1,32 @@
 #pragma once
 
+#include "EquivalenceCheckingManager.hpp"
 #include "VerificationExecutor.hpp"
 
-class AlternatingVerificationExecutor : public VerificationExecutor {};
+class AlternatingVerificationExecutor : public VerificationExecutor {
+public:
+  AlternatingVerificationExecutor() = default;
+  // checker and task must be set before use
+
+  json        executeTask() override;
+  std::string getIdentifier() override;
+
+private:
+  std::unique_ptr<VerificationTask> mVerTask;
+
+public:
+  [[nodiscard]] const std::unique_ptr<VerificationTask>& getMVerTask() const;
+
+  void setMVerTask(std::unique_ptr<VerificationTask>& verTask);
+
+private:
+  std::unique_ptr<ec::EquivalenceCheckingManager> mEquivalenceCheckingManager;
+
+public:
+  const std::unique_ptr<ec::EquivalenceCheckingManager>&
+  getEquivalenceCheckingManager();
+
+  void
+  setEquivalenceCheckingManager(std::unique_ptr<ec::EquivalenceCheckingManager>&
+                                    equivalenceCheckingManager);
+};
diff --git a/include/VerificationExecutor.hpp b/include/VerificationExecutor.hpp
index ed47c56..1f2f612 100644
--- a/include/VerificationExecutor.hpp
+++ b/include/VerificationExecutor.hpp
@@ -5,9 +5,13 @@
 
 class VerificationExecutor : public Executor {
 public:
-  //  explicit VerificationExecutor(const std::shared_ptr<VerificationTask>&
-  //  task) {
-  //    setTask(task);
-  //  };
-  //  json executeTask() override;
+  VerificationExecutor() = default;
+
+private:
+  std::unique_ptr<VerificationTask> mTask;
+
+public:
+  const std::unique_ptr<VerificationTask>& getMTask() const;
+
+  void setMTask(std::unique_ptr<VerificationTask>& task);
 };
diff --git a/include/VerificationTask.hpp b/include/VerificationTask.hpp
index 795362a..4032287 100644
--- a/include/VerificationTask.hpp
+++ b/include/VerificationTask.hpp
@@ -5,12 +5,13 @@
 
 class VerificationTask : public Task {
 public:
-  VerificationTask(qc::QuantumComputation qc1, qc::QuantumComputation qc2) {
-    this->qc1 = qc1.clone();
-    this->qc2 = qc2.clone();
-  };
+  VerificationTask() = default;
+  VerificationTask(std::unique_ptr<qc::QuantumComputation> qc1,
+                   std::unique_ptr<qc::QuantumComputation> qc2)
+      : qc1(std::move(qc1)), qc2(std::move(qc2)) {}
+  std::string getIdentifier() override;
 
-private:
-  qc::QuantumComputation qc1;
-  qc::QuantumComputation qc2;
+protected:
+  std::unique_ptr<qc::QuantumComputation> qc1;
+  std::unique_ptr<qc::QuantumComputation> qc2;
 };
diff --git a/src/AlternatingVerificationExecutor.cpp b/src/AlternatingVerificationExecutor.cpp
index d3d1834..1077342 100644
--- a/src/AlternatingVerificationExecutor.cpp
+++ b/src/AlternatingVerificationExecutor.cpp
@@ -1 +1,47 @@
 #include "AlternatingVerificationExecutor.hpp"
+
+class AlternatingVerificationExecutor::AlternatingVerificationExecutor {};
+
+std::string AlternatingVerificationExecutor::getIdentifier() {
+  return {"This is a alternating verification executor"};
+  // refactor. how?
+}
+
+json AlternatingVerificationExecutor::executeTask() {
+  json result;
+  auto start = std::chrono::high_resolution_clock::now();
+
+  mEquivalenceCheckingManager->run();
+  result = mEquivalenceCheckingManager->getResults().json();
+  // Add memory usage
+  auto stop = std::chrono::high_resolution_clock::now();
+  auto runtime =
+      std::chrono::duration_cast<std::chrono::microseconds>(stop - start);
+  result["runtime"] = runtime.count();
+  std::string const identifier =
+      this->getMVerTask()->getIdentifier() + "_" + this->getIdentifier();
+  result["identifier"] = identifier;
+
+  return result;
+}
+
+const std::unique_ptr<VerificationTask>&
+AlternatingVerificationExecutor::getMVerTask() const {
+  return mVerTask;
+}
+
+void AlternatingVerificationExecutor::setMVerTask(
+    std::unique_ptr<VerificationTask>& verTask) {
+  mVerTask = std::move(verTask);
+}
+
+const std::unique_ptr<ec::EquivalenceCheckingManager>&
+AlternatingVerificationExecutor::getEquivalenceCheckingManager() {
+  return mEquivalenceCheckingManager;
+}
+
+void AlternatingVerificationExecutor::setEquivalenceCheckingManager(
+    std::unique_ptr<ec::EquivalenceCheckingManager>&
+        equivalenceCheckingManager) {
+  mEquivalenceCheckingManager = std::move(equivalenceCheckingManager);
+}
diff --git a/src/SimulationTask.cpp b/src/SimulationTask.cpp
index fa6fa33..27db4c2 100644
--- a/src/SimulationTask.cpp
+++ b/src/SimulationTask.cpp
@@ -1,5 +1,4 @@
 #include "SimulationTask.hpp"
-// take one circuit
 
 std::string SimulationTask::getIdentifier() {
   return "This is a simulation task";
diff --git a/src/VerificationExecutor.cpp b/src/VerificationExecutor.cpp
index e35f42e..596852b 100644
--- a/src/VerificationExecutor.cpp
+++ b/src/VerificationExecutor.cpp
@@ -1,3 +1,10 @@
 #include "VerificationExecutor.hpp"
 
-// json VerificationExecutor::executeTask() { return nullptr; }
+const std::unique_ptr<VerificationTask>&
+VerificationExecutor::getMTask() const {
+  return mTask;
+}
+
+void VerificationExecutor::setMTask(std::unique_ptr<VerificationTask>& task) {
+  mTask = std::move(task);
+}
diff --git a/src/VerificationTask.cpp b/src/VerificationTask.cpp
index 9d76be3..bf4c744 100644
--- a/src/VerificationTask.cpp
+++ b/src/VerificationTask.cpp
@@ -1,2 +1,6 @@
 #include "VerificationTask.hpp"
-// take two circuits
+
+std::string VerificationTask::getIdentifier() {
+  return "This is a verification task";
+  // refactor. how?
+}
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 92f6c5d..e1a6cfc 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -11,5 +11,11 @@ if(NOT TARGET gtest OR NOT TARGET gmock)
 endif()
 configure_file(${CMAKE_SOURCE_DIR}/test/circuits.json
                ${CMAKE_CURRENT_BINARY_DIR}/circuits.json COPYONLY)
-package_add_test(${PROJECT_NAME}_test ${PROJECT_NAME} test_ddsim_simple.cpp
-                 test_qcec_simple.cpp test_simexec_simple.cpp test_simexec.cpp)
+package_add_test(
+  ${PROJECT_NAME}_test
+  ${PROJECT_NAME}
+  test_ddsim_simple.cpp
+  test_qcec_simple.cpp
+  test_simexec_simple.cpp
+  test_simexec.cpp
+  test_qcecexec_simple.cpp)
diff --git a/test/test_qcecexec_simple.cpp b/test/test_qcecexec_simple.cpp
new file mode 100644
index 0000000..d365d20
--- /dev/null
+++ b/test/test_qcecexec_simple.cpp
@@ -0,0 +1,26 @@
+#include "AlternatingVerificationExecutor.hpp"
+#include "EquivalenceCheckingManager.hpp"
+#include "VerificationTask.hpp"
+
+#include <gtest/gtest.h>
+#include <memory>
+
+TEST(QCECExecSimpleTest, EmptyCircuits) {
+  auto qc        = std::make_unique<qc::QuantumComputation>(2U);
+  auto clonedQC  = std::make_unique<qc::QuantumComputation>(qc->clone());
+  auto clonedQC2 = qc->clone();
+  auto clonedQC3 = qc->clone();
+  auto verificationTask =
+      std::make_unique<VerificationTask>(std::move(qc), std::move(clonedQC));
+  auto equivalenceCheckingManager =
+      std::make_unique<ec::EquivalenceCheckingManager>(clonedQC2, clonedQC3);
+  auto alternatingVerificationExecutor =
+      std::make_unique<AlternatingVerificationExecutor>();
+  alternatingVerificationExecutor->setMVerTask(verificationTask);
+  alternatingVerificationExecutor->setEquivalenceCheckingManager(
+      equivalenceCheckingManager);
+
+  json const result = alternatingVerificationExecutor->executeTask();
+
+  EXPECT_EQ("equivalent", result["equivalence"]);
+}

From 2f7032dd45e92d192509b60fdcbc40b8b96fb18f Mon Sep 17 00:00:00 2001
From: Tianyi Wang <tianyi1.wang@tum.de>
Date: Fri, 2 Jun 2023 16:10:34 +0200
Subject: [PATCH 18/43] Delete temporarily obsolete Results class

---
 include/Results.hpp | 23 -----------------------
 src/Result.cpp      | 29 -----------------------------
 2 files changed, 52 deletions(-)
 delete mode 100644 include/Results.hpp
 delete mode 100644 src/Result.cpp

diff --git a/include/Results.hpp b/include/Results.hpp
deleted file mode 100644
index 56d509a..0000000
--- a/include/Results.hpp
+++ /dev/null
@@ -1,23 +0,0 @@
-// #pragma once
-//
-// #include "Executor.hpp"
-// #include "Task.hpp"
-//
-// #include <nlohmann/json.hpp>
-//
-// using json = nlohmann::json;
-//
-// class Results {
-// public:
-//   virtual ~Results() = default;
-//
-//   virtual json        toJson() const = 0;
-//   virtual std::string toString() const { return toJson().dump(2); }
-//
-//   Results(Task task, Executor executor) {
-//     identifier = task.getIdentifier() + "_" + executor.getIdentifier();
-//   }
-//
-// private:
-//   std::string identifier;
-// };
diff --git a/src/Result.cpp b/src/Result.cpp
deleted file mode 100644
index fef28a5..0000000
--- a/src/Result.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-// #include "Result.hpp"
-
-// Result::Result(const std::string& name, double value) : name_(name),
-// value_(value) {}
-//
-// json Result::toJson() const {
-//     json resultJson;
-//     resultJson["name"] = name_;
-//     resultJson["value"] = value_;
-//     return resultJson;
-// }
-//
-// std::string Result::toString() const {
-//     return toJson().dump();
-// }
-
-#include "Results.hpp"
-
-// Results::Results(const std::string& name, double value)
-//     : name_(name), value_(value) {}
-//
-// json Result::toJson() const {
-//   json resultJson;
-//   resultJson["name"]  = name_;
-//   resultJson["value"] = value_;
-//   return resultJson;
-// }
-//
-// std::string Result::toString() const { return toJson().dump(); }

From ed137ab6422d3e1c5820e9e3bc14bb3982dcad12 Mon Sep 17 00:00:00 2001
From: Tianyi Wang <tianyi1.wang@tum.de>
Date: Fri, 2 Jun 2023 16:11:25 +0200
Subject: [PATCH 19/43] Add qcec tests (incl. refactoring ddsim tests to avoid
 name collisions)

---
 include/TestHelpers.hpp |  5 +++
 src/CMakeLists.txt      |  2 +
 src/TestHelpers.cpp     | 11 ++++++
 test/CMakeLists.txt     |  5 ++-
 test/equi_circuits.json |  8 ++++
 test/test_qcecexec.cpp  | 86 +++++++++++++++++++++++++++++++++++++++++
 test/test_simexec.cpp   | 25 +++++-------
 7 files changed, 125 insertions(+), 17 deletions(-)
 create mode 100644 include/TestHelpers.hpp
 create mode 100644 src/TestHelpers.cpp
 create mode 100644 test/equi_circuits.json
 create mode 100644 test/test_qcecexec.cpp

diff --git a/include/TestHelpers.hpp b/include/TestHelpers.hpp
new file mode 100644
index 0000000..7a90c94
--- /dev/null
+++ b/include/TestHelpers.hpp
@@ -0,0 +1,5 @@
+#pragma once
+
+#include <nlohmann/json.hpp>
+
+void printAll(const nlohmann::json& json);
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index a113869..93f09be 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -17,6 +17,8 @@ if(NOT TARGET ${PROJECT_NAME})
     ${PROJECT_SOURCE_DIR}/include/Task.hpp
     ${PROJECT_SOURCE_DIR}/include/SimulationTask.hpp
     ${PROJECT_SOURCE_DIR}/include/VerificationTask.hpp
+    ${PROJECT_SOURCE_DIR}/include/TestHelpers.hpp
+    TestHelpers.cpp
     SimulationExecutor.cpp
     CircuitSimulatorExecutor.cpp
     VerificationExecutor.cpp
diff --git a/src/TestHelpers.cpp b/src/TestHelpers.cpp
new file mode 100644
index 0000000..48fdbf1
--- /dev/null
+++ b/src/TestHelpers.cpp
@@ -0,0 +1,11 @@
+#include "TestHelpers.hpp"
+
+#include <iostream>
+
+void printAll(const nlohmann::json& jsonObject) {
+  for (auto it = jsonObject.begin(); it != jsonObject.end(); ++it) {
+    const auto& key   = it.key();
+    const auto& value = it.value();
+    std::cout << key << ": " << value << std::endl;
+  }
+}
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index e1a6cfc..b286f68 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -11,6 +11,8 @@ if(NOT TARGET gtest OR NOT TARGET gmock)
 endif()
 configure_file(${CMAKE_SOURCE_DIR}/test/circuits.json
                ${CMAKE_CURRENT_BINARY_DIR}/circuits.json COPYONLY)
+configure_file(${CMAKE_SOURCE_DIR}/test/equi_circuits.json
+               ${CMAKE_CURRENT_BINARY_DIR}/equi_circuits.json COPYONLY)
 package_add_test(
   ${PROJECT_NAME}_test
   ${PROJECT_NAME}
@@ -18,4 +20,5 @@ package_add_test(
   test_qcec_simple.cpp
   test_simexec_simple.cpp
   test_simexec.cpp
-  test_qcecexec_simple.cpp)
+  test_qcecexec_simple.cpp
+  test_qcecexec.cpp)
diff --git a/test/equi_circuits.json b/test/equi_circuits.json
new file mode 100644
index 0000000..470aaca
--- /dev/null
+++ b/test/equi_circuits.json
@@ -0,0 +1,8 @@
+[
+  {
+    "description": "empty_circuits",
+    "initial_circuit1": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];\n",
+    "initial_circuit2": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];\n",
+    "expected_equivalence": "equivalent"
+  }
+]
diff --git a/test/test_qcecexec.cpp b/test/test_qcecexec.cpp
new file mode 100644
index 0000000..2691c42
--- /dev/null
+++ b/test/test_qcecexec.cpp
@@ -0,0 +1,86 @@
+#include "AlternatingVerificationExecutor.hpp"
+#include "TestHelpers.hpp"
+#include "VerificationTask.hpp"
+
+#include "gtest/gtest.h"
+
+struct TestConfigurationQCEC {
+  // given input
+  std::string description;
+  std::string initialCircuit1;
+  std::string initialCircuit2;
+
+  // expected output
+  std::string expectedEquivalence;
+};
+
+// NOLINTNEXTLINE (readability-identifier-naming)
+inline void from_json(const nlohmann::json& j, TestConfigurationQCEC& test) {
+  test.description         = j.at("description").get<std::string>();
+  test.initialCircuit1     = j.at("initial_circuit1").get<std::string>();
+  test.initialCircuit2     = j.at("initial_circuit2").get<std::string>();
+  test.expectedEquivalence = j.at("expected_equivalence").get<std::string>();
+}
+
+static std::vector<TestConfigurationQCEC> getTests(const std::string& path) {
+  std::ifstream  input(path);
+  nlohmann::json j;
+  input >> j;
+  return j;
+}
+
+class QCECExecTest : public ::testing::TestWithParam<TestConfigurationQCEC> {
+protected:
+  void SetUp() override {
+    test = GetParam();
+
+    if (test.initialCircuit1.empty() or test.initialCircuit2.empty()) {
+      throw std::runtime_error("Circuit missing!");
+    }
+    std::stringstream      ss1(test.initialCircuit1);
+    qc::QuantumComputation qc1{};
+    qc1.import(ss1, qc::Format::OpenQASM);
+    std::cout << "Circuit 1:\n" << qc1 << std::endl;
+
+    std::stringstream      ss2(test.initialCircuit2);
+    qc::QuantumComputation qc2{};
+    qc2.import(ss2, qc::Format::OpenQASM);
+    std::cout << "Circuit 2:\n" << qc2 << std::endl;
+
+    qc1ForTask       = std::make_unique<qc::QuantumComputation>(qc1.clone());
+    qc2ForTask       = std::make_unique<qc::QuantumComputation>(qc2.clone());
+    verificationTask = std::make_unique<VerificationTask>(
+        std::move(qc1ForTask), std::move(qc2ForTask));
+    equivalenceCheckingManager =
+        std::make_unique<ec::EquivalenceCheckingManager>(qc1.clone(),
+                                                         qc2.clone());
+    alternatingVerificationExecutor =
+        std::make_unique<AlternatingVerificationExecutor>();
+    alternatingVerificationExecutor->setEquivalenceCheckingManager(
+        equivalenceCheckingManager);
+    alternatingVerificationExecutor->setMVerTask(verificationTask);
+  }
+
+  void TearDown() override { std::cout << "Tearing down...\n"; }
+
+  std::unique_ptr<qc::QuantumComputation>         qc1ForTask;
+  std::unique_ptr<qc::QuantumComputation>         qc2ForTask;
+  std::unique_ptr<VerificationTask>               verificationTask;
+  std::unique_ptr<ec::EquivalenceCheckingManager> equivalenceCheckingManager;
+  std::unique_ptr<AlternatingVerificationExecutor>
+                        alternatingVerificationExecutor;
+  TestConfigurationQCEC test;
+};
+
+INSTANTIATE_TEST_SUITE_P(
+    Circuits, QCECExecTest, testing::ValuesIn(getTests("equi_circuits.json")),
+    [](const testing::TestParamInfo<QCECExecTest::ParamType>& inf) {
+      return inf.param.description;
+    });
+
+TEST_P(QCECExecTest, EmptyCircuits) {
+  json const result = alternatingVerificationExecutor->executeTask();
+  std::cout << "Results:" << std::endl;
+  printAll(result);
+  EXPECT_EQ(result["equivalence"], test.expectedEquivalence);
+}
diff --git a/test/test_simexec.cpp b/test/test_simexec.cpp
index 2181cb7..7f33ac8 100644
--- a/test/test_simexec.cpp
+++ b/test/test_simexec.cpp
@@ -1,9 +1,10 @@
 #include "CircuitSimulatorExecutor.hpp"
 #include "SimulationTask.hpp"
+#include "TestHelpers.hpp"
 
 #include "gtest/gtest.h"
 
-struct TestConfiguration {
+struct TestConfigurationDDSIM {
   // given input
   std::string description;
   std::string initialCircuit;
@@ -13,20 +14,20 @@ struct TestConfiguration {
 };
 
 // NOLINTNEXTLINE (readability-identifier-naming)
-inline void from_json(const nlohmann::json& j, TestConfiguration& test) {
+inline void from_json(const nlohmann::json& j, TestConfigurationDDSIM& test) {
   test.description    = j.at("description").get<std::string>();
   test.initialCircuit = j.at("initial_circuit").get<std::string>();
   test.expected00     = j.at("expected_00").get<std::size_t>();
 }
 
-static std::vector<TestConfiguration> getTests(const std::string& path) {
+static std::vector<TestConfigurationDDSIM> getTests(const std::string& path) {
   std::ifstream  input(path);
   nlohmann::json j;
   input >> j;
   return j;
 }
 
-class SimulatorTest : public ::testing::TestWithParam<TestConfiguration> {
+class DDSIMExecTest : public ::testing::TestWithParam<TestConfigurationDDSIM> {
 protected:
   void SetUp() override {
     test = GetParam();
@@ -56,24 +57,16 @@ class SimulatorTest : public ::testing::TestWithParam<TestConfiguration> {
   std::unique_ptr<SimulationTask>           simulationTask;
   std::unique_ptr<CircuitSimulator<>>       circuitSimulator;
   std::unique_ptr<CircuitSimulatorExecutor> circuitSimulatorExecutor;
-  TestConfiguration                         test;
+  TestConfigurationDDSIM                    test;
 };
 
-void printAll(const json& jsonObject) {
-  for (auto it = jsonObject.begin(); it != jsonObject.end(); ++it) {
-    const auto& key   = it.key();
-    const auto& value = it.value();
-    std::cout << key << ": " << value << std::endl;
-  }
-}
-
 INSTANTIATE_TEST_SUITE_P(
-    Circuits, SimulatorTest, testing::ValuesIn(getTests("circuits.json")),
-    [](const testing::TestParamInfo<SimulatorTest::ParamType>& inf) {
+    Circuits, DDSIMExecTest, testing::ValuesIn(getTests("circuits.json")),
+    [](const testing::TestParamInfo<DDSIMExecTest::ParamType>& inf) {
       return inf.param.description;
     });
 
-TEST_P(SimulatorTest, EmptyCircuit) {
+TEST_P(DDSIMExecTest, EmptyCircuit) {
   json const result = circuitSimulatorExecutor->executeTask();
   std::cout << "Results:" << std::endl;
   printAll(result);

From 10cfd3bfd7b9d6405719e3d11619090c0ffaf73a Mon Sep 17 00:00:00 2001
From: Tianyi Wang <tianyi1.wang@tum.de>
Date: Fri, 2 Jun 2023 16:46:07 +0200
Subject: [PATCH 20/43] Refactored exec and task identifier

---
 src/AlternatingVerificationExecutor.cpp | 3 +--
 src/CircuitSimulatorExecutor.cpp        | 3 +--
 src/SimulationTask.cpp                  | 5 +----
 src/VerificationTask.cpp                | 3 +--
 4 files changed, 4 insertions(+), 10 deletions(-)

diff --git a/src/AlternatingVerificationExecutor.cpp b/src/AlternatingVerificationExecutor.cpp
index 1077342..a24a000 100644
--- a/src/AlternatingVerificationExecutor.cpp
+++ b/src/AlternatingVerificationExecutor.cpp
@@ -3,8 +3,7 @@
 class AlternatingVerificationExecutor::AlternatingVerificationExecutor {};
 
 std::string AlternatingVerificationExecutor::getIdentifier() {
-  return {"This is a alternating verification executor"};
-  // refactor. how?
+  return "alt_ver_exe" + mVerTask->getIdentifier();
 }
 
 json AlternatingVerificationExecutor::executeTask() {
diff --git a/src/CircuitSimulatorExecutor.cpp b/src/CircuitSimulatorExecutor.cpp
index 53988ff..224e467 100644
--- a/src/CircuitSimulatorExecutor.cpp
+++ b/src/CircuitSimulatorExecutor.cpp
@@ -3,8 +3,7 @@
 class CircuitSimulatorExecutor::CircuitSimulatorExecutor {};
 
 std::string CircuitSimulatorExecutor::getIdentifier() {
-  return {"This is a circuit simulator executor"};
-  // refactor. how?
+  return "circ_sim_exe" + mSimTask->getIdentifier();
 }
 
 template <typename KTy, typename VTy>
diff --git a/src/SimulationTask.cpp b/src/SimulationTask.cpp
index 27db4c2..b25b4ed 100644
--- a/src/SimulationTask.cpp
+++ b/src/SimulationTask.cpp
@@ -1,6 +1,3 @@
 #include "SimulationTask.hpp"
 
-std::string SimulationTask::getIdentifier() {
-  return "This is a simulation task";
-  // refactor. how?
-}
+std::string SimulationTask::getIdentifier() { return "sim_" + qc->getName(); }
diff --git a/src/VerificationTask.cpp b/src/VerificationTask.cpp
index bf4c744..f1fe270 100644
--- a/src/VerificationTask.cpp
+++ b/src/VerificationTask.cpp
@@ -1,6 +1,5 @@
 #include "VerificationTask.hpp"
 
 std::string VerificationTask::getIdentifier() {
-  return "This is a verification task";
-  // refactor. how?
+  return "ver_" + qc1->getName() + "_" + qc2->getName();
 }

From 9ae771598b833df07fd78e9bb8b8119dcba64c8f Mon Sep 17 00:00:00 2001
From: Tianyi Wang <tianyi1.wang@tum.de>
Date: Fri, 2 Jun 2023 17:05:37 +0200
Subject: [PATCH 21/43] Refactor Task and Executor inheritance

---
 include/AlternatingVerificationExecutor.hpp |  8 --------
 include/CircuitSimulatorExecutor.hpp        |  8 --------
 include/SimulationExecutor.hpp              |  4 ++--
 include/VerificationExecutor.hpp            |  6 +++---
 src/AlternatingVerificationExecutor.cpp     | 19 ++-----------------
 src/CircuitSimulatorExecutor.cpp            | 19 ++-----------------
 src/SimulationExecutor.cpp                  |  2 +-
 src/VerificationExecutor.cpp                |  5 ++---
 test/test_qcecexec.cpp                      |  2 +-
 test/test_qcecexec_simple.cpp               |  2 +-
 test/test_simexec.cpp                       |  2 +-
 test/test_simexec_simple.cpp                |  2 +-
 12 files changed, 16 insertions(+), 63 deletions(-)

diff --git a/include/AlternatingVerificationExecutor.hpp b/include/AlternatingVerificationExecutor.hpp
index d93f83b..09d464d 100644
--- a/include/AlternatingVerificationExecutor.hpp
+++ b/include/AlternatingVerificationExecutor.hpp
@@ -11,14 +11,6 @@ class AlternatingVerificationExecutor : public VerificationExecutor {
   json        executeTask() override;
   std::string getIdentifier() override;
 
-private:
-  std::unique_ptr<VerificationTask> mVerTask;
-
-public:
-  [[nodiscard]] const std::unique_ptr<VerificationTask>& getMVerTask() const;
-
-  void setMVerTask(std::unique_ptr<VerificationTask>& verTask);
-
 private:
   std::unique_ptr<ec::EquivalenceCheckingManager> mEquivalenceCheckingManager;
 
diff --git a/include/CircuitSimulatorExecutor.hpp b/include/CircuitSimulatorExecutor.hpp
index a9ab970..9ee2cfe 100644
--- a/include/CircuitSimulatorExecutor.hpp
+++ b/include/CircuitSimulatorExecutor.hpp
@@ -11,14 +11,6 @@ class CircuitSimulatorExecutor : public SimulationExecutor {
   json        executeTask() override;
   std::string getIdentifier() override;
 
-private:
-  std::unique_ptr<SimulationTask> mSimTask;
-
-public:
-  [[nodiscard]] const std::unique_ptr<SimulationTask>& getMSimTask() const;
-
-  void setMSimTask(std::unique_ptr<SimulationTask>& simTask);
-
 private:
   std::unique_ptr<CircuitSimulator<>> mCircuitSimulator;
 
diff --git a/include/SimulationExecutor.hpp b/include/SimulationExecutor.hpp
index 38cffdc..188ca7a 100644
--- a/include/SimulationExecutor.hpp
+++ b/include/SimulationExecutor.hpp
@@ -7,10 +7,10 @@ class SimulationExecutor : public Executor {
 public:
   SimulationExecutor() = default;
 
-  const std::unique_ptr<SimulationTask>& getMTask();
+  const std::unique_ptr<SimulationTask>& getTask();
 
   void setTask(std::unique_ptr<SimulationTask>& task);
 
-private:
+protected:
   std::unique_ptr<SimulationTask> mTask;
 };
diff --git a/include/VerificationExecutor.hpp b/include/VerificationExecutor.hpp
index 1f2f612..28261f9 100644
--- a/include/VerificationExecutor.hpp
+++ b/include/VerificationExecutor.hpp
@@ -7,11 +7,11 @@ class VerificationExecutor : public Executor {
 public:
   VerificationExecutor() = default;
 
-private:
+protected:
   std::unique_ptr<VerificationTask> mTask;
 
 public:
-  const std::unique_ptr<VerificationTask>& getMTask() const;
+  [[nodiscard]] const std::unique_ptr<VerificationTask>& getTask() const;
 
-  void setMTask(std::unique_ptr<VerificationTask>& task);
+  void setTask(std::unique_ptr<VerificationTask>& task);
 };
diff --git a/src/AlternatingVerificationExecutor.cpp b/src/AlternatingVerificationExecutor.cpp
index a24a000..c90cd5f 100644
--- a/src/AlternatingVerificationExecutor.cpp
+++ b/src/AlternatingVerificationExecutor.cpp
@@ -3,7 +3,7 @@
 class AlternatingVerificationExecutor::AlternatingVerificationExecutor {};
 
 std::string AlternatingVerificationExecutor::getIdentifier() {
-  return "alt_ver_exe" + mVerTask->getIdentifier();
+  return "alt_ver_exe" + mTask->getIdentifier();
 }
 
 json AlternatingVerificationExecutor::executeTask() {
@@ -18,27 +18,12 @@ json AlternatingVerificationExecutor::executeTask() {
       std::chrono::duration_cast<std::chrono::microseconds>(stop - start);
   result["runtime"] = runtime.count();
   std::string const identifier =
-      this->getMVerTask()->getIdentifier() + "_" + this->getIdentifier();
+      this->getTask()->getIdentifier() + "_" + this->getIdentifier();
   result["identifier"] = identifier;
 
   return result;
 }
 
-const std::unique_ptr<VerificationTask>&
-AlternatingVerificationExecutor::getMVerTask() const {
-  return mVerTask;
-}
-
-void AlternatingVerificationExecutor::setMVerTask(
-    std::unique_ptr<VerificationTask>& verTask) {
-  mVerTask = std::move(verTask);
-}
-
-const std::unique_ptr<ec::EquivalenceCheckingManager>&
-AlternatingVerificationExecutor::getEquivalenceCheckingManager() {
-  return mEquivalenceCheckingManager;
-}
-
 void AlternatingVerificationExecutor::setEquivalenceCheckingManager(
     std::unique_ptr<ec::EquivalenceCheckingManager>&
         equivalenceCheckingManager) {
diff --git a/src/CircuitSimulatorExecutor.cpp b/src/CircuitSimulatorExecutor.cpp
index 224e467..8d2ffb5 100644
--- a/src/CircuitSimulatorExecutor.cpp
+++ b/src/CircuitSimulatorExecutor.cpp
@@ -3,7 +3,7 @@
 class CircuitSimulatorExecutor::CircuitSimulatorExecutor {};
 
 std::string CircuitSimulatorExecutor::getIdentifier() {
-  return "circ_sim_exe" + mSimTask->getIdentifier();
+  return "circ_sim_exe" + mTask->getIdentifier();
 }
 
 template <typename KTy, typename VTy>
@@ -26,27 +26,12 @@ json CircuitSimulatorExecutor::executeTask() {
       std::chrono::duration_cast<std::chrono::microseconds>(stop - start);
   result["runtime"] = runtime.count();
   std::string const identifier =
-      this->getMSimTask()->getIdentifier() + "_" + this->getIdentifier();
+      this->getTask()->getIdentifier() + "_" + this->getIdentifier();
   result["identifier"] = identifier;
 
   return result;
 }
 
-const std::unique_ptr<SimulationTask>&
-CircuitSimulatorExecutor::getMSimTask() const {
-  return mSimTask;
-}
-
-void CircuitSimulatorExecutor::setMSimTask(
-    std::unique_ptr<SimulationTask>& simTask) {
-  mSimTask = std::move(simTask);
-}
-
-const std::unique_ptr<CircuitSimulator<>>&
-CircuitSimulatorExecutor::getCircuitSimulator() {
-  return mCircuitSimulator;
-}
-
 void CircuitSimulatorExecutor::setCircuitSimulator(
     std::unique_ptr<CircuitSimulator<>>& circuitSimulator) {
   mCircuitSimulator = std::move(circuitSimulator);
diff --git a/src/SimulationExecutor.cpp b/src/SimulationExecutor.cpp
index 6371eb4..b497dbf 100644
--- a/src/SimulationExecutor.cpp
+++ b/src/SimulationExecutor.cpp
@@ -1,6 +1,6 @@
 #include "SimulationExecutor.hpp"
 
-const std::unique_ptr<SimulationTask>& SimulationExecutor::getMTask() {
+const std::unique_ptr<SimulationTask>& SimulationExecutor::getTask() {
   return mTask;
 }
 
diff --git a/src/VerificationExecutor.cpp b/src/VerificationExecutor.cpp
index 596852b..bc4d99c 100644
--- a/src/VerificationExecutor.cpp
+++ b/src/VerificationExecutor.cpp
@@ -1,10 +1,9 @@
 #include "VerificationExecutor.hpp"
 
-const std::unique_ptr<VerificationTask>&
-VerificationExecutor::getMTask() const {
+const std::unique_ptr<VerificationTask>& VerificationExecutor::getTask() const {
   return mTask;
 }
 
-void VerificationExecutor::setMTask(std::unique_ptr<VerificationTask>& task) {
+void VerificationExecutor::setTask(std::unique_ptr<VerificationTask>& task) {
   mTask = std::move(task);
 }
diff --git a/test/test_qcecexec.cpp b/test/test_qcecexec.cpp
index 2691c42..1e19272 100644
--- a/test/test_qcecexec.cpp
+++ b/test/test_qcecexec.cpp
@@ -58,7 +58,7 @@ class QCECExecTest : public ::testing::TestWithParam<TestConfigurationQCEC> {
         std::make_unique<AlternatingVerificationExecutor>();
     alternatingVerificationExecutor->setEquivalenceCheckingManager(
         equivalenceCheckingManager);
-    alternatingVerificationExecutor->setMVerTask(verificationTask);
+    alternatingVerificationExecutor->setTask(verificationTask);
   }
 
   void TearDown() override { std::cout << "Tearing down...\n"; }
diff --git a/test/test_qcecexec_simple.cpp b/test/test_qcecexec_simple.cpp
index d365d20..c49d25d 100644
--- a/test/test_qcecexec_simple.cpp
+++ b/test/test_qcecexec_simple.cpp
@@ -16,7 +16,7 @@ TEST(QCECExecSimpleTest, EmptyCircuits) {
       std::make_unique<ec::EquivalenceCheckingManager>(clonedQC2, clonedQC3);
   auto alternatingVerificationExecutor =
       std::make_unique<AlternatingVerificationExecutor>();
-  alternatingVerificationExecutor->setMVerTask(verificationTask);
+  alternatingVerificationExecutor->setTask(verificationTask);
   alternatingVerificationExecutor->setEquivalenceCheckingManager(
       equivalenceCheckingManager);
 
diff --git a/test/test_simexec.cpp b/test/test_simexec.cpp
index 7f33ac8..9cc6c73 100644
--- a/test/test_simexec.cpp
+++ b/test/test_simexec.cpp
@@ -47,7 +47,7 @@ class DDSIMExecTest : public ::testing::TestWithParam<TestConfigurationDDSIM> {
         std::make_unique<CircuitSimulator<>>(std::move(qcForSim));
     circuitSimulatorExecutor = std::make_unique<CircuitSimulatorExecutor>();
     circuitSimulatorExecutor->setCircuitSimulator(circuitSimulator);
-    circuitSimulatorExecutor->setMSimTask(simulationTask);
+    circuitSimulatorExecutor->setTask(simulationTask);
   }
 
   void TearDown() override { std::cout << "Tearing down...\n"; }
diff --git a/test/test_simexec_simple.cpp b/test/test_simexec_simple.cpp
index 5b5dfad..5fd4a0a 100644
--- a/test/test_simexec_simple.cpp
+++ b/test/test_simexec_simple.cpp
@@ -12,7 +12,7 @@ TEST(DDSIMExecSimpleTest, EmptyCircuit) {
   auto circuitSimulator = std::make_unique<CircuitSimulator<>>(std::move(qc));
   auto circuitSimulatorExecutor = std::make_unique<CircuitSimulatorExecutor>();
   circuitSimulatorExecutor->setCircuitSimulator(circuitSimulator);
-  circuitSimulatorExecutor->setMSimTask(simulationTask);
+  circuitSimulatorExecutor->setTask(simulationTask);
   json const result = circuitSimulatorExecutor->executeTask();
 
   EXPECT_EQ(1024, result["00"]);

From 505053c1f880092a9114987c59b5f8a38be721e6 Mon Sep 17 00:00:00 2001
From: Tianyi Wang <tianyi1.wang@tum.de>
Date: Fri, 2 Jun 2023 17:05:52 +0200
Subject: [PATCH 22/43] Clean-up

---
 include/AlternatingVerificationExecutor.hpp | 3 ---
 include/CircuitSimulatorExecutor.hpp        | 4 +---
 include/SimulationTask.hpp                  | 2 --
 3 files changed, 1 insertion(+), 8 deletions(-)

diff --git a/include/AlternatingVerificationExecutor.hpp b/include/AlternatingVerificationExecutor.hpp
index 09d464d..48888d5 100644
--- a/include/AlternatingVerificationExecutor.hpp
+++ b/include/AlternatingVerificationExecutor.hpp
@@ -15,9 +15,6 @@ class AlternatingVerificationExecutor : public VerificationExecutor {
   std::unique_ptr<ec::EquivalenceCheckingManager> mEquivalenceCheckingManager;
 
 public:
-  const std::unique_ptr<ec::EquivalenceCheckingManager>&
-  getEquivalenceCheckingManager();
-
   void
   setEquivalenceCheckingManager(std::unique_ptr<ec::EquivalenceCheckingManager>&
                                     equivalenceCheckingManager);
diff --git a/include/CircuitSimulatorExecutor.hpp b/include/CircuitSimulatorExecutor.hpp
index 9ee2cfe..7bd42e7 100644
--- a/include/CircuitSimulatorExecutor.hpp
+++ b/include/CircuitSimulatorExecutor.hpp
@@ -6,7 +6,7 @@
 class CircuitSimulatorExecutor : public SimulationExecutor {
 public:
   CircuitSimulatorExecutor() = default;
-  //  simulator and task must be set before use
+  // simulator and task must be set before use
 
   json        executeTask() override;
   std::string getIdentifier() override;
@@ -15,8 +15,6 @@ class CircuitSimulatorExecutor : public SimulationExecutor {
   std::unique_ptr<CircuitSimulator<>> mCircuitSimulator;
 
 public:
-  const std::unique_ptr<CircuitSimulator<>>& getCircuitSimulator();
-
   void
   setCircuitSimulator(std::unique_ptr<CircuitSimulator<>>& circuitSimulator);
 };
diff --git a/include/SimulationTask.hpp b/include/SimulationTask.hpp
index efde458..d71fe22 100644
--- a/include/SimulationTask.hpp
+++ b/include/SimulationTask.hpp
@@ -14,7 +14,5 @@ class SimulationTask : public Task {
   std::unique_ptr<qc::QuantumComputation> qc;
 
 public:
-  std::unique_ptr<qc::QuantumComputation>& getQc() { return qc; }
-
   std::string getIdentifier() override;
 };

From 8bfad929d5759ca7b6114ba8a74ebf89012ecab6 Mon Sep 17 00:00:00 2001
From: Tianyi Wang <tianyi1.wang@tum.de>
Date: Fri, 2 Jun 2023 17:21:15 +0200
Subject: [PATCH 23/43] Make sure the alternating checker was run in
 alternating executor

---
 test/test_qcecexec.cpp        | 9 ++++++++-
 test/test_qcecexec_simple.cpp | 8 +++++++-
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/test/test_qcecexec.cpp b/test/test_qcecexec.cpp
index 1e19272..b13d353 100644
--- a/test/test_qcecexec.cpp
+++ b/test/test_qcecexec.cpp
@@ -51,9 +51,16 @@ class QCECExecTest : public ::testing::TestWithParam<TestConfigurationQCEC> {
     qc2ForTask       = std::make_unique<qc::QuantumComputation>(qc2.clone());
     verificationTask = std::make_unique<VerificationTask>(
         std::move(qc1ForTask), std::move(qc2ForTask));
+
+    auto config                             = ec::Configuration{};
+    config.execution.runAlternatingChecker  = true;
+    config.execution.runSimulationChecker   = false;
+    config.execution.runConstructionChecker = false;
+    config.execution.runZXChecker           = false;
+    // This should probably happen inside src?
     equivalenceCheckingManager =
         std::make_unique<ec::EquivalenceCheckingManager>(qc1.clone(),
-                                                         qc2.clone());
+                                                         qc2.clone(), config);
     alternatingVerificationExecutor =
         std::make_unique<AlternatingVerificationExecutor>();
     alternatingVerificationExecutor->setEquivalenceCheckingManager(
diff --git a/test/test_qcecexec_simple.cpp b/test/test_qcecexec_simple.cpp
index c49d25d..e7c5043 100644
--- a/test/test_qcecexec_simple.cpp
+++ b/test/test_qcecexec_simple.cpp
@@ -12,8 +12,14 @@ TEST(QCECExecSimpleTest, EmptyCircuits) {
   auto clonedQC3 = qc->clone();
   auto verificationTask =
       std::make_unique<VerificationTask>(std::move(qc), std::move(clonedQC));
+  auto config                             = ec::Configuration{};
+  config.execution.runAlternatingChecker  = true;
+  config.execution.runSimulationChecker   = false;
+  config.execution.runConstructionChecker = false;
+  config.execution.runZXChecker           = false;
   auto equivalenceCheckingManager =
-      std::make_unique<ec::EquivalenceCheckingManager>(clonedQC2, clonedQC3);
+      std::make_unique<ec::EquivalenceCheckingManager>(clonedQC2, clonedQC3,
+                                                       config);
   auto alternatingVerificationExecutor =
       std::make_unique<AlternatingVerificationExecutor>();
   alternatingVerificationExecutor->setTask(verificationTask);

From 3927554221a499e0f7870cb97d15269b571a21f9 Mon Sep 17 00:00:00 2001
From: Tianyi Wang <tianyi1.wang@tum.de>
Date: Fri, 2 Jun 2023 17:21:15 +0200
Subject: [PATCH 24/43] Make sure the alternating checker was run in
 alternating executor

---
 test/test_qcecexec.cpp        | 7 +++++++
 test/test_qcecexec_simple.cpp | 7 +++++++
 2 files changed, 14 insertions(+)

diff --git a/test/test_qcecexec.cpp b/test/test_qcecexec.cpp
index 1e19272..e8c82b6 100644
--- a/test/test_qcecexec.cpp
+++ b/test/test_qcecexec.cpp
@@ -51,9 +51,16 @@ class QCECExecTest : public ::testing::TestWithParam<TestConfigurationQCEC> {
     qc2ForTask       = std::make_unique<qc::QuantumComputation>(qc2.clone());
     verificationTask = std::make_unique<VerificationTask>(
         std::move(qc1ForTask), std::move(qc2ForTask));
+
     equivalenceCheckingManager =
         std::make_unique<ec::EquivalenceCheckingManager>(qc1.clone(),
                                                          qc2.clone());
+    equivalenceCheckingManager->setAlternatingChecker(true);
+    equivalenceCheckingManager->setSimulationChecker(false);
+    equivalenceCheckingManager->setConstructionChecker(false);
+    equivalenceCheckingManager->setZXChecker(false);
+    // This should probably happen inside src?
+
     alternatingVerificationExecutor =
         std::make_unique<AlternatingVerificationExecutor>();
     alternatingVerificationExecutor->setEquivalenceCheckingManager(
diff --git a/test/test_qcecexec_simple.cpp b/test/test_qcecexec_simple.cpp
index c49d25d..adc4ed9 100644
--- a/test/test_qcecexec_simple.cpp
+++ b/test/test_qcecexec_simple.cpp
@@ -12,8 +12,15 @@ TEST(QCECExecSimpleTest, EmptyCircuits) {
   auto clonedQC3 = qc->clone();
   auto verificationTask =
       std::make_unique<VerificationTask>(std::move(qc), std::move(clonedQC));
+
   auto equivalenceCheckingManager =
       std::make_unique<ec::EquivalenceCheckingManager>(clonedQC2, clonedQC3);
+  equivalenceCheckingManager->setAlternatingChecker(true);
+  equivalenceCheckingManager->setSimulationChecker(false);
+  equivalenceCheckingManager->setConstructionChecker(false);
+  equivalenceCheckingManager->setZXChecker(false);
+  // This should probably happen inside src?
+
   auto alternatingVerificationExecutor =
       std::make_unique<AlternatingVerificationExecutor>();
   alternatingVerificationExecutor->setTask(verificationTask);

From a7fea9aadc904c9c802b5067f4535554d7dcc6c6 Mon Sep 17 00:00:00 2001
From: Tianyi Wang <tianyi1.wang@tum.de>
Date: Fri, 2 Jun 2023 17:49:40 +0200
Subject: [PATCH 25/43] Fix CI issues (WIP)

---
 src/AlternatingVerificationExecutor.cpp | 2 --
 src/CircuitSimulatorExecutor.cpp        | 2 --
 2 files changed, 4 deletions(-)

diff --git a/src/AlternatingVerificationExecutor.cpp b/src/AlternatingVerificationExecutor.cpp
index c90cd5f..96b37fe 100644
--- a/src/AlternatingVerificationExecutor.cpp
+++ b/src/AlternatingVerificationExecutor.cpp
@@ -1,7 +1,5 @@
 #include "AlternatingVerificationExecutor.hpp"
 
-class AlternatingVerificationExecutor::AlternatingVerificationExecutor {};
-
 std::string AlternatingVerificationExecutor::getIdentifier() {
   return "alt_ver_exe" + mTask->getIdentifier();
 }
diff --git a/src/CircuitSimulatorExecutor.cpp b/src/CircuitSimulatorExecutor.cpp
index 8d2ffb5..9e4dd20 100644
--- a/src/CircuitSimulatorExecutor.cpp
+++ b/src/CircuitSimulatorExecutor.cpp
@@ -1,7 +1,5 @@
 #include "CircuitSimulatorExecutor.hpp"
 
-class CircuitSimulatorExecutor::CircuitSimulatorExecutor {};
-
 std::string CircuitSimulatorExecutor::getIdentifier() {
   return "circ_sim_exe" + mTask->getIdentifier();
 }

From 1bb3de70da834b2be695723036b604dd683b2c7b Mon Sep 17 00:00:00 2001
From: Tianyi Wang <tianyi1.wang@tum.de>
Date: Sat, 3 Jun 2023 00:13:00 +0200
Subject: [PATCH 26/43] Refactor architecture: set all necessary members inside
 of constructor

---
 include/AlternatingVerificationExecutor.hpp | 11 +++-----
 include/CircuitSimulatorExecutor.hpp        | 10 +++----
 include/SimulationTask.hpp                  |  6 ++---
 include/VerificationExecutor.hpp            |  7 +++--
 include/VerificationTask.hpp                |  5 ++++
 src/AlternatingVerificationExecutor.cpp     | 19 ++++++++-----
 src/CircuitSimulatorExecutor.cpp            | 12 +++++----
 src/SimulationTask.cpp                      |  4 +++
 src/VerificationTask.cpp                    | 10 +++++++
 test/test_qcecexec.cpp                      | 30 +++++++--------------
 test/test_qcecexec_simple.cpp               | 24 ++++-------------
 test/test_simexec.cpp                       | 16 ++++-------
 test/test_simexec_simple.cpp                | 12 +++------
 13 files changed, 76 insertions(+), 90 deletions(-)

diff --git a/include/AlternatingVerificationExecutor.hpp b/include/AlternatingVerificationExecutor.hpp
index 48888d5..2e9521f 100644
--- a/include/AlternatingVerificationExecutor.hpp
+++ b/include/AlternatingVerificationExecutor.hpp
@@ -5,17 +5,14 @@
 
 class AlternatingVerificationExecutor : public VerificationExecutor {
 public:
-  AlternatingVerificationExecutor() = default;
-  // checker and task must be set before use
+  AlternatingVerificationExecutor() = delete;
+
+  explicit AlternatingVerificationExecutor(
+      std::unique_ptr<VerificationTask> verificationTask);
 
   json        executeTask() override;
   std::string getIdentifier() override;
 
 private:
   std::unique_ptr<ec::EquivalenceCheckingManager> mEquivalenceCheckingManager;
-
-public:
-  void
-  setEquivalenceCheckingManager(std::unique_ptr<ec::EquivalenceCheckingManager>&
-                                    equivalenceCheckingManager);
 };
diff --git a/include/CircuitSimulatorExecutor.hpp b/include/CircuitSimulatorExecutor.hpp
index 7bd42e7..bc548ee 100644
--- a/include/CircuitSimulatorExecutor.hpp
+++ b/include/CircuitSimulatorExecutor.hpp
@@ -5,16 +5,14 @@
 
 class CircuitSimulatorExecutor : public SimulationExecutor {
 public:
-  CircuitSimulatorExecutor() = default;
-  // simulator and task must be set before use
+  CircuitSimulatorExecutor() = delete;
+
+  explicit CircuitSimulatorExecutor(
+      std::unique_ptr<SimulationTask> simulationTask);
 
   json        executeTask() override;
   std::string getIdentifier() override;
 
 private:
   std::unique_ptr<CircuitSimulator<>> mCircuitSimulator;
-
-public:
-  void
-  setCircuitSimulator(std::unique_ptr<CircuitSimulator<>>& circuitSimulator);
 };
diff --git a/include/SimulationTask.hpp b/include/SimulationTask.hpp
index d71fe22..c67e7bd 100644
--- a/include/SimulationTask.hpp
+++ b/include/SimulationTask.hpp
@@ -10,9 +10,9 @@ class SimulationTask : public Task {
   explicit SimulationTask(std::unique_ptr<qc::QuantumComputation> qc)
       : qc(std::move(qc)) {}
 
+  [[nodiscard]] const std::unique_ptr<qc::QuantumComputation>& getQc() const;
+  std::string getIdentifier() override;
+
 protected:
   std::unique_ptr<qc::QuantumComputation> qc;
-
-public:
-  std::string getIdentifier() override;
 };
diff --git a/include/VerificationExecutor.hpp b/include/VerificationExecutor.hpp
index 28261f9..0143bb0 100644
--- a/include/VerificationExecutor.hpp
+++ b/include/VerificationExecutor.hpp
@@ -7,11 +7,10 @@ class VerificationExecutor : public Executor {
 public:
   VerificationExecutor() = default;
 
-protected:
-  std::unique_ptr<VerificationTask> mTask;
-
-public:
   [[nodiscard]] const std::unique_ptr<VerificationTask>& getTask() const;
 
   void setTask(std::unique_ptr<VerificationTask>& task);
+
+protected:
+  std::unique_ptr<VerificationTask> mTask;
 };
diff --git a/include/VerificationTask.hpp b/include/VerificationTask.hpp
index 4032287..eb71402 100644
--- a/include/VerificationTask.hpp
+++ b/include/VerificationTask.hpp
@@ -14,4 +14,9 @@ class VerificationTask : public Task {
 protected:
   std::unique_ptr<qc::QuantumComputation> qc1;
   std::unique_ptr<qc::QuantumComputation> qc2;
+
+public:
+  [[nodiscard]] const std::unique_ptr<qc::QuantumComputation>& getQc1() const;
+
+  [[nodiscard]] const std::unique_ptr<qc::QuantumComputation>& getQc2() const;
 };
diff --git a/src/AlternatingVerificationExecutor.cpp b/src/AlternatingVerificationExecutor.cpp
index 96b37fe..d2799cc 100644
--- a/src/AlternatingVerificationExecutor.cpp
+++ b/src/AlternatingVerificationExecutor.cpp
@@ -1,5 +1,18 @@
 #include "AlternatingVerificationExecutor.hpp"
 
+AlternatingVerificationExecutor::AlternatingVerificationExecutor(
+    std::unique_ptr<VerificationTask> verificationTask) {
+  mTask    = std::move(verificationTask);
+  auto qc1 = mTask->getQc1()->clone();
+  auto qc2 = mTask->getQc2()->clone();
+  mEquivalenceCheckingManager =
+      std::make_unique<ec::EquivalenceCheckingManager>(qc1, qc2);
+  mEquivalenceCheckingManager->setAlternatingChecker(true);
+  mEquivalenceCheckingManager->setSimulationChecker(false);
+  mEquivalenceCheckingManager->setConstructionChecker(false);
+  mEquivalenceCheckingManager->setZXChecker(false);
+}
+
 std::string AlternatingVerificationExecutor::getIdentifier() {
   return "alt_ver_exe" + mTask->getIdentifier();
 }
@@ -21,9 +34,3 @@ json AlternatingVerificationExecutor::executeTask() {
 
   return result;
 }
-
-void AlternatingVerificationExecutor::setEquivalenceCheckingManager(
-    std::unique_ptr<ec::EquivalenceCheckingManager>&
-        equivalenceCheckingManager) {
-  mEquivalenceCheckingManager = std::move(equivalenceCheckingManager);
-}
diff --git a/src/CircuitSimulatorExecutor.cpp b/src/CircuitSimulatorExecutor.cpp
index 9e4dd20..d832f57 100644
--- a/src/CircuitSimulatorExecutor.cpp
+++ b/src/CircuitSimulatorExecutor.cpp
@@ -1,5 +1,12 @@
 #include "CircuitSimulatorExecutor.hpp"
 
+CircuitSimulatorExecutor::CircuitSimulatorExecutor(
+    std::unique_ptr<SimulationTask> simulationTask) {
+  mTask   = std::move(simulationTask);
+  auto qc = std::make_unique<qc::QuantumComputation>(mTask->getQc()->clone());
+  mCircuitSimulator = std::make_unique<CircuitSimulator<>>(std::move(qc));
+}
+
 std::string CircuitSimulatorExecutor::getIdentifier() {
   return "circ_sim_exe" + mTask->getIdentifier();
 }
@@ -29,8 +36,3 @@ json CircuitSimulatorExecutor::executeTask() {
 
   return result;
 }
-
-void CircuitSimulatorExecutor::setCircuitSimulator(
-    std::unique_ptr<CircuitSimulator<>>& circuitSimulator) {
-  mCircuitSimulator = std::move(circuitSimulator);
-}
diff --git a/src/SimulationTask.cpp b/src/SimulationTask.cpp
index b25b4ed..4e2a7cf 100644
--- a/src/SimulationTask.cpp
+++ b/src/SimulationTask.cpp
@@ -1,3 +1,7 @@
 #include "SimulationTask.hpp"
 
 std::string SimulationTask::getIdentifier() { return "sim_" + qc->getName(); }
+
+const std::unique_ptr<qc::QuantumComputation>& SimulationTask::getQc() const {
+  return qc;
+}
diff --git a/src/VerificationTask.cpp b/src/VerificationTask.cpp
index f1fe270..851a286 100644
--- a/src/VerificationTask.cpp
+++ b/src/VerificationTask.cpp
@@ -3,3 +3,13 @@
 std::string VerificationTask::getIdentifier() {
   return "ver_" + qc1->getName() + "_" + qc2->getName();
 }
+
+const std::unique_ptr<qc::QuantumComputation>&
+VerificationTask::getQc1() const {
+  return qc1;
+}
+
+const std::unique_ptr<qc::QuantumComputation>&
+VerificationTask::getQc2() const {
+  return qc2;
+}
diff --git a/test/test_qcecexec.cpp b/test/test_qcecexec.cpp
index e8c82b6..3c6ef8d 100644
--- a/test/test_qcecexec.cpp
+++ b/test/test_qcecexec.cpp
@@ -47,33 +47,21 @@ class QCECExecTest : public ::testing::TestWithParam<TestConfigurationQCEC> {
     qc2.import(ss2, qc::Format::OpenQASM);
     std::cout << "Circuit 2:\n" << qc2 << std::endl;
 
-    qc1ForTask       = std::make_unique<qc::QuantumComputation>(qc1.clone());
-    qc2ForTask       = std::make_unique<qc::QuantumComputation>(qc2.clone());
-    verificationTask = std::make_unique<VerificationTask>(
-        std::move(qc1ForTask), std::move(qc2ForTask));
-
-    equivalenceCheckingManager =
-        std::make_unique<ec::EquivalenceCheckingManager>(qc1.clone(),
-                                                         qc2.clone());
-    equivalenceCheckingManager->setAlternatingChecker(true);
-    equivalenceCheckingManager->setSimulationChecker(false);
-    equivalenceCheckingManager->setConstructionChecker(false);
-    equivalenceCheckingManager->setZXChecker(false);
-    // This should probably happen inside src?
+    qc1Ver           = std::make_unique<qc::QuantumComputation>(qc1.clone());
+    qc2Ver           = std::make_unique<qc::QuantumComputation>(qc2.clone());
+    verificationTask = std::make_unique<VerificationTask>(std::move(qc1Ver),
+                                                          std::move(qc2Ver));
 
     alternatingVerificationExecutor =
-        std::make_unique<AlternatingVerificationExecutor>();
-    alternatingVerificationExecutor->setEquivalenceCheckingManager(
-        equivalenceCheckingManager);
-    alternatingVerificationExecutor->setTask(verificationTask);
+        std::make_unique<AlternatingVerificationExecutor>(
+            std::move(verificationTask));
   }
 
   void TearDown() override { std::cout << "Tearing down...\n"; }
 
-  std::unique_ptr<qc::QuantumComputation>         qc1ForTask;
-  std::unique_ptr<qc::QuantumComputation>         qc2ForTask;
-  std::unique_ptr<VerificationTask>               verificationTask;
-  std::unique_ptr<ec::EquivalenceCheckingManager> equivalenceCheckingManager;
+  std::unique_ptr<qc::QuantumComputation> qc1Ver;
+  std::unique_ptr<qc::QuantumComputation> qc2Ver;
+  std::unique_ptr<VerificationTask>       verificationTask;
   std::unique_ptr<AlternatingVerificationExecutor>
                         alternatingVerificationExecutor;
   TestConfigurationQCEC test;
diff --git a/test/test_qcecexec_simple.cpp b/test/test_qcecexec_simple.cpp
index adc4ed9..4abd8f2 100644
--- a/test/test_qcecexec_simple.cpp
+++ b/test/test_qcecexec_simple.cpp
@@ -1,31 +1,17 @@
 #include "AlternatingVerificationExecutor.hpp"
-#include "EquivalenceCheckingManager.hpp"
 #include "VerificationTask.hpp"
 
 #include <gtest/gtest.h>
 #include <memory>
 
 TEST(QCECExecSimpleTest, EmptyCircuits) {
-  auto qc        = std::make_unique<qc::QuantumComputation>(2U);
-  auto clonedQC  = std::make_unique<qc::QuantumComputation>(qc->clone());
-  auto clonedQC2 = qc->clone();
-  auto clonedQC3 = qc->clone();
+  auto qc1 = std::make_unique<qc::QuantumComputation>(2U);
+  auto qc2 = std::make_unique<qc::QuantumComputation>(2U);
   auto verificationTask =
-      std::make_unique<VerificationTask>(std::move(qc), std::move(clonedQC));
-
-  auto equivalenceCheckingManager =
-      std::make_unique<ec::EquivalenceCheckingManager>(clonedQC2, clonedQC3);
-  equivalenceCheckingManager->setAlternatingChecker(true);
-  equivalenceCheckingManager->setSimulationChecker(false);
-  equivalenceCheckingManager->setConstructionChecker(false);
-  equivalenceCheckingManager->setZXChecker(false);
-  // This should probably happen inside src?
-
+      std::make_unique<VerificationTask>(std::move(qc1), std::move(qc2));
   auto alternatingVerificationExecutor =
-      std::make_unique<AlternatingVerificationExecutor>();
-  alternatingVerificationExecutor->setTask(verificationTask);
-  alternatingVerificationExecutor->setEquivalenceCheckingManager(
-      equivalenceCheckingManager);
+      std::make_unique<AlternatingVerificationExecutor>(
+          std::move(verificationTask));
 
   json const result = alternatingVerificationExecutor->executeTask();
 
diff --git a/test/test_simexec.cpp b/test/test_simexec.cpp
index 9cc6c73..b8b9dbb 100644
--- a/test/test_simexec.cpp
+++ b/test/test_simexec.cpp
@@ -40,22 +40,16 @@ class DDSIMExecTest : public ::testing::TestWithParam<TestConfigurationDDSIM> {
     qc.import(ss, qc::Format::OpenQASM);
     std::cout << "Circuit:\n" << qc;
 
-    qcForTask      = std::make_unique<qc::QuantumComputation>(qc.clone());
-    qcForSim       = std::make_unique<qc::QuantumComputation>(qc.clone());
-    simulationTask = std::make_unique<SimulationTask>(std::move(qcForTask));
-    circuitSimulator =
-        std::make_unique<CircuitSimulator<>>(std::move(qcForSim));
-    circuitSimulatorExecutor = std::make_unique<CircuitSimulatorExecutor>();
-    circuitSimulatorExecutor->setCircuitSimulator(circuitSimulator);
-    circuitSimulatorExecutor->setTask(simulationTask);
+    qcSim          = std::make_unique<qc::QuantumComputation>(qc.clone());
+    simulationTask = std::make_unique<SimulationTask>(std::move(qcSim));
+    circuitSimulatorExecutor =
+        std::make_unique<CircuitSimulatorExecutor>(std::move(simulationTask));
   }
 
   void TearDown() override { std::cout << "Tearing down...\n"; }
 
-  std::unique_ptr<qc::QuantumComputation>   qcForTask;
-  std::unique_ptr<qc::QuantumComputation>   qcForSim;
+  std::unique_ptr<qc::QuantumComputation>   qcSim;
   std::unique_ptr<SimulationTask>           simulationTask;
-  std::unique_ptr<CircuitSimulator<>>       circuitSimulator;
   std::unique_ptr<CircuitSimulatorExecutor> circuitSimulatorExecutor;
   TestConfigurationDDSIM                    test;
 };
diff --git a/test/test_simexec_simple.cpp b/test/test_simexec_simple.cpp
index 5fd4a0a..2b485fe 100644
--- a/test/test_simexec_simple.cpp
+++ b/test/test_simexec_simple.cpp
@@ -1,4 +1,3 @@
-#include "CircuitSimulator.hpp"
 #include "CircuitSimulatorExecutor.hpp"
 #include "SimulationTask.hpp"
 
@@ -6,13 +5,10 @@
 #include <memory>
 
 TEST(DDSIMExecSimpleTest, EmptyCircuit) {
-  auto qc               = std::make_unique<qc::QuantumComputation>(2U);
-  auto clonedQC         = std::make_unique<qc::QuantumComputation>(qc->clone());
-  auto simulationTask   = std::make_unique<SimulationTask>(std::move(clonedQC));
-  auto circuitSimulator = std::make_unique<CircuitSimulator<>>(std::move(qc));
-  auto circuitSimulatorExecutor = std::make_unique<CircuitSimulatorExecutor>();
-  circuitSimulatorExecutor->setCircuitSimulator(circuitSimulator);
-  circuitSimulatorExecutor->setTask(simulationTask);
+  auto qc             = std::make_unique<qc::QuantumComputation>(2U);
+  auto simulationTask = std::make_unique<SimulationTask>(std::move(qc));
+  auto circuitSimulatorExecutor =
+      std::make_unique<CircuitSimulatorExecutor>(std::move(simulationTask));
   json const result = circuitSimulatorExecutor->executeTask();
 
   EXPECT_EQ(1024, result["00"]);

From 11c5ecf75bcf26a67eeec7210992ce1c4dc0fc42 Mon Sep 17 00:00:00 2001
From: Tianyi Wang <tianyi1.wang@tum.de>
Date: Sat, 3 Jun 2023 00:37:40 +0200
Subject: [PATCH 27/43] Refactor simulator test to avoid empty circuits

---
 test/circuits.json           |  6 +++---
 test/test_simexec.cpp        |  8 ++++----
 test/test_simexec_simple.cpp | 12 ++++++++----
 3 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/test/circuits.json b/test/circuits.json
index dac448d..010bcf2 100644
--- a/test/circuits.json
+++ b/test/circuits.json
@@ -1,7 +1,7 @@
 [
   {
-    "description": "empty_circuit",
-    "initial_circuit": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];\n",
-    "expected_00": 1024
+    "description": "two_qubit_circuit_with_two_x_gates",
+    "initial_circuit": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];x q[0];x q[1];\n",
+    "expected_11": 1024
   }
 ]
diff --git a/test/test_simexec.cpp b/test/test_simexec.cpp
index b8b9dbb..9082aea 100644
--- a/test/test_simexec.cpp
+++ b/test/test_simexec.cpp
@@ -10,14 +10,14 @@ struct TestConfigurationDDSIM {
   std::string initialCircuit;
 
   // expected output
-  std::size_t expected00{};
+  std::size_t expected11{};
 };
 
 // NOLINTNEXTLINE (readability-identifier-naming)
 inline void from_json(const nlohmann::json& j, TestConfigurationDDSIM& test) {
   test.description    = j.at("description").get<std::string>();
   test.initialCircuit = j.at("initial_circuit").get<std::string>();
-  test.expected00     = j.at("expected_00").get<std::size_t>();
+  test.expected11     = j.at("expected_11").get<std::size_t>();
 }
 
 static std::vector<TestConfigurationDDSIM> getTests(const std::string& path) {
@@ -60,9 +60,9 @@ INSTANTIATE_TEST_SUITE_P(
       return inf.param.description;
     });
 
-TEST_P(DDSIMExecTest, EmptyCircuit) {
+TEST_P(DDSIMExecTest, TwoQubitCircuitWithTwoXGates) {
   json const result = circuitSimulatorExecutor->executeTask();
   std::cout << "Results:" << std::endl;
   printAll(result);
-  EXPECT_EQ(result["00"], test.expected00);
+  EXPECT_EQ(result["11"], test.expected11);
 }
diff --git a/test/test_simexec_simple.cpp b/test/test_simexec_simple.cpp
index 2b485fe..9ccd4ed 100644
--- a/test/test_simexec_simple.cpp
+++ b/test/test_simexec_simple.cpp
@@ -4,12 +4,16 @@
 #include <gtest/gtest.h>
 #include <memory>
 
-TEST(DDSIMExecSimpleTest, EmptyCircuit) {
-  auto qc             = std::make_unique<qc::QuantumComputation>(2U);
+TEST(DDSIMExecSimpleTest, SimpleCircuit) {
+  using namespace qc::literals;
+  auto qc = std::make_unique<qc::QuantumComputation>(2U);
+  qc->h(0U);
+  qc->x(1U, 0_pc);
+
   auto simulationTask = std::make_unique<SimulationTask>(std::move(qc));
   auto circuitSimulatorExecutor =
       std::make_unique<CircuitSimulatorExecutor>(std::move(simulationTask));
   json const result = circuitSimulatorExecutor->executeTask();
-
-  EXPECT_EQ(1024, result["00"]);
+  EXPECT_FALSE(result.contains("01"));
+  EXPECT_FALSE(result.contains("10"));
 }

From f80e730a5f0bea4023ac2795d6a5327cf245c9b4 Mon Sep 17 00:00:00 2001
From: Tianyi Wang <tianyi1.wang@tum.de>
Date: Sat, 3 Jun 2023 00:50:59 +0200
Subject: [PATCH 28/43] Refactor verification tests to avoid empty circuits

---
 test/equi_circuits.json       | 6 +++---
 test/test_qcecexec_simple.cpp | 8 +++++++-
 2 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/test/equi_circuits.json b/test/equi_circuits.json
index 470aaca..6d01275 100644
--- a/test/equi_circuits.json
+++ b/test/equi_circuits.json
@@ -1,8 +1,8 @@
 [
   {
-    "description": "empty_circuits",
-    "initial_circuit1": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];\n",
-    "initial_circuit2": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];\n",
+    "description": "simple_circuits",
+    "initial_circuit1": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];x q[0];x q[1];\n",
+    "initial_circuit2": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];x q[0];x q[1];x q[0];x q[0];\n",
     "expected_equivalence": "equivalent"
   }
 ]
diff --git a/test/test_qcecexec_simple.cpp b/test/test_qcecexec_simple.cpp
index 4abd8f2..c11107f 100644
--- a/test/test_qcecexec_simple.cpp
+++ b/test/test_qcecexec_simple.cpp
@@ -4,9 +4,15 @@
 #include <gtest/gtest.h>
 #include <memory>
 
-TEST(QCECExecSimpleTest, EmptyCircuits) {
+TEST(QCECExecSimpleTest, SimpleCircuit) {
   auto qc1 = std::make_unique<qc::QuantumComputation>(2U);
+  qc1->x(0U);
+  qc1->x(1U);
   auto qc2 = std::make_unique<qc::QuantumComputation>(2U);
+  qc2->x(0U);
+  qc2->x(0U);
+  qc2->x(0U);
+  qc2->x(1U);
   auto verificationTask =
       std::make_unique<VerificationTask>(std::move(qc1), std::move(qc2));
   auto alternatingVerificationExecutor =

From f3fea114eca9ec53eb88c6c18495b4a73363956d Mon Sep 17 00:00:00 2001
From: Tianyi Wang <tianyi1.wang@tum.de>
Date: Sat, 3 Jun 2023 01:24:26 +0200
Subject: [PATCH 29/43] Remove obsolete code for coverage

---
 src/SimulationExecutor.cpp   | 4 ----
 src/VerificationExecutor.cpp | 4 ----
 test/test_qcecexec.cpp       | 3 ---
 test/test_simexec.cpp        | 3 ---
 4 files changed, 14 deletions(-)

diff --git a/src/SimulationExecutor.cpp b/src/SimulationExecutor.cpp
index b497dbf..2fd4302 100644
--- a/src/SimulationExecutor.cpp
+++ b/src/SimulationExecutor.cpp
@@ -3,7 +3,3 @@
 const std::unique_ptr<SimulationTask>& SimulationExecutor::getTask() {
   return mTask;
 }
-
-void SimulationExecutor::setTask(std::unique_ptr<SimulationTask>& task) {
-  mTask = std::move(task);
-}
diff --git a/src/VerificationExecutor.cpp b/src/VerificationExecutor.cpp
index bc4d99c..075121c 100644
--- a/src/VerificationExecutor.cpp
+++ b/src/VerificationExecutor.cpp
@@ -3,7 +3,3 @@
 const std::unique_ptr<VerificationTask>& VerificationExecutor::getTask() const {
   return mTask;
 }
-
-void VerificationExecutor::setTask(std::unique_ptr<VerificationTask>& task) {
-  mTask = std::move(task);
-}
diff --git a/test/test_qcecexec.cpp b/test/test_qcecexec.cpp
index 3c6ef8d..de773d7 100644
--- a/test/test_qcecexec.cpp
+++ b/test/test_qcecexec.cpp
@@ -34,9 +34,6 @@ class QCECExecTest : public ::testing::TestWithParam<TestConfigurationQCEC> {
   void SetUp() override {
     test = GetParam();
 
-    if (test.initialCircuit1.empty() or test.initialCircuit2.empty()) {
-      throw std::runtime_error("Circuit missing!");
-    }
     std::stringstream      ss1(test.initialCircuit1);
     qc::QuantumComputation qc1{};
     qc1.import(ss1, qc::Format::OpenQASM);
diff --git a/test/test_simexec.cpp b/test/test_simexec.cpp
index 9082aea..895c7ac 100644
--- a/test/test_simexec.cpp
+++ b/test/test_simexec.cpp
@@ -32,9 +32,6 @@ class DDSIMExecTest : public ::testing::TestWithParam<TestConfigurationDDSIM> {
   void SetUp() override {
     test = GetParam();
 
-    if (test.initialCircuit.empty()) {
-      throw std::runtime_error("No circuit!");
-    }
     std::stringstream      ss(test.initialCircuit);
     qc::QuantumComputation qc{};
     qc.import(ss, qc::Format::OpenQASM);

From e737f71aa75bf70282aad71d422d910feebc86a5 Mon Sep 17 00:00:00 2001
From: tyi1025 <56802240+tyi1025@users.noreply.github.com>
Date: Wed, 7 Jun 2023 01:05:15 +0200
Subject: [PATCH 30/43] Apply suggestions from code review

Co-authored-by: Lukas Burgholzer <lukas.burgholzer@jku.at>
---
 src/CircuitSimulatorExecutor.cpp | 3 +--
 test/test_simexec.cpp            | 7 +++----
 2 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/src/CircuitSimulatorExecutor.cpp b/src/CircuitSimulatorExecutor.cpp
index d832f57..9c76141 100644
--- a/src/CircuitSimulatorExecutor.cpp
+++ b/src/CircuitSimulatorExecutor.cpp
@@ -22,8 +22,7 @@ json CircuitSimulatorExecutor::executeTask() {
   json result;
   auto start = std::chrono::high_resolution_clock::now();
 
-  const auto results = mCircuitSimulator->simulate(1024U);
-  toJson(result, results);
+  result["measurement_results"] = mCircuitSimulator->simulate(1024U);
   // Add memory usage
 
   auto stop = std::chrono::high_resolution_clock::now();
diff --git a/test/test_simexec.cpp b/test/test_simexec.cpp
index 895c7ac..3e891aa 100644
--- a/test/test_simexec.cpp
+++ b/test/test_simexec.cpp
@@ -33,12 +33,11 @@ class DDSIMExecTest : public ::testing::TestWithParam<TestConfigurationDDSIM> {
     test = GetParam();
 
     std::stringstream      ss(test.initialCircuit);
-    qc::QuantumComputation qc{};
-    qc.import(ss, qc::Format::OpenQASM);
+    auto qc = std::make_unique<qc::QuantumComputation>():
+    qc->import(ss, qc::Format::OpenQASM);
     std::cout << "Circuit:\n" << qc;
 
-    qcSim          = std::make_unique<qc::QuantumComputation>(qc.clone());
-    simulationTask = std::make_unique<SimulationTask>(std::move(qcSim));
+    simulationTask = std::make_unique<SimulationTask>(std::move(qc));
     circuitSimulatorExecutor =
         std::make_unique<CircuitSimulatorExecutor>(std::move(simulationTask));
   }

From 0a3f9569f9b5c8cb19071e275d3ad7c45e1d399e Mon Sep 17 00:00:00 2001
From: "pre-commit-ci[bot]"
 <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Date: Tue, 6 Jun 2023 23:05:21 +0000
Subject: [PATCH 31/43] =?UTF-8?q?=F0=9F=8E=A8=20pre-commit=20fixes?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 test/test_simexec.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/test/test_simexec.cpp b/test/test_simexec.cpp
index 3e891aa..6c824fd 100644
--- a/test/test_simexec.cpp
+++ b/test/test_simexec.cpp
@@ -32,9 +32,9 @@ class DDSIMExecTest : public ::testing::TestWithParam<TestConfigurationDDSIM> {
   void SetUp() override {
     test = GetParam();
 
-    std::stringstream      ss(test.initialCircuit);
-    auto qc = std::make_unique<qc::QuantumComputation>():
-    qc->import(ss, qc::Format::OpenQASM);
+    std::stringstream ss(test.initialCircuit);
+    auto              qc = std::make_unique<qc::QuantumComputation>()
+        : qc->import(ss, qc::Format::OpenQASM);
     std::cout << "Circuit:\n" << qc;
 
     simulationTask = std::make_unique<SimulationTask>(std::move(qc));

From 26889231014495daf6484d88693142e84910f048 Mon Sep 17 00:00:00 2001
From: Tianyi Wang <tianyi1.wang@tum.de>
Date: Thu, 8 Jun 2023 02:12:52 +0200
Subject: [PATCH 32/43] Refactoring the source code according to the review
 suggestions

---
 include/AlternatingVerificationExecutor.hpp   | 18 --------
 include/CircuitSimulatorExecutor.hpp          | 18 --------
 include/Executor.hpp                          | 16 ++++---
 include/SimulationExecutor.hpp                | 16 -------
 include/Task.hpp                              |  8 +---
 include/TestHelpers.hpp                       |  5 ---
 include/VerificationExecutor.hpp              | 16 -------
 .../AlternatingVerificationExecutor.hpp       | 15 +++++++
 .../executors/CircuitSimulatorExecutor.hpp    | 15 +++++++
 include/{ => tasks}/SimulationTask.hpp        | 11 ++++-
 include/{ => tasks}/VerificationTask.hpp      | 14 ++++--
 src/AlternatingVerificationExecutor.cpp       | 43 ++++++++-----------
 src/CMakeLists.txt                            | 18 +++-----
 src/CircuitSimulatorExecutor.cpp              | 40 ++++++-----------
 src/SimulationExecutor.cpp                    |  5 ---
 src/SimulationTask.cpp                        |  7 ---
 src/TestHelpers.cpp                           | 11 -----
 src/VerificationExecutor.cpp                  |  5 ---
 src/VerificationTask.cpp                      | 15 -------
 test/CMakeLists.txt                           | 11 +----
 test/test_qcecexec.cpp                        | 15 +++----
 test/test_qcecexec_simple.cpp                 | 25 -----------
 test/test_simexec.cpp                         | 23 +++++-----
 test/test_simexec_simple.cpp                  | 19 --------
 24 files changed, 116 insertions(+), 273 deletions(-)
 delete mode 100644 include/AlternatingVerificationExecutor.hpp
 delete mode 100644 include/CircuitSimulatorExecutor.hpp
 delete mode 100644 include/SimulationExecutor.hpp
 delete mode 100644 include/TestHelpers.hpp
 delete mode 100644 include/VerificationExecutor.hpp
 create mode 100644 include/executors/AlternatingVerificationExecutor.hpp
 create mode 100644 include/executors/CircuitSimulatorExecutor.hpp
 rename include/{ => tasks}/SimulationTask.hpp (70%)
 rename include/{ => tasks}/VerificationTask.hpp (72%)
 delete mode 100644 src/SimulationExecutor.cpp
 delete mode 100644 src/SimulationTask.cpp
 delete mode 100644 src/TestHelpers.cpp
 delete mode 100644 src/VerificationExecutor.cpp
 delete mode 100644 src/VerificationTask.cpp
 delete mode 100644 test/test_qcecexec_simple.cpp
 delete mode 100644 test/test_simexec_simple.cpp

diff --git a/include/AlternatingVerificationExecutor.hpp b/include/AlternatingVerificationExecutor.hpp
deleted file mode 100644
index 2e9521f..0000000
--- a/include/AlternatingVerificationExecutor.hpp
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma once
-
-#include "EquivalenceCheckingManager.hpp"
-#include "VerificationExecutor.hpp"
-
-class AlternatingVerificationExecutor : public VerificationExecutor {
-public:
-  AlternatingVerificationExecutor() = delete;
-
-  explicit AlternatingVerificationExecutor(
-      std::unique_ptr<VerificationTask> verificationTask);
-
-  json        executeTask() override;
-  std::string getIdentifier() override;
-
-private:
-  std::unique_ptr<ec::EquivalenceCheckingManager> mEquivalenceCheckingManager;
-};
diff --git a/include/CircuitSimulatorExecutor.hpp b/include/CircuitSimulatorExecutor.hpp
deleted file mode 100644
index bc548ee..0000000
--- a/include/CircuitSimulatorExecutor.hpp
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma once
-
-#include "CircuitSimulator.hpp"
-#include "SimulationExecutor.hpp"
-
-class CircuitSimulatorExecutor : public SimulationExecutor {
-public:
-  CircuitSimulatorExecutor() = delete;
-
-  explicit CircuitSimulatorExecutor(
-      std::unique_ptr<SimulationTask> simulationTask);
-
-  json        executeTask() override;
-  std::string getIdentifier() override;
-
-private:
-  std::unique_ptr<CircuitSimulator<>> mCircuitSimulator;
-};
diff --git a/include/Executor.hpp b/include/Executor.hpp
index 5042bcd..fafded8 100644
--- a/include/Executor.hpp
+++ b/include/Executor.hpp
@@ -2,16 +2,18 @@
 
 #include "Task.hpp"
 
-#include <memory>
+#include <nlohmann/json.hpp>
+#include <type_traits>
+
+using json = nlohmann::json;
+
+template <class T> class Executor {
+  static_assert(std::is_base_of_v<Task, T>);
 
-class Executor {
 public:
   virtual ~Executor() = default;
   explicit Executor() = default;
 
-  virtual json        executeTask()   = 0;
-  virtual std::string getIdentifier() = 0;
-
-private:
-  std::unique_ptr<Task> task;
+  virtual json                      execute(const T& task) = 0;
+  [[nodiscard]] virtual std::string getIdentifier() const  = 0;
 };
diff --git a/include/SimulationExecutor.hpp b/include/SimulationExecutor.hpp
deleted file mode 100644
index 188ca7a..0000000
--- a/include/SimulationExecutor.hpp
+++ /dev/null
@@ -1,16 +0,0 @@
-#pragma once
-
-#include "Executor.hpp"
-#include "SimulationTask.hpp"
-
-class SimulationExecutor : public Executor {
-public:
-  SimulationExecutor() = default;
-
-  const std::unique_ptr<SimulationTask>& getTask();
-
-  void setTask(std::unique_ptr<SimulationTask>& task);
-
-protected:
-  std::unique_ptr<SimulationTask> mTask;
-};
diff --git a/include/Task.hpp b/include/Task.hpp
index 2085fc6..a9267a4 100644
--- a/include/Task.hpp
+++ b/include/Task.hpp
@@ -1,11 +1,7 @@
 #pragma once
 
-#include <nlohmann/json.hpp>
-
-using json = nlohmann::json;
-
 class Task {
 public:
-  virtual ~Task()                     = default;
-  virtual std::string getIdentifier() = 0;
+  virtual ~Task()                                         = default;
+  [[nodiscard]] virtual std::string getIdentifier() const = 0;
 };
diff --git a/include/TestHelpers.hpp b/include/TestHelpers.hpp
deleted file mode 100644
index 7a90c94..0000000
--- a/include/TestHelpers.hpp
+++ /dev/null
@@ -1,5 +0,0 @@
-#pragma once
-
-#include <nlohmann/json.hpp>
-
-void printAll(const nlohmann::json& json);
diff --git a/include/VerificationExecutor.hpp b/include/VerificationExecutor.hpp
deleted file mode 100644
index 0143bb0..0000000
--- a/include/VerificationExecutor.hpp
+++ /dev/null
@@ -1,16 +0,0 @@
-#pragma once
-
-#include "Executor.hpp"
-#include "VerificationTask.hpp"
-
-class VerificationExecutor : public Executor {
-public:
-  VerificationExecutor() = default;
-
-  [[nodiscard]] const std::unique_ptr<VerificationTask>& getTask() const;
-
-  void setTask(std::unique_ptr<VerificationTask>& task);
-
-protected:
-  std::unique_ptr<VerificationTask> mTask;
-};
diff --git a/include/executors/AlternatingVerificationExecutor.hpp b/include/executors/AlternatingVerificationExecutor.hpp
new file mode 100644
index 0000000..072687e
--- /dev/null
+++ b/include/executors/AlternatingVerificationExecutor.hpp
@@ -0,0 +1,15 @@
+#pragma once
+
+#include "EquivalenceCheckingManager.hpp"
+#include "Executor.hpp"
+#include "tasks/VerificationTask.hpp"
+
+class AlternatingVerificationExecutor : public Executor<VerificationTask> {
+public:
+  AlternatingVerificationExecutor() = default;
+
+  json                      execute(const VerificationTask& task) override;
+  [[nodiscard]] std::string getIdentifier() const override {
+    return "alternating_verification";
+  }
+};
diff --git a/include/executors/CircuitSimulatorExecutor.hpp b/include/executors/CircuitSimulatorExecutor.hpp
new file mode 100644
index 0000000..d8d736b
--- /dev/null
+++ b/include/executors/CircuitSimulatorExecutor.hpp
@@ -0,0 +1,15 @@
+#pragma once
+
+#include "CircuitSimulator.hpp"
+#include "Executor.hpp"
+#include "tasks/SimulationTask.hpp"
+
+class CircuitSimulatorExecutor : public Executor<SimulationTask> {
+public:
+  CircuitSimulatorExecutor() = default;
+
+  json                      execute(const SimulationTask& task) override;
+  [[nodiscard]] std::string getIdentifier() const override {
+    return "circuit_simulator";
+  };
+};
diff --git a/include/SimulationTask.hpp b/include/tasks/SimulationTask.hpp
similarity index 70%
rename from include/SimulationTask.hpp
rename to include/tasks/SimulationTask.hpp
index c67e7bd..6911824 100644
--- a/include/SimulationTask.hpp
+++ b/include/tasks/SimulationTask.hpp
@@ -3,6 +3,8 @@
 #include "QuantumComputation.hpp"
 #include "Task.hpp"
 
+#include <memory>
+
 class SimulationTask : public Task {
 public:
   SimulationTask() = default;
@@ -10,8 +12,13 @@ class SimulationTask : public Task {
   explicit SimulationTask(std::unique_ptr<qc::QuantumComputation> qc)
       : qc(std::move(qc)) {}
 
-  [[nodiscard]] const std::unique_ptr<qc::QuantumComputation>& getQc() const;
-  std::string getIdentifier() override;
+  [[nodiscard]] const std::unique_ptr<qc::QuantumComputation>& getQc() const {
+    return qc;
+  };
+
+  [[nodiscard]] std::string getIdentifier() const override {
+    return "sim_" + qc->getName();
+  };
 
 protected:
   std::unique_ptr<qc::QuantumComputation> qc;
diff --git a/include/VerificationTask.hpp b/include/tasks/VerificationTask.hpp
similarity index 72%
rename from include/VerificationTask.hpp
rename to include/tasks/VerificationTask.hpp
index eb71402..917420c 100644
--- a/include/VerificationTask.hpp
+++ b/include/tasks/VerificationTask.hpp
@@ -3,20 +3,28 @@
 #include "QuantumComputation.hpp"
 #include "Task.hpp"
 
+#include <memory>
+
 class VerificationTask : public Task {
 public:
   VerificationTask() = default;
   VerificationTask(std::unique_ptr<qc::QuantumComputation> qc1,
                    std::unique_ptr<qc::QuantumComputation> qc2)
       : qc1(std::move(qc1)), qc2(std::move(qc2)) {}
-  std::string getIdentifier() override;
+  [[nodiscard]] std::string getIdentifier() const override {
+    return "ver_" + qc1->getName() + "_" + qc2->getName();
+  };
 
 protected:
   std::unique_ptr<qc::QuantumComputation> qc1;
   std::unique_ptr<qc::QuantumComputation> qc2;
 
 public:
-  [[nodiscard]] const std::unique_ptr<qc::QuantumComputation>& getQc1() const;
+  [[nodiscard]] const std::unique_ptr<qc::QuantumComputation>& getQc1() const {
+    return qc1;
+  };
 
-  [[nodiscard]] const std::unique_ptr<qc::QuantumComputation>& getQc2() const;
+  [[nodiscard]] const std::unique_ptr<qc::QuantumComputation>& getQc2() const {
+    return qc2;
+  };
 };
diff --git a/src/AlternatingVerificationExecutor.cpp b/src/AlternatingVerificationExecutor.cpp
index d2799cc..115e791 100644
--- a/src/AlternatingVerificationExecutor.cpp
+++ b/src/AlternatingVerificationExecutor.cpp
@@ -1,36 +1,27 @@
-#include "AlternatingVerificationExecutor.hpp"
+#include "executors/AlternatingVerificationExecutor.hpp"
 
-AlternatingVerificationExecutor::AlternatingVerificationExecutor(
-    std::unique_ptr<VerificationTask> verificationTask) {
-  mTask    = std::move(verificationTask);
-  auto qc1 = mTask->getQc1()->clone();
-  auto qc2 = mTask->getQc2()->clone();
-  mEquivalenceCheckingManager =
-      std::make_unique<ec::EquivalenceCheckingManager>(qc1, qc2);
-  mEquivalenceCheckingManager->setAlternatingChecker(true);
-  mEquivalenceCheckingManager->setSimulationChecker(false);
-  mEquivalenceCheckingManager->setConstructionChecker(false);
-  mEquivalenceCheckingManager->setZXChecker(false);
-}
-
-std::string AlternatingVerificationExecutor::getIdentifier() {
-  return "alt_ver_exe" + mTask->getIdentifier();
-}
-
-json AlternatingVerificationExecutor::executeTask() {
+json AlternatingVerificationExecutor::execute(const VerificationTask& task) {
   json result;
-  auto start = std::chrono::high_resolution_clock::now();
+  auto start = std::chrono::steady_clock::now();
+
+  auto qc1 = task.getQc1()->clone();
+  auto qc2 = task.getQc2()->clone();
+  auto equivalenceCheckingManager =
+      std::make_unique<ec::EquivalenceCheckingManager>(*task.getQc1(),
+                                                       *task.getQc2());
+  equivalenceCheckingManager->disableAllCheckers();
+  equivalenceCheckingManager->setAlternatingChecker(true);
 
-  mEquivalenceCheckingManager->run();
-  result = mEquivalenceCheckingManager->getResults().json();
+  equivalenceCheckingManager->run();
+  result["check_results"] = equivalenceCheckingManager->getResults().json();
   // Add memory usage
-  auto stop = std::chrono::high_resolution_clock::now();
+  auto stop = std::chrono::steady_clock::now();
   auto runtime =
       std::chrono::duration_cast<std::chrono::microseconds>(stop - start);
   result["runtime"] = runtime.count();
-  std::string const identifier =
-      this->getTask()->getIdentifier() + "_" + this->getIdentifier();
-  result["identifier"] = identifier;
+
+  result["executor"] = getIdentifier();
+  result["task"]     = task.getIdentifier();
 
   return result;
 }
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 93f09be..7795456 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -10,21 +10,13 @@ if(NOT TARGET ${PROJECT_NAME})
   add_library(
     ${PROJECT_NAME}
     ${PROJECT_SOURCE_DIR}/include/Executor.hpp
-    ${PROJECT_SOURCE_DIR}/include/SimulationExecutor.hpp
-    ${PROJECT_SOURCE_DIR}/include/VerificationExecutor.hpp
-    ${PROJECT_SOURCE_DIR}/include/CircuitSimulatorExecutor.hpp
-    ${PROJECT_SOURCE_DIR}/include/AlternatingVerificationExecutor.hpp
+    ${PROJECT_SOURCE_DIR}/include/executors/CircuitSimulatorExecutor.hpp
+    ${PROJECT_SOURCE_DIR}/include/executors/AlternatingVerificationExecutor.hpp
     ${PROJECT_SOURCE_DIR}/include/Task.hpp
-    ${PROJECT_SOURCE_DIR}/include/SimulationTask.hpp
-    ${PROJECT_SOURCE_DIR}/include/VerificationTask.hpp
-    ${PROJECT_SOURCE_DIR}/include/TestHelpers.hpp
-    TestHelpers.cpp
-    SimulationExecutor.cpp
+    ${PROJECT_SOURCE_DIR}/include/tasks/SimulationTask.hpp
+    ${PROJECT_SOURCE_DIR}/include/tasks/VerificationTask.hpp
     CircuitSimulatorExecutor.cpp
-    VerificationExecutor.cpp
-    AlternatingVerificationExecutor.cpp
-    SimulationTask.cpp
-    VerificationTask.cpp)
+    AlternatingVerificationExecutor.cpp)
 
   # set include directories
   target_include_directories(
diff --git a/src/CircuitSimulatorExecutor.cpp b/src/CircuitSimulatorExecutor.cpp
index 9c76141..6a73dd1 100644
--- a/src/CircuitSimulatorExecutor.cpp
+++ b/src/CircuitSimulatorExecutor.cpp
@@ -1,37 +1,21 @@
-#include "CircuitSimulatorExecutor.hpp"
+#include "executors/CircuitSimulatorExecutor.hpp"
 
-CircuitSimulatorExecutor::CircuitSimulatorExecutor(
-    std::unique_ptr<SimulationTask> simulationTask) {
-  mTask   = std::move(simulationTask);
-  auto qc = std::make_unique<qc::QuantumComputation>(mTask->getQc()->clone());
-  mCircuitSimulator = std::make_unique<CircuitSimulator<>>(std::move(qc));
-}
-
-std::string CircuitSimulatorExecutor::getIdentifier() {
-  return "circ_sim_exe" + mTask->getIdentifier();
-}
-
-template <typename KTy, typename VTy>
-inline void toJson(json& j, const std::map<KTy, VTy>& m) {
-  for (const auto& entry : m) {
-    j[entry.first] = entry.second;
-  }
-}
-
-json CircuitSimulatorExecutor::executeTask() {
+json CircuitSimulatorExecutor::execute(const SimulationTask& task) {
   json result;
-  auto start = std::chrono::high_resolution_clock::now();
+  auto start = std::chrono::steady_clock::now();
+
+  auto qc = std::make_unique<qc::QuantumComputation>(task.getQc()->clone());
+  auto circuitSimulator = std::make_unique<CircuitSimulator<>>(std::move(qc));
 
-  result["measurement_results"] = mCircuitSimulator->simulate(1024U);
+  result["measurement_results"] = circuitSimulator->simulate(1024U);
   // Add memory usage
 
-  auto stop = std::chrono::high_resolution_clock::now();
-  auto runtime =
+  auto       stop = std::chrono::steady_clock::now();
+  auto const runtime =
       std::chrono::duration_cast<std::chrono::microseconds>(stop - start);
-  result["runtime"] = runtime.count();
-  std::string const identifier =
-      this->getTask()->getIdentifier() + "_" + this->getIdentifier();
-  result["identifier"] = identifier;
+  result["runtime"]  = runtime.count();
+  result["executor"] = getIdentifier();
+  result["task"]     = task.getIdentifier();
 
   return result;
 }
diff --git a/src/SimulationExecutor.cpp b/src/SimulationExecutor.cpp
deleted file mode 100644
index 2fd4302..0000000
--- a/src/SimulationExecutor.cpp
+++ /dev/null
@@ -1,5 +0,0 @@
-#include "SimulationExecutor.hpp"
-
-const std::unique_ptr<SimulationTask>& SimulationExecutor::getTask() {
-  return mTask;
-}
diff --git a/src/SimulationTask.cpp b/src/SimulationTask.cpp
deleted file mode 100644
index 4e2a7cf..0000000
--- a/src/SimulationTask.cpp
+++ /dev/null
@@ -1,7 +0,0 @@
-#include "SimulationTask.hpp"
-
-std::string SimulationTask::getIdentifier() { return "sim_" + qc->getName(); }
-
-const std::unique_ptr<qc::QuantumComputation>& SimulationTask::getQc() const {
-  return qc;
-}
diff --git a/src/TestHelpers.cpp b/src/TestHelpers.cpp
deleted file mode 100644
index 48fdbf1..0000000
--- a/src/TestHelpers.cpp
+++ /dev/null
@@ -1,11 +0,0 @@
-#include "TestHelpers.hpp"
-
-#include <iostream>
-
-void printAll(const nlohmann::json& jsonObject) {
-  for (auto it = jsonObject.begin(); it != jsonObject.end(); ++it) {
-    const auto& key   = it.key();
-    const auto& value = it.value();
-    std::cout << key << ": " << value << std::endl;
-  }
-}
diff --git a/src/VerificationExecutor.cpp b/src/VerificationExecutor.cpp
deleted file mode 100644
index 075121c..0000000
--- a/src/VerificationExecutor.cpp
+++ /dev/null
@@ -1,5 +0,0 @@
-#include "VerificationExecutor.hpp"
-
-const std::unique_ptr<VerificationTask>& VerificationExecutor::getTask() const {
-  return mTask;
-}
diff --git a/src/VerificationTask.cpp b/src/VerificationTask.cpp
deleted file mode 100644
index 851a286..0000000
--- a/src/VerificationTask.cpp
+++ /dev/null
@@ -1,15 +0,0 @@
-#include "VerificationTask.hpp"
-
-std::string VerificationTask::getIdentifier() {
-  return "ver_" + qc1->getName() + "_" + qc2->getName();
-}
-
-const std::unique_ptr<qc::QuantumComputation>&
-VerificationTask::getQc1() const {
-  return qc1;
-}
-
-const std::unique_ptr<qc::QuantumComputation>&
-VerificationTask::getQc2() const {
-  return qc2;
-}
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index b286f68..a5565ee 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -13,12 +13,5 @@ configure_file(${CMAKE_SOURCE_DIR}/test/circuits.json
                ${CMAKE_CURRENT_BINARY_DIR}/circuits.json COPYONLY)
 configure_file(${CMAKE_SOURCE_DIR}/test/equi_circuits.json
                ${CMAKE_CURRENT_BINARY_DIR}/equi_circuits.json COPYONLY)
-package_add_test(
-  ${PROJECT_NAME}_test
-  ${PROJECT_NAME}
-  test_ddsim_simple.cpp
-  test_qcec_simple.cpp
-  test_simexec_simple.cpp
-  test_simexec.cpp
-  test_qcecexec_simple.cpp
-  test_qcecexec.cpp)
+package_add_test(${PROJECT_NAME}_test ${PROJECT_NAME} test_ddsim_simple.cpp
+                 test_qcec_simple.cpp test_simexec.cpp test_qcecexec.cpp)
diff --git a/test/test_qcecexec.cpp b/test/test_qcecexec.cpp
index de773d7..9947c81 100644
--- a/test/test_qcecexec.cpp
+++ b/test/test_qcecexec.cpp
@@ -1,6 +1,5 @@
-#include "AlternatingVerificationExecutor.hpp"
-#include "TestHelpers.hpp"
-#include "VerificationTask.hpp"
+#include "executors/AlternatingVerificationExecutor.hpp"
+#include "tasks/VerificationTask.hpp"
 
 #include "gtest/gtest.h"
 
@@ -50,8 +49,7 @@ class QCECExecTest : public ::testing::TestWithParam<TestConfigurationQCEC> {
                                                           std::move(qc2Ver));
 
     alternatingVerificationExecutor =
-        std::make_unique<AlternatingVerificationExecutor>(
-            std::move(verificationTask));
+        std::make_unique<AlternatingVerificationExecutor>();
   }
 
   void TearDown() override { std::cout << "Tearing down...\n"; }
@@ -71,8 +69,9 @@ INSTANTIATE_TEST_SUITE_P(
     });
 
 TEST_P(QCECExecTest, EmptyCircuits) {
-  json const result = alternatingVerificationExecutor->executeTask();
+  json const result =
+      alternatingVerificationExecutor->execute(*verificationTask);
   std::cout << "Results:" << std::endl;
-  printAll(result);
-  EXPECT_EQ(result["equivalence"], test.expectedEquivalence);
+  std::cout << result.dump(2U) << std::endl;
+  EXPECT_EQ(result["check_results"]["equivalence"], test.expectedEquivalence);
 }
diff --git a/test/test_qcecexec_simple.cpp b/test/test_qcecexec_simple.cpp
deleted file mode 100644
index c11107f..0000000
--- a/test/test_qcecexec_simple.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-#include "AlternatingVerificationExecutor.hpp"
-#include "VerificationTask.hpp"
-
-#include <gtest/gtest.h>
-#include <memory>
-
-TEST(QCECExecSimpleTest, SimpleCircuit) {
-  auto qc1 = std::make_unique<qc::QuantumComputation>(2U);
-  qc1->x(0U);
-  qc1->x(1U);
-  auto qc2 = std::make_unique<qc::QuantumComputation>(2U);
-  qc2->x(0U);
-  qc2->x(0U);
-  qc2->x(0U);
-  qc2->x(1U);
-  auto verificationTask =
-      std::make_unique<VerificationTask>(std::move(qc1), std::move(qc2));
-  auto alternatingVerificationExecutor =
-      std::make_unique<AlternatingVerificationExecutor>(
-          std::move(verificationTask));
-
-  json const result = alternatingVerificationExecutor->executeTask();
-
-  EXPECT_EQ("equivalent", result["equivalence"]);
-}
diff --git a/test/test_simexec.cpp b/test/test_simexec.cpp
index 6c824fd..353be67 100644
--- a/test/test_simexec.cpp
+++ b/test/test_simexec.cpp
@@ -1,6 +1,5 @@
-#include "CircuitSimulatorExecutor.hpp"
-#include "SimulationTask.hpp"
-#include "TestHelpers.hpp"
+#include "executors/CircuitSimulatorExecutor.hpp"
+#include "tasks/SimulationTask.hpp"
 
 #include "gtest/gtest.h"
 
@@ -33,13 +32,12 @@ class DDSIMExecTest : public ::testing::TestWithParam<TestConfigurationDDSIM> {
     test = GetParam();
 
     std::stringstream ss(test.initialCircuit);
-    auto              qc = std::make_unique<qc::QuantumComputation>()
-        : qc->import(ss, qc::Format::OpenQASM);
+    auto              qc = std::make_unique<qc::QuantumComputation>();
+    qc->import(ss, qc::Format::OpenQASM);
     std::cout << "Circuit:\n" << qc;
 
-    simulationTask = std::make_unique<SimulationTask>(std::move(qc));
-    circuitSimulatorExecutor =
-        std::make_unique<CircuitSimulatorExecutor>(std::move(simulationTask));
+    simulationTask           = std::make_unique<SimulationTask>(std::move(qc));
+    circuitSimulatorExecutor = std::make_unique<CircuitSimulatorExecutor>();
   }
 
   void TearDown() override { std::cout << "Tearing down...\n"; }
@@ -57,8 +55,11 @@ INSTANTIATE_TEST_SUITE_P(
     });
 
 TEST_P(DDSIMExecTest, TwoQubitCircuitWithTwoXGates) {
-  json const result = circuitSimulatorExecutor->executeTask();
+  json const result = circuitSimulatorExecutor->execute(*simulationTask);
   std::cout << "Results:" << std::endl;
-  printAll(result);
-  EXPECT_EQ(result["11"], test.expected11);
+  std::cout << result.dump(2U) << std::endl;
+  json const expected_results = {
+      {"11", test.expected11},
+  };
+  EXPECT_EQ(result["measurement_results"], expected_results);
 }
diff --git a/test/test_simexec_simple.cpp b/test/test_simexec_simple.cpp
deleted file mode 100644
index 9ccd4ed..0000000
--- a/test/test_simexec_simple.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-#include "CircuitSimulatorExecutor.hpp"
-#include "SimulationTask.hpp"
-
-#include <gtest/gtest.h>
-#include <memory>
-
-TEST(DDSIMExecSimpleTest, SimpleCircuit) {
-  using namespace qc::literals;
-  auto qc = std::make_unique<qc::QuantumComputation>(2U);
-  qc->h(0U);
-  qc->x(1U, 0_pc);
-
-  auto simulationTask = std::make_unique<SimulationTask>(std::move(qc));
-  auto circuitSimulatorExecutor =
-      std::make_unique<CircuitSimulatorExecutor>(std::move(simulationTask));
-  json const result = circuitSimulatorExecutor->executeTask();
-  EXPECT_FALSE(result.contains("01"));
-  EXPECT_FALSE(result.contains("10"));
-}

From a397089b0c2b96f8b78d86454315a56d14e85693 Mon Sep 17 00:00:00 2001
From: Tianyi Wang <tianyi1.wang@tum.de>
Date: Thu, 8 Jun 2023 02:21:17 +0200
Subject: [PATCH 33/43] Refactor test files to remove redundant copy

---
 test/test_qcecexec.cpp | 23 +++++++++--------------
 test/test_simexec.cpp  | 11 +++++------
 2 files changed, 14 insertions(+), 20 deletions(-)

diff --git a/test/test_qcecexec.cpp b/test/test_qcecexec.cpp
index 9947c81..11ea383 100644
--- a/test/test_qcecexec.cpp
+++ b/test/test_qcecexec.cpp
@@ -33,20 +33,17 @@ class QCECExecTest : public ::testing::TestWithParam<TestConfigurationQCEC> {
   void SetUp() override {
     test = GetParam();
 
-    std::stringstream      ss1(test.initialCircuit1);
-    qc::QuantumComputation qc1{};
-    qc1.import(ss1, qc::Format::OpenQASM);
+    std::stringstream ss1(test.initialCircuit1);
+    auto              qc1 = std::make_unique<qc::QuantumComputation>();
+    qc1->import(ss1, qc::Format::OpenQASM);
     std::cout << "Circuit 1:\n" << qc1 << std::endl;
 
-    std::stringstream      ss2(test.initialCircuit2);
-    qc::QuantumComputation qc2{};
-    qc2.import(ss2, qc::Format::OpenQASM);
+    std::stringstream ss2(test.initialCircuit2);
+    auto              qc2 = std::make_unique<qc::QuantumComputation>();
+    qc2->import(ss2, qc::Format::OpenQASM);
     std::cout << "Circuit 2:\n" << qc2 << std::endl;
 
-    qc1Ver           = std::make_unique<qc::QuantumComputation>(qc1.clone());
-    qc2Ver           = std::make_unique<qc::QuantumComputation>(qc2.clone());
-    verificationTask = std::make_unique<VerificationTask>(std::move(qc1Ver),
-                                                          std::move(qc2Ver));
+    verificationTask = VerificationTask(std::move(qc1), std::move(qc2));
 
     alternatingVerificationExecutor =
         std::make_unique<AlternatingVerificationExecutor>();
@@ -54,9 +51,7 @@ class QCECExecTest : public ::testing::TestWithParam<TestConfigurationQCEC> {
 
   void TearDown() override { std::cout << "Tearing down...\n"; }
 
-  std::unique_ptr<qc::QuantumComputation> qc1Ver;
-  std::unique_ptr<qc::QuantumComputation> qc2Ver;
-  std::unique_ptr<VerificationTask>       verificationTask;
+  VerificationTask verificationTask;
   std::unique_ptr<AlternatingVerificationExecutor>
                         alternatingVerificationExecutor;
   TestConfigurationQCEC test;
@@ -70,7 +65,7 @@ INSTANTIATE_TEST_SUITE_P(
 
 TEST_P(QCECExecTest, EmptyCircuits) {
   json const result =
-      alternatingVerificationExecutor->execute(*verificationTask);
+      alternatingVerificationExecutor->execute(verificationTask);
   std::cout << "Results:" << std::endl;
   std::cout << result.dump(2U) << std::endl;
   EXPECT_EQ(result["check_results"]["equivalence"], test.expectedEquivalence);
diff --git a/test/test_simexec.cpp b/test/test_simexec.cpp
index 353be67..81a71fb 100644
--- a/test/test_simexec.cpp
+++ b/test/test_simexec.cpp
@@ -36,14 +36,13 @@ class DDSIMExecTest : public ::testing::TestWithParam<TestConfigurationDDSIM> {
     qc->import(ss, qc::Format::OpenQASM);
     std::cout << "Circuit:\n" << qc;
 
-    simulationTask           = std::make_unique<SimulationTask>(std::move(qc));
+    simulationTask           = SimulationTask(std::move(qc));
     circuitSimulatorExecutor = std::make_unique<CircuitSimulatorExecutor>();
   }
 
   void TearDown() override { std::cout << "Tearing down...\n"; }
 
-  std::unique_ptr<qc::QuantumComputation>   qcSim;
-  std::unique_ptr<SimulationTask>           simulationTask;
+  SimulationTask                            simulationTask;
   std::unique_ptr<CircuitSimulatorExecutor> circuitSimulatorExecutor;
   TestConfigurationDDSIM                    test;
 };
@@ -55,11 +54,11 @@ INSTANTIATE_TEST_SUITE_P(
     });
 
 TEST_P(DDSIMExecTest, TwoQubitCircuitWithTwoXGates) {
-  json const result = circuitSimulatorExecutor->execute(*simulationTask);
+  json const result = circuitSimulatorExecutor->execute(simulationTask);
   std::cout << "Results:" << std::endl;
   std::cout << result.dump(2U) << std::endl;
-  json const expected_results = {
+  json const expectedResults = {
       {"11", test.expected11},
   };
-  EXPECT_EQ(result["measurement_results"], expected_results);
+  EXPECT_EQ(result["measurement_results"], expectedResults);
 }

From a4e752f055d7f365152c26e8756bfcbb84d14b07 Mon Sep 17 00:00:00 2001
From: Tianyi Wang <tianyi1.wang@tum.de>
Date: Thu, 8 Jun 2023 02:24:11 +0200
Subject: [PATCH 34/43] Track both times in execution

---
 src/AlternatingVerificationExecutor.cpp | 18 ++++++++++++------
 src/CircuitSimulatorExecutor.cpp        | 19 +++++++++++++------
 2 files changed, 25 insertions(+), 12 deletions(-)

diff --git a/src/AlternatingVerificationExecutor.cpp b/src/AlternatingVerificationExecutor.cpp
index 115e791..2325a2d 100644
--- a/src/AlternatingVerificationExecutor.cpp
+++ b/src/AlternatingVerificationExecutor.cpp
@@ -1,8 +1,8 @@
 #include "executors/AlternatingVerificationExecutor.hpp"
 
 json AlternatingVerificationExecutor::execute(const VerificationTask& task) {
-  json result;
-  auto start = std::chrono::steady_clock::now();
+  json       result;
+  auto const constructionStart = std::chrono::steady_clock::now();
 
   auto qc1 = task.getQc1()->clone();
   auto qc2 = task.getQc2()->clone();
@@ -12,13 +12,19 @@ json AlternatingVerificationExecutor::execute(const VerificationTask& task) {
   equivalenceCheckingManager->disableAllCheckers();
   equivalenceCheckingManager->setAlternatingChecker(true);
 
+  auto const executionStart = std::chrono::steady_clock::now();
+
   equivalenceCheckingManager->run();
   result["check_results"] = equivalenceCheckingManager->getResults().json();
   // Add memory usage
-  auto stop = std::chrono::steady_clock::now();
-  auto runtime =
-      std::chrono::duration_cast<std::chrono::microseconds>(stop - start);
-  result["runtime"] = runtime.count();
+  auto const executionStop = std::chrono::steady_clock::now();
+  auto const constructionTime =
+      std::chrono::duration_cast<std::chrono::microseconds>(executionStart -
+                                                            constructionStart);
+  auto const execTime = std::chrono::duration_cast<std::chrono::microseconds>(
+      executionStop - executionStart);
+  result["construction_time"] = constructionTime.count();
+  result["execution_time"]    = execTime.count();
 
   result["executor"] = getIdentifier();
   result["task"]     = task.getIdentifier();
diff --git a/src/CircuitSimulatorExecutor.cpp b/src/CircuitSimulatorExecutor.cpp
index 6a73dd1..2384338 100644
--- a/src/CircuitSimulatorExecutor.cpp
+++ b/src/CircuitSimulatorExecutor.cpp
@@ -1,19 +1,26 @@
 #include "executors/CircuitSimulatorExecutor.hpp"
 
 json CircuitSimulatorExecutor::execute(const SimulationTask& task) {
-  json result;
-  auto start = std::chrono::steady_clock::now();
+  json       result;
+  auto const constructionStart = std::chrono::steady_clock::now();
 
   auto qc = std::make_unique<qc::QuantumComputation>(task.getQc()->clone());
   auto circuitSimulator = std::make_unique<CircuitSimulator<>>(std::move(qc));
 
+  auto const executionStart = std::chrono::steady_clock::now();
+
   result["measurement_results"] = circuitSimulator->simulate(1024U);
   // Add memory usage
 
-  auto       stop = std::chrono::steady_clock::now();
-  auto const runtime =
-      std::chrono::duration_cast<std::chrono::microseconds>(stop - start);
-  result["runtime"]  = runtime.count();
+  auto const executionStop = std::chrono::steady_clock::now();
+  auto const constructionTime =
+      std::chrono::duration_cast<std::chrono::microseconds>(executionStart -
+                                                            constructionStart);
+  auto const execTime = std::chrono::duration_cast<std::chrono::microseconds>(
+      executionStop - executionStart);
+  result["construction_time"] = constructionTime.count();
+  result["execution_time"]    = execTime.count();
+
   result["executor"] = getIdentifier();
   result["task"]     = task.getIdentifier();
 

From 61c45d04aa76b8b3bc6882ad01f05ea61cc277e4 Mon Sep 17 00:00:00 2001
From: Tianyi Wang <tianyi1.wang@tum.de>
Date: Fri, 9 Jun 2023 14:36:34 +0200
Subject: [PATCH 35/43] Fix ci issues

---
 test/test_qcecexec.cpp | 4 ++--
 test/test_simexec.cpp  | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/test/test_qcecexec.cpp b/test/test_qcecexec.cpp
index 11ea383..53eef79 100644
--- a/test/test_qcecexec.cpp
+++ b/test/test_qcecexec.cpp
@@ -36,12 +36,12 @@ class QCECExecTest : public ::testing::TestWithParam<TestConfigurationQCEC> {
     std::stringstream ss1(test.initialCircuit1);
     auto              qc1 = std::make_unique<qc::QuantumComputation>();
     qc1->import(ss1, qc::Format::OpenQASM);
-    std::cout << "Circuit 1:\n" << qc1 << std::endl;
+    std::cout << "Circuit 1:\n" << *qc1 << std::endl;
 
     std::stringstream ss2(test.initialCircuit2);
     auto              qc2 = std::make_unique<qc::QuantumComputation>();
     qc2->import(ss2, qc::Format::OpenQASM);
-    std::cout << "Circuit 2:\n" << qc2 << std::endl;
+    std::cout << "Circuit 2:\n" << *qc2 << std::endl;
 
     verificationTask = VerificationTask(std::move(qc1), std::move(qc2));
 
diff --git a/test/test_simexec.cpp b/test/test_simexec.cpp
index 81a71fb..0b9da73 100644
--- a/test/test_simexec.cpp
+++ b/test/test_simexec.cpp
@@ -34,7 +34,7 @@ class DDSIMExecTest : public ::testing::TestWithParam<TestConfigurationDDSIM> {
     std::stringstream ss(test.initialCircuit);
     auto              qc = std::make_unique<qc::QuantumComputation>();
     qc->import(ss, qc::Format::OpenQASM);
-    std::cout << "Circuit:\n" << qc;
+    std::cout << "Circuit:\n" << *qc;
 
     simulationTask           = SimulationTask(std::move(qc));
     circuitSimulatorExecutor = std::make_unique<CircuitSimulatorExecutor>();

From 49f92f189c858efc77ba8a4a5f1357d07f6f04ce Mon Sep 17 00:00:00 2001
From: Tianyi Wang <tianyi1.wang@tum.de>
Date: Fri, 9 Jun 2023 15:10:30 +0200
Subject: [PATCH 36/43] Fix CI issues (continued)

---
 include/Task.hpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/Task.hpp b/include/Task.hpp
index a9267a4..658e71d 100644
--- a/include/Task.hpp
+++ b/include/Task.hpp
@@ -1,5 +1,7 @@
 #pragma once
 
+#include <string>
+
 class Task {
 public:
   virtual ~Task()                                         = default;

From fa3c7e5638206c0b033a383ea9ae37cb03153823 Mon Sep 17 00:00:00 2001
From: Tianyi Wang <tianyi1.wang@tum.de>
Date: Fri, 9 Jun 2023 15:20:52 +0200
Subject: [PATCH 37/43] Refactor tests to be more flexible

---
 test/circuits.json      | 11 ++++++++++-
 test/equi_circuits.json |  6 ++++++
 test/test_qcecexec.cpp  | 18 +++++++++++++-----
 test/test_simexec.cpp   | 30 ++++++++++++++++++------------
 4 files changed, 47 insertions(+), 18 deletions(-)

diff --git a/test/circuits.json b/test/circuits.json
index 010bcf2..75f9adc 100644
--- a/test/circuits.json
+++ b/test/circuits.json
@@ -2,6 +2,15 @@
   {
     "description": "two_qubit_circuit_with_two_x_gates",
     "initial_circuit": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];x q[0];x q[1];\n",
-    "expected_11": 1024
+    "expected_meas_results": {
+      "11": 1024
+    }
+  },
+  {
+    "description": "two_qubit_circuit_with_h_z_controlled_x_swap",
+    "initial_circuit": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];cx q[0], q[1];h q[0];z q[0];h q[0];swap q[0], q[1];\n",
+    "expected_meas_results": {
+      "10": 1024
+    }
   }
 ]
diff --git a/test/equi_circuits.json b/test/equi_circuits.json
index 6d01275..524fb62 100644
--- a/test/equi_circuits.json
+++ b/test/equi_circuits.json
@@ -4,5 +4,11 @@
     "initial_circuit1": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];x q[0];x q[1];\n",
     "initial_circuit2": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];x q[0];x q[1];x q[0];x q[0];\n",
     "expected_equivalence": "equivalent"
+  },
+  {
+    "description": "non_equi_circuits",
+    "initial_circuit1": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];h q[0];t q[1];cx q[0], q[1];\n",
+    "initial_circuit2": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];h q[1];cx q[0], q[1];s q[0];\n",
+    "expected_equivalence": "not_equivalent"
   }
 ]
diff --git a/test/test_qcecexec.cpp b/test/test_qcecexec.cpp
index 53eef79..5c91404 100644
--- a/test/test_qcecexec.cpp
+++ b/test/test_qcecexec.cpp
@@ -47,6 +47,10 @@ class QCECExecTest : public ::testing::TestWithParam<TestConfigurationQCEC> {
 
     alternatingVerificationExecutor =
         std::make_unique<AlternatingVerificationExecutor>();
+
+    result = alternatingVerificationExecutor->execute(verificationTask);
+    std::cout << "Results:" << std::endl;
+    std::cout << result.dump(2U) << std::endl;
   }
 
   void TearDown() override { std::cout << "Tearing down...\n"; }
@@ -55,6 +59,7 @@ class QCECExecTest : public ::testing::TestWithParam<TestConfigurationQCEC> {
   std::unique_ptr<AlternatingVerificationExecutor>
                         alternatingVerificationExecutor;
   TestConfigurationQCEC test;
+  json                  result;
 };
 
 INSTANTIATE_TEST_SUITE_P(
@@ -63,10 +68,13 @@ INSTANTIATE_TEST_SUITE_P(
       return inf.param.description;
     });
 
-TEST_P(QCECExecTest, EmptyCircuits) {
-  json const result =
-      alternatingVerificationExecutor->execute(verificationTask);
-  std::cout << "Results:" << std::endl;
-  std::cout << result.dump(2U) << std::endl;
+TEST_P(QCECExecTest, Equivalence) {
   EXPECT_EQ(result["check_results"]["equivalence"], test.expectedEquivalence);
 }
+
+TEST_P(QCECExecTest, Entries) {
+  EXPECT_TRUE(result.contains("construction_time"));
+  EXPECT_TRUE(result.contains("execution_time"));
+  EXPECT_TRUE(result.contains("executor"));
+  EXPECT_TRUE(result.contains("task"));
+}
diff --git a/test/test_simexec.cpp b/test/test_simexec.cpp
index 0b9da73..3976447 100644
--- a/test/test_simexec.cpp
+++ b/test/test_simexec.cpp
@@ -9,14 +9,14 @@ struct TestConfigurationDDSIM {
   std::string initialCircuit;
 
   // expected output
-  std::size_t expected11{};
+  json expectedResults{};
 };
 
 // NOLINTNEXTLINE (readability-identifier-naming)
 inline void from_json(const nlohmann::json& j, TestConfigurationDDSIM& test) {
-  test.description    = j.at("description").get<std::string>();
-  test.initialCircuit = j.at("initial_circuit").get<std::string>();
-  test.expected11     = j.at("expected_11").get<std::size_t>();
+  test.description     = j.at("description").get<std::string>();
+  test.initialCircuit  = j.at("initial_circuit").get<std::string>();
+  test.expectedResults = j.at("expected_meas_results").get<json>();
 }
 
 static std::vector<TestConfigurationDDSIM> getTests(const std::string& path) {
@@ -38,6 +38,10 @@ class DDSIMExecTest : public ::testing::TestWithParam<TestConfigurationDDSIM> {
 
     simulationTask           = SimulationTask(std::move(qc));
     circuitSimulatorExecutor = std::make_unique<CircuitSimulatorExecutor>();
+
+    result = circuitSimulatorExecutor->execute(simulationTask);
+    std::cout << "Results:" << std::endl;
+    std::cout << result.dump(2U) << std::endl;
   }
 
   void TearDown() override { std::cout << "Tearing down...\n"; }
@@ -45,6 +49,7 @@ class DDSIMExecTest : public ::testing::TestWithParam<TestConfigurationDDSIM> {
   SimulationTask                            simulationTask;
   std::unique_ptr<CircuitSimulatorExecutor> circuitSimulatorExecutor;
   TestConfigurationDDSIM                    test;
+  json                                      result;
 };
 
 INSTANTIATE_TEST_SUITE_P(
@@ -53,12 +58,13 @@ INSTANTIATE_TEST_SUITE_P(
       return inf.param.description;
     });
 
-TEST_P(DDSIMExecTest, TwoQubitCircuitWithTwoXGates) {
-  json const result = circuitSimulatorExecutor->execute(simulationTask);
-  std::cout << "Results:" << std::endl;
-  std::cout << result.dump(2U) << std::endl;
-  json const expectedResults = {
-      {"11", test.expected11},
-  };
-  EXPECT_EQ(result["measurement_results"], expectedResults);
+TEST_P(DDSIMExecTest, MeasResults) {
+  EXPECT_EQ(result["measurement_results"], test.expectedResults);
+}
+
+TEST_P(DDSIMExecTest, Entries) {
+  EXPECT_TRUE(result.contains("construction_time"));
+  EXPECT_TRUE(result.contains("execution_time"));
+  EXPECT_TRUE(result.contains("executor"));
+  EXPECT_TRUE(result.contains("task"));
 }

From 37592a6d2acd2863e210f179250f2ce617960a6c Mon Sep 17 00:00:00 2001
From: Lukas Burgholzer <lukas.burgholzer@jku.at>
Date: Fri, 9 Jun 2023 18:18:54 +0200
Subject: [PATCH 38/43] =?UTF-8?q?=F0=9F=8E=A8=20assorted=20cleanups?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 include/Executor.hpp                          |  6 ++--
 include/Task.hpp                              |  3 +-
 .../AlternatingVerificationExecutor.hpp       |  4 +--
 .../executors/CircuitSimulatorExecutor.hpp    |  4 +--
 include/tasks/SimulationTask.hpp              | 13 ++++----
 include/tasks/VerificationTask.hpp            | 18 +++++-----
 src/AlternatingVerificationExecutor.cpp       |  4 +--
 src/CircuitSimulatorExecutor.cpp              |  2 ++
 test/CMakeLists.txt                           | 12 +++----
 test/equi_circuits.json                       | 14 --------
 test/{circuits.json => sim_circuits.json}     |  4 +--
 test/test_ddsim_simple.cpp                    | 20 -----------
 test/test_qcec_simple.cpp                     | 19 -----------
 test/test_qcecexec.cpp                        | 30 ++++++++---------
 test/test_simexec.cpp                         | 33 +++++++++----------
 test/ver_circuits.json                        | 14 ++++++++
 16 files changed, 77 insertions(+), 123 deletions(-)
 delete mode 100644 test/equi_circuits.json
 rename test/{circuits.json => sim_circuits.json} (54%)
 delete mode 100644 test/test_ddsim_simple.cpp
 delete mode 100644 test/test_qcec_simple.cpp
 create mode 100644 test/ver_circuits.json

diff --git a/include/Executor.hpp b/include/Executor.hpp
index fafded8..4879301 100644
--- a/include/Executor.hpp
+++ b/include/Executor.hpp
@@ -12,8 +12,8 @@ template <class T> class Executor {
 
 public:
   virtual ~Executor() = default;
-  explicit Executor() = default;
 
-  virtual json                      execute(const T& task) = 0;
-  [[nodiscard]] virtual std::string getIdentifier() const  = 0;
+  virtual json execute(const T& task) = 0;
+
+  [[nodiscard]] virtual std::string getIdentifier() const = 0;
 };
diff --git a/include/Task.hpp b/include/Task.hpp
index 658e71d..bb94571 100644
--- a/include/Task.hpp
+++ b/include/Task.hpp
@@ -4,6 +4,7 @@
 
 class Task {
 public:
-  virtual ~Task()                                         = default;
+  virtual ~Task() = default;
+
   [[nodiscard]] virtual std::string getIdentifier() const = 0;
 };
diff --git a/include/executors/AlternatingVerificationExecutor.hpp b/include/executors/AlternatingVerificationExecutor.hpp
index 072687e..f133246 100644
--- a/include/executors/AlternatingVerificationExecutor.hpp
+++ b/include/executors/AlternatingVerificationExecutor.hpp
@@ -1,14 +1,12 @@
 #pragma once
 
-#include "EquivalenceCheckingManager.hpp"
 #include "Executor.hpp"
 #include "tasks/VerificationTask.hpp"
 
 class AlternatingVerificationExecutor : public Executor<VerificationTask> {
 public:
-  AlternatingVerificationExecutor() = default;
+  json execute(const VerificationTask& task) override;
 
-  json                      execute(const VerificationTask& task) override;
   [[nodiscard]] std::string getIdentifier() const override {
     return "alternating_verification";
   }
diff --git a/include/executors/CircuitSimulatorExecutor.hpp b/include/executors/CircuitSimulatorExecutor.hpp
index d8d736b..10987af 100644
--- a/include/executors/CircuitSimulatorExecutor.hpp
+++ b/include/executors/CircuitSimulatorExecutor.hpp
@@ -1,14 +1,12 @@
 #pragma once
 
-#include "CircuitSimulator.hpp"
 #include "Executor.hpp"
 #include "tasks/SimulationTask.hpp"
 
 class CircuitSimulatorExecutor : public Executor<SimulationTask> {
 public:
-  CircuitSimulatorExecutor() = default;
+  json execute(const SimulationTask& task) override;
 
-  json                      execute(const SimulationTask& task) override;
   [[nodiscard]] std::string getIdentifier() const override {
     return "circuit_simulator";
   };
diff --git a/include/tasks/SimulationTask.hpp b/include/tasks/SimulationTask.hpp
index 6911824..dae4bdd 100644
--- a/include/tasks/SimulationTask.hpp
+++ b/include/tasks/SimulationTask.hpp
@@ -7,19 +7,18 @@
 
 class SimulationTask : public Task {
 public:
-  SimulationTask() = default;
+  explicit SimulationTask() = default;
+  explicit SimulationTask(std::unique_ptr<qc::QuantumComputation> circ)
+      : qc(std::move(circ)) {}
 
-  explicit SimulationTask(std::unique_ptr<qc::QuantumComputation> qc)
-      : qc(std::move(qc)) {}
+  [[nodiscard]] std::string getIdentifier() const override {
+    return "sim_" + qc->getName();
+  };
 
   [[nodiscard]] const std::unique_ptr<qc::QuantumComputation>& getQc() const {
     return qc;
   };
 
-  [[nodiscard]] std::string getIdentifier() const override {
-    return "sim_" + qc->getName();
-  };
-
 protected:
   std::unique_ptr<qc::QuantumComputation> qc;
 };
diff --git a/include/tasks/VerificationTask.hpp b/include/tasks/VerificationTask.hpp
index 917420c..8a33f2b 100644
--- a/include/tasks/VerificationTask.hpp
+++ b/include/tasks/VerificationTask.hpp
@@ -7,19 +7,15 @@
 
 class VerificationTask : public Task {
 public:
-  VerificationTask() = default;
-  VerificationTask(std::unique_ptr<qc::QuantumComputation> qc1,
-                   std::unique_ptr<qc::QuantumComputation> qc2)
-      : qc1(std::move(qc1)), qc2(std::move(qc2)) {}
+  explicit VerificationTask() = default;
+  VerificationTask(std::unique_ptr<qc::QuantumComputation> circ1,
+                   std::unique_ptr<qc::QuantumComputation> circ2)
+      : qc1(std::move(circ1)), qc2(std::move(circ2)) {}
+
   [[nodiscard]] std::string getIdentifier() const override {
     return "ver_" + qc1->getName() + "_" + qc2->getName();
   };
 
-protected:
-  std::unique_ptr<qc::QuantumComputation> qc1;
-  std::unique_ptr<qc::QuantumComputation> qc2;
-
-public:
   [[nodiscard]] const std::unique_ptr<qc::QuantumComputation>& getQc1() const {
     return qc1;
   };
@@ -27,4 +23,8 @@ class VerificationTask : public Task {
   [[nodiscard]] const std::unique_ptr<qc::QuantumComputation>& getQc2() const {
     return qc2;
   };
+
+protected:
+  std::unique_ptr<qc::QuantumComputation> qc1;
+  std::unique_ptr<qc::QuantumComputation> qc2;
 };
diff --git a/src/AlternatingVerificationExecutor.cpp b/src/AlternatingVerificationExecutor.cpp
index 2325a2d..1ebb051 100644
--- a/src/AlternatingVerificationExecutor.cpp
+++ b/src/AlternatingVerificationExecutor.cpp
@@ -1,11 +1,11 @@
 #include "executors/AlternatingVerificationExecutor.hpp"
 
+#include "EquivalenceCheckingManager.hpp"
+
 json AlternatingVerificationExecutor::execute(const VerificationTask& task) {
   json       result;
   auto const constructionStart = std::chrono::steady_clock::now();
 
-  auto qc1 = task.getQc1()->clone();
-  auto qc2 = task.getQc2()->clone();
   auto equivalenceCheckingManager =
       std::make_unique<ec::EquivalenceCheckingManager>(*task.getQc1(),
                                                        *task.getQc2());
diff --git a/src/CircuitSimulatorExecutor.cpp b/src/CircuitSimulatorExecutor.cpp
index 2384338..367989a 100644
--- a/src/CircuitSimulatorExecutor.cpp
+++ b/src/CircuitSimulatorExecutor.cpp
@@ -1,5 +1,7 @@
 #include "executors/CircuitSimulatorExecutor.hpp"
 
+#include "CircuitSimulator.hpp"
+
 json CircuitSimulatorExecutor::execute(const SimulationTask& task) {
   json       result;
   auto const constructionStart = std::chrono::steady_clock::now();
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index a5565ee..6414a6c 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -9,9 +9,9 @@ if(NOT TARGET gtest OR NOT TARGET gmock)
   add_subdirectory("${PROJECT_SOURCE_DIR}/${GTEST_PATH}" "${GTEST_PATH}"
                    EXCLUDE_FROM_ALL)
 endif()
-configure_file(${CMAKE_SOURCE_DIR}/test/circuits.json
-               ${CMAKE_CURRENT_BINARY_DIR}/circuits.json COPYONLY)
-configure_file(${CMAKE_SOURCE_DIR}/test/equi_circuits.json
-               ${CMAKE_CURRENT_BINARY_DIR}/equi_circuits.json COPYONLY)
-package_add_test(${PROJECT_NAME}_test ${PROJECT_NAME} test_ddsim_simple.cpp
-                 test_qcec_simple.cpp test_simexec.cpp test_qcecexec.cpp)
+configure_file(${CMAKE_SOURCE_DIR}/test/sim_circuits.json
+               ${CMAKE_CURRENT_BINARY_DIR}/sim_circuits.json COPYONLY)
+configure_file(${CMAKE_SOURCE_DIR}/test/ver_circuits.json
+               ${CMAKE_CURRENT_BINARY_DIR}/ver_circuits.json COPYONLY)
+package_add_test(${PROJECT_NAME}_sim_test ${PROJECT_NAME} test_simexec.cpp)
+package_add_test(${PROJECT_NAME}_ver_test ${PROJECT_NAME} test_qcecexec.cpp)
diff --git a/test/equi_circuits.json b/test/equi_circuits.json
deleted file mode 100644
index 524fb62..0000000
--- a/test/equi_circuits.json
+++ /dev/null
@@ -1,14 +0,0 @@
-[
-  {
-    "description": "simple_circuits",
-    "initial_circuit1": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];x q[0];x q[1];\n",
-    "initial_circuit2": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];x q[0];x q[1];x q[0];x q[0];\n",
-    "expected_equivalence": "equivalent"
-  },
-  {
-    "description": "non_equi_circuits",
-    "initial_circuit1": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];h q[0];t q[1];cx q[0], q[1];\n",
-    "initial_circuit2": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];h q[1];cx q[0], q[1];s q[0];\n",
-    "expected_equivalence": "not_equivalent"
-  }
-]
diff --git a/test/circuits.json b/test/sim_circuits.json
similarity index 54%
rename from test/circuits.json
rename to test/sim_circuits.json
index 75f9adc..1602d8a 100644
--- a/test/circuits.json
+++ b/test/sim_circuits.json
@@ -1,14 +1,14 @@
 [
   {
     "description": "two_qubit_circuit_with_two_x_gates",
-    "initial_circuit": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];x q[0];x q[1];\n",
+    "circuit": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];x q[0];x q[1];\n",
     "expected_meas_results": {
       "11": 1024
     }
   },
   {
     "description": "two_qubit_circuit_with_h_z_controlled_x_swap",
-    "initial_circuit": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];cx q[0], q[1];h q[0];z q[0];h q[0];swap q[0], q[1];\n",
+    "circuit": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];cx q[0], q[1];h q[0];z q[0];h q[0];swap q[0], q[1];\n",
     "expected_meas_results": {
       "10": 1024
     }
diff --git a/test/test_ddsim_simple.cpp b/test/test_ddsim_simple.cpp
deleted file mode 100644
index 210cce0..0000000
--- a/test/test_ddsim_simple.cpp
+++ /dev/null
@@ -1,20 +0,0 @@
-// A simple test file using googletest to ensure DDSIM is working properly
-
-#include "CircuitSimulator.hpp"
-
-#include <gtest/gtest.h>
-#include <memory>
-
-TEST(DDSIMSimpleTest, SimpleTest) {
-  using namespace qc::literals;
-
-  // Create a simple circuit
-  auto qc = std::make_unique<qc::QuantumComputation>(2U);
-  qc->h(0U);
-  qc->x(1U, 0_pc);
-
-  auto       sim     = CircuitSimulator(std::move(qc));
-  const auto results = sim.simulate(1024U);
-  EXPECT_EQ(results.count("01"), 0U);
-  EXPECT_EQ(results.count("10"), 0U);
-}
diff --git a/test/test_qcec_simple.cpp b/test/test_qcec_simple.cpp
deleted file mode 100644
index a4323f5..0000000
--- a/test/test_qcec_simple.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-// A simple test file using googletest to ensure QCEC is working properly
-
-#include "EquivalenceCheckingManager.hpp"
-
-#include <gtest/gtest.h>
-
-TEST(QCECSimpleTest, SimpleTest) {
-  using namespace qc::literals;
-
-  // Create a simple circuit
-  auto qc = qc::QuantumComputation(2U);
-  qc.h(0U);
-  qc.x(1U, 0_pc);
-
-  // check the circuit against itself
-  auto ecm = ec::EquivalenceCheckingManager(qc, qc);
-  ecm.run();
-  EXPECT_TRUE(ecm.getResults().consideredEquivalent());
-}
diff --git a/test/test_qcecexec.cpp b/test/test_qcecexec.cpp
index 5c91404..46a9766 100644
--- a/test/test_qcecexec.cpp
+++ b/test/test_qcecexec.cpp
@@ -6,8 +6,8 @@
 struct TestConfigurationQCEC {
   // given input
   std::string description;
-  std::string initialCircuit1;
-  std::string initialCircuit2;
+  std::string circuit1;
+  std::string circuit2;
 
   // expected output
   std::string expectedEquivalence;
@@ -16,8 +16,8 @@ struct TestConfigurationQCEC {
 // NOLINTNEXTLINE (readability-identifier-naming)
 inline void from_json(const nlohmann::json& j, TestConfigurationQCEC& test) {
   test.description         = j.at("description").get<std::string>();
-  test.initialCircuit1     = j.at("initial_circuit1").get<std::string>();
-  test.initialCircuit2     = j.at("initial_circuit2").get<std::string>();
+  test.circuit1            = j.at("circuit1").get<std::string>();
+  test.circuit2            = j.at("circuit2").get<std::string>();
   test.expectedEquivalence = j.at("expected_equivalence").get<std::string>();
 }
 
@@ -33,12 +33,12 @@ class QCECExecTest : public ::testing::TestWithParam<TestConfigurationQCEC> {
   void SetUp() override {
     test = GetParam();
 
-    std::stringstream ss1(test.initialCircuit1);
+    std::stringstream ss1(test.circuit1);
     auto              qc1 = std::make_unique<qc::QuantumComputation>();
     qc1->import(ss1, qc::Format::OpenQASM);
     std::cout << "Circuit 1:\n" << *qc1 << std::endl;
 
-    std::stringstream ss2(test.initialCircuit2);
+    std::stringstream ss2(test.circuit2);
     auto              qc2 = std::make_unique<qc::QuantumComputation>();
     qc2->import(ss2, qc::Format::OpenQASM);
     std::cout << "Circuit 2:\n" << *qc2 << std::endl;
@@ -47,32 +47,28 @@ class QCECExecTest : public ::testing::TestWithParam<TestConfigurationQCEC> {
 
     alternatingVerificationExecutor =
         std::make_unique<AlternatingVerificationExecutor>();
-
-    result = alternatingVerificationExecutor->execute(verificationTask);
-    std::cout << "Results:" << std::endl;
-    std::cout << result.dump(2U) << std::endl;
   }
 
-  void TearDown() override { std::cout << "Tearing down...\n"; }
-
   VerificationTask verificationTask;
   std::unique_ptr<AlternatingVerificationExecutor>
                         alternatingVerificationExecutor;
   TestConfigurationQCEC test;
-  json                  result;
 };
 
 INSTANTIATE_TEST_SUITE_P(
-    Circuits, QCECExecTest, testing::ValuesIn(getTests("equi_circuits.json")),
+    Circuits, QCECExecTest, testing::ValuesIn(getTests("ver_circuits.json")),
     [](const testing::TestParamInfo<QCECExecTest::ParamType>& inf) {
       return inf.param.description;
     });
 
-TEST_P(QCECExecTest, Equivalence) {
+TEST_P(QCECExecTest, Tests) {
+  const auto result =
+      alternatingVerificationExecutor->execute(verificationTask);
+  std::cout << "Results:\n" << result.dump(2U) << std::endl;
+
+  ASSERT_TRUE(result.contains("check_results"));
   EXPECT_EQ(result["check_results"]["equivalence"], test.expectedEquivalence);
-}
 
-TEST_P(QCECExecTest, Entries) {
   EXPECT_TRUE(result.contains("construction_time"));
   EXPECT_TRUE(result.contains("execution_time"));
   EXPECT_TRUE(result.contains("executor"));
diff --git a/test/test_simexec.cpp b/test/test_simexec.cpp
index 3976447..27661e1 100644
--- a/test/test_simexec.cpp
+++ b/test/test_simexec.cpp
@@ -6,7 +6,7 @@
 struct TestConfigurationDDSIM {
   // given input
   std::string description;
-  std::string initialCircuit;
+  std::string circuit;
 
   // expected output
   json expectedResults{};
@@ -15,54 +15,53 @@ struct TestConfigurationDDSIM {
 // NOLINTNEXTLINE (readability-identifier-naming)
 inline void from_json(const nlohmann::json& j, TestConfigurationDDSIM& test) {
   test.description     = j.at("description").get<std::string>();
-  test.initialCircuit  = j.at("initial_circuit").get<std::string>();
+  test.circuit         = j.at("circuit").get<std::string>();
   test.expectedResults = j.at("expected_meas_results").get<json>();
 }
 
-static std::vector<TestConfigurationDDSIM> getTests(const std::string& path) {
+namespace {
+std::vector<TestConfigurationDDSIM> getTests(const std::string& path) {
   std::ifstream  input(path);
   nlohmann::json j;
   input >> j;
   return j;
 }
+} // namespace
 
 class DDSIMExecTest : public ::testing::TestWithParam<TestConfigurationDDSIM> {
 protected:
   void SetUp() override {
     test = GetParam();
+    std::stringstream ss(test.circuit);
 
-    std::stringstream ss(test.initialCircuit);
-    auto              qc = std::make_unique<qc::QuantumComputation>();
+    auto qc = std::make_unique<qc::QuantumComputation>();
     qc->import(ss, qc::Format::OpenQASM);
     std::cout << "Circuit:\n" << *qc;
 
     simulationTask           = SimulationTask(std::move(qc));
     circuitSimulatorExecutor = std::make_unique<CircuitSimulatorExecutor>();
-
-    result = circuitSimulatorExecutor->execute(simulationTask);
-    std::cout << "Results:" << std::endl;
-    std::cout << result.dump(2U) << std::endl;
   }
 
-  void TearDown() override { std::cout << "Tearing down...\n"; }
-
   SimulationTask                            simulationTask;
   std::unique_ptr<CircuitSimulatorExecutor> circuitSimulatorExecutor;
   TestConfigurationDDSIM                    test;
-  json                                      result;
 };
 
 INSTANTIATE_TEST_SUITE_P(
-    Circuits, DDSIMExecTest, testing::ValuesIn(getTests("circuits.json")),
+    Circuits, DDSIMExecTest, testing::ValuesIn(getTests("sim_circuits.json")),
     [](const testing::TestParamInfo<DDSIMExecTest::ParamType>& inf) {
       return inf.param.description;
     });
 
-TEST_P(DDSIMExecTest, MeasResults) {
-  EXPECT_EQ(result["measurement_results"], test.expectedResults);
-}
+TEST_P(DDSIMExecTest, Tests) {
+  const auto result = circuitSimulatorExecutor->execute(simulationTask);
+  std::cout << "Results:\n" << result.dump(2U) << std::endl;
+
+  ASSERT_TRUE(result.contains("measurement_results"));
+  if (!result["measurement_results"].empty()) {
+    EXPECT_EQ(result["measurement_results"], test.expectedResults);
+  }
 
-TEST_P(DDSIMExecTest, Entries) {
   EXPECT_TRUE(result.contains("construction_time"));
   EXPECT_TRUE(result.contains("execution_time"));
   EXPECT_TRUE(result.contains("executor"));
diff --git a/test/ver_circuits.json b/test/ver_circuits.json
new file mode 100644
index 0000000..0f7814a
--- /dev/null
+++ b/test/ver_circuits.json
@@ -0,0 +1,14 @@
+[
+  {
+    "description": "simple_circuits",
+    "circuit1": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];x q[0];x q[1];\n",
+    "circuit2": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];x q[0];x q[1];x q[0];x q[0];\n",
+    "expected_equivalence": "equivalent"
+  },
+  {
+    "description": "non_equi_circuits",
+    "circuit1": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];h q[0];t q[1];cx q[0], q[1];\n",
+    "circuit2": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];h q[1];cx q[0], q[1];s q[0];\n",
+    "expected_equivalence": "not_equivalent"
+  }
+]

From f8e3dec777f908c02e544bfe771fe243fbcdd3d2 Mon Sep 17 00:00:00 2001
From: Lukas Burgholzer <lukas.burgholzer@jku.at>
Date: Fri, 9 Jun 2023 18:22:14 +0200
Subject: [PATCH 39/43] =?UTF-8?q?=E2=9A=97=EF=B8=8F=20try=20newer=20cpp-li?=
 =?UTF-8?q?nter=20config?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .github/workflows/cpp-linter.yml | 45 ++++++++++++++++++++++++--------
 1 file changed, 34 insertions(+), 11 deletions(-)

diff --git a/.github/workflows/cpp-linter.yml b/.github/workflows/cpp-linter.yml
index 36f8545..3ef8ecb 100644
--- a/.github/workflows/cpp-linter.yml
+++ b/.github/workflows/cpp-linter.yml
@@ -2,7 +2,6 @@ name: cpp-linter
 
 on:
   pull_request:
-  merge_group:
   push:
     branches:
       - main
@@ -12,6 +11,9 @@ concurrency:
   group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
   cancel-in-progress: true
 
+env:
+  clang-version: 16
+
 jobs:
   cpp-linter:
     runs-on: ubuntu-latest
@@ -19,21 +21,42 @@ jobs:
       - uses: actions/checkout@v3
         with:
           submodules: recursive
+
+      - name: Install clang-${{ env.clang-version }}
+        run: |
+          sudo apt-get update
+          wget https://apt.llvm.org/llvm.sh -O ${{ runner.temp }}/llvm_install.sh
+          chmod +x ${{ runner.temp }}/llvm_install.sh
+          if sudo ${{ runner.temp }}/llvm_install.sh ${{ env.clang-version }}; then
+            sudo apt-get install -y clang-format-${{ env.clang-version }} clang-tidy-${{ env.clang-version }}
+          fi
+          echo "CC=clang-${{ env.clang-version }}" >> $GITHUB_ENV
+          echo "CXX=clang++-${{ env.clang-version }}" >> $GITHUB_ENV
+
       - name: Generate compilation database
-        run: CC=clang-14 CXX=clang++-14 cmake -S . -B build -DBUILD_DD_EVAL_TESTS=ON
+        run: |
+          echo $CC
+          echo $CXX
+          $CC --version
+          $CXX --version
+          cmake -S . -B build -DBUILD_DD_EVAL_TESTS=ON
+
       - name: Run cpp-linter
+        uses: cpp-linter/cpp-linter-action@v2
         id: linter
         env:
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-        run: |
-          pipx run cpp-linter \
-          --version=14 \
-          --style="" \
-          --tidy-checks="" \
-          --thread-comments=true \
-          --files-changed-only=true \
-          --ignore="build" \
-          --database=build
+        with:
+          style: ""
+          tidy-checks: ""
+          version: 16
+          ignore: build
+          thread-comments: true
+          step-summary: true
+          database: "build"
+          extra-args: -std=c++17
+          files-changed-only: true
+
       - name: Fail if linter found errors
         if: steps.linter.outputs.checks-failed > 0
         run: echo "Linter found errors" && exit 1

From 7a96d3cf65abd97e752f8c256429e13ad82d2056 Mon Sep 17 00:00:00 2001
From: Lukas Burgholzer <lukas.burgholzer@jku.at>
Date: Fri, 9 Jun 2023 18:30:00 +0200
Subject: [PATCH 40/43] =?UTF-8?q?=F0=9F=A9=B9=20fix=20CI=20coverage=20conf?=
 =?UTF-8?q?iguration?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .github/workflows/ci.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index cce5165..a04e5ff 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -45,7 +45,7 @@ jobs:
         name: Coverage
         run: |
           cmake -S . -B buildCov -DCMAKE_BUILD_TYPE=Debug -DBUILD_DD_EVAL_TESTS=ON -DENABLE_COVERAGE=ON
-          cmake --build buildCov --config Debug --target DDEval_test
+          cmake --build buildCov --config Debug
           ctest -C Debug --output-on-failure --test-dir buildCov --repeat until-pass:3 --timeout 300
       - if: runner.os == 'Linux'
         name: Upload coverage to Codecov

From 1b750ea75530b98e18c1e679725b298d10e769a4 Mon Sep 17 00:00:00 2001
From: Lukas Burgholzer <lukas.burgholzer@jku.at>
Date: Fri, 9 Jun 2023 18:41:53 +0200
Subject: [PATCH 41/43] =?UTF-8?q?=F0=9F=9A=A8=20another=20clang-tidy=20war?=
 =?UTF-8?q?ning=20fixed?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 test/test_qcecexec.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/test/test_qcecexec.cpp b/test/test_qcecexec.cpp
index 46a9766..d03c12f 100644
--- a/test/test_qcecexec.cpp
+++ b/test/test_qcecexec.cpp
@@ -21,12 +21,14 @@ inline void from_json(const nlohmann::json& j, TestConfigurationQCEC& test) {
   test.expectedEquivalence = j.at("expected_equivalence").get<std::string>();
 }
 
-static std::vector<TestConfigurationQCEC> getTests(const std::string& path) {
+namespace {
+std::vector<TestConfigurationQCEC> getTests(const std::string& path) {
   std::ifstream  input(path);
   nlohmann::json j;
   input >> j;
   return j;
 }
+} // namespace
 
 class QCECExecTest : public ::testing::TestWithParam<TestConfigurationQCEC> {
 protected:

From f68f5fb1b1c1ecfc00b200fe0e68877c3da579f1 Mon Sep 17 00:00:00 2001
From: Lukas Burgholzer <lukas.burgholzer@jku.at>
Date: Fri, 9 Jun 2023 18:43:37 +0200
Subject: [PATCH 42/43] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20remove=20expected=20?=
 =?UTF-8?q?output=20from=20simulation=20test?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

the criterion is just not generalizable in a reasonable way
---
 test/sim_circuits.json | 10 ++--------
 test/test_simexec.cpp  | 12 ++----------
 2 files changed, 4 insertions(+), 18 deletions(-)

diff --git a/test/sim_circuits.json b/test/sim_circuits.json
index 1602d8a..dd73f45 100644
--- a/test/sim_circuits.json
+++ b/test/sim_circuits.json
@@ -1,16 +1,10 @@
 [
   {
     "description": "two_qubit_circuit_with_two_x_gates",
-    "circuit": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];x q[0];x q[1];\n",
-    "expected_meas_results": {
-      "11": 1024
-    }
+    "circuit": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];x q[0];x q[1];\n"
   },
   {
     "description": "two_qubit_circuit_with_h_z_controlled_x_swap",
-    "circuit": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];cx q[0], q[1];h q[0];z q[0];h q[0];swap q[0], q[1];\n",
-    "expected_meas_results": {
-      "10": 1024
-    }
+    "circuit": "OPENQASM 2.0;include \"qelib1.inc\";qreg q[2];cx q[0], q[1];h q[0];z q[0];h q[0];swap q[0], q[1];\n"
   }
 ]
diff --git a/test/test_simexec.cpp b/test/test_simexec.cpp
index 27661e1..3c18a85 100644
--- a/test/test_simexec.cpp
+++ b/test/test_simexec.cpp
@@ -7,16 +7,12 @@ struct TestConfigurationDDSIM {
   // given input
   std::string description;
   std::string circuit;
-
-  // expected output
-  json expectedResults{};
 };
 
 // NOLINTNEXTLINE (readability-identifier-naming)
 inline void from_json(const nlohmann::json& j, TestConfigurationDDSIM& test) {
-  test.description     = j.at("description").get<std::string>();
-  test.circuit         = j.at("circuit").get<std::string>();
-  test.expectedResults = j.at("expected_meas_results").get<json>();
+  test.description = j.at("description").get<std::string>();
+  test.circuit     = j.at("circuit").get<std::string>();
 }
 
 namespace {
@@ -58,10 +54,6 @@ TEST_P(DDSIMExecTest, Tests) {
   std::cout << "Results:\n" << result.dump(2U) << std::endl;
 
   ASSERT_TRUE(result.contains("measurement_results"));
-  if (!result["measurement_results"].empty()) {
-    EXPECT_EQ(result["measurement_results"], test.expectedResults);
-  }
-
   EXPECT_TRUE(result.contains("construction_time"));
   EXPECT_TRUE(result.contains("execution_time"));
   EXPECT_TRUE(result.contains("executor"));

From bf32253e33f47bd19b6d56ca40671cedf3054030 Mon Sep 17 00:00:00 2001
From: Lukas Burgholzer <lukas.burgholzer@jku.at>
Date: Fri, 9 Jun 2023 18:54:51 +0200
Subject: [PATCH 43/43] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20some=20restructuring?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Also make use of forward declarartions to reduce the number of imports in headers
---
 include/tasks/SimulationTask.hpp                     | 12 ++++++------
 include/tasks/VerificationTask.hpp                   | 12 ++++++------
 src/CMakeLists.txt                                   |  6 ++++--
 .../AlternatingVerificationExecutor.cpp              |  0
 src/{ => executors}/CircuitSimulatorExecutor.cpp     |  0
 src/tasks/SimulationTask.cpp                         | 10 ++++++++++
 src/tasks/VerificationTask.cpp                       | 12 ++++++++++++
 test/test_qcecexec.cpp                               |  1 +
 test/test_simexec.cpp                                |  1 +
 9 files changed, 40 insertions(+), 14 deletions(-)
 rename src/{ => executors}/AlternatingVerificationExecutor.cpp (100%)
 rename src/{ => executors}/CircuitSimulatorExecutor.cpp (100%)
 create mode 100644 src/tasks/SimulationTask.cpp
 create mode 100644 src/tasks/VerificationTask.cpp

diff --git a/include/tasks/SimulationTask.hpp b/include/tasks/SimulationTask.hpp
index dae4bdd..17c6c36 100644
--- a/include/tasks/SimulationTask.hpp
+++ b/include/tasks/SimulationTask.hpp
@@ -1,19 +1,19 @@
 #pragma once
 
-#include "QuantumComputation.hpp"
 #include "Task.hpp"
 
 #include <memory>
 
+namespace qc {
+class QuantumComputation;
+}
+
 class SimulationTask : public Task {
 public:
   explicit SimulationTask() = default;
-  explicit SimulationTask(std::unique_ptr<qc::QuantumComputation> circ)
-      : qc(std::move(circ)) {}
+  explicit SimulationTask(std::unique_ptr<qc::QuantumComputation> circ);
 
-  [[nodiscard]] std::string getIdentifier() const override {
-    return "sim_" + qc->getName();
-  };
+  [[nodiscard]] std::string getIdentifier() const override;
 
   [[nodiscard]] const std::unique_ptr<qc::QuantumComputation>& getQc() const {
     return qc;
diff --git a/include/tasks/VerificationTask.hpp b/include/tasks/VerificationTask.hpp
index 8a33f2b..80b04d4 100644
--- a/include/tasks/VerificationTask.hpp
+++ b/include/tasks/VerificationTask.hpp
@@ -1,20 +1,20 @@
 #pragma once
 
-#include "QuantumComputation.hpp"
 #include "Task.hpp"
 
 #include <memory>
 
+namespace qc {
+class QuantumComputation;
+}
+
 class VerificationTask : public Task {
 public:
   explicit VerificationTask() = default;
   VerificationTask(std::unique_ptr<qc::QuantumComputation> circ1,
-                   std::unique_ptr<qc::QuantumComputation> circ2)
-      : qc1(std::move(circ1)), qc2(std::move(circ2)) {}
+                   std::unique_ptr<qc::QuantumComputation> circ2);
 
-  [[nodiscard]] std::string getIdentifier() const override {
-    return "ver_" + qc1->getName() + "_" + qc2->getName();
-  };
+  [[nodiscard]] std::string getIdentifier() const override;
 
   [[nodiscard]] const std::unique_ptr<qc::QuantumComputation>& getQc1() const {
     return qc1;
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 7795456..9dce18f 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -15,8 +15,10 @@ if(NOT TARGET ${PROJECT_NAME})
     ${PROJECT_SOURCE_DIR}/include/Task.hpp
     ${PROJECT_SOURCE_DIR}/include/tasks/SimulationTask.hpp
     ${PROJECT_SOURCE_DIR}/include/tasks/VerificationTask.hpp
-    CircuitSimulatorExecutor.cpp
-    AlternatingVerificationExecutor.cpp)
+    executors/CircuitSimulatorExecutor.cpp
+    executors/AlternatingVerificationExecutor.cpp
+    tasks/SimulationTask.cpp
+    tasks/VerificationTask.cpp)
 
   # set include directories
   target_include_directories(
diff --git a/src/AlternatingVerificationExecutor.cpp b/src/executors/AlternatingVerificationExecutor.cpp
similarity index 100%
rename from src/AlternatingVerificationExecutor.cpp
rename to src/executors/AlternatingVerificationExecutor.cpp
diff --git a/src/CircuitSimulatorExecutor.cpp b/src/executors/CircuitSimulatorExecutor.cpp
similarity index 100%
rename from src/CircuitSimulatorExecutor.cpp
rename to src/executors/CircuitSimulatorExecutor.cpp
diff --git a/src/tasks/SimulationTask.cpp b/src/tasks/SimulationTask.cpp
new file mode 100644
index 0000000..48bf4dd
--- /dev/null
+++ b/src/tasks/SimulationTask.cpp
@@ -0,0 +1,10 @@
+#include "tasks/SimulationTask.hpp"
+
+#include "QuantumComputation.hpp"
+
+SimulationTask::SimulationTask(std::unique_ptr<qc::QuantumComputation> circ)
+    : qc(std::move(circ)) {}
+
+std::string SimulationTask::getIdentifier() const {
+  return "sim_" + qc->getName();
+}
diff --git a/src/tasks/VerificationTask.cpp b/src/tasks/VerificationTask.cpp
new file mode 100644
index 0000000..a3d496e
--- /dev/null
+++ b/src/tasks/VerificationTask.cpp
@@ -0,0 +1,12 @@
+#include "tasks/VerificationTask.hpp"
+
+#include "QuantumComputation.hpp"
+
+VerificationTask::VerificationTask(
+    std::unique_ptr<qc::QuantumComputation> circ1,
+    std::unique_ptr<qc::QuantumComputation> circ2)
+    : qc1(std::move(circ1)), qc2(std::move(circ2)) {}
+
+std::string VerificationTask::getIdentifier() const {
+  return "ver_" + qc1->getName() + "_" + qc2->getName();
+}
diff --git a/test/test_qcecexec.cpp b/test/test_qcecexec.cpp
index d03c12f..da44a00 100644
--- a/test/test_qcecexec.cpp
+++ b/test/test_qcecexec.cpp
@@ -1,3 +1,4 @@
+#include "QuantumComputation.hpp"
 #include "executors/AlternatingVerificationExecutor.hpp"
 #include "tasks/VerificationTask.hpp"
 
diff --git a/test/test_simexec.cpp b/test/test_simexec.cpp
index 3c18a85..4f740cd 100644
--- a/test/test_simexec.cpp
+++ b/test/test_simexec.cpp
@@ -1,3 +1,4 @@
+#include "QuantumComputation.hpp"
 #include "executors/CircuitSimulatorExecutor.hpp"
 #include "tasks/SimulationTask.hpp"